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 Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 801EBC636D6 for ; Fri, 17 Feb 2023 16:44:16 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229685AbjBQQmh (ORCPT ); Fri, 17 Feb 2023 11:42:37 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53222 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230411AbjBQQlG (ORCPT ); Fri, 17 Feb 2023 11:41:06 -0500 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3C9167293C; Fri, 17 Feb 2023 08:40:57 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id AF68161F09; Fri, 17 Feb 2023 16:40:56 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 8475BC43444; Fri, 17 Feb 2023 16:40:53 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1676652056; bh=Ada5YJvntQNNf8mjai4BiBi5laL09boYhqgifAggSQ8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=oH++hjwqroHKIFxmF/HnsnxHUNBefUvOtOzGRWfyjk3g5O5C4HlXvlQqMjfF4mTtj MNIO3uV96d+6WmPTPJAuEjACZny2Q0P71ip5tuOusdjaO15DsfvSVO30mKv/iGyptl x4oK5StKhzqmaDlFnhtJ/6mLdFfotB5NAKiLI5qhj4oMEAlsDN8/Ma7ckgfLSI9LkR O3C1EzNtg6f6kZXUqnkilmrARmc312ZaryiS4cIQhbaRYTvwUV2IQ08keAmdjnFFBy oTJDX4Ci40ku7kp2I39uUsNuRhzNWOnyjqy4x1HScqJcHhdBZG/JQ1OPjD1H0Xgid0 XmZUqfnv+cG8Q== From: Conor Dooley To: Xu Yilun , conor@kernel.org Cc: Conor Dooley , Daire McNamara , Rob Herring , Krzysztof Kozlowski , Moritz Fischer , Wu Hao , Tom Rix , linux-riscv@lists.infradead.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-fpga@vger.kernel.org Subject: [PATCH v1 5/6] fpga: add PolarFire SoC Auto Update support Date: Fri, 17 Feb 2023 16:40:22 +0000 Message-Id: <20230217164023.14255-6-conor@kernel.org> X-Mailer: git-send-email 2.39.1 In-Reply-To: <20230217164023.14255-1-conor@kernel.org> References: <20230217164023.14255-1-conor@kernel.org> MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=18671; i=conor.dooley@microchip.com; h=from:subject; bh=5c9FyeDfJ+4rxNjXaNpKTn1QANdTH3UMNxq+UGzUyrc=; b=owGbwMvMwCFWscWwfUFT0iXG02pJDMnv175l+PRYZsXn5Ulb3itvSAu2UVC6qRv1bWL2lVv1RuvW 39hk0VHKwiDGwSArpsiSeLuvRWr9H5cdzj1vYeawMoEN4eIUgImwdzL8j1316fl8j+vp3VvUDy5y8u ud8Xh6Q6T2ki5LkYC6tJWdTowMW9dyu/abSShd2FJiZPnvnu31qbssdmaaBRafY7z1b8sDdgA= X-Developer-Key: i=conor.dooley@microchip.com; a=openpgp; fpr=F9ECA03CF54F12CD01F1655722E2C55B37CF380C Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-fpga@vger.kernel.org From: Conor Dooley Add support for Auto Update reprogramming of the FPGA fabric on PolarFire SoC. Signed-off-by: Conor Dooley --- drivers/fpga/Kconfig | 9 + drivers/fpga/Makefile | 1 + drivers/fpga/microchip-auto-update.c | 495 +++++++++++++++++++++++++++ 3 files changed, 505 insertions(+) create mode 100644 drivers/fpga/microchip-auto-update.c diff --git a/drivers/fpga/Kconfig b/drivers/fpga/Kconfig index 6ce143dafd04..0cdd6978a440 100644 --- a/drivers/fpga/Kconfig +++ b/drivers/fpga/Kconfig @@ -257,6 +257,15 @@ config FPGA_M10_BMC_SEC_UPDATE (BMC) and provides support for secure updates for the BMC image, the FPGA image, the Root Entry Hashes, etc. +config FPGA_MGR_MICROCHIP_AUTO_UPDATE + tristate "Microchip PolarFire SoC AUTO UPDATE" + depends on POLARFIRE_SOC_SYS_CTRL + help + FPGA manager driver support for reprogramming PolarFire SoC from + within Linux, using the Auto Upgrade feature of the system controller. + + If built as a module, it will be called microchip-auto-update. + config FPGA_MGR_MICROCHIP_SPI tristate "Microchip Polarfire SPI FPGA manager" depends on SPI diff --git a/drivers/fpga/Makefile b/drivers/fpga/Makefile index 72e554b4d2f7..a67903edf976 100644 --- a/drivers/fpga/Makefile +++ b/drivers/fpga/Makefile @@ -19,6 +19,7 @@ obj-$(CONFIG_FPGA_MGR_XILINX_SPI) += xilinx-spi.o obj-$(CONFIG_FPGA_MGR_ZYNQ_FPGA) += zynq-fpga.o obj-$(CONFIG_FPGA_MGR_ZYNQMP_FPGA) += zynqmp-fpga.o obj-$(CONFIG_FPGA_MGR_VERSAL_FPGA) += versal-fpga.o +obj-$(CONFIG_FPGA_MGR_MICROCHIP_AUTO_UPDATE) += microchip-auto-update.o obj-$(CONFIG_FPGA_MGR_MICROCHIP_SPI) += microchip-spi.o obj-$(CONFIG_FPGA_MGR_LATTICE_SYSCONFIG) += lattice-sysconfig.o obj-$(CONFIG_FPGA_MGR_LATTICE_SYSCONFIG_SPI) += lattice-sysconfig-spi.o diff --git a/drivers/fpga/microchip-auto-update.c b/drivers/fpga/microchip-auto-update.c new file mode 100644 index 000000000000..d90085f86b8b --- /dev/null +++ b/drivers/fpga/microchip-auto-update.c @@ -0,0 +1,495 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Microchip Polarfire SoC "Auto Update" FPGA reprogramming. + * + * Documentation of this functionality is available in the "PolarFire® FPGA and + * PolarFire SoC FPGA Programming" User Guide. + * + * Copyright (c) 2022-2023 Microchip Corporation. All rights reserved. + * + * Author: Conor Dooley + */ +#include +#include +#include +#include +#include +#include +#include + +#include + +#define AUTO_UPDATE_DEFAULT_MBOX_OFFSET 0u +#define AUTO_UPDATE_DEFAULT_RESP_OFFSET 0u + +#define AUTO_UPDATE_FEATURE_CMD_OPCODE 0x05u +#define AUTO_UPDATE_FEATURE_CMD_DATA_SIZE 0u +#define AUTO_UPDATE_FEATURE_RESP_SIZE 33u +#define AUTO_UPDATE_FEATURE_CMD_DATA NULL +#define AUTO_UPDATE_FEATURE_ENABLED BIT(5) + +#define AUTO_UPDATE_AUTHENTICATE_CMD_OPCODE 0x22u +#define AUTO_UPDATE_AUTHENTICATE_CMD_DATA_SIZE 0u +#define AUTO_UPDATE_AUTHENTICATE_RESP_SIZE 1u +#define AUTO_UPDATE_AUTHENTICATE_CMD_DATA NULL + +#define AUTO_UPDATE_PROGRAM_CMD_OPCODE 0x46u +#define AUTO_UPDATE_PROGRAM_CMD_DATA_SIZE 0u +#define AUTO_UPDATE_PROGRAM_RESP_SIZE 1u +#define AUTO_UPDATE_PROGRAM_CMD_DATA NULL + +/* + * SPI Flash layout example: + * |------------------------------| 0x0000000 + * | 1 KiB | + * | SPI "directories" | + * |------------------------------| 0x0000400 + * | 1 MiB | + * | Reserved area | + * | Used for bitstream info | + * |------------------------------| 0x0100400 + * | 20 MiB | + * | Golden Image | + * |------------------------------| 0x1500400 + * | 20 MiB | + * | Auto Upgrade Image | + * |------------------------------| 0x2900400 + * | 20 MiB | + * | Reserved for multi-image IAP | + * | Unused for Auto Upgrade | + * |------------------------------| 0x3D00400 + * | ? B | + * | Unused | + * |------------------------------| 0x? + */ +#define AUTO_UPDATE_DIRECTORY_BASE 0u +#define AUTO_UPDATE_DIRECTORY_WIDTH 4u +#define AUTO_UPDATE_GOLDEN_INDEX 0u +#define AUTO_UPDATE_UPGRADE_INDEX 1u +#define AUTO_UPDATE_BLANK_INDEX 2u +#define AUTO_UPDATE_GOLDEN_DIRECTORY (AUTO_UPDATE_DIRECTORY_WIDTH * AUTO_UPDATE_GOLDEN_INDEX) +#define AUTO_UPDATE_UPGRADE_DIRECTORY (AUTO_UPDATE_DIRECTORY_WIDTH * AUTO_UPDATE_UPGRADE_INDEX) +#define AUTO_UPDATE_BLANK_DIRECTORY (AUTO_UPDATE_DIRECTORY_WIDTH * AUTO_UPDATE_BLANK_INDEX) +#define AUTO_UPDATE_DIRECTORY_SIZE SZ_1K +#define AUTO_UPDATE_RESERVED_SIZE SZ_1M +#define AUTO_UPDATE_BITSTREAM_BASE (AUTO_UPDATE_DIRECTORY_SIZE + AUTO_UPDATE_RESERVED_SIZE) + +struct mpfs_auto_update_config { + u8 feature_response_size; +}; + +struct mpfs_auto_update_priv { + struct mpfs_sys_controller *sys_controller; + struct device *dev; + struct fpga_region *region; + struct mpfs_auto_update_config *config; + struct mtd_info *flash; + struct dentry *debugfs_dir; +}; + +static struct device *mpfs_auto_update_debug_dev; + +static enum fpga_mgr_states mpfs_auto_update_state(struct fpga_manager *mgr) +{ + struct mpfs_auto_update_priv *priv = mgr->priv; + struct mpfs_mss_response *response; + struct mpfs_mss_msg *message; + u32 *response_msg; + int ret; + enum fpga_mgr_states rc = FPGA_MGR_STATE_WRITE_INIT_ERR; + + response_msg = devm_kzalloc(priv->dev, AUTO_UPDATE_FEATURE_RESP_SIZE * sizeof(response_msg), + GFP_KERNEL); + if (!response_msg) + return FPGA_MGR_STATE_WRITE_INIT_ERR; + + response = devm_kzalloc(priv->dev, sizeof(struct mpfs_mss_response), GFP_KERNEL); + if (!response) { + rc = FPGA_MGR_STATE_WRITE_INIT_ERR; + goto free_response_msg; + } + + message = devm_kzalloc(priv->dev, sizeof(struct mpfs_mss_msg), GFP_KERNEL); + if (!message) { + rc = FPGA_MGR_STATE_WRITE_INIT_ERR; + goto free_response; + } + + /* + * To verify that Auto Update is possible, the "Query Security Service + * Request" is performed. Bit 5 of byte 1 is "UL_Auto Update" & if it is + * set, Auto Update is not possible. + * This service has no command data & does not overload mbox_offset. + * The size of the response varies between PolarFire & PolarFire SoC. + */ + response->resp_msg = response_msg; + response->resp_size = AUTO_UPDATE_FEATURE_RESP_SIZE; + message->cmd_opcode = AUTO_UPDATE_FEATURE_CMD_OPCODE; + message->cmd_data_size = AUTO_UPDATE_FEATURE_CMD_DATA_SIZE; + message->response = response; + message->cmd_data = AUTO_UPDATE_FEATURE_CMD_DATA; + message->mbox_offset = AUTO_UPDATE_DEFAULT_MBOX_OFFSET; + message->resp_offset = AUTO_UPDATE_DEFAULT_RESP_OFFSET; + + ret = mpfs_blocking_transaction(priv->sys_controller, message); + if (ret | response->resp_status) { + rc = FPGA_MGR_STATE_UNKNOWN; + goto free_message; + } + + if (!(response_msg[1] & AUTO_UPDATE_FEATURE_ENABLED)) + rc = FPGA_MGR_STATE_OPERATING; + +free_message: + devm_kfree(priv->dev, message); +free_response: + devm_kfree(priv->dev, response); +free_response_msg: + devm_kfree(priv->dev, response_msg); + + return rc; +} + +static int mpfs_auto_update_write_init(struct fpga_manager *mgr, struct fpga_image_info *info, + const char *buf, size_t count) +{ + /* + * Verifying the Golden Image is idealistic. It will be evaluated + * against the currently programmed image and thus may fail - due to + * either rollback protection (if its an older version than that in use) + * or if the version is the same as that of the in-use image. + * Extracting the information as to why a failure occurred is not + * currently possible due to limitations of the system controller + * driver. If those are fixed, verification of the Golden Image should + * be added here. + */ + return 0; +} + +static int mpfs_auto_update_write(struct fpga_manager *mgr, const char *buf, size_t count) +{ + /* + * No parsing etc of the bitstream is required. The system controller + * will do all of that itself - including verifying that the bitstream + * is valid. + */ + struct mpfs_auto_update_priv *priv = mgr->priv; + struct erase_info erase; + char *buffer; + loff_t directory_address = AUTO_UPDATE_UPGRADE_DIRECTORY; + size_t bytes_written = 0, bytes_read = 0; + size_t erase_size = AUTO_UPDATE_DIRECTORY_SIZE; + size_t size_per_bitstream = 0; + u32 image_address; + int ret; + + priv->flash = mpfs_sys_controller_get_flash(priv->sys_controller); + if (!priv->flash) + return -EIO; + + erase_size = round_up(erase_size, (u64)priv->flash->erasesize); + + /* + * We need to calculate if we have enough space in the flash for the + * new image. + * First, chop off the first 1 KiB as it's reserved for the directory. + * The 1 MiB reserved for design info needs to be ignored also. + * All that remains is carved into 3 & rounded down to the erasesize. + * If this is smaller than the image size, we abort. + * There's also no need to consume more than 20 MiB per image. + */ + size_per_bitstream = priv->flash->size - SZ_1K - SZ_1M; + size_per_bitstream = round_down(size_per_bitstream / 3, erase_size); + if (size_per_bitstream > 20 * SZ_1M) + size_per_bitstream = 20 * SZ_1M; + + if (size_per_bitstream < count) { + dev_err(priv->dev, + "flash device has insufficient capacity to store this bitstream\n"); + return -EINVAL; + } + + image_address = AUTO_UPDATE_BITSTREAM_BASE + AUTO_UPDATE_UPGRADE_INDEX * size_per_bitstream; + + buffer = devm_kzalloc(priv->dev, erase_size, GFP_KERNEL); + if (!buffer) + return -ENOMEM; + + erase.addr = AUTO_UPDATE_DIRECTORY_BASE; + erase.len = erase_size; + + /* + * We need to write the "SPI DIRECTORY" to the first 1 KiB, telling + * the system controller where to find the actual bitstream. Since + * this is spi-nor, we have to read the first eraseblock, erase that + * portion of the flash, modify the data and then write it back. + */ + ret = mtd_read(priv->flash, AUTO_UPDATE_DIRECTORY_BASE, erase_size, &bytes_read, + (u_char *)buffer); + if (ret) + goto out; + + if (bytes_read != erase_size) { + ret = -EIO; + goto out; + } + + ret = mtd_erase(priv->flash, &erase); + if (ret) + goto out; + + /* + * Populate the image address and then zero out the next directory so + * that the system controller doesn't complain if in "Single Image" + * mode. + */ + memcpy(buffer + AUTO_UPDATE_UPGRADE_DIRECTORY, &image_address, AUTO_UPDATE_DIRECTORY_WIDTH); + memset(buffer + AUTO_UPDATE_BLANK_DIRECTORY, 0x0, AUTO_UPDATE_DIRECTORY_WIDTH); + + dev_info(priv->dev, "Writing the image address (%x) to the flash directory (%llx)\n", + image_address, directory_address); + + ret = mtd_write(priv->flash, 0x0, erase_size, &bytes_written, (u_char *)buffer); + if (ret) + goto out; + + if (bytes_written != erase_size) { + ret = -EIO; + goto out; + } + + /* + * Now the .spi image itself can be written to the flash. Preservation + * of contents here is not important here, unlike the spi "directory" + * which must be RMWed. + */ + erase.len = round_up(count, (size_t)priv->flash->erasesize); + erase.addr = image_address; + + dev_info(priv->dev, "Erasing the flash at address (%x)\n", image_address); + ret = mtd_erase(priv->flash, &erase); + if (ret) + goto out; + + dev_info(priv->dev, "Writing the image to the flash at address (%x)\n", image_address); + ret = mtd_write(priv->flash, (loff_t)image_address, count, &bytes_written, buf); + if (ret) + goto out; + + if (bytes_written != count) + ret = -EIO; + +out: + devm_kfree(priv->dev, buffer); + return ret; +} + +static int mpfs_auto_update_write_complete(struct fpga_manager *mgr, struct fpga_image_info *info) +{ + struct mpfs_auto_update_priv *priv = mgr->priv; + struct mpfs_mss_response *response; + struct mpfs_mss_msg *message; + u32 *response_msg; + int ret; + + response_msg = devm_kzalloc(priv->dev, AUTO_UPDATE_FEATURE_RESP_SIZE * sizeof(response_msg), + GFP_KERNEL); + if (!response_msg) + return -ENOMEM; + + response = devm_kzalloc(priv->dev, sizeof(struct mpfs_mss_response), GFP_KERNEL); + if (!response) { + ret = -ENOMEM; + goto free_response_msg; + } + + message = devm_kzalloc(priv->dev, sizeof(struct mpfs_mss_msg), GFP_KERNEL); + if (!message) { + ret = -ENOMEM; + goto free_response; + } + + /* + * The system controller can verify that an image in the flash is valid. + * Rather than duplicate the check in this driver, call the relevant + * service from the system controller instead. + * This service has no command data and no response data. It overloads + * mbox_offset with the image index in the flash's SPI directory where + * the bitstream is located. + */ + response->resp_msg = response_msg; + response->resp_size = AUTO_UPDATE_AUTHENTICATE_RESP_SIZE; + message->cmd_opcode = AUTO_UPDATE_AUTHENTICATE_CMD_OPCODE; + message->cmd_data_size = AUTO_UPDATE_AUTHENTICATE_CMD_DATA_SIZE; + message->response = response; + message->cmd_data = AUTO_UPDATE_AUTHENTICATE_CMD_DATA; + message->mbox_offset = AUTO_UPDATE_UPGRADE_INDEX; + message->resp_offset = AUTO_UPDATE_DEFAULT_RESP_OFFSET; + + dev_info(priv->dev, "Running verification of Upgrade Image\n"); + ret = mpfs_blocking_transaction(priv->sys_controller, message); + if (ret | response->resp_status) { + dev_warn(priv->dev, "Verification of Upgrade Image failed!\n"); + ret = ret ? ret : -EBADMSG; + } + + dev_info(priv->dev, "Verification of Upgrade Image passed!\n"); +// /* +// * If the validation has passed, initiate Auto Update. +// * This service has no command data and no response data. It overloads +// * mbox_offset with the image index in the flash's SPI directory where +// * the bitstream is located. +// * Once we attempt Auto Update either: +// * - it passes and the board reboots +// * - it fails and the board reboots to recover +// * - the system controller aborts and we exit "gracefully". +// * "gracefully" since there is no interrupt produced & it just times +// * out. +// */ +// response->resp_msg = response_msg; +// response->resp_size = AUTO_UPDATE_PROGRAM_RESP_SIZE; +// message->cmd_opcode = AUTO_UPDATE_PROGRAM_CMD_OPCODE; +// message->cmd_data_size = AUTO_UPDATE_PROGRAM_CMD_DATA_SIZE; +// message->response = response; +// message->cmd_data = AUTO_UPDATE_PROGRAM_CMD_DATA; +// message->mbox_offset = 0; //field is ignored +// message->resp_offset = AUTO_UPDATE_DEFAULT_RESP_OFFSET; +// +// dev_info(priv->dev, "Running Auto Update command\n"); +// ret = mpfs_blocking_transaction(priv->sys_controller, message); +// if (ret && ret != -ETIMEDOUT) +// goto out; +// +// /* *remove this for auto update* +// * This return 0 is dead code. Either the Auto Update will fail, or it will pass +// * & the FPGA will be rebooted in which case mpfs_blocking_transaction() +// * will never return and Linux will die. +// */ +// return 0; + + devm_kfree(priv->dev, message); +free_response: + devm_kfree(priv->dev, response); +free_response_msg: + devm_kfree(priv->dev, response_msg); + + return ret; +} + +static const struct fpga_manager_ops mpfs_auto_update_ops = { + .state = mpfs_auto_update_state, + .write_init = mpfs_auto_update_write_init, + .write = mpfs_auto_update_write, + .write_complete = mpfs_auto_update_write_complete, +}; + +static int mpfs_auto_update_run(struct device *dev) +{ + struct fpga_manager *mgr; + struct fpga_image_info *info; + int ret; + + mgr = fpga_mgr_get(dev); + info = fpga_image_info_alloc(dev); + + info->firmware_name = devm_kstrdup(dev, "mpfs_bitstream.spi", GFP_KERNEL); + + ret = fpga_mgr_lock(mgr); + if (ret) + goto free_info; + + ret = fpga_mgr_load(mgr, info); + if (ret) { + dev_err(dev, "Failed to write the bitstream\n"); + goto unlock_mgr; + } + +unlock_mgr: + fpga_mgr_unlock(mgr); +free_info: + fpga_image_info_free(info); + fpga_mgr_put(mgr); + + return ret; +} + +static ssize_t mpfs_auto_update_exec(struct file *file, const char __user *data, size_t count, + loff_t *ppos) +{ + int ret; + + ret = mpfs_auto_update_run(mpfs_auto_update_debug_dev); + if (ret) + dev_err_probe(mpfs_auto_update_debug_dev, ret, "Auto Update failed"); + + return count; +} + +static const struct file_operations mpfs_auto_update_fops = { + .owner = THIS_MODULE, + .open = simple_open, + .write = mpfs_auto_update_exec +}; + +static int mpfs_auto_update_debugfs_setup(struct mpfs_auto_update_priv *priv) +{ + priv->debugfs_dir = debugfs_create_dir("fpga", NULL); + + if(IS_ERR(priv->debugfs_dir)) + return PTR_ERR(priv->debugfs_dir); + + debugfs_create_file("microchip_exec_update", 0200, priv->debugfs_dir, NULL, + &mpfs_auto_update_fops); + + return 0; +} + +static int mpfs_auto_update_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct mpfs_auto_update_priv *priv; + struct fpga_manager *mgr; + enum fpga_mgr_states state; + int ret; + + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + priv->sys_controller = mpfs_sys_controller_get(dev); + if (IS_ERR(priv->sys_controller)) + return dev_err_probe(dev, PTR_ERR(priv->sys_controller), + "Could not register as a sub device of the system controller\n"); + + priv->dev = dev; + platform_set_drvdata(pdev, priv); + + mgr = devm_fpga_mgr_register(dev, "Microchip MPFS Auto Update FPGA Manager", + &mpfs_auto_update_ops, priv); + if (IS_ERR(mgr)) + return dev_err_probe(dev, PTR_ERR(mgr), "Could not register FPGA manager.\n"); + + state = mpfs_auto_update_state(mgr); + if (state != FPGA_MGR_STATE_OPERATING) + return -EIO; + + ret = mpfs_auto_update_debugfs_setup(priv); + if (ret && ret != -ENODEV) + return ret; + + mpfs_auto_update_debug_dev = priv->dev; + + return 0; +} + +static struct platform_driver mpfs_auto_update_driver = { + .driver = { + .name = "mpfs-auto-update", + }, + .probe = mpfs_auto_update_probe, +}; +module_platform_driver(mpfs_auto_update_driver); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Conor Dooley "); +MODULE_DESCRIPTION("PolarFire SoC Auto Update FPGA reprogramming"); -- 2.39.1 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 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 smtp.lore.kernel.org (Postfix) with ESMTPS id 93B03C636D6 for ; Fri, 17 Feb 2023 16:41:15 +0000 (UTC) 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=w/ZSGEwhrxhFZHU9AZH/SJkndOG49FdjnuryEDEcb5M=; b=YFqUjgEo9mCc+J XQKD6jaPA2lSy+8BLIG6sWBIrZSd8Hnf3u0PdVlu84bdF+Ve7ByN99bH7BgBQvC5SHp6hFCc0q+8O 0YgE/arYNp4UCLdJnRWULUJDHCwiCotPi3xT9BL4+Ba0g7wVfQrl4W1AMblAaTLGeKsreoYc8zx3C Ehd3uaGRGKoZLwkowYJ4SORvmhuKh6BbGdLNCWgqbmnFl2Xb29Wegl1ix+dw0s4iuEtdQVogEUDM3 q0sSNpMQ7r8q8Jbx/8AbYmpCUNO4KZ88SlXo0H4bGULOupFIaRDxYL/cUrEr4exx9uhCZq3rK4ZPw 8WfRLdu1O5MR7I0qMF1A==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1pT3nH-00F7OP-GJ; Fri, 17 Feb 2023 16:41:07 +0000 Received: from dfw.source.kernel.org ([139.178.84.217]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1pT3n6-00F7Ix-Qv for linux-riscv@lists.infradead.org; Fri, 17 Feb 2023 16:40:59 +0000 Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 5891F61F0E; Fri, 17 Feb 2023 16:40:56 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 8475BC43444; Fri, 17 Feb 2023 16:40:53 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1676652056; bh=Ada5YJvntQNNf8mjai4BiBi5laL09boYhqgifAggSQ8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=oH++hjwqroHKIFxmF/HnsnxHUNBefUvOtOzGRWfyjk3g5O5C4HlXvlQqMjfF4mTtj MNIO3uV96d+6WmPTPJAuEjACZny2Q0P71ip5tuOusdjaO15DsfvSVO30mKv/iGyptl x4oK5StKhzqmaDlFnhtJ/6mLdFfotB5NAKiLI5qhj4oMEAlsDN8/Ma7ckgfLSI9LkR O3C1EzNtg6f6kZXUqnkilmrARmc312ZaryiS4cIQhbaRYTvwUV2IQ08keAmdjnFFBy oTJDX4Ci40ku7kp2I39uUsNuRhzNWOnyjqy4x1HScqJcHhdBZG/JQ1OPjD1H0Xgid0 XmZUqfnv+cG8Q== From: Conor Dooley To: Xu Yilun , conor@kernel.org Cc: Conor Dooley , Daire McNamara , Rob Herring , Krzysztof Kozlowski , Moritz Fischer , Wu Hao , Tom Rix , linux-riscv@lists.infradead.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-fpga@vger.kernel.org Subject: [PATCH v1 5/6] fpga: add PolarFire SoC Auto Update support Date: Fri, 17 Feb 2023 16:40:22 +0000 Message-Id: <20230217164023.14255-6-conor@kernel.org> X-Mailer: git-send-email 2.39.1 In-Reply-To: <20230217164023.14255-1-conor@kernel.org> References: <20230217164023.14255-1-conor@kernel.org> MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=18671; i=conor.dooley@microchip.com; h=from:subject; bh=5c9FyeDfJ+4rxNjXaNpKTn1QANdTH3UMNxq+UGzUyrc=; b=owGbwMvMwCFWscWwfUFT0iXG02pJDMnv175l+PRYZsXn5Ulb3itvSAu2UVC6qRv1bWL2lVv1RuvW 39hk0VHKwiDGwSArpsiSeLuvRWr9H5cdzj1vYeawMoEN4eIUgImwdzL8j1316fl8j+vp3VvUDy5y8u ud8Xh6Q6T2ki5LkYC6tJWdTowMW9dyu/abSShd2FJiZPnvnu31qbssdmaaBRafY7z1b8sDdgA= X-Developer-Key: i=conor.dooley@microchip.com; a=openpgp; fpr=F9ECA03CF54F12CD01F1655722E2C55B37CF380C X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20230217_084057_051165_936E12AC X-CRM114-Status: GOOD ( 34.38 ) X-BeenThere: linux-riscv@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-riscv" Errors-To: linux-riscv-bounces+linux-riscv=archiver.kernel.org@lists.infradead.org RnJvbTogQ29ub3IgRG9vbGV5IDxjb25vci5kb29sZXlAbWljcm9jaGlwLmNvbT4KCkFkZCBzdXBw b3J0IGZvciBBdXRvIFVwZGF0ZSByZXByb2dyYW1taW5nIG9mIHRoZSBGUEdBIGZhYnJpYyBvbgpQ b2xhckZpcmUgU29DLgoKU2lnbmVkLW9mZi1ieTogQ29ub3IgRG9vbGV5IDxjb25vci5kb29sZXlA bWljcm9jaGlwLmNvbT4KLS0tCiBkcml2ZXJzL2ZwZ2EvS2NvbmZpZyAgICAgICAgICAgICAgICAg fCAgIDkgKwogZHJpdmVycy9mcGdhL01ha2VmaWxlICAgICAgICAgICAgICAgIHwgICAxICsKIGRy aXZlcnMvZnBnYS9taWNyb2NoaXAtYXV0by11cGRhdGUuYyB8IDQ5NSArKysrKysrKysrKysrKysr KysrKysrKysrKysKIDMgZmlsZXMgY2hhbmdlZCwgNTA1IGluc2VydGlvbnMoKykKIGNyZWF0ZSBt b2RlIDEwMDY0NCBkcml2ZXJzL2ZwZ2EvbWljcm9jaGlwLWF1dG8tdXBkYXRlLmMKCmRpZmYgLS1n aXQgYS9kcml2ZXJzL2ZwZ2EvS2NvbmZpZyBiL2RyaXZlcnMvZnBnYS9LY29uZmlnCmluZGV4IDZj ZTE0M2RhZmQwNC4uMGNkZDY5NzhhNDQwIDEwMDY0NAotLS0gYS9kcml2ZXJzL2ZwZ2EvS2NvbmZp ZworKysgYi9kcml2ZXJzL2ZwZ2EvS2NvbmZpZwpAQCAtMjU3LDYgKzI1NywxNSBAQCBjb25maWcg RlBHQV9NMTBfQk1DX1NFQ19VUERBVEUKIAkgIChCTUMpIGFuZCBwcm92aWRlcyBzdXBwb3J0IGZv ciBzZWN1cmUgdXBkYXRlcyBmb3IgdGhlIEJNQyBpbWFnZSwKIAkgIHRoZSBGUEdBIGltYWdlLCB0 aGUgUm9vdCBFbnRyeSBIYXNoZXMsIGV0Yy4KIAorY29uZmlnIEZQR0FfTUdSX01JQ1JPQ0hJUF9B VVRPX1VQREFURQorCXRyaXN0YXRlICJNaWNyb2NoaXAgUG9sYXJGaXJlIFNvQyBBVVRPIFVQREFU RSIKKwlkZXBlbmRzIG9uIFBPTEFSRklSRV9TT0NfU1lTX0NUUkwKKwloZWxwCisJICBGUEdBIG1h bmFnZXIgZHJpdmVyIHN1cHBvcnQgZm9yIHJlcHJvZ3JhbW1pbmcgUG9sYXJGaXJlIFNvQyBmcm9t CisJICB3aXRoaW4gTGludXgsIHVzaW5nIHRoZSBBdXRvIFVwZ3JhZGUgZmVhdHVyZSBvZiB0aGUg c3lzdGVtIGNvbnRyb2xsZXIuCisKKwkgIElmIGJ1aWx0IGFzIGEgbW9kdWxlLCBpdCB3aWxsIGJl IGNhbGxlZCBtaWNyb2NoaXAtYXV0by11cGRhdGUuCisKIGNvbmZpZyBGUEdBX01HUl9NSUNST0NI SVBfU1BJCiAJdHJpc3RhdGUgIk1pY3JvY2hpcCBQb2xhcmZpcmUgU1BJIEZQR0EgbWFuYWdlciIK IAlkZXBlbmRzIG9uIFNQSQpkaWZmIC0tZ2l0IGEvZHJpdmVycy9mcGdhL01ha2VmaWxlIGIvZHJp dmVycy9mcGdhL01ha2VmaWxlCmluZGV4IDcyZTU1NGI0ZDJmNy4uYTY3OTAzZWRmOTc2IDEwMDY0 NAotLS0gYS9kcml2ZXJzL2ZwZ2EvTWFrZWZpbGUKKysrIGIvZHJpdmVycy9mcGdhL01ha2VmaWxl CkBAIC0xOSw2ICsxOSw3IEBAIG9iai0kKENPTkZJR19GUEdBX01HUl9YSUxJTlhfU1BJKQkrPSB4 aWxpbngtc3BpLm8KIG9iai0kKENPTkZJR19GUEdBX01HUl9aWU5RX0ZQR0EpCSs9IHp5bnEtZnBn YS5vCiBvYmotJChDT05GSUdfRlBHQV9NR1JfWllOUU1QX0ZQR0EpCSs9IHp5bnFtcC1mcGdhLm8K IG9iai0kKENPTkZJR19GUEdBX01HUl9WRVJTQUxfRlBHQSkJKz0gdmVyc2FsLWZwZ2Eubworb2Jq LSQoQ09ORklHX0ZQR0FfTUdSX01JQ1JPQ0hJUF9BVVRPX1VQREFURSkJKz0gbWljcm9jaGlwLWF1 dG8tdXBkYXRlLm8KIG9iai0kKENPTkZJR19GUEdBX01HUl9NSUNST0NISVBfU1BJKQkrPSBtaWNy b2NoaXAtc3BpLm8KIG9iai0kKENPTkZJR19GUEdBX01HUl9MQVRUSUNFX1NZU0NPTkZJRykJKz0g bGF0dGljZS1zeXNjb25maWcubwogb2JqLSQoQ09ORklHX0ZQR0FfTUdSX0xBVFRJQ0VfU1lTQ09O RklHX1NQSSkJKz0gbGF0dGljZS1zeXNjb25maWctc3BpLm8KZGlmZiAtLWdpdCBhL2RyaXZlcnMv ZnBnYS9taWNyb2NoaXAtYXV0by11cGRhdGUuYyBiL2RyaXZlcnMvZnBnYS9taWNyb2NoaXAtYXV0 by11cGRhdGUuYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwMDAwMDAuLmQ5MDA4 NWY4NmI4YgotLS0gL2Rldi9udWxsCisrKyBiL2RyaXZlcnMvZnBnYS9taWNyb2NoaXAtYXV0by11 cGRhdGUuYwpAQCAtMCwwICsxLDQ5NSBAQAorLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEdQ TC0yLjAKKy8qCisgKiBNaWNyb2NoaXAgUG9sYXJmaXJlIFNvQyAiQXV0byBVcGRhdGUiIEZQR0Eg cmVwcm9ncmFtbWluZy4KKyAqCisgKiBEb2N1bWVudGF0aW9uIG9mIHRoaXMgZnVuY3Rpb25hbGl0 eSBpcyBhdmFpbGFibGUgaW4gdGhlICJQb2xhckZpcmXCriBGUEdBIGFuZAorICogUG9sYXJGaXJl IFNvQyBGUEdBIFByb2dyYW1taW5nIiBVc2VyIEd1aWRlLgorICoKKyAqIENvcHlyaWdodCAoYykg MjAyMi0yMDIzIE1pY3JvY2hpcCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAq CisgKiBBdXRob3I6IENvbm9yIERvb2xleSA8Y29ub3IuZG9vbGV5QG1pY3JvY2hpcC5jb20+Cisg Ki8KKyNpbmNsdWRlIDxsaW51eC9kZWJ1Z2ZzLmg+CisjaW5jbHVkZSA8bGludXgvZnBnYS9mcGdh LW1nci5oPgorI2luY2x1ZGUgPGxpbnV4L21hdGguaD4KKyNpbmNsdWRlIDxsaW51eC9tb2R1bGUu aD4KKyNpbmNsdWRlIDxsaW51eC9tdGQvbXRkLmg+CisjaW5jbHVkZSA8bGludXgvb2ZfZGV2aWNl Lmg+CisjaW5jbHVkZSA8bGludXgvc2l6ZXMuaD4KKworI2luY2x1ZGUgPHNvYy9taWNyb2NoaXAv bXBmcy5oPgorCisjZGVmaW5lIEFVVE9fVVBEQVRFX0RFRkFVTFRfTUJPWF9PRkZTRVQJCTB1Cisj ZGVmaW5lIEFVVE9fVVBEQVRFX0RFRkFVTFRfUkVTUF9PRkZTRVQJCTB1CisKKyNkZWZpbmUgQVVU T19VUERBVEVfRkVBVFVSRV9DTURfT1BDT0RFCQkweDA1dQorI2RlZmluZSBBVVRPX1VQREFURV9G RUFUVVJFX0NNRF9EQVRBX1NJWkUJMHUKKyNkZWZpbmUgQVVUT19VUERBVEVfRkVBVFVSRV9SRVNQ X1NJWkUJCTMzdQorI2RlZmluZSBBVVRPX1VQREFURV9GRUFUVVJFX0NNRF9EQVRBCQlOVUxMCisj ZGVmaW5lIEFVVE9fVVBEQVRFX0ZFQVRVUkVfRU5BQkxFRAkJQklUKDUpCisKKyNkZWZpbmUgQVVU T19VUERBVEVfQVVUSEVOVElDQVRFX0NNRF9PUENPREUJMHgyMnUKKyNkZWZpbmUgQVVUT19VUERB VEVfQVVUSEVOVElDQVRFX0NNRF9EQVRBX1NJWkUJMHUKKyNkZWZpbmUgQVVUT19VUERBVEVfQVVU SEVOVElDQVRFX1JFU1BfU0laRQkxdQorI2RlZmluZSBBVVRPX1VQREFURV9BVVRIRU5USUNBVEVf Q01EX0RBVEEJTlVMTAorCisjZGVmaW5lIEFVVE9fVVBEQVRFX1BST0dSQU1fQ01EX09QQ09ERQkJ MHg0NnUKKyNkZWZpbmUgQVVUT19VUERBVEVfUFJPR1JBTV9DTURfREFUQV9TSVpFCTB1CisjZGVm aW5lIEFVVE9fVVBEQVRFX1BST0dSQU1fUkVTUF9TSVpFCQkxdQorI2RlZmluZSBBVVRPX1VQREFU RV9QUk9HUkFNX0NNRF9EQVRBCQlOVUxMCisKKy8qCisgKiBTUEkgRmxhc2ggbGF5b3V0IGV4YW1w bGU6CisgKiB8LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tfCAweDAwMDAwMDAKKyAqIHwg MSBLaUIgICAgICAgICAgICAgICAgICAgICAgICB8CisgKiB8IFNQSSAiZGlyZWN0b3JpZXMiICAg ICAgICAgICAgfAorICogfC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLXwgMHgwMDAwNDAw CisgKiB8IDEgTWlCICAgICAgICAgICAgICAgICAgICAgICAgfAorICogfCBSZXNlcnZlZCBhcmVh ICAgICAgICAgICAgICAgIHwKKyAqIHwgVXNlZCBmb3IgYml0c3RyZWFtIGluZm8gICAgICB8Cisg KiB8LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tfCAweDAxMDA0MDAKKyAqIHwgMjAgTWlC ICAgICAgICAgICAgICAgICAgICAgICB8CisgKiB8IEdvbGRlbiBJbWFnZSAgICAgICAgICAgICAg ICAgfAorICogfC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLXwgMHgxNTAwNDAwCisgKiB8 IDIwIE1pQiAgICAgICAgICAgICAgICAgICAgICAgfAorICogfCBBdXRvIFVwZ3JhZGUgSW1hZ2Ug ICAgICAgICAgIHwKKyAqIHwtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS18IDB4MjkwMDQw MAorICogfCAyMCBNaUIgICAgICAgICAgICAgICAgICAgICAgIHwKKyAqIHwgUmVzZXJ2ZWQgZm9y IG11bHRpLWltYWdlIElBUCB8CisgKiB8IFVudXNlZCBmb3IgQXV0byBVcGdyYWRlICAgICAgfAor ICogfC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLXwgMHgzRDAwNDAwCisgKiB8ID8gQiAg ICAgICAgICAgICAgICAgICAgICAgICAgfAorICogfCBVbnVzZWQgICAgICAgICAgICAgICAgICAg ICAgIHwKKyAqIHwtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS18IDB4PworICovCisjZGVm aW5lIEFVVE9fVVBEQVRFX0RJUkVDVE9SWV9CQVNFCTB1CisjZGVmaW5lIEFVVE9fVVBEQVRFX0RJ UkVDVE9SWV9XSURUSAk0dQorI2RlZmluZSBBVVRPX1VQREFURV9HT0xERU5fSU5ERVgJMHUKKyNk ZWZpbmUgQVVUT19VUERBVEVfVVBHUkFERV9JTkRFWAkxdQorI2RlZmluZSBBVVRPX1VQREFURV9C TEFOS19JTkRFWAkJMnUKKyNkZWZpbmUgQVVUT19VUERBVEVfR09MREVOX0RJUkVDVE9SWQkoQVVU T19VUERBVEVfRElSRUNUT1JZX1dJRFRIICogQVVUT19VUERBVEVfR09MREVOX0lOREVYKQorI2Rl ZmluZSBBVVRPX1VQREFURV9VUEdSQURFX0RJUkVDVE9SWQkoQVVUT19VUERBVEVfRElSRUNUT1JZ X1dJRFRIICogQVVUT19VUERBVEVfVVBHUkFERV9JTkRFWCkKKyNkZWZpbmUgQVVUT19VUERBVEVf QkxBTktfRElSRUNUT1JZCShBVVRPX1VQREFURV9ESVJFQ1RPUllfV0lEVEggKiBBVVRPX1VQREFU RV9CTEFOS19JTkRFWCkKKyNkZWZpbmUgQVVUT19VUERBVEVfRElSRUNUT1JZX1NJWkUJU1pfMUsK KyNkZWZpbmUgQVVUT19VUERBVEVfUkVTRVJWRURfU0laRQlTWl8xTQorI2RlZmluZSBBVVRPX1VQ REFURV9CSVRTVFJFQU1fQkFTRQkoQVVUT19VUERBVEVfRElSRUNUT1JZX1NJWkUgKyBBVVRPX1VQ REFURV9SRVNFUlZFRF9TSVpFKQorCitzdHJ1Y3QgbXBmc19hdXRvX3VwZGF0ZV9jb25maWcgewor CXU4IGZlYXR1cmVfcmVzcG9uc2Vfc2l6ZTsKK307CisKK3N0cnVjdCBtcGZzX2F1dG9fdXBkYXRl X3ByaXYgeworCXN0cnVjdCBtcGZzX3N5c19jb250cm9sbGVyICpzeXNfY29udHJvbGxlcjsKKwlz dHJ1Y3QgZGV2aWNlICpkZXY7CisJc3RydWN0IGZwZ2FfcmVnaW9uICpyZWdpb247CisJc3RydWN0 IG1wZnNfYXV0b191cGRhdGVfY29uZmlnICpjb25maWc7CisJc3RydWN0IG10ZF9pbmZvICpmbGFz aDsKKwlzdHJ1Y3QgZGVudHJ5ICpkZWJ1Z2ZzX2RpcjsKK307CisKK3N0YXRpYyBzdHJ1Y3QgZGV2 aWNlICptcGZzX2F1dG9fdXBkYXRlX2RlYnVnX2RldjsKKworc3RhdGljIGVudW0gZnBnYV9tZ3Jf c3RhdGVzIG1wZnNfYXV0b191cGRhdGVfc3RhdGUoc3RydWN0IGZwZ2FfbWFuYWdlciAqbWdyKQor eworCXN0cnVjdCBtcGZzX2F1dG9fdXBkYXRlX3ByaXYgKnByaXYgPSBtZ3ItPnByaXY7CisJc3Ry dWN0IG1wZnNfbXNzX3Jlc3BvbnNlICpyZXNwb25zZTsKKwlzdHJ1Y3QgbXBmc19tc3NfbXNnICpt ZXNzYWdlOworCXUzMiAqcmVzcG9uc2VfbXNnOworCWludCByZXQ7CisJZW51bSBmcGdhX21ncl9z dGF0ZXMgcmMgPSBGUEdBX01HUl9TVEFURV9XUklURV9JTklUX0VSUjsKKworCXJlc3BvbnNlX21z ZyA9IGRldm1fa3phbGxvYyhwcml2LT5kZXYsIEFVVE9fVVBEQVRFX0ZFQVRVUkVfUkVTUF9TSVpF ICogc2l6ZW9mKHJlc3BvbnNlX21zZyksCisJCQkJICAgIEdGUF9LRVJORUwpOworCWlmICghcmVz cG9uc2VfbXNnKQorCQlyZXR1cm4gRlBHQV9NR1JfU1RBVEVfV1JJVEVfSU5JVF9FUlI7CisKKwly ZXNwb25zZSA9IGRldm1fa3phbGxvYyhwcml2LT5kZXYsIHNpemVvZihzdHJ1Y3QgbXBmc19tc3Nf cmVzcG9uc2UpLCBHRlBfS0VSTkVMKTsKKwlpZiAoIXJlc3BvbnNlKSB7CisJCXJjID0gRlBHQV9N R1JfU1RBVEVfV1JJVEVfSU5JVF9FUlI7CisJCWdvdG8gZnJlZV9yZXNwb25zZV9tc2c7CisJfQor CisJbWVzc2FnZSA9IGRldm1fa3phbGxvYyhwcml2LT5kZXYsIHNpemVvZihzdHJ1Y3QgbXBmc19t c3NfbXNnKSwgR0ZQX0tFUk5FTCk7CisJaWYgKCFtZXNzYWdlKSB7CisJCXJjID0gRlBHQV9NR1Jf U1RBVEVfV1JJVEVfSU5JVF9FUlI7CisJCWdvdG8gZnJlZV9yZXNwb25zZTsKKwl9CisKKwkvKgor CSAqIFRvIHZlcmlmeSB0aGF0IEF1dG8gVXBkYXRlIGlzIHBvc3NpYmxlLCB0aGUgIlF1ZXJ5IFNl Y3VyaXR5IFNlcnZpY2UKKwkgKiBSZXF1ZXN0IiBpcyBwZXJmb3JtZWQuIEJpdCA1IG9mIGJ5dGUg MSBpcyAiVUxfQXV0byBVcGRhdGUiICYgaWYgaXQgaXMKKwkgKiBzZXQsIEF1dG8gVXBkYXRlIGlz IG5vdCBwb3NzaWJsZS4KKwkgKiBUaGlzIHNlcnZpY2UgaGFzIG5vIGNvbW1hbmQgZGF0YSAmIGRv ZXMgbm90IG92ZXJsb2FkIG1ib3hfb2Zmc2V0LgorCSAqIFRoZSBzaXplIG9mIHRoZSByZXNwb25z ZSB2YXJpZXMgYmV0d2VlbiBQb2xhckZpcmUgJiBQb2xhckZpcmUgU29DLgorCSAqLworCXJlc3Bv bnNlLT5yZXNwX21zZyA9IHJlc3BvbnNlX21zZzsKKwlyZXNwb25zZS0+cmVzcF9zaXplID0gQVVU T19VUERBVEVfRkVBVFVSRV9SRVNQX1NJWkU7CisJbWVzc2FnZS0+Y21kX29wY29kZSA9IEFVVE9f VVBEQVRFX0ZFQVRVUkVfQ01EX09QQ09ERTsKKwltZXNzYWdlLT5jbWRfZGF0YV9zaXplID0gQVVU T19VUERBVEVfRkVBVFVSRV9DTURfREFUQV9TSVpFOworCW1lc3NhZ2UtPnJlc3BvbnNlID0gcmVz cG9uc2U7CisJbWVzc2FnZS0+Y21kX2RhdGEgPSBBVVRPX1VQREFURV9GRUFUVVJFX0NNRF9EQVRB OworCW1lc3NhZ2UtPm1ib3hfb2Zmc2V0ID0gQVVUT19VUERBVEVfREVGQVVMVF9NQk9YX09GRlNF VDsKKwltZXNzYWdlLT5yZXNwX29mZnNldCA9IEFVVE9fVVBEQVRFX0RFRkFVTFRfUkVTUF9PRkZT RVQ7CisKKwlyZXQgPSBtcGZzX2Jsb2NraW5nX3RyYW5zYWN0aW9uKHByaXYtPnN5c19jb250cm9s bGVyLCBtZXNzYWdlKTsKKwlpZiAocmV0IHwgcmVzcG9uc2UtPnJlc3Bfc3RhdHVzKSB7CisJCXJj ID0gRlBHQV9NR1JfU1RBVEVfVU5LTk9XTjsKKwkJZ290byBmcmVlX21lc3NhZ2U7CisJfQorCisJ aWYgKCEocmVzcG9uc2VfbXNnWzFdICYgQVVUT19VUERBVEVfRkVBVFVSRV9FTkFCTEVEKSkKKwkJ cmMgPSBGUEdBX01HUl9TVEFURV9PUEVSQVRJTkc7CisKK2ZyZWVfbWVzc2FnZToKKwlkZXZtX2tm cmVlKHByaXYtPmRldiwgbWVzc2FnZSk7CitmcmVlX3Jlc3BvbnNlOgorCWRldm1fa2ZyZWUocHJp di0+ZGV2LCByZXNwb25zZSk7CitmcmVlX3Jlc3BvbnNlX21zZzoKKwlkZXZtX2tmcmVlKHByaXYt PmRldiwgcmVzcG9uc2VfbXNnKTsKKworCXJldHVybiByYzsKK30KKworc3RhdGljIGludCBtcGZz X2F1dG9fdXBkYXRlX3dyaXRlX2luaXQoc3RydWN0IGZwZ2FfbWFuYWdlciAqbWdyLCBzdHJ1Y3Qg ZnBnYV9pbWFnZV9pbmZvICppbmZvLAorCQkJCSAgICAgICBjb25zdCBjaGFyICpidWYsIHNpemVf dCBjb3VudCkKK3sKKwkvKgorCSAqIFZlcmlmeWluZyB0aGUgR29sZGVuIEltYWdlIGlzIGlkZWFs aXN0aWMuIEl0IHdpbGwgYmUgZXZhbHVhdGVkCisJICogYWdhaW5zdCB0aGUgY3VycmVudGx5IHBy b2dyYW1tZWQgaW1hZ2UgYW5kIHRodXMgbWF5IGZhaWwgLSBkdWUgdG8KKwkgKiBlaXRoZXIgcm9s bGJhY2sgcHJvdGVjdGlvbiAoaWYgaXRzIGFuIG9sZGVyIHZlcnNpb24gdGhhbiB0aGF0IGluIHVz ZSkKKwkgKiBvciBpZiB0aGUgdmVyc2lvbiBpcyB0aGUgc2FtZSBhcyB0aGF0IG9mIHRoZSBpbi11 c2UgaW1hZ2UuCisJICogRXh0cmFjdGluZyB0aGUgaW5mb3JtYXRpb24gYXMgdG8gd2h5IGEgZmFp bHVyZSBvY2N1cnJlZCBpcyBub3QKKwkgKiBjdXJyZW50bHkgcG9zc2libGUgZHVlIHRvIGxpbWl0 YXRpb25zIG9mIHRoZSBzeXN0ZW0gY29udHJvbGxlcgorCSAqIGRyaXZlci4gSWYgdGhvc2UgYXJl IGZpeGVkLCB2ZXJpZmljYXRpb24gb2YgdGhlIEdvbGRlbiBJbWFnZSBzaG91bGQKKwkgKiBiZSBh ZGRlZCBoZXJlLgorCSAqLworCXJldHVybiAwOworfQorCitzdGF0aWMgaW50IG1wZnNfYXV0b191 cGRhdGVfd3JpdGUoc3RydWN0IGZwZ2FfbWFuYWdlciAqbWdyLCBjb25zdCBjaGFyICpidWYsIHNp emVfdCBjb3VudCkKK3sKKwkvKgorCSAqIE5vIHBhcnNpbmcgZXRjIG9mIHRoZSBiaXRzdHJlYW0g aXMgcmVxdWlyZWQuIFRoZSBzeXN0ZW0gY29udHJvbGxlcgorCSAqIHdpbGwgZG8gYWxsIG9mIHRo YXQgaXRzZWxmIC0gaW5jbHVkaW5nIHZlcmlmeWluZyB0aGF0IHRoZSBiaXRzdHJlYW0KKwkgKiBp cyB2YWxpZC4KKwkgKi8KKwlzdHJ1Y3QgbXBmc19hdXRvX3VwZGF0ZV9wcml2ICpwcml2ID0gbWdy LT5wcml2OworCXN0cnVjdCBlcmFzZV9pbmZvIGVyYXNlOworCWNoYXIgKmJ1ZmZlcjsKKwlsb2Zm X3QgZGlyZWN0b3J5X2FkZHJlc3MgPSBBVVRPX1VQREFURV9VUEdSQURFX0RJUkVDVE9SWTsKKwlz aXplX3QgYnl0ZXNfd3JpdHRlbiA9IDAsIGJ5dGVzX3JlYWQgPSAwOworCXNpemVfdCBlcmFzZV9z aXplID0gQVVUT19VUERBVEVfRElSRUNUT1JZX1NJWkU7CisJc2l6ZV90IHNpemVfcGVyX2JpdHN0 cmVhbSA9IDA7CisJdTMyIGltYWdlX2FkZHJlc3M7CisJaW50IHJldDsKKworCXByaXYtPmZsYXNo ID0gbXBmc19zeXNfY29udHJvbGxlcl9nZXRfZmxhc2gocHJpdi0+c3lzX2NvbnRyb2xsZXIpOwor CWlmICghcHJpdi0+Zmxhc2gpCisJCXJldHVybiAtRUlPOworCisJZXJhc2Vfc2l6ZSA9IHJvdW5k X3VwKGVyYXNlX3NpemUsICh1NjQpcHJpdi0+Zmxhc2gtPmVyYXNlc2l6ZSk7CisKKwkvKgorCSAq IFdlIG5lZWQgdG8gY2FsY3VsYXRlIGlmIHdlIGhhdmUgZW5vdWdoIHNwYWNlIGluIHRoZSBmbGFz aCBmb3IgdGhlCisJICogbmV3IGltYWdlLgorCSAqIEZpcnN0LCBjaG9wIG9mZiB0aGUgZmlyc3Qg MSBLaUIgYXMgaXQncyByZXNlcnZlZCBmb3IgdGhlIGRpcmVjdG9yeS4KKwkgKiBUaGUgMSBNaUIg cmVzZXJ2ZWQgZm9yIGRlc2lnbiBpbmZvIG5lZWRzIHRvIGJlIGlnbm9yZWQgYWxzby4KKwkgKiBB bGwgdGhhdCByZW1haW5zIGlzIGNhcnZlZCBpbnRvIDMgJiByb3VuZGVkIGRvd24gdG8gdGhlIGVy YXNlc2l6ZS4KKwkgKiBJZiB0aGlzIGlzIHNtYWxsZXIgdGhhbiB0aGUgaW1hZ2Ugc2l6ZSwgd2Ug YWJvcnQuCisJICogVGhlcmUncyBhbHNvIG5vIG5lZWQgdG8gY29uc3VtZSBtb3JlIHRoYW4gMjAg TWlCIHBlciBpbWFnZS4KKwkgKi8KKwlzaXplX3Blcl9iaXRzdHJlYW0gPSBwcml2LT5mbGFzaC0+ c2l6ZSAtIFNaXzFLIC0gU1pfMU07CisJc2l6ZV9wZXJfYml0c3RyZWFtID0gcm91bmRfZG93bihz aXplX3Blcl9iaXRzdHJlYW0gLyAzLCBlcmFzZV9zaXplKTsKKwlpZiAoc2l6ZV9wZXJfYml0c3Ry ZWFtID4gMjAgKiBTWl8xTSkKKwkJc2l6ZV9wZXJfYml0c3RyZWFtID0gMjAgKiBTWl8xTTsKKwor CWlmIChzaXplX3Blcl9iaXRzdHJlYW0gPCBjb3VudCkgeworCQlkZXZfZXJyKHByaXYtPmRldiwK KwkJCSJmbGFzaCBkZXZpY2UgaGFzIGluc3VmZmljaWVudCBjYXBhY2l0eSB0byBzdG9yZSB0aGlz IGJpdHN0cmVhbVxuIik7CisJCXJldHVybiAtRUlOVkFMOworCX0KKworCWltYWdlX2FkZHJlc3Mg PSBBVVRPX1VQREFURV9CSVRTVFJFQU1fQkFTRSArIEFVVE9fVVBEQVRFX1VQR1JBREVfSU5ERVgg KiBzaXplX3Blcl9iaXRzdHJlYW07CisKKwlidWZmZXIgPSBkZXZtX2t6YWxsb2MocHJpdi0+ZGV2 LCBlcmFzZV9zaXplLCBHRlBfS0VSTkVMKTsKKwlpZiAoIWJ1ZmZlcikKKwkJcmV0dXJuIC1FTk9N RU07CisKKwllcmFzZS5hZGRyID0gQVVUT19VUERBVEVfRElSRUNUT1JZX0JBU0U7CisJZXJhc2Uu bGVuID0gZXJhc2Vfc2l6ZTsKKworCS8qCisJICogV2UgbmVlZCB0byB3cml0ZSB0aGUgIlNQSSBE SVJFQ1RPUlkiIHRvIHRoZSBmaXJzdCAxIEtpQiwgdGVsbGluZworCSAqIHRoZSBzeXN0ZW0gY29u dHJvbGxlciB3aGVyZSB0byBmaW5kIHRoZSBhY3R1YWwgYml0c3RyZWFtLiBTaW5jZQorCSAqIHRo aXMgaXMgc3BpLW5vciwgd2UgaGF2ZSB0byByZWFkIHRoZSBmaXJzdCBlcmFzZWJsb2NrLCBlcmFz ZSB0aGF0CisJICogcG9ydGlvbiBvZiB0aGUgZmxhc2gsIG1vZGlmeSB0aGUgZGF0YSBhbmQgdGhl biB3cml0ZSBpdCBiYWNrLgorCSAqLworCXJldCA9IG10ZF9yZWFkKHByaXYtPmZsYXNoLCBBVVRP X1VQREFURV9ESVJFQ1RPUllfQkFTRSwgZXJhc2Vfc2l6ZSwgJmJ5dGVzX3JlYWQsCisJCSAgICAg ICAodV9jaGFyICopYnVmZmVyKTsKKwlpZiAocmV0KQorCQlnb3RvIG91dDsKKworCWlmIChieXRl c19yZWFkICE9IGVyYXNlX3NpemUpIHsKKwkJcmV0ID0gLUVJTzsKKwkJZ290byBvdXQ7CisJfQor CisJcmV0ID0gbXRkX2VyYXNlKHByaXYtPmZsYXNoLCAmZXJhc2UpOworCWlmIChyZXQpCisJCWdv dG8gb3V0OworCisJLyoKKwkgKiBQb3B1bGF0ZSB0aGUgaW1hZ2UgYWRkcmVzcyBhbmQgdGhlbiB6 ZXJvIG91dCB0aGUgbmV4dCBkaXJlY3Rvcnkgc28KKwkgKiB0aGF0IHRoZSBzeXN0ZW0gY29udHJv bGxlciBkb2Vzbid0IGNvbXBsYWluIGlmIGluICJTaW5nbGUgSW1hZ2UiCisJICogbW9kZS4KKwkg Ki8KKwltZW1jcHkoYnVmZmVyICsgQVVUT19VUERBVEVfVVBHUkFERV9ESVJFQ1RPUlksICZpbWFn ZV9hZGRyZXNzLCBBVVRPX1VQREFURV9ESVJFQ1RPUllfV0lEVEgpOworCW1lbXNldChidWZmZXIg KyBBVVRPX1VQREFURV9CTEFOS19ESVJFQ1RPUlksIDB4MCwgQVVUT19VUERBVEVfRElSRUNUT1JZ X1dJRFRIKTsKKworCWRldl9pbmZvKHByaXYtPmRldiwgIldyaXRpbmcgdGhlIGltYWdlIGFkZHJl c3MgKCV4KSB0byB0aGUgZmxhc2ggZGlyZWN0b3J5ICglbGx4KVxuIiwKKwkJIGltYWdlX2FkZHJl c3MsIGRpcmVjdG9yeV9hZGRyZXNzKTsKKworCXJldCA9IG10ZF93cml0ZShwcml2LT5mbGFzaCwg MHgwLCBlcmFzZV9zaXplLCAmYnl0ZXNfd3JpdHRlbiwgKHVfY2hhciAqKWJ1ZmZlcik7CisJaWYg KHJldCkKKwkJZ290byBvdXQ7CisKKwlpZiAoYnl0ZXNfd3JpdHRlbiAhPSBlcmFzZV9zaXplKSB7 CisJCXJldCA9IC1FSU87CisJCWdvdG8gb3V0OworCX0KKworCS8qCisJICogTm93IHRoZSAuc3Bp IGltYWdlIGl0c2VsZiBjYW4gYmUgd3JpdHRlbiB0byB0aGUgZmxhc2guIFByZXNlcnZhdGlvbgor CSAqIG9mIGNvbnRlbnRzIGhlcmUgaXMgbm90IGltcG9ydGFudCBoZXJlLCB1bmxpa2UgdGhlIHNw aSAiZGlyZWN0b3J5IgorCSAqIHdoaWNoIG11c3QgYmUgUk1XZWQuCisJICovCisJZXJhc2UubGVu ID0gcm91bmRfdXAoY291bnQsIChzaXplX3QpcHJpdi0+Zmxhc2gtPmVyYXNlc2l6ZSk7CisJZXJh c2UuYWRkciA9IGltYWdlX2FkZHJlc3M7CisKKwlkZXZfaW5mbyhwcml2LT5kZXYsICJFcmFzaW5n IHRoZSBmbGFzaCBhdCBhZGRyZXNzICgleClcbiIsIGltYWdlX2FkZHJlc3MpOworCXJldCA9IG10 ZF9lcmFzZShwcml2LT5mbGFzaCwgJmVyYXNlKTsKKwlpZiAocmV0KQorCQlnb3RvIG91dDsKKwor CWRldl9pbmZvKHByaXYtPmRldiwgIldyaXRpbmcgdGhlIGltYWdlIHRvIHRoZSBmbGFzaCBhdCBh ZGRyZXNzICgleClcbiIsIGltYWdlX2FkZHJlc3MpOworCXJldCA9IG10ZF93cml0ZShwcml2LT5m bGFzaCwgKGxvZmZfdClpbWFnZV9hZGRyZXNzLCBjb3VudCwgJmJ5dGVzX3dyaXR0ZW4sIGJ1Zik7 CisJaWYgKHJldCkKKwkJZ290byBvdXQ7CisKKwlpZiAoYnl0ZXNfd3JpdHRlbiAhPSBjb3VudCkK KwkJcmV0ID0gLUVJTzsKKworb3V0OgorCWRldm1fa2ZyZWUocHJpdi0+ZGV2LCBidWZmZXIpOwor CXJldHVybiByZXQ7Cit9CisKK3N0YXRpYyBpbnQgbXBmc19hdXRvX3VwZGF0ZV93cml0ZV9jb21w bGV0ZShzdHJ1Y3QgZnBnYV9tYW5hZ2VyICptZ3IsIHN0cnVjdCBmcGdhX2ltYWdlX2luZm8gKmlu Zm8pCit7CisJc3RydWN0IG1wZnNfYXV0b191cGRhdGVfcHJpdiAqcHJpdiA9IG1nci0+cHJpdjsK KwlzdHJ1Y3QgbXBmc19tc3NfcmVzcG9uc2UgKnJlc3BvbnNlOworCXN0cnVjdCBtcGZzX21zc19t c2cgKm1lc3NhZ2U7CisJdTMyICpyZXNwb25zZV9tc2c7CisJaW50IHJldDsKKworCXJlc3BvbnNl X21zZyA9IGRldm1fa3phbGxvYyhwcml2LT5kZXYsIEFVVE9fVVBEQVRFX0ZFQVRVUkVfUkVTUF9T SVpFICogc2l6ZW9mKHJlc3BvbnNlX21zZyksCisJCQkJICAgIEdGUF9LRVJORUwpOworCWlmICgh cmVzcG9uc2VfbXNnKQorCQlyZXR1cm4gLUVOT01FTTsKKworCXJlc3BvbnNlID0gZGV2bV9remFs bG9jKHByaXYtPmRldiwgc2l6ZW9mKHN0cnVjdCBtcGZzX21zc19yZXNwb25zZSksIEdGUF9LRVJO RUwpOworCWlmICghcmVzcG9uc2UpIHsKKwkJcmV0ID0gLUVOT01FTTsKKwkJZ290byBmcmVlX3Jl c3BvbnNlX21zZzsKKwl9CisKKwltZXNzYWdlID0gZGV2bV9remFsbG9jKHByaXYtPmRldiwgc2l6 ZW9mKHN0cnVjdCBtcGZzX21zc19tc2cpLCBHRlBfS0VSTkVMKTsKKwlpZiAoIW1lc3NhZ2UpIHsK KwkJcmV0ID0gLUVOT01FTTsKKwkJZ290byBmcmVlX3Jlc3BvbnNlOworCX0KKworCS8qCisJICog VGhlIHN5c3RlbSBjb250cm9sbGVyIGNhbiB2ZXJpZnkgdGhhdCBhbiBpbWFnZSBpbiB0aGUgZmxh c2ggaXMgdmFsaWQuCisJICogUmF0aGVyIHRoYW4gZHVwbGljYXRlIHRoZSBjaGVjayBpbiB0aGlz IGRyaXZlciwgY2FsbCB0aGUgcmVsZXZhbnQKKwkgKiBzZXJ2aWNlIGZyb20gdGhlIHN5c3RlbSBj b250cm9sbGVyIGluc3RlYWQuCisJICogVGhpcyBzZXJ2aWNlIGhhcyBubyBjb21tYW5kIGRhdGEg YW5kIG5vIHJlc3BvbnNlIGRhdGEuIEl0IG92ZXJsb2FkcworCSAqIG1ib3hfb2Zmc2V0IHdpdGgg dGhlIGltYWdlIGluZGV4IGluIHRoZSBmbGFzaCdzIFNQSSBkaXJlY3Rvcnkgd2hlcmUKKwkgKiB0 aGUgYml0c3RyZWFtIGlzIGxvY2F0ZWQuCisJICovCisJcmVzcG9uc2UtPnJlc3BfbXNnID0gcmVz cG9uc2VfbXNnOworCXJlc3BvbnNlLT5yZXNwX3NpemUgPSBBVVRPX1VQREFURV9BVVRIRU5USUNB VEVfUkVTUF9TSVpFOworCW1lc3NhZ2UtPmNtZF9vcGNvZGUgPSBBVVRPX1VQREFURV9BVVRIRU5U SUNBVEVfQ01EX09QQ09ERTsKKwltZXNzYWdlLT5jbWRfZGF0YV9zaXplID0gQVVUT19VUERBVEVf QVVUSEVOVElDQVRFX0NNRF9EQVRBX1NJWkU7CisJbWVzc2FnZS0+cmVzcG9uc2UgPSByZXNwb25z ZTsKKwltZXNzYWdlLT5jbWRfZGF0YSA9IEFVVE9fVVBEQVRFX0FVVEhFTlRJQ0FURV9DTURfREFU QTsKKwltZXNzYWdlLT5tYm94X29mZnNldCA9IEFVVE9fVVBEQVRFX1VQR1JBREVfSU5ERVg7CisJ bWVzc2FnZS0+cmVzcF9vZmZzZXQgPSBBVVRPX1VQREFURV9ERUZBVUxUX1JFU1BfT0ZGU0VUOwor CisJZGV2X2luZm8ocHJpdi0+ZGV2LCAiUnVubmluZyB2ZXJpZmljYXRpb24gb2YgVXBncmFkZSBJ bWFnZVxuIik7CisJcmV0ID0gbXBmc19ibG9ja2luZ190cmFuc2FjdGlvbihwcml2LT5zeXNfY29u dHJvbGxlciwgbWVzc2FnZSk7CisJaWYgKHJldCB8IHJlc3BvbnNlLT5yZXNwX3N0YXR1cykgewor CQlkZXZfd2Fybihwcml2LT5kZXYsICJWZXJpZmljYXRpb24gb2YgVXBncmFkZSBJbWFnZSBmYWls ZWQhXG4iKTsKKwkJcmV0ID0gcmV0ID8gcmV0IDogLUVCQURNU0c7CisJfQorCisJZGV2X2luZm8o cHJpdi0+ZGV2LCAiVmVyaWZpY2F0aW9uIG9mIFVwZ3JhZGUgSW1hZ2UgcGFzc2VkIVxuIik7Cisv LwkvKgorLy8JICogSWYgdGhlIHZhbGlkYXRpb24gaGFzIHBhc3NlZCwgaW5pdGlhdGUgQXV0byBV cGRhdGUuCisvLwkgKiBUaGlzIHNlcnZpY2UgaGFzIG5vIGNvbW1hbmQgZGF0YSBhbmQgbm8gcmVz cG9uc2UgZGF0YS4gSXQgb3ZlcmxvYWRzCisvLwkgKiBtYm94X29mZnNldCB3aXRoIHRoZSBpbWFn ZSBpbmRleCBpbiB0aGUgZmxhc2gncyBTUEkgZGlyZWN0b3J5IHdoZXJlCisvLwkgKiB0aGUgYml0 c3RyZWFtIGlzIGxvY2F0ZWQuCisvLwkgKiBPbmNlIHdlIGF0dGVtcHQgQXV0byBVcGRhdGUgZWl0 aGVyOgorLy8JICogLSBpdCBwYXNzZXMgYW5kIHRoZSBib2FyZCByZWJvb3RzCisvLwkgKiAtIGl0 IGZhaWxzIGFuZCB0aGUgYm9hcmQgcmVib290cyB0byByZWNvdmVyCisvLwkgKiAtIHRoZSBzeXN0 ZW0gY29udHJvbGxlciBhYm9ydHMgYW5kIHdlIGV4aXQgImdyYWNlZnVsbHkiLgorLy8JICogICAi Z3JhY2VmdWxseSIgc2luY2UgdGhlcmUgaXMgbm8gaW50ZXJydXB0IHByb2R1Y2VkICYgaXQganVz dCB0aW1lcworLy8JICogICBvdXQuCisvLwkgKi8KKy8vCXJlc3BvbnNlLT5yZXNwX21zZyA9IHJl c3BvbnNlX21zZzsKKy8vCXJlc3BvbnNlLT5yZXNwX3NpemUgPSBBVVRPX1VQREFURV9QUk9HUkFN X1JFU1BfU0laRTsKKy8vCW1lc3NhZ2UtPmNtZF9vcGNvZGUgPSBBVVRPX1VQREFURV9QUk9HUkFN X0NNRF9PUENPREU7CisvLwltZXNzYWdlLT5jbWRfZGF0YV9zaXplID0gQVVUT19VUERBVEVfUFJP R1JBTV9DTURfREFUQV9TSVpFOworLy8JbWVzc2FnZS0+cmVzcG9uc2UgPSByZXNwb25zZTsKKy8v CW1lc3NhZ2UtPmNtZF9kYXRhID0gQVVUT19VUERBVEVfUFJPR1JBTV9DTURfREFUQTsKKy8vCW1l c3NhZ2UtPm1ib3hfb2Zmc2V0ID0gMDsgLy9maWVsZCBpcyBpZ25vcmVkCisvLwltZXNzYWdlLT5y ZXNwX29mZnNldCA9IEFVVE9fVVBEQVRFX0RFRkFVTFRfUkVTUF9PRkZTRVQ7CisvLworLy8JZGV2 X2luZm8ocHJpdi0+ZGV2LCAiUnVubmluZyBBdXRvIFVwZGF0ZSBjb21tYW5kXG4iKTsKKy8vCXJl dCA9IG1wZnNfYmxvY2tpbmdfdHJhbnNhY3Rpb24ocHJpdi0+c3lzX2NvbnRyb2xsZXIsIG1lc3Nh Z2UpOworLy8JaWYgKHJldCAmJiByZXQgIT0gLUVUSU1FRE9VVCkKKy8vCQlnb3RvIG91dDsKKy8v CisvLwkvKiAqcmVtb3ZlIHRoaXMgZm9yIGF1dG8gdXBkYXRlKgorLy8JICogVGhpcyByZXR1cm4g MCBpcyBkZWFkIGNvZGUuIEVpdGhlciB0aGUgQXV0byBVcGRhdGUgd2lsbCBmYWlsLCBvciBpdCB3 aWxsIHBhc3MKKy8vCSAqICYgdGhlIEZQR0Egd2lsbCBiZSByZWJvb3RlZCBpbiB3aGljaCBjYXNl IG1wZnNfYmxvY2tpbmdfdHJhbnNhY3Rpb24oKQorLy8JICogd2lsbCBuZXZlciByZXR1cm4gYW5k IExpbnV4IHdpbGwgZGllLgorLy8JICovCisvLwlyZXR1cm4gMDsKKworCWRldm1fa2ZyZWUocHJp di0+ZGV2LCBtZXNzYWdlKTsKK2ZyZWVfcmVzcG9uc2U6CisJZGV2bV9rZnJlZShwcml2LT5kZXYs IHJlc3BvbnNlKTsKK2ZyZWVfcmVzcG9uc2VfbXNnOgorCWRldm1fa2ZyZWUocHJpdi0+ZGV2LCBy ZXNwb25zZV9tc2cpOworCisJcmV0dXJuIHJldDsKK30KKworc3RhdGljIGNvbnN0IHN0cnVjdCBm cGdhX21hbmFnZXJfb3BzIG1wZnNfYXV0b191cGRhdGVfb3BzID0geworCS5zdGF0ZSA9IG1wZnNf YXV0b191cGRhdGVfc3RhdGUsCisJLndyaXRlX2luaXQgPSBtcGZzX2F1dG9fdXBkYXRlX3dyaXRl X2luaXQsCisJLndyaXRlID0gbXBmc19hdXRvX3VwZGF0ZV93cml0ZSwKKwkud3JpdGVfY29tcGxl dGUgPSBtcGZzX2F1dG9fdXBkYXRlX3dyaXRlX2NvbXBsZXRlLAorfTsKKworc3RhdGljIGludCBt cGZzX2F1dG9fdXBkYXRlX3J1bihzdHJ1Y3QgZGV2aWNlICpkZXYpCit7CisJc3RydWN0IGZwZ2Ff bWFuYWdlciAqbWdyOworCXN0cnVjdCBmcGdhX2ltYWdlX2luZm8gKmluZm87CisJaW50IHJldDsK KworCW1nciA9IGZwZ2FfbWdyX2dldChkZXYpOworCWluZm8gPSBmcGdhX2ltYWdlX2luZm9fYWxs b2MoZGV2KTsKKworCWluZm8tPmZpcm13YXJlX25hbWUgPSBkZXZtX2tzdHJkdXAoZGV2LCAibXBm c19iaXRzdHJlYW0uc3BpIiwgR0ZQX0tFUk5FTCk7CisKKwlyZXQgPSBmcGdhX21ncl9sb2NrKG1n cik7CisJaWYgKHJldCkKKwkJZ290byBmcmVlX2luZm87CisKKwlyZXQgPSBmcGdhX21ncl9sb2Fk KG1nciwgaW5mbyk7CisJaWYgKHJldCkgeworCQlkZXZfZXJyKGRldiwgIkZhaWxlZCB0byB3cml0 ZSB0aGUgYml0c3RyZWFtXG4iKTsKKwkJZ290byB1bmxvY2tfbWdyOworCX0KKwordW5sb2NrX21n cjoKKwlmcGdhX21ncl91bmxvY2sobWdyKTsKK2ZyZWVfaW5mbzoKKwlmcGdhX2ltYWdlX2luZm9f ZnJlZShpbmZvKTsKKwlmcGdhX21ncl9wdXQobWdyKTsKKworCXJldHVybiByZXQ7Cit9CisKK3N0 YXRpYyBzc2l6ZV90IG1wZnNfYXV0b191cGRhdGVfZXhlYyhzdHJ1Y3QgZmlsZSAqZmlsZSwgY29u c3QgY2hhciBfX3VzZXIgKmRhdGEsIHNpemVfdCBjb3VudCwKKwkJCQkgICAgIGxvZmZfdCAqcHBv cykKK3sKKwlpbnQgcmV0OworCisJcmV0ID0gbXBmc19hdXRvX3VwZGF0ZV9ydW4obXBmc19hdXRv X3VwZGF0ZV9kZWJ1Z19kZXYpOworCWlmIChyZXQpCisJCWRldl9lcnJfcHJvYmUobXBmc19hdXRv X3VwZGF0ZV9kZWJ1Z19kZXYsIHJldCwgIkF1dG8gVXBkYXRlIGZhaWxlZCIpOworCisJcmV0dXJu IGNvdW50OworfQorCitzdGF0aWMgY29uc3Qgc3RydWN0IGZpbGVfb3BlcmF0aW9ucyBtcGZzX2F1 dG9fdXBkYXRlX2ZvcHMgPSB7CisJLm93bmVyID0gVEhJU19NT0RVTEUsCisJLm9wZW4gPSBzaW1w bGVfb3BlbiwKKwkud3JpdGUgPSBtcGZzX2F1dG9fdXBkYXRlX2V4ZWMKK307CisKK3N0YXRpYyBp bnQgbXBmc19hdXRvX3VwZGF0ZV9kZWJ1Z2ZzX3NldHVwKHN0cnVjdCBtcGZzX2F1dG9fdXBkYXRl X3ByaXYgKnByaXYpCit7CisJcHJpdi0+ZGVidWdmc19kaXIgPSBkZWJ1Z2ZzX2NyZWF0ZV9kaXIo ImZwZ2EiLCBOVUxMKTsKKworCWlmKElTX0VSUihwcml2LT5kZWJ1Z2ZzX2RpcikpCisJCXJldHVy biBQVFJfRVJSKHByaXYtPmRlYnVnZnNfZGlyKTsKKworCWRlYnVnZnNfY3JlYXRlX2ZpbGUoIm1p Y3JvY2hpcF9leGVjX3VwZGF0ZSIsIDAyMDAsIHByaXYtPmRlYnVnZnNfZGlyLCBOVUxMLAorCQkJ ICAgICZtcGZzX2F1dG9fdXBkYXRlX2ZvcHMpOworCisJcmV0dXJuIDA7Cit9CisKK3N0YXRpYyBp bnQgbXBmc19hdXRvX3VwZGF0ZV9wcm9iZShzdHJ1Y3QgcGxhdGZvcm1fZGV2aWNlICpwZGV2KQor eworCXN0cnVjdCBkZXZpY2UgKmRldiA9ICZwZGV2LT5kZXY7CisJc3RydWN0IG1wZnNfYXV0b191 cGRhdGVfcHJpdiAqcHJpdjsKKwlzdHJ1Y3QgZnBnYV9tYW5hZ2VyICptZ3I7CisJZW51bSBmcGdh X21ncl9zdGF0ZXMgc3RhdGU7CisJaW50IHJldDsKKworCXByaXYgPSBkZXZtX2t6YWxsb2MoZGV2 LCBzaXplb2YoKnByaXYpLCBHRlBfS0VSTkVMKTsKKwlpZiAoIXByaXYpCisJCXJldHVybiAtRU5P TUVNOworCisJcHJpdi0+c3lzX2NvbnRyb2xsZXIgPSBtcGZzX3N5c19jb250cm9sbGVyX2dldChk ZXYpOworCWlmIChJU19FUlIocHJpdi0+c3lzX2NvbnRyb2xsZXIpKQorCQlyZXR1cm4gZGV2X2Vy cl9wcm9iZShkZXYsIFBUUl9FUlIocHJpdi0+c3lzX2NvbnRyb2xsZXIpLAorCQkJCSAgICAgIkNv dWxkIG5vdCByZWdpc3RlciBhcyBhIHN1YiBkZXZpY2Ugb2YgdGhlIHN5c3RlbSBjb250cm9sbGVy XG4iKTsKKworCXByaXYtPmRldiA9IGRldjsKKwlwbGF0Zm9ybV9zZXRfZHJ2ZGF0YShwZGV2LCBw cml2KTsKKworCW1nciA9IGRldm1fZnBnYV9tZ3JfcmVnaXN0ZXIoZGV2LCAiTWljcm9jaGlwIE1Q RlMgQXV0byBVcGRhdGUgRlBHQSBNYW5hZ2VyIiwKKwkJCQkgICAgICZtcGZzX2F1dG9fdXBkYXRl X29wcywgcHJpdik7CisJaWYgKElTX0VSUihtZ3IpKQorCQlyZXR1cm4gZGV2X2Vycl9wcm9iZShk ZXYsIFBUUl9FUlIobWdyKSwgIkNvdWxkIG5vdCByZWdpc3RlciBGUEdBIG1hbmFnZXIuXG4iKTsK KworCXN0YXRlID0gbXBmc19hdXRvX3VwZGF0ZV9zdGF0ZShtZ3IpOworCWlmIChzdGF0ZSAhPSBG UEdBX01HUl9TVEFURV9PUEVSQVRJTkcpCisJCXJldHVybiAtRUlPOworCisJcmV0ID0gbXBmc19h dXRvX3VwZGF0ZV9kZWJ1Z2ZzX3NldHVwKHByaXYpOworCWlmIChyZXQgJiYgcmV0ICE9IC1FTk9E RVYpCisJCXJldHVybiByZXQ7CisKKwltcGZzX2F1dG9fdXBkYXRlX2RlYnVnX2RldiA9IHByaXYt PmRldjsKKworCXJldHVybiAwOworfQorCitzdGF0aWMgc3RydWN0IHBsYXRmb3JtX2RyaXZlciBt cGZzX2F1dG9fdXBkYXRlX2RyaXZlciA9IHsKKwkuZHJpdmVyID0geworCQkubmFtZSA9ICJtcGZz LWF1dG8tdXBkYXRlIiwKKwl9LAorCS5wcm9iZSA9IG1wZnNfYXV0b191cGRhdGVfcHJvYmUsCit9 OworbW9kdWxlX3BsYXRmb3JtX2RyaXZlcihtcGZzX2F1dG9fdXBkYXRlX2RyaXZlcik7CisKK01P RFVMRV9MSUNFTlNFKCJHUEwiKTsKK01PRFVMRV9BVVRIT1IoIkNvbm9yIERvb2xleSA8Y29ub3Iu ZG9vbGV5QG1pY3JvY2hpcC5jb20+Iik7CitNT0RVTEVfREVTQ1JJUFRJT04oIlBvbGFyRmlyZSBT b0MgQXV0byBVcGRhdGUgRlBHQSByZXByb2dyYW1taW5nIik7Ci0tIAoyLjM5LjEKCgpfX19fX19f X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fXwpsaW51eC1yaXNjdiBtYWls aW5nIGxpc3QKbGludXgtcmlzY3ZAbGlzdHMuaW5mcmFkZWFkLm9yZwpodHRwOi8vbGlzdHMuaW5m cmFkZWFkLm9yZy9tYWlsbWFuL2xpc3RpbmZvL2xpbnV4LXJpc2N2Cg==