2010-11-26 09:57:24

by Wojciech Dubowik

[permalink] [raw]
Subject: [PATCH v6 9/9] ath5k: Fix reset and interrupts for AHB type of devices.

From: Felix Fietkau <[email protected]>

On WiSoc we cannot access mac register before it is resetted.
It will crash hardware otherwise.

Signed-off-by: Felix Fietkau <[email protected]>
Signed-off-by: Wojciech Dubowik <[email protected]>
---
drivers/net/wireless/ath/ath5k/base.c | 7 ++-
drivers/net/wireless/ath/ath5k/reset.c | 114 ++++++++++++++++++++++++-------
2 files changed, 94 insertions(+), 27 deletions(-)

diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c
index 4d5ac71..87a4bb6 100644
--- a/drivers/net/wireless/ath/ath5k/base.c
+++ b/drivers/net/wireless/ath/ath5k/base.c
@@ -2169,7 +2169,8 @@ ath5k_intr(int irq, void *dev_id)
unsigned int counter = 1000;

if (unlikely(test_bit(ATH_STAT_INVALID, sc->status) ||
- !ath5k_hw_is_intr_pending(ah)))
+ ((ath5k_get_bus_type(ah) != ATH_AHB) &&
+ !ath5k_hw_is_intr_pending(ah))))
return IRQ_NONE;

do {
@@ -2235,6 +2236,10 @@ ath5k_intr(int irq, void *dev_id)
tasklet_schedule(&sc->rf_kill.toggleq);

}
+
+ if (ath5k_get_bus_type(ah) == ATH_AHB)
+ break;
+
} while (ath5k_hw_is_intr_pending(ah) && --counter > 0);

if (unlikely(!counter))
diff --git a/drivers/net/wireless/ath/ath5k/reset.c b/drivers/net/wireless/ath/ath5k/reset.c
index 198a146..4f54655 100644
--- a/drivers/net/wireless/ath/ath5k/reset.c
+++ b/drivers/net/wireless/ath/ath5k/reset.c
@@ -27,6 +27,7 @@

#include <linux/pci.h> /* To determine if a card is pci-e */
#include <linux/log2.h>
+#include <linux/platform_device.h>
#include "ath5k.h"
#include "reg.h"
#include "base.h"
@@ -198,31 +199,74 @@ static inline void ath5k_hw_write_rate_duration(struct ath5k_hw *ah,
*/
static int ath5k_hw_nic_reset(struct ath5k_hw *ah, u32 val)
{
- int ret;
+ int ret = 0;
u32 mask = val ? val : ~0U;

/* Read-and-clear RX Descriptor Pointer*/
- ath5k_hw_reg_read(ah, AR5K_RXDP);
+ if (!(mask & AR5K_RESET_CTL_MAC))
+ ath5k_hw_reg_read(ah, AR5K_RXDP);

/*
* Reset the device and wait until success
*/
- ath5k_hw_reg_write(ah, val, AR5K_RESET_CTL);
+ if (ath5k_get_bus_type(ah) == ATH_AHB) {
+ volatile u32 *reg;
+ u32 regval;
+ val = 0;
+
+ /* ah->ah_mac_srev is not available at this point yet */
+ if (ah->ah_sc->devid >= AR5K_SREV_AR2315_R6) {
+ reg = (u32 *) AR5K_AR2315_RESET;
+ if (mask & AR5K_RESET_CTL_MAC)
+ val |= AR5K_AR2315_RESET_WMAC;
+ if (mask & AR5K_RESET_CTL_BASEBAND)
+ val |= AR5K_AR2315_RESET_BB_WARM;
+ } else {
+ reg = (u32 *) AR5K_AR5312_RESET;
+ if (to_platform_device(ah->ah_sc->dev)->id == 0) {
+ if (mask & AR5K_RESET_CTL_MAC)
+ val |= AR5K_AR5312_RESET_WMAC0;
+ if (mask & AR5K_RESET_CTL_BASEBAND)
+ val |= AR5K_AR5312_RESET_BB0_COLD |
+ AR5K_AR5312_RESET_BB0_WARM;
+ } else {
+ if (mask & AR5K_RESET_CTL_MAC)
+ val |= AR5K_AR5312_RESET_WMAC1;
+ if (mask & AR5K_RESET_CTL_BASEBAND)
+ val |= AR5K_AR5312_RESET_BB1_COLD |
+ AR5K_AR5312_RESET_BB1_WARM;
+ }
+ }

- /* Wait at least 128 PCI clocks */
- udelay(15);
+ /* Put BB/MAC into reset */
+ regval = __raw_readl(reg);
+ __raw_writel(regval | val, reg);
+ regval = __raw_readl(reg);
+ udelay(100);

- if (ah->ah_version == AR5K_AR5210) {
- val &= AR5K_RESET_CTL_PCU | AR5K_RESET_CTL_DMA
- | AR5K_RESET_CTL_MAC | AR5K_RESET_CTL_PHY;
- mask &= AR5K_RESET_CTL_PCU | AR5K_RESET_CTL_DMA
- | AR5K_RESET_CTL_MAC | AR5K_RESET_CTL_PHY;
+ /* Bring BB/MAC out of reset */
+ __raw_writel(regval & ~val, reg);
+ regval = __raw_readl(reg);
} else {
- val &= AR5K_RESET_CTL_PCU | AR5K_RESET_CTL_BASEBAND;
- mask &= AR5K_RESET_CTL_PCU | AR5K_RESET_CTL_BASEBAND;
- }

- ret = ath5k_hw_register_timeout(ah, AR5K_RESET_CTL, mask, val, false);
+ ath5k_hw_reg_write(ah, val, AR5K_RESET_CTL);
+
+ /* Wait at least 128 PCI clocks */
+ udelay(15);
+
+ if (ah->ah_version == AR5K_AR5210) {
+ val &= AR5K_RESET_CTL_PCU | AR5K_RESET_CTL_DMA
+ | AR5K_RESET_CTL_MAC | AR5K_RESET_CTL_PHY;
+ mask &= AR5K_RESET_CTL_PCU | AR5K_RESET_CTL_DMA
+ | AR5K_RESET_CTL_MAC | AR5K_RESET_CTL_PHY;
+ } else {
+ val &= AR5K_RESET_CTL_PCU | AR5K_RESET_CTL_BASEBAND;
+ mask &= AR5K_RESET_CTL_PCU | AR5K_RESET_CTL_BASEBAND;
+ }
+
+ ret = ath5k_hw_register_timeout(ah, AR5K_RESET_CTL,
+ mask, val, false);
+ }

/*
* Reset configuration register (for hw byte-swap). Note that this
@@ -334,6 +378,9 @@ int ath5k_hw_on_hold(struct ath5k_hw *ah)
u32 bus_flags;
int ret;

+ if (ath5k_get_bus_type(ah) == ATH_AHB)
+ return 0;
+
/* Make sure device is awake */
ret = ath5k_hw_set_power(ah, AR5K_PM_AWAKE, true, 0);
if (ret) {
@@ -390,22 +437,30 @@ int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial)
mode = 0;
clock = 0;

- /* Wakeup the device */
- ret = ath5k_hw_set_power(ah, AR5K_PM_AWAKE, true, 0);
- if (ret) {
- ATH5K_ERR(ah->ah_sc, "failed to wakeup the MAC Chip\n");
- return ret;
+ if (ath5k_get_bus_type(ah) == ATH_AHB && !initial) {
+ /* Wakeup the device */
+ ret = ath5k_hw_set_power(ah, AR5K_PM_AWAKE, true, 0);
+ if (ret) {
+ ATH5K_ERR(ah->ah_sc, "failed to wakeup the MAC Chip\n");
+ return ret;
+ }
}

/*
* Put chipset on warm reset...
*
- * Note: putting PCI core on warm reset on PCI-E cards
- * results card to hang and always return 0xffff... so
- * we ingore that flag for PCI-E cards. On PCI cards
- * this flag gets cleared after 64 PCI clocks.
*/
- bus_flags = (pdev && pdev->is_pcie) ? 0 : AR5K_RESET_CTL_PCI;
+ if (ath5k_get_bus_type(ah) == ATH_AHB) {
+ /* Reset MAC on WiSoc devices */
+ bus_flags = (initial) ? AR5K_RESET_CTL_MAC : 0;
+ } else {
+ /* Note: putting PCI core on warm reset on PCI-E cards
+ * results card to hang and always return 0xffff... so
+ * we ingore that flag for PCI-E cards. On PCI cards
+ * this flag gets cleared after 64 PCI clocks.
+ */
+ bus_flags = (pdev && pdev->is_pcie) ? 0 : AR5K_RESET_CTL_PCI;
+ }

if (ah->ah_version == AR5K_AR5210) {
ret = ath5k_hw_nic_reset(ah, AR5K_RESET_CTL_PCU |
@@ -536,6 +591,9 @@ static void ath5k_hw_set_sleep_clock(struct ath5k_hw *ah, bool enable)
struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
u32 scal, spending, usec32;

+ if (ath5k_get_bus_type(ah) == ATH_AHB)
+ enable = false;
+
/* Only set 32KHz settings if we have an external
* 32KHz crystal present */
if ((AR5K_EEPROM_HAS32KHZCRYSTAL(ee->ee_misc1) ||
@@ -607,6 +665,7 @@ static void ath5k_hw_set_sleep_clock(struct ath5k_hw *ah, bool enable)

if ((ah->ah_radio == AR5K_RF5112) ||
(ah->ah_radio == AR5K_RF5413) ||
+ (ah->ah_radio == AR5K_RF2316) ||
(ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4)))
spending = 0x14;
else
@@ -614,7 +673,9 @@ static void ath5k_hw_set_sleep_clock(struct ath5k_hw *ah, bool enable)
ath5k_hw_reg_write(ah, spending, AR5K_PHY_SPENDING);

if ((ah->ah_radio == AR5K_RF5112) ||
- (ah->ah_radio == AR5K_RF5413))
+ (ah->ah_radio == AR5K_RF5413) ||
+ (ah->ah_radio == AR5K_RF2316) ||
+ (ah->ah_radio == AR5K_RF2317))
usec32 = 39;
else
usec32 = 31;
@@ -678,7 +739,8 @@ static void ath5k_hw_tweak_initval_settings(struct ath5k_hw *ah,

/* Set fast ADC */
if ((ah->ah_radio == AR5K_RF5413) ||
- (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4))) {
+ (ah->ah_radio == AR5K_RF2317) ||
+ (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4))) {
u32 fast_adc = true;

if (channel->center_freq == 2462 ||
--
1.7.1



2010-11-27 00:29:57

by Nick Kossifidis

[permalink] [raw]
Subject: Re: [PATCH v6 9/9] ath5k: Fix reset and interrupts for AHB type of devices.

MjAxMC8xMS8yNiBXb2pjaWVjaCBEdWJvd2lrIDxkdWJvd29qQG5lcmF0ZWMuY29tPjoKPiBGcm9t
OiBGZWxpeCBGaWV0a2F1IDxuYmRAb3BlbndydC5vcmc+Cj4KPiBPbiBXaVNvYyB3ZSBjYW5ub3Qg
YWNjZXNzIG1hYyByZWdpc3RlciBiZWZvcmUgaXQgaXMgcmVzZXR0ZWQuCj4gSXQgd2lsbCBjcmFz
aCBoYXJkd2FyZSBvdGhlcndpc2UuCj4KPiBTaWduZWQtb2ZmLWJ5OiBGZWxpeCBGaWV0a2F1IDxu
YmRAb3BlbndydC5vcmc+Cj4gU2lnbmVkLW9mZi1ieTogV29qY2llY2ggRHVib3dpayA8V29qY2ll
Y2guRHVib3dpa0BuZXJhdGVjLmNvbT4KPiAtLS0KPiDCoGRyaXZlcnMvbmV0L3dpcmVsZXNzL2F0
aC9hdGg1ay9iYXNlLmMgwqB8IMKgIMKgNyArKy0KPiDCoGRyaXZlcnMvbmV0L3dpcmVsZXNzL2F0
aC9hdGg1ay9yZXNldC5jIHwgwqAxMTQgKysrKysrKysrKysrKysrKysrKysrKysrLS0tLS0tLQo+
IMKgMiBmaWxlcyBjaGFuZ2VkLCA5NCBpbnNlcnRpb25zKCspLCAyNyBkZWxldGlvbnMoLSkKPgo+
IGRpZmYgLS1naXQgYS9kcml2ZXJzL25ldC93aXJlbGVzcy9hdGgvYXRoNWsvYmFzZS5jIGIvZHJp
dmVycy9uZXQvd2lyZWxlc3MvYXRoL2F0aDVrL2Jhc2UuYwo+IGluZGV4IDRkNWFjNzEuLjg3YTRi
YjYgMTAwNjQ0Cj4gLS0tIGEvZHJpdmVycy9uZXQvd2lyZWxlc3MvYXRoL2F0aDVrL2Jhc2UuYwo+
ICsrKyBiL2RyaXZlcnMvbmV0L3dpcmVsZXNzL2F0aC9hdGg1ay9iYXNlLmMKPiBAQCAtMjE2OSw3
ICsyMTY5LDggQEAgYXRoNWtfaW50cihpbnQgaXJxLCB2b2lkICpkZXZfaWQpCj4gwqAgwqAgwqAg
wqB1bnNpZ25lZCBpbnQgY291bnRlciA9IDEwMDA7Cj4KPiDCoCDCoCDCoCDCoGlmICh1bmxpa2Vs
eSh0ZXN0X2JpdChBVEhfU1RBVF9JTlZBTElELCBzYy0+c3RhdHVzKSB8fAo+IC0gwqAgwqAgwqAg
wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgIWF0aDVrX2h3X2lzX2ludHJfcGVu
ZGluZyhhaCkpKQo+ICsgwqAgwqAgwqAgwqAgwqAgwqAgwqAgKChhdGg1a19nZXRfYnVzX3R5cGUo
YWgpICE9IEFUSF9BSEIpICYmCj4gKyDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoCDCoCDCoCAhYXRoNWtfaHdfaXNfaW50cl9wZW5kaW5nKGFoKSkpKQo+IMKgIMKgIMKgIMKg
IMKgIMKgIMKgIMKgcmV0dXJuIElSUV9OT05FOwo+Cj4gwqAgwqAgwqAgwqBkbyB7Cj4gQEAgLTIy
MzUsNiArMjIzNiwxMCBAQCBhdGg1a19pbnRyKGludCBpcnEsIHZvaWQgKmRldl9pZCkKPiDCoCDC
oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoHRhc2tsZXRfc2NoZWR1
bGUoJnNjLT5yZl9raWxsLnRvZ2dsZXEpOwo+Cj4gwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqB9Cj4g
Kwo+ICsgwqAgwqAgwqAgwqAgwqAgwqAgwqAgaWYgKGF0aDVrX2dldF9idXNfdHlwZShhaCkgPT0g
QVRIX0FIQikKPiArIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIGJyZWFrOwo+ICsK
PiDCoCDCoCDCoCDCoH0gd2hpbGUgKGF0aDVrX2h3X2lzX2ludHJfcGVuZGluZyhhaCkgJiYgLS1j
b3VudGVyID4gMCk7Cj4KPiDCoCDCoCDCoCDCoGlmICh1bmxpa2VseSghY291bnRlcikpCj4gZGlm
ZiAtLWdpdCBhL2RyaXZlcnMvbmV0L3dpcmVsZXNzL2F0aC9hdGg1ay9yZXNldC5jIGIvZHJpdmVy
cy9uZXQvd2lyZWxlc3MvYXRoL2F0aDVrL3Jlc2V0LmMKPiBpbmRleCAxOThhMTQ2Li40ZjU0NjU1
IDEwMDY0NAo+IC0tLSBhL2RyaXZlcnMvbmV0L3dpcmVsZXNzL2F0aC9hdGg1ay9yZXNldC5jCj4g
KysrIGIvZHJpdmVycy9uZXQvd2lyZWxlc3MvYXRoL2F0aDVrL3Jlc2V0LmMKPiBAQCAtMjcsNiAr
MjcsNyBAQAo+Cj4gwqAjaW5jbHVkZSA8bGludXgvcGNpLmg+IMKgIMKgIMKgIMKgIMKgIMKgIMKg
IMKgIC8qIFRvIGRldGVybWluZSBpZiBhIGNhcmQgaXMgcGNpLWUgKi8KPiDCoCNpbmNsdWRlIDxs
aW51eC9sb2cyLmg+Cj4gKyNpbmNsdWRlIDxsaW51eC9wbGF0Zm9ybV9kZXZpY2UuaD4KPiDCoCNp
bmNsdWRlICJhdGg1ay5oIgo+IMKgI2luY2x1ZGUgInJlZy5oIgo+IMKgI2luY2x1ZGUgImJhc2Uu
aCIKPiBAQCAtMTk4LDMxICsxOTksNzQgQEAgc3RhdGljIGlubGluZSB2b2lkIGF0aDVrX2h3X3dy
aXRlX3JhdGVfZHVyYXRpb24oc3RydWN0IGF0aDVrX2h3ICphaCwKPiDCoCovCj4gwqBzdGF0aWMg
aW50IGF0aDVrX2h3X25pY19yZXNldChzdHJ1Y3QgYXRoNWtfaHcgKmFoLCB1MzIgdmFsKQo+IMKg
ewo+IC0gwqAgwqAgwqAgaW50IHJldDsKPiArIMKgIMKgIMKgIGludCByZXQgPSAwOwo+IMKgIMKg
IMKgIMKgdTMyIG1hc2sgPSB2YWwgPyB2YWwgOiB+MFU7Cj4KPiDCoCDCoCDCoCDCoC8qIFJlYWQt
YW5kLWNsZWFyIFJYIERlc2NyaXB0b3IgUG9pbnRlciovCj4gLSDCoCDCoCDCoCBhdGg1a19od19y
ZWdfcmVhZChhaCwgQVI1S19SWERQKTsKPiArIMKgIMKgIMKgIGlmICghKG1hc2sgJiBBUjVLX1JF
U0VUX0NUTF9NQUMpKQo+ICsgwqAgwqAgwqAgwqAgwqAgwqAgwqAgYXRoNWtfaHdfcmVnX3JlYWQo
YWgsIEFSNUtfUlhEUCk7Cj4KPiDCoCDCoCDCoCDCoC8qCj4gwqAgwqAgwqAgwqAgKiBSZXNldCB0
aGUgZGV2aWNlIGFuZCB3YWl0IHVudGlsIHN1Y2Nlc3MKPiDCoCDCoCDCoCDCoCAqLwo+IC0gwqAg
wqAgwqAgYXRoNWtfaHdfcmVnX3dyaXRlKGFoLCB2YWwsIEFSNUtfUkVTRVRfQ1RMKTsKPiArIMKg
IMKgIMKgIGlmIChhdGg1a19nZXRfYnVzX3R5cGUoYWgpID09IEFUSF9BSEIpIHsKPiArIMKgIMKg
IMKgIMKgIMKgIMKgIMKgIHZvbGF0aWxlIHUzMiAqcmVnOwo+ICsgwqAgwqAgwqAgwqAgwqAgwqAg
wqAgdTMyIHJlZ3ZhbDsKPiArIMKgIMKgIMKgIMKgIMKgIMKgIMKgIHZhbCA9IDA7Cj4gKwo+ICsg
wqAgwqAgwqAgwqAgwqAgwqAgwqAgLyogYWgtPmFoX21hY19zcmV2IGlzIG5vdCBhdmFpbGFibGUg
YXQgdGhpcyBwb2ludCB5ZXQgKi8KPiArIMKgIMKgIMKgIMKgIMKgIMKgIMKgIGlmIChhaC0+YWhf
c2MtPmRldmlkID49IEFSNUtfU1JFVl9BUjIzMTVfUjYpIHsKPiArIMKgIMKgIMKgIMKgIMKgIMKg
IMKgIMKgIMKgIMKgIMKgIHJlZyA9ICh1MzIgKikgQVI1S19BUjIzMTVfUkVTRVQ7Cj4gKyDCoCDC
oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCBpZiAobWFzayAmIEFSNUtfUkVTRVRfQ1RMX01B
QykKPiArIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIHZhbCB8
PSBBUjVLX0FSMjMxNV9SRVNFVF9XTUFDOwo+ICsgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg
wqAgwqAgaWYgKG1hc2sgJiBBUjVLX1JFU0VUX0NUTF9CQVNFQkFORCkKPiArIMKgIMKgIMKgIMKg
IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIHZhbCB8PSBBUjVLX0FSMjMxNV9SRVNF
VF9CQl9XQVJNOwo+ICsgwqAgwqAgwqAgwqAgwqAgwqAgwqAgfSBlbHNlIHsKPiArIMKgIMKgIMKg
IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIHJlZyA9ICh1MzIgKikgQVI1S19BUjUzMTJfUkVTRVQ7
Cj4gKyDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCBpZiAodG9fcGxhdGZvcm1fZGV2
aWNlKGFoLT5haF9zYy0+ZGV2KS0+aWQgPT0gMCkgewo+ICsgwqAgwqAgwqAgwqAgwqAgwqAgwqAg
wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgaWYgKG1hc2sgJiBBUjVLX1JFU0VUX0NUTF9NQUMpCj4g
KyDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC
oCB2YWwgfD0gQVI1S19BUjUzMTJfUkVTRVRfV01BQzA7Cj4gKyDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCBpZiAobWFzayAmIEFSNUtfUkVTRVRfQ1RMX0JBU0VC
QU5EKQo+ICsgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg
wqAgwqAgwqAgdmFsIHw9IEFSNUtfQVI1MzEyX1JFU0VUX0JCMF9DT0xEIHwKPiArIMKgIMKgIMKg
IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg
IMKgQVI1S19BUjUzMTJfUkVTRVRfQkIwX1dBUk07Cj4gKyDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoCDCoCDCoCB9IGVsc2Ugewo+ICsgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg
wqAgwqAgwqAgwqAgaWYgKG1hc2sgJiBBUjVLX1JFU0VUX0NUTF9NQUMpCj4gKyDCoCDCoCDCoCDC
oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCB2YWwgfD0gQVI1
S19BUjUzMTJfUkVTRVRfV01BQzE7Cj4gKyDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoCDCoCDCoCDCoCBpZiAobWFzayAmIEFSNUtfUkVTRVRfQ1RMX0JBU0VCQU5EKQo+ICsgwqAg
wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgdmFs
IHw9IEFSNUtfQVI1MzEyX1JFU0VUX0JCMV9DT0xEIHwKPiArIMKgIMKgIMKgIMKgIMKgIMKgIMKg
IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgQVI1S19BUjUz
MTJfUkVTRVRfQkIxX1dBUk07Cj4gKyDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCB9
Cj4gKyDCoCDCoCDCoCDCoCDCoCDCoCDCoCB9Cj4KPiAtIMKgIMKgIMKgIC8qIFdhaXQgYXQgbGVh
c3QgMTI4IFBDSSBjbG9ja3MgKi8KPiAtIMKgIMKgIMKgIHVkZWxheSgxNSk7Cj4gKyDCoCDCoCDC
oCDCoCDCoCDCoCDCoCAvKiBQdXQgQkIvTUFDIGludG8gcmVzZXQgKi8KPiArIMKgIMKgIMKgIMKg
IMKgIMKgIMKgIHJlZ3ZhbCA9IF9fcmF3X3JlYWRsKHJlZyk7Cj4gKyDCoCDCoCDCoCDCoCDCoCDC
oCDCoCBfX3Jhd193cml0ZWwocmVndmFsIHwgdmFsLCByZWcpOwo+ICsgwqAgwqAgwqAgwqAgwqAg
wqAgwqAgcmVndmFsID0gX19yYXdfcmVhZGwocmVnKTsKPiArIMKgIMKgIMKgIMKgIMKgIMKgIMKg
IHVkZWxheSgxMDApOwo+Cj4gLSDCoCDCoCDCoCBpZiAoYWgtPmFoX3ZlcnNpb24gPT0gQVI1S19B
UjUyMTApIHsKPiAtIMKgIMKgIMKgIMKgIMKgIMKgIMKgIHZhbCAmPSBBUjVLX1JFU0VUX0NUTF9Q
Q1UgfCBBUjVLX1JFU0VUX0NUTF9ETUEKPiAtIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg
IMKgIHwgQVI1S19SRVNFVF9DVExfTUFDIHwgQVI1S19SRVNFVF9DVExfUEhZOwo+IC0gwqAgwqAg
wqAgwqAgwqAgwqAgwqAgbWFzayAmPSBBUjVLX1JFU0VUX0NUTF9QQ1UgfCBBUjVLX1JFU0VUX0NU
TF9ETUEKPiAtIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIHwgQVI1S19SRVNFVF9D
VExfTUFDIHwgQVI1S19SRVNFVF9DVExfUEhZOwo+ICsgwqAgwqAgwqAgwqAgwqAgwqAgwqAgLyog
QnJpbmcgQkIvTUFDIG91dCBvZiByZXNldCAqLwo+ICsgwqAgwqAgwqAgwqAgwqAgwqAgwqAgX19y
YXdfd3JpdGVsKHJlZ3ZhbCAmIH52YWwsIHJlZyk7Cj4gKyDCoCDCoCDCoCDCoCDCoCDCoCDCoCBy
ZWd2YWwgPSBfX3Jhd19yZWFkbChyZWcpOwo+IMKgIMKgIMKgIMKgfSBlbHNlIHsKPiAtIMKgIMKg
IMKgIMKgIMKgIMKgIMKgIHZhbCAmPSBBUjVLX1JFU0VUX0NUTF9QQ1UgfCBBUjVLX1JFU0VUX0NU
TF9CQVNFQkFORDsKPiAtIMKgIMKgIMKgIMKgIMKgIMKgIMKgIG1hc2sgJj0gQVI1S19SRVNFVF9D
VExfUENVIHwgQVI1S19SRVNFVF9DVExfQkFTRUJBTkQ7Cj4gLSDCoCDCoCDCoCB9Cj4KPiAtIMKg
IMKgIMKgIHJldCA9IGF0aDVrX2h3X3JlZ2lzdGVyX3RpbWVvdXQoYWgsIEFSNUtfUkVTRVRfQ1RM
LCBtYXNrLCB2YWwsIGZhbHNlKTsKPiArIMKgIMKgIMKgIMKgIMKgIMKgIMKgIGF0aDVrX2h3X3Jl
Z193cml0ZShhaCwgdmFsLCBBUjVLX1JFU0VUX0NUTCk7Cj4gKwo+ICsgwqAgwqAgwqAgwqAgwqAg
wqAgwqAgLyogV2FpdCBhdCBsZWFzdCAxMjggUENJIGNsb2NrcyAqLwo+ICsgwqAgwqAgwqAgwqAg
wqAgwqAgwqAgdWRlbGF5KDE1KTsKPiArCj4gKyDCoCDCoCDCoCDCoCDCoCDCoCDCoCBpZiAoYWgt
PmFoX3ZlcnNpb24gPT0gQVI1S19BUjUyMTApIHsKPiArIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg
IMKgIMKgIMKgIHZhbCAmPSBBUjVLX1JFU0VUX0NUTF9QQ1UgfCBBUjVLX1JFU0VUX0NUTF9ETUEK
PiArIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIHwgQVI1S19S
RVNFVF9DVExfTUFDIHwgQVI1S19SRVNFVF9DVExfUEhZOwo+ICsgwqAgwqAgwqAgwqAgwqAgwqAg
wqAgwqAgwqAgwqAgwqAgbWFzayAmPSBBUjVLX1JFU0VUX0NUTF9QQ1UgfCBBUjVLX1JFU0VUX0NU
TF9ETUEKPiArIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIHwg
QVI1S19SRVNFVF9DVExfTUFDIHwgQVI1S19SRVNFVF9DVExfUEhZOwo+ICsgwqAgwqAgwqAgwqAg
wqAgwqAgwqAgfSBlbHNlIHsKPiArIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIHZh
bCAmPSBBUjVLX1JFU0VUX0NUTF9QQ1UgfCBBUjVLX1JFU0VUX0NUTF9CQVNFQkFORDsKPiArIMKg
IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIG1hc2sgJj0gQVI1S19SRVNFVF9DVExfUENV
IHwgQVI1S19SRVNFVF9DVExfQkFTRUJBTkQ7Cj4gKyDCoCDCoCDCoCDCoCDCoCDCoCDCoCB9Cj4g
Kwo+ICsgwqAgwqAgwqAgwqAgwqAgwqAgwqAgcmV0ID0gYXRoNWtfaHdfcmVnaXN0ZXJfdGltZW91
dChhaCwgQVI1S19SRVNFVF9DVEwsCj4gKyDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoCDCoCDCoCDCoCBtYXNrLCB2YWwsIGZhbHNlKTsKPiArIMKgIMKgIMKgIH0KPgoKSSB0aGlu
ayBpdCB3b3VsZCBiZSBtdWNoIGNsZWFuZXIgaWYgd2UgaGFkIGEgZGlmZmVyZW50IGZ1bmN0aW9u
IHRvCmhhbmRsZSB3aXNvYyByZXNldCBpbnN0ZWFkCm9mIHB1dHRpbmcgYm90aCBvbiBuaWNfcmVz
ZXQuIEhvdyBhYm91dCBoYXZpbmcgYSBhdGg1a19od193aXNvY19yZXNldAphbmQgY2FsbCB0aGF0
IGluc3RlYWQgPwoKPiDCoCDCoCDCoCDCoC8qCj4gwqAgwqAgwqAgwqAgKiBSZXNldCBjb25maWd1
cmF0aW9uIHJlZ2lzdGVyIChmb3IgaHcgYnl0ZS1zd2FwKS4gTm90ZSB0aGF0IHRoaXMKPiBAQCAt
MzM0LDYgKzM3OCw5IEBAIGludCBhdGg1a19od19vbl9ob2xkKHN0cnVjdCBhdGg1a19odyAqYWgp
Cj4gwqAgwqAgwqAgwqB1MzIgYnVzX2ZsYWdzOwo+IMKgIMKgIMKgIMKgaW50IHJldDsKPgo+ICsg
wqAgwqAgwqAgaWYgKGF0aDVrX2dldF9idXNfdHlwZShhaCkgPT0gQVRIX0FIQikKPiArIMKgIMKg
IMKgIMKgIMKgIMKgIMKgIHJldHVybiAwOwo+ICsKPiDCoCDCoCDCoCDCoC8qIE1ha2Ugc3VyZSBk
ZXZpY2UgaXMgYXdha2UgKi8KPiDCoCDCoCDCoCDCoHJldCA9IGF0aDVrX2h3X3NldF9wb3dlcihh
aCwgQVI1S19QTV9BV0FLRSwgdHJ1ZSwgMCk7Cj4gwqAgwqAgwqAgwqBpZiAocmV0KSB7Cj4gQEAg
LTM5MCwyMiArNDM3LDMwIEBAIGludCBhdGg1a19od19uaWNfd2FrZXVwKHN0cnVjdCBhdGg1a19o
dyAqYWgsIGludCBmbGFncywgYm9vbCBpbml0aWFsKQo+IMKgIMKgIMKgIMKgbW9kZSA9IDA7Cj4g
wqAgwqAgwqAgwqBjbG9jayA9IDA7Cj4KPiAtIMKgIMKgIMKgIC8qIFdha2V1cCB0aGUgZGV2aWNl
ICovCj4gLSDCoCDCoCDCoCByZXQgPSBhdGg1a19od19zZXRfcG93ZXIoYWgsIEFSNUtfUE1fQVdB
S0UsIHRydWUsIDApOwo+IC0gwqAgwqAgwqAgaWYgKHJldCkgewo+IC0gwqAgwqAgwqAgwqAgwqAg
wqAgwqAgQVRINUtfRVJSKGFoLT5haF9zYywgImZhaWxlZCB0byB3YWtldXAgdGhlIE1BQyBDaGlw
XG4iKTsKPiAtIMKgIMKgIMKgIMKgIMKgIMKgIMKgIHJldHVybiByZXQ7Cj4gKyDCoCDCoCDCoCBp
ZiAoYXRoNWtfZ2V0X2J1c190eXBlKGFoKSA9PSBBVEhfQUhCICYmICFpbml0aWFsKSB7Cj4gKyDC
oCDCoCDCoCDCoCDCoCDCoCDCoCAvKiBXYWtldXAgdGhlIGRldmljZSAqLwo+ICsgwqAgwqAgwqAg
wqAgwqAgwqAgwqAgcmV0ID0gYXRoNWtfaHdfc2V0X3Bvd2VyKGFoLCBBUjVLX1BNX0FXQUtFLCB0
cnVlLCAwKTsKPiArIMKgIMKgIMKgIMKgIMKgIMKgIMKgIGlmIChyZXQpIHsKPiArIMKgIMKgIMKg
IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIEFUSDVLX0VSUihhaC0+YWhfc2MsICJmYWlsZWQgdG8g
d2FrZXVwIHRoZSBNQUMgQ2hpcFxuIik7Cj4gKyDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoCByZXR1cm4gcmV0Owo+ICsgwqAgwqAgwqAgwqAgwqAgwqAgwqAgfQo+IMKgIMKgIMKgIMKg
fQo+CgpZb3Ugb25seSBjYWxsIGF0aDVrX2h3X3NldF9wb3dlciBmb3IgQUhCIGRldmljZXMgdGhp
cyB3YXkgIQoKPiDCoCDCoCDCoCDCoC8qCj4gwqAgwqAgwqAgwqAgKiBQdXQgY2hpcHNldCBvbiB3
YXJtIHJlc2V0Li4uCj4gwqAgwqAgwqAgwqAgKgo+IC0gwqAgwqAgwqAgwqAqIE5vdGU6IHB1dHRp
bmcgUENJIGNvcmUgb24gd2FybSByZXNldCBvbiBQQ0ktRSBjYXJkcwo+IC0gwqAgwqAgwqAgwqAq
IHJlc3VsdHMgY2FyZCB0byBoYW5nIGFuZCBhbHdheXMgcmV0dXJuIDB4ZmZmZi4uLiBzbwo+IC0g
wqAgwqAgwqAgwqAqIHdlIGluZ29yZSB0aGF0IGZsYWcgZm9yIFBDSS1FIGNhcmRzLiBPbiBQQ0kg
Y2FyZHMKPiAtIMKgIMKgIMKgIMKgKiB0aGlzIGZsYWcgZ2V0cyBjbGVhcmVkIGFmdGVyIDY0IFBD
SSBjbG9ja3MuCj4gwqAgwqAgwqAgwqAgKi8KPiAtIMKgIMKgIMKgIGJ1c19mbGFncyA9IChwZGV2
ICYmIHBkZXYtPmlzX3BjaWUpID8gMCA6IEFSNUtfUkVTRVRfQ1RMX1BDSTsKPiArIMKgIMKgIMKg
IGlmIChhdGg1a19nZXRfYnVzX3R5cGUoYWgpID09IEFUSF9BSEIpIHsKPiArIMKgIMKgIMKgIMKg
IMKgIMKgIMKgIC8qIFJlc2V0IE1BQyBvbiBXaVNvYyBkZXZpY2VzICovCj4gKyDCoCDCoCDCoCDC
oCDCoCDCoCDCoCBidXNfZmxhZ3MgPSAoaW5pdGlhbCkgPyBBUjVLX1JFU0VUX0NUTF9NQUMgOiAw
Owo+ICsgwqAgwqAgwqAgfSBlbHNlIHsKPiArIMKgIMKgIMKgIMKgIMKgIMKgIMKgIC8qIE5vdGU6
IHB1dHRpbmcgUENJIGNvcmUgb24gd2FybSByZXNldCBvbiBQQ0ktRSBjYXJkcwo+ICsgwqAgwqAg
wqAgwqAgwqAgwqAgwqAgwqAqIHJlc3VsdHMgY2FyZCB0byBoYW5nIGFuZCBhbHdheXMgcmV0dXJu
IDB4ZmZmZi4uLiBzbwo+ICsgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAqIHdlIGluZ29yZSB0aGF0
IGZsYWcgZm9yIFBDSS1FIGNhcmRzLiBPbiBQQ0kgY2FyZHMKPiArIMKgIMKgIMKgIMKgIMKgIMKg
IMKgIMKgKiB0aGlzIGZsYWcgZ2V0cyBjbGVhcmVkIGFmdGVyIDY0IFBDSSBjbG9ja3MuCj4gKyDC
oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCovCj4gKyDCoCDCoCDCoCDCoCDCoCDCoCDCoCBidXNfZmxh
Z3MgPSAocGRldiAmJiBwZGV2LT5pc19wY2llKSA/IDAgOiBBUjVLX1JFU0VUX0NUTF9QQ0k7Cj4g
KyDCoCDCoCDCoCB9Cj4KClRoaXMgaXMgd3JvbmcuLi4KI2RlZmluZSBBUjVLX1JFU0VUX0NUTF9N
QUMgICAgICAweDAwMDAwMDA0ICAgICAgLyogTUFDIHJlc2V0CihQQ1UrQmFzZWJhbmQgPykgWzUy
MTBdICovCnRoaXMgYml0IHdhcyBvbmx5IGF2YWlsYWJsZSBvbiBlYXJsaWVyIGNoaXBzLiBUbyBy
ZXNldCBtYWMgb24gbGF0ZXIKY2hpcHMgKFdpU29DIHRvbykgeW91IG5lZWQgdG8gdXNlCkFSNUtf
UkVTRVRfQ1RMX1BDVSAgYW5kIHdlIGFscmVhZHkgZG8gdGhhdCBiZWxvdy4KClRoaXMgaXMgc29t
ZXRoaW5nIEkgaGF2ZSB0byBjbGVhbiB1cCBhY3R1YWxseSwgYml0IDAgaXMgcmVzZXQgbWFjCihi
b3RoIFBDVSArIERNQSkgYW5kIGJpdCAxIHJlc2V0cyBCYXNlYmFuZC4gTm90ZSB0aGVyZSBpcyBw
b29yCmRvY3VtZW50YXRpb24gb24gdGhhdCwgZG9jdW1lbnRhdGlvbiBvbiBBUjIzMTcgZWcuIHNh
eXMgbWFjIHJlc2V0IGZvcgpiaXQgMCBhbmQgIndhcm0gcmVzZXQgdG8gYmFzZWJhbmQgbG9naWMi
IGZvciBiaXQgMSAod2hpY2ggaXMgY29ycmVjdCkKYnV0IG9uIGRlc2NyaXB0aW9uIGZvciBiaXQg
MSBzYXlzICJQQ1UgYW5kIERNQSBidXQgbm90IGJhc2ViYW5kIgoodGhhdCdzIGFjdHVhbGx5IHRo
ZSBkZXNjcmlwdGlvbiBvZiBiaXQgMCkgYW5kIGFib3ZlIHNheXMgImluIG9yZGVyIHRvCnJlc2V0
IGJvdGggYmFzZWJhbmQgYW5kIG1hYyBhbmQgcGNpIHdyaXRlIDB4MTMiICgweDEwIGlzIHBjaSkg
dGhhdApkb2Vzbid0IG1ha2Ugc2Vuc2UgYmVjYXVzZSBhY2NvcmRpbmcgdG8gZGVzY3JpcHRpb25z
IG5vbmUgb2YgdGhlIDIKZmlyc3QgYml0cyByZXNldHMgYmFzZWJhbmQgOlAgSWYgeW91IGdvIG9u
IEFSNTIxMywgZG9jdW1lbnRhdGlvbiBpcwpjb3JyZWN0LCBpdCBzYXlzIHRoYXQgYml0IDAgaXMg
Zm9yIFBDVSBhbmQgRE1BIGFuZCBiaXQgMSBpcyBmb3IKYmFzZWJhbmQgYW5kIHRoYXQgYWxzbyB3
b3JrcyBvbiBhbGwgcG9zdC01MjExIGNoaXBzLiBUaGF0J3Mgd2h5IEkndmUKcHV0IHRoZSBjb21t
ZW50cyBvbiByZWcuaCwgYWxsIFs1MjEwXSBhcmUgb25seSBhdmFpbGFibGUgb24gQVI1MjEwLApv
bmx5IGJpdHMvcmVnaXN0ZXJzIG1hcmtlZCB3aXRoIFs1MjExK10gYXJlIGF2YWlsYWJsZSBvbiBs
YXRlciBtYWNzLgoKU28gd2hhdCB5b3UgYXJlIHJlYWxseSBkb2luZyBoZXJlIGlzIGFjdGl2YXRl
IGJpdCAzIHRoYXQgaXMgcmVzZXJ2ZWQKYWNjb3JkaW5nIHRvIGRvY3MgYW5kIHNob3VsZCBiZSB6
ZXJvZWQgISBXZSBhbHJlYWR5IGRvIHdoYXQncyBuZWVkZWQKdG8gcmVzZXQgYm90aCBtYWMgYW5k
IGJhc2ViYW5kIGxhdGVyLgoKdmFsICY9IEFSNUtfUkVTRVRfQ1RMX1BDVSB8IEFSNUtfUkVTRVRf
Q1RMX0JBU0VCQU5EOwoKTm90aWNlIHRoYXQgQVI1S19SRVNFVF9DVExfUENVIHwgQVI1S19SRVNF
VF9DVExfQkFTRUJBTkQgPSAweDEzIGFzCmRvY3VtZW50YXRpb24gc3VnZ2VzdHMuCgo+IMKgIMKg
IMKgIMKgaWYgKGFoLT5haF92ZXJzaW9uID09IEFSNUtfQVI1MjEwKSB7Cj4gwqAgwqAgwqAgwqAg
wqAgwqAgwqAgwqByZXQgPSBhdGg1a19od19uaWNfcmVzZXQoYWgsIEFSNUtfUkVTRVRfQ1RMX1BD
VSB8Cj4gQEAgLTUzNiw2ICs1OTEsOSBAQCBzdGF0aWMgdm9pZCBhdGg1a19od19zZXRfc2xlZXBf
Y2xvY2soc3RydWN0IGF0aDVrX2h3ICphaCwgYm9vbCBlbmFibGUpCj4gwqAgwqAgwqAgwqBzdHJ1
Y3QgYXRoNWtfZWVwcm9tX2luZm8gKmVlID0gJmFoLT5haF9jYXBhYmlsaXRpZXMuY2FwX2VlcHJv
bTsKPiDCoCDCoCDCoCDCoHUzMiBzY2FsLCBzcGVuZGluZywgdXNlYzMyOwo+Cj4gKyDCoCDCoCDC
oCBpZiAoYXRoNWtfZ2V0X2J1c190eXBlKGFoKSA9PSBBVEhfQUhCKQo+ICsgwqAgwqAgwqAgwqAg
wqAgwqAgwqAgZW5hYmxlID0gZmFsc2U7Cj4gKwo+IMKgIMKgIMKgIMKgLyogT25seSBzZXQgMzJL
SHogc2V0dGluZ3MgaWYgd2UgaGF2ZSBhbiBleHRlcm5hbAo+IMKgIMKgIMKgIMKgICogMzJLSHog
Y3J5c3RhbCBwcmVzZW50ICovCj4gwqAgwqAgwqAgwqBpZiAoKEFSNUtfRUVQUk9NX0hBUzMyS0ha
Q1JZU1RBTChlZS0+ZWVfbWlzYzEpIHx8Cj4gQEAgLTYwNyw2ICs2NjUsNyBAQCBzdGF0aWMgdm9p
ZCBhdGg1a19od19zZXRfc2xlZXBfY2xvY2soc3RydWN0IGF0aDVrX2h3ICphaCwgYm9vbCBlbmFi
bGUpCj4KPiDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoGlmICgoYWgtPmFoX3JhZGlvID09IEFSNUtf
UkY1MTEyKSB8fAo+IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgKGFoLT5haF9yYWRpbyA9PSBBUjVL
X1JGNTQxMykgfHwKPiArIMKgIMKgIMKgIMKgIMKgIMKgIMKgIChhaC0+YWhfcmFkaW8gPT0gQVI1
S19SRjIzMTYpIHx8Cj4gwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAoYWgtPmFoX21hY192ZXJzaW9u
ID09IChBUjVLX1NSRVZfQVIyNDE3ID4+IDQpKSkKPiDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoCDCoCDCoHNwZW5kaW5nID0gMHgxNDsKPiDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoGVsc2UK
PiBAQCAtNjE0LDcgKzY3Myw5IEBAIHN0YXRpYyB2b2lkIGF0aDVrX2h3X3NldF9zbGVlcF9jbG9j
ayhzdHJ1Y3QgYXRoNWtfaHcgKmFoLCBib29sIGVuYWJsZSkKPiDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoGF0aDVrX2h3X3JlZ193cml0ZShhaCwgc3BlbmRpbmcsIEFSNUtfUEhZX1NQRU5ESU5HKTsK
Pgo+IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgaWYgKChhaC0+YWhfcmFkaW8gPT0gQVI1S19SRjUx
MTIpIHx8Cj4gLSDCoCDCoCDCoCDCoCDCoCDCoCDCoCAoYWgtPmFoX3JhZGlvID09IEFSNUtfUkY1
NDEzKSkKPiArIMKgIMKgIMKgIMKgIMKgIMKgIMKgIChhaC0+YWhfcmFkaW8gPT0gQVI1S19SRjU0
MTMpIHx8Cj4gKyDCoCDCoCDCoCDCoCDCoCDCoCDCoCAoYWgtPmFoX3JhZGlvID09IEFSNUtfUkYy
MzE2KSB8fAo+ICsgwqAgwqAgwqAgwqAgwqAgwqAgwqAgKGFoLT5haF9yYWRpbyA9PSBBUjVLX1JG
MjMxNykpCj4gwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqB1c2VjMzIgPSAzOTsK
PiDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoGVsc2UKPiDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoCDCoCDCoHVzZWMzMiA9IDMxOwo+IEBAIC02NzgsNyArNzM5LDggQEAgc3RhdGljIHZvaWQg
YXRoNWtfaHdfdHdlYWtfaW5pdHZhbF9zZXR0aW5ncyhzdHJ1Y3QgYXRoNWtfaHcgKmFoLAo+Cj4g
wqAgwqAgwqAgwqAvKiBTZXQgZmFzdCBBREMgKi8KPiDCoCDCoCDCoCDCoGlmICgoYWgtPmFoX3Jh
ZGlvID09IEFSNUtfUkY1NDEzKSB8fAo+IC0gwqAgwqAgwqAgKGFoLT5haF9tYWNfdmVyc2lvbiA9
PSAoQVI1S19TUkVWX0FSMjQxNyA+PiA0KSkpIHsKPiArIMKgIMKgIMKgIMKgIMKgIMKgIMKgIChh
aC0+YWhfcmFkaW8gPT0gQVI1S19SRjIzMTcpIHx8Cj4gKyDCoCDCoCDCoCDCoCDCoCDCoCDCoCAo
YWgtPmFoX21hY192ZXJzaW9uID09IChBUjVLX1NSRVZfQVIyNDE3ID4+IDQpKSkgewo+IMKgIMKg
IMKgIMKgIMKgIMKgIMKgIMKgdTMyIGZhc3RfYWRjID0gdHJ1ZTsKPgo+IMKgIMKgIMKgIMKgIMKg
IMKgIMKgIMKgaWYgKGNoYW5uZWwtPmNlbnRlcl9mcmVxID09IDI0NjIgfHwKPiAtLQo+IDEuNy4x
Cj4KPiAtLQo+IFRvIHVuc3Vic2NyaWJlIGZyb20gdGhpcyBsaXN0OiBzZW5kIHRoZSBsaW5lICJ1
bnN1YnNjcmliZSBsaW51eC13aXJlbGVzcyIgaW4KPiB0aGUgYm9keSBvZiBhIG1lc3NhZ2UgdG8g
bWFqb3Jkb21vQHZnZXIua2VybmVsLm9yZwo+IE1vcmUgbWFqb3Jkb21vIGluZm8gYXQgwqBodHRw
Oi8vdmdlci5rZXJuZWwub3JnL21ham9yZG9tby1pbmZvLmh0bWwKPgoKCgotLSAKR1BHIElEOiAw
eEQyMURCMkRCCkFzIHlvdSByZWFkIHRoaXMgcG9zdCBnbG9iYWwgZW50cm9weSByaXNlcy4gSGF2
ZSBGdW4gOy0pCk5pY2sK