From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-3.9 required=3.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_PASS, URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 1FF31C43381 for ; Thu, 21 Feb 2019 09:23:07 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 013F92086A for ; Thu, 21 Feb 2019 09:23:06 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="Hckmh0Ab" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727661AbfBUJXD (ORCPT ); Thu, 21 Feb 2019 04:23:03 -0500 Received: from mail-it1-f193.google.com ([209.85.166.193]:36794 "EHLO mail-it1-f193.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725850AbfBUJXD (ORCPT ); Thu, 21 Feb 2019 04:23:03 -0500 Received: by mail-it1-f193.google.com with SMTP id h6so21812896itl.1; Thu, 21 Feb 2019 01:22:58 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc; bh=HqTMXSU0+50ME/XdfQFomlaDOmGFVR/W80ouDF90qtE=; b=Hckmh0AbghjpUW4er2ciBgQV1IWo5FidqVAZjE4IB/EK0+D/hXOyTQz6OcAOsDnW5p 5EsStCZHX/mL6Fw2sDpSKAjL+HjjZUwVMYY++Ne0jx9zjwlX1iRPHGIzPHwWDxypwkJ3 ZZ4wm3zdoHd7xmu0qLdLYQgANUA8itJjUxTe86jCdhC6FPlByoU72aboV4yXlsxzFBGM bLd22aopjnHigPDOY/FNiBP/sTzSyD5gi1Ovh30JHbTYNBAndd66le2pDjRRb2otNbd3 1b1XoZm1VehnCYQfDsxYiYDd57xiAtZAqECyMsOEyY3i8akO2YaGSBSSTWjlvGjEi0my bZjA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=HqTMXSU0+50ME/XdfQFomlaDOmGFVR/W80ouDF90qtE=; b=NiQhMPV6S37vrjCe2u54/hFP/UwKM+GFzfAQ1iSeQFi5L8JmiXfbhJge8bZZaHgbFA mh05/ugInDBfe/GYoyFrKRlsskumpNBGJV2G1pVt4NvmNOMyZc80Pt7h33Iy2r9HPdvS XfAmDQGXRe+Vu59p2TMT+OXGJWiXSC8CnVdKphc/Rk9cUzOoe9MbB7C18Rh8msOyUS3C Lhs74aZTFQq9EMW4/KI4e69BjLoWzgft0G613s8u1C7U8Ky3ri+IUD2/aczhz8bbHCWs +b2EPc1zDyk9UWVb72/1sjmxDixObtQyUXttMIlODjz9QOX7v9G0BnvdAO2ox+b3kbhG LdLA== X-Gm-Message-State: AHQUAuba2ElJO2qyBnhHQmbjb1dueglGqXFya5qgy51w4ueS13jUlO+k xXGOdZGWQpOyntGyYDeu0ZfEk7fQ6pTeCFZeajE= X-Google-Smtp-Source: AHgI3IanAkQ5wl8kB0Soyd5swo2SN4RGKmGmIEczKFBWjPsr1Q88UUnwHhwnJW7gkU1qYuvBhTk0ofkxfiN5GSgecsU= X-Received: by 2002:a24:cd87:: with SMTP id l129mr2281730itg.86.1550740976094; Thu, 21 Feb 2019 01:22:56 -0800 (PST) MIME-Version: 1.0 References: <1550173514-23573-1-git-send-email-pawell@cadence.com> <1550173514-23573-6-git-send-email-pawell@cadence.com> In-Reply-To: <1550173514-23573-6-git-send-email-pawell@cadence.com> From: Peter Chen Date: Thu, 21 Feb 2019 17:22:42 +0800 Message-ID: Subject: Re: [PATCH v4 5/6] usb:cdns3 Add Cadence USB3 DRD Driver To: Pawel Laszczak Cc: devicetree@vger.kernel.org, Greg Kroah-Hartman , felipe.balbi@linux.intel.com, mark.rutland@arm.com, linux-usb@vger.kernel.org, hdegoede@redhat.com, Heikki Krogerus , andy.shevchenko@gmail.com, robh+dt@kernel.org, rogerq@ti.com, lkml , jbergsagel@ti.com, nsekhar@ti.com, nm@ti.com, sureshp@cadence.com, peter.chen@nxp.com, kurahul@cadence.com Content-Type: text/plain; charset="UTF-8" Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org > +int cdns3_set_mode(struct cdns3 *cdns, enum usb_dr_mode mode) > +{ > + int ret = 0; > + u32 reg; > + > + cdns->current_dr_mode = mode; > + > + switch (mode) { > + case USB_DR_MODE_PERIPHERAL: > + dev_info(cdns->dev, "Set controller to Gadget mode\n"); > + ret = cdns3_drd_switch_gadget(cdns, 1); > + break; > + case USB_DR_MODE_HOST: > + dev_info(cdns->dev, "Set controller to Host mode\n"); > + ret = cdns3_drd_switch_host(cdns, 1); > + break; > + case USB_DR_MODE_OTG: > + dev_info(cdns->dev, "Set controller to OTG mode\n"); > + if (cdns->version == CDNS3_CONTROLLER_V1) { > + reg = readl(&cdns->otg_v1_regs->override); > + reg |= OVERRIDE_IDPULLUP; > + writel(reg, &cdns->otg_v1_regs->override); > + } else { > + reg = readl(&cdns->otg_v0_regs->ctrl1); > + reg |= OVERRIDE_IDPULLUP_V0; > + writel(reg, &cdns->otg_v0_regs->ctrl1); > + } > + > + /* > + * Hardware specification says: "ID_VALUE must be valid within > + * 50ms after idpullup is set to '1" so driver must wait > + * 50ms before reading this pin. > + */ > + usleep_range(50000, 60000); > + break; > + default: > + cdns->current_dr_mode = USB_DR_MODE_UNKNOWN; > + dev_err(cdns->dev, "Unsupported mode of operation %d\n", mode); > + return -EINVAL; > + } > + > + return ret; > +} > + > +int cdns3_get_id(struct cdns3 *cdns) > +{ > + int id; > + > + id = readl(&cdns->otg_regs->sts) & OTGSTS_ID_VALUE; > + dev_dbg(cdns->dev, "OTG ID: %d", id); > + return id; > +} > + > +int cdns3_is_host(struct cdns3 *cdns) > +{ > + if (cdns->current_dr_mode == USB_DR_MODE_HOST) > + return 1; I run out issue if I set dr_mode as host at dts (firmware). We need to return 1 at this case, but the cdns->current_dr_mode is changed to OTG before. If we set peripheral-only or host-only at dts, the above judgement should only reply on dts setting. Below changes work at my platform: diff --git a/drivers/usb/cdns3/drd.c b/drivers/usb/cdns3/drd.c index 3e56338cd7b9..2e3d2d19aaa3 100644 --- a/drivers/usb/cdns3/drd.c +++ b/drivers/usb/cdns3/drd.c @@ -81,7 +81,7 @@ int cdns3_get_id(struct cdns3 *cdns) int cdns3_is_host(struct cdns3 *cdns) { - if (cdns->current_dr_mode == USB_DR_MODE_HOST) + if (usb_get_dr_mode(cdns->dev) == USB_DR_MODE_HOST) return 1; else if (!cdns3_get_id(cdns)) return 1; @@ -91,7 +91,7 @@ int cdns3_is_host(struct cdns3 *cdns) int cdns3_is_device(struct cdns3 *cdns) { - if (cdns->current_dr_mode == USB_DR_MODE_PERIPHERAL) + if (usb_get_dr_mode(cdns->dev) == USB_DR_MODE_PERIPHERAL) return 1; else if (cdns->current_dr_mode == USB_DR_MODE_OTG) if (cdns3_get_id(cdns)) @@ -230,6 +230,8 @@ int cdns3_drd_update_mode(struct cdns3 *cdns) Below is the output I set dr_mode as host: [ 2.743538] cdns-usb3 5b130000.cdns3: DRD version v0 (00000100) [ 2.749476] cdns-usb3 5b130000.cdns3: Controller strapped to HOST [ 2.755638] cdns-usb3 5b130000.cdns3: cdns3_drd_update_mode:1:0:1 [ 2.763764] cdns-usb3 5b130000.cdns3: Set controller to Host mode [ 2.769868] cdns-usb3 5b130000.cdns3: Waiting for Host mode is turned on [ 2.769881] cdns-usb3 5b130000.cdns3: cdns3_drd_update_mode:3:1:3 [ 2.777990] cdns-usb3 5b130000.cdns3: Set controller to OTG mode [ 2.849353] cdns-usb3 5b130000.cdns3: Waiting for Host mode is turned on [ 2.849689] cdns-usb3 5b130000.cdns3: Cadence USB3 core: probe succeed [ 2.849722] nxp-cdns3 5b110000.usb3: Cadence USB3 core: probe succeed >From above log, the cdns3_drd_update_mode is called twice, and the controller switches like INIT_MODE->HOST->OTG->HOST. Your role initialization is a little complicated, please try to simply it.Please try to simply it. Besides, do you really need so many variables for dr_mode? dr_mode is static from firmware, the dynamic status can be described by cdns->role. Below is the output I set dr_mode as peripheral: [ 1.900029] cdns-usb3 5b130000.cdns3: DRD version v0 (00000100) [ 1.905983] cdns-usb3 5b130000.cdns3: Controller strapped to PERIPHERAL [ 1.912669] cdns-usb3 5b130000.cdns3: cdns3_drd_update_mode:2:0:2 [ 1.920803] cdns-usb3 5b130000.cdns3: Set controller to Gadget mode [ 1.927121] cdns-usb3 5b130000.cdns3: Waiting for Device mode is turned on [ 1.927138] cdns-usb3 5b130000.cdns3: cdns3_drd_update_mode:3:2:3 [ 1.935261] cdns-usb3 5b130000.cdns3: Set controller to OTG mode [ 2.001305] cdns-usb3 5b130000.cdns3: OTG ID: 1 [ 2.001312] cdns-usb3 5b130000.cdns3: Waiting for Device mode is turned on [ 2.001321] cdns-usb3 5b130000.cdns3: OTG ID: 1 [ 2.001334] cdns-usb3 5b130000.cdns3: Initializing non-zero endpoints And the output for cdns3_drd_update_mode is: @@ -230,6 +230,8 @@ int cdns3_drd_update_mode(struct cdns3 *cdns) { int ret = 0; + dev_dbg(cdns->dev, "%s:%d:%d:%d \n", __func__, cdns->desired_dr_mode, + cdns->current_dr_mode, cdns->dr_mode); Besides above issue, seems you forget to set OTGSIMULATE.OTG_CFG_FAST_SIMS, The set host will timeout when switch from otg to host. Below code works at my side @@ -314,6 +316,7 @@ int cdns3_drd_init(struct cdns3 *cdns) cdns->version = CDNS3_CONTROLLER_V0; cdns->otg_v1_regs = NULL; cdns->otg_regs = regs; + writel(1, &cdns->otg_v0_regs->simulate); dev_info(cdns->dev, "DRD version v0 (%08x)\n", readl(&cdns->otg_v0_regs->version)); Peter > + else if (!cdns3_get_id(cdns)) > + return 1; > + > + return 0; > +} > + > +int cdns3_is_device(struct cdns3 *cdns) > +{ > + if (cdns->current_dr_mode == USB_DR_MODE_PERIPHERAL) > + return 1; > + else if (cdns->current_dr_mode == USB_DR_MODE_OTG) > + if (cdns3_get_id(cdns)) > + return 1; > + > + return 0; > +} > + > +/** > + * cdns3_otg_disable_irq - Disable all OTG interrupts > + * @cdns: Pointer to controller context structure > + */ > +static void cdns3_otg_disable_irq(struct cdns3 *cdns) > +{ > + writel(0, &cdns->otg_regs->ien); > +} > + > +/** > + * cdns3_otg_enable_irq - enable id and sess_valid interrupts > + * @cdns: Pointer to controller context structure > + */ > +static void cdns3_otg_enable_irq(struct cdns3 *cdns) > +{ > + writel(OTGIEN_ID_CHANGE_INT | OTGIEN_VBUSVALID_RISE_INT | > + OTGIEN_VBUSVALID_FALL_INT, &cdns->otg_regs->ien); > +} > + > +/** > + * cdns3_drd_switch_host - start/stop host > + * @cdns: Pointer to controller context structure > + * @on: 1 for start, 0 for stop > + * > + * Returns 0 on success otherwise negative errno > + */ > +static int cdns3_drd_switch_host(struct cdns3 *cdns, int on) > +{ > + int ret; > + u32 reg = OTGCMD_OTG_DIS; > + > + /* switch OTG core */ > + if (on) { > + writel(OTGCMD_HOST_BUS_REQ | reg, &cdns->otg_regs->cmd); > + > + dev_dbg(cdns->dev, "Waiting for Host mode is turned on\n"); > + ret = cdns3_handshake(&cdns->otg_regs->sts, OTGSTS_XHCI_READY, > + OTGSTS_XHCI_READY, 100000); > + > + if (ret) > + return ret; > + } else { > + usleep_range(30, 40); > + writel(OTGCMD_HOST_BUS_DROP | OTGCMD_DEV_BUS_DROP | > + OTGCMD_DEV_POWER_OFF | OTGCMD_HOST_POWER_OFF, > + &cdns->otg_regs->cmd); > + usleep_range(3000, 4000); > + } > + > + return 0; > +} > + > +/** > + * cdns3_drd_switch_gadget - start/stop gadget > + * @cdns: Pointer to controller context structure > + * @on: 1 for start, 0 for stop > + * > + * Returns 0 on success otherwise negative errno > + */ > +static int cdns3_drd_switch_gadget(struct cdns3 *cdns, int on) > +{ > + int ret; > + u32 reg = OTGCMD_OTG_DIS; > + > + /* switch OTG core */ > + if (on) { > + writel(OTGCMD_DEV_BUS_REQ | reg, &cdns->otg_regs->cmd); > + > + dev_dbg(cdns->dev, "Waiting for Device mode is turned on\n"); > + > + ret = cdns3_handshake(&cdns->otg_regs->sts, OTGSTS_DEV_READY, > + OTGSTS_DEV_READY, 100000); > + > + if (ret) > + return ret; > + } else { > + /* > + * driver should wait at least 10us after disabling Device > + * before turning-off Device (DEV_BUS_DROP) > + */ > + usleep_range(20, 30); > + writel(OTGCMD_HOST_BUS_DROP | OTGCMD_DEV_BUS_DROP | > + OTGCMD_DEV_POWER_OFF | OTGCMD_HOST_POWER_OFF, > + &cdns->otg_regs->cmd); > + usleep_range(3000, 4000); > + } > + > + return 0; > +} > + > +/** > + * cdns3_init_otg_mode - initialize drd controller > + * @cdns: Pointer to controller context structure > + * > + * Returns 0 on success otherwise negative errno > + */ > +static int cdns3_init_otg_mode(struct cdns3 *cdns) > +{ > + int ret = 0; > + > + cdns3_otg_disable_irq(cdns); > + /* clear all interrupts */ > + writel(~0, &cdns->otg_regs->ivect); > + > + ret = cdns3_set_mode(cdns, USB_DR_MODE_OTG); > + if (ret) > + return ret; > + > + if (cdns3_is_host(cdns)) > + ret = cdns3_drd_switch_host(cdns, 1); > + else > + ret = cdns3_drd_switch_gadget(cdns, 1); > + > + if (ret) > + return ret; > + > + cdns3_otg_enable_irq(cdns); > + return ret; > +} > + > +/** > + * cdns3_drd_update_mode - initialize mode of operation > + * @cdns: Pointer to controller context structure > + * > + * Returns 0 on success otherwise negative errno > + */ > +int cdns3_drd_update_mode(struct cdns3 *cdns) > +{ > + int ret = 0; > + > + if (cdns->desired_dr_mode == cdns->current_dr_mode) > + return ret; > + > + cdns3_drd_switch_gadget(cdns, 0); > + cdns3_drd_switch_host(cdns, 0); > + > + switch (cdns->desired_dr_mode) { > + case USB_DR_MODE_PERIPHERAL: > + ret = cdns3_set_mode(cdns, USB_DR_MODE_PERIPHERAL); > + break; > + case USB_DR_MODE_HOST: > + ret = cdns3_set_mode(cdns, USB_DR_MODE_HOST); > + break; > + case USB_DR_MODE_OTG: > + ret = cdns3_init_otg_mode(cdns); > + break; > + default: > + dev_err(cdns->dev, "Unsupported mode of operation %d\n", > + cdns->dr_mode); > + return -EINVAL; > + } > + > + return ret; > +} > + > +/** > + * cdns3_drd_irq - interrupt handler for OTG events > + * > + * @irq: irq number for cdns3 core device > + * @data: structure of cdns3 > + * > + * Returns IRQ_HANDLED or IRQ_NONE > + */ > +static irqreturn_t cdns3_drd_irq(int irq, void *data) > +{ > + irqreturn_t ret = IRQ_NONE; > + struct cdns3 *cdns = data; > + u32 reg; > + > + if (cdns->dr_mode != USB_DR_MODE_OTG) > + return ret; > + > + reg = readl(&cdns->otg_regs->ivect); > + > + if (!reg) > + return ret; > + > + if (reg & OTGIEN_ID_CHANGE_INT) { > + dev_dbg(cdns->dev, "OTG IRQ: new ID: %d\n", > + cdns3_get_id(cdns)); > + > + queue_work(system_freezable_wq, &cdns->role_switch_wq); > + > + ret = IRQ_HANDLED; > + } > + > + writel(~0, &cdns->otg_regs->ivect); > + return ret; > +} > + > +int cdns3_drd_init(struct cdns3 *cdns) > +{ > + void __iomem *regs; > + int ret = 0; > + u32 state; > + > + regs = devm_ioremap_resource(cdns->dev, &cdns->otg_res); > + if (IS_ERR(regs)) > + return PTR_ERR(regs); > + > + /* Detection of DRD version. Controller has been released > + * in two versions. Both are similar, but they have same changes > + * in register maps. > + * The first register in old version is command register and it's read > + * only, so driver should read 0 from it. On the other hand, in v1 > + * the first register contains device ID number which is not set to 0. > + * Driver uses this fact to detect the proper version of > + * controller. > + */ > + cdns->otg_v0_regs = regs; > + if (!readl(&cdns->otg_v0_regs->cmd)) { > + cdns->version = CDNS3_CONTROLLER_V0; > + cdns->otg_v1_regs = NULL; > + cdns->otg_regs = regs; > + dev_info(cdns->dev, "DRD version v0 (%08x)\n", > + readl(&cdns->otg_v0_regs->version)); > + } else { > + cdns->otg_v0_regs = NULL; > + cdns->otg_v1_regs = regs; > + cdns->otg_regs = (void *)&cdns->otg_v1_regs->cmd; > + cdns->version = CDNS3_CONTROLLER_V1; > + dev_info(cdns->dev, "DRD version v1 (ID: %08x, rev: %08x)\n", > + readl(&cdns->otg_v1_regs->did), > + readl(&cdns->otg_v1_regs->rid)); > + } > + > + state = OTGSTS_STRAP(readl(&cdns->otg_regs->sts)); > + > + /* Update dr_mode according to STRAP configuration. */ > + cdns->dr_mode = USB_DR_MODE_OTG; > + if (state == OTGSTS_STRAP_HOST) { > + dev_info(cdns->dev, "Controller strapped to HOST\n"); > + cdns->dr_mode = USB_DR_MODE_HOST; > + } else if (state == OTGSTS_STRAP_GADGET) { > + dev_info(cdns->dev, "Controller strapped to PERIPHERAL\n"); > + cdns->dr_mode = USB_DR_MODE_PERIPHERAL; > + } > + > + cdns->desired_dr_mode = cdns->dr_mode; > + cdns->current_dr_mode = USB_DR_MODE_UNKNOWN; > + > + ret = devm_request_threaded_irq(cdns->dev, cdns->irq, cdns3_drd_irq, > + NULL, IRQF_SHARED, > + dev_name(cdns->dev), cdns); > + > + if (ret) > + return ret; > + > + state = readl(&cdns->otg_regs->sts); > + if (OTGSTS_OTG_NRDY(state) != 0) { > + dev_err(cdns->dev, "Cadence USB3 OTG device not ready\n"); > + return -ENODEV; > + } > + > + ret = cdns3_drd_update_mode(cdns); > + > + return ret; > +} > + > +int cdns3_drd_exit(struct cdns3 *cdns) > +{ > + return cdns3_drd_switch_host(cdns, 0); > +} > diff --git a/drivers/usb/cdns3/drd.h b/drivers/usb/cdns3/drd.h > new file mode 100644 > index 000000000000..6a29cdcb492d > --- /dev/null > +++ b/drivers/usb/cdns3/drd.h > @@ -0,0 +1,162 @@ > +/* SPDX-License-Identifier: GPL-2.0 */ > +/* > + * Cadence USB3 DRD header file. > + * > + * Copyright (C) 2018 Cadence. > + * > + * Author: Pawel Laszczak > + */ > +#ifndef __LINUX_CDNS3_DRD > +#define __LINUX_CDNS3_DRD > + > +#include > +#include > +#include "core.h" > + > +/* DRD register interface for version v1. */ > +struct cdns3_otg_regs { > + __le32 did; > + __le32 rid; > + __le32 capabilities; > + __le32 reserved1; > + __le32 cmd; > + __le32 sts; > + __le32 state; > + __le32 reserved2; > + __le32 ien; > + __le32 ivect; > + __le32 refclk; > + __le32 tmr; > + __le32 reserved3[4]; > + __le32 simulate; > + __le32 override; > + __le32 susp_ctrl; > + __le32 reserved4; > + __le32 anasts; > + __le32 adp_ramp_time; > + __le32 ctrl1; > + __le32 ctrl2; > +}; > + > +/* DRD register interface for version v0. */ > +struct cdns3_otg_legacy_regs { > + __le32 cmd; > + __le32 sts; > + __le32 state; > + __le32 refclk; > + __le32 ien; > + __le32 ivect; > + __le32 reserved1[3]; > + __le32 tmr; > + __le32 reserved2[2]; > + __le32 version; > + __le32 capabilities; > + __le32 reserved3[2]; > + __le32 simulate; > + __le32 reserved4[5]; > + __le32 ctrl1; > +}; > + > +/* > + * Common registers interface for both version of DRD. > + */ > +struct cdns3_otg_common_regs { > + __le32 cmd; > + __le32 sts; > + __le32 state; > + __le32 different1; > + __le32 ien; > + __le32 ivect; > +}; > + > +/* CDNS_RID - bitmasks */ > +#define CDNS_RID(p) ((p) & GENMASK(15, 0)) > + > +/* CDNS_VID - bitmasks */ > +#define CDNS_DID(p) ((p) & GENMASK(31, 0)) > + > +/* OTGCMD - bitmasks */ > +/* "Request the bus for Device mode. */ > +#define OTGCMD_DEV_BUS_REQ BIT(0) > +/* Request the bus for Host mode */ > +#define OTGCMD_HOST_BUS_REQ BIT(1) > +/* Enable OTG mode. */ > +#define OTGCMD_OTG_EN BIT(2) > +/* Disable OTG mode */ > +#define OTGCMD_OTG_DIS BIT(3) > +/*"Configure OTG as A-Device. */ > +#define OTGCMD_A_DEV_EN BIT(4) > +/*"Configure OTG as A-Device. */ > +#define OTGCMD_A_DEV_DIS BIT(5) > +/* Drop the bus for Device mod e. */ > +#define OTGCMD_DEV_BUS_DROP BIT(8) > +/* Drop the bus for Host mode*/ > +#define OTGCMD_HOST_BUS_DROP BIT(9) > +/* Power Down USBSS-DEV. */ > +#define OTGCMD_DEV_POWER_OFF BIT(11) > +/* Power Down CDNSXHCI. */ > +#define OTGCMD_HOST_POWER_OFF BIT(12) > + > +/* OTGIEN - bitmasks */ > +/* ID change interrupt enable */ > +#define OTGIEN_ID_CHANGE_INT BIT(0) > +/* Vbusvalid fall detected interrupt enable.*/ > +#define OTGIEN_VBUSVALID_RISE_INT BIT(4) > +/* Vbusvalid fall detected interrupt enable */ > +#define OTGIEN_VBUSVALID_FALL_INT BIT(5) > + > +/* OTGSTS - bitmasks */ > +/* > + * Current value of the ID pin. It is only valid when idpullup in > + * OTGCTRL1_TYPE register is set to '1'. > + */ > +#define OTGSTS_ID_VALUE BIT(0) > +/* Current value of the vbus_valid */ > +#define OTGSTS_VBUS_VALID BIT(1) > +/* Current value of the b_sess_vld */ > +#define OTGSTS_SESSION_VALID BIT(2) > +/*Device mode is active*/ > +#define OTGSTS_DEV_ACTIVE BIT(3) > +/* Host mode is active. */ > +#define OTGSTS_HOST_ACTIVE BIT(4) > +/* OTG Controller not ready. */ > +#define OTGSTS_OTG_NRDY_MASK BIT(11) > +#define OTGSTS_OTG_NRDY(p) ((p) & OTGSTS_OTG_NRDY_MASK) > +/* > + * Value of the strap pins. > + * 000 - no default configuration > + * 010 - Controller initiall configured as Host > + * 100 - Controller initially configured as Device > + */ > +#define OTGSTS_STRAP(p) (((p) & GENMASK(14, 12)) >> 12) > +#define OTGSTS_STRAP_NO_DEFAULT_CFG 0x00 > +#define OTGSTS_STRAP_HOST_OTG 0x01 > +#define OTGSTS_STRAP_HOST 0x02 > +#define OTGSTS_STRAP_GADGET 0x04 > +/* Host mode is turned on. */ > +#define OTGSTS_XHCI_READY BIT(26) > +/* "Device mode is turned on .*/ > +#define OTGSTS_DEV_READY BIT(27) > + > +/* OTGSTATE- bitmasks */ > +#define OTGSTATE_HOST_STATE_MASK GENMASK(5, 3) > +#define OTGSTATE_HOST_STATE_IDLE 0x0 > +#define OTGSTATE_HOST_STATE_VBUS_FALL 0x7 > +#define OTGSTATE_HOST_STATE(p) (((p) & OTGSTATE_HOST_STATE_MASK) >> 3) > + > +/* OTGREFCLK - bitmasks */ > +#define OTGREFCLK_STB_CLK_SWITCH_EN BIT(31) > + > +/* OVERRIDE - bitmasks */ > +#define OVERRIDE_IDPULLUP BIT(0) > +/* Only for CDNS3_CONTROLLER_V0 version */ > +#define OVERRIDE_IDPULLUP_V0 BIT(24) > + > +int cdns3_is_host(struct cdns3 *cdns); > +int cdns3_is_device(struct cdns3 *cdns); > +int cdns3_get_id(struct cdns3 *cdns); > +int cdns3_drd_init(struct cdns3 *cdns); > +int cdns3_drd_exit(struct cdns3 *cdns); > +int cdns3_drd_update_mode(struct cdns3 *cdns); > + > +#endif /* __LINUX_CDNS3_DRD */ > diff --git a/drivers/usb/cdns3/ep0.c b/drivers/usb/cdns3/ep0.c > new file mode 100644 > index 000000000000..2878982be1ec > --- /dev/null > +++ b/drivers/usb/cdns3/ep0.c > @@ -0,0 +1,907 @@ > +// SPDX-License-Identifier: GPL-2.0 > +/* > + * Cadence USBSS DRD Driver - gadget side. > + * > + * Copyright (C) 2018 Cadence Design Systems. > + * Copyright (C) 2017-2018 NXP > + * > + * Authors: Pawel Jez , > + * Pawel Laszczak > + * Peter Chen > + */ > + > +#include > + > +#include "gadget.h" > +#include "trace.h" > + > +static struct usb_endpoint_descriptor cdns3_gadget_ep0_desc = { > + .bLength = USB_DT_ENDPOINT_SIZE, > + .bDescriptorType = USB_DT_ENDPOINT, > + .bmAttributes = USB_ENDPOINT_XFER_CONTROL, > +}; > + > +/** > + * cdns3_ep0_run_transfer - Do transfer on default endpoint hardware > + * @priv_dev: extended gadget object > + * @dma_addr: physical address where data is/will be stored > + * @length: data length > + * @erdy: set it to 1 when ERDY packet should be sent - > + * exit from flow control state > + */ > +static void cdns3_ep0_run_transfer(struct cdns3_device *priv_dev, > + dma_addr_t dma_addr, > + unsigned int length, int erdy) > +{ > + struct cdns3_usb_regs __iomem *regs = priv_dev->regs; > + struct cdns3_endpoint *priv_ep = priv_dev->eps[0]; > + > + priv_ep->trb_pool->buffer = TRB_BUFFER(dma_addr); > + priv_ep->trb_pool->length = TRB_LEN(length); > + priv_ep->trb_pool->control = TRB_CYCLE | TRB_IOC | TRB_TYPE(TRB_NORMAL); > + > + trace_cdns3_prepare_trb(priv_ep, priv_ep->trb_pool); > + > + cdns3_select_ep(priv_dev, priv_dev->ep0_data_dir); > + > + writel(EP_STS_TRBERR, ®s->ep_sts); > + writel(EP_TRADDR_TRADDR(priv_ep->trb_pool_dma), ®s->ep_traddr); > + trace_cdns3_doorbell_ep0(priv_dev->ep0_data_dir ? "ep0in" : "ep0out", > + readl(®s->ep_traddr)); > + > + /* TRB should be prepared before starting transfer */ > + writel(EP_CMD_DRDY, ®s->ep_cmd); > + > + if (erdy) > + writel(EP_CMD_ERDY, &priv_dev->regs->ep_cmd); > +} > + > +/** > + * cdns3_ep0_delegate_req - Returns status of handling setup packet > + * Setup is handled by gadget driver > + * @priv_dev: extended gadget object > + * @ctrl_req: pointer to received setup packet > + * > + * Returns zero on success or negative value on failure > + */ > +static int cdns3_ep0_delegate_req(struct cdns3_device *priv_dev, > + struct usb_ctrlrequest *ctrl_req) > +{ > + int ret; > + > + spin_unlock(&priv_dev->lock); > + priv_dev->setup_pending = 1; > + ret = priv_dev->gadget_driver->setup(&priv_dev->gadget, ctrl_req); > + priv_dev->setup_pending = 0; > + spin_lock(&priv_dev->lock); > + return ret; > +} > + > +static void cdns3_prepare_setup_packet(struct cdns3_device *priv_dev) > +{ > + priv_dev->ep0_data_dir = 0; > + priv_dev->ep0_stage = CDNS3_SETUP_STAGE; > + cdns3_ep0_run_transfer(priv_dev, priv_dev->setup_dma, > + sizeof(struct usb_ctrlrequest), 0); > +} > + > +static void cdns3_ep0_complete_setup(struct cdns3_device *priv_dev, > + u8 send_stall, u8 send_erdy) > +{ > + struct cdns3_endpoint *priv_ep = priv_dev->eps[0]; > + struct usb_request *request; > + > + request = cdns3_next_request(&priv_ep->pending_req_list); > + if (request) > + list_del_init(&request->list); > + > + if (send_stall) { > + cdns3_dbg(priv_ep->cdns3_dev, "STALL for ep0\n"); > + /* set_stall on ep0 */ > + cdns3_select_ep(priv_dev, 0x00); > + writel(EP_CMD_SSTALL, &priv_dev->regs->ep_cmd); > + } else { > + cdns3_prepare_setup_packet(priv_dev); > + } > + > + priv_dev->ep0_stage = CDNS3_SETUP_STAGE; > + writel((send_erdy ? EP_CMD_ERDY : 0) | EP_CMD_REQ_CMPL, > + &priv_dev->regs->ep_cmd); > +} > + > +/** > + * cdns3_req_ep0_set_configuration - Handling of SET_CONFIG standard USB request > + * @priv_dev: extended gadget object > + * @ctrl_req: pointer to received setup packet > + * > + * Returns 0 if success, USB_GADGET_DELAYED_STATUS on deferred status stage, > + * error code on error > + */ > +static int cdns3_req_ep0_set_configuration(struct cdns3_device *priv_dev, > + struct usb_ctrlrequest *ctrl_req) > +{ > + enum usb_device_state device_state = priv_dev->gadget.state; > + struct cdns3_endpoint *priv_ep; > + u32 config = le16_to_cpu(ctrl_req->wValue); > + int result = 0; > + int i; > + > + switch (device_state) { > + case USB_STATE_ADDRESS: > + /* Configure non-control EPs */ > + for (i = 0; i < CDNS3_ENDPOINTS_MAX_COUNT; i++) { > + priv_ep = priv_dev->eps[i]; > + if (!priv_ep) > + continue; > + > + if (priv_ep->flags & EP_CLAIMED) > + cdns3_ep_config(priv_ep); > + } > + > + result = cdns3_ep0_delegate_req(priv_dev, ctrl_req); > + > + if (result) > + return result; > + > + if (config) { > + cdns3_set_hw_configuration(priv_dev); > + } else { > + cdns3_hw_reset_eps_config(priv_dev); > + usb_gadget_set_state(&priv_dev->gadget, > + USB_STATE_ADDRESS); > + } > + break; > + case USB_STATE_CONFIGURED: > + result = cdns3_ep0_delegate_req(priv_dev, ctrl_req); > + > + if (!config && !result) { > + cdns3_hw_reset_eps_config(priv_dev); > + usb_gadget_set_state(&priv_dev->gadget, > + USB_STATE_ADDRESS); > + } > + break; > + default: > + result = -EINVAL; > + } > + > + return result; > +} > + > +/** > + * cdns3_req_ep0_set_address - Handling of SET_ADDRESS standard USB request > + * @priv_dev: extended gadget object > + * @ctrl_req: pointer to received setup packet > + * > + * Returns 0 if success, error code on error > + */ > +static int cdns3_req_ep0_set_address(struct cdns3_device *priv_dev, > + struct usb_ctrlrequest *ctrl_req) > +{ > + enum usb_device_state device_state = priv_dev->gadget.state; > + u32 reg; > + u32 addr; > + > + addr = le16_to_cpu(ctrl_req->wValue); > + > + if (addr > USB_DEVICE_MAX_ADDRESS) { > + dev_err(priv_dev->dev, > + "Device address (%d) cannot be greater than %d\n", > + addr, USB_DEVICE_MAX_ADDRESS); > + return -EINVAL; > + } > + > + if (device_state == USB_STATE_CONFIGURED) { > + dev_err(priv_dev->dev, > + "can't set_address from configured state\n"); > + return -EINVAL; > + } > + > + reg = readl(&priv_dev->regs->usb_cmd); > + > + writel(reg | USB_CMD_FADDR(addr) | USB_CMD_SET_ADDR, > + &priv_dev->regs->usb_cmd); > + > + usb_gadget_set_state(&priv_dev->gadget, > + (addr ? USB_STATE_ADDRESS : USB_STATE_DEFAULT)); > + > + return 0; > +} > + > +/** > + * cdns3_req_ep0_get_status - Handling of GET_STATUS standard USB request > + * @priv_dev: extended gadget object > + * @ctrl_req: pointer to received setup packet > + * > + * Returns 0 if success, error code on error > + */ > +static int cdns3_req_ep0_get_status(struct cdns3_device *priv_dev, > + struct usb_ctrlrequest *ctrl) > +{ > + __le16 *response_pkt; > + u16 usb_status = 0; > + u32 recip; > + u32 reg; > + > + recip = ctrl->bRequestType & USB_RECIP_MASK; > + > + switch (recip) { > + case USB_RECIP_DEVICE: > + /* self powered */ > + if (priv_dev->is_selfpowered) > + usb_status = BIT(USB_DEVICE_SELF_POWERED); > + > + if (priv_dev->wake_up_flag) > + usb_status |= BIT(USB_DEVICE_REMOTE_WAKEUP); > + > + if (priv_dev->gadget.speed != USB_SPEED_SUPER) > + break; > + > + reg = readl(&priv_dev->regs->usb_sts); > + > + if (priv_dev->u1_allowed) > + usb_status |= BIT(USB_DEV_STAT_U1_ENABLED); > + > + if (priv_dev->u2_allowed) > + usb_status |= BIT(USB_DEV_STAT_U2_ENABLED); > + > + break; > + case USB_RECIP_INTERFACE: > + return cdns3_ep0_delegate_req(priv_dev, ctrl); > + case USB_RECIP_ENDPOINT: > + /* check if endpoint is stalled */ > + cdns3_select_ep(priv_dev, ctrl->wIndex); > + if (EP_STS_STALL(readl(&priv_dev->regs->ep_sts))) > + usb_status = BIT(USB_ENDPOINT_HALT); > + break; > + default: > + return -EINVAL; > + } > + > + response_pkt = (__le16 *)priv_dev->setup_buf; > + *response_pkt = cpu_to_le16(usb_status); > + > + cdns3_ep0_run_transfer(priv_dev, priv_dev->setup_dma, > + sizeof(*response_pkt), 1); > + return 0; > +} > + > +static int cdns3_ep0_feature_handle_device(struct cdns3_device *priv_dev, > + struct usb_ctrlrequest *ctrl, > + int set) > +{ > + enum usb_device_state state; > + enum usb_device_speed speed; > + int ret = 0; > + u32 wValue; > + u32 wIndex; > + u16 tmode; > + > + wValue = le16_to_cpu(ctrl->wValue); > + wIndex = le16_to_cpu(ctrl->wIndex); > + state = priv_dev->gadget.state; > + speed = priv_dev->gadget.speed; > + > + switch (ctrl->wValue) { > + case USB_DEVICE_REMOTE_WAKEUP: > + priv_dev->wake_up_flag = !!set; > + break; > + case USB_DEVICE_U1_ENABLE: > + if (state != USB_STATE_CONFIGURED || speed != USB_SPEED_SUPER) > + return -EINVAL; > + > + priv_dev->u1_allowed = !!set; > + break; > + case USB_DEVICE_U2_ENABLE: > + if (state != USB_STATE_CONFIGURED || speed != USB_SPEED_SUPER) > + return -EINVAL; > + > + priv_dev->u2_allowed = !!set; > + break; > + case USB_DEVICE_LTM_ENABLE: > + ret = -EINVAL; > + break; > + case USB_DEVICE_TEST_MODE: > + if (state != USB_STATE_CONFIGURED || speed > USB_SPEED_HIGH) > + return -EINVAL; > + > + tmode = le16_to_cpu(ctrl->wIndex); > + > + if (!set || (tmode & 0xff) != 0) > + return -EINVAL; > + > + switch (tmode >> 8) { > + case TEST_J: > + case TEST_K: > + case TEST_SE0_NAK: > + case TEST_PACKET: > + cdns3_ep0_complete_setup(priv_dev, 0, 1); > + /** > + * Little delay to give the controller some time > + * for sending status stage. > + * This time should be less then 3ms. > + */ > + usleep_range(1000, 2000); > + cdns3_set_register_bit(&priv_dev->regs->usb_cmd, > + USB_CMD_STMODE | > + USB_STS_TMODE_SEL(tmode - 1)); > + break; > + default: > + ret = -EINVAL; > + } > + break; > + default: > + ret = -EINVAL; > + } > + > + return ret; > +} > + > +static int cdns3_ep0_feature_handle_intf(struct cdns3_device *priv_dev, > + struct usb_ctrlrequest *ctrl, > + int set) > +{ > + u32 wValue; > + int ret = 0; > + > + wValue = le16_to_cpu(ctrl->wValue); > + > + switch (wValue) { > + case USB_INTRF_FUNC_SUSPEND: > + break; > + default: > + ret = -EINVAL; > + } > + > + return ret; > +} > + > +static int cdns3_ep0_feature_handle_endpoint(struct cdns3_device *priv_dev, > + struct usb_ctrlrequest *ctrl, > + int set) > +{ > + struct cdns3_endpoint *priv_ep; > + int ret = 0; > + u8 index; > + > + if (le16_to_cpu(ctrl->wValue) != USB_ENDPOINT_HALT) > + return -EINVAL; > + > + if (!(ctrl->wIndex & ~USB_DIR_IN)) > + return 0; > + > + index = cdns3_ep_addr_to_index(ctrl->wIndex); > + priv_ep = priv_dev->eps[index]; > + > + cdns3_select_ep(priv_dev, ctrl->wIndex); > + > + if (set) { > + cdns3_dbg(priv_ep->cdns3_dev, "Stall endpoint %s\n", > + priv_ep->name); > + writel(EP_CMD_SSTALL, &priv_dev->regs->ep_cmd); > + priv_ep->flags |= EP_STALL; > + } else { > + struct usb_request *request; > + > + if (priv_dev->eps[index]->flags & EP_WEDGE) { > + cdns3_select_ep(priv_dev, 0x00); > + return 0; > + } > + > + cdns3_dbg(priv_ep->cdns3_dev, "Clear Stalled endpoint %s\n", > + priv_ep->name); > + > + writel(EP_CMD_CSTALL | EP_CMD_EPRST, &priv_dev->regs->ep_cmd); > + > + /* wait for EPRST cleared */ > + ret = cdns3_handshake(&priv_dev->regs->ep_cmd, > + EP_CMD_EPRST, 0, 100); > + if (ret) > + return -EINVAL; > + > + priv_ep->flags &= ~EP_STALL; > + > + request = cdns3_next_request(&priv_ep->pending_req_list); > + if (request) { > + cdns3_dbg(priv_ep->cdns3_dev, "Resume transfer for %s\n", > + priv_ep->name); > + > + cdns3_rearm_transfer(priv_ep, 1); > + } > + } > + > + return ret; > +} > + > +/** > + * cdns3_req_ep0_handle_feature - > + * Handling of GET/SET_FEATURE standard USB request > + * > + * @priv_dev: extended gadget object > + * @ctrl_req: pointer to received setup packet > + * @set: must be set to 1 for SET_FEATURE request > + * > + * Returns 0 if success, error code on error > + */ > +static int cdns3_req_ep0_handle_feature(struct cdns3_device *priv_dev, > + struct usb_ctrlrequest *ctrl, > + int set) > +{ > + int ret = 0; > + u32 recip; > + > + recip = ctrl->bRequestType & USB_RECIP_MASK; > + > + switch (recip) { > + case USB_RECIP_DEVICE: > + ret = cdns3_ep0_feature_handle_device(priv_dev, ctrl, set); > + break; > + case USB_RECIP_INTERFACE: > + ret = cdns3_ep0_feature_handle_intf(priv_dev, ctrl, set); > + break; > + case USB_RECIP_ENDPOINT: > + ret = cdns3_ep0_feature_handle_endpoint(priv_dev, ctrl, set); > + break; > + default: > + return -EINVAL; > + } > + > + return ret; > +} > + > +/** > + * cdns3_req_ep0_set_sel - Handling of SET_SEL standard USB request > + * @priv_dev: extended gadget object > + * @ctrl_req: pointer to received setup packet > + * > + * Returns 0 if success, error code on error > + */ > +static int cdns3_req_ep0_set_sel(struct cdns3_device *priv_dev, > + struct usb_ctrlrequest *ctrl_req) > +{ > + if (priv_dev->gadget.state < USB_STATE_ADDRESS) > + return -EINVAL; > + > + if (ctrl_req->wLength != 6) { > + dev_err(priv_dev->dev, "Set SEL should be 6 bytes, got %d\n", > + ctrl_req->wLength); > + return -EINVAL; > + } > + > + cdns3_ep0_run_transfer(priv_dev, priv_dev->setup_dma, 6, 1); > + return 0; > +} > + > +/** > + * cdns3_req_ep0_set_isoch_delay - > + * Handling of GET_ISOCH_DELAY standard USB request > + * @priv_dev: extended gadget object > + * @ctrl_req: pointer to received setup packet > + * > + * Returns 0 if success, error code on error > + */ > +static int cdns3_req_ep0_set_isoch_delay(struct cdns3_device *priv_dev, > + struct usb_ctrlrequest *ctrl_req) > +{ > + if (ctrl_req->wIndex || ctrl_req->wLength) > + return -EINVAL; > + > + priv_dev->isoch_delay = ctrl_req->wValue; > + > + return 0; > +} > + > +/** > + * cdns3_ep0_standard_request - Handling standard USB requests > + * @priv_dev: extended gadget object > + * @ctrl_req: pointer to received setup packet > + * > + * Returns 0 if success, error code on error > + */ > +static int cdns3_ep0_standard_request(struct cdns3_device *priv_dev, > + struct usb_ctrlrequest *ctrl_req) > +{ > + int ret; > + > + switch (ctrl_req->bRequest) { > + case USB_REQ_SET_ADDRESS: > + ret = cdns3_req_ep0_set_address(priv_dev, ctrl_req); > + break; > + case USB_REQ_SET_CONFIGURATION: > + ret = cdns3_req_ep0_set_configuration(priv_dev, ctrl_req); > + break; > + case USB_REQ_GET_STATUS: > + ret = cdns3_req_ep0_get_status(priv_dev, ctrl_req); > + break; > + case USB_REQ_CLEAR_FEATURE: > + ret = cdns3_req_ep0_handle_feature(priv_dev, ctrl_req, 0); > + break; > + case USB_REQ_SET_FEATURE: > + ret = cdns3_req_ep0_handle_feature(priv_dev, ctrl_req, 1); > + break; > + case USB_REQ_SET_SEL: > + ret = cdns3_req_ep0_set_sel(priv_dev, ctrl_req); > + break; > + case USB_REQ_SET_ISOCH_DELAY: > + ret = cdns3_req_ep0_set_isoch_delay(priv_dev, ctrl_req); > + break; > + default: > + ret = cdns3_ep0_delegate_req(priv_dev, ctrl_req); > + break; > + } > + > + return ret; > +} > + > +static void __pending_setup_status_handler(struct cdns3_device *priv_dev) > +{ > + struct usb_request *request = priv_dev->pending_status_request; > + > + if (priv_dev->status_completion_no_call && request && > + request->complete) { > + request->complete(&priv_dev->eps[0]->endpoint, request); > + priv_dev->status_completion_no_call = 0; > + } > +} > + > +void cdns3_pending_setup_status_handler(struct work_struct *work) > +{ > + struct cdns3_device *priv_dev = container_of(work, struct cdns3_device, > + pending_status_wq); > + unsigned long flags; > + > + spin_lock_irqsave(&priv_dev->lock, flags); > + __pending_setup_status_handler(priv_dev); > + spin_unlock_irqrestore(&priv_dev->lock, flags); > +} > + > +/** > + * cdns3_gadget_ep_giveback - call struct usb_request's ->complete callback > + * @priv_ep: The endpoint to whom the request belongs to > + * @priv_req: The request we're giving back > + * @status: completion code for the request > + * > + * Must be called with controller's lock held and interrupts disabled. This > + * function will unmap @req and call its ->complete() callback to notify upper > + * layers that it has completed. > + */ > + > +void cdns3_gadget_ep0_giveback(struct cdns3_device *priv_dev, > + int status) > +{ > + struct cdns3_endpoint *priv_ep; > + struct usb_request *request; > + > + priv_ep = priv_dev->eps[0]; > + request = cdns3_next_request(&priv_ep->pending_req_list); > + > + priv_ep->dir = priv_dev->ep0_data_dir; > + cdns3_gadget_giveback(priv_ep, to_cdns3_request(request), status); > +} > + > +/** > + * cdns3_ep0_setup_phase - Handling setup USB requests > + * @priv_dev: extended gadget object > + */ > +static void cdns3_ep0_setup_phase(struct cdns3_device *priv_dev) > +{ > + struct usb_ctrlrequest *ctrl = priv_dev->setup_buf; > + struct cdns3_endpoint *priv_ep = priv_dev->eps[0]; > + int result; > + > + priv_dev->ep0_data_dir = ctrl->bRequestType & USB_DIR_IN; > + > + trace_cdns3_ctrl_req(ctrl); > + > + if (!list_empty(&priv_ep->pending_req_list)) { > + struct usb_request *request; > + > + request = cdns3_next_request(&priv_ep->pending_req_list); > + priv_ep->dir = priv_dev->ep0_data_dir; > + cdns3_gadget_giveback(priv_ep, to_cdns3_request(request), > + -ECONNRESET); > + } > + > + if (le16_to_cpu(ctrl->wLength)) > + priv_dev->ep0_stage = CDNS3_DATA_STAGE; > + else > + priv_dev->ep0_stage = CDNS3_STATUS_STAGE; > + > + if ((ctrl->bRequestType & USB_TYPE_MASK) == USB_TYPE_STANDARD) > + result = cdns3_ep0_standard_request(priv_dev, ctrl); > + else > + result = cdns3_ep0_delegate_req(priv_dev, ctrl); > + > + if (result == USB_GADGET_DELAYED_STATUS) > + return; > + > + if (result < 0) > + cdns3_ep0_complete_setup(priv_dev, 1, 1); > + else if (priv_dev->ep0_stage == CDNS3_STATUS_STAGE) > + cdns3_ep0_complete_setup(priv_dev, 0, 1); > +} > + > +static void cdns3_transfer_completed(struct cdns3_device *priv_dev) > +{ > + struct cdns3_endpoint *priv_ep = priv_dev->eps[0]; > + > + if (!list_empty(&priv_ep->pending_req_list)) { > + struct usb_request *request; > + > + trace_cdns3_complete_trb(priv_ep, priv_ep->trb_pool); > + request = cdns3_next_request(&priv_ep->pending_req_list); > + > + request->actual = > + TRB_LEN(le32_to_cpu(priv_ep->trb_pool->length)); > + > + priv_ep->dir = priv_dev->ep0_data_dir; > + cdns3_gadget_giveback(priv_ep, to_cdns3_request(request), 0); > + } > + > + cdns3_ep0_complete_setup(priv_dev, 0, 0); > +} > + > +/** > + * cdns3_check_new_setup - Check if controller receive new SETUP packet. > + * @priv_dev: extended gadget object > + * > + * The SETUP packet can be kept in on-chip memory or in system memory. > + */ > +static bool cdns3_check_new_setup(struct cdns3_device *priv_dev) > +{ > + u32 ep_sts_reg; > + > + cdns3_select_ep(priv_dev, 0 | USB_DIR_OUT); > + ep_sts_reg = readl(&priv_dev->regs->ep_sts); > + > + return !!(ep_sts_reg & (EP_STS_SETUP | EP_STS_STPWAIT)); > +} > + > +/** > + * cdns3_check_ep0_interrupt_proceed - Processes interrupt related to endpoint 0 > + * @priv_dev: extended gadget object > + * @dir: USB_DIR_IN for IN direction, USB_DIR_OUT for OUT direction > + */ > +void cdns3_check_ep0_interrupt_proceed(struct cdns3_device *priv_dev, int dir) > +{ > + u32 ep_sts_reg; > + > + cdns3_select_ep(priv_dev, dir); > + > + ep_sts_reg = readl(&priv_dev->regs->ep_sts); > + writel(ep_sts_reg, &priv_dev->regs->ep_sts); > + > + trace_cdns3_ep0_irq(priv_dev, ep_sts_reg); > + > + __pending_setup_status_handler(priv_dev); > + > + if ((ep_sts_reg & EP_STS_SETUP)) { > + cdns3_ep0_setup_phase(priv_dev); > + } else if ((ep_sts_reg & EP_STS_IOC) || (ep_sts_reg & EP_STS_ISP)) { > + priv_dev->ep0_data_dir = dir; > + cdns3_transfer_completed(priv_dev); > + } > + > + if (ep_sts_reg & EP_STS_DESCMIS) { > + if (dir == 0 && !priv_dev->setup_pending) > + cdns3_prepare_setup_packet(priv_dev); > + } > +} > + > +/** > + * cdns3_gadget_ep0_enable > + * Function shouldn't be called by gadget driver, > + * endpoint 0 is allways active > + */ > +static int cdns3_gadget_ep0_enable(struct usb_ep *ep, > + const struct usb_endpoint_descriptor *desc) > +{ > + return -EINVAL; > +} > + > +/** > + * cdns3_gadget_ep0_disable > + * Function shouldn't be called by gadget driver, > + * endpoint 0 is allways active > + */ > +static int cdns3_gadget_ep0_disable(struct usb_ep *ep) > +{ > + return -EINVAL; > +} > + > +/** > + * cdns3_gadget_ep0_set_halt > + * @ep: pointer to endpoint zero object > + * @value: 1 for set stall, 0 for clear stall > + * > + * Returns 0 > + */ > +static int cdns3_gadget_ep0_set_halt(struct usb_ep *ep, int value) > +{ > + /* TODO */ > + return 0; > +} > + > +/** > + * cdns3_gadget_ep0_queue Transfer data on endpoint zero > + * @ep: pointer to endpoint zero object > + * @request: pointer to request object > + * @gfp_flags: gfp flags > + * > + * Returns 0 on success, error code elsewhere > + */ > +static int cdns3_gadget_ep0_queue(struct usb_ep *ep, > + struct usb_request *request, > + gfp_t gfp_flags) > +{ > + struct cdns3_endpoint *priv_ep = ep_to_cdns3_ep(ep); > + struct cdns3_device *priv_dev = priv_ep->cdns3_dev; > + unsigned long flags; > + int erdy_sent = 0; > + int ret = 0; > + > + cdns3_dbg(priv_ep->cdns3_dev, "Queue to Ep0%s L: %d\n", > + priv_dev->ep0_data_dir ? "IN" : "OUT", > + request->length); > + > + /* cancel the request if controller receive new SETUP packet. */ > + if (cdns3_check_new_setup(priv_dev)) > + return -ECONNRESET; > + > + /* send STATUS stage. Should be called only for SET_CONFIGURATION */ > + if (priv_dev->ep0_stage == CDNS3_STATUS_STAGE) { > + spin_lock_irqsave(&priv_dev->lock, flags); > + cdns3_select_ep(priv_dev, 0x00); > + > + erdy_sent = !priv_dev->hw_configured_flag; > + cdns3_set_hw_configuration(priv_dev); > + > + if (!erdy_sent) > + cdns3_ep0_complete_setup(priv_dev, 0, 1); > + > + request->actual = 0; > + priv_dev->status_completion_no_call = true; > + priv_dev->pending_status_request = request; > + spin_unlock_irqrestore(&priv_dev->lock, flags); > + > + /* > + * Since there is no completion interrupt for status stage, > + * it needs to call ->completion in software after > + * ep0_queue is back. > + */ > + queue_work(system_freezable_wq, &priv_dev->pending_status_wq); > + return 0; > + } > + > + spin_lock_irqsave(&priv_dev->lock, flags); > + if (!list_empty(&priv_ep->pending_req_list)) { > + dev_err(priv_dev->dev, > + "can't handle multiple requests for ep0\n"); > + spin_unlock_irqrestore(&priv_dev->lock, flags); > + return -EBUSY; > + } > + > + ret = usb_gadget_map_request_by_dev(priv_dev->sysdev, request, > + priv_dev->ep0_data_dir); > + if (ret) { > + spin_unlock_irqrestore(&priv_dev->lock, flags); > + dev_err(priv_dev->dev, "failed to map request\n"); > + return -EINVAL; > + } > + > + request->status = -EINPROGRESS; > + list_add_tail(&request->list, &priv_ep->pending_req_list); > + cdns3_ep0_run_transfer(priv_dev, request->dma, request->length, 1); > + spin_unlock_irqrestore(&priv_dev->lock, flags); > + > + return ret; > +} > + > +/** > + * cdns3_gadget_ep_set_wedge Set wedge on selected endpoint > + * @ep: endpoint object > + * > + * Returns 0 > + */ > +int cdns3_gadget_ep_set_wedge(struct usb_ep *ep) > +{ > + struct cdns3_endpoint *priv_ep = ep_to_cdns3_ep(ep); > + struct cdns3_device *priv_dev = priv_ep->cdns3_dev; > + > + dev_dbg(priv_dev->dev, "Wedge for %s\n", ep->name); > + cdns3_gadget_ep_set_halt(ep, 1); > + priv_ep->flags |= EP_WEDGE; > + > + return 0; > +} > + > +const struct usb_ep_ops cdns3_gadget_ep0_ops = { > + .enable = cdns3_gadget_ep0_enable, > + .disable = cdns3_gadget_ep0_disable, > + .alloc_request = cdns3_gadget_ep_alloc_request, > + .free_request = cdns3_gadget_ep_free_request, > + .queue = cdns3_gadget_ep0_queue, > + .dequeue = cdns3_gadget_ep_dequeue, > + .set_halt = cdns3_gadget_ep0_set_halt, > + .set_wedge = cdns3_gadget_ep_set_wedge, > +}; > + > +/** > + * cdns3_ep0_config - Configures default endpoint > + * @priv_dev: extended gadget object > + * > + * Functions sets parameters: maximal packet size and enables interrupts > + */ > +void cdns3_ep0_config(struct cdns3_device *priv_dev) > +{ > + struct cdns3_usb_regs __iomem *regs; > + struct cdns3_endpoint *priv_ep; > + u32 max_packet_size = 64; > + > + regs = priv_dev->regs; > + > + if (priv_dev->gadget.speed == USB_SPEED_SUPER) > + max_packet_size = 512; > + > + priv_ep = priv_dev->eps[0]; > + > + if (!list_empty(&priv_ep->pending_req_list)) { > + struct usb_request *request; > + > + request = cdns3_next_request(&priv_ep->pending_req_list); > + list_del_init(&request->list); > + } > + > + priv_dev->u1_allowed = 0; > + priv_dev->u2_allowed = 0; > + > + priv_dev->gadget.ep0->maxpacket = max_packet_size; > + cdns3_gadget_ep0_desc.wMaxPacketSize = cpu_to_le16(max_packet_size); > + > + /* init ep out */ > + cdns3_select_ep(priv_dev, USB_DIR_OUT); > + > + writel(EP_CFG_ENABLE | EP_CFG_MAXPKTSIZE(max_packet_size), > + ®s->ep_cfg); > + > + writel(EP_STS_EN_SETUPEN | EP_STS_EN_DESCMISEN | EP_STS_EN_TRBERREN, > + ®s->ep_sts_en); > + > + /* init ep in */ > + cdns3_select_ep(priv_dev, USB_DIR_IN); > + > + writel(EP_CFG_ENABLE | EP_CFG_MAXPKTSIZE(max_packet_size), > + ®s->ep_cfg); > + > + writel(EP_STS_EN_SETUPEN | EP_STS_EN_TRBERREN, ®s->ep_sts_en); > + > + cdns3_set_register_bit(®s->usb_conf, USB_CONF_U1DS | USB_CONF_U2DS); > +} > + > +/** > + * cdns3_init_ep0 Initializes software endpoint 0 of gadget > + * @priv_dev: extended gadget object > + * @ep_priv: extended endpoint object > + * > + * Returns 0 on success else error code. > + */ > +int cdns3_init_ep0(struct cdns3_device *priv_dev, > + struct cdns3_endpoint *priv_ep) > +{ > + sprintf(priv_ep->name, "ep0"); > + > + /* fill linux fields */ > + priv_ep->endpoint.ops = &cdns3_gadget_ep0_ops; > + priv_ep->endpoint.maxburst = 1; > + usb_ep_set_maxpacket_limit(&priv_ep->endpoint, > + CDNS3_EP0_MAX_PACKET_LIMIT); > + priv_ep->endpoint.address = 0; > + priv_ep->endpoint.caps.type_control = 1; > + priv_ep->endpoint.caps.dir_in = 1; > + priv_ep->endpoint.caps.dir_out = 1; > + priv_ep->endpoint.name = priv_ep->name; > + priv_ep->endpoint.desc = &cdns3_gadget_ep0_desc; > + priv_dev->gadget.ep0 = &priv_ep->endpoint; > + priv_ep->type = USB_ENDPOINT_XFER_CONTROL; > + > + return cdns3_allocate_trb_pool(priv_ep); > +} > diff --git a/drivers/usb/cdns3/gadget-export.h b/drivers/usb/cdns3/gadget-export.h > new file mode 100644 > index 000000000000..577469eee961 > --- /dev/null > +++ b/drivers/usb/cdns3/gadget-export.h > @@ -0,0 +1,28 @@ > +/* SPDX-License-Identifier: GPL-2.0 */ > +/* > + * Cadence USBSS DRD Driver - Gadget Export APIs. > + * > + * Copyright (C) 2017 NXP > + * Copyright (C) 2017-2018 NXP > + * > + * Authors: Peter Chen > + */ > +#ifndef __LINUX_CDNS3_GADGET_EXPORT > +#define __LINUX_CDNS3_GADGET_EXPORT > + > +#ifdef CONFIG_USB_CDNS3_GADGET > + > +int cdns3_gadget_init(struct cdns3 *cdns); > +void cdns3_gadget_exit(struct cdns3 *cdns); > +#else > + > +static inline int cdns3_gadget_init(struct cdns3 *cdns) > +{ > + return -ENXIO; > +} > + > +static inline void cdns3_gadget_exit(struct cdns3 *cdns) { } > + > +#endif > + > +#endif /* __LINUX_CDNS3_GADGET_EXPORT */ > diff --git a/drivers/usb/cdns3/gadget.c b/drivers/usb/cdns3/gadget.c > new file mode 100644 > index 000000000000..7f7f24ee3c4b > --- /dev/null > +++ b/drivers/usb/cdns3/gadget.c > @@ -0,0 +1,2003 @@ > +// SPDX-License-Identifier: GPL-2.0 > +/* > + * Cadence USBSS DRD Driver - gadget side. > + * > + * Copyright (C) 2018 Cadence Design Systems. > + * Copyright (C) 2017-2018 NXP > + * > + * Authors: Pawel Jez , > + * Pawel Laszczak > + * Peter Chen > + */ > + > +/* > + * Work around 1: > + * At some situations, the controller may get stale data address in TRB > + * at below sequences: > + * 1. Controller read TRB includes data address > + * 2. Software updates TRBs includes data address and Cycle bit > + * 3. Controller read TRB which includes Cycle bit > + * 4. DMA run with stale data address > + > + * To fix this problem, we need to make the first TRB in TD as invalid TRB when > + * the TD which the DMA is handling close to the TRB we are adding, > + * and make this TRB as valid at TRBERR interrupt. The condition for > + * this TRB is: > + * > + * If (((Dequeue Ptr (i.e. EP_TRADDR) == Enqueue Ptr-1) or > + * (Dequeue Ptr (i.e. EP_TRADDR) == Enqueue Ptr)) > + * and (DRBL==1 and (not EP0))) > + */ > + > +#include > +#include > +#include > + > +#include "core.h" > +#include "gadget-export.h" > +#include "gadget.h" > +#include "trace.h" > + > +static int __cdns3_gadget_ep_queue(struct usb_ep *ep, > + struct usb_request *request, > + gfp_t gfp_flags); > + > +/** > + * cdns3_handshake - spin reading until handshake completes or fails > + * @ptr: address of device controller register to be read > + * @mask: bits to look at in result of read > + * @done: value of those bits when handshake succeeds > + * @usec: timeout in microseconds > + * > + * Returns negative errno, or zero on success > + * > + * Success happens when the "mask" bits have the specified value (hardware > + * handshake done). There are two failure modes: "usec" have passed (major > + * hardware flakeout), or the register reads as all-ones (hardware removed). > + */ > +int cdns3_handshake(void __iomem *ptr, u32 mask, u32 done, int usec) > +{ > + u32 result; > + > + do { > + result = readl(ptr); > + if (result == ~(u32)0) /* card removed */ > + return -ENODEV; > + result &= mask; > + if (result == done) > + return 0; > + udelay(1); > + usec--; > + } while (usec > 0); > + return -ETIMEDOUT; > +} > + > +/** > + * cdns3_set_register_bit - set bit in given register. > + * @ptr: address of device controller register to be read and changed > + * @mask: bits requested to set > + */ > +void cdns3_set_register_bit(void __iomem *ptr, u32 mask) > +{ > + mask = readl(ptr) | mask; > + writel(mask, ptr); > +} > + > +/** > + * cdns3_ep_addr_to_index - Macro converts endpoint address to > + * index of endpoint object in cdns3_device.eps[] container > + * @ep_addr: endpoint address for which endpoint object is required > + * > + */ > +u8 cdns3_ep_addr_to_index(u8 ep_addr) > +{ > + return (((ep_addr & 0x7F)) + ((ep_addr & USB_DIR_IN) ? 16 : 0)); > +} > + > +/** > + * cdns3_next_request - returns next request from list > + * @list: list containing requests > + * > + * Returns request or NULL if no requests in list > + */ > +struct usb_request *cdns3_next_request(struct list_head *list) > +{ > + return list_first_entry_or_null(list, struct usb_request, list); > +} > + > +/** > + * select_ep - selects endpoint > + * @priv_dev: extended gadget object > + * @ep: endpoint address > + */ > +void cdns3_select_ep(struct cdns3_device *priv_dev, u32 ep) > +{ > + if (priv_dev->selected_ep == ep) > + return; > + > + priv_dev->selected_ep = ep; > + writel(ep, &priv_dev->regs->ep_sel); > +} > + > +dma_addr_t cdns3_trb_virt_to_dma(struct cdns3_endpoint *priv_ep, > + struct cdns3_trb *trb) > +{ > + u32 offset = (char *)trb - (char *)priv_ep->trb_pool; > + > + return priv_ep->trb_pool_dma + offset; > +} > + > +int cdns3_ring_size(struct cdns3_endpoint *priv_ep) > +{ > + switch (priv_ep->type) { > + case USB_ENDPOINT_XFER_ISOC: > + return TRB_ISO_RING_SIZE; > + case USB_ENDPOINT_XFER_CONTROL: > + return TRB_CTRL_RING_SIZE; > + default: > + return TRB_RING_SIZE; > + } > +} > + > +/** > + * cdns3_allocate_trb_pool - Allocates TRB's pool for selected endpoint > + * @priv_ep: endpoint object > + * > + * Function will return 0 on success or -ENOMEM on allocation error > + */ > +int cdns3_allocate_trb_pool(struct cdns3_endpoint *priv_ep) > +{ > + struct cdns3_device *priv_dev = priv_ep->cdns3_dev; > + int ring_size = cdns3_ring_size(priv_ep); > + struct cdns3_trb *link_trb; > + > + if (!priv_ep->trb_pool) { > + priv_ep->trb_pool = dma_zalloc_coherent(priv_dev->sysdev, > + ring_size, > + &priv_ep->trb_pool_dma, > + GFP_DMA); > + if (!priv_ep->trb_pool) > + return -ENOMEM; > + } else { > + memset(priv_ep->trb_pool, 0, ring_size); > + } > + > + if (!priv_ep->num) > + return 0; > + > + if (!priv_ep->aligned_buff) { > + void *buff = dma_alloc_coherent(priv_dev->sysdev, > + CDNS3_ALIGNED_BUF_SIZE, > + &priv_ep->aligned_dma_addr, > + GFP_DMA); > + > + priv_ep->aligned_buff = buff; > + if (!priv_ep->aligned_buff) { > + dma_free_coherent(priv_dev->sysdev, > + ring_size, > + priv_ep->trb_pool, > + priv_ep->trb_pool_dma); > + priv_ep->trb_pool = NULL; > + > + return -ENOMEM; > + } > + } > + > + priv_ep->num_trbs = ring_size / TRB_SIZE; > + /* Initialize the last TRB as Link TRB */ > + link_trb = (priv_ep->trb_pool + (priv_ep->num_trbs - 1)); > + link_trb->buffer = TRB_BUFFER(priv_ep->trb_pool_dma); > + link_trb->control = TRB_CYCLE | TRB_TYPE(TRB_LINK) | > + TRB_CHAIN | TRB_TOGGLE; > + > + return 0; > +} > + > +static void cdns3_free_trb_pool(struct cdns3_endpoint *priv_ep) > +{ > + struct cdns3_device *priv_dev = priv_ep->cdns3_dev; > + > + if (priv_ep->trb_pool) { > + dma_free_coherent(priv_dev->sysdev, > + cdns3_ring_size(priv_ep), > + priv_ep->trb_pool, priv_ep->trb_pool_dma); > + priv_ep->trb_pool = NULL; > + } > + > + if (priv_ep->aligned_buff) { > + dma_free_coherent(priv_dev->sysdev, CDNS3_ALIGNED_BUF_SIZE, > + priv_ep->aligned_buff, > + priv_ep->aligned_dma_addr); > + priv_ep->aligned_buff = NULL; > + } > +} > + > +/** > + * cdns3_data_flush - flush data at onchip buffer > + * @priv_ep: endpoint object > + * > + * Endpoint must be selected before call to this function > + * > + * Returns zero on success or negative value on failure > + */ > +static int cdns3_data_flush(struct cdns3_endpoint *priv_ep) > +{ > + struct cdns3_device *priv_dev = priv_ep->cdns3_dev; > + > + writel(EP_CMD_DFLUSH, &priv_dev->regs->ep_cmd); > + > + /* wait for DFLUSH cleared */ > + return cdns3_handshake(&priv_dev->regs->ep_cmd, EP_CMD_DFLUSH, 0, 100); > +} > + > +/** > + * cdns3_ep_stall_flush - Stalls and flushes selected endpoint > + * @priv_ep: endpoint object > + * > + * Endpoint must be selected before call to this function > + */ > +static void cdns3_ep_stall_flush(struct cdns3_endpoint *priv_ep) > +{ > + struct cdns3_device *priv_dev = priv_ep->cdns3_dev; > + > + cdns3_dbg(priv_ep->cdns3_dev, "Stall & flush endpoint %s\n", > + priv_ep->name); > + > + writel(EP_CMD_DFLUSH | EP_CMD_ERDY | EP_CMD_SSTALL, > + &priv_dev->regs->ep_cmd); > + > + /* wait for DFLUSH cleared */ > + cdns3_handshake(&priv_dev->regs->ep_cmd, EP_CMD_DFLUSH, 0, 100); > + priv_ep->flags |= EP_STALL; > +} > + > +/** > + * cdns3_hw_reset_eps_config - reset endpoints configuration kept by controller. > + * @priv_dev: extended gadget object > + */ > +void cdns3_hw_reset_eps_config(struct cdns3_device *priv_dev) > +{ > + writel(USB_CONF_CFGRST, &priv_dev->regs->usb_conf); > + > + cdns3_allow_enable_l1(priv_dev, 0); > + priv_dev->hw_configured_flag = 0; > + priv_dev->onchip_mem_allocated_size = 0; > +} > + > +/** > + * cdns3_ep_inc_trb - increment a trb index. > + * @index: Pointer to the TRB index to increment. > + * @cs: Cycle state > + * @trb_in_seg: number of TRBs in segment > + * > + * The index should never point to the link TRB. After incrementing, > + * if it is point to the link TRB, wrap around to the beginning and revert > + * cycle state bit The > + * link TRB is always at the last TRB entry. > + */ > +static void cdns3_ep_inc_trb(int *index, u8 *cs, int trb_in_seg) > +{ > + (*index)++; > + if (*index == (trb_in_seg - 1)) { > + *index = 0; > + *cs ^= 1; > + } > +} > + > +/** > + * cdns3_ep_inc_enq - increment endpoint's enqueue pointer > + * @priv_ep: The endpoint whose enqueue pointer we're incrementing > + */ > +static void cdns3_ep_inc_enq(struct cdns3_endpoint *priv_ep) > +{ > + priv_ep->free_trbs--; > + cdns3_ep_inc_trb(&priv_ep->enqueue, &priv_ep->pcs, priv_ep->num_trbs); > +} > + > +/** > + * cdns3_ep_inc_deq - increment endpoint's dequeue pointer > + * @priv_ep: The endpoint whose dequeue pointer we're incrementing > + */ > +static void cdns3_ep_inc_deq(struct cdns3_endpoint *priv_ep) > +{ > + priv_ep->free_trbs++; > + cdns3_ep_inc_trb(&priv_ep->dequeue, &priv_ep->ccs, priv_ep->num_trbs); > +} > + > +void cdns3_move_deq_to_next_trb(struct cdns3_request *priv_req) > +{ > + struct cdns3_endpoint *priv_ep = priv_req->priv_ep; > + int current_trb = priv_req->start_trb; > + > + while (current_trb != priv_req->end_trb) { > + cdns3_ep_inc_deq(priv_ep); > + current_trb = priv_ep->dequeue; > + } > + > + cdns3_ep_inc_deq(priv_ep); > +} > + > +/** > + * cdns3_allow_enable_l1 - enable/disable permits to transition to L1. > + * @priv_dev: Extended gadget object > + * @enable: Enable/disable permit to transition to L1. > + * > + * If bit USB_CONF_L1EN is set and device receive Extended Token packet, > + * then controller answer with ACK handshake. > + * If bit USB_CONF_L1DS is set and device receive Extended Token packet, > + * then controller answer with NYET handshake. > + */ > +void cdns3_allow_enable_l1(struct cdns3_device *priv_dev, int enable) > +{ > + if (enable) > + writel(USB_CONF_L1EN, &priv_dev->regs->usb_conf); > + else > + writel(USB_CONF_L1DS, &priv_dev->regs->usb_conf); > +} > + > +enum usb_device_speed cdns3_get_speed(struct cdns3_device *priv_dev) > +{ > + u32 reg; > + > + reg = readl(&priv_dev->regs->usb_sts); > + > + if (DEV_SUPERSPEED(reg)) > + return USB_SPEED_SUPER; > + else if (DEV_HIGHSPEED(reg)) > + return USB_SPEED_HIGH; > + else if (DEV_FULLSPEED(reg)) > + return USB_SPEED_FULL; > + else if (DEV_LOWSPEED(reg)) > + return USB_SPEED_LOW; > + return USB_SPEED_UNKNOWN; > +} > + > +/** > + * cdns3_start_all_request - add to ring all request not started > + * @priv_dev: Extended gadget object > + * @priv_ep: The endpoint for whom request will be started. > + * > + * Returns return ENOMEM if transfer ring i not enough TRBs to start > + * all requests. > + */ > +static int cdns3_start_all_request(struct cdns3_device *priv_dev, > + struct cdns3_endpoint *priv_ep) > +{ > + struct cdns3_request *priv_req; > + struct usb_request *request; > + int ret = 0; > + > + while (!list_empty(&priv_ep->deferred_req_list)) { > + request = cdns3_next_request(&priv_ep->deferred_req_list); > + priv_req = to_cdns3_request(request); > + > + ret = cdns3_ep_run_transfer(priv_ep, request); > + if (ret) > + return ret; > + > + list_del(&request->list); > + list_add_tail(&request->list, > + &priv_ep->pending_req_list); > + } > + > + priv_ep->flags &= ~EP_RING_FULL; > + return ret; > +} > + > +/** > + * cdns3_gadget_giveback - call struct usb_request's ->complete callback > + * @priv_ep: The endpoint to whom the request belongs to > + * @priv_req: The request we're giving back > + * @status: completion code for the request > + * > + * Must be called with controller's lock held and interrupts disabled. This > + * function will unmap @req and call its ->complete() callback to notify upper > + * layers that it has completed. > + */ > +void cdns3_gadget_giveback(struct cdns3_endpoint *priv_ep, > + struct cdns3_request *priv_req, > + int status) > +{ > + struct cdns3_device *priv_dev = priv_ep->cdns3_dev; > + struct usb_request *request = &priv_req->request; > + > + list_del_init(&request->list); > + > + if (request->status == -EINPROGRESS) > + request->status = status; > + > + usb_gadget_unmap_request_by_dev(priv_dev->sysdev, request, > + priv_ep->dir); > + > + priv_req->flags &= ~REQUEST_PENDING; > + trace_cdns3_gadget_giveback(priv_req); > + > + /* Start all not pending request */ > + if (priv_ep->flags & EP_RING_FULL) > + cdns3_start_all_request(priv_dev, priv_ep); > + > + if (request->complete) { > + spin_unlock(&priv_dev->lock); > + usb_gadget_giveback_request(&priv_ep->endpoint, > + request); > + spin_lock(&priv_dev->lock); > + } > + > + if (request->buf == priv_dev->zlp_buf) > + cdns3_gadget_ep_free_request(&priv_ep->endpoint, request); > +} > + > +/** > + * cdns3_ep_run_transfer - start transfer on no-default endpoint hardware > + * @priv_ep: endpoint object > + * > + * Returns zero on success or negative value on failure > + */ > +int cdns3_ep_run_transfer(struct cdns3_endpoint *priv_ep, > + struct usb_request *request) > +{ > + struct cdns3_device *priv_dev = priv_ep->cdns3_dev; > + struct cdns3_request *priv_req; > + struct cdns3_trb *trb; > + dma_addr_t trb_dma; > + int dma_index; > + int sg_iter = 0; > + u32 first_pcs; > + int num_trb; > + int address; > + u32 doorbell; > + int pcs; > + > + if (priv_ep->type == USB_ENDPOINT_XFER_ISOC) > + num_trb = priv_ep->interval; > + else > + num_trb = request->num_sgs ? request->num_sgs : 1; > + > + if (num_trb > priv_ep->free_trbs) { > + priv_ep->flags |= EP_RING_FULL; > + return -ENOBUFS; > + } > + > + priv_req = to_cdns3_request(request); > + address = priv_ep->endpoint.desc->bEndpointAddress; > + > + priv_ep->flags |= EP_PENDING_REQUEST; > + trb_dma = request->dma; > + > + /* must allocate buffer aligned to 8 */ > + if ((request->dma % 8)) { > + if (request->length <= CDNS3_ALIGNED_BUF_SIZE) { > + memcpy(priv_ep->aligned_buff, request->buf, > + request->length); > + trb_dma = priv_ep->aligned_dma_addr; > + } else { > + return -ENOMEM; > + } > + } > + > + trb = priv_ep->trb_pool + priv_ep->enqueue; > + priv_req->start_trb = priv_ep->enqueue; > + priv_req->trb = trb; > + > + /* prepare ring */ > + if ((priv_ep->enqueue + num_trb) >= (priv_ep->num_trbs - 1)) { > + /*updating C bt in Link TRB before starting DMA*/ > + struct cdns3_trb *link_trb = priv_ep->trb_pool + > + (priv_ep->num_trbs - 1); > + link_trb->control = ((priv_ep->pcs) ? TRB_CYCLE : 0) | > + TRB_TYPE(TRB_LINK) | TRB_CHAIN | > + TRB_TOGGLE; > + } > + > + first_pcs = priv_ep->pcs ? TRB_CYCLE : 0; > + > + /* arm transfer on selected endpoint */ > + cdns3_select_ep(priv_ep->cdns3_dev, address); > + > + doorbell = !!(readl(&priv_dev->regs->ep_cmd) & EP_CMD_DRDY); > + dma_index = (readl(&priv_dev->regs->ep_traddr) - > + priv_ep->trb_pool_dma) / TRB_SIZE; > + > + if (!priv_ep->wa1_set) { > + if (doorbell && > + ((priv_ep->enqueue == 0 && > + dma_index >= GET_TRBS_PER_SEGMENT(priv_ep->type) - 2) || > + dma_index == priv_ep->enqueue || > + (dma_index == priv_ep->enqueue - 1))) { > + priv_ep->wa1_cycle_bit = first_pcs; > + priv_ep->wa1_set = 1; > + priv_ep->wa1_trb = trb; > + first_pcs ^= 0x1; > + cdns3_dbg(priv_dev, "WA1: deferred doorbel\n"); > + } > + } > + > + do { > + /* fill TRB */ > + trb->buffer = TRB_BUFFER(request->num_sgs == 0 > + ? trb_dma : request->sg[sg_iter].dma_address); > + > + trb->length = TRB_BURST_LEN(16) | > + TRB_LEN(request->num_sgs == 0 ? > + request->length : request->sg[sg_iter].length); > + > + trb->control = TRB_TYPE(TRB_NORMAL); > + pcs = priv_ep->pcs ? TRB_CYCLE : 0; > + > + /* > + * first trb should be prepared as last to avoid processing > + * transfer to early > + */ > + if (sg_iter != 0) > + trb->control |= pcs; > + > + if (priv_ep->type == USB_ENDPOINT_XFER_ISOC && !priv_ep->dir) { > + trb->control |= TRB_IOC | TRB_ISP; > + } else { > + /* for last element in TD or in SG list */ > + if (sg_iter == (num_trb - 1) && sg_iter != 0) > + trb->control |= pcs | TRB_IOC | TRB_ISP; > + } > + ++sg_iter; > + priv_req->end_trb = priv_ep->enqueue; > + cdns3_ep_inc_enq(priv_ep); > + trb = priv_ep->trb_pool + priv_ep->enqueue; > + } while (sg_iter < num_trb); > + > + trb = priv_req->trb; > + > + priv_req->flags |= REQUEST_PENDING; > + > + /* > + * Memory barrier - cycle bit must be set before other filds in trb. > + */ > + wmb(); > + > + /* give the TD to the consumer*/ > + if (sg_iter == 1) > + trb->control |= first_pcs | TRB_IOC | TRB_ISP; > + else > + trb->control |= first_pcs; > + > + trace_cdns3_prepare_trb(priv_ep, priv_req->trb); > + > + /* > + * Memory barrier - Cycle Bit must be set before trb->length and > + * trb->buffer fields. > + */ > + wmb(); > + > + /* > + * For DMULT mode we can set address to transfer ring only once after > + * enabling endpoint. > + */ > + if (priv_ep->flags & EP_UPDATE_EP_TRBADDR) { > + writel(EP_TRADDR_TRADDR(priv_ep->trb_pool_dma + > + priv_req->start_trb * TRB_SIZE), > + &priv_dev->regs->ep_traddr); > + > + cdns3_dbg(priv_ep->cdns3_dev, "Update ep_trbaddr for %s to %08x\n", > + priv_ep->name, readl(&priv_dev->regs->ep_traddr)); > + > + priv_ep->flags &= ~EP_UPDATE_EP_TRBADDR; > + } > + > + if (!priv_ep->wa1_set && !(priv_ep->flags & EP_STALL)) { > + trace_cdns3_ring(priv_ep); > + /*clearing TRBERR and EP_STS_DESCMIS before seting DRDY*/ > + writel(EP_STS_TRBERR | EP_STS_DESCMIS, &priv_dev->regs->ep_sts); > + writel(EP_CMD_DRDY, &priv_dev->regs->ep_cmd); > + trace_cdns3_doorbell_epx(priv_ep->name, > + readl(&priv_dev->regs->ep_traddr)); > + } > + > + return 0; > +} > + > +void cdns3_set_hw_configuration(struct cdns3_device *priv_dev) > +{ > + struct cdns3_endpoint *priv_ep; > + struct usb_ep *ep; > + int result = 0; > + > + if (priv_dev->hw_configured_flag) > + return; > + > + writel(USB_CONF_CFGSET, &priv_dev->regs->usb_conf); > + writel(EP_CMD_ERDY | EP_CMD_REQ_CMPL, &priv_dev->regs->ep_cmd); > + > + cdns3_set_register_bit(&priv_dev->regs->usb_conf, > + USB_CONF_U1EN | USB_CONF_U2EN); > + > + /* wait until configuration set */ > + result = cdns3_handshake(&priv_dev->regs->usb_sts, > + USB_STS_CFGSTS_MASK, 1, 100); > + > + priv_dev->hw_configured_flag = 1; > + cdns3_allow_enable_l1(priv_dev, 1); > + > + list_for_each_entry(ep, &priv_dev->gadget.ep_list, ep_list) { > + if (ep->enabled) { > + priv_ep = ep_to_cdns3_ep(ep); > + cdns3_start_all_request(priv_dev, priv_ep); > + } > + } > +} > + > +/** > + * cdns3_request_handled - check whether request has been handled by DMA > + * > + * @priv_ep: extended endpoint object. > + * @priv_req: request object for checking > + * > + * Endpoint must be selected before invoking this function. > + * > + * Returns false if request has not been handled by DMA, else returns true. > + * > + * SR - start ring > + * ER - end ring > + * DQ = priv_ep->dequeue - dequeue position > + * EQ = priv_ep->enqueue - enqueue position > + * ST = priv_req->start_trb - index of first TRB in transfer ring > + * ET = priv_req->end_trb - index of last TRB in transfer ring > + * CI = current_index - index of processed TRB by DMA. > + * > + * As first step, function checks if cycle bit for priv_req->start_trb is > + * correct. > + * > + * some rules: > + * 1. priv_ep->dequeue never exceed current_index. > + * 2 priv_ep->enqueue never exceed priv_ep->dequeue > + * > + * Then We can split recognition into two parts: > + * Case 1 - priv_ep->dequeue < current_index > + * SR ... EQ ... DQ ... CI ... ER > + * SR ... DQ ... CI ... EQ ... ER > + * > + * Request has been handled by DMA if ST and ET is between DQ and CI. > + * > + * Case 2 - priv_ep->dequeue > current_index > + * This situation take place when CI go through the LINK TRB at the end of > + * transfer ring. > + * SR ... CI ... EQ ... DQ ... ER > + * > + * Request has been handled by DMA if ET is less then CI or > + * ET is greater or equal DQ. > + */ > +static bool cdns3_request_handled(struct cdns3_endpoint *priv_ep, > + struct cdns3_request *priv_req) > +{ > + struct cdns3_device *priv_dev = priv_ep->cdns3_dev; > + struct cdns3_trb *trb = priv_req->trb; > + int current_index = 0; > + int handled = 0; > + > + current_index = (readl(&priv_dev->regs->ep_traddr) - > + priv_ep->trb_pool_dma) / TRB_SIZE; > + > + trb = &priv_ep->trb_pool[priv_req->start_trb]; > + > + if ((trb->control & TRB_CYCLE) != priv_ep->ccs) > + goto finish; > + > + if (priv_ep->dequeue < current_index) { > + if ((current_index == (priv_ep->num_trbs - 1)) && > + !priv_ep->dequeue) > + goto finish; > + > + if (priv_req->end_trb >= priv_ep->dequeue && > + priv_req->end_trb < current_index) > + handled = 1; > + } else if (priv_ep->dequeue > current_index) { > + if (priv_req->end_trb < current_index || > + priv_req->end_trb >= priv_ep->dequeue) > + handled = 1; > + } > + > +finish: > + trace_cdns3_request_handled(priv_req, current_index, handled); > + > + return handled; > +} > + > +static void cdns3_transfer_completed(struct cdns3_device *priv_dev, > + struct cdns3_endpoint *priv_ep) > +{ > + struct cdns3_request *priv_req; > + struct usb_request *request; > + struct cdns3_trb *trb; > + > + while (!list_empty(&priv_ep->pending_req_list)) { > + request = cdns3_next_request(&priv_ep->pending_req_list); > + priv_req = to_cdns3_request(request); > + > + /* Re-select endpoint. It could be changed by other CPU during > + * handling usb_gadget_giveback_request. > + */ > + cdns3_select_ep(priv_dev, priv_ep->endpoint.address); > + > + if (!cdns3_request_handled(priv_ep, priv_req)) > + return; > + > + if (request->dma % 8 && priv_ep->dir == USB_DIR_OUT) > + memcpy(request->buf, priv_ep->aligned_buff, > + request->length); > + > + trb = priv_ep->trb_pool + priv_ep->dequeue; > + trace_cdns3_complete_trb(priv_ep, trb); > + > + if (trb != priv_req->trb) > + dev_warn(priv_dev->dev, > + "request_trb=0x%p, queue_trb=0x%p\n", > + priv_req->trb, trb); > + > + request->actual = TRB_LEN(le32_to_cpu(trb->length)); > + cdns3_move_deq_to_next_trb(priv_req); > + cdns3_gadget_giveback(priv_ep, priv_req, 0); > + } > + priv_ep->flags &= ~EP_PENDING_REQUEST; > +} > + > +void cdns3_wa1_restore_cycle_bit(struct cdns3_endpoint *priv_ep) > +{ > + struct cdns3_device *priv_dev = priv_ep->cdns3_dev; > + > + /* Work around for stale data address in TRB*/ > + if (priv_ep->wa1_set) { > + cdns3_dbg(priv_dev, "WA1: update cycle bit\n"); > + priv_ep->wa1_set = 0; > + if (priv_ep->wa1_cycle_bit) { > + priv_ep->wa1_trb->control = > + priv_ep->wa1_trb->control | 0x1; > + } else { > + priv_ep->wa1_trb->control = > + priv_ep->wa1_trb->control & ~0x1; > + } > + } > +} > + > +void cdns3_rearm_transfer(struct cdns3_endpoint *priv_ep, u8 rearm) > +{ > + struct cdns3_device *priv_dev = priv_ep->cdns3_dev; > + > + cdns3_wa1_restore_cycle_bit(priv_ep); > + > + if (rearm) { > + trace_cdns3_ring(priv_ep); > + > + /* Cycle Bit must be updated before arming DMA. */ > + wmb(); > + writel(EP_CMD_DRDY, &priv_dev->regs->ep_cmd); > + > + trace_cdns3_doorbell_epx(priv_ep->name, > + readl(&priv_dev->regs->ep_traddr)); > + } > +} > + > +/** > + * cdns3_check_ep_interrupt_proceed - Processes interrupt related to endpoint > + * @priv_ep: endpoint object > + * > + * Returns 0 > + */ > +static int cdns3_check_ep_interrupt_proceed(struct cdns3_endpoint *priv_ep) > +{ > + struct cdns3_device *priv_dev = priv_ep->cdns3_dev; > + u32 ep_sts_reg; > + > + cdns3_select_ep(priv_dev, priv_ep->endpoint.address); > + > + trace_cdns3_epx_irq(priv_dev, priv_ep); > + > + ep_sts_reg = readl(&priv_dev->regs->ep_sts); > + writel(ep_sts_reg, &priv_dev->regs->ep_sts); > + > + if (ep_sts_reg & EP_STS_TRBERR) { > + /* > + * For isochronous transfer driver completes request on > + * IOC or on TRBERR. IOC appears only when device receive > + * OUT data packet. If host disable stream or lost some packet > + * then the only way to finish all queued transfer is to do it > + * on TRBERR event. > + */ > + if (priv_ep->type == USB_ENDPOINT_XFER_ISOC && > + !priv_ep->wa1_set) > + cdns3_transfer_completed(priv_dev, priv_ep); > + else > + cdns3_rearm_transfer(priv_ep, priv_ep->wa1_set); > + } > + > + if ((ep_sts_reg & EP_STS_IOC) || (ep_sts_reg & EP_STS_ISP)) > + cdns3_transfer_completed(priv_dev, priv_ep); > + > + return 0; > +} > + > +/** > + * cdns3_check_usb_interrupt_proceed - Processes interrupt related to device > + * @priv_dev: extended gadget object > + * @usb_ists: bitmap representation of device's reported interrupts > + * (usb_ists register value) > + */ > +static void cdns3_check_usb_interrupt_proceed(struct cdns3_device *priv_dev, > + u32 usb_ists) > +{ > + int speed = 0; > + > + trace_cdns3_usb_irq(priv_dev, usb_ists); > + /* Connection detected */ > + if (usb_ists & (USB_ISTS_CON2I | USB_ISTS_CONI)) { > + speed = cdns3_get_speed(priv_dev); > + priv_dev->gadget.speed = speed; > + usb_gadget_set_state(&priv_dev->gadget, USB_STATE_POWERED); > + cdns3_ep0_config(priv_dev); > + } > + > + /* Disconnection detected */ > + if (usb_ists & (USB_ISTS_DIS2I | USB_ISTS_DISI)) { > + if (priv_dev->gadget_driver && > + priv_dev->gadget_driver->disconnect) { > + spin_unlock(&priv_dev->lock); > + priv_dev->gadget_driver->disconnect(&priv_dev->gadget); > + spin_lock(&priv_dev->lock); > + } > + > + priv_dev->gadget.speed = USB_SPEED_UNKNOWN; > + usb_gadget_set_state(&priv_dev->gadget, USB_STATE_NOTATTACHED); > + cdns3_hw_reset_eps_config(priv_dev); > + } > + > + /* reset*/ > + if (usb_ists & (USB_ISTS_UWRESI | USB_ISTS_UHRESI | USB_ISTS_U2RESI)) { > + /*read again to check the actuall speed*/ > + speed = cdns3_get_speed(priv_dev); > + usb_gadget_set_state(&priv_dev->gadget, USB_STATE_DEFAULT); > + priv_dev->gadget.speed = speed; > + cdns3_hw_reset_eps_config(priv_dev); > + cdns3_ep0_config(priv_dev); > + } > +} > + > +/** > + * cdns3_device_irq_handler- interrupt handler for device part of controller > + * > + * @irq: irq number for cdns3 core device > + * @data: structure of cdns3 > + * > + * Returns IRQ_HANDLED or IRQ_NONE > + */ > +static irqreturn_t cdns3_device_irq_handler(int irq, void *data) > +{ > + struct cdns3_device *priv_dev; > + struct cdns3 *cdns = data; > + irqreturn_t ret = IRQ_NONE; > + unsigned long flags; > + u32 reg; > + > + priv_dev = cdns->gadget_dev; > + spin_lock_irqsave(&priv_dev->lock, flags); > + > + /* check USB device interrupt */ > + reg = readl(&priv_dev->regs->usb_ists); > + writel(reg, &priv_dev->regs->usb_ists); > + > + if (reg) { > + cdns3_check_usb_interrupt_proceed(priv_dev, reg); > + ret = IRQ_HANDLED; > + } > + > + /* check endpoint interrupt */ > + reg = readl(&priv_dev->regs->ep_ists); > + > + if (reg) { > + priv_dev->shadow_ep_en |= reg; > + reg = ~reg & readl(&priv_dev->regs->ep_ien); > + /* mask deferred interrupt. */ > + writel(reg, &priv_dev->regs->ep_ien); > + ret = IRQ_WAKE_THREAD; > + } > + > + spin_unlock_irqrestore(&priv_dev->lock, flags); > + return ret; > +} > + > +/** > + * cdns3_device_thread_irq_handler- interrupt handler for device part > + * of controller > + * > + * @irq: irq number for cdns3 core device > + * @data: structure of cdns3 > + * > + * Returns IRQ_HANDLED or IRQ_NONE > + */ > +static irqreturn_t cdns3_device_thread_irq_handler(int irq, void *data) > +{ > + struct cdns3_device *priv_dev; > + struct cdns3 *cdns = data; > + irqreturn_t ret = IRQ_NONE; > + unsigned long flags; > + u32 ep_ien; > + int bit; > + u32 reg; > + > + priv_dev = cdns->gadget_dev; > + spin_lock_irqsave(&priv_dev->lock, flags); > + > + reg = readl(&priv_dev->regs->ep_ists); > + > + /* handle default endpoint OUT */ > + if (reg & EP_ISTS_EP_OUT0) { > + cdns3_check_ep0_interrupt_proceed(priv_dev, USB_DIR_OUT); > + ret = IRQ_HANDLED; > + } > + > + /* handle default endpoint IN */ > + if (reg & EP_ISTS_EP_IN0) { > + cdns3_check_ep0_interrupt_proceed(priv_dev, USB_DIR_IN); > + ret = IRQ_HANDLED; > + } > + > + /* check if interrupt from non default endpoint, if no exit */ > + reg &= ~(EP_ISTS_EP_OUT0 | EP_ISTS_EP_IN0); > + if (!reg) > + goto irqend; > + > + for_each_set_bit(bit, (unsigned long *)®, > + sizeof(u32) * BITS_PER_BYTE) { > + priv_dev->shadow_ep_en |= BIT(bit); > + cdns3_check_ep_interrupt_proceed(priv_dev->eps[bit]); > + ret = IRQ_HANDLED; > + } > + > +irqend: > + ep_ien = readl(&priv_dev->regs->ep_ien) | priv_dev->shadow_ep_en; > + priv_dev->shadow_ep_en = 0; > + /* Unmask all handled EP interrupts */ > + writel(ep_ien, &priv_dev->regs->ep_ien); > + spin_unlock_irqrestore(&priv_dev->lock, flags); > + return ret; > +} > + > +/** > + * cdns3_ep_onchip_buffer_reserve - Try to reserve onchip buf for EP > + * > + * The real reservation will occur during write to EP_CFG register, > + * this function is used to check if the 'size' reservation is allowed. > + * > + * @priv_dev: extended gadget object > + * @size: the size (KB) for EP would like to allocate > + * > + * Return 0 if the required size can met or negative value on failure > + */ > +static int cdns3_ep_onchip_buffer_reserve(struct cdns3_device *priv_dev, > + int size) > +{ > + u32 onchip_mem; > + > + priv_dev->onchip_mem_allocated_size += size; > + > + onchip_mem = USB_CAP2_ACTUAL_MEM_SIZE(readl(&priv_dev->regs->usb_cap2)); > + if (!onchip_mem) > + onchip_mem = 256; > + > + /* 2KB is reserved for EP0*/ > + onchip_mem -= 2; > + if (priv_dev->onchip_mem_allocated_size > onchip_mem) { > + priv_dev->onchip_mem_allocated_size -= size; > + return -EPERM; > + } > + > + return 0; > +} > + > +/** > + * cdns3_ep_config Configure hardware endpoint > + * @priv_ep: extended endpoint object > + */ > +void cdns3_ep_config(struct cdns3_endpoint *priv_ep) > +{ > + bool is_iso_ep = (priv_ep->type == USB_ENDPOINT_XFER_ISOC); > + struct cdns3_device *priv_dev = priv_ep->cdns3_dev; > + u32 bEndpointAddress = priv_ep->num | priv_ep->dir; > + u32 buffering = CDNS3_EP_BUF_SIZE - 1; > + u32 max_packet_size = 0; > + u32 ep_cfg = 0; > + int ret; > + > + switch (priv_ep->type) { > + case USB_ENDPOINT_XFER_INT: > + ep_cfg = EP_CFG_EPTYPE(USB_ENDPOINT_XFER_INT); > + break; > + case USB_ENDPOINT_XFER_BULK: > + ep_cfg = EP_CFG_EPTYPE(USB_ENDPOINT_XFER_BULK); > + break; > + default: > + ep_cfg = EP_CFG_EPTYPE(USB_ENDPOINT_XFER_ISOC); > + buffering = priv_ep->endpoint.mult + 1; > + } > + > + switch (priv_dev->gadget.speed) { > + case USB_SPEED_FULL: > + max_packet_size = is_iso_ep ? 1023 : 64; > + break; > + case USB_SPEED_HIGH: > + max_packet_size = is_iso_ep ? 1024 : 512; > + break; > + case USB_SPEED_SUPER: > + max_packet_size = 1024; > + if (priv_ep->type == USB_ENDPOINT_XFER_ISOC) { > + buffering = (priv_ep->endpoint.mult + 1) * > + (priv_ep->endpoint.maxburst + 1); > + > + if (priv_ep->interval > 1) > + buffering++; > + } > + break; > + default: > + /* all other speed are not supported */ > + return; > + } > + > + ret = cdns3_ep_onchip_buffer_reserve(priv_dev, buffering); > + if (ret) { > + dev_err(priv_dev->dev, "onchip mem is full, ep is invalid\n"); > + return; > + } > + > + ep_cfg |= EP_CFG_MAXPKTSIZE(max_packet_size) | > + EP_CFG_MULT(priv_ep->endpoint.mult) | > + EP_CFG_BUFFERING(buffering) | > + EP_CFG_MAXBURST(priv_ep->endpoint.maxburst); > + > + cdns3_select_ep(priv_dev, bEndpointAddress); > + writel(ep_cfg, &priv_dev->regs->ep_cfg); > + > + dev_dbg(priv_dev->dev, "Configure %s: with val %08x\n", > + priv_ep->name, ep_cfg); > +} > + > +/* Find correct direction for HW endpoint according to description */ > +static int cdns3_ep_dir_is_correct(struct usb_endpoint_descriptor *desc, > + struct cdns3_endpoint *priv_ep) > +{ > + return (priv_ep->endpoint.caps.dir_in && usb_endpoint_dir_in(desc)) || > + (priv_ep->endpoint.caps.dir_out && usb_endpoint_dir_out(desc)); > +} > + > +static struct > +cdns3_endpoint *cdns3_find_available_ep(struct cdns3_device *priv_dev, > + struct usb_endpoint_descriptor *desc) > +{ > + struct usb_ep *ep; > + struct cdns3_endpoint *priv_ep; > + > + list_for_each_entry(ep, &priv_dev->gadget.ep_list, ep_list) { > + unsigned long num; > + int ret; > + /* ep name pattern likes epXin or epXout */ > + char c[2] = {ep->name[2], '\0'}; > + > + ret = kstrtoul(c, 10, &num); > + if (ret) > + return ERR_PTR(ret); > + > + priv_ep = ep_to_cdns3_ep(ep); > + if (cdns3_ep_dir_is_correct(desc, priv_ep)) { > + if (!(priv_ep->flags & EP_CLAIMED)) { > + priv_ep->num = num; > + return priv_ep; > + } > + } > + } > + > + return ERR_PTR(-ENOENT); > +} > + > +/* > + * Cadence IP has one limitation that all endpoints must be configured > + * (Type & MaxPacketSize) before setting configuration through hardware > + * register, it means we can't change endpoints configuration after > + * set_configuration. > + * > + * This function set EP_CLAIMED flag which is added when the gadget driver > + * uses usb_ep_autoconfig to configure specific endpoint; > + * When the udc driver receives set_configurion request, > + * it goes through all claimed endpoints, and configure all endpoints > + * accordingly. > + * > + * At usb_ep_ops.enable/disable, we only enable and disable endpoint through > + * ep_cfg register which can be changed after set_configuration, and do > + * some software operation accordingly. > + */ > +static struct > +usb_ep *cdns3_gadget_match_ep(struct usb_gadget *gadget, > + struct usb_endpoint_descriptor *desc, > + struct usb_ss_ep_comp_descriptor *comp_desc) > +{ > + struct cdns3_device *priv_dev = gadget_to_cdns3_device(gadget); > + struct cdns3_endpoint *priv_ep; > + unsigned long flags; > + > + priv_ep = cdns3_find_available_ep(priv_dev, desc); > + if (IS_ERR(priv_ep)) { > + dev_err(priv_dev->dev, "no available ep\n"); > + return NULL; > + } > + > + dev_dbg(priv_dev->dev, "match endpoint: %s\n", priv_ep->name); > + > + spin_lock_irqsave(&priv_dev->lock, flags); > + priv_ep->endpoint.desc = desc; > + priv_ep->dir = usb_endpoint_dir_in(desc) ? USB_DIR_IN : USB_DIR_OUT; > + priv_ep->type = usb_endpoint_type(desc); > + priv_ep->flags |= EP_CLAIMED; > + priv_ep->interval = desc->bInterval ? BIT(desc->bInterval - 1) : 0; > + > + spin_unlock_irqrestore(&priv_dev->lock, flags); > + return &priv_ep->endpoint; > +} > + > +/** > + * cdns3_gadget_ep_alloc_request Allocates request > + * @ep: endpoint object associated with request > + * @gfp_flags: gfp flags > + * > + * Returns allocated request address, NULL on allocation error > + */ > +struct usb_request *cdns3_gadget_ep_alloc_request(struct usb_ep *ep, > + gfp_t gfp_flags) > +{ > + struct cdns3_endpoint *priv_ep = ep_to_cdns3_ep(ep); > + struct cdns3_request *priv_req; > + > + priv_req = kzalloc(sizeof(*priv_req), gfp_flags); > + if (!priv_req) > + return NULL; > + > + priv_req->priv_ep = priv_ep; > + > + trace_cdns3_alloc_request(priv_req); > + return &priv_req->request; > +} > + > +/** > + * cdns3_gadget_ep_free_request Free memory occupied by request > + * @ep: endpoint object associated with request > + * @request: request to free memory > + */ > +void cdns3_gadget_ep_free_request(struct usb_ep *ep, > + struct usb_request *request) > +{ > + struct cdns3_request *priv_req = to_cdns3_request(request); > + > + trace_cdns3_free_request(priv_req); > + kfree(priv_req); > +} > + > +/** > + * cdns3_gadget_ep_enable Enable endpoint > + * @ep: endpoint object > + * @desc: endpoint descriptor > + * > + * Returns 0 on success, error code elsewhere > + */ > +static int cdns3_gadget_ep_enable(struct usb_ep *ep, > + const struct usb_endpoint_descriptor *desc) > +{ > + struct cdns3_endpoint *priv_ep; > + struct cdns3_device *priv_dev; > + u32 reg = EP_STS_EN_TRBERREN; > + u32 bEndpointAddress; > + unsigned long flags; > + int ret; > + > + priv_ep = ep_to_cdns3_ep(ep); > + priv_dev = priv_ep->cdns3_dev; > + > + if (!ep || !desc || desc->bDescriptorType != USB_DT_ENDPOINT) { > + dev_dbg(priv_dev->dev, "usbss: invalid parameters\n"); > + return -EINVAL; > + } > + > + if (!desc->wMaxPacketSize) { > + dev_err(priv_dev->dev, "usbss: missing wMaxPacketSize\n"); > + return -EINVAL; > + } > + > + if (dev_WARN_ONCE(priv_dev->dev, priv_ep->flags & EP_ENABLED, > + "%s is already enabled\n", priv_ep->name)) > + return 0; > + > + spin_lock_irqsave(&priv_dev->lock, flags); > + > + priv_ep->endpoint.desc = desc; > + priv_ep->type = usb_endpoint_type(desc); > + priv_ep->interval = desc->bInterval ? BIT(desc->bInterval - 1) : 0; > + > + if (priv_ep->interval > ISO_MAX_INTERVAL && > + priv_ep->type == USB_ENDPOINT_XFER_ISOC) { > + dev_err(priv_dev->dev, "Driver is limited to %d period\n", > + ISO_MAX_INTERVAL); > + > + ret = -EINVAL; > + goto exit; > + } > + > + ret = cdns3_allocate_trb_pool(priv_ep); > + > + if (ret) > + goto exit; > + > + bEndpointAddress = priv_ep->num | priv_ep->dir; > + cdns3_select_ep(priv_dev, bEndpointAddress); > + > + trace_cdns3_gadget_ep_enable(priv_ep); > + > + writel(EP_CMD_EPRST, &priv_dev->regs->ep_cmd); > + > + ret = cdns3_handshake(&priv_dev->regs->ep_cmd, > + EP_CMD_CSTALL | EP_CMD_EPRST, 0, 100); > + > + /* enable interrupt for selected endpoint */ > + cdns3_set_register_bit(&priv_dev->regs->ep_ien, > + BIT(cdns3_ep_addr_to_index(bEndpointAddress))); > + > + writel(reg, &priv_dev->regs->ep_sts_en); > + > + cdns3_set_register_bit(&priv_dev->regs->ep_cfg, EP_CFG_ENABLE); > + > + ep->desc = desc; > + priv_ep->flags &= ~(EP_PENDING_REQUEST | EP_STALL); > + priv_ep->flags |= EP_ENABLED | EP_UPDATE_EP_TRBADDR; > + priv_ep->wa1_set = 0; > + priv_ep->enqueue = 0; > + priv_ep->dequeue = 0; > + reg = readl(&priv_dev->regs->ep_sts); > + priv_ep->pcs = !!EP_STS_CCS(reg); > + priv_ep->ccs = !!EP_STS_CCS(reg); > + /* one TRB is reserved for link TRB used in DMULT mode*/ > + priv_ep->free_trbs = priv_ep->num_trbs - 1; > +exit: > + spin_unlock_irqrestore(&priv_dev->lock, flags); > + > + return ret; > +} > + > +/** > + * cdns3_gadget_ep_disable Disable endpoint > + * @ep: endpoint object > + * > + * Returns 0 on success, error code elsewhere > + */ > +static int cdns3_gadget_ep_disable(struct usb_ep *ep) > +{ > + struct cdns3_endpoint *priv_ep; > + struct cdns3_device *priv_dev; > + struct usb_request *request; > + unsigned long flags; > + int ret = 0; > + u32 ep_cfg; > + > + if (!ep) { > + pr_err("usbss: invalid parameters\n"); > + return -EINVAL; > + } > + > + priv_ep = ep_to_cdns3_ep(ep); > + priv_dev = priv_ep->cdns3_dev; > + > + if (dev_WARN_ONCE(priv_dev->dev, !(priv_ep->flags & EP_ENABLED), > + "%s is already disabled\n", priv_ep->name)) > + return 0; > + > + spin_lock_irqsave(&priv_dev->lock, flags); > + > + trace_cdns3_gadget_ep_disable(priv_ep); > + > + cdns3_select_ep(priv_dev, ep->desc->bEndpointAddress); > + ret = cdns3_data_flush(priv_ep); > + > + ep_cfg = readl(&priv_dev->regs->ep_cfg); > + ep_cfg &= ~EP_CFG_ENABLE; > + writel(ep_cfg, &priv_dev->regs->ep_cfg); > + > + while (!list_empty(&priv_ep->pending_req_list)) { > + request = cdns3_next_request(&priv_ep->pending_req_list); > + > + cdns3_gadget_giveback(priv_ep, to_cdns3_request(request), > + -ESHUTDOWN); > + } > + > + while (!list_empty(&priv_ep->deferred_req_list)) { > + request = cdns3_next_request(&priv_ep->deferred_req_list); > + > + cdns3_gadget_giveback(priv_ep, to_cdns3_request(request), > + -ESHUTDOWN); > + } > + > + priv_ep->descmis_req = NULL; > + > + ep->desc = NULL; > + priv_ep->flags &= ~EP_ENABLED; > + > + spin_unlock_irqrestore(&priv_dev->lock, flags); > + > + return ret; > +} > + > +/** > + * cdns3_gadget_ep_queue Transfer data on endpoint > + * @ep: endpoint object > + * @request: request object > + * @gfp_flags: gfp flags > + * > + * Returns 0 on success, error code elsewhere > + */ > +static int __cdns3_gadget_ep_queue(struct usb_ep *ep, > + struct usb_request *request, > + gfp_t gfp_flags) > +{ > + struct cdns3_endpoint *priv_ep = ep_to_cdns3_ep(ep); > + struct cdns3_device *priv_dev = priv_ep->cdns3_dev; > + struct cdns3_request *priv_req; > + int deferred = 0; > + int ret = 0; > + > + request->actual = 0; > + request->status = -EINPROGRESS; > + priv_req = to_cdns3_request(request); > + trace_cdns3_ep_queue(priv_req); > + > + ret = usb_gadget_map_request_by_dev(priv_dev->sysdev, request, > + usb_endpoint_dir_in(ep->desc)); > + if (ret) > + return ret; > + > + /* > + * If hardware endpoint configuration has not been set yet then > + * just queue request in deferred list. Transfer will be started in > + * cdns3_set_hw_configuration. > + */ > + if (!priv_dev->hw_configured_flag) > + deferred = 1; > + else > + ret = cdns3_ep_run_transfer(priv_ep, request); > + > + if (ret || deferred) > + list_add_tail(&request->list, &priv_ep->deferred_req_list); > + else > + list_add_tail(&request->list, &priv_ep->pending_req_list); > + > + return ret; > +} > + > +static int cdns3_gadget_ep_queue(struct usb_ep *ep, struct usb_request *request, > + gfp_t gfp_flags) > +{ > + struct usb_request *zlp_request; > + struct cdns3_endpoint *priv_ep; > + struct cdns3_device *priv_dev; > + unsigned long flags; > + int ret; > + > + if (!request || !ep) > + return -EINVAL; > + > + priv_ep = ep_to_cdns3_ep(ep); > + priv_dev = priv_ep->cdns3_dev; > + > + spin_lock_irqsave(&priv_dev->lock, flags); > + > + ret = __cdns3_gadget_ep_queue(ep, request, gfp_flags); > + > + if (ret == 0 && request->zero && request->length && > + (request->length % ep->maxpacket == 0)) { > + struct cdns3_request *priv_req; > + > + zlp_request = cdns3_gadget_ep_alloc_request(ep, GFP_ATOMIC); > + zlp_request->buf = priv_dev->zlp_buf; > + zlp_request->length = 0; > + > + priv_req = to_cdns3_request(zlp_request); > + priv_req->flags |= REQUEST_ZLP; > + > + dev_dbg(priv_dev->dev, "Queuing ZLP for endpoint: %s\n", > + priv_ep->name); > + ret = __cdns3_gadget_ep_queue(ep, zlp_request, gfp_flags); > + } > + > + spin_unlock_irqrestore(&priv_dev->lock, flags); > + return ret; > +} > + > +/** > + * cdns3_gadget_ep_dequeue Remove request from transfer queue > + * @ep: endpoint object associated with request > + * @request: request object > + * > + * Returns 0 on success, error code elsewhere > + */ > +int cdns3_gadget_ep_dequeue(struct usb_ep *ep, > + struct usb_request *request) > +{ > + struct cdns3_endpoint *priv_ep = ep_to_cdns3_ep(ep); > + struct cdns3_device *priv_dev = priv_ep->cdns3_dev; > + struct usb_request *req, *req_temp; > + struct cdns3_request *priv_req; > + struct cdns3_trb *link_trb; > + unsigned long flags; > + int ret = 0; > + > + if (!ep || !request || !ep->desc) > + return -EINVAL; > + > + spin_lock_irqsave(&priv_dev->lock, flags); > + > + priv_req = to_cdns3_request(request); > + > + trace_cdns3_ep_dequeue(priv_req); > + > + cdns3_select_ep(priv_dev, ep->desc->bEndpointAddress); > + > + list_for_each_entry_safe(req, req_temp, &priv_ep->pending_req_list, > + list) { > + if (request == req) > + goto found; > + } > + > + list_for_each_entry_safe(req, req_temp, &priv_ep->deferred_req_list, > + list) { > + if (request == req) > + goto found; > + } > + > + goto not_found; > + > +found: > + > + if (priv_ep->wa1_trb == priv_req->trb) > + cdns3_wa1_restore_cycle_bit(priv_ep); > + > + link_trb = priv_req->trb; > + cdns3_move_deq_to_next_trb(priv_req); > + cdns3_gadget_giveback(priv_ep, priv_req, -ECONNRESET); > + > + /* Update ring */ > + request = cdns3_next_request(&priv_ep->deferred_req_list); > + if (request) { > + priv_req = to_cdns3_request(request); > + > + link_trb->buffer = TRB_BUFFER(priv_ep->trb_pool_dma + > + (priv_req->start_trb * TRB_SIZE)); > + link_trb->control = (link_trb->control & TRB_CYCLE) | > + TRB_TYPE(TRB_LINK) | TRB_CHAIN | TRB_TOGGLE; > + } else { > + priv_ep->flags |= EP_UPDATE_EP_TRBADDR; > + } > + > +not_found: > + spin_unlock_irqrestore(&priv_dev->lock, flags); > + return ret; > +} > + > +/** > + * cdns3_gadget_ep_set_halt Sets/clears stall on selected endpoint > + * @ep: endpoint object to set/clear stall on > + * @value: 1 for set stall, 0 for clear stall > + * > + * Returns 0 on success, error code elsewhere > + */ > +int cdns3_gadget_ep_set_halt(struct usb_ep *ep, int value) > +{ > + struct cdns3_endpoint *priv_ep = ep_to_cdns3_ep(ep); > + struct cdns3_device *priv_dev = priv_ep->cdns3_dev; > + unsigned long flags; > + int ret = 0; > + > + if (!(priv_ep->flags & EP_ENABLED)) > + return -EPERM; > + > + spin_lock_irqsave(&priv_dev->lock, flags); > + > + cdns3_select_ep(priv_dev, ep->desc->bEndpointAddress); > + if (value) { > + cdns3_ep_stall_flush(priv_ep); > + } else { > + priv_ep->flags &= ~EP_WEDGE; > + > + cdns3_dbg(priv_ep->cdns3_dev, "Clear stalled endpoint %s\n", > + priv_ep->name); > + > + writel(EP_CMD_CSTALL | EP_CMD_EPRST, &priv_dev->regs->ep_cmd); > + > + /* wait for EPRST cleared */ > + ret = cdns3_handshake(&priv_dev->regs->ep_cmd, > + EP_CMD_EPRST, 0, 100); > + if (unlikely(ret)) { > + dev_err(priv_dev->dev, > + "Clearing halt condition failed for %s\n", > + priv_ep->name); > + goto finish; > + > + } else { > + priv_ep->flags &= ~EP_STALL; > + } > + } > + > + priv_ep->flags &= ~EP_PENDING_REQUEST; > +finish: > + spin_unlock_irqrestore(&priv_dev->lock, flags); > + > + return ret; > +} > + > +extern const struct usb_ep_ops cdns3_gadget_ep0_ops; > + > +static const struct usb_ep_ops cdns3_gadget_ep_ops = { > + .enable = cdns3_gadget_ep_enable, > + .disable = cdns3_gadget_ep_disable, > + .alloc_request = cdns3_gadget_ep_alloc_request, > + .free_request = cdns3_gadget_ep_free_request, > + .queue = cdns3_gadget_ep_queue, > + .dequeue = cdns3_gadget_ep_dequeue, > + .set_halt = cdns3_gadget_ep_set_halt, > + .set_wedge = cdns3_gadget_ep_set_wedge, > +}; > + > +/** > + * cdns3_gadget_get_frame Returns number of actual ITP frame > + * @gadget: gadget object > + * > + * Returns number of actual ITP frame > + */ > +static int cdns3_gadget_get_frame(struct usb_gadget *gadget) > +{ > + struct cdns3_device *priv_dev = gadget_to_cdns3_device(gadget); > + > + return readl(&priv_dev->regs->usb_iptn); > +} > + > +static int cdns3_gadget_wakeup(struct usb_gadget *gadget) > +{ > + return 0; > +} > + > +static int cdns3_gadget_set_selfpowered(struct usb_gadget *gadget, > + int is_selfpowered) > +{ > + struct cdns3_device *priv_dev = gadget_to_cdns3_device(gadget); > + unsigned long flags; > + > + spin_lock_irqsave(&priv_dev->lock, flags); > + priv_dev->is_selfpowered = !!is_selfpowered; > + spin_unlock_irqrestore(&priv_dev->lock, flags); > + return 0; > +} > + > +static int cdns3_gadget_pullup(struct usb_gadget *gadget, int is_on) > +{ > + struct cdns3_device *priv_dev = gadget_to_cdns3_device(gadget); > + > + if (is_on) > + writel(USB_CONF_DEVEN, &priv_dev->regs->usb_conf); > + else > + writel(USB_CONF_DEVDS, &priv_dev->regs->usb_conf); > + > + return 0; > +} > + > +static void cdns3_gadget_config(struct cdns3_device *priv_dev) > +{ > + struct cdns3_usb_regs __iomem *regs = priv_dev->regs; > + > + cdns3_ep0_config(priv_dev); > + > + /* enable interrupts for endpoint 0 (in and out) */ > + writel(EP_IEN_EP_OUT0 | EP_IEN_EP_IN0, ®s->ep_ien); > + > + /* > + *Driver need modify LFPS minimal U1 Exit time for 0x00024505 revision > + * of controller > + */ > + if (priv_dev->dev_ver == 0x00024505) { > + u32 reg = readl(®s->dbg_link1); > + > + reg &= ~DBG_LINK1_LFPS_MIN_GEN_U1_EXIT_MASK; > + reg |= DBG_LINK1_LFPS_MIN_GEN_U1_EXIT(0x55) | > + DBG_LINK1_LFPS_MIN_GEN_U1_EXIT_SET; > + writel(reg, ®s->dbg_link1); > + } > + > + /* enable generic interrupt*/ > + writel(USB_IEN_INIT, ®s->usb_ien); > + writel(USB_CONF_CLK2OFFDS | USB_CONF_L1DS, ®s->usb_conf); > + writel(USB_CONF_DMULT, ®s->usb_conf); > + cdns3_gadget_pullup(&priv_dev->gadget, 1); > +} > + > +/** > + * cdns3_gadget_udc_start Gadget start > + * @gadget: gadget object > + * @driver: driver which operates on this gadget > + * > + * Returns 0 on success, error code elsewhere > + */ > +static int cdns3_gadget_udc_start(struct usb_gadget *gadget, > + struct usb_gadget_driver *driver) > +{ > + struct cdns3_device *priv_dev = gadget_to_cdns3_device(gadget); > + unsigned long flags; > + > + spin_lock_irqsave(&priv_dev->lock, flags); > + priv_dev->gadget_driver = driver; > + cdns3_gadget_config(priv_dev); > + spin_unlock_irqrestore(&priv_dev->lock, flags); > + return 0; > +} > + > +/** > + * cdns3_gadget_udc_stop Stops gadget > + * @gadget: gadget object > + * > + * Returns 0 > + */ > +static int cdns3_gadget_udc_stop(struct usb_gadget *gadget) > +{ > + struct cdns3_device *priv_dev = gadget_to_cdns3_device(gadget); > + struct cdns3_endpoint *priv_ep; > + u32 bEndpointAddress; > + struct usb_ep *ep; > + int ret = 0; > + > + priv_dev->gadget_driver = NULL; > + > + priv_dev->onchip_mem_allocated_size = 0; > + priv_dev->gadget.speed = USB_SPEED_UNKNOWN; > + > + list_for_each_entry(ep, &priv_dev->gadget.ep_list, ep_list) { > + priv_ep = ep_to_cdns3_ep(ep); > + bEndpointAddress = priv_ep->num | priv_ep->dir; > + cdns3_select_ep(priv_dev, bEndpointAddress); > + writel(EP_CMD_EPRST, &priv_dev->regs->ep_cmd); > + ret = cdns3_handshake(&priv_dev->regs->ep_cmd, > + EP_CMD_EPRST, 0, 100); > + cdns3_free_trb_pool(priv_ep); > + } > + > + /* disable interrupt for device */ > + writel(0, &priv_dev->regs->usb_ien); > + writel(USB_CONF_DEVDS, &priv_dev->regs->usb_conf); > + > + return ret; > +} > + > +static const struct usb_gadget_ops cdns3_gadget_ops = { > + .get_frame = cdns3_gadget_get_frame, > + .wakeup = cdns3_gadget_wakeup, > + .set_selfpowered = cdns3_gadget_set_selfpowered, > + .pullup = cdns3_gadget_pullup, > + .udc_start = cdns3_gadget_udc_start, > + .udc_stop = cdns3_gadget_udc_stop, > + .match_ep = cdns3_gadget_match_ep, > +}; > + > +static void cdns3_free_all_eps(struct cdns3_device *priv_dev) > +{ > + int i; > + > + /*ep0 OUT point to ep0 IN*/ > + priv_dev->eps[16] = NULL; > + > + cdns3_free_trb_pool(priv_dev->eps[0]); > + > + for (i = 0; i < CDNS3_ENDPOINTS_MAX_COUNT; i++) > + if (priv_dev->eps[i]) > + devm_kfree(priv_dev->dev, priv_dev->eps[i]); > +} > + > +/** > + * cdns3_init_eps Initializes software endpoints of gadget > + * @cdns3: extended gadget object > + * > + * Returns 0 on success, error code elsewhere > + */ > +static int cdns3_init_eps(struct cdns3_device *priv_dev) > +{ > + u32 ep_enabled_reg, iso_ep_reg; > + struct cdns3_endpoint *priv_ep; > + int ep_dir, ep_number; > + u32 ep_mask; > + int ret = 0; > + int i; > + > + /* Read it from USB_CAP3 to USB_CAP5 */ > + ep_enabled_reg = readl(&priv_dev->regs->usb_cap3); > + iso_ep_reg = readl(&priv_dev->regs->usb_cap4); > + > + dev_dbg(priv_dev->dev, "Initializing non-zero endpoints\n"); > + > + for (i = 0; i < CDNS3_ENDPOINTS_MAX_COUNT; i++) { > + ep_dir = i >> 4; /* i div 16 */ > + ep_number = i & 0xF; /* i % 16 */ > + ep_mask = BIT(i); > + > + if (!(ep_enabled_reg & ep_mask)) > + continue; > + > + if (ep_dir && !ep_number) { > + priv_dev->eps[i] = priv_dev->eps[0]; > + continue; > + } > + > + priv_ep = devm_kzalloc(priv_dev->dev, sizeof(*priv_ep), > + GFP_KERNEL); > + if (!priv_ep) { > + ret = -ENOMEM; > + goto err; > + } > + > + /* set parent of endpoint object */ > + priv_ep->cdns3_dev = priv_dev; > + priv_dev->eps[i] = priv_ep; > + priv_ep->num = ep_number; > + priv_ep->dir = ep_dir ? USB_DIR_IN : USB_DIR_OUT; > + > + if (!ep_number) { > + ret = cdns3_init_ep0(priv_dev, priv_ep); > + if (ret) { > + dev_err(priv_dev->dev, "Failed to init ep0\n"); > + goto err; > + } > + } else { > + snprintf(priv_ep->name, sizeof(priv_ep->name), "ep%d%s", > + ep_number, !!ep_dir ? "in" : "out"); > + priv_ep->endpoint.name = priv_ep->name; > + > + usb_ep_set_maxpacket_limit(&priv_ep->endpoint, > + CDNS3_EP_MAX_PACKET_LIMIT); > + priv_ep->endpoint.max_streams = CDNS3_EP_MAX_STREAMS; > + priv_ep->endpoint.ops = &cdns3_gadget_ep_ops; > + if (ep_dir) > + priv_ep->endpoint.caps.dir_in = 1; > + else > + priv_ep->endpoint.caps.dir_out = 1; > + > + if (iso_ep_reg & ep_mask) > + priv_ep->endpoint.caps.type_iso = 1; > + > + priv_ep->endpoint.caps.type_bulk = 1; > + priv_ep->endpoint.caps.type_int = 1; > + priv_ep->endpoint.maxburst = CDNS3_EP_BUF_SIZE - 1; > + > + list_add_tail(&priv_ep->endpoint.ep_list, > + &priv_dev->gadget.ep_list); > + } > + > + priv_ep->flags = 0; > + > + dev_info(priv_dev->dev, "Initialized %s support: %s %s\n", > + priv_ep->name, > + priv_ep->endpoint.caps.type_bulk ? "BULK, INT" : "", > + priv_ep->endpoint.caps.type_iso ? "ISO" : ""); > + > + INIT_LIST_HEAD(&priv_ep->pending_req_list); > + INIT_LIST_HEAD(&priv_ep->deferred_req_list); > + } > + > + return 0; > +err: > + cdns3_free_all_eps(priv_dev); > + return -ENOMEM; > +} > + > +static void cdns3_gadget_disable(struct cdns3 *cdns) > +{ > + struct cdns3_device *priv_dev; > + > + priv_dev = cdns->gadget_dev; > + > + if (priv_dev->gadget_driver) > + priv_dev->gadget_driver->disconnect(&priv_dev->gadget); > + > + usb_gadget_disconnect(&priv_dev->gadget); > + priv_dev->gadget.speed = USB_SPEED_UNKNOWN; > +} > + > +void cdns3_gadget_exit(struct cdns3 *cdns) > +{ > + struct cdns3_device *priv_dev; > + > + priv_dev = cdns->gadget_dev; > + > + cdns3_gadget_disable(cdns); > + > + devm_free_irq(cdns->dev, cdns->irq, cdns); > + > + pm_runtime_mark_last_busy(cdns->dev); > + pm_runtime_put_autosuspend(cdns->dev); > + > + usb_del_gadget_udc(&priv_dev->gadget); > + > + cdns3_free_all_eps(priv_dev); > + > + dma_free_coherent(priv_dev->sysdev, 8, priv_dev->setup_buf, > + priv_dev->setup_dma); > + > + kfree(priv_dev->zlp_buf); > + kfree(priv_dev); > + cdns->gadget_dev = NULL; > +} > + > +static int cdns3_gadget_start(struct cdns3 *cdns) > +{ > + struct cdns3_device *priv_dev; > + u32 max_speed; > + int ret; > + > + priv_dev = kzalloc(sizeof(*priv_dev), GFP_KERNEL); > + if (!priv_dev) > + return -ENOMEM; > + > + cdns->gadget_dev = priv_dev; > + priv_dev->sysdev = cdns->dev; > + priv_dev->dev = cdns->dev; > + priv_dev->regs = cdns->dev_regs; > + > + max_speed = usb_get_maximum_speed(cdns->dev); > + > + /* Check the maximum_speed parameter */ > + switch (max_speed) { > + case USB_SPEED_FULL: > + case USB_SPEED_HIGH: > + case USB_SPEED_SUPER: > + break; > + default: > + dev_err(cdns->dev, "invalid maximum_speed parameter %d\n", > + max_speed); > + /* fall through */ > + case USB_SPEED_UNKNOWN: > + /* default to superspeed */ > + max_speed = USB_SPEED_SUPER; > + break; > + } > + > + /* fill gadget fields */ > + priv_dev->gadget.max_speed = max_speed; > + priv_dev->gadget.speed = USB_SPEED_UNKNOWN; > + priv_dev->gadget.ops = &cdns3_gadget_ops; > + priv_dev->gadget.name = "usb-ss-gadget"; > + priv_dev->gadget.sg_supported = 1; > + > + spin_lock_init(&priv_dev->lock); > + INIT_WORK(&priv_dev->pending_status_wq, > + cdns3_pending_setup_status_handler); > + > + /* initialize endpoint container */ > + INIT_LIST_HEAD(&priv_dev->gadget.ep_list); > + > + ret = cdns3_init_eps(priv_dev); > + if (ret) { > + dev_err(priv_dev->dev, "Failed to create endpoints\n"); > + goto err1; > + } > + > + /* allocate memory for setup packet buffer */ > + priv_dev->setup_buf = dma_alloc_coherent(priv_dev->sysdev, 8, > + &priv_dev->setup_dma, GFP_DMA); > + if (!priv_dev->setup_buf) { > + dev_err(priv_dev->dev, "Failed to allocate memory for SETUP buffer\n"); > + ret = -ENOMEM; > + goto err2; > + } > + > + priv_dev->dev_ver = readl(&priv_dev->regs->usb_cap6); > + dev_dbg(priv_dev->dev, "Device Controller version: %08x\n", > + readl(&priv_dev->regs->usb_cap6)); > + dev_dbg(priv_dev->dev, "USB Capabilities:: %08x\n", > + readl(&priv_dev->regs->usb_cap1)); > + dev_dbg(priv_dev->dev, "On-Chip memory cnfiguration: %08x\n", > + readl(&priv_dev->regs->usb_cap2)); > + > + priv_dev->zlp_buf = kzalloc(CDNS3_EP_ZLP_BUF_SIZE, GFP_KERNEL); > + if (!priv_dev->zlp_buf) { > + ret = -ENOMEM; > + goto err3; > + } > + > + /* add USB gadget device */ > + ret = usb_add_gadget_udc(priv_dev->dev, &priv_dev->gadget); > + if (ret < 0) { > + dev_err(priv_dev->dev, > + "Failed to register USB device controller\n"); > + goto err4; > + } > + > + return 0; > +err4: > + kfree(priv_dev->zlp_buf); > +err3: > + dma_free_coherent(priv_dev->sysdev, 8, priv_dev->setup_buf, > + priv_dev->setup_dma); > +err2: > + cdns3_free_all_eps(priv_dev); > +err1: > + cdns->gadget_dev = NULL; > + return ret; > +} > + > +static int __cdns3_gadget_init(struct cdns3 *cdns) > +{ > + struct cdns3_device *priv_dev; > + unsigned long flags; > + int ret = 0; > + > + ret = cdns3_gadget_start(cdns); > + if (ret) > + return ret; > + > + priv_dev = cdns->gadget_dev; > + ret = devm_request_threaded_irq(cdns->dev, cdns->irq, > + cdns3_device_irq_handler, > + cdns3_device_thread_irq_handler, > + IRQF_SHARED, dev_name(cdns->dev), cdns); > + if (ret) > + goto err0; > + > + pm_runtime_get_sync(cdns->dev); > + spin_lock_irqsave(&priv_dev->lock, flags); > + spin_unlock_irqrestore(&priv_dev->lock, flags); > + return 0; > +err0: > + cdns3_gadget_exit(cdns); > + return ret; > +} > + > +static int cdns3_gadget_suspend(struct cdns3 *cdns, bool do_wakeup) > +{ > + cdns3_gadget_disable(cdns); > + return 0; > +} > + > +static int cdns3_gadget_resume(struct cdns3 *cdns, bool hibernated) > +{ > + struct cdns3_device *priv_dev; > + unsigned long flags; > + > + priv_dev = cdns->gadget_dev; > + spin_lock_irqsave(&priv_dev->lock, flags); > + > + if (!priv_dev->gadget_driver) { > + spin_unlock_irqrestore(&priv_dev->lock, flags); > + return 0; > + } > + > + cdns3_gadget_config(priv_dev); > + spin_unlock_irqrestore(&priv_dev->lock, flags); > + return 0; > +} > + > +/** > + * cdns3_gadget_init - initialize device structure > + * > + * cdns: cdns3 instance > + * > + * This function initializes the gadget. > + */ > +int cdns3_gadget_init(struct cdns3 *cdns) > +{ > + struct cdns3_role_driver *rdrv; > + > + rdrv = devm_kzalloc(cdns->dev, sizeof(*rdrv), GFP_KERNEL); > + if (!rdrv) > + return -ENOMEM; > + > + rdrv->start = __cdns3_gadget_init; > + rdrv->stop = cdns3_gadget_exit; > + rdrv->suspend = cdns3_gadget_suspend; > + rdrv->resume = cdns3_gadget_resume; > + rdrv->state = CDNS3_ROLE_STATE_INACTIVE; > + rdrv->name = "gadget"; > + cdns->roles[CDNS3_ROLE_GADGET] = rdrv; > + > + return 0; > +} > diff --git a/drivers/usb/cdns3/gadget.h b/drivers/usb/cdns3/gadget.h > new file mode 100644 > index 000000000000..817f8ae7a4da > --- /dev/null > +++ b/drivers/usb/cdns3/gadget.h > @@ -0,0 +1,1207 @@ > +/* SPDX-License-Identifier: GPL-2.0 */ > +/* > + * USBSS device controller driver header file > + * > + * Copyright (C) 2018 Cadence. > + * Copyright (C) 2017-2018 NXP > + * > + * Author: Pawel Laszczak > + * Pawel Jez > + * Peter Chen > + */ > +#ifndef __LINUX_CDNS3_GADGET > +#define __LINUX_CDNS3_GADGET > +#include > + > +/* > + * USBSS-DEV register interface. > + * This corresponds to the USBSS Device Controller Interface > + */ > + > +/** > + * struct cdns3_usb_regs - device controller registers. > + * @usb_conf: Global Configuration Register. > + * @usb_sts: Global Status Register. > + * @usb_cmd: Global Command Register. > + * @usb_iptn: ITP/SOF number Register. > + * @usb_lpm: Global Command Register. > + * @usb_ien: USB Interrupt Enable Register. > + * @usb_ists: USB Interrupt Status Register. > + * @ep_sel: Endpoint Select Register. > + * @ep_traddr: Endpoint Transfer Ring Address Register. > + * @ep_cfg: Endpoint Configuration Register. > + * @ep_cmd: Endpoint Command Register. > + * @ep_sts: Endpoint Status Register. > + * @ep_sts_sid: Endpoint Status Register. > + * @ep_sts_en: Endpoint Status Register Enable. > + * @drbl: Doorbell Register. > + * @ep_ien: EP Interrupt Enable Register. > + * @ep_ists: EP Interrupt Status Register. > + * @usb_pwr: Global Power Configuration Register. > + * @usb_conf2: Global Configuration Register 2. > + * @usb_cap1: Capability Register 1. > + * @usb_cap2: Capability Register 2. > + * @usb_cap3: Capability Register 3. > + * @usb_cap4: Capability Register 4. > + * @usb_cap5: Capability Register 5. > + * @usb_cap6: Capability Register 6. > + * @usb_cpkt1: Custom Packet Register 1. > + * @usb_cpkt2: Custom Packet Register 2. > + * @usb_cpkt3: Custom Packet Register 3. > + * @reserved1: Reserved. > + * @cfg_regs: Configuration registers. > + * @reserved2: Reserved. > + * @dma_axi_ctrl: AXI Control register. > + * @dma_axi_id: AXI ID register. > + * @dma_axi_cap: AXI Capability register. > + * @dma_axi_ctrl0: AXI Control 0 register. > + * @dma_axi_ctrl1: AXI Control 1 register. > + */ > +struct cdns3_usb_regs { > + __le32 usb_conf; > + __le32 usb_sts; > + __le32 usb_cmd; > + __le32 usb_iptn; > + __le32 usb_lpm; > + __le32 usb_ien; > + __le32 usb_ists; > + __le32 ep_sel; > + __le32 ep_traddr; > + __le32 ep_cfg; > + __le32 ep_cmd; > + __le32 ep_sts; > + __le32 ep_sts_sid; > + __le32 ep_sts_en; > + __le32 drbl; > + __le32 ep_ien; > + __le32 ep_ists; > + __le32 usb_pwr; > + __le32 usb_conf2; > + __le32 usb_cap1; > + __le32 usb_cap2; > + __le32 usb_cap3; > + __le32 usb_cap4; > + __le32 usb_cap5; > + __le32 usb_cap6; > + __le32 usb_cpkt1; > + __le32 usb_cpkt2; > + __le32 usb_cpkt3; > + __le32 reserved1[36]; > + __le32 cfg_reg1; > + __le32 dbg_link1; > + __le32 dbg_link2; > + __le32 cfg_regs[74]; > + __le32 reserved2[34]; > + __le32 dma_axi_ctrl; > + __le32 dma_axi_id; > + __le32 dma_axi_cap; > + __le32 dma_axi_ctrl0; > + __le32 dma_axi_ctrl1; > +}; > + > +/* USB_CONF - bitmasks */ > +/* Reset USB device configuration. */ > +#define USB_CONF_CFGRST BIT(0) > +/* Set Configuration. */ > +#define USB_CONF_CFGSET BIT(1) > +/* Disconnect USB device in SuperSpeed. */ > +#define USB_CONF_USB3DIS BIT(3) > +/* Disconnect USB device in HS/FS */ > +#define USB_CONF_USB2DIS BIT(4) > +/* Little Endian access - default */ > +#define USB_CONF_LENDIAN BIT(5) > +/* > + * Big Endian access. Driver assume that byte order for > + * SFRs access always is as Little Endian so this bit > + * is not used. > + */ > +#define USB_CONF_BENDIAN BIT(6) > +/* Device software reset. */ > +#define USB_CONF_SWRST BIT(7) > +/* Singular DMA transfer mode. */ > +#define USB_CONF_DSING BIT(8) > +/* Multiple DMA transfers mode. */ > +#define USB_CONF_DMULT BIT(9) > +/* DMA clock turn-off enable. */ > +#define USB_CONF_DMAOFFEN BIT(10) > +/* DMA clock turn-off disable. */ > +#define USB_CONF_DMAOFFDS BIT(11) > +/* Clear Force Full Speed. */ > +#define USB_CONF_CFORCE_FS BIT(12) > +/* Set Force Full Speed. */ > +#define USB_CONF_SFORCE_FS BIT(13) > +/* Device enable. */ > +#define USB_CONF_DEVEN BIT(14) > +/* Device disable. */ > +#define USB_CONF_DEVDS BIT(15) > +/* L1 LPM state entry enable (used in HS/FS mode). */ > +#define USB_CONF_L1EN BIT(16) > +/* L1 LPM state entry disable (used in HS/FS mode). */ > +#define USB_CONF_L1DS BIT(17) > +/* USB 2.0 clock gate disable. */ > +#define USB_CONF_CLK2OFFEN BIT(18) > +/* USB 2.0 clock gate enable. */ > +#define USB_CONF_CLK2OFFDS BIT(19) > +/* L0 LPM state entry request (used in HS/FS mode). */ > +#define USB_CONF_LGO_L0 BIT(20) > +/* USB 3.0 clock gate disable. */ > +#define USB_CONF_CLK3OFFEN BIT(21) > +/* USB 3.0 clock gate enable. */ > +#define USB_CONF_CLK3OFFDS BIT(22) > +/* Bit 23 is reserved*/ > +/* U1 state entry enable (used in SS mode). */ > +#define USB_CONF_U1EN BIT(24) > +/* U1 state entry disable (used in SS mode). */ > +#define USB_CONF_U1DS BIT(25) > +/* U2 state entry enable (used in SS mode). */ > +#define USB_CONF_U2EN BIT(26) > +/* U2 state entry disable (used in SS mode). */ > +#define USB_CONF_U2DS BIT(27) > +/* U0 state entry request (used in SS mode). */ > +#define USB_CONF_LGO_U0 BIT(28) > +/* U1 state entry request (used in SS mode). */ > +#define USB_CONF_LGO_U1 BIT(29) > +/* U2 state entry request (used in SS mode). */ > +#define USB_CONF_LGO_U2 BIT(30) > +/* SS.Inactive state entry request (used in SS mode) */ > +#define USB_CONF_LGO_SSINACT BIT(31) > + > +/* USB_STS - bitmasks */ > +/* > + * Configuration status. > + * 1 - device is in the configured state. > + * 0 - device is not configured. > + */ > +#define USB_STS_CFGSTS_MASK BIT(0) > +#define USB_STS_CFGSTS(p) ((p) & USB_STS_CFGSTS_MASK) > +/* > + * On-chip memory overflow. > + * 0 - On-chip memory status OK. > + * 1 - On-chip memory overflow. > + */ > +#define USB_STS_OV_MASK BIT(1) > +#define USB_STS_OV(p) ((p) & USB_STS_OV_MASK) > +/* > + * SuperSpeed connection status. > + * 0 - USB in SuperSpeed mode disconnected. > + * 1 - USB in SuperSpeed mode connected. > + */ > +#define USB_STS_USB3CONS_MASK BIT(2) > +#define USB_STS_USB3CONS(p) ((p) & USB_STS_USB3CONS_MASK) > +/* > + * DMA transfer configuration status. > + * 0 - single request. > + * 1 - multiple TRB chain > + */ > +#define USB_STS_DTRANS_MASK BIT(3) > +#define USB_STS_DTRANS(p) ((p) & USB_STS_DTRANS_MASK) > +/* > + * Device speed. > + * 0 - Undefined (value after reset). > + * 1 - Low speed > + * 2 - Full speed > + * 3 - High speed > + * 4 - Super speed > + */ > +#define USB_STS_USBSPEED_MASK GENMASK(6, 4) > +#define USB_STS_USBSPEED(p) (((p) & USB_STS_USBSPEED_MASK) >> 4) > +#define USB_STS_LS (0x1 << 4) > +#define USB_STS_FS (0x2 << 4) > +#define USB_STS_HS (0x3 << 4) > +#define USB_STS_SS (0x4 << 4) > +#define DEV_UNDEFSPEED(p) (((p) & USB_STS_USBSPEED_MASK) == (0x0 << 4)) > +#define DEV_LOWSPEED(p) (((p) & USB_STS_USBSPEED_MASK) == USB_STS_LS) > +#define DEV_FULLSPEED(p) (((p) & USB_STS_USBSPEED_MASK) == USB_STS_FS) > +#define DEV_HIGHSPEED(p) (((p) & USB_STS_USBSPEED_MASK) == USB_STS_HS) > +#define DEV_SUPERSPEED(p) (((p) & USB_STS_USBSPEED_MASK) == USB_STS_SS) > +/* > + * Endianness for SFR access. > + * 0 - Little Endian order (default after hardware reset). > + * 1 - Big Endian order > + */ > +#define USB_STS_ENDIAN_MASK BIT(7) > +#define USB_STS_ENDIAN(p) ((p) & USB_STS_ENDIAN_MASK) > +/* > + * HS/FS clock turn-off status. > + * 0 - hsfs clock is always on. > + * 1 - hsfs clock turn-off in L2 (HS/FS mode) is enabled > + * (default after hardware reset). > + */ > +#define USB_STS_CLK2OFF_MASK BIT(8) > +#define USB_STS_CLK2OFF(p) ((p) & USB_STS_CLK2OFF_MASK) > +/* > + * PCLK clock turn-off status. > + * 0 - pclk clock is always on. > + * 1 - pclk clock turn-off in U3 (SS mode) is enabled > + * (default after hardware reset). > + */ > +#define USB_STS_CLK3OFF_MASK BIT(9) > +#define USB_STS_CLK3OFF(p) ((p) & USB_STS_CLK3OFF_MASK) > +/* > + * Controller in reset state. > + * 0 - Internal reset is active. > + * 1 - Internal reset is not active and controller is fully operational. > + */ > +#define USB_STS_IN_RST_MASK BIT(10) > +#define USB_STS_IN_RST(p) ((p) & USB_STS_IN_RST_MASK) > +/* > + * Device enable Status. > + * 0 - USB device is disabled (VBUS input is disconnected from internal logic). > + * 1 - USB device is enabled (VBUS input is connected to the internal logic). > + */ > +#define USB_STS_DEVS_MASK BIT(14) > +#define USB_STS_DEVS(p) ((p) & USB_STS_DEVS_MASK) > +/* > + * DAddress statuss. > + * 0 - USB device is default state. > + * 1 - USB device is at least in address state. > + */ > +#define USB_STS_ADDRESSED_MASK BIT(15) > +#define USB_STS_ADDRESSED(p) ((p) & USB_STS_ADDRESSED_MASK) > +/* > + * L1 LPM state enable status (used in HS/FS mode). > + * 0 - Entering to L1 LPM state disabled. > + * 1 - Entering to L1 LPM state enabled. > + */ > +#define USB_STS_L1ENS_MASK BIT(16) > +#define USB_STS_L1ENS(p) ((p) & USB_STS_L1ENS_MASK) > +/* > + * Internal VBUS connection status (used both in HS/FS and SS mode). > + * 0 - internal VBUS is not detected. > + * 1 - internal VBUS is detected. > + */ > +#define USB_STS_VBUSS_MASK BIT(17) > +#define USB_STS_VBUSS(p) ((p) & USB_STS_VBUSS_MASK) > +/* > + * HS/FS LPM state (used in FS/HS mode). > + * 0 - L0 State > + * 1 - L1 State > + * 2 - L2 State > + * 3 - L3 State > + */ > +#define USB_STS_LPMST_MASK GENMASK(19, 18) > +#define DEV_L0_STATE(p) (((p) & USB_STS_LPMST_MASK) == (0x0 << 18)) > +#define DEV_L1_STATE(p) (((p) & USB_STS_LPMST_MASK) == (0x1 << 18)) > +#define DEV_L2_STATE(p) (((p) & USB_STS_LPMST_MASK) == (0x2 << 18)) > +#define DEV_L3_STATE(p) (((p) & USB_STS_LPMST_MASK) == (0x3 << 18)) > +/* > + * Disable HS status (used in FS/HS mode). > + * 0 - the disconnect bit for HS/FS mode is set . > + * 1 - the disconnect bit for HS/FS mode is not set. > + */ > +#define USB_STS_USB2CONS_MASK BIT(20) > +#define USB_STS_USB2CONS(p) ((p) & USB_STS_USB2CONS_MASK) > +/* > + * HS/FS mode connection status (used in FS/HS mode). > + * 0 - High Speed operations in USB2.0 (FS/HS) mode not disabled. > + * 1 - High Speed operations in USB2.0 (FS/HS). > + */ > +#define USB_STS_DISABLE_HS_MASK BIT(21) > +#define USB_STS_DISABLE_HS(p) ((p) & USB_STS_DISABLE_HS_MASK) > +/* > + * U1 state enable status (used in SS mode). > + * 0 - Entering to U1 state disabled. > + * 1 - Entering to U1 state enabled. > + */ > +#define USB_STS_U1ENS_MASK BIT(24) > +#define USB_STS_U1ENS(p) ((p) & USB_STS_U1ENS_MASK) > +/* > + * U2 state enable status (used in SS mode). > + * 0 - Entering to U2 state disabled. > + * 1 - Entering to U2 state enabled. > + */ > +#define USB_STS_U2ENS_MASK BIT(25) > +#define USB_STS_U2ENS(p) ((p) & USB_STS_U2ENS_MASK) > +/* > + * SuperSpeed Link LTSSM state. This field reflects USBSS-DEV current > + * SuperSpeed link state > + */ > +#define USB_STS_LST_MASK GENMASK(29, 26) > +#define DEV_LST_U0 (((p) & USB_STS_LST_MASK) == (0x0 << 26)) > +#define DEV_LST_U1 (((p) & USB_STS_LST_MASK) == (0x1 << 26)) > +#define DEV_LST_U2 (((p) & USB_STS_LST_MASK) == (0x2 << 26)) > +#define DEV_LST_U3 (((p) & USB_STS_LST_MASK) == (0x3 << 26)) > +#define DEV_LST_DISABLED (((p) & USB_STS_LST_MASK) == (0x4 << 26)) > +#define DEV_LST_RXDETECT (((p) & USB_STS_LST_MASK) == (0x5 << 26)) > +#define DEV_LST_INACTIVE (((p) & USB_STS_LST_MASK) == (0x6 << 26)) > +#define DEV_LST_POLLING (((p) & USB_STS_LST_MASK) == (0x7 << 26)) > +#define DEV_LST_RECOVERY (((p) & USB_STS_LST_MASK) == (0x8 << 26)) > +#define DEV_LST_HOT_RESET (((p) & USB_STS_LST_MASK) == (0x9 << 26)) > +#define DEV_LST_COMP_MODE (((p) & USB_STS_LST_MASK) == (0xa << 26)) > +#define DEV_LST_LB_STATE (((p) & USB_STS_LST_MASK) == (0xb << 26)) > +/* > + * DMA clock turn-off status. > + * 0 - DMA clock is always on (default after hardware reset). > + * 1 - DMA clock turn-off in U1, U2 and U3 (SS mode) is enabled. > + */ > +#define USB_STS_DMAOFF_MASK BIT(30) > +#define USB_STS_DMAOFF(p) ((p) & USB_STS_DMAOFF_MASK) > +/* > + * SFR Endian statuss. > + * 0 - Little Endian order (default after hardware reset). > + * 1 - Big Endian order. > + */ > +#define USB_STS_ENDIAN2_MASK BIT(31) > +#define USB_STS_ENDIAN2(p) ((p) & USB_STS_ENDIAN2_MASK) > + > +/* USB_CMD - bitmasks */ > +/* Set Function Address */ > +#define USB_CMD_SET_ADDR BIT(0) > +/* > + * Function Address This field is saved to the device only when the field > + * SET_ADDR is set '1 ' during write to USB_CMD register. > + * Software is responsible for entering the address of the device during > + * SET_ADDRESS request service. This field should be set immediately after > + * the SETUP packet is decoded, and prior to confirmation of the status phase > + */ > +#define USB_CMD_FADDR_MASK GENMASK(7, 1) > +#define USB_CMD_FADDR(p) (((p) << 1) & USB_CMD_FADDR_MASK) > +/* Send Function Wake Device Notification TP (used only in SS mode). */ > +#define USB_CMD_SDNFW BIT(8) > +/* Set Test Mode (used only in HS/FS mode). */ > +#define USB_CMD_STMODE BIT(9) > +/* Test mode selector (used only in HS/FS mode) */ > +#define USB_STS_TMODE_SEL_MASK GENMASK(11, 10) > +#define USB_STS_TMODE_SEL(p) (((p) << 10) & USB_STS_TMODE_SEL_MASK) > +/* > + * Send Latency Tolerance Message Device Notification TP (used only > + * in SS mode). > + */ > +#define USB_CMD_SDNLTM BIT(12) > +/* Send Custom Transaction Packet (used only in SS mode) */ > +#define USB_CMD_SPKT BIT(13) > +/*Device Notification 'Function Wake' - Interface value (only in SS mode. */ > +#define USB_CMD_DNFW_INT_MASK GENMASK(23, 16) > +#define USB_STS_DNFW_INT(p) (((p) << 16) & USB_CMD_DNFW_INT_MASK) > +/* > + * Device Notification 'Latency Tolerance Message' -373 BELT value [7:0] > + * (used only in SS mode). > + */ > +#define USB_CMD_DNLTM_BELT_MASK GENMASK(27, 16) > +#define USB_STS_DNLTM_BELT(p) (((p) << 16) & USB_CMD_DNLTM_BELT_MASK) > + > +/* USB_ITPN - bitmasks */ > +/* > + * ITP(SS) / SOF (HS/FS) number > + * In SS mode this field represent number of last ITP received from host. > + * In HS/FS mode this field represent number of last SOF received from host. > + */ > +#define USB_ITPN_MASK GENMASK(13, 0) > +#define USB_ITPN(p) ((p) & USB_ITPN_MASK) > + > +/* USB_LPM - bitmasks */ > +/* Host Initiated Resume Duration. */ > +#define USB_LPM_HIRD_MASK GENMASK(3, 0) > +#define USB_LPM_HIRD(p) ((p) & USB_LPM_HIRD_MASK) > +/* Remote Wakeup Enable (bRemoteWake). */ > +#define USB_LPM_BRW BIT(4) > + > +/* USB_IEN - bitmasks */ > +/* SS connection interrupt enable */ > +#define USB_IEN_CONIEN BIT(0) > +/* SS disconnection interrupt enable. */ > +#define USB_IEN_DISIEN BIT(1) > +/* USB SS warm reset interrupt enable. */ > +#define USB_IEN_UWRESIEN BIT(2) > +/* USB SS hot reset interrupt enable */ > +#define USB_IEN_UHRESIEN BIT(3) > +/* SS link U3 state enter interrupt enable (suspend).*/ > +#define USB_IEN_U3ENTIEN BIT(4) > +/* SS link U3 state exit interrupt enable (wakeup). */ > +#define USB_IEN_U3EXTIEN BIT(5) > +/* SS link U2 state enter interrupt enable.*/ > +#define USB_IEN_U2ENTIEN BIT(6) > +/* SS link U2 state exit interrupt enable.*/ > +#define USB_IEN_U2EXTIEN BIT(7) > +/* SS link U1 state enter interrupt enable.*/ > +#define USB_IEN_U1ENTIEN BIT(8) > +/* SS link U1 state exit interrupt enable.*/ > +#define USB_IEN_U1EXTIEN BIT(9) > +/* ITP/SOF packet detected interrupt enable.*/ > +#define USB_IEN_ITPIEN BIT(10) > +/* Wakeup interrupt enable.*/ > +#define USB_IEN_WAKEIEN BIT(11) > +/* Send Custom Packet interrupt enable.*/ > +#define USB_IEN_SPKTIEN BIT(12) > +/* HS/FS mode connection interrupt enable.*/ > +#define USB_IEN_CON2IEN BIT(16) > +/* HS/FS mode disconnection interrupt enable.*/ > +#define USB_IEN_DIS2IEN BIT(17) > +/* USB reset (HS/FS mode) interrupt enable.*/ > +#define USB_IEN_U2RESIEN BIT(18) > +/* LPM L2 state enter interrupt enable.*/ > +#define USB_IEN_L2ENTIEN BIT(20) > +/* LPM L2 state exit interrupt enable.*/ > +#define USB_IEN_L2EXTIEN BIT(21) > +/* LPM L1 state enter interrupt enable.*/ > +#define USB_IEN_L1ENTIEN BIT(24) > +/* LPM L1 state exit interrupt enable.*/ > +#define USB_IEN_L1EXTIEN BIT(25) > +/* Configuration reset interrupt enable.*/ > +#define USB_IEN_CFGRESIEN BIT(26) > +/* Start of the USB SS warm reset interrupt enable.*/ > +#define USB_IEN_UWRESSIEN BIT(28) > +/* End of the USB SS warm reset interrupt enable.*/ > +#define USB_IEN_UWRESEIEN BIT(29) > + > +#define USB_IEN_INIT (USB_IEN_U2RESIEN | USB_ISTS_DIS2I | USB_IEN_CON2IEN \ > + | USB_IEN_UHRESIEN | USB_IEN_UWRESIEN | USB_IEN_DISIEN \ > + | USB_IEN_CONIEN | USB_IEN_U3EXTIEN | USB_IEN_L2ENTIEN \ > + | USB_IEN_L2EXTIEN) > + > +/* USB_ISTS - bitmasks */ > +/* SS Connection detected. */ > +#define USB_ISTS_CONI BIT(0) > +/* SS Disconnection detected. */ > +#define USB_ISTS_DISI BIT(1) > +/* UUSB warm reset detectede. */ > +#define USB_ISTS_UWRESI BIT(2) > +/* USB hot reset detected. */ > +#define USB_ISTS_UHRESI BIT(3) > +/* U3 link state enter detected (suspend).*/ > +#define USB_ISTS_U3ENTI BIT(4) > +/* U3 link state exit detected (wakeup). */ > +#define USB_ISTS_U3EXTI BIT(5) > +/* U2 link state enter detected.*/ > +#define USB_ISTS_U2ENTI BIT(6) > +/* U2 link state exit detected.*/ > +#define USB_ISTS_U2EXTI BIT(7) > +/* U1 link state enter detected.*/ > +#define USB_ISTS_U1ENTI BIT(8) > +/* U1 link state exit detected.*/ > +#define USB_ISTS_U1EXTI BIT(9) > +/* ITP/SOF packet detected.*/ > +#define USB_ISTS_ITPI BIT(10) > +/* Wakeup detected.*/ > +#define USB_ISTS_WAKEI BIT(11) > +/* Send Custom Packet detected.*/ > +#define USB_ISTS_SPKTI BIT(12) > +/* HS/FS mode connection detected.*/ > +#define USB_ISTS_CON2I BIT(16) > +/* HS/FS mode disconnection detected.*/ > +#define USB_ISTS_DIS2I BIT(17) > +/* USB reset (HS/FS mode) detected.*/ > +#define USB_ISTS_U2RESI BIT(18) > +/* LPM L2 state enter detected.*/ > +#define USB_ISTS_L2ENTI BIT(20) > +/* LPM L2 state exit detected.*/ > +#define USB_ISTS_L2EXTI BIT(21) > +/* LPM L1 state enter detected.*/ > +#define USB_ISTS_L1ENTI BIT(24) > +/* LPM L1 state exit detected.*/ > +#define USB_ISTS_L1EXTI BIT(25) > +/* USB configuration reset detected.*/ > +#define USB_ISTS_CFGRESI BIT(26) > +/* Start of the USB warm reset detected.*/ > +#define USB_ISTS_UWRESSI BIT(28) > +/* End of the USB warm reset detected.*/ > +#define USB_ISTS_UWRESEI BIT(29) > + > +/* USB_SEL - bitmasks */ > +#define EP_SEL_EPNO_MASK GENMASK(3, 0) > +/* Endpoint number. */ > +#define EP_SEL_EPNO(p) ((p) & EP_SEL_EPNO_MASK) > +/* Endpoint direction bit - 0 - OUT, 1 - IN. */ > +#define EP_SEL_DIR BIT(7) > + > +#define select_ep_in(nr) (EP_SEL_EPNO(p) | EP_SEL_DIR) > +#define select_ep_out (EP_SEL_EPNO(p)) > + > +/* EP_TRADDR - bitmasks */ > +/* Transfer Ring address. */ > +#define EP_TRADDR_TRADDR(p) ((p)) > + > +/* EP_CFG - bitmasks */ > +/* Endpoint enable */ > +#define EP_CFG_ENABLE BIT(0) > +/* > + * Endpoint type. > + * 1 - isochronous > + * 2 - bulk > + * 3 - interrupt > + */ > +#define EP_CFG_EPTYPE_MASK GENMASK(2, 1) > +#define EP_CFG_EPTYPE(p) (((p) << 1) & EP_CFG_EPTYPE_MASK) > +/* Stream support enable (only in SS mode). */ > +#define EP_CFG_STREAM_EN BIT(3) > +/* TDL check (only in SS mode for BULK EP). */ > +#define EP_CFG_TDL_CHK BIT(4) > +/* SID check (only in SS mode for BULK OUT EP). */ > +#define EP_CFG_SID_CHK BIT(5) > +/* DMA transfer endianness. */ > +#define EP_CFG_EPENDIAN BIT(7) > +/* Max burst size (used only in SS mode). */ > +#define EP_CFG_MAXBURST_MASK GENMASK(11, 8) > +#define EP_CFG_MAXBURST(p) (((p) << 8) & EP_CFG_MAXBURST_MASK) > +/* ISO max burst. */ > +#define EP_CFG_MULT_MASK GENMASK(15, 14) > +#define EP_CFG_MULT(p) (((p) << 14) & EP_CFG_MULT_MASK) > +/* ISO max burst. */ > +#define EP_CFG_MAXPKTSIZE_MASK GENMASK(26, 16) > +#define EP_CFG_MAXPKTSIZE(p) (((p) << 16) & EP_CFG_MAXPKTSIZE_MASK) > +/* Max number of buffered packets. */ > +#define EP_CFG_BUFFERING_MASK GENMASK(31, 27) > +#define EP_CFG_BUFFERING(p) (((p) << 27) & EP_CFG_BUFFERING_MASK) > + > +/* EP_CMD - bitmasks */ > +/* Endpoint reset. */ > +#define EP_CMD_EPRST BIT(0) > +/* Endpoint STALL set. */ > +#define EP_CMD_SSTALL BIT(1) > +/* Endpoint STALL clear. */ > +#define EP_CMD_CSTALL BIT(2) > +/* Send ERDY TP. */ > +#define EP_CMD_ERDY BIT(3) > +/* Request complete. */ > +#define EP_CMD_REQ_CMPL BIT(5) > +/* Transfer descriptor ready. */ > +#define EP_CMD_DRDY BIT(6) > +/* Data flush. */ > +#define EP_CMD_DFLUSH BIT(7) > +/* > + * Transfer Descriptor Length write (used only for Bulk Stream capable > + * endpoints in SS mode). > + */ > +#define EP_CMD_STDL BIT(8) > +/* Transfer Descriptor Length (used only in SS mode for bulk endpoints). */ > +#define EP_CMD_TDL_MASK GENMASK(15, 9) > +#define EP_CMD_TDL(p) (((p) << 9) & EP_CMD_TDL_MASK) > +/* ERDY Stream ID value (used in SS mode). */ > +#define EP_CMD_ERDY_SID_MASK GENMASK(31, 16) > +#define EP_CMD_ERDY_SID(p) (((p) << 16) & EP_CMD_SID_MASK) > + > +/* EP_STS - bitmasks */ > +/* Setup transfer complete. */ > +#define EP_STS_SETUP BIT(0) > +/* Endpoint STALL status. */ > +#define EP_STS_STALL(p) ((p) & BIT(1)) > +/* Interrupt On Complete. */ > +#define EP_STS_IOC BIT(2) > +/* Interrupt on Short Packet. */ > +#define EP_STS_ISP BIT(3) > +/* Transfer descriptor missing. */ > +#define EP_STS_DESCMIS BIT(4) > +/* Stream Rejected (used only in SS mode) */ > +#define EP_STS_STREAMR BIT(5) > +/* EXIT from MOVE DATA State (used only for stream transfers in SS mode). */ > +#define EP_STS_MD_EXIT BIT(6) > +/* TRB error. */ > +#define EP_STS_TRBERR BIT(7) > +/* Not ready (used only in SS mode). */ > +#define EP_STS_NRDY BIT(8) > +/* DMA busy. */ > +#define EP_STS_DBUSY(p) ((p) & BIT(9)) > +/* Endpoint Buffer Empty */ > +#define EP_STS_BUFFEMPTY(p) ((p) & BIT(10)) > +/* Current Cycle Status */ > +#define EP_STS_CCS(p) ((p) & BIT(11)) > +/* Prime (used only in SS mode. */ > +#define EP_STS_PRIME BIT(12) > +/* Stream error (used only in SS mode). */ > +#define EP_STS_SIDERR BIT(13) > +/* OUT size mismatch. */ > +#define EP_STS_OUTSMM BIT(14) > +/* ISO transmission error. */ > +#define EP_STS_ISOERR BIT(15) > +/* Host Packet Pending (only for SS mode). */ > +#define EP_STS_HOSTPP(p) ((p) & BIT(16)) > +/* Stream Protocol State Machine State (only for Bulk stream endpoints). */ > +#define EP_STS_SPSMST_MASK GENMASK(18, 17) > +#define EP_STS_SPSMST_DISABLED(p) (((p) & EP_STS_SPSMST_MASK) >> 17) > +#define EP_STS_SPSMST_IDLE(p) (((p) & EP_STS_SPSMST_MASK) >> 17) > +#define EP_STS_SPSMST_START_STREAM(p) (((p) & EP_STS_SPSMST_MASK) >> 17) > +#define EP_STS_SPSMST_MOVE_DATA(p) (((p) & EP_STS_SPSMST_MASK) >> 17) > +/* Interrupt On Transfer complete. */ > +#define EP_STS_IOT BIT(19) > +/* OUT queue endpoint number. */ > +#define EP_STS_OUTQ_NO_MASK GENMASK(27, 24) > +#define EP_STS_OUTQ_NO(p) (((p) & EP_STS_OUTQ_NO_MASK) >> 24) > +/* OUT queue valid flag. */ > +#define EP_STS_OUTQ_VAL_MASK BIT(28) > +#define EP_STS_OUTQ_VAL(p) ((p) & EP_STS_OUTQ_VAL_MASK) > +/* SETUP WAIT. */ > +#define EP_STS_STPWAIT BIT(31) > + > +/* EP_STS_SID - bitmasks */ > +/* Stream ID (used only in SS mode). */ > +#define EP_STS_SID_MASK GENMASK(15, 0) > +#define EP_STS_SID(p) ((p) & EP_STS_SID_MASK) > + > +/* EP_STS_EN - bitmasks */ > +/* SETUP interrupt enable. */ > +#define EP_STS_EN_SETUPEN BIT(0) > +/* OUT transfer missing descriptor enable. */ > +#define EP_STS_EN_DESCMISEN BIT(4) > +/* Stream Rejected enable. */ > +#define EP_STS_EN_STREAMREN BIT(5) > +/* Move Data Exit enable.*/ > +#define EP_STS_EN_MD_EXITEN BIT(6) > +/* TRB enable. */ > +#define EP_STS_EN_TRBERREN BIT(7) > +/* NRDY enable. */ > +#define EP_STS_EN_NRDYEN BIT(8) > +/* Prime enable. */ > +#define EP_STS_EN_PRIMEEEN BIT(12) > +/* Stream error enable. */ > +#define EP_STS_EN_SIDERREN BIT(13) > +/* OUT size mismatch enable. */ > +#define EP_STS_EN_OUTSMMEN BIT(14) > +/* ISO transmission error enable. */ > +#define EP_STS_EN_ISOERREN BIT(15) > +/* Interrupt on Transmission complete enable. */ > +#define EP_STS_EN_IOTEN BIT(19) > +/* Setup Wait interrupt enable. */ > +#define EP_STS_EN_STPWAITEN BIT(31) > + > +/* DRBL- bitmasks */ > +#define DB_VALUE_BY_INDEX(index) (1 << (index)) > +#define DB_VALUE_EP0_OUT BIT(0) > +#define DB_VALUE_EP0_IN BIT(16) > + > +/* EP_IEN - bitmasks */ > +#define EP_IEN(index) (1 << (index)) > +#define EP_IEN_EP_OUT0 BIT(0) > +#define EP_IEN_EP_IN0 BIT(16) > + > +/* EP_ISTS - bitmasks */ > +#define EP_ISTS(index) (1 << (index)) > +#define EP_ISTS_EP_OUT0 BIT(0) > +#define EP_ISTS_EP_IN0 BIT(16) > + > +/* EP_PWR- bitmasks */ > +/*Power Shut Off capability enable*/ > +#define PUSB_PWR_PSO_EN BIT(0) > +/*Power Shut Off capability disable*/ > +#define PUSB_PWR_PSO_DS BIT(1) > +/* > + * Enables turning-off Reference Clock. > + * This bit is optional and implemented only when support for OTG is > + * implemented (indicated by OTG_READY bit set to '1'). > + */ > +#define PUSB_PWR_STB_CLK_SWITCH_EN BIT(8) > +/* > + * Status bit indicating that operation required by STB_CLK_SWITCH_EN write > + * is completed > + */ > +#define PUSB_PWR_STB_CLK_SWITCH_DONE BIT(9) > +/* This bit informs if Fast Registers Access is enabled. */ > +#define PUSB_PWR_FST_REG_ACCESS_STAT BIT(30) > +/* Fast Registers Access Enable. */ > +#define PUSB_PWR_FST_REG_ACCESS BIT(31) > + > +/* USB_CAP1- bitmasks */ > +/* > + * SFR Interface type > + * These field reflects type of SFR interface implemented: > + * 0x0 - OCP > + * 0x1 - AHB, > + * 0x2 - PLB > + * 0x3 - AXI > + * 0x4-0xF - reserved > + */ > +#define USB_CAP1_SFR_TYPE_MASK GENMASK(3, 0) > +#define DEV_SFR_TYPE_OCP(p) (((p) & USB_CAP1_SFR_TYPE_MASK) == 0x0) > +#define DEV_SFR_TYPE_AHB(p) (((p) & USB_CAP1_SFR_TYPE_MASK) == 0x1) > +#define DEV_SFR_TYPE_PLB(p) (((p) & USB_CAP1_SFR_TYPE_MASK) == 0x2) > +#define DEV_SFR_TYPE_AXI(p) (((p) & USB_CAP1_SFR_TYPE_MASK) == 0x3) > +/* > + * SFR Interface width > + * These field reflects width of SFR interface implemented: > + * 0x0 - 8 bit interface, > + * 0x1 - 16 bit interface, > + * 0x2 - 32 bit interface > + * 0x3 - 64 bit interface > + * 0x4-0xF - reserved > + */ > +#define USB_CAP1_SFR_WIDTH_MASK GENMASK(7, 4) > +#define DEV_SFR_WIDTH_8(p) (((p) & USB_CAP1_SFR_WIDTH_MASK) == (0x0 << 4)) > +#define DEV_SFR_WIDTH_16(p) (((p) & USB_CAP1_SFR_WIDTH_MASK) == (0x1 << 4)) > +#define DEV_SFR_WIDTH_32(p) (((p) & USB_CAP1_SFR_WIDTH_MASK) == (0x2 << 4)) > +#define DEV_SFR_WIDTH_64(p) (((p) & USB_CAP1_SFR_WIDTH_MASK) == (0x3 << 4)) > +/* > + * DMA Interface type > + * These field reflects type of DMA interface implemented: > + * 0x0 - OCP > + * 0x1 - AHB, > + * 0x2 - PLB > + * 0x3 - AXI > + * 0x4-0xF - reserved > + */ > +#define USB_CAP1_DMA_TYPE_MASK GENMASK(11, 8) > +#define DEV_DMA_TYPE_OCP(p) (((p) & USB_CAP1_DMA_TYPE_MASK) == (0x0 << 8)) > +#define DEV_DMA_TYPE_AHB(p) (((p) & USB_CAP1_DMA_TYPE_MASK) == (0x1 << 8)) > +#define DEV_DMA_TYPE_PLB(p) (((p) & USB_CAP1_DMA_TYPE_MASK) == (0x2 << 8)) > +#define DEV_DMA_TYPE_AXI(p) (((p) & USB_CAP1_DMA_TYPE_MASK) == (0x3 << 8)) > +/* > + * DMA Interface width > + * These field reflects width of DMA interface implemented: > + * 0x0 - reserved, > + * 0x1 - reserved, > + * 0x2 - 32 bit interface > + * 0x3 - 64 bit interface > + * 0x4-0xF - reserved > + */ > +#define USB_CAP1_DMA_WIDTH_MASK GENMASK(15, 12) > +#define DEV_DMA_WIDTH_32(p) (((p) & USB_CAP1_DMA_WIDTH_MASK) == (0x2 << 12)) > +#define DEV_DMA_WIDTH_64(p) (((p) & USB_CAP1_DMA_WIDTH_MASK) == (0x3 << 12)) > +/* > + * USB3 PHY Interface type > + * These field reflects type of USB3 PHY interface implemented: > + * 0x0 - USB PIPE, > + * 0x1 - RMMI, > + * 0x2-0xF - reserved > + */ > +#define USB_CAP1_U3PHY_TYPE_MASK GENMASK(19, 16) > +#define DEV_U3PHY_PIPE(p) (((p) & USB_CAP1_U3PHY_TYPE_MASK) == (0x0 << 16)) > +#define DEV_U3PHY_RMMI(p) (((p) & USB_CAP1_U3PHY_TYPE_MASK) == (0x1 << 16)) > +/* > + * USB3 PHY Interface width > + * These field reflects width of USB3 PHY interface implemented: > + * 0x0 - 8 bit PIPE interface, > + * 0x1 - 16 bit PIPE interface, > + * 0x2 - 32 bit PIPE interface, > + * 0x3 - 64 bit PIPE interface > + * 0x4-0xF - reserved > + * Note: When SSIC interface is implemented this field shows the width of > + * internal PIPE interface. The RMMI interface is always 20bit wide. > + */ > +#define USB_CAP1_U3PHY_WIDTH_MASK GENMASK(23, 20) > +#define DEV_U3PHY_WIDTH_8(p) \ > + (((p) & USB_CAP1_U3PHY_WIDTH_MASK) == (0x0 << 20)) > +#define DEV_U3PHY_WIDTH_16(p) \ > + (((p) & USB_CAP1_U3PHY_WIDTH_MASK) == (0x1 << 16)) > +#define DEV_U3PHY_WIDTH_32(p) \ > + (((p) & USB_CAP1_U3PHY_WIDTH_MASK) == (0x2 << 20)) > +#define DEV_U3PHY_WIDTH_64(p) \ > + (((p) & USB_CAP1_U3PHY_WIDTH_MASK) == (0x3 << 16)) > + > +/* > + * USB2 PHY Interface enable > + * These field informs if USB2 PHY interface is implemented: > + * 0x0 - interface NOT implemented, > + * 0x1 - interface implemented > + */ > +#define USB_CAP1_U2PHY_EN(p) ((p) & BIT(24)) > +/* > + * USB2 PHY Interface type > + * These field reflects type of USB2 PHY interface implemented: > + * 0x0 - UTMI, > + * 0x1 - ULPI > + */ > +#define DEV_U2PHY_ULPI(p) ((p) & BIT(25)) > +/* > + * USB2 PHY Interface width > + * These field reflects width of USB2 PHY interface implemented: > + * 0x0 - 8 bit interface, > + * 0x1 - 16 bit interface, > + * Note: The ULPI interface is always 8bit wide. > + */ > +#define DEV_U2PHY_WIDTH_16(p) ((p) & BIT(26)) > +/* > + * OTG Ready > + * 0x0 - pure device mode > + * 0x1 - some features and ports for CDNS USB OTG controller are implemented. > + */ > +#define USB_CAP1_OTG_READY(p) ((p) & BIT(27)) > + > +/* USB_CAP2- bitmasks */ > +/* > + * The actual size of the connected On-chip RAM memory in kB: > + * - 0 means 256 kB (max supported mem size) > + * - value other than 0 reflects the mem size in kB > + */ > +#define USB_CAP2_ACTUAL_MEM_SIZE(p) ((p) & GENMASK(7, 0)) > +/* > + * Max supported mem size > + * These field reflects width of on-chip RAM address bus width, > + * which determines max supported mem size: > + * 0x0-0x7 - reserved, > + * 0x8 - support for 4kB mem, > + * 0x9 - support for 8kB mem, > + * 0xA - support for 16kB mem, > + * 0xB - support for 32kB mem, > + * 0xC - support for 64kB mem, > + * 0xD - support for 128kB mem, > + * 0xE - support for 256kB mem, > + * 0xF - reserved > + */ > +#define USB_CAP2_MAX_MEM_SIZE(p) ((p) & GENMASK(11, 8)) > + > +/* USB_CAP3- bitmasks */ > +#define EP_IS_IMPLEMENTED(reg, index) ((reg) & (1 << (index))) > + > +/* USB_CAP4- bitmasks */ > +#define EP_SUPPORT_ISO(reg, index) ((reg) & (1 << (index))) > + > +/* USB_CAP5- bitmasks */ > +#define EP_SUPPORT_STREAM(reg, index) ((reg) & (1 << (index))) > + > +/* USB_CAP6- bitmasks */ > +/* The USBSS-DEV Controller Internal build number. */ > +#define GET_DEV_VERSION__INTERNAL_NUMBER(p) ((p) & GENMASK(7, 0)) > +/* The USBSS-DEV Controller version number. */ > +#define GET_DEV_VERSION(p) ((p) & GENMASK(31, 8)) > + > +/* DBG_LINK1- bitmasks */ > +/* > + * LFPS_MIN_DET_U1_EXIT value This parameter configures the minimum > + * time required for decoding the received LFPS as an LFPS.U1_Exit. > + */ > +#define DBG_LINK1_LFPS_MIN_DET_U1_EXIT(p) ((p) & GENMASK(7, 0)) > +/* > + * LFPS_MIN_GEN_U1_EXIT value This parameter configures the minimum time for > + * phytxelecidle deassertion when LFPS.U1_Exit > + */ > +#define DBG_LINK1_LFPS_MIN_GEN_U1_EXIT_MASK GENMASK(15, 8) > +#define DBG_LINK1_LFPS_MIN_GEN_U1_EXIT(p) (((p) << 8) & GENMASK(15, 8)) > +/* > + * RXDET_BREAK_DIS value This parameter configures terminating the Far-end > + * Receiver termination detection sequence: > + * 0: it is possible that USBSS_DEV will terminate Farend receiver > + * termination detection sequence > + * 1: USBSS_DEV will not terminate Far-end receiver termination > + * detection sequence > + */ > +#define DBG_LINK1_RXDET_BREAK_DIS BIT(16) > +/* LFPS_GEN_PING value This parameter configures the LFPS.Ping generation */ > +#define DBG_LINK1_LFPS_GEN_PING(p) (((p) << 17) & GENMASK(21, 17)) > +/* > + * Set the LFPS_MIN_DET_U1_EXIT value Writing '1' to this bit writes the > + * LFPS_MIN_DET_U1_EXIT field value to the device. This bit is automatically > + * cleared. Writing '0' has no effect > + */ > +#define DBG_LINK1_LFPS_MIN_DET_U1_EXIT_SET BIT(24) > +/* > + * Set the LFPS_MIN_GEN_U1_EXIT value. Writing '1' to this bit writes the > + * LFPS_MIN_GEN_U1_EXIT field value to the device. This bit is automatically > + * cleared. Writing '0' has no effect > + */ > +#define DBG_LINK1_LFPS_MIN_GEN_U1_EXIT_SET BIT(25) > +/* > + * Set the RXDET_BREAK_DIS value Writing '1' to this bit writes > + * the RXDET_BREAK_DIS field value to the device. This bit is automatically > + * cleared. Writing '0' has no effect > + */ > +#define DBG_LINK1_RXDET_BREAK_DIS_SET BIT(26) > +/* > + * Set the LFPS_GEN_PING_SET value Writing '1' to this bit writes > + * the LFPS_GEN_PING field value to the device. This bit is automatically > + * cleared. Writing '0' has no effect." > + */ > +#define DBG_LINK1_LFPS_GEN_PING_SET BIT(27) > + > +#define gadget_to_cdns3_device(g) (container_of(g, struct cdns3_device, gadget)) > + > +#define ep_to_cdns3_ep(ep) (container_of(ep, struct cdns3_endpoint, endpoint)) > + > +/*-------------------------------------------------------------------------*/ > +/* > + * USBSS-DEV DMA interface. > + */ > +#define TRBS_PER_SEGMENT 40 > + > +#define ISO_MAX_INTERVAL 10 > + > +/* > + *Only for ISOC endpoints - maximum number of TRBs is calculated as > + * pow(2, bInterval-1) * number of usb requests. It is limitation made by > + * driver to save memory. Controller must prepare TRB for each ITP even > + * if bInterval > 1. It's the reason why driver needs so many TRBs for > + * isochronous endpoints. > + */ > +#define TRBS_PER_ISOC_SEGMENT (ISO_MAX_INTERVAL * 8) > + > +#define GET_TRBS_PER_SEGMENT(ep_type) ((ep_type) == USB_ENDPOINT_XFER_ISOC ? \ > + TRBS_PER_ISOC_SEGMENT : TRBS_PER_SEGMENT) > +/** > + * struct cdns3_trb - represent Transfer Descriptor block. > + * @buffer: pointer to buffer data > + * @length: length of data > + * @control: control flags. > + * > + * This structure describes transfer block serviced by DMA module. > + */ > +struct cdns3_trb { > + __le32 buffer; > + __le32 length; > + __le32 control; > +}; > + > +#define TRB_SIZE (sizeof(struct cdns3_trb)) > +#define TRB_RING_SIZE (TRB_SIZE * TRBS_PER_SEGMENT) > +#define TRB_ISO_RING_SIZE (TRB_SIZE * TRBS_PER_ISOC_SEGMENT) > +#define TRB_CTRL_RING_SIZE (TRB_SIZE * 2) > + > +/* TRB bit mask */ > +#define TRB_TYPE_BITMASK GENMASK(15, 10) > +#define TRB_TYPE(p) ((p) << 10) > +#define TRB_FIELD_TO_TYPE(p) (((p) & TRB_TYPE_BITMASK) >> 10) > + > +/* TRB type IDs */ > +/* bulk, interrupt, isoc , and control data stage */ > +#define TRB_NORMAL 1 > +/* TRB for linking ring segments */ > +#define TRB_LINK 6 > + > +/* Cycle bit - indicates TRB ownership by driver or hw*/ > +#define TRB_CYCLE BIT(0) > +/* > + * When set to '1', the device will toggle its interpretation of the Cycle bit > + */ > +#define TRB_TOGGLE BIT(1) > + > +/* Interrupt on short packet*/ > +#define TRB_ISP BIT(2) > +/*Setting this bit enables FIFO DMA operation mode*/ > +#define TRB_FIFO_MODE BIT(3) > +/* Set PCIe no snoop attribute */ > +#define TRB_CHAIN BIT(4) > +/* Interrupt on completion */ > +#define TRB_IOC BIT(5) > + > +/* stream ID bitmasks. */ > +#define TRB_STREAM_ID(p) ((p) & GENMASK(31, 16)) > + > +/* transfer_len bitmasks. */ > +#define TRB_LEN(p) ((p) & GENMASK(16, 0)) > + > +/* transfer_len bitmasks - bits 31:24 */ > +#define TRB_BURST_LEN(p) ((p) & GENMASK(31, 24)) > + > +/* Data buffer pointer bitmasks*/ > +#define TRB_BUFFER(p) ((p) & GENMASK(31, 0)) > + > +/*-------------------------------------------------------------------------*/ > +/* Driver numeric constants */ > + > +/* Such declaration should be added to ch9.h */ > +#define USB_DEVICE_MAX_ADDRESS 127 > + > +/* Endpoint init values */ > +#define CDNS3_EP_MAX_PACKET_LIMIT 1024 > +#define CDNS3_EP_MAX_STREAMS 15 > +#define CDNS3_EP0_MAX_PACKET_LIMIT 512 > + > +/* All endpoints including EP0 */ > +#define CDNS3_ENDPOINTS_MAX_COUNT 32 > +#define CDNS3_EP_ZLP_BUF_SIZE 1024 > + > +#define CDNS3_EP_BUF_SIZE 2 /* KB */ > +#define CDNS3_ALIGNED_BUF_SIZE 16384 /* Bytes */ > +#define CDNS3_MAX_NUM_DESCMISS_BUF 32 > +#define CDNS3_DESCMIS_BUF_SIZE 2048 /* Bytes */ > +/*-------------------------------------------------------------------------*/ > +/* Used structs */ > + > +struct cdns3_device; > + > +/** > + * struct cdns3_endpoint - extended device side representation of USB endpoint. > + * @endpoint: usb endpoint > + * @pending_req_list: list of requests queuing on transfer ring. > + * @deferred_req_list: list of requests waiting for queuing on transfer ring. > + * @trb_pool: transfer ring - array of transaction buffers > + * @trb_pool_dma: dma address of transfer ring > + * @cdns3_dev: device associated with this endpoint > + * @name: a human readable name e.g. ep1out > + * @flags: specify the current state of endpoint > + * @descmis_req: internal transfer object used for getting data from on-chip > + * buffer. It can happen only if function driver doesn't send usb_request > + * object on time. > + * @aligned_buff: aligned to 8 bytes data buffer. Buffer address used in > + * TRB shall be aligned to 8. > + * @aligned_dma_addr: dma address of aligned_buff > + * @dir: endpoint direction > + * @num: endpoint number (1 - 15) > + * @type: set to bmAttributes & USB_ENDPOINT_XFERTYPE_MASK > + * @interval: interval between packets used for ISOC endpoint. > + * @free_trbs: number of free TRBs in transfer ring > + * @num_trbs: number of all TRBs in transfer ring > + * @pcs: producer cycle state > + * @ccs: consumer cycle state > + * @enqueue: enqueue index in transfer ring > + * @dequeue: dequeue index in transfer ring > + */ > +struct cdns3_endpoint { > + struct usb_ep endpoint; > + struct list_head pending_req_list; > + struct list_head deferred_req_list; > + > + struct cdns3_trb *trb_pool; > + dma_addr_t trb_pool_dma; > + > + struct cdns3_device *cdns3_dev; > + char name[20]; > + > +#define EP_ENABLED BIT(0) > +#define EP_STALL BIT(1) > +#define EP_WEDGE BIT(2) > +#define EP_TRANSFER_STARTED BIT(3) > +#define EP_UPDATE_EP_TRBADDR BIT(4) > +#define EP_PENDING_REQUEST BIT(5) > +#define EP_RING_FULL BIT(6) > +#define EP_CLAIMED BIT(7) > + > + u32 flags; > + > + struct cdns3_request *descmis_req; > + > + void *aligned_buff; > + dma_addr_t aligned_dma_addr; > + u8 dir; > + u8 num; > + u8 type; > + int interval; > + > + int free_trbs; > + int num_trbs; > + u8 pcs; > + u8 ccs; > + int enqueue; > + int dequeue; > + > + unsigned int wa1_set:1; > + struct cdns3_trb *wa1_trb; > + unsigned int wa1_cycle_bit:1; > +}; > + > +/** > + * struct cdns3_request - extended device side representation of usb_request > + * object . > + * @request: generic usb_request object describing single I/O request. > + * @priv_ep: extended representation of usb_ep object > + * @trb: the first TRB association with this request > + * @start_trb: number of the first TRB in transfer ring > + * @end_trb: number of the last TRB in transfer ring > + * @flags: flag specifying special usage of request > + */ > +struct cdns3_request { > + struct usb_request request; > + struct cdns3_endpoint *priv_ep; > + struct cdns3_trb *trb; > + int start_trb; > + int end_trb; > +#define REQUEST_PENDING BIT(0) > +#define REQUEST_INTERNAL BIT(1) > +#define REQUEST_INTERNAL_CH BIT(2) > +#define REQUEST_ZLP BIT(3) > + u32 flags; > +}; > + > +#define to_cdns3_request(r) (container_of(r, struct cdns3_request, request)) > + > +/*Stages used during enumeration process.*/ > +#define CDNS3_SETUP_STAGE 0x0 > +#define CDNS3_DATA_STAGE 0x1 > +#define CDNS3_STATUS_STAGE 0x2 > + > +/** > + * struct cdns3_device - represent USB device. > + * @dev: pointer to device structure associated whit this controller > + * @sysdev: pointer to the DMA capable device > + * @gadget: device side representation of the peripheral controller > + * @gadget_driver: pointer to the gadget driver > + * @dev_ver: device controller version. > + * @lock: for synchronizing > + * @regs: base address for device side registers > + * @setup_buf: used while processing usb control requests > + * @setup_dma: dma address for setup_buf > + * @zlp_buf - zlp buffer > + * @ep0_stage: ep0 stage during enumeration process. > + * @ep0_data_dir: direction for control transfer > + * @eps: array of pointers to all endpoints with exclusion ep0 > + * @selected_ep: actually selected endpoint. It's used only to improve > + * performance. > + * @isoch_delay: value from Set Isoch Delay request. Only valid on SS/SSP. > + * @u1_allowed: allow device transition to u1 state > + * @u2_allowed: allow device transition to u2 state > + * @is_selfpowered: device is self powered > + * @setup_pending: setup packet is processing by gadget driver > + * @hw_configured_flag: hardware endpoint configuration was set. > + * @wake_up_flag: allow device to remote up the host > + * @status_completion_no_call: indicate that driver is waiting for status s > + * stage completion. It's used in deferred SET_CONFIGURATION request. > + * @onchip_mem_allocated_size: actual size of on-chip memory assigned > + * to endpoints > + * @pending_status_wq: workqueue handling status stage for deferred requests. > + * @shadow_ep_en: hold information about endpoints that will be enabled > + * in soft irq. > + * @pending_status_request: request for which status stage was deferred > + */ > +struct cdns3_device { > + struct device *dev; > + struct device *sysdev; > + > + struct usb_gadget gadget; > + struct usb_gadget_driver *gadget_driver; > + > +#define CDNS_REVISION_V0 0x00024501 > +#define CDNS_REVISION_V1 0x00024509 > + u32 dev_ver; > + > + /* generic spin-lock for drivers */ > + spinlock_t lock; > + > + struct cdns3_usb_regs __iomem *regs; > + > + struct usb_ctrlrequest *setup_buf; > + dma_addr_t setup_dma; > + void *zlp_buf; > + > + u8 ep0_stage; > + int ep0_data_dir; > + > + struct cdns3_endpoint *eps[CDNS3_ENDPOINTS_MAX_COUNT]; > + > + u32 selected_ep; > + u16 isoch_delay; > + > + unsigned u1_allowed:1; > + unsigned u2_allowed:1; > + unsigned is_selfpowered:1; > + unsigned setup_pending:1; > + int hw_configured_flag:1; > + int wake_up_flag:1; > + unsigned status_completion_no_call:1; > + > + struct work_struct pending_status_wq; > + struct usb_request *pending_status_request; > + u32 shadow_ep_en; > + /*in KB */ > + int onchip_mem_allocated_size; > +}; > + > +int cdns3_handshake(void __iomem *ptr, u32 mask, u32 done, int usec); > +void cdns3_set_register_bit(void __iomem *ptr, u32 mask); > +dma_addr_t cdns3_trb_virt_to_dma(struct cdns3_endpoint *priv_ep, > + struct cdns3_trb *trb); > +enum usb_device_speed cdns3_get_speed(struct cdns3_device *priv_dev); > +void cdns3_pending_setup_status_handler(struct work_struct *work); > +void cdns3_hw_reset_eps_config(struct cdns3_device *priv_dev); > +void cdns3_set_hw_configuration(struct cdns3_device *priv_dev); > +void cdns3_select_ep(struct cdns3_device *priv_dev, u32 ep); > +void cdns3_allow_enable_l1(struct cdns3_device *priv_dev, int enable); > +struct usb_request *cdns3_next_request(struct list_head *list); > +int cdns3_ep_run_transfer(struct cdns3_endpoint *priv_ep, > + struct usb_request *request); > +void cdns3_rearm_transfer(struct cdns3_endpoint *priv_ep, u8 rearm); > +int cdns3_allocate_trb_pool(struct cdns3_endpoint *priv_ep); > +u8 cdns3_ep_addr_to_index(u8 ep_addr); > +int cdns3_gadget_ep_set_wedge(struct usb_ep *ep); > +int cdns3_gadget_ep_set_halt(struct usb_ep *ep, int value); > +struct usb_request *cdns3_gadget_ep_alloc_request(struct usb_ep *ep, > + gfp_t gfp_flags); > +void cdns3_gadget_ep_free_request(struct usb_ep *ep, > + struct usb_request *request); > +int cdns3_gadget_ep_dequeue(struct usb_ep *ep, struct usb_request *request); > +void cdns3_gadget_giveback(struct cdns3_endpoint *priv_ep, > + struct cdns3_request *priv_req, > + int status); > + > +int cdns3_init_ep0(struct cdns3_device *priv_dev, > + struct cdns3_endpoint *priv_ep); > +void cdns3_ep0_config(struct cdns3_device *priv_dev); > +void cdns3_ep_config(struct cdns3_endpoint *priv_ep); > +void cdns3_check_ep0_interrupt_proceed(struct cdns3_device *priv_dev, int dir); > + > +#endif /* __LINUX_CDNS3_GADGET */ > diff --git a/drivers/usb/cdns3/host-export.h b/drivers/usb/cdns3/host-export.h > new file mode 100644 > index 000000000000..b498a170b7e8 > --- /dev/null > +++ b/drivers/usb/cdns3/host-export.h > @@ -0,0 +1,28 @@ > +/* SPDX-License-Identifier: GPL-2.0 */ > +/* > + * Cadence USBSS DRD Driver - Host Export APIs > + * > + * Copyright (C) 2017-2018 NXP > + * > + * Authors: Peter Chen > + */ > +#ifndef __LINUX_CDNS3_HOST_EXPORT > +#define __LINUX_CDNS3_HOST_EXPORT > + > +#ifdef CONFIG_USB_CDNS3_HOST > + > +int cdns3_host_init(struct cdns3 *cdns); > +void cdns3_host_exit(struct cdns3 *cdns); > + > +#else > + > +static inline int cdns3_host_init(struct cdns3 *cdns) > +{ > + return -ENXIO; > +} > + > +static inline void cdns3_host_exit(struct cdns3 *cdns) { } > + > +#endif /* CONFIG_USB_CDNS3_HOST */ > + > +#endif /* __LINUX_CDNS3_HOST_EXPORT */ > diff --git a/drivers/usb/cdns3/host.c b/drivers/usb/cdns3/host.c > new file mode 100644 > index 000000000000..b43b0236a885 > --- /dev/null > +++ b/drivers/usb/cdns3/host.c > @@ -0,0 +1,72 @@ > +// SPDX-License-Identifier: GPL-2.0 > +/* > + * Cadence USBSS DRD Driver - host side > + * > + * Copyright (C) 2018 Cadence Design Systems. > + * Copyright (C) 2017-2018 NXP > + * > + * Authors: Peter Chen > + * Pawel Laszczak > + */ > + > +#include > +#include "core.h" > + > +static int __cdns3_host_init(struct cdns3 *cdns) > +{ > + struct platform_device *xhci; > + int ret; > + > + xhci = platform_device_alloc("xhci-hcd", PLATFORM_DEVID_AUTO); > + if (!xhci) { > + dev_err(cdns->dev, "couldn't allocate xHCI device\n"); > + return -ENOMEM; > + } > + > + xhci->dev.parent = cdns->dev; > + cdns->host_dev = xhci; > + > + ret = platform_device_add_resources(xhci, cdns->xhci_res, > + CDNS3_XHCI_RESOURCES_NUM); > + if (ret) { > + dev_err(cdns->dev, "couldn't add resources to xHCI device\n"); > + goto err1; > + } > + > + ret = platform_device_add(xhci); > + if (ret) { > + dev_err(cdns->dev, "failed to register xHCI device\n"); > + goto err1; > + } > + > + return 0; > +err1: > + platform_device_put(xhci); > + return ret; > +} > + > +static void cdns3_host_exit(struct cdns3 *cdns) > +{ > + platform_device_unregister(cdns->host_dev); > + cdns->host_dev = NULL; > +} > + > +int cdns3_host_init(struct cdns3 *cdns) > +{ > + struct cdns3_role_driver *rdrv; > + > + rdrv = devm_kzalloc(cdns->dev, sizeof(*rdrv), GFP_KERNEL); > + if (!rdrv) > + return -ENOMEM; > + > + rdrv->start = __cdns3_host_init; > + rdrv->stop = cdns3_host_exit; > + rdrv->state = CDNS3_ROLE_STATE_INACTIVE; > + rdrv->suspend = NULL; > + rdrv->resume = NULL; > + rdrv->name = "host"; > + > + cdns->roles[CDNS3_ROLE_HOST] = rdrv; > + > + return 0; > +} > diff --git a/drivers/usb/cdns3/trace.c b/drivers/usb/cdns3/trace.c > new file mode 100644 > index 000000000000..9431eb86d4ff > --- /dev/null > +++ b/drivers/usb/cdns3/trace.c > @@ -0,0 +1,23 @@ > +// SPDX-License-Identifier: GPL-2.0 > +/* > + * USBSS device controller driver Trace Support > + * > + * Copyright (C) 2018 Cadence. > + * > + * Author: Pawel Laszczak > + */ > + > +#define CREATE_TRACE_POINTS > +#include "trace.h" > + > +void cdns3_dbg(struct cdns3_device *priv_dev, const char *fmt, ...) > +{ > + struct va_format vaf; > + va_list args; > + > + va_start(args, fmt); > + vaf.fmt = fmt; > + vaf.va = &args; > + trace_cdns3_log(priv_dev, &vaf); > + va_end(args); > +} > diff --git a/drivers/usb/cdns3/trace.h b/drivers/usb/cdns3/trace.h > new file mode 100644 > index 000000000000..a6bbf91c616b > --- /dev/null > +++ b/drivers/usb/cdns3/trace.h > @@ -0,0 +1,404 @@ > +/* SPDX-License-Identifier: GPL-2.0 */ > +/* > + * USBSS device controller driver. > + * Trace support header file. > + * > + * Copyright (C) 2018 Cadence. > + * > + * Author: Pawel Laszczak > + */ > + > +#undef TRACE_SYSTEM > +#define TRACE_SYSTEM cdns3 > + > +#if !defined(__LINUX_CDNS3_TRACE) || defined(TRACE_HEADER_MULTI_READ) > +#define __LINUX_CDNS3_TRACE > + > +#include > +#include > +#include > +#include > +#include "core.h" > +#include "gadget.h" > +#include "debug.h" > + > +#define CDNS3_MSG_MAX 500 > + > +TRACE_EVENT(cdns3_log, > + TP_PROTO(struct cdns3_device *priv_dev, struct va_format *vaf), > + TP_ARGS(priv_dev, vaf), > + TP_STRUCT__entry( > + __string(name, dev_name(priv_dev->dev)) > + __dynamic_array(char, msg, CDNS3_MSG_MAX) > + ), > + TP_fast_assign( > + __assign_str(name, dev_name(priv_dev->dev)); > + vsnprintf(__get_str(msg), CDNS3_MSG_MAX, vaf->fmt, *vaf->va); > + ), > + TP_printk("%s: %s", __get_str(name), __get_str(msg)) > +); > + > +DECLARE_EVENT_CLASS(cdns3_log_doorbell, > + TP_PROTO(const char *ep_name, u32 ep_trbaddr), > + TP_ARGS(ep_name, ep_trbaddr), > + TP_STRUCT__entry( > + __string(name, ep_name) > + __field(u32, ep_trbaddr) > + ), > + TP_fast_assign( > + __assign_str(name, ep_name); > + __entry->ep_trbaddr = ep_trbaddr; > + ), > + TP_printk("//Ding Dong %s, ep_trbaddr %08x", __get_str(name), > + __entry->ep_trbaddr) > +); > + > +DEFINE_EVENT(cdns3_log_doorbell, cdns3_doorbell_ep0, > + TP_PROTO(const char *ep_name, u32 ep_trbaddr), > + TP_ARGS(ep_name, ep_trbaddr) > +); > + > +DEFINE_EVENT(cdns3_log_doorbell, cdns3_doorbell_epx, > + TP_PROTO(const char *ep_name, u32 ep_trbaddr), > + TP_ARGS(ep_name, ep_trbaddr) > +); > + > +DECLARE_EVENT_CLASS(cdns3_log_usb_irq, > + TP_PROTO(struct cdns3_device *priv_dev, u32 usb_ists), > + TP_ARGS(priv_dev, usb_ists), > + TP_STRUCT__entry( > + __field(enum usb_device_speed, speed) > + __field(u32, usb_ists) > + __dynamic_array(char, str, CDNS3_MSG_MAX) > + ), > + TP_fast_assign( > + __entry->speed = cdns3_get_speed(priv_dev); > + __entry->usb_ists = usb_ists; > + ), > + TP_printk("%s", cdns3_decode_usb_irq(__get_str(str), __entry->speed, > + __entry->usb_ists)) > +); > + > +DEFINE_EVENT(cdns3_log_usb_irq, cdns3_usb_irq, > + TP_PROTO(struct cdns3_device *priv_dev, u32 usb_ists), > + TP_ARGS(priv_dev, usb_ists) > +); > + > +DECLARE_EVENT_CLASS(cdns3_log_epx_irq, > + TP_PROTO(struct cdns3_device *priv_dev, struct cdns3_endpoint *priv_ep), > + TP_ARGS(priv_dev, priv_ep), > + TP_STRUCT__entry( > + __string(ep_name, priv_ep->name) > + __field(u32, ep_sts) > + __field(u32, ep_traddr) > + __dynamic_array(char, str, CDNS3_MSG_MAX) > + ), > + TP_fast_assign( > + __assign_str(ep_name, priv_ep->name); > + __entry->ep_sts = readl(&priv_dev->regs->ep_sts); > + __entry->ep_traddr = readl(&priv_dev->regs->ep_traddr); > + ), > + TP_printk("%s, ep_traddr: %08x", > + cdns3_decode_epx_irq(__get_str(str), > + __get_str(ep_name), > + __entry->ep_sts), > + __entry->ep_traddr) > +); > + > +DEFINE_EVENT(cdns3_log_epx_irq, cdns3_epx_irq, > + TP_PROTO(struct cdns3_device *priv_dev, struct cdns3_endpoint *priv_ep), > + TP_ARGS(priv_dev, priv_ep) > +); > + > +DECLARE_EVENT_CLASS(cdns3_log_ep0_irq, > + TP_PROTO(struct cdns3_device *priv_dev, u32 ep_sts), > + TP_ARGS(priv_dev, ep_sts), > + TP_STRUCT__entry( > + __field(int, ep_dir) > + __field(u32, ep_sts) > + __dynamic_array(char, str, CDNS3_MSG_MAX) > + ), > + TP_fast_assign( > + __entry->ep_dir = priv_dev->ep0_data_dir; > + __entry->ep_sts = ep_sts; > + ), > + TP_printk("%s", cdns3_decode_ep0_irq(__get_str(str), > + __entry->ep_dir, > + __entry->ep_sts)) > +); > + > +DEFINE_EVENT(cdns3_log_ep0_irq, cdns3_ep0_irq, > + TP_PROTO(struct cdns3_device *priv_dev, u32 ep_sts), > + TP_ARGS(priv_dev, ep_sts) > +); > + > +DECLARE_EVENT_CLASS(cdns3_log_ctrl, > + TP_PROTO(struct usb_ctrlrequest *ctrl), > + TP_ARGS(ctrl), > + TP_STRUCT__entry( > + __field(u8, bRequestType) > + __field(u8, bRequest) > + __field(u16, wValue) > + __field(u16, wIndex) > + __field(u16, wLength) > + __dynamic_array(char, str, CDNS3_MSG_MAX) > + ), > + TP_fast_assign( > + __entry->bRequestType = ctrl->bRequestType; > + __entry->bRequest = ctrl->bRequest; > + __entry->wValue = le16_to_cpu(ctrl->wValue); > + __entry->wIndex = le16_to_cpu(ctrl->wIndex); > + __entry->wLength = le16_to_cpu(ctrl->wLength); > + ), > + TP_printk("%s", usb_decode_ctrl(__get_str(str), CDNS3_MSG_MAX, > + __entry->bRequestType, > + __entry->bRequest, __entry->wValue, > + __entry->wIndex, __entry->wLength) > + ) > +); > + > +DEFINE_EVENT(cdns3_log_ctrl, cdns3_ctrl_req, > + TP_PROTO(struct usb_ctrlrequest *ctrl), > + TP_ARGS(ctrl) > +); > + > +DECLARE_EVENT_CLASS(cdns3_log_request, > + TP_PROTO(struct cdns3_request *req), > + TP_ARGS(req), > + TP_STRUCT__entry( > + __string(name, req->priv_ep->name) > + __field(struct cdns3_request *, req) > + __field(unsigned int, actual) > + __field(unsigned int, length) > + __field(int, status) > + __field(int, zero) > + __field(int, short_not_ok) > + __field(int, no_interrupt) > + __field(int, start_trb) > + __field(int, end_trb) > + __field(struct cdns3_trb *, start_trb_addr) > + __field(int, flags) > + ), > + TP_fast_assign( > + __assign_str(name, req->priv_ep->name); > + __entry->req = req; > + __entry->actual = req->request.actual; > + __entry->length = req->request.length; > + __entry->status = req->request.status; > + __entry->zero = req->request.zero; > + __entry->short_not_ok = req->request.short_not_ok; > + __entry->no_interrupt = req->request.no_interrupt; > + __entry->start_trb = req->start_trb; > + __entry->end_trb = req->end_trb; > + __entry->start_trb_addr = req->trb; > + __entry->flags = req->flags; > + ), > + TP_printk("%s: req: %p, length: %u/%u %s%s%s, status: %d," > + " trb: [start:%d, end:%d: virt addr %pa], flags:%x ", > + __get_str(name), __entry->req, __entry->actual, __entry->length, > + __entry->zero ? "zero | " : "", > + __entry->short_not_ok ? "short | " : "", > + __entry->no_interrupt ? "no int" : "", > + __entry->status, > + __entry->start_trb, > + __entry->end_trb, > + __entry->start_trb_addr, > + __entry->flags > + ) > +); > + > +DEFINE_EVENT(cdns3_log_request, cdns3_alloc_request, > + TP_PROTO(struct cdns3_request *req), > + TP_ARGS(req) > +); > + > +DEFINE_EVENT(cdns3_log_request, cdns3_free_request, > + TP_PROTO(struct cdns3_request *req), > + TP_ARGS(req) > +); > + > +DEFINE_EVENT(cdns3_log_request, cdns3_ep_queue, > + TP_PROTO(struct cdns3_request *req), > + TP_ARGS(req) > +); > + > +DEFINE_EVENT(cdns3_log_request, cdns3_ep_dequeue, > + TP_PROTO(struct cdns3_request *req), > + TP_ARGS(req) > +); > + > +DEFINE_EVENT(cdns3_log_request, cdns3_gadget_giveback, > + TP_PROTO(struct cdns3_request *req), > + TP_ARGS(req) > +); > + > +DECLARE_EVENT_CLASS(cdns3_log_trb, > + TP_PROTO(struct cdns3_endpoint *priv_ep, struct cdns3_trb *trb), > + TP_ARGS(priv_ep, trb), > + TP_STRUCT__entry( > + __string(name, priv_ep->name) > + __field(struct cdns3_trb *, trb) > + __field(u32, buffer) > + __field(u32, length) > + __field(u32, control) > + __field(u32, type) > + ), > + TP_fast_assign( > + __assign_str(name, priv_ep->name); > + __entry->trb = trb; > + __entry->buffer = trb->buffer; > + __entry->length = trb->length; > + __entry->control = trb->control; > + __entry->type = usb_endpoint_type(priv_ep->endpoint.desc); > + ), > + TP_printk("%s: trb %pa, dma buf: 0x%08x, size: %ld, ctrl: 0x%08x (%s%s%s%s%s%s%s)", > + __get_str(name), __entry->trb, __entry->buffer, > + TRB_LEN(__entry->length), __entry->control, > + __entry->control & TRB_CYCLE ? "C=1, " : "C=0, ", > + __entry->control & TRB_TOGGLE ? "T=1, " : "T=0, ", > + __entry->control & TRB_ISP ? "ISP, " : "", > + __entry->control & TRB_FIFO_MODE ? "FIFO, " : "", > + __entry->control & TRB_CHAIN ? "CHAIN, " : "", > + __entry->control & TRB_IOC ? "IOC, " : "", > + TRB_FIELD_TO_TYPE(__entry->control) == TRB_NORMAL ? "Normal" : "LINK" > + ) > +); > + > +DEFINE_EVENT(cdns3_log_trb, cdns3_prepare_trb, > + TP_PROTO(struct cdns3_endpoint *priv_ep, struct cdns3_trb *trb), > + TP_ARGS(priv_ep, trb) > +); > + > +DEFINE_EVENT(cdns3_log_trb, cdns3_complete_trb, > + TP_PROTO(struct cdns3_endpoint *priv_ep, struct cdns3_trb *trb), > + TP_ARGS(priv_ep, trb) > +); > + > +DECLARE_EVENT_CLASS(cdns3_log_ring, > + TP_PROTO(struct cdns3_endpoint *priv_ep), > + TP_ARGS(priv_ep), > + TP_STRUCT__entry( > + __dynamic_array(u8, ring, TRB_RING_SIZE) > + __dynamic_array(u8, priv_ep, sizeof(struct cdns3_endpoint)) > + __dynamic_array(char, buffer, > + (TRBS_PER_SEGMENT * 65) + CDNS3_MSG_MAX) > + ), > + TP_fast_assign( > + memcpy(__get_dynamic_array(priv_ep), priv_ep, > + sizeof(struct cdns3_endpoint)); > + memcpy(__get_dynamic_array(ring), priv_ep->trb_pool, > + TRB_RING_SIZE); > + ), > + > + TP_printk("%s", > + cdns3_dbg_ring((struct cdns3_endpoint *)__get_str(priv_ep), > + (struct cdns3_trb *)__get_str(ring), > + __get_str(buffer))) > +); > + > +DEFINE_EVENT(cdns3_log_ring, cdns3_ring, > + TP_PROTO(struct cdns3_endpoint *priv_ep), > + TP_ARGS(priv_ep) > +); > + > +DECLARE_EVENT_CLASS(cdns3_log_ep, > + TP_PROTO(struct cdns3_endpoint *priv_ep), > + TP_ARGS(priv_ep), > + TP_STRUCT__entry( > + __string(name, priv_ep->name) > + __field(unsigned int, maxpacket) > + __field(unsigned int, maxpacket_limit) > + __field(unsigned int, max_streams) > + __field(unsigned int, maxburst) > + __field(unsigned int, flags) > + __field(unsigned int, dir) > + __field(u8, enqueue) > + __field(u8, dequeue) > + ), > + TP_fast_assign( > + __assign_str(name, priv_ep->name); > + __entry->maxpacket = priv_ep->endpoint.maxpacket; > + __entry->maxpacket_limit = priv_ep->endpoint.maxpacket_limit; > + __entry->max_streams = priv_ep->endpoint.max_streams; > + __entry->maxburst = priv_ep->endpoint.maxburst; > + __entry->flags = priv_ep->flags; > + __entry->dir = priv_ep->dir; > + __entry->enqueue = priv_ep->enqueue; > + __entry->dequeue = priv_ep->dequeue; > + ), > + TP_printk("%s: mps: %d/%d. streams: %d, burst: %d, enq idx: %d, " > + "deq idx: %d, flags %s%s%s%s%s%s%s%s, dir: %s", > + __get_str(name), __entry->maxpacket, > + __entry->maxpacket_limit, __entry->max_streams, > + __entry->maxburst, __entry->enqueue, > + __entry->dequeue, > + __entry->flags & EP_ENABLED ? "EN | " : "", > + __entry->flags & EP_STALL ? "STALL | " : "", > + __entry->flags & EP_WEDGE ? "WEDGE | " : "", > + __entry->flags & EP_TRANSFER_STARTED ? "STARTED | " : "", > + __entry->flags & EP_UPDATE_EP_TRBADDR ? "UPD TRB | " : "", > + __entry->flags & EP_PENDING_REQUEST ? "REQ PEN | " : "", > + __entry->flags & EP_RING_FULL ? "RING FULL |" : "", > + __entry->flags & EP_CLAIMED ? "CLAIMED " : "", > + __entry->dir ? "IN" : "OUT" > + ) > +); > + > +DEFINE_EVENT(cdns3_log_ep, cdns3_gadget_ep_enable, > + TP_PROTO(struct cdns3_endpoint *priv_ep), > + TP_ARGS(priv_ep) > +); > + > +DEFINE_EVENT(cdns3_log_ep, cdns3_gadget_ep_disable, > + TP_PROTO(struct cdns3_endpoint *priv_ep), > + TP_ARGS(priv_ep) > +); > + > +DECLARE_EVENT_CLASS(cdns3_log_request_handled, > + TP_PROTO(struct cdns3_request *priv_req, int current_index, > + int handled), > + TP_ARGS(priv_req, current_index, handled), > + TP_STRUCT__entry( > + __field(struct cdns3_request *, priv_req) > + __field(unsigned int, dma_position) > + __field(unsigned int, handled) > + __field(unsigned int, dequeue_idx) > + __field(unsigned int, enqueue_idx) > + __field(unsigned int, start_trb) > + __field(unsigned int, end_trb) > + ), > + TP_fast_assign( > + __entry->priv_req = priv_req; > + __entry->dma_position = current_index; > + __entry->handled = handled; > + __entry->dequeue_idx = priv_req->priv_ep->dequeue; > + __entry->enqueue_idx = priv_req->priv_ep->enqueue; > + __entry->start_trb = priv_req->start_trb; > + __entry->end_trb = priv_req->end_trb; > + ), > + TP_printk("Req: %p %s, DMA pos: %d, ep deq: %d, ep enq: %d," > + " start trb: %d, end trb: %d", > + __entry->priv_req, > + __entry->handled ? "handled" : "not handled", > + __entry->dma_position, __entry->dequeue_idx, > + __entry->enqueue_idx, __entry->start_trb, > + __entry->end_trb > + ) > +); > + > +DEFINE_EVENT(cdns3_log_request_handled, cdns3_request_handled, > + TP_PROTO(struct cdns3_request *priv_req, int current_index, > + int handled), > + TP_ARGS(priv_req, current_index, handled) > +); > +#endif /* __LINUX_CDNS3_TRACE */ > + > +/* this part must be outside header guard */ > + > +#undef TRACE_INCLUDE_PATH > +#define TRACE_INCLUDE_PATH . > + > +#undef TRACE_INCLUDE_FILE > +#define TRACE_INCLUDE_FILE trace > + > +#include > -- > 2.17.1 > From mboxrd@z Thu Jan 1 00:00:00 1970 From: Peter Chen Subject: Re: [PATCH v4 5/6] usb:cdns3 Add Cadence USB3 DRD Driver Date: Thu, 21 Feb 2019 17:22:42 +0800 Message-ID: References: <1550173514-23573-1-git-send-email-pawell@cadence.com> <1550173514-23573-6-git-send-email-pawell@cadence.com> Mime-Version: 1.0 Content-Type: text/plain; charset="UTF-8" Return-path: In-Reply-To: <1550173514-23573-6-git-send-email-pawell@cadence.com> Sender: linux-kernel-owner@vger.kernel.org To: Pawel Laszczak Cc: devicetree@vger.kernel.org, Greg Kroah-Hartman , felipe.balbi@linux.intel.com, mark.rutland@arm.com, linux-usb@vger.kernel.org, hdegoede@redhat.com, Heikki Krogerus , andy.shevchenko@gmail.com, robh+dt@kernel.org, rogerq@ti.com, lkml , jbergsagel@ti.com, nsekhar@ti.com, nm@ti.com, sureshp@cadence.com, peter.chen@nxp.com, kurahul@cadence.com List-Id: devicetree@vger.kernel.org > +int cdns3_set_mode(struct cdns3 *cdns, enum usb_dr_mode mode) > +{ > + int ret = 0; > + u32 reg; > + > + cdns->current_dr_mode = mode; > + > + switch (mode) { > + case USB_DR_MODE_PERIPHERAL: > + dev_info(cdns->dev, "Set controller to Gadget mode\n"); > + ret = cdns3_drd_switch_gadget(cdns, 1); > + break; > + case USB_DR_MODE_HOST: > + dev_info(cdns->dev, "Set controller to Host mode\n"); > + ret = cdns3_drd_switch_host(cdns, 1); > + break; > + case USB_DR_MODE_OTG: > + dev_info(cdns->dev, "Set controller to OTG mode\n"); > + if (cdns->version == CDNS3_CONTROLLER_V1) { > + reg = readl(&cdns->otg_v1_regs->override); > + reg |= OVERRIDE_IDPULLUP; > + writel(reg, &cdns->otg_v1_regs->override); > + } else { > + reg = readl(&cdns->otg_v0_regs->ctrl1); > + reg |= OVERRIDE_IDPULLUP_V0; > + writel(reg, &cdns->otg_v0_regs->ctrl1); > + } > + > + /* > + * Hardware specification says: "ID_VALUE must be valid within > + * 50ms after idpullup is set to '1" so driver must wait > + * 50ms before reading this pin. > + */ > + usleep_range(50000, 60000); > + break; > + default: > + cdns->current_dr_mode = USB_DR_MODE_UNKNOWN; > + dev_err(cdns->dev, "Unsupported mode of operation %d\n", mode); > + return -EINVAL; > + } > + > + return ret; > +} > + > +int cdns3_get_id(struct cdns3 *cdns) > +{ > + int id; > + > + id = readl(&cdns->otg_regs->sts) & OTGSTS_ID_VALUE; > + dev_dbg(cdns->dev, "OTG ID: %d", id); > + return id; > +} > + > +int cdns3_is_host(struct cdns3 *cdns) > +{ > + if (cdns->current_dr_mode == USB_DR_MODE_HOST) > + return 1; I run out issue if I set dr_mode as host at dts (firmware). We need to return 1 at this case, but the cdns->current_dr_mode is changed to OTG before. If we set peripheral-only or host-only at dts, the above judgement should only reply on dts setting. Below changes work at my platform: diff --git a/drivers/usb/cdns3/drd.c b/drivers/usb/cdns3/drd.c index 3e56338cd7b9..2e3d2d19aaa3 100644 --- a/drivers/usb/cdns3/drd.c +++ b/drivers/usb/cdns3/drd.c @@ -81,7 +81,7 @@ int cdns3_get_id(struct cdns3 *cdns) int cdns3_is_host(struct cdns3 *cdns) { - if (cdns->current_dr_mode == USB_DR_MODE_HOST) + if (usb_get_dr_mode(cdns->dev) == USB_DR_MODE_HOST) return 1; else if (!cdns3_get_id(cdns)) return 1; @@ -91,7 +91,7 @@ int cdns3_is_host(struct cdns3 *cdns) int cdns3_is_device(struct cdns3 *cdns) { - if (cdns->current_dr_mode == USB_DR_MODE_PERIPHERAL) + if (usb_get_dr_mode(cdns->dev) == USB_DR_MODE_PERIPHERAL) return 1; else if (cdns->current_dr_mode == USB_DR_MODE_OTG) if (cdns3_get_id(cdns)) @@ -230,6 +230,8 @@ int cdns3_drd_update_mode(struct cdns3 *cdns) Below is the output I set dr_mode as host: [ 2.743538] cdns-usb3 5b130000.cdns3: DRD version v0 (00000100) [ 2.749476] cdns-usb3 5b130000.cdns3: Controller strapped to HOST [ 2.755638] cdns-usb3 5b130000.cdns3: cdns3_drd_update_mode:1:0:1 [ 2.763764] cdns-usb3 5b130000.cdns3: Set controller to Host mode [ 2.769868] cdns-usb3 5b130000.cdns3: Waiting for Host mode is turned on [ 2.769881] cdns-usb3 5b130000.cdns3: cdns3_drd_update_mode:3:1:3 [ 2.777990] cdns-usb3 5b130000.cdns3: Set controller to OTG mode [ 2.849353] cdns-usb3 5b130000.cdns3: Waiting for Host mode is turned on [ 2.849689] cdns-usb3 5b130000.cdns3: Cadence USB3 core: probe succeed [ 2.849722] nxp-cdns3 5b110000.usb3: Cadence USB3 core: probe succeed >>From above log, the cdns3_drd_update_mode is called twice, and the controller switches like INIT_MODE->HOST->OTG->HOST. Your role initialization is a little complicated, please try to simply it.Please try to simply it. Besides, do you really need so many variables for dr_mode? dr_mode is static from firmware, the dynamic status can be described by cdns->role. Below is the output I set dr_mode as peripheral: [ 1.900029] cdns-usb3 5b130000.cdns3: DRD version v0 (00000100) [ 1.905983] cdns-usb3 5b130000.cdns3: Controller strapped to PERIPHERAL [ 1.912669] cdns-usb3 5b130000.cdns3: cdns3_drd_update_mode:2:0:2 [ 1.920803] cdns-usb3 5b130000.cdns3: Set controller to Gadget mode [ 1.927121] cdns-usb3 5b130000.cdns3: Waiting for Device mode is turned on [ 1.927138] cdns-usb3 5b130000.cdns3: cdns3_drd_update_mode:3:2:3 [ 1.935261] cdns-usb3 5b130000.cdns3: Set controller to OTG mode [ 2.001305] cdns-usb3 5b130000.cdns3: OTG ID: 1 [ 2.001312] cdns-usb3 5b130000.cdns3: Waiting for Device mode is turned on [ 2.001321] cdns-usb3 5b130000.cdns3: OTG ID: 1 [ 2.001334] cdns-usb3 5b130000.cdns3: Initializing non-zero endpoints And the output for cdns3_drd_update_mode is: @@ -230,6 +230,8 @@ int cdns3_drd_update_mode(struct cdns3 *cdns) { int ret = 0; + dev_dbg(cdns->dev, "%s:%d:%d:%d \n", __func__, cdns->desired_dr_mode, + cdns->current_dr_mode, cdns->dr_mode); Besides above issue, seems you forget to set OTGSIMULATE.OTG_CFG_FAST_SIMS, The set host will timeout when switch from otg to host. Below code works at my side @@ -314,6 +316,7 @@ int cdns3_drd_init(struct cdns3 *cdns) cdns->version = CDNS3_CONTROLLER_V0; cdns->otg_v1_regs = NULL; cdns->otg_regs = regs; + writel(1, &cdns->otg_v0_regs->simulate); dev_info(cdns->dev, "DRD version v0 (%08x)\n", readl(&cdns->otg_v0_regs->version)); Peter > + else if (!cdns3_get_id(cdns)) > + return 1; > + > + return 0; > +} > + > +int cdns3_is_device(struct cdns3 *cdns) > +{ > + if (cdns->current_dr_mode == USB_DR_MODE_PERIPHERAL) > + return 1; > + else if (cdns->current_dr_mode == USB_DR_MODE_OTG) > + if (cdns3_get_id(cdns)) > + return 1; > + > + return 0; > +} > + > +/** > + * cdns3_otg_disable_irq - Disable all OTG interrupts > + * @cdns: Pointer to controller context structure > + */ > +static void cdns3_otg_disable_irq(struct cdns3 *cdns) > +{ > + writel(0, &cdns->otg_regs->ien); > +} > + > +/** > + * cdns3_otg_enable_irq - enable id and sess_valid interrupts > + * @cdns: Pointer to controller context structure > + */ > +static void cdns3_otg_enable_irq(struct cdns3 *cdns) > +{ > + writel(OTGIEN_ID_CHANGE_INT | OTGIEN_VBUSVALID_RISE_INT | > + OTGIEN_VBUSVALID_FALL_INT, &cdns->otg_regs->ien); > +} > + > +/** > + * cdns3_drd_switch_host - start/stop host > + * @cdns: Pointer to controller context structure > + * @on: 1 for start, 0 for stop > + * > + * Returns 0 on success otherwise negative errno > + */ > +static int cdns3_drd_switch_host(struct cdns3 *cdns, int on) > +{ > + int ret; > + u32 reg = OTGCMD_OTG_DIS; > + > + /* switch OTG core */ > + if (on) { > + writel(OTGCMD_HOST_BUS_REQ | reg, &cdns->otg_regs->cmd); > + > + dev_dbg(cdns->dev, "Waiting for Host mode is turned on\n"); > + ret = cdns3_handshake(&cdns->otg_regs->sts, OTGSTS_XHCI_READY, > + OTGSTS_XHCI_READY, 100000); > + > + if (ret) > + return ret; > + } else { > + usleep_range(30, 40); > + writel(OTGCMD_HOST_BUS_DROP | OTGCMD_DEV_BUS_DROP | > + OTGCMD_DEV_POWER_OFF | OTGCMD_HOST_POWER_OFF, > + &cdns->otg_regs->cmd); > + usleep_range(3000, 4000); > + } > + > + return 0; > +} > + > +/** > + * cdns3_drd_switch_gadget - start/stop gadget > + * @cdns: Pointer to controller context structure > + * @on: 1 for start, 0 for stop > + * > + * Returns 0 on success otherwise negative errno > + */ > +static int cdns3_drd_switch_gadget(struct cdns3 *cdns, int on) > +{ > + int ret; > + u32 reg = OTGCMD_OTG_DIS; > + > + /* switch OTG core */ > + if (on) { > + writel(OTGCMD_DEV_BUS_REQ | reg, &cdns->otg_regs->cmd); > + > + dev_dbg(cdns->dev, "Waiting for Device mode is turned on\n"); > + > + ret = cdns3_handshake(&cdns->otg_regs->sts, OTGSTS_DEV_READY, > + OTGSTS_DEV_READY, 100000); > + > + if (ret) > + return ret; > + } else { > + /* > + * driver should wait at least 10us after disabling Device > + * before turning-off Device (DEV_BUS_DROP) > + */ > + usleep_range(20, 30); > + writel(OTGCMD_HOST_BUS_DROP | OTGCMD_DEV_BUS_DROP | > + OTGCMD_DEV_POWER_OFF | OTGCMD_HOST_POWER_OFF, > + &cdns->otg_regs->cmd); > + usleep_range(3000, 4000); > + } > + > + return 0; > +} > + > +/** > + * cdns3_init_otg_mode - initialize drd controller > + * @cdns: Pointer to controller context structure > + * > + * Returns 0 on success otherwise negative errno > + */ > +static int cdns3_init_otg_mode(struct cdns3 *cdns) > +{ > + int ret = 0; > + > + cdns3_otg_disable_irq(cdns); > + /* clear all interrupts */ > + writel(~0, &cdns->otg_regs->ivect); > + > + ret = cdns3_set_mode(cdns, USB_DR_MODE_OTG); > + if (ret) > + return ret; > + > + if (cdns3_is_host(cdns)) > + ret = cdns3_drd_switch_host(cdns, 1); > + else > + ret = cdns3_drd_switch_gadget(cdns, 1); > + > + if (ret) > + return ret; > + > + cdns3_otg_enable_irq(cdns); > + return ret; > +} > + > +/** > + * cdns3_drd_update_mode - initialize mode of operation > + * @cdns: Pointer to controller context structure > + * > + * Returns 0 on success otherwise negative errno > + */ > +int cdns3_drd_update_mode(struct cdns3 *cdns) > +{ > + int ret = 0; > + > + if (cdns->desired_dr_mode == cdns->current_dr_mode) > + return ret; > + > + cdns3_drd_switch_gadget(cdns, 0); > + cdns3_drd_switch_host(cdns, 0); > + > + switch (cdns->desired_dr_mode) { > + case USB_DR_MODE_PERIPHERAL: > + ret = cdns3_set_mode(cdns, USB_DR_MODE_PERIPHERAL); > + break; > + case USB_DR_MODE_HOST: > + ret = cdns3_set_mode(cdns, USB_DR_MODE_HOST); > + break; > + case USB_DR_MODE_OTG: > + ret = cdns3_init_otg_mode(cdns); > + break; > + default: > + dev_err(cdns->dev, "Unsupported mode of operation %d\n", > + cdns->dr_mode); > + return -EINVAL; > + } > + > + return ret; > +} > + > +/** > + * cdns3_drd_irq - interrupt handler for OTG events > + * > + * @irq: irq number for cdns3 core device > + * @data: structure of cdns3 > + * > + * Returns IRQ_HANDLED or IRQ_NONE > + */ > +static irqreturn_t cdns3_drd_irq(int irq, void *data) > +{ > + irqreturn_t ret = IRQ_NONE; > + struct cdns3 *cdns = data; > + u32 reg; > + > + if (cdns->dr_mode != USB_DR_MODE_OTG) > + return ret; > + > + reg = readl(&cdns->otg_regs->ivect); > + > + if (!reg) > + return ret; > + > + if (reg & OTGIEN_ID_CHANGE_INT) { > + dev_dbg(cdns->dev, "OTG IRQ: new ID: %d\n", > + cdns3_get_id(cdns)); > + > + queue_work(system_freezable_wq, &cdns->role_switch_wq); > + > + ret = IRQ_HANDLED; > + } > + > + writel(~0, &cdns->otg_regs->ivect); > + return ret; > +} > + > +int cdns3_drd_init(struct cdns3 *cdns) > +{ > + void __iomem *regs; > + int ret = 0; > + u32 state; > + > + regs = devm_ioremap_resource(cdns->dev, &cdns->otg_res); > + if (IS_ERR(regs)) > + return PTR_ERR(regs); > + > + /* Detection of DRD version. Controller has been released > + * in two versions. Both are similar, but they have same changes > + * in register maps. > + * The first register in old version is command register and it's read > + * only, so driver should read 0 from it. On the other hand, in v1 > + * the first register contains device ID number which is not set to 0. > + * Driver uses this fact to detect the proper version of > + * controller. > + */ > + cdns->otg_v0_regs = regs; > + if (!readl(&cdns->otg_v0_regs->cmd)) { > + cdns->version = CDNS3_CONTROLLER_V0; > + cdns->otg_v1_regs = NULL; > + cdns->otg_regs = regs; > + dev_info(cdns->dev, "DRD version v0 (%08x)\n", > + readl(&cdns->otg_v0_regs->version)); > + } else { > + cdns->otg_v0_regs = NULL; > + cdns->otg_v1_regs = regs; > + cdns->otg_regs = (void *)&cdns->otg_v1_regs->cmd; > + cdns->version = CDNS3_CONTROLLER_V1; > + dev_info(cdns->dev, "DRD version v1 (ID: %08x, rev: %08x)\n", > + readl(&cdns->otg_v1_regs->did), > + readl(&cdns->otg_v1_regs->rid)); > + } > + > + state = OTGSTS_STRAP(readl(&cdns->otg_regs->sts)); > + > + /* Update dr_mode according to STRAP configuration. */ > + cdns->dr_mode = USB_DR_MODE_OTG; > + if (state == OTGSTS_STRAP_HOST) { > + dev_info(cdns->dev, "Controller strapped to HOST\n"); > + cdns->dr_mode = USB_DR_MODE_HOST; > + } else if (state == OTGSTS_STRAP_GADGET) { > + dev_info(cdns->dev, "Controller strapped to PERIPHERAL\n"); > + cdns->dr_mode = USB_DR_MODE_PERIPHERAL; > + } > + > + cdns->desired_dr_mode = cdns->dr_mode; > + cdns->current_dr_mode = USB_DR_MODE_UNKNOWN; > + > + ret = devm_request_threaded_irq(cdns->dev, cdns->irq, cdns3_drd_irq, > + NULL, IRQF_SHARED, > + dev_name(cdns->dev), cdns); > + > + if (ret) > + return ret; > + > + state = readl(&cdns->otg_regs->sts); > + if (OTGSTS_OTG_NRDY(state) != 0) { > + dev_err(cdns->dev, "Cadence USB3 OTG device not ready\n"); > + return -ENODEV; > + } > + > + ret = cdns3_drd_update_mode(cdns); > + > + return ret; > +} > + > +int cdns3_drd_exit(struct cdns3 *cdns) > +{ > + return cdns3_drd_switch_host(cdns, 0); > +} > diff --git a/drivers/usb/cdns3/drd.h b/drivers/usb/cdns3/drd.h > new file mode 100644 > index 000000000000..6a29cdcb492d > --- /dev/null > +++ b/drivers/usb/cdns3/drd.h > @@ -0,0 +1,162 @@ > +/* SPDX-License-Identifier: GPL-2.0 */ > +/* > + * Cadence USB3 DRD header file. > + * > + * Copyright (C) 2018 Cadence. > + * > + * Author: Pawel Laszczak > + */ > +#ifndef __LINUX_CDNS3_DRD > +#define __LINUX_CDNS3_DRD > + > +#include > +#include > +#include "core.h" > + > +/* DRD register interface for version v1. */ > +struct cdns3_otg_regs { > + __le32 did; > + __le32 rid; > + __le32 capabilities; > + __le32 reserved1; > + __le32 cmd; > + __le32 sts; > + __le32 state; > + __le32 reserved2; > + __le32 ien; > + __le32 ivect; > + __le32 refclk; > + __le32 tmr; > + __le32 reserved3[4]; > + __le32 simulate; > + __le32 override; > + __le32 susp_ctrl; > + __le32 reserved4; > + __le32 anasts; > + __le32 adp_ramp_time; > + __le32 ctrl1; > + __le32 ctrl2; > +}; > + > +/* DRD register interface for version v0. */ > +struct cdns3_otg_legacy_regs { > + __le32 cmd; > + __le32 sts; > + __le32 state; > + __le32 refclk; > + __le32 ien; > + __le32 ivect; > + __le32 reserved1[3]; > + __le32 tmr; > + __le32 reserved2[2]; > + __le32 version; > + __le32 capabilities; > + __le32 reserved3[2]; > + __le32 simulate; > + __le32 reserved4[5]; > + __le32 ctrl1; > +}; > + > +/* > + * Common registers interface for both version of DRD. > + */ > +struct cdns3_otg_common_regs { > + __le32 cmd; > + __le32 sts; > + __le32 state; > + __le32 different1; > + __le32 ien; > + __le32 ivect; > +}; > + > +/* CDNS_RID - bitmasks */ > +#define CDNS_RID(p) ((p) & GENMASK(15, 0)) > + > +/* CDNS_VID - bitmasks */ > +#define CDNS_DID(p) ((p) & GENMASK(31, 0)) > + > +/* OTGCMD - bitmasks */ > +/* "Request the bus for Device mode. */ > +#define OTGCMD_DEV_BUS_REQ BIT(0) > +/* Request the bus for Host mode */ > +#define OTGCMD_HOST_BUS_REQ BIT(1) > +/* Enable OTG mode. */ > +#define OTGCMD_OTG_EN BIT(2) > +/* Disable OTG mode */ > +#define OTGCMD_OTG_DIS BIT(3) > +/*"Configure OTG as A-Device. */ > +#define OTGCMD_A_DEV_EN BIT(4) > +/*"Configure OTG as A-Device. */ > +#define OTGCMD_A_DEV_DIS BIT(5) > +/* Drop the bus for Device mod e. */ > +#define OTGCMD_DEV_BUS_DROP BIT(8) > +/* Drop the bus for Host mode*/ > +#define OTGCMD_HOST_BUS_DROP BIT(9) > +/* Power Down USBSS-DEV. */ > +#define OTGCMD_DEV_POWER_OFF BIT(11) > +/* Power Down CDNSXHCI. */ > +#define OTGCMD_HOST_POWER_OFF BIT(12) > + > +/* OTGIEN - bitmasks */ > +/* ID change interrupt enable */ > +#define OTGIEN_ID_CHANGE_INT BIT(0) > +/* Vbusvalid fall detected interrupt enable.*/ > +#define OTGIEN_VBUSVALID_RISE_INT BIT(4) > +/* Vbusvalid fall detected interrupt enable */ > +#define OTGIEN_VBUSVALID_FALL_INT BIT(5) > + > +/* OTGSTS - bitmasks */ > +/* > + * Current value of the ID pin. It is only valid when idpullup in > + * OTGCTRL1_TYPE register is set to '1'. > + */ > +#define OTGSTS_ID_VALUE BIT(0) > +/* Current value of the vbus_valid */ > +#define OTGSTS_VBUS_VALID BIT(1) > +/* Current value of the b_sess_vld */ > +#define OTGSTS_SESSION_VALID BIT(2) > +/*Device mode is active*/ > +#define OTGSTS_DEV_ACTIVE BIT(3) > +/* Host mode is active. */ > +#define OTGSTS_HOST_ACTIVE BIT(4) > +/* OTG Controller not ready. */ > +#define OTGSTS_OTG_NRDY_MASK BIT(11) > +#define OTGSTS_OTG_NRDY(p) ((p) & OTGSTS_OTG_NRDY_MASK) > +/* > + * Value of the strap pins. > + * 000 - no default configuration > + * 010 - Controller initiall configured as Host > + * 100 - Controller initially configured as Device > + */ > +#define OTGSTS_STRAP(p) (((p) & GENMASK(14, 12)) >> 12) > +#define OTGSTS_STRAP_NO_DEFAULT_CFG 0x00 > +#define OTGSTS_STRAP_HOST_OTG 0x01 > +#define OTGSTS_STRAP_HOST 0x02 > +#define OTGSTS_STRAP_GADGET 0x04 > +/* Host mode is turned on. */ > +#define OTGSTS_XHCI_READY BIT(26) > +/* "Device mode is turned on .*/ > +#define OTGSTS_DEV_READY BIT(27) > + > +/* OTGSTATE- bitmasks */ > +#define OTGSTATE_HOST_STATE_MASK GENMASK(5, 3) > +#define OTGSTATE_HOST_STATE_IDLE 0x0 > +#define OTGSTATE_HOST_STATE_VBUS_FALL 0x7 > +#define OTGSTATE_HOST_STATE(p) (((p) & OTGSTATE_HOST_STATE_MASK) >> 3) > + > +/* OTGREFCLK - bitmasks */ > +#define OTGREFCLK_STB_CLK_SWITCH_EN BIT(31) > + > +/* OVERRIDE - bitmasks */ > +#define OVERRIDE_IDPULLUP BIT(0) > +/* Only for CDNS3_CONTROLLER_V0 version */ > +#define OVERRIDE_IDPULLUP_V0 BIT(24) > + > +int cdns3_is_host(struct cdns3 *cdns); > +int cdns3_is_device(struct cdns3 *cdns); > +int cdns3_get_id(struct cdns3 *cdns); > +int cdns3_drd_init(struct cdns3 *cdns); > +int cdns3_drd_exit(struct cdns3 *cdns); > +int cdns3_drd_update_mode(struct cdns3 *cdns); > + > +#endif /* __LINUX_CDNS3_DRD */ > diff --git a/drivers/usb/cdns3/ep0.c b/drivers/usb/cdns3/ep0.c > new file mode 100644 > index 000000000000..2878982be1ec > --- /dev/null > +++ b/drivers/usb/cdns3/ep0.c > @@ -0,0 +1,907 @@ > +// SPDX-License-Identifier: GPL-2.0 > +/* > + * Cadence USBSS DRD Driver - gadget side. > + * > + * Copyright (C) 2018 Cadence Design Systems. > + * Copyright (C) 2017-2018 NXP > + * > + * Authors: Pawel Jez , > + * Pawel Laszczak > + * Peter Chen > + */ > + > +#include > + > +#include "gadget.h" > +#include "trace.h" > + > +static struct usb_endpoint_descriptor cdns3_gadget_ep0_desc = { > + .bLength = USB_DT_ENDPOINT_SIZE, > + .bDescriptorType = USB_DT_ENDPOINT, > + .bmAttributes = USB_ENDPOINT_XFER_CONTROL, > +}; > + > +/** > + * cdns3_ep0_run_transfer - Do transfer on default endpoint hardware > + * @priv_dev: extended gadget object > + * @dma_addr: physical address where data is/will be stored > + * @length: data length > + * @erdy: set it to 1 when ERDY packet should be sent - > + * exit from flow control state > + */ > +static void cdns3_ep0_run_transfer(struct cdns3_device *priv_dev, > + dma_addr_t dma_addr, > + unsigned int length, int erdy) > +{ > + struct cdns3_usb_regs __iomem *regs = priv_dev->regs; > + struct cdns3_endpoint *priv_ep = priv_dev->eps[0]; > + > + priv_ep->trb_pool->buffer = TRB_BUFFER(dma_addr); > + priv_ep->trb_pool->length = TRB_LEN(length); > + priv_ep->trb_pool->control = TRB_CYCLE | TRB_IOC | TRB_TYPE(TRB_NORMAL); > + > + trace_cdns3_prepare_trb(priv_ep, priv_ep->trb_pool); > + > + cdns3_select_ep(priv_dev, priv_dev->ep0_data_dir); > + > + writel(EP_STS_TRBERR, ®s->ep_sts); > + writel(EP_TRADDR_TRADDR(priv_ep->trb_pool_dma), ®s->ep_traddr); > + trace_cdns3_doorbell_ep0(priv_dev->ep0_data_dir ? "ep0in" : "ep0out", > + readl(®s->ep_traddr)); > + > + /* TRB should be prepared before starting transfer */ > + writel(EP_CMD_DRDY, ®s->ep_cmd); > + > + if (erdy) > + writel(EP_CMD_ERDY, &priv_dev->regs->ep_cmd); > +} > + > +/** > + * cdns3_ep0_delegate_req - Returns status of handling setup packet > + * Setup is handled by gadget driver > + * @priv_dev: extended gadget object > + * @ctrl_req: pointer to received setup packet > + * > + * Returns zero on success or negative value on failure > + */ > +static int cdns3_ep0_delegate_req(struct cdns3_device *priv_dev, > + struct usb_ctrlrequest *ctrl_req) > +{ > + int ret; > + > + spin_unlock(&priv_dev->lock); > + priv_dev->setup_pending = 1; > + ret = priv_dev->gadget_driver->setup(&priv_dev->gadget, ctrl_req); > + priv_dev->setup_pending = 0; > + spin_lock(&priv_dev->lock); > + return ret; > +} > + > +static void cdns3_prepare_setup_packet(struct cdns3_device *priv_dev) > +{ > + priv_dev->ep0_data_dir = 0; > + priv_dev->ep0_stage = CDNS3_SETUP_STAGE; > + cdns3_ep0_run_transfer(priv_dev, priv_dev->setup_dma, > + sizeof(struct usb_ctrlrequest), 0); > +} > + > +static void cdns3_ep0_complete_setup(struct cdns3_device *priv_dev, > + u8 send_stall, u8 send_erdy) > +{ > + struct cdns3_endpoint *priv_ep = priv_dev->eps[0]; > + struct usb_request *request; > + > + request = cdns3_next_request(&priv_ep->pending_req_list); > + if (request) > + list_del_init(&request->list); > + > + if (send_stall) { > + cdns3_dbg(priv_ep->cdns3_dev, "STALL for ep0\n"); > + /* set_stall on ep0 */ > + cdns3_select_ep(priv_dev, 0x00); > + writel(EP_CMD_SSTALL, &priv_dev->regs->ep_cmd); > + } else { > + cdns3_prepare_setup_packet(priv_dev); > + } > + > + priv_dev->ep0_stage = CDNS3_SETUP_STAGE; > + writel((send_erdy ? EP_CMD_ERDY : 0) | EP_CMD_REQ_CMPL, > + &priv_dev->regs->ep_cmd); > +} > + > +/** > + * cdns3_req_ep0_set_configuration - Handling of SET_CONFIG standard USB request > + * @priv_dev: extended gadget object > + * @ctrl_req: pointer to received setup packet > + * > + * Returns 0 if success, USB_GADGET_DELAYED_STATUS on deferred status stage, > + * error code on error > + */ > +static int cdns3_req_ep0_set_configuration(struct cdns3_device *priv_dev, > + struct usb_ctrlrequest *ctrl_req) > +{ > + enum usb_device_state device_state = priv_dev->gadget.state; > + struct cdns3_endpoint *priv_ep; > + u32 config = le16_to_cpu(ctrl_req->wValue); > + int result = 0; > + int i; > + > + switch (device_state) { > + case USB_STATE_ADDRESS: > + /* Configure non-control EPs */ > + for (i = 0; i < CDNS3_ENDPOINTS_MAX_COUNT; i++) { > + priv_ep = priv_dev->eps[i]; > + if (!priv_ep) > + continue; > + > + if (priv_ep->flags & EP_CLAIMED) > + cdns3_ep_config(priv_ep); > + } > + > + result = cdns3_ep0_delegate_req(priv_dev, ctrl_req); > + > + if (result) > + return result; > + > + if (config) { > + cdns3_set_hw_configuration(priv_dev); > + } else { > + cdns3_hw_reset_eps_config(priv_dev); > + usb_gadget_set_state(&priv_dev->gadget, > + USB_STATE_ADDRESS); > + } > + break; > + case USB_STATE_CONFIGURED: > + result = cdns3_ep0_delegate_req(priv_dev, ctrl_req); > + > + if (!config && !result) { > + cdns3_hw_reset_eps_config(priv_dev); > + usb_gadget_set_state(&priv_dev->gadget, > + USB_STATE_ADDRESS); > + } > + break; > + default: > + result = -EINVAL; > + } > + > + return result; > +} > + > +/** > + * cdns3_req_ep0_set_address - Handling of SET_ADDRESS standard USB request > + * @priv_dev: extended gadget object > + * @ctrl_req: pointer to received setup packet > + * > + * Returns 0 if success, error code on error > + */ > +static int cdns3_req_ep0_set_address(struct cdns3_device *priv_dev, > + struct usb_ctrlrequest *ctrl_req) > +{ > + enum usb_device_state device_state = priv_dev->gadget.state; > + u32 reg; > + u32 addr; > + > + addr = le16_to_cpu(ctrl_req->wValue); > + > + if (addr > USB_DEVICE_MAX_ADDRESS) { > + dev_err(priv_dev->dev, > + "Device address (%d) cannot be greater than %d\n", > + addr, USB_DEVICE_MAX_ADDRESS); > + return -EINVAL; > + } > + > + if (device_state == USB_STATE_CONFIGURED) { > + dev_err(priv_dev->dev, > + "can't set_address from configured state\n"); > + return -EINVAL; > + } > + > + reg = readl(&priv_dev->regs->usb_cmd); > + > + writel(reg | USB_CMD_FADDR(addr) | USB_CMD_SET_ADDR, > + &priv_dev->regs->usb_cmd); > + > + usb_gadget_set_state(&priv_dev->gadget, > + (addr ? USB_STATE_ADDRESS : USB_STATE_DEFAULT)); > + > + return 0; > +} > + > +/** > + * cdns3_req_ep0_get_status - Handling of GET_STATUS standard USB request > + * @priv_dev: extended gadget object > + * @ctrl_req: pointer to received setup packet > + * > + * Returns 0 if success, error code on error > + */ > +static int cdns3_req_ep0_get_status(struct cdns3_device *priv_dev, > + struct usb_ctrlrequest *ctrl) > +{ > + __le16 *response_pkt; > + u16 usb_status = 0; > + u32 recip; > + u32 reg; > + > + recip = ctrl->bRequestType & USB_RECIP_MASK; > + > + switch (recip) { > + case USB_RECIP_DEVICE: > + /* self powered */ > + if (priv_dev->is_selfpowered) > + usb_status = BIT(USB_DEVICE_SELF_POWERED); > + > + if (priv_dev->wake_up_flag) > + usb_status |= BIT(USB_DEVICE_REMOTE_WAKEUP); > + > + if (priv_dev->gadget.speed != USB_SPEED_SUPER) > + break; > + > + reg = readl(&priv_dev->regs->usb_sts); > + > + if (priv_dev->u1_allowed) > + usb_status |= BIT(USB_DEV_STAT_U1_ENABLED); > + > + if (priv_dev->u2_allowed) > + usb_status |= BIT(USB_DEV_STAT_U2_ENABLED); > + > + break; > + case USB_RECIP_INTERFACE: > + return cdns3_ep0_delegate_req(priv_dev, ctrl); > + case USB_RECIP_ENDPOINT: > + /* check if endpoint is stalled */ > + cdns3_select_ep(priv_dev, ctrl->wIndex); > + if (EP_STS_STALL(readl(&priv_dev->regs->ep_sts))) > + usb_status = BIT(USB_ENDPOINT_HALT); > + break; > + default: > + return -EINVAL; > + } > + > + response_pkt = (__le16 *)priv_dev->setup_buf; > + *response_pkt = cpu_to_le16(usb_status); > + > + cdns3_ep0_run_transfer(priv_dev, priv_dev->setup_dma, > + sizeof(*response_pkt), 1); > + return 0; > +} > + > +static int cdns3_ep0_feature_handle_device(struct cdns3_device *priv_dev, > + struct usb_ctrlrequest *ctrl, > + int set) > +{ > + enum usb_device_state state; > + enum usb_device_speed speed; > + int ret = 0; > + u32 wValue; > + u32 wIndex; > + u16 tmode; > + > + wValue = le16_to_cpu(ctrl->wValue); > + wIndex = le16_to_cpu(ctrl->wIndex); > + state = priv_dev->gadget.state; > + speed = priv_dev->gadget.speed; > + > + switch (ctrl->wValue) { > + case USB_DEVICE_REMOTE_WAKEUP: > + priv_dev->wake_up_flag = !!set; > + break; > + case USB_DEVICE_U1_ENABLE: > + if (state != USB_STATE_CONFIGURED || speed != USB_SPEED_SUPER) > + return -EINVAL; > + > + priv_dev->u1_allowed = !!set; > + break; > + case USB_DEVICE_U2_ENABLE: > + if (state != USB_STATE_CONFIGURED || speed != USB_SPEED_SUPER) > + return -EINVAL; > + > + priv_dev->u2_allowed = !!set; > + break; > + case USB_DEVICE_LTM_ENABLE: > + ret = -EINVAL; > + break; > + case USB_DEVICE_TEST_MODE: > + if (state != USB_STATE_CONFIGURED || speed > USB_SPEED_HIGH) > + return -EINVAL; > + > + tmode = le16_to_cpu(ctrl->wIndex); > + > + if (!set || (tmode & 0xff) != 0) > + return -EINVAL; > + > + switch (tmode >> 8) { > + case TEST_J: > + case TEST_K: > + case TEST_SE0_NAK: > + case TEST_PACKET: > + cdns3_ep0_complete_setup(priv_dev, 0, 1); > + /** > + * Little delay to give the controller some time > + * for sending status stage. > + * This time should be less then 3ms. > + */ > + usleep_range(1000, 2000); > + cdns3_set_register_bit(&priv_dev->regs->usb_cmd, > + USB_CMD_STMODE | > + USB_STS_TMODE_SEL(tmode - 1)); > + break; > + default: > + ret = -EINVAL; > + } > + break; > + default: > + ret = -EINVAL; > + } > + > + return ret; > +} > + > +static int cdns3_ep0_feature_handle_intf(struct cdns3_device *priv_dev, > + struct usb_ctrlrequest *ctrl, > + int set) > +{ > + u32 wValue; > + int ret = 0; > + > + wValue = le16_to_cpu(ctrl->wValue); > + > + switch (wValue) { > + case USB_INTRF_FUNC_SUSPEND: > + break; > + default: > + ret = -EINVAL; > + } > + > + return ret; > +} > + > +static int cdns3_ep0_feature_handle_endpoint(struct cdns3_device *priv_dev, > + struct usb_ctrlrequest *ctrl, > + int set) > +{ > + struct cdns3_endpoint *priv_ep; > + int ret = 0; > + u8 index; > + > + if (le16_to_cpu(ctrl->wValue) != USB_ENDPOINT_HALT) > + return -EINVAL; > + > + if (!(ctrl->wIndex & ~USB_DIR_IN)) > + return 0; > + > + index = cdns3_ep_addr_to_index(ctrl->wIndex); > + priv_ep = priv_dev->eps[index]; > + > + cdns3_select_ep(priv_dev, ctrl->wIndex); > + > + if (set) { > + cdns3_dbg(priv_ep->cdns3_dev, "Stall endpoint %s\n", > + priv_ep->name); > + writel(EP_CMD_SSTALL, &priv_dev->regs->ep_cmd); > + priv_ep->flags |= EP_STALL; > + } else { > + struct usb_request *request; > + > + if (priv_dev->eps[index]->flags & EP_WEDGE) { > + cdns3_select_ep(priv_dev, 0x00); > + return 0; > + } > + > + cdns3_dbg(priv_ep->cdns3_dev, "Clear Stalled endpoint %s\n", > + priv_ep->name); > + > + writel(EP_CMD_CSTALL | EP_CMD_EPRST, &priv_dev->regs->ep_cmd); > + > + /* wait for EPRST cleared */ > + ret = cdns3_handshake(&priv_dev->regs->ep_cmd, > + EP_CMD_EPRST, 0, 100); > + if (ret) > + return -EINVAL; > + > + priv_ep->flags &= ~EP_STALL; > + > + request = cdns3_next_request(&priv_ep->pending_req_list); > + if (request) { > + cdns3_dbg(priv_ep->cdns3_dev, "Resume transfer for %s\n", > + priv_ep->name); > + > + cdns3_rearm_transfer(priv_ep, 1); > + } > + } > + > + return ret; > +} > + > +/** > + * cdns3_req_ep0_handle_feature - > + * Handling of GET/SET_FEATURE standard USB request > + * > + * @priv_dev: extended gadget object > + * @ctrl_req: pointer to received setup packet > + * @set: must be set to 1 for SET_FEATURE request > + * > + * Returns 0 if success, error code on error > + */ > +static int cdns3_req_ep0_handle_feature(struct cdns3_device *priv_dev, > + struct usb_ctrlrequest *ctrl, > + int set) > +{ > + int ret = 0; > + u32 recip; > + > + recip = ctrl->bRequestType & USB_RECIP_MASK; > + > + switch (recip) { > + case USB_RECIP_DEVICE: > + ret = cdns3_ep0_feature_handle_device(priv_dev, ctrl, set); > + break; > + case USB_RECIP_INTERFACE: > + ret = cdns3_ep0_feature_handle_intf(priv_dev, ctrl, set); > + break; > + case USB_RECIP_ENDPOINT: > + ret = cdns3_ep0_feature_handle_endpoint(priv_dev, ctrl, set); > + break; > + default: > + return -EINVAL; > + } > + > + return ret; > +} > + > +/** > + * cdns3_req_ep0_set_sel - Handling of SET_SEL standard USB request > + * @priv_dev: extended gadget object > + * @ctrl_req: pointer to received setup packet > + * > + * Returns 0 if success, error code on error > + */ > +static int cdns3_req_ep0_set_sel(struct cdns3_device *priv_dev, > + struct usb_ctrlrequest *ctrl_req) > +{ > + if (priv_dev->gadget.state < USB_STATE_ADDRESS) > + return -EINVAL; > + > + if (ctrl_req->wLength != 6) { > + dev_err(priv_dev->dev, "Set SEL should be 6 bytes, got %d\n", > + ctrl_req->wLength); > + return -EINVAL; > + } > + > + cdns3_ep0_run_transfer(priv_dev, priv_dev->setup_dma, 6, 1); > + return 0; > +} > + > +/** > + * cdns3_req_ep0_set_isoch_delay - > + * Handling of GET_ISOCH_DELAY standard USB request > + * @priv_dev: extended gadget object > + * @ctrl_req: pointer to received setup packet > + * > + * Returns 0 if success, error code on error > + */ > +static int cdns3_req_ep0_set_isoch_delay(struct cdns3_device *priv_dev, > + struct usb_ctrlrequest *ctrl_req) > +{ > + if (ctrl_req->wIndex || ctrl_req->wLength) > + return -EINVAL; > + > + priv_dev->isoch_delay = ctrl_req->wValue; > + > + return 0; > +} > + > +/** > + * cdns3_ep0_standard_request - Handling standard USB requests > + * @priv_dev: extended gadget object > + * @ctrl_req: pointer to received setup packet > + * > + * Returns 0 if success, error code on error > + */ > +static int cdns3_ep0_standard_request(struct cdns3_device *priv_dev, > + struct usb_ctrlrequest *ctrl_req) > +{ > + int ret; > + > + switch (ctrl_req->bRequest) { > + case USB_REQ_SET_ADDRESS: > + ret = cdns3_req_ep0_set_address(priv_dev, ctrl_req); > + break; > + case USB_REQ_SET_CONFIGURATION: > + ret = cdns3_req_ep0_set_configuration(priv_dev, ctrl_req); > + break; > + case USB_REQ_GET_STATUS: > + ret = cdns3_req_ep0_get_status(priv_dev, ctrl_req); > + break; > + case USB_REQ_CLEAR_FEATURE: > + ret = cdns3_req_ep0_handle_feature(priv_dev, ctrl_req, 0); > + break; > + case USB_REQ_SET_FEATURE: > + ret = cdns3_req_ep0_handle_feature(priv_dev, ctrl_req, 1); > + break; > + case USB_REQ_SET_SEL: > + ret = cdns3_req_ep0_set_sel(priv_dev, ctrl_req); > + break; > + case USB_REQ_SET_ISOCH_DELAY: > + ret = cdns3_req_ep0_set_isoch_delay(priv_dev, ctrl_req); > + break; > + default: > + ret = cdns3_ep0_delegate_req(priv_dev, ctrl_req); > + break; > + } > + > + return ret; > +} > + > +static void __pending_setup_status_handler(struct cdns3_device *priv_dev) > +{ > + struct usb_request *request = priv_dev->pending_status_request; > + > + if (priv_dev->status_completion_no_call && request && > + request->complete) { > + request->complete(&priv_dev->eps[0]->endpoint, request); > + priv_dev->status_completion_no_call = 0; > + } > +} > + > +void cdns3_pending_setup_status_handler(struct work_struct *work) > +{ > + struct cdns3_device *priv_dev = container_of(work, struct cdns3_device, > + pending_status_wq); > + unsigned long flags; > + > + spin_lock_irqsave(&priv_dev->lock, flags); > + __pending_setup_status_handler(priv_dev); > + spin_unlock_irqrestore(&priv_dev->lock, flags); > +} > + > +/** > + * cdns3_gadget_ep_giveback - call struct usb_request's ->complete callback > + * @priv_ep: The endpoint to whom the request belongs to > + * @priv_req: The request we're giving back > + * @status: completion code for the request > + * > + * Must be called with controller's lock held and interrupts disabled. This > + * function will unmap @req and call its ->complete() callback to notify upper > + * layers that it has completed. > + */ > + > +void cdns3_gadget_ep0_giveback(struct cdns3_device *priv_dev, > + int status) > +{ > + struct cdns3_endpoint *priv_ep; > + struct usb_request *request; > + > + priv_ep = priv_dev->eps[0]; > + request = cdns3_next_request(&priv_ep->pending_req_list); > + > + priv_ep->dir = priv_dev->ep0_data_dir; > + cdns3_gadget_giveback(priv_ep, to_cdns3_request(request), status); > +} > + > +/** > + * cdns3_ep0_setup_phase - Handling setup USB requests > + * @priv_dev: extended gadget object > + */ > +static void cdns3_ep0_setup_phase(struct cdns3_device *priv_dev) > +{ > + struct usb_ctrlrequest *ctrl = priv_dev->setup_buf; > + struct cdns3_endpoint *priv_ep = priv_dev->eps[0]; > + int result; > + > + priv_dev->ep0_data_dir = ctrl->bRequestType & USB_DIR_IN; > + > + trace_cdns3_ctrl_req(ctrl); > + > + if (!list_empty(&priv_ep->pending_req_list)) { > + struct usb_request *request; > + > + request = cdns3_next_request(&priv_ep->pending_req_list); > + priv_ep->dir = priv_dev->ep0_data_dir; > + cdns3_gadget_giveback(priv_ep, to_cdns3_request(request), > + -ECONNRESET); > + } > + > + if (le16_to_cpu(ctrl->wLength)) > + priv_dev->ep0_stage = CDNS3_DATA_STAGE; > + else > + priv_dev->ep0_stage = CDNS3_STATUS_STAGE; > + > + if ((ctrl->bRequestType & USB_TYPE_MASK) == USB_TYPE_STANDARD) > + result = cdns3_ep0_standard_request(priv_dev, ctrl); > + else > + result = cdns3_ep0_delegate_req(priv_dev, ctrl); > + > + if (result == USB_GADGET_DELAYED_STATUS) > + return; > + > + if (result < 0) > + cdns3_ep0_complete_setup(priv_dev, 1, 1); > + else if (priv_dev->ep0_stage == CDNS3_STATUS_STAGE) > + cdns3_ep0_complete_setup(priv_dev, 0, 1); > +} > + > +static void cdns3_transfer_completed(struct cdns3_device *priv_dev) > +{ > + struct cdns3_endpoint *priv_ep = priv_dev->eps[0]; > + > + if (!list_empty(&priv_ep->pending_req_list)) { > + struct usb_request *request; > + > + trace_cdns3_complete_trb(priv_ep, priv_ep->trb_pool); > + request = cdns3_next_request(&priv_ep->pending_req_list); > + > + request->actual = > + TRB_LEN(le32_to_cpu(priv_ep->trb_pool->length)); > + > + priv_ep->dir = priv_dev->ep0_data_dir; > + cdns3_gadget_giveback(priv_ep, to_cdns3_request(request), 0); > + } > + > + cdns3_ep0_complete_setup(priv_dev, 0, 0); > +} > + > +/** > + * cdns3_check_new_setup - Check if controller receive new SETUP packet. > + * @priv_dev: extended gadget object > + * > + * The SETUP packet can be kept in on-chip memory or in system memory. > + */ > +static bool cdns3_check_new_setup(struct cdns3_device *priv_dev) > +{ > + u32 ep_sts_reg; > + > + cdns3_select_ep(priv_dev, 0 | USB_DIR_OUT); > + ep_sts_reg = readl(&priv_dev->regs->ep_sts); > + > + return !!(ep_sts_reg & (EP_STS_SETUP | EP_STS_STPWAIT)); > +} > + > +/** > + * cdns3_check_ep0_interrupt_proceed - Processes interrupt related to endpoint 0 > + * @priv_dev: extended gadget object > + * @dir: USB_DIR_IN for IN direction, USB_DIR_OUT for OUT direction > + */ > +void cdns3_check_ep0_interrupt_proceed(struct cdns3_device *priv_dev, int dir) > +{ > + u32 ep_sts_reg; > + > + cdns3_select_ep(priv_dev, dir); > + > + ep_sts_reg = readl(&priv_dev->regs->ep_sts); > + writel(ep_sts_reg, &priv_dev->regs->ep_sts); > + > + trace_cdns3_ep0_irq(priv_dev, ep_sts_reg); > + > + __pending_setup_status_handler(priv_dev); > + > + if ((ep_sts_reg & EP_STS_SETUP)) { > + cdns3_ep0_setup_phase(priv_dev); > + } else if ((ep_sts_reg & EP_STS_IOC) || (ep_sts_reg & EP_STS_ISP)) { > + priv_dev->ep0_data_dir = dir; > + cdns3_transfer_completed(priv_dev); > + } > + > + if (ep_sts_reg & EP_STS_DESCMIS) { > + if (dir == 0 && !priv_dev->setup_pending) > + cdns3_prepare_setup_packet(priv_dev); > + } > +} > + > +/** > + * cdns3_gadget_ep0_enable > + * Function shouldn't be called by gadget driver, > + * endpoint 0 is allways active > + */ > +static int cdns3_gadget_ep0_enable(struct usb_ep *ep, > + const struct usb_endpoint_descriptor *desc) > +{ > + return -EINVAL; > +} > + > +/** > + * cdns3_gadget_ep0_disable > + * Function shouldn't be called by gadget driver, > + * endpoint 0 is allways active > + */ > +static int cdns3_gadget_ep0_disable(struct usb_ep *ep) > +{ > + return -EINVAL; > +} > + > +/** > + * cdns3_gadget_ep0_set_halt > + * @ep: pointer to endpoint zero object > + * @value: 1 for set stall, 0 for clear stall > + * > + * Returns 0 > + */ > +static int cdns3_gadget_ep0_set_halt(struct usb_ep *ep, int value) > +{ > + /* TODO */ > + return 0; > +} > + > +/** > + * cdns3_gadget_ep0_queue Transfer data on endpoint zero > + * @ep: pointer to endpoint zero object > + * @request: pointer to request object > + * @gfp_flags: gfp flags > + * > + * Returns 0 on success, error code elsewhere > + */ > +static int cdns3_gadget_ep0_queue(struct usb_ep *ep, > + struct usb_request *request, > + gfp_t gfp_flags) > +{ > + struct cdns3_endpoint *priv_ep = ep_to_cdns3_ep(ep); > + struct cdns3_device *priv_dev = priv_ep->cdns3_dev; > + unsigned long flags; > + int erdy_sent = 0; > + int ret = 0; > + > + cdns3_dbg(priv_ep->cdns3_dev, "Queue to Ep0%s L: %d\n", > + priv_dev->ep0_data_dir ? "IN" : "OUT", > + request->length); > + > + /* cancel the request if controller receive new SETUP packet. */ > + if (cdns3_check_new_setup(priv_dev)) > + return -ECONNRESET; > + > + /* send STATUS stage. Should be called only for SET_CONFIGURATION */ > + if (priv_dev->ep0_stage == CDNS3_STATUS_STAGE) { > + spin_lock_irqsave(&priv_dev->lock, flags); > + cdns3_select_ep(priv_dev, 0x00); > + > + erdy_sent = !priv_dev->hw_configured_flag; > + cdns3_set_hw_configuration(priv_dev); > + > + if (!erdy_sent) > + cdns3_ep0_complete_setup(priv_dev, 0, 1); > + > + request->actual = 0; > + priv_dev->status_completion_no_call = true; > + priv_dev->pending_status_request = request; > + spin_unlock_irqrestore(&priv_dev->lock, flags); > + > + /* > + * Since there is no completion interrupt for status stage, > + * it needs to call ->completion in software after > + * ep0_queue is back. > + */ > + queue_work(system_freezable_wq, &priv_dev->pending_status_wq); > + return 0; > + } > + > + spin_lock_irqsave(&priv_dev->lock, flags); > + if (!list_empty(&priv_ep->pending_req_list)) { > + dev_err(priv_dev->dev, > + "can't handle multiple requests for ep0\n"); > + spin_unlock_irqrestore(&priv_dev->lock, flags); > + return -EBUSY; > + } > + > + ret = usb_gadget_map_request_by_dev(priv_dev->sysdev, request, > + priv_dev->ep0_data_dir); > + if (ret) { > + spin_unlock_irqrestore(&priv_dev->lock, flags); > + dev_err(priv_dev->dev, "failed to map request\n"); > + return -EINVAL; > + } > + > + request->status = -EINPROGRESS; > + list_add_tail(&request->list, &priv_ep->pending_req_list); > + cdns3_ep0_run_transfer(priv_dev, request->dma, request->length, 1); > + spin_unlock_irqrestore(&priv_dev->lock, flags); > + > + return ret; > +} > + > +/** > + * cdns3_gadget_ep_set_wedge Set wedge on selected endpoint > + * @ep: endpoint object > + * > + * Returns 0 > + */ > +int cdns3_gadget_ep_set_wedge(struct usb_ep *ep) > +{ > + struct cdns3_endpoint *priv_ep = ep_to_cdns3_ep(ep); > + struct cdns3_device *priv_dev = priv_ep->cdns3_dev; > + > + dev_dbg(priv_dev->dev, "Wedge for %s\n", ep->name); > + cdns3_gadget_ep_set_halt(ep, 1); > + priv_ep->flags |= EP_WEDGE; > + > + return 0; > +} > + > +const struct usb_ep_ops cdns3_gadget_ep0_ops = { > + .enable = cdns3_gadget_ep0_enable, > + .disable = cdns3_gadget_ep0_disable, > + .alloc_request = cdns3_gadget_ep_alloc_request, > + .free_request = cdns3_gadget_ep_free_request, > + .queue = cdns3_gadget_ep0_queue, > + .dequeue = cdns3_gadget_ep_dequeue, > + .set_halt = cdns3_gadget_ep0_set_halt, > + .set_wedge = cdns3_gadget_ep_set_wedge, > +}; > + > +/** > + * cdns3_ep0_config - Configures default endpoint > + * @priv_dev: extended gadget object > + * > + * Functions sets parameters: maximal packet size and enables interrupts > + */ > +void cdns3_ep0_config(struct cdns3_device *priv_dev) > +{ > + struct cdns3_usb_regs __iomem *regs; > + struct cdns3_endpoint *priv_ep; > + u32 max_packet_size = 64; > + > + regs = priv_dev->regs; > + > + if (priv_dev->gadget.speed == USB_SPEED_SUPER) > + max_packet_size = 512; > + > + priv_ep = priv_dev->eps[0]; > + > + if (!list_empty(&priv_ep->pending_req_list)) { > + struct usb_request *request; > + > + request = cdns3_next_request(&priv_ep->pending_req_list); > + list_del_init(&request->list); > + } > + > + priv_dev->u1_allowed = 0; > + priv_dev->u2_allowed = 0; > + > + priv_dev->gadget.ep0->maxpacket = max_packet_size; > + cdns3_gadget_ep0_desc.wMaxPacketSize = cpu_to_le16(max_packet_size); > + > + /* init ep out */ > + cdns3_select_ep(priv_dev, USB_DIR_OUT); > + > + writel(EP_CFG_ENABLE | EP_CFG_MAXPKTSIZE(max_packet_size), > + ®s->ep_cfg); > + > + writel(EP_STS_EN_SETUPEN | EP_STS_EN_DESCMISEN | EP_STS_EN_TRBERREN, > + ®s->ep_sts_en); > + > + /* init ep in */ > + cdns3_select_ep(priv_dev, USB_DIR_IN); > + > + writel(EP_CFG_ENABLE | EP_CFG_MAXPKTSIZE(max_packet_size), > + ®s->ep_cfg); > + > + writel(EP_STS_EN_SETUPEN | EP_STS_EN_TRBERREN, ®s->ep_sts_en); > + > + cdns3_set_register_bit(®s->usb_conf, USB_CONF_U1DS | USB_CONF_U2DS); > +} > + > +/** > + * cdns3_init_ep0 Initializes software endpoint 0 of gadget > + * @priv_dev: extended gadget object > + * @ep_priv: extended endpoint object > + * > + * Returns 0 on success else error code. > + */ > +int cdns3_init_ep0(struct cdns3_device *priv_dev, > + struct cdns3_endpoint *priv_ep) > +{ > + sprintf(priv_ep->name, "ep0"); > + > + /* fill linux fields */ > + priv_ep->endpoint.ops = &cdns3_gadget_ep0_ops; > + priv_ep->endpoint.maxburst = 1; > + usb_ep_set_maxpacket_limit(&priv_ep->endpoint, > + CDNS3_EP0_MAX_PACKET_LIMIT); > + priv_ep->endpoint.address = 0; > + priv_ep->endpoint.caps.type_control = 1; > + priv_ep->endpoint.caps.dir_in = 1; > + priv_ep->endpoint.caps.dir_out = 1; > + priv_ep->endpoint.name = priv_ep->name; > + priv_ep->endpoint.desc = &cdns3_gadget_ep0_desc; > + priv_dev->gadget.ep0 = &priv_ep->endpoint; > + priv_ep->type = USB_ENDPOINT_XFER_CONTROL; > + > + return cdns3_allocate_trb_pool(priv_ep); > +} > diff --git a/drivers/usb/cdns3/gadget-export.h b/drivers/usb/cdns3/gadget-export.h > new file mode 100644 > index 000000000000..577469eee961 > --- /dev/null > +++ b/drivers/usb/cdns3/gadget-export.h > @@ -0,0 +1,28 @@ > +/* SPDX-License-Identifier: GPL-2.0 */ > +/* > + * Cadence USBSS DRD Driver - Gadget Export APIs. > + * > + * Copyright (C) 2017 NXP > + * Copyright (C) 2017-2018 NXP > + * > + * Authors: Peter Chen > + */ > +#ifndef __LINUX_CDNS3_GADGET_EXPORT > +#define __LINUX_CDNS3_GADGET_EXPORT > + > +#ifdef CONFIG_USB_CDNS3_GADGET > + > +int cdns3_gadget_init(struct cdns3 *cdns); > +void cdns3_gadget_exit(struct cdns3 *cdns); > +#else > + > +static inline int cdns3_gadget_init(struct cdns3 *cdns) > +{ > + return -ENXIO; > +} > + > +static inline void cdns3_gadget_exit(struct cdns3 *cdns) { } > + > +#endif > + > +#endif /* __LINUX_CDNS3_GADGET_EXPORT */ > diff --git a/drivers/usb/cdns3/gadget.c b/drivers/usb/cdns3/gadget.c > new file mode 100644 > index 000000000000..7f7f24ee3c4b > --- /dev/null > +++ b/drivers/usb/cdns3/gadget.c > @@ -0,0 +1,2003 @@ > +// SPDX-License-Identifier: GPL-2.0 > +/* > + * Cadence USBSS DRD Driver - gadget side. > + * > + * Copyright (C) 2018 Cadence Design Systems. > + * Copyright (C) 2017-2018 NXP > + * > + * Authors: Pawel Jez , > + * Pawel Laszczak > + * Peter Chen > + */ > + > +/* > + * Work around 1: > + * At some situations, the controller may get stale data address in TRB > + * at below sequences: > + * 1. Controller read TRB includes data address > + * 2. Software updates TRBs includes data address and Cycle bit > + * 3. Controller read TRB which includes Cycle bit > + * 4. DMA run with stale data address > + > + * To fix this problem, we need to make the first TRB in TD as invalid TRB when > + * the TD which the DMA is handling close to the TRB we are adding, > + * and make this TRB as valid at TRBERR interrupt. The condition for > + * this TRB is: > + * > + * If (((Dequeue Ptr (i.e. EP_TRADDR) == Enqueue Ptr-1) or > + * (Dequeue Ptr (i.e. EP_TRADDR) == Enqueue Ptr)) > + * and (DRBL==1 and (not EP0))) > + */ > + > +#include > +#include > +#include > + > +#include "core.h" > +#include "gadget-export.h" > +#include "gadget.h" > +#include "trace.h" > + > +static int __cdns3_gadget_ep_queue(struct usb_ep *ep, > + struct usb_request *request, > + gfp_t gfp_flags); > + > +/** > + * cdns3_handshake - spin reading until handshake completes or fails > + * @ptr: address of device controller register to be read > + * @mask: bits to look at in result of read > + * @done: value of those bits when handshake succeeds > + * @usec: timeout in microseconds > + * > + * Returns negative errno, or zero on success > + * > + * Success happens when the "mask" bits have the specified value (hardware > + * handshake done). There are two failure modes: "usec" have passed (major > + * hardware flakeout), or the register reads as all-ones (hardware removed). > + */ > +int cdns3_handshake(void __iomem *ptr, u32 mask, u32 done, int usec) > +{ > + u32 result; > + > + do { > + result = readl(ptr); > + if (result == ~(u32)0) /* card removed */ > + return -ENODEV; > + result &= mask; > + if (result == done) > + return 0; > + udelay(1); > + usec--; > + } while (usec > 0); > + return -ETIMEDOUT; > +} > + > +/** > + * cdns3_set_register_bit - set bit in given register. > + * @ptr: address of device controller register to be read and changed > + * @mask: bits requested to set > + */ > +void cdns3_set_register_bit(void __iomem *ptr, u32 mask) > +{ > + mask = readl(ptr) | mask; > + writel(mask, ptr); > +} > + > +/** > + * cdns3_ep_addr_to_index - Macro converts endpoint address to > + * index of endpoint object in cdns3_device.eps[] container > + * @ep_addr: endpoint address for which endpoint object is required > + * > + */ > +u8 cdns3_ep_addr_to_index(u8 ep_addr) > +{ > + return (((ep_addr & 0x7F)) + ((ep_addr & USB_DIR_IN) ? 16 : 0)); > +} > + > +/** > + * cdns3_next_request - returns next request from list > + * @list: list containing requests > + * > + * Returns request or NULL if no requests in list > + */ > +struct usb_request *cdns3_next_request(struct list_head *list) > +{ > + return list_first_entry_or_null(list, struct usb_request, list); > +} > + > +/** > + * select_ep - selects endpoint > + * @priv_dev: extended gadget object > + * @ep: endpoint address > + */ > +void cdns3_select_ep(struct cdns3_device *priv_dev, u32 ep) > +{ > + if (priv_dev->selected_ep == ep) > + return; > + > + priv_dev->selected_ep = ep; > + writel(ep, &priv_dev->regs->ep_sel); > +} > + > +dma_addr_t cdns3_trb_virt_to_dma(struct cdns3_endpoint *priv_ep, > + struct cdns3_trb *trb) > +{ > + u32 offset = (char *)trb - (char *)priv_ep->trb_pool; > + > + return priv_ep->trb_pool_dma + offset; > +} > + > +int cdns3_ring_size(struct cdns3_endpoint *priv_ep) > +{ > + switch (priv_ep->type) { > + case USB_ENDPOINT_XFER_ISOC: > + return TRB_ISO_RING_SIZE; > + case USB_ENDPOINT_XFER_CONTROL: > + return TRB_CTRL_RING_SIZE; > + default: > + return TRB_RING_SIZE; > + } > +} > + > +/** > + * cdns3_allocate_trb_pool - Allocates TRB's pool for selected endpoint > + * @priv_ep: endpoint object > + * > + * Function will return 0 on success or -ENOMEM on allocation error > + */ > +int cdns3_allocate_trb_pool(struct cdns3_endpoint *priv_ep) > +{ > + struct cdns3_device *priv_dev = priv_ep->cdns3_dev; > + int ring_size = cdns3_ring_size(priv_ep); > + struct cdns3_trb *link_trb; > + > + if (!priv_ep->trb_pool) { > + priv_ep->trb_pool = dma_zalloc_coherent(priv_dev->sysdev, > + ring_size, > + &priv_ep->trb_pool_dma, > + GFP_DMA); > + if (!priv_ep->trb_pool) > + return -ENOMEM; > + } else { > + memset(priv_ep->trb_pool, 0, ring_size); > + } > + > + if (!priv_ep->num) > + return 0; > + > + if (!priv_ep->aligned_buff) { > + void *buff = dma_alloc_coherent(priv_dev->sysdev, > + CDNS3_ALIGNED_BUF_SIZE, > + &priv_ep->aligned_dma_addr, > + GFP_DMA); > + > + priv_ep->aligned_buff = buff; > + if (!priv_ep->aligned_buff) { > + dma_free_coherent(priv_dev->sysdev, > + ring_size, > + priv_ep->trb_pool, > + priv_ep->trb_pool_dma); > + priv_ep->trb_pool = NULL; > + > + return -ENOMEM; > + } > + } > + > + priv_ep->num_trbs = ring_size / TRB_SIZE; > + /* Initialize the last TRB as Link TRB */ > + link_trb = (priv_ep->trb_pool + (priv_ep->num_trbs - 1)); > + link_trb->buffer = TRB_BUFFER(priv_ep->trb_pool_dma); > + link_trb->control = TRB_CYCLE | TRB_TYPE(TRB_LINK) | > + TRB_CHAIN | TRB_TOGGLE; > + > + return 0; > +} > + > +static void cdns3_free_trb_pool(struct cdns3_endpoint *priv_ep) > +{ > + struct cdns3_device *priv_dev = priv_ep->cdns3_dev; > + > + if (priv_ep->trb_pool) { > + dma_free_coherent(priv_dev->sysdev, > + cdns3_ring_size(priv_ep), > + priv_ep->trb_pool, priv_ep->trb_pool_dma); > + priv_ep->trb_pool = NULL; > + } > + > + if (priv_ep->aligned_buff) { > + dma_free_coherent(priv_dev->sysdev, CDNS3_ALIGNED_BUF_SIZE, > + priv_ep->aligned_buff, > + priv_ep->aligned_dma_addr); > + priv_ep->aligned_buff = NULL; > + } > +} > + > +/** > + * cdns3_data_flush - flush data at onchip buffer > + * @priv_ep: endpoint object > + * > + * Endpoint must be selected before call to this function > + * > + * Returns zero on success or negative value on failure > + */ > +static int cdns3_data_flush(struct cdns3_endpoint *priv_ep) > +{ > + struct cdns3_device *priv_dev = priv_ep->cdns3_dev; > + > + writel(EP_CMD_DFLUSH, &priv_dev->regs->ep_cmd); > + > + /* wait for DFLUSH cleared */ > + return cdns3_handshake(&priv_dev->regs->ep_cmd, EP_CMD_DFLUSH, 0, 100); > +} > + > +/** > + * cdns3_ep_stall_flush - Stalls and flushes selected endpoint > + * @priv_ep: endpoint object > + * > + * Endpoint must be selected before call to this function > + */ > +static void cdns3_ep_stall_flush(struct cdns3_endpoint *priv_ep) > +{ > + struct cdns3_device *priv_dev = priv_ep->cdns3_dev; > + > + cdns3_dbg(priv_ep->cdns3_dev, "Stall & flush endpoint %s\n", > + priv_ep->name); > + > + writel(EP_CMD_DFLUSH | EP_CMD_ERDY | EP_CMD_SSTALL, > + &priv_dev->regs->ep_cmd); > + > + /* wait for DFLUSH cleared */ > + cdns3_handshake(&priv_dev->regs->ep_cmd, EP_CMD_DFLUSH, 0, 100); > + priv_ep->flags |= EP_STALL; > +} > + > +/** > + * cdns3_hw_reset_eps_config - reset endpoints configuration kept by controller. > + * @priv_dev: extended gadget object > + */ > +void cdns3_hw_reset_eps_config(struct cdns3_device *priv_dev) > +{ > + writel(USB_CONF_CFGRST, &priv_dev->regs->usb_conf); > + > + cdns3_allow_enable_l1(priv_dev, 0); > + priv_dev->hw_configured_flag = 0; > + priv_dev->onchip_mem_allocated_size = 0; > +} > + > +/** > + * cdns3_ep_inc_trb - increment a trb index. > + * @index: Pointer to the TRB index to increment. > + * @cs: Cycle state > + * @trb_in_seg: number of TRBs in segment > + * > + * The index should never point to the link TRB. After incrementing, > + * if it is point to the link TRB, wrap around to the beginning and revert > + * cycle state bit The > + * link TRB is always at the last TRB entry. > + */ > +static void cdns3_ep_inc_trb(int *index, u8 *cs, int trb_in_seg) > +{ > + (*index)++; > + if (*index == (trb_in_seg - 1)) { > + *index = 0; > + *cs ^= 1; > + } > +} > + > +/** > + * cdns3_ep_inc_enq - increment endpoint's enqueue pointer > + * @priv_ep: The endpoint whose enqueue pointer we're incrementing > + */ > +static void cdns3_ep_inc_enq(struct cdns3_endpoint *priv_ep) > +{ > + priv_ep->free_trbs--; > + cdns3_ep_inc_trb(&priv_ep->enqueue, &priv_ep->pcs, priv_ep->num_trbs); > +} > + > +/** > + * cdns3_ep_inc_deq - increment endpoint's dequeue pointer > + * @priv_ep: The endpoint whose dequeue pointer we're incrementing > + */ > +static void cdns3_ep_inc_deq(struct cdns3_endpoint *priv_ep) > +{ > + priv_ep->free_trbs++; > + cdns3_ep_inc_trb(&priv_ep->dequeue, &priv_ep->ccs, priv_ep->num_trbs); > +} > + > +void cdns3_move_deq_to_next_trb(struct cdns3_request *priv_req) > +{ > + struct cdns3_endpoint *priv_ep = priv_req->priv_ep; > + int current_trb = priv_req->start_trb; > + > + while (current_trb != priv_req->end_trb) { > + cdns3_ep_inc_deq(priv_ep); > + current_trb = priv_ep->dequeue; > + } > + > + cdns3_ep_inc_deq(priv_ep); > +} > + > +/** > + * cdns3_allow_enable_l1 - enable/disable permits to transition to L1. > + * @priv_dev: Extended gadget object > + * @enable: Enable/disable permit to transition to L1. > + * > + * If bit USB_CONF_L1EN is set and device receive Extended Token packet, > + * then controller answer with ACK handshake. > + * If bit USB_CONF_L1DS is set and device receive Extended Token packet, > + * then controller answer with NYET handshake. > + */ > +void cdns3_allow_enable_l1(struct cdns3_device *priv_dev, int enable) > +{ > + if (enable) > + writel(USB_CONF_L1EN, &priv_dev->regs->usb_conf); > + else > + writel(USB_CONF_L1DS, &priv_dev->regs->usb_conf); > +} > + > +enum usb_device_speed cdns3_get_speed(struct cdns3_device *priv_dev) > +{ > + u32 reg; > + > + reg = readl(&priv_dev->regs->usb_sts); > + > + if (DEV_SUPERSPEED(reg)) > + return USB_SPEED_SUPER; > + else if (DEV_HIGHSPEED(reg)) > + return USB_SPEED_HIGH; > + else if (DEV_FULLSPEED(reg)) > + return USB_SPEED_FULL; > + else if (DEV_LOWSPEED(reg)) > + return USB_SPEED_LOW; > + return USB_SPEED_UNKNOWN; > +} > + > +/** > + * cdns3_start_all_request - add to ring all request not started > + * @priv_dev: Extended gadget object > + * @priv_ep: The endpoint for whom request will be started. > + * > + * Returns return ENOMEM if transfer ring i not enough TRBs to start > + * all requests. > + */ > +static int cdns3_start_all_request(struct cdns3_device *priv_dev, > + struct cdns3_endpoint *priv_ep) > +{ > + struct cdns3_request *priv_req; > + struct usb_request *request; > + int ret = 0; > + > + while (!list_empty(&priv_ep->deferred_req_list)) { > + request = cdns3_next_request(&priv_ep->deferred_req_list); > + priv_req = to_cdns3_request(request); > + > + ret = cdns3_ep_run_transfer(priv_ep, request); > + if (ret) > + return ret; > + > + list_del(&request->list); > + list_add_tail(&request->list, > + &priv_ep->pending_req_list); > + } > + > + priv_ep->flags &= ~EP_RING_FULL; > + return ret; > +} > + > +/** > + * cdns3_gadget_giveback - call struct usb_request's ->complete callback > + * @priv_ep: The endpoint to whom the request belongs to > + * @priv_req: The request we're giving back > + * @status: completion code for the request > + * > + * Must be called with controller's lock held and interrupts disabled. This > + * function will unmap @req and call its ->complete() callback to notify upper > + * layers that it has completed. > + */ > +void cdns3_gadget_giveback(struct cdns3_endpoint *priv_ep, > + struct cdns3_request *priv_req, > + int status) > +{ > + struct cdns3_device *priv_dev = priv_ep->cdns3_dev; > + struct usb_request *request = &priv_req->request; > + > + list_del_init(&request->list); > + > + if (request->status == -EINPROGRESS) > + request->status = status; > + > + usb_gadget_unmap_request_by_dev(priv_dev->sysdev, request, > + priv_ep->dir); > + > + priv_req->flags &= ~REQUEST_PENDING; > + trace_cdns3_gadget_giveback(priv_req); > + > + /* Start all not pending request */ > + if (priv_ep->flags & EP_RING_FULL) > + cdns3_start_all_request(priv_dev, priv_ep); > + > + if (request->complete) { > + spin_unlock(&priv_dev->lock); > + usb_gadget_giveback_request(&priv_ep->endpoint, > + request); > + spin_lock(&priv_dev->lock); > + } > + > + if (request->buf == priv_dev->zlp_buf) > + cdns3_gadget_ep_free_request(&priv_ep->endpoint, request); > +} > + > +/** > + * cdns3_ep_run_transfer - start transfer on no-default endpoint hardware > + * @priv_ep: endpoint object > + * > + * Returns zero on success or negative value on failure > + */ > +int cdns3_ep_run_transfer(struct cdns3_endpoint *priv_ep, > + struct usb_request *request) > +{ > + struct cdns3_device *priv_dev = priv_ep->cdns3_dev; > + struct cdns3_request *priv_req; > + struct cdns3_trb *trb; > + dma_addr_t trb_dma; > + int dma_index; > + int sg_iter = 0; > + u32 first_pcs; > + int num_trb; > + int address; > + u32 doorbell; > + int pcs; > + > + if (priv_ep->type == USB_ENDPOINT_XFER_ISOC) > + num_trb = priv_ep->interval; > + else > + num_trb = request->num_sgs ? request->num_sgs : 1; > + > + if (num_trb > priv_ep->free_trbs) { > + priv_ep->flags |= EP_RING_FULL; > + return -ENOBUFS; > + } > + > + priv_req = to_cdns3_request(request); > + address = priv_ep->endpoint.desc->bEndpointAddress; > + > + priv_ep->flags |= EP_PENDING_REQUEST; > + trb_dma = request->dma; > + > + /* must allocate buffer aligned to 8 */ > + if ((request->dma % 8)) { > + if (request->length <= CDNS3_ALIGNED_BUF_SIZE) { > + memcpy(priv_ep->aligned_buff, request->buf, > + request->length); > + trb_dma = priv_ep->aligned_dma_addr; > + } else { > + return -ENOMEM; > + } > + } > + > + trb = priv_ep->trb_pool + priv_ep->enqueue; > + priv_req->start_trb = priv_ep->enqueue; > + priv_req->trb = trb; > + > + /* prepare ring */ > + if ((priv_ep->enqueue + num_trb) >= (priv_ep->num_trbs - 1)) { > + /*updating C bt in Link TRB before starting DMA*/ > + struct cdns3_trb *link_trb = priv_ep->trb_pool + > + (priv_ep->num_trbs - 1); > + link_trb->control = ((priv_ep->pcs) ? TRB_CYCLE : 0) | > + TRB_TYPE(TRB_LINK) | TRB_CHAIN | > + TRB_TOGGLE; > + } > + > + first_pcs = priv_ep->pcs ? TRB_CYCLE : 0; > + > + /* arm transfer on selected endpoint */ > + cdns3_select_ep(priv_ep->cdns3_dev, address); > + > + doorbell = !!(readl(&priv_dev->regs->ep_cmd) & EP_CMD_DRDY); > + dma_index = (readl(&priv_dev->regs->ep_traddr) - > + priv_ep->trb_pool_dma) / TRB_SIZE; > + > + if (!priv_ep->wa1_set) { > + if (doorbell && > + ((priv_ep->enqueue == 0 && > + dma_index >= GET_TRBS_PER_SEGMENT(priv_ep->type) - 2) || > + dma_index == priv_ep->enqueue || > + (dma_index == priv_ep->enqueue - 1))) { > + priv_ep->wa1_cycle_bit = first_pcs; > + priv_ep->wa1_set = 1; > + priv_ep->wa1_trb = trb; > + first_pcs ^= 0x1; > + cdns3_dbg(priv_dev, "WA1: deferred doorbel\n"); > + } > + } > + > + do { > + /* fill TRB */ > + trb->buffer = TRB_BUFFER(request->num_sgs == 0 > + ? trb_dma : request->sg[sg_iter].dma_address); > + > + trb->length = TRB_BURST_LEN(16) | > + TRB_LEN(request->num_sgs == 0 ? > + request->length : request->sg[sg_iter].length); > + > + trb->control = TRB_TYPE(TRB_NORMAL); > + pcs = priv_ep->pcs ? TRB_CYCLE : 0; > + > + /* > + * first trb should be prepared as last to avoid processing > + * transfer to early > + */ > + if (sg_iter != 0) > + trb->control |= pcs; > + > + if (priv_ep->type == USB_ENDPOINT_XFER_ISOC && !priv_ep->dir) { > + trb->control |= TRB_IOC | TRB_ISP; > + } else { > + /* for last element in TD or in SG list */ > + if (sg_iter == (num_trb - 1) && sg_iter != 0) > + trb->control |= pcs | TRB_IOC | TRB_ISP; > + } > + ++sg_iter; > + priv_req->end_trb = priv_ep->enqueue; > + cdns3_ep_inc_enq(priv_ep); > + trb = priv_ep->trb_pool + priv_ep->enqueue; > + } while (sg_iter < num_trb); > + > + trb = priv_req->trb; > + > + priv_req->flags |= REQUEST_PENDING; > + > + /* > + * Memory barrier - cycle bit must be set before other filds in trb. > + */ > + wmb(); > + > + /* give the TD to the consumer*/ > + if (sg_iter == 1) > + trb->control |= first_pcs | TRB_IOC | TRB_ISP; > + else > + trb->control |= first_pcs; > + > + trace_cdns3_prepare_trb(priv_ep, priv_req->trb); > + > + /* > + * Memory barrier - Cycle Bit must be set before trb->length and > + * trb->buffer fields. > + */ > + wmb(); > + > + /* > + * For DMULT mode we can set address to transfer ring only once after > + * enabling endpoint. > + */ > + if (priv_ep->flags & EP_UPDATE_EP_TRBADDR) { > + writel(EP_TRADDR_TRADDR(priv_ep->trb_pool_dma + > + priv_req->start_trb * TRB_SIZE), > + &priv_dev->regs->ep_traddr); > + > + cdns3_dbg(priv_ep->cdns3_dev, "Update ep_trbaddr for %s to %08x\n", > + priv_ep->name, readl(&priv_dev->regs->ep_traddr)); > + > + priv_ep->flags &= ~EP_UPDATE_EP_TRBADDR; > + } > + > + if (!priv_ep->wa1_set && !(priv_ep->flags & EP_STALL)) { > + trace_cdns3_ring(priv_ep); > + /*clearing TRBERR and EP_STS_DESCMIS before seting DRDY*/ > + writel(EP_STS_TRBERR | EP_STS_DESCMIS, &priv_dev->regs->ep_sts); > + writel(EP_CMD_DRDY, &priv_dev->regs->ep_cmd); > + trace_cdns3_doorbell_epx(priv_ep->name, > + readl(&priv_dev->regs->ep_traddr)); > + } > + > + return 0; > +} > + > +void cdns3_set_hw_configuration(struct cdns3_device *priv_dev) > +{ > + struct cdns3_endpoint *priv_ep; > + struct usb_ep *ep; > + int result = 0; > + > + if (priv_dev->hw_configured_flag) > + return; > + > + writel(USB_CONF_CFGSET, &priv_dev->regs->usb_conf); > + writel(EP_CMD_ERDY | EP_CMD_REQ_CMPL, &priv_dev->regs->ep_cmd); > + > + cdns3_set_register_bit(&priv_dev->regs->usb_conf, > + USB_CONF_U1EN | USB_CONF_U2EN); > + > + /* wait until configuration set */ > + result = cdns3_handshake(&priv_dev->regs->usb_sts, > + USB_STS_CFGSTS_MASK, 1, 100); > + > + priv_dev->hw_configured_flag = 1; > + cdns3_allow_enable_l1(priv_dev, 1); > + > + list_for_each_entry(ep, &priv_dev->gadget.ep_list, ep_list) { > + if (ep->enabled) { > + priv_ep = ep_to_cdns3_ep(ep); > + cdns3_start_all_request(priv_dev, priv_ep); > + } > + } > +} > + > +/** > + * cdns3_request_handled - check whether request has been handled by DMA > + * > + * @priv_ep: extended endpoint object. > + * @priv_req: request object for checking > + * > + * Endpoint must be selected before invoking this function. > + * > + * Returns false if request has not been handled by DMA, else returns true. > + * > + * SR - start ring > + * ER - end ring > + * DQ = priv_ep->dequeue - dequeue position > + * EQ = priv_ep->enqueue - enqueue position > + * ST = priv_req->start_trb - index of first TRB in transfer ring > + * ET = priv_req->end_trb - index of last TRB in transfer ring > + * CI = current_index - index of processed TRB by DMA. > + * > + * As first step, function checks if cycle bit for priv_req->start_trb is > + * correct. > + * > + * some rules: > + * 1. priv_ep->dequeue never exceed current_index. > + * 2 priv_ep->enqueue never exceed priv_ep->dequeue > + * > + * Then We can split recognition into two parts: > + * Case 1 - priv_ep->dequeue < current_index > + * SR ... EQ ... DQ ... CI ... ER > + * SR ... DQ ... CI ... EQ ... ER > + * > + * Request has been handled by DMA if ST and ET is between DQ and CI. > + * > + * Case 2 - priv_ep->dequeue > current_index > + * This situation take place when CI go through the LINK TRB at the end of > + * transfer ring. > + * SR ... CI ... EQ ... DQ ... ER > + * > + * Request has been handled by DMA if ET is less then CI or > + * ET is greater or equal DQ. > + */ > +static bool cdns3_request_handled(struct cdns3_endpoint *priv_ep, > + struct cdns3_request *priv_req) > +{ > + struct cdns3_device *priv_dev = priv_ep->cdns3_dev; > + struct cdns3_trb *trb = priv_req->trb; > + int current_index = 0; > + int handled = 0; > + > + current_index = (readl(&priv_dev->regs->ep_traddr) - > + priv_ep->trb_pool_dma) / TRB_SIZE; > + > + trb = &priv_ep->trb_pool[priv_req->start_trb]; > + > + if ((trb->control & TRB_CYCLE) != priv_ep->ccs) > + goto finish; > + > + if (priv_ep->dequeue < current_index) { > + if ((current_index == (priv_ep->num_trbs - 1)) && > + !priv_ep->dequeue) > + goto finish; > + > + if (priv_req->end_trb >= priv_ep->dequeue && > + priv_req->end_trb < current_index) > + handled = 1; > + } else if (priv_ep->dequeue > current_index) { > + if (priv_req->end_trb < current_index || > + priv_req->end_trb >= priv_ep->dequeue) > + handled = 1; > + } > + > +finish: > + trace_cdns3_request_handled(priv_req, current_index, handled); > + > + return handled; > +} > + > +static void cdns3_transfer_completed(struct cdns3_device *priv_dev, > + struct cdns3_endpoint *priv_ep) > +{ > + struct cdns3_request *priv_req; > + struct usb_request *request; > + struct cdns3_trb *trb; > + > + while (!list_empty(&priv_ep->pending_req_list)) { > + request = cdns3_next_request(&priv_ep->pending_req_list); > + priv_req = to_cdns3_request(request); > + > + /* Re-select endpoint. It could be changed by other CPU during > + * handling usb_gadget_giveback_request. > + */ > + cdns3_select_ep(priv_dev, priv_ep->endpoint.address); > + > + if (!cdns3_request_handled(priv_ep, priv_req)) > + return; > + > + if (request->dma % 8 && priv_ep->dir == USB_DIR_OUT) > + memcpy(request->buf, priv_ep->aligned_buff, > + request->length); > + > + trb = priv_ep->trb_pool + priv_ep->dequeue; > + trace_cdns3_complete_trb(priv_ep, trb); > + > + if (trb != priv_req->trb) > + dev_warn(priv_dev->dev, > + "request_trb=0x%p, queue_trb=0x%p\n", > + priv_req->trb, trb); > + > + request->actual = TRB_LEN(le32_to_cpu(trb->length)); > + cdns3_move_deq_to_next_trb(priv_req); > + cdns3_gadget_giveback(priv_ep, priv_req, 0); > + } > + priv_ep->flags &= ~EP_PENDING_REQUEST; > +} > + > +void cdns3_wa1_restore_cycle_bit(struct cdns3_endpoint *priv_ep) > +{ > + struct cdns3_device *priv_dev = priv_ep->cdns3_dev; > + > + /* Work around for stale data address in TRB*/ > + if (priv_ep->wa1_set) { > + cdns3_dbg(priv_dev, "WA1: update cycle bit\n"); > + priv_ep->wa1_set = 0; > + if (priv_ep->wa1_cycle_bit) { > + priv_ep->wa1_trb->control = > + priv_ep->wa1_trb->control | 0x1; > + } else { > + priv_ep->wa1_trb->control = > + priv_ep->wa1_trb->control & ~0x1; > + } > + } > +} > + > +void cdns3_rearm_transfer(struct cdns3_endpoint *priv_ep, u8 rearm) > +{ > + struct cdns3_device *priv_dev = priv_ep->cdns3_dev; > + > + cdns3_wa1_restore_cycle_bit(priv_ep); > + > + if (rearm) { > + trace_cdns3_ring(priv_ep); > + > + /* Cycle Bit must be updated before arming DMA. */ > + wmb(); > + writel(EP_CMD_DRDY, &priv_dev->regs->ep_cmd); > + > + trace_cdns3_doorbell_epx(priv_ep->name, > + readl(&priv_dev->regs->ep_traddr)); > + } > +} > + > +/** > + * cdns3_check_ep_interrupt_proceed - Processes interrupt related to endpoint > + * @priv_ep: endpoint object > + * > + * Returns 0 > + */ > +static int cdns3_check_ep_interrupt_proceed(struct cdns3_endpoint *priv_ep) > +{ > + struct cdns3_device *priv_dev = priv_ep->cdns3_dev; > + u32 ep_sts_reg; > + > + cdns3_select_ep(priv_dev, priv_ep->endpoint.address); > + > + trace_cdns3_epx_irq(priv_dev, priv_ep); > + > + ep_sts_reg = readl(&priv_dev->regs->ep_sts); > + writel(ep_sts_reg, &priv_dev->regs->ep_sts); > + > + if (ep_sts_reg & EP_STS_TRBERR) { > + /* > + * For isochronous transfer driver completes request on > + * IOC or on TRBERR. IOC appears only when device receive > + * OUT data packet. If host disable stream or lost some packet > + * then the only way to finish all queued transfer is to do it > + * on TRBERR event. > + */ > + if (priv_ep->type == USB_ENDPOINT_XFER_ISOC && > + !priv_ep->wa1_set) > + cdns3_transfer_completed(priv_dev, priv_ep); > + else > + cdns3_rearm_transfer(priv_ep, priv_ep->wa1_set); > + } > + > + if ((ep_sts_reg & EP_STS_IOC) || (ep_sts_reg & EP_STS_ISP)) > + cdns3_transfer_completed(priv_dev, priv_ep); > + > + return 0; > +} > + > +/** > + * cdns3_check_usb_interrupt_proceed - Processes interrupt related to device > + * @priv_dev: extended gadget object > + * @usb_ists: bitmap representation of device's reported interrupts > + * (usb_ists register value) > + */ > +static void cdns3_check_usb_interrupt_proceed(struct cdns3_device *priv_dev, > + u32 usb_ists) > +{ > + int speed = 0; > + > + trace_cdns3_usb_irq(priv_dev, usb_ists); > + /* Connection detected */ > + if (usb_ists & (USB_ISTS_CON2I | USB_ISTS_CONI)) { > + speed = cdns3_get_speed(priv_dev); > + priv_dev->gadget.speed = speed; > + usb_gadget_set_state(&priv_dev->gadget, USB_STATE_POWERED); > + cdns3_ep0_config(priv_dev); > + } > + > + /* Disconnection detected */ > + if (usb_ists & (USB_ISTS_DIS2I | USB_ISTS_DISI)) { > + if (priv_dev->gadget_driver && > + priv_dev->gadget_driver->disconnect) { > + spin_unlock(&priv_dev->lock); > + priv_dev->gadget_driver->disconnect(&priv_dev->gadget); > + spin_lock(&priv_dev->lock); > + } > + > + priv_dev->gadget.speed = USB_SPEED_UNKNOWN; > + usb_gadget_set_state(&priv_dev->gadget, USB_STATE_NOTATTACHED); > + cdns3_hw_reset_eps_config(priv_dev); > + } > + > + /* reset*/ > + if (usb_ists & (USB_ISTS_UWRESI | USB_ISTS_UHRESI | USB_ISTS_U2RESI)) { > + /*read again to check the actuall speed*/ > + speed = cdns3_get_speed(priv_dev); > + usb_gadget_set_state(&priv_dev->gadget, USB_STATE_DEFAULT); > + priv_dev->gadget.speed = speed; > + cdns3_hw_reset_eps_config(priv_dev); > + cdns3_ep0_config(priv_dev); > + } > +} > + > +/** > + * cdns3_device_irq_handler- interrupt handler for device part of controller > + * > + * @irq: irq number for cdns3 core device > + * @data: structure of cdns3 > + * > + * Returns IRQ_HANDLED or IRQ_NONE > + */ > +static irqreturn_t cdns3_device_irq_handler(int irq, void *data) > +{ > + struct cdns3_device *priv_dev; > + struct cdns3 *cdns = data; > + irqreturn_t ret = IRQ_NONE; > + unsigned long flags; > + u32 reg; > + > + priv_dev = cdns->gadget_dev; > + spin_lock_irqsave(&priv_dev->lock, flags); > + > + /* check USB device interrupt */ > + reg = readl(&priv_dev->regs->usb_ists); > + writel(reg, &priv_dev->regs->usb_ists); > + > + if (reg) { > + cdns3_check_usb_interrupt_proceed(priv_dev, reg); > + ret = IRQ_HANDLED; > + } > + > + /* check endpoint interrupt */ > + reg = readl(&priv_dev->regs->ep_ists); > + > + if (reg) { > + priv_dev->shadow_ep_en |= reg; > + reg = ~reg & readl(&priv_dev->regs->ep_ien); > + /* mask deferred interrupt. */ > + writel(reg, &priv_dev->regs->ep_ien); > + ret = IRQ_WAKE_THREAD; > + } > + > + spin_unlock_irqrestore(&priv_dev->lock, flags); > + return ret; > +} > + > +/** > + * cdns3_device_thread_irq_handler- interrupt handler for device part > + * of controller > + * > + * @irq: irq number for cdns3 core device > + * @data: structure of cdns3 > + * > + * Returns IRQ_HANDLED or IRQ_NONE > + */ > +static irqreturn_t cdns3_device_thread_irq_handler(int irq, void *data) > +{ > + struct cdns3_device *priv_dev; > + struct cdns3 *cdns = data; > + irqreturn_t ret = IRQ_NONE; > + unsigned long flags; > + u32 ep_ien; > + int bit; > + u32 reg; > + > + priv_dev = cdns->gadget_dev; > + spin_lock_irqsave(&priv_dev->lock, flags); > + > + reg = readl(&priv_dev->regs->ep_ists); > + > + /* handle default endpoint OUT */ > + if (reg & EP_ISTS_EP_OUT0) { > + cdns3_check_ep0_interrupt_proceed(priv_dev, USB_DIR_OUT); > + ret = IRQ_HANDLED; > + } > + > + /* handle default endpoint IN */ > + if (reg & EP_ISTS_EP_IN0) { > + cdns3_check_ep0_interrupt_proceed(priv_dev, USB_DIR_IN); > + ret = IRQ_HANDLED; > + } > + > + /* check if interrupt from non default endpoint, if no exit */ > + reg &= ~(EP_ISTS_EP_OUT0 | EP_ISTS_EP_IN0); > + if (!reg) > + goto irqend; > + > + for_each_set_bit(bit, (unsigned long *)®, > + sizeof(u32) * BITS_PER_BYTE) { > + priv_dev->shadow_ep_en |= BIT(bit); > + cdns3_check_ep_interrupt_proceed(priv_dev->eps[bit]); > + ret = IRQ_HANDLED; > + } > + > +irqend: > + ep_ien = readl(&priv_dev->regs->ep_ien) | priv_dev->shadow_ep_en; > + priv_dev->shadow_ep_en = 0; > + /* Unmask all handled EP interrupts */ > + writel(ep_ien, &priv_dev->regs->ep_ien); > + spin_unlock_irqrestore(&priv_dev->lock, flags); > + return ret; > +} > + > +/** > + * cdns3_ep_onchip_buffer_reserve - Try to reserve onchip buf for EP > + * > + * The real reservation will occur during write to EP_CFG register, > + * this function is used to check if the 'size' reservation is allowed. > + * > + * @priv_dev: extended gadget object > + * @size: the size (KB) for EP would like to allocate > + * > + * Return 0 if the required size can met or negative value on failure > + */ > +static int cdns3_ep_onchip_buffer_reserve(struct cdns3_device *priv_dev, > + int size) > +{ > + u32 onchip_mem; > + > + priv_dev->onchip_mem_allocated_size += size; > + > + onchip_mem = USB_CAP2_ACTUAL_MEM_SIZE(readl(&priv_dev->regs->usb_cap2)); > + if (!onchip_mem) > + onchip_mem = 256; > + > + /* 2KB is reserved for EP0*/ > + onchip_mem -= 2; > + if (priv_dev->onchip_mem_allocated_size > onchip_mem) { > + priv_dev->onchip_mem_allocated_size -= size; > + return -EPERM; > + } > + > + return 0; > +} > + > +/** > + * cdns3_ep_config Configure hardware endpoint > + * @priv_ep: extended endpoint object > + */ > +void cdns3_ep_config(struct cdns3_endpoint *priv_ep) > +{ > + bool is_iso_ep = (priv_ep->type == USB_ENDPOINT_XFER_ISOC); > + struct cdns3_device *priv_dev = priv_ep->cdns3_dev; > + u32 bEndpointAddress = priv_ep->num | priv_ep->dir; > + u32 buffering = CDNS3_EP_BUF_SIZE - 1; > + u32 max_packet_size = 0; > + u32 ep_cfg = 0; > + int ret; > + > + switch (priv_ep->type) { > + case USB_ENDPOINT_XFER_INT: > + ep_cfg = EP_CFG_EPTYPE(USB_ENDPOINT_XFER_INT); > + break; > + case USB_ENDPOINT_XFER_BULK: > + ep_cfg = EP_CFG_EPTYPE(USB_ENDPOINT_XFER_BULK); > + break; > + default: > + ep_cfg = EP_CFG_EPTYPE(USB_ENDPOINT_XFER_ISOC); > + buffering = priv_ep->endpoint.mult + 1; > + } > + > + switch (priv_dev->gadget.speed) { > + case USB_SPEED_FULL: > + max_packet_size = is_iso_ep ? 1023 : 64; > + break; > + case USB_SPEED_HIGH: > + max_packet_size = is_iso_ep ? 1024 : 512; > + break; > + case USB_SPEED_SUPER: > + max_packet_size = 1024; > + if (priv_ep->type == USB_ENDPOINT_XFER_ISOC) { > + buffering = (priv_ep->endpoint.mult + 1) * > + (priv_ep->endpoint.maxburst + 1); > + > + if (priv_ep->interval > 1) > + buffering++; > + } > + break; > + default: > + /* all other speed are not supported */ > + return; > + } > + > + ret = cdns3_ep_onchip_buffer_reserve(priv_dev, buffering); > + if (ret) { > + dev_err(priv_dev->dev, "onchip mem is full, ep is invalid\n"); > + return; > + } > + > + ep_cfg |= EP_CFG_MAXPKTSIZE(max_packet_size) | > + EP_CFG_MULT(priv_ep->endpoint.mult) | > + EP_CFG_BUFFERING(buffering) | > + EP_CFG_MAXBURST(priv_ep->endpoint.maxburst); > + > + cdns3_select_ep(priv_dev, bEndpointAddress); > + writel(ep_cfg, &priv_dev->regs->ep_cfg); > + > + dev_dbg(priv_dev->dev, "Configure %s: with val %08x\n", > + priv_ep->name, ep_cfg); > +} > + > +/* Find correct direction for HW endpoint according to description */ > +static int cdns3_ep_dir_is_correct(struct usb_endpoint_descriptor *desc, > + struct cdns3_endpoint *priv_ep) > +{ > + return (priv_ep->endpoint.caps.dir_in && usb_endpoint_dir_in(desc)) || > + (priv_ep->endpoint.caps.dir_out && usb_endpoint_dir_out(desc)); > +} > + > +static struct > +cdns3_endpoint *cdns3_find_available_ep(struct cdns3_device *priv_dev, > + struct usb_endpoint_descriptor *desc) > +{ > + struct usb_ep *ep; > + struct cdns3_endpoint *priv_ep; > + > + list_for_each_entry(ep, &priv_dev->gadget.ep_list, ep_list) { > + unsigned long num; > + int ret; > + /* ep name pattern likes epXin or epXout */ > + char c[2] = {ep->name[2], '\0'}; > + > + ret = kstrtoul(c, 10, &num); > + if (ret) > + return ERR_PTR(ret); > + > + priv_ep = ep_to_cdns3_ep(ep); > + if (cdns3_ep_dir_is_correct(desc, priv_ep)) { > + if (!(priv_ep->flags & EP_CLAIMED)) { > + priv_ep->num = num; > + return priv_ep; > + } > + } > + } > + > + return ERR_PTR(-ENOENT); > +} > + > +/* > + * Cadence IP has one limitation that all endpoints must be configured > + * (Type & MaxPacketSize) before setting configuration through hardware > + * register, it means we can't change endpoints configuration after > + * set_configuration. > + * > + * This function set EP_CLAIMED flag which is added when the gadget driver > + * uses usb_ep_autoconfig to configure specific endpoint; > + * When the udc driver receives set_configurion request, > + * it goes through all claimed endpoints, and configure all endpoints > + * accordingly. > + * > + * At usb_ep_ops.enable/disable, we only enable and disable endpoint through > + * ep_cfg register which can be changed after set_configuration, and do > + * some software operation accordingly. > + */ > +static struct > +usb_ep *cdns3_gadget_match_ep(struct usb_gadget *gadget, > + struct usb_endpoint_descriptor *desc, > + struct usb_ss_ep_comp_descriptor *comp_desc) > +{ > + struct cdns3_device *priv_dev = gadget_to_cdns3_device(gadget); > + struct cdns3_endpoint *priv_ep; > + unsigned long flags; > + > + priv_ep = cdns3_find_available_ep(priv_dev, desc); > + if (IS_ERR(priv_ep)) { > + dev_err(priv_dev->dev, "no available ep\n"); > + return NULL; > + } > + > + dev_dbg(priv_dev->dev, "match endpoint: %s\n", priv_ep->name); > + > + spin_lock_irqsave(&priv_dev->lock, flags); > + priv_ep->endpoint.desc = desc; > + priv_ep->dir = usb_endpoint_dir_in(desc) ? USB_DIR_IN : USB_DIR_OUT; > + priv_ep->type = usb_endpoint_type(desc); > + priv_ep->flags |= EP_CLAIMED; > + priv_ep->interval = desc->bInterval ? BIT(desc->bInterval - 1) : 0; > + > + spin_unlock_irqrestore(&priv_dev->lock, flags); > + return &priv_ep->endpoint; > +} > + > +/** > + * cdns3_gadget_ep_alloc_request Allocates request > + * @ep: endpoint object associated with request > + * @gfp_flags: gfp flags > + * > + * Returns allocated request address, NULL on allocation error > + */ > +struct usb_request *cdns3_gadget_ep_alloc_request(struct usb_ep *ep, > + gfp_t gfp_flags) > +{ > + struct cdns3_endpoint *priv_ep = ep_to_cdns3_ep(ep); > + struct cdns3_request *priv_req; > + > + priv_req = kzalloc(sizeof(*priv_req), gfp_flags); > + if (!priv_req) > + return NULL; > + > + priv_req->priv_ep = priv_ep; > + > + trace_cdns3_alloc_request(priv_req); > + return &priv_req->request; > +} > + > +/** > + * cdns3_gadget_ep_free_request Free memory occupied by request > + * @ep: endpoint object associated with request > + * @request: request to free memory > + */ > +void cdns3_gadget_ep_free_request(struct usb_ep *ep, > + struct usb_request *request) > +{ > + struct cdns3_request *priv_req = to_cdns3_request(request); > + > + trace_cdns3_free_request(priv_req); > + kfree(priv_req); > +} > + > +/** > + * cdns3_gadget_ep_enable Enable endpoint > + * @ep: endpoint object > + * @desc: endpoint descriptor > + * > + * Returns 0 on success, error code elsewhere > + */ > +static int cdns3_gadget_ep_enable(struct usb_ep *ep, > + const struct usb_endpoint_descriptor *desc) > +{ > + struct cdns3_endpoint *priv_ep; > + struct cdns3_device *priv_dev; > + u32 reg = EP_STS_EN_TRBERREN; > + u32 bEndpointAddress; > + unsigned long flags; > + int ret; > + > + priv_ep = ep_to_cdns3_ep(ep); > + priv_dev = priv_ep->cdns3_dev; > + > + if (!ep || !desc || desc->bDescriptorType != USB_DT_ENDPOINT) { > + dev_dbg(priv_dev->dev, "usbss: invalid parameters\n"); > + return -EINVAL; > + } > + > + if (!desc->wMaxPacketSize) { > + dev_err(priv_dev->dev, "usbss: missing wMaxPacketSize\n"); > + return -EINVAL; > + } > + > + if (dev_WARN_ONCE(priv_dev->dev, priv_ep->flags & EP_ENABLED, > + "%s is already enabled\n", priv_ep->name)) > + return 0; > + > + spin_lock_irqsave(&priv_dev->lock, flags); > + > + priv_ep->endpoint.desc = desc; > + priv_ep->type = usb_endpoint_type(desc); > + priv_ep->interval = desc->bInterval ? BIT(desc->bInterval - 1) : 0; > + > + if (priv_ep->interval > ISO_MAX_INTERVAL && > + priv_ep->type == USB_ENDPOINT_XFER_ISOC) { > + dev_err(priv_dev->dev, "Driver is limited to %d period\n", > + ISO_MAX_INTERVAL); > + > + ret = -EINVAL; > + goto exit; > + } > + > + ret = cdns3_allocate_trb_pool(priv_ep); > + > + if (ret) > + goto exit; > + > + bEndpointAddress = priv_ep->num | priv_ep->dir; > + cdns3_select_ep(priv_dev, bEndpointAddress); > + > + trace_cdns3_gadget_ep_enable(priv_ep); > + > + writel(EP_CMD_EPRST, &priv_dev->regs->ep_cmd); > + > + ret = cdns3_handshake(&priv_dev->regs->ep_cmd, > + EP_CMD_CSTALL | EP_CMD_EPRST, 0, 100); > + > + /* enable interrupt for selected endpoint */ > + cdns3_set_register_bit(&priv_dev->regs->ep_ien, > + BIT(cdns3_ep_addr_to_index(bEndpointAddress))); > + > + writel(reg, &priv_dev->regs->ep_sts_en); > + > + cdns3_set_register_bit(&priv_dev->regs->ep_cfg, EP_CFG_ENABLE); > + > + ep->desc = desc; > + priv_ep->flags &= ~(EP_PENDING_REQUEST | EP_STALL); > + priv_ep->flags |= EP_ENABLED | EP_UPDATE_EP_TRBADDR; > + priv_ep->wa1_set = 0; > + priv_ep->enqueue = 0; > + priv_ep->dequeue = 0; > + reg = readl(&priv_dev->regs->ep_sts); > + priv_ep->pcs = !!EP_STS_CCS(reg); > + priv_ep->ccs = !!EP_STS_CCS(reg); > + /* one TRB is reserved for link TRB used in DMULT mode*/ > + priv_ep->free_trbs = priv_ep->num_trbs - 1; > +exit: > + spin_unlock_irqrestore(&priv_dev->lock, flags); > + > + return ret; > +} > + > +/** > + * cdns3_gadget_ep_disable Disable endpoint > + * @ep: endpoint object > + * > + * Returns 0 on success, error code elsewhere > + */ > +static int cdns3_gadget_ep_disable(struct usb_ep *ep) > +{ > + struct cdns3_endpoint *priv_ep; > + struct cdns3_device *priv_dev; > + struct usb_request *request; > + unsigned long flags; > + int ret = 0; > + u32 ep_cfg; > + > + if (!ep) { > + pr_err("usbss: invalid parameters\n"); > + return -EINVAL; > + } > + > + priv_ep = ep_to_cdns3_ep(ep); > + priv_dev = priv_ep->cdns3_dev; > + > + if (dev_WARN_ONCE(priv_dev->dev, !(priv_ep->flags & EP_ENABLED), > + "%s is already disabled\n", priv_ep->name)) > + return 0; > + > + spin_lock_irqsave(&priv_dev->lock, flags); > + > + trace_cdns3_gadget_ep_disable(priv_ep); > + > + cdns3_select_ep(priv_dev, ep->desc->bEndpointAddress); > + ret = cdns3_data_flush(priv_ep); > + > + ep_cfg = readl(&priv_dev->regs->ep_cfg); > + ep_cfg &= ~EP_CFG_ENABLE; > + writel(ep_cfg, &priv_dev->regs->ep_cfg); > + > + while (!list_empty(&priv_ep->pending_req_list)) { > + request = cdns3_next_request(&priv_ep->pending_req_list); > + > + cdns3_gadget_giveback(priv_ep, to_cdns3_request(request), > + -ESHUTDOWN); > + } > + > + while (!list_empty(&priv_ep->deferred_req_list)) { > + request = cdns3_next_request(&priv_ep->deferred_req_list); > + > + cdns3_gadget_giveback(priv_ep, to_cdns3_request(request), > + -ESHUTDOWN); > + } > + > + priv_ep->descmis_req = NULL; > + > + ep->desc = NULL; > + priv_ep->flags &= ~EP_ENABLED; > + > + spin_unlock_irqrestore(&priv_dev->lock, flags); > + > + return ret; > +} > + > +/** > + * cdns3_gadget_ep_queue Transfer data on endpoint > + * @ep: endpoint object > + * @request: request object > + * @gfp_flags: gfp flags > + * > + * Returns 0 on success, error code elsewhere > + */ > +static int __cdns3_gadget_ep_queue(struct usb_ep *ep, > + struct usb_request *request, > + gfp_t gfp_flags) > +{ > + struct cdns3_endpoint *priv_ep = ep_to_cdns3_ep(ep); > + struct cdns3_device *priv_dev = priv_ep->cdns3_dev; > + struct cdns3_request *priv_req; > + int deferred = 0; > + int ret = 0; > + > + request->actual = 0; > + request->status = -EINPROGRESS; > + priv_req = to_cdns3_request(request); > + trace_cdns3_ep_queue(priv_req); > + > + ret = usb_gadget_map_request_by_dev(priv_dev->sysdev, request, > + usb_endpoint_dir_in(ep->desc)); > + if (ret) > + return ret; > + > + /* > + * If hardware endpoint configuration has not been set yet then > + * just queue request in deferred list. Transfer will be started in > + * cdns3_set_hw_configuration. > + */ > + if (!priv_dev->hw_configured_flag) > + deferred = 1; > + else > + ret = cdns3_ep_run_transfer(priv_ep, request); > + > + if (ret || deferred) > + list_add_tail(&request->list, &priv_ep->deferred_req_list); > + else > + list_add_tail(&request->list, &priv_ep->pending_req_list); > + > + return ret; > +} > + > +static int cdns3_gadget_ep_queue(struct usb_ep *ep, struct usb_request *request, > + gfp_t gfp_flags) > +{ > + struct usb_request *zlp_request; > + struct cdns3_endpoint *priv_ep; > + struct cdns3_device *priv_dev; > + unsigned long flags; > + int ret; > + > + if (!request || !ep) > + return -EINVAL; > + > + priv_ep = ep_to_cdns3_ep(ep); > + priv_dev = priv_ep->cdns3_dev; > + > + spin_lock_irqsave(&priv_dev->lock, flags); > + > + ret = __cdns3_gadget_ep_queue(ep, request, gfp_flags); > + > + if (ret == 0 && request->zero && request->length && > + (request->length % ep->maxpacket == 0)) { > + struct cdns3_request *priv_req; > + > + zlp_request = cdns3_gadget_ep_alloc_request(ep, GFP_ATOMIC); > + zlp_request->buf = priv_dev->zlp_buf; > + zlp_request->length = 0; > + > + priv_req = to_cdns3_request(zlp_request); > + priv_req->flags |= REQUEST_ZLP; > + > + dev_dbg(priv_dev->dev, "Queuing ZLP for endpoint: %s\n", > + priv_ep->name); > + ret = __cdns3_gadget_ep_queue(ep, zlp_request, gfp_flags); > + } > + > + spin_unlock_irqrestore(&priv_dev->lock, flags); > + return ret; > +} > + > +/** > + * cdns3_gadget_ep_dequeue Remove request from transfer queue > + * @ep: endpoint object associated with request > + * @request: request object > + * > + * Returns 0 on success, error code elsewhere > + */ > +int cdns3_gadget_ep_dequeue(struct usb_ep *ep, > + struct usb_request *request) > +{ > + struct cdns3_endpoint *priv_ep = ep_to_cdns3_ep(ep); > + struct cdns3_device *priv_dev = priv_ep->cdns3_dev; > + struct usb_request *req, *req_temp; > + struct cdns3_request *priv_req; > + struct cdns3_trb *link_trb; > + unsigned long flags; > + int ret = 0; > + > + if (!ep || !request || !ep->desc) > + return -EINVAL; > + > + spin_lock_irqsave(&priv_dev->lock, flags); > + > + priv_req = to_cdns3_request(request); > + > + trace_cdns3_ep_dequeue(priv_req); > + > + cdns3_select_ep(priv_dev, ep->desc->bEndpointAddress); > + > + list_for_each_entry_safe(req, req_temp, &priv_ep->pending_req_list, > + list) { > + if (request == req) > + goto found; > + } > + > + list_for_each_entry_safe(req, req_temp, &priv_ep->deferred_req_list, > + list) { > + if (request == req) > + goto found; > + } > + > + goto not_found; > + > +found: > + > + if (priv_ep->wa1_trb == priv_req->trb) > + cdns3_wa1_restore_cycle_bit(priv_ep); > + > + link_trb = priv_req->trb; > + cdns3_move_deq_to_next_trb(priv_req); > + cdns3_gadget_giveback(priv_ep, priv_req, -ECONNRESET); > + > + /* Update ring */ > + request = cdns3_next_request(&priv_ep->deferred_req_list); > + if (request) { > + priv_req = to_cdns3_request(request); > + > + link_trb->buffer = TRB_BUFFER(priv_ep->trb_pool_dma + > + (priv_req->start_trb * TRB_SIZE)); > + link_trb->control = (link_trb->control & TRB_CYCLE) | > + TRB_TYPE(TRB_LINK) | TRB_CHAIN | TRB_TOGGLE; > + } else { > + priv_ep->flags |= EP_UPDATE_EP_TRBADDR; > + } > + > +not_found: > + spin_unlock_irqrestore(&priv_dev->lock, flags); > + return ret; > +} > + > +/** > + * cdns3_gadget_ep_set_halt Sets/clears stall on selected endpoint > + * @ep: endpoint object to set/clear stall on > + * @value: 1 for set stall, 0 for clear stall > + * > + * Returns 0 on success, error code elsewhere > + */ > +int cdns3_gadget_ep_set_halt(struct usb_ep *ep, int value) > +{ > + struct cdns3_endpoint *priv_ep = ep_to_cdns3_ep(ep); > + struct cdns3_device *priv_dev = priv_ep->cdns3_dev; > + unsigned long flags; > + int ret = 0; > + > + if (!(priv_ep->flags & EP_ENABLED)) > + return -EPERM; > + > + spin_lock_irqsave(&priv_dev->lock, flags); > + > + cdns3_select_ep(priv_dev, ep->desc->bEndpointAddress); > + if (value) { > + cdns3_ep_stall_flush(priv_ep); > + } else { > + priv_ep->flags &= ~EP_WEDGE; > + > + cdns3_dbg(priv_ep->cdns3_dev, "Clear stalled endpoint %s\n", > + priv_ep->name); > + > + writel(EP_CMD_CSTALL | EP_CMD_EPRST, &priv_dev->regs->ep_cmd); > + > + /* wait for EPRST cleared */ > + ret = cdns3_handshake(&priv_dev->regs->ep_cmd, > + EP_CMD_EPRST, 0, 100); > + if (unlikely(ret)) { > + dev_err(priv_dev->dev, > + "Clearing halt condition failed for %s\n", > + priv_ep->name); > + goto finish; > + > + } else { > + priv_ep->flags &= ~EP_STALL; > + } > + } > + > + priv_ep->flags &= ~EP_PENDING_REQUEST; > +finish: > + spin_unlock_irqrestore(&priv_dev->lock, flags); > + > + return ret; > +} > + > +extern const struct usb_ep_ops cdns3_gadget_ep0_ops; > + > +static const struct usb_ep_ops cdns3_gadget_ep_ops = { > + .enable = cdns3_gadget_ep_enable, > + .disable = cdns3_gadget_ep_disable, > + .alloc_request = cdns3_gadget_ep_alloc_request, > + .free_request = cdns3_gadget_ep_free_request, > + .queue = cdns3_gadget_ep_queue, > + .dequeue = cdns3_gadget_ep_dequeue, > + .set_halt = cdns3_gadget_ep_set_halt, > + .set_wedge = cdns3_gadget_ep_set_wedge, > +}; > + > +/** > + * cdns3_gadget_get_frame Returns number of actual ITP frame > + * @gadget: gadget object > + * > + * Returns number of actual ITP frame > + */ > +static int cdns3_gadget_get_frame(struct usb_gadget *gadget) > +{ > + struct cdns3_device *priv_dev = gadget_to_cdns3_device(gadget); > + > + return readl(&priv_dev->regs->usb_iptn); > +} > + > +static int cdns3_gadget_wakeup(struct usb_gadget *gadget) > +{ > + return 0; > +} > + > +static int cdns3_gadget_set_selfpowered(struct usb_gadget *gadget, > + int is_selfpowered) > +{ > + struct cdns3_device *priv_dev = gadget_to_cdns3_device(gadget); > + unsigned long flags; > + > + spin_lock_irqsave(&priv_dev->lock, flags); > + priv_dev->is_selfpowered = !!is_selfpowered; > + spin_unlock_irqrestore(&priv_dev->lock, flags); > + return 0; > +} > + > +static int cdns3_gadget_pullup(struct usb_gadget *gadget, int is_on) > +{ > + struct cdns3_device *priv_dev = gadget_to_cdns3_device(gadget); > + > + if (is_on) > + writel(USB_CONF_DEVEN, &priv_dev->regs->usb_conf); > + else > + writel(USB_CONF_DEVDS, &priv_dev->regs->usb_conf); > + > + return 0; > +} > + > +static void cdns3_gadget_config(struct cdns3_device *priv_dev) > +{ > + struct cdns3_usb_regs __iomem *regs = priv_dev->regs; > + > + cdns3_ep0_config(priv_dev); > + > + /* enable interrupts for endpoint 0 (in and out) */ > + writel(EP_IEN_EP_OUT0 | EP_IEN_EP_IN0, ®s->ep_ien); > + > + /* > + *Driver need modify LFPS minimal U1 Exit time for 0x00024505 revision > + * of controller > + */ > + if (priv_dev->dev_ver == 0x00024505) { > + u32 reg = readl(®s->dbg_link1); > + > + reg &= ~DBG_LINK1_LFPS_MIN_GEN_U1_EXIT_MASK; > + reg |= DBG_LINK1_LFPS_MIN_GEN_U1_EXIT(0x55) | > + DBG_LINK1_LFPS_MIN_GEN_U1_EXIT_SET; > + writel(reg, ®s->dbg_link1); > + } > + > + /* enable generic interrupt*/ > + writel(USB_IEN_INIT, ®s->usb_ien); > + writel(USB_CONF_CLK2OFFDS | USB_CONF_L1DS, ®s->usb_conf); > + writel(USB_CONF_DMULT, ®s->usb_conf); > + cdns3_gadget_pullup(&priv_dev->gadget, 1); > +} > + > +/** > + * cdns3_gadget_udc_start Gadget start > + * @gadget: gadget object > + * @driver: driver which operates on this gadget > + * > + * Returns 0 on success, error code elsewhere > + */ > +static int cdns3_gadget_udc_start(struct usb_gadget *gadget, > + struct usb_gadget_driver *driver) > +{ > + struct cdns3_device *priv_dev = gadget_to_cdns3_device(gadget); > + unsigned long flags; > + > + spin_lock_irqsave(&priv_dev->lock, flags); > + priv_dev->gadget_driver = driver; > + cdns3_gadget_config(priv_dev); > + spin_unlock_irqrestore(&priv_dev->lock, flags); > + return 0; > +} > + > +/** > + * cdns3_gadget_udc_stop Stops gadget > + * @gadget: gadget object > + * > + * Returns 0 > + */ > +static int cdns3_gadget_udc_stop(struct usb_gadget *gadget) > +{ > + struct cdns3_device *priv_dev = gadget_to_cdns3_device(gadget); > + struct cdns3_endpoint *priv_ep; > + u32 bEndpointAddress; > + struct usb_ep *ep; > + int ret = 0; > + > + priv_dev->gadget_driver = NULL; > + > + priv_dev->onchip_mem_allocated_size = 0; > + priv_dev->gadget.speed = USB_SPEED_UNKNOWN; > + > + list_for_each_entry(ep, &priv_dev->gadget.ep_list, ep_list) { > + priv_ep = ep_to_cdns3_ep(ep); > + bEndpointAddress = priv_ep->num | priv_ep->dir; > + cdns3_select_ep(priv_dev, bEndpointAddress); > + writel(EP_CMD_EPRST, &priv_dev->regs->ep_cmd); > + ret = cdns3_handshake(&priv_dev->regs->ep_cmd, > + EP_CMD_EPRST, 0, 100); > + cdns3_free_trb_pool(priv_ep); > + } > + > + /* disable interrupt for device */ > + writel(0, &priv_dev->regs->usb_ien); > + writel(USB_CONF_DEVDS, &priv_dev->regs->usb_conf); > + > + return ret; > +} > + > +static const struct usb_gadget_ops cdns3_gadget_ops = { > + .get_frame = cdns3_gadget_get_frame, > + .wakeup = cdns3_gadget_wakeup, > + .set_selfpowered = cdns3_gadget_set_selfpowered, > + .pullup = cdns3_gadget_pullup, > + .udc_start = cdns3_gadget_udc_start, > + .udc_stop = cdns3_gadget_udc_stop, > + .match_ep = cdns3_gadget_match_ep, > +}; > + > +static void cdns3_free_all_eps(struct cdns3_device *priv_dev) > +{ > + int i; > + > + /*ep0 OUT point to ep0 IN*/ > + priv_dev->eps[16] = NULL; > + > + cdns3_free_trb_pool(priv_dev->eps[0]); > + > + for (i = 0; i < CDNS3_ENDPOINTS_MAX_COUNT; i++) > + if (priv_dev->eps[i]) > + devm_kfree(priv_dev->dev, priv_dev->eps[i]); > +} > + > +/** > + * cdns3_init_eps Initializes software endpoints of gadget > + * @cdns3: extended gadget object > + * > + * Returns 0 on success, error code elsewhere > + */ > +static int cdns3_init_eps(struct cdns3_device *priv_dev) > +{ > + u32 ep_enabled_reg, iso_ep_reg; > + struct cdns3_endpoint *priv_ep; > + int ep_dir, ep_number; > + u32 ep_mask; > + int ret = 0; > + int i; > + > + /* Read it from USB_CAP3 to USB_CAP5 */ > + ep_enabled_reg = readl(&priv_dev->regs->usb_cap3); > + iso_ep_reg = readl(&priv_dev->regs->usb_cap4); > + > + dev_dbg(priv_dev->dev, "Initializing non-zero endpoints\n"); > + > + for (i = 0; i < CDNS3_ENDPOINTS_MAX_COUNT; i++) { > + ep_dir = i >> 4; /* i div 16 */ > + ep_number = i & 0xF; /* i % 16 */ > + ep_mask = BIT(i); > + > + if (!(ep_enabled_reg & ep_mask)) > + continue; > + > + if (ep_dir && !ep_number) { > + priv_dev->eps[i] = priv_dev->eps[0]; > + continue; > + } > + > + priv_ep = devm_kzalloc(priv_dev->dev, sizeof(*priv_ep), > + GFP_KERNEL); > + if (!priv_ep) { > + ret = -ENOMEM; > + goto err; > + } > + > + /* set parent of endpoint object */ > + priv_ep->cdns3_dev = priv_dev; > + priv_dev->eps[i] = priv_ep; > + priv_ep->num = ep_number; > + priv_ep->dir = ep_dir ? USB_DIR_IN : USB_DIR_OUT; > + > + if (!ep_number) { > + ret = cdns3_init_ep0(priv_dev, priv_ep); > + if (ret) { > + dev_err(priv_dev->dev, "Failed to init ep0\n"); > + goto err; > + } > + } else { > + snprintf(priv_ep->name, sizeof(priv_ep->name), "ep%d%s", > + ep_number, !!ep_dir ? "in" : "out"); > + priv_ep->endpoint.name = priv_ep->name; > + > + usb_ep_set_maxpacket_limit(&priv_ep->endpoint, > + CDNS3_EP_MAX_PACKET_LIMIT); > + priv_ep->endpoint.max_streams = CDNS3_EP_MAX_STREAMS; > + priv_ep->endpoint.ops = &cdns3_gadget_ep_ops; > + if (ep_dir) > + priv_ep->endpoint.caps.dir_in = 1; > + else > + priv_ep->endpoint.caps.dir_out = 1; > + > + if (iso_ep_reg & ep_mask) > + priv_ep->endpoint.caps.type_iso = 1; > + > + priv_ep->endpoint.caps.type_bulk = 1; > + priv_ep->endpoint.caps.type_int = 1; > + priv_ep->endpoint.maxburst = CDNS3_EP_BUF_SIZE - 1; > + > + list_add_tail(&priv_ep->endpoint.ep_list, > + &priv_dev->gadget.ep_list); > + } > + > + priv_ep->flags = 0; > + > + dev_info(priv_dev->dev, "Initialized %s support: %s %s\n", > + priv_ep->name, > + priv_ep->endpoint.caps.type_bulk ? "BULK, INT" : "", > + priv_ep->endpoint.caps.type_iso ? "ISO" : ""); > + > + INIT_LIST_HEAD(&priv_ep->pending_req_list); > + INIT_LIST_HEAD(&priv_ep->deferred_req_list); > + } > + > + return 0; > +err: > + cdns3_free_all_eps(priv_dev); > + return -ENOMEM; > +} > + > +static void cdns3_gadget_disable(struct cdns3 *cdns) > +{ > + struct cdns3_device *priv_dev; > + > + priv_dev = cdns->gadget_dev; > + > + if (priv_dev->gadget_driver) > + priv_dev->gadget_driver->disconnect(&priv_dev->gadget); > + > + usb_gadget_disconnect(&priv_dev->gadget); > + priv_dev->gadget.speed = USB_SPEED_UNKNOWN; > +} > + > +void cdns3_gadget_exit(struct cdns3 *cdns) > +{ > + struct cdns3_device *priv_dev; > + > + priv_dev = cdns->gadget_dev; > + > + cdns3_gadget_disable(cdns); > + > + devm_free_irq(cdns->dev, cdns->irq, cdns); > + > + pm_runtime_mark_last_busy(cdns->dev); > + pm_runtime_put_autosuspend(cdns->dev); > + > + usb_del_gadget_udc(&priv_dev->gadget); > + > + cdns3_free_all_eps(priv_dev); > + > + dma_free_coherent(priv_dev->sysdev, 8, priv_dev->setup_buf, > + priv_dev->setup_dma); > + > + kfree(priv_dev->zlp_buf); > + kfree(priv_dev); > + cdns->gadget_dev = NULL; > +} > + > +static int cdns3_gadget_start(struct cdns3 *cdns) > +{ > + struct cdns3_device *priv_dev; > + u32 max_speed; > + int ret; > + > + priv_dev = kzalloc(sizeof(*priv_dev), GFP_KERNEL); > + if (!priv_dev) > + return -ENOMEM; > + > + cdns->gadget_dev = priv_dev; > + priv_dev->sysdev = cdns->dev; > + priv_dev->dev = cdns->dev; > + priv_dev->regs = cdns->dev_regs; > + > + max_speed = usb_get_maximum_speed(cdns->dev); > + > + /* Check the maximum_speed parameter */ > + switch (max_speed) { > + case USB_SPEED_FULL: > + case USB_SPEED_HIGH: > + case USB_SPEED_SUPER: > + break; > + default: > + dev_err(cdns->dev, "invalid maximum_speed parameter %d\n", > + max_speed); > + /* fall through */ > + case USB_SPEED_UNKNOWN: > + /* default to superspeed */ > + max_speed = USB_SPEED_SUPER; > + break; > + } > + > + /* fill gadget fields */ > + priv_dev->gadget.max_speed = max_speed; > + priv_dev->gadget.speed = USB_SPEED_UNKNOWN; > + priv_dev->gadget.ops = &cdns3_gadget_ops; > + priv_dev->gadget.name = "usb-ss-gadget"; > + priv_dev->gadget.sg_supported = 1; > + > + spin_lock_init(&priv_dev->lock); > + INIT_WORK(&priv_dev->pending_status_wq, > + cdns3_pending_setup_status_handler); > + > + /* initialize endpoint container */ > + INIT_LIST_HEAD(&priv_dev->gadget.ep_list); > + > + ret = cdns3_init_eps(priv_dev); > + if (ret) { > + dev_err(priv_dev->dev, "Failed to create endpoints\n"); > + goto err1; > + } > + > + /* allocate memory for setup packet buffer */ > + priv_dev->setup_buf = dma_alloc_coherent(priv_dev->sysdev, 8, > + &priv_dev->setup_dma, GFP_DMA); > + if (!priv_dev->setup_buf) { > + dev_err(priv_dev->dev, "Failed to allocate memory for SETUP buffer\n"); > + ret = -ENOMEM; > + goto err2; > + } > + > + priv_dev->dev_ver = readl(&priv_dev->regs->usb_cap6); > + dev_dbg(priv_dev->dev, "Device Controller version: %08x\n", > + readl(&priv_dev->regs->usb_cap6)); > + dev_dbg(priv_dev->dev, "USB Capabilities:: %08x\n", > + readl(&priv_dev->regs->usb_cap1)); > + dev_dbg(priv_dev->dev, "On-Chip memory cnfiguration: %08x\n", > + readl(&priv_dev->regs->usb_cap2)); > + > + priv_dev->zlp_buf = kzalloc(CDNS3_EP_ZLP_BUF_SIZE, GFP_KERNEL); > + if (!priv_dev->zlp_buf) { > + ret = -ENOMEM; > + goto err3; > + } > + > + /* add USB gadget device */ > + ret = usb_add_gadget_udc(priv_dev->dev, &priv_dev->gadget); > + if (ret < 0) { > + dev_err(priv_dev->dev, > + "Failed to register USB device controller\n"); > + goto err4; > + } > + > + return 0; > +err4: > + kfree(priv_dev->zlp_buf); > +err3: > + dma_free_coherent(priv_dev->sysdev, 8, priv_dev->setup_buf, > + priv_dev->setup_dma); > +err2: > + cdns3_free_all_eps(priv_dev); > +err1: > + cdns->gadget_dev = NULL; > + return ret; > +} > + > +static int __cdns3_gadget_init(struct cdns3 *cdns) > +{ > + struct cdns3_device *priv_dev; > + unsigned long flags; > + int ret = 0; > + > + ret = cdns3_gadget_start(cdns); > + if (ret) > + return ret; > + > + priv_dev = cdns->gadget_dev; > + ret = devm_request_threaded_irq(cdns->dev, cdns->irq, > + cdns3_device_irq_handler, > + cdns3_device_thread_irq_handler, > + IRQF_SHARED, dev_name(cdns->dev), cdns); > + if (ret) > + goto err0; > + > + pm_runtime_get_sync(cdns->dev); > + spin_lock_irqsave(&priv_dev->lock, flags); > + spin_unlock_irqrestore(&priv_dev->lock, flags); > + return 0; > +err0: > + cdns3_gadget_exit(cdns); > + return ret; > +} > + > +static int cdns3_gadget_suspend(struct cdns3 *cdns, bool do_wakeup) > +{ > + cdns3_gadget_disable(cdns); > + return 0; > +} > + > +static int cdns3_gadget_resume(struct cdns3 *cdns, bool hibernated) > +{ > + struct cdns3_device *priv_dev; > + unsigned long flags; > + > + priv_dev = cdns->gadget_dev; > + spin_lock_irqsave(&priv_dev->lock, flags); > + > + if (!priv_dev->gadget_driver) { > + spin_unlock_irqrestore(&priv_dev->lock, flags); > + return 0; > + } > + > + cdns3_gadget_config(priv_dev); > + spin_unlock_irqrestore(&priv_dev->lock, flags); > + return 0; > +} > + > +/** > + * cdns3_gadget_init - initialize device structure > + * > + * cdns: cdns3 instance > + * > + * This function initializes the gadget. > + */ > +int cdns3_gadget_init(struct cdns3 *cdns) > +{ > + struct cdns3_role_driver *rdrv; > + > + rdrv = devm_kzalloc(cdns->dev, sizeof(*rdrv), GFP_KERNEL); > + if (!rdrv) > + return -ENOMEM; > + > + rdrv->start = __cdns3_gadget_init; > + rdrv->stop = cdns3_gadget_exit; > + rdrv->suspend = cdns3_gadget_suspend; > + rdrv->resume = cdns3_gadget_resume; > + rdrv->state = CDNS3_ROLE_STATE_INACTIVE; > + rdrv->name = "gadget"; > + cdns->roles[CDNS3_ROLE_GADGET] = rdrv; > + > + return 0; > +} > diff --git a/drivers/usb/cdns3/gadget.h b/drivers/usb/cdns3/gadget.h > new file mode 100644 > index 000000000000..817f8ae7a4da > --- /dev/null > +++ b/drivers/usb/cdns3/gadget.h > @@ -0,0 +1,1207 @@ > +/* SPDX-License-Identifier: GPL-2.0 */ > +/* > + * USBSS device controller driver header file > + * > + * Copyright (C) 2018 Cadence. > + * Copyright (C) 2017-2018 NXP > + * > + * Author: Pawel Laszczak > + * Pawel Jez > + * Peter Chen > + */ > +#ifndef __LINUX_CDNS3_GADGET > +#define __LINUX_CDNS3_GADGET > +#include > + > +/* > + * USBSS-DEV register interface. > + * This corresponds to the USBSS Device Controller Interface > + */ > + > +/** > + * struct cdns3_usb_regs - device controller registers. > + * @usb_conf: Global Configuration Register. > + * @usb_sts: Global Status Register. > + * @usb_cmd: Global Command Register. > + * @usb_iptn: ITP/SOF number Register. > + * @usb_lpm: Global Command Register. > + * @usb_ien: USB Interrupt Enable Register. > + * @usb_ists: USB Interrupt Status Register. > + * @ep_sel: Endpoint Select Register. > + * @ep_traddr: Endpoint Transfer Ring Address Register. > + * @ep_cfg: Endpoint Configuration Register. > + * @ep_cmd: Endpoint Command Register. > + * @ep_sts: Endpoint Status Register. > + * @ep_sts_sid: Endpoint Status Register. > + * @ep_sts_en: Endpoint Status Register Enable. > + * @drbl: Doorbell Register. > + * @ep_ien: EP Interrupt Enable Register. > + * @ep_ists: EP Interrupt Status Register. > + * @usb_pwr: Global Power Configuration Register. > + * @usb_conf2: Global Configuration Register 2. > + * @usb_cap1: Capability Register 1. > + * @usb_cap2: Capability Register 2. > + * @usb_cap3: Capability Register 3. > + * @usb_cap4: Capability Register 4. > + * @usb_cap5: Capability Register 5. > + * @usb_cap6: Capability Register 6. > + * @usb_cpkt1: Custom Packet Register 1. > + * @usb_cpkt2: Custom Packet Register 2. > + * @usb_cpkt3: Custom Packet Register 3. > + * @reserved1: Reserved. > + * @cfg_regs: Configuration registers. > + * @reserved2: Reserved. > + * @dma_axi_ctrl: AXI Control register. > + * @dma_axi_id: AXI ID register. > + * @dma_axi_cap: AXI Capability register. > + * @dma_axi_ctrl0: AXI Control 0 register. > + * @dma_axi_ctrl1: AXI Control 1 register. > + */ > +struct cdns3_usb_regs { > + __le32 usb_conf; > + __le32 usb_sts; > + __le32 usb_cmd; > + __le32 usb_iptn; > + __le32 usb_lpm; > + __le32 usb_ien; > + __le32 usb_ists; > + __le32 ep_sel; > + __le32 ep_traddr; > + __le32 ep_cfg; > + __le32 ep_cmd; > + __le32 ep_sts; > + __le32 ep_sts_sid; > + __le32 ep_sts_en; > + __le32 drbl; > + __le32 ep_ien; > + __le32 ep_ists; > + __le32 usb_pwr; > + __le32 usb_conf2; > + __le32 usb_cap1; > + __le32 usb_cap2; > + __le32 usb_cap3; > + __le32 usb_cap4; > + __le32 usb_cap5; > + __le32 usb_cap6; > + __le32 usb_cpkt1; > + __le32 usb_cpkt2; > + __le32 usb_cpkt3; > + __le32 reserved1[36]; > + __le32 cfg_reg1; > + __le32 dbg_link1; > + __le32 dbg_link2; > + __le32 cfg_regs[74]; > + __le32 reserved2[34]; > + __le32 dma_axi_ctrl; > + __le32 dma_axi_id; > + __le32 dma_axi_cap; > + __le32 dma_axi_ctrl0; > + __le32 dma_axi_ctrl1; > +}; > + > +/* USB_CONF - bitmasks */ > +/* Reset USB device configuration. */ > +#define USB_CONF_CFGRST BIT(0) > +/* Set Configuration. */ > +#define USB_CONF_CFGSET BIT(1) > +/* Disconnect USB device in SuperSpeed. */ > +#define USB_CONF_USB3DIS BIT(3) > +/* Disconnect USB device in HS/FS */ > +#define USB_CONF_USB2DIS BIT(4) > +/* Little Endian access - default */ > +#define USB_CONF_LENDIAN BIT(5) > +/* > + * Big Endian access. Driver assume that byte order for > + * SFRs access always is as Little Endian so this bit > + * is not used. > + */ > +#define USB_CONF_BENDIAN BIT(6) > +/* Device software reset. */ > +#define USB_CONF_SWRST BIT(7) > +/* Singular DMA transfer mode. */ > +#define USB_CONF_DSING BIT(8) > +/* Multiple DMA transfers mode. */ > +#define USB_CONF_DMULT BIT(9) > +/* DMA clock turn-off enable. */ > +#define USB_CONF_DMAOFFEN BIT(10) > +/* DMA clock turn-off disable. */ > +#define USB_CONF_DMAOFFDS BIT(11) > +/* Clear Force Full Speed. */ > +#define USB_CONF_CFORCE_FS BIT(12) > +/* Set Force Full Speed. */ > +#define USB_CONF_SFORCE_FS BIT(13) > +/* Device enable. */ > +#define USB_CONF_DEVEN BIT(14) > +/* Device disable. */ > +#define USB_CONF_DEVDS BIT(15) > +/* L1 LPM state entry enable (used in HS/FS mode). */ > +#define USB_CONF_L1EN BIT(16) > +/* L1 LPM state entry disable (used in HS/FS mode). */ > +#define USB_CONF_L1DS BIT(17) > +/* USB 2.0 clock gate disable. */ > +#define USB_CONF_CLK2OFFEN BIT(18) > +/* USB 2.0 clock gate enable. */ > +#define USB_CONF_CLK2OFFDS BIT(19) > +/* L0 LPM state entry request (used in HS/FS mode). */ > +#define USB_CONF_LGO_L0 BIT(20) > +/* USB 3.0 clock gate disable. */ > +#define USB_CONF_CLK3OFFEN BIT(21) > +/* USB 3.0 clock gate enable. */ > +#define USB_CONF_CLK3OFFDS BIT(22) > +/* Bit 23 is reserved*/ > +/* U1 state entry enable (used in SS mode). */ > +#define USB_CONF_U1EN BIT(24) > +/* U1 state entry disable (used in SS mode). */ > +#define USB_CONF_U1DS BIT(25) > +/* U2 state entry enable (used in SS mode). */ > +#define USB_CONF_U2EN BIT(26) > +/* U2 state entry disable (used in SS mode). */ > +#define USB_CONF_U2DS BIT(27) > +/* U0 state entry request (used in SS mode). */ > +#define USB_CONF_LGO_U0 BIT(28) > +/* U1 state entry request (used in SS mode). */ > +#define USB_CONF_LGO_U1 BIT(29) > +/* U2 state entry request (used in SS mode). */ > +#define USB_CONF_LGO_U2 BIT(30) > +/* SS.Inactive state entry request (used in SS mode) */ > +#define USB_CONF_LGO_SSINACT BIT(31) > + > +/* USB_STS - bitmasks */ > +/* > + * Configuration status. > + * 1 - device is in the configured state. > + * 0 - device is not configured. > + */ > +#define USB_STS_CFGSTS_MASK BIT(0) > +#define USB_STS_CFGSTS(p) ((p) & USB_STS_CFGSTS_MASK) > +/* > + * On-chip memory overflow. > + * 0 - On-chip memory status OK. > + * 1 - On-chip memory overflow. > + */ > +#define USB_STS_OV_MASK BIT(1) > +#define USB_STS_OV(p) ((p) & USB_STS_OV_MASK) > +/* > + * SuperSpeed connection status. > + * 0 - USB in SuperSpeed mode disconnected. > + * 1 - USB in SuperSpeed mode connected. > + */ > +#define USB_STS_USB3CONS_MASK BIT(2) > +#define USB_STS_USB3CONS(p) ((p) & USB_STS_USB3CONS_MASK) > +/* > + * DMA transfer configuration status. > + * 0 - single request. > + * 1 - multiple TRB chain > + */ > +#define USB_STS_DTRANS_MASK BIT(3) > +#define USB_STS_DTRANS(p) ((p) & USB_STS_DTRANS_MASK) > +/* > + * Device speed. > + * 0 - Undefined (value after reset). > + * 1 - Low speed > + * 2 - Full speed > + * 3 - High speed > + * 4 - Super speed > + */ > +#define USB_STS_USBSPEED_MASK GENMASK(6, 4) > +#define USB_STS_USBSPEED(p) (((p) & USB_STS_USBSPEED_MASK) >> 4) > +#define USB_STS_LS (0x1 << 4) > +#define USB_STS_FS (0x2 << 4) > +#define USB_STS_HS (0x3 << 4) > +#define USB_STS_SS (0x4 << 4) > +#define DEV_UNDEFSPEED(p) (((p) & USB_STS_USBSPEED_MASK) == (0x0 << 4)) > +#define DEV_LOWSPEED(p) (((p) & USB_STS_USBSPEED_MASK) == USB_STS_LS) > +#define DEV_FULLSPEED(p) (((p) & USB_STS_USBSPEED_MASK) == USB_STS_FS) > +#define DEV_HIGHSPEED(p) (((p) & USB_STS_USBSPEED_MASK) == USB_STS_HS) > +#define DEV_SUPERSPEED(p) (((p) & USB_STS_USBSPEED_MASK) == USB_STS_SS) > +/* > + * Endianness for SFR access. > + * 0 - Little Endian order (default after hardware reset). > + * 1 - Big Endian order > + */ > +#define USB_STS_ENDIAN_MASK BIT(7) > +#define USB_STS_ENDIAN(p) ((p) & USB_STS_ENDIAN_MASK) > +/* > + * HS/FS clock turn-off status. > + * 0 - hsfs clock is always on. > + * 1 - hsfs clock turn-off in L2 (HS/FS mode) is enabled > + * (default after hardware reset). > + */ > +#define USB_STS_CLK2OFF_MASK BIT(8) > +#define USB_STS_CLK2OFF(p) ((p) & USB_STS_CLK2OFF_MASK) > +/* > + * PCLK clock turn-off status. > + * 0 - pclk clock is always on. > + * 1 - pclk clock turn-off in U3 (SS mode) is enabled > + * (default after hardware reset). > + */ > +#define USB_STS_CLK3OFF_MASK BIT(9) > +#define USB_STS_CLK3OFF(p) ((p) & USB_STS_CLK3OFF_MASK) > +/* > + * Controller in reset state. > + * 0 - Internal reset is active. > + * 1 - Internal reset is not active and controller is fully operational. > + */ > +#define USB_STS_IN_RST_MASK BIT(10) > +#define USB_STS_IN_RST(p) ((p) & USB_STS_IN_RST_MASK) > +/* > + * Device enable Status. > + * 0 - USB device is disabled (VBUS input is disconnected from internal logic). > + * 1 - USB device is enabled (VBUS input is connected to the internal logic). > + */ > +#define USB_STS_DEVS_MASK BIT(14) > +#define USB_STS_DEVS(p) ((p) & USB_STS_DEVS_MASK) > +/* > + * DAddress statuss. > + * 0 - USB device is default state. > + * 1 - USB device is at least in address state. > + */ > +#define USB_STS_ADDRESSED_MASK BIT(15) > +#define USB_STS_ADDRESSED(p) ((p) & USB_STS_ADDRESSED_MASK) > +/* > + * L1 LPM state enable status (used in HS/FS mode). > + * 0 - Entering to L1 LPM state disabled. > + * 1 - Entering to L1 LPM state enabled. > + */ > +#define USB_STS_L1ENS_MASK BIT(16) > +#define USB_STS_L1ENS(p) ((p) & USB_STS_L1ENS_MASK) > +/* > + * Internal VBUS connection status (used both in HS/FS and SS mode). > + * 0 - internal VBUS is not detected. > + * 1 - internal VBUS is detected. > + */ > +#define USB_STS_VBUSS_MASK BIT(17) > +#define USB_STS_VBUSS(p) ((p) & USB_STS_VBUSS_MASK) > +/* > + * HS/FS LPM state (used in FS/HS mode). > + * 0 - L0 State > + * 1 - L1 State > + * 2 - L2 State > + * 3 - L3 State > + */ > +#define USB_STS_LPMST_MASK GENMASK(19, 18) > +#define DEV_L0_STATE(p) (((p) & USB_STS_LPMST_MASK) == (0x0 << 18)) > +#define DEV_L1_STATE(p) (((p) & USB_STS_LPMST_MASK) == (0x1 << 18)) > +#define DEV_L2_STATE(p) (((p) & USB_STS_LPMST_MASK) == (0x2 << 18)) > +#define DEV_L3_STATE(p) (((p) & USB_STS_LPMST_MASK) == (0x3 << 18)) > +/* > + * Disable HS status (used in FS/HS mode). > + * 0 - the disconnect bit for HS/FS mode is set . > + * 1 - the disconnect bit for HS/FS mode is not set. > + */ > +#define USB_STS_USB2CONS_MASK BIT(20) > +#define USB_STS_USB2CONS(p) ((p) & USB_STS_USB2CONS_MASK) > +/* > + * HS/FS mode connection status (used in FS/HS mode). > + * 0 - High Speed operations in USB2.0 (FS/HS) mode not disabled. > + * 1 - High Speed operations in USB2.0 (FS/HS). > + */ > +#define USB_STS_DISABLE_HS_MASK BIT(21) > +#define USB_STS_DISABLE_HS(p) ((p) & USB_STS_DISABLE_HS_MASK) > +/* > + * U1 state enable status (used in SS mode). > + * 0 - Entering to U1 state disabled. > + * 1 - Entering to U1 state enabled. > + */ > +#define USB_STS_U1ENS_MASK BIT(24) > +#define USB_STS_U1ENS(p) ((p) & USB_STS_U1ENS_MASK) > +/* > + * U2 state enable status (used in SS mode). > + * 0 - Entering to U2 state disabled. > + * 1 - Entering to U2 state enabled. > + */ > +#define USB_STS_U2ENS_MASK BIT(25) > +#define USB_STS_U2ENS(p) ((p) & USB_STS_U2ENS_MASK) > +/* > + * SuperSpeed Link LTSSM state. This field reflects USBSS-DEV current > + * SuperSpeed link state > + */ > +#define USB_STS_LST_MASK GENMASK(29, 26) > +#define DEV_LST_U0 (((p) & USB_STS_LST_MASK) == (0x0 << 26)) > +#define DEV_LST_U1 (((p) & USB_STS_LST_MASK) == (0x1 << 26)) > +#define DEV_LST_U2 (((p) & USB_STS_LST_MASK) == (0x2 << 26)) > +#define DEV_LST_U3 (((p) & USB_STS_LST_MASK) == (0x3 << 26)) > +#define DEV_LST_DISABLED (((p) & USB_STS_LST_MASK) == (0x4 << 26)) > +#define DEV_LST_RXDETECT (((p) & USB_STS_LST_MASK) == (0x5 << 26)) > +#define DEV_LST_INACTIVE (((p) & USB_STS_LST_MASK) == (0x6 << 26)) > +#define DEV_LST_POLLING (((p) & USB_STS_LST_MASK) == (0x7 << 26)) > +#define DEV_LST_RECOVERY (((p) & USB_STS_LST_MASK) == (0x8 << 26)) > +#define DEV_LST_HOT_RESET (((p) & USB_STS_LST_MASK) == (0x9 << 26)) > +#define DEV_LST_COMP_MODE (((p) & USB_STS_LST_MASK) == (0xa << 26)) > +#define DEV_LST_LB_STATE (((p) & USB_STS_LST_MASK) == (0xb << 26)) > +/* > + * DMA clock turn-off status. > + * 0 - DMA clock is always on (default after hardware reset). > + * 1 - DMA clock turn-off in U1, U2 and U3 (SS mode) is enabled. > + */ > +#define USB_STS_DMAOFF_MASK BIT(30) > +#define USB_STS_DMAOFF(p) ((p) & USB_STS_DMAOFF_MASK) > +/* > + * SFR Endian statuss. > + * 0 - Little Endian order (default after hardware reset). > + * 1 - Big Endian order. > + */ > +#define USB_STS_ENDIAN2_MASK BIT(31) > +#define USB_STS_ENDIAN2(p) ((p) & USB_STS_ENDIAN2_MASK) > + > +/* USB_CMD - bitmasks */ > +/* Set Function Address */ > +#define USB_CMD_SET_ADDR BIT(0) > +/* > + * Function Address This field is saved to the device only when the field > + * SET_ADDR is set '1 ' during write to USB_CMD register. > + * Software is responsible for entering the address of the device during > + * SET_ADDRESS request service. This field should be set immediately after > + * the SETUP packet is decoded, and prior to confirmation of the status phase > + */ > +#define USB_CMD_FADDR_MASK GENMASK(7, 1) > +#define USB_CMD_FADDR(p) (((p) << 1) & USB_CMD_FADDR_MASK) > +/* Send Function Wake Device Notification TP (used only in SS mode). */ > +#define USB_CMD_SDNFW BIT(8) > +/* Set Test Mode (used only in HS/FS mode). */ > +#define USB_CMD_STMODE BIT(9) > +/* Test mode selector (used only in HS/FS mode) */ > +#define USB_STS_TMODE_SEL_MASK GENMASK(11, 10) > +#define USB_STS_TMODE_SEL(p) (((p) << 10) & USB_STS_TMODE_SEL_MASK) > +/* > + * Send Latency Tolerance Message Device Notification TP (used only > + * in SS mode). > + */ > +#define USB_CMD_SDNLTM BIT(12) > +/* Send Custom Transaction Packet (used only in SS mode) */ > +#define USB_CMD_SPKT BIT(13) > +/*Device Notification 'Function Wake' - Interface value (only in SS mode. */ > +#define USB_CMD_DNFW_INT_MASK GENMASK(23, 16) > +#define USB_STS_DNFW_INT(p) (((p) << 16) & USB_CMD_DNFW_INT_MASK) > +/* > + * Device Notification 'Latency Tolerance Message' -373 BELT value [7:0] > + * (used only in SS mode). > + */ > +#define USB_CMD_DNLTM_BELT_MASK GENMASK(27, 16) > +#define USB_STS_DNLTM_BELT(p) (((p) << 16) & USB_CMD_DNLTM_BELT_MASK) > + > +/* USB_ITPN - bitmasks */ > +/* > + * ITP(SS) / SOF (HS/FS) number > + * In SS mode this field represent number of last ITP received from host. > + * In HS/FS mode this field represent number of last SOF received from host. > + */ > +#define USB_ITPN_MASK GENMASK(13, 0) > +#define USB_ITPN(p) ((p) & USB_ITPN_MASK) > + > +/* USB_LPM - bitmasks */ > +/* Host Initiated Resume Duration. */ > +#define USB_LPM_HIRD_MASK GENMASK(3, 0) > +#define USB_LPM_HIRD(p) ((p) & USB_LPM_HIRD_MASK) > +/* Remote Wakeup Enable (bRemoteWake). */ > +#define USB_LPM_BRW BIT(4) > + > +/* USB_IEN - bitmasks */ > +/* SS connection interrupt enable */ > +#define USB_IEN_CONIEN BIT(0) > +/* SS disconnection interrupt enable. */ > +#define USB_IEN_DISIEN BIT(1) > +/* USB SS warm reset interrupt enable. */ > +#define USB_IEN_UWRESIEN BIT(2) > +/* USB SS hot reset interrupt enable */ > +#define USB_IEN_UHRESIEN BIT(3) > +/* SS link U3 state enter interrupt enable (suspend).*/ > +#define USB_IEN_U3ENTIEN BIT(4) > +/* SS link U3 state exit interrupt enable (wakeup). */ > +#define USB_IEN_U3EXTIEN BIT(5) > +/* SS link U2 state enter interrupt enable.*/ > +#define USB_IEN_U2ENTIEN BIT(6) > +/* SS link U2 state exit interrupt enable.*/ > +#define USB_IEN_U2EXTIEN BIT(7) > +/* SS link U1 state enter interrupt enable.*/ > +#define USB_IEN_U1ENTIEN BIT(8) > +/* SS link U1 state exit interrupt enable.*/ > +#define USB_IEN_U1EXTIEN BIT(9) > +/* ITP/SOF packet detected interrupt enable.*/ > +#define USB_IEN_ITPIEN BIT(10) > +/* Wakeup interrupt enable.*/ > +#define USB_IEN_WAKEIEN BIT(11) > +/* Send Custom Packet interrupt enable.*/ > +#define USB_IEN_SPKTIEN BIT(12) > +/* HS/FS mode connection interrupt enable.*/ > +#define USB_IEN_CON2IEN BIT(16) > +/* HS/FS mode disconnection interrupt enable.*/ > +#define USB_IEN_DIS2IEN BIT(17) > +/* USB reset (HS/FS mode) interrupt enable.*/ > +#define USB_IEN_U2RESIEN BIT(18) > +/* LPM L2 state enter interrupt enable.*/ > +#define USB_IEN_L2ENTIEN BIT(20) > +/* LPM L2 state exit interrupt enable.*/ > +#define USB_IEN_L2EXTIEN BIT(21) > +/* LPM L1 state enter interrupt enable.*/ > +#define USB_IEN_L1ENTIEN BIT(24) > +/* LPM L1 state exit interrupt enable.*/ > +#define USB_IEN_L1EXTIEN BIT(25) > +/* Configuration reset interrupt enable.*/ > +#define USB_IEN_CFGRESIEN BIT(26) > +/* Start of the USB SS warm reset interrupt enable.*/ > +#define USB_IEN_UWRESSIEN BIT(28) > +/* End of the USB SS warm reset interrupt enable.*/ > +#define USB_IEN_UWRESEIEN BIT(29) > + > +#define USB_IEN_INIT (USB_IEN_U2RESIEN | USB_ISTS_DIS2I | USB_IEN_CON2IEN \ > + | USB_IEN_UHRESIEN | USB_IEN_UWRESIEN | USB_IEN_DISIEN \ > + | USB_IEN_CONIEN | USB_IEN_U3EXTIEN | USB_IEN_L2ENTIEN \ > + | USB_IEN_L2EXTIEN) > + > +/* USB_ISTS - bitmasks */ > +/* SS Connection detected. */ > +#define USB_ISTS_CONI BIT(0) > +/* SS Disconnection detected. */ > +#define USB_ISTS_DISI BIT(1) > +/* UUSB warm reset detectede. */ > +#define USB_ISTS_UWRESI BIT(2) > +/* USB hot reset detected. */ > +#define USB_ISTS_UHRESI BIT(3) > +/* U3 link state enter detected (suspend).*/ > +#define USB_ISTS_U3ENTI BIT(4) > +/* U3 link state exit detected (wakeup). */ > +#define USB_ISTS_U3EXTI BIT(5) > +/* U2 link state enter detected.*/ > +#define USB_ISTS_U2ENTI BIT(6) > +/* U2 link state exit detected.*/ > +#define USB_ISTS_U2EXTI BIT(7) > +/* U1 link state enter detected.*/ > +#define USB_ISTS_U1ENTI BIT(8) > +/* U1 link state exit detected.*/ > +#define USB_ISTS_U1EXTI BIT(9) > +/* ITP/SOF packet detected.*/ > +#define USB_ISTS_ITPI BIT(10) > +/* Wakeup detected.*/ > +#define USB_ISTS_WAKEI BIT(11) > +/* Send Custom Packet detected.*/ > +#define USB_ISTS_SPKTI BIT(12) > +/* HS/FS mode connection detected.*/ > +#define USB_ISTS_CON2I BIT(16) > +/* HS/FS mode disconnection detected.*/ > +#define USB_ISTS_DIS2I BIT(17) > +/* USB reset (HS/FS mode) detected.*/ > +#define USB_ISTS_U2RESI BIT(18) > +/* LPM L2 state enter detected.*/ > +#define USB_ISTS_L2ENTI BIT(20) > +/* LPM L2 state exit detected.*/ > +#define USB_ISTS_L2EXTI BIT(21) > +/* LPM L1 state enter detected.*/ > +#define USB_ISTS_L1ENTI BIT(24) > +/* LPM L1 state exit detected.*/ > +#define USB_ISTS_L1EXTI BIT(25) > +/* USB configuration reset detected.*/ > +#define USB_ISTS_CFGRESI BIT(26) > +/* Start of the USB warm reset detected.*/ > +#define USB_ISTS_UWRESSI BIT(28) > +/* End of the USB warm reset detected.*/ > +#define USB_ISTS_UWRESEI BIT(29) > + > +/* USB_SEL - bitmasks */ > +#define EP_SEL_EPNO_MASK GENMASK(3, 0) > +/* Endpoint number. */ > +#define EP_SEL_EPNO(p) ((p) & EP_SEL_EPNO_MASK) > +/* Endpoint direction bit - 0 - OUT, 1 - IN. */ > +#define EP_SEL_DIR BIT(7) > + > +#define select_ep_in(nr) (EP_SEL_EPNO(p) | EP_SEL_DIR) > +#define select_ep_out (EP_SEL_EPNO(p)) > + > +/* EP_TRADDR - bitmasks */ > +/* Transfer Ring address. */ > +#define EP_TRADDR_TRADDR(p) ((p)) > + > +/* EP_CFG - bitmasks */ > +/* Endpoint enable */ > +#define EP_CFG_ENABLE BIT(0) > +/* > + * Endpoint type. > + * 1 - isochronous > + * 2 - bulk > + * 3 - interrupt > + */ > +#define EP_CFG_EPTYPE_MASK GENMASK(2, 1) > +#define EP_CFG_EPTYPE(p) (((p) << 1) & EP_CFG_EPTYPE_MASK) > +/* Stream support enable (only in SS mode). */ > +#define EP_CFG_STREAM_EN BIT(3) > +/* TDL check (only in SS mode for BULK EP). */ > +#define EP_CFG_TDL_CHK BIT(4) > +/* SID check (only in SS mode for BULK OUT EP). */ > +#define EP_CFG_SID_CHK BIT(5) > +/* DMA transfer endianness. */ > +#define EP_CFG_EPENDIAN BIT(7) > +/* Max burst size (used only in SS mode). */ > +#define EP_CFG_MAXBURST_MASK GENMASK(11, 8) > +#define EP_CFG_MAXBURST(p) (((p) << 8) & EP_CFG_MAXBURST_MASK) > +/* ISO max burst. */ > +#define EP_CFG_MULT_MASK GENMASK(15, 14) > +#define EP_CFG_MULT(p) (((p) << 14) & EP_CFG_MULT_MASK) > +/* ISO max burst. */ > +#define EP_CFG_MAXPKTSIZE_MASK GENMASK(26, 16) > +#define EP_CFG_MAXPKTSIZE(p) (((p) << 16) & EP_CFG_MAXPKTSIZE_MASK) > +/* Max number of buffered packets. */ > +#define EP_CFG_BUFFERING_MASK GENMASK(31, 27) > +#define EP_CFG_BUFFERING(p) (((p) << 27) & EP_CFG_BUFFERING_MASK) > + > +/* EP_CMD - bitmasks */ > +/* Endpoint reset. */ > +#define EP_CMD_EPRST BIT(0) > +/* Endpoint STALL set. */ > +#define EP_CMD_SSTALL BIT(1) > +/* Endpoint STALL clear. */ > +#define EP_CMD_CSTALL BIT(2) > +/* Send ERDY TP. */ > +#define EP_CMD_ERDY BIT(3) > +/* Request complete. */ > +#define EP_CMD_REQ_CMPL BIT(5) > +/* Transfer descriptor ready. */ > +#define EP_CMD_DRDY BIT(6) > +/* Data flush. */ > +#define EP_CMD_DFLUSH BIT(7) > +/* > + * Transfer Descriptor Length write (used only for Bulk Stream capable > + * endpoints in SS mode). > + */ > +#define EP_CMD_STDL BIT(8) > +/* Transfer Descriptor Length (used only in SS mode for bulk endpoints). */ > +#define EP_CMD_TDL_MASK GENMASK(15, 9) > +#define EP_CMD_TDL(p) (((p) << 9) & EP_CMD_TDL_MASK) > +/* ERDY Stream ID value (used in SS mode). */ > +#define EP_CMD_ERDY_SID_MASK GENMASK(31, 16) > +#define EP_CMD_ERDY_SID(p) (((p) << 16) & EP_CMD_SID_MASK) > + > +/* EP_STS - bitmasks */ > +/* Setup transfer complete. */ > +#define EP_STS_SETUP BIT(0) > +/* Endpoint STALL status. */ > +#define EP_STS_STALL(p) ((p) & BIT(1)) > +/* Interrupt On Complete. */ > +#define EP_STS_IOC BIT(2) > +/* Interrupt on Short Packet. */ > +#define EP_STS_ISP BIT(3) > +/* Transfer descriptor missing. */ > +#define EP_STS_DESCMIS BIT(4) > +/* Stream Rejected (used only in SS mode) */ > +#define EP_STS_STREAMR BIT(5) > +/* EXIT from MOVE DATA State (used only for stream transfers in SS mode). */ > +#define EP_STS_MD_EXIT BIT(6) > +/* TRB error. */ > +#define EP_STS_TRBERR BIT(7) > +/* Not ready (used only in SS mode). */ > +#define EP_STS_NRDY BIT(8) > +/* DMA busy. */ > +#define EP_STS_DBUSY(p) ((p) & BIT(9)) > +/* Endpoint Buffer Empty */ > +#define EP_STS_BUFFEMPTY(p) ((p) & BIT(10)) > +/* Current Cycle Status */ > +#define EP_STS_CCS(p) ((p) & BIT(11)) > +/* Prime (used only in SS mode. */ > +#define EP_STS_PRIME BIT(12) > +/* Stream error (used only in SS mode). */ > +#define EP_STS_SIDERR BIT(13) > +/* OUT size mismatch. */ > +#define EP_STS_OUTSMM BIT(14) > +/* ISO transmission error. */ > +#define EP_STS_ISOERR BIT(15) > +/* Host Packet Pending (only for SS mode). */ > +#define EP_STS_HOSTPP(p) ((p) & BIT(16)) > +/* Stream Protocol State Machine State (only for Bulk stream endpoints). */ > +#define EP_STS_SPSMST_MASK GENMASK(18, 17) > +#define EP_STS_SPSMST_DISABLED(p) (((p) & EP_STS_SPSMST_MASK) >> 17) > +#define EP_STS_SPSMST_IDLE(p) (((p) & EP_STS_SPSMST_MASK) >> 17) > +#define EP_STS_SPSMST_START_STREAM(p) (((p) & EP_STS_SPSMST_MASK) >> 17) > +#define EP_STS_SPSMST_MOVE_DATA(p) (((p) & EP_STS_SPSMST_MASK) >> 17) > +/* Interrupt On Transfer complete. */ > +#define EP_STS_IOT BIT(19) > +/* OUT queue endpoint number. */ > +#define EP_STS_OUTQ_NO_MASK GENMASK(27, 24) > +#define EP_STS_OUTQ_NO(p) (((p) & EP_STS_OUTQ_NO_MASK) >> 24) > +/* OUT queue valid flag. */ > +#define EP_STS_OUTQ_VAL_MASK BIT(28) > +#define EP_STS_OUTQ_VAL(p) ((p) & EP_STS_OUTQ_VAL_MASK) > +/* SETUP WAIT. */ > +#define EP_STS_STPWAIT BIT(31) > + > +/* EP_STS_SID - bitmasks */ > +/* Stream ID (used only in SS mode). */ > +#define EP_STS_SID_MASK GENMASK(15, 0) > +#define EP_STS_SID(p) ((p) & EP_STS_SID_MASK) > + > +/* EP_STS_EN - bitmasks */ > +/* SETUP interrupt enable. */ > +#define EP_STS_EN_SETUPEN BIT(0) > +/* OUT transfer missing descriptor enable. */ > +#define EP_STS_EN_DESCMISEN BIT(4) > +/* Stream Rejected enable. */ > +#define EP_STS_EN_STREAMREN BIT(5) > +/* Move Data Exit enable.*/ > +#define EP_STS_EN_MD_EXITEN BIT(6) > +/* TRB enable. */ > +#define EP_STS_EN_TRBERREN BIT(7) > +/* NRDY enable. */ > +#define EP_STS_EN_NRDYEN BIT(8) > +/* Prime enable. */ > +#define EP_STS_EN_PRIMEEEN BIT(12) > +/* Stream error enable. */ > +#define EP_STS_EN_SIDERREN BIT(13) > +/* OUT size mismatch enable. */ > +#define EP_STS_EN_OUTSMMEN BIT(14) > +/* ISO transmission error enable. */ > +#define EP_STS_EN_ISOERREN BIT(15) > +/* Interrupt on Transmission complete enable. */ > +#define EP_STS_EN_IOTEN BIT(19) > +/* Setup Wait interrupt enable. */ > +#define EP_STS_EN_STPWAITEN BIT(31) > + > +/* DRBL- bitmasks */ > +#define DB_VALUE_BY_INDEX(index) (1 << (index)) > +#define DB_VALUE_EP0_OUT BIT(0) > +#define DB_VALUE_EP0_IN BIT(16) > + > +/* EP_IEN - bitmasks */ > +#define EP_IEN(index) (1 << (index)) > +#define EP_IEN_EP_OUT0 BIT(0) > +#define EP_IEN_EP_IN0 BIT(16) > + > +/* EP_ISTS - bitmasks */ > +#define EP_ISTS(index) (1 << (index)) > +#define EP_ISTS_EP_OUT0 BIT(0) > +#define EP_ISTS_EP_IN0 BIT(16) > + > +/* EP_PWR- bitmasks */ > +/*Power Shut Off capability enable*/ > +#define PUSB_PWR_PSO_EN BIT(0) > +/*Power Shut Off capability disable*/ > +#define PUSB_PWR_PSO_DS BIT(1) > +/* > + * Enables turning-off Reference Clock. > + * This bit is optional and implemented only when support for OTG is > + * implemented (indicated by OTG_READY bit set to '1'). > + */ > +#define PUSB_PWR_STB_CLK_SWITCH_EN BIT(8) > +/* > + * Status bit indicating that operation required by STB_CLK_SWITCH_EN write > + * is completed > + */ > +#define PUSB_PWR_STB_CLK_SWITCH_DONE BIT(9) > +/* This bit informs if Fast Registers Access is enabled. */ > +#define PUSB_PWR_FST_REG_ACCESS_STAT BIT(30) > +/* Fast Registers Access Enable. */ > +#define PUSB_PWR_FST_REG_ACCESS BIT(31) > + > +/* USB_CAP1- bitmasks */ > +/* > + * SFR Interface type > + * These field reflects type of SFR interface implemented: > + * 0x0 - OCP > + * 0x1 - AHB, > + * 0x2 - PLB > + * 0x3 - AXI > + * 0x4-0xF - reserved > + */ > +#define USB_CAP1_SFR_TYPE_MASK GENMASK(3, 0) > +#define DEV_SFR_TYPE_OCP(p) (((p) & USB_CAP1_SFR_TYPE_MASK) == 0x0) > +#define DEV_SFR_TYPE_AHB(p) (((p) & USB_CAP1_SFR_TYPE_MASK) == 0x1) > +#define DEV_SFR_TYPE_PLB(p) (((p) & USB_CAP1_SFR_TYPE_MASK) == 0x2) > +#define DEV_SFR_TYPE_AXI(p) (((p) & USB_CAP1_SFR_TYPE_MASK) == 0x3) > +/* > + * SFR Interface width > + * These field reflects width of SFR interface implemented: > + * 0x0 - 8 bit interface, > + * 0x1 - 16 bit interface, > + * 0x2 - 32 bit interface > + * 0x3 - 64 bit interface > + * 0x4-0xF - reserved > + */ > +#define USB_CAP1_SFR_WIDTH_MASK GENMASK(7, 4) > +#define DEV_SFR_WIDTH_8(p) (((p) & USB_CAP1_SFR_WIDTH_MASK) == (0x0 << 4)) > +#define DEV_SFR_WIDTH_16(p) (((p) & USB_CAP1_SFR_WIDTH_MASK) == (0x1 << 4)) > +#define DEV_SFR_WIDTH_32(p) (((p) & USB_CAP1_SFR_WIDTH_MASK) == (0x2 << 4)) > +#define DEV_SFR_WIDTH_64(p) (((p) & USB_CAP1_SFR_WIDTH_MASK) == (0x3 << 4)) > +/* > + * DMA Interface type > + * These field reflects type of DMA interface implemented: > + * 0x0 - OCP > + * 0x1 - AHB, > + * 0x2 - PLB > + * 0x3 - AXI > + * 0x4-0xF - reserved > + */ > +#define USB_CAP1_DMA_TYPE_MASK GENMASK(11, 8) > +#define DEV_DMA_TYPE_OCP(p) (((p) & USB_CAP1_DMA_TYPE_MASK) == (0x0 << 8)) > +#define DEV_DMA_TYPE_AHB(p) (((p) & USB_CAP1_DMA_TYPE_MASK) == (0x1 << 8)) > +#define DEV_DMA_TYPE_PLB(p) (((p) & USB_CAP1_DMA_TYPE_MASK) == (0x2 << 8)) > +#define DEV_DMA_TYPE_AXI(p) (((p) & USB_CAP1_DMA_TYPE_MASK) == (0x3 << 8)) > +/* > + * DMA Interface width > + * These field reflects width of DMA interface implemented: > + * 0x0 - reserved, > + * 0x1 - reserved, > + * 0x2 - 32 bit interface > + * 0x3 - 64 bit interface > + * 0x4-0xF - reserved > + */ > +#define USB_CAP1_DMA_WIDTH_MASK GENMASK(15, 12) > +#define DEV_DMA_WIDTH_32(p) (((p) & USB_CAP1_DMA_WIDTH_MASK) == (0x2 << 12)) > +#define DEV_DMA_WIDTH_64(p) (((p) & USB_CAP1_DMA_WIDTH_MASK) == (0x3 << 12)) > +/* > + * USB3 PHY Interface type > + * These field reflects type of USB3 PHY interface implemented: > + * 0x0 - USB PIPE, > + * 0x1 - RMMI, > + * 0x2-0xF - reserved > + */ > +#define USB_CAP1_U3PHY_TYPE_MASK GENMASK(19, 16) > +#define DEV_U3PHY_PIPE(p) (((p) & USB_CAP1_U3PHY_TYPE_MASK) == (0x0 << 16)) > +#define DEV_U3PHY_RMMI(p) (((p) & USB_CAP1_U3PHY_TYPE_MASK) == (0x1 << 16)) > +/* > + * USB3 PHY Interface width > + * These field reflects width of USB3 PHY interface implemented: > + * 0x0 - 8 bit PIPE interface, > + * 0x1 - 16 bit PIPE interface, > + * 0x2 - 32 bit PIPE interface, > + * 0x3 - 64 bit PIPE interface > + * 0x4-0xF - reserved > + * Note: When SSIC interface is implemented this field shows the width of > + * internal PIPE interface. The RMMI interface is always 20bit wide. > + */ > +#define USB_CAP1_U3PHY_WIDTH_MASK GENMASK(23, 20) > +#define DEV_U3PHY_WIDTH_8(p) \ > + (((p) & USB_CAP1_U3PHY_WIDTH_MASK) == (0x0 << 20)) > +#define DEV_U3PHY_WIDTH_16(p) \ > + (((p) & USB_CAP1_U3PHY_WIDTH_MASK) == (0x1 << 16)) > +#define DEV_U3PHY_WIDTH_32(p) \ > + (((p) & USB_CAP1_U3PHY_WIDTH_MASK) == (0x2 << 20)) > +#define DEV_U3PHY_WIDTH_64(p) \ > + (((p) & USB_CAP1_U3PHY_WIDTH_MASK) == (0x3 << 16)) > + > +/* > + * USB2 PHY Interface enable > + * These field informs if USB2 PHY interface is implemented: > + * 0x0 - interface NOT implemented, > + * 0x1 - interface implemented > + */ > +#define USB_CAP1_U2PHY_EN(p) ((p) & BIT(24)) > +/* > + * USB2 PHY Interface type > + * These field reflects type of USB2 PHY interface implemented: > + * 0x0 - UTMI, > + * 0x1 - ULPI > + */ > +#define DEV_U2PHY_ULPI(p) ((p) & BIT(25)) > +/* > + * USB2 PHY Interface width > + * These field reflects width of USB2 PHY interface implemented: > + * 0x0 - 8 bit interface, > + * 0x1 - 16 bit interface, > + * Note: The ULPI interface is always 8bit wide. > + */ > +#define DEV_U2PHY_WIDTH_16(p) ((p) & BIT(26)) > +/* > + * OTG Ready > + * 0x0 - pure device mode > + * 0x1 - some features and ports for CDNS USB OTG controller are implemented. > + */ > +#define USB_CAP1_OTG_READY(p) ((p) & BIT(27)) > + > +/* USB_CAP2- bitmasks */ > +/* > + * The actual size of the connected On-chip RAM memory in kB: > + * - 0 means 256 kB (max supported mem size) > + * - value other than 0 reflects the mem size in kB > + */ > +#define USB_CAP2_ACTUAL_MEM_SIZE(p) ((p) & GENMASK(7, 0)) > +/* > + * Max supported mem size > + * These field reflects width of on-chip RAM address bus width, > + * which determines max supported mem size: > + * 0x0-0x7 - reserved, > + * 0x8 - support for 4kB mem, > + * 0x9 - support for 8kB mem, > + * 0xA - support for 16kB mem, > + * 0xB - support for 32kB mem, > + * 0xC - support for 64kB mem, > + * 0xD - support for 128kB mem, > + * 0xE - support for 256kB mem, > + * 0xF - reserved > + */ > +#define USB_CAP2_MAX_MEM_SIZE(p) ((p) & GENMASK(11, 8)) > + > +/* USB_CAP3- bitmasks */ > +#define EP_IS_IMPLEMENTED(reg, index) ((reg) & (1 << (index))) > + > +/* USB_CAP4- bitmasks */ > +#define EP_SUPPORT_ISO(reg, index) ((reg) & (1 << (index))) > + > +/* USB_CAP5- bitmasks */ > +#define EP_SUPPORT_STREAM(reg, index) ((reg) & (1 << (index))) > + > +/* USB_CAP6- bitmasks */ > +/* The USBSS-DEV Controller Internal build number. */ > +#define GET_DEV_VERSION__INTERNAL_NUMBER(p) ((p) & GENMASK(7, 0)) > +/* The USBSS-DEV Controller version number. */ > +#define GET_DEV_VERSION(p) ((p) & GENMASK(31, 8)) > + > +/* DBG_LINK1- bitmasks */ > +/* > + * LFPS_MIN_DET_U1_EXIT value This parameter configures the minimum > + * time required for decoding the received LFPS as an LFPS.U1_Exit. > + */ > +#define DBG_LINK1_LFPS_MIN_DET_U1_EXIT(p) ((p) & GENMASK(7, 0)) > +/* > + * LFPS_MIN_GEN_U1_EXIT value This parameter configures the minimum time for > + * phytxelecidle deassertion when LFPS.U1_Exit > + */ > +#define DBG_LINK1_LFPS_MIN_GEN_U1_EXIT_MASK GENMASK(15, 8) > +#define DBG_LINK1_LFPS_MIN_GEN_U1_EXIT(p) (((p) << 8) & GENMASK(15, 8)) > +/* > + * RXDET_BREAK_DIS value This parameter configures terminating the Far-end > + * Receiver termination detection sequence: > + * 0: it is possible that USBSS_DEV will terminate Farend receiver > + * termination detection sequence > + * 1: USBSS_DEV will not terminate Far-end receiver termination > + * detection sequence > + */ > +#define DBG_LINK1_RXDET_BREAK_DIS BIT(16) > +/* LFPS_GEN_PING value This parameter configures the LFPS.Ping generation */ > +#define DBG_LINK1_LFPS_GEN_PING(p) (((p) << 17) & GENMASK(21, 17)) > +/* > + * Set the LFPS_MIN_DET_U1_EXIT value Writing '1' to this bit writes the > + * LFPS_MIN_DET_U1_EXIT field value to the device. This bit is automatically > + * cleared. Writing '0' has no effect > + */ > +#define DBG_LINK1_LFPS_MIN_DET_U1_EXIT_SET BIT(24) > +/* > + * Set the LFPS_MIN_GEN_U1_EXIT value. Writing '1' to this bit writes the > + * LFPS_MIN_GEN_U1_EXIT field value to the device. This bit is automatically > + * cleared. Writing '0' has no effect > + */ > +#define DBG_LINK1_LFPS_MIN_GEN_U1_EXIT_SET BIT(25) > +/* > + * Set the RXDET_BREAK_DIS value Writing '1' to this bit writes > + * the RXDET_BREAK_DIS field value to the device. This bit is automatically > + * cleared. Writing '0' has no effect > + */ > +#define DBG_LINK1_RXDET_BREAK_DIS_SET BIT(26) > +/* > + * Set the LFPS_GEN_PING_SET value Writing '1' to this bit writes > + * the LFPS_GEN_PING field value to the device. This bit is automatically > + * cleared. Writing '0' has no effect." > + */ > +#define DBG_LINK1_LFPS_GEN_PING_SET BIT(27) > + > +#define gadget_to_cdns3_device(g) (container_of(g, struct cdns3_device, gadget)) > + > +#define ep_to_cdns3_ep(ep) (container_of(ep, struct cdns3_endpoint, endpoint)) > + > +/*-------------------------------------------------------------------------*/ > +/* > + * USBSS-DEV DMA interface. > + */ > +#define TRBS_PER_SEGMENT 40 > + > +#define ISO_MAX_INTERVAL 10 > + > +/* > + *Only for ISOC endpoints - maximum number of TRBs is calculated as > + * pow(2, bInterval-1) * number of usb requests. It is limitation made by > + * driver to save memory. Controller must prepare TRB for each ITP even > + * if bInterval > 1. It's the reason why driver needs so many TRBs for > + * isochronous endpoints. > + */ > +#define TRBS_PER_ISOC_SEGMENT (ISO_MAX_INTERVAL * 8) > + > +#define GET_TRBS_PER_SEGMENT(ep_type) ((ep_type) == USB_ENDPOINT_XFER_ISOC ? \ > + TRBS_PER_ISOC_SEGMENT : TRBS_PER_SEGMENT) > +/** > + * struct cdns3_trb - represent Transfer Descriptor block. > + * @buffer: pointer to buffer data > + * @length: length of data > + * @control: control flags. > + * > + * This structure describes transfer block serviced by DMA module. > + */ > +struct cdns3_trb { > + __le32 buffer; > + __le32 length; > + __le32 control; > +}; > + > +#define TRB_SIZE (sizeof(struct cdns3_trb)) > +#define TRB_RING_SIZE (TRB_SIZE * TRBS_PER_SEGMENT) > +#define TRB_ISO_RING_SIZE (TRB_SIZE * TRBS_PER_ISOC_SEGMENT) > +#define TRB_CTRL_RING_SIZE (TRB_SIZE * 2) > + > +/* TRB bit mask */ > +#define TRB_TYPE_BITMASK GENMASK(15, 10) > +#define TRB_TYPE(p) ((p) << 10) > +#define TRB_FIELD_TO_TYPE(p) (((p) & TRB_TYPE_BITMASK) >> 10) > + > +/* TRB type IDs */ > +/* bulk, interrupt, isoc , and control data stage */ > +#define TRB_NORMAL 1 > +/* TRB for linking ring segments */ > +#define TRB_LINK 6 > + > +/* Cycle bit - indicates TRB ownership by driver or hw*/ > +#define TRB_CYCLE BIT(0) > +/* > + * When set to '1', the device will toggle its interpretation of the Cycle bit > + */ > +#define TRB_TOGGLE BIT(1) > + > +/* Interrupt on short packet*/ > +#define TRB_ISP BIT(2) > +/*Setting this bit enables FIFO DMA operation mode*/ > +#define TRB_FIFO_MODE BIT(3) > +/* Set PCIe no snoop attribute */ > +#define TRB_CHAIN BIT(4) > +/* Interrupt on completion */ > +#define TRB_IOC BIT(5) > + > +/* stream ID bitmasks. */ > +#define TRB_STREAM_ID(p) ((p) & GENMASK(31, 16)) > + > +/* transfer_len bitmasks. */ > +#define TRB_LEN(p) ((p) & GENMASK(16, 0)) > + > +/* transfer_len bitmasks - bits 31:24 */ > +#define TRB_BURST_LEN(p) ((p) & GENMASK(31, 24)) > + > +/* Data buffer pointer bitmasks*/ > +#define TRB_BUFFER(p) ((p) & GENMASK(31, 0)) > + > +/*-------------------------------------------------------------------------*/ > +/* Driver numeric constants */ > + > +/* Such declaration should be added to ch9.h */ > +#define USB_DEVICE_MAX_ADDRESS 127 > + > +/* Endpoint init values */ > +#define CDNS3_EP_MAX_PACKET_LIMIT 1024 > +#define CDNS3_EP_MAX_STREAMS 15 > +#define CDNS3_EP0_MAX_PACKET_LIMIT 512 > + > +/* All endpoints including EP0 */ > +#define CDNS3_ENDPOINTS_MAX_COUNT 32 > +#define CDNS3_EP_ZLP_BUF_SIZE 1024 > + > +#define CDNS3_EP_BUF_SIZE 2 /* KB */ > +#define CDNS3_ALIGNED_BUF_SIZE 16384 /* Bytes */ > +#define CDNS3_MAX_NUM_DESCMISS_BUF 32 > +#define CDNS3_DESCMIS_BUF_SIZE 2048 /* Bytes */ > +/*-------------------------------------------------------------------------*/ > +/* Used structs */ > + > +struct cdns3_device; > + > +/** > + * struct cdns3_endpoint - extended device side representation of USB endpoint. > + * @endpoint: usb endpoint > + * @pending_req_list: list of requests queuing on transfer ring. > + * @deferred_req_list: list of requests waiting for queuing on transfer ring. > + * @trb_pool: transfer ring - array of transaction buffers > + * @trb_pool_dma: dma address of transfer ring > + * @cdns3_dev: device associated with this endpoint > + * @name: a human readable name e.g. ep1out > + * @flags: specify the current state of endpoint > + * @descmis_req: internal transfer object used for getting data from on-chip > + * buffer. It can happen only if function driver doesn't send usb_request > + * object on time. > + * @aligned_buff: aligned to 8 bytes data buffer. Buffer address used in > + * TRB shall be aligned to 8. > + * @aligned_dma_addr: dma address of aligned_buff > + * @dir: endpoint direction > + * @num: endpoint number (1 - 15) > + * @type: set to bmAttributes & USB_ENDPOINT_XFERTYPE_MASK > + * @interval: interval between packets used for ISOC endpoint. > + * @free_trbs: number of free TRBs in transfer ring > + * @num_trbs: number of all TRBs in transfer ring > + * @pcs: producer cycle state > + * @ccs: consumer cycle state > + * @enqueue: enqueue index in transfer ring > + * @dequeue: dequeue index in transfer ring > + */ > +struct cdns3_endpoint { > + struct usb_ep endpoint; > + struct list_head pending_req_list; > + struct list_head deferred_req_list; > + > + struct cdns3_trb *trb_pool; > + dma_addr_t trb_pool_dma; > + > + struct cdns3_device *cdns3_dev; > + char name[20]; > + > +#define EP_ENABLED BIT(0) > +#define EP_STALL BIT(1) > +#define EP_WEDGE BIT(2) > +#define EP_TRANSFER_STARTED BIT(3) > +#define EP_UPDATE_EP_TRBADDR BIT(4) > +#define EP_PENDING_REQUEST BIT(5) > +#define EP_RING_FULL BIT(6) > +#define EP_CLAIMED BIT(7) > + > + u32 flags; > + > + struct cdns3_request *descmis_req; > + > + void *aligned_buff; > + dma_addr_t aligned_dma_addr; > + u8 dir; > + u8 num; > + u8 type; > + int interval; > + > + int free_trbs; > + int num_trbs; > + u8 pcs; > + u8 ccs; > + int enqueue; > + int dequeue; > + > + unsigned int wa1_set:1; > + struct cdns3_trb *wa1_trb; > + unsigned int wa1_cycle_bit:1; > +}; > + > +/** > + * struct cdns3_request - extended device side representation of usb_request > + * object . > + * @request: generic usb_request object describing single I/O request. > + * @priv_ep: extended representation of usb_ep object > + * @trb: the first TRB association with this request > + * @start_trb: number of the first TRB in transfer ring > + * @end_trb: number of the last TRB in transfer ring > + * @flags: flag specifying special usage of request > + */ > +struct cdns3_request { > + struct usb_request request; > + struct cdns3_endpoint *priv_ep; > + struct cdns3_trb *trb; > + int start_trb; > + int end_trb; > +#define REQUEST_PENDING BIT(0) > +#define REQUEST_INTERNAL BIT(1) > +#define REQUEST_INTERNAL_CH BIT(2) > +#define REQUEST_ZLP BIT(3) > + u32 flags; > +}; > + > +#define to_cdns3_request(r) (container_of(r, struct cdns3_request, request)) > + > +/*Stages used during enumeration process.*/ > +#define CDNS3_SETUP_STAGE 0x0 > +#define CDNS3_DATA_STAGE 0x1 > +#define CDNS3_STATUS_STAGE 0x2 > + > +/** > + * struct cdns3_device - represent USB device. > + * @dev: pointer to device structure associated whit this controller > + * @sysdev: pointer to the DMA capable device > + * @gadget: device side representation of the peripheral controller > + * @gadget_driver: pointer to the gadget driver > + * @dev_ver: device controller version. > + * @lock: for synchronizing > + * @regs: base address for device side registers > + * @setup_buf: used while processing usb control requests > + * @setup_dma: dma address for setup_buf > + * @zlp_buf - zlp buffer > + * @ep0_stage: ep0 stage during enumeration process. > + * @ep0_data_dir: direction for control transfer > + * @eps: array of pointers to all endpoints with exclusion ep0 > + * @selected_ep: actually selected endpoint. It's used only to improve > + * performance. > + * @isoch_delay: value from Set Isoch Delay request. Only valid on SS/SSP. > + * @u1_allowed: allow device transition to u1 state > + * @u2_allowed: allow device transition to u2 state > + * @is_selfpowered: device is self powered > + * @setup_pending: setup packet is processing by gadget driver > + * @hw_configured_flag: hardware endpoint configuration was set. > + * @wake_up_flag: allow device to remote up the host > + * @status_completion_no_call: indicate that driver is waiting for status s > + * stage completion. It's used in deferred SET_CONFIGURATION request. > + * @onchip_mem_allocated_size: actual size of on-chip memory assigned > + * to endpoints > + * @pending_status_wq: workqueue handling status stage for deferred requests. > + * @shadow_ep_en: hold information about endpoints that will be enabled > + * in soft irq. > + * @pending_status_request: request for which status stage was deferred > + */ > +struct cdns3_device { > + struct device *dev; > + struct device *sysdev; > + > + struct usb_gadget gadget; > + struct usb_gadget_driver *gadget_driver; > + > +#define CDNS_REVISION_V0 0x00024501 > +#define CDNS_REVISION_V1 0x00024509 > + u32 dev_ver; > + > + /* generic spin-lock for drivers */ > + spinlock_t lock; > + > + struct cdns3_usb_regs __iomem *regs; > + > + struct usb_ctrlrequest *setup_buf; > + dma_addr_t setup_dma; > + void *zlp_buf; > + > + u8 ep0_stage; > + int ep0_data_dir; > + > + struct cdns3_endpoint *eps[CDNS3_ENDPOINTS_MAX_COUNT]; > + > + u32 selected_ep; > + u16 isoch_delay; > + > + unsigned u1_allowed:1; > + unsigned u2_allowed:1; > + unsigned is_selfpowered:1; > + unsigned setup_pending:1; > + int hw_configured_flag:1; > + int wake_up_flag:1; > + unsigned status_completion_no_call:1; > + > + struct work_struct pending_status_wq; > + struct usb_request *pending_status_request; > + u32 shadow_ep_en; > + /*in KB */ > + int onchip_mem_allocated_size; > +}; > + > +int cdns3_handshake(void __iomem *ptr, u32 mask, u32 done, int usec); > +void cdns3_set_register_bit(void __iomem *ptr, u32 mask); > +dma_addr_t cdns3_trb_virt_to_dma(struct cdns3_endpoint *priv_ep, > + struct cdns3_trb *trb); > +enum usb_device_speed cdns3_get_speed(struct cdns3_device *priv_dev); > +void cdns3_pending_setup_status_handler(struct work_struct *work); > +void cdns3_hw_reset_eps_config(struct cdns3_device *priv_dev); > +void cdns3_set_hw_configuration(struct cdns3_device *priv_dev); > +void cdns3_select_ep(struct cdns3_device *priv_dev, u32 ep); > +void cdns3_allow_enable_l1(struct cdns3_device *priv_dev, int enable); > +struct usb_request *cdns3_next_request(struct list_head *list); > +int cdns3_ep_run_transfer(struct cdns3_endpoint *priv_ep, > + struct usb_request *request); > +void cdns3_rearm_transfer(struct cdns3_endpoint *priv_ep, u8 rearm); > +int cdns3_allocate_trb_pool(struct cdns3_endpoint *priv_ep); > +u8 cdns3_ep_addr_to_index(u8 ep_addr); > +int cdns3_gadget_ep_set_wedge(struct usb_ep *ep); > +int cdns3_gadget_ep_set_halt(struct usb_ep *ep, int value); > +struct usb_request *cdns3_gadget_ep_alloc_request(struct usb_ep *ep, > + gfp_t gfp_flags); > +void cdns3_gadget_ep_free_request(struct usb_ep *ep, > + struct usb_request *request); > +int cdns3_gadget_ep_dequeue(struct usb_ep *ep, struct usb_request *request); > +void cdns3_gadget_giveback(struct cdns3_endpoint *priv_ep, > + struct cdns3_request *priv_req, > + int status); > + > +int cdns3_init_ep0(struct cdns3_device *priv_dev, > + struct cdns3_endpoint *priv_ep); > +void cdns3_ep0_config(struct cdns3_device *priv_dev); > +void cdns3_ep_config(struct cdns3_endpoint *priv_ep); > +void cdns3_check_ep0_interrupt_proceed(struct cdns3_device *priv_dev, int dir); > + > +#endif /* __LINUX_CDNS3_GADGET */ > diff --git a/drivers/usb/cdns3/host-export.h b/drivers/usb/cdns3/host-export.h > new file mode 100644 > index 000000000000..b498a170b7e8 > --- /dev/null > +++ b/drivers/usb/cdns3/host-export.h > @@ -0,0 +1,28 @@ > +/* SPDX-License-Identifier: GPL-2.0 */ > +/* > + * Cadence USBSS DRD Driver - Host Export APIs > + * > + * Copyright (C) 2017-2018 NXP > + * > + * Authors: Peter Chen > + */ > +#ifndef __LINUX_CDNS3_HOST_EXPORT > +#define __LINUX_CDNS3_HOST_EXPORT > + > +#ifdef CONFIG_USB_CDNS3_HOST > + > +int cdns3_host_init(struct cdns3 *cdns); > +void cdns3_host_exit(struct cdns3 *cdns); > + > +#else > + > +static inline int cdns3_host_init(struct cdns3 *cdns) > +{ > + return -ENXIO; > +} > + > +static inline void cdns3_host_exit(struct cdns3 *cdns) { } > + > +#endif /* CONFIG_USB_CDNS3_HOST */ > + > +#endif /* __LINUX_CDNS3_HOST_EXPORT */ > diff --git a/drivers/usb/cdns3/host.c b/drivers/usb/cdns3/host.c > new file mode 100644 > index 000000000000..b43b0236a885 > --- /dev/null > +++ b/drivers/usb/cdns3/host.c > @@ -0,0 +1,72 @@ > +// SPDX-License-Identifier: GPL-2.0 > +/* > + * Cadence USBSS DRD Driver - host side > + * > + * Copyright (C) 2018 Cadence Design Systems. > + * Copyright (C) 2017-2018 NXP > + * > + * Authors: Peter Chen > + * Pawel Laszczak > + */ > + > +#include > +#include "core.h" > + > +static int __cdns3_host_init(struct cdns3 *cdns) > +{ > + struct platform_device *xhci; > + int ret; > + > + xhci = platform_device_alloc("xhci-hcd", PLATFORM_DEVID_AUTO); > + if (!xhci) { > + dev_err(cdns->dev, "couldn't allocate xHCI device\n"); > + return -ENOMEM; > + } > + > + xhci->dev.parent = cdns->dev; > + cdns->host_dev = xhci; > + > + ret = platform_device_add_resources(xhci, cdns->xhci_res, > + CDNS3_XHCI_RESOURCES_NUM); > + if (ret) { > + dev_err(cdns->dev, "couldn't add resources to xHCI device\n"); > + goto err1; > + } > + > + ret = platform_device_add(xhci); > + if (ret) { > + dev_err(cdns->dev, "failed to register xHCI device\n"); > + goto err1; > + } > + > + return 0; > +err1: > + platform_device_put(xhci); > + return ret; > +} > + > +static void cdns3_host_exit(struct cdns3 *cdns) > +{ > + platform_device_unregister(cdns->host_dev); > + cdns->host_dev = NULL; > +} > + > +int cdns3_host_init(struct cdns3 *cdns) > +{ > + struct cdns3_role_driver *rdrv; > + > + rdrv = devm_kzalloc(cdns->dev, sizeof(*rdrv), GFP_KERNEL); > + if (!rdrv) > + return -ENOMEM; > + > + rdrv->start = __cdns3_host_init; > + rdrv->stop = cdns3_host_exit; > + rdrv->state = CDNS3_ROLE_STATE_INACTIVE; > + rdrv->suspend = NULL; > + rdrv->resume = NULL; > + rdrv->name = "host"; > + > + cdns->roles[CDNS3_ROLE_HOST] = rdrv; > + > + return 0; > +} > diff --git a/drivers/usb/cdns3/trace.c b/drivers/usb/cdns3/trace.c > new file mode 100644 > index 000000000000..9431eb86d4ff > --- /dev/null > +++ b/drivers/usb/cdns3/trace.c > @@ -0,0 +1,23 @@ > +// SPDX-License-Identifier: GPL-2.0 > +/* > + * USBSS device controller driver Trace Support > + * > + * Copyright (C) 2018 Cadence. > + * > + * Author: Pawel Laszczak > + */ > + > +#define CREATE_TRACE_POINTS > +#include "trace.h" > + > +void cdns3_dbg(struct cdns3_device *priv_dev, const char *fmt, ...) > +{ > + struct va_format vaf; > + va_list args; > + > + va_start(args, fmt); > + vaf.fmt = fmt; > + vaf.va = &args; > + trace_cdns3_log(priv_dev, &vaf); > + va_end(args); > +} > diff --git a/drivers/usb/cdns3/trace.h b/drivers/usb/cdns3/trace.h > new file mode 100644 > index 000000000000..a6bbf91c616b > --- /dev/null > +++ b/drivers/usb/cdns3/trace.h > @@ -0,0 +1,404 @@ > +/* SPDX-License-Identifier: GPL-2.0 */ > +/* > + * USBSS device controller driver. > + * Trace support header file. > + * > + * Copyright (C) 2018 Cadence. > + * > + * Author: Pawel Laszczak > + */ > + > +#undef TRACE_SYSTEM > +#define TRACE_SYSTEM cdns3 > + > +#if !defined(__LINUX_CDNS3_TRACE) || defined(TRACE_HEADER_MULTI_READ) > +#define __LINUX_CDNS3_TRACE > + > +#include > +#include > +#include > +#include > +#include "core.h" > +#include "gadget.h" > +#include "debug.h" > + > +#define CDNS3_MSG_MAX 500 > + > +TRACE_EVENT(cdns3_log, > + TP_PROTO(struct cdns3_device *priv_dev, struct va_format *vaf), > + TP_ARGS(priv_dev, vaf), > + TP_STRUCT__entry( > + __string(name, dev_name(priv_dev->dev)) > + __dynamic_array(char, msg, CDNS3_MSG_MAX) > + ), > + TP_fast_assign( > + __assign_str(name, dev_name(priv_dev->dev)); > + vsnprintf(__get_str(msg), CDNS3_MSG_MAX, vaf->fmt, *vaf->va); > + ), > + TP_printk("%s: %s", __get_str(name), __get_str(msg)) > +); > + > +DECLARE_EVENT_CLASS(cdns3_log_doorbell, > + TP_PROTO(const char *ep_name, u32 ep_trbaddr), > + TP_ARGS(ep_name, ep_trbaddr), > + TP_STRUCT__entry( > + __string(name, ep_name) > + __field(u32, ep_trbaddr) > + ), > + TP_fast_assign( > + __assign_str(name, ep_name); > + __entry->ep_trbaddr = ep_trbaddr; > + ), > + TP_printk("//Ding Dong %s, ep_trbaddr %08x", __get_str(name), > + __entry->ep_trbaddr) > +); > + > +DEFINE_EVENT(cdns3_log_doorbell, cdns3_doorbell_ep0, > + TP_PROTO(const char *ep_name, u32 ep_trbaddr), > + TP_ARGS(ep_name, ep_trbaddr) > +); > + > +DEFINE_EVENT(cdns3_log_doorbell, cdns3_doorbell_epx, > + TP_PROTO(const char *ep_name, u32 ep_trbaddr), > + TP_ARGS(ep_name, ep_trbaddr) > +); > + > +DECLARE_EVENT_CLASS(cdns3_log_usb_irq, > + TP_PROTO(struct cdns3_device *priv_dev, u32 usb_ists), > + TP_ARGS(priv_dev, usb_ists), > + TP_STRUCT__entry( > + __field(enum usb_device_speed, speed) > + __field(u32, usb_ists) > + __dynamic_array(char, str, CDNS3_MSG_MAX) > + ), > + TP_fast_assign( > + __entry->speed = cdns3_get_speed(priv_dev); > + __entry->usb_ists = usb_ists; > + ), > + TP_printk("%s", cdns3_decode_usb_irq(__get_str(str), __entry->speed, > + __entry->usb_ists)) > +); > + > +DEFINE_EVENT(cdns3_log_usb_irq, cdns3_usb_irq, > + TP_PROTO(struct cdns3_device *priv_dev, u32 usb_ists), > + TP_ARGS(priv_dev, usb_ists) > +); > + > +DECLARE_EVENT_CLASS(cdns3_log_epx_irq, > + TP_PROTO(struct cdns3_device *priv_dev, struct cdns3_endpoint *priv_ep), > + TP_ARGS(priv_dev, priv_ep), > + TP_STRUCT__entry( > + __string(ep_name, priv_ep->name) > + __field(u32, ep_sts) > + __field(u32, ep_traddr) > + __dynamic_array(char, str, CDNS3_MSG_MAX) > + ), > + TP_fast_assign( > + __assign_str(ep_name, priv_ep->name); > + __entry->ep_sts = readl(&priv_dev->regs->ep_sts); > + __entry->ep_traddr = readl(&priv_dev->regs->ep_traddr); > + ), > + TP_printk("%s, ep_traddr: %08x", > + cdns3_decode_epx_irq(__get_str(str), > + __get_str(ep_name), > + __entry->ep_sts), > + __entry->ep_traddr) > +); > + > +DEFINE_EVENT(cdns3_log_epx_irq, cdns3_epx_irq, > + TP_PROTO(struct cdns3_device *priv_dev, struct cdns3_endpoint *priv_ep), > + TP_ARGS(priv_dev, priv_ep) > +); > + > +DECLARE_EVENT_CLASS(cdns3_log_ep0_irq, > + TP_PROTO(struct cdns3_device *priv_dev, u32 ep_sts), > + TP_ARGS(priv_dev, ep_sts), > + TP_STRUCT__entry( > + __field(int, ep_dir) > + __field(u32, ep_sts) > + __dynamic_array(char, str, CDNS3_MSG_MAX) > + ), > + TP_fast_assign( > + __entry->ep_dir = priv_dev->ep0_data_dir; > + __entry->ep_sts = ep_sts; > + ), > + TP_printk("%s", cdns3_decode_ep0_irq(__get_str(str), > + __entry->ep_dir, > + __entry->ep_sts)) > +); > + > +DEFINE_EVENT(cdns3_log_ep0_irq, cdns3_ep0_irq, > + TP_PROTO(struct cdns3_device *priv_dev, u32 ep_sts), > + TP_ARGS(priv_dev, ep_sts) > +); > + > +DECLARE_EVENT_CLASS(cdns3_log_ctrl, > + TP_PROTO(struct usb_ctrlrequest *ctrl), > + TP_ARGS(ctrl), > + TP_STRUCT__entry( > + __field(u8, bRequestType) > + __field(u8, bRequest) > + __field(u16, wValue) > + __field(u16, wIndex) > + __field(u16, wLength) > + __dynamic_array(char, str, CDNS3_MSG_MAX) > + ), > + TP_fast_assign( > + __entry->bRequestType = ctrl->bRequestType; > + __entry->bRequest = ctrl->bRequest; > + __entry->wValue = le16_to_cpu(ctrl->wValue); > + __entry->wIndex = le16_to_cpu(ctrl->wIndex); > + __entry->wLength = le16_to_cpu(ctrl->wLength); > + ), > + TP_printk("%s", usb_decode_ctrl(__get_str(str), CDNS3_MSG_MAX, > + __entry->bRequestType, > + __entry->bRequest, __entry->wValue, > + __entry->wIndex, __entry->wLength) > + ) > +); > + > +DEFINE_EVENT(cdns3_log_ctrl, cdns3_ctrl_req, > + TP_PROTO(struct usb_ctrlrequest *ctrl), > + TP_ARGS(ctrl) > +); > + > +DECLARE_EVENT_CLASS(cdns3_log_request, > + TP_PROTO(struct cdns3_request *req), > + TP_ARGS(req), > + TP_STRUCT__entry( > + __string(name, req->priv_ep->name) > + __field(struct cdns3_request *, req) > + __field(unsigned int, actual) > + __field(unsigned int, length) > + __field(int, status) > + __field(int, zero) > + __field(int, short_not_ok) > + __field(int, no_interrupt) > + __field(int, start_trb) > + __field(int, end_trb) > + __field(struct cdns3_trb *, start_trb_addr) > + __field(int, flags) > + ), > + TP_fast_assign( > + __assign_str(name, req->priv_ep->name); > + __entry->req = req; > + __entry->actual = req->request.actual; > + __entry->length = req->request.length; > + __entry->status = req->request.status; > + __entry->zero = req->request.zero; > + __entry->short_not_ok = req->request.short_not_ok; > + __entry->no_interrupt = req->request.no_interrupt; > + __entry->start_trb = req->start_trb; > + __entry->end_trb = req->end_trb; > + __entry->start_trb_addr = req->trb; > + __entry->flags = req->flags; > + ), > + TP_printk("%s: req: %p, length: %u/%u %s%s%s, status: %d," > + " trb: [start:%d, end:%d: virt addr %pa], flags:%x ", > + __get_str(name), __entry->req, __entry->actual, __entry->length, > + __entry->zero ? "zero | " : "", > + __entry->short_not_ok ? "short | " : "", > + __entry->no_interrupt ? "no int" : "", > + __entry->status, > + __entry->start_trb, > + __entry->end_trb, > + __entry->start_trb_addr, > + __entry->flags > + ) > +); > + > +DEFINE_EVENT(cdns3_log_request, cdns3_alloc_request, > + TP_PROTO(struct cdns3_request *req), > + TP_ARGS(req) > +); > + > +DEFINE_EVENT(cdns3_log_request, cdns3_free_request, > + TP_PROTO(struct cdns3_request *req), > + TP_ARGS(req) > +); > + > +DEFINE_EVENT(cdns3_log_request, cdns3_ep_queue, > + TP_PROTO(struct cdns3_request *req), > + TP_ARGS(req) > +); > + > +DEFINE_EVENT(cdns3_log_request, cdns3_ep_dequeue, > + TP_PROTO(struct cdns3_request *req), > + TP_ARGS(req) > +); > + > +DEFINE_EVENT(cdns3_log_request, cdns3_gadget_giveback, > + TP_PROTO(struct cdns3_request *req), > + TP_ARGS(req) > +); > + > +DECLARE_EVENT_CLASS(cdns3_log_trb, > + TP_PROTO(struct cdns3_endpoint *priv_ep, struct cdns3_trb *trb), > + TP_ARGS(priv_ep, trb), > + TP_STRUCT__entry( > + __string(name, priv_ep->name) > + __field(struct cdns3_trb *, trb) > + __field(u32, buffer) > + __field(u32, length) > + __field(u32, control) > + __field(u32, type) > + ), > + TP_fast_assign( > + __assign_str(name, priv_ep->name); > + __entry->trb = trb; > + __entry->buffer = trb->buffer; > + __entry->length = trb->length; > + __entry->control = trb->control; > + __entry->type = usb_endpoint_type(priv_ep->endpoint.desc); > + ), > + TP_printk("%s: trb %pa, dma buf: 0x%08x, size: %ld, ctrl: 0x%08x (%s%s%s%s%s%s%s)", > + __get_str(name), __entry->trb, __entry->buffer, > + TRB_LEN(__entry->length), __entry->control, > + __entry->control & TRB_CYCLE ? "C=1, " : "C=0, ", > + __entry->control & TRB_TOGGLE ? "T=1, " : "T=0, ", > + __entry->control & TRB_ISP ? "ISP, " : "", > + __entry->control & TRB_FIFO_MODE ? "FIFO, " : "", > + __entry->control & TRB_CHAIN ? "CHAIN, " : "", > + __entry->control & TRB_IOC ? "IOC, " : "", > + TRB_FIELD_TO_TYPE(__entry->control) == TRB_NORMAL ? "Normal" : "LINK" > + ) > +); > + > +DEFINE_EVENT(cdns3_log_trb, cdns3_prepare_trb, > + TP_PROTO(struct cdns3_endpoint *priv_ep, struct cdns3_trb *trb), > + TP_ARGS(priv_ep, trb) > +); > + > +DEFINE_EVENT(cdns3_log_trb, cdns3_complete_trb, > + TP_PROTO(struct cdns3_endpoint *priv_ep, struct cdns3_trb *trb), > + TP_ARGS(priv_ep, trb) > +); > + > +DECLARE_EVENT_CLASS(cdns3_log_ring, > + TP_PROTO(struct cdns3_endpoint *priv_ep), > + TP_ARGS(priv_ep), > + TP_STRUCT__entry( > + __dynamic_array(u8, ring, TRB_RING_SIZE) > + __dynamic_array(u8, priv_ep, sizeof(struct cdns3_endpoint)) > + __dynamic_array(char, buffer, > + (TRBS_PER_SEGMENT * 65) + CDNS3_MSG_MAX) > + ), > + TP_fast_assign( > + memcpy(__get_dynamic_array(priv_ep), priv_ep, > + sizeof(struct cdns3_endpoint)); > + memcpy(__get_dynamic_array(ring), priv_ep->trb_pool, > + TRB_RING_SIZE); > + ), > + > + TP_printk("%s", > + cdns3_dbg_ring((struct cdns3_endpoint *)__get_str(priv_ep), > + (struct cdns3_trb *)__get_str(ring), > + __get_str(buffer))) > +); > + > +DEFINE_EVENT(cdns3_log_ring, cdns3_ring, > + TP_PROTO(struct cdns3_endpoint *priv_ep), > + TP_ARGS(priv_ep) > +); > + > +DECLARE_EVENT_CLASS(cdns3_log_ep, > + TP_PROTO(struct cdns3_endpoint *priv_ep), > + TP_ARGS(priv_ep), > + TP_STRUCT__entry( > + __string(name, priv_ep->name) > + __field(unsigned int, maxpacket) > + __field(unsigned int, maxpacket_limit) > + __field(unsigned int, max_streams) > + __field(unsigned int, maxburst) > + __field(unsigned int, flags) > + __field(unsigned int, dir) > + __field(u8, enqueue) > + __field(u8, dequeue) > + ), > + TP_fast_assign( > + __assign_str(name, priv_ep->name); > + __entry->maxpacket = priv_ep->endpoint.maxpacket; > + __entry->maxpacket_limit = priv_ep->endpoint.maxpacket_limit; > + __entry->max_streams = priv_ep->endpoint.max_streams; > + __entry->maxburst = priv_ep->endpoint.maxburst; > + __entry->flags = priv_ep->flags; > + __entry->dir = priv_ep->dir; > + __entry->enqueue = priv_ep->enqueue; > + __entry->dequeue = priv_ep->dequeue; > + ), > + TP_printk("%s: mps: %d/%d. streams: %d, burst: %d, enq idx: %d, " > + "deq idx: %d, flags %s%s%s%s%s%s%s%s, dir: %s", > + __get_str(name), __entry->maxpacket, > + __entry->maxpacket_limit, __entry->max_streams, > + __entry->maxburst, __entry->enqueue, > + __entry->dequeue, > + __entry->flags & EP_ENABLED ? "EN | " : "", > + __entry->flags & EP_STALL ? "STALL | " : "", > + __entry->flags & EP_WEDGE ? "WEDGE | " : "", > + __entry->flags & EP_TRANSFER_STARTED ? "STARTED | " : "", > + __entry->flags & EP_UPDATE_EP_TRBADDR ? "UPD TRB | " : "", > + __entry->flags & EP_PENDING_REQUEST ? "REQ PEN | " : "", > + __entry->flags & EP_RING_FULL ? "RING FULL |" : "", > + __entry->flags & EP_CLAIMED ? "CLAIMED " : "", > + __entry->dir ? "IN" : "OUT" > + ) > +); > + > +DEFINE_EVENT(cdns3_log_ep, cdns3_gadget_ep_enable, > + TP_PROTO(struct cdns3_endpoint *priv_ep), > + TP_ARGS(priv_ep) > +); > + > +DEFINE_EVENT(cdns3_log_ep, cdns3_gadget_ep_disable, > + TP_PROTO(struct cdns3_endpoint *priv_ep), > + TP_ARGS(priv_ep) > +); > + > +DECLARE_EVENT_CLASS(cdns3_log_request_handled, > + TP_PROTO(struct cdns3_request *priv_req, int current_index, > + int handled), > + TP_ARGS(priv_req, current_index, handled), > + TP_STRUCT__entry( > + __field(struct cdns3_request *, priv_req) > + __field(unsigned int, dma_position) > + __field(unsigned int, handled) > + __field(unsigned int, dequeue_idx) > + __field(unsigned int, enqueue_idx) > + __field(unsigned int, start_trb) > + __field(unsigned int, end_trb) > + ), > + TP_fast_assign( > + __entry->priv_req = priv_req; > + __entry->dma_position = current_index; > + __entry->handled = handled; > + __entry->dequeue_idx = priv_req->priv_ep->dequeue; > + __entry->enqueue_idx = priv_req->priv_ep->enqueue; > + __entry->start_trb = priv_req->start_trb; > + __entry->end_trb = priv_req->end_trb; > + ), > + TP_printk("Req: %p %s, DMA pos: %d, ep deq: %d, ep enq: %d," > + " start trb: %d, end trb: %d", > + __entry->priv_req, > + __entry->handled ? "handled" : "not handled", > + __entry->dma_position, __entry->dequeue_idx, > + __entry->enqueue_idx, __entry->start_trb, > + __entry->end_trb > + ) > +); > + > +DEFINE_EVENT(cdns3_log_request_handled, cdns3_request_handled, > + TP_PROTO(struct cdns3_request *priv_req, int current_index, > + int handled), > + TP_ARGS(priv_req, current_index, handled) > +); > +#endif /* __LINUX_CDNS3_TRACE */ > + > +/* this part must be outside header guard */ > + > +#undef TRACE_INCLUDE_PATH > +#define TRACE_INCLUDE_PATH . > + > +#undef TRACE_INCLUDE_FILE > +#define TRACE_INCLUDE_FILE trace > + > +#include > -- > 2.17.1 > From mboxrd@z Thu Jan 1 00:00:00 1970 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: base64 Subject: [v4,5/6] usb:cdns3 Add Cadence USB3 DRD Driver From: Peter Chen Message-Id: Date: Thu, 21 Feb 2019 17:22:42 +0800 To: Pawel Laszczak Cc: devicetree@vger.kernel.org, Greg Kroah-Hartman , felipe.balbi@linux.intel.com, mark.rutland@arm.com, linux-usb@vger.kernel.org, hdegoede@redhat.com, Heikki Krogerus , andy.shevchenko@gmail.com, robh+dt@kernel.org, rogerq@ti.com, lkml , jbergsagel@ti.com, nsekhar@ti.com, nm@ti.com, sureshp@cadence.com, peter.chen@nxp.com, kurahul@cadence.com List-ID: PiAraW50IGNkbnMzX3NldF9tb2RlKHN0cnVjdCBjZG5zMyAqY2RucywgZW51bSB1c2JfZHJfbW9k ZSBtb2RlKQo+ICt7Cj4gKyAgICAgICBpbnQgcmV0ID0gMDsKPiArICAgICAgIHUzMiByZWc7Cj4g Kwo+ICsgICAgICAgY2Rucy0+Y3VycmVudF9kcl9tb2RlID0gbW9kZTsKPiArCj4gKyAgICAgICBz d2l0Y2ggKG1vZGUpIHsKPiArICAgICAgIGNhc2UgVVNCX0RSX01PREVfUEVSSVBIRVJBTDoKPiAr ICAgICAgICAgICAgICAgZGV2X2luZm8oY2Rucy0+ZGV2LCAiU2V0IGNvbnRyb2xsZXIgdG8gR2Fk Z2V0IG1vZGVcbiIpOwo+ICsgICAgICAgICAgICAgICByZXQgPSBjZG5zM19kcmRfc3dpdGNoX2dh ZGdldChjZG5zLCAxKTsKPiArICAgICAgICAgICAgICAgYnJlYWs7Cj4gKyAgICAgICBjYXNlIFVT Ql9EUl9NT0RFX0hPU1Q6Cj4gKyAgICAgICAgICAgICAgIGRldl9pbmZvKGNkbnMtPmRldiwgIlNl dCBjb250cm9sbGVyIHRvIEhvc3QgbW9kZVxuIik7Cj4gKyAgICAgICAgICAgICAgIHJldCA9IGNk bnMzX2RyZF9zd2l0Y2hfaG9zdChjZG5zLCAxKTsKPiArICAgICAgICAgICAgICAgYnJlYWs7Cj4g KyAgICAgICBjYXNlIFVTQl9EUl9NT0RFX09URzoKPiArICAgICAgICAgICAgICAgZGV2X2luZm8o Y2Rucy0+ZGV2LCAiU2V0IGNvbnRyb2xsZXIgdG8gT1RHIG1vZGVcbiIpOwo+ICsgICAgICAgICAg ICAgICBpZiAoY2Rucy0+dmVyc2lvbiA9PSBDRE5TM19DT05UUk9MTEVSX1YxKSB7Cj4gKyAgICAg ICAgICAgICAgICAgICAgICAgcmVnID0gcmVhZGwoJmNkbnMtPm90Z192MV9yZWdzLT5vdmVycmlk ZSk7Cj4gKyAgICAgICAgICAgICAgICAgICAgICAgcmVnIHw9IE9WRVJSSURFX0lEUFVMTFVQOwo+ ICsgICAgICAgICAgICAgICAgICAgICAgIHdyaXRlbChyZWcsICZjZG5zLT5vdGdfdjFfcmVncy0+ b3ZlcnJpZGUpOwo+ICsgICAgICAgICAgICAgICB9IGVsc2Ugewo+ICsgICAgICAgICAgICAgICAg ICAgICAgIHJlZyA9IHJlYWRsKCZjZG5zLT5vdGdfdjBfcmVncy0+Y3RybDEpOwo+ICsgICAgICAg ICAgICAgICAgICAgICAgIHJlZyB8PSBPVkVSUklERV9JRFBVTExVUF9WMDsKPiArICAgICAgICAg ICAgICAgICAgICAgICB3cml0ZWwocmVnLCAmY2Rucy0+b3RnX3YwX3JlZ3MtPmN0cmwxKTsKPiAr ICAgICAgICAgICAgICAgfQo+ICsKPiArICAgICAgICAgICAgICAgLyoKPiArICAgICAgICAgICAg ICAgICogSGFyZHdhcmUgc3BlY2lmaWNhdGlvbiBzYXlzOiAiSURfVkFMVUUgbXVzdCBiZSB2YWxp ZCB3aXRoaW4KPiArICAgICAgICAgICAgICAgICogNTBtcyBhZnRlciBpZHB1bGx1cCBpcyBzZXQg dG8gJzEiIHNvIGRyaXZlciBtdXN0IHdhaXQKPiArICAgICAgICAgICAgICAgICogNTBtcyBiZWZv cmUgcmVhZGluZyB0aGlzIHBpbi4KPiArICAgICAgICAgICAgICAgICovCj4gKyAgICAgICAgICAg ICAgIHVzbGVlcF9yYW5nZSg1MDAwMCwgNjAwMDApOwo+ICsgICAgICAgICAgICAgICBicmVhazsK PiArICAgICAgIGRlZmF1bHQ6Cj4gKyAgICAgICAgICAgICAgIGNkbnMtPmN1cnJlbnRfZHJfbW9k ZSA9IFVTQl9EUl9NT0RFX1VOS05PV047Cj4gKyAgICAgICAgICAgICAgIGRldl9lcnIoY2Rucy0+ ZGV2LCAiVW5zdXBwb3J0ZWQgbW9kZSBvZiBvcGVyYXRpb24gJWRcbiIsIG1vZGUpOwo+ICsgICAg ICAgICAgICAgICByZXR1cm4gLUVJTlZBTDsKPiArICAgICAgIH0KPiArCj4gKyAgICAgICByZXR1 cm4gcmV0Owo+ICt9Cj4gKwo+ICtpbnQgY2RuczNfZ2V0X2lkKHN0cnVjdCBjZG5zMyAqY2RucykK PiArewo+ICsgICAgICAgaW50IGlkOwo+ICsKPiArICAgICAgIGlkID0gcmVhZGwoJmNkbnMtPm90 Z19yZWdzLT5zdHMpICYgT1RHU1RTX0lEX1ZBTFVFOwo+ICsgICAgICAgZGV2X2RiZyhjZG5zLT5k ZXYsICJPVEcgSUQ6ICVkIiwgaWQpOwo+ICsgICAgICAgcmV0dXJuIGlkOwo+ICt9Cj4gKwo+ICtp bnQgY2RuczNfaXNfaG9zdChzdHJ1Y3QgY2RuczMgKmNkbnMpCj4gK3sKPiArICAgICAgIGlmIChj ZG5zLT5jdXJyZW50X2RyX21vZGUgPT0gVVNCX0RSX01PREVfSE9TVCkKPiArICAgICAgICAgICAg ICAgcmV0dXJuIDE7CgpJIHJ1biBvdXQgaXNzdWUgaWYgSSBzZXQgZHJfbW9kZSBhcyBob3N0IGF0 IGR0cyAoZmlybXdhcmUpLiAgV2UgbmVlZCB0byByZXR1cm4KMSBhdCB0aGlzIGNhc2UsIGJ1dCB0 aGUgY2Rucy0+Y3VycmVudF9kcl9tb2RlIGlzIGNoYW5nZWQgdG8gT1RHIGJlZm9yZS4KSWYgd2Ug c2V0IHBlcmlwaGVyYWwtb25seSBvciBob3N0LW9ubHkgYXQgZHRzLCB0aGUgYWJvdmUganVkZ2Vt ZW50IHNob3VsZApvbmx5IHJlcGx5IG9uIGR0cyBzZXR0aW5nLiBCZWxvdyBjaGFuZ2VzIHdvcmsg YXQgbXkgcGxhdGZvcm06CgpbICAgIDIuNzY5ODgxXSBjZG5zLXVzYjMgNWIxMzAwMDAuY2RuczM6 IGNkbnMzX2RyZF91cGRhdGVfbW9kZTozOjE6MwpbICAgIDIuNzc3OTkwXSBjZG5zLXVzYjMgNWIx MzAwMDAuY2RuczM6IFNldCBjb250cm9sbGVyIHRvIE9URyBtb2RlClsgICAgMi44NDkzNTNdIGNk bnMtdXNiMyA1YjEzMDAwMC5jZG5zMzogV2FpdGluZyBmb3IgSG9zdCBtb2RlIGlzIHR1cm5lZCBv bgpbICAgIDIuODQ5Njg5XSBjZG5zLXVzYjMgNWIxMzAwMDAuY2RuczM6IENhZGVuY2UgVVNCMyBj b3JlOiBwcm9iZSBzdWNjZWVkClsgICAgMi44NDk3MjJdIG54cC1jZG5zMyA1YjExMDAwMC51c2Iz OiBDYWRlbmNlIFVTQjMgY29yZTogcHJvYmUgc3VjY2VlZAoKRnJvbSBhYm92ZSBsb2csIHRoZSBj ZG5zM19kcmRfdXBkYXRlX21vZGUgaXMgY2FsbGVkIHR3aWNlLCBhbmQgdGhlIGNvbnRyb2xsZXIK c3dpdGNoZXMgbGlrZSBJTklUX01PREUtPkhPU1QtPk9URy0+SE9TVC4gWW91ciByb2xlIGluaXRp YWxpemF0aW9uIGlzIGEgbGl0dGxlCiBjb21wbGljYXRlZCwgcGxlYXNlIHRyeSB0byBzaW1wbHkg aXQuUGxlYXNlIHRyeSB0byBzaW1wbHkgaXQuCkJlc2lkZXMsIGRvIHlvdSByZWFsbHkKbmVlZCBz byBtYW55IHZhcmlhYmxlcyBmb3IgZHJfbW9kZT8gZHJfbW9kZSBpcyBzdGF0aWMgZnJvbSBmaXJt d2FyZSwgdGhlIGR5bmFtaWMKc3RhdHVzIGNhbiBiZSBkZXNjcmliZWQgYnkgY2Rucy0+cm9sZS4K CkJlbG93IGlzIHRoZSBvdXRwdXQgSSBzZXQgZHJfbW9kZSBhcyBwZXJpcGhlcmFsOgpbICAgIDEu OTAwMDI5XSBjZG5zLXVzYjMgNWIxMzAwMDAuY2RuczM6IERSRCB2ZXJzaW9uIHYwICgwMDAwMDEw MCkKWyAgICAxLjkwNTk4M10gY2Rucy11c2IzIDViMTMwMDAwLmNkbnMzOiBDb250cm9sbGVyIHN0 cmFwcGVkIHRvIFBFUklQSEVSQUwKWyAgICAxLjkxMjY2OV0gY2Rucy11c2IzIDViMTMwMDAwLmNk bnMzOiBjZG5zM19kcmRfdXBkYXRlX21vZGU6MjowOjIKWyAgICAxLjkyMDgwM10gY2Rucy11c2Iz IDViMTMwMDAwLmNkbnMzOiBTZXQgY29udHJvbGxlciB0byBHYWRnZXQgbW9kZQpbICAgIDEuOTI3 MTIxXSBjZG5zLXVzYjMgNWIxMzAwMDAuY2RuczM6IFdhaXRpbmcgZm9yIERldmljZSBtb2RlIGlz IHR1cm5lZCBvbgpbICAgIDEuOTI3MTM4XSBjZG5zLXVzYjMgNWIxMzAwMDAuY2RuczM6IGNkbnMz X2RyZF91cGRhdGVfbW9kZTozOjI6MwpbICAgIDEuOTM1MjYxXSBjZG5zLXVzYjMgNWIxMzAwMDAu Y2RuczM6IFNldCBjb250cm9sbGVyIHRvIE9URyBtb2RlClsgICAgMi4wMDEzMDVdIGNkbnMtdXNi MyA1YjEzMDAwMC5jZG5zMzogT1RHIElEOiAxClsgICAgMi4wMDEzMTJdIGNkbnMtdXNiMyA1YjEz MDAwMC5jZG5zMzogV2FpdGluZyBmb3IgRGV2aWNlIG1vZGUgaXMgdHVybmVkIG9uClsgICAgMi4w MDEzMjFdIGNkbnMtdXNiMyA1YjEzMDAwMC5jZG5zMzogT1RHIElEOiAxClsgICAgMi4wMDEzMzRd IGNkbnMtdXNiMyA1YjEzMDAwMC5jZG5zMzogSW5pdGlhbGl6aW5nIG5vbi16ZXJvIGVuZHBvaW50 cwoKQW5kIHRoZSBvdXRwdXQgZm9yIGNkbnMzX2RyZF91cGRhdGVfbW9kZSBpczoKQEAgLTIzMCw2 ICsyMzAsOCBAQCBpbnQgY2RuczNfZHJkX3VwZGF0ZV9tb2RlKHN0cnVjdCBjZG5zMyAqY2RucykK IHsKICAgICAgICBpbnQgcmV0ID0gMDsKCisgICAgICAgZGV2X2RiZyhjZG5zLT5kZXYsICIlczol ZDolZDolZCBcbiIsIF9fZnVuY19fLCBjZG5zLT5kZXNpcmVkX2RyX21vZGUsCisgICAgICAgICAg ICAgICBjZG5zLT5jdXJyZW50X2RyX21vZGUsIGNkbnMtPmRyX21vZGUpOwoKQmVzaWRlcyBhYm92 ZSBpc3N1ZSwgc2VlbXMgeW91IGZvcmdldCB0byBzZXQgT1RHU0lNVUxBVEUuT1RHX0NGR19GQVNU X1NJTVMsClRoZSBzZXQgaG9zdCB3aWxsIHRpbWVvdXQgd2hlbiBzd2l0Y2ggZnJvbSBvdGcgdG8g aG9zdC4KCkJlbG93IGNvZGUgd29ya3MgYXQgbXkgc2lkZQoKQEAgLTMxNCw2ICszMTYsNyBAQCBp bnQgY2RuczNfZHJkX2luaXQoc3RydWN0IGNkbnMzICpjZG5zKQogICAgICAgICAgICAgICAgY2Ru cy0+dmVyc2lvbiAgPSBDRE5TM19DT05UUk9MTEVSX1YwOwogICAgICAgICAgICAgICAgY2Rucy0+ b3RnX3YxX3JlZ3MgPSBOVUxMOwogICAgICAgICAgICAgICAgY2Rucy0+b3RnX3JlZ3MgPSByZWdz OworICAgICAgICAgICAgICAgd3JpdGVsKDEsICZjZG5zLT5vdGdfdjBfcmVncy0+c2ltdWxhdGUp OwogICAgICAgICAgICAgICAgZGV2X2luZm8oY2Rucy0+ZGV2LCAiRFJEIHZlcnNpb24gdjAgKCUw OHgpXG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgcmVhZGwoJmNkbnMtPm90Z192MF9yZWdz LT52ZXJzaW9uKSk7CgpQZXRlcgoKPiArICAgICAgIGVsc2UgaWYgKCFjZG5zM19nZXRfaWQoY2Ru cykpCj4gKyAgICAgICAgICAgICAgIHJldHVybiAxOwo+ICsKPiArICAgICAgIHJldHVybiAwOwo+ ICt9Cj4gKwoKCj4gK2ludCBjZG5zM19pc19kZXZpY2Uoc3RydWN0IGNkbnMzICpjZG5zKQo+ICt7 Cj4gKyAgICAgICBpZiAoY2Rucy0+Y3VycmVudF9kcl9tb2RlID09IFVTQl9EUl9NT0RFX1BFUklQ SEVSQUwpCj4gKyAgICAgICAgICAgICAgIHJldHVybiAxOwo+ICsgICAgICAgZWxzZSBpZiAoY2Ru cy0+Y3VycmVudF9kcl9tb2RlID09IFVTQl9EUl9NT0RFX09URykKPiArICAgICAgICAgICAgICAg aWYgKGNkbnMzX2dldF9pZChjZG5zKSkKPiArICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4g MTsKPiArCj4gKyAgICAgICByZXR1cm4gMDsKPiArfQo+ICsKPiArLyoqCj4gKyAqIGNkbnMzX290 Z19kaXNhYmxlX2lycSAtIERpc2FibGUgYWxsIE9URyBpbnRlcnJ1cHRzCj4gKyAqIEBjZG5zOiBQ b2ludGVyIHRvIGNvbnRyb2xsZXIgY29udGV4dCBzdHJ1Y3R1cmUKPiArICovCj4gK3N0YXRpYyB2 b2lkIGNkbnMzX290Z19kaXNhYmxlX2lycShzdHJ1Y3QgY2RuczMgKmNkbnMpCj4gK3sKPiArICAg ICAgIHdyaXRlbCgwLCAmY2Rucy0+b3RnX3JlZ3MtPmllbik7Cj4gK30KPiArCj4gKy8qKgo+ICsg KiBjZG5zM19vdGdfZW5hYmxlX2lycSAtIGVuYWJsZSBpZCBhbmQgc2Vzc192YWxpZCBpbnRlcnJ1 cHRzCj4gKyAqIEBjZG5zOiBQb2ludGVyIHRvIGNvbnRyb2xsZXIgY29udGV4dCBzdHJ1Y3R1cmUK PiArICovCj4gK3N0YXRpYyB2b2lkIGNkbnMzX290Z19lbmFibGVfaXJxKHN0cnVjdCBjZG5zMyAq Y2RucykKPiArewo+ICsgICAgICAgd3JpdGVsKE9UR0lFTl9JRF9DSEFOR0VfSU5UIHwgT1RHSUVO X1ZCVVNWQUxJRF9SSVNFX0lOVCB8Cj4gKyAgICAgICAgICAgICAgT1RHSUVOX1ZCVVNWQUxJRF9G QUxMX0lOVCwgJmNkbnMtPm90Z19yZWdzLT5pZW4pOwo+ICt9Cj4gKwo+ICsvKioKPiArICogY2Ru czNfZHJkX3N3aXRjaF9ob3N0IC0gc3RhcnQvc3RvcCBob3N0Cj4gKyAqIEBjZG5zOiBQb2ludGVy IHRvIGNvbnRyb2xsZXIgY29udGV4dCBzdHJ1Y3R1cmUKPiArICogQG9uOiAxIGZvciBzdGFydCwg MCBmb3Igc3RvcAo+ICsgKgo+ICsgKiBSZXR1cm5zIDAgb24gc3VjY2VzcyBvdGhlcndpc2UgbmVn YXRpdmUgZXJybm8KPiArICovCj4gK3N0YXRpYyBpbnQgY2RuczNfZHJkX3N3aXRjaF9ob3N0KHN0 cnVjdCBjZG5zMyAqY2RucywgaW50IG9uKQo+ICt7Cj4gKyAgICAgICBpbnQgcmV0Owo+ICsgICAg ICAgdTMyIHJlZyA9IE9UR0NNRF9PVEdfRElTOwo+ICsKPiArICAgICAgIC8qIHN3aXRjaCBPVEcg Y29yZSAqLwo+ICsgICAgICAgaWYgKG9uKSB7Cj4gKyAgICAgICAgICAgICAgIHdyaXRlbChPVEdD TURfSE9TVF9CVVNfUkVRIHwgcmVnLCAmY2Rucy0+b3RnX3JlZ3MtPmNtZCk7Cj4gKwo+ICsgICAg ICAgICAgICAgICBkZXZfZGJnKGNkbnMtPmRldiwgIldhaXRpbmcgZm9yIEhvc3QgbW9kZSBpcyB0 dXJuZWQgb25cbiIpOwo+ICsgICAgICAgICAgICAgICByZXQgPSBjZG5zM19oYW5kc2hha2UoJmNk bnMtPm90Z19yZWdzLT5zdHMsIE9UR1NUU19YSENJX1JFQURZLAo+ICsgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgT1RHU1RTX1hIQ0lfUkVBRFksIDEwMDAwMCk7Cj4gKwo+ICsg ICAgICAgICAgICAgICBpZiAocmV0KQo+ICsgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBy ZXQ7Cj4gKyAgICAgICB9IGVsc2Ugewo+ICsgICAgICAgICAgICAgICB1c2xlZXBfcmFuZ2UoMzAs IDQwKTsKPiArICAgICAgICAgICAgICAgd3JpdGVsKE9UR0NNRF9IT1NUX0JVU19EUk9QIHwgT1RH Q01EX0RFVl9CVVNfRFJPUCB8Cj4gKyAgICAgICAgICAgICAgICAgICAgICBPVEdDTURfREVWX1BP V0VSX09GRiB8IE9UR0NNRF9IT1NUX1BPV0VSX09GRiwKPiArICAgICAgICAgICAgICAgICAgICAg ICZjZG5zLT5vdGdfcmVncy0+Y21kKTsKPiArICAgICAgICAgICAgICAgdXNsZWVwX3JhbmdlKDMw MDAsIDQwMDApOwo+ICsgICAgICAgfQo+ICsKPiArICAgICAgIHJldHVybiAwOwo+ICt9Cj4gKwo+ ICsvKioKPiArICogY2RuczNfZHJkX3N3aXRjaF9nYWRnZXQgLSBzdGFydC9zdG9wIGdhZGdldAo+ ICsgKiBAY2RuczogUG9pbnRlciB0byBjb250cm9sbGVyIGNvbnRleHQgc3RydWN0dXJlCj4gKyAq IEBvbjogMSBmb3Igc3RhcnQsIDAgZm9yIHN0b3AKPiArICoKPiArICogUmV0dXJucyAwIG9uIHN1 Y2Nlc3Mgb3RoZXJ3aXNlIG5lZ2F0aXZlIGVycm5vCj4gKyAqLwo+ICtzdGF0aWMgaW50IGNkbnMz X2RyZF9zd2l0Y2hfZ2FkZ2V0KHN0cnVjdCBjZG5zMyAqY2RucywgaW50IG9uKQo+ICt7Cj4gKyAg ICAgICBpbnQgcmV0Owo+ICsgICAgICAgdTMyIHJlZyA9IE9UR0NNRF9PVEdfRElTOwo+ICsKPiAr ICAgICAgIC8qIHN3aXRjaCBPVEcgY29yZSAqLwo+ICsgICAgICAgaWYgKG9uKSB7Cj4gKyAgICAg ICAgICAgICAgIHdyaXRlbChPVEdDTURfREVWX0JVU19SRVEgfCByZWcsICZjZG5zLT5vdGdfcmVn cy0+Y21kKTsKPiArCj4gKyAgICAgICAgICAgICAgIGRldl9kYmcoY2Rucy0+ZGV2LCAiV2FpdGlu ZyBmb3IgRGV2aWNlIG1vZGUgaXMgdHVybmVkIG9uXG4iKTsKPiArCj4gKyAgICAgICAgICAgICAg IHJldCA9IGNkbnMzX2hhbmRzaGFrZSgmY2Rucy0+b3RnX3JlZ3MtPnN0cywgT1RHU1RTX0RFVl9S RUFEWSwKPiArICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE9UR1NUU19ERVZf UkVBRFksIDEwMDAwMCk7Cj4gKwo+ICsgICAgICAgICAgICAgICBpZiAocmV0KQo+ICsgICAgICAg ICAgICAgICAgICAgICAgIHJldHVybiByZXQ7Cj4gKyAgICAgICB9IGVsc2Ugewo+ICsgICAgICAg ICAgICAgICAvKgo+ICsgICAgICAgICAgICAgICAgKiBkcml2ZXIgc2hvdWxkIHdhaXQgYXQgbGVh c3QgMTB1cyBhZnRlciBkaXNhYmxpbmcgRGV2aWNlCj4gKyAgICAgICAgICAgICAgICAqIGJlZm9y ZSB0dXJuaW5nLW9mZiBEZXZpY2UgKERFVl9CVVNfRFJPUCkKPiArICAgICAgICAgICAgICAgICov Cj4gKyAgICAgICAgICAgICAgIHVzbGVlcF9yYW5nZSgyMCwgMzApOwo+ICsgICAgICAgICAgICAg ICB3cml0ZWwoT1RHQ01EX0hPU1RfQlVTX0RST1AgfCBPVEdDTURfREVWX0JVU19EUk9QIHwKPiAr ICAgICAgICAgICAgICAgICAgICAgIE9UR0NNRF9ERVZfUE9XRVJfT0ZGIHwgT1RHQ01EX0hPU1Rf UE9XRVJfT0ZGLAo+ICsgICAgICAgICAgICAgICAgICAgICAgJmNkbnMtPm90Z19yZWdzLT5jbWQp Owo+ICsgICAgICAgICAgICAgICB1c2xlZXBfcmFuZ2UoMzAwMCwgNDAwMCk7Cj4gKyAgICAgICB9 Cj4gKwo+ICsgICAgICAgcmV0dXJuIDA7Cj4gK30KPiArCj4gKy8qKgo+ICsgKiBjZG5zM19pbml0 X290Z19tb2RlIC0gaW5pdGlhbGl6ZSBkcmQgY29udHJvbGxlcgo+ICsgKiBAY2RuczogUG9pbnRl ciB0byBjb250cm9sbGVyIGNvbnRleHQgc3RydWN0dXJlCj4gKyAqCj4gKyAqIFJldHVybnMgMCBv biBzdWNjZXNzIG90aGVyd2lzZSBuZWdhdGl2ZSBlcnJubwo+ICsgKi8KPiArc3RhdGljIGludCBj ZG5zM19pbml0X290Z19tb2RlKHN0cnVjdCBjZG5zMyAqY2RucykKPiArewo+ICsgICAgICAgaW50 IHJldCA9IDA7Cj4gKwo+ICsgICAgICAgY2RuczNfb3RnX2Rpc2FibGVfaXJxKGNkbnMpOwo+ICsg ICAgICAgLyogY2xlYXIgYWxsIGludGVycnVwdHMgKi8KPiArICAgICAgIHdyaXRlbCh+MCwgJmNk bnMtPm90Z19yZWdzLT5pdmVjdCk7Cj4gKwo+ICsgICAgICAgcmV0ID0gY2RuczNfc2V0X21vZGUo Y2RucywgVVNCX0RSX01PREVfT1RHKTsKPiArICAgICAgIGlmIChyZXQpCj4gKyAgICAgICAgICAg ICAgIHJldHVybiByZXQ7Cj4gKwo+ICsgICAgICAgaWYgKGNkbnMzX2lzX2hvc3QoY2RucykpCj4g KyAgICAgICAgICAgICAgIHJldCA9IGNkbnMzX2RyZF9zd2l0Y2hfaG9zdChjZG5zLCAxKTsKPiAr ICAgICAgIGVsc2UKPiArICAgICAgICAgICAgICAgcmV0ID0gY2RuczNfZHJkX3N3aXRjaF9nYWRn ZXQoY2RucywgMSk7Cj4gKwo+ICsgICAgICAgaWYgKHJldCkKPiArICAgICAgICAgICAgICAgcmV0 dXJuIHJldDsKPiArCj4gKyAgICAgICBjZG5zM19vdGdfZW5hYmxlX2lycShjZG5zKTsKPiArICAg ICAgIHJldHVybiByZXQ7Cj4gK30KPiArCj4gKy8qKgo+ICsgKiBjZG5zM19kcmRfdXBkYXRlX21v ZGUgLSBpbml0aWFsaXplIG1vZGUgb2Ygb3BlcmF0aW9uCj4gKyAqIEBjZG5zOiBQb2ludGVyIHRv IGNvbnRyb2xsZXIgY29udGV4dCBzdHJ1Y3R1cmUKPiArICoKPiArICogUmV0dXJucyAwIG9uIHN1 Y2Nlc3Mgb3RoZXJ3aXNlIG5lZ2F0aXZlIGVycm5vCj4gKyAqLwo+ICtpbnQgY2RuczNfZHJkX3Vw ZGF0ZV9tb2RlKHN0cnVjdCBjZG5zMyAqY2RucykKPiArewo+ICsgICAgICAgaW50IHJldCA9IDA7 Cj4gKwo+ICsgICAgICAgaWYgKGNkbnMtPmRlc2lyZWRfZHJfbW9kZSA9PSBjZG5zLT5jdXJyZW50 X2RyX21vZGUpCj4gKyAgICAgICAgICAgICAgIHJldHVybiByZXQ7Cj4gKwo+ICsgICAgICAgY2Ru czNfZHJkX3N3aXRjaF9nYWRnZXQoY2RucywgMCk7Cj4gKyAgICAgICBjZG5zM19kcmRfc3dpdGNo X2hvc3QoY2RucywgMCk7Cj4gKwo+ICsgICAgICAgc3dpdGNoIChjZG5zLT5kZXNpcmVkX2RyX21v ZGUpIHsKPiArICAgICAgIGNhc2UgVVNCX0RSX01PREVfUEVSSVBIRVJBTDoKPiArICAgICAgICAg ICAgICAgcmV0ID0gY2RuczNfc2V0X21vZGUoY2RucywgVVNCX0RSX01PREVfUEVSSVBIRVJBTCk7 Cj4gKyAgICAgICAgICAgICAgIGJyZWFrOwo+ICsgICAgICAgY2FzZSBVU0JfRFJfTU9ERV9IT1NU Ogo+ICsgICAgICAgICAgICAgICByZXQgPSBjZG5zM19zZXRfbW9kZShjZG5zLCBVU0JfRFJfTU9E RV9IT1NUKTsKPiArICAgICAgICAgICAgICAgYnJlYWs7Cj4gKyAgICAgICBjYXNlIFVTQl9EUl9N T0RFX09URzoKPiArICAgICAgICAgICAgICAgcmV0ID0gY2RuczNfaW5pdF9vdGdfbW9kZShjZG5z KTsKPiArICAgICAgICAgICAgICAgYnJlYWs7Cj4gKyAgICAgICBkZWZhdWx0Ogo+ICsgICAgICAg ICAgICAgICBkZXZfZXJyKGNkbnMtPmRldiwgIlVuc3VwcG9ydGVkIG1vZGUgb2Ygb3BlcmF0aW9u ICVkXG4iLAo+ICsgICAgICAgICAgICAgICAgICAgICAgIGNkbnMtPmRyX21vZGUpOwo+ICsgICAg ICAgICAgICAgICByZXR1cm4gLUVJTlZBTDsKPiArICAgICAgIH0KPiArCj4gKyAgICAgICByZXR1 cm4gcmV0Owo+ICt9Cj4gKwo+ICsvKioKPiArICogY2RuczNfZHJkX2lycSAtIGludGVycnVwdCBo YW5kbGVyIGZvciBPVEcgZXZlbnRzCj4gKyAqCj4gKyAqIEBpcnE6IGlycSBudW1iZXIgZm9yIGNk bnMzIGNvcmUgZGV2aWNlCj4gKyAqIEBkYXRhOiBzdHJ1Y3R1cmUgb2YgY2RuczMKPiArICoKPiAr ICogUmV0dXJucyBJUlFfSEFORExFRCBvciBJUlFfTk9ORQo+ICsgKi8KPiArc3RhdGljIGlycXJl dHVybl90IGNkbnMzX2RyZF9pcnEoaW50IGlycSwgdm9pZCAqZGF0YSkKPiArewo+ICsgICAgICAg aXJxcmV0dXJuX3QgcmV0ID0gSVJRX05PTkU7Cj4gKyAgICAgICBzdHJ1Y3QgY2RuczMgKmNkbnMg PSBkYXRhOwo+ICsgICAgICAgdTMyIHJlZzsKPiArCj4gKyAgICAgICBpZiAoY2Rucy0+ZHJfbW9k ZSAhPSBVU0JfRFJfTU9ERV9PVEcpCj4gKyAgICAgICAgICAgICAgIHJldHVybiByZXQ7Cj4gKwo+ ICsgICAgICAgcmVnID0gcmVhZGwoJmNkbnMtPm90Z19yZWdzLT5pdmVjdCk7Cj4gKwo+ICsgICAg ICAgaWYgKCFyZWcpCj4gKyAgICAgICAgICAgICAgIHJldHVybiByZXQ7Cj4gKwo+ICsgICAgICAg aWYgKHJlZyAmIE9UR0lFTl9JRF9DSEFOR0VfSU5UKSB7Cj4gKyAgICAgICAgICAgICAgIGRldl9k YmcoY2Rucy0+ZGV2LCAiT1RHIElSUTogbmV3IElEOiAlZFxuIiwKPiArICAgICAgICAgICAgICAg ICAgICAgICBjZG5zM19nZXRfaWQoY2RucykpOwo+ICsKPiArICAgICAgICAgICAgICAgcXVldWVf d29yayhzeXN0ZW1fZnJlZXphYmxlX3dxLCAmY2Rucy0+cm9sZV9zd2l0Y2hfd3EpOwo+ICsKPiAr ICAgICAgICAgICAgICAgcmV0ID0gSVJRX0hBTkRMRUQ7Cj4gKyAgICAgICB9Cj4gKwo+ICsgICAg ICAgd3JpdGVsKH4wLCAmY2Rucy0+b3RnX3JlZ3MtPml2ZWN0KTsKPiArICAgICAgIHJldHVybiBy ZXQ7Cj4gK30KPiArCj4gK2ludCBjZG5zM19kcmRfaW5pdChzdHJ1Y3QgY2RuczMgKmNkbnMpCj4g K3sKPiArICAgICAgIHZvaWQgX19pb21lbSAqcmVnczsKPiArICAgICAgIGludCByZXQgPSAwOwo+ ICsgICAgICAgdTMyIHN0YXRlOwo+ICsKPiArICAgICAgIHJlZ3MgPSBkZXZtX2lvcmVtYXBfcmVz b3VyY2UoY2Rucy0+ZGV2LCAmY2Rucy0+b3RnX3Jlcyk7Cj4gKyAgICAgICBpZiAoSVNfRVJSKHJl Z3MpKQo+ICsgICAgICAgICAgICAgICByZXR1cm4gUFRSX0VSUihyZWdzKTsKPiArCj4gKyAgICAg ICAvKiBEZXRlY3Rpb24gb2YgRFJEIHZlcnNpb24uIENvbnRyb2xsZXIgaGFzIGJlZW4gcmVsZWFz ZWQKPiArICAgICAgICAqIGluIHR3byB2ZXJzaW9ucy4gQm90aCBhcmUgc2ltaWxhciwgYnV0IHRo ZXkgaGF2ZSBzYW1lIGNoYW5nZXMKPiArICAgICAgICAqIGluIHJlZ2lzdGVyIG1hcHMuCj4gKyAg ICAgICAgKiBUaGUgZmlyc3QgcmVnaXN0ZXIgaW4gb2xkIHZlcnNpb24gaXMgY29tbWFuZCByZWdp c3RlciBhbmQgaXQncyByZWFkCj4gKyAgICAgICAgKiBvbmx5LCBzbyBkcml2ZXIgc2hvdWxkIHJl YWQgMCBmcm9tIGl0LiBPbiB0aGUgb3RoZXIgaGFuZCwgaW4gdjEKPiArICAgICAgICAqIHRoZSBm aXJzdCByZWdpc3RlciBjb250YWlucyBkZXZpY2UgSUQgbnVtYmVyIHdoaWNoIGlzIG5vdCBzZXQg dG8gMC4KPiArICAgICAgICAqIERyaXZlciB1c2VzIHRoaXMgZmFjdCB0byBkZXRlY3QgdGhlIHBy b3BlciB2ZXJzaW9uIG9mCj4gKyAgICAgICAgKiBjb250cm9sbGVyLgo+ICsgICAgICAgICovCj4g KyAgICAgICBjZG5zLT5vdGdfdjBfcmVncyA9IHJlZ3M7Cj4gKyAgICAgICBpZiAoIXJlYWRsKCZj ZG5zLT5vdGdfdjBfcmVncy0+Y21kKSkgewo+ICsgICAgICAgICAgICAgICBjZG5zLT52ZXJzaW9u ICA9IENETlMzX0NPTlRST0xMRVJfVjA7Cj4gKyAgICAgICAgICAgICAgIGNkbnMtPm90Z192MV9y ZWdzID0gTlVMTDsKPiArICAgICAgICAgICAgICAgY2Rucy0+b3RnX3JlZ3MgPSByZWdzOwo+ICsg ICAgICAgICAgICAgICBkZXZfaW5mbyhjZG5zLT5kZXYsICJEUkQgdmVyc2lvbiB2MCAoJTA4eClc biIsCj4gKyAgICAgICAgICAgICAgICAgICAgICAgIHJlYWRsKCZjZG5zLT5vdGdfdjBfcmVncy0+ dmVyc2lvbikpOwo+ICsgICAgICAgfSBlbHNlIHsKPiArICAgICAgICAgICAgICAgY2Rucy0+b3Rn X3YwX3JlZ3MgPSBOVUxMOwo+ICsgICAgICAgICAgICAgICBjZG5zLT5vdGdfdjFfcmVncyA9IHJl Z3M7Cj4gKyAgICAgICAgICAgICAgIGNkbnMtPm90Z19yZWdzID0gKHZvaWQgKikmY2Rucy0+b3Rn X3YxX3JlZ3MtPmNtZDsKPiArICAgICAgICAgICAgICAgY2Rucy0+dmVyc2lvbiAgPSBDRE5TM19D T05UUk9MTEVSX1YxOwo+ICsgICAgICAgICAgICAgICBkZXZfaW5mbyhjZG5zLT5kZXYsICJEUkQg dmVyc2lvbiB2MSAoSUQ6ICUwOHgsIHJldjogJTA4eClcbiIsCj4gKyAgICAgICAgICAgICAgICAg ICAgICAgIHJlYWRsKCZjZG5zLT5vdGdfdjFfcmVncy0+ZGlkKSwKPiArICAgICAgICAgICAgICAg ICAgICAgICAgcmVhZGwoJmNkbnMtPm90Z192MV9yZWdzLT5yaWQpKTsKPiArICAgICAgIH0KPiAr Cj4gKyAgICAgICBzdGF0ZSA9IE9UR1NUU19TVFJBUChyZWFkbCgmY2Rucy0+b3RnX3JlZ3MtPnN0 cykpOwo+ICsKPiArICAgICAgIC8qIFVwZGF0ZSBkcl9tb2RlIGFjY29yZGluZyB0byBTVFJBUCBj b25maWd1cmF0aW9uLiAqLwo+ICsgICAgICAgY2Rucy0+ZHJfbW9kZSA9IFVTQl9EUl9NT0RFX09U RzsKPiArICAgICAgIGlmIChzdGF0ZSA9PSBPVEdTVFNfU1RSQVBfSE9TVCkgewo+ICsgICAgICAg ICAgICAgICBkZXZfaW5mbyhjZG5zLT5kZXYsICJDb250cm9sbGVyIHN0cmFwcGVkIHRvIEhPU1Rc biIpOwo+ICsgICAgICAgICAgICAgICBjZG5zLT5kcl9tb2RlID0gVVNCX0RSX01PREVfSE9TVDsK PiArICAgICAgIH0gZWxzZSBpZiAoc3RhdGUgPT0gT1RHU1RTX1NUUkFQX0dBREdFVCkgewo+ICsg ICAgICAgICAgICAgICBkZXZfaW5mbyhjZG5zLT5kZXYsICJDb250cm9sbGVyIHN0cmFwcGVkIHRv IFBFUklQSEVSQUxcbiIpOwo+ICsgICAgICAgICAgICAgICBjZG5zLT5kcl9tb2RlID0gVVNCX0RS X01PREVfUEVSSVBIRVJBTDsKPiArICAgICAgIH0KPiArCj4gKyAgICAgICBjZG5zLT5kZXNpcmVk X2RyX21vZGUgPSBjZG5zLT5kcl9tb2RlOwo+ICsgICAgICAgY2Rucy0+Y3VycmVudF9kcl9tb2Rl ID0gVVNCX0RSX01PREVfVU5LTk9XTjsKPiArCj4gKyAgICAgICByZXQgPSBkZXZtX3JlcXVlc3Rf dGhyZWFkZWRfaXJxKGNkbnMtPmRldiwgY2Rucy0+aXJxLCBjZG5zM19kcmRfaXJxLAo+ICsgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOVUxMLCBJUlFGX1NIQVJFRCwKPiAr ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGV2X25hbWUoY2Rucy0+ZGV2 KSwgY2Rucyk7Cj4gKwo+ICsgICAgICAgaWYgKHJldCkKPiArICAgICAgICAgICAgICAgcmV0dXJu IHJldDsKPiArCj4gKyAgICAgICBzdGF0ZSA9IHJlYWRsKCZjZG5zLT5vdGdfcmVncy0+c3RzKTsK PiArICAgICAgIGlmIChPVEdTVFNfT1RHX05SRFkoc3RhdGUpICE9IDApIHsKPiArICAgICAgICAg ICAgICAgZGV2X2VycihjZG5zLT5kZXYsICJDYWRlbmNlIFVTQjMgT1RHIGRldmljZSBub3QgcmVh ZHlcbiIpOwo+ICsgICAgICAgICAgICAgICByZXR1cm4gLUVOT0RFVjsKPiArICAgICAgIH0KPiAr Cj4gKyAgICAgICByZXQgPSBjZG5zM19kcmRfdXBkYXRlX21vZGUoY2Rucyk7Cj4gKwo+ICsgICAg ICAgcmV0dXJuIHJldDsKPiArfQo+ICsKPiAraW50IGNkbnMzX2RyZF9leGl0KHN0cnVjdCBjZG5z MyAqY2RucykKPiArewo+ICsgICAgICAgcmV0dXJuIGNkbnMzX2RyZF9zd2l0Y2hfaG9zdChjZG5z LCAwKTsKPiArfQo+IGRpZmYgLS1naXQgYS9kcml2ZXJzL3VzYi9jZG5zMy9kcmQuaCBiL2RyaXZl cnMvdXNiL2NkbnMzL2RyZC5oCj4gbmV3IGZpbGUgbW9kZSAxMDA2NDQKPiBpbmRleCAwMDAwMDAw MDAwMDAuLjZhMjljZGNiNDkyZAo+IC0tLSAvZGV2L251bGwKPiArKysgYi9kcml2ZXJzL3VzYi9j ZG5zMy9kcmQuaAo+IEBAIC0wLDAgKzEsMTYyIEBACj4gKy8qIFNQRFgtTGljZW5zZS1JZGVudGlm aWVyOiBHUEwtMi4wICovCj4gKy8qCj4gKyAqIENhZGVuY2UgVVNCMyBEUkQgaGVhZGVyIGZpbGUu Cj4gKyAqCj4gKyAqIENvcHlyaWdodCAoQykgMjAxOCBDYWRlbmNlLgo+ICsgKgo+ICsgKiBBdXRo b3I6IFBhd2VsIExhc3pjemFrIDxwYXdlbGxAY2FkZW5jZS5jb20+Cj4gKyAqLwo+ICsjaWZuZGVm IF9fTElOVVhfQ0ROUzNfRFJECj4gKyNkZWZpbmUgX19MSU5VWF9DRE5TM19EUkQKPiArCj4gKyNp bmNsdWRlIDxsaW51eC91c2Ivb3RnLmg+Cj4gKyNpbmNsdWRlIDxsaW51eC9waHkvcGh5Lmg+Cj4g KyNpbmNsdWRlICJjb3JlLmgiCj4gKwo+ICsvKiAgRFJEIHJlZ2lzdGVyIGludGVyZmFjZSBmb3Ig dmVyc2lvbiB2MS4gKi8KPiArc3RydWN0IGNkbnMzX290Z19yZWdzIHsKPiArICAgICAgIF9fbGUz MiBkaWQ7Cj4gKyAgICAgICBfX2xlMzIgcmlkOwo+ICsgICAgICAgX19sZTMyIGNhcGFiaWxpdGll czsKPiArICAgICAgIF9fbGUzMiByZXNlcnZlZDE7Cj4gKyAgICAgICBfX2xlMzIgY21kOwo+ICsg ICAgICAgX19sZTMyIHN0czsKPiArICAgICAgIF9fbGUzMiBzdGF0ZTsKPiArICAgICAgIF9fbGUz MiByZXNlcnZlZDI7Cj4gKyAgICAgICBfX2xlMzIgaWVuOwo+ICsgICAgICAgX19sZTMyIGl2ZWN0 Owo+ICsgICAgICAgX19sZTMyIHJlZmNsazsKPiArICAgICAgIF9fbGUzMiB0bXI7Cj4gKyAgICAg ICBfX2xlMzIgcmVzZXJ2ZWQzWzRdOwo+ICsgICAgICAgX19sZTMyIHNpbXVsYXRlOwo+ICsgICAg ICAgX19sZTMyIG92ZXJyaWRlOwo+ICsgICAgICAgX19sZTMyIHN1c3BfY3RybDsKPiArICAgICAg IF9fbGUzMiByZXNlcnZlZDQ7Cj4gKyAgICAgICBfX2xlMzIgYW5hc3RzOwo+ICsgICAgICAgX19s ZTMyIGFkcF9yYW1wX3RpbWU7Cj4gKyAgICAgICBfX2xlMzIgY3RybDE7Cj4gKyAgICAgICBfX2xl MzIgY3RybDI7Cj4gK307Cj4gKwo+ICsvKiAgRFJEIHJlZ2lzdGVyIGludGVyZmFjZSBmb3IgdmVy c2lvbiB2MC4gKi8KPiArc3RydWN0IGNkbnMzX290Z19sZWdhY3lfcmVncyB7Cj4gKyAgICAgICBf X2xlMzIgY21kOwo+ICsgICAgICAgX19sZTMyIHN0czsKPiArICAgICAgIF9fbGUzMiBzdGF0ZTsK PiArICAgICAgIF9fbGUzMiByZWZjbGs7Cj4gKyAgICAgICBfX2xlMzIgaWVuOwo+ICsgICAgICAg X19sZTMyIGl2ZWN0Owo+ICsgICAgICAgX19sZTMyIHJlc2VydmVkMVszXTsKPiArICAgICAgIF9f bGUzMiB0bXI7Cj4gKyAgICAgICBfX2xlMzIgcmVzZXJ2ZWQyWzJdOwo+ICsgICAgICAgX19sZTMy IHZlcnNpb247Cj4gKyAgICAgICBfX2xlMzIgY2FwYWJpbGl0aWVzOwo+ICsgICAgICAgX19sZTMy IHJlc2VydmVkM1syXTsKPiArICAgICAgIF9fbGUzMiBzaW11bGF0ZTsKPiArICAgICAgIF9fbGUz MiByZXNlcnZlZDRbNV07Cj4gKyAgICAgICBfX2xlMzIgY3RybDE7Cj4gK307Cj4gKwo+ICsvKgo+ ICsgKiBDb21tb24gcmVnaXN0ZXJzIGludGVyZmFjZSBmb3IgYm90aCB2ZXJzaW9uIG9mIERSRC4K PiArICovCj4gK3N0cnVjdCBjZG5zM19vdGdfY29tbW9uX3JlZ3Mgewo+ICsgICAgICAgX19sZTMy IGNtZDsKPiArICAgICAgIF9fbGUzMiBzdHM7Cj4gKyAgICAgICBfX2xlMzIgc3RhdGU7Cj4gKyAg ICAgICBfX2xlMzIgZGlmZmVyZW50MTsKPiArICAgICAgIF9fbGUzMiBpZW47Cj4gKyAgICAgICBf X2xlMzIgaXZlY3Q7Cj4gK307Cj4gKwo+ICsvKiBDRE5TX1JJRCAtIGJpdG1hc2tzICovCj4gKyNk ZWZpbmUgQ0ROU19SSUQocCkgICAgICAgICAgICAgICAgICAgICgocCkgJiBHRU5NQVNLKDE1LCAw KSkKPiArCj4gKy8qIENETlNfVklEIC0gYml0bWFza3MgKi8KPiArI2RlZmluZSBDRE5TX0RJRChw KSAgICAgICAgICAgICAgICAgICAgKChwKSAmIEdFTk1BU0soMzEsIDApKQo+ICsKPiArLyogT1RH Q01EIC0gYml0bWFza3MgKi8KPiArLyogIlJlcXVlc3QgdGhlIGJ1cyBmb3IgRGV2aWNlIG1vZGUu ICovCj4gKyNkZWZpbmUgT1RHQ01EX0RFVl9CVVNfUkVRICAgICAgICAgICAgIEJJVCgwKQo+ICsv KiBSZXF1ZXN0IHRoZSBidXMgZm9yIEhvc3QgbW9kZSAqLwo+ICsjZGVmaW5lIE9UR0NNRF9IT1NU X0JVU19SRVEgICAgICAgICAgICBCSVQoMSkKPiArLyogRW5hYmxlIE9URyBtb2RlLiAqLwo+ICsj ZGVmaW5lIE9UR0NNRF9PVEdfRU4gICAgICAgICAgICAgICAgICBCSVQoMikKPiArLyogRGlzYWJs ZSBPVEcgbW9kZSAqLwo+ICsjZGVmaW5lIE9UR0NNRF9PVEdfRElTICAgICAgICAgICAgICAgICBC SVQoMykKPiArLyoiQ29uZmlndXJlIE9URyBhcyBBLURldmljZS4gKi8KPiArI2RlZmluZSBPVEdD TURfQV9ERVZfRU4gICAgICAgICAgICAgICAgICAgICAgICBCSVQoNCkKPiArLyoiQ29uZmlndXJl IE9URyBhcyBBLURldmljZS4gKi8KPiArI2RlZmluZSBPVEdDTURfQV9ERVZfRElTICAgICAgICAg ICAgICAgQklUKDUpCj4gKy8qIERyb3AgdGhlIGJ1cyBmb3IgRGV2aWNlIG1vZCBlLiAqLwo+ICsj ZGVmaW5lIE9UR0NNRF9ERVZfQlVTX0RST1AgICAgICAgICAgICBCSVQoOCkKPiArLyogRHJvcCB0 aGUgYnVzIGZvciBIb3N0IG1vZGUqLwo+ICsjZGVmaW5lIE9UR0NNRF9IT1NUX0JVU19EUk9QICAg ICAgICAgICBCSVQoOSkKPiArLyogUG93ZXIgRG93biBVU0JTUy1ERVYuICovCj4gKyNkZWZpbmUg T1RHQ01EX0RFVl9QT1dFUl9PRkYgICAgICAgICAgIEJJVCgxMSkKPiArLyogUG93ZXIgRG93biBD RE5TWEhDSS4gKi8KPiArI2RlZmluZSBPVEdDTURfSE9TVF9QT1dFUl9PRkYgICAgICAgICAgQklU KDEyKQo+ICsKPiArLyogT1RHSUVOIC0gYml0bWFza3MgKi8KPiArLyogSUQgY2hhbmdlIGludGVy cnVwdCBlbmFibGUgKi8KPiArI2RlZmluZSBPVEdJRU5fSURfQ0hBTkdFX0lOVCAgICAgICAgICAg QklUKDApCj4gKy8qIFZidXN2YWxpZCBmYWxsIGRldGVjdGVkIGludGVycnVwdCBlbmFibGUuKi8K PiArI2RlZmluZSBPVEdJRU5fVkJVU1ZBTElEX1JJU0VfSU5UICAgICAgQklUKDQpCj4gKy8qIFZi dXN2YWxpZCBmYWxsIGRldGVjdGVkIGludGVycnVwdCBlbmFibGUgKi8KPiArI2RlZmluZSBPVEdJ RU5fVkJVU1ZBTElEX0ZBTExfSU5UICAgICAgQklUKDUpCj4gKwo+ICsvKiBPVEdTVFMgLSBiaXRt YXNrcyAqLwo+ICsvKgo+ICsgKiBDdXJyZW50IHZhbHVlIG9mIHRoZSBJRCBwaW4uIEl0IGlzIG9u bHkgdmFsaWQgd2hlbiBpZHB1bGx1cCBpbgo+ICsgKiAgT1RHQ1RSTDFfVFlQRSByZWdpc3RlciBp cyBzZXQgdG8gJzEnLgo+ICsgKi8KPiArI2RlZmluZSBPVEdTVFNfSURfVkFMVUUgICAgICAgICAg ICAgICAgICAgICAgICBCSVQoMCkKPiArLyogQ3VycmVudCB2YWx1ZSBvZiB0aGUgdmJ1c192YWxp ZCAqLwo+ICsjZGVmaW5lIE9UR1NUU19WQlVTX1ZBTElEICAgICAgICAgICAgICBCSVQoMSkKPiAr LyogQ3VycmVudCB2YWx1ZSBvZiB0aGUgYl9zZXNzX3ZsZCAqLwo+ICsjZGVmaW5lIE9UR1NUU19T RVNTSU9OX1ZBTElEICAgICAgICAgICBCSVQoMikKPiArLypEZXZpY2UgbW9kZSBpcyBhY3RpdmUq Lwo+ICsjZGVmaW5lIE9UR1NUU19ERVZfQUNUSVZFICAgICAgICAgICAgICBCSVQoMykKPiArLyog SG9zdCBtb2RlIGlzIGFjdGl2ZS4gKi8KPiArI2RlZmluZSBPVEdTVFNfSE9TVF9BQ1RJVkUgICAg ICAgICAgICAgQklUKDQpCj4gKy8qIE9URyBDb250cm9sbGVyIG5vdCByZWFkeS4gKi8KPiArI2Rl ZmluZSBPVEdTVFNfT1RHX05SRFlfTUFTSyAgICAgICAgICAgQklUKDExKQo+ICsjZGVmaW5lIE9U R1NUU19PVEdfTlJEWShwKSAgICAgICAgICAgICAoKHApICYgT1RHU1RTX09UR19OUkRZX01BU0sp Cj4gKy8qCj4gKyAqIFZhbHVlIG9mIHRoZSBzdHJhcCBwaW5zLgo+ICsgKiAwMDAgLSBubyBkZWZh dWx0IGNvbmZpZ3VyYXRpb24KPiArICogMDEwIC0gQ29udHJvbGxlciBpbml0aWFsbCBjb25maWd1 cmVkIGFzIEhvc3QKPiArICogMTAwIC0gQ29udHJvbGxlciBpbml0aWFsbHkgY29uZmlndXJlZCBh cyBEZXZpY2UKPiArICovCj4gKyNkZWZpbmUgT1RHU1RTX1NUUkFQKHApICAgICAgICAgICAgICAg ICAgICAgICAgKCgocCkgJiBHRU5NQVNLKDE0LCAxMikpID4+IDEyKQo+ICsjZGVmaW5lIE9UR1NU U19TVFJBUF9OT19ERUZBVUxUX0NGRyAgICAweDAwCj4gKyNkZWZpbmUgT1RHU1RTX1NUUkFQX0hP U1RfT1RHICAgICAgICAgIDB4MDEKPiArI2RlZmluZSBPVEdTVFNfU1RSQVBfSE9TVCAgICAgICAg ICAgICAgMHgwMgo+ICsjZGVmaW5lIE9UR1NUU19TVFJBUF9HQURHRVQgICAgICAgICAgICAweDA0 Cj4gKy8qIEhvc3QgbW9kZSBpcyB0dXJuZWQgb24uICovCj4gKyNkZWZpbmUgT1RHU1RTX1hIQ0lf UkVBRFkgICAgICAgICAgICAgIEJJVCgyNikKPiArLyogIkRldmljZSBtb2RlIGlzIHR1cm5lZCBv biAuKi8KPiArI2RlZmluZSBPVEdTVFNfREVWX1JFQURZICAgICAgICAgICAgICAgQklUKDI3KQo+ ICsKPiArLyogT1RHU1RBVEUtIGJpdG1hc2tzICovCj4gKyNkZWZpbmUgT1RHU1RBVEVfSE9TVF9T VEFURV9NQVNLICAgICAgIEdFTk1BU0soNSwgMykKPiArI2RlZmluZSBPVEdTVEFURV9IT1NUX1NU QVRFX0lETEUgICAgICAgMHgwCj4gKyNkZWZpbmUgT1RHU1RBVEVfSE9TVF9TVEFURV9WQlVTX0ZB TEwgICAweDcKPiArI2RlZmluZSBPVEdTVEFURV9IT1NUX1NUQVRFKHApICAgICAgICAgKCgocCkg JiBPVEdTVEFURV9IT1NUX1NUQVRFX01BU0spID4+IDMpCj4gKwo+ICsvKiBPVEdSRUZDTEsgLSBi aXRtYXNrcyAqLwo+ICsjZGVmaW5lIE9UR1JFRkNMS19TVEJfQ0xLX1NXSVRDSF9FTiAgICBCSVQo MzEpCj4gKwo+ICsvKiBPVkVSUklERSAtIGJpdG1hc2tzICovCj4gKyNkZWZpbmUgT1ZFUlJJREVf SURQVUxMVVAgICAgICAgICAgICAgIEJJVCgwKQo+ICsvKiBPbmx5IGZvciBDRE5TM19DT05UUk9M TEVSX1YwIHZlcnNpb24gKi8KPiArI2RlZmluZSBPVkVSUklERV9JRFBVTExVUF9WMCAgICAgICAg ICAgQklUKDI0KQo+ICsKPiAraW50IGNkbnMzX2lzX2hvc3Qoc3RydWN0IGNkbnMzICpjZG5zKTsK PiAraW50IGNkbnMzX2lzX2RldmljZShzdHJ1Y3QgY2RuczMgKmNkbnMpOwo+ICtpbnQgY2RuczNf Z2V0X2lkKHN0cnVjdCBjZG5zMyAqY2Rucyk7Cj4gK2ludCBjZG5zM19kcmRfaW5pdChzdHJ1Y3Qg Y2RuczMgKmNkbnMpOwo+ICtpbnQgY2RuczNfZHJkX2V4aXQoc3RydWN0IGNkbnMzICpjZG5zKTsK PiAraW50IGNkbnMzX2RyZF91cGRhdGVfbW9kZShzdHJ1Y3QgY2RuczMgKmNkbnMpOwo+ICsKPiAr I2VuZGlmIC8qIF9fTElOVVhfQ0ROUzNfRFJEICovCj4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvdXNi L2NkbnMzL2VwMC5jIGIvZHJpdmVycy91c2IvY2RuczMvZXAwLmMKPiBuZXcgZmlsZSBtb2RlIDEw MDY0NAo+IGluZGV4IDAwMDAwMDAwMDAwMC4uMjg3ODk4MmJlMWVjCj4gLS0tIC9kZXYvbnVsbAo+ ICsrKyBiL2RyaXZlcnMvdXNiL2NkbnMzL2VwMC5jCj4gQEAgLTAsMCArMSw5MDcgQEAKPiArLy8g U1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEdQTC0yLjAKPiArLyoKPiArICogQ2FkZW5jZSBVU0JT UyBEUkQgRHJpdmVyIC0gZ2FkZ2V0IHNpZGUuCj4gKyAqCj4gKyAqIENvcHlyaWdodCAoQykgMjAx OCBDYWRlbmNlIERlc2lnbiBTeXN0ZW1zLgo+ICsgKiBDb3B5cmlnaHQgKEMpIDIwMTctMjAxOCBO WFAKPiArICoKPiArICogQXV0aG9yczogUGF3ZWwgSmV6IDxwamV6QGNhZGVuY2UuY29tPiwKPiAr ICogICAgICAgICAgUGF3ZWwgTGFzemN6YWsgPHBhd2VsbEBjYWRlbmNlLmNvbT4KPiArICogICAg ICAgICBQZXRlciBDaGVuIDxwZXRlci5jaGVuQG54cC5jb20+Cj4gKyAqLwo+ICsKPiArI2luY2x1 ZGUgPGxpbnV4L3VzYi9jb21wb3NpdGUuaD4KPiArCj4gKyNpbmNsdWRlICJnYWRnZXQuaCIKPiAr I2luY2x1ZGUgInRyYWNlLmgiCj4gKwo+ICtzdGF0aWMgc3RydWN0IHVzYl9lbmRwb2ludF9kZXNj cmlwdG9yIGNkbnMzX2dhZGdldF9lcDBfZGVzYyA9IHsKPiArICAgICAgIC5iTGVuZ3RoID0gVVNC X0RUX0VORFBPSU5UX1NJWkUsCj4gKyAgICAgICAuYkRlc2NyaXB0b3JUeXBlID0gVVNCX0RUX0VO RFBPSU5ULAo+ICsgICAgICAgLmJtQXR0cmlidXRlcyA9IFVTQl9FTkRQT0lOVF9YRkVSX0NPTlRS T0wsCj4gK307Cj4gKwo+ICsvKioKPiArICogY2RuczNfZXAwX3J1bl90cmFuc2ZlciAtIERvIHRy YW5zZmVyIG9uIGRlZmF1bHQgZW5kcG9pbnQgaGFyZHdhcmUKPiArICogQHByaXZfZGV2OiBleHRl bmRlZCBnYWRnZXQgb2JqZWN0Cj4gKyAqIEBkbWFfYWRkcjogcGh5c2ljYWwgYWRkcmVzcyB3aGVy ZSBkYXRhIGlzL3dpbGwgYmUgc3RvcmVkCj4gKyAqIEBsZW5ndGg6IGRhdGEgbGVuZ3RoCj4gKyAq IEBlcmR5OiBzZXQgaXQgdG8gMSB3aGVuIEVSRFkgcGFja2V0IHNob3VsZCBiZSBzZW50IC0KPiAr ICogICAgICAgIGV4aXQgZnJvbSBmbG93IGNvbnRyb2wgc3RhdGUKPiArICovCj4gK3N0YXRpYyB2 b2lkIGNkbnMzX2VwMF9ydW5fdHJhbnNmZXIoc3RydWN0IGNkbnMzX2RldmljZSAqcHJpdl9kZXYs Cj4gKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkbWFfYWRkcl90IGRtYV9hZGRy LAo+ICsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgaW50IGxlbmd0 aCwgaW50IGVyZHkpCj4gK3sKPiArICAgICAgIHN0cnVjdCBjZG5zM191c2JfcmVncyBfX2lvbWVt ICpyZWdzID0gcHJpdl9kZXYtPnJlZ3M7Cj4gKyAgICAgICBzdHJ1Y3QgY2RuczNfZW5kcG9pbnQg KnByaXZfZXAgPSBwcml2X2Rldi0+ZXBzWzBdOwo+ICsKPiArICAgICAgIHByaXZfZXAtPnRyYl9w b29sLT5idWZmZXIgPSBUUkJfQlVGRkVSKGRtYV9hZGRyKTsKPiArICAgICAgIHByaXZfZXAtPnRy Yl9wb29sLT5sZW5ndGggPSBUUkJfTEVOKGxlbmd0aCk7Cj4gKyAgICAgICBwcml2X2VwLT50cmJf cG9vbC0+Y29udHJvbCA9IFRSQl9DWUNMRSB8IFRSQl9JT0MgfCBUUkJfVFlQRShUUkJfTk9STUFM KTsKPiArCj4gKyAgICAgICB0cmFjZV9jZG5zM19wcmVwYXJlX3RyYihwcml2X2VwLCBwcml2X2Vw LT50cmJfcG9vbCk7Cj4gKwo+ICsgICAgICAgY2RuczNfc2VsZWN0X2VwKHByaXZfZGV2LCBwcml2 X2Rldi0+ZXAwX2RhdGFfZGlyKTsKPiArCj4gKyAgICAgICB3cml0ZWwoRVBfU1RTX1RSQkVSUiwg JnJlZ3MtPmVwX3N0cyk7Cj4gKyAgICAgICB3cml0ZWwoRVBfVFJBRERSX1RSQUREUihwcml2X2Vw LT50cmJfcG9vbF9kbWEpLCAmcmVncy0+ZXBfdHJhZGRyKTsKPiArICAgICAgIHRyYWNlX2NkbnMz X2Rvb3JiZWxsX2VwMChwcml2X2Rldi0+ZXAwX2RhdGFfZGlyID8gImVwMGluIiA6ICJlcDBvdXQi LAo+ICsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlYWRsKCZyZWdzLT5lcF90cmFk ZHIpKTsKPiArCj4gKyAgICAgICAvKiBUUkIgc2hvdWxkIGJlIHByZXBhcmVkIGJlZm9yZSBzdGFy dGluZyB0cmFuc2ZlciAqLwo+ICsgICAgICAgd3JpdGVsKEVQX0NNRF9EUkRZLCAmcmVncy0+ZXBf Y21kKTsKPiArCj4gKyAgICAgICBpZiAoZXJkeSkKPiArICAgICAgICAgICAgICAgd3JpdGVsKEVQ X0NNRF9FUkRZLCAmcHJpdl9kZXYtPnJlZ3MtPmVwX2NtZCk7Cj4gK30KPiArCj4gKy8qKgo+ICsg KiBjZG5zM19lcDBfZGVsZWdhdGVfcmVxIC0gUmV0dXJucyBzdGF0dXMgb2YgaGFuZGxpbmcgc2V0 dXAgcGFja2V0Cj4gKyAqIFNldHVwIGlzIGhhbmRsZWQgYnkgZ2FkZ2V0IGRyaXZlcgo+ICsgKiBA cHJpdl9kZXY6IGV4dGVuZGVkIGdhZGdldCBvYmplY3QKPiArICogQGN0cmxfcmVxOiBwb2ludGVy IHRvIHJlY2VpdmVkIHNldHVwIHBhY2tldAo+ICsgKgo+ICsgKiBSZXR1cm5zIHplcm8gb24gc3Vj Y2VzcyBvciBuZWdhdGl2ZSB2YWx1ZSBvbiBmYWlsdXJlCj4gKyAqLwo+ICtzdGF0aWMgaW50IGNk bnMzX2VwMF9kZWxlZ2F0ZV9yZXEoc3RydWN0IGNkbnMzX2RldmljZSAqcHJpdl9kZXYsCj4gKyAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cnVjdCB1c2JfY3RybHJlcXVlc3QgKmN0 cmxfcmVxKQo+ICt7Cj4gKyAgICAgICBpbnQgcmV0Owo+ICsKPiArICAgICAgIHNwaW5fdW5sb2Nr KCZwcml2X2Rldi0+bG9jayk7Cj4gKyAgICAgICBwcml2X2Rldi0+c2V0dXBfcGVuZGluZyA9IDE7 Cj4gKyAgICAgICByZXQgPSBwcml2X2Rldi0+Z2FkZ2V0X2RyaXZlci0+c2V0dXAoJnByaXZfZGV2 LT5nYWRnZXQsIGN0cmxfcmVxKTsKPiArICAgICAgIHByaXZfZGV2LT5zZXR1cF9wZW5kaW5nID0g MDsKPiArICAgICAgIHNwaW5fbG9jaygmcHJpdl9kZXYtPmxvY2spOwo+ICsgICAgICAgcmV0dXJu IHJldDsKPiArfQo+ICsKPiArc3RhdGljIHZvaWQgY2RuczNfcHJlcGFyZV9zZXR1cF9wYWNrZXQo c3RydWN0IGNkbnMzX2RldmljZSAqcHJpdl9kZXYpCj4gK3sKPiArICAgICAgIHByaXZfZGV2LT5l cDBfZGF0YV9kaXIgPSAwOwo+ICsgICAgICAgcHJpdl9kZXYtPmVwMF9zdGFnZSA9IENETlMzX1NF VFVQX1NUQUdFOwo+ICsgICAgICAgY2RuczNfZXAwX3J1bl90cmFuc2Zlcihwcml2X2RldiwgcHJp dl9kZXYtPnNldHVwX2RtYSwKPiArICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZW9m KHN0cnVjdCB1c2JfY3RybHJlcXVlc3QpLCAwKTsKPiArfQo+ICsKPiArc3RhdGljIHZvaWQgY2Ru czNfZXAwX2NvbXBsZXRlX3NldHVwKHN0cnVjdCBjZG5zM19kZXZpY2UgKnByaXZfZGV2LAo+ICsg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1OCBzZW5kX3N0YWxsLCB1OCBzZW5k X2VyZHkpCj4gK3sKPiArICAgICAgIHN0cnVjdCBjZG5zM19lbmRwb2ludCAqcHJpdl9lcCA9IHBy aXZfZGV2LT5lcHNbMF07Cj4gKyAgICAgICBzdHJ1Y3QgdXNiX3JlcXVlc3QgKnJlcXVlc3Q7Cj4g Kwo+ICsgICAgICAgcmVxdWVzdCA9IGNkbnMzX25leHRfcmVxdWVzdCgmcHJpdl9lcC0+cGVuZGlu Z19yZXFfbGlzdCk7Cj4gKyAgICAgICBpZiAocmVxdWVzdCkKPiArICAgICAgICAgICAgICAgbGlz dF9kZWxfaW5pdCgmcmVxdWVzdC0+bGlzdCk7Cj4gKwo+ICsgICAgICAgaWYgKHNlbmRfc3RhbGwp IHsKPiArICAgICAgICAgICAgICAgY2RuczNfZGJnKHByaXZfZXAtPmNkbnMzX2RldiwgIlNUQUxM IGZvciBlcDBcbiIpOwo+ICsgICAgICAgICAgICAgICAvKiBzZXRfc3RhbGwgb24gZXAwICovCj4g KyAgICAgICAgICAgICAgIGNkbnMzX3NlbGVjdF9lcChwcml2X2RldiwgMHgwMCk7Cj4gKyAgICAg ICAgICAgICAgIHdyaXRlbChFUF9DTURfU1NUQUxMLCAmcHJpdl9kZXYtPnJlZ3MtPmVwX2NtZCk7 Cj4gKyAgICAgICB9IGVsc2Ugewo+ICsgICAgICAgICAgICAgICBjZG5zM19wcmVwYXJlX3NldHVw X3BhY2tldChwcml2X2Rldik7Cj4gKyAgICAgICB9Cj4gKwo+ICsgICAgICAgcHJpdl9kZXYtPmVw MF9zdGFnZSA9IENETlMzX1NFVFVQX1NUQUdFOwo+ICsgICAgICAgd3JpdGVsKChzZW5kX2VyZHkg PyBFUF9DTURfRVJEWSA6IDApIHwgRVBfQ01EX1JFUV9DTVBMLAo+ICsgICAgICAgICAgICAgICZw cml2X2Rldi0+cmVncy0+ZXBfY21kKTsKPiArfQo+ICsKPiArLyoqCj4gKyAqIGNkbnMzX3JlcV9l cDBfc2V0X2NvbmZpZ3VyYXRpb24gLSBIYW5kbGluZyBvZiBTRVRfQ09ORklHIHN0YW5kYXJkIFVT QiByZXF1ZXN0Cj4gKyAqIEBwcml2X2RldjogZXh0ZW5kZWQgZ2FkZ2V0IG9iamVjdAo+ICsgKiBA Y3RybF9yZXE6IHBvaW50ZXIgdG8gcmVjZWl2ZWQgc2V0dXAgcGFja2V0Cj4gKyAqCj4gKyAqIFJl dHVybnMgMCBpZiBzdWNjZXNzLCBVU0JfR0FER0VUX0RFTEFZRURfU1RBVFVTIG9uIGRlZmVycmVk IHN0YXR1cyBzdGFnZSwKPiArICogZXJyb3IgY29kZSBvbiBlcnJvcgo+ICsgKi8KPiArc3RhdGlj IGludCBjZG5zM19yZXFfZXAwX3NldF9jb25maWd1cmF0aW9uKHN0cnVjdCBjZG5zM19kZXZpY2Ug KnByaXZfZGV2LAo+ICsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBz dHJ1Y3QgdXNiX2N0cmxyZXF1ZXN0ICpjdHJsX3JlcSkKPiArewo+ICsgICAgICAgZW51bSB1c2Jf ZGV2aWNlX3N0YXRlIGRldmljZV9zdGF0ZSA9IHByaXZfZGV2LT5nYWRnZXQuc3RhdGU7Cj4gKyAg ICAgICBzdHJ1Y3QgY2RuczNfZW5kcG9pbnQgKnByaXZfZXA7Cj4gKyAgICAgICB1MzIgY29uZmln ID0gbGUxNl90b19jcHUoY3RybF9yZXEtPndWYWx1ZSk7Cj4gKyAgICAgICBpbnQgcmVzdWx0ID0g MDsKPiArICAgICAgIGludCBpOwo+ICsKPiArICAgICAgIHN3aXRjaCAoZGV2aWNlX3N0YXRlKSB7 Cj4gKyAgICAgICBjYXNlIFVTQl9TVEFURV9BRERSRVNTOgo+ICsgICAgICAgICAgICAgICAvKiBD b25maWd1cmUgbm9uLWNvbnRyb2wgRVBzICovCj4gKyAgICAgICAgICAgICAgIGZvciAoaSA9IDA7 IGkgPCBDRE5TM19FTkRQT0lOVFNfTUFYX0NPVU5UOyBpKyspIHsKPiArICAgICAgICAgICAgICAg ICAgICAgICBwcml2X2VwID0gcHJpdl9kZXYtPmVwc1tpXTsKPiArICAgICAgICAgICAgICAgICAg ICAgICBpZiAoIXByaXZfZXApCj4gKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250 aW51ZTsKPiArCj4gKyAgICAgICAgICAgICAgICAgICAgICAgaWYgKHByaXZfZXAtPmZsYWdzICYg RVBfQ0xBSU1FRCkKPiArICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNkbnMzX2VwX2Nv bmZpZyhwcml2X2VwKTsKPiArICAgICAgICAgICAgICAgfQo+ICsKPiArICAgICAgICAgICAgICAg cmVzdWx0ID0gY2RuczNfZXAwX2RlbGVnYXRlX3JlcShwcml2X2RldiwgY3RybF9yZXEpOwo+ICsK PiArICAgICAgICAgICAgICAgaWYgKHJlc3VsdCkKPiArICAgICAgICAgICAgICAgICAgICAgICBy ZXR1cm4gcmVzdWx0Owo+ICsKPiArICAgICAgICAgICAgICAgaWYgKGNvbmZpZykgewo+ICsgICAg ICAgICAgICAgICAgICAgICAgIGNkbnMzX3NldF9od19jb25maWd1cmF0aW9uKHByaXZfZGV2KTsK PiArICAgICAgICAgICAgICAgfSBlbHNlIHsKPiArICAgICAgICAgICAgICAgICAgICAgICBjZG5z M19od19yZXNldF9lcHNfY29uZmlnKHByaXZfZGV2KTsKPiArICAgICAgICAgICAgICAgICAgICAg ICB1c2JfZ2FkZ2V0X3NldF9zdGF0ZSgmcHJpdl9kZXYtPmdhZGdldCwKPiArICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVU0JfU1RBVEVfQUREUkVTUyk7Cj4gKyAg ICAgICAgICAgICAgIH0KPiArICAgICAgICAgICAgICAgYnJlYWs7Cj4gKyAgICAgICBjYXNlIFVT Ql9TVEFURV9DT05GSUdVUkVEOgo+ICsgICAgICAgICAgICAgICByZXN1bHQgPSBjZG5zM19lcDBf ZGVsZWdhdGVfcmVxKHByaXZfZGV2LCBjdHJsX3JlcSk7Cj4gKwo+ICsgICAgICAgICAgICAgICBp ZiAoIWNvbmZpZyAmJiAhcmVzdWx0KSB7Cj4gKyAgICAgICAgICAgICAgICAgICAgICAgY2RuczNf aHdfcmVzZXRfZXBzX2NvbmZpZyhwcml2X2Rldik7Cj4gKyAgICAgICAgICAgICAgICAgICAgICAg dXNiX2dhZGdldF9zZXRfc3RhdGUoJnByaXZfZGV2LT5nYWRnZXQsCj4gKyAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVVNCX1NUQVRFX0FERFJFU1MpOwo+ICsgICAg ICAgICAgICAgICB9Cj4gKyAgICAgICAgICAgICAgIGJyZWFrOwo+ICsgICAgICAgZGVmYXVsdDoK PiArICAgICAgICAgICAgICAgcmVzdWx0ID0gLUVJTlZBTDsKPiArICAgICAgIH0KPiArCj4gKyAg ICAgICByZXR1cm4gcmVzdWx0Owo+ICt9Cj4gKwo+ICsvKioKPiArICogY2RuczNfcmVxX2VwMF9z ZXRfYWRkcmVzcyAtIEhhbmRsaW5nIG9mIFNFVF9BRERSRVNTIHN0YW5kYXJkIFVTQiByZXF1ZXN0 Cj4gKyAqIEBwcml2X2RldjogZXh0ZW5kZWQgZ2FkZ2V0IG9iamVjdAo+ICsgKiBAY3RybF9yZXE6 IHBvaW50ZXIgdG8gcmVjZWl2ZWQgc2V0dXAgcGFja2V0Cj4gKyAqCj4gKyAqIFJldHVybnMgMCBp ZiBzdWNjZXNzLCBlcnJvciBjb2RlIG9uIGVycm9yCj4gKyAqLwo+ICtzdGF0aWMgaW50IGNkbnMz X3JlcV9lcDBfc2V0X2FkZHJlc3Moc3RydWN0IGNkbnMzX2RldmljZSAqcHJpdl9kZXYsCj4gKyAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cnVjdCB1c2JfY3RybHJlcXVlc3Qg KmN0cmxfcmVxKQo+ICt7Cj4gKyAgICAgICBlbnVtIHVzYl9kZXZpY2Vfc3RhdGUgZGV2aWNlX3N0 YXRlID0gcHJpdl9kZXYtPmdhZGdldC5zdGF0ZTsKPiArICAgICAgIHUzMiByZWc7Cj4gKyAgICAg ICB1MzIgYWRkcjsKPiArCj4gKyAgICAgICBhZGRyID0gbGUxNl90b19jcHUoY3RybF9yZXEtPndW YWx1ZSk7Cj4gKwo+ICsgICAgICAgaWYgKGFkZHIgPiBVU0JfREVWSUNFX01BWF9BRERSRVNTKSB7 Cj4gKyAgICAgICAgICAgICAgIGRldl9lcnIocHJpdl9kZXYtPmRldiwKPiArICAgICAgICAgICAg ICAgICAgICAgICAiRGV2aWNlIGFkZHJlc3MgKCVkKSBjYW5ub3QgYmUgZ3JlYXRlciB0aGFuICVk XG4iLAo+ICsgICAgICAgICAgICAgICAgICAgICAgIGFkZHIsIFVTQl9ERVZJQ0VfTUFYX0FERFJF U1MpOwo+ICsgICAgICAgICAgICAgICByZXR1cm4gLUVJTlZBTDsKPiArICAgICAgIH0KPiArCj4g KyAgICAgICBpZiAoZGV2aWNlX3N0YXRlID09IFVTQl9TVEFURV9DT05GSUdVUkVEKSB7Cj4gKyAg ICAgICAgICAgICAgIGRldl9lcnIocHJpdl9kZXYtPmRldiwKPiArICAgICAgICAgICAgICAgICAg ICAgICAiY2FuJ3Qgc2V0X2FkZHJlc3MgZnJvbSBjb25maWd1cmVkIHN0YXRlXG4iKTsKPiArICAg ICAgICAgICAgICAgcmV0dXJuIC1FSU5WQUw7Cj4gKyAgICAgICB9Cj4gKwo+ICsgICAgICAgcmVn ID0gcmVhZGwoJnByaXZfZGV2LT5yZWdzLT51c2JfY21kKTsKPiArCj4gKyAgICAgICB3cml0ZWwo cmVnIHwgVVNCX0NNRF9GQUREUihhZGRyKSB8IFVTQl9DTURfU0VUX0FERFIsCj4gKyAgICAgICAg ICAgICAgJnByaXZfZGV2LT5yZWdzLT51c2JfY21kKTsKPiArCj4gKyAgICAgICB1c2JfZ2FkZ2V0 X3NldF9zdGF0ZSgmcHJpdl9kZXYtPmdhZGdldCwKPiArICAgICAgICAgICAgICAgICAgICAgICAg ICAgIChhZGRyID8gVVNCX1NUQVRFX0FERFJFU1MgOiBVU0JfU1RBVEVfREVGQVVMVCkpOwo+ICsK PiArICAgICAgIHJldHVybiAwOwo+ICt9Cj4gKwo+ICsvKioKPiArICogY2RuczNfcmVxX2VwMF9n ZXRfc3RhdHVzIC0gSGFuZGxpbmcgb2YgR0VUX1NUQVRVUyBzdGFuZGFyZCBVU0IgcmVxdWVzdAo+ ICsgKiBAcHJpdl9kZXY6IGV4dGVuZGVkIGdhZGdldCBvYmplY3QKPiArICogQGN0cmxfcmVxOiBw b2ludGVyIHRvIHJlY2VpdmVkIHNldHVwIHBhY2tldAo+ICsgKgo+ICsgKiBSZXR1cm5zIDAgaWYg c3VjY2VzcywgZXJyb3IgY29kZSBvbiBlcnJvcgo+ICsgKi8KPiArc3RhdGljIGludCBjZG5zM19y ZXFfZXAwX2dldF9zdGF0dXMoc3RydWN0IGNkbnMzX2RldmljZSAqcHJpdl9kZXYsCj4gKyAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RydWN0IHVzYl9jdHJscmVxdWVzdCAqY3Ry bCkKPiArewo+ICsgICAgICAgX19sZTE2ICpyZXNwb25zZV9wa3Q7Cj4gKyAgICAgICB1MTYgdXNi X3N0YXR1cyA9IDA7Cj4gKyAgICAgICB1MzIgcmVjaXA7Cj4gKyAgICAgICB1MzIgcmVnOwo+ICsK PiArICAgICAgIHJlY2lwID0gY3RybC0+YlJlcXVlc3RUeXBlICYgVVNCX1JFQ0lQX01BU0s7Cj4g Kwo+ICsgICAgICAgc3dpdGNoIChyZWNpcCkgewo+ICsgICAgICAgY2FzZSBVU0JfUkVDSVBfREVW SUNFOgo+ICsgICAgICAgICAgICAgICAvKiBzZWxmIHBvd2VyZWQgKi8KPiArICAgICAgICAgICAg ICAgaWYgKHByaXZfZGV2LT5pc19zZWxmcG93ZXJlZCkKPiArICAgICAgICAgICAgICAgICAgICAg ICB1c2Jfc3RhdHVzID0gQklUKFVTQl9ERVZJQ0VfU0VMRl9QT1dFUkVEKTsKPiArCj4gKyAgICAg ICAgICAgICAgIGlmIChwcml2X2Rldi0+d2FrZV91cF9mbGFnKQo+ICsgICAgICAgICAgICAgICAg ICAgICAgIHVzYl9zdGF0dXMgfD0gQklUKFVTQl9ERVZJQ0VfUkVNT1RFX1dBS0VVUCk7Cj4gKwo+ ICsgICAgICAgICAgICAgICBpZiAocHJpdl9kZXYtPmdhZGdldC5zcGVlZCAhPSBVU0JfU1BFRURf U1VQRVIpCj4gKyAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Cj4gKwo+ICsgICAgICAgICAg ICAgICByZWcgPSByZWFkbCgmcHJpdl9kZXYtPnJlZ3MtPnVzYl9zdHMpOwo+ICsKPiArICAgICAg ICAgICAgICAgaWYgKHByaXZfZGV2LT51MV9hbGxvd2VkKQo+ICsgICAgICAgICAgICAgICAgICAg ICAgIHVzYl9zdGF0dXMgfD0gQklUKFVTQl9ERVZfU1RBVF9VMV9FTkFCTEVEKTsKPiArCj4gKyAg ICAgICAgICAgICAgIGlmIChwcml2X2Rldi0+dTJfYWxsb3dlZCkKPiArICAgICAgICAgICAgICAg ICAgICAgICB1c2Jfc3RhdHVzIHw9IEJJVChVU0JfREVWX1NUQVRfVTJfRU5BQkxFRCk7Cj4gKwo+ ICsgICAgICAgICAgICAgICBicmVhazsKPiArICAgICAgIGNhc2UgVVNCX1JFQ0lQX0lOVEVSRkFD RToKPiArICAgICAgICAgICAgICAgcmV0dXJuIGNkbnMzX2VwMF9kZWxlZ2F0ZV9yZXEocHJpdl9k ZXYsIGN0cmwpOwo+ICsgICAgICAgY2FzZSBVU0JfUkVDSVBfRU5EUE9JTlQ6Cj4gKyAgICAgICAg ICAgICAgIC8qIGNoZWNrIGlmIGVuZHBvaW50IGlzIHN0YWxsZWQgKi8KPiArICAgICAgICAgICAg ICAgY2RuczNfc2VsZWN0X2VwKHByaXZfZGV2LCBjdHJsLT53SW5kZXgpOwo+ICsgICAgICAgICAg ICAgICBpZiAoRVBfU1RTX1NUQUxMKHJlYWRsKCZwcml2X2Rldi0+cmVncy0+ZXBfc3RzKSkpCj4g KyAgICAgICAgICAgICAgICAgICAgICAgdXNiX3N0YXR1cyA9ICBCSVQoVVNCX0VORFBPSU5UX0hB TFQpOwo+ICsgICAgICAgICAgICAgICBicmVhazsKPiArICAgICAgIGRlZmF1bHQ6Cj4gKyAgICAg ICAgICAgICAgIHJldHVybiAtRUlOVkFMOwo+ICsgICAgICAgfQo+ICsKPiArICAgICAgIHJlc3Bv bnNlX3BrdCA9IChfX2xlMTYgKilwcml2X2Rldi0+c2V0dXBfYnVmOwo+ICsgICAgICAgKnJlc3Bv bnNlX3BrdCA9IGNwdV90b19sZTE2KHVzYl9zdGF0dXMpOwo+ICsKPiArICAgICAgIGNkbnMzX2Vw MF9ydW5fdHJhbnNmZXIocHJpdl9kZXYsIHByaXZfZGV2LT5zZXR1cF9kbWEsCj4gKyAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgIHNpemVvZigqcmVzcG9uc2VfcGt0KSwgMSk7Cj4gKyAgICAg ICByZXR1cm4gMDsKPiArfQo+ICsKPiArc3RhdGljIGludCBjZG5zM19lcDBfZmVhdHVyZV9oYW5k bGVfZGV2aWNlKHN0cnVjdCBjZG5zM19kZXZpY2UgKnByaXZfZGV2LAo+ICsgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJ1Y3QgdXNiX2N0cmxyZXF1ZXN0ICpjdHJs LAo+ICsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgc2V0KQo+ ICt7Cj4gKyAgICAgICBlbnVtIHVzYl9kZXZpY2Vfc3RhdGUgc3RhdGU7Cj4gKyAgICAgICBlbnVt IHVzYl9kZXZpY2Vfc3BlZWQgc3BlZWQ7Cj4gKyAgICAgICBpbnQgcmV0ID0gMDsKPiArICAgICAg IHUzMiB3VmFsdWU7Cj4gKyAgICAgICB1MzIgd0luZGV4Owo+ICsgICAgICAgdTE2IHRtb2RlOwo+ ICsKPiArICAgICAgIHdWYWx1ZSA9IGxlMTZfdG9fY3B1KGN0cmwtPndWYWx1ZSk7Cj4gKyAgICAg ICB3SW5kZXggPSBsZTE2X3RvX2NwdShjdHJsLT53SW5kZXgpOwo+ICsgICAgICAgc3RhdGUgPSBw cml2X2Rldi0+Z2FkZ2V0LnN0YXRlOwo+ICsgICAgICAgc3BlZWQgPSBwcml2X2Rldi0+Z2FkZ2V0 LnNwZWVkOwo+ICsKPiArICAgICAgIHN3aXRjaCAoY3RybC0+d1ZhbHVlKSB7Cj4gKyAgICAgICBj YXNlIFVTQl9ERVZJQ0VfUkVNT1RFX1dBS0VVUDoKPiArICAgICAgICAgICAgICAgcHJpdl9kZXYt Pndha2VfdXBfZmxhZyA9ICEhc2V0Owo+ICsgICAgICAgICAgICAgICBicmVhazsKPiArICAgICAg IGNhc2UgVVNCX0RFVklDRV9VMV9FTkFCTEU6Cj4gKyAgICAgICAgICAgICAgIGlmIChzdGF0ZSAh PSBVU0JfU1RBVEVfQ09ORklHVVJFRCB8fCBzcGVlZCAhPSBVU0JfU1BFRURfU1VQRVIpCj4gKyAg ICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIC1FSU5WQUw7Cj4gKwo+ICsgICAgICAgICAgICAg ICBwcml2X2Rldi0+dTFfYWxsb3dlZCA9ICEhc2V0Owo+ICsgICAgICAgICAgICAgICBicmVhazsK PiArICAgICAgIGNhc2UgVVNCX0RFVklDRV9VMl9FTkFCTEU6Cj4gKyAgICAgICAgICAgICAgIGlm IChzdGF0ZSAhPSBVU0JfU1RBVEVfQ09ORklHVVJFRCB8fCBzcGVlZCAhPSBVU0JfU1BFRURfU1VQ RVIpCj4gKyAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIC1FSU5WQUw7Cj4gKwo+ICsgICAg ICAgICAgICAgICBwcml2X2Rldi0+dTJfYWxsb3dlZCA9ICEhc2V0Owo+ICsgICAgICAgICAgICAg ICBicmVhazsKPiArICAgICAgIGNhc2UgVVNCX0RFVklDRV9MVE1fRU5BQkxFOgo+ICsgICAgICAg ICAgICAgICByZXQgPSAtRUlOVkFMOwo+ICsgICAgICAgICAgICAgICBicmVhazsKPiArICAgICAg IGNhc2UgVVNCX0RFVklDRV9URVNUX01PREU6Cj4gKyAgICAgICAgICAgICAgIGlmIChzdGF0ZSAh PSBVU0JfU1RBVEVfQ09ORklHVVJFRCB8fCBzcGVlZCA+IFVTQl9TUEVFRF9ISUdIKQo+ICsgICAg ICAgICAgICAgICAgICAgICAgIHJldHVybiAtRUlOVkFMOwo+ICsKPiArICAgICAgICAgICAgICAg dG1vZGUgPSBsZTE2X3RvX2NwdShjdHJsLT53SW5kZXgpOwo+ICsKPiArICAgICAgICAgICAgICAg aWYgKCFzZXQgfHwgKHRtb2RlICYgMHhmZikgIT0gMCkKPiArICAgICAgICAgICAgICAgICAgICAg ICByZXR1cm4gLUVJTlZBTDsKPiArCj4gKyAgICAgICAgICAgICAgIHN3aXRjaCAodG1vZGUgPj4g OCkgewo+ICsgICAgICAgICAgICAgICBjYXNlIFRFU1RfSjoKPiArICAgICAgICAgICAgICAgY2Fz ZSBURVNUX0s6Cj4gKyAgICAgICAgICAgICAgIGNhc2UgVEVTVF9TRTBfTkFLOgo+ICsgICAgICAg ICAgICAgICBjYXNlIFRFU1RfUEFDS0VUOgo+ICsgICAgICAgICAgICAgICAgICAgICAgIGNkbnMz X2VwMF9jb21wbGV0ZV9zZXR1cChwcml2X2RldiwgMCwgMSk7Cj4gKyAgICAgICAgICAgICAgICAg ICAgICAgLyoqCj4gKyAgICAgICAgICAgICAgICAgICAgICAgICogIExpdHRsZSBkZWxheSB0byBn aXZlIHRoZSBjb250cm9sbGVyIHNvbWUgdGltZQo+ICsgICAgICAgICAgICAgICAgICAgICAgICAq IGZvciBzZW5kaW5nIHN0YXR1cyBzdGFnZS4KPiArICAgICAgICAgICAgICAgICAgICAgICAgKiBU aGlzIHRpbWUgc2hvdWxkIGJlIGxlc3MgdGhlbiAzbXMuCj4gKyAgICAgICAgICAgICAgICAgICAg ICAgICovCj4gKyAgICAgICAgICAgICAgICAgICAgICAgdXNsZWVwX3JhbmdlKDEwMDAsIDIwMDAp Owo+ICsgICAgICAgICAgICAgICAgICAgICAgIGNkbnMzX3NldF9yZWdpc3Rlcl9iaXQoJnByaXZf ZGV2LT5yZWdzLT51c2JfY21kLAo+ICsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgVVNCX0NNRF9TVE1PREUgfAo+ICsgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgVVNCX1NUU19UTU9ERV9TRUwodG1vZGUgLSAxKSk7Cj4gKyAg ICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Cj4gKyAgICAgICAgICAgICAgIGRlZmF1bHQ6Cj4g KyAgICAgICAgICAgICAgICAgICAgICAgcmV0ID0gLUVJTlZBTDsKPiArICAgICAgICAgICAgICAg fQo+ICsgICAgICAgICAgICAgICBicmVhazsKPiArICAgICAgIGRlZmF1bHQ6Cj4gKyAgICAgICAg ICAgICAgIHJldCA9IC1FSU5WQUw7Cj4gKyAgICAgICB9Cj4gKwo+ICsgICAgICAgcmV0dXJuIHJl dDsKPiArfQo+ICsKPiArc3RhdGljIGludCBjZG5zM19lcDBfZmVhdHVyZV9oYW5kbGVfaW50Zihz dHJ1Y3QgY2RuczNfZGV2aWNlICpwcml2X2RldiwKPiArICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgIHN0cnVjdCB1c2JfY3RybHJlcXVlc3QgKmN0cmwsCj4gKyAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgc2V0KQo+ICt7Cj4gKyAgICAgICB1 MzIgd1ZhbHVlOwo+ICsgICAgICAgaW50IHJldCA9IDA7Cj4gKwo+ICsgICAgICAgd1ZhbHVlID0g bGUxNl90b19jcHUoY3RybC0+d1ZhbHVlKTsKPiArCj4gKyAgICAgICBzd2l0Y2ggKHdWYWx1ZSkg ewo+ICsgICAgICAgY2FzZSBVU0JfSU5UUkZfRlVOQ19TVVNQRU5EOgo+ICsgICAgICAgICAgICAg ICBicmVhazsKPiArICAgICAgIGRlZmF1bHQ6Cj4gKyAgICAgICAgICAgICAgIHJldCA9IC1FSU5W QUw7Cj4gKyAgICAgICB9Cj4gKwo+ICsgICAgICAgcmV0dXJuIHJldDsKPiArfQo+ICsKPiArc3Rh dGljIGludCBjZG5zM19lcDBfZmVhdHVyZV9oYW5kbGVfZW5kcG9pbnQoc3RydWN0IGNkbnMzX2Rl dmljZSAqcHJpdl9kZXYsCj4gKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgc3RydWN0IHVzYl9jdHJscmVxdWVzdCAqY3RybCwKPiArICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgc2V0KQo+ICt7Cj4gKyAgICAgICBzdHJ1Y3Qg Y2RuczNfZW5kcG9pbnQgKnByaXZfZXA7Cj4gKyAgICAgICBpbnQgcmV0ID0gMDsKPiArICAgICAg IHU4IGluZGV4Owo+ICsKPiArICAgICAgIGlmIChsZTE2X3RvX2NwdShjdHJsLT53VmFsdWUpICE9 IFVTQl9FTkRQT0lOVF9IQUxUKQo+ICsgICAgICAgICAgICAgICByZXR1cm4gLUVJTlZBTDsKPiAr Cj4gKyAgICAgICBpZiAoIShjdHJsLT53SW5kZXggJiB+VVNCX0RJUl9JTikpCj4gKyAgICAgICAg ICAgICAgIHJldHVybiAwOwo+ICsKPiArICAgICAgIGluZGV4ID0gY2RuczNfZXBfYWRkcl90b19p bmRleChjdHJsLT53SW5kZXgpOwo+ICsgICAgICAgcHJpdl9lcCA9IHByaXZfZGV2LT5lcHNbaW5k ZXhdOwo+ICsKPiArICAgICAgIGNkbnMzX3NlbGVjdF9lcChwcml2X2RldiwgY3RybC0+d0luZGV4 KTsKPiArCj4gKyAgICAgICBpZiAoc2V0KSB7Cj4gKyAgICAgICAgICAgICAgIGNkbnMzX2RiZyhw cml2X2VwLT5jZG5zM19kZXYsICJTdGFsbCBlbmRwb2ludCAlc1xuIiwKPiArICAgICAgICAgICAg ICAgICAgICAgICAgIHByaXZfZXAtPm5hbWUpOwo+ICsgICAgICAgICAgICAgICB3cml0ZWwoRVBf Q01EX1NTVEFMTCwgJnByaXZfZGV2LT5yZWdzLT5lcF9jbWQpOwo+ICsgICAgICAgICAgICAgICBw cml2X2VwLT5mbGFncyB8PSBFUF9TVEFMTDsKPiArICAgICAgIH0gZWxzZSB7Cj4gKyAgICAgICAg ICAgICAgIHN0cnVjdCB1c2JfcmVxdWVzdCAqcmVxdWVzdDsKPiArCj4gKyAgICAgICAgICAgICAg IGlmIChwcml2X2Rldi0+ZXBzW2luZGV4XS0+ZmxhZ3MgJiBFUF9XRURHRSkgewo+ICsgICAgICAg ICAgICAgICAgICAgICAgIGNkbnMzX3NlbGVjdF9lcChwcml2X2RldiwgMHgwMCk7Cj4gKyAgICAg ICAgICAgICAgICAgICAgICAgcmV0dXJuIDA7Cj4gKyAgICAgICAgICAgICAgIH0KPiArCj4gKyAg ICAgICAgICAgICAgIGNkbnMzX2RiZyhwcml2X2VwLT5jZG5zM19kZXYsICJDbGVhciBTdGFsbGVk IGVuZHBvaW50ICVzXG4iLAo+ICsgICAgICAgICAgICAgICAgICAgICAgICAgcHJpdl9lcC0+bmFt ZSk7Cj4gKwo+ICsgICAgICAgICAgICAgICB3cml0ZWwoRVBfQ01EX0NTVEFMTCB8IEVQX0NNRF9F UFJTVCwgJnByaXZfZGV2LT5yZWdzLT5lcF9jbWQpOwo+ICsKPiArICAgICAgICAgICAgICAgLyog d2FpdCBmb3IgRVBSU1QgY2xlYXJlZCAqLwo+ICsgICAgICAgICAgICAgICByZXQgPSBjZG5zM19o YW5kc2hha2UoJnByaXZfZGV2LT5yZWdzLT5lcF9jbWQsCj4gKyAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICBFUF9DTURfRVBSU1QsIDAsIDEwMCk7Cj4gKyAgICAgICAgICAgICAg IGlmIChyZXQpCj4gKyAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIC1FSU5WQUw7Cj4gKwo+ ICsgICAgICAgICAgICAgICBwcml2X2VwLT5mbGFncyAmPSB+RVBfU1RBTEw7Cj4gKwo+ICsgICAg ICAgICAgICAgICByZXF1ZXN0ID0gY2RuczNfbmV4dF9yZXF1ZXN0KCZwcml2X2VwLT5wZW5kaW5n X3JlcV9saXN0KTsKPiArICAgICAgICAgICAgICAgaWYgKHJlcXVlc3QpIHsKPiArICAgICAgICAg ICAgICAgICAgICAgICBjZG5zM19kYmcocHJpdl9lcC0+Y2RuczNfZGV2LCAiUmVzdW1lIHRyYW5z ZmVyIGZvciAlc1xuIiwKPiArICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJpdl9l cC0+bmFtZSk7Cj4gKwo+ICsgICAgICAgICAgICAgICAgICAgICAgIGNkbnMzX3JlYXJtX3RyYW5z ZmVyKHByaXZfZXAsIDEpOwo+ICsgICAgICAgICAgICAgICB9Cj4gKyAgICAgICB9Cj4gKwo+ICsg ICAgICAgcmV0dXJuIHJldDsKPiArfQo+ICsKPiArLyoqCj4gKyAqIGNkbnMzX3JlcV9lcDBfaGFu ZGxlX2ZlYXR1cmUgLQo+ICsgKiBIYW5kbGluZyBvZiBHRVQvU0VUX0ZFQVRVUkUgc3RhbmRhcmQg VVNCIHJlcXVlc3QKPiArICoKPiArICogQHByaXZfZGV2OiBleHRlbmRlZCBnYWRnZXQgb2JqZWN0 Cj4gKyAqIEBjdHJsX3JlcTogcG9pbnRlciB0byByZWNlaXZlZCBzZXR1cCBwYWNrZXQKPiArICog QHNldDogbXVzdCBiZSBzZXQgdG8gMSBmb3IgU0VUX0ZFQVRVUkUgcmVxdWVzdAo+ICsgKgo+ICsg KiBSZXR1cm5zIDAgaWYgc3VjY2VzcywgZXJyb3IgY29kZSBvbiBlcnJvcgo+ICsgKi8KPiArc3Rh dGljIGludCBjZG5zM19yZXFfZXAwX2hhbmRsZV9mZWF0dXJlKHN0cnVjdCBjZG5zM19kZXZpY2Ug KnByaXZfZGV2LAo+ICsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJ1 Y3QgdXNiX2N0cmxyZXF1ZXN0ICpjdHJsLAo+ICsgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICBpbnQgc2V0KQo+ICt7Cj4gKyAgICAgICBpbnQgcmV0ID0gMDsKPiArICAgICAg IHUzMiByZWNpcDsKPiArCj4gKyAgICAgICByZWNpcCA9IGN0cmwtPmJSZXF1ZXN0VHlwZSAmIFVT Ql9SRUNJUF9NQVNLOwo+ICsKPiArICAgICAgIHN3aXRjaCAocmVjaXApIHsKPiArICAgICAgIGNh c2UgVVNCX1JFQ0lQX0RFVklDRToKPiArICAgICAgICAgICAgICAgcmV0ID0gY2RuczNfZXAwX2Zl YXR1cmVfaGFuZGxlX2RldmljZShwcml2X2RldiwgY3RybCwgc2V0KTsKPiArICAgICAgICAgICAg ICAgYnJlYWs7Cj4gKyAgICAgICBjYXNlIFVTQl9SRUNJUF9JTlRFUkZBQ0U6Cj4gKyAgICAgICAg ICAgICAgIHJldCA9IGNkbnMzX2VwMF9mZWF0dXJlX2hhbmRsZV9pbnRmKHByaXZfZGV2LCBjdHJs LCBzZXQpOwo+ICsgICAgICAgICAgICAgICBicmVhazsKPiArICAgICAgIGNhc2UgVVNCX1JFQ0lQ X0VORFBPSU5UOgo+ICsgICAgICAgICAgICAgICByZXQgPSBjZG5zM19lcDBfZmVhdHVyZV9oYW5k bGVfZW5kcG9pbnQocHJpdl9kZXYsIGN0cmwsIHNldCk7Cj4gKyAgICAgICAgICAgICAgIGJyZWFr Owo+ICsgICAgICAgZGVmYXVsdDoKPiArICAgICAgICAgICAgICAgcmV0dXJuIC1FSU5WQUw7Cj4g KyAgICAgICB9Cj4gKwo+ICsgICAgICAgcmV0dXJuIHJldDsKPiArfQo+ICsKPiArLyoqCj4gKyAq IGNkbnMzX3JlcV9lcDBfc2V0X3NlbCAtIEhhbmRsaW5nIG9mIFNFVF9TRUwgc3RhbmRhcmQgVVNC IHJlcXVlc3QKPiArICogQHByaXZfZGV2OiBleHRlbmRlZCBnYWRnZXQgb2JqZWN0Cj4gKyAqIEBj dHJsX3JlcTogcG9pbnRlciB0byByZWNlaXZlZCBzZXR1cCBwYWNrZXQKPiArICoKPiArICogUmV0 dXJucyAwIGlmIHN1Y2Nlc3MsIGVycm9yIGNvZGUgb24gZXJyb3IKPiArICovCj4gK3N0YXRpYyBp bnQgY2RuczNfcmVxX2VwMF9zZXRfc2VsKHN0cnVjdCBjZG5zM19kZXZpY2UgKnByaXZfZGV2LAo+ ICsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cnVjdCB1c2JfY3RybHJlcXVlc3Qg KmN0cmxfcmVxKQo+ICt7Cj4gKyAgICAgICBpZiAocHJpdl9kZXYtPmdhZGdldC5zdGF0ZSA8IFVT Ql9TVEFURV9BRERSRVNTKQo+ICsgICAgICAgICAgICAgICByZXR1cm4gLUVJTlZBTDsKPiArCj4g KyAgICAgICBpZiAoY3RybF9yZXEtPndMZW5ndGggIT0gNikgewo+ICsgICAgICAgICAgICAgICBk ZXZfZXJyKHByaXZfZGV2LT5kZXYsICJTZXQgU0VMIHNob3VsZCBiZSA2IGJ5dGVzLCBnb3QgJWRc biIsCj4gKyAgICAgICAgICAgICAgICAgICAgICAgY3RybF9yZXEtPndMZW5ndGgpOwo+ICsgICAg ICAgICAgICAgICByZXR1cm4gLUVJTlZBTDsKPiArICAgICAgIH0KPiArCj4gKyAgICAgICBjZG5z M19lcDBfcnVuX3RyYW5zZmVyKHByaXZfZGV2LCBwcml2X2Rldi0+c2V0dXBfZG1hLCA2LCAxKTsK PiArICAgICAgIHJldHVybiAwOwo+ICt9Cj4gKwo+ICsvKioKPiArICogY2RuczNfcmVxX2VwMF9z ZXRfaXNvY2hfZGVsYXkgLQo+ICsgKiBIYW5kbGluZyBvZiBHRVRfSVNPQ0hfREVMQVkgc3RhbmRh cmQgVVNCIHJlcXVlc3QKPiArICogQHByaXZfZGV2OiBleHRlbmRlZCBnYWRnZXQgb2JqZWN0Cj4g KyAqIEBjdHJsX3JlcTogcG9pbnRlciB0byByZWNlaXZlZCBzZXR1cCBwYWNrZXQKPiArICoKPiAr ICogUmV0dXJucyAwIGlmIHN1Y2Nlc3MsIGVycm9yIGNvZGUgb24gZXJyb3IKPiArICovCj4gK3N0 YXRpYyBpbnQgY2RuczNfcmVxX2VwMF9zZXRfaXNvY2hfZGVsYXkoc3RydWN0IGNkbnMzX2Rldmlj ZSAqcHJpdl9kZXYsCj4gKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBz dHJ1Y3QgdXNiX2N0cmxyZXF1ZXN0ICpjdHJsX3JlcSkKPiArewo+ICsgICAgICAgaWYgKGN0cmxf cmVxLT53SW5kZXggfHwgY3RybF9yZXEtPndMZW5ndGgpCj4gKyAgICAgICAgICAgICAgIHJldHVy biAtRUlOVkFMOwo+ICsKPiArICAgICAgIHByaXZfZGV2LT5pc29jaF9kZWxheSA9IGN0cmxfcmVx LT53VmFsdWU7Cj4gKwo+ICsgICAgICAgcmV0dXJuIDA7Cj4gK30KPiArCj4gKy8qKgo+ICsgKiBj ZG5zM19lcDBfc3RhbmRhcmRfcmVxdWVzdCAtIEhhbmRsaW5nIHN0YW5kYXJkIFVTQiByZXF1ZXN0 cwo+ICsgKiBAcHJpdl9kZXY6IGV4dGVuZGVkIGdhZGdldCBvYmplY3QKPiArICogQGN0cmxfcmVx OiBwb2ludGVyIHRvIHJlY2VpdmVkIHNldHVwIHBhY2tldAo+ICsgKgo+ICsgKiBSZXR1cm5zIDAg aWYgc3VjY2VzcywgZXJyb3IgY29kZSBvbiBlcnJvcgo+ICsgKi8KPiArc3RhdGljIGludCBjZG5z M19lcDBfc3RhbmRhcmRfcmVxdWVzdChzdHJ1Y3QgY2RuczNfZGV2aWNlICpwcml2X2RldiwKPiAr ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cnVjdCB1c2JfY3RybHJlcXVl c3QgKmN0cmxfcmVxKQo+ICt7Cj4gKyAgICAgICBpbnQgcmV0Owo+ICsKPiArICAgICAgIHN3aXRj aCAoY3RybF9yZXEtPmJSZXF1ZXN0KSB7Cj4gKyAgICAgICBjYXNlIFVTQl9SRVFfU0VUX0FERFJF U1M6Cj4gKyAgICAgICAgICAgICAgIHJldCA9IGNkbnMzX3JlcV9lcDBfc2V0X2FkZHJlc3MocHJp dl9kZXYsIGN0cmxfcmVxKTsKPiArICAgICAgICAgICAgICAgYnJlYWs7Cj4gKyAgICAgICBjYXNl IFVTQl9SRVFfU0VUX0NPTkZJR1VSQVRJT046Cj4gKyAgICAgICAgICAgICAgIHJldCA9IGNkbnMz X3JlcV9lcDBfc2V0X2NvbmZpZ3VyYXRpb24ocHJpdl9kZXYsIGN0cmxfcmVxKTsKPiArICAgICAg ICAgICAgICAgYnJlYWs7Cj4gKyAgICAgICBjYXNlIFVTQl9SRVFfR0VUX1NUQVRVUzoKPiArICAg ICAgICAgICAgICAgcmV0ID0gY2RuczNfcmVxX2VwMF9nZXRfc3RhdHVzKHByaXZfZGV2LCBjdHJs X3JlcSk7Cj4gKyAgICAgICAgICAgICAgIGJyZWFrOwo+ICsgICAgICAgY2FzZSBVU0JfUkVRX0NM RUFSX0ZFQVRVUkU6Cj4gKyAgICAgICAgICAgICAgIHJldCA9IGNkbnMzX3JlcV9lcDBfaGFuZGxl X2ZlYXR1cmUocHJpdl9kZXYsIGN0cmxfcmVxLCAwKTsKPiArICAgICAgICAgICAgICAgYnJlYWs7 Cj4gKyAgICAgICBjYXNlIFVTQl9SRVFfU0VUX0ZFQVRVUkU6Cj4gKyAgICAgICAgICAgICAgIHJl dCA9IGNkbnMzX3JlcV9lcDBfaGFuZGxlX2ZlYXR1cmUocHJpdl9kZXYsIGN0cmxfcmVxLCAxKTsK PiArICAgICAgICAgICAgICAgYnJlYWs7Cj4gKyAgICAgICBjYXNlIFVTQl9SRVFfU0VUX1NFTDoK PiArICAgICAgICAgICAgICAgcmV0ID0gY2RuczNfcmVxX2VwMF9zZXRfc2VsKHByaXZfZGV2LCBj dHJsX3JlcSk7Cj4gKyAgICAgICAgICAgICAgIGJyZWFrOwo+ICsgICAgICAgY2FzZSBVU0JfUkVR X1NFVF9JU09DSF9ERUxBWToKPiArICAgICAgICAgICAgICAgcmV0ID0gY2RuczNfcmVxX2VwMF9z ZXRfaXNvY2hfZGVsYXkocHJpdl9kZXYsIGN0cmxfcmVxKTsKPiArICAgICAgICAgICAgICAgYnJl YWs7Cj4gKyAgICAgICBkZWZhdWx0Ogo+ICsgICAgICAgICAgICAgICByZXQgPSBjZG5zM19lcDBf ZGVsZWdhdGVfcmVxKHByaXZfZGV2LCBjdHJsX3JlcSk7Cj4gKyAgICAgICAgICAgICAgIGJyZWFr Owo+ICsgICAgICAgfQo+ICsKPiArICAgICAgIHJldHVybiByZXQ7Cj4gK30KPiArCj4gK3N0YXRp YyB2b2lkIF9fcGVuZGluZ19zZXR1cF9zdGF0dXNfaGFuZGxlcihzdHJ1Y3QgY2RuczNfZGV2aWNl ICpwcml2X2RldikKPiArewo+ICsgICAgICAgc3RydWN0IHVzYl9yZXF1ZXN0ICpyZXF1ZXN0ID0g cHJpdl9kZXYtPnBlbmRpbmdfc3RhdHVzX3JlcXVlc3Q7Cj4gKwo+ICsgICAgICAgaWYgKHByaXZf ZGV2LT5zdGF0dXNfY29tcGxldGlvbl9ub19jYWxsICYmIHJlcXVlc3QgJiYKPiArICAgICAgICAg ICByZXF1ZXN0LT5jb21wbGV0ZSkgewo+ICsgICAgICAgICAgICAgICByZXF1ZXN0LT5jb21wbGV0 ZSgmcHJpdl9kZXYtPmVwc1swXS0+ZW5kcG9pbnQsIHJlcXVlc3QpOwo+ICsgICAgICAgICAgICAg ICBwcml2X2Rldi0+c3RhdHVzX2NvbXBsZXRpb25fbm9fY2FsbCA9IDA7Cj4gKyAgICAgICB9Cj4g K30KPiArCj4gK3ZvaWQgY2RuczNfcGVuZGluZ19zZXR1cF9zdGF0dXNfaGFuZGxlcihzdHJ1Y3Qg d29ya19zdHJ1Y3QgKndvcmspCj4gK3sKPiArICAgICAgIHN0cnVjdCBjZG5zM19kZXZpY2UgKnBy aXZfZGV2ID0gY29udGFpbmVyX29mKHdvcmssIHN0cnVjdCBjZG5zM19kZXZpY2UsCj4gKyAgICAg ICAgICAgICAgICAgICAgICAgcGVuZGluZ19zdGF0dXNfd3EpOwo+ICsgICAgICAgdW5zaWduZWQg bG9uZyBmbGFnczsKPiArCj4gKyAgICAgICBzcGluX2xvY2tfaXJxc2F2ZSgmcHJpdl9kZXYtPmxv Y2ssIGZsYWdzKTsKPiArICAgICAgIF9fcGVuZGluZ19zZXR1cF9zdGF0dXNfaGFuZGxlcihwcml2 X2Rldik7Cj4gKyAgICAgICBzcGluX3VubG9ja19pcnFyZXN0b3JlKCZwcml2X2Rldi0+bG9jaywg ZmxhZ3MpOwo+ICt9Cj4gKwo+ICsvKioKPiArICogY2RuczNfZ2FkZ2V0X2VwX2dpdmViYWNrIC0g Y2FsbCBzdHJ1Y3QgdXNiX3JlcXVlc3QncyAtPmNvbXBsZXRlIGNhbGxiYWNrCj4gKyAqIEBwcml2 X2VwOiBUaGUgZW5kcG9pbnQgdG8gd2hvbSB0aGUgcmVxdWVzdCBiZWxvbmdzIHRvCj4gKyAqIEBw cml2X3JlcTogVGhlIHJlcXVlc3Qgd2UncmUgZ2l2aW5nIGJhY2sKPiArICogQHN0YXR1czogY29t cGxldGlvbiBjb2RlIGZvciB0aGUgcmVxdWVzdAo+ICsgKgo+ICsgKiBNdXN0IGJlIGNhbGxlZCB3 aXRoIGNvbnRyb2xsZXIncyBsb2NrIGhlbGQgYW5kIGludGVycnVwdHMgZGlzYWJsZWQuIFRoaXMK PiArICogZnVuY3Rpb24gd2lsbCB1bm1hcCBAcmVxIGFuZCBjYWxsIGl0cyAtPmNvbXBsZXRlKCkg Y2FsbGJhY2sgdG8gbm90aWZ5IHVwcGVyCj4gKyAqIGxheWVycyB0aGF0IGl0IGhhcyBjb21wbGV0 ZWQuCj4gKyAqLwo+ICsKPiArdm9pZCBjZG5zM19nYWRnZXRfZXAwX2dpdmViYWNrKHN0cnVjdCBj ZG5zM19kZXZpY2UgKnByaXZfZGV2LAo+ICsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBp bnQgc3RhdHVzKQo+ICt7Cj4gKyAgICAgICBzdHJ1Y3QgY2RuczNfZW5kcG9pbnQgKnByaXZfZXA7 Cj4gKyAgICAgICBzdHJ1Y3QgdXNiX3JlcXVlc3QgKnJlcXVlc3Q7Cj4gKwo+ICsgICAgICAgcHJp dl9lcCA9IHByaXZfZGV2LT5lcHNbMF07Cj4gKyAgICAgICByZXF1ZXN0ID0gY2RuczNfbmV4dF9y ZXF1ZXN0KCZwcml2X2VwLT5wZW5kaW5nX3JlcV9saXN0KTsKPiArCj4gKyAgICAgICBwcml2X2Vw LT5kaXIgPSBwcml2X2Rldi0+ZXAwX2RhdGFfZGlyOwo+ICsgICAgICAgY2RuczNfZ2FkZ2V0X2dp dmViYWNrKHByaXZfZXAsIHRvX2NkbnMzX3JlcXVlc3QocmVxdWVzdCksIHN0YXR1cyk7Cj4gK30K PiArCj4gKy8qKgo+ICsgKiBjZG5zM19lcDBfc2V0dXBfcGhhc2UgLSBIYW5kbGluZyBzZXR1cCBV U0IgcmVxdWVzdHMKPiArICogQHByaXZfZGV2OiBleHRlbmRlZCBnYWRnZXQgb2JqZWN0Cj4gKyAq Lwo+ICtzdGF0aWMgdm9pZCBjZG5zM19lcDBfc2V0dXBfcGhhc2Uoc3RydWN0IGNkbnMzX2Rldmlj ZSAqcHJpdl9kZXYpCj4gK3sKPiArICAgICAgIHN0cnVjdCB1c2JfY3RybHJlcXVlc3QgKmN0cmwg PSBwcml2X2Rldi0+c2V0dXBfYnVmOwo+ICsgICAgICAgc3RydWN0IGNkbnMzX2VuZHBvaW50ICpw cml2X2VwID0gcHJpdl9kZXYtPmVwc1swXTsKPiArICAgICAgIGludCByZXN1bHQ7Cj4gKwo+ICsg ICAgICAgcHJpdl9kZXYtPmVwMF9kYXRhX2RpciA9IGN0cmwtPmJSZXF1ZXN0VHlwZSAmIFVTQl9E SVJfSU47Cj4gKwo+ICsgICAgICAgdHJhY2VfY2RuczNfY3RybF9yZXEoY3RybCk7Cj4gKwo+ICsg ICAgICAgaWYgKCFsaXN0X2VtcHR5KCZwcml2X2VwLT5wZW5kaW5nX3JlcV9saXN0KSkgewo+ICsg ICAgICAgICAgICAgICBzdHJ1Y3QgdXNiX3JlcXVlc3QgKnJlcXVlc3Q7Cj4gKwo+ICsgICAgICAg ICAgICAgICByZXF1ZXN0ID0gY2RuczNfbmV4dF9yZXF1ZXN0KCZwcml2X2VwLT5wZW5kaW5nX3Jl cV9saXN0KTsKPiArICAgICAgICAgICAgICAgcHJpdl9lcC0+ZGlyID0gcHJpdl9kZXYtPmVwMF9k YXRhX2RpcjsKPiArICAgICAgICAgICAgICAgY2RuczNfZ2FkZ2V0X2dpdmViYWNrKHByaXZfZXAs IHRvX2NkbnMzX3JlcXVlc3QocmVxdWVzdCksCj4gKyAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAtRUNPTk5SRVNFVCk7Cj4gKyAgICAgICB9Cj4gKwo+ICsgICAgICAgaWYgKGxl MTZfdG9fY3B1KGN0cmwtPndMZW5ndGgpKQo+ICsgICAgICAgICAgICAgICBwcml2X2Rldi0+ZXAw X3N0YWdlID0gQ0ROUzNfREFUQV9TVEFHRTsKPiArICAgICAgIGVsc2UKPiArICAgICAgICAgICAg ICAgcHJpdl9kZXYtPmVwMF9zdGFnZSA9IENETlMzX1NUQVRVU19TVEFHRTsKPiArCj4gKyAgICAg ICBpZiAoKGN0cmwtPmJSZXF1ZXN0VHlwZSAmIFVTQl9UWVBFX01BU0spID09IFVTQl9UWVBFX1NU QU5EQVJEKQo+ICsgICAgICAgICAgICAgICByZXN1bHQgPSBjZG5zM19lcDBfc3RhbmRhcmRfcmVx dWVzdChwcml2X2RldiwgY3RybCk7Cj4gKyAgICAgICBlbHNlCj4gKyAgICAgICAgICAgICAgIHJl c3VsdCA9IGNkbnMzX2VwMF9kZWxlZ2F0ZV9yZXEocHJpdl9kZXYsIGN0cmwpOwo+ICsKPiArICAg ICAgIGlmIChyZXN1bHQgPT0gVVNCX0dBREdFVF9ERUxBWUVEX1NUQVRVUykKPiArICAgICAgICAg ICAgICAgcmV0dXJuOwo+ICsKPiArICAgICAgIGlmIChyZXN1bHQgPCAwKQo+ICsgICAgICAgICAg ICAgICBjZG5zM19lcDBfY29tcGxldGVfc2V0dXAocHJpdl9kZXYsIDEsIDEpOwo+ICsgICAgICAg ZWxzZSBpZiAocHJpdl9kZXYtPmVwMF9zdGFnZSA9PSBDRE5TM19TVEFUVVNfU1RBR0UpCj4gKyAg ICAgICAgICAgICAgIGNkbnMzX2VwMF9jb21wbGV0ZV9zZXR1cChwcml2X2RldiwgMCwgMSk7Cj4g K30KPiArCj4gK3N0YXRpYyB2b2lkIGNkbnMzX3RyYW5zZmVyX2NvbXBsZXRlZChzdHJ1Y3QgY2Ru czNfZGV2aWNlICpwcml2X2RldikKPiArewo+ICsgICAgICAgc3RydWN0IGNkbnMzX2VuZHBvaW50 ICpwcml2X2VwID0gcHJpdl9kZXYtPmVwc1swXTsKPiArCj4gKyAgICAgICBpZiAoIWxpc3RfZW1w dHkoJnByaXZfZXAtPnBlbmRpbmdfcmVxX2xpc3QpKSB7Cj4gKyAgICAgICAgICAgICAgIHN0cnVj dCB1c2JfcmVxdWVzdCAqcmVxdWVzdDsKPiArCj4gKyAgICAgICAgICAgICAgIHRyYWNlX2NkbnMz X2NvbXBsZXRlX3RyYihwcml2X2VwLCBwcml2X2VwLT50cmJfcG9vbCk7Cj4gKyAgICAgICAgICAg ICAgIHJlcXVlc3QgPSBjZG5zM19uZXh0X3JlcXVlc3QoJnByaXZfZXAtPnBlbmRpbmdfcmVxX2xp c3QpOwo+ICsKPiArICAgICAgICAgICAgICAgcmVxdWVzdC0+YWN0dWFsID0KPiArICAgICAgICAg ICAgICAgICAgICAgICBUUkJfTEVOKGxlMzJfdG9fY3B1KHByaXZfZXAtPnRyYl9wb29sLT5sZW5n dGgpKTsKPiArCj4gKyAgICAgICAgICAgICAgIHByaXZfZXAtPmRpciA9IHByaXZfZGV2LT5lcDBf ZGF0YV9kaXI7Cj4gKyAgICAgICAgICAgICAgIGNkbnMzX2dhZGdldF9naXZlYmFjayhwcml2X2Vw LCB0b19jZG5zM19yZXF1ZXN0KHJlcXVlc3QpLCAwKTsKPiArICAgICAgIH0KPiArCj4gKyAgICAg ICBjZG5zM19lcDBfY29tcGxldGVfc2V0dXAocHJpdl9kZXYsIDAsIDApOwo+ICt9Cj4gKwo+ICsv KioKPiArICogY2RuczNfY2hlY2tfbmV3X3NldHVwIC0gQ2hlY2sgaWYgY29udHJvbGxlciByZWNl aXZlIG5ldyBTRVRVUCBwYWNrZXQuCj4gKyAqIEBwcml2X2RldjogZXh0ZW5kZWQgZ2FkZ2V0IG9i amVjdAo+ICsgKgo+ICsgKiBUaGUgU0VUVVAgcGFja2V0IGNhbiBiZSBrZXB0IGluIG9uLWNoaXAg bWVtb3J5IG9yIGluIHN5c3RlbSBtZW1vcnkuCj4gKyAqLwo+ICtzdGF0aWMgYm9vbCBjZG5zM19j aGVja19uZXdfc2V0dXAoc3RydWN0IGNkbnMzX2RldmljZSAqcHJpdl9kZXYpCj4gK3sKPiArICAg ICAgIHUzMiBlcF9zdHNfcmVnOwo+ICsKPiArICAgICAgIGNkbnMzX3NlbGVjdF9lcChwcml2X2Rl diwgMCB8IFVTQl9ESVJfT1VUKTsKPiArICAgICAgIGVwX3N0c19yZWcgPSByZWFkbCgmcHJpdl9k ZXYtPnJlZ3MtPmVwX3N0cyk7Cj4gKwo+ICsgICAgICAgcmV0dXJuICEhKGVwX3N0c19yZWcgJiAo RVBfU1RTX1NFVFVQIHwgRVBfU1RTX1NUUFdBSVQpKTsKPiArfQo+ICsKPiArLyoqCj4gKyAqIGNk bnMzX2NoZWNrX2VwMF9pbnRlcnJ1cHRfcHJvY2VlZCAtIFByb2Nlc3NlcyBpbnRlcnJ1cHQgcmVs YXRlZCB0byBlbmRwb2ludCAwCj4gKyAqIEBwcml2X2RldjogZXh0ZW5kZWQgZ2FkZ2V0IG9iamVj dAo+ICsgKiBAZGlyOiBVU0JfRElSX0lOIGZvciBJTiBkaXJlY3Rpb24sIFVTQl9ESVJfT1VUIGZv ciBPVVQgZGlyZWN0aW9uCj4gKyAqLwo+ICt2b2lkIGNkbnMzX2NoZWNrX2VwMF9pbnRlcnJ1cHRf cHJvY2VlZChzdHJ1Y3QgY2RuczNfZGV2aWNlICpwcml2X2RldiwgaW50IGRpcikKPiArewo+ICsg ICAgICAgdTMyIGVwX3N0c19yZWc7Cj4gKwo+ICsgICAgICAgY2RuczNfc2VsZWN0X2VwKHByaXZf ZGV2LCBkaXIpOwo+ICsKPiArICAgICAgIGVwX3N0c19yZWcgPSByZWFkbCgmcHJpdl9kZXYtPnJl Z3MtPmVwX3N0cyk7Cj4gKyAgICAgICB3cml0ZWwoZXBfc3RzX3JlZywgJnByaXZfZGV2LT5yZWdz LT5lcF9zdHMpOwo+ICsKPiArICAgICAgIHRyYWNlX2NkbnMzX2VwMF9pcnEocHJpdl9kZXYsIGVw X3N0c19yZWcpOwo+ICsKPiArICAgICAgIF9fcGVuZGluZ19zZXR1cF9zdGF0dXNfaGFuZGxlcihw cml2X2Rldik7Cj4gKwo+ICsgICAgICAgaWYgKChlcF9zdHNfcmVnICYgRVBfU1RTX1NFVFVQKSkg ewo+ICsgICAgICAgICAgICAgICBjZG5zM19lcDBfc2V0dXBfcGhhc2UocHJpdl9kZXYpOwo+ICsg ICAgICAgfSBlbHNlIGlmICgoZXBfc3RzX3JlZyAmIEVQX1NUU19JT0MpIHx8IChlcF9zdHNfcmVn ICYgRVBfU1RTX0lTUCkpIHsKPiArICAgICAgICAgICAgICAgcHJpdl9kZXYtPmVwMF9kYXRhX2Rp ciA9IGRpcjsKPiArICAgICAgICAgICAgICAgY2RuczNfdHJhbnNmZXJfY29tcGxldGVkKHByaXZf ZGV2KTsKPiArICAgICAgIH0KPiArCj4gKyAgICAgICBpZiAoZXBfc3RzX3JlZyAmIEVQX1NUU19E RVNDTUlTKSB7Cj4gKyAgICAgICAgICAgICAgIGlmIChkaXIgPT0gMCAmJiAhcHJpdl9kZXYtPnNl dHVwX3BlbmRpbmcpCj4gKyAgICAgICAgICAgICAgICAgICAgICAgY2RuczNfcHJlcGFyZV9zZXR1 cF9wYWNrZXQocHJpdl9kZXYpOwo+ICsgICAgICAgfQo+ICt9Cj4gKwo+ICsvKioKPiArICogY2Ru czNfZ2FkZ2V0X2VwMF9lbmFibGUKPiArICogRnVuY3Rpb24gc2hvdWxkbid0IGJlIGNhbGxlZCBi eSBnYWRnZXQgZHJpdmVyLAo+ICsgKiBlbmRwb2ludCAwIGlzIGFsbHdheXMgYWN0aXZlCj4gKyAq Lwo+ICtzdGF0aWMgaW50IGNkbnMzX2dhZGdldF9lcDBfZW5hYmxlKHN0cnVjdCB1c2JfZXAgKmVw LAo+ICsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RydWN0IHVzYl9l bmRwb2ludF9kZXNjcmlwdG9yICpkZXNjKQo+ICt7Cj4gKyAgICAgICByZXR1cm4gLUVJTlZBTDsK PiArfQo+ICsKPiArLyoqCj4gKyAqIGNkbnMzX2dhZGdldF9lcDBfZGlzYWJsZQo+ICsgKiBGdW5j dGlvbiBzaG91bGRuJ3QgYmUgY2FsbGVkIGJ5IGdhZGdldCBkcml2ZXIsCj4gKyAqIGVuZHBvaW50 IDAgaXMgYWxsd2F5cyBhY3RpdmUKPiArICovCj4gK3N0YXRpYyBpbnQgY2RuczNfZ2FkZ2V0X2Vw MF9kaXNhYmxlKHN0cnVjdCB1c2JfZXAgKmVwKQo+ICt7Cj4gKyAgICAgICByZXR1cm4gLUVJTlZB TDsKPiArfQo+ICsKPiArLyoqCj4gKyAqIGNkbnMzX2dhZGdldF9lcDBfc2V0X2hhbHQKPiArICog QGVwOiBwb2ludGVyIHRvIGVuZHBvaW50IHplcm8gb2JqZWN0Cj4gKyAqIEB2YWx1ZTogMSBmb3Ig c2V0IHN0YWxsLCAwIGZvciBjbGVhciBzdGFsbAo+ICsgKgo+ICsgKiBSZXR1cm5zIDAKPiArICov Cj4gK3N0YXRpYyBpbnQgY2RuczNfZ2FkZ2V0X2VwMF9zZXRfaGFsdChzdHJ1Y3QgdXNiX2VwICpl cCwgaW50IHZhbHVlKQo+ICt7Cj4gKyAgICAgICAvKiBUT0RPICovCj4gKyAgICAgICByZXR1cm4g MDsKPiArfQo+ICsKPiArLyoqCj4gKyAqIGNkbnMzX2dhZGdldF9lcDBfcXVldWUgVHJhbnNmZXIg ZGF0YSBvbiBlbmRwb2ludCB6ZXJvCj4gKyAqIEBlcDogcG9pbnRlciB0byBlbmRwb2ludCB6ZXJv IG9iamVjdAo+ICsgKiBAcmVxdWVzdDogcG9pbnRlciB0byByZXF1ZXN0IG9iamVjdAo+ICsgKiBA Z2ZwX2ZsYWdzOiBnZnAgZmxhZ3MKPiArICoKPiArICogUmV0dXJucyAwIG9uIHN1Y2Nlc3MsIGVy cm9yIGNvZGUgZWxzZXdoZXJlCj4gKyAqLwo+ICtzdGF0aWMgaW50IGNkbnMzX2dhZGdldF9lcDBf cXVldWUoc3RydWN0IHVzYl9lcCAqZXAsCj4gKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgIHN0cnVjdCB1c2JfcmVxdWVzdCAqcmVxdWVzdCwKPiArICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgZ2ZwX3QgZ2ZwX2ZsYWdzKQo+ICt7Cj4gKyAgICAgICBzdHJ1Y3QgY2RuczNf ZW5kcG9pbnQgKnByaXZfZXAgPSBlcF90b19jZG5zM19lcChlcCk7Cj4gKyAgICAgICBzdHJ1Y3Qg Y2RuczNfZGV2aWNlICpwcml2X2RldiA9IHByaXZfZXAtPmNkbnMzX2RldjsKPiArICAgICAgIHVu c2lnbmVkIGxvbmcgZmxhZ3M7Cj4gKyAgICAgICBpbnQgZXJkeV9zZW50ID0gMDsKPiArICAgICAg IGludCByZXQgPSAwOwo+ICsKPiArICAgICAgIGNkbnMzX2RiZyhwcml2X2VwLT5jZG5zM19kZXYs ICJRdWV1ZSB0byBFcDAlcyBMOiAlZFxuIiwKPiArICAgICAgICAgICAgICAgICBwcml2X2Rldi0+ ZXAwX2RhdGFfZGlyID8gIklOIiA6ICJPVVQiLAo+ICsgICAgICAgICAgICAgICAgIHJlcXVlc3Qt Pmxlbmd0aCk7Cj4gKwo+ICsgICAgICAgLyogY2FuY2VsIHRoZSByZXF1ZXN0IGlmIGNvbnRyb2xs ZXIgcmVjZWl2ZSBuZXcgU0VUVVAgcGFja2V0LiAqLwo+ICsgICAgICAgaWYgKGNkbnMzX2NoZWNr X25ld19zZXR1cChwcml2X2RldikpCj4gKyAgICAgICAgICAgICAgIHJldHVybiAtRUNPTk5SRVNF VDsKPiArCj4gKyAgICAgICAvKiBzZW5kIFNUQVRVUyBzdGFnZS4gU2hvdWxkIGJlIGNhbGxlZCBv bmx5IGZvciBTRVRfQ09ORklHVVJBVElPTiAqLwo+ICsgICAgICAgaWYgKHByaXZfZGV2LT5lcDBf c3RhZ2UgPT0gQ0ROUzNfU1RBVFVTX1NUQUdFKSB7Cj4gKyAgICAgICAgICAgICAgIHNwaW5fbG9j a19pcnFzYXZlKCZwcml2X2Rldi0+bG9jaywgZmxhZ3MpOwo+ICsgICAgICAgICAgICAgICBjZG5z M19zZWxlY3RfZXAocHJpdl9kZXYsIDB4MDApOwo+ICsKPiArICAgICAgICAgICAgICAgZXJkeV9z ZW50ID0gIXByaXZfZGV2LT5od19jb25maWd1cmVkX2ZsYWc7Cj4gKyAgICAgICAgICAgICAgIGNk bnMzX3NldF9od19jb25maWd1cmF0aW9uKHByaXZfZGV2KTsKPiArCj4gKyAgICAgICAgICAgICAg IGlmICghZXJkeV9zZW50KQo+ICsgICAgICAgICAgICAgICAgICAgICAgIGNkbnMzX2VwMF9jb21w bGV0ZV9zZXR1cChwcml2X2RldiwgMCwgMSk7Cj4gKwo+ICsgICAgICAgICAgICAgICByZXF1ZXN0 LT5hY3R1YWwgPSAwOwo+ICsgICAgICAgICAgICAgICBwcml2X2Rldi0+c3RhdHVzX2NvbXBsZXRp b25fbm9fY2FsbCA9IHRydWU7Cj4gKyAgICAgICAgICAgICAgIHByaXZfZGV2LT5wZW5kaW5nX3N0 YXR1c19yZXF1ZXN0ID0gcmVxdWVzdDsKPiArICAgICAgICAgICAgICAgc3Bpbl91bmxvY2tfaXJx cmVzdG9yZSgmcHJpdl9kZXYtPmxvY2ssIGZsYWdzKTsKPiArCj4gKyAgICAgICAgICAgICAgIC8q Cj4gKyAgICAgICAgICAgICAgICAqIFNpbmNlIHRoZXJlIGlzIG5vIGNvbXBsZXRpb24gaW50ZXJy dXB0IGZvciBzdGF0dXMgc3RhZ2UsCj4gKyAgICAgICAgICAgICAgICAqIGl0IG5lZWRzIHRvIGNh bGwgLT5jb21wbGV0aW9uIGluIHNvZnR3YXJlIGFmdGVyCj4gKyAgICAgICAgICAgICAgICAqIGVw MF9xdWV1ZSBpcyBiYWNrLgo+ICsgICAgICAgICAgICAgICAgKi8KPiArICAgICAgICAgICAgICAg cXVldWVfd29yayhzeXN0ZW1fZnJlZXphYmxlX3dxLCAmcHJpdl9kZXYtPnBlbmRpbmdfc3RhdHVz X3dxKTsKPiArICAgICAgICAgICAgICAgcmV0dXJuIDA7Cj4gKyAgICAgICB9Cj4gKwo+ICsgICAg ICAgc3Bpbl9sb2NrX2lycXNhdmUoJnByaXZfZGV2LT5sb2NrLCBmbGFncyk7Cj4gKyAgICAgICBp ZiAoIWxpc3RfZW1wdHkoJnByaXZfZXAtPnBlbmRpbmdfcmVxX2xpc3QpKSB7Cj4gKyAgICAgICAg ICAgICAgIGRldl9lcnIocHJpdl9kZXYtPmRldiwKPiArICAgICAgICAgICAgICAgICAgICAgICAi Y2FuJ3QgaGFuZGxlIG11bHRpcGxlIHJlcXVlc3RzIGZvciBlcDBcbiIpOwo+ICsgICAgICAgICAg ICAgICBzcGluX3VubG9ja19pcnFyZXN0b3JlKCZwcml2X2Rldi0+bG9jaywgZmxhZ3MpOwo+ICsg ICAgICAgICAgICAgICByZXR1cm4gLUVCVVNZOwo+ICsgICAgICAgfQo+ICsKPiArICAgICAgIHJl dCA9IHVzYl9nYWRnZXRfbWFwX3JlcXVlc3RfYnlfZGV2KHByaXZfZGV2LT5zeXNkZXYsIHJlcXVl c3QsCj4gKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcml2X2Rl di0+ZXAwX2RhdGFfZGlyKTsKPiArICAgICAgIGlmIChyZXQpIHsKPiArICAgICAgICAgICAgICAg c3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmcHJpdl9kZXYtPmxvY2ssIGZsYWdzKTsKPiArICAgICAg ICAgICAgICAgZGV2X2Vycihwcml2X2Rldi0+ZGV2LCAiZmFpbGVkIHRvIG1hcCByZXF1ZXN0XG4i KTsKPiArICAgICAgICAgICAgICAgcmV0dXJuIC1FSU5WQUw7Cj4gKyAgICAgICB9Cj4gKwo+ICsg ICAgICAgcmVxdWVzdC0+c3RhdHVzID0gLUVJTlBST0dSRVNTOwo+ICsgICAgICAgbGlzdF9hZGRf dGFpbCgmcmVxdWVzdC0+bGlzdCwgJnByaXZfZXAtPnBlbmRpbmdfcmVxX2xpc3QpOwo+ICsgICAg ICAgY2RuczNfZXAwX3J1bl90cmFuc2Zlcihwcml2X2RldiwgcmVxdWVzdC0+ZG1hLCByZXF1ZXN0 LT5sZW5ndGgsIDEpOwo+ICsgICAgICAgc3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmcHJpdl9kZXYt PmxvY2ssIGZsYWdzKTsKPiArCj4gKyAgICAgICByZXR1cm4gcmV0Owo+ICt9Cj4gKwo+ICsvKioK PiArICogY2RuczNfZ2FkZ2V0X2VwX3NldF93ZWRnZSBTZXQgd2VkZ2Ugb24gc2VsZWN0ZWQgZW5k cG9pbnQKPiArICogQGVwOiBlbmRwb2ludCBvYmplY3QKPiArICoKPiArICogUmV0dXJucyAwCj4g KyAqLwo+ICtpbnQgY2RuczNfZ2FkZ2V0X2VwX3NldF93ZWRnZShzdHJ1Y3QgdXNiX2VwICplcCkK PiArewo+ICsgICAgICAgc3RydWN0IGNkbnMzX2VuZHBvaW50ICpwcml2X2VwID0gZXBfdG9fY2Ru czNfZXAoZXApOwo+ICsgICAgICAgc3RydWN0IGNkbnMzX2RldmljZSAqcHJpdl9kZXYgPSBwcml2 X2VwLT5jZG5zM19kZXY7Cj4gKwo+ICsgICAgICAgZGV2X2RiZyhwcml2X2Rldi0+ZGV2LCAiV2Vk Z2UgZm9yICVzXG4iLCBlcC0+bmFtZSk7Cj4gKyAgICAgICBjZG5zM19nYWRnZXRfZXBfc2V0X2hh bHQoZXAsIDEpOwo+ICsgICAgICAgcHJpdl9lcC0+ZmxhZ3MgfD0gRVBfV0VER0U7Cj4gKwo+ICsg ICAgICAgcmV0dXJuIDA7Cj4gK30KPiArCj4gK2NvbnN0IHN0cnVjdCB1c2JfZXBfb3BzIGNkbnMz X2dhZGdldF9lcDBfb3BzID0gewo+ICsgICAgICAgLmVuYWJsZSA9IGNkbnMzX2dhZGdldF9lcDBf ZW5hYmxlLAo+ICsgICAgICAgLmRpc2FibGUgPSBjZG5zM19nYWRnZXRfZXAwX2Rpc2FibGUsCj4g KyAgICAgICAuYWxsb2NfcmVxdWVzdCA9IGNkbnMzX2dhZGdldF9lcF9hbGxvY19yZXF1ZXN0LAo+ ICsgICAgICAgLmZyZWVfcmVxdWVzdCA9IGNkbnMzX2dhZGdldF9lcF9mcmVlX3JlcXVlc3QsCj4g KyAgICAgICAucXVldWUgPSBjZG5zM19nYWRnZXRfZXAwX3F1ZXVlLAo+ICsgICAgICAgLmRlcXVl dWUgPSBjZG5zM19nYWRnZXRfZXBfZGVxdWV1ZSwKPiArICAgICAgIC5zZXRfaGFsdCA9IGNkbnMz X2dhZGdldF9lcDBfc2V0X2hhbHQsCj4gKyAgICAgICAuc2V0X3dlZGdlID0gY2RuczNfZ2FkZ2V0 X2VwX3NldF93ZWRnZSwKPiArfTsKPiArCj4gKy8qKgo+ICsgKiBjZG5zM19lcDBfY29uZmlnIC0g Q29uZmlndXJlcyBkZWZhdWx0IGVuZHBvaW50Cj4gKyAqIEBwcml2X2RldjogZXh0ZW5kZWQgZ2Fk Z2V0IG9iamVjdAo+ICsgKgo+ICsgKiBGdW5jdGlvbnMgc2V0cyBwYXJhbWV0ZXJzOiBtYXhpbWFs IHBhY2tldCBzaXplIGFuZCBlbmFibGVzIGludGVycnVwdHMKPiArICovCj4gK3ZvaWQgY2RuczNf ZXAwX2NvbmZpZyhzdHJ1Y3QgY2RuczNfZGV2aWNlICpwcml2X2RldikKPiArewo+ICsgICAgICAg c3RydWN0IGNkbnMzX3VzYl9yZWdzIF9faW9tZW0gKnJlZ3M7Cj4gKyAgICAgICBzdHJ1Y3QgY2Ru czNfZW5kcG9pbnQgKnByaXZfZXA7Cj4gKyAgICAgICB1MzIgbWF4X3BhY2tldF9zaXplID0gNjQ7 Cj4gKwo+ICsgICAgICAgcmVncyA9IHByaXZfZGV2LT5yZWdzOwo+ICsKPiArICAgICAgIGlmIChw cml2X2Rldi0+Z2FkZ2V0LnNwZWVkID09IFVTQl9TUEVFRF9TVVBFUikKPiArICAgICAgICAgICAg ICAgbWF4X3BhY2tldF9zaXplID0gNTEyOwo+ICsKPiArICAgICAgIHByaXZfZXAgPSBwcml2X2Rl di0+ZXBzWzBdOwo+ICsKPiArICAgICAgIGlmICghbGlzdF9lbXB0eSgmcHJpdl9lcC0+cGVuZGlu Z19yZXFfbGlzdCkpIHsKPiArICAgICAgICAgICAgICAgc3RydWN0IHVzYl9yZXF1ZXN0ICpyZXF1 ZXN0Owo+ICsKPiArICAgICAgICAgICAgICAgcmVxdWVzdCA9IGNkbnMzX25leHRfcmVxdWVzdCgm cHJpdl9lcC0+cGVuZGluZ19yZXFfbGlzdCk7Cj4gKyAgICAgICAgICAgICAgIGxpc3RfZGVsX2lu aXQoJnJlcXVlc3QtPmxpc3QpOwo+ICsgICAgICAgfQo+ICsKPiArICAgICAgIHByaXZfZGV2LT51 MV9hbGxvd2VkID0gMDsKPiArICAgICAgIHByaXZfZGV2LT51Ml9hbGxvd2VkID0gMDsKPiArCj4g KyAgICAgICBwcml2X2Rldi0+Z2FkZ2V0LmVwMC0+bWF4cGFja2V0ID0gbWF4X3BhY2tldF9zaXpl Owo+ICsgICAgICAgY2RuczNfZ2FkZ2V0X2VwMF9kZXNjLndNYXhQYWNrZXRTaXplID0gY3B1X3Rv X2xlMTYobWF4X3BhY2tldF9zaXplKTsKPiArCj4gKyAgICAgICAvKiBpbml0IGVwIG91dCAqLwo+ ICsgICAgICAgY2RuczNfc2VsZWN0X2VwKHByaXZfZGV2LCBVU0JfRElSX09VVCk7Cj4gKwo+ICsg ICAgICAgd3JpdGVsKEVQX0NGR19FTkFCTEUgfCBFUF9DRkdfTUFYUEtUU0laRShtYXhfcGFja2V0 X3NpemUpLAo+ICsgICAgICAgICAgICAgICZyZWdzLT5lcF9jZmcpOwo+ICsKPiArICAgICAgIHdy aXRlbChFUF9TVFNfRU5fU0VUVVBFTiB8IEVQX1NUU19FTl9ERVNDTUlTRU4gfCBFUF9TVFNfRU5f VFJCRVJSRU4sCj4gKyAgICAgICAgICAgICAgJnJlZ3MtPmVwX3N0c19lbik7Cj4gKwo+ICsgICAg ICAgLyogaW5pdCBlcCBpbiAqLwo+ICsgICAgICAgY2RuczNfc2VsZWN0X2VwKHByaXZfZGV2LCBV U0JfRElSX0lOKTsKPiArCj4gKyAgICAgICB3cml0ZWwoRVBfQ0ZHX0VOQUJMRSB8IEVQX0NGR19N QVhQS1RTSVpFKG1heF9wYWNrZXRfc2l6ZSksCj4gKyAgICAgICAgICAgICAgJnJlZ3MtPmVwX2Nm Zyk7Cj4gKwo+ICsgICAgICAgd3JpdGVsKEVQX1NUU19FTl9TRVRVUEVOIHwgRVBfU1RTX0VOX1RS QkVSUkVOLCAmcmVncy0+ZXBfc3RzX2VuKTsKPiArCj4gKyAgICAgICBjZG5zM19zZXRfcmVnaXN0 ZXJfYml0KCZyZWdzLT51c2JfY29uZiwgVVNCX0NPTkZfVTFEUyB8IFVTQl9DT05GX1UyRFMpOwo+ ICt9Cj4gKwo+ICsvKioKPiArICogY2RuczNfaW5pdF9lcDAgSW5pdGlhbGl6ZXMgc29mdHdhcmUg ZW5kcG9pbnQgMCBvZiBnYWRnZXQKPiArICogQHByaXZfZGV2OiBleHRlbmRlZCBnYWRnZXQgb2Jq ZWN0Cj4gKyAqIEBlcF9wcml2OiBleHRlbmRlZCBlbmRwb2ludCBvYmplY3QKPiArICoKPiArICog UmV0dXJucyAwIG9uIHN1Y2Nlc3MgZWxzZSBlcnJvciBjb2RlLgo+ICsgKi8KPiAraW50IGNkbnMz X2luaXRfZXAwKHN0cnVjdCBjZG5zM19kZXZpY2UgKnByaXZfZGV2LAo+ICsgICAgICAgICAgICAg ICAgICBzdHJ1Y3QgY2RuczNfZW5kcG9pbnQgKnByaXZfZXApCj4gK3sKPiArICAgICAgIHNwcmlu dGYocHJpdl9lcC0+bmFtZSwgImVwMCIpOwo+ICsKPiArICAgICAgIC8qIGZpbGwgbGludXggZmll bGRzICovCj4gKyAgICAgICBwcml2X2VwLT5lbmRwb2ludC5vcHMgPSAmY2RuczNfZ2FkZ2V0X2Vw MF9vcHM7Cj4gKyAgICAgICBwcml2X2VwLT5lbmRwb2ludC5tYXhidXJzdCA9IDE7Cj4gKyAgICAg ICB1c2JfZXBfc2V0X21heHBhY2tldF9saW1pdCgmcHJpdl9lcC0+ZW5kcG9pbnQsCj4gKyAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDRE5TM19FUDBfTUFYX1BBQ0tFVF9MSU1JVCk7 Cj4gKyAgICAgICBwcml2X2VwLT5lbmRwb2ludC5hZGRyZXNzID0gMDsKPiArICAgICAgIHByaXZf ZXAtPmVuZHBvaW50LmNhcHMudHlwZV9jb250cm9sID0gMTsKPiArICAgICAgIHByaXZfZXAtPmVu ZHBvaW50LmNhcHMuZGlyX2luID0gMTsKPiArICAgICAgIHByaXZfZXAtPmVuZHBvaW50LmNhcHMu ZGlyX291dCA9IDE7Cj4gKyAgICAgICBwcml2X2VwLT5lbmRwb2ludC5uYW1lID0gcHJpdl9lcC0+ bmFtZTsKPiArICAgICAgIHByaXZfZXAtPmVuZHBvaW50LmRlc2MgPSAmY2RuczNfZ2FkZ2V0X2Vw MF9kZXNjOwo+ICsgICAgICAgcHJpdl9kZXYtPmdhZGdldC5lcDAgPSAmcHJpdl9lcC0+ZW5kcG9p bnQ7Cj4gKyAgICAgICBwcml2X2VwLT50eXBlID0gVVNCX0VORFBPSU5UX1hGRVJfQ09OVFJPTDsK PiArCj4gKyAgICAgICByZXR1cm4gY2RuczNfYWxsb2NhdGVfdHJiX3Bvb2wocHJpdl9lcCk7Cj4g K30KPiBkaWZmIC0tZ2l0IGEvZHJpdmVycy91c2IvY2RuczMvZ2FkZ2V0LWV4cG9ydC5oIGIvZHJp dmVycy91c2IvY2RuczMvZ2FkZ2V0LWV4cG9ydC5oCj4gbmV3IGZpbGUgbW9kZSAxMDA2NDQKPiBp bmRleCAwMDAwMDAwMDAwMDAuLjU3NzQ2OWVlZTk2MQo+IC0tLSAvZGV2L251bGwKPiArKysgYi9k cml2ZXJzL3VzYi9jZG5zMy9nYWRnZXQtZXhwb3J0LmgKPiBAQCAtMCwwICsxLDI4IEBACj4gKy8q IFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBHUEwtMi4wICovCj4gKy8qCj4gKyAqIENhZGVuY2Ug VVNCU1MgRFJEIERyaXZlciAtIEdhZGdldCBFeHBvcnQgQVBJcy4KPiArICoKPiArICogQ29weXJp Z2h0IChDKSAyMDE3IE5YUAo+ICsgKiBDb3B5cmlnaHQgKEMpIDIwMTctMjAxOCBOWFAKPiArICoK PiArICogQXV0aG9yczogUGV0ZXIgQ2hlbiA8cGV0ZXIuY2hlbkBueHAuY29tPgo+ICsgKi8KPiAr I2lmbmRlZiBfX0xJTlVYX0NETlMzX0dBREdFVF9FWFBPUlQKPiArI2RlZmluZSBfX0xJTlVYX0NE TlMzX0dBREdFVF9FWFBPUlQKPiArCj4gKyNpZmRlZiBDT05GSUdfVVNCX0NETlMzX0dBREdFVAo+ ICsKPiAraW50IGNkbnMzX2dhZGdldF9pbml0KHN0cnVjdCBjZG5zMyAqY2Rucyk7Cj4gK3ZvaWQg Y2RuczNfZ2FkZ2V0X2V4aXQoc3RydWN0IGNkbnMzICpjZG5zKTsKPiArI2Vsc2UKPiArCj4gK3N0 YXRpYyBpbmxpbmUgaW50IGNkbnMzX2dhZGdldF9pbml0KHN0cnVjdCBjZG5zMyAqY2RucykKPiAr ewo+ICsgICAgICAgcmV0dXJuIC1FTlhJTzsKPiArfQo+ICsKPiArc3RhdGljIGlubGluZSB2b2lk IGNkbnMzX2dhZGdldF9leGl0KHN0cnVjdCBjZG5zMyAqY2RucykgeyB9Cj4gKwo+ICsjZW5kaWYK PiArCj4gKyNlbmRpZiAvKiBfX0xJTlVYX0NETlMzX0dBREdFVF9FWFBPUlQgKi8KPiBkaWZmIC0t Z2l0IGEvZHJpdmVycy91c2IvY2RuczMvZ2FkZ2V0LmMgYi9kcml2ZXJzL3VzYi9jZG5zMy9nYWRn ZXQuYwo+IG5ldyBmaWxlIG1vZGUgMTAwNjQ0Cj4gaW5kZXggMDAwMDAwMDAwMDAwLi43ZjdmMjRl ZTNjNGIKPiAtLS0gL2Rldi9udWxsCj4gKysrIGIvZHJpdmVycy91c2IvY2RuczMvZ2FkZ2V0LmMK PiBAQCAtMCwwICsxLDIwMDMgQEAKPiArLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEdQTC0y LjAKPiArLyoKPiArICogQ2FkZW5jZSBVU0JTUyBEUkQgRHJpdmVyIC0gZ2FkZ2V0IHNpZGUuCj4g KyAqCj4gKyAqIENvcHlyaWdodCAoQykgMjAxOCBDYWRlbmNlIERlc2lnbiBTeXN0ZW1zLgo+ICsg KiBDb3B5cmlnaHQgKEMpIDIwMTctMjAxOCBOWFAKPiArICoKPiArICogQXV0aG9yczogUGF3ZWwg SmV6IDxwamV6QGNhZGVuY2UuY29tPiwKPiArICogICAgICAgICAgUGF3ZWwgTGFzemN6YWsgPHBh d2VsbEBjYWRlbmNlLmNvbT4KPiArICogICAgICAgICBQZXRlciBDaGVuIDxwZXRlci5jaGVuQG54 cC5jb20+Cj4gKyAqLwo+ICsKPiArLyoKPiArICogV29yayBhcm91bmQgMToKPiArICogQXQgc29t ZSBzaXR1YXRpb25zLCB0aGUgY29udHJvbGxlciBtYXkgZ2V0IHN0YWxlIGRhdGEgYWRkcmVzcyBp biBUUkIKPiArICogYXQgYmVsb3cgc2VxdWVuY2VzOgo+ICsgKiAxLiBDb250cm9sbGVyIHJlYWQg VFJCIGluY2x1ZGVzIGRhdGEgYWRkcmVzcwo+ICsgKiAyLiBTb2Z0d2FyZSB1cGRhdGVzIFRSQnMg aW5jbHVkZXMgZGF0YSBhZGRyZXNzIGFuZCBDeWNsZSBiaXQKPiArICogMy4gQ29udHJvbGxlciBy ZWFkIFRSQiB3aGljaCBpbmNsdWRlcyBDeWNsZSBiaXQKPiArICogNC4gRE1BIHJ1biB3aXRoIHN0 YWxlIGRhdGEgYWRkcmVzcwo+ICsKPiArICogVG8gZml4IHRoaXMgcHJvYmxlbSwgd2UgbmVlZCB0 byBtYWtlIHRoZSBmaXJzdCBUUkIgaW4gVEQgYXMgaW52YWxpZCBUUkIgd2hlbgo+ICsgKiB0aGUg VEQgd2hpY2ggdGhlIERNQSBpcyBoYW5kbGluZyBjbG9zZSB0byB0aGUgVFJCIHdlIGFyZSBhZGRp bmcsCj4gKyAqIGFuZCBtYWtlIHRoaXMgVFJCIGFzIHZhbGlkIGF0IFRSQkVSUiBpbnRlcnJ1cHQu IFRoZSBjb25kaXRpb24gZm9yCj4gKyAqIHRoaXMgVFJCIGlzOgo+ICsgKgo+ICsgKiBJZiAoKChE ZXF1ZXVlIFB0ciAoaS5lLiBFUF9UUkFERFIpID09IEVucXVldWUgUHRyLTEpIG9yCj4gKyAqICAg ICAoRGVxdWV1ZSBQdHIgKGkuZS4gRVBfVFJBRERSKSA9PSBFbnF1ZXVlIFB0cikpCj4gKyAqICAg ICAgICAgICAgIGFuZCAoRFJCTD09MSBhbmQgKG5vdCBFUDApKSkKPiArICovCj4gKwo+ICsjaW5j bHVkZSA8bGludXgvZG1hLW1hcHBpbmcuaD4KPiArI2luY2x1ZGUgPGxpbnV4L3VzYi9nYWRnZXQu aD4KPiArI2luY2x1ZGUgPGxpbnV4L21vZHVsZS5oPgo+ICsKPiArI2luY2x1ZGUgImNvcmUuaCIK PiArI2luY2x1ZGUgImdhZGdldC1leHBvcnQuaCIKPiArI2luY2x1ZGUgImdhZGdldC5oIgo+ICsj aW5jbHVkZSAidHJhY2UuaCIKPiArCj4gK3N0YXRpYyBpbnQgX19jZG5zM19nYWRnZXRfZXBfcXVl dWUoc3RydWN0IHVzYl9lcCAqZXAsCj4gKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICBzdHJ1Y3QgdXNiX3JlcXVlc3QgKnJlcXVlc3QsCj4gKyAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICBnZnBfdCBnZnBfZmxhZ3MpOwo+ICsKPiArLyoqCj4gKyAqIGNkbnMzX2hhbmRz aGFrZSAtIHNwaW4gcmVhZGluZyAgdW50aWwgaGFuZHNoYWtlIGNvbXBsZXRlcyBvciBmYWlscwo+ ICsgKiBAcHRyOiBhZGRyZXNzIG9mIGRldmljZSBjb250cm9sbGVyIHJlZ2lzdGVyIHRvIGJlIHJl YWQKPiArICogQG1hc2s6IGJpdHMgdG8gbG9vayBhdCBpbiByZXN1bHQgb2YgcmVhZAo+ICsgKiBA ZG9uZTogdmFsdWUgb2YgdGhvc2UgYml0cyB3aGVuIGhhbmRzaGFrZSBzdWNjZWVkcwo+ICsgKiBA dXNlYzogdGltZW91dCBpbiBtaWNyb3NlY29uZHMKPiArICoKPiArICogUmV0dXJucyBuZWdhdGl2 ZSBlcnJubywgb3IgemVybyBvbiBzdWNjZXNzCj4gKyAqCj4gKyAqIFN1Y2Nlc3MgaGFwcGVucyB3 aGVuIHRoZSAibWFzayIgYml0cyBoYXZlIHRoZSBzcGVjaWZpZWQgdmFsdWUgKGhhcmR3YXJlCj4g KyAqIGhhbmRzaGFrZSBkb25lKS4gVGhlcmUgYXJlIHR3byBmYWlsdXJlIG1vZGVzOiAidXNlYyIg aGF2ZSBwYXNzZWQgKG1ham9yCj4gKyAqIGhhcmR3YXJlIGZsYWtlb3V0KSwgb3IgdGhlIHJlZ2lz dGVyIHJlYWRzIGFzIGFsbC1vbmVzIChoYXJkd2FyZSByZW1vdmVkKS4KPiArICovCj4gK2ludCBj ZG5zM19oYW5kc2hha2Uodm9pZCBfX2lvbWVtICpwdHIsIHUzMiBtYXNrLCB1MzIgZG9uZSwgaW50 IHVzZWMpCj4gK3sKPiArICAgICAgIHUzMiAgICAgcmVzdWx0Owo+ICsKPiArICAgICAgIGRvIHsK PiArICAgICAgICAgICAgICAgcmVzdWx0ID0gcmVhZGwocHRyKTsKPiArICAgICAgICAgICAgICAg aWYgKHJlc3VsdCA9PSB+KHUzMikwKSAgLyogY2FyZCByZW1vdmVkICovCj4gKyAgICAgICAgICAg ICAgICAgICAgICAgcmV0dXJuIC1FTk9ERVY7Cj4gKyAgICAgICAgICAgICAgIHJlc3VsdCAmPSBt YXNrOwo+ICsgICAgICAgICAgICAgICBpZiAocmVzdWx0ID09IGRvbmUpCj4gKyAgICAgICAgICAg ICAgICAgICAgICAgcmV0dXJuIDA7Cj4gKyAgICAgICAgICAgICAgIHVkZWxheSgxKTsKPiArICAg ICAgICAgICAgICAgdXNlYy0tOwo+ICsgICAgICAgfSB3aGlsZSAodXNlYyA+IDApOwo+ICsgICAg ICAgcmV0dXJuIC1FVElNRURPVVQ7Cj4gK30KPiArCj4gKy8qKgo+ICsgKiBjZG5zM19zZXRfcmVn aXN0ZXJfYml0IC0gc2V0IGJpdCBpbiBnaXZlbiByZWdpc3Rlci4KPiArICogQHB0cjogYWRkcmVz cyBvZiBkZXZpY2UgY29udHJvbGxlciByZWdpc3RlciB0byBiZSByZWFkIGFuZCBjaGFuZ2VkCj4g KyAqIEBtYXNrOiBiaXRzIHJlcXVlc3RlZCB0byBzZXQKPiArICovCj4gK3ZvaWQgY2RuczNfc2V0 X3JlZ2lzdGVyX2JpdCh2b2lkIF9faW9tZW0gKnB0ciwgdTMyIG1hc2spCj4gK3sKPiArICAgICAg IG1hc2sgPSByZWFkbChwdHIpIHwgbWFzazsKPiArICAgICAgIHdyaXRlbChtYXNrLCBwdHIpOwo+ ICt9Cj4gKwo+ICsvKioKPiArICogY2RuczNfZXBfYWRkcl90b19pbmRleCAtIE1hY3JvIGNvbnZl cnRzIGVuZHBvaW50IGFkZHJlc3MgdG8KPiArICogaW5kZXggb2YgZW5kcG9pbnQgb2JqZWN0IGlu IGNkbnMzX2RldmljZS5lcHNbXSBjb250YWluZXIKPiArICogQGVwX2FkZHI6IGVuZHBvaW50IGFk ZHJlc3MgZm9yIHdoaWNoIGVuZHBvaW50IG9iamVjdCBpcyByZXF1aXJlZAo+ICsgKgo+ICsgKi8K PiArdTggY2RuczNfZXBfYWRkcl90b19pbmRleCh1OCBlcF9hZGRyKQo+ICt7Cj4gKyAgICAgICBy ZXR1cm4gKCgoZXBfYWRkciAmIDB4N0YpKSArICgoZXBfYWRkciAmIFVTQl9ESVJfSU4pID8gMTYg OiAwKSk7Cj4gK30KPiArCj4gKy8qKgo+ICsgKiBjZG5zM19uZXh0X3JlcXVlc3QgLSByZXR1cm5z IG5leHQgcmVxdWVzdCBmcm9tIGxpc3QKPiArICogQGxpc3Q6IGxpc3QgY29udGFpbmluZyByZXF1 ZXN0cwo+ICsgKgo+ICsgKiBSZXR1cm5zIHJlcXVlc3Qgb3IgTlVMTCBpZiBubyByZXF1ZXN0cyBp biBsaXN0Cj4gKyAqLwo+ICtzdHJ1Y3QgdXNiX3JlcXVlc3QgKmNkbnMzX25leHRfcmVxdWVzdChz dHJ1Y3QgbGlzdF9oZWFkICpsaXN0KQo+ICt7Cj4gKyAgICAgICByZXR1cm4gbGlzdF9maXJzdF9l bnRyeV9vcl9udWxsKGxpc3QsIHN0cnVjdCB1c2JfcmVxdWVzdCwgbGlzdCk7Cj4gK30KPiArCj4g Ky8qKgo+ICsgKiBzZWxlY3RfZXAgLSBzZWxlY3RzIGVuZHBvaW50Cj4gKyAqIEBwcml2X2Rldjog IGV4dGVuZGVkIGdhZGdldCBvYmplY3QKPiArICogQGVwOiBlbmRwb2ludCBhZGRyZXNzCj4gKyAq Lwo+ICt2b2lkIGNkbnMzX3NlbGVjdF9lcChzdHJ1Y3QgY2RuczNfZGV2aWNlICpwcml2X2Rldiwg dTMyIGVwKQo+ICt7Cj4gKyAgICAgICBpZiAocHJpdl9kZXYtPnNlbGVjdGVkX2VwID09IGVwKQo+ ICsgICAgICAgICAgICAgICByZXR1cm47Cj4gKwo+ICsgICAgICAgcHJpdl9kZXYtPnNlbGVjdGVk X2VwID0gZXA7Cj4gKyAgICAgICB3cml0ZWwoZXAsICZwcml2X2Rldi0+cmVncy0+ZXBfc2VsKTsK PiArfQo+ICsKPiArZG1hX2FkZHJfdCBjZG5zM190cmJfdmlydF90b19kbWEoc3RydWN0IGNkbnMz X2VuZHBvaW50ICpwcml2X2VwLAo+ICsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0 cnVjdCBjZG5zM190cmIgKnRyYikKPiArewo+ICsgICAgICAgdTMyIG9mZnNldCA9IChjaGFyICop dHJiIC0gKGNoYXIgKilwcml2X2VwLT50cmJfcG9vbDsKPiArCj4gKyAgICAgICByZXR1cm4gcHJp dl9lcC0+dHJiX3Bvb2xfZG1hICsgb2Zmc2V0Owo+ICt9Cj4gKwo+ICtpbnQgY2RuczNfcmluZ19z aXplKHN0cnVjdCBjZG5zM19lbmRwb2ludCAqcHJpdl9lcCkKPiArewo+ICsgICAgICAgc3dpdGNo IChwcml2X2VwLT50eXBlKSB7Cj4gKyAgICAgICBjYXNlIFVTQl9FTkRQT0lOVF9YRkVSX0lTT0M6 Cj4gKyAgICAgICAgICAgICAgIHJldHVybiBUUkJfSVNPX1JJTkdfU0laRTsKPiArICAgICAgIGNh c2UgVVNCX0VORFBPSU5UX1hGRVJfQ09OVFJPTDoKPiArICAgICAgICAgICAgICAgcmV0dXJuIFRS Ql9DVFJMX1JJTkdfU0laRTsKPiArICAgICAgIGRlZmF1bHQ6Cj4gKyAgICAgICAgICAgICAgIHJl dHVybiBUUkJfUklOR19TSVpFOwo+ICsgICAgICAgfQo+ICt9Cj4gKwo+ICsvKioKPiArICogY2Ru czNfYWxsb2NhdGVfdHJiX3Bvb2wgLSBBbGxvY2F0ZXMgVFJCJ3MgcG9vbCBmb3Igc2VsZWN0ZWQg ZW5kcG9pbnQKPiArICogQHByaXZfZXA6ICBlbmRwb2ludCBvYmplY3QKPiArICoKPiArICogRnVu Y3Rpb24gd2lsbCByZXR1cm4gMCBvbiBzdWNjZXNzIG9yIC1FTk9NRU0gb24gYWxsb2NhdGlvbiBl cnJvcgo+ICsgKi8KPiAraW50IGNkbnMzX2FsbG9jYXRlX3RyYl9wb29sKHN0cnVjdCBjZG5zM19l bmRwb2ludCAqcHJpdl9lcCkKPiArewo+ICsgICAgICAgc3RydWN0IGNkbnMzX2RldmljZSAqcHJp dl9kZXYgPSBwcml2X2VwLT5jZG5zM19kZXY7Cj4gKyAgICAgICBpbnQgcmluZ19zaXplID0gY2Ru czNfcmluZ19zaXplKHByaXZfZXApOwo+ICsgICAgICAgc3RydWN0IGNkbnMzX3RyYiAqbGlua190 cmI7Cj4gKwo+ICsgICAgICAgaWYgKCFwcml2X2VwLT50cmJfcG9vbCkgewo+ICsgICAgICAgICAg ICAgICBwcml2X2VwLT50cmJfcG9vbCA9IGRtYV96YWxsb2NfY29oZXJlbnQocHJpdl9kZXYtPnN5 c2RldiwKPiArICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgIHJpbmdfc2l6ZSwKPiArICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICZwcml2X2VwLT50cmJfcG9vbF9kbWEsCj4gKyAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBHRlBfRE1BKTsKPiAr ICAgICAgICAgICAgICAgaWYgKCFwcml2X2VwLT50cmJfcG9vbCkKPiArICAgICAgICAgICAgICAg ICAgICAgICByZXR1cm4gLUVOT01FTTsKPiArICAgICAgIH0gZWxzZSB7Cj4gKyAgICAgICAgICAg ICAgIG1lbXNldChwcml2X2VwLT50cmJfcG9vbCwgMCwgcmluZ19zaXplKTsKPiArICAgICAgIH0K PiArCj4gKyAgICAgICBpZiAoIXByaXZfZXAtPm51bSkKPiArICAgICAgICAgICAgICAgcmV0dXJu IDA7Cj4gKwo+ICsgICAgICAgaWYgKCFwcml2X2VwLT5hbGlnbmVkX2J1ZmYpIHsKPiArICAgICAg ICAgICAgICAgdm9pZCAqYnVmZiA9IGRtYV9hbGxvY19jb2hlcmVudChwcml2X2Rldi0+c3lzZGV2 LAo+ICsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENETlMz X0FMSUdORURfQlVGX1NJWkUsCj4gKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgJnByaXZfZXAtPmFsaWduZWRfZG1hX2FkZHIsCj4gKyAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgR0ZQX0RNQSk7Cj4gKwo+ICsgICAgICAg ICAgICAgICBwcml2X2VwLT5hbGlnbmVkX2J1ZmYgID0gYnVmZjsKPiArICAgICAgICAgICAgICAg aWYgKCFwcml2X2VwLT5hbGlnbmVkX2J1ZmYpIHsKPiArICAgICAgICAgICAgICAgICAgICAgICBk bWFfZnJlZV9jb2hlcmVudChwcml2X2Rldi0+c3lzZGV2LAo+ICsgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgIHJpbmdfc2l6ZSwKPiArICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICBwcml2X2VwLT50cmJfcG9vbCwKPiArICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICBwcml2X2VwLT50cmJfcG9vbF9kbWEpOwo+ICsgICAg ICAgICAgICAgICAgICAgICAgIHByaXZfZXAtPnRyYl9wb29sID0gTlVMTDsKPiArCj4gKyAgICAg ICAgICAgICAgICAgICAgICAgcmV0dXJuIC1FTk9NRU07Cj4gKyAgICAgICAgICAgICAgIH0KPiAr ICAgICAgIH0KPiArCj4gKyAgICAgICBwcml2X2VwLT5udW1fdHJicyA9IHJpbmdfc2l6ZSAvIFRS Ql9TSVpFOwo+ICsgICAgICAgLyogSW5pdGlhbGl6ZSB0aGUgbGFzdCBUUkIgYXMgTGluayBUUkIg Ki8KPiArICAgICAgIGxpbmtfdHJiID0gKHByaXZfZXAtPnRyYl9wb29sICsgKHByaXZfZXAtPm51 bV90cmJzIC0gMSkpOwo+ICsgICAgICAgbGlua190cmItPmJ1ZmZlciA9IFRSQl9CVUZGRVIocHJp dl9lcC0+dHJiX3Bvb2xfZG1hKTsKPiArICAgICAgIGxpbmtfdHJiLT5jb250cm9sID0gVFJCX0NZ Q0xFIHwgVFJCX1RZUEUoVFJCX0xJTkspIHwKPiArICAgICAgICAgICAgICAgICAgICAgICAgICAg VFJCX0NIQUlOIHwgVFJCX1RPR0dMRTsKPiArCj4gKyAgICAgICByZXR1cm4gMDsKPiArfQo+ICsK PiArc3RhdGljIHZvaWQgY2RuczNfZnJlZV90cmJfcG9vbChzdHJ1Y3QgY2RuczNfZW5kcG9pbnQg KnByaXZfZXApCj4gK3sKPiArICAgICAgIHN0cnVjdCBjZG5zM19kZXZpY2UgKnByaXZfZGV2ID0g cHJpdl9lcC0+Y2RuczNfZGV2Owo+ICsKPiArICAgICAgIGlmIChwcml2X2VwLT50cmJfcG9vbCkg ewo+ICsgICAgICAgICAgICAgICBkbWFfZnJlZV9jb2hlcmVudChwcml2X2Rldi0+c3lzZGV2LAo+ ICsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjZG5zM19yaW5nX3NpemUocHJpdl9l cCksCj4gKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByaXZfZXAtPnRyYl9wb29s LCBwcml2X2VwLT50cmJfcG9vbF9kbWEpOwo+ICsgICAgICAgICAgICAgICBwcml2X2VwLT50cmJf cG9vbCA9IE5VTEw7Cj4gKyAgICAgICB9Cj4gKwo+ICsgICAgICAgaWYgKHByaXZfZXAtPmFsaWdu ZWRfYnVmZikgewo+ICsgICAgICAgICAgICAgICBkbWFfZnJlZV9jb2hlcmVudChwcml2X2Rldi0+ c3lzZGV2LCBDRE5TM19BTElHTkVEX0JVRl9TSVpFLAo+ICsgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICBwcml2X2VwLT5hbGlnbmVkX2J1ZmYsCj4gKyAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgIHByaXZfZXAtPmFsaWduZWRfZG1hX2FkZHIpOwo+ICsgICAgICAgICAgICAg ICBwcml2X2VwLT5hbGlnbmVkX2J1ZmYgPSBOVUxMOwo+ICsgICAgICAgfQo+ICt9Cj4gKwo+ICsv KioKPiArICogY2RuczNfZGF0YV9mbHVzaCAtIGZsdXNoIGRhdGEgYXQgb25jaGlwIGJ1ZmZlcgo+ ICsgKiBAcHJpdl9lcDogZW5kcG9pbnQgb2JqZWN0Cj4gKyAqCj4gKyAqIEVuZHBvaW50IG11c3Qg YmUgc2VsZWN0ZWQgYmVmb3JlIGNhbGwgdG8gdGhpcyBmdW5jdGlvbgo+ICsgKgo+ICsgKiBSZXR1 cm5zIHplcm8gb24gc3VjY2VzcyBvciBuZWdhdGl2ZSB2YWx1ZSBvbiBmYWlsdXJlCj4gKyAqLwo+ ICtzdGF0aWMgaW50IGNkbnMzX2RhdGFfZmx1c2goc3RydWN0IGNkbnMzX2VuZHBvaW50ICpwcml2 X2VwKQo+ICt7Cj4gKyAgICAgICBzdHJ1Y3QgY2RuczNfZGV2aWNlICpwcml2X2RldiA9IHByaXZf ZXAtPmNkbnMzX2RldjsKPiArCj4gKyAgICAgICB3cml0ZWwoRVBfQ01EX0RGTFVTSCwgJnByaXZf ZGV2LT5yZWdzLT5lcF9jbWQpOwo+ICsKPiArICAgICAgIC8qIHdhaXQgZm9yIERGTFVTSCBjbGVh cmVkICovCj4gKyAgICAgICByZXR1cm4gY2RuczNfaGFuZHNoYWtlKCZwcml2X2Rldi0+cmVncy0+ ZXBfY21kLCBFUF9DTURfREZMVVNILCAwLCAxMDApOwo+ICt9Cj4gKwo+ICsvKioKPiArICogY2Ru czNfZXBfc3RhbGxfZmx1c2ggLSBTdGFsbHMgYW5kIGZsdXNoZXMgc2VsZWN0ZWQgZW5kcG9pbnQK PiArICogQHByaXZfZXA6IGVuZHBvaW50IG9iamVjdAo+ICsgKgo+ICsgKiBFbmRwb2ludCBtdXN0 IGJlIHNlbGVjdGVkIGJlZm9yZSBjYWxsIHRvIHRoaXMgZnVuY3Rpb24KPiArICovCj4gK3N0YXRp YyB2b2lkIGNkbnMzX2VwX3N0YWxsX2ZsdXNoKHN0cnVjdCBjZG5zM19lbmRwb2ludCAqcHJpdl9l cCkKPiArewo+ICsgICAgICAgc3RydWN0IGNkbnMzX2RldmljZSAqcHJpdl9kZXYgPSBwcml2X2Vw LT5jZG5zM19kZXY7Cj4gKwo+ICsgICAgICAgY2RuczNfZGJnKHByaXZfZXAtPmNkbnMzX2Rldiwg IlN0YWxsICYgZmx1c2ggZW5kcG9pbnQgJXNcbiIsCj4gKyAgICAgICAgICAgICAgICAgcHJpdl9l cC0+bmFtZSk7Cj4gKwo+ICsgICAgICAgd3JpdGVsKEVQX0NNRF9ERkxVU0ggfCBFUF9DTURfRVJE WSB8IEVQX0NNRF9TU1RBTEwsCj4gKyAgICAgICAgICAgICAgJnByaXZfZGV2LT5yZWdzLT5lcF9j bWQpOwo+ICsKPiArICAgICAgIC8qIHdhaXQgZm9yIERGTFVTSCBjbGVhcmVkICovCj4gKyAgICAg ICBjZG5zM19oYW5kc2hha2UoJnByaXZfZGV2LT5yZWdzLT5lcF9jbWQsIEVQX0NNRF9ERkxVU0gs IDAsIDEwMCk7Cj4gKyAgICAgICBwcml2X2VwLT5mbGFncyB8PSBFUF9TVEFMTDsKPiArfQo+ICsK PiArLyoqCj4gKyAqIGNkbnMzX2h3X3Jlc2V0X2Vwc19jb25maWcgLSByZXNldCBlbmRwb2ludHMg Y29uZmlndXJhdGlvbiBrZXB0IGJ5IGNvbnRyb2xsZXIuCj4gKyAqIEBwcml2X2RldjogZXh0ZW5k ZWQgZ2FkZ2V0IG9iamVjdAo+ICsgKi8KPiArdm9pZCBjZG5zM19od19yZXNldF9lcHNfY29uZmln KHN0cnVjdCBjZG5zM19kZXZpY2UgKnByaXZfZGV2KQo+ICt7Cj4gKyAgICAgICB3cml0ZWwoVVNC X0NPTkZfQ0ZHUlNULCAmcHJpdl9kZXYtPnJlZ3MtPnVzYl9jb25mKTsKPiArCj4gKyAgICAgICBj ZG5zM19hbGxvd19lbmFibGVfbDEocHJpdl9kZXYsIDApOwo+ICsgICAgICAgcHJpdl9kZXYtPmh3 X2NvbmZpZ3VyZWRfZmxhZyA9IDA7Cj4gKyAgICAgICBwcml2X2Rldi0+b25jaGlwX21lbV9hbGxv Y2F0ZWRfc2l6ZSA9IDA7Cj4gK30KPiArCj4gKy8qKgo+ICsgKiBjZG5zM19lcF9pbmNfdHJiIC0g aW5jcmVtZW50IGEgdHJiIGluZGV4Lgo+ICsgKiBAaW5kZXg6IFBvaW50ZXIgdG8gdGhlIFRSQiBp bmRleCB0byBpbmNyZW1lbnQuCj4gKyAqIEBjczogQ3ljbGUgc3RhdGUKPiArICogQHRyYl9pbl9z ZWc6IG51bWJlciBvZiBUUkJzIGluIHNlZ21lbnQKPiArICoKPiArICogVGhlIGluZGV4IHNob3Vs ZCBuZXZlciBwb2ludCB0byB0aGUgbGluayBUUkIuIEFmdGVyIGluY3JlbWVudGluZywKPiArICog aWYgaXQgaXMgcG9pbnQgdG8gdGhlIGxpbmsgVFJCLCB3cmFwIGFyb3VuZCB0byB0aGUgYmVnaW5u aW5nIGFuZCByZXZlcnQKPiArICogY3ljbGUgc3RhdGUgYml0IFRoZQo+ICsgKiBsaW5rIFRSQiBp cyBhbHdheXMgYXQgdGhlIGxhc3QgVFJCIGVudHJ5Lgo+ICsgKi8KPiArc3RhdGljIHZvaWQgY2Ru czNfZXBfaW5jX3RyYihpbnQgKmluZGV4LCB1OCAqY3MsIGludCB0cmJfaW5fc2VnKQo+ICt7Cj4g KyAgICAgICAoKmluZGV4KSsrOwo+ICsgICAgICAgaWYgKCppbmRleCA9PSAodHJiX2luX3NlZyAt IDEpKSB7Cj4gKyAgICAgICAgICAgICAgICppbmRleCA9IDA7Cj4gKyAgICAgICAgICAgICAgICpj cyBePSAgMTsKPiArICAgICAgIH0KPiArfQo+ICsKPiArLyoqCj4gKyAqIGNkbnMzX2VwX2luY19l bnEgLSBpbmNyZW1lbnQgZW5kcG9pbnQncyBlbnF1ZXVlIHBvaW50ZXIKPiArICogQHByaXZfZXA6 IFRoZSBlbmRwb2ludCB3aG9zZSBlbnF1ZXVlIHBvaW50ZXIgd2UncmUgaW5jcmVtZW50aW5nCj4g KyAqLwo+ICtzdGF0aWMgdm9pZCBjZG5zM19lcF9pbmNfZW5xKHN0cnVjdCBjZG5zM19lbmRwb2lu dCAqcHJpdl9lcCkKPiArewo+ICsgICAgICAgcHJpdl9lcC0+ZnJlZV90cmJzLS07Cj4gKyAgICAg ICBjZG5zM19lcF9pbmNfdHJiKCZwcml2X2VwLT5lbnF1ZXVlLCAmcHJpdl9lcC0+cGNzLCBwcml2 X2VwLT5udW1fdHJicyk7Cj4gK30KPiArCj4gKy8qKgo+ICsgKiBjZG5zM19lcF9pbmNfZGVxIC0g aW5jcmVtZW50IGVuZHBvaW50J3MgZGVxdWV1ZSBwb2ludGVyCj4gKyAqIEBwcml2X2VwOiBUaGUg ZW5kcG9pbnQgd2hvc2UgZGVxdWV1ZSBwb2ludGVyIHdlJ3JlIGluY3JlbWVudGluZwo+ICsgKi8K PiArc3RhdGljIHZvaWQgY2RuczNfZXBfaW5jX2RlcShzdHJ1Y3QgY2RuczNfZW5kcG9pbnQgKnBy aXZfZXApCj4gK3sKPiArICAgICAgIHByaXZfZXAtPmZyZWVfdHJicysrOwo+ICsgICAgICAgY2Ru czNfZXBfaW5jX3RyYigmcHJpdl9lcC0+ZGVxdWV1ZSwgJnByaXZfZXAtPmNjcywgcHJpdl9lcC0+ bnVtX3RyYnMpOwo+ICt9Cj4gKwo+ICt2b2lkIGNkbnMzX21vdmVfZGVxX3RvX25leHRfdHJiKHN0 cnVjdCBjZG5zM19yZXF1ZXN0ICpwcml2X3JlcSkKPiArewo+ICsgICAgICAgc3RydWN0IGNkbnMz X2VuZHBvaW50ICpwcml2X2VwID0gcHJpdl9yZXEtPnByaXZfZXA7Cj4gKyAgICAgICBpbnQgY3Vy cmVudF90cmIgPSBwcml2X3JlcS0+c3RhcnRfdHJiOwo+ICsKPiArICAgICAgIHdoaWxlIChjdXJy ZW50X3RyYiAhPSBwcml2X3JlcS0+ZW5kX3RyYikgewo+ICsgICAgICAgICAgICAgICBjZG5zM19l cF9pbmNfZGVxKHByaXZfZXApOwo+ICsgICAgICAgICAgICAgICBjdXJyZW50X3RyYiA9IHByaXZf ZXAtPmRlcXVldWU7Cj4gKyAgICAgICB9Cj4gKwo+ICsgICAgICAgY2RuczNfZXBfaW5jX2RlcShw cml2X2VwKTsKPiArfQo+ICsKPiArLyoqCj4gKyAqIGNkbnMzX2FsbG93X2VuYWJsZV9sMSAtIGVu YWJsZS9kaXNhYmxlIHBlcm1pdHMgdG8gdHJhbnNpdGlvbiB0byBMMS4KPiArICogQHByaXZfZGV2 OiBFeHRlbmRlZCBnYWRnZXQgb2JqZWN0Cj4gKyAqIEBlbmFibGU6IEVuYWJsZS9kaXNhYmxlIHBl cm1pdCB0byB0cmFuc2l0aW9uIHRvIEwxLgo+ICsgKgo+ICsgKiBJZiBiaXQgVVNCX0NPTkZfTDFF TiBpcyBzZXQgYW5kIGRldmljZSByZWNlaXZlIEV4dGVuZGVkIFRva2VuIHBhY2tldCwKPiArICog dGhlbiBjb250cm9sbGVyIGFuc3dlciB3aXRoIEFDSyBoYW5kc2hha2UuCj4gKyAqIElmIGJpdCBV U0JfQ09ORl9MMURTIGlzIHNldCBhbmQgZGV2aWNlIHJlY2VpdmUgRXh0ZW5kZWQgVG9rZW4gcGFj a2V0LAo+ICsgKiB0aGVuIGNvbnRyb2xsZXIgYW5zd2VyIHdpdGggTllFVCBoYW5kc2hha2UuCj4g KyAqLwo+ICt2b2lkIGNkbnMzX2FsbG93X2VuYWJsZV9sMShzdHJ1Y3QgY2RuczNfZGV2aWNlICpw cml2X2RldiwgaW50IGVuYWJsZSkKPiArewo+ICsgICAgICAgaWYgKGVuYWJsZSkKPiArICAgICAg ICAgICAgICAgd3JpdGVsKFVTQl9DT05GX0wxRU4sICZwcml2X2Rldi0+cmVncy0+dXNiX2NvbmYp Owo+ICsgICAgICAgZWxzZQo+ICsgICAgICAgICAgICAgICB3cml0ZWwoVVNCX0NPTkZfTDFEUywg JnByaXZfZGV2LT5yZWdzLT51c2JfY29uZik7Cj4gK30KPiArCj4gK2VudW0gdXNiX2RldmljZV9z cGVlZCBjZG5zM19nZXRfc3BlZWQoc3RydWN0IGNkbnMzX2RldmljZSAqcHJpdl9kZXYpCj4gK3sK PiArICAgICAgIHUzMiByZWc7Cj4gKwo+ICsgICAgICAgcmVnID0gcmVhZGwoJnByaXZfZGV2LT5y ZWdzLT51c2Jfc3RzKTsKPiArCj4gKyAgICAgICBpZiAoREVWX1NVUEVSU1BFRUQocmVnKSkKPiAr ICAgICAgICAgICAgICAgcmV0dXJuIFVTQl9TUEVFRF9TVVBFUjsKPiArICAgICAgIGVsc2UgaWYg KERFVl9ISUdIU1BFRUQocmVnKSkKPiArICAgICAgICAgICAgICAgcmV0dXJuIFVTQl9TUEVFRF9I SUdIOwo+ICsgICAgICAgZWxzZSBpZiAoREVWX0ZVTExTUEVFRChyZWcpKQo+ICsgICAgICAgICAg ICAgICByZXR1cm4gVVNCX1NQRUVEX0ZVTEw7Cj4gKyAgICAgICBlbHNlIGlmIChERVZfTE9XU1BF RUQocmVnKSkKPiArICAgICAgICAgICAgICAgcmV0dXJuIFVTQl9TUEVFRF9MT1c7Cj4gKyAgICAg ICByZXR1cm4gVVNCX1NQRUVEX1VOS05PV047Cj4gK30KPiArCj4gKy8qKgo+ICsgKiBjZG5zM19z dGFydF9hbGxfcmVxdWVzdCAtIGFkZCB0byByaW5nIGFsbCByZXF1ZXN0IG5vdCBzdGFydGVkCj4g KyAqIEBwcml2X2RldjogRXh0ZW5kZWQgZ2FkZ2V0IG9iamVjdAo+ICsgKiBAcHJpdl9lcDogVGhl IGVuZHBvaW50IGZvciB3aG9tIHJlcXVlc3Qgd2lsbCBiZSBzdGFydGVkLgo+ICsgKgo+ICsgKiBS ZXR1cm5zIHJldHVybiBFTk9NRU0gaWYgdHJhbnNmZXIgcmluZyBpIG5vdCBlbm91Z2ggVFJCcyB0 byBzdGFydAo+ICsgKiAgICAgICAgIGFsbCByZXF1ZXN0cy4KPiArICovCj4gK3N0YXRpYyBpbnQg Y2RuczNfc3RhcnRfYWxsX3JlcXVlc3Qoc3RydWN0IGNkbnMzX2RldmljZSAqcHJpdl9kZXYsCj4g KyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJ1Y3QgY2RuczNfZW5kcG9pbnQg KnByaXZfZXApCj4gK3sKPiArICAgICAgIHN0cnVjdCBjZG5zM19yZXF1ZXN0ICpwcml2X3JlcTsK PiArICAgICAgIHN0cnVjdCB1c2JfcmVxdWVzdCAqcmVxdWVzdDsKPiArICAgICAgIGludCByZXQg PSAwOwo+ICsKPiArICAgICAgIHdoaWxlICghbGlzdF9lbXB0eSgmcHJpdl9lcC0+ZGVmZXJyZWRf cmVxX2xpc3QpKSB7Cj4gKyAgICAgICAgICAgICAgIHJlcXVlc3QgPSBjZG5zM19uZXh0X3JlcXVl c3QoJnByaXZfZXAtPmRlZmVycmVkX3JlcV9saXN0KTsKPiArICAgICAgICAgICAgICAgcHJpdl9y ZXEgPSB0b19jZG5zM19yZXF1ZXN0KHJlcXVlc3QpOwo+ICsKPiArICAgICAgICAgICAgICAgcmV0 ID0gY2RuczNfZXBfcnVuX3RyYW5zZmVyKHByaXZfZXAsIHJlcXVlc3QpOwo+ICsgICAgICAgICAg ICAgICBpZiAocmV0KQo+ICsgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZXQ7Cj4gKwo+ ICsgICAgICAgICAgICAgICBsaXN0X2RlbCgmcmVxdWVzdC0+bGlzdCk7Cj4gKyAgICAgICAgICAg ICAgIGxpc3RfYWRkX3RhaWwoJnJlcXVlc3QtPmxpc3QsCj4gKyAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgJnByaXZfZXAtPnBlbmRpbmdfcmVxX2xpc3QpOwo+ICsgICAgICAgfQo+ICsKPiAr ICAgICAgIHByaXZfZXAtPmZsYWdzICY9IH5FUF9SSU5HX0ZVTEw7Cj4gKyAgICAgICByZXR1cm4g cmV0Owo+ICt9Cj4gKwo+ICsvKioKPiArICogY2RuczNfZ2FkZ2V0X2dpdmViYWNrIC0gY2FsbCBz dHJ1Y3QgdXNiX3JlcXVlc3QncyAtPmNvbXBsZXRlIGNhbGxiYWNrCj4gKyAqIEBwcml2X2VwOiBU aGUgZW5kcG9pbnQgdG8gd2hvbSB0aGUgcmVxdWVzdCBiZWxvbmdzIHRvCj4gKyAqIEBwcml2X3Jl cTogVGhlIHJlcXVlc3Qgd2UncmUgZ2l2aW5nIGJhY2sKPiArICogQHN0YXR1czogY29tcGxldGlv biBjb2RlIGZvciB0aGUgcmVxdWVzdAo+ICsgKgo+ICsgKiBNdXN0IGJlIGNhbGxlZCB3aXRoIGNv bnRyb2xsZXIncyBsb2NrIGhlbGQgYW5kIGludGVycnVwdHMgZGlzYWJsZWQuIFRoaXMKPiArICog ZnVuY3Rpb24gd2lsbCB1bm1hcCBAcmVxIGFuZCBjYWxsIGl0cyAtPmNvbXBsZXRlKCkgY2FsbGJh Y2sgdG8gbm90aWZ5IHVwcGVyCj4gKyAqIGxheWVycyB0aGF0IGl0IGhhcyBjb21wbGV0ZWQuCj4g KyAqLwo+ICt2b2lkIGNkbnMzX2dhZGdldF9naXZlYmFjayhzdHJ1Y3QgY2RuczNfZW5kcG9pbnQg KnByaXZfZXAsCj4gKyAgICAgICAgICAgICAgICAgICAgICAgICAgc3RydWN0IGNkbnMzX3JlcXVl c3QgKnByaXZfcmVxLAo+ICsgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBzdGF0dXMpCj4g K3sKPiArICAgICAgIHN0cnVjdCBjZG5zM19kZXZpY2UgKnByaXZfZGV2ID0gcHJpdl9lcC0+Y2Ru czNfZGV2Owo+ICsgICAgICAgc3RydWN0IHVzYl9yZXF1ZXN0ICpyZXF1ZXN0ID0gJnByaXZfcmVx LT5yZXF1ZXN0Owo+ICsKPiArICAgICAgIGxpc3RfZGVsX2luaXQoJnJlcXVlc3QtPmxpc3QpOwo+ ICsKPiArICAgICAgIGlmIChyZXF1ZXN0LT5zdGF0dXMgPT0gLUVJTlBST0dSRVNTKQo+ICsgICAg ICAgICAgICAgICByZXF1ZXN0LT5zdGF0dXMgPSBzdGF0dXM7Cj4gKwo+ICsgICAgICAgdXNiX2dh ZGdldF91bm1hcF9yZXF1ZXN0X2J5X2Rldihwcml2X2Rldi0+c3lzZGV2LCByZXF1ZXN0LAo+ICsg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcml2X2VwLT5kaXIpOwo+ICsK PiArICAgICAgIHByaXZfcmVxLT5mbGFncyAmPSB+UkVRVUVTVF9QRU5ESU5HOwo+ICsgICAgICAg dHJhY2VfY2RuczNfZ2FkZ2V0X2dpdmViYWNrKHByaXZfcmVxKTsKPiArCj4gKyAgICAgICAvKiBT dGFydCBhbGwgbm90IHBlbmRpbmcgcmVxdWVzdCAqLwo+ICsgICAgICAgaWYgKHByaXZfZXAtPmZs YWdzICYgRVBfUklOR19GVUxMKQo+ICsgICAgICAgICAgICAgICBjZG5zM19zdGFydF9hbGxfcmVx dWVzdChwcml2X2RldiwgcHJpdl9lcCk7Cj4gKwo+ICsgICAgICAgaWYgKHJlcXVlc3QtPmNvbXBs ZXRlKSB7Cj4gKyAgICAgICAgICAgICAgIHNwaW5fdW5sb2NrKCZwcml2X2Rldi0+bG9jayk7Cj4g KyAgICAgICAgICAgICAgIHVzYl9nYWRnZXRfZ2l2ZWJhY2tfcmVxdWVzdCgmcHJpdl9lcC0+ZW5k cG9pbnQsCj4gKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXF1 ZXN0KTsKPiArICAgICAgICAgICAgICAgc3Bpbl9sb2NrKCZwcml2X2Rldi0+bG9jayk7Cj4gKyAg ICAgICB9Cj4gKwo+ICsgICAgICAgaWYgKHJlcXVlc3QtPmJ1ZiA9PSBwcml2X2Rldi0+emxwX2J1 ZikKPiArICAgICAgICAgICAgICAgY2RuczNfZ2FkZ2V0X2VwX2ZyZWVfcmVxdWVzdCgmcHJpdl9l cC0+ZW5kcG9pbnQsIHJlcXVlc3QpOwo+ICt9Cj4gKwo+ICsvKioKPiArICogY2RuczNfZXBfcnVu X3RyYW5zZmVyIC0gc3RhcnQgdHJhbnNmZXIgb24gbm8tZGVmYXVsdCBlbmRwb2ludCBoYXJkd2Fy ZQo+ICsgKiBAcHJpdl9lcDogZW5kcG9pbnQgb2JqZWN0Cj4gKyAqCj4gKyAqIFJldHVybnMgemVy byBvbiBzdWNjZXNzIG9yIG5lZ2F0aXZlIHZhbHVlIG9uIGZhaWx1cmUKPiArICovCj4gK2ludCBj ZG5zM19lcF9ydW5fdHJhbnNmZXIoc3RydWN0IGNkbnMzX2VuZHBvaW50ICpwcml2X2VwLAo+ICsg ICAgICAgICAgICAgICAgICAgICAgICAgc3RydWN0IHVzYl9yZXF1ZXN0ICpyZXF1ZXN0KQo+ICt7 Cj4gKyAgICAgICBzdHJ1Y3QgY2RuczNfZGV2aWNlICpwcml2X2RldiA9IHByaXZfZXAtPmNkbnMz X2RldjsKPiArICAgICAgIHN0cnVjdCBjZG5zM19yZXF1ZXN0ICpwcml2X3JlcTsKPiArICAgICAg IHN0cnVjdCBjZG5zM190cmIgKnRyYjsKPiArICAgICAgIGRtYV9hZGRyX3QgdHJiX2RtYTsKPiAr ICAgICAgIGludCBkbWFfaW5kZXg7Cj4gKyAgICAgICBpbnQgc2dfaXRlciA9IDA7Cj4gKyAgICAg ICB1MzIgZmlyc3RfcGNzOwo+ICsgICAgICAgaW50ICBudW1fdHJiOwo+ICsgICAgICAgaW50IGFk ZHJlc3M7Cj4gKyAgICAgICB1MzIgZG9vcmJlbGw7Cj4gKyAgICAgICBpbnQgcGNzOwo+ICsKPiAr ICAgICAgIGlmIChwcml2X2VwLT50eXBlID09IFVTQl9FTkRQT0lOVF9YRkVSX0lTT0MpCj4gKyAg ICAgICAgICAgICAgIG51bV90cmIgPSBwcml2X2VwLT5pbnRlcnZhbDsKPiArICAgICAgIGVsc2UK PiArICAgICAgICAgICAgICAgbnVtX3RyYiA9IHJlcXVlc3QtPm51bV9zZ3MgPyByZXF1ZXN0LT5u dW1fc2dzIDogMTsKPiArCj4gKyAgICAgICBpZiAobnVtX3RyYiA+IHByaXZfZXAtPmZyZWVfdHJi cykgewo+ICsgICAgICAgICAgICAgICBwcml2X2VwLT5mbGFncyB8PSBFUF9SSU5HX0ZVTEw7Cj4g KyAgICAgICAgICAgICAgIHJldHVybiAtRU5PQlVGUzsKPiArICAgICAgIH0KPiArCj4gKyAgICAg ICBwcml2X3JlcSA9IHRvX2NkbnMzX3JlcXVlc3QocmVxdWVzdCk7Cj4gKyAgICAgICBhZGRyZXNz ID0gcHJpdl9lcC0+ZW5kcG9pbnQuZGVzYy0+YkVuZHBvaW50QWRkcmVzczsKPiArCj4gKyAgICAg ICBwcml2X2VwLT5mbGFncyB8PSBFUF9QRU5ESU5HX1JFUVVFU1Q7Cj4gKyAgICAgICB0cmJfZG1h ID0gcmVxdWVzdC0+ZG1hOwo+ICsKPiArICAgICAgIC8qIG11c3QgYWxsb2NhdGUgYnVmZmVyIGFs aWduZWQgdG8gOCAqLwo+ICsgICAgICAgaWYgKChyZXF1ZXN0LT5kbWEgJSA4KSkgewo+ICsgICAg ICAgICAgICAgICBpZiAocmVxdWVzdC0+bGVuZ3RoIDw9IENETlMzX0FMSUdORURfQlVGX1NJWkUp IHsKPiArICAgICAgICAgICAgICAgICAgICAgICBtZW1jcHkocHJpdl9lcC0+YWxpZ25lZF9idWZm LCByZXF1ZXN0LT5idWYsCj4gKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcXVlc3Qt Pmxlbmd0aCk7Cj4gKyAgICAgICAgICAgICAgICAgICAgICAgdHJiX2RtYSA9IHByaXZfZXAtPmFs aWduZWRfZG1hX2FkZHI7Cj4gKyAgICAgICAgICAgICAgIH0gZWxzZSB7Cj4gKyAgICAgICAgICAg ICAgICAgICAgICAgcmV0dXJuIC1FTk9NRU07Cj4gKyAgICAgICAgICAgICAgIH0KPiArICAgICAg IH0KPiArCj4gKyAgICAgICB0cmIgPSBwcml2X2VwLT50cmJfcG9vbCArIHByaXZfZXAtPmVucXVl dWU7Cj4gKyAgICAgICBwcml2X3JlcS0+c3RhcnRfdHJiID0gcHJpdl9lcC0+ZW5xdWV1ZTsKPiAr ICAgICAgIHByaXZfcmVxLT50cmIgPSB0cmI7Cj4gKwo+ICsgICAgICAgLyogcHJlcGFyZSByaW5n ICovCj4gKyAgICAgICBpZiAoKHByaXZfZXAtPmVucXVldWUgKyBudW1fdHJiKSAgPj0gKHByaXZf ZXAtPm51bV90cmJzIC0gMSkpIHsKPiArICAgICAgICAgICAgICAgLyp1cGRhdGluZyBDIGJ0IGlu ICBMaW5rIFRSQiBiZWZvcmUgc3RhcnRpbmcgRE1BKi8KPiArICAgICAgICAgICAgICAgc3RydWN0 IGNkbnMzX3RyYiAqbGlua190cmIgPSBwcml2X2VwLT50cmJfcG9vbCArCj4gKyAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHByaXZfZXAtPm51bV90cmJzIC0gMSk7 Cj4gKyAgICAgICAgICAgICAgIGxpbmtfdHJiLT5jb250cm9sID0gKChwcml2X2VwLT5wY3MpID8g VFJCX0NZQ0xFIDogMCkgfAo+ICsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRS Ql9UWVBFKFRSQl9MSU5LKSB8IFRSQl9DSEFJTiB8Cj4gKyAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgVFJCX1RPR0dMRTsKPiArICAgICAgIH0KPiArCj4gKyAgICAgICBmaXJzdF9w Y3MgPSBwcml2X2VwLT5wY3MgPyBUUkJfQ1lDTEUgOiAwOwo+ICsKPiArICAgICAgIC8qIGFybSB0 cmFuc2ZlciBvbiBzZWxlY3RlZCBlbmRwb2ludCAqLwo+ICsgICAgICAgY2RuczNfc2VsZWN0X2Vw KHByaXZfZXAtPmNkbnMzX2RldiwgYWRkcmVzcyk7Cj4gKwo+ICsgICAgICAgZG9vcmJlbGwgPSAh IShyZWFkbCgmcHJpdl9kZXYtPnJlZ3MtPmVwX2NtZCkgJiBFUF9DTURfRFJEWSk7Cj4gKyAgICAg ICBkbWFfaW5kZXggPSAocmVhZGwoJnByaXZfZGV2LT5yZWdzLT5lcF90cmFkZHIpIC0KPiArICAg ICAgICAgICAgICAgICAgICAgICAgcHJpdl9lcC0+dHJiX3Bvb2xfZG1hKSAvIFRSQl9TSVpFOwo+ ICsKPiArICAgICAgIGlmICghcHJpdl9lcC0+d2ExX3NldCkgewo+ICsgICAgICAgICAgICAgICBp ZiAoZG9vcmJlbGwgJiYKPiArICAgICAgICAgICAgICAgICAgICgocHJpdl9lcC0+ZW5xdWV1ZSA9 PSAwICYmCj4gKyAgICAgICAgICAgICAgICAgICBkbWFfaW5kZXggPj0gR0VUX1RSQlNfUEVSX1NF R01FTlQocHJpdl9lcC0+dHlwZSkgLSAyKSB8fAo+ICsgICAgICAgICAgICAgICAgICAgZG1hX2lu ZGV4ID09IHByaXZfZXAtPmVucXVldWUgfHwKPiArICAgICAgICAgICAgICAgICAgIChkbWFfaW5k ZXggPT0gcHJpdl9lcC0+ZW5xdWV1ZSAtIDEpKSkgewo+ICsgICAgICAgICAgICAgICAgICAgICAg IHByaXZfZXAtPndhMV9jeWNsZV9iaXQgPSBmaXJzdF9wY3M7Cj4gKyAgICAgICAgICAgICAgICAg ICAgICAgcHJpdl9lcC0+d2ExX3NldCA9IDE7Cj4gKyAgICAgICAgICAgICAgICAgICAgICAgcHJp dl9lcC0+d2ExX3RyYiA9IHRyYjsKPiArICAgICAgICAgICAgICAgICAgICAgICBmaXJzdF9wY3Mg Xj0gMHgxOwo+ICsgICAgICAgICAgICAgICAgICAgICAgIGNkbnMzX2RiZyhwcml2X2RldiwgIldB MTogZGVmZXJyZWQgZG9vcmJlbFxuIik7Cj4gKyAgICAgICAgICAgICAgIH0KPiArICAgICAgIH0K PiArCj4gKyAgICAgICBkbyB7Cj4gKyAgICAgICAvKiBmaWxsIFRSQiAqLwo+ICsgICAgICAgICAg ICAgICB0cmItPmJ1ZmZlciA9IFRSQl9CVUZGRVIocmVxdWVzdC0+bnVtX3NncyA9PSAwCj4gKyAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICA/IHRyYl9kbWEgOiByZXF1ZXN0LT5zZ1tzZ19p dGVyXS5kbWFfYWRkcmVzcyk7Cj4gKwo+ICsgICAgICAgICAgICAgICB0cmItPmxlbmd0aCA9IFRS Ql9CVVJTVF9MRU4oMTYpIHwKPiArICAgICAgICAgICAgICAgICAgIFRSQl9MRU4ocmVxdWVzdC0+ bnVtX3NncyA9PSAwID8KPiArICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcXVlc3Qt Pmxlbmd0aCA6IHJlcXVlc3QtPnNnW3NnX2l0ZXJdLmxlbmd0aCk7Cj4gKwo+ICsgICAgICAgICAg ICAgICB0cmItPmNvbnRyb2wgPSBUUkJfVFlQRShUUkJfTk9STUFMKTsKPiArICAgICAgICAgICAg ICAgcGNzID0gcHJpdl9lcC0+cGNzID8gVFJCX0NZQ0xFIDogMDsKPiArCj4gKyAgICAgICAgICAg ICAgIC8qCj4gKyAgICAgICAgICAgICAgICAqIGZpcnN0IHRyYiBzaG91bGQgYmUgcHJlcGFyZWQg YXMgbGFzdCB0byBhdm9pZCBwcm9jZXNzaW5nCj4gKyAgICAgICAgICAgICAgICAqICB0cmFuc2Zl ciB0byBlYXJseQo+ICsgICAgICAgICAgICAgICAgKi8KPiArICAgICAgICAgICAgICAgaWYgKHNn X2l0ZXIgIT0gMCkKPiArICAgICAgICAgICAgICAgICAgICAgICB0cmItPmNvbnRyb2wgfD0gcGNz Owo+ICsKPiArICAgICAgICAgICAgICAgaWYgKHByaXZfZXAtPnR5cGUgPT0gVVNCX0VORFBPSU5U X1hGRVJfSVNPQyAgJiYgIXByaXZfZXAtPmRpcikgewo+ICsgICAgICAgICAgICAgICAgICAgICAg IHRyYi0+Y29udHJvbCB8PSBUUkJfSU9DIHwgVFJCX0lTUDsKPiArICAgICAgICAgICAgICAgfSBl bHNlIHsKPiArICAgICAgICAgICAgICAgICAgICAgICAvKiBmb3IgbGFzdCBlbGVtZW50IGluIFRE IG9yIGluIFNHIGxpc3QgKi8KPiArICAgICAgICAgICAgICAgICAgICAgICBpZiAoc2dfaXRlciA9 PSAobnVtX3RyYiAtIDEpICYmIHNnX2l0ZXIgIT0gMCkKPiArICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgIHRyYi0+Y29udHJvbCB8PSBwY3MgfCBUUkJfSU9DIHwgVFJCX0lTUDsKPiArICAg ICAgICAgICAgICAgfQo+ICsgICAgICAgICAgICAgICArK3NnX2l0ZXI7Cj4gKyAgICAgICAgICAg ICAgIHByaXZfcmVxLT5lbmRfdHJiID0gcHJpdl9lcC0+ZW5xdWV1ZTsKPiArICAgICAgICAgICAg ICAgY2RuczNfZXBfaW5jX2VucShwcml2X2VwKTsKPiArICAgICAgICAgICAgICAgdHJiID0gcHJp dl9lcC0+dHJiX3Bvb2wgKyBwcml2X2VwLT5lbnF1ZXVlOwo+ICsgICAgICAgfSB3aGlsZSAoc2df aXRlciA8IG51bV90cmIpOwo+ICsKPiArICAgICAgIHRyYiA9IHByaXZfcmVxLT50cmI7Cj4gKwo+ ICsgICAgICAgcHJpdl9yZXEtPmZsYWdzIHw9IFJFUVVFU1RfUEVORElORzsKPiArCj4gKyAgICAg ICAvKgo+ICsgICAgICAgICogTWVtb3J5IGJhcnJpZXIgLSBjeWNsZSBiaXQgbXVzdCBiZSBzZXQg YmVmb3JlIG90aGVyIGZpbGRzIGluIHRyYi4KPiArICAgICAgICAqLwo+ICsgICAgICAgd21iKCk7 Cj4gKwo+ICsgICAgICAgLyogZ2l2ZSB0aGUgVEQgdG8gdGhlIGNvbnN1bWVyKi8KPiArICAgICAg IGlmIChzZ19pdGVyID09IDEpCj4gKyAgICAgICAgICAgICAgIHRyYi0+Y29udHJvbCB8PSBmaXJz dF9wY3MgfCBUUkJfSU9DIHwgVFJCX0lTUDsKPiArICAgICAgIGVsc2UKPiArICAgICAgICAgICAg ICAgdHJiLT5jb250cm9sIHw9IGZpcnN0X3BjczsKPiArCj4gKyAgICAgICB0cmFjZV9jZG5zM19w cmVwYXJlX3RyYihwcml2X2VwLCBwcml2X3JlcS0+dHJiKTsKPiArCj4gKyAgICAgICAvKgo+ICsg ICAgICAgICogTWVtb3J5IGJhcnJpZXIgLSBDeWNsZSBCaXQgbXVzdCBiZSBzZXQgYmVmb3JlIHRy Yi0+bGVuZ3RoICBhbmQKPiArICAgICAgICAqIHRyYi0+YnVmZmVyIGZpZWxkcy4KPiArICAgICAg ICAqLwo+ICsgICAgICAgd21iKCk7Cj4gKwo+ICsgICAgICAgLyoKPiArICAgICAgICAqIEZvciBE TVVMVCBtb2RlIHdlIGNhbiBzZXQgYWRkcmVzcyB0byB0cmFuc2ZlciByaW5nIG9ubHkgb25jZSBh ZnRlcgo+ICsgICAgICAgICogZW5hYmxpbmcgZW5kcG9pbnQuCj4gKyAgICAgICAgKi8KPiArICAg ICAgIGlmIChwcml2X2VwLT5mbGFncyAmIEVQX1VQREFURV9FUF9UUkJBRERSKSB7Cj4gKyAgICAg ICAgICAgICAgIHdyaXRlbChFUF9UUkFERFJfVFJBRERSKHByaXZfZXAtPnRyYl9wb29sX2RtYSAr Cj4gKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByaXZfcmVxLT5zdGFy dF90cmIgKiBUUkJfU0laRSksCj4gKyAgICAgICAgICAgICAgICAgICAgICAmcHJpdl9kZXYtPnJl Z3MtPmVwX3RyYWRkcik7Cj4gKwo+ICsgICAgICAgICAgICAgICBjZG5zM19kYmcocHJpdl9lcC0+ Y2RuczNfZGV2LCAiVXBkYXRlIGVwX3RyYmFkZHIgZm9yICVzIHRvICUwOHhcbiIsCj4gKyAgICAg ICAgICAgICAgICAgICAgICAgICBwcml2X2VwLT5uYW1lLCByZWFkbCgmcHJpdl9kZXYtPnJlZ3Mt PmVwX3RyYWRkcikpOwo+ICsKPiArICAgICAgICAgICAgICAgcHJpdl9lcC0+ZmxhZ3MgJj0gfkVQ X1VQREFURV9FUF9UUkJBRERSOwo+ICsgICAgICAgfQo+ICsKPiArICAgICAgIGlmICghcHJpdl9l cC0+d2ExX3NldCAmJiAhKHByaXZfZXAtPmZsYWdzICYgRVBfU1RBTEwpKSB7Cj4gKyAgICAgICAg ICAgICAgIHRyYWNlX2NkbnMzX3JpbmcocHJpdl9lcCk7Cj4gKyAgICAgICAgICAgICAgIC8qY2xl YXJpbmcgVFJCRVJSIGFuZCBFUF9TVFNfREVTQ01JUyBiZWZvcmUgc2V0aW5nIERSRFkqLwo+ICsg ICAgICAgICAgICAgICB3cml0ZWwoRVBfU1RTX1RSQkVSUiB8IEVQX1NUU19ERVNDTUlTLCAmcHJp dl9kZXYtPnJlZ3MtPmVwX3N0cyk7Cj4gKyAgICAgICAgICAgICAgIHdyaXRlbChFUF9DTURfRFJE WSwgJnByaXZfZGV2LT5yZWdzLT5lcF9jbWQpOwo+ICsgICAgICAgICAgICAgICB0cmFjZV9jZG5z M19kb29yYmVsbF9lcHgocHJpdl9lcC0+bmFtZSwKPiArICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgIHJlYWRsKCZwcml2X2Rldi0+cmVncy0+ZXBfdHJhZGRyKSk7Cj4gKyAg ICAgICB9Cj4gKwo+ICsgICAgICAgcmV0dXJuIDA7Cj4gK30KPiArCj4gK3ZvaWQgY2RuczNfc2V0 X2h3X2NvbmZpZ3VyYXRpb24oc3RydWN0IGNkbnMzX2RldmljZSAqcHJpdl9kZXYpCj4gK3sKPiAr ICAgICAgIHN0cnVjdCBjZG5zM19lbmRwb2ludCAqcHJpdl9lcDsKPiArICAgICAgIHN0cnVjdCB1 c2JfZXAgKmVwOwo+ICsgICAgICAgaW50IHJlc3VsdCA9IDA7Cj4gKwo+ICsgICAgICAgaWYgKHBy aXZfZGV2LT5od19jb25maWd1cmVkX2ZsYWcpCj4gKyAgICAgICAgICAgICAgIHJldHVybjsKPiAr Cj4gKyAgICAgICB3cml0ZWwoVVNCX0NPTkZfQ0ZHU0VULCAmcHJpdl9kZXYtPnJlZ3MtPnVzYl9j b25mKTsKPiArICAgICAgIHdyaXRlbChFUF9DTURfRVJEWSB8IEVQX0NNRF9SRVFfQ01QTCwgJnBy aXZfZGV2LT5yZWdzLT5lcF9jbWQpOwo+ICsKPiArICAgICAgIGNkbnMzX3NldF9yZWdpc3Rlcl9i aXQoJnByaXZfZGV2LT5yZWdzLT51c2JfY29uZiwKPiArICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgVVNCX0NPTkZfVTFFTiB8IFVTQl9DT05GX1UyRU4pOwo+ICsKPiArICAgICAgIC8qIHdh aXQgdW50aWwgY29uZmlndXJhdGlvbiBzZXQgKi8KPiArICAgICAgIHJlc3VsdCA9IGNkbnMzX2hh bmRzaGFrZSgmcHJpdl9kZXYtPnJlZ3MtPnVzYl9zdHMsCj4gKyAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgVVNCX1NUU19DRkdTVFNfTUFTSywgMSwgMTAwKTsKPiArCj4gKyAgICAgICBw cml2X2Rldi0+aHdfY29uZmlndXJlZF9mbGFnID0gMTsKPiArICAgICAgIGNkbnMzX2FsbG93X2Vu YWJsZV9sMShwcml2X2RldiwgMSk7Cj4gKwo+ICsgICAgICAgbGlzdF9mb3JfZWFjaF9lbnRyeShl cCwgJnByaXZfZGV2LT5nYWRnZXQuZXBfbGlzdCwgZXBfbGlzdCkgewo+ICsgICAgICAgICAgICAg ICBpZiAoZXAtPmVuYWJsZWQpIHsKPiArICAgICAgICAgICAgICAgICAgICAgICBwcml2X2VwID0g ZXBfdG9fY2RuczNfZXAoZXApOwo+ICsgICAgICAgICAgICAgICAgICAgICAgIGNkbnMzX3N0YXJ0 X2FsbF9yZXF1ZXN0KHByaXZfZGV2LCBwcml2X2VwKTsKPiArICAgICAgICAgICAgICAgfQo+ICsg ICAgICAgfQo+ICt9Cj4gKwo+ICsvKioKPiArICogY2RuczNfcmVxdWVzdF9oYW5kbGVkIC0gY2hl Y2sgd2hldGhlciByZXF1ZXN0IGhhcyBiZWVuIGhhbmRsZWQgYnkgRE1BCj4gKyAqCj4gKyAqIEBw cml2X2VwOiBleHRlbmRlZCBlbmRwb2ludCBvYmplY3QuCj4gKyAqIEBwcml2X3JlcTogcmVxdWVz dCBvYmplY3QgZm9yIGNoZWNraW5nCj4gKyAqCj4gKyAqIEVuZHBvaW50IG11c3QgYmUgc2VsZWN0 ZWQgYmVmb3JlIGludm9raW5nIHRoaXMgZnVuY3Rpb24uCj4gKyAqCj4gKyAqIFJldHVybnMgZmFs c2UgaWYgcmVxdWVzdCBoYXMgbm90IGJlZW4gaGFuZGxlZCBieSBETUEsIGVsc2UgcmV0dXJucyB0 cnVlLgo+ICsgKgo+ICsgKiBTUiAtIHN0YXJ0IHJpbmcKPiArICogRVIgLSAgZW5kIHJpbmcKPiAr ICogRFEgPSBwcml2X2VwLT5kZXF1ZXVlIC0gZGVxdWV1ZSBwb3NpdGlvbgo+ICsgKiBFUSA9IHBy aXZfZXAtPmVucXVldWUgLSAgZW5xdWV1ZSBwb3NpdGlvbgo+ICsgKiBTVCA9IHByaXZfcmVxLT5z dGFydF90cmIgLSBpbmRleCBvZiBmaXJzdCBUUkIgaW4gdHJhbnNmZXIgcmluZwo+ICsgKiBFVCA9 IHByaXZfcmVxLT5lbmRfdHJiIC0gaW5kZXggb2YgbGFzdCBUUkIgaW4gdHJhbnNmZXIgcmluZwo+ ICsgKiBDSSA9IGN1cnJlbnRfaW5kZXggLSBpbmRleCBvZiBwcm9jZXNzZWQgVFJCIGJ5IERNQS4K PiArICoKPiArICogQXMgZmlyc3Qgc3RlcCwgZnVuY3Rpb24gY2hlY2tzIGlmIGN5Y2xlIGJpdCBm b3IgcHJpdl9yZXEtPnN0YXJ0X3RyYiBpcwo+ICsgKiBjb3JyZWN0Lgo+ICsgKgo+ICsgKiBzb21l IHJ1bGVzOgo+ICsgKiAxLiBwcml2X2VwLT5kZXF1ZXVlIG5ldmVyIGV4Y2VlZCBjdXJyZW50X2lu ZGV4Lgo+ICsgKiAyICBwcml2X2VwLT5lbnF1ZXVlIG5ldmVyIGV4Y2VlZCBwcml2X2VwLT5kZXF1 ZXVlCj4gKyAqCj4gKyAqIFRoZW4gV2UgY2FuIHNwbGl0IHJlY29nbml0aW9uIGludG8gdHdvIHBh cnRzOgo+ICsgKiBDYXNlIDEgLSBwcml2X2VwLT5kZXF1ZXVlIDwgY3VycmVudF9pbmRleAo+ICsg KiAgICAgIFNSIC4uLiBFUSAuLi4gRFEgLi4uIENJIC4uLiBFUgo+ICsgKiAgICAgIFNSIC4uLiBE USAuLi4gQ0kgLi4uIEVRIC4uLiBFUgo+ICsgKgo+ICsgKiAgICAgIFJlcXVlc3QgaGFzIGJlZW4g aGFuZGxlZCBieSBETUEgaWYgU1QgYW5kIEVUIGlzIGJldHdlZW4gRFEgYW5kIENJLgo+ICsgKgo+ ICsgKiBDYXNlIDIgLSBwcml2X2VwLT5kZXF1ZXVlID4gY3VycmVudF9pbmRleAo+ICsgKiBUaGlz IHNpdHVhdGlvbiB0YWtlIHBsYWNlIHdoZW4gQ0kgZ28gdGhyb3VnaCB0aGUgTElOSyBUUkIgYXQg dGhlIGVuZCBvZgo+ICsgKiB0cmFuc2ZlciByaW5nLgo+ICsgKiAgICAgIFNSIC4uLiBDSSAuLi4g RVEgLi4uIERRIC4uLiBFUgo+ICsgKgo+ICsgKiAgICAgIFJlcXVlc3QgaGFzIGJlZW4gaGFuZGxl ZCBieSBETUEgaWYgRVQgaXMgbGVzcyB0aGVuIENJIG9yCj4gKyAqICAgICAgRVQgaXMgZ3JlYXRl ciBvciBlcXVhbCBEUS4KPiArICovCj4gK3N0YXRpYyBib29sIGNkbnMzX3JlcXVlc3RfaGFuZGxl ZChzdHJ1Y3QgY2RuczNfZW5kcG9pbnQgKnByaXZfZXAsCj4gKyAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgIHN0cnVjdCBjZG5zM19yZXF1ZXN0ICpwcml2X3JlcSkKPiArewo+ICsgICAg ICAgc3RydWN0IGNkbnMzX2RldmljZSAqcHJpdl9kZXYgPSBwcml2X2VwLT5jZG5zM19kZXY7Cj4g KyAgICAgICBzdHJ1Y3QgY2RuczNfdHJiICp0cmIgPSBwcml2X3JlcS0+dHJiOwo+ICsgICAgICAg aW50IGN1cnJlbnRfaW5kZXggPSAwOwo+ICsgICAgICAgaW50IGhhbmRsZWQgPSAwOwo+ICsKPiAr ICAgICAgIGN1cnJlbnRfaW5kZXggPSAocmVhZGwoJnByaXZfZGV2LT5yZWdzLT5lcF90cmFkZHIp IC0KPiArICAgICAgICAgICAgICAgICAgICAgICAgcHJpdl9lcC0+dHJiX3Bvb2xfZG1hKSAvIFRS Ql9TSVpFOwo+ICsKPiArICAgICAgIHRyYiA9ICZwcml2X2VwLT50cmJfcG9vbFtwcml2X3JlcS0+ c3RhcnRfdHJiXTsKPiArCj4gKyAgICAgICBpZiAoKHRyYi0+Y29udHJvbCAgJiBUUkJfQ1lDTEUp ICE9IHByaXZfZXAtPmNjcykKPiArICAgICAgICAgICAgICAgZ290byBmaW5pc2g7Cj4gKwo+ICsg ICAgICAgaWYgKHByaXZfZXAtPmRlcXVldWUgPCBjdXJyZW50X2luZGV4KSB7Cj4gKyAgICAgICAg ICAgICAgIGlmICgoY3VycmVudF9pbmRleCA9PSAocHJpdl9lcC0+bnVtX3RyYnMgLSAxKSkgJiYK PiArICAgICAgICAgICAgICAgICAgICFwcml2X2VwLT5kZXF1ZXVlKQo+ICsgICAgICAgICAgICAg ICAgICAgICAgIGdvdG8gZmluaXNoOwo+ICsKPiArICAgICAgICAgICAgICAgaWYgKHByaXZfcmVx LT5lbmRfdHJiID49IHByaXZfZXAtPmRlcXVldWUgJiYKPiArICAgICAgICAgICAgICAgICAgIHBy aXZfcmVxLT5lbmRfdHJiIDwgY3VycmVudF9pbmRleCkKPiArICAgICAgICAgICAgICAgICAgICAg ICBoYW5kbGVkID0gMTsKPiArICAgICAgIH0gZWxzZSBpZiAocHJpdl9lcC0+ZGVxdWV1ZSAgPiBj dXJyZW50X2luZGV4KSB7Cj4gKyAgICAgICAgICAgICAgIGlmIChwcml2X3JlcS0+ZW5kX3RyYiAg PCBjdXJyZW50X2luZGV4IHx8Cj4gKyAgICAgICAgICAgICAgICAgICBwcml2X3JlcS0+ZW5kX3Ry YiA+PSBwcml2X2VwLT5kZXF1ZXVlKQo+ICsgICAgICAgICAgICAgICAgICAgICAgIGhhbmRsZWQg PSAxOwo+ICsgICAgICAgfQo+ICsKPiArZmluaXNoOgo+ICsgICAgICAgdHJhY2VfY2RuczNfcmVx dWVzdF9oYW5kbGVkKHByaXZfcmVxLCBjdXJyZW50X2luZGV4LCBoYW5kbGVkKTsKPiArCj4gKyAg ICAgICByZXR1cm4gaGFuZGxlZDsKPiArfQo+ICsKPiArc3RhdGljIHZvaWQgY2RuczNfdHJhbnNm ZXJfY29tcGxldGVkKHN0cnVjdCBjZG5zM19kZXZpY2UgKnByaXZfZGV2LAo+ICsgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJ1Y3QgY2RuczNfZW5kcG9pbnQgKnByaXZfZXAp Cj4gK3sKPiArICAgICAgIHN0cnVjdCBjZG5zM19yZXF1ZXN0ICpwcml2X3JlcTsKPiArICAgICAg IHN0cnVjdCB1c2JfcmVxdWVzdCAqcmVxdWVzdDsKPiArICAgICAgIHN0cnVjdCBjZG5zM190cmIg KnRyYjsKPiArCj4gKyAgICAgICB3aGlsZSAoIWxpc3RfZW1wdHkoJnByaXZfZXAtPnBlbmRpbmdf cmVxX2xpc3QpKSB7Cj4gKyAgICAgICAgICAgICAgIHJlcXVlc3QgPSBjZG5zM19uZXh0X3JlcXVl c3QoJnByaXZfZXAtPnBlbmRpbmdfcmVxX2xpc3QpOwo+ICsgICAgICAgICAgICAgICBwcml2X3Jl cSA9IHRvX2NkbnMzX3JlcXVlc3QocmVxdWVzdCk7Cj4gKwo+ICsgICAgICAgICAgICAgICAvKiBS ZS1zZWxlY3QgZW5kcG9pbnQuIEl0IGNvdWxkIGJlIGNoYW5nZWQgYnkgb3RoZXIgQ1BVIGR1cmlu Zwo+ICsgICAgICAgICAgICAgICAgKiBoYW5kbGluZyB1c2JfZ2FkZ2V0X2dpdmViYWNrX3JlcXVl c3QuCj4gKyAgICAgICAgICAgICAgICAqLwo+ICsgICAgICAgICAgICAgICBjZG5zM19zZWxlY3Rf ZXAocHJpdl9kZXYsIHByaXZfZXAtPmVuZHBvaW50LmFkZHJlc3MpOwo+ICsKPiArICAgICAgICAg ICAgICAgaWYgKCFjZG5zM19yZXF1ZXN0X2hhbmRsZWQocHJpdl9lcCwgcHJpdl9yZXEpKQo+ICsg ICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKPiArCj4gKyAgICAgICAgICAgICAgIGlmIChy ZXF1ZXN0LT5kbWEgJSA4ICYmIHByaXZfZXAtPmRpciA9PSBVU0JfRElSX09VVCkKPiArICAgICAg ICAgICAgICAgICAgICAgICBtZW1jcHkocmVxdWVzdC0+YnVmLCBwcml2X2VwLT5hbGlnbmVkX2J1 ZmYsCj4gKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcXVlc3QtPmxlbmd0aCk7Cj4g Kwo+ICsgICAgICAgICAgICAgICB0cmIgPSBwcml2X2VwLT50cmJfcG9vbCArIHByaXZfZXAtPmRl cXVldWU7Cj4gKyAgICAgICAgICAgICAgIHRyYWNlX2NkbnMzX2NvbXBsZXRlX3RyYihwcml2X2Vw LCB0cmIpOwo+ICsKPiArICAgICAgICAgICAgICAgaWYgKHRyYiAhPSBwcml2X3JlcS0+dHJiKQo+ ICsgICAgICAgICAgICAgICAgICAgICAgIGRldl93YXJuKHByaXZfZGV2LT5kZXYsCj4gKyAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgInJlcXVlc3RfdHJiPTB4JXAsIHF1ZXVlX3RyYj0w eCVwXG4iLAo+ICsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByaXZfcmVxLT50cmIs IHRyYik7Cj4gKwo+ICsgICAgICAgICAgICAgICByZXF1ZXN0LT5hY3R1YWwgPSBUUkJfTEVOKGxl MzJfdG9fY3B1KHRyYi0+bGVuZ3RoKSk7Cj4gKyAgICAgICAgICAgICAgIGNkbnMzX21vdmVfZGVx X3RvX25leHRfdHJiKHByaXZfcmVxKTsKPiArICAgICAgICAgICAgICAgY2RuczNfZ2FkZ2V0X2dp dmViYWNrKHByaXZfZXAsIHByaXZfcmVxLCAwKTsKPiArICAgICAgIH0KPiArICAgICAgIHByaXZf ZXAtPmZsYWdzICY9IH5FUF9QRU5ESU5HX1JFUVVFU1Q7Cj4gK30KPiArCj4gK3ZvaWQgY2RuczNf d2ExX3Jlc3RvcmVfY3ljbGVfYml0KHN0cnVjdCBjZG5zM19lbmRwb2ludCAqcHJpdl9lcCkKPiAr ewo+ICsgICAgICAgc3RydWN0IGNkbnMzX2RldmljZSAqcHJpdl9kZXYgPSBwcml2X2VwLT5jZG5z M19kZXY7Cj4gKwo+ICsgICAgICAgLyogV29yayBhcm91bmQgZm9yIHN0YWxlIGRhdGEgYWRkcmVz cyBpbiBUUkIqLwo+ICsgICAgICAgaWYgKHByaXZfZXAtPndhMV9zZXQpIHsKPiArICAgICAgICAg ICAgICAgY2RuczNfZGJnKHByaXZfZGV2LCAiV0ExOiB1cGRhdGUgY3ljbGUgYml0XG4iKTsKPiAr ICAgICAgICAgICAgICAgcHJpdl9lcC0+d2ExX3NldCA9IDA7Cj4gKyAgICAgICAgICAgICAgIGlm IChwcml2X2VwLT53YTFfY3ljbGVfYml0KSB7Cj4gKyAgICAgICAgICAgICAgICAgICAgICAgcHJp dl9lcC0+d2ExX3RyYi0+Y29udHJvbCA9Cj4gKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICBwcml2X2VwLT53YTFfdHJiLT5jb250cm9sIHwgMHgxOwo+ICsgICAgICAgICAgICAgICB9IGVs c2Ugewo+ICsgICAgICAgICAgICAgICAgICAgICAgIHByaXZfZXAtPndhMV90cmItPmNvbnRyb2wg PQo+ICsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJpdl9lcC0+d2ExX3RyYi0+Y29u dHJvbCAmIH4weDE7Cj4gKyAgICAgICAgICAgICAgIH0KPiArICAgICAgIH0KPiArfQo+ICsKPiAr dm9pZCBjZG5zM19yZWFybV90cmFuc2ZlcihzdHJ1Y3QgY2RuczNfZW5kcG9pbnQgKnByaXZfZXAs IHU4IHJlYXJtKQo+ICt7Cj4gKyAgICAgICBzdHJ1Y3QgY2RuczNfZGV2aWNlICpwcml2X2RldiA9 IHByaXZfZXAtPmNkbnMzX2RldjsKPiArCj4gKyAgICAgICBjZG5zM193YTFfcmVzdG9yZV9jeWNs ZV9iaXQocHJpdl9lcCk7Cj4gKwo+ICsgICAgICAgaWYgKHJlYXJtKSB7Cj4gKyAgICAgICAgICAg ICAgIHRyYWNlX2NkbnMzX3JpbmcocHJpdl9lcCk7Cj4gKwo+ICsgICAgICAgICAgICAgICAvKiBD eWNsZSBCaXQgbXVzdCBiZSB1cGRhdGVkIGJlZm9yZSBhcm1pbmcgRE1BLiAqLwo+ICsgICAgICAg ICAgICAgICB3bWIoKTsKPiArICAgICAgICAgICAgICAgd3JpdGVsKEVQX0NNRF9EUkRZLCAmcHJp dl9kZXYtPnJlZ3MtPmVwX2NtZCk7Cj4gKwo+ICsgICAgICAgICAgICAgICB0cmFjZV9jZG5zM19k b29yYmVsbF9lcHgocHJpdl9lcC0+bmFtZSwKPiArICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgIHJlYWRsKCZwcml2X2Rldi0+cmVncy0+ZXBfdHJhZGRyKSk7Cj4gKyAgICAg ICB9Cj4gK30KPiArCj4gKy8qKgo+ICsgKiBjZG5zM19jaGVja19lcF9pbnRlcnJ1cHRfcHJvY2Vl ZCAtIFByb2Nlc3NlcyBpbnRlcnJ1cHQgcmVsYXRlZCB0byBlbmRwb2ludAo+ICsgKiBAcHJpdl9l cDogZW5kcG9pbnQgb2JqZWN0Cj4gKyAqCj4gKyAqIFJldHVybnMgMAo+ICsgKi8KPiArc3RhdGlj IGludCBjZG5zM19jaGVja19lcF9pbnRlcnJ1cHRfcHJvY2VlZChzdHJ1Y3QgY2RuczNfZW5kcG9p bnQgKnByaXZfZXApCj4gK3sKPiArICAgICAgIHN0cnVjdCBjZG5zM19kZXZpY2UgKnByaXZfZGV2 ID0gcHJpdl9lcC0+Y2RuczNfZGV2Owo+ICsgICAgICAgdTMyIGVwX3N0c19yZWc7Cj4gKwo+ICsg ICAgICAgY2RuczNfc2VsZWN0X2VwKHByaXZfZGV2LCBwcml2X2VwLT5lbmRwb2ludC5hZGRyZXNz KTsKPiArCj4gKyAgICAgICB0cmFjZV9jZG5zM19lcHhfaXJxKHByaXZfZGV2LCBwcml2X2VwKTsK PiArCj4gKyAgICAgICBlcF9zdHNfcmVnID0gcmVhZGwoJnByaXZfZGV2LT5yZWdzLT5lcF9zdHMp Owo+ICsgICAgICAgd3JpdGVsKGVwX3N0c19yZWcsICZwcml2X2Rldi0+cmVncy0+ZXBfc3RzKTsK PiArCj4gKyAgICAgICBpZiAoZXBfc3RzX3JlZyAmIEVQX1NUU19UUkJFUlIpIHsKPiArICAgICAg ICAgICAgICAgLyoKPiArICAgICAgICAgICAgICAgICogRm9yIGlzb2Nocm9ub3VzIHRyYW5zZmVy IGRyaXZlciBjb21wbGV0ZXMgcmVxdWVzdCBvbgo+ICsgICAgICAgICAgICAgICAgKiBJT0Mgb3Ig b24gVFJCRVJSLiBJT0MgYXBwZWFycyBvbmx5IHdoZW4gZGV2aWNlIHJlY2VpdmUKPiArICAgICAg ICAgICAgICAgICogT1VUIGRhdGEgcGFja2V0LiBJZiBob3N0IGRpc2FibGUgc3RyZWFtIG9yIGxv c3Qgc29tZSBwYWNrZXQKPiArICAgICAgICAgICAgICAgICogdGhlbiB0aGUgb25seSB3YXkgdG8g ZmluaXNoIGFsbCBxdWV1ZWQgdHJhbnNmZXIgaXMgdG8gZG8gaXQKPiArICAgICAgICAgICAgICAg ICogb24gVFJCRVJSIGV2ZW50Lgo+ICsgICAgICAgICAgICAgICAgKi8KPiArICAgICAgICAgICAg ICAgaWYgKHByaXZfZXAtPnR5cGUgPT0gVVNCX0VORFBPSU5UX1hGRVJfSVNPQyAmJgo+ICsgICAg ICAgICAgICAgICAgICAgIXByaXZfZXAtPndhMV9zZXQpCj4gKyAgICAgICAgICAgICAgICAgICAg ICAgY2RuczNfdHJhbnNmZXJfY29tcGxldGVkKHByaXZfZGV2LCBwcml2X2VwKTsKPiArICAgICAg ICAgICAgICAgZWxzZQo+ICsgICAgICAgICAgICAgICAgICAgICAgIGNkbnMzX3JlYXJtX3RyYW5z ZmVyKHByaXZfZXAsIHByaXZfZXAtPndhMV9zZXQpOwo+ICsgICAgICAgfQo+ICsKPiArICAgICAg IGlmICgoZXBfc3RzX3JlZyAmIEVQX1NUU19JT0MpIHx8IChlcF9zdHNfcmVnICYgRVBfU1RTX0lT UCkpCj4gKyAgICAgICAgICAgICAgIGNkbnMzX3RyYW5zZmVyX2NvbXBsZXRlZChwcml2X2Rldiwg cHJpdl9lcCk7Cj4gKwo+ICsgICAgICAgcmV0dXJuIDA7Cj4gK30KPiArCj4gKy8qKgo+ICsgKiBj ZG5zM19jaGVja191c2JfaW50ZXJydXB0X3Byb2NlZWQgLSBQcm9jZXNzZXMgaW50ZXJydXB0IHJl bGF0ZWQgdG8gZGV2aWNlCj4gKyAqIEBwcml2X2RldjogZXh0ZW5kZWQgZ2FkZ2V0IG9iamVjdAo+ ICsgKiBAdXNiX2lzdHM6IGJpdG1hcCByZXByZXNlbnRhdGlvbiBvZiBkZXZpY2UncyByZXBvcnRl ZCBpbnRlcnJ1cHRzCj4gKyAqICh1c2JfaXN0cyByZWdpc3RlciB2YWx1ZSkKPiArICovCj4gK3N0 YXRpYyB2b2lkIGNkbnMzX2NoZWNrX3VzYl9pbnRlcnJ1cHRfcHJvY2VlZChzdHJ1Y3QgY2RuczNf ZGV2aWNlICpwcml2X2RldiwKPiArICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgdTMyIHVzYl9pc3RzKQo+ICt7Cj4gKyAgICAgICBpbnQgc3BlZWQgPSAwOwo+ICsK PiArICAgICAgIHRyYWNlX2NkbnMzX3VzYl9pcnEocHJpdl9kZXYsIHVzYl9pc3RzKTsKPiArICAg ICAgIC8qIENvbm5lY3Rpb24gZGV0ZWN0ZWQgKi8KPiArICAgICAgIGlmICh1c2JfaXN0cyAmIChV U0JfSVNUU19DT04ySSB8IFVTQl9JU1RTX0NPTkkpKSB7Cj4gKyAgICAgICAgICAgICAgIHNwZWVk ID0gY2RuczNfZ2V0X3NwZWVkKHByaXZfZGV2KTsKPiArICAgICAgICAgICAgICAgcHJpdl9kZXYt PmdhZGdldC5zcGVlZCA9IHNwZWVkOwo+ICsgICAgICAgICAgICAgICB1c2JfZ2FkZ2V0X3NldF9z dGF0ZSgmcHJpdl9kZXYtPmdhZGdldCwgVVNCX1NUQVRFX1BPV0VSRUQpOwo+ICsgICAgICAgICAg ICAgICBjZG5zM19lcDBfY29uZmlnKHByaXZfZGV2KTsKPiArICAgICAgIH0KPiArCj4gKyAgICAg ICAvKiBEaXNjb25uZWN0aW9uIGRldGVjdGVkICovCj4gKyAgICAgICBpZiAodXNiX2lzdHMgJiAo VVNCX0lTVFNfRElTMkkgfCBVU0JfSVNUU19ESVNJKSkgewo+ICsgICAgICAgICAgICAgICBpZiAo cHJpdl9kZXYtPmdhZGdldF9kcml2ZXIgJiYKPiArICAgICAgICAgICAgICAgICAgIHByaXZfZGV2 LT5nYWRnZXRfZHJpdmVyLT5kaXNjb25uZWN0KSB7Cj4gKyAgICAgICAgICAgICAgICAgICAgICAg c3Bpbl91bmxvY2soJnByaXZfZGV2LT5sb2NrKTsKPiArICAgICAgICAgICAgICAgICAgICAgICBw cml2X2Rldi0+Z2FkZ2V0X2RyaXZlci0+ZGlzY29ubmVjdCgmcHJpdl9kZXYtPmdhZGdldCk7Cj4g KyAgICAgICAgICAgICAgICAgICAgICAgc3Bpbl9sb2NrKCZwcml2X2Rldi0+bG9jayk7Cj4gKyAg ICAgICAgICAgICAgIH0KPiArCj4gKyAgICAgICAgICAgICAgIHByaXZfZGV2LT5nYWRnZXQuc3Bl ZWQgPSBVU0JfU1BFRURfVU5LTk9XTjsKPiArICAgICAgICAgICAgICAgdXNiX2dhZGdldF9zZXRf c3RhdGUoJnByaXZfZGV2LT5nYWRnZXQsIFVTQl9TVEFURV9OT1RBVFRBQ0hFRCk7Cj4gKyAgICAg ICAgICAgICAgIGNkbnMzX2h3X3Jlc2V0X2Vwc19jb25maWcocHJpdl9kZXYpOwo+ICsgICAgICAg fQo+ICsKPiArICAgICAgIC8qIHJlc2V0Ki8KPiArICAgICAgIGlmICh1c2JfaXN0cyAmIChVU0Jf SVNUU19VV1JFU0kgfCBVU0JfSVNUU19VSFJFU0kgfCBVU0JfSVNUU19VMlJFU0kpKSB7Cj4gKyAg ICAgICAgICAgICAgIC8qcmVhZCBhZ2FpbiB0byBjaGVjayB0aGUgYWN0dWFsbCBzcGVlZCovCj4g KyAgICAgICAgICAgICAgIHNwZWVkID0gY2RuczNfZ2V0X3NwZWVkKHByaXZfZGV2KTsKPiArICAg ICAgICAgICAgICAgdXNiX2dhZGdldF9zZXRfc3RhdGUoJnByaXZfZGV2LT5nYWRnZXQsIFVTQl9T VEFURV9ERUZBVUxUKTsKPiArICAgICAgICAgICAgICAgcHJpdl9kZXYtPmdhZGdldC5zcGVlZCA9 IHNwZWVkOwo+ICsgICAgICAgICAgICAgICBjZG5zM19od19yZXNldF9lcHNfY29uZmlnKHByaXZf ZGV2KTsKPiArICAgICAgICAgICAgICAgY2RuczNfZXAwX2NvbmZpZyhwcml2X2Rldik7Cj4gKyAg ICAgICB9Cj4gK30KPiArCj4gKy8qKgo+ICsgKiBjZG5zM19kZXZpY2VfaXJxX2hhbmRsZXItIGlu dGVycnVwdCBoYW5kbGVyIGZvciBkZXZpY2UgcGFydCBvZiBjb250cm9sbGVyCj4gKyAqCj4gKyAq IEBpcnE6IGlycSBudW1iZXIgZm9yIGNkbnMzIGNvcmUgZGV2aWNlCj4gKyAqIEBkYXRhOiBzdHJ1 Y3R1cmUgb2YgY2RuczMKPiArICoKPiArICogUmV0dXJucyBJUlFfSEFORExFRCBvciBJUlFfTk9O RQo+ICsgKi8KPiArc3RhdGljIGlycXJldHVybl90IGNkbnMzX2RldmljZV9pcnFfaGFuZGxlcihp bnQgaXJxLCB2b2lkICpkYXRhKQo+ICt7Cj4gKyAgICAgICBzdHJ1Y3QgY2RuczNfZGV2aWNlICpw cml2X2RldjsKPiArICAgICAgIHN0cnVjdCBjZG5zMyAqY2RucyA9IGRhdGE7Cj4gKyAgICAgICBp cnFyZXR1cm5fdCByZXQgPSBJUlFfTk9ORTsKPiArICAgICAgIHVuc2lnbmVkIGxvbmcgZmxhZ3M7 Cj4gKyAgICAgICB1MzIgcmVnOwo+ICsKPiArICAgICAgIHByaXZfZGV2ID0gY2Rucy0+Z2FkZ2V0 X2RldjsKPiArICAgICAgIHNwaW5fbG9ja19pcnFzYXZlKCZwcml2X2Rldi0+bG9jaywgZmxhZ3Mp Owo+ICsKPiArICAgICAgIC8qIGNoZWNrIFVTQiBkZXZpY2UgaW50ZXJydXB0ICovCj4gKyAgICAg ICByZWcgPSByZWFkbCgmcHJpdl9kZXYtPnJlZ3MtPnVzYl9pc3RzKTsKPiArICAgICAgIHdyaXRl bChyZWcsICZwcml2X2Rldi0+cmVncy0+dXNiX2lzdHMpOwo+ICsKPiArICAgICAgIGlmIChyZWcp IHsKPiArICAgICAgICAgICAgICAgY2RuczNfY2hlY2tfdXNiX2ludGVycnVwdF9wcm9jZWVkKHBy aXZfZGV2LCByZWcpOwo+ICsgICAgICAgICAgICAgICByZXQgPSBJUlFfSEFORExFRDsKPiArICAg ICAgIH0KPiArCj4gKyAgICAgICAvKiBjaGVjayBlbmRwb2ludCBpbnRlcnJ1cHQgKi8KPiArICAg ICAgIHJlZyA9IHJlYWRsKCZwcml2X2Rldi0+cmVncy0+ZXBfaXN0cyk7Cj4gKwo+ICsgICAgICAg aWYgKHJlZykgewo+ICsgICAgICAgICAgICAgICBwcml2X2Rldi0+c2hhZG93X2VwX2VuIHw9IHJl ZzsKPiArICAgICAgICAgICAgICAgcmVnID0gfnJlZyAmIHJlYWRsKCZwcml2X2Rldi0+cmVncy0+ ZXBfaWVuKTsKPiArICAgICAgICAgICAgICAgLyogbWFzayBkZWZlcnJlZCBpbnRlcnJ1cHQuICov Cj4gKyAgICAgICAgICAgICAgIHdyaXRlbChyZWcsICZwcml2X2Rldi0+cmVncy0+ZXBfaWVuKTsK PiArICAgICAgICAgICAgICAgcmV0ID0gSVJRX1dBS0VfVEhSRUFEOwo+ICsgICAgICAgfQo+ICsK PiArICAgICAgIHNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJnByaXZfZGV2LT5sb2NrLCBmbGFncyk7 Cj4gKyAgICAgICByZXR1cm4gcmV0Owo+ICt9Cj4gKwo+ICsvKioKPiArICogY2RuczNfZGV2aWNl X3RocmVhZF9pcnFfaGFuZGxlci0gaW50ZXJydXB0IGhhbmRsZXIgZm9yIGRldmljZSBwYXJ0Cj4g KyAqIG9mIGNvbnRyb2xsZXIKPiArICoKPiArICogQGlycTogaXJxIG51bWJlciBmb3IgY2RuczMg Y29yZSBkZXZpY2UKPiArICogQGRhdGE6IHN0cnVjdHVyZSBvZiBjZG5zMwo+ICsgKgo+ICsgKiBS ZXR1cm5zIElSUV9IQU5ETEVEIG9yIElSUV9OT05FCj4gKyAqLwo+ICtzdGF0aWMgaXJxcmV0dXJu X3QgY2RuczNfZGV2aWNlX3RocmVhZF9pcnFfaGFuZGxlcihpbnQgaXJxLCB2b2lkICpkYXRhKQo+ ICt7Cj4gKyAgICAgICBzdHJ1Y3QgY2RuczNfZGV2aWNlICpwcml2X2RldjsKPiArICAgICAgIHN0 cnVjdCBjZG5zMyAqY2RucyA9IGRhdGE7Cj4gKyAgICAgICBpcnFyZXR1cm5fdCByZXQgPSBJUlFf Tk9ORTsKPiArICAgICAgIHVuc2lnbmVkIGxvbmcgZmxhZ3M7Cj4gKyAgICAgICB1MzIgZXBfaWVu Owo+ICsgICAgICAgaW50IGJpdDsKPiArICAgICAgIHUzMiByZWc7Cj4gKwo+ICsgICAgICAgcHJp dl9kZXYgPSBjZG5zLT5nYWRnZXRfZGV2Owo+ICsgICAgICAgc3Bpbl9sb2NrX2lycXNhdmUoJnBy aXZfZGV2LT5sb2NrLCBmbGFncyk7Cj4gKwo+ICsgICAgICAgcmVnID0gcmVhZGwoJnByaXZfZGV2 LT5yZWdzLT5lcF9pc3RzKTsKPiArCj4gKyAgICAgICAvKiBoYW5kbGUgZGVmYXVsdCBlbmRwb2lu dCBPVVQgKi8KPiArICAgICAgIGlmIChyZWcgJiBFUF9JU1RTX0VQX09VVDApIHsKPiArICAgICAg ICAgICAgICAgY2RuczNfY2hlY2tfZXAwX2ludGVycnVwdF9wcm9jZWVkKHByaXZfZGV2LCBVU0Jf RElSX09VVCk7Cj4gKyAgICAgICAgICAgICAgIHJldCA9IElSUV9IQU5ETEVEOwo+ICsgICAgICAg fQo+ICsKPiArICAgICAgIC8qIGhhbmRsZSBkZWZhdWx0IGVuZHBvaW50IElOICovCj4gKyAgICAg ICBpZiAocmVnICYgRVBfSVNUU19FUF9JTjApIHsKPiArICAgICAgICAgICAgICAgY2RuczNfY2hl Y2tfZXAwX2ludGVycnVwdF9wcm9jZWVkKHByaXZfZGV2LCBVU0JfRElSX0lOKTsKPiArICAgICAg ICAgICAgICAgcmV0ID0gSVJRX0hBTkRMRUQ7Cj4gKyAgICAgICB9Cj4gKwo+ICsgICAgICAgLyog Y2hlY2sgaWYgaW50ZXJydXB0IGZyb20gbm9uIGRlZmF1bHQgZW5kcG9pbnQsIGlmIG5vIGV4aXQg Ki8KPiArICAgICAgIHJlZyAmPSB+KEVQX0lTVFNfRVBfT1VUMCB8IEVQX0lTVFNfRVBfSU4wKTsK PiArICAgICAgIGlmICghcmVnKQo+ICsgICAgICAgICAgICAgICBnb3RvIGlycWVuZDsKPiArCj4g KyAgICAgICBmb3JfZWFjaF9zZXRfYml0KGJpdCwgKHVuc2lnbmVkIGxvbmcgKikmcmVnLAo+ICsg ICAgICAgICAgICAgICAgICAgICAgICBzaXplb2YodTMyKSAqIEJJVFNfUEVSX0JZVEUpIHsKPiAr ICAgICAgICAgICAgICAgcHJpdl9kZXYtPnNoYWRvd19lcF9lbiB8PSBCSVQoYml0KTsKPiArICAg ICAgICAgICAgICAgY2RuczNfY2hlY2tfZXBfaW50ZXJydXB0X3Byb2NlZWQocHJpdl9kZXYtPmVw c1tiaXRdKTsKPiArICAgICAgICAgICAgICAgcmV0ID0gSVJRX0hBTkRMRUQ7Cj4gKyAgICAgICB9 Cj4gKwo+ICtpcnFlbmQ6Cj4gKyAgICAgICBlcF9pZW4gPSByZWFkbCgmcHJpdl9kZXYtPnJlZ3Mt PmVwX2llbikgfCBwcml2X2Rldi0+c2hhZG93X2VwX2VuOwo+ICsgICAgICAgcHJpdl9kZXYtPnNo YWRvd19lcF9lbiA9IDA7Cj4gKyAgICAgICAvKiBVbm1hc2sgYWxsIGhhbmRsZWQgRVAgaW50ZXJy dXB0cyAqLwo+ICsgICAgICAgd3JpdGVsKGVwX2llbiwgJnByaXZfZGV2LT5yZWdzLT5lcF9pZW4p Owo+ICsgICAgICAgc3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmcHJpdl9kZXYtPmxvY2ssIGZsYWdz KTsKPiArICAgICAgIHJldHVybiByZXQ7Cj4gK30KPiArCj4gKy8qKgo+ICsgKiBjZG5zM19lcF9v bmNoaXBfYnVmZmVyX3Jlc2VydmUgLSBUcnkgdG8gcmVzZXJ2ZSBvbmNoaXAgYnVmIGZvciBFUAo+ ICsgKgo+ICsgKiBUaGUgcmVhbCByZXNlcnZhdGlvbiB3aWxsIG9jY3VyIGR1cmluZyB3cml0ZSB0 byBFUF9DRkcgcmVnaXN0ZXIsCj4gKyAqIHRoaXMgZnVuY3Rpb24gaXMgdXNlZCB0byBjaGVjayBp ZiB0aGUgJ3NpemUnIHJlc2VydmF0aW9uIGlzIGFsbG93ZWQuCj4gKyAqCj4gKyAqIEBwcml2X2Rl djogZXh0ZW5kZWQgZ2FkZ2V0IG9iamVjdAo+ICsgKiBAc2l6ZTogdGhlIHNpemUgKEtCKSBmb3Ig RVAgd291bGQgbGlrZSB0byBhbGxvY2F0ZQo+ICsgKgo+ICsgKiBSZXR1cm4gMCBpZiB0aGUgcmVx dWlyZWQgc2l6ZSBjYW4gbWV0IG9yIG5lZ2F0aXZlIHZhbHVlIG9uIGZhaWx1cmUKPiArICovCj4g K3N0YXRpYyBpbnQgY2RuczNfZXBfb25jaGlwX2J1ZmZlcl9yZXNlcnZlKHN0cnVjdCBjZG5zM19k ZXZpY2UgKnByaXZfZGV2LAo+ICsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgIGludCBzaXplKQo+ICt7Cj4gKyAgICAgICB1MzIgb25jaGlwX21lbTsKPiArCj4gKyAgICAg ICBwcml2X2Rldi0+b25jaGlwX21lbV9hbGxvY2F0ZWRfc2l6ZSArPSBzaXplOwo+ICsKPiArICAg ICAgIG9uY2hpcF9tZW0gPSBVU0JfQ0FQMl9BQ1RVQUxfTUVNX1NJWkUocmVhZGwoJnByaXZfZGV2 LT5yZWdzLT51c2JfY2FwMikpOwo+ICsgICAgICAgaWYgKCFvbmNoaXBfbWVtKQo+ICsgICAgICAg ICAgICAgICBvbmNoaXBfbWVtID0gMjU2Owo+ICsKPiArICAgICAgIC8qIDJLQiBpcyByZXNlcnZl ZCBmb3IgRVAwKi8KPiArICAgICAgIG9uY2hpcF9tZW0gLT0gMjsKPiArICAgICAgIGlmIChwcml2 X2Rldi0+b25jaGlwX21lbV9hbGxvY2F0ZWRfc2l6ZSA+IG9uY2hpcF9tZW0pIHsKPiArICAgICAg ICAgICAgICAgcHJpdl9kZXYtPm9uY2hpcF9tZW1fYWxsb2NhdGVkX3NpemUgLT0gc2l6ZTsKPiAr ICAgICAgICAgICAgICAgcmV0dXJuIC1FUEVSTTsKPiArICAgICAgIH0KPiArCj4gKyAgICAgICBy ZXR1cm4gMDsKPiArfQo+ICsKPiArLyoqCj4gKyAqIGNkbnMzX2VwX2NvbmZpZyBDb25maWd1cmUg aGFyZHdhcmUgZW5kcG9pbnQKPiArICogQHByaXZfZXA6IGV4dGVuZGVkIGVuZHBvaW50IG9iamVj dAo+ICsgKi8KPiArdm9pZCBjZG5zM19lcF9jb25maWcoc3RydWN0IGNkbnMzX2VuZHBvaW50ICpw cml2X2VwKQo+ICt7Cj4gKyAgICAgICBib29sIGlzX2lzb19lcCA9IChwcml2X2VwLT50eXBlID09 IFVTQl9FTkRQT0lOVF9YRkVSX0lTT0MpOwo+ICsgICAgICAgc3RydWN0IGNkbnMzX2RldmljZSAq cHJpdl9kZXYgPSBwcml2X2VwLT5jZG5zM19kZXY7Cj4gKyAgICAgICB1MzIgYkVuZHBvaW50QWRk cmVzcyA9IHByaXZfZXAtPm51bSB8IHByaXZfZXAtPmRpcjsKPiArICAgICAgIHUzMiBidWZmZXJp bmcgPSBDRE5TM19FUF9CVUZfU0laRSAtIDE7Cj4gKyAgICAgICB1MzIgbWF4X3BhY2tldF9zaXpl ID0gMDsKPiArICAgICAgIHUzMiBlcF9jZmcgPSAwOwo+ICsgICAgICAgaW50IHJldDsKPiArCj4g KyAgICAgICBzd2l0Y2ggKHByaXZfZXAtPnR5cGUpIHsKPiArICAgICAgIGNhc2UgVVNCX0VORFBP SU5UX1hGRVJfSU5UOgo+ICsgICAgICAgICAgICAgICBlcF9jZmcgPSBFUF9DRkdfRVBUWVBFKFVT Ql9FTkRQT0lOVF9YRkVSX0lOVCk7Cj4gKyAgICAgICAgICAgICAgIGJyZWFrOwo+ICsgICAgICAg Y2FzZSBVU0JfRU5EUE9JTlRfWEZFUl9CVUxLOgo+ICsgICAgICAgICAgICAgICBlcF9jZmcgPSBF UF9DRkdfRVBUWVBFKFVTQl9FTkRQT0lOVF9YRkVSX0JVTEspOwo+ICsgICAgICAgICAgICAgICBi cmVhazsKPiArICAgICAgIGRlZmF1bHQ6Cj4gKyAgICAgICAgICAgICAgIGVwX2NmZyA9IEVQX0NG R19FUFRZUEUoVVNCX0VORFBPSU5UX1hGRVJfSVNPQyk7Cj4gKyAgICAgICAgICAgICAgIGJ1ZmZl cmluZyA9IHByaXZfZXAtPmVuZHBvaW50Lm11bHQgKyAxOwo+ICsgICAgICAgfQo+ICsKPiArICAg ICAgIHN3aXRjaCAocHJpdl9kZXYtPmdhZGdldC5zcGVlZCkgewo+ICsgICAgICAgY2FzZSBVU0Jf U1BFRURfRlVMTDoKPiArICAgICAgICAgICAgICAgbWF4X3BhY2tldF9zaXplID0gaXNfaXNvX2Vw ID8gMTAyMyA6IDY0Owo+ICsgICAgICAgICAgICAgICBicmVhazsKPiArICAgICAgIGNhc2UgVVNC X1NQRUVEX0hJR0g6Cj4gKyAgICAgICAgICAgICAgIG1heF9wYWNrZXRfc2l6ZSA9IGlzX2lzb19l cCA/IDEwMjQgOiA1MTI7Cj4gKyAgICAgICAgICAgICAgIGJyZWFrOwo+ICsgICAgICAgY2FzZSBV U0JfU1BFRURfU1VQRVI6Cj4gKyAgICAgICAgICAgICAgIG1heF9wYWNrZXRfc2l6ZSA9IDEwMjQ7 Cj4gKyAgICAgICAgICAgICAgIGlmIChwcml2X2VwLT50eXBlID09IFVTQl9FTkRQT0lOVF9YRkVS X0lTT0MpIHsKPiArICAgICAgICAgICAgICAgICAgICAgICBidWZmZXJpbmcgPSAocHJpdl9lcC0+ ZW5kcG9pbnQubXVsdCArIDEpICoKPiArICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAocHJpdl9lcC0+ZW5kcG9pbnQubWF4YnVyc3QgKyAxKTsKPiArCj4gKyAgICAgICAgICAgICAg ICAgICAgICAgaWYgKHByaXZfZXAtPmludGVydmFsID4gMSkKPiArICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgIGJ1ZmZlcmluZysrOwo+ICsgICAgICAgICAgICAgICB9Cj4gKyAgICAgICAg ICAgICAgIGJyZWFrOwo+ICsgICAgICAgZGVmYXVsdDoKPiArICAgICAgICAgICAgICAgLyogYWxs IG90aGVyIHNwZWVkIGFyZSBub3Qgc3VwcG9ydGVkICovCj4gKyAgICAgICAgICAgICAgIHJldHVy bjsKPiArICAgICAgIH0KPiArCj4gKyAgICAgICByZXQgPSBjZG5zM19lcF9vbmNoaXBfYnVmZmVy X3Jlc2VydmUocHJpdl9kZXYsIGJ1ZmZlcmluZyk7Cj4gKyAgICAgICBpZiAocmV0KSB7Cj4gKyAg ICAgICAgICAgICAgIGRldl9lcnIocHJpdl9kZXYtPmRldiwgIm9uY2hpcCBtZW0gaXMgZnVsbCwg ZXAgaXMgaW52YWxpZFxuIik7Cj4gKyAgICAgICAgICAgICAgIHJldHVybjsKPiArICAgICAgIH0K PiArCj4gKyAgICAgICBlcF9jZmcgfD0gRVBfQ0ZHX01BWFBLVFNJWkUobWF4X3BhY2tldF9zaXpl KSB8Cj4gKyAgICAgICAgICAgICAgICAgRVBfQ0ZHX01VTFQocHJpdl9lcC0+ZW5kcG9pbnQubXVs dCkgfAo+ICsgICAgICAgICAgICAgICAgIEVQX0NGR19CVUZGRVJJTkcoYnVmZmVyaW5nKSB8Cj4g KyAgICAgICAgICAgICAgICAgRVBfQ0ZHX01BWEJVUlNUKHByaXZfZXAtPmVuZHBvaW50Lm1heGJ1 cnN0KTsKPiArCj4gKyAgICAgICBjZG5zM19zZWxlY3RfZXAocHJpdl9kZXYsIGJFbmRwb2ludEFk ZHJlc3MpOwo+ICsgICAgICAgd3JpdGVsKGVwX2NmZywgJnByaXZfZGV2LT5yZWdzLT5lcF9jZmcp Owo+ICsKPiArICAgICAgIGRldl9kYmcocHJpdl9kZXYtPmRldiwgIkNvbmZpZ3VyZSAlczogd2l0 aCB2YWwgJTA4eFxuIiwKPiArICAgICAgICAgICAgICAgcHJpdl9lcC0+bmFtZSwgZXBfY2ZnKTsK PiArfQo+ICsKPiArLyogRmluZCBjb3JyZWN0IGRpcmVjdGlvbiBmb3IgSFcgZW5kcG9pbnQgYWNj b3JkaW5nIHRvIGRlc2NyaXB0aW9uICovCj4gK3N0YXRpYyBpbnQgY2RuczNfZXBfZGlyX2lzX2Nv cnJlY3Qoc3RydWN0IHVzYl9lbmRwb2ludF9kZXNjcmlwdG9yICpkZXNjLAo+ICsgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgc3RydWN0IGNkbnMzX2VuZHBvaW50ICpwcml2X2VwKQo+ ICt7Cj4gKyAgICAgICByZXR1cm4gKHByaXZfZXAtPmVuZHBvaW50LmNhcHMuZGlyX2luICYmIHVz Yl9lbmRwb2ludF9kaXJfaW4oZGVzYykpIHx8Cj4gKyAgICAgICAgICAgICAgKHByaXZfZXAtPmVu ZHBvaW50LmNhcHMuZGlyX291dCAmJiB1c2JfZW5kcG9pbnRfZGlyX291dChkZXNjKSk7Cj4gK30K PiArCj4gK3N0YXRpYyBzdHJ1Y3QKPiArY2RuczNfZW5kcG9pbnQgKmNkbnMzX2ZpbmRfYXZhaWxh YmxlX2VwKHN0cnVjdCBjZG5zM19kZXZpY2UgKnByaXZfZGV2LAo+ICsgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICBzdHJ1Y3QgdXNiX2VuZHBvaW50X2Rlc2NyaXB0b3IgKmRl c2MpCj4gK3sKPiArICAgICAgIHN0cnVjdCB1c2JfZXAgKmVwOwo+ICsgICAgICAgc3RydWN0IGNk bnMzX2VuZHBvaW50ICpwcml2X2VwOwo+ICsKPiArICAgICAgIGxpc3RfZm9yX2VhY2hfZW50cnko ZXAsICZwcml2X2Rldi0+Z2FkZ2V0LmVwX2xpc3QsIGVwX2xpc3QpIHsKPiArICAgICAgICAgICAg ICAgdW5zaWduZWQgbG9uZyBudW07Cj4gKyAgICAgICAgICAgICAgIGludCByZXQ7Cj4gKyAgICAg ICAgICAgICAgIC8qIGVwIG5hbWUgcGF0dGVybiBsaWtlcyBlcFhpbiBvciBlcFhvdXQgKi8KPiAr ICAgICAgICAgICAgICAgY2hhciBjWzJdID0ge2VwLT5uYW1lWzJdLCAnXDAnfTsKPiArCj4gKyAg ICAgICAgICAgICAgIHJldCA9IGtzdHJ0b3VsKGMsIDEwLCAmbnVtKTsKPiArICAgICAgICAgICAg ICAgaWYgKHJldCkKPiArICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gRVJSX1BUUihyZXQp Owo+ICsKPiArICAgICAgICAgICAgICAgcHJpdl9lcCA9IGVwX3RvX2NkbnMzX2VwKGVwKTsKPiAr ICAgICAgICAgICAgICAgaWYgKGNkbnMzX2VwX2Rpcl9pc19jb3JyZWN0KGRlc2MsIHByaXZfZXAp KSB7Cj4gKyAgICAgICAgICAgICAgICAgICAgICAgaWYgKCEocHJpdl9lcC0+ZmxhZ3MgJiBFUF9D TEFJTUVEKSkgewo+ICsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJpdl9lcC0+bnVt ICA9IG51bTsKPiArICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBwcml2X2Vw Owo+ICsgICAgICAgICAgICAgICAgICAgICAgIH0KPiArICAgICAgICAgICAgICAgfQo+ICsgICAg ICAgfQo+ICsKPiArICAgICAgIHJldHVybiBFUlJfUFRSKC1FTk9FTlQpOwo+ICt9Cj4gKwo+ICsv Kgo+ICsgKiAgQ2FkZW5jZSBJUCBoYXMgb25lIGxpbWl0YXRpb24gdGhhdCBhbGwgZW5kcG9pbnRz IG11c3QgYmUgY29uZmlndXJlZAo+ICsgKiAoVHlwZSAmIE1heFBhY2tldFNpemUpIGJlZm9yZSBz ZXR0aW5nIGNvbmZpZ3VyYXRpb24gdGhyb3VnaCBoYXJkd2FyZQo+ICsgKiByZWdpc3RlciwgaXQg bWVhbnMgd2UgY2FuJ3QgY2hhbmdlIGVuZHBvaW50cyBjb25maWd1cmF0aW9uIGFmdGVyCj4gKyAq IHNldF9jb25maWd1cmF0aW9uLgo+ICsgKgo+ICsgKiBUaGlzIGZ1bmN0aW9uIHNldCBFUF9DTEFJ TUVEIGZsYWcgd2hpY2ggaXMgYWRkZWQgd2hlbiB0aGUgZ2FkZ2V0IGRyaXZlcgo+ICsgKiB1c2Vz IHVzYl9lcF9hdXRvY29uZmlnIHRvIGNvbmZpZ3VyZSBzcGVjaWZpYyBlbmRwb2ludDsKPiArICog V2hlbiB0aGUgdWRjIGRyaXZlciByZWNlaXZlcyBzZXRfY29uZmlndXJpb24gcmVxdWVzdCwKPiAr ICogaXQgZ29lcyB0aHJvdWdoIGFsbCBjbGFpbWVkIGVuZHBvaW50cywgYW5kIGNvbmZpZ3VyZSBh bGwgZW5kcG9pbnRzCj4gKyAqIGFjY29yZGluZ2x5Lgo+ICsgKgo+ICsgKiBBdCB1c2JfZXBfb3Bz LmVuYWJsZS9kaXNhYmxlLCB3ZSBvbmx5IGVuYWJsZSBhbmQgZGlzYWJsZSBlbmRwb2ludCB0aHJv dWdoCj4gKyAqIGVwX2NmZyByZWdpc3RlciB3aGljaCBjYW4gYmUgY2hhbmdlZCBhZnRlciBzZXRf Y29uZmlndXJhdGlvbiwgYW5kIGRvCj4gKyAqIHNvbWUgc29mdHdhcmUgb3BlcmF0aW9uIGFjY29y ZGluZ2x5Lgo+ICsgKi8KPiArc3RhdGljIHN0cnVjdAo+ICt1c2JfZXAgKmNkbnMzX2dhZGdldF9t YXRjaF9lcChzdHJ1Y3QgdXNiX2dhZGdldCAqZ2FkZ2V0LAo+ICsgICAgICAgICAgICAgICAgICAg ICAgICAgICAgIHN0cnVjdCB1c2JfZW5kcG9pbnRfZGVzY3JpcHRvciAqZGVzYywKPiArICAgICAg ICAgICAgICAgICAgICAgICAgICAgICBzdHJ1Y3QgdXNiX3NzX2VwX2NvbXBfZGVzY3JpcHRvciAq Y29tcF9kZXNjKQo+ICt7Cj4gKyAgICAgICBzdHJ1Y3QgY2RuczNfZGV2aWNlICpwcml2X2RldiA9 IGdhZGdldF90b19jZG5zM19kZXZpY2UoZ2FkZ2V0KTsKPiArICAgICAgIHN0cnVjdCBjZG5zM19l bmRwb2ludCAqcHJpdl9lcDsKPiArICAgICAgIHVuc2lnbmVkIGxvbmcgZmxhZ3M7Cj4gKwo+ICsg ICAgICAgcHJpdl9lcCA9IGNkbnMzX2ZpbmRfYXZhaWxhYmxlX2VwKHByaXZfZGV2LCBkZXNjKTsK PiArICAgICAgIGlmIChJU19FUlIocHJpdl9lcCkpIHsKPiArICAgICAgICAgICAgICAgZGV2X2Vy cihwcml2X2Rldi0+ZGV2LCAibm8gYXZhaWxhYmxlIGVwXG4iKTsKPiArICAgICAgICAgICAgICAg cmV0dXJuIE5VTEw7Cj4gKyAgICAgICB9Cj4gKwo+ICsgICAgICAgZGV2X2RiZyhwcml2X2Rldi0+ ZGV2LCAibWF0Y2ggZW5kcG9pbnQ6ICVzXG4iLCBwcml2X2VwLT5uYW1lKTsKPiArCj4gKyAgICAg ICBzcGluX2xvY2tfaXJxc2F2ZSgmcHJpdl9kZXYtPmxvY2ssIGZsYWdzKTsKPiArICAgICAgIHBy aXZfZXAtPmVuZHBvaW50LmRlc2MgPSBkZXNjOwo+ICsgICAgICAgcHJpdl9lcC0+ZGlyICA9IHVz Yl9lbmRwb2ludF9kaXJfaW4oZGVzYykgPyBVU0JfRElSX0lOIDogVVNCX0RJUl9PVVQ7Cj4gKyAg ICAgICBwcml2X2VwLT50eXBlID0gdXNiX2VuZHBvaW50X3R5cGUoZGVzYyk7Cj4gKyAgICAgICBw cml2X2VwLT5mbGFncyB8PSBFUF9DTEFJTUVEOwo+ICsgICAgICAgcHJpdl9lcC0+aW50ZXJ2YWwg PSBkZXNjLT5iSW50ZXJ2YWwgPyBCSVQoZGVzYy0+YkludGVydmFsIC0gMSkgOiAwOwo+ICsKPiAr ICAgICAgIHNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJnByaXZfZGV2LT5sb2NrLCBmbGFncyk7Cj4g KyAgICAgICByZXR1cm4gJnByaXZfZXAtPmVuZHBvaW50Owo+ICt9Cj4gKwo+ICsvKioKPiArICog Y2RuczNfZ2FkZ2V0X2VwX2FsbG9jX3JlcXVlc3QgQWxsb2NhdGVzIHJlcXVlc3QKPiArICogQGVw OiBlbmRwb2ludCBvYmplY3QgYXNzb2NpYXRlZCB3aXRoIHJlcXVlc3QKPiArICogQGdmcF9mbGFn czogZ2ZwIGZsYWdzCj4gKyAqCj4gKyAqIFJldHVybnMgYWxsb2NhdGVkIHJlcXVlc3QgYWRkcmVz cywgTlVMTCBvbiBhbGxvY2F0aW9uIGVycm9yCj4gKyAqLwo+ICtzdHJ1Y3QgdXNiX3JlcXVlc3Qg KmNkbnMzX2dhZGdldF9lcF9hbGxvY19yZXF1ZXN0KHN0cnVjdCB1c2JfZXAgKmVwLAo+ICsgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2ZwX3QgZ2ZwX2Zs YWdzKQo+ICt7Cj4gKyAgICAgICBzdHJ1Y3QgY2RuczNfZW5kcG9pbnQgKnByaXZfZXAgPSBlcF90 b19jZG5zM19lcChlcCk7Cj4gKyAgICAgICBzdHJ1Y3QgY2RuczNfcmVxdWVzdCAqcHJpdl9yZXE7 Cj4gKwo+ICsgICAgICAgcHJpdl9yZXEgPSBremFsbG9jKHNpemVvZigqcHJpdl9yZXEpLCBnZnBf ZmxhZ3MpOwo+ICsgICAgICAgaWYgKCFwcml2X3JlcSkKPiArICAgICAgICAgICAgICAgcmV0dXJu IE5VTEw7Cj4gKwo+ICsgICAgICAgcHJpdl9yZXEtPnByaXZfZXAgPSBwcml2X2VwOwo+ICsKPiAr ICAgICAgIHRyYWNlX2NkbnMzX2FsbG9jX3JlcXVlc3QocHJpdl9yZXEpOwo+ICsgICAgICAgcmV0 dXJuICZwcml2X3JlcS0+cmVxdWVzdDsKPiArfQo+ICsKPiArLyoqCj4gKyAqIGNkbnMzX2dhZGdl dF9lcF9mcmVlX3JlcXVlc3QgRnJlZSBtZW1vcnkgb2NjdXBpZWQgYnkgcmVxdWVzdAo+ICsgKiBA ZXA6IGVuZHBvaW50IG9iamVjdCBhc3NvY2lhdGVkIHdpdGggcmVxdWVzdAo+ICsgKiBAcmVxdWVz dDogcmVxdWVzdCB0byBmcmVlIG1lbW9yeQo+ICsgKi8KPiArdm9pZCBjZG5zM19nYWRnZXRfZXBf ZnJlZV9yZXF1ZXN0KHN0cnVjdCB1c2JfZXAgKmVwLAo+ICsgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICBzdHJ1Y3QgdXNiX3JlcXVlc3QgKnJlcXVlc3QpCj4gK3sKPiArICAgICAgIHN0 cnVjdCBjZG5zM19yZXF1ZXN0ICpwcml2X3JlcSA9IHRvX2NkbnMzX3JlcXVlc3QocmVxdWVzdCk7 Cj4gKwo+ICsgICAgICAgdHJhY2VfY2RuczNfZnJlZV9yZXF1ZXN0KHByaXZfcmVxKTsKPiArICAg ICAgIGtmcmVlKHByaXZfcmVxKTsKPiArfQo+ICsKPiArLyoqCj4gKyAqIGNkbnMzX2dhZGdldF9l cF9lbmFibGUgRW5hYmxlIGVuZHBvaW50Cj4gKyAqIEBlcDogZW5kcG9pbnQgb2JqZWN0Cj4gKyAq IEBkZXNjOiBlbmRwb2ludCBkZXNjcmlwdG9yCj4gKyAqCj4gKyAqIFJldHVybnMgMCBvbiBzdWNj ZXNzLCBlcnJvciBjb2RlIGVsc2V3aGVyZQo+ICsgKi8KPiArc3RhdGljIGludCBjZG5zM19nYWRn ZXRfZXBfZW5hYmxlKHN0cnVjdCB1c2JfZXAgKmVwLAo+ICsgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICBjb25zdCBzdHJ1Y3QgdXNiX2VuZHBvaW50X2Rlc2NyaXB0b3IgKmRlc2MpCj4g K3sKPiArICAgICAgIHN0cnVjdCBjZG5zM19lbmRwb2ludCAqcHJpdl9lcDsKPiArICAgICAgIHN0 cnVjdCBjZG5zM19kZXZpY2UgKnByaXZfZGV2Owo+ICsgICAgICAgdTMyIHJlZyA9IEVQX1NUU19F Tl9UUkJFUlJFTjsKPiArICAgICAgIHUzMiBiRW5kcG9pbnRBZGRyZXNzOwo+ICsgICAgICAgdW5z aWduZWQgbG9uZyBmbGFnczsKPiArICAgICAgIGludCByZXQ7Cj4gKwo+ICsgICAgICAgcHJpdl9l cCA9IGVwX3RvX2NkbnMzX2VwKGVwKTsKPiArICAgICAgIHByaXZfZGV2ID0gcHJpdl9lcC0+Y2Ru czNfZGV2Owo+ICsKPiArICAgICAgIGlmICghZXAgfHwgIWRlc2MgfHwgZGVzYy0+YkRlc2NyaXB0 b3JUeXBlICE9IFVTQl9EVF9FTkRQT0lOVCkgewo+ICsgICAgICAgICAgICAgICBkZXZfZGJnKHBy aXZfZGV2LT5kZXYsICJ1c2JzczogaW52YWxpZCBwYXJhbWV0ZXJzXG4iKTsKPiArICAgICAgICAg ICAgICAgcmV0dXJuIC1FSU5WQUw7Cj4gKyAgICAgICB9Cj4gKwo+ICsgICAgICAgaWYgKCFkZXNj LT53TWF4UGFja2V0U2l6ZSkgewo+ICsgICAgICAgICAgICAgICBkZXZfZXJyKHByaXZfZGV2LT5k ZXYsICJ1c2JzczogbWlzc2luZyB3TWF4UGFja2V0U2l6ZVxuIik7Cj4gKyAgICAgICAgICAgICAg IHJldHVybiAtRUlOVkFMOwo+ICsgICAgICAgfQo+ICsKPiArICAgICAgIGlmIChkZXZfV0FSTl9P TkNFKHByaXZfZGV2LT5kZXYsIHByaXZfZXAtPmZsYWdzICYgRVBfRU5BQkxFRCwKPiArICAgICAg ICAgICAgICAgICAgICAgICAgICIlcyBpcyBhbHJlYWR5IGVuYWJsZWRcbiIsIHByaXZfZXAtPm5h bWUpKQo+ICsgICAgICAgICAgICAgICByZXR1cm4gMDsKPiArCj4gKyAgICAgICBzcGluX2xvY2tf aXJxc2F2ZSgmcHJpdl9kZXYtPmxvY2ssIGZsYWdzKTsKPiArCj4gKyAgICAgICBwcml2X2VwLT5l bmRwb2ludC5kZXNjID0gZGVzYzsKPiArICAgICAgIHByaXZfZXAtPnR5cGUgPSB1c2JfZW5kcG9p bnRfdHlwZShkZXNjKTsKPiArICAgICAgIHByaXZfZXAtPmludGVydmFsID0gZGVzYy0+YkludGVy dmFsID8gQklUKGRlc2MtPmJJbnRlcnZhbCAtIDEpIDogMDsKPiArCj4gKyAgICAgICBpZiAocHJp dl9lcC0+aW50ZXJ2YWwgPiBJU09fTUFYX0lOVEVSVkFMICYmCj4gKyAgICAgICAgICAgcHJpdl9l cC0+dHlwZSA9PSBVU0JfRU5EUE9JTlRfWEZFUl9JU09DKSB7Cj4gKyAgICAgICAgICAgICAgIGRl dl9lcnIocHJpdl9kZXYtPmRldiwgIkRyaXZlciBpcyBsaW1pdGVkIHRvICVkIHBlcmlvZFxuIiwK PiArICAgICAgICAgICAgICAgICAgICAgICBJU09fTUFYX0lOVEVSVkFMKTsKPiArCj4gKyAgICAg ICAgICAgICAgIHJldCA9ICAtRUlOVkFMOwo+ICsgICAgICAgICAgICAgICBnb3RvIGV4aXQ7Cj4g KyAgICAgICB9Cj4gKwo+ICsgICAgICAgcmV0ID0gY2RuczNfYWxsb2NhdGVfdHJiX3Bvb2wocHJp dl9lcCk7Cj4gKwo+ICsgICAgICAgaWYgKHJldCkKPiArICAgICAgICAgICAgICAgZ290byBleGl0 Owo+ICsKPiArICAgICAgIGJFbmRwb2ludEFkZHJlc3MgPSBwcml2X2VwLT5udW0gfCBwcml2X2Vw LT5kaXI7Cj4gKyAgICAgICBjZG5zM19zZWxlY3RfZXAocHJpdl9kZXYsIGJFbmRwb2ludEFkZHJl c3MpOwo+ICsKPiArICAgICAgIHRyYWNlX2NkbnMzX2dhZGdldF9lcF9lbmFibGUocHJpdl9lcCk7 Cj4gKwo+ICsgICAgICAgd3JpdGVsKEVQX0NNRF9FUFJTVCwgJnByaXZfZGV2LT5yZWdzLT5lcF9j bWQpOwo+ICsKPiArICAgICAgIHJldCA9IGNkbnMzX2hhbmRzaGFrZSgmcHJpdl9kZXYtPnJlZ3Mt PmVwX2NtZCwKPiArICAgICAgICAgICAgICAgICAgICAgICAgICAgICBFUF9DTURfQ1NUQUxMIHwg RVBfQ01EX0VQUlNULCAwLCAxMDApOwo+ICsKPiArICAgICAgIC8qIGVuYWJsZSBpbnRlcnJ1cHQg Zm9yIHNlbGVjdGVkIGVuZHBvaW50ICovCj4gKyAgICAgICBjZG5zM19zZXRfcmVnaXN0ZXJfYml0 KCZwcml2X2Rldi0+cmVncy0+ZXBfaWVuLAo+ICsgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICBCSVQoY2RuczNfZXBfYWRkcl90b19pbmRleChiRW5kcG9pbnRBZGRyZXNzKSkpOwo+ICsKPiAr ICAgICAgIHdyaXRlbChyZWcsICZwcml2X2Rldi0+cmVncy0+ZXBfc3RzX2VuKTsKPiArCj4gKyAg ICAgICBjZG5zM19zZXRfcmVnaXN0ZXJfYml0KCZwcml2X2Rldi0+cmVncy0+ZXBfY2ZnLCBFUF9D RkdfRU5BQkxFKTsKPiArCj4gKyAgICAgICBlcC0+ZGVzYyA9IGRlc2M7Cj4gKyAgICAgICBwcml2 X2VwLT5mbGFncyAmPSB+KEVQX1BFTkRJTkdfUkVRVUVTVCB8IEVQX1NUQUxMKTsKPiArICAgICAg IHByaXZfZXAtPmZsYWdzIHw9IEVQX0VOQUJMRUQgfCBFUF9VUERBVEVfRVBfVFJCQUREUjsKPiAr ICAgICAgIHByaXZfZXAtPndhMV9zZXQgPSAwOwo+ICsgICAgICAgcHJpdl9lcC0+ZW5xdWV1ZSA9 IDA7Cj4gKyAgICAgICBwcml2X2VwLT5kZXF1ZXVlID0gMDsKPiArICAgICAgIHJlZyA9IHJlYWRs KCZwcml2X2Rldi0+cmVncy0+ZXBfc3RzKTsKPiArICAgICAgIHByaXZfZXAtPnBjcyA9ICEhRVBf U1RTX0NDUyhyZWcpOwo+ICsgICAgICAgcHJpdl9lcC0+Y2NzID0gISFFUF9TVFNfQ0NTKHJlZyk7 Cj4gKyAgICAgICAvKiBvbmUgVFJCIGlzIHJlc2VydmVkIGZvciBsaW5rIFRSQiB1c2VkIGluIERN VUxUIG1vZGUqLwo+ICsgICAgICAgcHJpdl9lcC0+ZnJlZV90cmJzID0gcHJpdl9lcC0+bnVtX3Ry YnMgLSAxOwo+ICtleGl0Ogo+ICsgICAgICAgc3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmcHJpdl9k ZXYtPmxvY2ssIGZsYWdzKTsKPiArCj4gKyAgICAgICByZXR1cm4gcmV0Owo+ICt9Cj4gKwo+ICsv KioKPiArICogY2RuczNfZ2FkZ2V0X2VwX2Rpc2FibGUgRGlzYWJsZSBlbmRwb2ludAo+ICsgKiBA ZXA6IGVuZHBvaW50IG9iamVjdAo+ICsgKgo+ICsgKiBSZXR1cm5zIDAgb24gc3VjY2VzcywgZXJy b3IgY29kZSBlbHNld2hlcmUKPiArICovCj4gK3N0YXRpYyBpbnQgY2RuczNfZ2FkZ2V0X2VwX2Rp c2FibGUoc3RydWN0IHVzYl9lcCAqZXApCj4gK3sKPiArICAgICAgIHN0cnVjdCBjZG5zM19lbmRw b2ludCAqcHJpdl9lcDsKPiArICAgICAgIHN0cnVjdCBjZG5zM19kZXZpY2UgKnByaXZfZGV2Owo+ ICsgICAgICAgc3RydWN0IHVzYl9yZXF1ZXN0ICpyZXF1ZXN0Owo+ICsgICAgICAgdW5zaWduZWQg bG9uZyBmbGFnczsKPiArICAgICAgIGludCByZXQgPSAwOwo+ICsgICAgICAgdTMyIGVwX2NmZzsK PiArCj4gKyAgICAgICBpZiAoIWVwKSB7Cj4gKyAgICAgICAgICAgICAgIHByX2VycigidXNic3M6 IGludmFsaWQgcGFyYW1ldGVyc1xuIik7Cj4gKyAgICAgICAgICAgICAgIHJldHVybiAtRUlOVkFM Owo+ICsgICAgICAgfQo+ICsKPiArICAgICAgIHByaXZfZXAgPSBlcF90b19jZG5zM19lcChlcCk7 Cj4gKyAgICAgICBwcml2X2RldiA9IHByaXZfZXAtPmNkbnMzX2RldjsKPiArCj4gKyAgICAgICBp ZiAoZGV2X1dBUk5fT05DRShwcml2X2Rldi0+ZGV2LCAhKHByaXZfZXAtPmZsYWdzICYgRVBfRU5B QkxFRCksCj4gKyAgICAgICAgICAgICAgICAgICAgICAgICAiJXMgaXMgYWxyZWFkeSBkaXNhYmxl ZFxuIiwgcHJpdl9lcC0+bmFtZSkpCj4gKyAgICAgICAgICAgICAgIHJldHVybiAwOwo+ICsKPiAr ICAgICAgIHNwaW5fbG9ja19pcnFzYXZlKCZwcml2X2Rldi0+bG9jaywgZmxhZ3MpOwo+ICsKPiAr ICAgICAgIHRyYWNlX2NkbnMzX2dhZGdldF9lcF9kaXNhYmxlKHByaXZfZXApOwo+ICsKPiArICAg ICAgIGNkbnMzX3NlbGVjdF9lcChwcml2X2RldiwgZXAtPmRlc2MtPmJFbmRwb2ludEFkZHJlc3Mp Owo+ICsgICAgICAgcmV0ID0gY2RuczNfZGF0YV9mbHVzaChwcml2X2VwKTsKPiArCj4gKyAgICAg ICBlcF9jZmcgPSByZWFkbCgmcHJpdl9kZXYtPnJlZ3MtPmVwX2NmZyk7Cj4gKyAgICAgICBlcF9j ZmcgJj0gfkVQX0NGR19FTkFCTEU7Cj4gKyAgICAgICB3cml0ZWwoZXBfY2ZnLCAmcHJpdl9kZXYt PnJlZ3MtPmVwX2NmZyk7Cj4gKwo+ICsgICAgICAgd2hpbGUgKCFsaXN0X2VtcHR5KCZwcml2X2Vw LT5wZW5kaW5nX3JlcV9saXN0KSkgewo+ICsgICAgICAgICAgICAgICByZXF1ZXN0ID0gY2RuczNf bmV4dF9yZXF1ZXN0KCZwcml2X2VwLT5wZW5kaW5nX3JlcV9saXN0KTsKPiArCj4gKyAgICAgICAg ICAgICAgIGNkbnMzX2dhZGdldF9naXZlYmFjayhwcml2X2VwLCB0b19jZG5zM19yZXF1ZXN0KHJl cXVlc3QpLAo+ICsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLUVTSFVURE9X Tik7Cj4gKyAgICAgICB9Cj4gKwo+ICsgICAgICAgd2hpbGUgKCFsaXN0X2VtcHR5KCZwcml2X2Vw LT5kZWZlcnJlZF9yZXFfbGlzdCkpIHsKPiArICAgICAgICAgICAgICAgcmVxdWVzdCA9IGNkbnMz X25leHRfcmVxdWVzdCgmcHJpdl9lcC0+ZGVmZXJyZWRfcmVxX2xpc3QpOwo+ICsKPiArICAgICAg ICAgICAgICAgY2RuczNfZ2FkZ2V0X2dpdmViYWNrKHByaXZfZXAsIHRvX2NkbnMzX3JlcXVlc3Qo cmVxdWVzdCksCj4gKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAtRVNIVVRE T1dOKTsKPiArICAgICAgIH0KPiArCj4gKyAgICAgICBwcml2X2VwLT5kZXNjbWlzX3JlcSA9IE5V TEw7Cj4gKwo+ICsgICAgICAgZXAtPmRlc2MgPSBOVUxMOwo+ICsgICAgICAgcHJpdl9lcC0+Zmxh Z3MgJj0gfkVQX0VOQUJMRUQ7Cj4gKwo+ICsgICAgICAgc3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgm cHJpdl9kZXYtPmxvY2ssIGZsYWdzKTsKPiArCj4gKyAgICAgICByZXR1cm4gcmV0Owo+ICt9Cj4g Kwo+ICsvKioKPiArICogY2RuczNfZ2FkZ2V0X2VwX3F1ZXVlIFRyYW5zZmVyIGRhdGEgb24gZW5k cG9pbnQKPiArICogQGVwOiBlbmRwb2ludCBvYmplY3QKPiArICogQHJlcXVlc3Q6IHJlcXVlc3Qg b2JqZWN0Cj4gKyAqIEBnZnBfZmxhZ3M6IGdmcCBmbGFncwo+ICsgKgo+ICsgKiBSZXR1cm5zIDAg b24gc3VjY2VzcywgZXJyb3IgY29kZSBlbHNld2hlcmUKPiArICovCj4gK3N0YXRpYyBpbnQgX19j ZG5zM19nYWRnZXRfZXBfcXVldWUoc3RydWN0IHVzYl9lcCAqZXAsCj4gKyAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICBzdHJ1Y3QgdXNiX3JlcXVlc3QgKnJlcXVlc3QsCj4gKyAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZnBfdCBnZnBfZmxhZ3MpCj4gK3sKPiArICAg ICAgIHN0cnVjdCBjZG5zM19lbmRwb2ludCAqcHJpdl9lcCA9IGVwX3RvX2NkbnMzX2VwKGVwKTsK PiArICAgICAgIHN0cnVjdCBjZG5zM19kZXZpY2UgKnByaXZfZGV2ID0gcHJpdl9lcC0+Y2RuczNf ZGV2Owo+ICsgICAgICAgc3RydWN0IGNkbnMzX3JlcXVlc3QgKnByaXZfcmVxOwo+ICsgICAgICAg aW50IGRlZmVycmVkID0gMDsKPiArICAgICAgIGludCByZXQgPSAwOwo+ICsKPiArICAgICAgIHJl cXVlc3QtPmFjdHVhbCA9IDA7Cj4gKyAgICAgICByZXF1ZXN0LT5zdGF0dXMgPSAtRUlOUFJPR1JF U1M7Cj4gKyAgICAgICBwcml2X3JlcSA9IHRvX2NkbnMzX3JlcXVlc3QocmVxdWVzdCk7Cj4gKyAg ICAgICB0cmFjZV9jZG5zM19lcF9xdWV1ZShwcml2X3JlcSk7Cj4gKwo+ICsgICAgICAgcmV0ID0g dXNiX2dhZGdldF9tYXBfcmVxdWVzdF9ieV9kZXYocHJpdl9kZXYtPnN5c2RldiwgcmVxdWVzdCwK PiArICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVzYl9lbmRwb2lu dF9kaXJfaW4oZXAtPmRlc2MpKTsKPiArICAgICAgIGlmIChyZXQpCj4gKyAgICAgICAgICAgICAg IHJldHVybiByZXQ7Cj4gKwo+ICsgICAgICAgLyoKPiArICAgICAgICAqIElmIGhhcmR3YXJlIGVu ZHBvaW50IGNvbmZpZ3VyYXRpb24gaGFzIG5vdCBiZWVuIHNldCB5ZXQgdGhlbgo+ICsgICAgICAg ICoganVzdCBxdWV1ZSByZXF1ZXN0IGluIGRlZmVycmVkIGxpc3QuIFRyYW5zZmVyIHdpbGwgYmUg c3RhcnRlZCBpbgo+ICsgICAgICAgICogY2RuczNfc2V0X2h3X2NvbmZpZ3VyYXRpb24uCj4gKyAg ICAgICAgKi8KPiArICAgICAgIGlmICghcHJpdl9kZXYtPmh3X2NvbmZpZ3VyZWRfZmxhZykKPiAr ICAgICAgICAgICAgICAgZGVmZXJyZWQgPSAxOwo+ICsgICAgICAgZWxzZQo+ICsgICAgICAgICAg ICAgICByZXQgPSBjZG5zM19lcF9ydW5fdHJhbnNmZXIocHJpdl9lcCwgcmVxdWVzdCk7Cj4gKwo+ ICsgICAgICAgaWYgKHJldCB8fCBkZWZlcnJlZCkKPiArICAgICAgICAgICAgICAgbGlzdF9hZGRf dGFpbCgmcmVxdWVzdC0+bGlzdCwgJnByaXZfZXAtPmRlZmVycmVkX3JlcV9saXN0KTsKPiArICAg ICAgIGVsc2UKPiArICAgICAgICAgICAgICAgbGlzdF9hZGRfdGFpbCgmcmVxdWVzdC0+bGlzdCwg JnByaXZfZXAtPnBlbmRpbmdfcmVxX2xpc3QpOwo+ICsKPiArICAgICAgIHJldHVybiByZXQ7Cj4g K30KPiArCj4gK3N0YXRpYyBpbnQgY2RuczNfZ2FkZ2V0X2VwX3F1ZXVlKHN0cnVjdCB1c2JfZXAg KmVwLCBzdHJ1Y3QgdXNiX3JlcXVlc3QgKnJlcXVlc3QsCj4gKyAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgZ2ZwX3QgZ2ZwX2ZsYWdzKQo+ICt7Cj4gKyAgICAgICBzdHJ1Y3QgdXNiX3Jl cXVlc3QgKnpscF9yZXF1ZXN0Owo+ICsgICAgICAgc3RydWN0IGNkbnMzX2VuZHBvaW50ICpwcml2 X2VwOwo+ICsgICAgICAgc3RydWN0IGNkbnMzX2RldmljZSAqcHJpdl9kZXY7Cj4gKyAgICAgICB1 bnNpZ25lZCBsb25nIGZsYWdzOwo+ICsgICAgICAgaW50IHJldDsKPiArCj4gKyAgICAgICBpZiAo IXJlcXVlc3QgfHwgIWVwKQo+ICsgICAgICAgICAgICAgICByZXR1cm4gLUVJTlZBTDsKPiArCj4g KyAgICAgICBwcml2X2VwID0gZXBfdG9fY2RuczNfZXAoZXApOwo+ICsgICAgICAgcHJpdl9kZXYg PSBwcml2X2VwLT5jZG5zM19kZXY7Cj4gKwo+ICsgICAgICAgc3Bpbl9sb2NrX2lycXNhdmUoJnBy aXZfZGV2LT5sb2NrLCBmbGFncyk7Cj4gKwo+ICsgICAgICAgcmV0ID0gX19jZG5zM19nYWRnZXRf ZXBfcXVldWUoZXAsIHJlcXVlc3QsIGdmcF9mbGFncyk7Cj4gKwo+ICsgICAgICAgaWYgKHJldCA9 PSAwICYmIHJlcXVlc3QtPnplcm8gJiYgcmVxdWVzdC0+bGVuZ3RoICYmCj4gKyAgICAgICAgICAg KHJlcXVlc3QtPmxlbmd0aCAlIGVwLT5tYXhwYWNrZXQgPT0gMCkpIHsKPiArICAgICAgICAgICAg ICAgc3RydWN0IGNkbnMzX3JlcXVlc3QgKnByaXZfcmVxOwo+ICsKPiArICAgICAgICAgICAgICAg emxwX3JlcXVlc3QgPSBjZG5zM19nYWRnZXRfZXBfYWxsb2NfcmVxdWVzdChlcCwgR0ZQX0FUT01J Qyk7Cj4gKyAgICAgICAgICAgICAgIHpscF9yZXF1ZXN0LT5idWYgPSBwcml2X2Rldi0+emxwX2J1 ZjsKPiArICAgICAgICAgICAgICAgemxwX3JlcXVlc3QtPmxlbmd0aCA9IDA7Cj4gKwo+ICsgICAg ICAgICAgICAgICBwcml2X3JlcSA9IHRvX2NkbnMzX3JlcXVlc3QoemxwX3JlcXVlc3QpOwo+ICsg ICAgICAgICAgICAgICBwcml2X3JlcS0+ZmxhZ3MgfD0gUkVRVUVTVF9aTFA7Cj4gKwo+ICsgICAg ICAgICAgICAgICBkZXZfZGJnKHByaXZfZGV2LT5kZXYsICJRdWV1aW5nIFpMUCBmb3IgZW5kcG9p bnQ6ICVzXG4iLAo+ICsgICAgICAgICAgICAgICAgICAgICAgIHByaXZfZXAtPm5hbWUpOwo+ICsg ICAgICAgICAgICAgICByZXQgPSBfX2NkbnMzX2dhZGdldF9lcF9xdWV1ZShlcCwgemxwX3JlcXVl c3QsIGdmcF9mbGFncyk7Cj4gKyAgICAgICB9Cj4gKwo+ICsgICAgICAgc3Bpbl91bmxvY2tfaXJx cmVzdG9yZSgmcHJpdl9kZXYtPmxvY2ssIGZsYWdzKTsKPiArICAgICAgIHJldHVybiByZXQ7Cj4g K30KPiArCj4gKy8qKgo+ICsgKiBjZG5zM19nYWRnZXRfZXBfZGVxdWV1ZSBSZW1vdmUgcmVxdWVz dCBmcm9tIHRyYW5zZmVyIHF1ZXVlCj4gKyAqIEBlcDogZW5kcG9pbnQgb2JqZWN0IGFzc29jaWF0 ZWQgd2l0aCByZXF1ZXN0Cj4gKyAqIEByZXF1ZXN0OiByZXF1ZXN0IG9iamVjdAo+ICsgKgo+ICsg KiBSZXR1cm5zIDAgb24gc3VjY2VzcywgZXJyb3IgY29kZSBlbHNld2hlcmUKPiArICovCj4gK2lu dCBjZG5zM19nYWRnZXRfZXBfZGVxdWV1ZShzdHJ1Y3QgdXNiX2VwICplcCwKPiArICAgICAgICAg ICAgICAgICAgICAgICAgICAgc3RydWN0IHVzYl9yZXF1ZXN0ICpyZXF1ZXN0KQo+ICt7Cj4gKyAg ICAgICBzdHJ1Y3QgY2RuczNfZW5kcG9pbnQgKnByaXZfZXAgPSBlcF90b19jZG5zM19lcChlcCk7 Cj4gKyAgICAgICBzdHJ1Y3QgY2RuczNfZGV2aWNlICpwcml2X2RldiA9IHByaXZfZXAtPmNkbnMz X2RldjsKPiArICAgICAgIHN0cnVjdCB1c2JfcmVxdWVzdCAqcmVxLCAqcmVxX3RlbXA7Cj4gKyAg ICAgICBzdHJ1Y3QgY2RuczNfcmVxdWVzdCAqcHJpdl9yZXE7Cj4gKyAgICAgICBzdHJ1Y3QgY2Ru czNfdHJiICpsaW5rX3RyYjsKPiArICAgICAgIHVuc2lnbmVkIGxvbmcgZmxhZ3M7Cj4gKyAgICAg ICBpbnQgcmV0ID0gMDsKPiArCj4gKyAgICAgICBpZiAoIWVwIHx8ICFyZXF1ZXN0IHx8ICFlcC0+ ZGVzYykKPiArICAgICAgICAgICAgICAgcmV0dXJuIC1FSU5WQUw7Cj4gKwo+ICsgICAgICAgc3Bp bl9sb2NrX2lycXNhdmUoJnByaXZfZGV2LT5sb2NrLCBmbGFncyk7Cj4gKwo+ICsgICAgICAgcHJp dl9yZXEgPSB0b19jZG5zM19yZXF1ZXN0KHJlcXVlc3QpOwo+ICsKPiArICAgICAgIHRyYWNlX2Nk bnMzX2VwX2RlcXVldWUocHJpdl9yZXEpOwo+ICsKPiArICAgICAgIGNkbnMzX3NlbGVjdF9lcChw cml2X2RldiwgZXAtPmRlc2MtPmJFbmRwb2ludEFkZHJlc3MpOwo+ICsKPiArICAgICAgIGxpc3Rf Zm9yX2VhY2hfZW50cnlfc2FmZShyZXEsIHJlcV90ZW1wLCAmcHJpdl9lcC0+cGVuZGluZ19yZXFf bGlzdCwKPiArICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsaXN0KSB7Cj4gKyAgICAg ICAgICAgICAgIGlmIChyZXF1ZXN0ID09IHJlcSkKPiArICAgICAgICAgICAgICAgICAgICAgICBn b3RvIGZvdW5kOwo+ICsgICAgICAgfQo+ICsKPiArICAgICAgIGxpc3RfZm9yX2VhY2hfZW50cnlf c2FmZShyZXEsIHJlcV90ZW1wLCAmcHJpdl9lcC0+ZGVmZXJyZWRfcmVxX2xpc3QsCj4gKyAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgbGlzdCkgewo+ICsgICAgICAgICAgICAgICBpZiAo cmVxdWVzdCA9PSByZXEpCj4gKyAgICAgICAgICAgICAgICAgICAgICAgZ290byBmb3VuZDsKPiAr ICAgICAgIH0KPiArCj4gKyAgICAgICBnb3RvIG5vdF9mb3VuZDsKPiArCj4gK2ZvdW5kOgo+ICsK PiArICAgICAgIGlmIChwcml2X2VwLT53YTFfdHJiID09IHByaXZfcmVxLT50cmIpCj4gKyAgICAg ICAgICAgICAgIGNkbnMzX3dhMV9yZXN0b3JlX2N5Y2xlX2JpdChwcml2X2VwKTsKPiArCj4gKyAg ICAgICBsaW5rX3RyYiA9IHByaXZfcmVxLT50cmI7Cj4gKyAgICAgICBjZG5zM19tb3ZlX2RlcV90 b19uZXh0X3RyYihwcml2X3JlcSk7Cj4gKyAgICAgICBjZG5zM19nYWRnZXRfZ2l2ZWJhY2socHJp dl9lcCwgcHJpdl9yZXEsIC1FQ09OTlJFU0VUKTsKPiArCj4gKyAgICAgICAvKiBVcGRhdGUgcmlu ZyAqLwo+ICsgICAgICAgcmVxdWVzdCA9IGNkbnMzX25leHRfcmVxdWVzdCgmcHJpdl9lcC0+ZGVm ZXJyZWRfcmVxX2xpc3QpOwo+ICsgICAgICAgaWYgKHJlcXVlc3QpIHsKPiArICAgICAgICAgICAg ICAgcHJpdl9yZXEgPSB0b19jZG5zM19yZXF1ZXN0KHJlcXVlc3QpOwo+ICsKPiArICAgICAgICAg ICAgICAgbGlua190cmItPmJ1ZmZlciA9IFRSQl9CVUZGRVIocHJpdl9lcC0+dHJiX3Bvb2xfZG1h ICsKPiArICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHByaXZf cmVxLT5zdGFydF90cmIgKiBUUkJfU0laRSkpOwo+ICsgICAgICAgICAgICAgICBsaW5rX3RyYi0+ Y29udHJvbCA9IChsaW5rX3RyYi0+Y29udHJvbCAmIFRSQl9DWUNMRSkgfAo+ICsgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgIFRSQl9UWVBFKFRSQl9MSU5LKSB8IFRSQl9DSEFJTiB8 IFRSQl9UT0dHTEU7Cj4gKyAgICAgICB9IGVsc2Ugewo+ICsgICAgICAgICAgICAgICBwcml2X2Vw LT5mbGFncyB8PSBFUF9VUERBVEVfRVBfVFJCQUREUjsKPiArICAgICAgIH0KPiArCj4gK25vdF9m b3VuZDoKPiArICAgICAgIHNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJnByaXZfZGV2LT5sb2NrLCBm bGFncyk7Cj4gKyAgICAgICByZXR1cm4gcmV0Owo+ICt9Cj4gKwo+ICsvKioKPiArICogY2RuczNf Z2FkZ2V0X2VwX3NldF9oYWx0IFNldHMvY2xlYXJzIHN0YWxsIG9uIHNlbGVjdGVkIGVuZHBvaW50 Cj4gKyAqIEBlcDogZW5kcG9pbnQgb2JqZWN0IHRvIHNldC9jbGVhciBzdGFsbCBvbgo+ICsgKiBA dmFsdWU6IDEgZm9yIHNldCBzdGFsbCwgMCBmb3IgY2xlYXIgc3RhbGwKPiArICoKPiArICogUmV0 dXJucyAwIG9uIHN1Y2Nlc3MsIGVycm9yIGNvZGUgZWxzZXdoZXJlCj4gKyAqLwo+ICtpbnQgY2Ru czNfZ2FkZ2V0X2VwX3NldF9oYWx0KHN0cnVjdCB1c2JfZXAgKmVwLCBpbnQgdmFsdWUpCj4gK3sK PiArICAgICAgIHN0cnVjdCBjZG5zM19lbmRwb2ludCAqcHJpdl9lcCA9IGVwX3RvX2NkbnMzX2Vw KGVwKTsKPiArICAgICAgIHN0cnVjdCBjZG5zM19kZXZpY2UgKnByaXZfZGV2ID0gcHJpdl9lcC0+ Y2RuczNfZGV2Owo+ICsgICAgICAgdW5zaWduZWQgbG9uZyBmbGFnczsKPiArICAgICAgIGludCBy ZXQgPSAwOwo+ICsKPiArICAgICAgIGlmICghKHByaXZfZXAtPmZsYWdzICYgRVBfRU5BQkxFRCkp Cj4gKyAgICAgICAgICAgICAgIHJldHVybiAtRVBFUk07Cj4gKwo+ICsgICAgICAgc3Bpbl9sb2Nr X2lycXNhdmUoJnByaXZfZGV2LT5sb2NrLCBmbGFncyk7Cj4gKwo+ICsgICAgICAgY2RuczNfc2Vs ZWN0X2VwKHByaXZfZGV2LCBlcC0+ZGVzYy0+YkVuZHBvaW50QWRkcmVzcyk7Cj4gKyAgICAgICBp ZiAodmFsdWUpIHsKPiArICAgICAgICAgICAgICAgY2RuczNfZXBfc3RhbGxfZmx1c2gocHJpdl9l cCk7Cj4gKyAgICAgICB9IGVsc2Ugewo+ICsgICAgICAgICAgICAgICBwcml2X2VwLT5mbGFncyAm PSB+RVBfV0VER0U7Cj4gKwo+ICsgICAgICAgICAgICAgICBjZG5zM19kYmcocHJpdl9lcC0+Y2Ru czNfZGV2LCAiQ2xlYXIgc3RhbGxlZCBlbmRwb2ludCAlc1xuIiwKPiArICAgICAgICAgICAgICAg ICAgICAgICAgIHByaXZfZXAtPm5hbWUpOwo+ICsKPiArICAgICAgICAgICAgICAgd3JpdGVsKEVQ X0NNRF9DU1RBTEwgfCBFUF9DTURfRVBSU1QsICZwcml2X2Rldi0+cmVncy0+ZXBfY21kKTsKPiAr Cj4gKyAgICAgICAgICAgICAgIC8qIHdhaXQgZm9yIEVQUlNUIGNsZWFyZWQgKi8KPiArICAgICAg ICAgICAgICAgcmV0ID0gY2RuczNfaGFuZHNoYWtlKCZwcml2X2Rldi0+cmVncy0+ZXBfY21kLAo+ ICsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRVBfQ01EX0VQUlNULCAwLCAx MDApOwo+ICsgICAgICAgICAgICAgICBpZiAodW5saWtlbHkocmV0KSkgewo+ICsgICAgICAgICAg ICAgICAgICAgICAgIGRldl9lcnIocHJpdl9kZXYtPmRldiwKPiArICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICJDbGVhcmluZyBoYWx0IGNvbmRpdGlvbiBmYWlsZWQgZm9yICVzXG4iLAo+ ICsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJpdl9lcC0+bmFtZSk7Cj4gKyAgICAg ICAgICAgICAgICAgICAgICAgZ290byBmaW5pc2g7Cj4gKwo+ICsgICAgICAgICAgICAgICB9IGVs c2Ugewo+ICsgICAgICAgICAgICAgICAgICAgICAgIHByaXZfZXAtPmZsYWdzICY9IH5FUF9TVEFM TDsKPiArICAgICAgICAgICAgICAgfQo+ICsgICAgICAgfQo+ICsKPiArICAgICAgIHByaXZfZXAt PmZsYWdzICY9IH5FUF9QRU5ESU5HX1JFUVVFU1Q7Cj4gK2ZpbmlzaDoKPiArICAgICAgIHNwaW5f dW5sb2NrX2lycXJlc3RvcmUoJnByaXZfZGV2LT5sb2NrLCBmbGFncyk7Cj4gKwo+ICsgICAgICAg cmV0dXJuIHJldDsKPiArfQo+ICsKPiArZXh0ZXJuIGNvbnN0IHN0cnVjdCB1c2JfZXBfb3BzIGNk bnMzX2dhZGdldF9lcDBfb3BzOwo+ICsKPiArc3RhdGljIGNvbnN0IHN0cnVjdCB1c2JfZXBfb3Bz IGNkbnMzX2dhZGdldF9lcF9vcHMgPSB7Cj4gKyAgICAgICAuZW5hYmxlID0gY2RuczNfZ2FkZ2V0 X2VwX2VuYWJsZSwKPiArICAgICAgIC5kaXNhYmxlID0gY2RuczNfZ2FkZ2V0X2VwX2Rpc2FibGUs Cj4gKyAgICAgICAuYWxsb2NfcmVxdWVzdCA9IGNkbnMzX2dhZGdldF9lcF9hbGxvY19yZXF1ZXN0 LAo+ICsgICAgICAgLmZyZWVfcmVxdWVzdCA9IGNkbnMzX2dhZGdldF9lcF9mcmVlX3JlcXVlc3Qs Cj4gKyAgICAgICAucXVldWUgPSBjZG5zM19nYWRnZXRfZXBfcXVldWUsCj4gKyAgICAgICAuZGVx dWV1ZSA9IGNkbnMzX2dhZGdldF9lcF9kZXF1ZXVlLAo+ICsgICAgICAgLnNldF9oYWx0ID0gY2Ru czNfZ2FkZ2V0X2VwX3NldF9oYWx0LAo+ICsgICAgICAgLnNldF93ZWRnZSA9IGNkbnMzX2dhZGdl dF9lcF9zZXRfd2VkZ2UsCj4gK307Cj4gKwo+ICsvKioKPiArICogY2RuczNfZ2FkZ2V0X2dldF9m cmFtZSBSZXR1cm5zIG51bWJlciBvZiBhY3R1YWwgSVRQIGZyYW1lCj4gKyAqIEBnYWRnZXQ6IGdh ZGdldCBvYmplY3QKPiArICoKPiArICogUmV0dXJucyBudW1iZXIgb2YgYWN0dWFsIElUUCBmcmFt ZQo+ICsgKi8KPiArc3RhdGljIGludCBjZG5zM19nYWRnZXRfZ2V0X2ZyYW1lKHN0cnVjdCB1c2Jf Z2FkZ2V0ICpnYWRnZXQpCj4gK3sKPiArICAgICAgIHN0cnVjdCBjZG5zM19kZXZpY2UgKnByaXZf ZGV2ID0gZ2FkZ2V0X3RvX2NkbnMzX2RldmljZShnYWRnZXQpOwo+ICsKPiArICAgICAgIHJldHVy biByZWFkbCgmcHJpdl9kZXYtPnJlZ3MtPnVzYl9pcHRuKTsKPiArfQo+ICsKPiArc3RhdGljIGlu dCBjZG5zM19nYWRnZXRfd2FrZXVwKHN0cnVjdCB1c2JfZ2FkZ2V0ICpnYWRnZXQpCj4gK3sKPiAr ICAgICAgIHJldHVybiAwOwo+ICt9Cj4gKwo+ICtzdGF0aWMgaW50IGNkbnMzX2dhZGdldF9zZXRf c2VsZnBvd2VyZWQoc3RydWN0IHVzYl9nYWRnZXQgKmdhZGdldCwKPiArICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgaW50IGlzX3NlbGZwb3dlcmVkKQo+ICt7Cj4gKyAgICAg ICBzdHJ1Y3QgY2RuczNfZGV2aWNlICpwcml2X2RldiA9IGdhZGdldF90b19jZG5zM19kZXZpY2Uo Z2FkZ2V0KTsKPiArICAgICAgIHVuc2lnbmVkIGxvbmcgZmxhZ3M7Cj4gKwo+ICsgICAgICAgc3Bp bl9sb2NrX2lycXNhdmUoJnByaXZfZGV2LT5sb2NrLCBmbGFncyk7Cj4gKyAgICAgICBwcml2X2Rl di0+aXNfc2VsZnBvd2VyZWQgPSAhIWlzX3NlbGZwb3dlcmVkOwo+ICsgICAgICAgc3Bpbl91bmxv Y2tfaXJxcmVzdG9yZSgmcHJpdl9kZXYtPmxvY2ssIGZsYWdzKTsKPiArICAgICAgIHJldHVybiAw Owo+ICt9Cj4gKwo+ICtzdGF0aWMgaW50IGNkbnMzX2dhZGdldF9wdWxsdXAoc3RydWN0IHVzYl9n YWRnZXQgKmdhZGdldCwgaW50IGlzX29uKQo+ICt7Cj4gKyAgICAgICBzdHJ1Y3QgY2RuczNfZGV2 aWNlICpwcml2X2RldiA9IGdhZGdldF90b19jZG5zM19kZXZpY2UoZ2FkZ2V0KTsKPiArCj4gKyAg ICAgICBpZiAoaXNfb24pCj4gKyAgICAgICAgICAgICAgIHdyaXRlbChVU0JfQ09ORl9ERVZFTiwg JnByaXZfZGV2LT5yZWdzLT51c2JfY29uZik7Cj4gKyAgICAgICBlbHNlCj4gKyAgICAgICAgICAg ICAgIHdyaXRlbChVU0JfQ09ORl9ERVZEUywgJnByaXZfZGV2LT5yZWdzLT51c2JfY29uZik7Cj4g Kwo+ICsgICAgICAgcmV0dXJuIDA7Cj4gK30KPiArCj4gK3N0YXRpYyB2b2lkIGNkbnMzX2dhZGdl dF9jb25maWcoc3RydWN0IGNkbnMzX2RldmljZSAqcHJpdl9kZXYpCj4gK3sKPiArICAgICAgIHN0 cnVjdCBjZG5zM191c2JfcmVncyBfX2lvbWVtICpyZWdzID0gcHJpdl9kZXYtPnJlZ3M7Cj4gKwo+ ICsgICAgICAgY2RuczNfZXAwX2NvbmZpZyhwcml2X2Rldik7Cj4gKwo+ICsgICAgICAgLyogZW5h YmxlIGludGVycnVwdHMgZm9yIGVuZHBvaW50IDAgKGluIGFuZCBvdXQpICovCj4gKyAgICAgICB3 cml0ZWwoRVBfSUVOX0VQX09VVDAgfCBFUF9JRU5fRVBfSU4wLCAmcmVncy0+ZXBfaWVuKTsKPiAr Cj4gKyAgICAgICAvKgo+ICsgICAgICAgICpEcml2ZXIgbmVlZCBtb2RpZnkgTEZQUyBtaW5pbWFs IFUxIEV4aXQgdGltZSBmb3IgMHgwMDAyNDUwNSByZXZpc2lvbgo+ICsgICAgICAgICogb2YgY29u dHJvbGxlcgo+ICsgICAgICAgICovCj4gKyAgICAgICBpZiAocHJpdl9kZXYtPmRldl92ZXIgPT0g MHgwMDAyNDUwNSkgewo+ICsgICAgICAgICAgICAgICB1MzIgcmVnID0gcmVhZGwoJnJlZ3MtPmRi Z19saW5rMSk7Cj4gKwo+ICsgICAgICAgICAgICAgICByZWcgJj0gfkRCR19MSU5LMV9MRlBTX01J Tl9HRU5fVTFfRVhJVF9NQVNLOwo+ICsgICAgICAgICAgICAgICByZWcgfD0gREJHX0xJTksxX0xG UFNfTUlOX0dFTl9VMV9FWElUKDB4NTUpIHwKPiArICAgICAgICAgICAgICAgICAgICAgIERCR19M SU5LMV9MRlBTX01JTl9HRU5fVTFfRVhJVF9TRVQ7Cj4gKyAgICAgICAgICAgICAgIHdyaXRlbChy ZWcsICZyZWdzLT5kYmdfbGluazEpOwo+ICsgICAgICAgfQo+ICsKPiArICAgICAgIC8qIGVuYWJs ZSBnZW5lcmljIGludGVycnVwdCovCj4gKyAgICAgICB3cml0ZWwoVVNCX0lFTl9JTklULCAmcmVn cy0+dXNiX2llbik7Cj4gKyAgICAgICB3cml0ZWwoVVNCX0NPTkZfQ0xLMk9GRkRTIHwgVVNCX0NP TkZfTDFEUywgJnJlZ3MtPnVzYl9jb25mKTsKPiArICAgICAgIHdyaXRlbChVU0JfQ09ORl9ETVVM VCwgJnJlZ3MtPnVzYl9jb25mKTsKPiArICAgICAgIGNkbnMzX2dhZGdldF9wdWxsdXAoJnByaXZf ZGV2LT5nYWRnZXQsIDEpOwo+ICt9Cj4gKwo+ICsvKioKPiArICogY2RuczNfZ2FkZ2V0X3VkY19z dGFydCBHYWRnZXQgc3RhcnQKPiArICogQGdhZGdldDogZ2FkZ2V0IG9iamVjdAo+ICsgKiBAZHJp dmVyOiBkcml2ZXIgd2hpY2ggb3BlcmF0ZXMgb24gdGhpcyBnYWRnZXQKPiArICoKPiArICogUmV0 dXJucyAwIG9uIHN1Y2Nlc3MsIGVycm9yIGNvZGUgZWxzZXdoZXJlCj4gKyAqLwo+ICtzdGF0aWMg aW50IGNkbnMzX2dhZGdldF91ZGNfc3RhcnQoc3RydWN0IHVzYl9nYWRnZXQgKmdhZGdldCwKPiAr ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RydWN0IHVzYl9nYWRnZXRfZHJpdmVy ICpkcml2ZXIpCj4gK3sKPiArICAgICAgIHN0cnVjdCBjZG5zM19kZXZpY2UgKnByaXZfZGV2ID0g Z2FkZ2V0X3RvX2NkbnMzX2RldmljZShnYWRnZXQpOwo+ICsgICAgICAgdW5zaWduZWQgbG9uZyBm bGFnczsKPiArCj4gKyAgICAgICBzcGluX2xvY2tfaXJxc2F2ZSgmcHJpdl9kZXYtPmxvY2ssIGZs YWdzKTsKPiArICAgICAgIHByaXZfZGV2LT5nYWRnZXRfZHJpdmVyID0gZHJpdmVyOwo+ICsgICAg ICAgY2RuczNfZ2FkZ2V0X2NvbmZpZyhwcml2X2Rldik7Cj4gKyAgICAgICBzcGluX3VubG9ja19p cnFyZXN0b3JlKCZwcml2X2Rldi0+bG9jaywgZmxhZ3MpOwo+ICsgICAgICAgcmV0dXJuIDA7Cj4g K30KPiArCj4gKy8qKgo+ICsgKiBjZG5zM19nYWRnZXRfdWRjX3N0b3AgU3RvcHMgZ2FkZ2V0Cj4g KyAqIEBnYWRnZXQ6IGdhZGdldCBvYmplY3QKPiArICoKPiArICogUmV0dXJucyAwCj4gKyAqLwo+ ICtzdGF0aWMgaW50IGNkbnMzX2dhZGdldF91ZGNfc3RvcChzdHJ1Y3QgdXNiX2dhZGdldCAqZ2Fk Z2V0KQo+ICt7Cj4gKyAgICAgICBzdHJ1Y3QgY2RuczNfZGV2aWNlICpwcml2X2RldiA9IGdhZGdl dF90b19jZG5zM19kZXZpY2UoZ2FkZ2V0KTsKPiArICAgICAgIHN0cnVjdCBjZG5zM19lbmRwb2lu dCAqcHJpdl9lcDsKPiArICAgICAgIHUzMiBiRW5kcG9pbnRBZGRyZXNzOwo+ICsgICAgICAgc3Ry dWN0IHVzYl9lcCAqZXA7Cj4gKyAgICAgICBpbnQgcmV0ID0gMDsKPiArCj4gKyAgICAgICBwcml2 X2Rldi0+Z2FkZ2V0X2RyaXZlciA9IE5VTEw7Cj4gKwo+ICsgICAgICAgcHJpdl9kZXYtPm9uY2hp cF9tZW1fYWxsb2NhdGVkX3NpemUgPSAwOwo+ICsgICAgICAgcHJpdl9kZXYtPmdhZGdldC5zcGVl ZCA9IFVTQl9TUEVFRF9VTktOT1dOOwo+ICsKPiArICAgICAgIGxpc3RfZm9yX2VhY2hfZW50cnko ZXAsICZwcml2X2Rldi0+Z2FkZ2V0LmVwX2xpc3QsIGVwX2xpc3QpIHsKPiArICAgICAgICAgICAg ICAgcHJpdl9lcCA9IGVwX3RvX2NkbnMzX2VwKGVwKTsKPiArICAgICAgICAgICAgICAgYkVuZHBv aW50QWRkcmVzcyA9IHByaXZfZXAtPm51bSB8IHByaXZfZXAtPmRpcjsKPiArICAgICAgICAgICAg ICAgY2RuczNfc2VsZWN0X2VwKHByaXZfZGV2LCBiRW5kcG9pbnRBZGRyZXNzKTsKPiArICAgICAg ICAgICAgICAgd3JpdGVsKEVQX0NNRF9FUFJTVCwgJnByaXZfZGV2LT5yZWdzLT5lcF9jbWQpOwo+ ICsgICAgICAgICAgICAgICByZXQgPSBjZG5zM19oYW5kc2hha2UoJnByaXZfZGV2LT5yZWdzLT5l cF9jbWQsCj4gKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBFUF9DTURfRVBS U1QsIDAsIDEwMCk7Cj4gKyAgICAgICAgICAgICAgIGNkbnMzX2ZyZWVfdHJiX3Bvb2wocHJpdl9l cCk7Cj4gKyAgICAgICB9Cj4gKwo+ICsgICAgICAgLyogZGlzYWJsZSBpbnRlcnJ1cHQgZm9yIGRl dmljZSAqLwo+ICsgICAgICAgd3JpdGVsKDAsICZwcml2X2Rldi0+cmVncy0+dXNiX2llbik7Cj4g KyAgICAgICB3cml0ZWwoVVNCX0NPTkZfREVWRFMsICZwcml2X2Rldi0+cmVncy0+dXNiX2NvbmYp Owo+ICsKPiArICAgICAgIHJldHVybiByZXQ7Cj4gK30KPiArCj4gK3N0YXRpYyBjb25zdCBzdHJ1 Y3QgdXNiX2dhZGdldF9vcHMgY2RuczNfZ2FkZ2V0X29wcyA9IHsKPiArICAgICAgIC5nZXRfZnJh bWUgPSBjZG5zM19nYWRnZXRfZ2V0X2ZyYW1lLAo+ICsgICAgICAgLndha2V1cCA9IGNkbnMzX2dh ZGdldF93YWtldXAsCj4gKyAgICAgICAuc2V0X3NlbGZwb3dlcmVkID0gY2RuczNfZ2FkZ2V0X3Nl dF9zZWxmcG93ZXJlZCwKPiArICAgICAgIC5wdWxsdXAgPSBjZG5zM19nYWRnZXRfcHVsbHVwLAo+ ICsgICAgICAgLnVkY19zdGFydCA9IGNkbnMzX2dhZGdldF91ZGNfc3RhcnQsCj4gKyAgICAgICAu dWRjX3N0b3AgPSBjZG5zM19nYWRnZXRfdWRjX3N0b3AsCj4gKyAgICAgICAubWF0Y2hfZXAgPSBj ZG5zM19nYWRnZXRfbWF0Y2hfZXAsCj4gK307Cj4gKwo+ICtzdGF0aWMgdm9pZCBjZG5zM19mcmVl X2FsbF9lcHMoc3RydWN0IGNkbnMzX2RldmljZSAqcHJpdl9kZXYpCj4gK3sKPiArICAgICAgIGlu dCBpOwo+ICsKPiArICAgICAgIC8qZXAwIE9VVCBwb2ludCB0byBlcDAgSU4qLwo+ICsgICAgICAg cHJpdl9kZXYtPmVwc1sxNl0gPSBOVUxMOwo+ICsKPiArICAgICAgIGNkbnMzX2ZyZWVfdHJiX3Bv b2wocHJpdl9kZXYtPmVwc1swXSk7Cj4gKwo+ICsgICAgICAgZm9yIChpID0gMDsgaSA8IENETlMz X0VORFBPSU5UU19NQVhfQ09VTlQ7IGkrKykKPiArICAgICAgICAgICAgICAgaWYgKHByaXZfZGV2 LT5lcHNbaV0pCj4gKyAgICAgICAgICAgICAgICAgICAgICAgZGV2bV9rZnJlZShwcml2X2Rldi0+ ZGV2LCBwcml2X2Rldi0+ZXBzW2ldKTsKPiArfQo+ICsKPiArLyoqCj4gKyAqIGNkbnMzX2luaXRf ZXBzIEluaXRpYWxpemVzIHNvZnR3YXJlIGVuZHBvaW50cyBvZiBnYWRnZXQKPiArICogQGNkbnMz OiBleHRlbmRlZCBnYWRnZXQgb2JqZWN0Cj4gKyAqCj4gKyAqIFJldHVybnMgMCBvbiBzdWNjZXNz LCBlcnJvciBjb2RlIGVsc2V3aGVyZQo+ICsgKi8KPiArc3RhdGljIGludCBjZG5zM19pbml0X2Vw cyhzdHJ1Y3QgY2RuczNfZGV2aWNlICpwcml2X2RldikKPiArewo+ICsgICAgICAgdTMyIGVwX2Vu YWJsZWRfcmVnLCBpc29fZXBfcmVnOwo+ICsgICAgICAgc3RydWN0IGNkbnMzX2VuZHBvaW50ICpw cml2X2VwOwo+ICsgICAgICAgaW50IGVwX2RpciwgZXBfbnVtYmVyOwo+ICsgICAgICAgdTMyIGVw X21hc2s7Cj4gKyAgICAgICBpbnQgcmV0ID0gMDsKPiArICAgICAgIGludCBpOwo+ICsKPiArICAg ICAgIC8qIFJlYWQgaXQgZnJvbSBVU0JfQ0FQMyB0byBVU0JfQ0FQNSAqLwo+ICsgICAgICAgZXBf ZW5hYmxlZF9yZWcgPSByZWFkbCgmcHJpdl9kZXYtPnJlZ3MtPnVzYl9jYXAzKTsKPiArICAgICAg IGlzb19lcF9yZWcgPSByZWFkbCgmcHJpdl9kZXYtPnJlZ3MtPnVzYl9jYXA0KTsKPiArCj4gKyAg ICAgICBkZXZfZGJnKHByaXZfZGV2LT5kZXYsICJJbml0aWFsaXppbmcgbm9uLXplcm8gZW5kcG9p bnRzXG4iKTsKPiArCj4gKyAgICAgICBmb3IgKGkgPSAwOyBpIDwgQ0ROUzNfRU5EUE9JTlRTX01B WF9DT1VOVDsgaSsrKSB7Cj4gKyAgICAgICAgICAgICAgIGVwX2RpciA9IGkgPj4gNDsgICAgICAg IC8qIGkgZGl2IDE2ICovCj4gKyAgICAgICAgICAgICAgIGVwX251bWJlciA9IGkgJiAweEY7ICAg IC8qIGkgJSAxNiAqLwo+ICsgICAgICAgICAgICAgICBlcF9tYXNrID0gQklUKGkpOwo+ICsKPiAr ICAgICAgICAgICAgICAgaWYgKCEoZXBfZW5hYmxlZF9yZWcgJiBlcF9tYXNrKSkKPiArICAgICAg ICAgICAgICAgICAgICAgICBjb250aW51ZTsKPiArCj4gKyAgICAgICAgICAgICAgIGlmIChlcF9k aXIgJiYgIWVwX251bWJlcikgewo+ICsgICAgICAgICAgICAgICAgICAgICAgIHByaXZfZGV2LT5l cHNbaV0gPSBwcml2X2Rldi0+ZXBzWzBdOwo+ICsgICAgICAgICAgICAgICAgICAgICAgIGNvbnRp bnVlOwo+ICsgICAgICAgICAgICAgICB9Cj4gKwo+ICsgICAgICAgICAgICAgICBwcml2X2VwID0g ZGV2bV9remFsbG9jKHByaXZfZGV2LT5kZXYsIHNpemVvZigqcHJpdl9lcCksCj4gKyAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgR0ZQX0tFUk5FTCk7Cj4gKyAgICAgICAgICAg ICAgIGlmICghcHJpdl9lcCkgewo+ICsgICAgICAgICAgICAgICAgICAgICAgIHJldCA9IC1FTk9N RU07Cj4gKyAgICAgICAgICAgICAgICAgICAgICAgZ290byBlcnI7Cj4gKyAgICAgICAgICAgICAg IH0KPiArCj4gKyAgICAgICAgICAgICAgIC8qIHNldCBwYXJlbnQgb2YgZW5kcG9pbnQgb2JqZWN0 ICovCj4gKyAgICAgICAgICAgICAgIHByaXZfZXAtPmNkbnMzX2RldiA9IHByaXZfZGV2Owo+ICsg ICAgICAgICAgICAgICBwcml2X2Rldi0+ZXBzW2ldID0gcHJpdl9lcDsKPiArICAgICAgICAgICAg ICAgcHJpdl9lcC0+bnVtID0gZXBfbnVtYmVyOwo+ICsgICAgICAgICAgICAgICBwcml2X2VwLT5k aXIgPSBlcF9kaXIgPyBVU0JfRElSX0lOIDogVVNCX0RJUl9PVVQ7Cj4gKwo+ICsgICAgICAgICAg ICAgICBpZiAoIWVwX251bWJlcikgewo+ICsgICAgICAgICAgICAgICAgICAgICAgIHJldCA9IGNk bnMzX2luaXRfZXAwKHByaXZfZGV2LCBwcml2X2VwKTsKPiArICAgICAgICAgICAgICAgICAgICAg ICBpZiAocmV0KSB7Cj4gKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZXZfZXJyKHBy aXZfZGV2LT5kZXYsICJGYWlsZWQgdG8gaW5pdCBlcDBcbiIpOwo+ICsgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgZ290byBlcnI7Cj4gKyAgICAgICAgICAgICAgICAgICAgICAgfQo+ICsg ICAgICAgICAgICAgICB9IGVsc2Ugewo+ICsgICAgICAgICAgICAgICAgICAgICAgIHNucHJpbnRm KHByaXZfZXAtPm5hbWUsIHNpemVvZihwcml2X2VwLT5uYW1lKSwgImVwJWQlcyIsCj4gKyAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgZXBfbnVtYmVyLCAhIWVwX2RpciA/ICJpbiIgOiAi b3V0Iik7Cj4gKyAgICAgICAgICAgICAgICAgICAgICAgcHJpdl9lcC0+ZW5kcG9pbnQubmFtZSA9 IHByaXZfZXAtPm5hbWU7Cj4gKwo+ICsgICAgICAgICAgICAgICAgICAgICAgIHVzYl9lcF9zZXRf bWF4cGFja2V0X2xpbWl0KCZwcml2X2VwLT5lbmRwb2ludCwKPiArICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDRE5TM19FUF9NQVhfUEFDS0VUX0xJTUlU KTsKPiArICAgICAgICAgICAgICAgICAgICAgICBwcml2X2VwLT5lbmRwb2ludC5tYXhfc3RyZWFt cyA9IENETlMzX0VQX01BWF9TVFJFQU1TOwo+ICsgICAgICAgICAgICAgICAgICAgICAgIHByaXZf ZXAtPmVuZHBvaW50Lm9wcyA9ICZjZG5zM19nYWRnZXRfZXBfb3BzOwo+ICsgICAgICAgICAgICAg ICAgICAgICAgIGlmIChlcF9kaXIpCj4gKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBw cml2X2VwLT5lbmRwb2ludC5jYXBzLmRpcl9pbiA9IDE7Cj4gKyAgICAgICAgICAgICAgICAgICAg ICAgZWxzZQo+ICsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJpdl9lcC0+ZW5kcG9p bnQuY2Fwcy5kaXJfb3V0ID0gMTsKPiArCj4gKyAgICAgICAgICAgICAgICAgICAgICAgaWYgKGlz b19lcF9yZWcgJiBlcF9tYXNrKQo+ICsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJp dl9lcC0+ZW5kcG9pbnQuY2Fwcy50eXBlX2lzbyA9IDE7Cj4gKwo+ICsgICAgICAgICAgICAgICAg ICAgICAgIHByaXZfZXAtPmVuZHBvaW50LmNhcHMudHlwZV9idWxrID0gMTsKPiArICAgICAgICAg ICAgICAgICAgICAgICBwcml2X2VwLT5lbmRwb2ludC5jYXBzLnR5cGVfaW50ID0gMTsKPiArICAg ICAgICAgICAgICAgICAgICAgICBwcml2X2VwLT5lbmRwb2ludC5tYXhidXJzdCA9IENETlMzX0VQ X0JVRl9TSVpFIC0gMTsKPiArCj4gKyAgICAgICAgICAgICAgICAgICAgICAgbGlzdF9hZGRfdGFp bCgmcHJpdl9lcC0+ZW5kcG9pbnQuZXBfbGlzdCwKPiArICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICZwcml2X2Rldi0+Z2FkZ2V0LmVwX2xpc3QpOwo+ICsgICAgICAgICAgICAg ICB9Cj4gKwo+ICsgICAgICAgICAgICAgICBwcml2X2VwLT5mbGFncyA9IDA7Cj4gKwo+ICsgICAg ICAgICAgICAgICBkZXZfaW5mbyhwcml2X2Rldi0+ZGV2LCAiSW5pdGlhbGl6ZWQgICVzIHN1cHBv cnQ6ICVzICVzXG4iLAo+ICsgICAgICAgICAgICAgICAgICAgICAgICBwcml2X2VwLT5uYW1lLAo+ ICsgICAgICAgICAgICAgICAgICAgICAgICBwcml2X2VwLT5lbmRwb2ludC5jYXBzLnR5cGVfYnVs ayA/ICJCVUxLLCBJTlQiIDogIiIsCj4gKyAgICAgICAgICAgICAgICAgICAgICAgIHByaXZfZXAt PmVuZHBvaW50LmNhcHMudHlwZV9pc28gPyAiSVNPIiA6ICIiKTsKPiArCj4gKyAgICAgICAgICAg ICAgIElOSVRfTElTVF9IRUFEKCZwcml2X2VwLT5wZW5kaW5nX3JlcV9saXN0KTsKPiArICAgICAg ICAgICAgICAgSU5JVF9MSVNUX0hFQUQoJnByaXZfZXAtPmRlZmVycmVkX3JlcV9saXN0KTsKPiAr ICAgICAgIH0KPiArCj4gKyAgICAgICByZXR1cm4gMDsKPiArZXJyOgo+ICsgICAgICAgY2RuczNf ZnJlZV9hbGxfZXBzKHByaXZfZGV2KTsKPiArICAgICAgIHJldHVybiAtRU5PTUVNOwo+ICt9Cj4g Kwo+ICtzdGF0aWMgdm9pZCBjZG5zM19nYWRnZXRfZGlzYWJsZShzdHJ1Y3QgY2RuczMgKmNkbnMp Cj4gK3sKPiArICAgICAgIHN0cnVjdCBjZG5zM19kZXZpY2UgKnByaXZfZGV2Owo+ICsKPiArICAg ICAgIHByaXZfZGV2ID0gY2Rucy0+Z2FkZ2V0X2RldjsKPiArCj4gKyAgICAgICBpZiAocHJpdl9k ZXYtPmdhZGdldF9kcml2ZXIpCj4gKyAgICAgICAgICAgICAgIHByaXZfZGV2LT5nYWRnZXRfZHJp dmVyLT5kaXNjb25uZWN0KCZwcml2X2Rldi0+Z2FkZ2V0KTsKPiArCj4gKyAgICAgICB1c2JfZ2Fk Z2V0X2Rpc2Nvbm5lY3QoJnByaXZfZGV2LT5nYWRnZXQpOwo+ICsgICAgICAgcHJpdl9kZXYtPmdh ZGdldC5zcGVlZCA9IFVTQl9TUEVFRF9VTktOT1dOOwo+ICt9Cj4gKwo+ICt2b2lkIGNkbnMzX2dh ZGdldF9leGl0KHN0cnVjdCBjZG5zMyAqY2RucykKPiArewo+ICsgICAgICAgc3RydWN0IGNkbnMz X2RldmljZSAqcHJpdl9kZXY7Cj4gKwo+ICsgICAgICAgcHJpdl9kZXYgPSBjZG5zLT5nYWRnZXRf ZGV2Owo+ICsKPiArICAgICAgIGNkbnMzX2dhZGdldF9kaXNhYmxlKGNkbnMpOwo+ICsKPiArICAg ICAgIGRldm1fZnJlZV9pcnEoY2Rucy0+ZGV2LCBjZG5zLT5pcnEsIGNkbnMpOwo+ICsKPiArICAg ICAgIHBtX3J1bnRpbWVfbWFya19sYXN0X2J1c3koY2Rucy0+ZGV2KTsKPiArICAgICAgIHBtX3J1 bnRpbWVfcHV0X2F1dG9zdXNwZW5kKGNkbnMtPmRldik7Cj4gKwo+ICsgICAgICAgdXNiX2RlbF9n YWRnZXRfdWRjKCZwcml2X2Rldi0+Z2FkZ2V0KTsKPiArCj4gKyAgICAgICBjZG5zM19mcmVlX2Fs bF9lcHMocHJpdl9kZXYpOwo+ICsKPiArICAgICAgIGRtYV9mcmVlX2NvaGVyZW50KHByaXZfZGV2 LT5zeXNkZXYsIDgsIHByaXZfZGV2LT5zZXR1cF9idWYsCj4gKyAgICAgICAgICAgICAgICAgICAg ICAgICBwcml2X2Rldi0+c2V0dXBfZG1hKTsKPiArCj4gKyAgICAgICBrZnJlZShwcml2X2Rldi0+ emxwX2J1Zik7Cj4gKyAgICAgICBrZnJlZShwcml2X2Rldik7Cj4gKyAgICAgICBjZG5zLT5nYWRn ZXRfZGV2ID0gTlVMTDsKPiArfQo+ICsKPiArc3RhdGljIGludCBjZG5zM19nYWRnZXRfc3RhcnQo c3RydWN0IGNkbnMzICpjZG5zKQo+ICt7Cj4gKyAgICAgICBzdHJ1Y3QgY2RuczNfZGV2aWNlICpw cml2X2RldjsKPiArICAgICAgIHUzMiBtYXhfc3BlZWQ7Cj4gKyAgICAgICBpbnQgcmV0Owo+ICsK PiArICAgICAgIHByaXZfZGV2ID0ga3phbGxvYyhzaXplb2YoKnByaXZfZGV2KSwgR0ZQX0tFUk5F TCk7Cj4gKyAgICAgICBpZiAoIXByaXZfZGV2KQo+ICsgICAgICAgICAgICAgICByZXR1cm4gLUVO T01FTTsKPiArCj4gKyAgICAgICBjZG5zLT5nYWRnZXRfZGV2ID0gcHJpdl9kZXY7Cj4gKyAgICAg ICBwcml2X2Rldi0+c3lzZGV2ID0gY2Rucy0+ZGV2Owo+ICsgICAgICAgcHJpdl9kZXYtPmRldiA9 IGNkbnMtPmRldjsKPiArICAgICAgIHByaXZfZGV2LT5yZWdzID0gY2Rucy0+ZGV2X3JlZ3M7Cj4g Kwo+ICsgICAgICAgbWF4X3NwZWVkID0gdXNiX2dldF9tYXhpbXVtX3NwZWVkKGNkbnMtPmRldik7 Cj4gKwo+ICsgICAgICAgLyogQ2hlY2sgdGhlIG1heGltdW1fc3BlZWQgcGFyYW1ldGVyICovCj4g KyAgICAgICBzd2l0Y2ggKG1heF9zcGVlZCkgewo+ICsgICAgICAgY2FzZSBVU0JfU1BFRURfRlVM TDoKPiArICAgICAgIGNhc2UgVVNCX1NQRUVEX0hJR0g6Cj4gKyAgICAgICBjYXNlIFVTQl9TUEVF RF9TVVBFUjoKPiArICAgICAgICAgICAgICAgYnJlYWs7Cj4gKyAgICAgICBkZWZhdWx0Ogo+ICsg ICAgICAgICAgICAgICBkZXZfZXJyKGNkbnMtPmRldiwgImludmFsaWQgbWF4aW11bV9zcGVlZCBw YXJhbWV0ZXIgJWRcbiIsCj4gKyAgICAgICAgICAgICAgICAgICAgICAgbWF4X3NwZWVkKTsKPiAr ICAgICAgICAgICAgICAgLyogZmFsbCB0aHJvdWdoICovCj4gKyAgICAgICBjYXNlIFVTQl9TUEVF RF9VTktOT1dOOgo+ICsgICAgICAgICAgICAgICAvKiBkZWZhdWx0IHRvIHN1cGVyc3BlZWQgKi8K PiArICAgICAgICAgICAgICAgbWF4X3NwZWVkID0gVVNCX1NQRUVEX1NVUEVSOwo+ICsgICAgICAg ICAgICAgICBicmVhazsKPiArICAgICAgIH0KPiArCj4gKyAgICAgICAvKiBmaWxsIGdhZGdldCBm aWVsZHMgKi8KPiArICAgICAgIHByaXZfZGV2LT5nYWRnZXQubWF4X3NwZWVkID0gbWF4X3NwZWVk Owo+ICsgICAgICAgcHJpdl9kZXYtPmdhZGdldC5zcGVlZCA9IFVTQl9TUEVFRF9VTktOT1dOOwo+ ICsgICAgICAgcHJpdl9kZXYtPmdhZGdldC5vcHMgPSAmY2RuczNfZ2FkZ2V0X29wczsKPiArICAg ICAgIHByaXZfZGV2LT5nYWRnZXQubmFtZSA9ICJ1c2Itc3MtZ2FkZ2V0IjsKPiArICAgICAgIHBy aXZfZGV2LT5nYWRnZXQuc2dfc3VwcG9ydGVkID0gMTsKPiArCj4gKyAgICAgICBzcGluX2xvY2tf aW5pdCgmcHJpdl9kZXYtPmxvY2spOwo+ICsgICAgICAgSU5JVF9XT1JLKCZwcml2X2Rldi0+cGVu ZGluZ19zdGF0dXNfd3EsCj4gKyAgICAgICAgICAgICAgICAgY2RuczNfcGVuZGluZ19zZXR1cF9z dGF0dXNfaGFuZGxlcik7Cj4gKwo+ICsgICAgICAgLyogaW5pdGlhbGl6ZSBlbmRwb2ludCBjb250 YWluZXIgKi8KPiArICAgICAgIElOSVRfTElTVF9IRUFEKCZwcml2X2Rldi0+Z2FkZ2V0LmVwX2xp c3QpOwo+ICsKPiArICAgICAgIHJldCA9IGNkbnMzX2luaXRfZXBzKHByaXZfZGV2KTsKPiArICAg ICAgIGlmIChyZXQpIHsKPiArICAgICAgICAgICAgICAgZGV2X2Vycihwcml2X2Rldi0+ZGV2LCAi RmFpbGVkIHRvIGNyZWF0ZSBlbmRwb2ludHNcbiIpOwo+ICsgICAgICAgICAgICAgICBnb3RvIGVy cjE7Cj4gKyAgICAgICB9Cj4gKwo+ICsgICAgICAgLyogYWxsb2NhdGUgbWVtb3J5IGZvciBzZXR1 cCBwYWNrZXQgYnVmZmVyICovCj4gKyAgICAgICBwcml2X2Rldi0+c2V0dXBfYnVmID0gZG1hX2Fs bG9jX2NvaGVyZW50KHByaXZfZGV2LT5zeXNkZXYsIDgsCj4gKyAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICZwcml2X2Rldi0+c2V0dXBfZG1hLCBHRlBfRE1B KTsKPiArICAgICAgIGlmICghcHJpdl9kZXYtPnNldHVwX2J1Zikgewo+ICsgICAgICAgICAgICAg ICBkZXZfZXJyKHByaXZfZGV2LT5kZXYsICJGYWlsZWQgdG8gYWxsb2NhdGUgbWVtb3J5IGZvciBT RVRVUCBidWZmZXJcbiIpOwo+ICsgICAgICAgICAgICAgICByZXQgPSAtRU5PTUVNOwo+ICsgICAg ICAgICAgICAgICBnb3RvIGVycjI7Cj4gKyAgICAgICB9Cj4gKwo+ICsgICAgICAgcHJpdl9kZXYt PmRldl92ZXIgPSByZWFkbCgmcHJpdl9kZXYtPnJlZ3MtPnVzYl9jYXA2KTsKPiArICAgICAgIGRl dl9kYmcocHJpdl9kZXYtPmRldiwgIkRldmljZSBDb250cm9sbGVyIHZlcnNpb246ICUwOHhcbiIs Cj4gKyAgICAgICAgICAgICAgIHJlYWRsKCZwcml2X2Rldi0+cmVncy0+dXNiX2NhcDYpKTsKPiAr ICAgICAgIGRldl9kYmcocHJpdl9kZXYtPmRldiwgIlVTQiBDYXBhYmlsaXRpZXM6OiAlMDh4XG4i LAo+ICsgICAgICAgICAgICAgICByZWFkbCgmcHJpdl9kZXYtPnJlZ3MtPnVzYl9jYXAxKSk7Cj4g KyAgICAgICBkZXZfZGJnKHByaXZfZGV2LT5kZXYsICJPbi1DaGlwIG1lbW9yeSBjbmZpZ3VyYXRp b246ICUwOHhcbiIsCj4gKyAgICAgICAgICAgICAgIHJlYWRsKCZwcml2X2Rldi0+cmVncy0+dXNi X2NhcDIpKTsKPiArCj4gKyAgICAgICBwcml2X2Rldi0+emxwX2J1ZiA9IGt6YWxsb2MoQ0ROUzNf RVBfWkxQX0JVRl9TSVpFLCBHRlBfS0VSTkVMKTsKPiArICAgICAgIGlmICghcHJpdl9kZXYtPnps cF9idWYpIHsKPiArICAgICAgICAgICAgICAgcmV0ID0gLUVOT01FTTsKPiArICAgICAgICAgICAg ICAgZ290byBlcnIzOwo+ICsgICAgICAgfQo+ICsKPiArICAgICAgIC8qIGFkZCBVU0IgZ2FkZ2V0 IGRldmljZSAqLwo+ICsgICAgICAgcmV0ID0gdXNiX2FkZF9nYWRnZXRfdWRjKHByaXZfZGV2LT5k ZXYsICZwcml2X2Rldi0+Z2FkZ2V0KTsKPiArICAgICAgIGlmIChyZXQgPCAwKSB7Cj4gKyAgICAg ICAgICAgICAgIGRldl9lcnIocHJpdl9kZXYtPmRldiwKPiArICAgICAgICAgICAgICAgICAgICAg ICAiRmFpbGVkIHRvIHJlZ2lzdGVyIFVTQiBkZXZpY2UgY29udHJvbGxlclxuIik7Cj4gKyAgICAg ICAgICAgICAgIGdvdG8gZXJyNDsKPiArICAgICAgIH0KPiArCj4gKyAgICAgICByZXR1cm4gMDsK PiArZXJyNDoKPiArICAgICAgIGtmcmVlKHByaXZfZGV2LT56bHBfYnVmKTsKPiArZXJyMzoKPiAr ICAgICAgIGRtYV9mcmVlX2NvaGVyZW50KHByaXZfZGV2LT5zeXNkZXYsIDgsIHByaXZfZGV2LT5z ZXR1cF9idWYsCj4gKyAgICAgICAgICAgICAgICAgICAgICAgICBwcml2X2Rldi0+c2V0dXBfZG1h KTsKPiArZXJyMjoKPiArICAgICAgIGNkbnMzX2ZyZWVfYWxsX2Vwcyhwcml2X2Rldik7Cj4gK2Vy cjE6Cj4gKyAgICAgICBjZG5zLT5nYWRnZXRfZGV2ID0gTlVMTDsKPiArICAgICAgIHJldHVybiBy ZXQ7Cj4gK30KPiArCj4gK3N0YXRpYyBpbnQgX19jZG5zM19nYWRnZXRfaW5pdChzdHJ1Y3QgY2Ru czMgKmNkbnMpCj4gK3sKPiArICAgICAgIHN0cnVjdCBjZG5zM19kZXZpY2UgKnByaXZfZGV2Owo+ ICsgICAgICAgdW5zaWduZWQgbG9uZyBmbGFnczsKPiArICAgICAgIGludCByZXQgPSAwOwo+ICsK PiArICAgICAgIHJldCA9IGNkbnMzX2dhZGdldF9zdGFydChjZG5zKTsKPiArICAgICAgIGlmIChy ZXQpCj4gKyAgICAgICAgICAgICAgIHJldHVybiByZXQ7Cj4gKwo+ICsgICAgICAgcHJpdl9kZXYg PSBjZG5zLT5nYWRnZXRfZGV2Owo+ICsgICAgICAgcmV0ID0gZGV2bV9yZXF1ZXN0X3RocmVhZGVk X2lycShjZG5zLT5kZXYsIGNkbnMtPmlycSwKPiArICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgY2RuczNfZGV2aWNlX2lycV9oYW5kbGVyLAo+ICsgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICBjZG5zM19kZXZpY2VfdGhyZWFkX2lycV9oYW5kbGVyLAo+ ICsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJUlFGX1NIQVJFRCwgZGV2 X25hbWUoY2Rucy0+ZGV2KSwgY2Rucyk7Cj4gKyAgICAgICBpZiAocmV0KQo+ICsgICAgICAgICAg ICAgICBnb3RvIGVycjA7Cj4gKwo+ICsgICAgICAgcG1fcnVudGltZV9nZXRfc3luYyhjZG5zLT5k ZXYpOwo+ICsgICAgICAgc3Bpbl9sb2NrX2lycXNhdmUoJnByaXZfZGV2LT5sb2NrLCBmbGFncyk7 Cj4gKyAgICAgICBzcGluX3VubG9ja19pcnFyZXN0b3JlKCZwcml2X2Rldi0+bG9jaywgZmxhZ3Mp Owo+ICsgICAgICAgcmV0dXJuIDA7Cj4gK2VycjA6Cj4gKyAgICAgICBjZG5zM19nYWRnZXRfZXhp dChjZG5zKTsKPiArICAgICAgIHJldHVybiByZXQ7Cj4gK30KPiArCj4gK3N0YXRpYyBpbnQgY2Ru czNfZ2FkZ2V0X3N1c3BlbmQoc3RydWN0IGNkbnMzICpjZG5zLCBib29sIGRvX3dha2V1cCkKPiAr ewo+ICsgICAgICAgY2RuczNfZ2FkZ2V0X2Rpc2FibGUoY2Rucyk7Cj4gKyAgICAgICByZXR1cm4g MDsKPiArfQo+ICsKPiArc3RhdGljIGludCBjZG5zM19nYWRnZXRfcmVzdW1lKHN0cnVjdCBjZG5z MyAqY2RucywgYm9vbCBoaWJlcm5hdGVkKQo+ICt7Cj4gKyAgICAgICBzdHJ1Y3QgY2RuczNfZGV2 aWNlICpwcml2X2RldjsKPiArICAgICAgIHVuc2lnbmVkIGxvbmcgZmxhZ3M7Cj4gKwo+ICsgICAg ICAgcHJpdl9kZXYgPSBjZG5zLT5nYWRnZXRfZGV2Owo+ICsgICAgICAgc3Bpbl9sb2NrX2lycXNh dmUoJnByaXZfZGV2LT5sb2NrLCBmbGFncyk7Cj4gKwo+ICsgICAgICAgaWYgKCFwcml2X2Rldi0+ Z2FkZ2V0X2RyaXZlcikgewo+ICsgICAgICAgICAgICAgICBzcGluX3VubG9ja19pcnFyZXN0b3Jl KCZwcml2X2Rldi0+bG9jaywgZmxhZ3MpOwo+ICsgICAgICAgICAgICAgICByZXR1cm4gMDsKPiAr ICAgICAgIH0KPiArCj4gKyAgICAgICBjZG5zM19nYWRnZXRfY29uZmlnKHByaXZfZGV2KTsKPiAr ICAgICAgIHNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJnByaXZfZGV2LT5sb2NrLCBmbGFncyk7Cj4g KyAgICAgICByZXR1cm4gMDsKPiArfQo+ICsKPiArLyoqCj4gKyAqIGNkbnMzX2dhZGdldF9pbml0 IC0gaW5pdGlhbGl6ZSBkZXZpY2Ugc3RydWN0dXJlCj4gKyAqCj4gKyAqIGNkbnM6IGNkbnMzIGlu c3RhbmNlCj4gKyAqCj4gKyAqIFRoaXMgZnVuY3Rpb24gaW5pdGlhbGl6ZXMgdGhlIGdhZGdldC4K PiArICovCj4gK2ludCBjZG5zM19nYWRnZXRfaW5pdChzdHJ1Y3QgY2RuczMgKmNkbnMpCj4gK3sK PiArICAgICAgIHN0cnVjdCBjZG5zM19yb2xlX2RyaXZlciAqcmRydjsKPiArCj4gKyAgICAgICBy ZHJ2ID0gZGV2bV9remFsbG9jKGNkbnMtPmRldiwgc2l6ZW9mKCpyZHJ2KSwgR0ZQX0tFUk5FTCk7 Cj4gKyAgICAgICBpZiAoIXJkcnYpCj4gKyAgICAgICAgICAgICAgIHJldHVybiAtRU5PTUVNOwo+ ICsKPiArICAgICAgIHJkcnYtPnN0YXJ0ICAgICA9IF9fY2RuczNfZ2FkZ2V0X2luaXQ7Cj4gKyAg ICAgICByZHJ2LT5zdG9wICAgICAgPSBjZG5zM19nYWRnZXRfZXhpdDsKPiArICAgICAgIHJkcnYt PnN1c3BlbmQgICA9IGNkbnMzX2dhZGdldF9zdXNwZW5kOwo+ICsgICAgICAgcmRydi0+cmVzdW1l ICAgID0gY2RuczNfZ2FkZ2V0X3Jlc3VtZTsKPiArICAgICAgIHJkcnYtPnN0YXRlICAgICA9IENE TlMzX1JPTEVfU1RBVEVfSU5BQ1RJVkU7Cj4gKyAgICAgICByZHJ2LT5uYW1lICAgICAgPSAiZ2Fk Z2V0IjsKPiArICAgICAgIGNkbnMtPnJvbGVzW0NETlMzX1JPTEVfR0FER0VUXSA9IHJkcnY7Cj4g Kwo+ICsgICAgICAgcmV0dXJuIDA7Cj4gK30KPiBkaWZmIC0tZ2l0IGEvZHJpdmVycy91c2IvY2Ru czMvZ2FkZ2V0LmggYi9kcml2ZXJzL3VzYi9jZG5zMy9nYWRnZXQuaAo+IG5ldyBmaWxlIG1vZGUg MTAwNjQ0Cj4gaW5kZXggMDAwMDAwMDAwMDAwLi44MTdmOGFlN2E0ZGEKPiAtLS0gL2Rldi9udWxs Cj4gKysrIGIvZHJpdmVycy91c2IvY2RuczMvZ2FkZ2V0LmgKPiBAQCAtMCwwICsxLDEyMDcgQEAK PiArLyogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEdQTC0yLjAgKi8KPiArLyoKPiArICogVVNC U1MgZGV2aWNlIGNvbnRyb2xsZXIgZHJpdmVyIGhlYWRlciBmaWxlCj4gKyAqCj4gKyAqIENvcHly aWdodCAoQykgMjAxOCBDYWRlbmNlLgo+ICsgKiBDb3B5cmlnaHQgKEMpIDIwMTctMjAxOCBOWFAK PiArICoKPiArICogQXV0aG9yOiBQYXdlbCBMYXN6Y3phayA8cGF3ZWxsQGNhZGVuY2UuY29tPgo+ ICsgKiAgICAgICAgIFBhd2VsIEpleiA8cGplekBjYWRlbmNlLmNvbT4KPiArICogICAgICAgICBQ ZXRlciBDaGVuIDxwZXRlci5jaGVuQG54cC5jb20+Cj4gKyAqLwo+ICsjaWZuZGVmIF9fTElOVVhf Q0ROUzNfR0FER0VUCj4gKyNkZWZpbmUgX19MSU5VWF9DRE5TM19HQURHRVQKPiArI2luY2x1ZGUg PGxpbnV4L3VzYi9nYWRnZXQuaD4KPiArCj4gKy8qCj4gKyAqIFVTQlNTLURFViByZWdpc3RlciBp bnRlcmZhY2UuCj4gKyAqIFRoaXMgY29ycmVzcG9uZHMgdG8gdGhlIFVTQlNTIERldmljZSBDb250 cm9sbGVyIEludGVyZmFjZQo+ICsgKi8KPiArCj4gKy8qKgo+ICsgKiBzdHJ1Y3QgY2RuczNfdXNi X3JlZ3MgLSBkZXZpY2UgY29udHJvbGxlciByZWdpc3RlcnMuCj4gKyAqIEB1c2JfY29uZjogICAg ICBHbG9iYWwgQ29uZmlndXJhdGlvbiBSZWdpc3Rlci4KPiArICogQHVzYl9zdHM6ICAgICAgIEds b2JhbCBTdGF0dXMgUmVnaXN0ZXIuCj4gKyAqIEB1c2JfY21kOiAgICAgICBHbG9iYWwgQ29tbWFu ZCBSZWdpc3Rlci4KPiArICogQHVzYl9pcHRuOiAgICAgIElUUC9TT0YgbnVtYmVyIFJlZ2lzdGVy Lgo+ICsgKiBAdXNiX2xwbTogICAgICAgR2xvYmFsIENvbW1hbmQgUmVnaXN0ZXIuCj4gKyAqIEB1 c2JfaWVuOiAgICAgICBVU0IgSW50ZXJydXB0IEVuYWJsZSBSZWdpc3Rlci4KPiArICogQHVzYl9p c3RzOiAgICAgIFVTQiBJbnRlcnJ1cHQgU3RhdHVzIFJlZ2lzdGVyLgo+ICsgKiBAZXBfc2VsOiAg ICAgICAgRW5kcG9pbnQgU2VsZWN0IFJlZ2lzdGVyLgo+ICsgKiBAZXBfdHJhZGRyOiAgICAgRW5k cG9pbnQgVHJhbnNmZXIgUmluZyBBZGRyZXNzIFJlZ2lzdGVyLgo+ICsgKiBAZXBfY2ZnOiAgICAg ICAgRW5kcG9pbnQgQ29uZmlndXJhdGlvbiBSZWdpc3Rlci4KPiArICogQGVwX2NtZDogICAgICAg IEVuZHBvaW50IENvbW1hbmQgUmVnaXN0ZXIuCj4gKyAqIEBlcF9zdHM6ICAgICAgICBFbmRwb2lu dCBTdGF0dXMgUmVnaXN0ZXIuCj4gKyAqIEBlcF9zdHNfc2lkOiAgICBFbmRwb2ludCBTdGF0dXMg UmVnaXN0ZXIuCj4gKyAqIEBlcF9zdHNfZW46ICAgICBFbmRwb2ludCBTdGF0dXMgUmVnaXN0ZXIg RW5hYmxlLgo+ICsgKiBAZHJibDogICAgICAgICAgRG9vcmJlbGwgUmVnaXN0ZXIuCj4gKyAqIEBl cF9pZW46ICAgICAgICBFUCBJbnRlcnJ1cHQgRW5hYmxlIFJlZ2lzdGVyLgo+ICsgKiBAZXBfaXN0 czogICAgICAgRVAgSW50ZXJydXB0IFN0YXR1cyBSZWdpc3Rlci4KPiArICogQHVzYl9wd3I6ICAg ICAgIEdsb2JhbCBQb3dlciBDb25maWd1cmF0aW9uIFJlZ2lzdGVyLgo+ICsgKiBAdXNiX2NvbmYy OiAgICAgR2xvYmFsIENvbmZpZ3VyYXRpb24gUmVnaXN0ZXIgMi4KPiArICogQHVzYl9jYXAxOiAg ICAgIENhcGFiaWxpdHkgUmVnaXN0ZXIgMS4KPiArICogQHVzYl9jYXAyOiAgICAgIENhcGFiaWxp dHkgUmVnaXN0ZXIgMi4KPiArICogQHVzYl9jYXAzOiAgICAgIENhcGFiaWxpdHkgUmVnaXN0ZXIg My4KPiArICogQHVzYl9jYXA0OiAgICAgIENhcGFiaWxpdHkgUmVnaXN0ZXIgNC4KPiArICogQHVz Yl9jYXA1OiAgICAgIENhcGFiaWxpdHkgUmVnaXN0ZXIgNS4KPiArICogQHVzYl9jYXA2OiAgICAg IENhcGFiaWxpdHkgUmVnaXN0ZXIgNi4KPiArICogQHVzYl9jcGt0MTogICAgIEN1c3RvbSBQYWNr ZXQgUmVnaXN0ZXIgMS4KPiArICogQHVzYl9jcGt0MjogICAgIEN1c3RvbSBQYWNrZXQgUmVnaXN0 ZXIgMi4KPiArICogQHVzYl9jcGt0MzogICAgIEN1c3RvbSBQYWNrZXQgUmVnaXN0ZXIgMy4KPiAr ICogQHJlc2VydmVkMTogICAgIFJlc2VydmVkLgo+ICsgKiBAY2ZnX3JlZ3M6ICAgICAgQ29uZmln dXJhdGlvbiByZWdpc3RlcnMuCj4gKyAqIEByZXNlcnZlZDI6ICAgICBSZXNlcnZlZC4KPiArICog QGRtYV9heGlfY3RybDogIEFYSSBDb250cm9sIHJlZ2lzdGVyLgo+ICsgKiBAZG1hX2F4aV9pZDog ICAgQVhJIElEIHJlZ2lzdGVyLgo+ICsgKiBAZG1hX2F4aV9jYXA6ICAgQVhJIENhcGFiaWxpdHkg cmVnaXN0ZXIuCj4gKyAqIEBkbWFfYXhpX2N0cmwwOiBBWEkgQ29udHJvbCAwIHJlZ2lzdGVyLgo+ ICsgKiBAZG1hX2F4aV9jdHJsMTogQVhJIENvbnRyb2wgMSByZWdpc3Rlci4KPiArICovCj4gK3N0 cnVjdCBjZG5zM191c2JfcmVncyB7Cj4gKyAgICAgICBfX2xlMzIgdXNiX2NvbmY7Cj4gKyAgICAg ICBfX2xlMzIgdXNiX3N0czsKPiArICAgICAgIF9fbGUzMiB1c2JfY21kOwo+ICsgICAgICAgX19s ZTMyIHVzYl9pcHRuOwo+ICsgICAgICAgX19sZTMyIHVzYl9scG07Cj4gKyAgICAgICBfX2xlMzIg dXNiX2llbjsKPiArICAgICAgIF9fbGUzMiB1c2JfaXN0czsKPiArICAgICAgIF9fbGUzMiBlcF9z ZWw7Cj4gKyAgICAgICBfX2xlMzIgZXBfdHJhZGRyOwo+ICsgICAgICAgX19sZTMyIGVwX2NmZzsK PiArICAgICAgIF9fbGUzMiBlcF9jbWQ7Cj4gKyAgICAgICBfX2xlMzIgZXBfc3RzOwo+ICsgICAg ICAgX19sZTMyIGVwX3N0c19zaWQ7Cj4gKyAgICAgICBfX2xlMzIgZXBfc3RzX2VuOwo+ICsgICAg ICAgX19sZTMyIGRyYmw7Cj4gKyAgICAgICBfX2xlMzIgZXBfaWVuOwo+ICsgICAgICAgX19sZTMy IGVwX2lzdHM7Cj4gKyAgICAgICBfX2xlMzIgdXNiX3B3cjsKPiArICAgICAgIF9fbGUzMiB1c2Jf Y29uZjI7Cj4gKyAgICAgICBfX2xlMzIgdXNiX2NhcDE7Cj4gKyAgICAgICBfX2xlMzIgdXNiX2Nh cDI7Cj4gKyAgICAgICBfX2xlMzIgdXNiX2NhcDM7Cj4gKyAgICAgICBfX2xlMzIgdXNiX2NhcDQ7 Cj4gKyAgICAgICBfX2xlMzIgdXNiX2NhcDU7Cj4gKyAgICAgICBfX2xlMzIgdXNiX2NhcDY7Cj4g KyAgICAgICBfX2xlMzIgdXNiX2Nwa3QxOwo+ICsgICAgICAgX19sZTMyIHVzYl9jcGt0MjsKPiAr ICAgICAgIF9fbGUzMiB1c2JfY3BrdDM7Cj4gKyAgICAgICBfX2xlMzIgcmVzZXJ2ZWQxWzM2XTsK PiArICAgICAgIF9fbGUzMiBjZmdfcmVnMTsKPiArICAgICAgIF9fbGUzMiBkYmdfbGluazE7Cj4g KyAgICAgICBfX2xlMzIgZGJnX2xpbmsyOwo+ICsgICAgICAgX19sZTMyIGNmZ19yZWdzWzc0XTsK PiArICAgICAgIF9fbGUzMiByZXNlcnZlZDJbMzRdOwo+ICsgICAgICAgX19sZTMyIGRtYV9heGlf Y3RybDsKPiArICAgICAgIF9fbGUzMiBkbWFfYXhpX2lkOwo+ICsgICAgICAgX19sZTMyIGRtYV9h eGlfY2FwOwo+ICsgICAgICAgX19sZTMyIGRtYV9heGlfY3RybDA7Cj4gKyAgICAgICBfX2xlMzIg ZG1hX2F4aV9jdHJsMTsKPiArfTsKPiArCj4gKy8qIFVTQl9DT05GIC0gYml0bWFza3MgKi8KPiAr LyogUmVzZXQgVVNCIGRldmljZSBjb25maWd1cmF0aW9uLiAqLwo+ICsjZGVmaW5lIFVTQl9DT05G X0NGR1JTVCAgICAgICAgICAgICAgICBCSVQoMCkKPiArLyogU2V0IENvbmZpZ3VyYXRpb24uICov Cj4gKyNkZWZpbmUgVVNCX0NPTkZfQ0ZHU0VUICAgICAgICAgICAgICAgIEJJVCgxKQo+ICsvKiBE aXNjb25uZWN0IFVTQiBkZXZpY2UgaW4gU3VwZXJTcGVlZC4gKi8KPiArI2RlZmluZSBVU0JfQ09O Rl9VU0IzRElTICAgICAgIEJJVCgzKQo+ICsvKiBEaXNjb25uZWN0IFVTQiBkZXZpY2UgaW4gSFMv RlMgKi8KPiArI2RlZmluZSBVU0JfQ09ORl9VU0IyRElTICAgICAgIEJJVCg0KQo+ICsvKiBMaXR0 bGUgRW5kaWFuIGFjY2VzcyAtIGRlZmF1bHQgKi8KPiArI2RlZmluZSBVU0JfQ09ORl9MRU5ESUFO ICAgICAgIEJJVCg1KQo+ICsvKgo+ICsgKiBCaWcgRW5kaWFuIGFjY2Vzcy4gRHJpdmVyIGFzc3Vt ZSB0aGF0IGJ5dGUgb3JkZXIgZm9yCj4gKyAqIFNGUnMgYWNjZXNzIGFsd2F5cyBpcyBhcyBMaXR0 bGUgRW5kaWFuIHNvIHRoaXMgYml0Cj4gKyAqIGlzIG5vdCB1c2VkLgo+ICsgKi8KPiArI2RlZmlu ZSBVU0JfQ09ORl9CRU5ESUFOICAgICAgIEJJVCg2KQo+ICsvKiBEZXZpY2Ugc29mdHdhcmUgcmVz ZXQuICovCj4gKyNkZWZpbmUgVVNCX0NPTkZfU1dSU1QgICAgICAgICBCSVQoNykKPiArLyogU2lu Z3VsYXIgRE1BIHRyYW5zZmVyIG1vZGUuICovCj4gKyNkZWZpbmUgVVNCX0NPTkZfRFNJTkcgICAg ICAgICBCSVQoOCkKPiArLyogTXVsdGlwbGUgRE1BIHRyYW5zZmVycyBtb2RlLiAqLwo+ICsjZGVm aW5lIFVTQl9DT05GX0RNVUxUICAgICAgICAgQklUKDkpCj4gKy8qIERNQSBjbG9jayB0dXJuLW9m ZiBlbmFibGUuICovCj4gKyNkZWZpbmUgVVNCX0NPTkZfRE1BT0ZGRU4gICAgICBCSVQoMTApCj4g Ky8qIERNQSBjbG9jayB0dXJuLW9mZiBkaXNhYmxlLiAqLwo+ICsjZGVmaW5lIFVTQl9DT05GX0RN QU9GRkRTICAgICAgQklUKDExKQo+ICsvKiBDbGVhciBGb3JjZSBGdWxsIFNwZWVkLiAqLwo+ICsj ZGVmaW5lIFVTQl9DT05GX0NGT1JDRV9GUyAgICAgQklUKDEyKQo+ICsvKiBTZXQgRm9yY2UgRnVs bCBTcGVlZC4gKi8KPiArI2RlZmluZSBVU0JfQ09ORl9TRk9SQ0VfRlMgICAgIEJJVCgxMykKPiAr LyogRGV2aWNlIGVuYWJsZS4gKi8KPiArI2RlZmluZSBVU0JfQ09ORl9ERVZFTiAgICAgICAgIEJJ VCgxNCkKPiArLyogRGV2aWNlIGRpc2FibGUuICovCj4gKyNkZWZpbmUgVVNCX0NPTkZfREVWRFMg ICAgICAgICBCSVQoMTUpCj4gKy8qIEwxIExQTSBzdGF0ZSBlbnRyeSBlbmFibGUgKHVzZWQgaW4g SFMvRlMgbW9kZSkuICovCj4gKyNkZWZpbmUgVVNCX0NPTkZfTDFFTiAgICAgICAgICBCSVQoMTYp Cj4gKy8qIEwxIExQTSBzdGF0ZSBlbnRyeSBkaXNhYmxlICh1c2VkIGluIEhTL0ZTIG1vZGUpLiAq Lwo+ICsjZGVmaW5lIFVTQl9DT05GX0wxRFMgICAgICAgICAgQklUKDE3KQo+ICsvKiBVU0IgMi4w IGNsb2NrIGdhdGUgZGlzYWJsZS4gKi8KPiArI2RlZmluZSBVU0JfQ09ORl9DTEsyT0ZGRU4gICAg IEJJVCgxOCkKPiArLyogVVNCIDIuMCBjbG9jayBnYXRlIGVuYWJsZS4gKi8KPiArI2RlZmluZSBV U0JfQ09ORl9DTEsyT0ZGRFMgICAgIEJJVCgxOSkKPiArLyogTDAgTFBNIHN0YXRlIGVudHJ5IHJl cXVlc3QgKHVzZWQgaW4gSFMvRlMgbW9kZSkuICovCj4gKyNkZWZpbmUgVVNCX0NPTkZfTEdPX0ww ICAgICAgICAgICAgICAgIEJJVCgyMCkKPiArLyogVVNCIDMuMCBjbG9jayBnYXRlIGRpc2FibGUu ICovCj4gKyNkZWZpbmUgVVNCX0NPTkZfQ0xLM09GRkVOICAgICBCSVQoMjEpCj4gKy8qIFVTQiAz LjAgY2xvY2sgZ2F0ZSBlbmFibGUuICovCj4gKyNkZWZpbmUgVVNCX0NPTkZfQ0xLM09GRkRTICAg ICBCSVQoMjIpCj4gKy8qIEJpdCAyMyBpcyByZXNlcnZlZCovCj4gKy8qIFUxIHN0YXRlIGVudHJ5 IGVuYWJsZSAodXNlZCBpbiBTUyBtb2RlKS4gKi8KPiArI2RlZmluZSBVU0JfQ09ORl9VMUVOICAg ICAgICAgIEJJVCgyNCkKPiArLyogVTEgc3RhdGUgZW50cnkgZGlzYWJsZSAodXNlZCBpbiBTUyBt b2RlKS4gKi8KPiArI2RlZmluZSBVU0JfQ09ORl9VMURTICAgICAgICAgIEJJVCgyNSkKPiArLyog VTIgc3RhdGUgZW50cnkgZW5hYmxlICh1c2VkIGluIFNTIG1vZGUpLiAqLwo+ICsjZGVmaW5lIFVT Ql9DT05GX1UyRU4gICAgICAgICAgQklUKDI2KQo+ICsvKiBVMiBzdGF0ZSBlbnRyeSBkaXNhYmxl ICh1c2VkIGluIFNTIG1vZGUpLiAqLwo+ICsjZGVmaW5lIFVTQl9DT05GX1UyRFMgICAgICAgICAg QklUKDI3KQo+ICsvKiBVMCBzdGF0ZSBlbnRyeSByZXF1ZXN0ICh1c2VkIGluIFNTIG1vZGUpLiAq Lwo+ICsjZGVmaW5lIFVTQl9DT05GX0xHT19VMCAgICAgICAgICAgICAgICBCSVQoMjgpCj4gKy8q IFUxIHN0YXRlIGVudHJ5IHJlcXVlc3QgKHVzZWQgaW4gU1MgbW9kZSkuICovCj4gKyNkZWZpbmUg VVNCX0NPTkZfTEdPX1UxICAgICAgICAgICAgICAgIEJJVCgyOSkKPiArLyogVTIgc3RhdGUgZW50 cnkgcmVxdWVzdCAodXNlZCBpbiBTUyBtb2RlKS4gKi8KPiArI2RlZmluZSBVU0JfQ09ORl9MR09f VTIgICAgICAgICAgICAgICAgQklUKDMwKQo+ICsvKiBTUy5JbmFjdGl2ZSBzdGF0ZSBlbnRyeSBy ZXF1ZXN0ICh1c2VkIGluIFNTIG1vZGUpICovCj4gKyNkZWZpbmUgVVNCX0NPTkZfTEdPX1NTSU5B Q1QgICBCSVQoMzEpCj4gKwo+ICsvKiBVU0JfU1RTIC0gYml0bWFza3MgKi8KPiArLyoKPiArICog Q29uZmlndXJhdGlvbiBzdGF0dXMuCj4gKyAqIDEgLSBkZXZpY2UgaXMgaW4gdGhlIGNvbmZpZ3Vy ZWQgc3RhdGUuCj4gKyAqIDAgLSBkZXZpY2UgaXMgbm90IGNvbmZpZ3VyZWQuCj4gKyAqLwo+ICsj ZGVmaW5lIFVTQl9TVFNfQ0ZHU1RTX01BU0sgICAgQklUKDApCj4gKyNkZWZpbmUgVVNCX1NUU19D RkdTVFMocCkgICAgICAoKHApICYgVVNCX1NUU19DRkdTVFNfTUFTSykKPiArLyoKPiArICogT24t Y2hpcCBtZW1vcnkgb3ZlcmZsb3cuCj4gKyAqIDAgLSBPbi1jaGlwIG1lbW9yeSBzdGF0dXMgT0su Cj4gKyAqIDEgLSBPbi1jaGlwIG1lbW9yeSBvdmVyZmxvdy4KPiArICovCj4gKyNkZWZpbmUgVVNC X1NUU19PVl9NQVNLICAgICAgICAgICAgICAgIEJJVCgxKQo+ICsjZGVmaW5lIFVTQl9TVFNfT1Yo cCkgICAgICAgICAgKChwKSAmIFVTQl9TVFNfT1ZfTUFTSykKPiArLyoKPiArICogU3VwZXJTcGVl ZCBjb25uZWN0aW9uIHN0YXR1cy4KPiArICogMCAtIFVTQiBpbiBTdXBlclNwZWVkIG1vZGUgZGlz Y29ubmVjdGVkLgo+ICsgKiAxIC0gVVNCIGluIFN1cGVyU3BlZWQgbW9kZSBjb25uZWN0ZWQuCj4g KyAqLwo+ICsjZGVmaW5lIFVTQl9TVFNfVVNCM0NPTlNfTUFTSyAgQklUKDIpCj4gKyNkZWZpbmUg VVNCX1NUU19VU0IzQ09OUyhwKSAgICAoKHApICYgVVNCX1NUU19VU0IzQ09OU19NQVNLKQo+ICsv Kgo+ICsgKiBETUEgdHJhbnNmZXIgY29uZmlndXJhdGlvbiBzdGF0dXMuCj4gKyAqIDAgLSBzaW5n bGUgcmVxdWVzdC4KPiArICogMSAtIG11bHRpcGxlIFRSQiBjaGFpbgo+ICsgKi8KPiArI2RlZmlu ZSBVU0JfU1RTX0RUUkFOU19NQVNLICAgIEJJVCgzKQo+ICsjZGVmaW5lIFVTQl9TVFNfRFRSQU5T KHApICAgICAgKChwKSAmIFVTQl9TVFNfRFRSQU5TX01BU0spCj4gKy8qCj4gKyAqIERldmljZSBz cGVlZC4KPiArICogMCAtIFVuZGVmaW5lZCAodmFsdWUgYWZ0ZXIgcmVzZXQpLgo+ICsgKiAxIC0g TG93IHNwZWVkCj4gKyAqIDIgLSBGdWxsIHNwZWVkCj4gKyAqIDMgLSBIaWdoIHNwZWVkCj4gKyAq IDQgLSBTdXBlciBzcGVlZAo+ICsgKi8KPiArI2RlZmluZSBVU0JfU1RTX1VTQlNQRUVEX01BU0sg IEdFTk1BU0soNiwgNCkKPiArI2RlZmluZSBVU0JfU1RTX1VTQlNQRUVEKHApICAgICgoKHApICYg VVNCX1NUU19VU0JTUEVFRF9NQVNLKSA+PiA0KQo+ICsjZGVmaW5lIFVTQl9TVFNfTFMgICAgICAg ICAgICAgKDB4MSA8PCA0KQo+ICsjZGVmaW5lIFVTQl9TVFNfRlMgICAgICAgICAgICAgKDB4MiA8 PCA0KQo+ICsjZGVmaW5lIFVTQl9TVFNfSFMgICAgICAgICAgICAgKDB4MyA8PCA0KQo+ICsjZGVm aW5lIFVTQl9TVFNfU1MgICAgICAgICAgICAgKDB4NCA8PCA0KQo+ICsjZGVmaW5lIERFVl9VTkRF RlNQRUVEKHApICAgICAgKCgocCkgJiBVU0JfU1RTX1VTQlNQRUVEX01BU0spID09ICgweDAgPDwg NCkpCj4gKyNkZWZpbmUgREVWX0xPV1NQRUVEKHApICAgICAgICAgICAgICAgICgoKHApICYgVVNC X1NUU19VU0JTUEVFRF9NQVNLKSA9PSBVU0JfU1RTX0xTKQo+ICsjZGVmaW5lIERFVl9GVUxMU1BF RUQocCkgICAgICAgKCgocCkgJiBVU0JfU1RTX1VTQlNQRUVEX01BU0spID09IFVTQl9TVFNfRlMp Cj4gKyNkZWZpbmUgREVWX0hJR0hTUEVFRChwKSAgICAgICAoKChwKSAmIFVTQl9TVFNfVVNCU1BF RURfTUFTSykgPT0gVVNCX1NUU19IUykKPiArI2RlZmluZSBERVZfU1VQRVJTUEVFRChwKSAgICAg ICgoKHApICYgVVNCX1NUU19VU0JTUEVFRF9NQVNLKSA9PSBVU0JfU1RTX1NTKQo+ICsvKgo+ICsg KiBFbmRpYW5uZXNzIGZvciBTRlIgYWNjZXNzLgo+ICsgKiAwIC0gTGl0dGxlIEVuZGlhbiBvcmRl ciAoZGVmYXVsdCBhZnRlciBoYXJkd2FyZSByZXNldCkuCj4gKyAqIDEgLSBCaWcgRW5kaWFuIG9y ZGVyCj4gKyAqLwo+ICsjZGVmaW5lIFVTQl9TVFNfRU5ESUFOX01BU0sgICAgQklUKDcpCj4gKyNk ZWZpbmUgVVNCX1NUU19FTkRJQU4ocCkgICAgICAoKHApICYgVVNCX1NUU19FTkRJQU5fTUFTSykK PiArLyoKPiArICogSFMvRlMgY2xvY2sgdHVybi1vZmYgc3RhdHVzLgo+ICsgKiAwIC0gaHNmcyBj bG9jayBpcyBhbHdheXMgb24uCj4gKyAqIDEgLSBoc2ZzIGNsb2NrIHR1cm4tb2ZmIGluIEwyIChI Uy9GUyBtb2RlKSBpcyBlbmFibGVkCj4gKyAqICAgICAgICAgIChkZWZhdWx0IGFmdGVyIGhhcmR3 YXJlIHJlc2V0KS4KPiArICovCj4gKyNkZWZpbmUgVVNCX1NUU19DTEsyT0ZGX01BU0sgICBCSVQo OCkKPiArI2RlZmluZSBVU0JfU1RTX0NMSzJPRkYocCkgICAgICgocCkgJiBVU0JfU1RTX0NMSzJP RkZfTUFTSykKPiArLyoKPiArICogUENMSyBjbG9jayB0dXJuLW9mZiBzdGF0dXMuCj4gKyAqIDAg LSBwY2xrIGNsb2NrIGlzIGFsd2F5cyBvbi4KPiArICogMSAtIHBjbGsgY2xvY2sgdHVybi1vZmYg aW4gVTMgKFNTIG1vZGUpIGlzIGVuYWJsZWQKPiArICogICAgICAgICAgKGRlZmF1bHQgYWZ0ZXIg aGFyZHdhcmUgcmVzZXQpLgo+ICsgKi8KPiArI2RlZmluZSBVU0JfU1RTX0NMSzNPRkZfTUFTSyAg IEJJVCg5KQo+ICsjZGVmaW5lIFVTQl9TVFNfQ0xLM09GRihwKSAgICAgKChwKSAmIFVTQl9TVFNf Q0xLM09GRl9NQVNLKQo+ICsvKgo+ICsgKiBDb250cm9sbGVyIGluIHJlc2V0IHN0YXRlLgo+ICsg KiAwIC0gSW50ZXJuYWwgcmVzZXQgaXMgYWN0aXZlLgo+ICsgKiAxIC0gSW50ZXJuYWwgcmVzZXQg aXMgbm90IGFjdGl2ZSBhbmQgY29udHJvbGxlciBpcyBmdWxseSBvcGVyYXRpb25hbC4KPiArICov Cj4gKyNkZWZpbmUgVVNCX1NUU19JTl9SU1RfTUFTSyAgICBCSVQoMTApCj4gKyNkZWZpbmUgVVNC X1NUU19JTl9SU1QocCkgICAgICAoKHApICYgVVNCX1NUU19JTl9SU1RfTUFTSykKPiArLyoKPiAr ICogRGV2aWNlIGVuYWJsZSBTdGF0dXMuCj4gKyAqIDAgLSBVU0IgZGV2aWNlIGlzIGRpc2FibGVk IChWQlVTIGlucHV0IGlzIGRpc2Nvbm5lY3RlZCBmcm9tIGludGVybmFsIGxvZ2ljKS4KPiArICog MSAtIFVTQiBkZXZpY2UgaXMgZW5hYmxlZCAoVkJVUyBpbnB1dCBpcyBjb25uZWN0ZWQgdG8gdGhl IGludGVybmFsIGxvZ2ljKS4KPiArICovCj4gKyNkZWZpbmUgVVNCX1NUU19ERVZTX01BU0sgICAg ICBCSVQoMTQpCj4gKyNkZWZpbmUgVVNCX1NUU19ERVZTKHApICAgICAgICAgICAgICAgICgocCkg JiBVU0JfU1RTX0RFVlNfTUFTSykKPiArLyoKPiArICogREFkZHJlc3Mgc3RhdHVzcy4KPiArICog MCAtIFVTQiBkZXZpY2UgaXMgZGVmYXVsdCBzdGF0ZS4KPiArICogMSAtIFVTQiBkZXZpY2UgaXMg YXQgbGVhc3QgaW4gYWRkcmVzcyBzdGF0ZS4KPiArICovCj4gKyNkZWZpbmUgVVNCX1NUU19BRERS RVNTRURfTUFTSyBCSVQoMTUpCj4gKyNkZWZpbmUgVVNCX1NUU19BRERSRVNTRUQocCkgICAoKHAp ICYgVVNCX1NUU19BRERSRVNTRURfTUFTSykKPiArLyoKPiArICogTDEgTFBNIHN0YXRlIGVuYWJs ZSBzdGF0dXMgKHVzZWQgaW4gSFMvRlMgbW9kZSkuCj4gKyAqIDAgLSBFbnRlcmluZyB0byBMMSBM UE0gc3RhdGUgZGlzYWJsZWQuCj4gKyAqIDEgLSBFbnRlcmluZyB0byBMMSBMUE0gc3RhdGUgZW5h YmxlZC4KPiArICovCj4gKyNkZWZpbmUgVVNCX1NUU19MMUVOU19NQVNLICAgICBCSVQoMTYpCj4g KyNkZWZpbmUgVVNCX1NUU19MMUVOUyhwKSAgICAgICAoKHApICYgVVNCX1NUU19MMUVOU19NQVNL KQo+ICsvKgo+ICsgKiBJbnRlcm5hbCBWQlVTIGNvbm5lY3Rpb24gc3RhdHVzICh1c2VkIGJvdGgg aW4gSFMvRlMgIGFuZCBTUyBtb2RlKS4KPiArICogMCAtIGludGVybmFsIFZCVVMgaXMgbm90IGRl dGVjdGVkLgo+ICsgKiAxIC0gaW50ZXJuYWwgVkJVUyBpcyBkZXRlY3RlZC4KPiArICovCj4gKyNk ZWZpbmUgVVNCX1NUU19WQlVTU19NQVNLICAgICBCSVQoMTcpCj4gKyNkZWZpbmUgVVNCX1NUU19W QlVTUyhwKSAgICAgICAoKHApICYgVVNCX1NUU19WQlVTU19NQVNLKQo+ICsvKgo+ICsgKiBIUy9G UyBMUE0gIHN0YXRlICh1c2VkIGluIEZTL0hTIG1vZGUpLgo+ICsgKiAwIC0gTDAgU3RhdGUKPiAr ICogMSAtIEwxIFN0YXRlCj4gKyAqIDIgLSBMMiBTdGF0ZQo+ICsgKiAzIC0gTDMgU3RhdGUKPiAr ICovCj4gKyNkZWZpbmUgVVNCX1NUU19MUE1TVF9NQVNLICAgICBHRU5NQVNLKDE5LCAxOCkKPiAr I2RlZmluZSBERVZfTDBfU1RBVEUocCkgICAgICAgICAgICAgICAgKCgocCkgJiBVU0JfU1RTX0xQ TVNUX01BU0spID09ICgweDAgPDwgMTgpKQo+ICsjZGVmaW5lIERFVl9MMV9TVEFURShwKSAgICAg ICAgICAgICAgICAoKChwKSAmIFVTQl9TVFNfTFBNU1RfTUFTSykgPT0gKDB4MSA8PCAxOCkpCj4g KyNkZWZpbmUgREVWX0wyX1NUQVRFKHApICAgICAgICAgICAgICAgICgoKHApICYgVVNCX1NUU19M UE1TVF9NQVNLKSA9PSAoMHgyIDw8IDE4KSkKPiArI2RlZmluZSBERVZfTDNfU1RBVEUocCkgICAg ICAgICAgICAgICAgKCgocCkgJiBVU0JfU1RTX0xQTVNUX01BU0spID09ICgweDMgPDwgMTgpKQo+ ICsvKgo+ICsgKiBEaXNhYmxlIEhTIHN0YXR1cyAodXNlZCBpbiBGUy9IUyBtb2RlKS4KPiArICog MCAtIHRoZSBkaXNjb25uZWN0IGJpdCBmb3IgSFMvRlMgbW9kZSBpcyBzZXQgLgo+ICsgKiAxIC0g dGhlIGRpc2Nvbm5lY3QgYml0IGZvciBIUy9GUyBtb2RlIGlzIG5vdCBzZXQuCj4gKyAqLwo+ICsj ZGVmaW5lIFVTQl9TVFNfVVNCMkNPTlNfTUFTSyAgQklUKDIwKQo+ICsjZGVmaW5lIFVTQl9TVFNf VVNCMkNPTlMocCkgICAgKChwKSAmIFVTQl9TVFNfVVNCMkNPTlNfTUFTSykKPiArLyoKPiArICog SFMvRlMgbW9kZSBjb25uZWN0aW9uIHN0YXR1cyAodXNlZCBpbiBGUy9IUyBtb2RlKS4KPiArICog MCAtIEhpZ2ggU3BlZWQgb3BlcmF0aW9ucyBpbiBVU0IyLjAgKEZTL0hTKSBtb2RlIG5vdCBkaXNh YmxlZC4KPiArICogMSAtIEhpZ2ggU3BlZWQgb3BlcmF0aW9ucyBpbiBVU0IyLjAgKEZTL0hTKS4K PiArICovCj4gKyNkZWZpbmUgVVNCX1NUU19ESVNBQkxFX0hTX01BU0sgICAgICAgIEJJVCgyMSkK PiArI2RlZmluZSBVU0JfU1RTX0RJU0FCTEVfSFMocCkgICgocCkgJiBVU0JfU1RTX0RJU0FCTEVf SFNfTUFTSykKPiArLyoKPiArICogVTEgc3RhdGUgZW5hYmxlIHN0YXR1cyAodXNlZCBpbiBTUyBt b2RlKS4KPiArICogMCAtIEVudGVyaW5nIHRvICBVMSBzdGF0ZSBkaXNhYmxlZC4KPiArICogMSAt IEVudGVyaW5nIHRvICBVMSBzdGF0ZSBlbmFibGVkLgo+ICsgKi8KPiArI2RlZmluZSBVU0JfU1RT X1UxRU5TX01BU0sgICAgIEJJVCgyNCkKPiArI2RlZmluZSBVU0JfU1RTX1UxRU5TKHApICAgICAg ICgocCkgJiBVU0JfU1RTX1UxRU5TX01BU0spCj4gKy8qCj4gKyAqIFUyIHN0YXRlIGVuYWJsZSBz dGF0dXMgKHVzZWQgaW4gU1MgbW9kZSkuCj4gKyAqIDAgLSBFbnRlcmluZyB0byAgVTIgc3RhdGUg ZGlzYWJsZWQuCj4gKyAqIDEgLSBFbnRlcmluZyB0byAgVTIgc3RhdGUgZW5hYmxlZC4KPiArICov Cj4gKyNkZWZpbmUgVVNCX1NUU19VMkVOU19NQVNLICAgICBCSVQoMjUpCj4gKyNkZWZpbmUgVVNC X1NUU19VMkVOUyhwKSAgICAgICAoKHApICYgVVNCX1NUU19VMkVOU19NQVNLKQo+ICsvKgo+ICsg KiBTdXBlclNwZWVkIExpbmsgTFRTU00gc3RhdGUuIFRoaXMgZmllbGQgcmVmbGVjdHMgVVNCU1Mt REVWIGN1cnJlbnQKPiArICogU3VwZXJTcGVlZCBsaW5rIHN0YXRlCj4gKyAqLwo+ICsjZGVmaW5l IFVTQl9TVFNfTFNUX01BU0sgICAgICAgR0VOTUFTSygyOSwgMjYpCj4gKyNkZWZpbmUgREVWX0xT VF9VMCAgICAgICAgICAgICAoKChwKSAmIFVTQl9TVFNfTFNUX01BU0spID09ICgweDAgPDwgMjYp KQo+ICsjZGVmaW5lIERFVl9MU1RfVTEgICAgICAgICAgICAgKCgocCkgJiBVU0JfU1RTX0xTVF9N QVNLKSA9PSAoMHgxIDw8IDI2KSkKPiArI2RlZmluZSBERVZfTFNUX1UyICAgICAgICAgICAgICgo KHApICYgVVNCX1NUU19MU1RfTUFTSykgPT0gKDB4MiA8PCAyNikpCj4gKyNkZWZpbmUgREVWX0xT VF9VMyAgICAgICAgICAgICAoKChwKSAmIFVTQl9TVFNfTFNUX01BU0spID09ICgweDMgPDwgMjYp KQo+ICsjZGVmaW5lIERFVl9MU1RfRElTQUJMRUQgICAgICAgKCgocCkgJiBVU0JfU1RTX0xTVF9N QVNLKSA9PSAoMHg0IDw8IDI2KSkKPiArI2RlZmluZSBERVZfTFNUX1JYREVURUNUICAgICAgICgo KHApICYgVVNCX1NUU19MU1RfTUFTSykgPT0gKDB4NSA8PCAyNikpCj4gKyNkZWZpbmUgREVWX0xT VF9JTkFDVElWRSAgICAgICAoKChwKSAmIFVTQl9TVFNfTFNUX01BU0spID09ICgweDYgPDwgMjYp KQo+ICsjZGVmaW5lIERFVl9MU1RfUE9MTElORyAgICAgICAgICAgICAgICAoKChwKSAmIFVTQl9T VFNfTFNUX01BU0spID09ICgweDcgPDwgMjYpKQo+ICsjZGVmaW5lIERFVl9MU1RfUkVDT1ZFUlkg ICAgICAgKCgocCkgJiBVU0JfU1RTX0xTVF9NQVNLKSA9PSAoMHg4IDw8IDI2KSkKPiArI2RlZmlu ZSBERVZfTFNUX0hPVF9SRVNFVCAgICAgICgoKHApICYgVVNCX1NUU19MU1RfTUFTSykgPT0gKDB4 OSA8PCAyNikpCj4gKyNkZWZpbmUgREVWX0xTVF9DT01QX01PREUgICAgICAoKChwKSAmIFVTQl9T VFNfTFNUX01BU0spID09ICgweGEgPDwgMjYpKQo+ICsjZGVmaW5lIERFVl9MU1RfTEJfU1RBVEUg ICAgICAgKCgocCkgJiBVU0JfU1RTX0xTVF9NQVNLKSA9PSAoMHhiIDw8IDI2KSkKPiArLyoKPiAr ICogRE1BIGNsb2NrIHR1cm4tb2ZmIHN0YXR1cy4KPiArICogMCAtIERNQSBjbG9jayBpcyBhbHdh eXMgb24gKGRlZmF1bHQgYWZ0ZXIgaGFyZHdhcmUgcmVzZXQpLgo+ICsgKiAxIC0gRE1BIGNsb2Nr IHR1cm4tb2ZmIGluIFUxLCBVMiBhbmQgVTMgKFNTIG1vZGUpIGlzIGVuYWJsZWQuCj4gKyAqLwo+ ICsjZGVmaW5lIFVTQl9TVFNfRE1BT0ZGX01BU0sgICAgQklUKDMwKQo+ICsjZGVmaW5lIFVTQl9T VFNfRE1BT0ZGKHApICAgICAgKChwKSAmIFVTQl9TVFNfRE1BT0ZGX01BU0spCj4gKy8qCj4gKyAq IFNGUiBFbmRpYW4gc3RhdHVzcy4KPiArICogMCAtIExpdHRsZSBFbmRpYW4gb3JkZXIgKGRlZmF1 bHQgYWZ0ZXIgaGFyZHdhcmUgcmVzZXQpLgo+ICsgKiAxIC0gQmlnIEVuZGlhbiBvcmRlci4KPiAr ICovCj4gKyNkZWZpbmUgVVNCX1NUU19FTkRJQU4yX01BU0sgICBCSVQoMzEpCj4gKyNkZWZpbmUg VVNCX1NUU19FTkRJQU4yKHApICAgICAoKHApICYgVVNCX1NUU19FTkRJQU4yX01BU0spCj4gKwo+ ICsvKiBVU0JfQ01EIC0gIGJpdG1hc2tzICovCj4gKy8qIFNldCBGdW5jdGlvbiBBZGRyZXNzICov Cj4gKyNkZWZpbmUgVVNCX0NNRF9TRVRfQUREUiAgICAgICBCSVQoMCkKPiArLyoKPiArICogRnVu Y3Rpb24gQWRkcmVzcyBUaGlzIGZpZWxkIGlzIHNhdmVkIHRvIHRoZSBkZXZpY2Ugb25seSB3aGVu IHRoZSBmaWVsZAo+ICsgKiBTRVRfQUREUiBpcyBzZXQgJzEgJyBkdXJpbmcgd3JpdGUgdG8gVVNC X0NNRCByZWdpc3Rlci4KPiArICogU29mdHdhcmUgaXMgcmVzcG9uc2libGUgZm9yIGVudGVyaW5n IHRoZSBhZGRyZXNzIG9mIHRoZSBkZXZpY2UgZHVyaW5nCj4gKyAqIFNFVF9BRERSRVNTIHJlcXVl c3Qgc2VydmljZS4gVGhpcyBmaWVsZCBzaG91bGQgYmUgc2V0IGltbWVkaWF0ZWx5IGFmdGVyCj4g KyAqIHRoZSBTRVRVUCBwYWNrZXQgaXMgZGVjb2RlZCwgYW5kIHByaW9yIHRvIGNvbmZpcm1hdGlv biBvZiB0aGUgc3RhdHVzIHBoYXNlCj4gKyAqLwo+ICsjZGVmaW5lIFVTQl9DTURfRkFERFJfTUFT SyAgICAgR0VOTUFTSyg3LCAxKQo+ICsjZGVmaW5lIFVTQl9DTURfRkFERFIocCkgICAgICAgKCgo cCkgPDwgMSkgJiBVU0JfQ01EX0ZBRERSX01BU0spCj4gKy8qIFNlbmQgRnVuY3Rpb24gV2FrZSBE ZXZpY2UgTm90aWZpY2F0aW9uIFRQICh1c2VkIG9ubHkgaW4gU1MgbW9kZSkuICovCj4gKyNkZWZp bmUgVVNCX0NNRF9TRE5GVyAgICAgICAgICBCSVQoOCkKPiArLyogU2V0IFRlc3QgTW9kZSAodXNl ZCBvbmx5IGluIEhTL0ZTIG1vZGUpLiAqLwo+ICsjZGVmaW5lIFVTQl9DTURfU1RNT0RFICAgICAg ICAgQklUKDkpCj4gKy8qIFRlc3QgbW9kZSBzZWxlY3RvciAodXNlZCBvbmx5IGluIEhTL0ZTIG1v ZGUpICovCj4gKyNkZWZpbmUgVVNCX1NUU19UTU9ERV9TRUxfTUFTSyBHRU5NQVNLKDExLCAxMCkK PiArI2RlZmluZSBVU0JfU1RTX1RNT0RFX1NFTChwKSAgICgoKHApIDw8IDEwKSAmIFVTQl9TVFNf VE1PREVfU0VMX01BU0spCj4gKy8qCj4gKyAqICBTZW5kIExhdGVuY3kgVG9sZXJhbmNlIE1lc3Nh Z2UgRGV2aWNlIE5vdGlmaWNhdGlvbiBUUCAodXNlZCBvbmx5Cj4gKyAqICBpbiBTUyBtb2RlKS4K PiArICovCj4gKyNkZWZpbmUgVVNCX0NNRF9TRE5MVE0gICAgICAgICBCSVQoMTIpCj4gKy8qIFNl bmQgQ3VzdG9tIFRyYW5zYWN0aW9uIFBhY2tldCAodXNlZCBvbmx5IGluIFNTIG1vZGUpICovCj4g KyNkZWZpbmUgVVNCX0NNRF9TUEtUICAgICAgICAgICBCSVQoMTMpCj4gKy8qRGV2aWNlIE5vdGlm aWNhdGlvbiAnRnVuY3Rpb24gV2FrZScgLSBJbnRlcmZhY2UgdmFsdWUgKG9ubHkgaW4gU1MgbW9k ZS4gKi8KPiArI2RlZmluZSBVU0JfQ01EX0RORldfSU5UX01BU0sgIEdFTk1BU0soMjMsIDE2KQo+ ICsjZGVmaW5lIFVTQl9TVFNfRE5GV19JTlQocCkgICAgKCgocCkgPDwgMTYpICYgVVNCX0NNRF9E TkZXX0lOVF9NQVNLKQo+ICsvKgo+ICsgKiBEZXZpY2UgTm90aWZpY2F0aW9uICdMYXRlbmN5IFRv bGVyYW5jZSBNZXNzYWdlJyAtMzczIEJFTFQgdmFsdWUgWzc6MF0KPiArICogKHVzZWQgb25seSBp biBTUyBtb2RlKS4KPiArICovCj4gKyNkZWZpbmUgVVNCX0NNRF9ETkxUTV9CRUxUX01BU0sgICAg ICAgIEdFTk1BU0soMjcsIDE2KQo+ICsjZGVmaW5lIFVTQl9TVFNfRE5MVE1fQkVMVChwKSAgKCgo cCkgPDwgMTYpICYgVVNCX0NNRF9ETkxUTV9CRUxUX01BU0spCj4gKwo+ICsvKiBVU0JfSVRQTiAt IGJpdG1hc2tzICovCj4gKy8qCj4gKyAqIElUUChTUykgLyBTT0YgKEhTL0ZTKSBudW1iZXIKPiAr ICogSW4gU1MgbW9kZSB0aGlzIGZpZWxkIHJlcHJlc2VudCBudW1iZXIgb2YgbGFzdCBJVFAgcmVj ZWl2ZWQgZnJvbSBob3N0Lgo+ICsgKiBJbiBIUy9GUyBtb2RlIHRoaXMgZmllbGQgcmVwcmVzZW50 IG51bWJlciBvZiBsYXN0IFNPRiByZWNlaXZlZCBmcm9tIGhvc3QuCj4gKyAqLwo+ICsjZGVmaW5l IFVTQl9JVFBOX01BU0sgICAgICAgICAgR0VOTUFTSygxMywgMCkKPiArI2RlZmluZSBVU0JfSVRQ TihwKSAgICAgICAgICAgICgocCkgJiBVU0JfSVRQTl9NQVNLKQo+ICsKPiArLyogVVNCX0xQTSAt IGJpdG1hc2tzICovCj4gKy8qIEhvc3QgSW5pdGlhdGVkIFJlc3VtZSBEdXJhdGlvbi4gKi8KPiAr I2RlZmluZSBVU0JfTFBNX0hJUkRfTUFTSyAgICAgIEdFTk1BU0soMywgMCkKPiArI2RlZmluZSBV U0JfTFBNX0hJUkQocCkgICAgICAgICAgICAgICAgKChwKSAmIFVTQl9MUE1fSElSRF9NQVNLKQo+ ICsvKiBSZW1vdGUgV2FrZXVwIEVuYWJsZSAoYlJlbW90ZVdha2UpLiAqLwo+ICsjZGVmaW5lIFVT Ql9MUE1fQlJXICAgICAgICAgICAgQklUKDQpCj4gKwo+ICsvKiBVU0JfSUVOIC0gYml0bWFza3Mg Ki8KPiArLyogU1MgY29ubmVjdGlvbiBpbnRlcnJ1cHQgZW5hYmxlICovCj4gKyNkZWZpbmUgVVNC X0lFTl9DT05JRU4gICAgICAgICBCSVQoMCkKPiArLyogU1MgZGlzY29ubmVjdGlvbiBpbnRlcnJ1 cHQgZW5hYmxlLiAqLwo+ICsjZGVmaW5lIFVTQl9JRU5fRElTSUVOICAgICAgICAgQklUKDEpCj4g Ky8qIFVTQiBTUyB3YXJtIHJlc2V0IGludGVycnVwdCBlbmFibGUuICovCj4gKyNkZWZpbmUgVVNC X0lFTl9VV1JFU0lFTiAgICAgICBCSVQoMikKPiArLyogVVNCIFNTIGhvdCByZXNldCBpbnRlcnJ1 cHQgZW5hYmxlICovCj4gKyNkZWZpbmUgVVNCX0lFTl9VSFJFU0lFTiAgICAgICBCSVQoMykKPiAr LyogU1MgbGluayBVMyBzdGF0ZSBlbnRlciBpbnRlcnJ1cHQgZW5hYmxlIChzdXNwZW5kKS4qLwo+ ICsjZGVmaW5lIFVTQl9JRU5fVTNFTlRJRU4gICAgICAgQklUKDQpCj4gKy8qIFNTIGxpbmsgVTMg c3RhdGUgZXhpdCBpbnRlcnJ1cHQgZW5hYmxlICh3YWtldXApLiAqLwo+ICsjZGVmaW5lIFVTQl9J RU5fVTNFWFRJRU4gICAgICAgQklUKDUpCj4gKy8qIFNTIGxpbmsgVTIgc3RhdGUgZW50ZXIgaW50 ZXJydXB0IGVuYWJsZS4qLwo+ICsjZGVmaW5lIFVTQl9JRU5fVTJFTlRJRU4gICAgICAgQklUKDYp Cj4gKy8qIFNTIGxpbmsgVTIgc3RhdGUgZXhpdCBpbnRlcnJ1cHQgZW5hYmxlLiovCj4gKyNkZWZp bmUgVVNCX0lFTl9VMkVYVElFTiAgICAgICBCSVQoNykKPiArLyogU1MgbGluayBVMSBzdGF0ZSBl bnRlciBpbnRlcnJ1cHQgZW5hYmxlLiovCj4gKyNkZWZpbmUgVVNCX0lFTl9VMUVOVElFTiAgICAg ICBCSVQoOCkKPiArLyogU1MgbGluayBVMSBzdGF0ZSBleGl0IGludGVycnVwdCBlbmFibGUuKi8K PiArI2RlZmluZSBVU0JfSUVOX1UxRVhUSUVOICAgICAgIEJJVCg5KQo+ICsvKiBJVFAvU09GIHBh Y2tldCBkZXRlY3RlZCBpbnRlcnJ1cHQgZW5hYmxlLiovCj4gKyNkZWZpbmUgVVNCX0lFTl9JVFBJ RU4gICAgICAgICBCSVQoMTApCj4gKy8qIFdha2V1cCBpbnRlcnJ1cHQgZW5hYmxlLiovCj4gKyNk ZWZpbmUgVVNCX0lFTl9XQUtFSUVOICAgICAgICAgICAgICAgIEJJVCgxMSkKPiArLyogU2VuZCBD dXN0b20gUGFja2V0IGludGVycnVwdCBlbmFibGUuKi8KPiArI2RlZmluZSBVU0JfSUVOX1NQS1RJ RU4gICAgICAgICAgICAgICAgQklUKDEyKQo+ICsvKiBIUy9GUyBtb2RlIGNvbm5lY3Rpb24gaW50 ZXJydXB0IGVuYWJsZS4qLwo+ICsjZGVmaW5lIFVTQl9JRU5fQ09OMklFTiAgICAgICAgICAgICAg ICBCSVQoMTYpCj4gKy8qIEhTL0ZTIG1vZGUgZGlzY29ubmVjdGlvbiBpbnRlcnJ1cHQgZW5hYmxl LiovCj4gKyNkZWZpbmUgVVNCX0lFTl9ESVMySUVOICAgICAgICAgICAgICAgIEJJVCgxNykKPiAr LyogVVNCIHJlc2V0IChIUy9GUyBtb2RlKSBpbnRlcnJ1cHQgZW5hYmxlLiovCj4gKyNkZWZpbmUg VVNCX0lFTl9VMlJFU0lFTiAgICAgICBCSVQoMTgpCj4gKy8qIExQTSBMMiBzdGF0ZSBlbnRlciBp bnRlcnJ1cHQgZW5hYmxlLiovCj4gKyNkZWZpbmUgVVNCX0lFTl9MMkVOVElFTiAgICAgICBCSVQo MjApCj4gKy8qIExQTSAgTDIgc3RhdGUgZXhpdCBpbnRlcnJ1cHQgZW5hYmxlLiovCj4gKyNkZWZp bmUgVVNCX0lFTl9MMkVYVElFTiAgICAgICBCSVQoMjEpCj4gKy8qIExQTSBMMSBzdGF0ZSBlbnRl ciBpbnRlcnJ1cHQgZW5hYmxlLiovCj4gKyNkZWZpbmUgVVNCX0lFTl9MMUVOVElFTiAgICAgICBC SVQoMjQpCj4gKy8qIExQTSAgTDEgc3RhdGUgZXhpdCBpbnRlcnJ1cHQgZW5hYmxlLiovCj4gKyNk ZWZpbmUgVVNCX0lFTl9MMUVYVElFTiAgICAgICBCSVQoMjUpCj4gKy8qIENvbmZpZ3VyYXRpb24g cmVzZXQgaW50ZXJydXB0IGVuYWJsZS4qLwo+ICsjZGVmaW5lIFVTQl9JRU5fQ0ZHUkVTSUVOICAg ICAgQklUKDI2KQo+ICsvKiBTdGFydCBvZiB0aGUgVVNCIFNTIHdhcm0gcmVzZXQgaW50ZXJydXB0 IGVuYWJsZS4qLwo+ICsjZGVmaW5lIFVTQl9JRU5fVVdSRVNTSUVOICAgICAgQklUKDI4KQo+ICsv KiBFbmQgb2YgdGhlIFVTQiBTUyB3YXJtIHJlc2V0IGludGVycnVwdCBlbmFibGUuKi8KPiArI2Rl ZmluZSBVU0JfSUVOX1VXUkVTRUlFTiAgICAgIEJJVCgyOSkKPiArCj4gKyNkZWZpbmUgVVNCX0lF Tl9JTklUICAoVVNCX0lFTl9VMlJFU0lFTiB8IFVTQl9JU1RTX0RJUzJJIHwgVVNCX0lFTl9DT04y SUVOIFwKPiArICAgICAgICAgICAgICAgICAgICAgIHwgVVNCX0lFTl9VSFJFU0lFTiB8IFVTQl9J RU5fVVdSRVNJRU4gfCBVU0JfSUVOX0RJU0lFTiBcCj4gKyAgICAgICAgICAgICAgICAgICAgICB8 IFVTQl9JRU5fQ09OSUVOIHwgVVNCX0lFTl9VM0VYVElFTiB8IFVTQl9JRU5fTDJFTlRJRU4gXAo+ ICsgICAgICAgICAgICAgICAgICAgICAgfCBVU0JfSUVOX0wyRVhUSUVOKQo+ICsKPiArLyogVVNC X0lTVFMgLSBiaXRtYXNrcyAqLwo+ICsvKiBTUyBDb25uZWN0aW9uIGRldGVjdGVkLiAqLwo+ICsj ZGVmaW5lIFVTQl9JU1RTX0NPTkkgICAgICAgICAgQklUKDApCj4gKy8qIFNTIERpc2Nvbm5lY3Rp b24gZGV0ZWN0ZWQuICovCj4gKyNkZWZpbmUgVVNCX0lTVFNfRElTSSAgICAgICAgICBCSVQoMSkK PiArLyogVVVTQiB3YXJtIHJlc2V0IGRldGVjdGVkZS4gKi8KPiArI2RlZmluZSBVU0JfSVNUU19V V1JFU0kgICAgICAgICAgICAgICAgQklUKDIpCj4gKy8qIFVTQiBob3QgcmVzZXQgZGV0ZWN0ZWQu ICovCj4gKyNkZWZpbmUgVVNCX0lTVFNfVUhSRVNJICAgICAgICAgICAgICAgIEJJVCgzKQo+ICsv KiBVMyBsaW5rIHN0YXRlIGVudGVyIGRldGVjdGVkIChzdXNwZW5kKS4qLwo+ICsjZGVmaW5lIFVT Ql9JU1RTX1UzRU5USSAgICAgICAgICAgICAgICBCSVQoNCkKPiArLyogVTMgbGluayBzdGF0ZSBl eGl0IGRldGVjdGVkICh3YWtldXApLiAqLwo+ICsjZGVmaW5lIFVTQl9JU1RTX1UzRVhUSSAgICAg ICAgICAgICAgICBCSVQoNSkKPiArLyogVTIgbGluayBzdGF0ZSBlbnRlciBkZXRlY3RlZC4qLwo+ ICsjZGVmaW5lIFVTQl9JU1RTX1UyRU5USSAgICAgICAgICAgICAgICBCSVQoNikKPiArLyogVTIg bGluayBzdGF0ZSBleGl0IGRldGVjdGVkLiovCj4gKyNkZWZpbmUgVVNCX0lTVFNfVTJFWFRJICAg ICAgICAgICAgICAgIEJJVCg3KQo+ICsvKiBVMSBsaW5rIHN0YXRlIGVudGVyIGRldGVjdGVkLiov Cj4gKyNkZWZpbmUgVVNCX0lTVFNfVTFFTlRJICAgICAgICAgICAgICAgIEJJVCg4KQo+ICsvKiBV MSBsaW5rIHN0YXRlIGV4aXQgZGV0ZWN0ZWQuKi8KPiArI2RlZmluZSBVU0JfSVNUU19VMUVYVEkg ICAgICAgICAgICAgICAgQklUKDkpCj4gKy8qIElUUC9TT0YgcGFja2V0IGRldGVjdGVkLiovCj4g KyNkZWZpbmUgVVNCX0lTVFNfSVRQSSAgICAgICAgICBCSVQoMTApCj4gKy8qIFdha2V1cCBkZXRl Y3RlZC4qLwo+ICsjZGVmaW5lIFVTQl9JU1RTX1dBS0VJICAgICAgICAgQklUKDExKQo+ICsvKiBT ZW5kIEN1c3RvbSBQYWNrZXQgZGV0ZWN0ZWQuKi8KPiArI2RlZmluZSBVU0JfSVNUU19TUEtUSSAg ICAgICAgIEJJVCgxMikKPiArLyogSFMvRlMgbW9kZSBjb25uZWN0aW9uIGRldGVjdGVkLiovCj4g KyNkZWZpbmUgVVNCX0lTVFNfQ09OMkkgICAgICAgICBCSVQoMTYpCj4gKy8qIEhTL0ZTIG1vZGUg ZGlzY29ubmVjdGlvbiBkZXRlY3RlZC4qLwo+ICsjZGVmaW5lIFVTQl9JU1RTX0RJUzJJICAgICAg ICAgQklUKDE3KQo+ICsvKiBVU0IgcmVzZXQgKEhTL0ZTIG1vZGUpIGRldGVjdGVkLiovCj4gKyNk ZWZpbmUgVVNCX0lTVFNfVTJSRVNJICAgICAgICAgICAgICAgIEJJVCgxOCkKPiArLyogTFBNIEwy IHN0YXRlIGVudGVyIGRldGVjdGVkLiovCj4gKyNkZWZpbmUgVVNCX0lTVFNfTDJFTlRJICAgICAg ICAgICAgICAgIEJJVCgyMCkKPiArLyogTFBNICBMMiBzdGF0ZSBleGl0IGRldGVjdGVkLiovCj4g KyNkZWZpbmUgVVNCX0lTVFNfTDJFWFRJICAgICAgICAgICAgICAgIEJJVCgyMSkKPiArLyogTFBN IEwxIHN0YXRlIGVudGVyIGRldGVjdGVkLiovCj4gKyNkZWZpbmUgVVNCX0lTVFNfTDFFTlRJICAg ICAgICAgICAgICAgIEJJVCgyNCkKPiArLyogTFBNIEwxIHN0YXRlIGV4aXQgZGV0ZWN0ZWQuKi8K PiArI2RlZmluZSBVU0JfSVNUU19MMUVYVEkgICAgICAgICAgICAgICAgQklUKDI1KQo+ICsvKiBV U0IgY29uZmlndXJhdGlvbiByZXNldCBkZXRlY3RlZC4qLwo+ICsjZGVmaW5lIFVTQl9JU1RTX0NG R1JFU0kgICAgICAgQklUKDI2KQo+ICsvKiBTdGFydCBvZiB0aGUgVVNCIHdhcm0gcmVzZXQgZGV0 ZWN0ZWQuKi8KPiArI2RlZmluZSBVU0JfSVNUU19VV1JFU1NJICAgICAgIEJJVCgyOCkKPiArLyog RW5kIG9mIHRoZSBVU0Igd2FybSByZXNldCBkZXRlY3RlZC4qLwo+ICsjZGVmaW5lIFVTQl9JU1RT X1VXUkVTRUkgICAgICAgQklUKDI5KQo+ICsKPiArLyogVVNCX1NFTCAtIGJpdG1hc2tzICovCj4g KyNkZWZpbmUgRVBfU0VMX0VQTk9fTUFTSyAgICAgICBHRU5NQVNLKDMsIDApCj4gKy8qIEVuZHBv aW50IG51bWJlci4gKi8KPiArI2RlZmluZSBFUF9TRUxfRVBOTyhwKSAgICAgICAgICgocCkgJiBF UF9TRUxfRVBOT19NQVNLKQo+ICsvKiBFbmRwb2ludCBkaXJlY3Rpb24gYml0IC0gMCAtIE9VVCwg MSAtIElOLiAqLwo+ICsjZGVmaW5lIEVQX1NFTF9ESVIgICAgICAgICAgICAgQklUKDcpCj4gKwo+ ICsjZGVmaW5lIHNlbGVjdF9lcF9pbihucikgICAgICAgKEVQX1NFTF9FUE5PKHApIHwgRVBfU0VM X0RJUikKPiArI2RlZmluZSBzZWxlY3RfZXBfb3V0ICAgICAgICAgIChFUF9TRUxfRVBOTyhwKSkK PiArCj4gKy8qIEVQX1RSQUREUiAtIGJpdG1hc2tzICovCj4gKy8qIFRyYW5zZmVyIFJpbmcgYWRk cmVzcy4gKi8KPiArI2RlZmluZSBFUF9UUkFERFJfVFJBRERSKHApICAgICgocCkpCj4gKwo+ICsv KiBFUF9DRkcgLSBiaXRtYXNrcyAqLwo+ICsvKiBFbmRwb2ludCBlbmFibGUgKi8KPiArI2RlZmlu ZSBFUF9DRkdfRU5BQkxFICAgICAgICAgIEJJVCgwKQo+ICsvKgo+ICsgKiAgRW5kcG9pbnQgdHlw ZS4KPiArICogMSAtIGlzb2Nocm9ub3VzCj4gKyAqIDIgLSBidWxrCj4gKyAqIDMgLSBpbnRlcnJ1 cHQKPiArICovCj4gKyNkZWZpbmUgRVBfQ0ZHX0VQVFlQRV9NQVNLICAgICBHRU5NQVNLKDIsIDEp Cj4gKyNkZWZpbmUgRVBfQ0ZHX0VQVFlQRShwKSAgICAgICAoKChwKSA8PCAxKSAgJiBFUF9DRkdf RVBUWVBFX01BU0spCj4gKy8qIFN0cmVhbSBzdXBwb3J0IGVuYWJsZSAob25seSBpbiBTUyBtb2Rl KS4gKi8KPiArI2RlZmluZSBFUF9DRkdfU1RSRUFNX0VOICAgICAgIEJJVCgzKQo+ICsvKiBUREwg Y2hlY2sgKG9ubHkgaW4gU1MgbW9kZSBmb3IgQlVMSyBFUCkuICovCj4gKyNkZWZpbmUgRVBfQ0ZH X1RETF9DSEsgICAgICAgICBCSVQoNCkKPiArLyogU0lEIGNoZWNrIChvbmx5IGluIFNTIG1vZGUg Zm9yIEJVTEsgT1VUIEVQKS4gKi8KPiArI2RlZmluZSBFUF9DRkdfU0lEX0NISyAgICAgICAgIEJJ VCg1KQo+ICsvKiBETUEgdHJhbnNmZXIgZW5kaWFubmVzcy4gKi8KPiArI2RlZmluZSBFUF9DRkdf RVBFTkRJQU4gICAgICAgICAgICAgICAgQklUKDcpCj4gKy8qIE1heCBidXJzdCBzaXplICh1c2Vk IG9ubHkgaW4gU1MgbW9kZSkuICovCj4gKyNkZWZpbmUgRVBfQ0ZHX01BWEJVUlNUX01BU0sgICBH RU5NQVNLKDExLCA4KQo+ICsjZGVmaW5lIEVQX0NGR19NQVhCVVJTVChwKSAgICAgKCgocCkgPDwg OCkgJiBFUF9DRkdfTUFYQlVSU1RfTUFTSykKPiArLyogSVNPIG1heCBidXJzdC4gKi8KPiArI2Rl ZmluZSBFUF9DRkdfTVVMVF9NQVNLICAgICAgIEdFTk1BU0soMTUsIDE0KQo+ICsjZGVmaW5lIEVQ X0NGR19NVUxUKHApICAgICAgICAgKCgocCkgPDwgMTQpICYgRVBfQ0ZHX01VTFRfTUFTSykKPiAr LyogSVNPIG1heCBidXJzdC4gKi8KPiArI2RlZmluZSBFUF9DRkdfTUFYUEtUU0laRV9NQVNLIEdF Tk1BU0soMjYsIDE2KQo+ICsjZGVmaW5lIEVQX0NGR19NQVhQS1RTSVpFKHApICAgKCgocCkgPDwg MTYpICYgRVBfQ0ZHX01BWFBLVFNJWkVfTUFTSykKPiArLyogTWF4IG51bWJlciBvZiBidWZmZXJl ZCBwYWNrZXRzLiAqLwo+ICsjZGVmaW5lIEVQX0NGR19CVUZGRVJJTkdfTUFTSyAgR0VOTUFTSygz MSwgMjcpCj4gKyNkZWZpbmUgRVBfQ0ZHX0JVRkZFUklORyhwKSAgICAoKChwKSA8PCAyNykgJiBF UF9DRkdfQlVGRkVSSU5HX01BU0spCj4gKwo+ICsvKiBFUF9DTUQgLSBiaXRtYXNrcyAqLwo+ICsv KiBFbmRwb2ludCByZXNldC4gKi8KPiArI2RlZmluZSBFUF9DTURfRVBSU1QgICAgICAgICAgIEJJ VCgwKQo+ICsvKiBFbmRwb2ludCBTVEFMTCBzZXQuICovCj4gKyNkZWZpbmUgRVBfQ01EX1NTVEFM TCAgICAgICAgICBCSVQoMSkKPiArLyogRW5kcG9pbnQgU1RBTEwgY2xlYXIuICovCj4gKyNkZWZp bmUgRVBfQ01EX0NTVEFMTCAgICAgICAgICBCSVQoMikKPiArLyogU2VuZCBFUkRZIFRQLiAqLwo+ ICsjZGVmaW5lIEVQX0NNRF9FUkRZICAgICAgICAgICAgQklUKDMpCj4gKy8qIFJlcXVlc3QgY29t cGxldGUuICovCj4gKyNkZWZpbmUgRVBfQ01EX1JFUV9DTVBMICAgICAgICAgICAgICAgIEJJVCg1 KQo+ICsvKiBUcmFuc2ZlciBkZXNjcmlwdG9yIHJlYWR5LiAqLwo+ICsjZGVmaW5lIEVQX0NNRF9E UkRZICAgICAgICAgICAgQklUKDYpCj4gKy8qIERhdGEgZmx1c2guICovCj4gKyNkZWZpbmUgRVBf Q01EX0RGTFVTSCAgICAgICAgICBCSVQoNykKPiArLyoKPiArICogVHJhbnNmZXIgRGVzY3JpcHRv ciBMZW5ndGggd3JpdGUgICh1c2VkIG9ubHkgZm9yIEJ1bGsgU3RyZWFtIGNhcGFibGUKPiArICog ZW5kcG9pbnRzIGluIFNTIG1vZGUpLgo+ICsgKi8KPiArI2RlZmluZSBFUF9DTURfU1RETCAgICAg ICAgICAgIEJJVCg4KQo+ICsvKiBUcmFuc2ZlciBEZXNjcmlwdG9yIExlbmd0aCAodXNlZCBvbmx5 IGluIFNTIG1vZGUgZm9yIGJ1bGsgZW5kcG9pbnRzKS4gKi8KPiArI2RlZmluZSBFUF9DTURfVERM X01BU0sgICAgICAgICAgICAgICAgR0VOTUFTSygxNSwgOSkKPiArI2RlZmluZSBFUF9DTURfVERM KHApICAgICAgICAgICgoKHApIDw8IDkpICYgRVBfQ01EX1RETF9NQVNLKQo+ICsvKiBFUkRZIFN0 cmVhbSBJRCB2YWx1ZSAodXNlZCBpbiBTUyBtb2RlKS4gKi8KPiArI2RlZmluZSBFUF9DTURfRVJE WV9TSURfTUFTSyAgIEdFTk1BU0soMzEsIDE2KQo+ICsjZGVmaW5lIEVQX0NNRF9FUkRZX1NJRChw KSAgICAgKCgocCkgPDwgMTYpICYgRVBfQ01EX1NJRF9NQVNLKQo+ICsKPiArLyogRVBfU1RTIC0g Yml0bWFza3MgKi8KPiArLyogU2V0dXAgdHJhbnNmZXIgY29tcGxldGUuICovCj4gKyNkZWZpbmUg RVBfU1RTX1NFVFVQICAgICAgICAgICBCSVQoMCkKPiArLyogRW5kcG9pbnQgU1RBTEwgc3RhdHVz LiAqLwo+ICsjZGVmaW5lIEVQX1NUU19TVEFMTChwKSAgICAgICAgICAgICAgICAoKHApICYgQklU KDEpKQo+ICsvKiBJbnRlcnJ1cHQgT24gQ29tcGxldGUuICovCj4gKyNkZWZpbmUgRVBfU1RTX0lP QyAgICAgICAgICAgICBCSVQoMikKPiArLyogSW50ZXJydXB0IG9uIFNob3J0IFBhY2tldC4gKi8K PiArI2RlZmluZSBFUF9TVFNfSVNQICAgICAgICAgICAgIEJJVCgzKQo+ICsvKiBUcmFuc2ZlciBk ZXNjcmlwdG9yIG1pc3NpbmcuICovCj4gKyNkZWZpbmUgRVBfU1RTX0RFU0NNSVMgICAgICAgICBC SVQoNCkKPiArLyogU3RyZWFtIFJlamVjdGVkICh1c2VkIG9ubHkgaW4gU1MgbW9kZSkgKi8KPiAr I2RlZmluZSBFUF9TVFNfU1RSRUFNUiAgICAgICAgIEJJVCg1KQo+ICsvKiBFWElUIGZyb20gTU9W RSBEQVRBIFN0YXRlICh1c2VkIG9ubHkgZm9yIHN0cmVhbSB0cmFuc2ZlcnMgaW4gU1MgbW9kZSku ICovCj4gKyNkZWZpbmUgRVBfU1RTX01EX0VYSVQgICAgICAgICBCSVQoNikKPiArLyogVFJCIGVy cm9yLiAqLwo+ICsjZGVmaW5lIEVQX1NUU19UUkJFUlIgICAgICAgICAgQklUKDcpCj4gKy8qIE5v dCByZWFkeSAodXNlZCBvbmx5IGluIFNTIG1vZGUpLiAqLwo+ICsjZGVmaW5lIEVQX1NUU19OUkRZ ICAgICAgICAgICAgQklUKDgpCj4gKy8qIERNQSBidXN5LiAqLwo+ICsjZGVmaW5lIEVQX1NUU19E QlVTWShwKSAgICAgICAgICAgICAgICAoKHApICYgQklUKDkpKQo+ICsvKiBFbmRwb2ludCBCdWZm ZXIgRW1wdHkgKi8KPiArI2RlZmluZSBFUF9TVFNfQlVGRkVNUFRZKHApICAgICgocCkgJiBCSVQo MTApKQo+ICsvKiBDdXJyZW50IEN5Y2xlIFN0YXR1cyAqLwo+ICsjZGVmaW5lIEVQX1NUU19DQ1Mo cCkgICAgICAgICAgKChwKSAmIEJJVCgxMSkpCj4gKy8qIFByaW1lICh1c2VkIG9ubHkgaW4gU1Mg bW9kZS4gKi8KPiArI2RlZmluZSBFUF9TVFNfUFJJTUUgICAgICAgICAgIEJJVCgxMikKPiArLyog U3RyZWFtIGVycm9yICh1c2VkIG9ubHkgaW4gU1MgbW9kZSkuICovCj4gKyNkZWZpbmUgRVBfU1RT X1NJREVSUiAgICAgICAgICBCSVQoMTMpCj4gKy8qIE9VVCBzaXplIG1pc21hdGNoLiAqLwo+ICsj ZGVmaW5lIEVQX1NUU19PVVRTTU0gICAgICAgICAgQklUKDE0KQo+ICsvKiBJU08gdHJhbnNtaXNz aW9uIGVycm9yLiAqLwo+ICsjZGVmaW5lIEVQX1NUU19JU09FUlIgICAgICAgICAgQklUKDE1KQo+ ICsvKiBIb3N0IFBhY2tldCBQZW5kaW5nIChvbmx5IGZvciBTUyBtb2RlKS4gKi8KPiArI2RlZmlu ZSBFUF9TVFNfSE9TVFBQKHApICAgICAgICgocCkgJiBCSVQoMTYpKQo+ICsvKiBTdHJlYW0gUHJv dG9jb2wgU3RhdGUgTWFjaGluZSBTdGF0ZSAob25seSBmb3IgQnVsayBzdHJlYW0gZW5kcG9pbnRz KS4gKi8KPiArI2RlZmluZSBFUF9TVFNfU1BTTVNUX01BU0sgICAgICAgICAgICAgR0VOTUFTSygx OCwgMTcpCj4gKyNkZWZpbmUgRVBfU1RTX1NQU01TVF9ESVNBQkxFRChwKSAgICAgICgoKHApICYg RVBfU1RTX1NQU01TVF9NQVNLKSA+PiAxNykKPiArI2RlZmluZSBFUF9TVFNfU1BTTVNUX0lETEUo cCkgICAgICAgICAgKCgocCkgJiBFUF9TVFNfU1BTTVNUX01BU0spID4+IDE3KQo+ICsjZGVmaW5l IEVQX1NUU19TUFNNU1RfU1RBUlRfU1RSRUFNKHApICAoKChwKSAmIEVQX1NUU19TUFNNU1RfTUFT SykgPj4gMTcpCj4gKyNkZWZpbmUgRVBfU1RTX1NQU01TVF9NT1ZFX0RBVEEocCkgICAgICgoKHAp ICYgRVBfU1RTX1NQU01TVF9NQVNLKSA+PiAxNykKPiArLyogSW50ZXJydXB0IE9uIFRyYW5zZmVy IGNvbXBsZXRlLiAqLwo+ICsjZGVmaW5lIEVQX1NUU19JT1QgICAgICAgICAgICAgQklUKDE5KQo+ ICsvKiBPVVQgcXVldWUgZW5kcG9pbnQgbnVtYmVyLiAqLwo+ICsjZGVmaW5lIEVQX1NUU19PVVRR X05PX01BU0sgICAgR0VOTUFTSygyNywgMjQpCj4gKyNkZWZpbmUgRVBfU1RTX09VVFFfTk8ocCkg ICAgICAoKChwKSAmIEVQX1NUU19PVVRRX05PX01BU0spID4+IDI0KQo+ICsvKiBPVVQgcXVldWUg dmFsaWQgZmxhZy4gKi8KPiArI2RlZmluZSBFUF9TVFNfT1VUUV9WQUxfTUFTSyAgIEJJVCgyOCkK PiArI2RlZmluZSBFUF9TVFNfT1VUUV9WQUwocCkgICAgICgocCkgJiBFUF9TVFNfT1VUUV9WQUxf TUFTSykKPiArLyogU0VUVVAgV0FJVC4gKi8KPiArI2RlZmluZSBFUF9TVFNfU1RQV0FJVCAgICAg ICAgIEJJVCgzMSkKPiArCj4gKy8qIEVQX1NUU19TSUQgLSBiaXRtYXNrcyAqLwo+ICsvKiBTdHJl YW0gSUQgKHVzZWQgb25seSBpbiBTUyBtb2RlKS4gKi8KPiArI2RlZmluZSBFUF9TVFNfU0lEX01B U0sgICAgICAgICAgICAgICAgR0VOTUFTSygxNSwgMCkKPiArI2RlZmluZSBFUF9TVFNfU0lEKHAp ICAgICAgICAgICgocCkgJiBFUF9TVFNfU0lEX01BU0spCj4gKwo+ICsvKiBFUF9TVFNfRU4gLSBi aXRtYXNrcyAqLwo+ICsvKiBTRVRVUCBpbnRlcnJ1cHQgZW5hYmxlLiAqLwo+ICsjZGVmaW5lIEVQ X1NUU19FTl9TRVRVUEVOICAgICAgQklUKDApCj4gKy8qIE9VVCB0cmFuc2ZlciBtaXNzaW5nIGRl c2NyaXB0b3IgZW5hYmxlLiAqLwo+ICsjZGVmaW5lIEVQX1NUU19FTl9ERVNDTUlTRU4gICAgQklU KDQpCj4gKy8qIFN0cmVhbSBSZWplY3RlZCBlbmFibGUuICovCj4gKyNkZWZpbmUgRVBfU1RTX0VO X1NUUkVBTVJFTiAgICBCSVQoNSkKPiArLyogTW92ZSBEYXRhIEV4aXQgZW5hYmxlLiovCj4gKyNk ZWZpbmUgRVBfU1RTX0VOX01EX0VYSVRFTiAgICBCSVQoNikKPiArLyogVFJCIGVuYWJsZS4gKi8K PiArI2RlZmluZSBFUF9TVFNfRU5fVFJCRVJSRU4gICAgIEJJVCg3KQo+ICsvKiBOUkRZIGVuYWJs ZS4gKi8KPiArI2RlZmluZSBFUF9TVFNfRU5fTlJEWUVOICAgICAgIEJJVCg4KQo+ICsvKiBQcmlt ZSBlbmFibGUuICovCj4gKyNkZWZpbmUgRVBfU1RTX0VOX1BSSU1FRUVOICAgICBCSVQoMTIpCj4g Ky8qIFN0cmVhbSBlcnJvciBlbmFibGUuICovCj4gKyNkZWZpbmUgRVBfU1RTX0VOX1NJREVSUkVO ICAgICBCSVQoMTMpCj4gKy8qIE9VVCBzaXplIG1pc21hdGNoIGVuYWJsZS4gKi8KPiArI2RlZmlu ZSBFUF9TVFNfRU5fT1VUU01NRU4gICAgIEJJVCgxNCkKPiArLyogSVNPIHRyYW5zbWlzc2lvbiBl cnJvciBlbmFibGUuICovCj4gKyNkZWZpbmUgRVBfU1RTX0VOX0lTT0VSUkVOICAgICBCSVQoMTUp Cj4gKy8qIEludGVycnVwdCBvbiBUcmFuc21pc3Npb24gY29tcGxldGUgZW5hYmxlLiAqLwo+ICsj ZGVmaW5lIEVQX1NUU19FTl9JT1RFTiAgICAgICAgICAgICAgICBCSVQoMTkpCj4gKy8qIFNldHVw IFdhaXQgaW50ZXJydXB0IGVuYWJsZS4gKi8KPiArI2RlZmluZSBFUF9TVFNfRU5fU1RQV0FJVEVO ICAgIEJJVCgzMSkKPiArCj4gKy8qIERSQkwtIGJpdG1hc2tzICovCj4gKyNkZWZpbmUgREJfVkFM VUVfQllfSU5ERVgoaW5kZXgpICgxIDw8IChpbmRleCkpCj4gKyNkZWZpbmUgREJfVkFMVUVfRVAw X09VVCAgICAgICBCSVQoMCkKPiArI2RlZmluZSBEQl9WQUxVRV9FUDBfSU4gICAgICAgICAgICAg ICAgQklUKDE2KQo+ICsKPiArLyogRVBfSUVOIC0gYml0bWFza3MgKi8KPiArI2RlZmluZSBFUF9J RU4oaW5kZXgpICAgICAgICAgICgxIDw8IChpbmRleCkpCj4gKyNkZWZpbmUgRVBfSUVOX0VQX09V VDAgICAgICAgICBCSVQoMCkKPiArI2RlZmluZSBFUF9JRU5fRVBfSU4wICAgICAgICAgIEJJVCgx NikKPiArCj4gKy8qIEVQX0lTVFMgLSBiaXRtYXNrcyAqLwo+ICsjZGVmaW5lIEVQX0lTVFMoaW5k ZXgpICAgICAgICAgKDEgPDwgKGluZGV4KSkKPiArI2RlZmluZSBFUF9JU1RTX0VQX09VVDAgICAg ICAgICAgICAgICAgQklUKDApCj4gKyNkZWZpbmUgRVBfSVNUU19FUF9JTjAgICAgICAgICBCSVQo MTYpCj4gKwo+ICsvKiBFUF9QV1ItIGJpdG1hc2tzICovCj4gKy8qUG93ZXIgU2h1dCBPZmYgY2Fw YWJpbGl0eSBlbmFibGUqLwo+ICsjZGVmaW5lIFBVU0JfUFdSX1BTT19FTiAgICAgICAgICAgICAg ICBCSVQoMCkKPiArLypQb3dlciBTaHV0IE9mZiBjYXBhYmlsaXR5IGRpc2FibGUqLwo+ICsjZGVm aW5lIFBVU0JfUFdSX1BTT19EUyAgICAgICAgICAgICAgICBCSVQoMSkKPiArLyoKPiArICogRW5h YmxlcyB0dXJuaW5nLW9mZiBSZWZlcmVuY2UgQ2xvY2suCj4gKyAqIFRoaXMgYml0IGlzIG9wdGlv bmFsIGFuZCBpbXBsZW1lbnRlZCBvbmx5IHdoZW4gc3VwcG9ydCBmb3IgT1RHIGlzCj4gKyAqIGlt cGxlbWVudGVkIChpbmRpY2F0ZWQgYnkgT1RHX1JFQURZIGJpdCBzZXQgdG8gJzEnKS4KPiArICov Cj4gKyNkZWZpbmUgUFVTQl9QV1JfU1RCX0NMS19TV0lUQ0hfRU4gICAgIEJJVCg4KQo+ICsvKgo+ ICsgKiBTdGF0dXMgYml0IGluZGljYXRpbmcgdGhhdCBvcGVyYXRpb24gcmVxdWlyZWQgYnkgU1RC X0NMS19TV0lUQ0hfRU4gd3JpdGUKPiArICogaXMgY29tcGxldGVkCj4gKyAqLwo+ICsjZGVmaW5l IFBVU0JfUFdSX1NUQl9DTEtfU1dJVENIX0RPTkUgICBCSVQoOSkKPiArLyogVGhpcyBiaXQgaW5m b3JtcyBpZiBGYXN0IFJlZ2lzdGVycyBBY2Nlc3MgaXMgZW5hYmxlZC4gKi8KPiArI2RlZmluZSBQ VVNCX1BXUl9GU1RfUkVHX0FDQ0VTU19TVEFUICAgQklUKDMwKQo+ICsvKiBGYXN0IFJlZ2lzdGVy cyBBY2Nlc3MgRW5hYmxlLiAqLwo+ICsjZGVmaW5lIFBVU0JfUFdSX0ZTVF9SRUdfQUNDRVNTICAg ICAgICBCSVQoMzEpCj4gKwo+ICsvKiBVU0JfQ0FQMS0gYml0bWFza3MgKi8KPiArLyoKPiArICog U0ZSIEludGVyZmFjZSB0eXBlCj4gKyAqIFRoZXNlIGZpZWxkIHJlZmxlY3RzIHR5cGUgb2YgU0ZS IGludGVyZmFjZSBpbXBsZW1lbnRlZDoKPiArICogMHgwIC0gT0NQCj4gKyAqIDB4MSAtIEFIQiwK PiArICogMHgyIC0gUExCCj4gKyAqIDB4MyAtIEFYSQo+ICsgKiAweDQtMHhGIC0gcmVzZXJ2ZWQK PiArICovCj4gKyNkZWZpbmUgVVNCX0NBUDFfU0ZSX1RZUEVfTUFTSyBHRU5NQVNLKDMsIDApCj4g KyNkZWZpbmUgREVWX1NGUl9UWVBFX09DUChwKSAgICAoKChwKSAmIFVTQl9DQVAxX1NGUl9UWVBF X01BU0spID09IDB4MCkKPiArI2RlZmluZSBERVZfU0ZSX1RZUEVfQUhCKHApICAgICgoKHApICYg VVNCX0NBUDFfU0ZSX1RZUEVfTUFTSykgPT0gMHgxKQo+ICsjZGVmaW5lIERFVl9TRlJfVFlQRV9Q TEIocCkgICAgKCgocCkgJiBVU0JfQ0FQMV9TRlJfVFlQRV9NQVNLKSA9PSAweDIpCj4gKyNkZWZp bmUgREVWX1NGUl9UWVBFX0FYSShwKSAgICAoKChwKSAmIFVTQl9DQVAxX1NGUl9UWVBFX01BU0sp ID09IDB4MykKPiArLyoKPiArICogU0ZSIEludGVyZmFjZSB3aWR0aAo+ICsgKiBUaGVzZSBmaWVs ZCByZWZsZWN0cyB3aWR0aCBvZiBTRlIgaW50ZXJmYWNlIGltcGxlbWVudGVkOgo+ICsgKiAweDAg LSA4IGJpdCBpbnRlcmZhY2UsCj4gKyAqIDB4MSAtIDE2IGJpdCBpbnRlcmZhY2UsCj4gKyAqIDB4 MiAtIDMyIGJpdCBpbnRlcmZhY2UKPiArICogMHgzIC0gNjQgYml0IGludGVyZmFjZQo+ICsgKiAw eDQtMHhGIC0gcmVzZXJ2ZWQKPiArICovCj4gKyNkZWZpbmUgVVNCX0NBUDFfU0ZSX1dJRFRIX01B U0sgICAgICAgIEdFTk1BU0soNywgNCkKPiArI2RlZmluZSBERVZfU0ZSX1dJRFRIXzgocCkgICAg ICgoKHApICYgVVNCX0NBUDFfU0ZSX1dJRFRIX01BU0spID09ICgweDAgPDwgNCkpCj4gKyNkZWZp bmUgREVWX1NGUl9XSURUSF8xNihwKSAgICAoKChwKSAmIFVTQl9DQVAxX1NGUl9XSURUSF9NQVNL KSA9PSAoMHgxIDw8IDQpKQo+ICsjZGVmaW5lIERFVl9TRlJfV0lEVEhfMzIocCkgICAgKCgocCkg JiBVU0JfQ0FQMV9TRlJfV0lEVEhfTUFTSykgPT0gKDB4MiA8PCA0KSkKPiArI2RlZmluZSBERVZf U0ZSX1dJRFRIXzY0KHApICAgICgoKHApICYgVVNCX0NBUDFfU0ZSX1dJRFRIX01BU0spID09ICgw eDMgPDwgNCkpCj4gKy8qCj4gKyAqIERNQSBJbnRlcmZhY2UgdHlwZQo+ICsgKiBUaGVzZSBmaWVs ZCByZWZsZWN0cyB0eXBlIG9mIERNQSBpbnRlcmZhY2UgaW1wbGVtZW50ZWQ6Cj4gKyAqIDB4MCAt IE9DUAo+ICsgKiAweDEgLSBBSEIsCj4gKyAqIDB4MiAtIFBMQgo+ICsgKiAweDMgLSBBWEkKPiAr ICogMHg0LTB4RiAtIHJlc2VydmVkCj4gKyAqLwo+ICsjZGVmaW5lIFVTQl9DQVAxX0RNQV9UWVBF X01BU0sgR0VOTUFTSygxMSwgOCkKPiArI2RlZmluZSBERVZfRE1BX1RZUEVfT0NQKHApICAgICgo KHApICYgVVNCX0NBUDFfRE1BX1RZUEVfTUFTSykgPT0gKDB4MCA8PCA4KSkKPiArI2RlZmluZSBE RVZfRE1BX1RZUEVfQUhCKHApICAgICgoKHApICYgVVNCX0NBUDFfRE1BX1RZUEVfTUFTSykgPT0g KDB4MSA8PCA4KSkKPiArI2RlZmluZSBERVZfRE1BX1RZUEVfUExCKHApICAgICgoKHApICYgVVNC X0NBUDFfRE1BX1RZUEVfTUFTSykgPT0gKDB4MiA8PCA4KSkKPiArI2RlZmluZSBERVZfRE1BX1RZ UEVfQVhJKHApICAgICgoKHApICYgVVNCX0NBUDFfRE1BX1RZUEVfTUFTSykgPT0gKDB4MyA8PCA4 KSkKPiArLyoKPiArICogRE1BIEludGVyZmFjZSB3aWR0aAo+ICsgKiBUaGVzZSBmaWVsZCByZWZs ZWN0cyB3aWR0aCBvZiBETUEgaW50ZXJmYWNlIGltcGxlbWVudGVkOgo+ICsgKiAweDAgLSByZXNl cnZlZCwKPiArICogMHgxIC0gcmVzZXJ2ZWQsCj4gKyAqIDB4MiAtIDMyIGJpdCBpbnRlcmZhY2UK PiArICogMHgzIC0gNjQgYml0IGludGVyZmFjZQo+ICsgKiAweDQtMHhGIC0gcmVzZXJ2ZWQKPiAr ICovCj4gKyNkZWZpbmUgVVNCX0NBUDFfRE1BX1dJRFRIX01BU0sgICAgICAgIEdFTk1BU0soMTUs IDEyKQo+ICsjZGVmaW5lIERFVl9ETUFfV0lEVEhfMzIocCkgICAgKCgocCkgJiBVU0JfQ0FQMV9E TUFfV0lEVEhfTUFTSykgPT0gKDB4MiA8PCAxMikpCj4gKyNkZWZpbmUgREVWX0RNQV9XSURUSF82 NChwKSAgICAoKChwKSAmIFVTQl9DQVAxX0RNQV9XSURUSF9NQVNLKSA9PSAoMHgzIDw8IDEyKSkK PiArLyoKPiArICogVVNCMyBQSFkgSW50ZXJmYWNlIHR5cGUKPiArICogVGhlc2UgZmllbGQgcmVm bGVjdHMgdHlwZSBvZiBVU0IzIFBIWSBpbnRlcmZhY2UgaW1wbGVtZW50ZWQ6Cj4gKyAqIDB4MCAt IFVTQiBQSVBFLAo+ICsgKiAweDEgLSBSTU1JLAo+ICsgKiAweDItMHhGIC0gcmVzZXJ2ZWQKPiAr ICovCj4gKyNkZWZpbmUgVVNCX0NBUDFfVTNQSFlfVFlQRV9NQVNLIEdFTk1BU0soMTksIDE2KQo+ ICsjZGVmaW5lIERFVl9VM1BIWV9QSVBFKHApICgoKHApICYgVVNCX0NBUDFfVTNQSFlfVFlQRV9N QVNLKSA9PSAoMHgwIDw8IDE2KSkKPiArI2RlZmluZSBERVZfVTNQSFlfUk1NSShwKSAoKChwKSAm IFVTQl9DQVAxX1UzUEhZX1RZUEVfTUFTSykgPT0gKDB4MSA8PCAxNikpCj4gKy8qCj4gKyAqIFVT QjMgUEhZIEludGVyZmFjZSB3aWR0aAo+ICsgKiBUaGVzZSBmaWVsZCByZWZsZWN0cyB3aWR0aCBv ZiBVU0IzIFBIWSBpbnRlcmZhY2UgaW1wbGVtZW50ZWQ6Cj4gKyAqIDB4MCAtIDggYml0IFBJUEUg aW50ZXJmYWNlLAo+ICsgKiAweDEgLSAxNiBiaXQgUElQRSBpbnRlcmZhY2UsCj4gKyAqIDB4MiAt IDMyIGJpdCBQSVBFIGludGVyZmFjZSwKPiArICogMHgzIC0gNjQgYml0IFBJUEUgaW50ZXJmYWNl Cj4gKyAqIDB4NC0weEYgLSByZXNlcnZlZAo+ICsgKiBOb3RlOiBXaGVuIFNTSUMgaW50ZXJmYWNl IGlzIGltcGxlbWVudGVkIHRoaXMgZmllbGQgc2hvd3MgdGhlIHdpZHRoIG9mCj4gKyAqIGludGVy bmFsIFBJUEUgaW50ZXJmYWNlLiBUaGUgUk1NSSBpbnRlcmZhY2UgaXMgYWx3YXlzIDIwYml0IHdp ZGUuCj4gKyAqLwo+ICsjZGVmaW5lIFVTQl9DQVAxX1UzUEhZX1dJRFRIX01BU0sgR0VOTUFTSygy MywgMjApCj4gKyNkZWZpbmUgREVWX1UzUEhZX1dJRFRIXzgocCkgXAo+ICsgICAgICAgKCgocCkg JiBVU0JfQ0FQMV9VM1BIWV9XSURUSF9NQVNLKSA9PSAoMHgwIDw8IDIwKSkKPiArI2RlZmluZSBE RVZfVTNQSFlfV0lEVEhfMTYocCkgXAo+ICsgICAgICAgKCgocCkgJiBVU0JfQ0FQMV9VM1BIWV9X SURUSF9NQVNLKSA9PSAoMHgxIDw8IDE2KSkKPiArI2RlZmluZSBERVZfVTNQSFlfV0lEVEhfMzIo cCkgXAo+ICsgICAgICAgKCgocCkgJiBVU0JfQ0FQMV9VM1BIWV9XSURUSF9NQVNLKSA9PSAoMHgy IDw8IDIwKSkKPiArI2RlZmluZSBERVZfVTNQSFlfV0lEVEhfNjQocCkgXAo+ICsgICAgICAgKCgo cCkgJiBVU0JfQ0FQMV9VM1BIWV9XSURUSF9NQVNLKSA9PSAoMHgzIDw8IDE2KSkKPiArCj4gKy8q Cj4gKyAqIFVTQjIgUEhZIEludGVyZmFjZSBlbmFibGUKPiArICogVGhlc2UgZmllbGQgaW5mb3Jt cyBpZiBVU0IyIFBIWSBpbnRlcmZhY2UgaXMgaW1wbGVtZW50ZWQ6Cj4gKyAqIDB4MCAtIGludGVy ZmFjZSBOT1QgaW1wbGVtZW50ZWQsCj4gKyAqIDB4MSAtIGludGVyZmFjZSBpbXBsZW1lbnRlZAo+ ICsgKi8KPiArI2RlZmluZSBVU0JfQ0FQMV9VMlBIWV9FTihwKSAgICgocCkgJiBCSVQoMjQpKQo+ ICsvKgo+ICsgKiBVU0IyIFBIWSBJbnRlcmZhY2UgdHlwZQo+ICsgKiBUaGVzZSBmaWVsZCByZWZs ZWN0cyB0eXBlIG9mIFVTQjIgUEhZIGludGVyZmFjZSBpbXBsZW1lbnRlZDoKPiArICogMHgwIC0g VVRNSSwKPiArICogMHgxIC0gVUxQSQo+ICsgKi8KPiArI2RlZmluZSBERVZfVTJQSFlfVUxQSShw KSAgICAgICgocCkgJiBCSVQoMjUpKQo+ICsvKgo+ICsgKiBVU0IyIFBIWSBJbnRlcmZhY2Ugd2lk dGgKPiArICogVGhlc2UgZmllbGQgcmVmbGVjdHMgd2lkdGggb2YgVVNCMiBQSFkgaW50ZXJmYWNl IGltcGxlbWVudGVkOgo+ICsgKiAweDAgLSA4IGJpdCBpbnRlcmZhY2UsCj4gKyAqIDB4MSAtIDE2 IGJpdCBpbnRlcmZhY2UsCj4gKyAqIE5vdGU6IFRoZSBVTFBJIGludGVyZmFjZSBpcyBhbHdheXMg OGJpdCB3aWRlLgo+ICsgKi8KPiArI2RlZmluZSBERVZfVTJQSFlfV0lEVEhfMTYocCkgICgocCkg JiBCSVQoMjYpKQo+ICsvKgo+ICsgKiBPVEcgUmVhZHkKPiArICogMHgwIC0gcHVyZSBkZXZpY2Ug bW9kZQo+ICsgKiAweDEgLSBzb21lIGZlYXR1cmVzIGFuZCBwb3J0cyBmb3IgQ0ROUyBVU0IgT1RH IGNvbnRyb2xsZXIgYXJlIGltcGxlbWVudGVkLgo+ICsgKi8KPiArI2RlZmluZSBVU0JfQ0FQMV9P VEdfUkVBRFkocCkgICgocCkgJiBCSVQoMjcpKQo+ICsKPiArLyogVVNCX0NBUDItIGJpdG1hc2tz ICovCj4gKy8qCj4gKyAqIFRoZSBhY3R1YWwgc2l6ZSBvZiB0aGUgY29ubmVjdGVkIE9uLWNoaXAg UkFNIG1lbW9yeSBpbiBrQjoKPiArICogLSAwIG1lYW5zIDI1NiBrQiAobWF4IHN1cHBvcnRlZCBt ZW0gc2l6ZSkKPiArICogLSB2YWx1ZSBvdGhlciB0aGFuIDAgcmVmbGVjdHMgdGhlIG1lbSBzaXpl IGluIGtCCj4gKyAqLwo+ICsjZGVmaW5lIFVTQl9DQVAyX0FDVFVBTF9NRU1fU0laRShwKSAoKHAp ICYgR0VOTUFTSyg3LCAwKSkKPiArLyoKPiArICogTWF4IHN1cHBvcnRlZCBtZW0gc2l6ZQo+ICsg KiBUaGVzZSBmaWVsZCByZWZsZWN0cyB3aWR0aCBvZiBvbi1jaGlwIFJBTSBhZGRyZXNzIGJ1cyB3 aWR0aCwKPiArICogd2hpY2ggZGV0ZXJtaW5lcyBtYXggc3VwcG9ydGVkIG1lbSBzaXplOgo+ICsg KiAweDAtMHg3IC0gcmVzZXJ2ZWQsCj4gKyAqIDB4OCAtIHN1cHBvcnQgZm9yIDRrQiBtZW0sCj4g KyAqIDB4OSAtIHN1cHBvcnQgZm9yIDhrQiBtZW0sCj4gKyAqIDB4QSAtIHN1cHBvcnQgZm9yIDE2 a0IgbWVtLAo+ICsgKiAweEIgLSBzdXBwb3J0IGZvciAzMmtCIG1lbSwKPiArICogMHhDIC0gc3Vw cG9ydCBmb3IgNjRrQiBtZW0sCj4gKyAqIDB4RCAtIHN1cHBvcnQgZm9yIDEyOGtCIG1lbSwKPiAr ICogMHhFIC0gc3VwcG9ydCBmb3IgMjU2a0IgbWVtLAo+ICsgKiAweEYgLSByZXNlcnZlZAo+ICsg Ki8KPiArI2RlZmluZSBVU0JfQ0FQMl9NQVhfTUVNX1NJWkUocCkgKChwKSAmIEdFTk1BU0soMTEs IDgpKQo+ICsKPiArLyogVVNCX0NBUDMtIGJpdG1hc2tzICovCj4gKyNkZWZpbmUgRVBfSVNfSU1Q TEVNRU5URUQocmVnLCBpbmRleCkgKChyZWcpICYgKDEgPDwgKGluZGV4KSkpCj4gKwo+ICsvKiBV U0JfQ0FQNC0gYml0bWFza3MgKi8KPiArI2RlZmluZSBFUF9TVVBQT1JUX0lTTyhyZWcsIGluZGV4 KSAoKHJlZykgJiAoMSA8PCAoaW5kZXgpKSkKPiArCj4gKy8qIFVTQl9DQVA1LSBiaXRtYXNrcyAq Lwo+ICsjZGVmaW5lIEVQX1NVUFBPUlRfU1RSRUFNKHJlZywgaW5kZXgpICgocmVnKSAmICgxIDw8 IChpbmRleCkpKQo+ICsKPiArLyogVVNCX0NBUDYtIGJpdG1hc2tzICovCj4gKy8qIFRoZSBVU0JT Uy1ERVYgQ29udHJvbGxlciAgSW50ZXJuYWwgYnVpbGQgbnVtYmVyLiAqLwo+ICsjZGVmaW5lIEdF VF9ERVZfVkVSU0lPTl9fSU5URVJOQUxfTlVNQkVSKHApICgocCkgJiBHRU5NQVNLKDcsIDApKQo+ ICsvKiBUaGUgVVNCU1MtREVWIENvbnRyb2xsZXIgIHZlcnNpb24gbnVtYmVyLiAqLwo+ICsjZGVm aW5lIEdFVF9ERVZfVkVSU0lPTihwKSAoKHApICYgR0VOTUFTSygzMSwgOCkpCj4gKwo+ICsvKiBE QkdfTElOSzEtIGJpdG1hc2tzICovCj4gKy8qCj4gKyAqIExGUFNfTUlOX0RFVF9VMV9FWElUIHZh bHVlIFRoaXMgcGFyYW1ldGVyIGNvbmZpZ3VyZXMgdGhlIG1pbmltdW0KPiArICogdGltZSByZXF1 aXJlZCBmb3IgZGVjb2RpbmcgdGhlIHJlY2VpdmVkIExGUFMgYXMgYW4gTEZQUy5VMV9FeGl0Lgo+ ICsgKi8KPiArI2RlZmluZSBEQkdfTElOSzFfTEZQU19NSU5fREVUX1UxX0VYSVQocCkgICAgICAo KHApICYgR0VOTUFTSyg3LCAwKSkKPiArLyoKPiArICogTEZQU19NSU5fR0VOX1UxX0VYSVQgdmFs dWUgVGhpcyBwYXJhbWV0ZXIgY29uZmlndXJlcyB0aGUgbWluaW11bSB0aW1lIGZvcgo+ICsgKiBw aHl0eGVsZWNpZGxlIGRlYXNzZXJ0aW9uIHdoZW4gTEZQUy5VMV9FeGl0Cj4gKyAqLwo+ICsjZGVm aW5lIERCR19MSU5LMV9MRlBTX01JTl9HRU5fVTFfRVhJVF9NQVNLICAgIEdFTk1BU0soMTUsIDgp Cj4gKyNkZWZpbmUgREJHX0xJTksxX0xGUFNfTUlOX0dFTl9VMV9FWElUKHApICAgICAgKCgocCkg PDwgOCkgJiBHRU5NQVNLKDE1LCA4KSkKPiArLyoKPiArICogUlhERVRfQlJFQUtfRElTIHZhbHVl IFRoaXMgcGFyYW1ldGVyIGNvbmZpZ3VyZXMgdGVybWluYXRpbmcgdGhlIEZhci1lbmQKPiArICog UmVjZWl2ZXIgdGVybWluYXRpb24gZGV0ZWN0aW9uIHNlcXVlbmNlOgo+ICsgKiAwOiBpdCBpcyBw b3NzaWJsZSB0aGF0IFVTQlNTX0RFViB3aWxsIHRlcm1pbmF0ZSBGYXJlbmQgcmVjZWl2ZXIKPiAr ICogICAgdGVybWluYXRpb24gZGV0ZWN0aW9uIHNlcXVlbmNlCj4gKyAqIDE6IFVTQlNTX0RFViB3 aWxsIG5vdCB0ZXJtaW5hdGUgRmFyLWVuZCByZWNlaXZlciB0ZXJtaW5hdGlvbgo+ICsgKiAgICBk ZXRlY3Rpb24gc2VxdWVuY2UKPiArICovCj4gKyNkZWZpbmUgREJHX0xJTksxX1JYREVUX0JSRUFL X0RJUyAgICAgICAgICAgICAgQklUKDE2KQo+ICsvKiBMRlBTX0dFTl9QSU5HIHZhbHVlIFRoaXMg cGFyYW1ldGVyIGNvbmZpZ3VyZXMgdGhlIExGUFMuUGluZyBnZW5lcmF0aW9uICovCj4gKyNkZWZp bmUgREJHX0xJTksxX0xGUFNfR0VOX1BJTkcocCkgICAgICAgICAgICAgKCgocCkgPDwgMTcpICYg R0VOTUFTSygyMSwgMTcpKQo+ICsvKgo+ICsgKiBTZXQgdGhlIExGUFNfTUlOX0RFVF9VMV9FWElU IHZhbHVlIFdyaXRpbmcgJzEnIHRvIHRoaXMgYml0IHdyaXRlcyB0aGUKPiArICogTEZQU19NSU5f REVUX1UxX0VYSVQgZmllbGQgdmFsdWUgdG8gdGhlIGRldmljZS4gVGhpcyBiaXQgaXMgYXV0b21h dGljYWxseQo+ICsgKiBjbGVhcmVkLiBXcml0aW5nICcwJyBoYXMgbm8gZWZmZWN0Cj4gKyAqLwo+ ICsjZGVmaW5lIERCR19MSU5LMV9MRlBTX01JTl9ERVRfVTFfRVhJVF9TRVQgICAgIEJJVCgyNCkK PiArLyoKPiArICogU2V0IHRoZSBMRlBTX01JTl9HRU5fVTFfRVhJVCB2YWx1ZS4gV3JpdGluZyAn MScgdG8gdGhpcyBiaXQgd3JpdGVzIHRoZQo+ICsgKiBMRlBTX01JTl9HRU5fVTFfRVhJVCBmaWVs ZCB2YWx1ZSB0byB0aGUgZGV2aWNlLiBUaGlzIGJpdCBpcyBhdXRvbWF0aWNhbGx5Cj4gKyAqIGNs ZWFyZWQuIFdyaXRpbmcgJzAnIGhhcyBubyBlZmZlY3QKPiArICovCj4gKyNkZWZpbmUgREJHX0xJ TksxX0xGUFNfTUlOX0dFTl9VMV9FWElUX1NFVCAgICAgQklUKDI1KQo+ICsvKgo+ICsgKiBTZXQg dGhlIFJYREVUX0JSRUFLX0RJUyB2YWx1ZSBXcml0aW5nICcxJyB0byB0aGlzIGJpdCB3cml0ZXMK PiArICogdGhlIFJYREVUX0JSRUFLX0RJUyBmaWVsZCB2YWx1ZSB0byB0aGUgZGV2aWNlLiBUaGlz IGJpdCBpcyBhdXRvbWF0aWNhbGx5Cj4gKyAqIGNsZWFyZWQuIFdyaXRpbmcgJzAnIGhhcyBubyBl ZmZlY3QKPiArICovCj4gKyNkZWZpbmUgREJHX0xJTksxX1JYREVUX0JSRUFLX0RJU19TRVQgICAg ICAgICAgQklUKDI2KQo+ICsvKgo+ICsgKiBTZXQgdGhlIExGUFNfR0VOX1BJTkdfU0VUIHZhbHVl IFdyaXRpbmcgJzEnIHRvIHRoaXMgYml0IHdyaXRlcwo+ICsgKiB0aGUgTEZQU19HRU5fUElORyBm aWVsZCB2YWx1ZSB0byB0aGUgZGV2aWNlLiBUaGlzIGJpdCBpcyBhdXRvbWF0aWNhbGx5Cj4gKyAq IGNsZWFyZWQuIFdyaXRpbmcgJzAnIGhhcyBubyBlZmZlY3QuIgo+ICsgKi8KPiArI2RlZmluZSBE QkdfTElOSzFfTEZQU19HRU5fUElOR19TRVQgICAgICAgICAgICBCSVQoMjcpCj4gKwo+ICsjZGVm aW5lIGdhZGdldF90b19jZG5zM19kZXZpY2UoZykgKGNvbnRhaW5lcl9vZihnLCBzdHJ1Y3QgY2Ru czNfZGV2aWNlLCBnYWRnZXQpKQo+ICsKPiArI2RlZmluZSBlcF90b19jZG5zM19lcChlcCkgKGNv bnRhaW5lcl9vZihlcCwgc3RydWN0IGNkbnMzX2VuZHBvaW50LCBlbmRwb2ludCkpCj4gKwo+ICsv Ki0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0qLwo+ICsvKgo+ICsgKiBVU0JTUy1ERVYgRE1BIGludGVyZmFjZS4K PiArICovCj4gKyNkZWZpbmUgVFJCU19QRVJfU0VHTUVOVCAgICAgICA0MAo+ICsKPiArI2RlZmlu ZSBJU09fTUFYX0lOVEVSVkFMICAgICAgIDEwCj4gKwo+ICsvKgo+ICsgKk9ubHkgZm9yIElTT0Mg ZW5kcG9pbnRzIC0gbWF4aW11bSBudW1iZXIgb2YgVFJCcyBpcyBjYWxjdWxhdGVkIGFzCj4gKyAq IHBvdygyLCBiSW50ZXJ2YWwtMSkgKiBudW1iZXIgb2YgdXNiIHJlcXVlc3RzLiBJdCBpcyBsaW1p dGF0aW9uIG1hZGUgYnkKPiArICogZHJpdmVyIHRvIHNhdmUgbWVtb3J5LiBDb250cm9sbGVyIG11 c3QgcHJlcGFyZSBUUkIgZm9yIGVhY2ggSVRQIGV2ZW4KPiArICogaWYgYkludGVydmFsID4gMS4g SXQncyB0aGUgcmVhc29uIHdoeSBkcml2ZXIgbmVlZHMgc28gbWFueSBUUkJzIGZvcgo+ICsgKiBp c29jaHJvbm91cyBlbmRwb2ludHMuCj4gKyAqLwo+ICsjZGVmaW5lIFRSQlNfUEVSX0lTT0NfU0VH TUVOVCAgKElTT19NQVhfSU5URVJWQUwgKiA4KQo+ICsKPiArI2RlZmluZSBHRVRfVFJCU19QRVJf U0VHTUVOVChlcF90eXBlKSAoKGVwX3R5cGUpID09IFVTQl9FTkRQT0lOVF9YRkVSX0lTT0MgPyBc Cj4gKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUUkJTX1BFUl9JU09DX1NF R01FTlQgOiBUUkJTX1BFUl9TRUdNRU5UKQo+ICsvKioKPiArICogc3RydWN0IGNkbnMzX3RyYiAt IHJlcHJlc2VudCBUcmFuc2ZlciBEZXNjcmlwdG9yIGJsb2NrLgo+ICsgKiBAYnVmZmVyOiAgICBw b2ludGVyIHRvIGJ1ZmZlciBkYXRhCj4gKyAqIEBsZW5ndGg6ICAgIGxlbmd0aCBvZiBkYXRhCj4g KyAqIEBjb250cm9sOiAgIGNvbnRyb2wgZmxhZ3MuCj4gKyAqCj4gKyAqIFRoaXMgc3RydWN0dXJl IGRlc2NyaWJlcyB0cmFuc2ZlciBibG9jayBzZXJ2aWNlZCBieSBETUEgbW9kdWxlLgo+ICsgKi8K PiArc3RydWN0IGNkbnMzX3RyYiB7Cj4gKyAgICAgICBfX2xlMzIgYnVmZmVyOwo+ICsgICAgICAg X19sZTMyIGxlbmd0aDsKPiArICAgICAgIF9fbGUzMiBjb250cm9sOwo+ICt9Owo+ICsKPiArI2Rl ZmluZSBUUkJfU0laRSAgICAgICAgICAgICAgIChzaXplb2Yoc3RydWN0IGNkbnMzX3RyYikpCj4g KyNkZWZpbmUgVFJCX1JJTkdfU0laRSAgICAgICAgICAoVFJCX1NJWkUgKiBUUkJTX1BFUl9TRUdN RU5UKQo+ICsjZGVmaW5lIFRSQl9JU09fUklOR19TSVpFICAgICAgKFRSQl9TSVpFICogVFJCU19Q RVJfSVNPQ19TRUdNRU5UKQo+ICsjZGVmaW5lIFRSQl9DVFJMX1JJTkdfU0laRSAgICAgKFRSQl9T SVpFICogMikKPiArCj4gKy8qIFRSQiBiaXQgbWFzayAqLwo+ICsjZGVmaW5lIFRSQl9UWVBFX0JJ VE1BU0sgICAgICAgR0VOTUFTSygxNSwgMTApCj4gKyNkZWZpbmUgVFJCX1RZUEUocCkgICAgICAg ICAgICAoKHApIDw8IDEwKQo+ICsjZGVmaW5lIFRSQl9GSUVMRF9UT19UWVBFKHApICAgKCgocCkg JiBUUkJfVFlQRV9CSVRNQVNLKSA+PiAxMCkKPiArCj4gKy8qIFRSQiB0eXBlIElEcyAqLwo+ICsv KiBidWxrLCBpbnRlcnJ1cHQsIGlzb2MgLCBhbmQgY29udHJvbCBkYXRhIHN0YWdlICovCj4gKyNk ZWZpbmUgVFJCX05PUk1BTCAgICAgICAgICAgICAxCj4gKy8qIFRSQiBmb3IgbGlua2luZyByaW5n IHNlZ21lbnRzICovCj4gKyNkZWZpbmUgVFJCX0xJTksgICAgICAgICAgICAgICA2Cj4gKwo+ICsv KiBDeWNsZSBiaXQgLSBpbmRpY2F0ZXMgVFJCIG93bmVyc2hpcCBieSBkcml2ZXIgb3IgaHcqLwo+ ICsjZGVmaW5lIFRSQl9DWUNMRSAgICAgICAgICAgICAgQklUKDApCj4gKy8qCj4gKyAqIFdoZW4g c2V0IHRvICcxJywgdGhlIGRldmljZSB3aWxsIHRvZ2dsZSBpdHMgaW50ZXJwcmV0YXRpb24gb2Yg dGhlIEN5Y2xlIGJpdAo+ICsgKi8KPiArI2RlZmluZSBUUkJfVE9HR0xFICAgICAgICAgICAgIEJJ VCgxKQo+ICsKPiArLyogSW50ZXJydXB0IG9uIHNob3J0IHBhY2tldCovCj4gKyNkZWZpbmUgVFJC X0lTUCAgICAgICAgICAgICAgICAgICAgICAgIEJJVCgyKQo+ICsvKlNldHRpbmcgdGhpcyBiaXQg ZW5hYmxlcyBGSUZPIERNQSBvcGVyYXRpb24gbW9kZSovCj4gKyNkZWZpbmUgVFJCX0ZJRk9fTU9E RSAgICAgICAgICBCSVQoMykKPiArLyogU2V0IFBDSWUgbm8gc25vb3AgYXR0cmlidXRlICovCj4g KyNkZWZpbmUgVFJCX0NIQUlOICAgICAgICAgICAgICBCSVQoNCkKPiArLyogSW50ZXJydXB0IG9u IGNvbXBsZXRpb24gKi8KPiArI2RlZmluZSBUUkJfSU9DICAgICAgICAgICAgICAgICAgICAgICAg QklUKDUpCj4gKwo+ICsvKiBzdHJlYW0gSUQgYml0bWFza3MuICovCj4gKyNkZWZpbmUgVFJCX1NU UkVBTV9JRChwKSAgICAgICAoKHApICYgR0VOTUFTSygzMSwgMTYpKQo+ICsKPiArLyogdHJhbnNm ZXJfbGVuIGJpdG1hc2tzLiAqLwo+ICsjZGVmaW5lIFRSQl9MRU4ocCkgICAgICAgICAgICAgKChw KSAmIEdFTk1BU0soMTYsIDApKQo+ICsKPiArLyogdHJhbnNmZXJfbGVuIGJpdG1hc2tzIC0gYml0 cyAzMToyNCAqLwo+ICsjZGVmaW5lIFRSQl9CVVJTVF9MRU4ocCkgICAgICAgKChwKSAmIEdFTk1B U0soMzEsIDI0KSkKPiArCj4gKy8qIERhdGEgYnVmZmVyIHBvaW50ZXIgYml0bWFza3MqLwo+ICsj ZGVmaW5lIFRSQl9CVUZGRVIocCkgICAgICAgICAgKChwKSAmIEdFTk1BU0soMzEsIDApKQo+ICsK PiArLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KPiArLyogRHJpdmVyIG51bWVyaWMgY29uc3RhbnRzICov Cj4gKwo+ICsvKiBTdWNoIGRlY2xhcmF0aW9uIHNob3VsZCBiZSBhZGRlZCB0byBjaDkuaCAqLwo+ ICsjZGVmaW5lIFVTQl9ERVZJQ0VfTUFYX0FERFJFU1MgICAgICAgICAxMjcKPiArCj4gKy8qIEVu ZHBvaW50IGluaXQgdmFsdWVzICovCj4gKyNkZWZpbmUgQ0ROUzNfRVBfTUFYX1BBQ0tFVF9MSU1J VCAgICAgIDEwMjQKPiArI2RlZmluZSBDRE5TM19FUF9NQVhfU1RSRUFNUyAgICAgICAgICAgMTUK PiArI2RlZmluZSBDRE5TM19FUDBfTUFYX1BBQ0tFVF9MSU1JVCAgICAgNTEyCj4gKwo+ICsvKiBB bGwgZW5kcG9pbnRzIGluY2x1ZGluZyBFUDAgKi8KPiArI2RlZmluZSBDRE5TM19FTkRQT0lOVFNf TUFYX0NPVU5UICAgICAgMzIKPiArI2RlZmluZSBDRE5TM19FUF9aTFBfQlVGX1NJWkUgICAgICAg ICAgMTAyNAo+ICsKPiArI2RlZmluZSBDRE5TM19FUF9CVUZfU0laRSAgICAgICAgICAgICAgMiAg ICAgICAvKiBLQiAqLwo+ICsjZGVmaW5lIENETlMzX0FMSUdORURfQlVGX1NJWkUgICAgICAgICAx NjM4NCAgIC8qIEJ5dGVzICovCj4gKyNkZWZpbmUgQ0ROUzNfTUFYX05VTV9ERVNDTUlTU19CVUYg ICAgIDMyCj4gKyNkZWZpbmUgQ0ROUzNfREVTQ01JU19CVUZfU0laRSAgICAgICAgIDIwNDggICAg LyogQnl0ZXMgKi8KPiArLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KPiArLyogVXNlZCBzdHJ1Y3RzICov Cj4gKwo+ICtzdHJ1Y3QgY2RuczNfZGV2aWNlOwo+ICsKPiArLyoqCj4gKyAqIHN0cnVjdCBjZG5z M19lbmRwb2ludCAtIGV4dGVuZGVkIGRldmljZSBzaWRlIHJlcHJlc2VudGF0aW9uIG9mIFVTQiBl bmRwb2ludC4KPiArICogQGVuZHBvaW50OiB1c2IgZW5kcG9pbnQKPiArICogQHBlbmRpbmdfcmVx X2xpc3Q6IGxpc3Qgb2YgcmVxdWVzdHMgcXVldWluZyBvbiB0cmFuc2ZlciByaW5nLgo+ICsgKiBA ZGVmZXJyZWRfcmVxX2xpc3Q6IGxpc3Qgb2YgcmVxdWVzdHMgd2FpdGluZyBmb3IgcXVldWluZyBv biB0cmFuc2ZlciByaW5nLgo+ICsgKiBAdHJiX3Bvb2w6IHRyYW5zZmVyIHJpbmcgLSBhcnJheSBv ZiB0cmFuc2FjdGlvbiBidWZmZXJzCj4gKyAqIEB0cmJfcG9vbF9kbWE6IGRtYSBhZGRyZXNzIG9m IHRyYW5zZmVyIHJpbmcKPiArICogQGNkbnMzX2RldjogZGV2aWNlIGFzc29jaWF0ZWQgd2l0aCB0 aGlzIGVuZHBvaW50Cj4gKyAqIEBuYW1lOiBhIGh1bWFuIHJlYWRhYmxlIG5hbWUgZS5nLiBlcDFv dXQKPiArICogQGZsYWdzOiBzcGVjaWZ5IHRoZSBjdXJyZW50IHN0YXRlIG9mIGVuZHBvaW50Cj4g KyAqIEBkZXNjbWlzX3JlcTogaW50ZXJuYWwgdHJhbnNmZXIgb2JqZWN0IHVzZWQgZm9yIGdldHRp bmcgZGF0YSBmcm9tIG9uLWNoaXAKPiArICogICAgIGJ1ZmZlci4gSXQgY2FuIGhhcHBlbiBvbmx5 IGlmIGZ1bmN0aW9uIGRyaXZlciBkb2Vzbid0IHNlbmQgdXNiX3JlcXVlc3QKPiArICogICAgIG9i amVjdCBvbiB0aW1lLgo+ICsgKiBAYWxpZ25lZF9idWZmOiBhbGlnbmVkIHRvIDggYnl0ZXMgZGF0 YSBidWZmZXIuIEJ1ZmZlciBhZGRyZXNzIHVzZWQgaW4KPiArICogICAgIFRSQiBzaGFsbCBiZSBh bGlnbmVkIHRvIDguCj4gKyAqIEBhbGlnbmVkX2RtYV9hZGRyOiBkbWEgYWRkcmVzcyBvZiBhbGln bmVkX2J1ZmYKPiArICogQGRpcjogZW5kcG9pbnQgZGlyZWN0aW9uCj4gKyAqIEBudW06IGVuZHBv aW50IG51bWJlciAoMSAtIDE1KQo+ICsgKiBAdHlwZTogc2V0IHRvIGJtQXR0cmlidXRlcyAmIFVT Ql9FTkRQT0lOVF9YRkVSVFlQRV9NQVNLCj4gKyAqIEBpbnRlcnZhbDogaW50ZXJ2YWwgYmV0d2Vl biBwYWNrZXRzIHVzZWQgZm9yIElTT0MgZW5kcG9pbnQuCj4gKyAqIEBmcmVlX3RyYnM6IG51bWJl ciBvZiBmcmVlIFRSQnMgaW4gdHJhbnNmZXIgcmluZwo+ICsgKiBAbnVtX3RyYnM6IG51bWJlciBv ZiBhbGwgVFJCcyBpbiB0cmFuc2ZlciByaW5nCj4gKyAqIEBwY3M6IHByb2R1Y2VyIGN5Y2xlIHN0 YXRlCj4gKyAqIEBjY3M6IGNvbnN1bWVyIGN5Y2xlIHN0YXRlCj4gKyAqIEBlbnF1ZXVlOiBlbnF1 ZXVlIGluZGV4IGluIHRyYW5zZmVyIHJpbmcKPiArICogQGRlcXVldWU6IGRlcXVldWUgaW5kZXgg aW4gdHJhbnNmZXIgcmluZwo+ICsgKi8KPiArc3RydWN0IGNkbnMzX2VuZHBvaW50IHsKPiArICAg ICAgIHN0cnVjdCB1c2JfZXAgICAgICAgICAgIGVuZHBvaW50Owo+ICsgICAgICAgc3RydWN0IGxp c3RfaGVhZCAgICAgICAgcGVuZGluZ19yZXFfbGlzdDsKPiArICAgICAgIHN0cnVjdCBsaXN0X2hl YWQgICAgICAgIGRlZmVycmVkX3JlcV9saXN0Owo+ICsKPiArICAgICAgIHN0cnVjdCBjZG5zM190 cmIgICAgICAgICp0cmJfcG9vbDsKPiArICAgICAgIGRtYV9hZGRyX3QgICAgICAgICAgICAgIHRy Yl9wb29sX2RtYTsKPiArCj4gKyAgICAgICBzdHJ1Y3QgY2RuczNfZGV2aWNlICAgICAqY2RuczNf ZGV2Owo+ICsgICAgICAgY2hhciAgICAgICAgICAgICAgICAgICAgbmFtZVsyMF07Cj4gKwo+ICsj ZGVmaW5lIEVQX0VOQUJMRUQgICAgICAgICAgICAgQklUKDApCj4gKyNkZWZpbmUgRVBfU1RBTEwg ICAgICAgICAgICAgICBCSVQoMSkKPiArI2RlZmluZSBFUF9XRURHRSAgICAgICAgICAgICAgIEJJ VCgyKQo+ICsjZGVmaW5lIEVQX1RSQU5TRkVSX1NUQVJURUQgICAgQklUKDMpCj4gKyNkZWZpbmUg RVBfVVBEQVRFX0VQX1RSQkFERFIgICBCSVQoNCkKPiArI2RlZmluZSBFUF9QRU5ESU5HX1JFUVVF U1QgICAgIEJJVCg1KQo+ICsjZGVmaW5lIEVQX1JJTkdfRlVMTCAgICAgICAgICAgQklUKDYpCj4g KyNkZWZpbmUgRVBfQ0xBSU1FRCAgICAgICAgICAgICBCSVQoNykKPiArCj4gKyAgICAgICB1MzIg ICAgICAgICAgICAgICAgICAgICBmbGFnczsKPiArCj4gKyAgICAgICBzdHJ1Y3QgY2RuczNfcmVx dWVzdCAgICAqZGVzY21pc19yZXE7Cj4gKwo+ICsgICAgICAgdm9pZCAgICAgICAgICAgICAgICAg ICAgKmFsaWduZWRfYnVmZjsKPiArICAgICAgIGRtYV9hZGRyX3QgICAgICAgICAgICAgIGFsaWdu ZWRfZG1hX2FkZHI7Cj4gKyAgICAgICB1OCAgICAgICAgICAgICAgICAgICAgICBkaXI7Cj4gKyAg ICAgICB1OCAgICAgICAgICAgICAgICAgICAgICBudW07Cj4gKyAgICAgICB1OCAgICAgICAgICAg ICAgICAgICAgICB0eXBlOwo+ICsgICAgICAgaW50ICAgICAgICAgICAgICAgICAgICAgaW50ZXJ2 YWw7Cj4gKwo+ICsgICAgICAgaW50ICAgICAgICAgICAgICAgICAgICAgZnJlZV90cmJzOwo+ICsg ICAgICAgaW50ICAgICAgICAgICAgICAgICAgICAgbnVtX3RyYnM7Cj4gKyAgICAgICB1OCAgICAg ICAgICAgICAgICAgICAgICBwY3M7Cj4gKyAgICAgICB1OCAgICAgICAgICAgICAgICAgICAgICBj Y3M7Cj4gKyAgICAgICBpbnQgICAgICAgICAgICAgICAgICAgICBlbnF1ZXVlOwo+ICsgICAgICAg aW50ICAgICAgICAgICAgICAgICAgICAgZGVxdWV1ZTsKPiArCj4gKyAgICAgICB1bnNpZ25lZCBp bnQgICAgICAgICAgICB3YTFfc2V0OjE7Cj4gKyAgICAgICBzdHJ1Y3QgY2RuczNfdHJiICAgICAg ICAqd2ExX3RyYjsKPiArICAgICAgIHVuc2lnbmVkIGludCAgICAgICAgICAgIHdhMV9jeWNsZV9i aXQ6MTsKPiArfTsKPiArCj4gKy8qKgo+ICsgKiBzdHJ1Y3QgY2RuczNfcmVxdWVzdCAtIGV4dGVu ZGVkIGRldmljZSBzaWRlIHJlcHJlc2VudGF0aW9uIG9mIHVzYl9yZXF1ZXN0Cj4gKyAqICAgICAg ICAgICAgICAgICAgICAgICAgb2JqZWN0IC4KPiArICogQHJlcXVlc3Q6IGdlbmVyaWMgdXNiX3Jl cXVlc3Qgb2JqZWN0IGRlc2NyaWJpbmcgc2luZ2xlIEkvTyByZXF1ZXN0Lgo+ICsgKiBAcHJpdl9l cDogZXh0ZW5kZWQgcmVwcmVzZW50YXRpb24gb2YgdXNiX2VwIG9iamVjdAo+ICsgKiBAdHJiOiB0 aGUgZmlyc3QgVFJCIGFzc29jaWF0aW9uIHdpdGggdGhpcyByZXF1ZXN0Cj4gKyAqIEBzdGFydF90 cmI6IG51bWJlciBvZiB0aGUgZmlyc3QgVFJCIGluIHRyYW5zZmVyIHJpbmcKPiArICogQGVuZF90 cmI6IG51bWJlciBvZiB0aGUgbGFzdCBUUkIgaW4gdHJhbnNmZXIgcmluZwo+ICsgKiBAZmxhZ3M6 IGZsYWcgc3BlY2lmeWluZyBzcGVjaWFsIHVzYWdlIG9mIHJlcXVlc3QKPiArICovCj4gK3N0cnVj dCBjZG5zM19yZXF1ZXN0IHsKPiArICAgICAgIHN0cnVjdCB1c2JfcmVxdWVzdCAgICAgIHJlcXVl c3Q7Cj4gKyAgICAgICBzdHJ1Y3QgY2RuczNfZW5kcG9pbnQgICAqcHJpdl9lcDsKPiArICAgICAg IHN0cnVjdCBjZG5zM190cmIgICAgICAgICp0cmI7Cj4gKyAgICAgICBpbnQgICAgICAgICAgICAg ICAgICAgICBzdGFydF90cmI7Cj4gKyAgICAgICBpbnQgICAgICAgICAgICAgICAgICAgICBlbmRf dHJiOwo+ICsjZGVmaW5lIFJFUVVFU1RfUEVORElORyAgICAgICAgICAgICAgICBCSVQoMCkKPiAr I2RlZmluZSBSRVFVRVNUX0lOVEVSTkFMICAgICAgIEJJVCgxKQo+ICsjZGVmaW5lIFJFUVVFU1Rf SU5URVJOQUxfQ0ggICAgQklUKDIpCj4gKyNkZWZpbmUgUkVRVUVTVF9aTFAgICAgICAgICAgICBC SVQoMykKPiArICAgICAgIHUzMiAgICAgICAgICAgICAgICAgICAgIGZsYWdzOwo+ICt9Owo+ICsK PiArI2RlZmluZSB0b19jZG5zM19yZXF1ZXN0KHIpIChjb250YWluZXJfb2Yociwgc3RydWN0IGNk bnMzX3JlcXVlc3QsIHJlcXVlc3QpKQo+ICsKPiArLypTdGFnZXMgdXNlZCBkdXJpbmcgZW51bWVy YXRpb24gcHJvY2Vzcy4qLwo+ICsjZGVmaW5lIENETlMzX1NFVFVQX1NUQUdFICAgICAgICAgICAg ICAweDAKPiArI2RlZmluZSBDRE5TM19EQVRBX1NUQUdFICAgICAgICAgICAgICAgMHgxCj4gKyNk ZWZpbmUgQ0ROUzNfU1RBVFVTX1NUQUdFICAgICAgICAgICAgIDB4Mgo+ICsKPiArLyoqCj4gKyAq IHN0cnVjdCBjZG5zM19kZXZpY2UgLSByZXByZXNlbnQgVVNCIGRldmljZS4KPiArICogQGRldjog cG9pbnRlciB0byBkZXZpY2Ugc3RydWN0dXJlIGFzc29jaWF0ZWQgd2hpdCB0aGlzIGNvbnRyb2xs ZXIKPiArICogQHN5c2RldjogcG9pbnRlciB0byB0aGUgRE1BIGNhcGFibGUgZGV2aWNlCj4gKyAq IEBnYWRnZXQ6IGRldmljZSBzaWRlIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBwZXJpcGhlcmFsIGNv bnRyb2xsZXIKPiArICogQGdhZGdldF9kcml2ZXI6IHBvaW50ZXIgdG8gdGhlIGdhZGdldCBkcml2 ZXIKPiArICogQGRldl92ZXI6IGRldmljZSBjb250cm9sbGVyIHZlcnNpb24uCj4gKyAqIEBsb2Nr OiBmb3Igc3luY2hyb25pemluZwo+ICsgKiBAcmVnczogYmFzZSBhZGRyZXNzIGZvciBkZXZpY2Ug c2lkZSByZWdpc3RlcnMKPiArICogQHNldHVwX2J1ZjogdXNlZCB3aGlsZSBwcm9jZXNzaW5nIHVz YiBjb250cm9sIHJlcXVlc3RzCj4gKyAqIEBzZXR1cF9kbWE6IGRtYSBhZGRyZXNzIGZvciBzZXR1 cF9idWYKPiArICogQHpscF9idWYgLSB6bHAgYnVmZmVyCj4gKyAqIEBlcDBfc3RhZ2U6IGVwMCBz dGFnZSBkdXJpbmcgZW51bWVyYXRpb24gcHJvY2Vzcy4KPiArICogQGVwMF9kYXRhX2RpcjogZGly ZWN0aW9uIGZvciBjb250cm9sIHRyYW5zZmVyCj4gKyAqIEBlcHM6IGFycmF5IG9mIHBvaW50ZXJz IHRvIGFsbCBlbmRwb2ludHMgd2l0aCBleGNsdXNpb24gZXAwCj4gKyAqIEBzZWxlY3RlZF9lcDog YWN0dWFsbHkgc2VsZWN0ZWQgZW5kcG9pbnQuIEl0J3MgdXNlZCBvbmx5IHRvIGltcHJvdmUKPiAr ICogICAgICAgICAgICAgICBwZXJmb3JtYW5jZS4KPiArICogQGlzb2NoX2RlbGF5OiB2YWx1ZSBm cm9tIFNldCBJc29jaCBEZWxheSByZXF1ZXN0LiBPbmx5IHZhbGlkIG9uIFNTL1NTUC4KPiArICog QHUxX2FsbG93ZWQ6IGFsbG93IGRldmljZSB0cmFuc2l0aW9uIHRvIHUxIHN0YXRlCj4gKyAqIEB1 Ml9hbGxvd2VkOiBhbGxvdyBkZXZpY2UgdHJhbnNpdGlvbiB0byB1MiBzdGF0ZQo+ICsgKiBAaXNf c2VsZnBvd2VyZWQ6IGRldmljZSBpcyBzZWxmIHBvd2VyZWQKPiArICogQHNldHVwX3BlbmRpbmc6 IHNldHVwIHBhY2tldCBpcyBwcm9jZXNzaW5nIGJ5IGdhZGdldCBkcml2ZXIKPiArICogQGh3X2Nv bmZpZ3VyZWRfZmxhZzogaGFyZHdhcmUgZW5kcG9pbnQgY29uZmlndXJhdGlvbiB3YXMgc2V0Lgo+ ICsgKiBAd2FrZV91cF9mbGFnOiBhbGxvdyBkZXZpY2UgdG8gcmVtb3RlIHVwIHRoZSBob3N0Cj4g KyAqIEBzdGF0dXNfY29tcGxldGlvbl9ub19jYWxsOiBpbmRpY2F0ZSB0aGF0IGRyaXZlciBpcyB3 YWl0aW5nIGZvciBzdGF0dXMgcwo+ICsgKiAgICAgc3RhZ2UgY29tcGxldGlvbi4gSXQncyB1c2Vk IGluIGRlZmVycmVkIFNFVF9DT05GSUdVUkFUSU9OIHJlcXVlc3QuCj4gKyAqIEBvbmNoaXBfbWVt X2FsbG9jYXRlZF9zaXplOiBhY3R1YWwgc2l6ZSBvZiBvbi1jaGlwIG1lbW9yeSBhc3NpZ25lZAo+ ICsgKiAgICAgdG8gZW5kcG9pbnRzCj4gKyAqIEBwZW5kaW5nX3N0YXR1c193cTogd29ya3F1ZXVl IGhhbmRsaW5nIHN0YXR1cyBzdGFnZSBmb3IgZGVmZXJyZWQgcmVxdWVzdHMuCj4gKyAqIEBzaGFk b3dfZXBfZW46IGhvbGQgaW5mb3JtYXRpb24gYWJvdXQgZW5kcG9pbnRzIHRoYXQgd2lsbCBiZSBl bmFibGVkCj4gKyAqICAgICBpbiBzb2Z0IGlycS4KPiArICogQHBlbmRpbmdfc3RhdHVzX3JlcXVl c3Q6IHJlcXVlc3QgZm9yIHdoaWNoIHN0YXR1cyBzdGFnZSB3YXMgZGVmZXJyZWQKPiArICovCj4g K3N0cnVjdCBjZG5zM19kZXZpY2Ugewo+ICsgICAgICAgc3RydWN0IGRldmljZSAgICAgICAgICAg ICAgICAgICAqZGV2Owo+ICsgICAgICAgc3RydWN0IGRldmljZSAgICAgICAgICAgICAgICAgICAq c3lzZGV2Owo+ICsKPiArICAgICAgIHN0cnVjdCB1c2JfZ2FkZ2V0ICAgICAgICAgICAgICAgZ2Fk Z2V0Owo+ICsgICAgICAgc3RydWN0IHVzYl9nYWRnZXRfZHJpdmVyICAgICAgICAqZ2FkZ2V0X2Ry aXZlcjsKPiArCj4gKyNkZWZpbmUgQ0ROU19SRVZJU0lPTl9WMCAgICAgICAgICAgICAgIDB4MDAw MjQ1MDEKPiArI2RlZmluZSBDRE5TX1JFVklTSU9OX1YxICAgICAgICAgICAgICAgMHgwMDAyNDUw OQo+ICsgICAgICAgdTMyICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZXZfdmVyOwo+ICsK PiArICAgICAgIC8qIGdlbmVyaWMgc3Bpbi1sb2NrIGZvciBkcml2ZXJzICovCj4gKyAgICAgICBz cGlubG9ja190ICAgICAgICAgICAgICAgICAgICAgIGxvY2s7Cj4gKwo+ICsgICAgICAgc3RydWN0 IGNkbnMzX3VzYl9yZWdzICAgICAgICAgICBfX2lvbWVtICpyZWdzOwo+ICsKPiArICAgICAgIHN0 cnVjdCB1c2JfY3RybHJlcXVlc3QgICAgICAgICAgKnNldHVwX2J1ZjsKPiArICAgICAgIGRtYV9h ZGRyX3QgICAgICAgICAgICAgICAgICAgICAgc2V0dXBfZG1hOwo+ICsgICAgICAgdm9pZCAgICAg ICAgICAgICAgICAgICAgICAgICAgICAqemxwX2J1ZjsKPiArCj4gKyAgICAgICB1OCAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgIGVwMF9zdGFnZTsKPiArICAgICAgIGludCAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgZXAwX2RhdGFfZGlyOwo+ICsKPiArICAgICAgIHN0cnVjdCBjZG5z M19lbmRwb2ludCAgICAgICAgICAgKmVwc1tDRE5TM19FTkRQT0lOVFNfTUFYX0NPVU5UXTsKPiAr Cj4gKyAgICAgICB1MzIgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGVjdGVkX2VwOwo+ ICsgICAgICAgdTE2ICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpc29jaF9kZWxheTsKPiAr Cj4gKyAgICAgICB1bnNpZ25lZCAgICAgICAgICAgICAgICAgICAgICAgIHUxX2FsbG93ZWQ6MTsK PiArICAgICAgIHVuc2lnbmVkICAgICAgICAgICAgICAgICAgICAgICAgdTJfYWxsb3dlZDoxOwo+ ICsgICAgICAgdW5zaWduZWQgICAgICAgICAgICAgICAgICAgICAgICBpc19zZWxmcG93ZXJlZDox Owo+ICsgICAgICAgdW5zaWduZWQgICAgICAgICAgICAgICAgICAgICAgICBzZXR1cF9wZW5kaW5n OjE7Cj4gKyAgICAgICBpbnQgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGh3X2NvbmZpZ3Vy ZWRfZmxhZzoxOwo+ICsgICAgICAgaW50ICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3YWtl X3VwX2ZsYWc6MTsKPiArICAgICAgIHVuc2lnbmVkICAgICAgICAgICAgICAgICAgICAgICAgc3Rh dHVzX2NvbXBsZXRpb25fbm9fY2FsbDoxOwo+ICsKPiArICAgICAgIHN0cnVjdCB3b3JrX3N0cnVj dCAgICAgICAgICAgICAgcGVuZGluZ19zdGF0dXNfd3E7Cj4gKyAgICAgICBzdHJ1Y3QgdXNiX3Jl cXVlc3QgICAgICAgICAgICAgICpwZW5kaW5nX3N0YXR1c19yZXF1ZXN0Owo+ICsgICAgICAgdTMy ICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaGFkb3dfZXBfZW47Cj4gKyAgICAgICAvKmlu IEtCICovCj4gKyAgICAgICBpbnQgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9uY2hpcF9t ZW1fYWxsb2NhdGVkX3NpemU7Cj4gK307Cj4gKwo+ICtpbnQgY2RuczNfaGFuZHNoYWtlKHZvaWQg X19pb21lbSAqcHRyLCB1MzIgbWFzaywgdTMyIGRvbmUsIGludCB1c2VjKTsKPiArdm9pZCBjZG5z M19zZXRfcmVnaXN0ZXJfYml0KHZvaWQgX19pb21lbSAqcHRyLCB1MzIgbWFzayk7Cj4gK2RtYV9h ZGRyX3QgY2RuczNfdHJiX3ZpcnRfdG9fZG1hKHN0cnVjdCBjZG5zM19lbmRwb2ludCAqcHJpdl9l cCwKPiArICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJ1Y3QgY2RuczNfdHJiICp0 cmIpOwo+ICtlbnVtIHVzYl9kZXZpY2Vfc3BlZWQgY2RuczNfZ2V0X3NwZWVkKHN0cnVjdCBjZG5z M19kZXZpY2UgKnByaXZfZGV2KTsKPiArdm9pZCBjZG5zM19wZW5kaW5nX3NldHVwX3N0YXR1c19o YW5kbGVyKHN0cnVjdCB3b3JrX3N0cnVjdCAqd29yayk7Cj4gK3ZvaWQgY2RuczNfaHdfcmVzZXRf ZXBzX2NvbmZpZyhzdHJ1Y3QgY2RuczNfZGV2aWNlICpwcml2X2Rldik7Cj4gK3ZvaWQgY2RuczNf c2V0X2h3X2NvbmZpZ3VyYXRpb24oc3RydWN0IGNkbnMzX2RldmljZSAqcHJpdl9kZXYpOwo+ICt2 b2lkIGNkbnMzX3NlbGVjdF9lcChzdHJ1Y3QgY2RuczNfZGV2aWNlICpwcml2X2RldiwgdTMyIGVw KTsKPiArdm9pZCBjZG5zM19hbGxvd19lbmFibGVfbDEoc3RydWN0IGNkbnMzX2RldmljZSAqcHJp dl9kZXYsIGludCBlbmFibGUpOwo+ICtzdHJ1Y3QgdXNiX3JlcXVlc3QgKmNkbnMzX25leHRfcmVx dWVzdChzdHJ1Y3QgbGlzdF9oZWFkICpsaXN0KTsKPiAraW50IGNkbnMzX2VwX3J1bl90cmFuc2Zl cihzdHJ1Y3QgY2RuczNfZW5kcG9pbnQgKnByaXZfZXAsCj4gKyAgICAgICAgICAgICAgICAgICAg ICAgICBzdHJ1Y3QgdXNiX3JlcXVlc3QgKnJlcXVlc3QpOwo+ICt2b2lkIGNkbnMzX3JlYXJtX3Ry YW5zZmVyKHN0cnVjdCBjZG5zM19lbmRwb2ludCAqcHJpdl9lcCwgdTggcmVhcm0pOwo+ICtpbnQg Y2RuczNfYWxsb2NhdGVfdHJiX3Bvb2woc3RydWN0IGNkbnMzX2VuZHBvaW50ICpwcml2X2VwKTsK PiArdTggY2RuczNfZXBfYWRkcl90b19pbmRleCh1OCBlcF9hZGRyKTsKPiAraW50IGNkbnMzX2dh ZGdldF9lcF9zZXRfd2VkZ2Uoc3RydWN0IHVzYl9lcCAqZXApOwo+ICtpbnQgY2RuczNfZ2FkZ2V0 X2VwX3NldF9oYWx0KHN0cnVjdCB1c2JfZXAgKmVwLCBpbnQgdmFsdWUpOwo+ICtzdHJ1Y3QgdXNi X3JlcXVlc3QgKmNkbnMzX2dhZGdldF9lcF9hbGxvY19yZXF1ZXN0KHN0cnVjdCB1c2JfZXAgKmVw LAo+ICsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2Zw X3QgZ2ZwX2ZsYWdzKTsKPiArdm9pZCBjZG5zM19nYWRnZXRfZXBfZnJlZV9yZXF1ZXN0KHN0cnVj dCB1c2JfZXAgKmVwLAo+ICsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJ1Y3Qg dXNiX3JlcXVlc3QgKnJlcXVlc3QpOwo+ICtpbnQgY2RuczNfZ2FkZ2V0X2VwX2RlcXVldWUoc3Ry dWN0IHVzYl9lcCAqZXAsIHN0cnVjdCB1c2JfcmVxdWVzdCAqcmVxdWVzdCk7Cj4gK3ZvaWQgY2Ru czNfZ2FkZ2V0X2dpdmViYWNrKHN0cnVjdCBjZG5zM19lbmRwb2ludCAqcHJpdl9lcCwKPiArICAg ICAgICAgICAgICAgICAgICAgICAgICBzdHJ1Y3QgY2RuczNfcmVxdWVzdCAqcHJpdl9yZXEsCj4g KyAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IHN0YXR1cyk7Cj4gKwo+ICtpbnQgY2RuczNf aW5pdF9lcDAoc3RydWN0IGNkbnMzX2RldmljZSAqcHJpdl9kZXYsCj4gKyAgICAgICAgICAgICAg ICAgIHN0cnVjdCBjZG5zM19lbmRwb2ludCAqcHJpdl9lcCk7Cj4gK3ZvaWQgY2RuczNfZXAwX2Nv bmZpZyhzdHJ1Y3QgY2RuczNfZGV2aWNlICpwcml2X2Rldik7Cj4gK3ZvaWQgY2RuczNfZXBfY29u ZmlnKHN0cnVjdCBjZG5zM19lbmRwb2ludCAqcHJpdl9lcCk7Cj4gK3ZvaWQgY2RuczNfY2hlY2tf ZXAwX2ludGVycnVwdF9wcm9jZWVkKHN0cnVjdCBjZG5zM19kZXZpY2UgKnByaXZfZGV2LCBpbnQg ZGlyKTsKPiArCj4gKyNlbmRpZiAvKiBfX0xJTlVYX0NETlMzX0dBREdFVCAqLwo+IGRpZmYgLS1n aXQgYS9kcml2ZXJzL3VzYi9jZG5zMy9ob3N0LWV4cG9ydC5oIGIvZHJpdmVycy91c2IvY2RuczMv aG9zdC1leHBvcnQuaAo+IG5ldyBmaWxlIG1vZGUgMTAwNjQ0Cj4gaW5kZXggMDAwMDAwMDAwMDAw Li5iNDk4YTE3MGI3ZTgKPiAtLS0gL2Rldi9udWxsCj4gKysrIGIvZHJpdmVycy91c2IvY2RuczMv aG9zdC1leHBvcnQuaAo+IEBAIC0wLDAgKzEsMjggQEAKPiArLyogU1BEWC1MaWNlbnNlLUlkZW50 aWZpZXI6IEdQTC0yLjAgKi8KPiArLyoKPiArICogQ2FkZW5jZSBVU0JTUyBEUkQgRHJpdmVyIC0g SG9zdCBFeHBvcnQgQVBJcwo+ICsgKgo+ICsgKiBDb3B5cmlnaHQgKEMpIDIwMTctMjAxOCBOWFAK PiArICoKPiArICogQXV0aG9yczogUGV0ZXIgQ2hlbiA8cGV0ZXIuY2hlbkBueHAuY29tPgo+ICsg Ki8KPiArI2lmbmRlZiBfX0xJTlVYX0NETlMzX0hPU1RfRVhQT1JUCj4gKyNkZWZpbmUgX19MSU5V WF9DRE5TM19IT1NUX0VYUE9SVAo+ICsKPiArI2lmZGVmIENPTkZJR19VU0JfQ0ROUzNfSE9TVAo+ ICsKPiAraW50IGNkbnMzX2hvc3RfaW5pdChzdHJ1Y3QgY2RuczMgKmNkbnMpOwo+ICt2b2lkIGNk bnMzX2hvc3RfZXhpdChzdHJ1Y3QgY2RuczMgKmNkbnMpOwo+ICsKPiArI2Vsc2UKPiArCj4gK3N0 YXRpYyBpbmxpbmUgaW50IGNkbnMzX2hvc3RfaW5pdChzdHJ1Y3QgY2RuczMgKmNkbnMpCj4gK3sK PiArICAgICAgIHJldHVybiAtRU5YSU87Cj4gK30KPiArCj4gK3N0YXRpYyBpbmxpbmUgdm9pZCBj ZG5zM19ob3N0X2V4aXQoc3RydWN0IGNkbnMzICpjZG5zKSB7IH0KPiArCj4gKyNlbmRpZiAvKiBD T05GSUdfVVNCX0NETlMzX0hPU1QgKi8KPiArCj4gKyNlbmRpZiAvKiBfX0xJTlVYX0NETlMzX0hP U1RfRVhQT1JUICovCj4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvdXNiL2NkbnMzL2hvc3QuYyBiL2Ry aXZlcnMvdXNiL2NkbnMzL2hvc3QuYwo+IG5ldyBmaWxlIG1vZGUgMTAwNjQ0Cj4gaW5kZXggMDAw MDAwMDAwMDAwLi5iNDNiMDIzNmE4ODUKPiAtLS0gL2Rldi9udWxsCj4gKysrIGIvZHJpdmVycy91 c2IvY2RuczMvaG9zdC5jCj4gQEAgLTAsMCArMSw3MiBAQAo+ICsvLyBTUERYLUxpY2Vuc2UtSWRl bnRpZmllcjogR1BMLTIuMAo+ICsvKgo+ICsgKiBDYWRlbmNlIFVTQlNTIERSRCBEcml2ZXIgLSBo b3N0IHNpZGUKPiArICoKPiArICogQ29weXJpZ2h0IChDKSAyMDE4IENhZGVuY2UgRGVzaWduIFN5 c3RlbXMuCj4gKyAqIENvcHlyaWdodCAoQykgMjAxNy0yMDE4IE5YUAo+ICsgKgo+ICsgKiBBdXRo b3JzOiBQZXRlciBDaGVuIDxwZXRlci5jaGVuQG54cC5jb20+Cj4gKyAqICAgICAgICAgUGF3ZWwg TGFzemN6YWsgPHBhd2VsbEBjYWRlbmNlLmNvbT4KPiArICovCj4gKwo+ICsjaW5jbHVkZSA8bGlu dXgvcGxhdGZvcm1fZGV2aWNlLmg+Cj4gKyNpbmNsdWRlICJjb3JlLmgiCj4gKwo+ICtzdGF0aWMg aW50IF9fY2RuczNfaG9zdF9pbml0KHN0cnVjdCBjZG5zMyAqY2RucykKPiArewo+ICsgICAgICAg c3RydWN0IHBsYXRmb3JtX2RldmljZSAqeGhjaTsKPiArICAgICAgIGludCByZXQ7Cj4gKwo+ICsg ICAgICAgeGhjaSA9IHBsYXRmb3JtX2RldmljZV9hbGxvYygieGhjaS1oY2QiLCBQTEFURk9STV9E RVZJRF9BVVRPKTsKPiArICAgICAgIGlmICgheGhjaSkgewo+ICsgICAgICAgICAgICAgICBkZXZf ZXJyKGNkbnMtPmRldiwgImNvdWxkbid0IGFsbG9jYXRlIHhIQ0kgZGV2aWNlXG4iKTsKPiArICAg ICAgICAgICAgICAgcmV0dXJuIC1FTk9NRU07Cj4gKyAgICAgICB9Cj4gKwo+ICsgICAgICAgeGhj aS0+ZGV2LnBhcmVudCA9IGNkbnMtPmRldjsKPiArICAgICAgIGNkbnMtPmhvc3RfZGV2ID0geGhj aTsKPiArCj4gKyAgICAgICByZXQgPSBwbGF0Zm9ybV9kZXZpY2VfYWRkX3Jlc291cmNlcyh4aGNp LCBjZG5zLT54aGNpX3JlcywKPiArICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgIENETlMzX1hIQ0lfUkVTT1VSQ0VTX05VTSk7Cj4gKyAgICAgICBpZiAocmV0KSB7Cj4g KyAgICAgICAgICAgICAgIGRldl9lcnIoY2Rucy0+ZGV2LCAiY291bGRuJ3QgYWRkIHJlc291cmNl cyB0byB4SENJIGRldmljZVxuIik7Cj4gKyAgICAgICAgICAgICAgIGdvdG8gZXJyMTsKPiArICAg ICAgIH0KPiArCj4gKyAgICAgICByZXQgPSBwbGF0Zm9ybV9kZXZpY2VfYWRkKHhoY2kpOwo+ICsg ICAgICAgaWYgKHJldCkgewo+ICsgICAgICAgICAgICAgICBkZXZfZXJyKGNkbnMtPmRldiwgImZh aWxlZCB0byByZWdpc3RlciB4SENJIGRldmljZVxuIik7Cj4gKyAgICAgICAgICAgICAgIGdvdG8g ZXJyMTsKPiArICAgICAgIH0KPiArCj4gKyAgICAgICByZXR1cm4gMDsKPiArZXJyMToKPiArICAg ICAgIHBsYXRmb3JtX2RldmljZV9wdXQoeGhjaSk7Cj4gKyAgICAgICByZXR1cm4gcmV0Owo+ICt9 Cj4gKwo+ICtzdGF0aWMgdm9pZCBjZG5zM19ob3N0X2V4aXQoc3RydWN0IGNkbnMzICpjZG5zKQo+ ICt7Cj4gKyAgICAgICBwbGF0Zm9ybV9kZXZpY2VfdW5yZWdpc3RlcihjZG5zLT5ob3N0X2Rldik7 Cj4gKyAgICAgICBjZG5zLT5ob3N0X2RldiA9IE5VTEw7Cj4gK30KPiArCj4gK2ludCBjZG5zM19o b3N0X2luaXQoc3RydWN0IGNkbnMzICpjZG5zKQo+ICt7Cj4gKyAgICAgICBzdHJ1Y3QgY2RuczNf cm9sZV9kcml2ZXIgKnJkcnY7Cj4gKwo+ICsgICAgICAgcmRydiA9IGRldm1fa3phbGxvYyhjZG5z LT5kZXYsIHNpemVvZigqcmRydiksIEdGUF9LRVJORUwpOwo+ICsgICAgICAgaWYgKCFyZHJ2KQo+ ICsgICAgICAgICAgICAgICByZXR1cm4gLUVOT01FTTsKPiArCj4gKyAgICAgICByZHJ2LT5zdGFy dCAgICAgPSBfX2NkbnMzX2hvc3RfaW5pdDsKPiArICAgICAgIHJkcnYtPnN0b3AgICAgICA9IGNk bnMzX2hvc3RfZXhpdDsKPiArICAgICAgIHJkcnYtPnN0YXRlICAgICA9IENETlMzX1JPTEVfU1RB VEVfSU5BQ1RJVkU7Cj4gKyAgICAgICByZHJ2LT5zdXNwZW5kICAgPSBOVUxMOwo+ICsgICAgICAg cmRydi0+cmVzdW1lICAgID0gTlVMTDsKPiArICAgICAgIHJkcnYtPm5hbWUgICAgICA9ICJob3N0 IjsKPiArCj4gKyAgICAgICBjZG5zLT5yb2xlc1tDRE5TM19ST0xFX0hPU1RdID0gcmRydjsKPiAr Cj4gKyAgICAgICByZXR1cm4gMDsKPiArfQo+IGRpZmYgLS1naXQgYS9kcml2ZXJzL3VzYi9jZG5z My90cmFjZS5jIGIvZHJpdmVycy91c2IvY2RuczMvdHJhY2UuYwo+IG5ldyBmaWxlIG1vZGUgMTAw NjQ0Cj4gaW5kZXggMDAwMDAwMDAwMDAwLi45NDMxZWI4NmQ0ZmYKPiAtLS0gL2Rldi9udWxsCj4g KysrIGIvZHJpdmVycy91c2IvY2RuczMvdHJhY2UuYwo+IEBAIC0wLDAgKzEsMjMgQEAKPiArLy8g U1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEdQTC0yLjAKPiArLyoKPiArICogVVNCU1MgZGV2aWNl IGNvbnRyb2xsZXIgZHJpdmVyIFRyYWNlIFN1cHBvcnQKPiArICoKPiArICogQ29weXJpZ2h0IChD KSAyMDE4IENhZGVuY2UuCj4gKyAqCj4gKyAqIEF1dGhvcjogUGF3ZWwgTGFzemN6YWsgPHBhd2Vs bEBjYWRlbmNlLmNvbT4KPiArICovCj4gKwo+ICsjZGVmaW5lIENSRUFURV9UUkFDRV9QT0lOVFMK PiArI2luY2x1ZGUgInRyYWNlLmgiCj4gKwo+ICt2b2lkIGNkbnMzX2RiZyhzdHJ1Y3QgY2RuczNf ZGV2aWNlICpwcml2X2RldiwgY29uc3QgY2hhciAqZm10LCAuLi4pCj4gK3sKPiArICAgICAgIHN0 cnVjdCB2YV9mb3JtYXQgdmFmOwo+ICsgICAgICAgdmFfbGlzdCBhcmdzOwo+ICsKPiArICAgICAg IHZhX3N0YXJ0KGFyZ3MsIGZtdCk7Cj4gKyAgICAgICB2YWYuZm10ID0gZm10Owo+ICsgICAgICAg dmFmLnZhID0gJmFyZ3M7Cj4gKyAgICAgICB0cmFjZV9jZG5zM19sb2cocHJpdl9kZXYsICZ2YWYp Owo+ICsgICAgICAgdmFfZW5kKGFyZ3MpOwo+ICt9Cj4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvdXNi L2NkbnMzL3RyYWNlLmggYi9kcml2ZXJzL3VzYi9jZG5zMy90cmFjZS5oCj4gbmV3IGZpbGUgbW9k ZSAxMDA2NDQKPiBpbmRleCAwMDAwMDAwMDAwMDAuLmE2YmJmOTFjNjE2Ygo+IC0tLSAvZGV2L251 bGwKPiArKysgYi9kcml2ZXJzL3VzYi9jZG5zMy90cmFjZS5oCj4gQEAgLTAsMCArMSw0MDQgQEAK PiArLyogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEdQTC0yLjAgKi8KPiArLyoKPiArICogVVNC U1MgZGV2aWNlIGNvbnRyb2xsZXIgZHJpdmVyLgo+ICsgKiBUcmFjZSBzdXBwb3J0IGhlYWRlciBm aWxlLgo+ICsgKgo+ICsgKiBDb3B5cmlnaHQgKEMpIDIwMTggQ2FkZW5jZS4KPiArICoKPiArICog QXV0aG9yOiBQYXdlbCBMYXN6Y3phayA8cGF3ZWxsQGNhZGVuY2UuY29tPgo+ICsgKi8KPiArCj4g KyN1bmRlZiBUUkFDRV9TWVNURU0KPiArI2RlZmluZSBUUkFDRV9TWVNURU0gY2RuczMKPiArCj4g KyNpZiAhZGVmaW5lZChfX0xJTlVYX0NETlMzX1RSQUNFKSB8fCBkZWZpbmVkKFRSQUNFX0hFQURF Ul9NVUxUSV9SRUFEKQo+ICsjZGVmaW5lIF9fTElOVVhfQ0ROUzNfVFJBQ0UKPiArCj4gKyNpbmNs dWRlIDxsaW51eC90eXBlcy5oPgo+ICsjaW5jbHVkZSA8bGludXgvdHJhY2Vwb2ludC5oPgo+ICsj aW5jbHVkZSA8YXNtL2J5dGVvcmRlci5oPgo+ICsjaW5jbHVkZSA8bGludXgvdXNiL2NoOS5oPgo+ ICsjaW5jbHVkZSAiY29yZS5oIgo+ICsjaW5jbHVkZSAiZ2FkZ2V0LmgiCj4gKyNpbmNsdWRlICJk ZWJ1Zy5oIgo+ICsKPiArI2RlZmluZSBDRE5TM19NU0dfTUFYICA1MDAKPiArCj4gK1RSQUNFX0VW RU5UKGNkbnMzX2xvZywKPiArICAgICAgIFRQX1BST1RPKHN0cnVjdCBjZG5zM19kZXZpY2UgKnBy aXZfZGV2LCBzdHJ1Y3QgdmFfZm9ybWF0ICp2YWYpLAo+ICsgICAgICAgVFBfQVJHUyhwcml2X2Rl diwgdmFmKSwKPiArICAgICAgIFRQX1NUUlVDVF9fZW50cnkoCj4gKyAgICAgICAgICAgICAgIF9f c3RyaW5nKG5hbWUsIGRldl9uYW1lKHByaXZfZGV2LT5kZXYpKQo+ICsgICAgICAgICAgICAgICBf X2R5bmFtaWNfYXJyYXkoY2hhciwgbXNnLCBDRE5TM19NU0dfTUFYKQo+ICsgICAgICAgKSwKPiAr ICAgICAgIFRQX2Zhc3RfYXNzaWduKAo+ICsgICAgICAgICAgICAgICBfX2Fzc2lnbl9zdHIobmFt ZSwgZGV2X25hbWUocHJpdl9kZXYtPmRldikpOwo+ICsgICAgICAgICAgICAgICB2c25wcmludGYo X19nZXRfc3RyKG1zZyksIENETlMzX01TR19NQVgsIHZhZi0+Zm10LCAqdmFmLT52YSk7Cj4gKyAg ICAgICApLAo+ICsgICAgICAgVFBfcHJpbnRrKCIlczogJXMiLCBfX2dldF9zdHIobmFtZSksIF9f Z2V0X3N0cihtc2cpKQo+ICspOwo+ICsKPiArREVDTEFSRV9FVkVOVF9DTEFTUyhjZG5zM19sb2df ZG9vcmJlbGwsCj4gKyAgICAgICBUUF9QUk9UTyhjb25zdCBjaGFyICplcF9uYW1lLCB1MzIgZXBf dHJiYWRkciksCj4gKyAgICAgICBUUF9BUkdTKGVwX25hbWUsIGVwX3RyYmFkZHIpLAo+ICsgICAg ICAgVFBfU1RSVUNUX19lbnRyeSgKPiArICAgICAgICAgICAgICAgX19zdHJpbmcobmFtZSwgZXBf bmFtZSkKPiArICAgICAgICAgICAgICAgX19maWVsZCh1MzIsIGVwX3RyYmFkZHIpCj4gKyAgICAg ICApLAo+ICsgICAgICAgVFBfZmFzdF9hc3NpZ24oCj4gKyAgICAgICAgICAgICAgIF9fYXNzaWdu X3N0cihuYW1lLCBlcF9uYW1lKTsKPiArICAgICAgICAgICAgICAgX19lbnRyeS0+ZXBfdHJiYWRk ciA9IGVwX3RyYmFkZHI7Cj4gKyAgICAgICApLAo+ICsgICAgICAgVFBfcHJpbnRrKCIvL0Rpbmcg RG9uZyAlcywgZXBfdHJiYWRkciAlMDh4IiwgX19nZXRfc3RyKG5hbWUpLAo+ICsgICAgICAgICAg ICAgICAgIF9fZW50cnktPmVwX3RyYmFkZHIpCj4gKyk7Cj4gKwo+ICtERUZJTkVfRVZFTlQoY2Ru czNfbG9nX2Rvb3JiZWxsLCBjZG5zM19kb29yYmVsbF9lcDAsCj4gKyAgICAgICBUUF9QUk9UTyhj b25zdCBjaGFyICplcF9uYW1lLCB1MzIgZXBfdHJiYWRkciksCj4gKyAgICAgICBUUF9BUkdTKGVw X25hbWUsIGVwX3RyYmFkZHIpCj4gKyk7Cj4gKwo+ICtERUZJTkVfRVZFTlQoY2RuczNfbG9nX2Rv b3JiZWxsLCBjZG5zM19kb29yYmVsbF9lcHgsCj4gKyAgICAgICBUUF9QUk9UTyhjb25zdCBjaGFy ICplcF9uYW1lLCB1MzIgZXBfdHJiYWRkciksCj4gKyAgICAgICBUUF9BUkdTKGVwX25hbWUsIGVw X3RyYmFkZHIpCj4gKyk7Cj4gKwo+ICtERUNMQVJFX0VWRU5UX0NMQVNTKGNkbnMzX2xvZ191c2Jf aXJxLAo+ICsgICAgICAgVFBfUFJPVE8oc3RydWN0IGNkbnMzX2RldmljZSAqcHJpdl9kZXYsIHUz MiB1c2JfaXN0cyksCj4gKyAgICAgICBUUF9BUkdTKHByaXZfZGV2LCB1c2JfaXN0cyksCj4gKyAg ICAgICBUUF9TVFJVQ1RfX2VudHJ5KAo+ICsgICAgICAgICAgICAgICBfX2ZpZWxkKGVudW0gdXNi X2RldmljZV9zcGVlZCwgc3BlZWQpCj4gKyAgICAgICAgICAgICAgIF9fZmllbGQodTMyLCB1c2Jf aXN0cykKPiArICAgICAgICAgICAgICAgX19keW5hbWljX2FycmF5KGNoYXIsIHN0ciwgQ0ROUzNf TVNHX01BWCkKPiArICAgICAgICksCj4gKyAgICAgICBUUF9mYXN0X2Fzc2lnbigKPiArICAgICAg ICAgICAgICAgX19lbnRyeS0+c3BlZWQgPSBjZG5zM19nZXRfc3BlZWQocHJpdl9kZXYpOwo+ICsg ICAgICAgICAgICAgICBfX2VudHJ5LT51c2JfaXN0cyA9IHVzYl9pc3RzOwo+ICsgICAgICAgKSwK PiArICAgICAgIFRQX3ByaW50aygiJXMiLCBjZG5zM19kZWNvZGVfdXNiX2lycShfX2dldF9zdHIo c3RyKSwgX19lbnRyeS0+c3BlZWQsCj4gKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgX19lbnRyeS0+dXNiX2lzdHMpKQo+ICspOwo+ICsKPiArREVGSU5FX0VWRU5U KGNkbnMzX2xvZ191c2JfaXJxLCBjZG5zM191c2JfaXJxLAo+ICsgICAgICAgVFBfUFJPVE8oc3Ry dWN0IGNkbnMzX2RldmljZSAqcHJpdl9kZXYsIHUzMiB1c2JfaXN0cyksCj4gKyAgICAgICBUUF9B UkdTKHByaXZfZGV2LCB1c2JfaXN0cykKPiArKTsKPiArCj4gK0RFQ0xBUkVfRVZFTlRfQ0xBU1Mo Y2RuczNfbG9nX2VweF9pcnEsCj4gKyAgICAgICBUUF9QUk9UTyhzdHJ1Y3QgY2RuczNfZGV2aWNl ICpwcml2X2Rldiwgc3RydWN0IGNkbnMzX2VuZHBvaW50ICpwcml2X2VwKSwKPiArICAgICAgIFRQ X0FSR1MocHJpdl9kZXYsIHByaXZfZXApLAo+ICsgICAgICAgVFBfU1RSVUNUX19lbnRyeSgKPiAr ICAgICAgICAgICAgICAgX19zdHJpbmcoZXBfbmFtZSwgcHJpdl9lcC0+bmFtZSkKPiArICAgICAg ICAgICAgICAgX19maWVsZCh1MzIsIGVwX3N0cykKPiArICAgICAgICAgICAgICAgX19maWVsZCh1 MzIsIGVwX3RyYWRkcikKPiArICAgICAgICAgICAgICAgX19keW5hbWljX2FycmF5KGNoYXIsIHN0 ciwgQ0ROUzNfTVNHX01BWCkKPiArICAgICAgICksCj4gKyAgICAgICBUUF9mYXN0X2Fzc2lnbigK PiArICAgICAgICAgICAgICAgX19hc3NpZ25fc3RyKGVwX25hbWUsIHByaXZfZXAtPm5hbWUpOwo+ ICsgICAgICAgICAgICAgICBfX2VudHJ5LT5lcF9zdHMgPSByZWFkbCgmcHJpdl9kZXYtPnJlZ3Mt PmVwX3N0cyk7Cj4gKyAgICAgICAgICAgICAgIF9fZW50cnktPmVwX3RyYWRkciA9IHJlYWRsKCZw cml2X2Rldi0+cmVncy0+ZXBfdHJhZGRyKTsKPiArICAgICAgICksCj4gKyAgICAgICBUUF9wcmlu dGsoIiVzLCBlcF90cmFkZHI6ICUwOHgiLAo+ICsgICAgICAgICAgICAgICAgIGNkbnMzX2RlY29k ZV9lcHhfaXJxKF9fZ2V0X3N0cihzdHIpLAo+ICsgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgIF9fZ2V0X3N0cihlcF9uYW1lKSwKPiArICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICBfX2VudHJ5LT5lcF9zdHMpLAo+ICsgICAgICAgICAgICAgICAgIF9fZW50 cnktPmVwX3RyYWRkcikKPiArKTsKPiArCj4gK0RFRklORV9FVkVOVChjZG5zM19sb2dfZXB4X2ly cSwgY2RuczNfZXB4X2lycSwKPiArICAgICAgIFRQX1BST1RPKHN0cnVjdCBjZG5zM19kZXZpY2Ug KnByaXZfZGV2LCBzdHJ1Y3QgY2RuczNfZW5kcG9pbnQgKnByaXZfZXApLAo+ICsgICAgICAgVFBf QVJHUyhwcml2X2RldiwgcHJpdl9lcCkKPiArKTsKPiArCj4gK0RFQ0xBUkVfRVZFTlRfQ0xBU1Mo Y2RuczNfbG9nX2VwMF9pcnEsCj4gKyAgICAgICBUUF9QUk9UTyhzdHJ1Y3QgY2RuczNfZGV2aWNl ICpwcml2X2RldiwgIHUzMiBlcF9zdHMpLAo+ICsgICAgICAgVFBfQVJHUyhwcml2X2RldiwgZXBf c3RzKSwKPiArICAgICAgIFRQX1NUUlVDVF9fZW50cnkoCj4gKyAgICAgICAgICAgICAgIF9fZmll bGQoaW50LCBlcF9kaXIpCj4gKyAgICAgICAgICAgICAgIF9fZmllbGQodTMyLCBlcF9zdHMpCj4g KyAgICAgICAgICAgICAgIF9fZHluYW1pY19hcnJheShjaGFyLCBzdHIsIENETlMzX01TR19NQVgp Cj4gKyAgICAgICApLAo+ICsgICAgICAgVFBfZmFzdF9hc3NpZ24oCj4gKyAgICAgICAgICAgICAg IF9fZW50cnktPmVwX2RpciA9IHByaXZfZGV2LT5lcDBfZGF0YV9kaXI7Cj4gKyAgICAgICAgICAg ICAgIF9fZW50cnktPmVwX3N0cyA9IGVwX3N0czsKPiArICAgICAgICksCj4gKyAgICAgICBUUF9w cmludGsoIiVzIiwgY2RuczNfZGVjb2RlX2VwMF9pcnEoX19nZXRfc3RyKHN0ciksCj4gKyAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX19lbnRyeS0+ZXBfZGlyLAo+ ICsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9fZW50cnktPmVw X3N0cykpCj4gKyk7Cj4gKwo+ICtERUZJTkVfRVZFTlQoY2RuczNfbG9nX2VwMF9pcnEsIGNkbnMz X2VwMF9pcnEsCj4gKyAgICAgICBUUF9QUk9UTyhzdHJ1Y3QgY2RuczNfZGV2aWNlICpwcml2X2Rl diwgdTMyIGVwX3N0cyksCj4gKyAgICAgICBUUF9BUkdTKHByaXZfZGV2LCBlcF9zdHMpCj4gKyk7 Cj4gKwo+ICtERUNMQVJFX0VWRU5UX0NMQVNTKGNkbnMzX2xvZ19jdHJsLAo+ICsgICAgICAgVFBf UFJPVE8oc3RydWN0IHVzYl9jdHJscmVxdWVzdCAqY3RybCksCj4gKyAgICAgICBUUF9BUkdTKGN0 cmwpLAo+ICsgICAgICAgVFBfU1RSVUNUX19lbnRyeSgKPiArICAgICAgICAgICAgICAgX19maWVs ZCh1OCwgYlJlcXVlc3RUeXBlKQo+ICsgICAgICAgICAgICAgICBfX2ZpZWxkKHU4LCBiUmVxdWVz dCkKPiArICAgICAgICAgICAgICAgX19maWVsZCh1MTYsIHdWYWx1ZSkKPiArICAgICAgICAgICAg ICAgX19maWVsZCh1MTYsIHdJbmRleCkKPiArICAgICAgICAgICAgICAgX19maWVsZCh1MTYsIHdM ZW5ndGgpCj4gKyAgICAgICAgICAgICAgIF9fZHluYW1pY19hcnJheShjaGFyLCBzdHIsIENETlMz X01TR19NQVgpCj4gKyAgICAgICApLAo+ICsgICAgICAgVFBfZmFzdF9hc3NpZ24oCj4gKyAgICAg ICAgICAgICAgIF9fZW50cnktPmJSZXF1ZXN0VHlwZSA9IGN0cmwtPmJSZXF1ZXN0VHlwZTsKPiAr ICAgICAgICAgICAgICAgX19lbnRyeS0+YlJlcXVlc3QgPSBjdHJsLT5iUmVxdWVzdDsKPiArICAg ICAgICAgICAgICAgX19lbnRyeS0+d1ZhbHVlID0gbGUxNl90b19jcHUoY3RybC0+d1ZhbHVlKTsK PiArICAgICAgICAgICAgICAgX19lbnRyeS0+d0luZGV4ID0gbGUxNl90b19jcHUoY3RybC0+d0lu ZGV4KTsKPiArICAgICAgICAgICAgICAgX19lbnRyeS0+d0xlbmd0aCA9IGxlMTZfdG9fY3B1KGN0 cmwtPndMZW5ndGgpOwo+ICsgICAgICAgKSwKPiArICAgICAgIFRQX3ByaW50aygiJXMiLCB1c2Jf ZGVjb2RlX2N0cmwoX19nZXRfc3RyKHN0ciksIENETlMzX01TR19NQVgsCj4gKyAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9fZW50cnktPmJSZXF1ZXN0VHlwZSwKPiArICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX19lbnRyeS0+YlJlcXVlc3QsIF9f ZW50cnktPndWYWx1ZSwKPiArICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg X19lbnRyeS0+d0luZGV4LCBfX2VudHJ5LT53TGVuZ3RoKQo+ICsgICAgICAgKQo+ICspOwo+ICsK PiArREVGSU5FX0VWRU5UKGNkbnMzX2xvZ19jdHJsLCBjZG5zM19jdHJsX3JlcSwKPiArICAgICAg IFRQX1BST1RPKHN0cnVjdCB1c2JfY3RybHJlcXVlc3QgKmN0cmwpLAo+ICsgICAgICAgVFBfQVJH UyhjdHJsKQo+ICspOwo+ICsKPiArREVDTEFSRV9FVkVOVF9DTEFTUyhjZG5zM19sb2dfcmVxdWVz dCwKPiArICAgICAgIFRQX1BST1RPKHN0cnVjdCBjZG5zM19yZXF1ZXN0ICpyZXEpLAo+ICsgICAg ICAgVFBfQVJHUyhyZXEpLAo+ICsgICAgICAgVFBfU1RSVUNUX19lbnRyeSgKPiArICAgICAgICAg ICAgICAgX19zdHJpbmcobmFtZSwgcmVxLT5wcml2X2VwLT5uYW1lKQo+ICsgICAgICAgICAgICAg ICBfX2ZpZWxkKHN0cnVjdCBjZG5zM19yZXF1ZXN0ICosIHJlcSkKPiArICAgICAgICAgICAgICAg X19maWVsZCh1bnNpZ25lZCBpbnQsIGFjdHVhbCkKPiArICAgICAgICAgICAgICAgX19maWVsZCh1 bnNpZ25lZCBpbnQsIGxlbmd0aCkKPiArICAgICAgICAgICAgICAgX19maWVsZChpbnQsIHN0YXR1 cykKPiArICAgICAgICAgICAgICAgX19maWVsZChpbnQsIHplcm8pCj4gKyAgICAgICAgICAgICAg IF9fZmllbGQoaW50LCBzaG9ydF9ub3Rfb2spCj4gKyAgICAgICAgICAgICAgIF9fZmllbGQoaW50 LCBub19pbnRlcnJ1cHQpCj4gKyAgICAgICAgICAgICAgIF9fZmllbGQoaW50LCBzdGFydF90cmIp Cj4gKyAgICAgICAgICAgICAgIF9fZmllbGQoaW50LCBlbmRfdHJiKQo+ICsgICAgICAgICAgICAg ICBfX2ZpZWxkKHN0cnVjdCBjZG5zM190cmIgKiwgc3RhcnRfdHJiX2FkZHIpCj4gKyAgICAgICAg ICAgICAgIF9fZmllbGQoaW50LCBmbGFncykKPiArICAgICAgICksCj4gKyAgICAgICBUUF9mYXN0 X2Fzc2lnbigKPiArICAgICAgICAgICAgICAgX19hc3NpZ25fc3RyKG5hbWUsIHJlcS0+cHJpdl9l cC0+bmFtZSk7Cj4gKyAgICAgICAgICAgICAgIF9fZW50cnktPnJlcSA9IHJlcTsKPiArICAgICAg ICAgICAgICAgX19lbnRyeS0+YWN0dWFsID0gcmVxLT5yZXF1ZXN0LmFjdHVhbDsKPiArICAgICAg ICAgICAgICAgX19lbnRyeS0+bGVuZ3RoID0gcmVxLT5yZXF1ZXN0Lmxlbmd0aDsKPiArICAgICAg ICAgICAgICAgX19lbnRyeS0+c3RhdHVzID0gcmVxLT5yZXF1ZXN0LnN0YXR1czsKPiArICAgICAg ICAgICAgICAgX19lbnRyeS0+emVybyA9IHJlcS0+cmVxdWVzdC56ZXJvOwo+ICsgICAgICAgICAg ICAgICBfX2VudHJ5LT5zaG9ydF9ub3Rfb2sgPSByZXEtPnJlcXVlc3Quc2hvcnRfbm90X29rOwo+ ICsgICAgICAgICAgICAgICBfX2VudHJ5LT5ub19pbnRlcnJ1cHQgPSByZXEtPnJlcXVlc3Qubm9f aW50ZXJydXB0Owo+ICsgICAgICAgICAgICAgICBfX2VudHJ5LT5zdGFydF90cmIgPSByZXEtPnN0 YXJ0X3RyYjsKPiArICAgICAgICAgICAgICAgX19lbnRyeS0+ZW5kX3RyYiA9IHJlcS0+ZW5kX3Ry YjsKPiArICAgICAgICAgICAgICAgX19lbnRyeS0+c3RhcnRfdHJiX2FkZHIgPSByZXEtPnRyYjsK PiArICAgICAgICAgICAgICAgX19lbnRyeS0+ZmxhZ3MgPSByZXEtPmZsYWdzOwo+ICsgICAgICAg KSwKPiArICAgICAgIFRQX3ByaW50aygiJXM6IHJlcTogJXAsIGxlbmd0aDogJXUvJXUgJXMlcyVz LCBzdGF0dXM6ICVkLCIKPiArICAgICAgICAgICAgICAgICAiIHRyYjogW3N0YXJ0OiVkLCBlbmQ6 JWQ6IHZpcnQgYWRkciAlcGFdLCBmbGFnczoleCAiLAo+ICsgICAgICAgICAgICAgICBfX2dldF9z dHIobmFtZSksIF9fZW50cnktPnJlcSwgX19lbnRyeS0+YWN0dWFsLCBfX2VudHJ5LT5sZW5ndGgs Cj4gKyAgICAgICAgICAgICAgIF9fZW50cnktPnplcm8gPyAiemVybyB8ICIgOiAiIiwKPiArICAg ICAgICAgICAgICAgX19lbnRyeS0+c2hvcnRfbm90X29rID8gInNob3J0IHwgIiA6ICIiLAo+ICsg ICAgICAgICAgICAgICBfX2VudHJ5LT5ub19pbnRlcnJ1cHQgPyAibm8gaW50IiA6ICIiLAo+ICsg ICAgICAgICAgICAgICBfX2VudHJ5LT5zdGF0dXMsCj4gKyAgICAgICAgICAgICAgIF9fZW50cnkt PnN0YXJ0X3RyYiwKPiArICAgICAgICAgICAgICAgX19lbnRyeS0+ZW5kX3RyYiwKPiArICAgICAg ICAgICAgICAgX19lbnRyeS0+c3RhcnRfdHJiX2FkZHIsCj4gKyAgICAgICAgICAgICAgIF9fZW50 cnktPmZsYWdzCj4gKyAgICAgICApCj4gKyk7Cj4gKwo+ICtERUZJTkVfRVZFTlQoY2RuczNfbG9n X3JlcXVlc3QsIGNkbnMzX2FsbG9jX3JlcXVlc3QsCj4gKyAgICAgICBUUF9QUk9UTyhzdHJ1Y3Qg Y2RuczNfcmVxdWVzdCAqcmVxKSwKPiArICAgICAgIFRQX0FSR1MocmVxKQo+ICspOwo+ICsKPiAr REVGSU5FX0VWRU5UKGNkbnMzX2xvZ19yZXF1ZXN0LCBjZG5zM19mcmVlX3JlcXVlc3QsCj4gKyAg ICAgICBUUF9QUk9UTyhzdHJ1Y3QgY2RuczNfcmVxdWVzdCAqcmVxKSwKPiArICAgICAgIFRQX0FS R1MocmVxKQo+ICspOwo+ICsKPiArREVGSU5FX0VWRU5UKGNkbnMzX2xvZ19yZXF1ZXN0LCBjZG5z M19lcF9xdWV1ZSwKPiArICAgICAgIFRQX1BST1RPKHN0cnVjdCBjZG5zM19yZXF1ZXN0ICpyZXEp LAo+ICsgICAgICAgVFBfQVJHUyhyZXEpCj4gKyk7Cj4gKwo+ICtERUZJTkVfRVZFTlQoY2RuczNf bG9nX3JlcXVlc3QsIGNkbnMzX2VwX2RlcXVldWUsCj4gKyAgICAgICBUUF9QUk9UTyhzdHJ1Y3Qg Y2RuczNfcmVxdWVzdCAqcmVxKSwKPiArICAgICAgIFRQX0FSR1MocmVxKQo+ICspOwo+ICsKPiAr REVGSU5FX0VWRU5UKGNkbnMzX2xvZ19yZXF1ZXN0LCBjZG5zM19nYWRnZXRfZ2l2ZWJhY2ssCj4g KyAgICAgICBUUF9QUk9UTyhzdHJ1Y3QgY2RuczNfcmVxdWVzdCAqcmVxKSwKPiArICAgICAgIFRQ X0FSR1MocmVxKQo+ICspOwo+ICsKPiArREVDTEFSRV9FVkVOVF9DTEFTUyhjZG5zM19sb2dfdHJi LAo+ICsgICAgICAgVFBfUFJPVE8oc3RydWN0IGNkbnMzX2VuZHBvaW50ICpwcml2X2VwLCBzdHJ1 Y3QgY2RuczNfdHJiICp0cmIpLAo+ICsgICAgICAgVFBfQVJHUyhwcml2X2VwLCB0cmIpLAo+ICsg ICAgICAgVFBfU1RSVUNUX19lbnRyeSgKPiArICAgICAgICAgICAgICAgX19zdHJpbmcobmFtZSwg cHJpdl9lcC0+bmFtZSkKPiArICAgICAgICAgICAgICAgX19maWVsZChzdHJ1Y3QgY2RuczNfdHJi ICosIHRyYikKPiArICAgICAgICAgICAgICAgX19maWVsZCh1MzIsIGJ1ZmZlcikKPiArICAgICAg ICAgICAgICAgX19maWVsZCh1MzIsIGxlbmd0aCkKPiArICAgICAgICAgICAgICAgX19maWVsZCh1 MzIsIGNvbnRyb2wpCj4gKyAgICAgICAgICAgICAgIF9fZmllbGQodTMyLCB0eXBlKQo+ICsgICAg ICAgKSwKPiArICAgICAgIFRQX2Zhc3RfYXNzaWduKAo+ICsgICAgICAgICAgICAgICBfX2Fzc2ln bl9zdHIobmFtZSwgcHJpdl9lcC0+bmFtZSk7Cj4gKyAgICAgICAgICAgICAgIF9fZW50cnktPnRy YiA9IHRyYjsKPiArICAgICAgICAgICAgICAgX19lbnRyeS0+YnVmZmVyID0gdHJiLT5idWZmZXI7 Cj4gKyAgICAgICAgICAgICAgIF9fZW50cnktPmxlbmd0aCA9IHRyYi0+bGVuZ3RoOwo+ICsgICAg ICAgICAgICAgICBfX2VudHJ5LT5jb250cm9sID0gdHJiLT5jb250cm9sOwo+ICsgICAgICAgICAg ICAgICBfX2VudHJ5LT50eXBlID0gdXNiX2VuZHBvaW50X3R5cGUocHJpdl9lcC0+ZW5kcG9pbnQu ZGVzYyk7Cj4gKyAgICAgICApLAo+ICsgICAgICAgVFBfcHJpbnRrKCIlczogdHJiICVwYSwgZG1h IGJ1ZjogMHglMDh4LCBzaXplOiAlbGQsIGN0cmw6IDB4JTA4eCAoJXMlcyVzJXMlcyVzJXMpIiwK PiArICAgICAgICAgICAgICAgX19nZXRfc3RyKG5hbWUpLCBfX2VudHJ5LT50cmIsIF9fZW50cnkt PmJ1ZmZlciwKPiArICAgICAgICAgICAgICAgVFJCX0xFTihfX2VudHJ5LT5sZW5ndGgpLCBfX2Vu dHJ5LT5jb250cm9sLAo+ICsgICAgICAgICAgICAgICBfX2VudHJ5LT5jb250cm9sICYgVFJCX0NZ Q0xFID8gIkM9MSwgIiA6ICJDPTAsICIsCj4gKyAgICAgICAgICAgICAgIF9fZW50cnktPmNvbnRy b2wgJiBUUkJfVE9HR0xFID8gIlQ9MSwgIiA6ICJUPTAsICIsCj4gKyAgICAgICAgICAgICAgIF9f ZW50cnktPmNvbnRyb2wgJiBUUkJfSVNQID8gIklTUCwgIiA6ICIiLAo+ICsgICAgICAgICAgICAg ICBfX2VudHJ5LT5jb250cm9sICYgVFJCX0ZJRk9fTU9ERSA/ICJGSUZPLCAiIDogIiIsCj4gKyAg ICAgICAgICAgICAgIF9fZW50cnktPmNvbnRyb2wgJiBUUkJfQ0hBSU4gPyAiQ0hBSU4sICIgOiAi IiwKPiArICAgICAgICAgICAgICAgX19lbnRyeS0+Y29udHJvbCAmIFRSQl9JT0MgPyAiSU9DLCAi IDogIiIsCj4gKyAgICAgICAgICAgICAgIFRSQl9GSUVMRF9UT19UWVBFKF9fZW50cnktPmNvbnRy b2wpID09IFRSQl9OT1JNQUwgPyAiTm9ybWFsIiA6ICJMSU5LIgo+ICsgICAgICAgKQo+ICspOwo+ ICsKPiArREVGSU5FX0VWRU5UKGNkbnMzX2xvZ190cmIsIGNkbnMzX3ByZXBhcmVfdHJiLAo+ICsg ICAgICAgVFBfUFJPVE8oc3RydWN0IGNkbnMzX2VuZHBvaW50ICpwcml2X2VwLCBzdHJ1Y3QgY2Ru czNfdHJiICp0cmIpLAo+ICsgICAgICAgVFBfQVJHUyhwcml2X2VwLCB0cmIpCj4gKyk7Cj4gKwo+ ICtERUZJTkVfRVZFTlQoY2RuczNfbG9nX3RyYiwgY2RuczNfY29tcGxldGVfdHJiLAo+ICsgICAg ICAgVFBfUFJPVE8oc3RydWN0IGNkbnMzX2VuZHBvaW50ICpwcml2X2VwLCBzdHJ1Y3QgY2RuczNf dHJiICp0cmIpLAo+ICsgICAgICAgVFBfQVJHUyhwcml2X2VwLCB0cmIpCj4gKyk7Cj4gKwo+ICtE RUNMQVJFX0VWRU5UX0NMQVNTKGNkbnMzX2xvZ19yaW5nLAo+ICsgICAgICAgVFBfUFJPVE8oc3Ry dWN0IGNkbnMzX2VuZHBvaW50ICpwcml2X2VwKSwKPiArICAgICAgIFRQX0FSR1MocHJpdl9lcCks Cj4gKyAgICAgICBUUF9TVFJVQ1RfX2VudHJ5KAo+ICsgICAgICAgICAgICAgICBfX2R5bmFtaWNf YXJyYXkodTgsIHJpbmcsIFRSQl9SSU5HX1NJWkUpCj4gKyAgICAgICAgICAgICAgIF9fZHluYW1p Y19hcnJheSh1OCwgcHJpdl9lcCwgc2l6ZW9mKHN0cnVjdCBjZG5zM19lbmRwb2ludCkpCj4gKyAg ICAgICAgICAgICAgIF9fZHluYW1pY19hcnJheShjaGFyLCBidWZmZXIsCj4gKyAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAoVFJCU19QRVJfU0VHTUVOVCAqIDY1KSArIENETlMzX01TR19N QVgpCj4gKyAgICAgICApLAo+ICsgICAgICAgVFBfZmFzdF9hc3NpZ24oCj4gKyAgICAgICAgICAg ICAgIG1lbWNweShfX2dldF9keW5hbWljX2FycmF5KHByaXZfZXApLCBwcml2X2VwLAo+ICsgICAg ICAgICAgICAgICAgICAgICAgc2l6ZW9mKHN0cnVjdCBjZG5zM19lbmRwb2ludCkpOwo+ICsgICAg ICAgICAgICAgICBtZW1jcHkoX19nZXRfZHluYW1pY19hcnJheShyaW5nKSwgcHJpdl9lcC0+dHJi X3Bvb2wsCj4gKyAgICAgICAgICAgICAgICAgICAgICBUUkJfUklOR19TSVpFKTsKPiArICAgICAg ICksCj4gKwo+ICsgICAgICAgVFBfcHJpbnRrKCIlcyIsCj4gKyAgICAgICAgICAgICAgICAgY2Ru czNfZGJnX3JpbmcoKHN0cnVjdCBjZG5zM19lbmRwb2ludCAqKV9fZ2V0X3N0cihwcml2X2VwKSwK PiArICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoc3RydWN0IGNkbnMzX3RyYiAqKV9f Z2V0X3N0cihyaW5nKSwKPiArICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBfX2dldF9z dHIoYnVmZmVyKSkpCj4gKyk7Cj4gKwo+ICtERUZJTkVfRVZFTlQoY2RuczNfbG9nX3JpbmcsIGNk bnMzX3JpbmcsCj4gKyAgICAgICBUUF9QUk9UTyhzdHJ1Y3QgY2RuczNfZW5kcG9pbnQgKnByaXZf ZXApLAo+ICsgICAgICAgVFBfQVJHUyhwcml2X2VwKQo+ICspOwo+ICsKPiArREVDTEFSRV9FVkVO VF9DTEFTUyhjZG5zM19sb2dfZXAsCj4gKyAgICAgICBUUF9QUk9UTyhzdHJ1Y3QgY2RuczNfZW5k cG9pbnQgKnByaXZfZXApLAo+ICsgICAgICAgVFBfQVJHUyhwcml2X2VwKSwKPiArICAgICAgIFRQ X1NUUlVDVF9fZW50cnkoCj4gKyAgICAgICAgICAgICAgIF9fc3RyaW5nKG5hbWUsIHByaXZfZXAt Pm5hbWUpCj4gKyAgICAgICAgICAgICAgIF9fZmllbGQodW5zaWduZWQgaW50LCBtYXhwYWNrZXQp Cj4gKyAgICAgICAgICAgICAgIF9fZmllbGQodW5zaWduZWQgaW50LCBtYXhwYWNrZXRfbGltaXQp Cj4gKyAgICAgICAgICAgICAgIF9fZmllbGQodW5zaWduZWQgaW50LCBtYXhfc3RyZWFtcykKPiAr ICAgICAgICAgICAgICAgX19maWVsZCh1bnNpZ25lZCBpbnQsIG1heGJ1cnN0KQo+ICsgICAgICAg ICAgICAgICBfX2ZpZWxkKHVuc2lnbmVkIGludCwgZmxhZ3MpCj4gKyAgICAgICAgICAgICAgIF9f ZmllbGQodW5zaWduZWQgaW50LCBkaXIpCj4gKyAgICAgICAgICAgICAgIF9fZmllbGQodTgsIGVu cXVldWUpCj4gKyAgICAgICAgICAgICAgIF9fZmllbGQodTgsIGRlcXVldWUpCj4gKyAgICAgICAp LAo+ICsgICAgICAgVFBfZmFzdF9hc3NpZ24oCj4gKyAgICAgICAgICAgICAgIF9fYXNzaWduX3N0 cihuYW1lLCBwcml2X2VwLT5uYW1lKTsKPiArICAgICAgICAgICAgICAgX19lbnRyeS0+bWF4cGFj a2V0ID0gcHJpdl9lcC0+ZW5kcG9pbnQubWF4cGFja2V0Owo+ICsgICAgICAgICAgICAgICBfX2Vu dHJ5LT5tYXhwYWNrZXRfbGltaXQgPSBwcml2X2VwLT5lbmRwb2ludC5tYXhwYWNrZXRfbGltaXQ7 Cj4gKyAgICAgICAgICAgICAgIF9fZW50cnktPm1heF9zdHJlYW1zID0gcHJpdl9lcC0+ZW5kcG9p bnQubWF4X3N0cmVhbXM7Cj4gKyAgICAgICAgICAgICAgIF9fZW50cnktPm1heGJ1cnN0ID0gcHJp dl9lcC0+ZW5kcG9pbnQubWF4YnVyc3Q7Cj4gKyAgICAgICAgICAgICAgIF9fZW50cnktPmZsYWdz ID0gcHJpdl9lcC0+ZmxhZ3M7Cj4gKyAgICAgICAgICAgICAgIF9fZW50cnktPmRpciA9IHByaXZf ZXAtPmRpcjsKPiArICAgICAgICAgICAgICAgX19lbnRyeS0+ZW5xdWV1ZSA9IHByaXZfZXAtPmVu cXVldWU7Cj4gKyAgICAgICAgICAgICAgIF9fZW50cnktPmRlcXVldWUgPSBwcml2X2VwLT5kZXF1 ZXVlOwo+ICsgICAgICAgKSwKPiArICAgICAgIFRQX3ByaW50aygiJXM6IG1wczogJWQvJWQuIHN0 cmVhbXM6ICVkLCBidXJzdDogJWQsIGVucSBpZHg6ICVkLCAiCj4gKyAgICAgICAgICAgICAgICAg ImRlcSBpZHg6ICVkLCBmbGFncyAlcyVzJXMlcyVzJXMlcyVzLCBkaXI6ICVzIiwKPiArICAgICAg ICAgICAgICAgX19nZXRfc3RyKG5hbWUpLCBfX2VudHJ5LT5tYXhwYWNrZXQsCj4gKyAgICAgICAg ICAgICAgIF9fZW50cnktPm1heHBhY2tldF9saW1pdCwgX19lbnRyeS0+bWF4X3N0cmVhbXMsCj4g KyAgICAgICAgICAgICAgIF9fZW50cnktPm1heGJ1cnN0LCBfX2VudHJ5LT5lbnF1ZXVlLAo+ICsg ICAgICAgICAgICAgICBfX2VudHJ5LT5kZXF1ZXVlLAo+ICsgICAgICAgICAgICAgICBfX2VudHJ5 LT5mbGFncyAmIEVQX0VOQUJMRUQgPyAiRU4gfCAiIDogIiIsCj4gKyAgICAgICAgICAgICAgIF9f ZW50cnktPmZsYWdzICYgRVBfU1RBTEwgPyAiU1RBTEwgfCAiIDogIiIsCj4gKyAgICAgICAgICAg ICAgIF9fZW50cnktPmZsYWdzICYgRVBfV0VER0UgPyAiV0VER0UgfCAiIDogIiIsCj4gKyAgICAg ICAgICAgICAgIF9fZW50cnktPmZsYWdzICYgRVBfVFJBTlNGRVJfU1RBUlRFRCA/ICJTVEFSVEVE IHwgIiA6ICIiLAo+ICsgICAgICAgICAgICAgICBfX2VudHJ5LT5mbGFncyAmIEVQX1VQREFURV9F UF9UUkJBRERSID8gIlVQRCBUUkIgfCAiIDogIiIsCj4gKyAgICAgICAgICAgICAgIF9fZW50cnkt PmZsYWdzICYgRVBfUEVORElOR19SRVFVRVNUID8gIlJFUSBQRU4gfCAiIDogIiIsCj4gKyAgICAg ICAgICAgICAgIF9fZW50cnktPmZsYWdzICYgRVBfUklOR19GVUxMID8gIlJJTkcgRlVMTCB8IiA6 ICIiLAo+ICsgICAgICAgICAgICAgICBfX2VudHJ5LT5mbGFncyAmIEVQX0NMQUlNRUQgPyAgIkNM QUlNRUQgIiA6ICIiLAo+ICsgICAgICAgICAgICAgICBfX2VudHJ5LT5kaXIgPyAiSU4iIDogIk9V VCIKPiArICAgICAgICkKPiArKTsKPiArCj4gK0RFRklORV9FVkVOVChjZG5zM19sb2dfZXAsIGNk bnMzX2dhZGdldF9lcF9lbmFibGUsCj4gKyAgICAgICBUUF9QUk9UTyhzdHJ1Y3QgY2RuczNfZW5k cG9pbnQgKnByaXZfZXApLAo+ICsgICAgICAgVFBfQVJHUyhwcml2X2VwKQo+ICspOwo+ICsKPiAr REVGSU5FX0VWRU5UKGNkbnMzX2xvZ19lcCwgY2RuczNfZ2FkZ2V0X2VwX2Rpc2FibGUsCj4gKyAg ICAgICBUUF9QUk9UTyhzdHJ1Y3QgY2RuczNfZW5kcG9pbnQgKnByaXZfZXApLAo+ICsgICAgICAg VFBfQVJHUyhwcml2X2VwKQo+ICspOwo+ICsKPiArREVDTEFSRV9FVkVOVF9DTEFTUyhjZG5zM19s b2dfcmVxdWVzdF9oYW5kbGVkLAo+ICsgICAgICAgVFBfUFJPVE8oc3RydWN0IGNkbnMzX3JlcXVl c3QgKnByaXZfcmVxLCBpbnQgY3VycmVudF9pbmRleCwKPiArICAgICAgICAgICAgICAgIGludCBo YW5kbGVkKSwKPiArICAgICAgIFRQX0FSR1MocHJpdl9yZXEsIGN1cnJlbnRfaW5kZXgsIGhhbmRs ZWQpLAo+ICsgICAgICAgVFBfU1RSVUNUX19lbnRyeSgKPiArICAgICAgICAgICAgICAgX19maWVs ZChzdHJ1Y3QgY2RuczNfcmVxdWVzdCAqLCBwcml2X3JlcSkKPiArICAgICAgICAgICAgICAgX19m aWVsZCh1bnNpZ25lZCBpbnQsIGRtYV9wb3NpdGlvbikKPiArICAgICAgICAgICAgICAgX19maWVs ZCh1bnNpZ25lZCBpbnQsIGhhbmRsZWQpCj4gKyAgICAgICAgICAgICAgIF9fZmllbGQodW5zaWdu ZWQgaW50LCBkZXF1ZXVlX2lkeCkKPiArICAgICAgICAgICAgICAgX19maWVsZCh1bnNpZ25lZCBp bnQsIGVucXVldWVfaWR4KQo+ICsgICAgICAgICAgICAgICBfX2ZpZWxkKHVuc2lnbmVkIGludCwg c3RhcnRfdHJiKQo+ICsgICAgICAgICAgICAgICBfX2ZpZWxkKHVuc2lnbmVkIGludCwgZW5kX3Ry YikKPiArICAgICAgICksCj4gKyAgICAgICBUUF9mYXN0X2Fzc2lnbigKPiArICAgICAgICAgICAg ICAgX19lbnRyeS0+cHJpdl9yZXEgPSBwcml2X3JlcTsKPiArICAgICAgICAgICAgICAgX19lbnRy eS0+ZG1hX3Bvc2l0aW9uID0gY3VycmVudF9pbmRleDsKPiArICAgICAgICAgICAgICAgX19lbnRy eS0+aGFuZGxlZCA9IGhhbmRsZWQ7Cj4gKyAgICAgICAgICAgICAgIF9fZW50cnktPmRlcXVldWVf aWR4ID0gcHJpdl9yZXEtPnByaXZfZXAtPmRlcXVldWU7Cj4gKyAgICAgICAgICAgICAgIF9fZW50 cnktPmVucXVldWVfaWR4ID0gcHJpdl9yZXEtPnByaXZfZXAtPmVucXVldWU7Cj4gKyAgICAgICAg ICAgICAgIF9fZW50cnktPnN0YXJ0X3RyYiA9IHByaXZfcmVxLT5zdGFydF90cmI7Cj4gKyAgICAg ICAgICAgICAgIF9fZW50cnktPmVuZF90cmIgPSBwcml2X3JlcS0+ZW5kX3RyYjsKPiArICAgICAg ICksCj4gKyAgICAgICBUUF9wcmludGsoIlJlcTogJXAgJXMsIERNQSBwb3M6ICVkLCBlcCBkZXE6 ICVkLCBlcCBlbnE6ICVkLCIKPiArICAgICAgICAgICAgICAgICAiIHN0YXJ0IHRyYjogJWQsIGVu ZCB0cmI6ICVkIiwKPiArICAgICAgICAgICAgICAgX19lbnRyeS0+cHJpdl9yZXEsCj4gKyAgICAg ICAgICAgICAgIF9fZW50cnktPmhhbmRsZWQgPyAiaGFuZGxlZCIgOiAibm90IGhhbmRsZWQiLAo+ ICsgICAgICAgICAgICAgICBfX2VudHJ5LT5kbWFfcG9zaXRpb24sIF9fZW50cnktPmRlcXVldWVf aWR4LAo+ICsgICAgICAgICAgICAgICBfX2VudHJ5LT5lbnF1ZXVlX2lkeCwgX19lbnRyeS0+c3Rh cnRfdHJiLAo+ICsgICAgICAgICAgICAgICBfX2VudHJ5LT5lbmRfdHJiCj4gKyAgICAgICApCj4g Kyk7Cj4gKwo+ICtERUZJTkVfRVZFTlQoY2RuczNfbG9nX3JlcXVlc3RfaGFuZGxlZCwgY2RuczNf cmVxdWVzdF9oYW5kbGVkLAo+ICsgICAgICAgVFBfUFJPVE8oc3RydWN0IGNkbnMzX3JlcXVlc3Qg KnByaXZfcmVxLCBpbnQgY3VycmVudF9pbmRleCwKPiArICAgICAgICAgICAgICAgIGludCBoYW5k bGVkKSwKPiArICAgICAgIFRQX0FSR1MocHJpdl9yZXEsIGN1cnJlbnRfaW5kZXgsIGhhbmRsZWQp Cj4gKyk7Cj4gKyNlbmRpZiAvKiBfX0xJTlVYX0NETlMzX1RSQUNFICovCj4gKwo+ICsvKiB0aGlz IHBhcnQgbXVzdCBiZSBvdXRzaWRlIGhlYWRlciBndWFyZCAqLwo+ICsKPiArI3VuZGVmIFRSQUNF X0lOQ0xVREVfUEFUSAo+ICsjZGVmaW5lIFRSQUNFX0lOQ0xVREVfUEFUSCAuCj4gKwo+ICsjdW5k ZWYgVFJBQ0VfSU5DTFVERV9GSUxFCj4gKyNkZWZpbmUgVFJBQ0VfSU5DTFVERV9GSUxFIHRyYWNl Cj4gKwo+ICsjaW5jbHVkZSA8dHJhY2UvZGVmaW5lX3RyYWNlLmg+Cj4gLS0KPiAyLjE3LjEKPgoK ZGlmZiAtLWdpdCBhL2RyaXZlcnMvdXNiL2NkbnMzL2RyZC5jIGIvZHJpdmVycy91c2IvY2RuczMv ZHJkLmMKaW5kZXggM2U1NjMzOGNkN2I5Li4yZTNkMmQxOWFhYTMgMTAwNjQ0Ci0tLSBhL2RyaXZl cnMvdXNiL2NkbnMzL2RyZC5jCisrKyBiL2RyaXZlcnMvdXNiL2NkbnMzL2RyZC5jCkBAIC04MSw3 ICs4MSw3IEBAIGludCBjZG5zM19nZXRfaWQoc3RydWN0IGNkbnMzICpjZG5zKQoKIGludCBjZG5z M19pc19ob3N0KHN0cnVjdCBjZG5zMyAqY2RucykKIHsKLSAgICAgICBpZiAoY2Rucy0+Y3VycmVu dF9kcl9tb2RlID09IFVTQl9EUl9NT0RFX0hPU1QpCisgICAgICAgaWYgKHVzYl9nZXRfZHJfbW9k ZShjZG5zLT5kZXYpID09IFVTQl9EUl9NT0RFX0hPU1QpCiAgICAgICAgICAgICAgICByZXR1cm4g MTsKICAgICAgICBlbHNlIGlmICghY2RuczNfZ2V0X2lkKGNkbnMpKQogICAgICAgICAgICAgICAg cmV0dXJuIDE7CkBAIC05MSw3ICs5MSw3IEBAIGludCBjZG5zM19pc19ob3N0KHN0cnVjdCBjZG5z MyAqY2RucykKCiBpbnQgY2RuczNfaXNfZGV2aWNlKHN0cnVjdCBjZG5zMyAqY2RucykKIHsKLSAg ICAgICBpZiAoY2Rucy0+Y3VycmVudF9kcl9tb2RlID09IFVTQl9EUl9NT0RFX1BFUklQSEVSQUwp CisgICAgICAgaWYgKHVzYl9nZXRfZHJfbW9kZShjZG5zLT5kZXYpID09IFVTQl9EUl9NT0RFX1BF UklQSEVSQUwpCiAgICAgICAgICAgICAgICByZXR1cm4gMTsKICAgICAgICBlbHNlIGlmIChjZG5z LT5jdXJyZW50X2RyX21vZGUgPT0gVVNCX0RSX01PREVfT1RHKQogICAgICAgICAgICAgICAgaWYg KGNkbnMzX2dldF9pZChjZG5zKSkKQEAgLTIzMCw2ICsyMzAsOCBAQCBpbnQgY2RuczNfZHJkX3Vw ZGF0ZV9tb2RlKHN0cnVjdCBjZG5zMyAqY2RucykKCgpCZWxvdyBpcyB0aGUgb3V0cHV0IEkgc2V0 IGRyX21vZGUgYXMgaG9zdDoKWyAgICAyLjc0MzUzOF0gY2Rucy11c2IzIDViMTMwMDAwLmNkbnMz OiBEUkQgdmVyc2lvbiB2MCAoMDAwMDAxMDApClsgICAgMi43NDk0NzZdIGNkbnMtdXNiMyA1YjEz MDAwMC5jZG5zMzogQ29udHJvbGxlciBzdHJhcHBlZCB0byBIT1NUClsgICAgMi43NTU2MzhdIGNk bnMtdXNiMyA1YjEzMDAwMC5jZG5zMzogY2RuczNfZHJkX3VwZGF0ZV9tb2RlOjE6MDoxClsgICAg Mi43NjM3NjRdIGNkbnMtdXNiMyA1YjEzMDAwMC5jZG5zMzogU2V0IGNvbnRyb2xsZXIgdG8gSG9z dCBtb2RlClsgICAgMi43Njk4NjhdIGNkbnMtdXNiMyA1YjEzMDAwMC5jZG5zMzogV2FpdGluZyBm b3IgSG9zdCBtb2RlIGlzIHR1cm5lZCBvbgo=