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=-8.2 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,UNPARSEABLE_RELAY,URIBL_BLOCKED, USER_AGENT_SANE_2 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 25C0EC2BA2B for ; Thu, 9 Apr 2020 02:06:04 +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 C5A6B2084D for ; Thu, 9 Apr 2020 02:06:03 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="ljqFqeLJ"; dkim=fail reason="signature verification failed" (1024-bit key) header.d=mediatek.com header.i=@mediatek.com header.b="DX1YaUNA" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org C5A6B2084D Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=mediatek.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-mediatek-bounces+linux-mediatek=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:MIME-Version:References:In-Reply-To: Date:To:From:Subject:Message-ID:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=Rj2id+uLCMKJf7tiLLKAE+dsfkFKvt8ctZahucAwshw=; b=ljqFqeLJHsGUBa X6XsSQ3wU/QmH/Yzy5y+lMvqijftLubdOxT2InP+yt2CBBDpif6X5B7Z7mA7MzoJQQCrC0nTI9CUs kw3lg+ft8zqf4PWqDCziWCJaYBz/Ae4jmybZPjgSslje/3HN8cXfJ8RvTA597iBby/AKpngc27Scx FI9H8dp5R0vA1JMrr87fVLUfR4W9mfMVjXcXGX5vAsHRvgC5c8J+OVfO9wyJPS/3DrEa02UNkQF8Y IprJ2jwanB1AIhKmitRSARttFD5zDMiYW9U2RDTdw77CpbG9zc27rfE3rgrIG6bsj02ji8u7PCHyu pRAn42CSbbeR1Vyk27PQ==; 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 1jMMZh-0002xv-M2; Thu, 09 Apr 2020 02:05:49 +0000 Received: from mailgw01.mediatek.com ([216.200.240.184]) by bombadil.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1jMMZa-0002xM-VE; Thu, 09 Apr 2020 02:05:46 +0000 X-UUID: d6aea85172a2495ea1478810bc71d6d4-20200408 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=mediatek.com; s=dk; h=Content-Transfer-Encoding:MIME-Version:Content-Type:References:In-Reply-To:Date:CC:To:From:Subject:Message-ID; bh=N4BHJkfgb2NG7TqXytkbwGJ7xKCtAcShB1S8zEkrxYw=; b=DX1YaUNA/JMTb5OLBmuLANiVXjXKG7+9hs3B33mKMStcj0CeFzlw+so0ipcrME9U1LKEzlwVqHWxpUZjhnRpAclditmj/gISB+KFQ5M8pR2SyxbOl9YtigMfkhlFDm9yBCqpEzwO3Z07FwWNzaa2Go/LnTW5MHTvNSUQdouVfjY=; X-UUID: d6aea85172a2495ea1478810bc71d6d4-20200408 Received: from mtkcas67.mediatek.inc [(172.29.193.45)] by mailgw01.mediatek.com (envelope-from ) (musrelay.mediatek.com ESMTP with TLS) with ESMTP id 29781192; Wed, 08 Apr 2020 18:05:35 -0800 Received: from MTKMBS01N2.mediatek.inc (172.21.101.79) by MTKMBS62N2.mediatek.inc (172.29.193.42) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Wed, 8 Apr 2020 19:05:30 -0700 Received: from MTKCAS06.mediatek.inc (172.21.101.30) by mtkmbs01n2.mediatek.inc (172.21.101.79) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Thu, 9 Apr 2020 10:05:24 +0800 Received: from [172.21.84.99] (172.21.84.99) by MTKCAS06.mediatek.inc (172.21.101.73) with Microsoft SMTP Server id 15.0.1497.2 via Frontend Transport; Thu, 9 Apr 2020 10:05:27 +0800 Message-ID: <1586397928.8406.66.camel@mtksdccf07> Subject: Re: [v6, 5/5] media: platform: Add Mediatek ISP P1 V4L2 device driver From: Jungo Lin To: Helen Koike Date: Thu, 9 Apr 2020 10:05:28 +0800 In-Reply-To: <6cd0b8e9-2914-9440-b9ec-dbc7e01de5a1@collabora.com> References: <20191219054930.29513-1-jungo.lin@mediatek.com> <20191219054930.29513-6-jungo.lin@mediatek.com> <6cd0b8e9-2914-9440-b9ec-dbc7e01de5a1@collabora.com> X-Mailer: Evolution 3.2.3-0ubuntu6 MIME-Version: 1.0 X-TM-SNTS-SMTP: 406B4C37B047C3FE289E0D54AC96B2299E065749275A417EA97331CA9A92B2312000:8 X-MTK: N X-BeenThere: linux-mediatek@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: ryan.yu@mediatek.com, frankie.chiu@mediatek.com, laurent.pinchart@ideasonboard.com, robh@kernel.org, Rynn.Wu@mediatek.com, suleiman@chromium.org, Jerry-ch.Chen@mediatek.com, frederic.chen@mediatek.com, linux-media@vger.kernel.org, devicetree@vger.kernel.org, hverkuil-cisco@xs4all.nl, sj.huang@mediatek.com, yuzhao@chromium.org, linux-mediatek@lists.infradead.org, Pi-Hsun Shih , matthias.bgg@gmail.com, mchehab@kernel.org, linux-arm-kernel@lists.infradead.org, Sean.Cheng@mediatek.com, srv_heupstream@mediatek.com, shik@chromium.org, tfiga@chromium.org, zwisler@chromium.org, ddavenport@chromium.org Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Sender: "Linux-mediatek" Errors-To: linux-mediatek-bounces+linux-mediatek=archiver.kernel.org@lists.infradead.org Hi Helen: Thanks for your comments. On Tue, 2020-03-31 at 12:34 -0300, Helen Koike wrote: > Hello Jungo, > > I was taking a look at this patch (thanks for the work), > I didn't look in deep details, but I have some comments, please see > below. I hope it helps. > > On 12/19/19 3:49 AM, Jungo Lin wrote: > > This patch adds the Mediatek ISP P1 HW control device driver. > > It handles the ISP HW configuration, provides interrupt handling and > > initializes the V4L2 device nodes and other V4L2 functions. Moreover, > > implement standard V4L2 video driver that utilizes V4L2 and media > > framework APIs. It supports one media device, one sub-device and > > several video devices during initialization. Moreover, it also connects > > with sensor and seninf drivers with V4L2 async APIs. Communicate with > > co-process via SCP communication to compose ISP registers in the > > firmware. > > > > (The current metadata interface used in meta input and partial > > meta nodes is only a temporary solution to kick off the driver > > development and is not ready to be reviewed yet.) > > > > Signed-off-by: Jungo Lin > > Signed-off-by: Tomasz Figa > > Signed-off-by: Pi-Hsun Shih > > --- > > Changes from v6: > > - Revise help description for VIDEO_MEDIATEK_ISP_PASS1 > > - Apply SCP v21 change in P1 driver by Pi-Hsun Shih > > - Correct auto suspend timer value for suspend/resume issue > > - Increase IPI guard timer to 1 second to avoid false alarm command timeout event > > - Fix KE due to no sen-inf sub-device > > --- > > drivers/media/platform/mtk-isp/Kconfig | 20 + > > .../media/platform/mtk-isp/isp_50/Makefile | 3 + > > .../platform/mtk-isp/isp_50/cam/Makefile | 6 + > > .../platform/mtk-isp/isp_50/cam/mtk_cam-hw.c | 636 +++++ > > .../platform/mtk-isp/isp_50/cam/mtk_cam-hw.h | 64 + > > .../platform/mtk-isp/isp_50/cam/mtk_cam-ipi.h | 222 ++ > > .../mtk-isp/isp_50/cam/mtk_cam-regs.h | 95 + > > .../platform/mtk-isp/isp_50/cam/mtk_cam.c | 2087 +++++++++++++++++ > > I think I would split this file a bit, to separate which code is being used for the subdevice, which for > capture, which for metadata, and what is being used to deal with requests. > > It would make it easier to review imho. > For file structure design, it was reviewed in the previous patch serials. e.g. https://patchwork.kernel.org/patch/10938137/ If you think it is better, I will modify it. > > .../platform/mtk-isp/isp_50/cam/mtk_cam.h | 244 ++ > > It would be nice to chose beween mtk_cam or mtk-isp for naming functions, files and configs, and keep consistency. > > Or maybe something like: > > mtkisp_p1_core.c (with probe, who creates all the media entities, deals with fwnodes, etc) > mtkisp_p1_capture.c > mtkisp_p1_meta.c > mtkisp_p1_isp.c > mtkisp_p1_hw.c (or maybe split this between the other files) > mtkisp_p1_request.c > mtkisp_p1_common.c (?) > > or s/mtkisp_p1/mtk_cam/ > > what do you think? > Ok, I will revise our naming issue for consistency reason. > > 9 files changed, 3377 insertions(+) > > create mode 100644 drivers/media/platform/mtk-isp/Kconfig > > create mode 100644 drivers/media/platform/mtk-isp/isp_50/Makefile > > create mode 100644 drivers/media/platform/mtk-isp/isp_50/cam/Makefile > > create mode 100644 drivers/media/platform/mtk-isp/isp_50/cam/mtk_cam-hw.c > > create mode 100644 drivers/media/platform/mtk-isp/isp_50/cam/mtk_cam-hw.h > > create mode 100644 drivers/media/platform/mtk-isp/isp_50/cam/mtk_cam-ipi.h > > create mode 100644 drivers/media/platform/mtk-isp/isp_50/cam/mtk_cam-regs.h > > create mode 100644 drivers/media/platform/mtk-isp/isp_50/cam/mtk_cam.c > > create mode 100644 drivers/media/platform/mtk-isp/isp_50/cam/mtk_cam.h > > > > diff --git a/drivers/media/platform/mtk-isp/Kconfig b/drivers/media/platform/mtk-isp/Kconfig > > new file mode 100644 > > index 000000000000..f86e1b59ad1e > > --- /dev/null > > +++ b/drivers/media/platform/mtk-isp/Kconfig > > @@ -0,0 +1,20 @@ > > +config VIDEO_MEDIATEK_ISP_PASS1 > > + tristate "Mediatek ISP Pass 1 driver" > > + depends on VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API > > I think you need OF as well > > depends on VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API && OF > > > + depends on ARCH_MEDIATEK > > depends on ARCH_MEDIATEK || COMPILE_TEST > Ok, we will fix this in next patch. > > + select V4L2_FWNODE > > + select VIDEOBUF2_VMALLOC > > + select VIDEOBUF2_DMA_CONTIG > > + select MTK_SCP > > + default n > > + help > > + Pass 1 driver controls 3A (auto-focus, exposure, > > + and white balance) with tuning feature and outputs > > + the captured image buffers in Mediatek's camera system. > > + > > + Choose Y if you want to use Mediatek SoCs to create image > > + captured application such as video recording and still image > > + capturing. > > I would re-word this a bit, since people can use a captured application (and not create one) :) > Ok, I will re-word as "if you want to use image captured application based on Mediatek SoCs for video recording and still image capturing functions" > > + > > + To compile this driver as a module, choose M here; the module > > + will be called mtk-cam-isp. > > diff --git a/drivers/media/platform/mtk-isp/isp_50/Makefile b/drivers/media/platform/mtk-isp/isp_50/Makefile > > new file mode 100644 > > index 000000000000..ce79d283b209 > > --- /dev/null > > +++ b/drivers/media/platform/mtk-isp/isp_50/Makefile > > @@ -0,0 +1,3 @@ > > +# SPDX-License-Identifier: GPL-2.0 > > + > > +obj-$(CONFIG_VIDEO_MEDIATEK_ISP_PASS1) += cam/ > > \ No newline at end of file > > diff --git a/drivers/media/platform/mtk-isp/isp_50/cam/Makefile b/drivers/media/platform/mtk-isp/isp_50/cam/Makefile > > new file mode 100644 > > index 000000000000..53b54d3c26a0 > > --- /dev/null > > +++ b/drivers/media/platform/mtk-isp/isp_50/cam/Makefile > > @@ -0,0 +1,6 @@ > > +# SPDX-License-Identifier: GPL-2.0 > > + > > +mtk-cam-isp-objs += mtk_cam.o > > +mtk-cam-isp-objs += mtk_cam-hw.o > > + > > +obj-$(CONFIG_VIDEO_MEDIATEK_ISP_PASS1) += mtk-cam-isp.o > > \ No newline at end of file > > diff --git a/drivers/media/platform/mtk-isp/isp_50/cam/mtk_cam-hw.c b/drivers/media/platform/mtk-isp/isp_50/cam/mtk_cam-hw.c > > new file mode 100644 > > index 000000000000..4065d0d29b7f > > --- /dev/null > > +++ b/drivers/media/platform/mtk-isp/isp_50/cam/mtk_cam-hw.c > > @@ -0,0 +1,636 @@ > > +// SPDX-License-Identifier: GPL-2.0 > > +// > > +// Copyright (c) 2019 MediaTek Inc. > > + > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > + > > +#include > > Please sort headers alphabetically. > Will fix in next patch. > > + > > +#include "mtk_cam.h" > > +#include "mtk_cam-hw.h" > > +#include "mtk_cam-regs.h" > > + > > +#define MTK_ISP_COMPOSER_MEM_SIZE 0x200000 > > +#define MTK_ISP_CQ_BUFFER_COUNT 3 > > +#define MTK_ISP_CQ_ADDRESS_OFFSET 0x640 > > + > > +/* > > + * > > + * MTK Camera ISP P1 HW supports 3 ISP HW (CAM A/B/C). > > + * The T-put capability of CAM B is the maximum (max line buffer: 5376 pixels) > > + * For CAM A/C, it only supports max line buffer with 3328 pixels. > > + * In current driver, only supports CAM B. > > + * > > + */ > > +#define MTK_ISP_CAM_ID_B 3 > > +#define MTK_ISP_AUTOSUSPEND_DELAY_MS 66 > > +#define MTK_ISP_IPI_SEND_TIMEOUT 1000 > > +#define MTK_ISP_STOP_HW_TIMEOUT (33 * USEC_PER_MSEC) > > + > > +static void isp_tx_frame_worker(struct work_struct *work) > > I suggest prefixing all the function and macros with mtk_isp_, it is easier to know they are not > an external function. > Fix in next patch. > > +{ > > + struct mtk_cam_dev_request *req = > > + container_of(work, struct mtk_cam_dev_request, frame_work); > > + struct mtk_cam_dev *cam = > > + container_of(req->req.mdev, struct mtk_cam_dev, media_dev); > > + struct mtk_isp_p1_device *p1_dev = dev_get_drvdata(cam->dev); > > + > > + scp_ipi_send(p1_dev->scp, SCP_IPI_ISP_FRAME, &req->frame_params, > > + sizeof(req->frame_params), MTK_ISP_IPI_SEND_TIMEOUT); > > +} > > + > > +static void isp_composer_handler(void *data, unsigned int len, void *priv) > > +{ > > + struct mtk_isp_p1_device *p1_dev = (struct mtk_isp_p1_device *)priv; > > + struct device *dev = p1_dev->dev; > > + struct mtk_isp_scp_p1_cmd *ipi_msg; > > + > > + ipi_msg = (struct mtk_isp_scp_p1_cmd *)data; > > + > > + if (len < offsetofend(struct mtk_isp_scp_p1_cmd, ack_info)) { > > + dev_err(dev, "wrong IPI len:%d\n", len); > > + return; > > + } > > + > > + if (ipi_msg->cmd_id != ISP_CMD_ACK || > > + ipi_msg->ack_info.cmd_id != ISP_CMD_FRAME_ACK) > > + return; > > + > > + p1_dev->composed_frame_seq_no = ipi_msg->ack_info.frame_seq_no; > > + dev_dbg(dev, "ack frame_num:%d\n", p1_dev->composed_frame_seq_no); > > +} > > + > > +static int isp_composer_init(struct mtk_isp_p1_device *p1_dev) > > +{ > > + struct device *dev = p1_dev->dev; > > + int ret; > > + > > + ret = scp_ipi_register(p1_dev->scp, SCP_IPI_ISP_CMD, > > + isp_composer_handler, p1_dev); > > + if (ret) { > > + dev_err(dev, "failed to register IPI cmd\n"); > > + return ret; > > + } > > + ret = scp_ipi_register(p1_dev->scp, SCP_IPI_ISP_FRAME, > > + isp_composer_handler, p1_dev); > > + if (ret) { > > + dev_err(dev, "failed to register IPI frame\n"); > > + goto unreg_ipi_cmd; > > + } > > + > > + p1_dev->composer_wq = > > + alloc_ordered_workqueue(dev_name(p1_dev->dev), > > + __WQ_LEGACY | WQ_MEM_RECLAIM | > > + WQ_FREEZABLE); > > + if (!p1_dev->composer_wq) { > > + dev_err(dev, "failed to alloc composer workqueue\n"); > > + goto unreg_ipi_frame; > > + } > > + > > + return 0; > > + > > +unreg_ipi_frame: > > + scp_ipi_unregister(p1_dev->scp, SCP_IPI_ISP_FRAME); > > +unreg_ipi_cmd: > > + scp_ipi_unregister(p1_dev->scp, SCP_IPI_ISP_CMD); > > + > > + return ret; > > +} > > + > > +static void isp_composer_uninit(struct mtk_isp_p1_device *p1_dev) > > +{ > > + destroy_workqueue(p1_dev->composer_wq); > > + scp_ipi_unregister(p1_dev->scp, SCP_IPI_ISP_CMD); > > + scp_ipi_unregister(p1_dev->scp, SCP_IPI_ISP_FRAME); > > +} > > + > > +static void isp_composer_hw_init(struct mtk_isp_p1_device *p1_dev) > > +{ > > + struct mtk_isp_scp_p1_cmd composer_tx_cmd; > > + > > + memset(&composer_tx_cmd, 0, sizeof(composer_tx_cmd)); > > + composer_tx_cmd.cmd_id = ISP_CMD_INIT; > > + composer_tx_cmd.init_param.hw_module = MTK_ISP_CAM_ID_B; > > + > > + /* > > + * Passed coherent reserved memory info. for SCP firmware usage. > > + * This buffer is used for SCP's ISP composer to compose. > > + * The size of is fixed to 0x200000 for the requirement of composer. > > + */ > > + composer_tx_cmd.init_param.cq_addr.iova = p1_dev->composer_iova; > > + composer_tx_cmd.init_param.cq_addr.scp_addr = p1_dev->composer_scp_addr; > > + > > + scp_ipi_send(p1_dev->scp, SCP_IPI_ISP_CMD, &composer_tx_cmd, > > + sizeof(composer_tx_cmd), MTK_ISP_IPI_SEND_TIMEOUT); > > +} > > + > > +static void isp_composer_hw_deinit(struct mtk_isp_p1_device *p1_dev) > > +{ > > + struct mtk_isp_scp_p1_cmd composer_tx_cmd; > > + > > + memset(&composer_tx_cmd, 0, sizeof(composer_tx_cmd)); > > + composer_tx_cmd.cmd_id = ISP_CMD_DEINIT; > > + > > + scp_ipi_send(p1_dev->scp, SCP_IPI_ISP_CMD, &composer_tx_cmd, > > + sizeof(composer_tx_cmd), MTK_ISP_IPI_SEND_TIMEOUT); > > + > > + isp_composer_uninit(p1_dev); > > I think you can copy the 3 lines of this isp_composer_uninit() function here, since > this seems the only place it is being used, and having a deinit and uninit function is > a bit confusing. > Fix in next patch. > > +} > > + > > +void mtk_isp_hw_config(struct mtk_cam_dev *cam, > > + struct p1_config_param *config_param) > > +{ > > + struct mtk_isp_scp_p1_cmd composer_tx_cmd; > > + struct mtk_isp_p1_device *p1_dev = dev_get_drvdata(cam->dev); > > + > > + memset(&composer_tx_cmd, 0, sizeof(composer_tx_cmd)); > > + composer_tx_cmd.cmd_id = ISP_CMD_CONFIG; > > + memcpy(&composer_tx_cmd.config_param, config_param, > > + sizeof(*config_param)); > > + > > + scp_ipi_send(p1_dev->scp, SCP_IPI_ISP_CMD, &composer_tx_cmd, > > + sizeof(composer_tx_cmd), MTK_ISP_IPI_SEND_TIMEOUT); > > +} > > + > > +void mtk_isp_stream(struct mtk_cam_dev *cam, int on) > > I prefer not having a int parameter, this is easier to read: > > mtk_isp_stream_on(cam); > mtk_isp_stream_off(cam); > > or > > mtk_isp_stream(cam, MTK_ISP_STREAM_ON); > mtk_isp_stream(cam, MTK_ISP_STREAM_OFF); > > instead of: > > mtk_isp_stream(cam, 1); > mtk_isp_stream(cam, 0); > > You can add wrappers to this function, and leave this one (that receives the boolean parameter) internal. > Ok, I will choose the method 2. > > +{ > > + struct mtk_isp_scp_p1_cmd composer_tx_cmd; > > + struct mtk_isp_p1_device *p1_dev = dev_get_drvdata(cam->dev); > > + > > + memset(&composer_tx_cmd, 0, sizeof(composer_tx_cmd)); > > + composer_tx_cmd.cmd_id = ISP_CMD_STREAM; > > + composer_tx_cmd.is_stream_on = on; > > s/is_stream_on/is_streaming > Fix in next patch. > > + > > + scp_ipi_send(p1_dev->scp, SCP_IPI_ISP_CMD, &composer_tx_cmd, > > + sizeof(composer_tx_cmd), MTK_ISP_IPI_SEND_TIMEOUT); > > +} > > + > > +int mtk_isp_hw_init(struct mtk_cam_dev *cam) > > +{ > > + struct device *dev = cam->dev; > > + struct mtk_isp_p1_device *p1_dev = dev_get_drvdata(dev); > > + int ret; > > + > > + ret = rproc_boot(p1_dev->rproc_handle); > > + if (ret) { > > + dev_err(dev, "failed to rproc_boot\n"); > > It would be nice to improve this error message for users, how about: > > dev_err(dev, "Initialization of remote processor %s failed", p1_dev->rproc_handle); > > Or maybe even remove this message, since rproc_boot() already have several error messages. > Ok, we will remove the error message. > > + return ret; > > + } > > + > > + ret = isp_composer_init(p1_dev); > > + if (ret) > > should rproc_shutdown() be called here? > Yes, we will fix it. > > + return ret; > > + > > + pm_runtime_get_sync(dev); > > You should check return value here. > Fix in next patch. > > + isp_composer_hw_init(p1_dev); > > + > > + p1_dev->enqueued_frame_seq_no = 0; > > + p1_dev->dequeued_frame_seq_no = 0; > > + p1_dev->composed_frame_seq_no = 0; > > + p1_dev->sof_count = 0; > > + > > + dev_dbg(dev, "%s done\n", __func__); > > + > > + return 0; > > +} > > + > > +int mtk_isp_hw_release(struct mtk_cam_dev *cam) > > +{ > > + struct device *dev = cam->dev; > > + struct mtk_isp_p1_device *p1_dev = dev_get_drvdata(dev); > > + > > + isp_composer_hw_deinit(p1_dev); > > + pm_runtime_mark_last_busy(dev); > > + pm_runtime_put_autosuspend(dev); > > + rproc_shutdown(p1_dev->rproc_handle); > > + > > + dev_dbg(dev, "%s done\n", __func__); > > + > > + return 0; > > +} > > + > > +void mtk_isp_req_enqueue(struct mtk_cam_dev *cam, > > + struct mtk_cam_dev_request *req) > > +{ > > + struct mtk_isp_p1_device *p1_dev = dev_get_drvdata(cam->dev); > > + > > + /* Accumulated frame sequence number */ > > + req->frame_params.frame_seq_no = ++p1_dev->enqueued_frame_seq_no; > > + > > + INIT_WORK(&req->frame_work, isp_tx_frame_worker); > > + queue_work(p1_dev->composer_wq, &req->frame_work); > > + dev_dbg(cam->dev, "enqueue fd:%s frame_seq_no:%d job cnt:%d\n", > > + req->req.debug_str, req->frame_params.frame_seq_no, > > + cam->running_job_count); > > +} > > + > > +static void isp_irq_handle_sof(struct mtk_isp_p1_device *p1_dev, > > + unsigned int dequeued_frame_seq_no) > > +{ > > + dma_addr_t base_addr = p1_dev->composer_iova; > > + struct device *dev = p1_dev->dev; > > + struct mtk_cam_dev_request *req; > > + int composed_frame_seq_no = p1_dev->composed_frame_seq_no; > > + unsigned int addr_offset; > > + > > + /* Send V4L2_EVENT_FRAME_SYNC event */ > > + mtk_cam_dev_event_frame_sync(&p1_dev->cam_dev, dequeued_frame_seq_no); > > + > > + p1_dev->sof_count += 1; > > + /* Save frame information */ > > + p1_dev->dequeued_frame_seq_no = dequeued_frame_seq_no; > > + > > + req = mtk_cam_dev_get_req(&p1_dev->cam_dev, dequeued_frame_seq_no); > > + if (req) > > + req->timestamp = ktime_get_boottime_ns(); > > + > > + /* Update CQ base address if needed */ > > + if (composed_frame_seq_no <= dequeued_frame_seq_no) { > > + dev_dbg(dev, > > + "SOF_INT_ST, no update, cq_num:%d, frame_seq:%d\n", > > + composed_frame_seq_no, dequeued_frame_seq_no); > > + return; > > + } > > + addr_offset = MTK_ISP_CQ_ADDRESS_OFFSET * > > + (dequeued_frame_seq_no % MTK_ISP_CQ_BUFFER_COUNT); > > + writel(base_addr + addr_offset, p1_dev->regs + REG_CQ_THR0_BASEADDR); > > + dev_dbg(dev, > > + "SOF_INT_ST, update next, cq_num:%d, frame_seq:%d cq_addr:0x%x\n", > > + composed_frame_seq_no, dequeued_frame_seq_no, addr_offset); > > +} > > + > > +static void isp_irq_handle_dma_err(struct mtk_isp_p1_device *p1_dev) > > +{ > > + u32 val; > > + > > + dev_err(p1_dev->dev, > > + "IMGO:0x%x, RRZO:0x%x, AAO=0x%x, AFO=0x%x, LMVO=0x%x\n", > > + readl(p1_dev->regs + REG_IMGO_ERR_STAT), > > + readl(p1_dev->regs + REG_RRZO_ERR_STAT), > > + readl(p1_dev->regs + REG_AAO_ERR_STAT), > > + readl(p1_dev->regs + REG_AFO_ERR_STAT), > > + readl(p1_dev->regs + REG_LMVO_ERR_STAT)); > > + dev_err(p1_dev->dev, > > + "LCSO=0x%x, PSO=0x%x, FLKO=0x%x, BPCI:0x%x, LSCI=0x%x\n", > > + readl(p1_dev->regs + REG_LCSO_ERR_STAT), > > + readl(p1_dev->regs + REG_PSO_ERR_STAT), > > + readl(p1_dev->regs + REG_FLKO_ERR_STAT), > > + readl(p1_dev->regs + REG_BPCI_ERR_STAT), > > + readl(p1_dev->regs + REG_LSCI_ERR_STAT)); > > I think if would be better to transfor those into dev_dbg and add a counter > in debugfs. > These error messages are important for debugging. I suggest to keep in dev_err. Moreover, could you give more information about debug counter? I don't get your point. Do you suggest to accumulate the total count of DMA errors? > > + > > + /* Disable DMA error mask to avoid too much error log */ > > + val = readl(p1_dev->regs + REG_CTL_RAW_INT_EN); > > + writel((val & (~DMA_ERR_INT_EN)), p1_dev->regs + REG_CTL_RAW_INT_EN); > > + dev_dbg(p1_dev->dev, "disable DMA error mask:0x%x\n", val); > > +} > > + > > +static irqreturn_t isp_irq_cam(int irq, void *data) > > +{ > > + struct mtk_isp_p1_device *p1_dev = (struct mtk_isp_p1_device *)data; > > + struct device *dev = p1_dev->dev; > > + unsigned int dequeued_frame_seq_no; > > + unsigned int irq_status, err_status, dma_status; > > + unsigned long flags; > > + > > + spin_lock_irqsave(&p1_dev->spinlock_irq, flags); > > + irq_status = readl(p1_dev->regs + REG_CTL_RAW_INT_STAT); > > + err_status = irq_status & INT_ST_MASK_CAM_ERR; > > + dma_status = readl(p1_dev->regs + REG_CTL_RAW_INT2_STAT); > > + dequeued_frame_seq_no = readl(p1_dev->regs + REG_FRAME_SEQ_NUM); > > + spin_unlock_irqrestore(&p1_dev->spinlock_irq, flags); > > + > > + /* > > + * In normal case, the next SOF ISR should come after HW PASS1 DONE ISR. > > + * If these two ISRs come together, print warning msg to hint. > > + */ > > + if ((irq_status & SOF_INT_ST) && (irq_status & HW_PASS1_DON_ST)) > > + dev_dbg(dev, "sof_done block cnt:%d\n", p1_dev->sof_count); > > + > > + /* De-queue frame */ > > + if (irq_status & SW_PASS1_DON_ST) { > > I suppose this means "done streaming"? > Yes, it means the frame buffer is outputed done. > > + mtk_cam_dev_dequeue_req_frame(&p1_dev->cam_dev, > > + p1_dev->dequeued_frame_seq_no); > > + mtk_cam_dev_req_try_queue(&p1_dev->cam_dev); > > + } > > + > > + /* Save frame info. & update CQ address for frame HW en-queue */ > > + if (irq_status & SOF_INT_ST) > > + isp_irq_handle_sof(p1_dev, dequeued_frame_seq_no); > > + > > + /* Check ISP error status */ > > + if (err_status) { > > + dev_err(dev, "int_err:0x%x 0x%x\n", irq_status, err_status); > > + /* Show DMA errors in detail */ > > + if (err_status & DMA_ERR_ST) > > + isp_irq_handle_dma_err(p1_dev); > > + } > > + > > + dev_dbg(dev, "SOF:%d irq:0x%x, dma:0x%x, frame_num:%d\n", > > + p1_dev->sof_count, irq_status, dma_status, > > + dequeued_frame_seq_no); > > + > > + return IRQ_HANDLED; > > +} > > + > > +static int isp_setup_scp_rproc(struct mtk_isp_p1_device *p1_dev, > > + struct platform_device *pdev) > > +{ > > + struct device *dev = p1_dev->dev; > > + dma_addr_t addr; > > + void *ptr; > > Maybe "composer_buffer" would be a better name. > > But is this variable required at all? Can't it be allocated directly to p1_dev->composer_virt_addr ? > Ok, I will use p1_dev->composer_virt_addr directly. > > + int ret; > > + > > + p1_dev->scp = scp_get(pdev); > > + if (!p1_dev->scp) { > > + dev_err(dev, "failed to get scp device\n"); > > + return -ENODEV; > > + } > > + > > + p1_dev->rproc_handle = scp_get_rproc(p1_dev->scp); > > + dev_dbg(dev, "p1 rproc_phandle: 0x%pK\n", p1_dev->rproc_handle); > > + p1_dev->cam_dev.smem_dev = scp_get_device(p1_dev->scp); > > I would rename smem_dev to scp_dev, this helps making it clear when allocating dma buffers > which mapping we are refering to. > Fix in next patch. > > + > > + /* > > + * Allocate coherent reserved memory for SCP firmware usage. > > + * The size of SCP composer's memory is fixed to 0x200000 > > + * for the requirement of firmware. > > + */ > > + ptr = dma_alloc_coherent(p1_dev->cam_dev.smem_dev, > > + MTK_ISP_COMPOSER_MEM_SIZE, &addr, GFP_KERNEL); > > + if (!ptr) { > > + ret = -ENOMEM; > > + goto fail_put_scp; > > + } > > + > > + p1_dev->composer_scp_addr = addr; > > + p1_dev->composer_virt_addr = ptr; > > + dev_dbg(dev, "scp addr:%pad va:%pK\n", &addr, ptr); > > + > > + /* > > + * This reserved memory is also be used by ISP P1 HW. > > + * Need to get iova address for ISP P1 DMA. > > + */ > > + addr = dma_map_resource(dev, addr, MTK_ISP_COMPOSER_MEM_SIZE, > > + DMA_TO_DEVICE, DMA_ATTR_SKIP_CPU_SYNC); > > + if (dma_mapping_error(dev, addr)) { > > + dev_err(dev, "failed to map scp iova\n"); > > + ret = -ENOMEM; > > + goto fail_free_mem; > > + } > > + p1_dev->composer_iova = addr; > > why not rename this to composer_isp_addr ? > Since, afaik, composer_scp_addr is also iova. > > At least my concept of iova (IO virtual address), are an address behind an IOMMU (or bus address to be given to a device). > Ok, we will rename composer_iova to composer_isp_addr. Basically, scp_addr is reserved physical address and it is not behind an IOMMU. > > + dev_dbg(dev, "scp iova addr:%pad\n", &addr); > > + > > + return 0; > > + > > +fail_free_mem: > > + dma_free_coherent(p1_dev->cam_dev.smem_dev, MTK_ISP_COMPOSER_MEM_SIZE, > > + p1_dev->composer_virt_addr, > > + p1_dev->composer_scp_addr); > > + p1_dev->composer_scp_addr = 0; > > +fail_put_scp: > > + scp_put(p1_dev->scp); > > + > > + return ret; > > +} > > + > > +static void isp_teardown_scp_rproc(struct mtk_isp_p1_device *p1_dev) > > +{ > > + dma_free_coherent(p1_dev->cam_dev.smem_dev, MTK_ISP_COMPOSER_MEM_SIZE, > > + p1_dev->composer_virt_addr, > > + p1_dev->composer_scp_addr); > > + p1_dev->composer_scp_addr = 0; > > + scp_put(p1_dev->scp); > > +} > > + > > +static int mtk_isp_pm_suspend(struct device *dev) > > +{ > > + struct mtk_isp_p1_device *p1_dev = dev_get_drvdata(dev); > > + u32 val; > > + int ret; > > + > > + dev_dbg(dev, "- %s\n", __func__); > > + > > + if (pm_runtime_suspended(dev)) > > + return 0; > > + > > + /* Disable ISP's view finder and wait for TG idle if possible */ > > + dev_dbg(dev, "cam suspend, disable VF\n"); > > + val = readl(p1_dev->regs + REG_TG_VF_CON); > > + writel(val & (~TG_VF_CON_VFDATA_EN), p1_dev->regs + REG_TG_VF_CON); > > + readl_poll_timeout_atomic(p1_dev->regs + REG_TG_INTER_ST, val, > > + (val & TG_CS_MASK) == TG_IDLE_ST, > > + USEC_PER_MSEC, MTK_ISP_STOP_HW_TIMEOUT); > > + > > + /* Disable CMOS */ > > + val = readl(p1_dev->regs + REG_TG_SEN_MODE); > > + writel(val & (~TG_SEN_MODE_CMOS_EN), p1_dev->regs + REG_TG_SEN_MODE); > > + > > + /* Force ISP HW to idle */ > > + ret = pm_runtime_force_suspend(dev); > > + if (ret) { > > + dev_err(dev, "failed to force suspend:%d\n", ret); > > + goto reenable_hw; > > + } > > + > > + return 0; > > + > > +reenable_hw: > > + val = readl(p1_dev->regs + REG_TG_SEN_MODE); > > + writel(val | TG_SEN_MODE_CMOS_EN, p1_dev->regs + REG_TG_SEN_MODE); > > + val = readl(p1_dev->regs + REG_TG_VF_CON); > > + writel(val | TG_VF_CON_VFDATA_EN, p1_dev->regs + REG_TG_VF_CON); > > + > > + return ret; > > +} > > + > > +static int mtk_isp_pm_resume(struct device *dev) > > +{ > > + struct mtk_isp_p1_device *p1_dev = dev_get_drvdata(dev); > > + u32 val; > > + int ret; > > + > > + dev_dbg(dev, "- %s\n", __func__); > > + > > + if (pm_runtime_suspended(dev)) > > + return 0; > > + > > + /* Force ISP HW to resume */ > > + ret = pm_runtime_force_resume(dev); > > + if (ret) > > + return ret; > > + > > + /* Enable CMOS */ > > + dev_dbg(dev, "cam resume, enable CMOS/VF\n"); > > + val = readl(p1_dev->regs + REG_TG_SEN_MODE); > > + writel(val | TG_SEN_MODE_CMOS_EN, p1_dev->regs + REG_TG_SEN_MODE); > > + > > + /* Enable VF */ > > + val = readl(p1_dev->regs + REG_TG_VF_CON); > > + writel(val | TG_VF_CON_VFDATA_EN, p1_dev->regs + REG_TG_VF_CON); > > + > > + return 0; > > +} > > + > > +static int mtk_isp_runtime_suspend(struct device *dev) > > +{ > > + struct mtk_isp_p1_device *p1_dev = dev_get_drvdata(dev); > > + > > + dev_dbg(dev, "%s:disable clock\n", __func__); > > + clk_bulk_disable_unprepare(p1_dev->num_clks, p1_dev->clks); > > + > > + return 0; > > +} > > + > > +static int mtk_isp_runtime_resume(struct device *dev) > > +{ > > + struct mtk_isp_p1_device *p1_dev = dev_get_drvdata(dev); > > + int ret; > > + > > + dev_dbg(dev, "%s:enable clock\n", __func__); > > + ret = clk_bulk_prepare_enable(p1_dev->num_clks, p1_dev->clks); > > + if (ret) { > > + dev_err(dev, "failed to enable clock:%d\n", ret); > > + return ret; > > + } > > + > > + return 0; > > +} > > + > > +static int mtk_isp_probe(struct platform_device *pdev) > > +{ > > + /* List of clocks required by isp cam */ > > + static const char * const clk_names[] = { > > + "camsys_cam_cgpdn", "camsys_camtg_cgpdn" > > + }; > > + struct mtk_isp_p1_device *p1_dev; > > + struct device *dev = &pdev->dev; > > + struct resource *res; > > + int irq, ret, i; > > + > > + p1_dev = devm_kzalloc(dev, sizeof(*p1_dev), GFP_KERNEL); > > + if (!p1_dev) > > + return -ENOMEM; > > + > > + p1_dev->dev = dev; > > + dev_set_drvdata(dev, p1_dev); > > + > > + /* > > + * Now only support single CAM with CAM B. > > + * Get CAM B register base with CAM B index. > > + * Support multiple CAMs in future. > > + */ > > + res = platform_get_resource(pdev, IORESOURCE_MEM, MTK_ISP_CAM_ID_B); > > + p1_dev->regs = devm_ioremap_resource(dev, res); > > + if (IS_ERR(p1_dev->regs)) { > > + dev_err(dev, "failed to map reister base\n"); > > s/reister/register > Fix in next patch. > > + return PTR_ERR(p1_dev->regs); > > + } > > + dev_dbg(dev, "cam, map_addr=0x%pK\n", p1_dev->regs); > > + > > + /* > > + * The cam_sys unit only supports reg., but has no IRQ support. > > + * The reg. & IRQ index is shifted with 1 for CAM B in DTS. > > + */ > > + irq = platform_get_irq(pdev, MTK_ISP_CAM_ID_B - 1); > > + if (!irq) { > > + dev_err(dev, "failed to get irq\n"); > > + return -ENODEV; > > + } > > + ret = devm_request_irq(dev, irq, isp_irq_cam, 0, dev_name(dev), > > + p1_dev); > > + if (ret) { > > + dev_err(dev, "failed to request irq=%d\n", irq); > > + return ret; > > + } > > + dev_dbg(dev, "registered irq=%d\n", irq); > > + spin_lock_init(&p1_dev->spinlock_irq); > > + > > + p1_dev->num_clks = ARRAY_SIZE(clk_names); > > + p1_dev->clks = devm_kcalloc(dev, p1_dev->num_clks, > > + sizeof(*p1_dev->clks), GFP_KERNEL); > > + if (!p1_dev->clks) > > + return -ENOMEM; > > + > > + for (i = 0; i < p1_dev->num_clks; ++i) > > + p1_dev->clks[i].id = clk_names[i]; > > + > > + ret = devm_clk_bulk_get(dev, p1_dev->num_clks, p1_dev->clks); > > + if (ret) { > > + dev_err(dev, "failed to get isp cam clock:%d\n", ret); > > + return ret; > > + } > > + > > + ret = isp_setup_scp_rproc(p1_dev, pdev); > > + if (ret) > > + return ret; > > + > > + pm_runtime_set_autosuspend_delay(dev, MTK_ISP_AUTOSUSPEND_DELAY_MS); > > + pm_runtime_use_autosuspend(dev); > > + pm_runtime_enable(dev); > > + > > + /* Initialize the v4l2 common part */ > > + ret = mtk_cam_dev_init(pdev, &p1_dev->cam_dev); > > + if (ret) { > > + isp_teardown_scp_rproc(p1_dev); > > + return ret; > > + } > > + > > + return 0; > > +} > > + > > +static int mtk_isp_remove(struct platform_device *pdev) > > +{ > > + struct device *dev = &pdev->dev; > > + struct mtk_isp_p1_device *p1_dev = dev_get_drvdata(dev); > > + > > + mtk_cam_dev_cleanup(&p1_dev->cam_dev); > > + pm_runtime_dont_use_autosuspend(dev); > > + pm_runtime_disable(dev); > > + dma_unmap_page_attrs(dev, p1_dev->composer_iova, > > + MTK_ISP_COMPOSER_MEM_SIZE, DMA_TO_DEVICE, > > + DMA_ATTR_SKIP_CPU_SYNC); > > + isp_teardown_scp_rproc(p1_dev); > > + > > + return 0; > > +} > > + > > +static const struct dev_pm_ops mtk_isp_pm_ops = { > > + SET_SYSTEM_SLEEP_PM_OPS(mtk_isp_pm_suspend, mtk_isp_pm_resume) > > + SET_RUNTIME_PM_OPS(mtk_isp_runtime_suspend, mtk_isp_runtime_resume, > > + NULL) > > +}; > > + > > +static const struct of_device_id mtk_isp_of_ids[] = { > > + {.compatible = "mediatek,mt8183-camisp",}, > > + {} > > +}; > > +MODULE_DEVICE_TABLE(of, mtk_isp_of_ids); > > + > > +static struct platform_driver mtk_isp_driver = { > > + .probe = mtk_isp_probe, > > + .remove = mtk_isp_remove, > > + .driver = { > > + .name = "mtk-cam-p1", > > + .of_match_table = of_match_ptr(mtk_isp_of_ids), > > + .pm = &mtk_isp_pm_ops, > > + } > > +}; > > + > > +module_platform_driver(mtk_isp_driver); > > + > > +MODULE_DESCRIPTION("Mediatek ISP P1 driver"); > > +MODULE_LICENSE("GPL v2"); > > diff --git a/drivers/media/platform/mtk-isp/isp_50/cam/mtk_cam-hw.h b/drivers/media/platform/mtk-isp/isp_50/cam/mtk_cam-hw.h > > new file mode 100644 > > index 000000000000..837662f92a5e > > --- /dev/null > > +++ b/drivers/media/platform/mtk-isp/isp_50/cam/mtk_cam-hw.h > > This header file is really short, why not merge it with mtk_cam.h (that is small too) and call it mtk_isp_common.h or mtk_cam_common? > Ok, revise in next patch. > > @@ -0,0 +1,64 @@ > > +/* SPDX-License-Identifier: GPL-2.0 */ > > +/* > > + * Copyright (c) 2019 MediaTek Inc. > > + */ > > + > > +#ifndef __MTK_CAM_HW_H__ > > +#define __MTK_CAM_HW_H__ > > + > > +#include > > + > > +#include "mtk_cam.h" > > +#include "mtk_cam-ipi.h" > > + > > +/* > > + * struct mtk_isp_p1_device - the Mediatek ISP P1 device information > > + * > > + * @dev: Pointer to device. > > + * @scp_pdev: Pointer to SCP platform device. > > + * @rproc_handle: Pointer to new remoteproc instance. > > + * @cam_dev: Embedded struct cam_dev > > + * @regs: Camera ISP HW base register address > > + * @num_clks: The number of driver's clocks > > + * @clks: The clock data array > > + * @spinlock_irq: Used to protect register read/write data > > + * @enqueued_frame_seq_no: Frame sequence number of enqueued frame > > + * @dequeued_frame_seq_no: Frame sequence number of dequeued frame > > + * @composed_frame_seq_no: Frame sequence number of composed frame > > + * @timestamp: Frame timestamp in ns > > + * @sof_count: SOF counter > > + * @composer_wq: The work queue for frame request composing > > + * @composer_scp_addr: SCP address of ISP composer memory > > + * @composer_iova: DMA address of ISP composer memory > > + * @virt_addr: Virtual address of ISP composer memory > > + * > > + */ > > +struct mtk_isp_p1_device { > > + struct device *dev; > > + struct mtk_scp *scp; > > + struct rproc *rproc_handle; > > + struct mtk_cam_dev cam_dev; > > + void __iomem *regs; > > + unsigned int num_clks; > > + struct clk_bulk_data *clks; > > + /* Used to protect register read/write data */ > > + spinlock_t spinlock_irq; > > + unsigned int enqueued_frame_seq_no; > > + unsigned int dequeued_frame_seq_no; > > + unsigned int composed_frame_seq_no; > > + u8 sof_count; > > + struct workqueue_struct *composer_wq; > > + dma_addr_t composer_scp_addr; > > + dma_addr_t composer_iova; > > + void *composer_virt_addr; > > +}; > > + > > +int mtk_isp_hw_init(struct mtk_cam_dev *cam_dev); > > +int mtk_isp_hw_release(struct mtk_cam_dev *cam_dev); > > +void mtk_isp_hw_config(struct mtk_cam_dev *cam_dev, > > + struct p1_config_param *config_param); > > +void mtk_isp_stream(struct mtk_cam_dev *cam_dev, int on); > > +void mtk_isp_req_enqueue(struct mtk_cam_dev *cam_dev, > > + struct mtk_cam_dev_request *req); > > It would be nice to have docs for these too. > Ok, add in next patch. > > + > > +#endif /* __MTK_CAM_HW_H__ */ > > diff --git a/drivers/media/platform/mtk-isp/isp_50/cam/mtk_cam-ipi.h b/drivers/media/platform/mtk-isp/isp_50/cam/mtk_cam-ipi.h > > new file mode 100644 > > index 000000000000..981b634dd91f > > --- /dev/null > > +++ b/drivers/media/platform/mtk-isp/isp_50/cam/mtk_cam-ipi.h > > I'm skipping this file, since, if I understand correctly, this is not ready for review right? > I think this file is ready for review. > > @@ -0,0 +1,222 @@ > > +/* SPDX-License-Identifier: GPL-2.0 */ > > +/* > > + * Copyright (c) 2019 MediaTek Inc. > > + */ > > + > > +#ifndef __MTK_CAM_IPI_H__ > > +#define __MTK_CAM_IPI_H__ > > + > > +#include > > + > > +/* > > + * struct img_size - Image size information. > > + * > > + * @w: Image width, the unit is pixel > > + * @h: Image height, the unit is pixel > > + * @xsize: Bytes per line based on width. > > + * @stride: Bytes per line when changing line. > > + * Stride is based on xsize + HW constrain(byte align). > > + * > > + */ > > +struct img_size { > > + u32 w; > > + u32 h; > > + u32 xsize; > > + u32 stride; > > +} __packed; > > + > > +/* > > + * struct p1_img_crop - image corp information > > + * > > + * @left: The left of crop area. > > + * @top: The top of crop area. > > + * @width: The width of crop area. > > + * @height: The height of crop area. > > + * > > + */ > > +struct p1_img_crop { > > + u32 left; > > + u32 top; > > + u32 width; > > + u32 height; > > +} __packed; > > + > > +/* > > + * struct dma_buffer - DMA buffer address information > > + * > > + * @iova: DMA address for ISP DMA device > > + * @scp_addr: SCP address for external co-process unit > > + * > > + */ > > +struct dma_buffer { > > + u32 iova; > > I would rename this to isp_addr, since scp_addr is also iova (at least this is the way I understand). > Ok, revise in next patch. > > + u32 scp_addr; > > +} __packed; > > + > > +/* > > + * struct p1_img_output - ISP P1 image output information > > + * > > + * @buffer: DMA buffer address of image. > > + * @size: The image size configuration. > > + * @crop: The crop configuration. > > + * @pixel_bits: The bits per image pixel. > > + * @img_fmt: The image format. > > + * > > + */ > > +struct p1_img_output { > > + struct dma_buffer buffer; > > + struct img_size size; > > + struct p1_img_crop crop; > > + u8 pixel_bits; > > + u32 img_fmt; > > +} __packed; > > + > > +/* > > + * struct cfg_in_param - Image input parameters structure. > > + * Normally, it comes from sensor information. > > + * > > + * @continuous: Indicate the sensor mode. Continuous or single shot. > > + * @subsample: Indicate to enables SOF subsample or not. > > + * @pixel_mode: Describe 1/2/4 pixels per clock cycle. > > + * @data_pattern: Describe input data pattern. > > + * @raw_pixel_id: Bayer sequence. > > + * @tg_fps: The fps rate of TG (time generator). > > + * @img_fmt: The image format of input source. > > + * @p1_img_crop: The crop configuration of input source. > > + * > > + */ > > +struct cfg_in_param { > > + u8 continuous; > > + u8 subsample; > > + u8 pixel_mode; > > + u8 data_pattern; > > + u8 raw_pixel_id; > > + u16 tg_fps; > > + u32 img_fmt; > > + struct p1_img_crop crop; > > +} __packed; > > + > > +/* > > + * struct cfg_main_out_param - The image output parameters of main stream. > > + * > > + * @bypass: Indicate this device is enabled or disabled or not. > > + * @pure_raw: Indicate the image path control. > > + * True: pure raw > > + * False: processing raw > > + * @pure_raw_pack: Indicate the image is packed or not. > > + * True: packed mode > > + * False: unpacked mode > > + * @p1_img_output: The output image information. > > + * > > + */ > > +struct cfg_main_out_param { > > + u8 bypass; > > + u8 pure_raw; > > + u8 pure_raw_pack; > > + struct p1_img_output output; > > +} __packed; > > + > > +/* > > + * struct cfg_resize_out_param - The image output parameters of > > + * packed out stream. > > + * > > + * @bypass: Indicate this device is enabled or disabled or not. > > + * @p1_img_output: The output image information. > > + * > > + */ > > +struct cfg_resize_out_param { > > + u8 bypass; > > + struct p1_img_output output; > > +} __packed; > > + > > +/* > > + * struct p1_config_param - ISP P1 configuration parameters. > > + * > > + * @cfg_in_param: The Image input parameters. > > + * @cfg_main_param: The main output image parameters. > > + * @cfg_resize_out_param: The packed output image parameters. > > + * @enabled_dmas: The enabled DMA port information. > > + * > > + */ > > +struct p1_config_param { > > + struct cfg_in_param cfg_in_param; > > + struct cfg_main_out_param cfg_main_param; > > + struct cfg_resize_out_param cfg_resize_param; > > + u32 enabled_dmas; > > +} __packed; > > + > > +/* > > + * struct P1_meta_frame - ISP P1 meta frame information. > > + * > > + * @enabled_dma: The enabled DMA port information. > > + * @vb_index: The VB2 index of meta buffer. > > + * @meta_addr: DMA buffer address of meta buffer. > > + * > > + */ > > +struct P1_meta_frame { > > + u32 enabled_dma; > > + u32 vb_index; > > + struct dma_buffer meta_addr; > > +} __packed; > > + > > +/* > > + * struct isp_init_info - ISP P1 composer init information. > > + * > > + * @hw_module: The ISP Camera HW module ID. > > + * @cq_addr: The DMA address of composer memory. > > + * > > + */ > > +struct isp_init_info { > > + u8 hw_module; > > + struct dma_buffer cq_addr; > > +} __packed; > > + > > +/* > > + * struct isp_ack_info - ISP P1 IPI command ack information. > > + * > > + * @cmd_id: The IPI command ID is acked. > > + * @frame_seq_no: The IPI frame sequence number is acked. > > + * > > + */ > > +struct isp_ack_info { > > + u8 cmd_id; > > + u32 frame_seq_no; > > +} __packed; > > + > > +/* > > + * The IPI command enumeration. > > + */ > > +enum mtk_isp_scp_cmds { > > + ISP_CMD_INIT, > > + ISP_CMD_CONFIG, > > + ISP_CMD_STREAM, > > + ISP_CMD_DEINIT, > > + ISP_CMD_ACK, > > + ISP_CMD_FRAME_ACK, > > + ISP_CMD_RESERVED, > > +}; > > + > > +/* > > + * struct mtk_isp_scp_p1_cmd - ISP P1 IPI command strcture. > > + * > > + * @cmd_id: The IPI command ID. > > + * @init_param: The init formation for ISP_CMD_INIT. > > + * @config_param: The cmd configuration for ISP_CMD_CONFIG. > > + * @enabled_dmas: The meta configuration information for ISP_CMD_CONFIG_META. > > + * @is_stream_on: The stream information for ISP_CMD_STREAM. > > + * @ack_info: The cmd ack. information for ISP_CMD_ACK. > > + * > > + */ > > +struct mtk_isp_scp_p1_cmd { > > + u8 cmd_id; > > + union { > > + struct isp_init_info init_param; > > + struct p1_config_param config_param; > > + u32 enabled_dmas; > > + struct P1_meta_frame meta_frame; > > + u8 is_stream_on; > > + struct isp_ack_info ack_info; > > + }; > > +} __packed; > > + > > +#endif /* __MTK_CAM_IPI_H__ */ > > diff --git a/drivers/media/platform/mtk-isp/isp_50/cam/mtk_cam-regs.h b/drivers/media/platform/mtk-isp/isp_50/cam/mtk_cam-regs.h > > new file mode 100644 > > index 000000000000..ab2277f45fa4 > > --- /dev/null > > +++ b/drivers/media/platform/mtk-isp/isp_50/cam/mtk_cam-regs.h > > @@ -0,0 +1,95 @@ > > +/* SPDX-License-Identifier: GPL-2.0 */ > > +/* > > + * Copyright (c) 2019 MediaTek Inc. > > + */ > > + > > +#ifndef __MTK_CAM_REGS_H__ > > +#define __MTK_CAM_REGS_H__ > > + > > +/* ISP interrupt enable */ > > +#define REG_CTL_RAW_INT_EN 0x0020 > > +#define DMA_ERR_INT_EN BIT(29) > > + > > +/* ISP interrupt status */ > > +#define REG_CTL_RAW_INT_STAT 0x0024 > > +#define VS_INT_ST BIT(0) > > +#define TG_ERR_ST BIT(4) > > +#define TG_GBERR_ST BIT(5) > > +#define CQ_CODE_ERR_ST BIT(6) > > +#define CQ_APB_ERR_ST BIT(7) > > +#define CQ_VS_ERR_ST BIT(8) > > +#define HW_PASS1_DON_ST BIT(11) > > +#define SOF_INT_ST BIT(12) > > +#define AMX_ERR_ST BIT(15) > > +#define RMX_ERR_ST BIT(16) > > +#define BMX_ERR_ST BIT(17) > > +#define RRZO_ERR_ST BIT(18) > > +#define AFO_ERR_ST BIT(19) > > +#define IMGO_ERR_ST BIT(20) > > +#define AAO_ERR_ST BIT(21) > > +#define PSO_ERR_ST BIT(22) > > +#define LCSO_ERR_ST BIT(23) > > +#define BNR_ERR_ST BIT(24) > > +#define LSCI_ERR_ST BIT(25) > > +#define DMA_ERR_ST BIT(29) > > +#define SW_PASS1_DON_ST BIT(30) > > + > > +/* ISP interrupt 2 status */ > > +#define REG_CTL_RAW_INT2_STAT 0x0034 > > +#define AFO_DONE_ST BIT(5) > > +#define AAO_DONE_ST BIT(7) > > + > > +/* Configures sensor mode */ > > +#define REG_TG_SEN_MODE 0x0230 > > +#define TG_SEN_MODE_CMOS_EN BIT(0) > > + > > +/* View finder mode control */ > > +#define REG_TG_VF_CON 0x0234 > > +#define TG_VF_CON_VFDATA_EN BIT(0) > > + > > +/* View finder mode control */ > > +#define REG_TG_INTER_ST 0x026c > > +#define TG_CS_MASK 0x3f00 > > +#define TG_IDLE_ST BIT(8) > > + > > +/* IMGO error status register */ > > +#define REG_IMGO_ERR_STAT 0x1360 > > +/* RRZO error status register */ > > +#define REG_RRZO_ERR_STAT 0x1364 > > +/* AAO error status register */ > > +#define REG_AAO_ERR_STAT 0x1368 > > +/* AFO error status register */ > > +#define REG_AFO_ERR_STAT 0x136c > > +/* LCSO error status register */ > > +#define REG_LCSO_ERR_STAT 0x1370 > > +/* BPCI error status register */ > > +#define REG_BPCI_ERR_STAT 0x137c > > +/* LSCI error status register */ > > +#define REG_LSCI_ERR_STAT 0x1384 > > +/* LMVO error status register */ > > +#define REG_LMVO_ERR_STAT 0x1390 > > +/* FLKO error status register */ > > +#define REG_FLKO_ERR_STAT 0x1394 > > +/* PSO error status register */ > > +#define REG_PSO_ERR_STAT 0x13a0 > > + > > +/* CQ0 base address */ > > +#define REG_CQ_THR0_BASEADDR 0x0198 > > +/* Frame sequence number */ > > +#define REG_FRAME_SEQ_NUM 0x13b8 > > + > > +/* IRQ Error Mask */ > > +#define INT_ST_MASK_CAM_ERR ( \ > > + TG_ERR_ST |\ > > + TG_GBERR_ST |\ > > + CQ_CODE_ERR_ST |\ > > + CQ_APB_ERR_ST |\ > > + CQ_VS_ERR_ST |\ > > + BNR_ERR_ST |\ > > + RMX_ERR_ST |\ > > + BMX_ERR_ST |\ > > + BNR_ERR_ST |\ > > + LSCI_ERR_ST |\ > > + DMA_ERR_ST) > > + > > I would add a common prefix all the registers in the file. > > Also, add some docs to know what those acronyms means would be nice. > Ok, add this in next patch. > > +#endif /* __MTK_CAM_REGS_H__ */ > > diff --git a/drivers/media/platform/mtk-isp/isp_50/cam/mtk_cam.c b/drivers/media/platform/mtk-isp/isp_50/cam/mtk_cam.c > > new file mode 100644 > > index 000000000000..23fdb8b4abc5 > > --- /dev/null > > +++ b/drivers/media/platform/mtk-isp/isp_50/cam/mtk_cam.c > > @@ -0,0 +1,2087 @@ > > +// SPDX-License-Identifier: GPL-2.0 > > +// Copyright (c) 2019 MediaTek Inc. > > + > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > Please sort in alphabetical order. > Fix in next patch > > + > > +#include "mtk_cam.h" > > +#include "mtk_cam-hw.h" > > + > > +#define R_IMGO BIT(0) > > +#define R_RRZO BIT(1) > > +#define R_AAO BIT(3) > > +#define R_AFO BIT(4) > > +#define R_LCSO BIT(5) > > +#define R_LMVO BIT(7) > > +#define R_FLKO BIT(8) > > +#define R_PSO BIT(10) > > It would be nice to have better names of docs of what these means. > Add in next patch > > + > > +#define MTK_ISP_ONE_PIXEL_MODE 1 > > +#define MTK_ISP_MIN_RESIZE_RATIO 6 > > +#define MTK_ISP_MAX_RUNNING_JOBS 3 > > + > > +#define MTK_CAM_CIO_PAD_SRC 4 > > +#define MTK_CAM_CIO_PAD_SINK 11 > > + > > +static inline struct mtk_cam_video_device * > > +file_to_mtk_cam_node(struct file *__file) > > +{ > > + return container_of(video_devdata(__file), > > + struct mtk_cam_video_device, vdev); > > +} > > + > > +static inline struct mtk_cam_video_device * > > +mtk_cam_vbq_to_vdev(struct vb2_queue *__vq) > > no need for the underscore in __vq > Revise in next patch > > +{ > > + return container_of(__vq, struct mtk_cam_video_device, vbq); > > +} > > + > > +static inline struct mtk_cam_dev_request * > > +mtk_cam_req_to_dev_req(struct media_request *__req) > > +{ > > + return container_of(__req, struct mtk_cam_dev_request, req); > > +} > > + > > +static inline struct mtk_cam_dev_buffer * > > +mtk_cam_vb2_buf_to_dev_buf(struct vb2_buffer *__vb) > > +{ > > + return container_of(__vb, struct mtk_cam_dev_buffer, vbb.vb2_buf); > > +} > > + > > +static void mtk_cam_dev_job_done(struct mtk_cam_dev *cam, > > + struct mtk_cam_dev_request *req, > > + enum vb2_buffer_state state) > > +{ > > + struct media_request_object *obj, *obj_prev; > > + unsigned long flags; > > + u64 ts_eof = ktime_get_boottime_ns(); > > + > > + if (!cam->streaming) > > s/streaming/is_streaming > > this makes a bit more intuitive of what the the boolean means. > Revise in next patch > > + return; > > + > > + dev_dbg(cam->dev, "job done request:%s frame_seq:%d state:%d\n", > > + req->req.debug_str, req->frame_params.frame_seq_no, state); > > + > > + list_for_each_entry_safe(obj, obj_prev, &req->req.objects, list) { > > + struct vb2_buffer *vb; > > + struct mtk_cam_dev_buffer *buf; > > + struct mtk_cam_video_device *node; > > + > > + if (!vb2_request_object_is_buffer(obj)) > > + continue; > > + vb = container_of(obj, struct vb2_buffer, req_obj); > > + buf = mtk_cam_vb2_buf_to_dev_buf(vb); > > + node = mtk_cam_vbq_to_vdev(vb->vb2_queue); > > + spin_lock_irqsave(&node->buf_list_lock, flags); > > + list_del(&buf->list); > > + spin_unlock_irqrestore(&node->buf_list_lock, flags); > > + buf->vbb.sequence = req->frame_params.frame_seq_no; > > + if (V4L2_TYPE_IS_OUTPUT(vb->vb2_queue->type)) > > + vb->timestamp = ts_eof; > > + else > > + vb->timestamp = req->timestamp; > > + vb2_buffer_done(&buf->vbb.vb2_buf, state); > > + } > > +} > > + > > +struct mtk_cam_dev_request *mtk_cam_dev_get_req(struct mtk_cam_dev *cam, > > + unsigned int frame_seq_no) > > +{ > > + struct mtk_cam_dev_request *req, *req_prev; > > + unsigned long flags; > > + > > + spin_lock_irqsave(&cam->running_job_lock, flags); > > + list_for_each_entry_safe(req, req_prev, &cam->running_job_list, list) { > > + dev_dbg(cam->dev, "frame_seq:%d, get frame_seq:%d\n", > > + req->frame_params.frame_seq_no, frame_seq_no); > > + > > + /* Match by the en-queued request number */ > > + if (req->frame_params.frame_seq_no == frame_seq_no) { > > + spin_unlock_irqrestore(&cam->running_job_lock, flags); > > + return req; > > + } > > + } > > + spin_unlock_irqrestore(&cam->running_job_lock, flags); > > + > > + return NULL; > > +} > > + > > +void mtk_cam_dev_dequeue_req_frame(struct mtk_cam_dev *cam, > > + unsigned int frame_seq_no) > > +{ > > + struct mtk_cam_dev_request *req, *req_prev; > > + unsigned long flags; > > + > > + spin_lock_irqsave(&cam->running_job_lock, flags); > > + list_for_each_entry_safe(req, req_prev, &cam->running_job_list, list) { > > + dev_dbg(cam->dev, "frame_seq:%d, de-queue frame_seq:%d\n", > > + req->frame_params.frame_seq_no, frame_seq_no); > > + > > + /* Match by the en-queued request number */ > > + if (req->frame_params.frame_seq_no == frame_seq_no) { > > + cam->running_job_count--; > > + /* Pass to user space */ > > + mtk_cam_dev_job_done(cam, req, VB2_BUF_STATE_DONE); > > + list_del(&req->list); > > + break; > > + } else if (req->frame_params.frame_seq_no < frame_seq_no) { > > + cam->running_job_count--; > > + /* Pass to user space for frame drop */ > > + mtk_cam_dev_job_done(cam, req, VB2_BUF_STATE_ERROR); > > + dev_warn(cam->dev, "frame_seq:%d drop\n", > > + req->frame_params.frame_seq_no); > > maybe a counter in debugfs instead of the warning. > Do you mean to add counter to accumulate the total count of drop frames? Could we add this and also keep this warning message? > > + list_del(&req->list); > > + } else { > > + break; > > + } > > + } > > + spin_unlock_irqrestore(&cam->running_job_lock, flags); > > +} > > + > > +static void mtk_cam_dev_req_cleanup(struct mtk_cam_dev *cam) > > +{ > > + struct mtk_cam_dev_request *req, *req_prev; > > + unsigned long flags; > > + > > + dev_dbg(cam->dev, "%s\n", __func__); > > + > > + spin_lock_irqsave(&cam->pending_job_lock, flags); > > + list_for_each_entry_safe(req, req_prev, &cam->pending_job_list, list) > > + list_del(&req->list); > > + spin_unlock_irqrestore(&cam->pending_job_lock, flags); > > + > > + spin_lock_irqsave(&cam->running_job_lock, flags); > > + list_for_each_entry_safe(req, req_prev, &cam->running_job_list, list) > > + list_del(&req->list); > > + spin_unlock_irqrestore(&cam->running_job_lock, flags); > > +} > > + > > +void mtk_cam_dev_req_try_queue(struct mtk_cam_dev *cam) > > +{ > > + struct mtk_cam_dev_request *req, *req_prev; > > + unsigned long flags; > > + > > + if (!cam->streaming) { > > + dev_dbg(cam->dev, "stream is off\n"); > > + return; > > + } > > + > > + spin_lock_irqsave(&cam->pending_job_lock, flags); > > + spin_lock_irqsave(&cam->running_job_lock, flags); > > + list_for_each_entry_safe(req, req_prev, &cam->pending_job_list, list) { > > + if (cam->running_job_count >= MTK_ISP_MAX_RUNNING_JOBS) { > > + dev_dbg(cam->dev, "jobs are full\n"); > > + break; > > + } > > + cam->running_job_count++; > > + list_del(&req->list); > > + list_add_tail(&req->list, &cam->running_job_list); > > list_move_tail() can be used. > Revised in this patch. > > + mtk_isp_req_enqueue(cam, req); > > + } > > + spin_unlock_irqrestore(&cam->running_job_lock, flags); > > + spin_unlock_irqrestore(&cam->pending_job_lock, flags); > > +} > > + > > +static struct media_request *mtk_cam_req_alloc(struct media_device *mdev) > > +{ > > + struct mtk_cam_dev_request *cam_dev_req; > > + > > + cam_dev_req = kzalloc(sizeof(*cam_dev_req), GFP_KERNEL); > > + > > + return &cam_dev_req->req; > > +} > > + > > +static void mtk_cam_req_free(struct media_request *req) > > +{ > > + struct mtk_cam_dev_request *cam_dev_req = mtk_cam_req_to_dev_req(req); > > + > > + kfree(cam_dev_req); > > +} > > + > > +static void mtk_cam_req_queue(struct media_request *req) > > +{ > > + struct mtk_cam_dev_request *cam_req = mtk_cam_req_to_dev_req(req); > > + struct mtk_cam_dev *cam = container_of(req->mdev, struct mtk_cam_dev, > > + media_dev); > > + unsigned long flags; > > + > > + /* update frame_params's dma_bufs in mtk_cam_vb2_buf_queue */ > > + vb2_request_queue(req); > > + > > + /* add to pending job list */ > > + spin_lock_irqsave(&cam->pending_job_lock, flags); > > + list_add_tail(&cam_req->list, &cam->pending_job_list); > > + spin_unlock_irqrestore(&cam->pending_job_lock, flags); > > + > > + mtk_cam_dev_req_try_queue(cam); > > +} > > + > > +static unsigned int get_pixel_bits(unsigned int pix_fmt) > > +{ > > + switch (pix_fmt) { > > + case V4L2_PIX_FMT_MTISP_SBGGR8: > > + case V4L2_PIX_FMT_MTISP_SGBRG8: > > + case V4L2_PIX_FMT_MTISP_SGRBG8: > > + case V4L2_PIX_FMT_MTISP_SRGGB8: > > + case V4L2_PIX_FMT_MTISP_SBGGR8F: > > + case V4L2_PIX_FMT_MTISP_SGBRG8F: > > + case V4L2_PIX_FMT_MTISP_SGRBG8F: > > + case V4L2_PIX_FMT_MTISP_SRGGB8F: > > + return 8; > > + case V4L2_PIX_FMT_MTISP_SBGGR10: > > + case V4L2_PIX_FMT_MTISP_SGBRG10: > > + case V4L2_PIX_FMT_MTISP_SGRBG10: > > + case V4L2_PIX_FMT_MTISP_SRGGB10: > > + case V4L2_PIX_FMT_MTISP_SBGGR10F: > > + case V4L2_PIX_FMT_MTISP_SGBRG10F: > > + case V4L2_PIX_FMT_MTISP_SGRBG10F: > > + case V4L2_PIX_FMT_MTISP_SRGGB10F: > > + return 10; > > + case V4L2_PIX_FMT_MTISP_SBGGR12: > > + case V4L2_PIX_FMT_MTISP_SGBRG12: > > + case V4L2_PIX_FMT_MTISP_SGRBG12: > > + case V4L2_PIX_FMT_MTISP_SRGGB12: > > + case V4L2_PIX_FMT_MTISP_SBGGR12F: > > + case V4L2_PIX_FMT_MTISP_SGBRG12F: > > + case V4L2_PIX_FMT_MTISP_SGRBG12F: > > + case V4L2_PIX_FMT_MTISP_SRGGB12F: > > + return 12; > > + case V4L2_PIX_FMT_MTISP_SBGGR14: > > + case V4L2_PIX_FMT_MTISP_SGBRG14: > > + case V4L2_PIX_FMT_MTISP_SGRBG14: > > + case V4L2_PIX_FMT_MTISP_SRGGB14: > > + case V4L2_PIX_FMT_MTISP_SBGGR14F: > > + case V4L2_PIX_FMT_MTISP_SGBRG14F: > > + case V4L2_PIX_FMT_MTISP_SGRBG14F: > > + case V4L2_PIX_FMT_MTISP_SRGGB14F: > > + return 14; > > + default: > > + return 0; > > + } > > +} > > which patchset are these pixel formats defined? > I couldn't find them in the ones you pointed. > > I also wonder if all of them need to be defined, or if the pre-defined ones can be used, > so you can use v4l2_format_info() to get the number of bytes. > I miss some files related to pixel format definition in this patch set. You could refer the old patch set for pixel format definition. https://patchwork.kernel.org/patch/11126055/ > > + > > +static void cal_image_pix_mp(struct mtk_cam_dev *cam, unsigned int node_id, > > + struct v4l2_pix_format_mplane *mp) > > +{ > > + unsigned int bpl, ppl; > > bytes per line and pixels per line right? > Yes. > > + unsigned int pixel_bits = get_pixel_bits(mp->pixelformat); > > wouldn't be easier a get_pixel_bytes() function instead of bits? > Sorry. I didn't get the point. The unit of return value is bits, not bytes. Do you suggest move bpl & ppl calculation into get_pixel_bits() and rename to get_pixel_bytes()? > > + unsigned int width = mp->width; > > + > > + bpl = 0; > > + if (node_id == MTK_CAM_P1_MAIN_STREAM_OUT) { > > + /* Bayer encoding format & 2 bytes alignment */ > > + bpl = ALIGN(DIV_ROUND_UP(width * pixel_bits, 8), 2); > > + } else if (node_id == MTK_CAM_P1_PACKED_BIN_OUT) { > > + /* > > + * The FULL-G encoding format > > + * 1 G component per pixel > > + * 1 R component per 4 pixel > > + * 1 B component per 4 pixel > > + * Total 4G/1R/1B in 4 pixel (pixel per line:ppl) > > + */ > > + ppl = DIV_ROUND_UP(width * 6, 4); > > + bpl = DIV_ROUND_UP(ppl * pixel_bits, 8); > > + > > + /* 4 bytes alignment for 10 bit & others are 8 bytes */ > > + if (pixel_bits == 10) > > + bpl = ALIGN(bpl, 4); > > + else > > + bpl = ALIGN(bpl, 8); > > + } > > + /* > > + * This image output buffer will be input buffer of MTK CAM DIP HW > > + * For MTK CAM DIP HW constrained, it needs 4 bytes alignment > > + */ > > + bpl = ALIGN(bpl, 4); > > + > > + mp->plane_fmt[0].bytesperline = bpl; > > + mp->plane_fmt[0].sizeimage = bpl * mp->height; > > + > > + dev_dbg(cam->dev, "node:%d width:%d bytesperline:%d sizeimage:%d\n", > > + node_id, width, bpl, mp->plane_fmt[0].sizeimage); > > +} > > + > > +static const struct v4l2_format * > > +mtk_cam_dev_find_fmt(struct mtk_cam_dev_node_desc *desc, u32 format) > > +{ > > + int i; > > unsigned > Revised in next patch. > > + const struct v4l2_format *dev_fmt; > > + > > + for (i = 0; i < desc->num_fmts; i++) { > > + dev_fmt = &desc->fmts[i]; > > + if (dev_fmt->fmt.pix_mp.pixelformat == format) > > + return dev_fmt; > > + } > > + > > + return NULL; > > +} > > + > > +/* Get the default format setting */ > > +static void > > +mtk_cam_dev_load_default_fmt(struct mtk_cam_dev *cam, > > + struct mtk_cam_dev_node_desc *queue_desc, > > + struct v4l2_format *dest) > > +{ > > + const struct v4l2_format *default_fmt = > > + &queue_desc->fmts[queue_desc->default_fmt_idx]; > > + > > + dest->type = queue_desc->buf_type; > > + > > + /* Configure default format based on node type */ > > + if (!queue_desc->image) { > > + dest->fmt.meta.dataformat = default_fmt->fmt.meta.dataformat; > > + dest->fmt.meta.buffersize = default_fmt->fmt.meta.buffersize; > > + return; > > + } > > + > > + dest->fmt.pix_mp.pixelformat = default_fmt->fmt.pix_mp.pixelformat; > > + dest->fmt.pix_mp.width = default_fmt->fmt.pix_mp.width; > > + dest->fmt.pix_mp.height = default_fmt->fmt.pix_mp.height; > > + /* bytesperline & sizeimage calculation */ > > + cal_image_pix_mp(cam, queue_desc->id, &dest->fmt.pix_mp); > > + dest->fmt.pix_mp.num_planes = 1; > > + > > + dest->fmt.pix_mp.colorspace = V4L2_COLORSPACE_SRGB; > > + dest->fmt.pix_mp.field = V4L2_FIELD_NONE; > > + dest->fmt.pix_mp.ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT; > > + dest->fmt.pix_mp.quantization = V4L2_QUANTIZATION_DEFAULT; > > + dest->fmt.pix_mp.xfer_func = V4L2_XFER_FUNC_SRGB; > > +} > > + > > +/* Utility functions */ > > +static unsigned int get_sensor_pixel_id(unsigned int fmt) > > +{ > > + switch (fmt) { > > + case MEDIA_BUS_FMT_SBGGR8_1X8: > > + case MEDIA_BUS_FMT_SBGGR10_1X10: > > + case MEDIA_BUS_FMT_SBGGR12_1X12: > > + case MEDIA_BUS_FMT_SBGGR14_1X14: > > + return MTK_CAM_RAW_PXL_ID_B; > > + case MEDIA_BUS_FMT_SGBRG8_1X8: > > + case MEDIA_BUS_FMT_SGBRG10_1X10: > > + case MEDIA_BUS_FMT_SGBRG12_1X12: > > + case MEDIA_BUS_FMT_SGBRG14_1X14: > > + return MTK_CAM_RAW_PXL_ID_GB; > > + case MEDIA_BUS_FMT_SGRBG8_1X8: > > + case MEDIA_BUS_FMT_SGRBG10_1X10: > > + case MEDIA_BUS_FMT_SGRBG12_1X12: > > + case MEDIA_BUS_FMT_SGRBG14_1X14: > > + return MTK_CAM_RAW_PXL_ID_GR; > > + case MEDIA_BUS_FMT_SRGGB8_1X8: > > + case MEDIA_BUS_FMT_SRGGB10_1X10: > > + case MEDIA_BUS_FMT_SRGGB12_1X12: > > + case MEDIA_BUS_FMT_SRGGB14_1X14: > > + return MTK_CAM_RAW_PXL_ID_R; > > + default: > > + return MTK_CAM_RAW_PXL_ID_UNKNOWN; > > + } > > +} > > + > > +static unsigned int get_sensor_fmt(unsigned int fmt) > > +{ > > + switch (fmt) { > > + case MEDIA_BUS_FMT_SBGGR8_1X8: > > + case MEDIA_BUS_FMT_SGBRG8_1X8: > > + case MEDIA_BUS_FMT_SGRBG8_1X8: > > + case MEDIA_BUS_FMT_SRGGB8_1X8: > > + return MTK_CAM_IMG_FMT_BAYER8; > > + case MEDIA_BUS_FMT_SBGGR10_1X10: > > + case MEDIA_BUS_FMT_SGBRG10_1X10: > > + case MEDIA_BUS_FMT_SGRBG10_1X10: > > + case MEDIA_BUS_FMT_SRGGB10_1X10: > > + return MTK_CAM_IMG_FMT_BAYER10; > > + case MEDIA_BUS_FMT_SBGGR12_1X12: > > + case MEDIA_BUS_FMT_SGBRG12_1X12: > > + case MEDIA_BUS_FMT_SGRBG12_1X12: > > + case MEDIA_BUS_FMT_SRGGB12_1X12: > > + return MTK_CAM_IMG_FMT_BAYER12; > > + case MEDIA_BUS_FMT_SBGGR14_1X14: > > + case MEDIA_BUS_FMT_SGBRG14_1X14: > > + case MEDIA_BUS_FMT_SGRBG14_1X14: > > + case MEDIA_BUS_FMT_SRGGB14_1X14: > > + return MTK_CAM_IMG_FMT_BAYER14; > > + default: > > + return MTK_CAM_IMG_FMT_UNKNOWN; > > + } > > +} > > I was wondering if it is not better to save all the media bus format > into a table, instead of having several swtch case statements. > Ok, revise in next patch. > > + > > +static unsigned int get_img_fmt(unsigned int fourcc) > > +{ > > + switch (fourcc) { > > + case V4L2_PIX_FMT_MTISP_SBGGR8: > > + case V4L2_PIX_FMT_MTISP_SGBRG8: > > + case V4L2_PIX_FMT_MTISP_SGRBG8: > > + case V4L2_PIX_FMT_MTISP_SRGGB8: > > + return MTK_CAM_IMG_FMT_BAYER8; > > + case V4L2_PIX_FMT_MTISP_SBGGR8F: > > + case V4L2_PIX_FMT_MTISP_SGBRG8F: > > + case V4L2_PIX_FMT_MTISP_SGRBG8F: > > + case V4L2_PIX_FMT_MTISP_SRGGB8F: > > + return MTK_CAM_IMG_FMT_FG_BAYER8; > > + case V4L2_PIX_FMT_MTISP_SBGGR10: > > + case V4L2_PIX_FMT_MTISP_SGBRG10: > > + case V4L2_PIX_FMT_MTISP_SGRBG10: > > + case V4L2_PIX_FMT_MTISP_SRGGB10: > > + return MTK_CAM_IMG_FMT_BAYER10; > > + case V4L2_PIX_FMT_MTISP_SBGGR10F: > > + case V4L2_PIX_FMT_MTISP_SGBRG10F: > > + case V4L2_PIX_FMT_MTISP_SGRBG10F: > > + case V4L2_PIX_FMT_MTISP_SRGGB10F: > > + return MTK_CAM_IMG_FMT_FG_BAYER10; > > + case V4L2_PIX_FMT_MTISP_SBGGR12: > > + case V4L2_PIX_FMT_MTISP_SGBRG12: > > + case V4L2_PIX_FMT_MTISP_SGRBG12: > > + case V4L2_PIX_FMT_MTISP_SRGGB12: > > + return MTK_CAM_IMG_FMT_BAYER12; > > + case V4L2_PIX_FMT_MTISP_SBGGR12F: > > + case V4L2_PIX_FMT_MTISP_SGBRG12F: > > + case V4L2_PIX_FMT_MTISP_SGRBG12F: > > + case V4L2_PIX_FMT_MTISP_SRGGB12F: > > + return MTK_CAM_IMG_FMT_FG_BAYER12; > > + case V4L2_PIX_FMT_MTISP_SBGGR14: > > + case V4L2_PIX_FMT_MTISP_SGBRG14: > > + case V4L2_PIX_FMT_MTISP_SGRBG14: > > + case V4L2_PIX_FMT_MTISP_SRGGB14: > > + return MTK_CAM_IMG_FMT_BAYER14; > > + case V4L2_PIX_FMT_MTISP_SBGGR14F: > > + case V4L2_PIX_FMT_MTISP_SGBRG14F: > > + case V4L2_PIX_FMT_MTISP_SGRBG14F: > > + case V4L2_PIX_FMT_MTISP_SRGGB14F: > > + return MTK_CAM_IMG_FMT_FG_BAYER14; > > + default: > > + return MTK_CAM_IMG_FMT_UNKNOWN; > > + }> +} > > same for the pixelformat. > > Then you can cache object with the pixelformat in the main struct. > Ok, revise in next patch. > > + > > +static int config_img_fmt(struct mtk_cam_dev *cam, unsigned int node_id, > > + struct p1_img_output *out_fmt, int sd_width, > > + int sd_height) > > +{ > > + const struct v4l2_format *cfg_fmt = &cam->vdev_nodes[node_id].vdev_fmt; > > + > > + /* Check output & input image size dimension */ > > + if (cfg_fmt->fmt.pix_mp.width > sd_width || > > + cfg_fmt->fmt.pix_mp.height > sd_height) { > > + dev_err(cam->dev, "node:%d cfg size is larger than sensor\n", > > + node_id); > > + return -EINVAL; > > + } > > + > > + /* Check resize ratio for resize out stream due to HW constraint */ > > + if (((cfg_fmt->fmt.pix_mp.width * 100 / sd_width) < > > + MTK_ISP_MIN_RESIZE_RATIO) || > > + ((cfg_fmt->fmt.pix_mp.height * 100 / sd_height) < > > + MTK_ISP_MIN_RESIZE_RATIO)) { > > + dev_err(cam->dev, "node:%d resize ratio is less than %d%%\n", > > + node_id, MTK_ISP_MIN_RESIZE_RATIO); > > + return -EINVAL; > > + } > > + > > + out_fmt->img_fmt = get_img_fmt(cfg_fmt->fmt.pix_mp.pixelformat); > > + out_fmt->pixel_bits = get_pixel_bits(cfg_fmt->fmt.pix_mp.pixelformat); > > + if (out_fmt->img_fmt == MTK_CAM_IMG_FMT_UNKNOWN || > > + !out_fmt->pixel_bits) { > > + dev_err(cam->dev, "node:%d unknown pixel fmt:%d\n", > > + node_id, cfg_fmt->fmt.pix_mp.pixelformat); > > + return -EINVAL; > > + } > > + dev_dbg(cam->dev, "node:%d pixel_bits:%d img_fmt:0x%x\n", > > + node_id, out_fmt->pixel_bits, out_fmt->img_fmt); > > + > > + out_fmt->size.w = cfg_fmt->fmt.pix_mp.width; > > + out_fmt->size.h = cfg_fmt->fmt.pix_mp.height; > > + out_fmt->size.stride = cfg_fmt->fmt.pix_mp.plane_fmt[0].bytesperline; > > + out_fmt->size.xsize = cfg_fmt->fmt.pix_mp.plane_fmt[0].bytesperline; > > + > > + out_fmt->crop.left = 0; > > + out_fmt->crop.top = 0; > > + out_fmt->crop.width = sd_width; > > + out_fmt->crop.height = sd_height; > > + > > + dev_dbg(cam->dev, > > + "node:%d size=%0dx%0d, stride:%d, xsize:%d, crop=%0dx%0d\n", > > + node_id, out_fmt->size.w, out_fmt->size.h, > > + out_fmt->size.stride, out_fmt->size.xsize, > > + out_fmt->crop.width, out_fmt->crop.height); > > + > > + return 0; > > +} > > + > > +static void mtk_cam_dev_init_stream(struct mtk_cam_dev *cam) > > +{ > > + int i; > > + > > + cam->enabled_count = 0; > > + cam->enabled_dmas = 0; > > + cam->stream_count = 0; > > + cam->running_job_count = 0; > > + > > + /* Get the enabled meta DMA ports */ > > + for (i = 0; i < MTK_CAM_P1_TOTAL_NODES; i++) { > > + if (!cam->vdev_nodes[i].enabled) > > + continue; > > + cam->enabled_count++; > > + cam->enabled_dmas |= cam->vdev_nodes[i].desc.dma_port; > > + } > > + > > + dev_dbg(cam->dev, "%s:%d:0x%x\n", __func__, cam->enabled_count, > > + cam->enabled_dmas); > > +} > > + > > +static int mtk_cam_dev_isp_config(struct mtk_cam_dev *cam) > > +{ > > + struct device *dev = cam->dev; > > + struct p1_config_param config_param; > > + struct cfg_in_param *cfg_in_param; > > + struct v4l2_subdev_format sd_fmt; > > + int sd_width, sd_height, sd_code; > > are this sd_* variables required? Can't sd_fmt be directly accessed? > Ok, revised in next patch set. > > + unsigned int enabled_dma_ports = cam->enabled_dmas; > > + int ret; > > + > > + /* Get sensor format configuration */ > > + sd_fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE; > > + ret = v4l2_subdev_call(cam->sensor, pad, get_fmt, NULL, &sd_fmt); > > + if (ret) { > > + dev_dbg(dev, "sensor g_fmt failed:%d\n", ret); > > + return ret; > > + } > > + sd_width = sd_fmt.format.width; > > + sd_height = sd_fmt.format.height; > > + sd_code = sd_fmt.format.code; > > + dev_dbg(dev, "sd fmt w*h=%d*%d, code=0x%x\n", sd_width, sd_height, > > + sd_code); > > If V4L2_SUBDEV_FL_HAS_DEVNODE is used, then format shouldn't propagate from one node to the other, > it should be configured from userspace. > Could you explain why? Moreover, how does configuration from user space? > > + > > + memset(&config_param, 0, sizeof(config_param)); > > + > > + /* Update cfg_in_param */ > > + cfg_in_param = &config_param.cfg_in_param; > > + cfg_in_param->continuous = true; > > + /* Fix to one pixel mode in default */ > > + cfg_in_param->pixel_mode = MTK_ISP_ONE_PIXEL_MODE; > > + cfg_in_param->crop.width = sd_width; > > + cfg_in_param->crop.height = sd_height; > > + cfg_in_param->raw_pixel_id = get_sensor_pixel_id(sd_code); > > + cfg_in_param->img_fmt = get_sensor_fmt(sd_code); > > + if (cfg_in_param->img_fmt == MTK_CAM_IMG_FMT_UNKNOWN || > > + cfg_in_param->raw_pixel_id == MTK_CAM_RAW_PXL_ID_UNKNOWN) { > > + dev_err(dev, "unknown sd code:%d\n", sd_code); > > + return -EINVAL; > > + } > > + > > + /* Update cfg_main_param */ > > + config_param.cfg_main_param.pure_raw = true; > > + config_param.cfg_main_param.pure_raw_pack = true; > > + ret = config_img_fmt(cam, MTK_CAM_P1_MAIN_STREAM_OUT, > > + &config_param.cfg_main_param.output, > > + sd_width, sd_height); > > + if (ret) > > + return ret; > > + > > + /* Update cfg_resize_param */ > > + if (enabled_dma_ports & R_RRZO) { > > + ret = config_img_fmt(cam, MTK_CAM_P1_PACKED_BIN_OUT, > > + &config_param.cfg_resize_param.output, > > + sd_width, sd_height); > > + if (ret) > > + return ret; > > + } else { > > + config_param.cfg_resize_param.bypass = true; > > + } > > + > > + /* Update enabled_dmas */ > > + config_param.enabled_dmas = enabled_dma_ports; > > + mtk_isp_hw_config(cam, &config_param); > > + dev_dbg(dev, "%s done\n", __func__); > > + > > + return 0; > > +} > > + > > +void mtk_cam_dev_event_frame_sync(struct mtk_cam_dev *cam, > > + unsigned int frame_seq_no) > > +{ > > + struct v4l2_event event = { > > + .type = V4L2_EVENT_FRAME_SYNC, > > + .u.frame_sync.frame_sequence = frame_seq_no, > > + }; > > + > > + v4l2_event_queue(cam->subdev.devnode, &event); > > +} > > + > > +static struct v4l2_subdev * > > +mtk_cam_cio_get_active_sensor(struct mtk_cam_dev *cam) > > +{ > > + struct media_device *mdev = cam->seninf->entity.graph_obj.mdev; > > + struct device *dev = cam->dev; > > + struct media_entity *entity; > > + struct v4l2_subdev *sensor; > > + > > + sensor = NULL; > > + media_device_for_each_entity(entity, mdev) { > > + dev_dbg(dev, "media entity: %s:0x%x:%d\n", > > + entity->name, entity->function, entity->stream_count); > > + if (entity->function == MEDIA_ENT_F_CAM_SENSOR && > > + entity->stream_count) { > > + sensor = media_entity_to_v4l2_subdev(entity); > > + dev_dbg(dev, "sensor found: %s\n", entity->name); > > + break; > > + } > > + } > > + > > + if (!sensor) > > + dev_err(dev, "no seninf connected\n"); > > + > > + return sensor; > > +} > > + > > +static int mtk_cam_cio_stream_on(struct mtk_cam_dev *cam) > > +{ > > + struct device *dev = cam->dev; > > + int ret; > > + > > + if (!cam->seninf) { > > + dev_err(dev, "no seninf connected\n"); > > + return -ENODEV; > > + } > > + > > + /* Get active sensor from graph topology */ > > + cam->sensor = mtk_cam_cio_get_active_sensor(cam); > > + if (!cam->sensor) > > + return -ENODEV; > > + > > + /* Seninf must stream on first */ > > + ret = v4l2_subdev_call(cam->seninf, video, s_stream, 1); > > + if (ret) { > > + dev_err(dev, "failed to stream on %s:%d\n", > > + cam->seninf->entity.name, ret); > > + return ret; > > + } > > + > > + ret = v4l2_subdev_call(cam->sensor, video, s_stream, 1); > > + if (ret) { > > + dev_err(dev, "failed to stream on %s:%d\n", > > + cam->sensor->entity.name, ret); > > + goto fail_seninf_off; > > + } > > + > > + ret = mtk_cam_dev_isp_config(cam); > > + if (ret) > > + goto fail_sensor_off; > > + > > + cam->streaming = true; > > + mtk_isp_stream(cam, 1); > > + mtk_cam_dev_req_try_queue(cam); > > + dev_dbg(dev, "streamed on Pass 1\n"); > > + > > + return 0; > > + > > +fail_sensor_off: > > + v4l2_subdev_call(cam->sensor, video, s_stream, 0); > > +fail_seninf_off: > > + v4l2_subdev_call(cam->seninf, video, s_stream, 0); > > + > > + return ret; > > +} > > + > > +static int mtk_cam_cio_stream_off(struct mtk_cam_dev *cam) > > +{ > > + struct device *dev = cam->dev; > > + int ret; > > + > > + ret = v4l2_subdev_call(cam->sensor, video, s_stream, 0); > > + if (ret) { > > + dev_err(dev, "failed to stream off %s:%d\n", > > + cam->sensor->entity.name, ret); > > + return -EPERM; > > Why -EPERM ? > Ok, we will return ret directly. > > + } > > + > > + ret = v4l2_subdev_call(cam->seninf, video, s_stream, 0); > > + if (ret) { > > + dev_err(dev, "failed to stream off %s:%d\n", > > + cam->seninf->entity.name, ret); > > + return -EPERM; > > + } > > + > > + cam->streaming = false; > > + mtk_isp_stream(cam, 0); > > + mtk_isp_hw_release(cam); > > + > > + dev_dbg(dev, "streamed off Pass 1\n"); > > + > > + return 0; > > +} > > + > > +static int mtk_cam_sd_s_stream(struct v4l2_subdev *sd, int enable) > > +{ > > + struct mtk_cam_dev *cam = container_of(sd, struct mtk_cam_dev, subdev); > > + > > + if (enable) { > > + /* Align vb2_core_streamon design */ > > + if (cam->streaming) { > > + dev_warn(cam->dev, "already streaming on\n"); > > I think just dev_dbg is enough. > Fix in next patch. > > + return 0; > > + } > > + return mtk_cam_cio_stream_on(cam); > > + } > > + > > + if (!cam->streaming) { > > + dev_warn(cam->dev, "already streaming off\n"); > > same here > Fix in next patch. > > + return 0; > > + } > > + return mtk_cam_cio_stream_off(cam); > > +} > > + > > +static int mtk_cam_sd_subscribe_event(struct v4l2_subdev *subdev, > > + struct v4l2_fh *fh, > > + struct v4l2_event_subscription *sub) > > +{ > > + switch (sub->type) { > > + case V4L2_EVENT_FRAME_SYNC: > > + return v4l2_event_subscribe(fh, sub, 0, NULL); > > + default: > > + return -EINVAL; > > + } > > +} > > + > > +static int mtk_cam_media_link_setup(struct media_entity *entity, > > + const struct media_pad *local, > > + const struct media_pad *remote, u32 flags) > > +{ > > + struct mtk_cam_dev *cam = > > + container_of(entity, struct mtk_cam_dev, subdev.entity); > > + u32 pad = local->index; > > + > > + dev_dbg(cam->dev, "%s: %d->%d flags:0x%x\n", > > + __func__, pad, remote->index, flags); > > + > > + /* > > + * The video nodes exposed by the driver have pads indexes > > + * from 0 to MTK_CAM_P1_TOTAL_NODES - 1. > > + */ > > + if (pad < MTK_CAM_P1_TOTAL_NODES) > > + cam->dev_nodes[pad].enabled = > > + !!(flags & MEDIA_LNK_FL_ENABLED); > > Can't you just check the state of the link in the pad instead of saving it in cam->vdev_nodes[pad].enabled ? > Ok, revised in next patch. > > + > > + return 0; > > +} > > + > > +static void mtk_cam_vb2_buf_queue(struct vb2_buffer *vb) > > +{ > > + struct mtk_cam_dev *cam = vb2_get_drv_priv(vb->vb2_queue); > > + struct mtk_cam_dev_buffer *buf = mtk_cam_vb2_buf_to_dev_buf(vb); > > + struct mtk_cam_dev_request *req = mtk_cam_req_to_dev_req(vb->request); > > + struct mtk_cam_video_device *node = mtk_cam_vbq_to_vdev(vb->vb2_queue); > > + struct device *dev = cam->dev; > > + unsigned long flags; > > + > > + dev_dbg(dev, "%s: node:%d fd:%d idx:%d\n", __func__, > > + node->id, buf->vbb.request_fd, buf->vbb.vb2_buf.index); > > + > > + /* added the buffer into the tracking list */ > > + spin_lock_irqsave(&node->buf_list_lock, flags); > > + list_add_tail(&buf->list, &node->buf_list); > > + spin_unlock_irqrestore(&node->buf_list_lock, flags); > > + > > + /* update buffer internal address */ > > + req->frame_params.dma_bufs[buf->node_id].iova = buf->daddr; > > + req->frame_params.dma_bufs[buf->node_id].scp_addr = buf->scp_addr; > > isn't it an issue if userspace queue two buffers for the same video device in the same request? > > vb2_request_queue(req) will call all the .buf_queue() callbacks, and only the last buffer in the list > will be at req->frame_params.dma_bufs[buf->node_id], no? > > Also, what happens if a request doesn't contain buffers for all node_ids ? Will it put data in the previous programmed > buffer? > > Please, let me know if these questions doesn't make sense, I'm not that familiar with the request API internals. > 1. yes, it is a issue if userspace queues two buffers for the same video device with the same request FD. 2. All buffers which are belonged different to different video devices in the request list will be updated to req->frame_params.dma_bufs by buf->node_id. 3. It is not allowed for userspace to queue partial buffers for all enabled video devices. If it happens, it may trigger DMA errors for this request. > > +} > > + > > +static int mtk_cam_vb2_buf_init(struct vb2_buffer *vb) > > +{ > > + struct mtk_cam_video_device *node = mtk_cam_vbq_to_vdev(vb->vb2_queue); > > + struct mtk_cam_dev *cam = vb2_get_drv_priv(vb->vb2_queue); > > + struct device *dev = cam->dev; > > + struct mtk_cam_dev_buffer *buf; > > + dma_addr_t addr; > > + > > + buf = mtk_cam_vb2_buf_to_dev_buf(vb); > > + buf->node_id = node->id; > > + buf->daddr = vb2_dma_contig_plane_dma_addr(vb, 0); > > + buf->scp_addr = 0; > > + > > + /* SCP address is only valid for meta input buffer */ > > + if (!node->desc.smem_alloc) > > + return 0; > > + > > + buf = mtk_cam_vb2_buf_to_dev_buf(vb); > > + /* Use coherent address to get iova address */ > > + addr = dma_map_resource(dev, buf->daddr, vb->planes[0].length, > > + DMA_BIDIRECTIONAL, DMA_ATTR_SKIP_CPU_SYNC);> + if (dma_mapping_error(dev, addr)) { > > + dev_err(dev, "failed to map meta addr:%pad\n", &buf->daddr); > > + return -EFAULT; > > + } > > + buf->scp_addr = buf->daddr; > > + buf->daddr = addr; > > + > > + return 0; > > +} > > + > > +static int mtk_cam_vb2_buf_prepare(struct vb2_buffer *vb) > > +{ > > + struct mtk_cam_video_device *node = mtk_cam_vbq_to_vdev(vb->vb2_queue); > > + struct mtk_cam_dev *cam = vb2_get_drv_priv(vb->vb2_queue); > > + struct vb2_v4l2_buffer *v4l2_buf = to_vb2_v4l2_buffer(vb); > > + const struct v4l2_format *fmt = &node->vdev_fmt; > > + unsigned int size; > > + > > + if (vb->vb2_queue->type == V4L2_BUF_TYPE_META_OUTPUT || > > + vb->vb2_queue->type == V4L2_BUF_TYPE_META_CAPTURE) > > + size = fmt->fmt.meta.buffersize; > > + else > > + size = fmt->fmt.pix_mp.plane_fmt[0].sizeimage; > > + > > + if (vb2_plane_size(vb, 0) < size) { > > + dev_dbg(cam->dev, "plane size is too small:%lu<%u\n", > > + vb2_plane_size(vb, 0), size); > > + return -EINVAL; > > + } > > + > > + if (V4L2_TYPE_IS_OUTPUT(vb->vb2_queue->type)) { > > + if (vb2_get_plane_payload(vb, 0) != size) { > > + dev_dbg(cam->dev, "plane payload is mismatch:%lu:%u\n", > > + vb2_get_plane_payload(vb, 0), size); > > + return -EINVAL; > > + } > > + return 0; > > + } > > + > > + v4l2_buf->field = V4L2_FIELD_NONE; > > + vb2_set_plane_payload(vb, 0, size); > > + > > + return 0; > > +} > > + > > +static void mtk_cam_vb2_buf_cleanup(struct vb2_buffer *vb) > > +{ > > + struct mtk_cam_video_device *node = mtk_cam_vbq_to_vdev(vb->vb2_queue); > > + struct mtk_cam_dev *cam = vb2_get_drv_priv(vb->vb2_queue); > > + struct mtk_cam_dev_buffer *buf; > > + struct device *dev = cam->dev; > > + > > + if (!node->desc.smem_alloc) > > + return; > > + > > + buf = mtk_cam_vb2_buf_to_dev_buf(vb); > > + dma_unmap_page_attrs(dev, buf->daddr, > > + vb->planes[0].length, > > + DMA_BIDIRECTIONAL, > > + DMA_ATTR_SKIP_CPU_SYNC); > > +} > > + > > +static void mtk_cam_vb2_request_complete(struct vb2_buffer *vb) > > +{ > > + struct mtk_cam_dev *cam = vb2_get_drv_priv(vb->vb2_queue); > > + > > + dev_dbg(cam->dev, "%s\n", __func__); > > +} > > + > > +static int mtk_cam_vb2_queue_setup(struct vb2_queue *vq, > > + unsigned int *num_buffers, > > + unsigned int *num_planes, > > + unsigned int sizes[], > > + struct device *alloc_devs[]) > > +{ > > + struct mtk_cam_video_device *node = mtk_cam_vbq_to_vdev(vq); > > + unsigned int max_buffer_count = node->desc.max_buf_count; > > + const struct v4l2_format *fmt = &node->vdev_fmt; > > + unsigned int size; > > + > > + /* Check the limitation of buffer size */ > > + if (max_buffer_count) > > + *num_buffers = clamp_val(*num_buffers, 1, max_buffer_count); > > + > > + if (node->desc.smem_alloc) > > + vq->dma_attrs |= DMA_ATTR_NO_KERNEL_MAPPING; > > + > > + if (vq->type == V4L2_BUF_TYPE_META_OUTPUT || > > + vq->type == V4L2_BUF_TYPE_META_CAPTURE) > > + size = fmt->fmt.meta.buffersize; > > + else > > + size = fmt->fmt.pix_mp.plane_fmt[0].sizeimage; > > + > > + /* Add for q.create_bufs with fmt.g_sizeimage(p) / 2 test */ > > + if (*num_planes) { > > + if (sizes[0] < size || *num_planes != 1) > > + return -EINVAL; > > + } else { > > + *num_planes = 1; > > + sizes[0] = size; > > + } > > + > > + return 0; > > +} > > + > > +static void mtk_cam_vb2_return_all_buffers(struct mtk_cam_dev *cam, > > + struct mtk_cam_video_device *node, > > + enum vb2_buffer_state state) > > +{ > > + struct mtk_cam_dev_buffer *buf, *buf_prev; > > + unsigned long flags; > > + > > + spin_lock_irqsave(&node->buf_list_lock, flags); > > + list_for_each_entry_safe(buf, buf_prev, &node->buf_list, list) { > > + list_del(&buf->list); > > + vb2_buffer_done(&buf->vbb.vb2_buf, state); > > + } > > + spin_unlock_irqrestore(&node->buf_list_lock, flags); > > +} > > + > > +static int mtk_cam_vb2_start_streaming(struct vb2_queue *vq, > > + unsigned int count) > > +{ > > + struct mtk_cam_dev *cam = vb2_get_drv_priv(vq); > > + struct mtk_cam_video_device *node = mtk_cam_vbq_to_vdev(vq); > > + struct device *dev = cam->dev; > > + int ret; > > + > > + if (!node->enabled) { > > + dev_err(dev, "Node:%d is not enabled\n", node->id); > > + ret = -ENOLINK; > > + goto fail_ret_buf; > > + } > > + > > + mutex_lock(&cam->op_lock); > > + /* Start streaming of the whole pipeline now*/ > > + if (!cam->pipeline.streaming_count) { > > No need for this check, vb2 won't call .start_streaming() twice without stop_streaming() in between. > The check is designed to start the media pipeline when we start streaming on the first node. You could refer the detail in below link. https://patchwork.kernel.org/patch/10985819/ > > + ret = media_pipeline_start(&node->vdev.entity, &cam->pipeline); > > + if (ret) { > > + dev_err(dev, "failed to start pipeline:%d\n", ret); > > + goto fail_unlock; > > + } > > + mtk_cam_dev_init_stream(cam); > > + ret = mtk_isp_hw_init(cam); > > + if (ret) { > > + dev_err(dev, "failed to init HW:%d\n", ret); > > + goto fail_stop_pipeline; > > + } > > + } > > + > > + /* Media links are fixed after media_pipeline_start */ > > + cam->stream_count++; > > + dev_dbg(dev, "%s: count info:%d:%d\n", __func__, cam->stream_count, > > + cam->enabled_count); > > + if (cam->stream_count < cam->enabled_count) { > > + mutex_unlock(&cam->op_lock); > > + return 0; > > + } > > + > > + /* Stream on sub-devices node */ > > + ret = v4l2_subdev_call(&cam->subdev, video, s_stream, 1); > > + if (ret) > > + goto fail_no_stream; > > + mutex_unlock(&cam->op_lock); > > + > > + return 0; > > + > > +fail_no_stream: > > + cam->stream_count--; > > +fail_stop_pipeline: > > + if (cam->stream_count == 0) > > + media_pipeline_stop(&node->vdev.entity); > > +fail_unlock: > > + mutex_unlock(&cam->op_lock); > > +fail_ret_buf: > > + mtk_cam_vb2_return_all_buffers(cam, node, VB2_BUF_STATE_QUEUED); > > + > > + return ret; > > +} > > + > > +static void mtk_cam_vb2_stop_streaming(struct vb2_queue *vq) > > +{ > > + struct mtk_cam_dev *cam = vb2_get_drv_priv(vq); > > + struct mtk_cam_video_device *node = mtk_cam_vbq_to_vdev(vq); > > + struct device *dev = cam->dev; > > + > > + mutex_lock(&cam->op_lock); > > + dev_dbg(dev, "%s node:%d count info:%d\n", __func__, node->id, > > + cam->stream_count); > > + /* Check the first node to stream-off */ > > + if (cam->stream_count == cam->enabled_count) > > + v4l2_subdev_call(&cam->subdev, video, s_stream, 0); > > + > > + mtk_cam_vb2_return_all_buffers(cam, node, VB2_BUF_STATE_ERROR); > > + cam->stream_count--; > > + if (cam->stream_count) { > > + mutex_unlock(&cam->op_lock); > > + return; > > + } > > + mutex_unlock(&cam->op_lock); > > + > > + mtk_cam_dev_req_cleanup(cam); > > + media_pipeline_stop(&node->vdev.entity); > > +} > > + > > +static int mtk_cam_vidioc_querycap(struct file *file, void *fh, > > + struct v4l2_capability *cap) > > +{ > > + struct mtk_cam_dev *cam = video_drvdata(file); > > + > > + strscpy(cap->driver, dev_driver_string(cam->dev), sizeof(cap->driver)); > > + strscpy(cap->card, dev_driver_string(cam->dev), sizeof(cap->card)); > > + snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s", > > + dev_name(cam->dev)); > > + > > + return 0; > > +} > > + > > +static int mtk_cam_vidioc_enum_fmt(struct file *file, void *fh, > > + struct v4l2_fmtdesc *f) > > +{ > > + struct mtk_cam_video_device *node = file_to_mtk_cam_node(file); > > + > > + if (f->index >= node->desc.num_fmts) > > + return -EINVAL; > > + > > + /* f->description is filled in v4l_fill_fmtdesc function */ > > + f->pixelformat = node->desc.fmts[f->index].fmt.pix_mp.pixelformat; > > + f->flags = 0; > > + > > + return 0; > > +} > > + > > +static int mtk_cam_vidioc_g_fmt(struct file *file, void *fh, > > + struct v4l2_format *f) > > +{ > > + struct mtk_cam_video_device *node = file_to_mtk_cam_node(file); > > + > > + f->fmt = node->vdev_fmt.fmt; > > + > > + return 0; > > +} > > + > > +static int mtk_cam_vidioc_try_fmt(struct file *file, void *fh, > > + struct v4l2_format *f) > > +{ > > + struct mtk_cam_dev *cam = video_drvdata(file); > > + struct mtk_cam_video_device *node = file_to_mtk_cam_node(file); > > + struct device *dev = cam->dev; > > + const struct v4l2_format *dev_fmt; > > + struct v4l2_format try_fmt; > > + > > + memset(&try_fmt, 0, sizeof(try_fmt)); > > + try_fmt.type = f->type; > > + > > + /* Validate pixelformat */ > > + dev_fmt = mtk_cam_dev_find_fmt(&node->desc, f->fmt.pix_mp.pixelformat); > > + if (!dev_fmt) { > > + dev_dbg(dev, "unknown fmt:%d\n", f->fmt.pix_mp.pixelformat); > > + dev_fmt = &node->desc.fmts[node->desc.default_fmt_idx]; > > + } > > + try_fmt.fmt.pix_mp.pixelformat = dev_fmt->fmt.pix_mp.pixelformat; > > + > > + /* Validate image width & height range */ > > + try_fmt.fmt.pix_mp.width = clamp_val(f->fmt.pix_mp.width, > > + IMG_MIN_WIDTH, IMG_MAX_WIDTH); > > + try_fmt.fmt.pix_mp.height = clamp_val(f->fmt.pix_mp.height, > > + IMG_MIN_HEIGHT, IMG_MAX_HEIGHT); > > + /* 4 bytes alignment for width */ > > + try_fmt.fmt.pix_mp.width = ALIGN(try_fmt.fmt.pix_mp.width, 4); > > + > > + /* Only support one plane */ > > + try_fmt.fmt.pix_mp.num_planes = 1; > > + > > + /* bytesperline & sizeimage calculation */ > > + cal_image_pix_mp(cam, node->id, &try_fmt.fmt.pix_mp); > > + > > + /* Constant format fields */ > > + try_fmt.fmt.pix_mp.colorspace = V4L2_COLORSPACE_SRGB; > > + try_fmt.fmt.pix_mp.field = V4L2_FIELD_NONE; > > + try_fmt.fmt.pix_mp.ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT; > > + try_fmt.fmt.pix_mp.quantization = V4L2_QUANTIZATION_DEFAULT; > > + try_fmt.fmt.pix_mp.xfer_func = V4L2_XFER_FUNC_SRGB; > > + > > + *f = try_fmt; > > + > > + return 0; > > +} > > + > > +static int mtk_cam_vidioc_s_fmt(struct file *file, void *fh, > > + struct v4l2_format *f) > > +{ > > + struct mtk_cam_dev *cam = video_drvdata(file); > > + struct mtk_cam_video_device *node = file_to_mtk_cam_node(file); > > + > > + if (vb2_is_busy(node->vdev.queue)) { > > + dev_dbg(cam->dev, "%s: queue is busy\n", __func__); > > + return -EBUSY; > > + } > > + > > + /* Get the valid format */ > > + mtk_cam_vidioc_try_fmt(file, fh, f); > > + /* Configure to video device */ > > + node->vdev_fmt = *f; > > + > > + return 0; > > +} > > + > > +static int mtk_cam_vidioc_enum_framesizes(struct file *filp, void *priv, > > + struct v4l2_frmsizeenum *sizes) > > +{ > > + struct mtk_cam_video_device *node = file_to_mtk_cam_node(filp); > > + const struct v4l2_format *dev_fmt; > > + > > + dev_fmt = mtk_cam_dev_find_fmt(&node->desc, sizes->pixel_format); > > + if (!dev_fmt || sizes->index) > > + return -EINVAL; > > + > > + sizes->type = node->desc.frmsizes->type; > > + memcpy(&sizes->stepwise, &node->desc.frmsizes->stepwise, > > + sizeof(sizes->stepwise)); > > + > > + return 0; > > +} > > + > > +static int mtk_cam_vidioc_meta_enum_fmt(struct file *file, void *fh, > > + struct v4l2_fmtdesc *f) > > +{ > > + struct mtk_cam_video_device *node = file_to_mtk_cam_node(file); > > + > > + if (f->index) > > + return -EINVAL; > > + > > + /* f->description is filled in v4l_fill_fmtdesc function */ > > + f->pixelformat = node->vdev_fmt.fmt.meta.dataformat; > > + f->flags = 0; > > + > > + return 0; > > +} > > + > > +static int mtk_cam_vidioc_g_meta_fmt(struct file *file, void *fh, > > + struct v4l2_format *f) > > +{ > > + struct mtk_cam_video_device *node = file_to_mtk_cam_node(file); > > + > > + f->fmt.meta.dataformat = node->vdev_fmt.fmt.meta.dataformat; > > + f->fmt.meta.buffersize = node->vdev_fmt.fmt.meta.buffersize; > > + > > + return 0; > > +} > > + > > +static const struct v4l2_subdev_core_ops mtk_cam_subdev_core_ops = { > > + .subscribe_event = mtk_cam_sd_subscribe_event, > > + .unsubscribe_event = v4l2_event_subdev_unsubscribe, > > +}; > > + > > +static const struct v4l2_subdev_video_ops mtk_cam_subdev_video_ops = { > > + .s_stream = mtk_cam_sd_s_stream, > > +}; > > + > > +static const struct v4l2_subdev_ops mtk_cam_subdev_ops = { > > + .core = &mtk_cam_subdev_core_ops, > > + .video = &mtk_cam_subdev_video_ops, > > +}; > > hmm, since this subdevice is exposed with V4L2_SUBDEV_FL_HAS_DEVNODE, > I wonder if pad ops shouldn't be implemented too (to be verified). > Ok, I will investigate this. > > + > > +static const struct media_entity_operations mtk_cam_media_entity_ops = { > > + .link_setup = mtk_cam_media_link_setup, > > + .link_validate = v4l2_subdev_link_validate, > > +}; > > + > > +static const struct vb2_ops mtk_cam_vb2_ops = { > > + .queue_setup = mtk_cam_vb2_queue_setup, > > + .wait_prepare = vb2_ops_wait_prepare, > > + .wait_finish = vb2_ops_wait_finish, > > + .buf_init = mtk_cam_vb2_buf_init, > > + .buf_prepare = mtk_cam_vb2_buf_prepare, > > + .start_streaming = mtk_cam_vb2_start_streaming, > > + .stop_streaming = mtk_cam_vb2_stop_streaming, > > + .buf_queue = mtk_cam_vb2_buf_queue, > > + .buf_cleanup = mtk_cam_vb2_buf_cleanup, > > + .buf_request_complete = mtk_cam_vb2_request_complete, > > +};> + > > +static const struct v4l2_file_operations mtk_cam_v4l2_fops = { > > + .unlocked_ioctl = video_ioctl2, > > + .open = v4l2_fh_open, > > + .release = vb2_fop_release, > > + .poll = vb2_fop_poll, > > + .mmap = vb2_fop_mmap, > > +#ifdef CONFIG_COMPAT > > + .compat_ioctl32 = v4l2_compat_ioctl32, > > +#endif > > +}; > > + > > +static const struct media_device_ops mtk_cam_media_ops = { > > + .req_alloc = mtk_cam_req_alloc, > > + .req_free = mtk_cam_req_free, > > + .req_validate = vb2_request_validate, > > + .req_queue = mtk_cam_req_queue, > > +}; > > + > > +static int mtk_cam_media_register(struct mtk_cam_dev *cam, > > + struct media_device *media_dev) > > +{ > > + /* Reserved MTK_CAM_CIO_PAD_SINK + 1 pads to use */ > > + unsigned int num_pads = MTK_CAM_CIO_PAD_SINK + 1; > > + struct device *dev = cam->dev; > > + int i, ret; > > + > > + media_dev->dev = cam->dev; > > + strscpy(media_dev->model, dev_driver_string(dev), > > + sizeof(media_dev->model)); > > + snprintf(media_dev->bus_info, sizeof(media_dev->bus_info), > > + "platform:%s", dev_name(dev)); > > + media_dev->hw_revision = 0; > > + media_device_init(media_dev); > > + media_dev->ops = &mtk_cam_media_ops; > > + > > + ret = media_device_register(media_dev); > > + if (ret) { > > + dev_err(dev, "failed to register media device:%d\n", ret); > > + return ret; > > + } > > + > > + /* Initialize subdev pads */ > > + cam->subdev_pads = devm_kcalloc(dev, num_pads, > > + sizeof(*cam->subdev_pads), > > + GFP_KERNEL); > > + if (!cam->subdev_pads) { > > + dev_err(dev, "failed to allocate subdev_pads\n"); > > + ret = -ENOMEM; > > + goto fail_media_unreg; > > + } > > + > > + ret = media_entity_pads_init(&cam->subdev.entity, num_pads, > > + cam->subdev_pads); > > + if (ret) { > > + dev_err(dev, "failed to initialize media pads:%d\n", ret); > > + goto fail_media_unreg; > > + } > > + > > + /* Initialize all pads with MEDIA_PAD_FL_SOURCE */ > > + for (i = 0; i < num_pads; i++) > > + cam->subdev_pads[i].flags = MEDIA_PAD_FL_SOURCE; > > + > > + /* Customize the last one pad as CIO sink pad. */ > > + cam->subdev_pads[MTK_CAM_CIO_PAD_SINK].flags = MEDIA_PAD_FL_SINK; > > + > > + return 0; > > + > > +fail_media_unreg: > > + media_device_unregister(&cam->media_dev); > > + media_device_cleanup(&cam->media_dev); > > + > > + return ret; > > +} > > + > > +static int > > +mtk_cam_video_register_device(struct mtk_cam_dev *cam, > > + struct mtk_cam_video_device *node) > > +{ > > + struct device *dev = cam->dev; > > + struct video_device *vdev = &node->vdev; > > + struct vb2_queue *vbq = &node->vbq; > > + unsigned int output = V4L2_TYPE_IS_OUTPUT(node->desc.buf_type); > > + unsigned int link_flags = node->desc.link_flags; > > + int ret; > > + > > + /* Initialize mtk_cam_video_device */ > > + if (link_flags & MEDIA_LNK_FL_IMMUTABLE) > > + node->enabled = true; > > + else > > + node->enabled = false; > > + mtk_cam_dev_load_default_fmt(cam, &node->desc, &node->vdev_fmt); > > + > > + cam->subdev_pads[node->id].flags = output ? > > + MEDIA_PAD_FL_SINK : MEDIA_PAD_FL_SOURCE; > > + > > + /* Initialize media entities */ > > + ret = media_entity_pads_init(&vdev->entity, 1, &node->vdev_pad); > > + if (ret) { > > + dev_err(dev, "failed to initialize media pad:%d\n", ret); > > + return ret; > > + } > > + node->vdev_pad.flags = output ? MEDIA_PAD_FL_SOURCE : MEDIA_PAD_FL_SINK; > > + > > + /* Initialize vbq */ > > + vbq->type = node->desc.buf_type; > > + if (vbq->type == V4L2_BUF_TYPE_META_OUTPUT) > > + vbq->io_modes = VB2_MMAP; > > + else > > + vbq->io_modes = VB2_MMAP | VB2_DMABUF; > > + > > + if (node->desc.smem_alloc) { > > + vbq->bidirectional = 1; > > + vbq->dev = cam->smem_dev; > > + } else { > > + vbq->dev = dev; > > + } > > + vbq->ops = &mtk_cam_vb2_ops; > > + vbq->mem_ops = &vb2_dma_contig_memops; > > + vbq->buf_struct_size = sizeof(struct mtk_cam_dev_buffer); > > + vbq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_BOOTIME; > > + if (output) > > + vbq->timestamp_flags |= V4L2_BUF_FLAG_TSTAMP_SRC_EOF; > > + else > > + vbq->timestamp_flags |= V4L2_BUF_FLAG_TSTAMP_SRC_SOE; > > + /* No minimum buffers limitation */ > > + vbq->min_buffers_needed = 0; > > + vbq->drv_priv = cam; > > + vbq->lock = &node->vdev_lock; > > + vbq->supports_requests = true; > > + vbq->requires_requests = true; > > + > > + ret = vb2_queue_init(vbq); > > + if (ret) { > > + dev_err(dev, "failed to init. vb2 queue:%d\n", ret); > > + goto fail_media_clean; > > + } > > + > > + /* Initialize vdev */ > > + snprintf(vdev->name, sizeof(vdev->name), "%s %s", > > + dev_driver_string(dev), node->desc.name); > > + /* set cap/type/ioctl_ops of the video device */ > > + vdev->device_caps = node->desc.cap | V4L2_CAP_STREAMING; > > + vdev->ioctl_ops = node->desc.ioctl_ops; > > + vdev->fops = &mtk_cam_v4l2_fops; > > + vdev->release = video_device_release_empty; > > + vdev->lock = &node->vdev_lock; > > + vdev->v4l2_dev = &cam->v4l2_dev; > > + vdev->queue = &node->vbq; > > + vdev->vfl_dir = output ? VFL_DIR_TX : VFL_DIR_RX; > > + vdev->entity.function = MEDIA_ENT_F_IO_V4L; > > + vdev->entity.ops = NULL; > > + video_set_drvdata(vdev, cam); > > + dev_dbg(dev, "registered vdev:%d:%s\n", node->id, vdev->name); > > + > > + /* Initialize miscellaneous variables */ > > + mutex_init(&node->vdev_lock); > > + INIT_LIST_HEAD(&node->buf_list); > > + spin_lock_init(&node->buf_list_lock); > > + > > + ret = video_register_device(vdev, VFL_TYPE_GRABBER, -1); > > + if (ret) { > > + dev_err(dev, "failed to register vde:%d\n", ret); > > + goto fail_vb2_rel; > > + } > > + > > + /* Create link between video node and the subdev pad */ > > + if (output) { > > + ret = media_create_pad_link(&vdev->entity, 0, > > + &cam->subdev.entity, > > + node->id, link_flags); > > + } else { > > + ret = media_create_pad_link(&cam->subdev.entity, > > + node->id, &vdev->entity, 0, > > + link_flags); > > + } > > No need for the curly braces. > Revised in next patch. > > + if (ret) > > + goto fail_vdev_ureg; > > + > > + return 0; > > + > > +fail_vdev_ureg: > > + video_unregister_device(vdev); > > +fail_vb2_rel: > > + mutex_destroy(&node->vdev_lock); > > + vb2_queue_release(vbq); > > +fail_media_clean: > > + media_entity_cleanup(&vdev->entity); > > + > > + return ret; > > +} > > + > > +static void > > +mtk_cam_video_unregister_device(struct mtk_cam_video_device *node) > > +{ > > + video_unregister_device(&node->vdev); > > + vb2_queue_release(&node->vbq); > > + media_entity_cleanup(&node->vdev.entity); > > + mutex_destroy(&node->vdev_lock); > > +} > > + > > +static int mtk_cam_v4l2_register(struct mtk_cam_dev *cam) > > +{ > > + struct device *dev = cam->dev; > > + int i, ret; > > + > > + /* Set up media device & pads */ > > + ret = mtk_cam_media_register(cam, &cam->media_dev); > > + if (ret) > > + return ret; > > + dev_info(dev, "Registered media%d\n", cam->media_dev.devnode->minor); > > + > > + /* Set up v4l2 device */ > > + cam->v4l2_dev.mdev = &cam->media_dev; > > + ret = v4l2_device_register(dev, &cam->v4l2_dev); > > + if (ret) { > > + dev_err(dev, "failed to register V4L2 device:%d\n", ret); > > + goto fail_media_unreg; > > + } > > + dev_info(dev, "Registered %s\n", cam->v4l2_dev.name); > > + > > + /* Initialize subdev */ > > + v4l2_subdev_init(&cam->subdev, &mtk_cam_subdev_ops); > > + cam->subdev.entity.function = MEDIA_ENT_F_PROC_VIDEO_PIXEL_FORMATTER; > > + cam->subdev.entity.ops = &mtk_cam_media_entity_ops; > > + cam->subdev.flags = V4L2_SUBDEV_FL_HAS_DEVNODE | > > + V4L2_SUBDEV_FL_HAS_EVENTS; > > + snprintf(cam->subdev.name, sizeof(cam->subdev.name), > > + "%s", dev_driver_string(dev)); > > + v4l2_set_subdevdata(&cam->subdev, cam); > > + > > + ret = v4l2_device_register_subdev(&cam->v4l2_dev, &cam->subdev); > > + if (ret) { > > + dev_err(dev, "failed to initialize subdev:%d\n", ret); > > + goto fail_clean_media_entiy; > > + } > > + dev_dbg(dev, "registered %s\n", cam->subdev.name); > > + > > + /* Create video nodes and links */ > > + for (i = 0; i < MTK_CAM_P1_TOTAL_NODES; i++) { > > + struct mtk_cam_video_device *node = &cam->vdev_nodes[i]; > > + > > + node->id = node->desc.id; > > + ret = mtk_cam_video_register_device(cam, node); > > + if (ret) > > + goto fail_vdev_unreg; > > + } > > + vb2_dma_contig_set_max_seg_size(dev, DMA_BIT_MASK(32)); > > + > > + return 0; > > + > > +fail_vdev_unreg: > > + for (i--; i >= 0; i--) > > + mtk_cam_video_unregister_device(&cam->vdev_nodes[i]); > > +fail_clean_media_entiy: > > + media_entity_cleanup(&cam->subdev.entity); > > + v4l2_device_unregister(&cam->v4l2_dev); > > +fail_media_unreg: > > + media_device_unregister(&cam->media_dev); > > + media_device_cleanup(&cam->media_dev); > > + > > + return ret; > > +} > > + > > +static int mtk_cam_v4l2_unregister(struct mtk_cam_dev *cam) > > +{ > > + int i; > > + > > + for (i = 0; i < MTK_CAM_P1_TOTAL_NODES; i++) > > + mtk_cam_video_unregister_device(&cam->vdev_nodes[i]); > > + > > + vb2_dma_contig_clear_max_seg_size(cam->dev); > > + v4l2_device_unregister_subdev(&cam->subdev); > > + v4l2_device_unregister(&cam->v4l2_dev); > > + media_entity_cleanup(&cam->subdev.entity); > > + media_device_unregister(&cam->media_dev); > > + media_device_cleanup(&cam->media_dev); > > + > > + return 0; > > +} > > + > > +static int mtk_cam_dev_notifier_bound(struct v4l2_async_notifier *notifier, > > + struct v4l2_subdev *sd, > > + struct v4l2_async_subdev *asd) > > +{ > > + struct mtk_cam_dev *cam = > > + container_of(notifier, struct mtk_cam_dev, notifier); > > + > > + if (!(sd->entity.function & MEDIA_ENT_F_VID_IF_BRIDGE)) { > > + dev_dbg(cam->dev, "no MEDIA_ENT_F_VID_IF_BRIDGE function\n"); > > + return -ENODEV; > > + } > > + > > + cam->seninf = sd; > > + dev_dbg(cam->dev, "%s is bound\n", sd->entity.name); > > + > > + return 0; > > +} > > + > > +static void mtk_cam_dev_notifier_unbind(struct v4l2_async_notifier *notifier, > > + struct v4l2_subdev *sd, > > + struct v4l2_async_subdev *asd) > > +{ > > + struct mtk_cam_dev *cam = > > + container_of(notifier, struct mtk_cam_dev, notifier); > > + > > + cam->seninf = NULL; > > + dev_dbg(cam->dev, "%s is unbound\n", sd->entity.name); > > +} > > + > > +static int mtk_cam_dev_notifier_complete(struct v4l2_async_notifier *notifier) > > +{ > > + struct mtk_cam_dev *cam = > > + container_of(notifier, struct mtk_cam_dev, notifier); > > + struct device *dev = cam->dev; > > + int ret; > > + > > + if (!cam->seninf) { > > + dev_err(dev, "No seninf subdev\n"); > > + return -ENODEV; > > + } > > + > > + ret = media_create_pad_link(&cam->seninf->entity, MTK_CAM_CIO_PAD_SRC, > > + &cam->subdev.entity, MTK_CAM_CIO_PAD_SINK, > > + MEDIA_LNK_FL_IMMUTABLE | > > + MEDIA_LNK_FL_ENABLED); > > + if (ret) { > > + dev_err(dev, "failed to create pad link %s %s err:%d\n", > > + cam->seninf->entity.name, cam->subdev.entity.name, > > + ret); > > + return ret; > > + } > > + > > + ret = v4l2_device_register_subdev_nodes(&cam->v4l2_dev); > > + if (ret) { > > + dev_err(dev, "failed to initialize subdev nodes:%d\n", ret); > > + return ret; > > + } > > + > > + return ret; > > +} > > + > > +static const struct v4l2_async_notifier_operations mtk_cam_v4l2_async_ops = { > > + .bound = mtk_cam_dev_notifier_bound, > > + .unbind = mtk_cam_dev_notifier_unbind, > > + .complete = mtk_cam_dev_notifier_complete, > > +}; > > + > > +static int mtk_cam_v4l2_async_register(struct mtk_cam_dev *cam) > > +{ > > + struct device *dev = cam->dev; > > + int ret; > > + > > + v4l2_async_notifier_init(&cam->notifier); > > + ret = v4l2_async_notifier_parse_fwnode_endpoints(dev, > > + &cam->notifier, sizeof(struct v4l2_async_subdev), NULL); > > It seems we shouldn't be using this function, please see comments at https://patchwork.kernel.org/patch/11066527/ > > Regards, > Helen > Ok, we will investigate how to do. > > + if (ret) { > > + dev_err(dev, "failed to parse fwnode endpoints:%d\n", ret); > > + return ret; > > + } > > + > > + cam->notifier.ops = &mtk_cam_v4l2_async_ops; > > + dev_dbg(dev, "mtk_cam v4l2_async_notifier_register\n"); > > + ret = v4l2_async_notifier_register(&cam->v4l2_dev, &cam->notifier); > > + if (ret) { > > + dev_err(dev, "failed to register async notifier : %d\n", ret); > > + v4l2_async_notifier_cleanup(&cam->notifier); > > + } > > + > > + return ret; > > +} > > + > > +static void mtk_cam_v4l2_async_unregister(struct mtk_cam_dev *cam) > > +{ > > + v4l2_async_notifier_unregister(&cam->notifier); > > + v4l2_async_notifier_cleanup(&cam->notifier); > > +} > > + > > +static const struct v4l2_ioctl_ops mtk_cam_v4l2_vcap_ioctl_ops = { > > + .vidioc_querycap = mtk_cam_vidioc_querycap, > > + .vidioc_enum_framesizes = mtk_cam_vidioc_enum_framesizes, > > + .vidioc_enum_fmt_vid_cap = mtk_cam_vidioc_enum_fmt, > > + .vidioc_g_fmt_vid_cap_mplane = mtk_cam_vidioc_g_fmt, > > + .vidioc_s_fmt_vid_cap_mplane = mtk_cam_vidioc_s_fmt, > > + .vidioc_try_fmt_vid_cap_mplane = mtk_cam_vidioc_try_fmt, > > + .vidioc_reqbufs = vb2_ioctl_reqbufs, > > + .vidioc_create_bufs = vb2_ioctl_create_bufs, > > + .vidioc_prepare_buf = vb2_ioctl_prepare_buf, > > + .vidioc_querybuf = vb2_ioctl_querybuf, > > + .vidioc_qbuf = vb2_ioctl_qbuf, > > + .vidioc_dqbuf = vb2_ioctl_dqbuf, > > + .vidioc_streamon = vb2_ioctl_streamon, > > + .vidioc_streamoff = vb2_ioctl_streamoff, > > + .vidioc_expbuf = vb2_ioctl_expbuf, > > + .vidioc_subscribe_event = v4l2_ctrl_subscribe_event, > > + .vidioc_unsubscribe_event = v4l2_event_unsubscribe, > > +}; > > + > > +static const struct v4l2_ioctl_ops mtk_cam_v4l2_meta_cap_ioctl_ops = { > > + .vidioc_querycap = mtk_cam_vidioc_querycap, > > + .vidioc_enum_fmt_meta_cap = mtk_cam_vidioc_meta_enum_fmt, > > + .vidioc_g_fmt_meta_cap = mtk_cam_vidioc_g_meta_fmt, > > + .vidioc_s_fmt_meta_cap = mtk_cam_vidioc_g_meta_fmt, > > + .vidioc_try_fmt_meta_cap = mtk_cam_vidioc_g_meta_fmt, > > + .vidioc_reqbufs = vb2_ioctl_reqbufs, > > + .vidioc_create_bufs = vb2_ioctl_create_bufs, > > + .vidioc_prepare_buf = vb2_ioctl_prepare_buf, > > + .vidioc_querybuf = vb2_ioctl_querybuf, > > + .vidioc_qbuf = vb2_ioctl_qbuf, > > + .vidioc_dqbuf = vb2_ioctl_dqbuf, > > + .vidioc_streamon = vb2_ioctl_streamon, > > + .vidioc_streamoff = vb2_ioctl_streamoff, > > + .vidioc_expbuf = vb2_ioctl_expbuf, > > +}; > > + > > +static const struct v4l2_ioctl_ops mtk_cam_v4l2_meta_out_ioctl_ops = { > > + .vidioc_querycap = mtk_cam_vidioc_querycap, > > + .vidioc_enum_fmt_meta_out = mtk_cam_vidioc_meta_enum_fmt, > > + .vidioc_g_fmt_meta_out = mtk_cam_vidioc_g_meta_fmt, > > + .vidioc_s_fmt_meta_out = mtk_cam_vidioc_g_meta_fmt, > > + .vidioc_try_fmt_meta_out = mtk_cam_vidioc_g_meta_fmt, > > + .vidioc_reqbufs = vb2_ioctl_reqbufs, > > + .vidioc_create_bufs = vb2_ioctl_create_bufs, > > + .vidioc_prepare_buf = vb2_ioctl_prepare_buf, > > + .vidioc_querybuf = vb2_ioctl_querybuf, > > + .vidioc_qbuf = vb2_ioctl_qbuf, > > + .vidioc_dqbuf = vb2_ioctl_dqbuf, > > + .vidioc_streamon = vb2_ioctl_streamon, > > + .vidioc_streamoff = vb2_ioctl_streamoff, > > + .vidioc_expbuf = vb2_ioctl_expbuf, > > +};> + > > +static const struct v4l2_format meta_fmts[] = { > > + { > > + .fmt.meta = { > > + .dataformat = V4L2_META_FMT_MTISP_PARAMS, > > + .buffersize = 512 * SZ_1K, > > + }, > > + }, > > + { > > + .fmt.meta = { > > + .dataformat = V4L2_META_FMT_MTISP_3A, > > + .buffersize = 1200 * SZ_1K, > > + }, > > + }, > > + { > > + .fmt.meta = { > > + .dataformat = V4L2_META_FMT_MTISP_AF, > > + .buffersize = 640 * SZ_1K, > > + }, > > + }, > > + { > > + .fmt.meta = { > > + .dataformat = V4L2_META_FMT_MTISP_LCS, > > + .buffersize = 288 * SZ_1K, > > + }, > > + }, > > + { > > + .fmt.meta = { > > + .dataformat = V4L2_META_FMT_MTISP_LMV, > > + .buffersize = 256, > > + }, > > + }, > > +}; > > + > > +static const struct v4l2_format stream_out_fmts[] = { > > + /* This is a default image format */ > > + { > > + .fmt.pix_mp = { > > + .width = IMG_MAX_WIDTH, > > + .height = IMG_MAX_HEIGHT, > > + .pixelformat = V4L2_PIX_FMT_MTISP_SBGGR10, > > + }, > > + }, > > + { > > + .fmt.pix_mp = { > > + .width = IMG_MAX_WIDTH, > > + .height = IMG_MAX_HEIGHT, > > + .pixelformat = V4L2_PIX_FMT_MTISP_SBGGR8, > > + }, > > + }, > > + { > > + .fmt.pix_mp = { > > + .width = IMG_MAX_WIDTH, > > + .height = IMG_MAX_HEIGHT, > > + .pixelformat = V4L2_PIX_FMT_MTISP_SBGGR12, > > + }, > > + }, > > + { > > + .fmt.pix_mp = { > > + .width = IMG_MAX_WIDTH, > > + .height = IMG_MAX_HEIGHT, > > + .pixelformat = V4L2_PIX_FMT_MTISP_SBGGR14, > > + }, > > + }, > > + { > > + .fmt.pix_mp = { > > + .width = IMG_MAX_WIDTH, > > + .height = IMG_MAX_HEIGHT, > > + .pixelformat = V4L2_PIX_FMT_MTISP_SGBRG8, > > + }, > > + }, > > + { > > + .fmt.pix_mp = { > > + .width = IMG_MAX_WIDTH, > > + .height = IMG_MAX_HEIGHT, > > + .pixelformat = V4L2_PIX_FMT_MTISP_SGBRG10, > > + }, > > + }, > > + { > > + .fmt.pix_mp = { > > + .width = IMG_MAX_WIDTH, > > + .height = IMG_MAX_HEIGHT, > > + .pixelformat = V4L2_PIX_FMT_MTISP_SGBRG12, > > + }, > > + }, > > + { > > + .fmt.pix_mp = { > > + .width = IMG_MAX_WIDTH, > > + .height = IMG_MAX_HEIGHT, > > + .pixelformat = V4L2_PIX_FMT_MTISP_SGBRG14, > > + }, > > + }, > > + { > > + .fmt.pix_mp = { > > + .width = IMG_MAX_WIDTH, > > + .height = IMG_MAX_HEIGHT, > > + .pixelformat = V4L2_PIX_FMT_MTISP_SGRBG8, > > + }, > > + }, > > + { > > + .fmt.pix_mp = { > > + .width = IMG_MAX_WIDTH, > > + .height = IMG_MAX_HEIGHT, > > + .pixelformat = V4L2_PIX_FMT_MTISP_SGRBG10, > > + }, > > + }, > > + { > > + .fmt.pix_mp = { > > + .width = IMG_MAX_WIDTH, > > + .height = IMG_MAX_HEIGHT, > > + .pixelformat = V4L2_PIX_FMT_MTISP_SGRBG12, > > + }, > > + }, > > + { > > + .fmt.pix_mp = { > > + .width = IMG_MAX_WIDTH, > > + .height = IMG_MAX_HEIGHT, > > + .pixelformat = V4L2_PIX_FMT_MTISP_SGRBG14, > > + }, > > + }, > > + { > > + .fmt.pix_mp = { > > + .width = IMG_MAX_WIDTH, > > + .height = IMG_MAX_HEIGHT, > > + .pixelformat = V4L2_PIX_FMT_MTISP_SRGGB8, > > + }, > > + }, > > + { > > + .fmt.pix_mp = { > > + .width = IMG_MAX_WIDTH, > > + .height = IMG_MAX_HEIGHT, > > + .pixelformat = V4L2_PIX_FMT_MTISP_SRGGB10, > > + }, > > + }, > > + { > > + .fmt.pix_mp = { > > + .width = IMG_MAX_WIDTH, > > + .height = IMG_MAX_HEIGHT, > > + .pixelformat = V4L2_PIX_FMT_MTISP_SRGGB12, > > + }, > > + }, > > + { > > + .fmt.pix_mp = { > > + .width = IMG_MAX_WIDTH, > > + .height = IMG_MAX_HEIGHT, > > + .pixelformat = V4L2_PIX_FMT_MTISP_SRGGB14, > > + }, > > + }, > > +}; > > + > > +static const struct v4l2_format bin_out_fmts[] = { > > + { > > + .fmt.pix_mp = { > > + .width = IMG_MAX_WIDTH, > > + .height = IMG_MAX_HEIGHT, > > + .pixelformat = V4L2_PIX_FMT_MTISP_SBGGR8F, > > + }, > > + }, > > + { > > + .fmt.pix_mp = { > > + .width = IMG_MAX_WIDTH, > > + .height = IMG_MAX_HEIGHT, > > + .pixelformat = V4L2_PIX_FMT_MTISP_SBGGR10F, > > + }, > > + }, > > + { > > + .fmt.pix_mp = { > > + .width = IMG_MAX_WIDTH, > > + .height = IMG_MAX_HEIGHT, > > + .pixelformat = V4L2_PIX_FMT_MTISP_SBGGR12F, > > + }, > > + }, > > + { > > + .fmt.pix_mp = { > > + .width = IMG_MAX_WIDTH, > > + .height = IMG_MAX_HEIGHT, > > + .pixelformat = V4L2_PIX_FMT_MTISP_SBGGR14F, > > + }, > > + }, > > + { > > + .fmt.pix_mp = { > > + .width = IMG_MAX_WIDTH, > > + .height = IMG_MAX_HEIGHT, > > + .pixelformat = V4L2_PIX_FMT_MTISP_SGBRG8F, > > + }, > > + }, > > + { > > + .fmt.pix_mp = { > > + .width = IMG_MAX_WIDTH, > > + .height = IMG_MAX_HEIGHT, > > + .pixelformat = V4L2_PIX_FMT_MTISP_SGBRG10F, > > + }, > > + }, > > + { > > + .fmt.pix_mp = { > > + .width = IMG_MAX_WIDTH, > > + .height = IMG_MAX_HEIGHT, > > + .pixelformat = V4L2_PIX_FMT_MTISP_SGBRG12F, > > + }, > > + }, > > + { > > + .fmt.pix_mp = { > > + .width = IMG_MAX_WIDTH, > > + .height = IMG_MAX_HEIGHT, > > + .pixelformat = V4L2_PIX_FMT_MTISP_SGBRG14F, > > + }, > > + }, > > + { > > + .fmt.pix_mp = { > > + .width = IMG_MAX_WIDTH, > > + .height = IMG_MAX_HEIGHT, > > + .pixelformat = V4L2_PIX_FMT_MTISP_SGRBG8F, > > + }, > > + }, > > + { > > + .fmt.pix_mp = { > > + .width = IMG_MAX_WIDTH, > > + .height = IMG_MAX_HEIGHT, > > + .pixelformat = V4L2_PIX_FMT_MTISP_SGRBG10F, > > + }, > > + }, > > + { > > + .fmt.pix_mp = { > > + .width = IMG_MAX_WIDTH, > > + .height = IMG_MAX_HEIGHT, > > + .pixelformat = V4L2_PIX_FMT_MTISP_SGRBG12F, > > + }, > > + }, > > + { > > + .fmt.pix_mp = { > > + .width = IMG_MAX_WIDTH, > > + .height = IMG_MAX_HEIGHT, > > + .pixelformat = V4L2_PIX_FMT_MTISP_SGRBG14F, > > + }, > > + }, > > + { > > + .fmt.pix_mp = { > > + .width = IMG_MAX_WIDTH, > > + .height = IMG_MAX_HEIGHT, > > + .pixelformat = V4L2_PIX_FMT_MTISP_SRGGB8F, > > + }, > > + }, > > + { > > + .fmt.pix_mp = { > > + .width = IMG_MAX_WIDTH, > > + .height = IMG_MAX_HEIGHT, > > + .pixelformat = V4L2_PIX_FMT_MTISP_SRGGB10F, > > + }, > > + }, > > + { > > + .fmt.pix_mp = { > > + .width = IMG_MAX_WIDTH, > > + .height = IMG_MAX_HEIGHT, > > + .pixelformat = V4L2_PIX_FMT_MTISP_SRGGB12F, > > + }, > > + }, > > + { > > + .fmt.pix_mp = { > > + .width = IMG_MAX_WIDTH, > > + .height = IMG_MAX_HEIGHT, > > + .pixelformat = V4L2_PIX_FMT_MTISP_SRGGB14F, > > + }, > > + }, > > +}; > > + > > +static const struct > > +mtk_cam_dev_node_desc output_queues[] = { > > + { > > + .id = MTK_CAM_P1_META_IN_0, > > + .name = "meta input", > > + .cap = V4L2_CAP_META_OUTPUT, > > + .buf_type = V4L2_BUF_TYPE_META_OUTPUT, > > + .link_flags = 0, > > + .image = false, > > + .smem_alloc = true, > > + .fmts = meta_fmts, > > + .default_fmt_idx = 0, > > + .max_buf_count = 10, > > + .ioctl_ops = &mtk_cam_v4l2_meta_out_ioctl_ops, > > + }, > > +}; > > + > > +static const struct > > +mtk_cam_dev_node_desc capture_queues[] = { > > + { > > + .id = MTK_CAM_P1_MAIN_STREAM_OUT, > > + .name = "main stream", > > + .cap = V4L2_CAP_VIDEO_CAPTURE_MPLANE, > > + .buf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, > > + .link_flags = MEDIA_LNK_FL_IMMUTABLE | MEDIA_LNK_FL_ENABLED, > > + .image = true, > > + .smem_alloc = false, > > + .dma_port = R_IMGO, > > + .fmts = stream_out_fmts, > > + .num_fmts = ARRAY_SIZE(stream_out_fmts), > > + .default_fmt_idx = 0, > > + .ioctl_ops = &mtk_cam_v4l2_vcap_ioctl_ops, > > + .frmsizes = &(struct v4l2_frmsizeenum) { > > + .index = 0, > > + .type = V4L2_FRMSIZE_TYPE_CONTINUOUS, > > + .stepwise = { > > + .max_width = IMG_MAX_WIDTH, > > + .min_width = IMG_MIN_WIDTH, > > + .max_height = IMG_MAX_HEIGHT, > > + .min_height = IMG_MIN_HEIGHT, > > + .step_height = 1, > > + .step_width = 1, > > + }, > > + }, > > + }, > > + { > > + .id = MTK_CAM_P1_PACKED_BIN_OUT, > > + .name = "packed out", > > + .cap = V4L2_CAP_VIDEO_CAPTURE_MPLANE, > > + .buf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, > > + .link_flags = 0, > > + .image = true, > > + .smem_alloc = false, > > + .dma_port = R_RRZO, > > + .fmts = bin_out_fmts, > > + .num_fmts = ARRAY_SIZE(bin_out_fmts), > > + .default_fmt_idx = 0, > > + .ioctl_ops = &mtk_cam_v4l2_vcap_ioctl_ops, > > + .frmsizes = &(struct v4l2_frmsizeenum) { > > + .index = 0, > > + .type = V4L2_FRMSIZE_TYPE_CONTINUOUS, > > + .stepwise = { > > + .max_width = IMG_MAX_WIDTH, > > + .min_width = IMG_MIN_WIDTH, > > + .max_height = IMG_MAX_HEIGHT, > > + .min_height = IMG_MIN_HEIGHT, > > + .step_height = 1, > > + .step_width = 1, > > + }, > > + }, > > + }, > > + { > > + .id = MTK_CAM_P1_META_OUT_0, > > + .name = "partial meta 0", > > + .cap = V4L2_CAP_META_CAPTURE, > > + .buf_type = V4L2_BUF_TYPE_META_CAPTURE, > > + .link_flags = 0, > > + .image = false, > > + .smem_alloc = false, > > + .dma_port = R_AAO | R_FLKO | R_PSO, > > + .fmts = meta_fmts, > > + .default_fmt_idx = 1, > > + .max_buf_count = 5, > > + .ioctl_ops = &mtk_cam_v4l2_meta_cap_ioctl_ops, > > + }, > > + { > > + .id = MTK_CAM_P1_META_OUT_1, > > + .name = "partial meta 1", > > + .cap = V4L2_CAP_META_CAPTURE, > > + .buf_type = V4L2_BUF_TYPE_META_CAPTURE, > > + .link_flags = 0, > > + .image = false, > > + .smem_alloc = false, > > + .dma_port = R_AFO, > > + .fmts = meta_fmts, > > + .default_fmt_idx = 2, > > + .max_buf_count = 5, > > + .ioctl_ops = &mtk_cam_v4l2_meta_cap_ioctl_ops, > > + }, > > + { > > + .id = MTK_CAM_P1_META_OUT_2, > > + .name = "partial meta 2", > > + .cap = V4L2_CAP_META_CAPTURE, > > + .buf_type = V4L2_BUF_TYPE_META_CAPTURE, > > + .link_flags = 0, > > + .image = false, > > + .smem_alloc = false, > > + .dma_port = R_LCSO, > > + .fmts = meta_fmts, > > + .default_fmt_idx = 3, > > + .max_buf_count = 10, > > + .ioctl_ops = &mtk_cam_v4l2_meta_cap_ioctl_ops, > > + }, > > + { > > + .id = MTK_CAM_P1_META_OUT_3, > > + .name = "partial meta 3", > > + .cap = V4L2_CAP_META_CAPTURE, > > + .buf_type = V4L2_BUF_TYPE_META_CAPTURE, > > + .link_flags = 0, > > + .image = false, > > + .smem_alloc = false, > > + .dma_port = R_LMVO, > > + .fmts = meta_fmts, > > + .default_fmt_idx = 4, > > + .max_buf_count = 10, > > + .ioctl_ops = &mtk_cam_v4l2_meta_cap_ioctl_ops, > > + }, > > +}; > > + > > +/* The helper to configure the device context */ > > +static void mtk_cam_dev_queue_setup(struct mtk_cam_dev *cam) > > +{ > > + unsigned int node_idx; > > + int i; > > + > > + node_idx = 0; > > + /* Setup the output queue */ > > + for (i = 0; i < ARRAY_SIZE(output_queues); i++) > > + cam->vdev_nodes[node_idx++].desc = output_queues[i]; > > + > > + /* Setup the capture queue */ > > + for (i = 0; i < ARRAY_SIZE(capture_queues); i++) > > + cam->vdev_nodes[node_idx++].desc = capture_queues[i]; > > +} > > + > > +int mtk_cam_dev_init(struct platform_device *pdev, > > + struct mtk_cam_dev *cam) > > +{ > > + int ret; > > + > > + cam->dev = &pdev->dev; > > + mtk_cam_dev_queue_setup(cam); > > + > > + spin_lock_init(&cam->pending_job_lock); > > + spin_lock_init(&cam->running_job_lock); > > + INIT_LIST_HEAD(&cam->pending_job_list); > > + INIT_LIST_HEAD(&cam->running_job_list); > > + mutex_init(&cam->op_lock); > > + > > + /* v4l2 sub-device registration */ > > + ret = mtk_cam_v4l2_register(cam); > > + if (ret) > > + return ret; > > + > > + ret = mtk_cam_v4l2_async_register(cam); > > + if (ret) > > + goto fail_v4l2_unreg; > > + > > + return 0; > > + > > +fail_v4l2_unreg: > > + mutex_destroy(&cam->op_lock); > > + mtk_cam_v4l2_unregister(cam); > > + > > + return ret; > > +} > > + > > +void mtk_cam_dev_cleanup(struct mtk_cam_dev *cam) > > +{ > > + mtk_cam_v4l2_async_unregister(cam); > > + mtk_cam_v4l2_unregister(cam); > > + mutex_destroy(&cam->op_lock); > > +} > > + > > diff --git a/drivers/media/platform/mtk-isp/isp_50/cam/mtk_cam.h b/drivers/media/platform/mtk-isp/isp_50/cam/mtk_cam.h > > new file mode 100644 > > index 000000000000..0a340a1e65ea > > --- /dev/null > > +++ b/drivers/media/platform/mtk-isp/isp_50/cam/mtk_cam.h > > @@ -0,0 +1,244 @@ > > +/* SPDX-License-Identifier: GPL-2.0 */ > > +/* > > + * Copyright (c) 2019 MediaTek Inc. > > + */ > > + > > +#ifndef __MTK_CAM_H__ > > +#define __MTK_CAM_H__ > > + > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > + > > +#include "mtk_cam-ipi.h" > > + > > +#define IMG_MAX_WIDTH 5376 > > +#define IMG_MAX_HEIGHT 4032 > > +#define IMG_MIN_WIDTH 80 > > +#define IMG_MIN_HEIGHT 60 > > + > > +/* > > + * ID enum value for struct mtk_cam_dev_node_desc:id > > + * or mtk_cam_video_device:id > > + */ > > +enum { > > + MTK_CAM_P1_META_IN_0 = 0, > > + MTK_CAM_P1_MAIN_STREAM_OUT, > > + MTK_CAM_P1_PACKED_BIN_OUT, > > + MTK_CAM_P1_META_OUT_0, > > + MTK_CAM_P1_META_OUT_1, > > + MTK_CAM_P1_META_OUT_2, > > + MTK_CAM_P1_META_OUT_3, > > + MTK_CAM_P1_TOTAL_NODES > > +}; > > + > > +/* Supported image format list */ > > +#define MTK_CAM_IMG_FMT_UNKNOWN 0x0000 > > +#define MTK_CAM_IMG_FMT_BAYER8 0x2200 > > +#define MTK_CAM_IMG_FMT_BAYER10 0x2201 > > +#define MTK_CAM_IMG_FMT_BAYER12 0x2202 > > +#define MTK_CAM_IMG_FMT_BAYER14 0x2203 > > +#define MTK_CAM_IMG_FMT_FG_BAYER8 0x2204 > > +#define MTK_CAM_IMG_FMT_FG_BAYER10 0x2205 > > +#define MTK_CAM_IMG_FMT_FG_BAYER12 0x2206 > > +#define MTK_CAM_IMG_FMT_FG_BAYER14 0x2207 > > + > > +/* Supported bayer pixel order */ > > +#define MTK_CAM_RAW_PXL_ID_B 0 > > +#define MTK_CAM_RAW_PXL_ID_GB 1 > > +#define MTK_CAM_RAW_PXL_ID_GR 2 > > +#define MTK_CAM_RAW_PXL_ID_R 3 > > +#define MTK_CAM_RAW_PXL_ID_UNKNOWN 4 > > + > > +/* > > + * struct mtk_p1_frame_param - MTK ISP P1 driver frame parameters. > > + * > > + * @frame_seq_no: The frame sequence of frame in driver layer. > > + * @dma_bufs: The DMA buffer address information of enabled DMA nodes. > > + * > > + */ > > +struct mtk_p1_frame_param { > > + unsigned int frame_seq_no; > > + struct dma_buffer dma_bufs[MTK_CAM_P1_TOTAL_NODES]; > > +} __packed; > > + > > +/* > > + * struct mtk_cam_dev_request - MTK camera device request. > > + * > > + * @req: Embedded struct media request. > > + * @frame_params: The frame info. & address info. of enabled DMA nodes. > > + * @frame_work: work queue entry for frame transmission to SCP. > > + * @list: List entry of the object for @struct mtk_cam_dev: > > + * pending_job_list or running_job_list. > > + * @timestamp: Start of frame timestamp in ns > > + * > > + */ > > +struct mtk_cam_dev_request { > > + struct media_request req; > > + struct mtk_p1_frame_param frame_params; > > + struct work_struct frame_work; > > + struct list_head list; > > + u64 timestamp; > > +}; > > + > > +/* > > + * struct mtk_cam_dev_buffer - MTK camera device buffer. > > + * > > + * @vbb: Embedded struct vb2_v4l2_buffer. > > + * @list: List entry of the object for @struct mtk_cam_video_device: > > + * buf_list. > > + * @daddr: The DMA address of this buffer. > > + * @scp_addr: The SCP address of this buffer which > > + * is only supported for meta input node. > > + * @node_id: The vidoe node id which this buffer belongs to. > > + * > > + */ > > +struct mtk_cam_dev_buffer { > > + struct vb2_v4l2_buffer vbb; > > + struct list_head list; > > + /* Intenal part */ > > + dma_addr_t daddr; > > + dma_addr_t scp_addr; > > + unsigned int node_id; > > +}; > > + > > +/* > > + * struct mtk_cam_dev_node_desc - MTK camera device node descriptor > > + * > > + * @id: id of the node > > + * @name: name of the node > > + * @cap: supported V4L2 capabilities > > + * @buf_type: supported V4L2 buffer type > > + * @dma_port: the dma ports associated to the node > > + * @link_flags: default media link flags > > + * @smem_alloc: using the smem_dev as alloc device or not > > + * @image: true for image node, false for meta node > > + * @num_fmts: the number of supported node formats > > + * @default_fmt_idx: default format of this node > > + * @max_buf_count: maximum VB2 buffer count > > + * @ioctl_ops: mapped to v4l2_ioctl_ops > > + * @fmts: supported format > > + * @frmsizes: supported V4L2 frame size number > > + * > > + */ > > +struct mtk_cam_dev_node_desc { > > + u8 id; > > + const char *name; > > + u32 cap; > > + u32 buf_type; > > + u32 dma_port; > > + u32 link_flags; > > + u8 smem_alloc:1; > > + u8 image:1; > > + u8 num_fmts; > > + u8 default_fmt_idx; > > + u8 max_buf_count; > > + const struct v4l2_ioctl_ops *ioctl_ops; > > + const struct v4l2_format *fmts; > > + const struct v4l2_frmsizeenum *frmsizes; > > +}; > > + > > +/* > > + * struct mtk_cam_video_device - Mediatek video device structure > > + * > > + * @id: Id for index of mtk_cam_dev:vdev_nodes array > > + * @enabled: Indicate the video device is enabled or not > > + * @desc: The node description of video device > > + * @vdev_fmt: The V4L2 format of video device > > + * @vdev_pad: The media pad graph object of video device > > + * @vbq: A videobuf queue of video device > > + * @vdev: The video device instance > > + * @vdev_lock: Serializes vb2 queue and video device operations > > + * @buf_list: List for enqueue buffers > > + * @buf_list_lock: Lock used to protect buffer list. > > + * > > + */ > > +struct mtk_cam_video_device { > > + unsigned int id; > > + unsigned int enabled; > > + struct mtk_cam_dev_node_desc desc; > > + struct v4l2_format vdev_fmt; > > + struct media_pad vdev_pad; > > + struct vb2_queue vbq; > > + struct video_device vdev; > > + /* Serializes vb2 queue and video device operations */ > > + struct mutex vdev_lock; > > + struct list_head buf_list; > > + /* Lock used to protect buffer list */ > > + spinlock_t buf_list_lock; > > +}; > > + > > +/* > > + * struct mtk_cam_dev - Mediatek camera device structure. > > + * > > + * @dev: Pointer to device. > > + * @smem_pdev: Pointer to shared memory device. > > + * @pipeline: Media pipeline information. > > + * @media_dev: Media device instance. > > + * @subdev: The V4L2 sub-device instance. > > + * @v4l2_dev: The V4L2 device driver instance. > > + * @notifier: The v4l2_device notifier data. > > + * @subdev_pads: Pointer to the number of media pads of this sub-device. > > + * @vdev_nodes: The array list of mtk_cam_video_device nodes. > > + * @seninf: Pointer to the seninf sub-device. > > + * @sensor: Pointer to the active sensor V4L2 sub-device when streaming on. > > + * @streaming: Indicate the overall streaming status is on or off. > > + * @enabled_dmas: The enabled dma port information when streaming on. > > + * @enabled_count: Number of enabled video nodes > > + * @stream_count: Number of streaming video nodes > > + * @running_job_count: Nunber of running jobs in the HW driver. > > + * @pending_job_list: List to keep the media requests before en-queue into > > + * HW driver. > > + * @pending_job_lock: Protect the pending_job_list data & running_job_count. > > + * @running_job_list: List to keep the media requests after en-queue into > > + * HW driver. > > + * @running_job_lock: Protect the running_job_list data. > > + * @op_lock: Serializes driver's VB2 callback operations. > > + * > > + */ > > +struct mtk_cam_dev { > > + struct device *dev; > > + struct device *smem_dev; > > + struct media_pipeline pipeline; > > + struct media_device media_dev; > > + struct v4l2_subdev subdev; > > + struct v4l2_device v4l2_dev; > > + struct v4l2_async_notifier notifier; > > + struct media_pad *subdev_pads; > > + struct mtk_cam_video_device vdev_nodes[MTK_CAM_P1_TOTAL_NODES]; > > + struct v4l2_subdev *seninf; > > + struct v4l2_subdev *sensor; > > + unsigned int streaming; > > + unsigned int enabled_dmas; > > + unsigned int enabled_count; > > + unsigned int stream_count; > > + unsigned int running_job_count; > > + struct list_head pending_job_list; > > + /* Protect the pending_job_list data */ > > + spinlock_t pending_job_lock; > > + struct list_head running_job_list; > > + /* Protect the running_job_list data & running_job_count */ > > + spinlock_t running_job_lock; > > + /* Serializes driver's VB2 callback operations */ > > + struct mutex op_lock; > > +}; > > + > > +int mtk_cam_dev_init(struct platform_device *pdev, > > + struct mtk_cam_dev *cam_dev); > > +void mtk_cam_dev_cleanup(struct mtk_cam_dev *cam_dev); > > +void mtk_cam_dev_req_try_queue(struct mtk_cam_dev *cam_dev); > > +void mtk_cam_dev_dequeue_req_frame(struct mtk_cam_dev *cam_dev, > > + unsigned int frame_seq_no); > > +void mtk_cam_dev_event_frame_sync(struct mtk_cam_dev *cam_dev, > > + unsigned int frame_seq_no); > > +struct mtk_cam_dev_request *mtk_cam_dev_get_req(struct mtk_cam_dev *cam, > > + unsigned int frame_seq_no); > > + > > +#endif /* __MTK_CAM_H__ */ > > > > _______________________________________________ > Linux-mediatek mailing list > Linux-mediatek@lists.infradead.org > http://lists.infradead.org/mailman/listinfo/linux-mediatek _______________________________________________ Linux-mediatek mailing list Linux-mediatek@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-mediatek 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=-8.3 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,UNPARSEABLE_RELAY,URIBL_BLOCKED, USER_AGENT_SANE_2 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 5EEA5C2BA80 for ; Thu, 9 Apr 2020 02:06:16 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id BC3BA2084D for ; Thu, 9 Apr 2020 02:06:15 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=mediatek.com header.i=@mediatek.com header.b="DX1YaUNA" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726530AbgDICGO (ORCPT ); Wed, 8 Apr 2020 22:06:14 -0400 Received: from mailgw01.mediatek.com ([210.61.82.183]:49767 "EHLO mailgw01.mediatek.com" rhost-flags-OK-FAIL-OK-FAIL) by vger.kernel.org with ESMTP id S1726510AbgDICGN (ORCPT ); Wed, 8 Apr 2020 22:06:13 -0400 X-UUID: 52f8f6db0b254c729b3dc9dfef64ab47-20200409 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=mediatek.com; s=dk; h=Content-Transfer-Encoding:MIME-Version:Content-Type:References:In-Reply-To:Date:CC:To:From:Subject:Message-ID; bh=N4BHJkfgb2NG7TqXytkbwGJ7xKCtAcShB1S8zEkrxYw=; b=DX1YaUNA/JMTb5OLBmuLANiVXjXKG7+9hs3B33mKMStcj0CeFzlw+so0ipcrME9U1LKEzlwVqHWxpUZjhnRpAclditmj/gISB+KFQ5M8pR2SyxbOl9YtigMfkhlFDm9yBCqpEzwO3Z07FwWNzaa2Go/LnTW5MHTvNSUQdouVfjY=; X-UUID: 52f8f6db0b254c729b3dc9dfef64ab47-20200409 Received: from mtkcas10.mediatek.inc [(172.21.101.39)] by mailgw01.mediatek.com (envelope-from ) (Cellopoint E-mail Firewall v4.1.10 Build 0809 with TLS) with ESMTP id 851823849; Thu, 09 Apr 2020 10:05:30 +0800 Received: from MTKCAS06.mediatek.inc (172.21.101.30) by mtkmbs01n2.mediatek.inc (172.21.101.79) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Thu, 9 Apr 2020 10:05:24 +0800 Received: from [172.21.84.99] (172.21.84.99) by MTKCAS06.mediatek.inc (172.21.101.73) with Microsoft SMTP Server id 15.0.1497.2 via Frontend Transport; Thu, 9 Apr 2020 10:05:27 +0800 Message-ID: <1586397928.8406.66.camel@mtksdccf07> Subject: Re: [v6, 5/5] media: platform: Add Mediatek ISP P1 V4L2 device driver From: Jungo Lin To: Helen Koike CC: , , , , , , , , , , Pi-Hsun Shih , , , , , , , , , , , , , Date: Thu, 9 Apr 2020 10:05:28 +0800 In-Reply-To: <6cd0b8e9-2914-9440-b9ec-dbc7e01de5a1@collabora.com> References: <20191219054930.29513-1-jungo.lin@mediatek.com> <20191219054930.29513-6-jungo.lin@mediatek.com> <6cd0b8e9-2914-9440-b9ec-dbc7e01de5a1@collabora.com> Content-Type: text/plain; charset="UTF-8" X-Mailer: Evolution 3.2.3-0ubuntu6 MIME-Version: 1.0 X-TM-SNTS-SMTP: 406B4C37B047C3FE289E0D54AC96B2299E065749275A417EA97331CA9A92B2312000:8 X-MTK: N Content-Transfer-Encoding: base64 Sender: devicetree-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org SGkgSGVsZW46DQoNClRoYW5rcyBmb3IgeW91ciBjb21tZW50cy4NCg0KT24gVHVlLCAyMDIwLTAz LTMxIGF0IDEyOjM0IC0wMzAwLCBIZWxlbiBLb2lrZSB3cm90ZToNCj4gSGVsbG8gSnVuZ28sDQo+ IA0KPiBJIHdhcyB0YWtpbmcgYSBsb29rIGF0IHRoaXMgcGF0Y2ggKHRoYW5rcyBmb3IgdGhlIHdv cmspLA0KPiBJIGRpZG4ndCBsb29rIGluIGRlZXAgZGV0YWlscywgYnV0IEkgaGF2ZSBzb21lIGNv bW1lbnRzLCBwbGVhc2Ugc2VlDQo+IGJlbG93LiBJIGhvcGUgaXQgaGVscHMuDQo+IA0KPiBPbiAx Mi8xOS8xOSAzOjQ5IEFNLCBKdW5nbyBMaW4gd3JvdGU6DQo+ID4gVGhpcyBwYXRjaCBhZGRzIHRo ZSBNZWRpYXRlayBJU1AgUDEgSFcgY29udHJvbCBkZXZpY2UgZHJpdmVyLg0KPiA+IEl0IGhhbmRs ZXMgdGhlIElTUCBIVyBjb25maWd1cmF0aW9uLCBwcm92aWRlcyBpbnRlcnJ1cHQgaGFuZGxpbmcg YW5kDQo+ID4gaW5pdGlhbGl6ZXMgdGhlIFY0TDIgZGV2aWNlIG5vZGVzIGFuZCBvdGhlciBWNEwy IGZ1bmN0aW9ucy4gTW9yZW92ZXIsDQo+ID4gaW1wbGVtZW50IHN0YW5kYXJkIFY0TDIgdmlkZW8g ZHJpdmVyIHRoYXQgdXRpbGl6ZXMgVjRMMiBhbmQgbWVkaWENCj4gPiBmcmFtZXdvcmsgQVBJcy4g SXQgc3VwcG9ydHMgb25lIG1lZGlhIGRldmljZSwgb25lIHN1Yi1kZXZpY2UgYW5kDQo+ID4gc2V2 ZXJhbCB2aWRlbyBkZXZpY2VzIGR1cmluZyBpbml0aWFsaXphdGlvbi4gTW9yZW92ZXIsIGl0IGFs c28gY29ubmVjdHMNCj4gPiB3aXRoIHNlbnNvciBhbmQgc2VuaW5mIGRyaXZlcnMgd2l0aCBWNEwy IGFzeW5jIEFQSXMuIENvbW11bmljYXRlIHdpdGgNCj4gPiBjby1wcm9jZXNzIHZpYSBTQ1AgY29t bXVuaWNhdGlvbiB0byBjb21wb3NlIElTUCByZWdpc3RlcnMgaW4gdGhlDQo+ID4gZmlybXdhcmUu DQo+ID4gDQo+ID4gKFRoZSBjdXJyZW50IG1ldGFkYXRhIGludGVyZmFjZSB1c2VkIGluIG1ldGEg aW5wdXQgYW5kIHBhcnRpYWwNCj4gPiBtZXRhIG5vZGVzIGlzIG9ubHkgYSB0ZW1wb3Jhcnkgc29s dXRpb24gdG8ga2ljayBvZmYgdGhlIGRyaXZlcg0KPiA+IGRldmVsb3BtZW50IGFuZCBpcyBub3Qg cmVhZHkgdG8gYmUgcmV2aWV3ZWQgeWV0LikNCj4gPiANCj4gPiBTaWduZWQtb2ZmLWJ5OiBKdW5n byBMaW4gPGp1bmdvLmxpbkBtZWRpYXRlay5jb20+DQo+ID4gU2lnbmVkLW9mZi1ieTogVG9tYXN6 IEZpZ2EgPHRmaWdhQGNocm9taXVtLm9yZz4NCj4gPiBTaWduZWQtb2ZmLWJ5OiBQaS1Ic3VuIFNo aWggPHBpaHN1bkBjaHJvbWl1bS5vcmc+DQo+ID4gLS0tDQo+ID4gQ2hhbmdlcyBmcm9tIHY2Og0K PiA+ICAtIFJldmlzZSBoZWxwIGRlc2NyaXB0aW9uIGZvciBWSURFT19NRURJQVRFS19JU1BfUEFT UzENCj4gPiAgLSBBcHBseSBTQ1AgdjIxIGNoYW5nZSBpbiBQMSBkcml2ZXIgYnkgUGktSHN1biBT aGloDQo+ID4gIC0gQ29ycmVjdCBhdXRvIHN1c3BlbmQgdGltZXIgdmFsdWUgZm9yIHN1c3BlbmQv cmVzdW1lIGlzc3VlDQo+ID4gIC0gSW5jcmVhc2UgSVBJIGd1YXJkIHRpbWVyIHRvIDEgc2Vjb25k IHRvIGF2b2lkIGZhbHNlIGFsYXJtIGNvbW1hbmQgdGltZW91dCBldmVudA0KPiA+ICAtIEZpeCBL RSBkdWUgdG8gbm8gc2VuLWluZiBzdWItZGV2aWNlDQo+ID4gLS0tDQo+ID4gIGRyaXZlcnMvbWVk aWEvcGxhdGZvcm0vbXRrLWlzcC9LY29uZmlnICAgICAgICB8ICAgMjAgKw0KPiA+ICAuLi4vbWVk aWEvcGxhdGZvcm0vbXRrLWlzcC9pc3BfNTAvTWFrZWZpbGUgICAgfCAgICAzICsNCj4gPiAgLi4u L3BsYXRmb3JtL210ay1pc3AvaXNwXzUwL2NhbS9NYWtlZmlsZSAgICAgIHwgICAgNiArDQo+ID4g IC4uLi9wbGF0Zm9ybS9tdGstaXNwL2lzcF81MC9jYW0vbXRrX2NhbS1ody5jICB8ICA2MzYgKysr KysNCj4gPiAgLi4uL3BsYXRmb3JtL210ay1pc3AvaXNwXzUwL2NhbS9tdGtfY2FtLWh3LmggIHwg ICA2NCArDQo+ID4gIC4uLi9wbGF0Zm9ybS9tdGstaXNwL2lzcF81MC9jYW0vbXRrX2NhbS1pcGku aCB8ICAyMjIgKysNCj4gPiAgLi4uL210ay1pc3AvaXNwXzUwL2NhbS9tdGtfY2FtLXJlZ3MuaCAg ICAgICAgIHwgICA5NSArDQo+ID4gIC4uLi9wbGF0Zm9ybS9tdGstaXNwL2lzcF81MC9jYW0vbXRr X2NhbS5jICAgICB8IDIwODcgKysrKysrKysrKysrKysrKysNCj4gDQo+IEkgdGhpbmsgSSB3b3Vs ZCBzcGxpdCB0aGlzIGZpbGUgYSBiaXQsIHRvIHNlcGFyYXRlIHdoaWNoIGNvZGUgaXMgYmVpbmcg dXNlZCBmb3IgdGhlIHN1YmRldmljZSwgd2hpY2ggZm9yDQo+IGNhcHR1cmUsIHdoaWNoIGZvciBt ZXRhZGF0YSwgYW5kIHdoYXQgaXMgYmVpbmcgdXNlZCB0byBkZWFsIHdpdGggcmVxdWVzdHMuDQo+ IA0KPiBJdCB3b3VsZCBtYWtlIGl0IGVhc2llciB0byByZXZpZXcgaW1oby4NCj4gDQoNCkZvciBm aWxlIHN0cnVjdHVyZSBkZXNpZ24sIGl0IHdhcyByZXZpZXdlZCBpbiB0aGUgcHJldmlvdXMgcGF0 Y2gNCnNlcmlhbHMuDQplLmcuDQpodHRwczovL3BhdGNod29yay5rZXJuZWwub3JnL3BhdGNoLzEw OTM4MTM3Lw0KSWYgeW91IHRoaW5rIGl0IGlzIGJldHRlciwgSSB3aWxsIG1vZGlmeSBpdC4NCg0K PiA+ICAuLi4vcGxhdGZvcm0vbXRrLWlzcC9pc3BfNTAvY2FtL210a19jYW0uaCAgICAgfCAgMjQ0 ICsrDQo+IA0KPiBJdCB3b3VsZCBiZSBuaWNlIHRvIGNob3NlIGJld2VlbiBtdGtfY2FtIG9yIG10 ay1pc3AgZm9yIG5hbWluZyBmdW5jdGlvbnMsIGZpbGVzIGFuZCBjb25maWdzLCBhbmQga2VlcCBj b25zaXN0ZW5jeS4NCj4gDQo+IE9yIG1heWJlIHNvbWV0aGluZyBsaWtlOg0KPiANCj4gbXRraXNw X3AxX2NvcmUuYyAod2l0aCBwcm9iZSwgd2hvIGNyZWF0ZXMgYWxsIHRoZSBtZWRpYSBlbnRpdGll cywgZGVhbHMgd2l0aCBmd25vZGVzLCBldGMpDQo+IG10a2lzcF9wMV9jYXB0dXJlLmMNCj4gbXRr aXNwX3AxX21ldGEuYw0KPiBtdGtpc3BfcDFfaXNwLmMNCj4gbXRraXNwX3AxX2h3LmMgKG9yIG1h eWJlIHNwbGl0IHRoaXMgYmV0d2VlbiB0aGUgb3RoZXIgZmlsZXMpDQo+IG10a2lzcF9wMV9yZXF1 ZXN0LmMNCj4gbXRraXNwX3AxX2NvbW1vbi5jICg/KQ0KPiANCj4gb3Igcy9tdGtpc3BfcDEvbXRr X2NhbS8NCj4gDQo+IHdoYXQgZG8geW91IHRoaW5rPw0KPiANCg0KT2ssIEkgd2lsbCByZXZpc2Ug b3VyIG5hbWluZyBpc3N1ZSBmb3IgY29uc2lzdGVuY3kgcmVhc29uLg0KDQo+ID4gIDkgZmlsZXMg Y2hhbmdlZCwgMzM3NyBpbnNlcnRpb25zKCspDQo+ID4gIGNyZWF0ZSBtb2RlIDEwMDY0NCBkcml2 ZXJzL21lZGlhL3BsYXRmb3JtL210ay1pc3AvS2NvbmZpZw0KPiA+ICBjcmVhdGUgbW9kZSAxMDA2 NDQgZHJpdmVycy9tZWRpYS9wbGF0Zm9ybS9tdGstaXNwL2lzcF81MC9NYWtlZmlsZQ0KPiA+ICBj cmVhdGUgbW9kZSAxMDA2NDQgZHJpdmVycy9tZWRpYS9wbGF0Zm9ybS9tdGstaXNwL2lzcF81MC9j YW0vTWFrZWZpbGUNCj4gPiAgY3JlYXRlIG1vZGUgMTAwNjQ0IGRyaXZlcnMvbWVkaWEvcGxhdGZv cm0vbXRrLWlzcC9pc3BfNTAvY2FtL210a19jYW0taHcuYw0KPiA+ICBjcmVhdGUgbW9kZSAxMDA2 NDQgZHJpdmVycy9tZWRpYS9wbGF0Zm9ybS9tdGstaXNwL2lzcF81MC9jYW0vbXRrX2NhbS1ody5o DQo+ID4gIGNyZWF0ZSBtb2RlIDEwMDY0NCBkcml2ZXJzL21lZGlhL3BsYXRmb3JtL210ay1pc3Av aXNwXzUwL2NhbS9tdGtfY2FtLWlwaS5oDQo+ID4gIGNyZWF0ZSBtb2RlIDEwMDY0NCBkcml2ZXJz L21lZGlhL3BsYXRmb3JtL210ay1pc3AvaXNwXzUwL2NhbS9tdGtfY2FtLXJlZ3MuaA0KPiA+ICBj cmVhdGUgbW9kZSAxMDA2NDQgZHJpdmVycy9tZWRpYS9wbGF0Zm9ybS9tdGstaXNwL2lzcF81MC9j YW0vbXRrX2NhbS5jDQo+ID4gIGNyZWF0ZSBtb2RlIDEwMDY0NCBkcml2ZXJzL21lZGlhL3BsYXRm b3JtL210ay1pc3AvaXNwXzUwL2NhbS9tdGtfY2FtLmgNCj4gPiANCj4gPiBkaWZmIC0tZ2l0IGEv ZHJpdmVycy9tZWRpYS9wbGF0Zm9ybS9tdGstaXNwL0tjb25maWcgYi9kcml2ZXJzL21lZGlhL3Bs YXRmb3JtL210ay1pc3AvS2NvbmZpZw0KPiA+IG5ldyBmaWxlIG1vZGUgMTAwNjQ0DQo+ID4gaW5k ZXggMDAwMDAwMDAwMDAwLi5mODZlMWI1OWFkMWUNCj4gPiAtLS0gL2Rldi9udWxsDQo+ID4gKysr IGIvZHJpdmVycy9tZWRpYS9wbGF0Zm9ybS9tdGstaXNwL0tjb25maWcNCj4gPiBAQCAtMCwwICsx LDIwIEBADQo+ID4gK2NvbmZpZyBWSURFT19NRURJQVRFS19JU1BfUEFTUzENCj4gPiArCXRyaXN0 YXRlICJNZWRpYXRlayBJU1AgUGFzcyAxIGRyaXZlciINCj4gPiArCWRlcGVuZHMgb24gVklERU9f VjRMMiAmJiBWSURFT19WNEwyX1NVQkRFVl9BUEkNCj4gDQo+IEkgdGhpbmsgeW91IG5lZWQgT0Yg YXMgd2VsbA0KPiANCj4gZGVwZW5kcyBvbiBWSURFT19WNEwyICYmIFZJREVPX1Y0TDJfU1VCREVW X0FQSSAmJiBPRg0KPiANCj4gPiArCWRlcGVuZHMgb24gQVJDSF9NRURJQVRFSw0KPiANCj4gZGVw ZW5kcyBvbiBBUkNIX01FRElBVEVLIHx8IENPTVBJTEVfVEVTVA0KPiANCg0KT2ssIHdlIHdpbGwg Zml4IHRoaXMgaW4gbmV4dCBwYXRjaC4NCg0KPiA+ICsJc2VsZWN0IFY0TDJfRldOT0RFDQo+ID4g KwlzZWxlY3QgVklERU9CVUYyX1ZNQUxMT0MNCj4gPiArCXNlbGVjdCBWSURFT0JVRjJfRE1BX0NP TlRJRw0KPiA+ICsJc2VsZWN0IE1US19TQ1ANCj4gPiArCWRlZmF1bHQgbg0KPiA+ICsJaGVscA0K PiA+ICsJCVBhc3MgMSBkcml2ZXIgY29udHJvbHMgM0EgKGF1dG8tZm9jdXMsIGV4cG9zdXJlLA0K PiA+ICsJCWFuZCB3aGl0ZSBiYWxhbmNlKSB3aXRoIHR1bmluZyBmZWF0dXJlIGFuZCBvdXRwdXRz DQo+ID4gKwkJdGhlIGNhcHR1cmVkIGltYWdlIGJ1ZmZlcnMgaW4gTWVkaWF0ZWsncyBjYW1lcmEg c3lzdGVtLg0KPiA+ICsNCj4gPiArCQlDaG9vc2UgWSBpZiB5b3Ugd2FudCB0byB1c2UgTWVkaWF0 ZWsgU29DcyB0byBjcmVhdGUgaW1hZ2UNCj4gPiArCQljYXB0dXJlZCBhcHBsaWNhdGlvbiBzdWNo IGFzIHZpZGVvIHJlY29yZGluZyBhbmQgc3RpbGwgaW1hZ2UNCj4gPiArCQljYXB0dXJpbmcuDQo+ IA0KPiBJIHdvdWxkIHJlLXdvcmQgdGhpcyBhIGJpdCwgc2luY2UgcGVvcGxlIGNhbiB1c2UgYSBj YXB0dXJlZCBhcHBsaWNhdGlvbiAoYW5kIG5vdCBjcmVhdGUgb25lKSA6KQ0KPiANCg0KT2ssIEkg d2lsbCByZS13b3JkIGFzICJpZiB5b3Ugd2FudCB0byB1c2UgaW1hZ2UgY2FwdHVyZWQgYXBwbGlj YXRpb24NCmJhc2VkIG9uIE1lZGlhdGVrIFNvQ3MgZm9yIHZpZGVvIHJlY29yZGluZyBhbmQgc3Rp bGwgaW1hZ2UgY2FwdHVyaW5nDQpmdW5jdGlvbnMiDQoNCj4gPiArDQo+ID4gKwkJVG8gY29tcGls ZSB0aGlzIGRyaXZlciBhcyBhIG1vZHVsZSwgY2hvb3NlIE0gaGVyZTsgdGhlIG1vZHVsZQ0KPiA+ ICsJCXdpbGwgYmUgY2FsbGVkIG10ay1jYW0taXNwLg0KPiA+IGRpZmYgLS1naXQgYS9kcml2ZXJz L21lZGlhL3BsYXRmb3JtL210ay1pc3AvaXNwXzUwL01ha2VmaWxlIGIvZHJpdmVycy9tZWRpYS9w bGF0Zm9ybS9tdGstaXNwL2lzcF81MC9NYWtlZmlsZQ0KPiA+IG5ldyBmaWxlIG1vZGUgMTAwNjQ0 DQo+ID4gaW5kZXggMDAwMDAwMDAwMDAwLi5jZTc5ZDI4M2IyMDkNCj4gPiAtLS0gL2Rldi9udWxs DQo+ID4gKysrIGIvZHJpdmVycy9tZWRpYS9wbGF0Zm9ybS9tdGstaXNwL2lzcF81MC9NYWtlZmls ZQ0KPiA+IEBAIC0wLDAgKzEsMyBAQA0KPiA+ICsjIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBH UEwtMi4wDQo+ID4gKw0KPiA+ICtvYmotJChDT05GSUdfVklERU9fTUVESUFURUtfSVNQX1BBU1Mx KSArPSBjYW0vDQo+ID4gXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlDQo+ID4gZGlmZiAtLWdp dCBhL2RyaXZlcnMvbWVkaWEvcGxhdGZvcm0vbXRrLWlzcC9pc3BfNTAvY2FtL01ha2VmaWxlIGIv ZHJpdmVycy9tZWRpYS9wbGF0Zm9ybS9tdGstaXNwL2lzcF81MC9jYW0vTWFrZWZpbGUNCj4gPiBu ZXcgZmlsZSBtb2RlIDEwMDY0NA0KPiA+IGluZGV4IDAwMDAwMDAwMDAwMC4uNTNiNTRkM2MyNmEw DQo+ID4gLS0tIC9kZXYvbnVsbA0KPiA+ICsrKyBiL2RyaXZlcnMvbWVkaWEvcGxhdGZvcm0vbXRr LWlzcC9pc3BfNTAvY2FtL01ha2VmaWxlDQo+ID4gQEAgLTAsMCArMSw2IEBADQo+ID4gKyMgU1BE WC1MaWNlbnNlLUlkZW50aWZpZXI6IEdQTC0yLjANCj4gPiArDQo+ID4gK210ay1jYW0taXNwLW9i anMgKz0gbXRrX2NhbS5vDQo+ID4gK210ay1jYW0taXNwLW9ianMgKz0gbXRrX2NhbS1ody5vDQo+ ID4gKw0KPiA+ICtvYmotJChDT05GSUdfVklERU9fTUVESUFURUtfSVNQX1BBU1MxKSArPSBtdGst Y2FtLWlzcC5vDQo+ID4gXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlDQo+ID4gZGlmZiAtLWdp dCBhL2RyaXZlcnMvbWVkaWEvcGxhdGZvcm0vbXRrLWlzcC9pc3BfNTAvY2FtL210a19jYW0taHcu YyBiL2RyaXZlcnMvbWVkaWEvcGxhdGZvcm0vbXRrLWlzcC9pc3BfNTAvY2FtL210a19jYW0taHcu Yw0KPiA+IG5ldyBmaWxlIG1vZGUgMTAwNjQ0DQo+ID4gaW5kZXggMDAwMDAwMDAwMDAwLi40MDY1 ZDBkMjliN2YNCj4gPiAtLS0gL2Rldi9udWxsDQo+ID4gKysrIGIvZHJpdmVycy9tZWRpYS9wbGF0 Zm9ybS9tdGstaXNwL2lzcF81MC9jYW0vbXRrX2NhbS1ody5jDQo+ID4gQEAgLTAsMCArMSw2MzYg QEANCj4gPiArLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEdQTC0yLjANCj4gPiArLy8NCj4g PiArLy8gQ29weXJpZ2h0IChjKSAyMDE5IE1lZGlhVGVrIEluYy4NCj4gPiArDQo+ID4gKyNpbmNs dWRlIDxsaW51eC9hdG9taWMuaD4NCj4gPiArI2luY2x1ZGUgPGxpbnV4L2Nsay5oPg0KPiA+ICsj aW5jbHVkZSA8bGludXgvaW50ZXJydXB0Lmg+DQo+ID4gKyNpbmNsdWRlIDxsaW51eC9pb3BvbGwu aD4NCj4gPiArI2luY2x1ZGUgPGxpbnV4L29mX3BsYXRmb3JtLmg+DQo+ID4gKyNpbmNsdWRlIDxs aW51eC9vZl9pcnEuaD4NCj4gPiArI2luY2x1ZGUgPGxpbnV4L21vZHVsZS5oPg0KPiA+ICsjaW5j bHVkZSA8bGludXgvcmVtb3RlcHJvYy9tdGtfc2NwLmg+DQo+ID4gKyNpbmNsdWRlIDxsaW51eC9w bV9ydW50aW1lLmg+DQo+ID4gKyNpbmNsdWRlIDxsaW51eC9yZW1vdGVwcm9jLmg+DQo+ID4gKyNp bmNsdWRlIDxsaW51eC9zY2hlZC5oPg0KPiA+ICsjaW5jbHVkZSA8bGludXgvc3BpbmxvY2suaD4N Cj4gPiArI2luY2x1ZGUgPGxpbnV4L3R5cGVzLmg+DQo+ID4gKyNpbmNsdWRlIDxsaW51eC92aWRl b2RldjIuaD4NCj4gPiArI2luY2x1ZGUgPGxpbnV4L3ZtYWxsb2MuaD4NCj4gPiArDQo+ID4gKyNp bmNsdWRlIDxtZWRpYS92NGwyLWV2ZW50Lmg+DQo+IA0KPiBQbGVhc2Ugc29ydCBoZWFkZXJzIGFs cGhhYmV0aWNhbGx5Lg0KPiANCg0KV2lsbCBmaXggaW4gbmV4dCBwYXRjaC4NCg0KPiA+ICsNCj4g PiArI2luY2x1ZGUgIm10a19jYW0uaCINCj4gPiArI2luY2x1ZGUgIm10a19jYW0taHcuaCINCj4g PiArI2luY2x1ZGUgIm10a19jYW0tcmVncy5oIg0KPiA+ICsNCj4gPiArI2RlZmluZSBNVEtfSVNQ X0NPTVBPU0VSX01FTV9TSVpFCQkweDIwMDAwMA0KPiA+ICsjZGVmaW5lIE1US19JU1BfQ1FfQlVG RkVSX0NPVU5UCQkJMw0KPiA+ICsjZGVmaW5lIE1US19JU1BfQ1FfQUREUkVTU19PRkZTRVQJCTB4 NjQwDQo+ID4gKw0KPiA+ICsvKg0KPiA+ICsgKg0KPiA+ICsgKiBNVEsgQ2FtZXJhIElTUCBQMSBI VyBzdXBwb3J0cyAzIElTUCBIVyAoQ0FNIEEvQi9DKS4NCj4gPiArICogVGhlIFQtcHV0IGNhcGFi aWxpdHkgb2YgQ0FNIEIgaXMgdGhlIG1heGltdW0gKG1heCBsaW5lIGJ1ZmZlcjogNTM3NiBwaXhl bHMpDQo+ID4gKyAqIEZvciBDQU0gQS9DLCBpdCBvbmx5IHN1cHBvcnRzIG1heCBsaW5lIGJ1ZmZl ciB3aXRoIDMzMjggcGl4ZWxzLg0KPiA+ICsgKiBJbiBjdXJyZW50IGRyaXZlciwgb25seSBzdXBw b3J0cyBDQU0gQi4NCj4gPiArICoNCj4gPiArICovDQo+ID4gKyNkZWZpbmUgTVRLX0lTUF9DQU1f SURfQgkJCTMNCj4gPiArI2RlZmluZSBNVEtfSVNQX0FVVE9TVVNQRU5EX0RFTEFZX01TCQk2Ng0K PiA+ICsjZGVmaW5lIE1US19JU1BfSVBJX1NFTkRfVElNRU9VVAkJMTAwMA0KPiA+ICsjZGVmaW5l IE1US19JU1BfU1RPUF9IV19USU1FT1VUCQkJKDMzICogVVNFQ19QRVJfTVNFQykNCj4gPiArDQo+ ID4gK3N0YXRpYyB2b2lkIGlzcF90eF9mcmFtZV93b3JrZXIoc3RydWN0IHdvcmtfc3RydWN0ICp3 b3JrKQ0KPiANCj4gSSBzdWdnZXN0IHByZWZpeGluZyBhbGwgdGhlIGZ1bmN0aW9uIGFuZCBtYWNy b3Mgd2l0aCBtdGtfaXNwXywgaXQgaXMgZWFzaWVyIHRvIGtub3cgdGhleSBhcmUgbm90DQo+IGFu IGV4dGVybmFsIGZ1bmN0aW9uLg0KPiANCg0KRml4IGluIG5leHQgcGF0Y2guDQoNCj4gPiArew0K PiA+ICsJc3RydWN0IG10a19jYW1fZGV2X3JlcXVlc3QgKnJlcSA9DQo+ID4gKwkJY29udGFpbmVy X29mKHdvcmssIHN0cnVjdCBtdGtfY2FtX2Rldl9yZXF1ZXN0LCBmcmFtZV93b3JrKTsNCj4gPiAr CXN0cnVjdCBtdGtfY2FtX2RldiAqY2FtID0NCj4gPiArCQljb250YWluZXJfb2YocmVxLT5yZXEu bWRldiwgc3RydWN0IG10a19jYW1fZGV2LCBtZWRpYV9kZXYpOw0KPiA+ICsJc3RydWN0IG10a19p c3BfcDFfZGV2aWNlICpwMV9kZXYgPSBkZXZfZ2V0X2RydmRhdGEoY2FtLT5kZXYpOw0KPiA+ICsN Cj4gPiArCXNjcF9pcGlfc2VuZChwMV9kZXYtPnNjcCwgU0NQX0lQSV9JU1BfRlJBTUUsICZyZXEt PmZyYW1lX3BhcmFtcywNCj4gPiArCQkgICAgIHNpemVvZihyZXEtPmZyYW1lX3BhcmFtcyksIE1U S19JU1BfSVBJX1NFTkRfVElNRU9VVCk7DQo+ID4gK30NCj4gPiArDQo+ID4gK3N0YXRpYyB2b2lk IGlzcF9jb21wb3Nlcl9oYW5kbGVyKHZvaWQgKmRhdGEsIHVuc2lnbmVkIGludCBsZW4sIHZvaWQg KnByaXYpDQo+ID4gK3sNCj4gPiArCXN0cnVjdCBtdGtfaXNwX3AxX2RldmljZSAqcDFfZGV2ID0g KHN0cnVjdCBtdGtfaXNwX3AxX2RldmljZSAqKXByaXY7DQo+ID4gKwlzdHJ1Y3QgZGV2aWNlICpk ZXYgPSBwMV9kZXYtPmRldjsNCj4gPiArCXN0cnVjdCBtdGtfaXNwX3NjcF9wMV9jbWQgKmlwaV9t c2c7DQo+ID4gKw0KPiA+ICsJaXBpX21zZyA9IChzdHJ1Y3QgbXRrX2lzcF9zY3BfcDFfY21kICop ZGF0YTsNCj4gPiArDQo+ID4gKwlpZiAobGVuIDwgb2Zmc2V0b2ZlbmQoc3RydWN0IG10a19pc3Bf c2NwX3AxX2NtZCwgYWNrX2luZm8pKSB7DQo+ID4gKwkJZGV2X2VycihkZXYsICJ3cm9uZyBJUEkg bGVuOiVkXG4iLCBsZW4pOw0KPiA+ICsJCXJldHVybjsNCj4gPiArCX0NCj4gPiArDQo+ID4gKwlp ZiAoaXBpX21zZy0+Y21kX2lkICE9IElTUF9DTURfQUNLIHx8DQo+ID4gKwkgICAgaXBpX21zZy0+ YWNrX2luZm8uY21kX2lkICE9IElTUF9DTURfRlJBTUVfQUNLKQ0KPiA+ICsJCXJldHVybjsNCj4g PiArDQo+ID4gKwlwMV9kZXYtPmNvbXBvc2VkX2ZyYW1lX3NlcV9ubyA9IGlwaV9tc2ctPmFja19p bmZvLmZyYW1lX3NlcV9ubzsNCj4gPiArCWRldl9kYmcoZGV2LCAiYWNrIGZyYW1lX251bTolZFxu IiwgcDFfZGV2LT5jb21wb3NlZF9mcmFtZV9zZXFfbm8pOw0KPiA+ICt9DQo+ID4gKw0KPiA+ICtz dGF0aWMgaW50IGlzcF9jb21wb3Nlcl9pbml0KHN0cnVjdCBtdGtfaXNwX3AxX2RldmljZSAqcDFf ZGV2KQ0KPiA+ICt7DQo+ID4gKwlzdHJ1Y3QgZGV2aWNlICpkZXYgPSBwMV9kZXYtPmRldjsNCj4g PiArCWludCByZXQ7DQo+ID4gKw0KPiA+ICsJcmV0ID0gc2NwX2lwaV9yZWdpc3RlcihwMV9kZXYt PnNjcCwgU0NQX0lQSV9JU1BfQ01ELA0KPiA+ICsJCQkgICAgICAgaXNwX2NvbXBvc2VyX2hhbmRs ZXIsIHAxX2Rldik7DQo+ID4gKwlpZiAocmV0KSB7DQo+ID4gKwkJZGV2X2VycihkZXYsICJmYWls ZWQgdG8gcmVnaXN0ZXIgSVBJIGNtZFxuIik7DQo+ID4gKwkJcmV0dXJuIHJldDsNCj4gPiArCX0N Cj4gPiArCXJldCA9IHNjcF9pcGlfcmVnaXN0ZXIocDFfZGV2LT5zY3AsIFNDUF9JUElfSVNQX0ZS QU1FLA0KPiA+ICsJCQkgICAgICAgaXNwX2NvbXBvc2VyX2hhbmRsZXIsIHAxX2Rldik7DQo+ID4g KwlpZiAocmV0KSB7DQo+ID4gKwkJZGV2X2VycihkZXYsICJmYWlsZWQgdG8gcmVnaXN0ZXIgSVBJ IGZyYW1lXG4iKTsNCj4gPiArCQlnb3RvIHVucmVnX2lwaV9jbWQ7DQo+ID4gKwl9DQo+ID4gKw0K PiA+ICsJcDFfZGV2LT5jb21wb3Nlcl93cSA9DQo+ID4gKwkJYWxsb2Nfb3JkZXJlZF93b3JrcXVl dWUoZGV2X25hbWUocDFfZGV2LT5kZXYpLA0KPiA+ICsJCQkJCV9fV1FfTEVHQUNZIHwgV1FfTUVN X1JFQ0xBSU0gfA0KPiA+ICsJCQkJCVdRX0ZSRUVaQUJMRSk7DQo+ID4gKwlpZiAoIXAxX2Rldi0+ Y29tcG9zZXJfd3EpIHsNCj4gPiArCQlkZXZfZXJyKGRldiwgImZhaWxlZCB0byBhbGxvYyBjb21w b3NlciB3b3JrcXVldWVcbiIpOw0KPiA+ICsJCWdvdG8gdW5yZWdfaXBpX2ZyYW1lOw0KPiA+ICsJ fQ0KPiA+ICsNCj4gPiArCXJldHVybiAwOw0KPiA+ICsNCj4gPiArdW5yZWdfaXBpX2ZyYW1lOg0K PiA+ICsJc2NwX2lwaV91bnJlZ2lzdGVyKHAxX2Rldi0+c2NwLCBTQ1BfSVBJX0lTUF9GUkFNRSk7 DQo+ID4gK3VucmVnX2lwaV9jbWQ6DQo+ID4gKwlzY3BfaXBpX3VucmVnaXN0ZXIocDFfZGV2LT5z Y3AsIFNDUF9JUElfSVNQX0NNRCk7DQo+ID4gKw0KPiA+ICsJcmV0dXJuIHJldDsNCj4gPiArfQ0K PiA+ICsNCj4gPiArc3RhdGljIHZvaWQgaXNwX2NvbXBvc2VyX3VuaW5pdChzdHJ1Y3QgbXRrX2lz cF9wMV9kZXZpY2UgKnAxX2RldikNCj4gPiArew0KPiA+ICsJZGVzdHJveV93b3JrcXVldWUocDFf ZGV2LT5jb21wb3Nlcl93cSk7DQo+ID4gKwlzY3BfaXBpX3VucmVnaXN0ZXIocDFfZGV2LT5zY3As IFNDUF9JUElfSVNQX0NNRCk7DQo+ID4gKwlzY3BfaXBpX3VucmVnaXN0ZXIocDFfZGV2LT5zY3As IFNDUF9JUElfSVNQX0ZSQU1FKTsNCj4gPiArfQ0KPiA+ICsNCj4gPiArc3RhdGljIHZvaWQgaXNw X2NvbXBvc2VyX2h3X2luaXQoc3RydWN0IG10a19pc3BfcDFfZGV2aWNlICpwMV9kZXYpDQo+ID4g K3sNCj4gPiArCXN0cnVjdCBtdGtfaXNwX3NjcF9wMV9jbWQgY29tcG9zZXJfdHhfY21kOw0KPiA+ ICsNCj4gPiArCW1lbXNldCgmY29tcG9zZXJfdHhfY21kLCAwLCBzaXplb2YoY29tcG9zZXJfdHhf Y21kKSk7DQo+ID4gKwljb21wb3Nlcl90eF9jbWQuY21kX2lkID0gSVNQX0NNRF9JTklUOw0KPiA+ ICsJY29tcG9zZXJfdHhfY21kLmluaXRfcGFyYW0uaHdfbW9kdWxlID0gTVRLX0lTUF9DQU1fSURf QjsNCj4gPiArDQo+ID4gKwkvKg0KPiA+ICsJICogUGFzc2VkIGNvaGVyZW50IHJlc2VydmVkIG1l bW9yeSBpbmZvLiBmb3IgU0NQIGZpcm13YXJlIHVzYWdlLg0KPiA+ICsJICogVGhpcyBidWZmZXIg aXMgdXNlZCBmb3IgU0NQJ3MgSVNQIGNvbXBvc2VyIHRvIGNvbXBvc2UuDQo+ID4gKwkgKiBUaGUg c2l6ZSBvZiBpcyBmaXhlZCB0byAweDIwMDAwMCBmb3IgdGhlIHJlcXVpcmVtZW50IG9mIGNvbXBv c2VyLg0KPiA+ICsJICovDQo+ID4gKwljb21wb3Nlcl90eF9jbWQuaW5pdF9wYXJhbS5jcV9hZGRy LmlvdmEgPSBwMV9kZXYtPmNvbXBvc2VyX2lvdmE7DQo+ID4gKwljb21wb3Nlcl90eF9jbWQuaW5p dF9wYXJhbS5jcV9hZGRyLnNjcF9hZGRyID0gcDFfZGV2LT5jb21wb3Nlcl9zY3BfYWRkcjsNCj4g PiArDQo+ID4gKwlzY3BfaXBpX3NlbmQocDFfZGV2LT5zY3AsIFNDUF9JUElfSVNQX0NNRCwgJmNv bXBvc2VyX3R4X2NtZCwNCj4gPiArCQkgICAgIHNpemVvZihjb21wb3Nlcl90eF9jbWQpLCBNVEtf SVNQX0lQSV9TRU5EX1RJTUVPVVQpOw0KPiA+ICt9DQo+ID4gKw0KPiA+ICtzdGF0aWMgdm9pZCBp c3BfY29tcG9zZXJfaHdfZGVpbml0KHN0cnVjdCBtdGtfaXNwX3AxX2RldmljZSAqcDFfZGV2KQ0K PiA+ICt7DQo+ID4gKwlzdHJ1Y3QgbXRrX2lzcF9zY3BfcDFfY21kIGNvbXBvc2VyX3R4X2NtZDsN Cj4gPiArDQo+ID4gKwltZW1zZXQoJmNvbXBvc2VyX3R4X2NtZCwgMCwgc2l6ZW9mKGNvbXBvc2Vy X3R4X2NtZCkpOw0KPiA+ICsJY29tcG9zZXJfdHhfY21kLmNtZF9pZCA9IElTUF9DTURfREVJTklU Ow0KPiA+ICsNCj4gPiArCXNjcF9pcGlfc2VuZChwMV9kZXYtPnNjcCwgU0NQX0lQSV9JU1BfQ01E LCAmY29tcG9zZXJfdHhfY21kLA0KPiA+ICsJCSAgICAgc2l6ZW9mKGNvbXBvc2VyX3R4X2NtZCks IE1US19JU1BfSVBJX1NFTkRfVElNRU9VVCk7DQo+ID4gKw0KPiA+ICsJaXNwX2NvbXBvc2VyX3Vu aW5pdChwMV9kZXYpOw0KPiANCj4gSSB0aGluayB5b3UgY2FuIGNvcHkgdGhlIDMgbGluZXMgb2Yg dGhpcyBpc3BfY29tcG9zZXJfdW5pbml0KCkgZnVuY3Rpb24gaGVyZSwgc2luY2UNCj4gdGhpcyBz ZWVtcyB0aGUgb25seSBwbGFjZSBpdCBpcyBiZWluZyB1c2VkLCBhbmQgaGF2aW5nIGEgZGVpbml0 IGFuZCB1bmluaXQgZnVuY3Rpb24gaXMNCj4gYSBiaXQgY29uZnVzaW5nLg0KPiANCg0KRml4IGlu IG5leHQgcGF0Y2guDQoNCj4gPiArfQ0KPiA+ICsNCj4gPiArdm9pZCBtdGtfaXNwX2h3X2NvbmZp ZyhzdHJ1Y3QgbXRrX2NhbV9kZXYgKmNhbSwNCj4gPiArCQkgICAgICAgc3RydWN0IHAxX2NvbmZp Z19wYXJhbSAqY29uZmlnX3BhcmFtKQ0KPiA+ICt7DQo+ID4gKwlzdHJ1Y3QgbXRrX2lzcF9zY3Bf cDFfY21kIGNvbXBvc2VyX3R4X2NtZDsNCj4gPiArCXN0cnVjdCBtdGtfaXNwX3AxX2RldmljZSAq cDFfZGV2ID0gZGV2X2dldF9kcnZkYXRhKGNhbS0+ZGV2KTsNCj4gPiArDQo+ID4gKwltZW1zZXQo JmNvbXBvc2VyX3R4X2NtZCwgMCwgc2l6ZW9mKGNvbXBvc2VyX3R4X2NtZCkpOw0KPiA+ICsJY29t cG9zZXJfdHhfY21kLmNtZF9pZCA9IElTUF9DTURfQ09ORklHOw0KPiA+ICsJbWVtY3B5KCZjb21w b3Nlcl90eF9jbWQuY29uZmlnX3BhcmFtLCBjb25maWdfcGFyYW0sDQo+ID4gKwkgICAgICAgc2l6 ZW9mKCpjb25maWdfcGFyYW0pKTsNCj4gPiArDQo+ID4gKwlzY3BfaXBpX3NlbmQocDFfZGV2LT5z Y3AsIFNDUF9JUElfSVNQX0NNRCwgJmNvbXBvc2VyX3R4X2NtZCwNCj4gPiArCQkgICAgIHNpemVv Zihjb21wb3Nlcl90eF9jbWQpLCBNVEtfSVNQX0lQSV9TRU5EX1RJTUVPVVQpOw0KPiA+ICt9DQo+ ID4gKw0KPiA+ICt2b2lkIG10a19pc3Bfc3RyZWFtKHN0cnVjdCBtdGtfY2FtX2RldiAqY2FtLCBp bnQgb24pDQo+IA0KPiBJIHByZWZlciBub3QgaGF2aW5nIGEgaW50IHBhcmFtZXRlciwgdGhpcyBp cyBlYXNpZXIgdG8gcmVhZDoNCj4gDQo+IG10a19pc3Bfc3RyZWFtX29uKGNhbSk7DQo+IG10a19p c3Bfc3RyZWFtX29mZihjYW0pOw0KPiANCj4gb3INCj4gDQo+IG10a19pc3Bfc3RyZWFtKGNhbSwg TVRLX0lTUF9TVFJFQU1fT04pOw0KPiBtdGtfaXNwX3N0cmVhbShjYW0sIE1US19JU1BfU1RSRUFN X09GRik7DQo+IA0KPiBpbnN0ZWFkIG9mOg0KPiANCj4gbXRrX2lzcF9zdHJlYW0oY2FtLCAxKTsN Cj4gbXRrX2lzcF9zdHJlYW0oY2FtLCAwKTsNCj4gDQo+IFlvdSBjYW4gYWRkIHdyYXBwZXJzIHRv IHRoaXMgZnVuY3Rpb24sIGFuZCBsZWF2ZSB0aGlzIG9uZSAodGhhdCByZWNlaXZlcyB0aGUgYm9v bGVhbiBwYXJhbWV0ZXIpIGludGVybmFsLg0KPiANCg0KT2ssIEkgd2lsbCBjaG9vc2UgdGhlIG1l dGhvZCAyLg0KDQo+ID4gK3sNCj4gPiArCXN0cnVjdCBtdGtfaXNwX3NjcF9wMV9jbWQgY29tcG9z ZXJfdHhfY21kOw0KPiA+ICsJc3RydWN0IG10a19pc3BfcDFfZGV2aWNlICpwMV9kZXYgPSBkZXZf Z2V0X2RydmRhdGEoY2FtLT5kZXYpOw0KPiA+ICsNCj4gPiArCW1lbXNldCgmY29tcG9zZXJfdHhf Y21kLCAwLCBzaXplb2YoY29tcG9zZXJfdHhfY21kKSk7DQo+ID4gKwljb21wb3Nlcl90eF9jbWQu Y21kX2lkID0gSVNQX0NNRF9TVFJFQU07DQo+ID4gKwljb21wb3Nlcl90eF9jbWQuaXNfc3RyZWFt X29uID0gb247DQo+IA0KPiBzL2lzX3N0cmVhbV9vbi9pc19zdHJlYW1pbmcNCj4gDQoNCkZpeCBp biBuZXh0IHBhdGNoLg0KDQo+ID4gKw0KPiA+ICsJc2NwX2lwaV9zZW5kKHAxX2Rldi0+c2NwLCBT Q1BfSVBJX0lTUF9DTUQsICZjb21wb3Nlcl90eF9jbWQsDQo+ID4gKwkJICAgICBzaXplb2YoY29t cG9zZXJfdHhfY21kKSwgTVRLX0lTUF9JUElfU0VORF9USU1FT1VUKTsNCj4gPiArfQ0KPiA+ICsN Cj4gPiAraW50IG10a19pc3BfaHdfaW5pdChzdHJ1Y3QgbXRrX2NhbV9kZXYgKmNhbSkNCj4gPiAr ew0KPiA+ICsJc3RydWN0IGRldmljZSAqZGV2ID0gY2FtLT5kZXY7DQo+ID4gKwlzdHJ1Y3QgbXRr X2lzcF9wMV9kZXZpY2UgKnAxX2RldiA9IGRldl9nZXRfZHJ2ZGF0YShkZXYpOw0KPiA+ICsJaW50 IHJldDsNCj4gPiArDQo+ID4gKwlyZXQgPSBycHJvY19ib290KHAxX2Rldi0+cnByb2NfaGFuZGxl KTsNCj4gPiArCWlmIChyZXQpIHsNCj4gPiArCQlkZXZfZXJyKGRldiwgImZhaWxlZCB0byBycHJv Y19ib290XG4iKTsNCj4gDQo+IEl0IHdvdWxkIGJlIG5pY2UgdG8gaW1wcm92ZSB0aGlzIGVycm9y IG1lc3NhZ2UgZm9yIHVzZXJzLCBob3cgYWJvdXQ6DQo+IA0KPiBkZXZfZXJyKGRldiwgIkluaXRp YWxpemF0aW9uIG9mIHJlbW90ZSBwcm9jZXNzb3IgJXMgZmFpbGVkIiwgcDFfZGV2LT5ycHJvY19o YW5kbGUpOw0KPiANCj4gT3IgbWF5YmUgZXZlbiByZW1vdmUgdGhpcyBtZXNzYWdlLCBzaW5jZSBy cHJvY19ib290KCkgYWxyZWFkeSBoYXZlIHNldmVyYWwgZXJyb3IgbWVzc2FnZXMuDQo+IA0KDQpP aywgd2Ugd2lsbCByZW1vdmUgdGhlIGVycm9yIG1lc3NhZ2UuDQoNCj4gPiArCQlyZXR1cm4gcmV0 Ow0KPiA+ICsJfQ0KPiA+ICsNCj4gPiArCXJldCA9IGlzcF9jb21wb3Nlcl9pbml0KHAxX2Rldik7 DQo+ID4gKwlpZiAocmV0KQ0KPiANCj4gc2hvdWxkIHJwcm9jX3NodXRkb3duKCkgYmUgY2FsbGVk IGhlcmU/DQo+IA0KDQpZZXMsIHdlIHdpbGwgZml4IGl0Lg0KDQo+ID4gKwkJcmV0dXJuIHJldDsN Cj4gPiArDQo+ID4gKwlwbV9ydW50aW1lX2dldF9zeW5jKGRldik7DQo+IA0KPiBZb3Ugc2hvdWxk IGNoZWNrIHJldHVybiB2YWx1ZSBoZXJlLg0KPiANCg0KRml4IGluIG5leHQgcGF0Y2guDQoNCj4g PiArCWlzcF9jb21wb3Nlcl9od19pbml0KHAxX2Rldik7DQo+ID4gKw0KPiA+ICsJcDFfZGV2LT5l bnF1ZXVlZF9mcmFtZV9zZXFfbm8gPSAwOw0KPiA+ICsJcDFfZGV2LT5kZXF1ZXVlZF9mcmFtZV9z ZXFfbm8gPSAwOw0KPiA+ICsJcDFfZGV2LT5jb21wb3NlZF9mcmFtZV9zZXFfbm8gPSAwOw0KPiA+ ICsJcDFfZGV2LT5zb2ZfY291bnQgPSAwOw0KPiA+ICsNCj4gPiArCWRldl9kYmcoZGV2LCAiJXMg ZG9uZVxuIiwgX19mdW5jX18pOw0KPiA+ICsNCj4gPiArCXJldHVybiAwOw0KPiA+ICt9DQo+ID4g Kw0KPiA+ICtpbnQgbXRrX2lzcF9od19yZWxlYXNlKHN0cnVjdCBtdGtfY2FtX2RldiAqY2FtKQ0K PiA+ICt7DQo+ID4gKwlzdHJ1Y3QgZGV2aWNlICpkZXYgPSBjYW0tPmRldjsNCj4gPiArCXN0cnVj dCBtdGtfaXNwX3AxX2RldmljZSAqcDFfZGV2ID0gZGV2X2dldF9kcnZkYXRhKGRldik7DQo+ID4g Kw0KPiA+ICsJaXNwX2NvbXBvc2VyX2h3X2RlaW5pdChwMV9kZXYpOw0KPiA+ICsJcG1fcnVudGlt ZV9tYXJrX2xhc3RfYnVzeShkZXYpOw0KPiA+ICsJcG1fcnVudGltZV9wdXRfYXV0b3N1c3BlbmQo ZGV2KTsNCj4gPiArCXJwcm9jX3NodXRkb3duKHAxX2Rldi0+cnByb2NfaGFuZGxlKTsNCj4gPiAr DQo+ID4gKwlkZXZfZGJnKGRldiwgIiVzIGRvbmVcbiIsIF9fZnVuY19fKTsNCj4gPiArDQo+ID4g KwlyZXR1cm4gMDsNCj4gPiArfQ0KPiA+ICsNCj4gPiArdm9pZCBtdGtfaXNwX3JlcV9lbnF1ZXVl KHN0cnVjdCBtdGtfY2FtX2RldiAqY2FtLA0KPiA+ICsJCQkgc3RydWN0IG10a19jYW1fZGV2X3Jl cXVlc3QgKnJlcSkNCj4gPiArew0KPiA+ICsJc3RydWN0IG10a19pc3BfcDFfZGV2aWNlICpwMV9k ZXYgPSBkZXZfZ2V0X2RydmRhdGEoY2FtLT5kZXYpOw0KPiA+ICsNCj4gPiArCS8qIEFjY3VtdWxh dGVkIGZyYW1lIHNlcXVlbmNlIG51bWJlciAqLw0KPiA+ICsJcmVxLT5mcmFtZV9wYXJhbXMuZnJh bWVfc2VxX25vID0gKytwMV9kZXYtPmVucXVldWVkX2ZyYW1lX3NlcV9ubzsNCj4gPiArDQo+ID4g KwlJTklUX1dPUksoJnJlcS0+ZnJhbWVfd29yaywgaXNwX3R4X2ZyYW1lX3dvcmtlcik7DQo+ID4g KwlxdWV1ZV93b3JrKHAxX2Rldi0+Y29tcG9zZXJfd3EsICZyZXEtPmZyYW1lX3dvcmspOw0KPiA+ ICsJZGV2X2RiZyhjYW0tPmRldiwgImVucXVldWUgZmQ6JXMgZnJhbWVfc2VxX25vOiVkIGpvYiBj bnQ6JWRcbiIsDQo+ID4gKwkJcmVxLT5yZXEuZGVidWdfc3RyLCByZXEtPmZyYW1lX3BhcmFtcy5m cmFtZV9zZXFfbm8sDQo+ID4gKwkJY2FtLT5ydW5uaW5nX2pvYl9jb3VudCk7DQo+ID4gK30NCj4g PiArDQo+ID4gK3N0YXRpYyB2b2lkIGlzcF9pcnFfaGFuZGxlX3NvZihzdHJ1Y3QgbXRrX2lzcF9w MV9kZXZpY2UgKnAxX2RldiwNCj4gPiArCQkJICAgICAgIHVuc2lnbmVkIGludCBkZXF1ZXVlZF9m cmFtZV9zZXFfbm8pDQo+ID4gK3sNCj4gPiArCWRtYV9hZGRyX3QgYmFzZV9hZGRyID0gcDFfZGV2 LT5jb21wb3Nlcl9pb3ZhOw0KPiA+ICsJc3RydWN0IGRldmljZSAqZGV2ID0gcDFfZGV2LT5kZXY7 DQo+ID4gKwlzdHJ1Y3QgbXRrX2NhbV9kZXZfcmVxdWVzdCAqcmVxOw0KPiA+ICsJaW50IGNvbXBv c2VkX2ZyYW1lX3NlcV9ubyA9IHAxX2Rldi0+Y29tcG9zZWRfZnJhbWVfc2VxX25vOw0KPiA+ICsJ dW5zaWduZWQgaW50IGFkZHJfb2Zmc2V0Ow0KPiA+ICsNCj4gPiArCS8qIFNlbmQgVjRMMl9FVkVO VF9GUkFNRV9TWU5DIGV2ZW50ICovDQo+ID4gKwltdGtfY2FtX2Rldl9ldmVudF9mcmFtZV9zeW5j KCZwMV9kZXYtPmNhbV9kZXYsIGRlcXVldWVkX2ZyYW1lX3NlcV9ubyk7DQo+ID4gKw0KPiA+ICsJ cDFfZGV2LT5zb2ZfY291bnQgKz0gMTsNCj4gPiArCS8qIFNhdmUgZnJhbWUgaW5mb3JtYXRpb24g Ki8NCj4gPiArCXAxX2Rldi0+ZGVxdWV1ZWRfZnJhbWVfc2VxX25vID0gZGVxdWV1ZWRfZnJhbWVf c2VxX25vOw0KPiA+ICsNCj4gPiArCXJlcSA9IG10a19jYW1fZGV2X2dldF9yZXEoJnAxX2Rldi0+ Y2FtX2RldiwgZGVxdWV1ZWRfZnJhbWVfc2VxX25vKTsNCj4gPiArCWlmIChyZXEpDQo+ID4gKwkJ cmVxLT50aW1lc3RhbXAgPSBrdGltZV9nZXRfYm9vdHRpbWVfbnMoKTsNCj4gPiArDQo+ID4gKwkv KiBVcGRhdGUgQ1EgYmFzZSBhZGRyZXNzIGlmIG5lZWRlZCAqLw0KPiA+ICsJaWYgKGNvbXBvc2Vk X2ZyYW1lX3NlcV9ubyA8PSBkZXF1ZXVlZF9mcmFtZV9zZXFfbm8pIHsNCj4gPiArCQlkZXZfZGJn KGRldiwNCj4gPiArCQkJIlNPRl9JTlRfU1QsIG5vIHVwZGF0ZSwgY3FfbnVtOiVkLCBmcmFtZV9z ZXE6JWRcbiIsDQo+ID4gKwkJCWNvbXBvc2VkX2ZyYW1lX3NlcV9ubywgZGVxdWV1ZWRfZnJhbWVf c2VxX25vKTsNCj4gPiArCQlyZXR1cm47DQo+ID4gKwl9DQo+ID4gKwlhZGRyX29mZnNldCA9IE1U S19JU1BfQ1FfQUREUkVTU19PRkZTRVQgKg0KPiA+ICsJCShkZXF1ZXVlZF9mcmFtZV9zZXFfbm8g JSBNVEtfSVNQX0NRX0JVRkZFUl9DT1VOVCk7DQo+ID4gKwl3cml0ZWwoYmFzZV9hZGRyICsgYWRk cl9vZmZzZXQsIHAxX2Rldi0+cmVncyArIFJFR19DUV9USFIwX0JBU0VBRERSKTsNCj4gPiArCWRl dl9kYmcoZGV2LA0KPiA+ICsJCSJTT0ZfSU5UX1NULCB1cGRhdGUgbmV4dCwgY3FfbnVtOiVkLCBm cmFtZV9zZXE6JWQgY3FfYWRkcjoweCV4XG4iLA0KPiA+ICsJCWNvbXBvc2VkX2ZyYW1lX3NlcV9u bywgZGVxdWV1ZWRfZnJhbWVfc2VxX25vLCBhZGRyX29mZnNldCk7DQo+ID4gK30NCj4gPiArDQo+ ID4gK3N0YXRpYyB2b2lkIGlzcF9pcnFfaGFuZGxlX2RtYV9lcnIoc3RydWN0IG10a19pc3BfcDFf ZGV2aWNlICpwMV9kZXYpDQo+ID4gK3sNCj4gPiArCXUzMiB2YWw7DQo+ID4gKw0KPiA+ICsJZGV2 X2VycihwMV9kZXYtPmRldiwNCj4gPiArCQkiSU1HTzoweCV4LCBSUlpPOjB4JXgsIEFBTz0weCV4 LCBBRk89MHgleCwgTE1WTz0weCV4XG4iLA0KPiA+ICsJCXJlYWRsKHAxX2Rldi0+cmVncyArIFJF R19JTUdPX0VSUl9TVEFUKSwNCj4gPiArCQlyZWFkbChwMV9kZXYtPnJlZ3MgKyBSRUdfUlJaT19F UlJfU1RBVCksDQo+ID4gKwkJcmVhZGwocDFfZGV2LT5yZWdzICsgUkVHX0FBT19FUlJfU1RBVCks DQo+ID4gKwkJcmVhZGwocDFfZGV2LT5yZWdzICsgUkVHX0FGT19FUlJfU1RBVCksDQo+ID4gKwkJ cmVhZGwocDFfZGV2LT5yZWdzICsgUkVHX0xNVk9fRVJSX1NUQVQpKTsNCj4gPiArCWRldl9lcnIo cDFfZGV2LT5kZXYsDQo+ID4gKwkJIkxDU089MHgleCwgUFNPPTB4JXgsIEZMS089MHgleCwgQlBD SToweCV4LCBMU0NJPTB4JXhcbiIsDQo+ID4gKwkJcmVhZGwocDFfZGV2LT5yZWdzICsgUkVHX0xD U09fRVJSX1NUQVQpLA0KPiA+ICsJCXJlYWRsKHAxX2Rldi0+cmVncyArIFJFR19QU09fRVJSX1NU QVQpLA0KPiA+ICsJCXJlYWRsKHAxX2Rldi0+cmVncyArIFJFR19GTEtPX0VSUl9TVEFUKSwNCj4g PiArCQlyZWFkbChwMV9kZXYtPnJlZ3MgKyBSRUdfQlBDSV9FUlJfU1RBVCksDQo+ID4gKwkJcmVh ZGwocDFfZGV2LT5yZWdzICsgUkVHX0xTQ0lfRVJSX1NUQVQpKTsNCj4gDQo+IEkgdGhpbmsgaWYg d291bGQgYmUgYmV0dGVyIHRvIHRyYW5zZm9yIHRob3NlIGludG8gZGV2X2RiZyBhbmQgYWRkIGEg Y291bnRlcg0KPiBpbiBkZWJ1Z2ZzLg0KPiANCg0KVGhlc2UgZXJyb3IgbWVzc2FnZXMgYXJlIGlt cG9ydGFudCBmb3IgZGVidWdnaW5nLg0KSSBzdWdnZXN0IHRvIGtlZXAgaW4gZGV2X2Vyci4NCg0K TW9yZW92ZXIsIGNvdWxkIHlvdSBnaXZlIG1vcmUgaW5mb3JtYXRpb24gYWJvdXQgZGVidWcgY291 bnRlcj8NCkkgZG9uJ3QgZ2V0IHlvdXIgcG9pbnQuDQpEbyB5b3Ugc3VnZ2VzdCB0byBhY2N1bXVs YXRlIHRoZSB0b3RhbCBjb3VudCBvZiBETUEgZXJyb3JzPw0KDQo+ID4gKw0KPiA+ICsJLyogRGlz YWJsZSBETUEgZXJyb3IgbWFzayB0byBhdm9pZCB0b28gbXVjaCBlcnJvciBsb2cgKi8NCj4gPiAr CXZhbCA9IHJlYWRsKHAxX2Rldi0+cmVncyArIFJFR19DVExfUkFXX0lOVF9FTik7DQo+ID4gKwl3 cml0ZWwoKHZhbCAmICh+RE1BX0VSUl9JTlRfRU4pKSwgcDFfZGV2LT5yZWdzICsgUkVHX0NUTF9S QVdfSU5UX0VOKTsNCj4gPiArCWRldl9kYmcocDFfZGV2LT5kZXYsICJkaXNhYmxlIERNQSBlcnJv ciBtYXNrOjB4JXhcbiIsIHZhbCk7DQo+ID4gK30NCj4gPiArDQo+ID4gK3N0YXRpYyBpcnFyZXR1 cm5fdCBpc3BfaXJxX2NhbShpbnQgaXJxLCB2b2lkICpkYXRhKQ0KPiA+ICt7DQo+ID4gKwlzdHJ1 Y3QgbXRrX2lzcF9wMV9kZXZpY2UgKnAxX2RldiA9IChzdHJ1Y3QgbXRrX2lzcF9wMV9kZXZpY2Ug KilkYXRhOw0KPiA+ICsJc3RydWN0IGRldmljZSAqZGV2ID0gcDFfZGV2LT5kZXY7DQo+ID4gKwl1 bnNpZ25lZCBpbnQgZGVxdWV1ZWRfZnJhbWVfc2VxX25vOw0KPiA+ICsJdW5zaWduZWQgaW50IGly cV9zdGF0dXMsIGVycl9zdGF0dXMsIGRtYV9zdGF0dXM7DQo+ID4gKwl1bnNpZ25lZCBsb25nIGZs YWdzOw0KPiA+ICsNCj4gPiArCXNwaW5fbG9ja19pcnFzYXZlKCZwMV9kZXYtPnNwaW5sb2NrX2ly cSwgZmxhZ3MpOw0KPiA+ICsJaXJxX3N0YXR1cyA9IHJlYWRsKHAxX2Rldi0+cmVncyArIFJFR19D VExfUkFXX0lOVF9TVEFUKTsNCj4gPiArCWVycl9zdGF0dXMgPSBpcnFfc3RhdHVzICYgSU5UX1NU X01BU0tfQ0FNX0VSUjsNCj4gPiArCWRtYV9zdGF0dXMgPSByZWFkbChwMV9kZXYtPnJlZ3MgKyBS RUdfQ1RMX1JBV19JTlQyX1NUQVQpOw0KPiA+ICsJZGVxdWV1ZWRfZnJhbWVfc2VxX25vID0gcmVh ZGwocDFfZGV2LT5yZWdzICsgUkVHX0ZSQU1FX1NFUV9OVU0pOw0KPiA+ICsJc3Bpbl91bmxvY2tf aXJxcmVzdG9yZSgmcDFfZGV2LT5zcGlubG9ja19pcnEsIGZsYWdzKTsNCj4gPiArDQo+ID4gKwkv Kg0KPiA+ICsJICogSW4gbm9ybWFsIGNhc2UsIHRoZSBuZXh0IFNPRiBJU1Igc2hvdWxkIGNvbWUg YWZ0ZXIgSFcgUEFTUzEgRE9ORSBJU1IuDQo+ID4gKwkgKiBJZiB0aGVzZSB0d28gSVNScyBjb21l IHRvZ2V0aGVyLCBwcmludCB3YXJuaW5nIG1zZyB0byBoaW50Lg0KPiA+ICsJICovDQo+ID4gKwlp ZiAoKGlycV9zdGF0dXMgJiBTT0ZfSU5UX1NUKSAmJiAoaXJxX3N0YXR1cyAmIEhXX1BBU1MxX0RP Tl9TVCkpDQo+ID4gKwkJZGV2X2RiZyhkZXYsICJzb2ZfZG9uZSBibG9jayBjbnQ6JWRcbiIsIHAx X2Rldi0+c29mX2NvdW50KTsNCj4gPiArDQo+ID4gKwkvKiBEZS1xdWV1ZSBmcmFtZSAqLw0KPiA+ ICsJaWYgKGlycV9zdGF0dXMgJiBTV19QQVNTMV9ET05fU1QpIHsNCj4gDQo+IEkgc3VwcG9zZSB0 aGlzIG1lYW5zICJkb25lIHN0cmVhbWluZyI/DQo+IA0KDQpZZXMsIGl0IG1lYW5zIHRoZSBmcmFt ZSBidWZmZXIgaXMgb3V0cHV0ZWQgZG9uZS4NCg0KPiA+ICsJCW10a19jYW1fZGV2X2RlcXVldWVf cmVxX2ZyYW1lKCZwMV9kZXYtPmNhbV9kZXYsDQo+ID4gKwkJCQkJICAgICAgcDFfZGV2LT5kZXF1 ZXVlZF9mcmFtZV9zZXFfbm8pOw0KPiA+ICsJCW10a19jYW1fZGV2X3JlcV90cnlfcXVldWUoJnAx X2Rldi0+Y2FtX2Rldik7DQo+ID4gKwl9DQo+ID4gKw0KPiA+ICsJLyogU2F2ZSBmcmFtZSBpbmZv LiAmIHVwZGF0ZSBDUSBhZGRyZXNzIGZvciBmcmFtZSBIVyBlbi1xdWV1ZSAqLw0KPiA+ICsJaWYg KGlycV9zdGF0dXMgJiBTT0ZfSU5UX1NUKQ0KPiA+ICsJCWlzcF9pcnFfaGFuZGxlX3NvZihwMV9k ZXYsIGRlcXVldWVkX2ZyYW1lX3NlcV9ubyk7DQo+ID4gKw0KPiA+ICsJLyogQ2hlY2sgSVNQIGVy cm9yIHN0YXR1cyAqLw0KPiA+ICsJaWYgKGVycl9zdGF0dXMpIHsNCj4gPiArCQlkZXZfZXJyKGRl diwgImludF9lcnI6MHgleCAweCV4XG4iLCBpcnFfc3RhdHVzLCBlcnJfc3RhdHVzKTsNCj4gPiAr CQkvKiBTaG93IERNQSBlcnJvcnMgaW4gZGV0YWlsICovDQo+ID4gKwkJaWYgKGVycl9zdGF0dXMg JiBETUFfRVJSX1NUKQ0KPiA+ICsJCQlpc3BfaXJxX2hhbmRsZV9kbWFfZXJyKHAxX2Rldik7DQo+ ID4gKwl9DQo+ID4gKw0KPiA+ICsJZGV2X2RiZyhkZXYsICJTT0Y6JWQgaXJxOjB4JXgsIGRtYTow eCV4LCBmcmFtZV9udW06JWRcbiIsDQo+ID4gKwkJcDFfZGV2LT5zb2ZfY291bnQsIGlycV9zdGF0 dXMsIGRtYV9zdGF0dXMsDQo+ID4gKwkJZGVxdWV1ZWRfZnJhbWVfc2VxX25vKTsNCj4gPiArDQo+ ID4gKwlyZXR1cm4gSVJRX0hBTkRMRUQ7DQo+ID4gK30NCj4gPiArDQo+ID4gK3N0YXRpYyBpbnQg aXNwX3NldHVwX3NjcF9ycHJvYyhzdHJ1Y3QgbXRrX2lzcF9wMV9kZXZpY2UgKnAxX2RldiwNCj4g PiArCQkJICAgICAgIHN0cnVjdCBwbGF0Zm9ybV9kZXZpY2UgKnBkZXYpDQo+ID4gK3sNCj4gPiAr CXN0cnVjdCBkZXZpY2UgKmRldiA9IHAxX2Rldi0+ZGV2Ow0KPiA+ICsJZG1hX2FkZHJfdCBhZGRy Ow0KPiA+ICsJdm9pZCAqcHRyOw0KPiANCj4gTWF5YmUgImNvbXBvc2VyX2J1ZmZlciIgd291bGQg YmUgYSBiZXR0ZXIgbmFtZS4NCj4gDQo+IEJ1dCBpcyB0aGlzIHZhcmlhYmxlIHJlcXVpcmVkIGF0 IGFsbD8gQ2FuJ3QgaXQgYmUgYWxsb2NhdGVkIGRpcmVjdGx5IHRvIHAxX2Rldi0+Y29tcG9zZXJf dmlydF9hZGRyID8NCj4gDQoNCk9rLCBJIHdpbGwgdXNlIHAxX2Rldi0+Y29tcG9zZXJfdmlydF9h ZGRyIGRpcmVjdGx5Lg0KDQo+ID4gKwlpbnQgcmV0Ow0KPiA+ICsNCj4gPiArCXAxX2Rldi0+c2Nw ID0gc2NwX2dldChwZGV2KTsNCj4gPiArCWlmICghcDFfZGV2LT5zY3ApIHsNCj4gPiArCQlkZXZf ZXJyKGRldiwgImZhaWxlZCB0byBnZXQgc2NwIGRldmljZVxuIik7DQo+ID4gKwkJcmV0dXJuIC1F Tk9ERVY7DQo+ID4gKwl9DQo+ID4gKw0KPiA+ICsJcDFfZGV2LT5ycHJvY19oYW5kbGUgPSBzY3Bf Z2V0X3Jwcm9jKHAxX2Rldi0+c2NwKTsNCj4gPiArCWRldl9kYmcoZGV2LCAicDEgcnByb2NfcGhh bmRsZTogMHglcEtcbiIsIHAxX2Rldi0+cnByb2NfaGFuZGxlKTsNCj4gPiArCXAxX2Rldi0+Y2Ft X2Rldi5zbWVtX2RldiA9IHNjcF9nZXRfZGV2aWNlKHAxX2Rldi0+c2NwKTsNCj4gDQo+IEkgd291 bGQgcmVuYW1lIHNtZW1fZGV2IHRvIHNjcF9kZXYsIHRoaXMgaGVscHMgbWFraW5nIGl0IGNsZWFy IHdoZW4gYWxsb2NhdGluZyBkbWEgYnVmZmVycw0KPiB3aGljaCBtYXBwaW5nIHdlIGFyZSByZWZl cmluZyB0by4NCj4gDQoNCkZpeCBpbiBuZXh0IHBhdGNoLg0KDQo+ID4gKw0KPiA+ICsJLyoNCj4g PiArCSAqIEFsbG9jYXRlIGNvaGVyZW50IHJlc2VydmVkIG1lbW9yeSBmb3IgU0NQIGZpcm13YXJl IHVzYWdlLg0KPiA+ICsJICogVGhlIHNpemUgb2YgU0NQIGNvbXBvc2VyJ3MgbWVtb3J5IGlzIGZp eGVkIHRvIDB4MjAwMDAwDQo+ID4gKwkgKiBmb3IgdGhlIHJlcXVpcmVtZW50IG9mIGZpcm13YXJl Lg0KPiA+ICsJICovDQo+ID4gKwlwdHIgPSBkbWFfYWxsb2NfY29oZXJlbnQocDFfZGV2LT5jYW1f ZGV2LnNtZW1fZGV2LA0KPiA+ICsJCQkJIE1US19JU1BfQ09NUE9TRVJfTUVNX1NJWkUsICZhZGRy LCBHRlBfS0VSTkVMKTsNCj4gPiArCWlmICghcHRyKSB7DQo+ID4gKwkJcmV0ID0gLUVOT01FTTsN Cj4gPiArCQlnb3RvIGZhaWxfcHV0X3NjcDsNCj4gPiArCX0NCj4gPiArDQo+ID4gKwlwMV9kZXYt PmNvbXBvc2VyX3NjcF9hZGRyID0gYWRkcjsNCj4gPiArCXAxX2Rldi0+Y29tcG9zZXJfdmlydF9h ZGRyID0gcHRyOw0KPiA+ICsJZGV2X2RiZyhkZXYsICJzY3AgYWRkcjolcGFkIHZhOiVwS1xuIiwg JmFkZHIsIHB0cik7DQo+ID4gKw0KPiA+ICsJLyoNCj4gPiArCSAqIFRoaXMgcmVzZXJ2ZWQgbWVt b3J5IGlzIGFsc28gYmUgdXNlZCBieSBJU1AgUDEgSFcuDQo+ID4gKwkgKiBOZWVkIHRvIGdldCBp b3ZhIGFkZHJlc3MgZm9yIElTUCBQMSBETUEuDQo+ID4gKwkgKi8NCj4gPiArCWFkZHIgPSBkbWFf bWFwX3Jlc291cmNlKGRldiwgYWRkciwgTVRLX0lTUF9DT01QT1NFUl9NRU1fU0laRSwNCj4gPiAr CQkJCURNQV9UT19ERVZJQ0UsIERNQV9BVFRSX1NLSVBfQ1BVX1NZTkMpOw0KPiA+ICsJaWYgKGRt YV9tYXBwaW5nX2Vycm9yKGRldiwgYWRkcikpIHsNCj4gPiArCQlkZXZfZXJyKGRldiwgImZhaWxl ZCB0byBtYXAgc2NwIGlvdmFcbiIpOw0KPiA+ICsJCXJldCA9IC1FTk9NRU07DQo+ID4gKwkJZ290 byBmYWlsX2ZyZWVfbWVtOw0KPiA+ICsJfQ0KPiA+ICsJcDFfZGV2LT5jb21wb3Nlcl9pb3ZhID0g YWRkcjsNCj4gDQo+IHdoeSBub3QgcmVuYW1lIHRoaXMgdG8gY29tcG9zZXJfaXNwX2FkZHIgPw0K PiBTaW5jZSwgYWZhaWssIGNvbXBvc2VyX3NjcF9hZGRyIGlzIGFsc28gaW92YS4NCj4gDQo+IEF0 IGxlYXN0IG15IGNvbmNlcHQgb2YgaW92YSAoSU8gdmlydHVhbCBhZGRyZXNzKSwgYXJlIGFuIGFk ZHJlc3MgYmVoaW5kIGFuIElPTU1VIChvciBidXMgYWRkcmVzcyB0byBiZSBnaXZlbiB0byBhIGRl dmljZSkuDQo+IA0KDQpPaywgd2Ugd2lsbCByZW5hbWUgY29tcG9zZXJfaW92YSB0byBjb21wb3Nl cl9pc3BfYWRkci4NCkJhc2ljYWxseSwgc2NwX2FkZHIgaXMgcmVzZXJ2ZWQgcGh5c2ljYWwgYWRk cmVzcyBhbmQgaXQgaXMgbm90IGJlaGluZCBhbg0KSU9NTVUuDQoNCj4gPiArCWRldl9kYmcoZGV2 LCAic2NwIGlvdmEgYWRkcjolcGFkXG4iLCAmYWRkcik7DQo+ID4gKw0KPiA+ICsJcmV0dXJuIDA7 DQo+ID4gKw0KPiA+ICtmYWlsX2ZyZWVfbWVtOg0KPiA+ICsJZG1hX2ZyZWVfY29oZXJlbnQocDFf ZGV2LT5jYW1fZGV2LnNtZW1fZGV2LCBNVEtfSVNQX0NPTVBPU0VSX01FTV9TSVpFLA0KPiA+ICsJ CQkgIHAxX2Rldi0+Y29tcG9zZXJfdmlydF9hZGRyLA0KPiA+ICsJCQkgIHAxX2Rldi0+Y29tcG9z ZXJfc2NwX2FkZHIpOw0KPiA+ICsJcDFfZGV2LT5jb21wb3Nlcl9zY3BfYWRkciA9IDA7DQo+ID4g K2ZhaWxfcHV0X3NjcDoNCj4gPiArCXNjcF9wdXQocDFfZGV2LT5zY3ApOw0KPiA+ICsNCj4gPiAr CXJldHVybiByZXQ7DQo+ID4gK30NCj4gPiArDQo+ID4gK3N0YXRpYyB2b2lkIGlzcF90ZWFyZG93 bl9zY3BfcnByb2Moc3RydWN0IG10a19pc3BfcDFfZGV2aWNlICpwMV9kZXYpDQo+ID4gK3sNCj4g PiArCWRtYV9mcmVlX2NvaGVyZW50KHAxX2Rldi0+Y2FtX2Rldi5zbWVtX2RldiwgTVRLX0lTUF9D T01QT1NFUl9NRU1fU0laRSwNCj4gPiArCQkJICBwMV9kZXYtPmNvbXBvc2VyX3ZpcnRfYWRkciwN Cj4gPiArCQkJICBwMV9kZXYtPmNvbXBvc2VyX3NjcF9hZGRyKTsNCj4gPiArCXAxX2Rldi0+Y29t cG9zZXJfc2NwX2FkZHIgPSAwOw0KPiA+ICsJc2NwX3B1dChwMV9kZXYtPnNjcCk7DQo+ID4gK30N Cj4gPiArDQo+ID4gK3N0YXRpYyBpbnQgbXRrX2lzcF9wbV9zdXNwZW5kKHN0cnVjdCBkZXZpY2Ug KmRldikNCj4gPiArew0KPiA+ICsJc3RydWN0IG10a19pc3BfcDFfZGV2aWNlICpwMV9kZXYgPSBk ZXZfZ2V0X2RydmRhdGEoZGV2KTsNCj4gPiArCXUzMiB2YWw7DQo+ID4gKwlpbnQgcmV0Ow0KPiA+ ICsNCj4gPiArCWRldl9kYmcoZGV2LCAiLSAlc1xuIiwgX19mdW5jX18pOw0KPiA+ICsNCj4gPiAr CWlmIChwbV9ydW50aW1lX3N1c3BlbmRlZChkZXYpKQ0KPiA+ICsJCXJldHVybiAwOw0KPiA+ICsN Cj4gPiArCS8qIERpc2FibGUgSVNQJ3MgdmlldyBmaW5kZXIgYW5kIHdhaXQgZm9yIFRHIGlkbGUg aWYgcG9zc2libGUgKi8NCj4gPiArCWRldl9kYmcoZGV2LCAiY2FtIHN1c3BlbmQsIGRpc2FibGUg VkZcbiIpOw0KPiA+ICsJdmFsID0gcmVhZGwocDFfZGV2LT5yZWdzICsgUkVHX1RHX1ZGX0NPTik7 DQo+ID4gKwl3cml0ZWwodmFsICYgKH5UR19WRl9DT05fVkZEQVRBX0VOKSwgcDFfZGV2LT5yZWdz ICsgUkVHX1RHX1ZGX0NPTik7DQo+ID4gKwlyZWFkbF9wb2xsX3RpbWVvdXRfYXRvbWljKHAxX2Rl di0+cmVncyArIFJFR19UR19JTlRFUl9TVCwgdmFsLA0KPiA+ICsJCQkJICAodmFsICYgVEdfQ1Nf TUFTSykgPT0gVEdfSURMRV9TVCwNCj4gPiArCQkJCSAgVVNFQ19QRVJfTVNFQywgTVRLX0lTUF9T VE9QX0hXX1RJTUVPVVQpOw0KPiA+ICsNCj4gPiArCS8qIERpc2FibGUgQ01PUyAqLw0KPiA+ICsJ dmFsID0gcmVhZGwocDFfZGV2LT5yZWdzICsgUkVHX1RHX1NFTl9NT0RFKTsNCj4gPiArCXdyaXRl bCh2YWwgJiAoflRHX1NFTl9NT0RFX0NNT1NfRU4pLCBwMV9kZXYtPnJlZ3MgKyBSRUdfVEdfU0VO X01PREUpOw0KPiA+ICsNCj4gPiArCS8qIEZvcmNlIElTUCBIVyB0byBpZGxlICovDQo+ID4gKwly ZXQgPSBwbV9ydW50aW1lX2ZvcmNlX3N1c3BlbmQoZGV2KTsNCj4gPiArCWlmIChyZXQpIHsNCj4g PiArCQlkZXZfZXJyKGRldiwgImZhaWxlZCB0byBmb3JjZSBzdXNwZW5kOiVkXG4iLCByZXQpOw0K PiA+ICsJCWdvdG8gcmVlbmFibGVfaHc7DQo+ID4gKwl9DQo+ID4gKw0KPiA+ICsJcmV0dXJuIDA7 DQo+ID4gKw0KPiA+ICtyZWVuYWJsZV9odzoNCj4gPiArCXZhbCA9IHJlYWRsKHAxX2Rldi0+cmVn cyArIFJFR19UR19TRU5fTU9ERSk7DQo+ID4gKwl3cml0ZWwodmFsIHwgVEdfU0VOX01PREVfQ01P U19FTiwgcDFfZGV2LT5yZWdzICsgUkVHX1RHX1NFTl9NT0RFKTsNCj4gPiArCXZhbCA9IHJlYWRs KHAxX2Rldi0+cmVncyArIFJFR19UR19WRl9DT04pOw0KPiA+ICsJd3JpdGVsKHZhbCB8IFRHX1ZG X0NPTl9WRkRBVEFfRU4sIHAxX2Rldi0+cmVncyArIFJFR19UR19WRl9DT04pOw0KPiA+ICsNCj4g PiArCXJldHVybiByZXQ7DQo+ID4gK30NCj4gPiArDQo+ID4gK3N0YXRpYyBpbnQgbXRrX2lzcF9w bV9yZXN1bWUoc3RydWN0IGRldmljZSAqZGV2KQ0KPiA+ICt7DQo+ID4gKwlzdHJ1Y3QgbXRrX2lz cF9wMV9kZXZpY2UgKnAxX2RldiA9IGRldl9nZXRfZHJ2ZGF0YShkZXYpOw0KPiA+ICsJdTMyIHZh bDsNCj4gPiArCWludCByZXQ7DQo+ID4gKw0KPiA+ICsJZGV2X2RiZyhkZXYsICItICVzXG4iLCBf X2Z1bmNfXyk7DQo+ID4gKw0KPiA+ICsJaWYgKHBtX3J1bnRpbWVfc3VzcGVuZGVkKGRldikpDQo+ ID4gKwkJcmV0dXJuIDA7DQo+ID4gKw0KPiA+ICsJLyogRm9yY2UgSVNQIEhXIHRvIHJlc3VtZSAq Lw0KPiA+ICsJcmV0ID0gcG1fcnVudGltZV9mb3JjZV9yZXN1bWUoZGV2KTsNCj4gPiArCWlmIChy ZXQpDQo+ID4gKwkJcmV0dXJuIHJldDsNCj4gPiArDQo+ID4gKwkvKiBFbmFibGUgQ01PUyAqLw0K PiA+ICsJZGV2X2RiZyhkZXYsICJjYW0gcmVzdW1lLCBlbmFibGUgQ01PUy9WRlxuIik7DQo+ID4g Kwl2YWwgPSByZWFkbChwMV9kZXYtPnJlZ3MgKyBSRUdfVEdfU0VOX01PREUpOw0KPiA+ICsJd3Jp dGVsKHZhbCB8IFRHX1NFTl9NT0RFX0NNT1NfRU4sIHAxX2Rldi0+cmVncyArIFJFR19UR19TRU5f TU9ERSk7DQo+ID4gKw0KPiA+ICsJLyogRW5hYmxlIFZGICovDQo+ID4gKwl2YWwgPSByZWFkbChw MV9kZXYtPnJlZ3MgKyBSRUdfVEdfVkZfQ09OKTsNCj4gPiArCXdyaXRlbCh2YWwgfCBUR19WRl9D T05fVkZEQVRBX0VOLCBwMV9kZXYtPnJlZ3MgKyBSRUdfVEdfVkZfQ09OKTsNCj4gPiArDQo+ID4g KwlyZXR1cm4gMDsNCj4gPiArfQ0KPiA+ICsNCj4gPiArc3RhdGljIGludCBtdGtfaXNwX3J1bnRp bWVfc3VzcGVuZChzdHJ1Y3QgZGV2aWNlICpkZXYpDQo+ID4gK3sNCj4gPiArCXN0cnVjdCBtdGtf aXNwX3AxX2RldmljZSAqcDFfZGV2ID0gZGV2X2dldF9kcnZkYXRhKGRldik7DQo+ID4gKw0KPiA+ ICsJZGV2X2RiZyhkZXYsICIlczpkaXNhYmxlIGNsb2NrXG4iLCBfX2Z1bmNfXyk7DQo+ID4gKwlj bGtfYnVsa19kaXNhYmxlX3VucHJlcGFyZShwMV9kZXYtPm51bV9jbGtzLCBwMV9kZXYtPmNsa3Mp Ow0KPiA+ICsNCj4gPiArCXJldHVybiAwOw0KPiA+ICt9DQo+ID4gKw0KPiA+ICtzdGF0aWMgaW50 IG10a19pc3BfcnVudGltZV9yZXN1bWUoc3RydWN0IGRldmljZSAqZGV2KQ0KPiA+ICt7DQo+ID4g KwlzdHJ1Y3QgbXRrX2lzcF9wMV9kZXZpY2UgKnAxX2RldiA9IGRldl9nZXRfZHJ2ZGF0YShkZXYp Ow0KPiA+ICsJaW50IHJldDsNCj4gPiArDQo+ID4gKwlkZXZfZGJnKGRldiwgIiVzOmVuYWJsZSBj bG9ja1xuIiwgX19mdW5jX18pOw0KPiA+ICsJcmV0ID0gY2xrX2J1bGtfcHJlcGFyZV9lbmFibGUo cDFfZGV2LT5udW1fY2xrcywgcDFfZGV2LT5jbGtzKTsNCj4gPiArCWlmIChyZXQpIHsNCj4gPiAr CQlkZXZfZXJyKGRldiwgImZhaWxlZCB0byBlbmFibGUgY2xvY2s6JWRcbiIsIHJldCk7DQo+ID4g KwkJcmV0dXJuIHJldDsNCj4gPiArCX0NCj4gPiArDQo+ID4gKwlyZXR1cm4gMDsNCj4gPiArfQ0K PiA+ICsNCj4gPiArc3RhdGljIGludCBtdGtfaXNwX3Byb2JlKHN0cnVjdCBwbGF0Zm9ybV9kZXZp Y2UgKnBkZXYpDQo+ID4gK3sNCj4gPiArCS8qIExpc3Qgb2YgY2xvY2tzIHJlcXVpcmVkIGJ5IGlz cCBjYW0gKi8NCj4gPiArCXN0YXRpYyBjb25zdCBjaGFyICogY29uc3QgY2xrX25hbWVzW10gPSB7 DQo+ID4gKwkJImNhbXN5c19jYW1fY2dwZG4iLCAiY2Ftc3lzX2NhbXRnX2NncGRuIg0KPiA+ICsJ fTsNCj4gPiArCXN0cnVjdCBtdGtfaXNwX3AxX2RldmljZSAqcDFfZGV2Ow0KPiA+ICsJc3RydWN0 IGRldmljZSAqZGV2ID0gJnBkZXYtPmRldjsNCj4gPiArCXN0cnVjdCByZXNvdXJjZSAqcmVzOw0K PiA+ICsJaW50IGlycSwgcmV0LCBpOw0KPiA+ICsNCj4gPiArCXAxX2RldiA9IGRldm1fa3phbGxv YyhkZXYsIHNpemVvZigqcDFfZGV2KSwgR0ZQX0tFUk5FTCk7DQo+ID4gKwlpZiAoIXAxX2RldikN Cj4gPiArCQlyZXR1cm4gLUVOT01FTTsNCj4gPiArDQo+ID4gKwlwMV9kZXYtPmRldiA9IGRldjsN Cj4gPiArCWRldl9zZXRfZHJ2ZGF0YShkZXYsIHAxX2Rldik7DQo+ID4gKw0KPiA+ICsJLyoNCj4g PiArCSAqIE5vdyBvbmx5IHN1cHBvcnQgc2luZ2xlIENBTSB3aXRoIENBTSBCLg0KPiA+ICsJICog R2V0IENBTSBCIHJlZ2lzdGVyIGJhc2Ugd2l0aCBDQU0gQiBpbmRleC4NCj4gPiArCSAqIFN1cHBv cnQgbXVsdGlwbGUgQ0FNcyBpbiBmdXR1cmUuDQo+ID4gKwkgKi8NCj4gPiArCXJlcyA9IHBsYXRm b3JtX2dldF9yZXNvdXJjZShwZGV2LCBJT1JFU09VUkNFX01FTSwgTVRLX0lTUF9DQU1fSURfQik7 DQo+ID4gKwlwMV9kZXYtPnJlZ3MgPSBkZXZtX2lvcmVtYXBfcmVzb3VyY2UoZGV2LCByZXMpOw0K PiA+ICsJaWYgKElTX0VSUihwMV9kZXYtPnJlZ3MpKSB7DQo+ID4gKwkJZGV2X2VycihkZXYsICJm YWlsZWQgdG8gbWFwIHJlaXN0ZXIgYmFzZVxuIik7DQo+IA0KPiBzL3JlaXN0ZXIvcmVnaXN0ZXIN Cj4gDQoNCkZpeCBpbiBuZXh0IHBhdGNoLg0KDQo+ID4gKwkJcmV0dXJuIFBUUl9FUlIocDFfZGV2 LT5yZWdzKTsNCj4gPiArCX0NCj4gPiArCWRldl9kYmcoZGV2LCAiY2FtLCBtYXBfYWRkcj0weCVw S1xuIiwgcDFfZGV2LT5yZWdzKTsNCj4gPiArDQo+ID4gKwkvKg0KPiA+ICsJICogVGhlIGNhbV9z eXMgdW5pdCBvbmx5IHN1cHBvcnRzIHJlZy4sIGJ1dCBoYXMgbm8gSVJRIHN1cHBvcnQuDQo+ID4g KwkgKiBUaGUgcmVnLiAmIElSUSBpbmRleCBpcyBzaGlmdGVkIHdpdGggMSBmb3IgQ0FNIEIgaW4g RFRTLg0KPiA+ICsJICovDQo+ID4gKwlpcnEgPSBwbGF0Zm9ybV9nZXRfaXJxKHBkZXYsIE1US19J U1BfQ0FNX0lEX0IgLSAxKTsNCj4gPiArCWlmICghaXJxKSB7DQo+ID4gKwkJZGV2X2VycihkZXYs ICJmYWlsZWQgdG8gZ2V0IGlycVxuIik7DQo+ID4gKwkJcmV0dXJuIC1FTk9ERVY7DQo+ID4gKwl9 DQo+ID4gKwlyZXQgPSBkZXZtX3JlcXVlc3RfaXJxKGRldiwgaXJxLCBpc3BfaXJxX2NhbSwgMCwg ZGV2X25hbWUoZGV2KSwNCj4gPiArCQkJICAgICAgIHAxX2Rldik7DQo+ID4gKwlpZiAocmV0KSB7 DQo+ID4gKwkJZGV2X2VycihkZXYsICJmYWlsZWQgdG8gcmVxdWVzdCBpcnE9JWRcbiIsIGlycSk7 DQo+ID4gKwkJcmV0dXJuIHJldDsNCj4gPiArCX0NCj4gPiArCWRldl9kYmcoZGV2LCAicmVnaXN0 ZXJlZCBpcnE9JWRcbiIsIGlycSk7DQo+ID4gKwlzcGluX2xvY2tfaW5pdCgmcDFfZGV2LT5zcGlu bG9ja19pcnEpOw0KPiA+ICsNCj4gPiArCXAxX2Rldi0+bnVtX2Nsa3MgPSBBUlJBWV9TSVpFKGNs a19uYW1lcyk7DQo+ID4gKwlwMV9kZXYtPmNsa3MgPSBkZXZtX2tjYWxsb2MoZGV2LCBwMV9kZXYt Pm51bV9jbGtzLA0KPiA+ICsJCQkJICAgIHNpemVvZigqcDFfZGV2LT5jbGtzKSwgR0ZQX0tFUk5F TCk7DQo+ID4gKwlpZiAoIXAxX2Rldi0+Y2xrcykNCj4gPiArCQlyZXR1cm4gLUVOT01FTTsNCj4g PiArDQo+ID4gKwlmb3IgKGkgPSAwOyBpIDwgcDFfZGV2LT5udW1fY2xrczsgKytpKQ0KPiA+ICsJ CXAxX2Rldi0+Y2xrc1tpXS5pZCA9IGNsa19uYW1lc1tpXTsNCj4gPiArDQo+ID4gKwlyZXQgPSBk ZXZtX2Nsa19idWxrX2dldChkZXYsIHAxX2Rldi0+bnVtX2Nsa3MsIHAxX2Rldi0+Y2xrcyk7DQo+ ID4gKwlpZiAocmV0KSB7DQo+ID4gKwkJZGV2X2VycihkZXYsICJmYWlsZWQgdG8gZ2V0IGlzcCBj YW0gY2xvY2s6JWRcbiIsIHJldCk7DQo+ID4gKwkJcmV0dXJuIHJldDsNCj4gPiArCX0NCj4gPiAr DQo+ID4gKwlyZXQgPSBpc3Bfc2V0dXBfc2NwX3Jwcm9jKHAxX2RldiwgcGRldik7DQo+ID4gKwlp ZiAocmV0KQ0KPiA+ICsJCXJldHVybiByZXQ7DQo+ID4gKw0KPiA+ICsJcG1fcnVudGltZV9zZXRf YXV0b3N1c3BlbmRfZGVsYXkoZGV2LCBNVEtfSVNQX0FVVE9TVVNQRU5EX0RFTEFZX01TKTsNCj4g PiArCXBtX3J1bnRpbWVfdXNlX2F1dG9zdXNwZW5kKGRldik7DQo+ID4gKwlwbV9ydW50aW1lX2Vu YWJsZShkZXYpOw0KPiA+ICsNCj4gPiArCS8qIEluaXRpYWxpemUgdGhlIHY0bDIgY29tbW9uIHBh cnQgKi8NCj4gPiArCXJldCA9IG10a19jYW1fZGV2X2luaXQocGRldiwgJnAxX2Rldi0+Y2FtX2Rl dik7DQo+ID4gKwlpZiAocmV0KSB7DQo+ID4gKwkJaXNwX3RlYXJkb3duX3NjcF9ycHJvYyhwMV9k ZXYpOw0KPiA+ICsJCXJldHVybiByZXQ7DQo+ID4gKwl9DQo+ID4gKw0KPiA+ICsJcmV0dXJuIDA7 DQo+ID4gK30NCj4gPiArDQo+ID4gK3N0YXRpYyBpbnQgbXRrX2lzcF9yZW1vdmUoc3RydWN0IHBs YXRmb3JtX2RldmljZSAqcGRldikNCj4gPiArew0KPiA+ICsJc3RydWN0IGRldmljZSAqZGV2ID0g JnBkZXYtPmRldjsNCj4gPiArCXN0cnVjdCBtdGtfaXNwX3AxX2RldmljZSAqcDFfZGV2ID0gZGV2 X2dldF9kcnZkYXRhKGRldik7DQo+ID4gKw0KPiA+ICsJbXRrX2NhbV9kZXZfY2xlYW51cCgmcDFf ZGV2LT5jYW1fZGV2KTsNCj4gPiArCXBtX3J1bnRpbWVfZG9udF91c2VfYXV0b3N1c3BlbmQoZGV2 KTsNCj4gPiArCXBtX3J1bnRpbWVfZGlzYWJsZShkZXYpOw0KPiA+ICsJZG1hX3VubWFwX3BhZ2Vf YXR0cnMoZGV2LCBwMV9kZXYtPmNvbXBvc2VyX2lvdmEsDQo+ID4gKwkJCSAgICAgTVRLX0lTUF9D T01QT1NFUl9NRU1fU0laRSwgRE1BX1RPX0RFVklDRSwNCj4gPiArCQkJICAgICBETUFfQVRUUl9T S0lQX0NQVV9TWU5DKTsNCj4gPiArCWlzcF90ZWFyZG93bl9zY3BfcnByb2MocDFfZGV2KTsNCj4g PiArDQo+ID4gKwlyZXR1cm4gMDsNCj4gPiArfQ0KPiA+ICsNCj4gPiArc3RhdGljIGNvbnN0IHN0 cnVjdCBkZXZfcG1fb3BzIG10a19pc3BfcG1fb3BzID0gew0KPiA+ICsJU0VUX1NZU1RFTV9TTEVF UF9QTV9PUFMobXRrX2lzcF9wbV9zdXNwZW5kLCBtdGtfaXNwX3BtX3Jlc3VtZSkNCj4gPiArCVNF VF9SVU5USU1FX1BNX09QUyhtdGtfaXNwX3J1bnRpbWVfc3VzcGVuZCwgbXRrX2lzcF9ydW50aW1l X3Jlc3VtZSwNCj4gPiArCQkJICAgTlVMTCkNCj4gPiArfTsNCj4gPiArDQo+ID4gK3N0YXRpYyBj b25zdCBzdHJ1Y3Qgb2ZfZGV2aWNlX2lkIG10a19pc3Bfb2ZfaWRzW10gPSB7DQo+ID4gKwl7LmNv bXBhdGlibGUgPSAibWVkaWF0ZWssbXQ4MTgzLWNhbWlzcCIsfSwNCj4gPiArCXt9DQo+ID4gK307 DQo+ID4gK01PRFVMRV9ERVZJQ0VfVEFCTEUob2YsIG10a19pc3Bfb2ZfaWRzKTsNCj4gPiArDQo+ ID4gK3N0YXRpYyBzdHJ1Y3QgcGxhdGZvcm1fZHJpdmVyIG10a19pc3BfZHJpdmVyID0gew0KPiA+ ICsJLnByb2JlICAgPSBtdGtfaXNwX3Byb2JlLA0KPiA+ICsJLnJlbW92ZSAgPSBtdGtfaXNwX3Jl bW92ZSwNCj4gPiArCS5kcml2ZXIgID0gew0KPiA+ICsJCS5uYW1lICA9ICJtdGstY2FtLXAxIiwN Cj4gPiArCQkub2ZfbWF0Y2hfdGFibGUgPSBvZl9tYXRjaF9wdHIobXRrX2lzcF9vZl9pZHMpLA0K PiA+ICsJCS5wbSAgICAgPSAmbXRrX2lzcF9wbV9vcHMsDQo+ID4gKwl9DQo+ID4gK307DQo+ID4g Kw0KPiA+ICttb2R1bGVfcGxhdGZvcm1fZHJpdmVyKG10a19pc3BfZHJpdmVyKTsNCj4gPiArDQo+ ID4gK01PRFVMRV9ERVNDUklQVElPTigiTWVkaWF0ZWsgSVNQIFAxIGRyaXZlciIpOw0KPiA+ICtN T0RVTEVfTElDRU5TRSgiR1BMIHYyIik7DQo+ID4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvbWVkaWEv cGxhdGZvcm0vbXRrLWlzcC9pc3BfNTAvY2FtL210a19jYW0taHcuaCBiL2RyaXZlcnMvbWVkaWEv cGxhdGZvcm0vbXRrLWlzcC9pc3BfNTAvY2FtL210a19jYW0taHcuaA0KPiA+IG5ldyBmaWxlIG1v ZGUgMTAwNjQ0DQo+ID4gaW5kZXggMDAwMDAwMDAwMDAwLi44Mzc2NjJmOTJhNWUNCj4gPiAtLS0g L2Rldi9udWxsDQo+ID4gKysrIGIvZHJpdmVycy9tZWRpYS9wbGF0Zm9ybS9tdGstaXNwL2lzcF81 MC9jYW0vbXRrX2NhbS1ody5oDQo+IA0KPiBUaGlzIGhlYWRlciBmaWxlIGlzIHJlYWxseSBzaG9y dCwgd2h5IG5vdCBtZXJnZSBpdCB3aXRoIG10a19jYW0uaCAodGhhdCBpcyBzbWFsbCB0b28pIGFu ZCBjYWxsIGl0IG10a19pc3BfY29tbW9uLmggb3IgbXRrX2NhbV9jb21tb24/DQo+IA0KDQpPaywg cmV2aXNlIGluIG5leHQgcGF0Y2guDQoNCj4gPiBAQCAtMCwwICsxLDY0IEBADQo+ID4gKy8qIFNQ RFgtTGljZW5zZS1JZGVudGlmaWVyOiBHUEwtMi4wICovDQo+ID4gKy8qDQo+ID4gKyAqIENvcHly aWdodCAoYykgMjAxOSBNZWRpYVRlayBJbmMuDQo+ID4gKyAqLw0KPiA+ICsNCj4gPiArI2lmbmRl ZiBfX01US19DQU1fSFdfSF9fDQo+ID4gKyNkZWZpbmUgX19NVEtfQ0FNX0hXX0hfXw0KPiA+ICsN Cj4gPiArI2luY2x1ZGUgPGxpbnV4L3R5cGVzLmg+DQo+ID4gKw0KPiA+ICsjaW5jbHVkZSAibXRr X2NhbS5oIg0KPiA+ICsjaW5jbHVkZSAibXRrX2NhbS1pcGkuaCINCj4gPiArDQo+ID4gKy8qDQo+ ID4gKyAqIHN0cnVjdCBtdGtfaXNwX3AxX2RldmljZSAtIHRoZSBNZWRpYXRlayBJU1AgUDEgZGV2 aWNlIGluZm9ybWF0aW9uDQo+ID4gKyAqDQo+ID4gKyAqIEBkZXY6IFBvaW50ZXIgdG8gZGV2aWNl Lg0KPiA+ICsgKiBAc2NwX3BkZXY6IFBvaW50ZXIgdG8gU0NQIHBsYXRmb3JtIGRldmljZS4NCj4g PiArICogQHJwcm9jX2hhbmRsZTogUG9pbnRlciB0byBuZXcgcmVtb3RlcHJvYyBpbnN0YW5jZS4N Cj4gPiArICogQGNhbV9kZXY6IEVtYmVkZGVkIHN0cnVjdCBjYW1fZGV2DQo+ID4gKyAqIEByZWdz OiBDYW1lcmEgSVNQIEhXIGJhc2UgcmVnaXN0ZXIgYWRkcmVzcw0KPiA+ICsgKiBAbnVtX2Nsa3M6 IFRoZSBudW1iZXIgb2YgZHJpdmVyJ3MgY2xvY2tzDQo+ID4gKyAqIEBjbGtzOiBUaGUgY2xvY2sg ZGF0YSBhcnJheQ0KPiA+ICsgKiBAc3BpbmxvY2tfaXJxOiBVc2VkIHRvIHByb3RlY3QgcmVnaXN0 ZXIgcmVhZC93cml0ZSBkYXRhDQo+ID4gKyAqIEBlbnF1ZXVlZF9mcmFtZV9zZXFfbm86IEZyYW1l IHNlcXVlbmNlIG51bWJlciBvZiBlbnF1ZXVlZCBmcmFtZQ0KPiA+ICsgKiBAZGVxdWV1ZWRfZnJh bWVfc2VxX25vOiBGcmFtZSBzZXF1ZW5jZSBudW1iZXIgb2YgZGVxdWV1ZWQgZnJhbWUNCj4gPiAr ICogQGNvbXBvc2VkX2ZyYW1lX3NlcV9ubzogRnJhbWUgc2VxdWVuY2UgbnVtYmVyIG9mIGNvbXBv c2VkIGZyYW1lDQo+ID4gKyAqIEB0aW1lc3RhbXA6IEZyYW1lIHRpbWVzdGFtcCBpbiBucw0KPiA+ ICsgKiBAc29mX2NvdW50OiBTT0YgY291bnRlcg0KPiA+ICsgKiBAY29tcG9zZXJfd3E6IFRoZSB3 b3JrIHF1ZXVlIGZvciBmcmFtZSByZXF1ZXN0IGNvbXBvc2luZw0KPiA+ICsgKiBAY29tcG9zZXJf c2NwX2FkZHI6IFNDUCBhZGRyZXNzIG9mIElTUCBjb21wb3NlciBtZW1vcnkNCj4gPiArICogQGNv bXBvc2VyX2lvdmE6IERNQSBhZGRyZXNzIG9mIElTUCBjb21wb3NlciBtZW1vcnkNCj4gPiArICog QHZpcnRfYWRkcjogVmlydHVhbCBhZGRyZXNzIG9mIElTUCBjb21wb3NlciBtZW1vcnkNCj4gPiAr ICoNCj4gPiArICovDQo+ID4gK3N0cnVjdCBtdGtfaXNwX3AxX2RldmljZSB7DQo+ID4gKwlzdHJ1 Y3QgZGV2aWNlICpkZXY7DQo+ID4gKwlzdHJ1Y3QgbXRrX3NjcCAqc2NwOw0KPiA+ICsJc3RydWN0 IHJwcm9jICpycHJvY19oYW5kbGU7DQo+ID4gKwlzdHJ1Y3QgbXRrX2NhbV9kZXYgY2FtX2RldjsN Cj4gPiArCXZvaWQgX19pb21lbSAqcmVnczsNCj4gPiArCXVuc2lnbmVkIGludCBudW1fY2xrczsN Cj4gPiArCXN0cnVjdCBjbGtfYnVsa19kYXRhICpjbGtzOw0KPiA+ICsJLyogVXNlZCB0byBwcm90 ZWN0IHJlZ2lzdGVyIHJlYWQvd3JpdGUgZGF0YSAqLw0KPiA+ICsJc3BpbmxvY2tfdCBzcGlubG9j a19pcnE7DQo+ID4gKwl1bnNpZ25lZCBpbnQgZW5xdWV1ZWRfZnJhbWVfc2VxX25vOw0KPiA+ICsJ dW5zaWduZWQgaW50IGRlcXVldWVkX2ZyYW1lX3NlcV9ubzsNCj4gPiArCXVuc2lnbmVkIGludCBj b21wb3NlZF9mcmFtZV9zZXFfbm87DQo+ID4gKwl1OCBzb2ZfY291bnQ7DQo+ID4gKwlzdHJ1Y3Qg d29ya3F1ZXVlX3N0cnVjdCAqY29tcG9zZXJfd3E7DQo+ID4gKwlkbWFfYWRkcl90IGNvbXBvc2Vy X3NjcF9hZGRyOw0KPiA+ICsJZG1hX2FkZHJfdCBjb21wb3Nlcl9pb3ZhOw0KPiA+ICsJdm9pZCAq Y29tcG9zZXJfdmlydF9hZGRyOw0KPiA+ICt9Ow0KPiA+ICsNCj4gPiAraW50IG10a19pc3BfaHdf aW5pdChzdHJ1Y3QgbXRrX2NhbV9kZXYgKmNhbV9kZXYpOw0KPiA+ICtpbnQgbXRrX2lzcF9od19y ZWxlYXNlKHN0cnVjdCBtdGtfY2FtX2RldiAqY2FtX2Rldik7DQo+ID4gK3ZvaWQgbXRrX2lzcF9o d19jb25maWcoc3RydWN0IG10a19jYW1fZGV2ICpjYW1fZGV2LA0KPiA+ICsJCSAgICAgICBzdHJ1 Y3QgcDFfY29uZmlnX3BhcmFtICpjb25maWdfcGFyYW0pOw0KPiA+ICt2b2lkIG10a19pc3Bfc3Ry ZWFtKHN0cnVjdCBtdGtfY2FtX2RldiAqY2FtX2RldiwgaW50IG9uKTsNCj4gPiArdm9pZCBtdGtf aXNwX3JlcV9lbnF1ZXVlKHN0cnVjdCBtdGtfY2FtX2RldiAqY2FtX2RldiwNCj4gPiArCQkJIHN0 cnVjdCBtdGtfY2FtX2Rldl9yZXF1ZXN0ICpyZXEpOw0KPiANCj4gSXQgd291bGQgYmUgbmljZSB0 byBoYXZlIGRvY3MgZm9yIHRoZXNlIHRvby4NCj4gDQoNCk9rLCBhZGQgaW4gbmV4dCBwYXRjaC4N Cg0KPiA+ICsNCj4gPiArI2VuZGlmIC8qIF9fTVRLX0NBTV9IV19IX18gKi8NCj4gPiBkaWZmIC0t Z2l0IGEvZHJpdmVycy9tZWRpYS9wbGF0Zm9ybS9tdGstaXNwL2lzcF81MC9jYW0vbXRrX2NhbS1p cGkuaCBiL2RyaXZlcnMvbWVkaWEvcGxhdGZvcm0vbXRrLWlzcC9pc3BfNTAvY2FtL210a19jYW0t aXBpLmgNCj4gPiBuZXcgZmlsZSBtb2RlIDEwMDY0NA0KPiA+IGluZGV4IDAwMDAwMDAwMDAwMC4u OTgxYjYzNGRkOTFmDQo+ID4gLS0tIC9kZXYvbnVsbA0KPiA+ICsrKyBiL2RyaXZlcnMvbWVkaWEv cGxhdGZvcm0vbXRrLWlzcC9pc3BfNTAvY2FtL210a19jYW0taXBpLmgNCj4gDQo+IEknbSBza2lw cGluZyB0aGlzIGZpbGUsIHNpbmNlLCBpZiBJIHVuZGVyc3RhbmQgY29ycmVjdGx5LCB0aGlzIGlz IG5vdCByZWFkeSBmb3IgcmV2aWV3IHJpZ2h0Pw0KPiANCg0KSSB0aGluayB0aGlzIGZpbGUgaXMg cmVhZHkgZm9yIHJldmlldy4NCg0KDQo+ID4gQEAgLTAsMCArMSwyMjIgQEANCj4gPiArLyogU1BE WC1MaWNlbnNlLUlkZW50aWZpZXI6IEdQTC0yLjAgKi8NCj4gPiArLyoNCj4gPiArICogQ29weXJp Z2h0IChjKSAyMDE5IE1lZGlhVGVrIEluYy4NCj4gPiArICovDQo+ID4gKw0KPiA+ICsjaWZuZGVm IF9fTVRLX0NBTV9JUElfSF9fDQo+ID4gKyNkZWZpbmUgX19NVEtfQ0FNX0lQSV9IX18NCj4gPiAr DQo+ID4gKyNpbmNsdWRlIDxsaW51eC90eXBlcy5oPg0KPiA+ICsNCj4gPiArLyoNCj4gPiArICog c3RydWN0IGltZ19zaXplIC0gSW1hZ2Ugc2l6ZSBpbmZvcm1hdGlvbi4NCj4gPiArICoNCj4gPiAr ICogQHc6IEltYWdlIHdpZHRoLCB0aGUgdW5pdCBpcyBwaXhlbA0KPiA+ICsgKiBAaDogSW1hZ2Ug aGVpZ2h0LCB0aGUgdW5pdCBpcyBwaXhlbA0KPiA+ICsgKiBAeHNpemU6IEJ5dGVzIHBlciBsaW5l IGJhc2VkIG9uIHdpZHRoLg0KPiA+ICsgKiBAc3RyaWRlOiBCeXRlcyBwZXIgbGluZSB3aGVuIGNo YW5naW5nIGxpbmUuDQo+ID4gKyAqICAgICAgICAgIFN0cmlkZSBpcyBiYXNlZCBvbiB4c2l6ZSAr IEhXIGNvbnN0cmFpbihieXRlIGFsaWduKS4NCj4gPiArICoNCj4gPiArICovDQo+ID4gK3N0cnVj dCBpbWdfc2l6ZSB7DQo+ID4gKwl1MzIgdzsNCj4gPiArCXUzMiBoOw0KPiA+ICsJdTMyIHhzaXpl Ow0KPiA+ICsJdTMyIHN0cmlkZTsNCj4gPiArfSBfX3BhY2tlZDsNCj4gPiArDQo+ID4gKy8qDQo+ ID4gKyAqIHN0cnVjdCBwMV9pbWdfY3JvcCAtIGltYWdlIGNvcnAgaW5mb3JtYXRpb24NCj4gPiAr ICoNCj4gPiArICogQGxlZnQ6IFRoZSBsZWZ0IG9mIGNyb3AgYXJlYS4NCj4gPiArICogQHRvcDog VGhlIHRvcCBvZiBjcm9wIGFyZWEuDQo+ID4gKyAqIEB3aWR0aDogVGhlIHdpZHRoIG9mIGNyb3Ag YXJlYS4NCj4gPiArICogQGhlaWdodDogVGhlIGhlaWdodCBvZiBjcm9wIGFyZWEuDQo+ID4gKyAq DQo+ID4gKyAqLw0KPiA+ICtzdHJ1Y3QgcDFfaW1nX2Nyb3Agew0KPiA+ICsJdTMyIGxlZnQ7DQo+ ID4gKwl1MzIgdG9wOw0KPiA+ICsJdTMyIHdpZHRoOw0KPiA+ICsJdTMyIGhlaWdodDsNCj4gPiAr fSBfX3BhY2tlZDsNCj4gPiArDQo+ID4gKy8qDQo+ID4gKyAqIHN0cnVjdCBkbWFfYnVmZmVyIC0g RE1BIGJ1ZmZlciBhZGRyZXNzIGluZm9ybWF0aW9uDQo+ID4gKyAqDQo+ID4gKyAqIEBpb3ZhOiBE TUEgYWRkcmVzcyBmb3IgSVNQIERNQSBkZXZpY2UNCj4gPiArICogQHNjcF9hZGRyOiBTQ1AgYWRk cmVzcyBmb3IgZXh0ZXJuYWwgY28tcHJvY2VzcyB1bml0DQo+ID4gKyAqDQo+ID4gKyAqLw0KPiA+ ICtzdHJ1Y3QgZG1hX2J1ZmZlciB7DQo+ID4gKwl1MzIgaW92YTsNCj4gDQo+IEkgd291bGQgcmVu YW1lIHRoaXMgdG8gaXNwX2FkZHIsIHNpbmNlIHNjcF9hZGRyIGlzIGFsc28gaW92YSAoYXQgbGVh c3QgdGhpcyBpcyB0aGUgd2F5IEkgdW5kZXJzdGFuZCkuDQo+IA0KDQpPaywgcmV2aXNlIGluIG5l eHQgcGF0Y2guDQoNCj4gPiArCXUzMiBzY3BfYWRkcjsNCj4gPiArfSBfX3BhY2tlZDsNCj4gPiAr DQo+ID4gKy8qDQo+ID4gKyAqIHN0cnVjdCBwMV9pbWdfb3V0cHV0IC0gSVNQIFAxIGltYWdlIG91 dHB1dCBpbmZvcm1hdGlvbg0KPiA+ICsgKg0KPiA+ICsgKiBAYnVmZmVyOiBETUEgYnVmZmVyIGFk ZHJlc3Mgb2YgaW1hZ2UuDQo+ID4gKyAqIEBzaXplOiBUaGUgaW1hZ2Ugc2l6ZSBjb25maWd1cmF0 aW9uLg0KPiA+ICsgKiBAY3JvcDogVGhlIGNyb3AgY29uZmlndXJhdGlvbi4NCj4gPiArICogQHBp eGVsX2JpdHM6IFRoZSBiaXRzIHBlciBpbWFnZSBwaXhlbC4NCj4gPiArICogQGltZ19mbXQ6IFRo ZSBpbWFnZSBmb3JtYXQuDQo+ID4gKyAqDQo+ID4gKyAqLw0KPiA+ICtzdHJ1Y3QgcDFfaW1nX291 dHB1dCB7DQo+ID4gKwlzdHJ1Y3QgZG1hX2J1ZmZlciBidWZmZXI7DQo+ID4gKwlzdHJ1Y3QgaW1n X3NpemUgc2l6ZTsNCj4gPiArCXN0cnVjdCBwMV9pbWdfY3JvcCBjcm9wOw0KPiA+ICsJdTggcGl4 ZWxfYml0czsNCj4gPiArCXUzMiBpbWdfZm10Ow0KPiA+ICt9IF9fcGFja2VkOw0KPiA+ICsNCj4g PiArLyoNCj4gPiArICogc3RydWN0IGNmZ19pbl9wYXJhbSAtIEltYWdlIGlucHV0IHBhcmFtZXRl cnMgc3RydWN0dXJlLg0KPiA+ICsgKiAgICAgICAgICAgICAgICAgICAgICAgTm9ybWFsbHksIGl0 IGNvbWVzIGZyb20gc2Vuc29yIGluZm9ybWF0aW9uLg0KPiA+ICsgKg0KPiA+ICsgKiBAY29udGlu dW91czogSW5kaWNhdGUgdGhlIHNlbnNvciBtb2RlLiBDb250aW51b3VzIG9yIHNpbmdsZSBzaG90 Lg0KPiA+ICsgKiBAc3Vic2FtcGxlOiBJbmRpY2F0ZSB0byBlbmFibGVzIFNPRiBzdWJzYW1wbGUg b3Igbm90Lg0KPiA+ICsgKiBAcGl4ZWxfbW9kZTogRGVzY3JpYmUgMS8yLzQgcGl4ZWxzIHBlciBj bG9jayBjeWNsZS4NCj4gPiArICogQGRhdGFfcGF0dGVybjogRGVzY3JpYmUgaW5wdXQgZGF0YSBw YXR0ZXJuLg0KPiA+ICsgKiBAcmF3X3BpeGVsX2lkOiBCYXllciBzZXF1ZW5jZS4NCj4gPiArICog QHRnX2ZwczogVGhlIGZwcyByYXRlIG9mIFRHICh0aW1lIGdlbmVyYXRvcikuDQo+ID4gKyAqIEBp bWdfZm10OiBUaGUgaW1hZ2UgZm9ybWF0IG9mIGlucHV0IHNvdXJjZS4NCj4gPiArICogQHAxX2lt Z19jcm9wOiBUaGUgY3JvcCBjb25maWd1cmF0aW9uIG9mIGlucHV0IHNvdXJjZS4NCj4gPiArICoN Cj4gPiArICovDQo+ID4gK3N0cnVjdCBjZmdfaW5fcGFyYW0gew0KPiA+ICsJdTggY29udGludW91 czsNCj4gPiArCXU4IHN1YnNhbXBsZTsNCj4gPiArCXU4IHBpeGVsX21vZGU7DQo+ID4gKwl1OCBk YXRhX3BhdHRlcm47DQo+ID4gKwl1OCByYXdfcGl4ZWxfaWQ7DQo+ID4gKwl1MTYgdGdfZnBzOw0K PiA+ICsJdTMyIGltZ19mbXQ7DQo+ID4gKwlzdHJ1Y3QgcDFfaW1nX2Nyb3AgY3JvcDsNCj4gPiAr fSBfX3BhY2tlZDsNCj4gPiArDQo+ID4gKy8qDQo+ID4gKyAqIHN0cnVjdCBjZmdfbWFpbl9vdXRf cGFyYW0gLSBUaGUgaW1hZ2Ugb3V0cHV0IHBhcmFtZXRlcnMgb2YgbWFpbiBzdHJlYW0uDQo+ID4g KyAqDQo+ID4gKyAqIEBieXBhc3M6IEluZGljYXRlIHRoaXMgZGV2aWNlIGlzIGVuYWJsZWQgb3Ig ZGlzYWJsZWQgb3Igbm90Lg0KPiA+ICsgKiBAcHVyZV9yYXc6IEluZGljYXRlIHRoZSBpbWFnZSBw YXRoIGNvbnRyb2wuDQo+ID4gKyAqICAgICAgICAgICAgVHJ1ZTogcHVyZSByYXcNCj4gPiArICog ICAgICAgICAgICBGYWxzZTogcHJvY2Vzc2luZyByYXcNCj4gPiArICogQHB1cmVfcmF3X3BhY2s6 IEluZGljYXRlIHRoZSBpbWFnZSBpcyBwYWNrZWQgb3Igbm90Lg0KPiA+ICsgKiAgICAgICAgICAg ICAgICAgVHJ1ZTogcGFja2VkIG1vZGUNCj4gPiArICogICAgICAgICAgICAgICAgIEZhbHNlOiB1 bnBhY2tlZCBtb2RlDQo+ID4gKyAqIEBwMV9pbWdfb3V0cHV0OiBUaGUgb3V0cHV0IGltYWdlIGlu Zm9ybWF0aW9uLg0KPiA+ICsgKg0KPiA+ICsgKi8NCj4gPiArc3RydWN0IGNmZ19tYWluX291dF9w YXJhbSB7DQo+ID4gKwl1OCBieXBhc3M7DQo+ID4gKwl1OCBwdXJlX3JhdzsNCj4gPiArCXU4IHB1 cmVfcmF3X3BhY2s7DQo+ID4gKwlzdHJ1Y3QgcDFfaW1nX291dHB1dCBvdXRwdXQ7DQo+ID4gK30g X19wYWNrZWQ7DQo+ID4gKw0KPiA+ICsvKg0KPiA+ICsgKiBzdHJ1Y3QgY2ZnX3Jlc2l6ZV9vdXRf cGFyYW0gLSBUaGUgaW1hZ2Ugb3V0cHV0IHBhcmFtZXRlcnMgb2YNCj4gPiArICogICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgcGFja2VkIG91dCBzdHJlYW0uDQo+ID4gKyAqDQo+ID4gKyAq IEBieXBhc3M6IEluZGljYXRlIHRoaXMgZGV2aWNlIGlzIGVuYWJsZWQgb3IgZGlzYWJsZWQgb3Ig bm90Lg0KPiA+ICsgKiBAcDFfaW1nX291dHB1dDogVGhlIG91dHB1dCBpbWFnZSBpbmZvcm1hdGlv bi4NCj4gPiArICoNCj4gPiArICovDQo+ID4gK3N0cnVjdCBjZmdfcmVzaXplX291dF9wYXJhbSB7 DQo+ID4gKwl1OCBieXBhc3M7DQo+ID4gKwlzdHJ1Y3QgcDFfaW1nX291dHB1dCBvdXRwdXQ7DQo+ ID4gK30gX19wYWNrZWQ7DQo+ID4gKw0KPiA+ICsvKg0KPiA+ICsgKiBzdHJ1Y3QgcDFfY29uZmln X3BhcmFtIC0gSVNQIFAxIGNvbmZpZ3VyYXRpb24gcGFyYW1ldGVycy4NCj4gPiArICoNCj4gPiAr ICogQGNmZ19pbl9wYXJhbTogVGhlIEltYWdlIGlucHV0IHBhcmFtZXRlcnMuDQo+ID4gKyAqIEBj ZmdfbWFpbl9wYXJhbTogVGhlIG1haW4gb3V0cHV0IGltYWdlIHBhcmFtZXRlcnMuDQo+ID4gKyAq IEBjZmdfcmVzaXplX291dF9wYXJhbTogVGhlIHBhY2tlZCBvdXRwdXQgaW1hZ2UgcGFyYW1ldGVy cy4NCj4gPiArICogQGVuYWJsZWRfZG1hczogVGhlIGVuYWJsZWQgRE1BIHBvcnQgaW5mb3JtYXRp b24uDQo+ID4gKyAqDQo+ID4gKyAqLw0KPiA+ICtzdHJ1Y3QgcDFfY29uZmlnX3BhcmFtIHsNCj4g PiArCXN0cnVjdCBjZmdfaW5fcGFyYW0gY2ZnX2luX3BhcmFtOw0KPiA+ICsJc3RydWN0IGNmZ19t YWluX291dF9wYXJhbSBjZmdfbWFpbl9wYXJhbTsNCj4gPiArCXN0cnVjdCBjZmdfcmVzaXplX291 dF9wYXJhbSBjZmdfcmVzaXplX3BhcmFtOw0KPiA+ICsJdTMyIGVuYWJsZWRfZG1hczsNCj4gPiAr fSBfX3BhY2tlZDsNCj4gPiArDQo+ID4gKy8qDQo+ID4gKyAqIHN0cnVjdCBQMV9tZXRhX2ZyYW1l IC0gSVNQIFAxIG1ldGEgZnJhbWUgaW5mb3JtYXRpb24uDQo+ID4gKyAqDQo+ID4gKyAqIEBlbmFi bGVkX2RtYTogVGhlIGVuYWJsZWQgRE1BIHBvcnQgaW5mb3JtYXRpb24uDQo+ID4gKyAqIEB2Yl9p bmRleDogVGhlIFZCMiBpbmRleCBvZiBtZXRhIGJ1ZmZlci4NCj4gPiArICogQG1ldGFfYWRkcjog RE1BIGJ1ZmZlciBhZGRyZXNzIG9mIG1ldGEgYnVmZmVyLg0KPiA+ICsgKg0KPiA+ICsgKi8NCj4g PiArc3RydWN0IFAxX21ldGFfZnJhbWUgew0KPiA+ICsJdTMyIGVuYWJsZWRfZG1hOw0KPiA+ICsJ dTMyIHZiX2luZGV4Ow0KPiA+ICsJc3RydWN0IGRtYV9idWZmZXIgbWV0YV9hZGRyOw0KPiA+ICt9 IF9fcGFja2VkOw0KPiA+ICsNCj4gPiArLyoNCj4gPiArICogc3RydWN0IGlzcF9pbml0X2luZm8g LSBJU1AgUDEgY29tcG9zZXIgaW5pdCBpbmZvcm1hdGlvbi4NCj4gPiArICoNCj4gPiArICogQGh3 X21vZHVsZTogVGhlIElTUCBDYW1lcmEgSFcgbW9kdWxlIElELg0KPiA+ICsgKiBAY3FfYWRkcjog VGhlIERNQSBhZGRyZXNzIG9mIGNvbXBvc2VyIG1lbW9yeS4NCj4gPiArICoNCj4gPiArICovDQo+ ID4gK3N0cnVjdCBpc3BfaW5pdF9pbmZvIHsNCj4gPiArCXU4IGh3X21vZHVsZTsNCj4gPiArCXN0 cnVjdCBkbWFfYnVmZmVyIGNxX2FkZHI7DQo+ID4gK30gX19wYWNrZWQ7DQo+ID4gKw0KPiA+ICsv Kg0KPiA+ICsgKiBzdHJ1Y3QgaXNwX2Fja19pbmZvIC0gSVNQIFAxIElQSSBjb21tYW5kIGFjayBp bmZvcm1hdGlvbi4NCj4gPiArICoNCj4gPiArICogQGNtZF9pZDogVGhlIElQSSBjb21tYW5kIElE IGlzIGFja2VkLg0KPiA+ICsgKiBAZnJhbWVfc2VxX25vOiBUaGUgSVBJIGZyYW1lIHNlcXVlbmNl IG51bWJlciBpcyBhY2tlZC4NCj4gPiArICoNCj4gPiArICovDQo+ID4gK3N0cnVjdCBpc3BfYWNr X2luZm8gew0KPiA+ICsJdTggY21kX2lkOw0KPiA+ICsJdTMyIGZyYW1lX3NlcV9ubzsNCj4gPiAr fSBfX3BhY2tlZDsNCj4gPiArDQo+ID4gKy8qDQo+ID4gKyAqIFRoZSBJUEkgY29tbWFuZCBlbnVt ZXJhdGlvbi4NCj4gPiArICovDQo+ID4gK2VudW0gbXRrX2lzcF9zY3BfY21kcyB7DQo+ID4gKwlJ U1BfQ01EX0lOSVQsDQo+ID4gKwlJU1BfQ01EX0NPTkZJRywNCj4gPiArCUlTUF9DTURfU1RSRUFN LA0KPiA+ICsJSVNQX0NNRF9ERUlOSVQsDQo+ID4gKwlJU1BfQ01EX0FDSywNCj4gPiArCUlTUF9D TURfRlJBTUVfQUNLLA0KPiA+ICsJSVNQX0NNRF9SRVNFUlZFRCwNCj4gPiArfTsNCj4gPiArDQo+ ID4gKy8qDQo+ID4gKyAqIHN0cnVjdCBtdGtfaXNwX3NjcF9wMV9jbWQgLSBJU1AgUDEgSVBJIGNv bW1hbmQgc3RyY3R1cmUuDQo+ID4gKyAqDQo+ID4gKyAqIEBjbWRfaWQ6IFRoZSBJUEkgY29tbWFu ZCBJRC4NCj4gPiArICogQGluaXRfcGFyYW06IFRoZSBpbml0IGZvcm1hdGlvbiBmb3IgSVNQX0NN RF9JTklULg0KPiA+ICsgKiBAY29uZmlnX3BhcmFtOiBUaGUgY21kIGNvbmZpZ3VyYXRpb24gZm9y IElTUF9DTURfQ09ORklHLg0KPiA+ICsgKiBAZW5hYmxlZF9kbWFzOiBUaGUgbWV0YSBjb25maWd1 cmF0aW9uIGluZm9ybWF0aW9uIGZvciBJU1BfQ01EX0NPTkZJR19NRVRBLg0KPiA+ICsgKiBAaXNf c3RyZWFtX29uOiBUaGUgc3RyZWFtIGluZm9ybWF0aW9uIGZvciBJU1BfQ01EX1NUUkVBTS4NCj4g PiArICogQGFja19pbmZvOiBUaGUgY21kIGFjay4gaW5mb3JtYXRpb24gZm9yIElTUF9DTURfQUNL Lg0KPiA+ICsgKg0KPiA+ICsgKi8NCj4gPiArc3RydWN0IG10a19pc3Bfc2NwX3AxX2NtZCB7DQo+ ID4gKwl1OCBjbWRfaWQ7DQo+ID4gKwl1bmlvbiB7DQo+ID4gKwkJc3RydWN0IGlzcF9pbml0X2lu Zm8gaW5pdF9wYXJhbTsNCj4gPiArCQlzdHJ1Y3QgcDFfY29uZmlnX3BhcmFtIGNvbmZpZ19wYXJh bTsNCj4gPiArCQl1MzIgZW5hYmxlZF9kbWFzOw0KPiA+ICsJCXN0cnVjdCBQMV9tZXRhX2ZyYW1l IG1ldGFfZnJhbWU7DQo+ID4gKwkJdTggaXNfc3RyZWFtX29uOw0KPiA+ICsJCXN0cnVjdCBpc3Bf YWNrX2luZm8gYWNrX2luZm87DQo+ID4gKwl9Ow0KPiA+ICt9IF9fcGFja2VkOw0KPiA+ICsNCj4g PiArI2VuZGlmIC8qIF9fTVRLX0NBTV9JUElfSF9fICovDQo+ID4gZGlmZiAtLWdpdCBhL2RyaXZl cnMvbWVkaWEvcGxhdGZvcm0vbXRrLWlzcC9pc3BfNTAvY2FtL210a19jYW0tcmVncy5oIGIvZHJp dmVycy9tZWRpYS9wbGF0Zm9ybS9tdGstaXNwL2lzcF81MC9jYW0vbXRrX2NhbS1yZWdzLmgNCj4g PiBuZXcgZmlsZSBtb2RlIDEwMDY0NA0KPiA+IGluZGV4IDAwMDAwMDAwMDAwMC4uYWIyMjc3ZjQ1 ZmE0DQo+ID4gLS0tIC9kZXYvbnVsbA0KPiA+ICsrKyBiL2RyaXZlcnMvbWVkaWEvcGxhdGZvcm0v bXRrLWlzcC9pc3BfNTAvY2FtL210a19jYW0tcmVncy5oDQo+ID4gQEAgLTAsMCArMSw5NSBAQA0K PiA+ICsvKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogR1BMLTIuMCAqLw0KPiA+ICsvKg0KPiA+ ICsgKiBDb3B5cmlnaHQgKGMpIDIwMTkgTWVkaWFUZWsgSW5jLg0KPiA+ICsgKi8NCj4gPiArDQo+ ID4gKyNpZm5kZWYgX19NVEtfQ0FNX1JFR1NfSF9fDQo+ID4gKyNkZWZpbmUgX19NVEtfQ0FNX1JF R1NfSF9fDQo+ID4gKw0KPiA+ICsvKiBJU1AgaW50ZXJydXB0IGVuYWJsZSAqLw0KPiA+ICsjZGVm aW5lIFJFR19DVExfUkFXX0lOVF9FTgkJMHgwMDIwDQo+ID4gKyNkZWZpbmUgRE1BX0VSUl9JTlRf RU4JCQlCSVQoMjkpDQo+ID4gKw0KPiA+ICsvKiBJU1AgaW50ZXJydXB0IHN0YXR1cyAqLw0KPiA+ ICsjZGVmaW5lIFJFR19DVExfUkFXX0lOVF9TVEFUCQkweDAwMjQNCj4gPiArI2RlZmluZSBWU19J TlRfU1QJCQlCSVQoMCkNCj4gPiArI2RlZmluZSBUR19FUlJfU1QJCQlCSVQoNCkNCj4gPiArI2Rl ZmluZSBUR19HQkVSUl9TVAkJCUJJVCg1KQ0KPiA+ICsjZGVmaW5lIENRX0NPREVfRVJSX1NUCQkJ QklUKDYpDQo+ID4gKyNkZWZpbmUgQ1FfQVBCX0VSUl9TVAkJCUJJVCg3KQ0KPiA+ICsjZGVmaW5l IENRX1ZTX0VSUl9TVAkJCUJJVCg4KQ0KPiA+ICsjZGVmaW5lIEhXX1BBU1MxX0RPTl9TVAkJCUJJ VCgxMSkNCj4gPiArI2RlZmluZSBTT0ZfSU5UX1NUCQkJQklUKDEyKQ0KPiA+ICsjZGVmaW5lIEFN WF9FUlJfU1QJCQlCSVQoMTUpDQo+ID4gKyNkZWZpbmUgUk1YX0VSUl9TVAkJCUJJVCgxNikNCj4g PiArI2RlZmluZSBCTVhfRVJSX1NUCQkJQklUKDE3KQ0KPiA+ICsjZGVmaW5lIFJSWk9fRVJSX1NU CQkJQklUKDE4KQ0KPiA+ICsjZGVmaW5lIEFGT19FUlJfU1QJCQlCSVQoMTkpDQo+ID4gKyNkZWZp bmUgSU1HT19FUlJfU1QJCQlCSVQoMjApDQo+ID4gKyNkZWZpbmUgQUFPX0VSUl9TVAkJCUJJVCgy MSkNCj4gPiArI2RlZmluZSBQU09fRVJSX1NUCQkJQklUKDIyKQ0KPiA+ICsjZGVmaW5lIExDU09f RVJSX1NUCQkJQklUKDIzKQ0KPiA+ICsjZGVmaW5lIEJOUl9FUlJfU1QJCQlCSVQoMjQpDQo+ID4g KyNkZWZpbmUgTFNDSV9FUlJfU1QJCQlCSVQoMjUpDQo+ID4gKyNkZWZpbmUgRE1BX0VSUl9TVAkJ CUJJVCgyOSkNCj4gPiArI2RlZmluZSBTV19QQVNTMV9ET05fU1QJCQlCSVQoMzApDQo+ID4gKw0K PiA+ICsvKiBJU1AgaW50ZXJydXB0IDIgc3RhdHVzICovDQo+ID4gKyNkZWZpbmUgUkVHX0NUTF9S QVdfSU5UMl9TVEFUCQkweDAwMzQNCj4gPiArI2RlZmluZSBBRk9fRE9ORV9TVAkJCUJJVCg1KQ0K PiA+ICsjZGVmaW5lIEFBT19ET05FX1NUCQkJQklUKDcpDQo+ID4gKw0KPiA+ICsvKiBDb25maWd1 cmVzIHNlbnNvciBtb2RlICovDQo+ID4gKyNkZWZpbmUgUkVHX1RHX1NFTl9NT0RFCQkJMHgwMjMw DQo+ID4gKyNkZWZpbmUgVEdfU0VOX01PREVfQ01PU19FTgkJQklUKDApDQo+ID4gKw0KPiA+ICsv KiBWaWV3IGZpbmRlciBtb2RlIGNvbnRyb2wgKi8NCj4gPiArI2RlZmluZSBSRUdfVEdfVkZfQ09O CQkJMHgwMjM0DQo+ID4gKyNkZWZpbmUgVEdfVkZfQ09OX1ZGREFUQV9FTgkJQklUKDApDQo+ID4g Kw0KPiA+ICsvKiBWaWV3IGZpbmRlciBtb2RlIGNvbnRyb2wgKi8NCj4gPiArI2RlZmluZSBSRUdf VEdfSU5URVJfU1QJCQkweDAyNmMNCj4gPiArI2RlZmluZSBUR19DU19NQVNLCQkJMHgzZjAwDQo+ ID4gKyNkZWZpbmUgVEdfSURMRV9TVAkJCUJJVCg4KQ0KPiA+ICsNCj4gPiArLyogSU1HTyBlcnJv ciBzdGF0dXMgcmVnaXN0ZXIgKi8NCj4gPiArI2RlZmluZSBSRUdfSU1HT19FUlJfU1RBVAkJMHgx MzYwDQo+ID4gKy8qIFJSWk8gZXJyb3Igc3RhdHVzIHJlZ2lzdGVyICovDQo+ID4gKyNkZWZpbmUg UkVHX1JSWk9fRVJSX1NUQVQJCTB4MTM2NA0KPiA+ICsvKiBBQU8gZXJyb3Igc3RhdHVzIHJlZ2lz dGVyICovDQo+ID4gKyNkZWZpbmUgUkVHX0FBT19FUlJfU1RBVAkJMHgxMzY4DQo+ID4gKy8qIEFG TyBlcnJvciBzdGF0dXMgcmVnaXN0ZXIgKi8NCj4gPiArI2RlZmluZSBSRUdfQUZPX0VSUl9TVEFU CQkweDEzNmMNCj4gPiArLyogTENTTyBlcnJvciBzdGF0dXMgcmVnaXN0ZXIgKi8NCj4gPiArI2Rl ZmluZSBSRUdfTENTT19FUlJfU1RBVAkJMHgxMzcwDQo+ID4gKy8qIEJQQ0kgZXJyb3Igc3RhdHVz IHJlZ2lzdGVyICovDQo+ID4gKyNkZWZpbmUgUkVHX0JQQ0lfRVJSX1NUQVQJCTB4MTM3Yw0KPiA+ ICsvKiBMU0NJIGVycm9yIHN0YXR1cyByZWdpc3RlciAqLw0KPiA+ICsjZGVmaW5lIFJFR19MU0NJ X0VSUl9TVEFUCQkweDEzODQNCj4gPiArLyogTE1WTyBlcnJvciBzdGF0dXMgcmVnaXN0ZXIgKi8N Cj4gPiArI2RlZmluZSBSRUdfTE1WT19FUlJfU1RBVAkJMHgxMzkwDQo+ID4gKy8qIEZMS08gZXJy b3Igc3RhdHVzIHJlZ2lzdGVyICovDQo+ID4gKyNkZWZpbmUgUkVHX0ZMS09fRVJSX1NUQVQJCTB4 MTM5NA0KPiA+ICsvKiBQU08gZXJyb3Igc3RhdHVzIHJlZ2lzdGVyICovDQo+ID4gKyNkZWZpbmUg UkVHX1BTT19FUlJfU1RBVAkJMHgxM2EwDQo+ID4gKw0KPiA+ICsvKiBDUTAgYmFzZSBhZGRyZXNz ICovDQo+ID4gKyNkZWZpbmUgUkVHX0NRX1RIUjBfQkFTRUFERFIJCTB4MDE5OA0KPiA+ICsvKiBG cmFtZSBzZXF1ZW5jZSBudW1iZXIgKi8NCj4gPiArI2RlZmluZSBSRUdfRlJBTUVfU0VRX05VTQkJ MHgxM2I4DQo+ID4gKw0KPiA+ICsvKiBJUlEgRXJyb3IgTWFzayAqLw0KPiA+ICsjZGVmaW5lIElO VF9TVF9NQVNLX0NBTV9FUlIJCSggXA0KPiA+ICsJCQkJCVRHX0VSUl9TVCB8XA0KPiA+ICsJCQkJ CVRHX0dCRVJSX1NUIHxcDQo+ID4gKwkJCQkJQ1FfQ09ERV9FUlJfU1QgfFwNCj4gPiArCQkJCQlD UV9BUEJfRVJSX1NUIHxcDQo+ID4gKwkJCQkJQ1FfVlNfRVJSX1NUIHxcDQo+ID4gKwkJCQkJQk5S X0VSUl9TVCB8XA0KPiA+ICsJCQkJCVJNWF9FUlJfU1QgfFwNCj4gPiArCQkJCQlCTVhfRVJSX1NU IHxcDQo+ID4gKwkJCQkJQk5SX0VSUl9TVCB8XA0KPiA+ICsJCQkJCUxTQ0lfRVJSX1NUIHxcDQo+ ID4gKwkJCQkJRE1BX0VSUl9TVCkNCj4gPiArDQo+IA0KPiBJIHdvdWxkIGFkZCBhIGNvbW1vbiBw cmVmaXggYWxsIHRoZSByZWdpc3RlcnMgaW4gdGhlIGZpbGUuDQo+IA0KPiBBbHNvLCBhZGQgc29t ZSBkb2NzIHRvIGtub3cgd2hhdCB0aG9zZSBhY3JvbnltcyBtZWFucyB3b3VsZCBiZSBuaWNlLg0K PiANCg0KT2ssIGFkZCB0aGlzIGluIG5leHQgcGF0Y2guDQoNCg0KPiA+ICsjZW5kaWYJLyogX19N VEtfQ0FNX1JFR1NfSF9fICovDQo+ID4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvbWVkaWEvcGxhdGZv cm0vbXRrLWlzcC9pc3BfNTAvY2FtL210a19jYW0uYyBiL2RyaXZlcnMvbWVkaWEvcGxhdGZvcm0v bXRrLWlzcC9pc3BfNTAvY2FtL210a19jYW0uYw0KPiA+IG5ldyBmaWxlIG1vZGUgMTAwNjQ0DQo+ ID4gaW5kZXggMDAwMDAwMDAwMDAwLi4yM2ZkYjhiNGFiYzUNCj4gPiAtLS0gL2Rldi9udWxsDQo+ ID4gKysrIGIvZHJpdmVycy9tZWRpYS9wbGF0Zm9ybS9tdGstaXNwL2lzcF81MC9jYW0vbXRrX2Nh bS5jDQo+ID4gQEAgLTAsMCArMSwyMDg3IEBADQo+ID4gKy8vIFNQRFgtTGljZW5zZS1JZGVudGlm aWVyOiBHUEwtMi4wDQo+ID4gKy8vIENvcHlyaWdodCAoYykgMjAxOSBNZWRpYVRlayBJbmMuDQo+ ID4gKw0KPiA+ICsjaW5jbHVkZSA8bGludXgvZGV2aWNlLmg+DQo+ID4gKyNpbmNsdWRlIDxsaW51 eC9kbWEtbWFwcGluZy5oPg0KPiA+ICsjaW5jbHVkZSA8bGludXgvb2YuaD4NCj4gPiArI2luY2x1 ZGUgPGxpbnV4L29mX2dyYXBoLmg+DQo+ID4gKyNpbmNsdWRlIDxsaW51eC9vZl9wbGF0Zm9ybS5o Pg0KPiA+ICsjaW5jbHVkZSA8bGludXgvbW9kdWxlLmg+DQo+ID4gKyNpbmNsdWRlIDxsaW51eC9w bGF0Zm9ybV9kZXZpY2UuaD4NCj4gPiArI2luY2x1ZGUgPGxpbnV4L3BtX3J1bnRpbWUuaD4NCj4g PiArI2luY2x1ZGUgPGxpbnV4L3ZpZGVvZGV2Mi5oPg0KPiA+ICsjaW5jbHVkZSA8bWVkaWEvbWVk aWEtZW50aXR5Lmg+DQo+ID4gKyNpbmNsdWRlIDxtZWRpYS92NGwyLWFzeW5jLmg+DQo+ID4gKyNp bmNsdWRlIDxtZWRpYS92NGwyLWNvbW1vbi5oPg0KPiA+ICsjaW5jbHVkZSA8bWVkaWEvdjRsMi1l dmVudC5oPg0KPiA+ICsjaW5jbHVkZSA8bWVkaWEvdjRsMi1md25vZGUuaD4NCj4gPiArI2luY2x1 ZGUgPG1lZGlhL3Y0bDItaW9jdGwuaD4NCj4gPiArI2luY2x1ZGUgPG1lZGlhL3Y0bDItbWMuaD4N Cj4gPiArI2luY2x1ZGUgPG1lZGlhL3Y0bDItc3ViZGV2Lmg+DQo+ID4gKyNpbmNsdWRlIDxtZWRp YS92aWRlb2J1ZjItZG1hLWNvbnRpZy5oPg0KPiANCj4gUGxlYXNlIHNvcnQgaW4gYWxwaGFiZXRp Y2FsIG9yZGVyLg0KPiANCg0KRml4IGluIG5leHQgcGF0Y2gNCg0KPiA+ICsNCj4gPiArI2luY2x1 ZGUgIm10a19jYW0uaCINCj4gPiArI2luY2x1ZGUgIm10a19jYW0taHcuaCINCj4gPiArDQo+ID4g KyNkZWZpbmUgUl9JTUdPCQlCSVQoMCkNCj4gPiArI2RlZmluZSBSX1JSWk8JCUJJVCgxKQ0KPiA+ ICsjZGVmaW5lIFJfQUFPCQlCSVQoMykNCj4gPiArI2RlZmluZSBSX0FGTwkJQklUKDQpDQo+ID4g KyNkZWZpbmUgUl9MQ1NPCQlCSVQoNSkNCj4gPiArI2RlZmluZSBSX0xNVk8JCUJJVCg3KQ0KPiA+ ICsjZGVmaW5lIFJfRkxLTwkJQklUKDgpDQo+ID4gKyNkZWZpbmUgUl9QU08JCUJJVCgxMCkNCj4g DQo+IEl0IHdvdWxkIGJlIG5pY2UgdG8gaGF2ZSBiZXR0ZXIgbmFtZXMgb2YgZG9jcyBvZiB3aGF0 IHRoZXNlIG1lYW5zLg0KPiANCg0KQWRkIGluIG5leHQgcGF0Y2gNCg0KPiA+ICsNCj4gPiArI2Rl ZmluZSBNVEtfSVNQX09ORV9QSVhFTF9NT0RFCQkxDQo+ID4gKyNkZWZpbmUgTVRLX0lTUF9NSU5f UkVTSVpFX1JBVElPCTYNCj4gPiArI2RlZmluZSBNVEtfSVNQX01BWF9SVU5OSU5HX0pPQlMJMw0K PiA+ICsNCj4gPiArI2RlZmluZSBNVEtfQ0FNX0NJT19QQURfU1JDCQk0DQo+ID4gKyNkZWZpbmUg TVRLX0NBTV9DSU9fUEFEX1NJTksJCTExDQo+ID4gKw0KPiA+ICtzdGF0aWMgaW5saW5lIHN0cnVj dCBtdGtfY2FtX3ZpZGVvX2RldmljZSAqDQo+ID4gK2ZpbGVfdG9fbXRrX2NhbV9ub2RlKHN0cnVj dCBmaWxlICpfX2ZpbGUpDQo+ID4gK3sNCj4gPiArCXJldHVybiBjb250YWluZXJfb2YodmlkZW9f ZGV2ZGF0YShfX2ZpbGUpLA0KPiA+ICsJCXN0cnVjdCBtdGtfY2FtX3ZpZGVvX2RldmljZSwgdmRl dik7DQo+ID4gK30NCj4gPiArDQo+ID4gK3N0YXRpYyBpbmxpbmUgc3RydWN0IG10a19jYW1fdmlk ZW9fZGV2aWNlICoNCj4gPiArbXRrX2NhbV92YnFfdG9fdmRldihzdHJ1Y3QgdmIyX3F1ZXVlICpf X3ZxKQ0KPiANCj4gbm8gbmVlZCBmb3IgdGhlIHVuZGVyc2NvcmUgaW4gX192cQ0KPiANCg0KUmV2 aXNlIGluIG5leHQgcGF0Y2gNCg0KPiA+ICt7DQo+ID4gKwlyZXR1cm4gY29udGFpbmVyX29mKF9f dnEsIHN0cnVjdCBtdGtfY2FtX3ZpZGVvX2RldmljZSwgdmJxKTsNCj4gPiArfQ0KPiA+ICsNCj4g PiArc3RhdGljIGlubGluZSBzdHJ1Y3QgbXRrX2NhbV9kZXZfcmVxdWVzdCAqDQo+ID4gK210a19j YW1fcmVxX3RvX2Rldl9yZXEoc3RydWN0IG1lZGlhX3JlcXVlc3QgKl9fcmVxKQ0KPiA+ICt7DQo+ ID4gKwlyZXR1cm4gY29udGFpbmVyX29mKF9fcmVxLCBzdHJ1Y3QgbXRrX2NhbV9kZXZfcmVxdWVz dCwgcmVxKTsNCj4gPiArfQ0KPiA+ICsNCj4gPiArc3RhdGljIGlubGluZSBzdHJ1Y3QgbXRrX2Nh bV9kZXZfYnVmZmVyICoNCj4gPiArbXRrX2NhbV92YjJfYnVmX3RvX2Rldl9idWYoc3RydWN0IHZi Ml9idWZmZXIgKl9fdmIpDQo+ID4gK3sNCj4gPiArCXJldHVybiBjb250YWluZXJfb2YoX192Yiwg c3RydWN0IG10a19jYW1fZGV2X2J1ZmZlciwgdmJiLnZiMl9idWYpOw0KPiA+ICt9DQo+ID4gKw0K PiA+ICtzdGF0aWMgdm9pZCBtdGtfY2FtX2Rldl9qb2JfZG9uZShzdHJ1Y3QgbXRrX2NhbV9kZXYg KmNhbSwNCj4gPiArCQkJCSBzdHJ1Y3QgbXRrX2NhbV9kZXZfcmVxdWVzdCAqcmVxLA0KPiA+ICsJ CQkJIGVudW0gdmIyX2J1ZmZlcl9zdGF0ZSBzdGF0ZSkNCj4gPiArew0KPiA+ICsJc3RydWN0IG1l ZGlhX3JlcXVlc3Rfb2JqZWN0ICpvYmosICpvYmpfcHJldjsNCj4gPiArCXVuc2lnbmVkIGxvbmcg ZmxhZ3M7DQo+ID4gKwl1NjQgdHNfZW9mID0ga3RpbWVfZ2V0X2Jvb3R0aW1lX25zKCk7DQo+ID4g Kw0KPiA+ICsJaWYgKCFjYW0tPnN0cmVhbWluZykNCj4gDQo+IHMvc3RyZWFtaW5nL2lzX3N0cmVh bWluZw0KPiANCj4gdGhpcyBtYWtlcyBhIGJpdCBtb3JlIGludHVpdGl2ZSBvZiB3aGF0IHRoZSB0 aGUgYm9vbGVhbiBtZWFucy4NCj4gDQoNClJldmlzZSBpbiBuZXh0IHBhdGNoDQoNCj4gPiArCQly ZXR1cm47DQo+ID4gKw0KPiA+ICsJZGV2X2RiZyhjYW0tPmRldiwgImpvYiBkb25lIHJlcXVlc3Q6 JXMgZnJhbWVfc2VxOiVkIHN0YXRlOiVkXG4iLA0KPiA+ICsJCXJlcS0+cmVxLmRlYnVnX3N0ciwg cmVxLT5mcmFtZV9wYXJhbXMuZnJhbWVfc2VxX25vLCBzdGF0ZSk7DQo+ID4gKw0KPiA+ICsJbGlz dF9mb3JfZWFjaF9lbnRyeV9zYWZlKG9iaiwgb2JqX3ByZXYsICZyZXEtPnJlcS5vYmplY3RzLCBs aXN0KSB7DQo+ID4gKwkJc3RydWN0IHZiMl9idWZmZXIgKnZiOw0KPiA+ICsJCXN0cnVjdCBtdGtf Y2FtX2Rldl9idWZmZXIgKmJ1ZjsNCj4gPiArCQlzdHJ1Y3QgbXRrX2NhbV92aWRlb19kZXZpY2Ug Km5vZGU7DQo+ID4gKw0KPiA+ICsJCWlmICghdmIyX3JlcXVlc3Rfb2JqZWN0X2lzX2J1ZmZlcihv YmopKQ0KPiA+ICsJCQljb250aW51ZTsNCj4gPiArCQl2YiA9IGNvbnRhaW5lcl9vZihvYmosIHN0 cnVjdCB2YjJfYnVmZmVyLCByZXFfb2JqKTsNCj4gPiArCQlidWYgPSBtdGtfY2FtX3ZiMl9idWZf dG9fZGV2X2J1Zih2Yik7DQo+ID4gKwkJbm9kZSA9IG10a19jYW1fdmJxX3RvX3ZkZXYodmItPnZi Ml9xdWV1ZSk7DQo+ID4gKwkJc3Bpbl9sb2NrX2lycXNhdmUoJm5vZGUtPmJ1Zl9saXN0X2xvY2ss IGZsYWdzKTsNCj4gPiArCQlsaXN0X2RlbCgmYnVmLT5saXN0KTsNCj4gPiArCQlzcGluX3VubG9j a19pcnFyZXN0b3JlKCZub2RlLT5idWZfbGlzdF9sb2NrLCBmbGFncyk7DQo+ID4gKwkJYnVmLT52 YmIuc2VxdWVuY2UgPSByZXEtPmZyYW1lX3BhcmFtcy5mcmFtZV9zZXFfbm87DQo+ID4gKwkJaWYg KFY0TDJfVFlQRV9JU19PVVRQVVQodmItPnZiMl9xdWV1ZS0+dHlwZSkpDQo+ID4gKwkJCXZiLT50 aW1lc3RhbXAgPSB0c19lb2Y7DQo+ID4gKwkJZWxzZQ0KPiA+ICsJCQl2Yi0+dGltZXN0YW1wID0g cmVxLT50aW1lc3RhbXA7DQo+ID4gKwkJdmIyX2J1ZmZlcl9kb25lKCZidWYtPnZiYi52YjJfYnVm LCBzdGF0ZSk7DQo+ID4gKwl9DQo+ID4gK30NCj4gPiArDQo+ID4gK3N0cnVjdCBtdGtfY2FtX2Rl dl9yZXF1ZXN0ICptdGtfY2FtX2Rldl9nZXRfcmVxKHN0cnVjdCBtdGtfY2FtX2RldiAqY2FtLA0K PiA+ICsJCQkJCQl1bnNpZ25lZCBpbnQgZnJhbWVfc2VxX25vKQ0KPiA+ICt7DQo+ID4gKwlzdHJ1 Y3QgbXRrX2NhbV9kZXZfcmVxdWVzdCAqcmVxLCAqcmVxX3ByZXY7DQo+ID4gKwl1bnNpZ25lZCBs b25nIGZsYWdzOw0KPiA+ICsNCj4gPiArCXNwaW5fbG9ja19pcnFzYXZlKCZjYW0tPnJ1bm5pbmdf am9iX2xvY2ssIGZsYWdzKTsNCj4gPiArCWxpc3RfZm9yX2VhY2hfZW50cnlfc2FmZShyZXEsIHJl cV9wcmV2LCAmY2FtLT5ydW5uaW5nX2pvYl9saXN0LCBsaXN0KSB7DQo+ID4gKwkJZGV2X2RiZyhj YW0tPmRldiwgImZyYW1lX3NlcTolZCwgZ2V0IGZyYW1lX3NlcTolZFxuIiwNCj4gPiArCQkJcmVx LT5mcmFtZV9wYXJhbXMuZnJhbWVfc2VxX25vLCBmcmFtZV9zZXFfbm8pOw0KPiA+ICsNCj4gPiAr CQkvKiBNYXRjaCBieSB0aGUgZW4tcXVldWVkIHJlcXVlc3QgbnVtYmVyICovDQo+ID4gKwkJaWYg KHJlcS0+ZnJhbWVfcGFyYW1zLmZyYW1lX3NlcV9ubyA9PSBmcmFtZV9zZXFfbm8pIHsNCj4gPiAr CQkJc3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmY2FtLT5ydW5uaW5nX2pvYl9sb2NrLCBmbGFncyk7 DQo+ID4gKwkJCXJldHVybiByZXE7DQo+ID4gKwkJfQ0KPiA+ICsJfQ0KPiA+ICsJc3Bpbl91bmxv Y2tfaXJxcmVzdG9yZSgmY2FtLT5ydW5uaW5nX2pvYl9sb2NrLCBmbGFncyk7DQo+ID4gKw0KPiA+ ICsJcmV0dXJuIE5VTEw7DQo+ID4gK30NCj4gPiArDQo+ID4gK3ZvaWQgbXRrX2NhbV9kZXZfZGVx dWV1ZV9yZXFfZnJhbWUoc3RydWN0IG10a19jYW1fZGV2ICpjYW0sDQo+ID4gKwkJCQkgICB1bnNp Z25lZCBpbnQgZnJhbWVfc2VxX25vKQ0KPiA+ICt7DQo+ID4gKwlzdHJ1Y3QgbXRrX2NhbV9kZXZf cmVxdWVzdCAqcmVxLCAqcmVxX3ByZXY7DQo+ID4gKwl1bnNpZ25lZCBsb25nIGZsYWdzOw0KPiA+ ICsNCj4gPiArCXNwaW5fbG9ja19pcnFzYXZlKCZjYW0tPnJ1bm5pbmdfam9iX2xvY2ssIGZsYWdz KTsNCj4gPiArCWxpc3RfZm9yX2VhY2hfZW50cnlfc2FmZShyZXEsIHJlcV9wcmV2LCAmY2FtLT5y dW5uaW5nX2pvYl9saXN0LCBsaXN0KSB7DQo+ID4gKwkJZGV2X2RiZyhjYW0tPmRldiwgImZyYW1l X3NlcTolZCwgZGUtcXVldWUgZnJhbWVfc2VxOiVkXG4iLA0KPiA+ICsJCQlyZXEtPmZyYW1lX3Bh cmFtcy5mcmFtZV9zZXFfbm8sIGZyYW1lX3NlcV9ubyk7DQo+ID4gKw0KPiA+ICsJCS8qIE1hdGNo IGJ5IHRoZSBlbi1xdWV1ZWQgcmVxdWVzdCBudW1iZXIgKi8NCj4gPiArCQlpZiAocmVxLT5mcmFt ZV9wYXJhbXMuZnJhbWVfc2VxX25vID09IGZyYW1lX3NlcV9ubykgew0KPiA+ICsJCQljYW0tPnJ1 bm5pbmdfam9iX2NvdW50LS07DQo+ID4gKwkJCS8qIFBhc3MgdG8gdXNlciBzcGFjZSAqLw0KPiA+ ICsJCQltdGtfY2FtX2Rldl9qb2JfZG9uZShjYW0sIHJlcSwgVkIyX0JVRl9TVEFURV9ET05FKTsN Cj4gPiArCQkJbGlzdF9kZWwoJnJlcS0+bGlzdCk7DQo+ID4gKwkJCWJyZWFrOw0KPiA+ICsJCX0g ZWxzZSBpZiAocmVxLT5mcmFtZV9wYXJhbXMuZnJhbWVfc2VxX25vIDwgZnJhbWVfc2VxX25vKSB7 DQo+ID4gKwkJCWNhbS0+cnVubmluZ19qb2JfY291bnQtLTsNCj4gPiArCQkJLyogUGFzcyB0byB1 c2VyIHNwYWNlIGZvciBmcmFtZSBkcm9wICovDQo+ID4gKwkJCW10a19jYW1fZGV2X2pvYl9kb25l KGNhbSwgcmVxLCBWQjJfQlVGX1NUQVRFX0VSUk9SKTsNCj4gPiArCQkJZGV2X3dhcm4oY2FtLT5k ZXYsICJmcmFtZV9zZXE6JWQgZHJvcFxuIiwNCj4gPiArCQkJCSByZXEtPmZyYW1lX3BhcmFtcy5m cmFtZV9zZXFfbm8pOw0KPiANCj4gbWF5YmUgYSBjb3VudGVyIGluIGRlYnVnZnMgaW5zdGVhZCBv ZiB0aGUgd2FybmluZy4NCj4gDQoNCkRvIHlvdSBtZWFuIHRvIGFkZCBjb3VudGVyIHRvIGFjY3Vt dWxhdGUgdGhlIHRvdGFsIGNvdW50IG9mIGRyb3AgZnJhbWVzPw0KQ291bGQgd2UgYWRkIHRoaXMg YW5kIGFsc28ga2VlcCB0aGlzIHdhcm5pbmcgbWVzc2FnZT8NCg0KPiA+ICsJCQlsaXN0X2RlbCgm cmVxLT5saXN0KTsNCj4gPiArCQl9IGVsc2Ugew0KPiA+ICsJCQlicmVhazsNCj4gPiArCQl9DQo+ ID4gKwl9DQo+ID4gKwlzcGluX3VubG9ja19pcnFyZXN0b3JlKCZjYW0tPnJ1bm5pbmdfam9iX2xv Y2ssIGZsYWdzKTsNCj4gPiArfQ0KPiA+ICsNCj4gPiArc3RhdGljIHZvaWQgbXRrX2NhbV9kZXZf cmVxX2NsZWFudXAoc3RydWN0IG10a19jYW1fZGV2ICpjYW0pDQo+ID4gK3sNCj4gPiArCXN0cnVj dCBtdGtfY2FtX2Rldl9yZXF1ZXN0ICpyZXEsICpyZXFfcHJldjsNCj4gPiArCXVuc2lnbmVkIGxv bmcgZmxhZ3M7DQo+ID4gKw0KPiA+ICsJZGV2X2RiZyhjYW0tPmRldiwgIiVzXG4iLCBfX2Z1bmNf Xyk7DQo+ID4gKw0KPiA+ICsJc3Bpbl9sb2NrX2lycXNhdmUoJmNhbS0+cGVuZGluZ19qb2JfbG9j aywgZmxhZ3MpOw0KPiA+ICsJbGlzdF9mb3JfZWFjaF9lbnRyeV9zYWZlKHJlcSwgcmVxX3ByZXYs ICZjYW0tPnBlbmRpbmdfam9iX2xpc3QsIGxpc3QpDQo+ID4gKwkJbGlzdF9kZWwoJnJlcS0+bGlz dCk7DQo+ID4gKwlzcGluX3VubG9ja19pcnFyZXN0b3JlKCZjYW0tPnBlbmRpbmdfam9iX2xvY2ss IGZsYWdzKTsNCj4gPiArDQo+ID4gKwlzcGluX2xvY2tfaXJxc2F2ZSgmY2FtLT5ydW5uaW5nX2pv Yl9sb2NrLCBmbGFncyk7DQo+ID4gKwlsaXN0X2Zvcl9lYWNoX2VudHJ5X3NhZmUocmVxLCByZXFf cHJldiwgJmNhbS0+cnVubmluZ19qb2JfbGlzdCwgbGlzdCkNCj4gPiArCQlsaXN0X2RlbCgmcmVx LT5saXN0KTsNCj4gPiArCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJmNhbS0+cnVubmluZ19qb2Jf bG9jaywgZmxhZ3MpOw0KPiA+ICt9DQo+ID4gKw0KPiA+ICt2b2lkIG10a19jYW1fZGV2X3JlcV90 cnlfcXVldWUoc3RydWN0IG10a19jYW1fZGV2ICpjYW0pDQo+ID4gK3sNCj4gPiArCXN0cnVjdCBt dGtfY2FtX2Rldl9yZXF1ZXN0ICpyZXEsICpyZXFfcHJldjsNCj4gPiArCXVuc2lnbmVkIGxvbmcg ZmxhZ3M7DQo+ID4gKw0KPiA+ICsJaWYgKCFjYW0tPnN0cmVhbWluZykgew0KPiA+ICsJCWRldl9k YmcoY2FtLT5kZXYsICJzdHJlYW0gaXMgb2ZmXG4iKTsNCj4gPiArCQlyZXR1cm47DQo+ID4gKwl9 DQo+ID4gKw0KPiA+ICsJc3Bpbl9sb2NrX2lycXNhdmUoJmNhbS0+cGVuZGluZ19qb2JfbG9jaywg ZmxhZ3MpOw0KPiA+ICsJc3Bpbl9sb2NrX2lycXNhdmUoJmNhbS0+cnVubmluZ19qb2JfbG9jaywg ZmxhZ3MpOw0KPiA+ICsJbGlzdF9mb3JfZWFjaF9lbnRyeV9zYWZlKHJlcSwgcmVxX3ByZXYsICZj YW0tPnBlbmRpbmdfam9iX2xpc3QsIGxpc3QpIHsNCj4gPiArCQlpZiAoY2FtLT5ydW5uaW5nX2pv Yl9jb3VudCA+PSBNVEtfSVNQX01BWF9SVU5OSU5HX0pPQlMpIHsNCj4gPiArCQkJZGV2X2RiZyhj YW0tPmRldiwgImpvYnMgYXJlIGZ1bGxcbiIpOw0KPiA+ICsJCQlicmVhazsNCj4gPiArCQl9DQo+ ID4gKwkJY2FtLT5ydW5uaW5nX2pvYl9jb3VudCsrOw0KPiA+ICsJCWxpc3RfZGVsKCZyZXEtPmxp c3QpOw0KPiA+ICsJCWxpc3RfYWRkX3RhaWwoJnJlcS0+bGlzdCwgJmNhbS0+cnVubmluZ19qb2Jf bGlzdCk7DQo+IA0KPiBsaXN0X21vdmVfdGFpbCgpIGNhbiBiZSB1c2VkLg0KPiANCg0KUmV2aXNl ZCBpbiB0aGlzIHBhdGNoLg0KDQo+ID4gKwkJbXRrX2lzcF9yZXFfZW5xdWV1ZShjYW0sIHJlcSk7 DQo+ID4gKwl9DQo+ID4gKwlzcGluX3VubG9ja19pcnFyZXN0b3JlKCZjYW0tPnJ1bm5pbmdfam9i X2xvY2ssIGZsYWdzKTsNCj4gPiArCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJmNhbS0+cGVuZGlu Z19qb2JfbG9jaywgZmxhZ3MpOw0KPiA+ICt9DQo+ID4gKw0KPiA+ICtzdGF0aWMgc3RydWN0IG1l ZGlhX3JlcXVlc3QgKm10a19jYW1fcmVxX2FsbG9jKHN0cnVjdCBtZWRpYV9kZXZpY2UgKm1kZXYp DQo+ID4gK3sNCj4gPiArCXN0cnVjdCBtdGtfY2FtX2Rldl9yZXF1ZXN0ICpjYW1fZGV2X3JlcTsN Cj4gPiArDQo+ID4gKwljYW1fZGV2X3JlcSA9IGt6YWxsb2Moc2l6ZW9mKCpjYW1fZGV2X3JlcSks IEdGUF9LRVJORUwpOw0KPiA+ICsNCj4gPiArCXJldHVybiAmY2FtX2Rldl9yZXEtPnJlcTsNCj4g PiArfQ0KPiA+ICsNCj4gPiArc3RhdGljIHZvaWQgbXRrX2NhbV9yZXFfZnJlZShzdHJ1Y3QgbWVk aWFfcmVxdWVzdCAqcmVxKQ0KPiA+ICt7DQo+ID4gKwlzdHJ1Y3QgbXRrX2NhbV9kZXZfcmVxdWVz dCAqY2FtX2Rldl9yZXEgPSBtdGtfY2FtX3JlcV90b19kZXZfcmVxKHJlcSk7DQo+ID4gKw0KPiA+ ICsJa2ZyZWUoY2FtX2Rldl9yZXEpOw0KPiA+ICt9DQo+ID4gKw0KPiA+ICtzdGF0aWMgdm9pZCBt dGtfY2FtX3JlcV9xdWV1ZShzdHJ1Y3QgbWVkaWFfcmVxdWVzdCAqcmVxKQ0KPiA+ICt7DQo+ID4g KwlzdHJ1Y3QgbXRrX2NhbV9kZXZfcmVxdWVzdCAqY2FtX3JlcSA9IG10a19jYW1fcmVxX3RvX2Rl dl9yZXEocmVxKTsNCj4gPiArCXN0cnVjdCBtdGtfY2FtX2RldiAqY2FtID0gY29udGFpbmVyX29m KHJlcS0+bWRldiwgc3RydWN0IG10a19jYW1fZGV2LA0KPiA+ICsJCQkJCSAgICAgICBtZWRpYV9k ZXYpOw0KPiA+ICsJdW5zaWduZWQgbG9uZyBmbGFnczsNCj4gPiArDQo+ID4gKwkvKiB1cGRhdGUg ZnJhbWVfcGFyYW1zJ3MgZG1hX2J1ZnMgaW4gbXRrX2NhbV92YjJfYnVmX3F1ZXVlICovDQo+ID4g Kwl2YjJfcmVxdWVzdF9xdWV1ZShyZXEpOw0KPiA+ICsNCj4gPiArCS8qIGFkZCB0byBwZW5kaW5n IGpvYiBsaXN0ICovDQo+ID4gKwlzcGluX2xvY2tfaXJxc2F2ZSgmY2FtLT5wZW5kaW5nX2pvYl9s b2NrLCBmbGFncyk7DQo+ID4gKwlsaXN0X2FkZF90YWlsKCZjYW1fcmVxLT5saXN0LCAmY2FtLT5w ZW5kaW5nX2pvYl9saXN0KTsNCj4gPiArCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJmNhbS0+cGVu ZGluZ19qb2JfbG9jaywgZmxhZ3MpOw0KPiA+ICsNCj4gPiArCW10a19jYW1fZGV2X3JlcV90cnlf cXVldWUoY2FtKTsNCj4gPiArfQ0KPiA+ICsNCj4gPiArc3RhdGljIHVuc2lnbmVkIGludCBnZXRf cGl4ZWxfYml0cyh1bnNpZ25lZCBpbnQgcGl4X2ZtdCkNCj4gPiArew0KPiA+ICsJc3dpdGNoIChw aXhfZm10KSB7DQo+ID4gKwljYXNlIFY0TDJfUElYX0ZNVF9NVElTUF9TQkdHUjg6DQo+ID4gKwlj YXNlIFY0TDJfUElYX0ZNVF9NVElTUF9TR0JSRzg6DQo+ID4gKwljYXNlIFY0TDJfUElYX0ZNVF9N VElTUF9TR1JCRzg6DQo+ID4gKwljYXNlIFY0TDJfUElYX0ZNVF9NVElTUF9TUkdHQjg6DQo+ID4g KwljYXNlIFY0TDJfUElYX0ZNVF9NVElTUF9TQkdHUjhGOg0KPiA+ICsJY2FzZSBWNEwyX1BJWF9G TVRfTVRJU1BfU0dCUkc4RjoNCj4gPiArCWNhc2UgVjRMMl9QSVhfRk1UX01USVNQX1NHUkJHOEY6 DQo+ID4gKwljYXNlIFY0TDJfUElYX0ZNVF9NVElTUF9TUkdHQjhGOg0KPiA+ICsJCXJldHVybiA4 Ow0KPiA+ICsJY2FzZSBWNEwyX1BJWF9GTVRfTVRJU1BfU0JHR1IxMDoNCj4gPiArCWNhc2UgVjRM Ml9QSVhfRk1UX01USVNQX1NHQlJHMTA6DQo+ID4gKwljYXNlIFY0TDJfUElYX0ZNVF9NVElTUF9T R1JCRzEwOg0KPiA+ICsJY2FzZSBWNEwyX1BJWF9GTVRfTVRJU1BfU1JHR0IxMDoNCj4gPiArCWNh c2UgVjRMMl9QSVhfRk1UX01USVNQX1NCR0dSMTBGOg0KPiA+ICsJY2FzZSBWNEwyX1BJWF9GTVRf TVRJU1BfU0dCUkcxMEY6DQo+ID4gKwljYXNlIFY0TDJfUElYX0ZNVF9NVElTUF9TR1JCRzEwRjoN Cj4gPiArCWNhc2UgVjRMMl9QSVhfRk1UX01USVNQX1NSR0dCMTBGOg0KPiA+ICsJCXJldHVybiAx MDsNCj4gPiArCWNhc2UgVjRMMl9QSVhfRk1UX01USVNQX1NCR0dSMTI6DQo+ID4gKwljYXNlIFY0 TDJfUElYX0ZNVF9NVElTUF9TR0JSRzEyOg0KPiA+ICsJY2FzZSBWNEwyX1BJWF9GTVRfTVRJU1Bf U0dSQkcxMjoNCj4gPiArCWNhc2UgVjRMMl9QSVhfRk1UX01USVNQX1NSR0dCMTI6DQo+ID4gKwlj YXNlIFY0TDJfUElYX0ZNVF9NVElTUF9TQkdHUjEyRjoNCj4gPiArCWNhc2UgVjRMMl9QSVhfRk1U X01USVNQX1NHQlJHMTJGOg0KPiA+ICsJY2FzZSBWNEwyX1BJWF9GTVRfTVRJU1BfU0dSQkcxMkY6 DQo+ID4gKwljYXNlIFY0TDJfUElYX0ZNVF9NVElTUF9TUkdHQjEyRjoNCj4gPiArCQlyZXR1cm4g MTI7DQo+ID4gKwljYXNlIFY0TDJfUElYX0ZNVF9NVElTUF9TQkdHUjE0Og0KPiA+ICsJY2FzZSBW NEwyX1BJWF9GTVRfTVRJU1BfU0dCUkcxNDoNCj4gPiArCWNhc2UgVjRMMl9QSVhfRk1UX01USVNQ X1NHUkJHMTQ6DQo+ID4gKwljYXNlIFY0TDJfUElYX0ZNVF9NVElTUF9TUkdHQjE0Og0KPiA+ICsJ Y2FzZSBWNEwyX1BJWF9GTVRfTVRJU1BfU0JHR1IxNEY6DQo+ID4gKwljYXNlIFY0TDJfUElYX0ZN VF9NVElTUF9TR0JSRzE0RjoNCj4gPiArCWNhc2UgVjRMMl9QSVhfRk1UX01USVNQX1NHUkJHMTRG Og0KPiA+ICsJY2FzZSBWNEwyX1BJWF9GTVRfTVRJU1BfU1JHR0IxNEY6DQo+ID4gKwkJcmV0dXJu IDE0Ow0KPiA+ICsJZGVmYXVsdDoNCj4gPiArCQlyZXR1cm4gMDsNCj4gPiArCX0NCj4gPiArfQ0K PiANCj4gd2hpY2ggcGF0Y2hzZXQgYXJlIHRoZXNlIHBpeGVsIGZvcm1hdHMgZGVmaW5lZD8NCj4g SSBjb3VsZG4ndCBmaW5kIHRoZW0gaW4gdGhlIG9uZXMgeW91IHBvaW50ZWQuDQo+IA0KPiBJIGFs c28gd29uZGVyIGlmIGFsbCBvZiB0aGVtIG5lZWQgdG8gYmUgZGVmaW5lZCwgb3IgaWYgdGhlIHBy ZS1kZWZpbmVkIG9uZXMgY2FuIGJlIHVzZWQsDQo+IHNvIHlvdSBjYW4gdXNlIHY0bDJfZm9ybWF0 X2luZm8oKSB0byBnZXQgdGhlIG51bWJlciBvZiBieXRlcy4NCj4gDQoNCkkgbWlzcyBzb21lIGZp bGVzIHJlbGF0ZWQgdG8gcGl4ZWwgZm9ybWF0IGRlZmluaXRpb24gaW4gdGhpcyBwYXRjaCBzZXQu DQpZb3UgY291bGQgcmVmZXIgdGhlIG9sZCBwYXRjaCBzZXQgZm9yIHBpeGVsIGZvcm1hdCBkZWZp bml0aW9uLg0KaHR0cHM6Ly9wYXRjaHdvcmsua2VybmVsLm9yZy9wYXRjaC8xMTEyNjA1NS8NCg0K PiA+ICsNCj4gPiArc3RhdGljIHZvaWQgY2FsX2ltYWdlX3BpeF9tcChzdHJ1Y3QgbXRrX2NhbV9k ZXYgKmNhbSwgdW5zaWduZWQgaW50IG5vZGVfaWQsDQo+ID4gKwkJCSAgICAgc3RydWN0IHY0bDJf cGl4X2Zvcm1hdF9tcGxhbmUgKm1wKQ0KPiA+ICt7DQo+ID4gKwl1bnNpZ25lZCBpbnQgYnBsLCBw cGw7DQo+IA0KPiBieXRlcyBwZXIgbGluZSBhbmQgcGl4ZWxzIHBlciBsaW5lIHJpZ2h0Pw0KPiAN Cg0KWWVzLg0KDQo+ID4gKwl1bnNpZ25lZCBpbnQgcGl4ZWxfYml0cyA9IGdldF9waXhlbF9iaXRz KG1wLT5waXhlbGZvcm1hdCk7DQo+IA0KPiB3b3VsZG4ndCBiZSBlYXNpZXIgYSBnZXRfcGl4ZWxf Ynl0ZXMoKSBmdW5jdGlvbiBpbnN0ZWFkIG9mIGJpdHM/DQo+IA0KDQpTb3JyeS4gSSBkaWRuJ3Qg Z2V0IHRoZSBwb2ludC4NClRoZSB1bml0IG9mIHJldHVybiB2YWx1ZSBpcyBiaXRzLCBub3QgYnl0 ZXMuDQpEbyB5b3Ugc3VnZ2VzdCBtb3ZlIGJwbCAmIHBwbCBjYWxjdWxhdGlvbiBpbnRvIGdldF9w aXhlbF9iaXRzKCkgYW5kDQpyZW5hbWUgdG8gZ2V0X3BpeGVsX2J5dGVzKCk/DQoNCj4gPiArCXVu c2lnbmVkIGludCB3aWR0aCA9IG1wLT53aWR0aDsNCj4gPiArDQo+ID4gKwlicGwgPSAwOw0KPiA+ ICsJaWYgKG5vZGVfaWQgPT0gTVRLX0NBTV9QMV9NQUlOX1NUUkVBTV9PVVQpIHsNCj4gPiArCQkv KiBCYXllciBlbmNvZGluZyBmb3JtYXQgJiAyIGJ5dGVzIGFsaWdubWVudCAqLw0KPiA+ICsJCWJw bCA9IEFMSUdOKERJVl9ST1VORF9VUCh3aWR0aCAqIHBpeGVsX2JpdHMsIDgpLCAyKTsNCj4gPiAr CX0gZWxzZSBpZiAobm9kZV9pZCA9PSBNVEtfQ0FNX1AxX1BBQ0tFRF9CSU5fT1VUKSB7DQo+ID4g KwkJLyoNCj4gPiArCQkgKiBUaGUgRlVMTC1HIGVuY29kaW5nIGZvcm1hdA0KPiA+ICsJCSAqIDEg RyBjb21wb25lbnQgcGVyIHBpeGVsDQo+ID4gKwkJICogMSBSIGNvbXBvbmVudCBwZXIgNCBwaXhl bA0KPiA+ICsJCSAqIDEgQiBjb21wb25lbnQgcGVyIDQgcGl4ZWwNCj4gPiArCQkgKiBUb3RhbCA0 Ry8xUi8xQiBpbiA0IHBpeGVsIChwaXhlbCBwZXIgbGluZTpwcGwpDQo+ID4gKwkJICovDQo+ID4g KwkJcHBsID0gRElWX1JPVU5EX1VQKHdpZHRoICogNiwgNCk7DQo+ID4gKwkJYnBsID0gRElWX1JP VU5EX1VQKHBwbCAqIHBpeGVsX2JpdHMsIDgpOw0KPiA+ICsNCj4gPiArCQkvKiA0IGJ5dGVzIGFs aWdubWVudCBmb3IgMTAgYml0ICYgb3RoZXJzIGFyZSA4IGJ5dGVzICovDQo+ID4gKwkJaWYgKHBp eGVsX2JpdHMgPT0gMTApDQo+ID4gKwkJCWJwbCA9IEFMSUdOKGJwbCwgNCk7DQo+ID4gKwkJZWxz ZQ0KPiA+ICsJCQlicGwgPSBBTElHTihicGwsIDgpOw0KPiA+ICsJfQ0KPiA+ICsJLyoNCj4gPiAr CSAqIFRoaXMgaW1hZ2Ugb3V0cHV0IGJ1ZmZlciB3aWxsIGJlIGlucHV0IGJ1ZmZlciBvZiBNVEsg Q0FNIERJUCBIVw0KPiA+ICsJICogRm9yIE1USyBDQU0gRElQIEhXIGNvbnN0cmFpbmVkLCBpdCBu ZWVkcyA0IGJ5dGVzIGFsaWdubWVudA0KPiA+ICsJICovDQo+ID4gKwlicGwgPSBBTElHTihicGws IDQpOw0KPiA+ICsNCj4gPiArCW1wLT5wbGFuZV9mbXRbMF0uYnl0ZXNwZXJsaW5lID0gYnBsOw0K PiA+ICsJbXAtPnBsYW5lX2ZtdFswXS5zaXplaW1hZ2UgPSBicGwgKiBtcC0+aGVpZ2h0Ow0KPiA+ ICsNCj4gPiArCWRldl9kYmcoY2FtLT5kZXYsICJub2RlOiVkIHdpZHRoOiVkIGJ5dGVzcGVybGlu ZTolZCBzaXplaW1hZ2U6JWRcbiIsDQo+ID4gKwkJbm9kZV9pZCwgd2lkdGgsIGJwbCwgbXAtPnBs YW5lX2ZtdFswXS5zaXplaW1hZ2UpOw0KPiA+ICt9DQo+ID4gKw0KPiA+ICtzdGF0aWMgY29uc3Qg c3RydWN0IHY0bDJfZm9ybWF0ICoNCj4gPiArbXRrX2NhbV9kZXZfZmluZF9mbXQoc3RydWN0IG10 a19jYW1fZGV2X25vZGVfZGVzYyAqZGVzYywgdTMyIGZvcm1hdCkNCj4gPiArew0KPiA+ICsJaW50 IGk7DQo+IA0KPiB1bnNpZ25lZA0KPiANCg0KUmV2aXNlZCBpbiBuZXh0IHBhdGNoLg0KDQo+ID4g Kwljb25zdCBzdHJ1Y3QgdjRsMl9mb3JtYXQgKmRldl9mbXQ7DQo+ID4gKw0KPiA+ICsJZm9yIChp ID0gMDsgaSA8IGRlc2MtPm51bV9mbXRzOyBpKyspIHsNCj4gPiArCQlkZXZfZm10ID0gJmRlc2Mt PmZtdHNbaV07DQo+ID4gKwkJaWYgKGRldl9mbXQtPmZtdC5waXhfbXAucGl4ZWxmb3JtYXQgPT0g Zm9ybWF0KQ0KPiA+ICsJCQlyZXR1cm4gZGV2X2ZtdDsNCj4gPiArCX0NCj4gPiArDQo+ID4gKwly ZXR1cm4gTlVMTDsNCj4gPiArfQ0KPiA+ICsNCj4gPiArLyogR2V0IHRoZSBkZWZhdWx0IGZvcm1h dCBzZXR0aW5nICovDQo+ID4gK3N0YXRpYyB2b2lkDQo+ID4gK210a19jYW1fZGV2X2xvYWRfZGVm YXVsdF9mbXQoc3RydWN0IG10a19jYW1fZGV2ICpjYW0sDQo+ID4gKwkJCSAgICAgc3RydWN0IG10 a19jYW1fZGV2X25vZGVfZGVzYyAqcXVldWVfZGVzYywNCj4gPiArCQkJICAgICBzdHJ1Y3QgdjRs Ml9mb3JtYXQgKmRlc3QpDQo+ID4gK3sNCj4gPiArCWNvbnN0IHN0cnVjdCB2NGwyX2Zvcm1hdCAq ZGVmYXVsdF9mbXQgPQ0KPiA+ICsJCSZxdWV1ZV9kZXNjLT5mbXRzW3F1ZXVlX2Rlc2MtPmRlZmF1 bHRfZm10X2lkeF07DQo+ID4gKw0KPiA+ICsJZGVzdC0+dHlwZSA9IHF1ZXVlX2Rlc2MtPmJ1Zl90 eXBlOw0KPiA+ICsNCj4gPiArCS8qIENvbmZpZ3VyZSBkZWZhdWx0IGZvcm1hdCBiYXNlZCBvbiBu b2RlIHR5cGUgKi8NCj4gPiArCWlmICghcXVldWVfZGVzYy0+aW1hZ2UpIHsNCj4gPiArCQlkZXN0 LT5mbXQubWV0YS5kYXRhZm9ybWF0ID0gZGVmYXVsdF9mbXQtPmZtdC5tZXRhLmRhdGFmb3JtYXQ7 DQo+ID4gKwkJZGVzdC0+Zm10Lm1ldGEuYnVmZmVyc2l6ZSA9IGRlZmF1bHRfZm10LT5mbXQubWV0 YS5idWZmZXJzaXplOw0KPiA+ICsJCXJldHVybjsNCj4gPiArCX0NCj4gPiArDQo+ID4gKwlkZXN0 LT5mbXQucGl4X21wLnBpeGVsZm9ybWF0ID0gZGVmYXVsdF9mbXQtPmZtdC5waXhfbXAucGl4ZWxm b3JtYXQ7DQo+ID4gKwlkZXN0LT5mbXQucGl4X21wLndpZHRoID0gZGVmYXVsdF9mbXQtPmZtdC5w aXhfbXAud2lkdGg7DQo+ID4gKwlkZXN0LT5mbXQucGl4X21wLmhlaWdodCA9IGRlZmF1bHRfZm10 LT5mbXQucGl4X21wLmhlaWdodDsNCj4gPiArCS8qIGJ5dGVzcGVybGluZSAmIHNpemVpbWFnZSBj YWxjdWxhdGlvbiAqLw0KPiA+ICsJY2FsX2ltYWdlX3BpeF9tcChjYW0sIHF1ZXVlX2Rlc2MtPmlk LCAmZGVzdC0+Zm10LnBpeF9tcCk7DQo+ID4gKwlkZXN0LT5mbXQucGl4X21wLm51bV9wbGFuZXMg PSAxOw0KPiA+ICsNCj4gPiArCWRlc3QtPmZtdC5waXhfbXAuY29sb3JzcGFjZSA9IFY0TDJfQ09M T1JTUEFDRV9TUkdCOw0KPiA+ICsJZGVzdC0+Zm10LnBpeF9tcC5maWVsZCA9IFY0TDJfRklFTERf Tk9ORTsNCj4gPiArCWRlc3QtPmZtdC5waXhfbXAueWNiY3JfZW5jID0gVjRMMl9ZQ0JDUl9FTkNf REVGQVVMVDsNCj4gPiArCWRlc3QtPmZtdC5waXhfbXAucXVhbnRpemF0aW9uID0gVjRMMl9RVUFO VElaQVRJT05fREVGQVVMVDsNCj4gPiArCWRlc3QtPmZtdC5waXhfbXAueGZlcl9mdW5jID0gVjRM Ml9YRkVSX0ZVTkNfU1JHQjsNCj4gPiArfQ0KPiA+ICsNCj4gPiArLyogVXRpbGl0eSBmdW5jdGlv bnMgKi8NCj4gPiArc3RhdGljIHVuc2lnbmVkIGludCBnZXRfc2Vuc29yX3BpeGVsX2lkKHVuc2ln bmVkIGludCBmbXQpDQo+ID4gK3sNCj4gPiArCXN3aXRjaCAoZm10KSB7DQo+ID4gKwljYXNlIE1F RElBX0JVU19GTVRfU0JHR1I4XzFYODoNCj4gPiArCWNhc2UgTUVESUFfQlVTX0ZNVF9TQkdHUjEw XzFYMTA6DQo+ID4gKwljYXNlIE1FRElBX0JVU19GTVRfU0JHR1IxMl8xWDEyOg0KPiA+ICsJY2Fz ZSBNRURJQV9CVVNfRk1UX1NCR0dSMTRfMVgxNDoNCj4gPiArCQlyZXR1cm4gTVRLX0NBTV9SQVdf UFhMX0lEX0I7DQo+ID4gKwljYXNlIE1FRElBX0JVU19GTVRfU0dCUkc4XzFYODoNCj4gPiArCWNh c2UgTUVESUFfQlVTX0ZNVF9TR0JSRzEwXzFYMTA6DQo+ID4gKwljYXNlIE1FRElBX0JVU19GTVRf U0dCUkcxMl8xWDEyOg0KPiA+ICsJY2FzZSBNRURJQV9CVVNfRk1UX1NHQlJHMTRfMVgxNDoNCj4g PiArCQlyZXR1cm4gTVRLX0NBTV9SQVdfUFhMX0lEX0dCOw0KPiA+ICsJY2FzZSBNRURJQV9CVVNf Rk1UX1NHUkJHOF8xWDg6DQo+ID4gKwljYXNlIE1FRElBX0JVU19GTVRfU0dSQkcxMF8xWDEwOg0K PiA+ICsJY2FzZSBNRURJQV9CVVNfRk1UX1NHUkJHMTJfMVgxMjoNCj4gPiArCWNhc2UgTUVESUFf QlVTX0ZNVF9TR1JCRzE0XzFYMTQ6DQo+ID4gKwkJcmV0dXJuIE1US19DQU1fUkFXX1BYTF9JRF9H UjsNCj4gPiArCWNhc2UgTUVESUFfQlVTX0ZNVF9TUkdHQjhfMVg4Og0KPiA+ICsJY2FzZSBNRURJ QV9CVVNfRk1UX1NSR0dCMTBfMVgxMDoNCj4gPiArCWNhc2UgTUVESUFfQlVTX0ZNVF9TUkdHQjEy XzFYMTI6DQo+ID4gKwljYXNlIE1FRElBX0JVU19GTVRfU1JHR0IxNF8xWDE0Og0KPiA+ICsJCXJl dHVybiBNVEtfQ0FNX1JBV19QWExfSURfUjsNCj4gPiArCWRlZmF1bHQ6DQo+ID4gKwkJcmV0dXJu IE1US19DQU1fUkFXX1BYTF9JRF9VTktOT1dOOw0KPiA+ICsJfQ0KPiA+ICt9DQo+ID4gKw0KPiA+ ICtzdGF0aWMgdW5zaWduZWQgaW50IGdldF9zZW5zb3JfZm10KHVuc2lnbmVkIGludCBmbXQpDQo+ ID4gK3sNCj4gPiArCXN3aXRjaCAoZm10KSB7DQo+ID4gKwljYXNlIE1FRElBX0JVU19GTVRfU0JH R1I4XzFYODoNCj4gPiArCWNhc2UgTUVESUFfQlVTX0ZNVF9TR0JSRzhfMVg4Og0KPiA+ICsJY2Fz ZSBNRURJQV9CVVNfRk1UX1NHUkJHOF8xWDg6DQo+ID4gKwljYXNlIE1FRElBX0JVU19GTVRfU1JH R0I4XzFYODoNCj4gPiArCQlyZXR1cm4gTVRLX0NBTV9JTUdfRk1UX0JBWUVSODsNCj4gPiArCWNh c2UgTUVESUFfQlVTX0ZNVF9TQkdHUjEwXzFYMTA6DQo+ID4gKwljYXNlIE1FRElBX0JVU19GTVRf U0dCUkcxMF8xWDEwOg0KPiA+ICsJY2FzZSBNRURJQV9CVVNfRk1UX1NHUkJHMTBfMVgxMDoNCj4g PiArCWNhc2UgTUVESUFfQlVTX0ZNVF9TUkdHQjEwXzFYMTA6DQo+ID4gKwkJcmV0dXJuIE1US19D QU1fSU1HX0ZNVF9CQVlFUjEwOw0KPiA+ICsJY2FzZSBNRURJQV9CVVNfRk1UX1NCR0dSMTJfMVgx MjoNCj4gPiArCWNhc2UgTUVESUFfQlVTX0ZNVF9TR0JSRzEyXzFYMTI6DQo+ID4gKwljYXNlIE1F RElBX0JVU19GTVRfU0dSQkcxMl8xWDEyOg0KPiA+ICsJY2FzZSBNRURJQV9CVVNfRk1UX1NSR0dC MTJfMVgxMjoNCj4gPiArCQlyZXR1cm4gTVRLX0NBTV9JTUdfRk1UX0JBWUVSMTI7DQo+ID4gKwlj YXNlIE1FRElBX0JVU19GTVRfU0JHR1IxNF8xWDE0Og0KPiA+ICsJY2FzZSBNRURJQV9CVVNfRk1U X1NHQlJHMTRfMVgxNDoNCj4gPiArCWNhc2UgTUVESUFfQlVTX0ZNVF9TR1JCRzE0XzFYMTQ6DQo+ ID4gKwljYXNlIE1FRElBX0JVU19GTVRfU1JHR0IxNF8xWDE0Og0KPiA+ICsJCXJldHVybiBNVEtf Q0FNX0lNR19GTVRfQkFZRVIxNDsNCj4gPiArCWRlZmF1bHQ6DQo+ID4gKwkJcmV0dXJuIE1US19D QU1fSU1HX0ZNVF9VTktOT1dOOw0KPiA+ICsJfQ0KPiA+ICt9DQo+IA0KPiBJIHdhcyB3b25kZXJp bmcgaWYgaXQgaXMgbm90IGJldHRlciB0byBzYXZlIGFsbCB0aGUgbWVkaWEgYnVzIGZvcm1hdA0K PiBpbnRvIGEgdGFibGUsIGluc3RlYWQgb2YgaGF2aW5nIHNldmVyYWwgc3d0Y2ggY2FzZSBzdGF0 ZW1lbnRzLg0KPiANCg0KT2ssIHJldmlzZSBpbiBuZXh0IHBhdGNoLg0KDQo+ID4gKw0KPiA+ICtz dGF0aWMgdW5zaWduZWQgaW50IGdldF9pbWdfZm10KHVuc2lnbmVkIGludCBmb3VyY2MpDQo+ID4g K3sNCj4gPiArCXN3aXRjaCAoZm91cmNjKSB7DQo+ID4gKwljYXNlIFY0TDJfUElYX0ZNVF9NVElT UF9TQkdHUjg6DQo+ID4gKwljYXNlIFY0TDJfUElYX0ZNVF9NVElTUF9TR0JSRzg6DQo+ID4gKwlj YXNlIFY0TDJfUElYX0ZNVF9NVElTUF9TR1JCRzg6DQo+ID4gKwljYXNlIFY0TDJfUElYX0ZNVF9N VElTUF9TUkdHQjg6DQo+ID4gKwkJcmV0dXJuIE1US19DQU1fSU1HX0ZNVF9CQVlFUjg7DQo+ID4g KwljYXNlIFY0TDJfUElYX0ZNVF9NVElTUF9TQkdHUjhGOg0KPiA+ICsJY2FzZSBWNEwyX1BJWF9G TVRfTVRJU1BfU0dCUkc4RjoNCj4gPiArCWNhc2UgVjRMMl9QSVhfRk1UX01USVNQX1NHUkJHOEY6 DQo+ID4gKwljYXNlIFY0TDJfUElYX0ZNVF9NVElTUF9TUkdHQjhGOg0KPiA+ICsJCXJldHVybiBN VEtfQ0FNX0lNR19GTVRfRkdfQkFZRVI4Ow0KPiA+ICsJY2FzZSBWNEwyX1BJWF9GTVRfTVRJU1Bf U0JHR1IxMDoNCj4gPiArCWNhc2UgVjRMMl9QSVhfRk1UX01USVNQX1NHQlJHMTA6DQo+ID4gKwlj YXNlIFY0TDJfUElYX0ZNVF9NVElTUF9TR1JCRzEwOg0KPiA+ICsJY2FzZSBWNEwyX1BJWF9GTVRf TVRJU1BfU1JHR0IxMDoNCj4gPiArCQlyZXR1cm4gTVRLX0NBTV9JTUdfRk1UX0JBWUVSMTA7DQo+ ID4gKwljYXNlIFY0TDJfUElYX0ZNVF9NVElTUF9TQkdHUjEwRjoNCj4gPiArCWNhc2UgVjRMMl9Q SVhfRk1UX01USVNQX1NHQlJHMTBGOg0KPiA+ICsJY2FzZSBWNEwyX1BJWF9GTVRfTVRJU1BfU0dS QkcxMEY6DQo+ID4gKwljYXNlIFY0TDJfUElYX0ZNVF9NVElTUF9TUkdHQjEwRjoNCj4gPiArCQly ZXR1cm4gTVRLX0NBTV9JTUdfRk1UX0ZHX0JBWUVSMTA7DQo+ID4gKwljYXNlIFY0TDJfUElYX0ZN VF9NVElTUF9TQkdHUjEyOg0KPiA+ICsJY2FzZSBWNEwyX1BJWF9GTVRfTVRJU1BfU0dCUkcxMjoN Cj4gPiArCWNhc2UgVjRMMl9QSVhfRk1UX01USVNQX1NHUkJHMTI6DQo+ID4gKwljYXNlIFY0TDJf UElYX0ZNVF9NVElTUF9TUkdHQjEyOg0KPiA+ICsJCXJldHVybiBNVEtfQ0FNX0lNR19GTVRfQkFZ RVIxMjsNCj4gPiArCWNhc2UgVjRMMl9QSVhfRk1UX01USVNQX1NCR0dSMTJGOg0KPiA+ICsJY2Fz ZSBWNEwyX1BJWF9GTVRfTVRJU1BfU0dCUkcxMkY6DQo+ID4gKwljYXNlIFY0TDJfUElYX0ZNVF9N VElTUF9TR1JCRzEyRjoNCj4gPiArCWNhc2UgVjRMMl9QSVhfRk1UX01USVNQX1NSR0dCMTJGOg0K PiA+ICsJCXJldHVybiBNVEtfQ0FNX0lNR19GTVRfRkdfQkFZRVIxMjsNCj4gPiArCWNhc2UgVjRM Ml9QSVhfRk1UX01USVNQX1NCR0dSMTQ6DQo+ID4gKwljYXNlIFY0TDJfUElYX0ZNVF9NVElTUF9T R0JSRzE0Og0KPiA+ICsJY2FzZSBWNEwyX1BJWF9GTVRfTVRJU1BfU0dSQkcxNDoNCj4gPiArCWNh c2UgVjRMMl9QSVhfRk1UX01USVNQX1NSR0dCMTQ6DQo+ID4gKwkJcmV0dXJuIE1US19DQU1fSU1H X0ZNVF9CQVlFUjE0Ow0KPiA+ICsJY2FzZSBWNEwyX1BJWF9GTVRfTVRJU1BfU0JHR1IxNEY6DQo+ ID4gKwljYXNlIFY0TDJfUElYX0ZNVF9NVElTUF9TR0JSRzE0RjoNCj4gPiArCWNhc2UgVjRMMl9Q SVhfRk1UX01USVNQX1NHUkJHMTRGOg0KPiA+ICsJY2FzZSBWNEwyX1BJWF9GTVRfTVRJU1BfU1JH R0IxNEY6DQo+ID4gKwkJcmV0dXJuIE1US19DQU1fSU1HX0ZNVF9GR19CQVlFUjE0Ow0KPiA+ICsJ ZGVmYXVsdDoNCj4gPiArCQlyZXR1cm4gTVRLX0NBTV9JTUdfRk1UX1VOS05PV047DQo+ID4gKwl9 PiArfQ0KPiANCj4gc2FtZSBmb3IgdGhlIHBpeGVsZm9ybWF0Lg0KPiANCj4gVGhlbiB5b3UgY2Fu IGNhY2hlIG9iamVjdCB3aXRoIHRoZSBwaXhlbGZvcm1hdCBpbiB0aGUgbWFpbiBzdHJ1Y3QuDQo+ IA0KDQpPaywgcmV2aXNlIGluIG5leHQgcGF0Y2guDQoNCj4gPiArDQo+ID4gK3N0YXRpYyBpbnQg Y29uZmlnX2ltZ19mbXQoc3RydWN0IG10a19jYW1fZGV2ICpjYW0sIHVuc2lnbmVkIGludCBub2Rl X2lkLA0KPiA+ICsJCQkgIHN0cnVjdCBwMV9pbWdfb3V0cHV0ICpvdXRfZm10LCBpbnQgc2Rfd2lk dGgsDQo+ID4gKwkJCSAgaW50IHNkX2hlaWdodCkNCj4gPiArew0KPiA+ICsJY29uc3Qgc3RydWN0 IHY0bDJfZm9ybWF0ICpjZmdfZm10ID0gJmNhbS0+dmRldl9ub2Rlc1tub2RlX2lkXS52ZGV2X2Zt dDsNCj4gPiArDQo+ID4gKwkvKiBDaGVjayBvdXRwdXQgJiBpbnB1dCBpbWFnZSBzaXplIGRpbWVu c2lvbiAqLw0KPiA+ICsJaWYgKGNmZ19mbXQtPmZtdC5waXhfbXAud2lkdGggPiBzZF93aWR0aCB8 fA0KPiA+ICsJICAgIGNmZ19mbXQtPmZtdC5waXhfbXAuaGVpZ2h0ID4gc2RfaGVpZ2h0KSB7DQo+ ID4gKwkJZGV2X2VycihjYW0tPmRldiwgIm5vZGU6JWQgY2ZnIHNpemUgaXMgbGFyZ2VyIHRoYW4g c2Vuc29yXG4iLA0KPiA+ICsJCQlub2RlX2lkKTsNCj4gPiArCQlyZXR1cm4gLUVJTlZBTDsNCj4g PiArCX0NCj4gPiArDQo+ID4gKwkvKiBDaGVjayByZXNpemUgcmF0aW8gZm9yIHJlc2l6ZSBvdXQg c3RyZWFtIGR1ZSB0byBIVyBjb25zdHJhaW50ICovDQo+ID4gKwlpZiAoKChjZmdfZm10LT5mbXQu cGl4X21wLndpZHRoICogMTAwIC8gc2Rfd2lkdGgpIDwNCj4gPiArCSAgICBNVEtfSVNQX01JTl9S RVNJWkVfUkFUSU8pIHx8DQo+ID4gKwkgICAgKChjZmdfZm10LT5mbXQucGl4X21wLmhlaWdodCAq IDEwMCAvIHNkX2hlaWdodCkgPA0KPiA+ICsJICAgIE1US19JU1BfTUlOX1JFU0laRV9SQVRJTykp IHsNCj4gPiArCQlkZXZfZXJyKGNhbS0+ZGV2LCAibm9kZTolZCByZXNpemUgcmF0aW8gaXMgbGVz cyB0aGFuICVkJSVcbiIsDQo+ID4gKwkJCW5vZGVfaWQsIE1US19JU1BfTUlOX1JFU0laRV9SQVRJ Tyk7DQo+ID4gKwkJcmV0dXJuIC1FSU5WQUw7DQo+ID4gKwl9DQo+ID4gKw0KPiA+ICsJb3V0X2Zt dC0+aW1nX2ZtdCA9IGdldF9pbWdfZm10KGNmZ19mbXQtPmZtdC5waXhfbXAucGl4ZWxmb3JtYXQp Ow0KPiA+ICsJb3V0X2ZtdC0+cGl4ZWxfYml0cyA9IGdldF9waXhlbF9iaXRzKGNmZ19mbXQtPmZt dC5waXhfbXAucGl4ZWxmb3JtYXQpOw0KPiA+ICsJaWYgKG91dF9mbXQtPmltZ19mbXQgPT0gTVRL X0NBTV9JTUdfRk1UX1VOS05PV04gfHwNCj4gPiArCSAgICAhb3V0X2ZtdC0+cGl4ZWxfYml0cykg ew0KPiA+ICsJCWRldl9lcnIoY2FtLT5kZXYsICJub2RlOiVkIHVua25vd24gcGl4ZWwgZm10OiVk XG4iLA0KPiA+ICsJCQlub2RlX2lkLCBjZmdfZm10LT5mbXQucGl4X21wLnBpeGVsZm9ybWF0KTsN Cj4gPiArCQlyZXR1cm4gLUVJTlZBTDsNCj4gPiArCX0NCj4gPiArCWRldl9kYmcoY2FtLT5kZXYs ICJub2RlOiVkIHBpeGVsX2JpdHM6JWQgaW1nX2ZtdDoweCV4XG4iLA0KPiA+ICsJCW5vZGVfaWQs IG91dF9mbXQtPnBpeGVsX2JpdHMsIG91dF9mbXQtPmltZ19mbXQpOw0KPiA+ICsNCj4gPiArCW91 dF9mbXQtPnNpemUudyA9IGNmZ19mbXQtPmZtdC5waXhfbXAud2lkdGg7DQo+ID4gKwlvdXRfZm10 LT5zaXplLmggPSBjZmdfZm10LT5mbXQucGl4X21wLmhlaWdodDsNCj4gPiArCW91dF9mbXQtPnNp emUuc3RyaWRlID0gY2ZnX2ZtdC0+Zm10LnBpeF9tcC5wbGFuZV9mbXRbMF0uYnl0ZXNwZXJsaW5l Ow0KPiA+ICsJb3V0X2ZtdC0+c2l6ZS54c2l6ZSA9IGNmZ19mbXQtPmZtdC5waXhfbXAucGxhbmVf Zm10WzBdLmJ5dGVzcGVybGluZTsNCj4gPiArDQo+ID4gKwlvdXRfZm10LT5jcm9wLmxlZnQgPSAw Ow0KPiA+ICsJb3V0X2ZtdC0+Y3JvcC50b3AgPSAwOw0KPiA+ICsJb3V0X2ZtdC0+Y3JvcC53aWR0 aCA9IHNkX3dpZHRoOw0KPiA+ICsJb3V0X2ZtdC0+Y3JvcC5oZWlnaHQgPSBzZF9oZWlnaHQ7DQo+ ID4gKw0KPiA+ICsJZGV2X2RiZyhjYW0tPmRldiwNCj4gPiArCQkibm9kZTolZCBzaXplPSUwZHgl MGQsIHN0cmlkZTolZCwgeHNpemU6JWQsIGNyb3A9JTBkeCUwZFxuIiwNCj4gPiArCQlub2RlX2lk LCBvdXRfZm10LT5zaXplLncsIG91dF9mbXQtPnNpemUuaCwNCj4gPiArCQlvdXRfZm10LT5zaXpl LnN0cmlkZSwgb3V0X2ZtdC0+c2l6ZS54c2l6ZSwNCj4gPiArCQlvdXRfZm10LT5jcm9wLndpZHRo LCBvdXRfZm10LT5jcm9wLmhlaWdodCk7DQo+ID4gKw0KPiA+ICsJcmV0dXJuIDA7DQo+ID4gK30N Cj4gPiArDQo+ID4gK3N0YXRpYyB2b2lkIG10a19jYW1fZGV2X2luaXRfc3RyZWFtKHN0cnVjdCBt dGtfY2FtX2RldiAqY2FtKQ0KPiA+ICt7DQo+ID4gKwlpbnQgaTsNCj4gPiArDQo+ID4gKwljYW0t PmVuYWJsZWRfY291bnQgPSAwOw0KPiA+ICsJY2FtLT5lbmFibGVkX2RtYXMgPSAwOw0KPiA+ICsJ Y2FtLT5zdHJlYW1fY291bnQgPSAwOw0KPiA+ICsJY2FtLT5ydW5uaW5nX2pvYl9jb3VudCA9IDA7 DQo+ID4gKw0KPiA+ICsJLyogR2V0IHRoZSBlbmFibGVkIG1ldGEgRE1BIHBvcnRzICovDQo+ID4g Kwlmb3IgKGkgPSAwOyBpIDwgTVRLX0NBTV9QMV9UT1RBTF9OT0RFUzsgaSsrKSB7DQo+ID4gKwkJ aWYgKCFjYW0tPnZkZXZfbm9kZXNbaV0uZW5hYmxlZCkNCj4gPiArCQkJY29udGludWU7DQo+ID4g KwkJY2FtLT5lbmFibGVkX2NvdW50Kys7DQo+ID4gKwkJY2FtLT5lbmFibGVkX2RtYXMgfD0gY2Ft LT52ZGV2X25vZGVzW2ldLmRlc2MuZG1hX3BvcnQ7DQo+ID4gKwl9DQo+ID4gKw0KPiA+ICsJZGV2 X2RiZyhjYW0tPmRldiwgIiVzOiVkOjB4JXhcbiIsIF9fZnVuY19fLCBjYW0tPmVuYWJsZWRfY291 bnQsDQo+ID4gKwkJY2FtLT5lbmFibGVkX2RtYXMpOw0KPiA+ICt9DQo+ID4gKw0KPiA+ICtzdGF0 aWMgaW50IG10a19jYW1fZGV2X2lzcF9jb25maWcoc3RydWN0IG10a19jYW1fZGV2ICpjYW0pDQo+ ID4gK3sNCj4gPiArCXN0cnVjdCBkZXZpY2UgKmRldiA9IGNhbS0+ZGV2Ow0KPiA+ICsJc3RydWN0 IHAxX2NvbmZpZ19wYXJhbSBjb25maWdfcGFyYW07DQo+ID4gKwlzdHJ1Y3QgY2ZnX2luX3BhcmFt ICpjZmdfaW5fcGFyYW07DQo+ID4gKwlzdHJ1Y3QgdjRsMl9zdWJkZXZfZm9ybWF0IHNkX2ZtdDsN Cj4gPiArCWludCBzZF93aWR0aCwgc2RfaGVpZ2h0LCBzZF9jb2RlOw0KPiANCj4gYXJlIHRoaXMg c2RfKiB2YXJpYWJsZXMgcmVxdWlyZWQ/IENhbid0IHNkX2ZtdCBiZSBkaXJlY3RseSBhY2Nlc3Nl ZD8NCj4gDQoNCk9rLCByZXZpc2VkIGluIG5leHQgcGF0Y2ggc2V0Lg0KDQo+ID4gKwl1bnNpZ25l ZCBpbnQgZW5hYmxlZF9kbWFfcG9ydHMgPSBjYW0tPmVuYWJsZWRfZG1hczsNCj4gPiArCWludCBy ZXQ7DQo+ID4gKw0KPiA+ICsJLyogR2V0IHNlbnNvciBmb3JtYXQgY29uZmlndXJhdGlvbiAqLw0K PiA+ICsJc2RfZm10LndoaWNoID0gVjRMMl9TVUJERVZfRk9STUFUX0FDVElWRTsNCj4gPiArCXJl dCA9IHY0bDJfc3ViZGV2X2NhbGwoY2FtLT5zZW5zb3IsIHBhZCwgZ2V0X2ZtdCwgTlVMTCwgJnNk X2ZtdCk7DQo+ID4gKwlpZiAocmV0KSB7DQo+ID4gKwkJZGV2X2RiZyhkZXYsICJzZW5zb3IgZ19m bXQgZmFpbGVkOiVkXG4iLCByZXQpOw0KPiA+ICsJCXJldHVybiByZXQ7DQo+ID4gKwl9DQo+ID4g KwlzZF93aWR0aCA9IHNkX2ZtdC5mb3JtYXQud2lkdGg7DQo+ID4gKwlzZF9oZWlnaHQgPSBzZF9m bXQuZm9ybWF0LmhlaWdodDsNCj4gPiArCXNkX2NvZGUgPSBzZF9mbXQuZm9ybWF0LmNvZGU7DQo+ ID4gKwlkZXZfZGJnKGRldiwgInNkIGZtdCB3Kmg9JWQqJWQsIGNvZGU9MHgleFxuIiwgc2Rfd2lk dGgsIHNkX2hlaWdodCwNCj4gPiArCQlzZF9jb2RlKTsNCj4gDQo+IElmIFY0TDJfU1VCREVWX0ZM X0hBU19ERVZOT0RFIGlzIHVzZWQsIHRoZW4gZm9ybWF0IHNob3VsZG4ndCBwcm9wYWdhdGUgZnJv bSBvbmUgbm9kZSB0byB0aGUgb3RoZXIsDQo+IGl0IHNob3VsZCBiZSBjb25maWd1cmVkIGZyb20g dXNlcnNwYWNlLg0KPiANCg0KQ291bGQgeW91IGV4cGxhaW4gd2h5Pw0KTW9yZW92ZXIsIGhvdyBk b2VzIGNvbmZpZ3VyYXRpb24gZnJvbSB1c2VyIHNwYWNlPw0KDQo+ID4gKw0KPiA+ICsJbWVtc2V0 KCZjb25maWdfcGFyYW0sIDAsIHNpemVvZihjb25maWdfcGFyYW0pKTsNCj4gPiArDQo+ID4gKwkv KiBVcGRhdGUgY2ZnX2luX3BhcmFtICovDQo+ID4gKwljZmdfaW5fcGFyYW0gPSAmY29uZmlnX3Bh cmFtLmNmZ19pbl9wYXJhbTsNCj4gPiArCWNmZ19pbl9wYXJhbS0+Y29udGludW91cyA9IHRydWU7 DQo+ID4gKwkvKiBGaXggdG8gb25lIHBpeGVsIG1vZGUgaW4gZGVmYXVsdCAqLw0KPiA+ICsJY2Zn X2luX3BhcmFtLT5waXhlbF9tb2RlID0gTVRLX0lTUF9PTkVfUElYRUxfTU9ERTsNCj4gPiArCWNm Z19pbl9wYXJhbS0+Y3JvcC53aWR0aCA9IHNkX3dpZHRoOw0KPiA+ICsJY2ZnX2luX3BhcmFtLT5j cm9wLmhlaWdodCA9IHNkX2hlaWdodDsNCj4gPiArCWNmZ19pbl9wYXJhbS0+cmF3X3BpeGVsX2lk ID0gZ2V0X3NlbnNvcl9waXhlbF9pZChzZF9jb2RlKTsNCj4gPiArCWNmZ19pbl9wYXJhbS0+aW1n X2ZtdCA9IGdldF9zZW5zb3JfZm10KHNkX2NvZGUpOw0KPiA+ICsJaWYgKGNmZ19pbl9wYXJhbS0+ aW1nX2ZtdCA9PSBNVEtfQ0FNX0lNR19GTVRfVU5LTk9XTiB8fA0KPiA+ICsJICAgIGNmZ19pbl9w YXJhbS0+cmF3X3BpeGVsX2lkID09IE1US19DQU1fUkFXX1BYTF9JRF9VTktOT1dOKSB7DQo+ID4g KwkJZGV2X2VycihkZXYsICJ1bmtub3duIHNkIGNvZGU6JWRcbiIsIHNkX2NvZGUpOw0KPiA+ICsJ CXJldHVybiAtRUlOVkFMOw0KPiA+ICsJfQ0KPiA+ICsNCj4gPiArCS8qIFVwZGF0ZSBjZmdfbWFp bl9wYXJhbSAqLw0KPiA+ICsJY29uZmlnX3BhcmFtLmNmZ19tYWluX3BhcmFtLnB1cmVfcmF3ID0g dHJ1ZTsNCj4gPiArCWNvbmZpZ19wYXJhbS5jZmdfbWFpbl9wYXJhbS5wdXJlX3Jhd19wYWNrID0g dHJ1ZTsNCj4gPiArCXJldCA9IGNvbmZpZ19pbWdfZm10KGNhbSwgTVRLX0NBTV9QMV9NQUlOX1NU UkVBTV9PVVQsDQo+ID4gKwkJCSAgICAgJmNvbmZpZ19wYXJhbS5jZmdfbWFpbl9wYXJhbS5vdXRw dXQsDQo+ID4gKwkJCSAgICAgc2Rfd2lkdGgsIHNkX2hlaWdodCk7DQo+ID4gKwlpZiAocmV0KQ0K PiA+ICsJCXJldHVybiByZXQ7DQo+ID4gKw0KPiA+ICsJLyogVXBkYXRlIGNmZ19yZXNpemVfcGFy YW0gKi8NCj4gPiArCWlmIChlbmFibGVkX2RtYV9wb3J0cyAmIFJfUlJaTykgew0KPiA+ICsJCXJl dCA9IGNvbmZpZ19pbWdfZm10KGNhbSwgTVRLX0NBTV9QMV9QQUNLRURfQklOX09VVCwNCj4gPiAr CQkJCSAgICAgJmNvbmZpZ19wYXJhbS5jZmdfcmVzaXplX3BhcmFtLm91dHB1dCwNCj4gPiArCQkJ CSAgICAgc2Rfd2lkdGgsIHNkX2hlaWdodCk7DQo+ID4gKwkJaWYgKHJldCkNCj4gPiArCQkJcmV0 dXJuIHJldDsNCj4gPiArCX0gZWxzZSB7DQo+ID4gKwkJY29uZmlnX3BhcmFtLmNmZ19yZXNpemVf cGFyYW0uYnlwYXNzID0gdHJ1ZTsNCj4gPiArCX0NCj4gPiArDQo+ID4gKwkvKiBVcGRhdGUgZW5h YmxlZF9kbWFzICovDQo+ID4gKwljb25maWdfcGFyYW0uZW5hYmxlZF9kbWFzID0gZW5hYmxlZF9k bWFfcG9ydHM7DQo+ID4gKwltdGtfaXNwX2h3X2NvbmZpZyhjYW0sICZjb25maWdfcGFyYW0pOw0K PiA+ICsJZGV2X2RiZyhkZXYsICIlcyBkb25lXG4iLCBfX2Z1bmNfXyk7DQo+ID4gKw0KPiA+ICsJ cmV0dXJuIDA7DQo+ID4gK30NCj4gPiArDQo+ID4gK3ZvaWQgbXRrX2NhbV9kZXZfZXZlbnRfZnJh bWVfc3luYyhzdHJ1Y3QgbXRrX2NhbV9kZXYgKmNhbSwNCj4gPiArCQkJCSAgdW5zaWduZWQgaW50 IGZyYW1lX3NlcV9ubykNCj4gPiArew0KPiA+ICsJc3RydWN0IHY0bDJfZXZlbnQgZXZlbnQgPSB7 DQo+ID4gKwkJLnR5cGUgPSBWNEwyX0VWRU5UX0ZSQU1FX1NZTkMsDQo+ID4gKwkJLnUuZnJhbWVf c3luYy5mcmFtZV9zZXF1ZW5jZSA9IGZyYW1lX3NlcV9ubywNCj4gPiArCX07DQo+ID4gKw0KPiA+ ICsJdjRsMl9ldmVudF9xdWV1ZShjYW0tPnN1YmRldi5kZXZub2RlLCAmZXZlbnQpOw0KPiA+ICt9 DQo+ID4gKw0KPiA+ICtzdGF0aWMgc3RydWN0IHY0bDJfc3ViZGV2ICoNCj4gPiArbXRrX2NhbV9j aW9fZ2V0X2FjdGl2ZV9zZW5zb3Ioc3RydWN0IG10a19jYW1fZGV2ICpjYW0pDQo+ID4gK3sNCj4g PiArCXN0cnVjdCBtZWRpYV9kZXZpY2UgKm1kZXYgPSBjYW0tPnNlbmluZi0+ZW50aXR5LmdyYXBo X29iai5tZGV2Ow0KPiA+ICsJc3RydWN0IGRldmljZSAqZGV2ID0gY2FtLT5kZXY7DQo+ID4gKwlz dHJ1Y3QgbWVkaWFfZW50aXR5ICplbnRpdHk7DQo+ID4gKwlzdHJ1Y3QgdjRsMl9zdWJkZXYgKnNl bnNvcjsNCj4gPiArDQo+ID4gKwlzZW5zb3IgPSBOVUxMOw0KPiA+ICsJbWVkaWFfZGV2aWNlX2Zv cl9lYWNoX2VudGl0eShlbnRpdHksIG1kZXYpIHsNCj4gPiArCQlkZXZfZGJnKGRldiwgIm1lZGlh IGVudGl0eTogJXM6MHgleDolZFxuIiwNCj4gPiArCQkJZW50aXR5LT5uYW1lLCBlbnRpdHktPmZ1 bmN0aW9uLCBlbnRpdHktPnN0cmVhbV9jb3VudCk7DQo+ID4gKwkJaWYgKGVudGl0eS0+ZnVuY3Rp b24gPT0gTUVESUFfRU5UX0ZfQ0FNX1NFTlNPUiAmJg0KPiA+ICsJCSAgICBlbnRpdHktPnN0cmVh bV9jb3VudCkgew0KPiA+ICsJCQlzZW5zb3IgPSBtZWRpYV9lbnRpdHlfdG9fdjRsMl9zdWJkZXYo ZW50aXR5KTsNCj4gPiArCQkJZGV2X2RiZyhkZXYsICJzZW5zb3IgZm91bmQ6ICVzXG4iLCBlbnRp dHktPm5hbWUpOw0KPiA+ICsJCQlicmVhazsNCj4gPiArCQl9DQo+ID4gKwl9DQo+ID4gKw0KPiA+ ICsJaWYgKCFzZW5zb3IpDQo+ID4gKwkJZGV2X2VycihkZXYsICJubyBzZW5pbmYgY29ubmVjdGVk XG4iKTsNCj4gPiArDQo+ID4gKwlyZXR1cm4gc2Vuc29yOw0KPiA+ICt9DQo+ID4gKw0KPiA+ICtz dGF0aWMgaW50IG10a19jYW1fY2lvX3N0cmVhbV9vbihzdHJ1Y3QgbXRrX2NhbV9kZXYgKmNhbSkN Cj4gPiArew0KPiA+ICsJc3RydWN0IGRldmljZSAqZGV2ID0gY2FtLT5kZXY7DQo+ID4gKwlpbnQg cmV0Ow0KPiA+ICsNCj4gPiArCWlmICghY2FtLT5zZW5pbmYpIHsNCj4gPiArCQlkZXZfZXJyKGRl diwgIm5vIHNlbmluZiBjb25uZWN0ZWRcbiIpOw0KPiA+ICsJCXJldHVybiAtRU5PREVWOw0KPiA+ ICsJfQ0KPiA+ICsNCj4gPiArCS8qIEdldCBhY3RpdmUgc2Vuc29yIGZyb20gZ3JhcGggdG9wb2xv Z3kgKi8NCj4gPiArCWNhbS0+c2Vuc29yID0gbXRrX2NhbV9jaW9fZ2V0X2FjdGl2ZV9zZW5zb3Io Y2FtKTsNCj4gPiArCWlmICghY2FtLT5zZW5zb3IpDQo+ID4gKwkJcmV0dXJuIC1FTk9ERVY7DQo+ ID4gKw0KPiA+ICsJLyogU2VuaW5mIG11c3Qgc3RyZWFtIG9uIGZpcnN0ICovDQo+ID4gKwlyZXQg PSB2NGwyX3N1YmRldl9jYWxsKGNhbS0+c2VuaW5mLCB2aWRlbywgc19zdHJlYW0sIDEpOw0KPiA+ ICsJaWYgKHJldCkgew0KPiA+ICsJCWRldl9lcnIoZGV2LCAiZmFpbGVkIHRvIHN0cmVhbSBvbiAl czolZFxuIiwNCj4gPiArCQkJY2FtLT5zZW5pbmYtPmVudGl0eS5uYW1lLCByZXQpOw0KPiA+ICsJ CXJldHVybiByZXQ7DQo+ID4gKwl9DQo+ID4gKw0KPiA+ICsJcmV0ID0gdjRsMl9zdWJkZXZfY2Fs bChjYW0tPnNlbnNvciwgdmlkZW8sIHNfc3RyZWFtLCAxKTsNCj4gPiArCWlmIChyZXQpIHsNCj4g PiArCQlkZXZfZXJyKGRldiwgImZhaWxlZCB0byBzdHJlYW0gb24gJXM6JWRcbiIsDQo+ID4gKwkJ CWNhbS0+c2Vuc29yLT5lbnRpdHkubmFtZSwgcmV0KTsNCj4gPiArCQlnb3RvIGZhaWxfc2VuaW5m X29mZjsNCj4gPiArCX0NCj4gPiArDQo+ID4gKwlyZXQgPSBtdGtfY2FtX2Rldl9pc3BfY29uZmln KGNhbSk7DQo+ID4gKwlpZiAocmV0KQ0KPiA+ICsJCWdvdG8gZmFpbF9zZW5zb3Jfb2ZmOw0KPiA+ ICsNCj4gPiArCWNhbS0+c3RyZWFtaW5nID0gdHJ1ZTsNCj4gPiArCW10a19pc3Bfc3RyZWFtKGNh bSwgMSk7DQo+ID4gKwltdGtfY2FtX2Rldl9yZXFfdHJ5X3F1ZXVlKGNhbSk7DQo+ID4gKwlkZXZf ZGJnKGRldiwgInN0cmVhbWVkIG9uIFBhc3MgMVxuIik7DQo+ID4gKw0KPiA+ICsJcmV0dXJuIDA7 DQo+ID4gKw0KPiA+ICtmYWlsX3NlbnNvcl9vZmY6DQo+ID4gKwl2NGwyX3N1YmRldl9jYWxsKGNh bS0+c2Vuc29yLCB2aWRlbywgc19zdHJlYW0sIDApOw0KPiA+ICtmYWlsX3NlbmluZl9vZmY6DQo+ ID4gKwl2NGwyX3N1YmRldl9jYWxsKGNhbS0+c2VuaW5mLCB2aWRlbywgc19zdHJlYW0sIDApOw0K PiA+ICsNCj4gPiArCXJldHVybiByZXQ7DQo+ID4gK30NCj4gPiArDQo+ID4gK3N0YXRpYyBpbnQg bXRrX2NhbV9jaW9fc3RyZWFtX29mZihzdHJ1Y3QgbXRrX2NhbV9kZXYgKmNhbSkNCj4gPiArew0K PiA+ICsJc3RydWN0IGRldmljZSAqZGV2ID0gY2FtLT5kZXY7DQo+ID4gKwlpbnQgcmV0Ow0KPiA+ ICsNCj4gPiArCXJldCA9IHY0bDJfc3ViZGV2X2NhbGwoY2FtLT5zZW5zb3IsIHZpZGVvLCBzX3N0 cmVhbSwgMCk7DQo+ID4gKwlpZiAocmV0KSB7DQo+ID4gKwkJZGV2X2VycihkZXYsICJmYWlsZWQg dG8gc3RyZWFtIG9mZiAlczolZFxuIiwNCj4gPiArCQkJY2FtLT5zZW5zb3ItPmVudGl0eS5uYW1l LCByZXQpOw0KPiA+ICsJCXJldHVybiAtRVBFUk07DQo+IA0KPiBXaHkgLUVQRVJNID8NCj4gDQoN Ck9rLCB3ZSB3aWxsIHJldHVybiByZXQgZGlyZWN0bHkuDQoNCj4gPiArCX0NCj4gPiArDQo+ID4g KwlyZXQgPSB2NGwyX3N1YmRldl9jYWxsKGNhbS0+c2VuaW5mLCB2aWRlbywgc19zdHJlYW0sIDAp Ow0KPiA+ICsJaWYgKHJldCkgew0KPiA+ICsJCWRldl9lcnIoZGV2LCAiZmFpbGVkIHRvIHN0cmVh bSBvZmYgJXM6JWRcbiIsDQo+ID4gKwkJCWNhbS0+c2VuaW5mLT5lbnRpdHkubmFtZSwgcmV0KTsN Cj4gPiArCQlyZXR1cm4gLUVQRVJNOw0KPiA+ICsJfQ0KPiA+ICsNCj4gPiArCWNhbS0+c3RyZWFt aW5nID0gZmFsc2U7DQo+ID4gKwltdGtfaXNwX3N0cmVhbShjYW0sIDApOw0KPiA+ICsJbXRrX2lz cF9od19yZWxlYXNlKGNhbSk7DQo+ID4gKw0KPiA+ICsJZGV2X2RiZyhkZXYsICJzdHJlYW1lZCBv ZmYgUGFzcyAxXG4iKTsNCj4gPiArDQo+ID4gKwlyZXR1cm4gMDsNCj4gPiArfQ0KPiA+ICsNCj4g PiArc3RhdGljIGludCBtdGtfY2FtX3NkX3Nfc3RyZWFtKHN0cnVjdCB2NGwyX3N1YmRldiAqc2Qs IGludCBlbmFibGUpDQo+ID4gK3sNCj4gPiArCXN0cnVjdCBtdGtfY2FtX2RldiAqY2FtID0gY29u dGFpbmVyX29mKHNkLCBzdHJ1Y3QgbXRrX2NhbV9kZXYsIHN1YmRldik7DQo+ID4gKw0KPiA+ICsJ aWYgKGVuYWJsZSkgew0KPiA+ICsJCS8qIEFsaWduIHZiMl9jb3JlX3N0cmVhbW9uIGRlc2lnbiAq Lw0KPiA+ICsJCWlmIChjYW0tPnN0cmVhbWluZykgew0KPiA+ICsJCQlkZXZfd2FybihjYW0tPmRl diwgImFscmVhZHkgc3RyZWFtaW5nIG9uXG4iKTsNCj4gDQo+IEkgdGhpbmsganVzdCBkZXZfZGJn IGlzIGVub3VnaC4NCj4gDQoNCkZpeCBpbiBuZXh0IHBhdGNoLg0KDQo+ID4gKwkJCXJldHVybiAw Ow0KPiA+ICsJCX0NCj4gPiArCQlyZXR1cm4gbXRrX2NhbV9jaW9fc3RyZWFtX29uKGNhbSk7DQo+ ID4gKwl9DQo+ID4gKw0KPiA+ICsJaWYgKCFjYW0tPnN0cmVhbWluZykgew0KPiA+ICsJCWRldl93 YXJuKGNhbS0+ZGV2LCAiYWxyZWFkeSBzdHJlYW1pbmcgb2ZmXG4iKTsNCj4gDQo+IHNhbWUgaGVy ZQ0KPiANCg0KRml4IGluIG5leHQgcGF0Y2guDQoNCj4gPiArCQlyZXR1cm4gMDsNCj4gPiArCX0N Cj4gPiArCXJldHVybiBtdGtfY2FtX2Npb19zdHJlYW1fb2ZmKGNhbSk7DQo+ID4gK30NCj4gPiAr DQo+ID4gK3N0YXRpYyBpbnQgbXRrX2NhbV9zZF9zdWJzY3JpYmVfZXZlbnQoc3RydWN0IHY0bDJf c3ViZGV2ICpzdWJkZXYsDQo+ID4gKwkJCQkgICAgICBzdHJ1Y3QgdjRsMl9maCAqZmgsDQo+ID4g KwkJCQkgICAgICBzdHJ1Y3QgdjRsMl9ldmVudF9zdWJzY3JpcHRpb24gKnN1YikNCj4gPiArew0K PiA+ICsJc3dpdGNoIChzdWItPnR5cGUpIHsNCj4gPiArCWNhc2UgVjRMMl9FVkVOVF9GUkFNRV9T WU5DOg0KPiA+ICsJCXJldHVybiB2NGwyX2V2ZW50X3N1YnNjcmliZShmaCwgc3ViLCAwLCBOVUxM KTsNCj4gPiArCWRlZmF1bHQ6DQo+ID4gKwkJcmV0dXJuIC1FSU5WQUw7DQo+ID4gKwl9DQo+ID4g K30NCj4gPiArDQo+ID4gK3N0YXRpYyBpbnQgbXRrX2NhbV9tZWRpYV9saW5rX3NldHVwKHN0cnVj dCBtZWRpYV9lbnRpdHkgKmVudGl0eSwNCj4gPiArCQkJCSAgICBjb25zdCBzdHJ1Y3QgbWVkaWFf cGFkICpsb2NhbCwNCj4gPiArCQkJCSAgICBjb25zdCBzdHJ1Y3QgbWVkaWFfcGFkICpyZW1vdGUs IHUzMiBmbGFncykNCj4gPiArew0KPiA+ICsJc3RydWN0IG10a19jYW1fZGV2ICpjYW0gPQ0KPiA+ ICsJCWNvbnRhaW5lcl9vZihlbnRpdHksIHN0cnVjdCBtdGtfY2FtX2Rldiwgc3ViZGV2LmVudGl0 eSk7DQo+ID4gKwl1MzIgcGFkID0gbG9jYWwtPmluZGV4Ow0KPiA+ICsNCj4gPiArCWRldl9kYmco Y2FtLT5kZXYsICIlczogJWQtPiVkIGZsYWdzOjB4JXhcbiIsDQo+ID4gKwkJX19mdW5jX18sIHBh ZCwgcmVtb3RlLT5pbmRleCwgZmxhZ3MpOw0KPiA+ICsNCj4gPiArCS8qDQo+ID4gKwkgKiBUaGUg dmlkZW8gbm9kZXMgZXhwb3NlZCBieSB0aGUgZHJpdmVyIGhhdmUgcGFkcyBpbmRleGVzDQo+ID4g KwkgKiBmcm9tIDAgdG8gTVRLX0NBTV9QMV9UT1RBTF9OT0RFUyAtIDEuDQo+ID4gKwkgKi8NCj4g PiArCWlmIChwYWQgPCBNVEtfQ0FNX1AxX1RPVEFMX05PREVTKQ0KPiA+ICsJCWNhbS0+ZGV2X25v ZGVzW3BhZF0uZW5hYmxlZCA9DQo+ID4gKwkJCSEhKGZsYWdzICYgTUVESUFfTE5LX0ZMX0VOQUJM RUQpOw0KPiANCj4gQ2FuJ3QgeW91IGp1c3QgY2hlY2sgdGhlIHN0YXRlIG9mIHRoZSBsaW5rIGlu IHRoZSBwYWQgaW5zdGVhZCBvZiBzYXZpbmcgaXQgaW4gY2FtLT52ZGV2X25vZGVzW3BhZF0uZW5h YmxlZCA/DQo+IA0KDQpPaywgcmV2aXNlZCBpbiBuZXh0IHBhdGNoLg0KDQo+ID4gKw0KPiA+ICsJ cmV0dXJuIDA7DQo+ID4gK30NCj4gPiArDQo+ID4gK3N0YXRpYyB2b2lkIG10a19jYW1fdmIyX2J1 Zl9xdWV1ZShzdHJ1Y3QgdmIyX2J1ZmZlciAqdmIpDQo+ID4gK3sNCj4gPiArCXN0cnVjdCBtdGtf Y2FtX2RldiAqY2FtID0gdmIyX2dldF9kcnZfcHJpdih2Yi0+dmIyX3F1ZXVlKTsNCj4gPiArCXN0 cnVjdCBtdGtfY2FtX2Rldl9idWZmZXIgKmJ1ZiA9IG10a19jYW1fdmIyX2J1Zl90b19kZXZfYnVm KHZiKTsNCj4gPiArCXN0cnVjdCBtdGtfY2FtX2Rldl9yZXF1ZXN0ICpyZXEgPSBtdGtfY2FtX3Jl cV90b19kZXZfcmVxKHZiLT5yZXF1ZXN0KTsNCj4gPiArCXN0cnVjdCBtdGtfY2FtX3ZpZGVvX2Rl dmljZSAqbm9kZSA9IG10a19jYW1fdmJxX3RvX3ZkZXYodmItPnZiMl9xdWV1ZSk7DQo+ID4gKwlz dHJ1Y3QgZGV2aWNlICpkZXYgPSBjYW0tPmRldjsNCj4gPiArCXVuc2lnbmVkIGxvbmcgZmxhZ3M7 DQo+ID4gKw0KPiA+ICsJZGV2X2RiZyhkZXYsICIlczogbm9kZTolZCBmZDolZCBpZHg6JWRcbiIs IF9fZnVuY19fLA0KPiA+ICsJCW5vZGUtPmlkLCBidWYtPnZiYi5yZXF1ZXN0X2ZkLCBidWYtPnZi Yi52YjJfYnVmLmluZGV4KTsNCj4gPiArDQo+ID4gKwkvKiBhZGRlZCB0aGUgYnVmZmVyIGludG8g dGhlIHRyYWNraW5nIGxpc3QgKi8NCj4gPiArCXNwaW5fbG9ja19pcnFzYXZlKCZub2RlLT5idWZf bGlzdF9sb2NrLCBmbGFncyk7DQo+ID4gKwlsaXN0X2FkZF90YWlsKCZidWYtPmxpc3QsICZub2Rl LT5idWZfbGlzdCk7DQo+ID4gKwlzcGluX3VubG9ja19pcnFyZXN0b3JlKCZub2RlLT5idWZfbGlz dF9sb2NrLCBmbGFncyk7DQo+ID4gKw0KPiA+ICsJLyogdXBkYXRlIGJ1ZmZlciBpbnRlcm5hbCBh ZGRyZXNzICovDQo+ID4gKwlyZXEtPmZyYW1lX3BhcmFtcy5kbWFfYnVmc1tidWYtPm5vZGVfaWRd LmlvdmEgPSBidWYtPmRhZGRyOw0KPiA+ICsJcmVxLT5mcmFtZV9wYXJhbXMuZG1hX2J1ZnNbYnVm LT5ub2RlX2lkXS5zY3BfYWRkciA9IGJ1Zi0+c2NwX2FkZHI7DQo+IA0KPiBpc24ndCBpdCBhbiBp c3N1ZSBpZiB1c2Vyc3BhY2UgcXVldWUgdHdvIGJ1ZmZlcnMgZm9yIHRoZSBzYW1lIHZpZGVvIGRl dmljZSBpbiB0aGUgc2FtZSByZXF1ZXN0Pw0KPiANCj4gdmIyX3JlcXVlc3RfcXVldWUocmVxKSB3 aWxsIGNhbGwgYWxsIHRoZSAuYnVmX3F1ZXVlKCkgY2FsbGJhY2tzLCBhbmQgb25seSB0aGUgbGFz dCBidWZmZXIgaW4gdGhlIGxpc3QNCj4gd2lsbCBiZSBhdCByZXEtPmZyYW1lX3BhcmFtcy5kbWFf YnVmc1tidWYtPm5vZGVfaWRdLCBubz8NCj4gDQo+IEFsc28sIHdoYXQgaGFwcGVucyBpZiBhIHJl cXVlc3QgZG9lc24ndCBjb250YWluIGJ1ZmZlcnMgZm9yIGFsbCBub2RlX2lkcyA/IFdpbGwgaXQg cHV0IGRhdGEgaW4gdGhlIHByZXZpb3VzIHByb2dyYW1tZWQNCj4gYnVmZmVyPw0KPiANCj4gUGxl YXNlLCBsZXQgbWUga25vdyBpZiB0aGVzZSBxdWVzdGlvbnMgZG9lc24ndCBtYWtlIHNlbnNlLCBJ J20gbm90IHRoYXQgZmFtaWxpYXIgd2l0aCB0aGUgcmVxdWVzdCBBUEkgaW50ZXJuYWxzLg0KPiAN Cg0KMS4geWVzLCBpdCBpcyBhIGlzc3VlIGlmIHVzZXJzcGFjZSBxdWV1ZXMgdHdvIGJ1ZmZlcnMg Zm9yIHRoZSBzYW1lIHZpZGVvDQpkZXZpY2Ugd2l0aCB0aGUgc2FtZSByZXF1ZXN0IEZELg0KDQoy LiBBbGwgYnVmZmVycyB3aGljaCBhcmUgYmVsb25nZWQgZGlmZmVyZW50IHRvIGRpZmZlcmVudCB2 aWRlbyBkZXZpY2VzDQppbiB0aGUgcmVxdWVzdCBsaXN0IHdpbGwgYmUgdXBkYXRlZCB0byByZXEt PmZyYW1lX3BhcmFtcy5kbWFfYnVmcyBieQ0KYnVmLT5ub2RlX2lkLg0KDQozLiBJdCBpcyBub3Qg YWxsb3dlZCBmb3IgdXNlcnNwYWNlIHRvIHF1ZXVlIHBhcnRpYWwgYnVmZmVycyBmb3IgYWxsDQpl bmFibGVkIHZpZGVvIGRldmljZXMuIElmIGl0IGhhcHBlbnMsIGl0IG1heSB0cmlnZ2VyIERNQSBl cnJvcnMgZm9yIHRoaXMNCnJlcXVlc3QuDQoNCj4gPiArfQ0KPiA+ICsNCj4gPiArc3RhdGljIGlu dCBtdGtfY2FtX3ZiMl9idWZfaW5pdChzdHJ1Y3QgdmIyX2J1ZmZlciAqdmIpDQo+ID4gK3sNCj4g PiArCXN0cnVjdCBtdGtfY2FtX3ZpZGVvX2RldmljZSAqbm9kZSA9IG10a19jYW1fdmJxX3RvX3Zk ZXYodmItPnZiMl9xdWV1ZSk7DQo+ID4gKwlzdHJ1Y3QgbXRrX2NhbV9kZXYgKmNhbSA9IHZiMl9n ZXRfZHJ2X3ByaXYodmItPnZiMl9xdWV1ZSk7DQo+ID4gKwlzdHJ1Y3QgZGV2aWNlICpkZXYgPSBj YW0tPmRldjsNCj4gPiArCXN0cnVjdCBtdGtfY2FtX2Rldl9idWZmZXIgKmJ1ZjsNCj4gPiArCWRt YV9hZGRyX3QgYWRkcjsNCj4gPiArDQo+ID4gKwlidWYgPSBtdGtfY2FtX3ZiMl9idWZfdG9fZGV2 X2J1Zih2Yik7DQo+ID4gKwlidWYtPm5vZGVfaWQgPSBub2RlLT5pZDsNCj4gPiArCWJ1Zi0+ZGFk ZHIgPSB2YjJfZG1hX2NvbnRpZ19wbGFuZV9kbWFfYWRkcih2YiwgMCk7DQo+ID4gKwlidWYtPnNj cF9hZGRyID0gMDsNCj4gPiArDQo+ID4gKwkvKiBTQ1AgYWRkcmVzcyBpcyBvbmx5IHZhbGlkIGZv ciBtZXRhIGlucHV0IGJ1ZmZlciAqLw0KPiA+ICsJaWYgKCFub2RlLT5kZXNjLnNtZW1fYWxsb2Mp DQo+ID4gKwkJcmV0dXJuIDA7DQo+ID4gKw0KPiA+ICsJYnVmID0gbXRrX2NhbV92YjJfYnVmX3Rv X2Rldl9idWYodmIpOw0KPiA+ICsJLyogVXNlIGNvaGVyZW50IGFkZHJlc3MgdG8gZ2V0IGlvdmEg YWRkcmVzcyAqLw0KPiA+ICsJYWRkciA9IGRtYV9tYXBfcmVzb3VyY2UoZGV2LCBidWYtPmRhZGRy LCB2Yi0+cGxhbmVzWzBdLmxlbmd0aCwNCj4gPiArCQkJCURNQV9CSURJUkVDVElPTkFMLCBETUFf QVRUUl9TS0lQX0NQVV9TWU5DKTs+ICsJaWYgKGRtYV9tYXBwaW5nX2Vycm9yKGRldiwgYWRkcikp IHsNCj4gPiArCQlkZXZfZXJyKGRldiwgImZhaWxlZCB0byBtYXAgbWV0YSBhZGRyOiVwYWRcbiIs ICZidWYtPmRhZGRyKTsNCj4gPiArCQlyZXR1cm4gLUVGQVVMVDsNCj4gPiArCX0NCj4gPiArCWJ1 Zi0+c2NwX2FkZHIgPSBidWYtPmRhZGRyOw0KPiA+ICsJYnVmLT5kYWRkciA9IGFkZHI7DQo+ID4g Kw0KPiA+ICsJcmV0dXJuIDA7DQo+ID4gK30NCj4gPiArDQo+ID4gK3N0YXRpYyBpbnQgbXRrX2Nh bV92YjJfYnVmX3ByZXBhcmUoc3RydWN0IHZiMl9idWZmZXIgKnZiKQ0KPiA+ICt7DQo+ID4gKwlz dHJ1Y3QgbXRrX2NhbV92aWRlb19kZXZpY2UgKm5vZGUgPSBtdGtfY2FtX3ZicV90b192ZGV2KHZi LT52YjJfcXVldWUpOw0KPiA+ICsJc3RydWN0IG10a19jYW1fZGV2ICpjYW0gPSB2YjJfZ2V0X2Ry dl9wcml2KHZiLT52YjJfcXVldWUpOw0KPiA+ICsJc3RydWN0IHZiMl92NGwyX2J1ZmZlciAqdjRs Ml9idWYgPSB0b192YjJfdjRsMl9idWZmZXIodmIpOw0KPiA+ICsJY29uc3Qgc3RydWN0IHY0bDJf Zm9ybWF0ICpmbXQgPSAmbm9kZS0+dmRldl9mbXQ7DQo+ID4gKwl1bnNpZ25lZCBpbnQgc2l6ZTsN Cj4gPiArDQo+ID4gKwlpZiAodmItPnZiMl9xdWV1ZS0+dHlwZSA9PSBWNEwyX0JVRl9UWVBFX01F VEFfT1VUUFVUIHx8DQo+ID4gKwkgICAgdmItPnZiMl9xdWV1ZS0+dHlwZSA9PSBWNEwyX0JVRl9U WVBFX01FVEFfQ0FQVFVSRSkNCj4gPiArCQlzaXplID0gZm10LT5mbXQubWV0YS5idWZmZXJzaXpl Ow0KPiA+ICsJZWxzZQ0KPiA+ICsJCXNpemUgPSBmbXQtPmZtdC5waXhfbXAucGxhbmVfZm10WzBd LnNpemVpbWFnZTsNCj4gPiArDQo+ID4gKwlpZiAodmIyX3BsYW5lX3NpemUodmIsIDApIDwgc2l6 ZSkgew0KPiA+ICsJCWRldl9kYmcoY2FtLT5kZXYsICJwbGFuZSBzaXplIGlzIHRvbyBzbWFsbDol bHU8JXVcbiIsDQo+ID4gKwkJCXZiMl9wbGFuZV9zaXplKHZiLCAwKSwgc2l6ZSk7DQo+ID4gKwkJ cmV0dXJuIC1FSU5WQUw7DQo+ID4gKwl9DQo+ID4gKw0KPiA+ICsJaWYgKFY0TDJfVFlQRV9JU19P VVRQVVQodmItPnZiMl9xdWV1ZS0+dHlwZSkpIHsNCj4gPiArCQlpZiAodmIyX2dldF9wbGFuZV9w YXlsb2FkKHZiLCAwKSAhPSBzaXplKSB7DQo+ID4gKwkJCWRldl9kYmcoY2FtLT5kZXYsICJwbGFu ZSBwYXlsb2FkIGlzIG1pc21hdGNoOiVsdToldVxuIiwNCj4gPiArCQkJCXZiMl9nZXRfcGxhbmVf cGF5bG9hZCh2YiwgMCksIHNpemUpOw0KPiA+ICsJCQlyZXR1cm4gLUVJTlZBTDsNCj4gPiArCQl9 DQo+ID4gKwkJcmV0dXJuIDA7DQo+ID4gKwl9DQo+ID4gKw0KPiA+ICsJdjRsMl9idWYtPmZpZWxk ID0gVjRMMl9GSUVMRF9OT05FOw0KPiA+ICsJdmIyX3NldF9wbGFuZV9wYXlsb2FkKHZiLCAwLCBz aXplKTsNCj4gPiArDQo+ID4gKwlyZXR1cm4gMDsNCj4gPiArfQ0KPiA+ICsNCj4gPiArc3RhdGlj IHZvaWQgbXRrX2NhbV92YjJfYnVmX2NsZWFudXAoc3RydWN0IHZiMl9idWZmZXIgKnZiKQ0KPiA+ ICt7DQo+ID4gKwlzdHJ1Y3QgbXRrX2NhbV92aWRlb19kZXZpY2UgKm5vZGUgPSBtdGtfY2FtX3Zi cV90b192ZGV2KHZiLT52YjJfcXVldWUpOw0KPiA+ICsJc3RydWN0IG10a19jYW1fZGV2ICpjYW0g PSB2YjJfZ2V0X2Rydl9wcml2KHZiLT52YjJfcXVldWUpOw0KPiA+ICsJc3RydWN0IG10a19jYW1f ZGV2X2J1ZmZlciAqYnVmOw0KPiA+ICsJc3RydWN0IGRldmljZSAqZGV2ID0gY2FtLT5kZXY7DQo+ ID4gKw0KPiA+ICsJaWYgKCFub2RlLT5kZXNjLnNtZW1fYWxsb2MpDQo+ID4gKwkJcmV0dXJuOw0K PiA+ICsNCj4gPiArCWJ1ZiA9IG10a19jYW1fdmIyX2J1Zl90b19kZXZfYnVmKHZiKTsNCj4gPiAr CWRtYV91bm1hcF9wYWdlX2F0dHJzKGRldiwgYnVmLT5kYWRkciwNCj4gPiArCQkJICAgICB2Yi0+ cGxhbmVzWzBdLmxlbmd0aCwNCj4gPiArCQkJICAgICBETUFfQklESVJFQ1RJT05BTCwNCj4gPiAr CQkJICAgICBETUFfQVRUUl9TS0lQX0NQVV9TWU5DKTsNCj4gPiArfQ0KPiA+ICsNCj4gPiArc3Rh dGljIHZvaWQgbXRrX2NhbV92YjJfcmVxdWVzdF9jb21wbGV0ZShzdHJ1Y3QgdmIyX2J1ZmZlciAq dmIpDQo+ID4gK3sNCj4gPiArCXN0cnVjdCBtdGtfY2FtX2RldiAqY2FtID0gdmIyX2dldF9kcnZf cHJpdih2Yi0+dmIyX3F1ZXVlKTsNCj4gPiArDQo+ID4gKwlkZXZfZGJnKGNhbS0+ZGV2LCAiJXNc biIsIF9fZnVuY19fKTsNCj4gPiArfQ0KPiA+ICsNCj4gPiArc3RhdGljIGludCBtdGtfY2FtX3Zi Ml9xdWV1ZV9zZXR1cChzdHJ1Y3QgdmIyX3F1ZXVlICp2cSwNCj4gPiArCQkJCSAgIHVuc2lnbmVk IGludCAqbnVtX2J1ZmZlcnMsDQo+ID4gKwkJCQkgICB1bnNpZ25lZCBpbnQgKm51bV9wbGFuZXMs DQo+ID4gKwkJCQkgICB1bnNpZ25lZCBpbnQgc2l6ZXNbXSwNCj4gPiArCQkJCSAgIHN0cnVjdCBk ZXZpY2UgKmFsbG9jX2RldnNbXSkNCj4gPiArew0KPiA+ICsJc3RydWN0IG10a19jYW1fdmlkZW9f ZGV2aWNlICpub2RlID0gbXRrX2NhbV92YnFfdG9fdmRldih2cSk7DQo+ID4gKwl1bnNpZ25lZCBp bnQgbWF4X2J1ZmZlcl9jb3VudCA9IG5vZGUtPmRlc2MubWF4X2J1Zl9jb3VudDsNCj4gPiArCWNv bnN0IHN0cnVjdCB2NGwyX2Zvcm1hdCAqZm10ID0gJm5vZGUtPnZkZXZfZm10Ow0KPiA+ICsJdW5z aWduZWQgaW50IHNpemU7DQo+ID4gKw0KPiA+ICsJLyogQ2hlY2sgdGhlIGxpbWl0YXRpb24gb2Yg YnVmZmVyIHNpemUgKi8NCj4gPiArCWlmIChtYXhfYnVmZmVyX2NvdW50KQ0KPiA+ICsJCSpudW1f YnVmZmVycyA9IGNsYW1wX3ZhbCgqbnVtX2J1ZmZlcnMsIDEsIG1heF9idWZmZXJfY291bnQpOw0K PiA+ICsNCj4gPiArCWlmIChub2RlLT5kZXNjLnNtZW1fYWxsb2MpDQo+ID4gKwkJdnEtPmRtYV9h dHRycyB8PSBETUFfQVRUUl9OT19LRVJORUxfTUFQUElORzsNCj4gPiArDQo+ID4gKwlpZiAodnEt PnR5cGUgPT0gVjRMMl9CVUZfVFlQRV9NRVRBX09VVFBVVCB8fA0KPiA+ICsJICAgIHZxLT50eXBl ID09IFY0TDJfQlVGX1RZUEVfTUVUQV9DQVBUVVJFKQ0KPiA+ICsJCXNpemUgPSBmbXQtPmZtdC5t ZXRhLmJ1ZmZlcnNpemU7DQo+ID4gKwllbHNlDQo+ID4gKwkJc2l6ZSA9IGZtdC0+Zm10LnBpeF9t cC5wbGFuZV9mbXRbMF0uc2l6ZWltYWdlOw0KPiA+ICsNCj4gPiArCS8qIEFkZCBmb3IgcS5jcmVh dGVfYnVmcyB3aXRoIGZtdC5nX3NpemVpbWFnZShwKSAvIDIgdGVzdCAqLw0KPiA+ICsJaWYgKCpu dW1fcGxhbmVzKSB7DQo+ID4gKwkJaWYgKHNpemVzWzBdIDwgc2l6ZSB8fCAqbnVtX3BsYW5lcyAh PSAxKQ0KPiA+ICsJCQlyZXR1cm4gLUVJTlZBTDsNCj4gPiArCX0gZWxzZSB7DQo+ID4gKwkJKm51 bV9wbGFuZXMgPSAxOw0KPiA+ICsJCXNpemVzWzBdID0gc2l6ZTsNCj4gPiArCX0NCj4gPiArDQo+ ID4gKwlyZXR1cm4gMDsNCj4gPiArfQ0KPiA+ICsNCj4gPiArc3RhdGljIHZvaWQgbXRrX2NhbV92 YjJfcmV0dXJuX2FsbF9idWZmZXJzKHN0cnVjdCBtdGtfY2FtX2RldiAqY2FtLA0KPiA+ICsJCQkJ CSAgIHN0cnVjdCBtdGtfY2FtX3ZpZGVvX2RldmljZSAqbm9kZSwNCj4gPiArCQkJCQkgICBlbnVt IHZiMl9idWZmZXJfc3RhdGUgc3RhdGUpDQo+ID4gK3sNCj4gPiArCXN0cnVjdCBtdGtfY2FtX2Rl dl9idWZmZXIgKmJ1ZiwgKmJ1Zl9wcmV2Ow0KPiA+ICsJdW5zaWduZWQgbG9uZyBmbGFnczsNCj4g PiArDQo+ID4gKwlzcGluX2xvY2tfaXJxc2F2ZSgmbm9kZS0+YnVmX2xpc3RfbG9jaywgZmxhZ3Mp Ow0KPiA+ICsJbGlzdF9mb3JfZWFjaF9lbnRyeV9zYWZlKGJ1ZiwgYnVmX3ByZXYsICZub2RlLT5i dWZfbGlzdCwgbGlzdCkgew0KPiA+ICsJCWxpc3RfZGVsKCZidWYtPmxpc3QpOw0KPiA+ICsJCXZi Ml9idWZmZXJfZG9uZSgmYnVmLT52YmIudmIyX2J1Ziwgc3RhdGUpOw0KPiA+ICsJfQ0KPiA+ICsJ c3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmbm9kZS0+YnVmX2xpc3RfbG9jaywgZmxhZ3MpOw0KPiA+ ICt9DQo+ID4gKw0KPiA+ICtzdGF0aWMgaW50IG10a19jYW1fdmIyX3N0YXJ0X3N0cmVhbWluZyhz dHJ1Y3QgdmIyX3F1ZXVlICp2cSwNCj4gPiArCQkJCSAgICAgICB1bnNpZ25lZCBpbnQgY291bnQp DQo+ID4gK3sNCj4gPiArCXN0cnVjdCBtdGtfY2FtX2RldiAqY2FtID0gdmIyX2dldF9kcnZfcHJp dih2cSk7DQo+ID4gKwlzdHJ1Y3QgbXRrX2NhbV92aWRlb19kZXZpY2UgKm5vZGUgPSBtdGtfY2Ft X3ZicV90b192ZGV2KHZxKTsNCj4gPiArCXN0cnVjdCBkZXZpY2UgKmRldiA9IGNhbS0+ZGV2Ow0K PiA+ICsJaW50IHJldDsNCj4gPiArDQo+ID4gKwlpZiAoIW5vZGUtPmVuYWJsZWQpIHsNCj4gPiAr CQlkZXZfZXJyKGRldiwgIk5vZGU6JWQgaXMgbm90IGVuYWJsZWRcbiIsIG5vZGUtPmlkKTsNCj4g PiArCQlyZXQgPSAtRU5PTElOSzsNCj4gPiArCQlnb3RvIGZhaWxfcmV0X2J1ZjsNCj4gPiArCX0N Cj4gPiArDQo+ID4gKwltdXRleF9sb2NrKCZjYW0tPm9wX2xvY2spOw0KPiA+ICsJLyogU3RhcnQg c3RyZWFtaW5nIG9mIHRoZSB3aG9sZSBwaXBlbGluZSBub3cqLw0KPiA+ICsJaWYgKCFjYW0tPnBp cGVsaW5lLnN0cmVhbWluZ19jb3VudCkgew0KPiANCj4gTm8gbmVlZCBmb3IgdGhpcyBjaGVjaywg dmIyIHdvbid0IGNhbGwgLnN0YXJ0X3N0cmVhbWluZygpIHR3aWNlIHdpdGhvdXQgc3RvcF9zdHJl YW1pbmcoKSBpbiBiZXR3ZWVuLg0KPiANCg0KVGhlIGNoZWNrIGlzIGRlc2lnbmVkIHRvIHN0YXJ0 IHRoZSBtZWRpYSBwaXBlbGluZSB3aGVuIHdlIHN0YXJ0DQpzdHJlYW1pbmcgb24gdGhlIGZpcnN0 IG5vZGUuIFlvdSBjb3VsZCByZWZlciB0aGUgZGV0YWlsIGluIGJlbG93IGxpbmsuDQoNCmh0dHBz Oi8vcGF0Y2h3b3JrLmtlcm5lbC5vcmcvcGF0Y2gvMTA5ODU4MTkvDQoNCg0KPiA+ICsJCXJldCA9 IG1lZGlhX3BpcGVsaW5lX3N0YXJ0KCZub2RlLT52ZGV2LmVudGl0eSwgJmNhbS0+cGlwZWxpbmUp Ow0KPiA+ICsJCWlmIChyZXQpIHsNCj4gPiArCQkJZGV2X2VycihkZXYsICJmYWlsZWQgdG8gc3Rh cnQgcGlwZWxpbmU6JWRcbiIsIHJldCk7DQo+ID4gKwkJCWdvdG8gZmFpbF91bmxvY2s7DQo+ID4g KwkJfQ0KPiA+ICsJCW10a19jYW1fZGV2X2luaXRfc3RyZWFtKGNhbSk7DQo+ID4gKwkJcmV0ID0g bXRrX2lzcF9od19pbml0KGNhbSk7DQo+ID4gKwkJaWYgKHJldCkgew0KPiA+ICsJCQlkZXZfZXJy KGRldiwgImZhaWxlZCB0byBpbml0IEhXOiVkXG4iLCByZXQpOw0KPiA+ICsJCQlnb3RvIGZhaWxf c3RvcF9waXBlbGluZTsNCj4gPiArCQl9DQo+ID4gKwl9DQo+ID4gKw0KPiA+ICsJLyogTWVkaWEg bGlua3MgYXJlIGZpeGVkIGFmdGVyIG1lZGlhX3BpcGVsaW5lX3N0YXJ0ICovDQo+ID4gKwljYW0t PnN0cmVhbV9jb3VudCsrOw0KPiA+ICsJZGV2X2RiZyhkZXYsICIlczogY291bnQgaW5mbzolZDol ZFxuIiwgX19mdW5jX18sIGNhbS0+c3RyZWFtX2NvdW50LA0KPiA+ICsJCWNhbS0+ZW5hYmxlZF9j b3VudCk7DQo+ID4gKwlpZiAoY2FtLT5zdHJlYW1fY291bnQgPCBjYW0tPmVuYWJsZWRfY291bnQp IHsNCj4gPiArCQltdXRleF91bmxvY2soJmNhbS0+b3BfbG9jayk7DQo+ID4gKwkJcmV0dXJuIDA7 DQo+ID4gKwl9DQo+ID4gKw0KPiA+ICsJLyogU3RyZWFtIG9uIHN1Yi1kZXZpY2VzIG5vZGUgKi8N Cj4gPiArCXJldCA9IHY0bDJfc3ViZGV2X2NhbGwoJmNhbS0+c3ViZGV2LCB2aWRlbywgc19zdHJl YW0sIDEpOw0KPiA+ICsJaWYgKHJldCkNCj4gPiArCQlnb3RvIGZhaWxfbm9fc3RyZWFtOw0KPiA+ ICsJbXV0ZXhfdW5sb2NrKCZjYW0tPm9wX2xvY2spOw0KPiA+ICsNCj4gPiArCXJldHVybiAwOw0K PiA+ICsNCj4gPiArZmFpbF9ub19zdHJlYW06DQo+ID4gKwljYW0tPnN0cmVhbV9jb3VudC0tOw0K PiA+ICtmYWlsX3N0b3BfcGlwZWxpbmU6DQo+ID4gKwlpZiAoY2FtLT5zdHJlYW1fY291bnQgPT0g MCkNCj4gPiArCQltZWRpYV9waXBlbGluZV9zdG9wKCZub2RlLT52ZGV2LmVudGl0eSk7DQo+ID4g K2ZhaWxfdW5sb2NrOg0KPiA+ICsJbXV0ZXhfdW5sb2NrKCZjYW0tPm9wX2xvY2spOw0KPiA+ICtm YWlsX3JldF9idWY6DQo+ID4gKwltdGtfY2FtX3ZiMl9yZXR1cm5fYWxsX2J1ZmZlcnMoY2FtLCBu b2RlLCBWQjJfQlVGX1NUQVRFX1FVRVVFRCk7DQo+ID4gKw0KPiA+ICsJcmV0dXJuIHJldDsNCj4g PiArfQ0KPiA+ICsNCj4gPiArc3RhdGljIHZvaWQgbXRrX2NhbV92YjJfc3RvcF9zdHJlYW1pbmco c3RydWN0IHZiMl9xdWV1ZSAqdnEpDQo+ID4gK3sNCj4gPiArCXN0cnVjdCBtdGtfY2FtX2RldiAq Y2FtID0gdmIyX2dldF9kcnZfcHJpdih2cSk7DQo+ID4gKwlzdHJ1Y3QgbXRrX2NhbV92aWRlb19k ZXZpY2UgKm5vZGUgPSBtdGtfY2FtX3ZicV90b192ZGV2KHZxKTsNCj4gPiArCXN0cnVjdCBkZXZp Y2UgKmRldiA9IGNhbS0+ZGV2Ow0KPiA+ICsNCj4gPiArCW11dGV4X2xvY2soJmNhbS0+b3BfbG9j ayk7DQo+ID4gKwlkZXZfZGJnKGRldiwgIiVzIG5vZGU6JWQgY291bnQgaW5mbzolZFxuIiwgX19m dW5jX18sIG5vZGUtPmlkLA0KPiA+ICsJCWNhbS0+c3RyZWFtX2NvdW50KTsNCj4gPiArCS8qIENo ZWNrIHRoZSBmaXJzdCBub2RlIHRvIHN0cmVhbS1vZmYgKi8NCj4gPiArCWlmIChjYW0tPnN0cmVh bV9jb3VudCA9PSBjYW0tPmVuYWJsZWRfY291bnQpDQo+ID4gKwkJdjRsMl9zdWJkZXZfY2FsbCgm Y2FtLT5zdWJkZXYsIHZpZGVvLCBzX3N0cmVhbSwgMCk7DQo+ID4gKw0KPiA+ICsJbXRrX2NhbV92 YjJfcmV0dXJuX2FsbF9idWZmZXJzKGNhbSwgbm9kZSwgVkIyX0JVRl9TVEFURV9FUlJPUik7DQo+ ID4gKwljYW0tPnN0cmVhbV9jb3VudC0tOw0KPiA+ICsJaWYgKGNhbS0+c3RyZWFtX2NvdW50KSB7 DQo+ID4gKwkJbXV0ZXhfdW5sb2NrKCZjYW0tPm9wX2xvY2spOw0KPiA+ICsJCXJldHVybjsNCj4g PiArCX0NCj4gPiArCW11dGV4X3VubG9jaygmY2FtLT5vcF9sb2NrKTsNCj4gPiArDQo+ID4gKwlt dGtfY2FtX2Rldl9yZXFfY2xlYW51cChjYW0pOw0KPiA+ICsJbWVkaWFfcGlwZWxpbmVfc3RvcCgm bm9kZS0+dmRldi5lbnRpdHkpOw0KPiA+ICt9DQo+ID4gKw0KPiA+ICtzdGF0aWMgaW50IG10a19j YW1fdmlkaW9jX3F1ZXJ5Y2FwKHN0cnVjdCBmaWxlICpmaWxlLCB2b2lkICpmaCwNCj4gPiArCQkJ CSAgIHN0cnVjdCB2NGwyX2NhcGFiaWxpdHkgKmNhcCkNCj4gPiArew0KPiA+ICsJc3RydWN0IG10 a19jYW1fZGV2ICpjYW0gPSB2aWRlb19kcnZkYXRhKGZpbGUpOw0KPiA+ICsNCj4gPiArCXN0cnNj cHkoY2FwLT5kcml2ZXIsIGRldl9kcml2ZXJfc3RyaW5nKGNhbS0+ZGV2KSwgc2l6ZW9mKGNhcC0+ ZHJpdmVyKSk7DQo+ID4gKwlzdHJzY3B5KGNhcC0+Y2FyZCwgZGV2X2RyaXZlcl9zdHJpbmcoY2Ft LT5kZXYpLCBzaXplb2YoY2FwLT5jYXJkKSk7DQo+ID4gKwlzbnByaW50ZihjYXAtPmJ1c19pbmZv LCBzaXplb2YoY2FwLT5idXNfaW5mbyksICJwbGF0Zm9ybTolcyIsDQo+ID4gKwkJIGRldl9uYW1l KGNhbS0+ZGV2KSk7DQo+ID4gKw0KPiA+ICsJcmV0dXJuIDA7DQo+ID4gK30NCj4gPiArDQo+ID4g K3N0YXRpYyBpbnQgbXRrX2NhbV92aWRpb2NfZW51bV9mbXQoc3RydWN0IGZpbGUgKmZpbGUsIHZv aWQgKmZoLA0KPiA+ICsJCQkJICAgc3RydWN0IHY0bDJfZm10ZGVzYyAqZikNCj4gPiArew0KPiA+ ICsJc3RydWN0IG10a19jYW1fdmlkZW9fZGV2aWNlICpub2RlID0gZmlsZV90b19tdGtfY2FtX25v ZGUoZmlsZSk7DQo+ID4gKw0KPiA+ICsJaWYgKGYtPmluZGV4ID49IG5vZGUtPmRlc2MubnVtX2Zt dHMpDQo+ID4gKwkJcmV0dXJuIC1FSU5WQUw7DQo+ID4gKw0KPiA+ICsJLyogZi0+ZGVzY3JpcHRp b24gaXMgZmlsbGVkIGluIHY0bF9maWxsX2ZtdGRlc2MgZnVuY3Rpb24gKi8NCj4gPiArCWYtPnBp eGVsZm9ybWF0ID0gbm9kZS0+ZGVzYy5mbXRzW2YtPmluZGV4XS5mbXQucGl4X21wLnBpeGVsZm9y bWF0Ow0KPiA+ICsJZi0+ZmxhZ3MgPSAwOw0KPiA+ICsNCj4gPiArCXJldHVybiAwOw0KPiA+ICt9 DQo+ID4gKw0KPiA+ICtzdGF0aWMgaW50IG10a19jYW1fdmlkaW9jX2dfZm10KHN0cnVjdCBmaWxl ICpmaWxlLCB2b2lkICpmaCwNCj4gPiArCQkJCXN0cnVjdCB2NGwyX2Zvcm1hdCAqZikNCj4gPiAr ew0KPiA+ICsJc3RydWN0IG10a19jYW1fdmlkZW9fZGV2aWNlICpub2RlID0gZmlsZV90b19tdGtf Y2FtX25vZGUoZmlsZSk7DQo+ID4gKw0KPiA+ICsJZi0+Zm10ID0gbm9kZS0+dmRldl9mbXQuZm10 Ow0KPiA+ICsNCj4gPiArCXJldHVybiAwOw0KPiA+ICt9DQo+ID4gKw0KPiA+ICtzdGF0aWMgaW50 IG10a19jYW1fdmlkaW9jX3RyeV9mbXQoc3RydWN0IGZpbGUgKmZpbGUsIHZvaWQgKmZoLA0KPiA+ ICsJCQkJICBzdHJ1Y3QgdjRsMl9mb3JtYXQgKmYpDQo+ID4gK3sNCj4gPiArCXN0cnVjdCBtdGtf Y2FtX2RldiAqY2FtID0gdmlkZW9fZHJ2ZGF0YShmaWxlKTsNCj4gPiArCXN0cnVjdCBtdGtfY2Ft X3ZpZGVvX2RldmljZSAqbm9kZSA9IGZpbGVfdG9fbXRrX2NhbV9ub2RlKGZpbGUpOw0KPiA+ICsJ c3RydWN0IGRldmljZSAqZGV2ID0gY2FtLT5kZXY7DQo+ID4gKwljb25zdCBzdHJ1Y3QgdjRsMl9m b3JtYXQgKmRldl9mbXQ7DQo+ID4gKwlzdHJ1Y3QgdjRsMl9mb3JtYXQgdHJ5X2ZtdDsNCj4gPiAr DQo+ID4gKwltZW1zZXQoJnRyeV9mbXQsIDAsIHNpemVvZih0cnlfZm10KSk7DQo+ID4gKwl0cnlf Zm10LnR5cGUgPSBmLT50eXBlOw0KPiA+ICsNCj4gPiArCS8qIFZhbGlkYXRlIHBpeGVsZm9ybWF0 ICovDQo+ID4gKwlkZXZfZm10ID0gbXRrX2NhbV9kZXZfZmluZF9mbXQoJm5vZGUtPmRlc2MsIGYt PmZtdC5waXhfbXAucGl4ZWxmb3JtYXQpOw0KPiA+ICsJaWYgKCFkZXZfZm10KSB7DQo+ID4gKwkJ ZGV2X2RiZyhkZXYsICJ1bmtub3duIGZtdDolZFxuIiwgZi0+Zm10LnBpeF9tcC5waXhlbGZvcm1h dCk7DQo+ID4gKwkJZGV2X2ZtdCA9ICZub2RlLT5kZXNjLmZtdHNbbm9kZS0+ZGVzYy5kZWZhdWx0 X2ZtdF9pZHhdOw0KPiA+ICsJfQ0KPiA+ICsJdHJ5X2ZtdC5mbXQucGl4X21wLnBpeGVsZm9ybWF0 ID0gZGV2X2ZtdC0+Zm10LnBpeF9tcC5waXhlbGZvcm1hdDsNCj4gPiArDQo+ID4gKwkvKiBWYWxp ZGF0ZSBpbWFnZSB3aWR0aCAmIGhlaWdodCByYW5nZSAqLw0KPiA+ICsJdHJ5X2ZtdC5mbXQucGl4 X21wLndpZHRoID0gY2xhbXBfdmFsKGYtPmZtdC5waXhfbXAud2lkdGgsDQo+ID4gKwkJCQkJICAg ICBJTUdfTUlOX1dJRFRILCBJTUdfTUFYX1dJRFRIKTsNCj4gPiArCXRyeV9mbXQuZm10LnBpeF9t cC5oZWlnaHQgPSBjbGFtcF92YWwoZi0+Zm10LnBpeF9tcC5oZWlnaHQsDQo+ID4gKwkJCQkJICAg ICAgSU1HX01JTl9IRUlHSFQsIElNR19NQVhfSEVJR0hUKTsNCj4gPiArCS8qIDQgYnl0ZXMgYWxp Z25tZW50IGZvciB3aWR0aCAqLw0KPiA+ICsJdHJ5X2ZtdC5mbXQucGl4X21wLndpZHRoID0gQUxJ R04odHJ5X2ZtdC5mbXQucGl4X21wLndpZHRoLCA0KTsNCj4gPiArDQo+ID4gKwkvKiBPbmx5IHN1 cHBvcnQgb25lIHBsYW5lICovDQo+ID4gKwl0cnlfZm10LmZtdC5waXhfbXAubnVtX3BsYW5lcyA9 IDE7DQo+ID4gKw0KPiA+ICsJLyogYnl0ZXNwZXJsaW5lICYgc2l6ZWltYWdlIGNhbGN1bGF0aW9u ICovDQo+ID4gKwljYWxfaW1hZ2VfcGl4X21wKGNhbSwgbm9kZS0+aWQsICZ0cnlfZm10LmZtdC5w aXhfbXApOw0KPiA+ICsNCj4gPiArCS8qIENvbnN0YW50IGZvcm1hdCBmaWVsZHMgKi8NCj4gPiAr CXRyeV9mbXQuZm10LnBpeF9tcC5jb2xvcnNwYWNlID0gVjRMMl9DT0xPUlNQQUNFX1NSR0I7DQo+ ID4gKwl0cnlfZm10LmZtdC5waXhfbXAuZmllbGQgPSBWNEwyX0ZJRUxEX05PTkU7DQo+ID4gKwl0 cnlfZm10LmZtdC5waXhfbXAueWNiY3JfZW5jID0gVjRMMl9ZQ0JDUl9FTkNfREVGQVVMVDsNCj4g PiArCXRyeV9mbXQuZm10LnBpeF9tcC5xdWFudGl6YXRpb24gPSBWNEwyX1FVQU5USVpBVElPTl9E RUZBVUxUOw0KPiA+ICsJdHJ5X2ZtdC5mbXQucGl4X21wLnhmZXJfZnVuYyA9IFY0TDJfWEZFUl9G VU5DX1NSR0I7DQo+ID4gKw0KPiA+ICsJKmYgPSB0cnlfZm10Ow0KPiA+ICsNCj4gPiArCXJldHVy biAwOw0KPiA+ICt9DQo+ID4gKw0KPiA+ICtzdGF0aWMgaW50IG10a19jYW1fdmlkaW9jX3NfZm10 KHN0cnVjdCBmaWxlICpmaWxlLCB2b2lkICpmaCwNCj4gPiArCQkJCXN0cnVjdCB2NGwyX2Zvcm1h dCAqZikNCj4gPiArew0KPiA+ICsJc3RydWN0IG10a19jYW1fZGV2ICpjYW0gPSB2aWRlb19kcnZk YXRhKGZpbGUpOw0KPiA+ICsJc3RydWN0IG10a19jYW1fdmlkZW9fZGV2aWNlICpub2RlID0gZmls ZV90b19tdGtfY2FtX25vZGUoZmlsZSk7DQo+ID4gKw0KPiA+ICsJaWYgKHZiMl9pc19idXN5KG5v ZGUtPnZkZXYucXVldWUpKSB7DQo+ID4gKwkJZGV2X2RiZyhjYW0tPmRldiwgIiVzOiBxdWV1ZSBp cyBidXN5XG4iLCBfX2Z1bmNfXyk7DQo+ID4gKwkJcmV0dXJuIC1FQlVTWTsNCj4gPiArCX0NCj4g PiArDQo+ID4gKwkvKiBHZXQgdGhlIHZhbGlkIGZvcm1hdCAqLw0KPiA+ICsJbXRrX2NhbV92aWRp b2NfdHJ5X2ZtdChmaWxlLCBmaCwgZik7DQo+ID4gKwkvKiBDb25maWd1cmUgdG8gdmlkZW8gZGV2 aWNlICovDQo+ID4gKwlub2RlLT52ZGV2X2ZtdCA9ICpmOw0KPiA+ICsNCj4gPiArCXJldHVybiAw Ow0KPiA+ICt9DQo+ID4gKw0KPiA+ICtzdGF0aWMgaW50IG10a19jYW1fdmlkaW9jX2VudW1fZnJh bWVzaXplcyhzdHJ1Y3QgZmlsZSAqZmlscCwgdm9pZCAqcHJpdiwNCj4gPiArCQkJCQkgIHN0cnVj dCB2NGwyX2ZybXNpemVlbnVtICpzaXplcykNCj4gPiArew0KPiA+ICsJc3RydWN0IG10a19jYW1f dmlkZW9fZGV2aWNlICpub2RlID0gZmlsZV90b19tdGtfY2FtX25vZGUoZmlscCk7DQo+ID4gKwlj b25zdCBzdHJ1Y3QgdjRsMl9mb3JtYXQgKmRldl9mbXQ7DQo+ID4gKw0KPiA+ICsJZGV2X2ZtdCA9 IG10a19jYW1fZGV2X2ZpbmRfZm10KCZub2RlLT5kZXNjLCBzaXplcy0+cGl4ZWxfZm9ybWF0KTsN Cj4gPiArCWlmICghZGV2X2ZtdCB8fCBzaXplcy0+aW5kZXgpDQo+ID4gKwkJcmV0dXJuIC1FSU5W QUw7DQo+ID4gKw0KPiA+ICsJc2l6ZXMtPnR5cGUgPSBub2RlLT5kZXNjLmZybXNpemVzLT50eXBl Ow0KPiA+ICsJbWVtY3B5KCZzaXplcy0+c3RlcHdpc2UsICZub2RlLT5kZXNjLmZybXNpemVzLT5z dGVwd2lzZSwNCj4gPiArCSAgICAgICBzaXplb2Yoc2l6ZXMtPnN0ZXB3aXNlKSk7DQo+ID4gKw0K PiA+ICsJcmV0dXJuIDA7DQo+ID4gK30NCj4gPiArDQo+ID4gK3N0YXRpYyBpbnQgbXRrX2NhbV92 aWRpb2NfbWV0YV9lbnVtX2ZtdChzdHJ1Y3QgZmlsZSAqZmlsZSwgdm9pZCAqZmgsDQo+ID4gKwkJ CQkJc3RydWN0IHY0bDJfZm10ZGVzYyAqZikNCj4gPiArew0KPiA+ICsJc3RydWN0IG10a19jYW1f dmlkZW9fZGV2aWNlICpub2RlID0gZmlsZV90b19tdGtfY2FtX25vZGUoZmlsZSk7DQo+ID4gKw0K PiA+ICsJaWYgKGYtPmluZGV4KQ0KPiA+ICsJCXJldHVybiAtRUlOVkFMOw0KPiA+ICsNCj4gPiAr CS8qIGYtPmRlc2NyaXB0aW9uIGlzIGZpbGxlZCBpbiB2NGxfZmlsbF9mbXRkZXNjIGZ1bmN0aW9u ICovDQo+ID4gKwlmLT5waXhlbGZvcm1hdCA9IG5vZGUtPnZkZXZfZm10LmZtdC5tZXRhLmRhdGFm b3JtYXQ7DQo+ID4gKwlmLT5mbGFncyA9IDA7DQo+ID4gKw0KPiA+ICsJcmV0dXJuIDA7DQo+ID4g K30NCj4gPiArDQo+ID4gK3N0YXRpYyBpbnQgbXRrX2NhbV92aWRpb2NfZ19tZXRhX2ZtdChzdHJ1 Y3QgZmlsZSAqZmlsZSwgdm9pZCAqZmgsDQo+ID4gKwkJCQkgICAgIHN0cnVjdCB2NGwyX2Zvcm1h dCAqZikNCj4gPiArew0KPiA+ICsJc3RydWN0IG10a19jYW1fdmlkZW9fZGV2aWNlICpub2RlID0g ZmlsZV90b19tdGtfY2FtX25vZGUoZmlsZSk7DQo+ID4gKw0KPiA+ICsJZi0+Zm10Lm1ldGEuZGF0 YWZvcm1hdCA9IG5vZGUtPnZkZXZfZm10LmZtdC5tZXRhLmRhdGFmb3JtYXQ7DQo+ID4gKwlmLT5m bXQubWV0YS5idWZmZXJzaXplID0gbm9kZS0+dmRldl9mbXQuZm10Lm1ldGEuYnVmZmVyc2l6ZTsN Cj4gPiArDQo+ID4gKwlyZXR1cm4gMDsNCj4gPiArfQ0KPiA+ICsNCj4gPiArc3RhdGljIGNvbnN0 IHN0cnVjdCB2NGwyX3N1YmRldl9jb3JlX29wcyBtdGtfY2FtX3N1YmRldl9jb3JlX29wcyA9IHsN Cj4gPiArCS5zdWJzY3JpYmVfZXZlbnQgPSBtdGtfY2FtX3NkX3N1YnNjcmliZV9ldmVudCwNCj4g PiArCS51bnN1YnNjcmliZV9ldmVudCA9IHY0bDJfZXZlbnRfc3ViZGV2X3Vuc3Vic2NyaWJlLA0K PiA+ICt9Ow0KPiA+ICsNCj4gPiArc3RhdGljIGNvbnN0IHN0cnVjdCB2NGwyX3N1YmRldl92aWRl b19vcHMgbXRrX2NhbV9zdWJkZXZfdmlkZW9fb3BzID0gew0KPiA+ICsJLnNfc3RyZWFtID0gIG10 a19jYW1fc2Rfc19zdHJlYW0sDQo+ID4gK307DQo+ID4gKw0KPiA+ICtzdGF0aWMgY29uc3Qgc3Ry dWN0IHY0bDJfc3ViZGV2X29wcyBtdGtfY2FtX3N1YmRldl9vcHMgPSB7DQo+ID4gKwkuY29yZSA9 ICZtdGtfY2FtX3N1YmRldl9jb3JlX29wcywNCj4gPiArCS52aWRlbyA9ICZtdGtfY2FtX3N1YmRl dl92aWRlb19vcHMsDQo+ID4gK307DQo+IA0KPiBobW0sIHNpbmNlIHRoaXMgc3ViZGV2aWNlIGlz IGV4cG9zZWQgd2l0aCBWNEwyX1NVQkRFVl9GTF9IQVNfREVWTk9ERSwNCj4gSSB3b25kZXIgaWYg cGFkIG9wcyBzaG91bGRuJ3QgYmUgaW1wbGVtZW50ZWQgdG9vICh0byBiZSB2ZXJpZmllZCkuDQo+ IA0KDQpPaywgSSB3aWxsIGludmVzdGlnYXRlIHRoaXMuDQoNCj4gPiArDQo+ID4gK3N0YXRpYyBj b25zdCBzdHJ1Y3QgbWVkaWFfZW50aXR5X29wZXJhdGlvbnMgbXRrX2NhbV9tZWRpYV9lbnRpdHlf b3BzID0gew0KPiA+ICsJLmxpbmtfc2V0dXAgPSBtdGtfY2FtX21lZGlhX2xpbmtfc2V0dXAsDQo+ ID4gKwkubGlua192YWxpZGF0ZSA9IHY0bDJfc3ViZGV2X2xpbmtfdmFsaWRhdGUsDQo+ID4gK307 DQo+ID4gKw0KPiA+ICtzdGF0aWMgY29uc3Qgc3RydWN0IHZiMl9vcHMgbXRrX2NhbV92YjJfb3Bz ID0gew0KPiA+ICsJLnF1ZXVlX3NldHVwID0gbXRrX2NhbV92YjJfcXVldWVfc2V0dXAsDQo+ID4g Kwkud2FpdF9wcmVwYXJlID0gdmIyX29wc193YWl0X3ByZXBhcmUsDQo+ID4gKwkud2FpdF9maW5p c2ggPSB2YjJfb3BzX3dhaXRfZmluaXNoLA0KPiA+ICsJLmJ1Zl9pbml0ID0gbXRrX2NhbV92YjJf YnVmX2luaXQsDQo+ID4gKwkuYnVmX3ByZXBhcmUgPSBtdGtfY2FtX3ZiMl9idWZfcHJlcGFyZSwN Cj4gPiArCS5zdGFydF9zdHJlYW1pbmcgPSBtdGtfY2FtX3ZiMl9zdGFydF9zdHJlYW1pbmcsDQo+ ID4gKwkuc3RvcF9zdHJlYW1pbmcgPSBtdGtfY2FtX3ZiMl9zdG9wX3N0cmVhbWluZywNCj4gPiAr CS5idWZfcXVldWUgPSBtdGtfY2FtX3ZiMl9idWZfcXVldWUsDQo+ID4gKwkuYnVmX2NsZWFudXAg PSBtdGtfY2FtX3ZiMl9idWZfY2xlYW51cCwNCj4gPiArCS5idWZfcmVxdWVzdF9jb21wbGV0ZSA9 IG10a19jYW1fdmIyX3JlcXVlc3RfY29tcGxldGUsDQo+ID4gK307PiArDQo+ID4gK3N0YXRpYyBj b25zdCBzdHJ1Y3QgdjRsMl9maWxlX29wZXJhdGlvbnMgbXRrX2NhbV92NGwyX2ZvcHMgPSB7DQo+ ID4gKwkudW5sb2NrZWRfaW9jdGwgPSB2aWRlb19pb2N0bDIsDQo+ID4gKwkub3BlbiA9IHY0bDJf Zmhfb3BlbiwNCj4gPiArCS5yZWxlYXNlID0gdmIyX2ZvcF9yZWxlYXNlLA0KPiA+ICsJLnBvbGwg PSB2YjJfZm9wX3BvbGwsDQo+ID4gKwkubW1hcCA9IHZiMl9mb3BfbW1hcCwNCj4gPiArI2lmZGVm IENPTkZJR19DT01QQVQNCj4gPiArCS5jb21wYXRfaW9jdGwzMiA9IHY0bDJfY29tcGF0X2lvY3Rs MzIsDQo+ID4gKyNlbmRpZg0KPiA+ICt9Ow0KPiA+ICsNCj4gPiArc3RhdGljIGNvbnN0IHN0cnVj dCBtZWRpYV9kZXZpY2Vfb3BzIG10a19jYW1fbWVkaWFfb3BzID0gew0KPiA+ICsJLnJlcV9hbGxv YyA9IG10a19jYW1fcmVxX2FsbG9jLA0KPiA+ICsJLnJlcV9mcmVlID0gbXRrX2NhbV9yZXFfZnJl ZSwNCj4gPiArCS5yZXFfdmFsaWRhdGUgPSB2YjJfcmVxdWVzdF92YWxpZGF0ZSwNCj4gPiArCS5y ZXFfcXVldWUgPSBtdGtfY2FtX3JlcV9xdWV1ZSwNCj4gPiArfTsNCj4gPiArDQo+ID4gK3N0YXRp YyBpbnQgbXRrX2NhbV9tZWRpYV9yZWdpc3RlcihzdHJ1Y3QgbXRrX2NhbV9kZXYgKmNhbSwNCj4g PiArCQkJCSAgc3RydWN0IG1lZGlhX2RldmljZSAqbWVkaWFfZGV2KQ0KPiA+ICt7DQo+ID4gKwkv KiBSZXNlcnZlZCBNVEtfQ0FNX0NJT19QQURfU0lOSyArIDEgcGFkcyB0byB1c2UgKi8NCj4gPiAr CXVuc2lnbmVkIGludCBudW1fcGFkcyA9IE1US19DQU1fQ0lPX1BBRF9TSU5LICsgMTsNCj4gPiAr CXN0cnVjdCBkZXZpY2UgKmRldiA9IGNhbS0+ZGV2Ow0KPiA+ICsJaW50IGksIHJldDsNCj4gPiAr DQo+ID4gKwltZWRpYV9kZXYtPmRldiA9IGNhbS0+ZGV2Ow0KPiA+ICsJc3Ryc2NweShtZWRpYV9k ZXYtPm1vZGVsLCBkZXZfZHJpdmVyX3N0cmluZyhkZXYpLA0KPiA+ICsJCXNpemVvZihtZWRpYV9k ZXYtPm1vZGVsKSk7DQo+ID4gKwlzbnByaW50ZihtZWRpYV9kZXYtPmJ1c19pbmZvLCBzaXplb2Yo bWVkaWFfZGV2LT5idXNfaW5mbyksDQo+ID4gKwkJICJwbGF0Zm9ybTolcyIsIGRldl9uYW1lKGRl dikpOw0KPiA+ICsJbWVkaWFfZGV2LT5od19yZXZpc2lvbiA9IDA7DQo+ID4gKwltZWRpYV9kZXZp Y2VfaW5pdChtZWRpYV9kZXYpOw0KPiA+ICsJbWVkaWFfZGV2LT5vcHMgPSAmbXRrX2NhbV9tZWRp YV9vcHM7DQo+ID4gKw0KPiA+ICsJcmV0ID0gbWVkaWFfZGV2aWNlX3JlZ2lzdGVyKG1lZGlhX2Rl dik7DQo+ID4gKwlpZiAocmV0KSB7DQo+ID4gKwkJZGV2X2VycihkZXYsICJmYWlsZWQgdG8gcmVn aXN0ZXIgbWVkaWEgZGV2aWNlOiVkXG4iLCByZXQpOw0KPiA+ICsJCXJldHVybiByZXQ7DQo+ID4g Kwl9DQo+ID4gKw0KPiA+ICsJLyogSW5pdGlhbGl6ZSBzdWJkZXYgcGFkcyAqLw0KPiA+ICsJY2Ft LT5zdWJkZXZfcGFkcyA9IGRldm1fa2NhbGxvYyhkZXYsIG51bV9wYWRzLA0KPiA+ICsJCQkJCXNp emVvZigqY2FtLT5zdWJkZXZfcGFkcyksDQo+ID4gKwkJCQkJR0ZQX0tFUk5FTCk7DQo+ID4gKwlp ZiAoIWNhbS0+c3ViZGV2X3BhZHMpIHsNCj4gPiArCQlkZXZfZXJyKGRldiwgImZhaWxlZCB0byBh bGxvY2F0ZSBzdWJkZXZfcGFkc1xuIik7DQo+ID4gKwkJcmV0ID0gLUVOT01FTTsNCj4gPiArCQln b3RvIGZhaWxfbWVkaWFfdW5yZWc7DQo+ID4gKwl9DQo+ID4gKw0KPiA+ICsJcmV0ID0gbWVkaWFf ZW50aXR5X3BhZHNfaW5pdCgmY2FtLT5zdWJkZXYuZW50aXR5LCBudW1fcGFkcywNCj4gPiArCQkJ CSAgICAgY2FtLT5zdWJkZXZfcGFkcyk7DQo+ID4gKwlpZiAocmV0KSB7DQo+ID4gKwkJZGV2X2Vy cihkZXYsICJmYWlsZWQgdG8gaW5pdGlhbGl6ZSBtZWRpYSBwYWRzOiVkXG4iLCByZXQpOw0KPiA+ ICsJCWdvdG8gZmFpbF9tZWRpYV91bnJlZzsNCj4gPiArCX0NCj4gPiArDQo+ID4gKwkvKiBJbml0 aWFsaXplIGFsbCBwYWRzIHdpdGggTUVESUFfUEFEX0ZMX1NPVVJDRSAqLw0KPiA+ICsJZm9yIChp ID0gMDsgaSA8IG51bV9wYWRzOyBpKyspDQo+ID4gKwkJY2FtLT5zdWJkZXZfcGFkc1tpXS5mbGFn cyA9IE1FRElBX1BBRF9GTF9TT1VSQ0U7DQo+ID4gKw0KPiA+ICsJLyogQ3VzdG9taXplIHRoZSBs YXN0IG9uZSBwYWQgYXMgQ0lPIHNpbmsgcGFkLiAqLw0KPiA+ICsJY2FtLT5zdWJkZXZfcGFkc1tN VEtfQ0FNX0NJT19QQURfU0lOS10uZmxhZ3MgPSBNRURJQV9QQURfRkxfU0lOSzsNCj4gPiArDQo+ ID4gKwlyZXR1cm4gMDsNCj4gPiArDQo+ID4gK2ZhaWxfbWVkaWFfdW5yZWc6DQo+ID4gKwltZWRp YV9kZXZpY2VfdW5yZWdpc3RlcigmY2FtLT5tZWRpYV9kZXYpOw0KPiA+ICsJbWVkaWFfZGV2aWNl X2NsZWFudXAoJmNhbS0+bWVkaWFfZGV2KTsNCj4gPiArDQo+ID4gKwlyZXR1cm4gcmV0Ow0KPiA+ ICt9DQo+ID4gKw0KPiA+ICtzdGF0aWMgaW50DQo+ID4gK210a19jYW1fdmlkZW9fcmVnaXN0ZXJf ZGV2aWNlKHN0cnVjdCBtdGtfY2FtX2RldiAqY2FtLA0KPiA+ICsJCQkgICAgICBzdHJ1Y3QgbXRr X2NhbV92aWRlb19kZXZpY2UgKm5vZGUpDQo+ID4gK3sNCj4gPiArCXN0cnVjdCBkZXZpY2UgKmRl diA9IGNhbS0+ZGV2Ow0KPiA+ICsJc3RydWN0IHZpZGVvX2RldmljZSAqdmRldiA9ICZub2RlLT52 ZGV2Ow0KPiA+ICsJc3RydWN0IHZiMl9xdWV1ZSAqdmJxID0gJm5vZGUtPnZicTsNCj4gPiArCXVu c2lnbmVkIGludCBvdXRwdXQgPSBWNEwyX1RZUEVfSVNfT1VUUFVUKG5vZGUtPmRlc2MuYnVmX3R5 cGUpOw0KPiA+ICsJdW5zaWduZWQgaW50IGxpbmtfZmxhZ3MgPSBub2RlLT5kZXNjLmxpbmtfZmxh Z3M7DQo+ID4gKwlpbnQgcmV0Ow0KPiA+ICsNCj4gPiArCS8qIEluaXRpYWxpemUgbXRrX2NhbV92 aWRlb19kZXZpY2UgKi8NCj4gPiArCWlmIChsaW5rX2ZsYWdzICYgTUVESUFfTE5LX0ZMX0lNTVVU QUJMRSkNCj4gPiArCQlub2RlLT5lbmFibGVkID0gdHJ1ZTsNCj4gPiArCWVsc2UNCj4gPiArCQlu b2RlLT5lbmFibGVkID0gZmFsc2U7DQo+ID4gKwltdGtfY2FtX2Rldl9sb2FkX2RlZmF1bHRfZm10 KGNhbSwgJm5vZGUtPmRlc2MsICZub2RlLT52ZGV2X2ZtdCk7DQo+ID4gKw0KPiA+ICsJY2FtLT5z dWJkZXZfcGFkc1tub2RlLT5pZF0uZmxhZ3MgPSBvdXRwdXQgPw0KPiA+ICsJCU1FRElBX1BBRF9G TF9TSU5LIDogTUVESUFfUEFEX0ZMX1NPVVJDRTsNCj4gPiArDQo+ID4gKwkvKiBJbml0aWFsaXpl IG1lZGlhIGVudGl0aWVzICovDQo+ID4gKwlyZXQgPSBtZWRpYV9lbnRpdHlfcGFkc19pbml0KCZ2 ZGV2LT5lbnRpdHksIDEsICZub2RlLT52ZGV2X3BhZCk7DQo+ID4gKwlpZiAocmV0KSB7DQo+ID4g KwkJZGV2X2VycihkZXYsICJmYWlsZWQgdG8gaW5pdGlhbGl6ZSBtZWRpYSBwYWQ6JWRcbiIsIHJl dCk7DQo+ID4gKwkJcmV0dXJuIHJldDsNCj4gPiArCX0NCj4gPiArCW5vZGUtPnZkZXZfcGFkLmZs YWdzID0gb3V0cHV0ID8gTUVESUFfUEFEX0ZMX1NPVVJDRSA6IE1FRElBX1BBRF9GTF9TSU5LOw0K PiA+ICsNCj4gPiArCS8qIEluaXRpYWxpemUgdmJxICovDQo+ID4gKwl2YnEtPnR5cGUgPSBub2Rl LT5kZXNjLmJ1Zl90eXBlOw0KPiA+ICsJaWYgKHZicS0+dHlwZSA9PSBWNEwyX0JVRl9UWVBFX01F VEFfT1VUUFVUKQ0KPiA+ICsJCXZicS0+aW9fbW9kZXMgPSBWQjJfTU1BUDsNCj4gPiArCWVsc2UN Cj4gPiArCQl2YnEtPmlvX21vZGVzID0gVkIyX01NQVAgfCBWQjJfRE1BQlVGOw0KPiA+ICsNCj4g PiArCWlmIChub2RlLT5kZXNjLnNtZW1fYWxsb2MpIHsNCj4gPiArCQl2YnEtPmJpZGlyZWN0aW9u YWwgPSAxOw0KPiA+ICsJCXZicS0+ZGV2ID0gY2FtLT5zbWVtX2RldjsNCj4gPiArCX0gZWxzZSB7 DQo+ID4gKwkJdmJxLT5kZXYgPSBkZXY7DQo+ID4gKwl9DQo+ID4gKwl2YnEtPm9wcyA9ICZtdGtf Y2FtX3ZiMl9vcHM7DQo+ID4gKwl2YnEtPm1lbV9vcHMgPSAmdmIyX2RtYV9jb250aWdfbWVtb3Bz Ow0KPiA+ICsJdmJxLT5idWZfc3RydWN0X3NpemUgPSBzaXplb2Yoc3RydWN0IG10a19jYW1fZGV2 X2J1ZmZlcik7DQo+ID4gKwl2YnEtPnRpbWVzdGFtcF9mbGFncyA9IFY0TDJfQlVGX0ZMQUdfVElN RVNUQU1QX0JPT1RJTUU7DQo+ID4gKwlpZiAob3V0cHV0KQ0KPiA+ICsJCXZicS0+dGltZXN0YW1w X2ZsYWdzIHw9IFY0TDJfQlVGX0ZMQUdfVFNUQU1QX1NSQ19FT0Y7DQo+ID4gKwllbHNlDQo+ID4g KwkJdmJxLT50aW1lc3RhbXBfZmxhZ3MgfD0gVjRMMl9CVUZfRkxBR19UU1RBTVBfU1JDX1NPRTsN Cj4gPiArCS8qIE5vIG1pbmltdW0gYnVmZmVycyBsaW1pdGF0aW9uICovDQo+ID4gKwl2YnEtPm1p bl9idWZmZXJzX25lZWRlZCA9IDA7DQo+ID4gKwl2YnEtPmRydl9wcml2ID0gY2FtOw0KPiA+ICsJ dmJxLT5sb2NrID0gJm5vZGUtPnZkZXZfbG9jazsNCj4gPiArCXZicS0+c3VwcG9ydHNfcmVxdWVz dHMgPSB0cnVlOw0KPiA+ICsJdmJxLT5yZXF1aXJlc19yZXF1ZXN0cyA9IHRydWU7DQo+ID4gKw0K PiA+ICsJcmV0ID0gdmIyX3F1ZXVlX2luaXQodmJxKTsNCj4gPiArCWlmIChyZXQpIHsNCj4gPiAr CQlkZXZfZXJyKGRldiwgImZhaWxlZCB0byBpbml0LiB2YjIgcXVldWU6JWRcbiIsIHJldCk7DQo+ ID4gKwkJZ290byBmYWlsX21lZGlhX2NsZWFuOw0KPiA+ICsJfQ0KPiA+ICsNCj4gPiArCS8qIElu aXRpYWxpemUgdmRldiAqLw0KPiA+ICsJc25wcmludGYodmRldi0+bmFtZSwgc2l6ZW9mKHZkZXYt Pm5hbWUpLCAiJXMgJXMiLA0KPiA+ICsJCSBkZXZfZHJpdmVyX3N0cmluZyhkZXYpLCBub2RlLT5k ZXNjLm5hbWUpOw0KPiA+ICsJLyogc2V0IGNhcC90eXBlL2lvY3RsX29wcyBvZiB0aGUgdmlkZW8g ZGV2aWNlICovDQo+ID4gKwl2ZGV2LT5kZXZpY2VfY2FwcyA9IG5vZGUtPmRlc2MuY2FwIHwgVjRM Ml9DQVBfU1RSRUFNSU5HOw0KPiA+ICsJdmRldi0+aW9jdGxfb3BzID0gbm9kZS0+ZGVzYy5pb2N0 bF9vcHM7DQo+ID4gKwl2ZGV2LT5mb3BzID0gJm10a19jYW1fdjRsMl9mb3BzOw0KPiA+ICsJdmRl di0+cmVsZWFzZSA9IHZpZGVvX2RldmljZV9yZWxlYXNlX2VtcHR5Ow0KPiA+ICsJdmRldi0+bG9j ayA9ICZub2RlLT52ZGV2X2xvY2s7DQo+ID4gKwl2ZGV2LT52NGwyX2RldiA9ICZjYW0tPnY0bDJf ZGV2Ow0KPiA+ICsJdmRldi0+cXVldWUgPSAmbm9kZS0+dmJxOw0KPiA+ICsJdmRldi0+dmZsX2Rp ciA9IG91dHB1dCA/IFZGTF9ESVJfVFggOiBWRkxfRElSX1JYOw0KPiA+ICsJdmRldi0+ZW50aXR5 LmZ1bmN0aW9uID0gTUVESUFfRU5UX0ZfSU9fVjRMOw0KPiA+ICsJdmRldi0+ZW50aXR5Lm9wcyA9 IE5VTEw7DQo+ID4gKwl2aWRlb19zZXRfZHJ2ZGF0YSh2ZGV2LCBjYW0pOw0KPiA+ICsJZGV2X2Ri ZyhkZXYsICJyZWdpc3RlcmVkIHZkZXY6JWQ6JXNcbiIsIG5vZGUtPmlkLCB2ZGV2LT5uYW1lKTsN Cj4gPiArDQo+ID4gKwkvKiBJbml0aWFsaXplIG1pc2NlbGxhbmVvdXMgdmFyaWFibGVzICovDQo+ ID4gKwltdXRleF9pbml0KCZub2RlLT52ZGV2X2xvY2spOw0KPiA+ICsJSU5JVF9MSVNUX0hFQUQo Jm5vZGUtPmJ1Zl9saXN0KTsNCj4gPiArCXNwaW5fbG9ja19pbml0KCZub2RlLT5idWZfbGlzdF9s b2NrKTsNCj4gPiArDQo+ID4gKwlyZXQgPSB2aWRlb19yZWdpc3Rlcl9kZXZpY2UodmRldiwgVkZM X1RZUEVfR1JBQkJFUiwgLTEpOw0KPiA+ICsJaWYgKHJldCkgew0KPiA+ICsJCWRldl9lcnIoZGV2 LCAiZmFpbGVkIHRvIHJlZ2lzdGVyIHZkZTolZFxuIiwgcmV0KTsNCj4gPiArCQlnb3RvIGZhaWxf dmIyX3JlbDsNCj4gPiArCX0NCj4gPiArDQo+ID4gKwkvKiBDcmVhdGUgbGluayBiZXR3ZWVuIHZp ZGVvIG5vZGUgYW5kIHRoZSBzdWJkZXYgcGFkICovDQo+ID4gKwlpZiAob3V0cHV0KSB7DQo+ID4g KwkJcmV0ID0gbWVkaWFfY3JlYXRlX3BhZF9saW5rKCZ2ZGV2LT5lbnRpdHksIDAsDQo+ID4gKwkJ CQkJICAgICZjYW0tPnN1YmRldi5lbnRpdHksDQo+ID4gKwkJCQkJICAgIG5vZGUtPmlkLCBsaW5r X2ZsYWdzKTsNCj4gPiArCX0gZWxzZSB7DQo+ID4gKwkJcmV0ID0gbWVkaWFfY3JlYXRlX3BhZF9s aW5rKCZjYW0tPnN1YmRldi5lbnRpdHksDQo+ID4gKwkJCQkJICAgIG5vZGUtPmlkLCAmdmRldi0+ ZW50aXR5LCAwLA0KPiA+ICsJCQkJCSAgICBsaW5rX2ZsYWdzKTsNCj4gPiArCX0NCj4gDQo+IE5v IG5lZWQgZm9yIHRoZSBjdXJseSBicmFjZXMuDQo+IA0KDQpSZXZpc2VkIGluIG5leHQgcGF0Y2gu DQoNCj4gPiArCWlmIChyZXQpDQo+ID4gKwkJZ290byBmYWlsX3ZkZXZfdXJlZzsNCj4gPiArDQo+ ID4gKwlyZXR1cm4gMDsNCj4gPiArDQo+ID4gK2ZhaWxfdmRldl91cmVnOg0KPiA+ICsJdmlkZW9f dW5yZWdpc3Rlcl9kZXZpY2UodmRldik7DQo+ID4gK2ZhaWxfdmIyX3JlbDoNCj4gPiArCW11dGV4 X2Rlc3Ryb3koJm5vZGUtPnZkZXZfbG9jayk7DQo+ID4gKwl2YjJfcXVldWVfcmVsZWFzZSh2YnEp Ow0KPiA+ICtmYWlsX21lZGlhX2NsZWFuOg0KPiA+ICsJbWVkaWFfZW50aXR5X2NsZWFudXAoJnZk ZXYtPmVudGl0eSk7DQo+ID4gKw0KPiA+ICsJcmV0dXJuIHJldDsNCj4gPiArfQ0KPiA+ICsNCj4g PiArc3RhdGljIHZvaWQNCj4gPiArbXRrX2NhbV92aWRlb191bnJlZ2lzdGVyX2RldmljZShzdHJ1 Y3QgbXRrX2NhbV92aWRlb19kZXZpY2UgKm5vZGUpDQo+ID4gK3sNCj4gPiArCXZpZGVvX3VucmVn aXN0ZXJfZGV2aWNlKCZub2RlLT52ZGV2KTsNCj4gPiArCXZiMl9xdWV1ZV9yZWxlYXNlKCZub2Rl LT52YnEpOw0KPiA+ICsJbWVkaWFfZW50aXR5X2NsZWFudXAoJm5vZGUtPnZkZXYuZW50aXR5KTsN Cj4gPiArCW11dGV4X2Rlc3Ryb3koJm5vZGUtPnZkZXZfbG9jayk7DQo+ID4gK30NCj4gPiArDQo+ ID4gK3N0YXRpYyBpbnQgbXRrX2NhbV92NGwyX3JlZ2lzdGVyKHN0cnVjdCBtdGtfY2FtX2RldiAq Y2FtKQ0KPiA+ICt7DQo+ID4gKwlzdHJ1Y3QgZGV2aWNlICpkZXYgPSBjYW0tPmRldjsNCj4gPiAr CWludCBpLCByZXQ7DQo+ID4gKw0KPiA+ICsJLyogU2V0IHVwIG1lZGlhIGRldmljZSAmIHBhZHMg Ki8NCj4gPiArCXJldCA9IG10a19jYW1fbWVkaWFfcmVnaXN0ZXIoY2FtLCAmY2FtLT5tZWRpYV9k ZXYpOw0KPiA+ICsJaWYgKHJldCkNCj4gPiArCQlyZXR1cm4gcmV0Ow0KPiA+ICsJZGV2X2luZm8o ZGV2LCAiUmVnaXN0ZXJlZCBtZWRpYSVkXG4iLCBjYW0tPm1lZGlhX2Rldi5kZXZub2RlLT5taW5v cik7DQo+ID4gKw0KPiA+ICsJLyogU2V0IHVwIHY0bDIgZGV2aWNlICovDQo+ID4gKwljYW0tPnY0 bDJfZGV2Lm1kZXYgPSAmY2FtLT5tZWRpYV9kZXY7DQo+ID4gKwlyZXQgPSB2NGwyX2RldmljZV9y ZWdpc3RlcihkZXYsICZjYW0tPnY0bDJfZGV2KTsNCj4gPiArCWlmIChyZXQpIHsNCj4gPiArCQlk ZXZfZXJyKGRldiwgImZhaWxlZCB0byByZWdpc3RlciBWNEwyIGRldmljZTolZFxuIiwgcmV0KTsN Cj4gPiArCQlnb3RvIGZhaWxfbWVkaWFfdW5yZWc7DQo+ID4gKwl9DQo+ID4gKwlkZXZfaW5mbyhk ZXYsICJSZWdpc3RlcmVkICVzXG4iLCBjYW0tPnY0bDJfZGV2Lm5hbWUpOw0KPiA+ICsNCj4gPiAr CS8qIEluaXRpYWxpemUgc3ViZGV2ICovDQo+ID4gKwl2NGwyX3N1YmRldl9pbml0KCZjYW0tPnN1 YmRldiwgJm10a19jYW1fc3ViZGV2X29wcyk7DQo+ID4gKwljYW0tPnN1YmRldi5lbnRpdHkuZnVu Y3Rpb24gPSBNRURJQV9FTlRfRl9QUk9DX1ZJREVPX1BJWEVMX0ZPUk1BVFRFUjsNCj4gPiArCWNh bS0+c3ViZGV2LmVudGl0eS5vcHMgPSAmbXRrX2NhbV9tZWRpYV9lbnRpdHlfb3BzOw0KPiA+ICsJ Y2FtLT5zdWJkZXYuZmxhZ3MgPSBWNEwyX1NVQkRFVl9GTF9IQVNfREVWTk9ERSB8DQo+ID4gKwkJ CQlWNEwyX1NVQkRFVl9GTF9IQVNfRVZFTlRTOw0KPiA+ICsJc25wcmludGYoY2FtLT5zdWJkZXYu bmFtZSwgc2l6ZW9mKGNhbS0+c3ViZGV2Lm5hbWUpLA0KPiA+ICsJCSAiJXMiLCBkZXZfZHJpdmVy X3N0cmluZyhkZXYpKTsNCj4gPiArCXY0bDJfc2V0X3N1YmRldmRhdGEoJmNhbS0+c3ViZGV2LCBj YW0pOw0KPiA+ICsNCj4gPiArCXJldCA9IHY0bDJfZGV2aWNlX3JlZ2lzdGVyX3N1YmRldigmY2Ft LT52NGwyX2RldiwgJmNhbS0+c3ViZGV2KTsNCj4gPiArCWlmIChyZXQpIHsNCj4gPiArCQlkZXZf ZXJyKGRldiwgImZhaWxlZCB0byBpbml0aWFsaXplIHN1YmRldjolZFxuIiwgcmV0KTsNCj4gPiAr CQlnb3RvIGZhaWxfY2xlYW5fbWVkaWFfZW50aXk7DQo+ID4gKwl9DQo+ID4gKwlkZXZfZGJnKGRl diwgInJlZ2lzdGVyZWQgJXNcbiIsIGNhbS0+c3ViZGV2Lm5hbWUpOw0KPiA+ICsNCj4gPiArCS8q IENyZWF0ZSB2aWRlbyBub2RlcyBhbmQgbGlua3MgKi8NCj4gPiArCWZvciAoaSA9IDA7IGkgPCBN VEtfQ0FNX1AxX1RPVEFMX05PREVTOyBpKyspIHsNCj4gPiArCQlzdHJ1Y3QgbXRrX2NhbV92aWRl b19kZXZpY2UgKm5vZGUgPSAmY2FtLT52ZGV2X25vZGVzW2ldOw0KPiA+ICsNCj4gPiArCQlub2Rl LT5pZCA9IG5vZGUtPmRlc2MuaWQ7DQo+ID4gKwkJcmV0ID0gbXRrX2NhbV92aWRlb19yZWdpc3Rl cl9kZXZpY2UoY2FtLCBub2RlKTsNCj4gPiArCQlpZiAocmV0KQ0KPiA+ICsJCQlnb3RvIGZhaWxf dmRldl91bnJlZzsNCj4gPiArCX0NCj4gPiArCXZiMl9kbWFfY29udGlnX3NldF9tYXhfc2VnX3Np emUoZGV2LCBETUFfQklUX01BU0soMzIpKTsNCj4gPiArDQo+ID4gKwlyZXR1cm4gMDsNCj4gPiAr DQo+ID4gK2ZhaWxfdmRldl91bnJlZzoNCj4gPiArCWZvciAoaS0tOyBpID49IDA7IGktLSkNCj4g PiArCQltdGtfY2FtX3ZpZGVvX3VucmVnaXN0ZXJfZGV2aWNlKCZjYW0tPnZkZXZfbm9kZXNbaV0p Ow0KPiA+ICtmYWlsX2NsZWFuX21lZGlhX2VudGl5Og0KPiA+ICsJbWVkaWFfZW50aXR5X2NsZWFu dXAoJmNhbS0+c3ViZGV2LmVudGl0eSk7DQo+ID4gKwl2NGwyX2RldmljZV91bnJlZ2lzdGVyKCZj YW0tPnY0bDJfZGV2KTsNCj4gPiArZmFpbF9tZWRpYV91bnJlZzoNCj4gPiArCW1lZGlhX2Rldmlj ZV91bnJlZ2lzdGVyKCZjYW0tPm1lZGlhX2Rldik7DQo+ID4gKwltZWRpYV9kZXZpY2VfY2xlYW51 cCgmY2FtLT5tZWRpYV9kZXYpOw0KPiA+ICsNCj4gPiArCXJldHVybiByZXQ7DQo+ID4gK30NCj4g PiArDQo+ID4gK3N0YXRpYyBpbnQgbXRrX2NhbV92NGwyX3VucmVnaXN0ZXIoc3RydWN0IG10a19j YW1fZGV2ICpjYW0pDQo+ID4gK3sNCj4gPiArCWludCBpOw0KPiA+ICsNCj4gPiArCWZvciAoaSA9 IDA7IGkgPCBNVEtfQ0FNX1AxX1RPVEFMX05PREVTOyBpKyspDQo+ID4gKwkJbXRrX2NhbV92aWRl b191bnJlZ2lzdGVyX2RldmljZSgmY2FtLT52ZGV2X25vZGVzW2ldKTsNCj4gPiArDQo+ID4gKwl2 YjJfZG1hX2NvbnRpZ19jbGVhcl9tYXhfc2VnX3NpemUoY2FtLT5kZXYpOw0KPiA+ICsJdjRsMl9k ZXZpY2VfdW5yZWdpc3Rlcl9zdWJkZXYoJmNhbS0+c3ViZGV2KTsNCj4gPiArCXY0bDJfZGV2aWNl X3VucmVnaXN0ZXIoJmNhbS0+djRsMl9kZXYpOw0KPiA+ICsJbWVkaWFfZW50aXR5X2NsZWFudXAo JmNhbS0+c3ViZGV2LmVudGl0eSk7DQo+ID4gKwltZWRpYV9kZXZpY2VfdW5yZWdpc3RlcigmY2Ft LT5tZWRpYV9kZXYpOw0KPiA+ICsJbWVkaWFfZGV2aWNlX2NsZWFudXAoJmNhbS0+bWVkaWFfZGV2 KTsNCj4gPiArDQo+ID4gKwlyZXR1cm4gMDsNCj4gPiArfQ0KPiA+ICsNCj4gPiArc3RhdGljIGlu dCBtdGtfY2FtX2Rldl9ub3RpZmllcl9ib3VuZChzdHJ1Y3QgdjRsMl9hc3luY19ub3RpZmllciAq bm90aWZpZXIsDQo+ID4gKwkJCQkgICAgICBzdHJ1Y3QgdjRsMl9zdWJkZXYgKnNkLA0KPiA+ICsJ CQkJICAgICAgc3RydWN0IHY0bDJfYXN5bmNfc3ViZGV2ICphc2QpDQo+ID4gK3sNCj4gPiArCXN0 cnVjdCBtdGtfY2FtX2RldiAqY2FtID0NCj4gPiArCQljb250YWluZXJfb2Yobm90aWZpZXIsIHN0 cnVjdCBtdGtfY2FtX2Rldiwgbm90aWZpZXIpOw0KPiA+ICsNCj4gPiArCWlmICghKHNkLT5lbnRp dHkuZnVuY3Rpb24gJiBNRURJQV9FTlRfRl9WSURfSUZfQlJJREdFKSkgew0KPiA+ICsJCWRldl9k YmcoY2FtLT5kZXYsICJubyBNRURJQV9FTlRfRl9WSURfSUZfQlJJREdFIGZ1bmN0aW9uXG4iKTsN Cj4gPiArCQlyZXR1cm4gLUVOT0RFVjsNCj4gPiArCX0NCj4gPiArDQo+ID4gKwljYW0tPnNlbmlu ZiA9IHNkOw0KPiA+ICsJZGV2X2RiZyhjYW0tPmRldiwgIiVzIGlzIGJvdW5kXG4iLCBzZC0+ZW50 aXR5Lm5hbWUpOw0KPiA+ICsNCj4gPiArCXJldHVybiAwOw0KPiA+ICt9DQo+ID4gKw0KPiA+ICtz dGF0aWMgdm9pZCBtdGtfY2FtX2Rldl9ub3RpZmllcl91bmJpbmQoc3RydWN0IHY0bDJfYXN5bmNf bm90aWZpZXIgKm5vdGlmaWVyLA0KPiA+ICsJCQkJCXN0cnVjdCB2NGwyX3N1YmRldiAqc2QsDQo+ ID4gKwkJCQkJc3RydWN0IHY0bDJfYXN5bmNfc3ViZGV2ICphc2QpDQo+ID4gK3sNCj4gPiArCXN0 cnVjdCBtdGtfY2FtX2RldiAqY2FtID0NCj4gPiArCQljb250YWluZXJfb2Yobm90aWZpZXIsIHN0 cnVjdCBtdGtfY2FtX2Rldiwgbm90aWZpZXIpOw0KPiA+ICsNCj4gPiArCWNhbS0+c2VuaW5mID0g TlVMTDsNCj4gPiArCWRldl9kYmcoY2FtLT5kZXYsICIlcyBpcyB1bmJvdW5kXG4iLCBzZC0+ZW50 aXR5Lm5hbWUpOw0KPiA+ICt9DQo+ID4gKw0KPiA+ICtzdGF0aWMgaW50IG10a19jYW1fZGV2X25v dGlmaWVyX2NvbXBsZXRlKHN0cnVjdCB2NGwyX2FzeW5jX25vdGlmaWVyICpub3RpZmllcikNCj4g PiArew0KPiA+ICsJc3RydWN0IG10a19jYW1fZGV2ICpjYW0gPQ0KPiA+ICsJCWNvbnRhaW5lcl9v Zihub3RpZmllciwgc3RydWN0IG10a19jYW1fZGV2LCBub3RpZmllcik7DQo+ID4gKwlzdHJ1Y3Qg ZGV2aWNlICpkZXYgPSBjYW0tPmRldjsNCj4gPiArCWludCByZXQ7DQo+ID4gKw0KPiA+ICsJaWYg KCFjYW0tPnNlbmluZikgew0KPiA+ICsJCWRldl9lcnIoZGV2LCAiTm8gc2VuaW5mIHN1YmRldlxu Iik7DQo+ID4gKwkJcmV0dXJuIC1FTk9ERVY7DQo+ID4gKwl9DQo+ID4gKw0KPiA+ICsJcmV0ID0g bWVkaWFfY3JlYXRlX3BhZF9saW5rKCZjYW0tPnNlbmluZi0+ZW50aXR5LCBNVEtfQ0FNX0NJT19Q QURfU1JDLA0KPiA+ICsJCQkJICAgICZjYW0tPnN1YmRldi5lbnRpdHksIE1US19DQU1fQ0lPX1BB RF9TSU5LLA0KPiA+ICsJCQkJICAgIE1FRElBX0xOS19GTF9JTU1VVEFCTEUgfA0KPiA+ICsJCQkJ ICAgIE1FRElBX0xOS19GTF9FTkFCTEVEKTsNCj4gPiArCWlmIChyZXQpIHsNCj4gPiArCQlkZXZf ZXJyKGRldiwgImZhaWxlZCB0byBjcmVhdGUgcGFkIGxpbmsgJXMgJXMgZXJyOiVkXG4iLA0KPiA+ ICsJCQljYW0tPnNlbmluZi0+ZW50aXR5Lm5hbWUsIGNhbS0+c3ViZGV2LmVudGl0eS5uYW1lLA0K PiA+ICsJCQlyZXQpOw0KPiA+ICsJCXJldHVybiByZXQ7DQo+ID4gKwl9DQo+ID4gKw0KPiA+ICsJ cmV0ID0gdjRsMl9kZXZpY2VfcmVnaXN0ZXJfc3ViZGV2X25vZGVzKCZjYW0tPnY0bDJfZGV2KTsN Cj4gPiArCWlmIChyZXQpIHsNCj4gPiArCQlkZXZfZXJyKGRldiwgImZhaWxlZCB0byBpbml0aWFs aXplIHN1YmRldiBub2RlczolZFxuIiwgcmV0KTsNCj4gPiArCQlyZXR1cm4gcmV0Ow0KPiA+ICsJ fQ0KPiA+ICsNCj4gPiArCXJldHVybiByZXQ7DQo+ID4gK30NCj4gPiArDQo+ID4gK3N0YXRpYyBj b25zdCBzdHJ1Y3QgdjRsMl9hc3luY19ub3RpZmllcl9vcGVyYXRpb25zIG10a19jYW1fdjRsMl9h c3luY19vcHMgPSB7DQo+ID4gKwkuYm91bmQgPSBtdGtfY2FtX2Rldl9ub3RpZmllcl9ib3VuZCwN Cj4gPiArCS51bmJpbmQgPSBtdGtfY2FtX2Rldl9ub3RpZmllcl91bmJpbmQsDQo+ID4gKwkuY29t cGxldGUgPSBtdGtfY2FtX2Rldl9ub3RpZmllcl9jb21wbGV0ZSwNCj4gPiArfTsNCj4gPiArDQo+ ID4gK3N0YXRpYyBpbnQgbXRrX2NhbV92NGwyX2FzeW5jX3JlZ2lzdGVyKHN0cnVjdCBtdGtfY2Ft X2RldiAqY2FtKQ0KPiA+ICt7DQo+ID4gKwlzdHJ1Y3QgZGV2aWNlICpkZXYgPSBjYW0tPmRldjsN Cj4gPiArCWludCByZXQ7DQo+ID4gKw0KPiA+ICsJdjRsMl9hc3luY19ub3RpZmllcl9pbml0KCZj YW0tPm5vdGlmaWVyKTsNCj4gPiArCXJldCA9IHY0bDJfYXN5bmNfbm90aWZpZXJfcGFyc2VfZndu b2RlX2VuZHBvaW50cyhkZXYsDQo+ID4gKwkJJmNhbS0+bm90aWZpZXIsIHNpemVvZihzdHJ1Y3Qg djRsMl9hc3luY19zdWJkZXYpLCBOVUxMKTsNCj4gDQo+IEl0IHNlZW1zIHdlIHNob3VsZG4ndCBi ZSB1c2luZyB0aGlzIGZ1bmN0aW9uLCBwbGVhc2Ugc2VlIGNvbW1lbnRzIGF0IGh0dHBzOi8vcGF0 Y2h3b3JrLmtlcm5lbC5vcmcvcGF0Y2gvMTEwNjY1MjcvDQo+IA0KPiBSZWdhcmRzLA0KPiBIZWxl bg0KPiANCg0KT2ssIHdlIHdpbGwgaW52ZXN0aWdhdGUgaG93IHRvIGRvLg0KDQo+ID4gKwlpZiAo cmV0KSB7DQo+ID4gKwkJZGV2X2VycihkZXYsICJmYWlsZWQgdG8gcGFyc2UgZndub2RlIGVuZHBv aW50czolZFxuIiwgcmV0KTsNCj4gPiArCQlyZXR1cm4gcmV0Ow0KPiA+ICsJfQ0KPiA+ICsNCj4g PiArCWNhbS0+bm90aWZpZXIub3BzID0gJm10a19jYW1fdjRsMl9hc3luY19vcHM7DQo+ID4gKwlk ZXZfZGJnKGRldiwgIm10a19jYW0gdjRsMl9hc3luY19ub3RpZmllcl9yZWdpc3RlclxuIik7DQo+ ID4gKwlyZXQgPSB2NGwyX2FzeW5jX25vdGlmaWVyX3JlZ2lzdGVyKCZjYW0tPnY0bDJfZGV2LCAm Y2FtLT5ub3RpZmllcik7DQo+ID4gKwlpZiAocmV0KSB7DQo+ID4gKwkJZGV2X2VycihkZXYsICJm YWlsZWQgdG8gcmVnaXN0ZXIgYXN5bmMgbm90aWZpZXIgOiAlZFxuIiwgcmV0KTsNCj4gPiArCQl2 NGwyX2FzeW5jX25vdGlmaWVyX2NsZWFudXAoJmNhbS0+bm90aWZpZXIpOw0KPiA+ICsJfQ0KPiA+ ICsNCj4gPiArCXJldHVybiByZXQ7DQo+ID4gK30NCj4gPiArDQo+ID4gK3N0YXRpYyB2b2lkIG10 a19jYW1fdjRsMl9hc3luY191bnJlZ2lzdGVyKHN0cnVjdCBtdGtfY2FtX2RldiAqY2FtKQ0KPiA+ ICt7DQo+ID4gKwl2NGwyX2FzeW5jX25vdGlmaWVyX3VucmVnaXN0ZXIoJmNhbS0+bm90aWZpZXIp Ow0KPiA+ICsJdjRsMl9hc3luY19ub3RpZmllcl9jbGVhbnVwKCZjYW0tPm5vdGlmaWVyKTsNCj4g PiArfQ0KPiA+ICsNCj4gPiArc3RhdGljIGNvbnN0IHN0cnVjdCB2NGwyX2lvY3RsX29wcyBtdGtf Y2FtX3Y0bDJfdmNhcF9pb2N0bF9vcHMgPSB7DQo+ID4gKwkudmlkaW9jX3F1ZXJ5Y2FwID0gbXRr X2NhbV92aWRpb2NfcXVlcnljYXAsDQo+ID4gKwkudmlkaW9jX2VudW1fZnJhbWVzaXplcyA9IG10 a19jYW1fdmlkaW9jX2VudW1fZnJhbWVzaXplcywNCj4gPiArCS52aWRpb2NfZW51bV9mbXRfdmlk X2NhcCA9IG10a19jYW1fdmlkaW9jX2VudW1fZm10LA0KPiA+ICsJLnZpZGlvY19nX2ZtdF92aWRf Y2FwX21wbGFuZSA9IG10a19jYW1fdmlkaW9jX2dfZm10LA0KPiA+ICsJLnZpZGlvY19zX2ZtdF92 aWRfY2FwX21wbGFuZSA9IG10a19jYW1fdmlkaW9jX3NfZm10LA0KPiA+ICsJLnZpZGlvY190cnlf Zm10X3ZpZF9jYXBfbXBsYW5lID0gbXRrX2NhbV92aWRpb2NfdHJ5X2ZtdCwNCj4gPiArCS52aWRp b2NfcmVxYnVmcyA9IHZiMl9pb2N0bF9yZXFidWZzLA0KPiA+ICsJLnZpZGlvY19jcmVhdGVfYnVm cyA9IHZiMl9pb2N0bF9jcmVhdGVfYnVmcywNCj4gPiArCS52aWRpb2NfcHJlcGFyZV9idWYgPSB2 YjJfaW9jdGxfcHJlcGFyZV9idWYsDQo+ID4gKwkudmlkaW9jX3F1ZXJ5YnVmID0gdmIyX2lvY3Rs X3F1ZXJ5YnVmLA0KPiA+ICsJLnZpZGlvY19xYnVmID0gdmIyX2lvY3RsX3FidWYsDQo+ID4gKwku dmlkaW9jX2RxYnVmID0gdmIyX2lvY3RsX2RxYnVmLA0KPiA+ICsJLnZpZGlvY19zdHJlYW1vbiA9 IHZiMl9pb2N0bF9zdHJlYW1vbiwNCj4gPiArCS52aWRpb2Nfc3RyZWFtb2ZmID0gdmIyX2lvY3Rs X3N0cmVhbW9mZiwNCj4gPiArCS52aWRpb2NfZXhwYnVmID0gdmIyX2lvY3RsX2V4cGJ1ZiwNCj4g PiArCS52aWRpb2Nfc3Vic2NyaWJlX2V2ZW50ID0gdjRsMl9jdHJsX3N1YnNjcmliZV9ldmVudCwN Cj4gPiArCS52aWRpb2NfdW5zdWJzY3JpYmVfZXZlbnQgPSB2NGwyX2V2ZW50X3Vuc3Vic2NyaWJl LA0KPiA+ICt9Ow0KPiA+ICsNCj4gPiArc3RhdGljIGNvbnN0IHN0cnVjdCB2NGwyX2lvY3RsX29w cyBtdGtfY2FtX3Y0bDJfbWV0YV9jYXBfaW9jdGxfb3BzID0gew0KPiA+ICsJLnZpZGlvY19xdWVy eWNhcCA9IG10a19jYW1fdmlkaW9jX3F1ZXJ5Y2FwLA0KPiA+ICsJLnZpZGlvY19lbnVtX2ZtdF9t ZXRhX2NhcCA9IG10a19jYW1fdmlkaW9jX21ldGFfZW51bV9mbXQsDQo+ID4gKwkudmlkaW9jX2df Zm10X21ldGFfY2FwID0gbXRrX2NhbV92aWRpb2NfZ19tZXRhX2ZtdCwNCj4gPiArCS52aWRpb2Nf c19mbXRfbWV0YV9jYXAgPSBtdGtfY2FtX3ZpZGlvY19nX21ldGFfZm10LA0KPiA+ICsJLnZpZGlv Y190cnlfZm10X21ldGFfY2FwID0gbXRrX2NhbV92aWRpb2NfZ19tZXRhX2ZtdCwNCj4gPiArCS52 aWRpb2NfcmVxYnVmcyA9IHZiMl9pb2N0bF9yZXFidWZzLA0KPiA+ICsJLnZpZGlvY19jcmVhdGVf YnVmcyA9IHZiMl9pb2N0bF9jcmVhdGVfYnVmcywNCj4gPiArCS52aWRpb2NfcHJlcGFyZV9idWYg PSB2YjJfaW9jdGxfcHJlcGFyZV9idWYsDQo+ID4gKwkudmlkaW9jX3F1ZXJ5YnVmID0gdmIyX2lv Y3RsX3F1ZXJ5YnVmLA0KPiA+ICsJLnZpZGlvY19xYnVmID0gdmIyX2lvY3RsX3FidWYsDQo+ID4g KwkudmlkaW9jX2RxYnVmID0gdmIyX2lvY3RsX2RxYnVmLA0KPiA+ICsJLnZpZGlvY19zdHJlYW1v biA9IHZiMl9pb2N0bF9zdHJlYW1vbiwNCj4gPiArCS52aWRpb2Nfc3RyZWFtb2ZmID0gdmIyX2lv Y3RsX3N0cmVhbW9mZiwNCj4gPiArCS52aWRpb2NfZXhwYnVmID0gdmIyX2lvY3RsX2V4cGJ1ZiwN Cj4gPiArfTsNCj4gPiArDQo+ID4gK3N0YXRpYyBjb25zdCBzdHJ1Y3QgdjRsMl9pb2N0bF9vcHMg bXRrX2NhbV92NGwyX21ldGFfb3V0X2lvY3RsX29wcyA9IHsNCj4gPiArCS52aWRpb2NfcXVlcnlj YXAgPSBtdGtfY2FtX3ZpZGlvY19xdWVyeWNhcCwNCj4gPiArCS52aWRpb2NfZW51bV9mbXRfbWV0 YV9vdXQgPSBtdGtfY2FtX3ZpZGlvY19tZXRhX2VudW1fZm10LA0KPiA+ICsJLnZpZGlvY19nX2Zt dF9tZXRhX291dCA9IG10a19jYW1fdmlkaW9jX2dfbWV0YV9mbXQsDQo+ID4gKwkudmlkaW9jX3Nf Zm10X21ldGFfb3V0ID0gbXRrX2NhbV92aWRpb2NfZ19tZXRhX2ZtdCwNCj4gPiArCS52aWRpb2Nf dHJ5X2ZtdF9tZXRhX291dCA9IG10a19jYW1fdmlkaW9jX2dfbWV0YV9mbXQsDQo+ID4gKwkudmlk aW9jX3JlcWJ1ZnMgPSB2YjJfaW9jdGxfcmVxYnVmcywNCj4gPiArCS52aWRpb2NfY3JlYXRlX2J1 ZnMgPSB2YjJfaW9jdGxfY3JlYXRlX2J1ZnMsDQo+ID4gKwkudmlkaW9jX3ByZXBhcmVfYnVmID0g dmIyX2lvY3RsX3ByZXBhcmVfYnVmLA0KPiA+ICsJLnZpZGlvY19xdWVyeWJ1ZiA9IHZiMl9pb2N0 bF9xdWVyeWJ1ZiwNCj4gPiArCS52aWRpb2NfcWJ1ZiA9IHZiMl9pb2N0bF9xYnVmLA0KPiA+ICsJ LnZpZGlvY19kcWJ1ZiA9IHZiMl9pb2N0bF9kcWJ1ZiwNCj4gPiArCS52aWRpb2Nfc3RyZWFtb24g PSB2YjJfaW9jdGxfc3RyZWFtb24sDQo+ID4gKwkudmlkaW9jX3N0cmVhbW9mZiA9IHZiMl9pb2N0 bF9zdHJlYW1vZmYsDQo+ID4gKwkudmlkaW9jX2V4cGJ1ZiA9IHZiMl9pb2N0bF9leHBidWYsDQo+ ID4gK307PiArDQo+ID4gK3N0YXRpYyBjb25zdCBzdHJ1Y3QgdjRsMl9mb3JtYXQgbWV0YV9mbXRz W10gPSB7DQo+ID4gKwl7DQo+ID4gKwkJLmZtdC5tZXRhID0gew0KPiA+ICsJCQkuZGF0YWZvcm1h dCA9IFY0TDJfTUVUQV9GTVRfTVRJU1BfUEFSQU1TLA0KPiA+ICsJCQkuYnVmZmVyc2l6ZSA9IDUx MiAqIFNaXzFLLA0KPiA+ICsJCX0sDQo+ID4gKwl9LA0KPiA+ICsJew0KPiA+ICsJCS5mbXQubWV0 YSA9IHsNCj4gPiArCQkJLmRhdGFmb3JtYXQgPSBWNEwyX01FVEFfRk1UX01USVNQXzNBLA0KPiA+ ICsJCQkuYnVmZmVyc2l6ZSA9IDEyMDAgKiBTWl8xSywNCj4gPiArCQl9LA0KPiA+ICsJfSwNCj4g PiArCXsNCj4gPiArCQkuZm10Lm1ldGEgPSB7DQo+ID4gKwkJCS5kYXRhZm9ybWF0ID0gVjRMMl9N RVRBX0ZNVF9NVElTUF9BRiwNCj4gPiArCQkJLmJ1ZmZlcnNpemUgPSA2NDAgKiBTWl8xSywNCj4g PiArCQl9LA0KPiA+ICsJfSwNCj4gPiArCXsNCj4gPiArCQkuZm10Lm1ldGEgPSB7DQo+ID4gKwkJ CS5kYXRhZm9ybWF0ID0gVjRMMl9NRVRBX0ZNVF9NVElTUF9MQ1MsDQo+ID4gKwkJCS5idWZmZXJz aXplID0gMjg4ICogU1pfMUssDQo+ID4gKwkJfSwNCj4gPiArCX0sDQo+ID4gKwl7DQo+ID4gKwkJ LmZtdC5tZXRhID0gew0KPiA+ICsJCQkuZGF0YWZvcm1hdCA9IFY0TDJfTUVUQV9GTVRfTVRJU1Bf TE1WLA0KPiA+ICsJCQkuYnVmZmVyc2l6ZSA9IDI1NiwNCj4gPiArCQl9LA0KPiA+ICsJfSwNCj4g PiArfTsNCj4gPiArDQo+ID4gK3N0YXRpYyBjb25zdCBzdHJ1Y3QgdjRsMl9mb3JtYXQgc3RyZWFt X291dF9mbXRzW10gPSB7DQo+ID4gKwkvKiBUaGlzIGlzIGEgZGVmYXVsdCBpbWFnZSBmb3JtYXQg Ki8NCj4gPiArCXsNCj4gPiArCQkuZm10LnBpeF9tcCA9IHsNCj4gPiArCQkJLndpZHRoID0gSU1H X01BWF9XSURUSCwNCj4gPiArCQkJLmhlaWdodCA9IElNR19NQVhfSEVJR0hULA0KPiA+ICsJCQku cGl4ZWxmb3JtYXQgPSBWNEwyX1BJWF9GTVRfTVRJU1BfU0JHR1IxMCwNCj4gPiArCQl9LA0KPiA+ ICsJfSwNCj4gPiArCXsNCj4gPiArCQkuZm10LnBpeF9tcCA9IHsNCj4gPiArCQkJLndpZHRoID0g SU1HX01BWF9XSURUSCwNCj4gPiArCQkJLmhlaWdodCA9IElNR19NQVhfSEVJR0hULA0KPiA+ICsJ CQkucGl4ZWxmb3JtYXQgPSBWNEwyX1BJWF9GTVRfTVRJU1BfU0JHR1I4LA0KPiA+ICsJCX0sDQo+ ID4gKwl9LA0KPiA+ICsJew0KPiA+ICsJCS5mbXQucGl4X21wID0gew0KPiA+ICsJCQkud2lkdGgg PSBJTUdfTUFYX1dJRFRILA0KPiA+ICsJCQkuaGVpZ2h0ID0gSU1HX01BWF9IRUlHSFQsDQo+ID4g KwkJCS5waXhlbGZvcm1hdCA9IFY0TDJfUElYX0ZNVF9NVElTUF9TQkdHUjEyLA0KPiA+ICsJCX0s DQo+ID4gKwl9LA0KPiA+ICsJew0KPiA+ICsJCS5mbXQucGl4X21wID0gew0KPiA+ICsJCQkud2lk dGggPSBJTUdfTUFYX1dJRFRILA0KPiA+ICsJCQkuaGVpZ2h0ID0gSU1HX01BWF9IRUlHSFQsDQo+ ID4gKwkJCS5waXhlbGZvcm1hdCA9IFY0TDJfUElYX0ZNVF9NVElTUF9TQkdHUjE0LA0KPiA+ICsJ CX0sDQo+ID4gKwl9LA0KPiA+ICsJew0KPiA+ICsJCS5mbXQucGl4X21wID0gew0KPiA+ICsJCQku d2lkdGggPSBJTUdfTUFYX1dJRFRILA0KPiA+ICsJCQkuaGVpZ2h0ID0gSU1HX01BWF9IRUlHSFQs DQo+ID4gKwkJCS5waXhlbGZvcm1hdCA9IFY0TDJfUElYX0ZNVF9NVElTUF9TR0JSRzgsDQo+ID4g KwkJfSwNCj4gPiArCX0sDQo+ID4gKwl7DQo+ID4gKwkJLmZtdC5waXhfbXAgPSB7DQo+ID4gKwkJ CS53aWR0aCA9IElNR19NQVhfV0lEVEgsDQo+ID4gKwkJCS5oZWlnaHQgPSBJTUdfTUFYX0hFSUdI VCwNCj4gPiArCQkJLnBpeGVsZm9ybWF0ID0gVjRMMl9QSVhfRk1UX01USVNQX1NHQlJHMTAsDQo+ ID4gKwkJfSwNCj4gPiArCX0sDQo+ID4gKwl7DQo+ID4gKwkJLmZtdC5waXhfbXAgPSB7DQo+ID4g KwkJCS53aWR0aCA9IElNR19NQVhfV0lEVEgsDQo+ID4gKwkJCS5oZWlnaHQgPSBJTUdfTUFYX0hF SUdIVCwNCj4gPiArCQkJLnBpeGVsZm9ybWF0ID0gVjRMMl9QSVhfRk1UX01USVNQX1NHQlJHMTIs DQo+ID4gKwkJfSwNCj4gPiArCX0sDQo+ID4gKwl7DQo+ID4gKwkJLmZtdC5waXhfbXAgPSB7DQo+ ID4gKwkJCS53aWR0aCA9IElNR19NQVhfV0lEVEgsDQo+ID4gKwkJCS5oZWlnaHQgPSBJTUdfTUFY X0hFSUdIVCwNCj4gPiArCQkJLnBpeGVsZm9ybWF0ID0gVjRMMl9QSVhfRk1UX01USVNQX1NHQlJH MTQsDQo+ID4gKwkJfSwNCj4gPiArCX0sDQo+ID4gKwl7DQo+ID4gKwkJLmZtdC5waXhfbXAgPSB7 DQo+ID4gKwkJCS53aWR0aCA9IElNR19NQVhfV0lEVEgsDQo+ID4gKwkJCS5oZWlnaHQgPSBJTUdf TUFYX0hFSUdIVCwNCj4gPiArCQkJLnBpeGVsZm9ybWF0ID0gVjRMMl9QSVhfRk1UX01USVNQX1NH UkJHOCwNCj4gPiArCQl9LA0KPiA+ICsJfSwNCj4gPiArCXsNCj4gPiArCQkuZm10LnBpeF9tcCA9 IHsNCj4gPiArCQkJLndpZHRoID0gSU1HX01BWF9XSURUSCwNCj4gPiArCQkJLmhlaWdodCA9IElN R19NQVhfSEVJR0hULA0KPiA+ICsJCQkucGl4ZWxmb3JtYXQgPSBWNEwyX1BJWF9GTVRfTVRJU1Bf U0dSQkcxMCwNCj4gPiArCQl9LA0KPiA+ICsJfSwNCj4gPiArCXsNCj4gPiArCQkuZm10LnBpeF9t cCA9IHsNCj4gPiArCQkJLndpZHRoID0gSU1HX01BWF9XSURUSCwNCj4gPiArCQkJLmhlaWdodCA9 IElNR19NQVhfSEVJR0hULA0KPiA+ICsJCQkucGl4ZWxmb3JtYXQgPSBWNEwyX1BJWF9GTVRfTVRJ U1BfU0dSQkcxMiwNCj4gPiArCQl9LA0KPiA+ICsJfSwNCj4gPiArCXsNCj4gPiArCQkuZm10LnBp eF9tcCA9IHsNCj4gPiArCQkJLndpZHRoID0gSU1HX01BWF9XSURUSCwNCj4gPiArCQkJLmhlaWdo dCA9IElNR19NQVhfSEVJR0hULA0KPiA+ICsJCQkucGl4ZWxmb3JtYXQgPSBWNEwyX1BJWF9GTVRf TVRJU1BfU0dSQkcxNCwNCj4gPiArCQl9LA0KPiA+ICsJfSwNCj4gPiArCXsNCj4gPiArCQkuZm10 LnBpeF9tcCA9IHsNCj4gPiArCQkJLndpZHRoID0gSU1HX01BWF9XSURUSCwNCj4gPiArCQkJLmhl aWdodCA9IElNR19NQVhfSEVJR0hULA0KPiA+ICsJCQkucGl4ZWxmb3JtYXQgPSBWNEwyX1BJWF9G TVRfTVRJU1BfU1JHR0I4LA0KPiA+ICsJCX0sDQo+ID4gKwl9LA0KPiA+ICsJew0KPiA+ICsJCS5m bXQucGl4X21wID0gew0KPiA+ICsJCQkud2lkdGggPSBJTUdfTUFYX1dJRFRILA0KPiA+ICsJCQku aGVpZ2h0ID0gSU1HX01BWF9IRUlHSFQsDQo+ID4gKwkJCS5waXhlbGZvcm1hdCA9IFY0TDJfUElY X0ZNVF9NVElTUF9TUkdHQjEwLA0KPiA+ICsJCX0sDQo+ID4gKwl9LA0KPiA+ICsJew0KPiA+ICsJ CS5mbXQucGl4X21wID0gew0KPiA+ICsJCQkud2lkdGggPSBJTUdfTUFYX1dJRFRILA0KPiA+ICsJ CQkuaGVpZ2h0ID0gSU1HX01BWF9IRUlHSFQsDQo+ID4gKwkJCS5waXhlbGZvcm1hdCA9IFY0TDJf UElYX0ZNVF9NVElTUF9TUkdHQjEyLA0KPiA+ICsJCX0sDQo+ID4gKwl9LA0KPiA+ICsJew0KPiA+ ICsJCS5mbXQucGl4X21wID0gew0KPiA+ICsJCQkud2lkdGggPSBJTUdfTUFYX1dJRFRILA0KPiA+ ICsJCQkuaGVpZ2h0ID0gSU1HX01BWF9IRUlHSFQsDQo+ID4gKwkJCS5waXhlbGZvcm1hdCA9IFY0 TDJfUElYX0ZNVF9NVElTUF9TUkdHQjE0LA0KPiA+ICsJCX0sDQo+ID4gKwl9LA0KPiA+ICt9Ow0K PiA+ICsNCj4gPiArc3RhdGljIGNvbnN0IHN0cnVjdCB2NGwyX2Zvcm1hdCBiaW5fb3V0X2ZtdHNb XSA9IHsNCj4gPiArCXsNCj4gPiArCQkuZm10LnBpeF9tcCA9IHsNCj4gPiArCQkJLndpZHRoID0g SU1HX01BWF9XSURUSCwNCj4gPiArCQkJLmhlaWdodCA9IElNR19NQVhfSEVJR0hULA0KPiA+ICsJ CQkucGl4ZWxmb3JtYXQgPSBWNEwyX1BJWF9GTVRfTVRJU1BfU0JHR1I4RiwNCj4gPiArCQl9LA0K PiA+ICsJfSwNCj4gPiArCXsNCj4gPiArCQkuZm10LnBpeF9tcCA9IHsNCj4gPiArCQkJLndpZHRo ID0gSU1HX01BWF9XSURUSCwNCj4gPiArCQkJLmhlaWdodCA9IElNR19NQVhfSEVJR0hULA0KPiA+ ICsJCQkucGl4ZWxmb3JtYXQgPSBWNEwyX1BJWF9GTVRfTVRJU1BfU0JHR1IxMEYsDQo+ID4gKwkJ fSwNCj4gPiArCX0sDQo+ID4gKwl7DQo+ID4gKwkJLmZtdC5waXhfbXAgPSB7DQo+ID4gKwkJCS53 aWR0aCA9IElNR19NQVhfV0lEVEgsDQo+ID4gKwkJCS5oZWlnaHQgPSBJTUdfTUFYX0hFSUdIVCwN Cj4gPiArCQkJLnBpeGVsZm9ybWF0ID0gVjRMMl9QSVhfRk1UX01USVNQX1NCR0dSMTJGLA0KPiA+ ICsJCX0sDQo+ID4gKwl9LA0KPiA+ICsJew0KPiA+ICsJCS5mbXQucGl4X21wID0gew0KPiA+ICsJ CQkud2lkdGggPSBJTUdfTUFYX1dJRFRILA0KPiA+ICsJCQkuaGVpZ2h0ID0gSU1HX01BWF9IRUlH SFQsDQo+ID4gKwkJCS5waXhlbGZvcm1hdCA9IFY0TDJfUElYX0ZNVF9NVElTUF9TQkdHUjE0RiwN Cj4gPiArCQl9LA0KPiA+ICsJfSwNCj4gPiArCXsNCj4gPiArCQkuZm10LnBpeF9tcCA9IHsNCj4g PiArCQkJLndpZHRoID0gSU1HX01BWF9XSURUSCwNCj4gPiArCQkJLmhlaWdodCA9IElNR19NQVhf SEVJR0hULA0KPiA+ICsJCQkucGl4ZWxmb3JtYXQgPSBWNEwyX1BJWF9GTVRfTVRJU1BfU0dCUkc4 RiwNCj4gPiArCQl9LA0KPiA+ICsJfSwNCj4gPiArCXsNCj4gPiArCQkuZm10LnBpeF9tcCA9IHsN Cj4gPiArCQkJLndpZHRoID0gSU1HX01BWF9XSURUSCwNCj4gPiArCQkJLmhlaWdodCA9IElNR19N QVhfSEVJR0hULA0KPiA+ICsJCQkucGl4ZWxmb3JtYXQgPSBWNEwyX1BJWF9GTVRfTVRJU1BfU0dC UkcxMEYsDQo+ID4gKwkJfSwNCj4gPiArCX0sDQo+ID4gKwl7DQo+ID4gKwkJLmZtdC5waXhfbXAg PSB7DQo+ID4gKwkJCS53aWR0aCA9IElNR19NQVhfV0lEVEgsDQo+ID4gKwkJCS5oZWlnaHQgPSBJ TUdfTUFYX0hFSUdIVCwNCj4gPiArCQkJLnBpeGVsZm9ybWF0ID0gVjRMMl9QSVhfRk1UX01USVNQ X1NHQlJHMTJGLA0KPiA+ICsJCX0sDQo+ID4gKwl9LA0KPiA+ICsJew0KPiA+ICsJCS5mbXQucGl4 X21wID0gew0KPiA+ICsJCQkud2lkdGggPSBJTUdfTUFYX1dJRFRILA0KPiA+ICsJCQkuaGVpZ2h0 ID0gSU1HX01BWF9IRUlHSFQsDQo+ID4gKwkJCS5waXhlbGZvcm1hdCA9IFY0TDJfUElYX0ZNVF9N VElTUF9TR0JSRzE0RiwNCj4gPiArCQl9LA0KPiA+ICsJfSwNCj4gPiArCXsNCj4gPiArCQkuZm10 LnBpeF9tcCA9IHsNCj4gPiArCQkJLndpZHRoID0gSU1HX01BWF9XSURUSCwNCj4gPiArCQkJLmhl aWdodCA9IElNR19NQVhfSEVJR0hULA0KPiA+ICsJCQkucGl4ZWxmb3JtYXQgPSBWNEwyX1BJWF9G TVRfTVRJU1BfU0dSQkc4RiwNCj4gPiArCQl9LA0KPiA+ICsJfSwNCj4gPiArCXsNCj4gPiArCQku Zm10LnBpeF9tcCA9IHsNCj4gPiArCQkJLndpZHRoID0gSU1HX01BWF9XSURUSCwNCj4gPiArCQkJ LmhlaWdodCA9IElNR19NQVhfSEVJR0hULA0KPiA+ICsJCQkucGl4ZWxmb3JtYXQgPSBWNEwyX1BJ WF9GTVRfTVRJU1BfU0dSQkcxMEYsDQo+ID4gKwkJfSwNCj4gPiArCX0sDQo+ID4gKwl7DQo+ID4g KwkJLmZtdC5waXhfbXAgPSB7DQo+ID4gKwkJCS53aWR0aCA9IElNR19NQVhfV0lEVEgsDQo+ID4g KwkJCS5oZWlnaHQgPSBJTUdfTUFYX0hFSUdIVCwNCj4gPiArCQkJLnBpeGVsZm9ybWF0ID0gVjRM Ml9QSVhfRk1UX01USVNQX1NHUkJHMTJGLA0KPiA+ICsJCX0sDQo+ID4gKwl9LA0KPiA+ICsJew0K PiA+ICsJCS5mbXQucGl4X21wID0gew0KPiA+ICsJCQkud2lkdGggPSBJTUdfTUFYX1dJRFRILA0K PiA+ICsJCQkuaGVpZ2h0ID0gSU1HX01BWF9IRUlHSFQsDQo+ID4gKwkJCS5waXhlbGZvcm1hdCA9 IFY0TDJfUElYX0ZNVF9NVElTUF9TR1JCRzE0RiwNCj4gPiArCQl9LA0KPiA+ICsJfSwNCj4gPiAr CXsNCj4gPiArCQkuZm10LnBpeF9tcCA9IHsNCj4gPiArCQkJLndpZHRoID0gSU1HX01BWF9XSURU SCwNCj4gPiArCQkJLmhlaWdodCA9IElNR19NQVhfSEVJR0hULA0KPiA+ICsJCQkucGl4ZWxmb3Jt YXQgPSBWNEwyX1BJWF9GTVRfTVRJU1BfU1JHR0I4RiwNCj4gPiArCQl9LA0KPiA+ICsJfSwNCj4g PiArCXsNCj4gPiArCQkuZm10LnBpeF9tcCA9IHsNCj4gPiArCQkJLndpZHRoID0gSU1HX01BWF9X SURUSCwNCj4gPiArCQkJLmhlaWdodCA9IElNR19NQVhfSEVJR0hULA0KPiA+ICsJCQkucGl4ZWxm b3JtYXQgPSBWNEwyX1BJWF9GTVRfTVRJU1BfU1JHR0IxMEYsDQo+ID4gKwkJfSwNCj4gPiArCX0s DQo+ID4gKwl7DQo+ID4gKwkJLmZtdC5waXhfbXAgPSB7DQo+ID4gKwkJCS53aWR0aCA9IElNR19N QVhfV0lEVEgsDQo+ID4gKwkJCS5oZWlnaHQgPSBJTUdfTUFYX0hFSUdIVCwNCj4gPiArCQkJLnBp eGVsZm9ybWF0ID0gVjRMMl9QSVhfRk1UX01USVNQX1NSR0dCMTJGLA0KPiA+ICsJCX0sDQo+ID4g Kwl9LA0KPiA+ICsJew0KPiA+ICsJCS5mbXQucGl4X21wID0gew0KPiA+ICsJCQkud2lkdGggPSBJ TUdfTUFYX1dJRFRILA0KPiA+ICsJCQkuaGVpZ2h0ID0gSU1HX01BWF9IRUlHSFQsDQo+ID4gKwkJ CS5waXhlbGZvcm1hdCA9IFY0TDJfUElYX0ZNVF9NVElTUF9TUkdHQjE0RiwNCj4gPiArCQl9LA0K PiA+ICsJfSwNCj4gPiArfTsNCj4gPiArDQo+ID4gK3N0YXRpYyBjb25zdCBzdHJ1Y3QNCj4gPiAr bXRrX2NhbV9kZXZfbm9kZV9kZXNjIG91dHB1dF9xdWV1ZXNbXSA9IHsNCj4gPiArCXsNCj4gPiAr CQkuaWQgPSBNVEtfQ0FNX1AxX01FVEFfSU5fMCwNCj4gPiArCQkubmFtZSA9ICJtZXRhIGlucHV0 IiwNCj4gPiArCQkuY2FwID0gVjRMMl9DQVBfTUVUQV9PVVRQVVQsDQo+ID4gKwkJLmJ1Zl90eXBl ID0gVjRMMl9CVUZfVFlQRV9NRVRBX09VVFBVVCwNCj4gPiArCQkubGlua19mbGFncyA9IDAsDQo+ ID4gKwkJLmltYWdlID0gZmFsc2UsDQo+ID4gKwkJLnNtZW1fYWxsb2MgPSB0cnVlLA0KPiA+ICsJ CS5mbXRzID0gbWV0YV9mbXRzLA0KPiA+ICsJCS5kZWZhdWx0X2ZtdF9pZHggPSAwLA0KPiA+ICsJ CS5tYXhfYnVmX2NvdW50ID0gMTAsDQo+ID4gKwkJLmlvY3RsX29wcyA9ICZtdGtfY2FtX3Y0bDJf bWV0YV9vdXRfaW9jdGxfb3BzLA0KPiA+ICsJfSwNCj4gPiArfTsNCj4gPiArDQo+ID4gK3N0YXRp YyBjb25zdCBzdHJ1Y3QNCj4gPiArbXRrX2NhbV9kZXZfbm9kZV9kZXNjIGNhcHR1cmVfcXVldWVz W10gPSB7DQo+ID4gKwl7DQo+ID4gKwkJLmlkID0gTVRLX0NBTV9QMV9NQUlOX1NUUkVBTV9PVVQs DQo+ID4gKwkJLm5hbWUgPSAibWFpbiBzdHJlYW0iLA0KPiA+ICsJCS5jYXAgPSBWNEwyX0NBUF9W SURFT19DQVBUVVJFX01QTEFORSwNCj4gPiArCQkuYnVmX3R5cGUgPSBWNEwyX0JVRl9UWVBFX1ZJ REVPX0NBUFRVUkVfTVBMQU5FLA0KPiA+ICsJCS5saW5rX2ZsYWdzID0gTUVESUFfTE5LX0ZMX0lN TVVUQUJMRSB8IE1FRElBX0xOS19GTF9FTkFCTEVELA0KPiA+ICsJCS5pbWFnZSA9IHRydWUsDQo+ ID4gKwkJLnNtZW1fYWxsb2MgPSBmYWxzZSwNCj4gPiArCQkuZG1hX3BvcnQgPSBSX0lNR08sDQo+ ID4gKwkJLmZtdHMgPSBzdHJlYW1fb3V0X2ZtdHMsDQo+ID4gKwkJLm51bV9mbXRzID0gQVJSQVlf U0laRShzdHJlYW1fb3V0X2ZtdHMpLA0KPiA+ICsJCS5kZWZhdWx0X2ZtdF9pZHggPSAwLA0KPiA+ ICsJCS5pb2N0bF9vcHMgPSAmbXRrX2NhbV92NGwyX3ZjYXBfaW9jdGxfb3BzLA0KPiA+ICsJCS5m cm1zaXplcyA9ICYoc3RydWN0IHY0bDJfZnJtc2l6ZWVudW0pIHsNCj4gPiArCQkJLmluZGV4ID0g MCwNCj4gPiArCQkJLnR5cGUgPSBWNEwyX0ZSTVNJWkVfVFlQRV9DT05USU5VT1VTLA0KPiA+ICsJ CQkuc3RlcHdpc2UgPSB7DQo+ID4gKwkJCQkubWF4X3dpZHRoID0gSU1HX01BWF9XSURUSCwNCj4g PiArCQkJCS5taW5fd2lkdGggPSBJTUdfTUlOX1dJRFRILA0KPiA+ICsJCQkJLm1heF9oZWlnaHQg PSBJTUdfTUFYX0hFSUdIVCwNCj4gPiArCQkJCS5taW5faGVpZ2h0ID0gSU1HX01JTl9IRUlHSFQs DQo+ID4gKwkJCQkuc3RlcF9oZWlnaHQgPSAxLA0KPiA+ICsJCQkJLnN0ZXBfd2lkdGggPSAxLA0K PiA+ICsJCQl9LA0KPiA+ICsJCX0sDQo+ID4gKwl9LA0KPiA+ICsJew0KPiA+ICsJCS5pZCA9IE1U S19DQU1fUDFfUEFDS0VEX0JJTl9PVVQsDQo+ID4gKwkJLm5hbWUgPSAicGFja2VkIG91dCIsDQo+ ID4gKwkJLmNhcCA9IFY0TDJfQ0FQX1ZJREVPX0NBUFRVUkVfTVBMQU5FLA0KPiA+ICsJCS5idWZf dHlwZSA9IFY0TDJfQlVGX1RZUEVfVklERU9fQ0FQVFVSRV9NUExBTkUsDQo+ID4gKwkJLmxpbmtf ZmxhZ3MgPSAwLA0KPiA+ICsJCS5pbWFnZSA9IHRydWUsDQo+ID4gKwkJLnNtZW1fYWxsb2MgPSBm YWxzZSwNCj4gPiArCQkuZG1hX3BvcnQgPSBSX1JSWk8sDQo+ID4gKwkJLmZtdHMgPSBiaW5fb3V0 X2ZtdHMsDQo+ID4gKwkJLm51bV9mbXRzID0gQVJSQVlfU0laRShiaW5fb3V0X2ZtdHMpLA0KPiA+ ICsJCS5kZWZhdWx0X2ZtdF9pZHggPSAwLA0KPiA+ICsJCS5pb2N0bF9vcHMgPSAmbXRrX2NhbV92 NGwyX3ZjYXBfaW9jdGxfb3BzLA0KPiA+ICsJCS5mcm1zaXplcyA9ICYoc3RydWN0IHY0bDJfZnJt c2l6ZWVudW0pIHsNCj4gPiArCQkJLmluZGV4ID0gMCwNCj4gPiArCQkJLnR5cGUgPSBWNEwyX0ZS TVNJWkVfVFlQRV9DT05USU5VT1VTLA0KPiA+ICsJCQkuc3RlcHdpc2UgPSB7DQo+ID4gKwkJCQku bWF4X3dpZHRoID0gSU1HX01BWF9XSURUSCwNCj4gPiArCQkJCS5taW5fd2lkdGggPSBJTUdfTUlO X1dJRFRILA0KPiA+ICsJCQkJLm1heF9oZWlnaHQgPSBJTUdfTUFYX0hFSUdIVCwNCj4gPiArCQkJ CS5taW5faGVpZ2h0ID0gSU1HX01JTl9IRUlHSFQsDQo+ID4gKwkJCQkuc3RlcF9oZWlnaHQgPSAx LA0KPiA+ICsJCQkJLnN0ZXBfd2lkdGggPSAxLA0KPiA+ICsJCQl9LA0KPiA+ICsJCX0sDQo+ID4g Kwl9LA0KPiA+ICsJew0KPiA+ICsJCS5pZCA9IE1US19DQU1fUDFfTUVUQV9PVVRfMCwNCj4gPiAr CQkubmFtZSA9ICJwYXJ0aWFsIG1ldGEgMCIsDQo+ID4gKwkJLmNhcCA9IFY0TDJfQ0FQX01FVEFf Q0FQVFVSRSwNCj4gPiArCQkuYnVmX3R5cGUgPSBWNEwyX0JVRl9UWVBFX01FVEFfQ0FQVFVSRSwN Cj4gPiArCQkubGlua19mbGFncyA9IDAsDQo+ID4gKwkJLmltYWdlID0gZmFsc2UsDQo+ID4gKwkJ LnNtZW1fYWxsb2MgPSBmYWxzZSwNCj4gPiArCQkuZG1hX3BvcnQgPSBSX0FBTyB8IFJfRkxLTyB8 IFJfUFNPLA0KPiA+ICsJCS5mbXRzID0gbWV0YV9mbXRzLA0KPiA+ICsJCS5kZWZhdWx0X2ZtdF9p ZHggPSAxLA0KPiA+ICsJCS5tYXhfYnVmX2NvdW50ID0gNSwNCj4gPiArCQkuaW9jdGxfb3BzID0g Jm10a19jYW1fdjRsMl9tZXRhX2NhcF9pb2N0bF9vcHMsDQo+ID4gKwl9LA0KPiA+ICsJew0KPiA+ ICsJCS5pZCA9IE1US19DQU1fUDFfTUVUQV9PVVRfMSwNCj4gPiArCQkubmFtZSA9ICJwYXJ0aWFs IG1ldGEgMSIsDQo+ID4gKwkJLmNhcCA9IFY0TDJfQ0FQX01FVEFfQ0FQVFVSRSwNCj4gPiArCQku YnVmX3R5cGUgPSBWNEwyX0JVRl9UWVBFX01FVEFfQ0FQVFVSRSwNCj4gPiArCQkubGlua19mbGFn cyA9IDAsDQo+ID4gKwkJLmltYWdlID0gZmFsc2UsDQo+ID4gKwkJLnNtZW1fYWxsb2MgPSBmYWxz ZSwNCj4gPiArCQkuZG1hX3BvcnQgPSBSX0FGTywNCj4gPiArCQkuZm10cyA9IG1ldGFfZm10cywN Cj4gPiArCQkuZGVmYXVsdF9mbXRfaWR4ID0gMiwNCj4gPiArCQkubWF4X2J1Zl9jb3VudCA9IDUs DQo+ID4gKwkJLmlvY3RsX29wcyA9ICZtdGtfY2FtX3Y0bDJfbWV0YV9jYXBfaW9jdGxfb3BzLA0K PiA+ICsJfSwNCj4gPiArCXsNCj4gPiArCQkuaWQgPSBNVEtfQ0FNX1AxX01FVEFfT1VUXzIsDQo+ ID4gKwkJLm5hbWUgPSAicGFydGlhbCBtZXRhIDIiLA0KPiA+ICsJCS5jYXAgPSBWNEwyX0NBUF9N RVRBX0NBUFRVUkUsDQo+ID4gKwkJLmJ1Zl90eXBlID0gVjRMMl9CVUZfVFlQRV9NRVRBX0NBUFRV UkUsDQo+ID4gKwkJLmxpbmtfZmxhZ3MgPSAwLA0KPiA+ICsJCS5pbWFnZSA9IGZhbHNlLA0KPiA+ ICsJCS5zbWVtX2FsbG9jID0gZmFsc2UsDQo+ID4gKwkJLmRtYV9wb3J0ID0gUl9MQ1NPLA0KPiA+ ICsJCS5mbXRzID0gbWV0YV9mbXRzLA0KPiA+ICsJCS5kZWZhdWx0X2ZtdF9pZHggPSAzLA0KPiA+ ICsJCS5tYXhfYnVmX2NvdW50ID0gMTAsDQo+ID4gKwkJLmlvY3RsX29wcyA9ICZtdGtfY2FtX3Y0 bDJfbWV0YV9jYXBfaW9jdGxfb3BzLA0KPiA+ICsJfSwNCj4gPiArCXsNCj4gPiArCQkuaWQgPSBN VEtfQ0FNX1AxX01FVEFfT1VUXzMsDQo+ID4gKwkJLm5hbWUgPSAicGFydGlhbCBtZXRhIDMiLA0K PiA+ICsJCS5jYXAgPSBWNEwyX0NBUF9NRVRBX0NBUFRVUkUsDQo+ID4gKwkJLmJ1Zl90eXBlID0g VjRMMl9CVUZfVFlQRV9NRVRBX0NBUFRVUkUsDQo+ID4gKwkJLmxpbmtfZmxhZ3MgPSAwLA0KPiA+ ICsJCS5pbWFnZSA9IGZhbHNlLA0KPiA+ICsJCS5zbWVtX2FsbG9jID0gZmFsc2UsDQo+ID4gKwkJ LmRtYV9wb3J0ID0gUl9MTVZPLA0KPiA+ICsJCS5mbXRzID0gbWV0YV9mbXRzLA0KPiA+ICsJCS5k ZWZhdWx0X2ZtdF9pZHggPSA0LA0KPiA+ICsJCS5tYXhfYnVmX2NvdW50ID0gMTAsDQo+ID4gKwkJ LmlvY3RsX29wcyA9ICZtdGtfY2FtX3Y0bDJfbWV0YV9jYXBfaW9jdGxfb3BzLA0KPiA+ICsJfSwN Cj4gPiArfTsNCj4gPiArDQo+ID4gKy8qIFRoZSBoZWxwZXIgdG8gY29uZmlndXJlIHRoZSBkZXZp Y2UgY29udGV4dCAqLw0KPiA+ICtzdGF0aWMgdm9pZCBtdGtfY2FtX2Rldl9xdWV1ZV9zZXR1cChz dHJ1Y3QgbXRrX2NhbV9kZXYgKmNhbSkNCj4gPiArew0KPiA+ICsJdW5zaWduZWQgaW50IG5vZGVf aWR4Ow0KPiA+ICsJaW50IGk7DQo+ID4gKw0KPiA+ICsJbm9kZV9pZHggPSAwOw0KPiA+ICsJLyog U2V0dXAgdGhlIG91dHB1dCBxdWV1ZSAqLw0KPiA+ICsJZm9yIChpID0gMDsgaSA8IEFSUkFZX1NJ WkUob3V0cHV0X3F1ZXVlcyk7IGkrKykNCj4gPiArCQljYW0tPnZkZXZfbm9kZXNbbm9kZV9pZHgr K10uZGVzYyA9IG91dHB1dF9xdWV1ZXNbaV07DQo+ID4gKw0KPiA+ICsJLyogU2V0dXAgdGhlIGNh cHR1cmUgcXVldWUgKi8NCj4gPiArCWZvciAoaSA9IDA7IGkgPCBBUlJBWV9TSVpFKGNhcHR1cmVf cXVldWVzKTsgaSsrKQ0KPiA+ICsJCWNhbS0+dmRldl9ub2Rlc1tub2RlX2lkeCsrXS5kZXNjID0g Y2FwdHVyZV9xdWV1ZXNbaV07DQo+ID4gK30NCj4gPiArDQo+ID4gK2ludCBtdGtfY2FtX2Rldl9p bml0KHN0cnVjdCBwbGF0Zm9ybV9kZXZpY2UgKnBkZXYsDQo+ID4gKwkJICAgICBzdHJ1Y3QgbXRr X2NhbV9kZXYgKmNhbSkNCj4gPiArew0KPiA+ICsJaW50IHJldDsNCj4gPiArDQo+ID4gKwljYW0t PmRldiA9ICZwZGV2LT5kZXY7DQo+ID4gKwltdGtfY2FtX2Rldl9xdWV1ZV9zZXR1cChjYW0pOw0K PiA+ICsNCj4gPiArCXNwaW5fbG9ja19pbml0KCZjYW0tPnBlbmRpbmdfam9iX2xvY2spOw0KPiA+ ICsJc3Bpbl9sb2NrX2luaXQoJmNhbS0+cnVubmluZ19qb2JfbG9jayk7DQo+ID4gKwlJTklUX0xJ U1RfSEVBRCgmY2FtLT5wZW5kaW5nX2pvYl9saXN0KTsNCj4gPiArCUlOSVRfTElTVF9IRUFEKCZj YW0tPnJ1bm5pbmdfam9iX2xpc3QpOw0KPiA+ICsJbXV0ZXhfaW5pdCgmY2FtLT5vcF9sb2NrKTsN Cj4gPiArDQo+ID4gKwkvKiB2NGwyIHN1Yi1kZXZpY2UgcmVnaXN0cmF0aW9uICovDQo+ID4gKwly ZXQgPSBtdGtfY2FtX3Y0bDJfcmVnaXN0ZXIoY2FtKTsNCj4gPiArCWlmIChyZXQpDQo+ID4gKwkJ cmV0dXJuIHJldDsNCj4gPiArDQo+ID4gKwlyZXQgPSBtdGtfY2FtX3Y0bDJfYXN5bmNfcmVnaXN0 ZXIoY2FtKTsNCj4gPiArCWlmIChyZXQpDQo+ID4gKwkJZ290byBmYWlsX3Y0bDJfdW5yZWc7DQo+ ID4gKw0KPiA+ICsJcmV0dXJuIDA7DQo+ID4gKw0KPiA+ICtmYWlsX3Y0bDJfdW5yZWc6DQo+ID4g KwltdXRleF9kZXN0cm95KCZjYW0tPm9wX2xvY2spOw0KPiA+ICsJbXRrX2NhbV92NGwyX3VucmVn aXN0ZXIoY2FtKTsNCj4gPiArDQo+ID4gKwlyZXR1cm4gcmV0Ow0KPiA+ICt9DQo+ID4gKw0KPiA+ ICt2b2lkIG10a19jYW1fZGV2X2NsZWFudXAoc3RydWN0IG10a19jYW1fZGV2ICpjYW0pDQo+ID4g K3sNCj4gPiArCW10a19jYW1fdjRsMl9hc3luY191bnJlZ2lzdGVyKGNhbSk7DQo+ID4gKwltdGtf Y2FtX3Y0bDJfdW5yZWdpc3RlcihjYW0pOw0KPiA+ICsJbXV0ZXhfZGVzdHJveSgmY2FtLT5vcF9s b2NrKTsNCj4gPiArfQ0KPiA+ICsNCj4gPiBkaWZmIC0tZ2l0IGEvZHJpdmVycy9tZWRpYS9wbGF0 Zm9ybS9tdGstaXNwL2lzcF81MC9jYW0vbXRrX2NhbS5oIGIvZHJpdmVycy9tZWRpYS9wbGF0Zm9y bS9tdGstaXNwL2lzcF81MC9jYW0vbXRrX2NhbS5oDQo+ID4gbmV3IGZpbGUgbW9kZSAxMDA2NDQN Cj4gPiBpbmRleCAwMDAwMDAwMDAwMDAuLjBhMzQwYTFlNjVlYQ0KPiA+IC0tLSAvZGV2L251bGwN Cj4gPiArKysgYi9kcml2ZXJzL21lZGlhL3BsYXRmb3JtL210ay1pc3AvaXNwXzUwL2NhbS9tdGtf Y2FtLmgNCj4gPiBAQCAtMCwwICsxLDI0NCBAQA0KPiA+ICsvKiBTUERYLUxpY2Vuc2UtSWRlbnRp ZmllcjogR1BMLTIuMCAqLw0KPiA+ICsvKg0KPiA+ICsgKiBDb3B5cmlnaHQgKGMpIDIwMTkgTWVk aWFUZWsgSW5jLg0KPiA+ICsgKi8NCj4gPiArDQo+ID4gKyNpZm5kZWYgX19NVEtfQ0FNX0hfXw0K PiA+ICsjZGVmaW5lIF9fTVRLX0NBTV9IX18NCj4gPiArDQo+ID4gKyNpbmNsdWRlIDxsaW51eC9k ZXZpY2UuaD4NCj4gPiArI2luY2x1ZGUgPGxpbnV4L3R5cGVzLmg+DQo+ID4gKyNpbmNsdWRlIDxs aW51eC9wbGF0Zm9ybV9kZXZpY2UuaD4NCj4gPiArI2luY2x1ZGUgPGxpbnV4L3NwaW5sb2NrLmg+ DQo+ID4gKyNpbmNsdWRlIDxsaW51eC92aWRlb2RldjIuaD4NCj4gPiArI2luY2x1ZGUgPG1lZGlh L3Y0bDItZGV2aWNlLmg+DQo+ID4gKyNpbmNsdWRlIDxtZWRpYS92NGwyLWN0cmxzLmg+DQo+ID4g KyNpbmNsdWRlIDxtZWRpYS92NGwyLXN1YmRldi5oPg0KPiA+ICsjaW5jbHVkZSA8bWVkaWEvdmlk ZW9idWYyLWNvcmUuaD4NCj4gPiArI2luY2x1ZGUgPG1lZGlhL3ZpZGVvYnVmMi12NGwyLmg+DQo+ ID4gKw0KPiA+ICsjaW5jbHVkZSAibXRrX2NhbS1pcGkuaCINCj4gPiArDQo+ID4gKyNkZWZpbmUg SU1HX01BWF9XSURUSAkJNTM3Ng0KPiA+ICsjZGVmaW5lIElNR19NQVhfSEVJR0hUCQk0MDMyDQo+ ID4gKyNkZWZpbmUgSU1HX01JTl9XSURUSAkJODANCj4gPiArI2RlZmluZSBJTUdfTUlOX0hFSUdI VAkJNjANCj4gPiArDQo+ID4gKy8qDQo+ID4gKyAqIElEIGVudW0gdmFsdWUgZm9yIHN0cnVjdCBt dGtfY2FtX2Rldl9ub2RlX2Rlc2M6aWQNCj4gPiArICogb3IgbXRrX2NhbV92aWRlb19kZXZpY2U6 aWQNCj4gPiArICovDQo+ID4gK2VudW0gIHsNCj4gPiArCU1US19DQU1fUDFfTUVUQV9JTl8wID0g MCwNCj4gPiArCU1US19DQU1fUDFfTUFJTl9TVFJFQU1fT1VULA0KPiA+ICsJTVRLX0NBTV9QMV9Q QUNLRURfQklOX09VVCwNCj4gPiArCU1US19DQU1fUDFfTUVUQV9PVVRfMCwNCj4gPiArCU1US19D QU1fUDFfTUVUQV9PVVRfMSwNCj4gPiArCU1US19DQU1fUDFfTUVUQV9PVVRfMiwNCj4gPiArCU1U S19DQU1fUDFfTUVUQV9PVVRfMywNCj4gPiArCU1US19DQU1fUDFfVE9UQUxfTk9ERVMNCj4gPiAr fTsNCj4gPiArDQo+ID4gKy8qIFN1cHBvcnRlZCBpbWFnZSBmb3JtYXQgbGlzdCAqLw0KPiA+ICsj ZGVmaW5lIE1US19DQU1fSU1HX0ZNVF9VTktOT1dOCQkweDAwMDANCj4gPiArI2RlZmluZSBNVEtf Q0FNX0lNR19GTVRfQkFZRVI4CQkweDIyMDANCj4gPiArI2RlZmluZSBNVEtfQ0FNX0lNR19GTVRf QkFZRVIxMAkJMHgyMjAxDQo+ID4gKyNkZWZpbmUgTVRLX0NBTV9JTUdfRk1UX0JBWUVSMTIJCTB4 MjIwMg0KPiA+ICsjZGVmaW5lIE1US19DQU1fSU1HX0ZNVF9CQVlFUjE0CQkweDIyMDMNCj4gPiAr I2RlZmluZSBNVEtfQ0FNX0lNR19GTVRfRkdfQkFZRVI4CTB4MjIwNA0KPiA+ICsjZGVmaW5lIE1U S19DQU1fSU1HX0ZNVF9GR19CQVlFUjEwCTB4MjIwNQ0KPiA+ICsjZGVmaW5lIE1US19DQU1fSU1H X0ZNVF9GR19CQVlFUjEyCTB4MjIwNg0KPiA+ICsjZGVmaW5lIE1US19DQU1fSU1HX0ZNVF9GR19C QVlFUjE0CTB4MjIwNw0KPiA+ICsNCj4gPiArLyogU3VwcG9ydGVkIGJheWVyIHBpeGVsIG9yZGVy ICovDQo+ID4gKyNkZWZpbmUgTVRLX0NBTV9SQVdfUFhMX0lEX0IJCTANCj4gPiArI2RlZmluZSBN VEtfQ0FNX1JBV19QWExfSURfR0IJCTENCj4gPiArI2RlZmluZSBNVEtfQ0FNX1JBV19QWExfSURf R1IJCTINCj4gPiArI2RlZmluZSBNVEtfQ0FNX1JBV19QWExfSURfUgkJMw0KPiA+ICsjZGVmaW5l IE1US19DQU1fUkFXX1BYTF9JRF9VTktOT1dOCTQNCj4gPiArDQo+ID4gKy8qDQo+ID4gKyAqIHN0 cnVjdCBtdGtfcDFfZnJhbWVfcGFyYW0gLSBNVEsgSVNQIFAxIGRyaXZlciBmcmFtZSBwYXJhbWV0 ZXJzLg0KPiA+ICsgKg0KPiA+ICsgKiBAZnJhbWVfc2VxX25vOiBUaGUgZnJhbWUgc2VxdWVuY2Ug b2YgZnJhbWUgaW4gZHJpdmVyIGxheWVyLg0KPiA+ICsgKiBAZG1hX2J1ZnM6IFRoZSBETUEgYnVm ZmVyIGFkZHJlc3MgaW5mb3JtYXRpb24gb2YgZW5hYmxlZCBETUEgbm9kZXMuDQo+ID4gKyAqDQo+ ID4gKyAqLw0KPiA+ICtzdHJ1Y3QgbXRrX3AxX2ZyYW1lX3BhcmFtIHsNCj4gPiArCXVuc2lnbmVk IGludCBmcmFtZV9zZXFfbm87DQo+ID4gKwlzdHJ1Y3QgZG1hX2J1ZmZlciBkbWFfYnVmc1tNVEtf Q0FNX1AxX1RPVEFMX05PREVTXTsNCj4gPiArfSBfX3BhY2tlZDsNCj4gPiArDQo+ID4gKy8qDQo+ ID4gKyAqIHN0cnVjdCBtdGtfY2FtX2Rldl9yZXF1ZXN0IC0gTVRLIGNhbWVyYSBkZXZpY2UgcmVx dWVzdC4NCj4gPiArICoNCj4gPiArICogQHJlcTogRW1iZWRkZWQgc3RydWN0IG1lZGlhIHJlcXVl c3QuDQo+ID4gKyAqIEBmcmFtZV9wYXJhbXM6IFRoZSBmcmFtZSBpbmZvLiAmIGFkZHJlc3MgaW5m by4gb2YgZW5hYmxlZCBETUEgbm9kZXMuDQo+ID4gKyAqIEBmcmFtZV93b3JrOiB3b3JrIHF1ZXVl IGVudHJ5IGZvciBmcmFtZSB0cmFuc21pc3Npb24gdG8gU0NQLg0KPiA+ICsgKiBAbGlzdDogTGlz dCBlbnRyeSBvZiB0aGUgb2JqZWN0IGZvciBAc3RydWN0IG10a19jYW1fZGV2Og0KPiA+ICsgKiAg ICAgICAgcGVuZGluZ19qb2JfbGlzdCBvciBydW5uaW5nX2pvYl9saXN0Lg0KPiA+ICsgKiBAdGlt ZXN0YW1wOiBTdGFydCBvZiBmcmFtZSB0aW1lc3RhbXAgaW4gbnMNCj4gPiArICoNCj4gPiArICov DQo+ID4gK3N0cnVjdCBtdGtfY2FtX2Rldl9yZXF1ZXN0IHsNCj4gPiArCXN0cnVjdCBtZWRpYV9y ZXF1ZXN0IHJlcTsNCj4gPiArCXN0cnVjdCBtdGtfcDFfZnJhbWVfcGFyYW0gZnJhbWVfcGFyYW1z Ow0KPiA+ICsJc3RydWN0IHdvcmtfc3RydWN0IGZyYW1lX3dvcms7DQo+ID4gKwlzdHJ1Y3QgbGlz dF9oZWFkIGxpc3Q7DQo+ID4gKwl1NjQgdGltZXN0YW1wOw0KPiA+ICt9Ow0KPiA+ICsNCj4gPiAr LyoNCj4gPiArICogc3RydWN0IG10a19jYW1fZGV2X2J1ZmZlciAtIE1USyBjYW1lcmEgZGV2aWNl IGJ1ZmZlci4NCj4gPiArICoNCj4gPiArICogQHZiYjogRW1iZWRkZWQgc3RydWN0IHZiMl92NGwy X2J1ZmZlci4NCj4gPiArICogQGxpc3Q6IExpc3QgZW50cnkgb2YgdGhlIG9iamVjdCBmb3IgQHN0 cnVjdCBtdGtfY2FtX3ZpZGVvX2RldmljZToNCj4gPiArICogICAgICAgIGJ1Zl9saXN0Lg0KPiA+ ICsgKiBAZGFkZHI6IFRoZSBETUEgYWRkcmVzcyBvZiB0aGlzIGJ1ZmZlci4NCj4gPiArICogQHNj cF9hZGRyOiBUaGUgU0NQIGFkZHJlc3Mgb2YgdGhpcyBidWZmZXIgd2hpY2gNCj4gPiArICogICAg ICAgICAgICBpcyBvbmx5IHN1cHBvcnRlZCBmb3IgbWV0YSBpbnB1dCBub2RlLg0KPiA+ICsgKiBA bm9kZV9pZDogVGhlIHZpZG9lIG5vZGUgaWQgd2hpY2ggdGhpcyBidWZmZXIgYmVsb25ncyB0by4N Cj4gPiArICoNCj4gPiArICovDQo+ID4gK3N0cnVjdCBtdGtfY2FtX2Rldl9idWZmZXIgew0KPiA+ ICsJc3RydWN0IHZiMl92NGwyX2J1ZmZlciB2YmI7DQo+ID4gKwlzdHJ1Y3QgbGlzdF9oZWFkIGxp c3Q7DQo+ID4gKwkvKiBJbnRlbmFsIHBhcnQgKi8NCj4gPiArCWRtYV9hZGRyX3QgZGFkZHI7DQo+ ID4gKwlkbWFfYWRkcl90IHNjcF9hZGRyOw0KPiA+ICsJdW5zaWduZWQgaW50IG5vZGVfaWQ7DQo+ ID4gK307DQo+ID4gKw0KPiA+ICsvKg0KPiA+ICsgKiBzdHJ1Y3QgbXRrX2NhbV9kZXZfbm9kZV9k ZXNjIC0gTVRLIGNhbWVyYSBkZXZpY2Ugbm9kZSBkZXNjcmlwdG9yDQo+ID4gKyAqDQo+ID4gKyAq IEBpZDogaWQgb2YgdGhlIG5vZGUNCj4gPiArICogQG5hbWU6IG5hbWUgb2YgdGhlIG5vZGUNCj4g PiArICogQGNhcDogc3VwcG9ydGVkIFY0TDIgY2FwYWJpbGl0aWVzDQo+ID4gKyAqIEBidWZfdHlw ZTogc3VwcG9ydGVkIFY0TDIgYnVmZmVyIHR5cGUNCj4gPiArICogQGRtYV9wb3J0OiB0aGUgZG1h IHBvcnRzIGFzc29jaWF0ZWQgdG8gdGhlIG5vZGUNCj4gPiArICogQGxpbmtfZmxhZ3M6IGRlZmF1 bHQgbWVkaWEgbGluayBmbGFncw0KPiA+ICsgKiBAc21lbV9hbGxvYzogdXNpbmcgdGhlIHNtZW1f ZGV2IGFzIGFsbG9jIGRldmljZSBvciBub3QNCj4gPiArICogQGltYWdlOiB0cnVlIGZvciBpbWFn ZSBub2RlLCBmYWxzZSBmb3IgbWV0YSBub2RlDQo+ID4gKyAqIEBudW1fZm10czogdGhlIG51bWJl ciBvZiBzdXBwb3J0ZWQgbm9kZSBmb3JtYXRzDQo+ID4gKyAqIEBkZWZhdWx0X2ZtdF9pZHg6IGRl ZmF1bHQgZm9ybWF0IG9mIHRoaXMgbm9kZQ0KPiA+ICsgKiBAbWF4X2J1Zl9jb3VudDogbWF4aW11 bSBWQjIgYnVmZmVyIGNvdW50DQo+ID4gKyAqIEBpb2N0bF9vcHM6ICBtYXBwZWQgdG8gdjRsMl9p b2N0bF9vcHMNCj4gPiArICogQGZtdHM6IHN1cHBvcnRlZCBmb3JtYXQNCj4gPiArICogQGZybXNp emVzOiBzdXBwb3J0ZWQgVjRMMiBmcmFtZSBzaXplIG51bWJlcg0KPiA+ICsgKg0KPiA+ICsgKi8N Cj4gPiArc3RydWN0IG10a19jYW1fZGV2X25vZGVfZGVzYyB7DQo+ID4gKwl1OCBpZDsNCj4gPiAr CWNvbnN0IGNoYXIgKm5hbWU7DQo+ID4gKwl1MzIgY2FwOw0KPiA+ICsJdTMyIGJ1Zl90eXBlOw0K PiA+ICsJdTMyIGRtYV9wb3J0Ow0KPiA+ICsJdTMyIGxpbmtfZmxhZ3M7DQo+ID4gKwl1OCBzbWVt X2FsbG9jOjE7DQo+ID4gKwl1OCBpbWFnZToxOw0KPiA+ICsJdTggbnVtX2ZtdHM7DQo+ID4gKwl1 OCBkZWZhdWx0X2ZtdF9pZHg7DQo+ID4gKwl1OCBtYXhfYnVmX2NvdW50Ow0KPiA+ICsJY29uc3Qg c3RydWN0IHY0bDJfaW9jdGxfb3BzICppb2N0bF9vcHM7DQo+ID4gKwljb25zdCBzdHJ1Y3QgdjRs Ml9mb3JtYXQgKmZtdHM7DQo+ID4gKwljb25zdCBzdHJ1Y3QgdjRsMl9mcm1zaXplZW51bSAqZnJt c2l6ZXM7DQo+ID4gK307DQo+ID4gKw0KPiA+ICsvKg0KPiA+ICsgKiBzdHJ1Y3QgbXRrX2NhbV92 aWRlb19kZXZpY2UgLSBNZWRpYXRlayB2aWRlbyBkZXZpY2Ugc3RydWN0dXJlDQo+ID4gKyAqDQo+ ID4gKyAqIEBpZDogSWQgZm9yIGluZGV4IG9mIG10a19jYW1fZGV2OnZkZXZfbm9kZXMgYXJyYXkN Cj4gPiArICogQGVuYWJsZWQ6IEluZGljYXRlIHRoZSB2aWRlbyBkZXZpY2UgaXMgZW5hYmxlZCBv ciBub3QNCj4gPiArICogQGRlc2M6IFRoZSBub2RlIGRlc2NyaXB0aW9uIG9mIHZpZGVvIGRldmlj ZQ0KPiA+ICsgKiBAdmRldl9mbXQ6IFRoZSBWNEwyIGZvcm1hdCBvZiB2aWRlbyBkZXZpY2UNCj4g PiArICogQHZkZXZfcGFkOiBUaGUgbWVkaWEgcGFkIGdyYXBoIG9iamVjdCBvZiB2aWRlbyBkZXZp Y2UNCj4gPiArICogQHZicTogQSB2aWRlb2J1ZiBxdWV1ZSBvZiB2aWRlbyBkZXZpY2UNCj4gPiAr ICogQHZkZXY6IFRoZSB2aWRlbyBkZXZpY2UgaW5zdGFuY2UNCj4gPiArICogQHZkZXZfbG9jazog U2VyaWFsaXplcyB2YjIgcXVldWUgYW5kIHZpZGVvIGRldmljZSBvcGVyYXRpb25zDQo+ID4gKyAq IEBidWZfbGlzdDogTGlzdCBmb3IgZW5xdWV1ZSBidWZmZXJzDQo+ID4gKyAqIEBidWZfbGlzdF9s b2NrOiBMb2NrIHVzZWQgdG8gcHJvdGVjdCBidWZmZXIgbGlzdC4NCj4gPiArICoNCj4gPiArICov DQo+ID4gK3N0cnVjdCBtdGtfY2FtX3ZpZGVvX2RldmljZSB7DQo+ID4gKwl1bnNpZ25lZCBpbnQg aWQ7DQo+ID4gKwl1bnNpZ25lZCBpbnQgZW5hYmxlZDsNCj4gPiArCXN0cnVjdCBtdGtfY2FtX2Rl dl9ub2RlX2Rlc2MgZGVzYzsNCj4gPiArCXN0cnVjdCB2NGwyX2Zvcm1hdCB2ZGV2X2ZtdDsNCj4g PiArCXN0cnVjdCBtZWRpYV9wYWQgdmRldl9wYWQ7DQo+ID4gKwlzdHJ1Y3QgdmIyX3F1ZXVlIHZi cTsNCj4gPiArCXN0cnVjdCB2aWRlb19kZXZpY2UgdmRldjsNCj4gPiArCS8qIFNlcmlhbGl6ZXMg dmIyIHF1ZXVlIGFuZCB2aWRlbyBkZXZpY2Ugb3BlcmF0aW9ucyAqLw0KPiA+ICsJc3RydWN0IG11 dGV4IHZkZXZfbG9jazsNCj4gPiArCXN0cnVjdCBsaXN0X2hlYWQgYnVmX2xpc3Q7DQo+ID4gKwkv KiBMb2NrIHVzZWQgdG8gcHJvdGVjdCBidWZmZXIgbGlzdCAqLw0KPiA+ICsJc3BpbmxvY2tfdCBi dWZfbGlzdF9sb2NrOw0KPiA+ICt9Ow0KPiA+ICsNCj4gPiArLyoNCj4gPiArICogc3RydWN0IG10 a19jYW1fZGV2IC0gTWVkaWF0ZWsgY2FtZXJhIGRldmljZSBzdHJ1Y3R1cmUuDQo+ID4gKyAqDQo+ ID4gKyAqIEBkZXY6IFBvaW50ZXIgdG8gZGV2aWNlLg0KPiA+ICsgKiBAc21lbV9wZGV2OiBQb2lu dGVyIHRvIHNoYXJlZCBtZW1vcnkgZGV2aWNlLg0KPiA+ICsgKiBAcGlwZWxpbmU6IE1lZGlhIHBp cGVsaW5lIGluZm9ybWF0aW9uLg0KPiA+ICsgKiBAbWVkaWFfZGV2OiBNZWRpYSBkZXZpY2UgaW5z dGFuY2UuDQo+ID4gKyAqIEBzdWJkZXY6IFRoZSBWNEwyIHN1Yi1kZXZpY2UgaW5zdGFuY2UuDQo+ ID4gKyAqIEB2NGwyX2RldjogVGhlIFY0TDIgZGV2aWNlIGRyaXZlciBpbnN0YW5jZS4NCj4gPiAr ICogQG5vdGlmaWVyOiBUaGUgdjRsMl9kZXZpY2Ugbm90aWZpZXIgZGF0YS4NCj4gPiArICogQHN1 YmRldl9wYWRzOiBQb2ludGVyIHRvIHRoZSBudW1iZXIgb2YgbWVkaWEgcGFkcyBvZiB0aGlzIHN1 Yi1kZXZpY2UuDQo+ID4gKyAqIEB2ZGV2X25vZGVzOiBUaGUgYXJyYXkgbGlzdCBvZiBtdGtfY2Ft X3ZpZGVvX2RldmljZSBub2Rlcy4NCj4gPiArICogQHNlbmluZjogUG9pbnRlciB0byB0aGUgc2Vu aW5mIHN1Yi1kZXZpY2UuDQo+ID4gKyAqIEBzZW5zb3I6IFBvaW50ZXIgdG8gdGhlIGFjdGl2ZSBz ZW5zb3IgVjRMMiBzdWItZGV2aWNlIHdoZW4gc3RyZWFtaW5nIG9uLg0KPiA+ICsgKiBAc3RyZWFt aW5nOiBJbmRpY2F0ZSB0aGUgb3ZlcmFsbCBzdHJlYW1pbmcgc3RhdHVzIGlzIG9uIG9yIG9mZi4N Cj4gPiArICogQGVuYWJsZWRfZG1hczogVGhlIGVuYWJsZWQgZG1hIHBvcnQgaW5mb3JtYXRpb24g d2hlbiBzdHJlYW1pbmcgb24uDQo+ID4gKyAqIEBlbmFibGVkX2NvdW50OiBOdW1iZXIgb2YgZW5h YmxlZCB2aWRlbyBub2Rlcw0KPiA+ICsgKiBAc3RyZWFtX2NvdW50OiBOdW1iZXIgb2Ygc3RyZWFt aW5nIHZpZGVvIG5vZGVzDQo+ID4gKyAqIEBydW5uaW5nX2pvYl9jb3VudDogTnVuYmVyIG9mIHJ1 bm5pbmcgam9icyBpbiB0aGUgSFcgZHJpdmVyLg0KPiA+ICsgKiBAcGVuZGluZ19qb2JfbGlzdDog TGlzdCB0byBrZWVwIHRoZSBtZWRpYSByZXF1ZXN0cyBiZWZvcmUgZW4tcXVldWUgaW50bw0KPiA+ ICsgKiAgICAgICAgICAgICAgICAgICAgSFcgZHJpdmVyLg0KPiA+ICsgKiBAcGVuZGluZ19qb2Jf bG9jazogUHJvdGVjdCB0aGUgcGVuZGluZ19qb2JfbGlzdCBkYXRhICYgcnVubmluZ19qb2JfY291 bnQuDQo+ID4gKyAqIEBydW5uaW5nX2pvYl9saXN0OiBMaXN0IHRvIGtlZXAgdGhlIG1lZGlhIHJl cXVlc3RzIGFmdGVyIGVuLXF1ZXVlIGludG8NCj4gPiArICogICAgICAgICAgICAgICAgICAgIEhX IGRyaXZlci4NCj4gPiArICogQHJ1bm5pbmdfam9iX2xvY2s6IFByb3RlY3QgdGhlIHJ1bm5pbmdf am9iX2xpc3QgZGF0YS4NCj4gPiArICogQG9wX2xvY2s6IFNlcmlhbGl6ZXMgZHJpdmVyJ3MgVkIy IGNhbGxiYWNrIG9wZXJhdGlvbnMuDQo+ID4gKyAqDQo+ID4gKyAqLw0KPiA+ICtzdHJ1Y3QgbXRr X2NhbV9kZXYgew0KPiA+ICsJc3RydWN0IGRldmljZSAqZGV2Ow0KPiA+ICsJc3RydWN0IGRldmlj ZSAqc21lbV9kZXY7DQo+ID4gKwlzdHJ1Y3QgbWVkaWFfcGlwZWxpbmUgcGlwZWxpbmU7DQo+ID4g KwlzdHJ1Y3QgbWVkaWFfZGV2aWNlIG1lZGlhX2RldjsNCj4gPiArCXN0cnVjdCB2NGwyX3N1YmRl diBzdWJkZXY7DQo+ID4gKwlzdHJ1Y3QgdjRsMl9kZXZpY2UgdjRsMl9kZXY7DQo+ID4gKwlzdHJ1 Y3QgdjRsMl9hc3luY19ub3RpZmllciBub3RpZmllcjsNCj4gPiArCXN0cnVjdCBtZWRpYV9wYWQg KnN1YmRldl9wYWRzOw0KPiA+ICsJc3RydWN0IG10a19jYW1fdmlkZW9fZGV2aWNlIHZkZXZfbm9k ZXNbTVRLX0NBTV9QMV9UT1RBTF9OT0RFU107DQo+ID4gKwlzdHJ1Y3QgdjRsMl9zdWJkZXYgKnNl bmluZjsNCj4gPiArCXN0cnVjdCB2NGwyX3N1YmRldiAqc2Vuc29yOw0KPiA+ICsJdW5zaWduZWQg aW50IHN0cmVhbWluZzsNCj4gPiArCXVuc2lnbmVkIGludCBlbmFibGVkX2RtYXM7DQo+ID4gKwl1 bnNpZ25lZCBpbnQgZW5hYmxlZF9jb3VudDsNCj4gPiArCXVuc2lnbmVkIGludCBzdHJlYW1fY291 bnQ7DQo+ID4gKwl1bnNpZ25lZCBpbnQgcnVubmluZ19qb2JfY291bnQ7DQo+ID4gKwlzdHJ1Y3Qg bGlzdF9oZWFkIHBlbmRpbmdfam9iX2xpc3Q7DQo+ID4gKwkvKiBQcm90ZWN0IHRoZSBwZW5kaW5n X2pvYl9saXN0IGRhdGEgKi8NCj4gPiArCXNwaW5sb2NrX3QgcGVuZGluZ19qb2JfbG9jazsNCj4g PiArCXN0cnVjdCBsaXN0X2hlYWQgcnVubmluZ19qb2JfbGlzdDsNCj4gPiArCS8qIFByb3RlY3Qg dGhlIHJ1bm5pbmdfam9iX2xpc3QgZGF0YSAmIHJ1bm5pbmdfam9iX2NvdW50ICovDQo+ID4gKwlz cGlubG9ja190IHJ1bm5pbmdfam9iX2xvY2s7DQo+ID4gKwkvKiBTZXJpYWxpemVzIGRyaXZlcidz IFZCMiBjYWxsYmFjayBvcGVyYXRpb25zICovDQo+ID4gKwlzdHJ1Y3QgbXV0ZXggb3BfbG9jazsN Cj4gPiArfTsNCj4gPiArDQo+ID4gK2ludCBtdGtfY2FtX2Rldl9pbml0KHN0cnVjdCBwbGF0Zm9y bV9kZXZpY2UgKnBkZXYsDQo+ID4gKwkJICAgICBzdHJ1Y3QgbXRrX2NhbV9kZXYgKmNhbV9kZXYp Ow0KPiA+ICt2b2lkIG10a19jYW1fZGV2X2NsZWFudXAoc3RydWN0IG10a19jYW1fZGV2ICpjYW1f ZGV2KTsNCj4gPiArdm9pZCBtdGtfY2FtX2Rldl9yZXFfdHJ5X3F1ZXVlKHN0cnVjdCBtdGtfY2Ft X2RldiAqY2FtX2Rldik7DQo+ID4gK3ZvaWQgbXRrX2NhbV9kZXZfZGVxdWV1ZV9yZXFfZnJhbWUo c3RydWN0IG10a19jYW1fZGV2ICpjYW1fZGV2LA0KPiA+ICsJCQkJICAgdW5zaWduZWQgaW50IGZy YW1lX3NlcV9ubyk7DQo+ID4gK3ZvaWQgbXRrX2NhbV9kZXZfZXZlbnRfZnJhbWVfc3luYyhzdHJ1 Y3QgbXRrX2NhbV9kZXYgKmNhbV9kZXYsDQo+ID4gKwkJCQkgIHVuc2lnbmVkIGludCBmcmFtZV9z ZXFfbm8pOw0KPiA+ICtzdHJ1Y3QgbXRrX2NhbV9kZXZfcmVxdWVzdCAqbXRrX2NhbV9kZXZfZ2V0 X3JlcShzdHJ1Y3QgbXRrX2NhbV9kZXYgKmNhbSwNCj4gPiArCQkJCQkJdW5zaWduZWQgaW50IGZy YW1lX3NlcV9ubyk7DQo+ID4gKw0KPiA+ICsjZW5kaWYgLyogX19NVEtfQ0FNX0hfXyAqLw0KPiA+ IA0KPiANCj4gX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX18N Cj4gTGludXgtbWVkaWF0ZWsgbWFpbGluZyBsaXN0DQo+IExpbnV4LW1lZGlhdGVrQGxpc3RzLmlu ZnJhZGVhZC5vcmcNCj4gaHR0cDovL2xpc3RzLmluZnJhZGVhZC5vcmcvbWFpbG1hbi9saXN0aW5m by9saW51eC1tZWRpYXRlaw0KDQo=