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=-2.9 required=3.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI,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 17E76ECDE5F for ; Thu, 19 Jul 2018 18:00:02 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id D3F1920684 for ; Thu, 19 Jul 2018 18:00:00 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=cadence.com header.i=@cadence.com header.b="LL4pw8iZ" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org D3F1920684 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=cadence.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2388030AbeGSSoO (ORCPT ); Thu, 19 Jul 2018 14:44:14 -0400 Received: from mail-eopbgr730070.outbound.protection.outlook.com ([40.107.73.70]:35633 "EHLO NAM05-DM3-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1732089AbeGSSoJ (ORCPT ); Thu, 19 Jul 2018 14:44:09 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cadence.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=FSQAkbViVw8S5UjGTvRt5nTrhIo12DkDiPCLXSjM664=; b=LL4pw8iZIARVqfEqbN3zOgbTqa11ycqAL44eyEE81SA5lZh136SL+SGoUfHJZJEwopkzLdSD19ynLHNrZTvthNV5sX5yh93vEW628Cg4dsBvd5BaOW+07Icq/emSbcLmk7UAJnv3aHkLhA4El0evQBFJRW5Pe3gYJfhVLyG+PB0= Received: from SN1PR0701CA0078.namprd07.prod.outlook.com (2a01:111:e400:52fd::46) by BN3PR0701MB1330.namprd07.prod.outlook.com (2a01:111:e400:4019::27) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.973.20; Thu, 19 Jul 2018 17:59:28 +0000 Received: from DM3NAM05FT051.eop-nam05.prod.protection.outlook.com (2a01:111:f400:7e51::203) by SN1PR0701CA0078.outlook.office365.com (2a01:111:e400:52fd::46) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384) id 15.20.973.16 via Frontend Transport; Thu, 19 Jul 2018 17:59:28 +0000 Authentication-Results: spf=softfail (sender IP is 158.140.1.28) smtp.mailfrom=cadence.com; vger.kernel.org; dkim=none (message not signed) header.d=none;vger.kernel.org; dmarc=fail action=none header.from=cadence.com; Received-SPF: SoftFail (protection.outlook.com: domain of transitioning cadence.com discourages use of 158.140.1.28 as permitted sender) Received: from sjmaillnx2.cadence.com (158.140.1.28) by DM3NAM05FT051.mail.protection.outlook.com (10.152.98.165) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P384) id 15.20.995.0 via Frontend Transport; Thu, 19 Jul 2018 17:59:27 +0000 Received: from maileu3.global.cadence.com (maileu3.cadence.com [10.160.88.99]) by sjmaillnx2.cadence.com (8.14.4/8.14.4) with ESMTP id w6JHxNgD025447 (version=TLSv1/SSLv3 cipher=AES256-SHA bits=256 verify=FAIL); Thu, 19 Jul 2018 10:59:26 -0700 X-CrossPremisesHeadersFilteredBySendConnector: maileu3.global.cadence.com Received: from maileu3.global.cadence.com (10.160.88.99) by maileu3.global.cadence.com (10.160.88.99) with Microsoft SMTP Server (TLS) id 15.0.1367.3; Thu, 19 Jul 2018 19:59:31 +0200 Received: from lvlogina.cadence.com (10.165.176.102) by maileu3.global.cadence.com (10.160.88.99) with Microsoft SMTP Server id 15.0.1367.3 via Frontend Transport; Thu, 19 Jul 2018 19:59:31 +0200 Received: from lvlogina.cadence.com (localhost.localdomain [127.0.0.1]) by lvlogina.cadence.com (8.14.4/8.14.4) with ESMTP id w6JHxF8J005988; Thu, 19 Jul 2018 18:59:15 +0100 Received: (from pawell@localhost) by lvlogina.cadence.com (8.14.4/8.14.4/Submit) id w6JHxFTK005980; Thu, 19 Jul 2018 18:59:15 +0100 From: Pawel Laszczak CC: Greg Kroah-Hartman , , Felipe Balbi , , , , Subject: [PATCH 23/31] usb: usbssp: added implementation of transfer events. Date: Thu, 19 Jul 2018 18:57:56 +0100 Message-ID: <1532023084-28083-24-git-send-email-pawell@cadence.com> X-Mailer: git-send-email 1.7.11.2 In-Reply-To: <1532023084-28083-1-git-send-email-pawell@cadence.com> References: <1532023084-28083-1-git-send-email-pawell@cadence.com> MIME-Version: 1.0 Content-Type: text/plain X-OrganizationHeadersPreserved: maileu3.global.cadence.com X-EOPAttributedMessage: 0 X-Forefront-Antispam-Report: CIP:158.140.1.28;IPV:CAL;SCL:-1;CTRY:US;EFV:NLI;SFV:NSPM;SFS:(10009020)(136003)(396003)(376002)(346002)(39860400002)(2980300002)(36092001)(199004)(189003)(43544003)(36756003)(87636003)(50226002)(478600001)(486006)(50466002)(76176011)(4326008)(8936002)(42186006)(16586007)(316002)(26826003)(86362001)(5660300001)(575784001)(26005)(14444005)(426003)(48376002)(107886003)(1671002)(109986005)(186003)(246002)(8676002)(2616005)(51416003)(336012)(305945005)(476003)(7636002)(126002)(356003)(6666003)(11346002)(446003)(4720700003)(106466001)(105596002)(551934003)(2906002)(54906003)(47776003)(266003);DIR:OUT;SFP:1101;SCL:1;SRVR:BN3PR0701MB1330;H:sjmaillnx2.cadence.com;FPR:;SPF:SoftFail;LANG:en;PTR:corp.cadence.com;A:1;MX:1; X-Microsoft-Exchange-Diagnostics: 1;DM3NAM05FT051;1:nSH3KUaWWKPSL662snU+432bXsTnLNdL6xSX4zHSMXey7YPeKO0sFErJao11wPL4hlIgH4RLzPvA0Fn8POl13FPV1+hz4U+1Zj38aqHqanuZ+pAF39rfYbIgIPMqxf53 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 8020bbdd-ab6c-4bb2-488c-08d5eda15eeb X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:(7020095)(4652040)(8989117)(5600053)(711020)(4534165)(4627221)(201703031133081)(201702281549075)(8990107)(2017052603328)(7153060);SRVR:BN3PR0701MB1330; X-Microsoft-Exchange-Diagnostics: 1;BN3PR0701MB1330;3:2cLltF/5LWk2Ld6bQo/xnEXrb0XpSgtZwew6cdVM/n/17jKf+dl0mPDlQYvALX3R6mQTlP8GDMr0TpRxyRKX4PYl0YNLRJU1iozs2oiYgQw8NpVH90qm7Kc7UZBSmFp+CISTP3c4CbPOMbICRhKjSUUxdxByvbyK242rlcWsjhTewGOcXxTXoj0vv5dPSvtMm5quQQtOgdJ8lPrrq8NkN9ELpDP8J0XefWIJGv0tNDlT1XBsAH8Mldd28Wzr2ilzBX/FJngdI8kCBnJ73vt8UB5hAk481e+XUZkabQ2YcZFmXEdM8EmoKh5aZ5oeT4MXW0oiQz+CQ0GHNbfGNydCbui5yU0nDq7IboHcMopx3E4=;25:aK21VWE/Z36/5XLa4iuwMFxc1N6WRqvBXMhLT9yDHcrLCfqvXDv3KOyebRBg2oX/vr5kKHr3vGzxLU3R2RC1+l069KnMpM1eInncauiOA0pjhXyyYBlTn+b681tBwfo5EPEgps9OumUc4gbx59nMmLv0BHDEdA6KUz2k00t+sd8m2Yn3Zdq35EziMmIyDxZ4VjaruMC9EYje8Od5wZKpQA9pGqZHnVMvlWv3wwM/qnpCcbqVJVf6jotxgjEnKA1cEeMfLWNcGnB02vz9wAxRFh/Mdmg9yD08etT9u6ds5ybDWUf1aJennC9VhcmdKs/ql1KT1JNpY3lCFBta4ATZiw== X-MS-TrafficTypeDiagnostic: BN3PR0701MB1330: X-Microsoft-Exchange-Diagnostics: 1;BN3PR0701MB1330;31:Rh7v2R2NY8eCVGyHjKXjVzFC1U3lxh8UxcdBDbAQKiQMDlG17QPOhomT3t9o2lzkOGuOZkF1DUxAgPBuAY8iUTGOLZHTcfMJnp2L7bknHhD5avViBo+JqcH1VNTWv4au3mWYlqgC5Q9zHji57A/oMg2dYYcMkijN85tpQvaZSvGVx7sN5G2Jm5ht5MamzTMs4xqmblME35pCNHzcLVcz9BefSswUXLvRFzAgcoKKZTU=;20:OmCL4Ot7YoBdXMmicUwylr4i1ofAiXACJCe4hkML7ejho0nnuHL50RtPNdjYeTWtwEv8v7AL+r3fwSv4uo23oAq1P9d+dHPyYUoCJc+aX/+7o3du5OKULcGniJ/wVGemBKb20FACBiY9uKmxKBF/s+muoCibvwNb3dm5CGA5IQXRxyjDxEe1k633A9JMWHmf+AFgHNJMW93TF+qG8+43FAFptyxFIu3+6usOFybDhF+qUme9Nw45KnBl0Nf7a8NxynjLGbsyyY085fvtQZoJv5w+C07msmXg47FZQjvYzSPc2RPGRMdMr4BLUxIOB25iqi2P5el+K+VDBkNwZ4177+nmth8H+o8JLj93BIIph4CYkY1e38B82QIcv1pcJbAKYbKdQ5GYRdyJY4jio88GK6Vqg4idY/AEvysPOuPTyRMf0kYfaRhl0wuUNpzGhd46lsqyvYN5IllVHFZLLnLPwFnbsbYRlgvUpvcy+Erphe2rZDErC608fh+mMBvE6O7Y X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:(72806322054110); X-MS-Exchange-SenderADCheck: 1 X-Exchange-Antispam-Report-CFA-Test: BCL:0;PCL:0;RULEID:(8211001083)(6040522)(2401047)(8121501046)(5005006)(10201501046)(93006095)(93003095)(3002001)(3231311)(944501410)(52105095)(149027)(150027)(6041310)(201703131423095)(201702281528075)(20161123555045)(201703061421075)(201703061406153)(20161123560045)(20161123564045)(20161123562045)(20161123558120)(6072148)(201708071742011)(7699016);SRVR:BN3PR0701MB1330;BCL:0;PCL:0;RULEID:;SRVR:BN3PR0701MB1330; X-Microsoft-Exchange-Diagnostics: 1;BN3PR0701MB1330;4:rsvNV1dsaCXcC9Lqqf05VIlRBl2eEEOaj/+wYbMccYKZR72ZOuVu4THFU1U3SBqW4J2pCSf9j2AOYvaeAB8e5NY/GrfPSLqShlbjKfGhDWXIwxPfX1yoVu0oplaPIQzkaXTyCnpH+FnFNpr8jTM5rQU8MUiIaJCRd2i8lwRlHRL27f/y5yvIustiir5+22F/785Y4SDgE9wQ+1fJAmLbS4p45odxMVRPBzAYN1Ks0Se+Z0YAxGsltDZCBBc7VKOuLcJgMUuujhFqO5mpLMZGFfKW2NiO4fch620wuAjXSUxXWLVLcUnjPE4pZ0YEty0l X-Forefront-PRVS: 0738AF4208 X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1;BN3PR0701MB1330;23:+8QZwRbiFqNTaNjHYhzbBhaUazJbxGFfI4XZFlY?= =?us-ascii?Q?utqMuxsXeY048U5Nv5qZCjh3iS1z4GTur6zlZH/xZPDPvd9V2enuQ9kqLxwg?= =?us-ascii?Q?EX/HB7vkkEH0Pnh1ROhHE8fFNs3d45L5CfnkMCbU41GTmdUVhboBEDpHvFLg?= =?us-ascii?Q?54qgjcuL24Y82eTHaP75cwaj+lzlRJpWCT1jZ/I883a2cIg0k5NYVp+8Zq9l?= =?us-ascii?Q?6fkjQjabHnPDv1dVcYn25Ip31SdqhsGi4cc7DDu1NvkxQycUm4qCgwsou6yG?= =?us-ascii?Q?erNzQECRePbr6ff/YV58iH/waVuxjzQqKbHTV+XFwr9e1/izV/WnL0Ssvl7c?= =?us-ascii?Q?It/qES/BLaRgDMm3WQOCJRJNTNtoxHV4291O9oZyt033FX6RPye6Xxfp70MI?= =?us-ascii?Q?X2/vGOtzet9cXGD1PNbX9ejOyVb3wlLFWWxog3tjFfLRAfuP8ac5CraV3yhY?= =?us-ascii?Q?pe5LuGLwuN+w0YdpgfRAkzdchyhwwDQ3Oxxqi/9kZDs04uOkzYtn7KD4SxVL?= =?us-ascii?Q?M1XA2tFR60x12xo4H/fREfwmorgX9MZzaG2yzaUjy2KWECaxfFSwy/QXpWxd?= =?us-ascii?Q?D4JejpUAGkhptjB5mUj+YYNcGdJY4WDfXWTqttBI0tBSOs4LsYRkIh8W2BcG?= =?us-ascii?Q?6/zJlwr3CHIx+4obDJL05fF+gtx2jmg4yCMR8DBXGb1W+SHtYjwtNnhqyLgv?= =?us-ascii?Q?n4ptIf5sdFB/zptG4O2bQRjCojlD8z2zoYQ2cNqVfPMRMpSeOfRByMLKglnJ?= =?us-ascii?Q?kEXBFUZJkEP+wKm2nVKKUbga+9/DG6+CtYMLp1Cjmsualdl/6SL+OMUd8/K0?= =?us-ascii?Q?OLgipKGPQ/YX69KOB2m7akM5PUM0Pwu+44hy3HJMC3RsJ16rmiHrO8Xp1/KJ?= =?us-ascii?Q?FUf/6tZ09JC8hobJmc3owKHBUobEQoy21NF6SfT3C2Ld0Vib/R5tXiPf89UV?= =?us-ascii?Q?xH6+6MQZIrkUjeh46TnwjhNwZTQdoylRgJprxosKnO+5WJd4jvBnjHrnHm2u?= =?us-ascii?Q?UPQ5He4Y7PBhXYhSloVrXcW/MHFGZmBD2anc/EorBEBtF+Pg+wgpwsjz1544?= =?us-ascii?Q?mBYL3EDTzMfVa+6FESa1spGLD9uJcKG4fagSSo6ZUYby54zyZiluR0gju4aW?= =?us-ascii?Q?hhhCXHgUyjb7dqLQw2pDgzXWG0J92+TfGxfTEkSSev3BAmMxNc1u7keYwvgl?= =?us-ascii?Q?nzgC5DuvTApv5ahH+z3DlYvj7Nx4+udH3QuFJkl5mjRJtblWaaSdrPRuK3Q?= =?us-ascii?Q?=3D=3D?= X-Microsoft-Antispam-Message-Info: 8aNMwBab2IReWa5yYh5Rpsa1TS9roElJDWf1x3QsxmKwMhYcV7OAp5fMtBqfRPgSPG6JLMBRCvLzXN9u6dEr13bvkt2w8pWXJmh/6XT27MANjL0z/lCNbELgCkea5ilxXn9sEB8nJEScwjrvVoDpeFemdJbc/CSn4ES0tLXxxndr94ERGZgnVGf2L6rR6U2JjtACeXb5NxD16VvDdcguH+tzCMh8gfZC/7OTFlbZC+JGHLU54EG3hBE3ya1buZ0TTPouzokWSZRlxaJy01H8xmWlxfkPF0PAiUAs4N2iTzcuCo69/hhLawV3rWek7dLCO1l8Joh+2nGtm+2yHvtEgEcrMhRvWOFuuZdvYM3cd3eGdwkknd8njp0qnVJXekYPONSQZvKLzs5V5XVz3Vq9tA== X-Microsoft-Exchange-Diagnostics: 1;BN3PR0701MB1330;6:R8Phx5bXWjoT5oDFUgtL0XxwvU+QOFOFX4nec9zVWnQeiEaIjwiaL+J4khxdJ651BnEg8Ah1PAadxHmX9VBFB+v+ezeglVB8J0G0JbBCIhFxYXSfCgUAmNvAGE0YJDY9636EQ+Tn+eVUcET2q6KeoxER618HZ1CIUz2JbtM1zxTE+h+d4F4AEzcmt4kiSHV9jqoZUOEbzKFEJPgqGvJVQq7/QssOyuN6YiZvRRwY8lISvCYkgXseBsupiOFHMK99K8GnHt/qp6tQqRU4on7udrxKc/6xYVS17Tf7iWOaiSbjJDTrBqCRzRMO8H2qz/jeMXFvVivRhYPYwODLqfgfFP1XBUuFqAYzdKjnC42XbRSrsmUClbBB6N97JZNn+QV9fjupcLGcHHvLf7zeKBD09Wcye9TDudfglQ0EISXAY4Zv3O6gx9rW9m9NM0/Plczkh3r78i8vk90rY38ojXV+Xg==;5:iO7WfeM7CvAe+l9526UHfuDBHJvHZp6jg/qMCC0WVQt9EkfyD74HESyv5IWV/qsG7wdaEH2z+pru+tzlcqUOatxEvZojrEzK0L3niKeZlZtosiGMfC0WmrWZc8ULCwAkmElhBLLQkPGRNpidwYHX2EIYA+aVVYI2Mc5RTkFrmMQ=;7:6Hn3G4NLOa2RxOynDreDSmAIOz3ZejSFDenHHronZfeW0dNDs5tdL3Mvqn21xJHyI1BuYpn7E6EZIN2A4UxhXECGUah9FP01E18eRbmWB85AhDkO5RxNkDNgYBWWa51F6HObMBbG8vcV9bfe5saADH6gH+pjDMWDZfp9aOdbiXPoIaEFNuEoXqfpbMKWkfgqtRzMJC9EcpIJSZJ9pdlt44ru25t80gldmt3mGVT+1mSZLHXPhBpFeI6fLeWN6y2j SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1;BN3PR0701MB1330;20:clspRWW4tJHI4sxhprG/aRpDMlvff4j83ZqjVvXPUqJOEOGV9vz/nWrmd7NWPtD4/cQ3hdqo7eDVlM3GNk0rNcwkAdWirWw+jvwGNVhfIbPoHkhUG/dz1Fruqhmi85GuUTszpt2FBlj3AC38rdMhk7ag9QN9PPkOuW0t0Jt3575TauP2hXW4wTAu4WSnPsT+8mxsi+uxTOfGDB+sZkOGe/nDT18bcxJ/vHQJTVsYhzMLccLYH4cjBZuyjrdiOawL X-OriginatorOrg: cadence.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 19 Jul 2018 17:59:27.7351 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 8020bbdd-ab6c-4bb2-488c-08d5eda15eeb X-MS-Exchange-CrossTenant-Id: d36035c5-6ce6-4662-a3dc-e762e61ae4c9 X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=d36035c5-6ce6-4662-a3dc-e762e61ae4c9;Ip=[158.140.1.28];Helo=[sjmaillnx2.cadence.com] X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: BN3PR0701MB1330 To: unlisted-recipients:; (no To-header on input) Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Patch add functionality related to handling transfer events. This kind of events are added to event ring after completion transfer. This patch add supports for handling transfer events only for control, interrupt and bulk transfer. After the transfer, usbssp driver release the TD and informs about it gadget core driver by means of usbssp_gadget_giveback function. Signed-off-by: Pawel Laszczak --- drivers/usb/usbssp/gadget-mem.c | 9 + drivers/usb/usbssp/gadget-ring.c | 602 ++++++++++++++++++++++++++++++- drivers/usb/usbssp/gadget.h | 5 + 3 files changed, 615 insertions(+), 1 deletion(-) diff --git a/drivers/usb/usbssp/gadget-mem.c b/drivers/usb/usbssp/gadget-mem.c index 858bee77b0dc..d5d732b94454 100644 --- a/drivers/usb/usbssp/gadget-mem.c +++ b/drivers/usb/usbssp/gadget-mem.c @@ -555,6 +555,15 @@ static void usbssp_free_stream_ctx(struct usbssp_udc *usbssp_data, stream_ctx, dma); } +struct usbssp_ring *usbssp_dma_to_transfer_ring(struct usbssp_ep *ep, + u64 address) +{ + if (ep->ep_state & EP_HAS_STREAMS) + return radix_tree_lookup(&ep->stream_info->trb_address_map, + address >> TRB_SEGMENT_SHIFT); + return ep->ring; +} + struct usbssp_ring *usbssp_stream_id_to_ring(struct usbssp_device *dev, unsigned int ep_index, unsigned int stream_id) diff --git a/drivers/usb/usbssp/gadget-ring.c b/drivers/usb/usbssp/gadget-ring.c index cfb31120eef8..8cc6e4247eef 100644 --- a/drivers/usb/usbssp/gadget-ring.c +++ b/drivers/usb/usbssp/gadget-ring.c @@ -62,6 +62,13 @@ #include "gadget-trace.h" #include "gadget.h" +static void giveback_first_trb(struct usbssp_udc *usbssp_data, + unsigned int ep_index, + unsigned int stream_id, + int start_cycle, + struct usbssp_generic_trb + *start_trb); + /* * Returns zero if the TRB isn't in this segment, otherwise it returns the DMA * address of the TRB. @@ -80,6 +87,11 @@ dma_addr_t usbssp_trb_virt_to_dma(struct usbssp_segment *seg, return seg->dma + (segment_offset * sizeof(*trb)); } +static bool trb_is_noop(union usbssp_trb *trb) +{ + return TRB_TYPE_NOOP_LE32(trb->generic.field[3]); +} + static bool trb_is_link(union usbssp_trb *trb) { return TRB_TYPE_LINK_LE32(trb->link.control); @@ -1528,6 +1540,289 @@ int usbssp_is_vendor_info_code(struct usbssp_udc *usbssp_data, return 0; } +static int usbssp_td_cleanup(struct usbssp_udc *usbssp_data, + struct usbssp_td *td, struct usbssp_ring *ep_ring, + int *status) +{ + struct usbssp_request *req_priv = NULL; + + /* Clean up the endpoint's TD list */ + req_priv = td->priv_request; + + /* if a bounce buffer was used to align this td then unmap it */ + usbssp_unmap_td_bounce_buffer(usbssp_data, ep_ring, td); + + /* + * Do one last check of the actual transfer length. + * If the DC controller said we transferred more data than the buffer + * length, req_priv->request.actual will be a very big number (since it's + * unsigned). Play it safe and say we didn't transfer anything. + */ + if (req_priv->request.actual > req_priv->request.length) { + dev_warn(usbssp_data->dev, + "USB req %u and actual %u transfer length mismatch\n", + req_priv->request.length, req_priv->request.actual); + req_priv->request.actual = 0; + *status = 0; + } + list_del_init(&td->td_list); + + inc_td_cnt(req_priv); + /* Giveback the USB request when all the tds are completed */ + if (last_td_in_request(td)) { + if ((req_priv->request.actual != req_priv->request.length && + td->priv_request->request.short_not_ok) || (*status != 0 && + !usb_endpoint_xfer_isoc(req_priv->dep->endpoint.desc))) + dev_dbg(usbssp_data->dev, + "Giveback Request %p, len = %d, expected = %d" + " status = %d\n", + req_priv, req_priv->request.actual, + req_priv->request.length, *status); + + if (usb_endpoint_xfer_isoc(req_priv->dep->endpoint.desc)) + *status = 0; + + usbssp_giveback_request_in_irq(usbssp_data, td, *status); + } + + return 0; +} + +static int finish_td(struct usbssp_udc *usbssp_data, struct usbssp_td *td, + struct usbssp_transfer_event *event, struct usbssp_ep *ep, + int *status) +{ + struct usbssp_device *dev_priv; + struct usbssp_ring *ep_ring; + unsigned int slot_id; + int ep_index; + struct usbssp_ep_ctx *ep_ctx; + u32 trb_comp_code; + + slot_id = TRB_TO_SLOT_ID(le32_to_cpu(event->flags)); + dev_priv = &usbssp_data->devs; + ep_index = TRB_TO_EP_ID(le32_to_cpu(event->flags)) - 1; + ep_ring = usbssp_dma_to_transfer_ring(ep, le64_to_cpu(event->buffer)); + ep_ctx = usbssp_get_ep_ctx(usbssp_data, dev_priv->out_ctx, ep_index); + trb_comp_code = GET_COMP_CODE(le32_to_cpu(event->transfer_len)); + + if (trb_comp_code == COMP_STOPPED_LENGTH_INVALID || + trb_comp_code == COMP_STOPPED || + trb_comp_code == COMP_STOPPED_SHORT_PACKET) { + /* + * The Endpoint Stop Command completion will take care of any + * stopped TDs. A stopped TD may be restarted, so don't update + * the ring dequeue pointer or take this TD off any lists yet. + */ + return 0; + } + + /* Update ring dequeue pointer */ + while (ep_ring->dequeue != td->last_trb) + inc_deq(usbssp_data, ep_ring); + + inc_deq(usbssp_data, ep_ring); + + return usbssp_td_cleanup(usbssp_data, td, ep_ring, status); +} + +/* sum trb lengths from ring dequeue up to stop_trb, _excluding_ stop_trb */ +static int sum_trb_lengths(struct usbssp_udc *usbssp_data, + struct usbssp_ring *ring, + union usbssp_trb *stop_trb) +{ + u32 sum; + union usbssp_trb *trb = ring->dequeue; + struct usbssp_segment *seg = ring->deq_seg; + + for (sum = 0; trb != stop_trb; next_trb(usbssp_data, ring, &seg, &trb)) { + if (!trb_is_noop(trb) && !trb_is_link(trb)) + sum += TRB_LEN(le32_to_cpu(trb->generic.field[2])); + } + return sum; +} + +/* + * Process control tds, update USB request status and actual_length. + */ +static int process_ctrl_td(struct usbssp_udc *usbssp_data, struct usbssp_td *td, + union usbssp_trb *event_trb, + struct usbssp_transfer_event *event, + struct usbssp_ep *ep_priv, int *status) +{ + struct usbssp_device *dev_priv; + struct usbssp_ring *ep_ring; + unsigned int slot_id; + int ep_index; + struct usbssp_ep_ctx *ep_ctx; + u32 trb_comp_code; + u32 remaining, requested; + u32 trb_type; + + trb_type = TRB_FIELD_TO_TYPE(le32_to_cpu(event_trb->generic.field[3])); + slot_id = TRB_TO_SLOT_ID(le32_to_cpu(event->flags)); + dev_priv = &usbssp_data->devs; + ep_index = TRB_TO_EP_ID(le32_to_cpu(event->flags)) - 1; + ep_ring = usbssp_dma_to_transfer_ring(ep_priv, le64_to_cpu(event->buffer)); + ep_ctx = usbssp_get_ep_ctx(usbssp_data, dev_priv->out_ctx, ep_index); + trb_comp_code = GET_COMP_CODE(le32_to_cpu(event->transfer_len)); + requested = td->priv_request->request.length; + remaining = EVENT_TRB_LEN(le32_to_cpu(event->transfer_len)); + + switch (trb_comp_code) { + case COMP_SUCCESS: + *status = 0; + break; + case COMP_SHORT_PACKET: + *status = 0; + break; + case COMP_STOPPED_SHORT_PACKET: + if (trb_type == TRB_DATA || trb_type == TRB_NORMAL) + td->priv_request->request.actual = remaining; + goto finish_td; + case COMP_STOPPED: + switch (trb_type) { + case TRB_DATA: + case TRB_NORMAL: + td->priv_request->request.actual = requested - remaining; + goto finish_td; + case TRB_STATUS: + td->priv_request->request.actual = requested; + goto finish_td; + default: + dev_warn(usbssp_data->dev, + "WARN: unexpected TRB Type %d\n", + trb_type); + goto finish_td; + } + case COMP_STOPPED_LENGTH_INVALID: + goto finish_td; + default: + dev_dbg(usbssp_data->dev, "TRB error code %u, " + "halted endpoint index = %u\n", + trb_comp_code, ep_index); + } + + /* + * if on data stage then update the actual_length of the USB + * request and flag it as set, so it won't be overwritten in the event + * for the last TRB. + */ + if (trb_type == TRB_DATA || + trb_type == TRB_NORMAL) { + td->request_length_set = true; + td->priv_request->request.actual = requested - remaining; + } + + /* at status stage */ + if (!td->request_length_set) + td->priv_request->request.actual = requested; + + if (usbssp_data->ep0state == USBSSP_EP0_DATA_PHASE + && ep_priv->number == 0 + && usbssp_data->three_stage_setup) { + + td = list_entry(ep_ring->td_list.next, struct usbssp_td, td_list); + usbssp_data->ep0state = USBSSP_EP0_STATUS_PHASE; + dev_dbg(usbssp_data->dev, "Arm Status stage\n"); + giveback_first_trb(usbssp_data, ep_index, 0, + ep_ring->cycle_state, &td->last_trb->generic); + return 0; + } +finish_td: + return finish_td(usbssp_data, td, event, ep_priv, status); +} + +/* + * Process isochronous tds, update usb request status and actual_length. + */ +static int process_isoc_td(struct usbssp_udc *usbssp_data, struct usbssp_td *td, + union usbssp_trb *ep_trb, + struct usbssp_transfer_event *event, + struct usbssp_ep *ep_priv, int *status) +{ + /*TODO: this function must be implemented*/ + return 0; +} + +static int skip_isoc_td(struct usbssp_udc *usbssp_data, + struct usbssp_td *td, + struct usbssp_transfer_event *event, + struct usbssp_ep *ep_priv, + int *status) +{ + /*TODO: this function must be implemented*/ + return 0; +} + +/* + * Process bulk and interrupt tds, update usb request status and actual_length. + */ +static int process_bulk_intr_td(struct usbssp_udc *usbssp_data, + struct usbssp_td *td, + union usbssp_trb *ep_trb, + struct usbssp_transfer_event *event, + struct usbssp_ep *ep, int *status) +{ + struct usbssp_ring *ep_ring; + u32 trb_comp_code; + u32 remaining, requested, ep_trb_len; + + ep_ring = usbssp_dma_to_transfer_ring(ep, le64_to_cpu(event->buffer)); + trb_comp_code = GET_COMP_CODE(le32_to_cpu(event->transfer_len)); + remaining = EVENT_TRB_LEN(le32_to_cpu(event->transfer_len)); + ep_trb_len = TRB_LEN(le32_to_cpu(ep_trb->generic.field[2])); + requested = td->priv_request->request.length; + + switch (trb_comp_code) { + case COMP_SUCCESS: + /* handle success with untransferred data as short packet */ + if (ep_trb != td->last_trb || remaining) { + dev_warn(usbssp_data->dev, "WARN Successful completion " + "on short TX\n"); + dev_dbg(usbssp_data->dev, + "ep %#x - asked for %d bytes, %d bytes untransferred\n", + td->priv_request->dep->endpoint.desc->bEndpointAddress, + requested, remaining); + } + *status = 0; + break; + case COMP_SHORT_PACKET: + dev_dbg(usbssp_data->dev, + "ep %#x - asked for %d bytes, %d bytes untransferred\n", + td->priv_request->dep->endpoint.desc->bEndpointAddress, + requested, remaining); + + *status = 0; + break; + case COMP_STOPPED_SHORT_PACKET: + td->priv_request->request.length = remaining; + goto finish_td; + case COMP_STOPPED_LENGTH_INVALID: + /* stopped on ep trb with invalid length, exclude it */ + ep_trb_len = 0; + remaining = 0; + break; + default: + /* Others already handled above */ + break; + } + + if (ep_trb == td->last_trb) + td->priv_request->request.actual = requested - remaining; + else + td->priv_request->request.actual = + sum_trb_lengths(usbssp_data, ep_ring, ep_trb) + ep_trb_len - remaining; +finish_td: + if (remaining > requested) { + dev_warn(usbssp_data->dev, + "bad transfer trb length %d in event trb\n", + remaining); + td->priv_request->request.actual = 0; + } + + return finish_td(usbssp_data, td, event, ep, status); +} /* * If this function returns an error condition, it means it got a Transfer * event with a corrupted Slot ID, Endpoint ID, or TRB DMA address. @@ -1536,8 +1831,313 @@ int usbssp_is_vendor_info_code(struct usbssp_udc *usbssp_data, static int handle_tx_event(struct usbssp_udc *usbssp_data, struct usbssp_transfer_event *event) { - /*TODO: implement function handling transfer event*/ + struct usbssp_device *dev_priv; + struct usbssp_ep *ep_priv; + struct usbssp_ring *ep_ring; + unsigned int slot_id; + int ep_index; + struct usbssp_td *td = NULL; + dma_addr_t ep_trb_dma; + struct usbssp_segment *ep_seg; + union usbssp_trb *ep_trb; + int status = -EINPROGRESS; + struct usbssp_ep_ctx *ep_ctx; + struct list_head *tmp; + u32 trb_comp_code; + int ret = 0; + int td_num = 0; + bool handling_skipped_tds = false; + const struct usb_endpoint_descriptor *desc; + + slot_id = TRB_TO_SLOT_ID(le32_to_cpu(event->flags)); + ep_index = TRB_TO_EP_ID(le32_to_cpu(event->flags)) - 1; + trb_comp_code = GET_COMP_CODE(le32_to_cpu(event->transfer_len)); + ep_trb_dma = le64_to_cpu(event->buffer); + + dev_priv = &usbssp_data->devs; + + ep_priv = &dev_priv->eps[ep_index]; + ep_ring = usbssp_dma_to_transfer_ring(ep_priv, le64_to_cpu(event->buffer)); + ep_ctx = usbssp_get_ep_ctx(usbssp_data, dev_priv->out_ctx, ep_index); + + if (GET_EP_CTX_STATE(ep_ctx) == EP_STATE_DISABLED) { + dev_err(usbssp_data->dev, + "ERROR Transfer event for disabled endpoint slot %u ep %u\n", + slot_id, ep_index); + goto err_out; + } + + /* Some transfer events don't always point to a trb*/ + if (!ep_ring) { + switch (trb_comp_code) { + case COMP_USB_TRANSACTION_ERROR: + case COMP_INVALID_STREAM_TYPE_ERROR: + case COMP_INVALID_STREAM_ID_ERROR: + goto cleanup; + case COMP_RING_UNDERRUN: + case COMP_RING_OVERRUN: + goto cleanup; + default: + dev_err(usbssp_data->dev, "ERROR Transfer event for " + "unknown stream ring slot %u ep %u\n", + slot_id, ep_index); + goto err_out; + } + } + + /* Count current td numbers if ep->skip is set */ + if (ep_priv->skip) { + list_for_each(tmp, &ep_ring->td_list) + td_num++; + } + + /* Look for common error cases */ + switch (trb_comp_code) { + /* + * Skip codes that require special handling depending on + * transfer type + */ + case COMP_SUCCESS: + if (EVENT_TRB_LEN(le32_to_cpu(event->transfer_len)) == 0) + break; + + dev_warn_ratelimited(usbssp_data->dev, + "WARN Successful completion on short TX\n"); + case COMP_SHORT_PACKET: + break; + case COMP_STOPPED: + dev_dbg(usbssp_data->dev, "Stopped on Transfer TRB for ep %u\n", + ep_index); + break; + case COMP_STOPPED_LENGTH_INVALID: + dev_dbg(usbssp_data->dev, + "Stopped on No-op or Link TRB for ep %u\n", + ep_index); + break; + case COMP_STOPPED_SHORT_PACKET: + dev_dbg(usbssp_data->dev, + "Stopped with short packet transfer detected for ep %u\n", + ep_index); + break; + case COMP_BABBLE_DETECTED_ERROR: + dev_dbg(usbssp_data->dev, "Babble error for ep %u on endpoint\n", + ep_index); + status = -EOVERFLOW; + break; + case COMP_TRB_ERROR: + dev_warn(usbssp_data->dev, "WARN: TRB error on endpoint %u\n", + ep_index); + status = -EILSEQ; + break; + /* completion codes not indicating endpoint state change */ + case COMP_DATA_BUFFER_ERROR: + dev_warn(usbssp_data->dev, + "WARN: USBSSP couldn't access mem fast enough for ep %u\n", + ep_index); + status = -ENOSR; + break; + case COMP_ISOCH_BUFFER_OVERRUN: + dev_warn(usbssp_data->dev, + "WARN: buffer overrun event for ep %u on endpoint", + ep_index); + break; + case COMP_RING_UNDERRUN: + /* + * When the Isoch ring is empty, the DC will generate + * a Ring Overrun Event for IN Isoch endpoint or Ring + * Underrun Event for OUT Isoch endpoint. + */ + dev_dbg(usbssp_data->dev, "underrun event on endpoint\n"); + if (!list_empty(&ep_ring->td_list)) + dev_dbg(usbssp_data->dev, "Underrun Event for ep %d " + "still with TDs queued?\n", ep_index); + goto cleanup; + case COMP_RING_OVERRUN: + dev_dbg(usbssp_data->dev, "overrun event on endpoint\n"); + if (!list_empty(&ep_ring->td_list)) + dev_dbg(usbssp_data->dev, "Overrun Event for ep %d " + "still with TDs queued?\n", + ep_index); + goto cleanup; + case COMP_MISSED_SERVICE_ERROR: + /* + * When encounter missed service error, one or more isoc tds + * may be missed by DC. + * Set skip flag of the ep_ring; Complete the missed tds as + * short transfer when process the ep_ring next time. + */ + ep_priv->skip = true; + dev_dbg(usbssp_data->dev, + "Miss service interval error for ep %u, set skip flag\n", + ep_index); + goto cleanup; + case COMP_INCOMPATIBLE_DEVICE_ERROR: + /* needs disable slot command to recover */ + dev_warn(usbssp_data->dev, + "WARN: detect an incompatible device for ep %u", + ep_index); + status = -EPROTO; + break; + default: + if (usbssp_is_vendor_info_code(usbssp_data, trb_comp_code)) { + status = 0; + break; + } + + dev_warn(usbssp_data->dev, + "ERROR Unknown event condition %u, for ep %u - USBSSP probably busted\n", + trb_comp_code, ep_index); + goto cleanup; + } + + do { + /* + * This TRB should be in the TD at the head of this ring's TD + * list. + */ + if (list_empty(&ep_ring->td_list)) { + /* + * Don't print wanings if it's due to a stopped endpoint + * generating an extra completion event if the device + * was suspended. Or, a event for the last TRB of a + * short TD we already got a short event for. + * The short TD is already removed from the TD list. + */ + if (!(trb_comp_code == COMP_STOPPED || + trb_comp_code == COMP_STOPPED_LENGTH_INVALID || + ep_ring->last_td_was_short)) { + dev_warn(usbssp_data->dev, + "WARN Event TRB for ep %d with no TDs queued?\n", + ep_index); + } + + if (ep_priv->skip) { + ep_priv->skip = false; + dev_dbg(usbssp_data->dev, + "td_list is empty while skip " + "flag set. Clear skip flag for ep %u.\n", + ep_index); + } + goto cleanup; + } + + /* We've skipped all the TDs on the ep ring when ep->skip set */ + if (ep_priv->skip && td_num == 0) { + ep_priv->skip = false; + dev_dbg(usbssp_data->dev, + "All tds on the ep_ring skipped. " + "Clear skip flag for ep %u.\n", ep_index); + goto cleanup; + } + + td = list_entry(ep_ring->td_list.next, struct usbssp_td, td_list); + + if (ep_priv->skip) + td_num--; + + /* Is this a TRB in the currently executing TD? */ + ep_seg = usbssp_trb_in_td(usbssp_data, ep_ring->deq_seg, + ep_ring->dequeue, td->last_trb, + ep_trb_dma, false); + + /* + * Skip the Force Stopped Event. The event_trb(ep_trb_dma) + * of FSE is not in the current TD pointed by ep_ring->dequeue + * because that the hardware dequeue pointer still at the + * previous TRB of the current TD. The previous TRB maybe a + * Link TD or the last TRB of the previous TD. The command + * completion handle will take care the rest. + */ + if (!ep_seg && (trb_comp_code == COMP_STOPPED || + trb_comp_code == COMP_STOPPED_LENGTH_INVALID)) { + goto cleanup; + } + + desc = td->priv_request->dep->endpoint.desc; + if (!ep_seg) { + if (!ep_priv->skip || !usb_endpoint_xfer_isoc(desc)) { + + /* USBSSP is busted, give up! */ + dev_err(usbssp_data->dev, + "ERROR Transfer event TRB DMA ptr not " + "part of current TD ep_index %d " + "comp_code %u\n", ep_index, + trb_comp_code); + + usbssp_trb_in_td(usbssp_data, ep_ring->deq_seg, + ep_ring->dequeue, td->last_trb, + ep_trb_dma, true); + return -ESHUTDOWN; + } + + ret = skip_isoc_td(usbssp_data, td, event, ep_priv, + &status); + goto cleanup; + } + + if (trb_comp_code == COMP_SHORT_PACKET) + ep_ring->last_td_was_short = true; + else + ep_ring->last_td_was_short = false; + + if (ep_priv->skip) { + dev_dbg(usbssp_data->dev, + "Found td. Clear skip flag for ep %u.\n", + ep_index); + ep_priv->skip = false; + } + + ep_trb = &ep_seg->trbs[(ep_trb_dma - ep_seg->dma) / sizeof(*ep_trb)]; + + trace_usbssp_handle_transfer(ep_ring, + (struct usbssp_generic_trb *) ep_trb); + + if (trb_is_noop(ep_trb)) { + dev_dbg(usbssp_data->dev, + "event_trb is a no-op TRB. Skip it\n"); + goto cleanup; + } + + if (usb_endpoint_xfer_control(desc)) { + ret = process_ctrl_td(usbssp_data, td, ep_trb, event, + ep_priv, &status); + } else if (usb_endpoint_xfer_isoc(desc)) { + ret = process_isoc_td(usbssp_data, td, ep_trb, + event, ep_priv, &status); + } else { + ret = process_bulk_intr_td(usbssp_data, td, ep_trb, + event, ep_priv, &status); + } +cleanup: + handling_skipped_tds = ep_priv->skip && + trb_comp_code != COMP_MISSED_SERVICE_ERROR; + + /* + * Do not update event ring dequeue pointer if we're in a loop + * processing missed tds. + */ + if (!handling_skipped_tds) + inc_deq(usbssp_data, usbssp_data->event_ring); + /* + * If ep->skip is set, it means there are missed tds on the + * endpoint ring need to take care of. + * Process them as short transfer until reach the td pointed by + * the event. + */ + } while (handling_skipped_tds); + return 0; + +err_out: + dev_err(usbssp_data->dev, "@%016llx %08x %08x %08x %08x\n", + (unsigned long long) usbssp_trb_virt_to_dma( + usbssp_data->event_ring->deq_seg, + usbssp_data->event_ring->dequeue), + lower_32_bits(le64_to_cpu(event->buffer)), + upper_32_bits(le64_to_cpu(event->buffer)), + le32_to_cpu(event->transfer_len), + le32_to_cpu(event->flags)); + return -ENODEV; } /* diff --git a/drivers/usb/usbssp/gadget.h b/drivers/usb/usbssp/gadget.h index 000f2cb93723..c4e440db6b23 100644 --- a/drivers/usb/usbssp/gadget.h +++ b/drivers/usb/usbssp/gadget.h @@ -1699,6 +1699,11 @@ int usbssp_ring_expansion(struct usbssp_udc *usbssp_data, struct usbssp_ring *usbssp_stream_id_to_ring(struct usbssp_device *dev, unsigned int ep_index, unsigned int stream_id); +struct usbssp_ring *usbssp_dma_to_transfer_ring(struct usbssp_ep *ep, + u64 address); +struct usbssp_ring *usbssp_stream_id_to_ring(struct usbssp_device *dev, + unsigned int ep_index, + unsigned int stream_id); struct usbssp_command *usbssp_alloc_command(struct usbssp_udc *usbssp_data, bool allocate_completion, -- 2.17.1 From mboxrd@z Thu Jan 1 00:00:00 1970 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: base64 Subject: [23/31] usb: usbssp: added implementation of transfer events. From: Pawel Laszczak Message-Id: <1532023084-28083-24-git-send-email-pawell@cadence.com> Date: Thu, 19 Jul 2018 18:57:56 +0100 Cc: Greg Kroah-Hartman , linux-usb@vger.kernel.org, Felipe Balbi , linux-kernel@vger.kernel.org, ltyrala@cadence.com, adouglas@cadence.com, pawell@cadence.com List-ID: UGF0Y2ggYWRkIGZ1bmN0aW9uYWxpdHkgcmVsYXRlZCB0byBoYW5kbGluZyB0cmFuc2ZlciBldmVu dHMuClRoaXMga2luZCBvZiBldmVudHMgYXJlIGFkZGVkIHRvIGV2ZW50IHJpbmcgYWZ0ZXIgY29t cGxldGlvbiB0cmFuc2Zlci4KClRoaXMgcGF0Y2ggYWRkIHN1cHBvcnRzIGZvciBoYW5kbGluZyB0 cmFuc2ZlciBldmVudHMgb25seSBmb3IKY29udHJvbCwgaW50ZXJydXB0IGFuZCBidWxrIHRyYW5z ZmVyLgoKQWZ0ZXIgdGhlIHRyYW5zZmVyLCB1c2Jzc3AgZHJpdmVyIHJlbGVhc2UgdGhlIFREIGFu ZCBpbmZvcm1zIGFib3V0IGl0CmdhZGdldCBjb3JlIGRyaXZlciBieSBtZWFucyBvZiB1c2Jzc3Bf Z2FkZ2V0X2dpdmViYWNrIGZ1bmN0aW9uLgoKU2lnbmVkLW9mZi1ieTogUGF3ZWwgTGFzemN6YWsg PHBhd2VsbEBjYWRlbmNlLmNvbT4KLS0tCiBkcml2ZXJzL3VzYi91c2Jzc3AvZ2FkZ2V0LW1lbS5j ICB8ICAgOSArCiBkcml2ZXJzL3VzYi91c2Jzc3AvZ2FkZ2V0LXJpbmcuYyB8IDYwMiArKysrKysr KysrKysrKysrKysrKysrKysrKysrKystCiBkcml2ZXJzL3VzYi91c2Jzc3AvZ2FkZ2V0LmggICAg ICB8ICAgNSArCiAzIGZpbGVzIGNoYW5nZWQsIDYxNSBpbnNlcnRpb25zKCspLCAxIGRlbGV0aW9u KC0pCgpkaWZmIC0tZ2l0IGEvZHJpdmVycy91c2IvdXNic3NwL2dhZGdldC1tZW0uYyBiL2RyaXZl cnMvdXNiL3VzYnNzcC9nYWRnZXQtbWVtLmMKaW5kZXggODU4YmVlNzdiMGRjLi5kNWQ3MzJiOTQ0 NTQgMTAwNjQ0Ci0tLSBhL2RyaXZlcnMvdXNiL3VzYnNzcC9nYWRnZXQtbWVtLmMKKysrIGIvZHJp dmVycy91c2IvdXNic3NwL2dhZGdldC1tZW0uYwpAQCAtNTU1LDYgKzU1NSwxNSBAQCBzdGF0aWMg dm9pZCB1c2Jzc3BfZnJlZV9zdHJlYW1fY3R4KHN0cnVjdCB1c2Jzc3BfdWRjICp1c2Jzc3BfZGF0 YSwKIAkJCQlzdHJlYW1fY3R4LCBkbWEpOwogfQogCitzdHJ1Y3QgdXNic3NwX3JpbmcgKnVzYnNz cF9kbWFfdG9fdHJhbnNmZXJfcmluZyhzdHJ1Y3QgdXNic3NwX2VwICplcCwKKwkJCQkJCXU2NCBh ZGRyZXNzKQoreworCWlmIChlcC0+ZXBfc3RhdGUgJiBFUF9IQVNfU1RSRUFNUykKKwkJcmV0dXJu IHJhZGl4X3RyZWVfbG9va3VwKCZlcC0+c3RyZWFtX2luZm8tPnRyYl9hZGRyZXNzX21hcCwKKwkJ CQkJIGFkZHJlc3MgPj4gVFJCX1NFR01FTlRfU0hJRlQpOworCXJldHVybiBlcC0+cmluZzsKK30K Kwogc3RydWN0IHVzYnNzcF9yaW5nICp1c2Jzc3Bfc3RyZWFtX2lkX3RvX3Jpbmcoc3RydWN0IHVz YnNzcF9kZXZpY2UgKmRldiwKIAkJCQkJICAgICB1bnNpZ25lZCBpbnQgZXBfaW5kZXgsCiAJCQkJ CSAgICAgdW5zaWduZWQgaW50IHN0cmVhbV9pZCkKZGlmZiAtLWdpdCBhL2RyaXZlcnMvdXNiL3Vz YnNzcC9nYWRnZXQtcmluZy5jIGIvZHJpdmVycy91c2IvdXNic3NwL2dhZGdldC1yaW5nLmMKaW5k ZXggY2ZiMzExMjBlZWY4Li44Y2M2ZTQyNDdlZWYgMTAwNjQ0Ci0tLSBhL2RyaXZlcnMvdXNiL3Vz YnNzcC9nYWRnZXQtcmluZy5jCisrKyBiL2RyaXZlcnMvdXNiL3VzYnNzcC9nYWRnZXQtcmluZy5j CkBAIC02Miw2ICs2MiwxMyBAQAogI2luY2x1ZGUgImdhZGdldC10cmFjZS5oIgogI2luY2x1ZGUg ImdhZGdldC5oIgogCitzdGF0aWMgdm9pZCBnaXZlYmFja19maXJzdF90cmIoc3RydWN0IHVzYnNz cF91ZGMgKnVzYnNzcF9kYXRhLAorCQkJICAgICAgIHVuc2lnbmVkIGludCBlcF9pbmRleCwKKwkJ CSAgICAgICB1bnNpZ25lZCBpbnQgc3RyZWFtX2lkLAorCQkJICAgICAgIGludCBzdGFydF9jeWNs ZSwKKwkJCSAgICAgICBzdHJ1Y3QgdXNic3NwX2dlbmVyaWNfdHJiCisJCQkgICAgICAgKnN0YXJ0 X3RyYik7CisKIC8qCiAgKiBSZXR1cm5zIHplcm8gaWYgdGhlIFRSQiBpc24ndCBpbiB0aGlzIHNl Z21lbnQsIG90aGVyd2lzZSBpdCByZXR1cm5zIHRoZSBETUEKICAqIGFkZHJlc3Mgb2YgdGhlIFRS Qi4KQEAgLTgwLDYgKzg3LDExIEBAIGRtYV9hZGRyX3QgdXNic3NwX3RyYl92aXJ0X3RvX2RtYShz dHJ1Y3QgdXNic3NwX3NlZ21lbnQgKnNlZywKIAlyZXR1cm4gc2VnLT5kbWEgKyAoc2VnbWVudF9v ZmZzZXQgKiBzaXplb2YoKnRyYikpOwogfQogCitzdGF0aWMgYm9vbCB0cmJfaXNfbm9vcCh1bmlv biB1c2Jzc3BfdHJiICp0cmIpCit7CisJcmV0dXJuIFRSQl9UWVBFX05PT1BfTEUzMih0cmItPmdl bmVyaWMuZmllbGRbM10pOworfQorCiBzdGF0aWMgYm9vbCB0cmJfaXNfbGluayh1bmlvbiB1c2Jz c3BfdHJiICp0cmIpCiB7CiAJcmV0dXJuIFRSQl9UWVBFX0xJTktfTEUzMih0cmItPmxpbmsuY29u dHJvbCk7CkBAIC0xNTI4LDYgKzE1NDAsMjg5IEBAIGludCB1c2Jzc3BfaXNfdmVuZG9yX2luZm9f Y29kZShzdHJ1Y3QgdXNic3NwX3VkYyAqdXNic3NwX2RhdGEsCiAJcmV0dXJuIDA7CiB9CiAKK3N0 YXRpYyBpbnQgdXNic3NwX3RkX2NsZWFudXAoc3RydWN0IHVzYnNzcF91ZGMgKnVzYnNzcF9kYXRh LAorCQkJICAgICBzdHJ1Y3QgdXNic3NwX3RkICp0ZCwgc3RydWN0IHVzYnNzcF9yaW5nICplcF9y aW5nLAorCQkJICAgICBpbnQgKnN0YXR1cykKK3sKKwlzdHJ1Y3QgdXNic3NwX3JlcXVlc3QgKnJl cV9wcml2ID0gTlVMTDsKKworCS8qIENsZWFuIHVwIHRoZSBlbmRwb2ludCdzIFREIGxpc3QgKi8K KwlyZXFfcHJpdiA9IHRkLT5wcml2X3JlcXVlc3Q7CisKKwkvKiBpZiBhIGJvdW5jZSBidWZmZXIg d2FzIHVzZWQgdG8gYWxpZ24gdGhpcyB0ZCB0aGVuIHVubWFwIGl0ICovCisJdXNic3NwX3VubWFw X3RkX2JvdW5jZV9idWZmZXIodXNic3NwX2RhdGEsIGVwX3JpbmcsIHRkKTsKKworCS8qCisJICog RG8gb25lIGxhc3QgY2hlY2sgb2YgdGhlIGFjdHVhbCB0cmFuc2ZlciBsZW5ndGguCisJICogSWYg dGhlIERDIGNvbnRyb2xsZXIgc2FpZCB3ZSB0cmFuc2ZlcnJlZCBtb3JlIGRhdGEgdGhhbiB0aGUg YnVmZmVyCisJICogbGVuZ3RoLCByZXFfcHJpdi0+cmVxdWVzdC5hY3R1YWwgd2lsbCBiZSBhIHZl cnkgYmlnIG51bWJlciAoc2luY2UgaXQncworCSAqIHVuc2lnbmVkKS4gUGxheSBpdCBzYWZlIGFu ZCBzYXkgd2UgZGlkbid0IHRyYW5zZmVyIGFueXRoaW5nLgorCSAqLworCWlmIChyZXFfcHJpdi0+ cmVxdWVzdC5hY3R1YWwgPiByZXFfcHJpdi0+cmVxdWVzdC5sZW5ndGgpIHsKKwkJZGV2X3dhcm4o dXNic3NwX2RhdGEtPmRldiwKKwkJCSJVU0IgcmVxICV1IGFuZCBhY3R1YWwgJXUgdHJhbnNmZXIg bGVuZ3RoIG1pc21hdGNoXG4iLAorCQkJcmVxX3ByaXYtPnJlcXVlc3QubGVuZ3RoLCByZXFfcHJp di0+cmVxdWVzdC5hY3R1YWwpOworCQlyZXFfcHJpdi0+cmVxdWVzdC5hY3R1YWwgPSAwOworCQkq c3RhdHVzID0gMDsKKwl9CisJbGlzdF9kZWxfaW5pdCgmdGQtPnRkX2xpc3QpOworCisJaW5jX3Rk X2NudChyZXFfcHJpdik7CisJLyogR2l2ZWJhY2sgdGhlIFVTQiByZXF1ZXN0IHdoZW4gYWxsIHRo ZSB0ZHMgYXJlIGNvbXBsZXRlZCAqLworCWlmIChsYXN0X3RkX2luX3JlcXVlc3QodGQpKSB7CisJ CWlmICgocmVxX3ByaXYtPnJlcXVlc3QuYWN0dWFsICE9IHJlcV9wcml2LT5yZXF1ZXN0Lmxlbmd0 aCAmJgorCQkgICAgdGQtPnByaXZfcmVxdWVzdC0+cmVxdWVzdC5zaG9ydF9ub3Rfb2spIHx8ICgq c3RhdHVzICE9IDAgJiYKKwkJICAgICF1c2JfZW5kcG9pbnRfeGZlcl9pc29jKHJlcV9wcml2LT5k ZXAtPmVuZHBvaW50LmRlc2MpKSkKKwkJCWRldl9kYmcodXNic3NwX2RhdGEtPmRldiwKKwkJCQki R2l2ZWJhY2sgUmVxdWVzdCAlcCwgbGVuID0gJWQsIGV4cGVjdGVkID0gJWQiCisJCQkJIiBzdGF0 dXMgPSAlZFxuIiwKKwkJCQlyZXFfcHJpdiwgcmVxX3ByaXYtPnJlcXVlc3QuYWN0dWFsLAorCQkJ CXJlcV9wcml2LT5yZXF1ZXN0Lmxlbmd0aCwgKnN0YXR1cyk7CisKKwkJaWYgKHVzYl9lbmRwb2lu dF94ZmVyX2lzb2MocmVxX3ByaXYtPmRlcC0+ZW5kcG9pbnQuZGVzYykpCisJCQkqc3RhdHVzID0g MDsKKworCQl1c2Jzc3BfZ2l2ZWJhY2tfcmVxdWVzdF9pbl9pcnEodXNic3NwX2RhdGEsIHRkLCAq c3RhdHVzKTsKKwl9CisKKwlyZXR1cm4gMDsKK30KKworc3RhdGljIGludCBmaW5pc2hfdGQoc3Ry dWN0IHVzYnNzcF91ZGMgKnVzYnNzcF9kYXRhLCBzdHJ1Y3QgdXNic3NwX3RkICp0ZCwKKwkJICAg ICBzdHJ1Y3QgdXNic3NwX3RyYW5zZmVyX2V2ZW50ICpldmVudCwgc3RydWN0IHVzYnNzcF9lcCAq ZXAsCisJCSAgICAgaW50ICpzdGF0dXMpCit7CisJc3RydWN0IHVzYnNzcF9kZXZpY2UgKmRldl9w cml2OworCXN0cnVjdCB1c2Jzc3BfcmluZyAqZXBfcmluZzsKKwl1bnNpZ25lZCBpbnQgc2xvdF9p ZDsKKwlpbnQgZXBfaW5kZXg7CisJc3RydWN0IHVzYnNzcF9lcF9jdHggKmVwX2N0eDsKKwl1MzIg dHJiX2NvbXBfY29kZTsKKworCXNsb3RfaWQgPSBUUkJfVE9fU0xPVF9JRChsZTMyX3RvX2NwdShl dmVudC0+ZmxhZ3MpKTsKKwlkZXZfcHJpdiA9ICZ1c2Jzc3BfZGF0YS0+ZGV2czsKKwllcF9pbmRl eCA9IFRSQl9UT19FUF9JRChsZTMyX3RvX2NwdShldmVudC0+ZmxhZ3MpKSAtIDE7CisJZXBfcmlu ZyA9IHVzYnNzcF9kbWFfdG9fdHJhbnNmZXJfcmluZyhlcCwgbGU2NF90b19jcHUoZXZlbnQtPmJ1 ZmZlcikpOworCWVwX2N0eCA9IHVzYnNzcF9nZXRfZXBfY3R4KHVzYnNzcF9kYXRhLCBkZXZfcHJp di0+b3V0X2N0eCwgZXBfaW5kZXgpOworCXRyYl9jb21wX2NvZGUgPSBHRVRfQ09NUF9DT0RFKGxl MzJfdG9fY3B1KGV2ZW50LT50cmFuc2Zlcl9sZW4pKTsKKworCWlmICh0cmJfY29tcF9jb2RlID09 IENPTVBfU1RPUFBFRF9MRU5HVEhfSU5WQUxJRCB8fAorCSAgICB0cmJfY29tcF9jb2RlID09IENP TVBfU1RPUFBFRCB8fAorCSAgICB0cmJfY29tcF9jb2RlID09IENPTVBfU1RPUFBFRF9TSE9SVF9Q QUNLRVQpIHsKKwkJLyoKKwkJICogVGhlIEVuZHBvaW50IFN0b3AgQ29tbWFuZCBjb21wbGV0aW9u IHdpbGwgdGFrZSBjYXJlIG9mIGFueQorCQkgKiBzdG9wcGVkIFREcy4gQSBzdG9wcGVkIFREIG1h eSBiZSByZXN0YXJ0ZWQsIHNvIGRvbid0IHVwZGF0ZQorCQkgKiB0aGUgcmluZyBkZXF1ZXVlIHBv aW50ZXIgb3IgdGFrZSB0aGlzIFREIG9mZiBhbnkgbGlzdHMgeWV0LgorCQkgKi8KKwkJcmV0dXJu IDA7CisJfQorCisJLyogVXBkYXRlIHJpbmcgZGVxdWV1ZSBwb2ludGVyICovCisJd2hpbGUgKGVw X3JpbmctPmRlcXVldWUgIT0gdGQtPmxhc3RfdHJiKQorCQlpbmNfZGVxKHVzYnNzcF9kYXRhLCBl cF9yaW5nKTsKKworCWluY19kZXEodXNic3NwX2RhdGEsIGVwX3JpbmcpOworCisJcmV0dXJuIHVz YnNzcF90ZF9jbGVhbnVwKHVzYnNzcF9kYXRhLCB0ZCwgZXBfcmluZywgc3RhdHVzKTsKK30KKwor Lyogc3VtIHRyYiBsZW5ndGhzIGZyb20gcmluZyBkZXF1ZXVlIHVwIHRvIHN0b3BfdHJiLCBfZXhj bHVkaW5nXyBzdG9wX3RyYiAqLworc3RhdGljIGludCBzdW1fdHJiX2xlbmd0aHMoc3RydWN0IHVz YnNzcF91ZGMgKnVzYnNzcF9kYXRhLAorCQkJICAgc3RydWN0IHVzYnNzcF9yaW5nICpyaW5nLAor CQkJICAgdW5pb24gdXNic3NwX3RyYiAqc3RvcF90cmIpCit7CisJdTMyIHN1bTsKKwl1bmlvbiB1 c2Jzc3BfdHJiICp0cmIgPSByaW5nLT5kZXF1ZXVlOworCXN0cnVjdCB1c2Jzc3Bfc2VnbWVudCAq c2VnID0gcmluZy0+ZGVxX3NlZzsKKworCWZvciAoc3VtID0gMDsgdHJiICE9IHN0b3BfdHJiOyBu ZXh0X3RyYih1c2Jzc3BfZGF0YSwgcmluZywgJnNlZywgJnRyYikpIHsKKwkJaWYgKCF0cmJfaXNf bm9vcCh0cmIpICYmICF0cmJfaXNfbGluayh0cmIpKQorCQkJc3VtICs9IFRSQl9MRU4obGUzMl90 b19jcHUodHJiLT5nZW5lcmljLmZpZWxkWzJdKSk7CisJfQorCXJldHVybiBzdW07Cit9CisKKy8q CisgKiBQcm9jZXNzIGNvbnRyb2wgdGRzLCB1cGRhdGUgVVNCIHJlcXVlc3Qgc3RhdHVzIGFuZCBh Y3R1YWxfbGVuZ3RoLgorICovCitzdGF0aWMgaW50IHByb2Nlc3NfY3RybF90ZChzdHJ1Y3QgdXNi c3NwX3VkYyAqdXNic3NwX2RhdGEsIHN0cnVjdCB1c2Jzc3BfdGQgKnRkLAorCQkJICAgdW5pb24g dXNic3NwX3RyYiAqZXZlbnRfdHJiLAorCQkJICAgc3RydWN0IHVzYnNzcF90cmFuc2Zlcl9ldmVu dCAqZXZlbnQsCisJCQkgICBzdHJ1Y3QgdXNic3NwX2VwICplcF9wcml2LCBpbnQgKnN0YXR1cykK K3sKKwlzdHJ1Y3QgdXNic3NwX2RldmljZSAqZGV2X3ByaXY7CisJc3RydWN0IHVzYnNzcF9yaW5n ICplcF9yaW5nOworCXVuc2lnbmVkIGludCBzbG90X2lkOworCWludCBlcF9pbmRleDsKKwlzdHJ1 Y3QgdXNic3NwX2VwX2N0eCAqZXBfY3R4OworCXUzMiB0cmJfY29tcF9jb2RlOworCXUzMiByZW1h aW5pbmcsIHJlcXVlc3RlZDsKKwl1MzIgdHJiX3R5cGU7CisKKwl0cmJfdHlwZSA9IFRSQl9GSUVM RF9UT19UWVBFKGxlMzJfdG9fY3B1KGV2ZW50X3RyYi0+Z2VuZXJpYy5maWVsZFszXSkpOworCXNs b3RfaWQgPSBUUkJfVE9fU0xPVF9JRChsZTMyX3RvX2NwdShldmVudC0+ZmxhZ3MpKTsKKwlkZXZf cHJpdiA9ICZ1c2Jzc3BfZGF0YS0+ZGV2czsKKwllcF9pbmRleCA9IFRSQl9UT19FUF9JRChsZTMy X3RvX2NwdShldmVudC0+ZmxhZ3MpKSAtIDE7CisJZXBfcmluZyA9IHVzYnNzcF9kbWFfdG9fdHJh bnNmZXJfcmluZyhlcF9wcml2LCBsZTY0X3RvX2NwdShldmVudC0+YnVmZmVyKSk7CisJZXBfY3R4 ID0gdXNic3NwX2dldF9lcF9jdHgodXNic3NwX2RhdGEsIGRldl9wcml2LT5vdXRfY3R4LCBlcF9p bmRleCk7CisJdHJiX2NvbXBfY29kZSA9IEdFVF9DT01QX0NPREUobGUzMl90b19jcHUoZXZlbnQt PnRyYW5zZmVyX2xlbikpOworCXJlcXVlc3RlZCA9IHRkLT5wcml2X3JlcXVlc3QtPnJlcXVlc3Qu bGVuZ3RoOworCXJlbWFpbmluZyA9IEVWRU5UX1RSQl9MRU4obGUzMl90b19jcHUoZXZlbnQtPnRy YW5zZmVyX2xlbikpOworCisJc3dpdGNoICh0cmJfY29tcF9jb2RlKSB7CisJY2FzZSBDT01QX1NV Q0NFU1M6CisJCSpzdGF0dXMgPSAwOworCQlicmVhazsKKwljYXNlIENPTVBfU0hPUlRfUEFDS0VU OgorCQkqc3RhdHVzID0gMDsKKwkJYnJlYWs7CisJY2FzZSBDT01QX1NUT1BQRURfU0hPUlRfUEFD S0VUOgorCQlpZiAodHJiX3R5cGUgPT0gVFJCX0RBVEEgfHwgdHJiX3R5cGUgPT0gVFJCX05PUk1B TCkKKwkJCXRkLT5wcml2X3JlcXVlc3QtPnJlcXVlc3QuYWN0dWFsID0gcmVtYWluaW5nOworCWdv dG8gZmluaXNoX3RkOworCWNhc2UgQ09NUF9TVE9QUEVEOgorCQlzd2l0Y2ggKHRyYl90eXBlKSB7 CisJCWNhc2UgVFJCX0RBVEE6CisJCWNhc2UgVFJCX05PUk1BTDoKKwkJCXRkLT5wcml2X3JlcXVl c3QtPnJlcXVlc3QuYWN0dWFsID0gcmVxdWVzdGVkIC0gcmVtYWluaW5nOworCQkJZ290byBmaW5p c2hfdGQ7CisJCWNhc2UgVFJCX1NUQVRVUzoKKwkJCXRkLT5wcml2X3JlcXVlc3QtPnJlcXVlc3Qu YWN0dWFsID0gcmVxdWVzdGVkOworCQkJZ290byBmaW5pc2hfdGQ7CisJCWRlZmF1bHQ6CisJCQlk ZXZfd2Fybih1c2Jzc3BfZGF0YS0+ZGV2LAorCQkJCSJXQVJOOiB1bmV4cGVjdGVkIFRSQiBUeXBl ICVkXG4iLAorCQkJCXRyYl90eXBlKTsKKwkJCWdvdG8gZmluaXNoX3RkOworCQl9CisJY2FzZSBD T01QX1NUT1BQRURfTEVOR1RIX0lOVkFMSUQ6CisJCWdvdG8gZmluaXNoX3RkOworCWRlZmF1bHQ6 CisJCWRldl9kYmcodXNic3NwX2RhdGEtPmRldiwgIlRSQiBlcnJvciBjb2RlICV1LCAiCisJCQki aGFsdGVkIGVuZHBvaW50IGluZGV4ID0gJXVcbiIsCisJCQl0cmJfY29tcF9jb2RlLCBlcF9pbmRl eCk7CisJfQorCisJLyoKKwkgKiBpZiBvbiBkYXRhIHN0YWdlIHRoZW4gdXBkYXRlIHRoZSBhY3R1 YWxfbGVuZ3RoIG9mIHRoZSBVU0IKKwkgKiByZXF1ZXN0IGFuZCBmbGFnIGl0IGFzIHNldCwgc28g aXQgd29uJ3QgYmUgb3ZlcndyaXR0ZW4gaW4gdGhlIGV2ZW50CisJICogZm9yIHRoZSBsYXN0IFRS Qi4KKwkgKi8KKwlpZiAodHJiX3R5cGUgPT0gVFJCX0RBVEEgfHwKKwkgICAgdHJiX3R5cGUgPT0g VFJCX05PUk1BTCkgeworCQl0ZC0+cmVxdWVzdF9sZW5ndGhfc2V0ID0gdHJ1ZTsKKwkJdGQtPnBy aXZfcmVxdWVzdC0+cmVxdWVzdC5hY3R1YWwgPSByZXF1ZXN0ZWQgLSByZW1haW5pbmc7CisJfQor CisJLyogYXQgc3RhdHVzIHN0YWdlICovCisJaWYgKCF0ZC0+cmVxdWVzdF9sZW5ndGhfc2V0KQor CQl0ZC0+cHJpdl9yZXF1ZXN0LT5yZXF1ZXN0LmFjdHVhbCA9IHJlcXVlc3RlZDsKKworCWlmICh1 c2Jzc3BfZGF0YS0+ZXAwc3RhdGUgPT0gVVNCU1NQX0VQMF9EQVRBX1BIQVNFCisJICAgJiYgZXBf cHJpdi0+bnVtYmVyID09IDAKKwkgICAmJiB1c2Jzc3BfZGF0YS0+dGhyZWVfc3RhZ2Vfc2V0dXAp IHsKKworCQl0ZCA9IGxpc3RfZW50cnkoZXBfcmluZy0+dGRfbGlzdC5uZXh0LCBzdHJ1Y3QgdXNi c3NwX3RkLCB0ZF9saXN0KTsKKwkJdXNic3NwX2RhdGEtPmVwMHN0YXRlID0gVVNCU1NQX0VQMF9T VEFUVVNfUEhBU0U7CisJCWRldl9kYmcodXNic3NwX2RhdGEtPmRldiwgIkFybSBTdGF0dXMgc3Rh Z2VcbiIpOworCQlnaXZlYmFja19maXJzdF90cmIodXNic3NwX2RhdGEsIGVwX2luZGV4LCAwLAor CQkJCWVwX3JpbmctPmN5Y2xlX3N0YXRlLCAmdGQtPmxhc3RfdHJiLT5nZW5lcmljKTsKKwkJcmV0 dXJuIDA7CisJfQorZmluaXNoX3RkOgorCXJldHVybiBmaW5pc2hfdGQodXNic3NwX2RhdGEsIHRk LCBldmVudCwgZXBfcHJpdiwgc3RhdHVzKTsKK30KKworLyoKKyAqIFByb2Nlc3MgaXNvY2hyb25v dXMgdGRzLCB1cGRhdGUgdXNiIHJlcXVlc3Qgc3RhdHVzIGFuZCBhY3R1YWxfbGVuZ3RoLgorICov CitzdGF0aWMgaW50IHByb2Nlc3NfaXNvY190ZChzdHJ1Y3QgdXNic3NwX3VkYyAqdXNic3NwX2Rh dGEsIHN0cnVjdCB1c2Jzc3BfdGQgKnRkLAorCQkJICAgdW5pb24gdXNic3NwX3RyYiAqZXBfdHJi LAorCQkJICAgc3RydWN0IHVzYnNzcF90cmFuc2Zlcl9ldmVudCAqZXZlbnQsCisJCQkgICBzdHJ1 Y3QgdXNic3NwX2VwICplcF9wcml2LCBpbnQgKnN0YXR1cykKK3sKKwkvKlRPRE86IHRoaXMgZnVu Y3Rpb24gbXVzdCBiZSBpbXBsZW1lbnRlZCovCisJcmV0dXJuIDA7Cit9CisKK3N0YXRpYyBpbnQg c2tpcF9pc29jX3RkKHN0cnVjdCB1c2Jzc3BfdWRjICp1c2Jzc3BfZGF0YSwKKwkJCXN0cnVjdCB1 c2Jzc3BfdGQgKnRkLAorCQkJc3RydWN0IHVzYnNzcF90cmFuc2Zlcl9ldmVudCAqZXZlbnQsCisJ CQlzdHJ1Y3QgdXNic3NwX2VwICplcF9wcml2LAorCQkJaW50ICpzdGF0dXMpCit7CisJLypUT0RP OiB0aGlzIGZ1bmN0aW9uIG11c3QgYmUgaW1wbGVtZW50ZWQqLworCXJldHVybiAwOworfQorCisv KgorICogUHJvY2VzcyBidWxrIGFuZCBpbnRlcnJ1cHQgdGRzLCB1cGRhdGUgdXNiIHJlcXVlc3Qg c3RhdHVzIGFuZCBhY3R1YWxfbGVuZ3RoLgorICovCitzdGF0aWMgaW50IHByb2Nlc3NfYnVsa19p bnRyX3RkKHN0cnVjdCB1c2Jzc3BfdWRjICp1c2Jzc3BfZGF0YSwKKwkJCQlzdHJ1Y3QgdXNic3Nw X3RkICp0ZCwKKwkJCQl1bmlvbiB1c2Jzc3BfdHJiICplcF90cmIsCisJCQkJc3RydWN0IHVzYnNz cF90cmFuc2Zlcl9ldmVudCAqZXZlbnQsCisJCQkJc3RydWN0IHVzYnNzcF9lcCAqZXAsIGludCAq c3RhdHVzKQoreworCXN0cnVjdCB1c2Jzc3BfcmluZyAqZXBfcmluZzsKKwl1MzIgdHJiX2NvbXBf Y29kZTsKKwl1MzIgcmVtYWluaW5nLCByZXF1ZXN0ZWQsIGVwX3RyYl9sZW47CisKKwllcF9yaW5n ID0gdXNic3NwX2RtYV90b190cmFuc2Zlcl9yaW5nKGVwLCBsZTY0X3RvX2NwdShldmVudC0+YnVm ZmVyKSk7CisJdHJiX2NvbXBfY29kZSA9IEdFVF9DT01QX0NPREUobGUzMl90b19jcHUoZXZlbnQt PnRyYW5zZmVyX2xlbikpOworCXJlbWFpbmluZyA9IEVWRU5UX1RSQl9MRU4obGUzMl90b19jcHUo ZXZlbnQtPnRyYW5zZmVyX2xlbikpOworCWVwX3RyYl9sZW4gPSBUUkJfTEVOKGxlMzJfdG9fY3B1 KGVwX3RyYi0+Z2VuZXJpYy5maWVsZFsyXSkpOworCXJlcXVlc3RlZCA9IHRkLT5wcml2X3JlcXVl c3QtPnJlcXVlc3QubGVuZ3RoOworCisJc3dpdGNoICh0cmJfY29tcF9jb2RlKSB7CisJY2FzZSBD T01QX1NVQ0NFU1M6CisJCS8qIGhhbmRsZSBzdWNjZXNzIHdpdGggdW50cmFuc2ZlcnJlZCBkYXRh IGFzIHNob3J0IHBhY2tldCAqLworCQlpZiAoZXBfdHJiICE9IHRkLT5sYXN0X3RyYiB8fCByZW1h aW5pbmcpIHsKKwkJCWRldl93YXJuKHVzYnNzcF9kYXRhLT5kZXYsICJXQVJOIFN1Y2Nlc3NmdWwg Y29tcGxldGlvbiAiCisJCQkJIm9uIHNob3J0IFRYXG4iKTsKKwkJCWRldl9kYmcodXNic3NwX2Rh dGEtPmRldiwKKwkJCQkiZXAgJSN4IC0gYXNrZWQgZm9yICVkIGJ5dGVzLCAlZCBieXRlcyB1bnRy YW5zZmVycmVkXG4iLAorCQkJCXRkLT5wcml2X3JlcXVlc3QtPmRlcC0+ZW5kcG9pbnQuZGVzYy0+ YkVuZHBvaW50QWRkcmVzcywKKwkJCQlyZXF1ZXN0ZWQsIHJlbWFpbmluZyk7CisJCX0KKwkJKnN0 YXR1cyA9IDA7CisJCWJyZWFrOworCWNhc2UgQ09NUF9TSE9SVF9QQUNLRVQ6CisJCWRldl9kYmco dXNic3NwX2RhdGEtPmRldiwKKwkJCSJlcCAlI3ggLSBhc2tlZCBmb3IgJWQgYnl0ZXMsICVkIGJ5 dGVzIHVudHJhbnNmZXJyZWRcbiIsCisJCQkgdGQtPnByaXZfcmVxdWVzdC0+ZGVwLT5lbmRwb2lu dC5kZXNjLT5iRW5kcG9pbnRBZGRyZXNzLAorCQkJIHJlcXVlc3RlZCwgcmVtYWluaW5nKTsKKwor CQkqc3RhdHVzID0gMDsKKwkJYnJlYWs7CisJY2FzZSBDT01QX1NUT1BQRURfU0hPUlRfUEFDS0VU OgorCQl0ZC0+cHJpdl9yZXF1ZXN0LT5yZXF1ZXN0Lmxlbmd0aCA9IHJlbWFpbmluZzsKKwkJZ290 byBmaW5pc2hfdGQ7CisJY2FzZSBDT01QX1NUT1BQRURfTEVOR1RIX0lOVkFMSUQ6CisJCS8qIHN0 b3BwZWQgb24gZXAgdHJiIHdpdGggaW52YWxpZCBsZW5ndGgsIGV4Y2x1ZGUgaXQgKi8KKwkJZXBf dHJiX2xlbiA9IDA7CisJCXJlbWFpbmluZyA9IDA7CisJCWJyZWFrOworCWRlZmF1bHQ6CisJCS8q IE90aGVycyBhbHJlYWR5IGhhbmRsZWQgYWJvdmUgKi8KKwkJYnJlYWs7CisJfQorCisJaWYgKGVw X3RyYiA9PSB0ZC0+bGFzdF90cmIpCisJCXRkLT5wcml2X3JlcXVlc3QtPnJlcXVlc3QuYWN0dWFs ID0gcmVxdWVzdGVkIC0gcmVtYWluaW5nOworCWVsc2UKKwkJdGQtPnByaXZfcmVxdWVzdC0+cmVx dWVzdC5hY3R1YWwgPQorCQkJc3VtX3RyYl9sZW5ndGhzKHVzYnNzcF9kYXRhLCBlcF9yaW5nLCBl cF90cmIpICsgZXBfdHJiX2xlbiAtIHJlbWFpbmluZzsKK2ZpbmlzaF90ZDoKKwlpZiAocmVtYWlu aW5nID4gcmVxdWVzdGVkKSB7CisJCWRldl93YXJuKHVzYnNzcF9kYXRhLT5kZXYsCisJCQkiYmFk IHRyYW5zZmVyIHRyYiBsZW5ndGggJWQgaW4gZXZlbnQgdHJiXG4iLAorCQkJcmVtYWluaW5nKTsK KwkJdGQtPnByaXZfcmVxdWVzdC0+cmVxdWVzdC5hY3R1YWwgPSAwOworCX0KKworCXJldHVybiBm aW5pc2hfdGQodXNic3NwX2RhdGEsIHRkLCBldmVudCwgZXAsIHN0YXR1cyk7Cit9CiAvKgogICog SWYgdGhpcyBmdW5jdGlvbiByZXR1cm5zIGFuIGVycm9yIGNvbmRpdGlvbiwgaXQgbWVhbnMgaXQg Z290IGEgVHJhbnNmZXIKICAqIGV2ZW50IHdpdGggYSBjb3JydXB0ZWQgU2xvdCBJRCwgRW5kcG9p bnQgSUQsIG9yIFRSQiBETUEgYWRkcmVzcy4KQEAgLTE1MzYsOCArMTgzMSwzMTMgQEAgaW50IHVz YnNzcF9pc192ZW5kb3JfaW5mb19jb2RlKHN0cnVjdCB1c2Jzc3BfdWRjICp1c2Jzc3BfZGF0YSwK IHN0YXRpYyBpbnQgaGFuZGxlX3R4X2V2ZW50KHN0cnVjdCB1c2Jzc3BfdWRjICp1c2Jzc3BfZGF0 YSwKIAkJCSAgIHN0cnVjdCB1c2Jzc3BfdHJhbnNmZXJfZXZlbnQgKmV2ZW50KQogewotCS8qVE9E TzogaW1wbGVtZW50IGZ1bmN0aW9uIGhhbmRsaW5nIHRyYW5zZmVyIGV2ZW50Ki8KKwlzdHJ1Y3Qg dXNic3NwX2RldmljZSAqZGV2X3ByaXY7CisJc3RydWN0IHVzYnNzcF9lcCAqZXBfcHJpdjsKKwlz dHJ1Y3QgdXNic3NwX3JpbmcgKmVwX3Jpbmc7CisJdW5zaWduZWQgaW50IHNsb3RfaWQ7CisJaW50 IGVwX2luZGV4OworCXN0cnVjdCB1c2Jzc3BfdGQgKnRkID0gTlVMTDsKKwlkbWFfYWRkcl90IGVw X3RyYl9kbWE7CisJc3RydWN0IHVzYnNzcF9zZWdtZW50ICplcF9zZWc7CisJdW5pb24gdXNic3Nw X3RyYiAqZXBfdHJiOworCWludCBzdGF0dXMgPSAtRUlOUFJPR1JFU1M7CisJc3RydWN0IHVzYnNz cF9lcF9jdHggKmVwX2N0eDsKKwlzdHJ1Y3QgbGlzdF9oZWFkICp0bXA7CisJdTMyIHRyYl9jb21w X2NvZGU7CisJaW50IHJldCA9IDA7CisJaW50IHRkX251bSA9IDA7CisJYm9vbCBoYW5kbGluZ19z a2lwcGVkX3RkcyA9IGZhbHNlOworCWNvbnN0IHN0cnVjdCB1c2JfZW5kcG9pbnRfZGVzY3JpcHRv ciAqZGVzYzsKKworCXNsb3RfaWQgPSBUUkJfVE9fU0xPVF9JRChsZTMyX3RvX2NwdShldmVudC0+ ZmxhZ3MpKTsKKwllcF9pbmRleCA9IFRSQl9UT19FUF9JRChsZTMyX3RvX2NwdShldmVudC0+Zmxh Z3MpKSAtIDE7CisJdHJiX2NvbXBfY29kZSA9IEdFVF9DT01QX0NPREUobGUzMl90b19jcHUoZXZl bnQtPnRyYW5zZmVyX2xlbikpOworCWVwX3RyYl9kbWEgPSBsZTY0X3RvX2NwdShldmVudC0+YnVm ZmVyKTsKKworCWRldl9wcml2ID0gJnVzYnNzcF9kYXRhLT5kZXZzOworCisJZXBfcHJpdiA9ICZk ZXZfcHJpdi0+ZXBzW2VwX2luZGV4XTsKKwllcF9yaW5nID0gdXNic3NwX2RtYV90b190cmFuc2Zl cl9yaW5nKGVwX3ByaXYsIGxlNjRfdG9fY3B1KGV2ZW50LT5idWZmZXIpKTsKKwllcF9jdHggPSB1 c2Jzc3BfZ2V0X2VwX2N0eCh1c2Jzc3BfZGF0YSwgZGV2X3ByaXYtPm91dF9jdHgsIGVwX2luZGV4 KTsKKworCWlmIChHRVRfRVBfQ1RYX1NUQVRFKGVwX2N0eCkgPT0gRVBfU1RBVEVfRElTQUJMRUQp IHsKKwkJZGV2X2Vycih1c2Jzc3BfZGF0YS0+ZGV2LAorCQkJIkVSUk9SIFRyYW5zZmVyIGV2ZW50 IGZvciBkaXNhYmxlZCBlbmRwb2ludCBzbG90ICV1IGVwICV1XG4iLAorCQkJc2xvdF9pZCwgZXBf aW5kZXgpOworCQlnb3RvIGVycl9vdXQ7CisJfQorCisJLyogU29tZSB0cmFuc2ZlciBldmVudHMg ZG9uJ3QgYWx3YXlzIHBvaW50IHRvIGEgdHJiKi8KKwlpZiAoIWVwX3JpbmcpIHsKKwkJc3dpdGNo ICh0cmJfY29tcF9jb2RlKSB7CisJCWNhc2UgQ09NUF9VU0JfVFJBTlNBQ1RJT05fRVJST1I6CisJ CWNhc2UgQ09NUF9JTlZBTElEX1NUUkVBTV9UWVBFX0VSUk9SOgorCQljYXNlIENPTVBfSU5WQUxJ RF9TVFJFQU1fSURfRVJST1I6CisJCQlnb3RvIGNsZWFudXA7CisJCWNhc2UgQ09NUF9SSU5HX1VO REVSUlVOOgorCQljYXNlIENPTVBfUklOR19PVkVSUlVOOgorCQkJZ290byBjbGVhbnVwOworCQlk ZWZhdWx0OgorCQkJZGV2X2Vycih1c2Jzc3BfZGF0YS0+ZGV2LCAiRVJST1IgVHJhbnNmZXIgZXZl bnQgZm9yICIKKwkJCQkidW5rbm93biBzdHJlYW0gcmluZyBzbG90ICV1IGVwICV1XG4iLAorCQkJ CSBzbG90X2lkLCBlcF9pbmRleCk7CisJCQlnb3RvIGVycl9vdXQ7CisJCX0KKwl9CisKKwkvKiBD b3VudCBjdXJyZW50IHRkIG51bWJlcnMgaWYgZXAtPnNraXAgaXMgc2V0ICovCisJaWYgKGVwX3By aXYtPnNraXApIHsKKwkJbGlzdF9mb3JfZWFjaCh0bXAsICZlcF9yaW5nLT50ZF9saXN0KQorCQkJ dGRfbnVtKys7CisJfQorCisJLyogTG9vayBmb3IgY29tbW9uIGVycm9yIGNhc2VzICovCisJc3dp dGNoICh0cmJfY29tcF9jb2RlKSB7CisJLyoKKwkgKiBTa2lwIGNvZGVzIHRoYXQgcmVxdWlyZSBz cGVjaWFsIGhhbmRsaW5nIGRlcGVuZGluZyBvbgorCSAqIHRyYW5zZmVyIHR5cGUKKwkgKi8KKwlj YXNlIENPTVBfU1VDQ0VTUzoKKwkJaWYgKEVWRU5UX1RSQl9MRU4obGUzMl90b19jcHUoZXZlbnQt PnRyYW5zZmVyX2xlbikpID09IDApCisJCQlicmVhazsKKworCQlkZXZfd2Fybl9yYXRlbGltaXRl ZCh1c2Jzc3BfZGF0YS0+ZGV2LAorCQkJIldBUk4gU3VjY2Vzc2Z1bCBjb21wbGV0aW9uIG9uIHNo b3J0IFRYXG4iKTsKKwljYXNlIENPTVBfU0hPUlRfUEFDS0VUOgorCQlicmVhazsKKwljYXNlIENP TVBfU1RPUFBFRDoKKwkJZGV2X2RiZyh1c2Jzc3BfZGF0YS0+ZGV2LCAiU3RvcHBlZCBvbiBUcmFu c2ZlciBUUkIgZm9yIGVwICV1XG4iLAorCQkJZXBfaW5kZXgpOworCQlicmVhazsKKwljYXNlIENP TVBfU1RPUFBFRF9MRU5HVEhfSU5WQUxJRDoKKwkJZGV2X2RiZyh1c2Jzc3BfZGF0YS0+ZGV2LAor CQkJIlN0b3BwZWQgb24gTm8tb3Agb3IgTGluayBUUkIgZm9yIGVwICV1XG4iLAorCQkJZXBfaW5k ZXgpOworCQlicmVhazsKKwljYXNlIENPTVBfU1RPUFBFRF9TSE9SVF9QQUNLRVQ6CisJCWRldl9k YmcodXNic3NwX2RhdGEtPmRldiwKKwkJCSJTdG9wcGVkIHdpdGggc2hvcnQgcGFja2V0IHRyYW5z ZmVyIGRldGVjdGVkIGZvciBlcCAldVxuIiwKKwkJCWVwX2luZGV4KTsKKwkJYnJlYWs7CisJY2Fz ZSBDT01QX0JBQkJMRV9ERVRFQ1RFRF9FUlJPUjoKKwkJZGV2X2RiZyh1c2Jzc3BfZGF0YS0+ZGV2 LCAiQmFiYmxlIGVycm9yIGZvciBlcCAldSBvbiBlbmRwb2ludFxuIiwKKwkJCWVwX2luZGV4KTsK KwkJc3RhdHVzID0gLUVPVkVSRkxPVzsKKwkJYnJlYWs7CisJY2FzZSBDT01QX1RSQl9FUlJPUjoK KwkJZGV2X3dhcm4odXNic3NwX2RhdGEtPmRldiwgIldBUk46IFRSQiBlcnJvciBvbiBlbmRwb2lu dCAldVxuIiwKKwkJCWVwX2luZGV4KTsKKwkJc3RhdHVzID0gLUVJTFNFUTsKKwkJYnJlYWs7CisJ LyogY29tcGxldGlvbiBjb2RlcyBub3QgaW5kaWNhdGluZyBlbmRwb2ludCBzdGF0ZSBjaGFuZ2Ug Ki8KKwljYXNlIENPTVBfREFUQV9CVUZGRVJfRVJST1I6CisJCWRldl93YXJuKHVzYnNzcF9kYXRh LT5kZXYsCisJCQkiV0FSTjogVVNCU1NQIGNvdWxkbid0IGFjY2VzcyBtZW0gZmFzdCBlbm91Z2gg Zm9yIGVwICV1XG4iLAorCQkJZXBfaW5kZXgpOworCQlzdGF0dXMgPSAtRU5PU1I7CisJCWJyZWFr OworCWNhc2UgQ09NUF9JU09DSF9CVUZGRVJfT1ZFUlJVTjoKKwkJZGV2X3dhcm4odXNic3NwX2Rh dGEtPmRldiwKKwkJCSJXQVJOOiBidWZmZXIgb3ZlcnJ1biBldmVudCBmb3IgZXAgJXUgb24gZW5k cG9pbnQiLAorCQkJZXBfaW5kZXgpOworCQlicmVhazsKKwljYXNlIENPTVBfUklOR19VTkRFUlJV TjoKKwkJLyoKKwkJICogV2hlbiB0aGUgSXNvY2ggcmluZyBpcyBlbXB0eSwgdGhlIERDIHdpbGwg Z2VuZXJhdGUKKwkJICogYSBSaW5nIE92ZXJydW4gRXZlbnQgZm9yIElOIElzb2NoIGVuZHBvaW50 IG9yIFJpbmcKKwkJICogVW5kZXJydW4gRXZlbnQgZm9yIE9VVCBJc29jaCBlbmRwb2ludC4KKwkJ ICovCisJCWRldl9kYmcodXNic3NwX2RhdGEtPmRldiwgInVuZGVycnVuIGV2ZW50IG9uIGVuZHBv aW50XG4iKTsKKwkJaWYgKCFsaXN0X2VtcHR5KCZlcF9yaW5nLT50ZF9saXN0KSkKKwkJCWRldl9k YmcodXNic3NwX2RhdGEtPmRldiwgIlVuZGVycnVuIEV2ZW50IGZvciBlcCAlZCAiCisJCQkJInN0 aWxsIHdpdGggVERzIHF1ZXVlZD9cbiIsIGVwX2luZGV4KTsKKwkJZ290byBjbGVhbnVwOworCWNh c2UgQ09NUF9SSU5HX09WRVJSVU46CisJCWRldl9kYmcodXNic3NwX2RhdGEtPmRldiwgIm92ZXJy dW4gZXZlbnQgb24gZW5kcG9pbnRcbiIpOworCQlpZiAoIWxpc3RfZW1wdHkoJmVwX3JpbmctPnRk X2xpc3QpKQorCQkJZGV2X2RiZyh1c2Jzc3BfZGF0YS0+ZGV2LCAiT3ZlcnJ1biBFdmVudCBmb3Ig ZXAgJWQgIgorCQkJCSJzdGlsbCB3aXRoIFREcyBxdWV1ZWQ/XG4iLAorCQkJCWVwX2luZGV4KTsK KwkJZ290byBjbGVhbnVwOworCWNhc2UgQ09NUF9NSVNTRURfU0VSVklDRV9FUlJPUjoKKwkJLyoK KwkJICogV2hlbiBlbmNvdW50ZXIgbWlzc2VkIHNlcnZpY2UgZXJyb3IsIG9uZSBvciBtb3JlIGlz b2MgdGRzCisJCSAqIG1heSBiZSBtaXNzZWQgYnkgREMuCisJCSAqIFNldCBza2lwIGZsYWcgb2Yg dGhlIGVwX3Jpbmc7IENvbXBsZXRlIHRoZSBtaXNzZWQgdGRzIGFzCisJCSAqIHNob3J0IHRyYW5z ZmVyIHdoZW4gcHJvY2VzcyB0aGUgZXBfcmluZyBuZXh0IHRpbWUuCisJCSAqLworCQllcF9wcml2 LT5za2lwID0gdHJ1ZTsKKwkJZGV2X2RiZyh1c2Jzc3BfZGF0YS0+ZGV2LAorCQkJIk1pc3Mgc2Vy dmljZSBpbnRlcnZhbCBlcnJvciBmb3IgZXAgJXUsIHNldCBza2lwIGZsYWdcbiIsCisJCQllcF9p bmRleCk7CisJCWdvdG8gY2xlYW51cDsKKwljYXNlIENPTVBfSU5DT01QQVRJQkxFX0RFVklDRV9F UlJPUjoKKwkJLyogbmVlZHMgZGlzYWJsZSBzbG90IGNvbW1hbmQgdG8gcmVjb3ZlciAqLworCQlk ZXZfd2Fybih1c2Jzc3BfZGF0YS0+ZGV2LAorCQkJIldBUk46IGRldGVjdCBhbiBpbmNvbXBhdGli bGUgZGV2aWNlIGZvciBlcCAldSIsCisJCQllcF9pbmRleCk7CisJCXN0YXR1cyA9IC1FUFJPVE87 CisJCWJyZWFrOworCWRlZmF1bHQ6CisJCWlmICh1c2Jzc3BfaXNfdmVuZG9yX2luZm9fY29kZSh1 c2Jzc3BfZGF0YSwgdHJiX2NvbXBfY29kZSkpIHsKKwkJCXN0YXR1cyA9IDA7CisJCQlicmVhazsK KwkJfQorCisJCWRldl93YXJuKHVzYnNzcF9kYXRhLT5kZXYsCisJCQkiRVJST1IgVW5rbm93biBl dmVudCBjb25kaXRpb24gJXUsIGZvciBlcCAldSAtIFVTQlNTUCBwcm9iYWJseSBidXN0ZWRcbiIs CisJCQl0cmJfY29tcF9jb2RlLCBlcF9pbmRleCk7CisJCWdvdG8gY2xlYW51cDsKKwl9CisKKwlk byB7CisJCS8qCisJCSAqIFRoaXMgVFJCIHNob3VsZCBiZSBpbiB0aGUgVEQgYXQgdGhlIGhlYWQg b2YgdGhpcyByaW5nJ3MgVEQKKwkJICogbGlzdC4KKwkJICovCisJCWlmIChsaXN0X2VtcHR5KCZl cF9yaW5nLT50ZF9saXN0KSkgeworCQkJLyoKKwkJCSAqIERvbid0IHByaW50IHdhbmluZ3MgaWYg aXQncyBkdWUgdG8gYSBzdG9wcGVkIGVuZHBvaW50CisJCQkgKiBnZW5lcmF0aW5nIGFuIGV4dHJh IGNvbXBsZXRpb24gZXZlbnQgaWYgdGhlIGRldmljZQorCQkJICogd2FzIHN1c3BlbmRlZC4gT3Is IGEgZXZlbnQgZm9yIHRoZSBsYXN0IFRSQiBvZiBhCisJCQkgKiBzaG9ydCBURCB3ZSBhbHJlYWR5 IGdvdCBhIHNob3J0IGV2ZW50IGZvci4KKwkJCSAqIFRoZSBzaG9ydCBURCBpcyBhbHJlYWR5IHJl bW92ZWQgZnJvbSB0aGUgVEQgbGlzdC4KKwkJCSAqLworCQkJaWYgKCEodHJiX2NvbXBfY29kZSA9 PSBDT01QX1NUT1BQRUQgfHwKKwkJCSAgICB0cmJfY29tcF9jb2RlID09IENPTVBfU1RPUFBFRF9M RU5HVEhfSU5WQUxJRCB8fAorCQkJICAgIGVwX3JpbmctPmxhc3RfdGRfd2FzX3Nob3J0KSkgewor CQkJCWRldl93YXJuKHVzYnNzcF9kYXRhLT5kZXYsCisJCQkJCSJXQVJOIEV2ZW50IFRSQiBmb3Ig ZXAgJWQgd2l0aCBubyBURHMgcXVldWVkP1xuIiwKKwkJCQkJZXBfaW5kZXgpOworCQkJfQorCisJ CQlpZiAoZXBfcHJpdi0+c2tpcCkgeworCQkJCWVwX3ByaXYtPnNraXAgPSBmYWxzZTsKKwkJCQlk ZXZfZGJnKHVzYnNzcF9kYXRhLT5kZXYsCisJCQkJCSJ0ZF9saXN0IGlzIGVtcHR5IHdoaWxlIHNr aXAgIgorCQkJCQkiZmxhZyBzZXQuIENsZWFyIHNraXAgZmxhZyBmb3IgZXAgJXUuXG4iLAorCQkJ CQllcF9pbmRleCk7CisJCQl9CisJCQlnb3RvIGNsZWFudXA7CisJCX0KKworCQkvKiBXZSd2ZSBz a2lwcGVkIGFsbCB0aGUgVERzIG9uIHRoZSBlcCByaW5nIHdoZW4gZXAtPnNraXAgc2V0ICovCisJ CWlmIChlcF9wcml2LT5za2lwICYmIHRkX251bSA9PSAwKSB7CisJCQllcF9wcml2LT5za2lwID0g ZmFsc2U7CisJCQlkZXZfZGJnKHVzYnNzcF9kYXRhLT5kZXYsCisJCQkJIkFsbCB0ZHMgb24gdGhl IGVwX3Jpbmcgc2tpcHBlZC4gIgorCQkJCSJDbGVhciBza2lwIGZsYWcgZm9yIGVwICV1LlxuIiwg ZXBfaW5kZXgpOworCQkJZ290byBjbGVhbnVwOworCQl9CisKKwkJdGQgPSBsaXN0X2VudHJ5KGVw X3JpbmctPnRkX2xpc3QubmV4dCwgc3RydWN0IHVzYnNzcF90ZCwgdGRfbGlzdCk7CisKKwkJaWYg KGVwX3ByaXYtPnNraXApCisJCQl0ZF9udW0tLTsKKworCQkvKiBJcyB0aGlzIGEgVFJCIGluIHRo ZSBjdXJyZW50bHkgZXhlY3V0aW5nIFREPyAqLworCQllcF9zZWcgPSB1c2Jzc3BfdHJiX2luX3Rk KHVzYnNzcF9kYXRhLCBlcF9yaW5nLT5kZXFfc2VnLAorCQkJCQllcF9yaW5nLT5kZXF1ZXVlLCB0 ZC0+bGFzdF90cmIsCisJCQkJCWVwX3RyYl9kbWEsIGZhbHNlKTsKKworCQkvKgorCQkgKiBTa2lw IHRoZSBGb3JjZSBTdG9wcGVkIEV2ZW50LiBUaGUgZXZlbnRfdHJiKGVwX3RyYl9kbWEpCisJCSAq IG9mIEZTRSBpcyBub3QgaW4gdGhlIGN1cnJlbnQgVEQgcG9pbnRlZCBieSBlcF9yaW5nLT5kZXF1 ZXVlCisJCSAqIGJlY2F1c2UgdGhhdCB0aGUgaGFyZHdhcmUgZGVxdWV1ZSBwb2ludGVyIHN0aWxs IGF0IHRoZQorCQkgKiBwcmV2aW91cyBUUkIgb2YgdGhlIGN1cnJlbnQgVEQuIFRoZSBwcmV2aW91 cyBUUkIgbWF5YmUgYQorCQkgKiBMaW5rIFREIG9yIHRoZSBsYXN0IFRSQiBvZiB0aGUgcHJldmlv dXMgVEQuIFRoZSBjb21tYW5kCisJCSAqIGNvbXBsZXRpb24gaGFuZGxlIHdpbGwgdGFrZSBjYXJl IHRoZSByZXN0LgorCQkgKi8KKwkJaWYgKCFlcF9zZWcgJiYgKHRyYl9jb21wX2NvZGUgPT0gQ09N UF9TVE9QUEVEIHx8CisJCSAgICB0cmJfY29tcF9jb2RlID09IENPTVBfU1RPUFBFRF9MRU5HVEhf SU5WQUxJRCkpIHsKKwkJCWdvdG8gY2xlYW51cDsKKwkJfQorCisJCWRlc2MgPSB0ZC0+cHJpdl9y ZXF1ZXN0LT5kZXAtPmVuZHBvaW50LmRlc2M7CisJCWlmICghZXBfc2VnKSB7CisJCQlpZiAoIWVw X3ByaXYtPnNraXAgfHwgIXVzYl9lbmRwb2ludF94ZmVyX2lzb2MoZGVzYykpIHsKKworCQkJCS8q IFVTQlNTUCBpcyBidXN0ZWQsIGdpdmUgdXAhICovCisJCQkJZGV2X2Vycih1c2Jzc3BfZGF0YS0+ ZGV2LAorCQkJCQkiRVJST1IgVHJhbnNmZXIgZXZlbnQgVFJCIERNQSBwdHIgbm90ICIKKwkJCQkJ InBhcnQgb2YgY3VycmVudCBURCBlcF9pbmRleCAlZCAiCisJCQkJCSJjb21wX2NvZGUgJXVcbiIs IGVwX2luZGV4LAorCQkJCQl0cmJfY29tcF9jb2RlKTsKKworCQkJCXVzYnNzcF90cmJfaW5fdGQo dXNic3NwX2RhdGEsIGVwX3JpbmctPmRlcV9zZWcsCisJCQkJCWVwX3JpbmctPmRlcXVldWUsIHRk LT5sYXN0X3RyYiwKKwkJCQkJZXBfdHJiX2RtYSwgdHJ1ZSk7CisJCQkJcmV0dXJuIC1FU0hVVERP V047CisJCQl9CisKKwkJCXJldCA9IHNraXBfaXNvY190ZCh1c2Jzc3BfZGF0YSwgdGQsIGV2ZW50 LCBlcF9wcml2LAorCQkJCQkmc3RhdHVzKTsKKwkJCWdvdG8gY2xlYW51cDsKKwkJfQorCisJCWlm ICh0cmJfY29tcF9jb2RlID09IENPTVBfU0hPUlRfUEFDS0VUKQorCQkJZXBfcmluZy0+bGFzdF90 ZF93YXNfc2hvcnQgPSB0cnVlOworCQllbHNlCisJCQllcF9yaW5nLT5sYXN0X3RkX3dhc19zaG9y dCA9IGZhbHNlOworCisJCWlmIChlcF9wcml2LT5za2lwKSB7CisJCQlkZXZfZGJnKHVzYnNzcF9k YXRhLT5kZXYsCisJCQkJIkZvdW5kIHRkLiBDbGVhciBza2lwIGZsYWcgZm9yIGVwICV1LlxuIiwK KwkJCQllcF9pbmRleCk7CisJCQllcF9wcml2LT5za2lwID0gZmFsc2U7CisJCX0KKworCQllcF90 cmIgPSAmZXBfc2VnLT50cmJzWyhlcF90cmJfZG1hIC0gZXBfc2VnLT5kbWEpIC8gc2l6ZW9mKCpl cF90cmIpXTsKKworCQl0cmFjZV91c2Jzc3BfaGFuZGxlX3RyYW5zZmVyKGVwX3JpbmcsCisJCQkJ CShzdHJ1Y3QgdXNic3NwX2dlbmVyaWNfdHJiICopIGVwX3RyYik7CisKKwkJaWYgKHRyYl9pc19u b29wKGVwX3RyYikpIHsKKwkJCWRldl9kYmcodXNic3NwX2RhdGEtPmRldiwKKwkJCQkiZXZlbnRf dHJiIGlzIGEgbm8tb3AgVFJCLiBTa2lwIGl0XG4iKTsKKwkJCWdvdG8gY2xlYW51cDsKKwkJfQor CisJCWlmICh1c2JfZW5kcG9pbnRfeGZlcl9jb250cm9sKGRlc2MpKSB7CisJCQlyZXQgPSBwcm9j ZXNzX2N0cmxfdGQodXNic3NwX2RhdGEsIHRkLCBlcF90cmIsIGV2ZW50LAorCQkJCQllcF9wcml2 LCAmc3RhdHVzKTsKKwkJfSBlbHNlIGlmICh1c2JfZW5kcG9pbnRfeGZlcl9pc29jKGRlc2MpKSB7 CisJCQlyZXQgPSBwcm9jZXNzX2lzb2NfdGQodXNic3NwX2RhdGEsIHRkLCBlcF90cmIsCisJCQkJ CWV2ZW50LCBlcF9wcml2LCAmc3RhdHVzKTsKKwkJfSBlbHNlIHsKKwkJCXJldCA9IHByb2Nlc3Nf YnVsa19pbnRyX3RkKHVzYnNzcF9kYXRhLCB0ZCwgZXBfdHJiLAorCQkJCQkJZXZlbnQsIGVwX3By aXYsICZzdGF0dXMpOworCQl9CitjbGVhbnVwOgorCQloYW5kbGluZ19za2lwcGVkX3RkcyA9IGVw X3ByaXYtPnNraXAgJiYKKwkJCXRyYl9jb21wX2NvZGUgIT0gQ09NUF9NSVNTRURfU0VSVklDRV9F UlJPUjsKKworCQkvKgorCQkgKiBEbyBub3QgdXBkYXRlIGV2ZW50IHJpbmcgZGVxdWV1ZSBwb2lu dGVyIGlmIHdlJ3JlIGluIGEgbG9vcAorCQkgKiBwcm9jZXNzaW5nIG1pc3NlZCB0ZHMuCisJCSAq LworCQlpZiAoIWhhbmRsaW5nX3NraXBwZWRfdGRzKQorCQkJaW5jX2RlcSh1c2Jzc3BfZGF0YSwg dXNic3NwX2RhdGEtPmV2ZW50X3JpbmcpOworCS8qCisJICogSWYgZXAtPnNraXAgaXMgc2V0LCBp dCBtZWFucyB0aGVyZSBhcmUgbWlzc2VkIHRkcyBvbiB0aGUKKwkgKiBlbmRwb2ludCByaW5nIG5l ZWQgdG8gdGFrZSBjYXJlIG9mLgorCSAqIFByb2Nlc3MgdGhlbSBhcyBzaG9ydCB0cmFuc2ZlciB1 bnRpbCByZWFjaCB0aGUgdGQgcG9pbnRlZCBieQorCSAqIHRoZSBldmVudC4KKwkgKi8KKwl9IHdo aWxlIChoYW5kbGluZ19za2lwcGVkX3Rkcyk7CisKIAlyZXR1cm4gMDsKKworZXJyX291dDoKKwlk ZXZfZXJyKHVzYnNzcF9kYXRhLT5kZXYsICJAJTAxNmxseCAlMDh4ICUwOHggJTA4eCAlMDh4XG4i LAorCQkgKHVuc2lnbmVkIGxvbmcgbG9uZykgdXNic3NwX3RyYl92aXJ0X3RvX2RtYSgKKwkJCQkJ dXNic3NwX2RhdGEtPmV2ZW50X3JpbmctPmRlcV9zZWcsCisJCQkJCXVzYnNzcF9kYXRhLT5ldmVu dF9yaW5nLT5kZXF1ZXVlKSwKKwkJIGxvd2VyXzMyX2JpdHMobGU2NF90b19jcHUoZXZlbnQtPmJ1 ZmZlcikpLAorCQkgdXBwZXJfMzJfYml0cyhsZTY0X3RvX2NwdShldmVudC0+YnVmZmVyKSksCisJ CSBsZTMyX3RvX2NwdShldmVudC0+dHJhbnNmZXJfbGVuKSwKKwkJIGxlMzJfdG9fY3B1KGV2ZW50 LT5mbGFncykpOworCXJldHVybiAtRU5PREVWOwogfQogCiAvKgpkaWZmIC0tZ2l0IGEvZHJpdmVy cy91c2IvdXNic3NwL2dhZGdldC5oIGIvZHJpdmVycy91c2IvdXNic3NwL2dhZGdldC5oCmluZGV4 IDAwMGYyY2I5MzcyMy4uYzRlNDQwZGI2YjIzIDEwMDY0NAotLS0gYS9kcml2ZXJzL3VzYi91c2Jz c3AvZ2FkZ2V0LmgKKysrIGIvZHJpdmVycy91c2IvdXNic3NwL2dhZGdldC5oCkBAIC0xNjk5LDYg KzE2OTksMTEgQEAgaW50IHVzYnNzcF9yaW5nX2V4cGFuc2lvbihzdHJ1Y3QgdXNic3NwX3VkYyAq dXNic3NwX2RhdGEsCiBzdHJ1Y3QgdXNic3NwX3JpbmcgKnVzYnNzcF9zdHJlYW1faWRfdG9fcmlu ZyhzdHJ1Y3QgdXNic3NwX2RldmljZSAqZGV2LAogCQkJCQl1bnNpZ25lZCBpbnQgZXBfaW5kZXgs CiAJCQkJCXVuc2lnbmVkIGludCBzdHJlYW1faWQpOworc3RydWN0IHVzYnNzcF9yaW5nICp1c2Jz c3BfZG1hX3RvX3RyYW5zZmVyX3Jpbmcoc3RydWN0IHVzYnNzcF9lcCAqZXAsCisJCQkJCQl1NjQg YWRkcmVzcyk7CitzdHJ1Y3QgdXNic3NwX3JpbmcgKnVzYnNzcF9zdHJlYW1faWRfdG9fcmluZyhz dHJ1Y3QgdXNic3NwX2RldmljZSAqZGV2LAorCQkJCQl1bnNpZ25lZCBpbnQgZXBfaW5kZXgsCisJ CQkJCXVuc2lnbmVkIGludCBzdHJlYW1faWQpOwogCiBzdHJ1Y3QgdXNic3NwX2NvbW1hbmQgKnVz YnNzcF9hbGxvY19jb21tYW5kKHN0cnVjdCB1c2Jzc3BfdWRjICp1c2Jzc3BfZGF0YSwKIAkJCQkJ Ym9vbCBhbGxvY2F0ZV9jb21wbGV0aW9uLAo=