From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Google-Smtp-Source: AG47ELuVGwBmsoZisu1vFRQJeOhNQcP2hHNYZYvpjk3iYx2DiSN39MCIWWNQAMSf90vCH5hRdzEj ARC-Seal: i=1; a=rsa-sha256; t=1520608767; cv=none; d=google.com; s=arc-20160816; b=083s0Ozv4M8fIHxsYSNHwmZtLl4R66lVEDa1s6kHSrV8AzEwbK5Psya6HnKH+AcfX1 +pKhSnaprAlGx+ATEHFeaqrKU3ciAvMDxThBI3PAXIcP0lwWWAtwgnRB7LkNns0SOrhH RbDB/S1kavL081EaNRBtJXIGeJ0XI4lW+ly1vZTsH52jXaB0l6lH8OpYhJmQiNVYsQkg Z9+GiUCCEioZZ6yfKCD4oA+IikgrTHb89H3snZXC4cSQ5ArAKxK8v8fCt9fSxSygFwbY jOfwR39kSDeKrtrOgNNh0w8rtV/qYXPKTM91Tc0zgEyF/7pnChYJnzlC4fgJgRedAeJd pRnQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:arc-authentication-results; bh=S/aEhHR/BtXQs9SX6cCH5VdtXm7QSvFSiyfODBHLgZ8=; b=lap7ijqeE2S1DePTgcM8j6s25SrvTgYTyuleyfYgUWhmxhSTu4w95Tc7rIQOpryQGi UWXDyuFksbGGvXSKiWHjCnQO/tYWKRhB7n9vlKieUPUw8vrzakzpZTp2yPRZ7pSKZB+d 7Ohc1famxHuhEsTJpjJH1p3/twL7lQ+CUaUM3wb0hK0kyINOXIs4J32X3pvl2qtAIcYU 7wFsiFdmbDd7oEXeev3r5U29649OUhOAJ9kEJCbj6myKf2LJun7zUhvYivmEMbSSJ3x3 WagA8JLxFsOpqERtRPU0lX06R7dDHsep+k1Dt6tBVdxTq8DkjR2+cIQGrUVrGN/pdkE5 fSwQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of heikki.krogerus@linux.intel.com designates 134.134.136.126 as permitted sender) smtp.mailfrom=heikki.krogerus@linux.intel.com Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of heikki.krogerus@linux.intel.com designates 134.134.136.126 as permitted sender) smtp.mailfrom=heikki.krogerus@linux.intel.com X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.47,446,1515484800"; d="scan'208";a="36826683" From: Heikki Krogerus To: Greg Kroah-Hartman , Guenter Roeck , Hans de Goede Cc: Jun Li , "Regupathy, Rajaram" , linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [RFC PATCH v2 2/3] usb: typec: Bus type for alternate modes Date: Fri, 9 Mar 2018 18:19:17 +0300 Message-Id: <20180309151918.22048-3-heikki.krogerus@linux.intel.com> X-Mailer: git-send-email 2.16.1 In-Reply-To: <20180309151918.22048-1-heikki.krogerus@linux.intel.com> References: <20180309151918.22048-1-heikki.krogerus@linux.intel.com> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: =?utf-8?q?1594473859065547728?= X-GMAIL-MSGID: =?utf-8?q?1594473859065547728?= X-Mailing-List: linux-kernel@vger.kernel.org List-ID: Introducing a simple bus for the alternate modes. Bus allows binding drivers to the discovered alternate modes the partners support. Signed-off-by: Heikki Krogerus --- Documentation/ABI/obsolete/sysfs-class-typec | 48 +++ Documentation/ABI/testing/sysfs-bus-typec | 51 ++++ Documentation/ABI/testing/sysfs-class-typec | 62 +--- Documentation/driver-api/usb/typec_bus.rst | 143 +++++++++ drivers/usb/typec/Makefile | 2 +- drivers/usb/typec/bus.c | 421 +++++++++++++++++++++++++++ drivers/usb/typec/bus.h | 37 +++ drivers/usb/typec/class.c | 325 +++++++++++++++++---- include/linux/mod_devicetable.h | 15 + include/linux/usb/typec.h | 16 +- include/linux/usb/typec_altmode.h | 136 +++++++++ scripts/mod/devicetable-offsets.c | 4 + scripts/mod/file2alias.c | 13 + 13 files changed, 1138 insertions(+), 135 deletions(-) create mode 100644 Documentation/ABI/obsolete/sysfs-class-typec create mode 100644 Documentation/ABI/testing/sysfs-bus-typec create mode 100644 Documentation/driver-api/usb/typec_bus.rst create mode 100644 drivers/usb/typec/bus.c create mode 100644 drivers/usb/typec/bus.h create mode 100644 include/linux/usb/typec_altmode.h diff --git a/Documentation/ABI/obsolete/sysfs-class-typec b/Documentation/ABI/obsolete/sysfs-class-typec new file mode 100644 index 000000000000..32623514ee87 --- /dev/null +++ b/Documentation/ABI/obsolete/sysfs-class-typec @@ -0,0 +1,48 @@ +These files are deprecated and will be removed. The same files are available +under /sys/bus/typec (see Documentation/ABI/testing/sysfs-bus-typec). + +What: /sys/class/typec///svid +Date: April 2017 +Contact: Heikki Krogerus +Description: + The SVID (Standard or Vendor ID) assigned by USB-IF for this + alternate mode. + +What: /sys/class/typec///mode/ +Date: April 2017 +Contact: Heikki Krogerus +Description: + Every supported mode will have its own directory. The name of + a mode will be "mode" (for example mode1), where + is the actual index to the mode VDO returned by Discover Modes + USB power delivery command. + +What: /sys/class/typec///mode/description +Date: April 2017 +Contact: Heikki Krogerus +Description: + Shows description of the mode. The description is optional for + the drivers, just like with the Billboard Devices. + +What: /sys/class/typec///mode/vdo +Date: April 2017 +Contact: Heikki Krogerus +Description: + Shows the VDO in hexadecimal returned by Discover Modes command + for this mode. + +What: /sys/class/typec///mode/active +Date: April 2017 +Contact: Heikki Krogerus +Description: + Shows if the mode is active or not. The attribute can be used + for entering/exiting the mode with partners and cable plugs, and + with the port alternate modes it can be used for disabling + support for specific alternate modes. Entering/exiting modes is + supported as synchronous operation so write(2) to the attribute + does not return until the enter/exit mode operation has + finished. The attribute is notified when the mode is + entered/exited so poll(2) on the attribute wakes up. + Entering/exiting a mode will also generate uevent KOBJ_CHANGE. + + Valid values: yes, no diff --git a/Documentation/ABI/testing/sysfs-bus-typec b/Documentation/ABI/testing/sysfs-bus-typec new file mode 100644 index 000000000000..ead63f97d9a2 --- /dev/null +++ b/Documentation/ABI/testing/sysfs-bus-typec @@ -0,0 +1,51 @@ +What: /sys/bus/typec/devices/.../active +Date: April 2018 +Contact: Heikki Krogerus +Description: + Shows if the mode is active or not. The attribute can be used + for entering/exiting the mode. Entering/exiting modes is + supported as synchronous operation so write(2) to the attribute + does not return until the enter/exit mode operation has + finished. The attribute is notified when the mode is + entered/exited so poll(2) on the attribute wakes up. + Entering/exiting a mode will also generate uevent KOBJ_CHANGE. + + Valid values are boolean. + +What: /sys/bus/typec/devices/.../description +Date: April 2018 +Contact: Heikki Krogerus +Description: + Shows description of the mode. The description is optional for + the drivers, just like with the Billboard Devices. + +What: /sys/bus/typec/devices/.../mode +Date: April 2018 +Contact: Heikki Krogerus +Description: + The index number of the mode returned by Discover Modes USB + Power Delivery command. Depending on the alternate mode, the + mode index may be significant. + + With some alternate modes (SVIDs), the mode index is assigned + for specific functionality in the specification for that + alternate mode. + + With other alternate modes, the mode index values are not + assigned, and can not be therefore used for identification. When + the mode index is not assigned, identifying the alternate mode + must be done with either mode VDO or the description. + +What: /sys/bus/typec/devices/.../svid +Date: April 2018 +Contact: Heikki Krogerus +Description: + The Standard or Vendor ID (SVID) assigned by USB-IF for this + alternate mode. + +What: /sys/bus/typec/devices/.../vdo +Date: April 2018 +Contact: Heikki Krogerus +Description: + Shows the VDO in hexadecimal returned by Discover Modes command + for this mode. diff --git a/Documentation/ABI/testing/sysfs-class-typec b/Documentation/ABI/testing/sysfs-class-typec index 5be552e255e9..d7647b258c3c 100644 --- a/Documentation/ABI/testing/sysfs-class-typec +++ b/Documentation/ABI/testing/sysfs-class-typec @@ -222,70 +222,12 @@ Description: available. The value can be polled. -Alternate Mode devices. +USB Type-C port alternate mode devices. -The alternate modes will have Standard or Vendor ID (SVID) assigned by USB-IF. -The ports, partners and cable plugs can have alternate modes. A supported SVID -will consist of a set of modes. Every SVID a port/partner/plug supports will -have a device created for it, and every supported mode for a supported SVID will -have its own directory under that device. Below refers to the device for -the alternate mode. - -What: /sys/class/typec///svid -Date: April 2017 -Contact: Heikki Krogerus -Description: - The SVID (Standard or Vendor ID) assigned by USB-IF for this - alternate mode. - -What: /sys/class/typec///mode/ -Date: April 2017 -Contact: Heikki Krogerus -Description: - Every supported mode will have its own directory. The name of - a mode will be "mode" (for example mode1), where - is the actual index to the mode VDO returned by Discover Modes - USB power delivery command. - -What: /sys/class/typec///mode/description -Date: April 2017 -Contact: Heikki Krogerus -Description: - Shows description of the mode. The description is optional for - the drivers, just like with the Billboard Devices. - -What: /sys/class/typec///mode/vdo -Date: April 2017 -Contact: Heikki Krogerus -Description: - Shows the VDO in hexadecimal returned by Discover Modes command - for this mode. - -What: /sys/class/typec///mode/active -Date: April 2017 -Contact: Heikki Krogerus -Description: - Shows if the mode is active or not. The attribute can be used - for entering/exiting the mode with partners and cable plugs, and - with the port alternate modes it can be used for disabling - support for specific alternate modes. Entering/exiting modes is - supported as synchronous operation so write(2) to the attribute - does not return until the enter/exit mode operation has - finished. The attribute is notified when the mode is - entered/exited so poll(2) on the attribute wakes up. - Entering/exiting a mode will also generate uevent KOBJ_CHANGE. - - Valid values: yes, no - -What: /sys/class/typec///mode/supported_roles +What: /sys/class/typec///supported_roles Date: April 2017 Contact: Heikki Krogerus Description: Space separated list of the supported roles. - This attribute is available for the devices describing the - alternate modes a port supports, and it will not be exposed with - the devices presenting the alternate modes the partners or cable - plugs support. - Valid values: source, sink diff --git a/Documentation/driver-api/usb/typec_bus.rst b/Documentation/driver-api/usb/typec_bus.rst new file mode 100644 index 000000000000..ef3c049a8a7f --- /dev/null +++ b/Documentation/driver-api/usb/typec_bus.rst @@ -0,0 +1,143 @@ + +API for USB Type-C Alternate Mode drivers +========================================= + +Introduction +------------ + +Alternate modes require communication with the partner using Vendor Defined +Messages (VDM) as defined in USB Type-C and USB Power Delivery Specifications. +The communication is SVID (Standard or Vendor ID) specific, i.e. specific for +every alternate mode, so every alternate mode will need custom driver. + +USB Type-C bus allows binding a driver to the discovered partner alternate +modes by using the SVID and the mode number. + +USB Type-C Connector Class provides a device for every alternate mode a port +supports, and separate device for every alternate mode the partner supports. +The drivers for the alternate modes are bind to the partner alternate mode +devices, and the port alternate mode devices must be handled by the port +drivers. + +When a new partner alternate mode device is registered, it is linked to the +alternate mode device of the port that the partner is attached to, that has +matching SVID and mode. Communication between the port driver and alternate mode +driver will happen using the same API. + +The port alternate mode devices are used as a proxy between the partner and the +alternate mode drivers, so the port drivers are only expected to pass the SVID +specific commands from the alternate mode drivers to the partner, and from the +partners to the alternate mode drivers. No direct SVID specific communication is +needed from the port drivers, but the port drivers need to provide the operation +callbacks for the port alternate mode devices, just like the alternate mode +drivers need to provide them for the partner alternate mode devices. + +Usage: +------ + +General +~~~~~~~ + +By default, the alternate mode drivers are responsible for entering the mode. +It is also possible to leave the decision about entering the mode to the user +space (See Documentation/ABI/testing/sysfs-class-typec). Port drivers should not +enter any modes on their own. + +The alternate mode drivers need to register their operation vector in their +``->probe`` callback with :c:func:`typec_altmode_register_ops()`. They should +be registered before the mode is entered using :c:func:`typec_altmode_enter()`. + +``->vdm`` is the most important callback in the vector. It will be used to +deliver all the SVID specific commands from the partner to the alternate mode +driver, and vise versa in case of port drivers. The drivers send the SVID +specific commands to each other using :c:func:`typec_altmode_vmd()`. + +If the communication with the partner using the SVID specific commands results +in need to re-configure the pins on the connector, the alternate mode driver +needs to notify the bus using :c:func:`typec_altmode_notify()`. The driver +passes the negotiated SVID specific pin configuration value to the function as +parameter. The bus driver will then configure the mux behind the connector using +that value as the state value for the mux, and also call blocking notification +chain to notify the external drivers about the state of the connector that need +to know it. + +NOTE: The SVID specific pin configuration values must always start from +``TYPEC_STATE_MODAL``. USB Type-C specification defines two default states for +the connector: ``TYPEC_STATE_USB`` and ``TYPEC_STATE_SAFE``. USB Type-C +Specification also defines two Accessory modes, Audio and Debug: +``TYPEC_STATE_AUDIO`` and ``TYPEC_STATE_DEBUG`` These values are reserved by the +bus as the four first possible values for the state, and attempts to use them +from the alternate mode drivers will result in failure. When the alternate mode +is entered, the bus will put the connector into ``TYPEC_STATE_SAFE`` before +sending Enter or Exit Mode command as defined in USB Type-C Specification, and +also put the connector back to ``TYPEC_STATE_USB`` after the mode has been +exited. + +An example of working definitions for SVID specific pin configurations would +look like this: + +enum { + ALTMODEX_CONF_A = TYPEC_STATE_MODAL, + ALTMODEX_CONF_B, + ... +}; + +Helper macro ``TYPEC_MODAL_STATE()`` can also be used: + +#define ALTMODEX_CONF_A = TYPEC_MODAL_STATE(0); +#define ALTMODEX_CONF_B = TYPEC_MODAL_STATE(1); + +Notification chain +~~~~~~~~~~~~~~~~~~ + +The drivers for the components that the alternate modes are designed for need to +get details regarding the results of the negotiation with the partner, and the +pin configuration of the connector. In case of DisplayPort alternate mode for +example, the GPU drivers will need to know those details. In case of +Thunderbolt alternate mode, the thunderbolt drivers will need to know them, and +so on. + +The notification chain is designed for this purpose. The drivers can register +notifiers with :c:func:`typec_altmode_register_notifier()`. + +Cable plug alternate modes +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The alternate mode drivers are not bind to cable plug alternate mode devices, +only to the partner alternate mode devices. If the alternate mode supports, or +requires, a cable that responds to SOP Prime, and optionally SOP Double Prime +messages, the driver for that alternate mode must request handle to the cable +plug alternate modes using :c:func:`typec_altmode_get_plug()`, and taking over +their control. + +Driver API +---------- + +Alternate mode driver registering/unregistering +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. kernel-doc:: drivers/usb/typec/bus.c + :functions: typec_altmode_register_driver typec_altmode_unregister_driver + +Alternate mode driver operations +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. kernel-doc:: drivers/usb/typec/bus.c + :functions: typec_altmode_register_ops typec_altmode_enter typec_altmode_exit typec_altmode_attention typec_altmode_vdm typec_altmode_notify + +API for the port drivers +~~~~~~~~~~~~~~~~~~~~~~~~ + +.. kernel-doc:: drivers/usb/typec/bus.c + :functions: typec_match_altmode + +Cable Plug operations +~~~~~~~~~~~~~~~~~~~~~ + +.. kernel-doc:: drivers/usb/typec/bus.c + :functions: typec_altmode_get_plug typec_altmode_put_plug + +Notifications +~~~~~~~~~~~~~ +.. kernel-doc:: drivers/usb/typec/class.c + :functions: typec_altmode_register_notifier typec_altmode_unregister_notifier diff --git a/drivers/usb/typec/Makefile b/drivers/usb/typec/Makefile index 1f599a6c30cc..5466c62c8e97 100644 --- a/drivers/usb/typec/Makefile +++ b/drivers/usb/typec/Makefile @@ -1,6 +1,6 @@ # SPDX-License-Identifier: GPL-2.0 obj-$(CONFIG_TYPEC) += typec.o -typec-y := class.o mux.o +typec-y := class.o mux.o bus.o obj-$(CONFIG_TYPEC_TCPM) += tcpm.o obj-y += fusb302/ obj-$(CONFIG_TYPEC_WCOVE) += typec_wcove.o diff --git a/drivers/usb/typec/bus.c b/drivers/usb/typec/bus.c new file mode 100644 index 000000000000..92944aaf3d6a --- /dev/null +++ b/drivers/usb/typec/bus.c @@ -0,0 +1,421 @@ +// SPDX-License-Identifier: GPL-2.0 +/** + * Bus for USB Type-C Alternate Modes + * + * Copyright (C) 2018 Intel Corporation + * Author: Heikki Krogerus + */ + +#include "bus.h" + +/* -------------------------------------------------------------------------- */ +/* Common API */ + +/** + * typec_altmode_notify - Communication between the OS and alternate mode driver + * @adev: Handle to the alternate mode + * @conf: Alternate mode specific configuration value + * @data: Alternate mode specific data + * + * The primary purpose for this function is to allow the alternate mode drivers + * to tell which pin configuration has been negotiated with the partner. That + * information will then be used for example to configure the muxes. + * Communication to the other direction is also possible, and low level device + * drivers can also send notifications to the alternate mode drivers. The actual + * communication will be specific for every SVID. + */ +int typec_altmode_notify(struct typec_altmode *adev, + unsigned long conf, void *data) +{ + struct altmode *altmode; + struct altmode *partner; + int ret; + + /* + * All SVID specific configuration values must start from + * TYPEC_STATE_MODAL. The first values are reserved for the pin states + * defined in USB Type-C specification: TYPEC_STATE_USB and + * TYPEC_STATE_SAFE. We'll follow this rule even with modes that do not + * require pin reconfiguration for the sake of simplicity. + */ + if (conf < TYPEC_STATE_MODAL) + return -EINVAL; + + if (!adev) + return 0; + + altmode = to_altmode(adev); + + if (!altmode->partner) + return -ENODEV; + + ret = typec_set_mode(typec_altmode2port(adev), (int)conf); + if (ret) + return ret; + + partner = altmode->partner; + + blocking_notifier_call_chain(is_typec_port(adev->dev.parent) ? + &altmode->nh : &partner->nh, + conf, data); + + if (partner->ops && partner->ops->notify) + return partner->ops->notify(&partner->adev, conf, data); + + return 0; +} +EXPORT_SYMBOL_GPL(typec_altmode_notify); + +/** + * typec_altmode_enter - Enter Mode + * @adev: The alternate mode + * + * The alternate mode drivers use this function to enter mode. The port drivers + * use this to inform the alternate mode drivers that their mode has been + * entered successfully. + */ +int typec_altmode_enter(struct typec_altmode *adev) +{ + struct altmode *partner = to_altmode(adev)->partner; + struct typec_altmode *pdev = &partner->adev; + int ret; + + if (is_typec_port(adev->dev.parent)) { + typec_altmode_update_active(pdev, pdev->mode, true); + sysfs_notify(&pdev->dev.kobj, NULL, "active"); + goto enter_mode; + } + + if (!pdev->active) + return -EPERM; + + /* First moving to USB Safe State */ + ret = typec_set_mode(typec_altmode2port(adev), TYPEC_STATE_SAFE); + if (ret) + return ret; + + blocking_notifier_call_chain(&partner->nh, TYPEC_STATE_SAFE, NULL); + +enter_mode: + /* Enter Mode command */ + if (partner->ops && partner->ops->enter) + partner->ops->enter(pdev); + + return 0; +} +EXPORT_SYMBOL_GPL(typec_altmode_enter); + +/** + * typec_altmode_enter - Exit Mode + * @adev: The alternate mode + * + * The alternate mode drivers use this function to exit mode. The port drivers + * can also inform the alternate mode drivers with this function that the mode + * was successfully exited. + */ +int typec_altmode_exit(struct typec_altmode *adev) +{ + struct altmode *partner = to_altmode(adev)->partner; + struct typec_port *port = typec_altmode2port(adev); + struct typec_altmode *pdev = &partner->adev; + int ret; + + /* In case of port, just calling the driver and exiting */ + if (is_typec_port(adev->dev.parent)) { + typec_altmode_update_active(pdev, pdev->mode, false); + sysfs_notify(&pdev->dev.kobj, NULL, "active"); + + if (partner->ops && partner->ops->exit) + partner->ops->exit(pdev); + return 0; + } + + /* Moving to USB Safe State */ + ret = typec_set_mode(port, TYPEC_STATE_SAFE); + if (ret) + return ret; + + blocking_notifier_call_chain(&partner->nh, TYPEC_STATE_SAFE, NULL); + + /* Exit Mode command */ + if (partner->ops && partner->ops->exit) + partner->ops->exit(pdev); + + /* Back to USB operation */ + ret = typec_set_mode(port, TYPEC_STATE_USB); + if (ret) + return ret; + + blocking_notifier_call_chain(&partner->nh, TYPEC_STATE_USB, NULL); + + return 0; +} +EXPORT_SYMBOL_GPL(typec_altmode_exit); + +/** + * typec_altmode_attention - Attention command + * @adev: The alternate mode + * @vdo: VDO for the Attention command + * + * Notifies the partner of @adev about Attention command. + */ +void typec_altmode_attention(struct typec_altmode *adev, const u32 vdo) +{ + struct altmode *partner = to_altmode(adev)->partner; + + if (partner && partner->ops && partner->ops->attention) + partner->ops->attention(&partner->adev, vdo); +} +EXPORT_SYMBOL_GPL(typec_altmode_attention); + +/** + * typec_altmode_vdm - Send Vendor Defined Messages (VDM) to the partner + * @adev: Alternate mode handle + * @header: VDM Header + * @vdo: Array of Vendor Defined Data Objects + * @count: Number of Data Objects + * + * The alternate mode drivers use this function for SVID specific communication + * with the partner. The port drivers use it to deliver the Structured VDMs + * received from the partners to the alternate mode drivers. + */ +int typec_altmode_vdm(struct typec_altmode *adev, + const u32 header, const u32 *vdo, int count) +{ + struct altmode *altmode; + struct altmode *partner; + + if (!adev) + return 0; + + altmode = to_altmode(adev); + + if (!altmode->partner) + return -ENODEV; + + partner = altmode->partner; + + if (partner->ops && partner->ops->vdm) + return partner->ops->vdm(&partner->adev, header, vdo, count); + + return 0; +} +EXPORT_SYMBOL_GPL(typec_altmode_vdm); + +void typec_altmode_register_ops(struct typec_altmode *adev, + const struct typec_altmode_ops *ops) +{ + to_altmode(adev)->ops = ops; +} +EXPORT_SYMBOL_GPL(typec_altmode_register_ops); + +/* -------------------------------------------------------------------------- */ +/* API for the alternate mode drivers */ + +/** + * typec_altmode_get_plug - Find cable plug alternate mode + * @adev: Handle to partner alternate mode + * @index: Cable plug index + * + * Increment reference count for cable plug alternate mode device. Returns + * handle to the cable plug alternate mode, or NULL if none is found. + */ +struct typec_altmode *typec_altmode_get_plug(struct typec_altmode *adev, + int index) +{ + struct altmode *port = to_altmode(adev)->partner; + + if (port->plug[index]) { + get_device(&port->plug[index]->adev.dev); + return &port->plug[index]->adev; + } + + return NULL; +} +EXPORT_SYMBOL_GPL(typec_altmode_get_plug); + +/** + * typec_altmode_get_plug - Decrement cable plug alternate mode reference count + * @plug: Handle to the cable plug alternate mode + */ +void typec_altmode_put_plug(struct typec_altmode *plug) +{ + if (plug) + put_device(&plug->dev); +} +EXPORT_SYMBOL_GPL(typec_altmode_put_plug); + +int __typec_altmode_register_driver(struct typec_altmode_driver *drv, + struct module *module) +{ + if (!drv->probe) + return -EINVAL; + + drv->driver.owner = module; + drv->driver.bus = &typec_bus; + + return driver_register(&drv->driver); +} +EXPORT_SYMBOL_GPL(__typec_altmode_register_driver); + +void typec_altmode_unregister_driver(struct typec_altmode_driver *drv) +{ + driver_unregister(&drv->driver); +} +EXPORT_SYMBOL_GPL(typec_altmode_unregister_driver); + +/* -------------------------------------------------------------------------- */ +/* API for the port drivers */ + +bool typec_altmode_ufp_capable(struct typec_altmode *adev) +{ + struct altmode *altmode = to_altmode(adev); + + if (!is_typec_port(adev->dev.parent)) + return false; + + return !(altmode->roles == TYPEC_PORT_DFP); +} +EXPORT_SYMBOL_GPL(typec_altmode_ufp_capable); + +bool typec_altmode_dfp_capable(struct typec_altmode *adev) +{ + struct altmode *altmode = to_altmode(adev); + + if (!is_typec_port(adev->dev.parent)) + return false; + + return !(altmode->roles == TYPEC_PORT_UFP); +} +EXPORT_SYMBOL_GPL(typec_altmode_dfp_capable); + +/** + * typec_match_altmode - Match SVID to an array of alternate modes + * @altmodes: Array of alternate modes + * @n: Number of elements in the array, or -1 for NULL termiated arrays + * @svid: Standard or Vendor ID to match with + * + * Return pointer to an alternate mode with SVID mathing @svid, or NULL when no + * match is found. + */ +struct typec_altmode *typec_match_altmode(struct typec_altmode **altmodes, + size_t n, u16 svid, u8 mode) +{ + int i; + + for (i = 0; i < n; i++) { + if (!altmodes[i]) + break; + if (altmodes[i]->svid == svid && altmodes[i]->mode == mode) + return altmodes[i]; + } + + return NULL; +} +EXPORT_SYMBOL_GPL(typec_match_altmode); + +/* -------------------------------------------------------------------------- */ + +static ssize_t +description_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct typec_altmode *alt = to_typec_altmode(dev); + + return sprintf(buf, "%s\n", alt->desc ? alt->desc : ""); +} +static DEVICE_ATTR_RO(description); + +static struct attribute *typec_attrs[] = { + &dev_attr_description.attr, + NULL +}; +ATTRIBUTE_GROUPS(typec); + +static int typec_match(struct device *dev, struct device_driver *driver) +{ + struct typec_altmode_driver *drv = to_altmode_driver(driver); + struct typec_altmode *altmode = to_typec_altmode(dev); + const struct typec_device_id *id; + + for (id = drv->id_table; id->svid; id++) + if ((id->svid == altmode->svid) && + (id->mode == TYPEC_ANY_MODE || id->mode == altmode->mode)) + return 1; + return 0; +} + +static int typec_uevent(struct device *dev, struct kobj_uevent_env *env) +{ + struct typec_altmode *altmode = to_typec_altmode(dev); + + if (add_uevent_var(env, "SVID=%04X", altmode->svid)) + return -ENOMEM; + + if (add_uevent_var(env, "MODE=%u", altmode->mode)) + return -ENOMEM; + + return add_uevent_var(env, "MODALIAS=typec:id%04Xm%02X", + altmode->svid, altmode->mode); +} + +static int typec_altmode_create_links(struct altmode *alt) +{ + struct device *port_dev = &alt->partner->adev.dev; + struct device *dev = &alt->adev.dev; + int err; + + err = sysfs_create_link(&dev->kobj, &port_dev->kobj, "port"); + if (err) + return err; + + err = sysfs_create_link(&port_dev->kobj, &dev->kobj, "partner"); + if (err) + sysfs_remove_link(&dev->kobj, "port"); + + return err; +} + +static int typec_probe(struct device *dev) +{ + struct typec_altmode_driver *drv = to_altmode_driver(dev->driver); + struct typec_altmode *adev = to_typec_altmode(dev); + struct altmode *altmode = to_altmode(adev); + + /* Fail if the port does not support the alternate mode */ + if (!altmode->partner) + return -ENODEV; + + if (typec_altmode_create_links(altmode)) + dev_warn(dev, "failed to create symlinks\n"); + + return drv->probe(adev, altmode->partner->adev.vdo); +} + +static int typec_remove(struct device *dev) +{ + struct typec_altmode_driver *drv = to_altmode_driver(dev->driver); + struct typec_altmode *adev = to_typec_altmode(dev); + struct altmode *altmode = to_altmode(adev); + + if (!is_typec_port(adev->dev.parent)) { + sysfs_remove_link(&altmode->partner->adev.dev.kobj, "partner"); + sysfs_remove_link(&adev->dev.kobj, "port"); + } + + if (drv->remove) + drv->remove(to_typec_altmode(dev)); + + if (adev->active) + typec_altmode_exit(adev); + + return 0; +} + +struct bus_type typec_bus = { + .name = "typec", + .dev_groups = typec_groups, + .match = typec_match, + .uevent = typec_uevent, + .probe = typec_probe, + .remove = typec_remove, +}; diff --git a/drivers/usb/typec/bus.h b/drivers/usb/typec/bus.h new file mode 100644 index 000000000000..38585363952f --- /dev/null +++ b/drivers/usb/typec/bus.h @@ -0,0 +1,37 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#ifndef __USB_TYPEC_ALTMODE_H__ +#define __USB_TYPEC_ALTMODE_H__ + +#include + +struct bus_type; + +struct altmode { + unsigned int id; + struct typec_altmode adev; + + enum typec_port_data roles; + + struct attribute *attrs[5]; + char group_name[6]; + struct attribute_group group; + const struct attribute_group *groups[2]; + + struct altmode *partner; + struct altmode *plug[2]; + const struct typec_altmode_ops *ops; + + struct blocking_notifier_head nh; +}; + +#define to_altmode(d) container_of(d, struct altmode, adev) + +extern struct bus_type typec_bus; +extern const struct device_type typec_altmode_dev_type; +extern const struct device_type typec_port_dev_type; + +#define is_typec_altmode(_dev_) (_dev_->type == &typec_altmode_dev_type) +#define is_typec_port(_dev_) (_dev_->type == &typec_port_dev_type) + +#endif /* __USB_TYPEC_ALTMODE_H__ */ diff --git a/drivers/usb/typec/class.c b/drivers/usb/typec/class.c index 26eeab1491b7..33fffb853994 100644 --- a/drivers/usb/typec/class.c +++ b/drivers/usb/typec/class.c @@ -6,6 +6,7 @@ * Author: Heikki Krogerus */ +#include #include #include #include @@ -13,25 +14,12 @@ #include #include -struct typec_altmode { - struct device dev; - u16 svid; - u8 mode; - - u32 vdo; - char *desc; - enum typec_port_type roles; - unsigned int active:1; - - struct attribute *attrs[5]; - char group_name[6]; - struct attribute_group group; - const struct attribute_group *groups[2]; -}; +#include "bus.h" struct typec_plug { struct device dev; enum typec_plug_index index; + struct ida mode_ids; }; struct typec_cable { @@ -46,11 +34,13 @@ struct typec_partner { unsigned int usb_pd:1; struct usb_pd_identity *identity; enum typec_accessory accessory; + struct ida mode_ids; }; struct typec_port { unsigned int id; struct device dev; + struct ida mode_ids; int prefer_role; enum typec_data_role data_role; @@ -71,17 +61,14 @@ struct typec_port { #define to_typec_plug(_dev_) container_of(_dev_, struct typec_plug, dev) #define to_typec_cable(_dev_) container_of(_dev_, struct typec_cable, dev) #define to_typec_partner(_dev_) container_of(_dev_, struct typec_partner, dev) -#define to_altmode(_dev_) container_of(_dev_, struct typec_altmode, dev) static const struct device_type typec_partner_dev_type; static const struct device_type typec_cable_dev_type; static const struct device_type typec_plug_dev_type; -static const struct device_type typec_port_dev_type; #define is_typec_partner(_dev_) (_dev_->type == &typec_partner_dev_type) #define is_typec_cable(_dev_) (_dev_->type == &typec_cable_dev_type) #define is_typec_plug(_dev_) (_dev_->type == &typec_plug_dev_type) -#define is_typec_port(_dev_) (_dev_->type == &typec_port_dev_type) static DEFINE_IDA(typec_index_ida); static struct class *typec_class; @@ -163,27 +150,141 @@ static void typec_report_identity(struct device *dev) /* ------------------------------------------------------------------------- */ /* Alternate Modes */ +static int altmode_match(struct device *dev, void *data) +{ + struct typec_altmode *adev = to_typec_altmode(dev); + struct typec_device_id *id = data; + + if (!is_typec_altmode(dev)) + return 0; + + return ((adev->svid == id->svid) && (adev->mode == id->mode)); +} + +static void typec_altmode_get_partner(struct altmode *altmode) +{ + struct typec_altmode *adev = &altmode->adev; + struct typec_device_id id = { adev->svid, adev->mode, }; + struct typec_port *port = typec_altmode2port(adev); + struct altmode *partner; + struct device *dev; + + dev = device_find_child(&port->dev, &id, altmode_match); + if (!dev) + return; + + /* Bind the port alt mode to the partner/plug alt mode. */ + partner = to_altmode(to_typec_altmode(dev)); + altmode->partner = partner; + + /* Bind the partner/plug alt mode to the port alt mode. */ + if (is_typec_plug(adev->dev.parent)) { + struct typec_plug *plug = to_typec_plug(adev->dev.parent); + + partner->plug[plug->index] = altmode; + } else { + partner->partner = altmode; + } +} + +static void typec_altmode_put_partner(struct altmode *altmode) +{ + struct altmode *partner = altmode->partner; + struct typec_altmode *adev; + + if (!partner) + return; + + adev = &partner->adev; + + if (is_typec_plug(adev->dev.parent)) { + struct typec_plug *plug = to_typec_plug(adev->dev.parent); + + partner->plug[plug->index] = NULL; + } else { + partner->partner = NULL; + } + put_device(&adev->dev); +} + +static int __typec_port_match(struct device *dev, const void *name) +{ + return !strcmp((const char *)name, dev_name(dev)); +} + +static void *typec_port_match(struct devcon *con, int ep, void *data) +{ + return class_find_device(typec_class, NULL, con->endpoint[ep], + __typec_port_match); +} + +struct typec_altmode * +typec_altmode_register_notifier(struct device *dev, u16 svid, u8 mode, + struct notifier_block *nb) +{ + struct typec_device_id id = { svid, mode, }; + struct device *altmode_dev; + struct device *port_dev; + struct altmode *altmode; + int ret; + + /* Find the port linked to the caller */ + port_dev = __device_find_connection(dev, NULL, NULL, typec_port_match); + if (!port_dev) + return ERR_PTR(-ENODEV); + + /* Find the altmode with matching svid */ + altmode_dev = device_find_child(port_dev, &id, altmode_match); + + put_device(port_dev); + + if (!altmode_dev) + return ERR_PTR(-ENODEV); + + altmode = to_altmode(to_typec_altmode(altmode_dev)); + + /* Register notifier */ + ret = blocking_notifier_chain_register(&altmode->nh, nb); + if (ret) { + put_device(altmode_dev); + return ERR_PTR(ret); + } + + return &altmode->adev; +} +EXPORT_SYMBOL_GPL(typec_altmode_register_notifier); + +void typec_altmode_unregister_notifier(struct typec_altmode *adev, + struct notifier_block *nb) +{ + struct altmode *altmode = to_altmode(adev); + + blocking_notifier_chain_unregister(&altmode->nh, nb); + put_device(&adev->dev); +} +EXPORT_SYMBOL_GPL(typec_altmode_unregister_notifier); + /** * typec_altmode_update_active - Report Enter/Exit mode - * @alt: Handle to the alternate mode + * @adev: Handle to the alternate mode * @mode: Mode index * @active: True when the mode has been entered * * If a partner or cable plug executes Enter/Exit Mode command successfully, the * drivers use this routine to report the updated state of the mode. */ -void typec_altmode_update_active(struct typec_altmode *alt, int mode, +void typec_altmode_update_active(struct typec_altmode *adev, int mode, bool active) { char dir[6]; - if (alt->active == active) + if (adev->active == active) return; - alt->active = active; + adev->active = active; snprintf(dir, sizeof(dir), "mode%d", mode); - sysfs_notify(&alt->dev.kobj, dir, "active"); - kobject_uevent(&alt->dev.kobj, KOBJ_CHANGE); + sysfs_notify(&adev->dev.kobj, dir, "active"); + kobject_uevent(&adev->dev.kobj, KOBJ_CHANGE); } EXPORT_SYMBOL_GPL(typec_altmode_update_active); @@ -210,7 +311,7 @@ EXPORT_SYMBOL_GPL(typec_altmode2port); static ssize_t vdo_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct typec_altmode *alt = to_altmode(dev); + struct typec_altmode *alt = to_typec_altmode(dev); return sprintf(buf, "0x%08x\n", alt->vdo); } @@ -219,7 +320,7 @@ static DEVICE_ATTR_RO(vdo); static ssize_t description_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct typec_altmode *alt = to_altmode(dev); + struct typec_altmode *alt = to_typec_altmode(dev); return sprintf(buf, "%s\n", alt->desc ? alt->desc : ""); } @@ -228,28 +329,46 @@ static DEVICE_ATTR_RO(description); static ssize_t active_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct typec_altmode *alt = to_altmode(dev); + struct typec_altmode *alt = to_typec_altmode(dev); return sprintf(buf, "%s\n", alt->active ? "yes" : "no"); } -static ssize_t -active_store(struct device *dev, struct device_attribute *attr, - const char *buf, size_t size) +static ssize_t active_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t size) { - struct typec_altmode *alt = to_altmode(dev); - struct typec_port *port = typec_altmode2port(alt); - bool activate; + struct typec_altmode *adev = to_typec_altmode(dev); + struct typec_port *port = typec_altmode2port(adev); + struct altmode *altmode = to_altmode(adev); + bool enter; int ret; if (!port->cap->activate_mode) return -EOPNOTSUPP; - ret = kstrtobool(buf, &activate); + ret = kstrtobool(buf, &enter); if (ret) return ret; - ret = port->cap->activate_mode(port->cap, alt->mode, activate); + if (adev->active == enter) + return size; + + if (is_typec_port(adev->dev.parent)) { + typec_altmode_update_active(adev, adev->mode, enter); + sysfs_notify(&adev->dev.kobj, NULL, "active"); + + if (!altmode->partner) + return size; + } else { + adev = &altmode->partner->adev; + + if (!adev->active) { + dev_warn(dev, "port has the mode disabled\n"); + return -EPERM; + } + } + + ret = port->cap->activate_mode(adev, enter); if (ret) return ret; @@ -261,7 +380,7 @@ static ssize_t supported_roles_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct typec_altmode *alt = to_altmode(dev); + struct altmode *alt = to_altmode(to_typec_altmode(dev)); ssize_t ret; switch (alt->roles) { @@ -280,29 +399,72 @@ supported_roles_show(struct device *dev, struct device_attribute *attr, } static DEVICE_ATTR_RO(supported_roles); -static void typec_altmode_release(struct device *dev) +static ssize_t +mode_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct typec_altmode *alt = to_altmode(dev); + struct typec_altmode *adev = to_typec_altmode(dev); - kfree(alt); + return sprintf(buf, "%u\n", adev->mode); } +static DEVICE_ATTR_RO(mode); -static ssize_t svid_show(struct device *dev, struct device_attribute *attr, - char *buf) +static ssize_t +svid_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct typec_altmode *alt = to_altmode(dev); + struct typec_altmode *adev = to_typec_altmode(dev); - return sprintf(buf, "%04x\n", alt->svid); + return sprintf(buf, "%04x\n", adev->svid); } static DEVICE_ATTR_RO(svid); static struct attribute *typec_altmode_attrs[] = { + &dev_attr_active.attr, + &dev_attr_mode.attr, &dev_attr_svid.attr, + &dev_attr_vdo.attr, NULL }; ATTRIBUTE_GROUPS(typec_altmode); -static const struct device_type typec_altmode_dev_type = { +static int altmode_id_get(struct device *dev) +{ + struct ida *ids; + + if (is_typec_partner(dev)) + ids = &to_typec_partner(dev)->mode_ids; + else if (is_typec_plug(dev)) + ids = &to_typec_plug(dev)->mode_ids; + else + ids = &to_typec_port(dev)->mode_ids; + + return ida_simple_get(ids, 0, 0, GFP_KERNEL); +} + +static void altmode_id_remove(struct device *dev, int id) +{ + struct ida *ids; + + if (is_typec_partner(dev)) + ids = &to_typec_partner(dev)->mode_ids; + else if (is_typec_plug(dev)) + ids = &to_typec_plug(dev)->mode_ids; + else + ids = &to_typec_port(dev)->mode_ids; + + ida_simple_remove(ids, id); +} + +static void typec_altmode_release(struct device *dev) +{ + struct altmode *alt = to_altmode(to_typec_altmode(dev)); + + typec_altmode_put_partner(alt); + + altmode_id_remove(alt->adev.dev.parent, alt->id); + kfree(alt); +} + +const struct device_type typec_altmode_dev_type = { .name = "typec_alternate_mode", .groups = typec_altmode_groups, .release = typec_altmode_release, @@ -312,58 +474,72 @@ static struct typec_altmode * typec_register_altmode(struct device *parent, const struct typec_altmode_desc *desc) { - struct typec_altmode *alt; + unsigned int id = altmode_id_get(parent); + bool is_port = is_typec_port(parent); + struct altmode *alt; int ret; alt = kzalloc(sizeof(*alt), GFP_KERNEL); if (!alt) return ERR_PTR(-ENOMEM); - alt->svid = desc->svid; - alt->mode = desc->mode; - alt->vdo = desc->vdo; + alt->adev.svid = desc->svid; + alt->adev.mode = desc->mode; + alt->adev.vdo = desc->vdo; alt->roles = desc->roles; + alt->id = id; alt->attrs[0] = &dev_attr_vdo.attr; alt->attrs[1] = &dev_attr_description.attr; alt->attrs[2] = &dev_attr_active.attr; - if (is_typec_port(parent)) + if (is_port) { alt->attrs[3] = &dev_attr_supported_roles.attr; + alt->adev.active = true; /* Enabled by default */ + } sprintf(alt->group_name, "mode%d", desc->mode); alt->group.name = alt->group_name; alt->group.attrs = alt->attrs; alt->groups[0] = &alt->group; - alt->dev.parent = parent; - alt->dev.groups = alt->groups; - alt->dev.type = &typec_altmode_dev_type; - dev_set_name(&alt->dev, "%s-%04x:%u", dev_name(parent), - alt->svid, alt->mode); + alt->adev.dev.parent = parent; + alt->adev.dev.groups = alt->groups; + alt->adev.dev.type = &typec_altmode_dev_type; + dev_set_name(&alt->adev.dev, "%s.%u", dev_name(parent), id); + + /* Link partners and plugs with the ports */ + if (is_port) + BLOCKING_INIT_NOTIFIER_HEAD(&alt->nh); + else + typec_altmode_get_partner(alt); - ret = device_register(&alt->dev); + /* The partners are bind to drivers */ + if (is_typec_partner(parent)) + alt->adev.dev.bus = &typec_bus; + + ret = device_register(&alt->adev.dev); if (ret) { dev_err(parent, "failed to register alternate mode (%d)\n", ret); - put_device(&alt->dev); + put_device(&alt->adev.dev); return ERR_PTR(ret); } - return alt; + return &alt->adev; } /** * typec_unregister_altmode - Unregister Alternate Mode - * @alt: The alternate mode to be unregistered + * @adev: The alternate mode to be unregistered * * Unregister device created with typec_partner_register_altmode(), * typec_plug_register_altmode() or typec_port_register_altmode(). */ -void typec_unregister_altmode(struct typec_altmode *alt) +void typec_unregister_altmode(struct typec_altmode *adev) { - if (!IS_ERR_OR_NULL(alt)) - device_unregister(&alt->dev); + if (!IS_ERR_OR_NULL(adev)) + device_unregister(&adev->dev); } EXPORT_SYMBOL_GPL(typec_unregister_altmode); @@ -401,6 +577,7 @@ static void typec_partner_release(struct device *dev) { struct typec_partner *partner = to_typec_partner(dev); + ida_destroy(&partner->mode_ids); kfree(partner); } @@ -466,6 +643,7 @@ struct typec_partner *typec_register_partner(struct typec_port *port, if (!partner) return ERR_PTR(-ENOMEM); + ida_init(&partner->mode_ids); partner->usb_pd = desc->usb_pd; partner->accessory = desc->accessory; @@ -514,6 +692,7 @@ static void typec_plug_release(struct device *dev) { struct typec_plug *plug = to_typec_plug(dev); + ida_destroy(&plug->mode_ids); kfree(plug); } @@ -566,6 +745,7 @@ struct typec_plug *typec_register_plug(struct typec_cable *cable, sprintf(name, "plug%d", desc->index); + ida_init(&plug->mode_ids); plug->index = desc->index; plug->dev.class = typec_class; plug->dev.parent = &cable->dev; @@ -1080,12 +1260,13 @@ static void typec_release(struct device *dev) struct typec_port *port = to_typec_port(dev); ida_simple_remove(&typec_index_ida, port->id); + ida_destroy(&port->mode_ids); typec_switch_put(port->sw); typec_mux_put(port->mux); kfree(port); } -static const struct device_type typec_port_dev_type = { +const struct device_type typec_port_dev_type = { .name = "typec_port", .groups = typec_groups, .uevent = typec_uevent, @@ -1238,6 +1419,8 @@ EXPORT_SYMBOL_GPL(typec_set_mode); * typec_port_register_altmode - Register USB Type-C Port Alternate Mode * @port: USB Type-C Port that supports the alternate mode * @desc: Description of the alternate mode + * @ops: Port specific operations for the alternate mode + * @drvdata: Private pointer to driver specific info * * This routine is used to register an alternate mode that @port is capable of * supporting. @@ -1322,10 +1505,12 @@ struct typec_port *typec_register_port(struct device *parent, break; } + ida_init(&port->mode_ids); + mutex_init(&port->port_type_lock); + port->id = id; port->cap = cap; port->port_type = cap->type; - mutex_init(&port->port_type_lock); port->prefer_role = cap->prefer_role; port->dev.class = typec_class; @@ -1369,8 +1554,19 @@ EXPORT_SYMBOL_GPL(typec_unregister_port); static int __init typec_init(void) { + int ret; + + ret = bus_register(&typec_bus); + if (ret) + return ret; + typec_class = class_create(THIS_MODULE, "typec"); - return PTR_ERR_OR_ZERO(typec_class); + if (IS_ERR(typec_class)) { + bus_unregister(&typec_bus); + return PTR_ERR(typec_class); + } + + return 0; } subsys_initcall(typec_init); @@ -1378,6 +1574,7 @@ static void __exit typec_exit(void) { class_destroy(typec_class); ida_destroy(&typec_index_ida); + bus_unregister(&typec_bus); } module_exit(typec_exit); diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h index 48fb2b43c35a..17c1a912f524 100644 --- a/include/linux/mod_devicetable.h +++ b/include/linux/mod_devicetable.h @@ -733,4 +733,19 @@ struct tb_service_id { #define TBSVC_MATCH_PROTOCOL_VERSION 0x0004 #define TBSVC_MATCH_PROTOCOL_REVISION 0x0008 +/* USB Type-C Alternate Modes */ + +#define TYPEC_ANY_MODE 0x7 + +/** + * struct typec_device_id - USB Type-C alternate mode identifiers + * @svid: Standard or Vendor ID + * @mode: Mode index + */ +struct typec_device_id { + __u16 svid; + __u8 mode; + kernel_ulong_t driver_data; +}; + #endif /* LINUX_MOD_DEVICETABLE_H */ diff --git a/include/linux/usb/typec.h b/include/linux/usb/typec.h index 278b6b42c7ea..a19aa3db4272 100644 --- a/include/linux/usb/typec.h +++ b/include/linux/usb/typec.h @@ -4,16 +4,13 @@ #define __LINUX_USB_TYPEC_H #include - -/* XXX: Once we have a header for USB Power Delivery, this belongs there */ -#define ALTMODE_MAX_MODES 6 +#include /* USB Type-C Specification releases */ #define USB_TYPEC_REV_1_0 0x100 /* 1.0 */ #define USB_TYPEC_REV_1_1 0x110 /* 1.1 */ #define USB_TYPEC_REV_1_2 0x120 /* 1.2 */ -struct typec_altmode; struct typec_partner; struct typec_cable; struct typec_plug; @@ -107,7 +104,7 @@ struct typec_altmode_desc { u8 mode; u32 vdo; /* Only used with ports */ - enum typec_port_type roles; + enum typec_port_data roles; }; struct typec_altmode @@ -118,7 +115,8 @@ struct typec_altmode const struct typec_altmode_desc *desc); struct typec_altmode *typec_port_register_altmode(struct typec_port *port, - const struct typec_altmode_desc *desc); + const struct typec_altmode_desc *desc); + void typec_unregister_altmode(struct typec_altmode *altmode); struct typec_port *typec_altmode2port(struct typec_altmode *alt); @@ -213,12 +211,10 @@ struct typec_capability { enum typec_role); int (*vconn_set)(const struct typec_capability *, enum typec_role); - - int (*activate_mode)(const struct typec_capability *, - int mode, int activate); int (*port_type_set)(const struct typec_capability *, - enum typec_port_type); + enum typec_port_type); + int (*activate_mode)(struct typec_altmode *alt, int active); }; /* Specific to try_role(). Indicates the user want's to clear the preference. */ diff --git a/include/linux/usb/typec_altmode.h b/include/linux/usb/typec_altmode.h new file mode 100644 index 000000000000..bc765352a3c8 --- /dev/null +++ b/include/linux/usb/typec_altmode.h @@ -0,0 +1,136 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#ifndef __USB_TYPEC_ALTMODE_H +#define __USB_TYPEC_ALTMODE_H + +#include +#include + +#define MODE_DISCOVERY_MAX 6 + +/** + * struct typec_altmode - USB Type-C alternate mode device + * @dev: Driver model's view of this device + * @svid: Standard or Vendor ID (SVID) of the alternate mode + * @mode: Index of the Mode + * @vdo: VDO returned by Discover Modes USB PD command + * @desc: Optional human readable description of the mode + * @active: Tells has the mode been entered or not + */ +struct typec_altmode { + struct device dev; + u16 svid; + int mode; + u32 vdo; + char *desc; + bool active; +} __packed; + +#define to_typec_altmode(d) container_of(d, struct typec_altmode, dev) + +static inline void typec_altmode_set_drvdata(struct typec_altmode *altmode, + void *data) +{ + dev_set_drvdata(&altmode->dev, data); +} + +static inline void *typec_altmode_get_drvdata(struct typec_altmode *altmode) +{ + return dev_get_drvdata(&altmode->dev); +} + +/** + * struct typec_altmode_ops - Alternate mode specific operations vector + * @enter: Operations to be executed with Enter Mode Command + * @exit: Operations to be executed with Exit Mode Command + * @attention: Callback for Attention Command + * @vdm: Callback for SVID specific commands + * @notify: Communication channel for platform and the alternate mode + */ +struct typec_altmode_ops { + void (*enter)(struct typec_altmode *altmode); + void (*exit)(struct typec_altmode *altmode); + void (*attention)(struct typec_altmode *altmode, const u32 vdo); + int (*vdm)(struct typec_altmode *altmode, const u32 hdr, + const u32 *vdo, int cnt); + int (*notify)(struct typec_altmode *altmode, unsigned long conf, + void *data); +}; + +void typec_altmode_register_ops(struct typec_altmode *altmode, + const struct typec_altmode_ops *ops); + +int typec_altmode_enter(struct typec_altmode *altmode); +int typec_altmode_exit(struct typec_altmode *altmode); +void typec_altmode_attention(struct typec_altmode *altmode, const u32 vdo); +int typec_altmode_vdm(struct typec_altmode *altmode, + const u32 header, const u32 *vdo, int count); +int typec_altmode_notify(struct typec_altmode *altmode, unsigned long conf, + void *data); + +/* Return values for type_altmode_vdm() */ +#define VDM_DONE 0 /* Don't care */ +#define VDM_OK 1 /* Suits me */ + +/* + * These are the pin states (USB, Safe and Alt Mode) and accessory modes (Audio + * and Debug) defined in USB Type-C Specification. SVID specific pin states are + * expected to follow and start from the value TYPEC_STATE_MODAL. + * + * Port drivers should use TYPEC_STATE_AUDIO and TYPEC_STATE_DEBUG as the + * operation value for typec_set_mode() when accessory modes are in use. + * + * NOTE: typec_altmode_notify() does not accept values smaller then + * TYPEC_STATE_MODAL. USB Type-C bus will follow USB Type-C Specification with + * TYPEC_STATE_USB and TYPEC_STATE_SAFE. + */ +enum { + TYPEC_STATE_USB, /* USB Operation */ + TYPEC_STATE_AUDIO, /* Audio Accessory */ + TYPEC_STATE_DEBUG, /* Debug Accessory */ + TYPEC_STATE_SAFE, /* USB Safe State */ + TYPEC_STATE_MODAL, /* Alternate Modes */ +}; + +#define TYPEC_MODAL_STATE(_state_) ((_state_) + TYPEC_STATE_MODAL) + +struct typec_altmode *typec_altmode_get_plug(struct typec_altmode *altmode, + int index); +void typec_altmode_put_plug(struct typec_altmode *plug); + +bool typec_altmode_ufp_capable(struct typec_altmode *altmode); +bool typec_altmode_dfp_capable(struct typec_altmode *altmode); +struct typec_altmode *typec_match_altmode(struct typec_altmode **altmodes, + size_t n, u16 svid, u8 mode); + +/** + * struct typec_altmode_driver - USB Type-C alternate mode device driver + * @id_table: Null terminated array of SVIDs + * @probe: Callback for device binding + * @remove: Callback for device unbinding + * @driver: Device driver model driver + * + * These drivers will be bind to the partner alternate mode devices. They will + * handle all SVID specific communication. + */ +struct typec_altmode_driver { + const struct typec_device_id *id_table; + int (*probe)(struct typec_altmode *altmode, u32 port_vdo); + void (*remove)(struct typec_altmode *altmode); + struct device_driver driver; +}; + +#define to_altmode_driver(d) container_of(d, struct typec_altmode_driver, \ + driver) + +#define typec_altmode_register_driver(drv) \ + __typec_altmode_register_driver(drv, THIS_MODULE) +int __typec_altmode_register_driver(struct typec_altmode_driver *drv, + struct module *module); +void typec_altmode_unregister_driver(struct typec_altmode_driver *drv); + +#define module_typec_altmode_driver(__typec_altmode_driver) \ + module_driver(__typec_altmode_driver, typec_altmode_register_driver, \ + typec_altmode_unregister_driver) + +#endif /* __USB_TYPEC_ALTMODE_H */ diff --git a/scripts/mod/devicetable-offsets.c b/scripts/mod/devicetable-offsets.c index 9fad6afe4c41..c48c7f56ae64 100644 --- a/scripts/mod/devicetable-offsets.c +++ b/scripts/mod/devicetable-offsets.c @@ -218,5 +218,9 @@ int main(void) DEVID_FIELD(tb_service_id, protocol_version); DEVID_FIELD(tb_service_id, protocol_revision); + DEVID(typec_device_id); + DEVID_FIELD(typec_device_id, svid); + DEVID_FIELD(typec_device_id, mode); + return 0; } diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c index b9beeaa4695b..a8afba836409 100644 --- a/scripts/mod/file2alias.c +++ b/scripts/mod/file2alias.c @@ -1341,6 +1341,19 @@ static int do_tbsvc_entry(const char *filename, void *symval, char *alias) } ADD_TO_DEVTABLE("tbsvc", tb_service_id, do_tbsvc_entry); +/* Looks like: typec:idNmN */ +static int do_typec_entry(const char *filename, void *symval, char *alias) +{ + DEF_FIELD(symval, typec_device_id, svid); + DEF_FIELD(symval, typec_device_id, mode); + + sprintf(alias, "typec:id%04X", svid); + ADD(alias, "m", mode != TYPEC_ANY_MODE, mode); + + return 1; +} +ADD_TO_DEVTABLE("typec", typec_device_id, do_typec_entry); + /* Does namelen bytes of name exactly match the symbol? */ static bool sym_is(const char *name, unsigned namelen, const char *symbol) { -- 2.16.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: [RFC,v2,2/3] usb: typec: Bus type for alternate modes From: Heikki Krogerus Message-Id: <20180309151918.22048-3-heikki.krogerus@linux.intel.com> Date: Fri, 9 Mar 2018 18:19:17 +0300 To: Greg Kroah-Hartman , Guenter Roeck , Hans de Goede Cc: Jun Li , "Regupathy, Rajaram" , linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org List-ID: SW50cm9kdWNpbmcgYSBzaW1wbGUgYnVzIGZvciB0aGUgYWx0ZXJuYXRlIG1vZGVzLiBCdXMgYWxs b3dzCmJpbmRpbmcgZHJpdmVycyB0byB0aGUgZGlzY292ZXJlZCBhbHRlcm5hdGUgbW9kZXMgdGhl CnBhcnRuZXJzIHN1cHBvcnQuCgpTaWduZWQtb2ZmLWJ5OiBIZWlra2kgS3JvZ2VydXMgPGhlaWtr aS5rcm9nZXJ1c0BsaW51eC5pbnRlbC5jb20+Ci0tLQogRG9jdW1lbnRhdGlvbi9BQkkvb2Jzb2xl dGUvc3lzZnMtY2xhc3MtdHlwZWMgfCAgNDggKysrCiBEb2N1bWVudGF0aW9uL0FCSS90ZXN0aW5n L3N5c2ZzLWJ1cy10eXBlYyAgICB8ICA1MSArKysrCiBEb2N1bWVudGF0aW9uL0FCSS90ZXN0aW5n L3N5c2ZzLWNsYXNzLXR5cGVjICB8ICA2MiArLS0tCiBEb2N1bWVudGF0aW9uL2RyaXZlci1hcGkv dXNiL3R5cGVjX2J1cy5yc3QgICB8IDE0MyArKysrKysrKysKIGRyaXZlcnMvdXNiL3R5cGVjL01h a2VmaWxlICAgICAgICAgICAgICAgICAgIHwgICAyICstCiBkcml2ZXJzL3VzYi90eXBlYy9idXMu YyAgICAgICAgICAgICAgICAgICAgICB8IDQyMSArKysrKysrKysrKysrKysrKysrKysrKysrKysK IGRyaXZlcnMvdXNiL3R5cGVjL2J1cy5oICAgICAgICAgICAgICAgICAgICAgIHwgIDM3ICsrKwog ZHJpdmVycy91c2IvdHlwZWMvY2xhc3MuYyAgICAgICAgICAgICAgICAgICAgfCAzMjUgKysrKysr KysrKysrKysrKystLS0tCiBpbmNsdWRlL2xpbnV4L21vZF9kZXZpY2V0YWJsZS5oICAgICAgICAg ICAgICB8ICAxNSArCiBpbmNsdWRlL2xpbnV4L3VzYi90eXBlYy5oICAgICAgICAgICAgICAgICAg ICB8ICAxNiArLQogaW5jbHVkZS9saW51eC91c2IvdHlwZWNfYWx0bW9kZS5oICAgICAgICAgICAg fCAxMzYgKysrKysrKysrCiBzY3JpcHRzL21vZC9kZXZpY2V0YWJsZS1vZmZzZXRzLmMgICAgICAg ICAgICB8ICAgNCArCiBzY3JpcHRzL21vZC9maWxlMmFsaWFzLmMgICAgICAgICAgICAgICAgICAg ICB8ICAxMyArCiAxMyBmaWxlcyBjaGFuZ2VkLCAxMTM4IGluc2VydGlvbnMoKyksIDEzNSBkZWxl dGlvbnMoLSkKIGNyZWF0ZSBtb2RlIDEwMDY0NCBEb2N1bWVudGF0aW9uL0FCSS9vYnNvbGV0ZS9z eXNmcy1jbGFzcy10eXBlYwogY3JlYXRlIG1vZGUgMTAwNjQ0IERvY3VtZW50YXRpb24vQUJJL3Rl c3Rpbmcvc3lzZnMtYnVzLXR5cGVjCiBjcmVhdGUgbW9kZSAxMDA2NDQgRG9jdW1lbnRhdGlvbi9k cml2ZXItYXBpL3VzYi90eXBlY19idXMucnN0CiBjcmVhdGUgbW9kZSAxMDA2NDQgZHJpdmVycy91 c2IvdHlwZWMvYnVzLmMKIGNyZWF0ZSBtb2RlIDEwMDY0NCBkcml2ZXJzL3VzYi90eXBlYy9idXMu aAogY3JlYXRlIG1vZGUgMTAwNjQ0IGluY2x1ZGUvbGludXgvdXNiL3R5cGVjX2FsdG1vZGUuaAoK ZGlmZiAtLWdpdCBhL0RvY3VtZW50YXRpb24vQUJJL29ic29sZXRlL3N5c2ZzLWNsYXNzLXR5cGVj IGIvRG9jdW1lbnRhdGlvbi9BQkkvb2Jzb2xldGUvc3lzZnMtY2xhc3MtdHlwZWMKbmV3IGZpbGUg bW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMDAwMDAwLi4zMjYyMzUxNGVlODcKLS0tIC9kZXYvbnVs bAorKysgYi9Eb2N1bWVudGF0aW9uL0FCSS9vYnNvbGV0ZS9zeXNmcy1jbGFzcy10eXBlYwpAQCAt MCwwICsxLDQ4IEBACitUaGVzZSBmaWxlcyBhcmUgZGVwcmVjYXRlZCBhbmQgd2lsbCBiZSByZW1v dmVkLiBUaGUgc2FtZSBmaWxlcyBhcmUgYXZhaWxhYmxlCit1bmRlciAvc3lzL2J1cy90eXBlYyAo c2VlIERvY3VtZW50YXRpb24vQUJJL3Rlc3Rpbmcvc3lzZnMtYnVzLXR5cGVjKS4KKworV2hhdDoJ CS9zeXMvY2xhc3MvdHlwZWMvPHBvcnR8cGFydG5lcnxjYWJsZT4vPGRldj4vc3ZpZAorRGF0ZToJ CUFwcmlsIDIwMTcKK0NvbnRhY3Q6CUhlaWtraSBLcm9nZXJ1cyA8aGVpa2tpLmtyb2dlcnVzQGxp bnV4LmludGVsLmNvbT4KK0Rlc2NyaXB0aW9uOgorCQlUaGUgU1ZJRCAoU3RhbmRhcmQgb3IgVmVu ZG9yIElEKSBhc3NpZ25lZCBieSBVU0ItSUYgZm9yIHRoaXMKKwkJYWx0ZXJuYXRlIG1vZGUuCisK K1doYXQ6CQkvc3lzL2NsYXNzL3R5cGVjLzxwb3J0fHBhcnRuZXJ8Y2FibGU+LzxkZXY+L21vZGU8 aW5kZXg+LworRGF0ZToJCUFwcmlsIDIwMTcKK0NvbnRhY3Q6CUhlaWtraSBLcm9nZXJ1cyA8aGVp a2tpLmtyb2dlcnVzQGxpbnV4LmludGVsLmNvbT4KK0Rlc2NyaXB0aW9uOgorCQlFdmVyeSBzdXBw b3J0ZWQgbW9kZSB3aWxsIGhhdmUgaXRzIG93biBkaXJlY3RvcnkuIFRoZSBuYW1lIG9mCisJCWEg bW9kZSB3aWxsIGJlICJtb2RlPGluZGV4PiIgKGZvciBleGFtcGxlIG1vZGUxKSwgd2hlcmUgPGlu ZGV4PgorCQlpcyB0aGUgYWN0dWFsIGluZGV4IHRvIHRoZSBtb2RlIFZETyByZXR1cm5lZCBieSBE aXNjb3ZlciBNb2RlcworCQlVU0IgcG93ZXIgZGVsaXZlcnkgY29tbWFuZC4KKworV2hhdDoJCS9z eXMvY2xhc3MvdHlwZWMvPHBvcnR8cGFydG5lcnxjYWJsZT4vPGRldj4vbW9kZTxpbmRleD4vZGVz Y3JpcHRpb24KK0RhdGU6CQlBcHJpbCAyMDE3CitDb250YWN0OglIZWlra2kgS3JvZ2VydXMgPGhl aWtraS5rcm9nZXJ1c0BsaW51eC5pbnRlbC5jb20+CitEZXNjcmlwdGlvbjoKKwkJU2hvd3MgZGVz Y3JpcHRpb24gb2YgdGhlIG1vZGUuIFRoZSBkZXNjcmlwdGlvbiBpcyBvcHRpb25hbCBmb3IKKwkJ dGhlIGRyaXZlcnMsIGp1c3QgbGlrZSB3aXRoIHRoZSBCaWxsYm9hcmQgRGV2aWNlcy4KKworV2hh dDoJCS9zeXMvY2xhc3MvdHlwZWMvPHBvcnR8cGFydG5lcnxjYWJsZT4vPGRldj4vbW9kZTxpbmRl eD4vdmRvCitEYXRlOgkJQXByaWwgMjAxNworQ29udGFjdDoJSGVpa2tpIEtyb2dlcnVzIDxoZWlr a2kua3JvZ2VydXNAbGludXguaW50ZWwuY29tPgorRGVzY3JpcHRpb246CisJCVNob3dzIHRoZSBW RE8gaW4gaGV4YWRlY2ltYWwgcmV0dXJuZWQgYnkgRGlzY292ZXIgTW9kZXMgY29tbWFuZAorCQlm b3IgdGhpcyBtb2RlLgorCitXaGF0OgkJL3N5cy9jbGFzcy90eXBlYy88cG9ydHxwYXJ0bmVyfGNh YmxlPi88ZGV2Pi9tb2RlPGluZGV4Pi9hY3RpdmUKK0RhdGU6CQlBcHJpbCAyMDE3CitDb250YWN0 OglIZWlra2kgS3JvZ2VydXMgPGhlaWtraS5rcm9nZXJ1c0BsaW51eC5pbnRlbC5jb20+CitEZXNj cmlwdGlvbjoKKwkJU2hvd3MgaWYgdGhlIG1vZGUgaXMgYWN0aXZlIG9yIG5vdC4gVGhlIGF0dHJp YnV0ZSBjYW4gYmUgdXNlZAorCQlmb3IgZW50ZXJpbmcvZXhpdGluZyB0aGUgbW9kZSB3aXRoIHBh cnRuZXJzIGFuZCBjYWJsZSBwbHVncywgYW5kCisJCXdpdGggdGhlIHBvcnQgYWx0ZXJuYXRlIG1v ZGVzIGl0IGNhbiBiZSB1c2VkIGZvciBkaXNhYmxpbmcKKwkJc3VwcG9ydCBmb3Igc3BlY2lmaWMg YWx0ZXJuYXRlIG1vZGVzLiBFbnRlcmluZy9leGl0aW5nIG1vZGVzIGlzCisJCXN1cHBvcnRlZCBh cyBzeW5jaHJvbm91cyBvcGVyYXRpb24gc28gd3JpdGUoMikgdG8gdGhlIGF0dHJpYnV0ZQorCQlk b2VzIG5vdCByZXR1cm4gdW50aWwgdGhlIGVudGVyL2V4aXQgbW9kZSBvcGVyYXRpb24gaGFzCisJ CWZpbmlzaGVkLiBUaGUgYXR0cmlidXRlIGlzIG5vdGlmaWVkIHdoZW4gdGhlIG1vZGUgaXMKKwkJ ZW50ZXJlZC9leGl0ZWQgc28gcG9sbCgyKSBvbiB0aGUgYXR0cmlidXRlIHdha2VzIHVwLgorCQlF bnRlcmluZy9leGl0aW5nIGEgbW9kZSB3aWxsIGFsc28gZ2VuZXJhdGUgdWV2ZW50IEtPQkpfQ0hB TkdFLgorCisJCVZhbGlkIHZhbHVlczogeWVzLCBubwpkaWZmIC0tZ2l0IGEvRG9jdW1lbnRhdGlv bi9BQkkvdGVzdGluZy9zeXNmcy1idXMtdHlwZWMgYi9Eb2N1bWVudGF0aW9uL0FCSS90ZXN0aW5n L3N5c2ZzLWJ1cy10eXBlYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwMDAwMDAu LmVhZDYzZjk3ZDlhMgotLS0gL2Rldi9udWxsCisrKyBiL0RvY3VtZW50YXRpb24vQUJJL3Rlc3Rp bmcvc3lzZnMtYnVzLXR5cGVjCkBAIC0wLDAgKzEsNTEgQEAKK1doYXQ6CQkvc3lzL2J1cy90eXBl Yy9kZXZpY2VzLy4uLi9hY3RpdmUKK0RhdGU6CQlBcHJpbCAyMDE4CitDb250YWN0OglIZWlra2kg S3JvZ2VydXMgPGhlaWtraS5rcm9nZXJ1c0BsaW51eC5pbnRlbC5jb20+CitEZXNjcmlwdGlvbjoK KwkJU2hvd3MgaWYgdGhlIG1vZGUgaXMgYWN0aXZlIG9yIG5vdC4gVGhlIGF0dHJpYnV0ZSBjYW4g YmUgdXNlZAorCQlmb3IgZW50ZXJpbmcvZXhpdGluZyB0aGUgbW9kZS4gRW50ZXJpbmcvZXhpdGlu ZyBtb2RlcyBpcworCQlzdXBwb3J0ZWQgYXMgc3luY2hyb25vdXMgb3BlcmF0aW9uIHNvIHdyaXRl KDIpIHRvIHRoZSBhdHRyaWJ1dGUKKwkJZG9lcyBub3QgcmV0dXJuIHVudGlsIHRoZSBlbnRlci9l eGl0IG1vZGUgb3BlcmF0aW9uIGhhcworCQlmaW5pc2hlZC4gVGhlIGF0dHJpYnV0ZSBpcyBub3Rp ZmllZCB3aGVuIHRoZSBtb2RlIGlzCisJCWVudGVyZWQvZXhpdGVkIHNvIHBvbGwoMikgb24gdGhl IGF0dHJpYnV0ZSB3YWtlcyB1cC4KKwkJRW50ZXJpbmcvZXhpdGluZyBhIG1vZGUgd2lsbCBhbHNv IGdlbmVyYXRlIHVldmVudCBLT0JKX0NIQU5HRS4KKworCQlWYWxpZCB2YWx1ZXMgYXJlIGJvb2xl YW4uCisKK1doYXQ6CQkvc3lzL2J1cy90eXBlYy9kZXZpY2VzLy4uLi9kZXNjcmlwdGlvbgorRGF0 ZToJCUFwcmlsIDIwMTgKK0NvbnRhY3Q6CUhlaWtraSBLcm9nZXJ1cyA8aGVpa2tpLmtyb2dlcnVz QGxpbnV4LmludGVsLmNvbT4KK0Rlc2NyaXB0aW9uOgorCQlTaG93cyBkZXNjcmlwdGlvbiBvZiB0 aGUgbW9kZS4gVGhlIGRlc2NyaXB0aW9uIGlzIG9wdGlvbmFsIGZvcgorCQl0aGUgZHJpdmVycywg anVzdCBsaWtlIHdpdGggdGhlIEJpbGxib2FyZCBEZXZpY2VzLgorCitXaGF0OgkJL3N5cy9idXMv dHlwZWMvZGV2aWNlcy8uLi4vbW9kZQorRGF0ZToJCUFwcmlsIDIwMTgKK0NvbnRhY3Q6CUhlaWtr aSBLcm9nZXJ1cyA8aGVpa2tpLmtyb2dlcnVzQGxpbnV4LmludGVsLmNvbT4KK0Rlc2NyaXB0aW9u OgorCQlUaGUgaW5kZXggbnVtYmVyIG9mIHRoZSBtb2RlIHJldHVybmVkIGJ5IERpc2NvdmVyIE1v ZGVzIFVTQgorCQlQb3dlciBEZWxpdmVyeSBjb21tYW5kLiBEZXBlbmRpbmcgb24gdGhlIGFsdGVy bmF0ZSBtb2RlLCB0aGUKKwkJbW9kZSBpbmRleCBtYXkgYmUgc2lnbmlmaWNhbnQuCisKKwkJV2l0 aCBzb21lIGFsdGVybmF0ZSBtb2RlcyAoU1ZJRHMpLCB0aGUgbW9kZSBpbmRleCBpcyBhc3NpZ25l ZAorCQlmb3Igc3BlY2lmaWMgZnVuY3Rpb25hbGl0eSBpbiB0aGUgc3BlY2lmaWNhdGlvbiBmb3Ig dGhhdAorCQlhbHRlcm5hdGUgbW9kZS4KKworCQlXaXRoIG90aGVyIGFsdGVybmF0ZSBtb2Rlcywg dGhlIG1vZGUgaW5kZXggdmFsdWVzIGFyZSBub3QKKwkJYXNzaWduZWQsIGFuZCBjYW4gbm90IGJl IHRoZXJlZm9yZSB1c2VkIGZvciBpZGVudGlmaWNhdGlvbi4gV2hlbgorCQl0aGUgbW9kZSBpbmRl eCBpcyBub3QgYXNzaWduZWQsIGlkZW50aWZ5aW5nIHRoZSBhbHRlcm5hdGUgbW9kZQorCQltdXN0 IGJlIGRvbmUgd2l0aCBlaXRoZXIgbW9kZSBWRE8gb3IgdGhlIGRlc2NyaXB0aW9uLgorCitXaGF0 OgkJL3N5cy9idXMvdHlwZWMvZGV2aWNlcy8uLi4vc3ZpZAorRGF0ZToJCUFwcmlsIDIwMTgKK0Nv bnRhY3Q6CUhlaWtraSBLcm9nZXJ1cyA8aGVpa2tpLmtyb2dlcnVzQGxpbnV4LmludGVsLmNvbT4K K0Rlc2NyaXB0aW9uOgorCQlUaGUgU3RhbmRhcmQgb3IgVmVuZG9yIElEIChTVklEKSBhc3NpZ25l ZCBieSBVU0ItSUYgZm9yIHRoaXMKKwkJYWx0ZXJuYXRlIG1vZGUuCisKK1doYXQ6CQkvc3lzL2J1 cy90eXBlYy9kZXZpY2VzLy4uLi92ZG8KK0RhdGU6CQlBcHJpbCAyMDE4CitDb250YWN0OglIZWlr a2kgS3JvZ2VydXMgPGhlaWtraS5rcm9nZXJ1c0BsaW51eC5pbnRlbC5jb20+CitEZXNjcmlwdGlv bjoKKwkJU2hvd3MgdGhlIFZETyBpbiBoZXhhZGVjaW1hbCByZXR1cm5lZCBieSBEaXNjb3ZlciBN b2RlcyBjb21tYW5kCisJCWZvciB0aGlzIG1vZGUuCmRpZmYgLS1naXQgYS9Eb2N1bWVudGF0aW9u L0FCSS90ZXN0aW5nL3N5c2ZzLWNsYXNzLXR5cGVjIGIvRG9jdW1lbnRhdGlvbi9BQkkvdGVzdGlu Zy9zeXNmcy1jbGFzcy10eXBlYwppbmRleCA1YmU1NTJlMjU1ZTkuLmQ3NjQ3YjI1OGMzYyAxMDA2 NDQKLS0tIGEvRG9jdW1lbnRhdGlvbi9BQkkvdGVzdGluZy9zeXNmcy1jbGFzcy10eXBlYworKysg Yi9Eb2N1bWVudGF0aW9uL0FCSS90ZXN0aW5nL3N5c2ZzLWNsYXNzLXR5cGVjCkBAIC0yMjIsNzAg KzIyMiwxMiBAQCBEZXNjcmlwdGlvbjoKIAkJYXZhaWxhYmxlLiBUaGUgdmFsdWUgY2FuIGJlIHBv bGxlZC4KIAogCi1BbHRlcm5hdGUgTW9kZSBkZXZpY2VzLgorVVNCIFR5cGUtQyBwb3J0IGFsdGVy bmF0ZSBtb2RlIGRldmljZXMuCiAKLVRoZSBhbHRlcm5hdGUgbW9kZXMgd2lsbCBoYXZlIFN0YW5k YXJkIG9yIFZlbmRvciBJRCAoU1ZJRCkgYXNzaWduZWQgYnkgVVNCLUlGLgotVGhlIHBvcnRzLCBw YXJ0bmVycyBhbmQgY2FibGUgcGx1Z3MgY2FuIGhhdmUgYWx0ZXJuYXRlIG1vZGVzLiBBIHN1cHBv cnRlZCBTVklECi13aWxsIGNvbnNpc3Qgb2YgYSBzZXQgb2YgbW9kZXMuIEV2ZXJ5IFNWSUQgYSBw b3J0L3BhcnRuZXIvcGx1ZyBzdXBwb3J0cyB3aWxsCi1oYXZlIGEgZGV2aWNlIGNyZWF0ZWQgZm9y IGl0LCBhbmQgZXZlcnkgc3VwcG9ydGVkIG1vZGUgZm9yIGEgc3VwcG9ydGVkIFNWSUQgd2lsbAot aGF2ZSBpdHMgb3duIGRpcmVjdG9yeSB1bmRlciB0aGF0IGRldmljZS4gQmVsb3cgPGRldj4gcmVm ZXJzIHRvIHRoZSBkZXZpY2UgZm9yCi10aGUgYWx0ZXJuYXRlIG1vZGUuCi0KLVdoYXQ6CQkvc3lz L2NsYXNzL3R5cGVjLzxwb3J0fHBhcnRuZXJ8Y2FibGU+LzxkZXY+L3N2aWQKLURhdGU6CQlBcHJp bCAyMDE3Ci1Db250YWN0OglIZWlra2kgS3JvZ2VydXMgPGhlaWtraS5rcm9nZXJ1c0BsaW51eC5p bnRlbC5jb20+Ci1EZXNjcmlwdGlvbjoKLQkJVGhlIFNWSUQgKFN0YW5kYXJkIG9yIFZlbmRvciBJ RCkgYXNzaWduZWQgYnkgVVNCLUlGIGZvciB0aGlzCi0JCWFsdGVybmF0ZSBtb2RlLgotCi1XaGF0 OgkJL3N5cy9jbGFzcy90eXBlYy88cG9ydHxwYXJ0bmVyfGNhYmxlPi88ZGV2Pi9tb2RlPGluZGV4 Pi8KLURhdGU6CQlBcHJpbCAyMDE3Ci1Db250YWN0OglIZWlra2kgS3JvZ2VydXMgPGhlaWtraS5r cm9nZXJ1c0BsaW51eC5pbnRlbC5jb20+Ci1EZXNjcmlwdGlvbjoKLQkJRXZlcnkgc3VwcG9ydGVk IG1vZGUgd2lsbCBoYXZlIGl0cyBvd24gZGlyZWN0b3J5LiBUaGUgbmFtZSBvZgotCQlhIG1vZGUg d2lsbCBiZSAibW9kZTxpbmRleD4iIChmb3IgZXhhbXBsZSBtb2RlMSksIHdoZXJlIDxpbmRleD4K LQkJaXMgdGhlIGFjdHVhbCBpbmRleCB0byB0aGUgbW9kZSBWRE8gcmV0dXJuZWQgYnkgRGlzY292 ZXIgTW9kZXMKLQkJVVNCIHBvd2VyIGRlbGl2ZXJ5IGNvbW1hbmQuCi0KLVdoYXQ6CQkvc3lzL2Ns YXNzL3R5cGVjLzxwb3J0fHBhcnRuZXJ8Y2FibGU+LzxkZXY+L21vZGU8aW5kZXg+L2Rlc2NyaXB0 aW9uCi1EYXRlOgkJQXByaWwgMjAxNwotQ29udGFjdDoJSGVpa2tpIEtyb2dlcnVzIDxoZWlra2ku a3JvZ2VydXNAbGludXguaW50ZWwuY29tPgotRGVzY3JpcHRpb246Ci0JCVNob3dzIGRlc2NyaXB0 aW9uIG9mIHRoZSBtb2RlLiBUaGUgZGVzY3JpcHRpb24gaXMgb3B0aW9uYWwgZm9yCi0JCXRoZSBk cml2ZXJzLCBqdXN0IGxpa2Ugd2l0aCB0aGUgQmlsbGJvYXJkIERldmljZXMuCi0KLVdoYXQ6CQkv c3lzL2NsYXNzL3R5cGVjLzxwb3J0fHBhcnRuZXJ8Y2FibGU+LzxkZXY+L21vZGU8aW5kZXg+L3Zk bwotRGF0ZToJCUFwcmlsIDIwMTcKLUNvbnRhY3Q6CUhlaWtraSBLcm9nZXJ1cyA8aGVpa2tpLmty b2dlcnVzQGxpbnV4LmludGVsLmNvbT4KLURlc2NyaXB0aW9uOgotCQlTaG93cyB0aGUgVkRPIGlu IGhleGFkZWNpbWFsIHJldHVybmVkIGJ5IERpc2NvdmVyIE1vZGVzIGNvbW1hbmQKLQkJZm9yIHRo aXMgbW9kZS4KLQotV2hhdDoJCS9zeXMvY2xhc3MvdHlwZWMvPHBvcnR8cGFydG5lcnxjYWJsZT4v PGRldj4vbW9kZTxpbmRleD4vYWN0aXZlCi1EYXRlOgkJQXByaWwgMjAxNwotQ29udGFjdDoJSGVp a2tpIEtyb2dlcnVzIDxoZWlra2kua3JvZ2VydXNAbGludXguaW50ZWwuY29tPgotRGVzY3JpcHRp b246Ci0JCVNob3dzIGlmIHRoZSBtb2RlIGlzIGFjdGl2ZSBvciBub3QuIFRoZSBhdHRyaWJ1dGUg Y2FuIGJlIHVzZWQKLQkJZm9yIGVudGVyaW5nL2V4aXRpbmcgdGhlIG1vZGUgd2l0aCBwYXJ0bmVy cyBhbmQgY2FibGUgcGx1Z3MsIGFuZAotCQl3aXRoIHRoZSBwb3J0IGFsdGVybmF0ZSBtb2RlcyBp dCBjYW4gYmUgdXNlZCBmb3IgZGlzYWJsaW5nCi0JCXN1cHBvcnQgZm9yIHNwZWNpZmljIGFsdGVy bmF0ZSBtb2Rlcy4gRW50ZXJpbmcvZXhpdGluZyBtb2RlcyBpcwotCQlzdXBwb3J0ZWQgYXMgc3lu Y2hyb25vdXMgb3BlcmF0aW9uIHNvIHdyaXRlKDIpIHRvIHRoZSBhdHRyaWJ1dGUKLQkJZG9lcyBu b3QgcmV0dXJuIHVudGlsIHRoZSBlbnRlci9leGl0IG1vZGUgb3BlcmF0aW9uIGhhcwotCQlmaW5p c2hlZC4gVGhlIGF0dHJpYnV0ZSBpcyBub3RpZmllZCB3aGVuIHRoZSBtb2RlIGlzCi0JCWVudGVy ZWQvZXhpdGVkIHNvIHBvbGwoMikgb24gdGhlIGF0dHJpYnV0ZSB3YWtlcyB1cC4KLQkJRW50ZXJp bmcvZXhpdGluZyBhIG1vZGUgd2lsbCBhbHNvIGdlbmVyYXRlIHVldmVudCBLT0JKX0NIQU5HRS4K LQotCQlWYWxpZCB2YWx1ZXM6IHllcywgbm8KLQotV2hhdDoJCS9zeXMvY2xhc3MvdHlwZWMvPHBv cnQ+LzxkZXY+L21vZGU8aW5kZXg+L3N1cHBvcnRlZF9yb2xlcworV2hhdDoJCS9zeXMvY2xhc3Mv dHlwZWMvPHBvcnQ+LzxhbHQgbW9kZT4vc3VwcG9ydGVkX3JvbGVzCiBEYXRlOgkJQXByaWwgMjAx NwogQ29udGFjdDoJSGVpa2tpIEtyb2dlcnVzIDxoZWlra2kua3JvZ2VydXNAbGludXguaW50ZWwu Y29tPgogRGVzY3JpcHRpb246CiAJCVNwYWNlIHNlcGFyYXRlZCBsaXN0IG9mIHRoZSBzdXBwb3J0 ZWQgcm9sZXMuCiAKLQkJVGhpcyBhdHRyaWJ1dGUgaXMgYXZhaWxhYmxlIGZvciB0aGUgZGV2aWNl cyBkZXNjcmliaW5nIHRoZQotCQlhbHRlcm5hdGUgbW9kZXMgYSBwb3J0IHN1cHBvcnRzLCBhbmQg aXQgd2lsbCBub3QgYmUgZXhwb3NlZCB3aXRoCi0JCXRoZSBkZXZpY2VzIHByZXNlbnRpbmcgdGhl IGFsdGVybmF0ZSBtb2RlcyB0aGUgcGFydG5lcnMgb3IgY2FibGUKLQkJcGx1Z3Mgc3VwcG9ydC4K LQogCQlWYWxpZCB2YWx1ZXM6IHNvdXJjZSwgc2luawpkaWZmIC0tZ2l0IGEvRG9jdW1lbnRhdGlv bi9kcml2ZXItYXBpL3VzYi90eXBlY19idXMucnN0IGIvRG9jdW1lbnRhdGlvbi9kcml2ZXItYXBp L3VzYi90eXBlY19idXMucnN0Cm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAwMDAw MC4uZWYzYzA0OWE4YTdmCi0tLSAvZGV2L251bGwKKysrIGIvRG9jdW1lbnRhdGlvbi9kcml2ZXIt YXBpL3VzYi90eXBlY19idXMucnN0CkBAIC0wLDAgKzEsMTQzIEBACisKK0FQSSBmb3IgVVNCIFR5 cGUtQyBBbHRlcm5hdGUgTW9kZSBkcml2ZXJzCis9PT09PT09PT09PT09PT09PT09PT09PT09PT09 PT09PT09PT09PT09PQorCitJbnRyb2R1Y3Rpb24KKy0tLS0tLS0tLS0tLQorCitBbHRlcm5hdGUg bW9kZXMgcmVxdWlyZSBjb21tdW5pY2F0aW9uIHdpdGggdGhlIHBhcnRuZXIgdXNpbmcgVmVuZG9y IERlZmluZWQKK01lc3NhZ2VzIChWRE0pIGFzIGRlZmluZWQgaW4gVVNCIFR5cGUtQyBhbmQgVVNC IFBvd2VyIERlbGl2ZXJ5IFNwZWNpZmljYXRpb25zLgorVGhlIGNvbW11bmljYXRpb24gaXMgU1ZJ RCAoU3RhbmRhcmQgb3IgVmVuZG9yIElEKSBzcGVjaWZpYywgaS5lLiBzcGVjaWZpYyBmb3IKK2V2 ZXJ5IGFsdGVybmF0ZSBtb2RlLCBzbyBldmVyeSBhbHRlcm5hdGUgbW9kZSB3aWxsIG5lZWQgY3Vz dG9tIGRyaXZlci4KKworVVNCIFR5cGUtQyBidXMgYWxsb3dzIGJpbmRpbmcgYSBkcml2ZXIgdG8g dGhlIGRpc2NvdmVyZWQgcGFydG5lciBhbHRlcm5hdGUKK21vZGVzIGJ5IHVzaW5nIHRoZSBTVklE IGFuZCB0aGUgbW9kZSBudW1iZXIuCisKK1VTQiBUeXBlLUMgQ29ubmVjdG9yIENsYXNzIHByb3Zp ZGVzIGEgZGV2aWNlIGZvciBldmVyeSBhbHRlcm5hdGUgbW9kZSBhIHBvcnQKK3N1cHBvcnRzLCBh bmQgc2VwYXJhdGUgZGV2aWNlIGZvciBldmVyeSBhbHRlcm5hdGUgbW9kZSB0aGUgcGFydG5lciBz dXBwb3J0cy4KK1RoZSBkcml2ZXJzIGZvciB0aGUgYWx0ZXJuYXRlIG1vZGVzIGFyZSBiaW5kIHRv IHRoZSBwYXJ0bmVyIGFsdGVybmF0ZSBtb2RlCitkZXZpY2VzLCBhbmQgdGhlIHBvcnQgYWx0ZXJu YXRlIG1vZGUgZGV2aWNlcyBtdXN0IGJlIGhhbmRsZWQgYnkgdGhlIHBvcnQKK2RyaXZlcnMuCisK K1doZW4gYSBuZXcgcGFydG5lciBhbHRlcm5hdGUgbW9kZSBkZXZpY2UgaXMgcmVnaXN0ZXJlZCwg aXQgaXMgbGlua2VkIHRvIHRoZQorYWx0ZXJuYXRlIG1vZGUgZGV2aWNlIG9mIHRoZSBwb3J0IHRo YXQgdGhlIHBhcnRuZXIgaXMgYXR0YWNoZWQgdG8sIHRoYXQgaGFzCittYXRjaGluZyBTVklEIGFu ZCBtb2RlLiBDb21tdW5pY2F0aW9uIGJldHdlZW4gdGhlIHBvcnQgZHJpdmVyIGFuZCBhbHRlcm5h dGUgbW9kZQorZHJpdmVyIHdpbGwgaGFwcGVuIHVzaW5nIHRoZSBzYW1lIEFQSS4KKworVGhlIHBv cnQgYWx0ZXJuYXRlIG1vZGUgZGV2aWNlcyBhcmUgdXNlZCBhcyBhIHByb3h5IGJldHdlZW4gdGhl IHBhcnRuZXIgYW5kIHRoZQorYWx0ZXJuYXRlIG1vZGUgZHJpdmVycywgc28gdGhlIHBvcnQgZHJp dmVycyBhcmUgb25seSBleHBlY3RlZCB0byBwYXNzIHRoZSBTVklECitzcGVjaWZpYyBjb21tYW5k cyBmcm9tIHRoZSBhbHRlcm5hdGUgbW9kZSBkcml2ZXJzIHRvIHRoZSBwYXJ0bmVyLCBhbmQgZnJv bSB0aGUKK3BhcnRuZXJzIHRvIHRoZSBhbHRlcm5hdGUgbW9kZSBkcml2ZXJzLiBObyBkaXJlY3Qg U1ZJRCBzcGVjaWZpYyBjb21tdW5pY2F0aW9uIGlzCituZWVkZWQgZnJvbSB0aGUgcG9ydCBkcml2 ZXJzLCBidXQgdGhlIHBvcnQgZHJpdmVycyBuZWVkIHRvIHByb3ZpZGUgdGhlIG9wZXJhdGlvbgor Y2FsbGJhY2tzIGZvciB0aGUgcG9ydCBhbHRlcm5hdGUgbW9kZSBkZXZpY2VzLCBqdXN0IGxpa2Ug dGhlIGFsdGVybmF0ZSBtb2RlCitkcml2ZXJzIG5lZWQgdG8gcHJvdmlkZSB0aGVtIGZvciB0aGUg cGFydG5lciBhbHRlcm5hdGUgbW9kZSBkZXZpY2VzLgorCitVc2FnZToKKy0tLS0tLQorCitHZW5l cmFsCit+fn5+fn5+CisKK0J5IGRlZmF1bHQsIHRoZSBhbHRlcm5hdGUgbW9kZSBkcml2ZXJzIGFy ZSByZXNwb25zaWJsZSBmb3IgZW50ZXJpbmcgdGhlIG1vZGUuCitJdCBpcyBhbHNvIHBvc3NpYmxl IHRvIGxlYXZlIHRoZSBkZWNpc2lvbiBhYm91dCBlbnRlcmluZyB0aGUgbW9kZSB0byB0aGUgdXNl cgorc3BhY2UgKFNlZSBEb2N1bWVudGF0aW9uL0FCSS90ZXN0aW5nL3N5c2ZzLWNsYXNzLXR5cGVj KS4gUG9ydCBkcml2ZXJzIHNob3VsZCBub3QKK2VudGVyIGFueSBtb2RlcyBvbiB0aGVpciBvd24u CisKK1RoZSBhbHRlcm5hdGUgbW9kZSBkcml2ZXJzIG5lZWQgdG8gcmVnaXN0ZXIgdGhlaXIgb3Bl cmF0aW9uIHZlY3RvciBpbiB0aGVpcgorYGAtPnByb2JlYGAgY2FsbGJhY2sgd2l0aCA6YzpmdW5j OmB0eXBlY19hbHRtb2RlX3JlZ2lzdGVyX29wcygpYC4gVGhleSBzaG91bGQKK2JlIHJlZ2lzdGVy ZWQgYmVmb3JlIHRoZSBtb2RlIGlzIGVudGVyZWQgdXNpbmcgOmM6ZnVuYzpgdHlwZWNfYWx0bW9k ZV9lbnRlcigpYC4KKworYGAtPnZkbWBgIGlzIHRoZSBtb3N0IGltcG9ydGFudCBjYWxsYmFjayBp biB0aGUgdmVjdG9yLiBJdCB3aWxsIGJlIHVzZWQgdG8KK2RlbGl2ZXIgYWxsIHRoZSBTVklEIHNw ZWNpZmljIGNvbW1hbmRzIGZyb20gdGhlIHBhcnRuZXIgdG8gdGhlIGFsdGVybmF0ZSBtb2RlCitk cml2ZXIsIGFuZCB2aXNlIHZlcnNhIGluIGNhc2Ugb2YgcG9ydCBkcml2ZXJzLiBUaGUgZHJpdmVy cyBzZW5kIHRoZSBTVklECitzcGVjaWZpYyBjb21tYW5kcyB0byBlYWNoIG90aGVyIHVzaW5nIDpj OmZ1bmM6YHR5cGVjX2FsdG1vZGVfdm1kKClgLgorCitJZiB0aGUgY29tbXVuaWNhdGlvbiB3aXRo IHRoZSBwYXJ0bmVyIHVzaW5nIHRoZSBTVklEIHNwZWNpZmljIGNvbW1hbmRzIHJlc3VsdHMKK2lu IG5lZWQgdG8gcmUtY29uZmlndXJlIHRoZSBwaW5zIG9uIHRoZSBjb25uZWN0b3IsIHRoZSBhbHRl cm5hdGUgbW9kZSBkcml2ZXIKK25lZWRzIHRvIG5vdGlmeSB0aGUgYnVzIHVzaW5nIDpjOmZ1bmM6 YHR5cGVjX2FsdG1vZGVfbm90aWZ5KClgLiBUaGUgZHJpdmVyCitwYXNzZXMgdGhlIG5lZ290aWF0 ZWQgU1ZJRCBzcGVjaWZpYyBwaW4gY29uZmlndXJhdGlvbiB2YWx1ZSB0byB0aGUgZnVuY3Rpb24g YXMKK3BhcmFtZXRlci4gVGhlIGJ1cyBkcml2ZXIgd2lsbCB0aGVuIGNvbmZpZ3VyZSB0aGUgbXV4 IGJlaGluZCB0aGUgY29ubmVjdG9yIHVzaW5nCit0aGF0IHZhbHVlIGFzIHRoZSBzdGF0ZSB2YWx1 ZSBmb3IgdGhlIG11eCwgYW5kIGFsc28gY2FsbCBibG9ja2luZyBub3RpZmljYXRpb24KK2NoYWlu IHRvIG5vdGlmeSB0aGUgZXh0ZXJuYWwgZHJpdmVycyBhYm91dCB0aGUgc3RhdGUgb2YgdGhlIGNv bm5lY3RvciB0aGF0IG5lZWQKK3RvIGtub3cgaXQuCisKK05PVEU6IFRoZSBTVklEIHNwZWNpZmlj IHBpbiBjb25maWd1cmF0aW9uIHZhbHVlcyBtdXN0IGFsd2F5cyBzdGFydCBmcm9tCitgYFRZUEVD X1NUQVRFX01PREFMYGAuIFVTQiBUeXBlLUMgc3BlY2lmaWNhdGlvbiBkZWZpbmVzIHR3byBkZWZh dWx0IHN0YXRlcyBmb3IKK3RoZSBjb25uZWN0b3I6IGBgVFlQRUNfU1RBVEVfVVNCYGAgYW5kIGBg VFlQRUNfU1RBVEVfU0FGRWBgLiBVU0IgVHlwZS1DCitTcGVjaWZpY2F0aW9uIGFsc28gZGVmaW5l cyB0d28gQWNjZXNzb3J5IG1vZGVzLCBBdWRpbyBhbmQgRGVidWc6CitgYFRZUEVDX1NUQVRFX0FV RElPYGAgYW5kIGBgVFlQRUNfU1RBVEVfREVCVUdgYCBUaGVzZSB2YWx1ZXMgYXJlIHJlc2VydmVk IGJ5IHRoZQorYnVzIGFzIHRoZSBmb3VyIGZpcnN0IHBvc3NpYmxlIHZhbHVlcyBmb3IgdGhlIHN0 YXRlLCBhbmQgYXR0ZW1wdHMgdG8gdXNlIHRoZW0KK2Zyb20gdGhlIGFsdGVybmF0ZSBtb2RlIGRy aXZlcnMgd2lsbCByZXN1bHQgaW4gZmFpbHVyZS4gV2hlbiB0aGUgYWx0ZXJuYXRlIG1vZGUKK2lz IGVudGVyZWQsIHRoZSBidXMgd2lsbCBwdXQgdGhlIGNvbm5lY3RvciBpbnRvIGBgVFlQRUNfU1RB VEVfU0FGRWBgIGJlZm9yZQorc2VuZGluZyBFbnRlciBvciBFeGl0IE1vZGUgY29tbWFuZCBhcyBk ZWZpbmVkIGluIFVTQiBUeXBlLUMgU3BlY2lmaWNhdGlvbiwgYW5kCithbHNvIHB1dCB0aGUgY29u bmVjdG9yIGJhY2sgdG8gYGBUWVBFQ19TVEFURV9VU0JgYCBhZnRlciB0aGUgbW9kZSBoYXMgYmVl bgorZXhpdGVkLgorCitBbiBleGFtcGxlIG9mIHdvcmtpbmcgZGVmaW5pdGlvbnMgZm9yIFNWSUQg c3BlY2lmaWMgcGluIGNvbmZpZ3VyYXRpb25zIHdvdWxkCitsb29rIGxpa2UgdGhpczoKKworZW51 bSB7CisJQUxUTU9ERVhfQ09ORl9BID0gVFlQRUNfU1RBVEVfTU9EQUwsCisJQUxUTU9ERVhfQ09O Rl9CLAorCS4uLgorfTsKKworSGVscGVyIG1hY3JvIGBgVFlQRUNfTU9EQUxfU1RBVEUoKWBgIGNh biBhbHNvIGJlIHVzZWQ6CisKKyNkZWZpbmUgQUxUTU9ERVhfQ09ORl9BID0gVFlQRUNfTU9EQUxf U1RBVEUoMCk7CisjZGVmaW5lIEFMVE1PREVYX0NPTkZfQiA9IFRZUEVDX01PREFMX1NUQVRFKDEp OworCitOb3RpZmljYXRpb24gY2hhaW4KK35+fn5+fn5+fn5+fn5+fn5+fgorCitUaGUgZHJpdmVy cyBmb3IgdGhlIGNvbXBvbmVudHMgdGhhdCB0aGUgYWx0ZXJuYXRlIG1vZGVzIGFyZSBkZXNpZ25l ZCBmb3IgbmVlZCB0bworZ2V0IGRldGFpbHMgcmVnYXJkaW5nIHRoZSByZXN1bHRzIG9mIHRoZSBu ZWdvdGlhdGlvbiB3aXRoIHRoZSBwYXJ0bmVyLCBhbmQgdGhlCitwaW4gY29uZmlndXJhdGlvbiBv ZiB0aGUgY29ubmVjdG9yLiBJbiBjYXNlIG9mIERpc3BsYXlQb3J0IGFsdGVybmF0ZSBtb2RlIGZv cgorZXhhbXBsZSwgdGhlIEdQVSBkcml2ZXJzIHdpbGwgbmVlZCB0byBrbm93IHRob3NlIGRldGFp bHMuIEluIGNhc2Ugb2YKK1RodW5kZXJib2x0IGFsdGVybmF0ZSBtb2RlLCB0aGUgdGh1bmRlcmJv bHQgZHJpdmVycyB3aWxsIG5lZWQgdG8ga25vdyB0aGVtLCBhbmQKK3NvIG9uLgorCitUaGUgbm90 aWZpY2F0aW9uIGNoYWluIGlzIGRlc2lnbmVkIGZvciB0aGlzIHB1cnBvc2UuIFRoZSBkcml2ZXJz IGNhbiByZWdpc3Rlcgorbm90aWZpZXJzIHdpdGggOmM6ZnVuYzpgdHlwZWNfYWx0bW9kZV9yZWdp c3Rlcl9ub3RpZmllcigpYC4KKworQ2FibGUgcGx1ZyBhbHRlcm5hdGUgbW9kZXMKK35+fn5+fn5+ fn5+fn5+fn5+fn5+fn5+fn5+CisKK1RoZSBhbHRlcm5hdGUgbW9kZSBkcml2ZXJzIGFyZSBub3Qg YmluZCB0byBjYWJsZSBwbHVnIGFsdGVybmF0ZSBtb2RlIGRldmljZXMsCitvbmx5IHRvIHRoZSBw YXJ0bmVyIGFsdGVybmF0ZSBtb2RlIGRldmljZXMuIElmIHRoZSBhbHRlcm5hdGUgbW9kZSBzdXBw b3J0cywgb3IKK3JlcXVpcmVzLCBhIGNhYmxlIHRoYXQgcmVzcG9uZHMgdG8gU09QIFByaW1lLCBh bmQgb3B0aW9uYWxseSBTT1AgRG91YmxlIFByaW1lCittZXNzYWdlcywgdGhlIGRyaXZlciBmb3Ig dGhhdCBhbHRlcm5hdGUgbW9kZSBtdXN0IHJlcXVlc3QgaGFuZGxlIHRvIHRoZSBjYWJsZQorcGx1 ZyBhbHRlcm5hdGUgbW9kZXMgdXNpbmcgOmM6ZnVuYzpgdHlwZWNfYWx0bW9kZV9nZXRfcGx1Zygp YCwgYW5kIHRha2luZyBvdmVyCit0aGVpciBjb250cm9sLgorCitEcml2ZXIgQVBJCistLS0tLS0t LS0tCisKK0FsdGVybmF0ZSBtb2RlIGRyaXZlciByZWdpc3RlcmluZy91bnJlZ2lzdGVyaW5nCit+ fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fgorCisuLiBrZXJu ZWwtZG9jOjogZHJpdmVycy91c2IvdHlwZWMvYnVzLmMKKyAgIDpmdW5jdGlvbnM6IHR5cGVjX2Fs dG1vZGVfcmVnaXN0ZXJfZHJpdmVyIHR5cGVjX2FsdG1vZGVfdW5yZWdpc3Rlcl9kcml2ZXIKKwor QWx0ZXJuYXRlIG1vZGUgZHJpdmVyIG9wZXJhdGlvbnMKK35+fn5+fn5+fn5+fn5+fn5+fn5+fn5+ fn5+fn5+fn5+CisKKy4uIGtlcm5lbC1kb2M6OiBkcml2ZXJzL3VzYi90eXBlYy9idXMuYworICAg OmZ1bmN0aW9uczogdHlwZWNfYWx0bW9kZV9yZWdpc3Rlcl9vcHMgdHlwZWNfYWx0bW9kZV9lbnRl ciB0eXBlY19hbHRtb2RlX2V4aXQgdHlwZWNfYWx0bW9kZV9hdHRlbnRpb24gdHlwZWNfYWx0bW9k ZV92ZG0gdHlwZWNfYWx0bW9kZV9ub3RpZnkKKworQVBJIGZvciB0aGUgcG9ydCBkcml2ZXJzCit+ fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn4KKworLi4ga2VybmVsLWRvYzo6IGRyaXZlcnMvdXNiL3R5 cGVjL2J1cy5jCisgICA6ZnVuY3Rpb25zOiB0eXBlY19tYXRjaF9hbHRtb2RlCisKK0NhYmxlIFBs dWcgb3BlcmF0aW9ucworfn5+fn5+fn5+fn5+fn5+fn5+fn5+CisKKy4uIGtlcm5lbC1kb2M6OiBk cml2ZXJzL3VzYi90eXBlYy9idXMuYworICAgOmZ1bmN0aW9uczogdHlwZWNfYWx0bW9kZV9nZXRf cGx1ZyB0eXBlY19hbHRtb2RlX3B1dF9wbHVnCisKK05vdGlmaWNhdGlvbnMKK35+fn5+fn5+fn5+ fn4KKy4uIGtlcm5lbC1kb2M6OiBkcml2ZXJzL3VzYi90eXBlYy9jbGFzcy5jCisgICA6ZnVuY3Rp b25zOiB0eXBlY19hbHRtb2RlX3JlZ2lzdGVyX25vdGlmaWVyIHR5cGVjX2FsdG1vZGVfdW5yZWdp c3Rlcl9ub3RpZmllcgpkaWZmIC0tZ2l0IGEvZHJpdmVycy91c2IvdHlwZWMvTWFrZWZpbGUgYi9k cml2ZXJzL3VzYi90eXBlYy9NYWtlZmlsZQppbmRleCAxZjU5OWE2YzMwY2MuLjU0NjZjNjJjOGU5 NyAxMDA2NDQKLS0tIGEvZHJpdmVycy91c2IvdHlwZWMvTWFrZWZpbGUKKysrIGIvZHJpdmVycy91 c2IvdHlwZWMvTWFrZWZpbGUKQEAgLTEsNiArMSw2IEBACiAjIFNQRFgtTGljZW5zZS1JZGVudGlm aWVyOiBHUEwtMi4wCiBvYmotJChDT05GSUdfVFlQRUMpCQkrPSB0eXBlYy5vCi10eXBlYy15CQkJ CTo9IGNsYXNzLm8gbXV4Lm8KK3R5cGVjLXkJCQkJOj0gY2xhc3MubyBtdXgubyBidXMubwogb2Jq LSQoQ09ORklHX1RZUEVDX1RDUE0pCSs9IHRjcG0ubwogb2JqLXkJCQkJKz0gZnVzYjMwMi8KIG9i ai0kKENPTkZJR19UWVBFQ19XQ09WRSkJKz0gdHlwZWNfd2NvdmUubwpkaWZmIC0tZ2l0IGEvZHJp dmVycy91c2IvdHlwZWMvYnVzLmMgYi9kcml2ZXJzL3VzYi90eXBlYy9idXMuYwpuZXcgZmlsZSBt b2RlIDEwMDY0NAppbmRleCAwMDAwMDAwMDAwMDAuLjkyOTQ0YWFmM2Q2YQotLS0gL2Rldi9udWxs CisrKyBiL2RyaXZlcnMvdXNiL3R5cGVjL2J1cy5jCkBAIC0wLDAgKzEsNDIxIEBACisvLyBTUERY LUxpY2Vuc2UtSWRlbnRpZmllcjogR1BMLTIuMAorLyoqCisgKiBCdXMgZm9yIFVTQiBUeXBlLUMg QWx0ZXJuYXRlIE1vZGVzCisgKgorICogQ29weXJpZ2h0IChDKSAyMDE4IEludGVsIENvcnBvcmF0 aW9uCisgKiBBdXRob3I6IEhlaWtraSBLcm9nZXJ1cyA8aGVpa2tpLmtyb2dlcnVzQGxpbnV4Lmlu dGVsLmNvbT4KKyAqLworCisjaW5jbHVkZSAiYnVzLmgiCisKKy8qIC0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t ICovCisvKiBDb21tb24gQVBJICovCisKKy8qKgorICogdHlwZWNfYWx0bW9kZV9ub3RpZnkgLSBD b21tdW5pY2F0aW9uIGJldHdlZW4gdGhlIE9TIGFuZCBhbHRlcm5hdGUgbW9kZSBkcml2ZXIKKyAq IEBhZGV2OiBIYW5kbGUgdG8gdGhlIGFsdGVybmF0ZSBtb2RlCisgKiBAY29uZjogQWx0ZXJuYXRl IG1vZGUgc3BlY2lmaWMgY29uZmlndXJhdGlvbiB2YWx1ZQorICogQGRhdGE6IEFsdGVybmF0ZSBt b2RlIHNwZWNpZmljIGRhdGEKKyAqCisgKiBUaGUgcHJpbWFyeSBwdXJwb3NlIGZvciB0aGlzIGZ1 bmN0aW9uIGlzIHRvIGFsbG93IHRoZSBhbHRlcm5hdGUgbW9kZSBkcml2ZXJzCisgKiB0byB0ZWxs IHdoaWNoIHBpbiBjb25maWd1cmF0aW9uIGhhcyBiZWVuIG5lZ290aWF0ZWQgd2l0aCB0aGUgcGFy dG5lci4gVGhhdAorICogaW5mb3JtYXRpb24gd2lsbCB0aGVuIGJlIHVzZWQgZm9yIGV4YW1wbGUg dG8gY29uZmlndXJlIHRoZSBtdXhlcy4KKyAqIENvbW11bmljYXRpb24gdG8gdGhlIG90aGVyIGRp cmVjdGlvbiBpcyBhbHNvIHBvc3NpYmxlLCBhbmQgbG93IGxldmVsIGRldmljZQorICogZHJpdmVy cyBjYW4gYWxzbyBzZW5kIG5vdGlmaWNhdGlvbnMgdG8gdGhlIGFsdGVybmF0ZSBtb2RlIGRyaXZl cnMuIFRoZSBhY3R1YWwKKyAqIGNvbW11bmljYXRpb24gd2lsbCBiZSBzcGVjaWZpYyBmb3IgZXZl cnkgU1ZJRC4KKyAqLworaW50IHR5cGVjX2FsdG1vZGVfbm90aWZ5KHN0cnVjdCB0eXBlY19hbHRt b2RlICphZGV2LAorCQkJIHVuc2lnbmVkIGxvbmcgY29uZiwgdm9pZCAqZGF0YSkKK3sKKwlzdHJ1 Y3QgYWx0bW9kZSAqYWx0bW9kZTsKKwlzdHJ1Y3QgYWx0bW9kZSAqcGFydG5lcjsKKwlpbnQgcmV0 OworCisJLyoKKwkgKiBBbGwgU1ZJRCBzcGVjaWZpYyBjb25maWd1cmF0aW9uIHZhbHVlcyBtdXN0 IHN0YXJ0IGZyb20KKwkgKiBUWVBFQ19TVEFURV9NT0RBTC4gVGhlIGZpcnN0IHZhbHVlcyBhcmUg cmVzZXJ2ZWQgZm9yIHRoZSBwaW4gc3RhdGVzCisJICogZGVmaW5lZCBpbiBVU0IgVHlwZS1DIHNw ZWNpZmljYXRpb246IFRZUEVDX1NUQVRFX1VTQiBhbmQKKwkgKiBUWVBFQ19TVEFURV9TQUZFLiBX ZSdsbCBmb2xsb3cgdGhpcyBydWxlIGV2ZW4gd2l0aCBtb2RlcyB0aGF0IGRvIG5vdAorCSAqIHJl cXVpcmUgcGluIHJlY29uZmlndXJhdGlvbiBmb3IgdGhlIHNha2Ugb2Ygc2ltcGxpY2l0eS4KKwkg Ki8KKwlpZiAoY29uZiA8IFRZUEVDX1NUQVRFX01PREFMKQorCQlyZXR1cm4gLUVJTlZBTDsKKwor CWlmICghYWRldikKKwkJcmV0dXJuIDA7CisKKwlhbHRtb2RlID0gdG9fYWx0bW9kZShhZGV2KTsK KworCWlmICghYWx0bW9kZS0+cGFydG5lcikKKwkJcmV0dXJuIC1FTk9ERVY7CisKKwlyZXQgPSB0 eXBlY19zZXRfbW9kZSh0eXBlY19hbHRtb2RlMnBvcnQoYWRldiksIChpbnQpY29uZik7CisJaWYg KHJldCkKKwkJcmV0dXJuIHJldDsKKworCXBhcnRuZXIgPSBhbHRtb2RlLT5wYXJ0bmVyOworCisJ YmxvY2tpbmdfbm90aWZpZXJfY2FsbF9jaGFpbihpc190eXBlY19wb3J0KGFkZXYtPmRldi5wYXJl bnQpID8KKwkJCQkgICAgICZhbHRtb2RlLT5uaCA6ICZwYXJ0bmVyLT5uaCwKKwkJCQkgICAgIGNv bmYsIGRhdGEpOworCisJaWYgKHBhcnRuZXItPm9wcyAmJiBwYXJ0bmVyLT5vcHMtPm5vdGlmeSkK KwkJcmV0dXJuIHBhcnRuZXItPm9wcy0+bm90aWZ5KCZwYXJ0bmVyLT5hZGV2LCBjb25mLCBkYXRh KTsKKworCXJldHVybiAwOworfQorRVhQT1JUX1NZTUJPTF9HUEwodHlwZWNfYWx0bW9kZV9ub3Rp ZnkpOworCisvKioKKyAqIHR5cGVjX2FsdG1vZGVfZW50ZXIgLSBFbnRlciBNb2RlCisgKiBAYWRl djogVGhlIGFsdGVybmF0ZSBtb2RlCisgKgorICogVGhlIGFsdGVybmF0ZSBtb2RlIGRyaXZlcnMg dXNlIHRoaXMgZnVuY3Rpb24gdG8gZW50ZXIgbW9kZS4gVGhlIHBvcnQgZHJpdmVycworICogdXNl IHRoaXMgdG8gaW5mb3JtIHRoZSBhbHRlcm5hdGUgbW9kZSBkcml2ZXJzIHRoYXQgdGhlaXIgbW9k ZSBoYXMgYmVlbgorICogZW50ZXJlZCBzdWNjZXNzZnVsbHkuCisgKi8KK2ludCB0eXBlY19hbHRt b2RlX2VudGVyKHN0cnVjdCB0eXBlY19hbHRtb2RlICphZGV2KQoreworCXN0cnVjdCBhbHRtb2Rl ICpwYXJ0bmVyID0gdG9fYWx0bW9kZShhZGV2KS0+cGFydG5lcjsKKwlzdHJ1Y3QgdHlwZWNfYWx0 bW9kZSAqcGRldiA9ICZwYXJ0bmVyLT5hZGV2OworCWludCByZXQ7CisKKwlpZiAoaXNfdHlwZWNf cG9ydChhZGV2LT5kZXYucGFyZW50KSkgeworCQl0eXBlY19hbHRtb2RlX3VwZGF0ZV9hY3RpdmUo cGRldiwgcGRldi0+bW9kZSwgdHJ1ZSk7CisJCXN5c2ZzX25vdGlmeSgmcGRldi0+ZGV2LmtvYmos IE5VTEwsICJhY3RpdmUiKTsKKwkJZ290byBlbnRlcl9tb2RlOworCX0KKworCWlmICghcGRldi0+ YWN0aXZlKQorCQlyZXR1cm4gLUVQRVJNOworCisJLyogRmlyc3QgbW92aW5nIHRvIFVTQiBTYWZl IFN0YXRlICovCisJcmV0ID0gdHlwZWNfc2V0X21vZGUodHlwZWNfYWx0bW9kZTJwb3J0KGFkZXYp LCBUWVBFQ19TVEFURV9TQUZFKTsKKwlpZiAocmV0KQorCQlyZXR1cm4gcmV0OworCisJYmxvY2tp bmdfbm90aWZpZXJfY2FsbF9jaGFpbigmcGFydG5lci0+bmgsIFRZUEVDX1NUQVRFX1NBRkUsIE5V TEwpOworCitlbnRlcl9tb2RlOgorCS8qIEVudGVyIE1vZGUgY29tbWFuZCAqLworCWlmIChwYXJ0 bmVyLT5vcHMgJiYgcGFydG5lci0+b3BzLT5lbnRlcikKKwkJcGFydG5lci0+b3BzLT5lbnRlcihw ZGV2KTsKKworCXJldHVybiAwOworfQorRVhQT1JUX1NZTUJPTF9HUEwodHlwZWNfYWx0bW9kZV9l bnRlcik7CisKKy8qKgorICogdHlwZWNfYWx0bW9kZV9lbnRlciAtIEV4aXQgTW9kZQorICogQGFk ZXY6IFRoZSBhbHRlcm5hdGUgbW9kZQorICoKKyAqIFRoZSBhbHRlcm5hdGUgbW9kZSBkcml2ZXJz IHVzZSB0aGlzIGZ1bmN0aW9uIHRvIGV4aXQgbW9kZS4gVGhlIHBvcnQgZHJpdmVycworICogY2Fu IGFsc28gaW5mb3JtIHRoZSBhbHRlcm5hdGUgbW9kZSBkcml2ZXJzIHdpdGggdGhpcyBmdW5jdGlv biB0aGF0IHRoZSBtb2RlCisgKiB3YXMgc3VjY2Vzc2Z1bGx5IGV4aXRlZC4KKyAqLworaW50IHR5 cGVjX2FsdG1vZGVfZXhpdChzdHJ1Y3QgdHlwZWNfYWx0bW9kZSAqYWRldikKK3sKKwlzdHJ1Y3Qg YWx0bW9kZSAqcGFydG5lciA9IHRvX2FsdG1vZGUoYWRldiktPnBhcnRuZXI7CisJc3RydWN0IHR5 cGVjX3BvcnQgKnBvcnQgPSB0eXBlY19hbHRtb2RlMnBvcnQoYWRldik7CisJc3RydWN0IHR5cGVj X2FsdG1vZGUgKnBkZXYgPSAmcGFydG5lci0+YWRldjsKKwlpbnQgcmV0OworCisJLyogSW4gY2Fz ZSBvZiBwb3J0LCBqdXN0IGNhbGxpbmcgdGhlIGRyaXZlciBhbmQgZXhpdGluZyAqLworCWlmIChp c190eXBlY19wb3J0KGFkZXYtPmRldi5wYXJlbnQpKSB7CisJCXR5cGVjX2FsdG1vZGVfdXBkYXRl X2FjdGl2ZShwZGV2LCBwZGV2LT5tb2RlLCBmYWxzZSk7CisJCXN5c2ZzX25vdGlmeSgmcGRldi0+ ZGV2LmtvYmosIE5VTEwsICJhY3RpdmUiKTsKKworCQlpZiAocGFydG5lci0+b3BzICYmIHBhcnRu ZXItPm9wcy0+ZXhpdCkKKwkJCXBhcnRuZXItPm9wcy0+ZXhpdChwZGV2KTsKKwkJcmV0dXJuIDA7 CisJfQorCisJLyogTW92aW5nIHRvIFVTQiBTYWZlIFN0YXRlICovCisJcmV0ID0gdHlwZWNfc2V0 X21vZGUocG9ydCwgVFlQRUNfU1RBVEVfU0FGRSk7CisJaWYgKHJldCkKKwkJcmV0dXJuIHJldDsK KworCWJsb2NraW5nX25vdGlmaWVyX2NhbGxfY2hhaW4oJnBhcnRuZXItPm5oLCBUWVBFQ19TVEFU RV9TQUZFLCBOVUxMKTsKKworCS8qIEV4aXQgTW9kZSBjb21tYW5kICovCisJaWYgKHBhcnRuZXIt Pm9wcyAmJiBwYXJ0bmVyLT5vcHMtPmV4aXQpCisJCXBhcnRuZXItPm9wcy0+ZXhpdChwZGV2KTsK KworCS8qIEJhY2sgdG8gVVNCIG9wZXJhdGlvbiAqLworCXJldCA9IHR5cGVjX3NldF9tb2RlKHBv cnQsIFRZUEVDX1NUQVRFX1VTQik7CisJaWYgKHJldCkKKwkJcmV0dXJuIHJldDsKKworCWJsb2Nr aW5nX25vdGlmaWVyX2NhbGxfY2hhaW4oJnBhcnRuZXItPm5oLCBUWVBFQ19TVEFURV9VU0IsIE5V TEwpOworCisJcmV0dXJuIDA7Cit9CitFWFBPUlRfU1lNQk9MX0dQTCh0eXBlY19hbHRtb2RlX2V4 aXQpOworCisvKioKKyAqIHR5cGVjX2FsdG1vZGVfYXR0ZW50aW9uIC0gQXR0ZW50aW9uIGNvbW1h bmQKKyAqIEBhZGV2OiBUaGUgYWx0ZXJuYXRlIG1vZGUKKyAqIEB2ZG86IFZETyBmb3IgdGhlIEF0 dGVudGlvbiBjb21tYW5kCisgKgorICogTm90aWZpZXMgdGhlIHBhcnRuZXIgb2YgQGFkZXYgYWJv dXQgQXR0ZW50aW9uIGNvbW1hbmQuCisgKi8KK3ZvaWQgdHlwZWNfYWx0bW9kZV9hdHRlbnRpb24o c3RydWN0IHR5cGVjX2FsdG1vZGUgKmFkZXYsIGNvbnN0IHUzMiB2ZG8pCit7CisJc3RydWN0IGFs dG1vZGUgKnBhcnRuZXIgPSB0b19hbHRtb2RlKGFkZXYpLT5wYXJ0bmVyOworCisJaWYgKHBhcnRu ZXIgJiYgcGFydG5lci0+b3BzICYmIHBhcnRuZXItPm9wcy0+YXR0ZW50aW9uKQorCQlwYXJ0bmVy LT5vcHMtPmF0dGVudGlvbigmcGFydG5lci0+YWRldiwgdmRvKTsKK30KK0VYUE9SVF9TWU1CT0xf R1BMKHR5cGVjX2FsdG1vZGVfYXR0ZW50aW9uKTsKKworLyoqCisgKiB0eXBlY19hbHRtb2RlX3Zk bSAtIFNlbmQgVmVuZG9yIERlZmluZWQgTWVzc2FnZXMgKFZETSkgdG8gdGhlIHBhcnRuZXIKKyAq IEBhZGV2OiBBbHRlcm5hdGUgbW9kZSBoYW5kbGUKKyAqIEBoZWFkZXI6IFZETSBIZWFkZXIKKyAq IEB2ZG86IEFycmF5IG9mIFZlbmRvciBEZWZpbmVkIERhdGEgT2JqZWN0cworICogQGNvdW50OiBO dW1iZXIgb2YgRGF0YSBPYmplY3RzCisgKgorICogVGhlIGFsdGVybmF0ZSBtb2RlIGRyaXZlcnMg dXNlIHRoaXMgZnVuY3Rpb24gZm9yIFNWSUQgc3BlY2lmaWMgY29tbXVuaWNhdGlvbgorICogd2l0 aCB0aGUgcGFydG5lci4gVGhlIHBvcnQgZHJpdmVycyB1c2UgaXQgdG8gZGVsaXZlciB0aGUgU3Ry dWN0dXJlZCBWRE1zCisgKiByZWNlaXZlZCBmcm9tIHRoZSBwYXJ0bmVycyB0byB0aGUgYWx0ZXJu YXRlIG1vZGUgZHJpdmVycy4KKyAqLworaW50IHR5cGVjX2FsdG1vZGVfdmRtKHN0cnVjdCB0eXBl Y19hbHRtb2RlICphZGV2LAorCQkgICAgICBjb25zdCB1MzIgaGVhZGVyLCBjb25zdCB1MzIgKnZk bywgaW50IGNvdW50KQoreworCXN0cnVjdCBhbHRtb2RlICphbHRtb2RlOworCXN0cnVjdCBhbHRt b2RlICpwYXJ0bmVyOworCisJaWYgKCFhZGV2KQorCQlyZXR1cm4gMDsKKworCWFsdG1vZGUgPSB0 b19hbHRtb2RlKGFkZXYpOworCisJaWYgKCFhbHRtb2RlLT5wYXJ0bmVyKQorCQlyZXR1cm4gLUVO T0RFVjsKKworCXBhcnRuZXIgPSBhbHRtb2RlLT5wYXJ0bmVyOworCisJaWYgKHBhcnRuZXItPm9w cyAmJiBwYXJ0bmVyLT5vcHMtPnZkbSkKKwkJcmV0dXJuIHBhcnRuZXItPm9wcy0+dmRtKCZwYXJ0 bmVyLT5hZGV2LCBoZWFkZXIsIHZkbywgY291bnQpOworCisJcmV0dXJuIDA7Cit9CitFWFBPUlRf U1lNQk9MX0dQTCh0eXBlY19hbHRtb2RlX3ZkbSk7CisKK3ZvaWQgdHlwZWNfYWx0bW9kZV9yZWdp c3Rlcl9vcHMoc3RydWN0IHR5cGVjX2FsdG1vZGUgKmFkZXYsCisJCQkJY29uc3Qgc3RydWN0IHR5 cGVjX2FsdG1vZGVfb3BzICpvcHMpCit7CisJdG9fYWx0bW9kZShhZGV2KS0+b3BzID0gb3BzOwor fQorRVhQT1JUX1NZTUJPTF9HUEwodHlwZWNfYWx0bW9kZV9yZWdpc3Rlcl9vcHMpOworCisvKiAt LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLSAqLworLyogQVBJIGZvciB0aGUgYWx0ZXJuYXRlIG1vZGUgZHJpdmVy cyAqLworCisvKioKKyAqIHR5cGVjX2FsdG1vZGVfZ2V0X3BsdWcgLSBGaW5kIGNhYmxlIHBsdWcg YWx0ZXJuYXRlIG1vZGUKKyAqIEBhZGV2OiBIYW5kbGUgdG8gcGFydG5lciBhbHRlcm5hdGUgbW9k ZQorICogQGluZGV4OiBDYWJsZSBwbHVnIGluZGV4CisgKgorICogSW5jcmVtZW50IHJlZmVyZW5j ZSBjb3VudCBmb3IgY2FibGUgcGx1ZyBhbHRlcm5hdGUgbW9kZSBkZXZpY2UuIFJldHVybnMKKyAq IGhhbmRsZSB0byB0aGUgY2FibGUgcGx1ZyBhbHRlcm5hdGUgbW9kZSwgb3IgTlVMTCBpZiBub25l IGlzIGZvdW5kLgorICovCitzdHJ1Y3QgdHlwZWNfYWx0bW9kZSAqdHlwZWNfYWx0bW9kZV9nZXRf cGx1ZyhzdHJ1Y3QgdHlwZWNfYWx0bW9kZSAqYWRldiwKKwkJCQkJICAgICBpbnQgaW5kZXgpCit7 CisJc3RydWN0IGFsdG1vZGUgKnBvcnQgPSB0b19hbHRtb2RlKGFkZXYpLT5wYXJ0bmVyOworCisJ aWYgKHBvcnQtPnBsdWdbaW5kZXhdKSB7CisJCWdldF9kZXZpY2UoJnBvcnQtPnBsdWdbaW5kZXhd LT5hZGV2LmRldik7CisJCXJldHVybiAmcG9ydC0+cGx1Z1tpbmRleF0tPmFkZXY7CisJfQorCisJ cmV0dXJuIE5VTEw7Cit9CitFWFBPUlRfU1lNQk9MX0dQTCh0eXBlY19hbHRtb2RlX2dldF9wbHVn KTsKKworLyoqCisgKiB0eXBlY19hbHRtb2RlX2dldF9wbHVnIC0gRGVjcmVtZW50IGNhYmxlIHBs dWcgYWx0ZXJuYXRlIG1vZGUgcmVmZXJlbmNlIGNvdW50CisgKiBAcGx1ZzogSGFuZGxlIHRvIHRo ZSBjYWJsZSBwbHVnIGFsdGVybmF0ZSBtb2RlCisgKi8KK3ZvaWQgdHlwZWNfYWx0bW9kZV9wdXRf cGx1ZyhzdHJ1Y3QgdHlwZWNfYWx0bW9kZSAqcGx1ZykKK3sKKwlpZiAocGx1ZykKKwkJcHV0X2Rl dmljZSgmcGx1Zy0+ZGV2KTsKK30KK0VYUE9SVF9TWU1CT0xfR1BMKHR5cGVjX2FsdG1vZGVfcHV0 X3BsdWcpOworCitpbnQgX190eXBlY19hbHRtb2RlX3JlZ2lzdGVyX2RyaXZlcihzdHJ1Y3QgdHlw ZWNfYWx0bW9kZV9kcml2ZXIgKmRydiwKKwkJCQkgICAgc3RydWN0IG1vZHVsZSAqbW9kdWxlKQor eworCWlmICghZHJ2LT5wcm9iZSkKKwkJcmV0dXJuIC1FSU5WQUw7CisKKwlkcnYtPmRyaXZlci5v d25lciA9IG1vZHVsZTsKKwlkcnYtPmRyaXZlci5idXMgPSAmdHlwZWNfYnVzOworCisJcmV0dXJu IGRyaXZlcl9yZWdpc3RlcigmZHJ2LT5kcml2ZXIpOworfQorRVhQT1JUX1NZTUJPTF9HUEwoX190 eXBlY19hbHRtb2RlX3JlZ2lzdGVyX2RyaXZlcik7CisKK3ZvaWQgdHlwZWNfYWx0bW9kZV91bnJl Z2lzdGVyX2RyaXZlcihzdHJ1Y3QgdHlwZWNfYWx0bW9kZV9kcml2ZXIgKmRydikKK3sKKwlkcml2 ZXJfdW5yZWdpc3RlcigmZHJ2LT5kcml2ZXIpOworfQorRVhQT1JUX1NZTUJPTF9HUEwodHlwZWNf YWx0bW9kZV91bnJlZ2lzdGVyX2RyaXZlcik7CisKKy8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCisv KiBBUEkgZm9yIHRoZSBwb3J0IGRyaXZlcnMgKi8KKworYm9vbCB0eXBlY19hbHRtb2RlX3VmcF9j YXBhYmxlKHN0cnVjdCB0eXBlY19hbHRtb2RlICphZGV2KQoreworCXN0cnVjdCBhbHRtb2RlICph bHRtb2RlID0gdG9fYWx0bW9kZShhZGV2KTsKKworCWlmICghaXNfdHlwZWNfcG9ydChhZGV2LT5k ZXYucGFyZW50KSkKKwkJcmV0dXJuIGZhbHNlOworCisJcmV0dXJuICEoYWx0bW9kZS0+cm9sZXMg PT0gVFlQRUNfUE9SVF9ERlApOworfQorRVhQT1JUX1NZTUJPTF9HUEwodHlwZWNfYWx0bW9kZV91 ZnBfY2FwYWJsZSk7CisKK2Jvb2wgdHlwZWNfYWx0bW9kZV9kZnBfY2FwYWJsZShzdHJ1Y3QgdHlw ZWNfYWx0bW9kZSAqYWRldikKK3sKKwlzdHJ1Y3QgYWx0bW9kZSAqYWx0bW9kZSA9IHRvX2FsdG1v ZGUoYWRldik7CisKKwlpZiAoIWlzX3R5cGVjX3BvcnQoYWRldi0+ZGV2LnBhcmVudCkpCisJCXJl dHVybiBmYWxzZTsKKworCXJldHVybiAhKGFsdG1vZGUtPnJvbGVzID09IFRZUEVDX1BPUlRfVUZQ KTsKK30KK0VYUE9SVF9TWU1CT0xfR1BMKHR5cGVjX2FsdG1vZGVfZGZwX2NhcGFibGUpOworCisv KioKKyAqIHR5cGVjX21hdGNoX2FsdG1vZGUgLSBNYXRjaCBTVklEIHRvIGFuIGFycmF5IG9mIGFs dGVybmF0ZSBtb2RlcworICogQGFsdG1vZGVzOiBBcnJheSBvZiBhbHRlcm5hdGUgbW9kZXMKKyAq IEBuOiBOdW1iZXIgb2YgZWxlbWVudHMgaW4gdGhlIGFycmF5LCBvciAtMSBmb3IgTlVMTCB0ZXJt aWF0ZWQgYXJyYXlzCisgKiBAc3ZpZDogU3RhbmRhcmQgb3IgVmVuZG9yIElEIHRvIG1hdGNoIHdp dGgKKyAqCisgKiBSZXR1cm4gcG9pbnRlciB0byBhbiBhbHRlcm5hdGUgbW9kZSB3aXRoIFNWSUQg bWF0aGluZyBAc3ZpZCwgb3IgTlVMTCB3aGVuIG5vCisgKiBtYXRjaCBpcyBmb3VuZC4KKyAqLwor c3RydWN0IHR5cGVjX2FsdG1vZGUgKnR5cGVjX21hdGNoX2FsdG1vZGUoc3RydWN0IHR5cGVjX2Fs dG1vZGUgKiphbHRtb2RlcywKKwkJCQkJICBzaXplX3QgbiwgdTE2IHN2aWQsIHU4IG1vZGUpCit7 CisJaW50IGk7CisKKwlmb3IgKGkgPSAwOyBpIDwgbjsgaSsrKSB7CisJCWlmICghYWx0bW9kZXNb aV0pCisJCQlicmVhazsKKwkJaWYgKGFsdG1vZGVzW2ldLT5zdmlkID09IHN2aWQgJiYgYWx0bW9k ZXNbaV0tPm1vZGUgPT0gbW9kZSkKKwkJCXJldHVybiBhbHRtb2Rlc1tpXTsKKwl9CisKKwlyZXR1 cm4gTlVMTDsKK30KK0VYUE9SVF9TWU1CT0xfR1BMKHR5cGVjX21hdGNoX2FsdG1vZGUpOworCisv KiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLSAqLworCitzdGF0aWMgc3NpemVfdAorZGVzY3JpcHRpb25fc2hv dyhzdHJ1Y3QgZGV2aWNlICpkZXYsIHN0cnVjdCBkZXZpY2VfYXR0cmlidXRlICphdHRyLCBjaGFy ICpidWYpCit7CisJc3RydWN0IHR5cGVjX2FsdG1vZGUgKmFsdCA9IHRvX3R5cGVjX2FsdG1vZGUo ZGV2KTsKKworCXJldHVybiBzcHJpbnRmKGJ1ZiwgIiVzXG4iLCBhbHQtPmRlc2MgPyBhbHQtPmRl c2MgOiAiIik7Cit9CitzdGF0aWMgREVWSUNFX0FUVFJfUk8oZGVzY3JpcHRpb24pOworCitzdGF0 aWMgc3RydWN0IGF0dHJpYnV0ZSAqdHlwZWNfYXR0cnNbXSA9IHsKKwkmZGV2X2F0dHJfZGVzY3Jp cHRpb24uYXR0ciwKKwlOVUxMCit9OworQVRUUklCVVRFX0dST1VQUyh0eXBlYyk7CisKK3N0YXRp YyBpbnQgdHlwZWNfbWF0Y2goc3RydWN0IGRldmljZSAqZGV2LCBzdHJ1Y3QgZGV2aWNlX2RyaXZl ciAqZHJpdmVyKQoreworCXN0cnVjdCB0eXBlY19hbHRtb2RlX2RyaXZlciAqZHJ2ID0gdG9fYWx0 bW9kZV9kcml2ZXIoZHJpdmVyKTsKKwlzdHJ1Y3QgdHlwZWNfYWx0bW9kZSAqYWx0bW9kZSA9IHRv X3R5cGVjX2FsdG1vZGUoZGV2KTsKKwljb25zdCBzdHJ1Y3QgdHlwZWNfZGV2aWNlX2lkICppZDsK KworCWZvciAoaWQgPSBkcnYtPmlkX3RhYmxlOyBpZC0+c3ZpZDsgaWQrKykKKwkJaWYgKChpZC0+ c3ZpZCA9PSBhbHRtb2RlLT5zdmlkKSAmJgorCQkgICAgKGlkLT5tb2RlID09IFRZUEVDX0FOWV9N T0RFIHx8IGlkLT5tb2RlID09IGFsdG1vZGUtPm1vZGUpKQorCQkJcmV0dXJuIDE7CisJcmV0dXJu IDA7Cit9CisKK3N0YXRpYyBpbnQgdHlwZWNfdWV2ZW50KHN0cnVjdCBkZXZpY2UgKmRldiwgc3Ry dWN0IGtvYmpfdWV2ZW50X2VudiAqZW52KQoreworCXN0cnVjdCB0eXBlY19hbHRtb2RlICphbHRt b2RlID0gdG9fdHlwZWNfYWx0bW9kZShkZXYpOworCisJaWYgKGFkZF91ZXZlbnRfdmFyKGVudiwg IlNWSUQ9JTA0WCIsIGFsdG1vZGUtPnN2aWQpKQorCQlyZXR1cm4gLUVOT01FTTsKKworCWlmIChh ZGRfdWV2ZW50X3ZhcihlbnYsICJNT0RFPSV1IiwgYWx0bW9kZS0+bW9kZSkpCisJCXJldHVybiAt RU5PTUVNOworCisJcmV0dXJuIGFkZF91ZXZlbnRfdmFyKGVudiwgIk1PREFMSUFTPXR5cGVjOmlk JTA0WG0lMDJYIiwKKwkJCSAgICAgIGFsdG1vZGUtPnN2aWQsIGFsdG1vZGUtPm1vZGUpOworfQor CitzdGF0aWMgaW50IHR5cGVjX2FsdG1vZGVfY3JlYXRlX2xpbmtzKHN0cnVjdCBhbHRtb2RlICph bHQpCit7CisJc3RydWN0IGRldmljZSAqcG9ydF9kZXYgPSAmYWx0LT5wYXJ0bmVyLT5hZGV2LmRl djsKKwlzdHJ1Y3QgZGV2aWNlICpkZXYgPSAmYWx0LT5hZGV2LmRldjsKKwlpbnQgZXJyOworCisJ ZXJyID0gc3lzZnNfY3JlYXRlX2xpbmsoJmRldi0+a29iaiwgJnBvcnRfZGV2LT5rb2JqLCAicG9y dCIpOworCWlmIChlcnIpCisJCXJldHVybiBlcnI7CisKKwllcnIgPSBzeXNmc19jcmVhdGVfbGlu aygmcG9ydF9kZXYtPmtvYmosICZkZXYtPmtvYmosICJwYXJ0bmVyIik7CisJaWYgKGVycikKKwkJ c3lzZnNfcmVtb3ZlX2xpbmsoJmRldi0+a29iaiwgInBvcnQiKTsKKworCXJldHVybiBlcnI7Cit9 CisKK3N0YXRpYyBpbnQgdHlwZWNfcHJvYmUoc3RydWN0IGRldmljZSAqZGV2KQoreworCXN0cnVj dCB0eXBlY19hbHRtb2RlX2RyaXZlciAqZHJ2ID0gdG9fYWx0bW9kZV9kcml2ZXIoZGV2LT5kcml2 ZXIpOworCXN0cnVjdCB0eXBlY19hbHRtb2RlICphZGV2ID0gdG9fdHlwZWNfYWx0bW9kZShkZXYp OworCXN0cnVjdCBhbHRtb2RlICphbHRtb2RlID0gdG9fYWx0bW9kZShhZGV2KTsKKworCS8qIEZh aWwgaWYgdGhlIHBvcnQgZG9lcyBub3Qgc3VwcG9ydCB0aGUgYWx0ZXJuYXRlIG1vZGUgKi8KKwlp ZiAoIWFsdG1vZGUtPnBhcnRuZXIpCisJCXJldHVybiAtRU5PREVWOworCisJaWYgKHR5cGVjX2Fs dG1vZGVfY3JlYXRlX2xpbmtzKGFsdG1vZGUpKQorCQlkZXZfd2FybihkZXYsICJmYWlsZWQgdG8g Y3JlYXRlIHN5bWxpbmtzXG4iKTsKKworCXJldHVybiBkcnYtPnByb2JlKGFkZXYsIGFsdG1vZGUt PnBhcnRuZXItPmFkZXYudmRvKTsKK30KKworc3RhdGljIGludCB0eXBlY19yZW1vdmUoc3RydWN0 IGRldmljZSAqZGV2KQoreworCXN0cnVjdCB0eXBlY19hbHRtb2RlX2RyaXZlciAqZHJ2ID0gdG9f YWx0bW9kZV9kcml2ZXIoZGV2LT5kcml2ZXIpOworCXN0cnVjdCB0eXBlY19hbHRtb2RlICphZGV2 ID0gdG9fdHlwZWNfYWx0bW9kZShkZXYpOworCXN0cnVjdCBhbHRtb2RlICphbHRtb2RlID0gdG9f YWx0bW9kZShhZGV2KTsKKworCWlmICghaXNfdHlwZWNfcG9ydChhZGV2LT5kZXYucGFyZW50KSkg eworCQlzeXNmc19yZW1vdmVfbGluaygmYWx0bW9kZS0+cGFydG5lci0+YWRldi5kZXYua29iaiwg InBhcnRuZXIiKTsKKwkJc3lzZnNfcmVtb3ZlX2xpbmsoJmFkZXYtPmRldi5rb2JqLCAicG9ydCIp OworCX0KKworCWlmIChkcnYtPnJlbW92ZSkKKwkJZHJ2LT5yZW1vdmUodG9fdHlwZWNfYWx0bW9k ZShkZXYpKTsKKworCWlmIChhZGV2LT5hY3RpdmUpCisJCXR5cGVjX2FsdG1vZGVfZXhpdChhZGV2 KTsKKworCXJldHVybiAwOworfQorCitzdHJ1Y3QgYnVzX3R5cGUgdHlwZWNfYnVzID0geworCS5u YW1lID0gInR5cGVjIiwKKwkuZGV2X2dyb3VwcyA9IHR5cGVjX2dyb3VwcywKKwkubWF0Y2ggPSB0 eXBlY19tYXRjaCwKKwkudWV2ZW50ID0gdHlwZWNfdWV2ZW50LAorCS5wcm9iZSA9IHR5cGVjX3By b2JlLAorCS5yZW1vdmUgPSB0eXBlY19yZW1vdmUsCit9OwpkaWZmIC0tZ2l0IGEvZHJpdmVycy91 c2IvdHlwZWMvYnVzLmggYi9kcml2ZXJzL3VzYi90eXBlYy9idXMuaApuZXcgZmlsZSBtb2RlIDEw MDY0NAppbmRleCAwMDAwMDAwMDAwMDAuLjM4NTg1MzYzOTUyZgotLS0gL2Rldi9udWxsCisrKyBi L2RyaXZlcnMvdXNiL3R5cGVjL2J1cy5oCkBAIC0wLDAgKzEsMzcgQEAKKy8qIFNQRFgtTGljZW5z ZS1JZGVudGlmaWVyOiBHUEwtMi4wICovCisKKyNpZm5kZWYgX19VU0JfVFlQRUNfQUxUTU9ERV9I X18KKyNkZWZpbmUgX19VU0JfVFlQRUNfQUxUTU9ERV9IX18KKworI2luY2x1ZGUgPGxpbnV4L3Vz Yi90eXBlYy5oPgorCitzdHJ1Y3QgYnVzX3R5cGU7CisKK3N0cnVjdCBhbHRtb2RlIHsKKwl1bnNp Z25lZCBpbnQJCQlpZDsKKwlzdHJ1Y3QgdHlwZWNfYWx0bW9kZQkJYWRldjsKKworCWVudW0gdHlw ZWNfcG9ydF9kYXRhCQlyb2xlczsKKworCXN0cnVjdCBhdHRyaWJ1dGUJCSphdHRyc1s1XTsKKwlj aGFyCQkJCWdyb3VwX25hbWVbNl07CisJc3RydWN0IGF0dHJpYnV0ZV9ncm91cAkJZ3JvdXA7CisJ Y29uc3Qgc3RydWN0IGF0dHJpYnV0ZV9ncm91cAkqZ3JvdXBzWzJdOworCisJc3RydWN0IGFsdG1v ZGUJCQkqcGFydG5lcjsKKwlzdHJ1Y3QgYWx0bW9kZQkJCSpwbHVnWzJdOworCWNvbnN0IHN0cnVj dCB0eXBlY19hbHRtb2RlX29wcwkqb3BzOworCisJc3RydWN0IGJsb2NraW5nX25vdGlmaWVyX2hl YWQJbmg7Cit9OworCisjZGVmaW5lIHRvX2FsdG1vZGUoZCkgY29udGFpbmVyX29mKGQsIHN0cnVj dCBhbHRtb2RlLCBhZGV2KQorCitleHRlcm4gc3RydWN0IGJ1c190eXBlIHR5cGVjX2J1czsKK2V4 dGVybiBjb25zdCBzdHJ1Y3QgZGV2aWNlX3R5cGUgdHlwZWNfYWx0bW9kZV9kZXZfdHlwZTsKK2V4 dGVybiBjb25zdCBzdHJ1Y3QgZGV2aWNlX3R5cGUgdHlwZWNfcG9ydF9kZXZfdHlwZTsKKworI2Rl ZmluZSBpc190eXBlY19hbHRtb2RlKF9kZXZfKSAoX2Rldl8tPnR5cGUgPT0gJnR5cGVjX2FsdG1v ZGVfZGV2X3R5cGUpCisjZGVmaW5lIGlzX3R5cGVjX3BvcnQoX2Rldl8pIChfZGV2Xy0+dHlwZSA9 PSAmdHlwZWNfcG9ydF9kZXZfdHlwZSkKKworI2VuZGlmIC8qIF9fVVNCX1RZUEVDX0FMVE1PREVf SF9fICovCmRpZmYgLS1naXQgYS9kcml2ZXJzL3VzYi90eXBlYy9jbGFzcy5jIGIvZHJpdmVycy91 c2IvdHlwZWMvY2xhc3MuYwppbmRleCAyNmVlYWIxNDkxYjcuLjMzZmZmYjg1Mzk5NCAxMDA2NDQK LS0tIGEvZHJpdmVycy91c2IvdHlwZWMvY2xhc3MuYworKysgYi9kcml2ZXJzL3VzYi90eXBlYy9j bGFzcy5jCkBAIC02LDYgKzYsNyBAQAogICogQXV0aG9yOiBIZWlra2kgS3JvZ2VydXMgPGhlaWtr aS5rcm9nZXJ1c0BsaW51eC5pbnRlbC5jb20+CiAgKi8KIAorI2luY2x1ZGUgPGxpbnV4L2Nvbm5l Y3Rpb24uaD4KICNpbmNsdWRlIDxsaW51eC9kZXZpY2UuaD4KICNpbmNsdWRlIDxsaW51eC9tb2R1 bGUuaD4KICNpbmNsdWRlIDxsaW51eC9tdXRleC5oPgpAQCAtMTMsMjUgKzE0LDEyIEBACiAjaW5j bHVkZSA8bGludXgvdXNiL3R5cGVjLmg+CiAjaW5jbHVkZSA8bGludXgvdXNiL3R5cGVjX211eC5o PgogCi1zdHJ1Y3QgdHlwZWNfYWx0bW9kZSB7Ci0Jc3RydWN0IGRldmljZQkJCWRldjsKLQl1MTYJ CQkJc3ZpZDsKLQl1OAkJCQltb2RlOwotCi0JdTMyCQkJCXZkbzsKLQljaGFyCQkJCSpkZXNjOwot CWVudW0gdHlwZWNfcG9ydF90eXBlCQlyb2xlczsKLQl1bnNpZ25lZCBpbnQJCQlhY3RpdmU6MTsK LQotCXN0cnVjdCBhdHRyaWJ1dGUJCSphdHRyc1s1XTsKLQljaGFyCQkJCWdyb3VwX25hbWVbNl07 Ci0Jc3RydWN0IGF0dHJpYnV0ZV9ncm91cAkJZ3JvdXA7Ci0JY29uc3Qgc3RydWN0IGF0dHJpYnV0 ZV9ncm91cAkqZ3JvdXBzWzJdOwotfTsKKyNpbmNsdWRlICJidXMuaCIKIAogc3RydWN0IHR5cGVj X3BsdWcgewogCXN0cnVjdCBkZXZpY2UJCQlkZXY7CiAJZW51bSB0eXBlY19wbHVnX2luZGV4CQlp bmRleDsKKwlzdHJ1Y3QgaWRhCQkJbW9kZV9pZHM7CiB9OwogCiBzdHJ1Y3QgdHlwZWNfY2FibGUg ewpAQCAtNDYsMTEgKzM0LDEzIEBAIHN0cnVjdCB0eXBlY19wYXJ0bmVyIHsKIAl1bnNpZ25lZCBp bnQJCQl1c2JfcGQ6MTsKIAlzdHJ1Y3QgdXNiX3BkX2lkZW50aXR5CQkqaWRlbnRpdHk7CiAJZW51 bSB0eXBlY19hY2Nlc3NvcnkJCWFjY2Vzc29yeTsKKwlzdHJ1Y3QgaWRhCQkJbW9kZV9pZHM7CiB9 OwogCiBzdHJ1Y3QgdHlwZWNfcG9ydCB7CiAJdW5zaWduZWQgaW50CQkJaWQ7CiAJc3RydWN0IGRl dmljZQkJCWRldjsKKwlzdHJ1Y3QgaWRhCQkJbW9kZV9pZHM7CiAKIAlpbnQJCQkJcHJlZmVyX3Jv bGU7CiAJZW51bSB0eXBlY19kYXRhX3JvbGUJCWRhdGFfcm9sZTsKQEAgLTcxLDE3ICs2MSwxNCBA QCBzdHJ1Y3QgdHlwZWNfcG9ydCB7CiAjZGVmaW5lIHRvX3R5cGVjX3BsdWcoX2Rldl8pIGNvbnRh aW5lcl9vZihfZGV2Xywgc3RydWN0IHR5cGVjX3BsdWcsIGRldikKICNkZWZpbmUgdG9fdHlwZWNf Y2FibGUoX2Rldl8pIGNvbnRhaW5lcl9vZihfZGV2Xywgc3RydWN0IHR5cGVjX2NhYmxlLCBkZXYp CiAjZGVmaW5lIHRvX3R5cGVjX3BhcnRuZXIoX2Rldl8pIGNvbnRhaW5lcl9vZihfZGV2Xywgc3Ry dWN0IHR5cGVjX3BhcnRuZXIsIGRldikKLSNkZWZpbmUgdG9fYWx0bW9kZShfZGV2XykgY29udGFp bmVyX29mKF9kZXZfLCBzdHJ1Y3QgdHlwZWNfYWx0bW9kZSwgZGV2KQogCiBzdGF0aWMgY29uc3Qg c3RydWN0IGRldmljZV90eXBlIHR5cGVjX3BhcnRuZXJfZGV2X3R5cGU7CiBzdGF0aWMgY29uc3Qg c3RydWN0IGRldmljZV90eXBlIHR5cGVjX2NhYmxlX2Rldl90eXBlOwogc3RhdGljIGNvbnN0IHN0 cnVjdCBkZXZpY2VfdHlwZSB0eXBlY19wbHVnX2Rldl90eXBlOwotc3RhdGljIGNvbnN0IHN0cnVj dCBkZXZpY2VfdHlwZSB0eXBlY19wb3J0X2Rldl90eXBlOwogCiAjZGVmaW5lIGlzX3R5cGVjX3Bh cnRuZXIoX2Rldl8pIChfZGV2Xy0+dHlwZSA9PSAmdHlwZWNfcGFydG5lcl9kZXZfdHlwZSkKICNk ZWZpbmUgaXNfdHlwZWNfY2FibGUoX2Rldl8pIChfZGV2Xy0+dHlwZSA9PSAmdHlwZWNfY2FibGVf ZGV2X3R5cGUpCiAjZGVmaW5lIGlzX3R5cGVjX3BsdWcoX2Rldl8pIChfZGV2Xy0+dHlwZSA9PSAm dHlwZWNfcGx1Z19kZXZfdHlwZSkKLSNkZWZpbmUgaXNfdHlwZWNfcG9ydChfZGV2XykgKF9kZXZf LT50eXBlID09ICZ0eXBlY19wb3J0X2Rldl90eXBlKQogCiBzdGF0aWMgREVGSU5FX0lEQSh0eXBl Y19pbmRleF9pZGEpOwogc3RhdGljIHN0cnVjdCBjbGFzcyAqdHlwZWNfY2xhc3M7CkBAIC0xNjMs MjcgKzE1MCwxNDEgQEAgc3RhdGljIHZvaWQgdHlwZWNfcmVwb3J0X2lkZW50aXR5KHN0cnVjdCBk ZXZpY2UgKmRldikKIC8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KIC8qIEFsdGVybmF0ZSBNb2RlcyAq LwogCitzdGF0aWMgaW50IGFsdG1vZGVfbWF0Y2goc3RydWN0IGRldmljZSAqZGV2LCB2b2lkICpk YXRhKQoreworCXN0cnVjdCB0eXBlY19hbHRtb2RlICphZGV2ID0gdG9fdHlwZWNfYWx0bW9kZShk ZXYpOworCXN0cnVjdCB0eXBlY19kZXZpY2VfaWQgKmlkID0gZGF0YTsKKworCWlmICghaXNfdHlw ZWNfYWx0bW9kZShkZXYpKQorCQlyZXR1cm4gMDsKKworCXJldHVybiAoKGFkZXYtPnN2aWQgPT0g aWQtPnN2aWQpICYmIChhZGV2LT5tb2RlID09IGlkLT5tb2RlKSk7Cit9CisKK3N0YXRpYyB2b2lk IHR5cGVjX2FsdG1vZGVfZ2V0X3BhcnRuZXIoc3RydWN0IGFsdG1vZGUgKmFsdG1vZGUpCit7CisJ c3RydWN0IHR5cGVjX2FsdG1vZGUgKmFkZXYgPSAmYWx0bW9kZS0+YWRldjsKKwlzdHJ1Y3QgdHlw ZWNfZGV2aWNlX2lkIGlkID0geyBhZGV2LT5zdmlkLCBhZGV2LT5tb2RlLCB9OworCXN0cnVjdCB0 eXBlY19wb3J0ICpwb3J0ID0gdHlwZWNfYWx0bW9kZTJwb3J0KGFkZXYpOworCXN0cnVjdCBhbHRt b2RlICpwYXJ0bmVyOworCXN0cnVjdCBkZXZpY2UgKmRldjsKKworCWRldiA9IGRldmljZV9maW5k X2NoaWxkKCZwb3J0LT5kZXYsICZpZCwgYWx0bW9kZV9tYXRjaCk7CisJaWYgKCFkZXYpCisJCXJl dHVybjsKKworCS8qIEJpbmQgdGhlIHBvcnQgYWx0IG1vZGUgdG8gdGhlIHBhcnRuZXIvcGx1ZyBh bHQgbW9kZS4gKi8KKwlwYXJ0bmVyID0gdG9fYWx0bW9kZSh0b190eXBlY19hbHRtb2RlKGRldikp OworCWFsdG1vZGUtPnBhcnRuZXIgPSBwYXJ0bmVyOworCisJLyogQmluZCB0aGUgcGFydG5lci9w bHVnIGFsdCBtb2RlIHRvIHRoZSBwb3J0IGFsdCBtb2RlLiAqLworCWlmIChpc190eXBlY19wbHVn KGFkZXYtPmRldi5wYXJlbnQpKSB7CisJCXN0cnVjdCB0eXBlY19wbHVnICpwbHVnID0gdG9fdHlw ZWNfcGx1ZyhhZGV2LT5kZXYucGFyZW50KTsKKworCQlwYXJ0bmVyLT5wbHVnW3BsdWctPmluZGV4 XSA9IGFsdG1vZGU7CisJfSBlbHNlIHsKKwkJcGFydG5lci0+cGFydG5lciA9IGFsdG1vZGU7CisJ fQorfQorCitzdGF0aWMgdm9pZCB0eXBlY19hbHRtb2RlX3B1dF9wYXJ0bmVyKHN0cnVjdCBhbHRt b2RlICphbHRtb2RlKQoreworCXN0cnVjdCBhbHRtb2RlICpwYXJ0bmVyID0gYWx0bW9kZS0+cGFy dG5lcjsKKwlzdHJ1Y3QgdHlwZWNfYWx0bW9kZSAqYWRldjsKKworCWlmICghcGFydG5lcikKKwkJ cmV0dXJuOworCisJYWRldiA9ICZwYXJ0bmVyLT5hZGV2OworCisJaWYgKGlzX3R5cGVjX3BsdWco YWRldi0+ZGV2LnBhcmVudCkpIHsKKwkJc3RydWN0IHR5cGVjX3BsdWcgKnBsdWcgPSB0b190eXBl Y19wbHVnKGFkZXYtPmRldi5wYXJlbnQpOworCisJCXBhcnRuZXItPnBsdWdbcGx1Zy0+aW5kZXhd ID0gTlVMTDsKKwl9IGVsc2UgeworCQlwYXJ0bmVyLT5wYXJ0bmVyID0gTlVMTDsKKwl9CisJcHV0 X2RldmljZSgmYWRldi0+ZGV2KTsKK30KKworc3RhdGljIGludCBfX3R5cGVjX3BvcnRfbWF0Y2go c3RydWN0IGRldmljZSAqZGV2LCBjb25zdCB2b2lkICpuYW1lKQoreworCXJldHVybiAhc3RyY21w KChjb25zdCBjaGFyICopbmFtZSwgZGV2X25hbWUoZGV2KSk7Cit9CisKK3N0YXRpYyB2b2lkICp0 eXBlY19wb3J0X21hdGNoKHN0cnVjdCBkZXZjb24gKmNvbiwgaW50IGVwLCB2b2lkICpkYXRhKQor eworCXJldHVybiBjbGFzc19maW5kX2RldmljZSh0eXBlY19jbGFzcywgTlVMTCwgY29uLT5lbmRw b2ludFtlcF0sCisJCQkJIF9fdHlwZWNfcG9ydF9tYXRjaCk7Cit9CisKK3N0cnVjdCB0eXBlY19h bHRtb2RlICoKK3R5cGVjX2FsdG1vZGVfcmVnaXN0ZXJfbm90aWZpZXIoc3RydWN0IGRldmljZSAq ZGV2LCB1MTYgc3ZpZCwgdTggbW9kZSwKKwkJCQlzdHJ1Y3Qgbm90aWZpZXJfYmxvY2sgKm5iKQor eworCXN0cnVjdCB0eXBlY19kZXZpY2VfaWQgaWQgPSB7IHN2aWQsIG1vZGUsIH07CisJc3RydWN0 IGRldmljZSAqYWx0bW9kZV9kZXY7CisJc3RydWN0IGRldmljZSAqcG9ydF9kZXY7CisJc3RydWN0 IGFsdG1vZGUgKmFsdG1vZGU7CisJaW50IHJldDsKKworCS8qIEZpbmQgdGhlIHBvcnQgbGlua2Vk IHRvIHRoZSBjYWxsZXIgKi8KKwlwb3J0X2RldiA9IF9fZGV2aWNlX2ZpbmRfY29ubmVjdGlvbihk ZXYsIE5VTEwsIE5VTEwsIHR5cGVjX3BvcnRfbWF0Y2gpOworCWlmICghcG9ydF9kZXYpCisJCXJl dHVybiBFUlJfUFRSKC1FTk9ERVYpOworCisJLyogRmluZCB0aGUgYWx0bW9kZSB3aXRoIG1hdGNo aW5nIHN2aWQgKi8KKwlhbHRtb2RlX2RldiA9IGRldmljZV9maW5kX2NoaWxkKHBvcnRfZGV2LCAm aWQsIGFsdG1vZGVfbWF0Y2gpOworCisJcHV0X2RldmljZShwb3J0X2Rldik7CisKKwlpZiAoIWFs dG1vZGVfZGV2KQorCQlyZXR1cm4gRVJSX1BUUigtRU5PREVWKTsKKworCWFsdG1vZGUgPSB0b19h bHRtb2RlKHRvX3R5cGVjX2FsdG1vZGUoYWx0bW9kZV9kZXYpKTsKKworCS8qIFJlZ2lzdGVyIG5v dGlmaWVyICovCisJcmV0ID0gYmxvY2tpbmdfbm90aWZpZXJfY2hhaW5fcmVnaXN0ZXIoJmFsdG1v ZGUtPm5oLCBuYik7CisJaWYgKHJldCkgeworCQlwdXRfZGV2aWNlKGFsdG1vZGVfZGV2KTsKKwkJ cmV0dXJuIEVSUl9QVFIocmV0KTsKKwl9CisKKwlyZXR1cm4gJmFsdG1vZGUtPmFkZXY7Cit9CitF WFBPUlRfU1lNQk9MX0dQTCh0eXBlY19hbHRtb2RlX3JlZ2lzdGVyX25vdGlmaWVyKTsKKwordm9p ZCB0eXBlY19hbHRtb2RlX3VucmVnaXN0ZXJfbm90aWZpZXIoc3RydWN0IHR5cGVjX2FsdG1vZGUg KmFkZXYsCisJCQkJICAgICAgIHN0cnVjdCBub3RpZmllcl9ibG9jayAqbmIpCit7CisJc3RydWN0 IGFsdG1vZGUgKmFsdG1vZGUgPSB0b19hbHRtb2RlKGFkZXYpOworCisJYmxvY2tpbmdfbm90aWZp ZXJfY2hhaW5fdW5yZWdpc3RlcigmYWx0bW9kZS0+bmgsIG5iKTsKKwlwdXRfZGV2aWNlKCZhZGV2 LT5kZXYpOworfQorRVhQT1JUX1NZTUJPTF9HUEwodHlwZWNfYWx0bW9kZV91bnJlZ2lzdGVyX25v dGlmaWVyKTsKKwogLyoqCiAgKiB0eXBlY19hbHRtb2RlX3VwZGF0ZV9hY3RpdmUgLSBSZXBvcnQg RW50ZXIvRXhpdCBtb2RlCi0gKiBAYWx0OiBIYW5kbGUgdG8gdGhlIGFsdGVybmF0ZSBtb2RlCisg KiBAYWRldjogSGFuZGxlIHRvIHRoZSBhbHRlcm5hdGUgbW9kZQogICogQG1vZGU6IE1vZGUgaW5k ZXgKICAqIEBhY3RpdmU6IFRydWUgd2hlbiB0aGUgbW9kZSBoYXMgYmVlbiBlbnRlcmVkCiAgKgog ICogSWYgYSBwYXJ0bmVyIG9yIGNhYmxlIHBsdWcgZXhlY3V0ZXMgRW50ZXIvRXhpdCBNb2RlIGNv bW1hbmQgc3VjY2Vzc2Z1bGx5LCB0aGUKICAqIGRyaXZlcnMgdXNlIHRoaXMgcm91dGluZSB0byBy ZXBvcnQgdGhlIHVwZGF0ZWQgc3RhdGUgb2YgdGhlIG1vZGUuCiAgKi8KLXZvaWQgdHlwZWNfYWx0 bW9kZV91cGRhdGVfYWN0aXZlKHN0cnVjdCB0eXBlY19hbHRtb2RlICphbHQsIGludCBtb2RlLAor dm9pZCB0eXBlY19hbHRtb2RlX3VwZGF0ZV9hY3RpdmUoc3RydWN0IHR5cGVjX2FsdG1vZGUgKmFk ZXYsIGludCBtb2RlLAogCQkJCSBib29sIGFjdGl2ZSkKIHsKIAljaGFyIGRpcls2XTsKIAotCWlm IChhbHQtPmFjdGl2ZSA9PSBhY3RpdmUpCisJaWYgKGFkZXYtPmFjdGl2ZSA9PSBhY3RpdmUpCiAJ CXJldHVybjsKIAotCWFsdC0+YWN0aXZlID0gYWN0aXZlOworCWFkZXYtPmFjdGl2ZSA9IGFjdGl2 ZTsKIAlzbnByaW50ZihkaXIsIHNpemVvZihkaXIpLCAibW9kZSVkIiwgbW9kZSk7Ci0Jc3lzZnNf bm90aWZ5KCZhbHQtPmRldi5rb2JqLCBkaXIsICJhY3RpdmUiKTsKLQlrb2JqZWN0X3VldmVudCgm YWx0LT5kZXYua29iaiwgS09CSl9DSEFOR0UpOworCXN5c2ZzX25vdGlmeSgmYWRldi0+ZGV2Lmtv YmosIGRpciwgImFjdGl2ZSIpOworCWtvYmplY3RfdWV2ZW50KCZhZGV2LT5kZXYua29iaiwgS09C Sl9DSEFOR0UpOwogfQogRVhQT1JUX1NZTUJPTF9HUEwodHlwZWNfYWx0bW9kZV91cGRhdGVfYWN0 aXZlKTsKIApAQCAtMjEwLDcgKzMxMSw3IEBAIEVYUE9SVF9TWU1CT0xfR1BMKHR5cGVjX2FsdG1v ZGUycG9ydCk7CiBzdGF0aWMgc3NpemVfdAogdmRvX3Nob3coc3RydWN0IGRldmljZSAqZGV2LCBz dHJ1Y3QgZGV2aWNlX2F0dHJpYnV0ZSAqYXR0ciwgY2hhciAqYnVmKQogewotCXN0cnVjdCB0eXBl Y19hbHRtb2RlICphbHQgPSB0b19hbHRtb2RlKGRldik7CisJc3RydWN0IHR5cGVjX2FsdG1vZGUg KmFsdCA9IHRvX3R5cGVjX2FsdG1vZGUoZGV2KTsKIAogCXJldHVybiBzcHJpbnRmKGJ1ZiwgIjB4 JTA4eFxuIiwgYWx0LT52ZG8pOwogfQpAQCAtMjE5LDcgKzMyMCw3IEBAIHN0YXRpYyBERVZJQ0Vf QVRUUl9STyh2ZG8pOwogc3RhdGljIHNzaXplX3QKIGRlc2NyaXB0aW9uX3Nob3coc3RydWN0IGRl dmljZSAqZGV2LCBzdHJ1Y3QgZGV2aWNlX2F0dHJpYnV0ZSAqYXR0ciwgY2hhciAqYnVmKQogewot CXN0cnVjdCB0eXBlY19hbHRtb2RlICphbHQgPSB0b19hbHRtb2RlKGRldik7CisJc3RydWN0IHR5 cGVjX2FsdG1vZGUgKmFsdCA9IHRvX3R5cGVjX2FsdG1vZGUoZGV2KTsKIAogCXJldHVybiBzcHJp bnRmKGJ1ZiwgIiVzXG4iLCBhbHQtPmRlc2MgPyBhbHQtPmRlc2MgOiAiIik7CiB9CkBAIC0yMjgs MjggKzMyOSw0NiBAQCBzdGF0aWMgREVWSUNFX0FUVFJfUk8oZGVzY3JpcHRpb24pOwogc3RhdGlj IHNzaXplX3QKIGFjdGl2ZV9zaG93KHN0cnVjdCBkZXZpY2UgKmRldiwgc3RydWN0IGRldmljZV9h dHRyaWJ1dGUgKmF0dHIsIGNoYXIgKmJ1ZikKIHsKLQlzdHJ1Y3QgdHlwZWNfYWx0bW9kZSAqYWx0 ID0gdG9fYWx0bW9kZShkZXYpOworCXN0cnVjdCB0eXBlY19hbHRtb2RlICphbHQgPSB0b190eXBl Y19hbHRtb2RlKGRldik7CiAKIAlyZXR1cm4gc3ByaW50ZihidWYsICIlc1xuIiwgYWx0LT5hY3Rp dmUgPyAieWVzIiA6ICJubyIpOwogfQogCi1zdGF0aWMgc3NpemVfdAotYWN0aXZlX3N0b3JlKHN0 cnVjdCBkZXZpY2UgKmRldiwgc3RydWN0IGRldmljZV9hdHRyaWJ1dGUgKmF0dHIsCi0JCQkgICBj b25zdCBjaGFyICpidWYsIHNpemVfdCBzaXplKQorc3RhdGljIHNzaXplX3QgYWN0aXZlX3N0b3Jl KHN0cnVjdCBkZXZpY2UgKmRldiwgc3RydWN0IGRldmljZV9hdHRyaWJ1dGUgKmF0dHIsCisJCQkg ICAgY29uc3QgY2hhciAqYnVmLCBzaXplX3Qgc2l6ZSkKIHsKLQlzdHJ1Y3QgdHlwZWNfYWx0bW9k ZSAqYWx0ID0gdG9fYWx0bW9kZShkZXYpOwotCXN0cnVjdCB0eXBlY19wb3J0ICpwb3J0ID0gdHlw ZWNfYWx0bW9kZTJwb3J0KGFsdCk7Ci0JYm9vbCBhY3RpdmF0ZTsKKwlzdHJ1Y3QgdHlwZWNfYWx0 bW9kZSAqYWRldiA9IHRvX3R5cGVjX2FsdG1vZGUoZGV2KTsKKwlzdHJ1Y3QgdHlwZWNfcG9ydCAq cG9ydCA9IHR5cGVjX2FsdG1vZGUycG9ydChhZGV2KTsKKwlzdHJ1Y3QgYWx0bW9kZSAqYWx0bW9k ZSA9IHRvX2FsdG1vZGUoYWRldik7CisJYm9vbCBlbnRlcjsKIAlpbnQgcmV0OwogCiAJaWYgKCFw b3J0LT5jYXAtPmFjdGl2YXRlX21vZGUpCiAJCXJldHVybiAtRU9QTk9UU1VQUDsKIAotCXJldCA9 IGtzdHJ0b2Jvb2woYnVmLCAmYWN0aXZhdGUpOworCXJldCA9IGtzdHJ0b2Jvb2woYnVmLCAmZW50 ZXIpOwogCWlmIChyZXQpCiAJCXJldHVybiByZXQ7CiAKLQlyZXQgPSBwb3J0LT5jYXAtPmFjdGl2 YXRlX21vZGUocG9ydC0+Y2FwLCBhbHQtPm1vZGUsIGFjdGl2YXRlKTsKKwlpZiAoYWRldi0+YWN0 aXZlID09IGVudGVyKQorCQlyZXR1cm4gc2l6ZTsKKworCWlmIChpc190eXBlY19wb3J0KGFkZXYt PmRldi5wYXJlbnQpKSB7CisJCXR5cGVjX2FsdG1vZGVfdXBkYXRlX2FjdGl2ZShhZGV2LCBhZGV2 LT5tb2RlLCBlbnRlcik7CisJCXN5c2ZzX25vdGlmeSgmYWRldi0+ZGV2LmtvYmosIE5VTEwsICJh Y3RpdmUiKTsKKworCQlpZiAoIWFsdG1vZGUtPnBhcnRuZXIpCisJCQlyZXR1cm4gc2l6ZTsKKwl9 IGVsc2UgeworCQlhZGV2ID0gJmFsdG1vZGUtPnBhcnRuZXItPmFkZXY7CisKKwkJaWYgKCFhZGV2 LT5hY3RpdmUpIHsKKwkJCWRldl93YXJuKGRldiwgInBvcnQgaGFzIHRoZSBtb2RlIGRpc2FibGVk XG4iKTsKKwkJCXJldHVybiAtRVBFUk07CisJCX0KKwl9CisKKwlyZXQgPSBwb3J0LT5jYXAtPmFj dGl2YXRlX21vZGUoYWRldiwgZW50ZXIpOwogCWlmIChyZXQpCiAJCXJldHVybiByZXQ7CiAKQEAg LTI2MSw3ICszODAsNyBAQCBzdGF0aWMgc3NpemVfdAogc3VwcG9ydGVkX3JvbGVzX3Nob3coc3Ry dWN0IGRldmljZSAqZGV2LCBzdHJ1Y3QgZGV2aWNlX2F0dHJpYnV0ZSAqYXR0ciwKIAkJICAgICBj aGFyICpidWYpCiB7Ci0Jc3RydWN0IHR5cGVjX2FsdG1vZGUgKmFsdCA9IHRvX2FsdG1vZGUoZGV2 KTsKKwlzdHJ1Y3QgYWx0bW9kZSAqYWx0ID0gdG9fYWx0bW9kZSh0b190eXBlY19hbHRtb2RlKGRl dikpOwogCXNzaXplX3QgcmV0OwogCiAJc3dpdGNoIChhbHQtPnJvbGVzKSB7CkBAIC0yODAsMjkg KzM5OSw3MiBAQCBzdXBwb3J0ZWRfcm9sZXNfc2hvdyhzdHJ1Y3QgZGV2aWNlICpkZXYsIHN0cnVj dCBkZXZpY2VfYXR0cmlidXRlICphdHRyLAogfQogc3RhdGljIERFVklDRV9BVFRSX1JPKHN1cHBv cnRlZF9yb2xlcyk7CiAKLXN0YXRpYyB2b2lkIHR5cGVjX2FsdG1vZGVfcmVsZWFzZShzdHJ1Y3Qg ZGV2aWNlICpkZXYpCitzdGF0aWMgc3NpemVfdAorbW9kZV9zaG93KHN0cnVjdCBkZXZpY2UgKmRl diwgc3RydWN0IGRldmljZV9hdHRyaWJ1dGUgKmF0dHIsIGNoYXIgKmJ1ZikKIHsKLQlzdHJ1Y3Qg dHlwZWNfYWx0bW9kZSAqYWx0ID0gdG9fYWx0bW9kZShkZXYpOworCXN0cnVjdCB0eXBlY19hbHRt b2RlICphZGV2ID0gdG9fdHlwZWNfYWx0bW9kZShkZXYpOwogCi0Ja2ZyZWUoYWx0KTsKKwlyZXR1 cm4gc3ByaW50ZihidWYsICIldVxuIiwgYWRldi0+bW9kZSk7CiB9CitzdGF0aWMgREVWSUNFX0FU VFJfUk8obW9kZSk7CiAKLXN0YXRpYyBzc2l6ZV90IHN2aWRfc2hvdyhzdHJ1Y3QgZGV2aWNlICpk ZXYsIHN0cnVjdCBkZXZpY2VfYXR0cmlidXRlICphdHRyLAotCQkJIGNoYXIgKmJ1ZikKK3N0YXRp YyBzc2l6ZV90CitzdmlkX3Nob3coc3RydWN0IGRldmljZSAqZGV2LCBzdHJ1Y3QgZGV2aWNlX2F0 dHJpYnV0ZSAqYXR0ciwgY2hhciAqYnVmKQogewotCXN0cnVjdCB0eXBlY19hbHRtb2RlICphbHQg PSB0b19hbHRtb2RlKGRldik7CisJc3RydWN0IHR5cGVjX2FsdG1vZGUgKmFkZXYgPSB0b190eXBl Y19hbHRtb2RlKGRldik7CiAKLQlyZXR1cm4gc3ByaW50ZihidWYsICIlMDR4XG4iLCBhbHQtPnN2 aWQpOworCXJldHVybiBzcHJpbnRmKGJ1ZiwgIiUwNHhcbiIsIGFkZXYtPnN2aWQpOwogfQogc3Rh dGljIERFVklDRV9BVFRSX1JPKHN2aWQpOwogCiBzdGF0aWMgc3RydWN0IGF0dHJpYnV0ZSAqdHlw ZWNfYWx0bW9kZV9hdHRyc1tdID0geworCSZkZXZfYXR0cl9hY3RpdmUuYXR0ciwKKwkmZGV2X2F0 dHJfbW9kZS5hdHRyLAogCSZkZXZfYXR0cl9zdmlkLmF0dHIsCisJJmRldl9hdHRyX3Zkby5hdHRy LAogCU5VTEwKIH07CiBBVFRSSUJVVEVfR1JPVVBTKHR5cGVjX2FsdG1vZGUpOwogCi1zdGF0aWMg Y29uc3Qgc3RydWN0IGRldmljZV90eXBlIHR5cGVjX2FsdG1vZGVfZGV2X3R5cGUgPSB7CitzdGF0 aWMgaW50IGFsdG1vZGVfaWRfZ2V0KHN0cnVjdCBkZXZpY2UgKmRldikKK3sKKwlzdHJ1Y3QgaWRh ICppZHM7CisKKwlpZiAoaXNfdHlwZWNfcGFydG5lcihkZXYpKQorCQlpZHMgPSAmdG9fdHlwZWNf cGFydG5lcihkZXYpLT5tb2RlX2lkczsKKwllbHNlIGlmIChpc190eXBlY19wbHVnKGRldikpCisJ CWlkcyA9ICZ0b190eXBlY19wbHVnKGRldiktPm1vZGVfaWRzOworCWVsc2UKKwkJaWRzID0gJnRv X3R5cGVjX3BvcnQoZGV2KS0+bW9kZV9pZHM7CisKKwlyZXR1cm4gaWRhX3NpbXBsZV9nZXQoaWRz LCAwLCAwLCBHRlBfS0VSTkVMKTsKK30KKworc3RhdGljIHZvaWQgYWx0bW9kZV9pZF9yZW1vdmUo c3RydWN0IGRldmljZSAqZGV2LCBpbnQgaWQpCit7CisJc3RydWN0IGlkYSAqaWRzOworCisJaWYg KGlzX3R5cGVjX3BhcnRuZXIoZGV2KSkKKwkJaWRzID0gJnRvX3R5cGVjX3BhcnRuZXIoZGV2KS0+ bW9kZV9pZHM7CisJZWxzZSBpZiAoaXNfdHlwZWNfcGx1ZyhkZXYpKQorCQlpZHMgPSAmdG9fdHlw ZWNfcGx1ZyhkZXYpLT5tb2RlX2lkczsKKwllbHNlCisJCWlkcyA9ICZ0b190eXBlY19wb3J0KGRl diktPm1vZGVfaWRzOworCisJaWRhX3NpbXBsZV9yZW1vdmUoaWRzLCBpZCk7Cit9CisKK3N0YXRp YyB2b2lkIHR5cGVjX2FsdG1vZGVfcmVsZWFzZShzdHJ1Y3QgZGV2aWNlICpkZXYpCit7CisJc3Ry dWN0IGFsdG1vZGUgKmFsdCA9IHRvX2FsdG1vZGUodG9fdHlwZWNfYWx0bW9kZShkZXYpKTsKKwor CXR5cGVjX2FsdG1vZGVfcHV0X3BhcnRuZXIoYWx0KTsKKworCWFsdG1vZGVfaWRfcmVtb3ZlKGFs dC0+YWRldi5kZXYucGFyZW50LCBhbHQtPmlkKTsKKwlrZnJlZShhbHQpOworfQorCitjb25zdCBz dHJ1Y3QgZGV2aWNlX3R5cGUgdHlwZWNfYWx0bW9kZV9kZXZfdHlwZSA9IHsKIAkubmFtZSA9ICJ0 eXBlY19hbHRlcm5hdGVfbW9kZSIsCiAJLmdyb3VwcyA9IHR5cGVjX2FsdG1vZGVfZ3JvdXBzLAog CS5yZWxlYXNlID0gdHlwZWNfYWx0bW9kZV9yZWxlYXNlLApAQCAtMzEyLDU4ICs0NzQsNzIgQEAg c3RhdGljIHN0cnVjdCB0eXBlY19hbHRtb2RlICoKIHR5cGVjX3JlZ2lzdGVyX2FsdG1vZGUoc3Ry dWN0IGRldmljZSAqcGFyZW50LAogCQkgICAgICAgY29uc3Qgc3RydWN0IHR5cGVjX2FsdG1vZGVf ZGVzYyAqZGVzYykKIHsKLQlzdHJ1Y3QgdHlwZWNfYWx0bW9kZSAqYWx0OworCXVuc2lnbmVkIGlu dCBpZCA9IGFsdG1vZGVfaWRfZ2V0KHBhcmVudCk7CisJYm9vbCBpc19wb3J0ID0gaXNfdHlwZWNf cG9ydChwYXJlbnQpOworCXN0cnVjdCBhbHRtb2RlICphbHQ7CiAJaW50IHJldDsKIAogCWFsdCA9 IGt6YWxsb2Moc2l6ZW9mKCphbHQpLCBHRlBfS0VSTkVMKTsKIAlpZiAoIWFsdCkKIAkJcmV0dXJu IEVSUl9QVFIoLUVOT01FTSk7CiAKLQlhbHQtPnN2aWQgPSBkZXNjLT5zdmlkOwotCWFsdC0+bW9k ZSA9IGRlc2MtPm1vZGU7Ci0JYWx0LT52ZG8gPSBkZXNjLT52ZG87CisJYWx0LT5hZGV2LnN2aWQg PSBkZXNjLT5zdmlkOworCWFsdC0+YWRldi5tb2RlID0gZGVzYy0+bW9kZTsKKwlhbHQtPmFkZXYu dmRvID0gZGVzYy0+dmRvOwogCWFsdC0+cm9sZXMgPSBkZXNjLT5yb2xlczsKKwlhbHQtPmlkID0g aWQ7CiAKIAlhbHQtPmF0dHJzWzBdID0gJmRldl9hdHRyX3Zkby5hdHRyOwogCWFsdC0+YXR0cnNb MV0gPSAmZGV2X2F0dHJfZGVzY3JpcHRpb24uYXR0cjsKIAlhbHQtPmF0dHJzWzJdID0gJmRldl9h dHRyX2FjdGl2ZS5hdHRyOwogCi0JaWYgKGlzX3R5cGVjX3BvcnQocGFyZW50KSkKKwlpZiAoaXNf cG9ydCkgewogCQlhbHQtPmF0dHJzWzNdID0gJmRldl9hdHRyX3N1cHBvcnRlZF9yb2xlcy5hdHRy OworCQlhbHQtPmFkZXYuYWN0aXZlID0gdHJ1ZTsgLyogRW5hYmxlZCBieSBkZWZhdWx0ICovCisJ fQogCiAJc3ByaW50ZihhbHQtPmdyb3VwX25hbWUsICJtb2RlJWQiLCBkZXNjLT5tb2RlKTsKIAlh bHQtPmdyb3VwLm5hbWUgPSBhbHQtPmdyb3VwX25hbWU7CiAJYWx0LT5ncm91cC5hdHRycyA9IGFs dC0+YXR0cnM7CiAJYWx0LT5ncm91cHNbMF0gPSAmYWx0LT5ncm91cDsKIAotCWFsdC0+ZGV2LnBh cmVudCA9IHBhcmVudDsKLQlhbHQtPmRldi5ncm91cHMgPSBhbHQtPmdyb3VwczsKLQlhbHQtPmRl di50eXBlID0gJnR5cGVjX2FsdG1vZGVfZGV2X3R5cGU7Ci0JZGV2X3NldF9uYW1lKCZhbHQtPmRl diwgIiVzLSUwNHg6JXUiLCBkZXZfbmFtZShwYXJlbnQpLAotCQkgICAgIGFsdC0+c3ZpZCwgYWx0 LT5tb2RlKTsKKwlhbHQtPmFkZXYuZGV2LnBhcmVudCA9IHBhcmVudDsKKwlhbHQtPmFkZXYuZGV2 Lmdyb3VwcyA9IGFsdC0+Z3JvdXBzOworCWFsdC0+YWRldi5kZXYudHlwZSA9ICZ0eXBlY19hbHRt b2RlX2Rldl90eXBlOworCWRldl9zZXRfbmFtZSgmYWx0LT5hZGV2LmRldiwgIiVzLiV1IiwgZGV2 X25hbWUocGFyZW50KSwgaWQpOworCisJLyogTGluayBwYXJ0bmVycyBhbmQgcGx1Z3Mgd2l0aCB0 aGUgcG9ydHMgKi8KKwlpZiAoaXNfcG9ydCkKKwkJQkxPQ0tJTkdfSU5JVF9OT1RJRklFUl9IRUFE KCZhbHQtPm5oKTsKKwllbHNlCisJCXR5cGVjX2FsdG1vZGVfZ2V0X3BhcnRuZXIoYWx0KTsKIAot CXJldCA9IGRldmljZV9yZWdpc3RlcigmYWx0LT5kZXYpOworCS8qIFRoZSBwYXJ0bmVycyBhcmUg YmluZCB0byBkcml2ZXJzICovCisJaWYgKGlzX3R5cGVjX3BhcnRuZXIocGFyZW50KSkKKwkJYWx0 LT5hZGV2LmRldi5idXMgPSAmdHlwZWNfYnVzOworCisJcmV0ID0gZGV2aWNlX3JlZ2lzdGVyKCZh bHQtPmFkZXYuZGV2KTsKIAlpZiAocmV0KSB7CiAJCWRldl9lcnIocGFyZW50LCAiZmFpbGVkIHRv IHJlZ2lzdGVyIGFsdGVybmF0ZSBtb2RlICglZClcbiIsCiAJCQlyZXQpOwotCQlwdXRfZGV2aWNl KCZhbHQtPmRldik7CisJCXB1dF9kZXZpY2UoJmFsdC0+YWRldi5kZXYpOwogCQlyZXR1cm4gRVJS X1BUUihyZXQpOwogCX0KIAotCXJldHVybiBhbHQ7CisJcmV0dXJuICZhbHQtPmFkZXY7CiB9CiAK IC8qKgogICogdHlwZWNfdW5yZWdpc3Rlcl9hbHRtb2RlIC0gVW5yZWdpc3RlciBBbHRlcm5hdGUg TW9kZQotICogQGFsdDogVGhlIGFsdGVybmF0ZSBtb2RlIHRvIGJlIHVucmVnaXN0ZXJlZAorICog QGFkZXY6IFRoZSBhbHRlcm5hdGUgbW9kZSB0byBiZSB1bnJlZ2lzdGVyZWQKICAqCiAgKiBVbnJl Z2lzdGVyIGRldmljZSBjcmVhdGVkIHdpdGggdHlwZWNfcGFydG5lcl9yZWdpc3Rlcl9hbHRtb2Rl KCksCiAgKiB0eXBlY19wbHVnX3JlZ2lzdGVyX2FsdG1vZGUoKSBvciB0eXBlY19wb3J0X3JlZ2lz dGVyX2FsdG1vZGUoKS4KICAqLwotdm9pZCB0eXBlY191bnJlZ2lzdGVyX2FsdG1vZGUoc3RydWN0 IHR5cGVjX2FsdG1vZGUgKmFsdCkKK3ZvaWQgdHlwZWNfdW5yZWdpc3Rlcl9hbHRtb2RlKHN0cnVj dCB0eXBlY19hbHRtb2RlICphZGV2KQogewotCWlmICghSVNfRVJSX09SX05VTEwoYWx0KSkKLQkJ ZGV2aWNlX3VucmVnaXN0ZXIoJmFsdC0+ZGV2KTsKKwlpZiAoIUlTX0VSUl9PUl9OVUxMKGFkZXYp KQorCQlkZXZpY2VfdW5yZWdpc3RlcigmYWRldi0+ZGV2KTsKIH0KIEVYUE9SVF9TWU1CT0xfR1BM KHR5cGVjX3VucmVnaXN0ZXJfYWx0bW9kZSk7CiAKQEAgLTQwMSw2ICs1NzcsNyBAQCBzdGF0aWMg dm9pZCB0eXBlY19wYXJ0bmVyX3JlbGVhc2Uoc3RydWN0IGRldmljZSAqZGV2KQogewogCXN0cnVj dCB0eXBlY19wYXJ0bmVyICpwYXJ0bmVyID0gdG9fdHlwZWNfcGFydG5lcihkZXYpOwogCisJaWRh X2Rlc3Ryb3koJnBhcnRuZXItPm1vZGVfaWRzKTsKIAlrZnJlZShwYXJ0bmVyKTsKIH0KIApAQCAt NDY2LDYgKzY0Myw3IEBAIHN0cnVjdCB0eXBlY19wYXJ0bmVyICp0eXBlY19yZWdpc3Rlcl9wYXJ0 bmVyKHN0cnVjdCB0eXBlY19wb3J0ICpwb3J0LAogCWlmICghcGFydG5lcikKIAkJcmV0dXJuIEVS Ul9QVFIoLUVOT01FTSk7CiAKKwlpZGFfaW5pdCgmcGFydG5lci0+bW9kZV9pZHMpOwogCXBhcnRu ZXItPnVzYl9wZCA9IGRlc2MtPnVzYl9wZDsKIAlwYXJ0bmVyLT5hY2Nlc3NvcnkgPSBkZXNjLT5h Y2Nlc3Nvcnk7CiAKQEAgLTUxNCw2ICs2OTIsNyBAQCBzdGF0aWMgdm9pZCB0eXBlY19wbHVnX3Jl bGVhc2Uoc3RydWN0IGRldmljZSAqZGV2KQogewogCXN0cnVjdCB0eXBlY19wbHVnICpwbHVnID0g dG9fdHlwZWNfcGx1ZyhkZXYpOwogCisJaWRhX2Rlc3Ryb3koJnBsdWctPm1vZGVfaWRzKTsKIAlr ZnJlZShwbHVnKTsKIH0KIApAQCAtNTY2LDYgKzc0NSw3IEBAIHN0cnVjdCB0eXBlY19wbHVnICp0 eXBlY19yZWdpc3Rlcl9wbHVnKHN0cnVjdCB0eXBlY19jYWJsZSAqY2FibGUsCiAKIAlzcHJpbnRm KG5hbWUsICJwbHVnJWQiLCBkZXNjLT5pbmRleCk7CiAKKwlpZGFfaW5pdCgmcGx1Zy0+bW9kZV9p ZHMpOwogCXBsdWctPmluZGV4ID0gZGVzYy0+aW5kZXg7CiAJcGx1Zy0+ZGV2LmNsYXNzID0gdHlw ZWNfY2xhc3M7CiAJcGx1Zy0+ZGV2LnBhcmVudCA9ICZjYWJsZS0+ZGV2OwpAQCAtMTA4MCwxMiAr MTI2MCwxMyBAQCBzdGF0aWMgdm9pZCB0eXBlY19yZWxlYXNlKHN0cnVjdCBkZXZpY2UgKmRldikK IAlzdHJ1Y3QgdHlwZWNfcG9ydCAqcG9ydCA9IHRvX3R5cGVjX3BvcnQoZGV2KTsKIAogCWlkYV9z aW1wbGVfcmVtb3ZlKCZ0eXBlY19pbmRleF9pZGEsIHBvcnQtPmlkKTsKKwlpZGFfZGVzdHJveSgm cG9ydC0+bW9kZV9pZHMpOwogCXR5cGVjX3N3aXRjaF9wdXQocG9ydC0+c3cpOwogCXR5cGVjX211 eF9wdXQocG9ydC0+bXV4KTsKIAlrZnJlZShwb3J0KTsKIH0KIAotc3RhdGljIGNvbnN0IHN0cnVj dCBkZXZpY2VfdHlwZSB0eXBlY19wb3J0X2Rldl90eXBlID0geworY29uc3Qgc3RydWN0IGRldmlj ZV90eXBlIHR5cGVjX3BvcnRfZGV2X3R5cGUgPSB7CiAJLm5hbWUgPSAidHlwZWNfcG9ydCIsCiAJ Lmdyb3VwcyA9IHR5cGVjX2dyb3VwcywKIAkudWV2ZW50ID0gdHlwZWNfdWV2ZW50LApAQCAtMTIz OCw2ICsxNDE5LDggQEAgRVhQT1JUX1NZTUJPTF9HUEwodHlwZWNfc2V0X21vZGUpOwogICogdHlw ZWNfcG9ydF9yZWdpc3Rlcl9hbHRtb2RlIC0gUmVnaXN0ZXIgVVNCIFR5cGUtQyBQb3J0IEFsdGVy bmF0ZSBNb2RlCiAgKiBAcG9ydDogVVNCIFR5cGUtQyBQb3J0IHRoYXQgc3VwcG9ydHMgdGhlIGFs dGVybmF0ZSBtb2RlCiAgKiBAZGVzYzogRGVzY3JpcHRpb24gb2YgdGhlIGFsdGVybmF0ZSBtb2Rl CisgKiBAb3BzOiBQb3J0IHNwZWNpZmljIG9wZXJhdGlvbnMgZm9yIHRoZSBhbHRlcm5hdGUgbW9k ZQorICogQGRydmRhdGE6IFByaXZhdGUgcG9pbnRlciB0byBkcml2ZXIgc3BlY2lmaWMgaW5mbwog ICoKICAqIFRoaXMgcm91dGluZSBpcyB1c2VkIHRvIHJlZ2lzdGVyIGFuIGFsdGVybmF0ZSBtb2Rl IHRoYXQgQHBvcnQgaXMgY2FwYWJsZSBvZgogICogc3VwcG9ydGluZy4KQEAgLTEzMjIsMTAgKzE1 MDUsMTIgQEAgc3RydWN0IHR5cGVjX3BvcnQgKnR5cGVjX3JlZ2lzdGVyX3BvcnQoc3RydWN0IGRl dmljZSAqcGFyZW50LAogCQlicmVhazsKIAl9CiAKKwlpZGFfaW5pdCgmcG9ydC0+bW9kZV9pZHMp OworCW11dGV4X2luaXQoJnBvcnQtPnBvcnRfdHlwZV9sb2NrKTsKKwogCXBvcnQtPmlkID0gaWQ7 CiAJcG9ydC0+Y2FwID0gY2FwOwogCXBvcnQtPnBvcnRfdHlwZSA9IGNhcC0+dHlwZTsKLQltdXRl eF9pbml0KCZwb3J0LT5wb3J0X3R5cGVfbG9jayk7CiAJcG9ydC0+cHJlZmVyX3JvbGUgPSBjYXAt PnByZWZlcl9yb2xlOwogCiAJcG9ydC0+ZGV2LmNsYXNzID0gdHlwZWNfY2xhc3M7CkBAIC0xMzY5 LDggKzE1NTQsMTkgQEAgRVhQT1JUX1NZTUJPTF9HUEwodHlwZWNfdW5yZWdpc3Rlcl9wb3J0KTsK IAogc3RhdGljIGludCBfX2luaXQgdHlwZWNfaW5pdCh2b2lkKQogeworCWludCByZXQ7CisKKwly ZXQgPSBidXNfcmVnaXN0ZXIoJnR5cGVjX2J1cyk7CisJaWYgKHJldCkKKwkJcmV0dXJuIHJldDsK KwogCXR5cGVjX2NsYXNzID0gY2xhc3NfY3JlYXRlKFRISVNfTU9EVUxFLCAidHlwZWMiKTsKLQly ZXR1cm4gUFRSX0VSUl9PUl9aRVJPKHR5cGVjX2NsYXNzKTsKKwlpZiAoSVNfRVJSKHR5cGVjX2Ns YXNzKSkgeworCQlidXNfdW5yZWdpc3RlcigmdHlwZWNfYnVzKTsKKwkJcmV0dXJuIFBUUl9FUlIo dHlwZWNfY2xhc3MpOworCX0KKworCXJldHVybiAwOwogfQogc3Vic3lzX2luaXRjYWxsKHR5cGVj X2luaXQpOwogCkBAIC0xMzc4LDYgKzE1NzQsNyBAQCBzdGF0aWMgdm9pZCBfX2V4aXQgdHlwZWNf ZXhpdCh2b2lkKQogewogCWNsYXNzX2Rlc3Ryb3kodHlwZWNfY2xhc3MpOwogCWlkYV9kZXN0cm95 KCZ0eXBlY19pbmRleF9pZGEpOworCWJ1c191bnJlZ2lzdGVyKCZ0eXBlY19idXMpOwogfQogbW9k dWxlX2V4aXQodHlwZWNfZXhpdCk7CiAKZGlmZiAtLWdpdCBhL2luY2x1ZGUvbGludXgvbW9kX2Rl dmljZXRhYmxlLmggYi9pbmNsdWRlL2xpbnV4L21vZF9kZXZpY2V0YWJsZS5oCmluZGV4IDQ4ZmIy YjQzYzM1YS4uMTdjMWE5MTJmNTI0IDEwMDY0NAotLS0gYS9pbmNsdWRlL2xpbnV4L21vZF9kZXZp Y2V0YWJsZS5oCisrKyBiL2luY2x1ZGUvbGludXgvbW9kX2RldmljZXRhYmxlLmgKQEAgLTczMyw0 ICs3MzMsMTkgQEAgc3RydWN0IHRiX3NlcnZpY2VfaWQgewogI2RlZmluZSBUQlNWQ19NQVRDSF9Q Uk9UT0NPTF9WRVJTSU9OCTB4MDAwNAogI2RlZmluZSBUQlNWQ19NQVRDSF9QUk9UT0NPTF9SRVZJ U0lPTgkweDAwMDgKIAorLyogVVNCIFR5cGUtQyBBbHRlcm5hdGUgTW9kZXMgKi8KKworI2RlZmlu ZSBUWVBFQ19BTllfTU9ERQkweDcKKworLyoqCisgKiBzdHJ1Y3QgdHlwZWNfZGV2aWNlX2lkIC0g VVNCIFR5cGUtQyBhbHRlcm5hdGUgbW9kZSBpZGVudGlmaWVycworICogQHN2aWQ6IFN0YW5kYXJk IG9yIFZlbmRvciBJRAorICogQG1vZGU6IE1vZGUgaW5kZXgKKyAqLworc3RydWN0IHR5cGVjX2Rl dmljZV9pZCB7CisJX191MTYgc3ZpZDsKKwlfX3U4IG1vZGU7CisJa2VybmVsX3Vsb25nX3QgZHJp dmVyX2RhdGE7Cit9OworCiAjZW5kaWYgLyogTElOVVhfTU9EX0RFVklDRVRBQkxFX0ggKi8KZGlm ZiAtLWdpdCBhL2luY2x1ZGUvbGludXgvdXNiL3R5cGVjLmggYi9pbmNsdWRlL2xpbnV4L3VzYi90 eXBlYy5oCmluZGV4IDI3OGI2YjQyYzdlYS4uYTE5YWEzZGI0MjcyIDEwMDY0NAotLS0gYS9pbmNs dWRlL2xpbnV4L3VzYi90eXBlYy5oCisrKyBiL2luY2x1ZGUvbGludXgvdXNiL3R5cGVjLmgKQEAg LTQsMTYgKzQsMTMgQEAKICNkZWZpbmUgX19MSU5VWF9VU0JfVFlQRUNfSAogCiAjaW5jbHVkZSA8 bGludXgvdHlwZXMuaD4KLQotLyogWFhYOiBPbmNlIHdlIGhhdmUgYSBoZWFkZXIgZm9yIFVTQiBQ b3dlciBEZWxpdmVyeSwgdGhpcyBiZWxvbmdzIHRoZXJlICovCi0jZGVmaW5lIEFMVE1PREVfTUFY X01PREVTCTYKKyNpbmNsdWRlIDxsaW51eC91c2IvdHlwZWNfYWx0bW9kZS5oPgogCiAvKiBVU0Ig VHlwZS1DIFNwZWNpZmljYXRpb24gcmVsZWFzZXMgKi8KICNkZWZpbmUgVVNCX1RZUEVDX1JFVl8x XzAJMHgxMDAgLyogMS4wICovCiAjZGVmaW5lIFVTQl9UWVBFQ19SRVZfMV8xCTB4MTEwIC8qIDEu MSAqLwogI2RlZmluZSBVU0JfVFlQRUNfUkVWXzFfMgkweDEyMCAvKiAxLjIgKi8KIAotc3RydWN0 IHR5cGVjX2FsdG1vZGU7CiBzdHJ1Y3QgdHlwZWNfcGFydG5lcjsKIHN0cnVjdCB0eXBlY19jYWJs ZTsKIHN0cnVjdCB0eXBlY19wbHVnOwpAQCAtMTA3LDcgKzEwNCw3IEBAIHN0cnVjdCB0eXBlY19h bHRtb2RlX2Rlc2MgewogCXU4CQkJbW9kZTsKIAl1MzIJCQl2ZG87CiAJLyogT25seSB1c2VkIHdp dGggcG9ydHMgKi8KLQllbnVtIHR5cGVjX3BvcnRfdHlwZQlyb2xlczsKKwllbnVtIHR5cGVjX3Bv cnRfZGF0YQlyb2xlczsKIH07CiAKIHN0cnVjdCB0eXBlY19hbHRtb2RlCkBAIC0xMTgsNyArMTE1 LDggQEAgc3RydWN0IHR5cGVjX2FsdG1vZGUKIAkJCSAgICAgY29uc3Qgc3RydWN0IHR5cGVjX2Fs dG1vZGVfZGVzYyAqZGVzYyk7CiBzdHJ1Y3QgdHlwZWNfYWx0bW9kZQogKnR5cGVjX3BvcnRfcmVn aXN0ZXJfYWx0bW9kZShzdHJ1Y3QgdHlwZWNfcG9ydCAqcG9ydCwKLQkJCSAgICAgY29uc3Qgc3Ry dWN0IHR5cGVjX2FsdG1vZGVfZGVzYyAqZGVzYyk7CisJCQkgICAgY29uc3Qgc3RydWN0IHR5cGVj X2FsdG1vZGVfZGVzYyAqZGVzYyk7CisKIHZvaWQgdHlwZWNfdW5yZWdpc3Rlcl9hbHRtb2RlKHN0 cnVjdCB0eXBlY19hbHRtb2RlICphbHRtb2RlKTsKIAogc3RydWN0IHR5cGVjX3BvcnQgKnR5cGVj X2FsdG1vZGUycG9ydChzdHJ1Y3QgdHlwZWNfYWx0bW9kZSAqYWx0KTsKQEAgLTIxMywxMiArMjEx LDEwIEBAIHN0cnVjdCB0eXBlY19jYXBhYmlsaXR5IHsKIAkJCQkgIGVudW0gdHlwZWNfcm9sZSk7 CiAJaW50CQkoKnZjb25uX3NldCkoY29uc3Qgc3RydWN0IHR5cGVjX2NhcGFiaWxpdHkgKiwKIAkJ CQkgICAgIGVudW0gdHlwZWNfcm9sZSk7Ci0KLQlpbnQJCSgqYWN0aXZhdGVfbW9kZSkoY29uc3Qg c3RydWN0IHR5cGVjX2NhcGFiaWxpdHkgKiwKLQkJCQkJIGludCBtb2RlLCBpbnQgYWN0aXZhdGUp OwogCWludAkJKCpwb3J0X3R5cGVfc2V0KShjb25zdCBzdHJ1Y3QgdHlwZWNfY2FwYWJpbGl0eSAq LAotCQkJCQllbnVtIHR5cGVjX3BvcnRfdHlwZSk7CisJCQkJCSBlbnVtIHR5cGVjX3BvcnRfdHlw ZSk7CiAKKwlpbnQJCSgqYWN0aXZhdGVfbW9kZSkoc3RydWN0IHR5cGVjX2FsdG1vZGUgKmFsdCwg aW50IGFjdGl2ZSk7CiB9OwogCiAvKiBTcGVjaWZpYyB0byB0cnlfcm9sZSgpLiBJbmRpY2F0ZXMg dGhlIHVzZXIgd2FudCdzIHRvIGNsZWFyIHRoZSBwcmVmZXJlbmNlLiAqLwpkaWZmIC0tZ2l0IGEv aW5jbHVkZS9saW51eC91c2IvdHlwZWNfYWx0bW9kZS5oIGIvaW5jbHVkZS9saW51eC91c2IvdHlw ZWNfYWx0bW9kZS5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAwMDAwMC4uYmM3 NjUzNTJhM2M4Ci0tLSAvZGV2L251bGwKKysrIGIvaW5jbHVkZS9saW51eC91c2IvdHlwZWNfYWx0 bW9kZS5oCkBAIC0wLDAgKzEsMTM2IEBACisvKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogR1BM LTIuMCAqLworCisjaWZuZGVmIF9fVVNCX1RZUEVDX0FMVE1PREVfSAorI2RlZmluZSBfX1VTQl9U WVBFQ19BTFRNT0RFX0gKKworI2luY2x1ZGUgPGxpbnV4L2RldmljZS5oPgorI2luY2x1ZGUgPGxp bnV4L21vZF9kZXZpY2V0YWJsZS5oPgorCisjZGVmaW5lIE1PREVfRElTQ09WRVJZX01BWAk2CisK Ky8qKgorICogc3RydWN0IHR5cGVjX2FsdG1vZGUgLSBVU0IgVHlwZS1DIGFsdGVybmF0ZSBtb2Rl IGRldmljZQorICogQGRldjogRHJpdmVyIG1vZGVsJ3MgdmlldyBvZiB0aGlzIGRldmljZQorICog QHN2aWQ6IFN0YW5kYXJkIG9yIFZlbmRvciBJRCAoU1ZJRCkgb2YgdGhlIGFsdGVybmF0ZSBtb2Rl CisgKiBAbW9kZTogSW5kZXggb2YgdGhlIE1vZGUKKyAqIEB2ZG86IFZETyByZXR1cm5lZCBieSBE aXNjb3ZlciBNb2RlcyBVU0IgUEQgY29tbWFuZAorICogQGRlc2M6IE9wdGlvbmFsIGh1bWFuIHJl YWRhYmxlIGRlc2NyaXB0aW9uIG9mIHRoZSBtb2RlCisgKiBAYWN0aXZlOiBUZWxscyBoYXMgdGhl IG1vZGUgYmVlbiBlbnRlcmVkIG9yIG5vdAorICovCitzdHJ1Y3QgdHlwZWNfYWx0bW9kZSB7CisJ c3RydWN0IGRldmljZQkJZGV2OworCXUxNgkJCXN2aWQ7CisJaW50CQkJbW9kZTsKKwl1MzIJCQl2 ZG87CisJY2hhcgkJCSpkZXNjOworCWJvb2wJCQlhY3RpdmU7Cit9IF9fcGFja2VkOworCisjZGVm aW5lIHRvX3R5cGVjX2FsdG1vZGUoZCkgY29udGFpbmVyX29mKGQsIHN0cnVjdCB0eXBlY19hbHRt b2RlLCBkZXYpCisKK3N0YXRpYyBpbmxpbmUgdm9pZCB0eXBlY19hbHRtb2RlX3NldF9kcnZkYXRh KHN0cnVjdCB0eXBlY19hbHRtb2RlICphbHRtb2RlLAorCQkJCQkgICAgIHZvaWQgKmRhdGEpCit7 CisJZGV2X3NldF9kcnZkYXRhKCZhbHRtb2RlLT5kZXYsIGRhdGEpOworfQorCitzdGF0aWMgaW5s aW5lIHZvaWQgKnR5cGVjX2FsdG1vZGVfZ2V0X2RydmRhdGEoc3RydWN0IHR5cGVjX2FsdG1vZGUg KmFsdG1vZGUpCit7CisJcmV0dXJuIGRldl9nZXRfZHJ2ZGF0YSgmYWx0bW9kZS0+ZGV2KTsKK30K KworLyoqCisgKiBzdHJ1Y3QgdHlwZWNfYWx0bW9kZV9vcHMgLSBBbHRlcm5hdGUgbW9kZSBzcGVj aWZpYyBvcGVyYXRpb25zIHZlY3RvcgorICogQGVudGVyOiBPcGVyYXRpb25zIHRvIGJlIGV4ZWN1 dGVkIHdpdGggRW50ZXIgTW9kZSBDb21tYW5kCisgKiBAZXhpdDogT3BlcmF0aW9ucyB0byBiZSBl eGVjdXRlZCB3aXRoIEV4aXQgTW9kZSBDb21tYW5kCisgKiBAYXR0ZW50aW9uOiBDYWxsYmFjayBm b3IgQXR0ZW50aW9uIENvbW1hbmQKKyAqIEB2ZG06IENhbGxiYWNrIGZvciBTVklEIHNwZWNpZmlj IGNvbW1hbmRzCisgKiBAbm90aWZ5OiBDb21tdW5pY2F0aW9uIGNoYW5uZWwgZm9yIHBsYXRmb3Jt IGFuZCB0aGUgYWx0ZXJuYXRlIG1vZGUKKyAqLworc3RydWN0IHR5cGVjX2FsdG1vZGVfb3BzIHsK Kwl2b2lkICgqZW50ZXIpKHN0cnVjdCB0eXBlY19hbHRtb2RlICphbHRtb2RlKTsKKwl2b2lkICgq ZXhpdCkoc3RydWN0IHR5cGVjX2FsdG1vZGUgKmFsdG1vZGUpOworCXZvaWQgKCphdHRlbnRpb24p KHN0cnVjdCB0eXBlY19hbHRtb2RlICphbHRtb2RlLCBjb25zdCB1MzIgdmRvKTsKKwlpbnQgKCp2 ZG0pKHN0cnVjdCB0eXBlY19hbHRtb2RlICphbHRtb2RlLCBjb25zdCB1MzIgaGRyLAorCQkgICBj b25zdCB1MzIgKnZkbywgaW50IGNudCk7CisJaW50ICgqbm90aWZ5KShzdHJ1Y3QgdHlwZWNfYWx0 bW9kZSAqYWx0bW9kZSwgdW5zaWduZWQgbG9uZyBjb25mLAorCQkgICAgICB2b2lkICpkYXRhKTsK K307CisKK3ZvaWQgdHlwZWNfYWx0bW9kZV9yZWdpc3Rlcl9vcHMoc3RydWN0IHR5cGVjX2FsdG1v ZGUgKmFsdG1vZGUsCisJCQkJY29uc3Qgc3RydWN0IHR5cGVjX2FsdG1vZGVfb3BzICpvcHMpOwor CitpbnQgdHlwZWNfYWx0bW9kZV9lbnRlcihzdHJ1Y3QgdHlwZWNfYWx0bW9kZSAqYWx0bW9kZSk7 CitpbnQgdHlwZWNfYWx0bW9kZV9leGl0KHN0cnVjdCB0eXBlY19hbHRtb2RlICphbHRtb2RlKTsK K3ZvaWQgdHlwZWNfYWx0bW9kZV9hdHRlbnRpb24oc3RydWN0IHR5cGVjX2FsdG1vZGUgKmFsdG1v ZGUsIGNvbnN0IHUzMiB2ZG8pOworaW50IHR5cGVjX2FsdG1vZGVfdmRtKHN0cnVjdCB0eXBlY19h bHRtb2RlICphbHRtb2RlLAorCQkgICAgICBjb25zdCB1MzIgaGVhZGVyLCBjb25zdCB1MzIgKnZk bywgaW50IGNvdW50KTsKK2ludCB0eXBlY19hbHRtb2RlX25vdGlmeShzdHJ1Y3QgdHlwZWNfYWx0 bW9kZSAqYWx0bW9kZSwgdW5zaWduZWQgbG9uZyBjb25mLAorCQkJIHZvaWQgKmRhdGEpOworCisv KiBSZXR1cm4gdmFsdWVzIGZvciB0eXBlX2FsdG1vZGVfdmRtKCkgKi8KKyNkZWZpbmUgVkRNX0RP TkUJCTAgLyogRG9uJ3QgY2FyZSAqLworI2RlZmluZSBWRE1fT0sJCQkxIC8qIFN1aXRzIG1lICov CisKKy8qCisgKiBUaGVzZSBhcmUgdGhlIHBpbiBzdGF0ZXMgKFVTQiwgU2FmZSBhbmQgQWx0IE1v ZGUpIGFuZCBhY2Nlc3NvcnkgbW9kZXMgKEF1ZGlvCisgKiBhbmQgRGVidWcpIGRlZmluZWQgaW4g VVNCIFR5cGUtQyBTcGVjaWZpY2F0aW9uLiBTVklEIHNwZWNpZmljIHBpbiBzdGF0ZXMgYXJlCisg KiBleHBlY3RlZCB0byBmb2xsb3cgYW5kIHN0YXJ0IGZyb20gdGhlIHZhbHVlIFRZUEVDX1NUQVRF X01PREFMLgorICoKKyAqIFBvcnQgZHJpdmVycyBzaG91bGQgdXNlIFRZUEVDX1NUQVRFX0FVRElP IGFuZCBUWVBFQ19TVEFURV9ERUJVRyBhcyB0aGUKKyAqIG9wZXJhdGlvbiB2YWx1ZSBmb3IgdHlw ZWNfc2V0X21vZGUoKSB3aGVuIGFjY2Vzc29yeSBtb2RlcyBhcmUgaW4gdXNlLgorICoKKyAqIE5P VEU6IHR5cGVjX2FsdG1vZGVfbm90aWZ5KCkgZG9lcyBub3QgYWNjZXB0IHZhbHVlcyBzbWFsbGVy IHRoZW4KKyAqIFRZUEVDX1NUQVRFX01PREFMLiBVU0IgVHlwZS1DIGJ1cyB3aWxsIGZvbGxvdyBV U0IgVHlwZS1DIFNwZWNpZmljYXRpb24gd2l0aAorICogVFlQRUNfU1RBVEVfVVNCIGFuZCBUWVBF Q19TVEFURV9TQUZFLgorICovCitlbnVtIHsKKwlUWVBFQ19TVEFURV9VU0IsCS8qIFVTQiBPcGVy YXRpb24gKi8KKwlUWVBFQ19TVEFURV9BVURJTywJLyogQXVkaW8gQWNjZXNzb3J5ICovCisJVFlQ RUNfU1RBVEVfREVCVUcsCS8qIERlYnVnIEFjY2Vzc29yeSAqLworCVRZUEVDX1NUQVRFX1NBRkUs CS8qIFVTQiBTYWZlIFN0YXRlICovCisJVFlQRUNfU1RBVEVfTU9EQUwsCS8qIEFsdGVybmF0ZSBN b2RlcyAqLworfTsKKworI2RlZmluZSBUWVBFQ19NT0RBTF9TVEFURShfc3RhdGVfKQkoKF9zdGF0 ZV8pICsgVFlQRUNfU1RBVEVfTU9EQUwpCisKK3N0cnVjdCB0eXBlY19hbHRtb2RlICp0eXBlY19h bHRtb2RlX2dldF9wbHVnKHN0cnVjdCB0eXBlY19hbHRtb2RlICphbHRtb2RlLAorCQkJCQkgICAg IGludCBpbmRleCk7Cit2b2lkIHR5cGVjX2FsdG1vZGVfcHV0X3BsdWcoc3RydWN0IHR5cGVjX2Fs dG1vZGUgKnBsdWcpOworCitib29sIHR5cGVjX2FsdG1vZGVfdWZwX2NhcGFibGUoc3RydWN0IHR5 cGVjX2FsdG1vZGUgKmFsdG1vZGUpOworYm9vbCB0eXBlY19hbHRtb2RlX2RmcF9jYXBhYmxlKHN0 cnVjdCB0eXBlY19hbHRtb2RlICphbHRtb2RlKTsKK3N0cnVjdCB0eXBlY19hbHRtb2RlICp0eXBl Y19tYXRjaF9hbHRtb2RlKHN0cnVjdCB0eXBlY19hbHRtb2RlICoqYWx0bW9kZXMsCisJCQkJCSAg c2l6ZV90IG4sIHUxNiBzdmlkLCB1OCBtb2RlKTsKKworLyoqCisgKiBzdHJ1Y3QgdHlwZWNfYWx0 bW9kZV9kcml2ZXIgLSBVU0IgVHlwZS1DIGFsdGVybmF0ZSBtb2RlIGRldmljZSBkcml2ZXIKKyAq IEBpZF90YWJsZTogTnVsbCB0ZXJtaW5hdGVkIGFycmF5IG9mIFNWSURzCisgKiBAcHJvYmU6IENh bGxiYWNrIGZvciBkZXZpY2UgYmluZGluZworICrCoEByZW1vdmU6IENhbGxiYWNrIGZvciBkZXZp Y2UgdW5iaW5kaW5nCisgKiBAZHJpdmVyOiBEZXZpY2UgZHJpdmVyIG1vZGVsIGRyaXZlcgorICoK KyAqIFRoZXNlIGRyaXZlcnMgd2lsbCBiZSBiaW5kIHRvIHRoZSBwYXJ0bmVyIGFsdGVybmF0ZSBt b2RlIGRldmljZXMuIFRoZXkgd2lsbAorICogaGFuZGxlIGFsbCBTVklEIHNwZWNpZmljIGNvbW11 bmljYXRpb24uCisgKi8KK3N0cnVjdCB0eXBlY19hbHRtb2RlX2RyaXZlciB7CisJY29uc3Qgc3Ry dWN0IHR5cGVjX2RldmljZV9pZCAqaWRfdGFibGU7CisJaW50ICgqcHJvYmUpKHN0cnVjdCB0eXBl Y19hbHRtb2RlICphbHRtb2RlLCB1MzIgcG9ydF92ZG8pOworCXZvaWQgKCpyZW1vdmUpKHN0cnVj dCB0eXBlY19hbHRtb2RlICphbHRtb2RlKTsKKwlzdHJ1Y3QgZGV2aWNlX2RyaXZlciBkcml2ZXI7 Cit9OworCisjZGVmaW5lIHRvX2FsdG1vZGVfZHJpdmVyKGQpIGNvbnRhaW5lcl9vZihkLCBzdHJ1 Y3QgdHlwZWNfYWx0bW9kZV9kcml2ZXIsIFwKKwkJCQkJICBkcml2ZXIpCisKKyNkZWZpbmUgdHlw ZWNfYWx0bW9kZV9yZWdpc3Rlcl9kcml2ZXIoZHJ2KSBcCisJCV9fdHlwZWNfYWx0bW9kZV9yZWdp c3Rlcl9kcml2ZXIoZHJ2LCBUSElTX01PRFVMRSkKK2ludCBfX3R5cGVjX2FsdG1vZGVfcmVnaXN0 ZXJfZHJpdmVyKHN0cnVjdCB0eXBlY19hbHRtb2RlX2RyaXZlciAqZHJ2LAorCQkJCSAgICBzdHJ1 Y3QgbW9kdWxlICptb2R1bGUpOwordm9pZCB0eXBlY19hbHRtb2RlX3VucmVnaXN0ZXJfZHJpdmVy KHN0cnVjdCB0eXBlY19hbHRtb2RlX2RyaXZlciAqZHJ2KTsKKworI2RlZmluZSBtb2R1bGVfdHlw ZWNfYWx0bW9kZV9kcml2ZXIoX190eXBlY19hbHRtb2RlX2RyaXZlcikgXAorCW1vZHVsZV9kcml2 ZXIoX190eXBlY19hbHRtb2RlX2RyaXZlciwgdHlwZWNfYWx0bW9kZV9yZWdpc3Rlcl9kcml2ZXIs IFwKKwkJICAgICAgdHlwZWNfYWx0bW9kZV91bnJlZ2lzdGVyX2RyaXZlcikKKworI2VuZGlmIC8q IF9fVVNCX1RZUEVDX0FMVE1PREVfSCAqLwpkaWZmIC0tZ2l0IGEvc2NyaXB0cy9tb2QvZGV2aWNl dGFibGUtb2Zmc2V0cy5jIGIvc2NyaXB0cy9tb2QvZGV2aWNldGFibGUtb2Zmc2V0cy5jCmluZGV4 IDlmYWQ2YWZlNGM0MS4uYzQ4YzdmNTZhZTY0IDEwMDY0NAotLS0gYS9zY3JpcHRzL21vZC9kZXZp Y2V0YWJsZS1vZmZzZXRzLmMKKysrIGIvc2NyaXB0cy9tb2QvZGV2aWNldGFibGUtb2Zmc2V0cy5j CkBAIC0yMTgsNSArMjE4LDkgQEAgaW50IG1haW4odm9pZCkKIAlERVZJRF9GSUVMRCh0Yl9zZXJ2 aWNlX2lkLCBwcm90b2NvbF92ZXJzaW9uKTsKIAlERVZJRF9GSUVMRCh0Yl9zZXJ2aWNlX2lkLCBw cm90b2NvbF9yZXZpc2lvbik7CiAKKwlERVZJRCh0eXBlY19kZXZpY2VfaWQpOworCURFVklEX0ZJ RUxEKHR5cGVjX2RldmljZV9pZCwgc3ZpZCk7CisJREVWSURfRklFTEQodHlwZWNfZGV2aWNlX2lk LCBtb2RlKTsKKwogCXJldHVybiAwOwogfQpkaWZmIC0tZ2l0IGEvc2NyaXB0cy9tb2QvZmlsZTJh bGlhcy5jIGIvc2NyaXB0cy9tb2QvZmlsZTJhbGlhcy5jCmluZGV4IGI5YmVlYWE0Njk1Yi4uYThh ZmJhODM2NDA5IDEwMDY0NAotLS0gYS9zY3JpcHRzL21vZC9maWxlMmFsaWFzLmMKKysrIGIvc2Ny aXB0cy9tb2QvZmlsZTJhbGlhcy5jCkBAIC0xMzQxLDYgKzEzNDEsMTkgQEAgc3RhdGljIGludCBk b190YnN2Y19lbnRyeShjb25zdCBjaGFyICpmaWxlbmFtZSwgdm9pZCAqc3ltdmFsLCBjaGFyICph bGlhcykKIH0KIEFERF9UT19ERVZUQUJMRSgidGJzdmMiLCB0Yl9zZXJ2aWNlX2lkLCBkb190YnN2 Y19lbnRyeSk7CiAKKy8qIExvb2tzIGxpa2U6IHR5cGVjOmlkTm1OICovCitzdGF0aWMgaW50IGRv X3R5cGVjX2VudHJ5KGNvbnN0IGNoYXIgKmZpbGVuYW1lLCB2b2lkICpzeW12YWwsIGNoYXIgKmFs aWFzKQoreworCURFRl9GSUVMRChzeW12YWwsIHR5cGVjX2RldmljZV9pZCwgc3ZpZCk7CisJREVG X0ZJRUxEKHN5bXZhbCwgdHlwZWNfZGV2aWNlX2lkLCBtb2RlKTsKKworCXNwcmludGYoYWxpYXMs ICJ0eXBlYzppZCUwNFgiLCBzdmlkKTsKKwlBREQoYWxpYXMsICJtIiwgbW9kZSAhPSBUWVBFQ19B TllfTU9ERSwgbW9kZSk7CisKKwlyZXR1cm4gMTsKK30KK0FERF9UT19ERVZUQUJMRSgidHlwZWMi LCB0eXBlY19kZXZpY2VfaWQsIGRvX3R5cGVjX2VudHJ5KTsKKwogLyogRG9lcyBuYW1lbGVuIGJ5 dGVzIG9mIG5hbWUgZXhhY3RseSBtYXRjaCB0aGUgc3ltYm9sPyAqLwogc3RhdGljIGJvb2wgc3lt X2lzKGNvbnN0IGNoYXIgKm5hbWUsIHVuc2lnbmVkIG5hbWVsZW4sIGNvbnN0IGNoYXIgKnN5bWJv bCkKIHsK