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.6 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,INCLUDES_PATCH,MAILING_LIST_MULTI, MENTIONS_GIT_HOSTING,SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS,USER_AGENT_SANE_1 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 5767DC433DF for ; Tue, 25 Aug 2020 18:44:52 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 20A9E2071E for ; Tue, 25 Aug 2020 18:44:52 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1598381092; bh=Ky3AZtEajHYdLzZb4oG8HIGeIIAi2wq6AgZkGKkszBc=; h=Date:From:To:Cc:Subject:References:In-Reply-To:List-ID:From; b=b7Xpa9AQaPctfV0xiQUGA1M58YjaCGtJ0wk70XsqAB1GKytKZ3P9qUjyepOvYpMcV IDbxaxjcIJ/YyHs6DiDlmD05vDVLxFFsZWTTQBgANb+NXptp+J4p5DD5qaYEI7V+6u tJU3VvyNnZSJhdLBzSO7nf8kmCGjoopnv8RbMpEU= Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726119AbgHYSot convert rfc822-to-8bit (ORCPT ); Tue, 25 Aug 2020 14:44:49 -0400 Received: from mail-wm1-f67.google.com ([209.85.128.67]:53243 "EHLO mail-wm1-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726158AbgHYSor (ORCPT ); Tue, 25 Aug 2020 14:44:47 -0400 Received: by mail-wm1-f67.google.com with SMTP id x5so3639680wmi.2; Tue, 25 Aug 2020 11:44:37 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:content-transfer-encoding :in-reply-to:user-agent; bh=mSp8WG6g493mnX01NbbuUvBAyLbfT8UOuMbBofm+Th0=; b=H/kZ+tzlI0hKB5FmlZI2rRnjwljlJ6jQ3Cp85orH4sMQRvDC4eHlBoiTsTvuWKb1qU zBFtk7959b2zmH0w7/8UmkMgKvwks3+mXevba32++qmlKIKQeH9RhY+6euajAT+m+zG1 NroZSDIsWolgfWfMiy/FcWtuIae0NL7BtoYtAWFN7dFgbAicZCOZUG/Mc+svJeMTEEyf GemTYycc08LKOp8H1Kn2g4KHDx2jynGXDTYOkm5z+5cxBHxV/Ua0itPt2ed9aDB2Ruwy aPIR61WUlW0qPGOvI1rxwzlynLX2WyVguxGxsbiqYZg8/dmklM/7RNybYM0ULaty0kkn faYA== X-Gm-Message-State: AOAM532sItHLPM/YlVtkIeZooD/z36WhNsDokEEjG41punR0tGjlpLNx e9nB+DrQBU3YTiKR1wbZQsQ= X-Google-Smtp-Source: ABdhPJwStbL/Lo/OYVnKHTd2LixTswrYvYE+JRazM8Heamf9vj9ksOWQV4BET/1qTzwNkU0FM2m0+g== X-Received: by 2002:a7b:cb4d:: with SMTP id v13mr3490276wmj.56.1598381076439; Tue, 25 Aug 2020 11:44:36 -0700 (PDT) Received: from kozik-lap ([194.230.155.216]) by smtp.googlemail.com with ESMTPSA id p14sm36211224wrg.96.2020.08.25.11.44.21 (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Tue, 25 Aug 2020 11:44:35 -0700 (PDT) Date: Tue, 25 Aug 2020 20:44:13 +0200 From: Krzysztof Kozlowski To: =?utf-8?Q?=C5=81ukasz?= Stelmach Cc: "David S. Miller" , Jakub Kicinski , Kukjin Kim , Rob Herring , Russell King , linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-samsung-soc@vger.kernel.org, netdev@vger.kernel.org, devicetree@vger.kernel.org, m.szyprowski@samsung.com, b.zolnierkie@samsung.com Subject: Re: [PATCH 1/3] net: ax88796c: ASIX AX88796C SPI Ethernet Adapter Driver Message-ID: <20200825184413.GA2693@kozik-lap> References: <20200825170311.24886-1-l.stelmach@samsung.com> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: 8BIT In-Reply-To: <20200825170311.24886-1-l.stelmach@samsung.com> User-Agent: Mutt/1.9.4 (2018-02-28) Sender: linux-samsung-soc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-samsung-soc@vger.kernel.org On Tue, Aug 25, 2020 at 07:03:09PM +0200, Łukasz Stelmach wrote: > ASIX AX88796[1] is a versatile ethernet adapter chip, that can be > connected to a CPU with a 8/16-bit bus or with an SPI. This driver > supports SPI connection. > > The driver has been ported from the vendor kernel for ARTIK5[2] > boards. Several changes were made to adapt it to the current kernel > which include: > > + updated DT configuration, > + clock configuration moved to DT, > + new timer, ethtool and gpio APIs > + dev_* instead of pr_* and custom printk() wrappers. > > [1] https://www.asix.com.tw/products.php?op=pItemdetail&PItemID=104;65;86&PLine=65 > [2] https://git.tizen.org/cgit/profile/common/platform/kernel/linux-3.10-artik/ > > The other ax88796 driver is for NE2000 compatible AX88796L chip. These > chips are not compatible. Hence, two separate drivers are required. Hi, Thanks for the driver, nice work. Few comments below. > > Signed-off-by: Łukasz Stelmach > --- > drivers/net/ethernet/Kconfig | 1 + > drivers/net/ethernet/Makefile | 1 + > drivers/net/ethernet/asix/Kconfig | 20 + > drivers/net/ethernet/asix/Makefile | 6 + > drivers/net/ethernet/asix/ax88796c_ioctl.c | 293 +++++ > drivers/net/ethernet/asix/ax88796c_ioctl.h | 21 + > drivers/net/ethernet/asix/ax88796c_main.c | 1373 ++++++++++++++++++++ > drivers/net/ethernet/asix/ax88796c_main.h | 596 +++++++++ > drivers/net/ethernet/asix/ax88796c_spi.c | 103 ++ > drivers/net/ethernet/asix/ax88796c_spi.h | 67 + > 10 files changed, 2481 insertions(+) > create mode 100644 drivers/net/ethernet/asix/Kconfig > create mode 100644 drivers/net/ethernet/asix/Makefile > create mode 100644 drivers/net/ethernet/asix/ax88796c_ioctl.c > create mode 100644 drivers/net/ethernet/asix/ax88796c_ioctl.h > create mode 100644 drivers/net/ethernet/asix/ax88796c_main.c > create mode 100644 drivers/net/ethernet/asix/ax88796c_main.h > create mode 100644 drivers/net/ethernet/asix/ax88796c_spi.c > create mode 100644 drivers/net/ethernet/asix/ax88796c_spi.h > > diff --git a/drivers/net/ethernet/Kconfig b/drivers/net/ethernet/Kconfig > index de50e8b9e656..f3b218e45ea5 100644 > --- a/drivers/net/ethernet/Kconfig > +++ b/drivers/net/ethernet/Kconfig > @@ -32,6 +32,7 @@ source "drivers/net/ethernet/apm/Kconfig" > source "drivers/net/ethernet/apple/Kconfig" > source "drivers/net/ethernet/aquantia/Kconfig" > source "drivers/net/ethernet/arc/Kconfig" > +source "drivers/net/ethernet/asix/Kconfig" > source "drivers/net/ethernet/atheros/Kconfig" > source "drivers/net/ethernet/aurora/Kconfig" > source "drivers/net/ethernet/broadcom/Kconfig" > diff --git a/drivers/net/ethernet/Makefile b/drivers/net/ethernet/Makefile > index f8f38dcb5f8a..9eb368d93607 100644 > --- a/drivers/net/ethernet/Makefile > +++ b/drivers/net/ethernet/Makefile > @@ -18,6 +18,7 @@ obj-$(CONFIG_NET_XGENE) += apm/ > obj-$(CONFIG_NET_VENDOR_APPLE) += apple/ > obj-$(CONFIG_NET_VENDOR_AQUANTIA) += aquantia/ > obj-$(CONFIG_NET_VENDOR_ARC) += arc/ > +obj-$(CONFIG_NET_VENDOR_ASIX) += asix/ > obj-$(CONFIG_NET_VENDOR_ATHEROS) += atheros/ > obj-$(CONFIG_NET_VENDOR_AURORA) += aurora/ > obj-$(CONFIG_NET_VENDOR_CADENCE) += cadence/ > diff --git a/drivers/net/ethernet/asix/Kconfig b/drivers/net/ethernet/asix/Kconfig > new file mode 100644 > index 000000000000..4b127a4a659a > --- /dev/null > +++ b/drivers/net/ethernet/asix/Kconfig > @@ -0,0 +1,20 @@ > +# > +# Asix network device configuration > +# > + > +config NET_VENDOR_ASIX > + bool "Asix devices" > + depends on SPI > + help > + If you have a network (Ethernet) interface based on a chip from ASIX, say Y Looks like too long, did it pass checkpatch? > + > +if NET_VENDOR_ASIX > + > +config SPI_AX88796C > + tristate "Asix AX88796C-SPI support" > + depends on SPI > + depends on GPIOLIB > + help > + Say Y here if you intend to attach a Asix AX88796C as SPI mode > + > +endif # NET_VENDOR_ASIX > diff --git a/drivers/net/ethernet/asix/Makefile b/drivers/net/ethernet/asix/Makefile > new file mode 100644 > index 000000000000..0bfbbb042634 > --- /dev/null > +++ b/drivers/net/ethernet/asix/Makefile > @@ -0,0 +1,6 @@ > +# > +# Makefile for the Asix network device drivers. > +# > + > +obj-$(CONFIG_SPI_AX88796C) += ax88796c.o > +ax88796c-y := ax88796c_main.o ax88796c_ioctl.o ax88796c_spi.o > diff --git a/drivers/net/ethernet/asix/ax88796c_ioctl.c b/drivers/net/ethernet/asix/ax88796c_ioctl.c > new file mode 100644 > index 000000000000..eba361e2a8b7 > --- /dev/null > +++ b/drivers/net/ethernet/asix/ax88796c_ioctl.c > @@ -0,0 +1,293 @@ > +// SPDX-License-Identifier: GPL-2.0-only > +/* > + * Copyright (c) 2010 ASIX Electronics Corporation > + * Copyright (c) 2020 Samsung Electronics Co., Ltd. > + * > + * ASIX AX88796C SPI Fast Ethernet Linux driver > + */ > + > +#include "ax88796c_main.h" > +#include "ax88796c_spi.h" > +#include "ax88796c_ioctl.h" > + > +u8 ax88796c_check_power(struct ax88796c_device *ax_local) Looks here like pointer to const. Unless it is because of AX_READ_STATUS() which cannot take const? > +{ Please put file-scope definitions first, so this should go to the end. > + struct spi_status ax_status; > + > + /* Check media link status first */ > + if (netif_carrier_ok(ax_local->ndev) || > + (ax_local->ps_level == AX_PS_D0) || > + (ax_local->ps_level == AX_PS_D1)) { > + return 0; > + } > + > + AX_READ_STATUS(&ax_local->ax_spi, &ax_status); > + if (!(ax_status.status & AX_STATUS_READY)) This looks buggy... AX_READ_STATUS can fail, without reporting an error. There is no error handling. What will be the value of ax_status? Sure, some stack-protector-GCC-plugins might initialize it to 0, but that's not a good design. There is no error handling of all SPI functions so entire driver works because of luck... if there is any error in the middle of some work, it won't spot it. > + return 1; > + > + return 0; > +} > + > +u8 ax88796c_check_power_and_wake(struct ax88796c_device *ax_local) > +{ > + struct spi_status ax_status; > + unsigned long start_time; > + > + /* Check media link status first */ > + if (netif_carrier_ok(ax_local->ndev) || > + (ax_local->ps_level == AX_PS_D0) || > + (ax_local->ps_level == AX_PS_D1)) { > + return 0; > + } > + > + AX_READ_STATUS(&ax_local->ax_spi, &ax_status); > + if (!(ax_status.status & AX_STATUS_READY)) { > + > + /* AX88796C in power saving mode */ > + AX_WAKEUP(&ax_local->ax_spi); > + > + /* Check status */ > + start_time = jiffies; > + do { > + if (time_after(jiffies, start_time + HZ/2)) { > + netdev_err(ax_local->ndev, > + "timeout waiting for wakeup" > + " from power saving\n"); > + break; > + } > + > + AX_READ_STATUS(&ax_local->ax_spi, &ax_status); > + > + } while (!(ax_status.status & AX_STATUS_READY)); > + > + ax88796c_set_power_saving(ax_local, AX_PS_D0); > + > + return 1; > + } > + > + return 0; > +} > + > +void ax88796c_set_power_saving(struct ax88796c_device *ax_local, u8 ps_level) > +{ > + u16 pmm; > + > + if (ps_level == AX_PS_D1) > + pmm = PSCR_PS_D1; > + else if (ps_level == AX_PS_D2) > + pmm = PSCR_PS_D2; > + else > + pmm = PSCR_PS_D0; > + > + AX_WRITE(&ax_local->ax_spi, (AX_READ(&ax_local->ax_spi, P0_PSCR) > + & PSCR_PS_MASK) | pmm, P0_PSCR); > +} > + > +int ax88796c_mdio_read(struct net_device *ndev, int phy_id, int loc) > +{ > + struct ax88796c_device *ax_local = to_ax88796c_device(ndev); > + unsigned long start_time; > + > + AX_WRITE(&ax_local->ax_spi, MDIOCR_RADDR(loc) > + | MDIOCR_FADDR(phy_id) | MDIOCR_READ, P2_MDIOCR); > + > + start_time = jiffies; > + while ((AX_READ(&ax_local->ax_spi, P2_MDIOCR) & MDIOCR_VALID) == 0) { > + if (time_after(jiffies, start_time + HZ/100)) > + return -EBUSY; > + } > + > + return AX_READ(&ax_local->ax_spi, P2_MDIODR); > +} > + > +void > +ax88796c_mdio_write(struct net_device *ndev, int phy_id, int loc, int val) > +{ > + struct ax88796c_device *ax_local = to_ax88796c_device(ndev); > + unsigned long start_time; > + > + AX_WRITE(&ax_local->ax_spi, val, P2_MDIODR); > + > + AX_WRITE(&ax_local->ax_spi, > + MDIOCR_RADDR(loc) | MDIOCR_FADDR(phy_id) > + | MDIOCR_WRITE, P2_MDIOCR); > + > + start_time = jiffies; > + while ((AX_READ(&ax_local->ax_spi, P2_MDIOCR) & MDIOCR_VALID) == 0) { > + if (time_after(jiffies, start_time + HZ/100)) > + return; > + } > + > + if (loc == MII_ADVERTISE) { > + AX_WRITE(&ax_local->ax_spi, (BMCR_FULLDPLX | BMCR_ANRESTART | > + BMCR_ANENABLE | BMCR_SPEED100), P2_MDIODR); > + AX_WRITE(&ax_local->ax_spi, (MDIOCR_RADDR(MII_BMCR) | > + MDIOCR_FADDR(phy_id) | MDIOCR_WRITE), > + P2_MDIOCR); > + > + start_time = jiffies; > + while ((AX_READ(&ax_local->ax_spi, P2_MDIOCR) > + & MDIOCR_VALID) == 0) { > + if (time_after(jiffies, start_time + HZ/100)) > + return; > + } > + } > +} > + > +void ax88796c_set_csums(struct ax88796c_device *ax_local) > +{ > + if (ax_local->checksum & AX_RX_CHECKSUM) { > + AX_WRITE(&ax_local->ax_spi, COERCR0_DEFAULT, P4_COERCR0); > + AX_WRITE(&ax_local->ax_spi, COERCR1_DEFAULT, P4_COERCR1); > + } else { > + AX_WRITE(&ax_local->ax_spi, 0, P4_COERCR0); > + AX_WRITE(&ax_local->ax_spi, 0, P4_COERCR1); > + } > + > + if (ax_local->checksum & AX_TX_CHECKSUM) { > + AX_WRITE(&ax_local->ax_spi, COETCR0_DEFAULT, P4_COETCR0); > + AX_WRITE(&ax_local->ax_spi, COETCR1_TXPPPE, P4_COETCR1); > + } else { > + AX_WRITE(&ax_local->ax_spi, 0, P4_COETCR0); > + AX_WRITE(&ax_local->ax_spi, 0, P4_COETCR1); > + } > +} > + > +static void ax88796c_get_drvinfo(struct net_device *ndev, > + struct ethtool_drvinfo *info) > +{ > + /* Inherit standard device info */ > + strncpy(info->driver, DRV_NAME, sizeof(info->driver)); > + strncpy(info->version, DRV_VERSION, sizeof(info->version)); > +} > + > +static u32 ax88796c_get_link(struct net_device *ndev) > +{ > + u32 link; > + struct ax88796c_device *ax_local = to_ax88796c_device(ndev); > + u8 power; > + > + down(&ax_local->spi_lock); > + power = ax88796c_check_power_and_wake(ax_local); > + > + link = mii_link_ok(&ax_local->mii); > + > + if (power) > + ax88796c_set_power_saving(ax_local, ax_local->ps_level); > + up(&ax_local->spi_lock); > + > + return link; > + > + Empty lines. > +} > + > +static u32 ax88796c_get_msglevel(struct net_device *ndev) > +{ > + struct ax88796c_device *ax_local = to_ax88796c_device(ndev); > + return ax_local->msg_enable; > +} > + > +static void ax88796c_set_msglevel(struct net_device *ndev, u32 level) > +{ > + struct ax88796c_device *ax_local = to_ax88796c_device(ndev); > + ax_local->msg_enable = level; > +} > + > + One line break. > +static int > +ax88796c_get_link_ksettings(struct net_device *ndev, > + struct ethtool_link_ksettings *cmd) > +{ > + struct ax88796c_device *ax_local = to_ax88796c_device(ndev); > + u8 power; > + > + down(&ax_local->spi_lock); > + power = ax88796c_check_power_and_wake(ax_local); > + > + mii_ethtool_get_link_ksettings(&ax_local->mii, cmd); > + > + if (power) > + ax88796c_set_power_saving(ax_local, ax_local->ps_level); > + up(&ax_local->spi_lock); > + > + return 0; > +} > + > +static int > +ax88796c_set_link_ksettings(struct net_device *ndev, > + const struct ethtool_link_ksettings *cmd) > +{ > + struct ax88796c_device *ax_local = to_ax88796c_device(ndev); > + u8 power; > + > + down(&ax_local->spi_lock); > + power = ax88796c_check_power_and_wake(ax_local); > + > + mii_ethtool_set_link_ksettings(&ax_local->mii, cmd); > + > + if (power) > + ax88796c_set_power_saving(ax_local, ax_local->ps_level); > + up(&ax_local->spi_lock); > + return 0; > + Line before return, not after. > +} > + > +static int ax88796c_nway_reset(struct net_device *ndev) > +{ > + struct ax88796c_device *ax_local = to_ax88796c_device(ndev); > + int ret; > + u8 power; > + > + down(&ax_local->spi_lock); > + power = ax88796c_check_power_and_wake(ax_local); > + > + ret = mii_nway_restart(&ax_local->mii); > + > + if (power) > + ax88796c_set_power_saving(ax_local, ax_local->ps_level); > + up(&ax_local->spi_lock); > + return ret; > +} > + > +static u32 ax88796c_ethtool_getmsglevel(struct net_device *ndev) > +{ > + struct ax88796c_device *ax_local = to_ax88796c_device(ndev); > + return ax_local->msg_enable; > +} > + > +static void ax88796c_ethtool_setmsglevel(struct net_device *ndev, u32 level) > +{ > + struct ax88796c_device *ax_local = to_ax88796c_device(ndev); > + ax_local->msg_enable = level; > +} > + > +struct ethtool_ops ax88796c_ethtool_ops = { > + .get_drvinfo = ax88796c_get_drvinfo, > + .get_link = ax88796c_get_link, > + .get_msglevel = ax88796c_get_msglevel, > + .set_msglevel = ax88796c_set_msglevel, > + .get_link_ksettings = ax88796c_get_link_ksettings, > + .set_link_ksettings = ax88796c_set_link_ksettings, > + .nway_reset = ax88796c_nway_reset, > + .get_msglevel = ax88796c_ethtool_getmsglevel, > + .set_msglevel = ax88796c_ethtool_setmsglevel, > +}; > + > +int ax88796c_ioctl(struct net_device *ndev, struct ifreq *ifr, int cmd) > +{ > + struct ax88796c_device *ax_local = to_ax88796c_device(ndev); > + int ret; > + u8 power; > + > + down(&ax_local->spi_lock); > + power = ax88796c_check_power_and_wake(ax_local); > + > + ret = generic_mii_ioctl(&ax_local->mii, if_mii(ifr), cmd, NULL); > + > + if (power) > + ax88796c_set_power_saving(ax_local, ax_local->ps_level); > + up(&ax_local->spi_lock); > + > + return ret; > +} > + > diff --git a/drivers/net/ethernet/asix/ax88796c_ioctl.h b/drivers/net/ethernet/asix/ax88796c_ioctl.h > new file mode 100644 > index 000000000000..bafd573bd813 > --- /dev/null > +++ b/drivers/net/ethernet/asix/ax88796c_ioctl.h > @@ -0,0 +1,21 @@ > +// SPDX-License-Identifier: GPL-2.0-only > +/* > + * Copyright (c) 2010 ASIX Electronics Corporation > + * > + * ASIX AX88796C SPI Fast Ethernet Linux driver > + */ > + > +#ifndef _AX88796C_IOCTL_H > +#define _AX88796C_IOCTL_H > + > +extern struct ethtool_ops ax88796c_ethtool_ops; > + > +u8 ax88796c_check_power(struct ax88796c_device *ax_local); > +u8 ax88796c_check_power_and_wake(struct ax88796c_device *ax_local); > +void ax88796c_set_power_saving(struct ax88796c_device *ax_local, u8 ps_level); > +int ax88796c_mdio_read(struct net_device *dev, int phy_id, int loc); > +void ax88796c_mdio_write(struct net_device *dev, int phy_id, int loc, int val); > +void ax88796c_set_csums(struct ax88796c_device *ax_local); > +int ax88796c_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd); > + > +#endif > diff --git a/drivers/net/ethernet/asix/ax88796c_main.c b/drivers/net/ethernet/asix/ax88796c_main.c > new file mode 100644 > index 000000000000..c28cfb931319 > --- /dev/null > +++ b/drivers/net/ethernet/asix/ax88796c_main.c > @@ -0,0 +1,1373 @@ > +// SPDX-License-Identifier: GPL-2.0-only > +/* > + * Copyright (c) 2010 ASIX Electronics Corporation > + * Copyright (c) 2020 Samsung Electronics Co., Ltd. > + * > + * ASIX AX88796C SPI Fast Ethernet Linux driver > + */ > + > +#include "ax88796c_main.h" > +#include "ax88796c_ioctl.h" > + > +static int comp; > +static int ps_level = AX_PS_D0; > +static int msg_enable = NETIF_MSG_PROBE | > + NETIF_MSG_LINK | > + /* NETIF_MSG_TIMER | */ > + NETIF_MSG_RX_ERR | > + NETIF_MSG_TX_ERR | > + /* NETIF_MSG_TX_QUEUED | */ > + /* NETIF_MSG_INTR | */ > + /* NETIF_MSG_TX_DONE | */ > + /* NETIF_MSG_RX_STATUS | */ > + /* NETIF_MSG_PKTDATA | */ > + /* NETIF_MSG_HW | */ > + NETIF_MSG_WOL; > + > +module_param(comp, int, 0); > +MODULE_PARM_DESC(comp, "0=Non-Compression Mode, 1=Compression Mode"); > + > +module_param(ps_level, int, 0); > +MODULE_PARM_DESC(ps_level, > + "Power Saving Level (0:disable 1:level 1 2:level 2)"); > + > +module_param(msg_enable, int, 0); > +MODULE_PARM_DESC(msg_enable, "Message mask (see linux/netdevice.h for bitmap)"); > + > +static char *macaddr; > +module_param(macaddr, charp, 0); > +MODULE_PARM_DESC(macaddr, "MAC address"); I think MAC address as param is not accepted in mainline... > + > +MODULE_AUTHOR("ASIX"); > +MODULE_DESCRIPTION("ASIX AX88796C SPI Ethernet driver"); > +MODULE_LICENSE("GPL"); These three usually go to the end of file. > + > +static void ax88796c_dump_regs(struct ax88796c_device *ax_local) > +{ > + struct net_device *ndev = ax_local->ndev; > + u8 i, j; > + > + netdev_info(ndev, > + " Page0 Page1 Page2 Page3 " > + "Page4 Page5 Page6 Page7\n"); > + for (i = 0; i < 0x20; i += 2) { > + netdev_info(ndev, "0x%02x ", i); > + for (j = 0; j < 8; j++) { > + netdev_info(ndev, "0x%04x ", > + AX_READ(&ax_local->ax_spi, j * 0x20 + i)); > + } > + netdev_info(ndev, "\n"); > + } > + netdev_info(ndev, "\n"); > +} > + > +static void ax88796c_dump_phy_regs(struct ax88796c_device *ax_local) > +{ > + struct net_device *ndev = ax_local->ndev; > + int i; > + > + netdev_info(ndev, "Dump PHY registers:\n"); > + for (i = 0; i < 6; i++) { > + netdev_info(ndev, " MR%d = 0x%04x\n", i, > + ax88796c_mdio_read(ax_local->ndev, > + ax_local->mii.phy_id, i)); > + } > +} > + > +static void ax88796c_watchdog(struct ax88796c_device *ax_local) > +{ > + struct net_device *ndev = ax_local->ndev; > + u16 phy_status; > + unsigned long time_to_chk = AX88796C_WATCHDOG_PERIOD; > + > + if (ax88796c_check_power(ax_local)) { > + mod_timer(&ax_local->watchdog, jiffies + time_to_chk); > + return; > + } > + > + ax88796c_set_power_saving(ax_local, AX_PS_D0); > + > + phy_status = AX_READ(&ax_local->ax_spi, P0_PSCR); > + if (phy_status & PSCR_PHYLINK) { > + > + ax_local->w_state = ax_nop; > + time_to_chk = 0; > + > + } else if (!(phy_status & PSCR_PHYCOFF)) { > + /* The ethernet cable has been plugged */ > + if (ax_local->w_state == chk_cable) { > + if (netif_msg_timer(ax_local)) > + netdev_info(ndev, "Cable connected\n"); > + > + ax_local->w_state = chk_link; > + ax_local->w_ticks = 0; > + } else { > + if (netif_msg_timer(ax_local)) > + netdev_info(ndev, "Check media status\n"); > + > + if (++ax_local->w_ticks == AX88796C_WATCHDOG_RESTART) { > + if (netif_msg_timer(ax_local)) > + netdev_info(ndev, "Restart autoneg\n"); > + ax88796c_mdio_write(ndev, > + ax_local->mii.phy_id, MII_BMCR, > + (BMCR_SPEED100 | BMCR_ANENABLE | > + BMCR_ANRESTART)); > + > + if (netif_msg_hw(ax_local)) > + ax88796c_dump_phy_regs(ax_local); > + ax_local->w_ticks = 0; > + } > + } > + } else { > + if (netif_msg_timer(ax_local)) > + netdev_info(ndev, "Check cable status\n"); > + > + ax_local->w_state = chk_cable; > + } > + > + ax88796c_set_power_saving(ax_local, ax_local->ps_level); > + > + if (time_to_chk) > + mod_timer(&ax_local->watchdog, jiffies + time_to_chk); > +} > + > +static void ax88796c_watchdog_timer(struct timer_list *t) > +{ > + struct ax88796c_device *ax_local = from_timer(ax_local, t, watchdog); > + //struct net_device *ndev = ax_local->ndev; Clean up. > + > + set_bit(EVENT_WATCHDOG, &ax_local->flags); > + queue_work(ax_local->ax_work_queue, &ax_local->ax_work); > +} > + > +static int ax88796c_soft_reset(struct ax88796c_device *ax_local) > +{ > + unsigned long start; > + u16 temp; > + > + AX_WRITE(&ax_local->ax_spi, PSR_RESET, P0_PSR); > + AX_WRITE(&ax_local->ax_spi, PSR_RESET_CLR, P0_PSR); > + > + start = jiffies; > + while (!(AX_READ(&ax_local->ax_spi, P0_PSR) & PSR_DEV_READY)) { > + if (time_after(jiffies, start + (160 * HZ / 1000))) { > + dev_err(&ax_local->spi->dev, > + "timeout waiting for reset completion\n"); > + return -1; > + } > + } > + > + temp = AX_READ(&ax_local->ax_spi, P4_SPICR); > + if (ax_local->capabilities & AX_CAP_COMP) { > + AX_WRITE(&ax_local->ax_spi, > + (temp | SPICR_RCEN | SPICR_QCEN), P4_SPICR); > + ax_local->ax_spi.comp = 1; > + } else { > + AX_WRITE(&ax_local->ax_spi, > + (temp & ~(SPICR_RCEN | SPICR_QCEN)), P4_SPICR); > + ax_local->ax_spi.comp = 0; > + } > + > + return 0; > +} > + > +static int ax88796c_reload_eeprom(struct ax88796c_device *ax_local) > +{ > + unsigned long start; > + > + AX_WRITE(&ax_local->ax_spi, EECR_RELOAD, P3_EECR); > + > + start = jiffies; > + while (!(AX_READ(&ax_local->ax_spi, P0_PSR) & PSR_DEV_READY)) { > + if (time_after(jiffies, start + (2 * HZ / 100))) { > + dev_err(&ax_local->spi->dev, > + "timeout waiting for reload eeprom\n"); > + return -1; > + } > + } > + > + return 0; > +} > + > +static void ax88796c_set_hw_multicast(struct net_device *ndev) > +{ > + struct ax88796c_device *ax_local = to_ax88796c_device(ndev); > + u16 rx_ctl = RXCR_AB; > + int mc_count = netdev_mc_count(ndev); > + > + memset(ax_local->multi_filter, 0, AX_MCAST_FILTER_SIZE); > + > + if (ndev->flags & IFF_PROMISC) { > + rx_ctl |= RXCR_PRO; > + > + } else if (ndev->flags & IFF_ALLMULTI > + || mc_count > AX_MAX_MCAST) { > + rx_ctl |= RXCR_AMALL; > + > + } else if (mc_count == 0) { > + /* just broadcast and directed */ > + } else { > + u32 crc_bits; > + int i; > + struct netdev_hw_addr *ha; > + netdev_for_each_mc_addr(ha, ndev) { > + crc_bits = ether_crc(ETH_ALEN, ha->addr); > + ax_local->multi_filter[crc_bits >> 29] |= > + (1 << ((crc_bits >> 26) & 7)); > + } > + > + for (i = 0; i < 4; i++) { > + AX_WRITE(&ax_local->ax_spi, > + ((ax_local->multi_filter[i*2+1] << 8) | > + ax_local->multi_filter[i*2]), P3_MFAR(i)); > + > + } > + } > + > + AX_WRITE(&ax_local->ax_spi, rx_ctl, P2_RXCR); > + No need for empty line. > +} > + > +#if 0 Please comment why it is commented out. > +static void ax88796c_set_multicast(struct net_device *ndev) > +{ > + struct ax88796c_device *ax_local = to_ax88796c_device(ndev); > + > + set_bit(EVENT_SET_MULTI, &ax_local->flags); > + queue_work(ax_local->ax_work_queue, &ax_local->ax_work); > +} > +#endif > + > +static void ax88796c_set_mac_addr(struct net_device *ndev) > +{ > + struct ax88796c_device *ax_local = to_ax88796c_device(ndev); > + > + AX_WRITE(&ax_local->ax_spi, ((u16)(ndev->dev_addr[4] << 8) | > + (u16)ndev->dev_addr[5]), P3_MACASR0); > + AX_WRITE(&ax_local->ax_spi, ((u16)(ndev->dev_addr[2] << 8) | > + (u16)ndev->dev_addr[3]), P3_MACASR1); > + AX_WRITE(&ax_local->ax_spi, ((u16)(ndev->dev_addr[0] << 8) | > + (u16)ndev->dev_addr[1]), P3_MACASR2); > +} > + > +static int ax88796c_set_mac_address(struct net_device *ndev, void *p) > +{ > + struct ax88796c_device *ax_local = to_ax88796c_device(ndev); > + struct sockaddr *addr = p; > + > + if (!is_valid_ether_addr(addr->sa_data)) > + return -EADDRNOTAVAIL; > + > + memcpy(ndev->dev_addr, addr->sa_data, ndev->addr_len); > + > + down(&ax_local->spi_lock); > + > + ax88796c_set_mac_addr(ndev); > + > + up(&ax_local->spi_lock); > + > + return 0; > +} > + > +static int ax88796c_load_mac_addr(struct net_device *ndev) > +{ > + struct ax88796c_device *ax_local = to_ax88796c_device(ndev); > + u16 temp; > + > + /* Read the MAC address from AX88796C */ > + temp = AX_READ(&ax_local->ax_spi, P3_MACASR0); > + ndev->dev_addr[5] = (u8)temp; > + ndev->dev_addr[4] = (u8)(temp >> 8); > + > + temp = AX_READ(&ax_local->ax_spi, P3_MACASR1); > + ndev->dev_addr[3] = (u8)temp; > + ndev->dev_addr[2] = (u8)(temp >> 8); > + > + temp = AX_READ(&ax_local->ax_spi, P3_MACASR2); > + ndev->dev_addr[1] = (u8)temp; > + ndev->dev_addr[0] = (u8)(temp >> 8); > + > + /* Supported for no EEPROM */ > + if (!is_valid_ether_addr(ndev->dev_addr)) { > + if (macaddr && mac_pton(macaddr, ndev->dev_addr)) > + return 0; > + > + if (netif_msg_probe(ax_local)) > + dev_info(&ax_local->spi->dev, "Use random MAC address\n"); > + > + random_ether_addr(ndev->dev_addr); > + } > + > + return 0; > +} > + > +static void ax88796c_proc_tx_hdr(struct tx_pkt_info *info, u8 ip_summed) > +{ > + u16 pkt_len_bar = (~info->pkt_len & TX_HDR_SOP_PKTLENBAR); > + > + /* Prepare SOP header */ > + info->sop.flags_len = info->pkt_len | > + (ip_summed == CHECKSUM_NONE ? TX_HDR_SOP_DICF : 0); > + > + info->sop.seq_lenbar = ((info->seq_num << 11) & TX_HDR_SOP_SEQNUM) > + | pkt_len_bar; > + cpu_to_be16s(&info->sop.flags_len); > + cpu_to_be16s(&info->sop.seq_lenbar); > + > + /* Prepare Segment header */ > + info->seg.flags_seqnum_seglen = TX_HDR_SEG_FS | TX_HDR_SEG_LS > + | info->pkt_len; > + > + info->seg.eo_so_seglenbar = pkt_len_bar; > + > + cpu_to_be16s(&info->seg.flags_seqnum_seglen); > + cpu_to_be16s(&info->seg.eo_so_seglenbar); > + > + /* Prepare EOP header */ > + info->eop.seq_len = ((info->seq_num << 11) & > + TX_HDR_EOP_SEQNUM) | info->pkt_len; > + info->eop.seqbar_lenbar = ((~info->seq_num << 11) & > + TX_HDR_EOP_SEQNUMBAR) | pkt_len_bar; > + > + cpu_to_be16s(&info->eop.seq_len); > + cpu_to_be16s(&info->eop.seqbar_lenbar); > +} > + > +static int > +ax88796c_check_free_pages(struct ax88796c_device *ax_local, u8 need_pages) > +{ > + u8 free_pages; > + u16 tmp; > + > + free_pages = AX_READ(&ax_local->ax_spi, P0_TFBFCR) & TX_FREEBUF_MASK; > + if (free_pages < need_pages) { > + /* schedule free page interrupt */ > + tmp = AX_READ(&ax_local->ax_spi, P0_TFBFCR) > + & TFBFCR_SCHE_FREE_PAGE; > + AX_WRITE(&ax_local->ax_spi, tmp | TFBFCR_TX_PAGE_SET | > + TFBFCR_SET_FREE_PAGE(need_pages), > + P0_TFBFCR); > + return -ENOMEM; > + } > + > + return 0; > +} > + > +static struct sk_buff * > +ax88796c_tx_fixup(struct net_device *ndev, struct sk_buff_head *q) > +{ > + struct ax88796c_device *ax_local = to_ax88796c_device(ndev); > + struct sk_buff *skb, *tx_skb; > + struct tx_pkt_info *info; > + struct skb_data *entry; > + int headroom; > + int tailroom; > + u8 need_pages; > + u16 tol_len, pkt_len; > + u8 padlen, seq_num; > + u8 spi_len = ax_local->ax_spi.comp ? 1 : 4; > + > + if (skb_queue_empty(q)) > + return NULL; > + > + skb = skb_peek(q); > + pkt_len = skb->len; > + need_pages = (pkt_len + TX_OVERHEAD + 127) >> 7; > + if (ax88796c_check_free_pages(ax_local, need_pages) != 0) > + return NULL; > + > + headroom = skb_headroom(skb); > + tailroom = skb_tailroom(skb); > + padlen = ((pkt_len + 3) & 0x7FC) - pkt_len; > + tol_len = ((pkt_len + 3) & 0x7FC) + > + TX_OVERHEAD + TX_EOP_SIZE + spi_len; > + seq_num = ++ax_local->seq_num & 0x1F; > + > + info = (struct tx_pkt_info *) skb->cb; > + info->pkt_len = pkt_len; > + > + if ((!skb_cloned(skb)) && > + (headroom >= (TX_OVERHEAD + spi_len)) && > + (tailroom >= (padlen + TX_EOP_SIZE))) { > + > + info->seq_num = seq_num; > + ax88796c_proc_tx_hdr(info, skb->ip_summed); > + > + /* SOP and SEG header */ > + memcpy(skb_push(skb, TX_OVERHEAD), &info->sop, TX_OVERHEAD); > + > + /* Write SPI TXQ header */ > + memcpy(skb_push(skb, spi_len), tx_cmd_buf, spi_len); > + > + /* Make 32-bit aligment */ > + skb_put(skb, padlen); > + > + /* EOP header */ > + memcpy(skb_put(skb, TX_EOP_SIZE), &info->eop, TX_EOP_SIZE); > + > + tx_skb = skb; > + skb_unlink(skb, q); > + > + } else { > + > + tx_skb = alloc_skb(tol_len, GFP_KERNEL); > + if (!tx_skb) > + return NULL; > + > + /* Write SPI TXQ header */ > + memcpy(skb_put(tx_skb, spi_len), tx_cmd_buf, spi_len); > + > + info->seq_num = seq_num; > + ax88796c_proc_tx_hdr(info, skb->ip_summed); > + > + /* SOP and SEG header */ > + memcpy(skb_put(tx_skb, TX_OVERHEAD), > + &info->sop, TX_OVERHEAD); > + > + /* Packet */ > + memcpy(skb_put(tx_skb, ((pkt_len + 3) & 0xFFFC)), > + skb->data, pkt_len); > + > + /* EOP header */ > + memcpy(skb_put(tx_skb, TX_EOP_SIZE), > + &info->eop, TX_EOP_SIZE); > + > + skb_unlink(skb, q); > + dev_kfree_skb(skb); > + } > + > + entry = (struct skb_data *) tx_skb->cb; > + memset(entry, 0, sizeof(*entry)); > + entry->len = pkt_len; > + > + if (netif_msg_pktdata(ax_local)) { > + int loop; > + netdev_info(ndev, "TX packet len %d, total len %d, seq %d\n", > + pkt_len, tx_skb->len, seq_num); > + > + netdev_info(ndev, " Dump SPI Header:\n "); > + for (loop = 0; loop < 4; loop++) > + netdev_info(ndev, "%02x ", *(tx_skb->data + loop)); > + > + netdev_info(ndev, "\n"); > + > + netdev_info(ndev, " Dump TX SOP:\n "); > + for (loop = 0; loop < TX_OVERHEAD; loop++) > + netdev_info(ndev, "%02x ", *(tx_skb->data + 4 + loop)); > + > + netdev_info(ndev, "\n"); > + > + netdev_info(ndev, " Dump TX packet:"); > + for (loop = TX_OVERHEAD + 4; > + loop < (tx_skb->len - TX_EOP_SIZE); loop++) { > + if (((loop + 8) % 16) == 0) > + netdev_info(ndev, "\n "); > + netdev_info(ndev, "%02x ", *(tx_skb->data + loop)); > + } > + netdev_info(ndev, "\n"); > + > + netdev_info(ndev, " Dump TX EOP:\n %02x %02x %02x %02x\n", > + *(tx_skb->data + tx_skb->len - 4), > + *(tx_skb->data + tx_skb->len - 3), > + *(tx_skb->data + tx_skb->len - 2), > + *(tx_skb->data + tx_skb->len - 1)); > + } > + > + return tx_skb; > +} > + > +static int ax88796c_hard_xmit(struct ax88796c_device *ax_local) > +{ > + struct sk_buff *tx_skb; > + struct skb_data *entry; > + > + tx_skb = ax88796c_tx_fixup(ax_local->ndev, &ax_local->tx_wait_q); > + > + if (!tx_skb) > + return 0; > + > + entry = (struct skb_data *)tx_skb->cb; > + > + AX_WRITE(&ax_local->ax_spi, > + (TSNR_TXB_START | TSNR_PKT_CNT(1)), P0_TSNR); > + > + axspi_write_txq(&ax_local->ax_spi, tx_skb->data, tx_skb->len); > + > + if (((AX_READ(&ax_local->ax_spi, P0_TSNR) & TXNR_TXB_IDLE) == 0) || > + ((ISR_TXERR & AX_READ(&ax_local->ax_spi, P0_ISR)) != 0)) { > + > + /* Ack tx error int */ > + AX_WRITE(&ax_local->ax_spi, ISR_TXERR, P0_ISR); > + > + ax_local->stats.tx_dropped++; > + > + if (netif_msg_tx_err(ax_local)) > + netdev_err(ax_local->ndev, > + "TX FIFO error, re-initialize the TX bridge\n"); > + > + /* Reinitial tx bridge */ > + AX_WRITE(&ax_local->ax_spi, TXNR_TXB_REINIT | > + AX_READ(&ax_local->ax_spi, P0_TSNR), P0_TSNR); > + ax_local->seq_num = 0; > + } else { > + ax_local->stats.tx_packets++; > + ax_local->stats.tx_bytes += entry->len; > + } > + > + entry->state = tx_done; > + dev_kfree_skb(tx_skb); > + > + return 1; > +} > + > +static int > +ax88796c_start_xmit(struct sk_buff *skb, struct net_device *ndev) > +{ > + struct ax88796c_device *ax_local = to_ax88796c_device(ndev); > + > + skb_queue_tail(&ax_local->tx_wait_q, skb); > + if (skb_queue_len(&ax_local->tx_wait_q) > TX_QUEUE_HIGH_WATER) { > + if (netif_msg_tx_queued(ax_local)) > + netdev_err(ndev, "Too much TX packets in queue %d\n", > + skb_queue_len(&ax_local->tx_wait_q)); > + > + netif_stop_queue(ndev); > + } > + > + set_bit(EVENT_TX, &ax_local->flags); > + queue_work(ax_local->ax_work_queue, &ax_local->ax_work); > + > + return NETDEV_TX_OK; > + > +} > + > + > +static inline void > +ax88796c_skb_return(struct ax88796c_device *ax_local, struct sk_buff *skb, > + struct rx_header *rxhdr) > +{ > + struct net_device *ndev = ax_local->ndev; > + int status; > + > + do { > + if (!(ax_local->checksum & AX_RX_CHECKSUM)) > + break; > + > + /* checksum error bit is set */ > + if ((rxhdr->flags & RX_HDR3_L3_ERR) || > + (rxhdr->flags & RX_HDR3_L4_ERR)) > + break; > + > + if ((rxhdr->flags & RX_HDR3_L4_TYPE_TCP) || > + (rxhdr->flags & RX_HDR3_L4_TYPE_UDP)) { > + skb->ip_summed = CHECKSUM_UNNECESSARY; > + } > + } while (0); > + > + ax_local->stats.rx_packets++; > + ax_local->stats.rx_bytes += skb->len; > + skb->dev = ndev; > + > + skb->truesize = skb->len + sizeof(struct sk_buff); > + skb->protocol = eth_type_trans(skb, ax_local->ndev); > + > + if (netif_msg_rx_status(ax_local)) > + netdev_info(ndev, "< rx, len %zu, type 0x%x\n", > + skb->len + sizeof(struct ethhdr), skb->protocol); > + > + status = netif_rx(skb); > + if (status != NET_RX_SUCCESS && netif_msg_rx_err(ax_local)) > + netdev_info(ndev, "netif_rx status %d\n", status); > +} > + > +static void dump_packet(struct net_device *ndev, const char *msg, int len, const char *data) > +{ Too long lines. > + netdev_printk(KERN_DEBUG, ndev, DRV_NAME ": %s - packet len:%d\n", msg, len); > + print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 16, 1, > + data, len, true); > +} > + > +static void > +ax88796c_rx_fixup(struct ax88796c_device *ax_local, struct sk_buff *rx_skb) > +{ > + struct rx_header *rxhdr = (struct rx_header *) rx_skb->data; > + struct net_device *ndev = ax_local->ndev; > + u16 len; > + > + be16_to_cpus(&rxhdr->flags_len); > + be16_to_cpus(&rxhdr->seq_lenbar); > + be16_to_cpus(&rxhdr->flags); > + > + if ((((short)rxhdr->flags_len) & RX_HDR1_PKT_LEN) != > + (~((short)rxhdr->seq_lenbar) & 0x7FF)) { > + if (netif_msg_rx_err(ax_local)) { > + int i; > + netdev_err(ndev, "Header error\n"); > + //netdev_err(ndev, "Dump received frame\n"); > + /* for (i = 0; i < rx_skb->len; i++) { */ > + /* netdev_err(ndev, "%02x ", */ > + /* *(rx_skb->data + i)); */ > + /* if (((i + 1) % 16) == 0) */ > + /* netdev_err(ndev, "\n"); */ > + /* } */ > + dump_packet(ndev, __func__, rx_skb->len, rx_skb->data); > + } > + ax_local->stats.rx_frame_errors++; > + kfree_skb(rx_skb); > + return; > + } > + > + if ((rxhdr->flags_len & RX_HDR1_MII_ERR) || > + (rxhdr->flags_len & RX_HDR1_CRC_ERR)) { > + if (netif_msg_rx_err(ax_local)) > + netdev_err(ndev, "CRC or MII error\n"); > + > + ax_local->stats.rx_crc_errors++; > + kfree_skb(rx_skb); > + return; > + } > + > + len = rxhdr->flags_len & RX_HDR1_PKT_LEN; > + if (netif_msg_pktdata(ax_local)) { > + int loop; > + netdev_info(ndev, "RX data, total len %d, packet len %d\n", > + rx_skb->len, len); > + > + netdev_info(ndev, " Dump RX packet header:\n "); > + for (loop = 0; loop < sizeof(*rxhdr); loop++) > + netdev_info(ndev, "%02x ", *(rx_skb->data + loop)); > + > + netdev_info(ndev, "\n Dump RX packet:"); > + for (loop = 0; loop < len; loop++) { > + if ((loop % 16) == 0) > + netdev_info(ndev, "\n "); > + netdev_info(ndev, "%02x ", > + *(rx_skb->data + loop + sizeof(*rxhdr))); > + } > + netdev_info(ndev, "\n"); > + } > + > + skb_pull(rx_skb, sizeof(*rxhdr)); > + __pskb_trim(rx_skb, len); > + > + return ax88796c_skb_return(ax_local, rx_skb, rxhdr); > +} > + > +static int ax88796c_receive(struct net_device *ndev) > +{ > + struct ax88796c_device *ax_local = to_ax88796c_device(ndev); > + struct sk_buff *skb; > + struct skb_data *entry; > + u16 w_count, pkt_len; > + u8 pkt_cnt; > + > + /* check rx packet and total word count */ > + AX_WRITE(&ax_local->ax_spi, AX_READ(&ax_local->ax_spi, P0_RTWCR) > + | RTWCR_RX_LATCH, P0_RTWCR); > + > + pkt_cnt = AX_READ(&ax_local->ax_spi, P0_RXBCR2) & RXBCR2_PKT_MASK; > + if (!pkt_cnt) > + return 0; > + > + pkt_len = AX_READ(&ax_local->ax_spi, P0_RCPHR) & 0x7FF; > + > + w_count = ((pkt_len + 6 + 3) & 0xFFFC) >> 1; > + > + skb = alloc_skb((w_count * 2), GFP_KERNEL); > + if (!skb) { > + if (netif_msg_rx_err(ax_local)) > + netdev_err(ndev, > + "Couldn't allocate a sk_buff of size %d\n", > + w_count * 2); > + > + AX_WRITE(&ax_local->ax_spi, RXBCR1_RXB_DISCARD, P0_RXBCR1); > + return 0; > + } > + entry = (struct skb_data *) skb->cb; > + > + AX_WRITE(&ax_local->ax_spi, RXBCR1_RXB_START | w_count, P0_RXBCR1); > + > + axspi_read_rxq(&ax_local->ax_spi, > + skb_put(skb, w_count * 2), skb->len); > + > + /* Check if rx bridge is idle */ > + if ((AX_READ(&ax_local->ax_spi, P0_RXBCR2) & RXBCR2_RXB_IDLE) == 0) { > + > + if (netif_msg_rx_err(ax_local)) > + netdev_err(ndev, "Rx Bridge is not idle\n"); > + AX_WRITE(&ax_local->ax_spi, RXBCR2_RXB_REINIT, P0_RXBCR2); > + > + entry->state = rx_err; > + > + } else { > + > + entry->state = rx_done; > + } > + > + AX_WRITE(&ax_local->ax_spi, ISR_RXPKT, P0_ISR); > + > + ax88796c_rx_fixup(ax_local, skb); > + > + return 1; > +} > + > +static void ax88796c_check_media(struct ax88796c_device *ax_local) > +{ > + struct net_device *ndev = ax_local->ndev; > + u16 bmsr, bmcr; > + > + if (netif_msg_hw(ax_local)) > + ax88796c_dump_phy_regs(ax_local); > + > + bmsr = ax88796c_mdio_read(ndev, > + ax_local->mii.phy_id, MII_BMSR); > + > + if (!(bmsr & BMSR_LSTATUS) && netif_carrier_ok(ndev)) { > + > + netif_carrier_off(ndev); > + if (netif_msg_link(ax_local)) > + netdev_info(ndev, "link down\n"); > + > + ax_local->w_state = chk_cable; > + mod_timer(&ax_local->watchdog, > + jiffies + AX88796C_WATCHDOG_PERIOD); > + > + } else if ((bmsr & BMSR_LSTATUS) && > + !netif_carrier_ok(ndev)) { > + bmcr = ax88796c_mdio_read(ndev, > + ax_local->mii.phy_id, MII_BMCR); > + if (netif_msg_link(ax_local)) > + netdev_info(ndev, "link up, %sMbps, %s-duplex\n", > + (bmcr & BMCR_SPEED100) ? "100" : "10", > + (bmcr & BMCR_FULLDPLX) ? "full" : "half"); > + > + netif_carrier_on(ndev); > + } > + > + return; > +} > + > +static int ax88796c_process_isr(struct ax88796c_device *ax_local) > +{ > + u16 isr; > + u8 done = 0; > + struct net_device *ndev = ax_local->ndev; > + > + isr = AX_READ(&ax_local->ax_spi, P0_ISR); > + AX_WRITE(&ax_local->ax_spi, isr, P0_ISR); > + > + if (netif_msg_intr(ax_local)) > + netdev_info(ndev, " ISR 0x%04x\n", isr); > + > + if (isr & ISR_TXERR) { > + if (netif_msg_intr(ax_local)) > + netdev_info(ndev, " TXERR interrupt\n"); > + AX_WRITE(&ax_local->ax_spi, TXNR_TXB_REINIT, P0_TSNR); > + ax_local->seq_num = 0x1f; > + } > + > + if (isr & ISR_TXPAGES) { > + > + if (netif_msg_intr(ax_local)) > + netdev_info(ndev, " TXPAGES interrupt\n"); > + > + set_bit(EVENT_TX, &ax_local->flags); > + } > + > + if (isr & ISR_LINK) { > + > + if (netif_msg_intr(ax_local)) > + netdev_info(ndev, " Link change interrupt\n"); > + > + ax88796c_check_media(ax_local); > + } > + > + if (isr & ISR_RXPKT) { > + > + if (netif_msg_intr(ax_local)) > + netdev_info(ndev, " RX interrupt\n"); > + > + done = ax88796c_receive(ax_local->ndev); > + } > + > + return done; > +} > + > +static irqreturn_t ax88796c_interrupt(int irq, void *dev_instance) > +{ > + struct net_device *ndev = dev_instance; > + struct ax88796c_device *ax_local = to_ax88796c_device(ndev); > + > + if (ndev == NULL) { > + pr_err("irq %d for unknown device.\n", irq); > + return IRQ_RETVAL(0); > + } > + > + disable_irq_nosync(irq); > + > + if (netif_msg_intr(ax_local)) > + netdev_info(ndev, "Interrupt occurred\n"); > + > + set_bit(EVENT_INTR, &ax_local->flags); > + queue_work(ax_local->ax_work_queue, &ax_local->ax_work); > + > + return IRQ_HANDLED; > +} > + > + Only one line > +static void ax88796c_work(struct work_struct *work) > +{ > + struct ax88796c_device *ax_local = > + container_of(work, struct ax88796c_device, ax_work); > + u8 power = 0; > + > + down(&ax_local->spi_lock); > + > + if (test_bit(EVENT_WATCHDOG, &ax_local->flags)) { > + > + ax88796c_watchdog(ax_local); > + > + clear_bit(EVENT_WATCHDOG, &ax_local->flags); > + } > + > + if (test_bit(EVENT_SET_MULTI, &ax_local->flags)) { > + > + power = ax88796c_check_power_and_wake(ax_local); > + > + ax88796c_set_hw_multicast(ax_local->ndev); > + clear_bit(EVENT_SET_MULTI, &ax_local->flags); > + } > + > + if (test_bit(EVENT_INTR, &ax_local->flags)) { > + > + power = ax88796c_check_power_and_wake(ax_local); > + > + AX_WRITE(&ax_local->ax_spi, IMR_MASKALL, P0_IMR); > + > + while (1) { > + if (!ax88796c_process_isr(ax_local)) > + break; > + } > + > + clear_bit(EVENT_INTR, &ax_local->flags); > + > + AX_WRITE(&ax_local->ax_spi, IMR_DEFAULT, P0_IMR); > + > + enable_irq(ax_local->ndev->irq); > + } > + > + if (test_bit(EVENT_TX, &ax_local->flags)) { > + > + power = ax88796c_check_power_and_wake(ax_local); > + > + while (skb_queue_len(&ax_local->tx_wait_q)) { > + if (!ax88796c_hard_xmit(ax_local)) > + break; > + } > + > + clear_bit(EVENT_TX, &ax_local->flags); > + > + if (netif_queue_stopped(ax_local->ndev) && > + (skb_queue_len(&ax_local->tx_wait_q) < TX_QUEUE_LOW_WATER)) > + netif_wake_queue(ax_local->ndev); > + } > + > + if (power) > + ax88796c_set_power_saving(ax_local, ax_local->ps_level); > + > + up(&ax_local->spi_lock); > +} > + > +static struct net_device_stats *ax88796c_get_stats(struct net_device *ndev) > +{ > + struct ax88796c_device *ax_local = to_ax88796c_device(ndev); > + return &ax_local->stats; > +} > + > +void ax88796c_phy_init(struct ax88796c_device *ax_local) > +{ > + u16 advertise = ADVERTISE_ALL | ADVERTISE_CSMA | ADVERTISE_PAUSE_CAP; > + > + /* Setup LED mode */ > + AX_WRITE(&ax_local->ax_spi, > + (LCR_LED0_EN | LCR_LED0_DUPLEX | LCR_LED1_EN | > + LCR_LED1_100MODE), P2_LCR0); > + AX_WRITE(&ax_local->ax_spi, > + (AX_READ(&ax_local->ax_spi, P2_LCR1) & LCR_LED2_MASK) | > + LCR_LED2_EN | LCR_LED2_LINK, P2_LCR1); > + > + /* Enable PHY auto-polling */ > + AX_WRITE(&ax_local->ax_spi, > + POOLCR_PHYID(ax_local->mii.phy_id) | POOLCR_POLL_EN | > + POOLCR_POLL_FLOWCTRL | POOLCR_POLL_BMCR, P2_POOLCR); > + > + ax88796c_mdio_write(ax_local->ndev, > + ax_local->mii.phy_id, MII_ADVERTISE, advertise); > + > + ax88796c_mdio_write(ax_local->ndev, ax_local->mii.phy_id, MII_BMCR, > + BMCR_SPEED100 | BMCR_ANENABLE | BMCR_ANRESTART); > +} > + > +static int > +ax88796c_open(struct net_device *ndev) > +{ > + struct ax88796c_device *ax_local = to_ax88796c_device(ndev); > + int ret; > + u8 power; > + unsigned long irq_flag = IRQF_SHARED; > + > + netif_carrier_off(ax_local->ndev); > + > + down(&ax_local->spi_lock); > + > + power = ax88796c_check_power_and_wake(ax_local); > + > + ret = ax88796c_soft_reset(ax_local); > + if (ret < 0) { > + return -ENODEV; > + } > + > + ret = request_irq(ndev->irq, ax88796c_interrupt, > + irq_flag, ndev->name, ndev); > + if (ret) { > + netdev_err(ndev, "unable to get IRQ %d (errno=%d).\n", > + ndev->irq, ret); > + return -ENXIO; > + } > + > + ax_local->seq_num = 0x1f; > + > + ax88796c_set_mac_addr(ndev); > + ax88796c_set_csums(ax_local); > + > + /* Disable stuffing packet */ > + AX_WRITE(&ax_local->ax_spi, > + AX_READ(&ax_local->ax_spi, P1_RXBSPCR) > + & ~RXBSPCR_STUF_ENABLE, P1_RXBSPCR); > + > + /* Enable RX packet process */ > + AX_WRITE(&ax_local->ax_spi, RPPER_RXEN, P1_RPPER); > + > + AX_WRITE(&ax_local->ax_spi, AX_READ(&ax_local->ax_spi, P0_FER) > + | FER_RXEN | FER_TXEN | FER_BSWAP | FER_IRQ_PULL, P0_FER); > + > + ax88796c_phy_init(ax_local); > + > + netif_start_queue(ndev); > + > + AX_WRITE(&ax_local->ax_spi, IMR_DEFAULT, P0_IMR); > + > + if (netif_msg_hw(ax_local)) { > + netdev_info(ndev, > + "Dump all MAC registers after initialization:\n"); > + ax88796c_dump_regs(ax_local); > + ax88796c_dump_phy_regs(ax_local); > + } > + > + if (power) > + ax88796c_set_power_saving(ax_local, ax_local->ps_level); > + > + spi_message_init(&ax_local->ax_spi.rx_msg); > + > + up(&ax_local->spi_lock); > + > + timer_setup(&ax_local->watchdog, ax88796c_watchdog_timer, 0); > + /* init_timer(&ax_local->watchdog); */ > + /* ax_local->watchdog.function = &ax88796c_watchdog_timer; */ > + /* ax_local->watchdog.data = (unsigned long) ndev; */ I guess it's a development code. > + ax_local->watchdog.expires = jiffies + AX88796C_WATCHDOG_PERIOD; > + ax_local->w_state = chk_cable; > + ax_local->w_ticks = 0; > + > + add_timer(&ax_local->watchdog); > + > + return 0; > +} > + > +static void ax88796c_free_skb_queue(struct sk_buff_head *q) > +{ > + struct sk_buff *skb; > + > + while (q->qlen) { > + skb = skb_dequeue(q); > + kfree_skb(skb); > + } > +} > + > +static int > +ax88796c_close(struct net_device *ndev) > +{ > + struct ax88796c_device *ax_local = to_ax88796c_device(ndev); > + u8 power; > + > + netif_stop_queue(ndev); > + > + del_timer_sync(&ax_local->watchdog); > + > + free_irq(ndev->irq, ndev); > + > + down(&ax_local->spi_lock); > + > + power = ax88796c_check_power_and_wake(ax_local); > + > + AX_WRITE(&ax_local->ax_spi, IMR_MASKALL, P0_IMR); > + ax88796c_free_skb_queue(&ax_local->tx_wait_q); > + > + ax88796c_soft_reset(ax_local); > + > + if (power) > + ax88796c_set_power_saving(ax_local, ax_local->ps_level); > + > + up(&ax_local->spi_lock); > + > + return 0; > +} > + > +static const struct net_device_ops ax88796c_netdev_ops = { > + .ndo_open = ax88796c_open, > + .ndo_stop = ax88796c_close, > + .ndo_start_xmit = ax88796c_start_xmit, > + .ndo_get_stats = ax88796c_get_stats, > + /* .ndo_set_multicast_list = ax88796c_set_multicast, */ Still need a comment. > + .ndo_do_ioctl = ax88796c_ioctl, > + .ndo_set_mac_address = ax88796c_set_mac_address, > +}; > + > + > +static int ax88796c_hard_reset(struct ax88796c_device *ax_local) > +{ > + struct device *dev = (struct device*)&ax_local->spi->dev; > + struct gpio_desc *reset_gpio; > + > + /* reset info */ > + reset_gpio = gpiod_get(dev, "reset", 0); > + if (IS_ERR(reset_gpio)) { > + dev_err(dev, "Could not get 'reset' GPIO: %ld", PTR_ERR(reset_gpio)); > + return PTR_ERR(reset_gpio); > + } > + > + /* set reset */ > + gpiod_direction_output(reset_gpio, 1); > + msleep(100); > + gpiod_direction_output(reset_gpio, 0); > + gpiod_put(reset_gpio); > + msleep(10); > + > + return 0; > +} > + > +static int ax88796c_probe(struct spi_device *spi) > +{ > + struct net_device *ndev; > + struct ax88796c_device *ax_local; > + int ret; > + u16 temp; > + > + ndev = devm_alloc_etherdev(&spi->dev, sizeof(*ax_local)); > + if (!ndev) { > + dev_err(&spi->dev, "AX88796C SPI: Could not allocate ethernet device\n"); > + return -ENOMEM; > + } > + > + ax_local = to_ax88796c_device(ndev); > + memset(ax_local, 0, sizeof(*ax_local)); > + > + dev_set_drvdata(&spi->dev, ax_local); > + ax_local->spi = spi; > + ax_local->ax_spi.spi = spi; > + > + ndev->irq = spi->irq; > + > + ax_local->msg_enable = msg_enable; One space after '='. > + if (ps_level > AX_PS_D2 || ps_level < 0) > + ax_local->ps_level = 0; > + else > + ax_local->ps_level = ps_level; > + > + ax_local->capabilities |= comp ? AX_CAP_COMP : 0; > + > + if (netif_msg_probe(ax_local)) { > + dev_info(&spi->dev, "AX88796C-SPI Configuration:\n"); > + dev_info(&spi->dev, " Compression : %s\n", > + ax_local->capabilities & AX_CAP_COMP ? "ON" : "OFF"); > + dev_info(&spi->dev, " Power Saving Level: %d\n", > + ax_local->ps_level); > + } > + > + ndev->netdev_ops = &ax88796c_netdev_ops; > + ndev->ethtool_ops = &ax88796c_ethtool_ops; No spaces before '='. > + > + ax_local->ndev = ndev; Set all priv-storing-pointers in one place, so next to dev_set_drvdata() unless it is chosen by probe() flow on purpose. > + > + /* Initialize MII structure */ > + ax_local->mii.dev = ndev; > + ax_local->mii.mdio_read = ax88796c_mdio_read; > + ax_local->mii.mdio_write = ax88796c_mdio_write; > + ax_local->mii.phy_id_mask = 0x3f; > + ax_local->mii.reg_num_mask = 0x1f; > + ax_local->mii.phy_id = 0x10; > + > + /* ax88796c gpio reset */ > + ax88796c_hard_reset(ax_local); > + > + /* Reset AX88796C */ > + ret = ax88796c_soft_reset(ax_local); > + if (ret < 0) { > + return -ENODEV; > + } No need for {}. > + > + /* Check board revision */ > + temp = AX_READ(&ax_local->ax_spi, P2_CRIR); > + if ((temp & 0xF) != 0x0) { > + dev_err(&spi->dev, "spi read failed: %d\n", temp); > + return -ENODEV; > + } > + > + temp = AX_READ(&ax_local->ax_spi, P0_BOR); > + if (temp == 0x1234) { > + ax_local->plat_endian = PLAT_LITTLE_ENDIAN; > + } else { > + AX_WRITE(&ax_local->ax_spi, 0xFFFF, P0_BOR); > + ax_local->plat_endian = PLAT_BIG_ENDIAN; > + } > + > + if (netif_msg_hw(ax_local)) { > + dev_info(&spi->dev, > + "Dump all MAC registers before initialization:\n"); > + ax88796c_dump_regs(ax_local); > + ax88796c_dump_phy_regs(ax_local); > + } > + > + /*Reload EEPROM*/ > + ax88796c_reload_eeprom(ax_local); > + > + ax88796c_load_mac_addr(ndev); > + > + if (netif_msg_probe(ax_local)) > + dev_info(&spi->dev, > + "irq %d, MAC addr " > + "%02X:%02X:%02X:%02X:%02X:%02X\n", > + ndev->irq, > + ndev->dev_addr[0], ndev->dev_addr[1], > + ndev->dev_addr[2], ndev->dev_addr[3], > + ndev->dev_addr[4], ndev->dev_addr[5]); > + > + ax88796c_set_power_saving(ax_local, ax_local->ps_level); > + > + INIT_WORK(&ax_local->ax_work, ax88796c_work); > + > + ax_local->ax_work_queue = > + create_singlethread_workqueue("ax88796c_work"); > + > + sema_init(&ax_local->spi_lock, 1); > + > + skb_queue_head_init(&ax_local->tx_wait_q); > + > + ndev->features |= NETIF_F_HW_CSUM; > + ax_local->checksum = AX_RX_CHECKSUM | AX_TX_CHECKSUM; > + ndev->hard_header_len += (TX_OVERHEAD + 4); > + > + ret = register_netdev(ndev); > + if (!ret) { > + if (netif_msg_probe(ax_local)) > + netdev_info(ndev, "%s %s registered\n", > + dev_driver_string(&spi->dev), > + dev_name(&spi->dev)); > + return ret; > + } That's unusual flow - exit on success early. Follow the kernel pattern of "return 0" on success and jumps to common error handling like: ret = register_netdev(ndev) if (ret) // handle error: maybe dev_err and goto if (netif_msg_probe()) netdev_info(); return 0; > + > + dev_err(&spi->dev, "failed to register a network device\n"); > + destroy_workqueue(ax_local->ax_work_queue); > + > + return ret; > +} > + > +static int > +ax88796c_suspend(struct spi_device *spi, pm_message_t mesg) > +{ > + struct ax88796c_device *ax_local = dev_get_drvdata(&spi->dev); > + struct net_device *ndev = ax_local->ndev; > + u8 power; > + > + if (!ndev || !netif_running(ndev)) > + return 0; !ndev cannot happen (device should not be suspended before end of probe). If it can, there is a bug which you should not silently ignore. > + > + netif_device_detach(ndev); > + > + netif_stop_queue(ndev); > + > + down(&ax_local->spi_lock); > + > + power = ax88796c_check_power_and_wake(ax_local); > + > + AX_WRITE(&ax_local->ax_spi, IMR_MASKALL, P0_IMR); > + ax88796c_free_skb_queue(&ax_local->tx_wait_q); > + > + if (ax_local->wol) { > + > + AX_WRITE(&ax_local->ax_spi, 0, P5_WFTR); > + > + if (ax_local->wol & WFCR_LINKCH) { /* Link change */ > + > + /* Disable wol power saving in link change mode */ > + AX_WRITE(&ax_local->ax_spi, > + (AX_READ(&ax_local->ax_spi, P0_PSCR) > + & ~PSCR_WOLPS), P0_PSCR); > + > + if (netif_msg_wol(ax_local)) > + netdev_info(ndev, > + "Enable link change wakeup\n"); > + > + AX_WRITE(&ax_local->ax_spi, WFTR_8192MS, P5_WFTR); > + } > + if (ax_local->wol & WFCR_MAGICP) { /* Magic packet */ > + if (netif_msg_wol(ax_local)) > + netdev_info(ndev, > + "Enable magic packet wakeup\n"); > + } > + > + AX_WRITE(&ax_local->ax_spi, > + ax_local->wol | WFCR_WAKEUP | WFCR_PMEEN, P0_WFCR); > + } > + > + if (power) > + ax88796c_set_power_saving(ax_local, ax_local->ps_level); > + > + up(&ax_local->spi_lock); > + > + return 0; > +} > + > +static int > +ax88796c_resume(struct spi_device *spi) > +{ > + struct ax88796c_device *ax_local = dev_get_drvdata(&spi->dev); > + struct net_device *ndev = ax_local->ndev; > + u16 pme; > + > + down(&ax_local->spi_lock); > + > + /* Wakeup AX88796C first */ > + ax88796c_check_power_and_wake(ax_local); > + msleep(200); > + > + pme = AX_READ(&ax_local->ax_spi, P0_WFCR); > + if (ax_local->wol && ~(pme & WFCR_WAITEVENT)) { > + > + if (pme & WFCR_LINKCHS) { > + if (netif_msg_wol(ax_local)) > + netdev_info(ndev, > + "Wakeuped from link change.\n"); > + } else if (pme & WFCR_MAGICPS) { > + if (netif_msg_wol(ax_local)) > + netdev_info(ndev, > + "Wakeuped from magic packet.\n"); > + } > + > + AX_WRITE(&ax_local->ax_spi, WFCR_CLRWAKE, P0_WFCR); > + } > + > + netif_device_attach(ndev); > + > + /* Initialize all the local variables*/ > + ax88796c_soft_reset(ax_local); > + > + ax_local->seq_num = 0x1f; > + > + ax88796c_set_mac_addr(ndev); > + ax88796c_set_csums(ax_local); > + > + /* Disable stuffing packet */ > + AX_WRITE(&ax_local->ax_spi, > + AX_READ(&ax_local->ax_spi, P1_RXBSPCR) > + & ~RXBSPCR_STUF_ENABLE, P1_RXBSPCR); > + > + /* Enable RX packet process */ > + AX_WRITE(&ax_local->ax_spi, RPPER_RXEN, P1_RPPER); > + > + AX_WRITE(&ax_local->ax_spi, > + AX_READ(&ax_local->ax_spi, P0_FER) > + | FER_RXEN | FER_TXEN | FER_BSWAP, P0_FER); > + > + ax88796c_phy_init(ax_local); > + > + AX_WRITE(&ax_local->ax_spi, IMR_DEFAULT, P0_IMR); > + > + if (netif_msg_hw(ax_local)) { > + netdev_info(ndev, > + "Dump all MAC registers after initialization:\n"); > + ax88796c_dump_regs(ax_local); > + ax88796c_dump_phy_regs(ax_local); > + } > + > + ax88796c_set_power_saving(ax_local, ax_local->ps_level); > + > + netif_start_queue(ndev); > + > + up(&ax_local->spi_lock); > + > + return 0; > +} > + > +static int ax88796c_remove(struct spi_device *spi) > +{ > + struct ax88796c_device *ax_local = dev_get_drvdata(&spi->dev); > + struct net_device *ndev = ax_local->ndev; > + > + if (netif_msg_probe(ax_local)) > + netdev_info(ndev, "removing network device %s %s\n", > + dev_driver_string(&spi->dev), > + dev_name(&spi->dev)); > + > + destroy_workqueue(ax_local->ax_work_queue); > + > + unregister_netdev(ndev); > + > + if (netif_msg_probe(ax_local)) > + dev_info(&spi->dev, "device removed\n"); > + > + return 0; > +} > + > +#ifdef CONFIG_USE_OF #ifdef should not be needed. > +static const struct of_device_id ax88796c_dt_ids[] = { > + { .compatible = "asix,ax88796c" }, > + {}, > +}; > +MODULE_DEVICE_TABLE(of, ax88796c_dt_ids); > +#endif > + > +static const struct spi_device_id asix_id[] = { > + { "ax88796c", 0 }, > + { } > +}; > +MODULE_DEVICE_TABLE(spi, asix_id); > + > +static struct spi_driver ax88796c_spi_driver = { > + .driver = { > + .name = DRV_NAME, > + .owner = THIS_MODULE, No need for owner. > +#ifdef CONFIG_USE_OF > + .of_match_table = of_match_ptr(ax88796c_dt_ids), > +#endif No need for ifdef. > + }, > + .probe = ax88796c_probe, > + .remove = ax88796c_remove, > +// .suspend = ax88796c_suspend, > +// .resume = ax88796c_resume, ? > + .id_table = asix_id, > +}; > + > +static __init int ax88796c_spi_init(void) > +{ > + pr_info("Register AX88796C SPI Ethernet Driver.\n"); No, no printing of driver inits. It will bother everyone in the world. This all should be just module driver, no init/exit. > + return spi_register_driver(&ax88796c_spi_driver); > +} > + > +static __exit void ax88796c_spi_exit(void) > +{ > + spi_unregister_driver(&ax88796c_spi_driver); > +} > + > +module_init(ax88796c_spi_init); > +module_exit(ax88796c_spi_exit); > diff --git a/drivers/net/ethernet/asix/ax88796c_main.h b/drivers/net/ethernet/asix/ax88796c_main.h > new file mode 100644 > index 000000000000..6c61766b1788 > --- /dev/null > +++ b/drivers/net/ethernet/asix/ax88796c_main.h > @@ -0,0 +1,596 @@ > +// SPDX-License-Identifier: GPL-2.0-only > +/* > + * Copyright (c) 2010 ASIX Electronics Corporation > + * Copyright (c) 2020 Samsung Electronics > + * > + * ASIX AX88796C SPI Fast Ethernet Linux driver > + */ > + > +#ifndef _AX88796C_MAIN_H > +#define _AX88796C_MAIN_H > + > +#define pr_fmt(fmt) "ax88796c: " fmt > + > +/* INCLUDE FILE DECLARATIONS */ > +#ifdef CONFIG_USE_OF No ifdef. > +#include > +#endif > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include All of these should be removed except the headers used directly in this header. > + > +#include > + > +#include "ax88796c_spi.h" > + > +/* NAMING CONSTANT AND TYPE DECLARATIONS */ > +/* These identify the driver base version and may not be removed. */ > +#define DRV_NAME "ax88796c" > +#define ADP_NAME "ASIX AX88796C SPI Ethernet Adapter" > +#define DRV_VERSION "1.2.0" > + > +#define TX_QUEUE_HIGH_WATER 45 /* Tx queue high water mark */ > +#define TX_QUEUE_LOW_WATER 20 /* Tx queue low water mark */ > + > +#define AX88796C_WATCHDOG_PERIOD (1 * HZ) > +#define AX88796C_WATCHDOG_RESTART 7 > + > +#define TX_OVERHEAD 8 > +#define TX_EOP_SIZE 4 > + > +#define AX_MCAST_FILTER_SIZE 8 > +#define AX_MAX_MCAST 64 > +#define AX_MAX_CLK 80000000 > +#define TX_HDR_SOP_DICF 0x8000 > +#define TX_HDR_SOP_CPHI 0x4000 > +#define TX_HDR_SOP_INT 0x2000 > +#define TX_HDR_SOP_MDEQ 0x1000 > +#define TX_HDR_SOP_PKTLEN 0x07FF > +#define TX_HDR_SOP_SEQNUM 0xF800 > +#define TX_HDR_SOP_PKTLENBAR 0x07FF > + > +#define TX_HDR_SEG_FS 0x8000 > +#define TX_HDR_SEG_LS 0x4000 > +#define TX_HDR_SEG_SEGNUM 0x3800 > +#define TX_HDR_SEG_SEGLEN 0x0700 > +#define TX_HDR_SEG_EOFST 0xC000 > +#define TX_HDR_SEG_SOFST 0x3800 > +#define TX_HDR_SEG_SEGLENBAR 0x07FF > + > +#define TX_HDR_EOP_SEQNUM 0xF800 > +#define TX_HDR_EOP_PKTLEN 0x07FF > +#define TX_HDR_EOP_SEQNUMBAR 0xF800 > +#define TX_HDR_EOP_PKTLENBAR 0x07FF > + > +/* Rx header fields mask */ > +#define RX_HDR1_MCBC 0x8000 > +#define RX_HDR1_STUFF_PKT 0x4000 > +#define RX_HDR1_MII_ERR 0x2000 > +#define RX_HDR1_CRC_ERR 0x1000 > +#define RX_HDR1_PKT_LEN 0x07FF > + > +#define RX_HDR2_SEQ_NUM 0xF800 > +#define RX_HDR2_PKT_LEN_BAR 0x7FFF > + > +#define RX_HDR3_PE 0x8000 > +#define RX_HDR3_L4_TYPE_TCP 0x1000 > +#define RX_HDR3_L4_TYPE_UDP 0x0400 > +#define RX_HDR3_L3_ERR 0x0200 > +#define RX_HDR3_L4_ERR 0x0100 > +#define RX_HDR3_PRIORITY(x) ((x) << 4) > +#define RX_HDR3_STRIP 0x0008 > +#define RX_HDR3_VLAN_ID 0x0007 > + > +#define AX_RX_CHECKSUM 1 > +#define AX_TX_CHECKSUM 2 > + > +enum watchdog_state { > + chk_link = 0, > + chk_cable, > + ax_nop, > +}; > + > +struct ax88796c_device { > + > + struct resource *addr_res; /* resources found */ > + struct resource *addr_req; /* resources requested */ > + struct resource *irq_res; > + > + struct spi_device *spi; > + struct net_device *ndev; > + struct mii_if_info mii; > + struct net_device_stats stats; > + > + struct timer_list watchdog; > + enum watchdog_state w_state; > + size_t w_ticks; > + > + struct work_struct ax_work; > + struct workqueue_struct *ax_work_queue; > + struct tasklet_struct bh; > + > + struct semaphore spi_lock; > + > + struct sk_buff_head tx_wait_q; > + > + struct axspi_data ax_spi; > + > + int msg_enable; > + > + u16 seq_num; > + > + u16 wol; > + > + u8 checksum; > + > + u8 multi_filter[AX_MCAST_FILTER_SIZE]; > + > + unsigned long capabilities; > + #define AX_CAP_DMA 1 > + #define AX_CAP_COMP 2 > + #define AX_CAP_BIDIR 4 > + > + u8 plat_endian; > + #define PLAT_LITTLE_ENDIAN 0 > + #define PLAT_BIG_ENDIAN 1 > + > + unsigned long flags; > + #define EVENT_INTR 1 > + #define EVENT_TX 2 > + #define EVENT_SET_MULTI 4 > + #define EVENT_WATCHDOG 8 > + > + u8 ps_level; > + #define AX_PS_D0 0 > + #define AX_PS_D1 1 > + #define AX_PS_D2 2 > + > + > +}; > + > +#define to_ax88796c_device(ndev) ((struct ax88796c_device *)netdev_priv(ndev)) > + > +enum skb_state { > + illegal = 0, > + tx_done, > + rx_done, > + rx_err, > +}; > + > +struct skb_data; > + > +struct skb_data { > + enum skb_state state; > + struct net_device *ndev; > + struct sk_buff *skb; > + size_t len; > + dma_addr_t phy_addr; > +}; > + > +/* A88796C register definition */ > + /* Definition of PAGE0 */ > +#define P0_PSR (0x00) > + #define PSR_DEV_READY (1 << 7) > + #define PSR_RESET (0 << 15) > + #define PSR_RESET_CLR (1 << 15) > +#define P0_BOR (0x02) > +#define P0_FER (0x04) > + #define FER_IPALM (1 << 0) > + #define FER_DCRC (1 << 1) > + #define FER_RH3M (1 << 2) > + #define FER_HEADERSWAP (1 << 7) > + #define FER_WSWAP (1 << 8) > + #define FER_BSWAP (1 << 9) > + #define FER_INTHI (1 << 10) > + #define FER_INTLO (0 << 10) > + #define FER_IRQ_PULL (1 << 11) > + #define FER_RXEN (1 << 14) > + #define FER_TXEN (1 << 15) > +#define P0_ISR (0x06) > + #define ISR_RXPKT (1 << 0) > + #define ISR_MDQ (1 << 4) > + #define ISR_TXT (1 << 5) > + #define ISR_TXPAGES (1 << 6) > + #define ISR_TXERR (1 << 8) > + #define ISR_LINK (1 << 9) > +#define P0_IMR (0x08) > + #define IMR_RXPKT (1 << 0) > + #define IMR_MDQ (1 << 4) > + #define IMR_TXT (1 << 5) > + #define IMR_TXPAGES (1 << 6) > + #define IMR_TXERR (1 << 8) > + #define IMR_LINK (1 << 9) > + #define IMR_MASKALL (0xFFFF) > + #define IMR_DEFAULT (IMR_TXERR) > +#define P0_WFCR (0x0A) > + #define WFCR_PMEIND (1 << 0) /* PME indication */ > + #define WFCR_PMETYPE (1 << 1) /* PME I/O type */ > + #define WFCR_PMEPOL (1 << 2) /* PME polarity */ > + #define WFCR_PMERST (1 << 3) /* Reset PME */ > + #define WFCR_SLEEP (1 << 4) /* Enable sleep mode */ > + #define WFCR_WAKEUP (1 << 5) /* Enable wakeup mode */ > + #define WFCR_WAITEVENT (1 << 6) /* Reserved */ > + #define WFCR_CLRWAKE (1 << 7) /* Clear wakeup */ > + #define WFCR_LINKCH (1 << 8) /* Enable link change */ > + #define WFCR_MAGICP (1 << 9) /* Enable magic packet */ > + #define WFCR_WAKEF (1 << 10) /* Enable wakeup frame */ > + #define WFCR_PMEEN (1 << 11) /* Enable PME pin */ > + #define WFCR_LINKCHS (1 << 12) /* Link change status */ > + #define WFCR_MAGICPS (1 << 13) /* Magic packet status */ > + #define WFCR_WAKEFS (1 << 14) /* Wakeup frame status */ > + #define WFCR_PMES (1 << 15) /* PME pin status */ > +#define P0_PSCR (0x0C) > + #define PSCR_PS_MASK (0xFFF0) > + #define PSCR_PS_D0 (0) > + #define PSCR_PS_D1 (1 << 0) > + #define PSCR_PS_D2 (1 << 1) > + #define PSCR_FPS (1 << 3) /* Enable fiber mode PS */ > + #define PSCR_SWPS (1 << 4) /* Enable software */ > + /* PS control */ > + #define PSCR_WOLPS (1 << 5) /* Enable WOL PS */ > + #define PSCR_SWWOL (1 << 6) /* Enable software select */ > + /* WOL PS */ > + #define PSCR_PHYOSC (1 << 7) /* Internal PHY OSC control */ > + #define PSCR_FOFEF (1 << 8) /* Force PHY generate FEF */ > + #define PSCR_FOF (1 << 9) /* Force PHY in fiber mode */ > + #define PSCR_PHYPD (1 << 10) /* PHY power down. */ > + /* Active high */ > + #define PSCR_PHYRST (1 << 11) /* PHY reset signal. */ > + /* Active low */ > + #define PSCR_PHYCSIL (1 << 12) /* PHY cable energy detect */ > + #define PSCR_PHYCOFF (1 << 13) /* PHY cable off */ > + #define PSCR_PHYLINK (1 << 14) /* PHY link status */ > + #define PSCR_EEPOK (1 << 15) /* EEPROM load complete */ > +#define P0_MACCR (0x0E) > + #define MACCR_RXFC_ENABLE (1 << 3) > + #define MACCR_RXFC_MASK 0xFFF7 > + #define MACCR_TXFC_ENABLE (1 << 4) > + #define MACCR_TXFC_MASK 0xFFEF > + #define MACCR_PF (1 << 7) > + #define MACCR_PMM_BITS 8 > + #define MACCR_PMM_MASK (0x1F00) > + #define MACCR_PMM_RESET (1 << 8) > + #define MACCR_PMM_WAIT (2 << 8) > + #define MACCR_PMM_READY (3 << 8) > + #define MACCR_PMM_D1 (4 << 8) > + #define MACCR_PMM_D2 (5 << 8) > + #define MACCR_PMM_WAKE (7 << 8) > + #define MACCR_PMM_D1_WAKE (8 << 8) > + #define MACCR_PMM_D2_WAKE (9 << 8) > + #define MACCR_PMM_SLEEP (10 << 8) > + #define MACCR_PMM_PHY_RESET (11 << 8) > + #define MACCR_PMM_SOFT_D1 (16 << 8) > + #define MACCR_PMM_SOFT_D2 (17 << 8) > +#define P0_TFBFCR (0x10) > + #define TFBFCR_SCHE_FREE_PAGE 0xE07F > + #define TFBFCR_FREE_PAGE_BITS 0x07 > + #define TFBFCR_FREE_PAGE_LATCH (1 << 6) > + #define TFBFCR_SET_FREE_PAGE(x) ((x & 0x3F) << TFBFCR_FREE_PAGE_BITS) > + #define TFBFCR_TX_PAGE_SET (1 << 13) > + #define TFBFCR_MANU_ENTX (1 << 15) > + #define TX_FREEBUF_MASK 0x003F > + #define TX_DPTSTART 0x4000 > + > +#define P0_TSNR (0x12) > + #define TXNR_TXB_ERR (1 << 5) > + #define TXNR_TXB_IDLE (1 << 6) > + #define TSNR_PKT_CNT(x) (((x) & 0x3F) << 8) > + #define TXNR_TXB_REINIT (1 << 14) > + #define TSNR_TXB_START (1 << 15) > +#define P0_RTDPR (0x14) > +#define P0_RXBCR1 (0x16) > + #define RXBCR1_RXB_DISCARD (1 << 14) > + #define RXBCR1_RXB_START (1 << 15) > +#define P0_RXBCR2 (0x18) > + #define RXBCR2_PKT_MASK (0xFF) > + #define RXBCR2_RXPC_MASK (0x7F) > + #define RXBCR2_RXB_READY (1 << 13) > + #define RXBCR2_RXB_IDLE (1 << 14) > + #define RXBCR2_RXB_REINIT (1 << 15) > +#define P0_RTWCR (0x1A) > + #define RTWCR_RXWC_MASK (0x3FFF) > + #define RTWCR_RX_LATCH (1 << 15) > +#define P0_RCPHR (0x1C) > + > + /* Definition of PAGE1 */ > +#define P1_RPPER (0x22) > + #define RPPER_RXEN (1 << 0) > +#define P1_MRCR (0x28) > +#define P1_MDR (0x2A) > +#define P1_RMPR (0x2C) > +#define P1_TMPR (0x2E) > +#define P1_RXBSPCR (0x30) > + #define RXBSPCR_STUF_WORD_CNT(x) (((x) & 0x7000) >> 12) > + #define RXBSPCR_STUF_ENABLE (1 << 15) > +#define P1_MCR (0x32) > + #define MCR_SBP (1 << 8) > + #define MCR_SM (1 << 9) > + #define MCR_CRCENLAN (1 << 11) > + #define MCR_STP (1 << 12) > + /* Definition of PAGE2 */ > +#define P2_CIR (0x42) > +#define P2_POOLCR (0x44) > + #define POOLCR_POLL_EN (1 << 0) > + #define POOLCR_POLL_FLOWCTRL (1 << 1) > + #define POOLCR_POLL_BMCR (1 << 2) > + #define POOLCR_PHYID(x) ((x) << 8) > +#define P2_PHYSR (0x46) > +#define P2_MDIODR (0x48) > +#define P2_MDIOCR (0x4A) > + #define MDIOCR_RADDR(x) ((x) & 0x1F) > + #define MDIOCR_FADDR(x) (((x) & 0x1F) << 8) > + #define MDIOCR_VALID (1 << 13) > + #define MDIOCR_READ (1 << 14) > + #define MDIOCR_WRITE (1 << 15) > +#define P2_LCR0 (0x4C) > + #define LCR_LED0_EN (1 << 0) > + #define LCR_LED0_100MODE (1 << 1) > + #define LCR_LED0_DUPLEX (1 << 2) > + #define LCR_LED0_LINK (1 << 3) > + #define LCR_LED0_ACT (1 << 4) > + #define LCR_LED0_COL (1 << 5) > + #define LCR_LED0_10MODE (1 << 6) > + #define LCR_LED0_DUPCOL (1 << 7) > + #define LCR_LED1_EN (1 << 8) > + #define LCR_LED1_100MODE (1 << 9) > + #define LCR_LED1_DUPLEX (1 << 10) > + #define LCR_LED1_LINK (1 << 11) > + #define LCR_LED1_ACT (1 << 12) > + #define LCR_LED1_COL (1 << 13) > + #define LCR_LED1_10MODE (1 << 14) > + #define LCR_LED1_DUPCOL (1 << 15) > +#define P2_LCR1 (0x4E) > + #define LCR_LED2_MASK (0xFF00) > + #define LCR_LED2_EN (1 << 0) > + #define LCR_LED2_100MODE (1 << 1) > + #define LCR_LED2_DUPLEX (1 << 2) > + #define LCR_LED2_LINK (1 << 3) > + #define LCR_LED2_ACT (1 << 4) > + #define LCR_LED2_COL (1 << 5) > + #define LCR_LED2_10MODE (1 << 6) > + #define LCR_LED2_DUPCOL (1 << 7) > +#define P2_IPGCR (0x50) > +#define P2_CRIR (0x52) > +#define P2_FLHWCR (0x54) > +#define P2_RXCR (0x56) > + #define RXCR_PRO (1 << 0) > + #define RXCR_AMALL (1 << 1) > + #define RXCR_SEP (1 << 2) > + #define RXCR_AB (1 << 3) > + #define RXCR_AM (1 << 4) > + #define RXCR_AP (1 << 5) > + #define RXCR_ARP (1 << 6) > +#define P2_JLCR (0x58) > +#define P2_MPLR (0x5C) > + > + /* Definition of PAGE3 */ > +#define P3_MACASR0 (0x62) > + #define P3_MACASR(x) (P3_MACASR0 + 2*x) > + #define MACASR_LOWBYTE_MASK 0x00FF > + #define MACASR_HIGH_BITS 0x08 > +#define P3_MACASR1 (0x64) > +#define P3_MACASR2 (0x66) > +#define P3_MFAR01 (0x68) > +#define P3_MFAR_BASE (0x68) > + #define P3_MFAR(x) (P3_MFAR_BASE + 2*x) > + > +#define P3_MFAR23 (0x6A) > +#define P3_MFAR45 (0x6C) > +#define P3_MFAR67 (0x6E) > +#define P3_VID0FR (0x70) > +#define P3_VID1FR (0x72) > +#define P3_EECSR (0x74) > +#define P3_EEDR (0x76) > +#define P3_EECR (0x78) > + #define EECR_ADDR_MASK (0x00FF) > + #define EECR_READ_ACT (1 << 8) > + #define EECR_WRITE_ACT (1 << 9) > + #define EECR_WRITE_DISABLE (1 << 10) > + #define EECR_WRITE_ENABLE (1 << 11) > + #define EECR_EE_READY (1 << 13) > + #define EECR_RELOAD (1 << 14) > + #define EECR_RESET (1 << 15) > +#define P3_TPCR (0x7A) > + #define TPCR_PATT_MASK (0xFF) > + #define TPCR_RAND_PKT_EN (1 << 14) > + #define TPCR_FIXED_PKT_EN (1 << 15) > +#define P3_TPLR (0x7C) > + /* Definition of PAGE4 */ > +#define P4_SPICR (0x8A) > + #define SPICR_RCEN (1 << 0) > + #define SPICR_QCEN (1 << 1) > + #define SPICR_RBRE (1 << 3) > + #define SPICR_PMM (1 << 4) > + #define SPICR_LOOPBACK (1 << 8) > + #define SPICR_CORE_RES_CLR (1 << 10) > + #define SPICR_SPI_RES_CLR (1 << 11) > +#define P4_SPIISMR (0x8C) > + > +#define P4_COERCR0 (0x92) > + #define COERCR0_RXIPCE (1 << 0) > + #define COERCR0_RXIPVE (1 << 1) > + #define COERCR0_RXV6PE (1 << 2) > + #define COERCR0_RXTCPE (1 << 3) > + #define COERCR0_RXUDPE (1 << 4) > + #define COERCR0_RXICMP (1 << 5) > + #define COERCR0_RXIGMP (1 << 6) > + #define COERCR0_RXICV6 (1 << 7) > + > + #define COERCR0_RXTCPV6 (1 << 8) > + #define COERCR0_RXUDPV6 (1 << 9) > + #define COERCR0_RXICMV6 (1 << 10) > + #define COERCR0_RXIGMV6 (1 << 11) > + #define COERCR0_RXICV6V6 (1 << 12) > + > + #define COERCR0_DEFAULT (COERCR0_RXIPCE | COERCR0_RXV6PE | \ > + COERCR0_RXTCPE | COERCR0_RXUDPE | \ > + COERCR0_RXTCPV6 | COERCR0_RXUDPV6) > +#define P4_COERCR1 (0x94) > + #define COERCR1_IPCEDP (1 << 0) > + #define COERCR1_IPVEDP (1 << 1) > + #define COERCR1_V6VEDP (1 << 2) > + #define COERCR1_TCPEDP (1 << 3) > + #define COERCR1_UDPEDP (1 << 4) > + #define COERCR1_ICMPDP (1 << 5) > + #define COERCR1_IGMPDP (1 << 6) > + #define COERCR1_ICV6DP (1 << 7) > + #define COERCR1_RX64TE (1 << 8) > + #define COERCR1_RXPPPE (1 << 9) > + #define COERCR1_TCP6DP (1 << 10) > + #define COERCR1_UDP6DP (1 << 11) > + #define COERCR1_IC6DP (1 << 12) > + #define COERCR1_IG6DP (1 << 13) > + #define COERCR1_ICV66DP (1 << 14) > + #define COERCR1_RPCE (1 << 15) > + > + #define COERCR1_DEFAULT (COERCR1_RXPPPE) > +#define P4_COETCR0 (0x96) > + #define COETCR0_TXIP (1 << 0) > + #define COETCR0_TXTCP (1 << 1) > + #define COETCR0_TXUDP (1 << 2) > + #define COETCR0_TXICMP (1 << 3) > + #define COETCR0_TXIGMP (1 << 4) > + #define COETCR0_TXICV6 (1 << 5) > + #define COETCR0_TXTCPV6 (1 << 8) > + #define COETCR0_TXUDPV6 (1 << 9) > + #define COETCR0_TXICMV6 (1 << 10) > + #define COETCR0_TXIGMV6 (1 << 11) > + #define COETCR0_TXICV6V6 (1 << 12) > + > + #define COETCR0_DEFAULT (COETCR0_TXIP | COETCR0_TXTCP | \ > + COETCR0_TXUDP | COETCR0_TXTCPV6 | \ > + COETCR0_TXUDPV6) > +#define P4_COETCR1 (0x98) > + #define COETCR1_TX64TE (1 << 0) > + #define COETCR1_TXPPPE (1 << 1) > + > +#define P4_COECEDR (0x9A) > +#define P4_L2CECR (0x9C) > + > + /* Definition of PAGE5 */ > +#define P5_WFTR (0xA2) > + #define WFTR_2MS (0x01) > + #define WFTR_4MS (0x02) > + #define WFTR_8MS (0x03) > + #define WFTR_16MS (0x04) > + #define WFTR_32MS (0x05) > + #define WFTR_64MS (0x06) > + #define WFTR_128MS (0x07) > + #define WFTR_256MS (0x08) > + #define WFTR_512MS (0x09) > + #define WFTR_1024MS (0x0A) > + #define WFTR_2048MS (0x0B) > + #define WFTR_4096MS (0x0C) > + #define WFTR_8192MS (0x0D) > + #define WFTR_16384MS (0x0E) > + #define WFTR_32768MS (0x0F) > +#define P5_WFCCR (0xA4) > +#define P5_WFCR03 (0xA6) > + #define WFCR03_F0_EN (1 << 0) > + #define WFCR03_F1_EN (1 << 4) > + #define WFCR03_F2_EN (1 << 8) > + #define WFCR03_F3_EN (1 << 12) > +#define P5_WFCR47 (0xA8) > + #define WFCR47_F4_EN (1 << 0) > + #define WFCR47_F5_EN (1 << 4) > + #define WFCR47_F6_EN (1 << 8) > + #define WFCR47_F7_EN (1 << 12) > +#define P5_WF0BMR0 (0xAA) > +#define P5_WF0BMR1 (0xAC) > +#define P5_WF0CR (0xAE) > +#define P5_WF0OBR (0xB0) > +#define P5_WF1BMR0 (0xB2) > +#define P5_WF1BMR1 (0xB4) > +#define P5_WF1CR (0xB6) > +#define P5_WF1OBR (0xB8) > +#define P5_WF2BMR0 (0xBA) > +#define P5_WF2BMR1 (0xBC) > + > + /* Definition of PAGE6 */ > +#define P6_WF2CR (0xC2) > +#define P6_WF2OBR (0xC4) > +#define P6_WF3BMR0 (0xC6) > +#define P6_WF3BMR1 (0xC8) > +#define P6_WF3CR (0xCA) > +#define P6_WF3OBR (0xCC) > +#define P6_WF4BMR0 (0xCE) > +#define P6_WF4BMR1 (0xD0) > +#define P6_WF4CR (0xD2) > +#define P6_WF4OBR (0xD4) > +#define P6_WF5BMR0 (0xD6) > +#define P6_WF5BMR1 (0xD8) > +#define P6_WF5CR (0xDA) > +#define P6_WF5OBR (0xDC) > + > +/* Definition of PAGE7 */ > +#define P7_WF6BMR0 (0xE2) > +#define P7_WF6BMR1 (0xE4) > +#define P7_WF6CR (0xE6) > +#define P7_WF6OBR (0xE8) > +#define P7_WF7BMR0 (0xEA) > +#define P7_WF7BMR1 (0xEC) > +#define P7_WF7CR (0xEE) > +#define P7_WF7OBR (0xF0) > +#define P7_WFR01 (0xF2) > +#define P7_WFR23 (0xF4) > +#define P7_WFR45 (0xF6) > +#define P7_WFR67 (0xF8) > +#define P7_WFPC0 (0xFA) > +#define P7_WFPC1 (0xFC) > + > + > +/* Tx headers structure */ > +struct tx_sop_header { > + /* bit 15-11: flags, bit 10-0: packet length */ > + u16 flags_len; > + /* bit 15-11: sequence number, bit 11-0: packet length bar */ > + u16 seq_lenbar; > +} __packed; > + > +struct tx_segment_header { > + /* bit 15-14: flags, bit 13-11: segment number */ > + /* bit 10-0: segment length */ > + u16 flags_seqnum_seglen; > + /* bit 15-14: end offset, bit 13-11: start offset */ > + /* bit 10-0: segment length bar */ > + u16 eo_so_seglenbar; > +} __packed; > + > +struct tx_eop_header { > + /* bit 15-11: sequence number, bit 10-0: packet length */ > + u16 seq_len; > + /* bit 15-11: sequence number bar, bit 10-0: packet length bar */ > + u16 seqbar_lenbar; > +} __packed; > + > +struct tx_pkt_info { > + struct tx_sop_header sop; > + struct tx_segment_header seg; > + struct tx_eop_header eop; > + u16 pkt_len; > + u16 seq_num; > +} __packed; > + > +/* Rx headers structure */ > +struct rx_header { > + u16 flags_len; > + u16 seq_lenbar; > + u16 flags; > +} __packed; > + > +#endif /* #ifndef _AX88796C_MAIN_H */ > diff --git a/drivers/net/ethernet/asix/ax88796c_spi.c b/drivers/net/ethernet/asix/ax88796c_spi.c > new file mode 100644 > index 000000000000..5304eb33aad2 > --- /dev/null > +++ b/drivers/net/ethernet/asix/ax88796c_spi.c > @@ -0,0 +1,103 @@ > +// SPDX-License-Identifier: GPL-2.0-only > +/* > + * Copyright (c) 2010 ASIX Electronics Corporation > + * > + * ASIX AX88796C SPI Fast Ethernet Linux driver > + */ > + > +#include "ax88796c_main.h" > +#include "ax88796c_spi.h" > + > +/* driver bus management functions */ > +void axspi_wakeup(struct axspi_data *ax_spi) > +{ > + u8 tx_buf; > + int ret; > + > + tx_buf = AX_SPICMD_EXIT_PWD; /* OP */ > + ret = spi_write(ax_spi->spi, &tx_buf, 1); > + if (ret) > + dev_err(&ax_spi->spi->dev, "%s() failed: ret = %d\n", __func__, ret); > +} > + > +void axspi_read_status(struct axspi_data *ax_spi, struct spi_status *status) > +{ > + u8 tx_buf; > + int ret; > + > + /* OP */ > + tx_buf = AX_SPICMD_READ_STATUS; > + ret = spi_write_then_read(ax_spi->spi, &tx_buf, 1, (u8 *)&status, 3); > + if (ret) > + dev_err(&ax_spi->spi->dev, "%s() failed: ret = %d\n", __func__, ret); > + else > + le16_to_cpus(&status->isr); > +} > + > +int axspi_read_rxq(struct axspi_data *ax_spi, void *data, int len) > +{ > + struct spi_transfer *xfer = ax_spi->spi_rx_xfer; > + int ret; > + > + memcpy(ax_spi->cmd_buf, rx_cmd_buf, 5); > + > + xfer->tx_buf = ax_spi->cmd_buf; > + xfer->rx_buf = NULL; > + xfer->len = ax_spi->comp ? 2 : 5; > + xfer->bits_per_word = 8; > + spi_message_add_tail(xfer, &ax_spi->rx_msg); > + > + xfer++; > + xfer->rx_buf = data; > + xfer->tx_buf = NULL; > + xfer->len = len; > + xfer->bits_per_word = 8; > + spi_message_add_tail(xfer, &ax_spi->rx_msg); > + ret = spi_sync(ax_spi->spi, &ax_spi->rx_msg); > + if (ret) > + dev_err(&ax_spi->spi->dev, "%s() failed: ret = %d\n", __func__, ret); > + > + return ret; > +} > + > +int axspi_write_txq(struct axspi_data *ax_spi, void *data, int len) > +{ > + return spi_write(ax_spi->spi, data, len); > +} > + > +u16 axspi_read_reg(struct axspi_data *ax_spi, u8 reg) > +{ > + u8 tx_buf[4]; > + u16 rx_buf = 0; > + int ret; > + int len = ax_spi->comp ? 3 : 4; > + > + tx_buf[0] = 0x03; /* OP code read register */ > + tx_buf[1] = reg; /* register address */ > + tx_buf[2] = 0xFF; /* dumy cycle */ > + tx_buf[3] = 0xFF; /* dumy cycle */ > + ret = spi_write_then_read(ax_spi->spi, tx_buf, len, (u8 *)&rx_buf, 2); > + if (ret) > + dev_err(&ax_spi->spi->dev, "%s() failed: ret = %d\n", __func__, ret); > + else > + le16_to_cpus(&rx_buf); > + > + return rx_buf; > +} > + > +void axspi_write_reg(struct axspi_data *ax_spi, u8 reg, u16 value) > +{ > + u8 tx_buf[4]; > + int ret; > + > + tx_buf[0] = AX_SPICMD_WRITE_REG; /* OP code read register */ > + tx_buf[1] = reg; /* register address */ > + tx_buf[2] = value; > + tx_buf[3] = value >> 8; > + > + ret = spi_write(ax_spi->spi, tx_buf, 4); > + if (ret) > + dev_err(&ax_spi->spi->dev, "%s() failed: ret = %d\n", __func__, ret); > + Run the checkpatch string and fix almost all issues (except ones you disagree). Best regards, Krzysztof 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,INCLUDES_PATCH,MAILING_LIST_MULTI,MENTIONS_GIT_HOSTING, SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS,USER_AGENT_SANE_1 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 46715C433E1 for ; Tue, 25 Aug 2020 18:46:58 +0000 (UTC) Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) (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 ED27820738 for ; Tue, 25 Aug 2020 18:46:57 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="LaAfuNaq" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org ED27820738 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=kernel.org 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=merlin.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:Cc:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:In-Reply-To:MIME-Version:References:Message-ID: Subject:To:From:Date:Reply-To:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=TF6B28L06j7+wIrZY2kUXjAPEwPUbgqZEbrqc2G9BMg=; b=LaAfuNaq+Gp/4Sbzzk4ppxGVv +pwEKRdp+gmd/WjKEn0OdlXMiGHSJXIFpH0lrPbww7wPUa7gmA6q2rvRN1Q3omlpd1sKgSlKLZy0V 59NRNwkUsVLE2ynoy66SS2k5D7xwLyGsXfFVljFjz78pRg6NyvkoVb+AgR6hk/A+Md7YsA6TJiZTw GQSTlWVd6JA6wV+GVHW//Jnpg432T2WYzoyDSgsSleUE74VvBqzvt/8YZ64KBi0Zop2wZtunh2t/c MhvRdydqXnST4F0pOgmwkafVAs8nvCQa0QCVUwTEjzq7q/WweRD3fkcDJ1gwi0r8gnhwEuDcnQBYq Y31Nql13A==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1kAdw3-0000hN-VO; Tue, 25 Aug 2020 18:44:44 +0000 Received: from mail-wm1-f65.google.com ([209.85.128.65]) by merlin.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1kAdvz-0000gx-FK for linux-arm-kernel@lists.infradead.org; Tue, 25 Aug 2020 18:44:41 +0000 Received: by mail-wm1-f65.google.com with SMTP id 83so3617457wme.4 for ; Tue, 25 Aug 2020 11:44:38 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:content-transfer-encoding :in-reply-to:user-agent; bh=mSp8WG6g493mnX01NbbuUvBAyLbfT8UOuMbBofm+Th0=; b=KksBtV/nSRluSzggVZt3CSlYACq58p1SKyDlHlNwgs95G3P+nvUs7MZcjwUcwhWtaN 4fEeIm6Xq+b7jbxv6E2k7L6kIZDuswPza5SZWAwMbtzzipgMUq1K3UVr1Fb9F4LsR2gJ pIiqJVyrmbHzKQfS/tI5XC2qg2dqZQTSXD07Hz9O5/9m9dmQWHafX/XrTzL8/2WNvs7E 1mVu3xQec24fm/7Y6e9CNqvfso7GBkx+TvqJPeoeqm3zOZIMknkrunx0102r/gsPLMiq LQ6nyRvumMDKfXxU9aQPX7Ixmj0lTnNOrmD2FJBWgs9mc9zNxrC1R3fKaYEZREozoADJ rXrg== X-Gm-Message-State: AOAM530L3t0xBaqqUsUsNJWnhxpmsVvWAdIENhsd7ZNeNkqHCAOazb17 9ebWJBl44mbstLo8m4BylP0= X-Google-Smtp-Source: ABdhPJwStbL/Lo/OYVnKHTd2LixTswrYvYE+JRazM8Heamf9vj9ksOWQV4BET/1qTzwNkU0FM2m0+g== X-Received: by 2002:a7b:cb4d:: with SMTP id v13mr3490276wmj.56.1598381076439; Tue, 25 Aug 2020 11:44:36 -0700 (PDT) Received: from kozik-lap ([194.230.155.216]) by smtp.googlemail.com with ESMTPSA id p14sm36211224wrg.96.2020.08.25.11.44.21 (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Tue, 25 Aug 2020 11:44:35 -0700 (PDT) Date: Tue, 25 Aug 2020 20:44:13 +0200 From: Krzysztof Kozlowski To: =?utf-8?Q?=C5=81ukasz?= Stelmach Subject: Re: [PATCH 1/3] net: ax88796c: ASIX AX88796C SPI Ethernet Adapter Driver Message-ID: <20200825184413.GA2693@kozik-lap> References: <20200825170311.24886-1-l.stelmach@samsung.com> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <20200825170311.24886-1-l.stelmach@samsung.com> User-Agent: Mutt/1.9.4 (2018-02-28) X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20200825_144439_747593_ECD5357D X-CRM114-Status: GOOD ( 37.76 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: devicetree@vger.kernel.org, linux-samsung-soc@vger.kernel.org, b.zolnierkie@samsung.com, netdev@vger.kernel.org, Russell King , Rob Herring , linux-kernel@vger.kernel.org, Kukjin Kim , Jakub Kicinski , "David S. Miller" , linux-arm-kernel@lists.infradead.org, m.szyprowski@samsung.com 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 T24gVHVlLCBBdWcgMjUsIDIwMjAgYXQgMDc6MDM6MDlQTSArMDIwMCwgxYF1a2FzeiBTdGVsbWFj aCB3cm90ZToKPiBBU0lYIEFYODg3OTZbMV0gaXMgYSB2ZXJzYXRpbGUgZXRoZXJuZXQgYWRhcHRl ciBjaGlwLCB0aGF0IGNhbiBiZQo+IGNvbm5lY3RlZCB0byBhIENQVSB3aXRoIGEgOC8xNi1iaXQg YnVzIG9yIHdpdGggYW4gU1BJLiBUaGlzIGRyaXZlcgo+IHN1cHBvcnRzIFNQSSBjb25uZWN0aW9u Lgo+IAo+IFRoZSBkcml2ZXIgaGFzIGJlZW4gcG9ydGVkIGZyb20gdGhlIHZlbmRvciBrZXJuZWwg Zm9yIEFSVElLNVsyXQo+IGJvYXJkcy4gU2V2ZXJhbCBjaGFuZ2VzIHdlcmUgbWFkZSB0byBhZGFw dCBpdCB0byB0aGUgY3VycmVudCBrZXJuZWwKPiB3aGljaCBpbmNsdWRlOgo+IAo+ICsgdXBkYXRl ZCBEVCBjb25maWd1cmF0aW9uLAo+ICsgY2xvY2sgY29uZmlndXJhdGlvbiBtb3ZlZCB0byBEVCwK PiArIG5ldyB0aW1lciwgZXRodG9vbCBhbmQgZ3BpbyBBUElzCj4gKyBkZXZfKiBpbnN0ZWFkIG9m IHByXyogYW5kIGN1c3RvbSBwcmludGsoKSB3cmFwcGVycy4KPiAKPiBbMV0gaHR0cHM6Ly93d3cu YXNpeC5jb20udHcvcHJvZHVjdHMucGhwP29wPXBJdGVtZGV0YWlsJlBJdGVtSUQ9MTA0OzY1Ozg2 JlBMaW5lPTY1Cj4gWzJdIGh0dHBzOi8vZ2l0LnRpemVuLm9yZy9jZ2l0L3Byb2ZpbGUvY29tbW9u L3BsYXRmb3JtL2tlcm5lbC9saW51eC0zLjEwLWFydGlrLwo+IAo+IFRoZSBvdGhlciBheDg4Nzk2 IGRyaXZlciBpcyBmb3IgTkUyMDAwIGNvbXBhdGlibGUgQVg4ODc5NkwgY2hpcC4gVGhlc2UKPiBj aGlwcyBhcmUgbm90IGNvbXBhdGlibGUuIEhlbmNlLCB0d28gc2VwYXJhdGUgZHJpdmVycyBhcmUg cmVxdWlyZWQuCgpIaSwKClRoYW5rcyBmb3IgdGhlIGRyaXZlciwgbmljZSB3b3JrLiBGZXcgY29t bWVudHMgYmVsb3cuCgo+IAo+IFNpZ25lZC1vZmYtYnk6IMWBdWthc3ogU3RlbG1hY2ggPGwuc3Rl bG1hY2hAc2Ftc3VuZy5jb20+Cj4gLS0tCj4gIGRyaXZlcnMvbmV0L2V0aGVybmV0L0tjb25maWcg ICAgICAgICAgICAgICB8ICAgIDEgKwo+ICBkcml2ZXJzL25ldC9ldGhlcm5ldC9NYWtlZmlsZSAg ICAgICAgICAgICAgfCAgICAxICsKPiAgZHJpdmVycy9uZXQvZXRoZXJuZXQvYXNpeC9LY29uZmln ICAgICAgICAgIHwgICAyMCArCj4gIGRyaXZlcnMvbmV0L2V0aGVybmV0L2FzaXgvTWFrZWZpbGUg ICAgICAgICB8ICAgIDYgKwo+ICBkcml2ZXJzL25ldC9ldGhlcm5ldC9hc2l4L2F4ODg3OTZjX2lv Y3RsLmMgfCAgMjkzICsrKysrCj4gIGRyaXZlcnMvbmV0L2V0aGVybmV0L2FzaXgvYXg4ODc5NmNf aW9jdGwuaCB8ICAgMjEgKwo+ICBkcml2ZXJzL25ldC9ldGhlcm5ldC9hc2l4L2F4ODg3OTZjX21h aW4uYyAgfCAxMzczICsrKysrKysrKysrKysrKysrKysrCj4gIGRyaXZlcnMvbmV0L2V0aGVybmV0 L2FzaXgvYXg4ODc5NmNfbWFpbi5oICB8ICA1OTYgKysrKysrKysrCj4gIGRyaXZlcnMvbmV0L2V0 aGVybmV0L2FzaXgvYXg4ODc5NmNfc3BpLmMgICB8ICAxMDMgKysKPiAgZHJpdmVycy9uZXQvZXRo ZXJuZXQvYXNpeC9heDg4Nzk2Y19zcGkuaCAgIHwgICA2NyArCj4gIDEwIGZpbGVzIGNoYW5nZWQs IDI0ODEgaW5zZXJ0aW9ucygrKQo+ICBjcmVhdGUgbW9kZSAxMDA2NDQgZHJpdmVycy9uZXQvZXRo ZXJuZXQvYXNpeC9LY29uZmlnCj4gIGNyZWF0ZSBtb2RlIDEwMDY0NCBkcml2ZXJzL25ldC9ldGhl cm5ldC9hc2l4L01ha2VmaWxlCj4gIGNyZWF0ZSBtb2RlIDEwMDY0NCBkcml2ZXJzL25ldC9ldGhl cm5ldC9hc2l4L2F4ODg3OTZjX2lvY3RsLmMKPiAgY3JlYXRlIG1vZGUgMTAwNjQ0IGRyaXZlcnMv bmV0L2V0aGVybmV0L2FzaXgvYXg4ODc5NmNfaW9jdGwuaAo+ICBjcmVhdGUgbW9kZSAxMDA2NDQg ZHJpdmVycy9uZXQvZXRoZXJuZXQvYXNpeC9heDg4Nzk2Y19tYWluLmMKPiAgY3JlYXRlIG1vZGUg MTAwNjQ0IGRyaXZlcnMvbmV0L2V0aGVybmV0L2FzaXgvYXg4ODc5NmNfbWFpbi5oCj4gIGNyZWF0 ZSBtb2RlIDEwMDY0NCBkcml2ZXJzL25ldC9ldGhlcm5ldC9hc2l4L2F4ODg3OTZjX3NwaS5jCj4g IGNyZWF0ZSBtb2RlIDEwMDY0NCBkcml2ZXJzL25ldC9ldGhlcm5ldC9hc2l4L2F4ODg3OTZjX3Nw aS5oCj4gCj4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvbmV0L2V0aGVybmV0L0tjb25maWcgYi9kcml2 ZXJzL25ldC9ldGhlcm5ldC9LY29uZmlnCj4gaW5kZXggZGU1MGU4YjllNjU2Li5mM2IyMThlNDVl YTUgMTAwNjQ0Cj4gLS0tIGEvZHJpdmVycy9uZXQvZXRoZXJuZXQvS2NvbmZpZwo+ICsrKyBiL2Ry aXZlcnMvbmV0L2V0aGVybmV0L0tjb25maWcKPiBAQCAtMzIsNiArMzIsNyBAQCBzb3VyY2UgImRy aXZlcnMvbmV0L2V0aGVybmV0L2FwbS9LY29uZmlnIgo+ICBzb3VyY2UgImRyaXZlcnMvbmV0L2V0 aGVybmV0L2FwcGxlL0tjb25maWciCj4gIHNvdXJjZSAiZHJpdmVycy9uZXQvZXRoZXJuZXQvYXF1 YW50aWEvS2NvbmZpZyIKPiAgc291cmNlICJkcml2ZXJzL25ldC9ldGhlcm5ldC9hcmMvS2NvbmZp ZyIKPiArc291cmNlICJkcml2ZXJzL25ldC9ldGhlcm5ldC9hc2l4L0tjb25maWciCj4gIHNvdXJj ZSAiZHJpdmVycy9uZXQvZXRoZXJuZXQvYXRoZXJvcy9LY29uZmlnIgo+ICBzb3VyY2UgImRyaXZl cnMvbmV0L2V0aGVybmV0L2F1cm9yYS9LY29uZmlnIgo+ICBzb3VyY2UgImRyaXZlcnMvbmV0L2V0 aGVybmV0L2Jyb2FkY29tL0tjb25maWciCj4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvbmV0L2V0aGVy bmV0L01ha2VmaWxlIGIvZHJpdmVycy9uZXQvZXRoZXJuZXQvTWFrZWZpbGUKPiBpbmRleCBmOGYz OGRjYjVmOGEuLjllYjM2OGQ5MzYwNyAxMDA2NDQKPiAtLS0gYS9kcml2ZXJzL25ldC9ldGhlcm5l dC9NYWtlZmlsZQo+ICsrKyBiL2RyaXZlcnMvbmV0L2V0aGVybmV0L01ha2VmaWxlCj4gQEAgLTE4 LDYgKzE4LDcgQEAgb2JqLSQoQ09ORklHX05FVF9YR0VORSkgKz0gYXBtLwo+ICBvYmotJChDT05G SUdfTkVUX1ZFTkRPUl9BUFBMRSkgKz0gYXBwbGUvCj4gIG9iai0kKENPTkZJR19ORVRfVkVORE9S X0FRVUFOVElBKSArPSBhcXVhbnRpYS8KPiAgb2JqLSQoQ09ORklHX05FVF9WRU5ET1JfQVJDKSAr PSBhcmMvCj4gK29iai0kKENPTkZJR19ORVRfVkVORE9SX0FTSVgpICs9IGFzaXgvCj4gIG9iai0k KENPTkZJR19ORVRfVkVORE9SX0FUSEVST1MpICs9IGF0aGVyb3MvCj4gIG9iai0kKENPTkZJR19O RVRfVkVORE9SX0FVUk9SQSkgKz0gYXVyb3JhLwo+ICBvYmotJChDT05GSUdfTkVUX1ZFTkRPUl9D QURFTkNFKSArPSBjYWRlbmNlLwo+IGRpZmYgLS1naXQgYS9kcml2ZXJzL25ldC9ldGhlcm5ldC9h c2l4L0tjb25maWcgYi9kcml2ZXJzL25ldC9ldGhlcm5ldC9hc2l4L0tjb25maWcKPiBuZXcgZmls ZSBtb2RlIDEwMDY0NAo+IGluZGV4IDAwMDAwMDAwMDAwMC4uNGIxMjdhNGE2NTlhCj4gLS0tIC9k ZXYvbnVsbAo+ICsrKyBiL2RyaXZlcnMvbmV0L2V0aGVybmV0L2FzaXgvS2NvbmZpZwo+IEBAIC0w LDAgKzEsMjAgQEAKPiArIwo+ICsjIEFzaXggbmV0d29yayBkZXZpY2UgY29uZmlndXJhdGlvbgo+ ICsjCj4gKwo+ICtjb25maWcgTkVUX1ZFTkRPUl9BU0lYCj4gKwlib29sICJBc2l4IGRldmljZXMi Cj4gKwlkZXBlbmRzIG9uIFNQSQo+ICsJaGVscAo+ICsJICBJZiB5b3UgaGF2ZSBhIG5ldHdvcmsg KEV0aGVybmV0KSBpbnRlcmZhY2UgYmFzZWQgb24gYSBjaGlwIGZyb20gQVNJWCwgc2F5IFkKCkxv b2tzIGxpa2UgdG9vIGxvbmcsIGRpZCBpdCBwYXNzIGNoZWNrcGF0Y2g/Cgo+ICsKPiAraWYgTkVU X1ZFTkRPUl9BU0lYCj4gKwo+ICtjb25maWcgU1BJX0FYODg3OTZDCj4gKwl0cmlzdGF0ZSAiQXNp eCBBWDg4Nzk2Qy1TUEkgc3VwcG9ydCIKPiArCWRlcGVuZHMgb24gU1BJCj4gKwlkZXBlbmRzIG9u IEdQSU9MSUIKPiArCWhlbHAKPiArCSAgU2F5IFkgaGVyZSBpZiB5b3UgaW50ZW5kIHRvIGF0dGFj aCBhIEFzaXggQVg4ODc5NkMgYXMgU1BJIG1vZGUKPiArCj4gK2VuZGlmICMgTkVUX1ZFTkRPUl9B U0lYCj4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvbmV0L2V0aGVybmV0L2FzaXgvTWFrZWZpbGUgYi9k cml2ZXJzL25ldC9ldGhlcm5ldC9hc2l4L01ha2VmaWxlCj4gbmV3IGZpbGUgbW9kZSAxMDA2NDQK PiBpbmRleCAwMDAwMDAwMDAwMDAuLjBiZmJiYjA0MjYzNAo+IC0tLSAvZGV2L251bGwKPiArKysg Yi9kcml2ZXJzL25ldC9ldGhlcm5ldC9hc2l4L01ha2VmaWxlCj4gQEAgLTAsMCArMSw2IEBACj4g KyMKPiArIyBNYWtlZmlsZSBmb3IgdGhlIEFzaXggbmV0d29yayBkZXZpY2UgZHJpdmVycy4KPiAr Iwo+ICsKPiArb2JqLSQoQ09ORklHX1NQSV9BWDg4Nzk2QykgKz0gYXg4ODc5NmMubwo+ICtheDg4 Nzk2Yy15IDo9IGF4ODg3OTZjX21haW4ubyBheDg4Nzk2Y19pb2N0bC5vIGF4ODg3OTZjX3NwaS5v Cj4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvbmV0L2V0aGVybmV0L2FzaXgvYXg4ODc5NmNfaW9jdGwu YyBiL2RyaXZlcnMvbmV0L2V0aGVybmV0L2FzaXgvYXg4ODc5NmNfaW9jdGwuYwo+IG5ldyBmaWxl IG1vZGUgMTAwNjQ0Cj4gaW5kZXggMDAwMDAwMDAwMDAwLi5lYmEzNjFlMmE4YjcKPiAtLS0gL2Rl di9udWxsCj4gKysrIGIvZHJpdmVycy9uZXQvZXRoZXJuZXQvYXNpeC9heDg4Nzk2Y19pb2N0bC5j Cj4gQEAgLTAsMCArMSwyOTMgQEAKPiArLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEdQTC0y LjAtb25seQo+ICsvKgo+ICsgKiBDb3B5cmlnaHQgKGMpIDIwMTAgQVNJWCBFbGVjdHJvbmljcyBD b3Jwb3JhdGlvbgo+ICsgKiBDb3B5cmlnaHQgKGMpIDIwMjAgU2Ftc3VuZyBFbGVjdHJvbmljcyBD by4sIEx0ZC4KPiArICoKPiArICogQVNJWCBBWDg4Nzk2QyBTUEkgRmFzdCBFdGhlcm5ldCBMaW51 eCBkcml2ZXIKPiArICovCj4gKwo+ICsjaW5jbHVkZSAiYXg4ODc5NmNfbWFpbi5oIgo+ICsjaW5j bHVkZSAiYXg4ODc5NmNfc3BpLmgiCj4gKyNpbmNsdWRlICJheDg4Nzk2Y19pb2N0bC5oIgo+ICsK PiArdTggYXg4ODc5NmNfY2hlY2tfcG93ZXIoc3RydWN0IGF4ODg3OTZjX2RldmljZSAqYXhfbG9j YWwpCgpMb29rcyBoZXJlIGxpa2UgcG9pbnRlciB0byBjb25zdC4gVW5sZXNzIGl0IGlzIGJlY2F1 c2Ugb2YKQVhfUkVBRF9TVEFUVVMoKSB3aGljaCBjYW5ub3QgdGFrZSBjb25zdD8KCj4gK3sKClBs ZWFzZSBwdXQgZmlsZS1zY29wZSBkZWZpbml0aW9ucyBmaXJzdCwgc28gdGhpcyBzaG91bGQgZ28g dG8gdGhlIGVuZC4KCj4gKwlzdHJ1Y3Qgc3BpX3N0YXR1cyBheF9zdGF0dXM7Cj4gKwo+ICsJLyog Q2hlY2sgbWVkaWEgbGluayBzdGF0dXMgZmlyc3QgKi8KPiArCWlmIChuZXRpZl9jYXJyaWVyX29r KGF4X2xvY2FsLT5uZGV2KSB8fAo+ICsJICAgIChheF9sb2NhbC0+cHNfbGV2ZWwgPT0gQVhfUFNf RDApICB8fAo+ICsJICAgIChheF9sb2NhbC0+cHNfbGV2ZWwgPT0gQVhfUFNfRDEpKSB7Cj4gKwkJ cmV0dXJuIDA7Cj4gKwl9Cj4gKwo+ICsJQVhfUkVBRF9TVEFUVVMoJmF4X2xvY2FsLT5heF9zcGks ICZheF9zdGF0dXMpOwo+ICsJaWYgKCEoYXhfc3RhdHVzLnN0YXR1cyAmIEFYX1NUQVRVU19SRUFE WSkpCgpUaGlzIGxvb2tzIGJ1Z2d5Li4uIEFYX1JFQURfU1RBVFVTIGNhbiBmYWlsLCB3aXRob3V0 IHJlcG9ydGluZyBhbiBlcnJvci4KVGhlcmUgaXMgbm8gZXJyb3IgaGFuZGxpbmcuIFdoYXQgd2ls bCBiZSB0aGUgdmFsdWUgb2YgYXhfc3RhdHVzPyBTdXJlLApzb21lIHN0YWNrLXByb3RlY3Rvci1H Q0MtcGx1Z2lucyBtaWdodCBpbml0aWFsaXplIGl0IHRvIDAsIGJ1dCB0aGF0J3MKbm90IGEgZ29v ZCBkZXNpZ24uCgpUaGVyZSBpcyBubyBlcnJvciBoYW5kbGluZyBvZiBhbGwgU1BJIGZ1bmN0aW9u cyBzbyBlbnRpcmUgZHJpdmVyIHdvcmtzCmJlY2F1c2Ugb2YgbHVjay4uLiBpZiB0aGVyZSBpcyBh bnkgZXJyb3IgaW4gdGhlIG1pZGRsZSBvZiBzb21lIHdvcmssIGl0Cndvbid0IHNwb3QgaXQuCgo+ ICsJCXJldHVybiAxOwo+ICsKPiArCXJldHVybiAwOwo+ICt9Cj4gKwo+ICt1OCBheDg4Nzk2Y19j aGVja19wb3dlcl9hbmRfd2FrZShzdHJ1Y3QgYXg4ODc5NmNfZGV2aWNlICpheF9sb2NhbCkKPiAr ewo+ICsJc3RydWN0IHNwaV9zdGF0dXMgYXhfc3RhdHVzOwo+ICsJdW5zaWduZWQgbG9uZyBzdGFy dF90aW1lOwo+ICsKPiArCS8qIENoZWNrIG1lZGlhIGxpbmsgc3RhdHVzIGZpcnN0ICovCj4gKwlp ZiAobmV0aWZfY2Fycmllcl9vayhheF9sb2NhbC0+bmRldikgfHwKPiArCSAgICAoYXhfbG9jYWwt PnBzX2xldmVsID09IEFYX1BTX0QwKSB8fAo+ICsJICAgIChheF9sb2NhbC0+cHNfbGV2ZWwgPT0g QVhfUFNfRDEpKSB7Cj4gKwkJcmV0dXJuIDA7Cj4gKwl9Cj4gKwo+ICsJQVhfUkVBRF9TVEFUVVMo JmF4X2xvY2FsLT5heF9zcGksICZheF9zdGF0dXMpOwo+ICsJaWYgKCEoYXhfc3RhdHVzLnN0YXR1 cyAmIEFYX1NUQVRVU19SRUFEWSkpIHsKPiArCj4gKwkJLyogQVg4ODc5NkMgaW4gcG93ZXIgc2F2 aW5nIG1vZGUgKi8KPiArCQlBWF9XQUtFVVAoJmF4X2xvY2FsLT5heF9zcGkpOwo+ICsKPiArCQkv KiBDaGVjayBzdGF0dXMgKi8KPiArCQlzdGFydF90aW1lID0gamlmZmllczsKPiArCQlkbyB7Cj4g KwkJCWlmICh0aW1lX2FmdGVyKGppZmZpZXMsIHN0YXJ0X3RpbWUgKyBIWi8yKSkgewo+ICsJCQkJ bmV0ZGV2X2VycihheF9sb2NhbC0+bmRldiwKPiArCQkJCQkidGltZW91dCB3YWl0aW5nIGZvciB3 YWtldXAiCj4gKwkJCQkJIiBmcm9tIHBvd2VyIHNhdmluZ1xuIik7Cj4gKwkJCQlicmVhazsKPiAr CQkJfQo+ICsKPiArCQkJQVhfUkVBRF9TVEFUVVMoJmF4X2xvY2FsLT5heF9zcGksICZheF9zdGF0 dXMpOwo+ICsKPiArCQl9IHdoaWxlICghKGF4X3N0YXR1cy5zdGF0dXMgJiBBWF9TVEFUVVNfUkVB RFkpKTsKPiArCj4gKwkJYXg4ODc5NmNfc2V0X3Bvd2VyX3NhdmluZyhheF9sb2NhbCwgQVhfUFNf RDApOwo+ICsKPiArCQlyZXR1cm4gMTsKPiArCX0KPiArCj4gKwlyZXR1cm4gMDsKPiArfQo+ICsK PiArdm9pZCBheDg4Nzk2Y19zZXRfcG93ZXJfc2F2aW5nKHN0cnVjdCBheDg4Nzk2Y19kZXZpY2Ug KmF4X2xvY2FsLCB1OCBwc19sZXZlbCkKPiArewo+ICsJdTE2IHBtbTsKPiArCj4gKwlpZiAocHNf bGV2ZWwgPT0gQVhfUFNfRDEpCj4gKwkJcG1tID0gUFNDUl9QU19EMTsKPiArCWVsc2UgaWYgKHBz X2xldmVsID09IEFYX1BTX0QyKQo+ICsJCXBtbSA9IFBTQ1JfUFNfRDI7Cj4gKwllbHNlCj4gKwkJ cG1tID0gUFNDUl9QU19EMDsKPiArCj4gKwlBWF9XUklURSgmYXhfbG9jYWwtPmF4X3NwaSwgKEFY X1JFQUQoJmF4X2xvY2FsLT5heF9zcGksIFAwX1BTQ1IpCj4gKwkJCQkgICAgICAmIFBTQ1JfUFNf TUFTSykgfCBwbW0sIFAwX1BTQ1IpOwo+ICt9Cj4gKwo+ICtpbnQgYXg4ODc5NmNfbWRpb19yZWFk KHN0cnVjdCBuZXRfZGV2aWNlICpuZGV2LCBpbnQgcGh5X2lkLCBpbnQgbG9jKQo+ICt7Cj4gKwlz dHJ1Y3QgYXg4ODc5NmNfZGV2aWNlICpheF9sb2NhbCA9IHRvX2F4ODg3OTZjX2RldmljZShuZGV2 KTsKPiArCXVuc2lnbmVkIGxvbmcgc3RhcnRfdGltZTsKPiArCj4gKwlBWF9XUklURSgmYXhfbG9j YWwtPmF4X3NwaSwgTURJT0NSX1JBRERSKGxvYykKPiArCQkJfCBNRElPQ1JfRkFERFIocGh5X2lk KSB8IE1ESU9DUl9SRUFELCBQMl9NRElPQ1IpOwo+ICsKPiArCXN0YXJ0X3RpbWUgPSBqaWZmaWVz Owo+ICsJd2hpbGUgKChBWF9SRUFEKCZheF9sb2NhbC0+YXhfc3BpLCBQMl9NRElPQ1IpICYgTURJ T0NSX1ZBTElEKSA9PSAwKSB7Cj4gKwkJaWYgKHRpbWVfYWZ0ZXIoamlmZmllcywgc3RhcnRfdGlt ZSArIEhaLzEwMCkpCj4gKwkJCXJldHVybiAtRUJVU1k7Cj4gKwl9Cj4gKwo+ICsJcmV0dXJuIEFY X1JFQUQoJmF4X2xvY2FsLT5heF9zcGksIFAyX01ESU9EUik7Cj4gK30KPiArCj4gK3ZvaWQKPiAr YXg4ODc5NmNfbWRpb193cml0ZShzdHJ1Y3QgbmV0X2RldmljZSAqbmRldiwgaW50IHBoeV9pZCwg aW50IGxvYywgaW50IHZhbCkKPiArewo+ICsJc3RydWN0IGF4ODg3OTZjX2RldmljZSAqYXhfbG9j YWwgPSB0b19heDg4Nzk2Y19kZXZpY2UobmRldik7Cj4gKwl1bnNpZ25lZCBsb25nIHN0YXJ0X3Rp bWU7Cj4gKwo+ICsJQVhfV1JJVEUoJmF4X2xvY2FsLT5heF9zcGksIHZhbCwgUDJfTURJT0RSKTsK PiArCj4gKwlBWF9XUklURSgmYXhfbG9jYWwtPmF4X3NwaSwKPiArCQkJTURJT0NSX1JBRERSKGxv YykgfCBNRElPQ1JfRkFERFIocGh5X2lkKQo+ICsJCQl8IE1ESU9DUl9XUklURSwgUDJfTURJT0NS KTsKPiArCj4gKwlzdGFydF90aW1lID0gamlmZmllczsKPiArCXdoaWxlICgoQVhfUkVBRCgmYXhf bG9jYWwtPmF4X3NwaSwgUDJfTURJT0NSKSAmIE1ESU9DUl9WQUxJRCkgPT0gMCkgewo+ICsJCWlm ICh0aW1lX2FmdGVyKGppZmZpZXMsIHN0YXJ0X3RpbWUgKyBIWi8xMDApKQo+ICsJCQlyZXR1cm47 Cj4gKwl9Cj4gKwo+ICsJaWYgKGxvYyA9PSBNSUlfQURWRVJUSVNFKSB7Cj4gKwkJQVhfV1JJVEUo JmF4X2xvY2FsLT5heF9zcGksIChCTUNSX0ZVTExEUExYIHwgQk1DUl9BTlJFU1RBUlQgfAo+ICsJ CQkgIEJNQ1JfQU5FTkFCTEUgfCBCTUNSX1NQRUVEMTAwKSwgUDJfTURJT0RSKTsKPiArCQlBWF9X UklURSgmYXhfbG9jYWwtPmF4X3NwaSwgKE1ESU9DUl9SQUREUihNSUlfQk1DUikgfAo+ICsJCQkg IE1ESU9DUl9GQUREUihwaHlfaWQpIHwgTURJT0NSX1dSSVRFKSwKPiArCQkJICBQMl9NRElPQ1Ip Owo+ICsKPiArCQlzdGFydF90aW1lID0gamlmZmllczsKPiArCQl3aGlsZSAoKEFYX1JFQUQoJmF4 X2xvY2FsLT5heF9zcGksIFAyX01ESU9DUikKPiArCQkJCQkmIE1ESU9DUl9WQUxJRCkgPT0gMCkg ewo+ICsJCQlpZiAodGltZV9hZnRlcihqaWZmaWVzLCBzdGFydF90aW1lICsgSFovMTAwKSkKPiAr CQkJCXJldHVybjsKPiArCQl9Cj4gKwl9Cj4gK30KPiArCj4gK3ZvaWQgYXg4ODc5NmNfc2V0X2Nz dW1zKHN0cnVjdCBheDg4Nzk2Y19kZXZpY2UgKmF4X2xvY2FsKQo+ICt7Cj4gKwlpZiAoYXhfbG9j YWwtPmNoZWNrc3VtICYgQVhfUlhfQ0hFQ0tTVU0pIHsKPiArCQlBWF9XUklURSgmYXhfbG9jYWwt PmF4X3NwaSwgQ09FUkNSMF9ERUZBVUxULCBQNF9DT0VSQ1IwKTsKPiArCQlBWF9XUklURSgmYXhf bG9jYWwtPmF4X3NwaSwgQ09FUkNSMV9ERUZBVUxULCBQNF9DT0VSQ1IxKTsKPiArCX0gZWxzZSB7 Cj4gKwkJQVhfV1JJVEUoJmF4X2xvY2FsLT5heF9zcGksIDAsIFA0X0NPRVJDUjApOwo+ICsJCUFY X1dSSVRFKCZheF9sb2NhbC0+YXhfc3BpLCAwLCBQNF9DT0VSQ1IxKTsKPiArCX0KPiArCj4gKwlp ZiAoYXhfbG9jYWwtPmNoZWNrc3VtICYgQVhfVFhfQ0hFQ0tTVU0pIHsKPiArCQlBWF9XUklURSgm YXhfbG9jYWwtPmF4X3NwaSwgQ09FVENSMF9ERUZBVUxULCBQNF9DT0VUQ1IwKTsKPiArCQlBWF9X UklURSgmYXhfbG9jYWwtPmF4X3NwaSwgQ09FVENSMV9UWFBQUEUsIFA0X0NPRVRDUjEpOwo+ICsJ fSBlbHNlIHsKPiArCQlBWF9XUklURSgmYXhfbG9jYWwtPmF4X3NwaSwgMCwgUDRfQ09FVENSMCk7 Cj4gKwkJQVhfV1JJVEUoJmF4X2xvY2FsLT5heF9zcGksIDAsIFA0X0NPRVRDUjEpOwo+ICsJfQo+ ICt9Cj4gKwo+ICtzdGF0aWMgdm9pZCBheDg4Nzk2Y19nZXRfZHJ2aW5mbyhzdHJ1Y3QgbmV0X2Rl dmljZSAqbmRldiwKPiArCQkJCSBzdHJ1Y3QgZXRodG9vbF9kcnZpbmZvICppbmZvKQo+ICt7Cj4g KwkvKiBJbmhlcml0IHN0YW5kYXJkIGRldmljZSBpbmZvICovCj4gKwlzdHJuY3B5KGluZm8tPmRy aXZlciwgRFJWX05BTUUsIHNpemVvZihpbmZvLT5kcml2ZXIpKTsKPiArCXN0cm5jcHkoaW5mby0+ dmVyc2lvbiwgRFJWX1ZFUlNJT04sIHNpemVvZihpbmZvLT52ZXJzaW9uKSk7Cj4gK30KPiArCj4g K3N0YXRpYyB1MzIgYXg4ODc5NmNfZ2V0X2xpbmsoc3RydWN0IG5ldF9kZXZpY2UgKm5kZXYpCj4g K3sKPiArCXUzMiBsaW5rOwo+ICsJc3RydWN0IGF4ODg3OTZjX2RldmljZSAqYXhfbG9jYWwgPSB0 b19heDg4Nzk2Y19kZXZpY2UobmRldik7Cj4gKwl1OCBwb3dlcjsKPiArCj4gKwlkb3duKCZheF9s b2NhbC0+c3BpX2xvY2spOwo+ICsJcG93ZXIgPSBheDg4Nzk2Y19jaGVja19wb3dlcl9hbmRfd2Fr ZShheF9sb2NhbCk7Cj4gKwo+ICsJbGluayA9IG1paV9saW5rX29rKCZheF9sb2NhbC0+bWlpKTsK PiArCj4gKwlpZiAocG93ZXIpCj4gKwkJYXg4ODc5NmNfc2V0X3Bvd2VyX3NhdmluZyhheF9sb2Nh bCwgYXhfbG9jYWwtPnBzX2xldmVsKTsKPiArCXVwKCZheF9sb2NhbC0+c3BpX2xvY2spOwo+ICsK PiArCXJldHVybiBsaW5rOwo+ICsKPiArCgpFbXB0eSBsaW5lcy4KCj4gK30KPiArCj4gK3N0YXRp YyB1MzIgYXg4ODc5NmNfZ2V0X21zZ2xldmVsKHN0cnVjdCBuZXRfZGV2aWNlICpuZGV2KQo+ICt7 Cj4gKwlzdHJ1Y3QgYXg4ODc5NmNfZGV2aWNlICpheF9sb2NhbCA9IHRvX2F4ODg3OTZjX2Rldmlj ZShuZGV2KTsKPiArCXJldHVybiBheF9sb2NhbC0+bXNnX2VuYWJsZTsKPiArfQo+ICsKPiArc3Rh dGljIHZvaWQgYXg4ODc5NmNfc2V0X21zZ2xldmVsKHN0cnVjdCBuZXRfZGV2aWNlICpuZGV2LCB1 MzIgbGV2ZWwpCj4gK3sKPiArCXN0cnVjdCBheDg4Nzk2Y19kZXZpY2UgKmF4X2xvY2FsID0gdG9f YXg4ODc5NmNfZGV2aWNlKG5kZXYpOwo+ICsJYXhfbG9jYWwtPm1zZ19lbmFibGUgPSBsZXZlbDsK PiArfQo+ICsKPiArCgpPbmUgbGluZSBicmVhay4KCj4gK3N0YXRpYyBpbnQKPiArYXg4ODc5NmNf Z2V0X2xpbmtfa3NldHRpbmdzKHN0cnVjdCBuZXRfZGV2aWNlICpuZGV2LAo+ICsJCQkgICAgc3Ry dWN0IGV0aHRvb2xfbGlua19rc2V0dGluZ3MgKmNtZCkKPiArewo+ICsJc3RydWN0IGF4ODg3OTZj X2RldmljZSAqYXhfbG9jYWwgPSB0b19heDg4Nzk2Y19kZXZpY2UobmRldik7Cj4gKwl1OCBwb3dl cjsKPiArCj4gKwlkb3duKCZheF9sb2NhbC0+c3BpX2xvY2spOwo+ICsJcG93ZXIgPSBheDg4Nzk2 Y19jaGVja19wb3dlcl9hbmRfd2FrZShheF9sb2NhbCk7Cj4gKwo+ICsJbWlpX2V0aHRvb2xfZ2V0 X2xpbmtfa3NldHRpbmdzKCZheF9sb2NhbC0+bWlpLCBjbWQpOwo+ICsKPiArCWlmIChwb3dlcikK PiArCQlheDg4Nzk2Y19zZXRfcG93ZXJfc2F2aW5nKGF4X2xvY2FsLCBheF9sb2NhbC0+cHNfbGV2 ZWwpOwo+ICsJdXAoJmF4X2xvY2FsLT5zcGlfbG9jayk7Cj4gKwo+ICsJcmV0dXJuIDA7Cj4gK30K PiArCj4gK3N0YXRpYyBpbnQKPiArYXg4ODc5NmNfc2V0X2xpbmtfa3NldHRpbmdzKHN0cnVjdCBu ZXRfZGV2aWNlICpuZGV2LAo+ICsJCQkgICAgY29uc3Qgc3RydWN0IGV0aHRvb2xfbGlua19rc2V0 dGluZ3MgKmNtZCkKPiArewo+ICsJc3RydWN0IGF4ODg3OTZjX2RldmljZSAqYXhfbG9jYWwgPSB0 b19heDg4Nzk2Y19kZXZpY2UobmRldik7Cj4gKwl1OCBwb3dlcjsKPiArCj4gKwlkb3duKCZheF9s b2NhbC0+c3BpX2xvY2spOwo+ICsJcG93ZXIgPSBheDg4Nzk2Y19jaGVja19wb3dlcl9hbmRfd2Fr ZShheF9sb2NhbCk7Cj4gKwo+ICsJbWlpX2V0aHRvb2xfc2V0X2xpbmtfa3NldHRpbmdzKCZheF9s b2NhbC0+bWlpLCBjbWQpOwo+ICsKPiArCWlmIChwb3dlcikKPiArCQlheDg4Nzk2Y19zZXRfcG93 ZXJfc2F2aW5nKGF4X2xvY2FsLCBheF9sb2NhbC0+cHNfbGV2ZWwpOwo+ICsJdXAoJmF4X2xvY2Fs LT5zcGlfbG9jayk7Cj4gKwlyZXR1cm4gMDsKPiArCgpMaW5lIGJlZm9yZSByZXR1cm4sIG5vdCBh ZnRlci4KCj4gK30KPiArCj4gK3N0YXRpYyBpbnQgYXg4ODc5NmNfbndheV9yZXNldChzdHJ1Y3Qg bmV0X2RldmljZSAqbmRldikKPiArewo+ICsJc3RydWN0IGF4ODg3OTZjX2RldmljZSAqYXhfbG9j YWwgPSB0b19heDg4Nzk2Y19kZXZpY2UobmRldik7Cj4gKwlpbnQgcmV0Owo+ICsJdTggcG93ZXI7 Cj4gKwo+ICsJZG93bigmYXhfbG9jYWwtPnNwaV9sb2NrKTsKPiArCXBvd2VyID0gYXg4ODc5NmNf Y2hlY2tfcG93ZXJfYW5kX3dha2UoYXhfbG9jYWwpOwo+ICsKPiArCXJldCA9IG1paV9ud2F5X3Jl c3RhcnQoJmF4X2xvY2FsLT5taWkpOwo+ICsKPiArCWlmIChwb3dlcikKPiArCQlheDg4Nzk2Y19z ZXRfcG93ZXJfc2F2aW5nKGF4X2xvY2FsLCBheF9sb2NhbC0+cHNfbGV2ZWwpOwo+ICsJdXAoJmF4 X2xvY2FsLT5zcGlfbG9jayk7Cj4gKwlyZXR1cm4gcmV0Owo+ICt9Cj4gKwo+ICtzdGF0aWMgdTMy IGF4ODg3OTZjX2V0aHRvb2xfZ2V0bXNnbGV2ZWwoc3RydWN0IG5ldF9kZXZpY2UgKm5kZXYpCj4g K3sKPiArCXN0cnVjdCBheDg4Nzk2Y19kZXZpY2UgKmF4X2xvY2FsID0gdG9fYXg4ODc5NmNfZGV2 aWNlKG5kZXYpOwo+ICsJcmV0dXJuIGF4X2xvY2FsLT5tc2dfZW5hYmxlOwo+ICt9Cj4gKwo+ICtz dGF0aWMgdm9pZCBheDg4Nzk2Y19ldGh0b29sX3NldG1zZ2xldmVsKHN0cnVjdCBuZXRfZGV2aWNl ICpuZGV2LCB1MzIgbGV2ZWwpCj4gK3sKPiArCXN0cnVjdCBheDg4Nzk2Y19kZXZpY2UgKmF4X2xv Y2FsID0gdG9fYXg4ODc5NmNfZGV2aWNlKG5kZXYpOwo+ICsJYXhfbG9jYWwtPm1zZ19lbmFibGUg PSBsZXZlbDsKPiArfQo+ICsKPiArc3RydWN0IGV0aHRvb2xfb3BzIGF4ODg3OTZjX2V0aHRvb2xf b3BzID0gewo+ICsJLmdldF9kcnZpbmZvCQk9IGF4ODg3OTZjX2dldF9kcnZpbmZvLAo+ICsJLmdl dF9saW5rCQk9IGF4ODg3OTZjX2dldF9saW5rLAo+ICsJLmdldF9tc2dsZXZlbAkJPSBheDg4Nzk2 Y19nZXRfbXNnbGV2ZWwsCj4gKwkuc2V0X21zZ2xldmVsCQk9IGF4ODg3OTZjX3NldF9tc2dsZXZl bCwKPiArCS5nZXRfbGlua19rc2V0dGluZ3MJPSBheDg4Nzk2Y19nZXRfbGlua19rc2V0dGluZ3Ms Cj4gKwkuc2V0X2xpbmtfa3NldHRpbmdzCT0gYXg4ODc5NmNfc2V0X2xpbmtfa3NldHRpbmdzLAo+ ICsJLm53YXlfcmVzZXQJCT0gYXg4ODc5NmNfbndheV9yZXNldCwKPiArCS5nZXRfbXNnbGV2ZWwJ CT0gYXg4ODc5NmNfZXRodG9vbF9nZXRtc2dsZXZlbCwKPiArCS5zZXRfbXNnbGV2ZWwJCT0gYXg4 ODc5NmNfZXRodG9vbF9zZXRtc2dsZXZlbCwKPiArfTsKPiArCj4gK2ludCBheDg4Nzk2Y19pb2N0 bChzdHJ1Y3QgbmV0X2RldmljZSAqbmRldiwgc3RydWN0IGlmcmVxICppZnIsIGludCBjbWQpCj4g K3sKPiArCXN0cnVjdCBheDg4Nzk2Y19kZXZpY2UgKmF4X2xvY2FsID0gdG9fYXg4ODc5NmNfZGV2 aWNlKG5kZXYpOwo+ICsJaW50IHJldDsKPiArCXU4IHBvd2VyOwo+ICsKPiArCWRvd24oJmF4X2xv Y2FsLT5zcGlfbG9jayk7Cj4gKwlwb3dlciA9IGF4ODg3OTZjX2NoZWNrX3Bvd2VyX2FuZF93YWtl KGF4X2xvY2FsKTsKPiArCj4gKwlyZXQgPSBnZW5lcmljX21paV9pb2N0bCgmYXhfbG9jYWwtPm1p aSwgaWZfbWlpKGlmciksIGNtZCwgTlVMTCk7Cj4gKwo+ICsJaWYgKHBvd2VyKQo+ICsJCWF4ODg3 OTZjX3NldF9wb3dlcl9zYXZpbmcoYXhfbG9jYWwsIGF4X2xvY2FsLT5wc19sZXZlbCk7Cj4gKwl1 cCgmYXhfbG9jYWwtPnNwaV9sb2NrKTsKPiArCj4gKwlyZXR1cm4gcmV0Owo+ICt9Cj4gKwo+IGRp ZmYgLS1naXQgYS9kcml2ZXJzL25ldC9ldGhlcm5ldC9hc2l4L2F4ODg3OTZjX2lvY3RsLmggYi9k cml2ZXJzL25ldC9ldGhlcm5ldC9hc2l4L2F4ODg3OTZjX2lvY3RsLmgKPiBuZXcgZmlsZSBtb2Rl IDEwMDY0NAo+IGluZGV4IDAwMDAwMDAwMDAwMC4uYmFmZDU3M2JkODEzCj4gLS0tIC9kZXYvbnVs bAo+ICsrKyBiL2RyaXZlcnMvbmV0L2V0aGVybmV0L2FzaXgvYXg4ODc5NmNfaW9jdGwuaAo+IEBA IC0wLDAgKzEsMjEgQEAKPiArLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEdQTC0yLjAtb25s eQo+ICsvKgo+ICsgKiBDb3B5cmlnaHQgKGMpIDIwMTAgQVNJWCBFbGVjdHJvbmljcyBDb3Jwb3Jh dGlvbgo+ICsgKgo+ICsgKiBBU0lYIEFYODg3OTZDIFNQSSBGYXN0IEV0aGVybmV0IExpbnV4IGRy aXZlcgo+ICsgKi8KPiArCj4gKyNpZm5kZWYgX0FYODg3OTZDX0lPQ1RMX0gKPiArI2RlZmluZSBf QVg4ODc5NkNfSU9DVExfSAo+ICsKPiArZXh0ZXJuIHN0cnVjdCBldGh0b29sX29wcyBheDg4Nzk2 Y19ldGh0b29sX29wczsKPiArCj4gK3U4IGF4ODg3OTZjX2NoZWNrX3Bvd2VyKHN0cnVjdCBheDg4 Nzk2Y19kZXZpY2UgKmF4X2xvY2FsKTsKPiArdTggYXg4ODc5NmNfY2hlY2tfcG93ZXJfYW5kX3dh a2Uoc3RydWN0IGF4ODg3OTZjX2RldmljZSAqYXhfbG9jYWwpOwo+ICt2b2lkIGF4ODg3OTZjX3Nl dF9wb3dlcl9zYXZpbmcoc3RydWN0IGF4ODg3OTZjX2RldmljZSAqYXhfbG9jYWwsIHU4IHBzX2xl dmVsKTsKPiAraW50IGF4ODg3OTZjX21kaW9fcmVhZChzdHJ1Y3QgbmV0X2RldmljZSAqZGV2LCBp bnQgcGh5X2lkLCBpbnQgbG9jKTsKPiArdm9pZCBheDg4Nzk2Y19tZGlvX3dyaXRlKHN0cnVjdCBu ZXRfZGV2aWNlICpkZXYsIGludCBwaHlfaWQsIGludCBsb2MsIGludCB2YWwpOwo+ICt2b2lkIGF4 ODg3OTZjX3NldF9jc3VtcyhzdHJ1Y3QgYXg4ODc5NmNfZGV2aWNlICpheF9sb2NhbCk7Cj4gK2lu dCBheDg4Nzk2Y19pb2N0bChzdHJ1Y3QgbmV0X2RldmljZSAqZGV2LCBzdHJ1Y3QgaWZyZXEgKmlm ciwgaW50IGNtZCk7Cj4gKwo+ICsjZW5kaWYKPiBkaWZmIC0tZ2l0IGEvZHJpdmVycy9uZXQvZXRo ZXJuZXQvYXNpeC9heDg4Nzk2Y19tYWluLmMgYi9kcml2ZXJzL25ldC9ldGhlcm5ldC9hc2l4L2F4 ODg3OTZjX21haW4uYwo+IG5ldyBmaWxlIG1vZGUgMTAwNjQ0Cj4gaW5kZXggMDAwMDAwMDAwMDAw Li5jMjhjZmI5MzEzMTkKPiAtLS0gL2Rldi9udWxsCj4gKysrIGIvZHJpdmVycy9uZXQvZXRoZXJu ZXQvYXNpeC9heDg4Nzk2Y19tYWluLmMKPiBAQCAtMCwwICsxLDEzNzMgQEAKPiArLy8gU1BEWC1M aWNlbnNlLUlkZW50aWZpZXI6IEdQTC0yLjAtb25seQo+ICsvKgo+ICsgKiBDb3B5cmlnaHQgKGMp IDIwMTAgQVNJWCBFbGVjdHJvbmljcyBDb3Jwb3JhdGlvbgo+ICsgKiBDb3B5cmlnaHQgKGMpIDIw MjAgU2Ftc3VuZyBFbGVjdHJvbmljcyBDby4sIEx0ZC4KPiArICoKPiArICogQVNJWCBBWDg4Nzk2 QyBTUEkgRmFzdCBFdGhlcm5ldCBMaW51eCBkcml2ZXIKPiArICovCj4gKwo+ICsjaW5jbHVkZSAi YXg4ODc5NmNfbWFpbi5oIgo+ICsjaW5jbHVkZSAiYXg4ODc5NmNfaW9jdGwuaCIKPiArCj4gK3N0 YXRpYyBpbnQgY29tcDsKPiArc3RhdGljIGludCBwc19sZXZlbCA9IEFYX1BTX0QwOwo+ICtzdGF0 aWMgaW50IG1zZ19lbmFibGUgPSBORVRJRl9NU0dfUFJPQkUgfAo+ICsJCQlORVRJRl9NU0dfTElO SyB8Cj4gKwkJCS8qIE5FVElGX01TR19USU1FUiB8ICovCj4gKwkJCU5FVElGX01TR19SWF9FUlIg fAo+ICsJCQlORVRJRl9NU0dfVFhfRVJSIHwKPiArCQkJLyogTkVUSUZfTVNHX1RYX1FVRVVFRCB8 ICovCj4gKwkJCS8qIE5FVElGX01TR19JTlRSIHwgKi8KPiArCQkJLyogTkVUSUZfTVNHX1RYX0RP TkUgfCAqLwo+ICsJCQkvKiBORVRJRl9NU0dfUlhfU1RBVFVTIHwgKi8KPiArCQkJLyogTkVUSUZf TVNHX1BLVERBVEEgfCAqLwo+ICsJCQkvKiBORVRJRl9NU0dfSFcgfCAqLwo+ICsJCQlORVRJRl9N U0dfV09MOwo+ICsKPiArbW9kdWxlX3BhcmFtKGNvbXAsIGludCwgMCk7Cj4gK01PRFVMRV9QQVJN X0RFU0MoY29tcCwgIjA9Tm9uLUNvbXByZXNzaW9uIE1vZGUsIDE9Q29tcHJlc3Npb24gTW9kZSIp Owo+ICsKPiArbW9kdWxlX3BhcmFtKHBzX2xldmVsLCBpbnQsIDApOwo+ICtNT0RVTEVfUEFSTV9E RVNDKHBzX2xldmVsLAo+ICsJIlBvd2VyIFNhdmluZyBMZXZlbCAoMDpkaXNhYmxlIDE6bGV2ZWwg MSAyOmxldmVsIDIpIik7Cj4gKwo+ICttb2R1bGVfcGFyYW0obXNnX2VuYWJsZSwgaW50LCAwKTsK PiArTU9EVUxFX1BBUk1fREVTQyhtc2dfZW5hYmxlLCAiTWVzc2FnZSBtYXNrIChzZWUgbGludXgv bmV0ZGV2aWNlLmggZm9yIGJpdG1hcCkiKTsKPiArCj4gK3N0YXRpYyBjaGFyICptYWNhZGRyOwo+ ICttb2R1bGVfcGFyYW0obWFjYWRkciwgY2hhcnAsIDApOwo+ICtNT0RVTEVfUEFSTV9ERVNDKG1h Y2FkZHIsICJNQUMgYWRkcmVzcyIpOwoKSSB0aGluayBNQUMgYWRkcmVzcyBhcyBwYXJhbSBpcyBu b3QgYWNjZXB0ZWQgaW4gbWFpbmxpbmUuLi4KCj4gKwoKPiArTU9EVUxFX0FVVEhPUigiQVNJWCIp Owo+ICtNT0RVTEVfREVTQ1JJUFRJT04oIkFTSVggQVg4ODc5NkMgU1BJIEV0aGVybmV0IGRyaXZl ciIpOwo+ICtNT0RVTEVfTElDRU5TRSgiR1BMIik7CgpUaGVzZSB0aHJlZSB1c3VhbGx5IGdvIHRv IHRoZSBlbmQgb2YgZmlsZS4KCj4gKwo+ICtzdGF0aWMgdm9pZCBheDg4Nzk2Y19kdW1wX3JlZ3Mo c3RydWN0IGF4ODg3OTZjX2RldmljZSAqYXhfbG9jYWwpCj4gK3sKPiArCXN0cnVjdCBuZXRfZGV2 aWNlICpuZGV2ID0gYXhfbG9jYWwtPm5kZXY7Cj4gKwl1OCBpLCBqOwo+ICsKPiArCW5ldGRldl9p bmZvKG5kZXYsCj4gKwkJIiAgICAgICBQYWdlMCAgIFBhZ2UxICAgUGFnZTIgICBQYWdlMyAgICIK PiArCQkJCSJQYWdlNCAgIFBhZ2U1ICAgUGFnZTYgICBQYWdlN1xuIik7Cj4gKwlmb3IgKGkgPSAw OyBpIDwgMHgyMDsgaSArPSAyKSB7Cj4gKwkJbmV0ZGV2X2luZm8obmRldiwgIjB4JTAyeCAgICIs IGkpOwo+ICsJCWZvciAoaiA9IDA7IGogPCA4OyBqKyspIHsKPiArCQkJbmV0ZGV2X2luZm8obmRl diwgIjB4JTA0eCAgIiwKPiArCQkJCUFYX1JFQUQoJmF4X2xvY2FsLT5heF9zcGksIGogKiAweDIw ICsgaSkpOwo+ICsJCX0KPiArCQluZXRkZXZfaW5mbyhuZGV2LCAiXG4iKTsKPiArCX0KPiArCW5l dGRldl9pbmZvKG5kZXYsICJcbiIpOwo+ICt9Cj4gKwo+ICtzdGF0aWMgdm9pZCBheDg4Nzk2Y19k dW1wX3BoeV9yZWdzKHN0cnVjdCBheDg4Nzk2Y19kZXZpY2UgKmF4X2xvY2FsKQo+ICt7Cj4gKwlz dHJ1Y3QgbmV0X2RldmljZSAqbmRldiA9IGF4X2xvY2FsLT5uZGV2Owo+ICsJaW50IGk7Cj4gKwo+ ICsJbmV0ZGV2X2luZm8obmRldiwgIkR1bXAgUEhZIHJlZ2lzdGVyczpcbiIpOwo+ICsJZm9yIChp ID0gMDsgaSA8IDY7IGkrKykgewo+ICsJCW5ldGRldl9pbmZvKG5kZXYsICIgIE1SJWQgPSAweCUw NHhcbiIsIGksCj4gKwkJCWF4ODg3OTZjX21kaW9fcmVhZChheF9sb2NhbC0+bmRldiwKPiArCQkJ YXhfbG9jYWwtPm1paS5waHlfaWQsIGkpKTsKPiArCX0KPiArfQo+ICsKPiArc3RhdGljIHZvaWQg YXg4ODc5NmNfd2F0Y2hkb2coc3RydWN0IGF4ODg3OTZjX2RldmljZSAqYXhfbG9jYWwpCj4gK3sK PiArCXN0cnVjdCBuZXRfZGV2aWNlICpuZGV2ID0gYXhfbG9jYWwtPm5kZXY7Cj4gKwl1MTYgcGh5 X3N0YXR1czsKPiArCXVuc2lnbmVkIGxvbmcgdGltZV90b19jaGsgPSBBWDg4Nzk2Q19XQVRDSERP R19QRVJJT0Q7Cj4gKwo+ICsJaWYgKGF4ODg3OTZjX2NoZWNrX3Bvd2VyKGF4X2xvY2FsKSkgewo+ ICsJCW1vZF90aW1lcigmYXhfbG9jYWwtPndhdGNoZG9nLCBqaWZmaWVzICsgdGltZV90b19jaGsp Owo+ICsJCXJldHVybjsKPiArCX0KPiArCj4gKwlheDg4Nzk2Y19zZXRfcG93ZXJfc2F2aW5nKGF4 X2xvY2FsLCBBWF9QU19EMCk7Cj4gKwo+ICsJcGh5X3N0YXR1cyA9IEFYX1JFQUQoJmF4X2xvY2Fs LT5heF9zcGksIFAwX1BTQ1IpOwo+ICsJaWYgKHBoeV9zdGF0dXMgJiBQU0NSX1BIWUxJTkspIHsK PiArCj4gKwkJYXhfbG9jYWwtPndfc3RhdGUgPSBheF9ub3A7Cj4gKwkJdGltZV90b19jaGsgPSAw Owo+ICsKPiArCX0gZWxzZSBpZiAoIShwaHlfc3RhdHVzICYgUFNDUl9QSFlDT0ZGKSkgewo+ICsJ CS8qIFRoZSBldGhlcm5ldCBjYWJsZSBoYXMgYmVlbiBwbHVnZ2VkICovCj4gKwkJaWYgKGF4X2xv Y2FsLT53X3N0YXRlID09IGNoa19jYWJsZSkgewo+ICsJCQlpZiAobmV0aWZfbXNnX3RpbWVyKGF4 X2xvY2FsKSkKPiArCQkJCW5ldGRldl9pbmZvKG5kZXYsICJDYWJsZSBjb25uZWN0ZWRcbiIpOwo+ ICsKPiArCQkJYXhfbG9jYWwtPndfc3RhdGUgPSBjaGtfbGluazsKPiArCQkJYXhfbG9jYWwtPndf dGlja3MgPSAwOwo+ICsJCX0gZWxzZSB7Cj4gKwkJCWlmIChuZXRpZl9tc2dfdGltZXIoYXhfbG9j YWwpKQo+ICsJCQkJbmV0ZGV2X2luZm8obmRldiwgIkNoZWNrIG1lZGlhIHN0YXR1c1xuIik7Cj4g Kwo+ICsJCQlpZiAoKytheF9sb2NhbC0+d190aWNrcyA9PSBBWDg4Nzk2Q19XQVRDSERPR19SRVNU QVJUKSB7Cj4gKwkJCQlpZiAobmV0aWZfbXNnX3RpbWVyKGF4X2xvY2FsKSkKPiArCQkJCQluZXRk ZXZfaW5mbyhuZGV2LCAiUmVzdGFydCBhdXRvbmVnXG4iKTsKPiArCQkJCWF4ODg3OTZjX21kaW9f d3JpdGUobmRldiwKPiArCQkJCQlheF9sb2NhbC0+bWlpLnBoeV9pZCwgTUlJX0JNQ1IsCj4gKwkJ CQkJKEJNQ1JfU1BFRUQxMDAgfCBCTUNSX0FORU5BQkxFIHwKPiArCQkJCQlCTUNSX0FOUkVTVEFS VCkpOwo+ICsKPiArCQkJCWlmIChuZXRpZl9tc2dfaHcoYXhfbG9jYWwpKQo+ICsJCQkJCWF4ODg3 OTZjX2R1bXBfcGh5X3JlZ3MoYXhfbG9jYWwpOwo+ICsJCQkJYXhfbG9jYWwtPndfdGlja3MgPSAw Owo+ICsJCQl9Cj4gKwkJfQo+ICsJfSBlbHNlIHsKPiArCQlpZiAobmV0aWZfbXNnX3RpbWVyKGF4 X2xvY2FsKSkKPiArCQkJbmV0ZGV2X2luZm8obmRldiwgIkNoZWNrIGNhYmxlIHN0YXR1c1xuIik7 Cj4gKwo+ICsJCWF4X2xvY2FsLT53X3N0YXRlID0gY2hrX2NhYmxlOwo+ICsJfQo+ICsKPiArCWF4 ODg3OTZjX3NldF9wb3dlcl9zYXZpbmcoYXhfbG9jYWwsIGF4X2xvY2FsLT5wc19sZXZlbCk7Cj4g Kwo+ICsJaWYgKHRpbWVfdG9fY2hrKQo+ICsJCW1vZF90aW1lcigmYXhfbG9jYWwtPndhdGNoZG9n LCBqaWZmaWVzICsgdGltZV90b19jaGspOwo+ICt9Cj4gKwo+ICtzdGF0aWMgdm9pZCBheDg4Nzk2 Y193YXRjaGRvZ190aW1lcihzdHJ1Y3QgdGltZXJfbGlzdCAqdCkKPiArewo+ICsJc3RydWN0IGF4 ODg3OTZjX2RldmljZSAqYXhfbG9jYWwgPSBmcm9tX3RpbWVyKGF4X2xvY2FsLCB0LCB3YXRjaGRv Zyk7Cj4gKwkvL3N0cnVjdCBuZXRfZGV2aWNlICpuZGV2ID0gYXhfbG9jYWwtPm5kZXY7CgpDbGVh biB1cC4KCj4gKwo+ICsJc2V0X2JpdChFVkVOVF9XQVRDSERPRywgJmF4X2xvY2FsLT5mbGFncyk7 Cj4gKwlxdWV1ZV93b3JrKGF4X2xvY2FsLT5heF93b3JrX3F1ZXVlLCAmYXhfbG9jYWwtPmF4X3dv cmspOwo+ICt9Cj4gKwo+ICtzdGF0aWMgaW50IGF4ODg3OTZjX3NvZnRfcmVzZXQoc3RydWN0IGF4 ODg3OTZjX2RldmljZSAqYXhfbG9jYWwpCj4gK3sKPiArCXVuc2lnbmVkIGxvbmcgc3RhcnQ7Cj4g Kwl1MTYgdGVtcDsKPiArCj4gKwlBWF9XUklURSgmYXhfbG9jYWwtPmF4X3NwaSwgUFNSX1JFU0VU LCBQMF9QU1IpOwo+ICsJQVhfV1JJVEUoJmF4X2xvY2FsLT5heF9zcGksIFBTUl9SRVNFVF9DTFIs IFAwX1BTUik7Cj4gKwo+ICsJc3RhcnQgPSBqaWZmaWVzOwo+ICsJd2hpbGUgKCEoQVhfUkVBRCgm YXhfbG9jYWwtPmF4X3NwaSwgUDBfUFNSKSAmIFBTUl9ERVZfUkVBRFkpKSB7Cj4gKwkJaWYgKHRp bWVfYWZ0ZXIoamlmZmllcywgc3RhcnQgKyAoMTYwICogSFogLyAxMDAwKSkpIHsKPiArCQkJZGV2 X2VycigmYXhfbG9jYWwtPnNwaS0+ZGV2LAo+ICsJCQkJInRpbWVvdXQgd2FpdGluZyBmb3IgcmVz ZXQgY29tcGxldGlvblxuIik7Cj4gKwkJCXJldHVybiAtMTsKPiArCQl9Cj4gKwl9Cj4gKwo+ICsJ dGVtcCA9IEFYX1JFQUQoJmF4X2xvY2FsLT5heF9zcGksIFA0X1NQSUNSKTsKPiArCWlmIChheF9s b2NhbC0+Y2FwYWJpbGl0aWVzICYgQVhfQ0FQX0NPTVApIHsKPiArCQlBWF9XUklURSgmYXhfbG9j YWwtPmF4X3NwaSwKPiArCQkJKHRlbXAgfCBTUElDUl9SQ0VOIHwgU1BJQ1JfUUNFTiksIFA0X1NQ SUNSKTsKPiArCQlheF9sb2NhbC0+YXhfc3BpLmNvbXAgPSAxOwo+ICsJfSBlbHNlIHsKPiArCQlB WF9XUklURSgmYXhfbG9jYWwtPmF4X3NwaSwKPiArCQkJKHRlbXAgJiB+KFNQSUNSX1JDRU4gfCBT UElDUl9RQ0VOKSksIFA0X1NQSUNSKTsKPiArCQlheF9sb2NhbC0+YXhfc3BpLmNvbXAgPSAwOwo+ ICsJfQo+ICsKPiArCXJldHVybiAwOwo+ICt9Cj4gKwo+ICtzdGF0aWMgaW50IGF4ODg3OTZjX3Jl bG9hZF9lZXByb20oc3RydWN0IGF4ODg3OTZjX2RldmljZSAqYXhfbG9jYWwpCj4gK3sKPiArCXVu c2lnbmVkIGxvbmcgc3RhcnQ7Cj4gKwo+ICsJQVhfV1JJVEUoJmF4X2xvY2FsLT5heF9zcGksIEVF Q1JfUkVMT0FELCBQM19FRUNSKTsKPiArCj4gKwlzdGFydCA9IGppZmZpZXM7Cj4gKwl3aGlsZSAo IShBWF9SRUFEKCZheF9sb2NhbC0+YXhfc3BpLCBQMF9QU1IpICYgUFNSX0RFVl9SRUFEWSkpIHsK PiArCQlpZiAodGltZV9hZnRlcihqaWZmaWVzLCBzdGFydCArICgyICogSFogLyAxMDApKSkgewo+ ICsJCQlkZXZfZXJyKCZheF9sb2NhbC0+c3BpLT5kZXYsCj4gKwkJCQkidGltZW91dCB3YWl0aW5n IGZvciByZWxvYWQgZWVwcm9tXG4iKTsKPiArCQkJcmV0dXJuIC0xOwo+ICsJCX0KPiArCX0KPiAr Cj4gKwlyZXR1cm4gMDsKPiArfQo+ICsKPiArc3RhdGljIHZvaWQgYXg4ODc5NmNfc2V0X2h3X211 bHRpY2FzdChzdHJ1Y3QgbmV0X2RldmljZSAqbmRldikKPiArewo+ICsJc3RydWN0IGF4ODg3OTZj X2RldmljZSAqYXhfbG9jYWwgPSB0b19heDg4Nzk2Y19kZXZpY2UobmRldik7Cj4gKwl1MTYgcnhf Y3RsID0gUlhDUl9BQjsKPiArCWludCBtY19jb3VudCA9IG5ldGRldl9tY19jb3VudChuZGV2KTsK PiArCj4gKwltZW1zZXQoYXhfbG9jYWwtPm11bHRpX2ZpbHRlciwgMCwgQVhfTUNBU1RfRklMVEVS X1NJWkUpOwo+ICsKPiArCWlmIChuZGV2LT5mbGFncyAmIElGRl9QUk9NSVNDKSB7Cj4gKwkJcnhf Y3RsIHw9IFJYQ1JfUFJPOwo+ICsKPiArCX0gZWxzZSBpZiAobmRldi0+ZmxhZ3MgJiBJRkZfQUxM TVVMVEkKPiArCQkgICB8fCBtY19jb3VudCA+IEFYX01BWF9NQ0FTVCkgewo+ICsJCXJ4X2N0bCB8 PSBSWENSX0FNQUxMOwo+ICsKPiArCX0gZWxzZSBpZiAobWNfY291bnQgPT0gMCkgewo+ICsJCS8q IGp1c3QgYnJvYWRjYXN0IGFuZCBkaXJlY3RlZCAqLwo+ICsJfSBlbHNlIHsKPiArCQl1MzIgY3Jj X2JpdHM7Cj4gKwkJaW50IGk7Cj4gKwkJc3RydWN0IG5ldGRldl9od19hZGRyICpoYTsKPiArCQlu ZXRkZXZfZm9yX2VhY2hfbWNfYWRkcihoYSwgbmRldikgewo+ICsJCQljcmNfYml0cyA9IGV0aGVy X2NyYyhFVEhfQUxFTiwgaGEtPmFkZHIpOwo+ICsJCQlheF9sb2NhbC0+bXVsdGlfZmlsdGVyW2Ny Y19iaXRzID4+IDI5XSB8PQo+ICsJCQkJCQkoMSA8PCAoKGNyY19iaXRzID4+IDI2KSAmIDcpKTsK PiArCQl9Cj4gKwo+ICsJCWZvciAoaSA9IDA7IGkgPCA0OyBpKyspIHsKPiArCQkJQVhfV1JJVEUo JmF4X2xvY2FsLT5heF9zcGksCj4gKwkJCQkgICgoYXhfbG9jYWwtPm11bHRpX2ZpbHRlcltpKjIr MV0gPDwgOCkgfAo+ICsJCQkJICBheF9sb2NhbC0+bXVsdGlfZmlsdGVyW2kqMl0pLCBQM19NRkFS KGkpKTsKPiArCj4gKwkJfQo+ICsJfQo+ICsKPiArCUFYX1dSSVRFKCZheF9sb2NhbC0+YXhfc3Bp LCByeF9jdGwsIFAyX1JYQ1IpOwo+ICsKCk5vIG5lZWQgZm9yIGVtcHR5IGxpbmUuCgo+ICt9Cj4g Kwo+ICsjaWYgMAoKUGxlYXNlIGNvbW1lbnQgd2h5IGl0IGlzIGNvbW1lbnRlZCBvdXQuCgo+ICtz dGF0aWMgdm9pZCBheDg4Nzk2Y19zZXRfbXVsdGljYXN0KHN0cnVjdCBuZXRfZGV2aWNlICpuZGV2 KQo+ICt7Cj4gKwlzdHJ1Y3QgYXg4ODc5NmNfZGV2aWNlICpheF9sb2NhbCA9IHRvX2F4ODg3OTZj X2RldmljZShuZGV2KTsKPiArCj4gKwlzZXRfYml0KEVWRU5UX1NFVF9NVUxUSSwgJmF4X2xvY2Fs LT5mbGFncyk7Cj4gKwlxdWV1ZV93b3JrKGF4X2xvY2FsLT5heF93b3JrX3F1ZXVlLCAmYXhfbG9j YWwtPmF4X3dvcmspOwo+ICt9Cj4gKyNlbmRpZgo+ICsKPiArc3RhdGljIHZvaWQgYXg4ODc5NmNf c2V0X21hY19hZGRyKHN0cnVjdCBuZXRfZGV2aWNlICpuZGV2KQo+ICt7Cj4gKwlzdHJ1Y3QgYXg4 ODc5NmNfZGV2aWNlICpheF9sb2NhbCA9IHRvX2F4ODg3OTZjX2RldmljZShuZGV2KTsKPiArCj4g KwlBWF9XUklURSgmYXhfbG9jYWwtPmF4X3NwaSwgKCh1MTYpKG5kZXYtPmRldl9hZGRyWzRdIDw8 IDgpIHwKPiArCQkJKHUxNiluZGV2LT5kZXZfYWRkcls1XSksIFAzX01BQ0FTUjApOwo+ICsJQVhf V1JJVEUoJmF4X2xvY2FsLT5heF9zcGksICgodTE2KShuZGV2LT5kZXZfYWRkclsyXSA8PCA4KSB8 Cj4gKwkJCSh1MTYpbmRldi0+ZGV2X2FkZHJbM10pLCBQM19NQUNBU1IxKTsKPiArCUFYX1dSSVRF KCZheF9sb2NhbC0+YXhfc3BpLCAoKHUxNikobmRldi0+ZGV2X2FkZHJbMF0gPDwgOCkgfAo+ICsJ CQkodTE2KW5kZXYtPmRldl9hZGRyWzFdKSwgUDNfTUFDQVNSMik7Cj4gK30KPiArCj4gK3N0YXRp YyBpbnQgYXg4ODc5NmNfc2V0X21hY19hZGRyZXNzKHN0cnVjdCBuZXRfZGV2aWNlICpuZGV2LCB2 b2lkICpwKQo+ICt7Cj4gKwlzdHJ1Y3QgYXg4ODc5NmNfZGV2aWNlICpheF9sb2NhbCA9IHRvX2F4 ODg3OTZjX2RldmljZShuZGV2KTsKPiArCXN0cnVjdCBzb2NrYWRkciAqYWRkciA9IHA7Cj4gKwo+ ICsJaWYgKCFpc192YWxpZF9ldGhlcl9hZGRyKGFkZHItPnNhX2RhdGEpKQo+ICsJCXJldHVybiAt RUFERFJOT1RBVkFJTDsKPiArCj4gKwltZW1jcHkobmRldi0+ZGV2X2FkZHIsIGFkZHItPnNhX2Rh dGEsIG5kZXYtPmFkZHJfbGVuKTsKPiArCj4gKwlkb3duKCZheF9sb2NhbC0+c3BpX2xvY2spOwo+ ICsKPiArCWF4ODg3OTZjX3NldF9tYWNfYWRkcihuZGV2KTsKPiArCj4gKwl1cCgmYXhfbG9jYWwt PnNwaV9sb2NrKTsKPiArCj4gKwlyZXR1cm4gMDsKPiArfQo+ICsKPiArc3RhdGljIGludCBheDg4 Nzk2Y19sb2FkX21hY19hZGRyKHN0cnVjdCBuZXRfZGV2aWNlICpuZGV2KQo+ICt7Cj4gKwlzdHJ1 Y3QgYXg4ODc5NmNfZGV2aWNlICpheF9sb2NhbCA9IHRvX2F4ODg3OTZjX2RldmljZShuZGV2KTsK PiArCXUxNiB0ZW1wOwo+ICsKPiArCS8qIFJlYWQgdGhlIE1BQyBhZGRyZXNzIGZyb20gQVg4ODc5 NkMgKi8KPiArCXRlbXAgPSBBWF9SRUFEKCZheF9sb2NhbC0+YXhfc3BpLCBQM19NQUNBU1IwKTsK PiArCW5kZXYtPmRldl9hZGRyWzVdID0gKHU4KXRlbXA7Cj4gKwluZGV2LT5kZXZfYWRkcls0XSA9 ICh1OCkodGVtcCA+PiA4KTsKPiArCj4gKwl0ZW1wID0gQVhfUkVBRCgmYXhfbG9jYWwtPmF4X3Nw aSwgUDNfTUFDQVNSMSk7Cj4gKwluZGV2LT5kZXZfYWRkclszXSA9ICh1OCl0ZW1wOwo+ICsJbmRl di0+ZGV2X2FkZHJbMl0gPSAodTgpKHRlbXAgPj4gOCk7Cj4gKwo+ICsJdGVtcCA9IEFYX1JFQUQo JmF4X2xvY2FsLT5heF9zcGksIFAzX01BQ0FTUjIpOwo+ICsJbmRldi0+ZGV2X2FkZHJbMV0gPSAo dTgpdGVtcDsKPiArCW5kZXYtPmRldl9hZGRyWzBdID0gKHU4KSh0ZW1wID4+IDgpOwo+ICsKPiAr CS8qIFN1cHBvcnRlZCBmb3Igbm8gRUVQUk9NICovCj4gKwlpZiAoIWlzX3ZhbGlkX2V0aGVyX2Fk ZHIobmRldi0+ZGV2X2FkZHIpKSB7Cj4gKwkJaWYgKG1hY2FkZHIgJiYgbWFjX3B0b24obWFjYWRk ciwgbmRldi0+ZGV2X2FkZHIpKQo+ICsJCQlyZXR1cm4gMDsKPiArCj4gKwkJaWYgKG5ldGlmX21z Z19wcm9iZShheF9sb2NhbCkpCj4gKwkJCWRldl9pbmZvKCZheF9sb2NhbC0+c3BpLT5kZXYsICJV c2UgcmFuZG9tIE1BQyBhZGRyZXNzXG4iKTsKPiArCj4gKwkJcmFuZG9tX2V0aGVyX2FkZHIobmRl di0+ZGV2X2FkZHIpOwo+ICsJfQo+ICsKPiArCXJldHVybiAwOwo+ICt9Cj4gKwo+ICtzdGF0aWMg dm9pZCBheDg4Nzk2Y19wcm9jX3R4X2hkcihzdHJ1Y3QgdHhfcGt0X2luZm8gKmluZm8sIHU4IGlw X3N1bW1lZCkKPiArewo+ICsJdTE2IHBrdF9sZW5fYmFyID0gKH5pbmZvLT5wa3RfbGVuICYgVFhf SERSX1NPUF9QS1RMRU5CQVIpOwo+ICsKPiArCS8qIFByZXBhcmUgU09QIGhlYWRlciAqLwo+ICsJ aW5mby0+c29wLmZsYWdzX2xlbiA9IGluZm8tPnBrdF9sZW4gfAo+ICsJCQkoaXBfc3VtbWVkID09 IENIRUNLU1VNX05PTkUgPyBUWF9IRFJfU09QX0RJQ0YgOiAwKTsKPiArCj4gKwlpbmZvLT5zb3Au c2VxX2xlbmJhciA9ICgoaW5mby0+c2VxX251bSA8PCAxMSkgJiBUWF9IRFJfU09QX1NFUU5VTSkK PiArCQkJCXwgcGt0X2xlbl9iYXI7Cj4gKwljcHVfdG9fYmUxNnMoJmluZm8tPnNvcC5mbGFnc19s ZW4pOwo+ICsJY3B1X3RvX2JlMTZzKCZpbmZvLT5zb3Auc2VxX2xlbmJhcik7Cj4gKwo+ICsJLyog UHJlcGFyZSBTZWdtZW50IGhlYWRlciAqLwo+ICsJaW5mby0+c2VnLmZsYWdzX3NlcW51bV9zZWds ZW4gPSBUWF9IRFJfU0VHX0ZTIHwgVFhfSERSX1NFR19MUwo+ICsJCQkJCQl8IGluZm8tPnBrdF9s ZW47Cj4gKwo+ICsJaW5mby0+c2VnLmVvX3NvX3NlZ2xlbmJhciA9IHBrdF9sZW5fYmFyOwo+ICsK PiArCWNwdV90b19iZTE2cygmaW5mby0+c2VnLmZsYWdzX3NlcW51bV9zZWdsZW4pOwo+ICsJY3B1 X3RvX2JlMTZzKCZpbmZvLT5zZWcuZW9fc29fc2VnbGVuYmFyKTsKPiArCj4gKwkvKiBQcmVwYXJl IEVPUCBoZWFkZXIgKi8KPiArCWluZm8tPmVvcC5zZXFfbGVuID0gKChpbmZvLT5zZXFfbnVtIDw8 IDExKSAmCj4gKwkJCSAgICAgVFhfSERSX0VPUF9TRVFOVU0pIHwgaW5mby0+cGt0X2xlbjsKPiAr CWluZm8tPmVvcC5zZXFiYXJfbGVuYmFyID0gKCh+aW5mby0+c2VxX251bSA8PCAxMSkgJgo+ICsJ CQkJICAgVFhfSERSX0VPUF9TRVFOVU1CQVIpIHwgcGt0X2xlbl9iYXI7Cj4gKwo+ICsJY3B1X3Rv X2JlMTZzKCZpbmZvLT5lb3Auc2VxX2xlbik7Cj4gKwljcHVfdG9fYmUxNnMoJmluZm8tPmVvcC5z ZXFiYXJfbGVuYmFyKTsKPiArfQo+ICsKPiArc3RhdGljIGludAo+ICtheDg4Nzk2Y19jaGVja19m cmVlX3BhZ2VzKHN0cnVjdCBheDg4Nzk2Y19kZXZpY2UgKmF4X2xvY2FsLCB1OCBuZWVkX3BhZ2Vz KQo+ICt7Cj4gKwl1OCBmcmVlX3BhZ2VzOwo+ICsJdTE2IHRtcDsKPiArCj4gKwlmcmVlX3BhZ2Vz ID0gQVhfUkVBRCgmYXhfbG9jYWwtPmF4X3NwaSwgUDBfVEZCRkNSKSAmIFRYX0ZSRUVCVUZfTUFT SzsKPiArCWlmIChmcmVlX3BhZ2VzIDwgbmVlZF9wYWdlcykgewo+ICsJCS8qIHNjaGVkdWxlIGZy ZWUgcGFnZSBpbnRlcnJ1cHQgKi8KPiArCQl0bXAgPSBBWF9SRUFEKCZheF9sb2NhbC0+YXhfc3Bp LCBQMF9URkJGQ1IpCj4gKwkJCQkmIFRGQkZDUl9TQ0hFX0ZSRUVfUEFHRTsKPiArCQlBWF9XUklU RSgmYXhfbG9jYWwtPmF4X3NwaSwgdG1wIHwgVEZCRkNSX1RYX1BBR0VfU0VUIHwKPiArCQkJCVRG QkZDUl9TRVRfRlJFRV9QQUdFKG5lZWRfcGFnZXMpLAo+ICsJCQkJUDBfVEZCRkNSKTsKPiArCQly ZXR1cm4gLUVOT01FTTsKPiArCX0KPiArCj4gKwlyZXR1cm4gMDsKPiArfQo+ICsKPiArc3RhdGlj IHN0cnVjdCBza19idWZmICoKPiArYXg4ODc5NmNfdHhfZml4dXAoc3RydWN0IG5ldF9kZXZpY2Ug Km5kZXYsIHN0cnVjdCBza19idWZmX2hlYWQgKnEpCj4gK3sKPiArCXN0cnVjdCBheDg4Nzk2Y19k ZXZpY2UgKmF4X2xvY2FsID0gdG9fYXg4ODc5NmNfZGV2aWNlKG5kZXYpOwo+ICsJc3RydWN0IHNr X2J1ZmYgKnNrYiwgKnR4X3NrYjsKPiArCXN0cnVjdCB0eF9wa3RfaW5mbyAqaW5mbzsKPiArCXN0 cnVjdCBza2JfZGF0YSAqZW50cnk7Cj4gKwlpbnQgaGVhZHJvb207Cj4gKwlpbnQgdGFpbHJvb207 Cj4gKwl1OCBuZWVkX3BhZ2VzOwo+ICsJdTE2IHRvbF9sZW4sIHBrdF9sZW47Cj4gKwl1OCBwYWRs ZW4sIHNlcV9udW07Cj4gKwl1OCBzcGlfbGVuID0gYXhfbG9jYWwtPmF4X3NwaS5jb21wID8gMSA6 IDQ7Cj4gKwo+ICsJaWYgKHNrYl9xdWV1ZV9lbXB0eShxKSkKPiArCQlyZXR1cm4gTlVMTDsKPiAr Cj4gKwlza2IgPSBza2JfcGVlayhxKTsKPiArCXBrdF9sZW4gPSBza2ItPmxlbjsKPiArCW5lZWRf cGFnZXMgPSAocGt0X2xlbiArIFRYX09WRVJIRUFEICsgMTI3KSA+PiA3Owo+ICsJaWYgKGF4ODg3 OTZjX2NoZWNrX2ZyZWVfcGFnZXMoYXhfbG9jYWwsIG5lZWRfcGFnZXMpICE9IDApCj4gKwkJcmV0 dXJuIE5VTEw7Cj4gKwo+ICsJaGVhZHJvb20gPSBza2JfaGVhZHJvb20oc2tiKTsKPiArCXRhaWxy b29tID0gc2tiX3RhaWxyb29tKHNrYik7Cj4gKwlwYWRsZW4gPSAoKHBrdF9sZW4gKyAzKSAmIDB4 N0ZDKSAtIHBrdF9sZW47Cj4gKwl0b2xfbGVuID0gKChwa3RfbGVuICsgMykgJiAweDdGQykgKwo+ ICsJCQlUWF9PVkVSSEVBRCArIFRYX0VPUF9TSVpFICsgc3BpX2xlbjsKPiArCXNlcV9udW0gPSAr K2F4X2xvY2FsLT5zZXFfbnVtICYgMHgxRjsKPiArCj4gKwlpbmZvID0gKHN0cnVjdCB0eF9wa3Rf aW5mbyAqKSBza2ItPmNiOwo+ICsJaW5mby0+cGt0X2xlbiA9IHBrdF9sZW47Cj4gKwo+ICsJaWYg KCghc2tiX2Nsb25lZChza2IpKSAmJgo+ICsJICAgIChoZWFkcm9vbSA+PSAoVFhfT1ZFUkhFQUQg KyBzcGlfbGVuKSkgJiYKPiArCSAgICAodGFpbHJvb20gPj0gKHBhZGxlbiArIFRYX0VPUF9TSVpF KSkpIHsKPiArCj4gKwkJaW5mby0+c2VxX251bSA9IHNlcV9udW07Cj4gKwkJYXg4ODc5NmNfcHJv Y190eF9oZHIoaW5mbywgc2tiLT5pcF9zdW1tZWQpOwo+ICsKPiArCQkvKiBTT1AgYW5kIFNFRyBo ZWFkZXIgKi8KPiArCQltZW1jcHkoc2tiX3B1c2goc2tiLCBUWF9PVkVSSEVBRCksICZpbmZvLT5z b3AsIFRYX09WRVJIRUFEKTsKPiArCj4gKwkJLyogV3JpdGUgU1BJIFRYUSBoZWFkZXIgKi8KPiAr CQltZW1jcHkoc2tiX3B1c2goc2tiLCBzcGlfbGVuKSwgdHhfY21kX2J1Ziwgc3BpX2xlbik7Cj4g Kwo+ICsJCS8qIE1ha2UgMzItYml0IGFsaWdtZW50ICovCj4gKwkJc2tiX3B1dChza2IsIHBhZGxl bik7Cj4gKwo+ICsJCS8qIEVPUCBoZWFkZXIgKi8KPiArCQltZW1jcHkoc2tiX3B1dChza2IsIFRY X0VPUF9TSVpFKSwgJmluZm8tPmVvcCwgVFhfRU9QX1NJWkUpOwo+ICsKPiArCQl0eF9za2IgPSBz a2I7Cj4gKwkJc2tiX3VubGluayhza2IsIHEpOwo+ICsKPiArCX0gZWxzZSB7Cj4gKwo+ICsJCXR4 X3NrYiA9IGFsbG9jX3NrYih0b2xfbGVuLCBHRlBfS0VSTkVMKTsKPiArCQlpZiAoIXR4X3NrYikK PiArCQkJcmV0dXJuIE5VTEw7Cj4gKwo+ICsJCS8qIFdyaXRlIFNQSSBUWFEgaGVhZGVyICovCj4g KwkJbWVtY3B5KHNrYl9wdXQodHhfc2tiLCBzcGlfbGVuKSwgdHhfY21kX2J1Ziwgc3BpX2xlbik7 Cj4gKwo+ICsJCWluZm8tPnNlcV9udW0gPSBzZXFfbnVtOwo+ICsJCWF4ODg3OTZjX3Byb2NfdHhf aGRyKGluZm8sIHNrYi0+aXBfc3VtbWVkKTsKPiArCj4gKwkJLyogU09QIGFuZCBTRUcgaGVhZGVy ICovCj4gKwkJbWVtY3B5KHNrYl9wdXQodHhfc2tiLCBUWF9PVkVSSEVBRCksCj4gKwkJCQkmaW5m by0+c29wLCBUWF9PVkVSSEVBRCk7Cj4gKwo+ICsJCS8qIFBhY2tldCAqLwo+ICsJCW1lbWNweShz a2JfcHV0KHR4X3NrYiwgKChwa3RfbGVuICsgMykgJiAweEZGRkMpKSwKPiArCQkJCXNrYi0+ZGF0 YSwgcGt0X2xlbik7Cj4gKwo+ICsJCS8qIEVPUCBoZWFkZXIgKi8KPiArCQltZW1jcHkoc2tiX3B1 dCh0eF9za2IsIFRYX0VPUF9TSVpFKSwKPiArCQkJCSZpbmZvLT5lb3AsIFRYX0VPUF9TSVpFKTsK PiArCj4gKwkJc2tiX3VubGluayhza2IsIHEpOwo+ICsJCWRldl9rZnJlZV9za2Ioc2tiKTsKPiAr CX0KPiArCj4gKwllbnRyeSA9IChzdHJ1Y3Qgc2tiX2RhdGEgKikgdHhfc2tiLT5jYjsKPiArCW1l bXNldChlbnRyeSwgMCwgc2l6ZW9mKCplbnRyeSkpOwo+ICsJZW50cnktPmxlbiA9IHBrdF9sZW47 Cj4gKwo+ICsJaWYgKG5ldGlmX21zZ19wa3RkYXRhKGF4X2xvY2FsKSkgewo+ICsJCWludCBsb29w Owo+ICsJCW5ldGRldl9pbmZvKG5kZXYsICJUWCBwYWNrZXQgbGVuICVkLCB0b3RhbCBsZW4gJWQs IHNlcSAlZFxuIiwKPiArCQkJCXBrdF9sZW4sIHR4X3NrYi0+bGVuLCBzZXFfbnVtKTsKPiArCj4g KwkJbmV0ZGV2X2luZm8obmRldiwgIiAgRHVtcCBTUEkgSGVhZGVyOlxuICAgICIpOwo+ICsJCWZv ciAobG9vcCA9IDA7IGxvb3AgPCA0OyBsb29wKyspCj4gKwkJCW5ldGRldl9pbmZvKG5kZXYsICIl MDJ4ICIsICoodHhfc2tiLT5kYXRhICsgbG9vcCkpOwo+ICsKPiArCQluZXRkZXZfaW5mbyhuZGV2 LCAiXG4iKTsKPiArCj4gKwkJbmV0ZGV2X2luZm8obmRldiwgIiAgRHVtcCBUWCBTT1A6XG4gICAg Iik7Cj4gKwkJZm9yIChsb29wID0gMDsgbG9vcCA8IFRYX09WRVJIRUFEOyBsb29wKyspCj4gKwkJ CW5ldGRldl9pbmZvKG5kZXYsICIlMDJ4ICIsICoodHhfc2tiLT5kYXRhICsgNCArIGxvb3ApKTsK PiArCj4gKwkJbmV0ZGV2X2luZm8obmRldiwgIlxuIik7Cj4gKwo+ICsJCW5ldGRldl9pbmZvKG5k ZXYsICIgIER1bXAgVFggcGFja2V0OiIpOwo+ICsJCWZvciAobG9vcCA9IFRYX09WRVJIRUFEICsg NDsKPiArCQkgICAgIGxvb3AgPCAodHhfc2tiLT5sZW4gLSBUWF9FT1BfU0laRSk7IGxvb3ArKykg ewo+ICsJCQlpZiAoKChsb29wICsgOCkgJSAxNikgPT0gMCkKPiArCQkJCW5ldGRldl9pbmZvKG5k ZXYsICJcbiAgICAiKTsKPiArCQkJbmV0ZGV2X2luZm8obmRldiwgIiUwMnggIiwgKih0eF9za2It PmRhdGEgKyBsb29wKSk7Cj4gKwkJfQo+ICsJCW5ldGRldl9pbmZvKG5kZXYsICJcbiIpOwo+ICsK PiArCQluZXRkZXZfaW5mbyhuZGV2LCAiICBEdW1wIFRYIEVPUDpcbiAgICAlMDJ4ICUwMnggJTAy eCAlMDJ4XG4iLAo+ICsJCQkqKHR4X3NrYi0+ZGF0YSArIHR4X3NrYi0+bGVuIC0gNCksCj4gKwkJ CSoodHhfc2tiLT5kYXRhICsgdHhfc2tiLT5sZW4gLSAzKSwKPiArCQkJKih0eF9za2ItPmRhdGEg KyB0eF9za2ItPmxlbiAtIDIpLAo+ICsJCQkqKHR4X3NrYi0+ZGF0YSArIHR4X3NrYi0+bGVuIC0g MSkpOwo+ICsJfQo+ICsKPiArCXJldHVybiB0eF9za2I7Cj4gK30KPiArCj4gK3N0YXRpYyBpbnQg YXg4ODc5NmNfaGFyZF94bWl0KHN0cnVjdCBheDg4Nzk2Y19kZXZpY2UgKmF4X2xvY2FsKQo+ICt7 Cj4gKwlzdHJ1Y3Qgc2tfYnVmZiAqdHhfc2tiOwo+ICsJc3RydWN0IHNrYl9kYXRhICplbnRyeTsK PiArCj4gKwl0eF9za2IgPSBheDg4Nzk2Y190eF9maXh1cChheF9sb2NhbC0+bmRldiwgJmF4X2xv Y2FsLT50eF93YWl0X3EpOwo+ICsKPiArCWlmICghdHhfc2tiKQo+ICsJCXJldHVybiAwOwo+ICsK PiArCWVudHJ5ID0gKHN0cnVjdCBza2JfZGF0YSAqKXR4X3NrYi0+Y2I7Cj4gKwo+ICsJQVhfV1JJ VEUoJmF4X2xvY2FsLT5heF9zcGksCj4gKwkJCShUU05SX1RYQl9TVEFSVCB8IFRTTlJfUEtUX0NO VCgxKSksIFAwX1RTTlIpOwo+ICsKPiArCWF4c3BpX3dyaXRlX3R4cSgmYXhfbG9jYWwtPmF4X3Nw aSwgdHhfc2tiLT5kYXRhLCB0eF9za2ItPmxlbik7Cj4gKwo+ICsJaWYgKCgoQVhfUkVBRCgmYXhf bG9jYWwtPmF4X3NwaSwgUDBfVFNOUikgJiBUWE5SX1RYQl9JRExFKSA9PSAwKSB8fAo+ICsJICAg ICgoSVNSX1RYRVJSICYgQVhfUkVBRCgmYXhfbG9jYWwtPmF4X3NwaSwgUDBfSVNSKSkgIT0gMCkp IHsKPiArCj4gKwkJLyogQWNrIHR4IGVycm9yIGludCAqLwo+ICsJCUFYX1dSSVRFKCZheF9sb2Nh bC0+YXhfc3BpLCBJU1JfVFhFUlIsIFAwX0lTUik7Cj4gKwo+ICsJCWF4X2xvY2FsLT5zdGF0cy50 eF9kcm9wcGVkKys7Cj4gKwo+ICsJCWlmIChuZXRpZl9tc2dfdHhfZXJyKGF4X2xvY2FsKSkKPiAr CQkJbmV0ZGV2X2VycihheF9sb2NhbC0+bmRldiwKPiArCQkJCSJUWCBGSUZPIGVycm9yLCByZS1p bml0aWFsaXplIHRoZSBUWCBicmlkZ2VcbiIpOwo+ICsKPiArCQkvKiBSZWluaXRpYWwgdHggYnJp ZGdlICovCj4gKwkJQVhfV1JJVEUoJmF4X2xvY2FsLT5heF9zcGksIFRYTlJfVFhCX1JFSU5JVCB8 Cj4gKwkJCUFYX1JFQUQoJmF4X2xvY2FsLT5heF9zcGksIFAwX1RTTlIpLCBQMF9UU05SKTsKPiAr CQlheF9sb2NhbC0+c2VxX251bSA9IDA7Cj4gKwl9IGVsc2Ugewo+ICsJCWF4X2xvY2FsLT5zdGF0 cy50eF9wYWNrZXRzKys7Cj4gKwkJYXhfbG9jYWwtPnN0YXRzLnR4X2J5dGVzICs9IGVudHJ5LT5s ZW47Cj4gKwl9Cj4gKwo+ICsJZW50cnktPnN0YXRlID0gdHhfZG9uZTsKPiArCWRldl9rZnJlZV9z a2IodHhfc2tiKTsKPiArCj4gKwlyZXR1cm4gMTsKPiArfQo+ICsKPiArc3RhdGljIGludAo+ICth eDg4Nzk2Y19zdGFydF94bWl0KHN0cnVjdCBza19idWZmICpza2IsIHN0cnVjdCBuZXRfZGV2aWNl ICpuZGV2KQo+ICt7Cj4gKwlzdHJ1Y3QgYXg4ODc5NmNfZGV2aWNlICpheF9sb2NhbCA9IHRvX2F4 ODg3OTZjX2RldmljZShuZGV2KTsKPiArCj4gKwlza2JfcXVldWVfdGFpbCgmYXhfbG9jYWwtPnR4 X3dhaXRfcSwgc2tiKTsKPiArCWlmIChza2JfcXVldWVfbGVuKCZheF9sb2NhbC0+dHhfd2FpdF9x KSA+IFRYX1FVRVVFX0hJR0hfV0FURVIpIHsKPiArCQlpZiAobmV0aWZfbXNnX3R4X3F1ZXVlZChh eF9sb2NhbCkpCj4gKwkJCW5ldGRldl9lcnIobmRldiwgIlRvbyBtdWNoIFRYIHBhY2tldHMgaW4g cXVldWUgJWRcbiIsCj4gKwkJCQkJc2tiX3F1ZXVlX2xlbigmYXhfbG9jYWwtPnR4X3dhaXRfcSkp Owo+ICsKPiArCQluZXRpZl9zdG9wX3F1ZXVlKG5kZXYpOwo+ICsJfQo+ICsKPiArCXNldF9iaXQo RVZFTlRfVFgsICZheF9sb2NhbC0+ZmxhZ3MpOwo+ICsJcXVldWVfd29yayhheF9sb2NhbC0+YXhf d29ya19xdWV1ZSwgJmF4X2xvY2FsLT5heF93b3JrKTsKPiArCj4gKwlyZXR1cm4gTkVUREVWX1RY X09LOwo+ICsKPiArfQo+ICsKPiArCj4gK3N0YXRpYyBpbmxpbmUgdm9pZAo+ICtheDg4Nzk2Y19z a2JfcmV0dXJuKHN0cnVjdCBheDg4Nzk2Y19kZXZpY2UgKmF4X2xvY2FsLCBzdHJ1Y3Qgc2tfYnVm ZiAqc2tiLAo+ICsJCQlzdHJ1Y3QgcnhfaGVhZGVyICpyeGhkcikKPiArewo+ICsJc3RydWN0IG5l dF9kZXZpY2UgKm5kZXYgPSBheF9sb2NhbC0+bmRldjsKPiArCWludCBzdGF0dXM7Cj4gKwo+ICsJ ZG8gewo+ICsJCWlmICghKGF4X2xvY2FsLT5jaGVja3N1bSAmIEFYX1JYX0NIRUNLU1VNKSkKPiAr CQkJYnJlYWs7Cj4gKwo+ICsJCS8qIGNoZWNrc3VtIGVycm9yIGJpdCBpcyBzZXQgKi8KPiArCQlp ZiAoKHJ4aGRyLT5mbGFncyAmIFJYX0hEUjNfTDNfRVJSKSB8fAo+ICsJCSAgICAocnhoZHItPmZs YWdzICYgUlhfSERSM19MNF9FUlIpKQo+ICsJCQlicmVhazsKPiArCj4gKwkJaWYgKChyeGhkci0+ ZmxhZ3MgJiBSWF9IRFIzX0w0X1RZUEVfVENQKSB8fAo+ICsJCSAgICAocnhoZHItPmZsYWdzICYg UlhfSERSM19MNF9UWVBFX1VEUCkpIHsKPiArCQkJc2tiLT5pcF9zdW1tZWQgPSBDSEVDS1NVTV9V Tk5FQ0VTU0FSWTsKPiArCQl9Cj4gKwl9IHdoaWxlICgwKTsKPiArCj4gKwlheF9sb2NhbC0+c3Rh dHMucnhfcGFja2V0cysrOwo+ICsJYXhfbG9jYWwtPnN0YXRzLnJ4X2J5dGVzICs9IHNrYi0+bGVu Owo+ICsJc2tiLT5kZXYgPSBuZGV2Owo+ICsKPiArCXNrYi0+dHJ1ZXNpemUgPSBza2ItPmxlbiAr IHNpemVvZihzdHJ1Y3Qgc2tfYnVmZik7Cj4gKwlza2ItPnByb3RvY29sID0gZXRoX3R5cGVfdHJh bnMoc2tiLCBheF9sb2NhbC0+bmRldik7Cj4gKwo+ICsJaWYgKG5ldGlmX21zZ19yeF9zdGF0dXMo YXhfbG9jYWwpKQo+ICsJCW5ldGRldl9pbmZvKG5kZXYsICI8IHJ4LCBsZW4gJXp1LCB0eXBlIDB4 JXhcbiIsCj4gKwkJCXNrYi0+bGVuICsgc2l6ZW9mKHN0cnVjdCBldGhoZHIpLCBza2ItPnByb3Rv Y29sKTsKPiArCj4gKwlzdGF0dXMgPSBuZXRpZl9yeChza2IpOwo+ICsJaWYgKHN0YXR1cyAhPSBO RVRfUlhfU1VDQ0VTUyAmJiBuZXRpZl9tc2dfcnhfZXJyKGF4X2xvY2FsKSkKPiArCQluZXRkZXZf aW5mbyhuZGV2LCAibmV0aWZfcnggc3RhdHVzICVkXG4iLCBzdGF0dXMpOwo+ICt9Cj4gKwo+ICtz dGF0aWMgdm9pZCBkdW1wX3BhY2tldChzdHJ1Y3QgbmV0X2RldmljZSAqbmRldiwgY29uc3QgY2hh ciAqbXNnLCBpbnQgbGVuLCBjb25zdCBjaGFyICpkYXRhKQo+ICt7CgpUb28gbG9uZyBsaW5lcy4K Cj4gKyAgICAgICAgbmV0ZGV2X3ByaW50ayhLRVJOX0RFQlVHLCBuZGV2LCAgRFJWX05BTUUgIjog JXMgLSBwYWNrZXQgbGVuOiVkXG4iLCBtc2csIGxlbik7Cj4gKyAgICAgICAgcHJpbnRfaGV4X2R1 bXAoS0VSTl9ERUJVRywgIiIsIERVTVBfUFJFRklYX09GRlNFVCwgMTYsIDEsCj4gKyAgICAgICAg ICAgICAgICAgICAgICAgIGRhdGEsIGxlbiwgdHJ1ZSk7Cj4gK30KPiArCj4gK3N0YXRpYyB2b2lk Cj4gK2F4ODg3OTZjX3J4X2ZpeHVwKHN0cnVjdCBheDg4Nzk2Y19kZXZpY2UgKmF4X2xvY2FsLCBz dHJ1Y3Qgc2tfYnVmZiAqcnhfc2tiKQo+ICt7Cj4gKwlzdHJ1Y3QgcnhfaGVhZGVyICpyeGhkciA9 IChzdHJ1Y3QgcnhfaGVhZGVyICopIHJ4X3NrYi0+ZGF0YTsKPiArCXN0cnVjdCBuZXRfZGV2aWNl ICpuZGV2ID0gYXhfbG9jYWwtPm5kZXY7Cj4gKwl1MTYgbGVuOwo+ICsKPiArCWJlMTZfdG9fY3B1 cygmcnhoZHItPmZsYWdzX2xlbik7Cj4gKwliZTE2X3RvX2NwdXMoJnJ4aGRyLT5zZXFfbGVuYmFy KTsKPiArCWJlMTZfdG9fY3B1cygmcnhoZHItPmZsYWdzKTsKPiArCj4gKwlpZiAoKCgoc2hvcnQp cnhoZHItPmZsYWdzX2xlbikgJiBSWF9IRFIxX1BLVF9MRU4pICE9Cj4gKwkJCSAofigoc2hvcnQp cnhoZHItPnNlcV9sZW5iYXIpICYgMHg3RkYpKSB7Cj4gKwkJaWYgKG5ldGlmX21zZ19yeF9lcnIo YXhfbG9jYWwpKSB7Cj4gKwkJCWludCBpOwo+ICsJCQluZXRkZXZfZXJyKG5kZXYsICJIZWFkZXIg ZXJyb3JcbiIpOwo+ICsJCQkvL25ldGRldl9lcnIobmRldiwgIkR1bXAgcmVjZWl2ZWQgZnJhbWVc biIpOwo+ICsJCQkvKiBmb3IgKGkgPSAwOyBpIDwgcnhfc2tiLT5sZW47IGkrKykgeyAqLwo+ICsJ CQkvKiAJbmV0ZGV2X2VycihuZGV2LCAiJTAyeCAiLCAqLwo+ICsJCQkvKiAJCQkqKHJ4X3NrYi0+ ZGF0YSArIGkpKTsgKi8KPiArCQkJLyogCWlmICgoKGkgKyAxKSAlIDE2KSA9PSAwKSAqLwo+ICsJ CQkvKiAJCW5ldGRldl9lcnIobmRldiwgIlxuIik7ICovCj4gKwkJCS8qIH0gKi8KPiArCQkJZHVt cF9wYWNrZXQobmRldiwgX19mdW5jX18sIHJ4X3NrYi0+bGVuLCByeF9za2ItPmRhdGEpOwo+ICsJ CX0KPiArCQlheF9sb2NhbC0+c3RhdHMucnhfZnJhbWVfZXJyb3JzKys7Cj4gKwkJa2ZyZWVfc2ti KHJ4X3NrYik7Cj4gKwkJcmV0dXJuOwo+ICsJfQo+ICsKPiArCWlmICgocnhoZHItPmZsYWdzX2xl biAmIFJYX0hEUjFfTUlJX0VSUikgfHwKPiArCQkJKHJ4aGRyLT5mbGFnc19sZW4gJiBSWF9IRFIx X0NSQ19FUlIpKSB7Cj4gKwkJaWYgKG5ldGlmX21zZ19yeF9lcnIoYXhfbG9jYWwpKQo+ICsJCQlu ZXRkZXZfZXJyKG5kZXYsICJDUkMgb3IgTUlJIGVycm9yXG4iKTsKPiArCj4gKwkJYXhfbG9jYWwt PnN0YXRzLnJ4X2NyY19lcnJvcnMrKzsKPiArCQlrZnJlZV9za2Iocnhfc2tiKTsKPiArCQlyZXR1 cm47Cj4gKwl9Cj4gKwo+ICsJbGVuID0gcnhoZHItPmZsYWdzX2xlbiAmIFJYX0hEUjFfUEtUX0xF TjsKPiArCWlmIChuZXRpZl9tc2dfcGt0ZGF0YShheF9sb2NhbCkpIHsKPiArCQlpbnQgbG9vcDsK PiArCQluZXRkZXZfaW5mbyhuZGV2LCAiUlggZGF0YSwgdG90YWwgbGVuICVkLCBwYWNrZXQgbGVu ICVkXG4iLAo+ICsJCQkJcnhfc2tiLT5sZW4sIGxlbik7Cj4gKwo+ICsJCW5ldGRldl9pbmZvKG5k ZXYsICIgIER1bXAgUlggcGFja2V0IGhlYWRlcjpcbiAgICAiKTsKPiArCQlmb3IgKGxvb3AgPSAw OyBsb29wIDwgc2l6ZW9mKCpyeGhkcik7IGxvb3ArKykKPiArCQkJbmV0ZGV2X2luZm8obmRldiwg IiUwMnggIiwgKihyeF9za2ItPmRhdGEgKyBsb29wKSk7Cj4gKwo+ICsJCW5ldGRldl9pbmZvKG5k ZXYsICJcbiAgRHVtcCBSWCBwYWNrZXQ6Iik7Cj4gKwkJZm9yIChsb29wID0gMDsgbG9vcCA8IGxl bjsgbG9vcCsrKSB7Cj4gKwkJCWlmICgobG9vcCAlIDE2KSA9PSAwKQo+ICsJCQkJbmV0ZGV2X2lu Zm8obmRldiwgIlxuICAgICIpOwo+ICsJCQluZXRkZXZfaW5mbyhuZGV2LCAiJTAyeCAiLAo+ICsJ CQkJKihyeF9za2ItPmRhdGEgKyBsb29wICsgc2l6ZW9mKCpyeGhkcikpKTsKPiArCQl9Cj4gKwkJ bmV0ZGV2X2luZm8obmRldiwgIlxuIik7Cj4gKwl9Cj4gKwo+ICsJc2tiX3B1bGwocnhfc2tiLCBz aXplb2YoKnJ4aGRyKSk7Cj4gKwlfX3Bza2JfdHJpbShyeF9za2IsIGxlbik7Cj4gKwo+ICsJcmV0 dXJuIGF4ODg3OTZjX3NrYl9yZXR1cm4oYXhfbG9jYWwsIHJ4X3NrYiwgcnhoZHIpOwo+ICt9Cj4g Kwo+ICtzdGF0aWMgaW50IGF4ODg3OTZjX3JlY2VpdmUoc3RydWN0IG5ldF9kZXZpY2UgKm5kZXYp Cj4gK3sKPiArCXN0cnVjdCBheDg4Nzk2Y19kZXZpY2UgKmF4X2xvY2FsID0gdG9fYXg4ODc5NmNf ZGV2aWNlKG5kZXYpOwo+ICsJc3RydWN0IHNrX2J1ZmYgKnNrYjsKPiArCXN0cnVjdCBza2JfZGF0 YSAqZW50cnk7Cj4gKwl1MTYgd19jb3VudCwgcGt0X2xlbjsKPiArCXU4IHBrdF9jbnQ7Cj4gKwo+ ICsJLyogY2hlY2sgcnggcGFja2V0IGFuZCB0b3RhbCB3b3JkIGNvdW50ICovCj4gKwlBWF9XUklU RSgmYXhfbG9jYWwtPmF4X3NwaSwgQVhfUkVBRCgmYXhfbG9jYWwtPmF4X3NwaSwgUDBfUlRXQ1Ip Cj4gKwkJICB8IFJUV0NSX1JYX0xBVENILCBQMF9SVFdDUik7Cj4gKwo+ICsJcGt0X2NudCA9IEFY X1JFQUQoJmF4X2xvY2FsLT5heF9zcGksIFAwX1JYQkNSMikgJiBSWEJDUjJfUEtUX01BU0s7Cj4g KwlpZiAoIXBrdF9jbnQpCj4gKwkJcmV0dXJuIDA7Cj4gKwo+ICsJcGt0X2xlbiA9IEFYX1JFQUQo JmF4X2xvY2FsLT5heF9zcGksIFAwX1JDUEhSKSAmIDB4N0ZGOwo+ICsKPiArCXdfY291bnQgPSAo KHBrdF9sZW4gKyA2ICsgMykgJiAweEZGRkMpID4+IDE7Cj4gKwo+ICsJc2tiID0gYWxsb2Nfc2ti KCh3X2NvdW50ICogMiksIEdGUF9LRVJORUwpOwo+ICsJaWYgKCFza2IpIHsKPiArCQlpZiAobmV0 aWZfbXNnX3J4X2VycihheF9sb2NhbCkpCj4gKwkJCW5ldGRldl9lcnIobmRldiwKPiArCQkJCSJD b3VsZG4ndCBhbGxvY2F0ZSBhIHNrX2J1ZmYgb2Ygc2l6ZSAlZFxuIiwKPiArCQkJCXdfY291bnQg KiAyKTsKPiArCj4gKwkJQVhfV1JJVEUoJmF4X2xvY2FsLT5heF9zcGksIFJYQkNSMV9SWEJfRElT Q0FSRCwgUDBfUlhCQ1IxKTsKPiArCQlyZXR1cm4gMDsKPiArCX0KPiArCWVudHJ5ID0gKHN0cnVj dCBza2JfZGF0YSAqKSBza2ItPmNiOwo+ICsKPiArCUFYX1dSSVRFKCZheF9sb2NhbC0+YXhfc3Bp LCBSWEJDUjFfUlhCX1NUQVJUIHwgd19jb3VudCwgUDBfUlhCQ1IxKTsKPiArCj4gKwlheHNwaV9y ZWFkX3J4cSgmYXhfbG9jYWwtPmF4X3NwaSwKPiArCQkJc2tiX3B1dChza2IsIHdfY291bnQgKiAy KSwgc2tiLT5sZW4pOwo+ICsKPiArCS8qIENoZWNrIGlmIHJ4IGJyaWRnZSBpcyBpZGxlICovCj4g KwlpZiAoKEFYX1JFQUQoJmF4X2xvY2FsLT5heF9zcGksIFAwX1JYQkNSMikgJiBSWEJDUjJfUlhC X0lETEUpID09IDApIHsKPiArCj4gKwkJaWYgKG5ldGlmX21zZ19yeF9lcnIoYXhfbG9jYWwpKQo+ ICsJCQluZXRkZXZfZXJyKG5kZXYsICJSeCBCcmlkZ2UgaXMgbm90IGlkbGVcbiIpOwo+ICsJCUFY X1dSSVRFKCZheF9sb2NhbC0+YXhfc3BpLCBSWEJDUjJfUlhCX1JFSU5JVCwgUDBfUlhCQ1IyKTsK PiArCj4gKwkJZW50cnktPnN0YXRlID0gcnhfZXJyOwo+ICsKPiArCX0gZWxzZSB7Cj4gKwo+ICsJ CWVudHJ5LT5zdGF0ZSA9IHJ4X2RvbmU7Cj4gKwl9Cj4gKwo+ICsJQVhfV1JJVEUoJmF4X2xvY2Fs LT5heF9zcGksIElTUl9SWFBLVCwgUDBfSVNSKTsKPiArCj4gKwlheDg4Nzk2Y19yeF9maXh1cChh eF9sb2NhbCwgc2tiKTsKPiArCj4gKwlyZXR1cm4gMTsKPiArfQo+ICsKPiArc3RhdGljIHZvaWQg YXg4ODc5NmNfY2hlY2tfbWVkaWEoc3RydWN0IGF4ODg3OTZjX2RldmljZSAqYXhfbG9jYWwpCj4g K3sKPiArCXN0cnVjdCBuZXRfZGV2aWNlICpuZGV2ID0gYXhfbG9jYWwtPm5kZXY7Cj4gKwl1MTYg Ym1zciwgYm1jcjsKPiArCj4gKwlpZiAobmV0aWZfbXNnX2h3KGF4X2xvY2FsKSkKPiArCQlheDg4 Nzk2Y19kdW1wX3BoeV9yZWdzKGF4X2xvY2FsKTsKPiArCj4gKwlibXNyID0gYXg4ODc5NmNfbWRp b19yZWFkKG5kZXYsCj4gKwkJCWF4X2xvY2FsLT5taWkucGh5X2lkLCBNSUlfQk1TUik7Cj4gKwo+ ICsJaWYgKCEoYm1zciAmIEJNU1JfTFNUQVRVUykgJiYgbmV0aWZfY2Fycmllcl9vayhuZGV2KSkg ewo+ICsKPiArCQluZXRpZl9jYXJyaWVyX29mZihuZGV2KTsKPiArCQlpZiAobmV0aWZfbXNnX2xp bmsoYXhfbG9jYWwpKQo+ICsJCQluZXRkZXZfaW5mbyhuZGV2LCAibGluayBkb3duXG4iKTsKPiAr Cj4gKwkJYXhfbG9jYWwtPndfc3RhdGUgPSBjaGtfY2FibGU7Cj4gKwkJbW9kX3RpbWVyKCZheF9s b2NhbC0+d2F0Y2hkb2csCj4gKwkJCQlqaWZmaWVzICsgQVg4ODc5NkNfV0FUQ0hET0dfUEVSSU9E KTsKPiArCj4gKwl9IGVsc2UgaWYgKChibXNyICYgQk1TUl9MU1RBVFVTKSAmJgo+ICsJCSAgIW5l dGlmX2NhcnJpZXJfb2sobmRldikpIHsKPiArCQlibWNyID0gYXg4ODc5NmNfbWRpb19yZWFkKG5k ZXYsCj4gKwkJCQlheF9sb2NhbC0+bWlpLnBoeV9pZCwgTUlJX0JNQ1IpOwo+ICsJCWlmIChuZXRp Zl9tc2dfbGluayhheF9sb2NhbCkpCj4gKwkJCW5ldGRldl9pbmZvKG5kZXYsICJsaW5rIHVwLCAl c01icHMsICVzLWR1cGxleFxuIiwKPiArCQkJCShibWNyICYgQk1DUl9TUEVFRDEwMCkgPyAiMTAw IiA6ICIxMCIsCj4gKwkJCQkoYm1jciAmIEJNQ1JfRlVMTERQTFgpID8gImZ1bGwiIDogImhhbGYi KTsKPiArCj4gKwkJbmV0aWZfY2Fycmllcl9vbihuZGV2KTsKPiArCX0KPiArCj4gKwlyZXR1cm47 Cj4gK30KPiArCj4gK3N0YXRpYyBpbnQgYXg4ODc5NmNfcHJvY2Vzc19pc3Ioc3RydWN0IGF4ODg3 OTZjX2RldmljZSAqYXhfbG9jYWwpCj4gK3sKPiArCXUxNiBpc3I7Cj4gKwl1OCBkb25lID0gMDsK PiArCXN0cnVjdCBuZXRfZGV2aWNlICpuZGV2ID0gYXhfbG9jYWwtPm5kZXY7Cj4gKwo+ICsJaXNy ID0gQVhfUkVBRCgmYXhfbG9jYWwtPmF4X3NwaSwgUDBfSVNSKTsKPiArCUFYX1dSSVRFKCZheF9s b2NhbC0+YXhfc3BpLCBpc3IsIFAwX0lTUik7Cj4gKwo+ICsJaWYgKG5ldGlmX21zZ19pbnRyKGF4 X2xvY2FsKSkKPiArCQluZXRkZXZfaW5mbyhuZGV2LCAiICBJU1IgMHglMDR4XG4iLCBpc3IpOwo+ ICsKPiArCWlmIChpc3IgJiBJU1JfVFhFUlIpIHsKPiArCQlpZiAobmV0aWZfbXNnX2ludHIoYXhf bG9jYWwpKQo+ICsJCQluZXRkZXZfaW5mbyhuZGV2LCAiICBUWEVSUiBpbnRlcnJ1cHRcbiIpOwo+ ICsJCUFYX1dSSVRFKCZheF9sb2NhbC0+YXhfc3BpLCBUWE5SX1RYQl9SRUlOSVQsIFAwX1RTTlIp Owo+ICsJCWF4X2xvY2FsLT5zZXFfbnVtID0gMHgxZjsKPiArCX0KPiArCj4gKwlpZiAoaXNyICYg SVNSX1RYUEFHRVMpIHsKPiArCj4gKwkJaWYgKG5ldGlmX21zZ19pbnRyKGF4X2xvY2FsKSkKPiAr CQkJbmV0ZGV2X2luZm8obmRldiwgIiAgVFhQQUdFUyBpbnRlcnJ1cHRcbiIpOwo+ICsKPiArCQlz ZXRfYml0KEVWRU5UX1RYLCAmYXhfbG9jYWwtPmZsYWdzKTsKPiArCX0KPiArCj4gKwlpZiAoaXNy ICYgSVNSX0xJTkspIHsKPiArCj4gKwkJaWYgKG5ldGlmX21zZ19pbnRyKGF4X2xvY2FsKSkKPiAr CQkJbmV0ZGV2X2luZm8obmRldiwgIiAgTGluayBjaGFuZ2UgaW50ZXJydXB0XG4iKTsKPiArCj4g KwkJYXg4ODc5NmNfY2hlY2tfbWVkaWEoYXhfbG9jYWwpOwo+ICsJfQo+ICsKPiArCWlmIChpc3Ig JiBJU1JfUlhQS1QpIHsKPiArCj4gKwkJaWYgKG5ldGlmX21zZ19pbnRyKGF4X2xvY2FsKSkKPiAr CQkJbmV0ZGV2X2luZm8obmRldiwgIiAgUlggaW50ZXJydXB0XG4iKTsKPiArCj4gKwkJZG9uZSA9 IGF4ODg3OTZjX3JlY2VpdmUoYXhfbG9jYWwtPm5kZXYpOwo+ICsJfQo+ICsKPiArCXJldHVybiBk b25lOwo+ICt9Cj4gKwo+ICtzdGF0aWMgaXJxcmV0dXJuX3QgYXg4ODc5NmNfaW50ZXJydXB0KGlu dCBpcnEsIHZvaWQgKmRldl9pbnN0YW5jZSkKPiArewo+ICsJc3RydWN0IG5ldF9kZXZpY2UgKm5k ZXYgPSBkZXZfaW5zdGFuY2U7Cj4gKwlzdHJ1Y3QgYXg4ODc5NmNfZGV2aWNlICpheF9sb2NhbCA9 IHRvX2F4ODg3OTZjX2RldmljZShuZGV2KTsKPiArCj4gKwlpZiAobmRldiA9PSBOVUxMKSB7Cj4g KwkJcHJfZXJyKCJpcnEgJWQgZm9yIHVua25vd24gZGV2aWNlLlxuIiwgaXJxKTsKPiArCQlyZXR1 cm4gSVJRX1JFVFZBTCgwKTsKPiArCX0KPiArCj4gKwlkaXNhYmxlX2lycV9ub3N5bmMoaXJxKTsK PiArCj4gKwlpZiAobmV0aWZfbXNnX2ludHIoYXhfbG9jYWwpKQo+ICsJCW5ldGRldl9pbmZvKG5k ZXYsICJJbnRlcnJ1cHQgb2NjdXJyZWRcbiIpOwo+ICsKPiArCXNldF9iaXQoRVZFTlRfSU5UUiwg JmF4X2xvY2FsLT5mbGFncyk7Cj4gKwlxdWV1ZV93b3JrKGF4X2xvY2FsLT5heF93b3JrX3F1ZXVl LCAmYXhfbG9jYWwtPmF4X3dvcmspOwo+ICsKPiArCXJldHVybiBJUlFfSEFORExFRDsKPiArfQo+ ICsKPiArCgpPbmx5IG9uZSBsaW5lCgo+ICtzdGF0aWMgdm9pZCBheDg4Nzk2Y193b3JrKHN0cnVj dCB3b3JrX3N0cnVjdCAqd29yaykKPiArewo+ICsJc3RydWN0IGF4ODg3OTZjX2RldmljZSAqYXhf bG9jYWwgPQo+ICsJCQljb250YWluZXJfb2Yod29yaywgc3RydWN0IGF4ODg3OTZjX2RldmljZSwg YXhfd29yayk7Cj4gKwl1OCBwb3dlciA9IDA7Cj4gKwo+ICsJZG93bigmYXhfbG9jYWwtPnNwaV9s b2NrKTsKPiArCj4gKwlpZiAodGVzdF9iaXQoRVZFTlRfV0FUQ0hET0csICZheF9sb2NhbC0+Zmxh Z3MpKSB7Cj4gKwo+ICsJCWF4ODg3OTZjX3dhdGNoZG9nKGF4X2xvY2FsKTsKPiArCj4gKwkJY2xl YXJfYml0KEVWRU5UX1dBVENIRE9HLCAmYXhfbG9jYWwtPmZsYWdzKTsKPiArCX0KPiArCj4gKwlp ZiAodGVzdF9iaXQoRVZFTlRfU0VUX01VTFRJLCAmYXhfbG9jYWwtPmZsYWdzKSkgewo+ICsKPiAr CQlwb3dlciA9IGF4ODg3OTZjX2NoZWNrX3Bvd2VyX2FuZF93YWtlKGF4X2xvY2FsKTsKPiArCj4g KwkJYXg4ODc5NmNfc2V0X2h3X211bHRpY2FzdChheF9sb2NhbC0+bmRldik7Cj4gKwkJY2xlYXJf Yml0KEVWRU5UX1NFVF9NVUxUSSwgJmF4X2xvY2FsLT5mbGFncyk7Cj4gKwl9Cj4gKwo+ICsJaWYg KHRlc3RfYml0KEVWRU5UX0lOVFIsICZheF9sb2NhbC0+ZmxhZ3MpKSB7Cj4gKwo+ICsJCXBvd2Vy ID0gYXg4ODc5NmNfY2hlY2tfcG93ZXJfYW5kX3dha2UoYXhfbG9jYWwpOwo+ICsKPiArCQlBWF9X UklURSgmYXhfbG9jYWwtPmF4X3NwaSwgSU1SX01BU0tBTEwsIFAwX0lNUik7Cj4gKwo+ICsJCXdo aWxlICgxKSB7Cj4gKwkJCWlmICghYXg4ODc5NmNfcHJvY2Vzc19pc3IoYXhfbG9jYWwpKQo+ICsJ CQkJYnJlYWs7Cj4gKwkJfQo+ICsKPiArCQljbGVhcl9iaXQoRVZFTlRfSU5UUiwgJmF4X2xvY2Fs LT5mbGFncyk7Cj4gKwo+ICsJCUFYX1dSSVRFKCZheF9sb2NhbC0+YXhfc3BpLCBJTVJfREVGQVVM VCwgUDBfSU1SKTsKPiArCj4gKwkJZW5hYmxlX2lycShheF9sb2NhbC0+bmRldi0+aXJxKTsKPiAr CX0KPiArCj4gKwlpZiAodGVzdF9iaXQoRVZFTlRfVFgsICZheF9sb2NhbC0+ZmxhZ3MpKSB7Cj4g Kwo+ICsJCXBvd2VyID0gYXg4ODc5NmNfY2hlY2tfcG93ZXJfYW5kX3dha2UoYXhfbG9jYWwpOwo+ ICsKPiArCQl3aGlsZSAoc2tiX3F1ZXVlX2xlbigmYXhfbG9jYWwtPnR4X3dhaXRfcSkpIHsKPiAr CQkJaWYgKCFheDg4Nzk2Y19oYXJkX3htaXQoYXhfbG9jYWwpKQo+ICsJCQkJYnJlYWs7Cj4gKwkJ fQo+ICsKPiArCQljbGVhcl9iaXQoRVZFTlRfVFgsICZheF9sb2NhbC0+ZmxhZ3MpOwo+ICsKPiAr CQlpZiAobmV0aWZfcXVldWVfc3RvcHBlZChheF9sb2NhbC0+bmRldikgJiYKPiArCQkgICAgKHNr Yl9xdWV1ZV9sZW4oJmF4X2xvY2FsLT50eF93YWl0X3EpIDwgVFhfUVVFVUVfTE9XX1dBVEVSKSkK PiArCQkJbmV0aWZfd2FrZV9xdWV1ZShheF9sb2NhbC0+bmRldik7Cj4gKwl9Cj4gKwo+ICsJaWYg KHBvd2VyKQo+ICsJCWF4ODg3OTZjX3NldF9wb3dlcl9zYXZpbmcoYXhfbG9jYWwsIGF4X2xvY2Fs LT5wc19sZXZlbCk7Cj4gKwo+ICsJdXAoJmF4X2xvY2FsLT5zcGlfbG9jayk7Cj4gK30KPiArCj4g K3N0YXRpYyBzdHJ1Y3QgbmV0X2RldmljZV9zdGF0cyAqYXg4ODc5NmNfZ2V0X3N0YXRzKHN0cnVj dCBuZXRfZGV2aWNlICpuZGV2KQo+ICt7Cj4gKwlzdHJ1Y3QgYXg4ODc5NmNfZGV2aWNlICpheF9s b2NhbCA9IHRvX2F4ODg3OTZjX2RldmljZShuZGV2KTsKPiArCXJldHVybiAmYXhfbG9jYWwtPnN0 YXRzOwo+ICt9Cj4gKwo+ICt2b2lkIGF4ODg3OTZjX3BoeV9pbml0KHN0cnVjdCBheDg4Nzk2Y19k ZXZpY2UgKmF4X2xvY2FsKQo+ICt7Cj4gKwl1MTYgYWR2ZXJ0aXNlID0gQURWRVJUSVNFX0FMTCB8 IEFEVkVSVElTRV9DU01BIHwgQURWRVJUSVNFX1BBVVNFX0NBUDsKPiArCj4gKwkvKiBTZXR1cCBM RUQgbW9kZSAqLwo+ICsJQVhfV1JJVEUoJmF4X2xvY2FsLT5heF9zcGksCj4gKwkJICAoTENSX0xF RDBfRU4gfCBMQ1JfTEVEMF9EVVBMRVggfCBMQ1JfTEVEMV9FTiB8Cj4gKwkJICAgTENSX0xFRDFf MTAwTU9ERSksIFAyX0xDUjApOwo+ICsJQVhfV1JJVEUoJmF4X2xvY2FsLT5heF9zcGksCj4gKwkJ ICAoQVhfUkVBRCgmYXhfbG9jYWwtPmF4X3NwaSwgUDJfTENSMSkgJiBMQ1JfTEVEMl9NQVNLKSB8 Cj4gKwkJICAgTENSX0xFRDJfRU4gfCBMQ1JfTEVEMl9MSU5LLCBQMl9MQ1IxKTsKPiArCj4gKwkv KiBFbmFibGUgUEhZIGF1dG8tcG9sbGluZyAqLwo+ICsJQVhfV1JJVEUoJmF4X2xvY2FsLT5heF9z cGksCj4gKwkJICBQT09MQ1JfUEhZSUQoYXhfbG9jYWwtPm1paS5waHlfaWQpIHwgUE9PTENSX1BP TExfRU4gfAo+ICsJCSAgUE9PTENSX1BPTExfRkxPV0NUUkwgfCBQT09MQ1JfUE9MTF9CTUNSLCBQ Ml9QT09MQ1IpOwo+ICsKPiArCWF4ODg3OTZjX21kaW9fd3JpdGUoYXhfbG9jYWwtPm5kZXYsCj4g KwkJCWF4X2xvY2FsLT5taWkucGh5X2lkLCBNSUlfQURWRVJUSVNFLCBhZHZlcnRpc2UpOwo+ICsK PiArCWF4ODg3OTZjX21kaW9fd3JpdGUoYXhfbG9jYWwtPm5kZXYsIGF4X2xvY2FsLT5taWkucGh5 X2lkLCBNSUlfQk1DUiwKPiArCQkJQk1DUl9TUEVFRDEwMCB8IEJNQ1JfQU5FTkFCTEUgfCBCTUNS X0FOUkVTVEFSVCk7Cj4gK30KPiArCj4gK3N0YXRpYyBpbnQKPiArYXg4ODc5NmNfb3BlbihzdHJ1 Y3QgbmV0X2RldmljZSAqbmRldikKPiArewo+ICsJc3RydWN0IGF4ODg3OTZjX2RldmljZSAqYXhf bG9jYWwgPSB0b19heDg4Nzk2Y19kZXZpY2UobmRldik7Cj4gKwlpbnQgcmV0Owo+ICsJdTggcG93 ZXI7Cj4gKwl1bnNpZ25lZCBsb25nIGlycV9mbGFnID0gSVJRRl9TSEFSRUQ7Cj4gKwo+ICsJbmV0 aWZfY2Fycmllcl9vZmYoYXhfbG9jYWwtPm5kZXYpOwo+ICsKPiArCWRvd24oJmF4X2xvY2FsLT5z cGlfbG9jayk7Cj4gKwo+ICsJcG93ZXIgPSBheDg4Nzk2Y19jaGVja19wb3dlcl9hbmRfd2FrZShh eF9sb2NhbCk7Cj4gKwo+ICsJcmV0ID0gYXg4ODc5NmNfc29mdF9yZXNldChheF9sb2NhbCk7Cj4g KwlpZiAocmV0IDwgMCkgewo+ICsJCXJldHVybiAtRU5PREVWOwo+ICsJfQo+ICsKPiArCXJldCA9 IHJlcXVlc3RfaXJxKG5kZXYtPmlycSwgYXg4ODc5NmNfaW50ZXJydXB0LAo+ICsJCQlpcnFfZmxh ZywgbmRldi0+bmFtZSwgbmRldik7Cj4gKwlpZiAocmV0KSB7Cj4gKwkJbmV0ZGV2X2VycihuZGV2 LCAidW5hYmxlIHRvIGdldCBJUlEgJWQgKGVycm5vPSVkKS5cbiIsCj4gKwkJCQluZGV2LT5pcnEs IHJldCk7Cj4gKwkJcmV0dXJuIC1FTlhJTzsKPiArCX0KPiArCj4gKwlheF9sb2NhbC0+c2VxX251 bSA9IDB4MWY7Cj4gKwo+ICsJYXg4ODc5NmNfc2V0X21hY19hZGRyKG5kZXYpOwo+ICsJYXg4ODc5 NmNfc2V0X2NzdW1zKGF4X2xvY2FsKTsKPiArCj4gKwkvKiBEaXNhYmxlIHN0dWZmaW5nIHBhY2tl dCAqLwo+ICsJQVhfV1JJVEUoJmF4X2xvY2FsLT5heF9zcGksCj4gKwkJICBBWF9SRUFEKCZheF9s b2NhbC0+YXhfc3BpLCBQMV9SWEJTUENSKQo+ICsJCSAgJiB+UlhCU1BDUl9TVFVGX0VOQUJMRSwg UDFfUlhCU1BDUik7Cj4gKwo+ICsJLyogRW5hYmxlIFJYIHBhY2tldCBwcm9jZXNzICovCj4gKwlB WF9XUklURSgmYXhfbG9jYWwtPmF4X3NwaSwgUlBQRVJfUlhFTiwgUDFfUlBQRVIpOwo+ICsKPiAr CUFYX1dSSVRFKCZheF9sb2NhbC0+YXhfc3BpLCBBWF9SRUFEKCZheF9sb2NhbC0+YXhfc3BpLCBQ MF9GRVIpCj4gKwkJICB8IEZFUl9SWEVOIHwgRkVSX1RYRU4gfCBGRVJfQlNXQVAgfCBGRVJfSVJR X1BVTEwsIFAwX0ZFUik7Cj4gKwo+ICsJYXg4ODc5NmNfcGh5X2luaXQoYXhfbG9jYWwpOwo+ICsK PiArCW5ldGlmX3N0YXJ0X3F1ZXVlKG5kZXYpOwo+ICsKPiArCUFYX1dSSVRFKCZheF9sb2NhbC0+ YXhfc3BpLCBJTVJfREVGQVVMVCwgUDBfSU1SKTsKPiArCj4gKwlpZiAobmV0aWZfbXNnX2h3KGF4 X2xvY2FsKSkgewo+ICsJCW5ldGRldl9pbmZvKG5kZXYsCj4gKwkJCSJEdW1wIGFsbCBNQUMgcmVn aXN0ZXJzIGFmdGVyIGluaXRpYWxpemF0aW9uOlxuIik7Cj4gKwkJYXg4ODc5NmNfZHVtcF9yZWdz KGF4X2xvY2FsKTsKPiArCQlheDg4Nzk2Y19kdW1wX3BoeV9yZWdzKGF4X2xvY2FsKTsKPiArCX0K PiArCj4gKwlpZiAocG93ZXIpCj4gKwkJYXg4ODc5NmNfc2V0X3Bvd2VyX3NhdmluZyhheF9sb2Nh bCwgYXhfbG9jYWwtPnBzX2xldmVsKTsKPiArCj4gKwlzcGlfbWVzc2FnZV9pbml0KCZheF9sb2Nh bC0+YXhfc3BpLnJ4X21zZyk7Cj4gKwo+ICsJdXAoJmF4X2xvY2FsLT5zcGlfbG9jayk7Cj4gKwo+ ICsJdGltZXJfc2V0dXAoJmF4X2xvY2FsLT53YXRjaGRvZywgYXg4ODc5NmNfd2F0Y2hkb2dfdGlt ZXIsIDApOwo+ICsJLyogaW5pdF90aW1lcigmYXhfbG9jYWwtPndhdGNoZG9nKTsgKi8KPiArCS8q IGF4X2xvY2FsLT53YXRjaGRvZy5mdW5jdGlvbiA9ICZheDg4Nzk2Y193YXRjaGRvZ190aW1lcjsg Ki8KPiArCS8qIGF4X2xvY2FsLT53YXRjaGRvZy5kYXRhID0gKHVuc2lnbmVkIGxvbmcpIG5kZXY7 ICovCgpJIGd1ZXNzIGl0J3MgYSBkZXZlbG9wbWVudCBjb2RlLgoKPiArCWF4X2xvY2FsLT53YXRj aGRvZy5leHBpcmVzID0gamlmZmllcyArIEFYODg3OTZDX1dBVENIRE9HX1BFUklPRDsKPiArCWF4 X2xvY2FsLT53X3N0YXRlID0gY2hrX2NhYmxlOwo+ICsJYXhfbG9jYWwtPndfdGlja3MgPSAwOwo+ ICsKPiArCWFkZF90aW1lcigmYXhfbG9jYWwtPndhdGNoZG9nKTsKPiArCj4gKwlyZXR1cm4gMDsK PiArfQo+ICsKPiArc3RhdGljIHZvaWQgYXg4ODc5NmNfZnJlZV9za2JfcXVldWUoc3RydWN0IHNr X2J1ZmZfaGVhZCAqcSkKPiArewo+ICsJc3RydWN0IHNrX2J1ZmYgKnNrYjsKPiArCj4gKwl3aGls ZSAocS0+cWxlbikgewo+ICsJCXNrYiA9IHNrYl9kZXF1ZXVlKHEpOwo+ICsJCWtmcmVlX3NrYihz a2IpOwo+ICsJfQo+ICt9Cj4gKwo+ICtzdGF0aWMgaW50Cj4gK2F4ODg3OTZjX2Nsb3NlKHN0cnVj dCBuZXRfZGV2aWNlICpuZGV2KQo+ICt7Cj4gKwlzdHJ1Y3QgYXg4ODc5NmNfZGV2aWNlICpheF9s b2NhbCA9IHRvX2F4ODg3OTZjX2RldmljZShuZGV2KTsKPiArCXU4IHBvd2VyOwo+ICsKPiArCW5l dGlmX3N0b3BfcXVldWUobmRldik7Cj4gKwo+ICsJZGVsX3RpbWVyX3N5bmMoJmF4X2xvY2FsLT53 YXRjaGRvZyk7Cj4gKwo+ICsJZnJlZV9pcnEobmRldi0+aXJxLCBuZGV2KTsKPiArCj4gKwlkb3du KCZheF9sb2NhbC0+c3BpX2xvY2spOwo+ICsKPiArCXBvd2VyID0gYXg4ODc5NmNfY2hlY2tfcG93 ZXJfYW5kX3dha2UoYXhfbG9jYWwpOwo+ICsKPiArCUFYX1dSSVRFKCZheF9sb2NhbC0+YXhfc3Bp LCBJTVJfTUFTS0FMTCwgUDBfSU1SKTsKPiArCWF4ODg3OTZjX2ZyZWVfc2tiX3F1ZXVlKCZheF9s b2NhbC0+dHhfd2FpdF9xKTsKPiArCj4gKwlheDg4Nzk2Y19zb2Z0X3Jlc2V0KGF4X2xvY2FsKTsK PiArCj4gKwlpZiAocG93ZXIpCj4gKwkJYXg4ODc5NmNfc2V0X3Bvd2VyX3NhdmluZyhheF9sb2Nh bCwgYXhfbG9jYWwtPnBzX2xldmVsKTsKPiArCj4gKwl1cCgmYXhfbG9jYWwtPnNwaV9sb2NrKTsK PiArCj4gKwlyZXR1cm4gMDsKPiArfQo+ICsKPiArc3RhdGljIGNvbnN0IHN0cnVjdCBuZXRfZGV2 aWNlX29wcyBheDg4Nzk2Y19uZXRkZXZfb3BzID0gewo+ICsJLm5kb19vcGVuCQk9IGF4ODg3OTZj X29wZW4sCj4gKwkubmRvX3N0b3AJCT0gYXg4ODc5NmNfY2xvc2UsCj4gKwkubmRvX3N0YXJ0X3ht aXQJCT0gYXg4ODc5NmNfc3RhcnRfeG1pdCwKPiArCS5uZG9fZ2V0X3N0YXRzCQk9IGF4ODg3OTZj X2dldF9zdGF0cywKPiArCS8qIC5uZG9fc2V0X211bHRpY2FzdF9saXN0ID0gYXg4ODc5NmNfc2V0 X211bHRpY2FzdCwgKi8KClN0aWxsIG5lZWQgYSBjb21tZW50LgoKPiArCS5uZG9fZG9faW9jdGwJ CT0gYXg4ODc5NmNfaW9jdGwsCj4gKwkubmRvX3NldF9tYWNfYWRkcmVzcwk9IGF4ODg3OTZjX3Nl dF9tYWNfYWRkcmVzcywKPiArfTsKPiArCj4gKwo+ICtzdGF0aWMgaW50IGF4ODg3OTZjX2hhcmRf cmVzZXQoc3RydWN0IGF4ODg3OTZjX2RldmljZSAqYXhfbG9jYWwpCj4gK3sKPiArCXN0cnVjdCBk ZXZpY2UgKmRldiA9IChzdHJ1Y3QgZGV2aWNlKikmYXhfbG9jYWwtPnNwaS0+ZGV2Owo+ICsJc3Ry dWN0IGdwaW9fZGVzYyAqcmVzZXRfZ3BpbzsKPiArCj4gKwkvKiByZXNldCBpbmZvICovCj4gKwly ZXNldF9ncGlvID0gZ3Bpb2RfZ2V0KGRldiwgInJlc2V0IiwgMCk7Cj4gKwlpZiAoSVNfRVJSKHJl c2V0X2dwaW8pKSB7Cj4gKwkJZGV2X2VycihkZXYsICJDb3VsZCBub3QgZ2V0ICdyZXNldCcgR1BJ TzogJWxkIiwgUFRSX0VSUihyZXNldF9ncGlvKSk7Cj4gKwkJcmV0dXJuIFBUUl9FUlIocmVzZXRf Z3Bpbyk7Cj4gKwl9Cj4gKwo+ICsJLyogc2V0IHJlc2V0ICovCj4gKwlncGlvZF9kaXJlY3Rpb25f b3V0cHV0KHJlc2V0X2dwaW8sIDEpOwo+ICsJbXNsZWVwKDEwMCk7Cj4gKwlncGlvZF9kaXJlY3Rp b25fb3V0cHV0KHJlc2V0X2dwaW8sIDApOwo+ICsJZ3Bpb2RfcHV0KHJlc2V0X2dwaW8pOwo+ICsJ bXNsZWVwKDEwKTsKPiArCj4gKwlyZXR1cm4gMDsKPiArfQo+ICsKPiArc3RhdGljIGludCBheDg4 Nzk2Y19wcm9iZShzdHJ1Y3Qgc3BpX2RldmljZSAqc3BpKQo+ICt7Cj4gKwlzdHJ1Y3QgbmV0X2Rl dmljZSAqbmRldjsKPiArCXN0cnVjdCBheDg4Nzk2Y19kZXZpY2UgKmF4X2xvY2FsOwo+ICsJaW50 IHJldDsKPiArCXUxNiB0ZW1wOwo+ICsKPiArCW5kZXYgPSBkZXZtX2FsbG9jX2V0aGVyZGV2KCZz cGktPmRldiwgc2l6ZW9mKCpheF9sb2NhbCkpOwo+ICsJaWYgKCFuZGV2KSB7Cj4gKwkJZGV2X2Vy cigmc3BpLT5kZXYsICJBWDg4Nzk2QyBTUEk6IENvdWxkIG5vdCBhbGxvY2F0ZSBldGhlcm5ldCBk ZXZpY2VcbiIpOwo+ICsJCXJldHVybiAtRU5PTUVNOwo+ICsJfQo+ICsKPiArCWF4X2xvY2FsID0g dG9fYXg4ODc5NmNfZGV2aWNlKG5kZXYpOwo+ICsJbWVtc2V0KGF4X2xvY2FsLCAwLCBzaXplb2Yo KmF4X2xvY2FsKSk7Cj4gKwo+ICsJZGV2X3NldF9kcnZkYXRhKCZzcGktPmRldiwgYXhfbG9jYWwp Owo+ICsJYXhfbG9jYWwtPnNwaSA9IHNwaTsKPiArCWF4X2xvY2FsLT5heF9zcGkuc3BpID0gc3Bp Owo+ICsKPiArCW5kZXYtPmlycSA9IHNwaS0+aXJxOwo+ICsKPiArCWF4X2xvY2FsLT5tc2dfZW5h YmxlID0gIG1zZ19lbmFibGU7CgpPbmUgc3BhY2UgYWZ0ZXIgJz0nLgoKPiArCWlmIChwc19sZXZl bCA+IEFYX1BTX0QyIHx8IHBzX2xldmVsIDwgMCkKPiArCQlheF9sb2NhbC0+cHNfbGV2ZWwgPSAw Owo+ICsJZWxzZQo+ICsJCWF4X2xvY2FsLT5wc19sZXZlbCA9IHBzX2xldmVsOwo+ICsKPiArCWF4 X2xvY2FsLT5jYXBhYmlsaXRpZXMgfD0gY29tcCA/IEFYX0NBUF9DT01QIDogMDsKPiArCj4gKwlp ZiAobmV0aWZfbXNnX3Byb2JlKGF4X2xvY2FsKSkgewo+ICsJCWRldl9pbmZvKCZzcGktPmRldiwg IkFYODg3OTZDLVNQSSBDb25maWd1cmF0aW9uOlxuIik7Cj4gKwkJZGV2X2luZm8oJnNwaS0+ZGV2 LCAiICAgIENvbXByZXNzaW9uIDogJXNcbiIsCj4gKwkJCSBheF9sb2NhbC0+Y2FwYWJpbGl0aWVz ICYgQVhfQ0FQX0NPTVAgPyAiT04iIDogIk9GRiIpOwo+ICsJCWRldl9pbmZvKCZzcGktPmRldiwg IiAgICBQb3dlciBTYXZpbmcgTGV2ZWw6ICVkXG4iLAo+ICsJCQkgYXhfbG9jYWwtPnBzX2xldmVs KTsKPiArCX0KPiArCj4gKwluZGV2LT5uZXRkZXZfb3BzCT0gJmF4ODg3OTZjX25ldGRldl9vcHM7 Cj4gKwluZGV2LT5ldGh0b29sX29wcwk9ICZheDg4Nzk2Y19ldGh0b29sX29wczsKCk5vIHNwYWNl cyBiZWZvcmUgJz0nLgoKPiArCj4gKwlheF9sb2NhbC0+bmRldiA9IG5kZXY7CgpTZXQgYWxsIHBy aXYtc3RvcmluZy1wb2ludGVycyBpbiBvbmUgcGxhY2UsIHNvIG5leHQgdG8gZGV2X3NldF9kcnZk YXRhKCkKdW5sZXNzIGl0IGlzIGNob3NlbiBieSBwcm9iZSgpIGZsb3cgb24gcHVycG9zZS4KCj4g Kwo+ICsJLyogSW5pdGlhbGl6ZSBNSUkgc3RydWN0dXJlICovCj4gKwlheF9sb2NhbC0+bWlpLmRl diA9IG5kZXY7Cj4gKwlheF9sb2NhbC0+bWlpLm1kaW9fcmVhZCA9IGF4ODg3OTZjX21kaW9fcmVh ZDsKPiArCWF4X2xvY2FsLT5taWkubWRpb193cml0ZSA9IGF4ODg3OTZjX21kaW9fd3JpdGU7Cj4g KwlheF9sb2NhbC0+bWlpLnBoeV9pZF9tYXNrID0gMHgzZjsKPiArCWF4X2xvY2FsLT5taWkucmVn X251bV9tYXNrID0gMHgxZjsKPiArCWF4X2xvY2FsLT5taWkucGh5X2lkID0gMHgxMDsKPiArCj4g KwkvKiBheDg4Nzk2YyBncGlvIHJlc2V0ICovCj4gKwlheDg4Nzk2Y19oYXJkX3Jlc2V0KGF4X2xv Y2FsKTsKPiArCj4gKwkvKiBSZXNldCBBWDg4Nzk2QyAqLwo+ICsJcmV0ID0gYXg4ODc5NmNfc29m dF9yZXNldChheF9sb2NhbCk7Cj4gKwlpZiAocmV0IDwgMCkgewo+ICsJCXJldHVybiAtRU5PREVW Owo+ICsJfQoKTm8gbmVlZCBmb3Ige30uCgo+ICsKPiArCS8qIENoZWNrIGJvYXJkIHJldmlzaW9u ICovCj4gKwl0ZW1wID0gQVhfUkVBRCgmYXhfbG9jYWwtPmF4X3NwaSwgUDJfQ1JJUik7Cj4gKwlp ZiAoKHRlbXAgJiAweEYpICE9IDB4MCkgewo+ICsJCWRldl9lcnIoJnNwaS0+ZGV2LCAic3BpIHJl YWQgZmFpbGVkOiAlZFxuIiwgdGVtcCk7Cj4gKwkJcmV0dXJuIC1FTk9ERVY7Cj4gKwl9Cj4gKwo+ ICsJdGVtcCA9IEFYX1JFQUQoJmF4X2xvY2FsLT5heF9zcGksIFAwX0JPUik7Cj4gKwlpZiAodGVt cCA9PSAweDEyMzQpIHsKPiArCQlheF9sb2NhbC0+cGxhdF9lbmRpYW4gPSBQTEFUX0xJVFRMRV9F TkRJQU47Cj4gKwl9IGVsc2Ugewo+ICsJCUFYX1dSSVRFKCZheF9sb2NhbC0+YXhfc3BpLCAweEZG RkYsIFAwX0JPUik7Cj4gKwkJYXhfbG9jYWwtPnBsYXRfZW5kaWFuID0gUExBVF9CSUdfRU5ESUFO Owo+ICsJfQo+ICsKPiArCWlmIChuZXRpZl9tc2dfaHcoYXhfbG9jYWwpKSB7Cj4gKwkJZGV2X2lu Zm8oJnNwaS0+ZGV2LAo+ICsJCQkgIkR1bXAgYWxsIE1BQyByZWdpc3RlcnMgYmVmb3JlIGluaXRp YWxpemF0aW9uOlxuIik7Cj4gKwkJYXg4ODc5NmNfZHVtcF9yZWdzKGF4X2xvY2FsKTsKPiArCQlh eDg4Nzk2Y19kdW1wX3BoeV9yZWdzKGF4X2xvY2FsKTsKPiArCX0KPiArCj4gKwkvKlJlbG9hZCBF RVBST00qLwo+ICsJYXg4ODc5NmNfcmVsb2FkX2VlcHJvbShheF9sb2NhbCk7Cj4gKwo+ICsJYXg4 ODc5NmNfbG9hZF9tYWNfYWRkcihuZGV2KTsKPiArCj4gKwlpZiAobmV0aWZfbXNnX3Byb2JlKGF4 X2xvY2FsKSkKPiArCQlkZXZfaW5mbygmc3BpLT5kZXYsCj4gKwkJCSAiaXJxICVkLCBNQUMgYWRk ciAiCj4gKwkJCSAiJTAyWDolMDJYOiUwMlg6JTAyWDolMDJYOiUwMlhcbiIsCj4gKwkJCSBuZGV2 LT5pcnEsCj4gKwkJCSBuZGV2LT5kZXZfYWRkclswXSwgbmRldi0+ZGV2X2FkZHJbMV0sCj4gKwkJ CSBuZGV2LT5kZXZfYWRkclsyXSwgbmRldi0+ZGV2X2FkZHJbM10sCj4gKwkJCSBuZGV2LT5kZXZf YWRkcls0XSwgbmRldi0+ZGV2X2FkZHJbNV0pOwo+ICsKPiArCWF4ODg3OTZjX3NldF9wb3dlcl9z YXZpbmcoYXhfbG9jYWwsIGF4X2xvY2FsLT5wc19sZXZlbCk7Cj4gKwo+ICsJSU5JVF9XT1JLKCZh eF9sb2NhbC0+YXhfd29yaywgYXg4ODc5NmNfd29yayk7Cj4gKwo+ICsJYXhfbG9jYWwtPmF4X3dv cmtfcXVldWUgPQo+ICsJCQljcmVhdGVfc2luZ2xldGhyZWFkX3dvcmtxdWV1ZSgiYXg4ODc5NmNf d29yayIpOwo+ICsKPiArCXNlbWFfaW5pdCgmYXhfbG9jYWwtPnNwaV9sb2NrLCAxKTsKPiArCj4g Kwlza2JfcXVldWVfaGVhZF9pbml0KCZheF9sb2NhbC0+dHhfd2FpdF9xKTsKPiArCj4gKwluZGV2 LT5mZWF0dXJlcyB8PSBORVRJRl9GX0hXX0NTVU07Cj4gKwlheF9sb2NhbC0+Y2hlY2tzdW0gPSBB WF9SWF9DSEVDS1NVTSB8IEFYX1RYX0NIRUNLU1VNOwo+ICsJbmRldi0+aGFyZF9oZWFkZXJfbGVu ICs9IChUWF9PVkVSSEVBRCArIDQpOwo+ICsKPiArCXJldCA9IHJlZ2lzdGVyX25ldGRldihuZGV2 KTsKPiArCWlmICghcmV0KSB7Cj4gKwkJaWYgKG5ldGlmX21zZ19wcm9iZShheF9sb2NhbCkpCj4g KwkJCW5ldGRldl9pbmZvKG5kZXYsICIlcyAlcyByZWdpc3RlcmVkXG4iLAo+ICsJCQkJICAgIGRl dl9kcml2ZXJfc3RyaW5nKCZzcGktPmRldiksCj4gKwkJCQkgICAgZGV2X25hbWUoJnNwaS0+ZGV2 KSk7Cj4gKwkJcmV0dXJuIHJldDsKPiArCX0KClRoYXQncyB1bnVzdWFsIGZsb3cgLSBleGl0IG9u IHN1Y2Nlc3MgZWFybHkuIEZvbGxvdyB0aGUga2VybmVsIHBhdHRlcm4Kb2YgInJldHVybiAwIiBv biBzdWNjZXNzIGFuZCBqdW1wcyB0byBjb21tb24gZXJyb3IgaGFuZGxpbmcgbGlrZToKCglyZXQg PSByZWdpc3Rlcl9uZXRkZXYobmRldikKCWlmIChyZXQpCgkJLy8gaGFuZGxlIGVycm9yOiBtYXli ZSBkZXZfZXJyIGFuZCBnb3RvCgkKCWlmIChuZXRpZl9tc2dfcHJvYmUoKSkKCQluZXRkZXZfaW5m bygpOwoKCXJldHVybiAwOwoKCj4gKwo+ICsJZGV2X2Vycigmc3BpLT5kZXYsICJmYWlsZWQgdG8g cmVnaXN0ZXIgYSBuZXR3b3JrIGRldmljZVxuIik7Cj4gKwlkZXN0cm95X3dvcmtxdWV1ZShheF9s b2NhbC0+YXhfd29ya19xdWV1ZSk7Cj4gKwo+ICsJcmV0dXJuIHJldDsKPiArfQo+ICsKPiArc3Rh dGljIGludAo+ICtheDg4Nzk2Y19zdXNwZW5kKHN0cnVjdCBzcGlfZGV2aWNlICpzcGksIHBtX21l c3NhZ2VfdCBtZXNnKQo+ICt7Cj4gKwlzdHJ1Y3QgYXg4ODc5NmNfZGV2aWNlICpheF9sb2NhbCA9 IGRldl9nZXRfZHJ2ZGF0YSgmc3BpLT5kZXYpOwo+ICsJc3RydWN0IG5ldF9kZXZpY2UgKm5kZXYg PSBheF9sb2NhbC0+bmRldjsKPiArCXU4IHBvd2VyOwo+ICsKPiArCWlmICghbmRldiB8fCAhbmV0 aWZfcnVubmluZyhuZGV2KSkKPiArCQlyZXR1cm4gMDsKCiFuZGV2IGNhbm5vdCBoYXBwZW4gKGRl dmljZSBzaG91bGQgbm90IGJlIHN1c3BlbmRlZCBiZWZvcmUgZW5kIG9mCnByb2JlKS4gSWYgaXQg Y2FuLCB0aGVyZSBpcyBhIGJ1ZyB3aGljaCB5b3Ugc2hvdWxkIG5vdCBzaWxlbnRseSBpZ25vcmUu Cgo+ICsKPiArCW5ldGlmX2RldmljZV9kZXRhY2gobmRldik7Cj4gKwo+ICsJbmV0aWZfc3RvcF9x dWV1ZShuZGV2KTsKPiArCj4gKwlkb3duKCZheF9sb2NhbC0+c3BpX2xvY2spOwo+ICsKPiArCXBv d2VyID0gYXg4ODc5NmNfY2hlY2tfcG93ZXJfYW5kX3dha2UoYXhfbG9jYWwpOwo+ICsKPiArCUFY X1dSSVRFKCZheF9sb2NhbC0+YXhfc3BpLCBJTVJfTUFTS0FMTCwgUDBfSU1SKTsKPiArCWF4ODg3 OTZjX2ZyZWVfc2tiX3F1ZXVlKCZheF9sb2NhbC0+dHhfd2FpdF9xKTsKPiArCj4gKwlpZiAoYXhf bG9jYWwtPndvbCkgewo+ICsKPiArCQlBWF9XUklURSgmYXhfbG9jYWwtPmF4X3NwaSwgMCwgUDVf V0ZUUik7Cj4gKwo+ICsJCWlmIChheF9sb2NhbC0+d29sICYgV0ZDUl9MSU5LQ0gpIHsJLyogTGlu ayBjaGFuZ2UgKi8KPiArCj4gKwkJCS8qIERpc2FibGUgd29sIHBvd2VyIHNhdmluZyBpbiBsaW5r IGNoYW5nZSBtb2RlICovCj4gKwkJCUFYX1dSSVRFKCZheF9sb2NhbC0+YXhfc3BpLAo+ICsJCQkJ ICAoQVhfUkVBRCgmYXhfbG9jYWwtPmF4X3NwaSwgUDBfUFNDUikKPiArCQkJCSAgJiB+UFNDUl9X T0xQUyksIFAwX1BTQ1IpOwo+ICsKPiArCQkJaWYgKG5ldGlmX21zZ193b2woYXhfbG9jYWwpKQo+ ICsJCQkJbmV0ZGV2X2luZm8obmRldiwKPiArCQkJCQkiRW5hYmxlIGxpbmsgY2hhbmdlIHdha2V1 cFxuIik7Cj4gKwo+ICsJCQlBWF9XUklURSgmYXhfbG9jYWwtPmF4X3NwaSwgV0ZUUl84MTkyTVMs IFA1X1dGVFIpOwo+ICsJCX0KPiArCQlpZiAoYXhfbG9jYWwtPndvbCAmIFdGQ1JfTUFHSUNQKSB7 CS8qIE1hZ2ljIHBhY2tldCAqLwo+ICsJCQlpZiAobmV0aWZfbXNnX3dvbChheF9sb2NhbCkpCj4g KwkJCQluZXRkZXZfaW5mbyhuZGV2LAo+ICsJCQkJCSJFbmFibGUgbWFnaWMgcGFja2V0IHdha2V1 cFxuIik7Cj4gKwkJfQo+ICsKPiArCQlBWF9XUklURSgmYXhfbG9jYWwtPmF4X3NwaSwKPiArCQkJ ICBheF9sb2NhbC0+d29sIHwgV0ZDUl9XQUtFVVAgfCBXRkNSX1BNRUVOLCBQMF9XRkNSKTsKPiAr CX0KPiArCj4gKwlpZiAocG93ZXIpCj4gKwkJYXg4ODc5NmNfc2V0X3Bvd2VyX3NhdmluZyhheF9s b2NhbCwgYXhfbG9jYWwtPnBzX2xldmVsKTsKPiArCj4gKwl1cCgmYXhfbG9jYWwtPnNwaV9sb2Nr KTsKPiArCj4gKwlyZXR1cm4gMDsKPiArfQo+ICsKPiArc3RhdGljIGludAo+ICtheDg4Nzk2Y19y ZXN1bWUoc3RydWN0IHNwaV9kZXZpY2UgKnNwaSkKPiArewo+ICsJc3RydWN0IGF4ODg3OTZjX2Rl dmljZSAqYXhfbG9jYWwgPSBkZXZfZ2V0X2RydmRhdGEoJnNwaS0+ZGV2KTsKPiArCXN0cnVjdCBu ZXRfZGV2aWNlICpuZGV2ID0gYXhfbG9jYWwtPm5kZXY7Cj4gKwl1MTYgcG1lOwo+ICsKPiArCWRv d24oJmF4X2xvY2FsLT5zcGlfbG9jayk7Cj4gKwo+ICsJLyogV2FrZXVwIEFYODg3OTZDIGZpcnN0 ICovCj4gKwlheDg4Nzk2Y19jaGVja19wb3dlcl9hbmRfd2FrZShheF9sb2NhbCk7Cj4gKwltc2xl ZXAoMjAwKTsKPiArCj4gKwlwbWUgPSBBWF9SRUFEKCZheF9sb2NhbC0+YXhfc3BpLCBQMF9XRkNS KTsKPiArCWlmIChheF9sb2NhbC0+d29sICYmIH4ocG1lICYgV0ZDUl9XQUlURVZFTlQpKSB7Cj4g Kwo+ICsJCWlmIChwbWUgJiBXRkNSX0xJTktDSFMpIHsKPiArCQkJaWYgKG5ldGlmX21zZ193b2wo YXhfbG9jYWwpKQo+ICsJCQkJbmV0ZGV2X2luZm8obmRldiwKPiArCQkJCQkiV2FrZXVwZWQgZnJv bSBsaW5rIGNoYW5nZS5cbiIpOwo+ICsJCX0gZWxzZSBpZiAocG1lICYgV0ZDUl9NQUdJQ1BTKSB7 Cj4gKwkJCWlmIChuZXRpZl9tc2dfd29sKGF4X2xvY2FsKSkKPiArCQkJCW5ldGRldl9pbmZvKG5k ZXYsCj4gKwkJCQkJIldha2V1cGVkIGZyb20gbWFnaWMgcGFja2V0LlxuIik7Cj4gKwkJfQo+ICsK PiArCQlBWF9XUklURSgmYXhfbG9jYWwtPmF4X3NwaSwgV0ZDUl9DTFJXQUtFLCBQMF9XRkNSKTsK PiArCX0KPiArCj4gKwluZXRpZl9kZXZpY2VfYXR0YWNoKG5kZXYpOwo+ICsKPiArCS8qIEluaXRp YWxpemUgYWxsIHRoZSBsb2NhbCB2YXJpYWJsZXMqLwo+ICsJYXg4ODc5NmNfc29mdF9yZXNldChh eF9sb2NhbCk7Cj4gKwo+ICsJYXhfbG9jYWwtPnNlcV9udW0gPSAweDFmOwo+ICsKPiArCWF4ODg3 OTZjX3NldF9tYWNfYWRkcihuZGV2KTsKPiArCWF4ODg3OTZjX3NldF9jc3VtcyhheF9sb2NhbCk7 Cj4gKwo+ICsJLyogRGlzYWJsZSBzdHVmZmluZyBwYWNrZXQgKi8KPiArCUFYX1dSSVRFKCZheF9s b2NhbC0+YXhfc3BpLAo+ICsJCSAgQVhfUkVBRCgmYXhfbG9jYWwtPmF4X3NwaSwgUDFfUlhCU1BD UikKPiArCQkgICYgflJYQlNQQ1JfU1RVRl9FTkFCTEUsIFAxX1JYQlNQQ1IpOwo+ICsKPiArCS8q IEVuYWJsZSBSWCBwYWNrZXQgcHJvY2VzcyAqLwo+ICsJQVhfV1JJVEUoJmF4X2xvY2FsLT5heF9z cGksIFJQUEVSX1JYRU4sIFAxX1JQUEVSKTsKPiArCj4gKwlBWF9XUklURSgmYXhfbG9jYWwtPmF4 X3NwaSwKPiArCQkgIEFYX1JFQUQoJmF4X2xvY2FsLT5heF9zcGksIFAwX0ZFUikKPiArCQkgIHwg RkVSX1JYRU4gfCBGRVJfVFhFTiB8IEZFUl9CU1dBUCwgUDBfRkVSKTsKPiArCj4gKwlheDg4Nzk2 Y19waHlfaW5pdChheF9sb2NhbCk7Cj4gKwo+ICsJQVhfV1JJVEUoJmF4X2xvY2FsLT5heF9zcGks IElNUl9ERUZBVUxULCBQMF9JTVIpOwo+ICsKPiArCWlmIChuZXRpZl9tc2dfaHcoYXhfbG9jYWwp KSB7Cj4gKwkJbmV0ZGV2X2luZm8obmRldiwKPiArCQkJIkR1bXAgYWxsIE1BQyByZWdpc3RlcnMg YWZ0ZXIgaW5pdGlhbGl6YXRpb246XG4iKTsKPiArCQlheDg4Nzk2Y19kdW1wX3JlZ3MoYXhfbG9j YWwpOwo+ICsJCWF4ODg3OTZjX2R1bXBfcGh5X3JlZ3MoYXhfbG9jYWwpOwo+ICsJfQo+ICsKPiAr CWF4ODg3OTZjX3NldF9wb3dlcl9zYXZpbmcoYXhfbG9jYWwsIGF4X2xvY2FsLT5wc19sZXZlbCk7 Cj4gKwo+ICsJbmV0aWZfc3RhcnRfcXVldWUobmRldik7Cj4gKwo+ICsJdXAoJmF4X2xvY2FsLT5z cGlfbG9jayk7Cj4gKwo+ICsJcmV0dXJuIDA7Cj4gK30KPiArCj4gK3N0YXRpYyBpbnQgYXg4ODc5 NmNfcmVtb3ZlKHN0cnVjdCBzcGlfZGV2aWNlICpzcGkpCj4gK3sKPiArCXN0cnVjdCBheDg4Nzk2 Y19kZXZpY2UgKmF4X2xvY2FsID0gZGV2X2dldF9kcnZkYXRhKCZzcGktPmRldik7Cj4gKwlzdHJ1 Y3QgbmV0X2RldmljZSAqbmRldiA9IGF4X2xvY2FsLT5uZGV2Owo+ICsKPiArCWlmIChuZXRpZl9t c2dfcHJvYmUoYXhfbG9jYWwpKQo+ICsJCW5ldGRldl9pbmZvKG5kZXYsICJyZW1vdmluZyBuZXR3 b3JrIGRldmljZSAlcyAlc1xuIiwKPiArCQkJICAgIGRldl9kcml2ZXJfc3RyaW5nKCZzcGktPmRl diksCj4gKwkJCSAgICBkZXZfbmFtZSgmc3BpLT5kZXYpKTsKPiArCj4gKwlkZXN0cm95X3dvcmtx dWV1ZShheF9sb2NhbC0+YXhfd29ya19xdWV1ZSk7Cj4gKwo+ICsJdW5yZWdpc3Rlcl9uZXRkZXYo bmRldik7Cj4gKwo+ICsJaWYgKG5ldGlmX21zZ19wcm9iZShheF9sb2NhbCkpCj4gKwkJZGV2X2lu Zm8oJnNwaS0+ZGV2LCAiZGV2aWNlIHJlbW92ZWRcbiIpOwo+ICsKPiArCXJldHVybiAwOwo+ICt9 Cj4gKwo+ICsjaWZkZWYgQ09ORklHX1VTRV9PRgoKI2lmZGVmIHNob3VsZCBub3QgYmUgbmVlZGVk LgoKPiArc3RhdGljIGNvbnN0IHN0cnVjdCBvZl9kZXZpY2VfaWQgYXg4ODc5NmNfZHRfaWRzW10g PSB7Cj4gKwl7IC5jb21wYXRpYmxlID0gImFzaXgsYXg4ODc5NmMiIH0sCj4gKwl7fSwKPiArfTsK PiArTU9EVUxFX0RFVklDRV9UQUJMRShvZiwgYXg4ODc5NmNfZHRfaWRzKTsKPiArI2VuZGlmCj4g Kwo+ICtzdGF0aWMgY29uc3Qgc3RydWN0IHNwaV9kZXZpY2VfaWQgYXNpeF9pZFtdID0gewo+ICsJ eyAiYXg4ODc5NmMiLCAwIH0sCj4gKwl7IH0KPiArfTsKPiArTU9EVUxFX0RFVklDRV9UQUJMRShz cGksIGFzaXhfaWQpOwo+ICsKPiArc3RhdGljIHN0cnVjdCBzcGlfZHJpdmVyIGF4ODg3OTZjX3Nw aV9kcml2ZXIgPSB7Cj4gKwkuZHJpdmVyID0gewo+ICsJCS5uYW1lID0gRFJWX05BTUUsCj4gKwkJ Lm93bmVyID0gVEhJU19NT0RVTEUsCgpObyBuZWVkIGZvciBvd25lci4KCj4gKyNpZmRlZiBDT05G SUdfVVNFX09GCj4gKwkJLm9mX21hdGNoX3RhYmxlID0gb2ZfbWF0Y2hfcHRyKGF4ODg3OTZjX2R0 X2lkcyksCj4gKyNlbmRpZgoKTm8gbmVlZCBmb3IgaWZkZWYuCgo+ICsJfSwKPiArCS5wcm9iZSA9 IGF4ODg3OTZjX3Byb2JlLAo+ICsJLnJlbW92ZSA9IGF4ODg3OTZjX3JlbW92ZSwKPiArLy8JLnN1 c3BlbmQgPSBheDg4Nzk2Y19zdXNwZW5kLAo+ICsvLwkucmVzdW1lID0gYXg4ODc5NmNfcmVzdW1l LAoKPwoKPiArCS5pZF90YWJsZSA9IGFzaXhfaWQsCj4gK307Cj4gKwo+ICtzdGF0aWMgX19pbml0 IGludCBheDg4Nzk2Y19zcGlfaW5pdCh2b2lkKQo+ICt7Cj4gKwlwcl9pbmZvKCJSZWdpc3RlciBB WDg4Nzk2QyBTUEkgRXRoZXJuZXQgRHJpdmVyLlxuIik7CgpObywgbm8gcHJpbnRpbmcgb2YgZHJp dmVyIGluaXRzLiBJdCB3aWxsIGJvdGhlciBldmVyeW9uZSBpbiB0aGUgd29ybGQuCgpUaGlzIGFs bCBzaG91bGQgYmUganVzdCBtb2R1bGUgZHJpdmVyLCBubyBpbml0L2V4aXQuCgo+ICsJcmV0dXJu IHNwaV9yZWdpc3Rlcl9kcml2ZXIoJmF4ODg3OTZjX3NwaV9kcml2ZXIpOwo+ICt9Cj4gKwo+ICtz dGF0aWMgX19leGl0IHZvaWQgYXg4ODc5NmNfc3BpX2V4aXQodm9pZCkKPiArewo+ICsJc3BpX3Vu cmVnaXN0ZXJfZHJpdmVyKCZheDg4Nzk2Y19zcGlfZHJpdmVyKTsKPiArfQo+ICsKPiArbW9kdWxl X2luaXQoYXg4ODc5NmNfc3BpX2luaXQpOwo+ICttb2R1bGVfZXhpdChheDg4Nzk2Y19zcGlfZXhp dCk7Cj4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvbmV0L2V0aGVybmV0L2FzaXgvYXg4ODc5NmNfbWFp bi5oIGIvZHJpdmVycy9uZXQvZXRoZXJuZXQvYXNpeC9heDg4Nzk2Y19tYWluLmgKPiBuZXcgZmls ZSBtb2RlIDEwMDY0NAo+IGluZGV4IDAwMDAwMDAwMDAwMC4uNmM2MTc2NmIxNzg4Cj4gLS0tIC9k ZXYvbnVsbAo+ICsrKyBiL2RyaXZlcnMvbmV0L2V0aGVybmV0L2FzaXgvYXg4ODc5NmNfbWFpbi5o Cj4gQEAgLTAsMCArMSw1OTYgQEAKPiArLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEdQTC0y LjAtb25seQo+ICsvKgo+ICsgKiBDb3B5cmlnaHQgKGMpIDIwMTAgQVNJWCBFbGVjdHJvbmljcyBD b3Jwb3JhdGlvbgo+ICsgKiBDb3B5cmlnaHQgKGMpIDIwMjAgU2Ftc3VuZyBFbGVjdHJvbmljcwo+ ICsgKgo+ICsgKiBBU0lYIEFYODg3OTZDIFNQSSBGYXN0IEV0aGVybmV0IExpbnV4IGRyaXZlcgo+ ICsgKi8KPiArCj4gKyNpZm5kZWYgX0FYODg3OTZDX01BSU5fSAo+ICsjZGVmaW5lIF9BWDg4Nzk2 Q19NQUlOX0gKPiArCj4gKyNkZWZpbmUgcHJfZm10KGZtdCkJImF4ODg3OTZjOiAiIGZtdAo+ICsK PiArLyogSU5DTFVERSBGSUxFIERFQ0xBUkFUSU9OUyAqLwo+ICsjaWZkZWYgQ09ORklHX1VTRV9P RgoKTm8gaWZkZWYuCgo+ICsjaW5jbHVkZSA8bGludXgvb2YuaD4KPiArI2VuZGlmCj4gKyNpbmNs dWRlIDxsaW51eC9jcmMzMi5oPgo+ICsjaW5jbHVkZSA8bGludXgvZXRoZXJkZXZpY2UuaD4KPiAr I2luY2x1ZGUgPGxpbnV4L2V0aHRvb2wuaD4KPiArI2luY2x1ZGUgPGxpbnV4L2dwaW8vY29uc3Vt ZXIuaD4KPiArI2luY2x1ZGUgPGxpbnV4L2luaXQuaD4KPiArI2luY2x1ZGUgPGxpbnV4L2lvLmg+ Cj4gKyNpbmNsdWRlIDxsaW51eC9rbW9kLmg+Cj4gKyNpbmNsdWRlIDxsaW51eC9taWkuaD4KPiAr I2luY2x1ZGUgPGxpbnV4L21vZHVsZS5oPgo+ICsjaW5jbHVkZSA8bGludXgvbmV0ZGV2aWNlLmg+ Cj4gKyNpbmNsdWRlIDxsaW51eC9wbGF0Zm9ybV9kZXZpY2UuaD4KPiArI2luY2x1ZGUgPGxpbnV4 L3NjaGVkLmg+Cj4gKyNpbmNsdWRlIDxsaW51eC9zcGkvc3BpLmg+Cj4gKyNpbmNsdWRlIDxsaW51 eC90aW1lci5oPgo+ICsjaW5jbHVkZSA8bGludXgvdWFjY2Vzcy5oPgo+ICsjaW5jbHVkZSA8bGlu dXgvdXNiLmg+Cj4gKyNpbmNsdWRlIDxsaW51eC92ZXJzaW9uLmg+Cj4gKyNpbmNsdWRlIDxsaW51 eC93b3JrcXVldWUuaD4KCkFsbCBvZiB0aGVzZSBzaG91bGQgYmUgcmVtb3ZlZCBleGNlcHQgdGhl IGhlYWRlcnMgdXNlZCBkaXJlY3RseSBpbiB0aGlzCmhlYWRlci4KCj4gKwo+ICsjaW5jbHVkZSA8 YXNtL2RtYS5oPgo+ICsKPiArI2luY2x1ZGUgImF4ODg3OTZjX3NwaS5oIgo+ICsKPiArLyogTkFN SU5HIENPTlNUQU5UIEFORCBUWVBFIERFQ0xBUkFUSU9OUyAqLwo+ICsvKiBUaGVzZSBpZGVudGlm eSB0aGUgZHJpdmVyIGJhc2UgdmVyc2lvbiBhbmQgbWF5IG5vdCBiZSByZW1vdmVkLiAqLwo+ICsj ZGVmaW5lIERSVl9OQU1FCSJheDg4Nzk2YyIKPiArI2RlZmluZSBBRFBfTkFNRQkiQVNJWCBBWDg4 Nzk2QyBTUEkgRXRoZXJuZXQgQWRhcHRlciIKPiArI2RlZmluZSBEUlZfVkVSU0lPTgkiMS4yLjAi Cj4gKwo+ICsjZGVmaW5lIFRYX1FVRVVFX0hJR0hfV0FURVIJCTQ1CS8qIFR4IHF1ZXVlIGhpZ2gg d2F0ZXIgbWFyayAqLwo+ICsjZGVmaW5lIFRYX1FVRVVFX0xPV19XQVRFUgkJMjAJLyogVHggcXVl dWUgbG93IHdhdGVyIG1hcmsgKi8KPiArCj4gKyNkZWZpbmUgQVg4ODc5NkNfV0FUQ0hET0dfUEVS SU9ECSgxICogSFopCj4gKyNkZWZpbmUgQVg4ODc5NkNfV0FUQ0hET0dfUkVTVEFSVAk3Cj4gKwo+ ICsjZGVmaW5lIFRYX09WRVJIRUFECQkJOAo+ICsjZGVmaW5lIFRYX0VPUF9TSVpFCQkJNAo+ICsK PiArI2RlZmluZSBBWF9NQ0FTVF9GSUxURVJfU0laRQkJOAo+ICsjZGVmaW5lIEFYX01BWF9NQ0FT VAkJCTY0Cj4gKyNkZWZpbmUgQVhfTUFYX0NMSyAgICAgICAgICAgICAgICAgICAgICA4MDAwMDAw MAo+ICsjZGVmaW5lIFRYX0hEUl9TT1BfRElDRgkJCTB4ODAwMAo+ICsjZGVmaW5lIFRYX0hEUl9T T1BfQ1BISQkJCTB4NDAwMAo+ICsjZGVmaW5lIFRYX0hEUl9TT1BfSU5UCQkJMHgyMDAwCj4gKyNk ZWZpbmUgVFhfSERSX1NPUF9NREVRCQkJMHgxMDAwCj4gKyNkZWZpbmUgVFhfSERSX1NPUF9QS1RM RU4JCTB4MDdGRgo+ICsjZGVmaW5lIFRYX0hEUl9TT1BfU0VRTlVNCQkweEY4MDAKPiArI2RlZmlu ZSBUWF9IRFJfU09QX1BLVExFTkJBUgkJMHgwN0ZGCj4gKwo+ICsjZGVmaW5lIFRYX0hEUl9TRUdf RlMJCQkweDgwMDAKPiArI2RlZmluZSBUWF9IRFJfU0VHX0xTCQkJMHg0MDAwCj4gKyNkZWZpbmUg VFhfSERSX1NFR19TRUdOVU0JCTB4MzgwMAo+ICsjZGVmaW5lIFRYX0hEUl9TRUdfU0VHTEVOCQkw eDA3MDAKPiArI2RlZmluZSBUWF9IRFJfU0VHX0VPRlNUCQkweEMwMDAKPiArI2RlZmluZSBUWF9I RFJfU0VHX1NPRlNUCQkweDM4MDAKPiArI2RlZmluZSBUWF9IRFJfU0VHX1NFR0xFTkJBUgkJMHgw N0ZGCj4gKwo+ICsjZGVmaW5lIFRYX0hEUl9FT1BfU0VRTlVNCQkweEY4MDAKPiArI2RlZmluZSBU WF9IRFJfRU9QX1BLVExFTgkJMHgwN0ZGCj4gKyNkZWZpbmUgVFhfSERSX0VPUF9TRVFOVU1CQVIJ CTB4RjgwMAo+ICsjZGVmaW5lIFRYX0hEUl9FT1BfUEtUTEVOQkFSCQkweDA3RkYKPiArCj4gKy8q IFJ4IGhlYWRlciBmaWVsZHMgbWFzayAqLwo+ICsjZGVmaW5lIFJYX0hEUjFfTUNCQwkJCTB4ODAw MAo+ICsjZGVmaW5lIFJYX0hEUjFfU1RVRkZfUEtUCQkweDQwMDAKPiArI2RlZmluZSBSWF9IRFIx X01JSV9FUlIJCQkweDIwMDAKPiArI2RlZmluZSBSWF9IRFIxX0NSQ19FUlIJCQkweDEwMDAKPiAr I2RlZmluZSBSWF9IRFIxX1BLVF9MRU4JCQkweDA3RkYKPiArCj4gKyNkZWZpbmUgUlhfSERSMl9T RVFfTlVNCQkJMHhGODAwCj4gKyNkZWZpbmUgUlhfSERSMl9QS1RfTEVOX0JBUgkJMHg3RkZGCj4g Kwo+ICsjZGVmaW5lIFJYX0hEUjNfUEUJCQkweDgwMDAKPiArI2RlZmluZSBSWF9IRFIzX0w0X1RZ UEVfVENQCQkweDEwMDAKPiArI2RlZmluZSBSWF9IRFIzX0w0X1RZUEVfVURQCQkweDA0MDAKPiAr I2RlZmluZSBSWF9IRFIzX0wzX0VSUgkJCTB4MDIwMAo+ICsjZGVmaW5lIFJYX0hEUjNfTDRfRVJS CQkJMHgwMTAwCj4gKyNkZWZpbmUgUlhfSERSM19QUklPUklUWSh4KQkJKCh4KSA8PCA0KQo+ICsj ZGVmaW5lIFJYX0hEUjNfU1RSSVAJCQkweDAwMDgKPiArI2RlZmluZSBSWF9IRFIzX1ZMQU5fSUQJ CQkweDAwMDcKPiArCj4gKyNkZWZpbmUgQVhfUlhfQ0hFQ0tTVU0JCQkxCj4gKyNkZWZpbmUgQVhf VFhfQ0hFQ0tTVU0JCQkyCj4gKwo+ICtlbnVtIHdhdGNoZG9nX3N0YXRlIHsKPiArCWNoa19saW5r ID0gMCwKPiArCWNoa19jYWJsZSwKPiArCWF4X25vcCwKPiArfTsKPiArCj4gK3N0cnVjdCBheDg4 Nzk2Y19kZXZpY2Ugewo+ICsKPiArCXN0cnVjdCByZXNvdXJjZQkJKmFkZHJfcmVzOyAgIC8qIHJl c291cmNlcyBmb3VuZCAqLwo+ICsJc3RydWN0IHJlc291cmNlCQkqYWRkcl9yZXE7ICAgLyogcmVz b3VyY2VzIHJlcXVlc3RlZCAqLwo+ICsJc3RydWN0IHJlc291cmNlCQkqaXJxX3JlczsKPiArCj4g KwlzdHJ1Y3Qgc3BpX2RldmljZQkqc3BpOwo+ICsJc3RydWN0IG5ldF9kZXZpY2UJKm5kZXY7Cj4g KwlzdHJ1Y3QgbWlpX2lmX2luZm8gICAgICBtaWk7Cj4gKwlzdHJ1Y3QgbmV0X2RldmljZV9zdGF0 cwlzdGF0czsKPiArCj4gKwlzdHJ1Y3QgdGltZXJfbGlzdAl3YXRjaGRvZzsKPiArCWVudW0gd2F0 Y2hkb2dfc3RhdGUJd19zdGF0ZTsKPiArCXNpemVfdAkJCXdfdGlja3M7Cj4gKwo+ICsJc3RydWN0 IHdvcmtfc3RydWN0CWF4X3dvcms7Cj4gKwlzdHJ1Y3Qgd29ya3F1ZXVlX3N0cnVjdCAqYXhfd29y a19xdWV1ZTsKPiArCXN0cnVjdCB0YXNrbGV0X3N0cnVjdAliaDsKPiArCj4gKwlzdHJ1Y3Qgc2Vt YXBob3JlCXNwaV9sb2NrOwo+ICsKPiArCXN0cnVjdCBza19idWZmX2hlYWQJdHhfd2FpdF9xOwo+ ICsKPiArCXN0cnVjdCBheHNwaV9kYXRhCWF4X3NwaTsKPiArCj4gKwlpbnQJCQltc2dfZW5hYmxl Owo+ICsKPiArCXUxNgkJCXNlcV9udW07Cj4gKwo+ICsJdTE2CQkJd29sOwo+ICsKPiArCXU4CQkJ Y2hlY2tzdW07Cj4gKwo+ICsJdTgJCQltdWx0aV9maWx0ZXJbQVhfTUNBU1RfRklMVEVSX1NJWkVd Owo+ICsKPiArCXVuc2lnbmVkIGxvbmcJCWNhcGFiaWxpdGllczsKPiArCQkjZGVmaW5lIEFYX0NB UF9ETUEJCTEKPiArCQkjZGVmaW5lIEFYX0NBUF9DT01QCQkyCj4gKwkJI2RlZmluZSBBWF9DQVBf QklESVIJCTQKPiArCj4gKwl1OAkJCXBsYXRfZW5kaWFuOwo+ICsJCSNkZWZpbmUgUExBVF9MSVRU TEVfRU5ESUFOCTAKPiArCQkjZGVmaW5lIFBMQVRfQklHX0VORElBTgkJMQo+ICsKPiArCXVuc2ln bmVkIGxvbmcJCWZsYWdzOwo+ICsJCSNkZWZpbmUgRVZFTlRfSU5UUgkJMQo+ICsJCSNkZWZpbmUg RVZFTlRfVFgJCQkyCj4gKwkJI2RlZmluZSBFVkVOVF9TRVRfTVVMVEkJCTQKPiArCQkjZGVmaW5l IEVWRU5UX1dBVENIRE9HCQk4Cj4gKwo+ICsJdTgJcHNfbGV2ZWw7Cj4gKwkJI2RlZmluZSBBWF9Q U19EMAkJCTAKPiArCQkjZGVmaW5lIEFYX1BTX0QxCQkJMQo+ICsJCSNkZWZpbmUgQVhfUFNfRDIJ CQkyCj4gKwo+ICsKPiArfTsKPiArCj4gKyNkZWZpbmUgdG9fYXg4ODc5NmNfZGV2aWNlKG5kZXYp ICgoc3RydWN0IGF4ODg3OTZjX2RldmljZSAqKW5ldGRldl9wcml2KG5kZXYpKQo+ICsKPiArZW51 bSBza2Jfc3RhdGUgewo+ICsJaWxsZWdhbCA9IDAsCj4gKwl0eF9kb25lLAo+ICsJcnhfZG9uZSwK PiArCXJ4X2VyciwKPiArfTsKPiArCj4gK3N0cnVjdCBza2JfZGF0YTsKPiArCj4gK3N0cnVjdCBz a2JfZGF0YSB7Cj4gKwllbnVtIHNrYl9zdGF0ZSBzdGF0ZTsKPiArCXN0cnVjdCBuZXRfZGV2aWNl ICpuZGV2Owo+ICsJc3RydWN0IHNrX2J1ZmYgKnNrYjsKPiArCXNpemVfdCBsZW47Cj4gKwlkbWFf YWRkcl90IHBoeV9hZGRyOwo+ICt9Owo+ICsKPiArLyogQTg4Nzk2QyByZWdpc3RlciBkZWZpbml0 aW9uICovCj4gKwkvKiBEZWZpbml0aW9uIG9mIFBBR0UwICovCj4gKyNkZWZpbmUgUDBfUFNSCQko MHgwMCkKPiArCSNkZWZpbmUgUFNSX0RFVl9SRUFEWQkJKDEgPDwgNykKPiArCSNkZWZpbmUgUFNS X1JFU0VUCQkoMCA8PCAxNSkKPiArCSNkZWZpbmUgUFNSX1JFU0VUX0NMUgkJKDEgPDwgMTUpCj4g KyNkZWZpbmUgUDBfQk9SCQkoMHgwMikKPiArI2RlZmluZSBQMF9GRVIJCSgweDA0KQo+ICsJI2Rl ZmluZSBGRVJfSVBBTE0JCSgxIDw8IDApCj4gKwkjZGVmaW5lIEZFUl9EQ1JDCQkoMSA8PCAxKQo+ ICsJI2RlZmluZSBGRVJfUkgzTQkJKDEgPDwgMikKPiArCSNkZWZpbmUgRkVSX0hFQURFUlNXQVAJ CSgxIDw8IDcpCj4gKwkjZGVmaW5lIEZFUl9XU1dBUAkJKDEgPDwgOCkKPiArCSNkZWZpbmUgRkVS X0JTV0FQCQkoMSA8PCA5KQo+ICsJI2RlZmluZSBGRVJfSU5USEkJCSgxIDw8IDEwKQo+ICsJI2Rl ZmluZSBGRVJfSU5UTE8JCSgwIDw8IDEwKQo+ICsJI2RlZmluZSBGRVJfSVJRX1BVTEwJCSgxIDw8 IDExKQo+ICsJI2RlZmluZSBGRVJfUlhFTgkJKDEgPDwgMTQpCj4gKwkjZGVmaW5lIEZFUl9UWEVO CQkoMSA8PCAxNSkKPiArI2RlZmluZSBQMF9JU1IJCSgweDA2KQo+ICsJI2RlZmluZSBJU1JfUlhQ S1QJCSgxIDw8IDApCj4gKwkjZGVmaW5lIElTUl9NRFEJCQkoMSA8PCA0KQo+ICsJI2RlZmluZSBJ U1JfVFhUCQkJKDEgPDwgNSkKPiArCSNkZWZpbmUgSVNSX1RYUEFHRVMJCSgxIDw8IDYpCj4gKwkj ZGVmaW5lIElTUl9UWEVSUgkJKDEgPDwgOCkKPiArCSNkZWZpbmUgSVNSX0xJTksJCSgxIDw8IDkp Cj4gKyNkZWZpbmUgUDBfSU1SCQkoMHgwOCkKPiArCSNkZWZpbmUgSU1SX1JYUEtUCQkoMSA8PCAw KQo+ICsJI2RlZmluZSBJTVJfTURRCQkJKDEgPDwgNCkKPiArCSNkZWZpbmUgSU1SX1RYVAkJCSgx IDw8IDUpCj4gKwkjZGVmaW5lIElNUl9UWFBBR0VTCQkoMSA8PCA2KQo+ICsJI2RlZmluZSBJTVJf VFhFUlIJCSgxIDw8IDgpCj4gKwkjZGVmaW5lIElNUl9MSU5LCQkoMSA8PCA5KQo+ICsJI2RlZmlu ZSBJTVJfTUFTS0FMTAkJKDB4RkZGRikKPiArCSNkZWZpbmUgSU1SX0RFRkFVTFQJCShJTVJfVFhF UlIpCj4gKyNkZWZpbmUgUDBfV0ZDUgkJKDB4MEEpCj4gKwkjZGVmaW5lIFdGQ1JfUE1FSU5ECQko MSA8PCAwKSAvKiBQTUUgaW5kaWNhdGlvbiAqLwo+ICsJI2RlZmluZSBXRkNSX1BNRVRZUEUJCSgx IDw8IDEpIC8qIFBNRSBJL08gdHlwZSAqLwo+ICsJI2RlZmluZSBXRkNSX1BNRVBPTAkJKDEgPDwg MikgLyogUE1FIHBvbGFyaXR5ICovCj4gKwkjZGVmaW5lIFdGQ1JfUE1FUlNUCQkoMSA8PCAzKSAv KiBSZXNldCBQTUUgKi8KPiArCSNkZWZpbmUgV0ZDUl9TTEVFUAkJKDEgPDwgNCkgLyogRW5hYmxl IHNsZWVwIG1vZGUgKi8KPiArCSNkZWZpbmUgV0ZDUl9XQUtFVVAJCSgxIDw8IDUpIC8qIEVuYWJs ZSB3YWtldXAgbW9kZSAqLwo+ICsJI2RlZmluZSBXRkNSX1dBSVRFVkVOVAkJKDEgPDwgNikgLyog UmVzZXJ2ZWQgKi8KPiArCSNkZWZpbmUgV0ZDUl9DTFJXQUtFCQkoMSA8PCA3KSAvKiBDbGVhciB3 YWtldXAgKi8KPiArCSNkZWZpbmUgV0ZDUl9MSU5LQ0gJCSgxIDw8IDgpIC8qIEVuYWJsZSBsaW5r IGNoYW5nZSAqLwo+ICsJI2RlZmluZSBXRkNSX01BR0lDUAkJKDEgPDwgOSkgLyogRW5hYmxlIG1h Z2ljIHBhY2tldCAqLwo+ICsJI2RlZmluZSBXRkNSX1dBS0VGCQkoMSA8PCAxMCkgLyogRW5hYmxl IHdha2V1cCBmcmFtZSAqLwo+ICsJI2RlZmluZSBXRkNSX1BNRUVOCQkoMSA8PCAxMSkgLyogRW5h YmxlIFBNRSBwaW4gKi8KPiArCSNkZWZpbmUgV0ZDUl9MSU5LQ0hTCQkoMSA8PCAxMikgLyogTGlu ayBjaGFuZ2Ugc3RhdHVzICovCj4gKwkjZGVmaW5lIFdGQ1JfTUFHSUNQUwkJKDEgPDwgMTMpIC8q IE1hZ2ljIHBhY2tldCBzdGF0dXMgKi8KPiArCSNkZWZpbmUgV0ZDUl9XQUtFRlMJCSgxIDw8IDE0 KSAvKiBXYWtldXAgZnJhbWUgc3RhdHVzICovCj4gKwkjZGVmaW5lIFdGQ1JfUE1FUwkJKDEgPDwg MTUpIC8qIFBNRSBwaW4gc3RhdHVzICovCj4gKyNkZWZpbmUgUDBfUFNDUgkJKDB4MEMpCj4gKwkj ZGVmaW5lIFBTQ1JfUFNfTUFTSwkJKDB4RkZGMCkKPiArCSNkZWZpbmUgUFNDUl9QU19EMAkJKDAp Cj4gKwkjZGVmaW5lIFBTQ1JfUFNfRDEJCSgxIDw8IDApCj4gKwkjZGVmaW5lIFBTQ1JfUFNfRDIJ CSgxIDw8IDEpCj4gKwkjZGVmaW5lIFBTQ1JfRlBTCQkoMSA8PCAzKSAvKiBFbmFibGUgZmliZXIg bW9kZSBQUyAqLwo+ICsJI2RlZmluZSBQU0NSX1NXUFMJCSgxIDw8IDQpIC8qIEVuYWJsZSBzb2Z0 d2FyZSAqLwo+ICsJCQkJCQkgLyogUFMgY29udHJvbCAqLwo+ICsJI2RlZmluZSBQU0NSX1dPTFBT CQkoMSA8PCA1KSAvKiBFbmFibGUgV09MIFBTICovCj4gKwkjZGVmaW5lIFBTQ1JfU1dXT0wJCSgx IDw8IDYpIC8qIEVuYWJsZSBzb2Z0d2FyZSBzZWxlY3QgKi8KPiArCQkJCQkJIC8qIFdPTCBQUyAq Lwo+ICsJI2RlZmluZSBQU0NSX1BIWU9TQwkJKDEgPDwgNykgLyogSW50ZXJuYWwgUEhZIE9TQyBj b250cm9sICovCj4gKwkjZGVmaW5lIFBTQ1JfRk9GRUYJCSgxIDw8IDgpIC8qIEZvcmNlIFBIWSBn ZW5lcmF0ZSBGRUYgKi8KPiArCSNkZWZpbmUgUFNDUl9GT0YJCSgxIDw8IDkpIC8qIEZvcmNlIFBI WSBpbiBmaWJlciBtb2RlICovCj4gKwkjZGVmaW5lIFBTQ1JfUEhZUEQJCSgxIDw8IDEwKSAvKiBQ SFkgcG93ZXIgZG93bi4gKi8KPiArCQkJCQkJICAvKiBBY3RpdmUgaGlnaCAqLwo+ICsJI2RlZmlu ZSBQU0NSX1BIWVJTVAkJKDEgPDwgMTEpIC8qIFBIWSByZXNldCBzaWduYWwuICovCj4gKwkJCQkJ CSAgLyogQWN0aXZlIGxvdyAqLwo+ICsJI2RlZmluZSBQU0NSX1BIWUNTSUwJCSgxIDw8IDEyKSAv KiBQSFkgY2FibGUgZW5lcmd5IGRldGVjdCAqLwo+ICsJI2RlZmluZSBQU0NSX1BIWUNPRkYJCSgx IDw8IDEzKSAvKiBQSFkgY2FibGUgb2ZmICovCj4gKwkjZGVmaW5lIFBTQ1JfUEhZTElOSwkJKDEg PDwgMTQpIC8qIFBIWSBsaW5rIHN0YXR1cyAqLwo+ICsJI2RlZmluZSBQU0NSX0VFUE9LCQkoMSA8 PCAxNSkgLyogRUVQUk9NIGxvYWQgY29tcGxldGUgKi8KPiArI2RlZmluZSBQMF9NQUNDUgkoMHgw RSkKPiArCSNkZWZpbmUgTUFDQ1JfUlhGQ19FTkFCTEUJKDEgPDwgMykKPiArCSNkZWZpbmUgTUFD Q1JfUlhGQ19NQVNLCQkweEZGRjcKPiArCSNkZWZpbmUgTUFDQ1JfVFhGQ19FTkFCTEUJKDEgPDwg NCkKPiArCSNkZWZpbmUgTUFDQ1JfVFhGQ19NQVNLCQkweEZGRUYKPiArCSNkZWZpbmUgTUFDQ1Jf UEYJCSgxIDw8IDcpCj4gKwkjZGVmaW5lIE1BQ0NSX1BNTV9CSVRTCQk4Cj4gKwkjZGVmaW5lIE1B Q0NSX1BNTV9NQVNLCQkoMHgxRjAwKQo+ICsJI2RlZmluZSBNQUNDUl9QTU1fUkVTRVQJCSgxIDw8 IDgpCj4gKwkjZGVmaW5lIE1BQ0NSX1BNTV9XQUlUCQkoMiA8PCA4KQo+ICsJI2RlZmluZSBNQUND Ul9QTU1fUkVBRFkJCSgzIDw8IDgpCj4gKwkjZGVmaW5lIE1BQ0NSX1BNTV9EMQkJKDQgPDwgOCkK PiArCSNkZWZpbmUgTUFDQ1JfUE1NX0QyCQkoNSA8PCA4KQo+ICsJI2RlZmluZSBNQUNDUl9QTU1f V0FLRQkJKDcgPDwgOCkKPiArCSNkZWZpbmUgTUFDQ1JfUE1NX0QxX1dBS0UJKDggPDwgOCkKPiAr CSNkZWZpbmUgTUFDQ1JfUE1NX0QyX1dBS0UJKDkgPDwgOCkKPiArCSNkZWZpbmUgTUFDQ1JfUE1N X1NMRUVQCQkoMTAgPDwgOCkKPiArCSNkZWZpbmUgTUFDQ1JfUE1NX1BIWV9SRVNFVAkoMTEgPDwg OCkKPiArCSNkZWZpbmUgTUFDQ1JfUE1NX1NPRlRfRDEJKDE2IDw8IDgpCj4gKwkjZGVmaW5lIE1B Q0NSX1BNTV9TT0ZUX0QyCSgxNyA8PCA4KQo+ICsjZGVmaW5lIFAwX1RGQkZDUgkoMHgxMCkKPiAr CSNkZWZpbmUgVEZCRkNSX1NDSEVfRlJFRV9QQUdFCTB4RTA3Rgo+ICsJI2RlZmluZSBURkJGQ1Jf RlJFRV9QQUdFX0JJVFMJMHgwNwo+ICsJI2RlZmluZSBURkJGQ1JfRlJFRV9QQUdFX0xBVENICSgx IDw8IDYpCj4gKwkjZGVmaW5lIFRGQkZDUl9TRVRfRlJFRV9QQUdFKHgpCSgoeCAmIDB4M0YpIDw8 IFRGQkZDUl9GUkVFX1BBR0VfQklUUykKPiArCSNkZWZpbmUgVEZCRkNSX1RYX1BBR0VfU0VUCSgx IDw8IDEzKQo+ICsJI2RlZmluZSBURkJGQ1JfTUFOVV9FTlRYCSgxIDw8IDE1KQo+ICsJI2RlZmlu ZSBUWF9GUkVFQlVGX01BU0sJCTB4MDAzRgo+ICsJI2RlZmluZSBUWF9EUFRTVEFSVAkJMHg0MDAw Cj4gKwo+ICsjZGVmaW5lIFAwX1RTTlIJCSgweDEyKQo+ICsJI2RlZmluZSBUWE5SX1RYQl9FUlIJ CSgxIDw8IDUpCj4gKwkjZGVmaW5lIFRYTlJfVFhCX0lETEUJCSgxIDw8IDYpCj4gKwkjZGVmaW5l IFRTTlJfUEtUX0NOVCh4KQkJKCgoeCkgJiAweDNGKSA8PCA4KQo+ICsJI2RlZmluZSBUWE5SX1RY Ql9SRUlOSVQJCSgxIDw8IDE0KQo+ICsJI2RlZmluZSBUU05SX1RYQl9TVEFSVAkJKDEgPDwgMTUp Cj4gKyNkZWZpbmUgUDBfUlREUFIJKDB4MTQpCj4gKyNkZWZpbmUgUDBfUlhCQ1IxCSgweDE2KQo+ ICsJI2RlZmluZSBSWEJDUjFfUlhCX0RJU0NBUkQJKDEgPDwgMTQpCj4gKwkjZGVmaW5lIFJYQkNS MV9SWEJfU1RBUlQJKDEgPDwgMTUpCj4gKyNkZWZpbmUgUDBfUlhCQ1IyCSgweDE4KQo+ICsJI2Rl ZmluZSBSWEJDUjJfUEtUX01BU0sJCSgweEZGKQo+ICsJI2RlZmluZSBSWEJDUjJfUlhQQ19NQVNL CSgweDdGKQo+ICsJI2RlZmluZSBSWEJDUjJfUlhCX1JFQURZCSgxIDw8IDEzKQo+ICsJI2RlZmlu ZSBSWEJDUjJfUlhCX0lETEUJCSgxIDw8IDE0KQo+ICsJI2RlZmluZSBSWEJDUjJfUlhCX1JFSU5J VAkoMSA8PCAxNSkKPiArI2RlZmluZSBQMF9SVFdDUgkoMHgxQSkKPiArCSNkZWZpbmUgUlRXQ1Jf UlhXQ19NQVNLCQkoMHgzRkZGKQo+ICsJI2RlZmluZSBSVFdDUl9SWF9MQVRDSAkJKDEgPDwgMTUp Cj4gKyNkZWZpbmUgUDBfUkNQSFIJKDB4MUMpCj4gKwo+ICsJLyogRGVmaW5pdGlvbiBvZiBQQUdF MSAqLwo+ICsjZGVmaW5lIFAxX1JQUEVSCSgweDIyKQo+ICsJI2RlZmluZSBSUFBFUl9SWEVOCQko MSA8PCAwKQo+ICsjZGVmaW5lIFAxX01SQ1IJCSgweDI4KQo+ICsjZGVmaW5lIFAxX01EUgkJKDB4 MkEpCj4gKyNkZWZpbmUgUDFfUk1QUgkJKDB4MkMpCj4gKyNkZWZpbmUgUDFfVE1QUgkJKDB4MkUp Cj4gKyNkZWZpbmUgUDFfUlhCU1BDUgkoMHgzMCkKPiArCSNkZWZpbmUgUlhCU1BDUl9TVFVGX1dP UkRfQ05UKHgpCSgoKHgpICYgMHg3MDAwKSA+PiAxMikKPiArCSNkZWZpbmUgUlhCU1BDUl9TVFVG X0VOQUJMRQkJKDEgPDwgMTUpCj4gKyNkZWZpbmUgUDFfTUNSCQkoMHgzMikKPiArCSNkZWZpbmUg TUNSX1NCUAkJCSgxIDw8IDgpCj4gKwkjZGVmaW5lIE1DUl9TTQkJCSgxIDw8IDkpCj4gKwkjZGVm aW5lIE1DUl9DUkNFTkxBTgkJKDEgPDwgMTEpCj4gKwkjZGVmaW5lIE1DUl9TVFAJCQkoMSA8PCAx MikKPiArCS8qIERlZmluaXRpb24gb2YgUEFHRTIgKi8KPiArI2RlZmluZSBQMl9DSVIJCSgweDQy KQo+ICsjZGVmaW5lIFAyX1BPT0xDUgkoMHg0NCkKPiArCSNkZWZpbmUgUE9PTENSX1BPTExfRU4J CSgxIDw8IDApCj4gKwkjZGVmaW5lIFBPT0xDUl9QT0xMX0ZMT1dDVFJMCSgxIDw8IDEpCj4gKwkj ZGVmaW5lIFBPT0xDUl9QT0xMX0JNQ1IJKDEgPDwgMikKPiArCSNkZWZpbmUgUE9PTENSX1BIWUlE KHgpCQkoKHgpIDw8IDgpCj4gKyNkZWZpbmUgUDJfUEhZU1IJKDB4NDYpCj4gKyNkZWZpbmUgUDJf TURJT0RSCSgweDQ4KQo+ICsjZGVmaW5lIFAyX01ESU9DUgkoMHg0QSkKPiArCSNkZWZpbmUgTURJ T0NSX1JBRERSKHgpCQkoKHgpICYgMHgxRikKPiArCSNkZWZpbmUgTURJT0NSX0ZBRERSKHgpCQko KCh4KSAmIDB4MUYpIDw8IDgpCj4gKwkjZGVmaW5lIE1ESU9DUl9WQUxJRAkJKDEgPDwgMTMpCj4g KwkjZGVmaW5lIE1ESU9DUl9SRUFECQkoMSA8PCAxNCkKPiArCSNkZWZpbmUgTURJT0NSX1dSSVRF CQkoMSA8PCAxNSkKPiArI2RlZmluZSBQMl9MQ1IwCQkoMHg0QykKPiArCSNkZWZpbmUgTENSX0xF RDBfRU4JCSgxIDw8IDApCj4gKwkjZGVmaW5lIExDUl9MRUQwXzEwME1PREUJKDEgPDwgMSkKPiAr CSNkZWZpbmUgTENSX0xFRDBfRFVQTEVYCQkoMSA8PCAyKQo+ICsJI2RlZmluZSBMQ1JfTEVEMF9M SU5LCQkoMSA8PCAzKQo+ICsJI2RlZmluZSBMQ1JfTEVEMF9BQ1QJCSgxIDw8IDQpCj4gKwkjZGVm aW5lIExDUl9MRUQwX0NPTAkJKDEgPDwgNSkKPiArCSNkZWZpbmUgTENSX0xFRDBfMTBNT0RFCQko MSA8PCA2KQo+ICsJI2RlZmluZSBMQ1JfTEVEMF9EVVBDT0wJCSgxIDw8IDcpCj4gKwkjZGVmaW5l IExDUl9MRUQxX0VOCQkoMSA8PCA4KQo+ICsJI2RlZmluZSBMQ1JfTEVEMV8xMDBNT0RFCSgxIDw8 IDkpCj4gKwkjZGVmaW5lIExDUl9MRUQxX0RVUExFWAkJKDEgPDwgMTApCj4gKwkjZGVmaW5lIExD Ul9MRUQxX0xJTksJCSgxIDw8IDExKQo+ICsJI2RlZmluZSBMQ1JfTEVEMV9BQ1QJCSgxIDw8IDEy KQo+ICsJI2RlZmluZSBMQ1JfTEVEMV9DT0wJCSgxIDw8IDEzKQo+ICsJI2RlZmluZSBMQ1JfTEVE MV8xME1PREUJCSgxIDw8IDE0KQo+ICsJI2RlZmluZSBMQ1JfTEVEMV9EVVBDT0wJCSgxIDw8IDE1 KQo+ICsjZGVmaW5lIFAyX0xDUjEJCSgweDRFKQo+ICsJI2RlZmluZSBMQ1JfTEVEMl9NQVNLCQko MHhGRjAwKQo+ICsJI2RlZmluZSBMQ1JfTEVEMl9FTgkJKDEgPDwgMCkKPiArCSNkZWZpbmUgTENS X0xFRDJfMTAwTU9ERQkoMSA8PCAxKQo+ICsJI2RlZmluZSBMQ1JfTEVEMl9EVVBMRVgJCSgxIDw8 IDIpCj4gKwkjZGVmaW5lIExDUl9MRUQyX0xJTksJCSgxIDw8IDMpCj4gKwkjZGVmaW5lIExDUl9M RUQyX0FDVAkJKDEgPDwgNCkKPiArCSNkZWZpbmUgTENSX0xFRDJfQ09MCQkoMSA8PCA1KQo+ICsJ I2RlZmluZSBMQ1JfTEVEMl8xME1PREUJCSgxIDw8IDYpCj4gKwkjZGVmaW5lIExDUl9MRUQyX0RV UENPTAkJKDEgPDwgNykKPiArI2RlZmluZSBQMl9JUEdDUgkoMHg1MCkKPiArI2RlZmluZSBQMl9D UklSCQkoMHg1MikKPiArI2RlZmluZSBQMl9GTEhXQ1IJKDB4NTQpCj4gKyNkZWZpbmUgUDJfUlhD UgkJKDB4NTYpCj4gKwkjZGVmaW5lIFJYQ1JfUFJPCQkoMSA8PCAwKQo+ICsJI2RlZmluZSBSWENS X0FNQUxMCQkoMSA8PCAxKQo+ICsJI2RlZmluZSBSWENSX1NFUAkJKDEgPDwgMikKPiArCSNkZWZp bmUgUlhDUl9BQgkJCSgxIDw8IDMpCj4gKwkjZGVmaW5lIFJYQ1JfQU0JCQkoMSA8PCA0KQo+ICsJ I2RlZmluZSBSWENSX0FQCQkJKDEgPDwgNSkKPiArCSNkZWZpbmUgUlhDUl9BUlAJCSgxIDw8IDYp Cj4gKyNkZWZpbmUgUDJfSkxDUgkJKDB4NTgpCj4gKyNkZWZpbmUgUDJfTVBMUgkJKDB4NUMpCj4g Kwo+ICsJLyogRGVmaW5pdGlvbiBvZiBQQUdFMyAqLwo+ICsjZGVmaW5lIFAzX01BQ0FTUjAJKDB4 NjIpCj4gKwkjZGVmaW5lIFAzX01BQ0FTUih4KQkJKFAzX01BQ0FTUjAgKyAyKngpCj4gKwkjZGVm aW5lIE1BQ0FTUl9MT1dCWVRFX01BU0sJMHgwMEZGCj4gKwkjZGVmaW5lIE1BQ0FTUl9ISUdIX0JJ VFMJMHgwOAo+ICsjZGVmaW5lIFAzX01BQ0FTUjEJKDB4NjQpCj4gKyNkZWZpbmUgUDNfTUFDQVNS MgkoMHg2NikKPiArI2RlZmluZSBQM19NRkFSMDEJKDB4NjgpCj4gKyNkZWZpbmUgUDNfTUZBUl9C QVNFCSgweDY4KQo+ICsJI2RlZmluZSBQM19NRkFSKHgpCQkoUDNfTUZBUl9CQVNFICsgMip4KQo+ ICsKPiArI2RlZmluZSBQM19NRkFSMjMJKDB4NkEpCj4gKyNkZWZpbmUgUDNfTUZBUjQ1CSgweDZD KQo+ICsjZGVmaW5lIFAzX01GQVI2NwkoMHg2RSkKPiArI2RlZmluZSBQM19WSUQwRlIJKDB4NzAp Cj4gKyNkZWZpbmUgUDNfVklEMUZSCSgweDcyKQo+ICsjZGVmaW5lIFAzX0VFQ1NSCSgweDc0KQo+ ICsjZGVmaW5lIFAzX0VFRFIJCSgweDc2KQo+ICsjZGVmaW5lIFAzX0VFQ1IJCSgweDc4KQo+ICsJ I2RlZmluZSBFRUNSX0FERFJfTUFTSwkJKDB4MDBGRikKPiArCSNkZWZpbmUgRUVDUl9SRUFEX0FD VAkJKDEgPDwgOCkKPiArCSNkZWZpbmUgRUVDUl9XUklURV9BQ1QJCSgxIDw8IDkpCj4gKwkjZGVm aW5lIEVFQ1JfV1JJVEVfRElTQUJMRQkoMSA8PCAxMCkKPiArCSNkZWZpbmUgRUVDUl9XUklURV9F TkFCTEUJKDEgPDwgMTEpCj4gKwkjZGVmaW5lIEVFQ1JfRUVfUkVBRFkJCSgxIDw8IDEzKQo+ICsJ I2RlZmluZSBFRUNSX1JFTE9BRAkJKDEgPDwgMTQpCj4gKwkjZGVmaW5lIEVFQ1JfUkVTRVQJCSgx IDw8IDE1KQo+ICsjZGVmaW5lIFAzX1RQQ1IJCSgweDdBKQo+ICsJI2RlZmluZSBUUENSX1BBVFRf TUFTSwkJKDB4RkYpCj4gKwkjZGVmaW5lIFRQQ1JfUkFORF9QS1RfRU4JKDEgPDwgMTQpCj4gKwkj ZGVmaW5lIFRQQ1JfRklYRURfUEtUX0VOCSgxIDw8IDE1KQo+ICsjZGVmaW5lIFAzX1RQTFIJCSgw eDdDKQo+ICsJLyogRGVmaW5pdGlvbiBvZiBQQUdFNCAqLwo+ICsjZGVmaW5lIFA0X1NQSUNSCSgw eDhBKQo+ICsJI2RlZmluZSBTUElDUl9SQ0VOCQkoMSA8PCAwKQo+ICsJI2RlZmluZSBTUElDUl9R Q0VOCQkoMSA8PCAxKQo+ICsJI2RlZmluZSBTUElDUl9SQlJFCQkoMSA8PCAzKQo+ICsJI2RlZmlu ZSBTUElDUl9QTU0JCSgxIDw8IDQpCj4gKwkjZGVmaW5lIFNQSUNSX0xPT1BCQUNLCQkoMSA8PCA4 KQo+ICsJI2RlZmluZSBTUElDUl9DT1JFX1JFU19DTFIJKDEgPDwgMTApCj4gKwkjZGVmaW5lIFNQ SUNSX1NQSV9SRVNfQ0xSCSgxIDw8IDExKQo+ICsjZGVmaW5lIFA0X1NQSUlTTVIJKDB4OEMpCj4g Kwo+ICsjZGVmaW5lIFA0X0NPRVJDUjAJKDB4OTIpCj4gKwkjZGVmaW5lIENPRVJDUjBfUlhJUENF CQkoMSA8PCAwKQo+ICsJI2RlZmluZSBDT0VSQ1IwX1JYSVBWRQkJKDEgPDwgMSkKPiArCSNkZWZp bmUgQ09FUkNSMF9SWFY2UEUJCSgxIDw8IDIpCj4gKwkjZGVmaW5lIENPRVJDUjBfUlhUQ1BFCQko MSA8PCAzKQo+ICsJI2RlZmluZSBDT0VSQ1IwX1JYVURQRQkJKDEgPDwgNCkKPiArCSNkZWZpbmUg Q09FUkNSMF9SWElDTVAJCSgxIDw8IDUpCj4gKwkjZGVmaW5lIENPRVJDUjBfUlhJR01QCQkoMSA8 PCA2KQo+ICsJI2RlZmluZSBDT0VSQ1IwX1JYSUNWNgkJKDEgPDwgNykKPiArCj4gKwkjZGVmaW5l IENPRVJDUjBfUlhUQ1BWNgkJKDEgPDwgOCkKPiArCSNkZWZpbmUgQ09FUkNSMF9SWFVEUFY2CQko MSA8PCA5KQo+ICsJI2RlZmluZSBDT0VSQ1IwX1JYSUNNVjYJCSgxIDw8IDEwKQo+ICsJI2RlZmlu ZSBDT0VSQ1IwX1JYSUdNVjYJCSgxIDw8IDExKQo+ICsJI2RlZmluZSBDT0VSQ1IwX1JYSUNWNlY2 CSgxIDw8IDEyKQo+ICsKPiArCSNkZWZpbmUgQ09FUkNSMF9ERUZBVUxUCQkoQ09FUkNSMF9SWElQ Q0UgfCBDT0VSQ1IwX1JYVjZQRSB8IFwKPiArCQkJCQkgQ09FUkNSMF9SWFRDUEUgfCBDT0VSQ1Iw X1JYVURQRSB8IFwKPiArCQkJCQkgQ09FUkNSMF9SWFRDUFY2IHwgQ09FUkNSMF9SWFVEUFY2KQo+ ICsjZGVmaW5lIFA0X0NPRVJDUjEJKDB4OTQpCj4gKwkjZGVmaW5lIENPRVJDUjFfSVBDRURQCQko MSA8PCAwKQo+ICsJI2RlZmluZSBDT0VSQ1IxX0lQVkVEUAkJKDEgPDwgMSkKPiArCSNkZWZpbmUg Q09FUkNSMV9WNlZFRFAJCSgxIDw8IDIpCj4gKwkjZGVmaW5lIENPRVJDUjFfVENQRURQCQkoMSA8 PCAzKQo+ICsJI2RlZmluZSBDT0VSQ1IxX1VEUEVEUAkJKDEgPDwgNCkKPiArCSNkZWZpbmUgQ09F UkNSMV9JQ01QRFAJCSgxIDw8IDUpCj4gKwkjZGVmaW5lIENPRVJDUjFfSUdNUERQCQkoMSA8PCA2 KQo+ICsJI2RlZmluZSBDT0VSQ1IxX0lDVjZEUAkJKDEgPDwgNykKPiArCSNkZWZpbmUgQ09FUkNS MV9SWDY0VEUJCSgxIDw8IDgpCj4gKwkjZGVmaW5lIENPRVJDUjFfUlhQUFBFCQkoMSA8PCA5KQo+ ICsJI2RlZmluZSBDT0VSQ1IxX1RDUDZEUAkJKDEgPDwgMTApCj4gKwkjZGVmaW5lIENPRVJDUjFf VURQNkRQCQkoMSA8PCAxMSkKPiArCSNkZWZpbmUgQ09FUkNSMV9JQzZEUAkJKDEgPDwgMTIpCj4g KwkjZGVmaW5lIENPRVJDUjFfSUc2RFAJCSgxIDw8IDEzKQo+ICsJI2RlZmluZSBDT0VSQ1IxX0lD VjY2RFAJCSgxIDw8IDE0KQo+ICsJI2RlZmluZSBDT0VSQ1IxX1JQQ0UJCSgxIDw8IDE1KQo+ICsK PiArCSNkZWZpbmUgQ09FUkNSMV9ERUZBVUxUCQkoQ09FUkNSMV9SWFBQUEUpCj4gKyNkZWZpbmUg UDRfQ09FVENSMAkoMHg5NikKPiArCSNkZWZpbmUgQ09FVENSMF9UWElQCQkoMSA8PCAwKQo+ICsJ I2RlZmluZSBDT0VUQ1IwX1RYVENQCQkoMSA8PCAxKQo+ICsJI2RlZmluZSBDT0VUQ1IwX1RYVURQ CQkoMSA8PCAyKQo+ICsJI2RlZmluZSBDT0VUQ1IwX1RYSUNNUAkJKDEgPDwgMykKPiArCSNkZWZp bmUgQ09FVENSMF9UWElHTVAJCSgxIDw8IDQpCj4gKwkjZGVmaW5lIENPRVRDUjBfVFhJQ1Y2CQko MSA8PCA1KQo+ICsJI2RlZmluZSBDT0VUQ1IwX1RYVENQVjYJCSgxIDw8IDgpCj4gKwkjZGVmaW5l IENPRVRDUjBfVFhVRFBWNgkJKDEgPDwgOSkKPiArCSNkZWZpbmUgQ09FVENSMF9UWElDTVY2CQko MSA8PCAxMCkKPiArCSNkZWZpbmUgQ09FVENSMF9UWElHTVY2CQkoMSA8PCAxMSkKPiArCSNkZWZp bmUgQ09FVENSMF9UWElDVjZWNgkoMSA8PCAxMikKPiArCj4gKwkjZGVmaW5lIENPRVRDUjBfREVG QVVMVAkJKENPRVRDUjBfVFhJUCB8IENPRVRDUjBfVFhUQ1AgfCBcCj4gKwkJCQkJIENPRVRDUjBf VFhVRFAgfCBDT0VUQ1IwX1RYVENQVjYgfCBcCj4gKwkJCQkJIENPRVRDUjBfVFhVRFBWNikKPiAr I2RlZmluZSBQNF9DT0VUQ1IxCSgweDk4KQo+ICsJI2RlZmluZSBDT0VUQ1IxX1RYNjRURQkJKDEg PDwgMCkKPiArCSNkZWZpbmUgQ09FVENSMV9UWFBQUEUJCSgxIDw8IDEpCj4gKwo+ICsjZGVmaW5l IFA0X0NPRUNFRFIJKDB4OUEpCj4gKyNkZWZpbmUgUDRfTDJDRUNSCSgweDlDKQo+ICsKPiArCS8q IERlZmluaXRpb24gb2YgUEFHRTUgKi8KPiArI2RlZmluZSBQNV9XRlRSCQkoMHhBMikKPiArCSNk ZWZpbmUgV0ZUUl8yTVMJCSgweDAxKQo+ICsJI2RlZmluZSBXRlRSXzRNUwkJKDB4MDIpCj4gKwkj ZGVmaW5lIFdGVFJfOE1TCQkoMHgwMykKPiArCSNkZWZpbmUgV0ZUUl8xNk1TCQkoMHgwNCkKPiAr CSNkZWZpbmUgV0ZUUl8zMk1TCQkoMHgwNSkKPiArCSNkZWZpbmUgV0ZUUl82NE1TCQkoMHgwNikK PiArCSNkZWZpbmUgV0ZUUl8xMjhNUwkJKDB4MDcpCj4gKwkjZGVmaW5lIFdGVFJfMjU2TVMJCSgw eDA4KQo+ICsJI2RlZmluZSBXRlRSXzUxMk1TCQkoMHgwOSkKPiArCSNkZWZpbmUgV0ZUUl8xMDI0 TVMJCSgweDBBKQo+ICsJI2RlZmluZSBXRlRSXzIwNDhNUwkJKDB4MEIpCj4gKwkjZGVmaW5lIFdG VFJfNDA5Nk1TCQkoMHgwQykKPiArCSNkZWZpbmUgV0ZUUl84MTkyTVMJCSgweDBEKQo+ICsJI2Rl ZmluZSBXRlRSXzE2Mzg0TVMJCSgweDBFKQo+ICsJI2RlZmluZSBXRlRSXzMyNzY4TVMJCSgweDBG KQo+ICsjZGVmaW5lIFA1X1dGQ0NSCSgweEE0KQo+ICsjZGVmaW5lIFA1X1dGQ1IwMwkoMHhBNikK PiArCSNkZWZpbmUgV0ZDUjAzX0YwX0VOCQkoMSA8PCAwKQo+ICsJI2RlZmluZSBXRkNSMDNfRjFf RU4JCSgxIDw8IDQpCj4gKwkjZGVmaW5lIFdGQ1IwM19GMl9FTgkJKDEgPDwgOCkKPiArCSNkZWZp bmUgV0ZDUjAzX0YzX0VOCQkoMSA8PCAxMikKPiArI2RlZmluZSBQNV9XRkNSNDcJKDB4QTgpCj4g KwkjZGVmaW5lIFdGQ1I0N19GNF9FTgkJKDEgPDwgMCkKPiArCSNkZWZpbmUgV0ZDUjQ3X0Y1X0VO CQkoMSA8PCA0KQo+ICsJI2RlZmluZSBXRkNSNDdfRjZfRU4JCSgxIDw8IDgpCj4gKwkjZGVmaW5l IFdGQ1I0N19GN19FTgkJKDEgPDwgMTIpCj4gKyNkZWZpbmUgUDVfV0YwQk1SMAkoMHhBQSkKPiAr I2RlZmluZSBQNV9XRjBCTVIxCSgweEFDKQo+ICsjZGVmaW5lIFA1X1dGMENSCSgweEFFKQo+ICsj ZGVmaW5lIFA1X1dGME9CUgkoMHhCMCkKPiArI2RlZmluZSBQNV9XRjFCTVIwCSgweEIyKQo+ICsj ZGVmaW5lIFA1X1dGMUJNUjEJKDB4QjQpCj4gKyNkZWZpbmUgUDVfV0YxQ1IJKDB4QjYpCj4gKyNk ZWZpbmUgUDVfV0YxT0JSCSgweEI4KQo+ICsjZGVmaW5lIFA1X1dGMkJNUjAJKDB4QkEpCj4gKyNk ZWZpbmUgUDVfV0YyQk1SMQkoMHhCQykKPiArCj4gKwkvKiBEZWZpbml0aW9uIG9mIFBBR0U2ICov Cj4gKyNkZWZpbmUgUDZfV0YyQ1IJKDB4QzIpCj4gKyNkZWZpbmUgUDZfV0YyT0JSCSgweEM0KQo+ ICsjZGVmaW5lIFA2X1dGM0JNUjAJKDB4QzYpCj4gKyNkZWZpbmUgUDZfV0YzQk1SMQkoMHhDOCkK PiArI2RlZmluZSBQNl9XRjNDUgkoMHhDQSkKPiArI2RlZmluZSBQNl9XRjNPQlIJKDB4Q0MpCj4g KyNkZWZpbmUgUDZfV0Y0Qk1SMAkoMHhDRSkKPiArI2RlZmluZSBQNl9XRjRCTVIxCSgweEQwKQo+ ICsjZGVmaW5lIFA2X1dGNENSCSgweEQyKQo+ICsjZGVmaW5lIFA2X1dGNE9CUgkoMHhENCkKPiAr I2RlZmluZSBQNl9XRjVCTVIwCSgweEQ2KQo+ICsjZGVmaW5lIFA2X1dGNUJNUjEJKDB4RDgpCj4g KyNkZWZpbmUgUDZfV0Y1Q1IJKDB4REEpCj4gKyNkZWZpbmUgUDZfV0Y1T0JSCSgweERDKQo+ICsK PiArLyogRGVmaW5pdGlvbiBvZiBQQUdFNyAqLwo+ICsjZGVmaW5lIFA3X1dGNkJNUjAJKDB4RTIp Cj4gKyNkZWZpbmUgUDdfV0Y2Qk1SMQkoMHhFNCkKPiArI2RlZmluZSBQN19XRjZDUgkoMHhFNikK PiArI2RlZmluZSBQN19XRjZPQlIJKDB4RTgpCj4gKyNkZWZpbmUgUDdfV0Y3Qk1SMAkoMHhFQSkK PiArI2RlZmluZSBQN19XRjdCTVIxCSgweEVDKQo+ICsjZGVmaW5lIFA3X1dGN0NSCSgweEVFKQo+ ICsjZGVmaW5lIFA3X1dGN09CUgkoMHhGMCkKPiArI2RlZmluZSBQN19XRlIwMQkoMHhGMikKPiAr I2RlZmluZSBQN19XRlIyMwkoMHhGNCkKPiArI2RlZmluZSBQN19XRlI0NQkoMHhGNikKPiArI2Rl ZmluZSBQN19XRlI2NwkoMHhGOCkKPiArI2RlZmluZSBQN19XRlBDMAkoMHhGQSkKPiArI2RlZmlu ZSBQN19XRlBDMQkoMHhGQykKPiArCj4gKwo+ICsvKiBUeCBoZWFkZXJzIHN0cnVjdHVyZSAqLwo+ ICtzdHJ1Y3QgdHhfc29wX2hlYWRlciB7Cj4gKwkvKiBiaXQgMTUtMTE6IGZsYWdzLCBiaXQgMTAt MDogcGFja2V0IGxlbmd0aCAqLwo+ICsJdTE2IGZsYWdzX2xlbjsKPiArCS8qIGJpdCAxNS0xMTog c2VxdWVuY2UgbnVtYmVyLCBiaXQgMTEtMDogcGFja2V0IGxlbmd0aCBiYXIgKi8KPiArCXUxNiBz ZXFfbGVuYmFyOwo+ICt9IF9fcGFja2VkOwo+ICsKPiArc3RydWN0IHR4X3NlZ21lbnRfaGVhZGVy IHsKPiArCS8qIGJpdCAxNS0xNDogZmxhZ3MsIGJpdCAxMy0xMTogc2VnbWVudCBudW1iZXIgKi8K PiArCS8qIGJpdCAxMC0wOiBzZWdtZW50IGxlbmd0aCAqLwo+ICsJdTE2IGZsYWdzX3NlcW51bV9z ZWdsZW47Cj4gKwkvKiBiaXQgMTUtMTQ6IGVuZCBvZmZzZXQsIGJpdCAxMy0xMTogc3RhcnQgb2Zm c2V0ICovCj4gKwkvKiBiaXQgMTAtMDogc2VnbWVudCBsZW5ndGggYmFyICovCj4gKwl1MTYgZW9f c29fc2VnbGVuYmFyOwo+ICt9IF9fcGFja2VkOwo+ICsKPiArc3RydWN0IHR4X2VvcF9oZWFkZXIg ewo+ICsJLyogYml0IDE1LTExOiBzZXF1ZW5jZSBudW1iZXIsIGJpdCAxMC0wOiBwYWNrZXQgbGVu Z3RoICovCj4gKwl1MTYgc2VxX2xlbjsKPiArCS8qIGJpdCAxNS0xMTogc2VxdWVuY2UgbnVtYmVy IGJhciwgYml0IDEwLTA6IHBhY2tldCBsZW5ndGggYmFyICovCj4gKwl1MTYgc2VxYmFyX2xlbmJh cjsKPiArfSBfX3BhY2tlZDsKPiArCj4gK3N0cnVjdCB0eF9wa3RfaW5mbyB7Cj4gKwlzdHJ1Y3Qg dHhfc29wX2hlYWRlciBzb3A7Cj4gKwlzdHJ1Y3QgdHhfc2VnbWVudF9oZWFkZXIgc2VnOwo+ICsJ c3RydWN0IHR4X2VvcF9oZWFkZXIgZW9wOwo+ICsJdTE2IHBrdF9sZW47Cj4gKwl1MTYgc2VxX251 bTsKPiArfSBfX3BhY2tlZDsKPiArCj4gKy8qIFJ4IGhlYWRlcnMgc3RydWN0dXJlICovCj4gK3N0 cnVjdCByeF9oZWFkZXIgewo+ICsJdTE2IGZsYWdzX2xlbjsKPiArCXUxNiBzZXFfbGVuYmFyOwo+ ICsJdTE2IGZsYWdzOwo+ICt9IF9fcGFja2VkOwo+ICsKPiArI2VuZGlmIC8qICNpZm5kZWYgX0FY ODg3OTZDX01BSU5fSCAqLwo+IGRpZmYgLS1naXQgYS9kcml2ZXJzL25ldC9ldGhlcm5ldC9hc2l4 L2F4ODg3OTZjX3NwaS5jIGIvZHJpdmVycy9uZXQvZXRoZXJuZXQvYXNpeC9heDg4Nzk2Y19zcGku Ywo+IG5ldyBmaWxlIG1vZGUgMTAwNjQ0Cj4gaW5kZXggMDAwMDAwMDAwMDAwLi41MzA0ZWIzM2Fh ZDIKPiAtLS0gL2Rldi9udWxsCj4gKysrIGIvZHJpdmVycy9uZXQvZXRoZXJuZXQvYXNpeC9heDg4 Nzk2Y19zcGkuYwo+IEBAIC0wLDAgKzEsMTAzIEBACj4gKy8vIFNQRFgtTGljZW5zZS1JZGVudGlm aWVyOiBHUEwtMi4wLW9ubHkKPiArLyoKPiArICogQ29weXJpZ2h0IChjKSAyMDEwIEFTSVggRWxl Y3Ryb25pY3MgQ29ycG9yYXRpb24KPiArICoKPiArICogQVNJWCBBWDg4Nzk2QyBTUEkgRmFzdCBF dGhlcm5ldCBMaW51eCBkcml2ZXIKPiArICovCj4gKwo+ICsjaW5jbHVkZSAiYXg4ODc5NmNfbWFp bi5oIgo+ICsjaW5jbHVkZSAiYXg4ODc5NmNfc3BpLmgiCj4gKwo+ICsvKiBkcml2ZXIgYnVzIG1h bmFnZW1lbnQgZnVuY3Rpb25zICovCj4gK3ZvaWQgYXhzcGlfd2FrZXVwKHN0cnVjdCBheHNwaV9k YXRhICpheF9zcGkpCj4gK3sKPiArCXU4IHR4X2J1ZjsKPiArCWludCByZXQ7Cj4gKwo+ICsJdHhf YnVmID0gQVhfU1BJQ01EX0VYSVRfUFdEOwkvKiBPUCAqLwo+ICsJcmV0ID0gc3BpX3dyaXRlKGF4 X3NwaS0+c3BpLCAmdHhfYnVmLCAxKTsKPiArCWlmIChyZXQpCj4gKwkJZGV2X2VycigmYXhfc3Bp LT5zcGktPmRldiwgIiVzKCkgZmFpbGVkOiByZXQgPSAlZFxuIiwgX19mdW5jX18sIHJldCk7Cj4g K30KPiArCj4gK3ZvaWQgYXhzcGlfcmVhZF9zdGF0dXMoc3RydWN0IGF4c3BpX2RhdGEgKmF4X3Nw aSwgc3RydWN0IHNwaV9zdGF0dXMgKnN0YXR1cykKPiArewo+ICsJdTggdHhfYnVmOwo+ICsJaW50 IHJldDsKPiArCj4gKwkvKiBPUCAqLwo+ICsJdHhfYnVmID0gQVhfU1BJQ01EX1JFQURfU1RBVFVT Owo+ICsJcmV0ID0gc3BpX3dyaXRlX3RoZW5fcmVhZChheF9zcGktPnNwaSwgJnR4X2J1ZiwgMSwg KHU4ICopJnN0YXR1cywgMyk7Cj4gKwlpZiAocmV0KQo+ICsJCWRldl9lcnIoJmF4X3NwaS0+c3Bp LT5kZXYsICIlcygpIGZhaWxlZDogcmV0ID0gJWRcbiIsIF9fZnVuY19fLCByZXQpOwo+ICsJZWxz ZQo+ICsJCWxlMTZfdG9fY3B1cygmc3RhdHVzLT5pc3IpOwo+ICt9Cj4gKwo+ICtpbnQgYXhzcGlf cmVhZF9yeHEoc3RydWN0IGF4c3BpX2RhdGEgKmF4X3NwaSwgdm9pZCAqZGF0YSwgaW50IGxlbikK PiArewo+ICsJc3RydWN0IHNwaV90cmFuc2ZlciAqeGZlciA9IGF4X3NwaS0+c3BpX3J4X3hmZXI7 Cj4gKwlpbnQgcmV0Owo+ICsKPiArCW1lbWNweShheF9zcGktPmNtZF9idWYsIHJ4X2NtZF9idWYs IDUpOwo+ICsKPiArCXhmZXItPnR4X2J1ZiA9IGF4X3NwaS0+Y21kX2J1ZjsKPiArCXhmZXItPnJ4 X2J1ZiA9IE5VTEw7Cj4gKwl4ZmVyLT5sZW4gPSBheF9zcGktPmNvbXAgPyAyIDogNTsKPiArCXhm ZXItPmJpdHNfcGVyX3dvcmQgPSA4Owo+ICsJc3BpX21lc3NhZ2VfYWRkX3RhaWwoeGZlciwgJmF4 X3NwaS0+cnhfbXNnKTsKPiArCj4gKwl4ZmVyKys7Cj4gKwl4ZmVyLT5yeF9idWYgPSBkYXRhOwo+ ICsJeGZlci0+dHhfYnVmID0gTlVMTDsKPiArCXhmZXItPmxlbiA9IGxlbjsKPiArCXhmZXItPmJp dHNfcGVyX3dvcmQgPSA4Owo+ICsJc3BpX21lc3NhZ2VfYWRkX3RhaWwoeGZlciwgJmF4X3NwaS0+ cnhfbXNnKTsKPiArCXJldCA9IHNwaV9zeW5jKGF4X3NwaS0+c3BpLCAmYXhfc3BpLT5yeF9tc2cp Owo+ICsJaWYgKHJldCkKPiArCQlkZXZfZXJyKCZheF9zcGktPnNwaS0+ZGV2LCAiJXMoKSBmYWls ZWQ6IHJldCA9ICVkXG4iLCBfX2Z1bmNfXywgcmV0KTsKPiArCj4gKwlyZXR1cm4gcmV0Owo+ICt9 Cj4gKwo+ICtpbnQgYXhzcGlfd3JpdGVfdHhxKHN0cnVjdCBheHNwaV9kYXRhICpheF9zcGksIHZv aWQgKmRhdGEsIGludCBsZW4pCj4gK3sKPiArCXJldHVybiBzcGlfd3JpdGUoYXhfc3BpLT5zcGks IGRhdGEsIGxlbik7Cj4gK30KPiArCj4gK3UxNiBheHNwaV9yZWFkX3JlZyhzdHJ1Y3QgYXhzcGlf ZGF0YSAqYXhfc3BpLCB1OCByZWcpCj4gK3sKPiArCXU4IHR4X2J1Zls0XTsKPiArCXUxNiByeF9i dWYgPSAwOwo+ICsJaW50IHJldDsKPiArCWludCBsZW4gPSBheF9zcGktPmNvbXAgPyAzIDogNDsK PiArCj4gKwl0eF9idWZbMF0gPSAweDAzOwkvKiBPUCBjb2RlIHJlYWQgcmVnaXN0ZXIgKi8KPiAr CXR4X2J1ZlsxXSA9IHJlZzsJLyogcmVnaXN0ZXIgYWRkcmVzcyAqLwo+ICsJdHhfYnVmWzJdID0g MHhGRjsJLyogZHVteSBjeWNsZSAqLwo+ICsJdHhfYnVmWzNdID0gMHhGRjsJLyogZHVteSBjeWNs ZSAqLwo+ICsJcmV0ID0gc3BpX3dyaXRlX3RoZW5fcmVhZChheF9zcGktPnNwaSwgdHhfYnVmLCBs ZW4sICh1OCAqKSZyeF9idWYsIDIpOwo+ICsJaWYgKHJldCkKPiArCQlkZXZfZXJyKCZheF9zcGkt PnNwaS0+ZGV2LCAiJXMoKSBmYWlsZWQ6IHJldCA9ICVkXG4iLCBfX2Z1bmNfXywgcmV0KTsKPiAr CWVsc2UKPiArCQlsZTE2X3RvX2NwdXMoJnJ4X2J1Zik7Cj4gKwo+ICsJcmV0dXJuIHJ4X2J1ZjsK PiArfQo+ICsKPiArdm9pZCBheHNwaV93cml0ZV9yZWcoc3RydWN0IGF4c3BpX2RhdGEgKmF4X3Nw aSwgdTggcmVnLCB1MTYgdmFsdWUpCj4gK3sKPiArCXU4IHR4X2J1Zls0XTsKPiArCWludCByZXQ7 Cj4gKwo+ICsJdHhfYnVmWzBdID0gQVhfU1BJQ01EX1dSSVRFX1JFRzsJLyogT1AgY29kZSByZWFk IHJlZ2lzdGVyICovCj4gKwl0eF9idWZbMV0gPSByZWc7CQkJLyogcmVnaXN0ZXIgYWRkcmVzcyAq Lwo+ICsJdHhfYnVmWzJdID0gdmFsdWU7Cj4gKwl0eF9idWZbM10gPSB2YWx1ZSA+PiA4Owo+ICsK PiArCXJldCA9IHNwaV93cml0ZShheF9zcGktPnNwaSwgdHhfYnVmLCA0KTsKPiArCWlmIChyZXQp Cj4gKwkJZGV2X2VycigmYXhfc3BpLT5zcGktPmRldiwgIiVzKCkgZmFpbGVkOiByZXQgPSAlZFxu IiwgX19mdW5jX18sIHJldCk7Cj4gKwoKUnVuIHRoZSBjaGVja3BhdGNoIHN0cmluZyBhbmQgZml4 IGFsbW9zdCBhbGwgaXNzdWVzIChleGNlcHQgb25lcyB5b3UKZGlzYWdyZWUpLgoKQmVzdCByZWdh cmRzLApLcnp5c3p0b2YKCl9fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19f X19fX19fCmxpbnV4LWFybS1rZXJuZWwgbWFpbGluZyBsaXN0CmxpbnV4LWFybS1rZXJuZWxAbGlz dHMuaW5mcmFkZWFkLm9yZwpodHRwOi8vbGlzdHMuaW5mcmFkZWFkLm9yZy9tYWlsbWFuL2xpc3Rp bmZvL2xpbnV4LWFybS1rZXJuZWwK