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=-9.1 required=3.0 tests=DKIMWL_WL_HIGH,DKIM_SIGNED, DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH,MAILING_LIST_MULTI, SIGNED_OFF_BY,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT 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 A9B75C10F0E for ; Thu, 18 Apr 2019 12:42:44 +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 72C162183E for ; Thu, 18 Apr 2019 12:42:44 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="sMY9EMCr" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 72C162183E Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=bootlin.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+infradead-linux-arm-kernel=archiver.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=24hnpbtykSDgLrNAcHUFz0evT71wyAumdHWMvefEHM4=; b=sMY9EMCrEWA3PU 2psLjH0/x0yzhZYfsbjmeRlHERttqaf59I6ph89cU1IhfAWzV3mcoSn7AJ2L7aoNbhzOpWsOX4Itv hyZGTvQoZ5K9XCx284MyGV+nhzaK7aczVOCCHju546hf+665BnBS/71o1KWFHNi07tWeg0pLGW6TZ QLWN0PI2BSb5ipWgSixDFhBcKqXuru8SkRrdYIGpVL2lj+wPSt2YYa/XkGJ5Qo4u7Nkum5AoD17rF MqVLJ55foz8hVDpKg7i8332GRlgYLtHu0tP9yJ6+Aa99QSOOutA0TUZRFg7Zk8LmlcFo/JtQ9TL2c T6JB4yxRSYHdwbJkeQ1Q==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1hH6N9-0000AB-TI; Thu, 18 Apr 2019 12:42:35 +0000 Received: from relay9-d.mail.gandi.net ([217.70.183.199]) by bombadil.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1hH6Mu-0008H8-H0 for linux-arm-kernel@lists.infradead.org; Thu, 18 Apr 2019 12:42:23 +0000 X-Originating-IP: 90.88.160.238 Received: from localhost (aaubervilliers-681-1-42-238.w90-88.abo.wanadoo.fr [90.88.160.238]) (Authenticated sender: maxime.ripard@bootlin.com) by relay9-d.mail.gandi.net (Postfix) with ESMTPSA id 65844FF803; Thu, 18 Apr 2019 12:42:06 +0000 (UTC) From: Maxime Ripard To: Maarten Lankhorst , Sean Paul , Maxime Ripard , Daniel Vetter , David Airlie Subject: [PATCH v3 1/6] drm/modes: Rewrite the command line parser Date: Thu, 18 Apr 2019 14:41:54 +0200 Message-Id: <500140e56478f2b91c30ff7389a4444b427b1dfd.1555591281.git-series.maxime.ripard@bootlin.com> X-Mailer: git-send-email 2.21.0 In-Reply-To: References: MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20190418_054221_431749_5700C4B5 X-CRM114-Status: GOOD ( 18.45 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: eben@raspberrypi.org, dri-devel@lists.freedesktop.org, Paul Kocialkowski , Eric Anholt , noralf@tronnes.org, Thomas Petazzoni , Maxime Ripard , linux-arm-kernel@lists.infradead.org Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+infradead-linux-arm-kernel=archiver.kernel.org@lists.infradead.org From: Maxime Ripard Rewrite the command line parser in order to get away from the state machine parsing the video mode lines. Hopefully, this will allow to extend it more easily to support named modes and / or properties set directly on the command line. Signed-off-by: Maxime Ripard --- drivers/gpu/drm/drm_modes.c | 305 +++++++++++++++++++++++-------------- 1 file changed, 190 insertions(+), 115 deletions(-) diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c index 56f92a0bba62..3f89198f0891 100644 --- a/drivers/gpu/drm/drm_modes.c +++ b/drivers/gpu/drm/drm_modes.c @@ -30,6 +30,7 @@ * authorization from the copyright holder(s) and author(s). */ +#include #include #include #include @@ -1405,6 +1406,131 @@ void drm_connector_list_update(struct drm_connector *connector) } EXPORT_SYMBOL(drm_connector_list_update); +static int drm_mode_parse_cmdline_bpp(const char *str, char **end_ptr, + struct drm_cmdline_mode *mode) +{ + if (str[0] != '-') + return -EINVAL; + + mode->bpp = simple_strtol(str + 1, end_ptr, 10); + mode->bpp_specified = true; + + return 0; +} + +static int drm_mode_parse_cmdline_refresh(const char *str, char **end_ptr, + struct drm_cmdline_mode *mode) +{ + if (str[0] != '@') + return -EINVAL; + + mode->refresh = simple_strtol(str + 1, end_ptr, 10); + mode->refresh_specified = true; + + return 0; +} + +static int drm_mode_parse_cmdline_extra(const char *str, int length, + struct drm_connector *connector, + struct drm_cmdline_mode *mode) +{ + int i; + + for (i = 0; i < length; i++) { + switch (str[i]) { + case 'i': + mode->interlace = true; + break; + case 'm': + mode->margins = true; + break; + case 'D': + if (mode->force != DRM_FORCE_UNSPECIFIED) + return -EINVAL; + + if ((connector->connector_type != DRM_MODE_CONNECTOR_DVII) && + (connector->connector_type != DRM_MODE_CONNECTOR_HDMIB)) + mode->force = DRM_FORCE_ON; + else + mode->force = DRM_FORCE_ON_DIGITAL; + break; + case 'd': + if (mode->force != DRM_FORCE_UNSPECIFIED) + return -EINVAL; + + mode->force = DRM_FORCE_OFF; + break; + case 'e': + if (mode->force != DRM_FORCE_UNSPECIFIED) + return -EINVAL; + + mode->force = DRM_FORCE_ON; + break; + default: + return -EINVAL; + } + } + + return 0; +} + +static int drm_mode_parse_cmdline_res_mode(const char *str, unsigned int length, + bool extras, + struct drm_connector *connector, + struct drm_cmdline_mode *mode) +{ + bool rb = false, cvt = false; + int xres = 0, yres = 0; + int remaining, i; + char *end_ptr; + + xres = simple_strtol(str, &end_ptr, 10); + + if (end_ptr[0] != 'x') + return -EINVAL; + end_ptr++; + + yres = simple_strtol(end_ptr, &end_ptr, 10); + + remaining = length - (end_ptr - str); + if (remaining < 0) + return -EINVAL; + + for (i = 0; i < remaining; i++) { + switch (end_ptr[i]) { + case 'M': + cvt = true; + break; + case 'R': + rb = true; + break; + default: + /* + * Try to pass that to our extras parsing + * function to handle the case where the + * extras are directly after the resolution + */ + if (extras) { + int ret = drm_mode_parse_cmdline_extra(end_ptr + i, + 1, + connector, + mode); + if (ret) + return ret; + } else { + return -EINVAL; + } + } + } + + mode->xres = xres; + mode->yres = yres; + mode->cvt = cvt; + mode->rb = rb; + + return 0; +} + /** * drm_mode_parse_command_line_for_connector - parse command line modeline for connector * @mode_option: optional per connector mode option @@ -1431,13 +1557,12 @@ bool drm_mode_parse_command_line_for_connector(const char *mode_option, struct drm_cmdline_mode *mode) { const char *name; - unsigned int namelen; - bool res_specified = false, bpp_specified = false, refresh_specified = false; - unsigned int xres = 0, yres = 0, bpp = 32, refresh = 0; - bool yres_specified = false, cvt = false, rb = false; - bool interlace = false, margins = false, was_digit = false; - int i; - enum drm_connector_force force = DRM_FORCE_UNSPECIFIED; + bool parse_extras = false; + unsigned int bpp_off = 0, refresh_off = 0; + unsigned int mode_end = 0; + char *bpp_ptr = NULL, *refresh_ptr = NULL, *extra_ptr = NULL; + char *bpp_end_ptr = NULL, *refresh_end_ptr = NULL; + int ret; #ifdef CONFIG_FB if (!mode_option) @@ -1450,127 +1575,77 @@ bool drm_mode_parse_command_line_for_connector(const char *mode_option, } name = mode_option; - namelen = strlen(name); - for (i = namelen-1; i >= 0; i--) { - switch (name[i]) { - case '@': - if (!refresh_specified && !bpp_specified && - !yres_specified && !cvt && !rb && was_digit) { - refresh = simple_strtol(&name[i+1], NULL, 10); - refresh_specified = true; - was_digit = false; - } else - goto done; - break; - case '-': - if (!bpp_specified && !yres_specified && !cvt && - !rb && was_digit) { - bpp = simple_strtol(&name[i+1], NULL, 10); - bpp_specified = true; - was_digit = false; - } else - goto done; - break; - case 'x': - if (!yres_specified && was_digit) { - yres = simple_strtol(&name[i+1], NULL, 10); - yres_specified = true; - was_digit = false; - } else - goto done; - break; - case '0' ... '9': - was_digit = true; - break; - case 'M': - if (yres_specified || cvt || was_digit) - goto done; - cvt = true; - break; - case 'R': - if (yres_specified || cvt || rb || was_digit) - goto done; - rb = true; - break; - case 'm': - if (cvt || yres_specified || was_digit) - goto done; - margins = true; - break; - case 'i': - if (cvt || yres_specified || was_digit) - goto done; - interlace = true; - break; - case 'e': - if (yres_specified || bpp_specified || refresh_specified || - was_digit || (force != DRM_FORCE_UNSPECIFIED)) - goto done; - force = DRM_FORCE_ON; - break; - case 'D': - if (yres_specified || bpp_specified || refresh_specified || - was_digit || (force != DRM_FORCE_UNSPECIFIED)) - goto done; + if (!isdigit(name[0])) + return false; - if ((connector->connector_type != DRM_MODE_CONNECTOR_DVII) && - (connector->connector_type != DRM_MODE_CONNECTOR_HDMIB)) - force = DRM_FORCE_ON; - else - force = DRM_FORCE_ON_DIGITAL; - break; - case 'd': - if (yres_specified || bpp_specified || refresh_specified || - was_digit || (force != DRM_FORCE_UNSPECIFIED)) - goto done; + /* Try to locate the bpp and refresh specifiers, if any */ + bpp_ptr = strchr(name, '-'); + if (bpp_ptr) { + bpp_off = bpp_ptr - name; + mode->bpp_specified = true; + } - force = DRM_FORCE_OFF; - break; - default: - goto done; - } + refresh_ptr = strchr(name, '@'); + if (refresh_ptr) { + refresh_off = refresh_ptr - name; + mode->refresh_specified = true; } - if (i < 0 && yres_specified) { - char *ch; - xres = simple_strtol(name, &ch, 10); - if ((ch != NULL) && (*ch == 'x')) - res_specified = true; - else - i = ch - name; - } else if (!yres_specified && was_digit) { - /* catch mode that begins with digits but has no 'x' */ - i = 0; + /* Locate the end of the name / resolution, and parse it */ + if (bpp_ptr && refresh_ptr) { + mode_end = min(bpp_off, refresh_off); + } else if (bpp_ptr) { + mode_end = bpp_off; + } else if (refresh_ptr) { + mode_end = refresh_off; + } else { + mode_end = strlen(name); + parse_extras = true; } -done: - if (i >= 0) { - pr_warn("[drm] parse error at position %i in video mode '%s'\n", - i, name); - mode->specified = false; + + ret = drm_mode_parse_cmdline_res_mode(name, mode_end, + parse_extras, + connector, + mode); + if (ret) return false; - } + mode->specified = true; - if (res_specified) { - mode->specified = true; - mode->xres = xres; - mode->yres = yres; + if (bpp_ptr) { + ret = drm_mode_parse_cmdline_bpp(bpp_ptr, &bpp_end_ptr, mode); + if (ret) + return false; } - if (refresh_specified) { - mode->refresh_specified = true; - mode->refresh = refresh; + if (refresh_ptr) { + ret = drm_mode_parse_cmdline_refresh(refresh_ptr, + &refresh_end_ptr, mode); + if (ret) + return false; } - if (bpp_specified) { - mode->bpp_specified = true; - mode->bpp = bpp; + /* + * Locate the end of the bpp / refresh, and parse the extras + * if relevant + */ + if (bpp_ptr && refresh_ptr) + extra_ptr = max(bpp_end_ptr, refresh_end_ptr); + else if (bpp_ptr) + extra_ptr = bpp_end_ptr; + else if (refresh_ptr) + extra_ptr = refresh_end_ptr; + + if (extra_ptr) { + int remaining = strlen(name) - (extra_ptr - name); + + /* + * We still have characters to process, while + * we shouldn't have any + */ + if (remaining > 0) + return false; } - mode->rb = rb; - mode->cvt = cvt; - mode->interlace = interlace; - mode->margins = margins; - mode->force = force; return true; } -- git-series 0.9.1 _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel From mboxrd@z Thu Jan 1 00:00:00 1970 From: Maxime Ripard Subject: [PATCH v3 1/6] drm/modes: Rewrite the command line parser Date: Thu, 18 Apr 2019 14:41:54 +0200 Message-ID: <500140e56478f2b91c30ff7389a4444b427b1dfd.1555591281.git-series.maxime.ripard@bootlin.com> References: Mime-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Return-path: Received: from relay9-d.mail.gandi.net (relay9-d.mail.gandi.net [217.70.183.199]) by gabe.freedesktop.org (Postfix) with ESMTPS id 608BA6E123 for ; Thu, 18 Apr 2019 12:42:11 +0000 (UTC) In-Reply-To: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" To: Maarten Lankhorst , Sean Paul , Maxime Ripard , Daniel Vetter , David Airlie Cc: eben@raspberrypi.org, dri-devel@lists.freedesktop.org, Paul Kocialkowski , Thomas Petazzoni , Maxime Ripard , linux-arm-kernel@lists.infradead.org List-Id: dri-devel@lists.freedesktop.org RnJvbTogTWF4aW1lIFJpcGFyZCA8bWF4aW1lLnJpcGFyZEBmcmVlLWVsZWN0cm9ucy5jb20+CgpS ZXdyaXRlIHRoZSBjb21tYW5kIGxpbmUgcGFyc2VyIGluIG9yZGVyIHRvIGdldCBhd2F5IGZyb20g dGhlIHN0YXRlIG1hY2hpbmUKcGFyc2luZyB0aGUgdmlkZW8gbW9kZSBsaW5lcy4KCkhvcGVmdWxs eSwgdGhpcyB3aWxsIGFsbG93IHRvIGV4dGVuZCBpdCBtb3JlIGVhc2lseSB0byBzdXBwb3J0IG5h bWVkIG1vZGVzCmFuZCAvIG9yIHByb3BlcnRpZXMgc2V0IGRpcmVjdGx5IG9uIHRoZSBjb21tYW5k IGxpbmUuCgpTaWduZWQtb2ZmLWJ5OiBNYXhpbWUgUmlwYXJkIDxtYXhpbWUucmlwYXJkQGZyZWUt ZWxlY3Ryb25zLmNvbT4KLS0tCiBkcml2ZXJzL2dwdS9kcm0vZHJtX21vZGVzLmMgfCAzMDUgKysr KysrKysrKysrKysrKysrKysrKystLS0tLS0tLS0tLS0tLQogMSBmaWxlIGNoYW5nZWQsIDE5MCBp bnNlcnRpb25zKCspLCAxMTUgZGVsZXRpb25zKC0pCgpkaWZmIC0tZ2l0IGEvZHJpdmVycy9ncHUv ZHJtL2RybV9tb2Rlcy5jIGIvZHJpdmVycy9ncHUvZHJtL2RybV9tb2Rlcy5jCmluZGV4IDU2Zjky YTBiYmE2Mi4uM2Y4OTE5OGYwODkxIDEwMDY0NAotLS0gYS9kcml2ZXJzL2dwdS9kcm0vZHJtX21v ZGVzLmMKKysrIGIvZHJpdmVycy9ncHUvZHJtL2RybV9tb2Rlcy5jCkBAIC0zMCw2ICszMCw3IEBA CiAgKiBhdXRob3JpemF0aW9uIGZyb20gdGhlIGNvcHlyaWdodCBob2xkZXIocykgYW5kIGF1dGhv cihzKS4KICAqLwogCisjaW5jbHVkZSA8bGludXgvY3R5cGUuaD4KICNpbmNsdWRlIDxsaW51eC9s aXN0Lmg+CiAjaW5jbHVkZSA8bGludXgvbGlzdF9zb3J0Lmg+CiAjaW5jbHVkZSA8bGludXgvZXhw b3J0Lmg+CkBAIC0xNDA1LDYgKzE0MDYsMTMxIEBAIHZvaWQgZHJtX2Nvbm5lY3Rvcl9saXN0X3Vw ZGF0ZShzdHJ1Y3QgZHJtX2Nvbm5lY3RvciAqY29ubmVjdG9yKQogfQogRVhQT1JUX1NZTUJPTChk cm1fY29ubmVjdG9yX2xpc3RfdXBkYXRlKTsKIAorc3RhdGljIGludCBkcm1fbW9kZV9wYXJzZV9j bWRsaW5lX2JwcChjb25zdCBjaGFyICpzdHIsIGNoYXIgKiplbmRfcHRyLAorCQkJCSAgICAgIHN0 cnVjdCBkcm1fY21kbGluZV9tb2RlICptb2RlKQoreworCWlmIChzdHJbMF0gIT0gJy0nKQorCQly ZXR1cm4gLUVJTlZBTDsKKworCW1vZGUtPmJwcCA9IHNpbXBsZV9zdHJ0b2woc3RyICsgMSwgZW5k X3B0ciwgMTApOworCW1vZGUtPmJwcF9zcGVjaWZpZWQgPSB0cnVlOworCisJcmV0dXJuIDA7Cit9 CisKK3N0YXRpYyBpbnQgZHJtX21vZGVfcGFyc2VfY21kbGluZV9yZWZyZXNoKGNvbnN0IGNoYXIg KnN0ciwgY2hhciAqKmVuZF9wdHIsCisJCQkJCSAgc3RydWN0IGRybV9jbWRsaW5lX21vZGUgKm1v ZGUpCit7CisJaWYgKHN0clswXSAhPSAnQCcpCisJCXJldHVybiAtRUlOVkFMOworCisJbW9kZS0+ cmVmcmVzaCA9IHNpbXBsZV9zdHJ0b2woc3RyICsgMSwgZW5kX3B0ciwgMTApOworCW1vZGUtPnJl ZnJlc2hfc3BlY2lmaWVkID0gdHJ1ZTsKKworCXJldHVybiAwOworfQorCitzdGF0aWMgaW50IGRy bV9tb2RlX3BhcnNlX2NtZGxpbmVfZXh0cmEoY29uc3QgY2hhciAqc3RyLCBpbnQgbGVuZ3RoLAor CQkJCQlzdHJ1Y3QgZHJtX2Nvbm5lY3RvciAqY29ubmVjdG9yLAorCQkJCQlzdHJ1Y3QgZHJtX2Nt ZGxpbmVfbW9kZSAqbW9kZSkKK3sKKwlpbnQgaTsKKworCWZvciAoaSA9IDA7IGkgPCBsZW5ndGg7 IGkrKykgeworCQlzd2l0Y2ggKHN0cltpXSkgeworCQljYXNlICdpJzoKKwkJCW1vZGUtPmludGVy bGFjZSA9IHRydWU7CisJCQlicmVhazsKKwkJY2FzZSAnbSc6CisJCQltb2RlLT5tYXJnaW5zID0g dHJ1ZTsKKwkJCWJyZWFrOworCQljYXNlICdEJzoKKwkJCWlmIChtb2RlLT5mb3JjZSAhPSBEUk1f Rk9SQ0VfVU5TUEVDSUZJRUQpCisJCQkJcmV0dXJuIC1FSU5WQUw7CisKKwkJCWlmICgoY29ubmVj dG9yLT5jb25uZWN0b3JfdHlwZSAhPSBEUk1fTU9ERV9DT05ORUNUT1JfRFZJSSkgJiYKKwkJCSAg ICAoY29ubmVjdG9yLT5jb25uZWN0b3JfdHlwZSAhPSBEUk1fTU9ERV9DT05ORUNUT1JfSERNSUIp KQorCQkJCW1vZGUtPmZvcmNlID0gRFJNX0ZPUkNFX09OOworCQkJZWxzZQorCQkJCW1vZGUtPmZv cmNlID0gRFJNX0ZPUkNFX09OX0RJR0lUQUw7CisJCQlicmVhazsKKwkJY2FzZSAnZCc6CisJCQlp ZiAobW9kZS0+Zm9yY2UgIT0gRFJNX0ZPUkNFX1VOU1BFQ0lGSUVEKQorCQkJCXJldHVybiAtRUlO VkFMOworCisJCQltb2RlLT5mb3JjZSA9IERSTV9GT1JDRV9PRkY7CisJCQlicmVhazsKKwkJY2Fz ZSAnZSc6CisJCQlpZiAobW9kZS0+Zm9yY2UgIT0gRFJNX0ZPUkNFX1VOU1BFQ0lGSUVEKQorCQkJ CXJldHVybiAtRUlOVkFMOworCisJCQltb2RlLT5mb3JjZSA9IERSTV9GT1JDRV9PTjsKKwkJCWJy ZWFrOworCQlkZWZhdWx0OgorCQkJcmV0dXJuIC1FSU5WQUw7CisJCX0KKwl9CisKKwlyZXR1cm4g MDsKK30KKworc3RhdGljIGludCBkcm1fbW9kZV9wYXJzZV9jbWRsaW5lX3Jlc19tb2RlKGNvbnN0 IGNoYXIgKnN0ciwgdW5zaWduZWQgaW50IGxlbmd0aCwKKwkJCQkJICAgYm9vbCBleHRyYXMsCisJ CQkJCSAgIHN0cnVjdCBkcm1fY29ubmVjdG9yICpjb25uZWN0b3IsCisJCQkJCSAgIHN0cnVjdCBk cm1fY21kbGluZV9tb2RlICptb2RlKQoreworCWJvb2wgcmIgPSBmYWxzZSwgY3Z0ID0gZmFsc2U7 CisJaW50IHhyZXMgPSAwLCB5cmVzID0gMDsKKwlpbnQgcmVtYWluaW5nLCBpOworCWNoYXIgKmVu ZF9wdHI7CisKKwl4cmVzID0gc2ltcGxlX3N0cnRvbChzdHIsICZlbmRfcHRyLCAxMCk7CisKKwlp ZiAoZW5kX3B0clswXSAhPSAneCcpCisJCXJldHVybiAtRUlOVkFMOworCWVuZF9wdHIrKzsKKwor CXlyZXMgPSBzaW1wbGVfc3RydG9sKGVuZF9wdHIsICZlbmRfcHRyLCAxMCk7CisKKwlyZW1haW5p bmcgPSBsZW5ndGggLSAoZW5kX3B0ciAtIHN0cik7CisJaWYgKHJlbWFpbmluZyA8IDApCisJCXJl dHVybiAtRUlOVkFMOworCisJZm9yIChpID0gMDsgaSA8IHJlbWFpbmluZzsgaSsrKSB7CisJCXN3 aXRjaCAoZW5kX3B0cltpXSkgeworCQljYXNlICdNJzoKKwkJCWN2dCA9IHRydWU7CisJCQlicmVh azsKKwkJY2FzZSAnUic6CisJCQlyYiA9IHRydWU7CisJCQlicmVhazsKKwkJZGVmYXVsdDoKKwkJ CS8qCisJCQkgKiBUcnkgdG8gcGFzcyB0aGF0IHRvIG91ciBleHRyYXMgcGFyc2luZworCQkJICog ZnVuY3Rpb24gdG8gaGFuZGxlIHRoZSBjYXNlIHdoZXJlIHRoZQorCQkJICogZXh0cmFzIGFyZSBk aXJlY3RseSBhZnRlciB0aGUgcmVzb2x1dGlvbgorCQkJICovCisJCQlpZiAoZXh0cmFzKSB7CisJ CQkJaW50IHJldCA9IGRybV9tb2RlX3BhcnNlX2NtZGxpbmVfZXh0cmEoZW5kX3B0ciArIGksCisJ CQkJCQkJCSAgICAgICAxLAorCQkJCQkJCQkgICAgICAgY29ubmVjdG9yLAorCQkJCQkJCQkgICAg ICAgbW9kZSk7CisJCQkJaWYgKHJldCkKKwkJCQkJcmV0dXJuIHJldDsKKwkJCX0gZWxzZSB7CisJ CQkJcmV0dXJuIC1FSU5WQUw7CisJCQl9CisJCX0KKwl9CisKKwltb2RlLT54cmVzID0geHJlczsK Kwltb2RlLT55cmVzID0geXJlczsKKwltb2RlLT5jdnQgPSBjdnQ7CisJbW9kZS0+cmIgPSByYjsK KworCXJldHVybiAwOworfQorCiAvKioKICAqIGRybV9tb2RlX3BhcnNlX2NvbW1hbmRfbGluZV9m b3JfY29ubmVjdG9yIC0gcGFyc2UgY29tbWFuZCBsaW5lIG1vZGVsaW5lIGZvciBjb25uZWN0b3IK ICAqIEBtb2RlX29wdGlvbjogb3B0aW9uYWwgcGVyIGNvbm5lY3RvciBtb2RlIG9wdGlvbgpAQCAt MTQzMSwxMyArMTU1NywxMiBAQCBib29sIGRybV9tb2RlX3BhcnNlX2NvbW1hbmRfbGluZV9mb3Jf Y29ubmVjdG9yKGNvbnN0IGNoYXIgKm1vZGVfb3B0aW9uLAogCQkJCQkgICAgICAgc3RydWN0IGRy bV9jbWRsaW5lX21vZGUgKm1vZGUpCiB7CiAJY29uc3QgY2hhciAqbmFtZTsKLQl1bnNpZ25lZCBp bnQgbmFtZWxlbjsKLQlib29sIHJlc19zcGVjaWZpZWQgPSBmYWxzZSwgYnBwX3NwZWNpZmllZCA9 IGZhbHNlLCByZWZyZXNoX3NwZWNpZmllZCA9IGZhbHNlOwotCXVuc2lnbmVkIGludCB4cmVzID0g MCwgeXJlcyA9IDAsIGJwcCA9IDMyLCByZWZyZXNoID0gMDsKLQlib29sIHlyZXNfc3BlY2lmaWVk ID0gZmFsc2UsIGN2dCA9IGZhbHNlLCByYiA9IGZhbHNlOwotCWJvb2wgaW50ZXJsYWNlID0gZmFs c2UsIG1hcmdpbnMgPSBmYWxzZSwgd2FzX2RpZ2l0ID0gZmFsc2U7Ci0JaW50IGk7Ci0JZW51bSBk cm1fY29ubmVjdG9yX2ZvcmNlIGZvcmNlID0gRFJNX0ZPUkNFX1VOU1BFQ0lGSUVEOworCWJvb2wg cGFyc2VfZXh0cmFzID0gZmFsc2U7CisJdW5zaWduZWQgaW50IGJwcF9vZmYgPSAwLCByZWZyZXNo X29mZiA9IDA7CisJdW5zaWduZWQgaW50IG1vZGVfZW5kID0gMDsKKwljaGFyICpicHBfcHRyID0g TlVMTCwgKnJlZnJlc2hfcHRyID0gTlVMTCwgKmV4dHJhX3B0ciA9IE5VTEw7CisJY2hhciAqYnBw X2VuZF9wdHIgPSBOVUxMLCAqcmVmcmVzaF9lbmRfcHRyID0gTlVMTDsKKwlpbnQgcmV0OwogCiAj aWZkZWYgQ09ORklHX0ZCCiAJaWYgKCFtb2RlX29wdGlvbikKQEAgLTE0NTAsMTI3ICsxNTc1LDc3 IEBAIGJvb2wgZHJtX21vZGVfcGFyc2VfY29tbWFuZF9saW5lX2Zvcl9jb25uZWN0b3IoY29uc3Qg Y2hhciAqbW9kZV9vcHRpb24sCiAJfQogCiAJbmFtZSA9IG1vZGVfb3B0aW9uOwotCW5hbWVsZW4g PSBzdHJsZW4obmFtZSk7Ci0JZm9yIChpID0gbmFtZWxlbi0xOyBpID49IDA7IGktLSkgewotCQlz d2l0Y2ggKG5hbWVbaV0pIHsKLQkJY2FzZSAnQCc6Ci0JCQlpZiAoIXJlZnJlc2hfc3BlY2lmaWVk ICYmICFicHBfc3BlY2lmaWVkICYmCi0JCQkgICAgIXlyZXNfc3BlY2lmaWVkICYmICFjdnQgJiYg IXJiICYmIHdhc19kaWdpdCkgewotCQkJCXJlZnJlc2ggPSBzaW1wbGVfc3RydG9sKCZuYW1lW2kr MV0sIE5VTEwsIDEwKTsKLQkJCQlyZWZyZXNoX3NwZWNpZmllZCA9IHRydWU7Ci0JCQkJd2FzX2Rp Z2l0ID0gZmFsc2U7Ci0JCQl9IGVsc2UKLQkJCQlnb3RvIGRvbmU7Ci0JCQlicmVhazsKLQkJY2Fz ZSAnLSc6Ci0JCQlpZiAoIWJwcF9zcGVjaWZpZWQgJiYgIXlyZXNfc3BlY2lmaWVkICYmICFjdnQg JiYKLQkJCSAgICAhcmIgJiYgd2FzX2RpZ2l0KSB7Ci0JCQkJYnBwID0gc2ltcGxlX3N0cnRvbCgm bmFtZVtpKzFdLCBOVUxMLCAxMCk7Ci0JCQkJYnBwX3NwZWNpZmllZCA9IHRydWU7Ci0JCQkJd2Fz X2RpZ2l0ID0gZmFsc2U7Ci0JCQl9IGVsc2UKLQkJCQlnb3RvIGRvbmU7Ci0JCQlicmVhazsKLQkJ Y2FzZSAneCc6Ci0JCQlpZiAoIXlyZXNfc3BlY2lmaWVkICYmIHdhc19kaWdpdCkgewotCQkJCXly ZXMgPSBzaW1wbGVfc3RydG9sKCZuYW1lW2krMV0sIE5VTEwsIDEwKTsKLQkJCQl5cmVzX3NwZWNp ZmllZCA9IHRydWU7Ci0JCQkJd2FzX2RpZ2l0ID0gZmFsc2U7Ci0JCQl9IGVsc2UKLQkJCQlnb3Rv IGRvbmU7Ci0JCQlicmVhazsKLQkJY2FzZSAnMCcgLi4uICc5JzoKLQkJCXdhc19kaWdpdCA9IHRy dWU7Ci0JCQlicmVhazsKLQkJY2FzZSAnTSc6Ci0JCQlpZiAoeXJlc19zcGVjaWZpZWQgfHwgY3Z0 IHx8IHdhc19kaWdpdCkKLQkJCQlnb3RvIGRvbmU7Ci0JCQljdnQgPSB0cnVlOwotCQkJYnJlYWs7 Ci0JCWNhc2UgJ1InOgotCQkJaWYgKHlyZXNfc3BlY2lmaWVkIHx8IGN2dCB8fCByYiB8fCB3YXNf ZGlnaXQpCi0JCQkJZ290byBkb25lOwotCQkJcmIgPSB0cnVlOwotCQkJYnJlYWs7Ci0JCWNhc2Ug J20nOgotCQkJaWYgKGN2dCB8fCB5cmVzX3NwZWNpZmllZCB8fCB3YXNfZGlnaXQpCi0JCQkJZ290 byBkb25lOwotCQkJbWFyZ2lucyA9IHRydWU7Ci0JCQlicmVhazsKLQkJY2FzZSAnaSc6Ci0JCQlp ZiAoY3Z0IHx8IHlyZXNfc3BlY2lmaWVkIHx8IHdhc19kaWdpdCkKLQkJCQlnb3RvIGRvbmU7Ci0J CQlpbnRlcmxhY2UgPSB0cnVlOwotCQkJYnJlYWs7Ci0JCWNhc2UgJ2UnOgotCQkJaWYgKHlyZXNf c3BlY2lmaWVkIHx8IGJwcF9zcGVjaWZpZWQgfHwgcmVmcmVzaF9zcGVjaWZpZWQgfHwKLQkJCSAg ICB3YXNfZGlnaXQgfHwgKGZvcmNlICE9IERSTV9GT1JDRV9VTlNQRUNJRklFRCkpCi0JCQkJZ290 byBkb25lOwogCi0JCQlmb3JjZSA9IERSTV9GT1JDRV9PTjsKLQkJCWJyZWFrOwotCQljYXNlICdE JzoKLQkJCWlmICh5cmVzX3NwZWNpZmllZCB8fCBicHBfc3BlY2lmaWVkIHx8IHJlZnJlc2hfc3Bl Y2lmaWVkIHx8Ci0JCQkgICAgd2FzX2RpZ2l0IHx8IChmb3JjZSAhPSBEUk1fRk9SQ0VfVU5TUEVD SUZJRUQpKQotCQkJCWdvdG8gZG9uZTsKKwlpZiAoIWlzZGlnaXQobmFtZVswXSkpCisJCXJldHVy biBmYWxzZTsKIAotCQkJaWYgKChjb25uZWN0b3ItPmNvbm5lY3Rvcl90eXBlICE9IERSTV9NT0RF X0NPTk5FQ1RPUl9EVklJKSAmJgotCQkJICAgIChjb25uZWN0b3ItPmNvbm5lY3Rvcl90eXBlICE9 IERSTV9NT0RFX0NPTk5FQ1RPUl9IRE1JQikpCi0JCQkJZm9yY2UgPSBEUk1fRk9SQ0VfT047Ci0J CQllbHNlCi0JCQkJZm9yY2UgPSBEUk1fRk9SQ0VfT05fRElHSVRBTDsKLQkJCWJyZWFrOwotCQlj YXNlICdkJzoKLQkJCWlmICh5cmVzX3NwZWNpZmllZCB8fCBicHBfc3BlY2lmaWVkIHx8IHJlZnJl c2hfc3BlY2lmaWVkIHx8Ci0JCQkgICAgd2FzX2RpZ2l0IHx8IChmb3JjZSAhPSBEUk1fRk9SQ0Vf VU5TUEVDSUZJRUQpKQotCQkJCWdvdG8gZG9uZTsKKwkvKiBUcnkgdG8gbG9jYXRlIHRoZSBicHAg YW5kIHJlZnJlc2ggc3BlY2lmaWVycywgaWYgYW55ICovCisJYnBwX3B0ciA9IHN0cmNocihuYW1l LCAnLScpOworCWlmIChicHBfcHRyKSB7CisJCWJwcF9vZmYgPSBicHBfcHRyIC0gbmFtZTsKKwkJ bW9kZS0+YnBwX3NwZWNpZmllZCA9IHRydWU7CisJfQogCi0JCQlmb3JjZSA9IERSTV9GT1JDRV9P RkY7Ci0JCQlicmVhazsKLQkJZGVmYXVsdDoKLQkJCWdvdG8gZG9uZTsKLQkJfQorCXJlZnJlc2hf cHRyID0gc3RyY2hyKG5hbWUsICdAJyk7CisJaWYgKHJlZnJlc2hfcHRyKSB7CisJCXJlZnJlc2hf b2ZmID0gcmVmcmVzaF9wdHIgLSBuYW1lOworCQltb2RlLT5yZWZyZXNoX3NwZWNpZmllZCA9IHRy dWU7CiAJfQogCi0JaWYgKGkgPCAwICYmIHlyZXNfc3BlY2lmaWVkKSB7Ci0JCWNoYXIgKmNoOwot CQl4cmVzID0gc2ltcGxlX3N0cnRvbChuYW1lLCAmY2gsIDEwKTsKLQkJaWYgKChjaCAhPSBOVUxM KSAmJiAoKmNoID09ICd4JykpCi0JCQlyZXNfc3BlY2lmaWVkID0gdHJ1ZTsKLQkJZWxzZQotCQkJ aSA9IGNoIC0gbmFtZTsKLQl9IGVsc2UgaWYgKCF5cmVzX3NwZWNpZmllZCAmJiB3YXNfZGlnaXQp IHsKLQkJLyogY2F0Y2ggbW9kZSB0aGF0IGJlZ2lucyB3aXRoIGRpZ2l0cyBidXQgaGFzIG5vICd4 JyAqLwotCQlpID0gMDsKKwkvKiBMb2NhdGUgdGhlIGVuZCBvZiB0aGUgbmFtZSAvIHJlc29sdXRp b24sIGFuZCBwYXJzZSBpdCAqLworCWlmIChicHBfcHRyICYmIHJlZnJlc2hfcHRyKSB7CisJCW1v ZGVfZW5kID0gbWluKGJwcF9vZmYsIHJlZnJlc2hfb2ZmKTsKKwl9IGVsc2UgaWYgKGJwcF9wdHIp IHsKKwkJbW9kZV9lbmQgPSBicHBfb2ZmOworCX0gZWxzZSBpZiAocmVmcmVzaF9wdHIpIHsKKwkJ bW9kZV9lbmQgPSByZWZyZXNoX29mZjsKKwl9IGVsc2UgeworCQltb2RlX2VuZCA9IHN0cmxlbihu YW1lKTsKKwkJcGFyc2VfZXh0cmFzID0gdHJ1ZTsKIAl9Ci1kb25lOgotCWlmIChpID49IDApIHsK LQkJcHJfd2FybigiW2RybV0gcGFyc2UgZXJyb3IgYXQgcG9zaXRpb24gJWkgaW4gdmlkZW8gbW9k ZSAnJXMnXG4iLAotCQkJaSwgbmFtZSk7Ci0JCW1vZGUtPnNwZWNpZmllZCA9IGZhbHNlOworCisJ cmV0ID0gZHJtX21vZGVfcGFyc2VfY21kbGluZV9yZXNfbW9kZShuYW1lLCBtb2RlX2VuZCwKKwkJ CQkJICAgICAgcGFyc2VfZXh0cmFzLAorCQkJCQkgICAgICBjb25uZWN0b3IsCisJCQkJCSAgICAg IG1vZGUpOworCWlmIChyZXQpCiAJCXJldHVybiBmYWxzZTsKLQl9CisJbW9kZS0+c3BlY2lmaWVk ID0gdHJ1ZTsKIAotCWlmIChyZXNfc3BlY2lmaWVkKSB7Ci0JCW1vZGUtPnNwZWNpZmllZCA9IHRy dWU7Ci0JCW1vZGUtPnhyZXMgPSB4cmVzOwotCQltb2RlLT55cmVzID0geXJlczsKKwlpZiAoYnBw X3B0cikgeworCQlyZXQgPSBkcm1fbW9kZV9wYXJzZV9jbWRsaW5lX2JwcChicHBfcHRyLCAmYnBw X2VuZF9wdHIsIG1vZGUpOworCQlpZiAocmV0KQorCQkJcmV0dXJuIGZhbHNlOwogCX0KIAotCWlm IChyZWZyZXNoX3NwZWNpZmllZCkgewotCQltb2RlLT5yZWZyZXNoX3NwZWNpZmllZCA9IHRydWU7 Ci0JCW1vZGUtPnJlZnJlc2ggPSByZWZyZXNoOworCWlmIChyZWZyZXNoX3B0cikgeworCQlyZXQg PSBkcm1fbW9kZV9wYXJzZV9jbWRsaW5lX3JlZnJlc2gocmVmcmVzaF9wdHIsCisJCQkJCQkgICAg ICZyZWZyZXNoX2VuZF9wdHIsIG1vZGUpOworCQlpZiAocmV0KQorCQkJcmV0dXJuIGZhbHNlOwog CX0KIAotCWlmIChicHBfc3BlY2lmaWVkKSB7Ci0JCW1vZGUtPmJwcF9zcGVjaWZpZWQgPSB0cnVl OwotCQltb2RlLT5icHAgPSBicHA7CisJLyoKKwkgKiBMb2NhdGUgdGhlIGVuZCBvZiB0aGUgYnBw IC8gcmVmcmVzaCwgYW5kIHBhcnNlIHRoZSBleHRyYXMKKwkgKiBpZiByZWxldmFudAorCSAqLwor CWlmIChicHBfcHRyICYmIHJlZnJlc2hfcHRyKQorCQlleHRyYV9wdHIgPSBtYXgoYnBwX2VuZF9w dHIsIHJlZnJlc2hfZW5kX3B0cik7CisJZWxzZSBpZiAoYnBwX3B0cikKKwkJZXh0cmFfcHRyID0g YnBwX2VuZF9wdHI7CisJZWxzZSBpZiAocmVmcmVzaF9wdHIpCisJCWV4dHJhX3B0ciA9IHJlZnJl c2hfZW5kX3B0cjsKKworCWlmIChleHRyYV9wdHIpIHsKKwkJaW50IHJlbWFpbmluZyA9IHN0cmxl bihuYW1lKSAtIChleHRyYV9wdHIgLSBuYW1lKTsKKworCQkvKgorCQkgKiBXZSBzdGlsbCBoYXZl IGNoYXJhY3RlcnMgdG8gcHJvY2Vzcywgd2hpbGUKKwkJICogd2Ugc2hvdWxkbid0IGhhdmUgYW55 CisJCSAqLworCQlpZiAocmVtYWluaW5nID4gMCkKKwkJCXJldHVybiBmYWxzZTsKIAl9Ci0JbW9k ZS0+cmIgPSByYjsKLQltb2RlLT5jdnQgPSBjdnQ7Ci0JbW9kZS0+aW50ZXJsYWNlID0gaW50ZXJs YWNlOwotCW1vZGUtPm1hcmdpbnMgPSBtYXJnaW5zOwotCW1vZGUtPmZvcmNlID0gZm9yY2U7CiAK IAlyZXR1cm4gdHJ1ZTsKIH0KLS0gCmdpdC1zZXJpZXMgMC45LjEKX19fX19fX19fX19fX19fX19f X19fX19fX19fX19fX19fX19fX19fX19fX19fX18KZHJpLWRldmVsIG1haWxpbmcgbGlzdApkcmkt ZGV2ZWxAbGlzdHMuZnJlZWRlc2t0b3Aub3JnCmh0dHBzOi8vbGlzdHMuZnJlZWRlc2t0b3Aub3Jn L21haWxtYW4vbGlzdGluZm8vZHJpLWRldmVs