diff mbox

[RFC,1/2] mmc: core: support UHS-II in core stack.

Message ID 1419672479-30852-2-git-send-email-yi.y.sun@intel.com (mailing list archive)
State New, archived
Headers show

Commit Message

yisun1 Dec. 27, 2014, 9:27 a.m. UTC
This patch adds the UHS-II support in core layer. This is a RFC patch for
community review.

Signed-off-by: Yi Sun <yi.y.sun@intel.com>
---
 drivers/mmc/core/Makefile |    3 +-
 drivers/mmc/core/bus.c    |    5 +-
 drivers/mmc/core/core.c   |   89 ++++-
 drivers/mmc/core/sd.c     |   15 +
 drivers/mmc/core/sd_ops.c |   12 +
 drivers/mmc/core/uhs2.c   |  908 +++++++++++++++++++++++++++++++++++++++++++++
 drivers/mmc/core/uhs2.h   |   26 ++
 include/linux/mmc/core.h  |    6 +
 include/linux/mmc/host.h  |   27 ++
 include/linux/mmc/uhs2.h  |  274 ++++++++++++++
 10 files changed, 1356 insertions(+), 9 deletions(-)
 create mode 100644 drivers/mmc/core/uhs2.c
 create mode 100644 drivers/mmc/core/uhs2.h
 create mode 100644 include/linux/mmc/uhs2.h

Comments

Ulf Hansson Jan. 21, 2015, 10:31 a.m. UTC | #1
On 27 December 2014 at 10:27, Yi Sun <yi.y.sun@intel.com> wrote:
> This patch adds the UHS-II support in core layer. This is a RFC patch for
> community review.
>
> Signed-off-by: Yi Sun <yi.y.sun@intel.com>
> ---
>  drivers/mmc/core/Makefile |    3 +-
>  drivers/mmc/core/bus.c    |    5 +-
>  drivers/mmc/core/core.c   |   89 ++++-
>  drivers/mmc/core/sd.c     |   15 +
>  drivers/mmc/core/sd_ops.c |   12 +
>  drivers/mmc/core/uhs2.c   |  908 +++++++++++++++++++++++++++++++++++++++++++++
>  drivers/mmc/core/uhs2.h   |   26 ++
>  include/linux/mmc/core.h  |    6 +
>  include/linux/mmc/host.h  |   27 ++
>  include/linux/mmc/uhs2.h  |  274 ++++++++++++++
>  10 files changed, 1356 insertions(+), 9 deletions(-)
>  create mode 100644 drivers/mmc/core/uhs2.c
>  create mode 100644 drivers/mmc/core/uhs2.h
>  create mode 100644 include/linux/mmc/uhs2.h

Even if this an RFC, me and likely everybody else just stops from
reviewing this patch by looking at the above change log.

Is there a way to split it up?

Kind regards
Uffe

>
> diff --git a/drivers/mmc/core/Makefile b/drivers/mmc/core/Makefile
> index 38ed210..c0be0cb 100644
> --- a/drivers/mmc/core/Makefile
> +++ b/drivers/mmc/core/Makefile
> @@ -7,6 +7,7 @@ mmc_core-y                      := core.o bus.o host.o \
>                                    mmc.o mmc_ops.o sd.o sd_ops.o \
>                                    sdio.o sdio_ops.o sdio_bus.o \
>                                    sdio_cis.o sdio_io.o sdio_irq.o \
> -                                  quirks.o slot-gpio.o
> +                                  quirks.o slot-gpio.o \
> +                                  uhs2.o
>
>  mmc_core-$(CONFIG_DEBUG_FS)    += debugfs.o
> diff --git a/drivers/mmc/core/bus.c b/drivers/mmc/core/bus.c
> index 86d2711..6565754 100644
> --- a/drivers/mmc/core/bus.c
> +++ b/drivers/mmc/core/bus.c
> @@ -308,8 +308,9 @@ int mmc_add_card(struct mmc_card *card)
>         } else {
>                 pr_info("%s: new %s%s%s%s%s card at address %04x\n",
>                         mmc_hostname(card->host),
> -                       mmc_card_uhs(card) ? "ultra high speed " :
> -                       (mmc_card_hs(card) ? "high speed " : ""),
> +                       mmc_card_uhs2(card) ? "ultra high speed 2 " :
> +                       (mmc_card_uhs(card) ? "ultra high speed 1" :
> +                       (mmc_card_hs(card) ? "high speed " : "")),
>                         mmc_card_hs400(card) ? "HS400 " :
>                         (mmc_card_hs200(card) ? "HS200 " : ""),
>                         mmc_card_ddr52(card) ? "DDR " : "",
> diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
> index 9584bff..8a62063 100644
> --- a/drivers/mmc/core/core.c
> +++ b/drivers/mmc/core/core.c
> @@ -5,6 +5,7 @@
>   *  SD support Copyright (C) 2004 Ian Molton, All Rights Reserved.
>   *  Copyright (C) 2005-2008 Pierre Ossman, All Rights Reserved.
>   *  MMCv4 support Copyright (C) 2006 Philip Langdale, All Rights Reserved.
> + *  UHS2 support Copyright (C) 2014 Intel Corp, All Rights Reserved.
>   *
>   * This program is free software; you can redistribute it and/or modify
>   * it under the terms of the GNU General Public License version 2 as
> @@ -35,11 +36,13 @@
>  #include <linux/mmc/mmc.h>
>  #include <linux/mmc/sd.h>
>  #include <linux/mmc/slot-gpio.h>
> +#include <linux/mmc/uhs2.h>
>
>  #include "core.h"
>  #include "bus.h"
>  #include "host.h"
>  #include "sdio_bus.h"
> +#include "uhs2.h"
>
>  #include "mmc_ops.h"
>  #include "sd_ops.h"
> @@ -56,6 +59,7 @@
>
>  static struct workqueue_struct *workqueue;
>  static const unsigned freqs[] = { 400000, 300000, 200000, 100000 };
> +static const unsigned uhs2_freqs[] = { 52000000, 26000000 };
>
>  /*
>   * Enabling software CRCs on the data blocks can be a significant (30%)
> @@ -248,6 +252,12 @@ mmc_start_request(struct mmc_host *host, struct mmc_request *mrq)
>                         mrq->stop->mrq = mrq;
>                 }
>         }
> +
> +       if (host->flags & MMC_UHS2_SUPPORT &&
> +           host->flags & MMC_UHS2_INITIALIZED)
> +               if (mrq->cmd->uhs2_cmd == NULL)
> +                       uhs2_prepare_sd_cmd(host, mrq);
> +
>         mmc_host_clk_hold(host);
>         led_trigger_event(host->led, LED_FULL);
>         host->ops->request(host, mrq);
> @@ -385,7 +395,7 @@ static int mmc_wait_for_data_req_done(struct mmc_host *host,
>                                       struct mmc_request *mrq,
>                                       struct mmc_async_req *next_req)
>  {
> -       struct mmc_command *cmd;
> +       struct mmc_command *cmd = mrq->cmd;
>         struct mmc_context_info *context_info = &host->context_info;
>         int err;
>         unsigned long flags;
> @@ -400,7 +410,6 @@ static int mmc_wait_for_data_req_done(struct mmc_host *host,
>                 if (context_info->is_done_rcv) {
>                         context_info->is_done_rcv = false;
>                         context_info->is_new_req = false;
> -                       cmd = mrq->cmd;
>
>                         if (!cmd->error || !cmd->retries ||
>                             mmc_card_removed(host->card)) {
> @@ -424,6 +433,16 @@ static int mmc_wait_for_data_req_done(struct mmc_host *host,
>                         }
>                 }
>         }
> +
> +       if (cmd && cmd->uhs2_cmd) {
> +#ifdef CONFIG_MMC_DEBUG
> +               pr_info("%s: %s free uhs2_cmd!\n",
> +                       mmc_hostname(host), __func__);
> +#endif
> +               kfree(cmd->uhs2_cmd->payload);
> +               kfree(cmd->uhs2_cmd);
> +               cmd->uhs2_cmd = NULL;
> +       }
>         return err;
>  }
>
> @@ -464,6 +483,16 @@ static void mmc_wait_for_req_done(struct mmc_host *host,
>                 cmd->error = 0;
>                 host->ops->request(host, mrq);
>         }
> +
> +       if (cmd && cmd->uhs2_cmd) {
> +#ifdef CONFIG_MMC_DEBUG
> +               pr_info("%s: %s free uhs2_cmd!\n",
> +                       mmc_hostname(host), __func__);
> +#endif
> +               kfree(cmd->uhs2_cmd->payload);
> +               kfree(cmd->uhs2_cmd);
> +               cmd->uhs2_cmd = NULL;
> +       }
>  }
>
>  /**
> @@ -974,7 +1003,7 @@ EXPORT_SYMBOL(mmc_put_card);
>   * Internal function that does the actual ios call to the host driver,
>   * optionally printing some debug output.
>   */
> -static inline void mmc_set_ios(struct mmc_host *host)
> +void mmc_set_ios(struct mmc_host *host)
>  {
>         struct mmc_ios *ios = &host->ios;
>
> @@ -988,6 +1017,7 @@ static inline void mmc_set_ios(struct mmc_host *host)
>                 mmc_set_ungated(host);
>         host->ops->set_ios(host, ios);
>  }
> +EXPORT_SYMBOL(mmc_set_ios);
>
>  /*
>   * Control chip select pin on a host.
> @@ -1361,6 +1391,23 @@ int mmc_regulator_get_supply(struct mmc_host *mmc)
>                 dev_info(dev, "No vqmmc regulator found\n");
>         }
>
> +       if (!(mmc->caps & MMC_CAP_UHS2))
> +               return 0;
> +
> +       mmc->supply.vmmc2 = devm_regulator_get_optional(dev, "vmmc2");
> +       if (IS_ERR(mmc->supply.vmmc2)) {
> +               if (PTR_ERR(mmc->supply.vmmc2) == -EPROBE_DEFER)
> +                       return -EPROBE_DEFER;
> +               dev_info(dev, "No vmmc2 regulator found\n");
> +       } else {
> +               ret = mmc_regulator_get_ocrmask(mmc->supply.vmmc2);
> +               if (ret > 0)
> +                       mmc->ocr_avail_uhs2 = ret;
> +               else
> +                       dev_warn(dev, "Failed getting UHS2 OCR mask: %d\n",
> +                                       ret);
> +       }
> +
>         return 0;
>  }
>  EXPORT_SYMBOL_GPL(mmc_regulator_get_supply);
> @@ -1553,6 +1600,11 @@ void mmc_power_up(struct mmc_host *host, u32 ocr)
>         if (host->ios.power_mode == MMC_POWER_ON)
>                 return;
>
> +       if (host->flags & MMC_UHS2_SUPPORT) {
> +               uhs2_power_up(host);
> +               return;
> +       }
> +
>         mmc_host_clk_hold(host);
>
>         host->ios.vdd = fls(ocr) - 1;
> @@ -2287,7 +2339,9 @@ static int mmc_do_hw_reset(struct mmc_host *host, int check)
>         }
>
>         /* Set initial state and call mmc_set_ios */
> -       mmc_set_initial_state(host);
> +       /* TODO: need verify this for UHS2. */
> +       if (!host->flags & MMC_UHS2_SUPPORT)
> +               mmc_set_initial_state(host);
>
>         mmc_host_clk_release(host);
>
> @@ -2416,6 +2470,7 @@ void mmc_rescan(struct work_struct *work)
>         struct mmc_host *host =
>                 container_of(work, struct mmc_host, detect.work);
>         int i;
> +       int err;
>
>         if (host->trigger_card_event && host->ops->card_event) {
>                 host->ops->card_event(host);
> @@ -2470,6 +2525,27 @@ void mmc_rescan(struct work_struct *work)
>         }
>
>         mmc_claim_host(host);
> +       if (host->caps & MMC_CAP_UHS2) {
> +               /* Start to try UHS-II initialization from 52MHz to 26MHz
> +                * (RCLK range) per spec.
> +                */
> +               for (i = 0; i < ARRAY_SIZE(uhs2_freqs); i++) {
> +                       err = mmc_uhs2_try_frequency(host,
> +                               max(uhs2_freqs[i], host->f_min));
> +                       if (!err) {
> +                               mmc_release_host(host);
> +                               goto out;
> +                       } else if (err == UHS2_PHY_INIT_ERR)
> +                               /* UHS2 IF detect or Lane Sync error.
> +                                * Try legacy interface.
> +                                */
> +                               break;
> +
> +                       if (uhs2_freqs[i] <= host->f_min)
> +                               break;
> +               }
> +       }
> +
>         for (i = 0; i < ARRAY_SIZE(freqs); i++) {
>                 if (!mmc_rescan_try_freq(host, max(freqs[i], host->f_min)))
>                         break;
> @@ -2485,12 +2561,12 @@ void mmc_rescan(struct work_struct *work)
>
>  void mmc_start_host(struct mmc_host *host)
>  {
> -       host->f_init = max(freqs[0], host->f_min);
>         host->rescan_disable = 0;
>         host->ios.power_mode = MMC_POWER_UNDEFINED;
>         if (host->caps2 & MMC_CAP2_NO_PRESCAN_POWERUP)
>                 mmc_power_off(host);
> -       else
> +       /* Power up here will make UHS2 init ugly. */
> +       else if (!(host->caps & MMC_CAP_UHS2))
>                 mmc_power_up(host, host->ocr_avail);
>         mmc_gpiod_request_cd_irq(host);
>         _mmc_detect_change(host, 0, false);
> @@ -2573,6 +2649,7 @@ int mmc_power_restore_host(struct mmc_host *host)
>                 return -EINVAL;
>         }
>
> +       /* TODO: for UHS2, may execute UHS2 init process again. */
>         mmc_power_up(host, host->card->ocr);
>         ret = host->bus_ops->power_restore(host);
>
> diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c
> index d90a6de..d2000be 100644
> --- a/drivers/mmc/core/sd.c
> +++ b/drivers/mmc/core/sd.c
> @@ -969,6 +969,14 @@ static int mmc_sd_init_card(struct mmc_host *host, u32 ocr,
>         if (err)
>                 goto free_card;
>
> +       /* For UHS2, skip the UHS-I initialization. */
> +       /* TODO: shall we send CMD6 to set Maximum Power Consumption
> +        * to get better performance?
> +        */
> +       if ((host->flags & MMC_UHS2_SUPPORT) &&
> +           (host->flags & MMC_UHS2_INITIALIZED))
> +               goto uhs2_done;
> +
>         /* Initialization sequence for UHS-I cards */
>         if (rocr & SD_ROCR_S18A) {
>                 err = mmc_sd_init_uhs_card(card);
> @@ -1002,6 +1010,7 @@ static int mmc_sd_init_card(struct mmc_host *host, u32 ocr,
>                 }
>         }
>
> +uhs2_done:
>         host->card = card;
>         return 0;
>
> @@ -1118,6 +1127,9 @@ static int _mmc_sd_resume(struct mmc_host *host)
>         if (!mmc_card_suspended(host->card))
>                 goto out;
>
> +       /* TODO: for UHS2, may need UHS2 init process to be executed
> +        * again (DEVICE_INIT/ENUMERATE/CONFIG, etc).
> +        */
>         mmc_power_up(host, host->card->ocr);
>         err = mmc_sd_init_card(host, host->card->ocr, host->card);
>         mmc_card_clr_suspended(host->card);
> @@ -1185,6 +1197,9 @@ static int mmc_sd_power_restore(struct mmc_host *host)
>         int ret;
>
>         mmc_claim_host(host);
> +       /* TODO: for UHS2, may need UHS2 init process to be executed
> +        * again (DEVICE_INIT/ENUMERATE/CONFIG, etc).
> +        */
>         ret = mmc_sd_init_card(host, host->card->ocr, host->card);
>         mmc_release_host(host);
>
> diff --git a/drivers/mmc/core/sd_ops.c b/drivers/mmc/core/sd_ops.c
> index 48d0c93..fb2158f 100644
> --- a/drivers/mmc/core/sd_ops.c
> +++ b/drivers/mmc/core/sd_ops.c
> @@ -30,6 +30,18 @@ int mmc_app_cmd(struct mmc_host *host, struct mmc_card *card)
>         BUG_ON(!host);
>         BUG_ON(card && (card->host != host));
>
> +       /* UHS2 packet has APP bit so only set APP_CMD flag here.
> +        * Will set the APP bit when assembling UHS2 packet.
> +        */
> +       if (host->flags &  MMC_UHS2_SUPPORT &&
> +           host->flags & MMC_UHS2_INITIALIZED) {
> +#ifdef CONFIG_MMC_DEBUG
> +               pr_info("%s: it is app cmd, skip it!\n", mmc_hostname(host));
> +#endif
> +               host->flags |= MMC_UHS2_APP_CMD;
> +               return 0;
> +       }
> +
>         cmd.opcode = MMC_APP_CMD;
>
>         if (card) {
> diff --git a/drivers/mmc/core/uhs2.c b/drivers/mmc/core/uhs2.c
> new file mode 100644
> index 0000000..86a1dfa
> --- /dev/null
> +++ b/drivers/mmc/core/uhs2.c
> @@ -0,0 +1,908 @@
> +/*
> + *  linux/drivers/mmc/core/uhs2.c
> + *
> + *  Copyright (C) 2014 Intel Corp, All Rights Reserved.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +
> +#include <linux/err.h>
> +#include <linux/slab.h>
> +
> +#include <linux/mmc/host.h>
> +#include <linux/mmc/card.h>
> +#include <linux/mmc/mmc.h>
> +#include <linux/mmc/core.h>
> +#include <linux/mmc/sdio.h>
> +#include <linux/mmc/slot-gpio.h>
> +#include <linux/mmc/uhs2.h>
> +
> +#include "uhs2.h"
> +#include "mmc_ops.h"
> +#include "sd_ops.h"
> +#include "core.h"
> +
> +#define DBG(f, x...) \
> +       pr_warn("[%s()]: " f, __func__, ## x)
> +
> +/*
> + * TODO: payload, uhs2_cmd are all allocated which should be freed when
> + * response is got.
> + * resp is inputted outside which should be a variable created by caller
> + * so caller should handle it. For SD command, there is no uhs2_resp and
> + * response should be stored in resp of mmc_command.
> + */
> +int uhs2_cmd_assemble(struct mmc_command *cmd, u16 header, u16 arg,
> +                       u32 *payload, u8 plen, u8 *resp, u8 resp_len)
> +{
> +       struct uhs2_command *uhs2_cmd;
> +
> +       if (cmd == NULL || payload == NULL || resp == NULL)
> +               return -EIO;
> +
> +       uhs2_cmd = kzalloc(sizeof(struct uhs2_command),
> +                                               GFP_KERNEL);
> +       if (!uhs2_cmd) {
> +               kfree(payload);
> +               return -ENOMEM;
> +       }
> +
> +       uhs2_cmd->header = header;
> +       uhs2_cmd->arg = arg;
> +       uhs2_cmd->payload = payload;
> +       uhs2_cmd->payload_len = plen * sizeof(u32);
> +       uhs2_cmd->packet_len = uhs2_cmd->payload_len + 4;
> +
> +       cmd->uhs2_cmd = uhs2_cmd;
> +       cmd->uhs2_resp = resp;
> +       cmd->uhs2_resp_len = resp_len;
> +
> +#ifdef CONFIG_MMC_DEBUG
> +       pr_info("%s: uhs2_cmd->header = 0x%x, uhs2_cmd->arg = 0x%x,"
> +               " uhs2_cmd->payload_len = %d, uhs2_cmd->packet_len = %d,"
> +               " resp_len = %d.\n",
> +               __func__, uhs2_cmd->header,
> +               uhs2_cmd->arg, uhs2_cmd->payload_len, uhs2_cmd->packet_len,
> +               cmd->uhs2_resp_len);
> +#endif
> +
> +       return 0;
> +}
> +EXPORT_SYMBOL_GPL(uhs2_cmd_assemble);
> +
> +int uhs2_prepare_sd_cmd(struct mmc_host *host, struct mmc_request *mrq)
> +{
> +       struct mmc_command *cmd;
> +       u16 header = 0, arg = 0;
> +       u32 *payload;
> +       u8 plen = 0;
> +       int err = 0;
> +
> +       cmd = mrq->cmd;
> +       header = host->uhs2_dev_prop.node_id;
> +       if (cmd->flags & MMC_CMD_ADTC)
> +               header |= UHS2_PACKET_TYPE_DCMD;
> +       else
> +               header |= UHS2_PACKET_TYPE_CCMD;
> +       DBG("header = 0x%x.\n", header);
> +
> +       arg = cmd->opcode << UHS2_SD_CMD_INDEX_POS;
> +       if (host->flags & MMC_UHS2_APP_CMD) {
> +               arg |= UHS2_SD_CMD_APP;
> +               host->flags &= ~MMC_UHS2_APP_CMD;
> +       }
> +
> +       if (cmd->flags & MMC_CMD_ADTC) {
> +               /* TODO: do not understand. It may relates with ADMA3. */
> +               if (cmd->data->blocks > 1) {
> +                       payload = kzalloc(4*sizeof(u32), GFP_KERNEL);
> +                       if (!payload)
> +                               return -ENOMEM;
> +                       payload[2] = 0;
> +                       payload[3] = 0;
> +                       plen = 8 / sizeof(u32);
> +               } else {
> +                       payload = kzalloc(2*sizeof(u32), GFP_KERNEL);
> +                       if (!payload)
> +                               return -ENOMEM;
> +                       plen = 8 / sizeof(u32);
> +               }
> +
> +               if (host->flags & MMC_UHS2_2L_HD)
> +                       arg |= UHS2_DCMD_2L_HD_MODE;
> +
> +               arg |= UHS2_DCMD_LM_TLEN_EXIST;
> +
> +               if (cmd->data->blocks == 1 &&
> +                   cmd->opcode != MMC_READ_SINGLE_BLOCK &&
> +                   cmd->opcode != MMC_WRITE_BLOCK) {
> +                       arg |= UHS2_DCMD_TLUM_BYTE_MODE;
> +                       payload[1] = uhs2_dcmd_convert_msb(cmd->data->blksz);
> +               } else {
> +                       payload[1] = uhs2_dcmd_convert_msb(cmd->data->blocks);
> +               }
> +
> +               if (cmd->opcode == SD_IO_RW_EXTENDED) {
> +                       arg &= ~(UHS2_DCMD_LM_TLEN_EXIST |
> +                               UHS2_DCMD_TLUM_BYTE_MODE |
> +                               UHS2_NATIVE_DCMD_DAM_IO);
> +                       payload[1] = 0;
> +                       plen = 4 / sizeof(u32);
> +               }
> +       } else {
> +               payload = kzalloc(1 * sizeof(u32), GFP_KERNEL);
> +               if (!payload)
> +                       return -ENOMEM;
> +               plen = 4 / sizeof(u32);
> +       }
> +
> +       payload[0] = uhs2_dcmd_convert_msb(cmd->arg);
> +#ifdef CONFIG_MMC_DEBUG
> +       pr_info("%s: %s: sd_cmd->arg = 0x%x, payload[0]= 0x%x.\n",
> +                mmc_hostname(host), __func__, cmd->arg, payload[0]);
> +#endif
> +
> +       err = uhs2_cmd_assemble(cmd, header, arg, payload, plen,
> +                               NULL, 0);
> +
> +       return err;
> +}
> +EXPORT_SYMBOL_GPL(uhs2_prepare_sd_cmd);
> +
> +/*
> + * Apply power to the UHS2 stack.  This is a two-stage process.
> + * First, we enable power to the card without the clock running.
> + * We then wait a bit for the power to stabilise.  Finally,
> + * enable the bus drivers and clock to the card.
> + *
> + * We must _NOT_ enable the clock prior to power stablising.
> + *
> + * If a host does all the power sequencing itself, ignore the
> + * initial MMC_POWER_UP stage.
> + */
> +void uhs2_power_up(struct mmc_host *host)
> +{
> +       if (host->ios.power_mode == MMC_POWER_ON)
> +               return;
> +
> +       DBG("Enter!\n");
> +       mmc_host_clk_hold(host);
> +
> +       host->ios.vdd = fls(host->ocr_avail) - 1;
> +       host->ios.vdd2 = fls(host->ocr_avail_uhs2) - 1;
> +       if (mmc_host_is_spi(host))
> +               host->ios.chip_select = MMC_CS_HIGH;
> +       else
> +               host->ios.chip_select = MMC_CS_DONTCARE;
> +       host->ios.clock = host->f_init;
> +       host->ios.timing = MMC_TIMING_UHS2;
> +       host->ios.power_mode = MMC_POWER_ON;
> +       mmc_set_ios(host);
> +
> +       /*
> +        * This delay should be sufficient to allow the power supply
> +        * to reach the minimum voltage.
> +        */
> +       mmc_delay(10);
> +
> +       mmc_host_clk_release(host);
> +}
> +EXPORT_SYMBOL_GPL(uhs2_power_up);
> +
> +static int uhs2_dev_init(struct mmc_host *host)
> +{
> +       struct mmc_command cmd = {0};
> +       u32 cnt;
> +       u32 dap, gap, gap1;
> +       u16 header = 0, arg = 0;
> +       u32 *payload;
> +       u8 plen = 1;
> +       u8 gd = 0, cf = 1;
> +       u8 resp[6] = {0};
> +       u8 resp_len = 6;
> +       int err;
> +
> +       dap = host->uhs2_caps.dap;
> +       gap = host->uhs2_caps.gap;
> +       DBG("dap = 0x%x, gap = 0x%x.\n", dap, gap);
> +
> +       header = UHS2_NATIVE_PACKET | UHS2_PACKET_TYPE_CCMD;
> +       arg = ((UHS2_DEV_CMD_DEVICE_INIT & 0xFF) << 8) |
> +               UHS2_NATIVE_CMD_WRITE |
> +               UHS2_NATIVE_CMD_PLEN_4B |
> +               (UHS2_DEV_CMD_DEVICE_INIT >> 8);
> +
> +       payload = kcalloc(plen, sizeof(u32), GFP_KERNEL);
> +       if (!payload)
> +               return -ENOMEM;
> +       payload[0] = ((dap & 0xF) << 12) |
> +                 (cf << 11) |
> +                 ((gd & 0xF) << 4) |
> +                 (gap & 0xF);
> +
> +       err = uhs2_cmd_assemble(&cmd, header, arg, payload, plen,
> +                       resp, resp_len);
> +       if (err) {
> +               pr_err("%s: %s: UHS2 CMD assembling err = 0x%x!\n",
> +                       mmc_hostname(host), __func__, err);
> +               return -EIO;
> +       }
> +
> +       DBG("Begin DEVICE_INIT, header=0x%x, arg=0x%x, payload=0x%x.\n",
> +               header, arg, payload[0]);
> +       for (cnt = 0; cnt < 30; cnt++) {
> +               DBG("Sending DEVICE_INIT. Count = %d\n", cnt);
> +               err = mmc_wait_for_cmd(host, &cmd, 0);
> +               if (err) {
> +                       pr_err("%s: %s: UHS2 CMD send fail, err= 0x%x!\n",
> +                               mmc_hostname(host), __func__, err);
> +                       return -EIO;
> +               }
> +
> +#ifdef CONFIG_MMC_DEBUG
> +               int i;
> +
> +               pr_warn("%s: DEVICE_INIT response is: ", mmc_hostname(host));
> +               for (i = 0; i < resp_len; i++)
> +                       pr_warn("0x%x ", resp[i]);
> +               pr_warn("\n");
> +#endif
> +
> +               if (resp[3] != (UHS2_DEV_CMD_DEVICE_INIT & 0xFF)) {
> +                       pr_err("%s: DEVICE_INIT response is wrong!\n",
> +                               mmc_hostname(host));
> +                       return -EIO;
> +               }
> +
> +               if (resp[5] & 0x8) {
> +                       DBG("CF is set, device is initialized!\n");
> +                       host->group_desc = gd;
> +               } else {
> +                       gap1 = resp[4] & 0x0F;
> +                       if (gap == gap1)
> +                               gd++;
> +               }
> +       }
> +       if (30 == cnt) {
> +               pr_err("%s: DEVICE_INIT fail, already 30 times!\n",
> +                       mmc_hostname(host));
> +               return -EIO;
> +       }
> +
> +       return 0;
> +}
> +
> +static int uhs2_enum(struct mmc_host *host)
> +{
> +       struct mmc_command cmd = {0};
> +       u16 header = 0, arg = 0;
> +       u32 *payload;
> +       u8 plen = 1;
> +       u8 id_f = 0xF, id_l = 0x0;
> +       u8 resp[8] = {0};
> +       u8 resp_len = 8;
> +       int err;
> +
> +       header = UHS2_NATIVE_PACKET | UHS2_PACKET_TYPE_CCMD;
> +       arg = ((UHS2_DEV_CMD_ENUMERATE & 0xFF) << 8) |
> +               UHS2_NATIVE_CMD_WRITE |
> +               UHS2_NATIVE_CMD_PLEN_4B |
> +               (UHS2_DEV_CMD_ENUMERATE >> 8);
> +
> +       payload = kcalloc(plen, sizeof(u32), GFP_KERNEL);
> +       if (!payload)
> +               return -ENOMEM;
> +       payload[0] = (id_f << 4) | id_l;
> +
> +       DBG("Begin ENUMERATE, header=0x%x, arg=0x%x, payload=0x%x.\n",
> +               header, arg, payload[0]);
> +       err = uhs2_cmd_assemble(&cmd, header, arg, payload, plen,
> +                               resp, resp_len);
> +       if (err) {
> +               pr_err("%s: %s: UHS2 CMD assembling err = 0x%x!\n",
> +                       mmc_hostname(host), __func__, err);
> +               return -EIO;
> +       }
> +
> +       err = mmc_wait_for_cmd(host, &cmd, 0);
> +       if (err) {
> +               pr_err("%s: %s: UHS2 CMD send fail, err= 0x%x!\n",
> +                       mmc_hostname(host), __func__, err);
> +               return -EIO;
> +       }
> +
> +#ifdef CONFIG_MMC_DEBUG
> +       int i;
> +
> +       pr_warn("%s: ENUMERATE response is: ", mmc_hostname(host));
> +       for (i = 0; i < resp_len; i++)
> +               pr_warn("0x%x ", resp[i]);
> +       pr_warn("\n");
> +#endif
> +
> +       if (resp[3] != (UHS2_DEV_CMD_ENUMERATE & 0xFF)) {
> +               pr_err("%s: ENUMERATE response is wrong!\n",
> +                       mmc_hostname(host));
> +               return -EIO;
> +       }
> +
> +       /* TODO: shall I keep id_f or id_l as device node id?
> +        * For P2P connection, I think id_f is ok.
> +        */
> +       id_f = (resp[4] >> 4) & 0xF;
> +       id_l = resp[4] & 0xF;
> +       DBG("id_f = %d, id_l = %d.\n", id_f, id_l);
> +       DBG("Enumerate Cmd Completed. No. of Devices connected = %d\n",
> +               id_l - id_f + 1);
> +       host->uhs2_dev_prop.node_id = id_f;
> +
> +       return 0;
> +}
> +
> +static int uhs2_config_read(struct mmc_host *host)
> +{
> +       struct mmc_command cmd = {0};
> +       u16 header = 0, arg = 0;
> +       u32 cap;
> +       int err;
> +
> +       DBG("INQUIRY_CFG: read Generic Caps.\n");
> +       header = UHS2_NATIVE_PACKET | UHS2_PACKET_TYPE_CCMD;
> +       arg = ((UHS2_DEV_CONFIG_GEN_CAPS & 0xFF) << 8) |
> +               UHS2_NATIVE_CMD_READ |
> +               UHS2_NATIVE_CMD_PLEN_4B |
> +               (UHS2_DEV_CONFIG_GEN_CAPS >> 8);
> +
> +       DBG("Begin INQUIRY_CFG, header=0x%x, arg=0x%x.\n",
> +               header, arg);
> +       /* There is no payload because per spec, there should be
> +        * no payload field for read CCMD.
> +        * Plen is set in arg. Per spec, plen for read CCMD
> +        * represents the len of read data which is assigned in payload
> +        * of following RES (p136).
> +        */
> +       err = uhs2_cmd_assemble(&cmd, header, arg, NULL, 0,
> +                               NULL, 0);
> +       if (err) {
> +               pr_err("%s: %s: UHS2 CMD assembling err = 0x%x!\n",
> +                       mmc_hostname(host), __func__, err);
> +               return -EIO;
> +       }
> +
> +       err = mmc_wait_for_cmd(host, &cmd, 0);
> +       if (err) {
> +               pr_err("%s: %s: UHS2 CMD send fail, err= 0x%x!\n",
> +                       mmc_hostname(host), __func__, err);
> +               return -EIO;
> +       }
> +
> +#ifdef CONFIG_MMC_DEBUG
> +       int i;
> +
> +       pr_warn("%s: INQUIRY_CFG generic response is: ", mmc_hostname(host));
> +       for (i = 0; i < 2; i++)
> +               pr_warn("0x%x ", cmd.resp[i]);
> +       pr_warn("\n");
> +#endif
> +
> +       cap = cmd.resp[0];
> +       DBG("Device Generic Caps (0-31) is: 0x%x.\n", cap);
> +       host->uhs2_dev_prop.n_lanes = (cap >> UHS2_DEV_CONFIG_N_LANES_POS) &
> +                                       UHS2_DEV_CONFIG_N_LANES_MASK;
> +       host->uhs2_dev_prop.dadr_len = (cap >> UHS2_DEV_CONFIG_DADR_POS) &
> +                                       UHS2_DEV_CONFIG_DADR_MASK;
> +       host->uhs2_dev_prop.app_type = (cap >> UHS2_DEV_CONFIG_APP_POS) &
> +                                       UHS2_DEV_CONFIG_APP_MASK;
> +
> +       DBG("INQUIRY_CFG: read PHY Caps.\n");
> +       arg = ((UHS2_DEV_CONFIG_PHY_CAPS & 0xFF) << 8) |
> +               UHS2_NATIVE_CMD_READ |
> +               UHS2_NATIVE_CMD_PLEN_8B |
> +               (UHS2_DEV_CONFIG_PHY_CAPS >> 8);
> +
> +       DBG("Begin INQUIRY_CFG, header=0x%x, arg=0x%x.\n",
> +               header, arg);
> +       err = uhs2_cmd_assemble(&cmd, header, arg, NULL, 0,
> +                               NULL, 0);
> +       if (err) {
> +               pr_err("%s: %s: UHS2 CMD assembling err = 0x%x!\n",
> +                       mmc_hostname(host), __func__, err);
> +               return -EIO;
> +       }
> +
> +       err = mmc_wait_for_cmd(host, &cmd, 0);
> +       if (err) {
> +               pr_err("%s: %s: UHS2 CMD send fail, err= 0x%x!\n",
> +                       mmc_hostname(host), __func__, err);
> +               return -EIO;
> +       }
> +
> +#ifdef CONFIG_MMC_DEBUG
> +       pr_warn("%s: INQUIRY_CFG PHY response is: ", mmc_hostname(host));
> +       for (i = 0; i < 2; i++)
> +               pr_warn("0x%x ", cmd.resp[i]);
> +       pr_warn("\n");
> +#endif
> +
> +       cap = cmd.resp[0];
> +       DBG("Device PHY Caps (0-31) is: 0x%x.\n", cap);
> +       host->uhs2_dev_prop.phy_minor_rev = cap &
> +                                       UHS2_DEV_CONFIG_PHY_MINOR_MASK;
> +       host->uhs2_dev_prop.phy_major_rev = (cap >>
> +                                       UHS2_DEV_CONFIG_PHY_MAJOR_POS) &
> +                                       UHS2_DEV_CONFIG_PHY_MAJOR_MASK;
> +       host->uhs2_dev_prop.can_hibernate = (cap >>
> +                                       UHS2_DEV_CONFIG_CAN_HIBER_POS) &
> +                                       UHS2_DEV_CONFIG_CAN_HIBER_MASK;
> +
> +       cap = cmd.resp[1];
> +       DBG("Device PHY Caps (32-63) is: 0x%x.\n", cap);
> +       host->uhs2_dev_prop.n_lss_sync = cap & UHS2_DEV_CONFIG_N_LSS_SYN_MASK;
> +       host->uhs2_dev_prop.n_lss_dir = (cap >>
> +                                       UHS2_DEV_CONFIG_N_LSS_DIR_POS) &
> +                                       UHS2_DEV_CONFIG_N_LSS_DIR_MASK;
> +       if (host->uhs2_dev_prop.n_lss_sync == 0)
> +               host->uhs2_dev_prop.n_lss_sync = 16 << 2;
> +       else
> +               host->uhs2_dev_prop.n_lss_sync <<= 2;
> +
> +       if (host->uhs2_dev_prop.n_lss_dir == 0)
> +               host->uhs2_dev_prop.n_lss_dir = 16 << 3;
> +       else
> +               host->uhs2_dev_prop.n_lss_dir <<= 3;
> +
> +       DBG("INQUIRY_CFG: read LINK-TRAN Caps.\n");
> +       arg = ((UHS2_DEV_CONFIG_LINK_TRAN_CAPS & 0xFF) << 8) |
> +               UHS2_NATIVE_CMD_READ |
> +               UHS2_NATIVE_CMD_PLEN_8B |
> +               (UHS2_DEV_CONFIG_LINK_TRAN_CAPS >> 8);
> +
> +       DBG("Begin INQUIRY_CFG, header=0x%x, arg=0x%x.\n",
> +               header, arg);
> +       err = uhs2_cmd_assemble(&cmd, header, arg, NULL, 0,
> +                               NULL, 0);
> +       if (err) {
> +               pr_err("%s: %s: UHS2 CMD assembling err = 0x%x!\n",
> +                       mmc_hostname(host), __func__, err);
> +               return -EIO;
> +       }
> +
> +       err = mmc_wait_for_cmd(host, &cmd, 0);
> +       if (err) {
> +               pr_err("%s: %s: UHS2 CMD send fail, err= 0x%x!\n",
> +                       mmc_hostname(host), __func__, err);
> +               return -EIO;
> +       }
> +
> +#ifdef CONFIG_MMC_DEBUG
> +       pr_warn("%s: INQUIRY_CFG Link-Tran response is: ", mmc_hostname(host));
> +       for (i = 0; i < 2; i++)
> +               pr_warn("0x%x ", cmd.resp[i]);
> +       pr_warn("\n");
> +#endif
> +
> +       cap = cmd.resp[0];
> +       DBG("Device LINK-TRAN Caps (0-31) is: 0x%x.\n", cap);
> +       host->uhs2_dev_prop.link_minor_rev = cap &
> +                                       UHS2_DEV_CONFIG_LT_MINOR_MASK;
> +       host->uhs2_dev_prop.link_major_rev = (cap >>
> +                                       UHS2_DEV_CONFIG_LT_MAJOR_POS) &
> +                                       UHS2_DEV_CONFIG_LT_MAJOR_MASK;
> +       host->uhs2_dev_prop.n_fcu = (cap >> UHS2_DEV_CONFIG_N_FCU_POS) &
> +                                       UHS2_DEV_CONFIG_N_FCU_MASK;
> +       host->uhs2_dev_prop.dev_type = (cap >> UHS2_DEV_CONFIG_DEV_TYPE_POS) &
> +                                       UHS2_DEV_CONFIG_DEV_TYPE_MASK;
> +       host->uhs2_dev_prop.maxblk_len = (cap >>
> +                                       UHS2_DEV_CONFIG_MAX_BLK_LEN_POS) &
> +                                       UHS2_DEV_CONFIG_MAX_BLK_LEN_MASK;
> +
> +       cap = cmd.resp[1];
> +       DBG("Device LINK-TRAN Caps (32-63) is: 0x%x.\n", cap);
> +       host->uhs2_dev_prop.n_data_gap = cap & UHS2_DEV_CONFIG_N_DATA_GAP_MASK;
> +       if (host->uhs2_dev_prop.n_fcu == 0)
> +               host->uhs2_dev_prop.n_fcu = 256;
> +
> +       return 0;
> +}
> +
> +static int uhs2_config_write(struct mmc_host *host)
> +{
> +       struct mmc_command cmd = {0};
> +       u16 header = 0, arg = 0;
> +       u32 *payload;
> +       u8 plen = 1;
> +       int err;
> +       u8 resp[5] = {0};
> +       u8 resp_len = 5;
> +
> +       BUG_ON(!host->ops->uhs2_set_reg);
> +
> +       DBG("SET_COMMON_CFG: write Generic Settings.\n");
> +       header = UHS2_NATIVE_PACKET | UHS2_PACKET_TYPE_CCMD;
> +       arg = ((UHS2_DEV_CONFIG_GEN_SET & 0xFF) << 8) |
> +               UHS2_NATIVE_CMD_WRITE |
> +               UHS2_NATIVE_CMD_PLEN_4B |
> +               (UHS2_DEV_CONFIG_GEN_SET >> 8);
> +
> +       if (host->uhs2_dev_prop.n_lanes == UHS2_DEV_CONFIG_2L_HD_FD &&
> +           host->uhs2_caps.n_lanes == UHS2_DEV_CONFIG_2L_HD_FD) {
> +               /* Support HD */
> +               DBG("Both Host and device support 2L-HD.\n");
> +               host->flags |= MMC_UHS2_2L_HD;
> +               host->uhs2_caps.n_lanes_set = UHS2_DEV_CONFIG_GEN_SET_2L_FD_HD;
> +               host->uhs2_dev_prop.n_lanes_set =
> +                               UHS2_DEV_CONFIG_GEN_SET_2L_FD_HD;
> +       } else {
> +               /* Only support 2L-FD so far */
> +               host->flags &= ~MMC_UHS2_2L_HD;
> +               host->uhs2_caps.n_lanes_set = UHS2_DEV_CONFIG_GEN_SET_2L_FD_HD;
> +               host->uhs2_dev_prop.n_lanes_set =
> +                               UHS2_DEV_CONFIG_GEN_SET_2L_FD_HD;
> +       }
> +       payload = kcalloc(plen, sizeof(u32), GFP_KERNEL);
> +       payload[0] = host->uhs2_dev_prop.n_lanes_set <<
> +                       UHS2_DEV_CONFIG_N_LANES_POS;
> +       DBG("Begin SET_COMMON_CFG, header=0x%x, arg=0x%x, payload=0x%x.\n",
> +               header, arg, payload[0]);
> +       /* There is no payload because per spec, there should be
> +        * no payload field for read CCMD.
> +        * Plen is set in arg. Per spec, plen for read CCMD
> +        * represents the len of read data which is assigned in payload
> +        * of following RES (p136).
> +        */
> +       err = uhs2_cmd_assemble(&cmd, header, arg, payload, plen,
> +                               NULL, 0);
> +       if (err) {
> +               pr_err("%s: %s: UHS2 CMD assembling err = 0x%x!\n",
> +                       mmc_hostname(host), __func__, err);
> +               return -EIO;
> +       }
> +
> +       err = mmc_wait_for_cmd(host, &cmd, 0);
> +       if (err) {
> +               pr_err("%s: %s: UHS2 CMD send fail, err= 0x%x!\n",
> +                       mmc_hostname(host), __func__, err);
> +               return -EIO;
> +       }
> +
> +       DBG("SET_COMMON_CFG: PHY Settings.\n");
> +       arg = ((UHS2_DEV_CONFIG_PHY_SET & 0xFF) << 8) |
> +               UHS2_NATIVE_CMD_READ |
> +               UHS2_NATIVE_CMD_PLEN_8B |
> +               (UHS2_DEV_CONFIG_PHY_SET >> 8);
> +
> +       plen = 2;
> +       payload = kcalloc(plen, sizeof(u32), GFP_KERNEL);
> +
> +       if (host->uhs2_caps.speed_range ==
> +               UHS2_DEV_CONFIG_PHY_SET_SPEED_B) {
> +               host->flags |= MMC_UHS2_SPEED_B;
> +               host->uhs2_dev_prop.speed_range_set =
> +                       UHS2_DEV_CONFIG_PHY_SET_SPEED_B;
> +       } else {
> +               host->uhs2_dev_prop.speed_range_set =
> +                       UHS2_DEV_CONFIG_PHY_SET_SPEED_A;
> +               host->flags &= ~MMC_UHS2_SPEED_B;
> +       }
> +       payload[0] = host->uhs2_dev_prop.speed_range_set <<
> +                       UHS2_DEV_CONFIG_PHY_SET_SPEED_POS;
> +
> +       host->uhs2_dev_prop.n_lss_sync_set =
> +               (min(host->uhs2_dev_prop.n_lss_sync,
> +               host->uhs2_caps.n_lss_sync) >> 2) &
> +               UHS2_DEV_CONFIG_N_LSS_SYN_MASK;
> +       host->uhs2_caps.n_lss_sync_set = host->uhs2_dev_prop.n_lss_sync_set;
> +
> +       host->uhs2_dev_prop.n_lss_dir_set =
> +               (min(host->uhs2_dev_prop.n_lss_dir,
> +               host->uhs2_caps.n_lss_dir) >> 3) &
> +               UHS2_DEV_CONFIG_N_LSS_DIR_MASK;
> +       host->uhs2_caps.n_lss_dir_set = host->uhs2_dev_prop.n_lss_dir_set;
> +       payload[1] = (host->uhs2_dev_prop.n_lss_dir_set <<
> +                       UHS2_DEV_CONFIG_N_LSS_DIR_POS) |
> +                       host->uhs2_dev_prop.n_lss_sync_set;
> +
> +       DBG("Begin SET_COMMON_CFG, header=0x%x, arg=0x%x, payload[0]=0x%x,"
> +               " payload[1] = 0x%x.\n",
> +               header, arg, payload[0], payload[1]);
> +
> +       err = uhs2_cmd_assemble(&cmd, header, arg, payload, plen,
> +                               NULL, 0);
> +       if (err) {
> +               pr_err("%s: %s: UHS2 CMD assembling err = 0x%x!\n",
> +                       mmc_hostname(host), __func__, err);
> +               return -EIO;
> +       }
> +
> +       err = mmc_wait_for_cmd(host, &cmd, 0);
> +       if (err) {
> +               pr_err("%s: %s: UHS2 CMD send fail, err= 0x%x!\n",
> +                       mmc_hostname(host), __func__, err);
> +               return -EIO;
> +       }
> +
> +       DBG("SET_COMMON_CFG: LINK-TRAN Settings.\n");
> +       arg = ((UHS2_DEV_CONFIG_LINK_TRAN_SET & 0xFF) << 8) |
> +               UHS2_NATIVE_CMD_WRITE |
> +               UHS2_NATIVE_CMD_PLEN_8B |
> +               (UHS2_DEV_CONFIG_LINK_TRAN_SET >> 8);
> +
> +       plen = 2;
> +       payload = kcalloc(plen, sizeof(u32), GFP_KERNEL);
> +
> +       if (host->uhs2_dev_prop.app_type == UHS2_DEV_CONFIG_APP_SD_MEM)
> +               host->uhs2_dev_prop.maxblk_len_set =
> +                       UHS2_DEV_CONFIG_LT_SET_MAX_BLK_LEN;
> +       else
> +               host->uhs2_dev_prop.maxblk_len_set =
> +                       min(host->uhs2_dev_prop.maxblk_len,
> +                       host->uhs2_caps.maxblk_len);
> +       host->uhs2_caps.maxblk_len_set = host->uhs2_dev_prop.maxblk_len_set;
> +
> +       host->uhs2_dev_prop.n_fcu_set =
> +               min(host->uhs2_dev_prop.n_fcu,
> +               host->uhs2_caps.n_fcu);
> +       host->uhs2_caps.n_fcu_set = host->uhs2_dev_prop.n_fcu_set;
> +
> +       host->uhs2_dev_prop.n_data_gap_set =
> +               min(host->uhs2_caps.n_data_gap,
> +               host->uhs2_dev_prop.n_data_gap);
> +       host->uhs2_caps.n_data_gap_set = host->uhs2_dev_prop.n_data_gap_set;
> +
> +       host->uhs2_caps.max_retry_set = 3;
> +       host->uhs2_dev_prop.max_retry_set = host->uhs2_caps.max_retry_set;
> +
> +       payload[0] = (host->uhs2_dev_prop.maxblk_len_set <<
> +                       UHS2_DEV_CONFIG_MAX_BLK_LEN_POS) |
> +                       (host->uhs2_dev_prop.max_retry_set <<
> +                       UHS2_DEV_CONFIG_LT_SET_MAX_RETRY_POS) |
> +                       (host->uhs2_dev_prop.n_fcu_set <<
> +                       UHS2_DEV_CONFIG_N_FCU_POS);
> +       payload[1] = host->uhs2_dev_prop.n_data_gap_set;
> +
> +       DBG("Begin SET_COMMON_CFG, header=0x%x, arg=0x%x, payload[0] = 0x%x,"
> +               " payload[1] = 0x%x.\n",
> +               header, arg, payload[0], payload[1]);
> +       err = uhs2_cmd_assemble(&cmd, header, arg, payload, plen,
> +                               NULL, 0);
> +       if (err) {
> +               pr_err("%s: %s: UHS2 CMD assembling err = 0x%x!\n",
> +                       mmc_hostname(host), __func__, err);
> +               return -EIO;
> +       }
> +
> +       err = mmc_wait_for_cmd(host, &cmd, 0);
> +       if (err) {
> +               pr_err("%s: %s: UHS2 CMD send fail, err= 0x%x!\n",
> +                       mmc_hostname(host), __func__, err);
> +               return -EIO;
> +       }
> +
> +       DBG("SET_COMMON_CFG: Set Config Completion.\n");
> +       arg = (((UHS2_DEV_CONFIG_GEN_SET + 1) & 0xFF) << 8) |
> +               UHS2_NATIVE_CMD_WRITE |
> +               UHS2_NATIVE_CMD_PLEN_4B |
> +               ((UHS2_DEV_CONFIG_GEN_SET + 1) >> 8);
> +
> +       plen = 1;
> +       payload = kcalloc(plen, sizeof(u32), GFP_KERNEL);
> +       payload[0] = UHS2_DEV_CONFIG_GEN_SET_CFG_COMPLETE;
> +
> +       DBG("Begin SET_COMMON_CFG, header=0x%x, arg=0x%x, payload[0] = 0x%x.\n",
> +               header, arg, payload[0]);
> +       err = uhs2_cmd_assemble(&cmd, header, arg, payload, plen,
> +                               resp, resp_len);
> +       if (err) {
> +               pr_err("%s: %s: UHS2 CMD assembling err = 0x%x!\n",
> +                       mmc_hostname(host), __func__, err);
> +               return -EIO;
> +       }
> +
> +       err = mmc_wait_for_cmd(host, &cmd, 0);
> +       if (err) {
> +               pr_err("%s: %s: UHS2 CMD send fail, err= 0x%x!\n",
> +                       mmc_hostname(host), __func__, err);
> +               return -EIO;
> +       }
> +
> +       if ((resp[4] & 0x80) != 0x80) {
> +               pr_err("%s: %s: Config Complete is not set!\n",
> +                       mmc_hostname(host), __func__);
> +               return -EIO;
> +       }
> +
> +       /* Set host Config Setting registers */
> +       if (host->ops->uhs2_set_reg(host, SET_CONFIG)) {
> +               pr_err("%s: %s: UHS2 SET_CONFIG fail!\n",
> +                       mmc_hostname(host), __func__);
> +               return -EIO;
> +       }
> +
> +       return 0;
> +}
> +
> +static int uhs2_go_dormant(struct mmc_host *host, bool hibernate)
> +{
> +       struct mmc_command cmd = {0};
> +       u16 header = 0, arg = 0;
> +       u32 *payload;
> +       u8 plen = 1;
> +       int err;
> +
> +       BUG_ON(!host->ops->uhs2_set_reg);
> +
> +       /* Disable Normal INT */
> +       if (host->ops->uhs2_set_reg(host, DISABLE_INT)) {
> +               pr_err("%s: %s: UHS2 DISABLE_INT fail!\n",
> +                       mmc_hostname(host), __func__);
> +               return -EIO;
> +       }
> +
> +       /* TODO: shall I use host->uhs2_dev_prop.node_id here? */
> +       header = UHS2_NATIVE_PACKET | UHS2_PACKET_TYPE_CCMD |
> +               host->uhs2_dev_prop.node_id;
> +
> +       arg = ((UHS2_DEV_CMD_GO_DORMANT_STATE & 0xFF) << 8) |
> +               UHS2_NATIVE_CMD_WRITE |
> +               UHS2_NATIVE_CMD_PLEN_4B |
> +               (UHS2_DEV_CMD_GO_DORMANT_STATE >> 8);
> +
> +       payload = kcalloc(plen, sizeof(u32), GFP_KERNEL);
> +       if (!payload)
> +               return -ENOMEM;
> +       if (hibernate)
> +               payload[0] = UHS2_DEV_CMD_DORMANT_HIBER;
> +
> +       DBG("Begin GO_DORMANT_STATE, header=0x%x, arg=0x%x, payload=0x%x.\n",
> +               header, arg, payload[0]);
> +       err = uhs2_cmd_assemble(&cmd, header, arg, payload, plen,
> +                               NULL, 0);
> +       if (err) {
> +               pr_err("%s: %s: UHS2 CMD assembling err = 0x%x!\n",
> +                       mmc_hostname(host), __func__, err);
> +               return -EIO;
> +       }
> +
> +       err = mmc_wait_for_cmd(host, &cmd, 0);
> +       if (err) {
> +               pr_err("%s: %s: UHS2 CMD send fail, err= 0x%x!\n",
> +                       mmc_hostname(host), __func__, err);
> +               return -EIO;
> +       }
> +
> +       /* Check Dormant State in Present */
> +       if (host->ops->uhs2_set_reg(host, CHECK_DORMANT)) {
> +               pr_err("%s: %s: UHS2 GO_DORMANT_STATE fail!\n",
> +                       mmc_hostname(host), __func__);
> +               return -EIO;
> +       }
> +
> +       host->ios.clock = 0;
> +       if (hibernate)
> +               host->ios.vdd = -1;
> +       mmc_set_ios(host);
> +
> +       return 0;
> +}
> +
> +static int uhs2_change_speed(struct mmc_host *host)
> +{
> +       int err;
> +
> +       BUG_ON(!host->ops->uhs2_detect_init);
> +       BUG_ON(!host->ops->uhs2_set_reg);
> +
> +       err = uhs2_go_dormant(host, false);
> +       if (err) {
> +               pr_err("%s: %s: UHS2 GO_DORMANT_STATE fail, err= 0x%x!\n",
> +                       mmc_hostname(host), __func__, err);
> +               return -EIO;
> +       }
> +
> +       /* Enable Normal INT */
> +       if (host->ops->uhs2_set_reg(host, ENABLE_INT)) {
> +               pr_err("%s: %s: UHS2 ENABLE_INT fail!\n",
> +                       mmc_hostname(host), __func__);
> +               return -EIO;
> +       }
> +
> +       /* Change Speed Range */
> +       if (host->ops->uhs2_set_reg(host, SET_SPEED_B)) {
> +               pr_err("%s: %s: UHS2 SET_SPEED fail!\n",
> +                       mmc_hostname(host), __func__);
> +               return -EIO;
> +       }
> +
> +       /* TODO: if I set clock in sdhci_uhs2_interface_detect(), I should
> +        * remove below codes.
> +        */
> +       host->ios.clock = UHS2_RCLK_MAX;
> +       mmc_set_ios(host);
> +
> +       if (host->ops->uhs2_detect_init(host)) {
> +               pr_err("%s: %s: uhs2_detect_init() fail!\n",
> +                       mmc_hostname(host), __func__);
> +               return -EIO;
> +       }
> +
> +       DBG("Change to Speed Range B succeeds.\n");
> +       return 0;
> +}
> +
> +int mmc_uhs2_try_frequency(struct mmc_host *host, unsigned freq)
> +{
> +       int err = -EIO;
> +
> +       BUG_ON(!host->ops->uhs2_detect_init);
> +       BUG_ON(!host->ops->uhs2_set_reg);
> +
> +       host->flags |= MMC_UHS2_SUPPORT;
> +       host->f_init = freq;
> +
> +#ifdef CONFIG_MMC_DEBUG
> +       pr_info("%s: %s: trying to init card at %u Hz\n",
> +                mmc_hostname(host), __func__, host->f_init);
> +#endif
> +
> +       uhs2_power_up(host);
> +       if (host->ops->uhs2_detect_init(host)) {
> +               pr_err("%s: fail to detect UHS2!\n", mmc_hostname(host));
> +               err = UHS2_PHY_INIT_ERR;
> +               goto init_fail;
> +       }
> +
> +       if (uhs2_dev_init(host)) {
> +               pr_err("%s: UHS2 DEVICE_INIT fail!\n", mmc_hostname(host));
> +               goto init_fail;
> +       }
> +
> +       if (uhs2_enum(host)) {
> +               pr_err("%s: UHS2 ENUMERATE fail!\n", mmc_hostname(host));
> +               goto init_fail;
> +       }
> +
> +       if (uhs2_config_read(host)) {
> +               pr_err("%s: UHS2 INQUIRY_CONFIG fail!\n", mmc_hostname(host));
> +               goto init_fail;
> +       }
> +
> +       if (uhs2_config_write(host)) {
> +               pr_err("%s: UHS2 SET_COMMON_CONFIG fail!\n",
> +                       mmc_hostname(host));
> +               goto init_fail;
> +       }
> +
> +       mmc_delay(10);
> +
> +       /* Change to Speed Range B if it is supported */
> +       if (host->flags & MMC_UHS2_SPEED_B)
> +               if (uhs2_change_speed(host)) {
> +                       pr_err("%s: UHS2 uhs2_change_speed() fail!\n",
> +                               mmc_hostname(host));
> +                       goto init_fail;
> +               }
> +
> +
> +       host->flags |= MMC_UHS2_INITIALIZED;
> +
> +       mmc_go_idle(host);
> +
> +       mmc_send_if_cond(host, host->ocr_avail);
> +
> +       /* On market, only can some SD cards support UHS-II so only call SD
> +        * attach process here.
> +        */
> +       if (!mmc_attach_sd(host))
> +               return 0;
> +
> +init_fail:
> +       mmc_power_off(host);
> +       if (host->flags & MMC_UHS2_INITIALIZED)
> +               host->flags &= ~MMC_UHS2_INITIALIZED;
> +       host->flags &= ~MMC_UHS2_SUPPORT;
> +
> +       return err;
> +}
> +EXPORT_SYMBOL_GPL(mmc_uhs2_try_frequency);
> diff --git a/drivers/mmc/core/uhs2.h b/drivers/mmc/core/uhs2.h
> new file mode 100644
> index 0000000..6f21370
> --- /dev/null
> +++ b/drivers/mmc/core/uhs2.h
> @@ -0,0 +1,26 @@
> +/*
> + *  driver/mmc/core/uhs2.h - UHS-II driver
> + *
> + * Header file for UHS-II packets, Host Controller registers and I/O
> + * accessors.
> + *
> + *  Copyright (C) 2014 Intel Corp, All Rights Reserved.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or (at
> + * your option) any later version.
> + */
> +#ifndef MMC_UHS2_H
> +#define MMC_UHS2_H
> +
> +#include <linux/mmc/core.h>
> +#include <linux/mmc/host.h>
> +
> +#define UHS2_PHY_INIT_ERR      1
> +
> +extern int uhs2_prepare_sd_cmd(struct mmc_host *host, struct mmc_request *mrq);
> +extern void uhs2_power_up(struct mmc_host *host);
> +extern int mmc_uhs2_try_frequency(struct mmc_host *host, unsigned freq);
> +
> +#endif /* MMC_UHS2_H */
> diff --git a/include/linux/mmc/core.h b/include/linux/mmc/core.h
> index cb2b040..1eba129 100644
> --- a/include/linux/mmc/core.h
> +++ b/include/linux/mmc/core.h
> @@ -10,6 +10,7 @@
>
>  #include <linux/interrupt.h>
>  #include <linux/completion.h>
> +#include <linux/mmc/uhs2.h>
>
>  struct request;
>  struct mmc_data;
> @@ -101,6 +102,9 @@ struct mmc_command {
>
>         struct mmc_data         *data;          /* data segment associated with cmd */
>         struct mmc_request      *mrq;           /* associated request */
> +       struct uhs2_command     *uhs2_cmd;      /* UHS2 command */
> +       u8                      *uhs2_resp;     /* UHS2 native cmd resp */
> +       u8                      uhs2_resp_len;  /* UHS2 native cmd resp len */
>  };
>
>  struct mmc_data {
> @@ -198,6 +202,8 @@ extern int mmc_flush_cache(struct mmc_card *);
>
>  extern int mmc_detect_card_removed(struct mmc_host *host);
>
> +extern void mmc_set_ios(struct mmc_host *host);
> +
>  /**
>   *     mmc_claim_host - exclusively claim a host
>   *     @host: mmc host to claim
> diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
> index 9f32270..a79e2aa 100644
> --- a/include/linux/mmc/host.h
> +++ b/include/linux/mmc/host.h
> @@ -19,10 +19,12 @@
>  #include <linux/mmc/core.h>
>  #include <linux/mmc/card.h>
>  #include <linux/mmc/pm.h>
> +#include <linux/mmc/uhs2.h>
>
>  struct mmc_ios {
>         unsigned int    clock;                  /* clock rate */
>         unsigned short  vdd;
> +       unsigned short  vdd2;
>
>  /* vdd stores the bit number of the selected voltage range from below. */
>
> @@ -63,6 +65,7 @@ struct mmc_ios {
>  #define MMC_TIMING_MMC_DDR52   8
>  #define MMC_TIMING_MMC_HS200   9
>  #define MMC_TIMING_MMC_HS400   10
> +#define MMC_TIMING_UHS2                11
>
>         unsigned char   signal_voltage;         /* signalling voltage (1.8V or 3.3V) */
>
> @@ -147,6 +150,9 @@ struct mmc_host_ops {
>          */
>         int     (*multi_io_quirk)(struct mmc_card *card,
>                                   unsigned int direction, int blk_size);
> +       /* UHS2 interfaces */
> +       int     (*uhs2_detect_init)(struct mmc_host *host);
> +       int     (*uhs2_set_reg)(struct mmc_host *host, enum uhs2_act act);
>  };
>
>  struct mmc_card;
> @@ -200,6 +206,7 @@ struct regulator;
>
>  struct mmc_supply {
>         struct regulator *vmmc;         /* Card power supply */
> +       struct regulator *vmmc2;        /* UHS2 VDD2 power supply */
>         struct regulator *vqmmc;        /* Optional Vccq supply */
>  };
>
> @@ -215,10 +222,12 @@ struct mmc_host {
>         u32                     ocr_avail_sdio; /* SDIO-specific OCR */
>         u32                     ocr_avail_sd;   /* SD-specific OCR */
>         u32                     ocr_avail_mmc;  /* MMC-specific OCR */
> +       u32                     ocr_avail_uhs2; /* UHS2-specific OCR */
>         struct notifier_block   pm_notify;
>         u32                     max_current_330;
>         u32                     max_current_300;
>         u32                     max_current_180;
> +       u32                     max_current_180_vdd2;
>
>  #define MMC_VDD_165_195                0x00000080      /* VDD voltage 1.65 - 1.95 */
>  #define MMC_VDD_20_21          0x00000100      /* VDD voltage 2.0 ~ 2.1 */
> @@ -237,6 +246,7 @@ struct mmc_host {
>  #define MMC_VDD_33_34          0x00200000      /* VDD voltage 3.3 ~ 3.4 */
>  #define MMC_VDD_34_35          0x00400000      /* VDD voltage 3.4 ~ 3.5 */
>  #define MMC_VDD_35_36          0x00800000      /* VDD voltage 3.5 ~ 3.6 */
> +#define MMC_VDD2_165_195       0x00000080      /* VDD2 voltage 1.65 - 1.95 */
>
>         u32                     caps;           /* Host capabilities */
>
> @@ -266,6 +276,7 @@ struct mmc_host {
>  #define MMC_CAP_DRIVER_TYPE_A  (1 << 23)       /* Host supports Driver Type A */
>  #define MMC_CAP_DRIVER_TYPE_C  (1 << 24)       /* Host supports Driver Type C */
>  #define MMC_CAP_DRIVER_TYPE_D  (1 << 25)       /* Host supports Driver Type D */
> +#define MMC_CAP_UHS2           (1 << 26)       /* Host supports UHS2 mode */
>  #define MMC_CAP_CMD23          (1 << 30)       /* CMD23 supported. */
>  #define MMC_CAP_HW_RESET       (1 << 31)       /* Hardware reset */
>
> @@ -294,6 +305,17 @@ struct mmc_host {
>
>         mmc_pm_flag_t           pm_caps;        /* supported pm features */
>
> +       struct uhs2_host_caps   uhs2_caps;      /* UHS2 host capabilities */
> +       struct uhs2_card_prop   uhs2_dev_prop;  /* UHS2 device properties */
> +       u32                     group_desc;     /* UHS2 property */
> +       int                     flags;
> +#define MMC_UHS2_SUPPORT       (1 << 0)
> +#define MMC_UHS2_INITIALIZED   (1 << 1)
> +#define MMC_UHS2_2L_HD         (1 << 2)
> +#define MMC_UHS2_APP_CMD       (1 << 3)
> +#define MMC_UHS2_SPEED_B       (1 << 4)
> +#define MMC_SUPPORT_ADMA3      (1 << 5)
> +
>  #ifdef CONFIG_MMC_CLKGATE
>         int                     clk_requests;   /* internal reference counter */
>         unsigned int            clk_delay;      /* number of MCI clk hold cycles */
> @@ -519,4 +541,9 @@ static inline bool mmc_card_hs400(struct mmc_card *card)
>         return card->host->ios.timing == MMC_TIMING_MMC_HS400;
>  }
>
> +static inline bool mmc_card_uhs2(struct mmc_card *card)
> +{
> +       return (card->host->flags & MMC_UHS2_SUPPORT) &&
> +               (card->host->flags & MMC_UHS2_INITIALIZED);
> +}
>  #endif /* LINUX_MMC_HOST_H */
> diff --git a/include/linux/mmc/uhs2.h b/include/linux/mmc/uhs2.h
> new file mode 100644
> index 0000000..b0e805e
> --- /dev/null
> +++ b/include/linux/mmc/uhs2.h
> @@ -0,0 +1,274 @@
> +/*
> + *  linux/drivers/mmc/host/uhs2.h - UHS-II driver
> + *
> + * Header file for UHS-II packets, Host Controller registers and I/O
> + * accessors.
> + *
> + *  Copyright (C) 2014 Intel Corp, All Rights Reserved.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or (at
> + * your option) any later version.
> + */
> +#ifndef LINUX_MMC_UHS2_H
> +#define LINUX_MMC_UHS2_H
> +
> +struct mmc_request;
> +
> +/* LINK Layer definition */
> +/* UHS2 Header */
> +#define UHS2_NATIVE_PACKET_POS 7
> +#define UHS2_NATIVE_PACKET     (1 << UHS2_NATIVE_PACKET_POS)
> +
> +#define UHS2_PACKET_TYPE_POS   4
> +#define UHS2_PACKET_TYPE_CCMD  (0 << UHS2_PACKET_TYPE_POS)
> +#define UHS2_PACKET_TYPE_DCMD  (1 << UHS2_PACKET_TYPE_POS)
> +#define UHS2_PACKET_TYPE_RES   (2 << UHS2_PACKET_TYPE_POS)
> +#define UHS2_PACKET_TYPE_DATA  (3 << UHS2_PACKET_TYPE_POS)
> +#define UHS2_PACKET_TYPE_MSG   (7 << UHS2_PACKET_TYPE_POS)
> +
> +#define UHS2_DEST_ID_MASK      0x0F
> +#define UHS2_DEST_ID           0x1
> +
> +#define UHS2_SRC_ID_POS                12
> +#define UHS2_SRC_ID_MASK       0xF000
> +
> +#define UHS2_TRANS_ID_POS      8
> +#define UHS2_TRANS_ID_MASK     0x0700
> +
> +/* UHS2 MSG */
> +#define UHS2_MSG_CTG_POS       5
> +#define UHS2_MSG_CTG_LMSG      0x00
> +#define UHS2_MSG_CTG_INT       0x60
> +#define UHS2_MSG_CTG_AMSG      0x80
> +
> +#define UHS2_MSG_CTG_FCREQ     0x00
> +#define UHS2_MSG_CTG_FCRDY     0x01
> +#define UHS2_MSG_CTG_STAT      0x02
> +
> +#define UHS2_MSG_CODE_POS                      8
> +#define UHS2_MSG_CODE_FC_UNRECOVER_ERR         0x8
> +#define UHS2_MSG_CODE_STAT_UNRECOVER_ERR       0x8
> +#define UHS2_MSG_CODE_STAT_RECOVER_ERR         0x1
> +
> +/* TRANS Layer definition */
> +
> +/* Native packets*/
> +#define UHS2_NATIVE_CMD_RW_POS 7
> +#define UHS2_NATIVE_CMD_WRITE  (1 << UHS2_NATIVE_CMD_RW_POS)
> +#define UHS2_NATIVE_CMD_READ   (0 << UHS2_NATIVE_CMD_RW_POS)
> +
> +#define UHS2_NATIVE_CMD_PLEN_POS       4
> +#define UHS2_NATIVE_CMD_PLEN_4B                (1 << UHS2_NATIVE_CMD_PLEN_POS)
> +#define UHS2_NATIVE_CMD_PLEN_8B                (2 << UHS2_NATIVE_CMD_PLEN_POS)
> +#define UHS2_NATIVE_CMD_PLEN_16B       (3 << UHS2_NATIVE_CMD_PLEN_POS)
> +
> +#define UHS2_NATIVE_CCMD_GET_MIOADR_MASK       0xF00
> +#define UHS2_NATIVE_CCMD_MIOADR_MASK           0x0F
> +
> +#define UHS2_NATIVE_CCMD_LIOADR_POS            8
> +#define UHS2_NATIVE_CCMD_GET_LIOADR_MASK       0x0FF
> +
> +#define UHS2_DCMD_DM_POS       6
> +#define UHS2_DCMD_2L_HD_MODE   (1 << UHS2_DCMD_DM_POS)
> +#define UHS2_DCMD_LM_POS       5
> +#define UHS2_DCMD_LM_TLEN_EXIST        (1 << UHS2_DCMD_LM_POS)
> +#define UHS2_DCMD_TLUM_POS     4
> +#define UHS2_DCMD_TLUM_BYTE_MODE       (1 << UHS2_DCMD_TLUM_POS)
> +#define UHS2_NATIVE_DCMD_DAM_POS       3
> +#define UHS2_NATIVE_DCMD_DAM_IO                (1 << UHS2_NATIVE_DCMD_DAM_POS)
> +/*
> + * Per UHS2 spec, DCMD payload should be MSB first. There may be
> + * two types of data be assembled to MSB:
> + * 1. TLEN: Input block size for signle read/write and number of blocks
> + * for multiple read/write to calculate TLEN as MSB first per spec.
> + * 2. SD command argument.
> + */
> +static inline u32 uhs2_dcmd_convert_msb(u32 input)
> +{
> +       u32 ret = 0;
> +
> +       ret = ((input & 0xFF) << 24) |
> +               (((input >> 8) & 0xFF) << 16) |
> +               (((input >> 16) & 0xFF) << 8) |
> +               ((input >> 24) & 0xFF);
> +       return ret;
> +}
> +
> +#define UHS2_RES_NACK_POS      7
> +#define UHS2_RES_NACK_MASK     (0x1 << UHS2_RES_NACK_POS)
> +
> +#define UHS2_RES_ECODE_POS     4
> +#define UHS2_RES_ECODE_MASK    0x7
> +#define UHS2_RES_ECODE_COND    1
> +#define UHS2_RES_ECODE_ARG     2
> +#define UHS2_RES_ECODE_GEN     3
> +
> +/* IOADR of device registers */
> +#define UHS2_IOADR_GENERIC_CAPS                0x00
> +#define UHS2_IOADR_PHY_CAPS            0x02
> +#define UHS2_IOADR_LINK_CAPS           0x04
> +#define UHS2_IOADR_RSV_CAPS            0x06
> +#define UHS2_IOADR_GENERIC_SETTINGS    0x08
> +#define UHS2_IOADR_PHY_SETTINGS                0x0A
> +#define UHS2_IOADR_LINK_SETTINGS       0x0C
> +#define UHS2_IOADR_PRESET              0x40
> +
> +/* SD application packets */
> +#define UHS2_SD_CMD_INDEX_POS          8
> +
> +#define UHS2_SD_CMD_APP_POS            14
> +#define UHS2_SD_CMD_APP                        (1 << UHS2_SD_CMD_APP_POS)
> +
> +struct uhs2_command {
> +       u16     header;
> +       u16     arg;
> +       u32     *payload;
> +       u32     payload_len;
> +       u32     packet_len;
> +       u8      *resp;
> +       u8      resp_len;
> +};
> +
> +struct uhs2_host_caps {
> +       u32     dap;
> +       u32     gap;
> +       u32     maxblk_len;
> +       u32     n_fcu;
> +       u8      n_lanes;
> +       u8      addr64;
> +       u8      card_type;
> +       u8      phy_rev;
> +       u8      speed_range;
> +       u8      can_hibernate;
> +       u8      n_lss_sync;
> +       u8      n_lss_dir;
> +       u8      link_rev;
> +       u8      host_type;
> +       u8      n_data_gap;
> +
> +       u32     maxblk_len_set;
> +       u32     n_fcu_set;
> +       u8      n_lanes_set;
> +       u8      n_lss_sync_set;
> +       u8      n_lss_dir_set;
> +       u8      n_data_gap_set;
> +       u8      max_retry_set;
> +};
> +
> +struct uhs2_card_prop {
> +       u32     node_id;
> +       u32     dap;
> +       u32     gap;
> +       u32     n_fcu;
> +       u32     maxblk_len;
> +       u8      n_lanes;
> +       u8      dadr_len;
> +       u8      app_type;
> +       u8      phy_minor_rev;
> +       u8      phy_major_rev;
> +       u8      can_hibernate;
> +       u8      n_lss_sync;
> +       u8      n_lss_dir;
> +       u8      link_minor_rev;
> +       u8      link_major_rev;
> +       u8      dev_type;
> +       u8      n_data_gap;
> +
> +       u32     n_fcu_set;
> +       u32     maxblk_len_set;
> +       u8      n_lanes_set;
> +       u8      speed_range_set;
> +       u8      n_lss_sync_set;
> +       u8      n_lss_dir_set;
> +       u8      n_data_gap_set;
> +       u8      pwrctrl_mode_set;
> +       u8      max_retry_set;
> +
> +       u8      cfg_complete;
> +};
> +
> +enum uhs2_act {
> +       SET_CONFIG,
> +       ENABLE_INT,
> +       DISABLE_INT,
> +       SET_SPEED_B,
> +       CHECK_DORMANT,
> +};
> +
> +/* UHS-II Device Registers */
> +#define UHS2_DEV_CONFIG_REG    0x000
> +
> +/* General Caps and Settings registers */
> +#define  UHS2_DEV_CONFIG_GEN_CAPS      (UHS2_DEV_CONFIG_REG + 0x000)
> +#define   UHS2_DEV_CONFIG_N_LANES_POS  8
> +#define   UHS2_DEV_CONFIG_N_LANES_MASK 0x3F
> +#define   UHS2_DEV_CONFIG_2L_HD_FD     0x1
> +#define   UHS2_DEV_CONFIG_2D1U_FD      0x2
> +#define   UHS2_DEV_CONFIG_1D2U_FD      0x4
> +#define   UHS2_DEV_CONFIG_2D2U_FD      0x8
> +#define   UHS2_DEV_CONFIG_DADR_POS     14
> +#define   UHS2_DEV_CONFIG_DADR_MASK    0x1
> +#define   UHS2_DEV_CONFIG_APP_POS      16
> +#define   UHS2_DEV_CONFIG_APP_MASK     0xFF
> +#define   UHS2_DEV_CONFIG_APP_SD_MEM   0x1
> +
> +#define  UHS2_DEV_CONFIG_GEN_SET       (UHS2_DEV_CONFIG_REG + 0x008)
> +#define   UHS2_DEV_CONFIG_GEN_SET_2L_FD_HD     0x0
> +#define   UHS2_DEV_CONFIG_GEN_SET_CFG_COMPLETE (0x1 << 31)
> +
> +/* PHY Caps and Settings registers */
> +#define  UHS2_DEV_CONFIG_PHY_CAPS      (UHS2_DEV_CONFIG_REG + 0x002)
> +#define   UHS2_DEV_CONFIG_PHY_MINOR_MASK       0xF
> +#define   UHS2_DEV_CONFIG_PHY_MAJOR_POS                4
> +#define   UHS2_DEV_CONFIG_PHY_MAJOR_MASK       0x3
> +#define   UHS2_DEV_CONFIG_CAN_HIBER_POS                15
> +#define   UHS2_DEV_CONFIG_CAN_HIBER_MASK       0x1
> +#define  UHS2_DEV_CONFIG_PHY_CAPS1     (UHS2_DEV_CONFIG_REG + 0x003)
> +#define   UHS2_DEV_CONFIG_N_LSS_SYN_MASK       0xF
> +#define   UHS2_DEV_CONFIG_N_LSS_DIR_POS                4
> +#define   UHS2_DEV_CONFIG_N_LSS_DIR_MASK       0xF
> +
> +#define  UHS2_DEV_CONFIG_PHY_SET       (UHS2_DEV_CONFIG_REG + 0x00A)
> +#define   UHS2_DEV_CONFIG_PHY_SET_SPEED_POS    6
> +#define   UHS2_DEV_CONFIG_PHY_SET_SPEED_A      0x0
> +#define   UHS2_DEV_CONFIG_PHY_SET_SPEED_B      0x1
> +
> +/* LINK-TRAN Caps and Settins registers */
> +#define  UHS2_DEV_CONFIG_LINK_TRAN_CAPS        (UHS2_DEV_CONFIG_REG + 0x004)
> +#define   UHS2_DEV_CONFIG_LT_MINOR_MASK                0xF
> +#define   UHS2_DEV_CONFIG_LT_MAJOR_POS         4
> +#define   UHS2_DEV_CONFIG_LT_MAJOR_MASK                0x3
> +#define   UHS2_DEV_CONFIG_N_FCU_POS            8
> +#define   UHS2_DEV_CONFIG_N_FCU_MASK           0xFF
> +#define   UHS2_DEV_CONFIG_DEV_TYPE_POS         16
> +#define   UHS2_DEV_CONFIG_DEV_TYPE_MASK                0x7
> +#define   UHS2_DEV_CONFIG_MAX_BLK_LEN_POS      20
> +#define   UHS2_DEV_CONFIG_MAX_BLK_LEN_MASK     0xFFF
> +#define  UHS2_DEV_CONFIG_LINK_TRAN_CAPS1       (UHS2_DEV_CONFIG_REG + 0x005)
> +#define   UHS2_DEV_CONFIG_N_DATA_GAP_MASK      0xFF
> +
> +#define  UHS2_DEV_CONFIG_LINK_TRAN_SET (UHS2_DEV_CONFIG_REG + 0x00C)
> +#define   UHS2_DEV_CONFIG_LT_SET_MAX_BLK_LEN   0x200
> +#define   UHS2_DEV_CONFIG_LT_SET_MAX_RETRY_POS 16
> +
> +/* Preset register */
> +#define  UHS2_DEV_CONFIG_PRESET                (UHS2_DEV_CONFIG_REG + 0x040)
> +
> +#define UHS2_DEV_INT_REG       0x100
> +
> +#define UHS2_DEV_STATUS_REG    0x180
> +
> +#define UHS2_DEV_CMD_REG       0x200
> +#define  UHS2_DEV_CMD_FULL_RESET       (UHS2_DEV_CMD_REG + 0x000)
> +#define  UHS2_DEV_CMD_GO_DORMANT_STATE (UHS2_DEV_CMD_REG + 0x001)
> +#define   UHS2_DEV_CMD_DORMANT_HIBER   (0x1 << 7)
> +#define  UHS2_DEV_CMD_DEVICE_INIT      (UHS2_DEV_CMD_REG + 0x002)
> +#define  UHS2_DEV_CMD_ENUMERATE                (UHS2_DEV_CMD_REG + 0x003)
> +#define  UHS2_DEV_CMD_TRANS_ABORT      (UHS2_DEV_CMD_REG + 0x004)
> +
> +#define UHS2_RCLK_MAX  52000000
> +#define UHS2_RCLK_MIN  26000000
> +
> +#endif /* LINUX_MMC_UHS2_H */
> --
> 1.7.9.5
>
--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
yisun1 Jan. 22, 2015, 2:45 a.m. UTC | #2
SGksDQoNCj4gT24gMjcgRGVjZW1iZXIgMjAxNCBhdCAxMDoyNywgWWkgU3VuIDx5aS55LnN1bkBp
bnRlbC5jb20+PiB3cm90ZToNCj4+IFRoaXMgcGF0Y2ggYWRkcyB0aGUgVUhTLUlJIHN1cHBvcnQg
aW4gY29yZSBsYXllci4gVGhpcyBpcyBhIFJGQyBwYXRjaCBmb3INCj4+IGNvbW11bml0eSByZXZp
ZXcuDQo+Pg0KPj4gU2lnbmVkLW9mZi1ieTogWWkgU3VuIDx5aS55LnN1bkBpbnRlbC5jb20+Pg0K
Pj4gLS0tDQo+PiAgZHJpdmVycy9tbWMvY29yZS9NYWtlZmlsZSB8ICAgIDMgKy0NCj4+ICBkcml2
ZXJzL21tYy9jb3JlL2J1cy5jICAgIHwgICAgNSArLQ0KPj4gIGRyaXZlcnMvbW1jL2NvcmUvY29y
ZS5jICAgfCAgIDg5ICsrKystDQo+PiAgZHJpdmVycy9tbWMvY29yZS9zZC5jICAgICB8ICAgMTUg
Kw0KPj4gIGRyaXZlcnMvbW1jL2NvcmUvc2Rfb3BzLmMgfCAgIDEyICsNCj4+ICBkcml2ZXJzL21t
Yy9jb3JlL3VoczIuYyAgIHwgIDkwOCArKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysr
KysrKysrKysrKysNCj4+ICBkcml2ZXJzL21tYy9jb3JlL3VoczIuaCAgIHwgICAyNiArKw0KPj4g
IGluY2x1ZGUvbGludXgvbW1jL2NvcmUuaCAgfCAgICA2ICsNCj4+ICBpbmNsdWRlL2xpbnV4L21t
Yy9ob3N0LmggIHwgICAyNyArKw0KPj4gIGluY2x1ZGUvbGludXgvbW1jL3VoczIuaCAgfCAgMjc0
ICsrKysrKysrKysrKysrDQo+PiAgMTAgZmlsZXMgY2hhbmdlZCwgMTM1NiBpbnNlcnRpb25zKCsp
LCA5IGRlbGV0aW9ucygtKQ0KPj4gIGNyZWF0ZSBtb2RlIDEwMDY0NCBkcml2ZXJzL21tYy9jb3Jl
L3VoczIuYw0KPj4gIGNyZWF0ZSBtb2RlIDEwMDY0NCBkcml2ZXJzL21tYy9jb3JlL3VoczIuaA0K
Pj4gIGNyZWF0ZSBtb2RlIDEwMDY0NCBpbmNsdWRlL2xpbnV4L21tYy91aHMyLmgNCj4NCj4gRXZl
biBpZiB0aGlzIGFuIFJGQywgbWUgYW5kIGxpa2VseSBldmVyeWJvZHkgZWxzZSBqdXN0IHN0b3Bz
IGZyb20NCj4gcmV2aWV3aW5nIHRoaXMgcGF0Y2ggYnkgbG9va2luZyBhdCB0aGUgYWJvdmUgY2hh
bmdlIGxvZy4NCj4NCj4gSXMgdGhlcmUgYSB3YXkgdG8gc3BsaXQgaXQgdXA/DQo+DQo+IEtpbmQg
cmVnYXJkcw0KPiBVZmZlDQoNClVuZGVyc3RhbmQgeW91ciBjb25jZXJuLiBUaGUgY2hhbmdlcyBh
cmUgYmlnLCBlc3BlY2lhbGx5IHVoczIuYy4gSSB3aWxsIHRyeSB0byBzcGxpdCBpdCB1cCB3aGVu
IEkgYW0gZnJlZS4gDQoNClRoYW5rcywNClN1biBZaQ0KDQo+Pg0KPj4gZGlmZiAtLWdpdCBhL2Ry
aXZlcnMvbW1jL2NvcmUvTWFrZWZpbGUgYi9kcml2ZXJzL21tYy9jb3JlL01ha2VmaWxlDQo+PiBp
bmRleCAzOGVkMjEwLi5jMGJlMGNiIDEwMDY0NA0KPj4gLS0tIGEvZHJpdmVycy9tbWMvY29yZS9N
YWtlZmlsZQ0KPj4gKysrIGIvZHJpdmVycy9tbWMvY29yZS9NYWtlZmlsZQ0KPj4gQEAgLTcsNiAr
Nyw3IEBAIG1tY19jb3JlLXkgICAgICAgICAgICAgICAgICAgICAgOj0gY29yZS5vIGJ1cy5vIGhv
c3QubyBcDQo+PiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1tYy5vIG1tY19v
cHMubyBzZC5vIHNkX29wcy5vIFwNCj4+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgc2Rpby5vIHNkaW9fb3BzLm8gc2Rpb19idXMubyBcDQo+PiAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgIHNkaW9fY2lzLm8gc2Rpb19pby5vIHNkaW9faXJxLm8gXA0KPj4gLSAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBxdWlya3MubyBzbG90LWdwaW8ubw0KPj4g
KyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBxdWlya3MubyBzbG90LWdwaW8ubyBc
DQo+PiArICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVoczIubw0KPj4NCj4+ICBt
bWNfY29yZS0kKENPTkZJR19ERUJVR19GUykgICAgKz0gZGVidWdmcy5vDQo+PiBkaWZmIC0tZ2l0
IGEvZHJpdmVycy9tbWMvY29yZS9idXMuYyBiL2RyaXZlcnMvbW1jL2NvcmUvYnVzLmMNCj4+IGlu
ZGV4IDg2ZDI3MTEuLjY1NjU3NTQgMTAwNjQ0DQo+PiAtLS0gYS9kcml2ZXJzL21tYy9jb3JlL2J1
cy5jDQo+PiArKysgYi9kcml2ZXJzL21tYy9jb3JlL2J1cy5jDQo+PiBAQCAtMzA4LDggKzMwOCw5
IEBAIGludCBtbWNfYWRkX2NhcmQoc3RydWN0IG1tY19jYXJkICpjYXJkKQ0KPj4gICAgICAgICB9
IGVsc2Ugew0KPj4gICAgICAgICAgICAgICAgIHByX2luZm8oIiVzOiBuZXcgJXMlcyVzJXMlcyBj
YXJkIGF0IGFkZHJlc3MgJTA0eFxuIiwNCj4+ICAgICAgICAgICAgICAgICAgICAgICAgIG1tY19o
b3N0bmFtZShjYXJkLT4+aG9zdCksDQo+PiAtICAgICAgICAgICAgICAgICAgICAgICBtbWNfY2Fy
ZF91aHMoY2FyZCkgPyAidWx0cmEgaGlnaCBzcGVlZCAiIDoNCj4+IC0gICAgICAgICAgICAgICAg
ICAgICAgIChtbWNfY2FyZF9ocyhjYXJkKSA/ICJoaWdoIHNwZWVkICIgOiAiIiksDQo+PiArICAg
ICAgICAgICAgICAgICAgICAgICBtbWNfY2FyZF91aHMyKGNhcmQpID8gInVsdHJhIGhpZ2ggc3Bl
ZWQgMiAiIDoNCj4+ICsgICAgICAgICAgICAgICAgICAgICAgIChtbWNfY2FyZF91aHMoY2FyZCkg
PyAidWx0cmEgaGlnaCBzcGVlZCAxIiA6DQo+PiArICAgICAgICAgICAgICAgICAgICAgICAobW1j
X2NhcmRfaHMoY2FyZCkgPyAiaGlnaCBzcGVlZCAiIDogIiIpKSwNCj4+ICAgICAgICAgICAgICAg
ICAgICAgICAgIG1tY19jYXJkX2hzNDAwKGNhcmQpID8gIkhTNDAwICIgOg0KPj4gICAgICAgICAg
ICAgICAgICAgICAgICAgKG1tY19jYXJkX2hzMjAwKGNhcmQpID8gIkhTMjAwICIgOiAiIiksDQo+
PiAgICAgICAgICAgICAgICAgICAgICAgICBtbWNfY2FyZF9kZHI1MihjYXJkKSA/ICJERFIgIiA6
ICIiLA0KPj4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvbW1jL2NvcmUvY29yZS5jIGIvZHJpdmVycy9t
bWMvY29yZS9jb3JlLmMNCj4+IGluZGV4IDk1ODRiZmYuLjhhNjIwNjMgMTAwNjQ0DQo+PiAtLS0g
YS9kcml2ZXJzL21tYy9jb3JlL2NvcmUuYw0KPj4gKysrIGIvZHJpdmVycy9tbWMvY29yZS9jb3Jl
LmMNCj4+IEBAIC01LDYgKzUsNyBAQA0KPj4gICAqICBTRCBzdXBwb3J0IENvcHlyaWdodCAoQykg
MjAwNCBJYW4gTW9sdG9uLCBBbGwgUmlnaHRzIFJlc2VydmVkLg0KPj4gICAqICBDb3B5cmlnaHQg
KEMpIDIwMDUtMjAwOCBQaWVycmUgT3NzbWFuLCBBbGwgUmlnaHRzIFJlc2VydmVkLg0KPj4gICAq
ICBNTUN2NCBzdXBwb3J0IENvcHlyaWdodCAoQykgMjAwNiBQaGlsaXAgTGFuZ2RhbGUsIEFsbCBS
aWdodHMgUmVzZXJ2ZWQuDQo+PiArICogIFVIUzIgc3VwcG9ydCBDb3B5cmlnaHQgKEMpIDIwMTQg
SW50ZWwgQ29ycCwgQWxsIFJpZ2h0cyBSZXNlcnZlZC4NCj4+ICAgKg0KPj4gICAqIFRoaXMgcHJv
Z3JhbSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9k
aWZ5DQo+PiAgICogaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMg
TGljZW5zZSB2ZXJzaW9uIDIgYXMNCj4+IEBAIC0zNSwxMSArMzYsMTMgQEANCj4+ICAjaW5jbHVk
ZSA8bGludXgvbW1jL21tYy5oPj4NCj4+ICAjaW5jbHVkZSA8bGludXgvbW1jL3NkLmg+Pg0KPj4g
ICNpbmNsdWRlIDxsaW51eC9tbWMvc2xvdC1ncGlvLmg+Pg0KPj4gKyNpbmNsdWRlIDxsaW51eC9t
bWMvdWhzMi5oPj4NCj4+DQo+PiAgI2luY2x1ZGUgImNvcmUuaCINCj4+ICAjaW5jbHVkZSAiYnVz
LmgiDQo+PiAgI2luY2x1ZGUgImhvc3QuaCINCj4+ICAjaW5jbHVkZSAic2Rpb19idXMuaCINCj4+
ICsjaW5jbHVkZSAidWhzMi5oIg0KPj4NCj4+ICAjaW5jbHVkZSAibW1jX29wcy5oIg0KPj4gICNp
bmNsdWRlICJzZF9vcHMuaCINCj4+IEBAIC01Niw2ICs1OSw3IEBADQo+Pg0KPj4gIHN0YXRpYyBz
dHJ1Y3Qgd29ya3F1ZXVlX3N0cnVjdCAqd29ya3F1ZXVlOw0KPj4gIHN0YXRpYyBjb25zdCB1bnNp
Z25lZCBmcmVxc1tdID0geyA0MDAwMDAsIDMwMDAwMCwgMjAwMDAwLCAxMDAwMDAgfTsNCj4+ICtz
dGF0aWMgY29uc3QgdW5zaWduZWQgdWhzMl9mcmVxc1tdID0geyA1MjAwMDAwMCwgMjYwMDAwMDAg
fTsNCj4+DQo+PiAgLyoNCj4+ICAgKiBFbmFibGluZyBzb2Z0d2FyZSBDUkNzIG9uIHRoZSBkYXRh
IGJsb2NrcyBjYW4gYmUgYSBzaWduaWZpY2FudCAoMzAlKQ0KPj4gQEAgLTI0OCw2ICsyNTIsMTIg
QEAgbW1jX3N0YXJ0X3JlcXVlc3Qoc3RydWN0IG1tY19ob3N0ICpob3N0LCBzdHJ1Y3QgbW1jX3Jl
cXVlc3QgKm1ycSkNCj4+ICAgICAgICAgICAgICAgICAgICAgICAgIG1ycS0+PnN0b3AtPj5tcnEg
PSBtcnE7DQo+PiAgICAgICAgICAgICAgICAgfQ0KPj4gICAgICAgICB9DQo+PiArDQo+PiArICAg
ICAgIGlmIChob3N0LT4+ZmxhZ3MgJiBNTUNfVUhTMl9TVVBQT1JUICYmDQo+PiArICAgICAgICAg
ICBob3N0LT4+ZmxhZ3MgJiBNTUNfVUhTMl9JTklUSUFMSVpFRCkNCj4+ICsgICAgICAgICAgICAg
ICBpZiAobXJxLT4+Y21kLT4+dWhzMl9jbWQgPT0gTlVMTCkNCj4+ICsgICAgICAgICAgICAgICAg
ICAgICAgIHVoczJfcHJlcGFyZV9zZF9jbWQoaG9zdCwgbXJxKTsNCj4+ICsNCj4+ICAgICAgICAg
bW1jX2hvc3RfY2xrX2hvbGQoaG9zdCk7DQo+PiAgICAgICAgIGxlZF90cmlnZ2VyX2V2ZW50KGhv
c3QtPj5sZWQsIExFRF9GVUxMKTsNCj4+ICAgICAgICAgaG9zdC0+Pm9wcy0+PnJlcXVlc3QoaG9z
dCwgbXJxKTsNCj4+IEBAIC0zODUsNyArMzk1LDcgQEAgc3RhdGljIGludCBtbWNfd2FpdF9mb3Jf
ZGF0YV9yZXFfZG9uZShzdHJ1Y3QgbW1jX2hvc3QgKmhvc3QsDQo+PiAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgIHN0cnVjdCBtbWNfcmVxdWVzdCAqbXJxLA0KPj4gICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJ1Y3QgbW1jX2FzeW5jX3JlcSAqbmV4
dF9yZXEpDQo+PiAgew0KPj4gLSAgICAgICBzdHJ1Y3QgbW1jX2NvbW1hbmQgKmNtZDsNCj4+ICsg
ICAgICAgc3RydWN0IG1tY19jb21tYW5kICpjbWQgPSBtcnEtPj5jbWQ7DQo+PiAgICAgICAgIHN0
cnVjdCBtbWNfY29udGV4dF9pbmZvICpjb250ZXh0X2luZm8gPSAmaG9zdC0+PmNvbnRleHRfaW5m
bzsNCj4+ICAgICAgICAgaW50IGVycjsNCj4+ICAgICAgICAgdW5zaWduZWQgbG9uZyBmbGFnczsN
Cj4+IEBAIC00MDAsNyArNDEwLDYgQEAgc3RhdGljIGludCBtbWNfd2FpdF9mb3JfZGF0YV9yZXFf
ZG9uZShzdHJ1Y3QgbW1jX2hvc3QgKmhvc3QsDQo+PiAgICAgICAgICAgICAgICAgaWYgKGNvbnRl
eHRfaW5mby0+PmlzX2RvbmVfcmN2KSB7DQo+PiAgICAgICAgICAgICAgICAgICAgICAgICBjb250
ZXh0X2luZm8tPj5pc19kb25lX3JjdiA9IGZhbHNlOw0KPj4gICAgICAgICAgICAgICAgICAgICAg
ICAgY29udGV4dF9pbmZvLT4+aXNfbmV3X3JlcSA9IGZhbHNlOw0KPj4gLSAgICAgICAgICAgICAg
ICAgICAgICAgY21kID0gbXJxLT4+Y21kOw0KPj4NCj4+ICAgICAgICAgICAgICAgICAgICAgICAg
IGlmICghY21kLT4+ZXJyb3IgfHwgIWNtZC0+PnJldHJpZXMgfHwNCj4+ICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICBtbWNfY2FyZF9yZW1vdmVkKGhvc3QtPj5jYXJkKSkgew0KPj4gQEAgLTQy
NCw2ICs0MzMsMTYgQEAgc3RhdGljIGludCBtbWNfd2FpdF9mb3JfZGF0YV9yZXFfZG9uZShzdHJ1
Y3QgbW1jX2hvc3QgKmhvc3QsDQo+PiAgICAgICAgICAgICAgICAgICAgICAgICB9DQo+PiAgICAg
ICAgICAgICAgICAgfQ0KPj4gICAgICAgICB9DQo+PiArDQo+PiArICAgICAgIGlmIChjbWQgJiYg
Y21kLT4+dWhzMl9jbWQpIHsNCj4+ICsjaWZkZWYgQ09ORklHX01NQ19ERUJVRw0KPj4gKyAgICAg
ICAgICAgICAgIHByX2luZm8oIiVzOiAlcyBmcmVlIHVoczJfY21kIVxuIiwNCj4+ICsgICAgICAg
ICAgICAgICAgICAgICAgIG1tY19ob3N0bmFtZShob3N0KSwgX19mdW5jX18pOw0KPj4gKyNlbmRp
Zg0KPj4gKyAgICAgICAgICAgICAgIGtmcmVlKGNtZC0+PnVoczJfY21kLT4+cGF5bG9hZCk7DQo+
PiArICAgICAgICAgICAgICAga2ZyZWUoY21kLT4+dWhzMl9jbWQpOw0KPj4gKyAgICAgICAgICAg
ICAgIGNtZC0+PnVoczJfY21kID0gTlVMTDsNCj4+ICsgICAgICAgfQ0KPj4gICAgICAgICByZXR1
cm4gZXJyOw0KPj4gIH0NCj4+DQo+PiBAQCAtNDY0LDYgKzQ4MywxNiBAQCBzdGF0aWMgdm9pZCBt
bWNfd2FpdF9mb3JfcmVxX2RvbmUoc3RydWN0IG1tY19ob3N0ICpob3N0LA0KPj4gICAgICAgICAg
ICAgICAgIGNtZC0+PmVycm9yID0gMDsNCj4+ICAgICAgICAgICAgICAgICBob3N0LT4+b3BzLT4+
cmVxdWVzdChob3N0LCBtcnEpOw0KPj4gICAgICAgICB9DQo+PiArDQo+PiArICAgICAgIGlmIChj
bWQgJiYgY21kLT4+dWhzMl9jbWQpIHsNCj4+ICsjaWZkZWYgQ09ORklHX01NQ19ERUJVRw0KPj4g
KyAgICAgICAgICAgICAgIHByX2luZm8oIiVzOiAlcyBmcmVlIHVoczJfY21kIVxuIiwNCj4+ICsg
ICAgICAgICAgICAgICAgICAgICAgIG1tY19ob3N0bmFtZShob3N0KSwgX19mdW5jX18pOw0KPj4g
KyNlbmRpZg0KPj4gKyAgICAgICAgICAgICAgIGtmcmVlKGNtZC0+PnVoczJfY21kLT4+cGF5bG9h
ZCk7DQo+PiArICAgICAgICAgICAgICAga2ZyZWUoY21kLT4+dWhzMl9jbWQpOw0KPj4gKyAgICAg
ICAgICAgICAgIGNtZC0+PnVoczJfY21kID0gTlVMTDsNCj4+ICsgICAgICAgfQ0KPj4gIH0NCj4+
DQo+PiAgLyoqDQo+PiBAQCAtOTc0LDcgKzEwMDMsNyBAQCBFWFBPUlRfU1lNQk9MKG1tY19wdXRf
Y2FyZCk7DQo+PiAgICogSW50ZXJuYWwgZnVuY3Rpb24gdGhhdCBkb2VzIHRoZSBhY3R1YWwgaW9z
IGNhbGwgdG8gdGhlIGhvc3QgZHJpdmVyLA0KPj4gICAqIG9wdGlvbmFsbHkgcHJpbnRpbmcgc29t
ZSBkZWJ1ZyBvdXRwdXQuDQo+PiAgICovDQo+PiAtc3RhdGljIGlubGluZSB2b2lkIG1tY19zZXRf
aW9zKHN0cnVjdCBtbWNfaG9zdCAqaG9zdCkNCj4+ICt2b2lkIG1tY19zZXRfaW9zKHN0cnVjdCBt
bWNfaG9zdCAqaG9zdCkNCj4+ICB7DQo+PiAgICAgICAgIHN0cnVjdCBtbWNfaW9zICppb3MgPSAm
aG9zdC0+PmlvczsNCj4+DQo+PiBAQCAtOTg4LDYgKzEwMTcsNyBAQCBzdGF0aWMgaW5saW5lIHZv
aWQgbW1jX3NldF9pb3Moc3RydWN0IG1tY19ob3N0ICpob3N0KQ0KPj4gICAgICAgICAgICAgICAg
IG1tY19zZXRfdW5nYXRlZChob3N0KTsNCj4+ICAgICAgICAgaG9zdC0+Pm9wcy0+PnNldF9pb3Mo
aG9zdCwgaW9zKTsNCj4+ICB9DQo+PiArRVhQT1JUX1NZTUJPTChtbWNfc2V0X2lvcyk7DQo+Pg0K
Pj4gIC8qDQo+PiAgICogQ29udHJvbCBjaGlwIHNlbGVjdCBwaW4gb24gYSBob3N0Lg0KPj4gQEAg
LTEzNjEsNiArMTM5MSwyMyBAQCBpbnQgbW1jX3JlZ3VsYXRvcl9nZXRfc3VwcGx5KHN0cnVjdCBt
bWNfaG9zdCAqbW1jKQ0KPj4gICAgICAgICAgICAgICAgIGRldl9pbmZvKGRldiwgIk5vIHZxbW1j
IHJlZ3VsYXRvciBmb3VuZFxuIik7DQo+PiAgICAgICAgIH0NCj4+DQo+PiArICAgICAgIGlmICgh
KG1tYy0+PmNhcHMgJiBNTUNfQ0FQX1VIUzIpKQ0KPj4gKyAgICAgICAgICAgICAgIHJldHVybiAw
Ow0KPj4gKw0KPj4gKyAgICAgICBtbWMtPj5zdXBwbHkudm1tYzIgPSBkZXZtX3JlZ3VsYXRvcl9n
ZXRfb3B0aW9uYWwoZGV2LCAidm1tYzIiKTsNCj4+ICsgICAgICAgaWYgKElTX0VSUihtbWMtPj5z
dXBwbHkudm1tYzIpKSB7DQo+PiArICAgICAgICAgICAgICAgaWYgKFBUUl9FUlIobW1jLT4+c3Vw
cGx5LnZtbWMyKSA9PSAtRVBST0JFX0RFRkVSKQ0KPj4gKyAgICAgICAgICAgICAgICAgICAgICAg
cmV0dXJuIC1FUFJPQkVfREVGRVI7DQo+PiArICAgICAgICAgICAgICAgZGV2X2luZm8oZGV2LCAi
Tm8gdm1tYzIgcmVndWxhdG9yIGZvdW5kXG4iKTsNCj4+ICsgICAgICAgfSBlbHNlIHsNCj4+ICsg
ICAgICAgICAgICAgICByZXQgPSBtbWNfcmVndWxhdG9yX2dldF9vY3JtYXNrKG1tYy0+PnN1cHBs
eS52bW1jMik7DQo+PiArICAgICAgICAgICAgICAgaWYgKHJldCA+PiAwKQ0KPj4gKyAgICAgICAg
ICAgICAgICAgICAgICAgbW1jLT4+b2NyX2F2YWlsX3VoczIgPSByZXQ7DQo+PiArICAgICAgICAg
ICAgICAgZWxzZQ0KPj4gKyAgICAgICAgICAgICAgICAgICAgICAgZGV2X3dhcm4oZGV2LCAiRmFp
bGVkIGdldHRpbmcgVUhTMiBPQ1IgbWFzazogJWRcbiIsDQo+PiArICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgcmV0KTsNCj4+ICsgICAgICAgfQ0KPj4gKw0KPj4gICAgICAg
ICByZXR1cm4gMDsNCj4+ICB9DQo+PiAgRVhQT1JUX1NZTUJPTF9HUEwobW1jX3JlZ3VsYXRvcl9n
ZXRfc3VwcGx5KTsNCj4+IEBAIC0xNTUzLDYgKzE2MDAsMTEgQEAgdm9pZCBtbWNfcG93ZXJfdXAo
c3RydWN0IG1tY19ob3N0ICpob3N0LCB1MzIgb2NyKQ0KPj4gICAgICAgICBpZiAoaG9zdC0+Pmlv
cy5wb3dlcl9tb2RlID09IE1NQ19QT1dFUl9PTikNCj4+ICAgICAgICAgICAgICAgICByZXR1cm47
DQo+Pg0KPj4gKyAgICAgICBpZiAoaG9zdC0+PmZsYWdzICYgTU1DX1VIUzJfU1VQUE9SVCkgew0K
Pj4gKyAgICAgICAgICAgICAgIHVoczJfcG93ZXJfdXAoaG9zdCk7DQo+PiArICAgICAgICAgICAg
ICAgcmV0dXJuOw0KPj4gKyAgICAgICB9DQo+PiArDQo+PiAgICAgICAgIG1tY19ob3N0X2Nsa19o
b2xkKGhvc3QpOw0KPj4NCj4+ICAgICAgICAgaG9zdC0+Pmlvcy52ZGQgPSBmbHMob2NyKSAtIDE7
DQo+PiBAQCAtMjI4Nyw3ICsyMzM5LDkgQEAgc3RhdGljIGludCBtbWNfZG9faHdfcmVzZXQoc3Ry
dWN0IG1tY19ob3N0ICpob3N0LCBpbnQgY2hlY2spDQo+PiAgICAgICAgIH0NCj4+DQo+PiAgICAg
ICAgIC8qIFNldCBpbml0aWFsIHN0YXRlIGFuZCBjYWxsIG1tY19zZXRfaW9zICovDQo+PiAtICAg
ICAgIG1tY19zZXRfaW5pdGlhbF9zdGF0ZShob3N0KTsNCj4+ICsgICAgICAgLyogVE9ETzogbmVl
ZCB2ZXJpZnkgdGhpcyBmb3IgVUhTMi4gKi8NCj4+ICsgICAgICAgaWYgKCFob3N0LT4+ZmxhZ3Mg
JiBNTUNfVUhTMl9TVVBQT1JUKQ0KPj4gKyAgICAgICAgICAgICAgIG1tY19zZXRfaW5pdGlhbF9z
dGF0ZShob3N0KTsNCj4+DQo+PiAgICAgICAgIG1tY19ob3N0X2Nsa19yZWxlYXNlKGhvc3QpOw0K
Pj4NCj4+IEBAIC0yNDE2LDYgKzI0NzAsNyBAQCB2b2lkIG1tY19yZXNjYW4oc3RydWN0IHdvcmtf
c3RydWN0ICp3b3JrKQ0KPj4gICAgICAgICBzdHJ1Y3QgbW1jX2hvc3QgKmhvc3QgPQ0KPj4gICAg
ICAgICAgICAgICAgIGNvbnRhaW5lcl9vZih3b3JrLCBzdHJ1Y3QgbW1jX2hvc3QsIGRldGVjdC53
b3JrKTsNCj4+ICAgICAgICAgaW50IGk7DQo+PiArICAgICAgIGludCBlcnI7DQo+Pg0KPj4gICAg
ICAgICBpZiAoaG9zdC0+PnRyaWdnZXJfY2FyZF9ldmVudCAmJiBob3N0LT4+b3BzLT4+Y2FyZF9l
dmVudCkgew0KPj4gICAgICAgICAgICAgICAgIGhvc3QtPj5vcHMtPj5jYXJkX2V2ZW50KGhvc3Qp
Ow0KPj4gQEAgLTI0NzAsNiArMjUyNSwyNyBAQCB2b2lkIG1tY19yZXNjYW4oc3RydWN0IHdvcmtf
c3RydWN0ICp3b3JrKQ0KPj4gICAgICAgICB9DQo+Pg0KPj4gICAgICAgICBtbWNfY2xhaW1faG9z
dChob3N0KTsNCj4+ICsgICAgICAgaWYgKGhvc3QtPj5jYXBzICYgTU1DX0NBUF9VSFMyKSB7DQo+
PiArICAgICAgICAgICAgICAgLyogU3RhcnQgdG8gdHJ5IFVIUy1JSSBpbml0aWFsaXphdGlvbiBm
cm9tIDUyTUh6IHRvIDI2TUh6DQo+PiArICAgICAgICAgICAgICAgICogKFJDTEsgcmFuZ2UpIHBl
ciBzcGVjLg0KPj4gKyAgICAgICAgICAgICAgICAqLw0KPj4gKyAgICAgICAgICAgICAgIGZvciAo
aSA9IDA7IGkgPCBBUlJBWV9TSVpFKHVoczJfZnJlcXMpOyBpKyspIHsNCj4+ICsgICAgICAgICAg
ICAgICAgICAgICAgIGVyciA9IG1tY191aHMyX3RyeV9mcmVxdWVuY3koaG9zdCwNCj4+ICsgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgbWF4KHVoczJfZnJlcXNbaV0sIGhvc3QtPj5mX21p
bikpOw0KPj4gKyAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFlcnIpIHsNCj4+ICsgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgbW1jX3JlbGVhc2VfaG9zdChob3N0KTsNCj4+ICsgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgZ290byBvdXQ7DQo+PiArICAgICAgICAgICAgICAg
ICAgICAgICB9IGVsc2UgaWYgKGVyciA9PSBVSFMyX1BIWV9JTklUX0VSUikNCj4+ICsgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgLyogVUhTMiBJRiBkZXRlY3Qgb3IgTGFuZSBTeW5jIGVy
cm9yLg0KPj4gKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKiBUcnkgbGVnYWN5IGlu
dGVyZmFjZS4NCj4+ICsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovDQo+PiArICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOw0KPj4gKw0KPj4gKyAgICAgICAgICAg
ICAgICAgICAgICAgaWYgKHVoczJfZnJlcXNbaV0gPD0gaG9zdC0+PmZfbWluKQ0KPj4gKyAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsNCj4+ICsgICAgICAgICAgICAgICB9DQo+
PiArICAgICAgIH0NCj4+ICsNCj4+ICAgICAgICAgZm9yIChpID0gMDsgaSA8IEFSUkFZX1NJWkUo
ZnJlcXMpOyBpKyspIHsNCj4+ICAgICAgICAgICAgICAgICBpZiAoIW1tY19yZXNjYW5fdHJ5X2Zy
ZXEoaG9zdCwgbWF4KGZyZXFzW2ldLCBob3N0LT4+Zl9taW4pKSkNCj4+ICAgICAgICAgICAgICAg
ICAgICAgICAgIGJyZWFrOw0KPj4gQEAgLTI0ODUsMTIgKzI1NjEsMTIgQEAgdm9pZCBtbWNfcmVz
Y2FuKHN0cnVjdCB3b3JrX3N0cnVjdCAqd29yaykNCj4+DQo+PiAgdm9pZCBtbWNfc3RhcnRfaG9z
dChzdHJ1Y3QgbW1jX2hvc3QgKmhvc3QpDQo+PiAgew0KPj4gLSAgICAgICBob3N0LT4+Zl9pbml0
ID0gbWF4KGZyZXFzWzBdLCBob3N0LT4+Zl9taW4pOw0KPj4gICAgICAgICBob3N0LT4+cmVzY2Fu
X2Rpc2FibGUgPSAwOw0KPj4gICAgICAgICBob3N0LT4+aW9zLnBvd2VyX21vZGUgPSBNTUNfUE9X
RVJfVU5ERUZJTkVEOw0KPj4gICAgICAgICBpZiAoaG9zdC0+PmNhcHMyICYgTU1DX0NBUDJfTk9f
UFJFU0NBTl9QT1dFUlVQKQ0KPj4gICAgICAgICAgICAgICAgIG1tY19wb3dlcl9vZmYoaG9zdCk7
DQo+PiAtICAgICAgIGVsc2UNCj4+ICsgICAgICAgLyogUG93ZXIgdXAgaGVyZSB3aWxsIG1ha2Ug
VUhTMiBpbml0IHVnbHkuICovDQo+PiArICAgICAgIGVsc2UgaWYgKCEoaG9zdC0+PmNhcHMgJiBN
TUNfQ0FQX1VIUzIpKQ0KPj4gICAgICAgICAgICAgICAgIG1tY19wb3dlcl91cChob3N0LCBob3N0
LT4+b2NyX2F2YWlsKTsNCj4+ICAgICAgICAgbW1jX2dwaW9kX3JlcXVlc3RfY2RfaXJxKGhvc3Qp
Ow0KPj4gICAgICAgICBfbW1jX2RldGVjdF9jaGFuZ2UoaG9zdCwgMCwgZmFsc2UpOw0KPj4gQEAg
LTI1NzMsNiArMjY0OSw3IEBAIGludCBtbWNfcG93ZXJfcmVzdG9yZV9ob3N0KHN0cnVjdCBtbWNf
aG9zdCAqaG9zdCkNCj4+ICAgICAgICAgICAgICAgICByZXR1cm4gLUVJTlZBTDsNCj4+ICAgICAg
ICAgfQ0KPj4NCj4+ICsgICAgICAgLyogVE9ETzogZm9yIFVIUzIsIG1heSBleGVjdXRlIFVIUzIg
aW5pdCBwcm9jZXNzIGFnYWluLiAqLw0KPj4gICAgICAgICBtbWNfcG93ZXJfdXAoaG9zdCwgaG9z
dC0+PmNhcmQtPj5vY3IpOw0KPj4gICAgICAgICByZXQgPSBob3N0LT4+YnVzX29wcy0+PnBvd2Vy
X3Jlc3RvcmUoaG9zdCk7DQo+Pg0KPj4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvbW1jL2NvcmUvc2Qu
YyBiL2RyaXZlcnMvbW1jL2NvcmUvc2QuYw0KPj4gaW5kZXggZDkwYTZkZS4uZDIwMDBiZSAxMDA2
NDQNCj4+IC0tLSBhL2RyaXZlcnMvbW1jL2NvcmUvc2QuYw0KPj4gKysrIGIvZHJpdmVycy9tbWMv
Y29yZS9zZC5jDQo+PiBAQCAtOTY5LDYgKzk2OSwxNCBAQCBzdGF0aWMgaW50IG1tY19zZF9pbml0
X2NhcmQoc3RydWN0IG1tY19ob3N0ICpob3N0LCB1MzIgb2NyLA0KPj4gICAgICAgICBpZiAoZXJy
KQ0KPj4gICAgICAgICAgICAgICAgIGdvdG8gZnJlZV9jYXJkOw0KPj4NCj4+ICsgICAgICAgLyog
Rm9yIFVIUzIsIHNraXAgdGhlIFVIUy1JIGluaXRpYWxpemF0aW9uLiAqLw0KPj4gKyAgICAgICAv
KiBUT0RPOiBzaGFsbCB3ZSBzZW5kIENNRDYgdG8gc2V0IE1heGltdW0gUG93ZXIgQ29uc3VtcHRp
b24NCj4+ICsgICAgICAgICogdG8gZ2V0IGJldHRlciBwZXJmb3JtYW5jZT8NCj4+ICsgICAgICAg
ICovDQo+PiArICAgICAgIGlmICgoaG9zdC0+PmZsYWdzICYgTU1DX1VIUzJfU1VQUE9SVCkgJiYN
Cj4+ICsgICAgICAgICAgIChob3N0LT4+ZmxhZ3MgJiBNTUNfVUhTMl9JTklUSUFMSVpFRCkpDQo+
PiArICAgICAgICAgICAgICAgZ290byB1aHMyX2RvbmU7DQo+PiArDQo+PiAgICAgICAgIC8qIElu
aXRpYWxpemF0aW9uIHNlcXVlbmNlIGZvciBVSFMtSSBjYXJkcyAqLw0KPj4gICAgICAgICBpZiAo
cm9jciAmIFNEX1JPQ1JfUzE4QSkgew0KPj4gICAgICAgICAgICAgICAgIGVyciA9IG1tY19zZF9p
bml0X3Voc19jYXJkKGNhcmQpOw0KPj4gQEAgLTEwMDIsNiArMTAxMCw3IEBAIHN0YXRpYyBpbnQg
bW1jX3NkX2luaXRfY2FyZChzdHJ1Y3QgbW1jX2hvc3QgKmhvc3QsIHUzMiBvY3IsDQo+PiAgICAg
ICAgICAgICAgICAgfQ0KPj4gICAgICAgICB9DQo+Pg0KPj4gK3VoczJfZG9uZToNCj4+ICAgICAg
ICAgaG9zdC0+PmNhcmQgPSBjYXJkOw0KPj4gICAgICAgICByZXR1cm4gMDsNCj4+DQo+PiBAQCAt
MTExOCw2ICsxMTI3LDkgQEAgc3RhdGljIGludCBfbW1jX3NkX3Jlc3VtZShzdHJ1Y3QgbW1jX2hv
c3QgKmhvc3QpDQo+PiAgICAgICAgIGlmICghbW1jX2NhcmRfc3VzcGVuZGVkKGhvc3QtPj5jYXJk
KSkNCj4+ICAgICAgICAgICAgICAgICBnb3RvIG91dDsNCj4+DQo+PiArICAgICAgIC8qIFRPRE86
IGZvciBVSFMyLCBtYXkgbmVlZCBVSFMyIGluaXQgcHJvY2VzcyB0byBiZSBleGVjdXRlZA0KPj4g
KyAgICAgICAgKiBhZ2FpbiAoREVWSUNFX0lOSVQvRU5VTUVSQVRFL0NPTkZJRywgZXRjKS4NCj4+
ICsgICAgICAgICovDQo+PiAgICAgICAgIG1tY19wb3dlcl91cChob3N0LCBob3N0LT4+Y2FyZC0+
Pm9jcik7DQo+PiAgICAgICAgIGVyciA9IG1tY19zZF9pbml0X2NhcmQoaG9zdCwgaG9zdC0+PmNh
cmQtPj5vY3IsIGhvc3QtPj5jYXJkKTsNCj4+ICAgICAgICAgbW1jX2NhcmRfY2xyX3N1c3BlbmRl
ZChob3N0LT4+Y2FyZCk7DQo+PiBAQCAtMTE4NSw2ICsxMTk3LDkgQEAgc3RhdGljIGludCBtbWNf
c2RfcG93ZXJfcmVzdG9yZShzdHJ1Y3QgbW1jX2hvc3QgKmhvc3QpDQo+PiAgICAgICAgIGludCBy
ZXQ7DQo+Pg0KPj4gICAgICAgICBtbWNfY2xhaW1faG9zdChob3N0KTsNCj4+ICsgICAgICAgLyog
VE9ETzogZm9yIFVIUzIsIG1heSBuZWVkIFVIUzIgaW5pdCBwcm9jZXNzIHRvIGJlIGV4ZWN1dGVk
DQo+PiArICAgICAgICAqIGFnYWluIChERVZJQ0VfSU5JVC9FTlVNRVJBVEUvQ09ORklHLCBldGMp
Lg0KPj4gKyAgICAgICAgKi8NCj4+ICAgICAgICAgcmV0ID0gbW1jX3NkX2luaXRfY2FyZChob3N0
LCBob3N0LT4+Y2FyZC0+Pm9jciwgaG9zdC0+PmNhcmQpOw0KPj4gICAgICAgICBtbWNfcmVsZWFz
ZV9ob3N0KGhvc3QpOw0KPj4NCj4+IGRpZmYgLS1naXQgYS9kcml2ZXJzL21tYy9jb3JlL3NkX29w
cy5jIGIvZHJpdmVycy9tbWMvY29yZS9zZF9vcHMuYw0KPj4gaW5kZXggNDhkMGM5My4uZmIyMTU4
ZiAxMDA2NDQNCj4+IC0tLSBhL2RyaXZlcnMvbW1jL2NvcmUvc2Rfb3BzLmMNCj4+ICsrKyBiL2Ry
aXZlcnMvbW1jL2NvcmUvc2Rfb3BzLmMNCj4+IEBAIC0zMCw2ICszMCwxOCBAQCBpbnQgbW1jX2Fw
cF9jbWQoc3RydWN0IG1tY19ob3N0ICpob3N0LCBzdHJ1Y3QgbW1jX2NhcmQgKmNhcmQpDQo+PiAg
ICAgICAgIEJVR19PTighaG9zdCk7DQo+PiAgICAgICAgIEJVR19PTihjYXJkICYmIChjYXJkLT4+
aG9zdCAhPSBob3N0KSk7DQo+Pg0KPj4gKyAgICAgICAvKiBVSFMyIHBhY2tldCBoYXMgQVBQIGJp
dCBzbyBvbmx5IHNldCBBUFBfQ01EIGZsYWcgaGVyZS4NCj4+ICsgICAgICAgICogV2lsbCBzZXQg
dGhlIEFQUCBiaXQgd2hlbiBhc3NlbWJsaW5nIFVIUzIgcGFja2V0Lg0KPj4gKyAgICAgICAgKi8N
Cj4+ICsgICAgICAgaWYgKGhvc3QtPj5mbGFncyAmICBNTUNfVUhTMl9TVVBQT1JUICYmDQo+PiAr
ICAgICAgICAgICBob3N0LT4+ZmxhZ3MgJiBNTUNfVUhTMl9JTklUSUFMSVpFRCkgew0KPj4gKyNp
ZmRlZiBDT05GSUdfTU1DX0RFQlVHDQo+PiArICAgICAgICAgICAgICAgcHJfaW5mbygiJXM6IGl0
IGlzIGFwcCBjbWQsIHNraXAgaXQhXG4iLCBtbWNfaG9zdG5hbWUoaG9zdCkpOw0KPj4gKyNlbmRp
Zg0KPj4gKyAgICAgICAgICAgICAgIGhvc3QtPj5mbGFncyB8PSBNTUNfVUhTMl9BUFBfQ01EOw0K
Pj4gKyAgICAgICAgICAgICAgIHJldHVybiAwOw0KPj4gKyAgICAgICB9DQo+PiArDQo+PiAgICAg
ICAgIGNtZC5vcGNvZGUgPSBNTUNfQVBQX0NNRDsNCj4+DQo+PiAgICAgICAgIGlmIChjYXJkKSB7
DQo+PiBkaWZmIC0tZ2l0IGEvZHJpdmVycy9tbWMvY29yZS91aHMyLmMgYi9kcml2ZXJzL21tYy9j
b3JlL3VoczIuYw0KPj4gbmV3IGZpbGUgbW9kZSAxMDA2NDQNCj4+IGluZGV4IDAwMDAwMDAuLjg2
YTFkZmENCj4+IC0tLSAvZGV2L251bGwNCj4+ICsrKyBiL2RyaXZlcnMvbW1jL2NvcmUvdWhzMi5j
DQo+PiBAQCAtMCwwICsxLDkwOCBAQA0KPj4gKy8qDQo+PiArICogIGxpbnV4L2RyaXZlcnMvbW1j
L2NvcmUvdWhzMi5jDQo+PiArICoNCj4+ICsgKiAgQ29weXJpZ2h0IChDKSAyMDE0IEludGVsIENv
cnAsIEFsbCBSaWdodHMgUmVzZXJ2ZWQuDQo+PiArICoNCj4+ICsgKiBUaGlzIHByb2dyYW0gaXMg
ZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeQ0KPj4g
KyAqIGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2Ug
dmVyc2lvbiAyIGFzDQo+PiArICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5k
YXRpb24uDQo+PiArICovDQo+PiArDQo+PiArI2luY2x1ZGUgPGxpbnV4L2Vyci5oPj4NCj4+ICsj
aW5jbHVkZSA8bGludXgvc2xhYi5oPj4NCj4+ICsNCj4+ICsjaW5jbHVkZSA8bGludXgvbW1jL2hv
c3QuaD4+DQo+PiArI2luY2x1ZGUgPGxpbnV4L21tYy9jYXJkLmg+Pg0KPj4gKyNpbmNsdWRlIDxs
aW51eC9tbWMvbW1jLmg+Pg0KPj4gKyNpbmNsdWRlIDxsaW51eC9tbWMvY29yZS5oPj4NCj4+ICsj
aW5jbHVkZSA8bGludXgvbW1jL3NkaW8uaD4+DQo+PiArI2luY2x1ZGUgPGxpbnV4L21tYy9zbG90
LWdwaW8uaD4+DQo+PiArI2luY2x1ZGUgPGxpbnV4L21tYy91aHMyLmg+Pg0KPj4gKw0KPj4gKyNp
bmNsdWRlICJ1aHMyLmgiDQo+PiArI2luY2x1ZGUgIm1tY19vcHMuaCINCj4+ICsjaW5jbHVkZSAi
c2Rfb3BzLmgiDQo+PiArI2luY2x1ZGUgImNvcmUuaCINCj4+ICsNCj4+ICsjZGVmaW5lIERCRyhm
LCB4Li4uKSBcDQo+PiArICAgICAgIHByX3dhcm4oIlslcygpXTogIiBmLCBfX2Z1bmNfXywgIyMg
eCkNCj4+ICsNCj4+ICsvKg0KPj4gKyAqIFRPRE86IHBheWxvYWQsIHVoczJfY21kIGFyZSBhbGwg
YWxsb2NhdGVkIHdoaWNoIHNob3VsZCBiZSBmcmVlZCB3aGVuDQo+PiArICogcmVzcG9uc2UgaXMg
Z290Lg0KPj4gKyAqIHJlc3AgaXMgaW5wdXR0ZWQgb3V0c2lkZSB3aGljaCBzaG91bGQgYmUgYSB2
YXJpYWJsZSBjcmVhdGVkIGJ5IGNhbGxlcg0KPj4gKyAqIHNvIGNhbGxlciBzaG91bGQgaGFuZGxl
IGl0LiBGb3IgU0QgY29tbWFuZCwgdGhlcmUgaXMgbm8gdWhzMl9yZXNwIGFuZA0KPj4gKyAqIHJl
c3BvbnNlIHNob3VsZCBiZSBzdG9yZWQgaW4gcmVzcCBvZiBtbWNfY29tbWFuZC4NCj4+ICsgKi8N
Cj4+ICtpbnQgdWhzMl9jbWRfYXNzZW1ibGUoc3RydWN0IG1tY19jb21tYW5kICpjbWQsIHUxNiBo
ZWFkZXIsIHUxNiBhcmcsDQo+PiArICAgICAgICAgICAgICAgICAgICAgICB1MzIgKnBheWxvYWQs
IHU4IHBsZW4sIHU4ICpyZXNwLCB1OCByZXNwX2xlbikNCj4+ICt7DQo+PiArICAgICAgIHN0cnVj
dCB1aHMyX2NvbW1hbmQgKnVoczJfY21kOw0KPj4gKw0KPj4gKyAgICAgICBpZiAoY21kID09IE5V
TEwgfHwgcGF5bG9hZCA9PSBOVUxMIHx8IHJlc3AgPT0gTlVMTCkNCj4+ICsgICAgICAgICAgICAg
ICByZXR1cm4gLUVJTzsNCj4+ICsNCj4+ICsgICAgICAgdWhzMl9jbWQgPSBremFsbG9jKHNpemVv
ZihzdHJ1Y3QgdWhzMl9jb21tYW5kKSwNCj4+ICsgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgIEdGUF9LRVJORUwpOw0KPj4gKyAgICAgICBpZiAoIXVoczJfY21k
KSB7DQo+PiArICAgICAgICAgICAgICAga2ZyZWUocGF5bG9hZCk7DQo+PiArICAgICAgICAgICAg
ICAgcmV0dXJuIC1FTk9NRU07DQo+PiArICAgICAgIH0NCj4+ICsNCj4+ICsgICAgICAgdWhzMl9j
bWQtPj5oZWFkZXIgPSBoZWFkZXI7DQo+PiArICAgICAgIHVoczJfY21kLT4+YXJnID0gYXJnOw0K
Pj4gKyAgICAgICB1aHMyX2NtZC0+PnBheWxvYWQgPSBwYXlsb2FkOw0KPj4gKyAgICAgICB1aHMy
X2NtZC0+PnBheWxvYWRfbGVuID0gcGxlbiAqIHNpemVvZih1MzIpOw0KPj4gKyAgICAgICB1aHMy
X2NtZC0+PnBhY2tldF9sZW4gPSB1aHMyX2NtZC0+PnBheWxvYWRfbGVuICsgNDsNCj4+ICsNCj4+
ICsgICAgICAgY21kLT4+dWhzMl9jbWQgPSB1aHMyX2NtZDsNCj4+ICsgICAgICAgY21kLT4+dWhz
Ml9yZXNwID0gcmVzcDsNCj4+ICsgICAgICAgY21kLT4+dWhzMl9yZXNwX2xlbiA9IHJlc3BfbGVu
Ow0KPj4gKw0KPj4gKyNpZmRlZiBDT05GSUdfTU1DX0RFQlVHDQo+PiArICAgICAgIHByX2luZm8o
IiVzOiB1aHMyX2NtZC0+PmhlYWRlciA9IDB4JXgsIHVoczJfY21kLT4+YXJnID0gMHgleCwiDQo+
PiArICAgICAgICAgICAgICAgIiB1aHMyX2NtZC0+PnBheWxvYWRfbGVuID0gJWQsIHVoczJfY21k
LT4+cGFja2V0X2xlbiA9ICVkLCINCj4+ICsgICAgICAgICAgICAgICAiIHJlc3BfbGVuID0gJWQu
XG4iLA0KPj4gKyAgICAgICAgICAgICAgIF9fZnVuY19fLCB1aHMyX2NtZC0+PmhlYWRlciwNCj4+
ICsgICAgICAgICAgICAgICB1aHMyX2NtZC0+PmFyZywgdWhzMl9jbWQtPj5wYXlsb2FkX2xlbiwg
dWhzMl9jbWQtPj5wYWNrZXRfbGVuLA0KPj4gKyAgICAgICAgICAgICAgIGNtZC0+PnVoczJfcmVz
cF9sZW4pOw0KPj4gKyNlbmRpZg0KPj4gKw0KPj4gKyAgICAgICByZXR1cm4gMDsNCj4+ICt9DQo+
PiArRVhQT1JUX1NZTUJPTF9HUEwodWhzMl9jbWRfYXNzZW1ibGUpOw0KPj4gKw0KPj4gK2ludCB1
aHMyX3ByZXBhcmVfc2RfY21kKHN0cnVjdCBtbWNfaG9zdCAqaG9zdCwgc3RydWN0IG1tY19yZXF1
ZXN0ICptcnEpDQo+PiArew0KPj4gKyAgICAgICBzdHJ1Y3QgbW1jX2NvbW1hbmQgKmNtZDsNCj4+
ICsgICAgICAgdTE2IGhlYWRlciA9IDAsIGFyZyA9IDA7DQo+PiArICAgICAgIHUzMiAqcGF5bG9h
ZDsNCj4+ICsgICAgICAgdTggcGxlbiA9IDA7DQo+PiArICAgICAgIGludCBlcnIgPSAwOw0KPj4g
Kw0KPj4gKyAgICAgICBjbWQgPSBtcnEtPj5jbWQ7DQo+PiArICAgICAgIGhlYWRlciA9IGhvc3Qt
Pj51aHMyX2Rldl9wcm9wLm5vZGVfaWQ7DQo+PiArICAgICAgIGlmIChjbWQtPj5mbGFncyAmIE1N
Q19DTURfQURUQykNCj4+ICsgICAgICAgICAgICAgICBoZWFkZXIgfD0gVUhTMl9QQUNLRVRfVFlQ
RV9EQ01EOw0KPj4gKyAgICAgICBlbHNlDQo+PiArICAgICAgICAgICAgICAgaGVhZGVyIHw9IFVI
UzJfUEFDS0VUX1RZUEVfQ0NNRDsNCj4+ICsgICAgICAgREJHKCJoZWFkZXIgPSAweCV4LlxuIiwg
aGVhZGVyKTsNCj4+ICsNCj4+ICsgICAgICAgYXJnID0gY21kLT4+b3Bjb2RlIDw8IFVIUzJfU0Rf
Q01EX0lOREVYX1BPUzsNCj4+ICsgICAgICAgaWYgKGhvc3QtPj5mbGFncyAmIE1NQ19VSFMyX0FQ
UF9DTUQpIHsNCj4+ICsgICAgICAgICAgICAgICBhcmcgfD0gVUhTMl9TRF9DTURfQVBQOw0KPj4g
KyAgICAgICAgICAgICAgIGhvc3QtPj5mbGFncyAmPSB+TU1DX1VIUzJfQVBQX0NNRDsNCj4+ICsg
ICAgICAgfQ0KPj4gKw0KPj4gKyAgICAgICBpZiAoY21kLT4+ZmxhZ3MgJiBNTUNfQ01EX0FEVEMp
IHsNCj4+ICsgICAgICAgICAgICAgICAvKiBUT0RPOiBkbyBub3QgdW5kZXJzdGFuZC4gSXQgbWF5
IHJlbGF0ZXMgd2l0aCBBRE1BMy4gKi8NCj4+ICsgICAgICAgICAgICAgICBpZiAoY21kLT4+ZGF0
YS0+PmJsb2NrcyA+PiAxKSB7DQo+PiArICAgICAgICAgICAgICAgICAgICAgICBwYXlsb2FkID0g
a3phbGxvYyg0KnNpemVvZih1MzIpLCBHRlBfS0VSTkVMKTsNCj4+ICsgICAgICAgICAgICAgICAg
ICAgICAgIGlmICghcGF5bG9hZCkNCj4+ICsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
cmV0dXJuIC1FTk9NRU07DQo+PiArICAgICAgICAgICAgICAgICAgICAgICBwYXlsb2FkWzJdID0g
MDsNCj4+ICsgICAgICAgICAgICAgICAgICAgICAgIHBheWxvYWRbM10gPSAwOw0KPj4gKyAgICAg
ICAgICAgICAgICAgICAgICAgcGxlbiA9IDggLyBzaXplb2YodTMyKTsNCj4+ICsgICAgICAgICAg
ICAgICB9IGVsc2Ugew0KPj4gKyAgICAgICAgICAgICAgICAgICAgICAgcGF5bG9hZCA9IGt6YWxs
b2MoMipzaXplb2YodTMyKSwgR0ZQX0tFUk5FTCk7DQo+PiArICAgICAgICAgICAgICAgICAgICAg
ICBpZiAoIXBheWxvYWQpDQo+PiArICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVy
biAtRU5PTUVNOw0KPj4gKyAgICAgICAgICAgICAgICAgICAgICAgcGxlbiA9IDggLyBzaXplb2Yo
dTMyKTsNCj4+ICsgICAgICAgICAgICAgICB9DQo+PiArDQo+PiArICAgICAgICAgICAgICAgaWYg
KGhvc3QtPj5mbGFncyAmIE1NQ19VSFMyXzJMX0hEKQ0KPj4gKyAgICAgICAgICAgICAgICAgICAg
ICAgYXJnIHw9IFVIUzJfRENNRF8yTF9IRF9NT0RFOw0KPj4gKw0KPj4gKyAgICAgICAgICAgICAg
IGFyZyB8PSBVSFMyX0RDTURfTE1fVExFTl9FWElTVDsNCj4+ICsNCj4+ICsgICAgICAgICAgICAg
ICBpZiAoY21kLT4+ZGF0YS0+PmJsb2NrcyA9PSAxICYmDQo+PiArICAgICAgICAgICAgICAgICAg
IGNtZC0+Pm9wY29kZSAhPSBNTUNfUkVBRF9TSU5HTEVfQkxPQ0sgJiYNCj4+ICsgICAgICAgICAg
ICAgICAgICAgY21kLT4+b3Bjb2RlICE9IE1NQ19XUklURV9CTE9DSykgew0KPj4gKyAgICAgICAg
ICAgICAgICAgICAgICAgYXJnIHw9IFVIUzJfRENNRF9UTFVNX0JZVEVfTU9ERTsNCj4+ICsgICAg
ICAgICAgICAgICAgICAgICAgIHBheWxvYWRbMV0gPSB1aHMyX2RjbWRfY29udmVydF9tc2IoY21k
LT4+ZGF0YS0+PmJsa3N6KTsNCj4+ICsgICAgICAgICAgICAgICB9IGVsc2Ugew0KPj4gKyAgICAg
ICAgICAgICAgICAgICAgICAgcGF5bG9hZFsxXSA9IHVoczJfZGNtZF9jb252ZXJ0X21zYihjbWQt
Pj5kYXRhLT4+YmxvY2tzKTsNCj4+ICsgICAgICAgICAgICAgICB9DQo+PiArDQo+PiArICAgICAg
ICAgICAgICAgaWYgKGNtZC0+Pm9wY29kZSA9PSBTRF9JT19SV19FWFRFTkRFRCkgew0KPj4gKyAg
ICAgICAgICAgICAgICAgICAgICAgYXJnICY9IH4oVUhTMl9EQ01EX0xNX1RMRU5fRVhJU1QgfA0K
Pj4gKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVSFMyX0RDTURfVExVTV9CWVRFX01P
REUgfA0KPj4gKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVSFMyX05BVElWRV9EQ01E
X0RBTV9JTyk7DQo+PiArICAgICAgICAgICAgICAgICAgICAgICBwYXlsb2FkWzFdID0gMDsNCj4+
ICsgICAgICAgICAgICAgICAgICAgICAgIHBsZW4gPSA0IC8gc2l6ZW9mKHUzMik7DQo+PiArICAg
ICAgICAgICAgICAgfQ0KPj4gKyAgICAgICB9IGVsc2Ugew0KPj4gKyAgICAgICAgICAgICAgIHBh
eWxvYWQgPSBremFsbG9jKDEgKiBzaXplb2YodTMyKSwgR0ZQX0tFUk5FTCk7DQo+PiArICAgICAg
ICAgICAgICAgaWYgKCFwYXlsb2FkKQ0KPj4gKyAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJu
IC1FTk9NRU07DQo+PiArICAgICAgICAgICAgICAgcGxlbiA9IDQgLyBzaXplb2YodTMyKTsNCj4+
ICsgICAgICAgfQ0KPj4gKw0KPj4gKyAgICAgICBwYXlsb2FkWzBdID0gdWhzMl9kY21kX2NvbnZl
cnRfbXNiKGNtZC0+PmFyZyk7DQo+PiArI2lmZGVmIENPTkZJR19NTUNfREVCVUcNCj4+ICsgICAg
ICAgcHJfaW5mbygiJXM6ICVzOiBzZF9jbWQtPj5hcmcgPSAweCV4LCBwYXlsb2FkWzBdPSAweCV4
LlxuIiwNCj4+ICsgICAgICAgICAgICAgICAgbW1jX2hvc3RuYW1lKGhvc3QpLCBfX2Z1bmNfXywg
Y21kLT4+YXJnLCBwYXlsb2FkWzBdKTsNCj4+ICsjZW5kaWYNCj4+ICsNCj4+ICsgICAgICAgZXJy
ID0gdWhzMl9jbWRfYXNzZW1ibGUoY21kLCBoZWFkZXIsIGFyZywgcGF5bG9hZCwgcGxlbiwNCj4+
ICsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTlVMTCwgMCk7DQo+PiArDQo+PiArICAg
ICAgIHJldHVybiBlcnI7DQo+PiArfQ0KPj4gK0VYUE9SVF9TWU1CT0xfR1BMKHVoczJfcHJlcGFy
ZV9zZF9jbWQpOw0KPj4gKw0KPj4gKy8qDQo+PiArICogQXBwbHkgcG93ZXIgdG8gdGhlIFVIUzIg
c3RhY2suICBUaGlzIGlzIGEgdHdvLXN0YWdlIHByb2Nlc3MuDQo+PiArICogRmlyc3QsIHdlIGVu
YWJsZSBwb3dlciB0byB0aGUgY2FyZCB3aXRob3V0IHRoZSBjbG9jayBydW5uaW5nLg0KPj4gKyAq
IFdlIHRoZW4gd2FpdCBhIGJpdCBmb3IgdGhlIHBvd2VyIHRvIHN0YWJpbGlzZS4gIEZpbmFsbHks
DQo+PiArICogZW5hYmxlIHRoZSBidXMgZHJpdmVycyBhbmQgY2xvY2sgdG8gdGhlIGNhcmQuDQo+
PiArICoNCj4+ICsgKiBXZSBtdXN0IF9OT1RfIGVuYWJsZSB0aGUgY2xvY2sgcHJpb3IgdG8gcG93
ZXIgc3RhYmxpc2luZy4NCj4+ICsgKg0KPj4gKyAqIElmIGEgaG9zdCBkb2VzIGFsbCB0aGUgcG93
ZXIgc2VxdWVuY2luZyBpdHNlbGYsIGlnbm9yZSB0aGUNCj4+ICsgKiBpbml0aWFsIE1NQ19QT1dF
Ul9VUCBzdGFnZS4NCj4+ICsgKi8NCj4+ICt2b2lkIHVoczJfcG93ZXJfdXAoc3RydWN0IG1tY19o
b3N0ICpob3N0KQ0KPj4gK3sNCj4+ICsgICAgICAgaWYgKGhvc3QtPj5pb3MucG93ZXJfbW9kZSA9
PSBNTUNfUE9XRVJfT04pDQo+PiArICAgICAgICAgICAgICAgcmV0dXJuOw0KPj4gKw0KPj4gKyAg
ICAgICBEQkcoIkVudGVyIVxuIik7DQo+PiArICAgICAgIG1tY19ob3N0X2Nsa19ob2xkKGhvc3Qp
Ow0KPj4gKw0KPj4gKyAgICAgICBob3N0LT4+aW9zLnZkZCA9IGZscyhob3N0LT4+b2NyX2F2YWls
KSAtIDE7DQo+PiArICAgICAgIGhvc3QtPj5pb3MudmRkMiA9IGZscyhob3N0LT4+b2NyX2F2YWls
X3VoczIpIC0gMTsNCj4+ICsgICAgICAgaWYgKG1tY19ob3N0X2lzX3NwaShob3N0KSkNCj4+ICsg
ICAgICAgICAgICAgICBob3N0LT4+aW9zLmNoaXBfc2VsZWN0ID0gTU1DX0NTX0hJR0g7DQo+PiAr
ICAgICAgIGVsc2UNCj4+ICsgICAgICAgICAgICAgICBob3N0LT4+aW9zLmNoaXBfc2VsZWN0ID0g
TU1DX0NTX0RPTlRDQVJFOw0KPj4gKyAgICAgICBob3N0LT4+aW9zLmNsb2NrID0gaG9zdC0+PmZf
aW5pdDsNCj4+ICsgICAgICAgaG9zdC0+Pmlvcy50aW1pbmcgPSBNTUNfVElNSU5HX1VIUzI7DQo+
PiArICAgICAgIGhvc3QtPj5pb3MucG93ZXJfbW9kZSA9IE1NQ19QT1dFUl9PTjsNCj4+ICsgICAg
ICAgbW1jX3NldF9pb3MoaG9zdCk7DQo+PiArDQo+PiArICAgICAgIC8qDQo+PiArICAgICAgICAq
IFRoaXMgZGVsYXkgc2hvdWxkIGJlIHN1ZmZpY2llbnQgdG8gYWxsb3cgdGhlIHBvd2VyIHN1cHBs
eQ0KPj4gKyAgICAgICAgKiB0byByZWFjaCB0aGUgbWluaW11bSB2b2x0YWdlLg0KPj4gKyAgICAg
ICAgKi8NCj4+ICsgICAgICAgbW1jX2RlbGF5KDEwKTsNCj4+ICsNCj4+ICsgICAgICAgbW1jX2hv
c3RfY2xrX3JlbGVhc2UoaG9zdCk7DQo+PiArfQ0KPj4gK0VYUE9SVF9TWU1CT0xfR1BMKHVoczJf
cG93ZXJfdXApOw0KPj4gKw0KPj4gK3N0YXRpYyBpbnQgdWhzMl9kZXZfaW5pdChzdHJ1Y3QgbW1j
X2hvc3QgKmhvc3QpDQo+PiArew0KPj4gKyAgICAgICBzdHJ1Y3QgbW1jX2NvbW1hbmQgY21kID0g
ezB9Ow0KPj4gKyAgICAgICB1MzIgY250Ow0KPj4gKyAgICAgICB1MzIgZGFwLCBnYXAsIGdhcDE7
DQo+PiArICAgICAgIHUxNiBoZWFkZXIgPSAwLCBhcmcgPSAwOw0KPj4gKyAgICAgICB1MzIgKnBh
eWxvYWQ7DQo+PiArICAgICAgIHU4IHBsZW4gPSAxOw0KPj4gKyAgICAgICB1OCBnZCA9IDAsIGNm
ID0gMTsNCj4+ICsgICAgICAgdTggcmVzcFs2XSA9IHswfTsNCj4+ICsgICAgICAgdTggcmVzcF9s
ZW4gPSA2Ow0KPj4gKyAgICAgICBpbnQgZXJyOw0KPj4gKw0KPj4gKyAgICAgICBkYXAgPSBob3N0
LT4+dWhzMl9jYXBzLmRhcDsNCj4+ICsgICAgICAgZ2FwID0gaG9zdC0+PnVoczJfY2Fwcy5nYXA7
DQo+PiArICAgICAgIERCRygiZGFwID0gMHgleCwgZ2FwID0gMHgleC5cbiIsIGRhcCwgZ2FwKTsN
Cj4+ICsNCj4+ICsgICAgICAgaGVhZGVyID0gVUhTMl9OQVRJVkVfUEFDS0VUIHwgVUhTMl9QQUNL
RVRfVFlQRV9DQ01EOw0KPj4gKyAgICAgICBhcmcgPSAoKFVIUzJfREVWX0NNRF9ERVZJQ0VfSU5J
VCAmIDB4RkYpIDw8IDgpIHwNCj4+ICsgICAgICAgICAgICAgICBVSFMyX05BVElWRV9DTURfV1JJ
VEUgfA0KPj4gKyAgICAgICAgICAgICAgIFVIUzJfTkFUSVZFX0NNRF9QTEVOXzRCIHwNCj4+ICsg
ICAgICAgICAgICAgICAoVUhTMl9ERVZfQ01EX0RFVklDRV9JTklUID4+Pj4gOCk7DQo+PiArDQo+
PiArICAgICAgIHBheWxvYWQgPSBrY2FsbG9jKHBsZW4sIHNpemVvZih1MzIpLCBHRlBfS0VSTkVM
KTsNCj4+ICsgICAgICAgaWYgKCFwYXlsb2FkKQ0KPj4gKyAgICAgICAgICAgICAgIHJldHVybiAt
RU5PTUVNOw0KPj4gKyAgICAgICBwYXlsb2FkWzBdID0gKChkYXAgJiAweEYpIDw8IDEyKSB8DQo+
PiArICAgICAgICAgICAgICAgICAoY2YgPDwgMTEpIHwNCj4+ICsgICAgICAgICAgICAgICAgICgo
Z2QgJiAweEYpIDw8IDQpIHwNCj4+ICsgICAgICAgICAgICAgICAgIChnYXAgJiAweEYpOw0KPj4g
Kw0KPj4gKyAgICAgICBlcnIgPSB1aHMyX2NtZF9hc3NlbWJsZSgmY21kLCBoZWFkZXIsIGFyZywg
cGF5bG9hZCwgcGxlbiwNCj4+ICsgICAgICAgICAgICAgICAgICAgICAgIHJlc3AsIHJlc3BfbGVu
KTsNCj4+ICsgICAgICAgaWYgKGVycikgew0KPj4gKyAgICAgICAgICAgICAgIHByX2VycigiJXM6
ICVzOiBVSFMyIENNRCBhc3NlbWJsaW5nIGVyciA9IDB4JXghXG4iLA0KPj4gKyAgICAgICAgICAg
ICAgICAgICAgICAgbW1jX2hvc3RuYW1lKGhvc3QpLCBfX2Z1bmNfXywgZXJyKTsNCj4+ICsgICAg
ICAgICAgICAgICByZXR1cm4gLUVJTzsNCj4+ICsgICAgICAgfQ0KPj4gKw0KPj4gKyAgICAgICBE
QkcoIkJlZ2luIERFVklDRV9JTklULCBoZWFkZXI9MHgleCwgYXJnPTB4JXgsIHBheWxvYWQ9MHgl
eC5cbiIsDQo+PiArICAgICAgICAgICAgICAgaGVhZGVyLCBhcmcsIHBheWxvYWRbMF0pOw0KPj4g
KyAgICAgICBmb3IgKGNudCA9IDA7IGNudCA8IDMwOyBjbnQrKykgew0KPj4gKyAgICAgICAgICAg
ICAgIERCRygiU2VuZGluZyBERVZJQ0VfSU5JVC4gQ291bnQgPSAlZFxuIiwgY250KTsNCj4+ICsg
ICAgICAgICAgICAgICBlcnIgPSBtbWNfd2FpdF9mb3JfY21kKGhvc3QsICZjbWQsIDApOw0KPj4g
KyAgICAgICAgICAgICAgIGlmIChlcnIpIHsNCj4+ICsgICAgICAgICAgICAgICAgICAgICAgIHBy
X2VycigiJXM6ICVzOiBVSFMyIENNRCBzZW5kIGZhaWwsIGVycj0gMHgleCFcbiIsDQo+PiArICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1tY19ob3N0bmFtZShob3N0KSwgX19mdW5jX18s
IGVycik7DQo+PiArICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gLUVJTzsNCj4+ICsgICAg
ICAgICAgICAgICB9DQo+PiArDQo+PiArI2lmZGVmIENPTkZJR19NTUNfREVCVUcNCj4+ICsgICAg
ICAgICAgICAgICBpbnQgaTsNCj4+ICsNCj4+ICsgICAgICAgICAgICAgICBwcl93YXJuKCIlczog
REVWSUNFX0lOSVQgcmVzcG9uc2UgaXM6ICIsIG1tY19ob3N0bmFtZShob3N0KSk7DQo+PiArICAg
ICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IHJlc3BfbGVuOyBpKyspDQo+PiArICAgICAgICAg
ICAgICAgICAgICAgICBwcl93YXJuKCIweCV4ICIsIHJlc3BbaV0pOw0KPj4gKyAgICAgICAgICAg
ICAgIHByX3dhcm4oIlxuIik7DQo+PiArI2VuZGlmDQo+PiArDQo+PiArICAgICAgICAgICAgICAg
aWYgKHJlc3BbM10gIT0gKFVIUzJfREVWX0NNRF9ERVZJQ0VfSU5JVCAmIDB4RkYpKSB7DQo+PiAr
ICAgICAgICAgICAgICAgICAgICAgICBwcl9lcnIoIiVzOiBERVZJQ0VfSU5JVCByZXNwb25zZSBp
cyB3cm9uZyFcbiIsDQo+PiArICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1tY19ob3N0
bmFtZShob3N0KSk7DQo+PiArICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gLUVJTzsNCj4+
ICsgICAgICAgICAgICAgICB9DQo+PiArDQo+PiArICAgICAgICAgICAgICAgaWYgKHJlc3BbNV0g
JiAweDgpIHsNCj4+ICsgICAgICAgICAgICAgICAgICAgICAgIERCRygiQ0YgaXMgc2V0LCBkZXZp
Y2UgaXMgaW5pdGlhbGl6ZWQhXG4iKTsNCj4+ICsgICAgICAgICAgICAgICAgICAgICAgIGhvc3Qt
Pj5ncm91cF9kZXNjID0gZ2Q7DQo+PiArICAgICAgICAgICAgICAgfSBlbHNlIHsNCj4+ICsgICAg
ICAgICAgICAgICAgICAgICAgIGdhcDEgPSByZXNwWzRdICYgMHgwRjsNCj4+ICsgICAgICAgICAg
ICAgICAgICAgICAgIGlmIChnYXAgPT0gZ2FwMSkNCj4+ICsgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgZ2QrKzsNCj4+ICsgICAgICAgICAgICAgICB9DQo+PiArICAgICAgIH0NCj4+ICsg
ICAgICAgaWYgKDMwID09IGNudCkgew0KPj4gKyAgICAgICAgICAgICAgIHByX2VycigiJXM6IERF
VklDRV9JTklUIGZhaWwsIGFscmVhZHkgMzAgdGltZXMhXG4iLA0KPj4gKyAgICAgICAgICAgICAg
ICAgICAgICAgbW1jX2hvc3RuYW1lKGhvc3QpKTsNCj4+ICsgICAgICAgICAgICAgICByZXR1cm4g
LUVJTzsNCj4+ICsgICAgICAgfQ0KPj4gKw0KPj4gKyAgICAgICByZXR1cm4gMDsNCj4+ICt9DQo+
PiArDQo+PiArc3RhdGljIGludCB1aHMyX2VudW0oc3RydWN0IG1tY19ob3N0ICpob3N0KQ0KPj4g
K3sNCj4+ICsgICAgICAgc3RydWN0IG1tY19jb21tYW5kIGNtZCA9IHswfTsNCj4+ICsgICAgICAg
dTE2IGhlYWRlciA9IDAsIGFyZyA9IDA7DQo+PiArICAgICAgIHUzMiAqcGF5bG9hZDsNCj4+ICsg
ICAgICAgdTggcGxlbiA9IDE7DQo+PiArICAgICAgIHU4IGlkX2YgPSAweEYsIGlkX2wgPSAweDA7
DQo+PiArICAgICAgIHU4IHJlc3BbOF0gPSB7MH07DQo+PiArICAgICAgIHU4IHJlc3BfbGVuID0g
ODsNCj4+ICsgICAgICAgaW50IGVycjsNCj4+ICsNCj4+ICsgICAgICAgaGVhZGVyID0gVUhTMl9O
QVRJVkVfUEFDS0VUIHwgVUhTMl9QQUNLRVRfVFlQRV9DQ01EOw0KPj4gKyAgICAgICBhcmcgPSAo
KFVIUzJfREVWX0NNRF9FTlVNRVJBVEUgJiAweEZGKSA8PCA4KSB8DQo+PiArICAgICAgICAgICAg
ICAgVUhTMl9OQVRJVkVfQ01EX1dSSVRFIHwNCj4+ICsgICAgICAgICAgICAgICBVSFMyX05BVElW
RV9DTURfUExFTl80QiB8DQo+PiArICAgICAgICAgICAgICAgKFVIUzJfREVWX0NNRF9FTlVNRVJB
VEUgPj4+PiA4KTsNCj4+ICsNCj4+ICsgICAgICAgcGF5bG9hZCA9IGtjYWxsb2MocGxlbiwgc2l6
ZW9mKHUzMiksIEdGUF9LRVJORUwpOw0KPj4gKyAgICAgICBpZiAoIXBheWxvYWQpDQo+PiArICAg
ICAgICAgICAgICAgcmV0dXJuIC1FTk9NRU07DQo+PiArICAgICAgIHBheWxvYWRbMF0gPSAoaWRf
ZiA8PCA0KSB8IGlkX2w7DQo+PiArDQo+PiArICAgICAgIERCRygiQmVnaW4gRU5VTUVSQVRFLCBo
ZWFkZXI9MHgleCwgYXJnPTB4JXgsIHBheWxvYWQ9MHgleC5cbiIsDQo+PiArICAgICAgICAgICAg
ICAgaGVhZGVyLCBhcmcsIHBheWxvYWRbMF0pOw0KPj4gKyAgICAgICBlcnIgPSB1aHMyX2NtZF9h
c3NlbWJsZSgmY21kLCBoZWFkZXIsIGFyZywgcGF5bG9hZCwgcGxlbiwNCj4+ICsgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgcmVzcCwgcmVzcF9sZW4pOw0KPj4gKyAgICAgICBpZiAoZXJy
KSB7DQo+PiArICAgICAgICAgICAgICAgcHJfZXJyKCIlczogJXM6IFVIUzIgQ01EIGFzc2VtYmxp
bmcgZXJyID0gMHgleCFcbiIsDQo+PiArICAgICAgICAgICAgICAgICAgICAgICBtbWNfaG9zdG5h
bWUoaG9zdCksIF9fZnVuY19fLCBlcnIpOw0KPj4gKyAgICAgICAgICAgICAgIHJldHVybiAtRUlP
Ow0KPj4gKyAgICAgICB9DQo+PiArDQo+PiArICAgICAgIGVyciA9IG1tY193YWl0X2Zvcl9jbWQo
aG9zdCwgJmNtZCwgMCk7DQo+PiArICAgICAgIGlmIChlcnIpIHsNCj4+ICsgICAgICAgICAgICAg
ICBwcl9lcnIoIiVzOiAlczogVUhTMiBDTUQgc2VuZCBmYWlsLCBlcnI9IDB4JXghXG4iLA0KPj4g
KyAgICAgICAgICAgICAgICAgICAgICAgbW1jX2hvc3RuYW1lKGhvc3QpLCBfX2Z1bmNfXywgZXJy
KTsNCj4+ICsgICAgICAgICAgICAgICByZXR1cm4gLUVJTzsNCj4+ICsgICAgICAgfQ0KPj4gKw0K
Pj4gKyNpZmRlZiBDT05GSUdfTU1DX0RFQlVHDQo+PiArICAgICAgIGludCBpOw0KPj4gKw0KPj4g
KyAgICAgICBwcl93YXJuKCIlczogRU5VTUVSQVRFIHJlc3BvbnNlIGlzOiAiLCBtbWNfaG9zdG5h
bWUoaG9zdCkpOw0KPj4gKyAgICAgICBmb3IgKGkgPSAwOyBpIDwgcmVzcF9sZW47IGkrKykNCj4+
ICsgICAgICAgICAgICAgICBwcl93YXJuKCIweCV4ICIsIHJlc3BbaV0pOw0KPj4gKyAgICAgICBw
cl93YXJuKCJcbiIpOw0KPj4gKyNlbmRpZg0KPj4gKw0KPj4gKyAgICAgICBpZiAocmVzcFszXSAh
PSAoVUhTMl9ERVZfQ01EX0VOVU1FUkFURSAmIDB4RkYpKSB7DQo+PiArICAgICAgICAgICAgICAg
cHJfZXJyKCIlczogRU5VTUVSQVRFIHJlc3BvbnNlIGlzIHdyb25nIVxuIiwNCj4+ICsgICAgICAg
ICAgICAgICAgICAgICAgIG1tY19ob3N0bmFtZShob3N0KSk7DQo+PiArICAgICAgICAgICAgICAg
cmV0dXJuIC1FSU87DQo+PiArICAgICAgIH0NCj4+ICsNCj4+ICsgICAgICAgLyogVE9ETzogc2hh
bGwgSSBrZWVwIGlkX2Ygb3IgaWRfbCBhcyBkZXZpY2Ugbm9kZSBpZD8NCj4+ICsgICAgICAgICog
Rm9yIFAyUCBjb25uZWN0aW9uLCBJIHRoaW5rIGlkX2YgaXMgb2suDQo+PiArICAgICAgICAqLw0K
Pj4gKyAgICAgICBpZF9mID0gKHJlc3BbNF0gPj4+PiA0KSAmIDB4RjsNCj4+ICsgICAgICAgaWRf
bCA9IHJlc3BbNF0gJiAweEY7DQo+PiArICAgICAgIERCRygiaWRfZiA9ICVkLCBpZF9sID0gJWQu
XG4iLCBpZF9mLCBpZF9sKTsNCj4+ICsgICAgICAgREJHKCJFbnVtZXJhdGUgQ21kIENvbXBsZXRl
ZC4gTm8uIG9mIERldmljZXMgY29ubmVjdGVkID0gJWRcbiIsDQo+PiArICAgICAgICAgICAgICAg
aWRfbCAtIGlkX2YgKyAxKTsNCj4+ICsgICAgICAgaG9zdC0+PnVoczJfZGV2X3Byb3Aubm9kZV9p
ZCA9IGlkX2Y7DQo+PiArDQo+PiArICAgICAgIHJldHVybiAwOw0KPj4gK30NCj4+ICsNCj4+ICtz
dGF0aWMgaW50IHVoczJfY29uZmlnX3JlYWQoc3RydWN0IG1tY19ob3N0ICpob3N0KQ0KPj4gK3sN
Cj4+ICsgICAgICAgc3RydWN0IG1tY19jb21tYW5kIGNtZCA9IHswfTsNCj4+ICsgICAgICAgdTE2
IGhlYWRlciA9IDAsIGFyZyA9IDA7DQo+PiArICAgICAgIHUzMiBjYXA7DQo+PiArICAgICAgIGlu
dCBlcnI7DQo+PiArDQo+PiArICAgICAgIERCRygiSU5RVUlSWV9DRkc6IHJlYWQgR2VuZXJpYyBD
YXBzLlxuIik7DQo+PiArICAgICAgIGhlYWRlciA9IFVIUzJfTkFUSVZFX1BBQ0tFVCB8IFVIUzJf
UEFDS0VUX1RZUEVfQ0NNRDsNCj4+ICsgICAgICAgYXJnID0gKChVSFMyX0RFVl9DT05GSUdfR0VO
X0NBUFMgJiAweEZGKSA8PCA4KSB8DQo+PiArICAgICAgICAgICAgICAgVUhTMl9OQVRJVkVfQ01E
X1JFQUQgfA0KPj4gKyAgICAgICAgICAgICAgIFVIUzJfTkFUSVZFX0NNRF9QTEVOXzRCIHwNCj4+
ICsgICAgICAgICAgICAgICAoVUhTMl9ERVZfQ09ORklHX0dFTl9DQVBTID4+Pj4gOCk7DQo+PiAr
DQo+PiArICAgICAgIERCRygiQmVnaW4gSU5RVUlSWV9DRkcsIGhlYWRlcj0weCV4LCBhcmc9MHgl
eC5cbiIsDQo+PiArICAgICAgICAgICAgICAgaGVhZGVyLCBhcmcpOw0KPj4gKyAgICAgICAvKiBU
aGVyZSBpcyBubyBwYXlsb2FkIGJlY2F1c2UgcGVyIHNwZWMsIHRoZXJlIHNob3VsZCBiZQ0KPj4g
KyAgICAgICAgKiBubyBwYXlsb2FkIGZpZWxkIGZvciByZWFkIENDTUQuDQo+PiArICAgICAgICAq
IFBsZW4gaXMgc2V0IGluIGFyZy4gUGVyIHNwZWMsIHBsZW4gZm9yIHJlYWQgQ0NNRA0KPj4gKyAg
ICAgICAgKiByZXByZXNlbnRzIHRoZSBsZW4gb2YgcmVhZCBkYXRhIHdoaWNoIGlzIGFzc2lnbmVk
IGluIHBheWxvYWQNCj4+ICsgICAgICAgICogb2YgZm9sbG93aW5nIFJFUyAocDEzNikuDQo+PiAr
ICAgICAgICAqLw0KPj4gKyAgICAgICBlcnIgPSB1aHMyX2NtZF9hc3NlbWJsZSgmY21kLCBoZWFk
ZXIsIGFyZywgTlVMTCwgMCwNCj4+ICsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTlVM
TCwgMCk7DQo+PiArICAgICAgIGlmIChlcnIpIHsNCj4+ICsgICAgICAgICAgICAgICBwcl9lcnIo
IiVzOiAlczogVUhTMiBDTUQgYXNzZW1ibGluZyBlcnIgPSAweCV4IVxuIiwNCj4+ICsgICAgICAg
ICAgICAgICAgICAgICAgIG1tY19ob3N0bmFtZShob3N0KSwgX19mdW5jX18sIGVycik7DQo+PiAr
ICAgICAgICAgICAgICAgcmV0dXJuIC1FSU87DQo+PiArICAgICAgIH0NCj4+ICsNCj4+ICsgICAg
ICAgZXJyID0gbW1jX3dhaXRfZm9yX2NtZChob3N0LCAmY21kLCAwKTsNCj4+ICsgICAgICAgaWYg
KGVycikgew0KPj4gKyAgICAgICAgICAgICAgIHByX2VycigiJXM6ICVzOiBVSFMyIENNRCBzZW5k
IGZhaWwsIGVycj0gMHgleCFcbiIsDQo+PiArICAgICAgICAgICAgICAgICAgICAgICBtbWNfaG9z
dG5hbWUoaG9zdCksIF9fZnVuY19fLCBlcnIpOw0KPj4gKyAgICAgICAgICAgICAgIHJldHVybiAt
RUlPOw0KPj4gKyAgICAgICB9DQo+PiArDQo+PiArI2lmZGVmIENPTkZJR19NTUNfREVCVUcNCj4+
ICsgICAgICAgaW50IGk7DQo+PiArDQo+PiArICAgICAgIHByX3dhcm4oIiVzOiBJTlFVSVJZX0NG
RyBnZW5lcmljIHJlc3BvbnNlIGlzOiAiLCBtbWNfaG9zdG5hbWUoaG9zdCkpOw0KPj4gKyAgICAg
ICBmb3IgKGkgPSAwOyBpIDwgMjsgaSsrKQ0KPj4gKyAgICAgICAgICAgICAgIHByX3dhcm4oIjB4
JXggIiwgY21kLnJlc3BbaV0pOw0KPj4gKyAgICAgICBwcl93YXJuKCJcbiIpOw0KPj4gKyNlbmRp
Zg0KPj4gKw0KPj4gKyAgICAgICBjYXAgPSBjbWQucmVzcFswXTsNCj4+ICsgICAgICAgREJHKCJE
ZXZpY2UgR2VuZXJpYyBDYXBzICgwLTMxKSBpczogMHgleC5cbiIsIGNhcCk7DQo+PiArICAgICAg
IGhvc3QtPj51aHMyX2Rldl9wcm9wLm5fbGFuZXMgPSAoY2FwID4+Pj4gVUhTMl9ERVZfQ09ORklH
X05fTEFORVNfUE9TKSAmDQo+PiArICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgVUhTMl9ERVZfQ09ORklHX05fTEFORVNfTUFTSzsNCj4+ICsgICAgICAgaG9zdC0+PnVoczJf
ZGV2X3Byb3AuZGFkcl9sZW4gPSAoY2FwID4+Pj4gVUhTMl9ERVZfQ09ORklHX0RBRFJfUE9TKSAm
DQo+PiArICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUhTMl9ERVZfQ09O
RklHX0RBRFJfTUFTSzsNCj4+ICsgICAgICAgaG9zdC0+PnVoczJfZGV2X3Byb3AuYXBwX3R5cGUg
PSAoY2FwID4+Pj4gVUhTMl9ERVZfQ09ORklHX0FQUF9QT1MpICYNCj4+ICsgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICBVSFMyX0RFVl9DT05GSUdfQVBQX01BU0s7DQo+PiAr
DQo+PiArICAgICAgIERCRygiSU5RVUlSWV9DRkc6IHJlYWQgUEhZIENhcHMuXG4iKTsNCj4+ICsg
ICAgICAgYXJnID0gKChVSFMyX0RFVl9DT05GSUdfUEhZX0NBUFMgJiAweEZGKSA8PCA4KSB8DQo+
PiArICAgICAgICAgICAgICAgVUhTMl9OQVRJVkVfQ01EX1JFQUQgfA0KPj4gKyAgICAgICAgICAg
ICAgIFVIUzJfTkFUSVZFX0NNRF9QTEVOXzhCIHwNCj4+ICsgICAgICAgICAgICAgICAoVUhTMl9E
RVZfQ09ORklHX1BIWV9DQVBTID4+Pj4gOCk7DQo+PiArDQo+PiArICAgICAgIERCRygiQmVnaW4g
SU5RVUlSWV9DRkcsIGhlYWRlcj0weCV4LCBhcmc9MHgleC5cbiIsDQo+PiArICAgICAgICAgICAg
ICAgaGVhZGVyLCBhcmcpOw0KPj4gKyAgICAgICBlcnIgPSB1aHMyX2NtZF9hc3NlbWJsZSgmY21k
LCBoZWFkZXIsIGFyZywgTlVMTCwgMCwNCj4+ICsgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgTlVMTCwgMCk7DQo+PiArICAgICAgIGlmIChlcnIpIHsNCj4+ICsgICAgICAgICAgICAgICBw
cl9lcnIoIiVzOiAlczogVUhTMiBDTUQgYXNzZW1ibGluZyBlcnIgPSAweCV4IVxuIiwNCj4+ICsg
ICAgICAgICAgICAgICAgICAgICAgIG1tY19ob3N0bmFtZShob3N0KSwgX19mdW5jX18sIGVycik7
DQo+PiArICAgICAgICAgICAgICAgcmV0dXJuIC1FSU87DQo+PiArICAgICAgIH0NCj4+ICsNCj4+
ICsgICAgICAgZXJyID0gbW1jX3dhaXRfZm9yX2NtZChob3N0LCAmY21kLCAwKTsNCj4+ICsgICAg
ICAgaWYgKGVycikgew0KPj4gKyAgICAgICAgICAgICAgIHByX2VycigiJXM6ICVzOiBVSFMyIENN
RCBzZW5kIGZhaWwsIGVycj0gMHgleCFcbiIsDQo+PiArICAgICAgICAgICAgICAgICAgICAgICBt
bWNfaG9zdG5hbWUoaG9zdCksIF9fZnVuY19fLCBlcnIpOw0KPj4gKyAgICAgICAgICAgICAgIHJl
dHVybiAtRUlPOw0KPj4gKyAgICAgICB9DQo+PiArDQo+PiArI2lmZGVmIENPTkZJR19NTUNfREVC
VUcNCj4+ICsgICAgICAgcHJfd2FybigiJXM6IElOUVVJUllfQ0ZHIFBIWSByZXNwb25zZSBpczog
IiwgbW1jX2hvc3RuYW1lKGhvc3QpKTsNCj4+ICsgICAgICAgZm9yIChpID0gMDsgaSA8IDI7IGkr
KykNCj4+ICsgICAgICAgICAgICAgICBwcl93YXJuKCIweCV4ICIsIGNtZC5yZXNwW2ldKTsNCj4+
ICsgICAgICAgcHJfd2FybigiXG4iKTsNCj4+ICsjZW5kaWYNCj4+ICsNCj4+ICsgICAgICAgY2Fw
ID0gY21kLnJlc3BbMF07DQo+PiArICAgICAgIERCRygiRGV2aWNlIFBIWSBDYXBzICgwLTMxKSBp
czogMHgleC5cbiIsIGNhcCk7DQo+PiArICAgICAgIGhvc3QtPj51aHMyX2Rldl9wcm9wLnBoeV9t
aW5vcl9yZXYgPSBjYXAgJg0KPj4gKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgIFVIUzJfREVWX0NPTkZJR19QSFlfTUlOT1JfTUFTSzsNCj4+ICsgICAgICAgaG9zdC0+PnVo
czJfZGV2X3Byb3AucGh5X21ham9yX3JldiA9IChjYXAgPj4+Pg0KPj4gKyAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgIFVIUzJfREVWX0NPTkZJR19QSFlfTUFKT1JfUE9TKSAm
DQo+PiArICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUhTMl9ERVZfQ09O
RklHX1BIWV9NQUpPUl9NQVNLOw0KPj4gKyAgICAgICBob3N0LT4+dWhzMl9kZXZfcHJvcC5jYW5f
aGliZXJuYXRlID0gKGNhcCA+Pj4+DQo+PiArICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgVUhTMl9ERVZfQ09ORklHX0NBTl9ISUJFUl9QT1MpICYNCj4+ICsgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVSFMyX0RFVl9DT05GSUdfQ0FOX0hJQkVSX01B
U0s7DQo+PiArDQo+PiArICAgICAgIGNhcCA9IGNtZC5yZXNwWzFdOw0KPj4gKyAgICAgICBEQkco
IkRldmljZSBQSFkgQ2FwcyAoMzItNjMpIGlzOiAweCV4LlxuIiwgY2FwKTsNCj4+ICsgICAgICAg
aG9zdC0+PnVoczJfZGV2X3Byb3Aubl9sc3Nfc3luYyA9IGNhcCAmIFVIUzJfREVWX0NPTkZJR19O
X0xTU19TWU5fTUFTSzsNCj4+ICsgICAgICAgaG9zdC0+PnVoczJfZGV2X3Byb3Aubl9sc3NfZGly
ID0gKGNhcCA+Pj4+DQo+PiArICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
VUhTMl9ERVZfQ09ORklHX05fTFNTX0RJUl9QT1MpICYNCj4+ICsgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICBVSFMyX0RFVl9DT05GSUdfTl9MU1NfRElSX01BU0s7DQo+PiAr
ICAgICAgIGlmIChob3N0LT4+dWhzMl9kZXZfcHJvcC5uX2xzc19zeW5jID09IDApDQo+PiArICAg
ICAgICAgICAgICAgaG9zdC0+PnVoczJfZGV2X3Byb3Aubl9sc3Nfc3luYyA9IDE2IDw8IDI7DQo+
PiArICAgICAgIGVsc2UNCj4+ICsgICAgICAgICAgICAgICBob3N0LT4+dWhzMl9kZXZfcHJvcC5u
X2xzc19zeW5jIDw8PSAyOw0KPj4gKw0KPj4gKyAgICAgICBpZiAoaG9zdC0+PnVoczJfZGV2X3By
b3Aubl9sc3NfZGlyID09IDApDQo+PiArICAgICAgICAgICAgICAgaG9zdC0+PnVoczJfZGV2X3By
b3Aubl9sc3NfZGlyID0gMTYgPDwgMzsNCj4+ICsgICAgICAgZWxzZQ0KPj4gKyAgICAgICAgICAg
ICAgIGhvc3QtPj51aHMyX2Rldl9wcm9wLm5fbHNzX2RpciA8PD0gMzsNCj4+ICsNCj4+ICsgICAg
ICAgREJHKCJJTlFVSVJZX0NGRzogcmVhZCBMSU5LLVRSQU4gQ2Fwcy5cbiIpOw0KPj4gKyAgICAg
ICBhcmcgPSAoKFVIUzJfREVWX0NPTkZJR19MSU5LX1RSQU5fQ0FQUyAmIDB4RkYpIDw8IDgpIHwN
Cj4+ICsgICAgICAgICAgICAgICBVSFMyX05BVElWRV9DTURfUkVBRCB8DQo+PiArICAgICAgICAg
ICAgICAgVUhTMl9OQVRJVkVfQ01EX1BMRU5fOEIgfA0KPj4gKyAgICAgICAgICAgICAgIChVSFMy
X0RFVl9DT05GSUdfTElOS19UUkFOX0NBUFMgPj4+PiA4KTsNCj4+ICsNCj4+ICsgICAgICAgREJH
KCJCZWdpbiBJTlFVSVJZX0NGRywgaGVhZGVyPTB4JXgsIGFyZz0weCV4LlxuIiwNCj4+ICsgICAg
ICAgICAgICAgICBoZWFkZXIsIGFyZyk7DQo+PiArICAgICAgIGVyciA9IHVoczJfY21kX2Fzc2Vt
YmxlKCZjbWQsIGhlYWRlciwgYXJnLCBOVUxMLCAwLA0KPj4gKyAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICBOVUxMLCAwKTsNCj4+ICsgICAgICAgaWYgKGVycikgew0KPj4gKyAgICAgICAg
ICAgICAgIHByX2VycigiJXM6ICVzOiBVSFMyIENNRCBhc3NlbWJsaW5nIGVyciA9IDB4JXghXG4i
LA0KPj4gKyAgICAgICAgICAgICAgICAgICAgICAgbW1jX2hvc3RuYW1lKGhvc3QpLCBfX2Z1bmNf
XywgZXJyKTsNCj4+ICsgICAgICAgICAgICAgICByZXR1cm4gLUVJTzsNCj4+ICsgICAgICAgfQ0K
Pj4gKw0KPj4gKyAgICAgICBlcnIgPSBtbWNfd2FpdF9mb3JfY21kKGhvc3QsICZjbWQsIDApOw0K
Pj4gKyAgICAgICBpZiAoZXJyKSB7DQo+PiArICAgICAgICAgICAgICAgcHJfZXJyKCIlczogJXM6
IFVIUzIgQ01EIHNlbmQgZmFpbCwgZXJyPSAweCV4IVxuIiwNCj4+ICsgICAgICAgICAgICAgICAg
ICAgICAgIG1tY19ob3N0bmFtZShob3N0KSwgX19mdW5jX18sIGVycik7DQo+PiArICAgICAgICAg
ICAgICAgcmV0dXJuIC1FSU87DQo+PiArICAgICAgIH0NCj4+ICsNCj4+ICsjaWZkZWYgQ09ORklH
X01NQ19ERUJVRw0KPj4gKyAgICAgICBwcl93YXJuKCIlczogSU5RVUlSWV9DRkcgTGluay1UcmFu
IHJlc3BvbnNlIGlzOiAiLCBtbWNfaG9zdG5hbWUoaG9zdCkpOw0KPj4gKyAgICAgICBmb3IgKGkg
PSAwOyBpIDwgMjsgaSsrKQ0KPj4gKyAgICAgICAgICAgICAgIHByX3dhcm4oIjB4JXggIiwgY21k
LnJlc3BbaV0pOw0KPj4gKyAgICAgICBwcl93YXJuKCJcbiIpOw0KPj4gKyNlbmRpZg0KPj4gKw0K
Pj4gKyAgICAgICBjYXAgPSBjbWQucmVzcFswXTsNCj4+ICsgICAgICAgREJHKCJEZXZpY2UgTElO
Sy1UUkFOIENhcHMgKDAtMzEpIGlzOiAweCV4LlxuIiwgY2FwKTsNCj4+ICsgICAgICAgaG9zdC0+
PnVoczJfZGV2X3Byb3AubGlua19taW5vcl9yZXYgPSBjYXAgJg0KPj4gKyAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgIFVIUzJfREVWX0NPTkZJR19MVF9NSU5PUl9NQVNLOw0K
Pj4gKyAgICAgICBob3N0LT4+dWhzMl9kZXZfcHJvcC5saW5rX21ham9yX3JldiA9IChjYXAgPj4+
Pg0KPj4gKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVIUzJfREVWX0NP
TkZJR19MVF9NQUpPUl9QT1MpICYNCj4+ICsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICBVSFMyX0RFVl9DT05GSUdfTFRfTUFKT1JfTUFTSzsNCj4+ICsgICAgICAgaG9zdC0+
PnVoczJfZGV2X3Byb3Aubl9mY3UgPSAoY2FwID4+Pj4gVUhTMl9ERVZfQ09ORklHX05fRkNVX1BP
UykgJg0KPj4gKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVIUzJfREVW
X0NPTkZJR19OX0ZDVV9NQVNLOw0KPj4gKyAgICAgICBob3N0LT4+dWhzMl9kZXZfcHJvcC5kZXZf
dHlwZSA9IChjYXAgPj4+PiBVSFMyX0RFVl9DT05GSUdfREVWX1RZUEVfUE9TKSAmDQo+PiArICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUhTMl9ERVZfQ09ORklHX0RFVl9U
WVBFX01BU0s7DQo+PiArICAgICAgIGhvc3QtPj51aHMyX2Rldl9wcm9wLm1heGJsa19sZW4gPSAo
Y2FwID4+Pj4NCj4+ICsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVSFMy
X0RFVl9DT05GSUdfTUFYX0JMS19MRU5fUE9TKSAmDQo+PiArICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgVUhTMl9ERVZfQ09ORklHX01BWF9CTEtfTEVOX01BU0s7DQo+PiAr
DQo+PiArICAgICAgIGNhcCA9IGNtZC5yZXNwWzFdOw0KPj4gKyAgICAgICBEQkcoIkRldmljZSBM
SU5LLVRSQU4gQ2FwcyAoMzItNjMpIGlzOiAweCV4LlxuIiwgY2FwKTsNCj4+ICsgICAgICAgaG9z
dC0+PnVoczJfZGV2X3Byb3Aubl9kYXRhX2dhcCA9IGNhcCAmIFVIUzJfREVWX0NPTkZJR19OX0RB
VEFfR0FQX01BU0s7DQo+PiArICAgICAgIGlmIChob3N0LT4+dWhzMl9kZXZfcHJvcC5uX2ZjdSA9
PSAwKQ0KPj4gKyAgICAgICAgICAgICAgIGhvc3QtPj51aHMyX2Rldl9wcm9wLm5fZmN1ID0gMjU2
Ow0KPj4gKw0KPj4gKyAgICAgICByZXR1cm4gMDsNCj4+ICt9DQo+PiArDQo+PiArc3RhdGljIGlu
dCB1aHMyX2NvbmZpZ193cml0ZShzdHJ1Y3QgbW1jX2hvc3QgKmhvc3QpDQo+PiArew0KPj4gKyAg
ICAgICBzdHJ1Y3QgbW1jX2NvbW1hbmQgY21kID0gezB9Ow0KPj4gKyAgICAgICB1MTYgaGVhZGVy
ID0gMCwgYXJnID0gMDsNCj4+ICsgICAgICAgdTMyICpwYXlsb2FkOw0KPj4gKyAgICAgICB1OCBw
bGVuID0gMTsNCj4+ICsgICAgICAgaW50IGVycjsNCj4+ICsgICAgICAgdTggcmVzcFs1XSA9IHsw
fTsNCj4+ICsgICAgICAgdTggcmVzcF9sZW4gPSA1Ow0KPj4gKw0KPj4gKyAgICAgICBCVUdfT04o
IWhvc3QtPj5vcHMtPj51aHMyX3NldF9yZWcpOw0KPj4gKw0KPj4gKyAgICAgICBEQkcoIlNFVF9D
T01NT05fQ0ZHOiB3cml0ZSBHZW5lcmljIFNldHRpbmdzLlxuIik7DQo+PiArICAgICAgIGhlYWRl
ciA9IFVIUzJfTkFUSVZFX1BBQ0tFVCB8IFVIUzJfUEFDS0VUX1RZUEVfQ0NNRDsNCj4+ICsgICAg
ICAgYXJnID0gKChVSFMyX0RFVl9DT05GSUdfR0VOX1NFVCAmIDB4RkYpIDw8IDgpIHwNCj4+ICsg
ICAgICAgICAgICAgICBVSFMyX05BVElWRV9DTURfV1JJVEUgfA0KPj4gKyAgICAgICAgICAgICAg
IFVIUzJfTkFUSVZFX0NNRF9QTEVOXzRCIHwNCj4+ICsgICAgICAgICAgICAgICAoVUhTMl9ERVZf
Q09ORklHX0dFTl9TRVQgPj4+PiA4KTsNCj4+ICsNCj4+ICsgICAgICAgaWYgKGhvc3QtPj51aHMy
X2Rldl9wcm9wLm5fbGFuZXMgPT0gVUhTMl9ERVZfQ09ORklHXzJMX0hEX0ZEICYmDQo+PiArICAg
ICAgICAgICBob3N0LT4+dWhzMl9jYXBzLm5fbGFuZXMgPT0gVUhTMl9ERVZfQ09ORklHXzJMX0hE
X0ZEKSB7DQo+PiArICAgICAgICAgICAgICAgLyogU3VwcG9ydCBIRCAqLw0KPj4gKyAgICAgICAg
ICAgICAgIERCRygiQm90aCBIb3N0IGFuZCBkZXZpY2Ugc3VwcG9ydCAyTC1IRC5cbiIpOw0KPj4g
KyAgICAgICAgICAgICAgIGhvc3QtPj5mbGFncyB8PSBNTUNfVUhTMl8yTF9IRDsNCj4+ICsgICAg
ICAgICAgICAgICBob3N0LT4+dWhzMl9jYXBzLm5fbGFuZXNfc2V0ID0gVUhTMl9ERVZfQ09ORklH
X0dFTl9TRVRfMkxfRkRfSEQ7DQo+PiArICAgICAgICAgICAgICAgaG9zdC0+PnVoczJfZGV2X3By
b3Aubl9sYW5lc19zZXQgPQ0KPj4gKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVSFMy
X0RFVl9DT05GSUdfR0VOX1NFVF8yTF9GRF9IRDsNCj4+ICsgICAgICAgfSBlbHNlIHsNCj4+ICsg
ICAgICAgICAgICAgICAvKiBPbmx5IHN1cHBvcnQgMkwtRkQgc28gZmFyICovDQo+PiArICAgICAg
ICAgICAgICAgaG9zdC0+PmZsYWdzICY9IH5NTUNfVUhTMl8yTF9IRDsNCj4+ICsgICAgICAgICAg
ICAgICBob3N0LT4+dWhzMl9jYXBzLm5fbGFuZXNfc2V0ID0gVUhTMl9ERVZfQ09ORklHX0dFTl9T
RVRfMkxfRkRfSEQ7DQo+PiArICAgICAgICAgICAgICAgaG9zdC0+PnVoczJfZGV2X3Byb3Aubl9s
YW5lc19zZXQgPQ0KPj4gKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVSFMyX0RFVl9D
T05GSUdfR0VOX1NFVF8yTF9GRF9IRDsNCj4+ICsgICAgICAgfQ0KPj4gKyAgICAgICBwYXlsb2Fk
ID0ga2NhbGxvYyhwbGVuLCBzaXplb2YodTMyKSwgR0ZQX0tFUk5FTCk7DQo+PiArICAgICAgIHBh
eWxvYWRbMF0gPSBob3N0LT4+dWhzMl9kZXZfcHJvcC5uX2xhbmVzX3NldCA8PA0KPj4gKyAgICAg
ICAgICAgICAgICAgICAgICAgVUhTMl9ERVZfQ09ORklHX05fTEFORVNfUE9TOw0KPj4gKyAgICAg
ICBEQkcoIkJlZ2luIFNFVF9DT01NT05fQ0ZHLCBoZWFkZXI9MHgleCwgYXJnPTB4JXgsIHBheWxv
YWQ9MHgleC5cbiIsDQo+PiArICAgICAgICAgICAgICAgaGVhZGVyLCBhcmcsIHBheWxvYWRbMF0p
Ow0KPj4gKyAgICAgICAvKiBUaGVyZSBpcyBubyBwYXlsb2FkIGJlY2F1c2UgcGVyIHNwZWMsIHRo
ZXJlIHNob3VsZCBiZQ0KPj4gKyAgICAgICAgKiBubyBwYXlsb2FkIGZpZWxkIGZvciByZWFkIEND
TUQuDQo+PiArICAgICAgICAqIFBsZW4gaXMgc2V0IGluIGFyZy4gUGVyIHNwZWMsIHBsZW4gZm9y
IHJlYWQgQ0NNRA0KPj4gKyAgICAgICAgKiByZXByZXNlbnRzIHRoZSBsZW4gb2YgcmVhZCBkYXRh
IHdoaWNoIGlzIGFzc2lnbmVkIGluIHBheWxvYWQNCj4+ICsgICAgICAgICogb2YgZm9sbG93aW5n
IFJFUyAocDEzNikuDQo+PiArICAgICAgICAqLw0KPj4gKyAgICAgICBlcnIgPSB1aHMyX2NtZF9h
c3NlbWJsZSgmY21kLCBoZWFkZXIsIGFyZywgcGF5bG9hZCwgcGxlbiwNCj4+ICsgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgTlVMTCwgMCk7DQo+PiArICAgICAgIGlmIChlcnIpIHsNCj4+
ICsgICAgICAgICAgICAgICBwcl9lcnIoIiVzOiAlczogVUhTMiBDTUQgYXNzZW1ibGluZyBlcnIg
PSAweCV4IVxuIiwNCj4+ICsgICAgICAgICAgICAgICAgICAgICAgIG1tY19ob3N0bmFtZShob3N0
KSwgX19mdW5jX18sIGVycik7DQo+PiArICAgICAgICAgICAgICAgcmV0dXJuIC1FSU87DQo+PiAr
ICAgICAgIH0NCj4+ICsNCj4+ICsgICAgICAgZXJyID0gbW1jX3dhaXRfZm9yX2NtZChob3N0LCAm
Y21kLCAwKTsNCj4+ICsgICAgICAgaWYgKGVycikgew0KPj4gKyAgICAgICAgICAgICAgIHByX2Vy
cigiJXM6ICVzOiBVSFMyIENNRCBzZW5kIGZhaWwsIGVycj0gMHgleCFcbiIsDQo+PiArICAgICAg
ICAgICAgICAgICAgICAgICBtbWNfaG9zdG5hbWUoaG9zdCksIF9fZnVuY19fLCBlcnIpOw0KPj4g
KyAgICAgICAgICAgICAgIHJldHVybiAtRUlPOw0KPj4gKyAgICAgICB9DQo+PiArDQo+PiArICAg
ICAgIERCRygiU0VUX0NPTU1PTl9DRkc6IFBIWSBTZXR0aW5ncy5cbiIpOw0KPj4gKyAgICAgICBh
cmcgPSAoKFVIUzJfREVWX0NPTkZJR19QSFlfU0VUICYgMHhGRikgPDwgOCkgfA0KPj4gKyAgICAg
ICAgICAgICAgIFVIUzJfTkFUSVZFX0NNRF9SRUFEIHwNCj4+ICsgICAgICAgICAgICAgICBVSFMy
X05BVElWRV9DTURfUExFTl84QiB8DQo+PiArICAgICAgICAgICAgICAgKFVIUzJfREVWX0NPTkZJ
R19QSFlfU0VUID4+Pj4gOCk7DQo+PiArDQo+PiArICAgICAgIHBsZW4gPSAyOw0KPj4gKyAgICAg
ICBwYXlsb2FkID0ga2NhbGxvYyhwbGVuLCBzaXplb2YodTMyKSwgR0ZQX0tFUk5FTCk7DQo+PiAr
DQo+PiArICAgICAgIGlmIChob3N0LT4+dWhzMl9jYXBzLnNwZWVkX3JhbmdlID09DQo+PiArICAg
ICAgICAgICAgICAgVUhTMl9ERVZfQ09ORklHX1BIWV9TRVRfU1BFRURfQikgew0KPj4gKyAgICAg
ICAgICAgICAgIGhvc3QtPj5mbGFncyB8PSBNTUNfVUhTMl9TUEVFRF9COw0KPj4gKyAgICAgICAg
ICAgICAgIGhvc3QtPj51aHMyX2Rldl9wcm9wLnNwZWVkX3JhbmdlX3NldCA9DQo+PiArICAgICAg
ICAgICAgICAgICAgICAgICBVSFMyX0RFVl9DT05GSUdfUEhZX1NFVF9TUEVFRF9COw0KPj4gKyAg
ICAgICB9IGVsc2Ugew0KPj4gKyAgICAgICAgICAgICAgIGhvc3QtPj51aHMyX2Rldl9wcm9wLnNw
ZWVkX3JhbmdlX3NldCA9DQo+PiArICAgICAgICAgICAgICAgICAgICAgICBVSFMyX0RFVl9DT05G
SUdfUEhZX1NFVF9TUEVFRF9BOw0KPj4gKyAgICAgICAgICAgICAgIGhvc3QtPj5mbGFncyAmPSB+
TU1DX1VIUzJfU1BFRURfQjsNCj4+ICsgICAgICAgfQ0KPj4gKyAgICAgICBwYXlsb2FkWzBdID0g
aG9zdC0+PnVoczJfZGV2X3Byb3Auc3BlZWRfcmFuZ2Vfc2V0IDw8DQo+PiArICAgICAgICAgICAg
ICAgICAgICAgICBVSFMyX0RFVl9DT05GSUdfUEhZX1NFVF9TUEVFRF9QT1M7DQo+PiArDQo+PiAr
ICAgICAgIGhvc3QtPj51aHMyX2Rldl9wcm9wLm5fbHNzX3N5bmNfc2V0ID0NCj4+ICsgICAgICAg
ICAgICAgICAobWluKGhvc3QtPj51aHMyX2Rldl9wcm9wLm5fbHNzX3N5bmMsDQo+PiArICAgICAg
ICAgICAgICAgaG9zdC0+PnVoczJfY2Fwcy5uX2xzc19zeW5jKSA+Pj4+IDIpICYNCj4+ICsgICAg
ICAgICAgICAgICBVSFMyX0RFVl9DT05GSUdfTl9MU1NfU1lOX01BU0s7DQo+PiArICAgICAgIGhv
c3QtPj51aHMyX2NhcHMubl9sc3Nfc3luY19zZXQgPSBob3N0LT4+dWhzMl9kZXZfcHJvcC5uX2xz
c19zeW5jX3NldDsNCj4+ICsNCj4+ICsgICAgICAgaG9zdC0+PnVoczJfZGV2X3Byb3Aubl9sc3Nf
ZGlyX3NldCA9DQo+PiArICAgICAgICAgICAgICAgKG1pbihob3N0LT4+dWhzMl9kZXZfcHJvcC5u
X2xzc19kaXIsDQo+PiArICAgICAgICAgICAgICAgaG9zdC0+PnVoczJfY2Fwcy5uX2xzc19kaXIp
ID4+Pj4gMykgJg0KPj4gKyAgICAgICAgICAgICAgIFVIUzJfREVWX0NPTkZJR19OX0xTU19ESVJf
TUFTSzsNCj4+ICsgICAgICAgaG9zdC0+PnVoczJfY2Fwcy5uX2xzc19kaXJfc2V0ID0gaG9zdC0+
PnVoczJfZGV2X3Byb3Aubl9sc3NfZGlyX3NldDsNCj4+ICsgICAgICAgcGF5bG9hZFsxXSA9ICho
b3N0LT4+dWhzMl9kZXZfcHJvcC5uX2xzc19kaXJfc2V0IDw8DQo+PiArICAgICAgICAgICAgICAg
ICAgICAgICBVSFMyX0RFVl9DT05GSUdfTl9MU1NfRElSX1BPUykgfA0KPj4gKyAgICAgICAgICAg
ICAgICAgICAgICAgaG9zdC0+PnVoczJfZGV2X3Byb3Aubl9sc3Nfc3luY19zZXQ7DQo+PiArDQo+
PiArICAgICAgIERCRygiQmVnaW4gU0VUX0NPTU1PTl9DRkcsIGhlYWRlcj0weCV4LCBhcmc9MHgl
eCwgcGF5bG9hZFswXT0weCV4LCINCj4+ICsgICAgICAgICAgICAgICAiIHBheWxvYWRbMV0gPSAw
eCV4LlxuIiwNCj4+ICsgICAgICAgICAgICAgICBoZWFkZXIsIGFyZywgcGF5bG9hZFswXSwgcGF5
bG9hZFsxXSk7DQo+PiArDQo+PiArICAgICAgIGVyciA9IHVoczJfY21kX2Fzc2VtYmxlKCZjbWQs
IGhlYWRlciwgYXJnLCBwYXlsb2FkLCBwbGVuLA0KPj4gKyAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICBOVUxMLCAwKTsNCj4+ICsgICAgICAgaWYgKGVycikgew0KPj4gKyAgICAgICAgICAg
ICAgIHByX2VycigiJXM6ICVzOiBVSFMyIENNRCBhc3NlbWJsaW5nIGVyciA9IDB4JXghXG4iLA0K
Pj4gKyAgICAgICAgICAgICAgICAgICAgICAgbW1jX2hvc3RuYW1lKGhvc3QpLCBfX2Z1bmNfXywg
ZXJyKTsNCj4+ICsgICAgICAgICAgICAgICByZXR1cm4gLUVJTzsNCj4+ICsgICAgICAgfQ0KPj4g
Kw0KPj4gKyAgICAgICBlcnIgPSBtbWNfd2FpdF9mb3JfY21kKGhvc3QsICZjbWQsIDApOw0KPj4g
KyAgICAgICBpZiAoZXJyKSB7DQo+PiArICAgICAgICAgICAgICAgcHJfZXJyKCIlczogJXM6IFVI
UzIgQ01EIHNlbmQgZmFpbCwgZXJyPSAweCV4IVxuIiwNCj4+ICsgICAgICAgICAgICAgICAgICAg
ICAgIG1tY19ob3N0bmFtZShob3N0KSwgX19mdW5jX18sIGVycik7DQo+PiArICAgICAgICAgICAg
ICAgcmV0dXJuIC1FSU87DQo+PiArICAgICAgIH0NCj4+ICsNCj4+ICsgICAgICAgREJHKCJTRVRf
Q09NTU9OX0NGRzogTElOSy1UUkFOIFNldHRpbmdzLlxuIik7DQo+PiArICAgICAgIGFyZyA9ICgo
VUhTMl9ERVZfQ09ORklHX0xJTktfVFJBTl9TRVQgJiAweEZGKSA8PCA4KSB8DQo+PiArICAgICAg
ICAgICAgICAgVUhTMl9OQVRJVkVfQ01EX1dSSVRFIHwNCj4+ICsgICAgICAgICAgICAgICBVSFMy
X05BVElWRV9DTURfUExFTl84QiB8DQo+PiArICAgICAgICAgICAgICAgKFVIUzJfREVWX0NPTkZJ
R19MSU5LX1RSQU5fU0VUID4+Pj4gOCk7DQo+PiArDQo+PiArICAgICAgIHBsZW4gPSAyOw0KPj4g
KyAgICAgICBwYXlsb2FkID0ga2NhbGxvYyhwbGVuLCBzaXplb2YodTMyKSwgR0ZQX0tFUk5FTCk7
DQo+PiArDQo+PiArICAgICAgIGlmIChob3N0LT4+dWhzMl9kZXZfcHJvcC5hcHBfdHlwZSA9PSBV
SFMyX0RFVl9DT05GSUdfQVBQX1NEX01FTSkNCj4+ICsgICAgICAgICAgICAgICBob3N0LT4+dWhz
Ml9kZXZfcHJvcC5tYXhibGtfbGVuX3NldCA9DQo+PiArICAgICAgICAgICAgICAgICAgICAgICBV
SFMyX0RFVl9DT05GSUdfTFRfU0VUX01BWF9CTEtfTEVOOw0KPj4gKyAgICAgICBlbHNlDQo+PiAr
ICAgICAgICAgICAgICAgaG9zdC0+PnVoczJfZGV2X3Byb3AubWF4YmxrX2xlbl9zZXQgPQ0KPj4g
KyAgICAgICAgICAgICAgICAgICAgICAgbWluKGhvc3QtPj51aHMyX2Rldl9wcm9wLm1heGJsa19s
ZW4sDQo+PiArICAgICAgICAgICAgICAgICAgICAgICBob3N0LT4+dWhzMl9jYXBzLm1heGJsa19s
ZW4pOw0KPj4gKyAgICAgICBob3N0LT4+dWhzMl9jYXBzLm1heGJsa19sZW5fc2V0ID0gaG9zdC0+
PnVoczJfZGV2X3Byb3AubWF4YmxrX2xlbl9zZXQ7DQo+PiArDQo+PiArICAgICAgIGhvc3QtPj51
aHMyX2Rldl9wcm9wLm5fZmN1X3NldCA9DQo+PiArICAgICAgICAgICAgICAgbWluKGhvc3QtPj51
aHMyX2Rldl9wcm9wLm5fZmN1LA0KPj4gKyAgICAgICAgICAgICAgIGhvc3QtPj51aHMyX2NhcHMu
bl9mY3UpOw0KPj4gKyAgICAgICBob3N0LT4+dWhzMl9jYXBzLm5fZmN1X3NldCA9IGhvc3QtPj51
aHMyX2Rldl9wcm9wLm5fZmN1X3NldDsNCj4+ICsNCj4+ICsgICAgICAgaG9zdC0+PnVoczJfZGV2
X3Byb3Aubl9kYXRhX2dhcF9zZXQgPQ0KPj4gKyAgICAgICAgICAgICAgIG1pbihob3N0LT4+dWhz
Ml9jYXBzLm5fZGF0YV9nYXAsDQo+PiArICAgICAgICAgICAgICAgaG9zdC0+PnVoczJfZGV2X3By
b3Aubl9kYXRhX2dhcCk7DQo+PiArICAgICAgIGhvc3QtPj51aHMyX2NhcHMubl9kYXRhX2dhcF9z
ZXQgPSBob3N0LT4+dWhzMl9kZXZfcHJvcC5uX2RhdGFfZ2FwX3NldDsNCj4+ICsNCj4+ICsgICAg
ICAgaG9zdC0+PnVoczJfY2Fwcy5tYXhfcmV0cnlfc2V0ID0gMzsNCj4+ICsgICAgICAgaG9zdC0+
PnVoczJfZGV2X3Byb3AubWF4X3JldHJ5X3NldCA9IGhvc3QtPj51aHMyX2NhcHMubWF4X3JldHJ5
X3NldDsNCj4+ICsNCj4+ICsgICAgICAgcGF5bG9hZFswXSA9IChob3N0LT4+dWhzMl9kZXZfcHJv
cC5tYXhibGtfbGVuX3NldCA8PA0KPj4gKyAgICAgICAgICAgICAgICAgICAgICAgVUhTMl9ERVZf
Q09ORklHX01BWF9CTEtfTEVOX1BPUykgfA0KPj4gKyAgICAgICAgICAgICAgICAgICAgICAgKGhv
c3QtPj51aHMyX2Rldl9wcm9wLm1heF9yZXRyeV9zZXQgPDwNCj4+ICsgICAgICAgICAgICAgICAg
ICAgICAgIFVIUzJfREVWX0NPTkZJR19MVF9TRVRfTUFYX1JFVFJZX1BPUykgfA0KPj4gKyAgICAg
ICAgICAgICAgICAgICAgICAgKGhvc3QtPj51aHMyX2Rldl9wcm9wLm5fZmN1X3NldCA8PA0KPj4g
KyAgICAgICAgICAgICAgICAgICAgICAgVUhTMl9ERVZfQ09ORklHX05fRkNVX1BPUyk7DQo+PiAr
ICAgICAgIHBheWxvYWRbMV0gPSBob3N0LT4+dWhzMl9kZXZfcHJvcC5uX2RhdGFfZ2FwX3NldDsN
Cj4+ICsNCj4+ICsgICAgICAgREJHKCJCZWdpbiBTRVRfQ09NTU9OX0NGRywgaGVhZGVyPTB4JXgs
IGFyZz0weCV4LCBwYXlsb2FkWzBdID0gMHgleCwiDQo+PiArICAgICAgICAgICAgICAgIiBwYXls
b2FkWzFdID0gMHgleC5cbiIsDQo+PiArICAgICAgICAgICAgICAgaGVhZGVyLCBhcmcsIHBheWxv
YWRbMF0sIHBheWxvYWRbMV0pOw0KPj4gKyAgICAgICBlcnIgPSB1aHMyX2NtZF9hc3NlbWJsZSgm
Y21kLCBoZWFkZXIsIGFyZywgcGF5bG9hZCwgcGxlbiwNCj4+ICsgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgTlVMTCwgMCk7DQo+PiArICAgICAgIGlmIChlcnIpIHsNCj4+ICsgICAgICAg
ICAgICAgICBwcl9lcnIoIiVzOiAlczogVUhTMiBDTUQgYXNzZW1ibGluZyBlcnIgPSAweCV4IVxu
IiwNCj4+ICsgICAgICAgICAgICAgICAgICAgICAgIG1tY19ob3N0bmFtZShob3N0KSwgX19mdW5j
X18sIGVycik7DQo+PiArICAgICAgICAgICAgICAgcmV0dXJuIC1FSU87DQo+PiArICAgICAgIH0N
Cj4+ICsNCj4+ICsgICAgICAgZXJyID0gbW1jX3dhaXRfZm9yX2NtZChob3N0LCAmY21kLCAwKTsN
Cj4+ICsgICAgICAgaWYgKGVycikgew0KPj4gKyAgICAgICAgICAgICAgIHByX2VycigiJXM6ICVz
OiBVSFMyIENNRCBzZW5kIGZhaWwsIGVycj0gMHgleCFcbiIsDQo+PiArICAgICAgICAgICAgICAg
ICAgICAgICBtbWNfaG9zdG5hbWUoaG9zdCksIF9fZnVuY19fLCBlcnIpOw0KPj4gKyAgICAgICAg
ICAgICAgIHJldHVybiAtRUlPOw0KPj4gKyAgICAgICB9DQo+PiArDQo+PiArICAgICAgIERCRygi
U0VUX0NPTU1PTl9DRkc6IFNldCBDb25maWcgQ29tcGxldGlvbi5cbiIpOw0KPj4gKyAgICAgICBh
cmcgPSAoKChVSFMyX0RFVl9DT05GSUdfR0VOX1NFVCArIDEpICYgMHhGRikgPDwgOCkgfA0KPj4g
KyAgICAgICAgICAgICAgIFVIUzJfTkFUSVZFX0NNRF9XUklURSB8DQo+PiArICAgICAgICAgICAg
ICAgVUhTMl9OQVRJVkVfQ01EX1BMRU5fNEIgfA0KPj4gKyAgICAgICAgICAgICAgICgoVUhTMl9E
RVZfQ09ORklHX0dFTl9TRVQgKyAxKSA+Pj4+IDgpOw0KPj4gKw0KPj4gKyAgICAgICBwbGVuID0g
MTsNCj4+ICsgICAgICAgcGF5bG9hZCA9IGtjYWxsb2MocGxlbiwgc2l6ZW9mKHUzMiksIEdGUF9L
RVJORUwpOw0KPj4gKyAgICAgICBwYXlsb2FkWzBdID0gVUhTMl9ERVZfQ09ORklHX0dFTl9TRVRf
Q0ZHX0NPTVBMRVRFOw0KPj4gKw0KPj4gKyAgICAgICBEQkcoIkJlZ2luIFNFVF9DT01NT05fQ0ZH
LCBoZWFkZXI9MHgleCwgYXJnPTB4JXgsIHBheWxvYWRbMF0gPSAweCV4LlxuIiwNCj4+ICsgICAg
ICAgICAgICAgICBoZWFkZXIsIGFyZywgcGF5bG9hZFswXSk7DQo+PiArICAgICAgIGVyciA9IHVo
czJfY21kX2Fzc2VtYmxlKCZjbWQsIGhlYWRlciwgYXJnLCBwYXlsb2FkLCBwbGVuLA0KPj4gKyAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNwLCByZXNwX2xlbik7DQo+PiArICAgICAg
IGlmIChlcnIpIHsNCj4+ICsgICAgICAgICAgICAgICBwcl9lcnIoIiVzOiAlczogVUhTMiBDTUQg
YXNzZW1ibGluZyBlcnIgPSAweCV4IVxuIiwNCj4+ICsgICAgICAgICAgICAgICAgICAgICAgIG1t
Y19ob3N0bmFtZShob3N0KSwgX19mdW5jX18sIGVycik7DQo+PiArICAgICAgICAgICAgICAgcmV0
dXJuIC1FSU87DQo+PiArICAgICAgIH0NCj4+ICsNCj4+ICsgICAgICAgZXJyID0gbW1jX3dhaXRf
Zm9yX2NtZChob3N0LCAmY21kLCAwKTsNCj4+ICsgICAgICAgaWYgKGVycikgew0KPj4gKyAgICAg
ICAgICAgICAgIHByX2VycigiJXM6ICVzOiBVSFMyIENNRCBzZW5kIGZhaWwsIGVycj0gMHgleCFc
biIsDQo+PiArICAgICAgICAgICAgICAgICAgICAgICBtbWNfaG9zdG5hbWUoaG9zdCksIF9fZnVu
Y19fLCBlcnIpOw0KPj4gKyAgICAgICAgICAgICAgIHJldHVybiAtRUlPOw0KPj4gKyAgICAgICB9
DQo+PiArDQo+PiArICAgICAgIGlmICgocmVzcFs0XSAmIDB4ODApICE9IDB4ODApIHsNCj4+ICsg
ICAgICAgICAgICAgICBwcl9lcnIoIiVzOiAlczogQ29uZmlnIENvbXBsZXRlIGlzIG5vdCBzZXQh
XG4iLA0KPj4gKyAgICAgICAgICAgICAgICAgICAgICAgbW1jX2hvc3RuYW1lKGhvc3QpLCBfX2Z1
bmNfXyk7DQo+PiArICAgICAgICAgICAgICAgcmV0dXJuIC1FSU87DQo+PiArICAgICAgIH0NCj4+
ICsNCj4+ICsgICAgICAgLyogU2V0IGhvc3QgQ29uZmlnIFNldHRpbmcgcmVnaXN0ZXJzICovDQo+
PiArICAgICAgIGlmIChob3N0LT4+b3BzLT4+dWhzMl9zZXRfcmVnKGhvc3QsIFNFVF9DT05GSUcp
KSB7DQo+PiArICAgICAgICAgICAgICAgcHJfZXJyKCIlczogJXM6IFVIUzIgU0VUX0NPTkZJRyBm
YWlsIVxuIiwNCj4+ICsgICAgICAgICAgICAgICAgICAgICAgIG1tY19ob3N0bmFtZShob3N0KSwg
X19mdW5jX18pOw0KPj4gKyAgICAgICAgICAgICAgIHJldHVybiAtRUlPOw0KPj4gKyAgICAgICB9
DQo+PiArDQo+PiArICAgICAgIHJldHVybiAwOw0KPj4gK30NCj4+ICsNCj4+ICtzdGF0aWMgaW50
IHVoczJfZ29fZG9ybWFudChzdHJ1Y3QgbW1jX2hvc3QgKmhvc3QsIGJvb2wgaGliZXJuYXRlKQ0K
Pj4gK3sNCj4+ICsgICAgICAgc3RydWN0IG1tY19jb21tYW5kIGNtZCA9IHswfTsNCj4+ICsgICAg
ICAgdTE2IGhlYWRlciA9IDAsIGFyZyA9IDA7DQo+PiArICAgICAgIHUzMiAqcGF5bG9hZDsNCj4+
ICsgICAgICAgdTggcGxlbiA9IDE7DQo+PiArICAgICAgIGludCBlcnI7DQo+PiArDQo+PiArICAg
ICAgIEJVR19PTighaG9zdC0+Pm9wcy0+PnVoczJfc2V0X3JlZyk7DQo+PiArDQo+PiArICAgICAg
IC8qIERpc2FibGUgTm9ybWFsIElOVCAqLw0KPj4gKyAgICAgICBpZiAoaG9zdC0+Pm9wcy0+PnVo
czJfc2V0X3JlZyhob3N0LCBESVNBQkxFX0lOVCkpIHsNCj4+ICsgICAgICAgICAgICAgICBwcl9l
cnIoIiVzOiAlczogVUhTMiBESVNBQkxFX0lOVCBmYWlsIVxuIiwNCj4+ICsgICAgICAgICAgICAg
ICAgICAgICAgIG1tY19ob3N0bmFtZShob3N0KSwgX19mdW5jX18pOw0KPj4gKyAgICAgICAgICAg
ICAgIHJldHVybiAtRUlPOw0KPj4gKyAgICAgICB9DQo+PiArDQo+PiArICAgICAgIC8qIFRPRE86
IHNoYWxsIEkgdXNlIGhvc3QtPj51aHMyX2Rldl9wcm9wLm5vZGVfaWQgaGVyZT8gKi8NCj4+ICsg
ICAgICAgaGVhZGVyID0gVUhTMl9OQVRJVkVfUEFDS0VUIHwgVUhTMl9QQUNLRVRfVFlQRV9DQ01E
IHwNCj4+ICsgICAgICAgICAgICAgICBob3N0LT4+dWhzMl9kZXZfcHJvcC5ub2RlX2lkOw0KPj4g
Kw0KPj4gKyAgICAgICBhcmcgPSAoKFVIUzJfREVWX0NNRF9HT19ET1JNQU5UX1NUQVRFICYgMHhG
RikgPDwgOCkgfA0KPj4gKyAgICAgICAgICAgICAgIFVIUzJfTkFUSVZFX0NNRF9XUklURSB8DQo+
PiArICAgICAgICAgICAgICAgVUhTMl9OQVRJVkVfQ01EX1BMRU5fNEIgfA0KPj4gKyAgICAgICAg
ICAgICAgIChVSFMyX0RFVl9DTURfR09fRE9STUFOVF9TVEFURSA+Pj4+IDgpOw0KPj4gKw0KPj4g
KyAgICAgICBwYXlsb2FkID0ga2NhbGxvYyhwbGVuLCBzaXplb2YodTMyKSwgR0ZQX0tFUk5FTCk7
DQo+PiArICAgICAgIGlmICghcGF5bG9hZCkNCj4+ICsgICAgICAgICAgICAgICByZXR1cm4gLUVO
T01FTTsNCj4+ICsgICAgICAgaWYgKGhpYmVybmF0ZSkNCj4+ICsgICAgICAgICAgICAgICBwYXls
b2FkWzBdID0gVUhTMl9ERVZfQ01EX0RPUk1BTlRfSElCRVI7DQo+PiArDQo+PiArICAgICAgIERC
RygiQmVnaW4gR09fRE9STUFOVF9TVEFURSwgaGVhZGVyPTB4JXgsIGFyZz0weCV4LCBwYXlsb2Fk
PTB4JXguXG4iLA0KPj4gKyAgICAgICAgICAgICAgIGhlYWRlciwgYXJnLCBwYXlsb2FkWzBdKTsN
Cj4+ICsgICAgICAgZXJyID0gdWhzMl9jbWRfYXNzZW1ibGUoJmNtZCwgaGVhZGVyLCBhcmcsIHBh
eWxvYWQsIHBsZW4sDQo+PiArICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5VTEwsIDAp
Ow0KPj4gKyAgICAgICBpZiAoZXJyKSB7DQo+PiArICAgICAgICAgICAgICAgcHJfZXJyKCIlczog
JXM6IFVIUzIgQ01EIGFzc2VtYmxpbmcgZXJyID0gMHgleCFcbiIsDQo+PiArICAgICAgICAgICAg
ICAgICAgICAgICBtbWNfaG9zdG5hbWUoaG9zdCksIF9fZnVuY19fLCBlcnIpOw0KPj4gKyAgICAg
ICAgICAgICAgIHJldHVybiAtRUlPOw0KPj4gKyAgICAgICB9DQo+PiArDQo+PiArICAgICAgIGVy
ciA9IG1tY193YWl0X2Zvcl9jbWQoaG9zdCwgJmNtZCwgMCk7DQo+PiArICAgICAgIGlmIChlcnIp
IHsNCj4+ICsgICAgICAgICAgICAgICBwcl9lcnIoIiVzOiAlczogVUhTMiBDTUQgc2VuZCBmYWls
LCBlcnI9IDB4JXghXG4iLA0KPj4gKyAgICAgICAgICAgICAgICAgICAgICAgbW1jX2hvc3RuYW1l
KGhvc3QpLCBfX2Z1bmNfXywgZXJyKTsNCj4+ICsgICAgICAgICAgICAgICByZXR1cm4gLUVJTzsN
Cj4+ICsgICAgICAgfQ0KPj4gKw0KPj4gKyAgICAgICAvKiBDaGVjayBEb3JtYW50IFN0YXRlIGlu
IFByZXNlbnQgKi8NCj4+ICsgICAgICAgaWYgKGhvc3QtPj5vcHMtPj51aHMyX3NldF9yZWcoaG9z
dCwgQ0hFQ0tfRE9STUFOVCkpIHsNCj4+ICsgICAgICAgICAgICAgICBwcl9lcnIoIiVzOiAlczog
VUhTMiBHT19ET1JNQU5UX1NUQVRFIGZhaWwhXG4iLA0KPj4gKyAgICAgICAgICAgICAgICAgICAg
ICAgbW1jX2hvc3RuYW1lKGhvc3QpLCBfX2Z1bmNfXyk7DQo+PiArICAgICAgICAgICAgICAgcmV0
dXJuIC1FSU87DQo+PiArICAgICAgIH0NCj4+ICsNCj4+ICsgICAgICAgaG9zdC0+Pmlvcy5jbG9j
ayA9IDA7DQo+PiArICAgICAgIGlmIChoaWJlcm5hdGUpDQo+PiArICAgICAgICAgICAgICAgaG9z
dC0+Pmlvcy52ZGQgPSAtMTsNCj4+ICsgICAgICAgbW1jX3NldF9pb3MoaG9zdCk7DQo+PiArDQo+
PiArICAgICAgIHJldHVybiAwOw0KPj4gK30NCj4+ICsNCj4+ICtzdGF0aWMgaW50IHVoczJfY2hh
bmdlX3NwZWVkKHN0cnVjdCBtbWNfaG9zdCAqaG9zdCkNCj4+ICt7DQo+PiArICAgICAgIGludCBl
cnI7DQo+PiArDQo+PiArICAgICAgIEJVR19PTighaG9zdC0+Pm9wcy0+PnVoczJfZGV0ZWN0X2lu
aXQpOw0KPj4gKyAgICAgICBCVUdfT04oIWhvc3QtPj5vcHMtPj51aHMyX3NldF9yZWcpOw0KPj4g
Kw0KPj4gKyAgICAgICBlcnIgPSB1aHMyX2dvX2Rvcm1hbnQoaG9zdCwgZmFsc2UpOw0KPj4gKyAg
ICAgICBpZiAoZXJyKSB7DQo+PiArICAgICAgICAgICAgICAgcHJfZXJyKCIlczogJXM6IFVIUzIg
R09fRE9STUFOVF9TVEFURSBmYWlsLCBlcnI9IDB4JXghXG4iLA0KPj4gKyAgICAgICAgICAgICAg
ICAgICAgICAgbW1jX2hvc3RuYW1lKGhvc3QpLCBfX2Z1bmNfXywgZXJyKTsNCj4+ICsgICAgICAg
ICAgICAgICByZXR1cm4gLUVJTzsNCj4+ICsgICAgICAgfQ0KPj4gKw0KPj4gKyAgICAgICAvKiBF
bmFibGUgTm9ybWFsIElOVCAqLw0KPj4gKyAgICAgICBpZiAoaG9zdC0+Pm9wcy0+PnVoczJfc2V0
X3JlZyhob3N0LCBFTkFCTEVfSU5UKSkgew0KPj4gKyAgICAgICAgICAgICAgIHByX2VycigiJXM6
ICVzOiBVSFMyIEVOQUJMRV9JTlQgZmFpbCFcbiIsDQo+PiArICAgICAgICAgICAgICAgICAgICAg
ICBtbWNfaG9zdG5hbWUoaG9zdCksIF9fZnVuY19fKTsNCj4+ICsgICAgICAgICAgICAgICByZXR1
cm4gLUVJTzsNCj4+ICsgICAgICAgfQ0KPj4gKw0KPj4gKyAgICAgICAvKiBDaGFuZ2UgU3BlZWQg
UmFuZ2UgKi8NCj4+ICsgICAgICAgaWYgKGhvc3QtPj5vcHMtPj51aHMyX3NldF9yZWcoaG9zdCwg
U0VUX1NQRUVEX0IpKSB7DQo+PiArICAgICAgICAgICAgICAgcHJfZXJyKCIlczogJXM6IFVIUzIg
U0VUX1NQRUVEIGZhaWwhXG4iLA0KPj4gKyAgICAgICAgICAgICAgICAgICAgICAgbW1jX2hvc3Ru
YW1lKGhvc3QpLCBfX2Z1bmNfXyk7DQo+PiArICAgICAgICAgICAgICAgcmV0dXJuIC1FSU87DQo+
PiArICAgICAgIH0NCj4+ICsNCj4+ICsgICAgICAgLyogVE9ETzogaWYgSSBzZXQgY2xvY2sgaW4g
c2RoY2lfdWhzMl9pbnRlcmZhY2VfZGV0ZWN0KCksIEkgc2hvdWxkDQo+PiArICAgICAgICAqIHJl
bW92ZSBiZWxvdyBjb2Rlcy4NCj4+ICsgICAgICAgICovDQo+PiArICAgICAgIGhvc3QtPj5pb3Mu
Y2xvY2sgPSBVSFMyX1JDTEtfTUFYOw0KPj4gKyAgICAgICBtbWNfc2V0X2lvcyhob3N0KTsNCj4+
ICsNCj4+ICsgICAgICAgaWYgKGhvc3QtPj5vcHMtPj51aHMyX2RldGVjdF9pbml0KGhvc3QpKSB7
DQo+PiArICAgICAgICAgICAgICAgcHJfZXJyKCIlczogJXM6IHVoczJfZGV0ZWN0X2luaXQoKSBm
YWlsIVxuIiwNCj4+ICsgICAgICAgICAgICAgICAgICAgICAgIG1tY19ob3N0bmFtZShob3N0KSwg
X19mdW5jX18pOw0KPj4gKyAgICAgICAgICAgICAgIHJldHVybiAtRUlPOw0KPj4gKyAgICAgICB9
DQo+PiArDQo+PiArICAgICAgIERCRygiQ2hhbmdlIHRvIFNwZWVkIFJhbmdlIEIgc3VjY2VlZHMu
XG4iKTsNCj4+ICsgICAgICAgcmV0dXJuIDA7DQo+PiArfQ0KPj4gKw0KPj4gK2ludCBtbWNfdWhz
Ml90cnlfZnJlcXVlbmN5KHN0cnVjdCBtbWNfaG9zdCAqaG9zdCwgdW5zaWduZWQgZnJlcSkNCj4+
ICt7DQo+PiArICAgICAgIGludCBlcnIgPSAtRUlPOw0KPj4gKw0KPj4gKyAgICAgICBCVUdfT04o
IWhvc3QtPj5vcHMtPj51aHMyX2RldGVjdF9pbml0KTsNCj4+ICsgICAgICAgQlVHX09OKCFob3N0
LT4+b3BzLT4+dWhzMl9zZXRfcmVnKTsNCj4+ICsNCj4+ICsgICAgICAgaG9zdC0+PmZsYWdzIHw9
IE1NQ19VSFMyX1NVUFBPUlQ7DQo+PiArICAgICAgIGhvc3QtPj5mX2luaXQgPSBmcmVxOw0KPj4g
Kw0KPj4gKyNpZmRlZiBDT05GSUdfTU1DX0RFQlVHDQo+PiArICAgICAgIHByX2luZm8oIiVzOiAl
czogdHJ5aW5nIHRvIGluaXQgY2FyZCBhdCAldSBIelxuIiwNCj4+ICsgICAgICAgICAgICAgICAg
bW1jX2hvc3RuYW1lKGhvc3QpLCBfX2Z1bmNfXywgaG9zdC0+PmZfaW5pdCk7DQo+PiArI2VuZGlm
DQo+PiArDQo+PiArICAgICAgIHVoczJfcG93ZXJfdXAoaG9zdCk7DQo+PiArICAgICAgIGlmICho
b3N0LT4+b3BzLT4+dWhzMl9kZXRlY3RfaW5pdChob3N0KSkgew0KPj4gKyAgICAgICAgICAgICAg
IHByX2VycigiJXM6IGZhaWwgdG8gZGV0ZWN0IFVIUzIhXG4iLCBtbWNfaG9zdG5hbWUoaG9zdCkp
Ow0KPj4gKyAgICAgICAgICAgICAgIGVyciA9IFVIUzJfUEhZX0lOSVRfRVJSOw0KPj4gKyAgICAg
ICAgICAgICAgIGdvdG8gaW5pdF9mYWlsOw0KPj4gKyAgICAgICB9DQo+PiArDQo+PiArICAgICAg
IGlmICh1aHMyX2Rldl9pbml0KGhvc3QpKSB7DQo+PiArICAgICAgICAgICAgICAgcHJfZXJyKCIl
czogVUhTMiBERVZJQ0VfSU5JVCBmYWlsIVxuIiwgbW1jX2hvc3RuYW1lKGhvc3QpKTsNCj4+ICsg
ICAgICAgICAgICAgICBnb3RvIGluaXRfZmFpbDsNCj4+ICsgICAgICAgfQ0KPj4gKw0KPj4gKyAg
ICAgICBpZiAodWhzMl9lbnVtKGhvc3QpKSB7DQo+PiArICAgICAgICAgICAgICAgcHJfZXJyKCIl
czogVUhTMiBFTlVNRVJBVEUgZmFpbCFcbiIsIG1tY19ob3N0bmFtZShob3N0KSk7DQo+PiArICAg
ICAgICAgICAgICAgZ290byBpbml0X2ZhaWw7DQo+PiArICAgICAgIH0NCj4+ICsNCj4+ICsgICAg
ICAgaWYgKHVoczJfY29uZmlnX3JlYWQoaG9zdCkpIHsNCj4+ICsgICAgICAgICAgICAgICBwcl9l
cnIoIiVzOiBVSFMyIElOUVVJUllfQ09ORklHIGZhaWwhXG4iLCBtbWNfaG9zdG5hbWUoaG9zdCkp
Ow0KPj4gKyAgICAgICAgICAgICAgIGdvdG8gaW5pdF9mYWlsOw0KPj4gKyAgICAgICB9DQo+PiAr
DQo+PiArICAgICAgIGlmICh1aHMyX2NvbmZpZ193cml0ZShob3N0KSkgew0KPj4gKyAgICAgICAg
ICAgICAgIHByX2VycigiJXM6IFVIUzIgU0VUX0NPTU1PTl9DT05GSUcgZmFpbCFcbiIsDQo+PiAr
ICAgICAgICAgICAgICAgICAgICAgICBtbWNfaG9zdG5hbWUoaG9zdCkpOw0KPj4gKyAgICAgICAg
ICAgICAgIGdvdG8gaW5pdF9mYWlsOw0KPj4gKyAgICAgICB9DQo+PiArDQo+PiArICAgICAgIG1t
Y19kZWxheSgxMCk7DQo+PiArDQo+PiArICAgICAgIC8qIENoYW5nZSB0byBTcGVlZCBSYW5nZSBC
IGlmIGl0IGlzIHN1cHBvcnRlZCAqLw0KPj4gKyAgICAgICBpZiAoaG9zdC0+PmZsYWdzICYgTU1D
X1VIUzJfU1BFRURfQikNCj4+ICsgICAgICAgICAgICAgICBpZiAodWhzMl9jaGFuZ2Vfc3BlZWQo
aG9zdCkpIHsNCj4+ICsgICAgICAgICAgICAgICAgICAgICAgIHByX2VycigiJXM6IFVIUzIgdWhz
Ml9jaGFuZ2Vfc3BlZWQoKSBmYWlsIVxuIiwNCj4+ICsgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgbW1jX2hvc3RuYW1lKGhvc3QpKTsNCj4+ICsgICAgICAgICAgICAgICAgICAgICAgIGdv
dG8gaW5pdF9mYWlsOw0KPj4gKyAgICAgICAgICAgICAgIH0NCj4+ICsNCj4+ICsNCj4+ICsgICAg
ICAgaG9zdC0+PmZsYWdzIHw9IE1NQ19VSFMyX0lOSVRJQUxJWkVEOw0KPj4gKw0KPj4gKyAgICAg
ICBtbWNfZ29faWRsZShob3N0KTsNCj4+ICsNCj4+ICsgICAgICAgbW1jX3NlbmRfaWZfY29uZCho
b3N0LCBob3N0LT4+b2NyX2F2YWlsKTsNCj4+ICsNCj4+ICsgICAgICAgLyogT24gbWFya2V0LCBv
bmx5IGNhbiBzb21lIFNEIGNhcmRzIHN1cHBvcnQgVUhTLUlJIHNvIG9ubHkgY2FsbCBTRA0KPj4g
KyAgICAgICAgKiBhdHRhY2ggcHJvY2VzcyBoZXJlLg0KPj4gKyAgICAgICAgKi8NCj4+ICsgICAg
ICAgaWYgKCFtbWNfYXR0YWNoX3NkKGhvc3QpKQ0KPj4gKyAgICAgICAgICAgICAgIHJldHVybiAw
Ow0KPj4gKw0KPj4gK2luaXRfZmFpbDoNCj4+ICsgICAgICAgbW1jX3Bvd2VyX29mZihob3N0KTsN
Cj4+ICsgICAgICAgaWYgKGhvc3QtPj5mbGFncyAmIE1NQ19VSFMyX0lOSVRJQUxJWkVEKQ0KPj4g
KyAgICAgICAgICAgICAgIGhvc3QtPj5mbGFncyAmPSB+TU1DX1VIUzJfSU5JVElBTElaRUQ7DQo+
PiArICAgICAgIGhvc3QtPj5mbGFncyAmPSB+TU1DX1VIUzJfU1VQUE9SVDsNCj4+ICsNCj4+ICsg
ICAgICAgcmV0dXJuIGVycjsNCj4+ICt9DQo+PiArRVhQT1JUX1NZTUJPTF9HUEwobW1jX3VoczJf
dHJ5X2ZyZXF1ZW5jeSk7DQo+PiBkaWZmIC0tZ2l0IGEvZHJpdmVycy9tbWMvY29yZS91aHMyLmgg
Yi9kcml2ZXJzL21tYy9jb3JlL3VoczIuaA0KPj4gbmV3IGZpbGUgbW9kZSAxMDA2NDQNCj4+IGlu
ZGV4IDAwMDAwMDAuLjZmMjEzNzANCj4+IC0tLSAvZGV2L251bGwNCj4+ICsrKyBiL2RyaXZlcnMv
bW1jL2NvcmUvdWhzMi5oDQo+PiBAQCAtMCwwICsxLDI2IEBADQo+PiArLyoNCj4+ICsgKiAgZHJp
dmVyL21tYy9jb3JlL3VoczIuaCAtIFVIUy1JSSBkcml2ZXINCj4+ICsgKg0KPj4gKyAqIEhlYWRl
ciBmaWxlIGZvciBVSFMtSUkgcGFja2V0cywgSG9zdCBDb250cm9sbGVyIHJlZ2lzdGVycyBhbmQg
SS9PDQo+PiArICogYWNjZXNzb3JzLg0KPj4gKyAqDQo+PiArICogIENvcHlyaWdodCAoQykgMjAx
NCBJbnRlbCBDb3JwLCBBbGwgUmlnaHRzIFJlc2VydmVkLg0KPj4gKyAqDQo+PiArICogVGhpcyBw
cm9ncmFtIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBt
b2RpZnkNCj4+ICsgKiBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1Ymxp
YyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieQ0KPj4gKyAqIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5k
YXRpb247IGVpdGhlciB2ZXJzaW9uIDIgb2YgdGhlIExpY2Vuc2UsIG9yIChhdA0KPj4gKyAqIHlv
dXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4NCj4+ICsgKi8NCj4+ICsjaWZuZGVmIE1NQ19V
SFMyX0gNCj4+ICsjZGVmaW5lIE1NQ19VSFMyX0gNCj4+ICsNCj4+ICsjaW5jbHVkZSA8bGludXgv
bW1jL2NvcmUuaD4+DQo+PiArI2luY2x1ZGUgPGxpbnV4L21tYy9ob3N0Lmg+Pg0KPj4gKw0KPj4g
KyNkZWZpbmUgVUhTMl9QSFlfSU5JVF9FUlIgICAgICAxDQo+PiArDQo+PiArZXh0ZXJuIGludCB1
aHMyX3ByZXBhcmVfc2RfY21kKHN0cnVjdCBtbWNfaG9zdCAqaG9zdCwgc3RydWN0IG1tY19yZXF1
ZXN0ICptcnEpOw0KPj4gK2V4dGVybiB2b2lkIHVoczJfcG93ZXJfdXAoc3RydWN0IG1tY19ob3N0
ICpob3N0KTsNCj4+ICtleHRlcm4gaW50IG1tY191aHMyX3RyeV9mcmVxdWVuY3koc3RydWN0IG1t
Y19ob3N0ICpob3N0LCB1bnNpZ25lZCBmcmVxKTsNCj4+ICsNCj4+ICsjZW5kaWYgLyogTU1DX1VI
UzJfSCAqLw0KPj4gZGlmZiAtLWdpdCBhL2luY2x1ZGUvbGludXgvbW1jL2NvcmUuaCBiL2luY2x1
ZGUvbGludXgvbW1jL2NvcmUuaA0KPj4gaW5kZXggY2IyYjA0MC4uMWViYTEyOSAxMDA2NDQNCj4+
IC0tLSBhL2luY2x1ZGUvbGludXgvbW1jL2NvcmUuaA0KPj4gKysrIGIvaW5jbHVkZS9saW51eC9t
bWMvY29yZS5oDQo+PiBAQCAtMTAsNiArMTAsNyBAQA0KPj4NCj4+ICAjaW5jbHVkZSA8bGludXgv
aW50ZXJydXB0Lmg+Pg0KPj4gICNpbmNsdWRlIDxsaW51eC9jb21wbGV0aW9uLmg+Pg0KPj4gKyNp
bmNsdWRlIDxsaW51eC9tbWMvdWhzMi5oPj4NCj4+DQo+PiAgc3RydWN0IHJlcXVlc3Q7DQo+PiAg
c3RydWN0IG1tY19kYXRhOw0KPj4gQEAgLTEwMSw2ICsxMDIsOSBAQCBzdHJ1Y3QgbW1jX2NvbW1h
bmQgew0KPj4NCj4+ICAgICAgICAgc3RydWN0IG1tY19kYXRhICAgICAgICAgKmRhdGE7ICAgICAg
ICAgIC8qIGRhdGEgc2VnbWVudCBhc3NvY2lhdGVkIHdpdGggY21kICovDQo+PiAgICAgICAgIHN0
cnVjdCBtbWNfcmVxdWVzdCAgICAgICptcnE7ICAgICAgICAgICAvKiBhc3NvY2lhdGVkIHJlcXVl
c3QgKi8NCj4+ICsgICAgICAgc3RydWN0IHVoczJfY29tbWFuZCAgICAgKnVoczJfY21kOyAgICAg
IC8qIFVIUzIgY29tbWFuZCAqLw0KPj4gKyAgICAgICB1OCAgICAgICAgICAgICAgICAgICAgICAq
dWhzMl9yZXNwOyAgICAgLyogVUhTMiBuYXRpdmUgY21kIHJlc3AgKi8NCj4+ICsgICAgICAgdTgg
ICAgICAgICAgICAgICAgICAgICAgdWhzMl9yZXNwX2xlbjsgIC8qIFVIUzIgbmF0aXZlIGNtZCBy
ZXNwIGxlbiAqLw0KPj4gIH07DQo+Pg0KPj4gIHN0cnVjdCBtbWNfZGF0YSB7DQo+PiBAQCAtMTk4
LDYgKzIwMiw4IEBAIGV4dGVybiBpbnQgbW1jX2ZsdXNoX2NhY2hlKHN0cnVjdCBtbWNfY2FyZCAq
KTsNCj4+DQo+PiAgZXh0ZXJuIGludCBtbWNfZGV0ZWN0X2NhcmRfcmVtb3ZlZChzdHJ1Y3QgbW1j
X2hvc3QgKmhvc3QpOw0KPj4NCj4+ICtleHRlcm4gdm9pZCBtbWNfc2V0X2lvcyhzdHJ1Y3QgbW1j
X2hvc3QgKmhvc3QpOw0KPj4gKw0KPj4gIC8qKg0KPj4gICAqICAgICBtbWNfY2xhaW1faG9zdCAt
IGV4Y2x1c2l2ZWx5IGNsYWltIGEgaG9zdA0KPj4gICAqICAgICBAaG9zdDogbW1jIGhvc3QgdG8g
Y2xhaW0NCj4+IGRpZmYgLS1naXQgYS9pbmNsdWRlL2xpbnV4L21tYy9ob3N0LmggYi9pbmNsdWRl
L2xpbnV4L21tYy9ob3N0LmgNCj4+IGluZGV4IDlmMzIyNzAuLmE3OWUyYWEgMTAwNjQ0DQo+PiAt
LS0gYS9pbmNsdWRlL2xpbnV4L21tYy9ob3N0LmgNCj4+ICsrKyBiL2luY2x1ZGUvbGludXgvbW1j
L2hvc3QuaA0KPj4gQEAgLTE5LDEwICsxOSwxMiBAQA0KPj4gICNpbmNsdWRlIDxsaW51eC9tbWMv
Y29yZS5oPj4NCj4+ICAjaW5jbHVkZSA8bGludXgvbW1jL2NhcmQuaD4+DQo+PiAgI2luY2x1ZGUg
PGxpbnV4L21tYy9wbS5oPj4NCj4+ICsjaW5jbHVkZSA8bGludXgvbW1jL3VoczIuaD4+DQo+Pg0K
Pj4gIHN0cnVjdCBtbWNfaW9zIHsNCj4+ICAgICAgICAgdW5zaWduZWQgaW50ICAgIGNsb2NrOyAg
ICAgICAgICAgICAgICAgIC8qIGNsb2NrIHJhdGUgKi8NCj4+ICAgICAgICAgdW5zaWduZWQgc2hv
cnQgIHZkZDsNCj4+ICsgICAgICAgdW5zaWduZWQgc2hvcnQgIHZkZDI7DQo+Pg0KPj4gIC8qIHZk
ZCBzdG9yZXMgdGhlIGJpdCBudW1iZXIgb2YgdGhlIHNlbGVjdGVkIHZvbHRhZ2UgcmFuZ2UgZnJv
bSBiZWxvdy4gKi8NCj4+DQo+PiBAQCAtNjMsNiArNjUsNyBAQCBzdHJ1Y3QgbW1jX2lvcyB7DQo+
PiAgI2RlZmluZSBNTUNfVElNSU5HX01NQ19ERFI1MiAgIDgNCj4+ICAjZGVmaW5lIE1NQ19USU1J
TkdfTU1DX0hTMjAwICAgOQ0KPj4gICNkZWZpbmUgTU1DX1RJTUlOR19NTUNfSFM0MDAgICAxMA0K
Pj4gKyNkZWZpbmUgTU1DX1RJTUlOR19VSFMyICAgICAgICAgICAgICAgIDExDQo+Pg0KPj4gICAg
ICAgICB1bnNpZ25lZCBjaGFyICAgc2lnbmFsX3ZvbHRhZ2U7ICAgICAgICAgLyogc2lnbmFsbGlu
ZyB2b2x0YWdlICgxLjhWIG9yIDMuM1YpICovDQo+Pg0KPj4gQEAgLTE0Nyw2ICsxNTAsOSBAQCBz
dHJ1Y3QgbW1jX2hvc3Rfb3BzIHsNCj4+ICAgICAgICAgICovDQo+PiAgICAgICAgIGludCAgICAg
KCptdWx0aV9pb19xdWlyaykoc3RydWN0IG1tY19jYXJkICpjYXJkLA0KPj4gICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIGludCBkaXJlY3Rpb24sIGludCBibGtfc2l6
ZSk7DQo+PiArICAgICAgIC8qIFVIUzIgaW50ZXJmYWNlcyAqLw0KPj4gKyAgICAgICBpbnQgICAg
ICgqdWhzMl9kZXRlY3RfaW5pdCkoc3RydWN0IG1tY19ob3N0ICpob3N0KTsNCj4+ICsgICAgICAg
aW50ICAgICAoKnVoczJfc2V0X3JlZykoc3RydWN0IG1tY19ob3N0ICpob3N0LCBlbnVtIHVoczJf
YWN0IGFjdCk7DQo+PiAgfTsNCj4+DQo+PiAgc3RydWN0IG1tY19jYXJkOw0KPj4gQEAgLTIwMCw2
ICsyMDYsNyBAQCBzdHJ1Y3QgcmVndWxhdG9yOw0KPj4NCj4+ICBzdHJ1Y3QgbW1jX3N1cHBseSB7
DQo+PiAgICAgICAgIHN0cnVjdCByZWd1bGF0b3IgKnZtbWM7ICAgICAgICAgLyogQ2FyZCBwb3dl
ciBzdXBwbHkgKi8NCj4+ICsgICAgICAgc3RydWN0IHJlZ3VsYXRvciAqdm1tYzI7ICAgICAgICAv
KiBVSFMyIFZERDIgcG93ZXIgc3VwcGx5ICovDQo+PiAgICAgICAgIHN0cnVjdCByZWd1bGF0b3Ig
KnZxbW1jOyAgICAgICAgLyogT3B0aW9uYWwgVmNjcSBzdXBwbHkgKi8NCj4+ICB9Ow0KPj4NCj4+
IEBAIC0yMTUsMTAgKzIyMiwxMiBAQCBzdHJ1Y3QgbW1jX2hvc3Qgew0KPj4gICAgICAgICB1MzIg
ICAgICAgICAgICAgICAgICAgICBvY3JfYXZhaWxfc2RpbzsgLyogU0RJTy1zcGVjaWZpYyBPQ1Ig
Ki8NCj4+ICAgICAgICAgdTMyICAgICAgICAgICAgICAgICAgICAgb2NyX2F2YWlsX3NkOyAgIC8q
IFNELXNwZWNpZmljIE9DUiAqLw0KPj4gICAgICAgICB1MzIgICAgICAgICAgICAgICAgICAgICBv
Y3JfYXZhaWxfbW1jOyAgLyogTU1DLXNwZWNpZmljIE9DUiAqLw0KPj4gKyAgICAgICB1MzIgICAg
ICAgICAgICAgICAgICAgICBvY3JfYXZhaWxfdWhzMjsgLyogVUhTMi1zcGVjaWZpYyBPQ1IgKi8N
Cj4+ICAgICAgICAgc3RydWN0IG5vdGlmaWVyX2Jsb2NrICAgcG1fbm90aWZ5Ow0KPj4gICAgICAg
ICB1MzIgICAgICAgICAgICAgICAgICAgICBtYXhfY3VycmVudF8zMzA7DQo+PiAgICAgICAgIHUz
MiAgICAgICAgICAgICAgICAgICAgIG1heF9jdXJyZW50XzMwMDsNCj4+ICAgICAgICAgdTMyICAg
ICAgICAgICAgICAgICAgICAgbWF4X2N1cnJlbnRfMTgwOw0KPj4gKyAgICAgICB1MzIgICAgICAg
ICAgICAgICAgICAgICBtYXhfY3VycmVudF8xODBfdmRkMjsNCj4+DQo+PiAgI2RlZmluZSBNTUNf
VkREXzE2NV8xOTUgICAgICAgICAgICAgICAgMHgwMDAwMDA4MCAgICAgIC8qIFZERCB2b2x0YWdl
IDEuNjUgLSAxLjk1ICovDQo+PiAgI2RlZmluZSBNTUNfVkREXzIwXzIxICAgICAgICAgIDB4MDAw
MDAxMDAgICAgICAvKiBWREQgdm9sdGFnZSAyLjAgfiAyLjEgKi8NCj4+IEBAIC0yMzcsNiArMjQ2
LDcgQEAgc3RydWN0IG1tY19ob3N0IHsNCj4+ICAjZGVmaW5lIE1NQ19WRERfMzNfMzQgICAgICAg
ICAgMHgwMDIwMDAwMCAgICAgIC8qIFZERCB2b2x0YWdlIDMuMyB+IDMuNCAqLw0KPj4gICNkZWZp
bmUgTU1DX1ZERF8zNF8zNSAgICAgICAgICAweDAwNDAwMDAwICAgICAgLyogVkREIHZvbHRhZ2Ug
My40IH4gMy41ICovDQo+PiAgI2RlZmluZSBNTUNfVkREXzM1XzM2ICAgICAgICAgIDB4MDA4MDAw
MDAgICAgICAvKiBWREQgdm9sdGFnZSAzLjUgfiAzLjYgKi8NCj4+ICsjZGVmaW5lIE1NQ19WREQy
XzE2NV8xOTUgICAgICAgMHgwMDAwMDA4MCAgICAgIC8qIFZERDIgdm9sdGFnZSAxLjY1IC0gMS45
NSAqLw0KPj4NCj4+ICAgICAgICAgdTMyICAgICAgICAgICAgICAgICAgICAgY2FwczsgICAgICAg
ICAgIC8qIEhvc3QgY2FwYWJpbGl0aWVzICovDQo+Pg0KPj4gQEAgLTI2Niw2ICsyNzYsNyBAQCBz
dHJ1Y3QgbW1jX2hvc3Qgew0KPj4gICNkZWZpbmUgTU1DX0NBUF9EUklWRVJfVFlQRV9BICAoMSA8
PCAyMykgICAgICAgLyogSG9zdCBzdXBwb3J0cyBEcml2ZXIgVHlwZSBBICovDQo+PiAgI2RlZmlu
ZSBNTUNfQ0FQX0RSSVZFUl9UWVBFX0MgICgxIDw8IDI0KSAgICAgICAvKiBIb3N0IHN1cHBvcnRz
IERyaXZlciBUeXBlIEMgKi8NCj4+ICAjZGVmaW5lIE1NQ19DQVBfRFJJVkVSX1RZUEVfRCAgKDEg
PDwgMjUpICAgICAgIC8qIEhvc3Qgc3VwcG9ydHMgRHJpdmVyIFR5cGUgRCAqLw0KPj4gKyNkZWZp
bmUgTU1DX0NBUF9VSFMyICAgICAgICAgICAoMSA8PCAyNikgICAgICAgLyogSG9zdCBzdXBwb3J0
cyBVSFMyIG1vZGUgKi8NCj4+ICAjZGVmaW5lIE1NQ19DQVBfQ01EMjMgICAgICAgICAgKDEgPDwg
MzApICAgICAgIC8qIENNRDIzIHN1cHBvcnRlZC4gKi8NCj4+ICAjZGVmaW5lIE1NQ19DQVBfSFdf
UkVTRVQgICAgICAgKDEgPDwgMzEpICAgICAgIC8qIEhhcmR3YXJlIHJlc2V0ICovDQo+Pg0KPj4g
QEAgLTI5NCw2ICszMDUsMTcgQEAgc3RydWN0IG1tY19ob3N0IHsNCj4+DQo+PiAgICAgICAgIG1t
Y19wbV9mbGFnX3QgICAgICAgICAgIHBtX2NhcHM7ICAgICAgICAvKiBzdXBwb3J0ZWQgcG0gZmVh
dHVyZXMgKi8NCj4+DQo+PiArICAgICAgIHN0cnVjdCB1aHMyX2hvc3RfY2FwcyAgIHVoczJfY2Fw
czsgICAgICAvKiBVSFMyIGhvc3QgY2FwYWJpbGl0aWVzICovDQo+PiArICAgICAgIHN0cnVjdCB1
aHMyX2NhcmRfcHJvcCAgIHVoczJfZGV2X3Byb3A7ICAvKiBVSFMyIGRldmljZSBwcm9wZXJ0aWVz
ICovDQo+PiArICAgICAgIHUzMiAgICAgICAgICAgICAgICAgICAgIGdyb3VwX2Rlc2M7ICAgICAv
KiBVSFMyIHByb3BlcnR5ICovDQo+PiArICAgICAgIGludCAgICAgICAgICAgICAgICAgICAgIGZs
YWdzOw0KPj4gKyNkZWZpbmUgTU1DX1VIUzJfU1VQUE9SVCAgICAgICAoMSA8PCAwKQ0KPj4gKyNk
ZWZpbmUgTU1DX1VIUzJfSU5JVElBTElaRUQgICAoMSA8PCAxKQ0KPj4gKyNkZWZpbmUgTU1DX1VI
UzJfMkxfSEQgICAgICAgICAoMSA8PCAyKQ0KPj4gKyNkZWZpbmUgTU1DX1VIUzJfQVBQX0NNRCAg
ICAgICAoMSA8PCAzKQ0KPj4gKyNkZWZpbmUgTU1DX1VIUzJfU1BFRURfQiAgICAgICAoMSA8PCA0
KQ0KPj4gKyNkZWZpbmUgTU1DX1NVUFBPUlRfQURNQTMgICAgICAoMSA8PCA1KQ0KPj4gKw0KPj4g
ICNpZmRlZiBDT05GSUdfTU1DX0NMS0dBVEUNCj4+ICAgICAgICAgaW50ICAgICAgICAgICAgICAg
ICAgICAgY2xrX3JlcXVlc3RzOyAgIC8qIGludGVybmFsIHJlZmVyZW5jZSBjb3VudGVyICovDQo+
PiAgICAgICAgIHVuc2lnbmVkIGludCAgICAgICAgICAgIGNsa19kZWxheTsgICAgICAvKiBudW1i
ZXIgb2YgTUNJIGNsayBob2xkIGN5Y2xlcyAqLw0KPj4gQEAgLTUxOSw0ICs1NDEsOSBAQCBzdGF0
aWMgaW5saW5lIGJvb2wgbW1jX2NhcmRfaHM0MDAoc3RydWN0IG1tY19jYXJkICpjYXJkKQ0KPj4g
ICAgICAgICByZXR1cm4gY2FyZC0+Pmhvc3QtPj5pb3MudGltaW5nID09IE1NQ19USU1JTkdfTU1D
X0hTNDAwOw0KPj4gIH0NCj4+DQo+PiArc3RhdGljIGlubGluZSBib29sIG1tY19jYXJkX3VoczIo
c3RydWN0IG1tY19jYXJkICpjYXJkKQ0KPj4gK3sNCj4+ICsgICAgICAgcmV0dXJuIChjYXJkLT4+
aG9zdC0+PmZsYWdzICYgTU1DX1VIUzJfU1VQUE9SVCkgJiYNCj4+ICsgICAgICAgICAgICAgICAo
Y2FyZC0+Pmhvc3QtPj5mbGFncyAmIE1NQ19VSFMyX0lOSVRJQUxJWkVEKTsNCj4+ICt9DQo+PiAg
I2VuZGlmIC8qIExJTlVYX01NQ19IT1NUX0ggKi8NCj4+IGRpZmYgLS1naXQgYS9pbmNsdWRlL2xp
bnV4L21tYy91aHMyLmggYi9pbmNsdWRlL2xpbnV4L21tYy91aHMyLmgNCj4+IG5ldyBmaWxlIG1v
ZGUgMTAwNjQ0DQo+PiBpbmRleCAwMDAwMDAwLi5iMGU4MDVlDQo+PiAtLS0gL2Rldi9udWxsDQo+
PiArKysgYi9pbmNsdWRlL2xpbnV4L21tYy91aHMyLmgNCj4+IEBAIC0wLDAgKzEsMjc0IEBADQo+
PiArLyoNCj4+ICsgKiAgbGludXgvZHJpdmVycy9tbWMvaG9zdC91aHMyLmggLSBVSFMtSUkgZHJp
dmVyDQo+PiArICoNCj4+ICsgKiBIZWFkZXIgZmlsZSBmb3IgVUhTLUlJIHBhY2tldHMsIEhvc3Qg
Q29udHJvbGxlciByZWdpc3RlcnMgYW5kIEkvTw0KPj4gKyAqIGFjY2Vzc29ycy4NCj4+ICsgKg0K
Pj4gKyAqICBDb3B5cmlnaHQgKEMpIDIwMTQgSW50ZWwgQ29ycCwgQWxsIFJpZ2h0cyBSZXNlcnZl
ZC4NCj4+ICsgKg0KPj4gKyAqIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2Fu
IHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5DQo+PiArICogaXQgdW5kZXIgdGhlIHRlcm1z
IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkNCj4+ICsg
KiB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIgdmVyc2lvbiAyIG9mIHRoZSBM
aWNlbnNlLCBvciAoYXQNCj4+ICsgKiB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uDQo+
PiArICovDQo+PiArI2lmbmRlZiBMSU5VWF9NTUNfVUhTMl9IDQo+PiArI2RlZmluZSBMSU5VWF9N
TUNfVUhTMl9IDQo+PiArDQo+PiArc3RydWN0IG1tY19yZXF1ZXN0Ow0KPj4gKw0KPj4gKy8qIExJ
TksgTGF5ZXIgZGVmaW5pdGlvbiAqLw0KPj4gKy8qIFVIUzIgSGVhZGVyICovDQo+PiArI2RlZmlu
ZSBVSFMyX05BVElWRV9QQUNLRVRfUE9TIDcNCj4+ICsjZGVmaW5lIFVIUzJfTkFUSVZFX1BBQ0tF
VCAgICAgKDEgPDwgVUhTMl9OQVRJVkVfUEFDS0VUX1BPUykNCj4+ICsNCj4+ICsjZGVmaW5lIFVI
UzJfUEFDS0VUX1RZUEVfUE9TICAgNA0KPj4gKyNkZWZpbmUgVUhTMl9QQUNLRVRfVFlQRV9DQ01E
ICAoMCA8PCBVSFMyX1BBQ0tFVF9UWVBFX1BPUykNCj4+ICsjZGVmaW5lIFVIUzJfUEFDS0VUX1RZ
UEVfRENNRCAgKDEgPDwgVUhTMl9QQUNLRVRfVFlQRV9QT1MpDQo+PiArI2RlZmluZSBVSFMyX1BB
Q0tFVF9UWVBFX1JFUyAgICgyIDw8IFVIUzJfUEFDS0VUX1RZUEVfUE9TKQ0KPj4gKyNkZWZpbmUg
VUhTMl9QQUNLRVRfVFlQRV9EQVRBICAoMyA8PCBVSFMyX1BBQ0tFVF9UWVBFX1BPUykNCj4+ICsj
ZGVmaW5lIFVIUzJfUEFDS0VUX1RZUEVfTVNHICAgKDcgPDwgVUhTMl9QQUNLRVRfVFlQRV9QT1Mp
DQo+PiArDQo+PiArI2RlZmluZSBVSFMyX0RFU1RfSURfTUFTSyAgICAgIDB4MEYNCj4+ICsjZGVm
aW5lIFVIUzJfREVTVF9JRCAgICAgICAgICAgMHgxDQo+PiArDQo+PiArI2RlZmluZSBVSFMyX1NS
Q19JRF9QT1MgICAgICAgICAgICAgICAgMTINCj4+ICsjZGVmaW5lIFVIUzJfU1JDX0lEX01BU0sg
ICAgICAgMHhGMDAwDQo+PiArDQo+PiArI2RlZmluZSBVSFMyX1RSQU5TX0lEX1BPUyAgICAgIDgN
Cj4+ICsjZGVmaW5lIFVIUzJfVFJBTlNfSURfTUFTSyAgICAgMHgwNzAwDQo+PiArDQo+PiArLyog
VUhTMiBNU0cgKi8NCj4+ICsjZGVmaW5lIFVIUzJfTVNHX0NUR19QT1MgICAgICAgNQ0KPj4gKyNk
ZWZpbmUgVUhTMl9NU0dfQ1RHX0xNU0cgICAgICAweDAwDQo+PiArI2RlZmluZSBVSFMyX01TR19D
VEdfSU5UICAgICAgIDB4NjANCj4+ICsjZGVmaW5lIFVIUzJfTVNHX0NUR19BTVNHICAgICAgMHg4
MA0KPj4gKw0KPj4gKyNkZWZpbmUgVUhTMl9NU0dfQ1RHX0ZDUkVRICAgICAweDAwDQo+PiArI2Rl
ZmluZSBVSFMyX01TR19DVEdfRkNSRFkgICAgIDB4MDENCj4+ICsjZGVmaW5lIFVIUzJfTVNHX0NU
R19TVEFUICAgICAgMHgwMg0KPj4gKw0KPj4gKyNkZWZpbmUgVUhTMl9NU0dfQ09ERV9QT1MgICAg
ICAgICAgICAgICAgICAgICAgOA0KPj4gKyNkZWZpbmUgVUhTMl9NU0dfQ09ERV9GQ19VTlJFQ09W
RVJfRVJSICAgICAgICAgMHg4DQo+PiArI2RlZmluZSBVSFMyX01TR19DT0RFX1NUQVRfVU5SRUNP
VkVSX0VSUiAgICAgICAweDgNCj4+ICsjZGVmaW5lIFVIUzJfTVNHX0NPREVfU1RBVF9SRUNPVkVS
X0VSUiAgICAgICAgIDB4MQ0KPj4gKw0KPj4gKy8qIFRSQU5TIExheWVyIGRlZmluaXRpb24gKi8N
Cj4+ICsNCj4+ICsvKiBOYXRpdmUgcGFja2V0cyovDQo+PiArI2RlZmluZSBVSFMyX05BVElWRV9D
TURfUldfUE9TIDcNCj4+ICsjZGVmaW5lIFVIUzJfTkFUSVZFX0NNRF9XUklURSAgKDEgPDwgVUhT
Ml9OQVRJVkVfQ01EX1JXX1BPUykNCj4+ICsjZGVmaW5lIFVIUzJfTkFUSVZFX0NNRF9SRUFEICAg
KDAgPDwgVUhTMl9OQVRJVkVfQ01EX1JXX1BPUykNCj4+ICsNCj4+ICsjZGVmaW5lIFVIUzJfTkFU
SVZFX0NNRF9QTEVOX1BPUyAgICAgICA0DQo+PiArI2RlZmluZSBVSFMyX05BVElWRV9DTURfUExF
Tl80QiAgICAgICAgICAgICAgICAoMSA8PCBVSFMyX05BVElWRV9DTURfUExFTl9QT1MpDQo+PiAr
I2RlZmluZSBVSFMyX05BVElWRV9DTURfUExFTl84QiAgICAgICAgICAgICAgICAoMiA8PCBVSFMy
X05BVElWRV9DTURfUExFTl9QT1MpDQo+PiArI2RlZmluZSBVSFMyX05BVElWRV9DTURfUExFTl8x
NkIgICAgICAgKDMgPDwgVUhTMl9OQVRJVkVfQ01EX1BMRU5fUE9TKQ0KPj4gKw0KPj4gKyNkZWZp
bmUgVUhTMl9OQVRJVkVfQ0NNRF9HRVRfTUlPQURSX01BU0sgICAgICAgMHhGMDANCj4+ICsjZGVm
aW5lIFVIUzJfTkFUSVZFX0NDTURfTUlPQURSX01BU0sgICAgICAgICAgIDB4MEYNCj4+ICsNCj4+
ICsjZGVmaW5lIFVIUzJfTkFUSVZFX0NDTURfTElPQURSX1BPUyAgICAgICAgICAgIDgNCj4+ICsj
ZGVmaW5lIFVIUzJfTkFUSVZFX0NDTURfR0VUX0xJT0FEUl9NQVNLICAgICAgIDB4MEZGDQo+PiAr
DQo+PiArI2RlZmluZSBVSFMyX0RDTURfRE1fUE9TICAgICAgIDYNCj4+ICsjZGVmaW5lIFVIUzJf
RENNRF8yTF9IRF9NT0RFICAgKDEgPDwgVUhTMl9EQ01EX0RNX1BPUykNCj4+ICsjZGVmaW5lIFVI
UzJfRENNRF9MTV9QT1MgICAgICAgNQ0KPj4gKyNkZWZpbmUgVUhTMl9EQ01EX0xNX1RMRU5fRVhJ
U1QgICAgICAgICgxIDw8IFVIUzJfRENNRF9MTV9QT1MpDQo+PiArI2RlZmluZSBVSFMyX0RDTURf
VExVTV9QT1MgICAgIDQNCj4+ICsjZGVmaW5lIFVIUzJfRENNRF9UTFVNX0JZVEVfTU9ERSAgICAg
ICAoMSA8PCBVSFMyX0RDTURfVExVTV9QT1MpDQo+PiArI2RlZmluZSBVSFMyX05BVElWRV9EQ01E
X0RBTV9QT1MgICAgICAgMw0KPj4gKyNkZWZpbmUgVUhTMl9OQVRJVkVfRENNRF9EQU1fSU8gICAg
ICAgICAgICAgICAgKDEgPDwgVUhTMl9OQVRJVkVfRENNRF9EQU1fUE9TKQ0KPj4gKy8qDQo+PiAr
ICogUGVyIFVIUzIgc3BlYywgRENNRCBwYXlsb2FkIHNob3VsZCBiZSBNU0IgZmlyc3QuIFRoZXJl
IG1heSBiZQ0KPj4gKyAqIHR3byB0eXBlcyBvZiBkYXRhIGJlIGFzc2VtYmxlZCB0byBNU0I6DQo+
PiArICogMS4gVExFTjogSW5wdXQgYmxvY2sgc2l6ZSBmb3Igc2lnbmxlIHJlYWQvd3JpdGUgYW5k
IG51bWJlciBvZiBibG9ja3MNCj4+ICsgKiBmb3IgbXVsdGlwbGUgcmVhZC93cml0ZSB0byBjYWxj
dWxhdGUgVExFTiBhcyBNU0IgZmlyc3QgcGVyIHNwZWMuDQo+PiArICogMi4gU0QgY29tbWFuZCBh
cmd1bWVudC4NCj4+ICsgKi8NCj4+ICtzdGF0aWMgaW5saW5lIHUzMiB1aHMyX2RjbWRfY29udmVy
dF9tc2IodTMyIGlucHV0KQ0KPj4gK3sNCj4+ICsgICAgICAgdTMyIHJldCA9IDA7DQo+PiArDQo+
PiArICAgICAgIHJldCA9ICgoaW5wdXQgJiAweEZGKSA8PCAyNCkgfA0KPj4gKyAgICAgICAgICAg
ICAgICgoKGlucHV0ID4+Pj4gOCkgJiAweEZGKSA8PCAxNikgfA0KPj4gKyAgICAgICAgICAgICAg
ICgoKGlucHV0ID4+Pj4gMTYpICYgMHhGRikgPDwgOCkgfA0KPj4gKyAgICAgICAgICAgICAgICgo
aW5wdXQgPj4+PiAyNCkgJiAweEZGKTsNCj4+ICsgICAgICAgcmV0dXJuIHJldDsNCj4+ICt9DQo+
PiArDQo+PiArI2RlZmluZSBVSFMyX1JFU19OQUNLX1BPUyAgICAgIDcNCj4+ICsjZGVmaW5lIFVI
UzJfUkVTX05BQ0tfTUFTSyAgICAgKDB4MSA8PCBVSFMyX1JFU19OQUNLX1BPUykNCj4+ICsNCj4+
ICsjZGVmaW5lIFVIUzJfUkVTX0VDT0RFX1BPUyAgICAgNA0KPj4gKyNkZWZpbmUgVUhTMl9SRVNf
RUNPREVfTUFTSyAgICAweDcNCj4+ICsjZGVmaW5lIFVIUzJfUkVTX0VDT0RFX0NPTkQgICAgMQ0K
Pj4gKyNkZWZpbmUgVUhTMl9SRVNfRUNPREVfQVJHICAgICAyDQo+PiArI2RlZmluZSBVSFMyX1JF
U19FQ09ERV9HRU4gICAgIDMNCj4+ICsNCj4+ICsvKiBJT0FEUiBvZiBkZXZpY2UgcmVnaXN0ZXJz
ICovDQo+PiArI2RlZmluZSBVSFMyX0lPQURSX0dFTkVSSUNfQ0FQUyAgICAgICAgICAgICAgICAw
eDAwDQo+PiArI2RlZmluZSBVSFMyX0lPQURSX1BIWV9DQVBTICAgICAgICAgICAgMHgwMg0KPj4g
KyNkZWZpbmUgVUhTMl9JT0FEUl9MSU5LX0NBUFMgICAgICAgICAgIDB4MDQNCj4+ICsjZGVmaW5l
IFVIUzJfSU9BRFJfUlNWX0NBUFMgICAgICAgICAgICAweDA2DQo+PiArI2RlZmluZSBVSFMyX0lP
QURSX0dFTkVSSUNfU0VUVElOR1MgICAgMHgwOA0KPj4gKyNkZWZpbmUgVUhTMl9JT0FEUl9QSFlf
U0VUVElOR1MgICAgICAgICAgICAgICAgMHgwQQ0KPj4gKyNkZWZpbmUgVUhTMl9JT0FEUl9MSU5L
X1NFVFRJTkdTICAgICAgIDB4MEMNCj4+ICsjZGVmaW5lIFVIUzJfSU9BRFJfUFJFU0VUICAgICAg
ICAgICAgICAweDQwDQo+PiArDQo+PiArLyogU0QgYXBwbGljYXRpb24gcGFja2V0cyAqLw0KPj4g
KyNkZWZpbmUgVUhTMl9TRF9DTURfSU5ERVhfUE9TICAgICAgICAgIDgNCj4+ICsNCj4+ICsjZGVm
aW5lIFVIUzJfU0RfQ01EX0FQUF9QT1MgICAgICAgICAgICAxNA0KPj4gKyNkZWZpbmUgVUhTMl9T
RF9DTURfQVBQICAgICAgICAgICAgICAgICAgICAgICAgKDEgPDwgVUhTMl9TRF9DTURfQVBQX1BP
UykNCj4+ICsNCj4+ICtzdHJ1Y3QgdWhzMl9jb21tYW5kIHsNCj4+ICsgICAgICAgdTE2ICAgICBo
ZWFkZXI7DQo+PiArICAgICAgIHUxNiAgICAgYXJnOw0KPj4gKyAgICAgICB1MzIgICAgICpwYXls
b2FkOw0KPj4gKyAgICAgICB1MzIgICAgIHBheWxvYWRfbGVuOw0KPj4gKyAgICAgICB1MzIgICAg
IHBhY2tldF9sZW47DQo+PiArICAgICAgIHU4ICAgICAgKnJlc3A7DQo+PiArICAgICAgIHU4ICAg
ICAgcmVzcF9sZW47DQo+PiArfTsNCj4+ICsNCj4+ICtzdHJ1Y3QgdWhzMl9ob3N0X2NhcHMgew0K
Pj4gKyAgICAgICB1MzIgICAgIGRhcDsNCj4+ICsgICAgICAgdTMyICAgICBnYXA7DQo+PiArICAg
ICAgIHUzMiAgICAgbWF4YmxrX2xlbjsNCj4+ICsgICAgICAgdTMyICAgICBuX2ZjdTsNCj4+ICsg
ICAgICAgdTggICAgICBuX2xhbmVzOw0KPj4gKyAgICAgICB1OCAgICAgIGFkZHI2NDsNCj4+ICsg
ICAgICAgdTggICAgICBjYXJkX3R5cGU7DQo+PiArICAgICAgIHU4ICAgICAgcGh5X3JldjsNCj4+
ICsgICAgICAgdTggICAgICBzcGVlZF9yYW5nZTsNCj4+ICsgICAgICAgdTggICAgICBjYW5faGli
ZXJuYXRlOw0KPj4gKyAgICAgICB1OCAgICAgIG5fbHNzX3N5bmM7DQo+PiArICAgICAgIHU4ICAg
ICAgbl9sc3NfZGlyOw0KPj4gKyAgICAgICB1OCAgICAgIGxpbmtfcmV2Ow0KPj4gKyAgICAgICB1
OCAgICAgIGhvc3RfdHlwZTsNCj4+ICsgICAgICAgdTggICAgICBuX2RhdGFfZ2FwOw0KPj4gKw0K
Pj4gKyAgICAgICB1MzIgICAgIG1heGJsa19sZW5fc2V0Ow0KPj4gKyAgICAgICB1MzIgICAgIG5f
ZmN1X3NldDsNCj4+ICsgICAgICAgdTggICAgICBuX2xhbmVzX3NldDsNCj4+ICsgICAgICAgdTgg
ICAgICBuX2xzc19zeW5jX3NldDsNCj4+ICsgICAgICAgdTggICAgICBuX2xzc19kaXJfc2V0Ow0K
Pj4gKyAgICAgICB1OCAgICAgIG5fZGF0YV9nYXBfc2V0Ow0KPj4gKyAgICAgICB1OCAgICAgIG1h
eF9yZXRyeV9zZXQ7DQo+PiArfTsNCj4+ICsNCj4+ICtzdHJ1Y3QgdWhzMl9jYXJkX3Byb3Agew0K
Pj4gKyAgICAgICB1MzIgICAgIG5vZGVfaWQ7DQo+PiArICAgICAgIHUzMiAgICAgZGFwOw0KPj4g
KyAgICAgICB1MzIgICAgIGdhcDsNCj4+ICsgICAgICAgdTMyICAgICBuX2ZjdTsNCj4+ICsgICAg
ICAgdTMyICAgICBtYXhibGtfbGVuOw0KPj4gKyAgICAgICB1OCAgICAgIG5fbGFuZXM7DQo+PiAr
ICAgICAgIHU4ICAgICAgZGFkcl9sZW47DQo+PiArICAgICAgIHU4ICAgICAgYXBwX3R5cGU7DQo+
PiArICAgICAgIHU4ICAgICAgcGh5X21pbm9yX3JldjsNCj4+ICsgICAgICAgdTggICAgICBwaHlf
bWFqb3JfcmV2Ow0KPj4gKyAgICAgICB1OCAgICAgIGNhbl9oaWJlcm5hdGU7DQo+PiArICAgICAg
IHU4ICAgICAgbl9sc3Nfc3luYzsNCj4+ICsgICAgICAgdTggICAgICBuX2xzc19kaXI7DQo+PiAr
ICAgICAgIHU4ICAgICAgbGlua19taW5vcl9yZXY7DQo+PiArICAgICAgIHU4ICAgICAgbGlua19t
YWpvcl9yZXY7DQo+PiArICAgICAgIHU4ICAgICAgZGV2X3R5cGU7DQo+PiArICAgICAgIHU4ICAg
ICAgbl9kYXRhX2dhcDsNCj4+ICsNCj4+ICsgICAgICAgdTMyICAgICBuX2ZjdV9zZXQ7DQo+PiAr
ICAgICAgIHUzMiAgICAgbWF4YmxrX2xlbl9zZXQ7DQo+PiArICAgICAgIHU4ICAgICAgbl9sYW5l
c19zZXQ7DQo+PiArICAgICAgIHU4ICAgICAgc3BlZWRfcmFuZ2Vfc2V0Ow0KPj4gKyAgICAgICB1
OCAgICAgIG5fbHNzX3N5bmNfc2V0Ow0KPj4gKyAgICAgICB1OCAgICAgIG5fbHNzX2Rpcl9zZXQ7
DQo+PiArICAgICAgIHU4ICAgICAgbl9kYXRhX2dhcF9zZXQ7DQo+PiArICAgICAgIHU4ICAgICAg
cHdyY3RybF9tb2RlX3NldDsNCj4+ICsgICAgICAgdTggICAgICBtYXhfcmV0cnlfc2V0Ow0KPj4g
Kw0KPj4gKyAgICAgICB1OCAgICAgIGNmZ19jb21wbGV0ZTsNCj4+ICt9Ow0KPj4gKw0KPj4gK2Vu
dW0gdWhzMl9hY3Qgew0KPj4gKyAgICAgICBTRVRfQ09ORklHLA0KPj4gKyAgICAgICBFTkFCTEVf
SU5ULA0KPj4gKyAgICAgICBESVNBQkxFX0lOVCwNCj4+ICsgICAgICAgU0VUX1NQRUVEX0IsDQo+
PiArICAgICAgIENIRUNLX0RPUk1BTlQsDQo+PiArfTsNCj4+ICsNCj4+ICsvKiBVSFMtSUkgRGV2
aWNlIFJlZ2lzdGVycyAqLw0KPj4gKyNkZWZpbmUgVUhTMl9ERVZfQ09ORklHX1JFRyAgICAweDAw
MA0KPj4gKw0KPj4gKy8qIEdlbmVyYWwgQ2FwcyBhbmQgU2V0dGluZ3MgcmVnaXN0ZXJzICovDQo+
PiArI2RlZmluZSAgVUhTMl9ERVZfQ09ORklHX0dFTl9DQVBTICAgICAgKFVIUzJfREVWX0NPTkZJ
R19SRUcgKyAweDAwMCkNCj4+ICsjZGVmaW5lICAgVUhTMl9ERVZfQ09ORklHX05fTEFORVNfUE9T
ICA4DQo+PiArI2RlZmluZSAgIFVIUzJfREVWX0NPTkZJR19OX0xBTkVTX01BU0sgMHgzRg0KPj4g
KyNkZWZpbmUgICBVSFMyX0RFVl9DT05GSUdfMkxfSERfRkQgICAgIDB4MQ0KPj4gKyNkZWZpbmUg
ICBVSFMyX0RFVl9DT05GSUdfMkQxVV9GRCAgICAgIDB4Mg0KPj4gKyNkZWZpbmUgICBVSFMyX0RF
Vl9DT05GSUdfMUQyVV9GRCAgICAgIDB4NA0KPj4gKyNkZWZpbmUgICBVSFMyX0RFVl9DT05GSUdf
MkQyVV9GRCAgICAgIDB4OA0KPj4gKyNkZWZpbmUgICBVSFMyX0RFVl9DT05GSUdfREFEUl9QT1Mg
ICAgIDE0DQo+PiArI2RlZmluZSAgIFVIUzJfREVWX0NPTkZJR19EQURSX01BU0sgICAgMHgxDQo+
PiArI2RlZmluZSAgIFVIUzJfREVWX0NPTkZJR19BUFBfUE9TICAgICAgMTYNCj4+ICsjZGVmaW5l
ICAgVUhTMl9ERVZfQ09ORklHX0FQUF9NQVNLICAgICAweEZGDQo+PiArI2RlZmluZSAgIFVIUzJf
REVWX0NPTkZJR19BUFBfU0RfTUVNICAgMHgxDQo+PiArDQo+PiArI2RlZmluZSAgVUhTMl9ERVZf
Q09ORklHX0dFTl9TRVQgICAgICAgKFVIUzJfREVWX0NPTkZJR19SRUcgKyAweDAwOCkNCj4+ICsj
ZGVmaW5lICAgVUhTMl9ERVZfQ09ORklHX0dFTl9TRVRfMkxfRkRfSEQgICAgIDB4MA0KPj4gKyNk
ZWZpbmUgICBVSFMyX0RFVl9DT05GSUdfR0VOX1NFVF9DRkdfQ09NUExFVEUgKDB4MSA8PCAzMSkN
Cj4+ICsNCj4+ICsvKiBQSFkgQ2FwcyBhbmQgU2V0dGluZ3MgcmVnaXN0ZXJzICovDQo+PiArI2Rl
ZmluZSAgVUhTMl9ERVZfQ09ORklHX1BIWV9DQVBTICAgICAgKFVIUzJfREVWX0NPTkZJR19SRUcg
KyAweDAwMikNCj4+ICsjZGVmaW5lICAgVUhTMl9ERVZfQ09ORklHX1BIWV9NSU5PUl9NQVNLICAg
ICAgIDB4Rg0KPj4gKyNkZWZpbmUgICBVSFMyX0RFVl9DT05GSUdfUEhZX01BSk9SX1BPUyAgICAg
ICAgICAgICAgICA0DQo+PiArI2RlZmluZSAgIFVIUzJfREVWX0NPTkZJR19QSFlfTUFKT1JfTUFT
SyAgICAgICAweDMNCj4+ICsjZGVmaW5lICAgVUhTMl9ERVZfQ09ORklHX0NBTl9ISUJFUl9QT1Mg
ICAgICAgICAgICAgICAgMTUNCj4+ICsjZGVmaW5lICAgVUhTMl9ERVZfQ09ORklHX0NBTl9ISUJF
Ul9NQVNLICAgICAgIDB4MQ0KPj4gKyNkZWZpbmUgIFVIUzJfREVWX0NPTkZJR19QSFlfQ0FQUzEg
ICAgIChVSFMyX0RFVl9DT05GSUdfUkVHICsgMHgwMDMpDQo+PiArI2RlZmluZSAgIFVIUzJfREVW
X0NPTkZJR19OX0xTU19TWU5fTUFTSyAgICAgICAweEYNCj4+ICsjZGVmaW5lICAgVUhTMl9ERVZf
Q09ORklHX05fTFNTX0RJUl9QT1MgICAgICAgICAgICAgICAgNA0KPj4gKyNkZWZpbmUgICBVSFMy
X0RFVl9DT05GSUdfTl9MU1NfRElSX01BU0sgICAgICAgMHhGDQo+PiArDQo+PiArI2RlZmluZSAg
VUhTMl9ERVZfQ09ORklHX1BIWV9TRVQgICAgICAgKFVIUzJfREVWX0NPTkZJR19SRUcgKyAweDAw
QSkNCj4+ICsjZGVmaW5lICAgVUhTMl9ERVZfQ09ORklHX1BIWV9TRVRfU1BFRURfUE9TICAgIDYN
Cj4+ICsjZGVmaW5lICAgVUhTMl9ERVZfQ09ORklHX1BIWV9TRVRfU1BFRURfQSAgICAgIDB4MA0K
Pj4gKyNkZWZpbmUgICBVSFMyX0RFVl9DT05GSUdfUEhZX1NFVF9TUEVFRF9CICAgICAgMHgxDQo+
PiArDQo+PiArLyogTElOSy1UUkFOIENhcHMgYW5kIFNldHRpbnMgcmVnaXN0ZXJzICovDQo+PiAr
I2RlZmluZSAgVUhTMl9ERVZfQ09ORklHX0xJTktfVFJBTl9DQVBTICAgICAgICAoVUhTMl9ERVZf
Q09ORklHX1JFRyArIDB4MDA0KQ0KPj4gKyNkZWZpbmUgICBVSFMyX0RFVl9DT05GSUdfTFRfTUlO
T1JfTUFTSyAgICAgICAgICAgICAgICAweEYNCj4+ICsjZGVmaW5lICAgVUhTMl9ERVZfQ09ORklH
X0xUX01BSk9SX1BPUyAgICAgICAgIDQNCj4+ICsjZGVmaW5lICAgVUhTMl9ERVZfQ09ORklHX0xU
X01BSk9SX01BU0sgICAgICAgICAgICAgICAgMHgzDQo+PiArI2RlZmluZSAgIFVIUzJfREVWX0NP
TkZJR19OX0ZDVV9QT1MgICAgICAgICAgICA4DQo+PiArI2RlZmluZSAgIFVIUzJfREVWX0NPTkZJ
R19OX0ZDVV9NQVNLICAgICAgICAgICAweEZGDQo+PiArI2RlZmluZSAgIFVIUzJfREVWX0NPTkZJ
R19ERVZfVFlQRV9QT1MgICAgICAgICAxNg0KPj4gKyNkZWZpbmUgICBVSFMyX0RFVl9DT05GSUdf
REVWX1RZUEVfTUFTSyAgICAgICAgICAgICAgICAweDcNCj4+ICsjZGVmaW5lICAgVUhTMl9ERVZf
Q09ORklHX01BWF9CTEtfTEVOX1BPUyAgICAgIDIwDQo+PiArI2RlZmluZSAgIFVIUzJfREVWX0NP
TkZJR19NQVhfQkxLX0xFTl9NQVNLICAgICAweEZGRg0KPj4gKyNkZWZpbmUgIFVIUzJfREVWX0NP
TkZJR19MSU5LX1RSQU5fQ0FQUzEgICAgICAgKFVIUzJfREVWX0NPTkZJR19SRUcgKyAweDAwNSkN
Cj4+ICsjZGVmaW5lICAgVUhTMl9ERVZfQ09ORklHX05fREFUQV9HQVBfTUFTSyAgICAgIDB4RkYN
Cj4+ICsNCj4+ICsjZGVmaW5lICBVSFMyX0RFVl9DT05GSUdfTElOS19UUkFOX1NFVCAoVUhTMl9E
RVZfQ09ORklHX1JFRyArIDB4MDBDKQ0KPj4gKyNkZWZpbmUgICBVSFMyX0RFVl9DT05GSUdfTFRf
U0VUX01BWF9CTEtfTEVOICAgMHgyMDANCj4+ICsjZGVmaW5lICAgVUhTMl9ERVZfQ09ORklHX0xU
X1NFVF9NQVhfUkVUUllfUE9TIDE2DQo+PiArDQo+PiArLyogUHJlc2V0IHJlZ2lzdGVyICovDQo+
PiArI2RlZmluZSAgVUhTMl9ERVZfQ09ORklHX1BSRVNFVCAgICAgICAgICAgICAgICAoVUhTMl9E
RVZfQ09ORklHX1JFRyArIDB4MDQwKQ0KPj4gKw0KPj4gKyNkZWZpbmUgVUhTMl9ERVZfSU5UX1JF
RyAgICAgICAweDEwMA0KPj4gKw0KPj4gKyNkZWZpbmUgVUhTMl9ERVZfU1RBVFVTX1JFRyAgICAw
eDE4MA0KPj4gKw0KPj4gKyNkZWZpbmUgVUhTMl9ERVZfQ01EX1JFRyAgICAgICAweDIwMA0KPj4g
KyNkZWZpbmUgIFVIUzJfREVWX0NNRF9GVUxMX1JFU0VUICAgICAgIChVSFMyX0RFVl9DTURfUkVH
ICsgMHgwMDApDQo+PiArI2RlZmluZSAgVUhTMl9ERVZfQ01EX0dPX0RPUk1BTlRfU1RBVEUgKFVI
UzJfREVWX0NNRF9SRUcgKyAweDAwMSkNCj4+ICsjZGVmaW5lICAgVUhTMl9ERVZfQ01EX0RPUk1B
TlRfSElCRVIgICAoMHgxIDw8IDcpDQo+PiArI2RlZmluZSAgVUhTMl9ERVZfQ01EX0RFVklDRV9J
TklUICAgICAgKFVIUzJfREVWX0NNRF9SRUcgKyAweDAwMikNCj4+ICsjZGVmaW5lICBVSFMyX0RF
Vl9DTURfRU5VTUVSQVRFICAgICAgICAgICAgICAgIChVSFMyX0RFVl9DTURfUkVHICsgMHgwMDMp
DQo+PiArI2RlZmluZSAgVUhTMl9ERVZfQ01EX1RSQU5TX0FCT1JUICAgICAgKFVIUzJfREVWX0NN
RF9SRUcgKyAweDAwNCkNCj4+ICsNCj4+ICsjZGVmaW5lIFVIUzJfUkNMS19NQVggIDUyMDAwMDAw
DQo+PiArI2RlZmluZSBVSFMyX1JDTEtfTUlOICAyNjAwMDAwMA0KPj4gKw0KPj4gKyNlbmRpZiAv
KiBMSU5VWF9NTUNfVUhTMl9IICovDQo+PiAtLQ0KPj4gMS43LjkuNQ0KPj4NCi0tDQpUbyB1bnN1
YnNjcmliZSBmcm9tIHRoaXMgbGlzdDogc2VuZCB0aGUgbGluZSAidW5zdWJzY3JpYmUgbGludXgt
bW1jIiBpbg0KdGhlIGJvZHkgb2YgYSBtZXNzYWdlIHRvIG1ham9yZG9tb0B2Z2VyLmtlcm5lbC5v
cmcNCk1vcmUgbWFqb3Jkb21vIGluZm8gYXQgIGh0dHA6Ly92Z2VyLmtlcm5lbC5vcmcvbWFqb3Jk
b21vLWluZm8uaHRtbA0K
--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/drivers/mmc/core/Makefile b/drivers/mmc/core/Makefile
index 38ed210..c0be0cb 100644
--- a/drivers/mmc/core/Makefile
+++ b/drivers/mmc/core/Makefile
@@ -7,6 +7,7 @@  mmc_core-y			:= core.o bus.o host.o \
 				   mmc.o mmc_ops.o sd.o sd_ops.o \
 				   sdio.o sdio_ops.o sdio_bus.o \
 				   sdio_cis.o sdio_io.o sdio_irq.o \
-				   quirks.o slot-gpio.o
+				   quirks.o slot-gpio.o \
+				   uhs2.o
 
 mmc_core-$(CONFIG_DEBUG_FS)	+= debugfs.o
diff --git a/drivers/mmc/core/bus.c b/drivers/mmc/core/bus.c
index 86d2711..6565754 100644
--- a/drivers/mmc/core/bus.c
+++ b/drivers/mmc/core/bus.c
@@ -308,8 +308,9 @@  int mmc_add_card(struct mmc_card *card)
 	} else {
 		pr_info("%s: new %s%s%s%s%s card at address %04x\n",
 			mmc_hostname(card->host),
-			mmc_card_uhs(card) ? "ultra high speed " :
-			(mmc_card_hs(card) ? "high speed " : ""),
+			mmc_card_uhs2(card) ? "ultra high speed 2 " :
+			(mmc_card_uhs(card) ? "ultra high speed 1" :
+			(mmc_card_hs(card) ? "high speed " : "")),
 			mmc_card_hs400(card) ? "HS400 " :
 			(mmc_card_hs200(card) ? "HS200 " : ""),
 			mmc_card_ddr52(card) ? "DDR " : "",
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index 9584bff..8a62063 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -5,6 +5,7 @@ 
  *  SD support Copyright (C) 2004 Ian Molton, All Rights Reserved.
  *  Copyright (C) 2005-2008 Pierre Ossman, All Rights Reserved.
  *  MMCv4 support Copyright (C) 2006 Philip Langdale, All Rights Reserved.
+ *  UHS2 support Copyright (C) 2014 Intel Corp, All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -35,11 +36,13 @@ 
 #include <linux/mmc/mmc.h>
 #include <linux/mmc/sd.h>
 #include <linux/mmc/slot-gpio.h>
+#include <linux/mmc/uhs2.h>
 
 #include "core.h"
 #include "bus.h"
 #include "host.h"
 #include "sdio_bus.h"
+#include "uhs2.h"
 
 #include "mmc_ops.h"
 #include "sd_ops.h"
@@ -56,6 +59,7 @@ 
 
 static struct workqueue_struct *workqueue;
 static const unsigned freqs[] = { 400000, 300000, 200000, 100000 };
+static const unsigned uhs2_freqs[] = { 52000000, 26000000 };
 
 /*
  * Enabling software CRCs on the data blocks can be a significant (30%)
@@ -248,6 +252,12 @@  mmc_start_request(struct mmc_host *host, struct mmc_request *mrq)
 			mrq->stop->mrq = mrq;
 		}
 	}
+
+	if (host->flags & MMC_UHS2_SUPPORT &&
+	    host->flags & MMC_UHS2_INITIALIZED)
+		if (mrq->cmd->uhs2_cmd == NULL)
+			uhs2_prepare_sd_cmd(host, mrq);
+
 	mmc_host_clk_hold(host);
 	led_trigger_event(host->led, LED_FULL);
 	host->ops->request(host, mrq);
@@ -385,7 +395,7 @@  static int mmc_wait_for_data_req_done(struct mmc_host *host,
 				      struct mmc_request *mrq,
 				      struct mmc_async_req *next_req)
 {
-	struct mmc_command *cmd;
+	struct mmc_command *cmd = mrq->cmd;
 	struct mmc_context_info *context_info = &host->context_info;
 	int err;
 	unsigned long flags;
@@ -400,7 +410,6 @@  static int mmc_wait_for_data_req_done(struct mmc_host *host,
 		if (context_info->is_done_rcv) {
 			context_info->is_done_rcv = false;
 			context_info->is_new_req = false;
-			cmd = mrq->cmd;
 
 			if (!cmd->error || !cmd->retries ||
 			    mmc_card_removed(host->card)) {
@@ -424,6 +433,16 @@  static int mmc_wait_for_data_req_done(struct mmc_host *host,
 			}
 		}
 	}
+
+	if (cmd && cmd->uhs2_cmd) {
+#ifdef CONFIG_MMC_DEBUG
+		pr_info("%s: %s free uhs2_cmd!\n",
+			mmc_hostname(host), __func__);
+#endif
+		kfree(cmd->uhs2_cmd->payload);
+		kfree(cmd->uhs2_cmd);
+		cmd->uhs2_cmd = NULL;
+	}
 	return err;
 }
 
@@ -464,6 +483,16 @@  static void mmc_wait_for_req_done(struct mmc_host *host,
 		cmd->error = 0;
 		host->ops->request(host, mrq);
 	}
+
+	if (cmd && cmd->uhs2_cmd) {
+#ifdef CONFIG_MMC_DEBUG
+		pr_info("%s: %s free uhs2_cmd!\n",
+			mmc_hostname(host), __func__);
+#endif
+		kfree(cmd->uhs2_cmd->payload);
+		kfree(cmd->uhs2_cmd);
+		cmd->uhs2_cmd = NULL;
+	}
 }
 
 /**
@@ -974,7 +1003,7 @@  EXPORT_SYMBOL(mmc_put_card);
  * Internal function that does the actual ios call to the host driver,
  * optionally printing some debug output.
  */
-static inline void mmc_set_ios(struct mmc_host *host)
+void mmc_set_ios(struct mmc_host *host)
 {
 	struct mmc_ios *ios = &host->ios;
 
@@ -988,6 +1017,7 @@  static inline void mmc_set_ios(struct mmc_host *host)
 		mmc_set_ungated(host);
 	host->ops->set_ios(host, ios);
 }
+EXPORT_SYMBOL(mmc_set_ios);
 
 /*
  * Control chip select pin on a host.
@@ -1361,6 +1391,23 @@  int mmc_regulator_get_supply(struct mmc_host *mmc)
 		dev_info(dev, "No vqmmc regulator found\n");
 	}
 
+	if (!(mmc->caps & MMC_CAP_UHS2))
+		return 0;
+
+	mmc->supply.vmmc2 = devm_regulator_get_optional(dev, "vmmc2");
+	if (IS_ERR(mmc->supply.vmmc2)) {
+		if (PTR_ERR(mmc->supply.vmmc2) == -EPROBE_DEFER)
+			return -EPROBE_DEFER;
+		dev_info(dev, "No vmmc2 regulator found\n");
+	} else {
+		ret = mmc_regulator_get_ocrmask(mmc->supply.vmmc2);
+		if (ret > 0)
+			mmc->ocr_avail_uhs2 = ret;
+		else
+			dev_warn(dev, "Failed getting UHS2 OCR mask: %d\n",
+					ret);
+	}
+
 	return 0;
 }
 EXPORT_SYMBOL_GPL(mmc_regulator_get_supply);
@@ -1553,6 +1600,11 @@  void mmc_power_up(struct mmc_host *host, u32 ocr)
 	if (host->ios.power_mode == MMC_POWER_ON)
 		return;
 
+	if (host->flags & MMC_UHS2_SUPPORT) {
+		uhs2_power_up(host);
+		return;
+	}
+
 	mmc_host_clk_hold(host);
 
 	host->ios.vdd = fls(ocr) - 1;
@@ -2287,7 +2339,9 @@  static int mmc_do_hw_reset(struct mmc_host *host, int check)
 	}
 
 	/* Set initial state and call mmc_set_ios */
-	mmc_set_initial_state(host);
+	/* TODO: need verify this for UHS2. */
+	if (!host->flags & MMC_UHS2_SUPPORT)
+		mmc_set_initial_state(host);
 
 	mmc_host_clk_release(host);
 
@@ -2416,6 +2470,7 @@  void mmc_rescan(struct work_struct *work)
 	struct mmc_host *host =
 		container_of(work, struct mmc_host, detect.work);
 	int i;
+	int err;
 
 	if (host->trigger_card_event && host->ops->card_event) {
 		host->ops->card_event(host);
@@ -2470,6 +2525,27 @@  void mmc_rescan(struct work_struct *work)
 	}
 
 	mmc_claim_host(host);
+	if (host->caps & MMC_CAP_UHS2) {
+		/* Start to try UHS-II initialization from 52MHz to 26MHz
+		 * (RCLK range) per spec.
+		 */
+		for (i = 0; i < ARRAY_SIZE(uhs2_freqs); i++) {
+			err = mmc_uhs2_try_frequency(host,
+				max(uhs2_freqs[i], host->f_min));
+			if (!err) {
+				mmc_release_host(host);
+				goto out;
+			} else if (err == UHS2_PHY_INIT_ERR)
+				/* UHS2 IF detect or Lane Sync error.
+				 * Try legacy interface.
+				 */
+				break;
+
+			if (uhs2_freqs[i] <= host->f_min)
+				break;
+		}
+	}
+
 	for (i = 0; i < ARRAY_SIZE(freqs); i++) {
 		if (!mmc_rescan_try_freq(host, max(freqs[i], host->f_min)))
 			break;
@@ -2485,12 +2561,12 @@  void mmc_rescan(struct work_struct *work)
 
 void mmc_start_host(struct mmc_host *host)
 {
-	host->f_init = max(freqs[0], host->f_min);
 	host->rescan_disable = 0;
 	host->ios.power_mode = MMC_POWER_UNDEFINED;
 	if (host->caps2 & MMC_CAP2_NO_PRESCAN_POWERUP)
 		mmc_power_off(host);
-	else
+	/* Power up here will make UHS2 init ugly. */
+	else if (!(host->caps & MMC_CAP_UHS2))
 		mmc_power_up(host, host->ocr_avail);
 	mmc_gpiod_request_cd_irq(host);
 	_mmc_detect_change(host, 0, false);
@@ -2573,6 +2649,7 @@  int mmc_power_restore_host(struct mmc_host *host)
 		return -EINVAL;
 	}
 
+	/* TODO: for UHS2, may execute UHS2 init process again. */
 	mmc_power_up(host, host->card->ocr);
 	ret = host->bus_ops->power_restore(host);
 
diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c
index d90a6de..d2000be 100644
--- a/drivers/mmc/core/sd.c
+++ b/drivers/mmc/core/sd.c
@@ -969,6 +969,14 @@  static int mmc_sd_init_card(struct mmc_host *host, u32 ocr,
 	if (err)
 		goto free_card;
 
+	/* For UHS2, skip the UHS-I initialization. */
+	/* TODO: shall we send CMD6 to set Maximum Power Consumption
+	 * to get better performance?
+	 */
+	if ((host->flags & MMC_UHS2_SUPPORT) &&
+	    (host->flags & MMC_UHS2_INITIALIZED))
+		goto uhs2_done;
+
 	/* Initialization sequence for UHS-I cards */
 	if (rocr & SD_ROCR_S18A) {
 		err = mmc_sd_init_uhs_card(card);
@@ -1002,6 +1010,7 @@  static int mmc_sd_init_card(struct mmc_host *host, u32 ocr,
 		}
 	}
 
+uhs2_done:
 	host->card = card;
 	return 0;
 
@@ -1118,6 +1127,9 @@  static int _mmc_sd_resume(struct mmc_host *host)
 	if (!mmc_card_suspended(host->card))
 		goto out;
 
+	/* TODO: for UHS2, may need UHS2 init process to be executed
+	 * again (DEVICE_INIT/ENUMERATE/CONFIG, etc).
+	 */
 	mmc_power_up(host, host->card->ocr);
 	err = mmc_sd_init_card(host, host->card->ocr, host->card);
 	mmc_card_clr_suspended(host->card);
@@ -1185,6 +1197,9 @@  static int mmc_sd_power_restore(struct mmc_host *host)
 	int ret;
 
 	mmc_claim_host(host);
+	/* TODO: for UHS2, may need UHS2 init process to be executed
+	 * again (DEVICE_INIT/ENUMERATE/CONFIG, etc).
+	 */
 	ret = mmc_sd_init_card(host, host->card->ocr, host->card);
 	mmc_release_host(host);
 
diff --git a/drivers/mmc/core/sd_ops.c b/drivers/mmc/core/sd_ops.c
index 48d0c93..fb2158f 100644
--- a/drivers/mmc/core/sd_ops.c
+++ b/drivers/mmc/core/sd_ops.c
@@ -30,6 +30,18 @@  int mmc_app_cmd(struct mmc_host *host, struct mmc_card *card)
 	BUG_ON(!host);
 	BUG_ON(card && (card->host != host));
 
+	/* UHS2 packet has APP bit so only set APP_CMD flag here.
+	 * Will set the APP bit when assembling UHS2 packet.
+	 */
+	if (host->flags &  MMC_UHS2_SUPPORT &&
+	    host->flags & MMC_UHS2_INITIALIZED) {
+#ifdef CONFIG_MMC_DEBUG
+		pr_info("%s: it is app cmd, skip it!\n", mmc_hostname(host));
+#endif
+		host->flags |= MMC_UHS2_APP_CMD;
+		return 0;
+	}
+
 	cmd.opcode = MMC_APP_CMD;
 
 	if (card) {
diff --git a/drivers/mmc/core/uhs2.c b/drivers/mmc/core/uhs2.c
new file mode 100644
index 0000000..86a1dfa
--- /dev/null
+++ b/drivers/mmc/core/uhs2.c
@@ -0,0 +1,908 @@ 
+/*
+ *  linux/drivers/mmc/core/uhs2.c
+ *
+ *  Copyright (C) 2014 Intel Corp, All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/err.h>
+#include <linux/slab.h>
+
+#include <linux/mmc/host.h>
+#include <linux/mmc/card.h>
+#include <linux/mmc/mmc.h>
+#include <linux/mmc/core.h>
+#include <linux/mmc/sdio.h>
+#include <linux/mmc/slot-gpio.h>
+#include <linux/mmc/uhs2.h>
+
+#include "uhs2.h"
+#include "mmc_ops.h"
+#include "sd_ops.h"
+#include "core.h"
+
+#define DBG(f, x...) \
+	pr_warn("[%s()]: " f, __func__, ## x)
+
+/*
+ * TODO: payload, uhs2_cmd are all allocated which should be freed when
+ * response is got.
+ * resp is inputted outside which should be a variable created by caller
+ * so caller should handle it. For SD command, there is no uhs2_resp and
+ * response should be stored in resp of mmc_command.
+ */
+int uhs2_cmd_assemble(struct mmc_command *cmd, u16 header, u16 arg,
+			u32 *payload, u8 plen, u8 *resp, u8 resp_len)
+{
+	struct uhs2_command *uhs2_cmd;
+
+	if (cmd == NULL || payload == NULL || resp == NULL)
+		return -EIO;
+
+	uhs2_cmd = kzalloc(sizeof(struct uhs2_command),
+						GFP_KERNEL);
+	if (!uhs2_cmd) {
+		kfree(payload);
+		return -ENOMEM;
+	}
+
+	uhs2_cmd->header = header;
+	uhs2_cmd->arg = arg;
+	uhs2_cmd->payload = payload;
+	uhs2_cmd->payload_len = plen * sizeof(u32);
+	uhs2_cmd->packet_len = uhs2_cmd->payload_len + 4;
+
+	cmd->uhs2_cmd = uhs2_cmd;
+	cmd->uhs2_resp = resp;
+	cmd->uhs2_resp_len = resp_len;
+
+#ifdef CONFIG_MMC_DEBUG
+	pr_info("%s: uhs2_cmd->header = 0x%x, uhs2_cmd->arg = 0x%x,"
+		" uhs2_cmd->payload_len = %d, uhs2_cmd->packet_len = %d,"
+		" resp_len = %d.\n",
+		__func__, uhs2_cmd->header,
+		uhs2_cmd->arg, uhs2_cmd->payload_len, uhs2_cmd->packet_len,
+		cmd->uhs2_resp_len);
+#endif
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(uhs2_cmd_assemble);
+
+int uhs2_prepare_sd_cmd(struct mmc_host *host, struct mmc_request *mrq)
+{
+	struct mmc_command *cmd;
+	u16 header = 0, arg = 0;
+	u32 *payload;
+	u8 plen = 0;
+	int err = 0;
+
+	cmd = mrq->cmd;
+	header = host->uhs2_dev_prop.node_id;
+	if (cmd->flags & MMC_CMD_ADTC)
+		header |= UHS2_PACKET_TYPE_DCMD;
+	else
+		header |= UHS2_PACKET_TYPE_CCMD;
+	DBG("header = 0x%x.\n", header);
+
+	arg = cmd->opcode << UHS2_SD_CMD_INDEX_POS;
+	if (host->flags & MMC_UHS2_APP_CMD) {
+		arg |= UHS2_SD_CMD_APP;
+		host->flags &= ~MMC_UHS2_APP_CMD;
+	}
+
+	if (cmd->flags & MMC_CMD_ADTC) {
+		/* TODO: do not understand. It may relates with ADMA3. */
+		if (cmd->data->blocks > 1) {
+			payload = kzalloc(4*sizeof(u32), GFP_KERNEL);
+			if (!payload)
+				return -ENOMEM;
+			payload[2] = 0;
+			payload[3] = 0;
+			plen = 8 / sizeof(u32);
+		} else {
+			payload = kzalloc(2*sizeof(u32), GFP_KERNEL);
+			if (!payload)
+				return -ENOMEM;
+			plen = 8 / sizeof(u32);
+		}
+
+		if (host->flags & MMC_UHS2_2L_HD)
+			arg |= UHS2_DCMD_2L_HD_MODE;
+
+		arg |= UHS2_DCMD_LM_TLEN_EXIST;
+
+		if (cmd->data->blocks == 1 &&
+		    cmd->opcode != MMC_READ_SINGLE_BLOCK &&
+		    cmd->opcode != MMC_WRITE_BLOCK) {
+			arg |= UHS2_DCMD_TLUM_BYTE_MODE;
+			payload[1] = uhs2_dcmd_convert_msb(cmd->data->blksz);
+		} else {
+			payload[1] = uhs2_dcmd_convert_msb(cmd->data->blocks);
+		}
+
+		if (cmd->opcode == SD_IO_RW_EXTENDED) {
+			arg &= ~(UHS2_DCMD_LM_TLEN_EXIST |
+				UHS2_DCMD_TLUM_BYTE_MODE |
+				UHS2_NATIVE_DCMD_DAM_IO);
+			payload[1] = 0;
+			plen = 4 / sizeof(u32);
+		}
+	} else {
+		payload = kzalloc(1 * sizeof(u32), GFP_KERNEL);
+		if (!payload)
+			return -ENOMEM;
+		plen = 4 / sizeof(u32);
+	}
+
+	payload[0] = uhs2_dcmd_convert_msb(cmd->arg);
+#ifdef CONFIG_MMC_DEBUG
+	pr_info("%s: %s: sd_cmd->arg = 0x%x, payload[0]= 0x%x.\n",
+		 mmc_hostname(host), __func__, cmd->arg, payload[0]);
+#endif
+
+	err = uhs2_cmd_assemble(cmd, header, arg, payload, plen,
+				NULL, 0);
+
+	return err;
+}
+EXPORT_SYMBOL_GPL(uhs2_prepare_sd_cmd);
+
+/*
+ * Apply power to the UHS2 stack.  This is a two-stage process.
+ * First, we enable power to the card without the clock running.
+ * We then wait a bit for the power to stabilise.  Finally,
+ * enable the bus drivers and clock to the card.
+ *
+ * We must _NOT_ enable the clock prior to power stablising.
+ *
+ * If a host does all the power sequencing itself, ignore the
+ * initial MMC_POWER_UP stage.
+ */
+void uhs2_power_up(struct mmc_host *host)
+{
+	if (host->ios.power_mode == MMC_POWER_ON)
+		return;
+
+	DBG("Enter!\n");
+	mmc_host_clk_hold(host);
+
+	host->ios.vdd = fls(host->ocr_avail) - 1;
+	host->ios.vdd2 = fls(host->ocr_avail_uhs2) - 1;
+	if (mmc_host_is_spi(host))
+		host->ios.chip_select = MMC_CS_HIGH;
+	else
+		host->ios.chip_select = MMC_CS_DONTCARE;
+	host->ios.clock = host->f_init;
+	host->ios.timing = MMC_TIMING_UHS2;
+	host->ios.power_mode = MMC_POWER_ON;
+	mmc_set_ios(host);
+
+	/*
+	 * This delay should be sufficient to allow the power supply
+	 * to reach the minimum voltage.
+	 */
+	mmc_delay(10);
+
+	mmc_host_clk_release(host);
+}
+EXPORT_SYMBOL_GPL(uhs2_power_up);
+
+static int uhs2_dev_init(struct mmc_host *host)
+{
+	struct mmc_command cmd = {0};
+	u32 cnt;
+	u32 dap, gap, gap1;
+	u16 header = 0, arg = 0;
+	u32 *payload;
+	u8 plen = 1;
+	u8 gd = 0, cf = 1;
+	u8 resp[6] = {0};
+	u8 resp_len = 6;
+	int err;
+
+	dap = host->uhs2_caps.dap;
+	gap = host->uhs2_caps.gap;
+	DBG("dap = 0x%x, gap = 0x%x.\n", dap, gap);
+
+	header = UHS2_NATIVE_PACKET | UHS2_PACKET_TYPE_CCMD;
+	arg = ((UHS2_DEV_CMD_DEVICE_INIT & 0xFF) << 8) |
+		UHS2_NATIVE_CMD_WRITE |
+		UHS2_NATIVE_CMD_PLEN_4B |
+		(UHS2_DEV_CMD_DEVICE_INIT >> 8);
+
+	payload = kcalloc(plen, sizeof(u32), GFP_KERNEL);
+	if (!payload)
+		return -ENOMEM;
+	payload[0] = ((dap & 0xF) << 12) |
+		  (cf << 11) |
+		  ((gd & 0xF) << 4) |
+		  (gap & 0xF);
+
+	err = uhs2_cmd_assemble(&cmd, header, arg, payload, plen,
+			resp, resp_len);
+	if (err) {
+		pr_err("%s: %s: UHS2 CMD assembling err = 0x%x!\n",
+			mmc_hostname(host), __func__, err);
+		return -EIO;
+	}
+
+	DBG("Begin DEVICE_INIT, header=0x%x, arg=0x%x, payload=0x%x.\n",
+		header, arg, payload[0]);
+	for (cnt = 0; cnt < 30; cnt++) {
+		DBG("Sending DEVICE_INIT. Count = %d\n", cnt);
+		err = mmc_wait_for_cmd(host, &cmd, 0);
+		if (err) {
+			pr_err("%s: %s: UHS2 CMD send fail, err= 0x%x!\n",
+				mmc_hostname(host), __func__, err);
+			return -EIO;
+		}
+
+#ifdef CONFIG_MMC_DEBUG
+		int i;
+
+		pr_warn("%s: DEVICE_INIT response is: ", mmc_hostname(host));
+		for (i = 0; i < resp_len; i++)
+			pr_warn("0x%x ", resp[i]);
+		pr_warn("\n");
+#endif
+
+		if (resp[3] != (UHS2_DEV_CMD_DEVICE_INIT & 0xFF)) {
+			pr_err("%s: DEVICE_INIT response is wrong!\n",
+				mmc_hostname(host));
+			return -EIO;
+		}
+
+		if (resp[5] & 0x8) {
+			DBG("CF is set, device is initialized!\n");
+			host->group_desc = gd;
+		} else {
+			gap1 = resp[4] & 0x0F;
+			if (gap == gap1)
+				gd++;
+		}
+	}
+	if (30 == cnt) {
+		pr_err("%s: DEVICE_INIT fail, already 30 times!\n",
+			mmc_hostname(host));
+		return -EIO;
+	}
+
+	return 0;
+}
+
+static int uhs2_enum(struct mmc_host *host)
+{
+	struct mmc_command cmd = {0};
+	u16 header = 0, arg = 0;
+	u32 *payload;
+	u8 plen = 1;
+	u8 id_f = 0xF, id_l = 0x0;
+	u8 resp[8] = {0};
+	u8 resp_len = 8;
+	int err;
+
+	header = UHS2_NATIVE_PACKET | UHS2_PACKET_TYPE_CCMD;
+	arg = ((UHS2_DEV_CMD_ENUMERATE & 0xFF) << 8) |
+		UHS2_NATIVE_CMD_WRITE |
+		UHS2_NATIVE_CMD_PLEN_4B |
+		(UHS2_DEV_CMD_ENUMERATE >> 8);
+
+	payload = kcalloc(plen, sizeof(u32), GFP_KERNEL);
+	if (!payload)
+		return -ENOMEM;
+	payload[0] = (id_f << 4) | id_l;
+
+	DBG("Begin ENUMERATE, header=0x%x, arg=0x%x, payload=0x%x.\n",
+		header, arg, payload[0]);
+	err = uhs2_cmd_assemble(&cmd, header, arg, payload, plen,
+				resp, resp_len);
+	if (err) {
+		pr_err("%s: %s: UHS2 CMD assembling err = 0x%x!\n",
+			mmc_hostname(host), __func__, err);
+		return -EIO;
+	}
+
+	err = mmc_wait_for_cmd(host, &cmd, 0);
+	if (err) {
+		pr_err("%s: %s: UHS2 CMD send fail, err= 0x%x!\n",
+			mmc_hostname(host), __func__, err);
+		return -EIO;
+	}
+
+#ifdef CONFIG_MMC_DEBUG
+	int i;
+
+	pr_warn("%s: ENUMERATE response is: ", mmc_hostname(host));
+	for (i = 0; i < resp_len; i++)
+		pr_warn("0x%x ", resp[i]);
+	pr_warn("\n");
+#endif
+
+	if (resp[3] != (UHS2_DEV_CMD_ENUMERATE & 0xFF)) {
+		pr_err("%s: ENUMERATE response is wrong!\n",
+			mmc_hostname(host));
+		return -EIO;
+	}
+
+	/* TODO: shall I keep id_f or id_l as device node id?
+	 * For P2P connection, I think id_f is ok.
+	 */
+	id_f = (resp[4] >> 4) & 0xF;
+	id_l = resp[4] & 0xF;
+	DBG("id_f = %d, id_l = %d.\n", id_f, id_l);
+	DBG("Enumerate Cmd Completed. No. of Devices connected = %d\n",
+		id_l - id_f + 1);
+	host->uhs2_dev_prop.node_id = id_f;
+
+	return 0;
+}
+
+static int uhs2_config_read(struct mmc_host *host)
+{
+	struct mmc_command cmd = {0};
+	u16 header = 0, arg = 0;
+	u32 cap;
+	int err;
+
+	DBG("INQUIRY_CFG: read Generic Caps.\n");
+	header = UHS2_NATIVE_PACKET | UHS2_PACKET_TYPE_CCMD;
+	arg = ((UHS2_DEV_CONFIG_GEN_CAPS & 0xFF) << 8) |
+		UHS2_NATIVE_CMD_READ |
+		UHS2_NATIVE_CMD_PLEN_4B |
+		(UHS2_DEV_CONFIG_GEN_CAPS >> 8);
+
+	DBG("Begin INQUIRY_CFG, header=0x%x, arg=0x%x.\n",
+		header, arg);
+	/* There is no payload because per spec, there should be
+	 * no payload field for read CCMD.
+	 * Plen is set in arg. Per spec, plen for read CCMD
+	 * represents the len of read data which is assigned in payload
+	 * of following RES (p136).
+	 */
+	err = uhs2_cmd_assemble(&cmd, header, arg, NULL, 0,
+				NULL, 0);
+	if (err) {
+		pr_err("%s: %s: UHS2 CMD assembling err = 0x%x!\n",
+			mmc_hostname(host), __func__, err);
+		return -EIO;
+	}
+
+	err = mmc_wait_for_cmd(host, &cmd, 0);
+	if (err) {
+		pr_err("%s: %s: UHS2 CMD send fail, err= 0x%x!\n",
+			mmc_hostname(host), __func__, err);
+		return -EIO;
+	}
+
+#ifdef CONFIG_MMC_DEBUG
+	int i;
+
+	pr_warn("%s: INQUIRY_CFG generic response is: ", mmc_hostname(host));
+	for (i = 0; i < 2; i++)
+		pr_warn("0x%x ", cmd.resp[i]);
+	pr_warn("\n");
+#endif
+
+	cap = cmd.resp[0];
+	DBG("Device Generic Caps (0-31) is: 0x%x.\n", cap);
+	host->uhs2_dev_prop.n_lanes = (cap >> UHS2_DEV_CONFIG_N_LANES_POS) &
+					UHS2_DEV_CONFIG_N_LANES_MASK;
+	host->uhs2_dev_prop.dadr_len = (cap >> UHS2_DEV_CONFIG_DADR_POS) &
+					UHS2_DEV_CONFIG_DADR_MASK;
+	host->uhs2_dev_prop.app_type = (cap >> UHS2_DEV_CONFIG_APP_POS) &
+					UHS2_DEV_CONFIG_APP_MASK;
+
+	DBG("INQUIRY_CFG: read PHY Caps.\n");
+	arg = ((UHS2_DEV_CONFIG_PHY_CAPS & 0xFF) << 8) |
+		UHS2_NATIVE_CMD_READ |
+		UHS2_NATIVE_CMD_PLEN_8B |
+		(UHS2_DEV_CONFIG_PHY_CAPS >> 8);
+
+	DBG("Begin INQUIRY_CFG, header=0x%x, arg=0x%x.\n",
+		header, arg);
+	err = uhs2_cmd_assemble(&cmd, header, arg, NULL, 0,
+				NULL, 0);
+	if (err) {
+		pr_err("%s: %s: UHS2 CMD assembling err = 0x%x!\n",
+			mmc_hostname(host), __func__, err);
+		return -EIO;
+	}
+
+	err = mmc_wait_for_cmd(host, &cmd, 0);
+	if (err) {
+		pr_err("%s: %s: UHS2 CMD send fail, err= 0x%x!\n",
+			mmc_hostname(host), __func__, err);
+		return -EIO;
+	}
+
+#ifdef CONFIG_MMC_DEBUG
+	pr_warn("%s: INQUIRY_CFG PHY response is: ", mmc_hostname(host));
+	for (i = 0; i < 2; i++)
+		pr_warn("0x%x ", cmd.resp[i]);
+	pr_warn("\n");
+#endif
+
+	cap = cmd.resp[0];
+	DBG("Device PHY Caps (0-31) is: 0x%x.\n", cap);
+	host->uhs2_dev_prop.phy_minor_rev = cap &
+					UHS2_DEV_CONFIG_PHY_MINOR_MASK;
+	host->uhs2_dev_prop.phy_major_rev = (cap >>
+					UHS2_DEV_CONFIG_PHY_MAJOR_POS) &
+					UHS2_DEV_CONFIG_PHY_MAJOR_MASK;
+	host->uhs2_dev_prop.can_hibernate = (cap >>
+					UHS2_DEV_CONFIG_CAN_HIBER_POS) &
+					UHS2_DEV_CONFIG_CAN_HIBER_MASK;
+
+	cap = cmd.resp[1];
+	DBG("Device PHY Caps (32-63) is: 0x%x.\n", cap);
+	host->uhs2_dev_prop.n_lss_sync = cap & UHS2_DEV_CONFIG_N_LSS_SYN_MASK;
+	host->uhs2_dev_prop.n_lss_dir = (cap >>
+					UHS2_DEV_CONFIG_N_LSS_DIR_POS) &
+					UHS2_DEV_CONFIG_N_LSS_DIR_MASK;
+	if (host->uhs2_dev_prop.n_lss_sync == 0)
+		host->uhs2_dev_prop.n_lss_sync = 16 << 2;
+	else
+		host->uhs2_dev_prop.n_lss_sync <<= 2;
+
+	if (host->uhs2_dev_prop.n_lss_dir == 0)
+		host->uhs2_dev_prop.n_lss_dir = 16 << 3;
+	else
+		host->uhs2_dev_prop.n_lss_dir <<= 3;
+
+	DBG("INQUIRY_CFG: read LINK-TRAN Caps.\n");
+	arg = ((UHS2_DEV_CONFIG_LINK_TRAN_CAPS & 0xFF) << 8) |
+		UHS2_NATIVE_CMD_READ |
+		UHS2_NATIVE_CMD_PLEN_8B |
+		(UHS2_DEV_CONFIG_LINK_TRAN_CAPS >> 8);
+
+	DBG("Begin INQUIRY_CFG, header=0x%x, arg=0x%x.\n",
+		header, arg);
+	err = uhs2_cmd_assemble(&cmd, header, arg, NULL, 0,
+				NULL, 0);
+	if (err) {
+		pr_err("%s: %s: UHS2 CMD assembling err = 0x%x!\n",
+			mmc_hostname(host), __func__, err);
+		return -EIO;
+	}
+
+	err = mmc_wait_for_cmd(host, &cmd, 0);
+	if (err) {
+		pr_err("%s: %s: UHS2 CMD send fail, err= 0x%x!\n",
+			mmc_hostname(host), __func__, err);
+		return -EIO;
+	}
+
+#ifdef CONFIG_MMC_DEBUG
+	pr_warn("%s: INQUIRY_CFG Link-Tran response is: ", mmc_hostname(host));
+	for (i = 0; i < 2; i++)
+		pr_warn("0x%x ", cmd.resp[i]);
+	pr_warn("\n");
+#endif
+
+	cap = cmd.resp[0];
+	DBG("Device LINK-TRAN Caps (0-31) is: 0x%x.\n", cap);
+	host->uhs2_dev_prop.link_minor_rev = cap &
+					UHS2_DEV_CONFIG_LT_MINOR_MASK;
+	host->uhs2_dev_prop.link_major_rev = (cap >>
+					UHS2_DEV_CONFIG_LT_MAJOR_POS) &
+					UHS2_DEV_CONFIG_LT_MAJOR_MASK;
+	host->uhs2_dev_prop.n_fcu = (cap >> UHS2_DEV_CONFIG_N_FCU_POS) &
+					UHS2_DEV_CONFIG_N_FCU_MASK;
+	host->uhs2_dev_prop.dev_type = (cap >> UHS2_DEV_CONFIG_DEV_TYPE_POS) &
+					UHS2_DEV_CONFIG_DEV_TYPE_MASK;
+	host->uhs2_dev_prop.maxblk_len = (cap >>
+					UHS2_DEV_CONFIG_MAX_BLK_LEN_POS) &
+					UHS2_DEV_CONFIG_MAX_BLK_LEN_MASK;
+
+	cap = cmd.resp[1];
+	DBG("Device LINK-TRAN Caps (32-63) is: 0x%x.\n", cap);
+	host->uhs2_dev_prop.n_data_gap = cap & UHS2_DEV_CONFIG_N_DATA_GAP_MASK;
+	if (host->uhs2_dev_prop.n_fcu == 0)
+		host->uhs2_dev_prop.n_fcu = 256;
+
+	return 0;
+}
+
+static int uhs2_config_write(struct mmc_host *host)
+{
+	struct mmc_command cmd = {0};
+	u16 header = 0, arg = 0;
+	u32 *payload;
+	u8 plen = 1;
+	int err;
+	u8 resp[5] = {0};
+	u8 resp_len = 5;
+
+	BUG_ON(!host->ops->uhs2_set_reg);
+
+	DBG("SET_COMMON_CFG: write Generic Settings.\n");
+	header = UHS2_NATIVE_PACKET | UHS2_PACKET_TYPE_CCMD;
+	arg = ((UHS2_DEV_CONFIG_GEN_SET & 0xFF) << 8) |
+		UHS2_NATIVE_CMD_WRITE |
+		UHS2_NATIVE_CMD_PLEN_4B |
+		(UHS2_DEV_CONFIG_GEN_SET >> 8);
+
+	if (host->uhs2_dev_prop.n_lanes == UHS2_DEV_CONFIG_2L_HD_FD &&
+	    host->uhs2_caps.n_lanes == UHS2_DEV_CONFIG_2L_HD_FD) {
+		/* Support HD */
+		DBG("Both Host and device support 2L-HD.\n");
+		host->flags |= MMC_UHS2_2L_HD;
+		host->uhs2_caps.n_lanes_set = UHS2_DEV_CONFIG_GEN_SET_2L_FD_HD;
+		host->uhs2_dev_prop.n_lanes_set =
+				UHS2_DEV_CONFIG_GEN_SET_2L_FD_HD;
+	} else {
+		/* Only support 2L-FD so far */
+		host->flags &= ~MMC_UHS2_2L_HD;
+		host->uhs2_caps.n_lanes_set = UHS2_DEV_CONFIG_GEN_SET_2L_FD_HD;
+		host->uhs2_dev_prop.n_lanes_set =
+				UHS2_DEV_CONFIG_GEN_SET_2L_FD_HD;
+	}
+	payload = kcalloc(plen, sizeof(u32), GFP_KERNEL);
+	payload[0] = host->uhs2_dev_prop.n_lanes_set <<
+			UHS2_DEV_CONFIG_N_LANES_POS;
+	DBG("Begin SET_COMMON_CFG, header=0x%x, arg=0x%x, payload=0x%x.\n",
+		header, arg, payload[0]);
+	/* There is no payload because per spec, there should be
+	 * no payload field for read CCMD.
+	 * Plen is set in arg. Per spec, plen for read CCMD
+	 * represents the len of read data which is assigned in payload
+	 * of following RES (p136).
+	 */
+	err = uhs2_cmd_assemble(&cmd, header, arg, payload, plen,
+				NULL, 0);
+	if (err) {
+		pr_err("%s: %s: UHS2 CMD assembling err = 0x%x!\n",
+			mmc_hostname(host), __func__, err);
+		return -EIO;
+	}
+
+	err = mmc_wait_for_cmd(host, &cmd, 0);
+	if (err) {
+		pr_err("%s: %s: UHS2 CMD send fail, err= 0x%x!\n",
+			mmc_hostname(host), __func__, err);
+		return -EIO;
+	}
+
+	DBG("SET_COMMON_CFG: PHY Settings.\n");
+	arg = ((UHS2_DEV_CONFIG_PHY_SET & 0xFF) << 8) |
+		UHS2_NATIVE_CMD_READ |
+		UHS2_NATIVE_CMD_PLEN_8B |
+		(UHS2_DEV_CONFIG_PHY_SET >> 8);
+
+	plen = 2;
+	payload = kcalloc(plen, sizeof(u32), GFP_KERNEL);
+
+	if (host->uhs2_caps.speed_range ==
+		UHS2_DEV_CONFIG_PHY_SET_SPEED_B) {
+		host->flags |= MMC_UHS2_SPEED_B;
+		host->uhs2_dev_prop.speed_range_set =
+			UHS2_DEV_CONFIG_PHY_SET_SPEED_B;
+	} else {
+		host->uhs2_dev_prop.speed_range_set =
+			UHS2_DEV_CONFIG_PHY_SET_SPEED_A;
+		host->flags &= ~MMC_UHS2_SPEED_B;
+	}
+	payload[0] = host->uhs2_dev_prop.speed_range_set <<
+			UHS2_DEV_CONFIG_PHY_SET_SPEED_POS;
+
+	host->uhs2_dev_prop.n_lss_sync_set =
+		(min(host->uhs2_dev_prop.n_lss_sync,
+		host->uhs2_caps.n_lss_sync) >> 2) &
+		UHS2_DEV_CONFIG_N_LSS_SYN_MASK;
+	host->uhs2_caps.n_lss_sync_set = host->uhs2_dev_prop.n_lss_sync_set;
+
+	host->uhs2_dev_prop.n_lss_dir_set =
+		(min(host->uhs2_dev_prop.n_lss_dir,
+		host->uhs2_caps.n_lss_dir) >> 3) &
+		UHS2_DEV_CONFIG_N_LSS_DIR_MASK;
+	host->uhs2_caps.n_lss_dir_set = host->uhs2_dev_prop.n_lss_dir_set;
+	payload[1] = (host->uhs2_dev_prop.n_lss_dir_set <<
+			UHS2_DEV_CONFIG_N_LSS_DIR_POS) |
+			host->uhs2_dev_prop.n_lss_sync_set;
+
+	DBG("Begin SET_COMMON_CFG, header=0x%x, arg=0x%x, payload[0]=0x%x,"
+		" payload[1] = 0x%x.\n",
+		header, arg, payload[0], payload[1]);
+
+	err = uhs2_cmd_assemble(&cmd, header, arg, payload, plen,
+				NULL, 0);
+	if (err) {
+		pr_err("%s: %s: UHS2 CMD assembling err = 0x%x!\n",
+			mmc_hostname(host), __func__, err);
+		return -EIO;
+	}
+
+	err = mmc_wait_for_cmd(host, &cmd, 0);
+	if (err) {
+		pr_err("%s: %s: UHS2 CMD send fail, err= 0x%x!\n",
+			mmc_hostname(host), __func__, err);
+		return -EIO;
+	}
+
+	DBG("SET_COMMON_CFG: LINK-TRAN Settings.\n");
+	arg = ((UHS2_DEV_CONFIG_LINK_TRAN_SET & 0xFF) << 8) |
+		UHS2_NATIVE_CMD_WRITE |
+		UHS2_NATIVE_CMD_PLEN_8B |
+		(UHS2_DEV_CONFIG_LINK_TRAN_SET >> 8);
+
+	plen = 2;
+	payload = kcalloc(plen, sizeof(u32), GFP_KERNEL);
+
+	if (host->uhs2_dev_prop.app_type == UHS2_DEV_CONFIG_APP_SD_MEM)
+		host->uhs2_dev_prop.maxblk_len_set =
+			UHS2_DEV_CONFIG_LT_SET_MAX_BLK_LEN;
+	else
+		host->uhs2_dev_prop.maxblk_len_set =
+			min(host->uhs2_dev_prop.maxblk_len,
+			host->uhs2_caps.maxblk_len);
+	host->uhs2_caps.maxblk_len_set = host->uhs2_dev_prop.maxblk_len_set;
+
+	host->uhs2_dev_prop.n_fcu_set =
+		min(host->uhs2_dev_prop.n_fcu,
+		host->uhs2_caps.n_fcu);
+	host->uhs2_caps.n_fcu_set = host->uhs2_dev_prop.n_fcu_set;
+
+	host->uhs2_dev_prop.n_data_gap_set =
+		min(host->uhs2_caps.n_data_gap,
+		host->uhs2_dev_prop.n_data_gap);
+	host->uhs2_caps.n_data_gap_set = host->uhs2_dev_prop.n_data_gap_set;
+
+	host->uhs2_caps.max_retry_set = 3;
+	host->uhs2_dev_prop.max_retry_set = host->uhs2_caps.max_retry_set;
+
+	payload[0] = (host->uhs2_dev_prop.maxblk_len_set <<
+			UHS2_DEV_CONFIG_MAX_BLK_LEN_POS) |
+			(host->uhs2_dev_prop.max_retry_set <<
+			UHS2_DEV_CONFIG_LT_SET_MAX_RETRY_POS) |
+			(host->uhs2_dev_prop.n_fcu_set <<
+			UHS2_DEV_CONFIG_N_FCU_POS);
+	payload[1] = host->uhs2_dev_prop.n_data_gap_set;
+
+	DBG("Begin SET_COMMON_CFG, header=0x%x, arg=0x%x, payload[0] = 0x%x,"
+		" payload[1] = 0x%x.\n",
+		header, arg, payload[0], payload[1]);
+	err = uhs2_cmd_assemble(&cmd, header, arg, payload, plen,
+				NULL, 0);
+	if (err) {
+		pr_err("%s: %s: UHS2 CMD assembling err = 0x%x!\n",
+			mmc_hostname(host), __func__, err);
+		return -EIO;
+	}
+
+	err = mmc_wait_for_cmd(host, &cmd, 0);
+	if (err) {
+		pr_err("%s: %s: UHS2 CMD send fail, err= 0x%x!\n",
+			mmc_hostname(host), __func__, err);
+		return -EIO;
+	}
+
+	DBG("SET_COMMON_CFG: Set Config Completion.\n");
+	arg = (((UHS2_DEV_CONFIG_GEN_SET + 1) & 0xFF) << 8) |
+		UHS2_NATIVE_CMD_WRITE |
+		UHS2_NATIVE_CMD_PLEN_4B |
+		((UHS2_DEV_CONFIG_GEN_SET + 1) >> 8);
+
+	plen = 1;
+	payload = kcalloc(plen, sizeof(u32), GFP_KERNEL);
+	payload[0] = UHS2_DEV_CONFIG_GEN_SET_CFG_COMPLETE;
+
+	DBG("Begin SET_COMMON_CFG, header=0x%x, arg=0x%x, payload[0] = 0x%x.\n",
+		header, arg, payload[0]);
+	err = uhs2_cmd_assemble(&cmd, header, arg, payload, plen,
+				resp, resp_len);
+	if (err) {
+		pr_err("%s: %s: UHS2 CMD assembling err = 0x%x!\n",
+			mmc_hostname(host), __func__, err);
+		return -EIO;
+	}
+
+	err = mmc_wait_for_cmd(host, &cmd, 0);
+	if (err) {
+		pr_err("%s: %s: UHS2 CMD send fail, err= 0x%x!\n",
+			mmc_hostname(host), __func__, err);
+		return -EIO;
+	}
+
+	if ((resp[4] & 0x80) != 0x80) {
+		pr_err("%s: %s: Config Complete is not set!\n",
+			mmc_hostname(host), __func__);
+		return -EIO;
+	}
+
+	/* Set host Config Setting registers */
+	if (host->ops->uhs2_set_reg(host, SET_CONFIG)) {
+		pr_err("%s: %s: UHS2 SET_CONFIG fail!\n",
+			mmc_hostname(host), __func__);
+		return -EIO;
+	}
+
+	return 0;
+}
+
+static int uhs2_go_dormant(struct mmc_host *host, bool hibernate)
+{
+	struct mmc_command cmd = {0};
+	u16 header = 0, arg = 0;
+	u32 *payload;
+	u8 plen = 1;
+	int err;
+
+	BUG_ON(!host->ops->uhs2_set_reg);
+
+	/* Disable Normal INT */
+	if (host->ops->uhs2_set_reg(host, DISABLE_INT)) {
+		pr_err("%s: %s: UHS2 DISABLE_INT fail!\n",
+			mmc_hostname(host), __func__);
+		return -EIO;
+	}
+
+	/* TODO: shall I use host->uhs2_dev_prop.node_id here? */
+	header = UHS2_NATIVE_PACKET | UHS2_PACKET_TYPE_CCMD |
+		host->uhs2_dev_prop.node_id;
+
+	arg = ((UHS2_DEV_CMD_GO_DORMANT_STATE & 0xFF) << 8) |
+		UHS2_NATIVE_CMD_WRITE |
+		UHS2_NATIVE_CMD_PLEN_4B |
+		(UHS2_DEV_CMD_GO_DORMANT_STATE >> 8);
+
+	payload = kcalloc(plen, sizeof(u32), GFP_KERNEL);
+	if (!payload)
+		return -ENOMEM;
+	if (hibernate)
+		payload[0] = UHS2_DEV_CMD_DORMANT_HIBER;
+
+	DBG("Begin GO_DORMANT_STATE, header=0x%x, arg=0x%x, payload=0x%x.\n",
+		header, arg, payload[0]);
+	err = uhs2_cmd_assemble(&cmd, header, arg, payload, plen,
+				NULL, 0);
+	if (err) {
+		pr_err("%s: %s: UHS2 CMD assembling err = 0x%x!\n",
+			mmc_hostname(host), __func__, err);
+		return -EIO;
+	}
+
+	err = mmc_wait_for_cmd(host, &cmd, 0);
+	if (err) {
+		pr_err("%s: %s: UHS2 CMD send fail, err= 0x%x!\n",
+			mmc_hostname(host), __func__, err);
+		return -EIO;
+	}
+
+	/* Check Dormant State in Present */
+	if (host->ops->uhs2_set_reg(host, CHECK_DORMANT)) {
+		pr_err("%s: %s: UHS2 GO_DORMANT_STATE fail!\n",
+			mmc_hostname(host), __func__);
+		return -EIO;
+	}
+
+	host->ios.clock = 0;
+	if (hibernate)
+		host->ios.vdd = -1;
+	mmc_set_ios(host);
+
+	return 0;
+}
+
+static int uhs2_change_speed(struct mmc_host *host)
+{
+	int err;
+
+	BUG_ON(!host->ops->uhs2_detect_init);
+	BUG_ON(!host->ops->uhs2_set_reg);
+
+	err = uhs2_go_dormant(host, false);
+	if (err) {
+		pr_err("%s: %s: UHS2 GO_DORMANT_STATE fail, err= 0x%x!\n",
+			mmc_hostname(host), __func__, err);
+		return -EIO;
+	}
+
+	/* Enable Normal INT */
+	if (host->ops->uhs2_set_reg(host, ENABLE_INT)) {
+		pr_err("%s: %s: UHS2 ENABLE_INT fail!\n",
+			mmc_hostname(host), __func__);
+		return -EIO;
+	}
+
+	/* Change Speed Range */
+	if (host->ops->uhs2_set_reg(host, SET_SPEED_B)) {
+		pr_err("%s: %s: UHS2 SET_SPEED fail!\n",
+			mmc_hostname(host), __func__);
+		return -EIO;
+	}
+
+	/* TODO: if I set clock in sdhci_uhs2_interface_detect(), I should
+	 * remove below codes.
+	 */
+	host->ios.clock = UHS2_RCLK_MAX;
+	mmc_set_ios(host);
+
+	if (host->ops->uhs2_detect_init(host)) {
+		pr_err("%s: %s: uhs2_detect_init() fail!\n",
+			mmc_hostname(host), __func__);
+		return -EIO;
+	}
+
+	DBG("Change to Speed Range B succeeds.\n");
+	return 0;
+}
+
+int mmc_uhs2_try_frequency(struct mmc_host *host, unsigned freq)
+{
+	int err = -EIO;
+
+	BUG_ON(!host->ops->uhs2_detect_init);
+	BUG_ON(!host->ops->uhs2_set_reg);
+
+	host->flags |= MMC_UHS2_SUPPORT;
+	host->f_init = freq;
+
+#ifdef CONFIG_MMC_DEBUG
+	pr_info("%s: %s: trying to init card at %u Hz\n",
+		 mmc_hostname(host), __func__, host->f_init);
+#endif
+
+	uhs2_power_up(host);
+	if (host->ops->uhs2_detect_init(host)) {
+		pr_err("%s: fail to detect UHS2!\n", mmc_hostname(host));
+		err = UHS2_PHY_INIT_ERR;
+		goto init_fail;
+	}
+
+	if (uhs2_dev_init(host)) {
+		pr_err("%s: UHS2 DEVICE_INIT fail!\n", mmc_hostname(host));
+		goto init_fail;
+	}
+
+	if (uhs2_enum(host)) {
+		pr_err("%s: UHS2 ENUMERATE fail!\n", mmc_hostname(host));
+		goto init_fail;
+	}
+
+	if (uhs2_config_read(host)) {
+		pr_err("%s: UHS2 INQUIRY_CONFIG fail!\n", mmc_hostname(host));
+		goto init_fail;
+	}
+
+	if (uhs2_config_write(host)) {
+		pr_err("%s: UHS2 SET_COMMON_CONFIG fail!\n",
+			mmc_hostname(host));
+		goto init_fail;
+	}
+
+	mmc_delay(10);
+
+	/* Change to Speed Range B if it is supported */
+	if (host->flags & MMC_UHS2_SPEED_B)
+		if (uhs2_change_speed(host)) {
+			pr_err("%s: UHS2 uhs2_change_speed() fail!\n",
+				mmc_hostname(host));
+			goto init_fail;
+		}
+
+
+	host->flags |= MMC_UHS2_INITIALIZED;
+
+	mmc_go_idle(host);
+
+	mmc_send_if_cond(host, host->ocr_avail);
+
+	/* On market, only can some SD cards support UHS-II so only call SD
+	 * attach process here.
+	 */
+	if (!mmc_attach_sd(host))
+		return 0;
+
+init_fail:
+	mmc_power_off(host);
+	if (host->flags & MMC_UHS2_INITIALIZED)
+		host->flags &= ~MMC_UHS2_INITIALIZED;
+	host->flags &= ~MMC_UHS2_SUPPORT;
+
+	return err;
+}
+EXPORT_SYMBOL_GPL(mmc_uhs2_try_frequency);
diff --git a/drivers/mmc/core/uhs2.h b/drivers/mmc/core/uhs2.h
new file mode 100644
index 0000000..6f21370
--- /dev/null
+++ b/drivers/mmc/core/uhs2.h
@@ -0,0 +1,26 @@ 
+/*
+ *  driver/mmc/core/uhs2.h - UHS-II driver
+ *
+ * Header file for UHS-II packets, Host Controller registers and I/O
+ * accessors.
+ *
+ *  Copyright (C) 2014 Intel Corp, All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ */
+#ifndef MMC_UHS2_H
+#define MMC_UHS2_H
+
+#include <linux/mmc/core.h>
+#include <linux/mmc/host.h>
+
+#define UHS2_PHY_INIT_ERR	1
+
+extern int uhs2_prepare_sd_cmd(struct mmc_host *host, struct mmc_request *mrq);
+extern void uhs2_power_up(struct mmc_host *host);
+extern int mmc_uhs2_try_frequency(struct mmc_host *host, unsigned freq);
+
+#endif /* MMC_UHS2_H */
diff --git a/include/linux/mmc/core.h b/include/linux/mmc/core.h
index cb2b040..1eba129 100644
--- a/include/linux/mmc/core.h
+++ b/include/linux/mmc/core.h
@@ -10,6 +10,7 @@ 
 
 #include <linux/interrupt.h>
 #include <linux/completion.h>
+#include <linux/mmc/uhs2.h>
 
 struct request;
 struct mmc_data;
@@ -101,6 +102,9 @@  struct mmc_command {
 
 	struct mmc_data		*data;		/* data segment associated with cmd */
 	struct mmc_request	*mrq;		/* associated request */
+	struct uhs2_command	*uhs2_cmd;	/* UHS2 command */
+	u8			*uhs2_resp;	/* UHS2 native cmd resp */
+	u8			uhs2_resp_len;	/* UHS2 native cmd resp len */
 };
 
 struct mmc_data {
@@ -198,6 +202,8 @@  extern int mmc_flush_cache(struct mmc_card *);
 
 extern int mmc_detect_card_removed(struct mmc_host *host);
 
+extern void mmc_set_ios(struct mmc_host *host);
+
 /**
  *	mmc_claim_host - exclusively claim a host
  *	@host: mmc host to claim
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index 9f32270..a79e2aa 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -19,10 +19,12 @@ 
 #include <linux/mmc/core.h>
 #include <linux/mmc/card.h>
 #include <linux/mmc/pm.h>
+#include <linux/mmc/uhs2.h>
 
 struct mmc_ios {
 	unsigned int	clock;			/* clock rate */
 	unsigned short	vdd;
+	unsigned short	vdd2;
 
 /* vdd stores the bit number of the selected voltage range from below. */
 
@@ -63,6 +65,7 @@  struct mmc_ios {
 #define MMC_TIMING_MMC_DDR52	8
 #define MMC_TIMING_MMC_HS200	9
 #define MMC_TIMING_MMC_HS400	10
+#define MMC_TIMING_UHS2		11
 
 	unsigned char	signal_voltage;		/* signalling voltage (1.8V or 3.3V) */
 
@@ -147,6 +150,9 @@  struct mmc_host_ops {
 	 */
 	int	(*multi_io_quirk)(struct mmc_card *card,
 				  unsigned int direction, int blk_size);
+	/* UHS2 interfaces */
+	int	(*uhs2_detect_init)(struct mmc_host *host);
+	int	(*uhs2_set_reg)(struct mmc_host *host, enum uhs2_act act);
 };
 
 struct mmc_card;
@@ -200,6 +206,7 @@  struct regulator;
 
 struct mmc_supply {
 	struct regulator *vmmc;		/* Card power supply */
+	struct regulator *vmmc2;	/* UHS2 VDD2 power supply */
 	struct regulator *vqmmc;	/* Optional Vccq supply */
 };
 
@@ -215,10 +222,12 @@  struct mmc_host {
 	u32			ocr_avail_sdio;	/* SDIO-specific OCR */
 	u32			ocr_avail_sd;	/* SD-specific OCR */
 	u32			ocr_avail_mmc;	/* MMC-specific OCR */
+	u32			ocr_avail_uhs2;	/* UHS2-specific OCR */
 	struct notifier_block	pm_notify;
 	u32			max_current_330;
 	u32			max_current_300;
 	u32			max_current_180;
+	u32			max_current_180_vdd2;
 
 #define MMC_VDD_165_195		0x00000080	/* VDD voltage 1.65 - 1.95 */
 #define MMC_VDD_20_21		0x00000100	/* VDD voltage 2.0 ~ 2.1 */
@@ -237,6 +246,7 @@  struct mmc_host {
 #define MMC_VDD_33_34		0x00200000	/* VDD voltage 3.3 ~ 3.4 */
 #define MMC_VDD_34_35		0x00400000	/* VDD voltage 3.4 ~ 3.5 */
 #define MMC_VDD_35_36		0x00800000	/* VDD voltage 3.5 ~ 3.6 */
+#define MMC_VDD2_165_195	0x00000080	/* VDD2 voltage 1.65 - 1.95 */
 
 	u32			caps;		/* Host capabilities */
 
@@ -266,6 +276,7 @@  struct mmc_host {
 #define MMC_CAP_DRIVER_TYPE_A	(1 << 23)	/* Host supports Driver Type A */
 #define MMC_CAP_DRIVER_TYPE_C	(1 << 24)	/* Host supports Driver Type C */
 #define MMC_CAP_DRIVER_TYPE_D	(1 << 25)	/* Host supports Driver Type D */
+#define MMC_CAP_UHS2		(1 << 26)	/* Host supports UHS2 mode */
 #define MMC_CAP_CMD23		(1 << 30)	/* CMD23 supported. */
 #define MMC_CAP_HW_RESET	(1 << 31)	/* Hardware reset */
 
@@ -294,6 +305,17 @@  struct mmc_host {
 
 	mmc_pm_flag_t		pm_caps;	/* supported pm features */
 
+	struct uhs2_host_caps	uhs2_caps;	/* UHS2 host capabilities */
+	struct uhs2_card_prop	uhs2_dev_prop;	/* UHS2 device properties */
+	u32			group_desc;	/* UHS2 property */
+	int			flags;
+#define MMC_UHS2_SUPPORT	(1 << 0)
+#define MMC_UHS2_INITIALIZED	(1 << 1)
+#define MMC_UHS2_2L_HD		(1 << 2)
+#define MMC_UHS2_APP_CMD	(1 << 3)
+#define MMC_UHS2_SPEED_B	(1 << 4)
+#define MMC_SUPPORT_ADMA3	(1 << 5)
+
 #ifdef CONFIG_MMC_CLKGATE
 	int			clk_requests;	/* internal reference counter */
 	unsigned int		clk_delay;	/* number of MCI clk hold cycles */
@@ -519,4 +541,9 @@  static inline bool mmc_card_hs400(struct mmc_card *card)
 	return card->host->ios.timing == MMC_TIMING_MMC_HS400;
 }
 
+static inline bool mmc_card_uhs2(struct mmc_card *card)
+{
+	return (card->host->flags & MMC_UHS2_SUPPORT) &&
+		(card->host->flags & MMC_UHS2_INITIALIZED);
+}
 #endif /* LINUX_MMC_HOST_H */
diff --git a/include/linux/mmc/uhs2.h b/include/linux/mmc/uhs2.h
new file mode 100644
index 0000000..b0e805e
--- /dev/null
+++ b/include/linux/mmc/uhs2.h
@@ -0,0 +1,274 @@ 
+/*
+ *  linux/drivers/mmc/host/uhs2.h - UHS-II driver
+ *
+ * Header file for UHS-II packets, Host Controller registers and I/O
+ * accessors.
+ *
+ *  Copyright (C) 2014 Intel Corp, All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ */
+#ifndef LINUX_MMC_UHS2_H
+#define LINUX_MMC_UHS2_H
+
+struct mmc_request;
+
+/* LINK Layer definition */
+/* UHS2 Header */
+#define UHS2_NATIVE_PACKET_POS	7
+#define UHS2_NATIVE_PACKET	(1 << UHS2_NATIVE_PACKET_POS)
+
+#define UHS2_PACKET_TYPE_POS	4
+#define UHS2_PACKET_TYPE_CCMD	(0 << UHS2_PACKET_TYPE_POS)
+#define UHS2_PACKET_TYPE_DCMD	(1 << UHS2_PACKET_TYPE_POS)
+#define UHS2_PACKET_TYPE_RES	(2 << UHS2_PACKET_TYPE_POS)
+#define UHS2_PACKET_TYPE_DATA	(3 << UHS2_PACKET_TYPE_POS)
+#define UHS2_PACKET_TYPE_MSG	(7 << UHS2_PACKET_TYPE_POS)
+
+#define UHS2_DEST_ID_MASK	0x0F
+#define UHS2_DEST_ID		0x1
+
+#define UHS2_SRC_ID_POS		12
+#define UHS2_SRC_ID_MASK	0xF000
+
+#define UHS2_TRANS_ID_POS	8
+#define UHS2_TRANS_ID_MASK	0x0700
+
+/* UHS2 MSG */
+#define UHS2_MSG_CTG_POS	5
+#define UHS2_MSG_CTG_LMSG	0x00
+#define UHS2_MSG_CTG_INT	0x60
+#define UHS2_MSG_CTG_AMSG	0x80
+
+#define UHS2_MSG_CTG_FCREQ	0x00
+#define UHS2_MSG_CTG_FCRDY	0x01
+#define UHS2_MSG_CTG_STAT	0x02
+
+#define UHS2_MSG_CODE_POS			8
+#define UHS2_MSG_CODE_FC_UNRECOVER_ERR		0x8
+#define UHS2_MSG_CODE_STAT_UNRECOVER_ERR	0x8
+#define UHS2_MSG_CODE_STAT_RECOVER_ERR		0x1
+
+/* TRANS Layer definition */
+
+/* Native packets*/
+#define UHS2_NATIVE_CMD_RW_POS	7
+#define UHS2_NATIVE_CMD_WRITE	(1 << UHS2_NATIVE_CMD_RW_POS)
+#define UHS2_NATIVE_CMD_READ	(0 << UHS2_NATIVE_CMD_RW_POS)
+
+#define UHS2_NATIVE_CMD_PLEN_POS	4
+#define UHS2_NATIVE_CMD_PLEN_4B		(1 << UHS2_NATIVE_CMD_PLEN_POS)
+#define UHS2_NATIVE_CMD_PLEN_8B		(2 << UHS2_NATIVE_CMD_PLEN_POS)
+#define UHS2_NATIVE_CMD_PLEN_16B	(3 << UHS2_NATIVE_CMD_PLEN_POS)
+
+#define UHS2_NATIVE_CCMD_GET_MIOADR_MASK	0xF00
+#define UHS2_NATIVE_CCMD_MIOADR_MASK		0x0F
+
+#define UHS2_NATIVE_CCMD_LIOADR_POS		8
+#define UHS2_NATIVE_CCMD_GET_LIOADR_MASK	0x0FF
+
+#define UHS2_DCMD_DM_POS	6
+#define UHS2_DCMD_2L_HD_MODE	(1 << UHS2_DCMD_DM_POS)
+#define UHS2_DCMD_LM_POS	5
+#define UHS2_DCMD_LM_TLEN_EXIST	(1 << UHS2_DCMD_LM_POS)
+#define UHS2_DCMD_TLUM_POS	4
+#define UHS2_DCMD_TLUM_BYTE_MODE	(1 << UHS2_DCMD_TLUM_POS)
+#define UHS2_NATIVE_DCMD_DAM_POS	3
+#define UHS2_NATIVE_DCMD_DAM_IO		(1 << UHS2_NATIVE_DCMD_DAM_POS)
+/*
+ * Per UHS2 spec, DCMD payload should be MSB first. There may be
+ * two types of data be assembled to MSB:
+ * 1. TLEN: Input block size for signle read/write and number of blocks
+ * for multiple read/write to calculate TLEN as MSB first per spec.
+ * 2. SD command argument.
+ */
+static inline u32 uhs2_dcmd_convert_msb(u32 input)
+{
+	u32 ret = 0;
+
+	ret = ((input & 0xFF) << 24) |
+		(((input >> 8) & 0xFF) << 16) |
+		(((input >> 16) & 0xFF) << 8) |
+		((input >> 24) & 0xFF);
+	return ret;
+}
+
+#define UHS2_RES_NACK_POS	7
+#define UHS2_RES_NACK_MASK	(0x1 << UHS2_RES_NACK_POS)
+
+#define UHS2_RES_ECODE_POS	4
+#define UHS2_RES_ECODE_MASK	0x7
+#define UHS2_RES_ECODE_COND	1
+#define UHS2_RES_ECODE_ARG	2
+#define UHS2_RES_ECODE_GEN	3
+
+/* IOADR of device registers */
+#define UHS2_IOADR_GENERIC_CAPS		0x00
+#define UHS2_IOADR_PHY_CAPS		0x02
+#define UHS2_IOADR_LINK_CAPS		0x04
+#define UHS2_IOADR_RSV_CAPS		0x06
+#define UHS2_IOADR_GENERIC_SETTINGS	0x08
+#define UHS2_IOADR_PHY_SETTINGS		0x0A
+#define UHS2_IOADR_LINK_SETTINGS	0x0C
+#define UHS2_IOADR_PRESET		0x40
+
+/* SD application packets */
+#define UHS2_SD_CMD_INDEX_POS		8
+
+#define UHS2_SD_CMD_APP_POS		14
+#define UHS2_SD_CMD_APP			(1 << UHS2_SD_CMD_APP_POS)
+
+struct uhs2_command {
+	u16	header;
+	u16	arg;
+	u32	*payload;
+	u32	payload_len;
+	u32	packet_len;
+	u8	*resp;
+	u8	resp_len;
+};
+
+struct uhs2_host_caps {
+	u32	dap;
+	u32	gap;
+	u32	maxblk_len;
+	u32	n_fcu;
+	u8	n_lanes;
+	u8	addr64;
+	u8	card_type;
+	u8	phy_rev;
+	u8	speed_range;
+	u8	can_hibernate;
+	u8	n_lss_sync;
+	u8	n_lss_dir;
+	u8	link_rev;
+	u8	host_type;
+	u8	n_data_gap;
+
+	u32	maxblk_len_set;
+	u32	n_fcu_set;
+	u8	n_lanes_set;
+	u8	n_lss_sync_set;
+	u8	n_lss_dir_set;
+	u8	n_data_gap_set;
+	u8	max_retry_set;
+};
+
+struct uhs2_card_prop {
+	u32	node_id;
+	u32	dap;
+	u32	gap;
+	u32	n_fcu;
+	u32	maxblk_len;
+	u8	n_lanes;
+	u8	dadr_len;
+	u8	app_type;
+	u8	phy_minor_rev;
+	u8	phy_major_rev;
+	u8	can_hibernate;
+	u8	n_lss_sync;
+	u8	n_lss_dir;
+	u8	link_minor_rev;
+	u8	link_major_rev;
+	u8	dev_type;
+	u8	n_data_gap;
+
+	u32	n_fcu_set;
+	u32	maxblk_len_set;
+	u8	n_lanes_set;
+	u8	speed_range_set;
+	u8	n_lss_sync_set;
+	u8	n_lss_dir_set;
+	u8	n_data_gap_set;
+	u8	pwrctrl_mode_set;
+	u8	max_retry_set;
+
+	u8	cfg_complete;
+};
+
+enum uhs2_act {
+	SET_CONFIG,
+	ENABLE_INT,
+	DISABLE_INT,
+	SET_SPEED_B,
+	CHECK_DORMANT,
+};
+
+/* UHS-II Device Registers */
+#define UHS2_DEV_CONFIG_REG	0x000
+
+/* General Caps and Settings registers */
+#define  UHS2_DEV_CONFIG_GEN_CAPS	(UHS2_DEV_CONFIG_REG + 0x000)
+#define   UHS2_DEV_CONFIG_N_LANES_POS	8
+#define   UHS2_DEV_CONFIG_N_LANES_MASK	0x3F
+#define   UHS2_DEV_CONFIG_2L_HD_FD	0x1
+#define   UHS2_DEV_CONFIG_2D1U_FD	0x2
+#define   UHS2_DEV_CONFIG_1D2U_FD	0x4
+#define   UHS2_DEV_CONFIG_2D2U_FD	0x8
+#define   UHS2_DEV_CONFIG_DADR_POS	14
+#define   UHS2_DEV_CONFIG_DADR_MASK	0x1
+#define   UHS2_DEV_CONFIG_APP_POS	16
+#define   UHS2_DEV_CONFIG_APP_MASK	0xFF
+#define   UHS2_DEV_CONFIG_APP_SD_MEM	0x1
+
+#define  UHS2_DEV_CONFIG_GEN_SET	(UHS2_DEV_CONFIG_REG + 0x008)
+#define   UHS2_DEV_CONFIG_GEN_SET_2L_FD_HD	0x0
+#define   UHS2_DEV_CONFIG_GEN_SET_CFG_COMPLETE	(0x1 << 31)
+
+/* PHY Caps and Settings registers */
+#define  UHS2_DEV_CONFIG_PHY_CAPS	(UHS2_DEV_CONFIG_REG + 0x002)
+#define   UHS2_DEV_CONFIG_PHY_MINOR_MASK	0xF
+#define   UHS2_DEV_CONFIG_PHY_MAJOR_POS		4
+#define   UHS2_DEV_CONFIG_PHY_MAJOR_MASK	0x3
+#define   UHS2_DEV_CONFIG_CAN_HIBER_POS		15
+#define   UHS2_DEV_CONFIG_CAN_HIBER_MASK	0x1
+#define  UHS2_DEV_CONFIG_PHY_CAPS1	(UHS2_DEV_CONFIG_REG + 0x003)
+#define   UHS2_DEV_CONFIG_N_LSS_SYN_MASK	0xF
+#define   UHS2_DEV_CONFIG_N_LSS_DIR_POS		4
+#define   UHS2_DEV_CONFIG_N_LSS_DIR_MASK	0xF
+
+#define  UHS2_DEV_CONFIG_PHY_SET	(UHS2_DEV_CONFIG_REG + 0x00A)
+#define   UHS2_DEV_CONFIG_PHY_SET_SPEED_POS	6
+#define   UHS2_DEV_CONFIG_PHY_SET_SPEED_A	0x0
+#define   UHS2_DEV_CONFIG_PHY_SET_SPEED_B	0x1
+
+/* LINK-TRAN Caps and Settins registers */
+#define  UHS2_DEV_CONFIG_LINK_TRAN_CAPS	(UHS2_DEV_CONFIG_REG + 0x004)
+#define   UHS2_DEV_CONFIG_LT_MINOR_MASK		0xF
+#define   UHS2_DEV_CONFIG_LT_MAJOR_POS		4
+#define   UHS2_DEV_CONFIG_LT_MAJOR_MASK		0x3
+#define   UHS2_DEV_CONFIG_N_FCU_POS		8
+#define   UHS2_DEV_CONFIG_N_FCU_MASK		0xFF
+#define   UHS2_DEV_CONFIG_DEV_TYPE_POS		16
+#define   UHS2_DEV_CONFIG_DEV_TYPE_MASK		0x7
+#define   UHS2_DEV_CONFIG_MAX_BLK_LEN_POS	20
+#define   UHS2_DEV_CONFIG_MAX_BLK_LEN_MASK	0xFFF
+#define  UHS2_DEV_CONFIG_LINK_TRAN_CAPS1	(UHS2_DEV_CONFIG_REG + 0x005)
+#define   UHS2_DEV_CONFIG_N_DATA_GAP_MASK	0xFF
+
+#define  UHS2_DEV_CONFIG_LINK_TRAN_SET	(UHS2_DEV_CONFIG_REG + 0x00C)
+#define   UHS2_DEV_CONFIG_LT_SET_MAX_BLK_LEN	0x200
+#define   UHS2_DEV_CONFIG_LT_SET_MAX_RETRY_POS	16
+
+/* Preset register */
+#define  UHS2_DEV_CONFIG_PRESET		(UHS2_DEV_CONFIG_REG + 0x040)
+
+#define UHS2_DEV_INT_REG	0x100
+
+#define UHS2_DEV_STATUS_REG	0x180
+
+#define UHS2_DEV_CMD_REG	0x200
+#define  UHS2_DEV_CMD_FULL_RESET	(UHS2_DEV_CMD_REG + 0x000)
+#define  UHS2_DEV_CMD_GO_DORMANT_STATE	(UHS2_DEV_CMD_REG + 0x001)
+#define   UHS2_DEV_CMD_DORMANT_HIBER	(0x1 << 7)
+#define  UHS2_DEV_CMD_DEVICE_INIT	(UHS2_DEV_CMD_REG + 0x002)
+#define  UHS2_DEV_CMD_ENUMERATE		(UHS2_DEV_CMD_REG + 0x003)
+#define  UHS2_DEV_CMD_TRANS_ABORT	(UHS2_DEV_CMD_REG + 0x004)
+
+#define UHS2_RCLK_MAX	52000000
+#define UHS2_RCLK_MIN	26000000
+
+#endif /* LINUX_MMC_UHS2_H */