From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail.bootlin.com ([62.4.15.54]) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1g9brt-0006Ca-0p for linux-mtd@lists.infradead.org; Mon, 08 Oct 2018 20:12:11 +0000 From: Boris Brezillon To: David Woodhouse , Brian Norris , Boris Brezillon , Marek Vasut , Richard Weinberger , linux-mtd@lists.infradead.org Cc: Rob Herring , Pawel Moll , Mark Rutland , Ian Campbell , Kumar Gala , devicetree@vger.kernel.org, Ricardo Ribalda Delgado Subject: [PATCH 12/14] mtd: maps: Merge gpio-addr-flash.c into physmap-core.c Date: Mon, 8 Oct 2018 22:10:25 +0200 Message-Id: <20181008201027.17952-13-boris.brezillon@bootlin.com> In-Reply-To: <20181008201027.17952-1-boris.brezillon@bootlin.com> References: <20181008201027.17952-1-boris.brezillon@bootlin.com> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit List-Id: Linux MTD discussion mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Controlling some MSB address lines using GPIOs is just a small deviation of the generic physmap logic, and merging those two drivers allows us to share most of the probe logic, which is a good thing. Signed-off-by: Boris Brezillon --- drivers/mtd/maps/Kconfig | 19 ++- drivers/mtd/maps/Makefile | 1 - drivers/mtd/maps/gpio-addr-flash.c | 281 ------------------------------------- drivers/mtd/maps/physmap-core.c | 150 +++++++++++++++++++- 4 files changed, 157 insertions(+), 294 deletions(-) delete mode 100644 drivers/mtd/maps/gpio-addr-flash.c diff --git a/drivers/mtd/maps/Kconfig b/drivers/mtd/maps/Kconfig index 5bffebacce86..4fd13d76b7b5 100644 --- a/drivers/mtd/maps/Kconfig +++ b/drivers/mtd/maps/Kconfig @@ -94,6 +94,15 @@ config MTD_PHYSMAP_OF_GEMINI platforms, some detection and setting up parallel mode on the external interface. +config MTD_PHYSMAP_GPIO_ADDR + bool "GPIO-assisted Flash Chip Support" + depends on MTD_PHYSMAP + depends on GPIOLIB || COMPILE_TEST + depends on MTD_COMPLEX_MAPPINGS + help + Extend the physmap driver to allow flashes to be partially + physically addressed and assisted by GPIOs. + config MTD_PMC_MSP_EVM tristate "CFI Flash device mapped on PMC-Sierra MSP" depends on PMC_MSP && MTD_CFI @@ -334,16 +343,6 @@ config MTD_PCMCIA_ANONYMOUS If unsure, say N. -config MTD_GPIO_ADDR - tristate "GPIO-assisted Flash Chip Support" - depends on GPIOLIB || COMPILE_TEST - depends on MTD_COMPLEX_MAPPINGS - help - Map driver which allows flashes to be partially physically addressed - and assisted by GPIOs. - - If compiled as a module, it will be called gpio-addr-flash. - config MTD_UCLINUX bool "Generic uClinux RAM/ROM filesystem support" depends on (MTD_RAM=y || MTD_ROM=y) && (!MMU || COLDFIRE) diff --git a/drivers/mtd/maps/Makefile b/drivers/mtd/maps/Makefile index ad32b185a120..acec0fbfa18d 100644 --- a/drivers/mtd/maps/Makefile +++ b/drivers/mtd/maps/Makefile @@ -43,6 +43,5 @@ obj-$(CONFIG_MTD_PLATRAM) += plat-ram.o obj-$(CONFIG_MTD_INTEL_VR_NOR) += intel_vr_nor.o obj-$(CONFIG_MTD_RBTX4939) += rbtx4939-flash.o obj-$(CONFIG_MTD_VMU) += vmu-flash.o -obj-$(CONFIG_MTD_GPIO_ADDR) += gpio-addr-flash.o obj-$(CONFIG_MTD_LATCH_ADDR) += latch-addr-flash.o obj-$(CONFIG_MTD_LANTIQ) += lantiq-flash.o diff --git a/drivers/mtd/maps/gpio-addr-flash.c b/drivers/mtd/maps/gpio-addr-flash.c deleted file mode 100644 index a20e85aa770e..000000000000 --- a/drivers/mtd/maps/gpio-addr-flash.c +++ /dev/null @@ -1,281 +0,0 @@ -/* - * drivers/mtd/maps/gpio-addr-flash.c - * - * Handle the case where a flash device is mostly addressed using physical - * line and supplemented by GPIOs. This way you can hook up say a 8MiB flash - * to a 2MiB memory range and use the GPIOs to select a particular range. - * - * Copyright © 2000 Nicolas Pitre - * Copyright © 2005-2009 Analog Devices Inc. - * - * Enter bugs at http://blackfin.uclinux.org/ - * - * Licensed under the GPL-2 or later. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define win_mask(x) ((BIT(x)) - 1) - -#define DRIVER_NAME "gpio-addr-flash" - -/** - * struct async_state - keep GPIO flash state - * @mtd: MTD state for this mapping - * @map: MTD map state for this flash - * @gpios: Struct containing the array of GPIO descriptors - * @gpio_values: cached GPIO values - * @win_order: dedicated memory size (if no GPIOs) - */ -struct async_state { - struct mtd_info *mtd; - struct map_info map; - struct gpio_descs *gpios; - unsigned int gpio_values; - unsigned int win_order; -}; -#define gf_map_info_to_state(mi) ((struct async_state *)(mi)->map_priv_1) - -/** - * gf_set_gpios() - set GPIO address lines to access specified flash offset - * @state: GPIO flash state - * @ofs: desired offset to access - * - * Rather than call the GPIO framework every time, cache the last-programmed - * value. This speeds up sequential accesses (which are by far the most common - * type). - */ -static void gf_set_gpios(struct async_state *state, unsigned long ofs) -{ - int i; - - ofs >>= state->win_order; - - if (ofs == state->gpio_values) - return; - - for (i = 0; i < state->gpios->ndescs; i++) { - if ((ofs & BIT(i)) == (state->gpio_values & BIT(i))) - continue; - - gpiod_set_value(state->gpios->desc[i], !!(ofs & BIT(i))); - } - - state->gpio_values = ofs; -} - -/** - * gf_read() - read a word at the specified offset - * @map: MTD map state - * @ofs: desired offset to read - */ -static map_word gf_read(struct map_info *map, unsigned long ofs) -{ - struct async_state *state = gf_map_info_to_state(map); - uint16_t word; - map_word test; - - gf_set_gpios(state, ofs); - - word = readw(map->virt + (ofs & win_mask(state->win_order))); - test.x[0] = word; - return test; -} - -/** - * gf_copy_from() - copy a chunk of data from the flash - * @map: MTD map state - * @to: memory to copy to - * @from: flash offset to copy from - * @len: how much to copy - * - * The "from" region may straddle more than one window, so toggle the GPIOs for - * each window region before reading its data. - */ -static void gf_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len) -{ - struct async_state *state = gf_map_info_to_state(map); - - int this_len; - - while (len) { - this_len = from & win_mask(state->win_order); - this_len = BIT(state->win_order) - this_len; - this_len = min_t(int, len, this_len); - - gf_set_gpios(state, from); - memcpy_fromio(to, - map->virt + (from & win_mask(state->win_order)), - this_len); - len -= this_len; - from += this_len; - to += this_len; - } -} - -/** - * gf_write() - write a word at the specified offset - * @map: MTD map state - * @ofs: desired offset to write - */ -static void gf_write(struct map_info *map, map_word d1, unsigned long ofs) -{ - struct async_state *state = gf_map_info_to_state(map); - uint16_t d; - - gf_set_gpios(state, ofs); - - d = d1.x[0]; - writew(d, map->virt + (ofs & win_mask(state->win_order))); -} - -/** - * gf_copy_to() - copy a chunk of data to the flash - * @map: MTD map state - * @to: flash offset to copy to - * @from: memory to copy from - * @len: how much to copy - * - * See gf_copy_from() caveat. - */ -static void gf_copy_to(struct map_info *map, unsigned long to, - const void *from, ssize_t len) -{ - struct async_state *state = gf_map_info_to_state(map); - - int this_len; - - while (len) { - this_len = to & win_mask(state->win_order); - this_len = BIT(state->win_order) - this_len; - this_len = min_t(int, len, this_len); - - gf_set_gpios(state, to); - memcpy_toio(map->virt + (to & win_mask(state->win_order)), - from, len); - - len -= this_len; - to += this_len; - from += this_len; - } -} - -static const char * const part_probe_types[] = { - "cmdlinepart", "RedBoot", NULL }; - -/** - * gpio_flash_probe() - setup a mapping for a GPIO assisted flash - * @pdev: platform device - * - * The platform resource layout expected looks something like: - * struct mtd_partition partitions[] = { ... }; - * struct physmap_flash_data flash_data = { ... }; - * static struct gpiod_lookup_table addr_flash_gpios = { - * .dev_id = "gpio-addr-flash.0", - * .table = { - * GPIO_LOOKUP_IDX("gpio.0", 15, "addr", 0, GPIO_ACTIVE_HIGH), - * GPIO_LOOKUP_IDX("gpio.0", 16, "addr", 1, GPIO_ACTIVE_HIGH), - * ); - * }; - * gpiod_add_lookup_table(&addr_flash_gpios); - * - * struct resource flash_resource[] = { - * { - * .name = "cfi_probe", - * .start = 0x20000000, - * .end = 0x201fffff, - * .flags = IORESOURCE_MEM, - * }, - * }; - * struct platform_device flash_device = { - * .name = "gpio-addr-flash", - * .dev = { .platform_data = &flash_data, }, - * .num_resources = ARRAY_SIZE(flash_resource), - * .resource = flash_resource, - * ... - * }; - */ -static int gpio_flash_probe(struct platform_device *pdev) -{ - struct physmap_flash_data *pdata; - struct resource *memory; - struct async_state *state; - - pdata = dev_get_platdata(&pdev->dev); - memory = platform_get_resource(pdev, IORESOURCE_MEM, 0); - - if (!memory) - return -EINVAL; - - state = devm_kzalloc(&pdev->dev, sizeof(*state), GFP_KERNEL); - if (!state) - return -ENOMEM; - - state->gpios = devm_gpiod_get_array(&pdev->dev, "addr", GPIOD_OUT_LOW); - if (IS_ERR(state->gpios)) - return PTR_ERR(state->gpios); - - state->win_order = get_bitmask_order(resource_size(memory)) - 1; - - state->map.name = DRIVER_NAME; - state->map.read = gf_read; - state->map.copy_from = gf_copy_from; - state->map.write = gf_write; - state->map.copy_to = gf_copy_to; - state->map.bankwidth = pdata->width; - state->map.size = BIT(state->win_order + state->gpios->ndescs); - state->map.virt = devm_ioremap_resource(&pdev->dev, memory); - if (IS_ERR(state->map.virt)) - return PTR_ERR(state->map.virt); - - state->map.phys = NO_XIP; - state->map.map_priv_1 = (unsigned long)state; - - platform_set_drvdata(pdev, state); - - dev_notice(&pdev->dev, "probing %d-bit flash bus\n", - state->map.bankwidth * 8); - state->mtd = do_map_probe(memory->name, &state->map); - if (!state->mtd) - return -ENXIO; - state->mtd->dev.parent = &pdev->dev; - - mtd_device_parse_register(state->mtd, part_probe_types, NULL, - pdata->parts, pdata->nr_parts); - - return 0; -} - -static int gpio_flash_remove(struct platform_device *pdev) -{ - struct async_state *state = platform_get_drvdata(pdev); - - mtd_device_unregister(state->mtd); - map_destroy(state->mtd); - return 0; -} - -static struct platform_driver gpio_flash_driver = { - .probe = gpio_flash_probe, - .remove = gpio_flash_remove, - .driver = { - .name = DRIVER_NAME, - }, -}; - -module_platform_driver(gpio_flash_driver); - -MODULE_AUTHOR("Mike Frysinger "); -MODULE_DESCRIPTION("MTD map driver for flashes addressed physically and with gpios"); -MODULE_LICENSE("GPL"); diff --git a/drivers/mtd/maps/physmap-core.c b/drivers/mtd/maps/physmap-core.c index 7a50ff9ef812..2dc33ae71335 100644 --- a/drivers/mtd/maps/physmap-core.c +++ b/drivers/mtd/maps/physmap-core.c @@ -13,6 +13,14 @@ * * Revised to handle newer style flash binding by: * Copyright (C) 2007 David Gibson, IBM Corporation. + * + * GPIO address extension: + * Handle the case where a flash device is mostly addressed using physical + * line and supplemented by GPIOs. This way you can hook up say a 8MiB flash + * to a 2MiB memory range and use the GPIOs to select a particular range. + * + * Copyright © 2000 Nicolas Pitre + * Copyright © 2005-2009 Analog Devices Inc. */ #include @@ -30,6 +38,7 @@ #include #include #include +#include #include "physmap_of_gemini.h" #include "physmap_of_versatile.h" @@ -45,6 +54,9 @@ struct physmap_flash_info { const char * const *part_types; unsigned int nparts; const struct mtd_partition *parts; + struct gpio_descs *gpios; + unsigned int gpio_values; + unsigned int win_order; }; static int physmap_flash_remove(struct platform_device *dev) @@ -104,6 +116,119 @@ static void physmap_set_vpp(struct map_info *map, int state) spin_unlock_irqrestore(&info->vpp_lock, flags); } +#if IS_ENABLED(CONFIG_MTD_PHYSMAP_GPIO_ADDR) +static void physmap_set_addr_gpios(struct physmap_flash_info *info, + unsigned long ofs) +{ + unsigned int i; + + ofs >>= info->win_order; + if (info->gpio_values == ofs) + return; + + for (i = 0; i < info->gpios->ndescs; i++) { + if ((BIT(i) & ofs) == (BIT(i) & info->gpio_values)) + continue; + + gpiod_set_value(info->gpios->desc[i], !!(BIT(i) & ofs)); + } +} + +#define win_mask(order) (BIT(order) - 1) + +static map_word physmap_addr_gpios_read(struct map_info *map, + unsigned long ofs) +{ + struct platform_device *pdev; + struct physmap_flash_info *info; + map_word mw; + u16 word; + + pdev = (struct platform_device *)map->map_priv_1; + info = platform_get_drvdata(pdev); + physmap_set_addr_gpios(info, ofs); + + word = readw(map->virt + (ofs & win_mask(info->win_order))); + mw.x[0] = word; + return mw; +} + +static void physmap_addr_gpios_copy_from(struct map_info *map, void *buf, + unsigned long ofs, ssize_t len) +{ + struct platform_device *pdev; + struct physmap_flash_info *info; + + pdev = (struct platform_device *)map->map_priv_1; + info = platform_get_drvdata(pdev); + + while (len) { + unsigned int winofs = ofs & win_mask(info->win_order); + unsigned int chunklen = min_t(unsigned int, len, + BIT(info->win_order) - winofs); + + physmap_set_addr_gpios(info, ofs); + memcpy_fromio(buf, map->virt + winofs, chunklen); + len -= chunklen; + buf += chunklen; + ofs += chunklen; + } +} + +static void physmap_addr_gpios_write(struct map_info *map, map_word mw, + unsigned long ofs) +{ + struct platform_device *pdev; + struct physmap_flash_info *info; + u16 word; + + pdev = (struct platform_device *)map->map_priv_1; + info = platform_get_drvdata(pdev); + physmap_set_addr_gpios(info, ofs); + + word = mw.x[0]; + writew(word, map->virt + (ofs & win_mask(info->win_order))); +} + +static void physmap_addr_gpios_copy_to(struct map_info *map, unsigned long ofs, + const void *buf, ssize_t len) +{ + struct platform_device *pdev; + struct physmap_flash_info *info; + + pdev = (struct platform_device *)map->map_priv_1; + info = platform_get_drvdata(pdev); + + while (len) { + unsigned int winofs = ofs & win_mask(info->win_order); + unsigned int chunklen = min_t(unsigned int, len, + BIT(info->win_order) - winofs); + + physmap_set_addr_gpios(info, ofs); + memcpy_toio(map->virt + winofs, buf, chunklen); + len -= chunklen; + buf += chunklen; + ofs += chunklen; + } +} + +static int physmap_addr_gpios_map_init(struct map_info *map) +{ + map->phys = NO_XIP; + map->read = physmap_addr_gpios_read; + map->copy_from = physmap_addr_gpios_copy_from; + map->write = physmap_addr_gpios_write; + map->copy_to = physmap_addr_gpios_copy_to; + + return 0; +} +#else +static int physmap_addr_gpios_map_init(struct map_info *map) +{ + return -ENOTSUPP; +} +#endif + #if IS_ENABLED(CONFIG_MTD_PHYSMAP_OF) static const struct of_device_id of_flash_match[] = { { @@ -343,6 +468,16 @@ static int physmap_flash_probe(struct platform_device *dev) platform_set_drvdata(dev, info); + info->gpios = devm_gpiod_get_array_optional(&dev->dev, "addr", + GPIOD_OUT_LOW); + if (IS_ERR(info->gpios)) + return PTR_ERR(info->gpios); + + if (info->gpios && info->nmaps > 1) { + dev_err(&dev->dev, "addr-gpios only supported for nmaps == 1\n"); + return -EINVAL; + } + err = physmap_flash_of_init(dev); if (err) err = physmap_flash_pdata_init(dev); @@ -368,10 +503,20 @@ static int physmap_flash_probe(struct platform_device *dev) if (!info->maps[i].phys) info->maps[i].phys = res->start; - info->maps[i].size = resource_size(res); + info->win_order = get_bitmask_order(resource_size(res)) - 1; + info->maps[i].size = BIT(info->win_order + + (info->gpios ? + info->gpios->ndescs : 0)); + info->maps[i].map_priv_1 = (unsigned long)dev; - simple_map_init(&info->maps[i]); + if (info->gpios) { + err = physmap_addr_gpios_map_init(&info->maps[i]); + if (err) + goto err_out; + } else { + simple_map_init(&info->maps[i]); + } probe_type = rom_probe_types; if (!info->probe_type) { @@ -496,6 +641,7 @@ module_exit(physmap_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("David Woodhouse "); MODULE_AUTHOR("Vitaly Wool "); +MODULE_AUTHOR("Mike Frysinger "); MODULE_DESCRIPTION("Generic configurable MTD map driver"); /* legacy platform drivers can't hotplug or coldplg */ -- 2.14.1 From mboxrd@z Thu Jan 1 00:00:00 1970 From: Boris Brezillon Subject: [PATCH 12/14] mtd: maps: Merge gpio-addr-flash.c into physmap-core.c Date: Mon, 8 Oct 2018 22:10:25 +0200 Message-ID: <20181008201027.17952-13-boris.brezillon@bootlin.com> References: <20181008201027.17952-1-boris.brezillon@bootlin.com> Mime-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Return-path: In-Reply-To: <20181008201027.17952-1-boris.brezillon@bootlin.com> List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-mtd" Errors-To: linux-mtd-bounces+gldm-linux-mtd-36=gmane.org@lists.infradead.org To: David Woodhouse , Brian Norris , Boris Brezillon , Marek Vasut , Richard Weinberger , linux-mtd@lists.infradead.org Cc: Mark Rutland , devicetree@vger.kernel.org, Pawel Moll , Ian Campbell , Rob Herring , Kumar Gala , Ricardo Ribalda Delgado List-Id: devicetree@vger.kernel.org Q29udHJvbGxpbmcgc29tZSBNU0IgYWRkcmVzcyBsaW5lcyB1c2luZyBHUElPcyBpcyBqdXN0IGEg c21hbGwKZGV2aWF0aW9uIG9mIHRoZSBnZW5lcmljIHBoeXNtYXAgbG9naWMsIGFuZCBtZXJnaW5n IHRob3NlIHR3byBkcml2ZXJzCmFsbG93cyB1cyB0byBzaGFyZSBtb3N0IG9mIHRoZSBwcm9iZSBs b2dpYywgd2hpY2ggaXMgYSBnb29kIHRoaW5nLgoKU2lnbmVkLW9mZi1ieTogQm9yaXMgQnJlemls bG9uIDxib3Jpcy5icmV6aWxsb25AYm9vdGxpbi5jb20+Ci0tLQogZHJpdmVycy9tdGQvbWFwcy9L Y29uZmlnICAgICAgICAgICB8ICAxOSArKy0KIGRyaXZlcnMvbXRkL21hcHMvTWFrZWZpbGUgICAg ICAgICAgfCAgIDEgLQogZHJpdmVycy9tdGQvbWFwcy9ncGlvLWFkZHItZmxhc2guYyB8IDI4MSAt LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiBkcml2ZXJzL210ZC9tYXBzL3Bo eXNtYXAtY29yZS5jICAgIHwgMTUwICsrKysrKysrKysrKysrKysrKystCiA0IGZpbGVzIGNoYW5n ZWQsIDE1NyBpbnNlcnRpb25zKCspLCAyOTQgZGVsZXRpb25zKC0pCiBkZWxldGUgbW9kZSAxMDA2 NDQgZHJpdmVycy9tdGQvbWFwcy9ncGlvLWFkZHItZmxhc2guYwoKZGlmZiAtLWdpdCBhL2RyaXZl cnMvbXRkL21hcHMvS2NvbmZpZyBiL2RyaXZlcnMvbXRkL21hcHMvS2NvbmZpZwppbmRleCA1YmZm ZWJhY2NlODYuLjRmZDEzZDc2YjdiNSAxMDA2NDQKLS0tIGEvZHJpdmVycy9tdGQvbWFwcy9LY29u ZmlnCisrKyBiL2RyaXZlcnMvbXRkL21hcHMvS2NvbmZpZwpAQCAtOTQsNiArOTQsMTUgQEAgY29u ZmlnIE1URF9QSFlTTUFQX09GX0dFTUlOSQogCSAgcGxhdGZvcm1zLCBzb21lIGRldGVjdGlvbiBh bmQgc2V0dGluZyB1cCBwYXJhbGxlbCBtb2RlIG9uIHRoZQogCSAgZXh0ZXJuYWwgaW50ZXJmYWNl LgogCitjb25maWcgTVREX1BIWVNNQVBfR1BJT19BRERSCisJYm9vbCAiR1BJTy1hc3Npc3RlZCBG bGFzaCBDaGlwIFN1cHBvcnQiCisJZGVwZW5kcyBvbiBNVERfUEhZU01BUAorCWRlcGVuZHMgb24g R1BJT0xJQiB8fCBDT01QSUxFX1RFU1QKKwlkZXBlbmRzIG9uIE1URF9DT01QTEVYX01BUFBJTkdT CisJaGVscAorCSAgRXh0ZW5kIHRoZSBwaHlzbWFwIGRyaXZlciB0byBhbGxvdyBmbGFzaGVzIHRv IGJlIHBhcnRpYWxseQorCSAgcGh5c2ljYWxseSBhZGRyZXNzZWQgYW5kIGFzc2lzdGVkIGJ5IEdQ SU9zLgorCiBjb25maWcgTVREX1BNQ19NU1BfRVZNCiAJdHJpc3RhdGUgIkNGSSBGbGFzaCBkZXZp Y2UgbWFwcGVkIG9uIFBNQy1TaWVycmEgTVNQIgogCWRlcGVuZHMgb24gUE1DX01TUCAmJiBNVERf Q0ZJCkBAIC0zMzQsMTYgKzM0Myw2IEBAIGNvbmZpZyBNVERfUENNQ0lBX0FOT05ZTU9VUwogCiAJ ICBJZiB1bnN1cmUsIHNheSBOLgogCi1jb25maWcgTVREX0dQSU9fQUREUgotCXRyaXN0YXRlICJH UElPLWFzc2lzdGVkIEZsYXNoIENoaXAgU3VwcG9ydCIKLQlkZXBlbmRzIG9uIEdQSU9MSUIgfHwg Q09NUElMRV9URVNUCi0JZGVwZW5kcyBvbiBNVERfQ09NUExFWF9NQVBQSU5HUwotCWhlbHAKLQkg IE1hcCBkcml2ZXIgd2hpY2ggYWxsb3dzIGZsYXNoZXMgdG8gYmUgcGFydGlhbGx5IHBoeXNpY2Fs bHkgYWRkcmVzc2VkCi0JICBhbmQgYXNzaXN0ZWQgYnkgR1BJT3MuCi0KLQkgIElmIGNvbXBpbGVk IGFzIGEgbW9kdWxlLCBpdCB3aWxsIGJlIGNhbGxlZCBncGlvLWFkZHItZmxhc2guCi0KIGNvbmZp ZyBNVERfVUNMSU5VWAogCWJvb2wgIkdlbmVyaWMgdUNsaW51eCBSQU0vUk9NIGZpbGVzeXN0ZW0g c3VwcG9ydCIKIAlkZXBlbmRzIG9uIChNVERfUkFNPXkgfHwgTVREX1JPTT15KSAmJiAoIU1NVSB8 fCBDT0xERklSRSkKZGlmZiAtLWdpdCBhL2RyaXZlcnMvbXRkL21hcHMvTWFrZWZpbGUgYi9kcml2 ZXJzL210ZC9tYXBzL01ha2VmaWxlCmluZGV4IGFkMzJiMTg1YTEyMC4uYWNlYzBmYmZhMThkIDEw MDY0NAotLS0gYS9kcml2ZXJzL210ZC9tYXBzL01ha2VmaWxlCisrKyBiL2RyaXZlcnMvbXRkL21h cHMvTWFrZWZpbGUKQEAgLTQzLDYgKzQzLDUgQEAgb2JqLSQoQ09ORklHX01URF9QTEFUUkFNKQkr PSBwbGF0LXJhbS5vCiBvYmotJChDT05GSUdfTVREX0lOVEVMX1ZSX05PUikJKz0gaW50ZWxfdnJf bm9yLm8KIG9iai0kKENPTkZJR19NVERfUkJUWDQ5MzkpCSs9IHJidHg0OTM5LWZsYXNoLm8KIG9i ai0kKENPTkZJR19NVERfVk1VKQkJKz0gdm11LWZsYXNoLm8KLW9iai0kKENPTkZJR19NVERfR1BJ T19BRERSKQkrPSBncGlvLWFkZHItZmxhc2gubwogb2JqLSQoQ09ORklHX01URF9MQVRDSF9BRERS KQkrPSBsYXRjaC1hZGRyLWZsYXNoLm8KIG9iai0kKENPTkZJR19NVERfTEFOVElRKQkrPSBsYW50 aXEtZmxhc2gubwpkaWZmIC0tZ2l0IGEvZHJpdmVycy9tdGQvbWFwcy9ncGlvLWFkZHItZmxhc2gu YyBiL2RyaXZlcnMvbXRkL21hcHMvZ3Bpby1hZGRyLWZsYXNoLmMKZGVsZXRlZCBmaWxlIG1vZGUg MTAwNjQ0CmluZGV4IGEyMGU4NWFhNzcwZS4uMDAwMDAwMDAwMDAwCi0tLSBhL2RyaXZlcnMvbXRk L21hcHMvZ3Bpby1hZGRyLWZsYXNoLmMKKysrIC9kZXYvbnVsbApAQCAtMSwyODEgKzAsMCBAQAot LyoKLSAqIGRyaXZlcnMvbXRkL21hcHMvZ3Bpby1hZGRyLWZsYXNoLmMKLSAqCi0gKiBIYW5kbGUg dGhlIGNhc2Ugd2hlcmUgYSBmbGFzaCBkZXZpY2UgaXMgbW9zdGx5IGFkZHJlc3NlZCB1c2luZyBw aHlzaWNhbAotICogbGluZSBhbmQgc3VwcGxlbWVudGVkIGJ5IEdQSU9zLiAgVGhpcyB3YXkgeW91 IGNhbiBob29rIHVwIHNheSBhIDhNaUIgZmxhc2gKLSAqIHRvIGEgMk1pQiBtZW1vcnkgcmFuZ2Ug YW5kIHVzZSB0aGUgR1BJT3MgdG8gc2VsZWN0IGEgcGFydGljdWxhciByYW5nZS4KLSAqCi0gKiBD b3B5cmlnaHQgwqkgMjAwMCBOaWNvbGFzIFBpdHJlIDxuaWNvQGNhbS5vcmc+Ci0gKiBDb3B5cmln aHQgwqkgMjAwNS0yMDA5IEFuYWxvZyBEZXZpY2VzIEluYy4KLSAqCi0gKiBFbnRlciBidWdzIGF0 IGh0dHA6Ly9ibGFja2Zpbi51Y2xpbnV4Lm9yZy8KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUg R1BMLTIgb3IgbGF0ZXIuCi0gKi8KLQotI2luY2x1ZGUgPGxpbnV4L2dwaW8uaD4KLSNpbmNsdWRl IDxsaW51eC9ncGlvL2NvbnN1bWVyLmg+Ci0jaW5jbHVkZSA8bGludXgvaW8uaD4KLSNpbmNsdWRl IDxsaW51eC9rZXJuZWwuaD4KLSNpbmNsdWRlIDxsaW51eC9tb2R1bGUuaD4KLSNpbmNsdWRlIDxs aW51eC9tdGQvbXRkLmg+Ci0jaW5jbHVkZSA8bGludXgvbXRkL21hcC5oPgotI2luY2x1ZGUgPGxp bnV4L210ZC9wYXJ0aXRpb25zLmg+Ci0jaW5jbHVkZSA8bGludXgvbXRkL3BoeXNtYXAuaD4KLSNp bmNsdWRlIDxsaW51eC9wbGF0Zm9ybV9kZXZpY2UuaD4KLSNpbmNsdWRlIDxsaW51eC9zbGFiLmg+ Ci0jaW5jbHVkZSA8bGludXgvdHlwZXMuaD4KLQotI2RlZmluZSB3aW5fbWFzayh4KSAoKEJJVCh4 KSkgLSAxKQotCi0jZGVmaW5lIERSSVZFUl9OQU1FICJncGlvLWFkZHItZmxhc2giCi0KLS8qKgot ICogc3RydWN0IGFzeW5jX3N0YXRlIC0ga2VlcCBHUElPIGZsYXNoIHN0YXRlCi0gKglAbXRkOiAg ICAgICAgIE1URCBzdGF0ZSBmb3IgdGhpcyBtYXBwaW5nCi0gKglAbWFwOiAgICAgICAgIE1URCBt YXAgc3RhdGUgZm9yIHRoaXMgZmxhc2gKLSAqCUBncGlvczogICAgICAgU3RydWN0IGNvbnRhaW5p bmcgdGhlIGFycmF5IG9mIEdQSU8gZGVzY3JpcHRvcnMKLSAqCUBncGlvX3ZhbHVlczogY2FjaGVk IEdQSU8gdmFsdWVzCi0gKglAd2luX29yZGVyOiAgIGRlZGljYXRlZCBtZW1vcnkgc2l6ZSAoaWYg bm8gR1BJT3MpCi0gKi8KLXN0cnVjdCBhc3luY19zdGF0ZSB7Ci0Jc3RydWN0IG10ZF9pbmZvICpt dGQ7Ci0Jc3RydWN0IG1hcF9pbmZvIG1hcDsKLQlzdHJ1Y3QgZ3Bpb19kZXNjcyAqZ3Bpb3M7Ci0J dW5zaWduZWQgaW50IGdwaW9fdmFsdWVzOwotCXVuc2lnbmVkIGludCB3aW5fb3JkZXI7Ci19Owot I2RlZmluZSBnZl9tYXBfaW5mb190b19zdGF0ZShtaSkgKChzdHJ1Y3QgYXN5bmNfc3RhdGUgKiko bWkpLT5tYXBfcHJpdl8xKQotCi0vKioKLSAqIGdmX3NldF9ncGlvcygpIC0gc2V0IEdQSU8gYWRk cmVzcyBsaW5lcyB0byBhY2Nlc3Mgc3BlY2lmaWVkIGZsYXNoIG9mZnNldAotICoJQHN0YXRlOiBH UElPIGZsYXNoIHN0YXRlCi0gKglAb2ZzOiAgIGRlc2lyZWQgb2Zmc2V0IHRvIGFjY2VzcwotICoK LSAqIFJhdGhlciB0aGFuIGNhbGwgdGhlIEdQSU8gZnJhbWV3b3JrIGV2ZXJ5IHRpbWUsIGNhY2hl IHRoZSBsYXN0LXByb2dyYW1tZWQKLSAqIHZhbHVlLiAgVGhpcyBzcGVlZHMgdXAgc2VxdWVudGlh bCBhY2Nlc3NlcyAod2hpY2ggYXJlIGJ5IGZhciB0aGUgbW9zdCBjb21tb24KLSAqIHR5cGUpLgot ICovCi1zdGF0aWMgdm9pZCBnZl9zZXRfZ3Bpb3Moc3RydWN0IGFzeW5jX3N0YXRlICpzdGF0ZSwg dW5zaWduZWQgbG9uZyBvZnMpCi17Ci0JaW50IGk7Ci0KLQlvZnMgPj49IHN0YXRlLT53aW5fb3Jk ZXI7Ci0KLQlpZiAob2ZzID09IHN0YXRlLT5ncGlvX3ZhbHVlcykKLQkJcmV0dXJuOwotCi0JZm9y IChpID0gMDsgaSA8IHN0YXRlLT5ncGlvcy0+bmRlc2NzOyBpKyspIHsKLQkJaWYgKChvZnMgJiBC SVQoaSkpID09IChzdGF0ZS0+Z3Bpb192YWx1ZXMgJiBCSVQoaSkpKQotCQkJY29udGludWU7Ci0K LQkJZ3Bpb2Rfc2V0X3ZhbHVlKHN0YXRlLT5ncGlvcy0+ZGVzY1tpXSwgISEob2ZzICYgQklUKGkp KSk7Ci0JfQotCi0Jc3RhdGUtPmdwaW9fdmFsdWVzID0gb2ZzOwotfQotCi0vKioKLSAqIGdmX3Jl YWQoKSAtIHJlYWQgYSB3b3JkIGF0IHRoZSBzcGVjaWZpZWQgb2Zmc2V0Ci0gKglAbWFwOiBNVEQg bWFwIHN0YXRlCi0gKglAb2ZzOiBkZXNpcmVkIG9mZnNldCB0byByZWFkCi0gKi8KLXN0YXRpYyBt YXBfd29yZCBnZl9yZWFkKHN0cnVjdCBtYXBfaW5mbyAqbWFwLCB1bnNpZ25lZCBsb25nIG9mcykK LXsKLQlzdHJ1Y3QgYXN5bmNfc3RhdGUgKnN0YXRlID0gZ2ZfbWFwX2luZm9fdG9fc3RhdGUobWFw KTsKLQl1aW50MTZfdCB3b3JkOwotCW1hcF93b3JkIHRlc3Q7Ci0KLQlnZl9zZXRfZ3Bpb3Moc3Rh dGUsIG9mcyk7Ci0KLQl3b3JkID0gcmVhZHcobWFwLT52aXJ0ICsgKG9mcyAmIHdpbl9tYXNrKHN0 YXRlLT53aW5fb3JkZXIpKSk7Ci0JdGVzdC54WzBdID0gd29yZDsKLQlyZXR1cm4gdGVzdDsKLX0K LQotLyoqCi0gKiBnZl9jb3B5X2Zyb20oKSAtIGNvcHkgYSBjaHVuayBvZiBkYXRhIGZyb20gdGhl IGZsYXNoCi0gKglAbWFwOiAgTVREIG1hcCBzdGF0ZQotICoJQHRvOiAgIG1lbW9yeSB0byBjb3B5 IHRvCi0gKglAZnJvbTogZmxhc2ggb2Zmc2V0IHRvIGNvcHkgZnJvbQotICoJQGxlbjogIGhvdyBt dWNoIHRvIGNvcHkKLSAqCi0gKiBUaGUgImZyb20iIHJlZ2lvbiBtYXkgc3RyYWRkbGUgbW9yZSB0 aGFuIG9uZSB3aW5kb3csIHNvIHRvZ2dsZSB0aGUgR1BJT3MgZm9yCi0gKiBlYWNoIHdpbmRvdyBy ZWdpb24gYmVmb3JlIHJlYWRpbmcgaXRzIGRhdGEuCi0gKi8KLXN0YXRpYyB2b2lkIGdmX2NvcHlf ZnJvbShzdHJ1Y3QgbWFwX2luZm8gKm1hcCwgdm9pZCAqdG8sIHVuc2lnbmVkIGxvbmcgZnJvbSwg c3NpemVfdCBsZW4pCi17Ci0Jc3RydWN0IGFzeW5jX3N0YXRlICpzdGF0ZSA9IGdmX21hcF9pbmZv X3RvX3N0YXRlKG1hcCk7Ci0KLQlpbnQgdGhpc19sZW47Ci0KLQl3aGlsZSAobGVuKSB7Ci0JCXRo aXNfbGVuID0gZnJvbSAmIHdpbl9tYXNrKHN0YXRlLT53aW5fb3JkZXIpOwotCQl0aGlzX2xlbiA9 IEJJVChzdGF0ZS0+d2luX29yZGVyKSAtIHRoaXNfbGVuOwotCQl0aGlzX2xlbiA9IG1pbl90KGlu dCwgbGVuLCB0aGlzX2xlbik7Ci0KLQkJZ2Zfc2V0X2dwaW9zKHN0YXRlLCBmcm9tKTsKLQkJbWVt Y3B5X2Zyb21pbyh0bywKLQkJCSAgICAgIG1hcC0+dmlydCArIChmcm9tICYgd2luX21hc2soc3Rh dGUtPndpbl9vcmRlcikpLAotCQkJICAgICAgdGhpc19sZW4pOwotCQlsZW4gLT0gdGhpc19sZW47 Ci0JCWZyb20gKz0gdGhpc19sZW47Ci0JCXRvICs9IHRoaXNfbGVuOwotCX0KLX0KLQotLyoqCi0g KiBnZl93cml0ZSgpIC0gd3JpdGUgYSB3b3JkIGF0IHRoZSBzcGVjaWZpZWQgb2Zmc2V0Ci0gKglA bWFwOiBNVEQgbWFwIHN0YXRlCi0gKglAb2ZzOiBkZXNpcmVkIG9mZnNldCB0byB3cml0ZQotICov Ci1zdGF0aWMgdm9pZCBnZl93cml0ZShzdHJ1Y3QgbWFwX2luZm8gKm1hcCwgbWFwX3dvcmQgZDEs IHVuc2lnbmVkIGxvbmcgb2ZzKQotewotCXN0cnVjdCBhc3luY19zdGF0ZSAqc3RhdGUgPSBnZl9t YXBfaW5mb190b19zdGF0ZShtYXApOwotCXVpbnQxNl90IGQ7Ci0KLQlnZl9zZXRfZ3Bpb3Moc3Rh dGUsIG9mcyk7Ci0KLQlkID0gZDEueFswXTsKLQl3cml0ZXcoZCwgbWFwLT52aXJ0ICsgKG9mcyAm IHdpbl9tYXNrKHN0YXRlLT53aW5fb3JkZXIpKSk7Ci19Ci0KLS8qKgotICogZ2ZfY29weV90bygp IC0gY29weSBhIGNodW5rIG9mIGRhdGEgdG8gdGhlIGZsYXNoCi0gKglAbWFwOiAgTVREIG1hcCBz dGF0ZQotICoJQHRvOiAgIGZsYXNoIG9mZnNldCB0byBjb3B5IHRvCi0gKglAZnJvbTogbWVtb3J5 IHRvIGNvcHkgZnJvbQotICoJQGxlbjogIGhvdyBtdWNoIHRvIGNvcHkKLSAqCi0gKiBTZWUgZ2Zf Y29weV9mcm9tKCkgY2F2ZWF0LgotICovCi1zdGF0aWMgdm9pZCBnZl9jb3B5X3RvKHN0cnVjdCBt YXBfaW5mbyAqbWFwLCB1bnNpZ25lZCBsb25nIHRvLAotCQkgICAgICAgY29uc3Qgdm9pZCAqZnJv bSwgc3NpemVfdCBsZW4pCi17Ci0Jc3RydWN0IGFzeW5jX3N0YXRlICpzdGF0ZSA9IGdmX21hcF9p bmZvX3RvX3N0YXRlKG1hcCk7Ci0KLQlpbnQgdGhpc19sZW47Ci0KLQl3aGlsZSAobGVuKSB7Ci0J CXRoaXNfbGVuID0gdG8gJiB3aW5fbWFzayhzdGF0ZS0+d2luX29yZGVyKTsKLQkJdGhpc19sZW4g PSBCSVQoc3RhdGUtPndpbl9vcmRlcikgLSB0aGlzX2xlbjsKLQkJdGhpc19sZW4gPSBtaW5fdChp bnQsIGxlbiwgdGhpc19sZW4pOwotCi0JCWdmX3NldF9ncGlvcyhzdGF0ZSwgdG8pOwotCQltZW1j cHlfdG9pbyhtYXAtPnZpcnQgKyAodG8gJiB3aW5fbWFzayhzdGF0ZS0+d2luX29yZGVyKSksCi0J CQkgICAgZnJvbSwgbGVuKTsKLQotCQlsZW4gLT0gdGhpc19sZW47Ci0JCXRvICs9IHRoaXNfbGVu OwotCQlmcm9tICs9IHRoaXNfbGVuOwotCX0KLX0KLQotc3RhdGljIGNvbnN0IGNoYXIgKiBjb25z dCBwYXJ0X3Byb2JlX3R5cGVzW10gPSB7Ci0JImNtZGxpbmVwYXJ0IiwgIlJlZEJvb3QiLCBOVUxM IH07Ci0KLS8qKgotICogZ3Bpb19mbGFzaF9wcm9iZSgpIC0gc2V0dXAgYSBtYXBwaW5nIGZvciBh IEdQSU8gYXNzaXN0ZWQgZmxhc2gKLSAqCUBwZGV2OiBwbGF0Zm9ybSBkZXZpY2UKLSAqCi0gKiBU aGUgcGxhdGZvcm0gcmVzb3VyY2UgbGF5b3V0IGV4cGVjdGVkIGxvb2tzIHNvbWV0aGluZyBsaWtl OgotICogc3RydWN0IG10ZF9wYXJ0aXRpb24gcGFydGl0aW9uc1tdID0geyAuLi4gfTsKLSAqIHN0 cnVjdCBwaHlzbWFwX2ZsYXNoX2RhdGEgZmxhc2hfZGF0YSA9IHsgLi4uIH07Ci0gKiBzdGF0aWMg c3RydWN0IGdwaW9kX2xvb2t1cF90YWJsZSBhZGRyX2ZsYXNoX2dwaW9zID0gewotICoJCS5kZXZf aWQgPSAiZ3Bpby1hZGRyLWZsYXNoLjAiLAotICoJCS50YWJsZSA9IHsKLSAqCQlHUElPX0xPT0tV UF9JRFgoImdwaW8uMCIsIDE1LCAiYWRkciIsIDAsIEdQSU9fQUNUSVZFX0hJR0gpLAotICoJCUdQ SU9fTE9PS1VQX0lEWCgiZ3Bpby4wIiwgMTYsICJhZGRyIiwgMSwgR1BJT19BQ1RJVkVfSElHSCks Ci0gKgkJKTsKLSAqIH07Ci0gKiBncGlvZF9hZGRfbG9va3VwX3RhYmxlKCZhZGRyX2ZsYXNoX2dw aW9zKTsKLSAqCi0gKiBzdHJ1Y3QgcmVzb3VyY2UgZmxhc2hfcmVzb3VyY2VbXSA9IHsKLSAqCXsK LSAqCQkubmFtZSAgPSAiY2ZpX3Byb2JlIiwKLSAqCQkuc3RhcnQgPSAweDIwMDAwMDAwLAotICoJ CS5lbmQgICA9IDB4MjAxZmZmZmYsCi0gKgkJLmZsYWdzID0gSU9SRVNPVVJDRV9NRU0sCi0gKgl9 LAotICogfTsKLSAqIHN0cnVjdCBwbGF0Zm9ybV9kZXZpY2UgZmxhc2hfZGV2aWNlID0gewotICoJ Lm5hbWUgICAgICAgICAgPSAiZ3Bpby1hZGRyLWZsYXNoIiwKLSAqCS5kZXYgICAgICAgICAgID0g eyAucGxhdGZvcm1fZGF0YSA9ICZmbGFzaF9kYXRhLCB9LAotICoJLm51bV9yZXNvdXJjZXMgPSBB UlJBWV9TSVpFKGZsYXNoX3Jlc291cmNlKSwKLSAqCS5yZXNvdXJjZSAgICAgID0gZmxhc2hfcmVz b3VyY2UsCi0gKgkuLi4KLSAqIH07Ci0gKi8KLXN0YXRpYyBpbnQgZ3Bpb19mbGFzaF9wcm9iZShz dHJ1Y3QgcGxhdGZvcm1fZGV2aWNlICpwZGV2KQotewotCXN0cnVjdCBwaHlzbWFwX2ZsYXNoX2Rh dGEgKnBkYXRhOwotCXN0cnVjdCByZXNvdXJjZSAqbWVtb3J5OwotCXN0cnVjdCBhc3luY19zdGF0 ZSAqc3RhdGU7Ci0KLQlwZGF0YSA9IGRldl9nZXRfcGxhdGRhdGEoJnBkZXYtPmRldik7Ci0JbWVt b3J5ID0gcGxhdGZvcm1fZ2V0X3Jlc291cmNlKHBkZXYsIElPUkVTT1VSQ0VfTUVNLCAwKTsKLQot CWlmICghbWVtb3J5KQotCQlyZXR1cm4gLUVJTlZBTDsKLQotCXN0YXRlID0gZGV2bV9remFsbG9j KCZwZGV2LT5kZXYsIHNpemVvZigqc3RhdGUpLCBHRlBfS0VSTkVMKTsKLQlpZiAoIXN0YXRlKQot CQlyZXR1cm4gLUVOT01FTTsKLQotCXN0YXRlLT5ncGlvcyA9IGRldm1fZ3Bpb2RfZ2V0X2FycmF5 KCZwZGV2LT5kZXYsICJhZGRyIiwgR1BJT0RfT1VUX0xPVyk7Ci0JaWYgKElTX0VSUihzdGF0ZS0+ Z3Bpb3MpKQotCQlyZXR1cm4gUFRSX0VSUihzdGF0ZS0+Z3Bpb3MpOwotCi0Jc3RhdGUtPndpbl9v cmRlciAgICAgID0gZ2V0X2JpdG1hc2tfb3JkZXIocmVzb3VyY2Vfc2l6ZShtZW1vcnkpKSAtIDE7 Ci0KLQlzdGF0ZS0+bWFwLm5hbWUgICAgICAgPSBEUklWRVJfTkFNRTsKLQlzdGF0ZS0+bWFwLnJl YWQgICAgICAgPSBnZl9yZWFkOwotCXN0YXRlLT5tYXAuY29weV9mcm9tICA9IGdmX2NvcHlfZnJv bTsKLQlzdGF0ZS0+bWFwLndyaXRlICAgICAgPSBnZl93cml0ZTsKLQlzdGF0ZS0+bWFwLmNvcHlf dG8gICAgPSBnZl9jb3B5X3RvOwotCXN0YXRlLT5tYXAuYmFua3dpZHRoICA9IHBkYXRhLT53aWR0 aDsKLQlzdGF0ZS0+bWFwLnNpemUgICAgICAgPSBCSVQoc3RhdGUtPndpbl9vcmRlciArIHN0YXRl LT5ncGlvcy0+bmRlc2NzKTsKLQlzdGF0ZS0+bWFwLnZpcnQJICAgICAgPSBkZXZtX2lvcmVtYXBf cmVzb3VyY2UoJnBkZXYtPmRldiwgbWVtb3J5KTsKLQlpZiAoSVNfRVJSKHN0YXRlLT5tYXAudmly dCkpCi0JCXJldHVybiBQVFJfRVJSKHN0YXRlLT5tYXAudmlydCk7Ci0KLQlzdGF0ZS0+bWFwLnBo eXMgICAgICAgPSBOT19YSVA7Ci0Jc3RhdGUtPm1hcC5tYXBfcHJpdl8xID0gKHVuc2lnbmVkIGxv bmcpc3RhdGU7Ci0KLQlwbGF0Zm9ybV9zZXRfZHJ2ZGF0YShwZGV2LCBzdGF0ZSk7Ci0KLQlkZXZf bm90aWNlKCZwZGV2LT5kZXYsICJwcm9iaW5nICVkLWJpdCBmbGFzaCBidXNcbiIsCi0JCSAgIHN0 YXRlLT5tYXAuYmFua3dpZHRoICogOCk7Ci0Jc3RhdGUtPm10ZCA9IGRvX21hcF9wcm9iZShtZW1v cnktPm5hbWUsICZzdGF0ZS0+bWFwKTsKLQlpZiAoIXN0YXRlLT5tdGQpCi0JCXJldHVybiAtRU5Y SU87Ci0Jc3RhdGUtPm10ZC0+ZGV2LnBhcmVudCA9ICZwZGV2LT5kZXY7Ci0KLQltdGRfZGV2aWNl X3BhcnNlX3JlZ2lzdGVyKHN0YXRlLT5tdGQsIHBhcnRfcHJvYmVfdHlwZXMsIE5VTEwsCi0JCQkJ ICBwZGF0YS0+cGFydHMsIHBkYXRhLT5ucl9wYXJ0cyk7Ci0KLQlyZXR1cm4gMDsKLX0KLQotc3Rh dGljIGludCBncGlvX2ZsYXNoX3JlbW92ZShzdHJ1Y3QgcGxhdGZvcm1fZGV2aWNlICpwZGV2KQot ewotCXN0cnVjdCBhc3luY19zdGF0ZSAqc3RhdGUgPSBwbGF0Zm9ybV9nZXRfZHJ2ZGF0YShwZGV2 KTsKLQotCW10ZF9kZXZpY2VfdW5yZWdpc3RlcihzdGF0ZS0+bXRkKTsKLQltYXBfZGVzdHJveShz dGF0ZS0+bXRkKTsKLQlyZXR1cm4gMDsKLX0KLQotc3RhdGljIHN0cnVjdCBwbGF0Zm9ybV9kcml2 ZXIgZ3Bpb19mbGFzaF9kcml2ZXIgPSB7Ci0JLnByb2JlCQk9IGdwaW9fZmxhc2hfcHJvYmUsCi0J LnJlbW92ZQkJPSBncGlvX2ZsYXNoX3JlbW92ZSwKLQkuZHJpdmVyCQk9IHsKLQkJLm5hbWUJPSBE UklWRVJfTkFNRSwKLQl9LAotfTsKLQotbW9kdWxlX3BsYXRmb3JtX2RyaXZlcihncGlvX2ZsYXNo X2RyaXZlcik7Ci0KLU1PRFVMRV9BVVRIT1IoIk1pa2UgRnJ5c2luZ2VyIDx2YXBpZXJAZ2VudG9v Lm9yZz4iKTsKLU1PRFVMRV9ERVNDUklQVElPTigiTVREIG1hcCBkcml2ZXIgZm9yIGZsYXNoZXMg YWRkcmVzc2VkIHBoeXNpY2FsbHkgYW5kIHdpdGggZ3Bpb3MiKTsKLU1PRFVMRV9MSUNFTlNFKCJH UEwiKTsKZGlmZiAtLWdpdCBhL2RyaXZlcnMvbXRkL21hcHMvcGh5c21hcC1jb3JlLmMgYi9kcml2 ZXJzL210ZC9tYXBzL3BoeXNtYXAtY29yZS5jCmluZGV4IDdhNTBmZjllZjgxMi4uMmRjMzNhZTcx MzM1IDEwMDY0NAotLS0gYS9kcml2ZXJzL210ZC9tYXBzL3BoeXNtYXAtY29yZS5jCisrKyBiL2Ry aXZlcnMvbXRkL21hcHMvcGh5c21hcC1jb3JlLmMKQEAgLTEzLDYgKzEzLDE0IEBACiAgKgogICog ICAgUmV2aXNlZCB0byBoYW5kbGUgbmV3ZXIgc3R5bGUgZmxhc2ggYmluZGluZyBieToKICAqICAg IENvcHlyaWdodCAoQykgMjAwNyBEYXZpZCBHaWJzb24sIElCTSBDb3Jwb3JhdGlvbi4KKyAqCisg KiBHUElPIGFkZHJlc3MgZXh0ZW5zaW9uOgorICogICAgSGFuZGxlIHRoZSBjYXNlIHdoZXJlIGEg Zmxhc2ggZGV2aWNlIGlzIG1vc3RseSBhZGRyZXNzZWQgdXNpbmcgcGh5c2ljYWwKKyAqICAgIGxp bmUgYW5kIHN1cHBsZW1lbnRlZCBieSBHUElPcy4gIFRoaXMgd2F5IHlvdSBjYW4gaG9vayB1cCBz YXkgYSA4TWlCIGZsYXNoCisgKiAgICB0byBhIDJNaUIgbWVtb3J5IHJhbmdlIGFuZCB1c2UgdGhl IEdQSU9zIHRvIHNlbGVjdCBhIHBhcnRpY3VsYXIgcmFuZ2UuCisgKgorICogICAgQ29weXJpZ2h0 IMKpIDIwMDAgTmljb2xhcyBQaXRyZSA8bmljb0BjYW0ub3JnPgorICogICAgQ29weXJpZ2h0IMKp IDIwMDUtMjAwOSBBbmFsb2cgRGV2aWNlcyBJbmMuCiAgKi8KIAogI2luY2x1ZGUgPGxpbnV4L21v ZHVsZS5oPgpAQCAtMzAsNiArMzgsNyBAQAogI2luY2x1ZGUgPGxpbnV4L210ZC9jZmlfZW5kaWFu Lmg+CiAjaW5jbHVkZSA8bGludXgvaW8uaD4KICNpbmNsdWRlIDxsaW51eC9vZl9kZXZpY2UuaD4K KyNpbmNsdWRlIDxsaW51eC9ncGlvL2NvbnN1bWVyLmg+CiAKICNpbmNsdWRlICJwaHlzbWFwX29m X2dlbWluaS5oIgogI2luY2x1ZGUgInBoeXNtYXBfb2ZfdmVyc2F0aWxlLmgiCkBAIC00NSw2ICs1 NCw5IEBAIHN0cnVjdCBwaHlzbWFwX2ZsYXNoX2luZm8gewogCWNvbnN0IGNoYXIgKiBjb25zdAkq cGFydF90eXBlczsKIAl1bnNpZ25lZCBpbnQJCW5wYXJ0czsKIAljb25zdCBzdHJ1Y3QgbXRkX3Bh cnRpdGlvbiAqcGFydHM7CisJc3RydWN0IGdwaW9fZGVzY3MJKmdwaW9zOworCXVuc2lnbmVkIGlu dAkJZ3Bpb192YWx1ZXM7CisJdW5zaWduZWQgaW50CQl3aW5fb3JkZXI7CiB9OwogCiBzdGF0aWMg aW50IHBoeXNtYXBfZmxhc2hfcmVtb3ZlKHN0cnVjdCBwbGF0Zm9ybV9kZXZpY2UgKmRldikKQEAg LTEwNCw2ICsxMTYsMTE5IEBAIHN0YXRpYyB2b2lkIHBoeXNtYXBfc2V0X3ZwcChzdHJ1Y3QgbWFw X2luZm8gKm1hcCwgaW50IHN0YXRlKQogCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJmluZm8tPnZw cF9sb2NrLCBmbGFncyk7CiB9CiAKKyNpZiBJU19FTkFCTEVEKENPTkZJR19NVERfUEhZU01BUF9H UElPX0FERFIpCitzdGF0aWMgdm9pZCBwaHlzbWFwX3NldF9hZGRyX2dwaW9zKHN0cnVjdCBwaHlz bWFwX2ZsYXNoX2luZm8gKmluZm8sCisJCQkJICAgdW5zaWduZWQgbG9uZyBvZnMpCit7CisJdW5z aWduZWQgaW50IGk7CisKKwlvZnMgPj49IGluZm8tPndpbl9vcmRlcjsKKwlpZiAoaW5mby0+Z3Bp b192YWx1ZXMgPT0gb2ZzKQorCQlyZXR1cm47CisKKwlmb3IgKGkgPSAwOyBpIDwgaW5mby0+Z3Bp b3MtPm5kZXNjczsgaSsrKSB7CisJCWlmICgoQklUKGkpICYgb2ZzKSA9PSAoQklUKGkpICYgaW5m by0+Z3Bpb192YWx1ZXMpKQorCQkJY29udGludWU7CisKKwkJZ3Bpb2Rfc2V0X3ZhbHVlKGluZm8t PmdwaW9zLT5kZXNjW2ldLCAhIShCSVQoaSkgJiBvZnMpKTsKKwl9Cit9CisKKyNkZWZpbmUgd2lu X21hc2sob3JkZXIpCQkoQklUKG9yZGVyKSAtIDEpCisKK3N0YXRpYyBtYXBfd29yZCBwaHlzbWFw X2FkZHJfZ3Bpb3NfcmVhZChzdHJ1Y3QgbWFwX2luZm8gKm1hcCwKKwkJCQkJdW5zaWduZWQgbG9u ZyBvZnMpCit7CisJc3RydWN0IHBsYXRmb3JtX2RldmljZSAqcGRldjsKKwlzdHJ1Y3QgcGh5c21h cF9mbGFzaF9pbmZvICppbmZvOworCW1hcF93b3JkIG13OworCXUxNiB3b3JkOworCisJcGRldiA9 IChzdHJ1Y3QgcGxhdGZvcm1fZGV2aWNlICopbWFwLT5tYXBfcHJpdl8xOworCWluZm8gPSBwbGF0 Zm9ybV9nZXRfZHJ2ZGF0YShwZGV2KTsKKwlwaHlzbWFwX3NldF9hZGRyX2dwaW9zKGluZm8sIG9m cyk7CisKKwl3b3JkID0gcmVhZHcobWFwLT52aXJ0ICsgKG9mcyAmIHdpbl9tYXNrKGluZm8tPndp bl9vcmRlcikpKTsKKwltdy54WzBdID0gd29yZDsKKwlyZXR1cm4gbXc7Cit9CisKK3N0YXRpYyB2 b2lkIHBoeXNtYXBfYWRkcl9ncGlvc19jb3B5X2Zyb20oc3RydWN0IG1hcF9pbmZvICptYXAsIHZv aWQgKmJ1ZiwKKwkJCQkJIHVuc2lnbmVkIGxvbmcgb2ZzLCBzc2l6ZV90IGxlbikKK3sKKwlzdHJ1 Y3QgcGxhdGZvcm1fZGV2aWNlICpwZGV2OworCXN0cnVjdCBwaHlzbWFwX2ZsYXNoX2luZm8gKmlu Zm87CisKKwlwZGV2ID0gKHN0cnVjdCBwbGF0Zm9ybV9kZXZpY2UgKiltYXAtPm1hcF9wcml2XzE7 CisJaW5mbyA9IHBsYXRmb3JtX2dldF9kcnZkYXRhKHBkZXYpOworCisJd2hpbGUgKGxlbikgewor CQl1bnNpZ25lZCBpbnQgd2lub2ZzID0gb2ZzICYgd2luX21hc2soaW5mby0+d2luX29yZGVyKTsK KwkJdW5zaWduZWQgaW50IGNodW5rbGVuID0gbWluX3QodW5zaWduZWQgaW50LCBsZW4sCisJCQkJ CSAgICAgIEJJVChpbmZvLT53aW5fb3JkZXIpIC0gd2lub2ZzKTsKKworCQlwaHlzbWFwX3NldF9h ZGRyX2dwaW9zKGluZm8sIG9mcyk7CisJCW1lbWNweV9mcm9taW8oYnVmLCBtYXAtPnZpcnQgKyB3 aW5vZnMsIGNodW5rbGVuKTsKKwkJbGVuIC09IGNodW5rbGVuOworCQlidWYgKz0gY2h1bmtsZW47 CisJCW9mcyArPSBjaHVua2xlbjsKKwl9Cit9CisKK3N0YXRpYyB2b2lkIHBoeXNtYXBfYWRkcl9n cGlvc193cml0ZShzdHJ1Y3QgbWFwX2luZm8gKm1hcCwgbWFwX3dvcmQgbXcsCisJCQkJICAgICB1 bnNpZ25lZCBsb25nIG9mcykKK3sKKwlzdHJ1Y3QgcGxhdGZvcm1fZGV2aWNlICpwZGV2OworCXN0 cnVjdCBwaHlzbWFwX2ZsYXNoX2luZm8gKmluZm87CisJdTE2IHdvcmQ7CisKKwlwZGV2ID0gKHN0 cnVjdCBwbGF0Zm9ybV9kZXZpY2UgKiltYXAtPm1hcF9wcml2XzE7CisJaW5mbyA9IHBsYXRmb3Jt X2dldF9kcnZkYXRhKHBkZXYpOworCXBoeXNtYXBfc2V0X2FkZHJfZ3Bpb3MoaW5mbywgb2ZzKTsK KworCXdvcmQgPSBtdy54WzBdOworCXdyaXRldyh3b3JkLCBtYXAtPnZpcnQgKyAob2ZzICYgd2lu X21hc2soaW5mby0+d2luX29yZGVyKSkpOworfQorCitzdGF0aWMgdm9pZCBwaHlzbWFwX2FkZHJf Z3Bpb3NfY29weV90byhzdHJ1Y3QgbWFwX2luZm8gKm1hcCwgdW5zaWduZWQgbG9uZyBvZnMsCisJ CQkJICAgICAgIGNvbnN0IHZvaWQgKmJ1Ziwgc3NpemVfdCBsZW4pCit7CisJc3RydWN0IHBsYXRm b3JtX2RldmljZSAqcGRldjsKKwlzdHJ1Y3QgcGh5c21hcF9mbGFzaF9pbmZvICppbmZvOworCisJ cGRldiA9IChzdHJ1Y3QgcGxhdGZvcm1fZGV2aWNlICopbWFwLT5tYXBfcHJpdl8xOworCWluZm8g PSBwbGF0Zm9ybV9nZXRfZHJ2ZGF0YShwZGV2KTsKKworCXdoaWxlIChsZW4pIHsKKwkJdW5zaWdu ZWQgaW50IHdpbm9mcyA9IG9mcyAmIHdpbl9tYXNrKGluZm8tPndpbl9vcmRlcik7CisJCXVuc2ln bmVkIGludCBjaHVua2xlbiA9IG1pbl90KHVuc2lnbmVkIGludCwgbGVuLAorCQkJCQkgICAgICBC SVQoaW5mby0+d2luX29yZGVyKSAtIHdpbm9mcyk7CisKKwkJcGh5c21hcF9zZXRfYWRkcl9ncGlv cyhpbmZvLCBvZnMpOworCQltZW1jcHlfdG9pbyhtYXAtPnZpcnQgKyB3aW5vZnMsIGJ1ZiwgY2h1 bmtsZW4pOworCQlsZW4gLT0gY2h1bmtsZW47CisJCWJ1ZiArPSBjaHVua2xlbjsKKwkJb2ZzICs9 IGNodW5rbGVuOworCX0KK30KKworc3RhdGljIGludCBwaHlzbWFwX2FkZHJfZ3Bpb3NfbWFwX2lu aXQoc3RydWN0IG1hcF9pbmZvICptYXApCit7CisJbWFwLT5waHlzID0gTk9fWElQOworCW1hcC0+ cmVhZCA9IHBoeXNtYXBfYWRkcl9ncGlvc19yZWFkOworCW1hcC0+Y29weV9mcm9tID0gcGh5c21h cF9hZGRyX2dwaW9zX2NvcHlfZnJvbTsKKwltYXAtPndyaXRlID0gcGh5c21hcF9hZGRyX2dwaW9z X3dyaXRlOworCW1hcC0+Y29weV90byA9IHBoeXNtYXBfYWRkcl9ncGlvc19jb3B5X3RvOworCisJ cmV0dXJuIDA7Cit9CisjZWxzZQorc3RhdGljIGludCBwaHlzbWFwX2FkZHJfZ3Bpb3NfbWFwX2lu aXQoc3RydWN0IG1hcF9pbmZvICptYXApCit7CisJcmV0dXJuIC1FTk9UU1VQUDsKK30KKyNlbmRp ZgorCiAjaWYgSVNfRU5BQkxFRChDT05GSUdfTVREX1BIWVNNQVBfT0YpCiBzdGF0aWMgY29uc3Qg c3RydWN0IG9mX2RldmljZV9pZCBvZl9mbGFzaF9tYXRjaFtdID0gewogCXsKQEAgLTM0Myw2ICs0 NjgsMTYgQEAgc3RhdGljIGludCBwaHlzbWFwX2ZsYXNoX3Byb2JlKHN0cnVjdCBwbGF0Zm9ybV9k ZXZpY2UgKmRldikKIAogCXBsYXRmb3JtX3NldF9kcnZkYXRhKGRldiwgaW5mbyk7CiAKKwlpbmZv LT5ncGlvcyA9IGRldm1fZ3Bpb2RfZ2V0X2FycmF5X29wdGlvbmFsKCZkZXYtPmRldiwgImFkZHIi LAorCQkJCQkJICAgIEdQSU9EX09VVF9MT1cpOworCWlmIChJU19FUlIoaW5mby0+Z3Bpb3MpKQor CQlyZXR1cm4gUFRSX0VSUihpbmZvLT5ncGlvcyk7CisKKwlpZiAoaW5mby0+Z3Bpb3MgJiYgaW5m by0+bm1hcHMgPiAxKSB7CisJCWRldl9lcnIoJmRldi0+ZGV2LCAiYWRkci1ncGlvcyBvbmx5IHN1 cHBvcnRlZCBmb3Igbm1hcHMgPT0gMVxuIik7CisJCXJldHVybiAtRUlOVkFMOworCX0KKwogCWVy ciA9IHBoeXNtYXBfZmxhc2hfb2ZfaW5pdChkZXYpOwogCWlmIChlcnIpCiAJCWVyciA9IHBoeXNt YXBfZmxhc2hfcGRhdGFfaW5pdChkZXYpOwpAQCAtMzY4LDEwICs1MDMsMjAgQEAgc3RhdGljIGlu dCBwaHlzbWFwX2ZsYXNoX3Byb2JlKHN0cnVjdCBwbGF0Zm9ybV9kZXZpY2UgKmRldikKIAkJaWYg KCFpbmZvLT5tYXBzW2ldLnBoeXMpCiAJCQlpbmZvLT5tYXBzW2ldLnBoeXMgPSByZXMtPnN0YXJ0 OwogCi0JCWluZm8tPm1hcHNbaV0uc2l6ZSA9IHJlc291cmNlX3NpemUocmVzKTsKKwkJaW5mby0+ d2luX29yZGVyID0gZ2V0X2JpdG1hc2tfb3JkZXIocmVzb3VyY2Vfc2l6ZShyZXMpKSAtIDE7CisJ CWluZm8tPm1hcHNbaV0uc2l6ZSA9IEJJVChpbmZvLT53aW5fb3JkZXIgKworCQkJCQkgKGluZm8t PmdwaW9zID8KKwkJCQkJICBpbmZvLT5ncGlvcy0+bmRlc2NzIDogMCkpOworCiAJCWluZm8tPm1h cHNbaV0ubWFwX3ByaXZfMSA9ICh1bnNpZ25lZCBsb25nKWRldjsKIAotCQlzaW1wbGVfbWFwX2lu aXQoJmluZm8tPm1hcHNbaV0pOworCQlpZiAoaW5mby0+Z3Bpb3MpIHsKKwkJCWVyciA9IHBoeXNt YXBfYWRkcl9ncGlvc19tYXBfaW5pdCgmaW5mby0+bWFwc1tpXSk7CisJCQlpZiAoZXJyKQorCQkJ CWdvdG8gZXJyX291dDsKKwkJfSBlbHNlIHsKKwkJCXNpbXBsZV9tYXBfaW5pdCgmaW5mby0+bWFw c1tpXSk7CisJCX0KIAogCQlwcm9iZV90eXBlID0gcm9tX3Byb2JlX3R5cGVzOwogCQlpZiAoIWlu Zm8tPnByb2JlX3R5cGUpIHsKQEAgLTQ5Niw2ICs2NDEsNyBAQCBtb2R1bGVfZXhpdChwaHlzbWFw X2V4aXQpOwogTU9EVUxFX0xJQ0VOU0UoIkdQTCIpOwogTU9EVUxFX0FVVEhPUigiRGF2aWQgV29v ZGhvdXNlIDxkd213MkBpbmZyYWRlYWQub3JnPiIpOwogTU9EVUxFX0FVVEhPUigiVml0YWx5IFdv b2wgPHZ3b29sQHJ1Lm12aXN0YS5jb20+Iik7CitNT0RVTEVfQVVUSE9SKCJNaWtlIEZyeXNpbmdl ciA8dmFwaWVyQGdlbnRvby5vcmc+Iik7CiBNT0RVTEVfREVTQ1JJUFRJT04oIkdlbmVyaWMgY29u ZmlndXJhYmxlIE1URCBtYXAgZHJpdmVyIik7CiAKIC8qIGxlZ2FjeSBwbGF0Zm9ybSBkcml2ZXJz IGNhbid0IGhvdHBsdWcgb3IgY29sZHBsZyAqLwotLSAKMi4xNC4xCgoKX19fX19fX19fX19fX19f X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fCkxpbnV4IE1URCBkaXNjdXNz aW9uIG1haWxpbmcgbGlzdApodHRwOi8vbGlzdHMuaW5mcmFkZWFkLm9yZy9tYWlsbWFuL2xpc3Rp bmZvL2xpbnV4LW10ZC8K