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 3FD7FC468C6 for ; Thu, 19 Jul 2018 17:59:55 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 9CC9B20684 for ; Thu, 19 Jul 2018 17:59:54 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=cadence.com header.i=@cadence.com header.b="AYrwnlYt" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 9CC9B20684 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 S2387998AbeGSSoH (ORCPT ); Thu, 19 Jul 2018 14:44:07 -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 S1732159AbeGSSoG (ORCPT ); Thu, 19 Jul 2018 14:44:06 -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=gxAy70DoK/dmdZgoynut9MlY92jXnpgyWWl/u53hhXU=; b=AYrwnlYtFO4SKqIacC++vvDgc8t3YJJC5PQHR9WG4dW+dspA9fRfY2eFjQSASk1Tp402bcdhqFG4kE/uNsU5YHPgxPwqrJ7qKRwT/jC1OyeYNO6jJxfRyajWO9cjf6kuENgzMxXOWXwvgzKBeubHPeHq4I0ULTEkPV0F3vMDUA0= Received: from BYAPR07CA0047.namprd07.prod.outlook.com (2603:10b6:a03:60::24) 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:26 +0000 Received: from BY2NAM05FT012.eop-nam05.prod.protection.outlook.com (2a01:111:f400:7e52::202) by BYAPR07CA0047.outlook.office365.com (2603:10b6:a03:60::24) 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:26 +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 BY2NAM05FT012.mail.protection.outlook.com (10.152.100.149) 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:25 +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 w6JHxNgC025447 (version=TLSv1/SSLv3 cipher=AES256-SHA bits=256 verify=FAIL); Thu, 19 Jul 2018 10:59:25 -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:30 +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:30 +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 w6JHxF8Y005974; Thu, 19 Jul 2018 18:59:15 +0100 Received: (from pawell@localhost) by lvlogina.cadence.com (8.14.4/8.14.4/Submit) id w6JHxFc6005972; Thu, 19 Jul 2018 18:59:15 +0100 From: Pawel Laszczak CC: Greg Kroah-Hartman , , Felipe Balbi , , , , Subject: [PATCH 22/31] usb: usbssp: added procedure removing request from transfer ring Date: Thu, 19 Jul 2018 18:57:55 +0100 Message-ID: <1532023084-28083-23-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)(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)(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;BY2NAM05FT012;1:4ES0x6PQhhFMkoC+VclkjcrssFeaeyP6GkuPLVhQFiLvisIVH/jg7uKIsyag/DE1U7ACNbfVxIWI4WMOiVe7t3CUxO16Qefe0dL+epnnhgRNswmnO/8Z/LXovnxxGraw X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: b76e34c2-089c-45eb-6147-08d5eda15db7 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:3YAJIAk+l9yEpsGo7Y5fpiFlLy7NaCkYToWSSf3gDUfYKO/VYqe1XoSkEmHUu9qhC7/38IPvTZPlOFYJSH9LFlQkauzycRvSX+ZcPjwfWHaG8Io1GzJACgcmF0IT//aXifS98ZOwQorktJ8wrRDFo+IvQ//GXeqMGtaxg+3yRY+hWWdC6365v0iXkNTaxoT5uQVtFPBqBq3BWCKaQHbFv5O+GlUv1LjsV/yqXKAY67wx7NL7OhGYDU9CaQcSekvuRDtbU27j7fP2Lw31S/9rGFzTJrS8r8MVMcjUnm8feT6hPvSrKqXuL2fGS3+Ij7DplRiBFIAEUw/kMZUb0oFyP9sDBeJ80/RvZwui/hnQMmY=;25:oYJ1BedQU+70altbdScwTIl++MpEZfwU20tdJs+Xmi2JAIjmiMLHlaSY8ybrrJ/ZfpvmGr2Uf8vk6N6v5QvY5rajvW/R38iT8ZZnnQdsEdgYnXOLbctF8cPsRB1dre2gfi8vbHzjEqXBXoCIynyxw/st8Y43d+sN4hNjl+lo0+XpPT4+PLq1qeRxqneS9P70Fpev4AB26Y2NpKly++FY7lfDEeTeid4peSLoAkSNUkwI0U4TefLRh+NxgXlHvUiswIfvilUGUC8SUQhw2CbR3xgmICV6nm8UP70RMgVLkmjXFPaJm/6kKOgeGjowKF1EVpZBkXVnW9NZBqnfS5N74g== X-MS-TrafficTypeDiagnostic: BN3PR0701MB1330: X-Microsoft-Exchange-Diagnostics: 1;BN3PR0701MB1330;31:Aa/JzFI3nVrAlHLUGJnVRttMMJn/rkqpXw5rUyozf7QxzHOySw8e7k5QKF2er+W2U0ETgmAN03QPgG4/JnmxVLJXTz1p9+bR8NPCWef1fzwSFb9HdsozO6DTOQegPLfUpztcwvuHcoFIs54gfiR0g13f0bdvgWQQpWYNfKtwibQc6qZQMmFgmbX+eW7POI9tqYjYu/0RUyASNCUo39idYhhq8DGygG6UFHVAYvKJqyM=;20:x+Ebb6KtoJccVJGN6nniExzm5RVfGRTWZpJsIMw2gQ1kukohYYFFK1Ypg2SnyjTxnAZQddMslwtqQ5jshwCtxhYLWqbuIC5yPQr5lWsqZ+vOGR15h4C0UsVEA8PdvNLiktae+4AYqEcBBuScVtpjBDLnHDRhBBpoAuwvUMWYFHsIR1z8WTz3hHnKyEsZDnaf7yCDPUHcBENS/rJXLEbAvLquhHIpj3TXca00aZ7RVQOi+/23DwNWG/aCQag8qqODhgpzmxN4fVzn8WkTZYwrcUHNR2iLi/N3ZBT2o2CH3UGX+HL7BCh9zQw26O5mTN9CR+q8vxe+O6e+ndnlcKoRDJfnn/FxA6m703gEpzjl0pbhsJTB+M7P8iFz09uhAcaRCO6dflfNpq1PPj9A3BLwdg1QmZ3l0DFlJH0IDUTPPAtUqEsa9CIxnSqNjaINxL+JxWbeZP6wlRDbbxwkeDaxiJddctth0YAZXSIikpNUoNVjkw6xs83pCexcBTUxVkO4 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:TbtT29fUm4d3VF+ttUrEDi7nDZMXeyLSU5AD4FXeFMbgvZyEynx8SM7/xjR6AslNJ8aaktFma3LHFwsTyXr036wdkVVfiH3tgkZzgEOdJfIpspszudXHHQK4mxrvi4FpgqL3aWpAWqis/lYk3BkAMSfW6u5OWMeiN3Y6DsqM2oVb24t+ZjYj0EjEVIPWl6+QOJ4ZtsQ7BdrFfxx25kLzfoGJ3t9Tw6G+2wJsq9Rhxr6DabsJtK7WdF09SuPYXKlxZ+uFMKtjaKJ7XzHnJVkW1+Ao5H0Rde2OmkbSmnfGKfKzlIYI+tsz0CYSKz357qjR X-Forefront-PRVS: 0738AF4208 X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1;BN3PR0701MB1330;23:FbTdDlyRimTFQ+QdKNtItY8667+l/LcbeKPGFWh?= =?us-ascii?Q?jnSqltRSaPeIMLg6kaK9MME8DeyQX3XGj/spXluLq3BV3agT0qzTwM4gS3cL?= =?us-ascii?Q?8ogqSlVc1SHgXQo+VfsKWTQsRwT6/yJKNUmS8RG09dBBXgm4aj6EIOTfq4lJ?= =?us-ascii?Q?+O4O44GFkgYwax2PyDUmcULt88mvtnL8Qaiptxis+1Pri0xo20ciViRZXoph?= =?us-ascii?Q?8Yy2Lo14TXb6l8YlVjEc2N6oCOpT5uh+uRZpRGXF7+eeYYu3bpKribAxB+t5?= =?us-ascii?Q?zMDuL/SJbCHdySwWmrnO2FJ+Ma5qZM/n3UoEryYgLT1J40cUkvcTGN7+dD5B?= =?us-ascii?Q?7bAgOju5GZwd/07g58XG93zvR5edDKTgYEvb1RgwWR7n2ETGHJOshpq16oDe?= =?us-ascii?Q?kUrY32KIxzgq+6OBoC6BVAN9yLa0FF8rt3N56A+Ilz9Hh5AkFI+o9v3Swk49?= =?us-ascii?Q?npNspVKpzv0H6X8MIAlDGgNsiDdSzYvnBlUSp5AvhSL1pVcskzOywihz7i9n?= =?us-ascii?Q?rPJc71iJCHnxdCVdMY5S3ANiLaQBEOnihjbYsheeTqNm34X8fuVJam+Om9Sr?= =?us-ascii?Q?RYEC7+Ji+frWqbx4cCRrUv6dqi3FvdIhAU0MJv4IvXKCLkQ2gd72MrIASe7F?= =?us-ascii?Q?pabTjkS/Sos4DaUmqbxeK2K2CHFhHSv4FL5jXXHI0EbPaJGJLFdjE3cCijjw?= =?us-ascii?Q?WkBO3JqLEcd0aW16acoZZNdmLg5NkrIFnKw7tKNuIqo6ENjBXjMFWiTnjYfv?= =?us-ascii?Q?24mrS1MJKPBR9ZnhG0R7eQ4NykKL597PihSKNSXihF5hEoIbe2sg/+c/2A8O?= =?us-ascii?Q?LADzXo5PNe+l34mN5VB1bq07lmwaJ4uLIdaJLQoxsXJxwWuIUPkq41LLEdxn?= =?us-ascii?Q?WxXG4r5N8+U5L+9GFUkmhYBCeBf2bgdWnRhYpqg6xDLUq+8H3lofxJPAQOk7?= =?us-ascii?Q?hre/Kz7avuF0eciw/4i8YYxMMnzVgnYL9QMxwDLK2rD7oJlGxcGJTG/Qv0I4?= =?us-ascii?Q?2h9scoTpxKvi5vzUfuqzXQToKrEXd3w3TH0p5CEjyFYCfbSa4T/JSdaoKrs6?= =?us-ascii?Q?72BAYli6JvrNEHvnHimGiYufADlwBz02UGLNEZU8F3IpW0q7sSU0ry6j5GsD?= =?us-ascii?Q?zORLSLJdn9Rap/ywwslJXKEW6pbPPCxA/XNQ1hfJAgHYIyaEx7IEkW0BF/hK?= =?us-ascii?Q?lcEx6cYEPTzavEgU=3D?= X-Microsoft-Antispam-Message-Info: xudAfGchp+muwvwfEPDhDaW8sB2cUBfohmqz8Ofi8PTmzLv0hqGCurzagLZNZSWj8DJq7UKpQ4+U3zdXe8baNB9jEdH1wVOQocOF6eltpjExO2qjF0k5iEVCtmRjrBwtfLJsuUCRV7b3iMfMPdCTL4QEIk0DICPFUOsllKnEzJLPj2RiKKbrQS4o4iqhkD6xpRVS1m9hnbLi0TJliuKspug7kVNO4BHhNyM0ZlcW8PHRE0C5MJ7BU9t11G5j8uVoP//mbazv00ofbkLBWYT5O9eXfBJpvzUq+wD/R/eb3H0Hb+d20Fraj+3WEznqe7dGtafnn/hFIcwMfOS/HZ68s0QVnl5WeWtON6zASMAfbuLaKxdHP0z3G7INDG/ZE3kb06CeMKZRYfbw/vesm8eT2A== X-Microsoft-Exchange-Diagnostics: 1;BN3PR0701MB1330;6:5hCxjRkTK4ubAX+Cqxbsc2MRCVuDVSkci2YrnFpUss2N+wYJ1QZkT9kDzn5COKaQ4NV1YUJ864y525+U5PrXz02dGTu/ztmgIPqt5merF26giLFZRAYLApHASwBTCdFHEPreRSxTeByrApaUONDN45t1WO7wmtbncNg0GT2FAW89AeYTJ9WaUYdJOQSRk4K9SY9L1Gdcrbrruwci752cSpGJVjFhws5BXhwitHi+mnmDkPRcXinZKNQowPOE2XW4c0gheqZ8LbnCPQbVuqezXPKceBoeiIo7TpQDRdgq/TvVNasjQ102aXQZj8uHZDg6mYqUrqLMSWyu/FKCdPz82vQIRcHIQfLgH1qyBtvZcgEJRHTj9A9Vjvdn8X3Xma6V+AnEKk2OoFN2tYRYHRtHsA91aenNPeGnD3hk29IrfzNSjpWpRK218v6P4pr7lOn95/qA+BBiJFDnhbOQQLX9dA==;5:Cmd/LvIJu4kx9fjlTZDb6ixQXflEvqgLOTrUFGtQs8jopOk4GAyZ9vZfC0t24LeiIglYxHAorO61azUcBGIp7PNJP6KYq2ecJGgnvdYwAHAP8T5QWPG24TAcLjEgce3iZaUq5xgVkQ4asCkNKoIqa+llzJ5W+2Pq30RUPACCqJE=;7:KYxH40eNLt7ddbVQo7CKzmX1XguYVLYDYYExV3gCyZx6KO9FHthYFTm9zJGjvim7ijlpgubBkJoQn783m9Hcrt3ckkAwif8c1rVf9X6Q0jGiL69Z37gztvBBBtCR0SY6hAnX2bHwHmo2jHhBEgLeh98aRrIDhSEACBNyn+S96QnUeDvzs3lfbaSjaYuxL9IBkO05qOVksoAigkPFwVRsp8aYDone9Reep+qsrUyu2XTh2fiYZcf7T5My6PDeuoTF SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1;BN3PR0701MB1330;20:QbylnoHo2lTaYjMmk7rLYa4asWiUecFQxvPk8lF+K5F+1W4qvhGzoZSX2n1zWO9GnoBvf3VEbdgot0K4nhJSj3BAxn1ukxtcgAvNRd9/mC9iwYQx3+1aq/XCQuh12PVXSjdQq0M69uZR2oSgZfProFy1sKfYg09JxISezV1if09hexDPaz3kztZVj0AVc4WNPBb3huaXyf7b22ve32ZjtZmAPR+d5iXqvMMGrqDdF8swy/4AgfpR9gX1n19g1mgx X-OriginatorOrg: cadence.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 19 Jul 2018 17:59:25.9984 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: b76e34c2-089c-45eb-6147-08d5eda15db7 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 adds functionality that allows to remove the request from the endpoint ring. This may cause the DC to stop USB transfers, potentially stopping in the middle of a TRB buffer. The DC should pick up where it left off in the TD, unless a Set Transfer Ring Dequeue Pointer is issued. Signed-off-by: Pawel Laszczak --- drivers/usb/usbssp/gadget-ring.c | 331 ++++++++++++++++++++++++++++++- drivers/usb/usbssp/gadget.c | 49 ++++- drivers/usb/usbssp/gadget.h | 11 + 3 files changed, 387 insertions(+), 4 deletions(-) diff --git a/drivers/usb/usbssp/gadget-ring.c b/drivers/usb/usbssp/gadget-ring.c index 4bb13f9e311a..cfb31120eef8 100644 --- a/drivers/usb/usbssp/gadget-ring.c +++ b/drivers/usb/usbssp/gadget-ring.c @@ -102,11 +102,51 @@ static bool link_trb_toggles_cycle(union usbssp_trb *trb) return le32_to_cpu(trb->link.control) & LINK_TOGGLE; } +static bool last_td_in_request(struct usbssp_td *td) +{ + struct usbssp_request *req_priv = td->priv_request; + + return req_priv->num_tds_done == req_priv->num_tds; +} + static void inc_td_cnt(struct usbssp_request *priv_req) { priv_req->num_tds_done++; } +static void trb_to_noop(union usbssp_trb *trb, u32 noop_type) +{ + if (trb_is_link(trb)) { + /* unchain chained link TRBs */ + trb->link.control &= cpu_to_le32(~TRB_CHAIN); + } else { + trb->generic.field[0] = 0; + trb->generic.field[1] = 0; + trb->generic.field[2] = 0; + /* Preserve only the cycle bit of this TRB */ + trb->generic.field[3] &= cpu_to_le32(TRB_CYCLE); + trb->generic.field[3] |= cpu_to_le32(TRB_TYPE(noop_type)); + } +} + +/* + * Updates trb to point to the next TRB in the ring, and updates seg if the next + * TRB is in a new segment. This does not skip over link TRBs, and it does not + * effect the ring dequeue or enqueue pointers. + */ +static void next_trb(struct usbssp_udc *usbssp_data, + struct usbssp_ring *ring, + struct usbssp_segment **seg, + union usbssp_trb **trb) +{ + if (trb_is_link(*trb)) { + *seg = (*seg)->next; + *trb = ((*seg)->trbs); + } else { + (*trb)++; + } +} + /* * See Cycle bit rules. SW is the consumer for the event ring only. * Don't make a ring full of link TRBs. That would be dumb and this would loop. @@ -347,6 +387,157 @@ struct usbssp_ring *usbssp_triad_to_transfer_ring(struct usbssp_udc *usbssp_data return NULL; } +/* + * Get the hw dequeue pointer DC stopped on, either directly from the + * endpoint context, or if streams are in use from the stream context. + * The returned hw_dequeue contains the lowest four bits with cycle state + * and possbile stream context type. + */ +u64 usbssp_get_hw_deq(struct usbssp_udc *usbssp_data, + struct usbssp_device *dev, + unsigned int ep_index, + unsigned int stream_id) +{ + struct usbssp_ep_ctx *ep_ctx; + struct usbssp_stream_ctx *st_ctx; + struct usbssp_ep *ep; + + ep = &dev->eps[ep_index]; + + if (ep->ep_state & EP_HAS_STREAMS) { + st_ctx = &ep->stream_info->stream_ctx_array[stream_id]; + return le64_to_cpu(st_ctx->stream_ring); + } + ep_ctx = usbssp_get_ep_ctx(usbssp_data, dev->out_ctx, ep_index); + return le64_to_cpu(ep_ctx->deq); +} + +/* + * Move the DC endpoint ring dequeue pointer past cur_td. + * Record the new state of the DC endpoint ring dequeue segment, + * dequeue pointer, and new consumer cycle state in state. + * Update our internal representation of the ring's dequeue pointer. + * + * We do this in three jumps: + * - First we update our new ring state to be the same as when the DC stopped. + * - Then we traverse the ring to find the segment that contains + * the last TRB in the TD. We toggle the DC new cycle state when we pass + * any link TRBs with the toggle cycle bit set. + * - Finally we move the dequeue state one TRB further, toggling the cycle bit + * if we've moved it past a link TRB with the toggle cycle bit set. + */ +void usbssp_find_new_dequeue_state(struct usbssp_udc *usbssp_data, + unsigned int ep_index, + unsigned int stream_id, + struct usbssp_td *cur_td, + struct usbssp_dequeue_state *state) +{ + struct usbssp_device *dev_priv = &usbssp_data->devs; + struct usbssp_ep *ep_priv = &dev_priv->eps[ep_index]; + struct usbssp_ring *ep_ring; + struct usbssp_segment *new_seg; + union usbssp_trb *new_deq; + dma_addr_t addr; + u64 hw_dequeue; + bool cycle_found = false; + bool td_last_trb_found = false; + + ep_ring = usbssp_triad_to_transfer_ring(usbssp_data, + ep_index, stream_id); + if (!ep_ring) { + dev_warn(usbssp_data->dev, "WARN can't find new dequeue state " + "for invalid stream ID %u.\n", + stream_id); + return; + } + + /* Dig out the cycle state saved by the DC during the stop ep cmd */ + usbssp_dbg_trace(usbssp_data, trace_usbssp_dbg_cancel_request, + "Finding endpoint context"); + + hw_dequeue = usbssp_get_hw_deq(usbssp_data, dev_priv, + ep_index, stream_id); + new_seg = ep_ring->deq_seg; + new_deq = ep_ring->dequeue; + state->new_cycle_state = hw_dequeue & 0x1; + state->stream_id = stream_id; + + /* + * We want to find the pointer, segment and cycle state of the new trb + * (the one after current TD's last_trb). We know the cycle state at + * hw_dequeue, so walk the ring until both hw_dequeue and last_trb are + * found. + */ + do { + if (!cycle_found && usbssp_trb_virt_to_dma(new_seg, new_deq) + == (dma_addr_t)(hw_dequeue & ~0xf)) { + cycle_found = true; + if (td_last_trb_found) + break; + } + + if (new_deq == cur_td->last_trb) + td_last_trb_found = true; + + if (cycle_found && trb_is_link(new_deq) && + link_trb_toggles_cycle(new_deq)) + state->new_cycle_state ^= 0x1; + + next_trb(usbssp_data, ep_ring, &new_seg, &new_deq); + + /* Search wrapped around, bail out */ + if (new_deq == ep_priv->ring->dequeue) { + dev_err(usbssp_data->dev, + "Error: Failed finding new dequeue state\n"); + state->new_deq_seg = NULL; + state->new_deq_ptr = NULL; + return; + } + + } while (!cycle_found || !td_last_trb_found); + + state->new_deq_seg = new_seg; + state->new_deq_ptr = new_deq; + + /* Don't update the ring cycle state for the producer (us). */ + usbssp_dbg_trace(usbssp_data, trace_usbssp_dbg_cancel_request, + "Cycle state = 0x%x", state->new_cycle_state); + + usbssp_dbg_trace(usbssp_data, trace_usbssp_dbg_cancel_request, + "New dequeue segment = %p (virtual)", + state->new_deq_seg); + addr = usbssp_trb_virt_to_dma(state->new_deq_seg, state->new_deq_ptr); + usbssp_dbg_trace(usbssp_data, trace_usbssp_dbg_cancel_request, + "New dequeue pointer = 0x%llx (DMA)", + (unsigned long long) addr); +} + +/* + * flip_cycle means flip the cycle bit of all but the first and last TRB. + * (The last TRB actually points to the ring enqueue pointer, which is not part + * of this TD.) This is used to remove partially enqueued isoc TDs from a ring. + */ +static void td_to_noop(struct usbssp_udc *usbssp_data, + struct usbssp_ring *ep_ring, + struct usbssp_td *td, bool flip_cycle) +{ + struct usbssp_segment *seg = td->start_seg; + union usbssp_trb *trb = td->first_trb; + + while (1) { + trb_to_noop(trb, TRB_TR_NOOP); + + /* flip cycle if asked to */ + if (flip_cycle && trb != td->first_trb && trb != td->last_trb) + trb->generic.field[3] ^= cpu_to_le32(TRB_CYCLE); + + if (trb == td->last_trb) + break; + + next_trb(usbssp_data, ep_ring, &seg, &trb); + } +} + /* Must be called with usbssp_data->lock held in interrupt context * or usbssp_data->irq_thread_lock from thread conext (defered interrupt) */ @@ -365,6 +556,139 @@ void usbssp_giveback_request_in_irq(struct usbssp_udc *usbssp_data, usbssp_gadget_giveback(req_priv->dep, req_priv, status); } +void usbssp_unmap_td_bounce_buffer(struct usbssp_udc *usbssp_data, + struct usbssp_ring *ring, + struct usbssp_td *td) +{ + /*TODO: ??? */ +} + +void usbssp_remove_request(struct usbssp_udc *usbssp_data, + struct usbssp_request *req_priv, int ep_index) +{ + int i = 0; + struct usbssp_ring *ep_ring; + struct usbssp_ep *ep; + struct usbssp_td *cur_td = NULL; + struct usbssp_ep_ctx *ep_ctx; + struct usbssp_device *priv_dev; + u64 hw_deq; + struct usbssp_dequeue_state deq_state; + + memset(&deq_state, 0, sizeof(deq_state)); + ep = &usbssp_data->devs.eps[ep_index]; + + priv_dev = &usbssp_data->devs; + ep_ctx = usbssp_get_ep_ctx(usbssp_data, priv_dev->out_ctx, ep_index); + trace_usbssp_remove_request(ep_ctx); + + i = req_priv->num_tds_done; + + for (; i < req_priv->num_tds; i++) { + cur_td = &req_priv->td[i]; + usbssp_dbg_trace(usbssp_data, trace_usbssp_dbg_cancel_request, + "Removing canceled TD starting at 0x%llx (dma).", + (unsigned long long)usbssp_trb_virt_to_dma( + cur_td->start_seg, + cur_td->first_trb)); + + ep_ring = usbssp_request_to_transfer_ring(usbssp_data, + cur_td->priv_request); + + if (!ep_ring) { + /* + * This shouldn't happen unless a driver is mucking + * with the stream ID after submission. This will + * leave the TD on the hardware ring, and the hardware + * will try to execute it, and may access a buffer + * that has already been freed. In the best case, the + * hardware will execute it, and the event handler will + * ignore the completion event for that TD, since it was + * removed from the td_list for that endpoint. In + * short, don't muck with the stream ID after + * submission. + */ + dev_warn(usbssp_data->dev, "WARN Cancelled USB Request %p" + " has invalid stream ID %u.\n", + cur_td->priv_request, + cur_td->priv_request->request.stream_id); + goto remove_finished_td; + } + + if (!(ep->ep_state & USBSSP_EP_ENABLED) || + ep->ep_state & USBSSP_EP_DISABLE_PENDING) { + goto remove_finished_td; + } + + /* + * If we stopped on the TD we need to cancel, then we have to + * move the DC endpoint ring dequeue pointer past this TD. + */ + hw_deq = usbssp_get_hw_deq(usbssp_data, priv_dev, ep_index, + cur_td->priv_request->request.stream_id); + hw_deq &= ~0xf; + + if (usbssp_trb_in_td(usbssp_data, cur_td->start_seg, + cur_td->first_trb, cur_td->last_trb, hw_deq, false)) { + usbssp_find_new_dequeue_state(usbssp_data, ep_index, + cur_td->priv_request->request.stream_id, + cur_td, &deq_state); + } else { + td_to_noop(usbssp_data, ep_ring, cur_td, false); + } + +remove_finished_td: + /* + * The event handler won't see a completion for this TD anymore, + * so remove it from the endpoint ring's TD list. + */ + list_del_init(&cur_td->td_list); + } + + ep->ep_state &= ~EP_STOP_CMD_PENDING; + + if (!(ep->ep_state & USBSSP_EP_DISABLE_PENDING) && + ep->ep_state & USBSSP_EP_ENABLED) { + /* If necessary, queue a Set Transfer Ring Dequeue Pointer command*/ + if (deq_state.new_deq_ptr && deq_state.new_deq_seg) { + usbssp_queue_new_dequeue_state(usbssp_data, ep_index, + &deq_state); + usbssp_ring_cmd_db(usbssp_data); + } else { + /* + * Otherwise ring the doorbell(s) to restart queued + * transfers + */ + ring_doorbell_for_active_rings(usbssp_data, ep_index); + } + } + + /* + * Complete the cancellation of USB request. + */ + i = req_priv->num_tds_done; + for (; i < req_priv->num_tds; i++) { + cur_td = &req_priv->td[i]; + + /* + * Clean up the cancelled USB Request + * Doesn't matter what we pass for status, since the core will + * just overwrite it. + */ + ep_ring = usbssp_request_to_transfer_ring(usbssp_data, + cur_td->priv_request); + + usbssp_unmap_td_bounce_buffer(usbssp_data, ep_ring, cur_td); + + inc_td_cnt(cur_td->priv_request); + if (last_td_in_request(cur_td)) { + usbssp_giveback_request_in_irq(usbssp_data, + cur_td, -ECONNRESET); + } + } +} + + /* * When we get a command completion for a Stop Endpoint Command, we need to * stop timer and clear EP_STOP_CMD_PENDING flag. @@ -385,7 +709,6 @@ static void usbssp_handle_cmd_stop_ep(struct usbssp_udc *usbssp_data, "CMD stop endpoint completion for ep index: %d - %s\n", ep_index, ep->name); - priv_dev = &usbssp_data->devs; ep_ctx = usbssp_get_ep_ctx(usbssp_data, priv_dev->out_ctx, ep_index); trace_usbssp_handle_cmd_stop_ep(ep_ctx); @@ -2273,7 +2596,8 @@ void usbssp_queue_new_dequeue_state(struct usbssp_udc *usbssp_data, (unsigned long long)deq_state->new_deq_seg->dma, deq_state->new_deq_ptr, (unsigned long long)usbssp_trb_virt_to_dma( - deq_state->new_deq_seg, deq_state->new_deq_ptr), + deq_state->new_deq_seg, + deq_state->new_deq_ptr), deq_state->new_cycle_state); addr = usbssp_trb_virt_to_dma(deq_state->new_deq_seg, @@ -2284,6 +2608,7 @@ void usbssp_queue_new_dequeue_state(struct usbssp_udc *usbssp_data, deq_state->new_deq_seg, deq_state->new_deq_ptr); return; } + ep_priv = &usbssp_data->devs.eps[ep_index]; if ((ep_priv->ep_state & SET_DEQ_PENDING)) { dev_warn(usbssp_data->dev, "WARN Cannot submit Set TR Deq Ptr\n"); @@ -2304,10 +2629,12 @@ void usbssp_queue_new_dequeue_state(struct usbssp_udc *usbssp_data, ep_priv->queued_deq_ptr = deq_state->new_deq_ptr; if (deq_state->stream_id) trb_sct = SCT_FOR_TRB(SCT_PRI_TR); + ret = queue_command(usbssp_data, cmd, lower_32_bits(addr) | trb_sct | deq_state->new_cycle_state, upper_32_bits(addr), trb_stream_id, trb_slot_id | trb_ep_index | type, false); + if (ret < 0) { usbssp_free_command(usbssp_data, cmd); return; diff --git a/drivers/usb/usbssp/gadget.c b/drivers/usb/usbssp/gadget.c index e2751693404d..fe373a7b7198 100644 --- a/drivers/usb/usbssp/gadget.c +++ b/drivers/usb/usbssp/gadget.c @@ -545,8 +545,53 @@ int usbssp_enqueue(struct usbssp_ep *dep, struct usbssp_request *req_priv) */ int usbssp_dequeue(struct usbssp_ep *ep_priv, struct usbssp_request *req_priv) { - /*TODO: this function must be implemented*/ - return 0; + int ret = 0, i; + struct usbssp_udc *usbssp_data; + unsigned int ep_index; + struct usbssp_ring *ep_ring; + struct usbssp_device *priv_dev; + struct usbssp_ep_ctx *ep_ctx; + + usbssp_data = ep_priv->usbssp_data; + trace_usbssp_request_dequeue(&req_priv->request); + + priv_dev = &usbssp_data->devs; + ep_index = usbssp_get_endpoint_index(req_priv->dep->endpoint.desc); + ep_priv = &usbssp_data->devs.eps[ep_index]; + ep_ring = usbssp_request_to_transfer_ring(usbssp_data, req_priv); + + if (!ep_ring) + goto err_giveback; + + i = req_priv->num_tds_done; + + if (i < req_priv->num_tds) + usbssp_dbg_trace(usbssp_data, trace_usbssp_dbg_cancel_request, + "Cancel request %p, dev %s, ep 0x%x, " + "starting at offset 0x%llx", + &req_priv->request, usbssp_data->gadget.name, + req_priv->dep->endpoint.desc->bEndpointAddress, + (unsigned long long) usbssp_trb_virt_to_dma( + req_priv->td[i].start_seg, + req_priv->td[i].first_trb)); + + /* Queue a stop endpoint command, but only if it is + * in EP_STATE_RUNNING state. + */ + ep_ctx = usbssp_get_ep_ctx(usbssp_data, priv_dev->out_ctx, ep_index); + if (GET_EP_CTX_STATE(ep_ctx) == EP_STATE_RUNNING) { + ret = usbssp_cmd_stop_ep(usbssp_data, &usbssp_data->gadget, + ep_priv); + if (ret) + return ret; + } + + usbssp_remove_request(usbssp_data, req_priv, ep_index); + return ret; + +err_giveback: + usbssp_giveback_request_in_irq(usbssp_data, req_priv->td, -ESHUTDOWN); + return ret; } int usbssp_halt_endpoint(struct usbssp_udc *usbssp_data, struct usbssp_ep *dep, diff --git a/drivers/usb/usbssp/gadget.h b/drivers/usb/usbssp/gadget.h index 0477eb0f354c..000f2cb93723 100644 --- a/drivers/usb/usbssp/gadget.h +++ b/drivers/usb/usbssp/gadget.h @@ -1780,6 +1780,14 @@ int usbssp_queue_halt_endpoint(struct usbssp_udc *usbssp_data, unsigned int ep_index); int usbssp_queue_reset_device(struct usbssp_udc *usbssp_data, struct usbssp_command *cmd); +void usbssp_find_new_dequeue_state(struct usbssp_udc *usbssp_data, + unsigned int ep_index, + unsigned int stream_id, + struct usbssp_td *cur_td, + struct usbssp_dequeue_state *state); +void usbssp_queue_new_dequeue_state(struct usbssp_udc *usbssp_data, + unsigned int ep_index, + struct usbssp_dequeue_state *deq_state); void usbssp_handle_command_timeout(struct work_struct *work); void usbssp_cleanup_command_queue(struct usbssp_udc *usbssp_data); @@ -2313,4 +2321,7 @@ __le32 __iomem *usbssp_get_port_io_addr(struct usbssp_udc *usbssp_data); void usbssp_giveback_request_in_irq(struct usbssp_udc *usbssp_data, struct usbssp_td *cur_td, int status); +void usbssp_remove_request(struct usbssp_udc *usbssp_data, + struct usbssp_request *req_priv, int ep_index); + #endif /* __LINUX_USBSSP_GADGET_H */ -- 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: [22/31] usb: usbssp: added procedure removing request from transfer ring From: Pawel Laszczak Message-Id: <1532023084-28083-23-git-send-email-pawell@cadence.com> Date: Thu, 19 Jul 2018 18:57:55 +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: UGF0Y2ggYWRkcyBmdW5jdGlvbmFsaXR5IHRoYXQgYWxsb3dzIHRvIHJlbW92ZSB0aGUgcmVxdWVz dCBmcm9tIHRoZQplbmRwb2ludCByaW5nLiBUaGlzIG1heSBjYXVzZSB0aGUgREMgdG8gc3RvcCBV U0IgdHJhbnNmZXJzLApwb3RlbnRpYWxseSBzdG9wcGluZyBpbiB0aGUgbWlkZGxlIG9mIGEgVFJC IGJ1ZmZlci4gVGhlIERDIHNob3VsZApwaWNrIHVwIHdoZXJlIGl0IGxlZnQgb2ZmIGluIHRoZSBU RCwgdW5sZXNzIGEgU2V0IFRyYW5zZmVyIFJpbmcKRGVxdWV1ZSBQb2ludGVyIGlzIGlzc3VlZC4K ClNpZ25lZC1vZmYtYnk6IFBhd2VsIExhc3pjemFrIDxwYXdlbGxAY2FkZW5jZS5jb20+Ci0tLQog ZHJpdmVycy91c2IvdXNic3NwL2dhZGdldC1yaW5nLmMgfCAzMzEgKysrKysrKysrKysrKysrKysr KysrKysrKysrKysrLQogZHJpdmVycy91c2IvdXNic3NwL2dhZGdldC5jICAgICAgfCAgNDkgKysr Ky0KIGRyaXZlcnMvdXNiL3VzYnNzcC9nYWRnZXQuaCAgICAgIHwgIDExICsKIDMgZmlsZXMgY2hh bmdlZCwgMzg3IGluc2VydGlvbnMoKyksIDQgZGVsZXRpb25zKC0pCgpkaWZmIC0tZ2l0IGEvZHJp dmVycy91c2IvdXNic3NwL2dhZGdldC1yaW5nLmMgYi9kcml2ZXJzL3VzYi91c2Jzc3AvZ2FkZ2V0 LXJpbmcuYwppbmRleCA0YmIxM2Y5ZTMxMWEuLmNmYjMxMTIwZWVmOCAxMDA2NDQKLS0tIGEvZHJp dmVycy91c2IvdXNic3NwL2dhZGdldC1yaW5nLmMKKysrIGIvZHJpdmVycy91c2IvdXNic3NwL2dh ZGdldC1yaW5nLmMKQEAgLTEwMiwxMSArMTAyLDUxIEBAIHN0YXRpYyBib29sIGxpbmtfdHJiX3Rv Z2dsZXNfY3ljbGUodW5pb24gdXNic3NwX3RyYiAqdHJiKQogCXJldHVybiBsZTMyX3RvX2NwdSh0 cmItPmxpbmsuY29udHJvbCkgJiBMSU5LX1RPR0dMRTsKIH0KIAorc3RhdGljIGJvb2wgbGFzdF90 ZF9pbl9yZXF1ZXN0KHN0cnVjdCB1c2Jzc3BfdGQgKnRkKQoreworCXN0cnVjdCB1c2Jzc3BfcmVx dWVzdCAqcmVxX3ByaXYgPSB0ZC0+cHJpdl9yZXF1ZXN0OworCisJcmV0dXJuIHJlcV9wcml2LT5u dW1fdGRzX2RvbmUgPT0gcmVxX3ByaXYtPm51bV90ZHM7Cit9CisKIHN0YXRpYyB2b2lkIGluY190 ZF9jbnQoc3RydWN0IHVzYnNzcF9yZXF1ZXN0ICpwcml2X3JlcSkKIHsKIAlwcml2X3JlcS0+bnVt X3Rkc19kb25lKys7CiB9CiAKK3N0YXRpYyB2b2lkIHRyYl90b19ub29wKHVuaW9uIHVzYnNzcF90 cmIgKnRyYiwgdTMyIG5vb3BfdHlwZSkKK3sKKwlpZiAodHJiX2lzX2xpbmsodHJiKSkgeworCQkv KiB1bmNoYWluIGNoYWluZWQgbGluayBUUkJzICovCisJCXRyYi0+bGluay5jb250cm9sICY9IGNw dV90b19sZTMyKH5UUkJfQ0hBSU4pOworCX0gZWxzZSB7CisJCXRyYi0+Z2VuZXJpYy5maWVsZFsw XSA9IDA7CisJCXRyYi0+Z2VuZXJpYy5maWVsZFsxXSA9IDA7CisJCXRyYi0+Z2VuZXJpYy5maWVs ZFsyXSA9IDA7CisJCS8qIFByZXNlcnZlIG9ubHkgdGhlIGN5Y2xlIGJpdCBvZiB0aGlzIFRSQiAq LworCQl0cmItPmdlbmVyaWMuZmllbGRbM10gJj0gY3B1X3RvX2xlMzIoVFJCX0NZQ0xFKTsKKwkJ dHJiLT5nZW5lcmljLmZpZWxkWzNdIHw9IGNwdV90b19sZTMyKFRSQl9UWVBFKG5vb3BfdHlwZSkp OworCX0KK30KKworLyoKKyAqIFVwZGF0ZXMgdHJiIHRvIHBvaW50IHRvIHRoZSBuZXh0IFRSQiBp biB0aGUgcmluZywgYW5kIHVwZGF0ZXMgc2VnIGlmIHRoZSBuZXh0CisgKiBUUkIgaXMgaW4gYSBu ZXcgc2VnbWVudC4gVGhpcyBkb2VzIG5vdCBza2lwIG92ZXIgbGluayBUUkJzLCBhbmQgaXQgZG9l cyBub3QKKyAqIGVmZmVjdCB0aGUgcmluZyBkZXF1ZXVlIG9yIGVucXVldWUgcG9pbnRlcnMuCisg Ki8KK3N0YXRpYyB2b2lkIG5leHRfdHJiKHN0cnVjdCB1c2Jzc3BfdWRjICp1c2Jzc3BfZGF0YSwK KwkJICAgICBzdHJ1Y3QgdXNic3NwX3JpbmcgKnJpbmcsCisJCSAgICAgc3RydWN0IHVzYnNzcF9z ZWdtZW50ICoqc2VnLAorCQkgICAgIHVuaW9uIHVzYnNzcF90cmIgKip0cmIpCit7CisJaWYgKHRy Yl9pc19saW5rKCp0cmIpKSB7CisJCSpzZWcgPSAoKnNlZyktPm5leHQ7CisJCSp0cmIgPSAoKCpz ZWcpLT50cmJzKTsKKwl9IGVsc2UgeworCQkoKnRyYikrKzsKKwl9Cit9CisKIC8qCiAgKiBTZWUg Q3ljbGUgYml0IHJ1bGVzLiBTVyBpcyB0aGUgY29uc3VtZXIgZm9yIHRoZSBldmVudCByaW5nIG9u bHkuCiAgKiBEb24ndCBtYWtlIGEgcmluZyBmdWxsIG9mIGxpbmsgVFJCcy4gVGhhdCB3b3VsZCBi ZSBkdW1iIGFuZCB0aGlzIHdvdWxkIGxvb3AuCkBAIC0zNDcsNiArMzg3LDE1NyBAQCBzdHJ1Y3Qg dXNic3NwX3JpbmcgKnVzYnNzcF90cmlhZF90b190cmFuc2Zlcl9yaW5nKHN0cnVjdCB1c2Jzc3Bf dWRjICp1c2Jzc3BfZGF0YQogCXJldHVybiBOVUxMOwogfQogCisvKgorICogR2V0IHRoZSBodyBk ZXF1ZXVlIHBvaW50ZXIgREMgc3RvcHBlZCBvbiwgZWl0aGVyIGRpcmVjdGx5IGZyb20gdGhlCisg KiBlbmRwb2ludCBjb250ZXh0LCBvciBpZiBzdHJlYW1zIGFyZSBpbiB1c2UgZnJvbSB0aGUgc3Ry ZWFtIGNvbnRleHQuCisgKiBUaGUgcmV0dXJuZWQgaHdfZGVxdWV1ZSBjb250YWlucyB0aGUgbG93 ZXN0IGZvdXIgYml0cyB3aXRoIGN5Y2xlIHN0YXRlCisgKiBhbmQgcG9zc2JpbGUgc3RyZWFtIGNv bnRleHQgdHlwZS4KKyAqLwordTY0IHVzYnNzcF9nZXRfaHdfZGVxKHN0cnVjdCB1c2Jzc3BfdWRj ICp1c2Jzc3BfZGF0YSwKKwkJICAgICAgc3RydWN0IHVzYnNzcF9kZXZpY2UgKmRldiwKKwkJICAg ICAgdW5zaWduZWQgaW50IGVwX2luZGV4LAorCQkgICAgICB1bnNpZ25lZCBpbnQgc3RyZWFtX2lk KQoreworCXN0cnVjdCB1c2Jzc3BfZXBfY3R4ICplcF9jdHg7CisJc3RydWN0IHVzYnNzcF9zdHJl YW1fY3R4ICpzdF9jdHg7CisJc3RydWN0IHVzYnNzcF9lcCAqZXA7CisKKwllcCA9ICZkZXYtPmVw c1tlcF9pbmRleF07CisKKwlpZiAoZXAtPmVwX3N0YXRlICYgRVBfSEFTX1NUUkVBTVMpIHsKKwkJ c3RfY3R4ID0gJmVwLT5zdHJlYW1faW5mby0+c3RyZWFtX2N0eF9hcnJheVtzdHJlYW1faWRdOwor CQlyZXR1cm4gbGU2NF90b19jcHUoc3RfY3R4LT5zdHJlYW1fcmluZyk7CisJfQorCWVwX2N0eCA9 IHVzYnNzcF9nZXRfZXBfY3R4KHVzYnNzcF9kYXRhLCBkZXYtPm91dF9jdHgsIGVwX2luZGV4KTsK KwlyZXR1cm4gbGU2NF90b19jcHUoZXBfY3R4LT5kZXEpOworfQorCisvKgorICogTW92ZSB0aGUg REMgZW5kcG9pbnQgcmluZyBkZXF1ZXVlIHBvaW50ZXIgcGFzdCBjdXJfdGQuCisgKiBSZWNvcmQg dGhlIG5ldyBzdGF0ZSBvZiB0aGUgREMgZW5kcG9pbnQgcmluZyBkZXF1ZXVlIHNlZ21lbnQsCisg KiBkZXF1ZXVlIHBvaW50ZXIsIGFuZCBuZXcgY29uc3VtZXIgY3ljbGUgc3RhdGUgaW4gc3RhdGUu CisgKiBVcGRhdGUgb3VyIGludGVybmFsIHJlcHJlc2VudGF0aW9uIG9mIHRoZSByaW5nJ3MgZGVx dWV1ZSBwb2ludGVyLgorICoKKyAqIFdlIGRvIHRoaXMgaW4gdGhyZWUganVtcHM6CisgKiAgLSBG aXJzdCB3ZSB1cGRhdGUgb3VyIG5ldyByaW5nIHN0YXRlIHRvIGJlIHRoZSBzYW1lIGFzIHdoZW4g dGhlIERDIHN0b3BwZWQuCisgKiAgLSBUaGVuIHdlIHRyYXZlcnNlIHRoZSByaW5nIHRvIGZpbmQg dGhlIHNlZ21lbnQgdGhhdCBjb250YWlucworICogICAgdGhlIGxhc3QgVFJCIGluIHRoZSBURC4g V2UgdG9nZ2xlIHRoZSBEQyBuZXcgY3ljbGUgc3RhdGUgd2hlbiB3ZSBwYXNzCisgKiAgICBhbnkg bGluayBUUkJzIHdpdGggdGhlIHRvZ2dsZSBjeWNsZSBiaXQgc2V0LgorICogIC0gRmluYWxseSB3 ZSBtb3ZlIHRoZSBkZXF1ZXVlIHN0YXRlIG9uZSBUUkIgZnVydGhlciwgdG9nZ2xpbmcgdGhlIGN5 Y2xlIGJpdAorICogICAgaWYgd2UndmUgbW92ZWQgaXQgcGFzdCBhIGxpbmsgVFJCIHdpdGggdGhl IHRvZ2dsZSBjeWNsZSBiaXQgc2V0LgorICovCit2b2lkIHVzYnNzcF9maW5kX25ld19kZXF1ZXVl X3N0YXRlKHN0cnVjdCB1c2Jzc3BfdWRjICp1c2Jzc3BfZGF0YSwKKwkJCQkgICB1bnNpZ25lZCBp bnQgZXBfaW5kZXgsCisJCQkJICAgdW5zaWduZWQgaW50IHN0cmVhbV9pZCwKKwkJCQkgICBzdHJ1 Y3QgdXNic3NwX3RkICpjdXJfdGQsCisJCQkJICAgc3RydWN0IHVzYnNzcF9kZXF1ZXVlX3N0YXRl ICpzdGF0ZSkKK3sKKwlzdHJ1Y3QgdXNic3NwX2RldmljZSAqZGV2X3ByaXYgPSAmdXNic3NwX2Rh dGEtPmRldnM7CisJc3RydWN0IHVzYnNzcF9lcCAqZXBfcHJpdiA9ICZkZXZfcHJpdi0+ZXBzW2Vw X2luZGV4XTsKKwlzdHJ1Y3QgdXNic3NwX3JpbmcgKmVwX3Jpbmc7CisJc3RydWN0IHVzYnNzcF9z ZWdtZW50ICpuZXdfc2VnOworCXVuaW9uIHVzYnNzcF90cmIgKm5ld19kZXE7CisJZG1hX2FkZHJf dCBhZGRyOworCXU2NCBod19kZXF1ZXVlOworCWJvb2wgY3ljbGVfZm91bmQgPSBmYWxzZTsKKwli b29sIHRkX2xhc3RfdHJiX2ZvdW5kID0gZmFsc2U7CisKKwllcF9yaW5nID0gdXNic3NwX3RyaWFk X3RvX3RyYW5zZmVyX3JpbmcodXNic3NwX2RhdGEsCisJCQkJCQllcF9pbmRleCwgc3RyZWFtX2lk KTsKKwlpZiAoIWVwX3JpbmcpIHsKKwkJZGV2X3dhcm4odXNic3NwX2RhdGEtPmRldiwgIldBUk4g Y2FuJ3QgZmluZCBuZXcgZGVxdWV1ZSBzdGF0ZSAiCisJCQkiZm9yIGludmFsaWQgc3RyZWFtIElE ICV1LlxuIiwKKwkJCXN0cmVhbV9pZCk7CisJCXJldHVybjsKKwl9CisKKwkvKiBEaWcgb3V0IHRo ZSBjeWNsZSBzdGF0ZSBzYXZlZCBieSB0aGUgREMgZHVyaW5nIHRoZSBzdG9wIGVwIGNtZCAqLwor CXVzYnNzcF9kYmdfdHJhY2UodXNic3NwX2RhdGEsIHRyYWNlX3VzYnNzcF9kYmdfY2FuY2VsX3Jl cXVlc3QsCisJCQkiRmluZGluZyBlbmRwb2ludCBjb250ZXh0Iik7CisKKwlod19kZXF1ZXVlID0g dXNic3NwX2dldF9od19kZXEodXNic3NwX2RhdGEsIGRldl9wcml2LAorCQkJCWVwX2luZGV4LCBz dHJlYW1faWQpOworCW5ld19zZWcgPSBlcF9yaW5nLT5kZXFfc2VnOworCW5ld19kZXEgPSBlcF9y aW5nLT5kZXF1ZXVlOworCXN0YXRlLT5uZXdfY3ljbGVfc3RhdGUgPSBod19kZXF1ZXVlICYgMHgx OworCXN0YXRlLT5zdHJlYW1faWQgPSBzdHJlYW1faWQ7CisKKwkvKgorCSAqIFdlIHdhbnQgdG8g ZmluZCB0aGUgcG9pbnRlciwgc2VnbWVudCBhbmQgY3ljbGUgc3RhdGUgb2YgdGhlIG5ldyB0cmIK KwkgKiAodGhlIG9uZSBhZnRlciBjdXJyZW50IFREJ3MgbGFzdF90cmIpLiBXZSBrbm93IHRoZSBj eWNsZSBzdGF0ZSBhdAorCSAqIGh3X2RlcXVldWUsIHNvIHdhbGsgdGhlIHJpbmcgdW50aWwgYm90 aCBod19kZXF1ZXVlIGFuZCBsYXN0X3RyYiBhcmUKKwkgKiBmb3VuZC4KKwkgKi8KKwlkbyB7CisJ CWlmICghY3ljbGVfZm91bmQgJiYgdXNic3NwX3RyYl92aXJ0X3RvX2RtYShuZXdfc2VnLCBuZXdf ZGVxKQorCQkgICAgPT0gKGRtYV9hZGRyX3QpKGh3X2RlcXVldWUgJiB+MHhmKSkgeworCQkJY3lj bGVfZm91bmQgPSB0cnVlOworCQkJaWYgKHRkX2xhc3RfdHJiX2ZvdW5kKQorCQkJCWJyZWFrOwor CQl9CisKKwkJaWYgKG5ld19kZXEgPT0gY3VyX3RkLT5sYXN0X3RyYikKKwkJCXRkX2xhc3RfdHJi X2ZvdW5kID0gdHJ1ZTsKKworCQlpZiAoY3ljbGVfZm91bmQgJiYgdHJiX2lzX2xpbmsobmV3X2Rl cSkgJiYKKwkJCWxpbmtfdHJiX3RvZ2dsZXNfY3ljbGUobmV3X2RlcSkpCisJCQlzdGF0ZS0+bmV3 X2N5Y2xlX3N0YXRlIF49IDB4MTsKKworCQluZXh0X3RyYih1c2Jzc3BfZGF0YSwgZXBfcmluZywg Jm5ld19zZWcsICZuZXdfZGVxKTsKKworCQkvKiBTZWFyY2ggd3JhcHBlZCBhcm91bmQsIGJhaWwg b3V0ICovCisJCWlmIChuZXdfZGVxID09IGVwX3ByaXYtPnJpbmctPmRlcXVldWUpIHsKKwkJCWRl dl9lcnIodXNic3NwX2RhdGEtPmRldiwKKwkJCQkiRXJyb3I6IEZhaWxlZCBmaW5kaW5nIG5ldyBk ZXF1ZXVlIHN0YXRlXG4iKTsKKwkJCXN0YXRlLT5uZXdfZGVxX3NlZyA9IE5VTEw7CisJCQlzdGF0 ZS0+bmV3X2RlcV9wdHIgPSBOVUxMOworCQkJcmV0dXJuOworCQl9CisKKwl9IHdoaWxlICghY3lj bGVfZm91bmQgfHwgIXRkX2xhc3RfdHJiX2ZvdW5kKTsKKworCXN0YXRlLT5uZXdfZGVxX3NlZyA9 IG5ld19zZWc7CisJc3RhdGUtPm5ld19kZXFfcHRyID0gbmV3X2RlcTsKKworCS8qIERvbid0IHVw ZGF0ZSB0aGUgcmluZyBjeWNsZSBzdGF0ZSBmb3IgdGhlIHByb2R1Y2VyICh1cykuICovCisJdXNi c3NwX2RiZ190cmFjZSh1c2Jzc3BfZGF0YSwgdHJhY2VfdXNic3NwX2RiZ19jYW5jZWxfcmVxdWVz dCwKKwkJCSJDeWNsZSBzdGF0ZSA9IDB4JXgiLCBzdGF0ZS0+bmV3X2N5Y2xlX3N0YXRlKTsKKwor CXVzYnNzcF9kYmdfdHJhY2UodXNic3NwX2RhdGEsIHRyYWNlX3VzYnNzcF9kYmdfY2FuY2VsX3Jl cXVlc3QsCisJCQkiTmV3IGRlcXVldWUgc2VnbWVudCA9ICVwICh2aXJ0dWFsKSIsCisJCQlzdGF0 ZS0+bmV3X2RlcV9zZWcpOworCWFkZHIgPSB1c2Jzc3BfdHJiX3ZpcnRfdG9fZG1hKHN0YXRlLT5u ZXdfZGVxX3NlZywgc3RhdGUtPm5ld19kZXFfcHRyKTsKKwl1c2Jzc3BfZGJnX3RyYWNlKHVzYnNz cF9kYXRhLCB0cmFjZV91c2Jzc3BfZGJnX2NhbmNlbF9yZXF1ZXN0LAorCQkJIk5ldyBkZXF1ZXVl IHBvaW50ZXIgPSAweCVsbHggKERNQSkiLAorCQkJKHVuc2lnbmVkIGxvbmcgbG9uZykgYWRkcik7 Cit9CisKKy8qCisgKiBmbGlwX2N5Y2xlIG1lYW5zIGZsaXAgdGhlIGN5Y2xlIGJpdCBvZiBhbGwg YnV0IHRoZSBmaXJzdCBhbmQgbGFzdCBUUkIuCisgKiAoVGhlIGxhc3QgVFJCIGFjdHVhbGx5IHBv aW50cyB0byB0aGUgcmluZyBlbnF1ZXVlIHBvaW50ZXIsIHdoaWNoIGlzIG5vdCBwYXJ0CisgKiBv ZiB0aGlzIFRELikgVGhpcyBpcyB1c2VkIHRvIHJlbW92ZSBwYXJ0aWFsbHkgZW5xdWV1ZWQgaXNv YyBURHMgZnJvbSBhIHJpbmcuCisgKi8KK3N0YXRpYyB2b2lkIHRkX3RvX25vb3Aoc3RydWN0IHVz YnNzcF91ZGMgKnVzYnNzcF9kYXRhLAorCQkgICAgICAgc3RydWN0IHVzYnNzcF9yaW5nICplcF9y aW5nLAorCQkgICAgICAgc3RydWN0IHVzYnNzcF90ZCAqdGQsIGJvb2wgZmxpcF9jeWNsZSkKK3sK KwlzdHJ1Y3QgdXNic3NwX3NlZ21lbnQgKnNlZyA9IHRkLT5zdGFydF9zZWc7CisJdW5pb24gdXNi c3NwX3RyYiAqdHJiID0gdGQtPmZpcnN0X3RyYjsKKworCXdoaWxlICgxKSB7CisJCXRyYl90b19u b29wKHRyYiwgVFJCX1RSX05PT1ApOworCisJCS8qIGZsaXAgY3ljbGUgaWYgYXNrZWQgdG8gKi8K KwkJaWYgKGZsaXBfY3ljbGUgJiYgdHJiICE9IHRkLT5maXJzdF90cmIgJiYgdHJiICE9IHRkLT5s YXN0X3RyYikKKwkJCXRyYi0+Z2VuZXJpYy5maWVsZFszXSBePSBjcHVfdG9fbGUzMihUUkJfQ1lD TEUpOworCisJCWlmICh0cmIgPT0gdGQtPmxhc3RfdHJiKQorCQkJYnJlYWs7CisKKwkJbmV4dF90 cmIodXNic3NwX2RhdGEsIGVwX3JpbmcsICZzZWcsICZ0cmIpOworCX0KK30KKwogLyogTXVzdCBi ZSBjYWxsZWQgd2l0aCB1c2Jzc3BfZGF0YS0+bG9jayBoZWxkIGluIGludGVycnVwdCBjb250ZXh0 CiAgKiBvciB1c2Jzc3BfZGF0YS0+aXJxX3RocmVhZF9sb2NrIGZyb20gdGhyZWFkIGNvbmV4dCAo ZGVmZXJlZCBpbnRlcnJ1cHQpCiAgKi8KQEAgLTM2NSw2ICs1NTYsMTM5IEBAIHZvaWQgdXNic3Nw X2dpdmViYWNrX3JlcXVlc3RfaW5faXJxKHN0cnVjdCB1c2Jzc3BfdWRjICp1c2Jzc3BfZGF0YSwK IAl1c2Jzc3BfZ2FkZ2V0X2dpdmViYWNrKHJlcV9wcml2LT5kZXAsIHJlcV9wcml2LCBzdGF0dXMp OwogfQogCit2b2lkIHVzYnNzcF91bm1hcF90ZF9ib3VuY2VfYnVmZmVyKHN0cnVjdCB1c2Jzc3Bf dWRjICp1c2Jzc3BfZGF0YSwKKwkJCQkgICBzdHJ1Y3QgdXNic3NwX3JpbmcgKnJpbmcsCisJCQkJ ICAgc3RydWN0IHVzYnNzcF90ZCAqdGQpCit7CisJLypUT0RPOiA/Pz8gKi8KK30KKwordm9pZCB1 c2Jzc3BfcmVtb3ZlX3JlcXVlc3Qoc3RydWN0IHVzYnNzcF91ZGMgKnVzYnNzcF9kYXRhLAorCQkJ ICAgc3RydWN0IHVzYnNzcF9yZXF1ZXN0ICpyZXFfcHJpdiwgaW50IGVwX2luZGV4KQoreworCWlu dCBpID0gMDsKKwlzdHJ1Y3QgdXNic3NwX3JpbmcgKmVwX3Jpbmc7CisJc3RydWN0IHVzYnNzcF9l cCAqZXA7CisJc3RydWN0IHVzYnNzcF90ZCAqY3VyX3RkID0gTlVMTDsKKwlzdHJ1Y3QgdXNic3Nw X2VwX2N0eCAqZXBfY3R4OworCXN0cnVjdCB1c2Jzc3BfZGV2aWNlICpwcml2X2RldjsKKwl1NjQg aHdfZGVxOworCXN0cnVjdCB1c2Jzc3BfZGVxdWV1ZV9zdGF0ZSBkZXFfc3RhdGU7CisKKwltZW1z ZXQoJmRlcV9zdGF0ZSwgMCwgc2l6ZW9mKGRlcV9zdGF0ZSkpOworCWVwID0gJnVzYnNzcF9kYXRh LT5kZXZzLmVwc1tlcF9pbmRleF07CisKKwlwcml2X2RldiA9ICZ1c2Jzc3BfZGF0YS0+ZGV2czsK KwllcF9jdHggPSB1c2Jzc3BfZ2V0X2VwX2N0eCh1c2Jzc3BfZGF0YSwgcHJpdl9kZXYtPm91dF9j dHgsIGVwX2luZGV4KTsKKwl0cmFjZV91c2Jzc3BfcmVtb3ZlX3JlcXVlc3QoZXBfY3R4KTsKKwor CWkgPSByZXFfcHJpdi0+bnVtX3Rkc19kb25lOworCisJZm9yICg7IGkgPCByZXFfcHJpdi0+bnVt X3RkczsgaSsrKSB7CisJCWN1cl90ZCA9ICZyZXFfcHJpdi0+dGRbaV07CisJCXVzYnNzcF9kYmdf dHJhY2UodXNic3NwX2RhdGEsIHRyYWNlX3VzYnNzcF9kYmdfY2FuY2VsX3JlcXVlc3QsCisJCQki UmVtb3ZpbmcgY2FuY2VsZWQgVEQgc3RhcnRpbmcgYXQgMHglbGx4IChkbWEpLiIsCisJCQkodW5z aWduZWQgbG9uZyBsb25nKXVzYnNzcF90cmJfdmlydF90b19kbWEoCisJCQkJCQkJY3VyX3RkLT5z dGFydF9zZWcsCisJCQkJCQkJY3VyX3RkLT5maXJzdF90cmIpKTsKKworCQllcF9yaW5nID0gdXNi c3NwX3JlcXVlc3RfdG9fdHJhbnNmZXJfcmluZyh1c2Jzc3BfZGF0YSwKKwkJCQkJCQljdXJfdGQt PnByaXZfcmVxdWVzdCk7CisKKwkJaWYgKCFlcF9yaW5nKSB7CisJCQkvKgorCQkJICogVGhpcyBz aG91bGRuJ3QgaGFwcGVuIHVubGVzcyBhIGRyaXZlciBpcyBtdWNraW5nCisJCQkgKiB3aXRoIHRo ZSBzdHJlYW0gSUQgYWZ0ZXIgc3VibWlzc2lvbi4gVGhpcyB3aWxsCisJCQkgKiBsZWF2ZSB0aGUg VEQgb24gdGhlIGhhcmR3YXJlIHJpbmcsIGFuZCB0aGUgaGFyZHdhcmUKKwkJCSAqIHdpbGwgdHJ5 IHRvIGV4ZWN1dGUgaXQsIGFuZCBtYXkgYWNjZXNzIGEgYnVmZmVyCisJCQkgKiB0aGF0IGhhcyBh bHJlYWR5IGJlZW4gZnJlZWQuIEluIHRoZSBiZXN0IGNhc2UsIHRoZQorCQkJICogaGFyZHdhcmUg d2lsbCBleGVjdXRlIGl0LCBhbmQgdGhlIGV2ZW50IGhhbmRsZXIgd2lsbAorCQkJICogaWdub3Jl IHRoZSBjb21wbGV0aW9uIGV2ZW50IGZvciB0aGF0IFRELCBzaW5jZSBpdCB3YXMKKwkJCSAqIHJl bW92ZWQgZnJvbSB0aGUgdGRfbGlzdCBmb3IgdGhhdCBlbmRwb2ludC4gSW4KKwkJCSAqIHNob3J0 LCBkb24ndCBtdWNrIHdpdGggdGhlIHN0cmVhbSBJRCBhZnRlcgorCQkJICogc3VibWlzc2lvbi4K KwkJCSAqLworCQkJZGV2X3dhcm4odXNic3NwX2RhdGEtPmRldiwgIldBUk4gQ2FuY2VsbGVkIFVT QiBSZXF1ZXN0ICVwIgorCQkJCSIgaGFzIGludmFsaWQgc3RyZWFtIElEICV1LlxuIiwKKwkJCQlj dXJfdGQtPnByaXZfcmVxdWVzdCwKKwkJCQljdXJfdGQtPnByaXZfcmVxdWVzdC0+cmVxdWVzdC5z dHJlYW1faWQpOworCQkJZ290byByZW1vdmVfZmluaXNoZWRfdGQ7CisJCX0KKworCQlpZiAoIShl cC0+ZXBfc3RhdGUgJiBVU0JTU1BfRVBfRU5BQkxFRCkgfHwKKwkJICAgZXAtPmVwX3N0YXRlICYg VVNCU1NQX0VQX0RJU0FCTEVfUEVORElORykgeworCQkJZ290byByZW1vdmVfZmluaXNoZWRfdGQ7 CisJCX0KKworCQkvKgorCQkgKiBJZiB3ZSBzdG9wcGVkIG9uIHRoZSBURCB3ZSBuZWVkIHRvIGNh bmNlbCwgdGhlbiB3ZSBoYXZlIHRvCisJCSAqIG1vdmUgdGhlIERDIGVuZHBvaW50IHJpbmcgZGVx dWV1ZSBwb2ludGVyIHBhc3QgdGhpcyBURC4KKwkJICovCisJCWh3X2RlcSA9IHVzYnNzcF9nZXRf aHdfZGVxKHVzYnNzcF9kYXRhLCBwcml2X2RldiwgZXBfaW5kZXgsCisJCQkJCWN1cl90ZC0+cHJp dl9yZXF1ZXN0LT5yZXF1ZXN0LnN0cmVhbV9pZCk7CisJCWh3X2RlcSAmPSB+MHhmOworCisJCWlm ICh1c2Jzc3BfdHJiX2luX3RkKHVzYnNzcF9kYXRhLCBjdXJfdGQtPnN0YXJ0X3NlZywKKwkJCWN1 cl90ZC0+Zmlyc3RfdHJiLCBjdXJfdGQtPmxhc3RfdHJiLCBod19kZXEsIGZhbHNlKSkgeworCQkJ dXNic3NwX2ZpbmRfbmV3X2RlcXVldWVfc3RhdGUodXNic3NwX2RhdGEsIGVwX2luZGV4LAorCQkJ CQkJY3VyX3RkLT5wcml2X3JlcXVlc3QtPnJlcXVlc3Quc3RyZWFtX2lkLAorCQkJCQkJY3VyX3Rk LCAmZGVxX3N0YXRlKTsKKwkJfSBlbHNlIHsKKwkJCXRkX3RvX25vb3AodXNic3NwX2RhdGEsIGVw X3JpbmcsIGN1cl90ZCwgZmFsc2UpOworCQl9CisKK3JlbW92ZV9maW5pc2hlZF90ZDoKKwkJLyoK KwkJICogVGhlIGV2ZW50IGhhbmRsZXIgd29uJ3Qgc2VlIGEgY29tcGxldGlvbiBmb3IgdGhpcyBU RCBhbnltb3JlLAorCQkgKiBzbyByZW1vdmUgaXQgZnJvbSB0aGUgZW5kcG9pbnQgcmluZydzIFRE IGxpc3QuCisJCSAqLworCQlsaXN0X2RlbF9pbml0KCZjdXJfdGQtPnRkX2xpc3QpOworCX0KKwor CWVwLT5lcF9zdGF0ZSAmPSB+RVBfU1RPUF9DTURfUEVORElORzsKKworCWlmICghKGVwLT5lcF9z dGF0ZSAmIFVTQlNTUF9FUF9ESVNBQkxFX1BFTkRJTkcpICYmCisJCWVwLT5lcF9zdGF0ZSAmIFVT QlNTUF9FUF9FTkFCTEVEKSB7CisJCS8qIElmIG5lY2Vzc2FyeSwgcXVldWUgYSBTZXQgVHJhbnNm ZXIgUmluZyBEZXF1ZXVlIFBvaW50ZXIgY29tbWFuZCovCisJCWlmIChkZXFfc3RhdGUubmV3X2Rl cV9wdHIgJiYgZGVxX3N0YXRlLm5ld19kZXFfc2VnKSB7CisJCQl1c2Jzc3BfcXVldWVfbmV3X2Rl cXVldWVfc3RhdGUodXNic3NwX2RhdGEsIGVwX2luZGV4LAorCQkJCQkJJmRlcV9zdGF0ZSk7CisJ CQl1c2Jzc3BfcmluZ19jbWRfZGIodXNic3NwX2RhdGEpOworCQl9IGVsc2UgeworCQkJLyoKKwkJ CSAqIE90aGVyd2lzZSByaW5nIHRoZSBkb29yYmVsbChzKSB0byByZXN0YXJ0IHF1ZXVlZAorCQkJ ICogdHJhbnNmZXJzCisJCQkgKi8KKwkJCXJpbmdfZG9vcmJlbGxfZm9yX2FjdGl2ZV9yaW5ncyh1 c2Jzc3BfZGF0YSwgZXBfaW5kZXgpOworCQl9CisJfQorCisJLyoKKwkgKiBDb21wbGV0ZSB0aGUg Y2FuY2VsbGF0aW9uIG9mIFVTQiByZXF1ZXN0LgorCSAqLworCWkgPSByZXFfcHJpdi0+bnVtX3Rk c19kb25lOworCWZvciAoOyBpIDwgcmVxX3ByaXYtPm51bV90ZHM7IGkrKykgeworCQljdXJfdGQg PSAmcmVxX3ByaXYtPnRkW2ldOworCisJCS8qCisJCSAqIENsZWFuIHVwIHRoZSBjYW5jZWxsZWQg VVNCIFJlcXVlc3QKKwkJICogRG9lc24ndCBtYXR0ZXIgd2hhdCB3ZSBwYXNzIGZvciBzdGF0dXMs IHNpbmNlIHRoZSBjb3JlIHdpbGwKKwkJICoganVzdCBvdmVyd3JpdGUgaXQuCisJCSAqLworCQll cF9yaW5nID0gdXNic3NwX3JlcXVlc3RfdG9fdHJhbnNmZXJfcmluZyh1c2Jzc3BfZGF0YSwKKwkJ CQkJCQljdXJfdGQtPnByaXZfcmVxdWVzdCk7CisKKwkJdXNic3NwX3VubWFwX3RkX2JvdW5jZV9i dWZmZXIodXNic3NwX2RhdGEsIGVwX3JpbmcsIGN1cl90ZCk7CisKKwkJaW5jX3RkX2NudChjdXJf dGQtPnByaXZfcmVxdWVzdCk7CisJCWlmIChsYXN0X3RkX2luX3JlcXVlc3QoY3VyX3RkKSkgewor CQkJdXNic3NwX2dpdmViYWNrX3JlcXVlc3RfaW5faXJxKHVzYnNzcF9kYXRhLAorCQkJCQkJY3Vy X3RkLCAtRUNPTk5SRVNFVCk7CisJCX0KKwl9Cit9CisKKwogLyoKICAqIFdoZW4gd2UgZ2V0IGEg Y29tbWFuZCBjb21wbGV0aW9uIGZvciBhIFN0b3AgRW5kcG9pbnQgQ29tbWFuZCwgd2UgbmVlZCB0 bwogICogc3RvcCB0aW1lciBhbmQgY2xlYXIgRVBfU1RPUF9DTURfUEVORElORyBmbGFnLgpAQCAt Mzg1LDcgKzcwOSw2IEBAIHN0YXRpYyB2b2lkIHVzYnNzcF9oYW5kbGVfY21kX3N0b3BfZXAoc3Ry dWN0IHVzYnNzcF91ZGMgKnVzYnNzcF9kYXRhLAogCQkiQ01EIHN0b3AgZW5kcG9pbnQgY29tcGxl dGlvbiBmb3IgZXAgaW5kZXg6ICVkIC0gJXNcbiIsCiAJCWVwX2luZGV4LCBlcC0+bmFtZSk7CiAK LQogCXByaXZfZGV2ID0gJnVzYnNzcF9kYXRhLT5kZXZzOwogCWVwX2N0eCA9IHVzYnNzcF9nZXRf ZXBfY3R4KHVzYnNzcF9kYXRhLCBwcml2X2Rldi0+b3V0X2N0eCwgZXBfaW5kZXgpOwogCXRyYWNl X3VzYnNzcF9oYW5kbGVfY21kX3N0b3BfZXAoZXBfY3R4KTsKQEAgLTIyNzMsNyArMjU5Niw4IEBA IHZvaWQgdXNic3NwX3F1ZXVlX25ld19kZXF1ZXVlX3N0YXRlKHN0cnVjdCB1c2Jzc3BfdWRjICp1 c2Jzc3BfZGF0YSwKIAkJKHVuc2lnbmVkIGxvbmcgbG9uZylkZXFfc3RhdGUtPm5ld19kZXFfc2Vn LT5kbWEsCiAJCWRlcV9zdGF0ZS0+bmV3X2RlcV9wdHIsCiAJCSh1bnNpZ25lZCBsb25nIGxvbmcp dXNic3NwX3RyYl92aXJ0X3RvX2RtYSgKLQkJCWRlcV9zdGF0ZS0+bmV3X2RlcV9zZWcsIGRlcV9z dGF0ZS0+bmV3X2RlcV9wdHIpLAorCQkJCQkJZGVxX3N0YXRlLT5uZXdfZGVxX3NlZywKKwkJCQkJ CWRlcV9zdGF0ZS0+bmV3X2RlcV9wdHIpLAogCQlkZXFfc3RhdGUtPm5ld19jeWNsZV9zdGF0ZSk7 CiAKIAlhZGRyID0gdXNic3NwX3RyYl92aXJ0X3RvX2RtYShkZXFfc3RhdGUtPm5ld19kZXFfc2Vn LApAQCAtMjI4NCw2ICsyNjA4LDcgQEAgdm9pZCB1c2Jzc3BfcXVldWVfbmV3X2RlcXVldWVfc3Rh dGUoc3RydWN0IHVzYnNzcF91ZGMgKnVzYnNzcF9kYXRhLAogCQkJZGVxX3N0YXRlLT5uZXdfZGVx X3NlZywgZGVxX3N0YXRlLT5uZXdfZGVxX3B0cik7CiAJCXJldHVybjsKIAl9CisKIAllcF9wcml2 ID0gJnVzYnNzcF9kYXRhLT5kZXZzLmVwc1tlcF9pbmRleF07CiAJaWYgKChlcF9wcml2LT5lcF9z dGF0ZSAmIFNFVF9ERVFfUEVORElORykpIHsKIAkJZGV2X3dhcm4odXNic3NwX2RhdGEtPmRldiwg IldBUk4gQ2Fubm90IHN1Ym1pdCBTZXQgVFIgRGVxIFB0clxuIik7CkBAIC0yMzA0LDEwICsyNjI5 LDEyIEBAIHZvaWQgdXNic3NwX3F1ZXVlX25ld19kZXF1ZXVlX3N0YXRlKHN0cnVjdCB1c2Jzc3Bf dWRjICp1c2Jzc3BfZGF0YSwKIAllcF9wcml2LT5xdWV1ZWRfZGVxX3B0ciA9IGRlcV9zdGF0ZS0+ bmV3X2RlcV9wdHI7CiAJaWYgKGRlcV9zdGF0ZS0+c3RyZWFtX2lkKQogCQl0cmJfc2N0ID0gU0NU X0ZPUl9UUkIoU0NUX1BSSV9UUik7CisKIAlyZXQgPSBxdWV1ZV9jb21tYW5kKHVzYnNzcF9kYXRh LCBjbWQsCiAJCWxvd2VyXzMyX2JpdHMoYWRkcikgfCB0cmJfc2N0IHwgZGVxX3N0YXRlLT5uZXdf Y3ljbGVfc3RhdGUsCiAJCXVwcGVyXzMyX2JpdHMoYWRkciksIHRyYl9zdHJlYW1faWQsCiAJCXRy Yl9zbG90X2lkIHwgdHJiX2VwX2luZGV4IHwgdHlwZSwgZmFsc2UpOworCiAJaWYgKHJldCA8IDAp IHsKIAkJdXNic3NwX2ZyZWVfY29tbWFuZCh1c2Jzc3BfZGF0YSwgY21kKTsKIAkJcmV0dXJuOwpk aWZmIC0tZ2l0IGEvZHJpdmVycy91c2IvdXNic3NwL2dhZGdldC5jIGIvZHJpdmVycy91c2IvdXNi c3NwL2dhZGdldC5jCmluZGV4IGUyNzUxNjkzNDA0ZC4uZmUzNzNhN2I3MTk4IDEwMDY0NAotLS0g YS9kcml2ZXJzL3VzYi91c2Jzc3AvZ2FkZ2V0LmMKKysrIGIvZHJpdmVycy91c2IvdXNic3NwL2dh ZGdldC5jCkBAIC01NDUsOCArNTQ1LDUzIEBAIGludCB1c2Jzc3BfZW5xdWV1ZShzdHJ1Y3QgdXNi c3NwX2VwICpkZXAsIHN0cnVjdCB1c2Jzc3BfcmVxdWVzdCAqcmVxX3ByaXYpCiAgKi8KIGludCB1 c2Jzc3BfZGVxdWV1ZShzdHJ1Y3QgdXNic3NwX2VwICplcF9wcml2LCBzdHJ1Y3QgdXNic3NwX3Jl cXVlc3QgKnJlcV9wcml2KQogewotCS8qVE9ETzogdGhpcyBmdW5jdGlvbiBtdXN0IGJlIGltcGxl bWVudGVkKi8KLQlyZXR1cm4gMDsKKwlpbnQgcmV0ID0gMCwgaTsKKwlzdHJ1Y3QgdXNic3NwX3Vk YyAqdXNic3NwX2RhdGE7CisJdW5zaWduZWQgaW50IGVwX2luZGV4OworCXN0cnVjdCB1c2Jzc3Bf cmluZyAqZXBfcmluZzsKKwlzdHJ1Y3QgdXNic3NwX2RldmljZSAqcHJpdl9kZXY7CisJc3RydWN0 IHVzYnNzcF9lcF9jdHggKmVwX2N0eDsKKworCXVzYnNzcF9kYXRhID0gZXBfcHJpdi0+dXNic3Nw X2RhdGE7CisJdHJhY2VfdXNic3NwX3JlcXVlc3RfZGVxdWV1ZSgmcmVxX3ByaXYtPnJlcXVlc3Qp OworCisJcHJpdl9kZXYgPSAmdXNic3NwX2RhdGEtPmRldnM7CisJZXBfaW5kZXggPSB1c2Jzc3Bf Z2V0X2VuZHBvaW50X2luZGV4KHJlcV9wcml2LT5kZXAtPmVuZHBvaW50LmRlc2MpOworCWVwX3By aXYgPSAmdXNic3NwX2RhdGEtPmRldnMuZXBzW2VwX2luZGV4XTsKKwllcF9yaW5nID0gdXNic3Nw X3JlcXVlc3RfdG9fdHJhbnNmZXJfcmluZyh1c2Jzc3BfZGF0YSwgcmVxX3ByaXYpOworCisJaWYg KCFlcF9yaW5nKQorCQlnb3RvIGVycl9naXZlYmFjazsKKworCWkgPSByZXFfcHJpdi0+bnVtX3Rk c19kb25lOworCisJaWYgKGkgPCByZXFfcHJpdi0+bnVtX3RkcykKKwkJdXNic3NwX2RiZ190cmFj ZSh1c2Jzc3BfZGF0YSwgdHJhY2VfdXNic3NwX2RiZ19jYW5jZWxfcmVxdWVzdCwKKwkJCSJDYW5j ZWwgcmVxdWVzdCAlcCwgZGV2ICVzLCBlcCAweCV4LCAiCisJCQkic3RhcnRpbmcgYXQgb2Zmc2V0 IDB4JWxseCIsCisJCQkmcmVxX3ByaXYtPnJlcXVlc3QsIHVzYnNzcF9kYXRhLT5nYWRnZXQubmFt ZSwKKwkJCXJlcV9wcml2LT5kZXAtPmVuZHBvaW50LmRlc2MtPmJFbmRwb2ludEFkZHJlc3MsCisJ CQkodW5zaWduZWQgbG9uZyBsb25nKSB1c2Jzc3BfdHJiX3ZpcnRfdG9fZG1hKAorCQkJCQkJcmVx X3ByaXYtPnRkW2ldLnN0YXJ0X3NlZywKKwkJCQkJCXJlcV9wcml2LT50ZFtpXS5maXJzdF90cmIp KTsKKworCS8qIFF1ZXVlIGEgc3RvcCBlbmRwb2ludCBjb21tYW5kLCBidXQgb25seSBpZiBpdCBp cworCSAqIGluIEVQX1NUQVRFX1JVTk5JTkcgc3RhdGUuCisJICovCisJZXBfY3R4ID0gdXNic3Nw X2dldF9lcF9jdHgodXNic3NwX2RhdGEsIHByaXZfZGV2LT5vdXRfY3R4LCBlcF9pbmRleCk7CisJ aWYgKEdFVF9FUF9DVFhfU1RBVEUoZXBfY3R4KSA9PSBFUF9TVEFURV9SVU5OSU5HKSB7CisJCXJl dCA9IHVzYnNzcF9jbWRfc3RvcF9lcCh1c2Jzc3BfZGF0YSwgJnVzYnNzcF9kYXRhLT5nYWRnZXQs CisJCQkJCWVwX3ByaXYpOworCQlpZiAocmV0KQorCQkJcmV0dXJuIHJldDsKKwl9CisKKwl1c2Jz c3BfcmVtb3ZlX3JlcXVlc3QodXNic3NwX2RhdGEsIHJlcV9wcml2LCBlcF9pbmRleCk7CisJcmV0 dXJuIHJldDsKKworZXJyX2dpdmViYWNrOgorCXVzYnNzcF9naXZlYmFja19yZXF1ZXN0X2luX2ly cSh1c2Jzc3BfZGF0YSwgcmVxX3ByaXYtPnRkLCAtRVNIVVRET1dOKTsKKwlyZXR1cm4gcmV0Owog fQogCiBpbnQgdXNic3NwX2hhbHRfZW5kcG9pbnQoc3RydWN0IHVzYnNzcF91ZGMgKnVzYnNzcF9k YXRhLCBzdHJ1Y3QgdXNic3NwX2VwICpkZXAsCmRpZmYgLS1naXQgYS9kcml2ZXJzL3VzYi91c2Jz c3AvZ2FkZ2V0LmggYi9kcml2ZXJzL3VzYi91c2Jzc3AvZ2FkZ2V0LmgKaW5kZXggMDQ3N2ViMGYz NTRjLi4wMDBmMmNiOTM3MjMgMTAwNjQ0Ci0tLSBhL2RyaXZlcnMvdXNiL3VzYnNzcC9nYWRnZXQu aAorKysgYi9kcml2ZXJzL3VzYi91c2Jzc3AvZ2FkZ2V0LmgKQEAgLTE3ODAsNiArMTc4MCwxNCBA QCBpbnQgdXNic3NwX3F1ZXVlX2hhbHRfZW5kcG9pbnQoc3RydWN0IHVzYnNzcF91ZGMgKnVzYnNz cF9kYXRhLAogCQkJdW5zaWduZWQgaW50IGVwX2luZGV4KTsKIGludCB1c2Jzc3BfcXVldWVfcmVz ZXRfZGV2aWNlKHN0cnVjdCB1c2Jzc3BfdWRjICp1c2Jzc3BfZGF0YSwKIAkJCXN0cnVjdCB1c2Jz c3BfY29tbWFuZCAqY21kKTsKK3ZvaWQgdXNic3NwX2ZpbmRfbmV3X2RlcXVldWVfc3RhdGUoc3Ry dWN0IHVzYnNzcF91ZGMgKnVzYnNzcF9kYXRhLAorCQkJCXVuc2lnbmVkIGludCBlcF9pbmRleCwK KwkJCQl1bnNpZ25lZCBpbnQgc3RyZWFtX2lkLAorCQkJCXN0cnVjdCB1c2Jzc3BfdGQgKmN1cl90 ZCwKKwkJCQlzdHJ1Y3QgdXNic3NwX2RlcXVldWVfc3RhdGUgKnN0YXRlKTsKK3ZvaWQgdXNic3Nw X3F1ZXVlX25ld19kZXF1ZXVlX3N0YXRlKHN0cnVjdCB1c2Jzc3BfdWRjICp1c2Jzc3BfZGF0YSwK KwkJCQl1bnNpZ25lZCBpbnQgZXBfaW5kZXgsCisJCQkJc3RydWN0IHVzYnNzcF9kZXF1ZXVlX3N0 YXRlICpkZXFfc3RhdGUpOwogdm9pZCB1c2Jzc3BfaGFuZGxlX2NvbW1hbmRfdGltZW91dChzdHJ1 Y3Qgd29ya19zdHJ1Y3QgKndvcmspOwogCiB2b2lkIHVzYnNzcF9jbGVhbnVwX2NvbW1hbmRfcXVl dWUoc3RydWN0IHVzYnNzcF91ZGMgKnVzYnNzcF9kYXRhKTsKQEAgLTIzMTMsNCArMjMyMSw3IEBA IF9fbGUzMiBfX2lvbWVtICp1c2Jzc3BfZ2V0X3BvcnRfaW9fYWRkcihzdHJ1Y3QgdXNic3NwX3Vk YyAqdXNic3NwX2RhdGEpOwogdm9pZCB1c2Jzc3BfZ2l2ZWJhY2tfcmVxdWVzdF9pbl9pcnEoc3Ry dWN0IHVzYnNzcF91ZGMgKnVzYnNzcF9kYXRhLAogCQkJCXN0cnVjdCB1c2Jzc3BfdGQgKmN1cl90 ZCwgaW50IHN0YXR1cyk7CiAKK3ZvaWQgdXNic3NwX3JlbW92ZV9yZXF1ZXN0KHN0cnVjdCB1c2Jz c3BfdWRjICp1c2Jzc3BfZGF0YSwKKwkJCXN0cnVjdCB1c2Jzc3BfcmVxdWVzdCAqcmVxX3ByaXYs IGludCBlcF9pbmRleCk7CisKICNlbmRpZiAvKiBfX0xJTlVYX1VTQlNTUF9HQURHRVRfSCAqLwo=