From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.8 required=3.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH,MAILING_LIST_MULTI, SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 49CCCC4724C for ; Wed, 6 May 2020 15:12:04 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 2106A208E4 for ; Wed, 6 May 2020 15:12:04 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="h74pNX9K" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729341AbgEFPMD (ORCPT ); Wed, 6 May 2020 11:12:03 -0400 Received: from perceval.ideasonboard.com ([213.167.242.64]:56840 "EHLO perceval.ideasonboard.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727984AbgEFPMC (ORCPT ); Wed, 6 May 2020 11:12:02 -0400 Received: from pendragon.ideasonboard.com (81-175-216-236.bb.dnainternet.fi [81.175.216.236]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id E94FB542; Wed, 6 May 2020 17:11:47 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1588777908; bh=OgPW0FiG0bfGFWpm6HDke/69B2sIgCPK3Ih7ue2cWbE=; h=Date:From:To:Cc:Subject:References:In-Reply-To:From; b=h74pNX9KGvfOSBrhejIXpgLtaxc9kCnoLUeUfooKvarY4LyEkQHtRLY//RzycJ1D5 vj7q84n+Ut/Ue/iEiHHtVxsj8ZVtWFlyPm2J55urlAXqX9z+37opOINfp4uXDPBvb+ MSFf4bgkHNU4bBYv3xO3ryd4z6v8qCIY3Aq6Ydmk= Date: Wed, 6 May 2020 18:11:42 +0300 From: Laurent Pinchart To: Vishal Sagar Cc: Hyun Kwon , mchehab@kernel.org, robh+dt@kernel.org, mark.rutland@arm.com, Michal Simek , linux-media@vger.kernel.org, devicetree@vger.kernel.org, hans.verkuil@cisco.com, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, Dinesh Kumar , Sandip Kothari , Joe Perches Subject: Re: [PATCH v2 2/2] media: v4l: xilinx: Add Xilinx UHD-SDI Rx Subsystem driver Message-ID: <20200506151142.GA15206@pendragon.ideasonboard.com> References: <20200429141705.18755-1-vishal.sagar@xilinx.com> <20200429141705.18755-3-vishal.sagar@xilinx.com> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: <20200429141705.18755-3-vishal.sagar@xilinx.com> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Hi Vishal, Thank you for the patch. There are a few questions for Hans below. On Wed, Apr 29, 2020 at 07:47:04PM +0530, Vishal Sagar wrote: > The Xilinx UHD-SDI Rx subsystem soft IP is used to capture native SDI > streams from SDI sources like SDI broadcast equipment like cameras and > mixers. This block outputs either native SDI, native video or > AXI4-Stream compliant data stream for further processing. Please refer > to PG290 for details. > > The driver is used to configure the IP to add framer, search for > specific modes, get the detected mode, stream parameters, errors, etc. > It also generates events for video lock/unlock, bridge over/under flow. > > The driver supports 10/12 bpc YUV 422 media bus format currently. It also > decodes the stream parameters based on the ST352 packet embedded in the > stream. In case the ST352 packet isn't present in the stream, the core's > detected properties are used to set stream properties. As commented on patch 1/2, I don't see a mention of 12 bpc in the documentation. Let's discuss it as part of patch 1/2. > The driver currently supports only the AXI4-Stream IP configuration. > > Signed-off-by: Vishal Sagar > --- > v2 > - Added DV timing support based on Hans Verkuilś feedback > - More documentation to custom v4l controls and events > - Fixed Hyunś comments > - Added macro for masking and shifting as per Joe Perches comments > - Updated to latest as per Xilinx github repo driver like > adding new DV timings not in mainline yet uptill 03/21/20 > > drivers/media/platform/xilinx/Kconfig | 11 + > drivers/media/platform/xilinx/Makefile | 1 + > .../media/platform/xilinx/xilinx-sdirxss.c | 2162 +++++++++++++++++ > include/uapi/linux/xilinx-sdirxss.h | 179 ++ > include/uapi/linux/xilinx-v4l2-controls.h | 67 + > 5 files changed, 2420 insertions(+) > create mode 100644 drivers/media/platform/xilinx/xilinx-sdirxss.c > create mode 100644 include/uapi/linux/xilinx-sdirxss.h > > diff --git a/drivers/media/platform/xilinx/Kconfig b/drivers/media/platform/xilinx/Kconfig > index 01c96fb66414..77091318a9c9 100644 > --- a/drivers/media/platform/xilinx/Kconfig > +++ b/drivers/media/platform/xilinx/Kconfig > @@ -12,6 +12,17 @@ config VIDEO_XILINX > > if VIDEO_XILINX > > +config VIDEO_XILINX_SDIRXSS > + tristate "Xilinx UHD SDI Rx Subsystem" > + help > + Driver for Xilinx UHD-SDI Rx Subsystem. This is a V4L sub-device > + based driver that takes input from a SDI source like SDI camera and > + converts it into an AXI4-Stream. The subsystem comprises of a SMPTE s/comprises of/comprises/ > + UHD-SDI Rx core, a SDI Rx to Native Video bridge and a Video In to > + AXI4-Stream bridge. The driver is used to set different stream > + detection modes and identify stream properties to properly configure > + downstream. > + > config VIDEO_XILINX_TPG > tristate "Xilinx Video Test Pattern Generator" > depends on VIDEO_XILINX > diff --git a/drivers/media/platform/xilinx/Makefile b/drivers/media/platform/xilinx/Makefile > index 4cdc0b1ec7a5..6c375f03f587 100644 > --- a/drivers/media/platform/xilinx/Makefile > +++ b/drivers/media/platform/xilinx/Makefile > @@ -2,6 +2,7 @@ > > xilinx-video-objs += xilinx-dma.o xilinx-vip.o xilinx-vipp.o > > +obj-$(CONFIG_VIDEO_XILINX_SDIRXSS) += xilinx-sdirxss.o > obj-$(CONFIG_VIDEO_XILINX) += xilinx-video.o > obj-$(CONFIG_VIDEO_XILINX_TPG) += xilinx-tpg.o > obj-$(CONFIG_VIDEO_XILINX_VTC) += xilinx-vtc.o > diff --git a/drivers/media/platform/xilinx/xilinx-sdirxss.c b/drivers/media/platform/xilinx/xilinx-sdirxss.c > new file mode 100644 > index 000000000000..c536ea3aaa0d > --- /dev/null > +++ b/drivers/media/platform/xilinx/xilinx-sdirxss.c > @@ -0,0 +1,2162 @@ > +// SPDX-License-Identifier: GPL-2.0 > +/* > + * Driver for Xilinx SDI Rx Subsystem > + * > + * Copyright (C) 2017 - 2020 Xilinx, Inc. > + * > + * Contacts: Vishal Sagar > + * You can remove this blank line. > + */ > + > +#include > +#include > +#include > +#include You nearly got the alphabetical order right ;-) > +#include No use of delay or sleep functions in the code, is this needed ? > +#include You can probably drop this one as you include platform_device.h. > +#include > +#include > +#include > +#include > +#include > +#include I don't think of_irq is needed either. > +#include > +#include > +#include > +#include > +#include The driver doesn't seems to use spinlocks, you can remove those two headers. > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include "xilinx-vip.h" > + > +/* > + * SDI Rx register map, bitmask and offsets > + */ > +#define XSDIRX_RST_CTRL_REG 0x00 > +#define XSDIRX_MDL_CTRL_REG 0x04 > +#define XSDIRX_GLBL_IER_REG 0x0C > +#define XSDIRX_ISR_REG 0x10 > +#define XSDIRX_IER_REG 0x14 > +#define XSDIRX_ST352_VALID_REG 0x18 > +#define XSDIRX_ST352_DS1_REG 0x1C Could you use lower-case hex values ? That's the most common option in kernel code. If you use vim, :%s/\<0x[0-9A-F]\+\>/\L\0/ I'm sure there's an emacs equivalent :-) > +#define XSDIRX_ST352_DS3_REG 0x20 > +#define XSDIRX_ST352_DS5_REG 0x24 > +#define XSDIRX_ST352_DS7_REG 0x28 > +#define XSDIRX_ST352_DS9_REG 0x2C > +#define XSDIRX_ST352_DS11_REG 0x30 > +#define XSDIRX_ST352_DS13_REG 0x34 > +#define XSDIRX_ST352_DS15_REG 0x38 > +#define XSDIRX_VERSION_REG 0x3C > +#define XSDIRX_SS_CONFIG_REG 0x40 > +#define XSDIRX_MODE_DET_STAT_REG 0x44 > +#define XSDIRX_TS_DET_STAT_REG 0x48 > +#define XSDIRX_EDH_STAT_REG 0x4C > +#define XSDIRX_EDH_ERRCNT_EN_REG 0x50 > +#define XSDIRX_EDH_ERRCNT_REG 0x54 > +#define XSDIRX_CRC_ERRCNT_REG 0x58 > +#define XSDIRX_VID_LOCK_WINDOW_REG 0x5C > +#define XSDIRX_SB_RX_STS_REG 0x60 > + > +#define XSDIRX_RST_CTRL_SS_EN_MASK BIT(0) > +#define XSDIRX_RST_CTRL_SRST_MASK BIT(1) > +#define XSDIRX_RST_CTRL_RST_CRC_ERRCNT_MASK BIT(2) > +#define XSDIRX_RST_CTRL_RST_EDH_ERRCNT_MASK BIT(3) > +#define XSDIRX_RST_CTRL_SDIRX_BRIDGE_ENB_MASK BIT(8) > +#define XSDIRX_RST_CTRL_VIDIN_AXI4S_MOD_ENB_MASK BIT(9) > +#define XSDIRX_RST_CTRL_BRIDGE_CH_FMT_OFFSET 10 > +#define XSDIRX_RST_CTRL_BRIDGE_CH_FMT_MASK GENMASK(12, 10) > +#define XSDIRX_RST_CTRL_BRIDGE_CH_FMT_YUV444 1 > + > +#define XSDIRX_MDL_CTRL_FRM_EN_MASK BIT(4) > +#define XSDIRX_MDL_CTRL_MODE_DET_EN_MASK BIT(5) > +#define XSDIRX_MDL_CTRL_MODE_HD_EN_MASK BIT(8) > +#define XSDIRX_MDL_CTRL_MODE_SD_EN_MASK BIT(9) > +#define XSDIRX_MDL_CTRL_MODE_3G_EN_MASK BIT(10) > +#define XSDIRX_MDL_CTRL_MODE_6G_EN_MASK BIT(11) > +#define XSDIRX_MDL_CTRL_MODE_12GI_EN_MASK BIT(12) > +#define XSDIRX_MDL_CTRL_MODE_12GF_EN_MASK BIT(13) > +#define XSDIRX_MDL_CTRL_MODE_AUTO_DET_MASK GENMASK(13, 8) > + > +#define XSDIRX_MDL_CTRL_FORCED_MODE_OFFSET 16 > +#define XSDIRX_MDL_CTRL_FORCED_MODE_MASK GENMASK(18, 16) > + > +#define XSDIRX_GLBL_INTR_EN_MASK BIT(0) > + > +#define XSDIRX_INTR_VIDLOCK_MASK BIT(0) > +#define XSDIRX_INTR_VIDUNLOCK_MASK BIT(1) > +#define XSDIRX_INTR_OVERFLOW_MASK BIT(9) > +#define XSDIRX_INTR_UNDERFLOW_MASK BIT(10) > + > +#define XSDIRX_INTR_ALL_MASK (XSDIRX_INTR_VIDLOCK_MASK |\ > + XSDIRX_INTR_VIDUNLOCK_MASK |\ > + XSDIRX_INTR_OVERFLOW_MASK |\ > + XSDIRX_INTR_UNDERFLOW_MASK) > + > +#define XSDIRX_ST352_VALID_DS1_MASK BIT(0) > +#define XSDIRX_ST352_VALID_DS3_MASK BIT(1) > +#define XSDIRX_ST352_VALID_DS5_MASK BIT(2) > +#define XSDIRX_ST352_VALID_DS7_MASK BIT(3) > +#define XSDIRX_ST352_VALID_DS9_MASK BIT(4) > +#define XSDIRX_ST352_VALID_DS11_MASK BIT(5) > +#define XSDIRX_ST352_VALID_DS13_MASK BIT(6) > +#define XSDIRX_ST352_VALID_DS15_MASK BIT(7) > + > +#define XSDIRX_MODE_DET_STAT_RX_MODE_MASK GENMASK(2, 0) > +#define XSDIRX_MODE_DET_STAT_MODE_LOCK_MASK BIT(3) > +#define XSDIRX_MODE_DET_STAT_ACT_STREAM_MASK GENMASK(6, 4) > +#define XSDIRX_MODE_DET_STAT_ACT_STREAM_OFFSET 4 > +#define XSDIRX_MODE_DET_STAT_LVLB_3G_MASK BIT(7) > + > +#define XSDIRX_TS_DET_STAT_LOCKED_MASK BIT(0) > +#define XSDIRX_TS_DET_STAT_SCAN_MASK BIT(1) > +#define XSDIRX_TS_DET_STAT_SCAN_OFFSET (1) > +#define XSDIRX_TS_DET_STAT_FAMILY_MASK GENMASK(7, 4) > +#define XSDIRX_TS_DET_STAT_FAMILY_OFFSET (4) > +#define XSDIRX_TS_DET_STAT_RATE_MASK GENMASK(11, 8) > +#define XSDIRX_TS_DET_STAT_RATE_OFFSET (8) > + > +#define XSDIRX_TS_DET_STAT_RATE_NONE 0x0 > +#define XSDIRX_TS_DET_STAT_RATE_23_98HZ 0x2 > +#define XSDIRX_TS_DET_STAT_RATE_24HZ 0x3 > +#define XSDIRX_TS_DET_STAT_RATE_47_95HZ 0x4 > +#define XSDIRX_TS_DET_STAT_RATE_25HZ 0x5 > +#define XSDIRX_TS_DET_STAT_RATE_29_97HZ 0x6 > +#define XSDIRX_TS_DET_STAT_RATE_30HZ 0x7 > +#define XSDIRX_TS_DET_STAT_RATE_48HZ 0x8 > +#define XSDIRX_TS_DET_STAT_RATE_50HZ 0x9 > +#define XSDIRX_TS_DET_STAT_RATE_59_94HZ 0xA > +#define XSDIRX_TS_DET_STAT_RATE_60HZ 0xB > + > +#define XSDIRX_EDH_STAT_EDH_AP_MASK BIT(0) > +#define XSDIRX_EDH_STAT_EDH_FF_MASK BIT(1) > +#define XSDIRX_EDH_STAT_EDH_ANC_MASK BIT(2) > +#define XSDIRX_EDH_STAT_AP_FLAG_MASK GENMASK(8, 4) > +#define XSDIRX_EDH_STAT_FF_FLAG_MASK GENMASK(13, 9) > +#define XSDIRX_EDH_STAT_ANC_FLAG_MASK GENMASK(18, 14) > +#define XSDIRX_EDH_STAT_PKT_FLAG_MASK GENMASK(22, 19) > + > +#define XSDIRX_EDH_ERRCNT_COUNT_MASK GENMASK(15, 0) > + > +#define XSDIRX_CRC_ERRCNT_COUNT_MASK GENMASK(31, 16) > +#define XSDIRX_CRC_ERRCNT_DS_CRC_MASK GENMASK(15, 0) > + > +#define XSDIRX_VERSION_REV_MASK GENMASK(7, 0) > +#define XSDIRX_VERSION_PATCHID_MASK GENMASK(11, 8) > +#define XSDIRX_VERSION_VER_REV_MASK GENMASK(15, 12) > +#define XSDIRX_VERSION_VER_MIN_MASK GENMASK(23, 16) > +#define XSDIRX_VERSION_VER_MAJ_MASK GENMASK(31, 24) > + > +#define XSDIRX_SS_CONFIG_EDH_INCLUDED_MASK BIT(1) > + > +#define XSDIRX_STAT_SB_RX_TDATA_CHANGE_DONE_MASK BIT(0) > +#define XSDIRX_STAT_SB_RX_TDATA_CHANGE_FAIL_MASK BIT(1) > +#define XSDIRX_STAT_SB_RX_TDATA_GT_RESETDONE_MASK BIT(2) > +#define XSDIRX_STAT_SB_RX_TDATA_GT_BITRATE_MASK BIT(3) > + > +#define XSDIRX_DEFAULT_WIDTH (1920) No need for parentheses around integer values in macros. > +#define XSDIRX_DEFAULT_HEIGHT (1080) > + > +#define XSDIRX_MAX_STR_LENGTH 16 > + > +#define XSDIRXSS_SDI_STD_3G 0 > +#define XSDIRXSS_SDI_STD_6G 1 > +#define XSDIRXSS_SDI_STD_12G_8DS 2 Should these three constants be placed in an enum ? The xsdirxss_core.mode field would then become an enum. > + > +#define XSDIRX_DEFAULT_VIDEO_LOCK_WINDOW 0x3000 > + > +#define XSDIRX_MODE_HD_MASK 0x0 > +#define XSDIRX_MODE_SD_MASK 0x1 > +#define XSDIRX_MODE_3G_MASK 0x2 > +#define XSDIRX_MODE_6G_MASK 0x4 > +#define XSDIRX_MODE_12GI_MASK 0x5 > +#define XSDIRX_MODE_12GF_MASK 0x6 > + > +/* Maximum number of events per file handle. */ > +#define XSDIRX_MAX_EVENTS (128) Do we really need such a high number ? How often are the overflow and underflow expected ? > + > +/* ST352 related macros */ > +#define XST352_PAYLOAD_BYTE1_MASK 0xFF > +#define XST352_PAYLOAD_BYTE1_OFFSET 0 > +#define XST352_PAYLOAD_BYTE2_OFFSET 8 > +#define XST352_PAYLOAD_BYTE3_OFFSET 16 > +#define XST352_PAYLOAD_BYTE4_OFFSET 24 > + > +#define XST352_BYTE1_ST292_1x720L_1_5G 0x84 > +#define XST352_BYTE1_ST292_1x1080L_1_5G 0x85 > +#define XST352_BYTE1_ST425_2008_750L_3GB 0x88 > +#define XST352_BYTE1_ST425_2008_1125L_3GA 0x89 > +#define XST352_BYTE1_ST372_DL_3GB 0x8A > +#define XST352_BYTE1_ST372_2x720L_3GB 0x8B > +#define XST352_BYTE1_ST372_2x1080L_3GB 0x8C > +#define XST352_BYTE1_ST2081_10_2160L_6G 0xC0 > +#define XST352_BYTE1_ST2081_10_2_1080L_6G 0xC1 > +#define XST352_BYTE1_ST2081_10_DL_2160L_6G 0xC2 > +#define XST352_BYTE1_ST2082_10_2160L_12G 0xCE > + > +#define XST352_BYTE2_TS_TYPE_MASK BIT(15) > +#define XST352_BYTE2_TS_TYPE_OFFSET 15 > +#define XST352_BYTE2_PIC_TYPE_MASK BIT(14) > +#define XST352_BYTE2_PIC_TYPE_OFFSET 14 > +#define XST352_BYTE2_TS_PIC_TYPE_INTERLACED 0 > +#define XST352_BYTE2_TS_PIC_TYPE_PROGRESSIVE 1 > + > +#define XST352_BYTE2_FPS_MASK 0xF > +#define XST352_BYTE2_FPS_OFFSET 8 > +#define XST352_BYTE2_FPS_24F 0x2 > +#define XST352_BYTE2_FPS_24 0x3 > +#define XST352_BYTE2_FPS_48F 0x4 > +#define XST352_BYTE2_FPS_25 0x5 > +#define XST352_BYTE2_FPS_30F 0x6 > +#define XST352_BYTE2_FPS_30 0x7 > +#define XST352_BYTE2_FPS_48 0x8 > +#define XST352_BYTE2_FPS_50 0x9 > +#define XST352_BYTE2_FPS_60F 0xA > +#define XST352_BYTE2_FPS_60 0xB > +/* Table 4 ST 2081-10:2015 */ > +#define XST352_BYTE2_FPS_96 0xC > +#define XST352_BYTE2_FPS_100 0xD > +#define XST352_BYTE2_FPS_120 0xE > +#define XST352_BYTE2_FPS_120F 0xF > + > +#define XST352_BYTE3_ACT_LUMA_COUNT_MASK BIT(22) > +#define XST352_BYTE3_ACT_LUMA_COUNT_OFFSET 22 > + > +#define XST352_BYTE3_COLOR_FORMAT_MASK GENMASK(19, 16) > +#define XST352_BYTE3_COLOR_FORMAT_OFFSET 16 > +#define XST352_BYTE3_COLOR_FORMAT_422 0x0 > +#define XST352_BYTE3_COLOR_FORMAT_YUV444 0x1 > +#define XST352_BYTE3_COLOR_FORMAT_420 0x3 > +#define XST352_BYTE3_COLOR_FORMAT_GBR 0x2 > + > +#define XST352_BYTE4_BIT_DEPTH_MASK GENMASK(25, 24) > +#define XST352_BYTE4_BIT_DEPTH_OFFSET 24 > +#define XST352_BYTE4_BIT_DEPTH_10 0x1 > +#define XST352_BYTE4_BIT_DEPTH_12 0x2 > + > +#define CLK_INT 148500000UL > + > +#define rshift_and_mask(val, type) \ > + (((val) >> type##_OFFSET) & type##_MASK) > + > +#define mask_and_rshift(val, type) \ > + (((val) & type##_MASK) >> type##_OFFSET) How about using FIELD_GET() from linux/bitfield.h ? It's more standard, and will thus be less confusing to readers. > + > +/** > + * enum sdi_family_enc - SDI Transport Video Format Detected with Active Pixels > + * @XSDIRX_SMPTE_ST_274: SMPTE ST 274 detected with AP 1920x1080 > + * @XSDIRX_SMPTE_ST_296: SMPTE ST 296 detected with AP 1280x720 > + * @XSDIRX_SMPTE_ST_2048_2: SMPTE ST 2048-2 detected with AP 2048x1080 > + * @XSDIRX_SMPTE_ST_295: SMPTE ST 295 detected with AP 1920x1080 > + * @XSDIRX_NTSC: NTSC encoding detected with AP 720x486 > + * @XSDIRX_PAL: PAL encoding detected with AP 720x576 > + * @XSDIRX_TS_UNKNOWN: Unknown SMPTE Transport family type > + */ > +enum sdi_family_enc { > + XSDIRX_SMPTE_ST_274 = 0, > + XSDIRX_SMPTE_ST_296 = 1, > + XSDIRX_SMPTE_ST_2048_2 = 2, > + XSDIRX_SMPTE_ST_295 = 3, > + XSDIRX_NTSC = 8, > + XSDIRX_PAL = 9, > + XSDIRX_TS_UNKNOWN = 15 > +}; This should ideally go in a header file shared between the SDI RX and TX, as it's part of the UHD-SDI IP core, but it can be done later. > + > +/** > + * struct xsdirxss_core - Core configuration SDI Rx Subsystem device structure > + * @dev: Platform structure > + * @iomem: Base address of subsystem > + * @irq: requested irq number > + * @include_edh: EDH processor presence > + * @mode: 3G/6G/12G mode > + * @clks: array of clocks > + * @num_clks: number of clocks > + * @bpc: Bits per component, can be 10 or 12 > + */ > +struct xsdirxss_core { > + struct device *dev; > + void __iomem *iomem; > + int irq; > + bool include_edh; > + int mode; > + struct clk_bulk_data *clks; > + int num_clks; num_clks is never negative, you can make it an unsigned int. > + u32 bpc; > +}; > + > +/** > + * struct xsdirxss_state - SDI Rx Subsystem device structure > + * @core: Core structure for MIPI SDI Rx Subsystem > + * @subdev: The v4l2 subdev structure > + * @ctrl_handler: control handler > + * @event: Holds the video unlock event > + * @format: Active V4L2 format on source pad > + * @default_format: default V4L2 media bus format > + * @frame_interval: Captures the frame rate > + * @pad: source media pad > + * @vidlockwin: Video lock window value set by control > + * @edhmask: EDH mask set by control > + * @searchmask: Search mask set by control > + * @streaming: Flag for storing streaming state > + * @vidlocked: Flag indicating SDI Rx has locked onto video stream > + * @ts_is_interlaced: Flag indicating Transport Stream is interlaced. > + * @framer_enable: Flag for framer enabled or not set by control > + * > + * This structure contains the device driver related parameters > + */ > +struct xsdirxss_state { > + struct xsdirxss_core core; > + struct v4l2_subdev subdev; > + struct v4l2_ctrl_handler ctrl_handler; > + struct v4l2_event event; Is this needed, can't it be a local variable in the function where it is used ? > + struct v4l2_mbus_framefmt format; > + struct v4l2_mbus_framefmt default_format; > + struct v4l2_fract frame_interval; > + struct media_pad pad; You will need two pads as there should be two ports (let's discuss it as part of patch 1/2). > + u32 vidlockwin; > + u32 edhmask; > + u16 searchmask; > + bool streaming; > + bool vidlocked; > + bool ts_is_interlaced; > + bool framer_enable; > +}; As for the CSI2-RX, splitting core and state in separate structures isn't an established practice. I think it leads to more complex code as you have to remember in which structure each field is located. > + > +/* List of clocks required by UHD-SDI Rx subsystem */ > +static const char * const xsdirxss_clks[] = { > + "s_axi_aclk", "sdi_rx_clk", "video_out_clk", > +}; > + > +/* TODO - Add YUV 444/420 and RBG 10/12 bpc mbus formats here */ s/RBG/RGB/ ? > +static const u32 xsdirxss_10bpc_mbus_fmts[] = { > + MEDIA_BUS_FMT_UYVY10_1X20, > +}; > + > +static const u32 xsdirxss_12bpc_mbus_fmts[] = { > + MEDIA_BUS_FMT_UYVY12_1X24, > +}; > + > +static const struct v4l2_dv_timings fmt_cap[] = { > + V4L2_DV_BT_SDI_720X487I60, > + V4L2_DV_BT_CEA_720X576I50, > + V4L2_DV_BT_CEA_1280X720P24, > + V4L2_DV_BT_CEA_1280X720P25, > + V4L2_DV_BT_CEA_1280X720P30, > + V4L2_DV_BT_CEA_1280X720P50, > + V4L2_DV_BT_CEA_1280X720P60, > + V4L2_DV_BT_CEA_1920X1080P24, > + V4L2_DV_BT_CEA_1920X1080P30, > + V4L2_DV_BT_CEA_1920X1080I50, > + V4L2_DV_BT_CEA_1920X1080I60, > + V4L2_DV_BT_CEA_1920X1080P50, > + V4L2_DV_BT_CEA_1920X1080P60, > + V4L2_DV_BT_CEA_3840X2160P24, > + V4L2_DV_BT_CEA_3840X2160P30, > + V4L2_DV_BT_CEA_3840X2160P50, > + V4L2_DV_BT_CEA_3840X2160P60, > + V4L2_DV_BT_CEA_4096X2160P24, > + V4L2_DV_BT_CEA_4096X2160P25, > + V4L2_DV_BT_CEA_4096X2160P30, > + V4L2_DV_BT_CEA_4096X2160P50, > + V4L2_DV_BT_CEA_4096X2160P60, > + > + XLNX_V4L2_DV_BT_2048X1080P24, > + XLNX_V4L2_DV_BT_2048X1080P25, > + XLNX_V4L2_DV_BT_2048X1080P30, > + XLNX_V4L2_DV_BT_2048X1080I48, > + XLNX_V4L2_DV_BT_2048X1080I50, > + XLNX_V4L2_DV_BT_2048X1080I60, > + XLNX_V4L2_DV_BT_2048X1080P48, > + XLNX_V4L2_DV_BT_2048X1080P50, > + XLNX_V4L2_DV_BT_2048X1080P60, > + XLNX_V4L2_DV_BT_1920X1080P48, > + XLNX_V4L2_DV_BT_1920X1080I48, > + XLNX_V4L2_DV_BT_3840X2160P48, > + XLNX_V4L2_DV_BT_4096X2160P48, > +}; > + > +struct xsdirxss_dv_map { > + u32 width; > + u32 height; > + u32 fps; > + struct v4l2_dv_timings format; > +}; > + > +static const struct xsdirxss_dv_map xsdirxss_dv_timings[] = { > + /* SD - 720x487i60 */ > + { 720, 243, 30, V4L2_DV_BT_SDI_720X487I60 }, > + /* SD - 720x576i50 */ > + { 720, 288, 25, V4L2_DV_BT_CEA_720X576I50 }, > + /* HD - 1280x720p23.98 */ > + /* HD - 1280x720p24 */ > + { 1280, 720, 24, V4L2_DV_BT_CEA_1280X720P24 }, > + /* HD - 1280x720p25 */ > + { 1280, 720, 25, V4L2_DV_BT_CEA_1280X720P25 }, > + /* HD - 1280x720p29.97 */ > + /* HD - 1280x720p30 */ > + { 1280, 720, 30, V4L2_DV_BT_CEA_1280X720P30 }, > + /* HD - 1280x720p50 */ > + { 1280, 720, 50, V4L2_DV_BT_CEA_1280X720P50 }, > + /* HD - 1280x720p59.94 */ > + /* HD - 1280x720p60 */ > + { 1280, 720, 60, V4L2_DV_BT_CEA_1280X720P60 }, > + /* HD - 1920x1080p23.98 */ > + /* HD - 1920x1080p24 */ > + { 1920, 1080, 24, V4L2_DV_BT_CEA_1920X1080P24 }, > + /* HD - 1920x1080p25 */ > + { 1920, 1080, 25, V4L2_DV_BT_CEA_1920X1080P25 }, > + /* HD - 1920x1080p29.97 */ > + /* HD - 1920x1080p30 */ > + { 1920, 1080, 30, V4L2_DV_BT_CEA_1920X1080P30 }, > + > + /* HD - 2048x1080p23.98 */ > + /* HD - 2048x1080p24 */ > + { 2048, 1080, 24, XLNX_V4L2_DV_BT_2048X1080P24 }, > + /* HD - 2048x1080p25 */ > + { 2048, 1080, 24, XLNX_V4L2_DV_BT_2048X1080P25 }, > + /* HD - 2048x1080p29.97 */ > + /* HD - 2048x1080p30 */ > + { 2048, 1080, 24, XLNX_V4L2_DV_BT_2048X1080P30 }, > + /* HD - 1920x1080i47.95 */ > + /* HD - 1920x1080i48 */ > + { 1920, 540, 24, XLNX_V4L2_DV_BT_1920X1080I48 }, > + > + /* HD - 1920x1080i50 */ > + { 1920, 540, 25, V4L2_DV_BT_CEA_1920X1080I50 }, > + /* HD - 1920x1080i59.94 */ > + /* HD - 1920x1080i60 */ > + { 1920, 540, 30, V4L2_DV_BT_CEA_1920X1080I60 }, > + > + /* HD - 2048x1080i47.95 */ > + /* HD - 2048x1080i48 */ > + { 2048, 540, 24, XLNX_V4L2_DV_BT_2048X1080I48 }, > + /* HD - 2048x1080i50 */ > + { 2048, 540, 25, XLNX_V4L2_DV_BT_2048X1080I50 }, > + /* HD - 2048x1080i59.94 */ > + /* HD - 2048x1080i60 */ > + { 2048, 540, 30, XLNX_V4L2_DV_BT_2048X1080I60 }, > + /* 3G - 1920x1080p47.95 */ > + /* 3G - 1920x1080p48 */ > + { 1920, 1080, 48, XLNX_V4L2_DV_BT_1920X1080P48 }, > + > + /* 3G - 1920x1080p50 148.5 */ > + { 1920, 1080, 50, V4L2_DV_BT_CEA_1920X1080P50 }, > + /* 3G - 1920x1080p59.94 148.5/1.001 */ > + /* 3G - 1920x1080p60 148.5 */ > + { 1920, 1080, 60, V4L2_DV_BT_CEA_1920X1080P60 }, > + > + /* 3G - 2048x1080p47.95 */ > + /* 3G - 2048x1080p48 */ > + { 2048, 1080, 48, XLNX_V4L2_DV_BT_2048X1080P48 }, > + /* 3G - 2048x1080p50 */ > + { 2048, 1080, 50, XLNX_V4L2_DV_BT_2048X1080P50 }, > + /* 3G - 2048x1080p59.94 */ > + /* 3G - 2048x1080p60 */ > + { 2048, 1080, 60, XLNX_V4L2_DV_BT_2048X1080P60 }, > + > + /* 6G - 3840X2160p23.98 */ > + /* 6G - 3840X2160p24 */ > + { 3840, 2160, 24, V4L2_DV_BT_CEA_3840X2160P24 }, > + /* 6G - 3840X2160p25 */ > + { 3840, 2160, 25, V4L2_DV_BT_CEA_3840X2160P25 }, > + /* 6G - 3840X2160p29.97 */ > + /* 6G - 3840X2160p30 */ > + { 3840, 2160, 30, V4L2_DV_BT_CEA_3840X2160P30 }, > + /* 6G - 4096X2160p23.98 */ > + /* 6G - 4096X2160p24 */ > + { 4096, 2160, 24, V4L2_DV_BT_CEA_4096X2160P24 }, > + /* 6G - 4096X2160p25 */ > + { 4096, 2160, 25, V4L2_DV_BT_CEA_4096X2160P25 }, > + /* 6G - 4096X2160p29.97 */ > + /* 6G - 4096X2160p30 */ > + { 4096, 2160, 30, V4L2_DV_BT_CEA_4096X2160P30 }, > + /* 12G - 3840X2160p47.95 */ > + /* 12G - 3840X2160p48 */ > + { 3840, 2160, 48, XLNX_V4L2_DV_BT_3840X2160P48 }, > + > + /* 12G - 3840X2160p50 */ > + { 3840, 2160, 50, V4L2_DV_BT_CEA_3840X2160P50 }, > + /* 12G - 3840X2160p59.94 */ > + /* 12G - 3840X2160p60 */ > + { 3840, 2160, 60, V4L2_DV_BT_CEA_3840X2160P60 }, > + > + /* 12G - 4096X2160p47.95 */ > + /* 12G - 4096X2160p48 */ > + { 3840, 2160, 48, XLNX_V4L2_DV_BT_4096X2160P48 }, > + > + /* 12G - 4096X2160p50 */ > + { 4096, 2160, 50, V4L2_DV_BT_CEA_4096X2160P50 }, > + /* 12G - 4096X2160p59.94 */ > + /* 12G - 4096X2160p60 */ > + { 4096, 2160, 60, V4L2_DV_BT_CEA_4096X2160P60 }, > +}; > + > +static inline struct xsdirxss_state * > +to_xsdirxssstate(struct v4l2_subdev *subdev) > +{ > + return container_of(subdev, struct xsdirxss_state, subdev); > +} > + > +/* > + * Register related operations > + */ > +static inline u32 xsdirxss_read(struct xsdirxss_core *xsdirxss, u32 addr) > +{ > + return ioread32(xsdirxss->iomem + addr); > +} > + > +static inline void xsdirxss_write(struct xsdirxss_core *xsdirxss, u32 addr, > + u32 value) > +{ > + iowrite32(value, xsdirxss->iomem + addr); > +} > + > +static inline void xsdirxss_clr(struct xsdirxss_core *xsdirxss, u32 addr, > + u32 clr) > +{ > + xsdirxss_write(xsdirxss, addr, xsdirxss_read(xsdirxss, addr) & ~clr); > +} > + > +static inline void xsdirxss_set(struct xsdirxss_core *xsdirxss, u32 addr, > + u32 set) > +{ > + xsdirxss_write(xsdirxss, addr, xsdirxss_read(xsdirxss, addr) | set); > +} > + > +static inline void xsdirx_core_disable(struct xsdirxss_core *core) > +{ > + xsdirxss_clr(core, XSDIRX_RST_CTRL_REG, XSDIRX_RST_CTRL_SS_EN_MASK); > +} > + > +static inline void xsdirx_core_enable(struct xsdirxss_core *core) > +{ > + xsdirxss_set(core, XSDIRX_RST_CTRL_REG, XSDIRX_RST_CTRL_SS_EN_MASK); > +} > + > +static int xsdirx_set_modedetect(struct xsdirxss_core *core, u16 mask) > +{ > + u32 val; > + struct device *dev = core->dev; > + > + mask &= XSDIRX_DETECT_ALL_MODES; > + if (!mask) { > + dev_err(dev, "Invalid bit mask = 0x%08x\n", mask); > + return -EINVAL; > + } > + > + dev_dbg(dev, "mask = 0x%x\n", mask); > + > + val = xsdirxss_read(core, XSDIRX_MDL_CTRL_REG); > + val &= ~XSDIRX_MDL_CTRL_MODE_DET_EN_MASK; > + val &= ~XSDIRX_MDL_CTRL_MODE_AUTO_DET_MASK; > + val &= ~XSDIRX_MDL_CTRL_FORCED_MODE_MASK; > + > + if (hweight16(mask) > 1) { > + /* Multi mode detection as more than 1 bit set in mask */ > + dev_dbg(dev, "Detect multiple modes\n"); > + > + if (mask & BIT(XSDIRX_MODE_SD_OFFSET)) > + val |= XSDIRX_MDL_CTRL_MODE_SD_EN_MASK; > + if (mask & BIT(XSDIRX_MODE_HD_OFFSET)) > + val |= XSDIRX_MDL_CTRL_MODE_HD_EN_MASK; > + if (mask & BIT(XSDIRX_MODE_3G_OFFSET)) > + val |= XSDIRX_MDL_CTRL_MODE_3G_EN_MASK; > + if (mask & BIT(XSDIRX_MODE_6G_OFFSET)) > + val |= XSDIRX_MDL_CTRL_MODE_6G_EN_MASK; > + if (mask & BIT(XSDIRX_MODE_12GI_OFFSET)) > + val |= XSDIRX_MDL_CTRL_MODE_12GI_EN_MASK; > + if (mask & BIT(XSDIRX_MODE_12GF_OFFSET)) > + val |= XSDIRX_MDL_CTRL_MODE_12GF_EN_MASK; > + > + val |= XSDIRX_MDL_CTRL_MODE_DET_EN_MASK; > + } else { > + /* Fixed Mode */ > + u32 forced_mode_mask; > + > + dev_dbg(dev, "Detect fixed mode\n"); > + > + /* Find offset of first bit set */ > + switch (__ffs(mask)) { > + case XSDIRX_MODE_SD_OFFSET: > + forced_mode_mask = XSDIRX_MODE_SD_MASK; > + break; > + case XSDIRX_MODE_HD_OFFSET: > + forced_mode_mask = XSDIRX_MODE_HD_MASK; > + break; > + case XSDIRX_MODE_3G_OFFSET: > + forced_mode_mask = XSDIRX_MODE_3G_MASK; > + break; > + case XSDIRX_MODE_6G_OFFSET: > + forced_mode_mask = XSDIRX_MODE_6G_MASK; > + break; > + case XSDIRX_MODE_12GI_OFFSET: > + forced_mode_mask = XSDIRX_MODE_12GI_MASK; > + break; > + case XSDIRX_MODE_12GF_OFFSET: > + forced_mode_mask = XSDIRX_MODE_12GF_MASK; > + break; > + default: > + forced_mode_mask = 0; > + } > + dev_dbg(dev, "Forced Mode Mask : 0x%x\n", > + forced_mode_mask); > + val |= forced_mode_mask << XSDIRX_MDL_CTRL_FORCED_MODE_OFFSET; > + } > + > + dev_dbg(dev, "Modes to be detected : sdi ctrl reg = 0x%08x\n", > + val); > + xsdirxss_write(core, XSDIRX_MDL_CTRL_REG, val); > + > + return 0; > +} > + > +static void xsdirx_framer(struct xsdirxss_core *core, bool flag) > +{ > + if (flag) > + xsdirxss_set(core, XSDIRX_MDL_CTRL_REG, > + XSDIRX_MDL_CTRL_FRM_EN_MASK); > + else > + xsdirxss_clr(core, XSDIRX_MDL_CTRL_REG, > + XSDIRX_MDL_CTRL_FRM_EN_MASK); > +} > + > +static void xsdirx_setedherrcnttrigger(struct xsdirxss_core *core, u32 enable) That's a hard to read function name. Could you separate words with underscores ? Same for functions below that concatenate multiple words together. > +{ > + u32 val = xsdirxss_read(core, XSDIRX_EDH_ERRCNT_EN_REG); > + > + val = enable & XSDIRX_EDH_ALLERR_MASK; > + > + xsdirxss_write(core, XSDIRX_EDH_ERRCNT_EN_REG, val); > +} > + > +static inline void xsdirx_setvidlockwindow(struct xsdirxss_core *core, u32 val) > +{ > + /* > + * The video lock window is the amount of time for which the > + * the mode and transport stream should be locked to get the > + * video lock interrupt. > + */ > + xsdirxss_write(core, XSDIRX_VID_LOCK_WINDOW_REG, val); > +} > + > +static inline void xsdirx_disableintr(struct xsdirxss_core *core, u32 mask) > +{ > + xsdirxss_clr(core, XSDIRX_IER_REG, mask); > +} > + > +static inline void xsdirx_enableintr(struct xsdirxss_core *core, u32 mask) > +{ > + xsdirxss_set(core, XSDIRX_IER_REG, mask); > +} > + > +static void xsdirx_globalintr(struct xsdirxss_core *core, bool flag) > +{ > + if (flag) > + xsdirxss_set(core, XSDIRX_GLBL_IER_REG, > + XSDIRX_GLBL_INTR_EN_MASK); > + else > + xsdirxss_clr(core, XSDIRX_GLBL_IER_REG, > + XSDIRX_GLBL_INTR_EN_MASK); > +} > + > +static inline void xsdirx_clearintr(struct xsdirxss_core *core, u32 mask) > +{ > + xsdirxss_set(core, XSDIRX_ISR_REG, mask); > +} > + > +static void xsdirx_vid_bridge_control(struct xsdirxss_core *core, > + bool enable) > +{ > + u32 mask = XSDIRX_RST_CTRL_SDIRX_BRIDGE_ENB_MASK; > + > + /* > + * TODO - Enable YUV444/RBG format in the bridge based > + * on BYTE3 color format. > + * XSDIRX_RST_CTRL_BRIDGE_CH_FMT_YUV444 > + */ > + if (enable) > + xsdirxss_set(core, XSDIRX_RST_CTRL_REG, mask); > + else > + xsdirxss_clr(core, XSDIRX_RST_CTRL_REG, mask); > +} This is only used in xsdirx_streamflow_control(), inlining it manually would be simpler I think. > + > +static void xsdirx_axis4_bridge_control(struct xsdirxss_core *core, > + bool enable) > +{ > + if (enable) > + xsdirxss_set(core, XSDIRX_RST_CTRL_REG, > + XSDIRX_RST_CTRL_VIDIN_AXI4S_MOD_ENB_MASK); > + else > + xsdirxss_clr(core, XSDIRX_RST_CTRL_REG, > + XSDIRX_RST_CTRL_VIDIN_AXI4S_MOD_ENB_MASK); > +} Same for this one. > + > +static void xsdirx_streamflow_control(struct xsdirxss_core *core, bool enable) > +{ > + /* The sdi to native bridge is followed by native to axis4 bridge */ > + if (enable) { > + xsdirx_axis4_bridge_control(core, enable); > + xsdirx_vid_bridge_control(core, enable); > + } else { > + xsdirx_vid_bridge_control(core, enable); > + xsdirx_axis4_bridge_control(core, enable); > + } > +} > + > +static void xsdirxss_get_framerate(struct v4l2_fract *frame_interval, > + u32 framerate) > +{ > + switch (framerate) { > + case XSDIRX_TS_DET_STAT_RATE_23_98HZ: > + frame_interval->numerator = 1001; > + frame_interval->denominator = 24000; > + break; > + case XSDIRX_TS_DET_STAT_RATE_24HZ: > + frame_interval->numerator = 1000; > + frame_interval->denominator = 24000; > + break; > + case XSDIRX_TS_DET_STAT_RATE_25HZ: > + frame_interval->numerator = 1000; > + frame_interval->denominator = 25000; > + break; > + case XSDIRX_TS_DET_STAT_RATE_29_97HZ: > + frame_interval->numerator = 1001; > + frame_interval->denominator = 30000; > + break; > + case XSDIRX_TS_DET_STAT_RATE_30HZ: > + frame_interval->numerator = 1000; > + frame_interval->denominator = 30000; > + break; > + case XSDIRX_TS_DET_STAT_RATE_47_95HZ: > + frame_interval->numerator = 1001; > + frame_interval->denominator = 48000; > + break; > + case XSDIRX_TS_DET_STAT_RATE_48HZ: > + frame_interval->numerator = 1000; > + frame_interval->denominator = 48000; > + break; > + case XSDIRX_TS_DET_STAT_RATE_50HZ: > + frame_interval->numerator = 1000; > + frame_interval->denominator = 50000; > + break; > + case XSDIRX_TS_DET_STAT_RATE_59_94HZ: > + frame_interval->numerator = 1001; > + frame_interval->denominator = 60000; > + break; > + case XSDIRX_TS_DET_STAT_RATE_60HZ: > + frame_interval->numerator = 1000; > + frame_interval->denominator = 60000; > + break; > + default: > + frame_interval->numerator = 1; > + frame_interval->denominator = 1; > + } > +} > + > +static void xsdirxss_set_gtclk(struct xsdirxss_state *state) > +{ > + struct clk *gtclk; > + unsigned long clkrate; > + int ret, is_frac; > + struct xsdirxss_core *core = &state->core; > + u32 mode; > + static int prev_is_frac = -1; > + > + mode = xsdirxss_read(core, XSDIRX_MODE_DET_STAT_REG); > + mode &= XSDIRX_MODE_DET_STAT_RX_MODE_MASK; > + > + /* > + * TODO: For now, don't change the clock rate for any mode except 12G. > + * In future, configure gt clock for all modes and enable clock only > + * when needed (stream on/off). > + */ > + if (mode != XSDIRX_MODE_12GI_MASK && mode != XSDIRX_MODE_12GF_MASK) > + return; > + > + is_frac = state->frame_interval.numerator == 1001 ? 1 : 0; > + > + if (prev_is_frac == is_frac) > + return; > + > + xsdirx_core_disable(core); > + xsdirx_globalintr(core, false); > + xsdirx_disableintr(core, XSDIRX_INTR_ALL_MASK); > + > + /* get sdi_rx_clk */ > + gtclk = core->clks[1].clk; > + clkrate = clk_get_rate(gtclk); > + is_frac = state->frame_interval.numerator == 1001 ? 1 : 0; > + > + /* calcualte clkrate */ s/calcualte/calculate/ > + if (!is_frac) > + clkrate = CLK_INT; > + else > + clkrate = (CLK_INT * 1000) / 1001; Shouldn't the clock rate also depend on the mode ? Table 3-2 lists different clock rates for HD-SDI and 12G-SDI. > + > + ret = clk_set_rate(gtclk, clkrate); > + if (ret) > + dev_err(core->dev, "failed to set clk rate = %d\n", ret); > + > + clkrate = clk_get_rate(gtclk); > + > + dev_dbg(core->dev, "clkrate = %lu is_frac = %d\n", > + clkrate, is_frac); > + > + xsdirx_framer(core, state->framer_enable); As this is called in both the IRQ handler and the s_ctrl handler, you could have a race when accessing the XSDIRX_MDL_CTRL_REG register. You will need to protect all accesses to registers that are written from both the IRQ handler and userspace contexts with a spinlock. > + xsdirx_setedherrcnttrigger(core, state->edhmask); > + xsdirx_setvidlockwindow(core, state->vidlockwin); > + xsdirx_set_modedetect(core, state->searchmask); > + xsdirx_enableintr(core, XSDIRX_INTR_ALL_MASK); > + xsdirx_globalintr(core, true); > + xsdirx_core_enable(core); > + > + prev_is_frac = is_frac; That's lots of work done in an interrupt handler. As this function is called when a stream lock is detected, if the clock rate has to be changed, do I assume correctly that the resolution may have changed too ? That may require reconfiguring the pipeline and reallocating buffers. With SD and HD TV, I think the usual practice is to notify userspace of video lock and let it do the reconfiguration is required, instead of attempting to do so automatically. Hans, is that correct ? How would we handle then the case where the pipeline is already correctly configured with big enough buffers (I'm not sure this can actually happen, for the buffers yes, but for the pipeline configuration, maybe the format will always need to change) ? And I've now seen that we do emit the V4L2_EVENT_SRC_CH_RESOLUTION event :-) Do we thus need to reconfigure the IP core here ? > +} > + > +/** > + * xsdirx_get_stream_properties - Get SDI Rx stream properties > + * @state: pointer to driver state > + * > + * This function decodes the stream's ST352 payload (if available) to get > + * stream properties like width, height, picture type (interlaced/progressive), > + * etc. > + * > + * Return: 0 for success else errors > + */ > +static int xsdirx_get_stream_properties(struct xsdirxss_state *state) > +{ > + struct xsdirxss_core *core = &state->core; > + struct device *dev = core->dev; > + u32 mode, payload = 0, val, family, valid, tscan; > + u8 byte1 = 0, active_luma = 0, pic_type = 0, framerate = 0; > + u8 sampling = XST352_BYTE3_COLOR_FORMAT_422; > + struct v4l2_mbus_framefmt *format = &state->format; > + u32 bpc = XST352_BYTE4_BIT_DEPTH_10; > + > + mode = xsdirxss_read(core, XSDIRX_MODE_DET_STAT_REG); > + mode &= XSDIRX_MODE_DET_STAT_RX_MODE_MASK; > + > + valid = xsdirxss_read(core, XSDIRX_ST352_VALID_REG); > + > + if (mode >= XSDIRX_MODE_3G_MASK && !valid) { > + dev_err(dev, "No valid ST352 payload present even for 3G mode and above\n"); > + return -EINVAL; > + } > + > + val = xsdirxss_read(core, XSDIRX_TS_DET_STAT_REG); > + if (valid & XSDIRX_ST352_VALID_DS1_MASK) { > + payload = xsdirxss_read(core, XSDIRX_ST352_DS1_REG); > + byte1 = rshift_and_mask(payload, XST352_PAYLOAD_BYTE1); > + active_luma = mask_and_rshift(payload, > + XST352_BYTE3_ACT_LUMA_COUNT); > + pic_type = mask_and_rshift(payload, XST352_BYTE2_PIC_TYPE); > + framerate = rshift_and_mask(payload, XST352_BYTE2_FPS); > + tscan = mask_and_rshift(payload, XST352_BYTE2_TS_TYPE); > + sampling = mask_and_rshift(payload, XST352_BYTE3_COLOR_FORMAT); > + bpc = mask_and_rshift(payload, XST352_BYTE4_BIT_DEPTH); > + } else { > + dev_dbg(dev, "No ST352 payload available : Mode = %d\n", mode); > + framerate = mask_and_rshift(val, XSDIRX_TS_DET_STAT_RATE); > + tscan = mask_and_rshift(val, XSDIRX_TS_DET_STAT_SCAN); > + } > + > + if ((bpc == XST352_BYTE4_BIT_DEPTH_10 && core->bpc != 10) || > + (bpc == XST352_BYTE4_BIT_DEPTH_12 && core->bpc != 12)) { > + dev_dbg(dev, "Bit depth not supported. bpc = %d core->bpc = %d\n", > + bpc, core->bpc); > + return -EINVAL; > + } > + > + family = mask_and_rshift(val, XSDIRX_TS_DET_STAT_FAMILY); > + state->ts_is_interlaced = tscan ? false : true; > + > + dev_dbg(dev, "ts_is_interlaced = %d, family = %d\n", > + state->ts_is_interlaced, family); > + > + switch (mode) { > + case XSDIRX_MODE_HD_MASK: > + if (!valid) { > + /* No payload obtained */ > + dev_dbg(dev, "frame rate : %d, tscan = %d\n", > + framerate, tscan); > + /* > + * NOTE : A progressive segmented frame pSF will be > + * reported incorrectly as Interlaced as we rely on IP's > + * transport scan locked bit. > + */ > + dev_warn(dev, "pSF will be incorrectly reported as Interlaced\n"); > + > + switch (framerate) { > + case XSDIRX_TS_DET_STAT_RATE_23_98HZ: > + case XSDIRX_TS_DET_STAT_RATE_24HZ: > + case XSDIRX_TS_DET_STAT_RATE_25HZ: > + case XSDIRX_TS_DET_STAT_RATE_29_97HZ: > + case XSDIRX_TS_DET_STAT_RATE_30HZ: > + if (family == XSDIRX_SMPTE_ST_296) { > + format->width = 1280; > + format->height = 720; > + format->field = V4L2_FIELD_NONE; > + } else if (family == XSDIRX_SMPTE_ST_2048_2) { > + format->width = 2048; > + format->height = 1080; > + if (tscan) > + format->field = V4L2_FIELD_NONE; > + else > + format->field = > + V4L2_FIELD_ALTERNATE; > + } else { > + format->width = 1920; > + format->height = 1080; > + if (tscan) > + format->field = V4L2_FIELD_NONE; > + else > + format->field = > + V4L2_FIELD_ALTERNATE; > + } > + break; > + case XSDIRX_TS_DET_STAT_RATE_50HZ: > + case XSDIRX_TS_DET_STAT_RATE_59_94HZ: > + case XSDIRX_TS_DET_STAT_RATE_60HZ: > + if (family == XSDIRX_SMPTE_ST_274) { > + format->width = 1920; > + format->height = 1080; > + } else { > + format->width = 1280; > + format->height = 720; > + } > + format->field = V4L2_FIELD_NONE; > + break; > + default: > + format->width = 1920; > + format->height = 1080; > + format->field = V4L2_FIELD_NONE; > + } > + } else { > + dev_dbg(dev, "Got the payload\n"); > + switch (byte1) { > + case XST352_BYTE1_ST292_1x720L_1_5G: > + /* SMPTE ST 292-1 for 720 line payloads */ > + format->width = 1280; > + format->height = 720; > + break; > + case XST352_BYTE1_ST292_1x1080L_1_5G: > + /* SMPTE ST 292-1 for 1080 line payloads */ > + format->height = 1080; > + if (active_luma) > + format->width = 2048; > + else > + format->width = 1920; > + break; > + default: > + dev_dbg(dev, "Unknown HD Mode SMPTE standard\n"); > + return -EINVAL; > + } > + } > + break; > + case XSDIRX_MODE_SD_MASK: > + format->field = V4L2_FIELD_ALTERNATE; > + > + switch (family) { > + case XSDIRX_NTSC: > + format->width = 720; > + format->height = 486; > + break; > + case XSDIRX_PAL: > + format->width = 720; > + format->height = 576; > + break; > + default: > + dev_dbg(dev, "Unknown SD Mode SMPTE standard\n"); > + return -EINVAL; > + } > + break; > + case XSDIRX_MODE_3G_MASK: > + switch (byte1) { > + case XST352_BYTE1_ST425_2008_750L_3GB: > + /* Sec 4.1.6.1 SMPTE 425-2008 */ > + case XST352_BYTE1_ST372_2x720L_3GB: > + /* Table 13 SMPTE 425-2008 */ > + format->width = 1280; > + format->height = 720; > + break; > + case XST352_BYTE1_ST425_2008_1125L_3GA: > + /* ST352 Table SMPTE 425-1 */ > + case XST352_BYTE1_ST372_DL_3GB: > + /* Table 13 SMPTE 425-2008 */ > + case XST352_BYTE1_ST372_2x1080L_3GB: > + /* Table 13 SMPTE 425-2008 */ > + format->height = 1080; > + if (active_luma) > + format->width = 2048; > + else > + format->width = 1920; > + break; > + default: > + dev_dbg(dev, "Unknown 3G Mode SMPTE standard\n"); > + return -EINVAL; > + } > + break; > + case XSDIRX_MODE_6G_MASK: > + switch (byte1) { > + case XST352_BYTE1_ST2081_10_DL_2160L_6G: > + /* Dual link 6G */ > + case XST352_BYTE1_ST2081_10_2160L_6G: > + /* Table 3 SMPTE ST 2081-10 */ > + format->height = 2160; > + if (active_luma) > + format->width = 4096; > + else > + format->width = 3840; > + break; > + case XST352_BYTE1_ST2081_10_2_1080L_6G: > + format->height = 1080; > + if (active_luma) > + format->width = 2048; > + else > + format->width = 1920; > + break; > + default: > + dev_dbg(dev, "Unknown 6G Mode SMPTE standard\n"); > + return -EINVAL; > + } > + break; > + case XSDIRX_MODE_12GI_MASK: > + case XSDIRX_MODE_12GF_MASK: > + switch (byte1) { > + case XST352_BYTE1_ST2082_10_2160L_12G: > + /* Section 4.3.1 SMPTE ST 2082-10 */ > + format->height = 2160; > + if (active_luma) > + format->width = 4096; > + else > + format->width = 3840; > + break; > + default: > + dev_dbg(dev, "Unknown 12G Mode SMPTE standard\n"); > + return -EINVAL; > + } > + break; > + default: > + dev_err(dev, "Invalid Mode\n"); > + return -EINVAL; > + } > + > + if (valid) { > + if (pic_type) > + format->field = V4L2_FIELD_NONE; > + else > + format->field = V4L2_FIELD_ALTERNATE; > + > + if (format->height == 1080 && pic_type && !tscan) > + format->field = V4L2_FIELD_ALTERNATE; > + > + /* > + * In 3GB DL pSF mode the video is similar to interlaced. > + * So though it is a progressive video, its transport is > + * interlaced and is sent as two width x (height/2) buffers. > + */ > + if (byte1 == XST352_BYTE1_ST372_DL_3GB) { > + if (state->ts_is_interlaced) > + format->field = V4L2_FIELD_ALTERNATE; > + else > + format->field = V4L2_FIELD_NONE; > + } > + } > + > + if (format->field == V4L2_FIELD_ALTERNATE) > + format->height = format->height / 2; > + > + switch (sampling) { > + case XST352_BYTE3_COLOR_FORMAT_422: > + if (core->bpc == 10) > + format->code = MEDIA_BUS_FMT_UYVY10_1X20; > + else > + format->code = MEDIA_BUS_FMT_UYVY12_1X24; > + break; > + case XST352_BYTE3_COLOR_FORMAT_420: > + case XST352_BYTE3_COLOR_FORMAT_YUV444: > + case XST352_BYTE3_COLOR_FORMAT_GBR: > + format->code = 0; > + dev_dbg(dev, "No corresponding media bus formats\n"); > + break; > + default: > + dev_err(dev, "Unsupported color format : %d\n", sampling); > + return -EINVAL; > + } > + > + xsdirxss_get_framerate(&state->frame_interval, framerate); > + > + dev_dbg(dev, "Stream width = %d height = %d Field = %d payload = 0x%08x ts = 0x%08x\n", > + format->width, format->height, format->field, payload, val); > + dev_dbg(dev, "frame rate numerator = %d denominator = %d\n", > + state->frame_interval.numerator, > + state->frame_interval.denominator); > + dev_dbg(dev, "Stream code = 0x%x\n", format->code); > + return 0; > +} > + > +/** > + * xsdirxss_irq_handler - Interrupt handler for SDI Rx > + * @irq: IRQ number > + * @dev_id: Pointer to device state > + * > + * The SDI Rx interrupts are cleared by writing 1 to corresponding bit. > + * > + * Return: IRQ_HANDLED after handling interrupts > + */ > +static irqreturn_t xsdirxss_irq_handler(int irq, void *dev_id) > +{ > + struct xsdirxss_state *state = (struct xsdirxss_state *)dev_id; > + struct xsdirxss_core *core = &state->core; > + struct device *dev = core->dev; > + u32 status; > + > + status = xsdirxss_read(core, XSDIRX_ISR_REG); > + xsdirxss_write(core, XSDIRX_ISR_REG, status); > + dev_dbg(dev, "interrupt status = 0x%08x\n", status); > + > + if (status & XSDIRX_INTR_VIDLOCK_MASK || > + status & XSDIRX_INTR_VIDUNLOCK_MASK) { > + u32 val1, val2; > + > + dev_dbg(dev, "video lock/unlock interrupt\n"); > + > + xsdirx_streamflow_control(core, false); > + state->streaming = false; > + > + val1 = xsdirxss_read(core, XSDIRX_MODE_DET_STAT_REG); > + val2 = xsdirxss_read(core, XSDIRX_TS_DET_STAT_REG); > + > + if ((val1 & XSDIRX_MODE_DET_STAT_MODE_LOCK_MASK) && > + (val2 & XSDIRX_TS_DET_STAT_LOCKED_MASK)) { > + u32 mask = XSDIRX_RST_CTRL_RST_CRC_ERRCNT_MASK | > + XSDIRX_RST_CTRL_RST_EDH_ERRCNT_MASK; > + > + dev_dbg(dev, "video lock interrupt\n"); > + > + xsdirxss_set(core, XSDIRX_RST_CTRL_REG, mask); > + xsdirxss_clr(core, XSDIRX_RST_CTRL_REG, mask); > + > + val1 = xsdirxss_read(core, XSDIRX_ST352_VALID_REG); > + val2 = xsdirxss_read(core, XSDIRX_ST352_DS1_REG); > + > + dev_dbg(dev, "valid st352 mask = 0x%08x\n", val1); > + dev_dbg(dev, "st352 payload = 0x%08x\n", val2); > + > + if (!xsdirx_get_stream_properties(state)) { > + state->vidlocked = true; > + xsdirxss_set_gtclk(state); > + } else { > + dev_err(dev, "Unable to get stream properties!\n"); > + state->vidlocked = false; > + } > + } else { > + dev_dbg(dev, "video unlock interrupt\n"); > + state->vidlocked = false; > + } > + > + memset(&state->event, 0, sizeof(state->event)); > + state->event.type = V4L2_EVENT_SOURCE_CHANGE; > + state->event.u.src_change.changes = > + V4L2_EVENT_SRC_CH_RESOLUTION; > + v4l2_subdev_notify_event(&state->subdev, &state->event); > + } > + > + if (status & XSDIRX_INTR_UNDERFLOW_MASK) { > + dev_dbg(dev, "Video in to AXI4 Stream core underflow interrupt\n"); > + > + memset(&state->event, 0, sizeof(state->event)); > + state->event.type = V4L2_EVENT_XILINX_SDIRX_UNDERFLOW; > + v4l2_subdev_notify_event(&state->subdev, &state->event); > + } > + > + if (status & XSDIRX_INTR_OVERFLOW_MASK) { > + dev_dbg(dev, "Video in to AXI4 Stream core overflow interrupt\n"); > + > + memset(&state->event, 0, sizeof(state->event)); > + state->event.type = V4L2_EVENT_XILINX_SDIRX_OVERFLOW; > + v4l2_subdev_notify_event(&state->subdev, &state->event); > + } Can't we combine these two in a single event type, with underflow and overflow reported in the event payload in a bitmask ? > + return IRQ_HANDLED; > +} > + > +/** > + * xsdirxss_subscribe_event - Subscribe to video lock and unlock event > + * @sd: V4L2 Sub device > + * @fh: V4L2 File Handle > + * @sub: Subcribe event structure > + * > + * Return: 0 on success, errors otherwise > + */ > +static int xsdirxss_subscribe_event(struct v4l2_subdev *sd, > + struct v4l2_fh *fh, > + struct v4l2_event_subscription *sub) > +{ > + int ret; > + struct xsdirxss_state *xsdirxss = to_xsdirxssstate(sd); > + struct xsdirxss_core *core = &xsdirxss->core; > + > + switch (sub->type) { > + case V4L2_EVENT_XILINX_SDIRX_UNDERFLOW: > + case V4L2_EVENT_XILINX_SDIRX_OVERFLOW: > + ret = v4l2_event_subscribe(fh, sub, XSDIRX_MAX_EVENTS, NULL); > + break; > + case V4L2_EVENT_SOURCE_CHANGE: > + ret = v4l2_src_change_event_subscribe(fh, sub); > + break; > + default: > + return -EINVAL; As Hans commented, you need to call v4l2_ctrl_subscribe_event() here. > + } > + dev_dbg(core->dev, "Event subscribed : 0x%08x\n", sub->type); > + return ret; > +} > + > +/** > + * xsdirxss_unsubscribe_event - Unsubscribe from all events registered > + * @sd: V4L2 Sub device > + * @fh: V4L2 file handle > + * @sub: pointer to Event unsubscription structure > + * > + * Return: zero on success, else a negative error code. > + */ > +static int xsdirxss_unsubscribe_event(struct v4l2_subdev *sd, > + struct v4l2_fh *fh, > + struct v4l2_event_subscription *sub) > +{ > + struct xsdirxss_state *xsdirxss = to_xsdirxssstate(sd); > + struct xsdirxss_core *core = &xsdirxss->core; > + > + dev_dbg(core->dev, "Event unsubscribe : 0x%08x\n", sub->type); > + return v4l2_event_unsubscribe(fh, sub); > +} I think you can drop this function and use v4l2_event_subdev_unsubscribe as the ..unsubscribe_event() handler. > + > +/** > + * xsdirxss_s_ctrl - This is used to set the Xilinx SDI Rx V4L2 controls > + * @ctrl: V4L2 control to be set > + * > + * This function is used to set the V4L2 controls for the Xilinx SDI Rx > + * Subsystem. > + * > + * Return: 0 on success, errors otherwise > + */ > +static int xsdirxss_s_ctrl(struct v4l2_ctrl *ctrl) > +{ > + int ret = 0; > + struct xsdirxss_state *xsdirxss = > + container_of(ctrl->handler, struct xsdirxss_state, > + ctrl_handler); > + struct xsdirxss_core *core = &xsdirxss->core; > + struct device *dev = core->dev; > + > + dev_dbg(dev, "set ctrl id = 0x%08x val = 0x%08x\n", > + ctrl->id, ctrl->val); > + > + if (xsdirxss->streaming) { > + dev_err(dev, "Cannot set controls while streaming\n"); > + return -EINVAL; > + } > + > + xsdirx_core_disable(core); > + switch (ctrl->id) { > + case V4L2_CID_XILINX_SDIRX_FRAMER: > + xsdirx_framer(core, ctrl->val); > + xsdirxss->framer_enable = ctrl->val; > + break; > + case V4L2_CID_XILINX_SDIRX_VIDLOCK_WINDOW: > + xsdirx_setvidlockwindow(core, ctrl->val); > + xsdirxss->vidlockwin = ctrl->val; > + break; > + case V4L2_CID_XILINX_SDIRX_EDH_ERRCNT_ENABLE: As this is used to select which error sources to enable, how about naming the control V4L2_CID_XILINX_SDIRX_EDH_ERROR_SOURCES or V4L2_CID_XILINX_SDIRX_EDH_ERRORS_MASK ? > + xsdirx_setedherrcnttrigger(core, ctrl->val); > + xsdirxss->edhmask = ctrl->val; > + break; > + case V4L2_CID_XILINX_SDIRX_SEARCH_MODES: > + if (ctrl->val) { > + if (core->mode == XSDIRXSS_SDI_STD_3G) { > + dev_dbg(dev, "Upto 3G supported\n"); > + ctrl->val &= ~(BIT(XSDIRX_MODE_6G_OFFSET) | > + BIT(XSDIRX_MODE_12GI_OFFSET) | > + BIT(XSDIRX_MODE_12GF_OFFSET)); > + } > + > + if (core->mode == XSDIRXSS_SDI_STD_6G) { > + dev_dbg(dev, "Upto 6G supported\n"); > + ctrl->val &= ~(BIT(XSDIRX_MODE_12GI_OFFSET) | > + BIT(XSDIRX_MODE_12GF_OFFSET)); > + } > + > + ret = xsdirx_set_modedetect(core, ctrl->val); > + if (!ret) > + xsdirxss->searchmask = ctrl->val; > + } else { > + dev_err(dev, "Select at least one mode!\n"); > + return -EINVAL; > + } > + break; The traditional approach to select timing standards is to use ioctls. Hans, do you think a custom control is fine here, or should the dv timings ioctls be extended (or new sdi timings ioctls created) ? If we go for a single control, I'm a bit concerned that this control will restrict the search when multiple bits are set, but force a specific mode when a single bit is set. I don't have enough experience with SDI to tell whether this is the right behaviour. > + default: > + xsdirxss_set(core, XSDIRX_RST_CTRL_REG, > + XSDIRX_RST_CTRL_SS_EN_MASK); > + return -EINVAL; This looks weird. ret = -EINVAL; break; would be better. > + } > + xsdirx_core_enable(core); Do we really need to disable and reenable the core as we're guaranteed not to be streaming ? > + return ret; > +} > + > +/** > + * xsdirxss_g_volatile_ctrl - get the Xilinx SDI Rx controls > + * @ctrl: Pointer to V4L2 control > + * > + * Return: 0 on success, errors otherwise > + */ > +static int xsdirxss_g_volatile_ctrl(struct v4l2_ctrl *ctrl) > +{ > + u32 val; > + struct xsdirxss_state *xsdirxss = > + container_of(ctrl->handler, > + struct xsdirxss_state, ctrl_handler); > + struct xsdirxss_core *core = &xsdirxss->core; > + struct device *dev = core->dev; > + > + switch (ctrl->id) { > + case V4L2_CID_XILINX_SDIRX_MODE_DETECT: > + if (!xsdirxss->vidlocked) { > + dev_err(dev, "Can't get values when video not locked!\n"); > + return -EINVAL; > + } > + val = xsdirxss_read(core, XSDIRX_MODE_DET_STAT_REG); > + val &= XSDIRX_MODE_DET_STAT_RX_MODE_MASK; > + > + switch (val) { > + case XSDIRX_MODE_SD_MASK: > + ctrl->val = XSDIRX_MODE_SD_OFFSET; > + break; > + case XSDIRX_MODE_HD_MASK: > + ctrl->val = XSDIRX_MODE_HD_OFFSET; > + break; > + case XSDIRX_MODE_3G_MASK: > + ctrl->val = XSDIRX_MODE_3G_OFFSET; > + break; > + case XSDIRX_MODE_6G_MASK: > + ctrl->val = XSDIRX_MODE_6G_OFFSET; > + break; > + case XSDIRX_MODE_12GI_MASK: > + ctrl->val = XSDIRX_MODE_12GI_OFFSET; > + break; > + case XSDIRX_MODE_12GF_MASK: > + ctrl->val = XSDIRX_MODE_12GF_OFFSET; > + break; > + } > + break; Hans commented that the dv timings structure will report whether the mode is interlaced, I wonder if reporting the SDI mode shouldn't go through that structure too. > + case V4L2_CID_XILINX_SDIRX_CRC: > + ctrl->val = xsdirxss_read(core, XSDIRX_CRC_ERRCNT_REG); > + xsdirxss_write(core, XSDIRX_CRC_ERRCNT_REG, 0xFFFF); > + break; Are CRC errors common (and recoverable), or are they rare and fatal errors ? In other words, does this report information that would be classified as link quality, or fatal errors ? In the later case I wonder if an event wouldn't make more sense. It could be reported as another bit in the overflow/underflow event. > + case V4L2_CID_XILINX_SDIRX_EDH_ERRCNT: > + val = xsdirxss_read(core, XSDIRX_MODE_DET_STAT_REG); > + val &= XSDIRX_MODE_DET_STAT_RX_MODE_MASK; > + if (val == XSDIRX_MODE_SD_MASK) { > + ctrl->val = xsdirxss_read(core, XSDIRX_EDH_ERRCNT_REG); > + } else { > + dev_dbg(dev, "%d - not in SD mode\n", ctrl->id); > + return -EINVAL; > + } > + break; If my understanding of the datasheet is correct, this will be reset for every frame, right ? Reporting the information this way is thus quite racy. Isn't it better to send it through an event ? > + case V4L2_CID_XILINX_SDIRX_EDH_STATUS: > + val = xsdirxss_read(core, XSDIRX_MODE_DET_STAT_REG); > + val &= XSDIRX_MODE_DET_STAT_RX_MODE_MASK; > + if (val == XSDIRX_MODE_SD_MASK) { > + ctrl->val = xsdirxss_read(core, XSDIRX_EDH_STAT_REG); > + } else { > + dev_dbg(dev, "%d - not in SD mode\n", ctrl->id); > + return -EINVAL; > + } > + break; Same here, seems quite racy. > + case V4L2_CID_XILINX_SDIRX_TS_IS_INTERLACED: > + if (!xsdirxss->vidlocked) { > + dev_err(dev, "Can't get values when video not locked!\n"); > + return -EINVAL; > + } > + ctrl->val = xsdirxss->ts_is_interlaced; > + break; > + case V4L2_CID_XILINX_SDIRX_ACTIVE_STREAMS: > + if (!xsdirxss->vidlocked) { > + dev_err(dev, "Can't get values when video not locked!\n"); > + return -EINVAL; > + } > + val = xsdirxss_read(core, XSDIRX_MODE_DET_STAT_REG); > + val &= XSDIRX_MODE_DET_STAT_ACT_STREAM_MASK; > + val >>= XSDIRX_MODE_DET_STAT_ACT_STREAM_OFFSET; > + ctrl->val = 1 << val; > + break; > + case V4L2_CID_XILINX_SDIRX_IS_3GB: > + if (!xsdirxss->vidlocked) { > + dev_err(dev, "Can't get values when video not locked!\n"); > + return -EINVAL; > + } > + val = xsdirxss_read(core, XSDIRX_MODE_DET_STAT_REG); > + val &= XSDIRX_MODE_DET_STAT_LVLB_3G_MASK; > + ctrl->val = val ? true : false; > + break; Shouldn't this also go through DV timings ? If not, I think it should at least be combined with V4L2_CID_XILINX_SDIRX_MODE_DETECT. > + default: > + dev_err(dev, "Get Invalid control id 0x%0x\n", ctrl->id); > + return -EINVAL; > + } > + dev_dbg(dev, "Get ctrl id = 0x%08x val = 0x%08x\n", ctrl->id, > + ctrl->val); I would drop this line. > + return 0; > +} > + > +/** > + * xsdirxss_log_status - Logs the status of the SDI Rx Subsystem > + * @sd: Pointer to V4L2 subdevice structure > + * > + * This function prints the current status of Xilinx SDI Rx Subsystem > + * > + * Return: 0 on success > + */ > +static int xsdirxss_log_status(struct v4l2_subdev *sd) > +{ > + struct xsdirxss_state *xsdirxss = to_xsdirxssstate(sd); > + struct xsdirxss_core *core = &xsdirxss->core; > + u32 i; > + > + v4l2_info(sd, "***** SDI Rx subsystem reg dump start *****\n"); > + for (i = 0; i < 0x28; i++) { There are registers in this range that are not documented in the datasheet. Is it really safe to read them ? There are also registers that are of no real interest I believe (ISR for instance), or registers that seems to map to a FIFO (RX_ST352_DATA_DS*) which may cause issue when read as the IRQ handler extracts data from them (I could be wrong here though). Should this be restricted to a handful of carefully selected registers ? You could then also print their name instead of their address, that would be more readable. > + u32 data; > + > + data = xsdirxss_read(core, i * 4); > + v4l2_info(sd, "offset 0x%08x data 0x%08x\n", > + i * 4, data); > + } > + v4l2_info(sd, "***** SDI Rx subsystem reg dump end *****\n"); > + return 0; > +} > + > +/** > + * xsdirxss_g_frame_interval - Get the frame interval > + * @sd: V4L2 Sub device > + * @fi: Pointer to V4l2 Sub device frame interval structure > + * > + * This function is used to get the frame interval. > + * The frame rate can be integral or fractional. > + * Integral frame rate e.g. numerator = 1000, denominator = 24000 => 24 fps > + * Fractional frame rate e.g. numerator = 1001, denominator = 24000 => 23.97 fps > + * > + * Return: 0 on success > + */ > +static int xsdirxss_g_frame_interval(struct v4l2_subdev *sd, > + struct v4l2_subdev_frame_interval *fi) > +{ > + struct xsdirxss_state *xsdirxss = to_xsdirxssstate(sd); > + struct xsdirxss_core *core = &xsdirxss->core; > + > + if (!xsdirxss->vidlocked) { > + dev_err(core->dev, "Video not locked!\n"); > + return -EINVAL; > + } > + > + fi->interval = xsdirxss->frame_interval; There's a data race with the interrupt handler here. > + > + dev_dbg(core->dev, "frame rate numerator = %d denominator = %d\n", > + xsdirxss->frame_interval.numerator, > + xsdirxss->frame_interval.denominator); > + return 0; > +} > + > +/** > + * xsdirxss_s_stream - It is used to start/stop the streaming. > + * @sd: V4L2 Sub device > + * @enable: Flag (True / False) > + * > + * This function controls the start or stop of streaming for the > + * Xilinx SDI Rx Subsystem. > + * > + * Return: 0 on success, errors otherwise > + */ > +static int xsdirxss_s_stream(struct v4l2_subdev *sd, int enable) > +{ > + struct xsdirxss_state *xsdirxss = to_xsdirxssstate(sd); > + struct xsdirxss_core *core = &xsdirxss->core; > + struct device *dev = core->dev; > + Maybe if (enable == xsdirxss->streaming) { dev_dbg(...); return enable ? -EINVAL : 0; } ? Up to you. > + if (enable) { > + if (!xsdirxss->vidlocked) { > + dev_dbg(dev, "Video is not locked\n"); > + return -EINVAL; > + } > + if (xsdirxss->streaming) { > + dev_dbg(dev, "Already streaming\n"); > + return -EINVAL; > + } > + > + xsdirx_streamflow_control(core, true); > + xsdirxss->streaming = true; > + dev_dbg(dev, "Streaming started\n"); > + } else { > + if (!xsdirxss->streaming) { > + dev_dbg(dev, "Stopped streaming already\n"); > + return 0; > + } > + > + xsdirx_streamflow_control(core, false); > + xsdirxss->streaming = false; > + dev_dbg(dev, "Streaming stopped\n"); > + } > + And possibly xsdirxss->streaming = enable; dev_dbg(dev, "Streaming %s\", enable ? "started" : "stopped"); > + return 0; > +} > + > +/** > + * xsdirxss_g_input_status - It is used to determine if the video signal > + * is present / locked onto or not. > + * > + * @sd: V4L2 Sub device > + * @status: status of signal locked > + * > + * This is used to determine if the video signal is present and locked onto > + * by the SDI Rx core or not based on vidlocked flag. > + * > + * Return: zero on success > + */ > +static int xsdirxss_g_input_status(struct v4l2_subdev *sd, u32 *status) > +{ > + struct xsdirxss_state *xsdirxss = to_xsdirxssstate(sd); > + > + if (!xsdirxss->vidlocked) > + *status = V4L2_IN_ST_NO_SYNC | V4L2_IN_ST_NO_SIGNAL; > + else > + *status = 0; > + > + return 0; > +} > + > +static struct v4l2_mbus_framefmt * > +__xsdirxss_get_pad_format(struct xsdirxss_state *xsdirxss, > + struct v4l2_subdev_pad_config *cfg, > + unsigned int pad, u32 which) > +{ > + switch (which) { > + case V4L2_SUBDEV_FORMAT_TRY: > + return v4l2_subdev_get_try_format(&xsdirxss->subdev, cfg, pad); > + case V4L2_SUBDEV_FORMAT_ACTIVE: > + return &xsdirxss->format; > + default: > + return NULL; > + } > +} > + > +/** > + * xsdirxss_init_cfg - Initialise the pad format config to default > + * @sd: Pointer to V4L2 Sub device structure > + * @cfg: Pointer to sub device pad information structure > + * > + * This function is used to initialize the pad format with the default > + * values. > + * > + * Return: 0 on success > + */ > +static int xsdirxss_init_cfg(struct v4l2_subdev *sd, > + struct v4l2_subdev_pad_config *cfg) > +{ > + struct xsdirxss_state *xsdirxss = to_xsdirxssstate(sd); > + struct v4l2_mbus_framefmt *format; > + > + format = v4l2_subdev_get_try_format(sd, cfg, 0); > + *format = xsdirxss->default_format; > + > + return 0; > +} > + > +/** > + * xsdirxss_get_format - Get the pad format > + * @sd: Pointer to V4L2 Sub device structure > + * @cfg: Pointer to sub device pad information structure > + * @fmt: Pointer to pad level media bus format > + * > + * This function is used to get the pad format information. > + * > + * Return: 0 on success > + */ > +static int xsdirxss_get_format(struct v4l2_subdev *sd, > + struct v4l2_subdev_pad_config *cfg, > + struct v4l2_subdev_format *fmt) > +{ > + struct xsdirxss_state *xsdirxss = to_xsdirxssstate(sd); > + struct xsdirxss_core *core = &xsdirxss->core; > + > + if (!xsdirxss->vidlocked) { > + dev_err(core->dev, "Video not locked!\n"); > + return -EINVAL; > + } > + > + fmt->format = *__xsdirxss_get_pad_format(xsdirxss, cfg, > + fmt->pad, fmt->which); > + > + dev_dbg(core->dev, "Stream width = %d height = %d Field = %d\n", > + fmt->format.width, fmt->format.height, fmt->format.field); > + > + return 0; > +} > + > +/** > + * xsdirxss_set_format - This is used to set the pad format > + * @sd: Pointer to V4L2 Sub device structure > + * @cfg: Pointer to sub device pad information structure > + * @fmt: Pointer to pad level media bus format > + * > + * This function is used to set the pad format. > + * Since the pad format is fixed in hardware, it can't be > + * modified on run time. > + * > + * Return: 0 on success > + */ > +static int xsdirxss_set_format(struct v4l2_subdev *sd, > + struct v4l2_subdev_pad_config *cfg, > + struct v4l2_subdev_format *fmt) > +{ > + struct v4l2_mbus_framefmt *__format; > + struct xsdirxss_state *xsdirxss = to_xsdirxssstate(sd); > + > + dev_dbg(xsdirxss->core.dev, > + "set width %d height %d code %d field %d colorspace %d\n", > + fmt->format.width, fmt->format.height, > + fmt->format.code, fmt->format.field, > + fmt->format.colorspace); > + > + __format = __xsdirxss_get_pad_format(xsdirxss, cfg, > + fmt->pad, fmt->which); > + > + /* Currently reset the code to one fixed in hardware */ > + /* TODO : Add checks for width height */ > + fmt->format.code = __format->code; As Hans requested, width, height and field should be set here too, and probably colorspace information too. > + > + return 0; > +} > + > +/** > + * xsdirxss_enum_mbus_code - Handle pixel format enumeration > + * @sd: pointer to v4l2 subdev structure > + * @cfg: V4L2 subdev pad configuration > + * @code: pointer to v4l2_subdev_mbus_code_enum structure > + * > + * Return: -EINVAL or zero on success > + */ > +static int xsdirxss_enum_mbus_code(struct v4l2_subdev *sd, > + struct v4l2_subdev_pad_config *cfg, > + struct v4l2_subdev_mbus_code_enum *code) > +{ > + struct xsdirxss_state *xsdirxss = to_xsdirxssstate(sd); > + u32 index = code->index; > + u32 maxindex; > + > + if (xsdirxss->core.bpc == 10) > + maxindex = ARRAY_SIZE(xsdirxss_10bpc_mbus_fmts); > + else > + maxindex = ARRAY_SIZE(xsdirxss_12bpc_mbus_fmts); > + > + if (code->pad || index >= maxindex) > + return -EINVAL; > + > + if (xsdirxss->core.bpc == 10) > + code->code = xsdirxss_10bpc_mbus_fmts[index]; > + else > + code->code = xsdirxss_12bpc_mbus_fmts[index]; > + > + return 0; > +} > + > +/** > + * xsdirxss_enum_dv_timings: Enumerate all the supported DV timings > + * @sd: pointer to v4l2 subdev structure > + * @timings: DV timings structure to be returned. > + * > + * Return: -EINVAL incase of invalid index and pad or zero on success > + */ > +static int xsdirxss_enum_dv_timings(struct v4l2_subdev *sd, > + struct v4l2_enum_dv_timings *timings) > +{ > + if (timings->index >= ARRAY_SIZE(fmt_cap)) > + return -EINVAL; > + > + if (timings->pad != 0) > + return -EINVAL; > + > + timings->timings = fmt_cap[timings->index]; > + return 0; > +} > + > +/** > + * xsdirxss_query_dv_timings: Query for the current DV timings > + * @sd: pointer to v4l2 subdev structure > + * @timings: DV timings structure to be returned. > + * > + * Return: -ENOLCK when video is not locked, -ERANGE when corresponding timing > + * entry is not found or zero on success. > + */ > +static int xsdirxss_query_dv_timings(struct v4l2_subdev *sd, > + struct v4l2_dv_timings *timings) > +{ > + struct xsdirxss_state *state = to_xsdirxssstate(sd); > + unsigned int i; > + > + if (!state->vidlocked) > + return -ENOLCK; > + > + for (i = 0; i < ARRAY_SIZE(xsdirxss_dv_timings); i++) { > + if (state->format.width == xsdirxss_dv_timings[i].width && > + state->format.height == xsdirxss_dv_timings[i].height && > + state->frame_interval.denominator == > + (xsdirxss_dv_timings[i].fps * 1000)) { > + *timings = xsdirxss_dv_timings[i].format; > + return 0; > + } > + } > + > + return -ERANGE; > +} > + > +/* ----------------------------------------------------------------------------- > + * Media Operations > + */ > + > +static const struct media_entity_operations xsdirxss_media_ops = { > + .link_validate = v4l2_subdev_link_validate > +}; > + > +static const struct v4l2_ctrl_ops xsdirxss_ctrl_ops = { > + .g_volatile_ctrl = xsdirxss_g_volatile_ctrl, > + .s_ctrl = xsdirxss_s_ctrl > +}; > + > +static const struct v4l2_ctrl_config xsdirxss_edh_ctrls[] = { > + { > + .ops = &xsdirxss_ctrl_ops, > + .id = V4L2_CID_XILINX_SDIRX_EDH_ERRCNT_ENABLE, > + .name = "SDI Rx : EDH Error Count Enable", > + .type = V4L2_CTRL_TYPE_BITMASK, > + .min = 0, > + .max = XSDIRX_EDH_ALLERR_MASK, > + .def = 0, > + }, { > + .ops = &xsdirxss_ctrl_ops, > + .id = V4L2_CID_XILINX_SDIRX_EDH_ERRCNT, > + .name = "SDI Rx : EDH Error Count", > + .type = V4L2_CTRL_TYPE_INTEGER, > + .min = 0, > + .max = 0xFFFF, > + .step = 1, > + .def = 0, > + .flags = V4L2_CTRL_FLAG_VOLATILE | V4L2_CTRL_FLAG_READ_ONLY, > + }, { > + .ops = &xsdirxss_ctrl_ops, > + .id = V4L2_CID_XILINX_SDIRX_EDH_STATUS, > + .name = "SDI Rx : EDH Status", > + .type = V4L2_CTRL_TYPE_INTEGER, > + .min = 0, > + .max = 0xFFFFFFFF, > + .step = 1, > + .def = 0, > + .flags = V4L2_CTRL_FLAG_VOLATILE | V4L2_CTRL_FLAG_READ_ONLY, > + } > +}; > + > +static const struct v4l2_ctrl_config xsdirxss_ctrls[] = { > + { > + .ops = &xsdirxss_ctrl_ops, > + .id = V4L2_CID_XILINX_SDIRX_FRAMER, > + .name = "SDI Rx : Enable Framer", > + .type = V4L2_CTRL_TYPE_BOOLEAN, > + .min = false, > + .max = true, > + .step = 1, > + .def = true, > + }, { > + .ops = &xsdirxss_ctrl_ops, > + .id = V4L2_CID_XILINX_SDIRX_VIDLOCK_WINDOW, > + .name = "SDI Rx : Video Lock Window", > + .type = V4L2_CTRL_TYPE_INTEGER, > + .min = 0, > + .max = 0xFFFFFFFF, > + .step = 1, > + .def = XSDIRX_DEFAULT_VIDEO_LOCK_WINDOW, > + }, { > + .ops = &xsdirxss_ctrl_ops, > + .id = V4L2_CID_XILINX_SDIRX_SEARCH_MODES, > + .name = "SDI Rx : Modes search Mask", > + .type = V4L2_CTRL_TYPE_BITMASK, > + .min = 0, > + .max = XSDIRX_DETECT_ALL_MODES, > + .def = XSDIRX_DETECT_ALL_MODES, > + }, { > + .ops = &xsdirxss_ctrl_ops, > + .id = V4L2_CID_XILINX_SDIRX_MODE_DETECT, > + .name = "SDI Rx : Mode Detect Status", > + .type = V4L2_CTRL_TYPE_INTEGER, > + .min = XSDIRX_MODE_SD_OFFSET, > + .max = XSDIRX_MODE_12GF_OFFSET, > + .step = 1, > + .flags = V4L2_CTRL_FLAG_VOLATILE | V4L2_CTRL_FLAG_READ_ONLY, > + }, { > + .ops = &xsdirxss_ctrl_ops, > + .id = V4L2_CID_XILINX_SDIRX_CRC, > + .name = "SDI Rx : CRC Error status", > + .type = V4L2_CTRL_TYPE_INTEGER, > + .min = 0, > + .max = 0xFFFFFFFF, > + .step = 1, > + .def = 0, > + .flags = V4L2_CTRL_FLAG_VOLATILE | V4L2_CTRL_FLAG_READ_ONLY, > + }, { > + .ops = &xsdirxss_ctrl_ops, > + .id = V4L2_CID_XILINX_SDIRX_TS_IS_INTERLACED, > + .name = "SDI Rx : TS is Interlaced", > + .type = V4L2_CTRL_TYPE_BOOLEAN, > + .min = false, > + .max = true, > + .def = false, > + .step = 1, > + .flags = V4L2_CTRL_FLAG_VOLATILE | V4L2_CTRL_FLAG_READ_ONLY, > + }, { > + .ops = &xsdirxss_ctrl_ops, > + .id = V4L2_CID_XILINX_SDIRX_ACTIVE_STREAMS, > + .name = "SDI Rx : Active Streams", > + .type = V4L2_CTRL_TYPE_INTEGER, > + .min = 1, > + .max = 16, > + .def = 1, > + .step = 1, > + .flags = V4L2_CTRL_FLAG_VOLATILE | V4L2_CTRL_FLAG_READ_ONLY, > + }, { > + .ops = &xsdirxss_ctrl_ops, > + .id = V4L2_CID_XILINX_SDIRX_IS_3GB, > + .name = "SDI Rx : Is 3GB", > + .type = V4L2_CTRL_TYPE_BOOLEAN, > + .min = false, > + .max = true, > + .def = false, > + .step = 1, > + .flags = V4L2_CTRL_FLAG_VOLATILE | V4L2_CTRL_FLAG_READ_ONLY, > + } > +}; > + > +static const struct v4l2_subdev_core_ops xsdirxss_core_ops = { > + .log_status = xsdirxss_log_status, > + .subscribe_event = xsdirxss_subscribe_event, > + .unsubscribe_event = xsdirxss_unsubscribe_event > +}; > + > +static const struct v4l2_subdev_video_ops xsdirxss_video_ops = { > + .g_frame_interval = xsdirxss_g_frame_interval, > + .s_stream = xsdirxss_s_stream, > + .g_input_status = xsdirxss_g_input_status, > + .query_dv_timings = xsdirxss_query_dv_timings, > +}; > + > +static const struct v4l2_subdev_pad_ops xsdirxss_pad_ops = { > + .init_cfg = xsdirxss_init_cfg, > + .get_fmt = xsdirxss_get_format, > + .set_fmt = xsdirxss_set_format, > + .enum_mbus_code = xsdirxss_enum_mbus_code, > + .enum_dv_timings = xsdirxss_enum_dv_timings, > +}; > + > +static const struct v4l2_subdev_ops xsdirxss_ops = { > + .core = &xsdirxss_core_ops, > + .video = &xsdirxss_video_ops, > + .pad = &xsdirxss_pad_ops > +}; > + > +/* ----------------------------------------------------------------------------- > + * Platform Device Driver > + */ > + > +static int xsdirxss_parse_of(struct xsdirxss_state *xsdirxss) > +{ > + struct device_node *node = xsdirxss->core.dev->of_node; > + struct xsdirxss_core *core = &xsdirxss->core; > + struct device *dev = core->dev; > + struct fwnode_handle *ep, *rep; > + int ret; > + const char *sdi_std; > + > + core->include_edh = of_property_read_bool(node, "xlnx,include-edh"); > + dev_dbg(dev, "EDH property = %s\n", > + core->include_edh ? "Present" : "Absent"); > + > + ret = of_property_read_string(node, "xlnx,line-rate", &sdi_std); > + if (ret < 0) { > + dev_err(dev, "xlnx,line-rate property not found\n"); > + return ret; > + } > + > + if (!strncmp(sdi_std, "12G_SDI_8DS", XSDIRX_MAX_STR_LENGTH)) { Strings in DT are null-terminated, you can use strcmp() and drop XSDIRX_MAX_STR_LENGTH. > + core->mode = XSDIRXSS_SDI_STD_12G_8DS; > + } else if (!strncmp(sdi_std, "6G_SDI", XSDIRX_MAX_STR_LENGTH)) { > + core->mode = XSDIRXSS_SDI_STD_6G; > + } else if (!strncmp(sdi_std, "3G_SDI", XSDIRX_MAX_STR_LENGTH)) { > + core->mode = XSDIRXSS_SDI_STD_3G; > + } else { > + dev_err(dev, "Invalid Line Rate\n"); > + return -EINVAL; > + } > + dev_dbg(dev, "SDI Rx Line Rate = %s, mode = %d\n", sdi_std, > + core->mode); > + > + ret = of_property_read_u32(node, "xlnx,bpp", &core->bpc); > + if (ret < 0) { > + dev_err(dev, "failed to get xlnx,bpp\n"); > + return ret; > + } > + > + if (core->bpc != 10 && core->bpc != 12) { > + dev_err(dev, "bits per component=%u. Can be 10 or 12 only\n", > + core->bpc); > + return -EINVAL; > + } > + > + ep = fwnode_graph_get_endpoint_by_id(dev_fwnode(dev), 0, 0, > + FWNODE_GRAPH_ENDPOINT_NEXT); > + if (!ep) { > + dev_err(dev, "no source port found"); > + ret = -EINVAL; > + goto dt_parse_done; > + } > + > + rep = fwnode_graph_get_remote_endpoint(ep); > + if (!rep) { > + dev_err(dev, "no remote sink endpoint found"); > + ret = -EINVAL; > + } I don't think you need to check this, the subdev won't be linked properly in the pipeline if there's no port anyway. > + > + fwnode_handle_put(rep); > +dt_parse_done: > + fwnode_handle_put(ep); > + return ret; > +} > + > +static int xsdirxss_probe(struct platform_device *pdev) > +{ > + struct v4l2_subdev *subdev; > + struct xsdirxss_state *xsdirxss; > + struct xsdirxss_core *core; > + struct device *dev; > + int ret; > + unsigned int num_ctrls, num_edh_ctrls = 0, i; > + > + xsdirxss = devm_kzalloc(&pdev->dev, sizeof(*xsdirxss), GFP_KERNEL); > + if (!xsdirxss) > + return -ENOMEM; > + > + xsdirxss->core.dev = &pdev->dev; > + core = &xsdirxss->core; > + dev = core->dev; > + > + /* Register interrupt handler */ > + core->irq = platform_get_irq(pdev, 0); > + ret = devm_request_threaded_irq(dev, core->irq, NULL, > + xsdirxss_irq_handler, IRQF_ONESHOT, > + dev_name(dev), xsdirxss); Why a threaded IRQ ? > + if (ret) { > + dev_err(dev, "Err = %d Interrupt handler reg failed!\n", > + ret); > + return ret; > + } You should request the IRQ after resetting the core, otherwise interrupts could be triggered immediately. > + > + core->num_clks = ARRAY_SIZE(xsdirxss_clks); > + core->clks = devm_kcalloc(dev, core->num_clks, > + sizeof(*core->clks), GFP_KERNEL); > + if (!core->clks) > + return -ENOMEM; > + > + for (i = 0; i < core->num_clks; i++) > + core->clks[i].id = xsdirxss_clks[i]; > + > + ret = devm_clk_bulk_get(dev, core->num_clks, core->clks); > + if (ret) > + return ret; > + > + ret = clk_bulk_prepare_enable(core->num_clks, core->clks); > + if (ret) > + return ret; > + > + ret = xsdirxss_parse_of(xsdirxss); > + if (ret < 0) > + goto clk_err; > + > + core->iomem = devm_platform_ioremap_resource(pdev, 0); > + if (IS_ERR(core->iomem)) { > + ret = PTR_ERR(core->iomem); > + goto clk_err; > + } If you move these two calls above handling of the clocks, you will be able to return immediately and avoid the goto. > + > + /* Reset the core */ > + xsdirx_streamflow_control(core, false); > + xsdirx_core_disable(core); > + xsdirx_clearintr(core, XSDIRX_INTR_ALL_MASK); > + xsdirx_disableintr(core, XSDIRX_INTR_ALL_MASK); > + xsdirx_enableintr(core, XSDIRX_INTR_ALL_MASK); > + xsdirx_globalintr(core, true); > + xsdirxss_write(core, XSDIRX_CRC_ERRCNT_REG, 0xFFFF); > + > + /* Initialize V4L2 subdevice and media entity */ > + xsdirxss->pad.flags = MEDIA_PAD_FL_SOURCE; > + > + /* Initialize the default format */ > + if (core->bpc == 10) > + xsdirxss->default_format.code = MEDIA_BUS_FMT_UYVY10_1X20; > + else > + xsdirxss->default_format.code = MEDIA_BUS_FMT_UYVY12_1X24; > + xsdirxss->default_format.field = V4L2_FIELD_NONE; > + xsdirxss->default_format.colorspace = V4L2_COLORSPACE_DEFAULT; > + xsdirxss->default_format.width = XSDIRX_DEFAULT_WIDTH; > + xsdirxss->default_format.height = XSDIRX_DEFAULT_HEIGHT; > + > + xsdirxss->format = xsdirxss->default_format; > + > + /* Initialize V4L2 subdevice and media entity */ > + subdev = &xsdirxss->subdev; > + v4l2_subdev_init(subdev, &xsdirxss_ops); > + > + subdev->dev = &pdev->dev; > + strscpy(subdev->name, dev_name(dev), sizeof(subdev->name)); > + > + subdev->flags |= V4L2_SUBDEV_FL_HAS_EVENTS | V4L2_SUBDEV_FL_HAS_DEVNODE; > + > + subdev->entity.ops = &xsdirxss_media_ops; > + > + v4l2_set_subdevdata(subdev, xsdirxss); > + > + ret = media_entity_pads_init(&subdev->entity, 1, &xsdirxss->pad); > + if (ret < 0) > + goto error; > + > + /* Initialise and register the controls */ > + num_ctrls = ARRAY_SIZE(xsdirxss_ctrls); > + > + if (core->include_edh) > + num_edh_ctrls = ARRAY_SIZE(xsdirxss_edh_ctrls); How about num_ctrls += ARRAY_SIZE(xsdirxss_edh_ctrls); > + > + v4l2_ctrl_handler_init(&xsdirxss->ctrl_handler, > + (num_ctrls + num_edh_ctrls)); num_ctrls); > + > + for (i = 0; i < num_ctrls; i++) { for (i = 0; i < ARRAY_SIZE(xsdirxss_ctrls); i++) { > + struct v4l2_ctrl *ctrl; > + > + dev_dbg(dev, "%d %s ctrl = 0x%x\n", i, xsdirxss_ctrls[i].name, > + xsdirxss_ctrls[i].id); > + > + ctrl = v4l2_ctrl_new_custom(&xsdirxss->ctrl_handler, > + &xsdirxss_ctrls[i], NULL); > + if (!ctrl) { > + dev_dbg(dev, "Failed to add %s ctrl\n", > + xsdirxss_ctrls[i].name); > + goto error; > + } As you check for xsdirxss->ctrl_handler.error below you can drop this check and the equivalent one for the EDH controls. > + } > + > + if (core->include_edh) { > + for (i = 0; i < num_edh_ctrls; i++) { for (i = 0; i < ARRAY_SIZE(xsdirxss_edh_ctrls); i++) { > + struct v4l2_ctrl *ctrl; > + > + dev_dbg(dev, "%d %s ctrl = 0x%x\n", i, > + xsdirxss_edh_ctrls[i].name, > + xsdirxss_edh_ctrls[i].id); > + > + ctrl = v4l2_ctrl_new_custom(&xsdirxss->ctrl_handler, > + &xsdirxss_edh_ctrls[i], > + NULL); > + if (!ctrl) { > + dev_dbg(dev, "Failed to add %s ctrl\n", > + xsdirxss_edh_ctrls[i].name); > + goto error; > + } > + } > + } > + > + if (xsdirxss->ctrl_handler.error) { > + dev_err(dev, "failed to add controls\n"); > + ret = xsdirxss->ctrl_handler.error; > + goto error; > + } > + > + subdev->ctrl_handler = &xsdirxss->ctrl_handler; > + > + ret = v4l2_ctrl_handler_setup(&xsdirxss->ctrl_handler); > + if (ret < 0) { > + dev_err(dev, "failed to set controls\n"); > + goto error; > + } > + > + platform_set_drvdata(pdev, xsdirxss); > + > + ret = v4l2_async_register_subdev(subdev); > + if (ret < 0) { > + dev_err(dev, "failed to register subdev\n"); > + goto error; > + } > + > + xsdirxss->streaming = false; > + > + xsdirx_core_enable(core); > + > + dev_info(dev, "probe success\n"); You can drop this line, successful driver probing should be silent. > + > + return 0; > +error: > + v4l2_ctrl_handler_free(&xsdirxss->ctrl_handler); > + media_entity_cleanup(&subdev->entity); > + xsdirx_globalintr(core, false); > + xsdirx_disableintr(core, XSDIRX_INTR_ALL_MASK); > +clk_err: > + clk_bulk_disable_unprepare(core->num_clks, core->clks); > + return ret; > +} > + > +static int xsdirxss_remove(struct platform_device *pdev) > +{ > + struct xsdirxss_state *xsdirxss = platform_get_drvdata(pdev); > + struct xsdirxss_core *core = &xsdirxss->core; > + struct v4l2_subdev *subdev = &xsdirxss->subdev; > + > + v4l2_async_unregister_subdev(subdev); > + v4l2_ctrl_handler_free(&xsdirxss->ctrl_handler); > + media_entity_cleanup(&subdev->entity); > + > + xsdirx_globalintr(core, false); > + xsdirx_disableintr(core, XSDIRX_INTR_ALL_MASK); > + xsdirx_core_disable(core); > + xsdirx_streamflow_control(core, false); > + > + clk_bulk_disable_unprepare(core->num_clks, core->clks); > + > + return 0; > +} > + > +static const struct of_device_id xsdirxss_of_id_table[] = { > + { .compatible = "xlnx,v-smpte-uhdsdi-rx-ss-2.0" }, > + { } > +}; > +MODULE_DEVICE_TABLE(of, xsdirxss_of_id_table); > + > +static struct platform_driver xsdirxss_driver = { > + .driver = { > + .name = "xilinx-sdirxss", > + .of_match_table = xsdirxss_of_id_table, > + }, > + .probe = xsdirxss_probe, > + .remove = xsdirxss_remove, > +}; > + > +module_platform_driver(xsdirxss_driver); > + > +MODULE_AUTHOR("Vishal Sagar "); > +MODULE_DESCRIPTION("Xilinx SDI Rx Subsystem Driver"); > +MODULE_LICENSE("GPL v2"); > diff --git a/include/uapi/linux/xilinx-sdirxss.h b/include/uapi/linux/xilinx-sdirxss.h > new file mode 100644 > index 000000000000..6f2a093968d9 > --- /dev/null > +++ b/include/uapi/linux/xilinx-sdirxss.h > @@ -0,0 +1,179 @@ > +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ > +/* > + * Xilinx SDI Rx Subsystem mode, event, custom timings > + * and flag definitions. > + * > + * Copyright (C) 2019 - 2020 Xilinx, Inc. > + * > + * Contacts: Vishal Sagar > + */ > + > +#ifndef __UAPI_XILINX_SDIRXSS_H__ > +#define __UAPI_XILINX_SDIRXSS_H__ > + > +#include > +#include > +#include > + > +/* > + * Events > + * > + * V4L2_EVENT_XILINX_SDIRX_UNDERFLOW: Video in to AXI4 Stream core underflowed > + * V4L2_EVENT_XILINX_SDIRX_OVERFLOW: Video in to AXI4 Stream core overflowed > + */ > +#define V4L2_EVENT_XILINX_SDIRX_CLASS (V4L2_EVENT_PRIVATE_START | 0x200) > +#define V4L2_EVENT_XILINX_SDIRX_UNDERFLOW (V4L2_EVENT_XILINX_SDIRX_CLASS | 0x1) > +#define V4L2_EVENT_XILINX_SDIRX_OVERFLOW (V4L2_EVENT_XILINX_SDIRX_CLASS | 0x2) > + > +/* > + * This enum is used to prepare the bitmask of modes to be detected > + */ > +enum { > + XSDIRX_MODE_SD_OFFSET = 0, > + XSDIRX_MODE_HD_OFFSET, > + XSDIRX_MODE_3G_OFFSET, > + XSDIRX_MODE_6G_OFFSET, > + XSDIRX_MODE_12GI_OFFSET, > + XSDIRX_MODE_12GF_OFFSET, > + XSDIRX_MODE_NUM_SUPPORTED, > +}; > + > +#define XSDIRX_DETECT_ALL_MODES (BIT(XSDIRX_MODE_SD_OFFSET) | \ > + BIT(XSDIRX_MODE_HD_OFFSET) | \ > + BIT(XSDIRX_MODE_3G_OFFSET) | \ > + BIT(XSDIRX_MODE_6G_OFFSET) | \ > + BIT(XSDIRX_MODE_12GI_OFFSET) | \ > + BIT(XSDIRX_MODE_12GF_OFFSET)) > + > +/* > + * EDH Error Types > + * ANC - Ancillary Data Packet Errors > + * FF - Full Field Errors > + * AP - Active Portion Errors > + */ > + > +#define XSDIRX_EDH_ERRCNT_ANC_EDH_ERR BIT(0) > +#define XSDIRX_EDH_ERRCNT_ANC_EDA_ERR BIT(1) > +#define XSDIRX_EDH_ERRCNT_ANC_IDH_ERR BIT(2) > +#define XSDIRX_EDH_ERRCNT_ANC_IDA_ERR BIT(3) > +#define XSDIRX_EDH_ERRCNT_ANC_UES_ERR BIT(4) > +#define XSDIRX_EDH_ERRCNT_FF_EDH_ERR BIT(5) > +#define XSDIRX_EDH_ERRCNT_FF_EDA_ERR BIT(6) > +#define XSDIRX_EDH_ERRCNT_FF_IDH_ERR BIT(7) > +#define XSDIRX_EDH_ERRCNT_FF_IDA_ERR BIT(8) > +#define XSDIRX_EDH_ERRCNT_FF_UES_ERR BIT(9) > +#define XSDIRX_EDH_ERRCNT_AP_EDH_ERR BIT(10) > +#define XSDIRX_EDH_ERRCNT_AP_EDA_ERR BIT(11) > +#define XSDIRX_EDH_ERRCNT_AP_IDH_ERR BIT(12) > +#define XSDIRX_EDH_ERRCNT_AP_IDA_ERR BIT(13) > +#define XSDIRX_EDH_ERRCNT_AP_UES_ERR BIT(14) > +#define XSDIRX_EDH_ERRCNT_PKT_CHKSUM_ERR BIT(15) > + > +#define XSDIRX_EDH_ALLERR_MASK 0xFFFF > + > +/* Xilinx DV timings not in mainline yet */ > +#define XLNX_V4L2_DV_BT_2048X1080P24 { \ > + .type = V4L2_DV_BT_656_1120, \ > + V4L2_INIT_BT_TIMINGS(2048, 1080, 0, \ > + V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \ > + 74250000, 510, 44, 148, 4, 5, 36, 0, 0, 0, \ > + V4L2_DV_BT_STD_SDI) \ > +} > + > +#define XLNX_V4L2_DV_BT_2048X1080P25 { \ > + .type = V4L2_DV_BT_656_1120, \ > + V4L2_INIT_BT_TIMINGS(2048, 1080, 0, \ > + V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \ > + 74250000, 400, 44, 148, 4, 5, 36, 0, 0, 0, \ > + V4L2_DV_BT_STD_SDI) \ > +} > + > +#define XLNX_V4L2_DV_BT_2048X1080P30 { \ > + .type = V4L2_DV_BT_656_1120, \ > + V4L2_INIT_BT_TIMINGS(2048, 1080, 0, \ > + V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \ > + 74250000, 66, 20, 66, 4, 5, 36, 0, 0, 0, \ > + V4L2_DV_BT_STD_SDI) \ > +} > + > +#define XLNX_V4L2_DV_BT_2048X1080I48 { \ > + .type = V4L2_DV_BT_656_1120, \ > + V4L2_INIT_BT_TIMINGS(2048, 1080, 1, \ > + V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \ > + 74250000, 329, 44, 329, 2, 5, 15, 3, 5, 15, \ > + V4L2_DV_BT_STD_SDI) \ > +} > + > +#define XLNX_V4L2_DV_BT_2048X1080I50 { \ > + .type = V4L2_DV_BT_656_1120, \ > + V4L2_INIT_BT_TIMINGS(2048, 1080, 1, \ > + V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \ > + 74250000, 274, 44, 274, 2, 5, 15, 3, 5, 15, \ > + V4L2_DV_BT_STD_SDI) \ > +} > + > +#define XLNX_V4L2_DV_BT_2048X1080I60 { \ > + .type = V4L2_DV_BT_656_1120, \ > + V4L2_INIT_BT_TIMINGS(2048, 1080, 1, \ > + V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \ > + 74250000, 66, 20, 66, 2, 5, 15, 3, 5, 15, \ > + V4L2_DV_BT_STD_SDI) \ > +} > + > +#define XLNX_V4L2_DV_BT_1920X1080P48 { \ > + .type = V4L2_DV_BT_656_1120, \ > + V4L2_INIT_BT_TIMINGS(1920, 1080, 0, \ > + V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \ > + 148500000, 638, 44, 148, 4, 5, 36, 0, 0, 0, \ > + V4L2_DV_BT_STD_SDI) \ > +} > + > +#define XLNX_V4L2_DV_BT_2048X1080P48 { \ > + .type = V4L2_DV_BT_656_1120, \ > + V4L2_INIT_BT_TIMINGS(2048, 1080, 0, \ > + V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \ > + 148500000, 510, 44, 148, 4, 5, 36, 0, 0, 0, \ > + V4L2_DV_BT_STD_SDI) \ > +} > + > +#define XLNX_V4L2_DV_BT_2048X1080P50 { \ > + .type = V4L2_DV_BT_656_1120, \ > + V4L2_INIT_BT_TIMINGS(2048, 1080, 0, \ > + V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \ > + 148500000, 400, 44, 148, 4, 5, 36, 0, 0, 0, \ > + V4L2_DV_BT_STD_SDI) \ > +} > + > +#define XLNX_V4L2_DV_BT_2048X1080P60 { \ > + .type = V4L2_DV_BT_656_1120, \ > + V4L2_INIT_BT_TIMINGS(2048, 1080, 0, \ > + V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \ > + 148500000, 88, 44, 20, 4, 5, 36, 0, 0, 0, \ > + V4L2_DV_BT_STD_SDI) \ > +} > + > +#define XLNX_V4L2_DV_BT_3840X2160P48 { \ > + .type = V4L2_DV_BT_656_1120, \ > + V4L2_INIT_BT_TIMINGS(3840, 2160, 0, \ > + V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \ > + 594000000, 1276, 88, 296, 8, 10, 72, 0, 0, 0, \ > + V4L2_DV_BT_STD_SDI) \ > +} > + > +#define XLNX_V4L2_DV_BT_4096X2160P48 { \ > + .type = V4L2_DV_BT_656_1120, \ > + V4L2_INIT_BT_TIMINGS(4096, 2160, 0, \ > + V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \ > + 594000000, 1020, 88, 296, 8, 10, 72, 0, 0, 0, \ > + V4L2_DV_BT_STD_SDI) \ > +} > + > +#define XLNX_V4L2_DV_BT_1920X1080I48 { \ > + .type = V4L2_DV_BT_656_1120, \ > + V4L2_INIT_BT_TIMINGS(1920, 1080, 1, \ > + V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \ > + 148500000, 371, 88, 371, 2, 5, 15, 3, 5, 15, \ > + V4L2_DV_BT_STD_SDI) \ > +} > + > +#endif /* __UAPI_XILINX_SDIRXSS_H__ */ > diff --git a/include/uapi/linux/xilinx-v4l2-controls.h b/include/uapi/linux/xilinx-v4l2-controls.h > index b6441fe705c5..e9de65e82642 100644 > --- a/include/uapi/linux/xilinx-v4l2-controls.h > +++ b/include/uapi/linux/xilinx-v4l2-controls.h > @@ -71,4 +71,71 @@ > /* Noise level */ > #define V4L2_CID_XILINX_TPG_NOISE_GAIN (V4L2_CID_XILINX_TPG + 17) > > +/* > + * Xilinx SDI Rx Subsystem > + */ > + > +/* The base for the sdi rx driver controls. > + * We reserve 32 controls for this driver. > + * > + * The V4L2_CID_XILINX_SDIRX_EDH_* controls are present only if > + * EDH is enabled. > + * The controls which can be set should only be set before enabling > + * streaming. The controls which can be got should be called while > + * streaming to get correct values. > + * The V4L2_CID_XILINX_SDIRX_MODE_DETECT can be called when query dv timing > + * returns a valid timing. > + */ > + > +#define V4L2_CID_XILINX_SDIRX (V4L2_CID_XILINX_BASE + 0x20) > + > +/* Framer Control to enable or disable the framer */ > +#define V4L2_CID_XILINX_SDIRX_FRAMER (V4L2_CID_XILINX_SDIRX + 1) This control needs more documentation. What does it do, and how should it be used ? > +/* > + * Video Lock Window Control to set the video lock window value > + * This is the amount of time the mode and transport stream need > + * to be locked before a video lock interrupt occurs. > + */ > +#define V4L2_CID_XILINX_SDIRX_VIDLOCK_WINDOW (V4L2_CID_XILINX_SDIRX + 2) > +/* EDH Error Mask Control to enable EDH error count */ > +#define V4L2_CID_XILINX_SDIRX_EDH_ERRCNT_ENABLE (V4L2_CID_XILINX_SDIRX + 3) > +/* > + * Mode search Control to pass the bit mask of modes to detect. > + * > + * bit 0 set to detect SD mode, > + * bit 1 set to detect HD mode, > + * bit 2 set to detect 3G (3GA & 3GB) mode, > + * bit 3 set to detect 6G mode, > + * bit 4 set to detect 12G integer frame rate mode, > + * bit 5 set to detect 12G fractional frame rate mode, > + */ > +#define V4L2_CID_XILINX_SDIRX_SEARCH_MODES (V4L2_CID_XILINX_SDIRX + 4) > +/* > + * Get Detected Mode control > + * > + * Control Value - Mode detected > + * 0 - SD > + * 1 - HD > + * 2 - 3G (3GA & 3GB) > + * 3 - 6G > + * 4 - 12G integer frame rate > + * 5 - 12G fractional frame rate > + */ > +#define V4L2_CID_XILINX_SDIRX_MODE_DETECT (V4L2_CID_XILINX_SDIRX + 5) > +/* Get number of CRC errors status control */ > +#define V4L2_CID_XILINX_SDIRX_CRC (V4L2_CID_XILINX_SDIRX + 6) > +/* Get EDH error count control */ > +#define V4L2_CID_XILINX_SDIRX_EDH_ERRCNT (V4L2_CID_XILINX_SDIRX + 7) > +/* Get EDH status control */ > +#define V4L2_CID_XILINX_SDIRX_EDH_STATUS (V4L2_CID_XILINX_SDIRX + 8) > +/* Get Transport Interlaced status whether it is interlaced or not */ > +#define V4L2_CID_XILINX_SDIRX_TS_IS_INTERLACED (V4L2_CID_XILINX_SDIRX + 9) > +/* Get number of Active Streams */ > +#define V4L2_CID_XILINX_SDIRX_ACTIVE_STREAMS (V4L2_CID_XILINX_SDIRX + 10) > +/* > + * Get if the detected mode is 3GB. > + * Can be used to distinguished between 3GA and 3GB > + */ > +#define V4L2_CID_XILINX_SDIRX_IS_3GB (V4L2_CID_XILINX_SDIRX + 11) > + > #endif /* __UAPI_XILINX_V4L2_CONTROLS_H__ */ -- Regards, Laurent Pinchart From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.8 required=3.0 tests=DKIMWL_WL_HIGH,DKIM_SIGNED, DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH,MAILING_LIST_MULTI, SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id B33EBC4725A for ; Wed, 6 May 2020 15:12:12 +0000 (UTC) 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 mail.kernel.org (Postfix) with ESMTPS id 66B19208E4 for ; Wed, 6 May 2020 15:12:12 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="lQ0lkryH"; dkim=fail reason="signature verification failed" (1024-bit key) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="h74pNX9K" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 66B19208E4 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=ideasonboard.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+infradead-linux-arm-kernel=archiver.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:In-Reply-To:MIME-Version:References: Message-ID:Subject:To:From:Date:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=3RSFmlvuJJ9MUhNGTMEJbcJjoe7r3mhcN7pLLoH5hts=; b=lQ0lkryHSp+CtL 89oF2oWHI8cAZ8tRjOxBloHpa+i52evobrkEAfRYYLh6VC9DqZnzBybYCijCwpgwqXbjVH2ylC6QS RhtJVkZR5eEjjDZbseHrU+Z8yzssWNx7rA9I+JsL88g5kZm61uah5622Dk4PB4QId+mp57GNVrfi1 6CzoaMEH9xue9SCcb6AptsRkXNmvus08LQFElTpVBoriAtdxcprltYI357g/bgr6Xm4gjyoBW3xdn pZTWTM6u3AjRCBT6OnzwEHjehA3U9d/aa0Fc/WnD3T0GhqThCg56R85vvzBhwbzxPavuj3O7+Z5hO 38iWXtnNccXEnSI4M2BQ==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1jWLiR-0007sZ-6t; Wed, 06 May 2020 15:12:07 +0000 Received: from perceval.ideasonboard.com ([213.167.242.64]) by bombadil.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1jWLiL-0007ra-IH for linux-arm-kernel@lists.infradead.org; Wed, 06 May 2020 15:12:06 +0000 Received: from pendragon.ideasonboard.com (81-175-216-236.bb.dnainternet.fi [81.175.216.236]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id E94FB542; Wed, 6 May 2020 17:11:47 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1588777908; bh=OgPW0FiG0bfGFWpm6HDke/69B2sIgCPK3Ih7ue2cWbE=; h=Date:From:To:Cc:Subject:References:In-Reply-To:From; b=h74pNX9KGvfOSBrhejIXpgLtaxc9kCnoLUeUfooKvarY4LyEkQHtRLY//RzycJ1D5 vj7q84n+Ut/Ue/iEiHHtVxsj8ZVtWFlyPm2J55urlAXqX9z+37opOINfp4uXDPBvb+ MSFf4bgkHNU4bBYv3xO3ryd4z6v8qCIY3Aq6Ydmk= Date: Wed, 6 May 2020 18:11:42 +0300 From: Laurent Pinchart To: Vishal Sagar Subject: Re: [PATCH v2 2/2] media: v4l: xilinx: Add Xilinx UHD-SDI Rx Subsystem driver Message-ID: <20200506151142.GA15206@pendragon.ideasonboard.com> References: <20200429141705.18755-1-vishal.sagar@xilinx.com> <20200429141705.18755-3-vishal.sagar@xilinx.com> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <20200429141705.18755-3-vishal.sagar@xilinx.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20200506_081202_206730_F2FE92CC X-CRM114-Status: GOOD ( 23.16 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: mark.rutland@arm.com, devicetree@vger.kernel.org, Dinesh Kumar , Hyun Kwon , Sandip Kothari , linux-kernel@vger.kernel.org, robh+dt@kernel.org, Michal Simek , Joe Perches , hans.verkuil@cisco.com, mchehab@kernel.org, linux-arm-kernel@lists.infradead.org, linux-media@vger.kernel.org Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+infradead-linux-arm-kernel=archiver.kernel.org@lists.infradead.org SGkgVmlzaGFsLAoKVGhhbmsgeW91IGZvciB0aGUgcGF0Y2guCgpUaGVyZSBhcmUgYSBmZXcgcXVl c3Rpb25zIGZvciBIYW5zIGJlbG93LgoKT24gV2VkLCBBcHIgMjksIDIwMjAgYXQgMDc6NDc6MDRQ TSArMDUzMCwgVmlzaGFsIFNhZ2FyIHdyb3RlOgo+IFRoZSBYaWxpbnggVUhELVNESSBSeCBzdWJz eXN0ZW0gc29mdCBJUCBpcyB1c2VkIHRvIGNhcHR1cmUgbmF0aXZlIFNESQo+IHN0cmVhbXMgZnJv bSBTREkgc291cmNlcyBsaWtlIFNESSBicm9hZGNhc3QgZXF1aXBtZW50IGxpa2UgY2FtZXJhcyBh bmQKPiBtaXhlcnMuIFRoaXMgYmxvY2sgb3V0cHV0cyBlaXRoZXIgbmF0aXZlIFNESSwgbmF0aXZl IHZpZGVvIG9yCj4gQVhJNC1TdHJlYW0gY29tcGxpYW50IGRhdGEgc3RyZWFtIGZvciBmdXJ0aGVy IHByb2Nlc3NpbmcuIFBsZWFzZSByZWZlcgo+IHRvIFBHMjkwIGZvciBkZXRhaWxzLgo+IAo+IFRo ZSBkcml2ZXIgaXMgdXNlZCB0byBjb25maWd1cmUgdGhlIElQIHRvIGFkZCBmcmFtZXIsIHNlYXJj aCBmb3IKPiBzcGVjaWZpYyBtb2RlcywgZ2V0IHRoZSBkZXRlY3RlZCBtb2RlLCBzdHJlYW0gcGFy YW1ldGVycywgZXJyb3JzLCBldGMuCj4gSXQgYWxzbyBnZW5lcmF0ZXMgZXZlbnRzIGZvciB2aWRl byBsb2NrL3VubG9jaywgYnJpZGdlIG92ZXIvdW5kZXIgZmxvdy4KPiAKPiBUaGUgZHJpdmVyIHN1 cHBvcnRzIDEwLzEyIGJwYyBZVVYgNDIyIG1lZGlhIGJ1cyBmb3JtYXQgY3VycmVudGx5LiBJdCBh bHNvCj4gZGVjb2RlcyB0aGUgc3RyZWFtIHBhcmFtZXRlcnMgYmFzZWQgb24gdGhlIFNUMzUyIHBh Y2tldCBlbWJlZGRlZCBpbiB0aGUKPiBzdHJlYW0uIEluIGNhc2UgdGhlIFNUMzUyIHBhY2tldCBp c24ndCBwcmVzZW50IGluIHRoZSBzdHJlYW0sIHRoZSBjb3JlJ3MKPiBkZXRlY3RlZCBwcm9wZXJ0 aWVzIGFyZSB1c2VkIHRvIHNldCBzdHJlYW0gcHJvcGVydGllcy4KCkFzIGNvbW1lbnRlZCBvbiBw YXRjaCAxLzIsIEkgZG9uJ3Qgc2VlIGEgbWVudGlvbiBvZiAxMiBicGMgaW4gdGhlCmRvY3VtZW50 YXRpb24uIExldCdzIGRpc2N1c3MgaXQgYXMgcGFydCBvZiBwYXRjaCAxLzIuCgo+IFRoZSBkcml2 ZXIgY3VycmVudGx5IHN1cHBvcnRzIG9ubHkgdGhlIEFYSTQtU3RyZWFtIElQIGNvbmZpZ3VyYXRp b24uCj4gCj4gU2lnbmVkLW9mZi1ieTogVmlzaGFsIFNhZ2FyIDx2aXNoYWwuc2FnYXJAeGlsaW54 LmNvbT4KPiAtLS0KPiB2Mgo+IC0gQWRkZWQgRFYgdGltaW5nIHN1cHBvcnQgYmFzZWQgb24gSGFu cyBWZXJrdWlsxZsgZmVlZGJhY2sKPiAtIE1vcmUgZG9jdW1lbnRhdGlvbiB0byBjdXN0b20gdjRs IGNvbnRyb2xzIGFuZCBldmVudHMKPiAtIEZpeGVkIEh5dW7FmyBjb21tZW50cwo+IC0gQWRkZWQg bWFjcm8gZm9yIG1hc2tpbmcgYW5kIHNoaWZ0aW5nIGFzIHBlciBKb2UgUGVyY2hlcyBjb21tZW50 cwo+IC0gVXBkYXRlZCB0byBsYXRlc3QgYXMgcGVyIFhpbGlueCBnaXRodWIgcmVwbyBkcml2ZXIg bGlrZQo+ICAgYWRkaW5nIG5ldyBEViB0aW1pbmdzIG5vdCBpbiBtYWlubGluZSB5ZXQgdXB0aWxs IDAzLzIxLzIwCj4gCj4gIGRyaXZlcnMvbWVkaWEvcGxhdGZvcm0veGlsaW54L0tjb25maWcgICAg ICAgICB8ICAgMTEgKwo+ICBkcml2ZXJzL21lZGlhL3BsYXRmb3JtL3hpbGlueC9NYWtlZmlsZSAg ICAgICAgfCAgICAxICsKPiAgLi4uL21lZGlhL3BsYXRmb3JtL3hpbGlueC94aWxpbngtc2Rpcnhz cy5jICAgIHwgMjE2MiArKysrKysrKysrKysrKysrKwo+ICBpbmNsdWRlL3VhcGkvbGludXgveGls aW54LXNkaXJ4c3MuaCAgICAgICAgICAgfCAgMTc5ICsrCj4gIGluY2x1ZGUvdWFwaS9saW51eC94 aWxpbngtdjRsMi1jb250cm9scy5oICAgICB8ICAgNjcgKwo+ICA1IGZpbGVzIGNoYW5nZWQsIDI0 MjAgaW5zZXJ0aW9ucygrKQo+ICBjcmVhdGUgbW9kZSAxMDA2NDQgZHJpdmVycy9tZWRpYS9wbGF0 Zm9ybS94aWxpbngveGlsaW54LXNkaXJ4c3MuYwo+ICBjcmVhdGUgbW9kZSAxMDA2NDQgaW5jbHVk ZS91YXBpL2xpbnV4L3hpbGlueC1zZGlyeHNzLmgKPiAKPiBkaWZmIC0tZ2l0IGEvZHJpdmVycy9t ZWRpYS9wbGF0Zm9ybS94aWxpbngvS2NvbmZpZyBiL2RyaXZlcnMvbWVkaWEvcGxhdGZvcm0veGls aW54L0tjb25maWcKPiBpbmRleCAwMWM5NmZiNjY0MTQuLjc3MDkxMzE4YTljOSAxMDA2NDQKPiAt LS0gYS9kcml2ZXJzL21lZGlhL3BsYXRmb3JtL3hpbGlueC9LY29uZmlnCj4gKysrIGIvZHJpdmVy cy9tZWRpYS9wbGF0Zm9ybS94aWxpbngvS2NvbmZpZwo+IEBAIC0xMiw2ICsxMiwxNyBAQCBjb25m aWcgVklERU9fWElMSU5YCj4gIAo+ICBpZiBWSURFT19YSUxJTlgKPiAgCj4gK2NvbmZpZyBWSURF T19YSUxJTlhfU0RJUlhTUwo+ICsJdHJpc3RhdGUgIlhpbGlueCBVSEQgU0RJIFJ4IFN1YnN5c3Rl bSIKPiArCWhlbHAKPiArCSAgRHJpdmVyIGZvciBYaWxpbnggVUhELVNESSBSeCBTdWJzeXN0ZW0u IFRoaXMgaXMgYSBWNEwgc3ViLWRldmljZQo+ICsJICBiYXNlZCBkcml2ZXIgdGhhdCB0YWtlcyBp bnB1dCBmcm9tIGEgU0RJIHNvdXJjZSBsaWtlIFNESSBjYW1lcmEgYW5kCj4gKwkgIGNvbnZlcnRz IGl0IGludG8gYW4gQVhJNC1TdHJlYW0uIFRoZSBzdWJzeXN0ZW0gY29tcHJpc2VzIG9mIGEgU01Q VEUKCnMvY29tcHJpc2VzIG9mL2NvbXByaXNlcy8KCj4gKwkgIFVIRC1TREkgUnggY29yZSwgYSBT REkgUnggdG8gTmF0aXZlIFZpZGVvIGJyaWRnZSBhbmQgYSBWaWRlbyBJbiB0bwo+ICsJICBBWEk0 LVN0cmVhbSBicmlkZ2UuIFRoZSBkcml2ZXIgaXMgdXNlZCB0byBzZXQgZGlmZmVyZW50IHN0cmVh bQo+ICsJICBkZXRlY3Rpb24gbW9kZXMgYW5kIGlkZW50aWZ5IHN0cmVhbSBwcm9wZXJ0aWVzIHRv IHByb3Blcmx5IGNvbmZpZ3VyZQo+ICsJICBkb3duc3RyZWFtLgo+ICsKPiAgY29uZmlnIFZJREVP X1hJTElOWF9UUEcKPiAgCXRyaXN0YXRlICJYaWxpbnggVmlkZW8gVGVzdCBQYXR0ZXJuIEdlbmVy YXRvciIKPiAgCWRlcGVuZHMgb24gVklERU9fWElMSU5YCj4gZGlmZiAtLWdpdCBhL2RyaXZlcnMv bWVkaWEvcGxhdGZvcm0veGlsaW54L01ha2VmaWxlIGIvZHJpdmVycy9tZWRpYS9wbGF0Zm9ybS94 aWxpbngvTWFrZWZpbGUKPiBpbmRleCA0Y2RjMGIxZWM3YTUuLjZjMzc1ZjAzZjU4NyAxMDA2NDQK PiAtLS0gYS9kcml2ZXJzL21lZGlhL3BsYXRmb3JtL3hpbGlueC9NYWtlZmlsZQo+ICsrKyBiL2Ry aXZlcnMvbWVkaWEvcGxhdGZvcm0veGlsaW54L01ha2VmaWxlCj4gQEAgLTIsNiArMiw3IEBACj4g IAo+ICB4aWxpbngtdmlkZW8tb2JqcyArPSB4aWxpbngtZG1hLm8geGlsaW54LXZpcC5vIHhpbGlu eC12aXBwLm8KPiAgCj4gK29iai0kKENPTkZJR19WSURFT19YSUxJTlhfU0RJUlhTUykgKz0geGls aW54LXNkaXJ4c3Mubwo+ICBvYmotJChDT05GSUdfVklERU9fWElMSU5YKSArPSB4aWxpbngtdmlk ZW8ubwo+ICBvYmotJChDT05GSUdfVklERU9fWElMSU5YX1RQRykgKz0geGlsaW54LXRwZy5vCj4g IG9iai0kKENPTkZJR19WSURFT19YSUxJTlhfVlRDKSArPSB4aWxpbngtdnRjLm8KPiBkaWZmIC0t Z2l0IGEvZHJpdmVycy9tZWRpYS9wbGF0Zm9ybS94aWxpbngveGlsaW54LXNkaXJ4c3MuYyBiL2Ry aXZlcnMvbWVkaWEvcGxhdGZvcm0veGlsaW54L3hpbGlueC1zZGlyeHNzLmMKPiBuZXcgZmlsZSBt b2RlIDEwMDY0NAo+IGluZGV4IDAwMDAwMDAwMDAwMC4uYzUzNmVhM2FhYTBkCj4gLS0tIC9kZXYv bnVsbAo+ICsrKyBiL2RyaXZlcnMvbWVkaWEvcGxhdGZvcm0veGlsaW54L3hpbGlueC1zZGlyeHNz LmMKPiBAQCAtMCwwICsxLDIxNjIgQEAKPiArLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEdQ TC0yLjAKPiArLyoKPiArICogRHJpdmVyIGZvciBYaWxpbnggU0RJIFJ4IFN1YnN5c3RlbQo+ICsg Kgo+ICsgKiBDb3B5cmlnaHQgKEMpIDIwMTcgLSAyMDIwIFhpbGlueCwgSW5jLgo+ICsgKgo+ICsg KiBDb250YWN0czogVmlzaGFsIFNhZ2FyIDx2aXNoYWwuc2FnYXJAeGlsaW54LmNvbT4KPiArICoK CllvdSBjYW4gcmVtb3ZlIHRoaXMgYmxhbmsgbGluZS4KCj4gKyAqLwo+ICsKPiArI2luY2x1ZGUg PGR0LWJpbmRpbmdzL21lZGlhL3hpbGlueC12aXAuaD4KPiArI2luY2x1ZGUgPGxpbnV4L2JpdG9w cy5oPgo+ICsjaW5jbHVkZSA8bGludXgvY29tcGlsZXIuaD4KPiArI2luY2x1ZGUgPGxpbnV4L2Ns ay5oPgoKWW91IG5lYXJseSBnb3QgdGhlIGFscGhhYmV0aWNhbCBvcmRlciByaWdodCA7LSkKCj4g KyNpbmNsdWRlIDxsaW51eC9kZWxheS5oPgoKTm8gdXNlIG9mIGRlbGF5IG9yIHNsZWVwIGZ1bmN0 aW9ucyBpbiB0aGUgY29kZSwgaXMgdGhpcyBuZWVkZWQgPwoKPiArI2luY2x1ZGUgPGxpbnV4L2Rl dmljZS5oPgoKWW91IGNhbiBwcm9iYWJseSBkcm9wIHRoaXMgb25lIGFzIHlvdSBpbmNsdWRlIHBs YXRmb3JtX2RldmljZS5oLgoKPiArI2luY2x1ZGUgPGxpbnV4L2ludGVycnVwdC5oPgo+ICsjaW5j bHVkZSA8bGludXgvaW8uaD4KPiArI2luY2x1ZGUgPGxpbnV4L2tlcm5lbC5oPgo+ICsjaW5jbHVk ZSA8bGludXgvbW9kdWxlLmg+Cj4gKyNpbmNsdWRlIDxsaW51eC9vZi5oPgo+ICsjaW5jbHVkZSA8 bGludXgvb2ZfaXJxLmg+CgpJIGRvbid0IHRoaW5rIG9mX2lycSBpcyBuZWVkZWQgZWl0aGVyLgoK PiArI2luY2x1ZGUgPGxpbnV4L3BsYXRmb3JtX2RldmljZS5oPgo+ICsjaW5jbHVkZSA8bGludXgv cG0uaD4KPiArI2luY2x1ZGUgPGxpbnV4L3NsYWIuaD4KPiArI2luY2x1ZGUgPGxpbnV4L3NwaW5s b2NrLmg+Cj4gKyNpbmNsdWRlIDxsaW51eC9zcGlubG9ja190eXBlcy5oPgoKVGhlIGRyaXZlciBk b2Vzbid0IHNlZW1zIHRvIHVzZSBzcGlubG9ja3MsIHlvdSBjYW4gcmVtb3ZlIHRob3NlIHR3bwpo ZWFkZXJzLgoKPiArI2luY2x1ZGUgPGxpbnV4L3R5cGVzLmg+Cj4gKyNpbmNsdWRlIDxsaW51eC92 NGwyLWR2LXRpbWluZ3MuaD4KPiArI2luY2x1ZGUgPGxpbnV4L3Y0bDItc3ViZGV2Lmg+Cj4gKyNp bmNsdWRlIDxsaW51eC94aWxpbngtc2Rpcnhzcy5oPgo+ICsjaW5jbHVkZSA8bGludXgveGlsaW54 LXY0bDItY29udHJvbHMuaD4KPiArI2luY2x1ZGUgPG1lZGlhL21lZGlhLWVudGl0eS5oPgo+ICsj aW5jbHVkZSA8bWVkaWEvdjRsMi1jb21tb24uaD4KPiArI2luY2x1ZGUgPG1lZGlhL3Y0bDItY3Ry bHMuaD4KPiArI2luY2x1ZGUgPG1lZGlhL3Y0bDItZXZlbnQuaD4KPiArI2luY2x1ZGUgPG1lZGlh L3Y0bDItZndub2RlLmg+Cj4gKyNpbmNsdWRlIDxtZWRpYS92NGwyLXN1YmRldi5oPgo+ICsjaW5j bHVkZSAieGlsaW54LXZpcC5oIgo+ICsKPiArLyoKPiArICogU0RJIFJ4IHJlZ2lzdGVyIG1hcCwg Yml0bWFzayBhbmQgb2Zmc2V0cwo+ICsgKi8KPiArI2RlZmluZSBYU0RJUlhfUlNUX0NUUkxfUkVH CQkweDAwCj4gKyNkZWZpbmUgWFNESVJYX01ETF9DVFJMX1JFRwkJMHgwNAo+ICsjZGVmaW5lIFhT RElSWF9HTEJMX0lFUl9SRUcJCTB4MEMKPiArI2RlZmluZSBYU0RJUlhfSVNSX1JFRwkJCTB4MTAK PiArI2RlZmluZSBYU0RJUlhfSUVSX1JFRwkJCTB4MTQKPiArI2RlZmluZSBYU0RJUlhfU1QzNTJf VkFMSURfUkVHCQkweDE4Cj4gKyNkZWZpbmUgWFNESVJYX1NUMzUyX0RTMV9SRUcJCTB4MUMKCkNv dWxkIHlvdSB1c2UgbG93ZXItY2FzZSBoZXggdmFsdWVzID8gVGhhdCdzIHRoZSBtb3N0IGNvbW1v biBvcHRpb24gaW4Ka2VybmVsIGNvZGUuIElmIHlvdSB1c2UgdmltLAoKOiVzL1w8MHhbMC05QS1G XVwrXD4vXExcMC8KCkknbSBzdXJlIHRoZXJlJ3MgYW4gZW1hY3MgZXF1aXZhbGVudCA6LSkKCj4g KyNkZWZpbmUgWFNESVJYX1NUMzUyX0RTM19SRUcJCTB4MjAKPiArI2RlZmluZSBYU0RJUlhfU1Qz NTJfRFM1X1JFRwkJMHgyNAo+ICsjZGVmaW5lIFhTRElSWF9TVDM1Ml9EUzdfUkVHCQkweDI4Cj4g KyNkZWZpbmUgWFNESVJYX1NUMzUyX0RTOV9SRUcJCTB4MkMKPiArI2RlZmluZSBYU0RJUlhfU1Qz NTJfRFMxMV9SRUcJCTB4MzAKPiArI2RlZmluZSBYU0RJUlhfU1QzNTJfRFMxM19SRUcJCTB4MzQK PiArI2RlZmluZSBYU0RJUlhfU1QzNTJfRFMxNV9SRUcJCTB4MzgKPiArI2RlZmluZSBYU0RJUlhf VkVSU0lPTl9SRUcJCTB4M0MKPiArI2RlZmluZSBYU0RJUlhfU1NfQ09ORklHX1JFRwkJMHg0MAo+ ICsjZGVmaW5lIFhTRElSWF9NT0RFX0RFVF9TVEFUX1JFRwkweDQ0Cj4gKyNkZWZpbmUgWFNESVJY X1RTX0RFVF9TVEFUX1JFRwkJMHg0OAo+ICsjZGVmaW5lIFhTRElSWF9FREhfU1RBVF9SRUcJCTB4 NEMKPiArI2RlZmluZSBYU0RJUlhfRURIX0VSUkNOVF9FTl9SRUcJMHg1MAo+ICsjZGVmaW5lIFhT RElSWF9FREhfRVJSQ05UX1JFRwkJMHg1NAo+ICsjZGVmaW5lIFhTRElSWF9DUkNfRVJSQ05UX1JF RwkJMHg1OAo+ICsjZGVmaW5lIFhTRElSWF9WSURfTE9DS19XSU5ET1dfUkVHCTB4NUMKPiArI2Rl ZmluZSBYU0RJUlhfU0JfUlhfU1RTX1JFRwkJMHg2MAo+ICsKPiArI2RlZmluZSBYU0RJUlhfUlNU X0NUUkxfU1NfRU5fTUFTSwkJCUJJVCgwKQo+ICsjZGVmaW5lIFhTRElSWF9SU1RfQ1RSTF9TUlNU X01BU0sJCQlCSVQoMSkKPiArI2RlZmluZSBYU0RJUlhfUlNUX0NUUkxfUlNUX0NSQ19FUlJDTlRf TUFTSwkJQklUKDIpCj4gKyNkZWZpbmUgWFNESVJYX1JTVF9DVFJMX1JTVF9FREhfRVJSQ05UX01B U0sJCUJJVCgzKQo+ICsjZGVmaW5lIFhTRElSWF9SU1RfQ1RSTF9TRElSWF9CUklER0VfRU5CX01B U0sJCUJJVCg4KQo+ICsjZGVmaW5lIFhTRElSWF9SU1RfQ1RSTF9WSURJTl9BWEk0U19NT0RfRU5C X01BU0sJQklUKDkpCj4gKyNkZWZpbmUgWFNESVJYX1JTVF9DVFJMX0JSSURHRV9DSF9GTVRfT0ZG U0VUCQkxMAo+ICsjZGVmaW5lIFhTRElSWF9SU1RfQ1RSTF9CUklER0VfQ0hfRk1UX01BU0sJCUdF Tk1BU0soMTIsIDEwKQo+ICsjZGVmaW5lIFhTRElSWF9SU1RfQ1RSTF9CUklER0VfQ0hfRk1UX1lV VjQ0NAkJMQo+ICsKPiArI2RlZmluZSBYU0RJUlhfTURMX0NUUkxfRlJNX0VOX01BU0sJCUJJVCg0 KQo+ICsjZGVmaW5lIFhTRElSWF9NRExfQ1RSTF9NT0RFX0RFVF9FTl9NQVNLCUJJVCg1KQo+ICsj ZGVmaW5lIFhTRElSWF9NRExfQ1RSTF9NT0RFX0hEX0VOX01BU0sJCUJJVCg4KQo+ICsjZGVmaW5l IFhTRElSWF9NRExfQ1RSTF9NT0RFX1NEX0VOX01BU0sJCUJJVCg5KQo+ICsjZGVmaW5lIFhTRElS WF9NRExfQ1RSTF9NT0RFXzNHX0VOX01BU0sJCUJJVCgxMCkKPiArI2RlZmluZSBYU0RJUlhfTURM X0NUUkxfTU9ERV82R19FTl9NQVNLCQlCSVQoMTEpCj4gKyNkZWZpbmUgWFNESVJYX01ETF9DVFJM X01PREVfMTJHSV9FTl9NQVNLCUJJVCgxMikKPiArI2RlZmluZSBYU0RJUlhfTURMX0NUUkxfTU9E RV8xMkdGX0VOX01BU0sJQklUKDEzKQo+ICsjZGVmaW5lIFhTRElSWF9NRExfQ1RSTF9NT0RFX0FV VE9fREVUX01BU0sJR0VOTUFTSygxMywgOCkKPiArCj4gKyNkZWZpbmUgWFNESVJYX01ETF9DVFJM X0ZPUkNFRF9NT0RFX09GRlNFVAkxNgo+ICsjZGVmaW5lIFhTRElSWF9NRExfQ1RSTF9GT1JDRURf TU9ERV9NQVNLCUdFTk1BU0soMTgsIDE2KQo+ICsKPiArI2RlZmluZSBYU0RJUlhfR0xCTF9JTlRS X0VOX01BU0sJQklUKDApCj4gKwo+ICsjZGVmaW5lIFhTRElSWF9JTlRSX1ZJRExPQ0tfTUFTSwlC SVQoMCkKPiArI2RlZmluZSBYU0RJUlhfSU5UUl9WSURVTkxPQ0tfTUFTSwlCSVQoMSkKPiArI2Rl ZmluZSBYU0RJUlhfSU5UUl9PVkVSRkxPV19NQVNLCUJJVCg5KQo+ICsjZGVmaW5lIFhTRElSWF9J TlRSX1VOREVSRkxPV19NQVNLCUJJVCgxMCkKPiArCj4gKyNkZWZpbmUgWFNESVJYX0lOVFJfQUxM X01BU0sJKFhTRElSWF9JTlRSX1ZJRExPQ0tfTUFTSyB8XAo+ICsJCQkJWFNESVJYX0lOVFJfVklE VU5MT0NLX01BU0sgfFwKPiArCQkJCVhTRElSWF9JTlRSX09WRVJGTE9XX01BU0sgfFwKPiArCQkJ CVhTRElSWF9JTlRSX1VOREVSRkxPV19NQVNLKQo+ICsKPiArI2RlZmluZSBYU0RJUlhfU1QzNTJf VkFMSURfRFMxX01BU0sJQklUKDApCj4gKyNkZWZpbmUgWFNESVJYX1NUMzUyX1ZBTElEX0RTM19N QVNLCUJJVCgxKQo+ICsjZGVmaW5lIFhTRElSWF9TVDM1Ml9WQUxJRF9EUzVfTUFTSwlCSVQoMikK PiArI2RlZmluZSBYU0RJUlhfU1QzNTJfVkFMSURfRFM3X01BU0sJQklUKDMpCj4gKyNkZWZpbmUg WFNESVJYX1NUMzUyX1ZBTElEX0RTOV9NQVNLCUJJVCg0KQo+ICsjZGVmaW5lIFhTRElSWF9TVDM1 Ml9WQUxJRF9EUzExX01BU0sJQklUKDUpCj4gKyNkZWZpbmUgWFNESVJYX1NUMzUyX1ZBTElEX0RT MTNfTUFTSwlCSVQoNikKPiArI2RlZmluZSBYU0RJUlhfU1QzNTJfVkFMSURfRFMxNV9NQVNLCUJJ VCg3KQo+ICsKPiArI2RlZmluZSBYU0RJUlhfTU9ERV9ERVRfU1RBVF9SWF9NT0RFX01BU0sJR0VO TUFTSygyLCAwKQo+ICsjZGVmaW5lIFhTRElSWF9NT0RFX0RFVF9TVEFUX01PREVfTE9DS19NQVNL CUJJVCgzKQo+ICsjZGVmaW5lIFhTRElSWF9NT0RFX0RFVF9TVEFUX0FDVF9TVFJFQU1fTUFTSwlH RU5NQVNLKDYsIDQpCj4gKyNkZWZpbmUgWFNESVJYX01PREVfREVUX1NUQVRfQUNUX1NUUkVBTV9P RkZTRVQJNAo+ICsjZGVmaW5lIFhTRElSWF9NT0RFX0RFVF9TVEFUX0xWTEJfM0dfTUFTSwlCSVQo NykKPiArCj4gKyNkZWZpbmUgWFNESVJYX1RTX0RFVF9TVEFUX0xPQ0tFRF9NQVNLCQlCSVQoMCkK PiArI2RlZmluZSBYU0RJUlhfVFNfREVUX1NUQVRfU0NBTl9NQVNLCQlCSVQoMSkKPiArI2RlZmlu ZSBYU0RJUlhfVFNfREVUX1NUQVRfU0NBTl9PRkZTRVQJCSgxKQo+ICsjZGVmaW5lIFhTRElSWF9U U19ERVRfU1RBVF9GQU1JTFlfTUFTSwkJR0VOTUFTSyg3LCA0KQo+ICsjZGVmaW5lIFhTRElSWF9U U19ERVRfU1RBVF9GQU1JTFlfT0ZGU0VUCSg0KQo+ICsjZGVmaW5lIFhTRElSWF9UU19ERVRfU1RB VF9SQVRFX01BU0sJCUdFTk1BU0soMTEsIDgpCj4gKyNkZWZpbmUgWFNESVJYX1RTX0RFVF9TVEFU X1JBVEVfT0ZGU0VUCQkoOCkKPiArCj4gKyNkZWZpbmUgWFNESVJYX1RTX0RFVF9TVEFUX1JBVEVf Tk9ORQkJMHgwCj4gKyNkZWZpbmUgWFNESVJYX1RTX0RFVF9TVEFUX1JBVEVfMjNfOThIWgkJMHgy Cj4gKyNkZWZpbmUgWFNESVJYX1RTX0RFVF9TVEFUX1JBVEVfMjRIWgkJMHgzCj4gKyNkZWZpbmUg WFNESVJYX1RTX0RFVF9TVEFUX1JBVEVfNDdfOTVIWgkJMHg0Cj4gKyNkZWZpbmUgWFNESVJYX1RT X0RFVF9TVEFUX1JBVEVfMjVIWgkJMHg1Cj4gKyNkZWZpbmUgWFNESVJYX1RTX0RFVF9TVEFUX1JB VEVfMjlfOTdIWgkJMHg2Cj4gKyNkZWZpbmUgWFNESVJYX1RTX0RFVF9TVEFUX1JBVEVfMzBIWgkJ MHg3Cj4gKyNkZWZpbmUgWFNESVJYX1RTX0RFVF9TVEFUX1JBVEVfNDhIWgkJMHg4Cj4gKyNkZWZp bmUgWFNESVJYX1RTX0RFVF9TVEFUX1JBVEVfNTBIWgkJMHg5Cj4gKyNkZWZpbmUgWFNESVJYX1RT X0RFVF9TVEFUX1JBVEVfNTlfOTRIWgkJMHhBCj4gKyNkZWZpbmUgWFNESVJYX1RTX0RFVF9TVEFU X1JBVEVfNjBIWgkJMHhCCj4gKwo+ICsjZGVmaW5lIFhTRElSWF9FREhfU1RBVF9FREhfQVBfTUFT SwlCSVQoMCkKPiArI2RlZmluZSBYU0RJUlhfRURIX1NUQVRfRURIX0ZGX01BU0sJQklUKDEpCj4g KyNkZWZpbmUgWFNESVJYX0VESF9TVEFUX0VESF9BTkNfTUFTSwlCSVQoMikKPiArI2RlZmluZSBY U0RJUlhfRURIX1NUQVRfQVBfRkxBR19NQVNLCUdFTk1BU0soOCwgNCkKPiArI2RlZmluZSBYU0RJ UlhfRURIX1NUQVRfRkZfRkxBR19NQVNLCUdFTk1BU0soMTMsIDkpCj4gKyNkZWZpbmUgWFNESVJY X0VESF9TVEFUX0FOQ19GTEFHX01BU0sJR0VOTUFTSygxOCwgMTQpCj4gKyNkZWZpbmUgWFNESVJY X0VESF9TVEFUX1BLVF9GTEFHX01BU0sJR0VOTUFTSygyMiwgMTkpCj4gKwo+ICsjZGVmaW5lIFhT RElSWF9FREhfRVJSQ05UX0NPVU5UX01BU0sJR0VOTUFTSygxNSwgMCkKPiArCj4gKyNkZWZpbmUg WFNESVJYX0NSQ19FUlJDTlRfQ09VTlRfTUFTSwlHRU5NQVNLKDMxLCAxNikKPiArI2RlZmluZSBY U0RJUlhfQ1JDX0VSUkNOVF9EU19DUkNfTUFTSwlHRU5NQVNLKDE1LCAwKQo+ICsKPiArI2RlZmlu ZSBYU0RJUlhfVkVSU0lPTl9SRVZfTUFTSwkJR0VOTUFTSyg3LCAwKQo+ICsjZGVmaW5lIFhTRElS WF9WRVJTSU9OX1BBVENISURfTUFTSwlHRU5NQVNLKDExLCA4KQo+ICsjZGVmaW5lIFhTRElSWF9W RVJTSU9OX1ZFUl9SRVZfTUFTSwlHRU5NQVNLKDE1LCAxMikKPiArI2RlZmluZSBYU0RJUlhfVkVS U0lPTl9WRVJfTUlOX01BU0sJR0VOTUFTSygyMywgMTYpCj4gKyNkZWZpbmUgWFNESVJYX1ZFUlNJ T05fVkVSX01BSl9NQVNLCUdFTk1BU0soMzEsIDI0KQo+ICsKPiArI2RlZmluZSBYU0RJUlhfU1Nf Q09ORklHX0VESF9JTkNMVURFRF9NQVNLCQlCSVQoMSkKPiArCj4gKyNkZWZpbmUgWFNESVJYX1NU QVRfU0JfUlhfVERBVEFfQ0hBTkdFX0RPTkVfTUFTSwlCSVQoMCkKPiArI2RlZmluZSBYU0RJUlhf U1RBVF9TQl9SWF9UREFUQV9DSEFOR0VfRkFJTF9NQVNLCUJJVCgxKQo+ICsjZGVmaW5lIFhTRElS WF9TVEFUX1NCX1JYX1REQVRBX0dUX1JFU0VURE9ORV9NQVNLCUJJVCgyKQo+ICsjZGVmaW5lIFhT RElSWF9TVEFUX1NCX1JYX1REQVRBX0dUX0JJVFJBVEVfTUFTSwkJQklUKDMpCj4gKwo+ICsjZGVm aW5lIFhTRElSWF9ERUZBVUxUX1dJRFRICSgxOTIwKQoKTm8gbmVlZCBmb3IgcGFyZW50aGVzZXMg YXJvdW5kIGludGVnZXIgdmFsdWVzIGluIG1hY3Jvcy4KCj4gKyNkZWZpbmUgWFNESVJYX0RFRkFV TFRfSEVJR0hUCSgxMDgwKQo+ICsKPiArI2RlZmluZSBYU0RJUlhfTUFYX1NUUl9MRU5HVEgJMTYK PiArCj4gKyNkZWZpbmUgWFNESVJYU1NfU0RJX1NURF8zRwkJMAo+ICsjZGVmaW5lIFhTRElSWFNT X1NESV9TVERfNkcJCTEKPiArI2RlZmluZSBYU0RJUlhTU19TRElfU1REXzEyR184RFMJMgoKU2hv dWxkIHRoZXNlIHRocmVlIGNvbnN0YW50cyBiZSBwbGFjZWQgaW4gYW4gZW51bSA/IFRoZQp4c2Rp cnhzc19jb3JlLm1vZGUgZmllbGQgd291bGQgdGhlbiBiZWNvbWUgYW4gZW51bS4KCj4gKwo+ICsj ZGVmaW5lIFhTRElSWF9ERUZBVUxUX1ZJREVPX0xPQ0tfV0lORE9XCTB4MzAwMAo+ICsKPiArI2Rl ZmluZSBYU0RJUlhfTU9ERV9IRF9NQVNLCTB4MAo+ICsjZGVmaW5lIFhTRElSWF9NT0RFX1NEX01B U0sJMHgxCj4gKyNkZWZpbmUgWFNESVJYX01PREVfM0dfTUFTSwkweDIKPiArI2RlZmluZSBYU0RJ UlhfTU9ERV82R19NQVNLCTB4NAo+ICsjZGVmaW5lIFhTRElSWF9NT0RFXzEyR0lfTUFTSwkweDUK PiArI2RlZmluZSBYU0RJUlhfTU9ERV8xMkdGX01BU0sJMHg2Cj4gKwo+ICsvKiBNYXhpbXVtIG51 bWJlciBvZiBldmVudHMgcGVyIGZpbGUgaGFuZGxlLiAqLwo+ICsjZGVmaW5lIFhTRElSWF9NQVhf RVZFTlRTCSgxMjgpCgpEbyB3ZSByZWFsbHkgbmVlZCBzdWNoIGEgaGlnaCBudW1iZXIgPyBIb3cg b2Z0ZW4gYXJlIHRoZSBvdmVyZmxvdyBhbmQKdW5kZXJmbG93IGV4cGVjdGVkID8KCj4gKwo+ICsv KiBTVDM1MiByZWxhdGVkIG1hY3JvcyAqLwo+ICsjZGVmaW5lIFhTVDM1Ml9QQVlMT0FEX0JZVEUx X01BU0sJMHhGRgo+ICsjZGVmaW5lIFhTVDM1Ml9QQVlMT0FEX0JZVEUxX09GRlNFVAkwCj4gKyNk ZWZpbmUgWFNUMzUyX1BBWUxPQURfQllURTJfT0ZGU0VUCTgKPiArI2RlZmluZSBYU1QzNTJfUEFZ TE9BRF9CWVRFM19PRkZTRVQJMTYKPiArI2RlZmluZSBYU1QzNTJfUEFZTE9BRF9CWVRFNF9PRkZT RVQJMjQKPiArCj4gKyNkZWZpbmUgWFNUMzUyX0JZVEUxX1NUMjkyXzF4NzIwTF8xXzVHCQkweDg0 Cj4gKyNkZWZpbmUgWFNUMzUyX0JZVEUxX1NUMjkyXzF4MTA4MExfMV81RwkJMHg4NQo+ICsjZGVm aW5lIFhTVDM1Ml9CWVRFMV9TVDQyNV8yMDA4Xzc1MExfM0dCCTB4ODgKPiArI2RlZmluZSBYU1Qz NTJfQllURTFfU1Q0MjVfMjAwOF8xMTI1TF8zR0EJMHg4OQo+ICsjZGVmaW5lIFhTVDM1Ml9CWVRF MV9TVDM3Ml9ETF8zR0IJCTB4OEEKPiArI2RlZmluZSBYU1QzNTJfQllURTFfU1QzNzJfMng3MjBM XzNHQgkJMHg4Qgo+ICsjZGVmaW5lIFhTVDM1Ml9CWVRFMV9TVDM3Ml8yeDEwODBMXzNHQgkJMHg4 Qwo+ICsjZGVmaW5lIFhTVDM1Ml9CWVRFMV9TVDIwODFfMTBfMjE2MExfNkcJCTB4QzAKPiArI2Rl ZmluZSBYU1QzNTJfQllURTFfU1QyMDgxXzEwXzJfMTA4MExfNkcJMHhDMQo+ICsjZGVmaW5lIFhT VDM1Ml9CWVRFMV9TVDIwODFfMTBfRExfMjE2MExfNkcJMHhDMgo+ICsjZGVmaW5lIFhTVDM1Ml9C WVRFMV9TVDIwODJfMTBfMjE2MExfMTJHCTB4Q0UKPiArCj4gKyNkZWZpbmUgWFNUMzUyX0JZVEUy X1RTX1RZUEVfTUFTSwkJQklUKDE1KQo+ICsjZGVmaW5lIFhTVDM1Ml9CWVRFMl9UU19UWVBFX09G RlNFVAkJMTUKPiArI2RlZmluZSBYU1QzNTJfQllURTJfUElDX1RZUEVfTUFTSwkJQklUKDE0KQo+ ICsjZGVmaW5lIFhTVDM1Ml9CWVRFMl9QSUNfVFlQRV9PRkZTRVQJCTE0Cj4gKyNkZWZpbmUgWFNU MzUyX0JZVEUyX1RTX1BJQ19UWVBFX0lOVEVSTEFDRUQJMAo+ICsjZGVmaW5lIFhTVDM1Ml9CWVRF Ml9UU19QSUNfVFlQRV9QUk9HUkVTU0lWRQkxCj4gKwo+ICsjZGVmaW5lIFhTVDM1Ml9CWVRFMl9G UFNfTUFTSwkJCTB4Rgo+ICsjZGVmaW5lIFhTVDM1Ml9CWVRFMl9GUFNfT0ZGU0VUCQkJOAo+ICsj ZGVmaW5lIFhTVDM1Ml9CWVRFMl9GUFNfMjRGCQkJMHgyCj4gKyNkZWZpbmUgWFNUMzUyX0JZVEUy X0ZQU18yNAkJCTB4Mwo+ICsjZGVmaW5lIFhTVDM1Ml9CWVRFMl9GUFNfNDhGCQkJMHg0Cj4gKyNk ZWZpbmUgWFNUMzUyX0JZVEUyX0ZQU18yNQkJCTB4NQo+ICsjZGVmaW5lIFhTVDM1Ml9CWVRFMl9G UFNfMzBGCQkJMHg2Cj4gKyNkZWZpbmUgWFNUMzUyX0JZVEUyX0ZQU18zMAkJCTB4Nwo+ICsjZGVm aW5lIFhTVDM1Ml9CWVRFMl9GUFNfNDgJCQkweDgKPiArI2RlZmluZSBYU1QzNTJfQllURTJfRlBT XzUwCQkJMHg5Cj4gKyNkZWZpbmUgWFNUMzUyX0JZVEUyX0ZQU182MEYJCQkweEEKPiArI2RlZmlu ZSBYU1QzNTJfQllURTJfRlBTXzYwCQkJMHhCCj4gKy8qIFRhYmxlIDQgU1QgMjA4MS0xMDoyMDE1 ICovCj4gKyNkZWZpbmUgWFNUMzUyX0JZVEUyX0ZQU185NgkJCTB4Qwo+ICsjZGVmaW5lIFhTVDM1 Ml9CWVRFMl9GUFNfMTAwCQkJMHhECj4gKyNkZWZpbmUgWFNUMzUyX0JZVEUyX0ZQU18xMjAJCQkw eEUKPiArI2RlZmluZSBYU1QzNTJfQllURTJfRlBTXzEyMEYJCQkweEYKPiArCj4gKyNkZWZpbmUg WFNUMzUyX0JZVEUzX0FDVF9MVU1BX0NPVU5UX01BU0sJQklUKDIyKQo+ICsjZGVmaW5lIFhTVDM1 Ml9CWVRFM19BQ1RfTFVNQV9DT1VOVF9PRkZTRVQJMjIKPiArCj4gKyNkZWZpbmUgWFNUMzUyX0JZ VEUzX0NPTE9SX0ZPUk1BVF9NQVNLCQlHRU5NQVNLKDE5LCAxNikKPiArI2RlZmluZSBYU1QzNTJf QllURTNfQ09MT1JfRk9STUFUX09GRlNFVAkxNgo+ICsjZGVmaW5lIFhTVDM1Ml9CWVRFM19DT0xP Ul9GT1JNQVRfNDIyCQkweDAKPiArI2RlZmluZSBYU1QzNTJfQllURTNfQ09MT1JfRk9STUFUX1lV VjQ0NAkweDEKPiArI2RlZmluZSBYU1QzNTJfQllURTNfQ09MT1JfRk9STUFUXzQyMAkJMHgzCj4g KyNkZWZpbmUgWFNUMzUyX0JZVEUzX0NPTE9SX0ZPUk1BVF9HQlIJCTB4Mgo+ICsKPiArI2RlZmlu ZSBYU1QzNTJfQllURTRfQklUX0RFUFRIX01BU0sJCUdFTk1BU0soMjUsIDI0KQo+ICsjZGVmaW5l IFhTVDM1Ml9CWVRFNF9CSVRfREVQVEhfT0ZGU0VUCQkyNAo+ICsjZGVmaW5lIFhTVDM1Ml9CWVRF NF9CSVRfREVQVEhfMTAJCTB4MQo+ICsjZGVmaW5lIFhTVDM1Ml9CWVRFNF9CSVRfREVQVEhfMTIJ CTB4Mgo+ICsKPiArI2RlZmluZSBDTEtfSU5UCQkxNDg1MDAwMDBVTAo+ICsKPiArI2RlZmluZSBy c2hpZnRfYW5kX21hc2sodmFsLCB0eXBlKSBcCj4gKwkJKCgodmFsKSA+PiB0eXBlIyNfT0ZGU0VU KSAmIHR5cGUjI19NQVNLKQo+ICsKPiArI2RlZmluZSBtYXNrX2FuZF9yc2hpZnQodmFsLCB0eXBl KSBcCj4gKwkJKCgodmFsKSAmIHR5cGUjI19NQVNLKSA+PiB0eXBlIyNfT0ZGU0VUKQoKSG93IGFi b3V0IHVzaW5nIEZJRUxEX0dFVCgpIGZyb20gbGludXgvYml0ZmllbGQuaCA/IEl0J3MgbW9yZSBz dGFuZGFyZCwKYW5kIHdpbGwgdGh1cyBiZSBsZXNzIGNvbmZ1c2luZyB0byByZWFkZXJzLgoKPiAr Cj4gKy8qKgo+ICsgKiBlbnVtIHNkaV9mYW1pbHlfZW5jIC0gU0RJIFRyYW5zcG9ydCBWaWRlbyBG b3JtYXQgRGV0ZWN0ZWQgd2l0aCBBY3RpdmUgUGl4ZWxzCj4gKyAqIEBYU0RJUlhfU01QVEVfU1Rf Mjc0OiBTTVBURSBTVCAyNzQgZGV0ZWN0ZWQgd2l0aCBBUCAxOTIweDEwODAKPiArICogQFhTRElS WF9TTVBURV9TVF8yOTY6IFNNUFRFIFNUIDI5NiBkZXRlY3RlZCB3aXRoIEFQIDEyODB4NzIwCj4g KyAqIEBYU0RJUlhfU01QVEVfU1RfMjA0OF8yOiBTTVBURSBTVCAyMDQ4LTIgZGV0ZWN0ZWQgd2l0 aCBBUCAyMDQ4eDEwODAKPiArICogQFhTRElSWF9TTVBURV9TVF8yOTU6IFNNUFRFIFNUIDI5NSBk ZXRlY3RlZCB3aXRoIEFQIDE5MjB4MTA4MAo+ICsgKiBAWFNESVJYX05UU0M6IE5UU0MgZW5jb2Rp bmcgZGV0ZWN0ZWQgd2l0aCBBUCA3MjB4NDg2Cj4gKyAqIEBYU0RJUlhfUEFMOiBQQUwgZW5jb2Rp bmcgZGV0ZWN0ZWQgd2l0aCBBUCA3MjB4NTc2Cj4gKyAqIEBYU0RJUlhfVFNfVU5LTk9XTjogVW5r bm93biBTTVBURSBUcmFuc3BvcnQgZmFtaWx5IHR5cGUKPiArICovCj4gK2VudW0gc2RpX2ZhbWls eV9lbmMgewo+ICsJWFNESVJYX1NNUFRFX1NUXzI3NAk9IDAsCj4gKwlYU0RJUlhfU01QVEVfU1Rf Mjk2CT0gMSwKPiArCVhTRElSWF9TTVBURV9TVF8yMDQ4XzIJPSAyLAo+ICsJWFNESVJYX1NNUFRF X1NUXzI5NQk9IDMsCj4gKwlYU0RJUlhfTlRTQwkJPSA4LAo+ICsJWFNESVJYX1BBTAkJPSA5LAo+ ICsJWFNESVJYX1RTX1VOS05PV04JPSAxNQo+ICt9OwoKVGhpcyBzaG91bGQgaWRlYWxseSBnbyBp biBhIGhlYWRlciBmaWxlIHNoYXJlZCBiZXR3ZWVuIHRoZSBTREkgUlggYW5kClRYLCBhcyBpdCdz IHBhcnQgb2YgdGhlIFVIRC1TREkgSVAgY29yZSwgYnV0IGl0IGNhbiBiZSBkb25lIGxhdGVyLgoK PiArCj4gKy8qKgo+ICsgKiBzdHJ1Y3QgeHNkaXJ4c3NfY29yZSAtIENvcmUgY29uZmlndXJhdGlv biBTREkgUnggU3Vic3lzdGVtIGRldmljZSBzdHJ1Y3R1cmUKPiArICogQGRldjogUGxhdGZvcm0g c3RydWN0dXJlCj4gKyAqIEBpb21lbTogQmFzZSBhZGRyZXNzIG9mIHN1YnN5c3RlbQo+ICsgKiBA aXJxOiByZXF1ZXN0ZWQgaXJxIG51bWJlcgo+ICsgKiBAaW5jbHVkZV9lZGg6IEVESCBwcm9jZXNz b3IgcHJlc2VuY2UKPiArICogQG1vZGU6IDNHLzZHLzEyRyBtb2RlCj4gKyAqIEBjbGtzOiBhcnJh eSBvZiBjbG9ja3MKPiArICogQG51bV9jbGtzOiBudW1iZXIgb2YgY2xvY2tzCj4gKyAqIEBicGM6 IEJpdHMgcGVyIGNvbXBvbmVudCwgY2FuIGJlIDEwIG9yIDEyCj4gKyAqLwo+ICtzdHJ1Y3QgeHNk aXJ4c3NfY29yZSB7Cj4gKwlzdHJ1Y3QgZGV2aWNlICpkZXY7Cj4gKwl2b2lkIF9faW9tZW0gKmlv bWVtOwo+ICsJaW50IGlycTsKPiArCWJvb2wgaW5jbHVkZV9lZGg7Cj4gKwlpbnQgbW9kZTsKPiAr CXN0cnVjdCBjbGtfYnVsa19kYXRhICpjbGtzOwo+ICsJaW50IG51bV9jbGtzOwoKbnVtX2Nsa3Mg aXMgbmV2ZXIgbmVnYXRpdmUsIHlvdSBjYW4gbWFrZSBpdCBhbiB1bnNpZ25lZCBpbnQuCgo+ICsJ dTMyIGJwYzsKPiArfTsKPiArCj4gKy8qKgo+ICsgKiBzdHJ1Y3QgeHNkaXJ4c3Nfc3RhdGUgLSBT REkgUnggU3Vic3lzdGVtIGRldmljZSBzdHJ1Y3R1cmUKPiArICogQGNvcmU6IENvcmUgc3RydWN0 dXJlIGZvciBNSVBJIFNESSBSeCBTdWJzeXN0ZW0KPiArICogQHN1YmRldjogVGhlIHY0bDIgc3Vi ZGV2IHN0cnVjdHVyZQo+ICsgKiBAY3RybF9oYW5kbGVyOiBjb250cm9sIGhhbmRsZXIKPiArICog QGV2ZW50OiBIb2xkcyB0aGUgdmlkZW8gdW5sb2NrIGV2ZW50Cj4gKyAqIEBmb3JtYXQ6IEFjdGl2 ZSBWNEwyIGZvcm1hdCBvbiBzb3VyY2UgcGFkCj4gKyAqIEBkZWZhdWx0X2Zvcm1hdDogZGVmYXVs dCBWNEwyIG1lZGlhIGJ1cyBmb3JtYXQKPiArICogQGZyYW1lX2ludGVydmFsOiBDYXB0dXJlcyB0 aGUgZnJhbWUgcmF0ZQo+ICsgKiBAcGFkOiBzb3VyY2UgbWVkaWEgcGFkCj4gKyAqIEB2aWRsb2Nr d2luOiBWaWRlbyBsb2NrIHdpbmRvdyB2YWx1ZSBzZXQgYnkgY29udHJvbAo+ICsgKiBAZWRobWFz azogRURIIG1hc2sgc2V0IGJ5IGNvbnRyb2wKPiArICogQHNlYXJjaG1hc2s6IFNlYXJjaCBtYXNr IHNldCBieSBjb250cm9sCj4gKyAqIEBzdHJlYW1pbmc6IEZsYWcgZm9yIHN0b3Jpbmcgc3RyZWFt aW5nIHN0YXRlCj4gKyAqIEB2aWRsb2NrZWQ6IEZsYWcgaW5kaWNhdGluZyBTREkgUnggaGFzIGxv Y2tlZCBvbnRvIHZpZGVvIHN0cmVhbQo+ICsgKiBAdHNfaXNfaW50ZXJsYWNlZDogRmxhZyBpbmRp Y2F0aW5nIFRyYW5zcG9ydCBTdHJlYW0gaXMgaW50ZXJsYWNlZC4KPiArICogQGZyYW1lcl9lbmFi bGU6IEZsYWcgZm9yIGZyYW1lciBlbmFibGVkIG9yIG5vdCBzZXQgYnkgY29udHJvbAo+ICsgKgo+ ICsgKiBUaGlzIHN0cnVjdHVyZSBjb250YWlucyB0aGUgZGV2aWNlIGRyaXZlciByZWxhdGVkIHBh cmFtZXRlcnMKPiArICovCj4gK3N0cnVjdCB4c2Rpcnhzc19zdGF0ZSB7Cj4gKwlzdHJ1Y3QgeHNk aXJ4c3NfY29yZSBjb3JlOwo+ICsJc3RydWN0IHY0bDJfc3ViZGV2IHN1YmRldjsKPiArCXN0cnVj dCB2NGwyX2N0cmxfaGFuZGxlciBjdHJsX2hhbmRsZXI7Cj4gKwlzdHJ1Y3QgdjRsMl9ldmVudCBl dmVudDsKCklzIHRoaXMgbmVlZGVkLCBjYW4ndCBpdCBiZSBhIGxvY2FsIHZhcmlhYmxlIGluIHRo ZSBmdW5jdGlvbiB3aGVyZSBpdCBpcwp1c2VkID8KCj4gKwlzdHJ1Y3QgdjRsMl9tYnVzX2ZyYW1l Zm10IGZvcm1hdDsKPiArCXN0cnVjdCB2NGwyX21idXNfZnJhbWVmbXQgZGVmYXVsdF9mb3JtYXQ7 Cj4gKwlzdHJ1Y3QgdjRsMl9mcmFjdCBmcmFtZV9pbnRlcnZhbDsKPiArCXN0cnVjdCBtZWRpYV9w YWQgcGFkOwoKWW91IHdpbGwgbmVlZCB0d28gcGFkcyBhcyB0aGVyZSBzaG91bGQgYmUgdHdvIHBv cnRzIChsZXQncyBkaXNjdXNzIGl0IGFzCnBhcnQgb2YgcGF0Y2ggMS8yKS4KCj4gKwl1MzIgdmlk bG9ja3dpbjsKPiArCXUzMiBlZGhtYXNrOwo+ICsJdTE2IHNlYXJjaG1hc2s7Cj4gKwlib29sIHN0 cmVhbWluZzsKPiArCWJvb2wgdmlkbG9ja2VkOwo+ICsJYm9vbCB0c19pc19pbnRlcmxhY2VkOwo+ ICsJYm9vbCBmcmFtZXJfZW5hYmxlOwo+ICt9OwoKQXMgZm9yIHRoZSBDU0kyLVJYLCBzcGxpdHRp bmcgY29yZSBhbmQgc3RhdGUgaW4gc2VwYXJhdGUgc3RydWN0dXJlcwppc24ndCBhbiBlc3RhYmxp c2hlZCBwcmFjdGljZS4gSSB0aGluayBpdCBsZWFkcyB0byBtb3JlIGNvbXBsZXggY29kZSBhcwp5 b3UgaGF2ZSB0byByZW1lbWJlciBpbiB3aGljaCBzdHJ1Y3R1cmUgZWFjaCBmaWVsZCBpcyBsb2Nh dGVkLgoKPiArCj4gKy8qIExpc3Qgb2YgY2xvY2tzIHJlcXVpcmVkIGJ5IFVIRC1TREkgUnggc3Vi c3lzdGVtICovCj4gK3N0YXRpYyBjb25zdCBjaGFyICogY29uc3QgeHNkaXJ4c3NfY2xrc1tdID0g ewo+ICsJInNfYXhpX2FjbGsiLCAic2RpX3J4X2NsayIsICJ2aWRlb19vdXRfY2xrIiwKPiArfTsK PiArCj4gKy8qIFRPRE8gLSBBZGQgWVVWIDQ0NC80MjAgYW5kIFJCRyAxMC8xMiBicGMgbWJ1cyBm b3JtYXRzIGhlcmUgKi8KCnMvUkJHL1JHQi8gPwoKPiArc3RhdGljIGNvbnN0IHUzMiB4c2Rpcnhz c18xMGJwY19tYnVzX2ZtdHNbXSA9IHsKPiArCU1FRElBX0JVU19GTVRfVVlWWTEwXzFYMjAsCj4g K307Cj4gKwo+ICtzdGF0aWMgY29uc3QgdTMyIHhzZGlyeHNzXzEyYnBjX21idXNfZm10c1tdID0g ewo+ICsJTUVESUFfQlVTX0ZNVF9VWVZZMTJfMVgyNCwKPiArfTsKPiArCj4gK3N0YXRpYyBjb25z dCBzdHJ1Y3QgdjRsMl9kdl90aW1pbmdzIGZtdF9jYXBbXSA9IHsKPiArCVY0TDJfRFZfQlRfU0RJ XzcyMFg0ODdJNjAsCj4gKwlWNEwyX0RWX0JUX0NFQV83MjBYNTc2STUwLAo+ICsJVjRMMl9EVl9C VF9DRUFfMTI4MFg3MjBQMjQsCj4gKwlWNEwyX0RWX0JUX0NFQV8xMjgwWDcyMFAyNSwKPiArCVY0 TDJfRFZfQlRfQ0VBXzEyODBYNzIwUDMwLAo+ICsJVjRMMl9EVl9CVF9DRUFfMTI4MFg3MjBQNTAs Cj4gKwlWNEwyX0RWX0JUX0NFQV8xMjgwWDcyMFA2MCwKPiArCVY0TDJfRFZfQlRfQ0VBXzE5MjBY MTA4MFAyNCwKPiArCVY0TDJfRFZfQlRfQ0VBXzE5MjBYMTA4MFAzMCwKPiArCVY0TDJfRFZfQlRf Q0VBXzE5MjBYMTA4MEk1MCwKPiArCVY0TDJfRFZfQlRfQ0VBXzE5MjBYMTA4MEk2MCwKPiArCVY0 TDJfRFZfQlRfQ0VBXzE5MjBYMTA4MFA1MCwKPiArCVY0TDJfRFZfQlRfQ0VBXzE5MjBYMTA4MFA2 MCwKPiArCVY0TDJfRFZfQlRfQ0VBXzM4NDBYMjE2MFAyNCwKPiArCVY0TDJfRFZfQlRfQ0VBXzM4 NDBYMjE2MFAzMCwKPiArCVY0TDJfRFZfQlRfQ0VBXzM4NDBYMjE2MFA1MCwKPiArCVY0TDJfRFZf QlRfQ0VBXzM4NDBYMjE2MFA2MCwKPiArCVY0TDJfRFZfQlRfQ0VBXzQwOTZYMjE2MFAyNCwKPiAr CVY0TDJfRFZfQlRfQ0VBXzQwOTZYMjE2MFAyNSwKPiArCVY0TDJfRFZfQlRfQ0VBXzQwOTZYMjE2 MFAzMCwKPiArCVY0TDJfRFZfQlRfQ0VBXzQwOTZYMjE2MFA1MCwKPiArCVY0TDJfRFZfQlRfQ0VB XzQwOTZYMjE2MFA2MCwKPiArCj4gKwlYTE5YX1Y0TDJfRFZfQlRfMjA0OFgxMDgwUDI0LAo+ICsJ WExOWF9WNEwyX0RWX0JUXzIwNDhYMTA4MFAyNSwKPiArCVhMTlhfVjRMMl9EVl9CVF8yMDQ4WDEw ODBQMzAsCj4gKwlYTE5YX1Y0TDJfRFZfQlRfMjA0OFgxMDgwSTQ4LAo+ICsJWExOWF9WNEwyX0RW X0JUXzIwNDhYMTA4MEk1MCwKPiArCVhMTlhfVjRMMl9EVl9CVF8yMDQ4WDEwODBJNjAsCj4gKwlY TE5YX1Y0TDJfRFZfQlRfMjA0OFgxMDgwUDQ4LAo+ICsJWExOWF9WNEwyX0RWX0JUXzIwNDhYMTA4 MFA1MCwKPiArCVhMTlhfVjRMMl9EVl9CVF8yMDQ4WDEwODBQNjAsCj4gKwlYTE5YX1Y0TDJfRFZf QlRfMTkyMFgxMDgwUDQ4LAo+ICsJWExOWF9WNEwyX0RWX0JUXzE5MjBYMTA4MEk0OCwKPiArCVhM TlhfVjRMMl9EVl9CVF8zODQwWDIxNjBQNDgsCj4gKwlYTE5YX1Y0TDJfRFZfQlRfNDA5NlgyMTYw UDQ4LAo+ICt9Owo+ICsKPiArc3RydWN0IHhzZGlyeHNzX2R2X21hcCB7Cj4gKwl1MzIgd2lkdGg7 Cj4gKwl1MzIgaGVpZ2h0Owo+ICsJdTMyIGZwczsKPiArCXN0cnVjdCB2NGwyX2R2X3RpbWluZ3Mg Zm9ybWF0Owo+ICt9Owo+ICsKPiArc3RhdGljIGNvbnN0IHN0cnVjdCB4c2Rpcnhzc19kdl9tYXAg eHNkaXJ4c3NfZHZfdGltaW5nc1tdID0gewo+ICsJLyogU0QgLSA3MjB4NDg3aTYwICovCj4gKwl7 IDcyMCwgMjQzLCAzMCwgVjRMMl9EVl9CVF9TRElfNzIwWDQ4N0k2MCB9LAo+ICsJLyogU0QgLSA3 MjB4NTc2aTUwICovCj4gKwl7IDcyMCwgMjg4LCAyNSwgVjRMMl9EVl9CVF9DRUFfNzIwWDU3Nkk1 MCB9LAo+ICsJLyogSEQgLSAxMjgweDcyMHAyMy45OCAqLwo+ICsJLyogSEQgLSAxMjgweDcyMHAy NCAqLwo+ICsJeyAxMjgwLCA3MjAsIDI0LCBWNEwyX0RWX0JUX0NFQV8xMjgwWDcyMFAyNCB9LAo+ ICsJLyogSEQgLSAxMjgweDcyMHAyNSAqLwo+ICsJeyAxMjgwLCA3MjAsIDI1LCBWNEwyX0RWX0JU X0NFQV8xMjgwWDcyMFAyNSB9LAo+ICsJLyogSEQgLSAxMjgweDcyMHAyOS45NyAqLwo+ICsJLyog SEQgLSAxMjgweDcyMHAzMCAqLwo+ICsJeyAxMjgwLCA3MjAsIDMwLCBWNEwyX0RWX0JUX0NFQV8x MjgwWDcyMFAzMCB9LAo+ICsJLyogSEQgLSAxMjgweDcyMHA1MCAqLwo+ICsJeyAxMjgwLCA3MjAs IDUwLCBWNEwyX0RWX0JUX0NFQV8xMjgwWDcyMFA1MCB9LAo+ICsJLyogSEQgLSAxMjgweDcyMHA1 OS45NCAqLwo+ICsJLyogSEQgLSAxMjgweDcyMHA2MCAqLwo+ICsJeyAxMjgwLCA3MjAsIDYwLCBW NEwyX0RWX0JUX0NFQV8xMjgwWDcyMFA2MCB9LAo+ICsJLyogSEQgLSAxOTIweDEwODBwMjMuOTgg Ki8KPiArCS8qIEhEIC0gMTkyMHgxMDgwcDI0ICovCj4gKwl7IDE5MjAsIDEwODAsIDI0LCBWNEwy X0RWX0JUX0NFQV8xOTIwWDEwODBQMjQgfSwKPiArCS8qIEhEIC0gMTkyMHgxMDgwcDI1ICovCj4g Kwl7IDE5MjAsIDEwODAsIDI1LCBWNEwyX0RWX0JUX0NFQV8xOTIwWDEwODBQMjUgfSwKPiArCS8q IEhEIC0gMTkyMHgxMDgwcDI5Ljk3ICovCj4gKwkvKiBIRCAtIDE5MjB4MTA4MHAzMCAqLwo+ICsJ eyAxOTIwLCAxMDgwLCAzMCwgVjRMMl9EVl9CVF9DRUFfMTkyMFgxMDgwUDMwIH0sCj4gKwo+ICsJ LyogSEQgLSAyMDQ4eDEwODBwMjMuOTggKi8KPiArCS8qIEhEIC0gMjA0OHgxMDgwcDI0ICovCj4g Kwl7IDIwNDgsIDEwODAsIDI0LCBYTE5YX1Y0TDJfRFZfQlRfMjA0OFgxMDgwUDI0IH0sCj4gKwkv KiBIRCAtIDIwNDh4MTA4MHAyNSAqLwo+ICsJeyAyMDQ4LCAxMDgwLCAyNCwgWExOWF9WNEwyX0RW X0JUXzIwNDhYMTA4MFAyNSB9LAo+ICsJLyogSEQgLSAyMDQ4eDEwODBwMjkuOTcgKi8KPiArCS8q IEhEIC0gMjA0OHgxMDgwcDMwICovCj4gKwl7IDIwNDgsIDEwODAsIDI0LCBYTE5YX1Y0TDJfRFZf QlRfMjA0OFgxMDgwUDMwIH0sCj4gKwkvKiBIRCAtIDE5MjB4MTA4MGk0Ny45NSAqLwo+ICsJLyog SEQgLSAxOTIweDEwODBpNDggKi8KPiArCXsgMTkyMCwgNTQwLCAyNCwgWExOWF9WNEwyX0RWX0JU XzE5MjBYMTA4MEk0OCB9LAo+ICsKPiArCS8qIEhEIC0gMTkyMHgxMDgwaTUwICovCj4gKwl7IDE5 MjAsIDU0MCwgMjUsIFY0TDJfRFZfQlRfQ0VBXzE5MjBYMTA4MEk1MCB9LAo+ICsJLyogSEQgLSAx OTIweDEwODBpNTkuOTQgKi8KPiArCS8qIEhEIC0gMTkyMHgxMDgwaTYwICovCj4gKwl7IDE5MjAs IDU0MCwgMzAsIFY0TDJfRFZfQlRfQ0VBXzE5MjBYMTA4MEk2MCB9LAo+ICsKPiArCS8qIEhEIC0g MjA0OHgxMDgwaTQ3Ljk1ICovCj4gKwkvKiBIRCAtIDIwNDh4MTA4MGk0OCAqLwo+ICsJeyAyMDQ4 LCA1NDAsIDI0LCBYTE5YX1Y0TDJfRFZfQlRfMjA0OFgxMDgwSTQ4IH0sCj4gKwkvKiBIRCAtIDIw NDh4MTA4MGk1MCAqLwo+ICsJeyAyMDQ4LCA1NDAsIDI1LCBYTE5YX1Y0TDJfRFZfQlRfMjA0OFgx MDgwSTUwIH0sCj4gKwkvKiBIRCAtIDIwNDh4MTA4MGk1OS45NCAqLwo+ICsJLyogSEQgLSAyMDQ4 eDEwODBpNjAgKi8KPiArCXsgMjA0OCwgNTQwLCAzMCwgWExOWF9WNEwyX0RWX0JUXzIwNDhYMTA4 MEk2MCB9LAo+ICsJLyogM0cgLSAxOTIweDEwODBwNDcuOTUgKi8KPiArCS8qIDNHIC0gMTkyMHgx MDgwcDQ4ICovCj4gKwl7IDE5MjAsIDEwODAsIDQ4LCBYTE5YX1Y0TDJfRFZfQlRfMTkyMFgxMDgw UDQ4IH0sCj4gKwo+ICsJLyogM0cgLSAxOTIweDEwODBwNTAgMTQ4LjUgKi8KPiArCXsgMTkyMCwg MTA4MCwgNTAsIFY0TDJfRFZfQlRfQ0VBXzE5MjBYMTA4MFA1MCB9LAo+ICsJLyogM0cgLSAxOTIw eDEwODBwNTkuOTQgMTQ4LjUvMS4wMDEgKi8KPiArCS8qIDNHIC0gMTkyMHgxMDgwcDYwIDE0OC41 ICovCj4gKwl7IDE5MjAsIDEwODAsIDYwLCBWNEwyX0RWX0JUX0NFQV8xOTIwWDEwODBQNjAgfSwK PiArCj4gKwkvKiAzRyAtIDIwNDh4MTA4MHA0Ny45NSAqLwo+ICsJLyogM0cgLSAyMDQ4eDEwODBw NDggKi8KPiArCXsgMjA0OCwgMTA4MCwgNDgsIFhMTlhfVjRMMl9EVl9CVF8yMDQ4WDEwODBQNDgg fSwKPiArCS8qIDNHIC0gMjA0OHgxMDgwcDUwICovCj4gKwl7IDIwNDgsIDEwODAsIDUwLCBYTE5Y X1Y0TDJfRFZfQlRfMjA0OFgxMDgwUDUwIH0sCj4gKwkvKiAzRyAtIDIwNDh4MTA4MHA1OS45NCAq Lwo+ICsJLyogM0cgLSAyMDQ4eDEwODBwNjAgKi8KPiArCXsgMjA0OCwgMTA4MCwgNjAsIFhMTlhf VjRMMl9EVl9CVF8yMDQ4WDEwODBQNjAgfSwKPiArCj4gKwkvKiA2RyAtIDM4NDBYMjE2MHAyMy45 OCAqLwo+ICsJLyogNkcgLSAzODQwWDIxNjBwMjQgKi8KPiArCXsgMzg0MCwgMjE2MCwgMjQsIFY0 TDJfRFZfQlRfQ0VBXzM4NDBYMjE2MFAyNCB9LAo+ICsJLyogNkcgLSAzODQwWDIxNjBwMjUgKi8K PiArCXsgMzg0MCwgMjE2MCwgMjUsIFY0TDJfRFZfQlRfQ0VBXzM4NDBYMjE2MFAyNSB9LAo+ICsJ LyogNkcgLSAzODQwWDIxNjBwMjkuOTcgKi8KPiArCS8qIDZHIC0gMzg0MFgyMTYwcDMwICovCj4g Kwl7IDM4NDAsIDIxNjAsIDMwLCBWNEwyX0RWX0JUX0NFQV8zODQwWDIxNjBQMzAgfSwKPiArCS8q IDZHIC0gNDA5NlgyMTYwcDIzLjk4ICovCj4gKwkvKiA2RyAtIDQwOTZYMjE2MHAyNCAqLwo+ICsJ eyA0MDk2LCAyMTYwLCAyNCwgVjRMMl9EVl9CVF9DRUFfNDA5NlgyMTYwUDI0IH0sCj4gKwkvKiA2 RyAtIDQwOTZYMjE2MHAyNSAqLwo+ICsJeyA0MDk2LCAyMTYwLCAyNSwgVjRMMl9EVl9CVF9DRUFf NDA5NlgyMTYwUDI1IH0sCj4gKwkvKiA2RyAtIDQwOTZYMjE2MHAyOS45NyAqLwo+ICsJLyogNkcg LSA0MDk2WDIxNjBwMzAgKi8KPiArCXsgNDA5NiwgMjE2MCwgMzAsIFY0TDJfRFZfQlRfQ0VBXzQw OTZYMjE2MFAzMCB9LAo+ICsJLyogMTJHIC0gMzg0MFgyMTYwcDQ3Ljk1ICovCj4gKwkvKiAxMkcg LSAzODQwWDIxNjBwNDggKi8KPiArCXsgMzg0MCwgMjE2MCwgNDgsIFhMTlhfVjRMMl9EVl9CVF8z ODQwWDIxNjBQNDggfSwKPiArCj4gKwkvKiAxMkcgLSAzODQwWDIxNjBwNTAgKi8KPiArCXsgMzg0 MCwgMjE2MCwgNTAsIFY0TDJfRFZfQlRfQ0VBXzM4NDBYMjE2MFA1MCB9LAo+ICsJLyogMTJHIC0g Mzg0MFgyMTYwcDU5Ljk0ICovCj4gKwkvKiAxMkcgLSAzODQwWDIxNjBwNjAgKi8KPiArCXsgMzg0 MCwgMjE2MCwgNjAsIFY0TDJfRFZfQlRfQ0VBXzM4NDBYMjE2MFA2MCB9LAo+ICsKPiArCS8qIDEy RyAtIDQwOTZYMjE2MHA0Ny45NSAqLwo+ICsJLyogMTJHIC0gNDA5NlgyMTYwcDQ4ICovCj4gKwl7 IDM4NDAsIDIxNjAsIDQ4LCBYTE5YX1Y0TDJfRFZfQlRfNDA5NlgyMTYwUDQ4IH0sCj4gKwo+ICsJ LyogMTJHIC0gNDA5NlgyMTYwcDUwICovCj4gKwl7IDQwOTYsIDIxNjAsIDUwLCBWNEwyX0RWX0JU X0NFQV80MDk2WDIxNjBQNTAgfSwKPiArCS8qIDEyRyAtIDQwOTZYMjE2MHA1OS45NCAqLwo+ICsJ LyogMTJHIC0gNDA5NlgyMTYwcDYwICovCj4gKwl7IDQwOTYsIDIxNjAsIDYwLCBWNEwyX0RWX0JU X0NFQV80MDk2WDIxNjBQNjAgfSwKPiArfTsKPiArCj4gK3N0YXRpYyBpbmxpbmUgc3RydWN0IHhz ZGlyeHNzX3N0YXRlICoKPiArdG9feHNkaXJ4c3NzdGF0ZShzdHJ1Y3QgdjRsMl9zdWJkZXYgKnN1 YmRldikKPiArewo+ICsJcmV0dXJuIGNvbnRhaW5lcl9vZihzdWJkZXYsIHN0cnVjdCB4c2Rpcnhz c19zdGF0ZSwgc3ViZGV2KTsKPiArfQo+ICsKPiArLyoKPiArICogUmVnaXN0ZXIgcmVsYXRlZCBv cGVyYXRpb25zCj4gKyAqLwo+ICtzdGF0aWMgaW5saW5lIHUzMiB4c2Rpcnhzc19yZWFkKHN0cnVj dCB4c2Rpcnhzc19jb3JlICp4c2RpcnhzcywgdTMyIGFkZHIpCj4gK3sKPiArCXJldHVybiBpb3Jl YWQzMih4c2Rpcnhzcy0+aW9tZW0gKyBhZGRyKTsKPiArfQo+ICsKPiArc3RhdGljIGlubGluZSB2 b2lkIHhzZGlyeHNzX3dyaXRlKHN0cnVjdCB4c2Rpcnhzc19jb3JlICp4c2RpcnhzcywgdTMyIGFk ZHIsCj4gKwkJCQkgIHUzMiB2YWx1ZSkKPiArewo+ICsJaW93cml0ZTMyKHZhbHVlLCB4c2Rpcnhz cy0+aW9tZW0gKyBhZGRyKTsKPiArfQo+ICsKPiArc3RhdGljIGlubGluZSB2b2lkIHhzZGlyeHNz X2NscihzdHJ1Y3QgeHNkaXJ4c3NfY29yZSAqeHNkaXJ4c3MsIHUzMiBhZGRyLAo+ICsJCQkJdTMy IGNscikKPiArewo+ICsJeHNkaXJ4c3Nfd3JpdGUoeHNkaXJ4c3MsIGFkZHIsIHhzZGlyeHNzX3Jl YWQoeHNkaXJ4c3MsIGFkZHIpICYgfmNscik7Cj4gK30KPiArCj4gK3N0YXRpYyBpbmxpbmUgdm9p ZCB4c2Rpcnhzc19zZXQoc3RydWN0IHhzZGlyeHNzX2NvcmUgKnhzZGlyeHNzLCB1MzIgYWRkciwK PiArCQkJCXUzMiBzZXQpCj4gK3sKPiArCXhzZGlyeHNzX3dyaXRlKHhzZGlyeHNzLCBhZGRyLCB4 c2Rpcnhzc19yZWFkKHhzZGlyeHNzLCBhZGRyKSB8IHNldCk7Cj4gK30KPiArCj4gK3N0YXRpYyBp bmxpbmUgdm9pZCB4c2RpcnhfY29yZV9kaXNhYmxlKHN0cnVjdCB4c2Rpcnhzc19jb3JlICpjb3Jl KQo+ICt7Cj4gKwl4c2Rpcnhzc19jbHIoY29yZSwgWFNESVJYX1JTVF9DVFJMX1JFRywgWFNESVJY X1JTVF9DVFJMX1NTX0VOX01BU0spOwo+ICt9Cj4gKwo+ICtzdGF0aWMgaW5saW5lIHZvaWQgeHNk aXJ4X2NvcmVfZW5hYmxlKHN0cnVjdCB4c2Rpcnhzc19jb3JlICpjb3JlKQo+ICt7Cj4gKwl4c2Rp cnhzc19zZXQoY29yZSwgWFNESVJYX1JTVF9DVFJMX1JFRywgWFNESVJYX1JTVF9DVFJMX1NTX0VO X01BU0spOwo+ICt9Cj4gKwo+ICtzdGF0aWMgaW50IHhzZGlyeF9zZXRfbW9kZWRldGVjdChzdHJ1 Y3QgeHNkaXJ4c3NfY29yZSAqY29yZSwgdTE2IG1hc2spCj4gK3sKPiArCXUzMiB2YWw7Cj4gKwlz dHJ1Y3QgZGV2aWNlICpkZXYgPSBjb3JlLT5kZXY7Cj4gKwo+ICsJbWFzayAmPSBYU0RJUlhfREVU RUNUX0FMTF9NT0RFUzsKPiArCWlmICghbWFzaykgewo+ICsJCWRldl9lcnIoZGV2LCAiSW52YWxp ZCBiaXQgbWFzayA9IDB4JTA4eFxuIiwgbWFzayk7Cj4gKwkJcmV0dXJuIC1FSU5WQUw7Cj4gKwl9 Cj4gKwo+ICsJZGV2X2RiZyhkZXYsICJtYXNrID0gMHgleFxuIiwgbWFzayk7Cj4gKwo+ICsJdmFs ID0geHNkaXJ4c3NfcmVhZChjb3JlLCBYU0RJUlhfTURMX0NUUkxfUkVHKTsKPiArCXZhbCAmPSB+ WFNESVJYX01ETF9DVFJMX01PREVfREVUX0VOX01BU0s7Cj4gKwl2YWwgJj0gflhTRElSWF9NRExf Q1RSTF9NT0RFX0FVVE9fREVUX01BU0s7Cj4gKwl2YWwgJj0gflhTRElSWF9NRExfQ1RSTF9GT1JD RURfTU9ERV9NQVNLOwo+ICsKPiArCWlmIChod2VpZ2h0MTYobWFzaykgPiAxKSB7Cj4gKwkJLyog TXVsdGkgbW9kZSBkZXRlY3Rpb24gYXMgbW9yZSB0aGFuIDEgYml0IHNldCBpbiBtYXNrICovCj4g KwkJZGV2X2RiZyhkZXYsICJEZXRlY3QgbXVsdGlwbGUgbW9kZXNcbiIpOwo+ICsKPiArCQlpZiAo bWFzayAmIEJJVChYU0RJUlhfTU9ERV9TRF9PRkZTRVQpKQo+ICsJCQl2YWwgfD0gWFNESVJYX01E TF9DVFJMX01PREVfU0RfRU5fTUFTSzsKPiArCQlpZiAobWFzayAmIEJJVChYU0RJUlhfTU9ERV9I RF9PRkZTRVQpKQo+ICsJCQl2YWwgfD0gWFNESVJYX01ETF9DVFJMX01PREVfSERfRU5fTUFTSzsK PiArCQlpZiAobWFzayAmIEJJVChYU0RJUlhfTU9ERV8zR19PRkZTRVQpKQo+ICsJCQl2YWwgfD0g WFNESVJYX01ETF9DVFJMX01PREVfM0dfRU5fTUFTSzsKPiArCQlpZiAobWFzayAmIEJJVChYU0RJ UlhfTU9ERV82R19PRkZTRVQpKQo+ICsJCQl2YWwgfD0gWFNESVJYX01ETF9DVFJMX01PREVfNkdf RU5fTUFTSzsKPiArCQlpZiAobWFzayAmIEJJVChYU0RJUlhfTU9ERV8xMkdJX09GRlNFVCkpCj4g KwkJCXZhbCB8PSBYU0RJUlhfTURMX0NUUkxfTU9ERV8xMkdJX0VOX01BU0s7Cj4gKwkJaWYgKG1h c2sgJiBCSVQoWFNESVJYX01PREVfMTJHRl9PRkZTRVQpKQo+ICsJCQl2YWwgfD0gWFNESVJYX01E TF9DVFJMX01PREVfMTJHRl9FTl9NQVNLOwo+ICsKPiArCQl2YWwgfD0gWFNESVJYX01ETF9DVFJM X01PREVfREVUX0VOX01BU0s7Cj4gKwl9IGVsc2Ugewo+ICsJCS8qIEZpeGVkIE1vZGUgKi8KPiAr CQl1MzIgZm9yY2VkX21vZGVfbWFzazsKPiArCj4gKwkJZGV2X2RiZyhkZXYsICJEZXRlY3QgZml4 ZWQgbW9kZVxuIik7Cj4gKwo+ICsJCS8qIEZpbmQgb2Zmc2V0IG9mIGZpcnN0IGJpdCBzZXQgKi8K PiArCQlzd2l0Y2ggKF9fZmZzKG1hc2spKSB7Cj4gKwkJY2FzZSBYU0RJUlhfTU9ERV9TRF9PRkZT RVQ6Cj4gKwkJCWZvcmNlZF9tb2RlX21hc2sgPSBYU0RJUlhfTU9ERV9TRF9NQVNLOwo+ICsJCQli cmVhazsKPiArCQljYXNlIFhTRElSWF9NT0RFX0hEX09GRlNFVDoKPiArCQkJZm9yY2VkX21vZGVf bWFzayA9IFhTRElSWF9NT0RFX0hEX01BU0s7Cj4gKwkJCWJyZWFrOwo+ICsJCWNhc2UgWFNESVJY X01PREVfM0dfT0ZGU0VUOgo+ICsJCQlmb3JjZWRfbW9kZV9tYXNrID0gWFNESVJYX01PREVfM0df TUFTSzsKPiArCQkJYnJlYWs7Cj4gKwkJY2FzZSBYU0RJUlhfTU9ERV82R19PRkZTRVQ6Cj4gKwkJ CWZvcmNlZF9tb2RlX21hc2sgPSBYU0RJUlhfTU9ERV82R19NQVNLOwo+ICsJCQlicmVhazsKPiAr CQljYXNlIFhTRElSWF9NT0RFXzEyR0lfT0ZGU0VUOgo+ICsJCQlmb3JjZWRfbW9kZV9tYXNrID0g WFNESVJYX01PREVfMTJHSV9NQVNLOwo+ICsJCQlicmVhazsKPiArCQljYXNlIFhTRElSWF9NT0RF XzEyR0ZfT0ZGU0VUOgo+ICsJCQlmb3JjZWRfbW9kZV9tYXNrID0gWFNESVJYX01PREVfMTJHRl9N QVNLOwo+ICsJCQlicmVhazsKPiArCQlkZWZhdWx0Ogo+ICsJCQlmb3JjZWRfbW9kZV9tYXNrID0g MDsKPiArCQl9Cj4gKwkJZGV2X2RiZyhkZXYsICJGb3JjZWQgTW9kZSBNYXNrIDogMHgleFxuIiwK PiArCQkJZm9yY2VkX21vZGVfbWFzayk7Cj4gKwkJdmFsIHw9IGZvcmNlZF9tb2RlX21hc2sgPDwg WFNESVJYX01ETF9DVFJMX0ZPUkNFRF9NT0RFX09GRlNFVDsKPiArCX0KPiArCj4gKwlkZXZfZGJn KGRldiwgIk1vZGVzIHRvIGJlIGRldGVjdGVkIDogc2RpIGN0cmwgcmVnID0gMHglMDh4XG4iLAo+ ICsJCXZhbCk7Cj4gKwl4c2Rpcnhzc193cml0ZShjb3JlLCBYU0RJUlhfTURMX0NUUkxfUkVHLCB2 YWwpOwo+ICsKPiArCXJldHVybiAwOwo+ICt9Cj4gKwo+ICtzdGF0aWMgdm9pZCB4c2RpcnhfZnJh bWVyKHN0cnVjdCB4c2Rpcnhzc19jb3JlICpjb3JlLCBib29sIGZsYWcpCj4gK3sKPiArCWlmIChm bGFnKQo+ICsJCXhzZGlyeHNzX3NldChjb3JlLCBYU0RJUlhfTURMX0NUUkxfUkVHLAo+ICsJCQkg ICAgIFhTRElSWF9NRExfQ1RSTF9GUk1fRU5fTUFTSyk7Cj4gKwllbHNlCj4gKwkJeHNkaXJ4c3Nf Y2xyKGNvcmUsIFhTRElSWF9NRExfQ1RSTF9SRUcsCj4gKwkJCSAgICAgWFNESVJYX01ETF9DVFJM X0ZSTV9FTl9NQVNLKTsKPiArfQo+ICsKPiArc3RhdGljIHZvaWQgeHNkaXJ4X3NldGVkaGVycmNu dHRyaWdnZXIoc3RydWN0IHhzZGlyeHNzX2NvcmUgKmNvcmUsIHUzMiBlbmFibGUpCgpUaGF0J3Mg YSBoYXJkIHRvIHJlYWQgZnVuY3Rpb24gbmFtZS4gQ291bGQgeW91IHNlcGFyYXRlIHdvcmRzIHdp dGgKdW5kZXJzY29yZXMgPyBTYW1lIGZvciBmdW5jdGlvbnMgYmVsb3cgdGhhdCBjb25jYXRlbmF0 ZSBtdWx0aXBsZSB3b3Jkcwp0b2dldGhlci4KCj4gK3sKPiArCXUzMiB2YWwgPSB4c2Rpcnhzc19y ZWFkKGNvcmUsIFhTRElSWF9FREhfRVJSQ05UX0VOX1JFRyk7Cj4gKwo+ICsJdmFsID0gZW5hYmxl ICYgWFNESVJYX0VESF9BTExFUlJfTUFTSzsKPiArCj4gKwl4c2Rpcnhzc193cml0ZShjb3JlLCBY U0RJUlhfRURIX0VSUkNOVF9FTl9SRUcsIHZhbCk7Cj4gK30KPiArCj4gK3N0YXRpYyBpbmxpbmUg dm9pZCB4c2Rpcnhfc2V0dmlkbG9ja3dpbmRvdyhzdHJ1Y3QgeHNkaXJ4c3NfY29yZSAqY29yZSwg dTMyIHZhbCkKPiArewo+ICsJLyoKPiArCSAqIFRoZSB2aWRlbyBsb2NrIHdpbmRvdyBpcyB0aGUg YW1vdW50IG9mIHRpbWUgZm9yIHdoaWNoIHRoZQo+ICsJICogdGhlIG1vZGUgYW5kIHRyYW5zcG9y dCBzdHJlYW0gc2hvdWxkIGJlIGxvY2tlZCB0byBnZXQgdGhlCj4gKwkgKiB2aWRlbyBsb2NrIGlu dGVycnVwdC4KPiArCSAqLwo+ICsJeHNkaXJ4c3Nfd3JpdGUoY29yZSwgWFNESVJYX1ZJRF9MT0NL X1dJTkRPV19SRUcsIHZhbCk7Cj4gK30KPiArCj4gK3N0YXRpYyBpbmxpbmUgdm9pZCB4c2Rpcnhf ZGlzYWJsZWludHIoc3RydWN0IHhzZGlyeHNzX2NvcmUgKmNvcmUsIHUzMiBtYXNrKQo+ICt7Cj4g Kwl4c2Rpcnhzc19jbHIoY29yZSwgWFNESVJYX0lFUl9SRUcsIG1hc2spOwo+ICt9Cj4gKwo+ICtz dGF0aWMgaW5saW5lIHZvaWQgeHNkaXJ4X2VuYWJsZWludHIoc3RydWN0IHhzZGlyeHNzX2NvcmUg KmNvcmUsIHUzMiBtYXNrKQo+ICt7Cj4gKwl4c2Rpcnhzc19zZXQoY29yZSwgWFNESVJYX0lFUl9S RUcsIG1hc2spOwo+ICt9Cj4gKwo+ICtzdGF0aWMgdm9pZCB4c2RpcnhfZ2xvYmFsaW50cihzdHJ1 Y3QgeHNkaXJ4c3NfY29yZSAqY29yZSwgYm9vbCBmbGFnKQo+ICt7Cj4gKwlpZiAoZmxhZykKPiAr CQl4c2Rpcnhzc19zZXQoY29yZSwgWFNESVJYX0dMQkxfSUVSX1JFRywKPiArCQkJICAgICBYU0RJ UlhfR0xCTF9JTlRSX0VOX01BU0spOwo+ICsJZWxzZQo+ICsJCXhzZGlyeHNzX2Nscihjb3JlLCBY U0RJUlhfR0xCTF9JRVJfUkVHLAo+ICsJCQkgICAgIFhTRElSWF9HTEJMX0lOVFJfRU5fTUFTSyk7 Cj4gK30KPiArCj4gK3N0YXRpYyBpbmxpbmUgdm9pZCB4c2RpcnhfY2xlYXJpbnRyKHN0cnVjdCB4 c2Rpcnhzc19jb3JlICpjb3JlLCB1MzIgbWFzaykKPiArewo+ICsJeHNkaXJ4c3Nfc2V0KGNvcmUs IFhTRElSWF9JU1JfUkVHLCBtYXNrKTsKPiArfQo+ICsKPiArc3RhdGljIHZvaWQgeHNkaXJ4X3Zp ZF9icmlkZ2VfY29udHJvbChzdHJ1Y3QgeHNkaXJ4c3NfY29yZSAqY29yZSwKPiArCQkJCSAgICAg IGJvb2wgZW5hYmxlKQo+ICt7Cj4gKwl1MzIgbWFzayA9IFhTRElSWF9SU1RfQ1RSTF9TRElSWF9C UklER0VfRU5CX01BU0s7Cj4gKwo+ICsJLyoKPiArCSAqIFRPRE8gLSBFbmFibGUgWVVWNDQ0L1JC RyBmb3JtYXQgaW4gdGhlIGJyaWRnZSBiYXNlZAo+ICsJICogb24gQllURTMgY29sb3IgZm9ybWF0 Lgo+ICsJICogWFNESVJYX1JTVF9DVFJMX0JSSURHRV9DSF9GTVRfWVVWNDQ0Cj4gKwkgKi8KPiAr CWlmIChlbmFibGUpCj4gKwkJeHNkaXJ4c3Nfc2V0KGNvcmUsIFhTRElSWF9SU1RfQ1RSTF9SRUcs IG1hc2spOwo+ICsJZWxzZQo+ICsJCXhzZGlyeHNzX2Nscihjb3JlLCBYU0RJUlhfUlNUX0NUUkxf UkVHLCBtYXNrKTsKPiArfQoKVGhpcyBpcyBvbmx5IHVzZWQgaW4geHNkaXJ4X3N0cmVhbWZsb3df Y29udHJvbCgpLCBpbmxpbmluZyBpdCBtYW51YWxseQp3b3VsZCBiZSBzaW1wbGVyIEkgdGhpbmsu Cgo+ICsKPiArc3RhdGljIHZvaWQgeHNkaXJ4X2F4aXM0X2JyaWRnZV9jb250cm9sKHN0cnVjdCB4 c2Rpcnhzc19jb3JlICpjb3JlLAo+ICsJCQkJCWJvb2wgZW5hYmxlKQo+ICt7Cj4gKwlpZiAoZW5h YmxlKQo+ICsJCXhzZGlyeHNzX3NldChjb3JlLCBYU0RJUlhfUlNUX0NUUkxfUkVHLAo+ICsJCQkg ICAgIFhTRElSWF9SU1RfQ1RSTF9WSURJTl9BWEk0U19NT0RfRU5CX01BU0spOwo+ICsJZWxzZQo+ ICsJCXhzZGlyeHNzX2Nscihjb3JlLCBYU0RJUlhfUlNUX0NUUkxfUkVHLAo+ICsJCQkgICAgIFhT RElSWF9SU1RfQ1RSTF9WSURJTl9BWEk0U19NT0RfRU5CX01BU0spOwo+ICt9CgpTYW1lIGZvciB0 aGlzIG9uZS4KCj4gKwo+ICtzdGF0aWMgdm9pZCB4c2Rpcnhfc3RyZWFtZmxvd19jb250cm9sKHN0 cnVjdCB4c2Rpcnhzc19jb3JlICpjb3JlLCBib29sIGVuYWJsZSkKPiArewo+ICsJLyogVGhlIHNk aSB0byBuYXRpdmUgYnJpZGdlIGlzIGZvbGxvd2VkIGJ5IG5hdGl2ZSB0byBheGlzNCBicmlkZ2Ug Ki8KPiArCWlmIChlbmFibGUpIHsKPiArCQl4c2RpcnhfYXhpczRfYnJpZGdlX2NvbnRyb2woY29y ZSwgZW5hYmxlKTsKPiArCQl4c2RpcnhfdmlkX2JyaWRnZV9jb250cm9sKGNvcmUsIGVuYWJsZSk7 Cj4gKwl9IGVsc2Ugewo+ICsJCXhzZGlyeF92aWRfYnJpZGdlX2NvbnRyb2woY29yZSwgZW5hYmxl KTsKPiArCQl4c2RpcnhfYXhpczRfYnJpZGdlX2NvbnRyb2woY29yZSwgZW5hYmxlKTsKPiArCX0K PiArfQo+ICsKPiArc3RhdGljIHZvaWQgeHNkaXJ4c3NfZ2V0X2ZyYW1lcmF0ZShzdHJ1Y3QgdjRs Ml9mcmFjdCAqZnJhbWVfaW50ZXJ2YWwsCj4gKwkJCQkgICB1MzIgZnJhbWVyYXRlKQo+ICt7Cj4g Kwlzd2l0Y2ggKGZyYW1lcmF0ZSkgewo+ICsJY2FzZSBYU0RJUlhfVFNfREVUX1NUQVRfUkFURV8y M185OEhaOgo+ICsJCWZyYW1lX2ludGVydmFsLT5udW1lcmF0b3IgPSAxMDAxOwo+ICsJCWZyYW1l X2ludGVydmFsLT5kZW5vbWluYXRvciA9IDI0MDAwOwo+ICsJCWJyZWFrOwo+ICsJY2FzZSBYU0RJ UlhfVFNfREVUX1NUQVRfUkFURV8yNEhaOgo+ICsJCWZyYW1lX2ludGVydmFsLT5udW1lcmF0b3Ig PSAxMDAwOwo+ICsJCWZyYW1lX2ludGVydmFsLT5kZW5vbWluYXRvciA9IDI0MDAwOwo+ICsJCWJy ZWFrOwo+ICsJY2FzZSBYU0RJUlhfVFNfREVUX1NUQVRfUkFURV8yNUhaOgo+ICsJCWZyYW1lX2lu dGVydmFsLT5udW1lcmF0b3IgPSAxMDAwOwo+ICsJCWZyYW1lX2ludGVydmFsLT5kZW5vbWluYXRv ciA9IDI1MDAwOwo+ICsJCWJyZWFrOwo+ICsJY2FzZSBYU0RJUlhfVFNfREVUX1NUQVRfUkFURV8y OV85N0haOgo+ICsJCWZyYW1lX2ludGVydmFsLT5udW1lcmF0b3IgPSAxMDAxOwo+ICsJCWZyYW1l X2ludGVydmFsLT5kZW5vbWluYXRvciA9IDMwMDAwOwo+ICsJCWJyZWFrOwo+ICsJY2FzZSBYU0RJ UlhfVFNfREVUX1NUQVRfUkFURV8zMEhaOgo+ICsJCWZyYW1lX2ludGVydmFsLT5udW1lcmF0b3Ig PSAxMDAwOwo+ICsJCWZyYW1lX2ludGVydmFsLT5kZW5vbWluYXRvciA9IDMwMDAwOwo+ICsJCWJy ZWFrOwo+ICsJY2FzZSBYU0RJUlhfVFNfREVUX1NUQVRfUkFURV80N185NUhaOgo+ICsJCWZyYW1l X2ludGVydmFsLT5udW1lcmF0b3IgPSAxMDAxOwo+ICsJCWZyYW1lX2ludGVydmFsLT5kZW5vbWlu YXRvciA9IDQ4MDAwOwo+ICsJCWJyZWFrOwo+ICsJY2FzZSBYU0RJUlhfVFNfREVUX1NUQVRfUkFU RV80OEhaOgo+ICsJCWZyYW1lX2ludGVydmFsLT5udW1lcmF0b3IgPSAxMDAwOwo+ICsJCWZyYW1l X2ludGVydmFsLT5kZW5vbWluYXRvciA9IDQ4MDAwOwo+ICsJCWJyZWFrOwo+ICsJY2FzZSBYU0RJ UlhfVFNfREVUX1NUQVRfUkFURV81MEhaOgo+ICsJCWZyYW1lX2ludGVydmFsLT5udW1lcmF0b3Ig PSAxMDAwOwo+ICsJCWZyYW1lX2ludGVydmFsLT5kZW5vbWluYXRvciA9IDUwMDAwOwo+ICsJCWJy ZWFrOwo+ICsJY2FzZSBYU0RJUlhfVFNfREVUX1NUQVRfUkFURV81OV85NEhaOgo+ICsJCWZyYW1l X2ludGVydmFsLT5udW1lcmF0b3IgPSAxMDAxOwo+ICsJCWZyYW1lX2ludGVydmFsLT5kZW5vbWlu YXRvciA9IDYwMDAwOwo+ICsJCWJyZWFrOwo+ICsJY2FzZSBYU0RJUlhfVFNfREVUX1NUQVRfUkFU RV82MEhaOgo+ICsJCWZyYW1lX2ludGVydmFsLT5udW1lcmF0b3IgPSAxMDAwOwo+ICsJCWZyYW1l X2ludGVydmFsLT5kZW5vbWluYXRvciA9IDYwMDAwOwo+ICsJCWJyZWFrOwo+ICsJZGVmYXVsdDoK PiArCQlmcmFtZV9pbnRlcnZhbC0+bnVtZXJhdG9yID0gMTsKPiArCQlmcmFtZV9pbnRlcnZhbC0+ ZGVub21pbmF0b3IgPSAxOwo+ICsJfQo+ICt9Cj4gKwo+ICtzdGF0aWMgdm9pZCB4c2Rpcnhzc19z ZXRfZ3RjbGsoc3RydWN0IHhzZGlyeHNzX3N0YXRlICpzdGF0ZSkKPiArewo+ICsJc3RydWN0IGNs ayAqZ3RjbGs7Cj4gKwl1bnNpZ25lZCBsb25nIGNsa3JhdGU7Cj4gKwlpbnQgcmV0LCBpc19mcmFj Owo+ICsJc3RydWN0IHhzZGlyeHNzX2NvcmUgKmNvcmUgPSAmc3RhdGUtPmNvcmU7Cj4gKwl1MzIg bW9kZTsKPiArCXN0YXRpYyBpbnQgcHJldl9pc19mcmFjID0gLTE7Cj4gKwo+ICsJbW9kZSA9IHhz ZGlyeHNzX3JlYWQoY29yZSwgWFNESVJYX01PREVfREVUX1NUQVRfUkVHKTsKPiArCW1vZGUgJj0g WFNESVJYX01PREVfREVUX1NUQVRfUlhfTU9ERV9NQVNLOwo+ICsKPiArCS8qCj4gKwkgKiBUT0RP OiBGb3Igbm93LCBkb24ndCBjaGFuZ2UgdGhlIGNsb2NrIHJhdGUgZm9yIGFueSBtb2RlIGV4Y2Vw dCAxMkcuCj4gKwkgKiBJbiBmdXR1cmUsIGNvbmZpZ3VyZSBndCBjbG9jayBmb3IgYWxsIG1vZGVz IGFuZCBlbmFibGUgY2xvY2sgb25seQo+ICsJICogd2hlbiBuZWVkZWQgKHN0cmVhbSBvbi9vZmYp Lgo+ICsJICovCj4gKwlpZiAobW9kZSAhPSBYU0RJUlhfTU9ERV8xMkdJX01BU0sgJiYgbW9kZSAh PSBYU0RJUlhfTU9ERV8xMkdGX01BU0spCj4gKwkJcmV0dXJuOwo+ICsKPiArCWlzX2ZyYWMgPSBz dGF0ZS0+ZnJhbWVfaW50ZXJ2YWwubnVtZXJhdG9yID09IDEwMDEgPyAxIDogMDsKPiArCj4gKwlp ZiAocHJldl9pc19mcmFjID09IGlzX2ZyYWMpCj4gKwkJcmV0dXJuOwo+ICsKPiArCXhzZGlyeF9j b3JlX2Rpc2FibGUoY29yZSk7Cj4gKwl4c2RpcnhfZ2xvYmFsaW50cihjb3JlLCBmYWxzZSk7Cj4g Kwl4c2RpcnhfZGlzYWJsZWludHIoY29yZSwgWFNESVJYX0lOVFJfQUxMX01BU0spOwo+ICsKPiAr CS8qIGdldCBzZGlfcnhfY2xrICovCj4gKwlndGNsayA9IGNvcmUtPmNsa3NbMV0uY2xrOwo+ICsJ Y2xrcmF0ZSA9IGNsa19nZXRfcmF0ZShndGNsayk7Cj4gKwlpc19mcmFjID0gc3RhdGUtPmZyYW1l X2ludGVydmFsLm51bWVyYXRvciA9PSAxMDAxID8gMSA6IDA7Cj4gKwo+ICsJLyogY2FsY3VhbHRl IGNsa3JhdGUgKi8KCnMvY2FsY3VhbHRlL2NhbGN1bGF0ZS8KCj4gKwlpZiAoIWlzX2ZyYWMpCj4g KwkJY2xrcmF0ZSA9IENMS19JTlQ7Cj4gKwllbHNlCj4gKwkJY2xrcmF0ZSA9IChDTEtfSU5UICog MTAwMCkgLyAxMDAxOwoKU2hvdWxkbid0IHRoZSBjbG9jayByYXRlIGFsc28gZGVwZW5kIG9uIHRo ZSBtb2RlID8gVGFibGUgMy0yIGxpc3RzCmRpZmZlcmVudCBjbG9jayByYXRlcyBmb3IgSEQtU0RJ IGFuZCAxMkctU0RJLgoKPiArCj4gKwlyZXQgPSBjbGtfc2V0X3JhdGUoZ3RjbGssIGNsa3JhdGUp Owo+ICsJaWYgKHJldCkKPiArCQlkZXZfZXJyKGNvcmUtPmRldiwgImZhaWxlZCB0byBzZXQgY2xr IHJhdGUgPSAlZFxuIiwgcmV0KTsKPiArCj4gKwljbGtyYXRlID0gY2xrX2dldF9yYXRlKGd0Y2xr KTsKPiArCj4gKwlkZXZfZGJnKGNvcmUtPmRldiwgImNsa3JhdGUgPSAlbHUgaXNfZnJhYyA9ICVk XG4iLAo+ICsJCWNsa3JhdGUsIGlzX2ZyYWMpOwo+ICsKPiArCXhzZGlyeF9mcmFtZXIoY29yZSwg c3RhdGUtPmZyYW1lcl9lbmFibGUpOwoKQXMgdGhpcyBpcyBjYWxsZWQgaW4gYm90aCB0aGUgSVJR IGhhbmRsZXIgYW5kIHRoZSBzX2N0cmwgaGFuZGxlciwgeW91CmNvdWxkIGhhdmUgYSByYWNlIHdo ZW4gYWNjZXNzaW5nIHRoZSBYU0RJUlhfTURMX0NUUkxfUkVHIHJlZ2lzdGVyLiBZb3UKd2lsbCBu ZWVkIHRvIHByb3RlY3QgYWxsIGFjY2Vzc2VzIHRvIHJlZ2lzdGVycyB0aGF0IGFyZSB3cml0dGVu IGZyb20KYm90aCB0aGUgSVJRIGhhbmRsZXIgYW5kIHVzZXJzcGFjZSBjb250ZXh0cyB3aXRoIGEg c3BpbmxvY2suCgo+ICsJeHNkaXJ4X3NldGVkaGVycmNudHRyaWdnZXIoY29yZSwgc3RhdGUtPmVk aG1hc2spOwo+ICsJeHNkaXJ4X3NldHZpZGxvY2t3aW5kb3coY29yZSwgc3RhdGUtPnZpZGxvY2t3 aW4pOwo+ICsJeHNkaXJ4X3NldF9tb2RlZGV0ZWN0KGNvcmUsIHN0YXRlLT5zZWFyY2htYXNrKTsK PiArCXhzZGlyeF9lbmFibGVpbnRyKGNvcmUsIFhTRElSWF9JTlRSX0FMTF9NQVNLKTsKPiArCXhz ZGlyeF9nbG9iYWxpbnRyKGNvcmUsIHRydWUpOwo+ICsJeHNkaXJ4X2NvcmVfZW5hYmxlKGNvcmUp Owo+ICsKPiArCXByZXZfaXNfZnJhYyA9IGlzX2ZyYWM7CgpUaGF0J3MgbG90cyBvZiB3b3JrIGRv bmUgaW4gYW4gaW50ZXJydXB0IGhhbmRsZXIuIEFzIHRoaXMgZnVuY3Rpb24gaXMKY2FsbGVkIHdo ZW4gYSBzdHJlYW0gbG9jayBpcyBkZXRlY3RlZCwgaWYgdGhlIGNsb2NrIHJhdGUgaGFzIHRvIGJl CmNoYW5nZWQsIGRvIEkgYXNzdW1lIGNvcnJlY3RseSB0aGF0IHRoZSByZXNvbHV0aW9uIG1heSBo YXZlIGNoYW5nZWQgdG9vCj8gVGhhdCBtYXkgcmVxdWlyZSByZWNvbmZpZ3VyaW5nIHRoZSBwaXBl bGluZSBhbmQgcmVhbGxvY2F0aW5nIGJ1ZmZlcnMuCldpdGggU0QgYW5kIEhEIFRWLCBJIHRoaW5r IHRoZSB1c3VhbCBwcmFjdGljZSBpcyB0byBub3RpZnkgdXNlcnNwYWNlIG9mCnZpZGVvIGxvY2sg YW5kIGxldCBpdCBkbyB0aGUgcmVjb25maWd1cmF0aW9uIGlzIHJlcXVpcmVkLCBpbnN0ZWFkIG9m CmF0dGVtcHRpbmcgdG8gZG8gc28gYXV0b21hdGljYWxseS4gSGFucywgaXMgdGhhdCBjb3JyZWN0 ID8gSG93IHdvdWxkIHdlCmhhbmRsZSB0aGVuIHRoZSBjYXNlIHdoZXJlIHRoZSBwaXBlbGluZSBp cyBhbHJlYWR5IGNvcnJlY3RseSBjb25maWd1cmVkCndpdGggYmlnIGVub3VnaCBidWZmZXJzIChJ J20gbm90IHN1cmUgdGhpcyBjYW4gYWN0dWFsbHkgaGFwcGVuLCBmb3IgdGhlCmJ1ZmZlcnMgeWVz LCBidXQgZm9yIHRoZSBwaXBlbGluZSBjb25maWd1cmF0aW9uLCBtYXliZSB0aGUgZm9ybWF0IHdp bGwKYWx3YXlzIG5lZWQgdG8gY2hhbmdlKSA/CgpBbmQgSSd2ZSBub3cgc2VlbiB0aGF0IHdlIGRv IGVtaXQgdGhlIFY0TDJfRVZFTlRfU1JDX0NIX1JFU09MVVRJT04gZXZlbnQKOi0pIERvIHdlIHRo dXMgbmVlZCB0byByZWNvbmZpZ3VyZSB0aGUgSVAgY29yZSBoZXJlID8KCj4gK30KPiArCj4gKy8q Kgo+ICsgKiB4c2RpcnhfZ2V0X3N0cmVhbV9wcm9wZXJ0aWVzIC0gR2V0IFNESSBSeCBzdHJlYW0g cHJvcGVydGllcwo+ICsgKiBAc3RhdGU6IHBvaW50ZXIgdG8gZHJpdmVyIHN0YXRlCj4gKyAqCj4g KyAqIFRoaXMgZnVuY3Rpb24gZGVjb2RlcyB0aGUgc3RyZWFtJ3MgU1QzNTIgcGF5bG9hZCAoaWYg YXZhaWxhYmxlKSB0byBnZXQKPiArICogc3RyZWFtIHByb3BlcnRpZXMgbGlrZSB3aWR0aCwgaGVp Z2h0LCBwaWN0dXJlIHR5cGUgKGludGVybGFjZWQvcHJvZ3Jlc3NpdmUpLAo+ICsgKiBldGMuCj4g KyAqCj4gKyAqIFJldHVybjogMCBmb3Igc3VjY2VzcyBlbHNlIGVycm9ycwo+ICsgKi8KPiArc3Rh dGljIGludCB4c2RpcnhfZ2V0X3N0cmVhbV9wcm9wZXJ0aWVzKHN0cnVjdCB4c2Rpcnhzc19zdGF0 ZSAqc3RhdGUpCj4gK3sKPiArCXN0cnVjdCB4c2Rpcnhzc19jb3JlICpjb3JlID0gJnN0YXRlLT5j b3JlOwo+ICsJc3RydWN0IGRldmljZSAqZGV2ID0gY29yZS0+ZGV2Owo+ICsJdTMyIG1vZGUsIHBh eWxvYWQgPSAwLCB2YWwsIGZhbWlseSwgdmFsaWQsIHRzY2FuOwo+ICsJdTggYnl0ZTEgPSAwLCBh Y3RpdmVfbHVtYSA9IDAsIHBpY190eXBlID0gMCwgZnJhbWVyYXRlID0gMDsKPiArCXU4IHNhbXBs aW5nID0gWFNUMzUyX0JZVEUzX0NPTE9SX0ZPUk1BVF80MjI7Cj4gKwlzdHJ1Y3QgdjRsMl9tYnVz X2ZyYW1lZm10ICpmb3JtYXQgPSAmc3RhdGUtPmZvcm1hdDsKPiArCXUzMiBicGMgPSBYU1QzNTJf QllURTRfQklUX0RFUFRIXzEwOwo+ICsKPiArCW1vZGUgPSB4c2Rpcnhzc19yZWFkKGNvcmUsIFhT RElSWF9NT0RFX0RFVF9TVEFUX1JFRyk7Cj4gKwltb2RlICY9IFhTRElSWF9NT0RFX0RFVF9TVEFU X1JYX01PREVfTUFTSzsKPiArCj4gKwl2YWxpZCA9IHhzZGlyeHNzX3JlYWQoY29yZSwgWFNESVJY X1NUMzUyX1ZBTElEX1JFRyk7Cj4gKwo+ICsJaWYgKG1vZGUgPj0gWFNESVJYX01PREVfM0dfTUFT SyAmJiAhdmFsaWQpIHsKPiArCQlkZXZfZXJyKGRldiwgIk5vIHZhbGlkIFNUMzUyIHBheWxvYWQg cHJlc2VudCBldmVuIGZvciAzRyBtb2RlIGFuZCBhYm92ZVxuIik7Cj4gKwkJcmV0dXJuIC1FSU5W QUw7Cj4gKwl9Cj4gKwo+ICsJdmFsID0geHNkaXJ4c3NfcmVhZChjb3JlLCBYU0RJUlhfVFNfREVU X1NUQVRfUkVHKTsKPiArCWlmICh2YWxpZCAmIFhTRElSWF9TVDM1Ml9WQUxJRF9EUzFfTUFTSykg ewo+ICsJCXBheWxvYWQgPSB4c2Rpcnhzc19yZWFkKGNvcmUsIFhTRElSWF9TVDM1Ml9EUzFfUkVH KTsKPiArCQlieXRlMSA9IHJzaGlmdF9hbmRfbWFzayhwYXlsb2FkLCBYU1QzNTJfUEFZTE9BRF9C WVRFMSk7Cj4gKwkJYWN0aXZlX2x1bWEgPSBtYXNrX2FuZF9yc2hpZnQocGF5bG9hZCwKPiArCQkJ CQkgICAgICBYU1QzNTJfQllURTNfQUNUX0xVTUFfQ09VTlQpOwo+ICsJCXBpY190eXBlID0gbWFz a19hbmRfcnNoaWZ0KHBheWxvYWQsIFhTVDM1Ml9CWVRFMl9QSUNfVFlQRSk7Cj4gKwkJZnJhbWVy YXRlID0gcnNoaWZ0X2FuZF9tYXNrKHBheWxvYWQsIFhTVDM1Ml9CWVRFMl9GUFMpOwo+ICsJCXRz Y2FuID0gbWFza19hbmRfcnNoaWZ0KHBheWxvYWQsIFhTVDM1Ml9CWVRFMl9UU19UWVBFKTsKPiAr CQlzYW1wbGluZyA9IG1hc2tfYW5kX3JzaGlmdChwYXlsb2FkLCBYU1QzNTJfQllURTNfQ09MT1Jf Rk9STUFUKTsKPiArCQlicGMgPSBtYXNrX2FuZF9yc2hpZnQocGF5bG9hZCwgWFNUMzUyX0JZVEU0 X0JJVF9ERVBUSCk7Cj4gKwl9IGVsc2Ugewo+ICsJCWRldl9kYmcoZGV2LCAiTm8gU1QzNTIgcGF5 bG9hZCBhdmFpbGFibGUgOiBNb2RlID0gJWRcbiIsIG1vZGUpOwo+ICsJCWZyYW1lcmF0ZSA9IG1h c2tfYW5kX3JzaGlmdCh2YWwsIFhTRElSWF9UU19ERVRfU1RBVF9SQVRFKTsKPiArCQl0c2NhbiA9 IG1hc2tfYW5kX3JzaGlmdCh2YWwsIFhTRElSWF9UU19ERVRfU1RBVF9TQ0FOKTsKPiArCX0KPiAr Cj4gKwlpZiAoKGJwYyA9PSBYU1QzNTJfQllURTRfQklUX0RFUFRIXzEwICYmIGNvcmUtPmJwYyAh PSAxMCkgfHwKPiArCSAgICAoYnBjID09IFhTVDM1Ml9CWVRFNF9CSVRfREVQVEhfMTIgJiYgY29y ZS0+YnBjICE9IDEyKSkgewo+ICsJCWRldl9kYmcoZGV2LCAiQml0IGRlcHRoIG5vdCBzdXBwb3J0 ZWQuIGJwYyA9ICVkIGNvcmUtPmJwYyA9ICVkXG4iLAo+ICsJCQlicGMsIGNvcmUtPmJwYyk7Cj4g KwkJcmV0dXJuIC1FSU5WQUw7Cj4gKwl9Cj4gKwo+ICsJZmFtaWx5ID0gbWFza19hbmRfcnNoaWZ0 KHZhbCwgWFNESVJYX1RTX0RFVF9TVEFUX0ZBTUlMWSk7Cj4gKwlzdGF0ZS0+dHNfaXNfaW50ZXJs YWNlZCA9IHRzY2FuID8gZmFsc2UgOiB0cnVlOwo+ICsKPiArCWRldl9kYmcoZGV2LCAidHNfaXNf aW50ZXJsYWNlZCA9ICVkLCBmYW1pbHkgPSAlZFxuIiwKPiArCQlzdGF0ZS0+dHNfaXNfaW50ZXJs YWNlZCwgZmFtaWx5KTsKPiArCj4gKwlzd2l0Y2ggKG1vZGUpIHsKPiArCWNhc2UgWFNESVJYX01P REVfSERfTUFTSzoKPiArCQlpZiAoIXZhbGlkKSB7Cj4gKwkJCS8qIE5vIHBheWxvYWQgb2J0YWlu ZWQgKi8KPiArCQkJZGV2X2RiZyhkZXYsICJmcmFtZSByYXRlIDogJWQsIHRzY2FuID0gJWRcbiIs Cj4gKwkJCQlmcmFtZXJhdGUsIHRzY2FuKTsKPiArCQkJLyoKPiArCQkJICogTk9URSA6IEEgcHJv Z3Jlc3NpdmUgc2VnbWVudGVkIGZyYW1lIHBTRiB3aWxsIGJlCj4gKwkJCSAqIHJlcG9ydGVkIGlu Y29ycmVjdGx5IGFzIEludGVybGFjZWQgYXMgd2UgcmVseSBvbiBJUCdzCj4gKwkJCSAqIHRyYW5z cG9ydCBzY2FuIGxvY2tlZCBiaXQuCj4gKwkJCSAqLwo+ICsJCQlkZXZfd2FybihkZXYsICJwU0Yg d2lsbCBiZSBpbmNvcnJlY3RseSByZXBvcnRlZCBhcyBJbnRlcmxhY2VkXG4iKTsKPiArCj4gKwkJ CXN3aXRjaCAoZnJhbWVyYXRlKSB7Cj4gKwkJCWNhc2UgWFNESVJYX1RTX0RFVF9TVEFUX1JBVEVf MjNfOThIWjoKPiArCQkJY2FzZSBYU0RJUlhfVFNfREVUX1NUQVRfUkFURV8yNEhaOgo+ICsJCQlj YXNlIFhTRElSWF9UU19ERVRfU1RBVF9SQVRFXzI1SFo6Cj4gKwkJCWNhc2UgWFNESVJYX1RTX0RF VF9TVEFUX1JBVEVfMjlfOTdIWjoKPiArCQkJY2FzZSBYU0RJUlhfVFNfREVUX1NUQVRfUkFURV8z MEhaOgo+ICsJCQkJaWYgKGZhbWlseSA9PSBYU0RJUlhfU01QVEVfU1RfMjk2KSB7Cj4gKwkJCQkJ Zm9ybWF0LT53aWR0aCA9IDEyODA7Cj4gKwkJCQkJZm9ybWF0LT5oZWlnaHQgPSA3MjA7Cj4gKwkJ CQkJZm9ybWF0LT5maWVsZCA9IFY0TDJfRklFTERfTk9ORTsKPiArCQkJCX0gZWxzZSBpZiAoZmFt aWx5ID09IFhTRElSWF9TTVBURV9TVF8yMDQ4XzIpIHsKPiArCQkJCQlmb3JtYXQtPndpZHRoID0g MjA0ODsKPiArCQkJCQlmb3JtYXQtPmhlaWdodCA9IDEwODA7Cj4gKwkJCQkJaWYgKHRzY2FuKQo+ ICsJCQkJCQlmb3JtYXQtPmZpZWxkID0gVjRMMl9GSUVMRF9OT05FOwo+ICsJCQkJCWVsc2UKPiAr CQkJCQkJZm9ybWF0LT5maWVsZCA9Cj4gKwkJCQkJCQlWNEwyX0ZJRUxEX0FMVEVSTkFURTsKPiAr CQkJCX0gZWxzZSB7Cj4gKwkJCQkJZm9ybWF0LT53aWR0aCA9IDE5MjA7Cj4gKwkJCQkJZm9ybWF0 LT5oZWlnaHQgPSAxMDgwOwo+ICsJCQkJCWlmICh0c2NhbikKPiArCQkJCQkJZm9ybWF0LT5maWVs ZCA9IFY0TDJfRklFTERfTk9ORTsKPiArCQkJCQllbHNlCj4gKwkJCQkJCWZvcm1hdC0+ZmllbGQg PQo+ICsJCQkJCQkJVjRMMl9GSUVMRF9BTFRFUk5BVEU7Cj4gKwkJCQl9Cj4gKwkJCQlicmVhazsK PiArCQkJY2FzZSBYU0RJUlhfVFNfREVUX1NUQVRfUkFURV81MEhaOgo+ICsJCQljYXNlIFhTRElS WF9UU19ERVRfU1RBVF9SQVRFXzU5Xzk0SFo6Cj4gKwkJCWNhc2UgWFNESVJYX1RTX0RFVF9TVEFU X1JBVEVfNjBIWjoKPiArCQkJCWlmIChmYW1pbHkgPT0gWFNESVJYX1NNUFRFX1NUXzI3NCkgewo+ ICsJCQkJCWZvcm1hdC0+d2lkdGggPSAxOTIwOwo+ICsJCQkJCWZvcm1hdC0+aGVpZ2h0ID0gMTA4 MDsKPiArCQkJCX0gZWxzZSB7Cj4gKwkJCQkJZm9ybWF0LT53aWR0aCA9IDEyODA7Cj4gKwkJCQkJ Zm9ybWF0LT5oZWlnaHQgPSA3MjA7Cj4gKwkJCQl9Cj4gKwkJCQlmb3JtYXQtPmZpZWxkID0gVjRM Ml9GSUVMRF9OT05FOwo+ICsJCQkJYnJlYWs7Cj4gKwkJCWRlZmF1bHQ6Cj4gKwkJCQlmb3JtYXQt PndpZHRoID0gMTkyMDsKPiArCQkJCWZvcm1hdC0+aGVpZ2h0ID0gMTA4MDsKPiArCQkJCWZvcm1h dC0+ZmllbGQgPSBWNEwyX0ZJRUxEX05PTkU7Cj4gKwkJCX0KPiArCQl9IGVsc2Ugewo+ICsJCQlk ZXZfZGJnKGRldiwgIkdvdCB0aGUgcGF5bG9hZFxuIik7Cj4gKwkJCXN3aXRjaCAoYnl0ZTEpIHsK PiArCQkJY2FzZSBYU1QzNTJfQllURTFfU1QyOTJfMXg3MjBMXzFfNUc6Cj4gKwkJCQkvKiBTTVBU RSBTVCAyOTItMSBmb3IgNzIwIGxpbmUgcGF5bG9hZHMgKi8KPiArCQkJCWZvcm1hdC0+d2lkdGgg PSAxMjgwOwo+ICsJCQkJZm9ybWF0LT5oZWlnaHQgPSA3MjA7Cj4gKwkJCQlicmVhazsKPiArCQkJ Y2FzZSBYU1QzNTJfQllURTFfU1QyOTJfMXgxMDgwTF8xXzVHOgo+ICsJCQkJLyogU01QVEUgU1Qg MjkyLTEgZm9yIDEwODAgbGluZSBwYXlsb2FkcyAqLwo+ICsJCQkJZm9ybWF0LT5oZWlnaHQgPSAx MDgwOwo+ICsJCQkJaWYgKGFjdGl2ZV9sdW1hKQo+ICsJCQkJCWZvcm1hdC0+d2lkdGggPSAyMDQ4 Owo+ICsJCQkJZWxzZQo+ICsJCQkJCWZvcm1hdC0+d2lkdGggPSAxOTIwOwo+ICsJCQkJYnJlYWs7 Cj4gKwkJCWRlZmF1bHQ6Cj4gKwkJCQlkZXZfZGJnKGRldiwgIlVua25vd24gSEQgTW9kZSBTTVBU RSBzdGFuZGFyZFxuIik7Cj4gKwkJCQlyZXR1cm4gLUVJTlZBTDsKPiArCQkJfQo+ICsJCX0KPiAr CQlicmVhazsKPiArCWNhc2UgWFNESVJYX01PREVfU0RfTUFTSzoKPiArCQlmb3JtYXQtPmZpZWxk ID0gVjRMMl9GSUVMRF9BTFRFUk5BVEU7Cj4gKwo+ICsJCXN3aXRjaCAoZmFtaWx5KSB7Cj4gKwkJ Y2FzZSBYU0RJUlhfTlRTQzoKPiArCQkJZm9ybWF0LT53aWR0aCA9IDcyMDsKPiArCQkJZm9ybWF0 LT5oZWlnaHQgPSA0ODY7Cj4gKwkJCWJyZWFrOwo+ICsJCWNhc2UgWFNESVJYX1BBTDoKPiArCQkJ Zm9ybWF0LT53aWR0aCA9IDcyMDsKPiArCQkJZm9ybWF0LT5oZWlnaHQgPSA1NzY7Cj4gKwkJCWJy ZWFrOwo+ICsJCWRlZmF1bHQ6Cj4gKwkJCWRldl9kYmcoZGV2LCAiVW5rbm93biBTRCBNb2RlIFNN UFRFIHN0YW5kYXJkXG4iKTsKPiArCQkJcmV0dXJuIC1FSU5WQUw7Cj4gKwkJfQo+ICsJCWJyZWFr Owo+ICsJY2FzZSBYU0RJUlhfTU9ERV8zR19NQVNLOgo+ICsJCXN3aXRjaCAoYnl0ZTEpIHsKPiAr CQljYXNlIFhTVDM1Ml9CWVRFMV9TVDQyNV8yMDA4Xzc1MExfM0dCOgo+ICsJCQkvKiBTZWMgNC4x LjYuMSBTTVBURSA0MjUtMjAwOCAqLwo+ICsJCWNhc2UgWFNUMzUyX0JZVEUxX1NUMzcyXzJ4NzIw TF8zR0I6Cj4gKwkJCS8qIFRhYmxlIDEzIFNNUFRFIDQyNS0yMDA4ICovCj4gKwkJCWZvcm1hdC0+ d2lkdGggPSAxMjgwOwo+ICsJCQlmb3JtYXQtPmhlaWdodCA9IDcyMDsKPiArCQkJYnJlYWs7Cj4g KwkJY2FzZSBYU1QzNTJfQllURTFfU1Q0MjVfMjAwOF8xMTI1TF8zR0E6Cj4gKwkJCS8qIFNUMzUy IFRhYmxlIFNNUFRFIDQyNS0xICovCj4gKwkJY2FzZSBYU1QzNTJfQllURTFfU1QzNzJfRExfM0dC Ogo+ICsJCQkvKiBUYWJsZSAxMyBTTVBURSA0MjUtMjAwOCAqLwo+ICsJCWNhc2UgWFNUMzUyX0JZ VEUxX1NUMzcyXzJ4MTA4MExfM0dCOgo+ICsJCQkvKiBUYWJsZSAxMyBTTVBURSA0MjUtMjAwOCAq Lwo+ICsJCQlmb3JtYXQtPmhlaWdodCA9IDEwODA7Cj4gKwkJCWlmIChhY3RpdmVfbHVtYSkKPiAr CQkJCWZvcm1hdC0+d2lkdGggPSAyMDQ4Owo+ICsJCQllbHNlCj4gKwkJCQlmb3JtYXQtPndpZHRo ID0gMTkyMDsKPiArCQkJYnJlYWs7Cj4gKwkJZGVmYXVsdDoKPiArCQkJZGV2X2RiZyhkZXYsICJV bmtub3duIDNHIE1vZGUgU01QVEUgc3RhbmRhcmRcbiIpOwo+ICsJCQlyZXR1cm4gLUVJTlZBTDsK PiArCQl9Cj4gKwkJYnJlYWs7Cj4gKwljYXNlIFhTRElSWF9NT0RFXzZHX01BU0s6Cj4gKwkJc3dp dGNoIChieXRlMSkgewo+ICsJCWNhc2UgWFNUMzUyX0JZVEUxX1NUMjA4MV8xMF9ETF8yMTYwTF82 RzoKPiArCQkJLyogRHVhbCBsaW5rIDZHICovCj4gKwkJY2FzZSBYU1QzNTJfQllURTFfU1QyMDgx XzEwXzIxNjBMXzZHOgo+ICsJCQkvKiBUYWJsZSAzIFNNUFRFIFNUIDIwODEtMTAgKi8KPiArCQkJ Zm9ybWF0LT5oZWlnaHQgPSAyMTYwOwo+ICsJCQlpZiAoYWN0aXZlX2x1bWEpCj4gKwkJCQlmb3Jt YXQtPndpZHRoID0gNDA5NjsKPiArCQkJZWxzZQo+ICsJCQkJZm9ybWF0LT53aWR0aCA9IDM4NDA7 Cj4gKwkJCWJyZWFrOwo+ICsJCWNhc2UgWFNUMzUyX0JZVEUxX1NUMjA4MV8xMF8yXzEwODBMXzZH Ogo+ICsJCQlmb3JtYXQtPmhlaWdodCA9IDEwODA7Cj4gKwkJCWlmIChhY3RpdmVfbHVtYSkKPiAr CQkJCWZvcm1hdC0+d2lkdGggPSAyMDQ4Owo+ICsJCQllbHNlCj4gKwkJCQlmb3JtYXQtPndpZHRo ID0gMTkyMDsKPiArCQkJYnJlYWs7Cj4gKwkJZGVmYXVsdDoKPiArCQkJZGV2X2RiZyhkZXYsICJV bmtub3duIDZHIE1vZGUgU01QVEUgc3RhbmRhcmRcbiIpOwo+ICsJCQlyZXR1cm4gLUVJTlZBTDsK PiArCQl9Cj4gKwkJYnJlYWs7Cj4gKwljYXNlIFhTRElSWF9NT0RFXzEyR0lfTUFTSzoKPiArCWNh c2UgWFNESVJYX01PREVfMTJHRl9NQVNLOgo+ICsJCXN3aXRjaCAoYnl0ZTEpIHsKPiArCQljYXNl IFhTVDM1Ml9CWVRFMV9TVDIwODJfMTBfMjE2MExfMTJHOgo+ICsJCQkvKiBTZWN0aW9uIDQuMy4x IFNNUFRFIFNUIDIwODItMTAgKi8KPiArCQkJZm9ybWF0LT5oZWlnaHQgPSAyMTYwOwo+ICsJCQlp ZiAoYWN0aXZlX2x1bWEpCj4gKwkJCQlmb3JtYXQtPndpZHRoID0gNDA5NjsKPiArCQkJZWxzZQo+ ICsJCQkJZm9ybWF0LT53aWR0aCA9IDM4NDA7Cj4gKwkJCWJyZWFrOwo+ICsJCWRlZmF1bHQ6Cj4g KwkJCWRldl9kYmcoZGV2LCAiVW5rbm93biAxMkcgTW9kZSBTTVBURSBzdGFuZGFyZFxuIik7Cj4g KwkJCXJldHVybiAtRUlOVkFMOwo+ICsJCX0KPiArCQlicmVhazsKPiArCWRlZmF1bHQ6Cj4gKwkJ ZGV2X2VycihkZXYsICJJbnZhbGlkIE1vZGVcbiIpOwo+ICsJCXJldHVybiAtRUlOVkFMOwo+ICsJ fQo+ICsKPiArCWlmICh2YWxpZCkgewo+ICsJCWlmIChwaWNfdHlwZSkKPiArCQkJZm9ybWF0LT5m aWVsZCA9IFY0TDJfRklFTERfTk9ORTsKPiArCQllbHNlCj4gKwkJCWZvcm1hdC0+ZmllbGQgPSBW NEwyX0ZJRUxEX0FMVEVSTkFURTsKPiArCj4gKwkJaWYgKGZvcm1hdC0+aGVpZ2h0ID09IDEwODAg JiYgcGljX3R5cGUgJiYgIXRzY2FuKQo+ICsJCQlmb3JtYXQtPmZpZWxkID0gVjRMMl9GSUVMRF9B TFRFUk5BVEU7Cj4gKwo+ICsJCS8qCj4gKwkJICogSW4gM0dCIERMIHBTRiBtb2RlIHRoZSB2aWRl byBpcyBzaW1pbGFyIHRvIGludGVybGFjZWQuCj4gKwkJICogU28gdGhvdWdoIGl0IGlzIGEgcHJv Z3Jlc3NpdmUgdmlkZW8sIGl0cyB0cmFuc3BvcnQgaXMKPiArCQkgKiBpbnRlcmxhY2VkIGFuZCBp cyBzZW50IGFzIHR3byB3aWR0aCB4IChoZWlnaHQvMikgYnVmZmVycy4KPiArCQkgKi8KPiArCQlp ZiAoYnl0ZTEgPT0gWFNUMzUyX0JZVEUxX1NUMzcyX0RMXzNHQikgewo+ICsJCQlpZiAoc3RhdGUt PnRzX2lzX2ludGVybGFjZWQpCj4gKwkJCQlmb3JtYXQtPmZpZWxkID0gVjRMMl9GSUVMRF9BTFRF Uk5BVEU7Cj4gKwkJCWVsc2UKPiArCQkJCWZvcm1hdC0+ZmllbGQgPSBWNEwyX0ZJRUxEX05PTkU7 Cj4gKwkJfQo+ICsJfQo+ICsKPiArCWlmIChmb3JtYXQtPmZpZWxkID09IFY0TDJfRklFTERfQUxU RVJOQVRFKQo+ICsJCWZvcm1hdC0+aGVpZ2h0ID0gZm9ybWF0LT5oZWlnaHQgLyAyOwo+ICsKPiAr CXN3aXRjaCAoc2FtcGxpbmcpIHsKPiArCWNhc2UgWFNUMzUyX0JZVEUzX0NPTE9SX0ZPUk1BVF80 MjI6Cj4gKwkJaWYgKGNvcmUtPmJwYyA9PSAxMCkKPiArCQkJZm9ybWF0LT5jb2RlID0gTUVESUFf QlVTX0ZNVF9VWVZZMTBfMVgyMDsKPiArCQllbHNlCj4gKwkJCWZvcm1hdC0+Y29kZSA9IE1FRElB X0JVU19GTVRfVVlWWTEyXzFYMjQ7Cj4gKwkJYnJlYWs7Cj4gKwljYXNlIFhTVDM1Ml9CWVRFM19D T0xPUl9GT1JNQVRfNDIwOgo+ICsJY2FzZSBYU1QzNTJfQllURTNfQ09MT1JfRk9STUFUX1lVVjQ0 NDoKPiArCWNhc2UgWFNUMzUyX0JZVEUzX0NPTE9SX0ZPUk1BVF9HQlI6Cj4gKwkJZm9ybWF0LT5j b2RlID0gMDsKPiArCQlkZXZfZGJnKGRldiwgIk5vIGNvcnJlc3BvbmRpbmcgbWVkaWEgYnVzIGZv cm1hdHNcbiIpOwo+ICsJCWJyZWFrOwo+ICsJZGVmYXVsdDoKPiArCQlkZXZfZXJyKGRldiwgIlVu c3VwcG9ydGVkIGNvbG9yIGZvcm1hdCA6ICVkXG4iLCBzYW1wbGluZyk7Cj4gKwkJcmV0dXJuIC1F SU5WQUw7Cj4gKwl9Cj4gKwo+ICsJeHNkaXJ4c3NfZ2V0X2ZyYW1lcmF0ZSgmc3RhdGUtPmZyYW1l X2ludGVydmFsLCBmcmFtZXJhdGUpOwo+ICsKPiArCWRldl9kYmcoZGV2LCAiU3RyZWFtIHdpZHRo ID0gJWQgaGVpZ2h0ID0gJWQgRmllbGQgPSAlZCBwYXlsb2FkID0gMHglMDh4IHRzID0gMHglMDh4 XG4iLAo+ICsJCWZvcm1hdC0+d2lkdGgsIGZvcm1hdC0+aGVpZ2h0LCBmb3JtYXQtPmZpZWxkLCBw YXlsb2FkLCB2YWwpOwo+ICsJZGV2X2RiZyhkZXYsICJmcmFtZSByYXRlIG51bWVyYXRvciA9ICVk IGRlbm9taW5hdG9yID0gJWRcbiIsCj4gKwkJc3RhdGUtPmZyYW1lX2ludGVydmFsLm51bWVyYXRv ciwKPiArCQlzdGF0ZS0+ZnJhbWVfaW50ZXJ2YWwuZGVub21pbmF0b3IpOwo+ICsJZGV2X2RiZyhk ZXYsICJTdHJlYW0gY29kZSA9IDB4JXhcbiIsIGZvcm1hdC0+Y29kZSk7Cj4gKwlyZXR1cm4gMDsK PiArfQo+ICsKPiArLyoqCj4gKyAqIHhzZGlyeHNzX2lycV9oYW5kbGVyIC0gSW50ZXJydXB0IGhh bmRsZXIgZm9yIFNESSBSeAo+ICsgKiBAaXJxOiBJUlEgbnVtYmVyCj4gKyAqIEBkZXZfaWQ6IFBv aW50ZXIgdG8gZGV2aWNlIHN0YXRlCj4gKyAqCj4gKyAqIFRoZSBTREkgUnggaW50ZXJydXB0cyBh cmUgY2xlYXJlZCBieSB3cml0aW5nIDEgdG8gY29ycmVzcG9uZGluZyBiaXQuCj4gKyAqCj4gKyAq IFJldHVybjogSVJRX0hBTkRMRUQgYWZ0ZXIgaGFuZGxpbmcgaW50ZXJydXB0cwo+ICsgKi8KPiAr c3RhdGljIGlycXJldHVybl90IHhzZGlyeHNzX2lycV9oYW5kbGVyKGludCBpcnEsIHZvaWQgKmRl dl9pZCkKPiArewo+ICsJc3RydWN0IHhzZGlyeHNzX3N0YXRlICpzdGF0ZSA9IChzdHJ1Y3QgeHNk aXJ4c3Nfc3RhdGUgKilkZXZfaWQ7Cj4gKwlzdHJ1Y3QgeHNkaXJ4c3NfY29yZSAqY29yZSA9ICZz dGF0ZS0+Y29yZTsKPiArCXN0cnVjdCBkZXZpY2UgKmRldiA9IGNvcmUtPmRldjsKPiArCXUzMiBz dGF0dXM7Cj4gKwo+ICsJc3RhdHVzID0geHNkaXJ4c3NfcmVhZChjb3JlLCBYU0RJUlhfSVNSX1JF Ryk7Cj4gKwl4c2Rpcnhzc193cml0ZShjb3JlLCBYU0RJUlhfSVNSX1JFRywgc3RhdHVzKTsKPiAr CWRldl9kYmcoZGV2LCAiaW50ZXJydXB0IHN0YXR1cyA9IDB4JTA4eFxuIiwgc3RhdHVzKTsKPiAr Cj4gKwlpZiAoc3RhdHVzICYgWFNESVJYX0lOVFJfVklETE9DS19NQVNLIHx8Cj4gKwkgICAgc3Rh dHVzICYgWFNESVJYX0lOVFJfVklEVU5MT0NLX01BU0spIHsKPiArCQl1MzIgdmFsMSwgdmFsMjsK PiArCj4gKwkJZGV2X2RiZyhkZXYsICJ2aWRlbyBsb2NrL3VubG9jayBpbnRlcnJ1cHRcbiIpOwo+ ICsKPiArCQl4c2Rpcnhfc3RyZWFtZmxvd19jb250cm9sKGNvcmUsIGZhbHNlKTsKPiArCQlzdGF0 ZS0+c3RyZWFtaW5nID0gZmFsc2U7Cj4gKwo+ICsJCXZhbDEgPSB4c2Rpcnhzc19yZWFkKGNvcmUs IFhTRElSWF9NT0RFX0RFVF9TVEFUX1JFRyk7Cj4gKwkJdmFsMiA9IHhzZGlyeHNzX3JlYWQoY29y ZSwgWFNESVJYX1RTX0RFVF9TVEFUX1JFRyk7Cj4gKwo+ICsJCWlmICgodmFsMSAmIFhTRElSWF9N T0RFX0RFVF9TVEFUX01PREVfTE9DS19NQVNLKSAmJgo+ICsJCSAgICAodmFsMiAmIFhTRElSWF9U U19ERVRfU1RBVF9MT0NLRURfTUFTSykpIHsKPiArCQkJdTMyIG1hc2sgPSBYU0RJUlhfUlNUX0NU UkxfUlNUX0NSQ19FUlJDTlRfTUFTSyB8Cj4gKwkJCQkgICBYU0RJUlhfUlNUX0NUUkxfUlNUX0VE SF9FUlJDTlRfTUFTSzsKPiArCj4gKwkJCWRldl9kYmcoZGV2LCAidmlkZW8gbG9jayBpbnRlcnJ1 cHRcbiIpOwo+ICsKPiArCQkJeHNkaXJ4c3Nfc2V0KGNvcmUsIFhTRElSWF9SU1RfQ1RSTF9SRUcs IG1hc2spOwo+ICsJCQl4c2Rpcnhzc19jbHIoY29yZSwgWFNESVJYX1JTVF9DVFJMX1JFRywgbWFz ayk7Cj4gKwo+ICsJCQl2YWwxID0geHNkaXJ4c3NfcmVhZChjb3JlLCBYU0RJUlhfU1QzNTJfVkFM SURfUkVHKTsKPiArCQkJdmFsMiA9IHhzZGlyeHNzX3JlYWQoY29yZSwgWFNESVJYX1NUMzUyX0RT MV9SRUcpOwo+ICsKPiArCQkJZGV2X2RiZyhkZXYsICJ2YWxpZCBzdDM1MiBtYXNrID0gMHglMDh4 XG4iLCB2YWwxKTsKPiArCQkJZGV2X2RiZyhkZXYsICJzdDM1MiBwYXlsb2FkID0gMHglMDh4XG4i LCB2YWwyKTsKPiArCj4gKwkJCWlmICgheHNkaXJ4X2dldF9zdHJlYW1fcHJvcGVydGllcyhzdGF0 ZSkpIHsKPiArCQkJCXN0YXRlLT52aWRsb2NrZWQgPSB0cnVlOwo+ICsJCQkJeHNkaXJ4c3Nfc2V0 X2d0Y2xrKHN0YXRlKTsKPiArCQkJfSBlbHNlIHsKPiArCQkJCWRldl9lcnIoZGV2LCAiVW5hYmxl IHRvIGdldCBzdHJlYW0gcHJvcGVydGllcyFcbiIpOwo+ICsJCQkJc3RhdGUtPnZpZGxvY2tlZCA9 IGZhbHNlOwo+ICsJCQl9Cj4gKwkJfSBlbHNlIHsKPiArCQkJZGV2X2RiZyhkZXYsICJ2aWRlbyB1 bmxvY2sgaW50ZXJydXB0XG4iKTsKPiArCQkJc3RhdGUtPnZpZGxvY2tlZCA9IGZhbHNlOwo+ICsJ CX0KPiArCj4gKwkJbWVtc2V0KCZzdGF0ZS0+ZXZlbnQsIDAsIHNpemVvZihzdGF0ZS0+ZXZlbnQp KTsKPiArCQlzdGF0ZS0+ZXZlbnQudHlwZSA9IFY0TDJfRVZFTlRfU09VUkNFX0NIQU5HRTsKPiAr CQlzdGF0ZS0+ZXZlbnQudS5zcmNfY2hhbmdlLmNoYW5nZXMgPQo+ICsJCQlWNEwyX0VWRU5UX1NS Q19DSF9SRVNPTFVUSU9OOwo+ICsJCXY0bDJfc3ViZGV2X25vdGlmeV9ldmVudCgmc3RhdGUtPnN1 YmRldiwgJnN0YXRlLT5ldmVudCk7Cj4gKwl9Cj4gKwo+ICsJaWYgKHN0YXR1cyAmIFhTRElSWF9J TlRSX1VOREVSRkxPV19NQVNLKSB7Cj4gKwkJZGV2X2RiZyhkZXYsICJWaWRlbyBpbiB0byBBWEk0 IFN0cmVhbSBjb3JlIHVuZGVyZmxvdyBpbnRlcnJ1cHRcbiIpOwo+ICsKPiArCQltZW1zZXQoJnN0 YXRlLT5ldmVudCwgMCwgc2l6ZW9mKHN0YXRlLT5ldmVudCkpOwo+ICsJCXN0YXRlLT5ldmVudC50 eXBlID0gVjRMMl9FVkVOVF9YSUxJTlhfU0RJUlhfVU5ERVJGTE9XOwo+ICsJCXY0bDJfc3ViZGV2 X25vdGlmeV9ldmVudCgmc3RhdGUtPnN1YmRldiwgJnN0YXRlLT5ldmVudCk7Cj4gKwl9Cj4gKwo+ ICsJaWYgKHN0YXR1cyAmIFhTRElSWF9JTlRSX09WRVJGTE9XX01BU0spIHsKPiArCQlkZXZfZGJn KGRldiwgIlZpZGVvIGluIHRvIEFYSTQgU3RyZWFtIGNvcmUgb3ZlcmZsb3cgaW50ZXJydXB0XG4i KTsKPiArCj4gKwkJbWVtc2V0KCZzdGF0ZS0+ZXZlbnQsIDAsIHNpemVvZihzdGF0ZS0+ZXZlbnQp KTsKPiArCQlzdGF0ZS0+ZXZlbnQudHlwZSA9IFY0TDJfRVZFTlRfWElMSU5YX1NESVJYX09WRVJG TE9XOwo+ICsJCXY0bDJfc3ViZGV2X25vdGlmeV9ldmVudCgmc3RhdGUtPnN1YmRldiwgJnN0YXRl LT5ldmVudCk7Cj4gKwl9CgpDYW4ndCB3ZSBjb21iaW5lIHRoZXNlIHR3byBpbiBhIHNpbmdsZSBl dmVudCB0eXBlLCB3aXRoIHVuZGVyZmxvdyBhbmQKb3ZlcmZsb3cgcmVwb3J0ZWQgaW4gdGhlIGV2 ZW50IHBheWxvYWQgaW4gYSBiaXRtYXNrID8KCj4gKwlyZXR1cm4gSVJRX0hBTkRMRUQ7Cj4gK30K PiArCj4gKy8qKgo+ICsgKiB4c2Rpcnhzc19zdWJzY3JpYmVfZXZlbnQgLSBTdWJzY3JpYmUgdG8g dmlkZW8gbG9jayBhbmQgdW5sb2NrIGV2ZW50Cj4gKyAqIEBzZDogVjRMMiBTdWIgZGV2aWNlCj4g KyAqIEBmaDogVjRMMiBGaWxlIEhhbmRsZQo+ICsgKiBAc3ViOiBTdWJjcmliZSBldmVudCBzdHJ1 Y3R1cmUKPiArICoKPiArICogUmV0dXJuOiAwIG9uIHN1Y2Nlc3MsIGVycm9ycyBvdGhlcndpc2UK PiArICovCj4gK3N0YXRpYyBpbnQgeHNkaXJ4c3Nfc3Vic2NyaWJlX2V2ZW50KHN0cnVjdCB2NGwy X3N1YmRldiAqc2QsCj4gKwkJCQkgICAgc3RydWN0IHY0bDJfZmggKmZoLAo+ICsJCQkJICAgIHN0 cnVjdCB2NGwyX2V2ZW50X3N1YnNjcmlwdGlvbiAqc3ViKQo+ICt7Cj4gKwlpbnQgcmV0Owo+ICsJ c3RydWN0IHhzZGlyeHNzX3N0YXRlICp4c2RpcnhzcyA9IHRvX3hzZGlyeHNzc3RhdGUoc2QpOwo+ ICsJc3RydWN0IHhzZGlyeHNzX2NvcmUgKmNvcmUgPSAmeHNkaXJ4c3MtPmNvcmU7Cj4gKwo+ICsJ c3dpdGNoIChzdWItPnR5cGUpIHsKPiArCWNhc2UgVjRMMl9FVkVOVF9YSUxJTlhfU0RJUlhfVU5E RVJGTE9XOgo+ICsJY2FzZSBWNEwyX0VWRU5UX1hJTElOWF9TRElSWF9PVkVSRkxPVzoKPiArCQly ZXQgPSB2NGwyX2V2ZW50X3N1YnNjcmliZShmaCwgc3ViLCBYU0RJUlhfTUFYX0VWRU5UUywgTlVM TCk7Cj4gKwkJYnJlYWs7Cj4gKwljYXNlIFY0TDJfRVZFTlRfU09VUkNFX0NIQU5HRToKPiArCQly ZXQgPSB2NGwyX3NyY19jaGFuZ2VfZXZlbnRfc3Vic2NyaWJlKGZoLCBzdWIpOwo+ICsJCWJyZWFr Owo+ICsJZGVmYXVsdDoKPiArCQlyZXR1cm4gLUVJTlZBTDsKCkFzIEhhbnMgY29tbWVudGVkLCB5 b3UgbmVlZCB0byBjYWxsIHY0bDJfY3RybF9zdWJzY3JpYmVfZXZlbnQoKSBoZXJlLgoKPiArCX0K PiArCWRldl9kYmcoY29yZS0+ZGV2LCAiRXZlbnQgc3Vic2NyaWJlZCA6IDB4JTA4eFxuIiwgc3Vi LT50eXBlKTsKPiArCXJldHVybiByZXQ7Cj4gK30KPiArCj4gKy8qKgo+ICsgKiB4c2Rpcnhzc191 bnN1YnNjcmliZV9ldmVudCAtIFVuc3Vic2NyaWJlIGZyb20gYWxsIGV2ZW50cyByZWdpc3RlcmVk Cj4gKyAqIEBzZDogVjRMMiBTdWIgZGV2aWNlCj4gKyAqIEBmaDogVjRMMiBmaWxlIGhhbmRsZQo+ ICsgKiBAc3ViOiBwb2ludGVyIHRvIEV2ZW50IHVuc3Vic2NyaXB0aW9uIHN0cnVjdHVyZQo+ICsg Kgo+ICsgKiBSZXR1cm46IHplcm8gb24gc3VjY2VzcywgZWxzZSBhIG5lZ2F0aXZlIGVycm9yIGNv ZGUuCj4gKyAqLwo+ICtzdGF0aWMgaW50IHhzZGlyeHNzX3Vuc3Vic2NyaWJlX2V2ZW50KHN0cnVj dCB2NGwyX3N1YmRldiAqc2QsCj4gKwkJCQkgICAgICBzdHJ1Y3QgdjRsMl9maCAqZmgsCj4gKwkJ CQkgICAgICBzdHJ1Y3QgdjRsMl9ldmVudF9zdWJzY3JpcHRpb24gKnN1YikKPiArewo+ICsJc3Ry dWN0IHhzZGlyeHNzX3N0YXRlICp4c2RpcnhzcyA9IHRvX3hzZGlyeHNzc3RhdGUoc2QpOwo+ICsJ c3RydWN0IHhzZGlyeHNzX2NvcmUgKmNvcmUgPSAmeHNkaXJ4c3MtPmNvcmU7Cj4gKwo+ICsJZGV2 X2RiZyhjb3JlLT5kZXYsICJFdmVudCB1bnN1YnNjcmliZSA6IDB4JTA4eFxuIiwgc3ViLT50eXBl KTsKPiArCXJldHVybiB2NGwyX2V2ZW50X3Vuc3Vic2NyaWJlKGZoLCBzdWIpOwo+ICt9CgpJIHRo aW5rIHlvdSBjYW4gZHJvcCB0aGlzIGZ1bmN0aW9uIGFuZCB1c2UgdjRsMl9ldmVudF9zdWJkZXZf dW5zdWJzY3JpYmUKYXMgdGhlIC4udW5zdWJzY3JpYmVfZXZlbnQoKSBoYW5kbGVyLgoKPiArCj4g Ky8qKgo+ICsgKiB4c2Rpcnhzc19zX2N0cmwgLSBUaGlzIGlzIHVzZWQgdG8gc2V0IHRoZSBYaWxp bnggU0RJIFJ4IFY0TDIgY29udHJvbHMKPiArICogQGN0cmw6IFY0TDIgY29udHJvbCB0byBiZSBz ZXQKPiArICoKPiArICogVGhpcyBmdW5jdGlvbiBpcyB1c2VkIHRvIHNldCB0aGUgVjRMMiBjb250 cm9scyBmb3IgdGhlIFhpbGlueCBTREkgUngKPiArICogU3Vic3lzdGVtLgo+ICsgKgo+ICsgKiBS ZXR1cm46IDAgb24gc3VjY2VzcywgZXJyb3JzIG90aGVyd2lzZQo+ICsgKi8KPiArc3RhdGljIGlu dCB4c2Rpcnhzc19zX2N0cmwoc3RydWN0IHY0bDJfY3RybCAqY3RybCkKPiArewo+ICsJaW50IHJl dCA9IDA7Cj4gKwlzdHJ1Y3QgeHNkaXJ4c3Nfc3RhdGUgKnhzZGlyeHNzID0KPiArCQljb250YWlu ZXJfb2YoY3RybC0+aGFuZGxlciwgc3RydWN0IHhzZGlyeHNzX3N0YXRlLAo+ICsJCQkgICAgIGN0 cmxfaGFuZGxlcik7Cj4gKwlzdHJ1Y3QgeHNkaXJ4c3NfY29yZSAqY29yZSA9ICZ4c2Rpcnhzcy0+ Y29yZTsKPiArCXN0cnVjdCBkZXZpY2UgKmRldiA9IGNvcmUtPmRldjsKPiArCj4gKwlkZXZfZGJn KGRldiwgInNldCBjdHJsIGlkID0gMHglMDh4IHZhbCA9IDB4JTA4eFxuIiwKPiArCQljdHJsLT5p ZCwgY3RybC0+dmFsKTsKPiArCj4gKwlpZiAoeHNkaXJ4c3MtPnN0cmVhbWluZykgewo+ICsJCWRl dl9lcnIoZGV2LCAiQ2Fubm90IHNldCBjb250cm9scyB3aGlsZSBzdHJlYW1pbmdcbiIpOwo+ICsJ CXJldHVybiAtRUlOVkFMOwo+ICsJfQo+ICsKPiArCXhzZGlyeF9jb3JlX2Rpc2FibGUoY29yZSk7 Cj4gKwlzd2l0Y2ggKGN0cmwtPmlkKSB7Cj4gKwljYXNlIFY0TDJfQ0lEX1hJTElOWF9TRElSWF9G UkFNRVI6Cj4gKwkJeHNkaXJ4X2ZyYW1lcihjb3JlLCBjdHJsLT52YWwpOwo+ICsJCXhzZGlyeHNz LT5mcmFtZXJfZW5hYmxlID0gY3RybC0+dmFsOwo+ICsJCWJyZWFrOwo+ICsJY2FzZSBWNEwyX0NJ RF9YSUxJTlhfU0RJUlhfVklETE9DS19XSU5ET1c6Cj4gKwkJeHNkaXJ4X3NldHZpZGxvY2t3aW5k b3coY29yZSwgY3RybC0+dmFsKTsKPiArCQl4c2Rpcnhzcy0+dmlkbG9ja3dpbiA9IGN0cmwtPnZh bDsKPiArCQlicmVhazsKPiArCWNhc2UgVjRMMl9DSURfWElMSU5YX1NESVJYX0VESF9FUlJDTlRf RU5BQkxFOgoKQXMgdGhpcyBpcyB1c2VkIHRvIHNlbGVjdCB3aGljaCBlcnJvciBzb3VyY2VzIHRv IGVuYWJsZSwgaG93IGFib3V0Cm5hbWluZyB0aGUgY29udHJvbCBWNEwyX0NJRF9YSUxJTlhfU0RJ UlhfRURIX0VSUk9SX1NPVVJDRVMgb3IKVjRMMl9DSURfWElMSU5YX1NESVJYX0VESF9FUlJPUlNf TUFTSyA/Cgo+ICsJCXhzZGlyeF9zZXRlZGhlcnJjbnR0cmlnZ2VyKGNvcmUsIGN0cmwtPnZhbCk7 Cj4gKwkJeHNkaXJ4c3MtPmVkaG1hc2sgPSBjdHJsLT52YWw7Cj4gKwkJYnJlYWs7Cj4gKwljYXNl IFY0TDJfQ0lEX1hJTElOWF9TRElSWF9TRUFSQ0hfTU9ERVM6Cj4gKwkJaWYgKGN0cmwtPnZhbCkg ewo+ICsJCQlpZiAoY29yZS0+bW9kZSA9PSBYU0RJUlhTU19TRElfU1REXzNHKSB7Cj4gKwkJCQlk ZXZfZGJnKGRldiwgIlVwdG8gM0cgc3VwcG9ydGVkXG4iKTsKPiArCQkJCWN0cmwtPnZhbCAmPSB+ KEJJVChYU0RJUlhfTU9ERV82R19PRkZTRVQpIHwKPiArCQkJCQkgICAgICAgQklUKFhTRElSWF9N T0RFXzEyR0lfT0ZGU0VUKSB8Cj4gKwkJCQkJICAgICAgIEJJVChYU0RJUlhfTU9ERV8xMkdGX09G RlNFVCkpOwo+ICsJCQl9Cj4gKwo+ICsJCQlpZiAoY29yZS0+bW9kZSA9PSBYU0RJUlhTU19TRElf U1REXzZHKSB7Cj4gKwkJCQlkZXZfZGJnKGRldiwgIlVwdG8gNkcgc3VwcG9ydGVkXG4iKTsKPiAr CQkJCWN0cmwtPnZhbCAmPSB+KEJJVChYU0RJUlhfTU9ERV8xMkdJX09GRlNFVCkgfAo+ICsJCQkJ CSAgICAgICBCSVQoWFNESVJYX01PREVfMTJHRl9PRkZTRVQpKTsKPiArCQkJfQo+ICsKPiArCQkJ cmV0ID0geHNkaXJ4X3NldF9tb2RlZGV0ZWN0KGNvcmUsIGN0cmwtPnZhbCk7Cj4gKwkJCWlmICgh cmV0KQo+ICsJCQkJeHNkaXJ4c3MtPnNlYXJjaG1hc2sgPSBjdHJsLT52YWw7Cj4gKwkJfSBlbHNl IHsKPiArCQkJZGV2X2VycihkZXYsICJTZWxlY3QgYXQgbGVhc3Qgb25lIG1vZGUhXG4iKTsKPiAr CQkJcmV0dXJuIC1FSU5WQUw7Cj4gKwkJfQo+ICsJCWJyZWFrOwoKVGhlIHRyYWRpdGlvbmFsIGFw cHJvYWNoIHRvIHNlbGVjdCB0aW1pbmcgc3RhbmRhcmRzIGlzIHRvIHVzZSBpb2N0bHMuCkhhbnMs IGRvIHlvdSB0aGluayBhIGN1c3RvbSBjb250cm9sIGlzIGZpbmUgaGVyZSwgb3Igc2hvdWxkIHRo ZSBkdgp0aW1pbmdzIGlvY3RscyBiZSBleHRlbmRlZCAob3IgbmV3IHNkaSB0aW1pbmdzIGlvY3Rs cyBjcmVhdGVkKSA/CgpJZiB3ZSBnbyBmb3IgYSBzaW5nbGUgY29udHJvbCwgSSdtIGEgYml0IGNv bmNlcm5lZCB0aGF0IHRoaXMgY29udHJvbAp3aWxsIHJlc3RyaWN0IHRoZSBzZWFyY2ggd2hlbiBt dWx0aXBsZSBiaXRzIGFyZSBzZXQsIGJ1dCBmb3JjZSBhCnNwZWNpZmljIG1vZGUgd2hlbiBhIHNp bmdsZSBiaXQgaXMgc2V0LiBJIGRvbid0IGhhdmUgZW5vdWdoIGV4cGVyaWVuY2UKd2l0aCBTREkg dG8gdGVsbCB3aGV0aGVyIHRoaXMgaXMgdGhlIHJpZ2h0IGJlaGF2aW91ci4KCj4gKwlkZWZhdWx0 Ogo+ICsJCXhzZGlyeHNzX3NldChjb3JlLCBYU0RJUlhfUlNUX0NUUkxfUkVHLAo+ICsJCQkgICAg IFhTRElSWF9SU1RfQ1RSTF9TU19FTl9NQVNLKTsKPiArCQlyZXR1cm4gLUVJTlZBTDsKClRoaXMg bG9va3Mgd2VpcmQuCgoJCXJldCA9IC1FSU5WQUw7CgkJYnJlYWs7Cgp3b3VsZCBiZSBiZXR0ZXIu Cgo+ICsJfQo+ICsJeHNkaXJ4X2NvcmVfZW5hYmxlKGNvcmUpOwoKRG8gd2UgcmVhbGx5IG5lZWQg dG8gZGlzYWJsZSBhbmQgcmVlbmFibGUgdGhlIGNvcmUgYXMgd2UncmUgZ3VhcmFudGVlZApub3Qg dG8gYmUgc3RyZWFtaW5nID8KCj4gKwlyZXR1cm4gcmV0Owo+ICt9Cj4gKwo+ICsvKioKPiArICog eHNkaXJ4c3NfZ192b2xhdGlsZV9jdHJsIC0gZ2V0IHRoZSBYaWxpbnggU0RJIFJ4IGNvbnRyb2xz Cj4gKyAqIEBjdHJsOiBQb2ludGVyIHRvIFY0TDIgY29udHJvbAo+ICsgKgo+ICsgKiBSZXR1cm46 IDAgb24gc3VjY2VzcywgZXJyb3JzIG90aGVyd2lzZQo+ICsgKi8KPiArc3RhdGljIGludCB4c2Rp cnhzc19nX3ZvbGF0aWxlX2N0cmwoc3RydWN0IHY0bDJfY3RybCAqY3RybCkKPiArewo+ICsJdTMy IHZhbDsKPiArCXN0cnVjdCB4c2Rpcnhzc19zdGF0ZSAqeHNkaXJ4c3MgPQo+ICsJCWNvbnRhaW5l cl9vZihjdHJsLT5oYW5kbGVyLAo+ICsJCQkgICAgIHN0cnVjdCB4c2Rpcnhzc19zdGF0ZSwgY3Ry bF9oYW5kbGVyKTsKPiArCXN0cnVjdCB4c2Rpcnhzc19jb3JlICpjb3JlID0gJnhzZGlyeHNzLT5j b3JlOwo+ICsJc3RydWN0IGRldmljZSAqZGV2ID0gY29yZS0+ZGV2Owo+ICsKPiArCXN3aXRjaCAo Y3RybC0+aWQpIHsKPiArCWNhc2UgVjRMMl9DSURfWElMSU5YX1NESVJYX01PREVfREVURUNUOgo+ ICsJCWlmICgheHNkaXJ4c3MtPnZpZGxvY2tlZCkgewo+ICsJCQlkZXZfZXJyKGRldiwgIkNhbid0 IGdldCB2YWx1ZXMgd2hlbiB2aWRlbyBub3QgbG9ja2VkIVxuIik7Cj4gKwkJCXJldHVybiAtRUlO VkFMOwo+ICsJCX0KPiArCQl2YWwgPSB4c2Rpcnhzc19yZWFkKGNvcmUsIFhTRElSWF9NT0RFX0RF VF9TVEFUX1JFRyk7Cj4gKwkJdmFsICY9IFhTRElSWF9NT0RFX0RFVF9TVEFUX1JYX01PREVfTUFT SzsKPiArCj4gKwkJc3dpdGNoICh2YWwpIHsKPiArCQljYXNlIFhTRElSWF9NT0RFX1NEX01BU0s6 Cj4gKwkJCWN0cmwtPnZhbCA9IFhTRElSWF9NT0RFX1NEX09GRlNFVDsKPiArCQkJYnJlYWs7Cj4g KwkJY2FzZSBYU0RJUlhfTU9ERV9IRF9NQVNLOgo+ICsJCQljdHJsLT52YWwgPSBYU0RJUlhfTU9E RV9IRF9PRkZTRVQ7Cj4gKwkJCWJyZWFrOwo+ICsJCWNhc2UgWFNESVJYX01PREVfM0dfTUFTSzoK PiArCQkJY3RybC0+dmFsID0gWFNESVJYX01PREVfM0dfT0ZGU0VUOwo+ICsJCQlicmVhazsKPiAr CQljYXNlIFhTRElSWF9NT0RFXzZHX01BU0s6Cj4gKwkJCWN0cmwtPnZhbCA9IFhTRElSWF9NT0RF XzZHX09GRlNFVDsKPiArCQkJYnJlYWs7Cj4gKwkJY2FzZSBYU0RJUlhfTU9ERV8xMkdJX01BU0s6 Cj4gKwkJCWN0cmwtPnZhbCA9IFhTRElSWF9NT0RFXzEyR0lfT0ZGU0VUOwo+ICsJCQlicmVhazsK PiArCQljYXNlIFhTRElSWF9NT0RFXzEyR0ZfTUFTSzoKPiArCQkJY3RybC0+dmFsID0gWFNESVJY X01PREVfMTJHRl9PRkZTRVQ7Cj4gKwkJCWJyZWFrOwo+ICsJCX0KPiArCQlicmVhazsKCkhhbnMg Y29tbWVudGVkIHRoYXQgdGhlIGR2IHRpbWluZ3Mgc3RydWN0dXJlIHdpbGwgcmVwb3J0IHdoZXRo ZXIgdGhlCm1vZGUgaXMgaW50ZXJsYWNlZCwgSSB3b25kZXIgaWYgcmVwb3J0aW5nIHRoZSBTREkg bW9kZSBzaG91bGRuJ3QgZ28KdGhyb3VnaCB0aGF0IHN0cnVjdHVyZSB0b28uCgo+ICsJY2FzZSBW NEwyX0NJRF9YSUxJTlhfU0RJUlhfQ1JDOgo+ICsJCWN0cmwtPnZhbCA9IHhzZGlyeHNzX3JlYWQo Y29yZSwgWFNESVJYX0NSQ19FUlJDTlRfUkVHKTsKPiArCQl4c2Rpcnhzc193cml0ZShjb3JlLCBY U0RJUlhfQ1JDX0VSUkNOVF9SRUcsIDB4RkZGRik7Cj4gKwkJYnJlYWs7CgpBcmUgQ1JDIGVycm9y cyBjb21tb24gKGFuZCByZWNvdmVyYWJsZSksIG9yIGFyZSB0aGV5IHJhcmUgYW5kIGZhdGFsCmVy cm9ycyA/IEluIG90aGVyIHdvcmRzLCBkb2VzIHRoaXMgcmVwb3J0IGluZm9ybWF0aW9uIHRoYXQg d291bGQgYmUKY2xhc3NpZmllZCBhcyBsaW5rIHF1YWxpdHksIG9yIGZhdGFsIGVycm9ycyA/IElu IHRoZSBsYXRlciBjYXNlIEkgd29uZGVyCmlmIGFuIGV2ZW50IHdvdWxkbid0IG1ha2UgbW9yZSBz ZW5zZS4gSXQgY291bGQgYmUgcmVwb3J0ZWQgYXMgYW5vdGhlcgpiaXQgaW4gdGhlIG92ZXJmbG93 L3VuZGVyZmxvdyBldmVudC4KCj4gKwljYXNlIFY0TDJfQ0lEX1hJTElOWF9TRElSWF9FREhfRVJS Q05UOgo+ICsJCXZhbCA9IHhzZGlyeHNzX3JlYWQoY29yZSwgWFNESVJYX01PREVfREVUX1NUQVRf UkVHKTsKPiArCQl2YWwgJj0gWFNESVJYX01PREVfREVUX1NUQVRfUlhfTU9ERV9NQVNLOwo+ICsJ CWlmICh2YWwgPT0gWFNESVJYX01PREVfU0RfTUFTSykgewo+ICsJCQljdHJsLT52YWwgPSB4c2Rp cnhzc19yZWFkKGNvcmUsIFhTRElSWF9FREhfRVJSQ05UX1JFRyk7Cj4gKwkJfSBlbHNlIHsKPiAr CQkJZGV2X2RiZyhkZXYsICIlZCAtIG5vdCBpbiBTRCBtb2RlXG4iLCBjdHJsLT5pZCk7Cj4gKwkJ CXJldHVybiAtRUlOVkFMOwo+ICsJCX0KPiArCQlicmVhazsKCklmIG15IHVuZGVyc3RhbmRpbmcg b2YgdGhlIGRhdGFzaGVldCBpcyBjb3JyZWN0LCB0aGlzIHdpbGwgYmUgcmVzZXQgZm9yCmV2ZXJ5 IGZyYW1lLCByaWdodCA/IFJlcG9ydGluZyB0aGUgaW5mb3JtYXRpb24gdGhpcyB3YXkgaXMgdGh1 cyBxdWl0ZQpyYWN5LiBJc24ndCBpdCBiZXR0ZXIgdG8gc2VuZCBpdCB0aHJvdWdoIGFuIGV2ZW50 ID8KCj4gKwljYXNlIFY0TDJfQ0lEX1hJTElOWF9TRElSWF9FREhfU1RBVFVTOgo+ICsJCXZhbCA9 IHhzZGlyeHNzX3JlYWQoY29yZSwgWFNESVJYX01PREVfREVUX1NUQVRfUkVHKTsKPiArCQl2YWwg Jj0gWFNESVJYX01PREVfREVUX1NUQVRfUlhfTU9ERV9NQVNLOwo+ICsJCWlmICh2YWwgPT0gWFNE SVJYX01PREVfU0RfTUFTSykgewo+ICsJCQljdHJsLT52YWwgPSB4c2Rpcnhzc19yZWFkKGNvcmUs IFhTRElSWF9FREhfU1RBVF9SRUcpOwo+ICsJCX0gZWxzZSB7Cj4gKwkJCWRldl9kYmcoZGV2LCAi JWQgLSBub3QgaW4gU0QgbW9kZVxuIiwgY3RybC0+aWQpOwo+ICsJCQlyZXR1cm4gLUVJTlZBTDsK PiArCQl9Cj4gKwkJYnJlYWs7CgpTYW1lIGhlcmUsIHNlZW1zIHF1aXRlIHJhY3kuCgo+ICsJY2Fz ZSBWNEwyX0NJRF9YSUxJTlhfU0RJUlhfVFNfSVNfSU5URVJMQUNFRDoKPiArCQlpZiAoIXhzZGly eHNzLT52aWRsb2NrZWQpIHsKPiArCQkJZGV2X2VycihkZXYsICJDYW4ndCBnZXQgdmFsdWVzIHdo ZW4gdmlkZW8gbm90IGxvY2tlZCFcbiIpOwo+ICsJCQlyZXR1cm4gLUVJTlZBTDsKPiArCQl9Cj4g KwkJY3RybC0+dmFsID0geHNkaXJ4c3MtPnRzX2lzX2ludGVybGFjZWQ7Cj4gKwkJYnJlYWs7Cj4g KwljYXNlIFY0TDJfQ0lEX1hJTElOWF9TRElSWF9BQ1RJVkVfU1RSRUFNUzoKPiArCQlpZiAoIXhz ZGlyeHNzLT52aWRsb2NrZWQpIHsKPiArCQkJZGV2X2VycihkZXYsICJDYW4ndCBnZXQgdmFsdWVz IHdoZW4gdmlkZW8gbm90IGxvY2tlZCFcbiIpOwo+ICsJCQlyZXR1cm4gLUVJTlZBTDsKPiArCQl9 Cj4gKwkJdmFsID0geHNkaXJ4c3NfcmVhZChjb3JlLCBYU0RJUlhfTU9ERV9ERVRfU1RBVF9SRUcp Owo+ICsJCXZhbCAmPSBYU0RJUlhfTU9ERV9ERVRfU1RBVF9BQ1RfU1RSRUFNX01BU0s7Cj4gKwkJ dmFsID4+PSBYU0RJUlhfTU9ERV9ERVRfU1RBVF9BQ1RfU1RSRUFNX09GRlNFVDsKPiArCQljdHJs LT52YWwgPSAxIDw8IHZhbDsKPiArCQlicmVhazsKPiArCWNhc2UgVjRMMl9DSURfWElMSU5YX1NE SVJYX0lTXzNHQjoKPiArCQlpZiAoIXhzZGlyeHNzLT52aWRsb2NrZWQpIHsKPiArCQkJZGV2X2Vy cihkZXYsICJDYW4ndCBnZXQgdmFsdWVzIHdoZW4gdmlkZW8gbm90IGxvY2tlZCFcbiIpOwo+ICsJ CQlyZXR1cm4gLUVJTlZBTDsKPiArCQl9Cj4gKwkJdmFsID0geHNkaXJ4c3NfcmVhZChjb3JlLCBY U0RJUlhfTU9ERV9ERVRfU1RBVF9SRUcpOwo+ICsJCXZhbCAmPSBYU0RJUlhfTU9ERV9ERVRfU1RB VF9MVkxCXzNHX01BU0s7Cj4gKwkJY3RybC0+dmFsID0gdmFsID8gdHJ1ZSA6IGZhbHNlOwo+ICsJ CWJyZWFrOwoKU2hvdWxkbid0IHRoaXMgYWxzbyBnbyB0aHJvdWdoIERWIHRpbWluZ3MgPyBJZiBu b3QsIEkgdGhpbmsgaXQgc2hvdWxkIGF0CmxlYXN0IGJlIGNvbWJpbmVkIHdpdGggVjRMMl9DSURf WElMSU5YX1NESVJYX01PREVfREVURUNULgoKPiArCWRlZmF1bHQ6Cj4gKwkJZGV2X2VycihkZXYs ICJHZXQgSW52YWxpZCBjb250cm9sIGlkIDB4JTB4XG4iLCBjdHJsLT5pZCk7Cj4gKwkJcmV0dXJu IC1FSU5WQUw7Cj4gKwl9Cj4gKwlkZXZfZGJnKGRldiwgIkdldCBjdHJsIGlkID0gMHglMDh4IHZh bCA9IDB4JTA4eFxuIiwgY3RybC0+aWQsCj4gKwkJY3RybC0+dmFsKTsKCkkgd291bGQgZHJvcCB0 aGlzIGxpbmUuCgo+ICsJcmV0dXJuIDA7Cj4gK30KPiArCj4gKy8qKgo+ICsgKiB4c2Rpcnhzc19s b2dfc3RhdHVzIC0gTG9ncyB0aGUgc3RhdHVzIG9mIHRoZSBTREkgUnggU3Vic3lzdGVtCj4gKyAq IEBzZDogUG9pbnRlciB0byBWNEwyIHN1YmRldmljZSBzdHJ1Y3R1cmUKPiArICoKPiArICogVGhp cyBmdW5jdGlvbiBwcmludHMgdGhlIGN1cnJlbnQgc3RhdHVzIG9mIFhpbGlueCBTREkgUnggU3Vi c3lzdGVtCj4gKyAqCj4gKyAqIFJldHVybjogMCBvbiBzdWNjZXNzCj4gKyAqLwo+ICtzdGF0aWMg aW50IHhzZGlyeHNzX2xvZ19zdGF0dXMoc3RydWN0IHY0bDJfc3ViZGV2ICpzZCkKPiArewo+ICsJ c3RydWN0IHhzZGlyeHNzX3N0YXRlICp4c2RpcnhzcyA9IHRvX3hzZGlyeHNzc3RhdGUoc2QpOwo+ ICsJc3RydWN0IHhzZGlyeHNzX2NvcmUgKmNvcmUgPSAmeHNkaXJ4c3MtPmNvcmU7Cj4gKwl1MzIg aTsKPiArCj4gKwl2NGwyX2luZm8oc2QsICIqKioqKiBTREkgUnggc3Vic3lzdGVtIHJlZyBkdW1w IHN0YXJ0ICoqKioqXG4iKTsKPiArCWZvciAoaSA9IDA7IGkgPCAweDI4OyBpKyspIHsKClRoZXJl IGFyZSByZWdpc3RlcnMgaW4gdGhpcyByYW5nZSB0aGF0IGFyZSBub3QgZG9jdW1lbnRlZCBpbiB0 aGUKZGF0YXNoZWV0LiBJcyBpdCByZWFsbHkgc2FmZSB0byByZWFkIHRoZW0gPyBUaGVyZSBhcmUg YWxzbyByZWdpc3RlcnMKdGhhdCBhcmUgb2Ygbm8gcmVhbCBpbnRlcmVzdCBJIGJlbGlldmUgKElT UiBmb3IgaW5zdGFuY2UpLCBvciByZWdpc3RlcnMKdGhhdCBzZWVtcyB0byBtYXAgdG8gYSBGSUZP IChSWF9TVDM1Ml9EQVRBX0RTKikgd2hpY2ggbWF5IGNhdXNlIGlzc3VlCndoZW4gcmVhZCBhcyB0 aGUgSVJRIGhhbmRsZXIgZXh0cmFjdHMgZGF0YSBmcm9tIHRoZW0gKEkgY291bGQgYmUgd3JvbmcK aGVyZSB0aG91Z2gpLiBTaG91bGQgdGhpcyBiZSByZXN0cmljdGVkIHRvIGEgaGFuZGZ1bCBvZiBj YXJlZnVsbHkKc2VsZWN0ZWQgcmVnaXN0ZXJzID8gWW91IGNvdWxkIHRoZW4gYWxzbyBwcmludCB0 aGVpciBuYW1lIGluc3RlYWQgb2YKdGhlaXIgYWRkcmVzcywgdGhhdCB3b3VsZCBiZSBtb3JlIHJl YWRhYmxlLgoKPiArCQl1MzIgZGF0YTsKPiArCj4gKwkJZGF0YSA9IHhzZGlyeHNzX3JlYWQoY29y ZSwgaSAqIDQpOwo+ICsJCXY0bDJfaW5mbyhzZCwgIm9mZnNldCAweCUwOHggZGF0YSAweCUwOHhc biIsCj4gKwkJCSAgaSAqIDQsIGRhdGEpOwo+ICsJfQo+ICsJdjRsMl9pbmZvKHNkLCAiKioqKiog U0RJIFJ4IHN1YnN5c3RlbSByZWcgZHVtcCBlbmQgKioqKipcbiIpOwo+ICsJcmV0dXJuIDA7Cj4g K30KPiArCj4gKy8qKgo+ICsgKiB4c2Rpcnhzc19nX2ZyYW1lX2ludGVydmFsIC0gR2V0IHRoZSBm cmFtZSBpbnRlcnZhbAo+ICsgKiBAc2Q6IFY0TDIgU3ViIGRldmljZQo+ICsgKiBAZmk6IFBvaW50 ZXIgdG8gVjRsMiBTdWIgZGV2aWNlIGZyYW1lIGludGVydmFsIHN0cnVjdHVyZQo+ICsgKgo+ICsg KiBUaGlzIGZ1bmN0aW9uIGlzIHVzZWQgdG8gZ2V0IHRoZSBmcmFtZSBpbnRlcnZhbC4KPiArICog VGhlIGZyYW1lIHJhdGUgY2FuIGJlIGludGVncmFsIG9yIGZyYWN0aW9uYWwuCj4gKyAqIEludGVn cmFsIGZyYW1lIHJhdGUgZS5nLiBudW1lcmF0b3IgPSAxMDAwLCBkZW5vbWluYXRvciA9IDI0MDAw ID0+IDI0IGZwcwo+ICsgKiBGcmFjdGlvbmFsIGZyYW1lIHJhdGUgZS5nLiBudW1lcmF0b3IgPSAx MDAxLCBkZW5vbWluYXRvciA9IDI0MDAwID0+IDIzLjk3IGZwcwo+ICsgKgo+ICsgKiBSZXR1cm46 IDAgb24gc3VjY2Vzcwo+ICsgKi8KPiArc3RhdGljIGludCB4c2Rpcnhzc19nX2ZyYW1lX2ludGVy dmFsKHN0cnVjdCB2NGwyX3N1YmRldiAqc2QsCj4gKwkJCQkgICAgIHN0cnVjdCB2NGwyX3N1YmRl dl9mcmFtZV9pbnRlcnZhbCAqZmkpCj4gK3sKPiArCXN0cnVjdCB4c2Rpcnhzc19zdGF0ZSAqeHNk aXJ4c3MgPSB0b194c2Rpcnhzc3N0YXRlKHNkKTsKPiArCXN0cnVjdCB4c2Rpcnhzc19jb3JlICpj b3JlID0gJnhzZGlyeHNzLT5jb3JlOwo+ICsKPiArCWlmICgheHNkaXJ4c3MtPnZpZGxvY2tlZCkg ewo+ICsJCWRldl9lcnIoY29yZS0+ZGV2LCAiVmlkZW8gbm90IGxvY2tlZCFcbiIpOwo+ICsJCXJl dHVybiAtRUlOVkFMOwo+ICsJfQo+ICsKPiArCWZpLT5pbnRlcnZhbCA9IHhzZGlyeHNzLT5mcmFt ZV9pbnRlcnZhbDsKClRoZXJlJ3MgYSBkYXRhIHJhY2Ugd2l0aCB0aGUgaW50ZXJydXB0IGhhbmRs ZXIgaGVyZS4KCj4gKwo+ICsJZGV2X2RiZyhjb3JlLT5kZXYsICJmcmFtZSByYXRlIG51bWVyYXRv ciA9ICVkIGRlbm9taW5hdG9yID0gJWRcbiIsCj4gKwkJeHNkaXJ4c3MtPmZyYW1lX2ludGVydmFs Lm51bWVyYXRvciwKPiArCQl4c2Rpcnhzcy0+ZnJhbWVfaW50ZXJ2YWwuZGVub21pbmF0b3IpOwo+ ICsJcmV0dXJuIDA7Cj4gK30KPiArCj4gKy8qKgo+ICsgKiB4c2Rpcnhzc19zX3N0cmVhbSAtIEl0 IGlzIHVzZWQgdG8gc3RhcnQvc3RvcCB0aGUgc3RyZWFtaW5nLgo+ICsgKiBAc2Q6IFY0TDIgU3Vi IGRldmljZQo+ICsgKiBAZW5hYmxlOiBGbGFnIChUcnVlIC8gRmFsc2UpCj4gKyAqCj4gKyAqIFRo aXMgZnVuY3Rpb24gY29udHJvbHMgdGhlIHN0YXJ0IG9yIHN0b3Agb2Ygc3RyZWFtaW5nIGZvciB0 aGUKPiArICogWGlsaW54IFNESSBSeCBTdWJzeXN0ZW0uCj4gKyAqCj4gKyAqIFJldHVybjogMCBv biBzdWNjZXNzLCBlcnJvcnMgb3RoZXJ3aXNlCj4gKyAqLwo+ICtzdGF0aWMgaW50IHhzZGlyeHNz X3Nfc3RyZWFtKHN0cnVjdCB2NGwyX3N1YmRldiAqc2QsIGludCBlbmFibGUpCj4gK3sKPiArCXN0 cnVjdCB4c2Rpcnhzc19zdGF0ZSAqeHNkaXJ4c3MgPSB0b194c2Rpcnhzc3N0YXRlKHNkKTsKPiAr CXN0cnVjdCB4c2Rpcnhzc19jb3JlICpjb3JlID0gJnhzZGlyeHNzLT5jb3JlOwo+ICsJc3RydWN0 IGRldmljZSAqZGV2ID0gY29yZS0+ZGV2Owo+ICsKCk1heWJlCgoJaWYgKGVuYWJsZSA9PSB4c2Rp cnhzcy0+c3RyZWFtaW5nKSB7CgkJZGV2X2RiZyguLi4pOwoJCXJldHVybiBlbmFibGUgPyAtRUlO VkFMIDogMDsKCX0KCj8gVXAgdG8geW91LgoKPiArCWlmIChlbmFibGUpIHsKPiArCQlpZiAoIXhz ZGlyeHNzLT52aWRsb2NrZWQpIHsKPiArCQkJZGV2X2RiZyhkZXYsICJWaWRlbyBpcyBub3QgbG9j a2VkXG4iKTsKPiArCQkJcmV0dXJuIC1FSU5WQUw7Cj4gKwkJfQo+ICsJCWlmICh4c2Rpcnhzcy0+ c3RyZWFtaW5nKSB7Cj4gKwkJCWRldl9kYmcoZGV2LCAiQWxyZWFkeSBzdHJlYW1pbmdcbiIpOwo+ ICsJCQlyZXR1cm4gLUVJTlZBTDsKPiArCQl9Cj4gKwo+ICsJCXhzZGlyeF9zdHJlYW1mbG93X2Nv bnRyb2woY29yZSwgdHJ1ZSk7Cj4gKwkJeHNkaXJ4c3MtPnN0cmVhbWluZyA9IHRydWU7Cj4gKwkJ ZGV2X2RiZyhkZXYsICJTdHJlYW1pbmcgc3RhcnRlZFxuIik7Cj4gKwl9IGVsc2Ugewo+ICsJCWlm ICgheHNkaXJ4c3MtPnN0cmVhbWluZykgewo+ICsJCQlkZXZfZGJnKGRldiwgIlN0b3BwZWQgc3Ry ZWFtaW5nIGFscmVhZHlcbiIpOwo+ICsJCQlyZXR1cm4gMDsKPiArCQl9Cj4gKwo+ICsJCXhzZGly eF9zdHJlYW1mbG93X2NvbnRyb2woY29yZSwgZmFsc2UpOwo+ICsJCXhzZGlyeHNzLT5zdHJlYW1p bmcgPSBmYWxzZTsKPiArCQlkZXZfZGJnKGRldiwgIlN0cmVhbWluZyBzdG9wcGVkXG4iKTsKPiAr CX0KPiArCgpBbmQgcG9zc2libHkKCgl4c2Rpcnhzcy0+c3RyZWFtaW5nID0gZW5hYmxlOwoJZGV2 X2RiZyhkZXYsICJTdHJlYW1pbmcgJXNcIiwgZW5hYmxlID8gInN0YXJ0ZWQiIDogInN0b3BwZWQi KTsKCj4gKwlyZXR1cm4gMDsKPiArfQo+ICsKPiArLyoqCj4gKyAqIHhzZGlyeHNzX2dfaW5wdXRf c3RhdHVzIC0gSXQgaXMgdXNlZCB0byBkZXRlcm1pbmUgaWYgdGhlIHZpZGVvIHNpZ25hbAo+ICsg KiBpcyBwcmVzZW50IC8gbG9ja2VkIG9udG8gb3Igbm90Lgo+ICsgKgo+ICsgKiBAc2Q6IFY0TDIg U3ViIGRldmljZQo+ICsgKiBAc3RhdHVzOiBzdGF0dXMgb2Ygc2lnbmFsIGxvY2tlZAo+ICsgKgo+ ICsgKiBUaGlzIGlzIHVzZWQgdG8gZGV0ZXJtaW5lIGlmIHRoZSB2aWRlbyBzaWduYWwgaXMgcHJl c2VudCBhbmQgbG9ja2VkIG9udG8KPiArICogYnkgdGhlIFNESSBSeCBjb3JlIG9yIG5vdCBiYXNl ZCBvbiB2aWRsb2NrZWQgZmxhZy4KPiArICoKPiArICogUmV0dXJuOiB6ZXJvIG9uIHN1Y2Nlc3MK PiArICovCj4gK3N0YXRpYyBpbnQgeHNkaXJ4c3NfZ19pbnB1dF9zdGF0dXMoc3RydWN0IHY0bDJf c3ViZGV2ICpzZCwgdTMyICpzdGF0dXMpCj4gK3sKPiArCXN0cnVjdCB4c2Rpcnhzc19zdGF0ZSAq eHNkaXJ4c3MgPSB0b194c2Rpcnhzc3N0YXRlKHNkKTsKPiArCj4gKwlpZiAoIXhzZGlyeHNzLT52 aWRsb2NrZWQpCj4gKwkJKnN0YXR1cyA9IFY0TDJfSU5fU1RfTk9fU1lOQyB8IFY0TDJfSU5fU1Rf Tk9fU0lHTkFMOwo+ICsJZWxzZQo+ICsJCSpzdGF0dXMgPSAwOwo+ICsKPiArCXJldHVybiAwOwo+ ICt9Cj4gKwo+ICtzdGF0aWMgc3RydWN0IHY0bDJfbWJ1c19mcmFtZWZtdCAqCj4gK19feHNkaXJ4 c3NfZ2V0X3BhZF9mb3JtYXQoc3RydWN0IHhzZGlyeHNzX3N0YXRlICp4c2RpcnhzcywKPiArCQkJ ICBzdHJ1Y3QgdjRsMl9zdWJkZXZfcGFkX2NvbmZpZyAqY2ZnLAo+ICsJCQkgIHVuc2lnbmVkIGlu dCBwYWQsIHUzMiB3aGljaCkKPiArewo+ICsJc3dpdGNoICh3aGljaCkgewo+ICsJY2FzZSBWNEwy X1NVQkRFVl9GT1JNQVRfVFJZOgo+ICsJCXJldHVybiB2NGwyX3N1YmRldl9nZXRfdHJ5X2Zvcm1h dCgmeHNkaXJ4c3MtPnN1YmRldiwgY2ZnLCBwYWQpOwo+ICsJY2FzZSBWNEwyX1NVQkRFVl9GT1JN QVRfQUNUSVZFOgo+ICsJCXJldHVybiAmeHNkaXJ4c3MtPmZvcm1hdDsKPiArCWRlZmF1bHQ6Cj4g KwkJcmV0dXJuIE5VTEw7Cj4gKwl9Cj4gK30KPiArCj4gKy8qKgo+ICsgKiB4c2Rpcnhzc19pbml0 X2NmZyAtIEluaXRpYWxpc2UgdGhlIHBhZCBmb3JtYXQgY29uZmlnIHRvIGRlZmF1bHQKPiArICog QHNkOiBQb2ludGVyIHRvIFY0TDIgU3ViIGRldmljZSBzdHJ1Y3R1cmUKPiArICogQGNmZzogUG9p bnRlciB0byBzdWIgZGV2aWNlIHBhZCBpbmZvcm1hdGlvbiBzdHJ1Y3R1cmUKPiArICoKPiArICog VGhpcyBmdW5jdGlvbiBpcyB1c2VkIHRvIGluaXRpYWxpemUgdGhlIHBhZCBmb3JtYXQgd2l0aCB0 aGUgZGVmYXVsdAo+ICsgKiB2YWx1ZXMuCj4gKyAqCj4gKyAqIFJldHVybjogMCBvbiBzdWNjZXNz Cj4gKyAqLwo+ICtzdGF0aWMgaW50IHhzZGlyeHNzX2luaXRfY2ZnKHN0cnVjdCB2NGwyX3N1YmRl diAqc2QsCj4gKwkJCSAgICAgc3RydWN0IHY0bDJfc3ViZGV2X3BhZF9jb25maWcgKmNmZykKPiAr ewo+ICsJc3RydWN0IHhzZGlyeHNzX3N0YXRlICp4c2RpcnhzcyA9IHRvX3hzZGlyeHNzc3RhdGUo c2QpOwo+ICsJc3RydWN0IHY0bDJfbWJ1c19mcmFtZWZtdCAqZm9ybWF0Owo+ICsKPiArCWZvcm1h dCA9IHY0bDJfc3ViZGV2X2dldF90cnlfZm9ybWF0KHNkLCBjZmcsIDApOwo+ICsJKmZvcm1hdCA9 IHhzZGlyeHNzLT5kZWZhdWx0X2Zvcm1hdDsKPiArCj4gKwlyZXR1cm4gMDsKPiArfQo+ICsKPiAr LyoqCj4gKyAqIHhzZGlyeHNzX2dldF9mb3JtYXQgLSBHZXQgdGhlIHBhZCBmb3JtYXQKPiArICog QHNkOiBQb2ludGVyIHRvIFY0TDIgU3ViIGRldmljZSBzdHJ1Y3R1cmUKPiArICogQGNmZzogUG9p bnRlciB0byBzdWIgZGV2aWNlIHBhZCBpbmZvcm1hdGlvbiBzdHJ1Y3R1cmUKPiArICogQGZtdDog UG9pbnRlciB0byBwYWQgbGV2ZWwgbWVkaWEgYnVzIGZvcm1hdAo+ICsgKgo+ICsgKiBUaGlzIGZ1 bmN0aW9uIGlzIHVzZWQgdG8gZ2V0IHRoZSBwYWQgZm9ybWF0IGluZm9ybWF0aW9uLgo+ICsgKgo+ ICsgKiBSZXR1cm46IDAgb24gc3VjY2Vzcwo+ICsgKi8KPiArc3RhdGljIGludCB4c2Rpcnhzc19n ZXRfZm9ybWF0KHN0cnVjdCB2NGwyX3N1YmRldiAqc2QsCj4gKwkJCSAgICAgICBzdHJ1Y3QgdjRs Ml9zdWJkZXZfcGFkX2NvbmZpZyAqY2ZnLAo+ICsJCQkgICAgICAgc3RydWN0IHY0bDJfc3ViZGV2 X2Zvcm1hdCAqZm10KQo+ICt7Cj4gKwlzdHJ1Y3QgeHNkaXJ4c3Nfc3RhdGUgKnhzZGlyeHNzID0g dG9feHNkaXJ4c3NzdGF0ZShzZCk7Cj4gKwlzdHJ1Y3QgeHNkaXJ4c3NfY29yZSAqY29yZSA9ICZ4 c2Rpcnhzcy0+Y29yZTsKPiArCj4gKwlpZiAoIXhzZGlyeHNzLT52aWRsb2NrZWQpIHsKPiArCQlk ZXZfZXJyKGNvcmUtPmRldiwgIlZpZGVvIG5vdCBsb2NrZWQhXG4iKTsKPiArCQlyZXR1cm4gLUVJ TlZBTDsKPiArCX0KPiArCj4gKwlmbXQtPmZvcm1hdCA9ICpfX3hzZGlyeHNzX2dldF9wYWRfZm9y bWF0KHhzZGlyeHNzLCBjZmcsCj4gKwkJCQkJCSBmbXQtPnBhZCwgZm10LT53aGljaCk7Cj4gKwo+ ICsJZGV2X2RiZyhjb3JlLT5kZXYsICJTdHJlYW0gd2lkdGggPSAlZCBoZWlnaHQgPSAlZCBGaWVs ZCA9ICVkXG4iLAo+ICsJCWZtdC0+Zm9ybWF0LndpZHRoLCBmbXQtPmZvcm1hdC5oZWlnaHQsIGZt dC0+Zm9ybWF0LmZpZWxkKTsKPiArCj4gKwlyZXR1cm4gMDsKPiArfQo+ICsKPiArLyoqCj4gKyAq IHhzZGlyeHNzX3NldF9mb3JtYXQgLSBUaGlzIGlzIHVzZWQgdG8gc2V0IHRoZSBwYWQgZm9ybWF0 Cj4gKyAqIEBzZDogUG9pbnRlciB0byBWNEwyIFN1YiBkZXZpY2Ugc3RydWN0dXJlCj4gKyAqIEBj Zmc6IFBvaW50ZXIgdG8gc3ViIGRldmljZSBwYWQgaW5mb3JtYXRpb24gc3RydWN0dXJlCj4gKyAq IEBmbXQ6IFBvaW50ZXIgdG8gcGFkIGxldmVsIG1lZGlhIGJ1cyBmb3JtYXQKPiArICoKPiArICog VGhpcyBmdW5jdGlvbiBpcyB1c2VkIHRvIHNldCB0aGUgcGFkIGZvcm1hdC4KPiArICogU2luY2Ug dGhlIHBhZCBmb3JtYXQgaXMgZml4ZWQgaW4gaGFyZHdhcmUsIGl0IGNhbid0IGJlCj4gKyAqIG1v ZGlmaWVkIG9uIHJ1biB0aW1lLgo+ICsgKgo+ICsgKiBSZXR1cm46IDAgb24gc3VjY2Vzcwo+ICsg Ki8KPiArc3RhdGljIGludCB4c2Rpcnhzc19zZXRfZm9ybWF0KHN0cnVjdCB2NGwyX3N1YmRldiAq c2QsCj4gKwkJCSAgICAgICBzdHJ1Y3QgdjRsMl9zdWJkZXZfcGFkX2NvbmZpZyAqY2ZnLAo+ICsJ CQkgICAgICAgc3RydWN0IHY0bDJfc3ViZGV2X2Zvcm1hdCAqZm10KQo+ICt7Cj4gKwlzdHJ1Y3Qg djRsMl9tYnVzX2ZyYW1lZm10ICpfX2Zvcm1hdDsKPiArCXN0cnVjdCB4c2Rpcnhzc19zdGF0ZSAq eHNkaXJ4c3MgPSB0b194c2Rpcnhzc3N0YXRlKHNkKTsKPiArCj4gKwlkZXZfZGJnKHhzZGlyeHNz LT5jb3JlLmRldiwKPiArCQkic2V0IHdpZHRoICVkIGhlaWdodCAlZCBjb2RlICVkIGZpZWxkICVk IGNvbG9yc3BhY2UgJWRcbiIsCj4gKwkJZm10LT5mb3JtYXQud2lkdGgsIGZtdC0+Zm9ybWF0Lmhl aWdodCwKPiArCQlmbXQtPmZvcm1hdC5jb2RlLCBmbXQtPmZvcm1hdC5maWVsZCwKPiArCQlmbXQt PmZvcm1hdC5jb2xvcnNwYWNlKTsKPiArCj4gKwlfX2Zvcm1hdCA9IF9feHNkaXJ4c3NfZ2V0X3Bh ZF9mb3JtYXQoeHNkaXJ4c3MsIGNmZywKPiArCQkJCQkgICAgIGZtdC0+cGFkLCBmbXQtPndoaWNo KTsKPiArCj4gKwkvKiBDdXJyZW50bHkgcmVzZXQgdGhlIGNvZGUgdG8gb25lIGZpeGVkIGluIGhh cmR3YXJlICovCj4gKwkvKiBUT0RPIDogQWRkIGNoZWNrcyBmb3Igd2lkdGggaGVpZ2h0ICovCj4g KwlmbXQtPmZvcm1hdC5jb2RlID0gX19mb3JtYXQtPmNvZGU7CgpBcyBIYW5zIHJlcXVlc3RlZCwg d2lkdGgsIGhlaWdodCBhbmQgZmllbGQgc2hvdWxkIGJlIHNldCBoZXJlIHRvbywgYW5kCnByb2Jh Ymx5IGNvbG9yc3BhY2UgaW5mb3JtYXRpb24gdG9vLgoKPiArCj4gKwlyZXR1cm4gMDsKPiArfQo+ ICsKPiArLyoqCj4gKyAqIHhzZGlyeHNzX2VudW1fbWJ1c19jb2RlIC0gSGFuZGxlIHBpeGVsIGZv cm1hdCBlbnVtZXJhdGlvbgo+ICsgKiBAc2Q6IHBvaW50ZXIgdG8gdjRsMiBzdWJkZXYgc3RydWN0 dXJlCj4gKyAqIEBjZmc6IFY0TDIgc3ViZGV2IHBhZCBjb25maWd1cmF0aW9uCj4gKyAqIEBjb2Rl OiBwb2ludGVyIHRvIHY0bDJfc3ViZGV2X21idXNfY29kZV9lbnVtIHN0cnVjdHVyZQo+ICsgKgo+ ICsgKiBSZXR1cm46IC1FSU5WQUwgb3IgemVybyBvbiBzdWNjZXNzCj4gKyAqLwo+ICtzdGF0aWMg aW50IHhzZGlyeHNzX2VudW1fbWJ1c19jb2RlKHN0cnVjdCB2NGwyX3N1YmRldiAqc2QsCj4gKwkJ CQkgICBzdHJ1Y3QgdjRsMl9zdWJkZXZfcGFkX2NvbmZpZyAqY2ZnLAo+ICsJCQkJICAgc3RydWN0 IHY0bDJfc3ViZGV2X21idXNfY29kZV9lbnVtICpjb2RlKQo+ICt7Cj4gKwlzdHJ1Y3QgeHNkaXJ4 c3Nfc3RhdGUgKnhzZGlyeHNzID0gdG9feHNkaXJ4c3NzdGF0ZShzZCk7Cj4gKwl1MzIgaW5kZXgg PSBjb2RlLT5pbmRleDsKPiArCXUzMiBtYXhpbmRleDsKPiArCj4gKwlpZiAoeHNkaXJ4c3MtPmNv cmUuYnBjID09IDEwKQo+ICsJCW1heGluZGV4ID0gQVJSQVlfU0laRSh4c2Rpcnhzc18xMGJwY19t YnVzX2ZtdHMpOwo+ICsJZWxzZQo+ICsJCW1heGluZGV4ID0gQVJSQVlfU0laRSh4c2Rpcnhzc18x MmJwY19tYnVzX2ZtdHMpOwo+ICsKPiArCWlmIChjb2RlLT5wYWQgfHwgaW5kZXggPj0gbWF4aW5k ZXgpCj4gKwkJcmV0dXJuIC1FSU5WQUw7Cj4gKwo+ICsJaWYgKHhzZGlyeHNzLT5jb3JlLmJwYyA9 PSAxMCkKPiArCQljb2RlLT5jb2RlID0geHNkaXJ4c3NfMTBicGNfbWJ1c19mbXRzW2luZGV4XTsK PiArCWVsc2UKPiArCQljb2RlLT5jb2RlID0geHNkaXJ4c3NfMTJicGNfbWJ1c19mbXRzW2luZGV4 XTsKPiArCj4gKwlyZXR1cm4gMDsKPiArfQo+ICsKPiArLyoqCj4gKyAqIHhzZGlyeHNzX2VudW1f ZHZfdGltaW5nczogRW51bWVyYXRlIGFsbCB0aGUgc3VwcG9ydGVkIERWIHRpbWluZ3MKPiArICog QHNkOiBwb2ludGVyIHRvIHY0bDIgc3ViZGV2IHN0cnVjdHVyZQo+ICsgKiBAdGltaW5nczogRFYg dGltaW5ncyBzdHJ1Y3R1cmUgdG8gYmUgcmV0dXJuZWQuCj4gKyAqCj4gKyAqIFJldHVybjogLUVJ TlZBTCBpbmNhc2Ugb2YgaW52YWxpZCBpbmRleCBhbmQgcGFkIG9yIHplcm8gb24gc3VjY2Vzcwo+ ICsgKi8KPiArc3RhdGljIGludCB4c2Rpcnhzc19lbnVtX2R2X3RpbWluZ3Moc3RydWN0IHY0bDJf c3ViZGV2ICpzZCwKPiArCQkJCSAgICBzdHJ1Y3QgdjRsMl9lbnVtX2R2X3RpbWluZ3MgKnRpbWlu Z3MpCj4gK3sKPiArCWlmICh0aW1pbmdzLT5pbmRleCA+PSBBUlJBWV9TSVpFKGZtdF9jYXApKQo+ ICsJCXJldHVybiAtRUlOVkFMOwo+ICsKPiArCWlmICh0aW1pbmdzLT5wYWQgIT0gMCkKPiArCQly ZXR1cm4gLUVJTlZBTDsKPiArCj4gKwl0aW1pbmdzLT50aW1pbmdzID0gZm10X2NhcFt0aW1pbmdz LT5pbmRleF07Cj4gKwlyZXR1cm4gMDsKPiArfQo+ICsKPiArLyoqCj4gKyAqIHhzZGlyeHNzX3F1 ZXJ5X2R2X3RpbWluZ3M6IFF1ZXJ5IGZvciB0aGUgY3VycmVudCBEViB0aW1pbmdzCj4gKyAqIEBz ZDogcG9pbnRlciB0byB2NGwyIHN1YmRldiBzdHJ1Y3R1cmUKPiArICogQHRpbWluZ3M6IERWIHRp bWluZ3Mgc3RydWN0dXJlIHRvIGJlIHJldHVybmVkLgo+ICsgKgo+ICsgKiBSZXR1cm46IC1FTk9M Q0sgd2hlbiB2aWRlbyBpcyBub3QgbG9ja2VkLCAtRVJBTkdFIHdoZW4gY29ycmVzcG9uZGluZyB0 aW1pbmcKPiArICogZW50cnkgaXMgbm90IGZvdW5kIG9yIHplcm8gb24gc3VjY2Vzcy4KPiArICov Cj4gK3N0YXRpYyBpbnQgeHNkaXJ4c3NfcXVlcnlfZHZfdGltaW5ncyhzdHJ1Y3QgdjRsMl9zdWJk ZXYgKnNkLAo+ICsJCQkJICAgICBzdHJ1Y3QgdjRsMl9kdl90aW1pbmdzICp0aW1pbmdzKQo+ICt7 Cj4gKwlzdHJ1Y3QgeHNkaXJ4c3Nfc3RhdGUgKnN0YXRlID0gdG9feHNkaXJ4c3NzdGF0ZShzZCk7 Cj4gKwl1bnNpZ25lZCBpbnQgaTsKPiArCj4gKwlpZiAoIXN0YXRlLT52aWRsb2NrZWQpCj4gKwkJ cmV0dXJuIC1FTk9MQ0s7Cj4gKwo+ICsJZm9yIChpID0gMDsgaSA8IEFSUkFZX1NJWkUoeHNkaXJ4 c3NfZHZfdGltaW5ncyk7IGkrKykgewo+ICsJCWlmIChzdGF0ZS0+Zm9ybWF0LndpZHRoID09IHhz ZGlyeHNzX2R2X3RpbWluZ3NbaV0ud2lkdGggJiYKPiArCQkgICAgc3RhdGUtPmZvcm1hdC5oZWln aHQgPT0geHNkaXJ4c3NfZHZfdGltaW5nc1tpXS5oZWlnaHQgJiYKPiArCQkgICAgc3RhdGUtPmZy YW1lX2ludGVydmFsLmRlbm9taW5hdG9yID09Cj4gKwkJICAgICh4c2Rpcnhzc19kdl90aW1pbmdz W2ldLmZwcyAqIDEwMDApKSB7Cj4gKwkJCSp0aW1pbmdzID0geHNkaXJ4c3NfZHZfdGltaW5nc1tp XS5mb3JtYXQ7Cj4gKwkJCXJldHVybiAwOwo+ICsJCX0KPiArCX0KPiArCj4gKwlyZXR1cm4gLUVS QU5HRTsKPiArfQo+ICsKPiArLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KPiArICogTWVkaWEgT3Bl cmF0aW9ucwo+ICsgKi8KPiArCj4gK3N0YXRpYyBjb25zdCBzdHJ1Y3QgbWVkaWFfZW50aXR5X29w ZXJhdGlvbnMgeHNkaXJ4c3NfbWVkaWFfb3BzID0gewo+ICsJLmxpbmtfdmFsaWRhdGUgPSB2NGwy X3N1YmRldl9saW5rX3ZhbGlkYXRlCj4gK307Cj4gKwo+ICtzdGF0aWMgY29uc3Qgc3RydWN0IHY0 bDJfY3RybF9vcHMgeHNkaXJ4c3NfY3RybF9vcHMgPSB7Cj4gKwkuZ192b2xhdGlsZV9jdHJsID0g eHNkaXJ4c3NfZ192b2xhdGlsZV9jdHJsLAo+ICsJLnNfY3RybAk9IHhzZGlyeHNzX3NfY3RybAo+ ICt9Owo+ICsKPiArc3RhdGljIGNvbnN0IHN0cnVjdCB2NGwyX2N0cmxfY29uZmlnIHhzZGlyeHNz X2VkaF9jdHJsc1tdID0gewo+ICsJewo+ICsJCS5vcHMJPSAmeHNkaXJ4c3NfY3RybF9vcHMsCj4g KwkJLmlkCT0gVjRMMl9DSURfWElMSU5YX1NESVJYX0VESF9FUlJDTlRfRU5BQkxFLAo+ICsJCS5u YW1lCT0gIlNESSBSeCA6IEVESCBFcnJvciBDb3VudCBFbmFibGUiLAo+ICsJCS50eXBlCT0gVjRM Ml9DVFJMX1RZUEVfQklUTUFTSywKPiArCQkubWluCT0gMCwKPiArCQkubWF4CT0gWFNESVJYX0VE SF9BTExFUlJfTUFTSywKPiArCQkuZGVmCT0gMCwKPiArCX0sIHsKPiArCQkub3BzCT0gJnhzZGly eHNzX2N0cmxfb3BzLAo+ICsJCS5pZAk9IFY0TDJfQ0lEX1hJTElOWF9TRElSWF9FREhfRVJSQ05U LAo+ICsJCS5uYW1lCT0gIlNESSBSeCA6IEVESCBFcnJvciBDb3VudCIsCj4gKwkJLnR5cGUJPSBW NEwyX0NUUkxfVFlQRV9JTlRFR0VSLAo+ICsJCS5taW4JPSAwLAo+ICsJCS5tYXgJPSAweEZGRkYs Cj4gKwkJLnN0ZXAJPSAxLAo+ICsJCS5kZWYJPSAwLAo+ICsJCS5mbGFncyAgPSBWNEwyX0NUUkxf RkxBR19WT0xBVElMRSB8IFY0TDJfQ1RSTF9GTEFHX1JFQURfT05MWSwKPiArCX0sIHsKPiArCQku b3BzCT0gJnhzZGlyeHNzX2N0cmxfb3BzLAo+ICsJCS5pZAk9IFY0TDJfQ0lEX1hJTElOWF9TRElS WF9FREhfU1RBVFVTLAo+ICsJCS5uYW1lCT0gIlNESSBSeCA6IEVESCBTdGF0dXMiLAo+ICsJCS50 eXBlCT0gVjRMMl9DVFJMX1RZUEVfSU5URUdFUiwKPiArCQkubWluCT0gMCwKPiArCQkubWF4CT0g MHhGRkZGRkZGRiwKPiArCQkuc3RlcAk9IDEsCj4gKwkJLmRlZgk9IDAsCj4gKwkJLmZsYWdzICA9 IFY0TDJfQ1RSTF9GTEFHX1ZPTEFUSUxFIHwgVjRMMl9DVFJMX0ZMQUdfUkVBRF9PTkxZLAo+ICsJ fQo+ICt9Owo+ICsKPiArc3RhdGljIGNvbnN0IHN0cnVjdCB2NGwyX2N0cmxfY29uZmlnIHhzZGly eHNzX2N0cmxzW10gPSB7Cj4gKwl7Cj4gKwkJLm9wcwk9ICZ4c2Rpcnhzc19jdHJsX29wcywKPiAr CQkuaWQJPSBWNEwyX0NJRF9YSUxJTlhfU0RJUlhfRlJBTUVSLAo+ICsJCS5uYW1lCT0gIlNESSBS eCA6IEVuYWJsZSBGcmFtZXIiLAo+ICsJCS50eXBlCT0gVjRMMl9DVFJMX1RZUEVfQk9PTEVBTiwK PiArCQkubWluCT0gZmFsc2UsCj4gKwkJLm1heAk9IHRydWUsCj4gKwkJLnN0ZXAJPSAxLAo+ICsJ CS5kZWYJPSB0cnVlLAo+ICsJfSwgewo+ICsJCS5vcHMJPSAmeHNkaXJ4c3NfY3RybF9vcHMsCj4g KwkJLmlkCT0gVjRMMl9DSURfWElMSU5YX1NESVJYX1ZJRExPQ0tfV0lORE9XLAo+ICsJCS5uYW1l CT0gIlNESSBSeCA6IFZpZGVvIExvY2sgV2luZG93IiwKPiArCQkudHlwZQk9IFY0TDJfQ1RSTF9U WVBFX0lOVEVHRVIsCj4gKwkJLm1pbgk9IDAsCj4gKwkJLm1heAk9IDB4RkZGRkZGRkYsCj4gKwkJ LnN0ZXAJPSAxLAo+ICsJCS5kZWYJPSBYU0RJUlhfREVGQVVMVF9WSURFT19MT0NLX1dJTkRPVywK PiArCX0sIHsKPiArCQkub3BzCT0gJnhzZGlyeHNzX2N0cmxfb3BzLAo+ICsJCS5pZAk9IFY0TDJf Q0lEX1hJTElOWF9TRElSWF9TRUFSQ0hfTU9ERVMsCj4gKwkJLm5hbWUJPSAiU0RJIFJ4IDogTW9k ZXMgc2VhcmNoIE1hc2siLAo+ICsJCS50eXBlCT0gVjRMMl9DVFJMX1RZUEVfQklUTUFTSywKPiAr CQkubWluCT0gMCwKPiArCQkubWF4CT0gWFNESVJYX0RFVEVDVF9BTExfTU9ERVMsCj4gKwkJLmRl Zgk9IFhTRElSWF9ERVRFQ1RfQUxMX01PREVTLAo+ICsJfSwgewo+ICsJCS5vcHMJPSAmeHNkaXJ4 c3NfY3RybF9vcHMsCj4gKwkJLmlkCT0gVjRMMl9DSURfWElMSU5YX1NESVJYX01PREVfREVURUNU LAo+ICsJCS5uYW1lCT0gIlNESSBSeCA6IE1vZGUgRGV0ZWN0IFN0YXR1cyIsCj4gKwkJLnR5cGUJ PSBWNEwyX0NUUkxfVFlQRV9JTlRFR0VSLAo+ICsJCS5taW4JPSBYU0RJUlhfTU9ERV9TRF9PRkZT RVQsCj4gKwkJLm1heAk9IFhTRElSWF9NT0RFXzEyR0ZfT0ZGU0VULAo+ICsJCS5zdGVwCT0gMSwK PiArCQkuZmxhZ3MgID0gVjRMMl9DVFJMX0ZMQUdfVk9MQVRJTEUgfCBWNEwyX0NUUkxfRkxBR19S RUFEX09OTFksCj4gKwl9LCB7Cj4gKwkJLm9wcwk9ICZ4c2Rpcnhzc19jdHJsX29wcywKPiArCQku aWQJPSBWNEwyX0NJRF9YSUxJTlhfU0RJUlhfQ1JDLAo+ICsJCS5uYW1lCT0gIlNESSBSeCA6IENS QyBFcnJvciBzdGF0dXMiLAo+ICsJCS50eXBlCT0gVjRMMl9DVFJMX1RZUEVfSU5URUdFUiwKPiAr CQkubWluCT0gMCwKPiArCQkubWF4CT0gMHhGRkZGRkZGRiwKPiArCQkuc3RlcAk9IDEsCj4gKwkJ LmRlZgk9IDAsCj4gKwkJLmZsYWdzICA9IFY0TDJfQ1RSTF9GTEFHX1ZPTEFUSUxFIHwgVjRMMl9D VFJMX0ZMQUdfUkVBRF9PTkxZLAo+ICsJfSwgewo+ICsJCS5vcHMJPSAmeHNkaXJ4c3NfY3RybF9v cHMsCj4gKwkJLmlkCT0gVjRMMl9DSURfWElMSU5YX1NESVJYX1RTX0lTX0lOVEVSTEFDRUQsCj4g KwkJLm5hbWUJPSAiU0RJIFJ4IDogVFMgaXMgSW50ZXJsYWNlZCIsCj4gKwkJLnR5cGUJPSBWNEwy X0NUUkxfVFlQRV9CT09MRUFOLAo+ICsJCS5taW4JPSBmYWxzZSwKPiArCQkubWF4CT0gdHJ1ZSwK PiArCQkuZGVmCT0gZmFsc2UsCj4gKwkJLnN0ZXAJPSAxLAo+ICsJCS5mbGFncyAgPSBWNEwyX0NU UkxfRkxBR19WT0xBVElMRSB8IFY0TDJfQ1RSTF9GTEFHX1JFQURfT05MWSwKPiArCX0sIHsKPiAr CQkub3BzCT0gJnhzZGlyeHNzX2N0cmxfb3BzLAo+ICsJCS5pZAk9IFY0TDJfQ0lEX1hJTElOWF9T RElSWF9BQ1RJVkVfU1RSRUFNUywKPiArCQkubmFtZQk9ICJTREkgUnggOiBBY3RpdmUgU3RyZWFt cyIsCj4gKwkJLnR5cGUJPSBWNEwyX0NUUkxfVFlQRV9JTlRFR0VSLAo+ICsJCS5taW4JPSAxLAo+ ICsJCS5tYXgJPSAxNiwKPiArCQkuZGVmCT0gMSwKPiArCQkuc3RlcAk9IDEsCj4gKwkJLmZsYWdz ICA9IFY0TDJfQ1RSTF9GTEFHX1ZPTEFUSUxFIHwgVjRMMl9DVFJMX0ZMQUdfUkVBRF9PTkxZLAo+ ICsJfSwgewo+ICsJCS5vcHMJPSAmeHNkaXJ4c3NfY3RybF9vcHMsCj4gKwkJLmlkCT0gVjRMMl9D SURfWElMSU5YX1NESVJYX0lTXzNHQiwKPiArCQkubmFtZQk9ICJTREkgUnggOiBJcyAzR0IiLAo+ ICsJCS50eXBlCT0gVjRMMl9DVFJMX1RZUEVfQk9PTEVBTiwKPiArCQkubWluCT0gZmFsc2UsCj4g KwkJLm1heAk9IHRydWUsCj4gKwkJLmRlZgk9IGZhbHNlLAo+ICsJCS5zdGVwCT0gMSwKPiArCQku ZmxhZ3MgID0gVjRMMl9DVFJMX0ZMQUdfVk9MQVRJTEUgfCBWNEwyX0NUUkxfRkxBR19SRUFEX09O TFksCj4gKwl9Cj4gK307Cj4gKwo+ICtzdGF0aWMgY29uc3Qgc3RydWN0IHY0bDJfc3ViZGV2X2Nv cmVfb3BzIHhzZGlyeHNzX2NvcmVfb3BzID0gewo+ICsJLmxvZ19zdGF0dXMgPSB4c2Rpcnhzc19s b2dfc3RhdHVzLAo+ICsJLnN1YnNjcmliZV9ldmVudCA9IHhzZGlyeHNzX3N1YnNjcmliZV9ldmVu dCwKPiArCS51bnN1YnNjcmliZV9ldmVudCA9IHhzZGlyeHNzX3Vuc3Vic2NyaWJlX2V2ZW50Cj4g K307Cj4gKwo+ICtzdGF0aWMgY29uc3Qgc3RydWN0IHY0bDJfc3ViZGV2X3ZpZGVvX29wcyB4c2Rp cnhzc192aWRlb19vcHMgPSB7Cj4gKwkuZ19mcmFtZV9pbnRlcnZhbCA9IHhzZGlyeHNzX2dfZnJh bWVfaW50ZXJ2YWwsCj4gKwkuc19zdHJlYW0gPSB4c2Rpcnhzc19zX3N0cmVhbSwKPiArCS5nX2lu cHV0X3N0YXR1cyA9IHhzZGlyeHNzX2dfaW5wdXRfc3RhdHVzLAo+ICsJLnF1ZXJ5X2R2X3RpbWlu Z3MgPSB4c2Rpcnhzc19xdWVyeV9kdl90aW1pbmdzLAo+ICt9Owo+ICsKPiArc3RhdGljIGNvbnN0 IHN0cnVjdCB2NGwyX3N1YmRldl9wYWRfb3BzIHhzZGlyeHNzX3BhZF9vcHMgPSB7Cj4gKwkuaW5p dF9jZmcgPSB4c2Rpcnhzc19pbml0X2NmZywKPiArCS5nZXRfZm10ID0geHNkaXJ4c3NfZ2V0X2Zv cm1hdCwKPiArCS5zZXRfZm10ID0geHNkaXJ4c3Nfc2V0X2Zvcm1hdCwKPiArCS5lbnVtX21idXNf Y29kZSA9IHhzZGlyeHNzX2VudW1fbWJ1c19jb2RlLAo+ICsJLmVudW1fZHZfdGltaW5ncyA9IHhz ZGlyeHNzX2VudW1fZHZfdGltaW5ncywKPiArfTsKPiArCj4gK3N0YXRpYyBjb25zdCBzdHJ1Y3Qg djRsMl9zdWJkZXZfb3BzIHhzZGlyeHNzX29wcyA9IHsKPiArCS5jb3JlID0gJnhzZGlyeHNzX2Nv cmVfb3BzLAo+ICsJLnZpZGVvID0gJnhzZGlyeHNzX3ZpZGVvX29wcywKPiArCS5wYWQgPSAmeHNk aXJ4c3NfcGFkX29wcwo+ICt9Owo+ICsKPiArLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KPiArICog UGxhdGZvcm0gRGV2aWNlIERyaXZlcgo+ICsgKi8KPiArCj4gK3N0YXRpYyBpbnQgeHNkaXJ4c3Nf cGFyc2Vfb2Yoc3RydWN0IHhzZGlyeHNzX3N0YXRlICp4c2RpcnhzcykKPiArewo+ICsJc3RydWN0 IGRldmljZV9ub2RlICpub2RlID0geHNkaXJ4c3MtPmNvcmUuZGV2LT5vZl9ub2RlOwo+ICsJc3Ry dWN0IHhzZGlyeHNzX2NvcmUgKmNvcmUgPSAmeHNkaXJ4c3MtPmNvcmU7Cj4gKwlzdHJ1Y3QgZGV2 aWNlICpkZXYgPSBjb3JlLT5kZXY7Cj4gKwlzdHJ1Y3QgZndub2RlX2hhbmRsZSAqZXAsICpyZXA7 Cj4gKwlpbnQgcmV0Owo+ICsJY29uc3QgY2hhciAqc2RpX3N0ZDsKPiArCj4gKwljb3JlLT5pbmNs dWRlX2VkaCA9IG9mX3Byb3BlcnR5X3JlYWRfYm9vbChub2RlLCAieGxueCxpbmNsdWRlLWVkaCIp Owo+ICsJZGV2X2RiZyhkZXYsICJFREggcHJvcGVydHkgPSAlc1xuIiwKPiArCQljb3JlLT5pbmNs dWRlX2VkaCA/ICJQcmVzZW50IiA6ICJBYnNlbnQiKTsKPiArCj4gKwlyZXQgPSBvZl9wcm9wZXJ0 eV9yZWFkX3N0cmluZyhub2RlLCAieGxueCxsaW5lLXJhdGUiLCAmc2RpX3N0ZCk7Cj4gKwlpZiAo cmV0IDwgMCkgewo+ICsJCWRldl9lcnIoZGV2LCAieGxueCxsaW5lLXJhdGUgcHJvcGVydHkgbm90 IGZvdW5kXG4iKTsKPiArCQlyZXR1cm4gcmV0Owo+ICsJfQo+ICsKPiArCWlmICghc3RybmNtcChz ZGlfc3RkLCAiMTJHX1NESV84RFMiLCBYU0RJUlhfTUFYX1NUUl9MRU5HVEgpKSB7CgpTdHJpbmdz IGluIERUIGFyZSBudWxsLXRlcm1pbmF0ZWQsIHlvdSBjYW4gdXNlIHN0cmNtcCgpIGFuZCBkcm9w ClhTRElSWF9NQVhfU1RSX0xFTkdUSC4KCj4gKwkJY29yZS0+bW9kZSA9IFhTRElSWFNTX1NESV9T VERfMTJHXzhEUzsKPiArCX0gZWxzZSBpZiAoIXN0cm5jbXAoc2RpX3N0ZCwgIjZHX1NESSIsIFhT RElSWF9NQVhfU1RSX0xFTkdUSCkpIHsKPiArCQljb3JlLT5tb2RlID0gWFNESVJYU1NfU0RJX1NU RF82RzsKPiArCX0gZWxzZSBpZiAoIXN0cm5jbXAoc2RpX3N0ZCwgIjNHX1NESSIsIFhTRElSWF9N QVhfU1RSX0xFTkdUSCkpIHsKPiArCQljb3JlLT5tb2RlID0gWFNESVJYU1NfU0RJX1NURF8zRzsK PiArCX0gZWxzZSB7Cj4gKwkJZGV2X2VycihkZXYsICJJbnZhbGlkIExpbmUgUmF0ZVxuIik7Cj4g KwkJcmV0dXJuIC1FSU5WQUw7Cj4gKwl9Cj4gKwlkZXZfZGJnKGRldiwgIlNESSBSeCBMaW5lIFJh dGUgPSAlcywgbW9kZSA9ICVkXG4iLCBzZGlfc3RkLAo+ICsJCWNvcmUtPm1vZGUpOwo+ICsKPiAr CXJldCA9IG9mX3Byb3BlcnR5X3JlYWRfdTMyKG5vZGUsICJ4bG54LGJwcCIsICZjb3JlLT5icGMp Owo+ICsJaWYgKHJldCA8IDApIHsKPiArCQlkZXZfZXJyKGRldiwgImZhaWxlZCB0byBnZXQgeGxu eCxicHBcbiIpOwo+ICsJCXJldHVybiByZXQ7Cj4gKwl9Cj4gKwo+ICsJaWYgKGNvcmUtPmJwYyAh PSAxMCAmJiBjb3JlLT5icGMgIT0gMTIpIHsKPiArCQlkZXZfZXJyKGRldiwgImJpdHMgcGVyIGNv bXBvbmVudD0ldS4gQ2FuIGJlIDEwIG9yIDEyIG9ubHlcbiIsCj4gKwkJCWNvcmUtPmJwYyk7Cj4g KwkJcmV0dXJuIC1FSU5WQUw7Cj4gKwl9Cj4gKwo+ICsJZXAgPSBmd25vZGVfZ3JhcGhfZ2V0X2Vu ZHBvaW50X2J5X2lkKGRldl9md25vZGUoZGV2KSwgMCwgMCwKPiArCQkJCQkgICAgIEZXTk9ERV9H UkFQSF9FTkRQT0lOVF9ORVhUKTsKPiArCWlmICghZXApIHsKPiArCQlkZXZfZXJyKGRldiwgIm5v IHNvdXJjZSBwb3J0IGZvdW5kIik7Cj4gKwkJcmV0ID0gLUVJTlZBTDsKPiArCQlnb3RvIGR0X3Bh cnNlX2RvbmU7Cj4gKwl9Cj4gKwo+ICsJcmVwID0gZndub2RlX2dyYXBoX2dldF9yZW1vdGVfZW5k cG9pbnQoZXApOwo+ICsJaWYgKCFyZXApIHsKPiArCQlkZXZfZXJyKGRldiwgIm5vIHJlbW90ZSBz aW5rIGVuZHBvaW50IGZvdW5kIik7Cj4gKwkJcmV0ID0gLUVJTlZBTDsKPiArCX0KCkkgZG9uJ3Qg dGhpbmsgeW91IG5lZWQgdG8gY2hlY2sgdGhpcywgdGhlIHN1YmRldiB3b24ndCBiZSBsaW5rZWQK cHJvcGVybHkgaW4gdGhlIHBpcGVsaW5lIGlmIHRoZXJlJ3Mgbm8gcG9ydCBhbnl3YXkuCgo+ICsK PiArCWZ3bm9kZV9oYW5kbGVfcHV0KHJlcCk7Cj4gK2R0X3BhcnNlX2RvbmU6Cj4gKwlmd25vZGVf aGFuZGxlX3B1dChlcCk7Cj4gKwlyZXR1cm4gcmV0Owo+ICt9Cj4gKwo+ICtzdGF0aWMgaW50IHhz ZGlyeHNzX3Byb2JlKHN0cnVjdCBwbGF0Zm9ybV9kZXZpY2UgKnBkZXYpCj4gK3sKPiArCXN0cnVj dCB2NGwyX3N1YmRldiAqc3ViZGV2Owo+ICsJc3RydWN0IHhzZGlyeHNzX3N0YXRlICp4c2Rpcnhz czsKPiArCXN0cnVjdCB4c2Rpcnhzc19jb3JlICpjb3JlOwo+ICsJc3RydWN0IGRldmljZSAqZGV2 Owo+ICsJaW50IHJldDsKPiArCXVuc2lnbmVkIGludCBudW1fY3RybHMsIG51bV9lZGhfY3RybHMg PSAwLCBpOwo+ICsKPiArCXhzZGlyeHNzID0gZGV2bV9remFsbG9jKCZwZGV2LT5kZXYsIHNpemVv ZigqeHNkaXJ4c3MpLCBHRlBfS0VSTkVMKTsKPiArCWlmICgheHNkaXJ4c3MpCj4gKwkJcmV0dXJu IC1FTk9NRU07Cj4gKwo+ICsJeHNkaXJ4c3MtPmNvcmUuZGV2ID0gJnBkZXYtPmRldjsKPiArCWNv cmUgPSAmeHNkaXJ4c3MtPmNvcmU7Cj4gKwlkZXYgPSBjb3JlLT5kZXY7Cj4gKwo+ICsJLyogUmVn aXN0ZXIgaW50ZXJydXB0IGhhbmRsZXIgKi8KPiArCWNvcmUtPmlycSA9IHBsYXRmb3JtX2dldF9p cnEocGRldiwgMCk7Cj4gKwlyZXQgPSBkZXZtX3JlcXVlc3RfdGhyZWFkZWRfaXJxKGRldiwgY29y ZS0+aXJxLCBOVUxMLAo+ICsJCQkJCXhzZGlyeHNzX2lycV9oYW5kbGVyLCBJUlFGX09ORVNIT1Qs Cj4gKwkJCQkJZGV2X25hbWUoZGV2KSwgeHNkaXJ4c3MpOwoKV2h5IGEgdGhyZWFkZWQgSVJRID8K Cj4gKwlpZiAocmV0KSB7Cj4gKwkJZGV2X2VycihkZXYsICJFcnIgPSAlZCBJbnRlcnJ1cHQgaGFu ZGxlciByZWcgZmFpbGVkIVxuIiwKPiArCQkJcmV0KTsKPiArCQlyZXR1cm4gcmV0Owo+ICsJfQoK WW91IHNob3VsZCByZXF1ZXN0IHRoZSBJUlEgYWZ0ZXIgcmVzZXR0aW5nIHRoZSBjb3JlLCBvdGhl cndpc2UKaW50ZXJydXB0cyBjb3VsZCBiZSB0cmlnZ2VyZWQgaW1tZWRpYXRlbHkuCgo+ICsKPiAr CWNvcmUtPm51bV9jbGtzID0gQVJSQVlfU0laRSh4c2Rpcnhzc19jbGtzKTsKPiArCWNvcmUtPmNs a3MgPSBkZXZtX2tjYWxsb2MoZGV2LCBjb3JlLT5udW1fY2xrcywKPiArCQkJCSAgc2l6ZW9mKCpj b3JlLT5jbGtzKSwgR0ZQX0tFUk5FTCk7Cj4gKwlpZiAoIWNvcmUtPmNsa3MpCj4gKwkJcmV0dXJu IC1FTk9NRU07Cj4gKwo+ICsJZm9yIChpID0gMDsgaSA8IGNvcmUtPm51bV9jbGtzOyBpKyspCj4g KwkJY29yZS0+Y2xrc1tpXS5pZCA9IHhzZGlyeHNzX2Nsa3NbaV07Cj4gKwo+ICsJcmV0ID0gZGV2 bV9jbGtfYnVsa19nZXQoZGV2LCBjb3JlLT5udW1fY2xrcywgY29yZS0+Y2xrcyk7Cj4gKwlpZiAo cmV0KQo+ICsJCXJldHVybiByZXQ7Cj4gKwo+ICsJcmV0ID0gY2xrX2J1bGtfcHJlcGFyZV9lbmFi bGUoY29yZS0+bnVtX2Nsa3MsIGNvcmUtPmNsa3MpOwo+ICsJaWYgKHJldCkKPiArCQlyZXR1cm4g cmV0Owo+ICsKPiArCXJldCA9IHhzZGlyeHNzX3BhcnNlX29mKHhzZGlyeHNzKTsKPiArCWlmIChy ZXQgPCAwKQo+ICsJCWdvdG8gY2xrX2VycjsKPiArCj4gKwljb3JlLT5pb21lbSA9IGRldm1fcGxh dGZvcm1faW9yZW1hcF9yZXNvdXJjZShwZGV2LCAwKTsKPiArCWlmIChJU19FUlIoY29yZS0+aW9t ZW0pKSB7Cj4gKwkJcmV0ID0gUFRSX0VSUihjb3JlLT5pb21lbSk7Cj4gKwkJZ290byBjbGtfZXJy Owo+ICsJfQoKSWYgeW91IG1vdmUgdGhlc2UgdHdvIGNhbGxzIGFib3ZlIGhhbmRsaW5nIG9mIHRo ZSBjbG9ja3MsIHlvdSB3aWxsIGJlCmFibGUgdG8gcmV0dXJuIGltbWVkaWF0ZWx5IGFuZCBhdm9p ZCB0aGUgZ290by4KCj4gKwo+ICsJLyogUmVzZXQgdGhlIGNvcmUgKi8KPiArCXhzZGlyeF9zdHJl YW1mbG93X2NvbnRyb2woY29yZSwgZmFsc2UpOwo+ICsJeHNkaXJ4X2NvcmVfZGlzYWJsZShjb3Jl KTsKPiArCXhzZGlyeF9jbGVhcmludHIoY29yZSwgWFNESVJYX0lOVFJfQUxMX01BU0spOwo+ICsJ eHNkaXJ4X2Rpc2FibGVpbnRyKGNvcmUsIFhTRElSWF9JTlRSX0FMTF9NQVNLKTsKPiArCXhzZGly eF9lbmFibGVpbnRyKGNvcmUsIFhTRElSWF9JTlRSX0FMTF9NQVNLKTsKPiArCXhzZGlyeF9nbG9i YWxpbnRyKGNvcmUsIHRydWUpOwo+ICsJeHNkaXJ4c3Nfd3JpdGUoY29yZSwgWFNESVJYX0NSQ19F UlJDTlRfUkVHLCAweEZGRkYpOwo+ICsKPiArCS8qIEluaXRpYWxpemUgVjRMMiBzdWJkZXZpY2Ug YW5kIG1lZGlhIGVudGl0eSAqLwo+ICsJeHNkaXJ4c3MtPnBhZC5mbGFncyA9IE1FRElBX1BBRF9G TF9TT1VSQ0U7Cj4gKwo+ICsJLyogSW5pdGlhbGl6ZSB0aGUgZGVmYXVsdCBmb3JtYXQgKi8KPiAr CWlmIChjb3JlLT5icGMgPT0gMTApCj4gKwkJeHNkaXJ4c3MtPmRlZmF1bHRfZm9ybWF0LmNvZGUg PSBNRURJQV9CVVNfRk1UX1VZVlkxMF8xWDIwOwo+ICsJZWxzZQo+ICsJCXhzZGlyeHNzLT5kZWZh dWx0X2Zvcm1hdC5jb2RlID0gTUVESUFfQlVTX0ZNVF9VWVZZMTJfMVgyNDsKPiArCXhzZGlyeHNz LT5kZWZhdWx0X2Zvcm1hdC5maWVsZCA9IFY0TDJfRklFTERfTk9ORTsKPiArCXhzZGlyeHNzLT5k ZWZhdWx0X2Zvcm1hdC5jb2xvcnNwYWNlID0gVjRMMl9DT0xPUlNQQUNFX0RFRkFVTFQ7Cj4gKwl4 c2Rpcnhzcy0+ZGVmYXVsdF9mb3JtYXQud2lkdGggPSBYU0RJUlhfREVGQVVMVF9XSURUSDsKPiAr CXhzZGlyeHNzLT5kZWZhdWx0X2Zvcm1hdC5oZWlnaHQgPSBYU0RJUlhfREVGQVVMVF9IRUlHSFQ7 Cj4gKwo+ICsJeHNkaXJ4c3MtPmZvcm1hdCA9IHhzZGlyeHNzLT5kZWZhdWx0X2Zvcm1hdDsKPiAr Cj4gKwkvKiBJbml0aWFsaXplIFY0TDIgc3ViZGV2aWNlIGFuZCBtZWRpYSBlbnRpdHkgKi8KPiAr CXN1YmRldiA9ICZ4c2Rpcnhzcy0+c3ViZGV2Owo+ICsJdjRsMl9zdWJkZXZfaW5pdChzdWJkZXYs ICZ4c2Rpcnhzc19vcHMpOwo+ICsKPiArCXN1YmRldi0+ZGV2ID0gJnBkZXYtPmRldjsKPiArCXN0 cnNjcHkoc3ViZGV2LT5uYW1lLCBkZXZfbmFtZShkZXYpLCBzaXplb2Yoc3ViZGV2LT5uYW1lKSk7 Cj4gKwo+ICsJc3ViZGV2LT5mbGFncyB8PSBWNEwyX1NVQkRFVl9GTF9IQVNfRVZFTlRTIHwgVjRM Ml9TVUJERVZfRkxfSEFTX0RFVk5PREU7Cj4gKwo+ICsJc3ViZGV2LT5lbnRpdHkub3BzID0gJnhz ZGlyeHNzX21lZGlhX29wczsKPiArCj4gKwl2NGwyX3NldF9zdWJkZXZkYXRhKHN1YmRldiwgeHNk aXJ4c3MpOwo+ICsKPiArCXJldCA9IG1lZGlhX2VudGl0eV9wYWRzX2luaXQoJnN1YmRldi0+ZW50 aXR5LCAxLCAmeHNkaXJ4c3MtPnBhZCk7Cj4gKwlpZiAocmV0IDwgMCkKPiArCQlnb3RvIGVycm9y Owo+ICsKPiArCS8qIEluaXRpYWxpc2UgYW5kIHJlZ2lzdGVyIHRoZSBjb250cm9scyAqLwo+ICsJ bnVtX2N0cmxzID0gQVJSQVlfU0laRSh4c2Rpcnhzc19jdHJscyk7Cj4gKwo+ICsJaWYgKGNvcmUt PmluY2x1ZGVfZWRoKQo+ICsJCW51bV9lZGhfY3RybHMgPSBBUlJBWV9TSVpFKHhzZGlyeHNzX2Vk aF9jdHJscyk7CgpIb3cgYWJvdXQKCgkJbnVtX2N0cmxzICs9IEFSUkFZX1NJWkUoeHNkaXJ4c3Nf ZWRoX2N0cmxzKTsKCj4gKwo+ICsJdjRsMl9jdHJsX2hhbmRsZXJfaW5pdCgmeHNkaXJ4c3MtPmN0 cmxfaGFuZGxlciwKPiArCQkJICAgICAgIChudW1fY3RybHMgKyBudW1fZWRoX2N0cmxzKSk7CgoJ CQkgICAgICAgbnVtX2N0cmxzKTsKCj4gKwo+ICsJZm9yIChpID0gMDsgaSA8IG51bV9jdHJsczsg aSsrKSB7CgoJZm9yIChpID0gMDsgaSA8IEFSUkFZX1NJWkUoeHNkaXJ4c3NfY3RybHMpOyBpKysp IHsKCj4gKwkJc3RydWN0IHY0bDJfY3RybCAqY3RybDsKPiArCj4gKwkJZGV2X2RiZyhkZXYsICIl ZCAlcyBjdHJsID0gMHgleFxuIiwgaSwgeHNkaXJ4c3NfY3RybHNbaV0ubmFtZSwKPiArCQkJeHNk aXJ4c3NfY3RybHNbaV0uaWQpOwo+ICsKPiArCQljdHJsID0gdjRsMl9jdHJsX25ld19jdXN0b20o JnhzZGlyeHNzLT5jdHJsX2hhbmRsZXIsCj4gKwkJCQkJICAgICZ4c2Rpcnhzc19jdHJsc1tpXSwg TlVMTCk7Cj4gKwkJaWYgKCFjdHJsKSB7Cj4gKwkJCWRldl9kYmcoZGV2LCAiRmFpbGVkIHRvIGFk ZCAlcyBjdHJsXG4iLAo+ICsJCQkJeHNkaXJ4c3NfY3RybHNbaV0ubmFtZSk7Cj4gKwkJCWdvdG8g ZXJyb3I7Cj4gKwkJfQoKQXMgeW91IGNoZWNrIGZvciB4c2Rpcnhzcy0+Y3RybF9oYW5kbGVyLmVy cm9yIGJlbG93IHlvdSBjYW4gZHJvcCB0aGlzCmNoZWNrIGFuZCB0aGUgZXF1aXZhbGVudCBvbmUg Zm9yIHRoZSBFREggY29udHJvbHMuCgo+ICsJfQo+ICsKPiArCWlmIChjb3JlLT5pbmNsdWRlX2Vk aCkgewo+ICsJCWZvciAoaSA9IDA7IGkgPCBudW1fZWRoX2N0cmxzOyBpKyspIHsKCgkJZm9yIChp ID0gMDsgaSA8IEFSUkFZX1NJWkUoeHNkaXJ4c3NfZWRoX2N0cmxzKTsgaSsrKSB7Cgo+ICsJCQlz dHJ1Y3QgdjRsMl9jdHJsICpjdHJsOwo+ICsKPiArCQkJZGV2X2RiZyhkZXYsICIlZCAlcyBjdHJs ID0gMHgleFxuIiwgaSwKPiArCQkJCXhzZGlyeHNzX2VkaF9jdHJsc1tpXS5uYW1lLAo+ICsJCQkJ eHNkaXJ4c3NfZWRoX2N0cmxzW2ldLmlkKTsKPiArCj4gKwkJCWN0cmwgPSB2NGwyX2N0cmxfbmV3 X2N1c3RvbSgmeHNkaXJ4c3MtPmN0cmxfaGFuZGxlciwKPiArCQkJCQkJICAgICZ4c2Rpcnhzc19l ZGhfY3RybHNbaV0sCj4gKwkJCQkJCSAgICBOVUxMKTsKPiArCQkJaWYgKCFjdHJsKSB7Cj4gKwkJ CQlkZXZfZGJnKGRldiwgIkZhaWxlZCB0byBhZGQgJXMgY3RybFxuIiwKPiArCQkJCQl4c2Rpcnhz c19lZGhfY3RybHNbaV0ubmFtZSk7Cj4gKwkJCQlnb3RvIGVycm9yOwo+ICsJCQl9Cj4gKwkJfQo+ ICsJfQo+ICsKPiArCWlmICh4c2Rpcnhzcy0+Y3RybF9oYW5kbGVyLmVycm9yKSB7Cj4gKwkJZGV2 X2VycihkZXYsICJmYWlsZWQgdG8gYWRkIGNvbnRyb2xzXG4iKTsKPiArCQlyZXQgPSB4c2Rpcnhz cy0+Y3RybF9oYW5kbGVyLmVycm9yOwo+ICsJCWdvdG8gZXJyb3I7Cj4gKwl9Cj4gKwo+ICsJc3Vi ZGV2LT5jdHJsX2hhbmRsZXIgPSAmeHNkaXJ4c3MtPmN0cmxfaGFuZGxlcjsKPiArCj4gKwlyZXQg PSB2NGwyX2N0cmxfaGFuZGxlcl9zZXR1cCgmeHNkaXJ4c3MtPmN0cmxfaGFuZGxlcik7Cj4gKwlp ZiAocmV0IDwgMCkgewo+ICsJCWRldl9lcnIoZGV2LCAiZmFpbGVkIHRvIHNldCBjb250cm9sc1xu Iik7Cj4gKwkJZ290byBlcnJvcjsKPiArCX0KPiArCj4gKwlwbGF0Zm9ybV9zZXRfZHJ2ZGF0YShw ZGV2LCB4c2Rpcnhzcyk7Cj4gKwo+ICsJcmV0ID0gdjRsMl9hc3luY19yZWdpc3Rlcl9zdWJkZXYo c3ViZGV2KTsKPiArCWlmIChyZXQgPCAwKSB7Cj4gKwkJZGV2X2VycihkZXYsICJmYWlsZWQgdG8g cmVnaXN0ZXIgc3ViZGV2XG4iKTsKPiArCQlnb3RvIGVycm9yOwo+ICsJfQo+ICsKPiArCXhzZGly eHNzLT5zdHJlYW1pbmcgPSBmYWxzZTsKPiArCj4gKwl4c2RpcnhfY29yZV9lbmFibGUoY29yZSk7 Cj4gKwo+ICsJZGV2X2luZm8oZGV2LCAicHJvYmUgc3VjY2Vzc1xuIik7CgpZb3UgY2FuIGRyb3Ag dGhpcyBsaW5lLCBzdWNjZXNzZnVsIGRyaXZlciBwcm9iaW5nIHNob3VsZCBiZSBzaWxlbnQuCgo+ ICsKPiArCXJldHVybiAwOwo+ICtlcnJvcjoKPiArCXY0bDJfY3RybF9oYW5kbGVyX2ZyZWUoJnhz ZGlyeHNzLT5jdHJsX2hhbmRsZXIpOwo+ICsJbWVkaWFfZW50aXR5X2NsZWFudXAoJnN1YmRldi0+ ZW50aXR5KTsKPiArCXhzZGlyeF9nbG9iYWxpbnRyKGNvcmUsIGZhbHNlKTsKPiArCXhzZGlyeF9k aXNhYmxlaW50cihjb3JlLCBYU0RJUlhfSU5UUl9BTExfTUFTSyk7Cj4gK2Nsa19lcnI6Cj4gKwlj bGtfYnVsa19kaXNhYmxlX3VucHJlcGFyZShjb3JlLT5udW1fY2xrcywgY29yZS0+Y2xrcyk7Cj4g KwlyZXR1cm4gcmV0Owo+ICt9Cj4gKwo+ICtzdGF0aWMgaW50IHhzZGlyeHNzX3JlbW92ZShzdHJ1 Y3QgcGxhdGZvcm1fZGV2aWNlICpwZGV2KQo+ICt7Cj4gKwlzdHJ1Y3QgeHNkaXJ4c3Nfc3RhdGUg KnhzZGlyeHNzID0gcGxhdGZvcm1fZ2V0X2RydmRhdGEocGRldik7Cj4gKwlzdHJ1Y3QgeHNkaXJ4 c3NfY29yZSAqY29yZSA9ICZ4c2Rpcnhzcy0+Y29yZTsKPiArCXN0cnVjdCB2NGwyX3N1YmRldiAq c3ViZGV2ID0gJnhzZGlyeHNzLT5zdWJkZXY7Cj4gKwo+ICsJdjRsMl9hc3luY191bnJlZ2lzdGVy X3N1YmRldihzdWJkZXYpOwo+ICsJdjRsMl9jdHJsX2hhbmRsZXJfZnJlZSgmeHNkaXJ4c3MtPmN0 cmxfaGFuZGxlcik7Cj4gKwltZWRpYV9lbnRpdHlfY2xlYW51cCgmc3ViZGV2LT5lbnRpdHkpOwo+ ICsKPiArCXhzZGlyeF9nbG9iYWxpbnRyKGNvcmUsIGZhbHNlKTsKPiArCXhzZGlyeF9kaXNhYmxl aW50cihjb3JlLCBYU0RJUlhfSU5UUl9BTExfTUFTSyk7Cj4gKwl4c2RpcnhfY29yZV9kaXNhYmxl KGNvcmUpOwo+ICsJeHNkaXJ4X3N0cmVhbWZsb3dfY29udHJvbChjb3JlLCBmYWxzZSk7Cj4gKwo+ ICsJY2xrX2J1bGtfZGlzYWJsZV91bnByZXBhcmUoY29yZS0+bnVtX2Nsa3MsIGNvcmUtPmNsa3Mp Owo+ICsKPiArCXJldHVybiAwOwo+ICt9Cj4gKwo+ICtzdGF0aWMgY29uc3Qgc3RydWN0IG9mX2Rl dmljZV9pZCB4c2Rpcnhzc19vZl9pZF90YWJsZVtdID0gewo+ICsJeyAuY29tcGF0aWJsZSA9ICJ4 bG54LHYtc21wdGUtdWhkc2RpLXJ4LXNzLTIuMCIgfSwKPiArCXsgfQo+ICt9Owo+ICtNT0RVTEVf REVWSUNFX1RBQkxFKG9mLCB4c2Rpcnhzc19vZl9pZF90YWJsZSk7Cj4gKwo+ICtzdGF0aWMgc3Ry dWN0IHBsYXRmb3JtX2RyaXZlciB4c2Rpcnhzc19kcml2ZXIgPSB7Cj4gKwkuZHJpdmVyID0gewo+ ICsJCS5uYW1lCQk9ICJ4aWxpbngtc2RpcnhzcyIsCj4gKwkJLm9mX21hdGNoX3RhYmxlCT0geHNk aXJ4c3Nfb2ZfaWRfdGFibGUsCj4gKwl9LAo+ICsJLnByb2JlCQkJPSB4c2Rpcnhzc19wcm9iZSwK PiArCS5yZW1vdmUJCQk9IHhzZGlyeHNzX3JlbW92ZSwKPiArfTsKPiArCj4gK21vZHVsZV9wbGF0 Zm9ybV9kcml2ZXIoeHNkaXJ4c3NfZHJpdmVyKTsKPiArCj4gK01PRFVMRV9BVVRIT1IoIlZpc2hh bCBTYWdhciA8dnNhZ2FyQHhpbGlueC5jb20+Iik7Cj4gK01PRFVMRV9ERVNDUklQVElPTigiWGls aW54IFNESSBSeCBTdWJzeXN0ZW0gRHJpdmVyIik7Cj4gK01PRFVMRV9MSUNFTlNFKCJHUEwgdjIi KTsKPiBkaWZmIC0tZ2l0IGEvaW5jbHVkZS91YXBpL2xpbnV4L3hpbGlueC1zZGlyeHNzLmggYi9p bmNsdWRlL3VhcGkvbGludXgveGlsaW54LXNkaXJ4c3MuaAo+IG5ldyBmaWxlIG1vZGUgMTAwNjQ0 Cj4gaW5kZXggMDAwMDAwMDAwMDAwLi42ZjJhMDkzOTY4ZDkKPiAtLS0gL2Rldi9udWxsCj4gKysr IGIvaW5jbHVkZS91YXBpL2xpbnV4L3hpbGlueC1zZGlyeHNzLmgKPiBAQCAtMCwwICsxLDE3OSBA QAo+ICsvKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogR1BMLTIuMCBXSVRIIExpbnV4LXN5c2Nh bGwtbm90ZSAqLwo+ICsvKgo+ICsgKiBYaWxpbnggU0RJIFJ4IFN1YnN5c3RlbSBtb2RlLCBldmVu dCwgY3VzdG9tIHRpbWluZ3MKPiArICogYW5kIGZsYWcgZGVmaW5pdGlvbnMuCj4gKyAqCj4gKyAq IENvcHlyaWdodCAoQykgMjAxOSAtIDIwMjAgWGlsaW54LCBJbmMuCj4gKyAqCj4gKyAqIENvbnRh Y3RzOiBWaXNoYWwgU2FnYXIgPHZpc2hhbC5zYWdhckB4aWxpbnguY29tPgo+ICsgKi8KPiArCj4g KyNpZm5kZWYgX19VQVBJX1hJTElOWF9TRElSWFNTX0hfXwo+ICsjZGVmaW5lIF9fVUFQSV9YSUxJ TlhfU0RJUlhTU19IX18KPiArCj4gKyNpbmNsdWRlIDxsaW51eC90eXBlcy5oPgo+ICsjaW5jbHVk ZSA8bGludXgvdjRsMi1kdi10aW1pbmdzLmg+Cj4gKyNpbmNsdWRlIDxsaW51eC92aWRlb2RldjIu aD4KPiArCj4gKy8qCj4gKyAqIEV2ZW50cwo+ICsgKgo+ICsgKiBWNEwyX0VWRU5UX1hJTElOWF9T RElSWF9VTkRFUkZMT1c6IFZpZGVvIGluIHRvIEFYSTQgU3RyZWFtIGNvcmUgdW5kZXJmbG93ZWQK PiArICogVjRMMl9FVkVOVF9YSUxJTlhfU0RJUlhfT1ZFUkZMT1c6IFZpZGVvIGluIHRvIEFYSTQg U3RyZWFtIGNvcmUgb3ZlcmZsb3dlZAo+ICsgKi8KPiArI2RlZmluZSBWNEwyX0VWRU5UX1hJTElO WF9TRElSWF9DTEFTUyAgICAgIChWNEwyX0VWRU5UX1BSSVZBVEVfU1RBUlQgfCAweDIwMCkKPiAr I2RlZmluZSBWNEwyX0VWRU5UX1hJTElOWF9TRElSWF9VTkRFUkZMT1cgIChWNEwyX0VWRU5UX1hJ TElOWF9TRElSWF9DTEFTUyB8IDB4MSkKPiArI2RlZmluZSBWNEwyX0VWRU5UX1hJTElOWF9TRElS WF9PVkVSRkxPVyAgIChWNEwyX0VWRU5UX1hJTElOWF9TRElSWF9DTEFTUyB8IDB4MikKPiArCj4g Ky8qCj4gKyAqIFRoaXMgZW51bSBpcyB1c2VkIHRvIHByZXBhcmUgdGhlIGJpdG1hc2sgb2YgbW9k ZXMgdG8gYmUgZGV0ZWN0ZWQKPiArICovCj4gK2VudW0gewo+ICsJWFNESVJYX01PREVfU0RfT0ZG U0VUID0gMCwKPiArCVhTRElSWF9NT0RFX0hEX09GRlNFVCwKPiArCVhTRElSWF9NT0RFXzNHX09G RlNFVCwKPiArCVhTRElSWF9NT0RFXzZHX09GRlNFVCwKPiArCVhTRElSWF9NT0RFXzEyR0lfT0ZG U0VULAo+ICsJWFNESVJYX01PREVfMTJHRl9PRkZTRVQsCj4gKwlYU0RJUlhfTU9ERV9OVU1fU1VQ UE9SVEVELAo+ICt9Owo+ICsKPiArI2RlZmluZSBYU0RJUlhfREVURUNUX0FMTF9NT0RFUwkJKEJJ VChYU0RJUlhfTU9ERV9TRF9PRkZTRVQpIHwgXAo+ICsJCQkJCUJJVChYU0RJUlhfTU9ERV9IRF9P RkZTRVQpIHwgXAo+ICsJCQkJCUJJVChYU0RJUlhfTU9ERV8zR19PRkZTRVQpIHwgXAo+ICsJCQkJ CUJJVChYU0RJUlhfTU9ERV82R19PRkZTRVQpIHwgXAo+ICsJCQkJCUJJVChYU0RJUlhfTU9ERV8x MkdJX09GRlNFVCkgfCBcCj4gKwkJCQkJQklUKFhTRElSWF9NT0RFXzEyR0ZfT0ZGU0VUKSkKPiAr Cj4gKy8qCj4gKyAqIEVESCBFcnJvciBUeXBlcwo+ICsgKiBBTkMgLSBBbmNpbGxhcnkgRGF0YSBQ YWNrZXQgRXJyb3JzCj4gKyAqIEZGIC0gRnVsbCBGaWVsZCBFcnJvcnMKPiArICogQVAgLSBBY3Rp dmUgUG9ydGlvbiBFcnJvcnMKPiArICovCj4gKwo+ICsjZGVmaW5lIFhTRElSWF9FREhfRVJSQ05U X0FOQ19FREhfRVJSCQlCSVQoMCkKPiArI2RlZmluZSBYU0RJUlhfRURIX0VSUkNOVF9BTkNfRURB X0VSUgkJQklUKDEpCj4gKyNkZWZpbmUgWFNESVJYX0VESF9FUlJDTlRfQU5DX0lESF9FUlIJCUJJ VCgyKQo+ICsjZGVmaW5lIFhTRElSWF9FREhfRVJSQ05UX0FOQ19JREFfRVJSCQlCSVQoMykKPiAr I2RlZmluZSBYU0RJUlhfRURIX0VSUkNOVF9BTkNfVUVTX0VSUgkJQklUKDQpCj4gKyNkZWZpbmUg WFNESVJYX0VESF9FUlJDTlRfRkZfRURIX0VSUgkJQklUKDUpCj4gKyNkZWZpbmUgWFNESVJYX0VE SF9FUlJDTlRfRkZfRURBX0VSUgkJQklUKDYpCj4gKyNkZWZpbmUgWFNESVJYX0VESF9FUlJDTlRf RkZfSURIX0VSUgkJQklUKDcpCj4gKyNkZWZpbmUgWFNESVJYX0VESF9FUlJDTlRfRkZfSURBX0VS UgkJQklUKDgpCj4gKyNkZWZpbmUgWFNESVJYX0VESF9FUlJDTlRfRkZfVUVTX0VSUgkJQklUKDkp Cj4gKyNkZWZpbmUgWFNESVJYX0VESF9FUlJDTlRfQVBfRURIX0VSUgkJQklUKDEwKQo+ICsjZGVm aW5lIFhTRElSWF9FREhfRVJSQ05UX0FQX0VEQV9FUlIJCUJJVCgxMSkKPiArI2RlZmluZSBYU0RJ UlhfRURIX0VSUkNOVF9BUF9JREhfRVJSCQlCSVQoMTIpCj4gKyNkZWZpbmUgWFNESVJYX0VESF9F UlJDTlRfQVBfSURBX0VSUgkJQklUKDEzKQo+ICsjZGVmaW5lIFhTRElSWF9FREhfRVJSQ05UX0FQ X1VFU19FUlIJCUJJVCgxNCkKPiArI2RlZmluZSBYU0RJUlhfRURIX0VSUkNOVF9QS1RfQ0hLU1VN X0VSUglCSVQoMTUpCj4gKwo+ICsjZGVmaW5lIFhTRElSWF9FREhfQUxMRVJSX01BU0sJCTB4RkZG Rgo+ICsKPiArLyogWGlsaW54IERWIHRpbWluZ3Mgbm90IGluIG1haW5saW5lIHlldCAqLwo+ICsj ZGVmaW5lIFhMTlhfVjRMMl9EVl9CVF8yMDQ4WDEwODBQMjQgeyBcCj4gKwkudHlwZSA9IFY0TDJf RFZfQlRfNjU2XzExMjAsIFwKPiArCVY0TDJfSU5JVF9CVF9USU1JTkdTKDIwNDgsIDEwODAsIDAs IFwKPiArCQlWNEwyX0RWX0hTWU5DX1BPU19QT0wgfCBWNEwyX0RWX1ZTWU5DX1BPU19QT0wsIFwK PiArCQk3NDI1MDAwMCwgNTEwLCA0NCwgMTQ4LCA0LCA1LCAzNiwgMCwgMCwgMCwgXAo+ICsJCVY0 TDJfRFZfQlRfU1REX1NESSkgXAo+ICt9Cj4gKwo+ICsjZGVmaW5lIFhMTlhfVjRMMl9EVl9CVF8y MDQ4WDEwODBQMjUgeyBcCj4gKwkudHlwZSA9IFY0TDJfRFZfQlRfNjU2XzExMjAsIFwKPiArCVY0 TDJfSU5JVF9CVF9USU1JTkdTKDIwNDgsIDEwODAsIDAsIFwKPiArCQlWNEwyX0RWX0hTWU5DX1BP U19QT0wgfCBWNEwyX0RWX1ZTWU5DX1BPU19QT0wsIFwKPiArCQk3NDI1MDAwMCwgNDAwLCA0NCwg MTQ4LCA0LCA1LCAzNiwgMCwgMCwgMCwgXAo+ICsJCVY0TDJfRFZfQlRfU1REX1NESSkgXAo+ICt9 Cj4gKwo+ICsjZGVmaW5lIFhMTlhfVjRMMl9EVl9CVF8yMDQ4WDEwODBQMzAgeyBcCj4gKwkudHlw ZSA9IFY0TDJfRFZfQlRfNjU2XzExMjAsIFwKPiArCVY0TDJfSU5JVF9CVF9USU1JTkdTKDIwNDgs IDEwODAsIDAsIFwKPiArCQlWNEwyX0RWX0hTWU5DX1BPU19QT0wgfCBWNEwyX0RWX1ZTWU5DX1BP U19QT0wsIFwKPiArCQk3NDI1MDAwMCwgNjYsIDIwLCA2NiwgNCwgNSwgMzYsIDAsIDAsIDAsIFwK PiArCQlWNEwyX0RWX0JUX1NURF9TREkpIFwKPiArfQo+ICsKPiArI2RlZmluZSBYTE5YX1Y0TDJf RFZfQlRfMjA0OFgxMDgwSTQ4IHsgXAo+ICsJLnR5cGUgPSBWNEwyX0RWX0JUXzY1Nl8xMTIwLCBc Cj4gKwlWNEwyX0lOSVRfQlRfVElNSU5HUygyMDQ4LCAxMDgwLCAxLCBcCj4gKwkJVjRMMl9EVl9I U1lOQ19QT1NfUE9MIHwgVjRMMl9EVl9WU1lOQ19QT1NfUE9MLCBcCj4gKwkJNzQyNTAwMDAsIDMy OSwgNDQsIDMyOSwgMiwgNSwgMTUsIDMsIDUsIDE1LCBcCj4gKwkJVjRMMl9EVl9CVF9TVERfU0RJ KSBcCj4gK30KPiArCj4gKyNkZWZpbmUgWExOWF9WNEwyX0RWX0JUXzIwNDhYMTA4MEk1MCB7IFwK PiArCS50eXBlID0gVjRMMl9EVl9CVF82NTZfMTEyMCwgXAo+ICsJVjRMMl9JTklUX0JUX1RJTUlO R1MoMjA0OCwgMTA4MCwgMSwgXAo+ICsJCVY0TDJfRFZfSFNZTkNfUE9TX1BPTCB8IFY0TDJfRFZf VlNZTkNfUE9TX1BPTCwgXAo+ICsJCTc0MjUwMDAwLCAyNzQsIDQ0LCAyNzQsIDIsIDUsIDE1LCAz LCA1LCAxNSwgXAo+ICsJCVY0TDJfRFZfQlRfU1REX1NESSkgXAo+ICt9Cj4gKwo+ICsjZGVmaW5l IFhMTlhfVjRMMl9EVl9CVF8yMDQ4WDEwODBJNjAgeyBcCj4gKwkudHlwZSA9IFY0TDJfRFZfQlRf NjU2XzExMjAsIFwKPiArCVY0TDJfSU5JVF9CVF9USU1JTkdTKDIwNDgsIDEwODAsIDEsIFwKPiAr CQlWNEwyX0RWX0hTWU5DX1BPU19QT0wgfCBWNEwyX0RWX1ZTWU5DX1BPU19QT0wsIFwKPiArCQk3 NDI1MDAwMCwgNjYsIDIwLCA2NiwgMiwgNSwgMTUsIDMsIDUsIDE1LCBcCj4gKwkJVjRMMl9EVl9C VF9TVERfU0RJKSBcCj4gK30KPiArCj4gKyNkZWZpbmUgWExOWF9WNEwyX0RWX0JUXzE5MjBYMTA4 MFA0OCB7IFwKPiArCS50eXBlID0gVjRMMl9EVl9CVF82NTZfMTEyMCwgXAo+ICsJVjRMMl9JTklU X0JUX1RJTUlOR1MoMTkyMCwgMTA4MCwgMCwgXAo+ICsJCVY0TDJfRFZfSFNZTkNfUE9TX1BPTCB8 IFY0TDJfRFZfVlNZTkNfUE9TX1BPTCwgXAo+ICsJCTE0ODUwMDAwMCwgNjM4LCA0NCwgMTQ4LCA0 LCA1LCAzNiwgMCwgMCwgMCwgXAo+ICsJCVY0TDJfRFZfQlRfU1REX1NESSkgXAo+ICt9Cj4gKwo+ ICsjZGVmaW5lIFhMTlhfVjRMMl9EVl9CVF8yMDQ4WDEwODBQNDggeyBcCj4gKwkudHlwZSA9IFY0 TDJfRFZfQlRfNjU2XzExMjAsIFwKPiArCVY0TDJfSU5JVF9CVF9USU1JTkdTKDIwNDgsIDEwODAs IDAsIFwKPiArCQlWNEwyX0RWX0hTWU5DX1BPU19QT0wgfCBWNEwyX0RWX1ZTWU5DX1BPU19QT0ws IFwKPiArCQkxNDg1MDAwMDAsIDUxMCwgNDQsIDE0OCwgNCwgNSwgMzYsIDAsIDAsIDAsIFwKPiAr CQlWNEwyX0RWX0JUX1NURF9TREkpIFwKPiArfQo+ICsKPiArI2RlZmluZSBYTE5YX1Y0TDJfRFZf QlRfMjA0OFgxMDgwUDUwIHsgXAo+ICsJLnR5cGUgPSBWNEwyX0RWX0JUXzY1Nl8xMTIwLCBcCj4g KwlWNEwyX0lOSVRfQlRfVElNSU5HUygyMDQ4LCAxMDgwLCAwLCBcCj4gKwkJVjRMMl9EVl9IU1lO Q19QT1NfUE9MIHwgVjRMMl9EVl9WU1lOQ19QT1NfUE9MLCBcCj4gKwkJMTQ4NTAwMDAwLCA0MDAs IDQ0LCAxNDgsIDQsIDUsIDM2LCAwLCAwLCAwLCBcCj4gKwkJVjRMMl9EVl9CVF9TVERfU0RJKSBc Cj4gK30KPiArCj4gKyNkZWZpbmUgWExOWF9WNEwyX0RWX0JUXzIwNDhYMTA4MFA2MCB7IFwKPiAr CS50eXBlID0gVjRMMl9EVl9CVF82NTZfMTEyMCwgXAo+ICsJVjRMMl9JTklUX0JUX1RJTUlOR1Mo MjA0OCwgMTA4MCwgMCwgXAo+ICsJCVY0TDJfRFZfSFNZTkNfUE9TX1BPTCB8IFY0TDJfRFZfVlNZ TkNfUE9TX1BPTCwgXAo+ICsJCTE0ODUwMDAwMCwgODgsIDQ0LCAyMCwgNCwgNSwgMzYsIDAsIDAs IDAsIFwKPiArCQlWNEwyX0RWX0JUX1NURF9TREkpIFwKPiArfQo+ICsKPiArI2RlZmluZSBYTE5Y X1Y0TDJfRFZfQlRfMzg0MFgyMTYwUDQ4IHsgXAo+ICsJLnR5cGUgPSBWNEwyX0RWX0JUXzY1Nl8x MTIwLCBcCj4gKwlWNEwyX0lOSVRfQlRfVElNSU5HUygzODQwLCAyMTYwLCAwLCBcCj4gKwkJVjRM Ml9EVl9IU1lOQ19QT1NfUE9MIHwgVjRMMl9EVl9WU1lOQ19QT1NfUE9MLCBcCj4gKwkJNTk0MDAw MDAwLCAxMjc2LCA4OCwgMjk2LCA4LCAxMCwgNzIsIDAsIDAsIDAsIFwKPiArCQlWNEwyX0RWX0JU X1NURF9TREkpIFwKPiArfQo+ICsKPiArI2RlZmluZSBYTE5YX1Y0TDJfRFZfQlRfNDA5NlgyMTYw UDQ4IHsgXAo+ICsJLnR5cGUgPSBWNEwyX0RWX0JUXzY1Nl8xMTIwLCBcCj4gKwlWNEwyX0lOSVRf QlRfVElNSU5HUyg0MDk2LCAyMTYwLCAwLCBcCj4gKwkJVjRMMl9EVl9IU1lOQ19QT1NfUE9MIHwg VjRMMl9EVl9WU1lOQ19QT1NfUE9MLCBcCj4gKwkJNTk0MDAwMDAwLCAxMDIwLCA4OCwgMjk2LCA4 LCAxMCwgNzIsIDAsIDAsIDAsIFwKPiArCQlWNEwyX0RWX0JUX1NURF9TREkpIFwKPiArfQo+ICsK PiArI2RlZmluZSBYTE5YX1Y0TDJfRFZfQlRfMTkyMFgxMDgwSTQ4IHsgXAo+ICsJLnR5cGUgPSBW NEwyX0RWX0JUXzY1Nl8xMTIwLCBcCj4gKwlWNEwyX0lOSVRfQlRfVElNSU5HUygxOTIwLCAxMDgw LCAxLCBcCj4gKwkJVjRMMl9EVl9IU1lOQ19QT1NfUE9MIHwgVjRMMl9EVl9WU1lOQ19QT1NfUE9M LCBcCj4gKwkJMTQ4NTAwMDAwLCAzNzEsIDg4LCAzNzEsIDIsIDUsIDE1LCAzLCA1LCAxNSwgXAo+ ICsJCVY0TDJfRFZfQlRfU1REX1NESSkgXAo+ICt9Cj4gKwo+ICsjZW5kaWYgLyogX19VQVBJX1hJ TElOWF9TRElSWFNTX0hfXyAqLwo+IGRpZmYgLS1naXQgYS9pbmNsdWRlL3VhcGkvbGludXgveGls aW54LXY0bDItY29udHJvbHMuaCBiL2luY2x1ZGUvdWFwaS9saW51eC94aWxpbngtdjRsMi1jb250 cm9scy5oCj4gaW5kZXggYjY0NDFmZTcwNWM1Li5lOWRlNjVlODI2NDIgMTAwNjQ0Cj4gLS0tIGEv aW5jbHVkZS91YXBpL2xpbnV4L3hpbGlueC12NGwyLWNvbnRyb2xzLmgKPiArKysgYi9pbmNsdWRl L3VhcGkvbGludXgveGlsaW54LXY0bDItY29udHJvbHMuaAo+IEBAIC03MSw0ICs3MSw3MSBAQAo+ ICAvKiBOb2lzZSBsZXZlbCAqLwo+ICAjZGVmaW5lIFY0TDJfQ0lEX1hJTElOWF9UUEdfTk9JU0Vf R0FJTgkJKFY0TDJfQ0lEX1hJTElOWF9UUEcgKyAxNykKPiAgCj4gKy8qCj4gKyAqIFhpbGlueCBT REkgUnggU3Vic3lzdGVtCj4gKyAqLwo+ICsKPiArLyogVGhlIGJhc2UgZm9yIHRoZSBzZGkgcngg ZHJpdmVyIGNvbnRyb2xzLgo+ICsgKiBXZSByZXNlcnZlIDMyIGNvbnRyb2xzIGZvciB0aGlzIGRy aXZlci4KPiArICoKPiArICogVGhlIFY0TDJfQ0lEX1hJTElOWF9TRElSWF9FREhfKiBjb250cm9s cyBhcmUgcHJlc2VudCBvbmx5IGlmCj4gKyAqIEVESCBpcyBlbmFibGVkLgo+ICsgKiBUaGUgY29u dHJvbHMgd2hpY2ggY2FuIGJlIHNldCBzaG91bGQgb25seSBiZSBzZXQgYmVmb3JlIGVuYWJsaW5n Cj4gKyAqIHN0cmVhbWluZy4gVGhlIGNvbnRyb2xzIHdoaWNoIGNhbiBiZSBnb3Qgc2hvdWxkIGJl IGNhbGxlZCB3aGlsZQo+ICsgKiBzdHJlYW1pbmcgdG8gZ2V0IGNvcnJlY3QgdmFsdWVzLgo+ICsg KiBUaGUgVjRMMl9DSURfWElMSU5YX1NESVJYX01PREVfREVURUNUIGNhbiBiZSBjYWxsZWQgd2hl biBxdWVyeSBkdiB0aW1pbmcKPiArICogcmV0dXJucyBhIHZhbGlkIHRpbWluZy4KPiArICovCj4g Kwo+ICsjZGVmaW5lIFY0TDJfQ0lEX1hJTElOWF9TRElSWAkJCShWNEwyX0NJRF9YSUxJTlhfQkFT RSArIDB4MjApCj4gKwo+ICsvKiBGcmFtZXIgQ29udHJvbCB0byBlbmFibGUgb3IgZGlzYWJsZSB0 aGUgZnJhbWVyICovCj4gKyNkZWZpbmUgVjRMMl9DSURfWElMSU5YX1NESVJYX0ZSQU1FUgkJKFY0 TDJfQ0lEX1hJTElOWF9TRElSWCArIDEpCgpUaGlzIGNvbnRyb2wgbmVlZHMgbW9yZSBkb2N1bWVu dGF0aW9uLiBXaGF0IGRvZXMgaXQgZG8sIGFuZCBob3cgc2hvdWxkCml0IGJlIHVzZWQgPwoKPiAr LyoKPiArICogVmlkZW8gTG9jayBXaW5kb3cgQ29udHJvbCB0byBzZXQgdGhlIHZpZGVvIGxvY2sg d2luZG93IHZhbHVlCj4gKyAqIFRoaXMgaXMgdGhlIGFtb3VudCBvZiB0aW1lIHRoZSBtb2RlIGFu ZCB0cmFuc3BvcnQgc3RyZWFtIG5lZWQKPiArICogdG8gYmUgbG9ja2VkIGJlZm9yZSBhIHZpZGVv IGxvY2sgaW50ZXJydXB0IG9jY3Vycy4KPiArICovCj4gKyNkZWZpbmUgVjRMMl9DSURfWElMSU5Y X1NESVJYX1ZJRExPQ0tfV0lORE9XCShWNEwyX0NJRF9YSUxJTlhfU0RJUlggKyAyKQo+ICsvKiBF REggRXJyb3IgTWFzayBDb250cm9sIHRvIGVuYWJsZSBFREggZXJyb3IgY291bnQgKi8KPiArI2Rl ZmluZSBWNEwyX0NJRF9YSUxJTlhfU0RJUlhfRURIX0VSUkNOVF9FTkFCTEUJKFY0TDJfQ0lEX1hJ TElOWF9TRElSWCArIDMpCj4gKy8qCj4gKyAqIE1vZGUgc2VhcmNoIENvbnRyb2wgdG8gcGFzcyB0 aGUgYml0IG1hc2sgb2YgbW9kZXMgdG8gZGV0ZWN0Lgo+ICsgKgo+ICsgKiBiaXQgMCBzZXQgdG8g ZGV0ZWN0IFNEIG1vZGUsCj4gKyAqIGJpdCAxIHNldCB0byBkZXRlY3QgSEQgbW9kZSwKPiArICog Yml0IDIgc2V0IHRvIGRldGVjdCAzRyAoM0dBICYgM0dCKSBtb2RlLAo+ICsgKiBiaXQgMyBzZXQg dG8gZGV0ZWN0IDZHIG1vZGUsCj4gKyAqIGJpdCA0IHNldCB0byBkZXRlY3QgMTJHIGludGVnZXIg ZnJhbWUgcmF0ZSBtb2RlLAo+ICsgKiBiaXQgNSBzZXQgdG8gZGV0ZWN0IDEyRyBmcmFjdGlvbmFs IGZyYW1lIHJhdGUgbW9kZSwKPiArICovCj4gKyNkZWZpbmUgVjRMMl9DSURfWElMSU5YX1NESVJY X1NFQVJDSF9NT0RFUwkoVjRMMl9DSURfWElMSU5YX1NESVJYICsgNCkKPiArLyoKPiArICogR2V0 IERldGVjdGVkIE1vZGUgY29udHJvbAo+ICsgKgo+ICsgKiBDb250cm9sIFZhbHVlIC0gTW9kZSBk ZXRlY3RlZAo+ICsgKiAgICAgICAgMCAgICAgIC0gICAgIFNECj4gKyAqICAgICAgICAxICAgICAg LSAgICAgSEQKPiArICogICAgICAgIDIgICAgICAtICAgICAzRyAoM0dBICYgM0dCKQo+ICsgKiAg ICAgICAgMyAgICAgIC0gICAgIDZHCj4gKyAqICAgICAgICA0ICAgICAgLSAgICAgMTJHIGludGVn ZXIgZnJhbWUgcmF0ZQo+ICsgKiAgICAgICAgNSAgICAgIC0gICAgIDEyRyBmcmFjdGlvbmFsIGZy YW1lIHJhdGUKPiArICovCj4gKyNkZWZpbmUgVjRMMl9DSURfWElMSU5YX1NESVJYX01PREVfREVU RUNUCShWNEwyX0NJRF9YSUxJTlhfU0RJUlggKyA1KQo+ICsvKiBHZXQgbnVtYmVyIG9mIENSQyBl cnJvcnMgc3RhdHVzIGNvbnRyb2wgKi8KPiArI2RlZmluZSBWNEwyX0NJRF9YSUxJTlhfU0RJUlhf Q1JDCQkoVjRMMl9DSURfWElMSU5YX1NESVJYICsgNikKPiArLyogR2V0IEVESCBlcnJvciBjb3Vu dCBjb250cm9sICovCj4gKyNkZWZpbmUgVjRMMl9DSURfWElMSU5YX1NESVJYX0VESF9FUlJDTlQJ KFY0TDJfQ0lEX1hJTElOWF9TRElSWCArIDcpCj4gKy8qIEdldCBFREggc3RhdHVzIGNvbnRyb2wg Ki8KPiArI2RlZmluZSBWNEwyX0NJRF9YSUxJTlhfU0RJUlhfRURIX1NUQVRVUwkoVjRMMl9DSURf WElMSU5YX1NESVJYICsgOCkKPiArLyogR2V0IFRyYW5zcG9ydCBJbnRlcmxhY2VkIHN0YXR1cyB3 aGV0aGVyIGl0IGlzIGludGVybGFjZWQgb3Igbm90ICovCj4gKyNkZWZpbmUgVjRMMl9DSURfWElM SU5YX1NESVJYX1RTX0lTX0lOVEVSTEFDRUQJKFY0TDJfQ0lEX1hJTElOWF9TRElSWCArIDkpCj4g Ky8qIEdldCBudW1iZXIgb2YgQWN0aXZlIFN0cmVhbXMgKi8KPiArI2RlZmluZSBWNEwyX0NJRF9Y SUxJTlhfU0RJUlhfQUNUSVZFX1NUUkVBTVMJKFY0TDJfQ0lEX1hJTElOWF9TRElSWCArIDEwKQo+ ICsvKgo+ICsgKiBHZXQgaWYgdGhlIGRldGVjdGVkIG1vZGUgaXMgM0dCLgo+ICsgKiBDYW4gYmUg dXNlZCB0byBkaXN0aW5ndWlzaGVkIGJldHdlZW4gM0dBIGFuZCAzR0IKPiArICovCj4gKyNkZWZp bmUgVjRMMl9DSURfWElMSU5YX1NESVJYX0lTXzNHQgkJKFY0TDJfQ0lEX1hJTElOWF9TRElSWCAr IDExKQo+ICsKPiAgI2VuZGlmIC8qIF9fVUFQSV9YSUxJTlhfVjRMMl9DT05UUk9MU19IX18gKi8K Ci0tIApSZWdhcmRzLAoKTGF1cmVudCBQaW5jaGFydAoKX19fX19fX19fX19fX19fX19fX19fX19f X19fX19fX19fX19fX19fX19fX19fX18KbGludXgtYXJtLWtlcm5lbCBtYWlsaW5nIGxpc3QKbGlu dXgtYXJtLWtlcm5lbEBsaXN0cy5pbmZyYWRlYWQub3JnCmh0dHA6Ly9saXN0cy5pbmZyYWRlYWQu b3JnL21haWxtYW4vbGlzdGluZm8vbGludXgtYXJtLWtlcm5lbAo=