From mboxrd@z Thu Jan 1 00:00:00 1970 Return-path: Received: from galahad.ideasonboard.com ([185.26.127.97]:35876 "EHLO galahad.ideasonboard.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751679AbeDFT7Q (ORCPT ); Fri, 6 Apr 2018 15:59:16 -0400 From: Laurent Pinchart To: linux-media@vger.kernel.org Cc: dri-devel@lists.freedesktop.org, linux-renesas-soc@vger.kernel.org, Kieran Bingham Subject: [PATCH v2.1 06/15] v4l: vsp1: Move DRM atomic commit pipeline setup to separate function Date: Fri, 6 Apr 2018 22:59:09 +0300 Message-Id: <20180406195909.12029-1-laurent.pinchart+renesas@ideasonboard.com> In-Reply-To: <20180405091840.30728-7-laurent.pinchart+renesas@ideasonboard.com> References: <20180405091840.30728-7-laurent.pinchart+renesas@ideasonboard.com> Sender: linux-media-owner@vger.kernel.org List-ID: The DRM pipeline setup code used at atomic commit time is similar to the setup code used when enabling the pipeline. Move it to a separate function in order to share it. Signed-off-by: Laurent Pinchart Reviewed-by: Kieran Bingham --- Changes since v2: - Rename vsp1_du_pipeline_setup_input() to vsp1_du_pipeline_setup_inputs() --- drivers/media/platform/vsp1/vsp1_drm.c | 347 +++++++++++++++++---------------- 1 file changed, 180 insertions(+), 167 deletions(-) diff --git a/drivers/media/platform/vsp1/vsp1_drm.c b/drivers/media/platform/vsp1/vsp1_drm.c index 9a043a915c0b..d99278f45bd8 100644 --- a/drivers/media/platform/vsp1/vsp1_drm.c +++ b/drivers/media/platform/vsp1/vsp1_drm.c @@ -46,6 +46,185 @@ static void vsp1_du_pipeline_frame_end(struct vsp1_pipeline *pipe, * Pipeline Configuration */ +/* Setup one RPF and the connected BRU sink pad. */ +static int vsp1_du_pipeline_setup_rpf(struct vsp1_device *vsp1, + struct vsp1_pipeline *pipe, + struct vsp1_rwpf *rpf, + unsigned int bru_input) +{ + struct v4l2_subdev_selection sel; + struct v4l2_subdev_format format; + const struct v4l2_rect *crop; + int ret; + + /* + * Configure the format on the RPF sink pad and propagate it up to the + * BRU sink pad. + */ + crop = &vsp1->drm->inputs[rpf->entity.index].crop; + + memset(&format, 0, sizeof(format)); + format.which = V4L2_SUBDEV_FORMAT_ACTIVE; + format.pad = RWPF_PAD_SINK; + format.format.width = crop->width + crop->left; + format.format.height = crop->height + crop->top; + format.format.code = rpf->fmtinfo->mbus; + format.format.field = V4L2_FIELD_NONE; + + ret = v4l2_subdev_call(&rpf->entity.subdev, pad, set_fmt, NULL, + &format); + if (ret < 0) + return ret; + + dev_dbg(vsp1->dev, + "%s: set format %ux%u (%x) on RPF%u sink\n", + __func__, format.format.width, format.format.height, + format.format.code, rpf->entity.index); + + memset(&sel, 0, sizeof(sel)); + sel.which = V4L2_SUBDEV_FORMAT_ACTIVE; + sel.pad = RWPF_PAD_SINK; + sel.target = V4L2_SEL_TGT_CROP; + sel.r = *crop; + + ret = v4l2_subdev_call(&rpf->entity.subdev, pad, set_selection, NULL, + &sel); + if (ret < 0) + return ret; + + dev_dbg(vsp1->dev, + "%s: set selection (%u,%u)/%ux%u on RPF%u sink\n", + __func__, sel.r.left, sel.r.top, sel.r.width, sel.r.height, + rpf->entity.index); + + /* + * RPF source, hardcode the format to ARGB8888 to turn on format + * conversion if needed. + */ + format.pad = RWPF_PAD_SOURCE; + + ret = v4l2_subdev_call(&rpf->entity.subdev, pad, get_fmt, NULL, + &format); + if (ret < 0) + return ret; + + dev_dbg(vsp1->dev, + "%s: got format %ux%u (%x) on RPF%u source\n", + __func__, format.format.width, format.format.height, + format.format.code, rpf->entity.index); + + format.format.code = MEDIA_BUS_FMT_ARGB8888_1X32; + + ret = v4l2_subdev_call(&rpf->entity.subdev, pad, set_fmt, NULL, + &format); + if (ret < 0) + return ret; + + /* BRU sink, propagate the format from the RPF source. */ + format.pad = bru_input; + + ret = v4l2_subdev_call(&pipe->bru->subdev, pad, set_fmt, NULL, + &format); + if (ret < 0) + return ret; + + dev_dbg(vsp1->dev, "%s: set format %ux%u (%x) on %s pad %u\n", + __func__, format.format.width, format.format.height, + format.format.code, BRU_NAME(pipe->bru), format.pad); + + sel.pad = bru_input; + sel.target = V4L2_SEL_TGT_COMPOSE; + sel.r = vsp1->drm->inputs[rpf->entity.index].compose; + + ret = v4l2_subdev_call(&pipe->bru->subdev, pad, set_selection, NULL, + &sel); + if (ret < 0) + return ret; + + dev_dbg(vsp1->dev, "%s: set selection (%u,%u)/%ux%u on %s pad %u\n", + __func__, sel.r.left, sel.r.top, sel.r.width, sel.r.height, + BRU_NAME(pipe->bru), sel.pad); + + return 0; +} + +static unsigned int rpf_zpos(struct vsp1_device *vsp1, struct vsp1_rwpf *rpf) +{ + return vsp1->drm->inputs[rpf->entity.index].zpos; +} + +/* Setup the input side of the pipeline (RPFs and BRU sink pads). */ +static int vsp1_du_pipeline_setup_inputs(struct vsp1_device *vsp1, + struct vsp1_pipeline *pipe) +{ + struct vsp1_rwpf *inputs[VSP1_MAX_RPF] = { NULL, }; + struct vsp1_bru *bru = to_bru(&pipe->bru->subdev); + unsigned int i; + int ret; + + /* Count the number of enabled inputs and sort them by Z-order. */ + pipe->num_inputs = 0; + + for (i = 0; i < vsp1->info->rpf_count; ++i) { + struct vsp1_rwpf *rpf = vsp1->rpf[i]; + unsigned int j; + + /* + * Make sure we don't accept more inputs than the hardware can + * handle. This is a temporary fix to avoid display stall, we + * need to instead allocate the BRU or BRS to display pipelines + * dynamically based on the number of planes they each use. + */ + if (pipe->num_inputs >= pipe->bru->source_pad) + pipe->inputs[i] = NULL; + + if (!pipe->inputs[i]) + continue; + + /* Insert the RPF in the sorted RPFs array. */ + for (j = pipe->num_inputs++; j > 0; --j) { + if (rpf_zpos(vsp1, inputs[j-1]) <= rpf_zpos(vsp1, rpf)) + break; + inputs[j] = inputs[j-1]; + } + + inputs[j] = rpf; + } + + /* Setup the RPF input pipeline for every enabled input. */ + for (i = 0; i < pipe->bru->source_pad; ++i) { + struct vsp1_rwpf *rpf = inputs[i]; + + if (!rpf) { + bru->inputs[i].rpf = NULL; + continue; + } + + if (!rpf->entity.pipe) { + rpf->entity.pipe = pipe; + list_add_tail(&rpf->entity.list_pipe, &pipe->entities); + } + + bru->inputs[i].rpf = rpf; + rpf->bru_input = i; + rpf->entity.sink = pipe->bru; + rpf->entity.sink_pad = i; + + dev_dbg(vsp1->dev, "%s: connecting RPF.%u to %s:%u\n", + __func__, rpf->entity.index, BRU_NAME(pipe->bru), i); + + ret = vsp1_du_pipeline_setup_rpf(vsp1, pipe, rpf, i); + if (ret < 0) { + dev_err(vsp1->dev, + "%s: failed to setup RPF.%u\n", + __func__, rpf->entity.index); + return ret; + } + } + + return 0; +} + /* Configure all entities in the pipeline. */ static void vsp1_du_pipeline_configure(struct vsp1_pipeline *pipe) { @@ -396,111 +575,6 @@ int vsp1_du_atomic_update(struct device *dev, unsigned int pipe_index, } EXPORT_SYMBOL_GPL(vsp1_du_atomic_update); -static int vsp1_du_setup_rpf_pipe(struct vsp1_device *vsp1, - struct vsp1_pipeline *pipe, - struct vsp1_rwpf *rpf, unsigned int bru_input) -{ - struct v4l2_subdev_selection sel; - struct v4l2_subdev_format format; - const struct v4l2_rect *crop; - int ret; - - /* - * Configure the format on the RPF sink pad and propagate it up to the - * BRU sink pad. - */ - crop = &vsp1->drm->inputs[rpf->entity.index].crop; - - memset(&format, 0, sizeof(format)); - format.which = V4L2_SUBDEV_FORMAT_ACTIVE; - format.pad = RWPF_PAD_SINK; - format.format.width = crop->width + crop->left; - format.format.height = crop->height + crop->top; - format.format.code = rpf->fmtinfo->mbus; - format.format.field = V4L2_FIELD_NONE; - - ret = v4l2_subdev_call(&rpf->entity.subdev, pad, set_fmt, NULL, - &format); - if (ret < 0) - return ret; - - dev_dbg(vsp1->dev, - "%s: set format %ux%u (%x) on RPF%u sink\n", - __func__, format.format.width, format.format.height, - format.format.code, rpf->entity.index); - - memset(&sel, 0, sizeof(sel)); - sel.which = V4L2_SUBDEV_FORMAT_ACTIVE; - sel.pad = RWPF_PAD_SINK; - sel.target = V4L2_SEL_TGT_CROP; - sel.r = *crop; - - ret = v4l2_subdev_call(&rpf->entity.subdev, pad, set_selection, NULL, - &sel); - if (ret < 0) - return ret; - - dev_dbg(vsp1->dev, - "%s: set selection (%u,%u)/%ux%u on RPF%u sink\n", - __func__, sel.r.left, sel.r.top, sel.r.width, sel.r.height, - rpf->entity.index); - - /* - * RPF source, hardcode the format to ARGB8888 to turn on format - * conversion if needed. - */ - format.pad = RWPF_PAD_SOURCE; - - ret = v4l2_subdev_call(&rpf->entity.subdev, pad, get_fmt, NULL, - &format); - if (ret < 0) - return ret; - - dev_dbg(vsp1->dev, - "%s: got format %ux%u (%x) on RPF%u source\n", - __func__, format.format.width, format.format.height, - format.format.code, rpf->entity.index); - - format.format.code = MEDIA_BUS_FMT_ARGB8888_1X32; - - ret = v4l2_subdev_call(&rpf->entity.subdev, pad, set_fmt, NULL, - &format); - if (ret < 0) - return ret; - - /* BRU sink, propagate the format from the RPF source. */ - format.pad = bru_input; - - ret = v4l2_subdev_call(&pipe->bru->subdev, pad, set_fmt, NULL, - &format); - if (ret < 0) - return ret; - - dev_dbg(vsp1->dev, "%s: set format %ux%u (%x) on %s pad %u\n", - __func__, format.format.width, format.format.height, - format.format.code, BRU_NAME(pipe->bru), format.pad); - - sel.pad = bru_input; - sel.target = V4L2_SEL_TGT_COMPOSE; - sel.r = vsp1->drm->inputs[rpf->entity.index].compose; - - ret = v4l2_subdev_call(&pipe->bru->subdev, pad, set_selection, NULL, - &sel); - if (ret < 0) - return ret; - - dev_dbg(vsp1->dev, "%s: set selection (%u,%u)/%ux%u on %s pad %u\n", - __func__, sel.r.left, sel.r.top, sel.r.width, sel.r.height, - BRU_NAME(pipe->bru), sel.pad); - - return 0; -} - -static unsigned int rpf_zpos(struct vsp1_device *vsp1, struct vsp1_rwpf *rpf) -{ - return vsp1->drm->inputs[rpf->entity.index].zpos; -} - /** * vsp1_du_atomic_flush - Commit an atomic update * @dev: the VSP device @@ -511,69 +585,8 @@ void vsp1_du_atomic_flush(struct device *dev, unsigned int pipe_index) struct vsp1_device *vsp1 = dev_get_drvdata(dev); struct vsp1_drm_pipeline *drm_pipe = &vsp1->drm->pipe[pipe_index]; struct vsp1_pipeline *pipe = &drm_pipe->pipe; - struct vsp1_rwpf *inputs[VSP1_MAX_RPF] = { NULL, }; - struct vsp1_bru *bru = to_bru(&pipe->bru->subdev); - unsigned int i; - int ret; - - /* Count the number of enabled inputs and sort them by Z-order. */ - pipe->num_inputs = 0; - - for (i = 0; i < vsp1->info->rpf_count; ++i) { - struct vsp1_rwpf *rpf = vsp1->rpf[i]; - unsigned int j; - - /* - * Make sure we don't accept more inputs than the hardware can - * handle. This is a temporary fix to avoid display stall, we - * need to instead allocate the BRU or BRS to display pipelines - * dynamically based on the number of planes they each use. - */ - if (pipe->num_inputs >= pipe->bru->source_pad) - pipe->inputs[i] = NULL; - - if (!pipe->inputs[i]) - continue; - - /* Insert the RPF in the sorted RPFs array. */ - for (j = pipe->num_inputs++; j > 0; --j) { - if (rpf_zpos(vsp1, inputs[j-1]) <= rpf_zpos(vsp1, rpf)) - break; - inputs[j] = inputs[j-1]; - } - - inputs[j] = rpf; - } - - /* Setup the RPF input pipeline for every enabled input. */ - for (i = 0; i < pipe->bru->source_pad; ++i) { - struct vsp1_rwpf *rpf = inputs[i]; - - if (!rpf) { - bru->inputs[i].rpf = NULL; - continue; - } - - if (!rpf->entity.pipe) { - rpf->entity.pipe = pipe; - list_add_tail(&rpf->entity.list_pipe, &pipe->entities); - } - - bru->inputs[i].rpf = rpf; - rpf->bru_input = i; - rpf->entity.sink = pipe->bru; - rpf->entity.sink_pad = i; - - dev_dbg(vsp1->dev, "%s: connecting RPF.%u to %s:%u\n", - __func__, rpf->entity.index, BRU_NAME(pipe->bru), i); - - ret = vsp1_du_setup_rpf_pipe(vsp1, pipe, rpf, i); - if (ret < 0) - dev_err(vsp1->dev, - "%s: failed to setup RPF.%u\n", - __func__, rpf->entity.index); - } + vsp1_du_pipeline_setup_inputs(vsp1, pipe); vsp1_du_pipeline_configure(pipe); } EXPORT_SYMBOL_GPL(vsp1_du_atomic_flush); -- Regards, Laurent Pinchart From mboxrd@z Thu Jan 1 00:00:00 1970 From: Laurent Pinchart Subject: [PATCH v2.1 06/15] v4l: vsp1: Move DRM atomic commit pipeline setup to separate function Date: Fri, 6 Apr 2018 22:59:09 +0300 Message-ID: <20180406195909.12029-1-laurent.pinchart+renesas@ideasonboard.com> References: <20180405091840.30728-7-laurent.pinchart+renesas@ideasonboard.com> Mime-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Return-path: Received: from galahad.ideasonboard.com (galahad.ideasonboard.com [185.26.127.97]) by gabe.freedesktop.org (Postfix) with ESMTPS id 9529E6E1C0 for ; Fri, 6 Apr 2018 19:59:16 +0000 (UTC) In-Reply-To: <20180405091840.30728-7-laurent.pinchart+renesas@ideasonboard.com> List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" To: linux-media@vger.kernel.org Cc: linux-renesas-soc@vger.kernel.org, Kieran Bingham , dri-devel@lists.freedesktop.org List-Id: dri-devel@lists.freedesktop.org VGhlIERSTSBwaXBlbGluZSBzZXR1cCBjb2RlIHVzZWQgYXQgYXRvbWljIGNvbW1pdCB0aW1lIGlz IHNpbWlsYXIgdG8gdGhlCnNldHVwIGNvZGUgdXNlZCB3aGVuIGVuYWJsaW5nIHRoZSBwaXBlbGlu ZS4gTW92ZSBpdCB0byBhIHNlcGFyYXRlCmZ1bmN0aW9uIGluIG9yZGVyIHRvIHNoYXJlIGl0LgoK U2lnbmVkLW9mZi1ieTogTGF1cmVudCBQaW5jaGFydCA8bGF1cmVudC5waW5jaGFydCtyZW5lc2Fz QGlkZWFzb25ib2FyZC5jb20+ClJldmlld2VkLWJ5OiBLaWVyYW4gQmluZ2hhbSA8a2llcmFuLmJp bmdoYW0rcmVuZXNhc0BpZGVhc29uYm9hcmQuY29tPgotLS0KQ2hhbmdlcyBzaW5jZSB2MjoKCi0g UmVuYW1lIHZzcDFfZHVfcGlwZWxpbmVfc2V0dXBfaW5wdXQoKSB0bwogIHZzcDFfZHVfcGlwZWxp bmVfc2V0dXBfaW5wdXRzKCkKLS0tCiBkcml2ZXJzL21lZGlhL3BsYXRmb3JtL3ZzcDEvdnNwMV9k cm0uYyB8IDM0NyArKysrKysrKysrKysrKysrKy0tLS0tLS0tLS0tLS0tLS0KIDEgZmlsZSBjaGFu Z2VkLCAxODAgaW5zZXJ0aW9ucygrKSwgMTY3IGRlbGV0aW9ucygtKQoKZGlmZiAtLWdpdCBhL2Ry aXZlcnMvbWVkaWEvcGxhdGZvcm0vdnNwMS92c3AxX2RybS5jIGIvZHJpdmVycy9tZWRpYS9wbGF0 Zm9ybS92c3AxL3ZzcDFfZHJtLmMKaW5kZXggOWEwNDNhOTE1YzBiLi5kOTkyNzhmNDViZDggMTAw NjQ0Ci0tLSBhL2RyaXZlcnMvbWVkaWEvcGxhdGZvcm0vdnNwMS92c3AxX2RybS5jCisrKyBiL2Ry aXZlcnMvbWVkaWEvcGxhdGZvcm0vdnNwMS92c3AxX2RybS5jCkBAIC00Niw2ICs0NiwxODUgQEAg c3RhdGljIHZvaWQgdnNwMV9kdV9waXBlbGluZV9mcmFtZV9lbmQoc3RydWN0IHZzcDFfcGlwZWxp bmUgKnBpcGUsCiAgKiBQaXBlbGluZSBDb25maWd1cmF0aW9uCiAgKi8KIAorLyogU2V0dXAgb25l IFJQRiBhbmQgdGhlIGNvbm5lY3RlZCBCUlUgc2luayBwYWQuICovCitzdGF0aWMgaW50IHZzcDFf ZHVfcGlwZWxpbmVfc2V0dXBfcnBmKHN0cnVjdCB2c3AxX2RldmljZSAqdnNwMSwKKwkJCQkgICAg ICBzdHJ1Y3QgdnNwMV9waXBlbGluZSAqcGlwZSwKKwkJCQkgICAgICBzdHJ1Y3QgdnNwMV9yd3Bm ICpycGYsCisJCQkJICAgICAgdW5zaWduZWQgaW50IGJydV9pbnB1dCkKK3sKKwlzdHJ1Y3QgdjRs Ml9zdWJkZXZfc2VsZWN0aW9uIHNlbDsKKwlzdHJ1Y3QgdjRsMl9zdWJkZXZfZm9ybWF0IGZvcm1h dDsKKwljb25zdCBzdHJ1Y3QgdjRsMl9yZWN0ICpjcm9wOworCWludCByZXQ7CisKKwkvKgorCSAq IENvbmZpZ3VyZSB0aGUgZm9ybWF0IG9uIHRoZSBSUEYgc2luayBwYWQgYW5kIHByb3BhZ2F0ZSBp dCB1cCB0byB0aGUKKwkgKiBCUlUgc2luayBwYWQuCisJICovCisJY3JvcCA9ICZ2c3AxLT5kcm0t PmlucHV0c1tycGYtPmVudGl0eS5pbmRleF0uY3JvcDsKKworCW1lbXNldCgmZm9ybWF0LCAwLCBz aXplb2YoZm9ybWF0KSk7CisJZm9ybWF0LndoaWNoID0gVjRMMl9TVUJERVZfRk9STUFUX0FDVElW RTsKKwlmb3JtYXQucGFkID0gUldQRl9QQURfU0lOSzsKKwlmb3JtYXQuZm9ybWF0LndpZHRoID0g Y3JvcC0+d2lkdGggKyBjcm9wLT5sZWZ0OworCWZvcm1hdC5mb3JtYXQuaGVpZ2h0ID0gY3JvcC0+ aGVpZ2h0ICsgY3JvcC0+dG9wOworCWZvcm1hdC5mb3JtYXQuY29kZSA9IHJwZi0+Zm10aW5mby0+ bWJ1czsKKwlmb3JtYXQuZm9ybWF0LmZpZWxkID0gVjRMMl9GSUVMRF9OT05FOworCisJcmV0ID0g djRsMl9zdWJkZXZfY2FsbCgmcnBmLT5lbnRpdHkuc3ViZGV2LCBwYWQsIHNldF9mbXQsIE5VTEws CisJCQkgICAgICAgJmZvcm1hdCk7CisJaWYgKHJldCA8IDApCisJCXJldHVybiByZXQ7CisKKwlk ZXZfZGJnKHZzcDEtPmRldiwKKwkJIiVzOiBzZXQgZm9ybWF0ICV1eCV1ICgleCkgb24gUlBGJXUg c2lua1xuIiwKKwkJX19mdW5jX18sIGZvcm1hdC5mb3JtYXQud2lkdGgsIGZvcm1hdC5mb3JtYXQu aGVpZ2h0LAorCQlmb3JtYXQuZm9ybWF0LmNvZGUsIHJwZi0+ZW50aXR5LmluZGV4KTsKKworCW1l bXNldCgmc2VsLCAwLCBzaXplb2Yoc2VsKSk7CisJc2VsLndoaWNoID0gVjRMMl9TVUJERVZfRk9S TUFUX0FDVElWRTsKKwlzZWwucGFkID0gUldQRl9QQURfU0lOSzsKKwlzZWwudGFyZ2V0ID0gVjRM Ml9TRUxfVEdUX0NST1A7CisJc2VsLnIgPSAqY3JvcDsKKworCXJldCA9IHY0bDJfc3ViZGV2X2Nh bGwoJnJwZi0+ZW50aXR5LnN1YmRldiwgcGFkLCBzZXRfc2VsZWN0aW9uLCBOVUxMLAorCQkJICAg ICAgICZzZWwpOworCWlmIChyZXQgPCAwKQorCQlyZXR1cm4gcmV0OworCisJZGV2X2RiZyh2c3Ax LT5kZXYsCisJCSIlczogc2V0IHNlbGVjdGlvbiAoJXUsJXUpLyV1eCV1IG9uIFJQRiV1IHNpbmtc biIsCisJCV9fZnVuY19fLCBzZWwuci5sZWZ0LCBzZWwuci50b3AsIHNlbC5yLndpZHRoLCBzZWwu ci5oZWlnaHQsCisJCXJwZi0+ZW50aXR5LmluZGV4KTsKKworCS8qCisJICogUlBGIHNvdXJjZSwg aGFyZGNvZGUgdGhlIGZvcm1hdCB0byBBUkdCODg4OCB0byB0dXJuIG9uIGZvcm1hdAorCSAqIGNv bnZlcnNpb24gaWYgbmVlZGVkLgorCSAqLworCWZvcm1hdC5wYWQgPSBSV1BGX1BBRF9TT1VSQ0U7 CisKKwlyZXQgPSB2NGwyX3N1YmRldl9jYWxsKCZycGYtPmVudGl0eS5zdWJkZXYsIHBhZCwgZ2V0 X2ZtdCwgTlVMTCwKKwkJCSAgICAgICAmZm9ybWF0KTsKKwlpZiAocmV0IDwgMCkKKwkJcmV0dXJu IHJldDsKKworCWRldl9kYmcodnNwMS0+ZGV2LAorCQkiJXM6IGdvdCBmb3JtYXQgJXV4JXUgKCV4 KSBvbiBSUEYldSBzb3VyY2VcbiIsCisJCV9fZnVuY19fLCBmb3JtYXQuZm9ybWF0LndpZHRoLCBm b3JtYXQuZm9ybWF0LmhlaWdodCwKKwkJZm9ybWF0LmZvcm1hdC5jb2RlLCBycGYtPmVudGl0eS5p bmRleCk7CisKKwlmb3JtYXQuZm9ybWF0LmNvZGUgPSBNRURJQV9CVVNfRk1UX0FSR0I4ODg4XzFY MzI7CisKKwlyZXQgPSB2NGwyX3N1YmRldl9jYWxsKCZycGYtPmVudGl0eS5zdWJkZXYsIHBhZCwg c2V0X2ZtdCwgTlVMTCwKKwkJCSAgICAgICAmZm9ybWF0KTsKKwlpZiAocmV0IDwgMCkKKwkJcmV0 dXJuIHJldDsKKworCS8qIEJSVSBzaW5rLCBwcm9wYWdhdGUgdGhlIGZvcm1hdCBmcm9tIHRoZSBS UEYgc291cmNlLiAqLworCWZvcm1hdC5wYWQgPSBicnVfaW5wdXQ7CisKKwlyZXQgPSB2NGwyX3N1 YmRldl9jYWxsKCZwaXBlLT5icnUtPnN1YmRldiwgcGFkLCBzZXRfZm10LCBOVUxMLAorCQkJICAg ICAgICZmb3JtYXQpOworCWlmIChyZXQgPCAwKQorCQlyZXR1cm4gcmV0OworCisJZGV2X2RiZyh2 c3AxLT5kZXYsICIlczogc2V0IGZvcm1hdCAldXgldSAoJXgpIG9uICVzIHBhZCAldVxuIiwKKwkJ X19mdW5jX18sIGZvcm1hdC5mb3JtYXQud2lkdGgsIGZvcm1hdC5mb3JtYXQuaGVpZ2h0LAorCQlm b3JtYXQuZm9ybWF0LmNvZGUsIEJSVV9OQU1FKHBpcGUtPmJydSksIGZvcm1hdC5wYWQpOworCisJ c2VsLnBhZCA9IGJydV9pbnB1dDsKKwlzZWwudGFyZ2V0ID0gVjRMMl9TRUxfVEdUX0NPTVBPU0U7 CisJc2VsLnIgPSB2c3AxLT5kcm0tPmlucHV0c1tycGYtPmVudGl0eS5pbmRleF0uY29tcG9zZTsK KworCXJldCA9IHY0bDJfc3ViZGV2X2NhbGwoJnBpcGUtPmJydS0+c3ViZGV2LCBwYWQsIHNldF9z ZWxlY3Rpb24sIE5VTEwsCisJCQkgICAgICAgJnNlbCk7CisJaWYgKHJldCA8IDApCisJCXJldHVy biByZXQ7CisKKwlkZXZfZGJnKHZzcDEtPmRldiwgIiVzOiBzZXQgc2VsZWN0aW9uICgldSwldSkv JXV4JXUgb24gJXMgcGFkICV1XG4iLAorCQlfX2Z1bmNfXywgc2VsLnIubGVmdCwgc2VsLnIudG9w LCBzZWwuci53aWR0aCwgc2VsLnIuaGVpZ2h0LAorCQlCUlVfTkFNRShwaXBlLT5icnUpLCBzZWwu cGFkKTsKKworCXJldHVybiAwOworfQorCitzdGF0aWMgdW5zaWduZWQgaW50IHJwZl96cG9zKHN0 cnVjdCB2c3AxX2RldmljZSAqdnNwMSwgc3RydWN0IHZzcDFfcndwZiAqcnBmKQoreworCXJldHVy biB2c3AxLT5kcm0tPmlucHV0c1tycGYtPmVudGl0eS5pbmRleF0uenBvczsKK30KKworLyogU2V0 dXAgdGhlIGlucHV0IHNpZGUgb2YgdGhlIHBpcGVsaW5lIChSUEZzIGFuZCBCUlUgc2luayBwYWRz KS4gKi8KK3N0YXRpYyBpbnQgdnNwMV9kdV9waXBlbGluZV9zZXR1cF9pbnB1dHMoc3RydWN0IHZz cDFfZGV2aWNlICp2c3AxLAorCQkJCQkgc3RydWN0IHZzcDFfcGlwZWxpbmUgKnBpcGUpCit7CisJ c3RydWN0IHZzcDFfcndwZiAqaW5wdXRzW1ZTUDFfTUFYX1JQRl0gPSB7IE5VTEwsIH07CisJc3Ry dWN0IHZzcDFfYnJ1ICpicnUgPSB0b19icnUoJnBpcGUtPmJydS0+c3ViZGV2KTsKKwl1bnNpZ25l ZCBpbnQgaTsKKwlpbnQgcmV0OworCisJLyogQ291bnQgdGhlIG51bWJlciBvZiBlbmFibGVkIGlu cHV0cyBhbmQgc29ydCB0aGVtIGJ5IFotb3JkZXIuICovCisJcGlwZS0+bnVtX2lucHV0cyA9IDA7 CisKKwlmb3IgKGkgPSAwOyBpIDwgdnNwMS0+aW5mby0+cnBmX2NvdW50OyArK2kpIHsKKwkJc3Ry dWN0IHZzcDFfcndwZiAqcnBmID0gdnNwMS0+cnBmW2ldOworCQl1bnNpZ25lZCBpbnQgajsKKwor CQkvKgorCQkgKiBNYWtlIHN1cmUgd2UgZG9uJ3QgYWNjZXB0IG1vcmUgaW5wdXRzIHRoYW4gdGhl IGhhcmR3YXJlIGNhbgorCQkgKiBoYW5kbGUuIFRoaXMgaXMgYSB0ZW1wb3JhcnkgZml4IHRvIGF2 b2lkIGRpc3BsYXkgc3RhbGwsIHdlCisJCSAqIG5lZWQgdG8gaW5zdGVhZCBhbGxvY2F0ZSB0aGUg QlJVIG9yIEJSUyB0byBkaXNwbGF5IHBpcGVsaW5lcworCQkgKiBkeW5hbWljYWxseSBiYXNlZCBv biB0aGUgbnVtYmVyIG9mIHBsYW5lcyB0aGV5IGVhY2ggdXNlLgorCQkgKi8KKwkJaWYgKHBpcGUt Pm51bV9pbnB1dHMgPj0gcGlwZS0+YnJ1LT5zb3VyY2VfcGFkKQorCQkJcGlwZS0+aW5wdXRzW2ld ID0gTlVMTDsKKworCQlpZiAoIXBpcGUtPmlucHV0c1tpXSkKKwkJCWNvbnRpbnVlOworCisJCS8q IEluc2VydCB0aGUgUlBGIGluIHRoZSBzb3J0ZWQgUlBGcyBhcnJheS4gKi8KKwkJZm9yIChqID0g cGlwZS0+bnVtX2lucHV0cysrOyBqID4gMDsgLS1qKSB7CisJCQlpZiAocnBmX3pwb3ModnNwMSwg aW5wdXRzW2otMV0pIDw9IHJwZl96cG9zKHZzcDEsIHJwZikpCisJCQkJYnJlYWs7CisJCQlpbnB1 dHNbal0gPSBpbnB1dHNbai0xXTsKKwkJfQorCisJCWlucHV0c1tqXSA9IHJwZjsKKwl9CisKKwkv KiBTZXR1cCB0aGUgUlBGIGlucHV0IHBpcGVsaW5lIGZvciBldmVyeSBlbmFibGVkIGlucHV0LiAq LworCWZvciAoaSA9IDA7IGkgPCBwaXBlLT5icnUtPnNvdXJjZV9wYWQ7ICsraSkgeworCQlzdHJ1 Y3QgdnNwMV9yd3BmICpycGYgPSBpbnB1dHNbaV07CisKKwkJaWYgKCFycGYpIHsKKwkJCWJydS0+ aW5wdXRzW2ldLnJwZiA9IE5VTEw7CisJCQljb250aW51ZTsKKwkJfQorCisJCWlmICghcnBmLT5l bnRpdHkucGlwZSkgeworCQkJcnBmLT5lbnRpdHkucGlwZSA9IHBpcGU7CisJCQlsaXN0X2FkZF90 YWlsKCZycGYtPmVudGl0eS5saXN0X3BpcGUsICZwaXBlLT5lbnRpdGllcyk7CisJCX0KKworCQli cnUtPmlucHV0c1tpXS5ycGYgPSBycGY7CisJCXJwZi0+YnJ1X2lucHV0ID0gaTsKKwkJcnBmLT5l bnRpdHkuc2luayA9IHBpcGUtPmJydTsKKwkJcnBmLT5lbnRpdHkuc2lua19wYWQgPSBpOworCisJ CWRldl9kYmcodnNwMS0+ZGV2LCAiJXM6IGNvbm5lY3RpbmcgUlBGLiV1IHRvICVzOiV1XG4iLAor CQkJX19mdW5jX18sIHJwZi0+ZW50aXR5LmluZGV4LCBCUlVfTkFNRShwaXBlLT5icnUpLCBpKTsK KworCQlyZXQgPSB2c3AxX2R1X3BpcGVsaW5lX3NldHVwX3JwZih2c3AxLCBwaXBlLCBycGYsIGkp OworCQlpZiAocmV0IDwgMCkgeworCQkJZGV2X2Vycih2c3AxLT5kZXYsCisJCQkJIiVzOiBmYWls ZWQgdG8gc2V0dXAgUlBGLiV1XG4iLAorCQkJCV9fZnVuY19fLCBycGYtPmVudGl0eS5pbmRleCk7 CisJCQlyZXR1cm4gcmV0OworCQl9CisJfQorCisJcmV0dXJuIDA7Cit9CisKIC8qIENvbmZpZ3Vy ZSBhbGwgZW50aXRpZXMgaW4gdGhlIHBpcGVsaW5lLiAqLwogc3RhdGljIHZvaWQgdnNwMV9kdV9w aXBlbGluZV9jb25maWd1cmUoc3RydWN0IHZzcDFfcGlwZWxpbmUgKnBpcGUpCiB7CkBAIC0zOTYs MTExICs1NzUsNiBAQCBpbnQgdnNwMV9kdV9hdG9taWNfdXBkYXRlKHN0cnVjdCBkZXZpY2UgKmRl diwgdW5zaWduZWQgaW50IHBpcGVfaW5kZXgsCiB9CiBFWFBPUlRfU1lNQk9MX0dQTCh2c3AxX2R1 X2F0b21pY191cGRhdGUpOwogCi1zdGF0aWMgaW50IHZzcDFfZHVfc2V0dXBfcnBmX3BpcGUoc3Ry dWN0IHZzcDFfZGV2aWNlICp2c3AxLAotCQkJCSAgc3RydWN0IHZzcDFfcGlwZWxpbmUgKnBpcGUs Ci0JCQkJICBzdHJ1Y3QgdnNwMV9yd3BmICpycGYsIHVuc2lnbmVkIGludCBicnVfaW5wdXQpCi17 Ci0Jc3RydWN0IHY0bDJfc3ViZGV2X3NlbGVjdGlvbiBzZWw7Ci0Jc3RydWN0IHY0bDJfc3ViZGV2 X2Zvcm1hdCBmb3JtYXQ7Ci0JY29uc3Qgc3RydWN0IHY0bDJfcmVjdCAqY3JvcDsKLQlpbnQgcmV0 OwotCi0JLyoKLQkgKiBDb25maWd1cmUgdGhlIGZvcm1hdCBvbiB0aGUgUlBGIHNpbmsgcGFkIGFu ZCBwcm9wYWdhdGUgaXQgdXAgdG8gdGhlCi0JICogQlJVIHNpbmsgcGFkLgotCSAqLwotCWNyb3Ag PSAmdnNwMS0+ZHJtLT5pbnB1dHNbcnBmLT5lbnRpdHkuaW5kZXhdLmNyb3A7Ci0KLQltZW1zZXQo JmZvcm1hdCwgMCwgc2l6ZW9mKGZvcm1hdCkpOwotCWZvcm1hdC53aGljaCA9IFY0TDJfU1VCREVW X0ZPUk1BVF9BQ1RJVkU7Ci0JZm9ybWF0LnBhZCA9IFJXUEZfUEFEX1NJTks7Ci0JZm9ybWF0LmZv cm1hdC53aWR0aCA9IGNyb3AtPndpZHRoICsgY3JvcC0+bGVmdDsKLQlmb3JtYXQuZm9ybWF0Lmhl aWdodCA9IGNyb3AtPmhlaWdodCArIGNyb3AtPnRvcDsKLQlmb3JtYXQuZm9ybWF0LmNvZGUgPSBy cGYtPmZtdGluZm8tPm1idXM7Ci0JZm9ybWF0LmZvcm1hdC5maWVsZCA9IFY0TDJfRklFTERfTk9O RTsKLQotCXJldCA9IHY0bDJfc3ViZGV2X2NhbGwoJnJwZi0+ZW50aXR5LnN1YmRldiwgcGFkLCBz ZXRfZm10LCBOVUxMLAotCQkJICAgICAgICZmb3JtYXQpOwotCWlmIChyZXQgPCAwKQotCQlyZXR1 cm4gcmV0OwotCi0JZGV2X2RiZyh2c3AxLT5kZXYsCi0JCSIlczogc2V0IGZvcm1hdCAldXgldSAo JXgpIG9uIFJQRiV1IHNpbmtcbiIsCi0JCV9fZnVuY19fLCBmb3JtYXQuZm9ybWF0LndpZHRoLCBm b3JtYXQuZm9ybWF0LmhlaWdodCwKLQkJZm9ybWF0LmZvcm1hdC5jb2RlLCBycGYtPmVudGl0eS5p bmRleCk7Ci0KLQltZW1zZXQoJnNlbCwgMCwgc2l6ZW9mKHNlbCkpOwotCXNlbC53aGljaCA9IFY0 TDJfU1VCREVWX0ZPUk1BVF9BQ1RJVkU7Ci0Jc2VsLnBhZCA9IFJXUEZfUEFEX1NJTks7Ci0Jc2Vs LnRhcmdldCA9IFY0TDJfU0VMX1RHVF9DUk9QOwotCXNlbC5yID0gKmNyb3A7Ci0KLQlyZXQgPSB2 NGwyX3N1YmRldl9jYWxsKCZycGYtPmVudGl0eS5zdWJkZXYsIHBhZCwgc2V0X3NlbGVjdGlvbiwg TlVMTCwKLQkJCSAgICAgICAmc2VsKTsKLQlpZiAocmV0IDwgMCkKLQkJcmV0dXJuIHJldDsKLQot CWRldl9kYmcodnNwMS0+ZGV2LAotCQkiJXM6IHNldCBzZWxlY3Rpb24gKCV1LCV1KS8ldXgldSBv biBSUEYldSBzaW5rXG4iLAotCQlfX2Z1bmNfXywgc2VsLnIubGVmdCwgc2VsLnIudG9wLCBzZWwu ci53aWR0aCwgc2VsLnIuaGVpZ2h0LAotCQlycGYtPmVudGl0eS5pbmRleCk7Ci0KLQkvKgotCSAq IFJQRiBzb3VyY2UsIGhhcmRjb2RlIHRoZSBmb3JtYXQgdG8gQVJHQjg4ODggdG8gdHVybiBvbiBm b3JtYXQKLQkgKiBjb252ZXJzaW9uIGlmIG5lZWRlZC4KLQkgKi8KLQlmb3JtYXQucGFkID0gUldQ Rl9QQURfU09VUkNFOwotCi0JcmV0ID0gdjRsMl9zdWJkZXZfY2FsbCgmcnBmLT5lbnRpdHkuc3Vi ZGV2LCBwYWQsIGdldF9mbXQsIE5VTEwsCi0JCQkgICAgICAgJmZvcm1hdCk7Ci0JaWYgKHJldCA8 IDApCi0JCXJldHVybiByZXQ7Ci0KLQlkZXZfZGJnKHZzcDEtPmRldiwKLQkJIiVzOiBnb3QgZm9y bWF0ICV1eCV1ICgleCkgb24gUlBGJXUgc291cmNlXG4iLAotCQlfX2Z1bmNfXywgZm9ybWF0LmZv cm1hdC53aWR0aCwgZm9ybWF0LmZvcm1hdC5oZWlnaHQsCi0JCWZvcm1hdC5mb3JtYXQuY29kZSwg cnBmLT5lbnRpdHkuaW5kZXgpOwotCi0JZm9ybWF0LmZvcm1hdC5jb2RlID0gTUVESUFfQlVTX0ZN VF9BUkdCODg4OF8xWDMyOwotCi0JcmV0ID0gdjRsMl9zdWJkZXZfY2FsbCgmcnBmLT5lbnRpdHku c3ViZGV2LCBwYWQsIHNldF9mbXQsIE5VTEwsCi0JCQkgICAgICAgJmZvcm1hdCk7Ci0JaWYgKHJl dCA8IDApCi0JCXJldHVybiByZXQ7Ci0KLQkvKiBCUlUgc2luaywgcHJvcGFnYXRlIHRoZSBmb3Jt YXQgZnJvbSB0aGUgUlBGIHNvdXJjZS4gKi8KLQlmb3JtYXQucGFkID0gYnJ1X2lucHV0OwotCi0J cmV0ID0gdjRsMl9zdWJkZXZfY2FsbCgmcGlwZS0+YnJ1LT5zdWJkZXYsIHBhZCwgc2V0X2ZtdCwg TlVMTCwKLQkJCSAgICAgICAmZm9ybWF0KTsKLQlpZiAocmV0IDwgMCkKLQkJcmV0dXJuIHJldDsK LQotCWRldl9kYmcodnNwMS0+ZGV2LCAiJXM6IHNldCBmb3JtYXQgJXV4JXUgKCV4KSBvbiAlcyBw YWQgJXVcbiIsCi0JCV9fZnVuY19fLCBmb3JtYXQuZm9ybWF0LndpZHRoLCBmb3JtYXQuZm9ybWF0 LmhlaWdodCwKLQkJZm9ybWF0LmZvcm1hdC5jb2RlLCBCUlVfTkFNRShwaXBlLT5icnUpLCBmb3Jt YXQucGFkKTsKLQotCXNlbC5wYWQgPSBicnVfaW5wdXQ7Ci0Jc2VsLnRhcmdldCA9IFY0TDJfU0VM X1RHVF9DT01QT1NFOwotCXNlbC5yID0gdnNwMS0+ZHJtLT5pbnB1dHNbcnBmLT5lbnRpdHkuaW5k ZXhdLmNvbXBvc2U7Ci0KLQlyZXQgPSB2NGwyX3N1YmRldl9jYWxsKCZwaXBlLT5icnUtPnN1YmRl diwgcGFkLCBzZXRfc2VsZWN0aW9uLCBOVUxMLAotCQkJICAgICAgICZzZWwpOwotCWlmIChyZXQg PCAwKQotCQlyZXR1cm4gcmV0OwotCi0JZGV2X2RiZyh2c3AxLT5kZXYsICIlczogc2V0IHNlbGVj dGlvbiAoJXUsJXUpLyV1eCV1IG9uICVzIHBhZCAldVxuIiwKLQkJX19mdW5jX18sIHNlbC5yLmxl ZnQsIHNlbC5yLnRvcCwgc2VsLnIud2lkdGgsIHNlbC5yLmhlaWdodCwKLQkJQlJVX05BTUUocGlw ZS0+YnJ1KSwgc2VsLnBhZCk7Ci0KLQlyZXR1cm4gMDsKLX0KLQotc3RhdGljIHVuc2lnbmVkIGlu dCBycGZfenBvcyhzdHJ1Y3QgdnNwMV9kZXZpY2UgKnZzcDEsIHN0cnVjdCB2c3AxX3J3cGYgKnJw ZikKLXsKLQlyZXR1cm4gdnNwMS0+ZHJtLT5pbnB1dHNbcnBmLT5lbnRpdHkuaW5kZXhdLnpwb3M7 Ci19Ci0KIC8qKgogICogdnNwMV9kdV9hdG9taWNfZmx1c2ggLSBDb21taXQgYW4gYXRvbWljIHVw ZGF0ZQogICogQGRldjogdGhlIFZTUCBkZXZpY2UKQEAgLTUxMSw2OSArNTg1LDggQEAgdm9pZCB2 c3AxX2R1X2F0b21pY19mbHVzaChzdHJ1Y3QgZGV2aWNlICpkZXYsIHVuc2lnbmVkIGludCBwaXBl X2luZGV4KQogCXN0cnVjdCB2c3AxX2RldmljZSAqdnNwMSA9IGRldl9nZXRfZHJ2ZGF0YShkZXYp OwogCXN0cnVjdCB2c3AxX2RybV9waXBlbGluZSAqZHJtX3BpcGUgPSAmdnNwMS0+ZHJtLT5waXBl W3BpcGVfaW5kZXhdOwogCXN0cnVjdCB2c3AxX3BpcGVsaW5lICpwaXBlID0gJmRybV9waXBlLT5w aXBlOwotCXN0cnVjdCB2c3AxX3J3cGYgKmlucHV0c1tWU1AxX01BWF9SUEZdID0geyBOVUxMLCB9 OwotCXN0cnVjdCB2c3AxX2JydSAqYnJ1ID0gdG9fYnJ1KCZwaXBlLT5icnUtPnN1YmRldik7Ci0J dW5zaWduZWQgaW50IGk7Ci0JaW50IHJldDsKLQotCS8qIENvdW50IHRoZSBudW1iZXIgb2YgZW5h YmxlZCBpbnB1dHMgYW5kIHNvcnQgdGhlbSBieSBaLW9yZGVyLiAqLwotCXBpcGUtPm51bV9pbnB1 dHMgPSAwOwotCi0JZm9yIChpID0gMDsgaSA8IHZzcDEtPmluZm8tPnJwZl9jb3VudDsgKytpKSB7 Ci0JCXN0cnVjdCB2c3AxX3J3cGYgKnJwZiA9IHZzcDEtPnJwZltpXTsKLQkJdW5zaWduZWQgaW50 IGo7Ci0KLQkJLyoKLQkJICogTWFrZSBzdXJlIHdlIGRvbid0IGFjY2VwdCBtb3JlIGlucHV0cyB0 aGFuIHRoZSBoYXJkd2FyZSBjYW4KLQkJICogaGFuZGxlLiBUaGlzIGlzIGEgdGVtcG9yYXJ5IGZp eCB0byBhdm9pZCBkaXNwbGF5IHN0YWxsLCB3ZQotCQkgKiBuZWVkIHRvIGluc3RlYWQgYWxsb2Nh dGUgdGhlIEJSVSBvciBCUlMgdG8gZGlzcGxheSBwaXBlbGluZXMKLQkJICogZHluYW1pY2FsbHkg YmFzZWQgb24gdGhlIG51bWJlciBvZiBwbGFuZXMgdGhleSBlYWNoIHVzZS4KLQkJICovCi0JCWlm IChwaXBlLT5udW1faW5wdXRzID49IHBpcGUtPmJydS0+c291cmNlX3BhZCkKLQkJCXBpcGUtPmlu cHV0c1tpXSA9IE5VTEw7Ci0KLQkJaWYgKCFwaXBlLT5pbnB1dHNbaV0pCi0JCQljb250aW51ZTsK LQotCQkvKiBJbnNlcnQgdGhlIFJQRiBpbiB0aGUgc29ydGVkIFJQRnMgYXJyYXkuICovCi0JCWZv ciAoaiA9IHBpcGUtPm51bV9pbnB1dHMrKzsgaiA+IDA7IC0taikgewotCQkJaWYgKHJwZl96cG9z KHZzcDEsIGlucHV0c1tqLTFdKSA8PSBycGZfenBvcyh2c3AxLCBycGYpKQotCQkJCWJyZWFrOwot CQkJaW5wdXRzW2pdID0gaW5wdXRzW2otMV07Ci0JCX0KLQotCQlpbnB1dHNbal0gPSBycGY7Ci0J fQotCi0JLyogU2V0dXAgdGhlIFJQRiBpbnB1dCBwaXBlbGluZSBmb3IgZXZlcnkgZW5hYmxlZCBp bnB1dC4gKi8KLQlmb3IgKGkgPSAwOyBpIDwgcGlwZS0+YnJ1LT5zb3VyY2VfcGFkOyArK2kpIHsK LQkJc3RydWN0IHZzcDFfcndwZiAqcnBmID0gaW5wdXRzW2ldOwotCi0JCWlmICghcnBmKSB7Ci0J CQlicnUtPmlucHV0c1tpXS5ycGYgPSBOVUxMOwotCQkJY29udGludWU7Ci0JCX0KLQotCQlpZiAo IXJwZi0+ZW50aXR5LnBpcGUpIHsKLQkJCXJwZi0+ZW50aXR5LnBpcGUgPSBwaXBlOwotCQkJbGlz dF9hZGRfdGFpbCgmcnBmLT5lbnRpdHkubGlzdF9waXBlLCAmcGlwZS0+ZW50aXRpZXMpOwotCQl9 Ci0KLQkJYnJ1LT5pbnB1dHNbaV0ucnBmID0gcnBmOwotCQlycGYtPmJydV9pbnB1dCA9IGk7Ci0J CXJwZi0+ZW50aXR5LnNpbmsgPSBwaXBlLT5icnU7Ci0JCXJwZi0+ZW50aXR5LnNpbmtfcGFkID0g aTsKLQotCQlkZXZfZGJnKHZzcDEtPmRldiwgIiVzOiBjb25uZWN0aW5nIFJQRi4ldSB0byAlczol dVxuIiwKLQkJCV9fZnVuY19fLCBycGYtPmVudGl0eS5pbmRleCwgQlJVX05BTUUocGlwZS0+YnJ1 KSwgaSk7Ci0KLQkJcmV0ID0gdnNwMV9kdV9zZXR1cF9ycGZfcGlwZSh2c3AxLCBwaXBlLCBycGYs IGkpOwotCQlpZiAocmV0IDwgMCkKLQkJCWRldl9lcnIodnNwMS0+ZGV2LAotCQkJCSIlczogZmFp bGVkIHRvIHNldHVwIFJQRi4ldVxuIiwKLQkJCQlfX2Z1bmNfXywgcnBmLT5lbnRpdHkuaW5kZXgp OwotCX0KIAorCXZzcDFfZHVfcGlwZWxpbmVfc2V0dXBfaW5wdXRzKHZzcDEsIHBpcGUpOwogCXZz cDFfZHVfcGlwZWxpbmVfY29uZmlndXJlKHBpcGUpOwogfQogRVhQT1JUX1NZTUJPTF9HUEwodnNw MV9kdV9hdG9taWNfZmx1c2gpOwotLSAKUmVnYXJkcywKCkxhdXJlbnQgUGluY2hhcnQKCl9fX19f X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fCmRyaS1kZXZlbCBtYWls aW5nIGxpc3QKZHJpLWRldmVsQGxpc3RzLmZyZWVkZXNrdG9wLm9yZwpodHRwczovL2xpc3RzLmZy ZWVkZXNrdG9wLm9yZy9tYWlsbWFuL2xpc3RpbmZvL2RyaS1kZXZlbAo=