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=-18.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,MSGID_FROM_MTA_HEADER,SPF_HELO_NONE, SPF_PASS,USER_AGENT_GIT autolearn=unavailable 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 13058C07E96 for ; Tue, 13 Jul 2021 05:54:53 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id E75BF6101B for ; Tue, 13 Jul 2021 05:54:52 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233625AbhGMF5l (ORCPT ); Tue, 13 Jul 2021 01:57:41 -0400 Received: from mail-bn8nam12on2135.outbound.protection.outlook.com ([40.107.237.135]:6497 "EHLO NAM12-BN8-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S231971AbhGMF5j (ORCPT ); Tue, 13 Jul 2021 01:57:39 -0400 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=jVe0vKpcctIo13jJmdKu8uSNGxFAJo4IgPCnqf6Obgz7vyeLzvK4DvkNqKUSUMWbr8sSl12JkwzcA0gAHQGJi3iJxaXadl3dEqPVrYEN1TBzhYJzk7ieOsMU1J/fJMefEf1Wl0UaeLtv/IK1pKqEXF3l1nBBHdl09B8BS89QM5/OXMBXAq+8+sRN73ZXah93p1gpBZvmxcDNUJHIwy+22nAcsny5igsP3X1Nv0dD00oK0QdhmrW5U+VhN+op1BTpWl42z/DwDgXtxGBRC43mtNca5FGhBTS4lv9a9KMVcGnrWdw7pPwtvmf9uOgf3tYoDStD5jst6Zd2Jij8WzBrpA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=MRvCkcGmZy3X92RZSBBoLKQ35hZ5gVX6F7qMfHu+Rok=; b=JsQVcBtKiW+ea1lVbxf8cOMR0Q0NA5rRYdRYJ1EjguoqKgymlYDZWolMQUbnNMiQPxfMnU1ZYpOA4IcVhlPGY3zFNO/JjMCaugDgKiXiRBhvUkRMs+t6QYYbZpev+xZWL9EGCuqbwneTkLni7P798QAyEHVxXiSUTcZUSNKA/kYA8rYcTKM5rWU2njXLQsOuIOY1n7Nt/PyffF5Wdato9S8n6aRj9OxdleOSgWkh6c3LjW9aXsQyzpE+K67TH69+z7SrJ1yz0Z5obImDYXp7JzHZCfFKo7qyA4ACByHvX5c2ebE+aQxxDBwhEnsHaK2eoseir9HQo8FMYJUXwWXphg== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=os.amperecomputing.com; dmarc=pass action=none header.from=os.amperecomputing.com; dkim=pass header.d=os.amperecomputing.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=os.amperecomputing.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=MRvCkcGmZy3X92RZSBBoLKQ35hZ5gVX6F7qMfHu+Rok=; b=n6L0Hz0kumq0OzNpogAyeAoXDgWzTJ5fqyLLBgZCAaXjkysYK/6YqLzx1bBu7pwAIpYYddq6Y4mpXoQywHMyj+I/GK15Fos0pp3zp9zm467ckKEvtlh+n7e+yn/TrWP/hNAk1dBqNLJ0b6Q4j1/7zxVdUh3/3qGJs9Gk3gp6mew= Authentication-Results: acm.org; dkim=none (message not signed) header.d=none;acm.org; dmarc=none action=none header.from=os.amperecomputing.com; Received: from MW2PR0102MB3482.prod.exchangelabs.com (2603:10b6:302:c::32) by CO1PR01MB6535.prod.exchangelabs.com (2603:10b6:303:d9::17) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4308.19; Tue, 13 Jul 2021 05:54:47 +0000 Received: from MW2PR0102MB3482.prod.exchangelabs.com ([fe80::452a:24fb:12cb:9d7e]) by MW2PR0102MB3482.prod.exchangelabs.com ([fe80::452a:24fb:12cb:9d7e%5]) with mapi id 15.20.4308.027; Tue, 13 Jul 2021 05:54:47 +0000 From: Quan Nguyen To: Corey Minyard , Rob Herring , Joel Stanley , Andrew Jeffery , Brendan Higgins , Benjamin Herrenschmidt , Wolfram Sang , openipmi-developer@lists.sourceforge.net, devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-aspeed@lists.ozlabs.org, linux-kernel@vger.kernel.org, linux-i2c@vger.kernel.org Cc: Open Source Submission , Phong Vo , "Thang Q . Nguyen" Subject: [PATCH v4 1/3] ipmi: ssif_bmc: Add SSIF BMC driver Date: Tue, 13 Jul 2021 12:54:23 +0700 Message-Id: <20210713055425.30636-2-quan@os.amperecomputing.com> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20210713055425.30636-1-quan@os.amperecomputing.com> References: <20210713055425.30636-1-quan@os.amperecomputing.com> Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-ClientProxiedBy: HKAPR03CA0027.apcprd03.prod.outlook.com (2603:1096:203:c9::14) To MW2PR0102MB3482.prod.exchangelabs.com (2603:10b6:302:c::32) MIME-Version: 1.0 X-MS-Exchange-MessageSentRepresentingType: 1 Received: from hcm-sw-17.amperecomputing.com (118.69.219.201) by HKAPR03CA0027.apcprd03.prod.outlook.com (2603:1096:203:c9::14) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4331.10 via Frontend Transport; Tue, 13 Jul 2021 05:54:43 +0000 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 61f6150d-c42a-4d25-d8a6-08d945c2b880 X-MS-TrafficTypeDiagnostic: CO1PR01MB6535: X-MS-Exchange-Transport-Forked: True X-Microsoft-Antispam-PRVS: X-MS-Oob-TLC-OOBClassifiers: OLM:3044; X-MS-Exchange-SenderADCheck: 1 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: jDO4Gr8uTPEAARhIG+6EdCP/zdidEH8VXrPclSXiwflta/4Ubh49lgEpZ9C5ENhoqvI7ekXK9MVdqYRyFqhIYSRmHyN3fijTp2h/7n5M0t7ZuMS7oMXKz6kbNwDI1vCAnrWqfx+GpyKT7oHuR5WNZqay4uVZ1RmE3sxncwqCc5Ixt84cj+PSD7X6s3loODW3l6NioE13cMJlU7od0me1dBxi2xcoWM1CrJ2KiMCmZ+fQ6Z5ABheuSN50DMWoDBCtzfNGC7zhDnY0NqaV+jRgo8F1AV+3f3SeeeWK5AtyTgHpvbzSZrrAuArYKKenS6QINLeXOJB1QvqjC9oCbURWUxcyyMw1IW5zbGqKJR40kudq339zPwFNtiPZt+0fPwxb68yaDYeioB5YDnVp1E/vH/T/Sh094xpCECckea6FSqikxAa80EV5kg0Cum3QmUh0V0tMKcBMDr7B0Gz5CwQVrsLvVG6kyy2eBb65TUNUTe++j72isCQwhepenTPaK0M8xfdMa6FLRXFMmKHURkMEKCsAt7h4Og89Y3hhEIYcOog4ZvZj6BOdIa+UiLs5e1gj5M7kJGI48ScciW2xd+ojW9thIMSlFlCgOYyzZ8Cx6SLDg8tQPf8h1Im19Wy7qlRMbKtXrgT22dNnYRcwysyP4bVaDPSrXtUIQDQBgryKsX0kDMjCrkm16pMLI904RbRgjltApbNwX1iZvXrpFSH9N3Z7jmx6Pc5yUXVJxpi3op94JcczjPlkt62QeaB70h3qqQb2+lh6VQZZEDRc5eEc83sQO/zmZyPhsOIFuvZ5Q5ujOTHbXrzosGbZWTqcl5kTiM8pvRdgiVWNNoofoIoFag== X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:MW2PR0102MB3482.prod.exchangelabs.com;PTR:;CAT:NONE;SFS:(4636009)(376002)(136003)(366004)(396003)(39850400004)(346002)(956004)(8676002)(54906003)(86362001)(5660300002)(2616005)(2906002)(1076003)(7416002)(52116002)(66946007)(107886003)(478600001)(66556008)(6666004)(30864003)(66476007)(6506007)(921005)(110136005)(26005)(186003)(38100700002)(316002)(4326008)(38350700002)(83380400001)(6512007)(8936002)(6486002)(2004002);DIR:OUT;SFP:1102; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?utf-8?B?VlI5Q2Z6VS9BSGJYMGJhcUVJUG1EaXdVbWtMVGpoSDF5Z2ZVQXhXL1dhTUxB?= =?utf-8?B?alFTTVRGWkVFMDNtZy8vVSsvQVRraE5zZ1JXcXZXTlQ0RTFJWFFUTkY4WVgy?= =?utf-8?B?Z0wxTzhTdmQrWXVxRUpVam1LdmFta1dDRXF0WjhOZk5iQUhMZXZVOXlhdzJL?= =?utf-8?B?WWltbk81TWs1ZlRmeWJIa0Z2Rms3Nk9iUG12SUtpWkgwek1FR1FzanZTUlBn?= =?utf-8?B?VkFyNXRSVUl0YTdLM3IrUHpEa0pEczgvVXVhNDRrdEZGd1VUbmNIL0dkcW41?= =?utf-8?B?bDVRaFJqaGYvSE43YUh3SW1jWGdXUnJ6eEpYMVNDUmpxNEdKd0tnL2Z3d0pa?= =?utf-8?B?V04wamM0L21wWlJMVXdKWnhkaE14WGNBZWovRWNFaCt6dlkxZmhmV2VPRnAw?= =?utf-8?B?VGp2T2dUK1lvNVhzbXk3eUUvMjdnNTQwRUFSV0VJSUFMdnFqUXh1RDI1cXU2?= =?utf-8?B?NVRjeSs1YmFOQVY5OFdOUG9rL05yazJRbjJzYlpVdWZuMGh4OWIwRGg4bXhG?= =?utf-8?B?ZCt0cTVtQmhjU0M4M1d0akRyZTdtUjJMbVdKZDJuSXBXTFQ2TFNqYkFLOFdX?= =?utf-8?B?dldEMHIzMThXbi9DRllRZGNYSmhQUUFFOHg0NGdEOERZVVV5US94NU1FNUFV?= =?utf-8?B?V3dTQi94R0Q3clVvbnBFNWlnQ2Z2cVpqOXQ4MUluV1VZZXUwcjJ5cDgxc3d4?= =?utf-8?B?NVErbm1DTTdhbllnalJYbkVkMHREUWhPVmFwMmVra1dmVGh0RnVORVZBanN6?= =?utf-8?B?ZFlNQUw0M1lmTGVqVFpRc05TV2NXQ1d2T0tvMmhUZWNOQk5oTzlIaVk4bUxt?= =?utf-8?B?MTNzNEpZVkF3NlhsZXdYWWMvVFNEUDVyejRKS0tienFJTEY2Nk8yZnJXcnhO?= =?utf-8?B?Z05IejZUZzU3dC9KSytSenNQYVgvbmtyNVFMT1I5UkdOZjI1YXU2TEdWdDZ3?= =?utf-8?B?Ry9sMmFKWWFmRHdBTW9yZUhkYUN5MjVHcjg4bW5xMUY0Yk5OdVp4S2NWMDlD?= =?utf-8?B?TXpCTmtMMGk0aXN5UDV0blE2Zlgrc2xCSDkrSkFrVWQ5KzNkOTZXTlQ1OU0v?= =?utf-8?B?M0FLdkhhVGN3dGcyWjRZcHRkbGZ3d1U1dWFVRmpKMW9QTkVQOGtldzNHVytB?= =?utf-8?B?Wm5KTG1KVDc4a0ZNZHk4RnFTZjJQRC9iNkJ0YThBYmJXYzNJTUVSN0N1WWs5?= =?utf-8?B?SWxvWU4zMFk0SEl4U2xycGJPUUNlWWdWNXUwN296cm9SNW5PTkx4QjlCckYv?= =?utf-8?B?dE9XTVdPdUQ3cml4WGszZlhvbXB3Y1ZtUmd1bUR5UnpSVGYyL1AzYzQ2VHRi?= =?utf-8?B?SFdJVHBxUFYweFd1a0NmNENLcXR2WFdnM0NPRUVWSDlJUU9xNE9SNHpoTk1m?= =?utf-8?B?N284ZEFwZGpRT2N0Z3gweUZraWZNTm9UQTdMRmdoWnQ4ZzlLREZuS25pc0lk?= =?utf-8?B?K1JWYkVha3hjQVFFL3NHQjJmak1pekJhWXhRSHlRRVRHVFpzaXhESVZhTDJq?= =?utf-8?B?a1ZXcEd0d25zM0lHV3RnOEZ0UGNsOU14RjZIc2JlV05DMHU2TXlsbHBvRThF?= =?utf-8?B?TSs0NEFZR0NTN3o2czgyblhOZklBdVZySVRhRVVDaWlXOTByZWREd1NLaVVw?= =?utf-8?B?VUVHTm9SYXI3ZksrYnFxSGFPc3RTdVU1RDVkbmRGeGZNSDZyUVpYTnFPTzVR?= =?utf-8?B?clA3bEJVNitKSXdhcVg2Rk00S2dRY252dG9jb3B3WnhpOW9ITmVJZVlLRlgw?= =?utf-8?Q?Pvpih8/6+0jQumBRjJtfEQdCOhO87JMG5M2BAsh?= X-OriginatorOrg: os.amperecomputing.com X-MS-Exchange-CrossTenant-Network-Message-Id: 61f6150d-c42a-4d25-d8a6-08d945c2b880 X-MS-Exchange-CrossTenant-AuthSource: MW2PR0102MB3482.prod.exchangelabs.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 13 Jul 2021 05:54:47.6106 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 3bc2b170-fd94-476d-b0ce-4229bdc904a7 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: 2cgLGhPbvWyTK1vUudvExk+wmJ5Mky5V/IW9t9BjwzC6ysi36/5CZp8mv87hY5AW2MnbbomGJYuz7f/j/2sOobNT9Qyc+pCRCIlA3UXVisY= X-MS-Exchange-Transport-CrossTenantHeadersStamped: CO1PR01MB6535 Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org The SMBus system interface (SSIF) IPMI BMC driver can be used to perform in-band IPMI communication with their host in management (BMC) side. Signed-off-by: Quan Nguyen --- v4: + Send response with Completion code 0xFF when aborting [Quan] + Added bounding check on SMBus writes and the whole request [Dan] + Moved buffer to end of struct ssif_bmc_ctx to avoid context corruption if somehow buffer is written past the end [Dan] + Return -EINVAL if userspace buffer too small, dont silence truncate [Corey, Joel] + Not necessary to check NONBLOCK in lock [Corey] + Enforce one user at a time [Joel] + Reject write with invalid response length from userspace [Corey] + Add state machines for better ssif bmc state handling [Quan] + Drop ssif_bmc_aspeed.c and make ssif_bmc.c is generic SSIF BMC driver [Quan] + Change compatible string "aspeed,ast2500-ssif-bmc" to "ampere,ssif-bmc" [Quan] + Abort current request with invalid SMBus write or invalid command [Quan] + Abort all request if there is pending response [Quan] + Changed validate_pec() to validate_request() [Quan] + Add unsupported_smbus_cmd() to handle unknown SMBus command [Quan] + Print internal state string for ease investigating issue [Quan] + Move to READY state on SLAVE_STOP event [Quan] + Change initilize_transfer() to process_smbus_cmd() [Quan] + Introduce functions for each slave event [Quan] v3: + Removed redundant license info [Joel] + Switched to use traditional if-else [Joel] + Removed unused ssif_bmc_ioctl() [Joel] + Made handle_request()/complete_response() to return void [Joel] + Refactored send_ssif_bmc_response()/receive_ssif_bmc_request() [Corey] + Removed mutex [Corey] + Use spin_lock/unlock_irqsave/restore in callback [Corey] + Removed the unnecessary memset [Corey] + Switch to use dev_err() [Corey] v2: + Fixed compiling error with COMPILE_TEST for arc drivers/char/ipmi/Kconfig | 11 + drivers/char/ipmi/Makefile | 1 + drivers/char/ipmi/ssif_bmc.c | 781 +++++++++++++++++++++++++++++++++++ drivers/char/ipmi/ssif_bmc.h | 106 +++++ 4 files changed, 899 insertions(+) create mode 100644 drivers/char/ipmi/ssif_bmc.c create mode 100644 drivers/char/ipmi/ssif_bmc.h diff --git a/drivers/char/ipmi/Kconfig b/drivers/char/ipmi/Kconfig index 249b31197eea..e09a470ab2da 100644 --- a/drivers/char/ipmi/Kconfig +++ b/drivers/char/ipmi/Kconfig @@ -160,6 +160,17 @@ config ASPEED_BT_IPMI_BMC found on Aspeed SOCs (AST2400 and AST2500). The driver implements the BMC side of the BT interface. +config SSIF_IPMI_BMC + tristate "SSIF IPMI BMC driver" + select I2C + select I2C_SLAVE + help + This enables the IPMI SMBus system interface (SSIF) at the + management (BMC) side. + + The driver implements the BMC side of the SMBus system + interface (SSIF). + config IPMB_DEVICE_INTERFACE tristate 'IPMB Interface handler' depends on I2C diff --git a/drivers/char/ipmi/Makefile b/drivers/char/ipmi/Makefile index 84f47d18007f..a93c09dad22a 100644 --- a/drivers/char/ipmi/Makefile +++ b/drivers/char/ipmi/Makefile @@ -29,3 +29,4 @@ obj-$(CONFIG_ASPEED_BT_IPMI_BMC) += bt-bmc.o obj-$(CONFIG_ASPEED_KCS_IPMI_BMC) += kcs_bmc_aspeed.o obj-$(CONFIG_NPCM7XX_KCS_IPMI_BMC) += kcs_bmc_npcm7xx.o obj-$(CONFIG_IPMB_DEVICE_INTERFACE) += ipmb_dev_int.o +obj-$(CONFIG_SSIF_IPMI_BMC) += ssif_bmc.o diff --git a/drivers/char/ipmi/ssif_bmc.c b/drivers/char/ipmi/ssif_bmc.c new file mode 100644 index 000000000000..b15c05622e72 --- /dev/null +++ b/drivers/char/ipmi/ssif_bmc.c @@ -0,0 +1,781 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * The driver for BMC side of SSIF interface + * + * Copyright (c) 2021, Ampere Computing LLC + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ssif_bmc.h" + +static const char *state_to_string(enum ssif_state state) +{ + switch (state) { + case SSIF_READY: + return "SSIF_READY"; + case SSIF_START: + return "SSIF_START"; + case SSIF_SMBUS_CMD: + return "SSIF_SMBUS_CMD"; + case SSIF_REQ_RECVING: + return "SSIF_REQ_RECVING"; + case SSIF_RES_SENDING: + return "SSIF_RES_SENDING"; + case SSIF_BAD_SMBUS: + return "SSIF_BAD_SMBUS"; + default: + return "SSIF_STATE_UNKNOWN"; + } +} + +/* Handle SSIF message that will be sent to user */ +static ssize_t ssif_bmc_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) +{ + struct ssif_bmc_ctx *ssif_bmc = to_ssif_bmc(file); + struct ssif_msg msg; + unsigned long flags; + ssize_t ret; + + spin_lock_irqsave(&ssif_bmc->lock, flags); + while (!ssif_bmc->request_available) { + spin_unlock_irqrestore(&ssif_bmc->lock, flags); + if (file->f_flags & O_NONBLOCK) + return -EAGAIN; + ret = wait_event_interruptible(ssif_bmc->wait_queue, + ssif_bmc->request_available); + if (ret) + return ret; + spin_lock_irqsave(&ssif_bmc->lock, flags); + } + + if (count < min_t(ssize_t, ssif_msg_len(&ssif_bmc->request), sizeof(struct ssif_msg))) { + spin_unlock_irqrestore(&ssif_bmc->lock, flags); + ret = -EINVAL; + } else { + count = min_t(ssize_t, ssif_msg_len(&ssif_bmc->request), sizeof(struct ssif_msg)); + memcpy(&msg, &ssif_bmc->request, count); + ssif_bmc->request_available = false; + spin_unlock_irqrestore(&ssif_bmc->lock, flags); + + ret = copy_to_user(buf, &msg, count); + } + + return (ret < 0) ? ret : count; +} + +/* Handle SSIF message that is written by user */ +static ssize_t ssif_bmc_write(struct file *file, const char __user *buf, size_t count, + loff_t *ppos) +{ + struct ssif_bmc_ctx *ssif_bmc = to_ssif_bmc(file); + struct ssif_msg msg; + unsigned long flags; + ssize_t ret; + + if (count > sizeof(struct ssif_msg)) + return -EINVAL; + + ret = copy_from_user(&msg, buf, count); + if (ret) + return ret; + + if (!msg.len || count < ssif_msg_len(&msg)) + return -EINVAL; + + spin_lock_irqsave(&ssif_bmc->lock, flags); + while (ssif_bmc->response_in_progress) { + spin_unlock_irqrestore(&ssif_bmc->lock, flags); + if (file->f_flags & O_NONBLOCK) + return -EAGAIN; + ret = wait_event_interruptible(ssif_bmc->wait_queue, + !ssif_bmc->response_in_progress); + if (ret) + return ret; + spin_lock_irqsave(&ssif_bmc->lock, flags); + } + + memcpy(&ssif_bmc->response, &msg, count); + ssif_bmc->is_singlepart_read = (ssif_msg_len(&msg) <= MAX_PAYLOAD_PER_TRANSACTION + 1); + ssif_bmc->response_in_progress = true; + + if (ssif_bmc->client->adapter->algo->slave_enable) + ret = ssif_bmc->client->adapter->algo->slave_enable(ssif_bmc->client, true); + + spin_unlock_irqrestore(&ssif_bmc->lock, flags); + + return (ret < 0) ? ret : count; +} + +static int ssif_bmc_open(struct inode *inode, struct file *file) +{ + struct ssif_bmc_ctx *ssif_bmc = to_ssif_bmc(file); + int ret = 0; + + spin_lock_irq(&ssif_bmc->lock); + if (!ssif_bmc->running) + ssif_bmc->running = 1; + else + ret = -EBUSY; + spin_unlock_irq(&ssif_bmc->lock); + + return ret; +} + +static unsigned int ssif_bmc_poll(struct file *file, poll_table *wait) +{ + struct ssif_bmc_ctx *ssif_bmc = to_ssif_bmc(file); + unsigned int mask = 0; + + poll_wait(file, &ssif_bmc->wait_queue, wait); + + spin_lock_irq(&ssif_bmc->lock); + /* The request is available, userspace application can get the request */ + if (ssif_bmc->request_available) + mask |= POLLIN; + + spin_unlock_irq(&ssif_bmc->lock); + + return mask; +} + +static int ssif_bmc_release(struct inode *inode, struct file *file) +{ + struct ssif_bmc_ctx *ssif_bmc = to_ssif_bmc(file); + + spin_lock_irq(&ssif_bmc->lock); + ssif_bmc->running = 0; + spin_unlock_irq(&ssif_bmc->lock); + + return 0; +} + +/* + * System calls to device interface for user apps + */ +static const struct file_operations ssif_bmc_fops = { + .owner = THIS_MODULE, + .open = ssif_bmc_open, + .read = ssif_bmc_read, + .write = ssif_bmc_write, + .release = ssif_bmc_release, + .poll = ssif_bmc_poll, +}; + +/* Called with ssif_bmc->lock held. */ +static void complete_response(struct ssif_bmc_ctx *ssif_bmc) +{ + /* Invalidate response in buffer to denote it having been sent. */ + ssif_bmc->response.len = 0; + ssif_bmc->response_in_progress = false; + ssif_bmc->nbytes_processed = 0; + ssif_bmc->remain_len = 0; + wake_up_all(&ssif_bmc->wait_queue); +} + +/* Called with ssif_bmc->lock held. */ +static void handle_request(struct ssif_bmc_ctx *ssif_bmc) +{ + if (ssif_bmc->client->adapter->algo->slave_enable) + ssif_bmc->client->adapter->algo->slave_enable(ssif_bmc->client, false); + + /* Request message is available to process */ + ssif_bmc->request_available = true; + /* + * This is the new READ request. + */ + wake_up_all(&ssif_bmc->wait_queue); +} + +static void set_multipart_response_buffer(struct ssif_bmc_ctx *ssif_bmc, u8 *val) +{ + u8 response_len = 0; + int idx = 0; + u8 data_len; + + data_len = ssif_bmc->response.len; + switch (ssif_bmc->smbus_cmd) { + case SSIF_IPMI_MULTIPART_READ_START: + /* + * Read Start length is 32 bytes. + * Read Start transfer first 30 bytes of IPMI response + * and 2 special code 0x00, 0x01. + */ + *val = MAX_PAYLOAD_PER_TRANSACTION; + ssif_bmc->remain_len = data_len - MAX_IPMI_DATA_PER_START_TRANSACTION; + ssif_bmc->block_num = 0; + + ssif_bmc->response_buf[idx++] = 0x00; /* Start Flag */ + ssif_bmc->response_buf[idx++] = 0x01; /* Start Flag */ + ssif_bmc->response_buf[idx++] = ssif_bmc->response.netfn_lun; + ssif_bmc->response_buf[idx++] = ssif_bmc->response.cmd; + ssif_bmc->response_buf[idx++] = ssif_bmc->response.payload[0]; + + response_len = MAX_PAYLOAD_PER_TRANSACTION - idx; + + memcpy(&ssif_bmc->response_buf[idx], &ssif_bmc->response.payload[1], + response_len); + break; + + case SSIF_IPMI_MULTIPART_READ_MIDDLE: + /* + * IPMI READ Middle or READ End messages can carry up to 31 bytes + * IPMI data plus block number byte. + */ + if (ssif_bmc->remain_len < MAX_IPMI_DATA_PER_MIDDLE_TRANSACTION) { + /* + * This is READ End message + * Return length is the remaining response data length + * plus block number + * Block number 0xFF is to indicate this is last message + * + */ + *val = ssif_bmc->remain_len + 1; + ssif_bmc->block_num = 0xFF; + ssif_bmc->response_buf[idx++] = ssif_bmc->block_num; + response_len = ssif_bmc->remain_len; + /* Clean the buffer */ + memset(&ssif_bmc->response_buf[idx], 0, MAX_PAYLOAD_PER_TRANSACTION - idx); + } else { + /* + * This is READ Middle message + * Response length is the maximum SMBUS transfer length + * Block number byte is incremented + * Return length is maximum SMBUS transfer length + */ + *val = MAX_PAYLOAD_PER_TRANSACTION; + ssif_bmc->remain_len -= MAX_IPMI_DATA_PER_MIDDLE_TRANSACTION; + response_len = MAX_IPMI_DATA_PER_MIDDLE_TRANSACTION; + ssif_bmc->response_buf[idx++] = ssif_bmc->block_num; + ssif_bmc->block_num++; + } + + memcpy(&ssif_bmc->response_buf[idx], + ssif_bmc->response.payload + 1 + ssif_bmc->nbytes_processed, + response_len); + break; + + default: + /* Do not expect to go to this case */ + dev_err(&ssif_bmc->client->dev, + "%s: Unexpected SMBus command 0x%x, aborting ...\n", + __func__, ssif_bmc->smbus_cmd); + ssif_bmc->aborting = true; + break; + } + + ssif_bmc->nbytes_processed += response_len; +} + +/* Process the IPMI response that will be read by master */ +static void handle_read_processed(struct ssif_bmc_ctx *ssif_bmc, u8 *val) +{ + u8 *buf; + u8 pec_len, addr, len; + u8 pec = 0; + + pec_len = ssif_bmc->pec_support ? 1 : 0; + /* PEC - Start Read Address */ + addr = GET_8BIT_ADDR(ssif_bmc->client->addr); + pec = i2c_smbus_pec(pec, &addr, 1); + /* PEC - SSIF Command */ + pec = i2c_smbus_pec(pec, &ssif_bmc->smbus_cmd, 1); + /* PEC - Restart Write Address */ + addr = addr | 0x01; + pec = i2c_smbus_pec(pec, &addr, 1); + + if (ssif_bmc->is_singlepart_read) { + /* Single-part Read processing */ + buf = (u8 *)&ssif_bmc->response; + + if (ssif_bmc->response.len && ssif_bmc->msg_idx < ssif_bmc->response.len) { + ssif_bmc->msg_idx++; + *val = buf[ssif_bmc->msg_idx]; + } else if (ssif_bmc->response.len && ssif_bmc->msg_idx == ssif_bmc->response.len) { + ssif_bmc->msg_idx++; + *val = i2c_smbus_pec(pec, buf, ssif_msg_len(&ssif_bmc->response)); + } else { + *val = 0; + } + /* Invalidate response buffer to denote it is sent */ + if (ssif_bmc->msg_idx + 1 >= (ssif_msg_len(&ssif_bmc->response) + pec_len)) + complete_response(ssif_bmc); + } else { + /* Multi-part Read processing */ + switch (ssif_bmc->smbus_cmd) { + case SSIF_IPMI_MULTIPART_READ_START: + case SSIF_IPMI_MULTIPART_READ_MIDDLE: + buf = (u8 *)&ssif_bmc->response_buf; + *val = buf[ssif_bmc->msg_idx]; + ssif_bmc->msg_idx++; + break; + default: + /* Do not expect to go to this case */ + dev_err(&ssif_bmc->client->dev, + "%s: Unexpected SMBus command 0x%x, aborting ...\n", + __func__, ssif_bmc->smbus_cmd); + ssif_bmc->aborting = true; + break; + } + + len = (ssif_bmc->block_num == 0xFF) ? + ssif_bmc->remain_len + 1 : MAX_PAYLOAD_PER_TRANSACTION; + if (ssif_bmc->msg_idx == (len + 1)) { + pec = i2c_smbus_pec(pec, &len, 1); + *val = i2c_smbus_pec(pec, ssif_bmc->response_buf, len); + } + /* Invalidate response buffer to denote last response is sent */ + if (ssif_bmc->block_num == 0xFF && + ssif_bmc->msg_idx > (ssif_bmc->remain_len + pec_len)) { + complete_response(ssif_bmc); + } + } +} + +static void handle_write_received(struct ssif_bmc_ctx *ssif_bmc, u8 *val) +{ + u8 *buf = (u8 *)&ssif_bmc->request; + + if (ssif_bmc->msg_idx >= sizeof(struct ssif_msg)) + return; + + switch (ssif_bmc->smbus_cmd) { + case SSIF_IPMI_SINGLEPART_WRITE: + buf[ssif_bmc->msg_idx - 1] = *val; + ssif_bmc->msg_idx++; + + break; + case SSIF_IPMI_MULTIPART_WRITE_START: + if (ssif_bmc->msg_idx == 1) + ssif_bmc->request.len = 0; + + fallthrough; + case SSIF_IPMI_MULTIPART_WRITE_MIDDLE: + /* The len should always be 32 */ + if (ssif_bmc->msg_idx == 1 && *val != MAX_PAYLOAD_PER_TRANSACTION) { + dev_warn(&ssif_bmc->client->dev, + "Warn: Invalid Multipart Write len, aborting ..."); + ssif_bmc->aborting = true; + } + + fallthrough; + case SSIF_IPMI_MULTIPART_WRITE_END: + /* Multi-part write, 2nd byte received is length */ + if (ssif_bmc->msg_idx == 1) { + if (*val > MAX_PAYLOAD_PER_TRANSACTION) { + dev_warn(&ssif_bmc->client->dev, + "Warn: Invalid Multipart Write End len, aborting ..."); + ssif_bmc->aborting = true; + } + + ssif_bmc->request.len += *val; + ssif_bmc->recv_len = *val; + + /* request len should never exceeded 255 bytes */ + if (ssif_bmc->request.len > 255) { + dev_warn(&ssif_bmc->client->dev, + "Warn: Invalid request len, aborting ..."); + ssif_bmc->aborting = true; + } + + } else { + buf[ssif_bmc->msg_idx - 1 + + ssif_bmc->request.len - ssif_bmc->recv_len] = *val; + } + + ssif_bmc->msg_idx++; + + break; + default: + /* Do not expect to go to this case */ + dev_err(&ssif_bmc->client->dev, + "%s: Unexpected SMBus command 0x%x, aborting ...\n", + __func__, ssif_bmc->smbus_cmd); + ssif_bmc->aborting = true; + break; + } +} + +static bool validate_request(struct ssif_bmc_ctx *ssif_bmc) +{ + u8 rpec = 0, cpec = 0; + bool ret = true; + u8 addr, index; + u8 *buf; + + buf = (u8 *)&ssif_bmc->request; + switch (ssif_bmc->smbus_cmd) { + case SSIF_IPMI_SINGLEPART_WRITE: + if ((ssif_bmc->msg_idx - 1) == ssif_msg_len(&ssif_bmc->request)) { + /* PEC is not included */ + ssif_bmc->pec_support = false; + ret = true; + goto exit; + } + + if ((ssif_bmc->msg_idx - 1) != (ssif_msg_len(&ssif_bmc->request) + 1)) { + dev_err(&ssif_bmc->client->dev, "Error: Unexpected length received %d\n", + ssif_msg_len(&ssif_bmc->request)); + ret = false; + goto exit; + } + + /* PEC is included */ + ssif_bmc->pec_support = true; + rpec = buf[ssif_bmc->msg_idx - 2]; + addr = GET_8BIT_ADDR(ssif_bmc->client->addr); + cpec = i2c_smbus_pec(cpec, &addr, 1); + cpec = i2c_smbus_pec(cpec, &ssif_bmc->smbus_cmd, 1); + cpec = i2c_smbus_pec(cpec, buf, ssif_msg_len(&ssif_bmc->request)); + if (rpec != cpec) { + dev_err(&ssif_bmc->client->dev, "Bad PEC 0x%02x vs. 0x%02x\n", rpec, cpec); + ret = false; + } + + break; + case SSIF_IPMI_MULTIPART_WRITE_START: + case SSIF_IPMI_MULTIPART_WRITE_MIDDLE: + case SSIF_IPMI_MULTIPART_WRITE_END: + index = ssif_bmc->request.len - ssif_bmc->recv_len; + if ((ssif_bmc->msg_idx - 1 + index) == ssif_msg_len(&ssif_bmc->request)) { + /* PEC is not included */ + ssif_bmc->pec_support = false; + ret = true; + goto exit; + } + + if ((ssif_bmc->msg_idx - 1 + index) != (ssif_msg_len(&ssif_bmc->request) + 1)) { + dev_err(&ssif_bmc->client->dev, "Error: Unexpected length received %d\n", + ssif_msg_len(&ssif_bmc->request)); + ret = false; + goto exit; + } + + /* PEC is included */ + ssif_bmc->pec_support = true; + rpec = buf[ssif_bmc->msg_idx - 2 + index]; + addr = GET_8BIT_ADDR(ssif_bmc->client->addr); + cpec = i2c_smbus_pec(cpec, &addr, 1); + cpec = i2c_smbus_pec(cpec, &ssif_bmc->smbus_cmd, 1); + cpec = i2c_smbus_pec(cpec, &ssif_bmc->recv_len, 1); + /* As SMBus specification does not allow the length + * (byte count) in the Write-Block protocol to be zero. + * Therefore, it is illegal to have the last Middle + * transaction in the sequence carry 32-byte and have + * a length of ‘0’ in the End transaction. + * But some users may try to use this way and we should + * prevent ssif_bmc driver broken in this case. + */ + if (ssif_bmc->recv_len != 0) + cpec = i2c_smbus_pec(cpec, buf + 1 + index, ssif_bmc->recv_len); + + if (rpec != cpec) { + dev_err(&ssif_bmc->client->dev, "Bad PEC 0x%02x vs. 0x%02x\n", rpec, cpec); + ret = false; + } + + break; + default: + /* Do not expect to go to this case */ + dev_err(&ssif_bmc->client->dev, "%s: Unexpected SMBus command 0x%x, aborting ...\n", + __func__, ssif_bmc->smbus_cmd); + ret = false; + break; + } + +exit: + return ret; +} + +static bool unsupported_smbus_cmd(u8 cmd) +{ + if (cmd == SSIF_IPMI_SINGLEPART_READ || + cmd == SSIF_IPMI_SINGLEPART_WRITE || + cmd == SSIF_IPMI_MULTIPART_WRITE_START || + cmd == SSIF_IPMI_MULTIPART_WRITE_MIDDLE || + cmd == SSIF_IPMI_MULTIPART_WRITE_END || + cmd == SSIF_IPMI_MULTIPART_READ_START || + cmd == SSIF_IPMI_MULTIPART_READ_MIDDLE) + return false; + + return true; +} + +static void process_smbus_cmd(struct ssif_bmc_ctx *ssif_bmc, u8 *val) +{ + /* SMBUS command can vary (single or multi-part) */ + ssif_bmc->smbus_cmd = *val; + ssif_bmc->msg_idx++; + + if (unsupported_smbus_cmd(*val)) { + dev_warn(&ssif_bmc->client->dev, "Warn: Unknown SMBus command, aborting ..."); + ssif_bmc->aborting = true; + } else if (ssif_bmc->aborting && + (*val == SSIF_IPMI_SINGLEPART_WRITE || + *val == SSIF_IPMI_MULTIPART_WRITE_START)) { + /* New request */ + dev_warn(&ssif_bmc->client->dev, "Warn: New request found, stop aborting ..."); + ssif_bmc->aborting = false; + } +} + +static void on_read_requested_event(struct ssif_bmc_ctx *ssif_bmc, u8 *val) +{ + if (ssif_bmc->state == SSIF_READY || + ssif_bmc->state == SSIF_START || + ssif_bmc->state == SSIF_REQ_RECVING || + ssif_bmc->state == SSIF_RES_SENDING) { + ssif_bmc->state = SSIF_BAD_SMBUS; + dev_warn(&ssif_bmc->client->dev, + "Warn: %s unexpected READ REQUESTED in state=%s, aborting ...\n", + __func__, state_to_string(ssif_bmc->state)); + ssif_bmc->aborting = true; + + } else if (ssif_bmc->state == SSIF_SMBUS_CMD) { + ssif_bmc->state = SSIF_RES_SENDING; + } + + if (ssif_bmc->aborting || ssif_bmc->state != SSIF_RES_SENDING) { + /* Abort by returning the last request with 0xFF as completion code */ + ssif_bmc->is_singlepart_read = true; + ssif_bmc->response.len = 0x03; + ssif_bmc->response.netfn_lun = ssif_bmc->request.netfn_lun | 4; + ssif_bmc->response.cmd = ssif_bmc->request.cmd; + memset(&ssif_bmc->response.payload[0], 0xFF, MAX_PAYLOAD_PER_TRANSACTION); + } + + ssif_bmc->msg_idx = 0; + if (ssif_bmc->is_singlepart_read) + *val = ssif_bmc->response.len; + else + set_multipart_response_buffer(ssif_bmc, val); +} + +static void on_read_processed_event(struct ssif_bmc_ctx *ssif_bmc, u8 *val) +{ + if (ssif_bmc->state == SSIF_READY || + ssif_bmc->state == SSIF_START || + ssif_bmc->state == SSIF_REQ_RECVING || + ssif_bmc->state == SSIF_SMBUS_CMD) { + dev_warn(&ssif_bmc->client->dev, + "Warn: %s unexpected READ PROCESSED in state=%s\n", + __func__, state_to_string(ssif_bmc->state)); + ssif_bmc->state = SSIF_BAD_SMBUS; + } + + handle_read_processed(ssif_bmc, val); +} + +static void on_write_requested_event(struct ssif_bmc_ctx *ssif_bmc, u8 *val) +{ + ssif_bmc->msg_idx = 0; + + if (ssif_bmc->state == SSIF_READY || ssif_bmc->state == SSIF_SMBUS_CMD) { + ssif_bmc->state = SSIF_START; + + } else if (ssif_bmc->state == SSIF_START || + ssif_bmc->state == SSIF_REQ_RECVING || + ssif_bmc->state == SSIF_RES_SENDING) { + dev_warn(&ssif_bmc->client->dev, + "Warn: %s unexpected WRITE REQUEST in state=%s\n", + __func__, state_to_string(ssif_bmc->state)); + ssif_bmc->state = SSIF_BAD_SMBUS; + } +} + +static void on_write_received_event(struct ssif_bmc_ctx *ssif_bmc, u8 *val) +{ + if (ssif_bmc->state == SSIF_READY || ssif_bmc->state == SSIF_RES_SENDING) { + dev_warn(&ssif_bmc->client->dev, + "Warn: %s unexpected WRITE RECEIVED in state=%s\n", + __func__, state_to_string(ssif_bmc->state)); + ssif_bmc->state = SSIF_BAD_SMBUS; + } else if (ssif_bmc->state == SSIF_START) { + ssif_bmc->state = SSIF_SMBUS_CMD; + } else if (ssif_bmc->state == SSIF_SMBUS_CMD) { + ssif_bmc->state = SSIF_REQ_RECVING; + } + + /* This is response sending state */ + if (ssif_bmc->state == SSIF_REQ_RECVING) { + if (ssif_bmc->response_in_progress) { + /* + * As per spec, it is generic management software or SSIF drivers to take + * care of issuing new request before the prior requests completed. + * So just abort everything here and wait for next new request + */ + dev_warn(&ssif_bmc->client->dev, + "Warn: SSIF new request with pending response, aborting ..."); + ssif_bmc->aborting = true; + complete_response(ssif_bmc); + } + + handle_write_received(ssif_bmc, val); + } else if (ssif_bmc->state == SSIF_SMBUS_CMD) { + process_smbus_cmd(ssif_bmc, val); + } +} + +static void on_stop_event(struct ssif_bmc_ctx *ssif_bmc, u8 *val) +{ + if (ssif_bmc->state == SSIF_READY || + ssif_bmc->state == SSIF_START || + ssif_bmc->state == SSIF_SMBUS_CMD) { + dev_warn(&ssif_bmc->client->dev, + "Warn: %s unexpected SLAVE STOP in state=%s\n", + __func__, state_to_string(ssif_bmc->state)); + + } else if (ssif_bmc->state == SSIF_BAD_SMBUS) { + dev_warn(&ssif_bmc->client->dev, + "Warn: %s received SLAVE STOP from bad state=%s\n", + __func__, state_to_string(ssif_bmc->state)); + + } else if (ssif_bmc->state == SSIF_REQ_RECVING) { + /* A BMC that receives an invalid request drop the data for the write + * transaction and any further transactions (read or write) until + * the next valid read or write Start transaction is received + */ + if (!validate_request(ssif_bmc)) + ssif_bmc->aborting = true; + + if (!ssif_bmc->aborting && + (ssif_bmc->smbus_cmd == SSIF_IPMI_SINGLEPART_WRITE || + ssif_bmc->smbus_cmd == SSIF_IPMI_MULTIPART_WRITE_END)) + handle_request(ssif_bmc); + } + + ssif_bmc->state = SSIF_READY; + /* Reset message index */ + ssif_bmc->msg_idx = 0; +} + +/* + * Callback function to handle I2C slave events + */ +static int ssif_bmc_cb(struct i2c_client *client, enum i2c_slave_event event, u8 *val) +{ + unsigned long flags; + struct ssif_bmc_ctx *ssif_bmc = i2c_get_clientdata(client); + + spin_lock_irqsave(&ssif_bmc->lock, flags); + + switch (event) { + case I2C_SLAVE_READ_REQUESTED: + on_read_requested_event(ssif_bmc, val); + break; + + case I2C_SLAVE_WRITE_REQUESTED: + on_write_requested_event(ssif_bmc, val); + break; + + case I2C_SLAVE_READ_PROCESSED: + on_read_processed_event(ssif_bmc, val); + break; + + case I2C_SLAVE_WRITE_RECEIVED: + on_write_received_event(ssif_bmc, val); + break; + + case I2C_SLAVE_STOP: + on_stop_event(ssif_bmc, val); + break; + + default: + dev_warn(&ssif_bmc->client->dev, "Warn: Unknown i2c slave event, aborting ...\n"); + ssif_bmc->aborting = true; + break; + } + + spin_unlock_irqrestore(&ssif_bmc->lock, flags); + + return 0; +} + +static int ssif_bmc_probe(struct i2c_client *client, const struct i2c_device_id *id) +{ + struct ssif_bmc_ctx *ssif_bmc; + int ret; + + ssif_bmc = devm_kzalloc(&client->dev, sizeof(*ssif_bmc), GFP_KERNEL); + if (!ssif_bmc) + return -ENOMEM; + + spin_lock_init(&ssif_bmc->lock); + + init_waitqueue_head(&ssif_bmc->wait_queue); + ssif_bmc->request_available = false; + ssif_bmc->response_in_progress = false; + + /* Register misc device interface */ + ssif_bmc->miscdev.minor = MISC_DYNAMIC_MINOR; + ssif_bmc->miscdev.name = DEVICE_NAME; + ssif_bmc->miscdev.fops = &ssif_bmc_fops; + ssif_bmc->miscdev.parent = &client->dev; + ret = misc_register(&ssif_bmc->miscdev); + if (ret) + goto out; + + ssif_bmc->client = client; + ssif_bmc->client->flags |= I2C_CLIENT_SLAVE; + + /* Register I2C slave */ + i2c_set_clientdata(client, ssif_bmc); + ret = i2c_slave_register(client, ssif_bmc_cb); + if (ret) { + misc_deregister(&ssif_bmc->miscdev); + goto out; + } + + return 0; +out: + devm_kfree(&client->dev, ssif_bmc); + return ret; +} + +static int ssif_bmc_remove(struct i2c_client *client) +{ + struct ssif_bmc_ctx *ssif_bmc = i2c_get_clientdata(client); + + i2c_slave_unregister(client); + misc_deregister(&ssif_bmc->miscdev); + + return 0; +} + +static const struct of_device_id ssif_bmc_match[] = { + { .compatible = "ampere,ssif-bmc" }, + { }, +}; + +static const struct i2c_device_id ssif_bmc_id[] = { + { DEVICE_NAME, 0 }, + { }, +}; + +MODULE_DEVICE_TABLE(i2c, ssif_bmc_id); + +static struct i2c_driver ssif_bmc_driver = { + .driver = { + .name = DEVICE_NAME, + .of_match_table = ssif_bmc_match, + }, + .probe = ssif_bmc_probe, + .remove = ssif_bmc_remove, + .id_table = ssif_bmc_id, +}; + +module_i2c_driver(ssif_bmc_driver); + +MODULE_AUTHOR("Quan Nguyen "); +MODULE_AUTHOR("Chuong Tran "); +MODULE_DESCRIPTION("Linux device driver of the BMC IPMI SSIF interface."); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/char/ipmi/ssif_bmc.h b/drivers/char/ipmi/ssif_bmc.h new file mode 100644 index 000000000000..b63e40a4b900 --- /dev/null +++ b/drivers/char/ipmi/ssif_bmc.h @@ -0,0 +1,106 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * The driver for BMC side of SSIF interface + * + * Copyright (c) 2021, Ampere Computing LLC + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#ifndef __SSIF_BMC_H__ +#define __SSIF_BMC_H__ + +#define DEVICE_NAME "ipmi-ssif-host" + +#define GET_8BIT_ADDR(addr_7bit) (((addr_7bit) << 1) & 0xff) + +/* A standard SMBus Transaction is limited to 32 data bytes */ +#define MAX_PAYLOAD_PER_TRANSACTION 32 + +#define MAX_IPMI_DATA_PER_START_TRANSACTION 30 +#define MAX_IPMI_DATA_PER_MIDDLE_TRANSACTION 31 + +#define SSIF_IPMI_SINGLEPART_WRITE 0x2 +#define SSIF_IPMI_SINGLEPART_READ 0x3 +#define SSIF_IPMI_MULTIPART_WRITE_START 0x6 +#define SSIF_IPMI_MULTIPART_WRITE_MIDDLE 0x7 +#define SSIF_IPMI_MULTIPART_WRITE_END 0x8 +#define SSIF_IPMI_MULTIPART_READ_START 0x3 +#define SSIF_IPMI_MULTIPART_READ_MIDDLE 0x9 + +#define MSG_PAYLOAD_LEN_MAX 252 + +struct ssif_msg { + u8 len; + u8 netfn_lun; + u8 cmd; + u8 payload[MSG_PAYLOAD_LEN_MAX]; +} __packed; + +static inline u32 ssif_msg_len(struct ssif_msg *ssif_msg) +{ + return ssif_msg->len + 1; +} + +/* + * SSIF internal states: + * SSIF_READY 0x00 : Ready state + * SSIF_START 0x01 : Start smbus transaction + * SSIF_SMBUS_CMD 0x02 : Received SMBus command + * SSIF_REQ_RECVING 0x03 : Receiving request + * SSIF_RES_SENDING 0x04 : Sending response + * SSIF_BAD_SMBUS 0x05 : Bad SMbus transaction + */ +enum ssif_state { + SSIF_READY, + SSIF_START, + SSIF_SMBUS_CMD, + SSIF_REQ_RECVING, + SSIF_RES_SENDING, + SSIF_BAD_SMBUS, + SSIF_STATE_MAX +}; + +struct ssif_bmc_ctx { + struct i2c_client *client; + struct miscdevice miscdev; + size_t msg_idx; + bool pec_support; + /* ssif bmc spinlock */ + spinlock_t lock; + wait_queue_head_t wait_queue; + u8 running; + enum ssif_state state; + u8 smbus_cmd; + /* Flag to abort current process */ + bool aborting; + /* Flag to identify a Multi-part Read Transaction */ + bool is_singlepart_read; + u8 nbytes_processed; + u8 remain_len; + u8 recv_len; + /* Block Number of a Multi-part Read Transaction */ + u8 block_num; + bool request_available; + bool response_in_progress; + /* Response buffer for Multi-part Read Transaction */ + u8 response_buf[MAX_PAYLOAD_PER_TRANSACTION]; + struct ssif_msg response; + struct ssif_msg request; +}; + +static inline struct ssif_bmc_ctx *to_ssif_bmc(struct file *file) +{ + return container_of(file->private_data, struct ssif_bmc_ctx, miscdev); +} +#endif /* __SSIF_BMC_H__ */ -- 2.28.0 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=-17.5 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,MSGID_FROM_MTA_HEADER,SPF_HELO_NONE, SPF_PASS,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 0B019C07E95 for ; Tue, 13 Jul 2021 05:57:16 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id C26CC61008 for ; Tue, 13 Jul 2021 05:57:15 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org C26CC61008 Authentication-Results: mail.kernel.org; dmarc=fail (p=quarantine dis=none) header.from=os.amperecomputing.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=StSZ2evlMouq6qU/PbEUZQCZ1C67MI1qTGNhowSN0z4=; b=lIbqNmvr3unPOt r92L4guO5A4ZTCad1u54ra62vMfecpXm/6NC4DbJZzXjSop1uP1mLy8zhjp9+zo3u94Rtoku8fj95 +Bk19oaflXxK4msxC0ut9Iq8GN0n6BgLJXoQgN9aBLTaehMBzY3zBLzMxsZRCUgSVU/MmaJgWhjx5 qOYXNAOjtst1VbNkQoTZK34XKrn1CotKNyQzeP/YOha2CXmGzl9MbNiIzGKeh8RSlRkyc7yGzUPex 46bqMvcFr6nMDmJf/D6p/qfFGhdGSfKbF/tbC0UY7eMYoCGOs7vNjERwK9gVNqWZEaqKly3GrxF7s psH+rWX3Qvmhp3EH6CBg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1m3BNw-009CSI-W4; Tue, 13 Jul 2021 05:55:13 +0000 Received: from mail-dm6nam10on2095.outbound.protection.outlook.com ([40.107.93.95] helo=NAM10-DM6-obe.outbound.protection.outlook.com) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1m3BNa-009CGf-7P for linux-arm-kernel@lists.infradead.org; Tue, 13 Jul 2021 05:54:53 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=jVe0vKpcctIo13jJmdKu8uSNGxFAJo4IgPCnqf6Obgz7vyeLzvK4DvkNqKUSUMWbr8sSl12JkwzcA0gAHQGJi3iJxaXadl3dEqPVrYEN1TBzhYJzk7ieOsMU1J/fJMefEf1Wl0UaeLtv/IK1pKqEXF3l1nBBHdl09B8BS89QM5/OXMBXAq+8+sRN73ZXah93p1gpBZvmxcDNUJHIwy+22nAcsny5igsP3X1Nv0dD00oK0QdhmrW5U+VhN+op1BTpWl42z/DwDgXtxGBRC43mtNca5FGhBTS4lv9a9KMVcGnrWdw7pPwtvmf9uOgf3tYoDStD5jst6Zd2Jij8WzBrpA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=MRvCkcGmZy3X92RZSBBoLKQ35hZ5gVX6F7qMfHu+Rok=; b=JsQVcBtKiW+ea1lVbxf8cOMR0Q0NA5rRYdRYJ1EjguoqKgymlYDZWolMQUbnNMiQPxfMnU1ZYpOA4IcVhlPGY3zFNO/JjMCaugDgKiXiRBhvUkRMs+t6QYYbZpev+xZWL9EGCuqbwneTkLni7P798QAyEHVxXiSUTcZUSNKA/kYA8rYcTKM5rWU2njXLQsOuIOY1n7Nt/PyffF5Wdato9S8n6aRj9OxdleOSgWkh6c3LjW9aXsQyzpE+K67TH69+z7SrJ1yz0Z5obImDYXp7JzHZCfFKo7qyA4ACByHvX5c2ebE+aQxxDBwhEnsHaK2eoseir9HQo8FMYJUXwWXphg== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=os.amperecomputing.com; dmarc=pass action=none header.from=os.amperecomputing.com; dkim=pass header.d=os.amperecomputing.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=os.amperecomputing.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=MRvCkcGmZy3X92RZSBBoLKQ35hZ5gVX6F7qMfHu+Rok=; b=n6L0Hz0kumq0OzNpogAyeAoXDgWzTJ5fqyLLBgZCAaXjkysYK/6YqLzx1bBu7pwAIpYYddq6Y4mpXoQywHMyj+I/GK15Fos0pp3zp9zm467ckKEvtlh+n7e+yn/TrWP/hNAk1dBqNLJ0b6Q4j1/7zxVdUh3/3qGJs9Gk3gp6mew= Authentication-Results: acm.org; dkim=none (message not signed) header.d=none;acm.org; dmarc=none action=none header.from=os.amperecomputing.com; Received: from MW2PR0102MB3482.prod.exchangelabs.com (2603:10b6:302:c::32) by CO1PR01MB6535.prod.exchangelabs.com (2603:10b6:303:d9::17) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4308.19; Tue, 13 Jul 2021 05:54:47 +0000 Received: from MW2PR0102MB3482.prod.exchangelabs.com ([fe80::452a:24fb:12cb:9d7e]) by MW2PR0102MB3482.prod.exchangelabs.com ([fe80::452a:24fb:12cb:9d7e%5]) with mapi id 15.20.4308.027; Tue, 13 Jul 2021 05:54:47 +0000 From: Quan Nguyen To: Corey Minyard , Rob Herring , Joel Stanley , Andrew Jeffery , Brendan Higgins , Benjamin Herrenschmidt , Wolfram Sang , openipmi-developer@lists.sourceforge.net, devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-aspeed@lists.ozlabs.org, linux-kernel@vger.kernel.org, linux-i2c@vger.kernel.org Cc: Open Source Submission , Phong Vo , "Thang Q . Nguyen" Subject: [PATCH v4 1/3] ipmi: ssif_bmc: Add SSIF BMC driver Date: Tue, 13 Jul 2021 12:54:23 +0700 Message-Id: <20210713055425.30636-2-quan@os.amperecomputing.com> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20210713055425.30636-1-quan@os.amperecomputing.com> References: <20210713055425.30636-1-quan@os.amperecomputing.com> X-ClientProxiedBy: HKAPR03CA0027.apcprd03.prod.outlook.com (2603:1096:203:c9::14) To MW2PR0102MB3482.prod.exchangelabs.com (2603:10b6:302:c::32) MIME-Version: 1.0 X-MS-Exchange-MessageSentRepresentingType: 1 Received: from hcm-sw-17.amperecomputing.com (118.69.219.201) by HKAPR03CA0027.apcprd03.prod.outlook.com (2603:1096:203:c9::14) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4331.10 via Frontend Transport; Tue, 13 Jul 2021 05:54:43 +0000 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 61f6150d-c42a-4d25-d8a6-08d945c2b880 X-MS-TrafficTypeDiagnostic: CO1PR01MB6535: X-MS-Exchange-Transport-Forked: True X-Microsoft-Antispam-PRVS: X-MS-Oob-TLC-OOBClassifiers: OLM:3044; X-MS-Exchange-SenderADCheck: 1 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: jDO4Gr8uTPEAARhIG+6EdCP/zdidEH8VXrPclSXiwflta/4Ubh49lgEpZ9C5ENhoqvI7ekXK9MVdqYRyFqhIYSRmHyN3fijTp2h/7n5M0t7ZuMS7oMXKz6kbNwDI1vCAnrWqfx+GpyKT7oHuR5WNZqay4uVZ1RmE3sxncwqCc5Ixt84cj+PSD7X6s3loODW3l6NioE13cMJlU7od0me1dBxi2xcoWM1CrJ2KiMCmZ+fQ6Z5ABheuSN50DMWoDBCtzfNGC7zhDnY0NqaV+jRgo8F1AV+3f3SeeeWK5AtyTgHpvbzSZrrAuArYKKenS6QINLeXOJB1QvqjC9oCbURWUxcyyMw1IW5zbGqKJR40kudq339zPwFNtiPZt+0fPwxb68yaDYeioB5YDnVp1E/vH/T/Sh094xpCECckea6FSqikxAa80EV5kg0Cum3QmUh0V0tMKcBMDr7B0Gz5CwQVrsLvVG6kyy2eBb65TUNUTe++j72isCQwhepenTPaK0M8xfdMa6FLRXFMmKHURkMEKCsAt7h4Og89Y3hhEIYcOog4ZvZj6BOdIa+UiLs5e1gj5M7kJGI48ScciW2xd+ojW9thIMSlFlCgOYyzZ8Cx6SLDg8tQPf8h1Im19Wy7qlRMbKtXrgT22dNnYRcwysyP4bVaDPSrXtUIQDQBgryKsX0kDMjCrkm16pMLI904RbRgjltApbNwX1iZvXrpFSH9N3Z7jmx6Pc5yUXVJxpi3op94JcczjPlkt62QeaB70h3qqQb2+lh6VQZZEDRc5eEc83sQO/zmZyPhsOIFuvZ5Q5ujOTHbXrzosGbZWTqcl5kTiM8pvRdgiVWNNoofoIoFag== X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:MW2PR0102MB3482.prod.exchangelabs.com; PTR:; CAT:NONE; SFS:(4636009)(376002)(136003)(366004)(396003)(39850400004)(346002)(956004)(8676002)(54906003)(86362001)(5660300002)(2616005)(2906002)(1076003)(7416002)(52116002)(66946007)(107886003)(478600001)(66556008)(6666004)(30864003)(66476007)(6506007)(921005)(110136005)(26005)(186003)(38100700002)(316002)(4326008)(38350700002)(83380400001)(6512007)(8936002)(6486002)(2004002); DIR:OUT; SFP:1102; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?utf-8?B?VlI5Q2Z6VS9BSGJYMGJhcUVJUG1EaXdVbWtMVGpoSDF5Z2ZVQXhXL1dhTUxB?= =?utf-8?B?alFTTVRGWkVFMDNtZy8vVSsvQVRraE5zZ1JXcXZXTlQ0RTFJWFFUTkY4WVgy?= =?utf-8?B?Z0wxTzhTdmQrWXVxRUpVam1LdmFta1dDRXF0WjhOZk5iQUhMZXZVOXlhdzJL?= =?utf-8?B?WWltbk81TWs1ZlRmeWJIa0Z2Rms3Nk9iUG12SUtpWkgwek1FR1FzanZTUlBn?= =?utf-8?B?VkFyNXRSVUl0YTdLM3IrUHpEa0pEczgvVXVhNDRrdEZGd1VUbmNIL0dkcW41?= =?utf-8?B?bDVRaFJqaGYvSE43YUh3SW1jWGdXUnJ6eEpYMVNDUmpxNEdKd0tnL2Z3d0pa?= =?utf-8?B?V04wamM0L21wWlJMVXdKWnhkaE14WGNBZWovRWNFaCt6dlkxZmhmV2VPRnAw?= =?utf-8?B?VGp2T2dUK1lvNVhzbXk3eUUvMjdnNTQwRUFSV0VJSUFMdnFqUXh1RDI1cXU2?= =?utf-8?B?NVRjeSs1YmFOQVY5OFdOUG9rL05yazJRbjJzYlpVdWZuMGh4OWIwRGg4bXhG?= =?utf-8?B?ZCt0cTVtQmhjU0M4M1d0akRyZTdtUjJMbVdKZDJuSXBXTFQ2TFNqYkFLOFdX?= =?utf-8?B?dldEMHIzMThXbi9DRllRZGNYSmhQUUFFOHg0NGdEOERZVVV5US94NU1FNUFV?= =?utf-8?B?V3dTQi94R0Q3clVvbnBFNWlnQ2Z2cVpqOXQ4MUluV1VZZXUwcjJ5cDgxc3d4?= =?utf-8?B?NVErbm1DTTdhbllnalJYbkVkMHREUWhPVmFwMmVra1dmVGh0RnVORVZBanN6?= =?utf-8?B?ZFlNQUw0M1lmTGVqVFpRc05TV2NXQ1d2T0tvMmhUZWNOQk5oTzlIaVk4bUxt?= =?utf-8?B?MTNzNEpZVkF3NlhsZXdYWWMvVFNEUDVyejRKS0tienFJTEY2Nk8yZnJXcnhO?= =?utf-8?B?Z05IejZUZzU3dC9KSytSenNQYVgvbmtyNVFMT1I5UkdOZjI1YXU2TEdWdDZ3?= =?utf-8?B?Ry9sMmFKWWFmRHdBTW9yZUhkYUN5MjVHcjg4bW5xMUY0Yk5OdVp4S2NWMDlD?= =?utf-8?B?TXpCTmtMMGk0aXN5UDV0blE2Zlgrc2xCSDkrSkFrVWQ5KzNkOTZXTlQ1OU0v?= =?utf-8?B?M0FLdkhhVGN3dGcyWjRZcHRkbGZ3d1U1dWFVRmpKMW9QTkVQOGtldzNHVytB?= =?utf-8?B?Wm5KTG1KVDc4a0ZNZHk4RnFTZjJQRC9iNkJ0YThBYmJXYzNJTUVSN0N1WWs5?= =?utf-8?B?SWxvWU4zMFk0SEl4U2xycGJPUUNlWWdWNXUwN296cm9SNW5PTkx4QjlCckYv?= =?utf-8?B?dE9XTVdPdUQ3cml4WGszZlhvbXB3Y1ZtUmd1bUR5UnpSVGYyL1AzYzQ2VHRi?= =?utf-8?B?SFdJVHBxUFYweFd1a0NmNENLcXR2WFdnM0NPRUVWSDlJUU9xNE9SNHpoTk1m?= =?utf-8?B?N284ZEFwZGpRT2N0Z3gweUZraWZNTm9UQTdMRmdoWnQ4ZzlLREZuS25pc0lk?= =?utf-8?B?K1JWYkVha3hjQVFFL3NHQjJmak1pekJhWXhRSHlRRVRHVFpzaXhESVZhTDJq?= =?utf-8?B?a1ZXcEd0d25zM0lHV3RnOEZ0UGNsOU14RjZIc2JlV05DMHU2TXlsbHBvRThF?= =?utf-8?B?TSs0NEFZR0NTN3o2czgyblhOZklBdVZySVRhRVVDaWlXOTByZWREd1NLaVVw?= =?utf-8?B?VUVHTm9SYXI3ZksrYnFxSGFPc3RTdVU1RDVkbmRGeGZNSDZyUVpYTnFPTzVR?= =?utf-8?B?clA3bEJVNitKSXdhcVg2Rk00S2dRY252dG9jb3B3WnhpOW9ITmVJZVlLRlgw?= =?utf-8?Q?Pvpih8/6+0jQumBRjJtfEQdCOhO87JMG5M2BAsh?= X-OriginatorOrg: os.amperecomputing.com X-MS-Exchange-CrossTenant-Network-Message-Id: 61f6150d-c42a-4d25-d8a6-08d945c2b880 X-MS-Exchange-CrossTenant-AuthSource: MW2PR0102MB3482.prod.exchangelabs.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 13 Jul 2021 05:54:47.6106 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 3bc2b170-fd94-476d-b0ce-4229bdc904a7 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: 2cgLGhPbvWyTK1vUudvExk+wmJ5Mky5V/IW9t9BjwzC6ysi36/5CZp8mv87hY5AW2MnbbomGJYuz7f/j/2sOobNT9Qyc+pCRCIlA3UXVisY= X-MS-Exchange-Transport-CrossTenantHeadersStamped: CO1PR01MB6535 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210712_225450_406291_E05594C7 X-CRM114-Status: GOOD ( 18.65 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org VGhlIFNNQnVzIHN5c3RlbSBpbnRlcmZhY2UgKFNTSUYpIElQTUkgQk1DIGRyaXZlciBjYW4gYmUg dXNlZCB0byBwZXJmb3JtCmluLWJhbmQgSVBNSSBjb21tdW5pY2F0aW9uIHdpdGggdGhlaXIgaG9z dCBpbiBtYW5hZ2VtZW50IChCTUMpIHNpZGUuCgpTaWduZWQtb2ZmLWJ5OiBRdWFuIE5ndXllbiA8 cXVhbkBvcy5hbXBlcmVjb21wdXRpbmcuY29tPgotLS0KdjQ6CiAgKyBTZW5kIHJlc3BvbnNlIHdp dGggQ29tcGxldGlvbiBjb2RlIDB4RkYgd2hlbiBhYm9ydGluZyAgICAgICAgIFtRdWFuXQogICsg QWRkZWQgYm91bmRpbmcgY2hlY2sgb24gU01CdXMgd3JpdGVzIGFuZCB0aGUgd2hvbGUgcmVxdWVz dCAgICAgW0Rhbl0KICArIE1vdmVkIGJ1ZmZlciB0byBlbmQgb2Ygc3RydWN0IHNzaWZfYm1jX2N0 eCB0byBhdm9pZCBjb250ZXh0CiAgICBjb3JydXB0aW9uIGlmIHNvbWVob3cgYnVmZmVyIGlzIHdy aXR0ZW4gcGFzdCB0aGUgZW5kICAgICAgICAgICBbRGFuXQogICsgUmV0dXJuIC1FSU5WQUwgaWYg dXNlcnNwYWNlIGJ1ZmZlciB0b28gc21hbGwsIGRvbnQKICAgIHNpbGVuY2UgdHJ1bmNhdGUgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbQ29yZXksIEpvZWxdCiAgKyBOb3Qg bmVjZXNzYXJ5IHRvIGNoZWNrIE5PTkJMT0NLIGluIGxvY2sgICAgICAgICAgICAgICAgICAgICAg W0NvcmV5XQogICsgRW5mb3JjZSBvbmUgdXNlciBhdCBhIHRpbWUgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICBbSm9lbF0KICArIFJlamVjdCB3cml0ZSB3aXRoIGludmFsaWQgcmVz cG9uc2UgbGVuZ3RoIGZyb20gdXNlcnNwYWNlICAgICBbQ29yZXldCiAgKyBBZGQgc3RhdGUgbWFj aGluZXMgZm9yIGJldHRlciBzc2lmIGJtYyBzdGF0ZSBoYW5kbGluZyAgICAgICAgIFtRdWFuXQog ICsgRHJvcCBzc2lmX2JtY19hc3BlZWQuYyBhbmQgbWFrZSBzc2lmX2JtYy5jIGlzIGdlbmVyaWMK ICAgIFNTSUYgQk1DIGRyaXZlciAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgW1F1YW5dCiAgKyBDaGFuZ2UgY29tcGF0aWJsZSBzdHJpbmcgImFzcGVlZCxhc3Qy NTAwLXNzaWYtYm1jIiB0bwogICAgImFtcGVyZSxzc2lmLWJtYyIgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICBbUXVhbl0KICArIEFib3J0IGN1cnJlbnQgcmVxdWVz dCB3aXRoIGludmFsaWQgU01CdXMgd3JpdGUgb3IKICAgIGludmFsaWQgY29tbWFuZCAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW1F1YW5dCiAgKyBBYm9ydCBh bGwgcmVxdWVzdCBpZiB0aGVyZSBpcyBwZW5kaW5nIHJlc3BvbnNlICAgICAgICAgICAgICAgIFtR dWFuXQogICsgQ2hhbmdlZCB2YWxpZGF0ZV9wZWMoKSB0byB2YWxpZGF0ZV9yZXF1ZXN0KCkgICAg ICAgICAgICAgICAgICBbUXVhbl0KICArIEFkZCB1bnN1cHBvcnRlZF9zbWJ1c19jbWQoKSB0byBo YW5kbGUgdW5rbm93biBTTUJ1cyBjb21tYW5kICAgW1F1YW5dCiAgKyBQcmludCBpbnRlcm5hbCBz dGF0ZSBzdHJpbmcgZm9yIGVhc2UgaW52ZXN0aWdhdGluZyBpc3N1ZSAgICAgIFtRdWFuXQogICsg TW92ZSB0byBSRUFEWSBzdGF0ZSBvbiBTTEFWRV9TVE9QIGV2ZW50ICAgICAgICAgICAgICAgICAg ICAgICBbUXVhbl0KICArIENoYW5nZSBpbml0aWxpemVfdHJhbnNmZXIoKSB0byBwcm9jZXNzX3Nt YnVzX2NtZCgpICAgICAgICAgICAgW1F1YW5dCiAgKyBJbnRyb2R1Y2UgZnVuY3Rpb25zIGZvciBl YWNoIHNsYXZlIGV2ZW50ICAgICAgICAgICAgICAgICAgICAgIFtRdWFuXQoKdjM6CiAgKyBSZW1v dmVkIHJlZHVuZGFudCBsaWNlbnNlIGluZm8gW0pvZWxdCiAgKyBTd2l0Y2hlZCB0byB1c2UgdHJh ZGl0aW9uYWwgaWYtZWxzZSBbSm9lbF0KICArIFJlbW92ZWQgdW51c2VkIHNzaWZfYm1jX2lvY3Rs KCkgW0pvZWxdCiAgKyBNYWRlIGhhbmRsZV9yZXF1ZXN0KCkvY29tcGxldGVfcmVzcG9uc2UoKSB0 byByZXR1cm4gdm9pZCBbSm9lbF0KICArIFJlZmFjdG9yZWQgc2VuZF9zc2lmX2JtY19yZXNwb25z ZSgpL3JlY2VpdmVfc3NpZl9ibWNfcmVxdWVzdCgpCltDb3JleV0KICArIFJlbW92ZWQgbXV0ZXgg W0NvcmV5XQogICsgVXNlIHNwaW5fbG9jay91bmxvY2tfaXJxc2F2ZS9yZXN0b3JlIGluIGNhbGxi YWNrIFtDb3JleV0KICArIFJlbW92ZWQgdGhlIHVubmVjZXNzYXJ5IG1lbXNldCBbQ29yZXldCiAg KyBTd2l0Y2ggdG8gdXNlIGRldl9lcnIoKSBbQ29yZXldCgp2MjoKICArIEZpeGVkIGNvbXBpbGlu ZyBlcnJvciB3aXRoIENPTVBJTEVfVEVTVCBmb3IgYXJjCgogZHJpdmVycy9jaGFyL2lwbWkvS2Nv bmZpZyAgICB8ICAxMSArCiBkcml2ZXJzL2NoYXIvaXBtaS9NYWtlZmlsZSAgIHwgICAxICsKIGRy aXZlcnMvY2hhci9pcG1pL3NzaWZfYm1jLmMgfCA3ODEgKysrKysrKysrKysrKysrKysrKysrKysr KysrKysrKysrKysKIGRyaXZlcnMvY2hhci9pcG1pL3NzaWZfYm1jLmggfCAxMDYgKysrKysKIDQg ZmlsZXMgY2hhbmdlZCwgODk5IGluc2VydGlvbnMoKykKIGNyZWF0ZSBtb2RlIDEwMDY0NCBkcml2 ZXJzL2NoYXIvaXBtaS9zc2lmX2JtYy5jCiBjcmVhdGUgbW9kZSAxMDA2NDQgZHJpdmVycy9jaGFy L2lwbWkvc3NpZl9ibWMuaAoKZGlmZiAtLWdpdCBhL2RyaXZlcnMvY2hhci9pcG1pL0tjb25maWcg Yi9kcml2ZXJzL2NoYXIvaXBtaS9LY29uZmlnCmluZGV4IDI0OWIzMTE5N2VlYS4uZTA5YTQ3MGFi MmRhIDEwMDY0NAotLS0gYS9kcml2ZXJzL2NoYXIvaXBtaS9LY29uZmlnCisrKyBiL2RyaXZlcnMv Y2hhci9pcG1pL0tjb25maWcKQEAgLTE2MCw2ICsxNjAsMTcgQEAgY29uZmlnIEFTUEVFRF9CVF9J UE1JX0JNQwogCSAgZm91bmQgb24gQXNwZWVkIFNPQ3MgKEFTVDI0MDAgYW5kIEFTVDI1MDApLiBU aGUgZHJpdmVyCiAJICBpbXBsZW1lbnRzIHRoZSBCTUMgc2lkZSBvZiB0aGUgQlQgaW50ZXJmYWNl LgogCitjb25maWcgU1NJRl9JUE1JX0JNQworCXRyaXN0YXRlICJTU0lGIElQTUkgQk1DIGRyaXZl ciIKKwlzZWxlY3QgSTJDCisJc2VsZWN0IEkyQ19TTEFWRQorCWhlbHAKKwkgIFRoaXMgZW5hYmxl cyB0aGUgSVBNSSBTTUJ1cyBzeXN0ZW0gaW50ZXJmYWNlIChTU0lGKSBhdCB0aGUKKwkgIG1hbmFn ZW1lbnQgKEJNQykgc2lkZS4KKworCSAgVGhlIGRyaXZlciBpbXBsZW1lbnRzIHRoZSBCTUMgc2lk ZSBvZiB0aGUgU01CdXMgc3lzdGVtCisJICBpbnRlcmZhY2UgKFNTSUYpLgorCiBjb25maWcgSVBN Ql9ERVZJQ0VfSU5URVJGQUNFCiAJdHJpc3RhdGUgJ0lQTUIgSW50ZXJmYWNlIGhhbmRsZXInCiAJ ZGVwZW5kcyBvbiBJMkMKZGlmZiAtLWdpdCBhL2RyaXZlcnMvY2hhci9pcG1pL01ha2VmaWxlIGIv ZHJpdmVycy9jaGFyL2lwbWkvTWFrZWZpbGUKaW5kZXggODRmNDdkMTgwMDdmLi5hOTNjMDlkYWQy MmEgMTAwNjQ0Ci0tLSBhL2RyaXZlcnMvY2hhci9pcG1pL01ha2VmaWxlCisrKyBiL2RyaXZlcnMv Y2hhci9pcG1pL01ha2VmaWxlCkBAIC0yOSwzICsyOSw0IEBAIG9iai0kKENPTkZJR19BU1BFRURf QlRfSVBNSV9CTUMpICs9IGJ0LWJtYy5vCiBvYmotJChDT05GSUdfQVNQRUVEX0tDU19JUE1JX0JN QykgKz0ga2NzX2JtY19hc3BlZWQubwogb2JqLSQoQ09ORklHX05QQ003WFhfS0NTX0lQTUlfQk1D KSArPSBrY3NfYm1jX25wY203eHgubwogb2JqLSQoQ09ORklHX0lQTUJfREVWSUNFX0lOVEVSRkFD RSkgKz0gaXBtYl9kZXZfaW50Lm8KK29iai0kKENPTkZJR19TU0lGX0lQTUlfQk1DKSArPSBzc2lm X2JtYy5vCmRpZmYgLS1naXQgYS9kcml2ZXJzL2NoYXIvaXBtaS9zc2lmX2JtYy5jIGIvZHJpdmVy cy9jaGFyL2lwbWkvc3NpZl9ibWMuYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAw MDAwMDAuLmIxNWMwNTYyMmU3MgotLS0gL2Rldi9udWxsCisrKyBiL2RyaXZlcnMvY2hhci9pcG1p L3NzaWZfYm1jLmMKQEAgLTAsMCArMSw3ODEgQEAKKy8vIFNQRFgtTGljZW5zZS1JZGVudGlmaWVy OiBHUEwtMi4wKworLyoKKyAqIFRoZSBkcml2ZXIgZm9yIEJNQyBzaWRlIG9mIFNTSUYgaW50ZXJm YWNlCisgKgorICogQ29weXJpZ2h0IChjKSAyMDIxLCBBbXBlcmUgQ29tcHV0aW5nIExMQworICoK KyAqLworCisjaW5jbHVkZSA8bGludXgvaTJjLmg+CisjaW5jbHVkZSA8bGludXgvbWlzY2Rldmlj ZS5oPgorI2luY2x1ZGUgPGxpbnV4L21vZHVsZS5oPgorI2luY2x1ZGUgPGxpbnV4L29mLmg+Cisj aW5jbHVkZSA8bGludXgvcGxhdGZvcm1fZGV2aWNlLmg+CisjaW5jbHVkZSA8bGludXgvcG9sbC5o PgorI2luY2x1ZGUgPGxpbnV4L3NjaGVkLmg+CisjaW5jbHVkZSA8bGludXgvbXV0ZXguaD4KKyNp bmNsdWRlIDxsaW51eC9zcGlubG9jay5oPgorCisjaW5jbHVkZSAic3NpZl9ibWMuaCIKKworc3Rh dGljIGNvbnN0IGNoYXIgKnN0YXRlX3RvX3N0cmluZyhlbnVtIHNzaWZfc3RhdGUgc3RhdGUpCit7 CisJc3dpdGNoIChzdGF0ZSkgeworCWNhc2UgU1NJRl9SRUFEWToKKwkJcmV0dXJuICJTU0lGX1JF QURZIjsKKwljYXNlIFNTSUZfU1RBUlQ6CisJCXJldHVybiAiU1NJRl9TVEFSVCI7CisJY2FzZSBT U0lGX1NNQlVTX0NNRDoKKwkJcmV0dXJuICJTU0lGX1NNQlVTX0NNRCI7CisJY2FzZSBTU0lGX1JF UV9SRUNWSU5HOgorCQlyZXR1cm4gIlNTSUZfUkVRX1JFQ1ZJTkciOworCWNhc2UgU1NJRl9SRVNf U0VORElORzoKKwkJcmV0dXJuICJTU0lGX1JFU19TRU5ESU5HIjsKKwljYXNlIFNTSUZfQkFEX1NN QlVTOgorCQlyZXR1cm4gIlNTSUZfQkFEX1NNQlVTIjsKKwlkZWZhdWx0OgorCQlyZXR1cm4gIlNT SUZfU1RBVEVfVU5LTk9XTiI7CisJfQorfQorCisvKiBIYW5kbGUgU1NJRiBtZXNzYWdlIHRoYXQg d2lsbCBiZSBzZW50IHRvIHVzZXIgKi8KK3N0YXRpYyBzc2l6ZV90IHNzaWZfYm1jX3JlYWQoc3Ry dWN0IGZpbGUgKmZpbGUsIGNoYXIgX191c2VyICpidWYsIHNpemVfdCBjb3VudCwgbG9mZl90ICpw cG9zKQoreworCXN0cnVjdCBzc2lmX2JtY19jdHggKnNzaWZfYm1jID0gdG9fc3NpZl9ibWMoZmls ZSk7CisJc3RydWN0IHNzaWZfbXNnIG1zZzsKKwl1bnNpZ25lZCBsb25nIGZsYWdzOworCXNzaXpl X3QgcmV0OworCisJc3Bpbl9sb2NrX2lycXNhdmUoJnNzaWZfYm1jLT5sb2NrLCBmbGFncyk7CisJ d2hpbGUgKCFzc2lmX2JtYy0+cmVxdWVzdF9hdmFpbGFibGUpIHsKKwkJc3Bpbl91bmxvY2tfaXJx cmVzdG9yZSgmc3NpZl9ibWMtPmxvY2ssIGZsYWdzKTsKKwkJaWYgKGZpbGUtPmZfZmxhZ3MgJiBP X05PTkJMT0NLKQorCQkJcmV0dXJuIC1FQUdBSU47CisJCXJldCA9IHdhaXRfZXZlbnRfaW50ZXJy dXB0aWJsZShzc2lmX2JtYy0+d2FpdF9xdWV1ZSwKKwkJCQkJICAgICAgIHNzaWZfYm1jLT5yZXF1 ZXN0X2F2YWlsYWJsZSk7CisJCWlmIChyZXQpCisJCQlyZXR1cm4gcmV0OworCQlzcGluX2xvY2tf aXJxc2F2ZSgmc3NpZl9ibWMtPmxvY2ssIGZsYWdzKTsKKwl9CisKKwlpZiAoY291bnQgPCBtaW5f dChzc2l6ZV90LCBzc2lmX21zZ19sZW4oJnNzaWZfYm1jLT5yZXF1ZXN0KSwgc2l6ZW9mKHN0cnVj dCBzc2lmX21zZykpKSB7CisJCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJnNzaWZfYm1jLT5sb2Nr LCBmbGFncyk7CisJCXJldCA9IC1FSU5WQUw7CisJfSBlbHNlIHsKKwkJY291bnQgPSBtaW5fdChz c2l6ZV90LCBzc2lmX21zZ19sZW4oJnNzaWZfYm1jLT5yZXF1ZXN0KSwgc2l6ZW9mKHN0cnVjdCBz c2lmX21zZykpOworCQltZW1jcHkoJm1zZywgJnNzaWZfYm1jLT5yZXF1ZXN0LCBjb3VudCk7CisJ CXNzaWZfYm1jLT5yZXF1ZXN0X2F2YWlsYWJsZSA9IGZhbHNlOworCQlzcGluX3VubG9ja19pcnFy ZXN0b3JlKCZzc2lmX2JtYy0+bG9jaywgZmxhZ3MpOworCisJCXJldCA9IGNvcHlfdG9fdXNlcihi dWYsICZtc2csIGNvdW50KTsKKwl9CisKKwlyZXR1cm4gKHJldCA8IDApID8gcmV0IDogY291bnQ7 Cit9CisKKy8qIEhhbmRsZSBTU0lGIG1lc3NhZ2UgdGhhdCBpcyB3cml0dGVuIGJ5IHVzZXIgKi8K K3N0YXRpYyBzc2l6ZV90IHNzaWZfYm1jX3dyaXRlKHN0cnVjdCBmaWxlICpmaWxlLCBjb25zdCBj aGFyIF9fdXNlciAqYnVmLCBzaXplX3QgY291bnQsCisJCQkgICAgICBsb2ZmX3QgKnBwb3MpCit7 CisJc3RydWN0IHNzaWZfYm1jX2N0eCAqc3NpZl9ibWMgPSB0b19zc2lmX2JtYyhmaWxlKTsKKwlz dHJ1Y3Qgc3NpZl9tc2cgbXNnOworCXVuc2lnbmVkIGxvbmcgZmxhZ3M7CisJc3NpemVfdCByZXQ7 CisKKwlpZiAoY291bnQgPiBzaXplb2Yoc3RydWN0IHNzaWZfbXNnKSkKKwkJcmV0dXJuIC1FSU5W QUw7CisKKwlyZXQgPSBjb3B5X2Zyb21fdXNlcigmbXNnLCBidWYsIGNvdW50KTsKKwlpZiAocmV0 KQorCQlyZXR1cm4gcmV0OworCisJaWYgKCFtc2cubGVuIHx8IGNvdW50IDwgc3NpZl9tc2dfbGVu KCZtc2cpKQorCQlyZXR1cm4gLUVJTlZBTDsKKworCXNwaW5fbG9ja19pcnFzYXZlKCZzc2lmX2Jt Yy0+bG9jaywgZmxhZ3MpOworCXdoaWxlIChzc2lmX2JtYy0+cmVzcG9uc2VfaW5fcHJvZ3Jlc3Mp IHsKKwkJc3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmc3NpZl9ibWMtPmxvY2ssIGZsYWdzKTsKKwkJ aWYgKGZpbGUtPmZfZmxhZ3MgJiBPX05PTkJMT0NLKQorCQkJcmV0dXJuIC1FQUdBSU47CisJCXJl dCA9IHdhaXRfZXZlbnRfaW50ZXJydXB0aWJsZShzc2lmX2JtYy0+d2FpdF9xdWV1ZSwKKwkJCQkJ ICAgICAgICFzc2lmX2JtYy0+cmVzcG9uc2VfaW5fcHJvZ3Jlc3MpOworCQlpZiAocmV0KQorCQkJ cmV0dXJuIHJldDsKKwkJc3Bpbl9sb2NrX2lycXNhdmUoJnNzaWZfYm1jLT5sb2NrLCBmbGFncyk7 CisJfQorCisJbWVtY3B5KCZzc2lmX2JtYy0+cmVzcG9uc2UsICZtc2csIGNvdW50KTsKKwlzc2lm X2JtYy0+aXNfc2luZ2xlcGFydF9yZWFkID0gKHNzaWZfbXNnX2xlbigmbXNnKSA8PSBNQVhfUEFZ TE9BRF9QRVJfVFJBTlNBQ1RJT04gKyAxKTsKKwlzc2lmX2JtYy0+cmVzcG9uc2VfaW5fcHJvZ3Jl c3MgPSB0cnVlOworCisJaWYgKHNzaWZfYm1jLT5jbGllbnQtPmFkYXB0ZXItPmFsZ28tPnNsYXZl X2VuYWJsZSkKKwkJcmV0ID0gc3NpZl9ibWMtPmNsaWVudC0+YWRhcHRlci0+YWxnby0+c2xhdmVf ZW5hYmxlKHNzaWZfYm1jLT5jbGllbnQsIHRydWUpOworCisJc3Bpbl91bmxvY2tfaXJxcmVzdG9y ZSgmc3NpZl9ibWMtPmxvY2ssIGZsYWdzKTsKKworCXJldHVybiAocmV0IDwgMCkgPyByZXQgOiBj b3VudDsKK30KKworc3RhdGljIGludCBzc2lmX2JtY19vcGVuKHN0cnVjdCBpbm9kZSAqaW5vZGUs IHN0cnVjdCBmaWxlICpmaWxlKQoreworCXN0cnVjdCBzc2lmX2JtY19jdHggKnNzaWZfYm1jID0g dG9fc3NpZl9ibWMoZmlsZSk7CisJaW50IHJldCA9IDA7CisKKwlzcGluX2xvY2tfaXJxKCZzc2lm X2JtYy0+bG9jayk7CisJaWYgKCFzc2lmX2JtYy0+cnVubmluZykKKwkJc3NpZl9ibWMtPnJ1bm5p bmcgPSAxOworCWVsc2UKKwkJcmV0ID0gLUVCVVNZOworCXNwaW5fdW5sb2NrX2lycSgmc3NpZl9i bWMtPmxvY2spOworCisJcmV0dXJuIHJldDsKK30KKworc3RhdGljIHVuc2lnbmVkIGludCBzc2lm X2JtY19wb2xsKHN0cnVjdCBmaWxlICpmaWxlLCBwb2xsX3RhYmxlICp3YWl0KQoreworCXN0cnVj dCBzc2lmX2JtY19jdHggKnNzaWZfYm1jID0gdG9fc3NpZl9ibWMoZmlsZSk7CisJdW5zaWduZWQg aW50IG1hc2sgPSAwOworCisJcG9sbF93YWl0KGZpbGUsICZzc2lmX2JtYy0+d2FpdF9xdWV1ZSwg d2FpdCk7CisKKwlzcGluX2xvY2tfaXJxKCZzc2lmX2JtYy0+bG9jayk7CisJLyogVGhlIHJlcXVl c3QgaXMgYXZhaWxhYmxlLCB1c2Vyc3BhY2UgYXBwbGljYXRpb24gY2FuIGdldCB0aGUgcmVxdWVz dCAqLworCWlmIChzc2lmX2JtYy0+cmVxdWVzdF9hdmFpbGFibGUpCisJCW1hc2sgfD0gUE9MTElO OworCisJc3Bpbl91bmxvY2tfaXJxKCZzc2lmX2JtYy0+bG9jayk7CisKKwlyZXR1cm4gbWFzazsK K30KKworc3RhdGljIGludCBzc2lmX2JtY19yZWxlYXNlKHN0cnVjdCBpbm9kZSAqaW5vZGUsIHN0 cnVjdCBmaWxlICpmaWxlKQoreworCXN0cnVjdCBzc2lmX2JtY19jdHggKnNzaWZfYm1jID0gdG9f c3NpZl9ibWMoZmlsZSk7CisKKwlzcGluX2xvY2tfaXJxKCZzc2lmX2JtYy0+bG9jayk7CisJc3Np Zl9ibWMtPnJ1bm5pbmcgPSAwOworCXNwaW5fdW5sb2NrX2lycSgmc3NpZl9ibWMtPmxvY2spOwor CisJcmV0dXJuIDA7Cit9CisKKy8qCisgKiBTeXN0ZW0gY2FsbHMgdG8gZGV2aWNlIGludGVyZmFj ZSBmb3IgdXNlciBhcHBzCisgKi8KK3N0YXRpYyBjb25zdCBzdHJ1Y3QgZmlsZV9vcGVyYXRpb25z IHNzaWZfYm1jX2ZvcHMgPSB7CisJLm93bmVyCQk9IFRISVNfTU9EVUxFLAorCS5vcGVuCQk9IHNz aWZfYm1jX29wZW4sCisJLnJlYWQJCT0gc3NpZl9ibWNfcmVhZCwKKwkud3JpdGUJCT0gc3NpZl9i bWNfd3JpdGUsCisJLnJlbGVhc2UJPSBzc2lmX2JtY19yZWxlYXNlLAorCS5wb2xsCQk9IHNzaWZf Ym1jX3BvbGwsCit9OworCisvKiBDYWxsZWQgd2l0aCBzc2lmX2JtYy0+bG9jayBoZWxkLiAqLwor c3RhdGljIHZvaWQgY29tcGxldGVfcmVzcG9uc2Uoc3RydWN0IHNzaWZfYm1jX2N0eCAqc3NpZl9i bWMpCit7CisJLyogSW52YWxpZGF0ZSByZXNwb25zZSBpbiBidWZmZXIgdG8gZGVub3RlIGl0IGhh dmluZyBiZWVuIHNlbnQuICovCisJc3NpZl9ibWMtPnJlc3BvbnNlLmxlbiA9IDA7CisJc3NpZl9i bWMtPnJlc3BvbnNlX2luX3Byb2dyZXNzID0gZmFsc2U7CisJc3NpZl9ibWMtPm5ieXRlc19wcm9j ZXNzZWQgPSAwOworCXNzaWZfYm1jLT5yZW1haW5fbGVuID0gMDsKKwl3YWtlX3VwX2FsbCgmc3Np Zl9ibWMtPndhaXRfcXVldWUpOworfQorCisvKiBDYWxsZWQgd2l0aCBzc2lmX2JtYy0+bG9jayBo ZWxkLiAqLworc3RhdGljIHZvaWQgaGFuZGxlX3JlcXVlc3Qoc3RydWN0IHNzaWZfYm1jX2N0eCAq c3NpZl9ibWMpCit7CisJaWYgKHNzaWZfYm1jLT5jbGllbnQtPmFkYXB0ZXItPmFsZ28tPnNsYXZl X2VuYWJsZSkKKwkJc3NpZl9ibWMtPmNsaWVudC0+YWRhcHRlci0+YWxnby0+c2xhdmVfZW5hYmxl KHNzaWZfYm1jLT5jbGllbnQsIGZhbHNlKTsKKworCS8qIFJlcXVlc3QgbWVzc2FnZSBpcyBhdmFp bGFibGUgdG8gcHJvY2VzcyAqLworCXNzaWZfYm1jLT5yZXF1ZXN0X2F2YWlsYWJsZSA9IHRydWU7 CisJLyoKKwkgKiBUaGlzIGlzIHRoZSBuZXcgUkVBRCByZXF1ZXN0LgorCSAqLworCXdha2VfdXBf YWxsKCZzc2lmX2JtYy0+d2FpdF9xdWV1ZSk7Cit9CisKK3N0YXRpYyB2b2lkIHNldF9tdWx0aXBh cnRfcmVzcG9uc2VfYnVmZmVyKHN0cnVjdCBzc2lmX2JtY19jdHggKnNzaWZfYm1jLCB1OCAqdmFs KQoreworCXU4IHJlc3BvbnNlX2xlbiA9IDA7CisJaW50IGlkeCA9IDA7CisJdTggZGF0YV9sZW47 CisKKwlkYXRhX2xlbiA9IHNzaWZfYm1jLT5yZXNwb25zZS5sZW47CisJc3dpdGNoIChzc2lmX2Jt Yy0+c21idXNfY21kKSB7CisJY2FzZSBTU0lGX0lQTUlfTVVMVElQQVJUX1JFQURfU1RBUlQ6CisJ CS8qCisJCSAqIFJlYWQgU3RhcnQgbGVuZ3RoIGlzIDMyIGJ5dGVzLgorCQkgKiBSZWFkIFN0YXJ0 IHRyYW5zZmVyIGZpcnN0IDMwIGJ5dGVzIG9mIElQTUkgcmVzcG9uc2UKKwkJICogYW5kIDIgc3Bl Y2lhbCBjb2RlIDB4MDAsIDB4MDEuCisJCSAqLworCQkqdmFsID0gTUFYX1BBWUxPQURfUEVSX1RS QU5TQUNUSU9OOworCQlzc2lmX2JtYy0+cmVtYWluX2xlbiA9IGRhdGFfbGVuIC0gTUFYX0lQTUlf REFUQV9QRVJfU1RBUlRfVFJBTlNBQ1RJT047CisJCXNzaWZfYm1jLT5ibG9ja19udW0gPSAwOwor CisJCXNzaWZfYm1jLT5yZXNwb25zZV9idWZbaWR4KytdID0gMHgwMDsgLyogU3RhcnQgRmxhZyAq LworCQlzc2lmX2JtYy0+cmVzcG9uc2VfYnVmW2lkeCsrXSA9IDB4MDE7IC8qIFN0YXJ0IEZsYWcg Ki8KKwkJc3NpZl9ibWMtPnJlc3BvbnNlX2J1ZltpZHgrK10gPSBzc2lmX2JtYy0+cmVzcG9uc2Uu bmV0Zm5fbHVuOworCQlzc2lmX2JtYy0+cmVzcG9uc2VfYnVmW2lkeCsrXSA9IHNzaWZfYm1jLT5y ZXNwb25zZS5jbWQ7CisJCXNzaWZfYm1jLT5yZXNwb25zZV9idWZbaWR4KytdID0gc3NpZl9ibWMt PnJlc3BvbnNlLnBheWxvYWRbMF07CisKKwkJcmVzcG9uc2VfbGVuID0gTUFYX1BBWUxPQURfUEVS X1RSQU5TQUNUSU9OIC0gaWR4OworCisJCW1lbWNweSgmc3NpZl9ibWMtPnJlc3BvbnNlX2J1Zltp ZHhdLCAmc3NpZl9ibWMtPnJlc3BvbnNlLnBheWxvYWRbMV0sCisJCSAgICAgICByZXNwb25zZV9s ZW4pOworCQlicmVhazsKKworCWNhc2UgU1NJRl9JUE1JX01VTFRJUEFSVF9SRUFEX01JRERMRToK KwkJLyoKKwkJICogSVBNSSBSRUFEIE1pZGRsZSBvciBSRUFEIEVuZCBtZXNzYWdlcyBjYW4gY2Fy cnkgdXAgdG8gMzEgYnl0ZXMKKwkJICogSVBNSSBkYXRhIHBsdXMgYmxvY2sgbnVtYmVyIGJ5dGUu CisJCSAqLworCQlpZiAoc3NpZl9ibWMtPnJlbWFpbl9sZW4gPCBNQVhfSVBNSV9EQVRBX1BFUl9N SURETEVfVFJBTlNBQ1RJT04pIHsKKwkJCS8qCisJCQkgKiBUaGlzIGlzIFJFQUQgRW5kIG1lc3Nh Z2UKKwkJCSAqICBSZXR1cm4gbGVuZ3RoIGlzIHRoZSByZW1haW5pbmcgcmVzcG9uc2UgZGF0YSBs ZW5ndGgKKwkJCSAqICBwbHVzIGJsb2NrIG51bWJlcgorCQkJICogIEJsb2NrIG51bWJlciAweEZG IGlzIHRvIGluZGljYXRlIHRoaXMgaXMgbGFzdCBtZXNzYWdlCisJCQkgKgorCQkJICovCisJCQkq dmFsID0gc3NpZl9ibWMtPnJlbWFpbl9sZW4gKyAxOworCQkJc3NpZl9ibWMtPmJsb2NrX251bSA9 IDB4RkY7CisJCQlzc2lmX2JtYy0+cmVzcG9uc2VfYnVmW2lkeCsrXSA9IHNzaWZfYm1jLT5ibG9j a19udW07CisJCQlyZXNwb25zZV9sZW4gPSBzc2lmX2JtYy0+cmVtYWluX2xlbjsKKwkJCS8qIENs ZWFuIHRoZSBidWZmZXIgKi8KKwkJCW1lbXNldCgmc3NpZl9ibWMtPnJlc3BvbnNlX2J1ZltpZHhd LCAwLCBNQVhfUEFZTE9BRF9QRVJfVFJBTlNBQ1RJT04gLSBpZHgpOworCQl9IGVsc2UgeworCQkJ LyoKKwkJCSAqIFRoaXMgaXMgUkVBRCBNaWRkbGUgbWVzc2FnZQorCQkJICogIFJlc3BvbnNlIGxl bmd0aCBpcyB0aGUgbWF4aW11bSBTTUJVUyB0cmFuc2ZlciBsZW5ndGgKKwkJCSAqICBCbG9jayBu dW1iZXIgYnl0ZSBpcyBpbmNyZW1lbnRlZAorCQkJICogUmV0dXJuIGxlbmd0aCBpcyBtYXhpbXVt IFNNQlVTIHRyYW5zZmVyIGxlbmd0aAorCQkJICovCisJCQkqdmFsID0gTUFYX1BBWUxPQURfUEVS X1RSQU5TQUNUSU9OOworCQkJc3NpZl9ibWMtPnJlbWFpbl9sZW4gLT0gTUFYX0lQTUlfREFUQV9Q RVJfTUlERExFX1RSQU5TQUNUSU9OOworCQkJcmVzcG9uc2VfbGVuID0gTUFYX0lQTUlfREFUQV9Q RVJfTUlERExFX1RSQU5TQUNUSU9OOworCQkJc3NpZl9ibWMtPnJlc3BvbnNlX2J1ZltpZHgrK10g PSBzc2lmX2JtYy0+YmxvY2tfbnVtOworCQkJc3NpZl9ibWMtPmJsb2NrX251bSsrOworCQl9CisK KwkJbWVtY3B5KCZzc2lmX2JtYy0+cmVzcG9uc2VfYnVmW2lkeF0sCisJCSAgICAgICBzc2lmX2Jt Yy0+cmVzcG9uc2UucGF5bG9hZCArIDEgKyBzc2lmX2JtYy0+bmJ5dGVzX3Byb2Nlc3NlZCwKKwkJ ICAgICAgIHJlc3BvbnNlX2xlbik7CisJCWJyZWFrOworCisJZGVmYXVsdDoKKwkJLyogRG8gbm90 IGV4cGVjdCB0byBnbyB0byB0aGlzIGNhc2UgKi8KKwkJZGV2X2Vycigmc3NpZl9ibWMtPmNsaWVu dC0+ZGV2LAorCQkJIiVzOiBVbmV4cGVjdGVkIFNNQnVzIGNvbW1hbmQgMHgleCwgYWJvcnRpbmcg Li4uXG4iLAorCQkJX19mdW5jX18sIHNzaWZfYm1jLT5zbWJ1c19jbWQpOworCQlzc2lmX2JtYy0+ YWJvcnRpbmcgPSB0cnVlOworCQlicmVhazsKKwl9CisKKwlzc2lmX2JtYy0+bmJ5dGVzX3Byb2Nl c3NlZCArPSByZXNwb25zZV9sZW47Cit9CisKKy8qIFByb2Nlc3MgdGhlIElQTUkgcmVzcG9uc2Ug dGhhdCB3aWxsIGJlIHJlYWQgYnkgbWFzdGVyICovCitzdGF0aWMgdm9pZCBoYW5kbGVfcmVhZF9w cm9jZXNzZWQoc3RydWN0IHNzaWZfYm1jX2N0eCAqc3NpZl9ibWMsIHU4ICp2YWwpCit7CisJdTgg KmJ1ZjsKKwl1OCBwZWNfbGVuLCBhZGRyLCBsZW47CisJdTggcGVjID0gMDsKKworCXBlY19sZW4g PSBzc2lmX2JtYy0+cGVjX3N1cHBvcnQgPyAxIDogMDsKKwkvKiBQRUMgLSBTdGFydCBSZWFkIEFk ZHJlc3MgKi8KKwlhZGRyID0gR0VUXzhCSVRfQUREUihzc2lmX2JtYy0+Y2xpZW50LT5hZGRyKTsK KwlwZWMgPSBpMmNfc21idXNfcGVjKHBlYywgJmFkZHIsIDEpOworCS8qIFBFQyAtIFNTSUYgQ29t bWFuZCAqLworCXBlYyA9IGkyY19zbWJ1c19wZWMocGVjLCAmc3NpZl9ibWMtPnNtYnVzX2NtZCwg MSk7CisJLyogUEVDIC0gUmVzdGFydCBXcml0ZSBBZGRyZXNzICovCisJYWRkciA9IGFkZHIgfCAw eDAxOworCXBlYyA9IGkyY19zbWJ1c19wZWMocGVjLCAmYWRkciwgMSk7CisKKwlpZiAoc3NpZl9i bWMtPmlzX3NpbmdsZXBhcnRfcmVhZCkgeworCQkvKiBTaW5nbGUtcGFydCBSZWFkIHByb2Nlc3Np bmcgKi8KKwkJYnVmID0gKHU4ICopJnNzaWZfYm1jLT5yZXNwb25zZTsKKworCQlpZiAoc3NpZl9i bWMtPnJlc3BvbnNlLmxlbiAmJiBzc2lmX2JtYy0+bXNnX2lkeCA8IHNzaWZfYm1jLT5yZXNwb25z ZS5sZW4pIHsKKwkJCXNzaWZfYm1jLT5tc2dfaWR4Kys7CisJCQkqdmFsID0gYnVmW3NzaWZfYm1j LT5tc2dfaWR4XTsKKwkJfSBlbHNlIGlmIChzc2lmX2JtYy0+cmVzcG9uc2UubGVuICYmIHNzaWZf Ym1jLT5tc2dfaWR4ID09IHNzaWZfYm1jLT5yZXNwb25zZS5sZW4pIHsKKwkJCXNzaWZfYm1jLT5t c2dfaWR4Kys7CisJCQkqdmFsID0gaTJjX3NtYnVzX3BlYyhwZWMsIGJ1Ziwgc3NpZl9tc2dfbGVu KCZzc2lmX2JtYy0+cmVzcG9uc2UpKTsKKwkJfSBlbHNlIHsKKwkJCSp2YWwgPSAwOworCQl9CisJ CS8qIEludmFsaWRhdGUgcmVzcG9uc2UgYnVmZmVyIHRvIGRlbm90ZSBpdCBpcyBzZW50ICovCisJ CWlmIChzc2lmX2JtYy0+bXNnX2lkeCArIDEgPj0gKHNzaWZfbXNnX2xlbigmc3NpZl9ibWMtPnJl c3BvbnNlKSArIHBlY19sZW4pKQorCQkJY29tcGxldGVfcmVzcG9uc2Uoc3NpZl9ibWMpOworCX0g ZWxzZSB7CisJCS8qIE11bHRpLXBhcnQgUmVhZCBwcm9jZXNzaW5nICovCisJCXN3aXRjaCAoc3Np Zl9ibWMtPnNtYnVzX2NtZCkgeworCQljYXNlIFNTSUZfSVBNSV9NVUxUSVBBUlRfUkVBRF9TVEFS VDoKKwkJY2FzZSBTU0lGX0lQTUlfTVVMVElQQVJUX1JFQURfTUlERExFOgorCQkJYnVmID0gKHU4 ICopJnNzaWZfYm1jLT5yZXNwb25zZV9idWY7CisJCQkqdmFsID0gYnVmW3NzaWZfYm1jLT5tc2df aWR4XTsKKwkJCXNzaWZfYm1jLT5tc2dfaWR4Kys7CisJCQlicmVhazsKKwkJZGVmYXVsdDoKKwkJ CS8qIERvIG5vdCBleHBlY3QgdG8gZ28gdG8gdGhpcyBjYXNlICovCisJCQlkZXZfZXJyKCZzc2lm X2JtYy0+Y2xpZW50LT5kZXYsCisJCQkJIiVzOiBVbmV4cGVjdGVkIFNNQnVzIGNvbW1hbmQgMHgl eCwgYWJvcnRpbmcgLi4uXG4iLAorCQkJCV9fZnVuY19fLCBzc2lmX2JtYy0+c21idXNfY21kKTsK KwkJCXNzaWZfYm1jLT5hYm9ydGluZyA9IHRydWU7CisJCQlicmVhazsKKwkJfQorCisJCWxlbiA9 IChzc2lmX2JtYy0+YmxvY2tfbnVtID09IDB4RkYpID8KKwkJICAgICAgIHNzaWZfYm1jLT5yZW1h aW5fbGVuICsgMSA6IE1BWF9QQVlMT0FEX1BFUl9UUkFOU0FDVElPTjsKKwkJaWYgKHNzaWZfYm1j LT5tc2dfaWR4ID09IChsZW4gKyAxKSkgeworCQkJcGVjID0gaTJjX3NtYnVzX3BlYyhwZWMsICZs ZW4sIDEpOworCQkJKnZhbCA9IGkyY19zbWJ1c19wZWMocGVjLCBzc2lmX2JtYy0+cmVzcG9uc2Vf YnVmLCBsZW4pOworCQl9CisJCS8qIEludmFsaWRhdGUgcmVzcG9uc2UgYnVmZmVyIHRvIGRlbm90 ZSBsYXN0IHJlc3BvbnNlIGlzIHNlbnQgKi8KKwkJaWYgKHNzaWZfYm1jLT5ibG9ja19udW0gPT0g MHhGRiAmJgorCQkgICAgc3NpZl9ibWMtPm1zZ19pZHggPiAoc3NpZl9ibWMtPnJlbWFpbl9sZW4g KyBwZWNfbGVuKSkgeworCQkJY29tcGxldGVfcmVzcG9uc2Uoc3NpZl9ibWMpOworCQl9CisJfQor fQorCitzdGF0aWMgdm9pZCBoYW5kbGVfd3JpdGVfcmVjZWl2ZWQoc3RydWN0IHNzaWZfYm1jX2N0 eCAqc3NpZl9ibWMsIHU4ICp2YWwpCit7CisJdTggKmJ1ZiA9ICh1OCAqKSZzc2lmX2JtYy0+cmVx dWVzdDsKKworCWlmIChzc2lmX2JtYy0+bXNnX2lkeCA+PSBzaXplb2Yoc3RydWN0IHNzaWZfbXNn KSkKKwkJcmV0dXJuOworCisJc3dpdGNoIChzc2lmX2JtYy0+c21idXNfY21kKSB7CisJY2FzZSBT U0lGX0lQTUlfU0lOR0xFUEFSVF9XUklURToKKwkJYnVmW3NzaWZfYm1jLT5tc2dfaWR4IC0gMV0g PSAqdmFsOworCQlzc2lmX2JtYy0+bXNnX2lkeCsrOworCisJCWJyZWFrOworCWNhc2UgU1NJRl9J UE1JX01VTFRJUEFSVF9XUklURV9TVEFSVDoKKwkJaWYgKHNzaWZfYm1jLT5tc2dfaWR4ID09IDEp CisJCQlzc2lmX2JtYy0+cmVxdWVzdC5sZW4gPSAwOworCisJCWZhbGx0aHJvdWdoOworCWNhc2Ug U1NJRl9JUE1JX01VTFRJUEFSVF9XUklURV9NSURETEU6CisJCS8qIFRoZSBsZW4gc2hvdWxkIGFs d2F5cyBiZSAzMiAqLworCQlpZiAoc3NpZl9ibWMtPm1zZ19pZHggPT0gMSAmJiAqdmFsICE9IE1B WF9QQVlMT0FEX1BFUl9UUkFOU0FDVElPTikgeworCQkJZGV2X3dhcm4oJnNzaWZfYm1jLT5jbGll bnQtPmRldiwKKwkJCQkgIldhcm46IEludmFsaWQgTXVsdGlwYXJ0IFdyaXRlIGxlbiwgYWJvcnRp bmcgLi4uIik7CisJCQlzc2lmX2JtYy0+YWJvcnRpbmcgPSB0cnVlOworCQl9CisKKwkJZmFsbHRo cm91Z2g7CisJY2FzZSBTU0lGX0lQTUlfTVVMVElQQVJUX1dSSVRFX0VORDoKKwkJLyogTXVsdGkt cGFydCB3cml0ZSwgMm5kIGJ5dGUgcmVjZWl2ZWQgaXMgbGVuZ3RoICovCisJCWlmIChzc2lmX2Jt Yy0+bXNnX2lkeCA9PSAxKSB7CisJCQlpZiAoKnZhbCA+IE1BWF9QQVlMT0FEX1BFUl9UUkFOU0FD VElPTikgeworCQkJCWRldl93YXJuKCZzc2lmX2JtYy0+Y2xpZW50LT5kZXYsCisJCQkJCSAiV2Fy bjogSW52YWxpZCBNdWx0aXBhcnQgV3JpdGUgRW5kIGxlbiwgYWJvcnRpbmcgLi4uIik7CisJCQkJ c3NpZl9ibWMtPmFib3J0aW5nID0gdHJ1ZTsKKwkJCX0KKworCQkJc3NpZl9ibWMtPnJlcXVlc3Qu bGVuICs9ICp2YWw7CisJCQlzc2lmX2JtYy0+cmVjdl9sZW4gPSAqdmFsOworCisJCQkvKiByZXF1 ZXN0IGxlbiBzaG91bGQgbmV2ZXIgZXhjZWVkZWQgMjU1IGJ5dGVzICovCisJCQlpZiAoc3NpZl9i bWMtPnJlcXVlc3QubGVuID4gMjU1KSB7CisJCQkJZGV2X3dhcm4oJnNzaWZfYm1jLT5jbGllbnQt PmRldiwKKwkJCQkJICJXYXJuOiBJbnZhbGlkIHJlcXVlc3QgbGVuLCBhYm9ydGluZyAuLi4iKTsK KwkJCQlzc2lmX2JtYy0+YWJvcnRpbmcgPSB0cnVlOworCQkJfQorCisJCX0gZWxzZSB7CisJCQli dWZbc3NpZl9ibWMtPm1zZ19pZHggLSAxICsKKwkJCSAgICBzc2lmX2JtYy0+cmVxdWVzdC5sZW4g LSBzc2lmX2JtYy0+cmVjdl9sZW5dCT0gKnZhbDsKKwkJfQorCisJCXNzaWZfYm1jLT5tc2dfaWR4 Kys7CisKKwkJYnJlYWs7CisJZGVmYXVsdDoKKwkJLyogRG8gbm90IGV4cGVjdCB0byBnbyB0byB0 aGlzIGNhc2UgKi8KKwkJZGV2X2Vycigmc3NpZl9ibWMtPmNsaWVudC0+ZGV2LAorCQkJIiVzOiBV bmV4cGVjdGVkIFNNQnVzIGNvbW1hbmQgMHgleCwgYWJvcnRpbmcgLi4uXG4iLAorCQkJX19mdW5j X18sIHNzaWZfYm1jLT5zbWJ1c19jbWQpOworCQlzc2lmX2JtYy0+YWJvcnRpbmcgPSB0cnVlOwor CQlicmVhazsKKwl9Cit9CisKK3N0YXRpYyBib29sIHZhbGlkYXRlX3JlcXVlc3Qoc3RydWN0IHNz aWZfYm1jX2N0eCAqc3NpZl9ibWMpCit7CisJdTggcnBlYyA9IDAsIGNwZWMgPSAwOworCWJvb2wg cmV0ID0gdHJ1ZTsKKwl1OCBhZGRyLCBpbmRleDsKKwl1OCAqYnVmOworCisJYnVmID0gKHU4ICop JnNzaWZfYm1jLT5yZXF1ZXN0OworCXN3aXRjaCAoc3NpZl9ibWMtPnNtYnVzX2NtZCkgeworCWNh c2UgU1NJRl9JUE1JX1NJTkdMRVBBUlRfV1JJVEU6CisJCWlmICgoc3NpZl9ibWMtPm1zZ19pZHgg LSAxKSA9PSBzc2lmX21zZ19sZW4oJnNzaWZfYm1jLT5yZXF1ZXN0KSkgeworCQkJLyogUEVDIGlz IG5vdCBpbmNsdWRlZCAqLworCQkJc3NpZl9ibWMtPnBlY19zdXBwb3J0ID0gZmFsc2U7CisJCQly ZXQgPSB0cnVlOworCQkJZ290byBleGl0OworCQl9CisKKwkJaWYgKChzc2lmX2JtYy0+bXNnX2lk eCAtIDEpICE9IChzc2lmX21zZ19sZW4oJnNzaWZfYm1jLT5yZXF1ZXN0KSArIDEpKSB7CisJCQlk ZXZfZXJyKCZzc2lmX2JtYy0+Y2xpZW50LT5kZXYsICJFcnJvcjogVW5leHBlY3RlZCBsZW5ndGgg cmVjZWl2ZWQgJWRcbiIsCisJCQkJc3NpZl9tc2dfbGVuKCZzc2lmX2JtYy0+cmVxdWVzdCkpOwor CQkJcmV0ID0gZmFsc2U7CisJCQlnb3RvIGV4aXQ7CisJCX0KKworCQkvKiBQRUMgaXMgaW5jbHVk ZWQgKi8KKwkJc3NpZl9ibWMtPnBlY19zdXBwb3J0ID0gdHJ1ZTsKKwkJcnBlYyA9IGJ1Zltzc2lm X2JtYy0+bXNnX2lkeCAtIDJdOworCQlhZGRyID0gR0VUXzhCSVRfQUREUihzc2lmX2JtYy0+Y2xp ZW50LT5hZGRyKTsKKwkJY3BlYyA9IGkyY19zbWJ1c19wZWMoY3BlYywgJmFkZHIsIDEpOworCQlj cGVjID0gaTJjX3NtYnVzX3BlYyhjcGVjLCAmc3NpZl9ibWMtPnNtYnVzX2NtZCwgMSk7CisJCWNw ZWMgPSBpMmNfc21idXNfcGVjKGNwZWMsIGJ1Ziwgc3NpZl9tc2dfbGVuKCZzc2lmX2JtYy0+cmVx dWVzdCkpOworCQlpZiAocnBlYyAhPSBjcGVjKSB7CisJCQlkZXZfZXJyKCZzc2lmX2JtYy0+Y2xp ZW50LT5kZXYsICJCYWQgUEVDIDB4JTAyeCB2cy4gMHglMDJ4XG4iLCBycGVjLCBjcGVjKTsKKwkJ CXJldCA9IGZhbHNlOworCQl9CisKKwkJYnJlYWs7CisJY2FzZSBTU0lGX0lQTUlfTVVMVElQQVJU X1dSSVRFX1NUQVJUOgorCWNhc2UgU1NJRl9JUE1JX01VTFRJUEFSVF9XUklURV9NSURETEU6CisJ Y2FzZSBTU0lGX0lQTUlfTVVMVElQQVJUX1dSSVRFX0VORDoKKwkJaW5kZXggPSBzc2lmX2JtYy0+ cmVxdWVzdC5sZW4gLSBzc2lmX2JtYy0+cmVjdl9sZW47CisJCWlmICgoc3NpZl9ibWMtPm1zZ19p ZHggLSAxICsgaW5kZXgpID09IHNzaWZfbXNnX2xlbigmc3NpZl9ibWMtPnJlcXVlc3QpKSB7CisJ CQkvKiBQRUMgaXMgbm90IGluY2x1ZGVkICovCisJCQlzc2lmX2JtYy0+cGVjX3N1cHBvcnQgPSBm YWxzZTsKKwkJCXJldCA9IHRydWU7CisJCQlnb3RvIGV4aXQ7CisJCX0KKworCQlpZiAoKHNzaWZf Ym1jLT5tc2dfaWR4IC0gMSArIGluZGV4KSAhPSAoc3NpZl9tc2dfbGVuKCZzc2lmX2JtYy0+cmVx dWVzdCkgKyAxKSkgeworCQkJZGV2X2Vycigmc3NpZl9ibWMtPmNsaWVudC0+ZGV2LCAiRXJyb3I6 IFVuZXhwZWN0ZWQgbGVuZ3RoIHJlY2VpdmVkICVkXG4iLAorCQkJCXNzaWZfbXNnX2xlbigmc3Np Zl9ibWMtPnJlcXVlc3QpKTsKKwkJCXJldCA9IGZhbHNlOworCQkJZ290byBleGl0OworCQl9CisK KwkJLyogUEVDIGlzIGluY2x1ZGVkICovCisJCXNzaWZfYm1jLT5wZWNfc3VwcG9ydCA9IHRydWU7 CisJCXJwZWMgPSBidWZbc3NpZl9ibWMtPm1zZ19pZHggLSAyICsgaW5kZXhdOworCQlhZGRyID0g R0VUXzhCSVRfQUREUihzc2lmX2JtYy0+Y2xpZW50LT5hZGRyKTsKKwkJY3BlYyA9IGkyY19zbWJ1 c19wZWMoY3BlYywgJmFkZHIsIDEpOworCQljcGVjID0gaTJjX3NtYnVzX3BlYyhjcGVjLCAmc3Np Zl9ibWMtPnNtYnVzX2NtZCwgMSk7CisJCWNwZWMgPSBpMmNfc21idXNfcGVjKGNwZWMsICZzc2lm X2JtYy0+cmVjdl9sZW4sIDEpOworCQkvKiBBcyBTTUJ1cyBzcGVjaWZpY2F0aW9uIGRvZXMgbm90 IGFsbG93IHRoZSBsZW5ndGgKKwkJICogKGJ5dGUgY291bnQpIGluIHRoZSBXcml0ZS1CbG9jayBw cm90b2NvbCB0byBiZSB6ZXJvLgorCQkgKiBUaGVyZWZvcmUsIGl0IGlzIGlsbGVnYWwgdG8gaGF2 ZSB0aGUgbGFzdCBNaWRkbGUKKwkJICogdHJhbnNhY3Rpb24gaW4gdGhlIHNlcXVlbmNlIGNhcnJ5 IDMyLWJ5dGUgYW5kIGhhdmUKKwkJICogYSBsZW5ndGggb2Yg4oCYMOKAmSBpbiB0aGUgRW5kIHRy YW5zYWN0aW9uLgorCQkgKiBCdXQgc29tZSB1c2VycyBtYXkgdHJ5IHRvIHVzZSB0aGlzIHdheSBh bmQgd2Ugc2hvdWxkCisJCSAqIHByZXZlbnQgc3NpZl9ibWMgZHJpdmVyIGJyb2tlbiBpbiB0aGlz IGNhc2UuCisJCSAqLworCQlpZiAoc3NpZl9ibWMtPnJlY3ZfbGVuICE9IDApCisJCQljcGVjID0g aTJjX3NtYnVzX3BlYyhjcGVjLCBidWYgKyAxICsgaW5kZXgsIHNzaWZfYm1jLT5yZWN2X2xlbik7 CisKKwkJaWYgKHJwZWMgIT0gY3BlYykgeworCQkJZGV2X2Vycigmc3NpZl9ibWMtPmNsaWVudC0+ ZGV2LCAiQmFkIFBFQyAweCUwMnggdnMuIDB4JTAyeFxuIiwgcnBlYywgY3BlYyk7CisJCQlyZXQg PSBmYWxzZTsKKwkJfQorCisJCWJyZWFrOworCWRlZmF1bHQ6CisJCS8qIERvIG5vdCBleHBlY3Qg dG8gZ28gdG8gdGhpcyBjYXNlICovCisJCWRldl9lcnIoJnNzaWZfYm1jLT5jbGllbnQtPmRldiwg IiVzOiBVbmV4cGVjdGVkIFNNQnVzIGNvbW1hbmQgMHgleCwgYWJvcnRpbmcgLi4uXG4iLAorCQkJ X19mdW5jX18sIHNzaWZfYm1jLT5zbWJ1c19jbWQpOworCQlyZXQgPSBmYWxzZTsKKwkJYnJlYWs7 CisJfQorCitleGl0OgorCXJldHVybiByZXQ7Cit9CisKK3N0YXRpYyBib29sIHVuc3VwcG9ydGVk X3NtYnVzX2NtZCh1OCBjbWQpCit7CisJaWYgKGNtZCA9PSBTU0lGX0lQTUlfU0lOR0xFUEFSVF9S RUFEIHx8CisJICAgIGNtZCA9PSBTU0lGX0lQTUlfU0lOR0xFUEFSVF9XUklURSB8fAorCSAgICBj bWQgPT0gU1NJRl9JUE1JX01VTFRJUEFSVF9XUklURV9TVEFSVCB8fAorCSAgICBjbWQgPT0gU1NJ Rl9JUE1JX01VTFRJUEFSVF9XUklURV9NSURETEUgfHwKKwkgICAgY21kID09IFNTSUZfSVBNSV9N VUxUSVBBUlRfV1JJVEVfRU5EIHx8CisJICAgIGNtZCA9PSBTU0lGX0lQTUlfTVVMVElQQVJUX1JF QURfU1RBUlQgfHwKKwkgICAgY21kID09IFNTSUZfSVBNSV9NVUxUSVBBUlRfUkVBRF9NSURETEUp CisJCXJldHVybiBmYWxzZTsKKworCXJldHVybiB0cnVlOworfQorCitzdGF0aWMgdm9pZCBwcm9j ZXNzX3NtYnVzX2NtZChzdHJ1Y3Qgc3NpZl9ibWNfY3R4ICpzc2lmX2JtYywgdTggKnZhbCkKK3sK KwkvKiBTTUJVUyBjb21tYW5kIGNhbiB2YXJ5IChzaW5nbGUgb3IgbXVsdGktcGFydCkgKi8KKwlz c2lmX2JtYy0+c21idXNfY21kID0gKnZhbDsKKwlzc2lmX2JtYy0+bXNnX2lkeCsrOworCisJaWYg KHVuc3VwcG9ydGVkX3NtYnVzX2NtZCgqdmFsKSkgeworCQlkZXZfd2Fybigmc3NpZl9ibWMtPmNs aWVudC0+ZGV2LCAiV2FybjogVW5rbm93biBTTUJ1cyBjb21tYW5kLCBhYm9ydGluZyAuLi4iKTsK KwkJc3NpZl9ibWMtPmFib3J0aW5nID0gdHJ1ZTsKKwl9IGVsc2UgaWYgKHNzaWZfYm1jLT5hYm9y dGluZyAmJgorCQkgICAoKnZhbCA9PSBTU0lGX0lQTUlfU0lOR0xFUEFSVF9XUklURSB8fAorCQkg ICAgKnZhbCA9PSBTU0lGX0lQTUlfTVVMVElQQVJUX1dSSVRFX1NUQVJUKSkgeworCQkvKiBOZXcg cmVxdWVzdCAqLworCQlkZXZfd2Fybigmc3NpZl9ibWMtPmNsaWVudC0+ZGV2LCAiV2FybjogTmV3 IHJlcXVlc3QgZm91bmQsIHN0b3AgYWJvcnRpbmcgLi4uIik7CisJCXNzaWZfYm1jLT5hYm9ydGlu ZyA9IGZhbHNlOworCX0KK30KKworc3RhdGljIHZvaWQgb25fcmVhZF9yZXF1ZXN0ZWRfZXZlbnQo c3RydWN0IHNzaWZfYm1jX2N0eCAqc3NpZl9ibWMsIHU4ICp2YWwpCit7CisJaWYgKHNzaWZfYm1j LT5zdGF0ZSA9PSBTU0lGX1JFQURZIHx8CisJICAgIHNzaWZfYm1jLT5zdGF0ZSA9PSBTU0lGX1NU QVJUIHx8CisJICAgIHNzaWZfYm1jLT5zdGF0ZSA9PSBTU0lGX1JFUV9SRUNWSU5HIHx8CisJICAg IHNzaWZfYm1jLT5zdGF0ZSA9PSBTU0lGX1JFU19TRU5ESU5HKSB7CisJCXNzaWZfYm1jLT5zdGF0 ZSA9IFNTSUZfQkFEX1NNQlVTOworCQlkZXZfd2Fybigmc3NpZl9ibWMtPmNsaWVudC0+ZGV2LAor CQkJICJXYXJuOiAlcyB1bmV4cGVjdGVkIFJFQUQgUkVRVUVTVEVEIGluIHN0YXRlPSVzLCBhYm9y dGluZyAuLi5cbiIsCisJCQkgX19mdW5jX18sIHN0YXRlX3RvX3N0cmluZyhzc2lmX2JtYy0+c3Rh dGUpKTsKKwkJc3NpZl9ibWMtPmFib3J0aW5nID0gdHJ1ZTsKKworCX0gZWxzZSBpZiAoc3NpZl9i bWMtPnN0YXRlID09IFNTSUZfU01CVVNfQ01EKSB7CisJCXNzaWZfYm1jLT5zdGF0ZSA9IFNTSUZf UkVTX1NFTkRJTkc7CisJfQorCisJaWYgKHNzaWZfYm1jLT5hYm9ydGluZyB8fCBzc2lmX2JtYy0+ c3RhdGUgIT0gU1NJRl9SRVNfU0VORElORykgeworCQkvKiBBYm9ydCBieSByZXR1cm5pbmcgdGhl IGxhc3QgcmVxdWVzdCB3aXRoIDB4RkYgYXMgY29tcGxldGlvbiBjb2RlICovCisJCXNzaWZfYm1j LT5pc19zaW5nbGVwYXJ0X3JlYWQgPSB0cnVlOworCQlzc2lmX2JtYy0+cmVzcG9uc2UubGVuID0g MHgwMzsKKwkJc3NpZl9ibWMtPnJlc3BvbnNlLm5ldGZuX2x1biA9IHNzaWZfYm1jLT5yZXF1ZXN0 Lm5ldGZuX2x1biB8IDQ7CisJCXNzaWZfYm1jLT5yZXNwb25zZS5jbWQgPSBzc2lmX2JtYy0+cmVx dWVzdC5jbWQ7CisJCW1lbXNldCgmc3NpZl9ibWMtPnJlc3BvbnNlLnBheWxvYWRbMF0sIDB4RkYs IE1BWF9QQVlMT0FEX1BFUl9UUkFOU0FDVElPTik7CisJfQorCisJc3NpZl9ibWMtPm1zZ19pZHgg PSAwOworCWlmIChzc2lmX2JtYy0+aXNfc2luZ2xlcGFydF9yZWFkKQorCQkqdmFsID0gc3NpZl9i bWMtPnJlc3BvbnNlLmxlbjsKKwllbHNlCisJCXNldF9tdWx0aXBhcnRfcmVzcG9uc2VfYnVmZmVy KHNzaWZfYm1jLCB2YWwpOworfQorCitzdGF0aWMgdm9pZCBvbl9yZWFkX3Byb2Nlc3NlZF9ldmVu dChzdHJ1Y3Qgc3NpZl9ibWNfY3R4ICpzc2lmX2JtYywgdTggKnZhbCkKK3sKKwlpZiAoc3NpZl9i bWMtPnN0YXRlID09IFNTSUZfUkVBRFkgfHwKKwkgICAgc3NpZl9ibWMtPnN0YXRlID09IFNTSUZf U1RBUlQgfHwKKwkgICAgc3NpZl9ibWMtPnN0YXRlID09IFNTSUZfUkVRX1JFQ1ZJTkcgfHwKKwkg ICAgc3NpZl9ibWMtPnN0YXRlID09IFNTSUZfU01CVVNfQ01EKSB7CisJCWRldl93YXJuKCZzc2lm X2JtYy0+Y2xpZW50LT5kZXYsCisJCQkgIldhcm46ICVzIHVuZXhwZWN0ZWQgUkVBRCBQUk9DRVNT RUQgaW4gc3RhdGU9JXNcbiIsCisJCQkgX19mdW5jX18sIHN0YXRlX3RvX3N0cmluZyhzc2lmX2Jt Yy0+c3RhdGUpKTsKKwkJc3NpZl9ibWMtPnN0YXRlID0gU1NJRl9CQURfU01CVVM7CisJfQorCisJ aGFuZGxlX3JlYWRfcHJvY2Vzc2VkKHNzaWZfYm1jLCB2YWwpOworfQorCitzdGF0aWMgdm9pZCBv bl93cml0ZV9yZXF1ZXN0ZWRfZXZlbnQoc3RydWN0IHNzaWZfYm1jX2N0eCAqc3NpZl9ibWMsIHU4 ICp2YWwpCit7CisJc3NpZl9ibWMtPm1zZ19pZHggPSAwOworCisJaWYgKHNzaWZfYm1jLT5zdGF0 ZSA9PSBTU0lGX1JFQURZIHx8IHNzaWZfYm1jLT5zdGF0ZSA9PSBTU0lGX1NNQlVTX0NNRCkgewor CQlzc2lmX2JtYy0+c3RhdGUgPSBTU0lGX1NUQVJUOworCisJfSBlbHNlIGlmIChzc2lmX2JtYy0+ c3RhdGUgPT0gU1NJRl9TVEFSVCB8fAorCQkgICBzc2lmX2JtYy0+c3RhdGUgPT0gU1NJRl9SRVFf UkVDVklORyB8fAorCQkgICBzc2lmX2JtYy0+c3RhdGUgPT0gU1NJRl9SRVNfU0VORElORykgewor CQlkZXZfd2Fybigmc3NpZl9ibWMtPmNsaWVudC0+ZGV2LAorCQkJICJXYXJuOiAlcyB1bmV4cGVj dGVkIFdSSVRFIFJFUVVFU1QgaW4gc3RhdGU9JXNcbiIsCisJCQkgX19mdW5jX18sIHN0YXRlX3Rv X3N0cmluZyhzc2lmX2JtYy0+c3RhdGUpKTsKKwkJc3NpZl9ibWMtPnN0YXRlID0gU1NJRl9CQURf U01CVVM7CisJfQorfQorCitzdGF0aWMgdm9pZCBvbl93cml0ZV9yZWNlaXZlZF9ldmVudChzdHJ1 Y3Qgc3NpZl9ibWNfY3R4ICpzc2lmX2JtYywgdTggKnZhbCkKK3sKKwlpZiAoc3NpZl9ibWMtPnN0 YXRlID09IFNTSUZfUkVBRFkgfHwgc3NpZl9ibWMtPnN0YXRlID09IFNTSUZfUkVTX1NFTkRJTkcp IHsKKwkJZGV2X3dhcm4oJnNzaWZfYm1jLT5jbGllbnQtPmRldiwKKwkJCSAiV2FybjogJXMgdW5l eHBlY3RlZCBXUklURSBSRUNFSVZFRCBpbiBzdGF0ZT0lc1xuIiwKKwkJCSBfX2Z1bmNfXywgc3Rh dGVfdG9fc3RyaW5nKHNzaWZfYm1jLT5zdGF0ZSkpOworCQlzc2lmX2JtYy0+c3RhdGUgPSBTU0lG X0JBRF9TTUJVUzsKKwl9IGVsc2UgaWYgKHNzaWZfYm1jLT5zdGF0ZSA9PSBTU0lGX1NUQVJUKSB7 CisJCXNzaWZfYm1jLT5zdGF0ZSA9IFNTSUZfU01CVVNfQ01EOworCX0gZWxzZSBpZiAoc3NpZl9i bWMtPnN0YXRlID09IFNTSUZfU01CVVNfQ01EKSB7CisJCXNzaWZfYm1jLT5zdGF0ZSA9IFNTSUZf UkVRX1JFQ1ZJTkc7CisJfQorCisJLyogVGhpcyBpcyByZXNwb25zZSBzZW5kaW5nIHN0YXRlICov CisJaWYgKHNzaWZfYm1jLT5zdGF0ZSA9PSBTU0lGX1JFUV9SRUNWSU5HKSB7CisJCWlmIChzc2lm X2JtYy0+cmVzcG9uc2VfaW5fcHJvZ3Jlc3MpIHsKKwkJCS8qCisJCQkgKiBBcyBwZXIgc3BlYywg aXQgaXMgZ2VuZXJpYyBtYW5hZ2VtZW50IHNvZnR3YXJlIG9yIFNTSUYgZHJpdmVycyB0byB0YWtl CisJCQkgKiBjYXJlIG9mIGlzc3VpbmcgbmV3IHJlcXVlc3QgYmVmb3JlIHRoZSBwcmlvciByZXF1 ZXN0cyBjb21wbGV0ZWQuCisJCQkgKiBTbyBqdXN0IGFib3J0IGV2ZXJ5dGhpbmcgaGVyZSBhbmQg d2FpdCBmb3IgbmV4dCBuZXcgcmVxdWVzdAorCQkJICovCisJCQlkZXZfd2Fybigmc3NpZl9ibWMt PmNsaWVudC0+ZGV2LAorCQkJCSAiV2FybjogU1NJRiBuZXcgcmVxdWVzdCB3aXRoIHBlbmRpbmcg cmVzcG9uc2UsIGFib3J0aW5nIC4uLiIpOworCQkJc3NpZl9ibWMtPmFib3J0aW5nID0gdHJ1ZTsK KwkJCWNvbXBsZXRlX3Jlc3BvbnNlKHNzaWZfYm1jKTsKKwkJfQorCisJCWhhbmRsZV93cml0ZV9y ZWNlaXZlZChzc2lmX2JtYywgdmFsKTsKKwl9IGVsc2UgaWYgKHNzaWZfYm1jLT5zdGF0ZSA9PSBT U0lGX1NNQlVTX0NNRCkgeworCQlwcm9jZXNzX3NtYnVzX2NtZChzc2lmX2JtYywgdmFsKTsKKwl9 Cit9CisKK3N0YXRpYyB2b2lkIG9uX3N0b3BfZXZlbnQoc3RydWN0IHNzaWZfYm1jX2N0eCAqc3Np Zl9ibWMsIHU4ICp2YWwpCit7CisJaWYgKHNzaWZfYm1jLT5zdGF0ZSA9PSBTU0lGX1JFQURZIHx8 CisJICAgIHNzaWZfYm1jLT5zdGF0ZSA9PSBTU0lGX1NUQVJUIHx8CisJICAgIHNzaWZfYm1jLT5z dGF0ZSA9PSBTU0lGX1NNQlVTX0NNRCkgeworCQlkZXZfd2Fybigmc3NpZl9ibWMtPmNsaWVudC0+ ZGV2LAorCQkJICJXYXJuOiAlcyB1bmV4cGVjdGVkIFNMQVZFIFNUT1AgaW4gc3RhdGU9JXNcbiIs CisJCQkgX19mdW5jX18sIHN0YXRlX3RvX3N0cmluZyhzc2lmX2JtYy0+c3RhdGUpKTsKKworCX0g ZWxzZSBpZiAoc3NpZl9ibWMtPnN0YXRlID09IFNTSUZfQkFEX1NNQlVTKSB7CisJCWRldl93YXJu KCZzc2lmX2JtYy0+Y2xpZW50LT5kZXYsCisJCQkgIldhcm46ICVzIHJlY2VpdmVkIFNMQVZFIFNU T1AgZnJvbSBiYWQgc3RhdGU9JXNcbiIsCisJCQkgX19mdW5jX18sIHN0YXRlX3RvX3N0cmluZyhz c2lmX2JtYy0+c3RhdGUpKTsKKworCX0gZWxzZSBpZiAoc3NpZl9ibWMtPnN0YXRlID09IFNTSUZf UkVRX1JFQ1ZJTkcpIHsKKwkJLyogQSBCTUMgdGhhdCByZWNlaXZlcyBhbiBpbnZhbGlkIHJlcXVl c3QgZHJvcCB0aGUgZGF0YSBmb3IgdGhlIHdyaXRlCisJCSAqIHRyYW5zYWN0aW9uIGFuZCBhbnkg ZnVydGhlciB0cmFuc2FjdGlvbnMgKHJlYWQgb3Igd3JpdGUpIHVudGlsCisJCSAqIHRoZSBuZXh0 IHZhbGlkIHJlYWQgb3Igd3JpdGUgU3RhcnQgdHJhbnNhY3Rpb24gaXMgcmVjZWl2ZWQKKwkJICov CisJCWlmICghdmFsaWRhdGVfcmVxdWVzdChzc2lmX2JtYykpCisJCQlzc2lmX2JtYy0+YWJvcnRp bmcgPSB0cnVlOworCisJCWlmICghc3NpZl9ibWMtPmFib3J0aW5nICYmCisJCSAgICAoc3NpZl9i bWMtPnNtYnVzX2NtZCA9PSBTU0lGX0lQTUlfU0lOR0xFUEFSVF9XUklURSB8fAorCQkgICAgIHNz aWZfYm1jLT5zbWJ1c19jbWQgPT0gU1NJRl9JUE1JX01VTFRJUEFSVF9XUklURV9FTkQpKQorCQkJ aGFuZGxlX3JlcXVlc3Qoc3NpZl9ibWMpOworCX0KKworCXNzaWZfYm1jLT5zdGF0ZSA9IFNTSUZf UkVBRFk7CisJLyogUmVzZXQgbWVzc2FnZSBpbmRleCAqLworCXNzaWZfYm1jLT5tc2dfaWR4ID0g MDsKK30KKworLyoKKyAqIENhbGxiYWNrIGZ1bmN0aW9uIHRvIGhhbmRsZSBJMkMgc2xhdmUgZXZl bnRzCisgKi8KK3N0YXRpYyBpbnQgc3NpZl9ibWNfY2Ioc3RydWN0IGkyY19jbGllbnQgKmNsaWVu dCwgZW51bSBpMmNfc2xhdmVfZXZlbnQgZXZlbnQsIHU4ICp2YWwpCit7CisJdW5zaWduZWQgbG9u ZyBmbGFnczsKKwlzdHJ1Y3Qgc3NpZl9ibWNfY3R4ICpzc2lmX2JtYyA9IGkyY19nZXRfY2xpZW50 ZGF0YShjbGllbnQpOworCisJc3Bpbl9sb2NrX2lycXNhdmUoJnNzaWZfYm1jLT5sb2NrLCBmbGFn cyk7CisKKwlzd2l0Y2ggKGV2ZW50KSB7CisJY2FzZSBJMkNfU0xBVkVfUkVBRF9SRVFVRVNURUQ6 CisJCW9uX3JlYWRfcmVxdWVzdGVkX2V2ZW50KHNzaWZfYm1jLCB2YWwpOworCQlicmVhazsKKwor CWNhc2UgSTJDX1NMQVZFX1dSSVRFX1JFUVVFU1RFRDoKKwkJb25fd3JpdGVfcmVxdWVzdGVkX2V2 ZW50KHNzaWZfYm1jLCB2YWwpOworCQlicmVhazsKKworCWNhc2UgSTJDX1NMQVZFX1JFQURfUFJP Q0VTU0VEOgorCQlvbl9yZWFkX3Byb2Nlc3NlZF9ldmVudChzc2lmX2JtYywgdmFsKTsKKwkJYnJl YWs7CisKKwljYXNlIEkyQ19TTEFWRV9XUklURV9SRUNFSVZFRDoKKwkJb25fd3JpdGVfcmVjZWl2 ZWRfZXZlbnQoc3NpZl9ibWMsIHZhbCk7CisJCWJyZWFrOworCisJY2FzZSBJMkNfU0xBVkVfU1RP UDoKKwkJb25fc3RvcF9ldmVudChzc2lmX2JtYywgdmFsKTsKKwkJYnJlYWs7CisKKwlkZWZhdWx0 OgorCQlkZXZfd2Fybigmc3NpZl9ibWMtPmNsaWVudC0+ZGV2LCAiV2FybjogVW5rbm93biBpMmMg c2xhdmUgZXZlbnQsIGFib3J0aW5nIC4uLlxuIik7CisJCXNzaWZfYm1jLT5hYm9ydGluZyA9IHRy dWU7CisJCWJyZWFrOworCX0KKworCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJnNzaWZfYm1jLT5s b2NrLCBmbGFncyk7CisKKwlyZXR1cm4gMDsKK30KKworc3RhdGljIGludCBzc2lmX2JtY19wcm9i ZShzdHJ1Y3QgaTJjX2NsaWVudCAqY2xpZW50LCBjb25zdCBzdHJ1Y3QgaTJjX2RldmljZV9pZCAq aWQpCit7CisJc3RydWN0IHNzaWZfYm1jX2N0eCAqc3NpZl9ibWM7CisJaW50IHJldDsKKworCXNz aWZfYm1jID0gZGV2bV9remFsbG9jKCZjbGllbnQtPmRldiwgc2l6ZW9mKCpzc2lmX2JtYyksIEdG UF9LRVJORUwpOworCWlmICghc3NpZl9ibWMpCisJCXJldHVybiAtRU5PTUVNOworCisJc3Bpbl9s b2NrX2luaXQoJnNzaWZfYm1jLT5sb2NrKTsKKworCWluaXRfd2FpdHF1ZXVlX2hlYWQoJnNzaWZf Ym1jLT53YWl0X3F1ZXVlKTsKKwlzc2lmX2JtYy0+cmVxdWVzdF9hdmFpbGFibGUgPSBmYWxzZTsK Kwlzc2lmX2JtYy0+cmVzcG9uc2VfaW5fcHJvZ3Jlc3MgPSBmYWxzZTsKKworCS8qIFJlZ2lzdGVy IG1pc2MgZGV2aWNlIGludGVyZmFjZSAqLworCXNzaWZfYm1jLT5taXNjZGV2Lm1pbm9yID0gTUlT Q19EWU5BTUlDX01JTk9SOworCXNzaWZfYm1jLT5taXNjZGV2Lm5hbWUgPSBERVZJQ0VfTkFNRTsK Kwlzc2lmX2JtYy0+bWlzY2Rldi5mb3BzID0gJnNzaWZfYm1jX2ZvcHM7CisJc3NpZl9ibWMtPm1p c2NkZXYucGFyZW50ID0gJmNsaWVudC0+ZGV2OworCXJldCA9IG1pc2NfcmVnaXN0ZXIoJnNzaWZf Ym1jLT5taXNjZGV2KTsKKwlpZiAocmV0KQorCQlnb3RvIG91dDsKKworCXNzaWZfYm1jLT5jbGll bnQgPSBjbGllbnQ7CisJc3NpZl9ibWMtPmNsaWVudC0+ZmxhZ3MgfD0gSTJDX0NMSUVOVF9TTEFW RTsKKworCS8qIFJlZ2lzdGVyIEkyQyBzbGF2ZSAqLworCWkyY19zZXRfY2xpZW50ZGF0YShjbGll bnQsIHNzaWZfYm1jKTsKKwlyZXQgPSBpMmNfc2xhdmVfcmVnaXN0ZXIoY2xpZW50LCBzc2lmX2Jt Y19jYik7CisJaWYgKHJldCkgeworCQltaXNjX2RlcmVnaXN0ZXIoJnNzaWZfYm1jLT5taXNjZGV2 KTsKKwkJZ290byBvdXQ7CisJfQorCisJcmV0dXJuIDA7CitvdXQ6CisJZGV2bV9rZnJlZSgmY2xp ZW50LT5kZXYsIHNzaWZfYm1jKTsKKwlyZXR1cm4gcmV0OworfQorCitzdGF0aWMgaW50IHNzaWZf Ym1jX3JlbW92ZShzdHJ1Y3QgaTJjX2NsaWVudCAqY2xpZW50KQoreworCXN0cnVjdCBzc2lmX2Jt Y19jdHggKnNzaWZfYm1jID0gaTJjX2dldF9jbGllbnRkYXRhKGNsaWVudCk7CisKKwlpMmNfc2xh dmVfdW5yZWdpc3RlcihjbGllbnQpOworCW1pc2NfZGVyZWdpc3Rlcigmc3NpZl9ibWMtPm1pc2Nk ZXYpOworCisJcmV0dXJuIDA7Cit9CisKK3N0YXRpYyBjb25zdCBzdHJ1Y3Qgb2ZfZGV2aWNlX2lk IHNzaWZfYm1jX21hdGNoW10gPSB7CisJeyAuY29tcGF0aWJsZSA9ICJhbXBlcmUsc3NpZi1ibWMi IH0sCisJeyB9LAorfTsKKworc3RhdGljIGNvbnN0IHN0cnVjdCBpMmNfZGV2aWNlX2lkIHNzaWZf Ym1jX2lkW10gPSB7CisJeyBERVZJQ0VfTkFNRSwgMCB9LAorCXsgfSwKK307CisKK01PRFVMRV9E RVZJQ0VfVEFCTEUoaTJjLCBzc2lmX2JtY19pZCk7CisKK3N0YXRpYyBzdHJ1Y3QgaTJjX2RyaXZl ciBzc2lmX2JtY19kcml2ZXIgPSB7CisJLmRyaXZlciAgICAgICAgID0geworCQkubmFtZSAgICAg ICAgICAgPSBERVZJQ0VfTkFNRSwKKwkJLm9mX21hdGNoX3RhYmxlID0gc3NpZl9ibWNfbWF0Y2gs CisJfSwKKwkucHJvYmUgICAgICAgICAgPSBzc2lmX2JtY19wcm9iZSwKKwkucmVtb3ZlICAgICAg ICAgPSBzc2lmX2JtY19yZW1vdmUsCisJLmlkX3RhYmxlICAgICAgID0gc3NpZl9ibWNfaWQsCit9 OworCittb2R1bGVfaTJjX2RyaXZlcihzc2lmX2JtY19kcml2ZXIpOworCitNT0RVTEVfQVVUSE9S KCJRdWFuIE5ndXllbiA8cXVhbkBvcy5hbXBlcmVjb21wdXRpbmcuY29tPiIpOworTU9EVUxFX0FV VEhPUigiQ2h1b25nIFRyYW4gPGNodW9uZ0Bvcy5hbXBlcmVjb21wdXRpbmcuY29tPiIpOworTU9E VUxFX0RFU0NSSVBUSU9OKCJMaW51eCBkZXZpY2UgZHJpdmVyIG9mIHRoZSBCTUMgSVBNSSBTU0lG IGludGVyZmFjZS4iKTsKK01PRFVMRV9MSUNFTlNFKCJHUEwgdjIiKTsKZGlmZiAtLWdpdCBhL2Ry aXZlcnMvY2hhci9pcG1pL3NzaWZfYm1jLmggYi9kcml2ZXJzL2NoYXIvaXBtaS9zc2lmX2JtYy5o Cm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAwMDAwMC4uYjYzZTQwYTRiOTAwCi0t LSAvZGV2L251bGwKKysrIGIvZHJpdmVycy9jaGFyL2lwbWkvc3NpZl9ibWMuaApAQCAtMCwwICsx LDEwNiBAQAorLyogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEdQTC0yLjArICovCisvKgorICog VGhlIGRyaXZlciBmb3IgQk1DIHNpZGUgb2YgU1NJRiBpbnRlcmZhY2UKKyAqCisgKiBDb3B5cmln aHQgKGMpIDIwMjEsIEFtcGVyZSBDb21wdXRpbmcgTExDCisgKgorICogVGhpcyBwcm9ncmFtIGlz IGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vcgorICogbW9kaWZ5 IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMK KyAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIgdmVy c2lvbiAyIG9mCisgKiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIg dmVyc2lvbi4KKyAqCisgKiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUg dGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKKyAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0 aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCisgKiBNRVJDSEFOVEFCSUxJVFkgb3Ig RklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlCisgKiBHTlUgR2VuZXJh bCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgorICoKKyAqIFlvdSBzaG91bGQgaGF2 ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCisgKiBh bG9uZyB3aXRoIHRoaXMgcHJvZ3JhbS4gIElmIG5vdCwgc2VlIDxodHRwczovL3d3dy5nbnUub3Jn L2xpY2Vuc2VzLz4uCisgKi8KKyNpZm5kZWYgX19TU0lGX0JNQ19IX18KKyNkZWZpbmUgX19TU0lG X0JNQ19IX18KKworI2RlZmluZSBERVZJQ0VfTkFNRQkJCQkiaXBtaS1zc2lmLWhvc3QiCisKKyNk ZWZpbmUgR0VUXzhCSVRfQUREUihhZGRyXzdiaXQpCQkoKChhZGRyXzdiaXQpIDw8IDEpICYgMHhm ZikKKworLyogQSBzdGFuZGFyZCBTTUJ1cyBUcmFuc2FjdGlvbiBpcyBsaW1pdGVkIHRvIDMyIGRh dGEgYnl0ZXMgKi8KKyNkZWZpbmUgTUFYX1BBWUxPQURfUEVSX1RSQU5TQUNUSU9OCQkzMgorCisj ZGVmaW5lIE1BWF9JUE1JX0RBVEFfUEVSX1NUQVJUX1RSQU5TQUNUSU9OCTMwCisjZGVmaW5lIE1B WF9JUE1JX0RBVEFfUEVSX01JRERMRV9UUkFOU0FDVElPTgkzMQorCisjZGVmaW5lIFNTSUZfSVBN SV9TSU5HTEVQQVJUX1dSSVRFCQkweDIKKyNkZWZpbmUgU1NJRl9JUE1JX1NJTkdMRVBBUlRfUkVB RAkJMHgzCisjZGVmaW5lIFNTSUZfSVBNSV9NVUxUSVBBUlRfV1JJVEVfU1RBUlQJCTB4NgorI2Rl ZmluZSBTU0lGX0lQTUlfTVVMVElQQVJUX1dSSVRFX01JRERMRQkweDcKKyNkZWZpbmUgU1NJRl9J UE1JX01VTFRJUEFSVF9XUklURV9FTkQJCTB4OAorI2RlZmluZSBTU0lGX0lQTUlfTVVMVElQQVJU X1JFQURfU1RBUlQJCTB4MworI2RlZmluZSBTU0lGX0lQTUlfTVVMVElQQVJUX1JFQURfTUlERExF CQkweDkKKworI2RlZmluZSBNU0dfUEFZTE9BRF9MRU5fTUFYCQkJMjUyCisKK3N0cnVjdCBzc2lm X21zZyB7CisJdTggbGVuOworCXU4IG5ldGZuX2x1bjsKKwl1OCBjbWQ7CisJdTggcGF5bG9hZFtN U0dfUEFZTE9BRF9MRU5fTUFYXTsKK30gX19wYWNrZWQ7CisKK3N0YXRpYyBpbmxpbmUgdTMyIHNz aWZfbXNnX2xlbihzdHJ1Y3Qgc3NpZl9tc2cgKnNzaWZfbXNnKQoreworCXJldHVybiBzc2lmX21z Zy0+bGVuICsgMTsKK30KKworLyoKKyAqIFNTSUYgaW50ZXJuYWwgc3RhdGVzOgorICogICBTU0lG X1JFQURZICAgICAgICAgMHgwMCA6IFJlYWR5IHN0YXRlCisgKiAgIFNTSUZfU1RBUlQgICAgICAg ICAweDAxIDogU3RhcnQgc21idXMgdHJhbnNhY3Rpb24KKyAqICAgU1NJRl9TTUJVU19DTUQgICAg IDB4MDIgOiBSZWNlaXZlZCBTTUJ1cyBjb21tYW5kCisgKiAgIFNTSUZfUkVRX1JFQ1ZJTkcgICAw eDAzIDogUmVjZWl2aW5nIHJlcXVlc3QKKyAqICAgU1NJRl9SRVNfU0VORElORyAgIDB4MDQgOiBT ZW5kaW5nIHJlc3BvbnNlCisgKiAgIFNTSUZfQkFEX1NNQlVTICAgICAweDA1IDogQmFkIFNNYnVz IHRyYW5zYWN0aW9uCisgKi8KK2VudW0gc3NpZl9zdGF0ZSB7CisJU1NJRl9SRUFEWSwKKwlTU0lG X1NUQVJULAorCVNTSUZfU01CVVNfQ01ELAorCVNTSUZfUkVRX1JFQ1ZJTkcsCisJU1NJRl9SRVNf U0VORElORywKKwlTU0lGX0JBRF9TTUJVUywKKwlTU0lGX1NUQVRFX01BWAorfTsKKworc3RydWN0 IHNzaWZfYm1jX2N0eCB7CisJc3RydWN0IGkyY19jbGllbnQJKmNsaWVudDsKKwlzdHJ1Y3QgbWlz Y2RldmljZQltaXNjZGV2OworCXNpemVfdAkJCW1zZ19pZHg7CisJYm9vbAkJCXBlY19zdXBwb3J0 OworCS8qIHNzaWYgYm1jIHNwaW5sb2NrICovCisJc3BpbmxvY2tfdAkJbG9jazsKKwl3YWl0X3F1 ZXVlX2hlYWRfdAl3YWl0X3F1ZXVlOworCXU4CQkJcnVubmluZzsKKwllbnVtIHNzaWZfc3RhdGUJ CXN0YXRlOworCXU4CQkJc21idXNfY21kOworCS8qIEZsYWcgdG8gYWJvcnQgY3VycmVudCBwcm9j ZXNzICovCisJYm9vbAkJCWFib3J0aW5nOworCS8qIEZsYWcgdG8gaWRlbnRpZnkgYSBNdWx0aS1w YXJ0IFJlYWQgVHJhbnNhY3Rpb24gKi8KKwlib29sCQkJaXNfc2luZ2xlcGFydF9yZWFkOworCXU4 CQkJbmJ5dGVzX3Byb2Nlc3NlZDsKKwl1OAkJCXJlbWFpbl9sZW47CisJdTgJCQlyZWN2X2xlbjsK KwkvKiBCbG9jayBOdW1iZXIgb2YgYSBNdWx0aS1wYXJ0IFJlYWQgVHJhbnNhY3Rpb24gKi8KKwl1 OAkJCWJsb2NrX251bTsKKwlib29sCQkJcmVxdWVzdF9hdmFpbGFibGU7CisJYm9vbAkJCXJlc3Bv bnNlX2luX3Byb2dyZXNzOworCS8qIFJlc3BvbnNlIGJ1ZmZlciBmb3IgTXVsdGktcGFydCBSZWFk IFRyYW5zYWN0aW9uICovCisJdTgJCQlyZXNwb25zZV9idWZbTUFYX1BBWUxPQURfUEVSX1RSQU5T QUNUSU9OXTsKKwlzdHJ1Y3Qgc3NpZl9tc2cJCXJlc3BvbnNlOworCXN0cnVjdCBzc2lmX21zZwkJ cmVxdWVzdDsKK307CisKK3N0YXRpYyBpbmxpbmUgc3RydWN0IHNzaWZfYm1jX2N0eCAqdG9fc3Np Zl9ibWMoc3RydWN0IGZpbGUgKmZpbGUpCit7CisJcmV0dXJuIGNvbnRhaW5lcl9vZihmaWxlLT5w cml2YXRlX2RhdGEsIHN0cnVjdCBzc2lmX2JtY19jdHgsIG1pc2NkZXYpOworfQorI2VuZGlmIC8q IF9fU1NJRl9CTUNfSF9fICovCi0tIAoyLjI4LjAKCgpfX19fX19fX19fX19fX19fX19fX19fX19f X19fX19fX19fX19fX19fX19fX19fXwpsaW51eC1hcm0ta2VybmVsIG1haWxpbmcgbGlzdApsaW51 eC1hcm0ta2VybmVsQGxpc3RzLmluZnJhZGVhZC5vcmcKaHR0cDovL2xpc3RzLmluZnJhZGVhZC5v cmcvbWFpbG1hbi9saXN0aW5mby9saW51eC1hcm0ta2VybmVsCg==