From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 90885C43217 for ; Thu, 20 Oct 2022 07:26:59 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229921AbiJTH06 (ORCPT ); Thu, 20 Oct 2022 03:26:58 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42834 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229849AbiJTH0z (ORCPT ); Thu, 20 Oct 2022 03:26:55 -0400 Received: from twspam01.aspeedtech.com (twspam01.aspeedtech.com [211.20.114.71]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8899915CB09; Thu, 20 Oct 2022 00:26:48 -0700 (PDT) Received: from mail.aspeedtech.com ([192.168.0.24]) by twspam01.aspeedtech.com with ESMTP id 29K72xkV072568; Thu, 20 Oct 2022 15:02:59 +0800 (GMT-8) (envelope-from jammy_huang@aspeedtech.com) Received: from [192.168.2.115] (192.168.2.115) by TWMBX02.aspeed.com (192.168.0.24) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Thu, 20 Oct 2022 15:25:26 +0800 Message-ID: <14a96f82-0f36-e981-b6e1-31d662eded33@aspeedtech.com> Date: Thu, 20 Oct 2022 15:25:26 +0800 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:91.0) Gecko/20100101 Thunderbird/91.13.1 Subject: Re: [PATCH v9 3/4] media: aspeed: Support aspeed mode to reduce compressed data Content-Language: en-US To: Nicolas Dufresne , , , , , , , , , , , , , , , References: <20220921025112.13150-1-jammy_huang@aspeedtech.com> <20220921025112.13150-4-jammy_huang@aspeedtech.com> From: Jammy Huang In-Reply-To: Content-Type: text/plain; charset="UTF-8"; format=flowed Content-Transfer-Encoding: 8bit X-Originating-IP: [192.168.2.115] X-ClientProxiedBy: TWMBX02.aspeed.com (192.168.0.24) To TWMBX02.aspeed.com (192.168.0.24) X-DNSRBL: X-MAIL: twspam01.aspeedtech.com 29K72xkV072568 Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Hi Nocolas, On 2022/10/18 下午 11:20, Nicolas Dufresne wrote: > Hi, > > Le mercredi 21 septembre 2022 à 10:51 +0800, Jammy Huang a écrit : >> aspeed supports differential jpeg format which only compress the parts >> which are changed. In this way, it reduces both the amount of data to be >> transferred by network and those to be decoded on the client side. >> >> 2 new ctrls are added: >> * Aspeed HQ Mode: to control aspeed's high quality(2-pass) compression mode >> This only works with yuv444 subsampling. >> * Aspeed HQ Quality: to control the quality of aspeed's HQ mode >> only useful if Aspeed HQ mode is enabled >> >> Aspeed JPEG Format requires an additional buffer, called bcd, to store >> the information about which macro block in the new frame is different >> from the previous one. >> >> To have bcd correctly working, we need to swap the buffers for src0/1 to >> make src1 refer to previous frame and src0 to the coming new frame. >> >> Signed-off-by: Jammy Huang >> --- >> drivers/media/platform/aspeed/aspeed-video.c | 281 +++++++++++++++---- >> include/uapi/linux/aspeed-video.h | 15 + >> 2 files changed, 245 insertions(+), 51 deletions(-) >> create mode 100644 include/uapi/linux/aspeed-video.h >> >> diff --git a/drivers/media/platform/aspeed/aspeed-video.c b/drivers/media/platform/aspeed/aspeed-video.c >> index 20f795ccc11b..739288026418 100644 >> --- a/drivers/media/platform/aspeed/aspeed-video.c >> +++ b/drivers/media/platform/aspeed/aspeed-video.c >> @@ -33,6 +33,7 @@ >> #include >> #include >> #include >> +#include >> >> #define ASPEED_VIDEO_V4L2_MIN_BUF_REQ 3 >> >> @@ -59,6 +60,7 @@ >> >> #define VE_MAX_SRC_BUFFER_SIZE 0x8ca000 /* 1920 * 1200, 32bpp */ >> #define VE_JPEG_HEADER_SIZE 0x006000 /* 512 * 12 * 4 */ >> +#define VE_BCD_BUFF_SIZE 0x9000 /* (1920/8) * (1200/8) */ >> >> #define VE_PROTECTION_KEY 0x000 >> #define VE_PROTECTION_KEY_UNLOCK 0x1a038aa8 >> @@ -107,6 +109,13 @@ >> #define VE_SCALING_FILTER2 0x020 >> #define VE_SCALING_FILTER3 0x024 >> >> +#define VE_BCD_CTRL 0x02C >> +#define VE_BCD_CTRL_EN_BCD BIT(0) >> +#define VE_BCD_CTRL_EN_ABCD BIT(1) >> +#define VE_BCD_CTRL_EN_CB BIT(2) >> +#define VE_BCD_CTRL_THR GENMASK(23, 16) >> +#define VE_BCD_CTRL_ABCD_THR GENMASK(31, 24) >> + >> #define VE_CAP_WINDOW 0x030 >> #define VE_COMP_WINDOW 0x034 >> #define VE_COMP_PROC_OFFSET 0x038 >> @@ -115,6 +124,7 @@ >> #define VE_SRC0_ADDR 0x044 >> #define VE_SRC_SCANLINE_OFFSET 0x048 >> #define VE_SRC1_ADDR 0x04c >> +#define VE_BCD_ADDR 0x050 >> #define VE_COMP_ADDR 0x054 >> >> #define VE_STREAM_BUF_SIZE 0x058 >> @@ -135,6 +145,8 @@ >> #define VE_COMP_CTRL_HQ_DCT_CHR GENMASK(26, 22) >> #define VE_COMP_CTRL_HQ_DCT_LUM GENMASK(31, 27) >> >> +#define VE_CB_ADDR 0x06C >> + >> #define AST2400_VE_COMP_SIZE_READ_BACK 0x078 >> #define AST2600_VE_COMP_SIZE_READ_BACK 0x084 >> >> @@ -211,6 +223,12 @@ enum { >> VIDEO_CLOCKS_ON, >> }; >> >> +enum aspeed_video_format { >> + VIDEO_FMT_STANDARD = 0, >> + VIDEO_FMT_ASPEED, >> + VIDEO_FMT_MAX = VIDEO_FMT_ASPEED >> +}; >> + >> // for VE_CTRL_CAPTURE_FMT >> enum aspeed_video_capture_format { >> VIDEO_CAP_FMT_YUV_STUDIO_SWING = 0, >> @@ -245,16 +263,20 @@ struct aspeed_video_perf { >> /* >> * struct aspeed_video - driver data >> * >> - * res_work: holds the delayed_work for res-detection if unlock >> - * buffers: holds the list of buffer queued from user >> + * res_work: holds the delayed_work for res-detection if unlock >> + * buffers: holds the list of buffer queued from user >> * flags: holds the state of video >> * sequence: holds the last number of frame completed >> * max_compressed_size: holds max compressed stream's size >> * srcs: holds the buffer information for srcs >> * jpeg: holds the buffer information for jpeg header >> + * bcd: holds the buffer information for bcd work >> * yuv420: a flag raised if JPEG subsampling is 420 >> + * format: holds the video format >> + * hq_mode: a flag raised if HQ is enabled. Only for VIDEO_FMT_ASPEED >> * frame_rate: holds the frame_rate >> * jpeg_quality: holds jpeq's quality (0~11) >> + * jpeg_hq_quality: holds hq's quality (1~12) only if hq_mode enabled >> * frame_bottom: end position of video data in vertical direction >> * frame_left: start position of video data in horizontal direction >> * frame_right: end position of video data in horizontal direction >> @@ -290,10 +312,14 @@ struct aspeed_video { >> unsigned int max_compressed_size; >> struct aspeed_video_addr srcs[2]; >> struct aspeed_video_addr jpeg; >> + struct aspeed_video_addr bcd; >> >> bool yuv420; >> + enum aspeed_video_format format; >> + bool hq_mode; >> unsigned int frame_rate; >> unsigned int jpeg_quality; >> + unsigned int jpeg_hq_quality; >> >> unsigned int frame_bottom; >> unsigned int frame_left; >> @@ -458,8 +484,20 @@ static const struct v4l2_dv_timings_cap aspeed_video_timings_cap = { >> }, >> }; >> >> +static const char * const compress_scheme_str[] = {"DCT Only", >> + "DCT VQ mix 2-color", "DCT VQ mix 4-color"}; >> +static const char * const format_str[] = {"Standard JPEG", >> + "Aspeed JPEG"}; >> + >> static unsigned int debug; >> >> +static bool aspeed_video_alloc_buf(struct aspeed_video *video, >> + struct aspeed_video_addr *addr, >> + unsigned int size); >> + >> +static void aspeed_video_free_buf(struct aspeed_video *video, >> + struct aspeed_video_addr *addr); >> + >> static void aspeed_video_init_jpeg_table(u32 *table, bool yuv420) >> { >> int i; >> @@ -547,6 +585,7 @@ static int aspeed_video_start_frame(struct aspeed_video *video) >> unsigned long flags; >> struct aspeed_video_buffer *buf; >> u32 seq_ctrl = aspeed_video_read(video, VE_SEQ_CTRL); >> + bool bcd_buf_need = (video->format != VIDEO_FMT_STANDARD); >> >> if (video->v4l2_input_status) { >> v4l2_warn(&video->v4l2_dev, "No signal; don't start frame\n"); >> @@ -559,6 +598,20 @@ static int aspeed_video_start_frame(struct aspeed_video *video) >> return -EBUSY; >> } >> >> + if (bcd_buf_need && !video->bcd.size) { >> + if (!aspeed_video_alloc_buf(video, &video->bcd, >> + VE_BCD_BUFF_SIZE)) { >> + dev_err(video->dev, "Failed to allocate BCD buffer\n"); >> + dev_err(video->dev, "don't start frame\n"); >> + return -ENOMEM; >> + } >> + aspeed_video_write(video, VE_BCD_ADDR, video->bcd.dma); >> + v4l2_dbg(1, debug, &video->v4l2_dev, "bcd addr(%#x) size(%d)\n", >> + video->bcd.dma, video->bcd.size); >> + } else if (!bcd_buf_need && video->bcd.size) { >> + aspeed_video_free_buf(video, &video->bcd); >> + } >> + >> spin_lock_irqsave(&video->lock, flags); >> buf = list_first_entry_or_null(&video->buffers, >> struct aspeed_video_buffer, link); >> @@ -657,6 +710,24 @@ static void aspeed_video_irq_res_change(struct aspeed_video *video, ulong delay) >> schedule_delayed_work(&video->res_work, delay); >> } >> >> +static void aspeed_video_swap_src_buf(struct aspeed_video *v) >> +{ >> + if (v->format == VIDEO_FMT_STANDARD) >> + return; >> + >> + /* Reset bcd buffer to have a full frame update every 8 frames. */ >> + if (IS_ALIGNED(v->sequence, 8)) >> + memset((u8 *)v->bcd.virt, 0x00, VE_BCD_BUFF_SIZE); >> + >> + if (v->sequence & 0x01) { >> + aspeed_video_write(v, VE_SRC0_ADDR, v->srcs[1].dma); >> + aspeed_video_write(v, VE_SRC1_ADDR, v->srcs[0].dma); >> + } else { >> + aspeed_video_write(v, VE_SRC0_ADDR, v->srcs[0].dma); >> + aspeed_video_write(v, VE_SRC1_ADDR, v->srcs[1].dma); >> + } >> +} >> + >> static irqreturn_t aspeed_video_irq(int irq, void *arg) >> { >> struct aspeed_video *video = arg; >> @@ -705,6 +776,7 @@ static irqreturn_t aspeed_video_irq(int irq, void *arg) >> >> if (sts & VE_INTERRUPT_COMP_COMPLETE) { >> struct aspeed_video_buffer *buf; >> + bool empty = true; >> u32 frame_size = aspeed_video_read(video, >> video->comp_size_read); >> >> @@ -718,13 +790,23 @@ static irqreturn_t aspeed_video_irq(int irq, void *arg) >> if (buf) { >> vb2_set_plane_payload(&buf->vb.vb2_buf, 0, frame_size); >> >> - if (!list_is_last(&buf->link, &video->buffers)) { >> + /* >> + * aspeed_jpeg requires continuous update. >> + * On the contrary, standard jpeg can keep last buffer >> + * to always have the latest result. >> + */ >> + if (video->format == VIDEO_FMT_STANDARD && >> + list_is_last(&buf->link, &video->buffers)) { >> + empty = false; >> + v4l2_warn(&video->v4l2_dev, "skip to keep last frame updated\n"); >> + } else { >> buf->vb.vb2_buf.timestamp = ktime_get_ns(); >> buf->vb.sequence = video->sequence++; >> buf->vb.field = V4L2_FIELD_NONE; >> vb2_buffer_done(&buf->vb.vb2_buf, >> VB2_BUF_STATE_DONE); >> list_del(&buf->link); >> + empty = list_empty(&video->buffers); >> } >> } >> spin_unlock(&video->lock); >> @@ -738,7 +820,10 @@ static irqreturn_t aspeed_video_irq(int irq, void *arg) >> aspeed_video_write(video, VE_INTERRUPT_STATUS, >> VE_INTERRUPT_COMP_COMPLETE); >> sts &= ~VE_INTERRUPT_COMP_COMPLETE; >> - if (test_bit(VIDEO_STREAMING, &video->flags) && buf) >> + >> + aspeed_video_swap_src_buf(video); >> + >> + if (test_bit(VIDEO_STREAMING, &video->flags) && !empty) >> aspeed_video_start_frame(video); >> } >> >> @@ -1085,10 +1170,14 @@ static void aspeed_video_set_resolution(struct aspeed_video *video) >> FIELD_PREP(VE_TGS_FIRST, video->frame_top) | >> FIELD_PREP(VE_TGS_LAST, >> video->frame_bottom + 1)); >> - aspeed_video_update(video, VE_CTRL, 0, VE_CTRL_INT_DE); >> + aspeed_video_update(video, VE_CTRL, >> + VE_CTRL_INT_DE | VE_CTRL_DIRECT_FETCH, >> + VE_CTRL_INT_DE); >> } else { >> v4l2_dbg(1, debug, &video->v4l2_dev, "Capture: Direct Mode\n"); >> - aspeed_video_update(video, VE_CTRL, 0, VE_CTRL_DIRECT_FETCH); >> + aspeed_video_update(video, VE_CTRL, >> + VE_CTRL_INT_DE | VE_CTRL_DIRECT_FETCH, >> + VE_CTRL_DIRECT_FETCH); >> } >> >> size *= 4; >> @@ -1121,21 +1210,66 @@ static void aspeed_video_set_resolution(struct aspeed_video *video) >> aspeed_video_free_buf(video, &video->srcs[0]); >> } >> >> -static void aspeed_video_init_regs(struct aspeed_video *video) >> +static void aspeed_video_update_regs(struct aspeed_video *video) >> { >> - u32 comp_ctrl = VE_COMP_CTRL_RSVD | >> - FIELD_PREP(VE_COMP_CTRL_DCT_LUM, video->jpeg_quality) | >> - FIELD_PREP(VE_COMP_CTRL_DCT_CHR, video->jpeg_quality | 0x10); >> - u32 ctrl = VE_CTRL_AUTO_OR_CURSOR | >> - FIELD_PREP(VE_CTRL_CAPTURE_FMT, VIDEO_CAP_FMT_YUV_FULL_SWING); >> - u32 seq_ctrl = video->jpeg_mode; >> + u8 jpeg_hq_quality = clamp((int)video->jpeg_hq_quality - 1, 0, >> + ASPEED_VIDEO_JPEG_NUM_QUALITIES - 1); >> + u32 comp_ctrl = FIELD_PREP(VE_COMP_CTRL_DCT_LUM, video->jpeg_quality) | >> + FIELD_PREP(VE_COMP_CTRL_DCT_CHR, video->jpeg_quality | 0x10) | >> + FIELD_PREP(VE_COMP_CTRL_EN_HQ, video->hq_mode) | >> + FIELD_PREP(VE_COMP_CTRL_HQ_DCT_LUM, jpeg_hq_quality) | >> + FIELD_PREP(VE_COMP_CTRL_HQ_DCT_CHR, jpeg_hq_quality | 0x10); >> + u32 ctrl = 0; >> + u32 seq_ctrl = 0; >> + >> + v4l2_dbg(1, debug, &video->v4l2_dev, "framerate(%d)\n", >> + video->frame_rate); >> + v4l2_dbg(1, debug, &video->v4l2_dev, "jpeg format(%s) subsample(%s)\n", >> + format_str[video->format], >> + video->yuv420 ? "420" : "444"); >> + v4l2_dbg(1, debug, &video->v4l2_dev, "compression quality(%d)\n", >> + video->jpeg_quality); >> + v4l2_dbg(1, debug, &video->v4l2_dev, "hq_mode(%s) hq_quality(%d)\n", >> + video->hq_mode ? "on" : "off", video->jpeg_hq_quality); >> + >> + if (video->format == VIDEO_FMT_ASPEED) >> + aspeed_video_update(video, VE_BCD_CTRL, 0, VE_BCD_CTRL_EN_BCD); >> + else >> + aspeed_video_update(video, VE_BCD_CTRL, VE_BCD_CTRL_EN_BCD, 0); >> >> if (video->frame_rate) >> ctrl |= FIELD_PREP(VE_CTRL_FRC, video->frame_rate); >> >> + if (video->format == VIDEO_FMT_STANDARD) { >> + comp_ctrl &= ~FIELD_PREP(VE_COMP_CTRL_EN_HQ, video->hq_mode); >> + seq_ctrl |= video->jpeg_mode; >> + } >> + >> if (video->yuv420) >> seq_ctrl |= VE_SEQ_CTRL_YUV420; >> >> + if (video->jpeg.virt) >> + aspeed_video_update_jpeg_table(video->jpeg.virt, video->yuv420); >> + >> + >> + /* Set control registers */ >> + aspeed_video_update(video, VE_SEQ_CTRL, >> + video->jpeg_mode | VE_SEQ_CTRL_YUV420, >> + seq_ctrl); >> + aspeed_video_update(video, VE_CTRL, VE_CTRL_FRC, ctrl); >> + aspeed_video_update(video, VE_COMP_CTRL, >> + VE_COMP_CTRL_DCT_LUM | VE_COMP_CTRL_DCT_CHR | >> + VE_COMP_CTRL_EN_HQ | VE_COMP_CTRL_HQ_DCT_LUM | >> + VE_COMP_CTRL_HQ_DCT_CHR | VE_COMP_CTRL_VQ_4COLOR | >> + VE_COMP_CTRL_VQ_DCT_ONLY, >> + comp_ctrl); >> +} >> + >> +static void aspeed_video_init_regs(struct aspeed_video *video) >> +{ >> + u32 ctrl = VE_CTRL_AUTO_OR_CURSOR | >> + FIELD_PREP(VE_CTRL_CAPTURE_FMT, VIDEO_CAP_FMT_YUV_FULL_SWING); >> + >> /* Unlock VE registers */ >> aspeed_video_write(video, VE_PROTECTION_KEY, VE_PROTECTION_KEY_UNLOCK); >> >> @@ -1150,9 +1284,8 @@ static void aspeed_video_init_regs(struct aspeed_video *video) >> aspeed_video_write(video, VE_JPEG_ADDR, video->jpeg.dma); >> >> /* Set control registers */ >> - aspeed_video_write(video, VE_SEQ_CTRL, seq_ctrl); >> aspeed_video_write(video, VE_CTRL, ctrl); >> - aspeed_video_write(video, VE_COMP_CTRL, comp_ctrl); >> + aspeed_video_write(video, VE_COMP_CTRL, VE_COMP_CTRL_RSVD); >> >> /* Don't downscale */ >> aspeed_video_write(video, VE_SCALING_FACTOR, 0x10001000); >> @@ -1168,6 +1301,8 @@ static void aspeed_video_init_regs(struct aspeed_video *video) >> FIELD_PREP(VE_MODE_DT_HOR_STABLE, 6) | >> FIELD_PREP(VE_MODE_DT_VER_STABLE, 6) | >> FIELD_PREP(VE_MODE_DT_EDG_THROD, 0x65)); >> + >> + aspeed_video_write(video, VE_BCD_CTRL, 0); >> } >> >> static void aspeed_video_start(struct aspeed_video *video) >> @@ -1201,6 +1336,9 @@ static void aspeed_video_stop(struct aspeed_video *video) >> if (video->srcs[1].size) >> aspeed_video_free_buf(video, &video->srcs[1]); >> >> + if (video->bcd.size) >> + aspeed_video_free_buf(video, &video->bcd); >> + >> video->v4l2_input_status = V4L2_IN_ST_NO_SIGNAL; >> video->flags = 0; >> } >> @@ -1219,10 +1357,12 @@ static int aspeed_video_querycap(struct file *file, void *fh, >> static int aspeed_video_enum_format(struct file *file, void *fh, >> struct v4l2_fmtdesc *f) >> { >> + struct aspeed_video *video = video_drvdata(file); >> + >> if (f->index) >> return -EINVAL; >> >> - f->pixelformat = V4L2_PIX_FMT_JPEG; >> + f->pixelformat = video->pix_fmt.pixelformat; >> >> return 0; >> } >> @@ -1237,6 +1377,29 @@ static int aspeed_video_get_format(struct file *file, void *fh, >> return 0; >> } >> >> +static int aspeed_video_set_format(struct file *file, void *fh, >> + struct v4l2_format *f) >> +{ >> + struct aspeed_video *video = video_drvdata(file); >> + >> + if (vb2_is_busy(&video->queue)) >> + return -EBUSY; >> + >> + switch (f->fmt.pix.pixelformat) { >> + case V4L2_PIX_FMT_JPEG: >> + video->format = VIDEO_FMT_STANDARD; >> + break; >> + case V4L2_PIX_FMT_AJPG: >> + video->format = VIDEO_FMT_ASPEED; >> + break; >> + default: >> + return -EINVAL; >> + } >> + video->pix_fmt.pixelformat = f->fmt.pix.pixelformat; >> + >> + return 0; >> +} >> + >> static int aspeed_video_enum_input(struct file *file, void *fh, >> struct v4l2_input *inp) >> { >> @@ -1454,7 +1617,7 @@ static const struct v4l2_ioctl_ops aspeed_video_ioctl_ops = { >> >> .vidioc_enum_fmt_vid_cap = aspeed_video_enum_format, >> .vidioc_g_fmt_vid_cap = aspeed_video_get_format, >> - .vidioc_s_fmt_vid_cap = aspeed_video_get_format, >> + .vidioc_s_fmt_vid_cap = aspeed_video_set_format, >> .vidioc_try_fmt_vid_cap = aspeed_video_get_format, >> >> .vidioc_reqbufs = vb2_ioctl_reqbufs, >> @@ -1486,27 +1649,6 @@ static const struct v4l2_ioctl_ops aspeed_video_ioctl_ops = { >> .vidioc_unsubscribe_event = v4l2_event_unsubscribe, >> }; >> >> -static void aspeed_video_update_jpeg_quality(struct aspeed_video *video) >> -{ >> - u32 comp_ctrl = FIELD_PREP(VE_COMP_CTRL_DCT_LUM, video->jpeg_quality) | >> - FIELD_PREP(VE_COMP_CTRL_DCT_CHR, video->jpeg_quality | 0x10); >> - >> - aspeed_video_update(video, VE_COMP_CTRL, >> - VE_COMP_CTRL_DCT_LUM | VE_COMP_CTRL_DCT_CHR, >> - comp_ctrl); >> -} >> - >> -static void aspeed_video_update_subsampling(struct aspeed_video *video) >> -{ >> - if (video->jpeg.virt) >> - aspeed_video_update_jpeg_table(video->jpeg.virt, video->yuv420); >> - >> - if (video->yuv420) >> - aspeed_video_update(video, VE_SEQ_CTRL, 0, VE_SEQ_CTRL_YUV420); >> - else >> - aspeed_video_update(video, VE_SEQ_CTRL, VE_SEQ_CTRL_YUV420, 0); >> -} >> - >> static int aspeed_video_set_ctrl(struct v4l2_ctrl *ctrl) >> { >> struct aspeed_video *video = container_of(ctrl->handler, >> @@ -1516,16 +1658,23 @@ static int aspeed_video_set_ctrl(struct v4l2_ctrl *ctrl) >> switch (ctrl->id) { >> case V4L2_CID_JPEG_COMPRESSION_QUALITY: >> video->jpeg_quality = ctrl->val; >> - aspeed_video_update_jpeg_quality(video); >> + if (test_bit(VIDEO_STREAMING, &video->flags)) >> + aspeed_video_update_regs(video); >> break; >> case V4L2_CID_JPEG_CHROMA_SUBSAMPLING: >> - if (ctrl->val == V4L2_JPEG_CHROMA_SUBSAMPLING_420) { >> - video->yuv420 = true; >> - aspeed_video_update_subsampling(video); >> - } else { >> - video->yuv420 = false; >> - aspeed_video_update_subsampling(video); >> - } >> + video->yuv420 = (ctrl->val == V4L2_JPEG_CHROMA_SUBSAMPLING_420); >> + if (test_bit(VIDEO_STREAMING, &video->flags)) >> + aspeed_video_update_regs(video); >> + break; >> + case V4L2_CID_ASPEED_HQ_MODE: >> + video->hq_mode = ctrl->val; >> + if (test_bit(VIDEO_STREAMING, &video->flags)) >> + aspeed_video_update_regs(video); >> + break; >> + case V4L2_CID_ASPEED_HQ_JPEG_QUALITY: >> + video->jpeg_hq_quality = ctrl->val; >> + if (test_bit(VIDEO_STREAMING, &video->flags)) >> + aspeed_video_update_regs(video); >> break; >> default: >> return -EINVAL; >> @@ -1538,6 +1687,28 @@ static const struct v4l2_ctrl_ops aspeed_video_ctrl_ops = { >> .s_ctrl = aspeed_video_set_ctrl, >> }; >> >> +static const struct v4l2_ctrl_config aspeed_ctrl_HQ_mode = { >> + .ops = &aspeed_video_ctrl_ops, >> + .id = V4L2_CID_ASPEED_HQ_MODE, >> + .name = "Aspeed HQ Mode", >> + .type = V4L2_CTRL_TYPE_BOOLEAN, >> + .min = false, >> + .max = true, >> + .step = 1, >> + .def = false, >> +}; >> + >> +static const struct v4l2_ctrl_config aspeed_ctrl_HQ_jpeg_quality = { >> + .ops = &aspeed_video_ctrl_ops, >> + .id = V4L2_CID_ASPEED_HQ_JPEG_QUALITY, >> + .name = "Aspeed HQ Quality", >> + .type = V4L2_CTRL_TYPE_INTEGER, >> + .min = 1, >> + .max = ASPEED_VIDEO_JPEG_NUM_QUALITIES, >> + .step = 1, >> + .def = 1, >> +}; >> + >> static void aspeed_video_resolution_work(struct work_struct *work) >> { >> struct delayed_work *dwork = to_delayed_work(work); >> @@ -1552,6 +1723,8 @@ static void aspeed_video_resolution_work(struct work_struct *work) >> >> aspeed_video_init_regs(video); >> >> + aspeed_video_update_regs(video); >> + >> aspeed_video_get_resolution(video); >> >> if (video->detected_timings.width != video->active_timings.width || >> @@ -1662,6 +1835,8 @@ static int aspeed_video_start_streaming(struct vb2_queue *q, >> video->perf.duration_max = 0; >> video->perf.duration_min = 0xffffffff; >> >> + aspeed_video_update_regs(video); >> + >> rc = aspeed_video_start_frame(video); >> if (rc) { >> aspeed_video_bufs_done(video, VB2_BUF_STATE_QUEUED); >> @@ -1800,6 +1975,7 @@ static int aspeed_video_setup_video(struct aspeed_video *video) >> struct v4l2_device *v4l2_dev = &video->v4l2_dev; >> struct vb2_queue *vbq = &video->queue; >> struct video_device *vdev = &video->vdev; >> + struct v4l2_ctrl_handler *hdl = &video->ctrl_handler; >> int rc; >> >> video->pix_fmt.pixelformat = V4L2_PIX_FMT_JPEG; >> @@ -1814,16 +1990,18 @@ static int aspeed_video_setup_video(struct aspeed_video *video) >> return rc; >> } >> >> - v4l2_ctrl_handler_init(&video->ctrl_handler, 2); >> - v4l2_ctrl_new_std(&video->ctrl_handler, &aspeed_video_ctrl_ops, >> + v4l2_ctrl_handler_init(hdl, 4); >> + v4l2_ctrl_new_std(hdl, &aspeed_video_ctrl_ops, >> V4L2_CID_JPEG_COMPRESSION_QUALITY, 0, >> ASPEED_VIDEO_JPEG_NUM_QUALITIES - 1, 1, 0); >> - v4l2_ctrl_new_std_menu(&video->ctrl_handler, &aspeed_video_ctrl_ops, >> + v4l2_ctrl_new_std_menu(hdl, &aspeed_video_ctrl_ops, >> V4L2_CID_JPEG_CHROMA_SUBSAMPLING, >> V4L2_JPEG_CHROMA_SUBSAMPLING_420, mask, >> V4L2_JPEG_CHROMA_SUBSAMPLING_444); >> + v4l2_ctrl_new_custom(hdl, &aspeed_ctrl_HQ_mode, NULL); >> + v4l2_ctrl_new_custom(hdl, &aspeed_ctrl_HQ_jpeg_quality, NULL); >> >> - rc = video->ctrl_handler.error; >> + rc = hdl->error; >> if (rc) { >> v4l2_ctrl_handler_free(&video->ctrl_handler); >> v4l2_device_unregister(v4l2_dev); >> @@ -1832,7 +2010,7 @@ static int aspeed_video_setup_video(struct aspeed_video *video) >> return rc; >> } >> >> - v4l2_dev->ctrl_handler = &video->ctrl_handler; >> + v4l2_dev->ctrl_handler = hdl; >> >> vbq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; >> vbq->io_modes = VB2_MMAP | VB2_READ | VB2_DMABUF; >> @@ -1980,6 +2158,7 @@ static int aspeed_video_probe(struct platform_device *pdev) >> video->comp_size_read = config->comp_size_read; >> >> video->frame_rate = 30; >> + video->jpeg_hq_quality = 1; >> video->dev = &pdev->dev; >> spin_lock_init(&video->lock); >> mutex_init(&video->video_lock); >> diff --git a/include/uapi/linux/aspeed-video.h b/include/uapi/linux/aspeed-video.h >> new file mode 100644 >> index 000000000000..63f0432192a5 >> --- /dev/null >> +++ b/include/uapi/linux/aspeed-video.h >> @@ -0,0 +1,15 @@ >> +/* SPDX-License-Identifier: GPL-2.0-or-later */ >> +/* >> + * Copyright (C) 2021 ASPEED Technology Inc. >> + */ >> + >> +#ifndef _UAPI_LINUX_ASPEED_VIDEO_H >> +#define _UAPI_LINUX_ASPEED_VIDEO_H >> + >> +#include >> + >> +#define V4L2_CID_ASPEED_COMPRESSION_SCHEME (V4L2_CID_USER_ASPEED_BASE + 1) >> +#define V4L2_CID_ASPEED_HQ_MODE (V4L2_CID_USER_ASPEED_BASE + 2) >> +#define V4L2_CID_ASPEED_HQ_JPEG_QUALITY (V4L2_CID_USER_ASPEED_BASE + 3) > I believe you are missing documentation for these. Even vendor CID get to be > documented in the RST doc, it also helps us reviewer to judge if these are > trully vendor controls or should be generalized, its not currently possible to > make an opinion. OK, I will add aspeed.rst to disclose related information. >> + >> +#endif /* _UAPI_LINUX_ASPEED_VIDEO_H */ -- Best Regards Jammy From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id B98E6C433FE for ; Thu, 20 Oct 2022 08:04:51 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender:Content-Type: Content-Transfer-Encoding:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:In-Reply-To:From:References:To:Subject:MIME-Version: Date:Message-ID:Reply-To:Cc:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=SloE4Fi37BS4FQu3yA9WVMEgR+ETjR10hudAYxIpeLI=; b=pE1mPG49Frd8qp35C2AcS25q9h xoNUHT9qpLUVcJ3OL1Ws3aaNXqv91jpmB/mQkHEruLjub1c4IpfVUwPxGVzdt/zBuFVdSmeuJ1eOr bZF78VCyU0qshNK1UPvH6p9Ay4NfcKb/reiaPpJqwvX0FuJXbT2QrKW3EWDT1jKHXo7Wt2DVC7xcX f1c4XnhaCy4Wc2ZwaF6hsqjS9uxxXIGrHh8yb5cDt0meu6CvzluiHgwYydGmiBtmAC+xtg86UXb3r 7ND/WbO3g1clrM2rv+fuVJQuietjx8UsD34o0lN6bw1DtGF4+lM5JoJs8XLA3XyCZ12HQaYZcMS6G 7cfWeaLw==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1olQWX-00C35E-Am; Thu, 20 Oct 2022 08:03:29 +0000 Received: from desiato.infradead.org ([2001:8b0:10b:1:d65d:64ff:fe57:4e05]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1olQWV-00C33s-4n for linux-arm-kernel@bombadil.infradead.org; Thu, 20 Oct 2022 08:03:27 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=desiato.20200630; h=Content-Transfer-Encoding:Content-Type :In-Reply-To:From:References:To:Subject:MIME-Version:Date:Message-ID:Sender: Reply-To:Cc:Content-ID:Content-Description; bh=Sn9bVd7vIlqBBMmmwfIuez6NONdptJ05GaAb8IGxclU=; b=l3vCjJcrNJVPjtdTHzSv18XJUV RHCe262Wy16h6uvTUz9gGYDYBl22VlNx6PGE+iTUqjUJBCcNrf/q/lFkPHsIT0Q8c4lLSp5qPR9zr wg2aGRL77HakE2BGaXwo6JPl9BjW+peOstTAhMAUAQjCeSeJ3kzvPXyJDXrLeddfVyp2Mw37Ct5Sw wxFLjh9actm/3lj6wPt5axRwJaGLPODlWFegNbsamsxm4tlRne83gyLQiAj7Xj0kG3ZXK+e8OTCOr 9e3Z51hu9MJD4QfOF3j3El/Ji2VahAGt/lO0kfL8obclqwrgsXdc+oPCzlyvibPUBIjP0ONrp004F UGiG+GSQ==; Received: from twspam01.aspeedtech.com ([211.20.114.71]) by desiato.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1olPwm-004ysr-9d for linux-arm-kernel@lists.infradead.org; Thu, 20 Oct 2022 07:26:37 +0000 Received: from mail.aspeedtech.com ([192.168.0.24]) by twspam01.aspeedtech.com with ESMTP id 29K72xkV072568; Thu, 20 Oct 2022 15:02:59 +0800 (GMT-8) (envelope-from jammy_huang@aspeedtech.com) Received: from [192.168.2.115] (192.168.2.115) by TWMBX02.aspeed.com (192.168.0.24) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Thu, 20 Oct 2022 15:25:26 +0800 Message-ID: <14a96f82-0f36-e981-b6e1-31d662eded33@aspeedtech.com> Date: Thu, 20 Oct 2022 15:25:26 +0800 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:91.0) Gecko/20100101 Thunderbird/91.13.1 Subject: Re: [PATCH v9 3/4] media: aspeed: Support aspeed mode to reduce compressed data Content-Language: en-US To: Nicolas Dufresne , , , , , , , , , , , , , , , References: <20220921025112.13150-1-jammy_huang@aspeedtech.com> <20220921025112.13150-4-jammy_huang@aspeedtech.com> From: Jammy Huang In-Reply-To: X-Originating-IP: [192.168.2.115] X-ClientProxiedBy: TWMBX02.aspeed.com (192.168.0.24) To TWMBX02.aspeed.com (192.168.0.24) X-DNSRBL: X-MAIL: twspam01.aspeedtech.com 29K72xkV072568 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20221020_082634_743967_BDE8C5FF X-CRM114-Status: GOOD ( 23.82 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Transfer-Encoding: base64 Content-Type: text/plain; charset="utf-8"; Format="flowed" Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org SGkgTm9jb2xhcywKCgpPbiAyMDIyLzEwLzE4IOS4i+WNiCAxMToyMCwgTmljb2xhcyBEdWZyZXNu ZSB3cm90ZToKPiBIaSwKPgo+IExlIG1lcmNyZWRpIDIxIHNlcHRlbWJyZSAyMDIyIMOgIDEwOjUx ICswODAwLCBKYW1teSBIdWFuZyBhIMOpY3JpdMKgOgo+PiBhc3BlZWQgc3VwcG9ydHMgZGlmZmVy ZW50aWFsIGpwZWcgZm9ybWF0IHdoaWNoIG9ubHkgY29tcHJlc3MgdGhlIHBhcnRzCj4+IHdoaWNo IGFyZSBjaGFuZ2VkLiBJbiB0aGlzIHdheSwgaXQgcmVkdWNlcyBib3RoIHRoZSBhbW91bnQgb2Yg ZGF0YSB0byBiZQo+PiB0cmFuc2ZlcnJlZCBieSBuZXR3b3JrIGFuZCB0aG9zZSB0byBiZSBkZWNv ZGVkIG9uIHRoZSBjbGllbnQgc2lkZS4KPj4KPj4gMiBuZXcgY3RybHMgYXJlIGFkZGVkOgo+PiAq IEFzcGVlZCBIUSBNb2RlOiB0byBjb250cm9sIGFzcGVlZCdzIGhpZ2ggcXVhbGl0eSgyLXBhc3Mp IGNvbXByZXNzaW9uIG1vZGUKPj4gICAgVGhpcyBvbmx5IHdvcmtzIHdpdGggeXV2NDQ0IHN1YnNh bXBsaW5nLgo+PiAqIEFzcGVlZCBIUSBRdWFsaXR5OiB0byBjb250cm9sIHRoZSBxdWFsaXR5IG9m IGFzcGVlZCdzIEhRIG1vZGUKPj4gICAgb25seSB1c2VmdWwgaWYgQXNwZWVkIEhRIG1vZGUgaXMg ZW5hYmxlZAo+Pgo+PiBBc3BlZWQgSlBFRyBGb3JtYXQgcmVxdWlyZXMgYW4gYWRkaXRpb25hbCBi dWZmZXIsIGNhbGxlZCBiY2QsIHRvIHN0b3JlCj4+IHRoZSBpbmZvcm1hdGlvbiBhYm91dCB3aGlj aCBtYWNybyBibG9jayBpbiB0aGUgbmV3IGZyYW1lIGlzIGRpZmZlcmVudAo+PiBmcm9tIHRoZSBw cmV2aW91cyBvbmUuCj4+Cj4+IFRvIGhhdmUgYmNkIGNvcnJlY3RseSB3b3JraW5nLCB3ZSBuZWVk IHRvIHN3YXAgdGhlIGJ1ZmZlcnMgZm9yIHNyYzAvMSB0bwo+PiBtYWtlIHNyYzEgcmVmZXIgdG8g cHJldmlvdXMgZnJhbWUgYW5kIHNyYzAgdG8gdGhlIGNvbWluZyBuZXcgZnJhbWUuCj4+Cj4+IFNp Z25lZC1vZmYtYnk6IEphbW15IEh1YW5nIDxqYW1teV9odWFuZ0Bhc3BlZWR0ZWNoLmNvbT4KPj4g LS0tCj4+ICAgZHJpdmVycy9tZWRpYS9wbGF0Zm9ybS9hc3BlZWQvYXNwZWVkLXZpZGVvLmMgfCAy ODEgKysrKysrKysrKysrKysrLS0tLQo+PiAgIGluY2x1ZGUvdWFwaS9saW51eC9hc3BlZWQtdmlk ZW8uaCAgICAgICAgICAgIHwgIDE1ICsKPj4gICAyIGZpbGVzIGNoYW5nZWQsIDI0NSBpbnNlcnRp b25zKCspLCA1MSBkZWxldGlvbnMoLSkKPj4gICBjcmVhdGUgbW9kZSAxMDA2NDQgaW5jbHVkZS91 YXBpL2xpbnV4L2FzcGVlZC12aWRlby5oCj4+Cj4+IGRpZmYgLS1naXQgYS9kcml2ZXJzL21lZGlh L3BsYXRmb3JtL2FzcGVlZC9hc3BlZWQtdmlkZW8uYyBiL2RyaXZlcnMvbWVkaWEvcGxhdGZvcm0v YXNwZWVkL2FzcGVlZC12aWRlby5jCj4+IGluZGV4IDIwZjc5NWNjYzExYi4uNzM5Mjg4MDI2NDE4 IDEwMDY0NAo+PiAtLS0gYS9kcml2ZXJzL21lZGlhL3BsYXRmb3JtL2FzcGVlZC9hc3BlZWQtdmlk ZW8uYwo+PiArKysgYi9kcml2ZXJzL21lZGlhL3BsYXRmb3JtL2FzcGVlZC9hc3BlZWQtdmlkZW8u Ywo+PiBAQCAtMzMsNiArMzMsNyBAQAo+PiAgICNpbmNsdWRlIDxtZWRpYS92NGwyLWV2ZW50Lmg+ Cj4+ICAgI2luY2x1ZGUgPG1lZGlhL3Y0bDItaW9jdGwuaD4KPj4gICAjaW5jbHVkZSA8bWVkaWEv dmlkZW9idWYyLWRtYS1jb250aWcuaD4KPj4gKyNpbmNsdWRlIDx1YXBpL2xpbnV4L2FzcGVlZC12 aWRlby5oPgo+PiAgIAo+PiAgICNkZWZpbmUgQVNQRUVEX1ZJREVPX1Y0TDJfTUlOX0JVRl9SRVEg Mwo+PiAgIAo+PiBAQCAtNTksNiArNjAsNyBAQAo+PiAgIAo+PiAgICNkZWZpbmUgVkVfTUFYX1NS Q19CVUZGRVJfU0laRQkJMHg4Y2EwMDAgLyogMTkyMCAqIDEyMDAsIDMyYnBwICovCj4+ICAgI2Rl ZmluZSBWRV9KUEVHX0hFQURFUl9TSVpFCQkweDAwNjAwMCAvKiA1MTIgKiAxMiAqIDQgKi8KPj4g KyNkZWZpbmUgVkVfQkNEX0JVRkZfU0laRQkJMHg5MDAwIC8qICgxOTIwLzgpICogKDEyMDAvOCkg Ki8KPj4gICAKPj4gICAjZGVmaW5lIFZFX1BST1RFQ1RJT05fS0VZCQkweDAwMAo+PiAgICNkZWZp bmUgIFZFX1BST1RFQ1RJT05fS0VZX1VOTE9DSwkweDFhMDM4YWE4Cj4+IEBAIC0xMDcsNiArMTA5 LDEzIEBACj4+ICAgI2RlZmluZSBWRV9TQ0FMSU5HX0ZJTFRFUjIJCTB4MDIwCj4+ICAgI2RlZmlu ZSBWRV9TQ0FMSU5HX0ZJTFRFUjMJCTB4MDI0Cj4+ICAgCj4+ICsjZGVmaW5lIFZFX0JDRF9DVFJM CQkJMHgwMkMKPj4gKyNkZWZpbmUgIFZFX0JDRF9DVFJMX0VOX0JDRAkJQklUKDApCj4+ICsjZGVm aW5lICBWRV9CQ0RfQ1RSTF9FTl9BQkNECQlCSVQoMSkKPj4gKyNkZWZpbmUgIFZFX0JDRF9DVFJM X0VOX0NCCQlCSVQoMikKPj4gKyNkZWZpbmUgIFZFX0JDRF9DVFJMX1RIUgkJR0VOTUFTSygyMywg MTYpCj4+ICsjZGVmaW5lICBWRV9CQ0RfQ1RSTF9BQkNEX1RIUgkJR0VOTUFTSygzMSwgMjQpCj4+ ICsKPj4gICAjZGVmaW5lIFZFX0NBUF9XSU5ET1cJCQkweDAzMAo+PiAgICNkZWZpbmUgVkVfQ09N UF9XSU5ET1cJCQkweDAzNAo+PiAgICNkZWZpbmUgVkVfQ09NUF9QUk9DX09GRlNFVAkJMHgwMzgK Pj4gQEAgLTExNSw2ICsxMjQsNyBAQAo+PiAgICNkZWZpbmUgVkVfU1JDMF9BRERSCQkJMHgwNDQK Pj4gICAjZGVmaW5lIFZFX1NSQ19TQ0FOTElORV9PRkZTRVQJCTB4MDQ4Cj4+ICAgI2RlZmluZSBW RV9TUkMxX0FERFIJCQkweDA0Ywo+PiArI2RlZmluZSBWRV9CQ0RfQUREUgkJCTB4MDUwCj4+ICAg I2RlZmluZSBWRV9DT01QX0FERFIJCQkweDA1NAo+PiAgIAo+PiAgICNkZWZpbmUgVkVfU1RSRUFN X0JVRl9TSVpFCQkweDA1OAo+PiBAQCAtMTM1LDYgKzE0NSw4IEBACj4+ICAgI2RlZmluZSAgVkVf Q09NUF9DVFJMX0hRX0RDVF9DSFIJR0VOTUFTSygyNiwgMjIpCj4+ICAgI2RlZmluZSAgVkVfQ09N UF9DVFJMX0hRX0RDVF9MVU0JR0VOTUFTSygzMSwgMjcpCj4+ICAgCj4+ICsjZGVmaW5lIFZFX0NC X0FERFIJCQkweDA2Qwo+PiArCj4+ICAgI2RlZmluZSBBU1QyNDAwX1ZFX0NPTVBfU0laRV9SRUFE X0JBQ0sJMHgwNzgKPj4gICAjZGVmaW5lIEFTVDI2MDBfVkVfQ09NUF9TSVpFX1JFQURfQkFDSwkw eDA4NAo+PiAgIAo+PiBAQCAtMjExLDYgKzIyMywxMiBAQCBlbnVtIHsKPj4gICAJVklERU9fQ0xP Q0tTX09OLAo+PiAgIH07Cj4+ICAgCj4+ICtlbnVtIGFzcGVlZF92aWRlb19mb3JtYXQgewo+PiAr CVZJREVPX0ZNVF9TVEFOREFSRCA9IDAsCj4+ICsJVklERU9fRk1UX0FTUEVFRCwKPj4gKwlWSURF T19GTVRfTUFYID0gVklERU9fRk1UX0FTUEVFRAo+PiArfTsKPj4gKwo+PiAgIC8vIGZvciBWRV9D VFJMX0NBUFRVUkVfRk1UCj4+ICAgZW51bSBhc3BlZWRfdmlkZW9fY2FwdHVyZV9mb3JtYXQgewo+ PiAgIAlWSURFT19DQVBfRk1UX1lVVl9TVFVESU9fU1dJTkcgPSAwLAo+PiBAQCAtMjQ1LDE2ICsy NjMsMjAgQEAgc3RydWN0IGFzcGVlZF92aWRlb19wZXJmIHsKPj4gICAvKgo+PiAgICAqIHN0cnVj dCBhc3BlZWRfdmlkZW8gLSBkcml2ZXIgZGF0YQo+PiAgICAqCj4+IC0gKiByZXNfd29yazogICAg ICAgICAgIGhvbGRzIHRoZSBkZWxheWVkX3dvcmsgZm9yIHJlcy1kZXRlY3Rpb24gaWYgdW5sb2Nr Cj4+IC0gKiBidWZmZXJzOiAgICAgICAgICAgIGhvbGRzIHRoZSBsaXN0IG9mIGJ1ZmZlciBxdWV1 ZWQgZnJvbSB1c2VyCj4+ICsgKiByZXNfd29yazoJCWhvbGRzIHRoZSBkZWxheWVkX3dvcmsgZm9y IHJlcy1kZXRlY3Rpb24gaWYgdW5sb2NrCj4+ICsgKiBidWZmZXJzOgkJaG9sZHMgdGhlIGxpc3Qg b2YgYnVmZmVyIHF1ZXVlZCBmcm9tIHVzZXIKPj4gICAgKiBmbGFnczoJCWhvbGRzIHRoZSBzdGF0 ZSBvZiB2aWRlbwo+PiAgICAqIHNlcXVlbmNlOgkJaG9sZHMgdGhlIGxhc3QgbnVtYmVyIG9mIGZy YW1lIGNvbXBsZXRlZAo+PiAgICAqIG1heF9jb21wcmVzc2VkX3NpemU6CWhvbGRzIG1heCBjb21w cmVzc2VkIHN0cmVhbSdzIHNpemUKPj4gICAgKiBzcmNzOgkJaG9sZHMgdGhlIGJ1ZmZlciBpbmZv cm1hdGlvbiBmb3Igc3Jjcwo+PiAgICAqIGpwZWc6CQlob2xkcyB0aGUgYnVmZmVyIGluZm9ybWF0 aW9uIGZvciBqcGVnIGhlYWRlcgo+PiArICogYmNkOgkJCWhvbGRzIHRoZSBidWZmZXIgaW5mb3Jt YXRpb24gZm9yIGJjZCB3b3JrCj4+ICAgICogeXV2NDIwOgkJYSBmbGFnIHJhaXNlZCBpZiBKUEVH IHN1YnNhbXBsaW5nIGlzIDQyMAo+PiArICogZm9ybWF0OgkJaG9sZHMgdGhlIHZpZGVvIGZvcm1h dAo+PiArICogaHFfbW9kZToJCWEgZmxhZyByYWlzZWQgaWYgSFEgaXMgZW5hYmxlZC4gT25seSBm b3IgVklERU9fRk1UX0FTUEVFRAo+PiAgICAqIGZyYW1lX3JhdGU6CQlob2xkcyB0aGUgZnJhbWVf cmF0ZQo+PiAgICAqIGpwZWdfcXVhbGl0eToJaG9sZHMganBlcSdzIHF1YWxpdHkgKDB+MTEpCj4+ ICsgKiBqcGVnX2hxX3F1YWxpdHk6CWhvbGRzIGhxJ3MgcXVhbGl0eSAoMX4xMikgb25seSBpZiBo cV9tb2RlIGVuYWJsZWQKPj4gICAgKiBmcmFtZV9ib3R0b206CWVuZCBwb3NpdGlvbiBvZiB2aWRl byBkYXRhIGluIHZlcnRpY2FsIGRpcmVjdGlvbgo+PiAgICAqIGZyYW1lX2xlZnQ6CQlzdGFydCBw b3NpdGlvbiBvZiB2aWRlbyBkYXRhIGluIGhvcml6b250YWwgZGlyZWN0aW9uCj4+ICAgICogZnJh bWVfcmlnaHQ6CQllbmQgcG9zaXRpb24gb2YgdmlkZW8gZGF0YSBpbiBob3Jpem9udGFsIGRpcmVj dGlvbgo+PiBAQCAtMjkwLDEwICszMTIsMTQgQEAgc3RydWN0IGFzcGVlZF92aWRlbyB7Cj4+ICAg CXVuc2lnbmVkIGludCBtYXhfY29tcHJlc3NlZF9zaXplOwo+PiAgIAlzdHJ1Y3QgYXNwZWVkX3Zp ZGVvX2FkZHIgc3Jjc1syXTsKPj4gICAJc3RydWN0IGFzcGVlZF92aWRlb19hZGRyIGpwZWc7Cj4+ ICsJc3RydWN0IGFzcGVlZF92aWRlb19hZGRyIGJjZDsKPj4gICAKPj4gICAJYm9vbCB5dXY0MjA7 Cj4+ICsJZW51bSBhc3BlZWRfdmlkZW9fZm9ybWF0IGZvcm1hdDsKPj4gKwlib29sIGhxX21vZGU7 Cj4+ICAgCXVuc2lnbmVkIGludCBmcmFtZV9yYXRlOwo+PiAgIAl1bnNpZ25lZCBpbnQganBlZ19x dWFsaXR5Owo+PiArCXVuc2lnbmVkIGludCBqcGVnX2hxX3F1YWxpdHk7Cj4+ICAgCj4+ICAgCXVu c2lnbmVkIGludCBmcmFtZV9ib3R0b207Cj4+ICAgCXVuc2lnbmVkIGludCBmcmFtZV9sZWZ0Owo+ PiBAQCAtNDU4LDggKzQ4NCwyMCBAQCBzdGF0aWMgY29uc3Qgc3RydWN0IHY0bDJfZHZfdGltaW5n c19jYXAgYXNwZWVkX3ZpZGVvX3RpbWluZ3NfY2FwID0gewo+PiAgIAl9LAo+PiAgIH07Cj4+ICAg Cj4+ICtzdGF0aWMgY29uc3QgY2hhciAqIGNvbnN0IGNvbXByZXNzX3NjaGVtZV9zdHJbXSA9IHsi RENUIE9ubHkiLAo+PiArCSJEQ1QgVlEgbWl4IDItY29sb3IiLCAiRENUIFZRIG1peCA0LWNvbG9y In07Cj4+ICtzdGF0aWMgY29uc3QgY2hhciAqIGNvbnN0IGZvcm1hdF9zdHJbXSA9IHsiU3RhbmRh cmQgSlBFRyIsCj4+ICsJIkFzcGVlZCBKUEVHIn07Cj4+ICsKPj4gICBzdGF0aWMgdW5zaWduZWQg aW50IGRlYnVnOwo+PiAgIAo+PiArc3RhdGljIGJvb2wgYXNwZWVkX3ZpZGVvX2FsbG9jX2J1Zihz dHJ1Y3QgYXNwZWVkX3ZpZGVvICp2aWRlbywKPj4gKwkJCQkgICBzdHJ1Y3QgYXNwZWVkX3ZpZGVv X2FkZHIgKmFkZHIsCj4+ICsJCQkJICAgdW5zaWduZWQgaW50IHNpemUpOwo+PiArCj4+ICtzdGF0 aWMgdm9pZCBhc3BlZWRfdmlkZW9fZnJlZV9idWYoc3RydWN0IGFzcGVlZF92aWRlbyAqdmlkZW8s Cj4+ICsJCQkJICBzdHJ1Y3QgYXNwZWVkX3ZpZGVvX2FkZHIgKmFkZHIpOwo+PiArCj4+ICAgc3Rh dGljIHZvaWQgYXNwZWVkX3ZpZGVvX2luaXRfanBlZ190YWJsZSh1MzIgKnRhYmxlLCBib29sIHl1 djQyMCkKPj4gICB7Cj4+ICAgCWludCBpOwo+PiBAQCAtNTQ3LDYgKzU4NSw3IEBAIHN0YXRpYyBp bnQgYXNwZWVkX3ZpZGVvX3N0YXJ0X2ZyYW1lKHN0cnVjdCBhc3BlZWRfdmlkZW8gKnZpZGVvKQo+ PiAgIAl1bnNpZ25lZCBsb25nIGZsYWdzOwo+PiAgIAlzdHJ1Y3QgYXNwZWVkX3ZpZGVvX2J1ZmZl ciAqYnVmOwo+PiAgIAl1MzIgc2VxX2N0cmwgPSBhc3BlZWRfdmlkZW9fcmVhZCh2aWRlbywgVkVf U0VRX0NUUkwpOwo+PiArCWJvb2wgYmNkX2J1Zl9uZWVkID0gKHZpZGVvLT5mb3JtYXQgIT0gVklE RU9fRk1UX1NUQU5EQVJEKTsKPj4gICAKPj4gICAJaWYgKHZpZGVvLT52NGwyX2lucHV0X3N0YXR1 cykgewo+PiAgIAkJdjRsMl93YXJuKCZ2aWRlby0+djRsMl9kZXYsICJObyBzaWduYWw7IGRvbid0 IHN0YXJ0IGZyYW1lXG4iKTsKPj4gQEAgLTU1OSw2ICs1OTgsMjAgQEAgc3RhdGljIGludCBhc3Bl ZWRfdmlkZW9fc3RhcnRfZnJhbWUoc3RydWN0IGFzcGVlZF92aWRlbyAqdmlkZW8pCj4+ICAgCQly ZXR1cm4gLUVCVVNZOwo+PiAgIAl9Cj4+ICAgCj4+ICsJaWYgKGJjZF9idWZfbmVlZCAmJiAhdmlk ZW8tPmJjZC5zaXplKSB7Cj4+ICsJCWlmICghYXNwZWVkX3ZpZGVvX2FsbG9jX2J1Zih2aWRlbywg JnZpZGVvLT5iY2QsCj4+ICsJCQkJCSAgICBWRV9CQ0RfQlVGRl9TSVpFKSkgewo+PiArCQkJZGV2 X2Vycih2aWRlby0+ZGV2LCAiRmFpbGVkIHRvIGFsbG9jYXRlIEJDRCBidWZmZXJcbiIpOwo+PiAr CQkJZGV2X2Vycih2aWRlby0+ZGV2LCAiZG9uJ3Qgc3RhcnQgZnJhbWVcbiIpOwo+PiArCQkJcmV0 dXJuIC1FTk9NRU07Cj4+ICsJCX0KPj4gKwkJYXNwZWVkX3ZpZGVvX3dyaXRlKHZpZGVvLCBWRV9C Q0RfQUREUiwgdmlkZW8tPmJjZC5kbWEpOwo+PiArCQl2NGwyX2RiZygxLCBkZWJ1ZywgJnZpZGVv LT52NGwyX2RldiwgImJjZCBhZGRyKCUjeCkgc2l6ZSglZClcbiIsCj4+ICsJCQkgdmlkZW8tPmJj ZC5kbWEsIHZpZGVvLT5iY2Quc2l6ZSk7Cj4+ICsJfSBlbHNlIGlmICghYmNkX2J1Zl9uZWVkICYm IHZpZGVvLT5iY2Quc2l6ZSkgewo+PiArCQlhc3BlZWRfdmlkZW9fZnJlZV9idWYodmlkZW8sICZ2 aWRlby0+YmNkKTsKPj4gKwl9Cj4+ICsKPj4gICAJc3Bpbl9sb2NrX2lycXNhdmUoJnZpZGVvLT5s b2NrLCBmbGFncyk7Cj4+ICAgCWJ1ZiA9IGxpc3RfZmlyc3RfZW50cnlfb3JfbnVsbCgmdmlkZW8t PmJ1ZmZlcnMsCj4+ICAgCQkJCSAgICAgICBzdHJ1Y3QgYXNwZWVkX3ZpZGVvX2J1ZmZlciwgbGlu ayk7Cj4+IEBAIC02NTcsNiArNzEwLDI0IEBAIHN0YXRpYyB2b2lkIGFzcGVlZF92aWRlb19pcnFf cmVzX2NoYW5nZShzdHJ1Y3QgYXNwZWVkX3ZpZGVvICp2aWRlbywgdWxvbmcgZGVsYXkpCj4+ICAg CXNjaGVkdWxlX2RlbGF5ZWRfd29yaygmdmlkZW8tPnJlc193b3JrLCBkZWxheSk7Cj4+ICAgfQo+ PiAgIAo+PiArc3RhdGljIHZvaWQgYXNwZWVkX3ZpZGVvX3N3YXBfc3JjX2J1ZihzdHJ1Y3QgYXNw ZWVkX3ZpZGVvICp2KQo+PiArewo+PiArCWlmICh2LT5mb3JtYXQgPT0gVklERU9fRk1UX1NUQU5E QVJEKQo+PiArCQlyZXR1cm47Cj4+ICsKPj4gKwkvKiBSZXNldCBiY2QgYnVmZmVyIHRvIGhhdmUg YSBmdWxsIGZyYW1lIHVwZGF0ZSBldmVyeSA4IGZyYW1lcy4gICovCj4+ICsJaWYgKElTX0FMSUdO RUQodi0+c2VxdWVuY2UsIDgpKQo+PiArCQltZW1zZXQoKHU4ICopdi0+YmNkLnZpcnQsIDB4MDAs IFZFX0JDRF9CVUZGX1NJWkUpOwo+PiArCj4+ICsJaWYgKHYtPnNlcXVlbmNlICYgMHgwMSkgewo+ PiArCQlhc3BlZWRfdmlkZW9fd3JpdGUodiwgVkVfU1JDMF9BRERSLCB2LT5zcmNzWzFdLmRtYSk7 Cj4+ICsJCWFzcGVlZF92aWRlb193cml0ZSh2LCBWRV9TUkMxX0FERFIsIHYtPnNyY3NbMF0uZG1h KTsKPj4gKwl9IGVsc2Ugewo+PiArCQlhc3BlZWRfdmlkZW9fd3JpdGUodiwgVkVfU1JDMF9BRERS LCB2LT5zcmNzWzBdLmRtYSk7Cj4+ICsJCWFzcGVlZF92aWRlb193cml0ZSh2LCBWRV9TUkMxX0FE RFIsIHYtPnNyY3NbMV0uZG1hKTsKPj4gKwl9Cj4+ICt9Cj4+ICsKPj4gICBzdGF0aWMgaXJxcmV0 dXJuX3QgYXNwZWVkX3ZpZGVvX2lycShpbnQgaXJxLCB2b2lkICphcmcpCj4+ICAgewo+PiAgIAlz dHJ1Y3QgYXNwZWVkX3ZpZGVvICp2aWRlbyA9IGFyZzsKPj4gQEAgLTcwNSw2ICs3NzYsNyBAQCBz dGF0aWMgaXJxcmV0dXJuX3QgYXNwZWVkX3ZpZGVvX2lycShpbnQgaXJxLCB2b2lkICphcmcpCj4+ ICAgCj4+ICAgCWlmIChzdHMgJiBWRV9JTlRFUlJVUFRfQ09NUF9DT01QTEVURSkgewo+PiAgIAkJ c3RydWN0IGFzcGVlZF92aWRlb19idWZmZXIgKmJ1ZjsKPj4gKwkJYm9vbCBlbXB0eSA9IHRydWU7 Cj4+ICAgCQl1MzIgZnJhbWVfc2l6ZSA9IGFzcGVlZF92aWRlb19yZWFkKHZpZGVvLAo+PiAgIAkJ CQkJCSAgIHZpZGVvLT5jb21wX3NpemVfcmVhZCk7Cj4+ICAgCj4+IEBAIC03MTgsMTMgKzc5MCwy MyBAQCBzdGF0aWMgaXJxcmV0dXJuX3QgYXNwZWVkX3ZpZGVvX2lycShpbnQgaXJxLCB2b2lkICph cmcpCj4+ICAgCQlpZiAoYnVmKSB7Cj4+ICAgCQkJdmIyX3NldF9wbGFuZV9wYXlsb2FkKCZidWYt PnZiLnZiMl9idWYsIDAsIGZyYW1lX3NpemUpOwo+PiAgIAo+PiAtCQkJaWYgKCFsaXN0X2lzX2xh c3QoJmJ1Zi0+bGluaywgJnZpZGVvLT5idWZmZXJzKSkgewo+PiArCQkJLyoKPj4gKwkJCSAqIGFz cGVlZF9qcGVnIHJlcXVpcmVzIGNvbnRpbnVvdXMgdXBkYXRlLgo+PiArCQkJICogT24gdGhlIGNv bnRyYXJ5LCBzdGFuZGFyZCBqcGVnIGNhbiBrZWVwIGxhc3QgYnVmZmVyCj4+ICsJCQkgKiB0byBh bHdheXMgaGF2ZSB0aGUgbGF0ZXN0IHJlc3VsdC4KPj4gKwkJCSAqLwo+PiArCQkJaWYgKHZpZGVv LT5mb3JtYXQgPT0gVklERU9fRk1UX1NUQU5EQVJEICYmCj4+ICsJCQkgICAgbGlzdF9pc19sYXN0 KCZidWYtPmxpbmssICZ2aWRlby0+YnVmZmVycykpIHsKPj4gKwkJCQllbXB0eSA9IGZhbHNlOwo+ PiArCQkJCXY0bDJfd2FybigmdmlkZW8tPnY0bDJfZGV2LCAic2tpcCB0byBrZWVwIGxhc3QgZnJh bWUgdXBkYXRlZFxuIik7Cj4+ICsJCQl9IGVsc2Ugewo+PiAgIAkJCQlidWYtPnZiLnZiMl9idWYu dGltZXN0YW1wID0ga3RpbWVfZ2V0X25zKCk7Cj4+ICAgCQkJCWJ1Zi0+dmIuc2VxdWVuY2UgPSB2 aWRlby0+c2VxdWVuY2UrKzsKPj4gICAJCQkJYnVmLT52Yi5maWVsZCA9IFY0TDJfRklFTERfTk9O RTsKPj4gICAJCQkJdmIyX2J1ZmZlcl9kb25lKCZidWYtPnZiLnZiMl9idWYsCj4+ICAgCQkJCQkJ VkIyX0JVRl9TVEFURV9ET05FKTsKPj4gICAJCQkJbGlzdF9kZWwoJmJ1Zi0+bGluayk7Cj4+ICsJ CQkJZW1wdHkgPSBsaXN0X2VtcHR5KCZ2aWRlby0+YnVmZmVycyk7Cj4+ICAgCQkJfQo+PiAgIAkJ fQo+PiAgIAkJc3Bpbl91bmxvY2soJnZpZGVvLT5sb2NrKTsKPj4gQEAgLTczOCw3ICs4MjAsMTAg QEAgc3RhdGljIGlycXJldHVybl90IGFzcGVlZF92aWRlb19pcnEoaW50IGlycSwgdm9pZCAqYXJn KQo+PiAgIAkJYXNwZWVkX3ZpZGVvX3dyaXRlKHZpZGVvLCBWRV9JTlRFUlJVUFRfU1RBVFVTLAo+ PiAgIAkJCQkgICBWRV9JTlRFUlJVUFRfQ09NUF9DT01QTEVURSk7Cj4+ICAgCQlzdHMgJj0gflZF X0lOVEVSUlVQVF9DT01QX0NPTVBMRVRFOwo+PiAtCQlpZiAodGVzdF9iaXQoVklERU9fU1RSRUFN SU5HLCAmdmlkZW8tPmZsYWdzKSAmJiBidWYpCj4+ICsKPj4gKwkJYXNwZWVkX3ZpZGVvX3N3YXBf c3JjX2J1Zih2aWRlbyk7Cj4+ICsKPj4gKwkJaWYgKHRlc3RfYml0KFZJREVPX1NUUkVBTUlORywg JnZpZGVvLT5mbGFncykgJiYgIWVtcHR5KQo+PiAgIAkJCWFzcGVlZF92aWRlb19zdGFydF9mcmFt ZSh2aWRlbyk7Cj4+ICAgCX0KPj4gICAKPj4gQEAgLTEwODUsMTAgKzExNzAsMTQgQEAgc3RhdGlj IHZvaWQgYXNwZWVkX3ZpZGVvX3NldF9yZXNvbHV0aW9uKHN0cnVjdCBhc3BlZWRfdmlkZW8gKnZp ZGVvKQo+PiAgIAkJCQkgICBGSUVMRF9QUkVQKFZFX1RHU19GSVJTVCwgdmlkZW8tPmZyYW1lX3Rv cCkgfAo+PiAgIAkJCQkgICBGSUVMRF9QUkVQKFZFX1RHU19MQVNULAo+PiAgIAkJCQkJICAgICAg dmlkZW8tPmZyYW1lX2JvdHRvbSArIDEpKTsKPj4gLQkJYXNwZWVkX3ZpZGVvX3VwZGF0ZSh2aWRl bywgVkVfQ1RSTCwgMCwgVkVfQ1RSTF9JTlRfREUpOwo+PiArCQlhc3BlZWRfdmlkZW9fdXBkYXRl KHZpZGVvLCBWRV9DVFJMLAo+PiArCQkJCSAgICBWRV9DVFJMX0lOVF9ERSB8IFZFX0NUUkxfRElS RUNUX0ZFVENILAo+PiArCQkJCSAgICBWRV9DVFJMX0lOVF9ERSk7Cj4+ICAgCX0gZWxzZSB7Cj4+ ICAgCQl2NGwyX2RiZygxLCBkZWJ1ZywgJnZpZGVvLT52NGwyX2RldiwgIkNhcHR1cmU6IERpcmVj dCBNb2RlXG4iKTsKPj4gLQkJYXNwZWVkX3ZpZGVvX3VwZGF0ZSh2aWRlbywgVkVfQ1RSTCwgMCwg VkVfQ1RSTF9ESVJFQ1RfRkVUQ0gpOwo+PiArCQlhc3BlZWRfdmlkZW9fdXBkYXRlKHZpZGVvLCBW RV9DVFJMLAo+PiArCQkJCSAgICBWRV9DVFJMX0lOVF9ERSB8IFZFX0NUUkxfRElSRUNUX0ZFVENI LAo+PiArCQkJCSAgICBWRV9DVFJMX0RJUkVDVF9GRVRDSCk7Cj4+ICAgCX0KPj4gICAKPj4gICAJ c2l6ZSAqPSA0Owo+PiBAQCAtMTEyMSwyMSArMTIxMCw2NiBAQCBzdGF0aWMgdm9pZCBhc3BlZWRf dmlkZW9fc2V0X3Jlc29sdXRpb24oc3RydWN0IGFzcGVlZF92aWRlbyAqdmlkZW8pCj4+ICAgCQlh c3BlZWRfdmlkZW9fZnJlZV9idWYodmlkZW8sICZ2aWRlby0+c3Jjc1swXSk7Cj4+ICAgfQo+PiAg IAo+PiAtc3RhdGljIHZvaWQgYXNwZWVkX3ZpZGVvX2luaXRfcmVncyhzdHJ1Y3QgYXNwZWVkX3Zp ZGVvICp2aWRlbykKPj4gK3N0YXRpYyB2b2lkIGFzcGVlZF92aWRlb191cGRhdGVfcmVncyhzdHJ1 Y3QgYXNwZWVkX3ZpZGVvICp2aWRlbykKPj4gICB7Cj4+IC0JdTMyIGNvbXBfY3RybCA9IFZFX0NP TVBfQ1RSTF9SU1ZEIHwKPj4gLQkJRklFTERfUFJFUChWRV9DT01QX0NUUkxfRENUX0xVTSwgdmlk ZW8tPmpwZWdfcXVhbGl0eSkgfAo+PiAtCQlGSUVMRF9QUkVQKFZFX0NPTVBfQ1RSTF9EQ1RfQ0hS LCB2aWRlby0+anBlZ19xdWFsaXR5IHwgMHgxMCk7Cj4+IC0JdTMyIGN0cmwgPSBWRV9DVFJMX0FV VE9fT1JfQ1VSU09SIHwKPj4gLQkJRklFTERfUFJFUChWRV9DVFJMX0NBUFRVUkVfRk1ULCBWSURF T19DQVBfRk1UX1lVVl9GVUxMX1NXSU5HKTsKPj4gLQl1MzIgc2VxX2N0cmwgPSB2aWRlby0+anBl Z19tb2RlOwo+PiArCXU4IGpwZWdfaHFfcXVhbGl0eSA9IGNsYW1wKChpbnQpdmlkZW8tPmpwZWdf aHFfcXVhbGl0eSAtIDEsIDAsCj4+ICsJCQkJICAgQVNQRUVEX1ZJREVPX0pQRUdfTlVNX1FVQUxJ VElFUyAtIDEpOwo+PiArCXUzMiBjb21wX2N0cmwgPQlGSUVMRF9QUkVQKFZFX0NPTVBfQ1RSTF9E Q1RfTFVNLCB2aWRlby0+anBlZ19xdWFsaXR5KSB8Cj4+ICsJCUZJRUxEX1BSRVAoVkVfQ09NUF9D VFJMX0RDVF9DSFIsIHZpZGVvLT5qcGVnX3F1YWxpdHkgfCAweDEwKSB8Cj4+ICsJCUZJRUxEX1BS RVAoVkVfQ09NUF9DVFJMX0VOX0hRLCB2aWRlby0+aHFfbW9kZSkgfAo+PiArCQlGSUVMRF9QUkVQ KFZFX0NPTVBfQ1RSTF9IUV9EQ1RfTFVNLCBqcGVnX2hxX3F1YWxpdHkpIHwKPj4gKwkJRklFTERf UFJFUChWRV9DT01QX0NUUkxfSFFfRENUX0NIUiwganBlZ19ocV9xdWFsaXR5IHwgMHgxMCk7Cj4+ ICsJdTMyIGN0cmwgPSAwOwo+PiArCXUzMiBzZXFfY3RybCA9IDA7Cj4+ICsKPj4gKwl2NGwyX2Ri ZygxLCBkZWJ1ZywgJnZpZGVvLT52NGwyX2RldiwgImZyYW1lcmF0ZSglZClcbiIsCj4+ICsJCSB2 aWRlby0+ZnJhbWVfcmF0ZSk7Cj4+ICsJdjRsMl9kYmcoMSwgZGVidWcsICZ2aWRlby0+djRsMl9k ZXYsICJqcGVnIGZvcm1hdCglcykgc3Vic2FtcGxlKCVzKVxuIiwKPj4gKwkJIGZvcm1hdF9zdHJb dmlkZW8tPmZvcm1hdF0sCj4+ICsJCSB2aWRlby0+eXV2NDIwID8gIjQyMCIgOiAiNDQ0Iik7Cj4+ ICsJdjRsMl9kYmcoMSwgZGVidWcsICZ2aWRlby0+djRsMl9kZXYsICJjb21wcmVzc2lvbiBxdWFs aXR5KCVkKVxuIiwKPj4gKwkJIHZpZGVvLT5qcGVnX3F1YWxpdHkpOwo+PiArCXY0bDJfZGJnKDEs IGRlYnVnLCAmdmlkZW8tPnY0bDJfZGV2LCAiaHFfbW9kZSglcykgaHFfcXVhbGl0eSglZClcbiIs Cj4+ICsJCSB2aWRlby0+aHFfbW9kZSA/ICJvbiIgOiAib2ZmIiwgdmlkZW8tPmpwZWdfaHFfcXVh bGl0eSk7Cj4+ICsKPj4gKwlpZiAodmlkZW8tPmZvcm1hdCA9PSBWSURFT19GTVRfQVNQRUVEKQo+ PiArCQlhc3BlZWRfdmlkZW9fdXBkYXRlKHZpZGVvLCBWRV9CQ0RfQ1RSTCwgMCwgVkVfQkNEX0NU UkxfRU5fQkNEKTsKPj4gKwllbHNlCj4+ICsJCWFzcGVlZF92aWRlb191cGRhdGUodmlkZW8sIFZF X0JDRF9DVFJMLCBWRV9CQ0RfQ1RSTF9FTl9CQ0QsIDApOwo+PiAgIAo+PiAgIAlpZiAodmlkZW8t PmZyYW1lX3JhdGUpCj4+ICAgCQljdHJsIHw9IEZJRUxEX1BSRVAoVkVfQ1RSTF9GUkMsIHZpZGVv LT5mcmFtZV9yYXRlKTsKPj4gICAKPj4gKwlpZiAodmlkZW8tPmZvcm1hdCA9PSBWSURFT19GTVRf U1RBTkRBUkQpIHsKPj4gKwkJY29tcF9jdHJsICY9IH5GSUVMRF9QUkVQKFZFX0NPTVBfQ1RSTF9F Tl9IUSwgdmlkZW8tPmhxX21vZGUpOwo+PiArCQlzZXFfY3RybCB8PSB2aWRlby0+anBlZ19tb2Rl Owo+PiArCX0KPj4gKwo+PiAgIAlpZiAodmlkZW8tPnl1djQyMCkKPj4gICAJCXNlcV9jdHJsIHw9 IFZFX1NFUV9DVFJMX1lVVjQyMDsKPj4gICAKPj4gKwlpZiAodmlkZW8tPmpwZWcudmlydCkKPj4g KwkJYXNwZWVkX3ZpZGVvX3VwZGF0ZV9qcGVnX3RhYmxlKHZpZGVvLT5qcGVnLnZpcnQsIHZpZGVv LT55dXY0MjApOwo+PiArCj4+ICsKPj4gKwkvKiBTZXQgY29udHJvbCByZWdpc3RlcnMgKi8KPj4g Kwlhc3BlZWRfdmlkZW9fdXBkYXRlKHZpZGVvLCBWRV9TRVFfQ1RSTCwKPj4gKwkJCSAgICB2aWRl by0+anBlZ19tb2RlIHwgVkVfU0VRX0NUUkxfWVVWNDIwLAo+PiArCQkJICAgIHNlcV9jdHJsKTsK Pj4gKwlhc3BlZWRfdmlkZW9fdXBkYXRlKHZpZGVvLCBWRV9DVFJMLCBWRV9DVFJMX0ZSQywgY3Ry bCk7Cj4+ICsJYXNwZWVkX3ZpZGVvX3VwZGF0ZSh2aWRlbywgVkVfQ09NUF9DVFJMLAo+PiArCQkJ ICAgIFZFX0NPTVBfQ1RSTF9EQ1RfTFVNIHwgVkVfQ09NUF9DVFJMX0RDVF9DSFIgfAo+PiArCQkJ ICAgIFZFX0NPTVBfQ1RSTF9FTl9IUSB8IFZFX0NPTVBfQ1RSTF9IUV9EQ1RfTFVNIHwKPj4gKwkJ CSAgICBWRV9DT01QX0NUUkxfSFFfRENUX0NIUiB8IFZFX0NPTVBfQ1RSTF9WUV80Q09MT1IgfAo+ PiArCQkJICAgIFZFX0NPTVBfQ1RSTF9WUV9EQ1RfT05MWSwKPj4gKwkJCSAgICBjb21wX2N0cmwp Owo+PiArfQo+PiArCj4+ICtzdGF0aWMgdm9pZCBhc3BlZWRfdmlkZW9faW5pdF9yZWdzKHN0cnVj dCBhc3BlZWRfdmlkZW8gKnZpZGVvKQo+PiArewo+PiArCXUzMiBjdHJsID0gVkVfQ1RSTF9BVVRP X09SX0NVUlNPUiB8Cj4+ICsJCUZJRUxEX1BSRVAoVkVfQ1RSTF9DQVBUVVJFX0ZNVCwgVklERU9f Q0FQX0ZNVF9ZVVZfRlVMTF9TV0lORyk7Cj4+ICsKPj4gICAJLyogVW5sb2NrIFZFIHJlZ2lzdGVy cyAqLwo+PiAgIAlhc3BlZWRfdmlkZW9fd3JpdGUodmlkZW8sIFZFX1BST1RFQ1RJT05fS0VZLCBW RV9QUk9URUNUSU9OX0tFWV9VTkxPQ0spOwo+PiAgIAo+PiBAQCAtMTE1MCw5ICsxMjg0LDggQEAg c3RhdGljIHZvaWQgYXNwZWVkX3ZpZGVvX2luaXRfcmVncyhzdHJ1Y3QgYXNwZWVkX3ZpZGVvICp2 aWRlbykKPj4gICAJYXNwZWVkX3ZpZGVvX3dyaXRlKHZpZGVvLCBWRV9KUEVHX0FERFIsIHZpZGVv LT5qcGVnLmRtYSk7Cj4+ICAgCj4+ICAgCS8qIFNldCBjb250cm9sIHJlZ2lzdGVycyAqLwo+PiAt CWFzcGVlZF92aWRlb193cml0ZSh2aWRlbywgVkVfU0VRX0NUUkwsIHNlcV9jdHJsKTsKPj4gICAJ YXNwZWVkX3ZpZGVvX3dyaXRlKHZpZGVvLCBWRV9DVFJMLCBjdHJsKTsKPj4gLQlhc3BlZWRfdmlk ZW9fd3JpdGUodmlkZW8sIFZFX0NPTVBfQ1RSTCwgY29tcF9jdHJsKTsKPj4gKwlhc3BlZWRfdmlk ZW9fd3JpdGUodmlkZW8sIFZFX0NPTVBfQ1RSTCwgVkVfQ09NUF9DVFJMX1JTVkQpOwo+PiAgIAo+ PiAgIAkvKiBEb24ndCBkb3duc2NhbGUgKi8KPj4gICAJYXNwZWVkX3ZpZGVvX3dyaXRlKHZpZGVv LCBWRV9TQ0FMSU5HX0ZBQ1RPUiwgMHgxMDAwMTAwMCk7Cj4+IEBAIC0xMTY4LDYgKzEzMDEsOCBA QCBzdGF0aWMgdm9pZCBhc3BlZWRfdmlkZW9faW5pdF9yZWdzKHN0cnVjdCBhc3BlZWRfdmlkZW8g KnZpZGVvKQo+PiAgIAkJCSAgIEZJRUxEX1BSRVAoVkVfTU9ERV9EVF9IT1JfU1RBQkxFLCA2KSB8 Cj4+ICAgCQkJICAgRklFTERfUFJFUChWRV9NT0RFX0RUX1ZFUl9TVEFCTEUsIDYpIHwKPj4gICAJ CQkgICBGSUVMRF9QUkVQKFZFX01PREVfRFRfRURHX1RIUk9ELCAweDY1KSk7Cj4+ICsKPj4gKwlh c3BlZWRfdmlkZW9fd3JpdGUodmlkZW8sIFZFX0JDRF9DVFJMLCAwKTsKPj4gICB9Cj4+ICAgCj4+ ICAgc3RhdGljIHZvaWQgYXNwZWVkX3ZpZGVvX3N0YXJ0KHN0cnVjdCBhc3BlZWRfdmlkZW8gKnZp ZGVvKQo+PiBAQCAtMTIwMSw2ICsxMzM2LDkgQEAgc3RhdGljIHZvaWQgYXNwZWVkX3ZpZGVvX3N0 b3Aoc3RydWN0IGFzcGVlZF92aWRlbyAqdmlkZW8pCj4+ICAgCWlmICh2aWRlby0+c3Jjc1sxXS5z aXplKQo+PiAgIAkJYXNwZWVkX3ZpZGVvX2ZyZWVfYnVmKHZpZGVvLCAmdmlkZW8tPnNyY3NbMV0p Owo+PiAgIAo+PiArCWlmICh2aWRlby0+YmNkLnNpemUpCj4+ICsJCWFzcGVlZF92aWRlb19mcmVl X2J1Zih2aWRlbywgJnZpZGVvLT5iY2QpOwo+PiArCj4+ICAgCXZpZGVvLT52NGwyX2lucHV0X3N0 YXR1cyA9IFY0TDJfSU5fU1RfTk9fU0lHTkFMOwo+PiAgIAl2aWRlby0+ZmxhZ3MgPSAwOwo+PiAg IH0KPj4gQEAgLTEyMTksMTAgKzEzNTcsMTIgQEAgc3RhdGljIGludCBhc3BlZWRfdmlkZW9fcXVl cnljYXAoc3RydWN0IGZpbGUgKmZpbGUsIHZvaWQgKmZoLAo+PiAgIHN0YXRpYyBpbnQgYXNwZWVk X3ZpZGVvX2VudW1fZm9ybWF0KHN0cnVjdCBmaWxlICpmaWxlLCB2b2lkICpmaCwKPj4gICAJCQkJ ICAgIHN0cnVjdCB2NGwyX2ZtdGRlc2MgKmYpCj4+ICAgewo+PiArCXN0cnVjdCBhc3BlZWRfdmlk ZW8gKnZpZGVvID0gdmlkZW9fZHJ2ZGF0YShmaWxlKTsKPj4gKwo+PiAgIAlpZiAoZi0+aW5kZXgp Cj4+ICAgCQlyZXR1cm4gLUVJTlZBTDsKPj4gICAKPj4gLQlmLT5waXhlbGZvcm1hdCA9IFY0TDJf UElYX0ZNVF9KUEVHOwo+PiArCWYtPnBpeGVsZm9ybWF0ID0gdmlkZW8tPnBpeF9mbXQucGl4ZWxm b3JtYXQ7Cj4+ICAgCj4+ICAgCXJldHVybiAwOwo+PiAgIH0KPj4gQEAgLTEyMzcsNiArMTM3Nywy OSBAQCBzdGF0aWMgaW50IGFzcGVlZF92aWRlb19nZXRfZm9ybWF0KHN0cnVjdCBmaWxlICpmaWxl LCB2b2lkICpmaCwKPj4gICAJcmV0dXJuIDA7Cj4+ICAgfQo+PiAgIAo+PiArc3RhdGljIGludCBh c3BlZWRfdmlkZW9fc2V0X2Zvcm1hdChzdHJ1Y3QgZmlsZSAqZmlsZSwgdm9pZCAqZmgsCj4+ICsJ CQkJICAgc3RydWN0IHY0bDJfZm9ybWF0ICpmKQo+PiArewo+PiArCXN0cnVjdCBhc3BlZWRfdmlk ZW8gKnZpZGVvID0gdmlkZW9fZHJ2ZGF0YShmaWxlKTsKPj4gKwo+PiArCWlmICh2YjJfaXNfYnVz eSgmdmlkZW8tPnF1ZXVlKSkKPj4gKwkJcmV0dXJuIC1FQlVTWTsKPj4gKwo+PiArCXN3aXRjaCAo Zi0+Zm10LnBpeC5waXhlbGZvcm1hdCkgewo+PiArCWNhc2UgVjRMMl9QSVhfRk1UX0pQRUc6Cj4+ ICsJCXZpZGVvLT5mb3JtYXQgPSBWSURFT19GTVRfU1RBTkRBUkQ7Cj4+ICsJCWJyZWFrOwo+PiAr CWNhc2UgVjRMMl9QSVhfRk1UX0FKUEc6Cj4+ICsJCXZpZGVvLT5mb3JtYXQgPSBWSURFT19GTVRf QVNQRUVEOwo+PiArCQlicmVhazsKPj4gKwlkZWZhdWx0Ogo+PiArCQlyZXR1cm4gLUVJTlZBTDsK Pj4gKwl9Cj4+ICsJdmlkZW8tPnBpeF9mbXQucGl4ZWxmb3JtYXQgPSBmLT5mbXQucGl4LnBpeGVs Zm9ybWF0Owo+PiArCj4+ICsJcmV0dXJuIDA7Cj4+ICt9Cj4+ICsKPj4gICBzdGF0aWMgaW50IGFz cGVlZF92aWRlb19lbnVtX2lucHV0KHN0cnVjdCBmaWxlICpmaWxlLCB2b2lkICpmaCwKPj4gICAJ CQkJICAgc3RydWN0IHY0bDJfaW5wdXQgKmlucCkKPj4gICB7Cj4+IEBAIC0xNDU0LDcgKzE2MTcs NyBAQCBzdGF0aWMgY29uc3Qgc3RydWN0IHY0bDJfaW9jdGxfb3BzIGFzcGVlZF92aWRlb19pb2N0 bF9vcHMgPSB7Cj4+ICAgCj4+ICAgCS52aWRpb2NfZW51bV9mbXRfdmlkX2NhcCA9IGFzcGVlZF92 aWRlb19lbnVtX2Zvcm1hdCwKPj4gICAJLnZpZGlvY19nX2ZtdF92aWRfY2FwID0gYXNwZWVkX3Zp ZGVvX2dldF9mb3JtYXQsCj4+IC0JLnZpZGlvY19zX2ZtdF92aWRfY2FwID0gYXNwZWVkX3ZpZGVv X2dldF9mb3JtYXQsCj4+ICsJLnZpZGlvY19zX2ZtdF92aWRfY2FwID0gYXNwZWVkX3ZpZGVvX3Nl dF9mb3JtYXQsCj4+ICAgCS52aWRpb2NfdHJ5X2ZtdF92aWRfY2FwID0gYXNwZWVkX3ZpZGVvX2dl dF9mb3JtYXQsCj4+ICAgCj4+ICAgCS52aWRpb2NfcmVxYnVmcyA9IHZiMl9pb2N0bF9yZXFidWZz LAo+PiBAQCAtMTQ4NiwyNyArMTY0OSw2IEBAIHN0YXRpYyBjb25zdCBzdHJ1Y3QgdjRsMl9pb2N0 bF9vcHMgYXNwZWVkX3ZpZGVvX2lvY3RsX29wcyA9IHsKPj4gICAJLnZpZGlvY191bnN1YnNjcmli ZV9ldmVudCA9IHY0bDJfZXZlbnRfdW5zdWJzY3JpYmUsCj4+ICAgfTsKPj4gICAKPj4gLXN0YXRp YyB2b2lkIGFzcGVlZF92aWRlb191cGRhdGVfanBlZ19xdWFsaXR5KHN0cnVjdCBhc3BlZWRfdmlk ZW8gKnZpZGVvKQo+PiAtewo+PiAtCXUzMiBjb21wX2N0cmwgPSBGSUVMRF9QUkVQKFZFX0NPTVBf Q1RSTF9EQ1RfTFVNLCB2aWRlby0+anBlZ19xdWFsaXR5KSB8Cj4+IC0JCUZJRUxEX1BSRVAoVkVf Q09NUF9DVFJMX0RDVF9DSFIsIHZpZGVvLT5qcGVnX3F1YWxpdHkgfCAweDEwKTsKPj4gLQo+PiAt CWFzcGVlZF92aWRlb191cGRhdGUodmlkZW8sIFZFX0NPTVBfQ1RSTCwKPj4gLQkJCSAgICBWRV9D T01QX0NUUkxfRENUX0xVTSB8IFZFX0NPTVBfQ1RSTF9EQ1RfQ0hSLAo+PiAtCQkJICAgIGNvbXBf Y3RybCk7Cj4+IC19Cj4+IC0KPj4gLXN0YXRpYyB2b2lkIGFzcGVlZF92aWRlb191cGRhdGVfc3Vi c2FtcGxpbmcoc3RydWN0IGFzcGVlZF92aWRlbyAqdmlkZW8pCj4+IC17Cj4+IC0JaWYgKHZpZGVv LT5qcGVnLnZpcnQpCj4+IC0JCWFzcGVlZF92aWRlb191cGRhdGVfanBlZ190YWJsZSh2aWRlby0+ anBlZy52aXJ0LCB2aWRlby0+eXV2NDIwKTsKPj4gLQo+PiAtCWlmICh2aWRlby0+eXV2NDIwKQo+ PiAtCQlhc3BlZWRfdmlkZW9fdXBkYXRlKHZpZGVvLCBWRV9TRVFfQ1RSTCwgMCwgVkVfU0VRX0NU UkxfWVVWNDIwKTsKPj4gLQllbHNlCj4+IC0JCWFzcGVlZF92aWRlb191cGRhdGUodmlkZW8sIFZF X1NFUV9DVFJMLCBWRV9TRVFfQ1RSTF9ZVVY0MjAsIDApOwo+PiAtfQo+PiAtCj4+ICAgc3RhdGlj IGludCBhc3BlZWRfdmlkZW9fc2V0X2N0cmwoc3RydWN0IHY0bDJfY3RybCAqY3RybCkKPj4gICB7 Cj4+ICAgCXN0cnVjdCBhc3BlZWRfdmlkZW8gKnZpZGVvID0gY29udGFpbmVyX29mKGN0cmwtPmhh bmRsZXIsCj4+IEBAIC0xNTE2LDE2ICsxNjU4LDIzIEBAIHN0YXRpYyBpbnQgYXNwZWVkX3ZpZGVv X3NldF9jdHJsKHN0cnVjdCB2NGwyX2N0cmwgKmN0cmwpCj4+ICAgCXN3aXRjaCAoY3RybC0+aWQp IHsKPj4gICAJY2FzZSBWNEwyX0NJRF9KUEVHX0NPTVBSRVNTSU9OX1FVQUxJVFk6Cj4+ICAgCQl2 aWRlby0+anBlZ19xdWFsaXR5ID0gY3RybC0+dmFsOwo+PiAtCQlhc3BlZWRfdmlkZW9fdXBkYXRl X2pwZWdfcXVhbGl0eSh2aWRlbyk7Cj4+ICsJCWlmICh0ZXN0X2JpdChWSURFT19TVFJFQU1JTkcs ICZ2aWRlby0+ZmxhZ3MpKQo+PiArCQkJYXNwZWVkX3ZpZGVvX3VwZGF0ZV9yZWdzKHZpZGVvKTsK Pj4gICAJCWJyZWFrOwo+PiAgIAljYXNlIFY0TDJfQ0lEX0pQRUdfQ0hST01BX1NVQlNBTVBMSU5H Ogo+PiAtCQlpZiAoY3RybC0+dmFsID09IFY0TDJfSlBFR19DSFJPTUFfU1VCU0FNUExJTkdfNDIw KSB7Cj4+IC0JCQl2aWRlby0+eXV2NDIwID0gdHJ1ZTsKPj4gLQkJCWFzcGVlZF92aWRlb191cGRh dGVfc3Vic2FtcGxpbmcodmlkZW8pOwo+PiAtCQl9IGVsc2Ugewo+PiAtCQkJdmlkZW8tPnl1djQy MCA9IGZhbHNlOwo+PiAtCQkJYXNwZWVkX3ZpZGVvX3VwZGF0ZV9zdWJzYW1wbGluZyh2aWRlbyk7 Cj4+IC0JCX0KPj4gKwkJdmlkZW8tPnl1djQyMCA9IChjdHJsLT52YWwgPT0gVjRMMl9KUEVHX0NI Uk9NQV9TVUJTQU1QTElOR180MjApOwo+PiArCQlpZiAodGVzdF9iaXQoVklERU9fU1RSRUFNSU5H LCAmdmlkZW8tPmZsYWdzKSkKPj4gKwkJCWFzcGVlZF92aWRlb191cGRhdGVfcmVncyh2aWRlbyk7 Cj4+ICsJCWJyZWFrOwo+PiArCWNhc2UgVjRMMl9DSURfQVNQRUVEX0hRX01PREU6Cj4+ICsJCXZp ZGVvLT5ocV9tb2RlID0gY3RybC0+dmFsOwo+PiArCQlpZiAodGVzdF9iaXQoVklERU9fU1RSRUFN SU5HLCAmdmlkZW8tPmZsYWdzKSkKPj4gKwkJCWFzcGVlZF92aWRlb191cGRhdGVfcmVncyh2aWRl byk7Cj4+ICsJCWJyZWFrOwo+PiArCWNhc2UgVjRMMl9DSURfQVNQRUVEX0hRX0pQRUdfUVVBTElU WToKPj4gKwkJdmlkZW8tPmpwZWdfaHFfcXVhbGl0eSA9IGN0cmwtPnZhbDsKPj4gKwkJaWYgKHRl c3RfYml0KFZJREVPX1NUUkVBTUlORywgJnZpZGVvLT5mbGFncykpCj4+ICsJCQlhc3BlZWRfdmlk ZW9fdXBkYXRlX3JlZ3ModmlkZW8pOwo+PiAgIAkJYnJlYWs7Cj4+ICAgCWRlZmF1bHQ6Cj4+ICAg CQlyZXR1cm4gLUVJTlZBTDsKPj4gQEAgLTE1MzgsNiArMTY4NywyOCBAQCBzdGF0aWMgY29uc3Qg c3RydWN0IHY0bDJfY3RybF9vcHMgYXNwZWVkX3ZpZGVvX2N0cmxfb3BzID0gewo+PiAgIAkuc19j dHJsID0gYXNwZWVkX3ZpZGVvX3NldF9jdHJsLAo+PiAgIH07Cj4+ICAgCj4+ICtzdGF0aWMgY29u c3Qgc3RydWN0IHY0bDJfY3RybF9jb25maWcgYXNwZWVkX2N0cmxfSFFfbW9kZSA9IHsKPj4gKwku b3BzID0gJmFzcGVlZF92aWRlb19jdHJsX29wcywKPj4gKwkuaWQgPSBWNEwyX0NJRF9BU1BFRURf SFFfTU9ERSwKPj4gKwkubmFtZSA9ICJBc3BlZWQgSFEgTW9kZSIsCj4+ICsJLnR5cGUgPSBWNEwy X0NUUkxfVFlQRV9CT09MRUFOLAo+PiArCS5taW4gPSBmYWxzZSwKPj4gKwkubWF4ID0gdHJ1ZSwK Pj4gKwkuc3RlcCA9IDEsCj4+ICsJLmRlZiA9IGZhbHNlLAo+PiArfTsKPj4gKwo+PiArc3RhdGlj IGNvbnN0IHN0cnVjdCB2NGwyX2N0cmxfY29uZmlnIGFzcGVlZF9jdHJsX0hRX2pwZWdfcXVhbGl0 eSA9IHsKPj4gKwkub3BzID0gJmFzcGVlZF92aWRlb19jdHJsX29wcywKPj4gKwkuaWQgPSBWNEwy X0NJRF9BU1BFRURfSFFfSlBFR19RVUFMSVRZLAo+PiArCS5uYW1lID0gIkFzcGVlZCBIUSBRdWFs aXR5IiwKPj4gKwkudHlwZSA9IFY0TDJfQ1RSTF9UWVBFX0lOVEVHRVIsCj4+ICsJLm1pbiA9IDEs Cj4+ICsJLm1heCA9IEFTUEVFRF9WSURFT19KUEVHX05VTV9RVUFMSVRJRVMsCj4+ICsJLnN0ZXAg PSAxLAo+PiArCS5kZWYgPSAxLAo+PiArfTsKPj4gKwo+PiAgIHN0YXRpYyB2b2lkIGFzcGVlZF92 aWRlb19yZXNvbHV0aW9uX3dvcmsoc3RydWN0IHdvcmtfc3RydWN0ICp3b3JrKQo+PiAgIHsKPj4g ICAJc3RydWN0IGRlbGF5ZWRfd29yayAqZHdvcmsgPSB0b19kZWxheWVkX3dvcmsod29yayk7Cj4+ IEBAIC0xNTUyLDYgKzE3MjMsOCBAQCBzdGF0aWMgdm9pZCBhc3BlZWRfdmlkZW9fcmVzb2x1dGlv bl93b3JrKHN0cnVjdCB3b3JrX3N0cnVjdCAqd29yaykKPj4gICAKPj4gICAJYXNwZWVkX3ZpZGVv X2luaXRfcmVncyh2aWRlbyk7Cj4+ICAgCj4+ICsJYXNwZWVkX3ZpZGVvX3VwZGF0ZV9yZWdzKHZp ZGVvKTsKPj4gKwo+PiAgIAlhc3BlZWRfdmlkZW9fZ2V0X3Jlc29sdXRpb24odmlkZW8pOwo+PiAg IAo+PiAgIAlpZiAodmlkZW8tPmRldGVjdGVkX3RpbWluZ3Mud2lkdGggIT0gdmlkZW8tPmFjdGl2 ZV90aW1pbmdzLndpZHRoIHx8Cj4+IEBAIC0xNjYyLDYgKzE4MzUsOCBAQCBzdGF0aWMgaW50IGFz cGVlZF92aWRlb19zdGFydF9zdHJlYW1pbmcoc3RydWN0IHZiMl9xdWV1ZSAqcSwKPj4gICAJdmlk ZW8tPnBlcmYuZHVyYXRpb25fbWF4ID0gMDsKPj4gICAJdmlkZW8tPnBlcmYuZHVyYXRpb25fbWlu ID0gMHhmZmZmZmZmZjsKPj4gICAKPj4gKwlhc3BlZWRfdmlkZW9fdXBkYXRlX3JlZ3ModmlkZW8p Owo+PiArCj4+ICAgCXJjID0gYXNwZWVkX3ZpZGVvX3N0YXJ0X2ZyYW1lKHZpZGVvKTsKPj4gICAJ aWYgKHJjKSB7Cj4+ICAgCQlhc3BlZWRfdmlkZW9fYnVmc19kb25lKHZpZGVvLCBWQjJfQlVGX1NU QVRFX1FVRVVFRCk7Cj4+IEBAIC0xODAwLDYgKzE5NzUsNyBAQCBzdGF0aWMgaW50IGFzcGVlZF92 aWRlb19zZXR1cF92aWRlbyhzdHJ1Y3QgYXNwZWVkX3ZpZGVvICp2aWRlbykKPj4gICAJc3RydWN0 IHY0bDJfZGV2aWNlICp2NGwyX2RldiA9ICZ2aWRlby0+djRsMl9kZXY7Cj4+ICAgCXN0cnVjdCB2 YjJfcXVldWUgKnZicSA9ICZ2aWRlby0+cXVldWU7Cj4+ICAgCXN0cnVjdCB2aWRlb19kZXZpY2Ug KnZkZXYgPSAmdmlkZW8tPnZkZXY7Cj4+ICsJc3RydWN0IHY0bDJfY3RybF9oYW5kbGVyICpoZGwg PSAmdmlkZW8tPmN0cmxfaGFuZGxlcjsKPj4gICAJaW50IHJjOwo+PiAgIAo+PiAgIAl2aWRlby0+ cGl4X2ZtdC5waXhlbGZvcm1hdCA9IFY0TDJfUElYX0ZNVF9KUEVHOwo+PiBAQCAtMTgxNCwxNiAr MTk5MCwxOCBAQCBzdGF0aWMgaW50IGFzcGVlZF92aWRlb19zZXR1cF92aWRlbyhzdHJ1Y3QgYXNw ZWVkX3ZpZGVvICp2aWRlbykKPj4gICAJCXJldHVybiByYzsKPj4gICAJfQo+PiAgIAo+PiAtCXY0 bDJfY3RybF9oYW5kbGVyX2luaXQoJnZpZGVvLT5jdHJsX2hhbmRsZXIsIDIpOwo+PiAtCXY0bDJf Y3RybF9uZXdfc3RkKCZ2aWRlby0+Y3RybF9oYW5kbGVyLCAmYXNwZWVkX3ZpZGVvX2N0cmxfb3Bz LAo+PiArCXY0bDJfY3RybF9oYW5kbGVyX2luaXQoaGRsLCA0KTsKPj4gKwl2NGwyX2N0cmxfbmV3 X3N0ZChoZGwsICZhc3BlZWRfdmlkZW9fY3RybF9vcHMsCj4+ICAgCQkJICBWNEwyX0NJRF9KUEVH X0NPTVBSRVNTSU9OX1FVQUxJVFksIDAsCj4+ICAgCQkJICBBU1BFRURfVklERU9fSlBFR19OVU1f UVVBTElUSUVTIC0gMSwgMSwgMCk7Cj4+IC0JdjRsMl9jdHJsX25ld19zdGRfbWVudSgmdmlkZW8t PmN0cmxfaGFuZGxlciwgJmFzcGVlZF92aWRlb19jdHJsX29wcywKPj4gKwl2NGwyX2N0cmxfbmV3 X3N0ZF9tZW51KGhkbCwgJmFzcGVlZF92aWRlb19jdHJsX29wcywKPj4gICAJCQkgICAgICAgVjRM Ml9DSURfSlBFR19DSFJPTUFfU1VCU0FNUExJTkcsCj4+ICAgCQkJICAgICAgIFY0TDJfSlBFR19D SFJPTUFfU1VCU0FNUExJTkdfNDIwLCBtYXNrLAo+PiAgIAkJCSAgICAgICBWNEwyX0pQRUdfQ0hS T01BX1NVQlNBTVBMSU5HXzQ0NCk7Cj4+ICsJdjRsMl9jdHJsX25ld19jdXN0b20oaGRsLCAmYXNw ZWVkX2N0cmxfSFFfbW9kZSwgTlVMTCk7Cj4+ICsJdjRsMl9jdHJsX25ld19jdXN0b20oaGRsLCAm YXNwZWVkX2N0cmxfSFFfanBlZ19xdWFsaXR5LCBOVUxMKTsKPj4gICAKPj4gLQlyYyA9IHZpZGVv LT5jdHJsX2hhbmRsZXIuZXJyb3I7Cj4+ICsJcmMgPSBoZGwtPmVycm9yOwo+PiAgIAlpZiAocmMp IHsKPj4gICAJCXY0bDJfY3RybF9oYW5kbGVyX2ZyZWUoJnZpZGVvLT5jdHJsX2hhbmRsZXIpOwo+ PiAgIAkJdjRsMl9kZXZpY2VfdW5yZWdpc3Rlcih2NGwyX2Rldik7Cj4+IEBAIC0xODMyLDcgKzIw MTAsNyBAQCBzdGF0aWMgaW50IGFzcGVlZF92aWRlb19zZXR1cF92aWRlbyhzdHJ1Y3QgYXNwZWVk X3ZpZGVvICp2aWRlbykKPj4gICAJCXJldHVybiByYzsKPj4gICAJfQo+PiAgIAo+PiAtCXY0bDJf ZGV2LT5jdHJsX2hhbmRsZXIgPSAmdmlkZW8tPmN0cmxfaGFuZGxlcjsKPj4gKwl2NGwyX2Rldi0+ Y3RybF9oYW5kbGVyID0gaGRsOwo+PiAgIAo+PiAgIAl2YnEtPnR5cGUgPSBWNEwyX0JVRl9UWVBF X1ZJREVPX0NBUFRVUkU7Cj4+ICAgCXZicS0+aW9fbW9kZXMgPSBWQjJfTU1BUCB8IFZCMl9SRUFE IHwgVkIyX0RNQUJVRjsKPj4gQEAgLTE5ODAsNiArMjE1OCw3IEBAIHN0YXRpYyBpbnQgYXNwZWVk X3ZpZGVvX3Byb2JlKHN0cnVjdCBwbGF0Zm9ybV9kZXZpY2UgKnBkZXYpCj4+ICAgCXZpZGVvLT5j b21wX3NpemVfcmVhZCA9IGNvbmZpZy0+Y29tcF9zaXplX3JlYWQ7Cj4+ICAgCj4+ICAgCXZpZGVv LT5mcmFtZV9yYXRlID0gMzA7Cj4+ICsJdmlkZW8tPmpwZWdfaHFfcXVhbGl0eSA9IDE7Cj4+ICAg CXZpZGVvLT5kZXYgPSAmcGRldi0+ZGV2Owo+PiAgIAlzcGluX2xvY2tfaW5pdCgmdmlkZW8tPmxv Y2spOwo+PiAgIAltdXRleF9pbml0KCZ2aWRlby0+dmlkZW9fbG9jayk7Cj4+IGRpZmYgLS1naXQg YS9pbmNsdWRlL3VhcGkvbGludXgvYXNwZWVkLXZpZGVvLmggYi9pbmNsdWRlL3VhcGkvbGludXgv YXNwZWVkLXZpZGVvLmgKPj4gbmV3IGZpbGUgbW9kZSAxMDA2NDQKPj4gaW5kZXggMDAwMDAwMDAw MDAwLi42M2YwNDMyMTkyYTUKPj4gLS0tIC9kZXYvbnVsbAo+PiArKysgYi9pbmNsdWRlL3VhcGkv bGludXgvYXNwZWVkLXZpZGVvLmgKPj4gQEAgLTAsMCArMSwxNSBAQAo+PiArLyogU1BEWC1MaWNl bnNlLUlkZW50aWZpZXI6IEdQTC0yLjAtb3ItbGF0ZXIgKi8KPj4gKy8qCj4+ICsgKiBDb3B5cmln aHQgKEMpIDIwMjEgQVNQRUVEIFRlY2hub2xvZ3kgSW5jLgo+PiArICovCj4+ICsKPj4gKyNpZm5k ZWYgX1VBUElfTElOVVhfQVNQRUVEX1ZJREVPX0gKPj4gKyNkZWZpbmUgX1VBUElfTElOVVhfQVNQ RUVEX1ZJREVPX0gKPj4gKwo+PiArI2luY2x1ZGUgPGxpbnV4L3Y0bDItY29udHJvbHMuaD4KPj4g Kwo+PiArI2RlZmluZSBWNEwyX0NJRF9BU1BFRURfQ09NUFJFU1NJT05fU0NIRU1FCShWNEwyX0NJ RF9VU0VSX0FTUEVFRF9CQVNFICArIDEpCj4+ICsjZGVmaW5lIFY0TDJfQ0lEX0FTUEVFRF9IUV9N T0RFCQkJKFY0TDJfQ0lEX1VTRVJfQVNQRUVEX0JBU0UgICsgMikKPj4gKyNkZWZpbmUgVjRMMl9D SURfQVNQRUVEX0hRX0pQRUdfUVVBTElUWQkJKFY0TDJfQ0lEX1VTRVJfQVNQRUVEX0JBU0UgICsg MykKPiBJIGJlbGlldmUgeW91IGFyZSBtaXNzaW5nIGRvY3VtZW50YXRpb24gZm9yIHRoZXNlLiBF dmVuIHZlbmRvciBDSUQgZ2V0IHRvIGJlCj4gZG9jdW1lbnRlZCBpbiB0aGUgUlNUIGRvYywgaXQg YWxzbyBoZWxwcyB1cyByZXZpZXdlciB0byBqdWRnZSBpZiB0aGVzZSBhcmUKPiB0cnVsbHkgdmVu ZG9yIGNvbnRyb2xzIG9yIHNob3VsZCBiZSBnZW5lcmFsaXplZCwgaXRzIG5vdCBjdXJyZW50bHkg cG9zc2libGUgdG8KPiBtYWtlIGFuIG9waW5pb24uCk9LLCBJIHdpbGwgYWRkIGFzcGVlZC5yc3Qg dG8gZGlzY2xvc2UgcmVsYXRlZCBpbmZvcm1hdGlvbi4KPj4gKwo+PiArI2VuZGlmIC8qIF9VQVBJ X0xJTlVYX0FTUEVFRF9WSURFT19IICovCgotLSAKQmVzdCBSZWdhcmRzCkphbW15CgoKX19fX19f X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX18KbGludXgtYXJtLWtlcm5l bCBtYWlsaW5nIGxpc3QKbGludXgtYXJtLWtlcm5lbEBsaXN0cy5pbmZyYWRlYWQub3JnCmh0dHA6 Ly9saXN0cy5pbmZyYWRlYWQub3JnL21haWxtYW4vbGlzdGluZm8vbGludXgtYXJtLWtlcm5lbAo=