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=-7.1 required=3.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH,MAILING_LIST_MULTI, SIGNED_OFF_BY,SPF_PASS 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 0D1D7C43381 for ; Mon, 4 Mar 2019 09:23:33 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id A33FD20863 for ; Mon, 4 Mar 2019 09:23:32 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=cadence.com header.i=@cadence.com header.b="JJYJguRu"; dkim=pass (1024-bit key) header.d=cadence.com header.i=@cadence.com header.b="e31rE18z" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726241AbfCDJXb (ORCPT ); Mon, 4 Mar 2019 04:23:31 -0500 Received: from mx0a-0014ca01.pphosted.com ([208.84.65.235]:54618 "EHLO mx0a-0014ca01.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726087AbfCDJXa (ORCPT ); Mon, 4 Mar 2019 04:23:30 -0500 Received: from pps.filterd (m0042385.ppops.net [127.0.0.1]) by mx0a-0014ca01.pphosted.com (8.16.0.27/8.16.0.27) with SMTP id x249MTAZ007246; Mon, 4 Mar 2019 01:23:12 -0800 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cadence.com; h=from : to : cc : subject : date : message-id : references : in-reply-to : content-type : content-transfer-encoding : mime-version; s=proofpoint; bh=AW6V265SWECPXXIFPaoP9+3psZqLbLtqSvnsrLG/WxY=; b=JJYJguRukZgeYEid+FIKZrA9HVsEQCffOgeQLgqyK6lBTNZoTa7sVXmXiDVcaQQrJ82w 2Xkv4Joq8vj0Av7s7mq/Wki1K34K5RgZZRmAkxIHr1DH2l4US/+kox28sfkUufscbs9S +aYnRwvjAG+mMf8gUlB2IyHY0X+VkYR5Nhi7iAMynC1YIJQteixrgnL5FdtD+YouLjzr L0z1bAOmftNs92tefT/MhL2f6xLn43EOxBMjLrNfuMbUHb7aJmQxCeM3KZsNFTJhTV43 qQU5QvEEf1aqun0I3PL85+4PYVwzcVR1Af8xeiqJERJI4/I6wTNezd277k9H7l+0QOpR QQ== Authentication-Results: cadence.com; spf=pass smtp.mailfrom=pawell@cadence.com Received: from nam02-bl2-obe.outbound.protection.outlook.com (mail-bl2nam02lp2052.outbound.protection.outlook.com [104.47.38.52]) by mx0a-0014ca01.pphosted.com with ESMTP id 2qyq8xy0va-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-SHA384 bits=256 verify=NOT); Mon, 04 Mar 2019 01:23:11 -0800 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cadence.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=AW6V265SWECPXXIFPaoP9+3psZqLbLtqSvnsrLG/WxY=; b=e31rE18zjn/vrPVb8p9g5vTLA3qP51Pz7xbobrwWr8VcU8Isunl9jW1fDMxGgaeHX8NEYDkZvzJereZOdr7eWGwvEsKVf+rODwIbWdDgurufpGBqlVxKlnFK+MlDHb0s21x/wDGEGiQ5EQ2wFvSs6ThMJX82HTkqqMW9fT0HR1I= Received: from BYAPR07MB4709.namprd07.prod.outlook.com (52.135.204.159) by BYAPR07MB5368.namprd07.prod.outlook.com (20.177.125.21) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.1665.19; Mon, 4 Mar 2019 09:23:07 +0000 Received: from BYAPR07MB4709.namprd07.prod.outlook.com ([fe80::2dae:f6be:5a31:3bc8]) by BYAPR07MB4709.namprd07.prod.outlook.com ([fe80::2dae:f6be:5a31:3bc8%4]) with mapi id 15.20.1665.020; Mon, 4 Mar 2019 09:23:07 +0000 From: Pawel Laszczak To: Greg KH CC: "devicetree@vger.kernel.org" , "felipe.balbi@linux.intel.com" , "mark.rutland@arm.com" , "linux-usb@vger.kernel.org" , "hdegoede@redhat.com" , "heikki.krogerus@linux.intel.com" , "andy.shevchenko@gmail.com" , "robh+dt@kernel.org" , "rogerq@ti.com" , "linux-kernel@vger.kernel.org" , "jbergsagel@ti.com" , "nsekhar@ti.com" , "nm@ti.com" , Suresh Punnoose , "peter.chen@nxp.com" , Rahul Kumar Subject: RE: [PATCH v4 5/6] usb:cdns3 Add Cadence USB3 DRD Driver Thread-Topic: [PATCH v4 5/6] usb:cdns3 Add Cadence USB3 DRD Driver Thread-Index: AQHUxJ4VnRX9klsPV0GCGU5zGXPUXqXnI4aAgBQLQeA= Date: Mon, 4 Mar 2019 09:23:07 +0000 Message-ID: References: <1550173514-23573-1-git-send-email-pawell@cadence.com> <1550173514-23573-6-git-send-email-pawell@cadence.com> <20190219132403.GC20719@kroah.com> In-Reply-To: <20190219132403.GC20719@kroah.com> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-dg-ref: PG1ldGE+PGF0IG5tPSJib2R5LnR4dCIgcD0iYzpcdXNlcnNccGF3ZWxsXGFwcGRhdGFccm9hbWluZ1wwOWQ4NDliNi0zMmQzLTRhNDAtODVlZS02Yjg0YmEyOWUzNWJcbXNnc1xtc2ctMWMwMThkNWEtM2U1Zi0xMWU5LTg3MzAtMWM0ZDcwMWRmYmE0XGFtZS10ZXN0XDFjMDE4ZDViLTNlNWYtMTFlOS04NzMwLTFjNGQ3MDFkZmJhNGJvZHkudHh0IiBzej0iMjA0NDgiIHQ9IjEzMTk2MTY0OTg0NjkwNjQ0MSIgaD0iMHhKYjlnNy9sbGpLR0NML2drS1NJK1NMN2dZPSIgaWQ9IiIgYmw9IjAiIGJvPSIxIi8+PC9tZXRhPg== x-dg-rorf: x-originating-ip: [185.217.253.59] x-ms-publictraffictype: Email x-ms-office365-filtering-correlation-id: c4084978-6949-43e6-eb4d-08d6a0830335 x-microsoft-antispam: BCL:0;PCL:0;RULEID:(2390118)(7020095)(4652040)(8989299)(4534185)(4627221)(201703031133081)(201702281549075)(8990200)(5600127)(711020)(4605104)(2017052603328)(7153060)(7193020);SRVR:BYAPR07MB5368; x-ms-traffictypediagnostic: BYAPR07MB5368: x-microsoft-exchange-diagnostics: 1;BYAPR07MB5368;20:QoAAgfeD85zSloynP6H0G8vHbudZQpejOr+5tQ/m4+UwoU5UZjWNLPBrXICEOjF5W3TAe3o1ih2nKJtSedseAQ36/REYrlEqK0mlYDa8PF0amytkW1gJMppVgnc+DrDdiWbge9pWwIE8NSLxN+m4j1pFY/ykGtvmXnaqdBEQuwUHqfzh2vuaSM2AuTFFIPOu2xbagffwWnsEGQWdqISRuQgSXg+RitKSYAaG873jSdmU62VKlzx4tGNt7JTxGNyS x-microsoft-antispam-prvs: x-forefront-prvs: 09669DB681 x-forefront-antispam-report: SFV:NSPM;SFS:(10009020)(136003)(366004)(39860400002)(396003)(346002)(376002)(52314003)(36092001)(189003)(199004)(6506007)(6436002)(102836004)(4326008)(5660300002)(86362001)(26005)(71200400001)(71190400001)(14444005)(256004)(25786009)(3846002)(52536013)(229853002)(7696005)(30864003)(99286004)(55016002)(53936002)(6116002)(53946003)(2906002)(76176011)(6246003)(107886003)(9686003)(14454004)(446003)(106356001)(476003)(11346002)(8676002)(486006)(478600001)(105586002)(54906003)(81156014)(81166006)(97736004)(6916009)(8936002)(305945005)(7416002)(186003)(7736002)(66066001)(74316002)(316002)(33656002)(68736007)(579004);DIR:OUT;SFP:1101;SCL:1;SRVR:BYAPR07MB5368;H:BYAPR07MB4709.namprd07.prod.outlook.com;FPR:;SPF:None;LANG:en;PTR:InfoNoRecords;MX:1;A:1; received-spf: None (protection.outlook.com: cadence.com does not designate permitted sender hosts) x-ms-exchange-senderadcheck: 1 x-microsoft-antispam-message-info: Rq3UtSFtxbY0SWEiR8akFZkAbvuhdiZBmJc/6MQrd/ioZW/o4+Wb9Kkva1m8E1IrKPVHgq9KNlegP/y3b4hy3wRl7wFopQKXb29WpDaBevfC1tww+ZfZ+kfxk/egvw3UZkyV/WArZV9rAppRvuVBHJenHYa1xBTzi/LfJ4dBeQVRNn4poL/h9GSEGx90ztIYL3QdrdXB/6crvs0Pe/dSsczh82mN6GxL7vO2Mg/NJWjJ/3weAmBYDWHpvU3uBFnNf8zMwFFJoLkqIRpxX42DlgzcA0JPLmlxHkW3cxl3Ly6JLqXCw8A/Za5v+qSX6nGRYKRcyKhisD1pJpaa6yv2bbUQDSSlsp9JXmxRg+buxpCHtOOCiYlDWfm+E3lnR488N5ffN6FvzEBoA0XjVL6Yjma5Ml6Lvv8l0LkCyjQJWHA= Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 X-OriginatorOrg: cadence.com X-MS-Exchange-CrossTenant-Network-Message-Id: c4084978-6949-43e6-eb4d-08d6a0830335 X-MS-Exchange-CrossTenant-originalarrivaltime: 04 Mar 2019 09:23:07.2517 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: d36035c5-6ce6-4662-a3dc-e762e61ae4c9 X-MS-Exchange-CrossTenant-mailboxtype: HOSTED X-MS-Exchange-Transport-CrossTenantHeadersStamped: BYAPR07MB5368 X-Proofpoint-SPF-Result: pass X-Proofpoint-SPF-Record: v=spf1 include:_spf.salesforce.com include:mktomail.com include:spf-0014ca01.pphosted.com include:spf.protection.outlook.com include:auth.msgapp.com include:spf.mandrillapp.com ~all X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:,, definitions=2019-03-04_04:,, signatures=0 X-Proofpoint-Spam-Details: rule=outbound_check_notspam policy=outbound_check score=0 priorityscore=1501 malwarescore=0 suspectscore=0 phishscore=0 bulkscore=0 spamscore=0 clxscore=1015 lowpriorityscore=0 mlxscore=0 impostorscore=0 mlxlogscore=999 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1810050000 definitions=main-1903040070 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Hi,=20 > >On Thu, Feb 14, 2019 at 07:45:13PM +0000, Pawel Laszczak wrote: >> This patch introduce new Cadence USBSS DRD driver to linux kernel. > >Nit, "Linux" :) > >> The Cadence USBSS DRD Driver is a highly configurable IP Core whichi > >"whichi"? > >> can be instantiated as Dual-Role Device (DRD), Peripheral Only and >> Host Only (XHCI)configurations. >> >> The current driver has been validated with FPGA burned. We have support > >I can not parse that sentance, sorry. what does "with FPGA burned" >mean? I met with such sentence, and It's means that implementation (IP Core)=20 Is loaded to FPGA. Maybe it was used from some historical reason,=20 and nowadays it is not correct.=20 I will replace it with ".. which is used on FPGA prototyping." > >> for PCIe bus, which is used on FPGA prototyping. >> >> The host side of USBSS-DRD controller is compliance with XHCI > >"compliant" > >> specification, so it works with standard XHCI linux driver. > >"Linux" > >> >> Signed-off-by: Pawel Laszczak >> --- >> drivers/usb/Kconfig | 2 + >> drivers/usb/Makefile | 2 + >> drivers/usb/cdns3/Kconfig | 44 + >> drivers/usb/cdns3/Makefile | 14 + >> drivers/usb/cdns3/cdns3-pci-wrap.c | 155 +++ >> drivers/usb/cdns3/core.c | 403 ++++++ >> drivers/usb/cdns3/core.h | 116 ++ >> drivers/usb/cdns3/debug.h | 168 +++ >> drivers/usb/cdns3/debugfs.c | 164 +++ >> drivers/usb/cdns3/drd.c | 365 +++++ >> drivers/usb/cdns3/drd.h | 162 +++ >> drivers/usb/cdns3/ep0.c | 907 +++++++++++++ >> drivers/usb/cdns3/gadget-export.h | 28 + >> drivers/usb/cdns3/gadget.c | 2003 ++++++++++++++++++++++++++++ >> drivers/usb/cdns3/gadget.h | 1207 +++++++++++++++++ >> drivers/usb/cdns3/host-export.h | 28 + >> drivers/usb/cdns3/host.c | 72 + >> drivers/usb/cdns3/trace.c | 23 + >> drivers/usb/cdns3/trace.h | 404 ++++++ >> 19 files changed, 6267 insertions(+) >> create mode 100644 drivers/usb/cdns3/Kconfig >> create mode 100644 drivers/usb/cdns3/Makefile >> create mode 100644 drivers/usb/cdns3/cdns3-pci-wrap.c >> create mode 100644 drivers/usb/cdns3/core.c >> create mode 100644 drivers/usb/cdns3/core.h >> create mode 100644 drivers/usb/cdns3/debug.h >> create mode 100644 drivers/usb/cdns3/debugfs.c >> create mode 100644 drivers/usb/cdns3/drd.c >> create mode 100644 drivers/usb/cdns3/drd.h >> create mode 100644 drivers/usb/cdns3/ep0.c >> create mode 100644 drivers/usb/cdns3/gadget-export.h >> create mode 100644 drivers/usb/cdns3/gadget.c >> create mode 100644 drivers/usb/cdns3/gadget.h >> create mode 100644 drivers/usb/cdns3/host-export.h >> create mode 100644 drivers/usb/cdns3/host.c >> create mode 100644 drivers/usb/cdns3/trace.c >> create mode 100644 drivers/usb/cdns3/trace.h >> >> diff --git a/drivers/usb/Kconfig b/drivers/usb/Kconfig >> index 987fc5ba6321..5f9334019d04 100644 >> --- a/drivers/usb/Kconfig >> +++ b/drivers/usb/Kconfig >> @@ -112,6 +112,8 @@ source "drivers/usb/usbip/Kconfig" >> >> endif >> >> +source "drivers/usb/cdns3/Kconfig" >> + >> source "drivers/usb/mtu3/Kconfig" >> >> source "drivers/usb/musb/Kconfig" >> diff --git a/drivers/usb/Makefile b/drivers/usb/Makefile >> index 7d1b8c82b208..ab125b966cac 100644 >> --- a/drivers/usb/Makefile >> +++ b/drivers/usb/Makefile >> @@ -12,6 +12,8 @@ obj-$(CONFIG_USB_DWC3) +=3D dwc3/ >> obj-$(CONFIG_USB_DWC2) +=3D dwc2/ >> obj-$(CONFIG_USB_ISP1760) +=3D isp1760/ >> >> +obj-$(CONFIG_USB_CDNS3) +=3D cdns3/ >> + >> obj-$(CONFIG_USB_MON) +=3D mon/ >> obj-$(CONFIG_USB_MTU3) +=3D mtu3/ >> >> diff --git a/drivers/usb/cdns3/Kconfig b/drivers/usb/cdns3/Kconfig >> new file mode 100644 >> index 000000000000..27cb3d8dbe3d >> --- /dev/null >> +++ b/drivers/usb/cdns3/Kconfig >> @@ -0,0 +1,44 @@ >> +config USB_CDNS3 >> + tristate "Cadence USB3 Dual-Role Controller" >> + depends on USB_SUPPORT && (USB || USB_GADGET) && HAS_DMA >> + help >> + Say Y here if your system has a cadence USB3 dual-role controller. >> + It supports: dual-role switch, Host-only, and Peripheral-only. >> + >> + If you choose to build this driver is a dynamically linked >> + as module, the module will be called cdns3.ko. >> + >> +if USB_CDNS3 >> + >> +config USB_CDNS3_GADGET >> + bool "Cadence USB3 device controller" >> + depends on USB_GADGET >> + help >> + Say Y here to enable device controller functionality of the >> + cadence USBSS-DEV driver. >> + >> + This controller supports FF, HS and SS mode. It doesn't suppo= rt >> + LS and SSP mode. >> + >> +config USB_CDNS3_HOST >> + bool "Cadence USB3 host controller" >> + depends on USB_XHCI_HCD >> + help >> + Say Y here to enable host controller functionality of the >> + cadence driver. >> + >> + Host controller is compliant with XHCI so it will use >> + standard XHCI driver. >> + >> +config USB_CDNS3_PCI_WRAP >> + tristate "Cadence USB3 support on PCIe-based platforms" >> + depends on USB_PCI && ACPI >> + default USB_CDNS3 >> + help >> + If you're using the USBSS Core IP with a PCIe, please say >> + 'Y' or 'M' here. >> + >> + If you choose to build this driver as module it will >> + be dynamically linked and module will be called cdns3-pci.ko > >You use tabs here, but not tabs in the other options. Please be >uniform. > > >> + >> +endif >> diff --git a/drivers/usb/cdns3/Makefile b/drivers/usb/cdns3/Makefile >> new file mode 100644 >> index 000000000000..8f9438593375 >> --- /dev/null >> +++ b/drivers/usb/cdns3/Makefile >> @@ -0,0 +1,14 @@ >> +# SPDX-License-Identifier: GPL-2.0 >> +# define_trace.h needs to know how to find our header >> +CFLAGS_trace.o :=3D -I$(src) >> + >> +cdns3-y :=3D core.o drd.o trace.o >> + >> +obj-$(CONFIG_USB_CDNS3) +=3D cdns3.o >> +ifneq ($(CONFIG_DEBUG_FS),) >> + cdns3-y +=3D debugfs.o >> +endif >> + >> +cdns3-$(CONFIG_USB_CDNS3_GADGET) +=3D gadget.o ep0.o >> +cdns3-$(CONFIG_USB_CDNS3_HOST) +=3D host.o >> +obj-$(CONFIG_USB_CDNS3_PCI_WRAP) +=3D cdns3-pci-wrap.o >> diff --git a/drivers/usb/cdns3/cdns3-pci-wrap.c b/drivers/usb/cdns3/cdns= 3-pci-wrap.c >> new file mode 100644 >> index 000000000000..d0b2d3d9b983 >> --- /dev/null >> +++ b/drivers/usb/cdns3/cdns3-pci-wrap.c >> @@ -0,0 +1,155 @@ >> +// SPDX-License-Identifier: GPL-2.0 >> +/* >> + * Cadence USBSS PCI Glue driver >> + * >> + * Copyright (C) 2018 Cadence. >> + * >> + * Author: Pawel Laszczak >> + */ >> + >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> + >> +struct cdns3_wrap { >> + struct platform_device *plat_dev; >> + struct pci_dev *hg_dev; >> + struct resource dev_res[4]; >> +}; >> + >> +struct cdns3_wrap wrap; >> + >> +#define RES_IRQ_ID 0 >> +#define RES_HOST_ID 1 >> +#define RES_DEV_ID 2 >> +#define RES_DRD_ID 3 >> + >> +#define PCI_BAR_HOST 0 >> +#define PCI_BAR_DEV 2 >> +#define PCI_BAR_OTG 4 >> + >> +#define PCI_DEV_FN_HOST_DEVICE 0 >> +#define PCI_DEV_FN_OTG 1 >> + >> +#define PCI_DRIVER_NAME "cdns3-pci-usbss" >> +#define PLAT_DRIVER_NAME "cdns-usb3" >> + >> +#define CDNS_VENDOR_ID 0x17cd > >PCI_VENDOR_ID_CDNS is already in pci_ids.h, no need to define it again >here. > >> +#define CDNS_DEVICE_ID 0x0100 > >No tabs? Corrected.=20 > >> + >> +/** > >kerneldoc is great, but for static functions? Who is pulling these into >documentation? > >If not, then no need for that format at all. I'm not sure I understood you correct.=20 Should I remove all static function description, or should change the formatting style to avoid pulling description into documentation ? For example in MTU3 driver witch is quite new I found: " /* * Set or clear the halt bit of an EP. * A halted EP won't TX/RX any data but will queue requests. */ static int mtu3_gadget_ep_set_halt(struct usb_ep *ep, int value)=20 " Will it be correct if I change comment formatting from: /**=20 * */ Into=20 /* * */ ? I ask because in this function the description is unnecessary, but in some = other static functions the comments could be helpful in understanding what functi= on does.=20 Currently I have kerneldoc for many static function.=20 >> + * cdns3_pci_probe - Probe function for Cadence USB wrapper driver >> + * @pdev: platform device object >> + * @id: pci device id >> + * >> + * Returns 0 on success otherwise negative errno >> + */ >> +static int cdns3_pci_probe(struct pci_dev *pdev, >> + const struct pci_device_id *id) >> +{ >> + struct platform_device_info plat_info; >> + struct cdns3_wrap *wrap; >> + struct resource *res; >> + int err; >> + >> + /* >> + * for GADGET/HOST PCI (devfn) function number is 0, >> + * for OTG PCI (devfn) function number is 1 >> + */ >> + if (!id || pdev->devfn !=3D PCI_DEV_FN_HOST_DEVICE) >> + return -EINVAL; >> + >> + err =3D pcim_enable_device(pdev); >> + if (err) { >> + dev_err(&pdev->dev, "Enabling PCI device has failed %d\n", err); >> + return err; >> + } >> + >> + pci_set_master(pdev); >> + wrap =3D devm_kzalloc(&pdev->dev, sizeof(*wrap), GFP_KERNEL); >> + if (!wrap) { >> + dev_err(&pdev->dev, "Failed to allocate memory\n"); > >No need to print an error again after kzalloc already printed an error. Ok, I didn't know.=20 > >> + return -ENOMEM; > >Did you forget to disable the pci device? Yes, I really forgot.=20 >> + } >> + >> + /* function 0: host(BAR_0) + device(BAR_1) + otg(BAR_2)). */ >> + memset(wrap->dev_res, 0x00, >> + sizeof(struct resource) * ARRAY_SIZE(wrap->dev_res)); >> + dev_dbg(&pdev->dev, "Initialize Device resources\n"); >> + res =3D wrap->dev_res; >> + >> + res[RES_DEV_ID].start =3D pci_resource_start(pdev, PCI_BAR_DEV); >> + res[RES_DEV_ID].end =3D pci_resource_end(pdev, PCI_BAR_DEV); >> + res[RES_DEV_ID].name =3D "dev"; >> + res[RES_DEV_ID].flags =3D IORESOURCE_MEM; >> + dev_dbg(&pdev->dev, "USBSS-DEV physical base addr: %pa\n", >> + &res[RES_DEV_ID].start); >> + >> + res[RES_HOST_ID].start =3D pci_resource_start(pdev, PCI_BAR_HOST); >> + res[RES_HOST_ID].end =3D pci_resource_end(pdev, PCI_BAR_HOST); >> + res[RES_HOST_ID].name =3D "xhci"; >> + res[RES_HOST_ID].flags =3D IORESOURCE_MEM; >> + dev_dbg(&pdev->dev, "USBSS-XHCI physical base addr: %pa\n", >> + &res[RES_HOST_ID].start); >> + >> + res[RES_DRD_ID].start =3D pci_resource_start(pdev, PCI_BAR_OTG); >> + res[RES_DRD_ID].end =3D pci_resource_end(pdev, PCI_BAR_OTG); >> + res[RES_DRD_ID].name =3D "otg"; >> + res[RES_DRD_ID].flags =3D IORESOURCE_MEM; >> + dev_dbg(&pdev->dev, "USBSS-DRD physical base addr: %pa\n", >> + &res[RES_DRD_ID].start); >> + >> + /* Interrupt common for both device and XHCI */ >> + wrap->dev_res[RES_IRQ_ID].start =3D pdev->irq; >> + wrap->dev_res[RES_IRQ_ID].name =3D "cdns3-irq"; >> + wrap->dev_res[RES_IRQ_ID].flags =3D IORESOURCE_IRQ; >> + >> + /* set up platform device info */ >> + memset(&plat_info, 0, sizeof(plat_info)); >> + plat_info.parent =3D &pdev->dev; >> + plat_info.fwnode =3D pdev->dev.fwnode; >> + plat_info.name =3D PLAT_DRIVER_NAME; >> + plat_info.id =3D pdev->devfn; >> + plat_info.res =3D wrap->dev_res; >> + plat_info.num_res =3D ARRAY_SIZE(wrap->dev_res); >> + plat_info.dma_mask =3D pdev->dma_mask; >> + >> + /* register platform device */ >> + wrap->plat_dev =3D platform_device_register_full(&plat_info); >> + if (IS_ERR(wrap->plat_dev)) >> + return PTR_ERR(wrap->plat_dev); > >No disabling of the device? > >Anyway, why are you creating a platform device when you have a real PCI >device? That seems odd, and an abuse of the platform code. What's >wrong with your real PCI device here? I use PCI platform, but the most our customers use this driver as platform= =20 driver.=20 The second reason was that we use different PCI configuration, and some of= them=20 makes it impossible to use DRD driver as single driver. For example PCI fu= nction 0 contains Device/Host register, and PCI function 1 contains OTG register.= =20 > > >> + >> + pci_set_drvdata(pdev, wrap); >> + >> + return err; >> +} >> + >> +void cdns3_pci_remove(struct pci_dev *pdev) >> +{ >> + struct cdns3_wrap *wrap =3D (struct cdns3_wrap *)pci_get_drvdata(pdev)= ; >> + >> + platform_device_unregister(wrap->plat_dev); >> +} >> + >> +static const struct pci_device_id cdns3_pci_ids[] =3D { >> + { PCI_DEVICE(CDNS_VENDOR_ID, CDNS_DEVICE_ID), }, >> + { 0, } >> +}; >> + >> +static struct pci_driver cdns3_pci_driver =3D { >> + .name =3D PCI_DRIVER_NAME, >> + .id_table =3D cdns3_pci_ids, >> + .probe =3D cdns3_pci_probe, >> + .remove =3D cdns3_pci_remove, >> +}; >> + >> +module_pci_driver(cdns3_pci_driver); >> +MODULE_DEVICE_TABLE(pci, cdns3_pci_ids); >> + >> +MODULE_AUTHOR("Pawel Laszczak "); >> +MODULE_LICENSE("GPL v2"); >> +MODULE_DESCRIPTION("Cadence USBSS PCI wrapperr"); >> + >> diff --git a/drivers/usb/cdns3/core.c b/drivers/usb/cdns3/core.c >> new file mode 100644 >> index 000000000000..aa2f63241dab >> --- /dev/null >> +++ b/drivers/usb/cdns3/core.c >> @@ -0,0 +1,403 @@ >> +// SPDX-License-Identifier: GPL-2.0 >> +/* >> + * Cadence USBSS DRD Driver. >> + * >> + * Copyright (C) 2018 Cadence. >> + * Copyright (C) 2017-2018 NXP >> + * >> + * Author: Peter Chen >> + * Pawel Laszczak >> + */ >> + >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> + >> +#include "gadget.h" >> +#include "core.h" >> +#include "host-export.h" >> +#include "gadget-export.h" >> +#include "drd.h" >> +#include "debug.h" >> + >> +static inline >> +struct cdns3_role_driver *cdns3_get_current_role_driver(struct cdns3 *c= dns) >> +{ >> + WARN_ON(cdns->role >=3D CDNS3_ROLE_END || !cdns->roles[cdns->role]); > >What is someone supposed to do with this? > Generally such concept was created by Peter Chan. He has different platform= .=20 Some time ago he wrote:=20 "The current version of this IP has some issues to detect vbus status corre= ctly, we have to force vbus status accordingly, so we need a status to indicate vbus disconnection, and add some code to let controller know vbus removal, in that case, the controller's state machine can be correct. So, we increase one role 'CDNS3_ROLE_END' to for this purpose. CDNS3_ROLE_GADGET: gadget mode and VBUS on CDNS3_ROLE_HOST: host mode and VBUS on CDNS3_ROLE_END: VBUS off, eg either host or device cable on the port. So, we may start role from CDNS3_ROLE_END at probe when nothing is connecte= d, and need to set role as CDNS3_ROLE_END at ->stop for further handling at role switch routine. " So It's looks like this third state is necessary for his platform and role = =3D=3D CDNS3_ROLE_END is possible but role > CDNS3_ROLE_END is not possible. I know that I could= remove this=20 from code, but I want to be compatible with Peter Chan platform as much as = possible.=20 As far as I know, his platform specific code will be upstreaming in the fut= ure.=20 >> + return cdns->roles[cdns->role]; >> +} >> + >> +static int cdns3_role_start(struct cdns3 *cdns, enum cdns3_roles role) >> +{ >> + int ret; >> + >> + if (WARN_ON(role >=3D CDNS3_ROLE_END)) > >Same here, how can this happen? What can I do if it does? > >> + return 0; >> + >> + if (!cdns->roles[role]) >> + return -ENXIO; >> + >> + if (cdns->roles[role]->state =3D=3D CDNS3_ROLE_STATE_ACTIVE) >> + return 0; >> + >> + mutex_lock(&cdns->mutex); >> + cdns->role =3D role; >> + ret =3D cdns->roles[role]->start(cdns); >> + if (!ret) >> + cdns->roles[role]->state =3D CDNS3_ROLE_STATE_ACTIVE; >> + mutex_unlock(&cdns->mutex); >> + return ret; >> +} >> + >> +void cdns3_role_stop(struct cdns3 *cdns) >> +{ >> + enum cdns3_roles role =3D cdns->role; >> + >> + if (role >=3D CDNS3_ROLE_END) { >> + WARN_ON(role > CDNS3_ROLE_END); > >Again, why? > >> + return; >> + } >> + >> + if (cdns->roles[role]->state =3D=3D CDNS3_ROLE_STATE_INACTIVE) >> + return; >> + >> + mutex_lock(&cdns->mutex); >> + cdns->roles[role]->stop(cdns); >> + cdns->roles[role]->state =3D CDNS3_ROLE_STATE_INACTIVE; >> + mutex_unlock(&cdns->mutex); >> +} >> + >> +/* >> + * cdns->role gets from cdns3_get_initial_role, and this API tells role= at the >> + * runtime. >> + * If both roles are supported, the role is selected based on vbus/id. >> + * It could be read from OTG register or external connector. >> + * If only single role is supported, only one role structure >> + * is allocated, cdns->roles[CDNS3_ROLE_HOST] or cdns->roles[CDNS3_ROLE= _GADGET]. >> + */ >> +static enum cdns3_roles cdns3_get_initial_role(struct cdns3 *cdns) >> +{ >> + if (cdns->roles[CDNS3_ROLE_HOST] && cdns->roles[CDNS3_ROLE_GADGET]) { >> + if (cdns3_is_host(cdns)) >> + return CDNS3_ROLE_HOST; >> + if (cdns3_is_device(cdns)) >> + return CDNS3_ROLE_GADGET; >> + } >> + return cdns->roles[CDNS3_ROLE_HOST] >> + ? CDNS3_ROLE_HOST >> + : CDNS3_ROLE_GADGET; >> +} >> + >> +static void cdns3_exit_roles(struct cdns3 *cdns) >> +{ >> + cdns3_role_stop(cdns); >> + cdns3_drd_exit(cdns); >> +} >> + >> +/** >> + * cdns3_core_init_role - initialize role of operation >> + * @cdns: Pointer to cdns3 structure >> + * >> + * Returns 0 on success otherwise negative errno >> + */ >> +static int cdns3_core_init_role(struct cdns3 *cdns) >> +{ >> + struct device *dev =3D cdns->dev; >> + enum usb_dr_mode best_dr_mode; >> + enum usb_dr_mode dr_mode; >> + int ret =3D 0; >> + >> + dr_mode =3D usb_get_dr_mode(dev); >> + cdns->role =3D CDNS3_ROLE_END; >> + >> + /* >> + * If driver can't read mode by means of usb_get_dr_mdoe function then >> + * chooses mode according with Kernel configuration. This setting >> + * can be restricted later depending on strap pin configuration. >> + */ >> + if (dr_mode =3D=3D USB_DR_MODE_UNKNOWN) { >> + if (IS_ENABLED(CONFIG_USB_CDNS3_HOST) && >> + IS_ENABLED(CONFIG_USB_CDNS3_GADGET)) >> + dr_mode =3D USB_DR_MODE_OTG; >> + else if (IS_ENABLED(CONFIG_USB_CDNS3_HOST)) >> + dr_mode =3D USB_DR_MODE_HOST; >> + else if (IS_ENABLED(CONFIG_USB_CDNS3_GADGET)) >> + dr_mode =3D USB_DR_MODE_PERIPHERAL; >> + } >> + >> + best_dr_mode =3D USB_DR_MODE_OTG; >> + >> + if (dr_mode =3D=3D USB_DR_MODE_OTG) { >> + best_dr_mode =3D cdns->dr_mode; >> + } else if (cdns->dr_mode =3D=3D USB_DR_MODE_OTG) { >> + best_dr_mode =3D dr_mode; >> + } else if (cdns->dr_mode !=3D dr_mode) { >> + dev_err(dev, "Incorrect DRD configuration\n"); >> + return -EINVAL; >> + } >> + >> + dr_mode =3D best_dr_mode; >> + >> + if (dr_mode =3D=3D USB_DR_MODE_OTG || dr_mode =3D=3D USB_DR_MODE_HOST)= { >> + ret =3D cdns3_host_init(cdns); >> + if (ret) { >> + dev_err(dev, "Host initialization failed with %d\n", >> + ret); >> + goto err; >> + } >> + } >> + >> + if (dr_mode =3D=3D USB_DR_MODE_OTG || dr_mode =3D=3D USB_DR_MODE_PERIP= HERAL) { >> + ret =3D cdns3_gadget_init(cdns); >> + if (ret) { >> + dev_err(dev, "Device initialization failed with %d\n", >> + ret); >> + goto err; > >Do you clean up from the host init here properly? It's hard to tell. Driver doesn't have to clean anything here from cdns3_host_init. =20 > >> + } >> + } >> + >> + cdns->desired_dr_mode =3D dr_mode; >> + cdns->dr_mode =3D dr_mode; >> + /* >> + * dr_mode could be change so DRD must update controller >> + * configuration >> + */ >> + ret =3D cdns3_drd_update_mode(cdns); >> + if (ret) >> + goto err; >> + >> + cdns->role =3D cdns3_get_initial_role(cdns); >> + >> + ret =3D cdns3_role_start(cdns, cdns->role); >> + if (ret) { >> + dev_err(dev, "can't start %s role\n", >> + cdns3_get_current_role_driver(cdns)->name); >> + goto err; >> + } >> + >> + return ret; >> +err: >> + cdns3_exit_roles(cdns); >> + return ret; >> +} > >thanks, > >greg k-h Thanks=20 Pawel 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: Pawel Laszczak Message-Id: Date: Mon, 4 Mar 2019 09:23:07 +0000 To: Greg KH Cc: "devicetree@vger.kernel.org" , "felipe.balbi@linux.intel.com" , "mark.rutland@arm.com" , "linux-usb@vger.kernel.org" , "hdegoede@redhat.com" , "heikki.krogerus@linux.intel.com" , "andy.shevchenko@gmail.com" , "robh+dt@kernel.org" , "rogerq@ti.com" , "linux-kernel@vger.kernel.org" , "jbergsagel@ti.com" , "nsekhar@ti.com" , "nm@ti.com" , Suresh Punnoose , "peter.chen@nxp.com" , Rahul Kumar List-ID: SGksIAoKPgo+T24gVGh1LCBGZWIgMTQsIDIwMTkgYXQgMDc6NDU6MTNQTSArMDAwMCwgUGF3ZWwg TGFzemN6YWsgd3JvdGU6Cj4+IFRoaXMgcGF0Y2ggaW50cm9kdWNlIG5ldyBDYWRlbmNlIFVTQlNT IERSRCBkcml2ZXIgdG8gbGludXgga2VybmVsLgo+Cj5OaXQsICJMaW51eCIgOikKPgo+PiBUaGUg Q2FkZW5jZSBVU0JTUyBEUkQgRHJpdmVyIGlzIGEgaGlnaGx5IGNvbmZpZ3VyYWJsZSBJUCBDb3Jl IHdoaWNoaQo+Cj4id2hpY2hpIj8KPgo+PiBjYW4gYmUgaW5zdGFudGlhdGVkIGFzIER1YWwtUm9s ZSBEZXZpY2UgKERSRCksIFBlcmlwaGVyYWwgT25seSBhbmQKPj4gSG9zdCBPbmx5IChYSENJKWNv bmZpZ3VyYXRpb25zLgo+Pgo+PiBUaGUgY3VycmVudCBkcml2ZXIgaGFzIGJlZW4gdmFsaWRhdGVk IHdpdGggRlBHQSBidXJuZWQuIFdlIGhhdmUgc3VwcG9ydAo+Cj5JIGNhbiBub3QgcGFyc2UgdGhh dCBzZW50YW5jZSwgc29ycnkuICB3aGF0IGRvZXMgIndpdGggRlBHQSBidXJuZWQiCj5tZWFuPwoK SSBtZXQgd2l0aCBzdWNoIHNlbnRlbmNlLCBhbmQgSXQncyBtZWFucyB0aGF0IGltcGxlbWVudGF0 aW9uIChJUCBDb3JlKSAKSXMgbG9hZGVkIHRvIEZQR0EuIE1heWJlIGl0IHdhcyB1c2VkIGZyb20g c29tZSBoaXN0b3JpY2FsIHJlYXNvbiwgCmFuZCBub3dhZGF5cyBpdCBpcyBub3QgY29ycmVjdC4g CgpJIHdpbGwgcmVwbGFjZSBpdCB3aXRoICIuLiB3aGljaCBpcyB1c2VkIG9uIEZQR0EgcHJvdG90 eXBpbmcuIgoKPgo+PiBmb3IgUENJZSBidXMsIHdoaWNoIGlzIHVzZWQgb24gRlBHQSBwcm90b3R5 cGluZy4KPj4KPj4gVGhlIGhvc3Qgc2lkZSBvZiBVU0JTUy1EUkQgY29udHJvbGxlciBpcyBjb21w bGlhbmNlIHdpdGggWEhDSQo+Cj4iY29tcGxpYW50Igo+Cj4+IHNwZWNpZmljYXRpb24sIHNvIGl0 IHdvcmtzIHdpdGggc3RhbmRhcmQgWEhDSSBsaW51eCBkcml2ZXIuCj4KPiJMaW51eCIKPgo+Pgo+ PiBTaWduZWQtb2ZmLWJ5OiBQYXdlbCBMYXN6Y3phayA8cGF3ZWxsQGNhZGVuY2UuY29tPgo+PiAt LS0KPj4gIGRyaXZlcnMvdXNiL0tjb25maWcgICAgICAgICAgICAgICAgfCAgICAyICsKPj4gIGRy aXZlcnMvdXNiL01ha2VmaWxlICAgICAgICAgICAgICAgfCAgICAyICsKPj4gIGRyaXZlcnMvdXNi L2NkbnMzL0tjb25maWcgICAgICAgICAgfCAgIDQ0ICsKPj4gIGRyaXZlcnMvdXNiL2NkbnMzL01h a2VmaWxlICAgICAgICAgfCAgIDE0ICsKPj4gIGRyaXZlcnMvdXNiL2NkbnMzL2NkbnMzLXBjaS13 cmFwLmMgfCAgMTU1ICsrKwo+PiAgZHJpdmVycy91c2IvY2RuczMvY29yZS5jICAgICAgICAgICB8 ICA0MDMgKysrKysrCj4+ICBkcml2ZXJzL3VzYi9jZG5zMy9jb3JlLmggICAgICAgICAgIHwgIDEx NiArKwo+PiAgZHJpdmVycy91c2IvY2RuczMvZGVidWcuaCAgICAgICAgICB8ICAxNjggKysrCj4+ ICBkcml2ZXJzL3VzYi9jZG5zMy9kZWJ1Z2ZzLmMgICAgICAgIHwgIDE2NCArKysKPj4gIGRyaXZl cnMvdXNiL2NkbnMzL2RyZC5jICAgICAgICAgICAgfCAgMzY1ICsrKysrCj4+ICBkcml2ZXJzL3Vz Yi9jZG5zMy9kcmQuaCAgICAgICAgICAgIHwgIDE2MiArKysKPj4gIGRyaXZlcnMvdXNiL2NkbnMz L2VwMC5jICAgICAgICAgICAgfCAgOTA3ICsrKysrKysrKysrKysKPj4gIGRyaXZlcnMvdXNiL2Nk bnMzL2dhZGdldC1leHBvcnQuaCAgfCAgIDI4ICsKPj4gIGRyaXZlcnMvdXNiL2NkbnMzL2dhZGdl dC5jICAgICAgICAgfCAyMDAzICsrKysrKysrKysrKysrKysrKysrKysrKysrKysKPj4gIGRyaXZl cnMvdXNiL2NkbnMzL2dhZGdldC5oICAgICAgICAgfCAxMjA3ICsrKysrKysrKysrKysrKysrCj4+ ICBkcml2ZXJzL3VzYi9jZG5zMy9ob3N0LWV4cG9ydC5oICAgIHwgICAyOCArCj4+ICBkcml2ZXJz L3VzYi9jZG5zMy9ob3N0LmMgICAgICAgICAgIHwgICA3MiArCj4+ICBkcml2ZXJzL3VzYi9jZG5z My90cmFjZS5jICAgICAgICAgIHwgICAyMyArCj4+ICBkcml2ZXJzL3VzYi9jZG5zMy90cmFjZS5o ICAgICAgICAgIHwgIDQwNCArKysrKysKPj4gIDE5IGZpbGVzIGNoYW5nZWQsIDYyNjcgaW5zZXJ0 aW9ucygrKQo+PiAgY3JlYXRlIG1vZGUgMTAwNjQ0IGRyaXZlcnMvdXNiL2NkbnMzL0tjb25maWcK Pj4gIGNyZWF0ZSBtb2RlIDEwMDY0NCBkcml2ZXJzL3VzYi9jZG5zMy9NYWtlZmlsZQo+PiAgY3Jl YXRlIG1vZGUgMTAwNjQ0IGRyaXZlcnMvdXNiL2NkbnMzL2NkbnMzLXBjaS13cmFwLmMKPj4gIGNy ZWF0ZSBtb2RlIDEwMDY0NCBkcml2ZXJzL3VzYi9jZG5zMy9jb3JlLmMKPj4gIGNyZWF0ZSBtb2Rl IDEwMDY0NCBkcml2ZXJzL3VzYi9jZG5zMy9jb3JlLmgKPj4gIGNyZWF0ZSBtb2RlIDEwMDY0NCBk cml2ZXJzL3VzYi9jZG5zMy9kZWJ1Zy5oCj4+ICBjcmVhdGUgbW9kZSAxMDA2NDQgZHJpdmVycy91 c2IvY2RuczMvZGVidWdmcy5jCj4+ICBjcmVhdGUgbW9kZSAxMDA2NDQgZHJpdmVycy91c2IvY2Ru czMvZHJkLmMKPj4gIGNyZWF0ZSBtb2RlIDEwMDY0NCBkcml2ZXJzL3VzYi9jZG5zMy9kcmQuaAo+ PiAgY3JlYXRlIG1vZGUgMTAwNjQ0IGRyaXZlcnMvdXNiL2NkbnMzL2VwMC5jCj4+ICBjcmVhdGUg bW9kZSAxMDA2NDQgZHJpdmVycy91c2IvY2RuczMvZ2FkZ2V0LWV4cG9ydC5oCj4+ICBjcmVhdGUg bW9kZSAxMDA2NDQgZHJpdmVycy91c2IvY2RuczMvZ2FkZ2V0LmMKPj4gIGNyZWF0ZSBtb2RlIDEw MDY0NCBkcml2ZXJzL3VzYi9jZG5zMy9nYWRnZXQuaAo+PiAgY3JlYXRlIG1vZGUgMTAwNjQ0IGRy aXZlcnMvdXNiL2NkbnMzL2hvc3QtZXhwb3J0LmgKPj4gIGNyZWF0ZSBtb2RlIDEwMDY0NCBkcml2 ZXJzL3VzYi9jZG5zMy9ob3N0LmMKPj4gIGNyZWF0ZSBtb2RlIDEwMDY0NCBkcml2ZXJzL3VzYi9j ZG5zMy90cmFjZS5jCj4+ICBjcmVhdGUgbW9kZSAxMDA2NDQgZHJpdmVycy91c2IvY2RuczMvdHJh Y2UuaAo+Pgo+PiBkaWZmIC0tZ2l0IGEvZHJpdmVycy91c2IvS2NvbmZpZyBiL2RyaXZlcnMvdXNi L0tjb25maWcKPj4gaW5kZXggOTg3ZmM1YmE2MzIxLi41ZjkzMzQwMTlkMDQgMTAwNjQ0Cj4+IC0t LSBhL2RyaXZlcnMvdXNiL0tjb25maWcKPj4gKysrIGIvZHJpdmVycy91c2IvS2NvbmZpZwo+PiBA QCAtMTEyLDYgKzExMiw4IEBAIHNvdXJjZSAiZHJpdmVycy91c2IvdXNiaXAvS2NvbmZpZyIKPj4K Pj4gIGVuZGlmCj4+Cj4+ICtzb3VyY2UgImRyaXZlcnMvdXNiL2NkbnMzL0tjb25maWciCj4+ICsK Pj4gIHNvdXJjZSAiZHJpdmVycy91c2IvbXR1My9LY29uZmlnIgo+Pgo+PiAgc291cmNlICJkcml2 ZXJzL3VzYi9tdXNiL0tjb25maWciCj4+IGRpZmYgLS1naXQgYS9kcml2ZXJzL3VzYi9NYWtlZmls ZSBiL2RyaXZlcnMvdXNiL01ha2VmaWxlCj4+IGluZGV4IDdkMWI4YzgyYjIwOC4uYWIxMjViOTY2 Y2FjIDEwMDY0NAo+PiAtLS0gYS9kcml2ZXJzL3VzYi9NYWtlZmlsZQo+PiArKysgYi9kcml2ZXJz L3VzYi9NYWtlZmlsZQo+PiBAQCAtMTIsNiArMTIsOCBAQCBvYmotJChDT05GSUdfVVNCX0RXQzMp CQkrPSBkd2MzLwo+PiAgb2JqLSQoQ09ORklHX1VTQl9EV0MyKQkJKz0gZHdjMi8KPj4gIG9iai0k KENPTkZJR19VU0JfSVNQMTc2MCkJKz0gaXNwMTc2MC8KPj4KPj4gK29iai0kKENPTkZJR19VU0Jf Q0ROUzMpCQkrPSBjZG5zMy8KPj4gKwo+PiAgb2JqLSQoQ09ORklHX1VTQl9NT04pCQkrPSBtb24v Cj4+ICBvYmotJChDT05GSUdfVVNCX01UVTMpCQkrPSBtdHUzLwo+Pgo+PiBkaWZmIC0tZ2l0IGEv ZHJpdmVycy91c2IvY2RuczMvS2NvbmZpZyBiL2RyaXZlcnMvdXNiL2NkbnMzL0tjb25maWcKPj4g bmV3IGZpbGUgbW9kZSAxMDA2NDQKPj4gaW5kZXggMDAwMDAwMDAwMDAwLi4yN2NiM2Q4ZGJlM2QK Pj4gLS0tIC9kZXYvbnVsbAo+PiArKysgYi9kcml2ZXJzL3VzYi9jZG5zMy9LY29uZmlnCj4+IEBA IC0wLDAgKzEsNDQgQEAKPj4gK2NvbmZpZyBVU0JfQ0ROUzMKPj4gKwl0cmlzdGF0ZSAiQ2FkZW5j ZSBVU0IzIER1YWwtUm9sZSBDb250cm9sbGVyIgo+PiArCWRlcGVuZHMgb24gVVNCX1NVUFBPUlQg JiYgKFVTQiB8fCBVU0JfR0FER0VUKSAmJiBIQVNfRE1BCj4+ICsJaGVscAo+PiArCSAgU2F5IFkg aGVyZSBpZiB5b3VyIHN5c3RlbSBoYXMgYSBjYWRlbmNlIFVTQjMgZHVhbC1yb2xlIGNvbnRyb2xs ZXIuCj4+ICsJICBJdCBzdXBwb3J0czogZHVhbC1yb2xlIHN3aXRjaCwgSG9zdC1vbmx5LCBhbmQg UGVyaXBoZXJhbC1vbmx5Lgo+PiArCj4+ICsJICBJZiB5b3UgY2hvb3NlIHRvIGJ1aWxkIHRoaXMg ZHJpdmVyIGlzIGEgZHluYW1pY2FsbHkgbGlua2VkCj4+ICsJICBhcyBtb2R1bGUsIHRoZSBtb2R1 bGUgd2lsbCBiZSBjYWxsZWQgY2RuczMua28uCj4+ICsKPj4gK2lmIFVTQl9DRE5TMwo+PiArCj4+ ICtjb25maWcgVVNCX0NETlMzX0dBREdFVAo+PiArICAgICAgICBib29sICJDYWRlbmNlIFVTQjMg ZGV2aWNlIGNvbnRyb2xsZXIiCj4+ICsgICAgICAgIGRlcGVuZHMgb24gVVNCX0dBREdFVAo+PiAr ICAgICAgICBoZWxwCj4+ICsgICAgICAgICAgU2F5IFkgaGVyZSB0byBlbmFibGUgZGV2aWNlIGNv bnRyb2xsZXIgZnVuY3Rpb25hbGl0eSBvZiB0aGUKPj4gKyAgICAgICAgICBjYWRlbmNlIFVTQlNT LURFViBkcml2ZXIuCj4+ICsKPj4gKyAgICAgICAgICBUaGlzIGNvbnRyb2xsZXIgc3VwcG9ydHMg RkYsIEhTIGFuZCBTUyBtb2RlLiBJdCBkb2Vzbid0IHN1cHBvcnQKPj4gKyAgICAgICAgICBMUyBh bmQgU1NQIG1vZGUuCj4+ICsKPj4gK2NvbmZpZyBVU0JfQ0ROUzNfSE9TVAo+PiArICAgICAgICBi b29sICJDYWRlbmNlIFVTQjMgaG9zdCBjb250cm9sbGVyIgo+PiArICAgICAgICBkZXBlbmRzIG9u IFVTQl9YSENJX0hDRAo+PiArICAgICAgICBoZWxwCj4+ICsgICAgICAgICAgU2F5IFkgaGVyZSB0 byBlbmFibGUgaG9zdCBjb250cm9sbGVyIGZ1bmN0aW9uYWxpdHkgb2YgdGhlCj4+ICsgICAgICAg ICAgY2FkZW5jZSBkcml2ZXIuCj4+ICsKPj4gKyAgICAgICAgICBIb3N0IGNvbnRyb2xsZXIgaXMg Y29tcGxpYW50IHdpdGggWEhDSSBzbyBpdCB3aWxsIHVzZQo+PiArICAgICAgICAgIHN0YW5kYXJk IFhIQ0kgZHJpdmVyLgo+PiArCj4+ICtjb25maWcgVVNCX0NETlMzX1BDSV9XUkFQCj4+ICsJdHJp c3RhdGUgIkNhZGVuY2UgVVNCMyBzdXBwb3J0IG9uIFBDSWUtYmFzZWQgcGxhdGZvcm1zIgo+PiAr CWRlcGVuZHMgb24gVVNCX1BDSSAmJiBBQ1BJCj4+ICsJZGVmYXVsdCBVU0JfQ0ROUzMKPj4gKwlo ZWxwCj4+ICsJICBJZiB5b3UncmUgdXNpbmcgdGhlIFVTQlNTIENvcmUgSVAgd2l0aCBhIFBDSWUs IHBsZWFzZSBzYXkKPj4gKwkgICdZJyBvciAnTScgaGVyZS4KPj4gKwo+PiArCSAgSWYgeW91IGNo b29zZSB0byBidWlsZCB0aGlzIGRyaXZlciBhcyBtb2R1bGUgaXQgd2lsbAo+PiArCSAgYmUgZHlu YW1pY2FsbHkgbGlua2VkIGFuZCBtb2R1bGUgd2lsbCBiZSBjYWxsZWQgY2RuczMtcGNpLmtvCj4K PllvdSB1c2UgdGFicyBoZXJlLCBidXQgbm90IHRhYnMgaW4gdGhlIG90aGVyIG9wdGlvbnMuICBQ bGVhc2UgYmUKPnVuaWZvcm0uCj4KPgo+PiArCj4+ICtlbmRpZgo+PiBkaWZmIC0tZ2l0IGEvZHJp dmVycy91c2IvY2RuczMvTWFrZWZpbGUgYi9kcml2ZXJzL3VzYi9jZG5zMy9NYWtlZmlsZQo+PiBu ZXcgZmlsZSBtb2RlIDEwMDY0NAo+PiBpbmRleCAwMDAwMDAwMDAwMDAuLjhmOTQzODU5MzM3NQo+ PiAtLS0gL2Rldi9udWxsCj4+ICsrKyBiL2RyaXZlcnMvdXNiL2NkbnMzL01ha2VmaWxlCj4+IEBA IC0wLDAgKzEsMTQgQEAKPj4gKyMgU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEdQTC0yLjAKPj4g KyMgZGVmaW5lX3RyYWNlLmggbmVlZHMgdG8ga25vdyBob3cgdG8gZmluZCBvdXIgaGVhZGVyCj4+ ICtDRkxBR1NfdHJhY2UubwkJCQk6PSAtSSQoc3JjKQo+PiArCj4+ICtjZG5zMy15CQkJCQk6PSBj b3JlLm8gZHJkLm8gdHJhY2Uubwo+PiArCj4+ICtvYmotJChDT05GSUdfVVNCX0NETlMzKQkJCSs9 IGNkbnMzLm8KPj4gK2lmbmVxICgkKENPTkZJR19ERUJVR19GUyksKQo+PiArCWNkbnMzLXkJCQkJ Kz0gZGVidWdmcy5vCj4+ICtlbmRpZgo+PiArCj4+ICtjZG5zMy0kKENPTkZJR19VU0JfQ0ROUzNf R0FER0VUKQkrPSBnYWRnZXQubyBlcDAubwo+PiArY2RuczMtJChDT05GSUdfVVNCX0NETlMzX0hP U1QpCQkrPSBob3N0Lm8KPj4gK29iai0kKENPTkZJR19VU0JfQ0ROUzNfUENJX1dSQVApCSs9IGNk bnMzLXBjaS13cmFwLm8KPj4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvdXNiL2NkbnMzL2NkbnMzLXBj aS13cmFwLmMgYi9kcml2ZXJzL3VzYi9jZG5zMy9jZG5zMy1wY2ktd3JhcC5jCj4+IG5ldyBmaWxl IG1vZGUgMTAwNjQ0Cj4+IGluZGV4IDAwMDAwMDAwMDAwMC4uZDBiMmQzZDliOTgzCj4+IC0tLSAv ZGV2L251bGwKPj4gKysrIGIvZHJpdmVycy91c2IvY2RuczMvY2RuczMtcGNpLXdyYXAuYwo+PiBA QCAtMCwwICsxLDE1NSBAQAo+PiArLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEdQTC0yLjAK Pj4gKy8qCj4+ICsgKiBDYWRlbmNlIFVTQlNTIFBDSSBHbHVlIGRyaXZlcgo+PiArICoKPj4gKyAq IENvcHlyaWdodCAoQykgMjAxOCBDYWRlbmNlLgo+PiArICoKPj4gKyAqIEF1dGhvcjogUGF3ZWwg TGFzemN6YWsgPHBhd2VsbEBjYWRlbmNlLmNvbT4KPj4gKyAqLwo+PiArCj4+ICsjaW5jbHVkZSA8 bGludXgva2VybmVsLmg+Cj4+ICsjaW5jbHVkZSA8bGludXgvbW9kdWxlLmg+Cj4+ICsjaW5jbHVk ZSA8bGludXgvcGNpLmg+Cj4+ICsjaW5jbHVkZSA8bGludXgvcGxhdGZvcm1fZGV2aWNlLmg+Cj4+ ICsjaW5jbHVkZSA8bGludXgvZG1hLW1hcHBpbmcuaD4KPj4gKyNpbmNsdWRlIDxsaW51eC9zbGFi Lmg+Cj4+ICsKPj4gK3N0cnVjdCBjZG5zM193cmFwIHsKPj4gKwlzdHJ1Y3QgcGxhdGZvcm1fZGV2 aWNlICpwbGF0X2RldjsKPj4gKwlzdHJ1Y3QgcGNpX2RldiAqaGdfZGV2Owo+PiArCXN0cnVjdCBy ZXNvdXJjZSBkZXZfcmVzWzRdOwo+PiArfTsKPj4gKwo+PiArc3RydWN0IGNkbnMzX3dyYXAgd3Jh cDsKPj4gKwo+PiArI2RlZmluZSBSRVNfSVJRX0lECQkwCj4+ICsjZGVmaW5lIFJFU19IT1NUX0lE CQkxCj4+ICsjZGVmaW5lIFJFU19ERVZfSUQJCTIKPj4gKyNkZWZpbmUgUkVTX0RSRF9JRAkJMwo+ PiArCj4+ICsjZGVmaW5lIFBDSV9CQVJfSE9TVAkJMAo+PiArI2RlZmluZSBQQ0lfQkFSX0RFVgkJ Mgo+PiArI2RlZmluZSBQQ0lfQkFSX09URwkJNAo+PiArCj4+ICsjZGVmaW5lIFBDSV9ERVZfRk5f SE9TVF9ERVZJQ0UJMAo+PiArI2RlZmluZSBQQ0lfREVWX0ZOX09URwkJMQo+PiArCj4+ICsjZGVm aW5lIFBDSV9EUklWRVJfTkFNRQkJImNkbnMzLXBjaS11c2JzcyIKPj4gKyNkZWZpbmUgUExBVF9E UklWRVJfTkFNRQkiY2Rucy11c2IzIgo+PiArCj4+ICsjZGVmaW5lIENETlNfVkVORE9SX0lEIDB4 MTdjZAo+Cj5QQ0lfVkVORE9SX0lEX0NETlMgaXMgYWxyZWFkeSBpbiBwY2lfaWRzLmgsIG5vIG5l ZWQgdG8gZGVmaW5lIGl0IGFnYWluCj5oZXJlLgo+Cj4+ICsjZGVmaW5lIENETlNfREVWSUNFX0lE IDB4MDEwMAo+Cj5ObyB0YWJzPwoKQ29ycmVjdGVkLiAKCj4KPj4gKwo+PiArLyoqCj4KPmtlcm5l bGRvYyBpcyBncmVhdCwgYnV0IGZvciBzdGF0aWMgZnVuY3Rpb25zPyAgV2hvIGlzIHB1bGxpbmcg dGhlc2UgaW50bwo+ZG9jdW1lbnRhdGlvbj8KPgo+SWYgbm90LCB0aGVuIG5vIG5lZWQgZm9yIHRo YXQgZm9ybWF0IGF0IGFsbC4KCkknbSBub3Qgc3VyZSBJIHVuZGVyc3Rvb2QgeW91IGNvcnJlY3Qu IAoKU2hvdWxkIEkgcmVtb3ZlIGFsbCBzdGF0aWMgZnVuY3Rpb24gZGVzY3JpcHRpb24sIG9yIHNo b3VsZCBjaGFuZ2UgdGhlCmZvcm1hdHRpbmcgc3R5bGUgdG8gYXZvaWQgcHVsbGluZyBkZXNjcmlw dGlvbiBpbnRvIGRvY3VtZW50YXRpb24gPwoKRm9yIGV4YW1wbGUgaW4gTVRVMyBkcml2ZXIgd2l0 Y2ggaXMgcXVpdGUgbmV3IEkgZm91bmQ6CgoiCi8qCiAqIFNldCBvciBjbGVhciB0aGUgaGFsdCBi aXQgb2YgYW4gRVAuCiAqIEEgaGFsdGVkIEVQIHdvbid0IFRYL1JYIGFueSBkYXRhIGJ1dCB3aWxs IHF1ZXVlIHJlcXVlc3RzLgogKi8Kc3RhdGljIGludCBtdHUzX2dhZGdldF9lcF9zZXRfaGFsdChz dHJ1Y3QgdXNiX2VwICplcCwgaW50IHZhbHVlKSAKIgpXaWxsIGl0IGJlIGNvcnJlY3QgaWYgSSBj aGFuZ2UgY29tbWVudCBmb3JtYXR0aW5nIGZyb206Ci8qKiAKICAqCiAqLwoKSW50byAKICAvKgog ICAqCiAgICovCgo/CgpJIGFzayBiZWNhdXNlIGluIHRoaXMgZnVuY3Rpb24gdGhlIGRlc2NyaXB0 aW9uIGlzIHVubmVjZXNzYXJ5LCBidXQgaW4gc29tZSBvdGhlcgpzdGF0aWMgZnVuY3Rpb25zIHRo ZSBjb21tZW50cyBjb3VsZCBiZSBoZWxwZnVsIGluIHVuZGVyc3RhbmRpbmcgd2hhdCBmdW5jdGlv biBkb2VzLiAKCkN1cnJlbnRseSBJIGhhdmUga2VybmVsZG9jIGZvciBtYW55IHN0YXRpYyBmdW5j dGlvbi4gCgo+PiArICogY2RuczNfcGNpX3Byb2JlIC0gUHJvYmUgZnVuY3Rpb24gZm9yIENhZGVu Y2UgVVNCIHdyYXBwZXIgZHJpdmVyCj4+ICsgKiBAcGRldjogcGxhdGZvcm0gZGV2aWNlIG9iamVj dAo+PiArICogQGlkOiBwY2kgZGV2aWNlIGlkCj4+ICsgKgo+PiArICogUmV0dXJucyAwIG9uIHN1 Y2Nlc3Mgb3RoZXJ3aXNlIG5lZ2F0aXZlIGVycm5vCj4+ICsgKi8KPj4gK3N0YXRpYyBpbnQgY2Ru czNfcGNpX3Byb2JlKHN0cnVjdCBwY2lfZGV2ICpwZGV2LAo+PiArCQkJICAgY29uc3Qgc3RydWN0 IHBjaV9kZXZpY2VfaWQgKmlkKQo+PiArewo+PiArCXN0cnVjdCBwbGF0Zm9ybV9kZXZpY2VfaW5m byBwbGF0X2luZm87Cj4+ICsJc3RydWN0IGNkbnMzX3dyYXAgKndyYXA7Cj4+ICsJc3RydWN0IHJl c291cmNlICpyZXM7Cj4+ICsJaW50IGVycjsKPj4gKwo+PiArCS8qCj4+ICsJICogZm9yIEdBREdF VC9IT1NUIFBDSSAoZGV2Zm4pIGZ1bmN0aW9uIG51bWJlciBpcyAwLAo+PiArCSAqIGZvciBPVEcg UENJIChkZXZmbikgZnVuY3Rpb24gbnVtYmVyIGlzIDEKPj4gKwkgKi8KPj4gKwlpZiAoIWlkIHx8 IHBkZXYtPmRldmZuICE9IFBDSV9ERVZfRk5fSE9TVF9ERVZJQ0UpCj4+ICsJCXJldHVybiAtRUlO VkFMOwo+PiArCj4+ICsJZXJyID0gcGNpbV9lbmFibGVfZGV2aWNlKHBkZXYpOwo+PiArCWlmIChl cnIpIHsKPj4gKwkJZGV2X2VycigmcGRldi0+ZGV2LCAiRW5hYmxpbmcgUENJIGRldmljZSBoYXMg ZmFpbGVkICVkXG4iLCBlcnIpOwo+PiArCQlyZXR1cm4gZXJyOwo+PiArCX0KPj4gKwo+PiArCXBj aV9zZXRfbWFzdGVyKHBkZXYpOwo+PiArCXdyYXAgPSBkZXZtX2t6YWxsb2MoJnBkZXYtPmRldiwg c2l6ZW9mKCp3cmFwKSwgR0ZQX0tFUk5FTCk7Cj4+ICsJaWYgKCF3cmFwKSB7Cj4+ICsJCWRldl9l cnIoJnBkZXYtPmRldiwgIkZhaWxlZCB0byBhbGxvY2F0ZSBtZW1vcnlcbiIpOwo+Cj5ObyBuZWVk IHRvIHByaW50IGFuIGVycm9yIGFnYWluIGFmdGVyIGt6YWxsb2MgYWxyZWFkeSBwcmludGVkIGFu IGVycm9yLgoKT2ssIEkgZGlkbid0IGtub3cuIAoKPgo+PiArCQlyZXR1cm4gLUVOT01FTTsKPgo+ RGlkIHlvdSBmb3JnZXQgdG8gZGlzYWJsZSB0aGUgcGNpIGRldmljZT8KClllcywgSSByZWFsbHkg Zm9yZ290LiAKCj4+ICsJfQo+PiArCj4+ICsJLyogZnVuY3Rpb24gMDogaG9zdChCQVJfMCkgKyBk ZXZpY2UoQkFSXzEpICsgb3RnKEJBUl8yKSkuICovCj4+ICsJbWVtc2V0KHdyYXAtPmRldl9yZXMs IDB4MDAsCj4+ICsJICAgICAgIHNpemVvZihzdHJ1Y3QgcmVzb3VyY2UpICogQVJSQVlfU0laRSh3 cmFwLT5kZXZfcmVzKSk7Cj4+ICsJZGV2X2RiZygmcGRldi0+ZGV2LCAiSW5pdGlhbGl6ZSBEZXZp Y2UgcmVzb3VyY2VzXG4iKTsKPj4gKwlyZXMgPSB3cmFwLT5kZXZfcmVzOwo+PiArCj4+ICsJcmVz W1JFU19ERVZfSURdLnN0YXJ0ID0gcGNpX3Jlc291cmNlX3N0YXJ0KHBkZXYsIFBDSV9CQVJfREVW KTsKPj4gKwlyZXNbUkVTX0RFVl9JRF0uZW5kID0gICBwY2lfcmVzb3VyY2VfZW5kKHBkZXYsIFBD SV9CQVJfREVWKTsKPj4gKwlyZXNbUkVTX0RFVl9JRF0ubmFtZSA9ICJkZXYiOwo+PiArCXJlc1tS RVNfREVWX0lEXS5mbGFncyA9IElPUkVTT1VSQ0VfTUVNOwo+PiArCWRldl9kYmcoJnBkZXYtPmRl diwgIlVTQlNTLURFViBwaHlzaWNhbCBiYXNlIGFkZHI6ICVwYVxuIiwKPj4gKwkJJnJlc1tSRVNf REVWX0lEXS5zdGFydCk7Cj4+ICsKPj4gKwlyZXNbUkVTX0hPU1RfSURdLnN0YXJ0ID0gcGNpX3Jl c291cmNlX3N0YXJ0KHBkZXYsIFBDSV9CQVJfSE9TVCk7Cj4+ICsJcmVzW1JFU19IT1NUX0lEXS5l bmQgPSBwY2lfcmVzb3VyY2VfZW5kKHBkZXYsIFBDSV9CQVJfSE9TVCk7Cj4+ICsJcmVzW1JFU19I T1NUX0lEXS5uYW1lID0gInhoY2kiOwo+PiArCXJlc1tSRVNfSE9TVF9JRF0uZmxhZ3MgPSBJT1JF U09VUkNFX01FTTsKPj4gKwlkZXZfZGJnKCZwZGV2LT5kZXYsICJVU0JTUy1YSENJIHBoeXNpY2Fs IGJhc2UgYWRkcjogJXBhXG4iLAo+PiArCQkmcmVzW1JFU19IT1NUX0lEXS5zdGFydCk7Cj4+ICsK Pj4gKwlyZXNbUkVTX0RSRF9JRF0uc3RhcnQgPSBwY2lfcmVzb3VyY2Vfc3RhcnQocGRldiwgUENJ X0JBUl9PVEcpOwo+PiArCXJlc1tSRVNfRFJEX0lEXS5lbmQgPSAgIHBjaV9yZXNvdXJjZV9lbmQo cGRldiwgUENJX0JBUl9PVEcpOwo+PiArCXJlc1tSRVNfRFJEX0lEXS5uYW1lID0gIm90ZyI7Cj4+ ICsJcmVzW1JFU19EUkRfSURdLmZsYWdzID0gSU9SRVNPVVJDRV9NRU07Cj4+ICsJZGV2X2RiZygm cGRldi0+ZGV2LCAiVVNCU1MtRFJEIHBoeXNpY2FsIGJhc2UgYWRkcjogJXBhXG4iLAo+PiArCQkm cmVzW1JFU19EUkRfSURdLnN0YXJ0KTsKPj4gKwo+PiArCS8qIEludGVycnVwdCBjb21tb24gZm9y IGJvdGggZGV2aWNlIGFuZCBYSENJICovCj4+ICsJd3JhcC0+ZGV2X3Jlc1tSRVNfSVJRX0lEXS5z dGFydCA9IHBkZXYtPmlycTsKPj4gKwl3cmFwLT5kZXZfcmVzW1JFU19JUlFfSURdLm5hbWUgPSAi Y2RuczMtaXJxIjsKPj4gKwl3cmFwLT5kZXZfcmVzW1JFU19JUlFfSURdLmZsYWdzID0gSU9SRVNP VVJDRV9JUlE7Cj4+ICsKPj4gKwkvKiBzZXQgdXAgcGxhdGZvcm0gZGV2aWNlIGluZm8gKi8KPj4g KwltZW1zZXQoJnBsYXRfaW5mbywgMCwgc2l6ZW9mKHBsYXRfaW5mbykpOwo+PiArCXBsYXRfaW5m by5wYXJlbnQgPSAmcGRldi0+ZGV2Owo+PiArCXBsYXRfaW5mby5md25vZGUgPSBwZGV2LT5kZXYu Zndub2RlOwo+PiArCXBsYXRfaW5mby5uYW1lID0gUExBVF9EUklWRVJfTkFNRTsKPj4gKwlwbGF0 X2luZm8uaWQgPSBwZGV2LT5kZXZmbjsKPj4gKwlwbGF0X2luZm8ucmVzID0gd3JhcC0+ZGV2X3Jl czsKPj4gKwlwbGF0X2luZm8ubnVtX3JlcyA9IEFSUkFZX1NJWkUod3JhcC0+ZGV2X3Jlcyk7Cj4+ ICsJcGxhdF9pbmZvLmRtYV9tYXNrID0gcGRldi0+ZG1hX21hc2s7Cj4+ICsKPj4gKwkvKiByZWdp c3RlciBwbGF0Zm9ybSBkZXZpY2UgKi8KPj4gKwl3cmFwLT5wbGF0X2RldiA9IHBsYXRmb3JtX2Rl dmljZV9yZWdpc3Rlcl9mdWxsKCZwbGF0X2luZm8pOwo+PiArCWlmIChJU19FUlIod3JhcC0+cGxh dF9kZXYpKQo+PiArCQlyZXR1cm4gUFRSX0VSUih3cmFwLT5wbGF0X2Rldik7Cj4KPk5vIGRpc2Fi bGluZyBvZiB0aGUgZGV2aWNlPwo+Cj5Bbnl3YXksIHdoeSBhcmUgeW91IGNyZWF0aW5nIGEgcGxh dGZvcm0gZGV2aWNlIHdoZW4geW91IGhhdmUgYSByZWFsIFBDSQo+ZGV2aWNlPyAgVGhhdCBzZWVt cyBvZGQsIGFuZCBhbiBhYnVzZSBvZiB0aGUgcGxhdGZvcm0gY29kZS4gIFdoYXQncwo+d3Jvbmcg d2l0aCB5b3VyIHJlYWwgUENJIGRldmljZSBoZXJlPwoKSSB1c2UgUENJIHBsYXRmb3JtLCBidXQg dGhlIG1vc3Qgb3VyIGN1c3RvbWVycyB1c2UgdGhpcyBkcml2ZXIgYXMgcGxhdGZvcm0gCmRyaXZl ci4gClRoZSBzZWNvbmQgcmVhc29uIHdhcyB0aGF0IHdlIHVzZSAgZGlmZmVyZW50IFBDSSBjb25m aWd1cmF0aW9uLCBhbmQgc29tZSBvZiB0aGVtIAptYWtlcyBpdCBpbXBvc3NpYmxlIHRvIHVzZSBE UkQgZHJpdmVyIGFzIHNpbmdsZSBkcml2ZXIuICBGb3IgZXhhbXBsZSBQQ0kgZnVuY3Rpb24KMCBj b250YWlucyBEZXZpY2UvSG9zdCByZWdpc3RlciwgYW5kIFBDSSBmdW5jdGlvbiAxIGNvbnRhaW5z IE9URyByZWdpc3Rlci4gCgo+Cj4KPj4gKwo+PiArCXBjaV9zZXRfZHJ2ZGF0YShwZGV2LCB3cmFw KTsKPj4gKwo+PiArCXJldHVybiBlcnI7Cj4+ICt9Cj4+ICsKPj4gK3ZvaWQgY2RuczNfcGNpX3Jl bW92ZShzdHJ1Y3QgcGNpX2RldiAqcGRldikKPj4gK3sKPj4gKwlzdHJ1Y3QgY2RuczNfd3JhcCAq d3JhcCA9IChzdHJ1Y3QgY2RuczNfd3JhcCAqKXBjaV9nZXRfZHJ2ZGF0YShwZGV2KTsKPj4gKwo+ PiArCXBsYXRmb3JtX2RldmljZV91bnJlZ2lzdGVyKHdyYXAtPnBsYXRfZGV2KTsKPj4gK30KPj4g Kwo+PiArc3RhdGljIGNvbnN0IHN0cnVjdCBwY2lfZGV2aWNlX2lkIGNkbnMzX3BjaV9pZHNbXSA9 IHsKPj4gKwl7IFBDSV9ERVZJQ0UoQ0ROU19WRU5ET1JfSUQsIENETlNfREVWSUNFX0lEKSwgfSwK Pj4gKwl7IDAsIH0KPj4gK307Cj4+ICsKPj4gK3N0YXRpYyBzdHJ1Y3QgcGNpX2RyaXZlciBjZG5z M19wY2lfZHJpdmVyID0gewo+PiArCS5uYW1lID0gUENJX0RSSVZFUl9OQU1FLAo+PiArCS5pZF90 YWJsZSA9IGNkbnMzX3BjaV9pZHMsCj4+ICsJLnByb2JlID0gY2RuczNfcGNpX3Byb2JlLAo+PiAr CS5yZW1vdmUgPSBjZG5zM19wY2lfcmVtb3ZlLAo+PiArfTsKPj4gKwo+PiArbW9kdWxlX3BjaV9k cml2ZXIoY2RuczNfcGNpX2RyaXZlcik7Cj4+ICtNT0RVTEVfREVWSUNFX1RBQkxFKHBjaSwgY2Ru czNfcGNpX2lkcyk7Cj4+ICsKPj4gK01PRFVMRV9BVVRIT1IoIlBhd2VsIExhc3pjemFrIDxwYXdl bGxAY2FkZW5jZS5jb20+Iik7Cj4+ICtNT0RVTEVfTElDRU5TRSgiR1BMIHYyIik7Cj4+ICtNT0RV TEVfREVTQ1JJUFRJT04oIkNhZGVuY2UgVVNCU1MgUENJIHdyYXBwZXJyIik7Cj4+ICsKPj4gZGlm ZiAtLWdpdCBhL2RyaXZlcnMvdXNiL2NkbnMzL2NvcmUuYyBiL2RyaXZlcnMvdXNiL2NkbnMzL2Nv cmUuYwo+PiBuZXcgZmlsZSBtb2RlIDEwMDY0NAo+PiBpbmRleCAwMDAwMDAwMDAwMDAuLmFhMmY2 MzI0MWRhYgo+PiAtLS0gL2Rldi9udWxsCj4+ICsrKyBiL2RyaXZlcnMvdXNiL2NkbnMzL2NvcmUu Ywo+PiBAQCAtMCwwICsxLDQwMyBAQAo+PiArLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEdQ TC0yLjAKPj4gKy8qCj4+ICsgKiBDYWRlbmNlIFVTQlNTIERSRCBEcml2ZXIuCj4+ICsgKgo+PiAr ICogQ29weXJpZ2h0IChDKSAyMDE4IENhZGVuY2UuCj4+ICsgKiBDb3B5cmlnaHQgKEMpIDIwMTct MjAxOCBOWFAKPj4gKyAqCj4+ICsgKiBBdXRob3I6IFBldGVyIENoZW4gPHBldGVyLmNoZW5Abnhw LmNvbT4KPj4gKyAqICAgICAgICAgUGF3ZWwgTGFzemN6YWsgPHBhd2VsbEBjYWRlbmNlLmNvbT4K Pj4gKyAqLwo+PiArCj4+ICsjaW5jbHVkZSA8bGludXgvbW9kdWxlLmg+Cj4+ICsjaW5jbHVkZSA8 bGludXgva2VybmVsLmg+Cj4+ICsjaW5jbHVkZSA8bGludXgvcGxhdGZvcm1fZGV2aWNlLmg+Cj4+ ICsjaW5jbHVkZSA8bGludXgvaW50ZXJydXB0Lmg+Cj4+ICsjaW5jbHVkZSA8bGludXgvaW8uaD4K Pj4gKyNpbmNsdWRlIDxsaW51eC9wbV9ydW50aW1lLmg+Cj4+ICsKPj4gKyNpbmNsdWRlICJnYWRn ZXQuaCIKPj4gKyNpbmNsdWRlICJjb3JlLmgiCj4+ICsjaW5jbHVkZSAiaG9zdC1leHBvcnQuaCIK Pj4gKyNpbmNsdWRlICJnYWRnZXQtZXhwb3J0LmgiCj4+ICsjaW5jbHVkZSAiZHJkLmgiCj4+ICsj aW5jbHVkZSAiZGVidWcuaCIKPj4gKwo+PiArc3RhdGljIGlubGluZQo+PiArc3RydWN0IGNkbnMz X3JvbGVfZHJpdmVyICpjZG5zM19nZXRfY3VycmVudF9yb2xlX2RyaXZlcihzdHJ1Y3QgY2RuczMg KmNkbnMpCj4+ICt7Cj4+ICsJV0FSTl9PTihjZG5zLT5yb2xlID49IENETlMzX1JPTEVfRU5EIHx8 ICFjZG5zLT5yb2xlc1tjZG5zLT5yb2xlXSk7Cj4KPldoYXQgaXMgc29tZW9uZSBzdXBwb3NlZCB0 byBkbyB3aXRoIHRoaXM/Cj4KCkdlbmVyYWxseSBzdWNoIGNvbmNlcHQgd2FzIGNyZWF0ZWQgYnkg UGV0ZXIgQ2hhbi4gSGUgaGFzIGRpZmZlcmVudCBwbGF0Zm9ybS4gClNvbWUgdGltZSBhZ28gaGUg d3JvdGU6IAoiVGhlIGN1cnJlbnQgdmVyc2lvbiBvZiB0aGlzIElQIGhhcyBzb21lIGlzc3VlcyB0 byBkZXRlY3QgdmJ1cyBzdGF0dXMgY29ycmVjdGx5LAp3ZSBoYXZlIHRvIGZvcmNlIHZidXMgc3Rh dHVzIGFjY29yZGluZ2x5LCBzbyB3ZSBuZWVkIGEgc3RhdHVzIHRvIGluZGljYXRlCnZidXMgZGlz Y29ubmVjdGlvbiwgYW5kIGFkZCBzb21lIGNvZGUgdG8gbGV0IGNvbnRyb2xsZXIga25vdyB2YnVz CnJlbW92YWwsIGluIHRoYXQgY2FzZSwgdGhlIGNvbnRyb2xsZXIncyBzdGF0ZSBtYWNoaW5lIGNh biBiZSBjb3JyZWN0LgpTbywgd2UgaW5jcmVhc2Ugb25lIHJvbGUgJ0NETlMzX1JPTEVfRU5EJyB0 byBmb3IgdGhpcyBwdXJwb3NlLgoKQ0ROUzNfUk9MRV9HQURHRVQ6IGdhZGdldCBtb2RlIGFuZCBW QlVTIG9uCkNETlMzX1JPTEVfSE9TVDogaG9zdCBtb2RlIGFuZCBWQlVTIG9uCkNETlMzX1JPTEVf RU5EOiBWQlVTIG9mZiwgZWcgZWl0aGVyIGhvc3Qgb3IgZGV2aWNlIGNhYmxlIG9uIHRoZSBwb3J0 LgoKU28sIHdlIG1heSBzdGFydCByb2xlIGZyb20gQ0ROUzNfUk9MRV9FTkQgYXQgcHJvYmUgd2hl biBub3RoaW5nIGlzIGNvbm5lY3RlZCwKYW5kIG5lZWQgdG8gc2V0IHJvbGUgYXMgQ0ROUzNfUk9M RV9FTkQgYXQgLT5zdG9wIGZvciBmdXJ0aGVyIGhhbmRsaW5nIGF0CnJvbGUgc3dpdGNoIHJvdXRp bmUuICIKClNvIEl0J3MgbG9va3MgbGlrZSB0aGlzIHRoaXJkIHN0YXRlIGlzIG5lY2Vzc2FyeSBm b3IgaGlzIHBsYXRmb3JtIGFuZCByb2xlID09IENETlMzX1JPTEVfRU5ECmlzIHBvc3NpYmxlIGJ1 dCByb2xlID4gQ0ROUzNfUk9MRV9FTkQgaXMgbm90IHBvc3NpYmxlLiAgSSBrbm93IHRoYXQgSSBj b3VsZCByZW1vdmUgdGhpcyAKZnJvbSBjb2RlLCBidXQgSSB3YW50IHRvIGJlIGNvbXBhdGlibGUg d2l0aCBQZXRlciBDaGFuIHBsYXRmb3JtIGFzIG11Y2ggYXMgcG9zc2libGUuIApBcyBmYXIgYXMg SSBrbm93LCBoaXMgcGxhdGZvcm0gc3BlY2lmaWMgY29kZSB3aWxsIGJlIHVwc3RyZWFtaW5nIGlu IHRoZSBmdXR1cmUuIAoKPj4gKwlyZXR1cm4gY2Rucy0+cm9sZXNbY2Rucy0+cm9sZV07Cj4+ICt9 Cj4+ICsKPj4gK3N0YXRpYyBpbnQgY2RuczNfcm9sZV9zdGFydChzdHJ1Y3QgY2RuczMgKmNkbnMs IGVudW0gY2RuczNfcm9sZXMgcm9sZSkKPj4gK3sKPj4gKwlpbnQgcmV0Owo+PiArCj4+ICsJaWYg KFdBUk5fT04ocm9sZSA+PSBDRE5TM19ST0xFX0VORCkpCj4KPlNhbWUgaGVyZSwgaG93IGNhbiB0 aGlzIGhhcHBlbj8gIFdoYXQgY2FuIEkgZG8gaWYgaXQgZG9lcz8KCj4KPj4gKwkJcmV0dXJuIDA7 Cj4+ICsKPj4gKwlpZiAoIWNkbnMtPnJvbGVzW3JvbGVdKQo+PiArCQlyZXR1cm4gLUVOWElPOwo+ PiArCj4+ICsJaWYgKGNkbnMtPnJvbGVzW3JvbGVdLT5zdGF0ZSA9PSBDRE5TM19ST0xFX1NUQVRF X0FDVElWRSkKPj4gKwkJcmV0dXJuIDA7Cj4+ICsKPj4gKwltdXRleF9sb2NrKCZjZG5zLT5tdXRl eCk7Cj4+ICsJY2Rucy0+cm9sZSA9IHJvbGU7Cj4+ICsJcmV0ID0gY2Rucy0+cm9sZXNbcm9sZV0t PnN0YXJ0KGNkbnMpOwo+PiArCWlmICghcmV0KQo+PiArCQljZG5zLT5yb2xlc1tyb2xlXS0+c3Rh dGUgPSBDRE5TM19ST0xFX1NUQVRFX0FDVElWRTsKPj4gKwltdXRleF91bmxvY2soJmNkbnMtPm11 dGV4KTsKPj4gKwlyZXR1cm4gcmV0Owo+PiArfQo+PiArCj4+ICt2b2lkIGNkbnMzX3JvbGVfc3Rv cChzdHJ1Y3QgY2RuczMgKmNkbnMpCj4+ICt7Cj4+ICsJZW51bSBjZG5zM19yb2xlcyByb2xlID0g Y2Rucy0+cm9sZTsKPj4gKwo+PiArCWlmIChyb2xlID49IENETlMzX1JPTEVfRU5EKSB7Cj4+ICsJ CVdBUk5fT04ocm9sZSA+IENETlMzX1JPTEVfRU5EKTsKPgo+QWdhaW4sIHdoeT8KPgo+PiArCQly ZXR1cm47Cj4+ICsJfQo+PiArCj4+ICsJaWYgKGNkbnMtPnJvbGVzW3JvbGVdLT5zdGF0ZSA9PSBD RE5TM19ST0xFX1NUQVRFX0lOQUNUSVZFKQo+PiArCQlyZXR1cm47Cj4+ICsKPj4gKwltdXRleF9s b2NrKCZjZG5zLT5tdXRleCk7Cj4+ICsJY2Rucy0+cm9sZXNbcm9sZV0tPnN0b3AoY2Rucyk7Cj4+ ICsJY2Rucy0+cm9sZXNbcm9sZV0tPnN0YXRlID0gQ0ROUzNfUk9MRV9TVEFURV9JTkFDVElWRTsK Pj4gKwltdXRleF91bmxvY2soJmNkbnMtPm11dGV4KTsKPj4gK30KPj4gKwo+PiArLyoKPj4gKyAq IGNkbnMtPnJvbGUgZ2V0cyBmcm9tIGNkbnMzX2dldF9pbml0aWFsX3JvbGUsIGFuZCB0aGlzIEFQ SSB0ZWxscyByb2xlIGF0IHRoZQo+PiArICogcnVudGltZS4KPj4gKyAqIElmIGJvdGggcm9sZXMg YXJlIHN1cHBvcnRlZCwgdGhlIHJvbGUgaXMgc2VsZWN0ZWQgYmFzZWQgb24gdmJ1cy9pZC4KPj4g KyAqIEl0IGNvdWxkIGJlIHJlYWQgZnJvbSBPVEcgcmVnaXN0ZXIgb3IgZXh0ZXJuYWwgY29ubmVj dG9yLgo+PiArICogSWYgb25seSBzaW5nbGUgcm9sZSBpcyBzdXBwb3J0ZWQsIG9ubHkgb25lIHJv bGUgc3RydWN0dXJlCj4+ICsgKiBpcyBhbGxvY2F0ZWQsIGNkbnMtPnJvbGVzW0NETlMzX1JPTEVf SE9TVF0gb3IgY2Rucy0+cm9sZXNbQ0ROUzNfUk9MRV9HQURHRVRdLgo+PiArICovCj4+ICtzdGF0 aWMgZW51bSBjZG5zM19yb2xlcyBjZG5zM19nZXRfaW5pdGlhbF9yb2xlKHN0cnVjdCBjZG5zMyAq Y2RucykKPj4gK3sKPj4gKwlpZiAoY2Rucy0+cm9sZXNbQ0ROUzNfUk9MRV9IT1NUXSAmJiBjZG5z LT5yb2xlc1tDRE5TM19ST0xFX0dBREdFVF0pIHsKPj4gKwkJaWYgKGNkbnMzX2lzX2hvc3QoY2Ru cykpCj4+ICsJCQlyZXR1cm4gQ0ROUzNfUk9MRV9IT1NUOwo+PiArCQlpZiAoY2RuczNfaXNfZGV2 aWNlKGNkbnMpKQo+PiArCQkJcmV0dXJuIENETlMzX1JPTEVfR0FER0VUOwo+PiArCX0KPj4gKwly ZXR1cm4gY2Rucy0+cm9sZXNbQ0ROUzNfUk9MRV9IT1NUXQo+PiArCQk/IENETlMzX1JPTEVfSE9T VAo+PiArCQk6IENETlMzX1JPTEVfR0FER0VUOwo+PiArfQo+PiArCj4+ICtzdGF0aWMgdm9pZCBj ZG5zM19leGl0X3JvbGVzKHN0cnVjdCBjZG5zMyAqY2RucykKPj4gK3sKPj4gKwljZG5zM19yb2xl X3N0b3AoY2Rucyk7Cj4+ICsJY2RuczNfZHJkX2V4aXQoY2Rucyk7Cj4+ICt9Cj4+ICsKPj4gKy8q Kgo+PiArICogY2RuczNfY29yZV9pbml0X3JvbGUgLSBpbml0aWFsaXplIHJvbGUgb2Ygb3BlcmF0 aW9uCj4+ICsgKiBAY2RuczogUG9pbnRlciB0byBjZG5zMyBzdHJ1Y3R1cmUKPj4gKyAqCj4+ICsg KiBSZXR1cm5zIDAgb24gc3VjY2VzcyBvdGhlcndpc2UgbmVnYXRpdmUgZXJybm8KPj4gKyAqLwo+ PiArc3RhdGljIGludCBjZG5zM19jb3JlX2luaXRfcm9sZShzdHJ1Y3QgY2RuczMgKmNkbnMpCj4+ ICt7Cj4+ICsJc3RydWN0IGRldmljZSAqZGV2ID0gY2Rucy0+ZGV2Owo+PiArCWVudW0gdXNiX2Ry X21vZGUgYmVzdF9kcl9tb2RlOwo+PiArCWVudW0gdXNiX2RyX21vZGUgZHJfbW9kZTsKPj4gKwlp bnQgcmV0ID0gMDsKPj4gKwo+PiArCWRyX21vZGUgPSB1c2JfZ2V0X2RyX21vZGUoZGV2KTsKPj4g KwljZG5zLT5yb2xlID0gQ0ROUzNfUk9MRV9FTkQ7Cj4+ICsKPj4gKwkvKgo+PiArCSAqIElmIGRy aXZlciBjYW4ndCByZWFkIG1vZGUgYnkgbWVhbnMgb2YgdXNiX2dldF9kcl9tZG9lIGZ1bmN0aW9u IHRoZW4KPj4gKwkgKiBjaG9vc2VzIG1vZGUgYWNjb3JkaW5nIHdpdGggS2VybmVsIGNvbmZpZ3Vy YXRpb24uIFRoaXMgc2V0dGluZwo+PiArCSAqIGNhbiBiZSByZXN0cmljdGVkIGxhdGVyIGRlcGVu ZGluZyBvbiBzdHJhcCBwaW4gY29uZmlndXJhdGlvbi4KPj4gKwkgKi8KPj4gKwlpZiAoZHJfbW9k ZSA9PSBVU0JfRFJfTU9ERV9VTktOT1dOKSB7Cj4+ICsJCWlmIChJU19FTkFCTEVEKENPTkZJR19V U0JfQ0ROUzNfSE9TVCkgJiYKPj4gKwkJICAgIElTX0VOQUJMRUQoQ09ORklHX1VTQl9DRE5TM19H QURHRVQpKQo+PiArCQkJZHJfbW9kZSA9IFVTQl9EUl9NT0RFX09URzsKPj4gKwkJZWxzZSBpZiAo SVNfRU5BQkxFRChDT05GSUdfVVNCX0NETlMzX0hPU1QpKQo+PiArCQkJZHJfbW9kZSA9IFVTQl9E Ul9NT0RFX0hPU1Q7Cj4+ICsJCWVsc2UgaWYgKElTX0VOQUJMRUQoQ09ORklHX1VTQl9DRE5TM19H QURHRVQpKQo+PiArCQkJZHJfbW9kZSA9IFVTQl9EUl9NT0RFX1BFUklQSEVSQUw7Cj4+ICsJfQo+ PiArCj4+ICsJYmVzdF9kcl9tb2RlID0gVVNCX0RSX01PREVfT1RHOwo+PiArCj4+ICsJaWYgKGRy X21vZGUgPT0gVVNCX0RSX01PREVfT1RHKSB7Cj4+ICsJCWJlc3RfZHJfbW9kZSA9IGNkbnMtPmRy X21vZGU7Cj4+ICsJfSBlbHNlIGlmIChjZG5zLT5kcl9tb2RlID09IFVTQl9EUl9NT0RFX09URykg ewo+PiArCQliZXN0X2RyX21vZGUgPSBkcl9tb2RlOwo+PiArCX0gZWxzZSBpZiAoY2Rucy0+ZHJf bW9kZSAhPSBkcl9tb2RlKSB7Cj4+ICsJCWRldl9lcnIoZGV2LCAiSW5jb3JyZWN0IERSRCBjb25m aWd1cmF0aW9uXG4iKTsKPj4gKwkJcmV0dXJuIC1FSU5WQUw7Cj4+ICsJfQo+PiArCj4+ICsJZHJf bW9kZSA9IGJlc3RfZHJfbW9kZTsKPj4gKwo+PiArCWlmIChkcl9tb2RlID09IFVTQl9EUl9NT0RF X09URyB8fCBkcl9tb2RlID09IFVTQl9EUl9NT0RFX0hPU1QpIHsKPj4gKwkJcmV0ID0gY2RuczNf aG9zdF9pbml0KGNkbnMpOwo+PiArCQlpZiAocmV0KSB7Cj4+ICsJCQlkZXZfZXJyKGRldiwgIkhv c3QgaW5pdGlhbGl6YXRpb24gZmFpbGVkIHdpdGggJWRcbiIsCj4+ICsJCQkJcmV0KTsKPj4gKwkJ CWdvdG8gZXJyOwo+PiArCQl9Cj4+ICsJfQo+PiArCj4+ICsJaWYgKGRyX21vZGUgPT0gVVNCX0RS X01PREVfT1RHIHx8IGRyX21vZGUgPT0gVVNCX0RSX01PREVfUEVSSVBIRVJBTCkgewo+PiArCQly ZXQgPSBjZG5zM19nYWRnZXRfaW5pdChjZG5zKTsKPj4gKwkJaWYgKHJldCkgewo+PiArCQkJZGV2 X2VycihkZXYsICJEZXZpY2UgaW5pdGlhbGl6YXRpb24gZmFpbGVkIHdpdGggJWRcbiIsCj4+ICsJ CQkJcmV0KTsKPj4gKwkJCWdvdG8gZXJyOwo+Cj5EbyB5b3UgY2xlYW4gdXAgZnJvbSB0aGUgaG9z dCBpbml0IGhlcmUgcHJvcGVybHk/ICAgSXQncyBoYXJkIHRvIHRlbGwuCgpEcml2ZXIgZG9lc24n dCBoYXZlIHRvIGNsZWFuIGFueXRoaW5nIGhlcmUgZnJvbSBjZG5zM19ob3N0X2luaXQuCiAKPgo+ PiArCQl9Cj4+ICsJfQo+PiArCj4+ICsJY2Rucy0+ZGVzaXJlZF9kcl9tb2RlID0gZHJfbW9kZTsK Pj4gKwljZG5zLT5kcl9tb2RlID0gZHJfbW9kZTsKPj4gKwkvKgo+PiArCSAqIGRyX21vZGUgY291 bGQgYmUgY2hhbmdlIHNvIERSRCBtdXN0IHVwZGF0ZSBjb250cm9sbGVyCj4+ICsJICogY29uZmln dXJhdGlvbgo+PiArCSAqLwo+PiArCXJldCA9IGNkbnMzX2RyZF91cGRhdGVfbW9kZShjZG5zKTsK Pj4gKwlpZiAocmV0KQo+PiArCQlnb3RvIGVycjsKPj4gKwo+PiArCWNkbnMtPnJvbGUgPSBjZG5z M19nZXRfaW5pdGlhbF9yb2xlKGNkbnMpOwo+PiArCj4+ICsJcmV0ID0gY2RuczNfcm9sZV9zdGFy dChjZG5zLCBjZG5zLT5yb2xlKTsKPj4gKwlpZiAocmV0KSB7Cj4+ICsJCWRldl9lcnIoZGV2LCAi Y2FuJ3Qgc3RhcnQgJXMgcm9sZVxuIiwKPj4gKwkJCWNkbnMzX2dldF9jdXJyZW50X3JvbGVfZHJp dmVyKGNkbnMpLT5uYW1lKTsKPj4gKwkJZ290byBlcnI7Cj4+ICsJfQo+PiArCj4+ICsJcmV0dXJu IHJldDsKPj4gK2VycjoKPj4gKwljZG5zM19leGl0X3JvbGVzKGNkbnMpOwo+PiArCXJldHVybiBy ZXQ7Cj4+ICt9Cj4KPnRoYW5rcywKPgo+Z3JlZyBrLWgKClRoYW5rcyAKUGF3ZWwK