LyoKICogTW9kaWZpZWQgaW4gb3JkZXIgdG8ga2VlcCBpdCBjb21wYXRpYmxlIGJvdGggd2l0aCBuZXcgYW5kIG9sZCB2aWRlb3RleHQgSU9DVExzIGJ5CiAqIE1pY2hhZWwgR2VuZyA8bGludXhATWljaGFlbEdlbmcuZGU+CiAqCiAqCUNsZWFuZWQgdXAgdG8gdXNlIGV4aXN0aW5nIHZpZGVvZGV2IGludGVyZmFjZSBhbmQgYWxsb3cgdGhlIGlkZWEKICoJb2YgbXVsdGlwbGUgdGVsZXRleHQgZGVjb2RlcnMgb24gdGhlIHZpZGVvNGxpbnV4IGlmYWNlLiBDaGFuZ2VkIGkyYwogKgl0byBjb3ZlciBhZGRyZXNzaW5nIGNsYXNoZXMgb24gZGV2aWNlIGJ1c3Nlcy4gSXQncyBhbHNvIHJlYnVpbHQgc28KICoJeW91IGNhbiBhZGQgYXJiaXRhcnkgbXVsdGlwbGUgdGVsZXRleHQgZGV2aWNlcyB0byBMaW51eCB2aWRlbzRsaW51eAogKglub3cgKHdlbGwgMzIgYW55d2F5KS4KICoKICoJQWxhbiBDb3ggPEFsYW4uQ294QGxpbnV4Lm9yZz4KICoKICoJVGhlIG9yaWdpbmFsIGRyaXZlciB3YXMgaGVhdmlseSBtb2RpZmllZCB0byBtYXRjaCB0aGUgaTJjIGludGVyZmFjZQogKglJdCB3YXMgdHJ1bmNhdGVkIHRvIHVzZSB0aGUgV2luVFYgYm9hcmRzLCB0b28uCiAqCiAqCUNvcHlyaWdodCAoYykgMTk5OCBSaWNoYXJkIEd1ZW50aGVyIDxyaWNoYXJkLmd1ZW50aGVyQHN0dWRlbnQudW5pLXR1ZWJpbmdlbi5kZT4KICoKICogJElkOiBzYWE1MjQ5LmMsdiAxLjEgMTk5OC8wMy8zMCAyMjoyMzoyMyBhbGFuIEV4cCAkCiAqCiAqCURlcml2ZWQgRnJvbQogKgogKiB2dHguYzoKICogVGhpcyBpcyBhIGxvYWRhYmxlIGNoYXJhY3Rlci1kZXZpY2UtZHJpdmVyIGZvciB2aWRlb3RleHQtaW50ZXJmYWNlcwogKiAoYWthIHRlbGV0ZXh0KS4gUGxlYXNlIGNoZWNrIHRoZSBNYWtlZmlsZS9SRUFETUUgZm9yIGEgbGlzdCBvZiBzdXBwb3J0ZWQKICogaW50ZXJmYWNlcy4KICoKICogQ29weXJpZ2h0IChjKSAxOTk0LTk3IE1hcnRpbiBCdWNrICA8bWFydGluLTIuYnVja0BzdHVkZW50LnVuaS11bG0uZGU+CiAqCiAqCiAqIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5CiAqIGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5CiAqIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlciB2ZXJzaW9uIDIgb2YgdGhlIExpY2Vuc2UsIG9yCiAqIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlCiAqIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIGFsb25nIHdpdGggdGhpcyBwcm9ncmFtOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDU5IFRlbXBsZSBQbGFjZSAtIFN1aXRlIDMzMCwgQm9zdG9uLCBNQSAwMjExMS0xMzA3LAogKiBVU0EuCiAqLwoKI2luY2x1ZGUgPGxpbnV4L21vZHVsZS5oPgojaW5jbHVkZSA8bGludXgva2VybmVsLmg+CiNpbmNsdWRlIDxsaW51eC9zY2hlZC5oPgojaW5jbHVkZSA8bGludXgvbW0uaD4KI2luY2x1ZGUgPGxpbnV4L2Vycm5vLmg+CiNpbmNsdWRlIDxsaW51eC9kZWxheS5oPgojaW5jbHVkZSA8bGludXgvaW9wb3J0Lmg+CiNpbmNsdWRlIDxsaW51eC9zbGFiLmg+CiNpbmNsdWRlIDxsaW51eC9pbml0Lmg+CiNpbmNsdWRlIDxzdGRhcmcuaD4KI2luY2x1ZGUgPGxpbnV4L2kyYy5oPgojaW5jbHVkZSA8bGludXgvdmlkZW90ZXh0Lmg+CiNpbmNsdWRlIDxsaW51eC92aWRlb2Rldi5oPgojaW5jbHVkZSA8bGludXgvbXV0ZXguaD4KCgojaW5jbHVkZSA8YXNtL2lvLmg+CiNpbmNsdWRlIDxhc20vdWFjY2Vzcy5oPgoKI2RlZmluZSBWVFhfVkVSX01BSiAxCiNkZWZpbmUgVlRYX1ZFUl9NSU4gOAoKCgojZGVmaW5lIE5VTV9EQVVTIDQKI2RlZmluZSBOVU1fQlVGUyA4CiNkZWZpbmUgSUZfTkFNRSAiU0FBNTI0OSIKCnN0YXRpYyBjb25zdCBpbnQgZGlzcF9tb2Rlc1s4XVszXSA9CnsKCXsgMHg0NiwgMHgwMywgMHgwMyB9LAkvKiBESVNQT0ZGICovCgl7IDB4NDYsIDB4Y2MsIDB4Y2MgfSwJLyogRElTUE5PUk0gKi8KCXsgMHg0NCwgMHgwZiwgMHgwZiB9LAkvKiBESVNQVFJBTlMgKi8KCXsgMHg0NiwgMHhjYywgMHg0NiB9LAkvKiBESVNQSU5TICovCgl7IDB4NDQsIDB4MDMsIDB4MDMgfSwJLyogRElTUE9GRiwgaW50ZXJsYWNlZCAqLwoJeyAweDQ0LCAweGNjLCAweGNjIH0sCS8qIERJU1BOT1JNLCBpbnRlcmxhY2VkICovCgl7IDB4NDQsIDB4MGYsIDB4MGYgfSwJLyogRElTUFRSQU5TLCBpbnRlcmxhY2VkICovCgl7IDB4NDQsIDB4Y2MsIDB4NDYgfQkvKiBESVNQSU5TLCBpbnRlcmxhY2VkICovCn07CgoKCiNkZWZpbmUgUEFHRV9XQUlUICgzMDAqSFovMTAwMCkJCQkvKiBUaW1lIGJldHdlZW4gcmVxdWVzdGluZyBwYWdlIGFuZCAqLwoJCQkJCQkvKiBjaGVja2luZyBzdGF0dXMgYml0cyAqLwojZGVmaW5lIFBHQlVGX0VYUElSRSAoMTUqSFopCQkJLyogVGltZSB0byB3YWl0IGJlZm9yZSByZXRyYW5zbWl0dGluZyAqLwoJCQkJCQkvKiBwYWdlIHJlZ2FyZGxlc3Mgb2YgaW5mb2JpdHMgKi8KdHlwZWRlZiBzdHJ1Y3QgewoJdTggcGdidWZbVlRYX1ZJUlRVQUxTSVpFXTsJCS8qIFBhZ2UtYnVmZmVyICovCgl1OCBsYXN0c3RhdFsxMF07CQkJLyogTGFzdCB2YWx1ZSBvZiBpbmZvYml0cyBmb3IgREFVICovCgl1OCBzcmVnc1s3XTsJCQkJLyogUGFnZS1yZXF1ZXN0IHJlZ2lzdGVycyAqLwoJdW5zaWduZWQgbG9uZyBleHBpcmU7CQkJLyogVGltZSB3aGVuIHBhZ2Ugd2lsbCBiZSBleHBpcmVkICovCgl1bnNpZ25lZCBjbHJmb3VuZCA6IDE7CQkJLyogVlRYSU9DQ0xSRk9VTkQgaGFzIGJlZW4gY2FsbGVkICovCgl1bnNpZ25lZCBzdG9wcGVkIDogMTsJCQkvKiBWVFhJT0NTVE9QREFVIGhhcyBiZWVuIGNhbGxlZCAqLwp9IHZkYXVfdDsKCnN0cnVjdCBzYWE1MjQ5X2RldmljZQp7Cgl2ZGF1X3QgdmRhdVtOVU1fREFVU107CQkJLyogRGF0YSBmb3IgdmlydHVhbCBEQVVzICh0aGUgNTI0OSBvbmx5IGhhcyBvbmUgKi8KCQkJCQkJLyogcmVhbCBEQVUsIHNvIHdlIGhhdmUgdG8gc2ltdWxhdGUgc29tZSBtb3JlKSAqLwoJaW50IHZ0eF91c2VfY291bnQ7CglpbnQgaXNfc2VhcmNoaW5nW05VTV9EQVVTXTsKCWludCBkaXNwX21vZGU7CglpbnQgdmlydHVhbF9tb2RlOwoJc3RydWN0IGkyY19jbGllbnQgKmNsaWVudDsKCXN0cnVjdCBtdXRleCBsb2NrOwp9OwoKCiNkZWZpbmUgQ0NUV1IgMzQJCS8qIEmyQyB3cml0ZS9yZWFkLWFkZHJlc3Mgb2YgdnR4LWNoaXAgKi8KI2RlZmluZSBDQ1RSRCAzNQojZGVmaW5lIE5PQUNLX1JFUEVBVCAxMAkJLyogUmV0cnkgYWNjZXNzIHRoaXMgbWFueSB0aW1lcyBvbiBmYWlsdXJlICovCiNkZWZpbmUgQ0xFQVJfREVMQVkgKEhaLzIwKQkvKiBUaW1lIHJlcXVpcmVkIHRvIGNsZWFyIGEgcGFnZSAqLwojZGVmaW5lIFJFQURZX1RJTUVPVVQgKDMwKkhaLzEwMDApCS8qIFRpbWUgdG8gd2FpdCBmb3IgcmVhZHkgc2lnbmFsIG9mIEmyQy1idXMgaW50ZXJmYWNlICovCiNkZWZpbmUgSU5JVF9ERUxBWSA1MDAJCS8qIFRpbWUgaW4gdXNlYyB0byB3YWl0IGF0IGluaXRpYWxpemF0aW9uIG9mIENFQSBpbnRlcmZhY2UgKi8KI2RlZmluZSBTVEFSVF9ERUxBWSAxMAkJLyogVGltZSBpbiB1c2VjIHRvIHdhaXQgYmVmb3JlIHN0YXJ0aW5nIHdyaXRlLWN5Y2xlIChDRUEpICovCgojZGVmaW5lIFZUWF9ERVZfTUlOT1IgMAoKLyogR2VuZXJhbCBkZWZpbmVzIGFuZCBkZWJ1Z2dpbmcgc3VwcG9ydCAqLwoKI2lmbmRlZiBGQUxTRQojZGVmaW5lIEZBTFNFIDAKI2RlZmluZSBUUlVFIDEKI2VuZGlmCgojZGVmaW5lIFJFU0NIRUQgZG8geyBjb25kX3Jlc2NoZWQoKTsgfSB3aGlsZSgwKQoKc3RhdGljIHN0cnVjdCB2aWRlb19kZXZpY2Ugc2FhX3RlbXBsYXRlOwkvKiBEZWNsYXJlZCBuZWFyIGJvdHRvbSAqLwoKLyogQWRkcmVzc2VzIHRvIHNjYW4gKi8Kc3RhdGljIHVuc2lnbmVkIHNob3J0IG5vcm1hbF9pMmNbXSA9IHszND4+MSxJMkNfQ0xJRU5UX0VORH07CkkyQ19DTElFTlRfSU5TTU9EOwoKc3RhdGljIHN0cnVjdCBpMmNfY2xpZW50IGNsaWVudF90ZW1wbGF0ZTsKCnN0YXRpYyBpbnQgc2FhNTI0OV9hdHRhY2goc3RydWN0IGkyY19hZGFwdGVyICphZGFwLCBpbnQgYWRkciwgaW50IGtpbmQpCnsKCWludCBwZ2J1ZjsKCWludCBlcnI7CglzdHJ1Y3QgaTJjX2NsaWVudCAqY2xpZW50OwoJc3RydWN0IHZpZGVvX2RldmljZSAqdmQ7CglzdHJ1Y3Qgc2FhNTI0OV9kZXZpY2UgKnQ7CgoJcHJpbnRrKEtFUk5fSU5GTyAic2FhNTI0OTogdGVsZXRleHQgY2hpcCBmb3VuZC5cbiIpOwoJY2xpZW50PWttYWxsb2Moc2l6ZW9mKCpjbGllbnQpLCBHRlBfS0VSTkVMKTsKCWlmKGNsaWVudD09TlVMTCkKCQlyZXR1cm4gLUVOT01FTTsKCWNsaWVudF90ZW1wbGF0ZS5hZGFwdGVyID0gYWRhcDsKCWNsaWVudF90ZW1wbGF0ZS5hZGRyID0gYWRkcjsKCW1lbWNweShjbGllbnQsICZjbGllbnRfdGVtcGxhdGUsIHNpemVvZigqY2xpZW50KSk7Cgl0ID0ga3phbGxvYyhzaXplb2YoKnQpLCBHRlBfS0VSTkVMKTsKCWlmKHQ9PU5VTEwpCgl7CgkJa2ZyZWUoY2xpZW50KTsKCQlyZXR1cm4gLUVOT01FTTsKCX0KCXN0cmxjcHkoY2xpZW50LT5uYW1lLCBJRl9OQU1FLCBJMkNfTkFNRV9TSVpFKTsKCW11dGV4X2luaXQoJnQtPmxvY2spOwoKCS8qCgkgKglOb3cgY3JlYXRlIGEgdmlkZW80bGludXggZGV2aWNlCgkgKi8KCgl2ZCA9IGttYWxsb2Moc2l6ZW9mKHN0cnVjdCB2aWRlb19kZXZpY2UpLCBHRlBfS0VSTkVMKTsKCWlmKHZkPT1OVUxMKQoJewoJCWtmcmVlKHQpOwoJCWtmcmVlKGNsaWVudCk7CgkJcmV0dXJuIC1FTk9NRU07Cgl9CglpMmNfc2V0X2NsaWVudGRhdGEoY2xpZW50LCB2ZCk7CgltZW1jcHkodmQsICZzYWFfdGVtcGxhdGUsIHNpemVvZigqdmQpKTsKCglmb3IgKHBnYnVmID0gMDsgcGdidWYgPCBOVU1fREFVUzsgcGdidWYrKykKCXsKCQltZW1zZXQodC0+dmRhdVtwZ2J1Zl0ucGdidWYsICcgJywgc2l6ZW9mKHQtPnZkYXVbMF0ucGdidWYpKTsKCQltZW1zZXQodC0+dmRhdVtwZ2J1Zl0uc3JlZ3MsIDAsIHNpemVvZih0LT52ZGF1WzBdLnNyZWdzKSk7CgkJbWVtc2V0KHQtPnZkYXVbcGdidWZdLmxhc3RzdGF0LCAwLCBzaXplb2YodC0+dmRhdVswXS5sYXN0c3RhdCkpOwoJCXQtPnZkYXVbcGdidWZdLmV4cGlyZSA9IDA7CgkJdC0+dmRhdVtwZ2J1Zl0uY2xyZm91bmQgPSBUUlVFOwoJCXQtPnZkYXVbcGdidWZdLnN0b3BwZWQgPSBUUlVFOwoJCXQtPmlzX3NlYXJjaGluZ1twZ2J1Zl0gPSBGQUxTRTsKCX0KCXZkLT5wcml2PXQ7CgoKCS8qCgkgKglSZWdpc3RlciBpdAoJICovCgoJaWYoKGVycj12aWRlb19yZWdpc3Rlcl9kZXZpY2UodmQsIFZGTF9UWVBFX1ZUWCwtMSkpPDApCgl7CgkJa2ZyZWUodCk7CgkJa2ZyZWUodmQpOwoJCWtmcmVlKGNsaWVudCk7CgkJcmV0dXJuIGVycjsKCX0KCXQtPmNsaWVudCA9IGNsaWVudDsKCWkyY19hdHRhY2hfY2xpZW50KGNsaWVudCk7CglyZXR1cm4gMDsKfQoKLyoKICoJV2UgZG8gbW9zdCBvZiB0aGUgaGFyZCB3b3JrIHdoZW4gd2UgYmVjb21lIGEgZGV2aWNlIG9uIHRoZSBpMmMuCiAqLwoKc3RhdGljIGludCBzYWE1MjQ5X3Byb2JlKHN0cnVjdCBpMmNfYWRhcHRlciAqYWRhcCkKewoJaWYgKGFkYXAtPmNsYXNzICYgSTJDX0NMQVNTX1RWX0FOQUxPRykKCQlyZXR1cm4gaTJjX3Byb2JlKGFkYXAsICZhZGRyX2RhdGEsIHNhYTUyNDlfYXR0YWNoKTsKCXJldHVybiAwOwp9CgpzdGF0aWMgaW50IHNhYTUyNDlfZGV0YWNoKHN0cnVjdCBpMmNfY2xpZW50ICpjbGllbnQpCnsKCXN0cnVjdCB2aWRlb19kZXZpY2UgKnZkID0gaTJjX2dldF9jbGllbnRkYXRhKGNsaWVudCk7CglpMmNfZGV0YWNoX2NsaWVudChjbGllbnQpOwoJdmlkZW9fdW5yZWdpc3Rlcl9kZXZpY2UodmQpOwoJa2ZyZWUodmQtPnByaXYpOwoJa2ZyZWUodmQpOwoJa2ZyZWUoY2xpZW50KTsKCXJldHVybiAwOwp9CgovKiBuZXcgSTJDIGRyaXZlciBzdXBwb3J0ICovCgpzdGF0aWMgc3RydWN0IGkyY19kcml2ZXIgaTJjX2RyaXZlcl92aWRlb3RleHQgPQp7CgkuZHJpdmVyID0gewoJCS5uYW1lIAk9IElGX05BTUUsCQkvKiBuYW1lICovCgl9LAoJLmlkIAkJPSBJMkNfRFJJVkVSSURfU0FBNTI0OSwgLyogaW4gaTJjLmggKi8KCS5hdHRhY2hfYWRhcHRlciA9IHNhYTUyNDlfcHJvYmUsCgkuZGV0YWNoX2NsaWVudCAgPSBzYWE1MjQ5X2RldGFjaCwKfTsKCnN0YXRpYyBzdHJ1Y3QgaTJjX2NsaWVudCBjbGllbnRfdGVtcGxhdGUgPSB7CgkuZHJpdmVyCQk9ICZpMmNfZHJpdmVyX3ZpZGVvdGV4dCwKCS5uYW1lCQk9ICIodW5zZXQpIiwKfTsKCi8qCiAqCVdhaXQgdGhlIGdpdmVuIG51bWJlciBvZiBqaWZmaWVzICgxMG1zKS4gVGhpcyBjYWxscyB0aGUgc2NoZWR1bGVyLCBzbyB0aGUgYWN0dWFsCiAqCWRlbGF5IG1heSBiZSBsb25nZXIuCiAqLwoKc3RhdGljIHZvaWQgamRlbGF5KHVuc2lnbmVkIGxvbmcgZGVsYXkpCnsKCXNpZ3NldF90IG9sZGJsb2NrZWQgPSBjdXJyZW50LT5ibG9ja2VkOwoKCXNwaW5fbG9ja19pcnEoJmN1cnJlbnQtPnNpZ2hhbmQtPnNpZ2xvY2spOwoJc2lnZmlsbHNldCgmY3VycmVudC0+YmxvY2tlZCk7CglyZWNhbGNfc2lncGVuZGluZygpOwoJc3Bpbl91bmxvY2tfaXJxKCZjdXJyZW50LT5zaWdoYW5kLT5zaWdsb2NrKTsKCW1zbGVlcF9pbnRlcnJ1cHRpYmxlKGppZmZpZXNfdG9fbXNlY3MoZGVsYXkpKTsKCglzcGluX2xvY2tfaXJxKCZjdXJyZW50LT5zaWdoYW5kLT5zaWdsb2NrKTsKCWN1cnJlbnQtPmJsb2NrZWQgPSBvbGRibG9ja2VkOwoJcmVjYWxjX3NpZ3BlbmRpbmcoKTsKCXNwaW5fdW5sb2NrX2lycSgmY3VycmVudC0+c2lnaGFuZC0+c2lnbG9jayk7Cn0KCgovKgogKglJMkMgaW50ZXJmYWNlcwogKi8KCnN0YXRpYyBpbnQgaTJjX3NlbmRidWYoc3RydWN0IHNhYTUyNDlfZGV2aWNlICp0LCBpbnQgcmVnLCBpbnQgY291bnQsIHU4ICpkYXRhKQp7CgljaGFyIGJ1Zls2NF07CgoJYnVmWzBdID0gcmVnOwoJbWVtY3B5KGJ1ZisxLCBkYXRhLCBjb3VudCk7CgoJaWYoaTJjX21hc3Rlcl9zZW5kKHQtPmNsaWVudCwgYnVmLCBjb3VudCsxKT09Y291bnQrMSkKCQlyZXR1cm4gMDsKCXJldHVybiAtMTsKfQoKc3RhdGljIGludCBpMmNfc2VuZGRhdGEoc3RydWN0IHNhYTUyNDlfZGV2aWNlICp0LCAuLi4pCnsKCXVuc2lnbmVkIGNoYXIgYnVmWzY0XTsKCWludCB2OwoJaW50IGN0PTA7Cgl2YV9saXN0IGFyZ3A7Cgl2YV9zdGFydChhcmdwLHQpOwoKCXdoaWxlKCh2PXZhX2FyZyhhcmdwLGludCkpIT0tMSkKCQlidWZbY3QrK109djsKCXJldHVybiBpMmNfc2VuZGJ1Zih0LCBidWZbMF0sIGN0LTEsIGJ1ZisxKTsKfQoKLyogR2V0IGNvdW50IG51bWJlciBvZiBieXRlcyBmcm9tIEmyQy1kZXZpY2UgYXQgYWRkcmVzcyBhZHIsIHN0b3JlIHRoZW0gaW4gYnVmLiBTdGFydCAmIHN0b3AKICogaGFuZHNoYWtpbmcgaXMgZG9uZSBieSB0aGlzIHJvdXRpbmUsIGFjayB3aWxsIGJlIHNlbnQgYWZ0ZXIgdGhlIGxhc3QgYnl0ZSB0byBpbmhpYml0IGZ1cnRoZXIKICogc2VuZGluZyBvZiBkYXRhLiBJZiB1YWNjZXNzIGlzIFRSVUUsIGRhdGEgaXMgd3JpdHRlbiB0byB1c2VyLXNwYWNlIHdpdGggcHV0X3VzZXIuCiAqIFJldHVybnMgLTEgaWYgSbJDLWRldmljZSBkaWRuJ3Qgc2VuZCBhY2tub3dsZWRnZSwgMCBvdGhlcndpc2UKICovCgpzdGF0aWMgaW50IGkyY19nZXRkYXRhKHN0cnVjdCBzYWE1MjQ5X2RldmljZSAqdCwgaW50IGNvdW50LCB1OCAqYnVmKQp7CglpZihpMmNfbWFzdGVyX3JlY3YodC0+Y2xpZW50LCBidWYsIGNvdW50KSE9Y291bnQpCgkJcmV0dXJuIC0xOwoJcmV0dXJuIDA7Cn0KCgovKgogKglTdGFuZGFyZCBjaGFyYWN0ZXItZGV2aWNlLWRyaXZlciBmdW5jdGlvbnMKICovCgpzdGF0aWMgaW50IGRvX3NhYTUyNDlfaW9jdGwoc3RydWN0IGlub2RlICppbm9kZSwgc3RydWN0IGZpbGUgKmZpbGUsCgkJCSAgICB1bnNpZ25lZCBpbnQgY21kLCB2b2lkICphcmcpCnsKCXN0YXRpYyBpbnQgdmlydHVhbF9tb2RlID0gRkFMU0U7CglzdHJ1Y3QgdmlkZW9fZGV2aWNlICp2ZCA9IHZpZGVvX2RldmRhdGEoZmlsZSk7CglzdHJ1Y3Qgc2FhNTI0OV9kZXZpY2UgKnQ9dmQtPnByaXY7CgoJc3dpdGNoKGNtZCkKCXsKCQljYXNlIFZUWElPQ0dFVElORk86CgkJewoJCQl2dHhfaW5mb190ICppbmZvID0gYXJnOwoJCQlpbmZvLT52ZXJzaW9uX21ham9yID0gVlRYX1ZFUl9NQUo7CgkJCWluZm8tPnZlcnNpb25fbWlub3IgPSBWVFhfVkVSX01JTjsKCQkJaW5mby0+bnVtcGFnZXMgPSBOVU1fREFVUzsKCQkJLyppbmZvLT5jY3RfdHlwZSA9IENDVF9UWVBFOyovCgkJCXJldHVybiAwOwoJCX0KCgkJY2FzZSBWVFhJT0NDTFJQQUdFOgoJCXsKCQkJdnR4X3BhZ2VyZXFfdCAqcmVxID0gYXJnOwoKCQkJaWYgKHJlcS0+cGdidWYgPCAwIHx8IHJlcS0+cGdidWYgPj0gTlVNX0RBVVMpCgkJCQlyZXR1cm4gLUVJTlZBTDsKCQkJbWVtc2V0KHQtPnZkYXVbcmVxLT5wZ2J1Zl0ucGdidWYsICcgJywgc2l6ZW9mKHQtPnZkYXVbMF0ucGdidWYpKTsKCQkJdC0+dmRhdVtyZXEtPnBnYnVmXS5jbHJmb3VuZCA9IFRSVUU7CgkJCXJldHVybiAwOwoJCX0KCgkJY2FzZSBWVFhJT0NDTFJGT1VORDoKCQl7CgkJCXZ0eF9wYWdlcmVxX3QgKnJlcSA9IGFyZzsKCgkJCWlmIChyZXEtPnBnYnVmIDwgMCB8fCByZXEtPnBnYnVmID49IE5VTV9EQVVTKQoJCQkJcmV0dXJuIC1FSU5WQUw7CgkJCXQtPnZkYXVbcmVxLT5wZ2J1Zl0uY2xyZm91bmQgPSBUUlVFOwoJCQlyZXR1cm4gMDsKCQl9CgoJCWNhc2UgVlRYSU9DUEFHRVJFUToKCQl7CgkJCXZ0eF9wYWdlcmVxX3QgKnJlcSA9IGFyZzsKCQkJaWYgKCEocmVxLT5wYWdlbWFzayAmIFBHTUFTS19QQUdFKSkKCQkJCXJlcS0+cGFnZSA9IDA7CgkJCWlmICghKHJlcS0+cGFnZW1hc2sgJiBQR01BU0tfSE9VUikpCgkJCQlyZXEtPmhvdXIgPSAwOwoJCQlpZiAoIShyZXEtPnBhZ2VtYXNrICYgUEdNQVNLX01JTlVURSkpCgkJCQlyZXEtPm1pbnV0ZSA9IDA7CgkJCWlmIChyZXEtPnBhZ2UgPCAwIHx8IHJlcS0+cGFnZSA+IDB4OGZmKSAvKiA3RkYgPz8gKi8KCQkJCXJldHVybiAtRUlOVkFMOwoJCQlyZXEtPnBhZ2UgJj0gMHg3ZmY7CgkJCWlmIChyZXEtPmhvdXIgPCAwIHx8IHJlcS0+aG91ciA+IDB4M2YgfHwgcmVxLT5taW51dGUgPCAwIHx8IHJlcS0+bWludXRlID4gMHg3ZiB8fAoJCQkJcmVxLT5wYWdlbWFzayA8IDAgfHwgcmVxLT5wYWdlbWFzayA+PSBQR01BU0tfTUFYIHx8IHJlcS0+cGdidWYgPCAwIHx8IHJlcS0+cGdidWYgPj0gTlVNX0RBVVMpCgkJCQlyZXR1cm4gLUVJTlZBTDsKCQkJdC0+dmRhdVtyZXEtPnBnYnVmXS5zcmVnc1swXSA9IChyZXEtPnBhZ2VtYXNrICYgUEdfSFVORCA/IDB4MTAgOiAwKSB8IChyZXEtPnBhZ2UgLyAweDEwMCk7CgkJCXQtPnZkYXVbcmVxLT5wZ2J1Zl0uc3JlZ3NbMV0gPSAocmVxLT5wYWdlbWFzayAmIFBHX1RFTiA/IDB4MTAgOiAwKSB8ICgocmVxLT5wYWdlIC8gMHgxMCkgJiAweGYpOwoJCQl0LT52ZGF1W3JlcS0+cGdidWZdLnNyZWdzWzJdID0gKHJlcS0+cGFnZW1hc2sgJiBQR19VTklUID8gMHgxMCA6IDApIHwgKHJlcS0+cGFnZSAmIDB4Zik7CgkJCXQtPnZkYXVbcmVxLT5wZ2J1Zl0uc3JlZ3NbM10gPSAocmVxLT5wYWdlbWFzayAmIEhSX1RFTiA/IDB4MTAgOiAwKSB8IChyZXEtPmhvdXIgLyAweDEwKTsKCQkJdC0+dmRhdVtyZXEtPnBnYnVmXS5zcmVnc1s0XSA9IChyZXEtPnBhZ2VtYXNrICYgSFJfVU5JVCA/IDB4MTAgOiAwKSB8IChyZXEtPmhvdXIgJiAweGYpOwoJCQl0LT52ZGF1W3JlcS0+cGdidWZdLnNyZWdzWzVdID0gKHJlcS0+cGFnZW1hc2sgJiBNSU5fVEVOID8gMHgxMCA6IDApIHwgKHJlcS0+bWludXRlIC8gMHgxMCk7CgkJCXQtPnZkYXVbcmVxLT5wZ2J1Zl0uc3JlZ3NbNl0gPSAocmVxLT5wYWdlbWFzayAmIE1JTl9VTklUID8gMHgxMCA6IDApIHwgKHJlcS0+bWludXRlICYgMHhmKTsKCQkJdC0+dmRhdVtyZXEtPnBnYnVmXS5zdG9wcGVkID0gRkFMU0U7CgkJCXQtPnZkYXVbcmVxLT5wZ2J1Zl0uY2xyZm91bmQgPSBUUlVFOwoJCQl0LT5pc19zZWFyY2hpbmdbcmVxLT5wZ2J1Zl0gPSBUUlVFOwoJCQlyZXR1cm4gMDsKCQl9CgoJCWNhc2UgVlRYSU9DR0VUU1RBVDoKCQl7CgkJCXZ0eF9wYWdlcmVxX3QgKnJlcSA9IGFyZzsKCQkJdTggaW5mb2JpdHNbMTBdOwoJCQl2dHhfcGFnZWluZm9fdCBpbmZvOwoJCQlpbnQgYTsKCgkJCWlmIChyZXEtPnBnYnVmIDwgMCB8fCByZXEtPnBnYnVmID49IE5VTV9EQVVTKQoJCQkJcmV0dXJuIC1FSU5WQUw7CgkJCWlmICghdC0+dmRhdVtyZXEtPnBnYnVmXS5zdG9wcGVkKQoJCQl7CgkJCQlpZiAoaTJjX3NlbmRkYXRhKHQsIDIsIDAsIC0xKSB8fAoJCQkJCWkyY19zZW5kYnVmKHQsIDMsIHNpemVvZih0LT52ZGF1WzBdLnNyZWdzKSwgdC0+dmRhdVtyZXEtPnBnYnVmXS5zcmVncykgfHwKCQkJCQlpMmNfc2VuZGRhdGEodCwgOCwgMCwgMjUsIDAsICcgJywgJyAnLCAnICcsICcgJywgJyAnLCAnICcsICcgJywgJyAnLCAnICcsIC0xKSB8fAoJCQkJCWkyY19zZW5kZGF0YSh0LCAyLCAwLCB0LT52ZGF1W3JlcS0+cGdidWZdLnNyZWdzWzBdIHwgOCwgLTEpIHx8CgkJCQkJaTJjX3NlbmRkYXRhKHQsIDgsIDAsIDI1LCAwLCAtMSkpCgkJCQkJcmV0dXJuIC1FSU87CgkJCQlqZGVsYXkoUEFHRV9XQUlUKTsKCQkJCWlmIChpMmNfZ2V0ZGF0YSh0LCAxMCwgaW5mb2JpdHMpKQoJCQkJCXJldHVybiAtRUlPOwoKCQkJCWlmICghKGluZm9iaXRzWzhdICYgMHgxMCkgJiYgIShpbmZvYml0c1s3XSAmIDB4ZjApICYmCS8qIGNoZWNrIEZPVU5ELWJpdCAqLwoJCQkJCShtZW1jbXAoaW5mb2JpdHMsIHQtPnZkYXVbcmVxLT5wZ2J1Zl0ubGFzdHN0YXQsIHNpemVvZihpbmZvYml0cykpIHx8CgkJCQkJdGltZV9hZnRlcl9lcShqaWZmaWVzLCB0LT52ZGF1W3JlcS0+cGdidWZdLmV4cGlyZSkpKQoJCQkJewkJLyogY2hlY2sgaWYgbmV3IHBhZ2UgYXJyaXZlZCAqLwoJCQkJCWlmIChpMmNfc2VuZGRhdGEodCwgOCwgMCwgMCwgMCwgLTEpIHx8CgkJCQkJCWkyY19nZXRkYXRhKHQsIFZUWF9QQUdFU0laRSwgdC0+dmRhdVtyZXEtPnBnYnVmXS5wZ2J1ZikpCgkJCQkJCXJldHVybiAtRUlPOwoJCQkJCXQtPnZkYXVbcmVxLT5wZ2J1Zl0uZXhwaXJlID0gamlmZmllcyArIFBHQlVGX0VYUElSRTsKCQkJCQltZW1zZXQodC0+dmRhdVtyZXEtPnBnYnVmXS5wZ2J1ZiArIFZUWF9QQUdFU0laRSwgJyAnLCBWVFhfVklSVFVBTFNJWkUgLSBWVFhfUEFHRVNJWkUpOwoJCQkJCWlmICh0LT52aXJ0dWFsX21vZGUpCgkJCQkJewoJCQkJCQkvKiBQYWNrZXQgWC8yNCAqLwoJCQkJCQlpZiAoaTJjX3NlbmRkYXRhKHQsIDgsIDAsIDB4MjAsIDAsIC0xKSB8fAoJCQkJCQkJaTJjX2dldGRhdGEodCwgNDAsIHQtPnZkYXVbcmVxLT5wZ2J1Zl0ucGdidWYgKyBWVFhfUEFHRVNJWkUgKyAyMCAqIDQwKSkKCQkJCQkJCXJldHVybiAtRUlPOwoJCQkJCQkvKiBQYWNrZXQgWC8yNy8wICovCgkJCQkJCWlmIChpMmNfc2VuZGRhdGEodCwgOCwgMCwgMHgyMSwgMCwgLTEpIHx8CgkJCQkJCQlpMmNfZ2V0ZGF0YSh0LCA0MCwgdC0+dmRhdVtyZXEtPnBnYnVmXS5wZ2J1ZiArIFZUWF9QQUdFU0laRSArIDE2ICogNDApKQoJCQkJCQkJcmV0dXJuIC1FSU87CgkJCQkJCS8qIFBhY2tldCA4LzMwLzAuLi44LzMwLzE1CgkJCQkJCSAqIEZJWE1FOiBBRkFJSywgdGhlIDUyNDkgZG9lcyBoYW1taW5nLWRlY29kaW5nIGZvciBzb21lIGJ5dGVzIGluIHBhY2tldCA4LzMwLAoJCQkJCQkgKiAgICAgICAgc28gd2Ugc2hvdWxkIHVuZG8gdGhpcyBoZXJlLgoJCQkJCQkgKi8KCQkJCQkJaWYgKGkyY19zZW5kZGF0YSh0LCA4LCAwLCAweDIyLCAwLCAtMSkgfHwKCQkJCQkJCWkyY19nZXRkYXRhKHQsIDQwLCB0LT52ZGF1W3JlcS0+cGdidWZdLnBnYnVmICsgVlRYX1BBR0VTSVpFICsgMjMgKiA0MCkpCgkJCQkJCQlyZXR1cm4gLUVJTzsKCQkJCQl9CgkJCQkJdC0+dmRhdVtyZXEtPnBnYnVmXS5jbHJmb3VuZCA9IEZBTFNFOwoJCQkJCW1lbWNweSh0LT52ZGF1W3JlcS0+cGdidWZdLmxhc3RzdGF0LCBpbmZvYml0cywgc2l6ZW9mKGluZm9iaXRzKSk7CgkJCQl9CgkJCQllbHNlCgkJCQl7CgkJCQkJbWVtY3B5KGluZm9iaXRzLCB0LT52ZGF1W3JlcS0+cGdidWZdLmxhc3RzdGF0LCBzaXplb2YoaW5mb2JpdHMpKTsKCQkJCX0KCQkJfQoJCQllbHNlCgkJCXsKCQkJCW1lbWNweShpbmZvYml0cywgdC0+dmRhdVtyZXEtPnBnYnVmXS5sYXN0c3RhdCwgc2l6ZW9mKGluZm9iaXRzKSk7CgkJCX0KCgkJCWluZm8ucGFnZW51bSA9ICgoaW5mb2JpdHNbOF0gPDwgOCkgJiAweDcwMCkgfCAoKGluZm9iaXRzWzFdIDw8IDQpICYgMHhmMCkgfCAoaW5mb2JpdHNbMF0gJiAweDBmKTsKCQkJaWYgKGluZm8ucGFnZW51bSA8IDB4MTAwKQoJCQkJaW5mby5wYWdlbnVtICs9IDB4ODAwOwoJCQlpbmZvLmhvdXIgPSAoKGluZm9iaXRzWzVdIDw8IDQpICYgMHgzMCkgfCAoaW5mb2JpdHNbNF0gJiAweDBmKTsKCQkJaW5mby5taW51dGUgPSAoKGluZm9iaXRzWzNdIDw8IDQpICYgMHg3MCkgfCAoaW5mb2JpdHNbMl0gJiAweDBmKTsKCQkJaW5mby5jaGFyc2V0ID0gKChpbmZvYml0c1s3XSA+PiAxKSAmIDcpOwoJCQlpbmZvLmRlbGV0ZSA9ICEhKGluZm9iaXRzWzNdICYgOCk7CgkJCWluZm8uaGVhZGxpbmUgPSAhIShpbmZvYml0c1s1XSAmIDQpOwoJCQlpbmZvLnN1YnRpdGxlID0gISEoaW5mb2JpdHNbNV0gJiA4KTsKCQkJaW5mby5zdXBwX2hlYWRlciA9ICEhKGluZm9iaXRzWzZdICYgMSk7CgkJCWluZm8udXBkYXRlID0gISEoaW5mb2JpdHNbNl0gJiAyKTsKCQkJaW5mby5pbnRlcl9zZXEgPSAhIShpbmZvYml0c1s2XSAmIDQpOwoJCQlpbmZvLmRpc19kaXNwID0gISEoaW5mb2JpdHNbNl0gJiA4KTsKCQkJaW5mby5zZXJpYWwgPSAhIShpbmZvYml0c1s3XSAmIDEpOwoJCQlpbmZvLm5vdGZvdW5kID0gISEoaW5mb2JpdHNbOF0gJiAweDEwKTsKCQkJaW5mby5wYmxmID0gISEoaW5mb2JpdHNbOV0gJiAweDIwKTsKCQkJaW5mby5oYW1taW5nID0gMDsKCQkJZm9yIChhID0gMDsgYSA8PSA3OyBhKyspCgkJCXsKCQkJCWlmIChpbmZvYml0c1thXSAmIDB4ZjApCgkJCQl7CgkJCQkJaW5mby5oYW1taW5nID0gMTsKCQkJCQlicmVhazsKCQkJCX0KCQkJfQoJCQlpZiAodC0+dmRhdVtyZXEtPnBnYnVmXS5jbHJmb3VuZCkKCQkJCWluZm8ubm90Zm91bmQgPSAxOwoJCQlpZihjb3B5X3RvX3VzZXIocmVxLT5idWZmZXIsICZpbmZvLCBzaXplb2YodnR4X3BhZ2VpbmZvX3QpKSkKCQkJCXJldHVybiAtRUZBVUxUOwoJCQlpZiAoIWluZm8uaGFtbWluZyAmJiAhaW5mby5ub3Rmb3VuZCkKCQkJewoJCQkJdC0+aXNfc2VhcmNoaW5nW3JlcS0+cGdidWZdID0gRkFMU0U7CgkJCX0KCQkJcmV0dXJuIDA7CgkJfQoKCQljYXNlIFZUWElPQ0dFVFBBR0U6CgkJewoJCQl2dHhfcGFnZXJlcV90ICpyZXEgPSBhcmc7CgkJCWludCBzdGFydCwgZW5kOwoKCQkJaWYgKHJlcS0+cGdidWYgPCAwIHx8IHJlcS0+cGdidWYgPj0gTlVNX0RBVVMgfHwgcmVxLT5zdGFydCA8IDAgfHwKCQkJCXJlcS0+c3RhcnQgPiByZXEtPmVuZCB8fCByZXEtPmVuZCA+PSAodmlydHVhbF9tb2RlID8gVlRYX1ZJUlRVQUxTSVpFIDogVlRYX1BBR0VTSVpFKSkKCQkJCXJldHVybiAtRUlOVkFMOwoJCQlpZihjb3B5X3RvX3VzZXIocmVxLT5idWZmZXIsICZ0LT52ZGF1W3JlcS0+cGdidWZdLnBnYnVmW3JlcS0+c3RhcnRdLCByZXEtPmVuZCAtIHJlcS0+c3RhcnQgKyAxKSkKCQkJCXJldHVybiAtRUZBVUxUOwoKCQkJIC8qCgkJCSAgKglBbHdheXMgcmVhZCB0aGUgdGltZSBkaXJlY3RseSBmcm9tIFNBQTUyNDkKCQkJICAqLwoKCQkJaWYgKHJlcS0+c3RhcnQgPD0gMzkgJiYgcmVxLT5lbmQgPj0gMzIpCgkJCXsKCQkJCWludCBsZW47CgkJCQljaGFyIGJ1ZlsxNl07CgkJCQlzdGFydCA9IG1heChyZXEtPnN0YXJ0LCAzMik7CgkJCQllbmQgPSBtaW4ocmVxLT5lbmQsIDM5KTsKCQkJCWxlbj1lbmQtc3RhcnQrMTsKCQkJCWlmIChpMmNfc2VuZGRhdGEodCwgOCwgMCwgMCwgc3RhcnQsIC0xKSB8fAoJCQkJCWkyY19nZXRkYXRhKHQsIGxlbiwgYnVmKSkKCQkJCQlyZXR1cm4gLUVJTzsKCQkJCWlmKGNvcHlfdG9fdXNlcihyZXEtPmJ1ZmZlcitzdGFydC1yZXEtPnN0YXJ0LCBidWYsIGxlbikpCgkJCQkJcmV0dXJuIC1FRkFVTFQ7CgkJCX0KCQkJLyogSW5zZXJ0IHRoZSBjdXJyZW50IGhlYWRlciBpZiBEQVUgaXMgc3RpbGwgc2VhcmNoaW5nIGZvciBhIHBhZ2UgKi8KCQkJaWYgKHJlcS0+c3RhcnQgPD0gMzEgJiYgcmVxLT5lbmQgPj0gNyAmJiB0LT5pc19zZWFyY2hpbmdbcmVxLT5wZ2J1Zl0pCgkJCXsKCQkJCWNoYXIgYnVmWzMyXTsKCQkJCWludCBsZW47CgkJCQlzdGFydCA9IG1heChyZXEtPnN0YXJ0LCA3KTsKCQkJCWVuZCA9IG1pbihyZXEtPmVuZCwgMzEpOwoJCQkJbGVuPWVuZC1zdGFydCsxOwoJCQkJaWYgKGkyY19zZW5kZGF0YSh0LCA4LCAwLCAwLCBzdGFydCwgLTEpIHx8CgkJCQkJaTJjX2dldGRhdGEodCwgbGVuLCBidWYpKQoJCQkJCXJldHVybiAtRUlPOwoJCQkJaWYoY29weV90b191c2VyKHJlcS0+YnVmZmVyK3N0YXJ0LXJlcS0+c3RhcnQsIGJ1ZiwgbGVuKSkKCQkJCQlyZXR1cm4gLUVGQVVMVDsKCQkJfQoJCQlyZXR1cm4gMDsKCQl9CgoJCWNhc2UgVlRYSU9DU1RPUERBVToKCQl7CgkJCXZ0eF9wYWdlcmVxX3QgKnJlcSA9IGFyZzsKCgkJCWlmIChyZXEtPnBnYnVmIDwgMCB8fCByZXEtPnBnYnVmID49IE5VTV9EQVVTKQoJCQkJcmV0dXJuIC1FSU5WQUw7CgkJCXQtPnZkYXVbcmVxLT5wZ2J1Zl0uc3RvcHBlZCA9IFRSVUU7CgkJCXQtPmlzX3NlYXJjaGluZ1tyZXEtPnBnYnVmXSA9IEZBTFNFOwoJCQlyZXR1cm4gMDsKCQl9CgoJCWNhc2UgVlRYSU9DUFVUUEFHRToKCQljYXNlIFZUWElPQ1NFVERJU1A6CgkJY2FzZSBWVFhJT0NQVVRTVEFUOgoJCQlyZXR1cm4gMDsKCgkJY2FzZSBWVFhJT0NDTFJDQUNIRToKCQl7CgkJCWlmIChpMmNfc2VuZGRhdGEodCwgMCwgTlVNX0RBVVMsIDAsIDgsIC0xKSB8fCBpMmNfc2VuZGRhdGEodCwgMTEsCgkJCQknICcsJyAnLCcgJywnICcsJyAnLCcgJywnICcsJyAnLCcgJywnICcsJyAnLCcgJywKCQkJCScgJywnICcsJyAnLCcgJywnICcsJyAnLCcgJywnICcsJyAnLCcgJywnICcsJyAnLCAtMSkpCgkJCQlyZXR1cm4gLUVJTzsKCQkJaWYgKGkyY19zZW5kZGF0YSh0LCAzLCAweDIwLCAtMSkpCgkJCQlyZXR1cm4gLUVJTzsKCQkJamRlbGF5KDEwICogQ0xFQVJfREVMQVkpOwkJCS8qIEkgaGF2ZSBubyBpZGVhIGhvdyBsb25nIHdlIGhhdmUgdG8gd2FpdCBoZXJlICovCgkJCXJldHVybiAwOwoJCX0KCgkJY2FzZSBWVFhJT0NTRVRWSVJUOgoJCXsKCQkJLyogVGhlIFNBQTUyNDkgaGFzIHZpcnR1YWwtcm93IHJlY2VwdGlvbiB0dXJuZWQgb24gYWx3YXlzICovCgkJCXQtPnZpcnR1YWxfbW9kZSA9IChpbnQpKGxvbmcpYXJnOwoJCQlyZXR1cm4gMDsKCQl9Cgl9CglyZXR1cm4gLUVJTlZBTDsKfQoKLyoKICogVHJhbnNsYXRlcyBvbGQgdnR4IElPQ1RMcyB0byBuZXcgb25lcwogKgogKiBUaGlzIGtlZXBzIG5ldyBrZXJuZWwgdmVyc2lvbnMgY29tcGF0aWJsZSB3aXRoIG9sZCB1c2Vyc3BhY2UgcHJvZ3JhbXMuCiAqLwpzdGF0aWMgaW5saW5lIHVuc2lnbmVkIGludCB2dHhfZml4X2NvbW1hbmQodW5zaWduZWQgaW50IGNtZCkKewoJc3dpdGNoIChjbWQpIHsKCWNhc2UgVlRYSU9DR0VUSU5GT19PTEQ6CgkJY21kID0gVlRYSU9DR0VUSU5GTzsKCQlicmVhazsKCWNhc2UgVlRYSU9DQ0xSUEFHRV9PTEQ6CgkJY21kID0gVlRYSU9DQ0xSUEFHRTsKCQlicmVhazsKCWNhc2UgVlRYSU9DQ0xSRk9VTkRfT0xEOgoJCWNtZCA9IFZUWElPQ0NMUkZPVU5EOwoJCWJyZWFrOwoJY2FzZSBWVFhJT0NQQUdFUkVRX09MRDoKCQljbWQgPSBWVFhJT0NQQUdFUkVROwoJCWJyZWFrOwoJY2FzZSBWVFhJT0NHRVRTVEFUX09MRDoKCQljbWQgPSBWVFhJT0NHRVRTVEFUOwoJCWJyZWFrOwoJY2FzZSBWVFhJT0NHRVRQQUdFX09MRDoKCQljbWQgPSBWVFhJT0NHRVRQQUdFOwoJCWJyZWFrOwoJY2FzZSBWVFhJT0NTVE9QREFVX09MRDoKCQljbWQgPSBWVFhJT0NTVE9QREFVOwoJCWJyZWFrOwoJY2FzZSBWVFhJT0NQVVRQQUdFX09MRDoKCQljbWQgPSBWVFhJT0NQVVRQQUdFOwoJCWJyZWFrOwoJY2FzZSBWVFhJT0NTRVRESVNQX09MRDoKCQljbWQgPSBWVFhJT0NTRVRESVNQOwoJCWJyZWFrOwoJY2FzZSBWVFhJT0NQVVRTVEFUX09MRDoKCQljbWQgPSBWVFhJT0NQVVRTVEFUOwoJCWJyZWFrOwoJY2FzZSBWVFhJT0NDTFJDQUNIRV9PTEQ6CgkJY21kID0gVlRYSU9DQ0xSQ0FDSEU7CgkJYnJlYWs7CgljYXNlIFZUWElPQ1NFVFZJUlRfT0xEOgoJCWNtZCA9IFZUWElPQ1NFVFZJUlQ7CgkJYnJlYWs7Cgl9CglyZXR1cm4gY21kOwp9CgovKgogKglIYW5kbGUgdGhlIGxvY2tpbmcKICovCgpzdGF0aWMgaW50IHNhYTUyNDlfaW9jdGwoc3RydWN0IGlub2RlICppbm9kZSwgc3RydWN0IGZpbGUgKmZpbGUsCgkJCSB1bnNpZ25lZCBpbnQgY21kLCB1bnNpZ25lZCBsb25nIGFyZykKewoJc3RydWN0IHZpZGVvX2RldmljZSAqdmQgPSB2aWRlb19kZXZkYXRhKGZpbGUpOwoJc3RydWN0IHNhYTUyNDlfZGV2aWNlICp0PXZkLT5wcml2OwoJaW50IGVycjsKCgljbWQgPSB2dHhfZml4X2NvbW1hbmQoY21kKTsKCW11dGV4X2xvY2soJnQtPmxvY2spOwoJZXJyID0gdmlkZW9fdXNlcmNvcHkoaW5vZGUsZmlsZSxjbWQsYXJnLGRvX3NhYTUyNDlfaW9jdGwpOwoJbXV0ZXhfdW5sb2NrKCZ0LT5sb2NrKTsKCXJldHVybiBlcnI7Cn0KCnN0YXRpYyBpbnQgc2FhNTI0OV9vcGVuKHN0cnVjdCBpbm9kZSAqaW5vZGUsIHN0cnVjdCBmaWxlICpmaWxlKQp7CglzdHJ1Y3QgdmlkZW9fZGV2aWNlICp2ZCA9IHZpZGVvX2RldmRhdGEoZmlsZSk7CglzdHJ1Y3Qgc2FhNTI0OV9kZXZpY2UgKnQ9dmQtPnByaXY7CglpbnQgZXJyLHBnYnVmOwoKCWVyciA9IHZpZGVvX2V4Y2x1c2l2ZV9vcGVuKGlub2RlLGZpbGUpOwoJaWYgKGVyciA8IDApCgkJcmV0dXJuIGVycjsKCglpZiAodC0+Y2xpZW50PT1OVUxMKSB7CgkJZXJyID0gLUVOT0RFVjsKCQlnb3RvIGZhaWw7Cgl9CgoJaWYgKGkyY19zZW5kZGF0YSh0LCAwLCAwLCAtMSkgfHwJCS8qIFNlbGVjdCBSMTEgKi8KCQkJCQkJLyogVHVybiBvZmYgcGFyaXR5IGNoZWNrcyAod2UgZG8gdGhpcyBvdXJzZWx2ZXMpICovCgkJaTJjX3NlbmRkYXRhKHQsIDEsIGRpc3BfbW9kZXNbdC0+ZGlzcF9tb2RlXVswXSwgMCwgLTEpIHx8CgkJCQkJCS8qIERpc3BsYXkgVFYtcGljdHVyZSwgbm8gdmlydHVhbCByb3dzICovCgkJaTJjX3NlbmRkYXRhKHQsIDQsIE5VTV9EQVVTLCBkaXNwX21vZGVzW3QtPmRpc3BfbW9kZV1bMV0sIGRpc3BfbW9kZXNbdC0+ZGlzcF9tb2RlXVsyXSwgNywgLTEpKSAvKiBTZXQgZGlzcGxheSB0byBwYWdlIDQgKi8KCgl7CgkJZXJyID0gLUVJTzsKCQlnb3RvIGZhaWw7Cgl9CgoJZm9yIChwZ2J1ZiA9IDA7IHBnYnVmIDwgTlVNX0RBVVM7IHBnYnVmKyspCgl7CgkJbWVtc2V0KHQtPnZkYXVbcGdidWZdLnBnYnVmLCAnICcsIHNpemVvZih0LT52ZGF1WzBdLnBnYnVmKSk7CgkJbWVtc2V0KHQtPnZkYXVbcGdidWZdLnNyZWdzLCAwLCBzaXplb2YodC0+dmRhdVswXS5zcmVncykpOwoJCW1lbXNldCh0LT52ZGF1W3BnYnVmXS5sYXN0c3RhdCwgMCwgc2l6ZW9mKHQtPnZkYXVbMF0ubGFzdHN0YXQpKTsKCQl0LT52ZGF1W3BnYnVmXS5leHBpcmUgPSAwOwoJCXQtPnZkYXVbcGdidWZdLmNscmZvdW5kID0gVFJVRTsKCQl0LT52ZGF1W3BnYnVmXS5zdG9wcGVkID0gVFJVRTsKCQl0LT5pc19zZWFyY2hpbmdbcGdidWZdID0gRkFMU0U7Cgl9Cgl0LT52aXJ0dWFsX21vZGU9RkFMU0U7CglyZXR1cm4gMDsKCiBmYWlsOgoJdmlkZW9fZXhjbHVzaXZlX3JlbGVhc2UoaW5vZGUsZmlsZSk7CglyZXR1cm4gZXJyOwp9CgoKCnN0YXRpYyBpbnQgc2FhNTI0OV9yZWxlYXNlKHN0cnVjdCBpbm9kZSAqaW5vZGUsIHN0cnVjdCBmaWxlICpmaWxlKQp7CglzdHJ1Y3QgdmlkZW9fZGV2aWNlICp2ZCA9IHZpZGVvX2RldmRhdGEoZmlsZSk7CglzdHJ1Y3Qgc2FhNTI0OV9kZXZpY2UgKnQ9dmQtPnByaXY7CglpMmNfc2VuZGRhdGEodCwgMSwgMHgyMCwgLTEpOwkJLyogVHVybiBvZmYgQ0NUICovCglpMmNfc2VuZGRhdGEodCwgNSwgMywgMywgLTEpOwkJLyogVHVybiBvZmYgVFYtZGlzcGxheSAqLwoJdmlkZW9fZXhjbHVzaXZlX3JlbGVhc2UoaW5vZGUsZmlsZSk7CglyZXR1cm4gMDsKfQoKc3RhdGljIGludCBfX2luaXQgaW5pdF9zYWFfNTI0OSAodm9pZCkKewoJcHJpbnRrKEtFUk5fSU5GTyAiU0FBNTI0OSBkcml2ZXIgKCIgSUZfTkFNRSAiIGludGVyZmFjZSkgZm9yIFZpZGVvVGV4dCB2ZXJzaW9uICVkLiVkXG4iLAoJCQlWVFhfVkVSX01BSiwgVlRYX1ZFUl9NSU4pOwoJcmV0dXJuIGkyY19hZGRfZHJpdmVyKCZpMmNfZHJpdmVyX3ZpZGVvdGV4dCk7Cn0KCnN0YXRpYyB2b2lkIF9fZXhpdCBjbGVhbnVwX3NhYV81MjQ5ICh2b2lkKQp7CglpMmNfZGVsX2RyaXZlcigmaTJjX2RyaXZlcl92aWRlb3RleHQpOwp9Cgptb2R1bGVfaW5pdChpbml0X3NhYV81MjQ5KTsKbW9kdWxlX2V4aXQoY2xlYW51cF9zYWFfNTI0OSk7CgpzdGF0aWMgc3RydWN0IGZpbGVfb3BlcmF0aW9ucyBzYWFfZm9wcyA9IHsKCS5vd25lcgkJPSBUSElTX01PRFVMRSwKCS5vcGVuCQk9IHNhYTUyNDlfb3BlbiwKCS5yZWxlYXNlICAgICAgIAk9IHNhYTUyNDlfcmVsZWFzZSwKCS5pb2N0bCAgICAgICAgICA9IHNhYTUyNDlfaW9jdGwsCgkuY29tcGF0X2lvY3RsCT0gdjRsX2NvbXBhdF9pb2N0bDMyLAoJLmxsc2VlayAgICAgICAgID0gbm9fbGxzZWVrLAp9OwoKc3RhdGljIHN0cnVjdCB2aWRlb19kZXZpY2Ugc2FhX3RlbXBsYXRlID0KewoJLm93bmVyCQk9IFRISVNfTU9EVUxFLAoJLm5hbWUJCT0gSUZfTkFNRSwKCS50eXBlCQk9IFZJRF9UWVBFX1RFTEVURVhULAkvKnwgVklEX1RZUEVfVFVORVIgPz8gKi8KCS5oYXJkd2FyZQk9IFZJRF9IQVJEV0FSRV9TQUE1MjQ5LAoJLmZvcHMgICAgICAgICAgID0gJnNhYV9mb3BzLAp9OwoKTU9EVUxFX0xJQ0VOU0UoIkdQTCIpOwo=