From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-1.1 required=3.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI,SPF_PASS autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id D692DC10F13 for ; Fri, 12 Apr 2019 00:55:48 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 985E3218A6 for ; Fri, 12 Apr 2019 00:55:48 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=linaro.org header.i=@linaro.org header.b="TsjlWIJv" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726739AbfDLAzr (ORCPT ); Thu, 11 Apr 2019 20:55:47 -0400 Received: from mail-wr1-f67.google.com ([209.85.221.67]:45981 "EHLO mail-wr1-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726661AbfDLAzr (ORCPT ); Thu, 11 Apr 2019 20:55:47 -0400 Received: by mail-wr1-f67.google.com with SMTP id s15so9637616wra.12 for ; Thu, 11 Apr 2019 17:55:45 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc; bh=9fx65PGs+hcTLW3v5Oxc17IQCXrFa7XQEHDSKo+zIjg=; b=TsjlWIJv+DW3+CPH6/AwmnLDzKKYSz2qaedQ4z4004P48t2r8voIdztozBT9E386a/ 5rc3Vr9fAhascrbg5ePHArL72NqgpsSWIBir2VCUou4q1kWw708b0EFVvXVgCbNFc1/9 DmvaU/A42NIyQW2VCV9GCWxI9OQUM5SfS/OH+OfEr9XH+eLbj8T7VriJ9yCdv7leTUe8 8uJTdVstjDmG7dXzwAVuzmdUpd9qFapAszN+dEMcWPEoodwUKvqAJPU/CJPpSns+1waA GfM6RDT5ZVa5VktjBTBjgHx9dpzo/J4ddOW5N3pGHU0LKriUrmFlTfZe1I7eUxtYe6SC Ve0Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=9fx65PGs+hcTLW3v5Oxc17IQCXrFa7XQEHDSKo+zIjg=; b=oVeasZZdYUzHxECaVGF9DdzJeWO/y+Up823R5xXuXUDfkn3deqUvBin6gvXbGwjG3V 2jMQhX/4fFpit4rzaK6dBzHJzbATav+dsahqJQ3zW+k2wxYRMQaD32Fg6U3OpI10wRnw sELT4rZCb8Qh84YPxQyfXm6LRtg68nKkv3DgAzSI6dBGtwdYD59wsB9bisSwOn8Iw/MA 7LgfG1BqsctyinSW5R7sfOZRtqBqEtM9sCi60+bHi+oI9Vv59lMh9VRh48BojuAtBiF8 Q1mm9dMJJXLIyEajF1Ukh8HkJRAfV/i9su4S1TvbYsR5Xyu6vcqwQdBxNk6cueKHdHsI KDiw== X-Gm-Message-State: APjAAAVhMptsmjviZOXHt56P8F9WuR2DyDc7xD22Ksb6uHe0vodMTyWO WfFYIHr0p4rZ7/2kIZ1IloC9eD9JWZepGj60DnfNSg== X-Google-Smtp-Source: APXvYqyTVKbY+rzszRq9p2dM0geGu5ZteEkp4ydnwlItURigbQOQ7cDwZKcWU7KZtCtyaCbRXo2CYivy92hIHs6jiJY= X-Received: by 2002:adf:b612:: with SMTP id f18mr22392914wre.236.1555030544590; Thu, 11 Apr 2019 17:55:44 -0700 (PDT) MIME-Version: 1.0 References: <20190329041409.70138-1-chenyu56@huawei.com> <20190329041409.70138-12-chenyu56@huawei.com> In-Reply-To: <20190329041409.70138-12-chenyu56@huawei.com> From: John Stultz Date: Thu, 11 Apr 2019 17:55:32 -0700 Message-ID: Subject: Re: [PATCH v5 11/13] hikey960: Support usb functionality of Hikey960 To: Yu Chen Cc: Linux USB List , "open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS" , lkml , Zhuangluan Su , Kongfei , "Liuyu (R)" , wanghu17@hisilicon.com, butao , chenyao11@huawei.com, fangshengzhou@hisilicon.com, Li Pengcheng , songxiaowei@hisilicon.com, YiPing Xu , xuyoujun4@huawei.com, Yudongbin , Zang Leigang , Chunfeng Yun , Andy Shevchenko , Arnd Bergmann , Greg Kroah-Hartman , Binghui Wang , Heikki Krogerus Content-Type: text/plain; charset="UTF-8" Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Thu, Mar 28, 2019 at 9:14 PM Yu Chen wrote: > > This driver handles usb hub power on and typeC port event of HiKey960 board: > 1)DP&DM switching between usb hub and typeC port base on typeC port > state > 2)Control power of usb hub on Hikey960 > 3)Control vbus of typeC port Hey Yu Chen! Wanted to say thanks again for sending these patches out so persistently. I did catch an issue with this driver that I wanted to let you know about. > +static int hisi_hikey_role_switch(struct notifier_block *nb, > + unsigned long state, void *data) > +{ > + struct hisi_hikey_usb *hisi_hikey_usb; > + > + hisi_hikey_usb = container_of(nb, struct hisi_hikey_usb, nb); > + > + switch (state) { > + case USB_ROLE_NONE: > + usb_typec_power_ctrl(hisi_hikey_usb, TYPEC_VBUS_POWER_OFF); > + usb_switch_ctrl(hisi_hikey_usb, USB_SWITCH_TO_HUB); > + hub_power_ctrl(hisi_hikey_usb, HUB_VBUS_POWER_ON); > + break; > + case USB_ROLE_HOST: > + usb_switch_ctrl(hisi_hikey_usb, USB_SWITCH_TO_TYPEC); > + usb_typec_power_ctrl(hisi_hikey_usb, TYPEC_VBUS_POWER_ON); > + break; > + case USB_ROLE_DEVICE: > + hub_power_ctrl(hisi_hikey_usb, HUB_VBUS_POWER_OFF); > + usb_typec_power_ctrl(hisi_hikey_usb, TYPEC_VBUS_POWER_OFF); > + usb_switch_ctrl(hisi_hikey_usb, USB_SWITCH_TO_TYPEC); > + break; > + default: > + break; > + } > + > + return 0; > +} > + > +static int hisi_hikey_usb_probe(struct platform_device *pdev) > +{ > + struct device *dev = &pdev->dev; > + struct hisi_hikey_usb *hisi_hikey_usb; > + int ret; > + > + hisi_hikey_usb = devm_kzalloc(dev, sizeof(*hisi_hikey_usb), GFP_KERNEL); > + if (!hisi_hikey_usb) > + return -ENOMEM; > + > + hisi_hikey_usb->nb.notifier_call = hisi_hikey_role_switch; > + > + hisi_hikey_usb->typec_vbus = devm_gpiod_get(dev, "typec-vbus", > + GPIOD_OUT_LOW); > + if (IS_ERR(hisi_hikey_usb->typec_vbus)) > + return PTR_ERR(hisi_hikey_usb->typec_vbus); > + > + hisi_hikey_usb->otg_switch = devm_gpiod_get(dev, "otg-switch", > + GPIOD_OUT_HIGH); > + if (IS_ERR(hisi_hikey_usb->otg_switch)) > + return PTR_ERR(hisi_hikey_usb->otg_switch); > + > + /* hub-vdd33-en is optional */ > + hisi_hikey_usb->hub_vbus = devm_gpiod_get_optional(dev, "hub-vdd33-en", > + GPIOD_OUT_HIGH); > + if (IS_ERR(hisi_hikey_usb->hub_vbus)) > + return PTR_ERR(hisi_hikey_usb->hub_vbus); > + > + hisi_hikey_usb->role_sw = usb_role_switch_get(dev); > + if (!hisi_hikey_usb->role_sw) > + return -EPROBE_DEFER; > + if (IS_ERR(hisi_hikey_usb->role_sw)) > + return PTR_ERR(hisi_hikey_usb->role_sw); > + > + ret = usb_role_switch_register_notifier(hisi_hikey_usb->role_sw, > + &hisi_hikey_usb->nb); > + if (ret) { > + usb_role_switch_put(hisi_hikey_usb->role_sw); > + return ret; > + } > + > + platform_set_drvdata(pdev, hisi_hikey_usb); > + > + return 0; > +} The issue I found is that if due to module load order or other randomization in bootup timing, this driver loads much later then the other USB infrastructure, the usb_role_switch notifier that is registered may be registered after any state initialization or change has occurred that would trigger the notifier callbacks. This means initially this driver could be out of sync with the core usb_role_switch state. I've tried doing something like the following on probe to force the initialization: cur_role = usb_role_switch_get_role(hisi_hikey_usb->role_sw); usb_role_switch_set_role(hisi_hikey_usb->role_sw, cur_role); But this is racy, as a state change can happen in between the call to get_role and set_role, which would end up overwriting the proper state. I suspect a proper fix needs to happen in the usb_role_switch_register_notifier(), where the callback gets called with the initial state while holding the lock to avoid races. I'll comment more in that patch. thanks -john From mboxrd@z Thu Jan 1 00:00:00 1970 From: John Stultz Subject: Re: [PATCH v5 11/13] hikey960: Support usb functionality of Hikey960 Date: Thu, 11 Apr 2019 17:55:32 -0700 Message-ID: References: <20190329041409.70138-1-chenyu56@huawei.com> <20190329041409.70138-12-chenyu56@huawei.com> Mime-Version: 1.0 Content-Type: text/plain; charset="UTF-8" Return-path: In-Reply-To: <20190329041409.70138-12-chenyu56@huawei.com> Sender: linux-kernel-owner@vger.kernel.org To: Yu Chen Cc: Linux USB List , "open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS" , lkml , Zhuangluan Su , Kongfei , "Liuyu (R)" , wanghu17@hisilicon.com, butao , chenyao11@huawei.com, fangshengzhou@hisilicon.com, Li Pengcheng , songxiaowei@hisilicon.com, YiPing Xu , xuyoujun4@huawei.com, Yudongbin , Zang Leigang , Chunfeng Yun , Andy Shevchenko , Arnd Bergmann , Greg Kroah-Hartman , Bingh List-Id: devicetree@vger.kernel.org On Thu, Mar 28, 2019 at 9:14 PM Yu Chen wrote: > > This driver handles usb hub power on and typeC port event of HiKey960 board: > 1)DP&DM switching between usb hub and typeC port base on typeC port > state > 2)Control power of usb hub on Hikey960 > 3)Control vbus of typeC port Hey Yu Chen! Wanted to say thanks again for sending these patches out so persistently. I did catch an issue with this driver that I wanted to let you know about. > +static int hisi_hikey_role_switch(struct notifier_block *nb, > + unsigned long state, void *data) > +{ > + struct hisi_hikey_usb *hisi_hikey_usb; > + > + hisi_hikey_usb = container_of(nb, struct hisi_hikey_usb, nb); > + > + switch (state) { > + case USB_ROLE_NONE: > + usb_typec_power_ctrl(hisi_hikey_usb, TYPEC_VBUS_POWER_OFF); > + usb_switch_ctrl(hisi_hikey_usb, USB_SWITCH_TO_HUB); > + hub_power_ctrl(hisi_hikey_usb, HUB_VBUS_POWER_ON); > + break; > + case USB_ROLE_HOST: > + usb_switch_ctrl(hisi_hikey_usb, USB_SWITCH_TO_TYPEC); > + usb_typec_power_ctrl(hisi_hikey_usb, TYPEC_VBUS_POWER_ON); > + break; > + case USB_ROLE_DEVICE: > + hub_power_ctrl(hisi_hikey_usb, HUB_VBUS_POWER_OFF); > + usb_typec_power_ctrl(hisi_hikey_usb, TYPEC_VBUS_POWER_OFF); > + usb_switch_ctrl(hisi_hikey_usb, USB_SWITCH_TO_TYPEC); > + break; > + default: > + break; > + } > + > + return 0; > +} > + > +static int hisi_hikey_usb_probe(struct platform_device *pdev) > +{ > + struct device *dev = &pdev->dev; > + struct hisi_hikey_usb *hisi_hikey_usb; > + int ret; > + > + hisi_hikey_usb = devm_kzalloc(dev, sizeof(*hisi_hikey_usb), GFP_KERNEL); > + if (!hisi_hikey_usb) > + return -ENOMEM; > + > + hisi_hikey_usb->nb.notifier_call = hisi_hikey_role_switch; > + > + hisi_hikey_usb->typec_vbus = devm_gpiod_get(dev, "typec-vbus", > + GPIOD_OUT_LOW); > + if (IS_ERR(hisi_hikey_usb->typec_vbus)) > + return PTR_ERR(hisi_hikey_usb->typec_vbus); > + > + hisi_hikey_usb->otg_switch = devm_gpiod_get(dev, "otg-switch", > + GPIOD_OUT_HIGH); > + if (IS_ERR(hisi_hikey_usb->otg_switch)) > + return PTR_ERR(hisi_hikey_usb->otg_switch); > + > + /* hub-vdd33-en is optional */ > + hisi_hikey_usb->hub_vbus = devm_gpiod_get_optional(dev, "hub-vdd33-en", > + GPIOD_OUT_HIGH); > + if (IS_ERR(hisi_hikey_usb->hub_vbus)) > + return PTR_ERR(hisi_hikey_usb->hub_vbus); > + > + hisi_hikey_usb->role_sw = usb_role_switch_get(dev); > + if (!hisi_hikey_usb->role_sw) > + return -EPROBE_DEFER; > + if (IS_ERR(hisi_hikey_usb->role_sw)) > + return PTR_ERR(hisi_hikey_usb->role_sw); > + > + ret = usb_role_switch_register_notifier(hisi_hikey_usb->role_sw, > + &hisi_hikey_usb->nb); > + if (ret) { > + usb_role_switch_put(hisi_hikey_usb->role_sw); > + return ret; > + } > + > + platform_set_drvdata(pdev, hisi_hikey_usb); > + > + return 0; > +} The issue I found is that if due to module load order or other randomization in bootup timing, this driver loads much later then the other USB infrastructure, the usb_role_switch notifier that is registered may be registered after any state initialization or change has occurred that would trigger the notifier callbacks. This means initially this driver could be out of sync with the core usb_role_switch state. I've tried doing something like the following on probe to force the initialization: cur_role = usb_role_switch_get_role(hisi_hikey_usb->role_sw); usb_role_switch_set_role(hisi_hikey_usb->role_sw, cur_role); But this is racy, as a state change can happen in between the call to get_role and set_role, which would end up overwriting the proper state. I suspect a proper fix needs to happen in the usb_role_switch_register_notifier(), where the callback gets called with the initial state while holding the lock to avoid races. I'll comment more in that patch. thanks -john 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: [v5,11/13] hikey960: Support usb functionality of Hikey960 From: John Stultz Message-Id: Date: Thu, 11 Apr 2019 17:55:32 -0700 To: Yu Chen Cc: Linux USB List , "open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS" , lkml , Zhuangluan Su , Kongfei , "Liuyu \(R\)" , wanghu17@hisilicon.com, butao , chenyao11@huawei.com, fangshengzhou@hisilicon.com, Li Pengcheng , songxiaowei@hisilicon.com, YiPing Xu , xuyoujun4@huawei.com, Yudongbin , Zang Leigang , Chunfeng Yun , Andy Shevchenko , Arnd Bergmann , Greg Kroah-Hartman , Binghui Wang , Heikki Krogerus List-ID: T24gVGh1LCBNYXIgMjgsIDIwMTkgYXQgOToxNCBQTSBZdSBDaGVuIDxjaGVueXU1NkBodWF3ZWku Y29tPiB3cm90ZToKPgo+IFRoaXMgZHJpdmVyIGhhbmRsZXMgdXNiIGh1YiBwb3dlciBvbiBhbmQg dHlwZUMgcG9ydCBldmVudCBvZiBIaUtleTk2MCBib2FyZDoKPiAxKURQJkRNIHN3aXRjaGluZyBi ZXR3ZWVuIHVzYiBodWIgYW5kIHR5cGVDIHBvcnQgYmFzZSBvbiB0eXBlQyBwb3J0Cj4gc3RhdGUK PiAyKUNvbnRyb2wgcG93ZXIgb2YgdXNiIGh1YiBvbiBIaWtleTk2MAo+IDMpQ29udHJvbCB2YnVz IG9mIHR5cGVDIHBvcnQKCkhleSBZdSBDaGVuIQogIFdhbnRlZCB0byBzYXkgdGhhbmtzIGFnYWlu IGZvciBzZW5kaW5nIHRoZXNlIHBhdGNoZXMgb3V0IHNvCnBlcnNpc3RlbnRseS4gSSBkaWQgY2F0 Y2ggYW4gaXNzdWUgd2l0aCB0aGlzIGRyaXZlciB0aGF0IEkgd2FudGVkIHRvCmxldCB5b3Uga25v dyBhYm91dC4KCj4gK3N0YXRpYyBpbnQgaGlzaV9oaWtleV9yb2xlX3N3aXRjaChzdHJ1Y3Qgbm90 aWZpZXJfYmxvY2sgKm5iLAo+ICsgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIGxvbmcg c3RhdGUsIHZvaWQgKmRhdGEpCj4gK3sKPiArICAgICAgIHN0cnVjdCBoaXNpX2hpa2V5X3VzYiAq aGlzaV9oaWtleV91c2I7Cj4gKwo+ICsgICAgICAgaGlzaV9oaWtleV91c2IgPSBjb250YWluZXJf b2YobmIsIHN0cnVjdCBoaXNpX2hpa2V5X3VzYiwgbmIpOwo+ICsKPiArICAgICAgIHN3aXRjaCAo c3RhdGUpIHsKPiArICAgICAgIGNhc2UgVVNCX1JPTEVfTk9ORToKPiArICAgICAgICAgICAgICAg dXNiX3R5cGVjX3Bvd2VyX2N0cmwoaGlzaV9oaWtleV91c2IsIFRZUEVDX1ZCVVNfUE9XRVJfT0ZG KTsKPiArICAgICAgICAgICAgICAgdXNiX3N3aXRjaF9jdHJsKGhpc2lfaGlrZXlfdXNiLCBVU0Jf U1dJVENIX1RPX0hVQik7Cj4gKyAgICAgICAgICAgICAgIGh1Yl9wb3dlcl9jdHJsKGhpc2lfaGlr ZXlfdXNiLCBIVUJfVkJVU19QT1dFUl9PTik7Cj4gKyAgICAgICAgICAgICAgIGJyZWFrOwo+ICsg ICAgICAgY2FzZSBVU0JfUk9MRV9IT1NUOgo+ICsgICAgICAgICAgICAgICB1c2Jfc3dpdGNoX2N0 cmwoaGlzaV9oaWtleV91c2IsIFVTQl9TV0lUQ0hfVE9fVFlQRUMpOwo+ICsgICAgICAgICAgICAg ICB1c2JfdHlwZWNfcG93ZXJfY3RybChoaXNpX2hpa2V5X3VzYiwgVFlQRUNfVkJVU19QT1dFUl9P Tik7Cj4gKyAgICAgICAgICAgICAgIGJyZWFrOwo+ICsgICAgICAgY2FzZSBVU0JfUk9MRV9ERVZJ Q0U6Cj4gKyAgICAgICAgICAgICAgIGh1Yl9wb3dlcl9jdHJsKGhpc2lfaGlrZXlfdXNiLCBIVUJf VkJVU19QT1dFUl9PRkYpOwo+ICsgICAgICAgICAgICAgICB1c2JfdHlwZWNfcG93ZXJfY3RybCho aXNpX2hpa2V5X3VzYiwgVFlQRUNfVkJVU19QT1dFUl9PRkYpOwo+ICsgICAgICAgICAgICAgICB1 c2Jfc3dpdGNoX2N0cmwoaGlzaV9oaWtleV91c2IsIFVTQl9TV0lUQ0hfVE9fVFlQRUMpOwo+ICsg ICAgICAgICAgICAgICBicmVhazsKPiArICAgICAgIGRlZmF1bHQ6Cj4gKyAgICAgICAgICAgICAg IGJyZWFrOwo+ICsgICAgICAgfQo+ICsKPiArICAgICAgIHJldHVybiAwOwo+ICt9Cj4gKwo+ICtz dGF0aWMgaW50IGhpc2lfaGlrZXlfdXNiX3Byb2JlKHN0cnVjdCBwbGF0Zm9ybV9kZXZpY2UgKnBk ZXYpCj4gK3sKPiArICAgICAgIHN0cnVjdCBkZXZpY2UgKmRldiA9ICZwZGV2LT5kZXY7Cj4gKyAg ICAgICBzdHJ1Y3QgaGlzaV9oaWtleV91c2IgKmhpc2lfaGlrZXlfdXNiOwo+ICsgICAgICAgaW50 IHJldDsKPiArCj4gKyAgICAgICBoaXNpX2hpa2V5X3VzYiA9IGRldm1fa3phbGxvYyhkZXYsIHNp emVvZigqaGlzaV9oaWtleV91c2IpLCBHRlBfS0VSTkVMKTsKPiArICAgICAgIGlmICghaGlzaV9o aWtleV91c2IpCj4gKyAgICAgICAgICAgICAgIHJldHVybiAtRU5PTUVNOwo+ICsKPiArICAgICAg IGhpc2lfaGlrZXlfdXNiLT5uYi5ub3RpZmllcl9jYWxsID0gaGlzaV9oaWtleV9yb2xlX3N3aXRj aDsKPiArCj4gKyAgICAgICBoaXNpX2hpa2V5X3VzYi0+dHlwZWNfdmJ1cyA9IGRldm1fZ3Bpb2Rf Z2V0KGRldiwgInR5cGVjLXZidXMiLAo+ICsgICAgICAgICAgICAgICAgICAgICAgIEdQSU9EX09V VF9MT1cpOwo+ICsgICAgICAgaWYgKElTX0VSUihoaXNpX2hpa2V5X3VzYi0+dHlwZWNfdmJ1cykp Cj4gKyAgICAgICAgICAgICAgIHJldHVybiBQVFJfRVJSKGhpc2lfaGlrZXlfdXNiLT50eXBlY192 YnVzKTsKPiArCj4gKyAgICAgICBoaXNpX2hpa2V5X3VzYi0+b3RnX3N3aXRjaCA9IGRldm1fZ3Bp b2RfZ2V0KGRldiwgIm90Zy1zd2l0Y2giLAo+ICsgICAgICAgICAgICAgICAgICAgICAgIEdQSU9E X09VVF9ISUdIKTsKPiArICAgICAgIGlmIChJU19FUlIoaGlzaV9oaWtleV91c2ItPm90Z19zd2l0 Y2gpKQo+ICsgICAgICAgICAgICAgICByZXR1cm4gUFRSX0VSUihoaXNpX2hpa2V5X3VzYi0+b3Rn X3N3aXRjaCk7Cj4gKwo+ICsgICAgICAgLyogaHViLXZkZDMzLWVuIGlzIG9wdGlvbmFsICovCj4g KyAgICAgICBoaXNpX2hpa2V5X3VzYi0+aHViX3ZidXMgPSBkZXZtX2dwaW9kX2dldF9vcHRpb25h bChkZXYsICJodWItdmRkMzMtZW4iLAo+ICsgICAgICAgICAgICAgICAgICAgICAgIEdQSU9EX09V VF9ISUdIKTsKPiArICAgICAgIGlmIChJU19FUlIoaGlzaV9oaWtleV91c2ItPmh1Yl92YnVzKSkK PiArICAgICAgICAgICAgICAgcmV0dXJuIFBUUl9FUlIoaGlzaV9oaWtleV91c2ItPmh1Yl92YnVz KTsKPiArCj4gKyAgICAgICBoaXNpX2hpa2V5X3VzYi0+cm9sZV9zdyA9IHVzYl9yb2xlX3N3aXRj aF9nZXQoZGV2KTsKPiArICAgICAgIGlmICghaGlzaV9oaWtleV91c2ItPnJvbGVfc3cpCj4gKyAg ICAgICAgICAgICAgIHJldHVybiAtRVBST0JFX0RFRkVSOwo+ICsgICAgICAgaWYgKElTX0VSUiho aXNpX2hpa2V5X3VzYi0+cm9sZV9zdykpCj4gKyAgICAgICAgICAgICAgIHJldHVybiBQVFJfRVJS KGhpc2lfaGlrZXlfdXNiLT5yb2xlX3N3KTsKPiArCj4gKyAgICAgICByZXQgPSB1c2Jfcm9sZV9z d2l0Y2hfcmVnaXN0ZXJfbm90aWZpZXIoaGlzaV9oaWtleV91c2ItPnJvbGVfc3csCj4gKyAgICAg ICAgICAgICAgICAgICAgICAgJmhpc2lfaGlrZXlfdXNiLT5uYik7Cj4gKyAgICAgICBpZiAocmV0 KSB7Cj4gKyAgICAgICAgICAgICAgIHVzYl9yb2xlX3N3aXRjaF9wdXQoaGlzaV9oaWtleV91c2It PnJvbGVfc3cpOwo+ICsgICAgICAgICAgICAgICByZXR1cm4gcmV0Owo+ICsgICAgICAgfQo+ICsK PiArICAgICAgIHBsYXRmb3JtX3NldF9kcnZkYXRhKHBkZXYsIGhpc2lfaGlrZXlfdXNiKTsKPiAr Cj4gKyAgICAgICByZXR1cm4gMDsKPiArfQoKVGhlIGlzc3VlIEkgZm91bmQgaXMgdGhhdCBpZiBk dWUgdG8gbW9kdWxlIGxvYWQgb3JkZXIgb3Igb3RoZXIKcmFuZG9taXphdGlvbiBpbiBib290dXAg dGltaW5nLCB0aGlzIGRyaXZlciBsb2FkcyBtdWNoIGxhdGVyIHRoZW4gdGhlCm90aGVyIFVTQiBp bmZyYXN0cnVjdHVyZSwgdGhlIHVzYl9yb2xlX3N3aXRjaCBub3RpZmllciB0aGF0IGlzCnJlZ2lz dGVyZWQgbWF5IGJlIHJlZ2lzdGVyZWQgYWZ0ZXIgYW55IHN0YXRlIGluaXRpYWxpemF0aW9uIG9y IGNoYW5nZQpoYXMgb2NjdXJyZWQgdGhhdCB3b3VsZCB0cmlnZ2VyIHRoZSBub3RpZmllciBjYWxs YmFja3MuCgpUaGlzIG1lYW5zIGluaXRpYWxseSB0aGlzIGRyaXZlciBjb3VsZCBiZSBvdXQgb2Yg c3luYyB3aXRoIHRoZSBjb3JlCnVzYl9yb2xlX3N3aXRjaCBzdGF0ZS4KCkkndmUgdHJpZWQgZG9p bmcgc29tZXRoaW5nIGxpa2UgdGhlIGZvbGxvd2luZyBvbiBwcm9iZSB0byBmb3JjZSB0aGUKaW5p dGlhbGl6YXRpb246CiAgIGN1cl9yb2xlID0gdXNiX3JvbGVfc3dpdGNoX2dldF9yb2xlKGhpc2lf aGlrZXlfdXNiLT5yb2xlX3N3KTsKICAgdXNiX3JvbGVfc3dpdGNoX3NldF9yb2xlKGhpc2lfaGlr ZXlfdXNiLT5yb2xlX3N3LCBjdXJfcm9sZSk7CgpCdXQgdGhpcyBpcyByYWN5LCBhcyBhIHN0YXRl IGNoYW5nZSBjYW4gaGFwcGVuIGluIGJldHdlZW4gdGhlIGNhbGwgdG8KZ2V0X3JvbGUgYW5kIHNl dF9yb2xlLCB3aGljaCB3b3VsZCBlbmQgdXAgb3ZlcndyaXRpbmcgdGhlIHByb3BlcgpzdGF0ZS4K Ckkgc3VzcGVjdCBhIHByb3BlciBmaXggbmVlZHMgdG8gaGFwcGVuIGluIHRoZQp1c2Jfcm9sZV9z d2l0Y2hfcmVnaXN0ZXJfbm90aWZpZXIoKSwgd2hlcmUgdGhlIGNhbGxiYWNrIGdldHMgY2FsbGVk CndpdGggdGhlIGluaXRpYWwgc3RhdGUgd2hpbGUgaG9sZGluZyB0aGUgbG9jayB0byBhdm9pZCBy YWNlcy4KCkknbGwgY29tbWVudCBtb3JlIGluIHRoYXQgcGF0Y2guCgp0aGFua3MKLWpvaG4K