From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Google-Smtp-Source: AG47ELuEX1JpX8NdQJMPdU/xvRrjNvllEGmnh5Mg7wh2GcBs8zTxjxDTA8m9jrb1Hs1+W3Hi9CSq ARC-Seal: i=1; a=rsa-sha256; t=1521550648; cv=none; d=google.com; s=arc-20160816; b=VQ0NtPsZLQ8RQGptHRyKI9yVTgxZ4APO8+DouKf8Say96O/trkVztMMboyMyv4mBCZ oYu0kxDZ3YVvvAHjsppshA5nfz05z6WQG/NKe5nQFjISLmMCOXs/vJSSxjWPCUF7vir4 7ia3QNamENCwQNrG+jWHD++4Vrp45o80eapPsSNHuPAxiENxtLOdqWPzRrxJBU3+MPF2 +6AQve1jLn5UPNwBv01R+rKyjsQMzF3xzswdaR1wyWZhGolxlNJWz1kdxgjK6YzM8Whi l50+4w0Z7dWK8IgUBcGyzHAAEFEEkd3ERJAylq1f9NrSebabz53gudOEEQ/NgB8aHYqo Ro7g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=references:in-reply-to:message-id:date:subject:cc:to:from :arc-authentication-results; bh=NKp4YKqHr0cyfZrszTbj1bzgqgYIDtX4jkvfQzc8Kiw=; b=qhlFUmTPr47NW271qjr6udz8+zbsVsrMXwQEEt5+n4nryCQ5Hzo3qTPS1cemSX4gJq CHjf3bGPoc8DEyosVRHqzkZfkQxaloiNhcsz8J6Eu9Idw3T6detrVR6jnb9WqopdjD5C yCu/C7W8dDEmo5zOBJeVBOVo7dL865yKqTgjU5qA8IptlPbVHySp747m9LJ46Scp05GV pOt2UgDt8jNv1mn4/qnMJ2F7hhD06iMwXmU3RnJ8rzFTIBE6MsPqaghP5HKLbMKndHd3 juJ3ex6TGNvCTMGz766u7PBHMUu5MetdN3OUe7FY3z0Kb4KyScWx2eyaw2KG/I4HbSZL EPvg== 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.31 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.31 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.48,335,1517904000"; d="scan'208";a="39592512" From: Heikki Krogerus To: Greg Kroah-Hartman , Hans de Goede Cc: Darren Hart , Andy Shevchenko , MyungJoo Ham , Chanwoo Choi , Mathias Nyman , Guenter Roeck , Jun Li , platform-driver-x86@vger.kernel.org, linux-kernel@vger.kernel.org, linux-usb@vger.kernel.org Subject: [PATCH v9 03/12] usb: common: Small class for USB role switches Date: Tue, 20 Mar 2018 15:57:04 +0300 Message-Id: <20180320125713.85465-4-heikki.krogerus@linux.intel.com> X-Mailer: git-send-email 2.16.2 In-Reply-To: <20180320125713.85465-1-heikki.krogerus@linux.intel.com> References: <20180320125713.85465-1-heikki.krogerus@linux.intel.com> X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: =?utf-8?q?1595461493099811103?= X-GMAIL-MSGID: =?utf-8?q?1595461493099811103?= X-Mailing-List: linux-kernel@vger.kernel.org List-ID: USB role switch is a device that can be used to choose the data role for USB connector. With dual-role capable USB controllers, the controller itself will be the switch, but on some platforms the USB host and device controllers are separate IPs and there is a mux between them and the connector. On those platforms the mux driver will need to register the switch. With USB Type-C connectors, the host-to-device relationship is negotiated over the Configuration Channel (CC). That means the USB Type-C drivers need to be in control of the role switch. The class provides a simple API for the USB Type-C drivers for the control. For other types of USB connectors (mainly microAB) the class provides user space control via sysfs attribute file that can be used to request role swapping from the switch. Reviewed-by: Hans de Goede Reviewed-by: Andy Shevchenko Signed-off-by: Heikki Krogerus --- Changes in v4: -Consistently use IS_ERR_OR_NULL where applicable -Add Andy's Reviewed-by Changes in v2: -Minor style fixes from review of v1 --- Documentation/ABI/testing/sysfs-class-usb_role | 21 ++ drivers/usb/Kconfig | 3 + drivers/usb/common/Makefile | 1 + drivers/usb/common/roles.c | 305 +++++++++++++++++++++++++ include/linux/usb/role.h | 53 +++++ 5 files changed, 383 insertions(+) create mode 100644 Documentation/ABI/testing/sysfs-class-usb_role create mode 100644 drivers/usb/common/roles.c create mode 100644 include/linux/usb/role.h diff --git a/Documentation/ABI/testing/sysfs-class-usb_role b/Documentation/ABI/testing/sysfs-class-usb_role new file mode 100644 index 000000000000..3b810a425a52 --- /dev/null +++ b/Documentation/ABI/testing/sysfs-class-usb_role @@ -0,0 +1,21 @@ +What: /sys/class/usb_role/ +Date: Jan 2018 +Contact: Heikki Krogerus +Description: + Place in sysfs for USB Role Switches. USB Role Switch is a + device that can select the data role (host or device) for USB + port. + +What: /sys/class/usb_role//role +Date: Jan 2018 +Contact: Heikki Krogerus +Description: + The current role of the switch. This attribute can be used for + requesting role swapping with non-USB Type-C ports. With USB + Type-C ports, the ABI defined for USB Type-C connector class + must be used. + + Valid values: + - none + - host + - device diff --git a/drivers/usb/Kconfig b/drivers/usb/Kconfig index 148f3ee70286..f278958e04ca 100644 --- a/drivers/usb/Kconfig +++ b/drivers/usb/Kconfig @@ -203,4 +203,7 @@ config USB_ULPI_BUS To compile this driver as a module, choose M here: the module will be called ulpi. +config USB_ROLE_SWITCH + tristate + endif # USB_SUPPORT diff --git a/drivers/usb/common/Makefile b/drivers/usb/common/Makefile index 0a7c45e85481..fb4d5ef4165c 100644 --- a/drivers/usb/common/Makefile +++ b/drivers/usb/common/Makefile @@ -9,3 +9,4 @@ usb-common-$(CONFIG_USB_LED_TRIG) += led.o obj-$(CONFIG_USB_OTG_FSM) += usb-otg-fsm.o obj-$(CONFIG_USB_ULPI_BUS) += ulpi.o +obj-$(CONFIG_USB_ROLE_SWITCH) += roles.o diff --git a/drivers/usb/common/roles.c b/drivers/usb/common/roles.c new file mode 100644 index 000000000000..15cc76e22123 --- /dev/null +++ b/drivers/usb/common/roles.c @@ -0,0 +1,305 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * USB Role Switch Support + * + * Copyright (C) 2018 Intel Corporation + * Author: Heikki Krogerus + * Hans de Goede + */ + +#include +#include +#include +#include +#include + +static struct class *role_class; + +struct usb_role_switch { + struct device dev; + struct mutex lock; /* device lock*/ + enum usb_role role; + + /* From descriptor */ + struct device *usb2_port; + struct device *usb3_port; + struct device *udc; + usb_role_switch_set_t set; + usb_role_switch_get_t get; + bool allow_userspace_control; +}; + +#define to_role_switch(d) container_of(d, struct usb_role_switch, dev) + +/** + * usb_role_switch_set_role - Set USB role for a switch + * @sw: USB role switch + * @role: USB role to be switched to + * + * Set USB role @role for @sw. + */ +int usb_role_switch_set_role(struct usb_role_switch *sw, enum usb_role role) +{ + int ret; + + if (IS_ERR_OR_NULL(sw)) + return 0; + + mutex_lock(&sw->lock); + + ret = sw->set(sw->dev.parent, role); + if (!ret) + sw->role = role; + + mutex_unlock(&sw->lock); + + return ret; +} +EXPORT_SYMBOL_GPL(usb_role_switch_set_role); + +/** + * usb_role_switch_get_role - Get the USB role for a switch + * @sw: USB role switch + * + * Depending on the role-switch-driver this function returns either a cached + * value of the last set role, or reads back the actual value from the hardware. + */ +enum usb_role usb_role_switch_get_role(struct usb_role_switch *sw) +{ + enum usb_role role; + + if (IS_ERR_OR_NULL(sw)) + return USB_ROLE_NONE; + + mutex_lock(&sw->lock); + + if (sw->get) + role = sw->get(sw->dev.parent); + else + role = sw->role; + + mutex_unlock(&sw->lock); + + return role; +} +EXPORT_SYMBOL_GPL(usb_role_switch_get_role); + +static int __switch_match(struct device *dev, const void *name) +{ + return !strcmp((const char *)name, dev_name(dev)); +} + +static void *usb_role_switch_match(struct device_connection *con, int ep, + void *data) +{ + struct device *dev; + + dev = class_find_device(role_class, NULL, con->endpoint[ep], + __switch_match); + + return dev ? to_role_switch(dev) : ERR_PTR(-EPROBE_DEFER); +} + +/** + * usb_role_switch_get - Find USB role switch linked with the caller + * @dev: The caller device + * + * Finds and returns role switch linked with @dev. The reference count for the + * found switch is incremented. + */ +struct usb_role_switch *usb_role_switch_get(struct device *dev) +{ + return device_connection_find_match(dev, "usb-role-switch", NULL, + usb_role_switch_match); +} +EXPORT_SYMBOL_GPL(usb_role_switch_get); + +/** + * usb_role_switch_put - Release handle to a switch + * @sw: USB Role Switch + * + * Decrement reference count for @sw. + */ +void usb_role_switch_put(struct usb_role_switch *sw) +{ + if (!IS_ERR_OR_NULL(sw)) + put_device(&sw->dev); +} +EXPORT_SYMBOL_GPL(usb_role_switch_put); + +static umode_t +usb_role_switch_is_visible(struct kobject *kobj, struct attribute *attr, int n) +{ + struct device *dev = container_of(kobj, typeof(*dev), kobj); + struct usb_role_switch *sw = to_role_switch(dev); + + if (sw->allow_userspace_control) + return attr->mode; + + return 0; +} + +static const char * const usb_roles[] = { + [USB_ROLE_NONE] = "none", + [USB_ROLE_HOST] = "host", + [USB_ROLE_DEVICE] = "device", +}; + +static ssize_t +role_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct usb_role_switch *sw = to_role_switch(dev); + enum usb_role role = usb_role_switch_get_role(sw); + + return sprintf(buf, "%s\n", usb_roles[role]); +} + +static ssize_t role_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t size) +{ + struct usb_role_switch *sw = to_role_switch(dev); + int ret; + + ret = sysfs_match_string(usb_roles, buf); + if (ret < 0) { + bool res; + + /* Extra check if the user wants to disable the switch */ + ret = kstrtobool(buf, &res); + if (ret || res) + return -EINVAL; + } + + ret = usb_role_switch_set_role(sw, ret); + if (ret) + return ret; + + return size; +} +static DEVICE_ATTR_RW(role); + +static struct attribute *usb_role_switch_attrs[] = { + &dev_attr_role.attr, + NULL, +}; + +static const struct attribute_group usb_role_switch_group = { + .is_visible = usb_role_switch_is_visible, + .attrs = usb_role_switch_attrs, +}; + +static const struct attribute_group *usb_role_switch_groups[] = { + &usb_role_switch_group, + NULL, +}; + +static int +usb_role_switch_uevent(struct device *dev, struct kobj_uevent_env *env) +{ + int ret; + + ret = add_uevent_var(env, "USB_ROLE_SWITCH=%s", dev_name(dev)); + if (ret) + dev_err(dev, "failed to add uevent USB_ROLE_SWITCH\n"); + + return ret; +} + +static void usb_role_switch_release(struct device *dev) +{ + struct usb_role_switch *sw = to_role_switch(dev); + + kfree(sw); +} + +static const struct device_type usb_role_dev_type = { + .name = "usb_role_switch", + .groups = usb_role_switch_groups, + .uevent = usb_role_switch_uevent, + .release = usb_role_switch_release, +}; + +/** + * usb_role_switch_register - Register USB Role Switch + * @parent: Parent device for the switch + * @desc: Description of the switch + * + * USB Role Switch is a device capable or choosing the role for USB connector. + * On platforms where the USB controller is dual-role capable, the controller + * driver will need to register the switch. On platforms where the USB host and + * USB device controllers behind the connector are separate, there will be a + * mux, and the driver for that mux will need to register the switch. + * + * Returns handle to a new role switch or ERR_PTR. The content of @desc is + * copied. + */ +struct usb_role_switch * +usb_role_switch_register(struct device *parent, + const struct usb_role_switch_desc *desc) +{ + struct usb_role_switch *sw; + int ret; + + if (!desc || !desc->set) + return ERR_PTR(-EINVAL); + + sw = kzalloc(sizeof(*sw), GFP_KERNEL); + if (!sw) + return ERR_PTR(-ENOMEM); + + mutex_init(&sw->lock); + + sw->allow_userspace_control = desc->allow_userspace_control; + sw->usb2_port = desc->usb2_port; + sw->usb3_port = desc->usb3_port; + sw->udc = desc->udc; + sw->set = desc->set; + sw->get = desc->get; + + sw->dev.parent = parent; + sw->dev.class = role_class; + sw->dev.type = &usb_role_dev_type; + dev_set_name(&sw->dev, "%s-role-switch", dev_name(parent)); + + ret = device_register(&sw->dev); + if (ret) { + put_device(&sw->dev); + return ERR_PTR(ret); + } + + /* TODO: Symlinks for the host port and the device controller. */ + + return sw; +} +EXPORT_SYMBOL_GPL(usb_role_switch_register); + +/** + * usb_role_switch_unregister - Unregsiter USB Role Switch + * @sw: USB Role Switch + * + * Unregister switch that was registered with usb_role_switch_register(). + */ +void usb_role_switch_unregister(struct usb_role_switch *sw) +{ + if (!IS_ERR_OR_NULL(sw)) + device_unregister(&sw->dev); +} +EXPORT_SYMBOL_GPL(usb_role_switch_unregister); + +static int __init usb_roles_init(void) +{ + role_class = class_create(THIS_MODULE, "usb_role"); + return PTR_ERR_OR_ZERO(role_class); +} +subsys_initcall(usb_roles_init); + +static void __exit usb_roles_exit(void) +{ + class_destroy(role_class); +} +module_exit(usb_roles_exit); + +MODULE_AUTHOR("Heikki Krogerus "); +MODULE_AUTHOR("Hans de Goede "); +MODULE_LICENSE("GPL v2"); +MODULE_DESCRIPTION("USB Role Class"); diff --git a/include/linux/usb/role.h b/include/linux/usb/role.h new file mode 100644 index 000000000000..edc51be4a77c --- /dev/null +++ b/include/linux/usb/role.h @@ -0,0 +1,53 @@ +// SPDX-License-Identifier: GPL-2.0 + +#ifndef __LINUX_USB_ROLE_H +#define __LINUX_USB_ROLE_H + +#include + +struct usb_role_switch; + +enum usb_role { + USB_ROLE_NONE, + USB_ROLE_HOST, + USB_ROLE_DEVICE, +}; + +typedef int (*usb_role_switch_set_t)(struct device *dev, enum usb_role role); +typedef enum usb_role (*usb_role_switch_get_t)(struct device *dev); + +/** + * struct usb_role_switch_desc - USB Role Switch Descriptor + * @usb2_port: Optional reference to the host controller port device (USB2) + * @usb3_port: Optional reference to the host controller port device (USB3) + * @udc: Optional reference to the peripheral controller device + * @set: Callback for setting the role + * @get: Callback for getting the role (optional) + * @allow_userspace_control: If true userspace may change the role through sysfs + * + * @usb2_port and @usb3_port will point to the USB host port and @udc to the USB + * device controller behind the USB connector with the role switch. If + * @usb2_port, @usb3_port and @udc are included in the description, the + * reference count for them should be incremented by the caller of + * usb_role_switch_register() before registering the switch. + */ +struct usb_role_switch_desc { + struct device *usb2_port; + struct device *usb3_port; + struct device *udc; + usb_role_switch_set_t set; + usb_role_switch_get_t get; + bool allow_userspace_control; +}; + +int usb_role_switch_set_role(struct usb_role_switch *sw, enum usb_role role); +enum usb_role usb_role_switch_get_role(struct usb_role_switch *sw); +struct usb_role_switch *usb_role_switch_get(struct device *dev); +void usb_role_switch_put(struct usb_role_switch *sw); + +struct usb_role_switch * +usb_role_switch_register(struct device *parent, + const struct usb_role_switch_desc *desc); +void usb_role_switch_unregister(struct usb_role_switch *sw); + +#endif /* __LINUX_USB_ROLE_H */ -- 2.16.2 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: [v9,03/12] usb: common: Small class for USB role switches From: Heikki Krogerus Message-Id: <20180320125713.85465-4-heikki.krogerus@linux.intel.com> Date: Tue, 20 Mar 2018 15:57:04 +0300 To: Greg Kroah-Hartman , Hans de Goede Cc: Darren Hart , Andy Shevchenko , MyungJoo Ham , Chanwoo Choi , Mathias Nyman , Guenter Roeck , Jun Li , platform-driver-x86@vger.kernel.org, linux-kernel@vger.kernel.org, linux-usb@vger.kernel.org List-ID: VVNCIHJvbGUgc3dpdGNoIGlzIGEgZGV2aWNlIHRoYXQgY2FuIGJlIHVzZWQgdG8gY2hvb3NlIHRo ZQpkYXRhIHJvbGUgZm9yIFVTQiBjb25uZWN0b3IuIFdpdGggZHVhbC1yb2xlIGNhcGFibGUgVVNC CmNvbnRyb2xsZXJzLCB0aGUgY29udHJvbGxlciBpdHNlbGYgd2lsbCBiZSB0aGUgc3dpdGNoLCBi dXQKb24gc29tZSBwbGF0Zm9ybXMgdGhlIFVTQiBob3N0IGFuZCBkZXZpY2UgY29udHJvbGxlcnMg YXJlCnNlcGFyYXRlIElQcyBhbmQgdGhlcmUgaXMgYSBtdXggYmV0d2VlbiB0aGVtIGFuZCB0aGUK Y29ubmVjdG9yLiBPbiB0aG9zZSBwbGF0Zm9ybXMgdGhlIG11eCBkcml2ZXIgd2lsbCBuZWVkIHRv CnJlZ2lzdGVyIHRoZSBzd2l0Y2guCgpXaXRoIFVTQiBUeXBlLUMgY29ubmVjdG9ycywgdGhlIGhv c3QtdG8tZGV2aWNlIHJlbGF0aW9uc2hpcAppcyBuZWdvdGlhdGVkIG92ZXIgdGhlIENvbmZpZ3Vy YXRpb24gQ2hhbm5lbCAoQ0MpLiBUaGF0Cm1lYW5zIHRoZSBVU0IgVHlwZS1DIGRyaXZlcnMgbmVl ZCB0byBiZSBpbiBjb250cm9sIG9mIHRoZQpyb2xlIHN3aXRjaC4gVGhlIGNsYXNzIHByb3ZpZGVz IGEgc2ltcGxlIEFQSSBmb3IgdGhlIFVTQgpUeXBlLUMgZHJpdmVycyBmb3IgdGhlIGNvbnRyb2wu CgpGb3Igb3RoZXIgdHlwZXMgb2YgVVNCIGNvbm5lY3RvcnMgKG1haW5seSBtaWNyb0FCKSB0aGUg Y2xhc3MKcHJvdmlkZXMgdXNlciBzcGFjZSBjb250cm9sIHZpYSBzeXNmcyBhdHRyaWJ1dGUgZmls ZSB0aGF0CmNhbiBiZSB1c2VkIHRvIHJlcXVlc3Qgcm9sZSBzd2FwcGluZyBmcm9tIHRoZSBzd2l0 Y2guCgpSZXZpZXdlZC1ieTogSGFucyBkZSBHb2VkZSA8aGRlZ29lZGVAcmVkaGF0LmNvbT4KUmV2 aWV3ZWQtYnk6IEFuZHkgU2hldmNoZW5rbyA8YW5keS5zaGV2Y2hlbmtvQGdtYWlsLmNvbT4KU2ln bmVkLW9mZi1ieTogSGVpa2tpIEtyb2dlcnVzIDxoZWlra2kua3JvZ2VydXNAbGludXguaW50ZWwu Y29tPgotLS0KQ2hhbmdlcyBpbiB2NDoKLUNvbnNpc3RlbnRseSB1c2UgSVNfRVJSX09SX05VTEwg d2hlcmUgYXBwbGljYWJsZQotQWRkIEFuZHkncyBSZXZpZXdlZC1ieQoKQ2hhbmdlcyBpbiB2MjoK LU1pbm9yIHN0eWxlIGZpeGVzIGZyb20gcmV2aWV3IG9mIHYxCi0tLQogRG9jdW1lbnRhdGlvbi9B QkkvdGVzdGluZy9zeXNmcy1jbGFzcy11c2Jfcm9sZSB8ICAyMSArKwogZHJpdmVycy91c2IvS2Nv bmZpZyAgICAgICAgICAgICAgICAgICAgICAgICAgICB8ICAgMyArCiBkcml2ZXJzL3VzYi9jb21t b24vTWFrZWZpbGUgICAgICAgICAgICAgICAgICAgIHwgICAxICsKIGRyaXZlcnMvdXNiL2NvbW1v bi9yb2xlcy5jICAgICAgICAgICAgICAgICAgICAgfCAzMDUgKysrKysrKysrKysrKysrKysrKysr KysrKwogaW5jbHVkZS9saW51eC91c2Ivcm9sZS5oICAgICAgICAgICAgICAgICAgICAgICB8ICA1 MyArKysrKwogNSBmaWxlcyBjaGFuZ2VkLCAzODMgaW5zZXJ0aW9ucygrKQogY3JlYXRlIG1vZGUg MTAwNjQ0IERvY3VtZW50YXRpb24vQUJJL3Rlc3Rpbmcvc3lzZnMtY2xhc3MtdXNiX3JvbGUKIGNy ZWF0ZSBtb2RlIDEwMDY0NCBkcml2ZXJzL3VzYi9jb21tb24vcm9sZXMuYwogY3JlYXRlIG1vZGUg MTAwNjQ0IGluY2x1ZGUvbGludXgvdXNiL3JvbGUuaAoKZGlmZiAtLWdpdCBhL0RvY3VtZW50YXRp b24vQUJJL3Rlc3Rpbmcvc3lzZnMtY2xhc3MtdXNiX3JvbGUgYi9Eb2N1bWVudGF0aW9uL0FCSS90 ZXN0aW5nL3N5c2ZzLWNsYXNzLXVzYl9yb2xlCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAw MDAwMDAwMDAwMC4uM2I4MTBhNDI1YTUyCi0tLSAvZGV2L251bGwKKysrIGIvRG9jdW1lbnRhdGlv bi9BQkkvdGVzdGluZy9zeXNmcy1jbGFzcy11c2Jfcm9sZQpAQCAtMCwwICsxLDIxIEBACitXaGF0 OgkJL3N5cy9jbGFzcy91c2Jfcm9sZS8KK0RhdGU6CQlKYW4gMjAxOAorQ29udGFjdDoJSGVpa2tp IEtyb2dlcnVzIDxoZWlra2kua3JvZ2VydXNAbGludXguaW50ZWwuY29tPgorRGVzY3JpcHRpb246 CisJCVBsYWNlIGluIHN5c2ZzIGZvciBVU0IgUm9sZSBTd2l0Y2hlcy4gVVNCIFJvbGUgU3dpdGNo IGlzIGEKKwkJZGV2aWNlIHRoYXQgY2FuIHNlbGVjdCB0aGUgZGF0YSByb2xlIChob3N0IG9yIGRl dmljZSkgZm9yIFVTQgorCQlwb3J0LgorCitXaGF0OgkJL3N5cy9jbGFzcy91c2Jfcm9sZS88c3dp dGNoPi9yb2xlCitEYXRlOgkJSmFuIDIwMTgKK0NvbnRhY3Q6CUhlaWtraSBLcm9nZXJ1cyA8aGVp a2tpLmtyb2dlcnVzQGxpbnV4LmludGVsLmNvbT4KK0Rlc2NyaXB0aW9uOgorCQlUaGUgY3VycmVu dCByb2xlIG9mIHRoZSBzd2l0Y2guIFRoaXMgYXR0cmlidXRlIGNhbiBiZSB1c2VkIGZvcgorCQly ZXF1ZXN0aW5nIHJvbGUgc3dhcHBpbmcgd2l0aCBub24tVVNCIFR5cGUtQyBwb3J0cy4gV2l0aCBV U0IKKwkJVHlwZS1DIHBvcnRzLCB0aGUgQUJJIGRlZmluZWQgZm9yIFVTQiBUeXBlLUMgY29ubmVj dG9yIGNsYXNzCisJCW11c3QgYmUgdXNlZC4KKworCQlWYWxpZCB2YWx1ZXM6CisJCS0gbm9uZQor CQktIGhvc3QKKwkJLSBkZXZpY2UKZGlmZiAtLWdpdCBhL2RyaXZlcnMvdXNiL0tjb25maWcgYi9k cml2ZXJzL3VzYi9LY29uZmlnCmluZGV4IDE0OGYzZWU3MDI4Ni4uZjI3ODk1OGUwNGNhIDEwMDY0 NAotLS0gYS9kcml2ZXJzL3VzYi9LY29uZmlnCisrKyBiL2RyaXZlcnMvdXNiL0tjb25maWcKQEAg LTIwMyw0ICsyMDMsNyBAQCBjb25maWcgVVNCX1VMUElfQlVTCiAJICBUbyBjb21waWxlIHRoaXMg ZHJpdmVyIGFzIGEgbW9kdWxlLCBjaG9vc2UgTSBoZXJlOiB0aGUgbW9kdWxlIHdpbGwKIAkgIGJl IGNhbGxlZCB1bHBpLgogCitjb25maWcgVVNCX1JPTEVfU1dJVENICisJdHJpc3RhdGUKKwogZW5k aWYgIyBVU0JfU1VQUE9SVApkaWZmIC0tZ2l0IGEvZHJpdmVycy91c2IvY29tbW9uL01ha2VmaWxl IGIvZHJpdmVycy91c2IvY29tbW9uL01ha2VmaWxlCmluZGV4IDBhN2M0NWU4NTQ4MS4uZmI0ZDVl ZjQxNjVjIDEwMDY0NAotLS0gYS9kcml2ZXJzL3VzYi9jb21tb24vTWFrZWZpbGUKKysrIGIvZHJp dmVycy91c2IvY29tbW9uL01ha2VmaWxlCkBAIC05LDMgKzksNCBAQCB1c2ItY29tbW9uLSQoQ09O RklHX1VTQl9MRURfVFJJRykgKz0gbGVkLm8KIAogb2JqLSQoQ09ORklHX1VTQl9PVEdfRlNNKSAr PSB1c2Itb3RnLWZzbS5vCiBvYmotJChDT05GSUdfVVNCX1VMUElfQlVTKQkrPSB1bHBpLm8KK29i ai0kKENPTkZJR19VU0JfUk9MRV9TV0lUQ0gpCSs9IHJvbGVzLm8KZGlmZiAtLWdpdCBhL2RyaXZl cnMvdXNiL2NvbW1vbi9yb2xlcy5jIGIvZHJpdmVycy91c2IvY29tbW9uL3JvbGVzLmMKbmV3IGZp bGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMDAwMDAwLi4xNWNjNzZlMjIxMjMKLS0tIC9kZXYv bnVsbAorKysgYi9kcml2ZXJzL3VzYi9jb21tb24vcm9sZXMuYwpAQCAtMCwwICsxLDMwNSBAQAor Ly8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEdQTC0yLjAKKy8qCisgKiBVU0IgUm9sZSBTd2l0 Y2ggU3VwcG9ydAorICoKKyAqIENvcHlyaWdodCAoQykgMjAxOCBJbnRlbCBDb3Jwb3JhdGlvbgor ICogQXV0aG9yOiBIZWlra2kgS3JvZ2VydXMgPGhlaWtraS5rcm9nZXJ1c0BsaW51eC5pbnRlbC5j b20+CisgKiAgICAgICAgIEhhbnMgZGUgR29lZGUgPGhkZWdvZWRlQHJlZGhhdC5jb20+CisgKi8K KworI2luY2x1ZGUgPGxpbnV4L3VzYi9yb2xlLmg+CisjaW5jbHVkZSA8bGludXgvZGV2aWNlLmg+ CisjaW5jbHVkZSA8bGludXgvbW9kdWxlLmg+CisjaW5jbHVkZSA8bGludXgvbXV0ZXguaD4KKyNp bmNsdWRlIDxsaW51eC9zbGFiLmg+CisKK3N0YXRpYyBzdHJ1Y3QgY2xhc3MgKnJvbGVfY2xhc3M7 CisKK3N0cnVjdCB1c2Jfcm9sZV9zd2l0Y2ggeworCXN0cnVjdCBkZXZpY2UgZGV2OworCXN0cnVj dCBtdXRleCBsb2NrOyAvKiBkZXZpY2UgbG9jayovCisJZW51bSB1c2Jfcm9sZSByb2xlOworCisJ LyogRnJvbSBkZXNjcmlwdG9yICovCisJc3RydWN0IGRldmljZSAqdXNiMl9wb3J0OworCXN0cnVj dCBkZXZpY2UgKnVzYjNfcG9ydDsKKwlzdHJ1Y3QgZGV2aWNlICp1ZGM7CisJdXNiX3JvbGVfc3dp dGNoX3NldF90IHNldDsKKwl1c2Jfcm9sZV9zd2l0Y2hfZ2V0X3QgZ2V0OworCWJvb2wgYWxsb3df dXNlcnNwYWNlX2NvbnRyb2w7Cit9OworCisjZGVmaW5lIHRvX3JvbGVfc3dpdGNoKGQpCWNvbnRh aW5lcl9vZihkLCBzdHJ1Y3QgdXNiX3JvbGVfc3dpdGNoLCBkZXYpCisKKy8qKgorICogdXNiX3Jv bGVfc3dpdGNoX3NldF9yb2xlIC0gU2V0IFVTQiByb2xlIGZvciBhIHN3aXRjaAorICogQHN3OiBV U0Igcm9sZSBzd2l0Y2gKKyAqIEByb2xlOiBVU0Igcm9sZSB0byBiZSBzd2l0Y2hlZCB0bworICoK KyAqIFNldCBVU0Igcm9sZSBAcm9sZSBmb3IgQHN3LgorICovCitpbnQgdXNiX3JvbGVfc3dpdGNo X3NldF9yb2xlKHN0cnVjdCB1c2Jfcm9sZV9zd2l0Y2ggKnN3LCBlbnVtIHVzYl9yb2xlIHJvbGUp Cit7CisJaW50IHJldDsKKworCWlmIChJU19FUlJfT1JfTlVMTChzdykpCisJCXJldHVybiAwOwor CisJbXV0ZXhfbG9jaygmc3ctPmxvY2spOworCisJcmV0ID0gc3ctPnNldChzdy0+ZGV2LnBhcmVu dCwgcm9sZSk7CisJaWYgKCFyZXQpCisJCXN3LT5yb2xlID0gcm9sZTsKKworCW11dGV4X3VubG9j aygmc3ctPmxvY2spOworCisJcmV0dXJuIHJldDsKK30KK0VYUE9SVF9TWU1CT0xfR1BMKHVzYl9y b2xlX3N3aXRjaF9zZXRfcm9sZSk7CisKKy8qKgorICogdXNiX3JvbGVfc3dpdGNoX2dldF9yb2xl IC0gR2V0IHRoZSBVU0Igcm9sZSBmb3IgYSBzd2l0Y2gKKyAqIEBzdzogVVNCIHJvbGUgc3dpdGNo CisgKgorICogRGVwZW5kaW5nIG9uIHRoZSByb2xlLXN3aXRjaC1kcml2ZXIgdGhpcyBmdW5jdGlv biByZXR1cm5zIGVpdGhlciBhIGNhY2hlZAorICogdmFsdWUgb2YgdGhlIGxhc3Qgc2V0IHJvbGUs IG9yIHJlYWRzIGJhY2sgdGhlIGFjdHVhbCB2YWx1ZSBmcm9tIHRoZSBoYXJkd2FyZS4KKyAqLwor ZW51bSB1c2Jfcm9sZSB1c2Jfcm9sZV9zd2l0Y2hfZ2V0X3JvbGUoc3RydWN0IHVzYl9yb2xlX3N3 aXRjaCAqc3cpCit7CisJZW51bSB1c2Jfcm9sZSByb2xlOworCisJaWYgKElTX0VSUl9PUl9OVUxM KHN3KSkKKwkJcmV0dXJuIFVTQl9ST0xFX05PTkU7CisKKwltdXRleF9sb2NrKCZzdy0+bG9jayk7 CisKKwlpZiAoc3ctPmdldCkKKwkJcm9sZSA9IHN3LT5nZXQoc3ctPmRldi5wYXJlbnQpOworCWVs c2UKKwkJcm9sZSA9IHN3LT5yb2xlOworCisJbXV0ZXhfdW5sb2NrKCZzdy0+bG9jayk7CisKKwly ZXR1cm4gcm9sZTsKK30KK0VYUE9SVF9TWU1CT0xfR1BMKHVzYl9yb2xlX3N3aXRjaF9nZXRfcm9s ZSk7CisKK3N0YXRpYyBpbnQgX19zd2l0Y2hfbWF0Y2goc3RydWN0IGRldmljZSAqZGV2LCBjb25z dCB2b2lkICpuYW1lKQoreworCXJldHVybiAhc3RyY21wKChjb25zdCBjaGFyICopbmFtZSwgZGV2 X25hbWUoZGV2KSk7Cit9CisKK3N0YXRpYyB2b2lkICp1c2Jfcm9sZV9zd2l0Y2hfbWF0Y2goc3Ry dWN0IGRldmljZV9jb25uZWN0aW9uICpjb24sIGludCBlcCwKKwkJCQkgICB2b2lkICpkYXRhKQor eworCXN0cnVjdCBkZXZpY2UgKmRldjsKKworCWRldiA9IGNsYXNzX2ZpbmRfZGV2aWNlKHJvbGVf Y2xhc3MsIE5VTEwsIGNvbi0+ZW5kcG9pbnRbZXBdLAorCQkJCV9fc3dpdGNoX21hdGNoKTsKKwor CXJldHVybiBkZXYgPyB0b19yb2xlX3N3aXRjaChkZXYpIDogRVJSX1BUUigtRVBST0JFX0RFRkVS KTsKK30KKworLyoqCisgKiB1c2Jfcm9sZV9zd2l0Y2hfZ2V0IC0gRmluZCBVU0Igcm9sZSBzd2l0 Y2ggbGlua2VkIHdpdGggdGhlIGNhbGxlcgorICogQGRldjogVGhlIGNhbGxlciBkZXZpY2UKKyAq CisgKiBGaW5kcyBhbmQgcmV0dXJucyByb2xlIHN3aXRjaCBsaW5rZWQgd2l0aCBAZGV2LiBUaGUg cmVmZXJlbmNlIGNvdW50IGZvciB0aGUKKyAqIGZvdW5kIHN3aXRjaCBpcyBpbmNyZW1lbnRlZC4K KyAqLworc3RydWN0IHVzYl9yb2xlX3N3aXRjaCAqdXNiX3JvbGVfc3dpdGNoX2dldChzdHJ1Y3Qg ZGV2aWNlICpkZXYpCit7CisJcmV0dXJuIGRldmljZV9jb25uZWN0aW9uX2ZpbmRfbWF0Y2goZGV2 LCAidXNiLXJvbGUtc3dpdGNoIiwgTlVMTCwKKwkJCQkJICAgIHVzYl9yb2xlX3N3aXRjaF9tYXRj aCk7Cit9CitFWFBPUlRfU1lNQk9MX0dQTCh1c2Jfcm9sZV9zd2l0Y2hfZ2V0KTsKKworLyoqCisg KiB1c2Jfcm9sZV9zd2l0Y2hfcHV0IC0gUmVsZWFzZSBoYW5kbGUgdG8gYSBzd2l0Y2gKKyAqIEBz dzogVVNCIFJvbGUgU3dpdGNoCisgKgorICogRGVjcmVtZW50IHJlZmVyZW5jZSBjb3VudCBmb3Ig QHN3LgorICovCit2b2lkIHVzYl9yb2xlX3N3aXRjaF9wdXQoc3RydWN0IHVzYl9yb2xlX3N3aXRj aCAqc3cpCit7CisJaWYgKCFJU19FUlJfT1JfTlVMTChzdykpCisJCXB1dF9kZXZpY2UoJnN3LT5k ZXYpOworfQorRVhQT1JUX1NZTUJPTF9HUEwodXNiX3JvbGVfc3dpdGNoX3B1dCk7CisKK3N0YXRp YyB1bW9kZV90Cit1c2Jfcm9sZV9zd2l0Y2hfaXNfdmlzaWJsZShzdHJ1Y3Qga29iamVjdCAqa29i aiwgc3RydWN0IGF0dHJpYnV0ZSAqYXR0ciwgaW50IG4pCit7CisJc3RydWN0IGRldmljZSAqZGV2 ID0gY29udGFpbmVyX29mKGtvYmosIHR5cGVvZigqZGV2KSwga29iaik7CisJc3RydWN0IHVzYl9y b2xlX3N3aXRjaCAqc3cgPSB0b19yb2xlX3N3aXRjaChkZXYpOworCisJaWYgKHN3LT5hbGxvd191 c2Vyc3BhY2VfY29udHJvbCkKKwkJcmV0dXJuIGF0dHItPm1vZGU7CisKKwlyZXR1cm4gMDsKK30K Kworc3RhdGljIGNvbnN0IGNoYXIgKiBjb25zdCB1c2Jfcm9sZXNbXSA9IHsKKwlbVVNCX1JPTEVf Tk9ORV0JCT0gIm5vbmUiLAorCVtVU0JfUk9MRV9IT1NUXQkJPSAiaG9zdCIsCisJW1VTQl9ST0xF X0RFVklDRV0JPSAiZGV2aWNlIiwKK307CisKK3N0YXRpYyBzc2l6ZV90Cityb2xlX3Nob3coc3Ry dWN0IGRldmljZSAqZGV2LCBzdHJ1Y3QgZGV2aWNlX2F0dHJpYnV0ZSAqYXR0ciwgY2hhciAqYnVm KQoreworCXN0cnVjdCB1c2Jfcm9sZV9zd2l0Y2ggKnN3ID0gdG9fcm9sZV9zd2l0Y2goZGV2KTsK KwllbnVtIHVzYl9yb2xlIHJvbGUgPSB1c2Jfcm9sZV9zd2l0Y2hfZ2V0X3JvbGUoc3cpOworCisJ cmV0dXJuIHNwcmludGYoYnVmLCAiJXNcbiIsIHVzYl9yb2xlc1tyb2xlXSk7Cit9CisKK3N0YXRp YyBzc2l6ZV90IHJvbGVfc3RvcmUoc3RydWN0IGRldmljZSAqZGV2LCBzdHJ1Y3QgZGV2aWNlX2F0 dHJpYnV0ZSAqYXR0ciwKKwkJCSAgY29uc3QgY2hhciAqYnVmLCBzaXplX3Qgc2l6ZSkKK3sKKwlz dHJ1Y3QgdXNiX3JvbGVfc3dpdGNoICpzdyA9IHRvX3JvbGVfc3dpdGNoKGRldik7CisJaW50IHJl dDsKKworCXJldCA9IHN5c2ZzX21hdGNoX3N0cmluZyh1c2Jfcm9sZXMsIGJ1Zik7CisJaWYgKHJl dCA8IDApIHsKKwkJYm9vbCByZXM7CisKKwkJLyogRXh0cmEgY2hlY2sgaWYgdGhlIHVzZXIgd2Fu dHMgdG8gZGlzYWJsZSB0aGUgc3dpdGNoICovCisJCXJldCA9IGtzdHJ0b2Jvb2woYnVmLCAmcmVz KTsKKwkJaWYgKHJldCB8fCByZXMpCisJCQlyZXR1cm4gLUVJTlZBTDsKKwl9CisKKwlyZXQgPSB1 c2Jfcm9sZV9zd2l0Y2hfc2V0X3JvbGUoc3csIHJldCk7CisJaWYgKHJldCkKKwkJcmV0dXJuIHJl dDsKKworCXJldHVybiBzaXplOworfQorc3RhdGljIERFVklDRV9BVFRSX1JXKHJvbGUpOworCitz dGF0aWMgc3RydWN0IGF0dHJpYnV0ZSAqdXNiX3JvbGVfc3dpdGNoX2F0dHJzW10gPSB7CisJJmRl dl9hdHRyX3JvbGUuYXR0ciwKKwlOVUxMLAorfTsKKworc3RhdGljIGNvbnN0IHN0cnVjdCBhdHRy aWJ1dGVfZ3JvdXAgdXNiX3JvbGVfc3dpdGNoX2dyb3VwID0geworCS5pc192aXNpYmxlID0gdXNi X3JvbGVfc3dpdGNoX2lzX3Zpc2libGUsCisJLmF0dHJzID0gdXNiX3JvbGVfc3dpdGNoX2F0dHJz LAorfTsKKworc3RhdGljIGNvbnN0IHN0cnVjdCBhdHRyaWJ1dGVfZ3JvdXAgKnVzYl9yb2xlX3N3 aXRjaF9ncm91cHNbXSA9IHsKKwkmdXNiX3JvbGVfc3dpdGNoX2dyb3VwLAorCU5VTEwsCit9Owor CitzdGF0aWMgaW50Cit1c2Jfcm9sZV9zd2l0Y2hfdWV2ZW50KHN0cnVjdCBkZXZpY2UgKmRldiwg c3RydWN0IGtvYmpfdWV2ZW50X2VudiAqZW52KQoreworCWludCByZXQ7CisKKwlyZXQgPSBhZGRf dWV2ZW50X3ZhcihlbnYsICJVU0JfUk9MRV9TV0lUQ0g9JXMiLCBkZXZfbmFtZShkZXYpKTsKKwlp ZiAocmV0KQorCQlkZXZfZXJyKGRldiwgImZhaWxlZCB0byBhZGQgdWV2ZW50IFVTQl9ST0xFX1NX SVRDSFxuIik7CisKKwlyZXR1cm4gcmV0OworfQorCitzdGF0aWMgdm9pZCB1c2Jfcm9sZV9zd2l0 Y2hfcmVsZWFzZShzdHJ1Y3QgZGV2aWNlICpkZXYpCit7CisJc3RydWN0IHVzYl9yb2xlX3N3aXRj aCAqc3cgPSB0b19yb2xlX3N3aXRjaChkZXYpOworCisJa2ZyZWUoc3cpOworfQorCitzdGF0aWMg Y29uc3Qgc3RydWN0IGRldmljZV90eXBlIHVzYl9yb2xlX2Rldl90eXBlID0geworCS5uYW1lID0g InVzYl9yb2xlX3N3aXRjaCIsCisJLmdyb3VwcyA9IHVzYl9yb2xlX3N3aXRjaF9ncm91cHMsCisJ LnVldmVudCA9IHVzYl9yb2xlX3N3aXRjaF91ZXZlbnQsCisJLnJlbGVhc2UgPSB1c2Jfcm9sZV9z d2l0Y2hfcmVsZWFzZSwKK307CisKKy8qKgorICogdXNiX3JvbGVfc3dpdGNoX3JlZ2lzdGVyIC0g UmVnaXN0ZXIgVVNCIFJvbGUgU3dpdGNoCisgKiBAcGFyZW50OiBQYXJlbnQgZGV2aWNlIGZvciB0 aGUgc3dpdGNoCisgKiBAZGVzYzogRGVzY3JpcHRpb24gb2YgdGhlIHN3aXRjaAorICoKKyAqIFVT QiBSb2xlIFN3aXRjaCBpcyBhIGRldmljZSBjYXBhYmxlIG9yIGNob29zaW5nIHRoZSByb2xlIGZv ciBVU0IgY29ubmVjdG9yLgorICogT24gcGxhdGZvcm1zIHdoZXJlIHRoZSBVU0IgY29udHJvbGxl ciBpcyBkdWFsLXJvbGUgY2FwYWJsZSwgdGhlIGNvbnRyb2xsZXIKKyAqIGRyaXZlciB3aWxsIG5l ZWQgdG8gcmVnaXN0ZXIgdGhlIHN3aXRjaC4gT24gcGxhdGZvcm1zIHdoZXJlIHRoZSBVU0IgaG9z dCBhbmQKKyAqIFVTQiBkZXZpY2UgY29udHJvbGxlcnMgYmVoaW5kIHRoZSBjb25uZWN0b3IgYXJl IHNlcGFyYXRlLCB0aGVyZSB3aWxsIGJlIGEKKyAqIG11eCwgYW5kIHRoZSBkcml2ZXIgZm9yIHRo YXQgbXV4IHdpbGwgbmVlZCB0byByZWdpc3RlciB0aGUgc3dpdGNoLgorICoKKyAqIFJldHVybnMg aGFuZGxlIHRvIGEgbmV3IHJvbGUgc3dpdGNoIG9yIEVSUl9QVFIuIFRoZSBjb250ZW50IG9mIEBk ZXNjIGlzCisgKiBjb3BpZWQuCisgKi8KK3N0cnVjdCB1c2Jfcm9sZV9zd2l0Y2ggKgordXNiX3Jv bGVfc3dpdGNoX3JlZ2lzdGVyKHN0cnVjdCBkZXZpY2UgKnBhcmVudCwKKwkJCSBjb25zdCBzdHJ1 Y3QgdXNiX3JvbGVfc3dpdGNoX2Rlc2MgKmRlc2MpCit7CisJc3RydWN0IHVzYl9yb2xlX3N3aXRj aCAqc3c7CisJaW50IHJldDsKKworCWlmICghZGVzYyB8fCAhZGVzYy0+c2V0KQorCQlyZXR1cm4g RVJSX1BUUigtRUlOVkFMKTsKKworCXN3ID0ga3phbGxvYyhzaXplb2YoKnN3KSwgR0ZQX0tFUk5F TCk7CisJaWYgKCFzdykKKwkJcmV0dXJuIEVSUl9QVFIoLUVOT01FTSk7CisKKwltdXRleF9pbml0 KCZzdy0+bG9jayk7CisKKwlzdy0+YWxsb3dfdXNlcnNwYWNlX2NvbnRyb2wgPSBkZXNjLT5hbGxv d191c2Vyc3BhY2VfY29udHJvbDsKKwlzdy0+dXNiMl9wb3J0ID0gZGVzYy0+dXNiMl9wb3J0Owor CXN3LT51c2IzX3BvcnQgPSBkZXNjLT51c2IzX3BvcnQ7CisJc3ctPnVkYyA9IGRlc2MtPnVkYzsK Kwlzdy0+c2V0ID0gZGVzYy0+c2V0OworCXN3LT5nZXQgPSBkZXNjLT5nZXQ7CisKKwlzdy0+ZGV2 LnBhcmVudCA9IHBhcmVudDsKKwlzdy0+ZGV2LmNsYXNzID0gcm9sZV9jbGFzczsKKwlzdy0+ZGV2 LnR5cGUgPSAmdXNiX3JvbGVfZGV2X3R5cGU7CisJZGV2X3NldF9uYW1lKCZzdy0+ZGV2LCAiJXMt cm9sZS1zd2l0Y2giLCBkZXZfbmFtZShwYXJlbnQpKTsKKworCXJldCA9IGRldmljZV9yZWdpc3Rl cigmc3ctPmRldik7CisJaWYgKHJldCkgeworCQlwdXRfZGV2aWNlKCZzdy0+ZGV2KTsKKwkJcmV0 dXJuIEVSUl9QVFIocmV0KTsKKwl9CisKKwkvKiBUT0RPOiBTeW1saW5rcyBmb3IgdGhlIGhvc3Qg cG9ydCBhbmQgdGhlIGRldmljZSBjb250cm9sbGVyLiAqLworCisJcmV0dXJuIHN3OworfQorRVhQ T1JUX1NZTUJPTF9HUEwodXNiX3JvbGVfc3dpdGNoX3JlZ2lzdGVyKTsKKworLyoqCisgKiB1c2Jf cm9sZV9zd2l0Y2hfdW5yZWdpc3RlciAtIFVucmVnc2l0ZXIgVVNCIFJvbGUgU3dpdGNoCisgKiBA c3c6IFVTQiBSb2xlIFN3aXRjaAorICoKKyAqIFVucmVnaXN0ZXIgc3dpdGNoIHRoYXQgd2FzIHJl Z2lzdGVyZWQgd2l0aCB1c2Jfcm9sZV9zd2l0Y2hfcmVnaXN0ZXIoKS4KKyAqLwordm9pZCB1c2Jf cm9sZV9zd2l0Y2hfdW5yZWdpc3RlcihzdHJ1Y3QgdXNiX3JvbGVfc3dpdGNoICpzdykKK3sKKwlp ZiAoIUlTX0VSUl9PUl9OVUxMKHN3KSkKKwkJZGV2aWNlX3VucmVnaXN0ZXIoJnN3LT5kZXYpOwor fQorRVhQT1JUX1NZTUJPTF9HUEwodXNiX3JvbGVfc3dpdGNoX3VucmVnaXN0ZXIpOworCitzdGF0 aWMgaW50IF9faW5pdCB1c2Jfcm9sZXNfaW5pdCh2b2lkKQoreworCXJvbGVfY2xhc3MgPSBjbGFz c19jcmVhdGUoVEhJU19NT0RVTEUsICJ1c2Jfcm9sZSIpOworCXJldHVybiBQVFJfRVJSX09SX1pF Uk8ocm9sZV9jbGFzcyk7Cit9CitzdWJzeXNfaW5pdGNhbGwodXNiX3JvbGVzX2luaXQpOworCitz dGF0aWMgdm9pZCBfX2V4aXQgdXNiX3JvbGVzX2V4aXQodm9pZCkKK3sKKwljbGFzc19kZXN0cm95 KHJvbGVfY2xhc3MpOworfQorbW9kdWxlX2V4aXQodXNiX3JvbGVzX2V4aXQpOworCitNT0RVTEVf QVVUSE9SKCJIZWlra2kgS3JvZ2VydXMgPGhlaWtraS5rcm9nZXJ1c0BsaW51eC5pbnRlbC5jb20+ Iik7CitNT0RVTEVfQVVUSE9SKCJIYW5zIGRlIEdvZWRlIDxoZGVnb2VkZUByZWRoYXQuY29tPiIp OworTU9EVUxFX0xJQ0VOU0UoIkdQTCB2MiIpOworTU9EVUxFX0RFU0NSSVBUSU9OKCJVU0IgUm9s ZSBDbGFzcyIpOwpkaWZmIC0tZ2l0IGEvaW5jbHVkZS9saW51eC91c2Ivcm9sZS5oIGIvaW5jbHVk ZS9saW51eC91c2Ivcm9sZS5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAwMDAw MC4uZWRjNTFiZTRhNzdjCi0tLSAvZGV2L251bGwKKysrIGIvaW5jbHVkZS9saW51eC91c2Ivcm9s ZS5oCkBAIC0wLDAgKzEsNTMgQEAKKy8vIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBHUEwtMi4w CisKKyNpZm5kZWYgX19MSU5VWF9VU0JfUk9MRV9ICisjZGVmaW5lIF9fTElOVVhfVVNCX1JPTEVf SAorCisjaW5jbHVkZSA8bGludXgvZGV2aWNlLmg+CisKK3N0cnVjdCB1c2Jfcm9sZV9zd2l0Y2g7 CisKK2VudW0gdXNiX3JvbGUgeworCVVTQl9ST0xFX05PTkUsCisJVVNCX1JPTEVfSE9TVCwKKwlV U0JfUk9MRV9ERVZJQ0UsCit9OworCit0eXBlZGVmIGludCAoKnVzYl9yb2xlX3N3aXRjaF9zZXRf dCkoc3RydWN0IGRldmljZSAqZGV2LCBlbnVtIHVzYl9yb2xlIHJvbGUpOwordHlwZWRlZiBlbnVt IHVzYl9yb2xlICgqdXNiX3JvbGVfc3dpdGNoX2dldF90KShzdHJ1Y3QgZGV2aWNlICpkZXYpOwor CisvKioKKyAqIHN0cnVjdCB1c2Jfcm9sZV9zd2l0Y2hfZGVzYyAtIFVTQiBSb2xlIFN3aXRjaCBE ZXNjcmlwdG9yCisgKiBAdXNiMl9wb3J0OiBPcHRpb25hbCByZWZlcmVuY2UgdG8gdGhlIGhvc3Qg Y29udHJvbGxlciBwb3J0IGRldmljZSAoVVNCMikKKyAqIEB1c2IzX3BvcnQ6IE9wdGlvbmFsIHJl ZmVyZW5jZSB0byB0aGUgaG9zdCBjb250cm9sbGVyIHBvcnQgZGV2aWNlIChVU0IzKQorICogQHVk YzogT3B0aW9uYWwgcmVmZXJlbmNlIHRvIHRoZSBwZXJpcGhlcmFsIGNvbnRyb2xsZXIgZGV2aWNl CisgKiBAc2V0OiBDYWxsYmFjayBmb3Igc2V0dGluZyB0aGUgcm9sZQorICogQGdldDogQ2FsbGJh Y2sgZm9yIGdldHRpbmcgdGhlIHJvbGUgKG9wdGlvbmFsKQorICogQGFsbG93X3VzZXJzcGFjZV9j b250cm9sOiBJZiB0cnVlIHVzZXJzcGFjZSBtYXkgY2hhbmdlIHRoZSByb2xlIHRocm91Z2ggc3lz ZnMKKyAqCisgKiBAdXNiMl9wb3J0IGFuZCBAdXNiM19wb3J0IHdpbGwgcG9pbnQgdG8gdGhlIFVT QiBob3N0IHBvcnQgYW5kIEB1ZGMgdG8gdGhlIFVTQgorICogZGV2aWNlIGNvbnRyb2xsZXIgYmVo aW5kIHRoZSBVU0IgY29ubmVjdG9yIHdpdGggdGhlIHJvbGUgc3dpdGNoLiBJZgorICogQHVzYjJf cG9ydCwgQHVzYjNfcG9ydCBhbmQgQHVkYyBhcmUgaW5jbHVkZWQgaW4gdGhlIGRlc2NyaXB0aW9u LCB0aGUKKyAqIHJlZmVyZW5jZSBjb3VudCBmb3IgdGhlbSBzaG91bGQgYmUgaW5jcmVtZW50ZWQg YnkgdGhlIGNhbGxlciBvZgorICogdXNiX3JvbGVfc3dpdGNoX3JlZ2lzdGVyKCkgYmVmb3JlIHJl Z2lzdGVyaW5nIHRoZSBzd2l0Y2guCisgKi8KK3N0cnVjdCB1c2Jfcm9sZV9zd2l0Y2hfZGVzYyB7 CisJc3RydWN0IGRldmljZSAqdXNiMl9wb3J0OworCXN0cnVjdCBkZXZpY2UgKnVzYjNfcG9ydDsK KwlzdHJ1Y3QgZGV2aWNlICp1ZGM7CisJdXNiX3JvbGVfc3dpdGNoX3NldF90IHNldDsKKwl1c2Jf cm9sZV9zd2l0Y2hfZ2V0X3QgZ2V0OworCWJvb2wgYWxsb3dfdXNlcnNwYWNlX2NvbnRyb2w7Cit9 OworCitpbnQgdXNiX3JvbGVfc3dpdGNoX3NldF9yb2xlKHN0cnVjdCB1c2Jfcm9sZV9zd2l0Y2gg KnN3LCBlbnVtIHVzYl9yb2xlIHJvbGUpOworZW51bSB1c2Jfcm9sZSB1c2Jfcm9sZV9zd2l0Y2hf Z2V0X3JvbGUoc3RydWN0IHVzYl9yb2xlX3N3aXRjaCAqc3cpOworc3RydWN0IHVzYl9yb2xlX3N3 aXRjaCAqdXNiX3JvbGVfc3dpdGNoX2dldChzdHJ1Y3QgZGV2aWNlICpkZXYpOwordm9pZCB1c2Jf cm9sZV9zd2l0Y2hfcHV0KHN0cnVjdCB1c2Jfcm9sZV9zd2l0Y2ggKnN3KTsKKworc3RydWN0IHVz Yl9yb2xlX3N3aXRjaCAqCit1c2Jfcm9sZV9zd2l0Y2hfcmVnaXN0ZXIoc3RydWN0IGRldmljZSAq cGFyZW50LAorCQkJIGNvbnN0IHN0cnVjdCB1c2Jfcm9sZV9zd2l0Y2hfZGVzYyAqZGVzYyk7Cit2 b2lkIHVzYl9yb2xlX3N3aXRjaF91bnJlZ2lzdGVyKHN0cnVjdCB1c2Jfcm9sZV9zd2l0Y2ggKnN3 KTsKKworI2VuZGlmIC8qIF9fTElOVVhfVVNCX1JPTEVfSCAqLwo=