LyoKICogTW9kaWZpZWQgaW4gb3JkZXIgdG8ga2VlcCBpdCBjb21wYXRpYmxlIGJvdGggd2l0aCBuZXcgYW5kIG9sZCB2aWRlb3RleHQgSU9DVExzIGJ5CiAqIE1pY2hhZWwgR2VuZyA8bGludXhATWljaGFlbEdlbmcuZGU+CiAqCiAqCUNsZWFuZWQgdXAgdG8gdXNlIGV4aXN0aW5nIHZpZGVvZGV2IGludGVyZmFjZSBhbmQgYWxsb3cgdGhlIGlkZWEKICoJb2YgbXVsdGlwbGUgdGVsZXRleHQgZGVjb2RlcnMgb24gdGhlIHZpZGVvNGxpbnV4IGlmYWNlLiBDaGFuZ2VkIGkyYwogKgl0byBjb3ZlciBhZGRyZXNzaW5nIGNsYXNoZXMgb24gZGV2aWNlIGJ1c3Nlcy4gSXQncyBhbHNvIHJlYnVpbHQgc28KICoJeW91IGNhbiBhZGQgYXJiaXRhcnkgbXVsdGlwbGUgdGVsZXRleHQgZGV2aWNlcyB0byBMaW51eCB2aWRlbzRsaW51eAogKglub3cgKHdlbGwgMzIgYW55d2F5KS4KICoKICoJQWxhbiBDb3ggPEFsYW4uQ294QGxpbnV4Lm9yZz4KICoKICoJVGhlIG9yaWdpbmFsIGRyaXZlciB3YXMgaGVhdmlseSBtb2RpZmllZCB0byBtYXRjaCB0aGUgaTJjIGludGVyZmFjZQogKglJdCB3YXMgdHJ1bmNhdGVkIHRvIHVzZSB0aGUgV2luVFYgYm9hcmRzLCB0b28uCiAqCiAqCUNvcHlyaWdodCAoYykgMTk5OCBSaWNoYXJkIEd1ZW50aGVyIDxyaWNoYXJkLmd1ZW50aGVyQHN0dWRlbnQudW5pLXR1ZWJpbmdlbi5kZT4KICoKICogJElkOiBzYWE1MjQ5LmMsdiAxLjEgMTk5OC8wMy8zMCAyMjoyMzoyMyBhbGFuIEV4cCAkCiAqCiAqCURlcml2ZWQgRnJvbQogKgogKiB2dHguYzoKICogVGhpcyBpcyBhIGxvYWRhYmxlIGNoYXJhY3Rlci1kZXZpY2UtZHJpdmVyIGZvciB2aWRlb3RleHQtaW50ZXJmYWNlcwogKiAoYWthIHRlbGV0ZXh0KS4gUGxlYXNlIGNoZWNrIHRoZSBNYWtlZmlsZS9SRUFETUUgZm9yIGEgbGlzdCBvZiBzdXBwb3J0ZWQKICogaW50ZXJmYWNlcy4KICoKICogQ29weXJpZ2h0IChjKSAxOTk0LTk3IE1hcnRpbiBCdWNrICA8bWFydGluLTIuYnVja0BzdHVkZW50LnVuaS11bG0uZGU+CiAqCiAqCiAqIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5CiAqIGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5CiAqIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlciB2ZXJzaW9uIDIgb2YgdGhlIExpY2Vuc2UsIG9yCiAqIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlCiAqIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIGFsb25nIHdpdGggdGhpcyBwcm9ncmFtOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDU5IFRlbXBsZSBQbGFjZSAtIFN1aXRlIDMzMCwgQm9zdG9uLCBNQSAwMjExMS0xMzA3LAogKiBVU0EuCiAqLwoKI2luY2x1ZGUgPGxpbnV4L21vZHVsZS5oPgojaW5jbHVkZSA8bGludXgva2VybmVsLmg+CiNpbmNsdWRlIDxsaW51eC9zY2hlZC5oPgojaW5jbHVkZSA8bGludXgvbW0uaD4KI2luY2x1ZGUgPGxpbnV4L2Vycm5vLmg+CiNpbmNsdWRlIDxsaW51eC9kZWxheS5oPgojaW5jbHVkZSA8bGludXgvaW9wb3J0Lmg+CiNpbmNsdWRlIDxsaW51eC9zbGFiLmg+CiNpbmNsdWRlIDxsaW51eC9pbml0Lmg+CiNpbmNsdWRlIDxzdGRhcmcuaD4KI2luY2x1ZGUgPGxpbnV4L2kyYy5oPgojaW5jbHVkZSA8bGludXgvdmlkZW90ZXh0Lmg+CiNpbmNsdWRlIDxsaW51eC92aWRlb2Rldi5oPgoKI2luY2x1ZGUgPGFzbS9pby5oPgojaW5jbHVkZSA8YXNtL3VhY2Nlc3MuaD4KCiNkZWZpbmUgVlRYX1ZFUl9NQUogMQojZGVmaW5lIFZUWF9WRVJfTUlOIDgKCgoKI2RlZmluZSBOVU1fREFVUyA0CiNkZWZpbmUgTlVNX0JVRlMgOAojZGVmaW5lIElGX05BTUUgIlNBQTUyNDkiCgpzdGF0aWMgY29uc3QgaW50IGRpc3BfbW9kZXNbOF1bM10gPSAKewoJeyAweDQ2LCAweDAzLCAweDAzIH0sCS8qIERJU1BPRkYgKi8KCXsgMHg0NiwgMHhjYywgMHhjYyB9LAkvKiBESVNQTk9STSAqLwoJeyAweDQ0LCAweDBmLCAweDBmIH0sCS8qIERJU1BUUkFOUyAqLwoJeyAweDQ2LCAweGNjLCAweDQ2IH0sCS8qIERJU1BJTlMgKi8KCXsgMHg0NCwgMHgwMywgMHgwMyB9LAkvKiBESVNQT0ZGLCBpbnRlcmxhY2VkICovCgl7IDB4NDQsIDB4Y2MsIDB4Y2MgfSwJLyogRElTUE5PUk0sIGludGVybGFjZWQgKi8KCXsgMHg0NCwgMHgwZiwgMHgwZiB9LAkvKiBESVNQVFJBTlMsIGludGVybGFjZWQgKi8KCXsgMHg0NCwgMHhjYywgMHg0NiB9CS8qIERJU1BJTlMsIGludGVybGFjZWQgKi8KfTsKCgoKI2RlZmluZSBQQUdFX1dBSVQgKDMwMCpIWi8xMDAwKQkJCS8qIFRpbWUgYmV0d2VlbiByZXF1ZXN0aW5nIHBhZ2UgYW5kICovCgkJCQkJCS8qIGNoZWNraW5nIHN0YXR1cyBiaXRzICovCiNkZWZpbmUgUEdCVUZfRVhQSVJFICgxNSpIWikJCQkvKiBUaW1lIHRvIHdhaXQgYmVmb3JlIHJldHJhbnNtaXR0aW5nICovCgkJCQkJCS8qIHBhZ2UgcmVnYXJkbGVzcyBvZiBpbmZvYml0cyAqLwp0eXBlZGVmIHN0cnVjdCB7Cgl1OCBwZ2J1ZltWVFhfVklSVFVBTFNJWkVdOwkJLyogUGFnZS1idWZmZXIgKi8KCXU4IGxhc3RzdGF0WzEwXTsJCQkvKiBMYXN0IHZhbHVlIG9mIGluZm9iaXRzIGZvciBEQVUgKi8KCXU4IHNyZWdzWzddOwkJCQkvKiBQYWdlLXJlcXVlc3QgcmVnaXN0ZXJzICovCgl1bnNpZ25lZCBsb25nIGV4cGlyZTsJCQkvKiBUaW1lIHdoZW4gcGFnZSB3aWxsIGJlIGV4cGlyZWQgKi8KCXVuc2lnbmVkIGNscmZvdW5kIDogMTsJCQkvKiBWVFhJT0NDTFJGT1VORCBoYXMgYmVlbiBjYWxsZWQgKi8KCXVuc2lnbmVkIHN0b3BwZWQgOiAxOwkJCS8qIFZUWElPQ1NUT1BEQVUgaGFzIGJlZW4gY2FsbGVkICovCn0gdmRhdV90OwoKc3RydWN0IHNhYTUyNDlfZGV2aWNlCnsKCXZkYXVfdCB2ZGF1W05VTV9EQVVTXTsJCQkvKiBEYXRhIGZvciB2aXJ0dWFsIERBVXMgKHRoZSA1MjQ5IG9ubHkgaGFzIG9uZSAqLwoJCQkJCQkvKiByZWFsIERBVSwgc28gd2UgaGF2ZSB0byBzaW11bGF0ZSBzb21lIG1vcmUpICovCglpbnQgdnR4X3VzZV9jb3VudDsKCWludCBpc19zZWFyY2hpbmdbTlVNX0RBVVNdOwoJaW50IGRpc3BfbW9kZTsKCWludCB2aXJ0dWFsX21vZGU7CglzdHJ1Y3QgaTJjX2NsaWVudCAqY2xpZW50OwoJc3RydWN0IHNlbWFwaG9yZSBsb2NrOwp9OwoKCiNkZWZpbmUgQ0NUV1IgMzQJCS8qIEmyQyB3cml0ZS9yZWFkLWFkZHJlc3Mgb2YgdnR4LWNoaXAgKi8KI2RlZmluZSBDQ1RSRCAzNQojZGVmaW5lIE5PQUNLX1JFUEVBVCAxMAkJLyogUmV0cnkgYWNjZXNzIHRoaXMgbWFueSB0aW1lcyBvbiBmYWlsdXJlICovCiNkZWZpbmUgQ0xFQVJfREVMQVkgKEhaLzIwKQkvKiBUaW1lIHJlcXVpcmVkIHRvIGNsZWFyIGEgcGFnZSAqLwojZGVmaW5lIFJFQURZX1RJTUVPVVQgKDMwKkhaLzEwMDApCS8qIFRpbWUgdG8gd2FpdCBmb3IgcmVhZHkgc2lnbmFsIG9mIEmyQy1idXMgaW50ZXJmYWNlICovCiNkZWZpbmUgSU5JVF9ERUxBWSA1MDAJCS8qIFRpbWUgaW4gdXNlYyB0byB3YWl0IGF0IGluaXRpYWxpemF0aW9uIG9mIENFQSBpbnRlcmZhY2UgKi8KI2RlZmluZSBTVEFSVF9ERUxBWSAxMAkJLyogVGltZSBpbiB1c2VjIHRvIHdhaXQgYmVmb3JlIHN0YXJ0aW5nIHdyaXRlLWN5Y2xlIChDRUEpICovCgojZGVmaW5lIFZUWF9ERVZfTUlOT1IgMAoKLyogR2VuZXJhbCBkZWZpbmVzIGFuZCBkZWJ1Z2dpbmcgc3VwcG9ydCAqLwoKI2lmbmRlZiBGQUxTRQojZGVmaW5lIEZBTFNFIDAKI2RlZmluZSBUUlVFIDEKI2VuZGlmCgojZGVmaW5lIFJFU0NIRUQgZG8geyBjb25kX3Jlc2NoZWQoKTsgfSB3aGlsZSgwKQoKc3RhdGljIHN0cnVjdCB2aWRlb19kZXZpY2Ugc2FhX3RlbXBsYXRlOwkvKiBEZWNsYXJlZCBuZWFyIGJvdHRvbSAqLwoKLyogQWRkcmVzc2VzIHRvIHNjYW4gKi8Kc3RhdGljIHVuc2lnbmVkIHNob3J0IG5vcm1hbF9pMmNbXSA9IHszND4+MSxJMkNfQ0xJRU5UX0VORH07CkkyQ19DTElFTlRfSU5TTU9EOwoKc3RhdGljIHN0cnVjdCBpMmNfY2xpZW50IGNsaWVudF90ZW1wbGF0ZTsKCnN0YXRpYyBpbnQgc2FhNTI0OV9hdHRhY2goc3RydWN0IGkyY19hZGFwdGVyICphZGFwLCBpbnQgYWRkciwgaW50IGtpbmQpCnsKCWludCBwZ2J1ZjsKCWludCBlcnI7CglzdHJ1Y3QgaTJjX2NsaWVudCAqY2xpZW50OwoJc3RydWN0IHZpZGVvX2RldmljZSAqdmQ7CglzdHJ1Y3Qgc2FhNTI0OV9kZXZpY2UgKnQ7CgoJcHJpbnRrKEtFUk5fSU5GTyAic2FhNTI0OTogdGVsZXRleHQgY2hpcCBmb3VuZC5cbiIpOwoJY2xpZW50PWttYWxsb2Moc2l6ZW9mKCpjbGllbnQpLCBHRlBfS0VSTkVMKTsKCWlmKGNsaWVudD09TlVMTCkKCQlyZXR1cm4gLUVOT01FTTsKICAgICAgICBjbGllbnRfdGVtcGxhdGUuYWRhcHRlciA9IGFkYXA7CiAgICAgICAgY2xpZW50X3RlbXBsYXRlLmFkZHIgPSBhZGRyOwoJbWVtY3B5KGNsaWVudCwgJmNsaWVudF90ZW1wbGF0ZSwgc2l6ZW9mKCpjbGllbnQpKTsKCXQgPSBrbWFsbG9jKHNpemVvZigqdCksIEdGUF9LRVJORUwpOwoJaWYodD09TlVMTCkKCXsKCQlrZnJlZShjbGllbnQpOwoJCXJldHVybiAtRU5PTUVNOwoJfQoJbWVtc2V0KHQsIDAsIHNpemVvZigqdCkpOwoJc3RybGNweShjbGllbnQtPm5hbWUsIElGX05BTUUsIEkyQ19OQU1FX1NJWkUpOwoJaW5pdF9NVVRFWCgmdC0+bG9jayk7CgkKCS8qCgkgKglOb3cgY3JlYXRlIGEgdmlkZW80bGludXggZGV2aWNlCgkgKi8KCSAKCXZkID0gKHN0cnVjdCB2aWRlb19kZXZpY2UgKilrbWFsbG9jKHNpemVvZihzdHJ1Y3QgdmlkZW9fZGV2aWNlKSwgR0ZQX0tFUk5FTCk7CglpZih2ZD09TlVMTCkKCXsKCQlrZnJlZSh0KTsKCQlrZnJlZShjbGllbnQpOwoJCXJldHVybiAtRU5PTUVNOwoJfQoJaTJjX3NldF9jbGllbnRkYXRhKGNsaWVudCwgdmQpOwoJbWVtY3B5KHZkLCAmc2FhX3RlbXBsYXRlLCBzaXplb2YoKnZkKSk7CgkJCglmb3IgKHBnYnVmID0gMDsgcGdidWYgPCBOVU1fREFVUzsgcGdidWYrKykgCgl7CgkJbWVtc2V0KHQtPnZkYXVbcGdidWZdLnBnYnVmLCAnICcsIHNpemVvZih0LT52ZGF1WzBdLnBnYnVmKSk7CgkJbWVtc2V0KHQtPnZkYXVbcGdidWZdLnNyZWdzLCAwLCBzaXplb2YodC0+dmRhdVswXS5zcmVncykpOwoJCW1lbXNldCh0LT52ZGF1W3BnYnVmXS5sYXN0c3RhdCwgMCwgc2l6ZW9mKHQtPnZkYXVbMF0ubGFzdHN0YXQpKTsKCQl0LT52ZGF1W3BnYnVmXS5leHBpcmUgPSAwOwoJCXQtPnZkYXVbcGdidWZdLmNscmZvdW5kID0gVFJVRTsKCQl0LT52ZGF1W3BnYnVmXS5zdG9wcGVkID0gVFJVRTsKCQl0LT5pc19zZWFyY2hpbmdbcGdidWZdID0gRkFMU0U7Cgl9Cgl2ZC0+cHJpdj10OwkKCSAKCQoJLyoKCSAqCVJlZ2lzdGVyIGl0CgkgKi8KCglpZigoZXJyPXZpZGVvX3JlZ2lzdGVyX2RldmljZSh2ZCwgVkZMX1RZUEVfVlRYLC0xKSk8MCkKCXsKCQlrZnJlZSh0KTsKCQlrZnJlZSh2ZCk7CgkJa2ZyZWUoY2xpZW50KTsKCQlyZXR1cm4gZXJyOwoJfQoJdC0+Y2xpZW50ID0gY2xpZW50OwoJaTJjX2F0dGFjaF9jbGllbnQoY2xpZW50KTsKCXJldHVybiAwOwp9CgovKgogKglXZSBkbyBtb3N0IG9mIHRoZSBoYXJkIHdvcmsgd2hlbiB3ZSBiZWNvbWUgYSBkZXZpY2Ugb24gdGhlIGkyYy4KICovCiAKc3RhdGljIGludCBzYWE1MjQ5X3Byb2JlKHN0cnVjdCBpMmNfYWRhcHRlciAqYWRhcCkKewoJaWYgKGFkYXAtPmNsYXNzICYgSTJDX0NMQVNTX1RWX0FOQUxPRykKCQlyZXR1cm4gaTJjX3Byb2JlKGFkYXAsICZhZGRyX2RhdGEsIHNhYTUyNDlfYXR0YWNoKTsKCXJldHVybiAwOwp9CgpzdGF0aWMgaW50IHNhYTUyNDlfZGV0YWNoKHN0cnVjdCBpMmNfY2xpZW50ICpjbGllbnQpCnsKCXN0cnVjdCB2aWRlb19kZXZpY2UgKnZkID0gaTJjX2dldF9jbGllbnRkYXRhKGNsaWVudCk7CglpMmNfZGV0YWNoX2NsaWVudChjbGllbnQpOwoJdmlkZW9fdW5yZWdpc3Rlcl9kZXZpY2UodmQpOwoJa2ZyZWUodmQtPnByaXYpOwoJa2ZyZWUodmQpOwoJa2ZyZWUoY2xpZW50KTsKCXJldHVybiAwOwp9CgovKiBuZXcgSTJDIGRyaXZlciBzdXBwb3J0ICovCgpzdGF0aWMgc3RydWN0IGkyY19kcml2ZXIgaTJjX2RyaXZlcl92aWRlb3RleHQgPSAKewoJLmRyaXZlciA9IHsKCQkubmFtZSAJPSBJRl9OQU1FLAkJLyogbmFtZSAqLwoJfSwKCS5pZCAJCT0gSTJDX0RSSVZFUklEX1NBQTUyNDksIC8qIGluIGkyYy5oICovCgkuYXR0YWNoX2FkYXB0ZXIgPSBzYWE1MjQ5X3Byb2JlLAoJLmRldGFjaF9jbGllbnQgID0gc2FhNTI0OV9kZXRhY2gsCn07CgpzdGF0aWMgc3RydWN0IGkyY19jbGllbnQgY2xpZW50X3RlbXBsYXRlID0gewoJLmRyaXZlcgkJPSAmaTJjX2RyaXZlcl92aWRlb3RleHQsCgkubmFtZQkJPSAiKHVuc2V0KSIsCn07CgovKgogKglXYWl0IHRoZSBnaXZlbiBudW1iZXIgb2YgamlmZmllcyAoMTBtcykuIFRoaXMgY2FsbHMgdGhlIHNjaGVkdWxlciwgc28gdGhlIGFjdHVhbAogKglkZWxheSBtYXkgYmUgbG9uZ2VyLgogKi8KCnN0YXRpYyB2b2lkIGpkZWxheSh1bnNpZ25lZCBsb25nIGRlbGF5KSAKewoJc2lnc2V0X3Qgb2xkYmxvY2tlZCA9IGN1cnJlbnQtPmJsb2NrZWQ7CgoJc3Bpbl9sb2NrX2lycSgmY3VycmVudC0+c2lnaGFuZC0+c2lnbG9jayk7CglzaWdmaWxsc2V0KCZjdXJyZW50LT5ibG9ja2VkKTsKCXJlY2FsY19zaWdwZW5kaW5nKCk7CglzcGluX3VubG9ja19pcnEoJmN1cnJlbnQtPnNpZ2hhbmQtPnNpZ2xvY2spOwoJbXNsZWVwX2ludGVycnVwdGlibGUoamlmZmllc190b19tc2VjcyhkZWxheSkpOwoKCXNwaW5fbG9ja19pcnEoJmN1cnJlbnQtPnNpZ2hhbmQtPnNpZ2xvY2spOwoJY3VycmVudC0+YmxvY2tlZCA9IG9sZGJsb2NrZWQ7CglyZWNhbGNfc2lncGVuZGluZygpOwoJc3Bpbl91bmxvY2tfaXJxKCZjdXJyZW50LT5zaWdoYW5kLT5zaWdsb2NrKTsKfQoKCi8qCiAqCUkyQyBpbnRlcmZhY2VzCiAqLwogCnN0YXRpYyBpbnQgaTJjX3NlbmRidWYoc3RydWN0IHNhYTUyNDlfZGV2aWNlICp0LCBpbnQgcmVnLCBpbnQgY291bnQsIHU4ICpkYXRhKSAKewoJY2hhciBidWZbNjRdOwoJCglidWZbMF0gPSByZWc7CgltZW1jcHkoYnVmKzEsIGRhdGEsIGNvdW50KTsKCQoJaWYoaTJjX21hc3Rlcl9zZW5kKHQtPmNsaWVudCwgYnVmLCBjb3VudCsxKT09Y291bnQrMSkKCQlyZXR1cm4gMDsKCXJldHVybiAtMTsKfQoKc3RhdGljIGludCBpMmNfc2VuZGRhdGEoc3RydWN0IHNhYTUyNDlfZGV2aWNlICp0LCAuLi4pCnsKCXVuc2lnbmVkIGNoYXIgYnVmWzY0XTsKCWludCB2OwoJaW50IGN0PTA7Cgl2YV9saXN0IGFyZ3A7Cgl2YV9zdGFydChhcmdwLHQpOwoJCgl3aGlsZSgodj12YV9hcmcoYXJncCxpbnQpKSE9LTEpCgkJYnVmW2N0KytdPXY7CglyZXR1cm4gaTJjX3NlbmRidWYodCwgYnVmWzBdLCBjdC0xLCBidWYrMSk7Cn0KCi8qIEdldCBjb3VudCBudW1iZXIgb2YgYnl0ZXMgZnJvbSBJskMtZGV2aWNlIGF0IGFkZHJlc3MgYWRyLCBzdG9yZSB0aGVtIGluIGJ1Zi4gU3RhcnQgJiBzdG9wCiAqIGhhbmRzaGFraW5nIGlzIGRvbmUgYnkgdGhpcyByb3V0aW5lLCBhY2sgd2lsbCBiZSBzZW50IGFmdGVyIHRoZSBsYXN0IGJ5dGUgdG8gaW5oaWJpdCBmdXJ0aGVyCiAqIHNlbmRpbmcgb2YgZGF0YS4gSWYgdWFjY2VzcyBpcyBUUlVFLCBkYXRhIGlzIHdyaXR0ZW4gdG8gdXNlci1zcGFjZSB3aXRoIHB1dF91c2VyLgogKiBSZXR1cm5zIC0xIGlmIEmyQy1kZXZpY2UgZGlkbid0IHNlbmQgYWNrbm93bGVkZ2UsIDAgb3RoZXJ3aXNlCiAqLwoKc3RhdGljIGludCBpMmNfZ2V0ZGF0YShzdHJ1Y3Qgc2FhNTI0OV9kZXZpY2UgKnQsIGludCBjb3VudCwgdTggKmJ1ZikgCnsKCWlmKGkyY19tYXN0ZXJfcmVjdih0LT5jbGllbnQsIGJ1ZiwgY291bnQpIT1jb3VudCkKCQlyZXR1cm4gLTE7CglyZXR1cm4gMDsKfQoKCi8qCiAqCVN0YW5kYXJkIGNoYXJhY3Rlci1kZXZpY2UtZHJpdmVyIGZ1bmN0aW9ucwogKi8KCnN0YXRpYyBpbnQgZG9fc2FhNTI0OV9pb2N0bChzdHJ1Y3QgaW5vZGUgKmlub2RlLCBzdHJ1Y3QgZmlsZSAqZmlsZSwKCQkJICAgIHVuc2lnbmVkIGludCBjbWQsIHZvaWQgKmFyZykKewoJc3RhdGljIGludCB2aXJ0dWFsX21vZGUgPSBGQUxTRTsKCXN0cnVjdCB2aWRlb19kZXZpY2UgKnZkID0gdmlkZW9fZGV2ZGF0YShmaWxlKTsKCXN0cnVjdCBzYWE1MjQ5X2RldmljZSAqdD12ZC0+cHJpdjsKCglzd2l0Y2goY21kKSAKCXsKCQljYXNlIFZUWElPQ0dFVElORk86IAoJCXsKCQkJdnR4X2luZm9fdCAqaW5mbyA9IGFyZzsKCQkJaW5mby0+dmVyc2lvbl9tYWpvciA9IFZUWF9WRVJfTUFKOwoJCQlpbmZvLT52ZXJzaW9uX21pbm9yID0gVlRYX1ZFUl9NSU47CgkJCWluZm8tPm51bXBhZ2VzID0gTlVNX0RBVVM7CgkJCS8qaW5mby0+Y2N0X3R5cGUgPSBDQ1RfVFlQRTsqLwoJCQlyZXR1cm4gMDsKCQl9CgoJCWNhc2UgVlRYSU9DQ0xSUEFHRTogCgkJewoJCQl2dHhfcGFnZXJlcV90ICpyZXEgPSBhcmc7CiAgICAgIAoJCQlpZiAocmVxLT5wZ2J1ZiA8IDAgfHwgcmVxLT5wZ2J1ZiA+PSBOVU1fREFVUykKCQkJCXJldHVybiAtRUlOVkFMOwoJCQltZW1zZXQodC0+dmRhdVtyZXEtPnBnYnVmXS5wZ2J1ZiwgJyAnLCBzaXplb2YodC0+dmRhdVswXS5wZ2J1ZikpOwoJCQl0LT52ZGF1W3JlcS0+cGdidWZdLmNscmZvdW5kID0gVFJVRTsKCQkJcmV0dXJuIDA7CgkJfQoKCQljYXNlIFZUWElPQ0NMUkZPVU5EOiAKCQl7CgkJCXZ0eF9wYWdlcmVxX3QgKnJlcSA9IGFyZzsKICAgICAgCgkJCWlmIChyZXEtPnBnYnVmIDwgMCB8fCByZXEtPnBnYnVmID49IE5VTV9EQVVTKQoJCQkJcmV0dXJuIC1FSU5WQUw7CgkJCXQtPnZkYXVbcmVxLT5wZ2J1Zl0uY2xyZm91bmQgPSBUUlVFOwoJCQlyZXR1cm4gMDsKCQl9CgoJCWNhc2UgVlRYSU9DUEFHRVJFUTogCgkJewoJCQl2dHhfcGFnZXJlcV90ICpyZXEgPSBhcmc7CgkJCWlmICghKHJlcS0+cGFnZW1hc2sgJiBQR01BU0tfUEFHRSkpCgkJCQlyZXEtPnBhZ2UgPSAwOwoJCQlpZiAoIShyZXEtPnBhZ2VtYXNrICYgUEdNQVNLX0hPVVIpKQoJCQkJcmVxLT5ob3VyID0gMDsKCQkJaWYgKCEocmVxLT5wYWdlbWFzayAmIFBHTUFTS19NSU5VVEUpKQoJCQkJcmVxLT5taW51dGUgPSAwOwoJCQlpZiAocmVxLT5wYWdlIDwgMCB8fCByZXEtPnBhZ2UgPiAweDhmZikgLyogN0ZGID8/ICovCgkJCQlyZXR1cm4gLUVJTlZBTDsKCQkJcmVxLT5wYWdlICY9IDB4N2ZmOwoJCQlpZiAocmVxLT5ob3VyIDwgMCB8fCByZXEtPmhvdXIgPiAweDNmIHx8IHJlcS0+bWludXRlIDwgMCB8fCByZXEtPm1pbnV0ZSA+IDB4N2YgfHwKCQkJCXJlcS0+cGFnZW1hc2sgPCAwIHx8IHJlcS0+cGFnZW1hc2sgPj0gUEdNQVNLX01BWCB8fCByZXEtPnBnYnVmIDwgMCB8fCByZXEtPnBnYnVmID49IE5VTV9EQVVTKQoJCQkJcmV0dXJuIC1FSU5WQUw7CgkJCXQtPnZkYXVbcmVxLT5wZ2J1Zl0uc3JlZ3NbMF0gPSAocmVxLT5wYWdlbWFzayAmIFBHX0hVTkQgPyAweDEwIDogMCkgfCAocmVxLT5wYWdlIC8gMHgxMDApOwoJCQl0LT52ZGF1W3JlcS0+cGdidWZdLnNyZWdzWzFdID0gKHJlcS0+cGFnZW1hc2sgJiBQR19URU4gPyAweDEwIDogMCkgfCAoKHJlcS0+cGFnZSAvIDB4MTApICYgMHhmKTsKCQkJdC0+dmRhdVtyZXEtPnBnYnVmXS5zcmVnc1syXSA9IChyZXEtPnBhZ2VtYXNrICYgUEdfVU5JVCA/IDB4MTAgOiAwKSB8IChyZXEtPnBhZ2UgJiAweGYpOwoJCQl0LT52ZGF1W3JlcS0+cGdidWZdLnNyZWdzWzNdID0gKHJlcS0+cGFnZW1hc2sgJiBIUl9URU4gPyAweDEwIDogMCkgfCAocmVxLT5ob3VyIC8gMHgxMCk7CgkJCXQtPnZkYXVbcmVxLT5wZ2J1Zl0uc3JlZ3NbNF0gPSAocmVxLT5wYWdlbWFzayAmIEhSX1VOSVQgPyAweDEwIDogMCkgfCAocmVxLT5ob3VyICYgMHhmKTsKCQkJdC0+dmRhdVtyZXEtPnBnYnVmXS5zcmVnc1s1XSA9IChyZXEtPnBhZ2VtYXNrICYgTUlOX1RFTiA/IDB4MTAgOiAwKSB8IChyZXEtPm1pbnV0ZSAvIDB4MTApOwoJCQl0LT52ZGF1W3JlcS0+cGdidWZdLnNyZWdzWzZdID0gKHJlcS0+cGFnZW1hc2sgJiBNSU5fVU5JVCA/IDB4MTAgOiAwKSB8IChyZXEtPm1pbnV0ZSAmIDB4Zik7CgkJCXQtPnZkYXVbcmVxLT5wZ2J1Zl0uc3RvcHBlZCA9IEZBTFNFOwoJCQl0LT52ZGF1W3JlcS0+cGdidWZdLmNscmZvdW5kID0gVFJVRTsKCQkJdC0+aXNfc2VhcmNoaW5nW3JlcS0+cGdidWZdID0gVFJVRTsKCQkJcmV0dXJuIDA7CgkJfQoKCQljYXNlIFZUWElPQ0dFVFNUQVQ6IAoJCXsKCQkJdnR4X3BhZ2VyZXFfdCAqcmVxID0gYXJnOwoJCQl1OCBpbmZvYml0c1sxMF07CgkJCXZ0eF9wYWdlaW5mb190IGluZm87CgkJCWludCBhOwoKCQkJaWYgKHJlcS0+cGdidWYgPCAwIHx8IHJlcS0+cGdidWYgPj0gTlVNX0RBVVMpCgkJCQlyZXR1cm4gLUVJTlZBTDsKCQkJaWYgKCF0LT52ZGF1W3JlcS0+cGdidWZdLnN0b3BwZWQpIAoJCQl7CgkJCQlpZiAoaTJjX3NlbmRkYXRhKHQsIDIsIDAsIC0xKSB8fAoJCQkJCWkyY19zZW5kYnVmKHQsIDMsIHNpemVvZih0LT52ZGF1WzBdLnNyZWdzKSwgdC0+dmRhdVtyZXEtPnBnYnVmXS5zcmVncykgfHwKCQkJCQlpMmNfc2VuZGRhdGEodCwgOCwgMCwgMjUsIDAsICcgJywgJyAnLCAnICcsICcgJywgJyAnLCAnICcsICcgJywgJyAnLCAnICcsIC0xKSB8fAoJCQkJCWkyY19zZW5kZGF0YSh0LCAyLCAwLCB0LT52ZGF1W3JlcS0+cGdidWZdLnNyZWdzWzBdIHwgOCwgLTEpIHx8CgkJCQkJaTJjX3NlbmRkYXRhKHQsIDgsIDAsIDI1LCAwLCAtMSkpCgkJCQkJcmV0dXJuIC1FSU87CgkJCQlqZGVsYXkoUEFHRV9XQUlUKTsKCQkJCWlmIChpMmNfZ2V0ZGF0YSh0LCAxMCwgaW5mb2JpdHMpKQoJCQkJCXJldHVybiAtRUlPOwoKCQkJCWlmICghKGluZm9iaXRzWzhdICYgMHgxMCkgJiYgIShpbmZvYml0c1s3XSAmIDB4ZjApICYmCS8qIGNoZWNrIEZPVU5ELWJpdCAqLwoJCQkJCShtZW1jbXAoaW5mb2JpdHMsIHQtPnZkYXVbcmVxLT5wZ2J1Zl0ubGFzdHN0YXQsIHNpemVvZihpbmZvYml0cykpIHx8IAoJCQkJCXRpbWVfYWZ0ZXJfZXEoamlmZmllcywgdC0+dmRhdVtyZXEtPnBnYnVmXS5leHBpcmUpKSkKCQkJCXsJCS8qIGNoZWNrIGlmIG5ldyBwYWdlIGFycml2ZWQgKi8KCQkJCQlpZiAoaTJjX3NlbmRkYXRhKHQsIDgsIDAsIDAsIDAsIC0xKSB8fAoJCQkJCQlpMmNfZ2V0ZGF0YSh0LCBWVFhfUEFHRVNJWkUsIHQtPnZkYXVbcmVxLT5wZ2J1Zl0ucGdidWYpKQoJCQkJCQlyZXR1cm4gLUVJTzsKCQkJCQl0LT52ZGF1W3JlcS0+cGdidWZdLmV4cGlyZSA9IGppZmZpZXMgKyBQR0JVRl9FWFBJUkU7CgkJCQkJbWVtc2V0KHQtPnZkYXVbcmVxLT5wZ2J1Zl0ucGdidWYgKyBWVFhfUEFHRVNJWkUsICcgJywgVlRYX1ZJUlRVQUxTSVpFIC0gVlRYX1BBR0VTSVpFKTsKCQkJCQlpZiAodC0+dmlydHVhbF9tb2RlKSAKCQkJCQl7CgkJCQkJCS8qIFBhY2tldCBYLzI0ICovCgkJCQkJCWlmIChpMmNfc2VuZGRhdGEodCwgOCwgMCwgMHgyMCwgMCwgLTEpIHx8CgkJCQkJCQlpMmNfZ2V0ZGF0YSh0LCA0MCwgdC0+dmRhdVtyZXEtPnBnYnVmXS5wZ2J1ZiArIFZUWF9QQUdFU0laRSArIDIwICogNDApKQoJCQkJCQkJcmV0dXJuIC1FSU87CgkJCQkJCS8qIFBhY2tldCBYLzI3LzAgKi8KCQkJCQkJaWYgKGkyY19zZW5kZGF0YSh0LCA4LCAwLCAweDIxLCAwLCAtMSkgfHwKCQkJCQkJCWkyY19nZXRkYXRhKHQsIDQwLCB0LT52ZGF1W3JlcS0+cGdidWZdLnBnYnVmICsgVlRYX1BBR0VTSVpFICsgMTYgKiA0MCkpCgkJCQkJCQlyZXR1cm4gLUVJTzsKCQkJCQkJLyogUGFja2V0IDgvMzAvMC4uLjgvMzAvMTUKCQkJCQkJICogRklYTUU6IEFGQUlLLCB0aGUgNTI0OSBkb2VzIGhhbW1pbmctZGVjb2RpbmcgZm9yIHNvbWUgYnl0ZXMgaW4gcGFja2V0IDgvMzAsCgkJCQkJCSAqICAgICAgICBzbyB3ZSBzaG91bGQgdW5kbyB0aGlzIGhlcmUuCgkJCQkJCSAqLwoJCQkJCQlpZiAoaTJjX3NlbmRkYXRhKHQsIDgsIDAsIDB4MjIsIDAsIC0xKSB8fAoJCQkJCQkJaTJjX2dldGRhdGEodCwgNDAsIHQtPnZkYXVbcmVxLT5wZ2J1Zl0ucGdidWYgKyBWVFhfUEFHRVNJWkUgKyAyMyAqIDQwKSkKCQkJCQkJCXJldHVybiAtRUlPOwoJCQkJCX0KCQkJCQl0LT52ZGF1W3JlcS0+cGdidWZdLmNscmZvdW5kID0gRkFMU0U7CgkJCQkJbWVtY3B5KHQtPnZkYXVbcmVxLT5wZ2J1Zl0ubGFzdHN0YXQsIGluZm9iaXRzLCBzaXplb2YoaW5mb2JpdHMpKTsKCQkJCX0KCQkJCWVsc2UKCQkJCXsKCQkJCQltZW1jcHkoaW5mb2JpdHMsIHQtPnZkYXVbcmVxLT5wZ2J1Zl0ubGFzdHN0YXQsIHNpemVvZihpbmZvYml0cykpOwoJCQkJfQoJCQl9CgkJCWVsc2UKCQkJewoJCQkJbWVtY3B5KGluZm9iaXRzLCB0LT52ZGF1W3JlcS0+cGdidWZdLmxhc3RzdGF0LCBzaXplb2YoaW5mb2JpdHMpKTsKCQkJfQoKCQkJaW5mby5wYWdlbnVtID0gKChpbmZvYml0c1s4XSA8PCA4KSAmIDB4NzAwKSB8ICgoaW5mb2JpdHNbMV0gPDwgNCkgJiAweGYwKSB8IChpbmZvYml0c1swXSAmIDB4MGYpOwoJCQlpZiAoaW5mby5wYWdlbnVtIDwgMHgxMDApCgkJCQlpbmZvLnBhZ2VudW0gKz0gMHg4MDA7CgkJCWluZm8uaG91ciA9ICgoaW5mb2JpdHNbNV0gPDwgNCkgJiAweDMwKSB8IChpbmZvYml0c1s0XSAmIDB4MGYpOwoJCQlpbmZvLm1pbnV0ZSA9ICgoaW5mb2JpdHNbM10gPDwgNCkgJiAweDcwKSB8IChpbmZvYml0c1syXSAmIDB4MGYpOwoJCQlpbmZvLmNoYXJzZXQgPSAoKGluZm9iaXRzWzddID4+IDEpICYgNyk7CgkJCWluZm8uZGVsZXRlID0gISEoaW5mb2JpdHNbM10gJiA4KTsKCQkJaW5mby5oZWFkbGluZSA9ICEhKGluZm9iaXRzWzVdICYgNCk7CgkJCWluZm8uc3VidGl0bGUgPSAhIShpbmZvYml0c1s1XSAmIDgpOwoJCQlpbmZvLnN1cHBfaGVhZGVyID0gISEoaW5mb2JpdHNbNl0gJiAxKTsKCQkJaW5mby51cGRhdGUgPSAhIShpbmZvYml0c1s2XSAmIDIpOwoJCQlpbmZvLmludGVyX3NlcSA9ICEhKGluZm9iaXRzWzZdICYgNCk7CgkJCWluZm8uZGlzX2Rpc3AgPSAhIShpbmZvYml0c1s2XSAmIDgpOwoJCQlpbmZvLnNlcmlhbCA9ICEhKGluZm9iaXRzWzddICYgMSk7CgkJCWluZm8ubm90Zm91bmQgPSAhIShpbmZvYml0c1s4XSAmIDB4MTApOwoJCQlpbmZvLnBibGYgPSAhIShpbmZvYml0c1s5XSAmIDB4MjApOwoJCQlpbmZvLmhhbW1pbmcgPSAwOwoJCQlmb3IgKGEgPSAwOyBhIDw9IDc7IGErKykgCgkJCXsKCQkJCWlmIChpbmZvYml0c1thXSAmIDB4ZjApIAoJCQkJewoJCQkJCWluZm8uaGFtbWluZyA9IDE7CgkJCQkJYnJlYWs7CgkJCQl9CgkJCX0KCQkJaWYgKHQtPnZkYXVbcmVxLT5wZ2J1Zl0uY2xyZm91bmQpCgkJCQlpbmZvLm5vdGZvdW5kID0gMTsKCQkJaWYoY29weV90b191c2VyKHJlcS0+YnVmZmVyLCAmaW5mbywgc2l6ZW9mKHZ0eF9wYWdlaW5mb190KSkpCgkJCQlyZXR1cm4gLUVGQVVMVDsKCQkJaWYgKCFpbmZvLmhhbW1pbmcgJiYgIWluZm8ubm90Zm91bmQpIAoJCQl7CgkJCQl0LT5pc19zZWFyY2hpbmdbcmVxLT5wZ2J1Zl0gPSBGQUxTRTsKCQkJfQoJCQlyZXR1cm4gMDsKCQl9CgoJCWNhc2UgVlRYSU9DR0VUUEFHRTogCgkJewoJCQl2dHhfcGFnZXJlcV90ICpyZXEgPSBhcmc7CgkJCWludCBzdGFydCwgZW5kOwoKCQkJaWYgKHJlcS0+cGdidWYgPCAwIHx8IHJlcS0+cGdidWYgPj0gTlVNX0RBVVMgfHwgcmVxLT5zdGFydCA8IDAgfHwKCQkJCXJlcS0+c3RhcnQgPiByZXEtPmVuZCB8fCByZXEtPmVuZCA+PSAodmlydHVhbF9tb2RlID8gVlRYX1ZJUlRVQUxTSVpFIDogVlRYX1BBR0VTSVpFKSkKCQkJCXJldHVybiAtRUlOVkFMOwoJCQlpZihjb3B5X3RvX3VzZXIocmVxLT5idWZmZXIsICZ0LT52ZGF1W3JlcS0+cGdidWZdLnBnYnVmW3JlcS0+c3RhcnRdLCByZXEtPmVuZCAtIHJlcS0+c3RhcnQgKyAxKSkKCQkJCXJldHVybiAtRUZBVUxUOwoJCQkJCgkJCSAvKiAKCQkJICAqCUFsd2F5cyByZWFkIHRoZSB0aW1lIGRpcmVjdGx5IGZyb20gU0FBNTI0OQoJCQkgICovCgkJCSAgCgkJCWlmIChyZXEtPnN0YXJ0IDw9IDM5ICYmIHJlcS0+ZW5kID49IDMyKSAKCQkJewoJCQkJaW50IGxlbjsKCQkJCWNoYXIgYnVmWzE2XTsgIAoJCQkJc3RhcnQgPSBtYXgocmVxLT5zdGFydCwgMzIpOwoJCQkJZW5kID0gbWluKHJlcS0+ZW5kLCAzOSk7CgkJCQlsZW49ZW5kLXN0YXJ0KzE7CgkJCQlpZiAoaTJjX3NlbmRkYXRhKHQsIDgsIDAsIDAsIHN0YXJ0LCAtMSkgfHwKCQkJCQlpMmNfZ2V0ZGF0YSh0LCBsZW4sIGJ1ZikpCgkJCQkJcmV0dXJuIC1FSU87CgkJCQlpZihjb3B5X3RvX3VzZXIocmVxLT5idWZmZXIrc3RhcnQtcmVxLT5zdGFydCwgYnVmLCBsZW4pKQoJCQkJCXJldHVybiAtRUZBVUxUOwoJCQl9CgkJCS8qIEluc2VydCB0aGUgY3VycmVudCBoZWFkZXIgaWYgREFVIGlzIHN0aWxsIHNlYXJjaGluZyBmb3IgYSBwYWdlICovCgkJCWlmIChyZXEtPnN0YXJ0IDw9IDMxICYmIHJlcS0+ZW5kID49IDcgJiYgdC0+aXNfc2VhcmNoaW5nW3JlcS0+cGdidWZdKSAKCQkJewoJCQkJY2hhciBidWZbMzJdOwoJCQkJaW50IGxlbjsKCQkJCXN0YXJ0ID0gbWF4KHJlcS0+c3RhcnQsIDcpOwoJCQkJZW5kID0gbWluKHJlcS0+ZW5kLCAzMSk7CgkJCQlsZW49ZW5kLXN0YXJ0KzE7CgkJCQlpZiAoaTJjX3NlbmRkYXRhKHQsIDgsIDAsIDAsIHN0YXJ0LCAtMSkgfHwKCQkJCQlpMmNfZ2V0ZGF0YSh0LCBsZW4sIGJ1ZikpCgkJCQkJcmV0dXJuIC1FSU87CgkJCQlpZihjb3B5X3RvX3VzZXIocmVxLT5idWZmZXIrc3RhcnQtcmVxLT5zdGFydCwgYnVmLCBsZW4pKQoJCQkJCXJldHVybiAtRUZBVUxUOwoJCQl9CgkJCXJldHVybiAwOwoJCX0KCgkJY2FzZSBWVFhJT0NTVE9QREFVOiAKCQl7CgkJCXZ0eF9wYWdlcmVxX3QgKnJlcSA9IGFyZzsKCgkJCWlmIChyZXEtPnBnYnVmIDwgMCB8fCByZXEtPnBnYnVmID49IE5VTV9EQVVTKQoJCQkJcmV0dXJuIC1FSU5WQUw7CgkJCXQtPnZkYXVbcmVxLT5wZ2J1Zl0uc3RvcHBlZCA9IFRSVUU7CgkJCXQtPmlzX3NlYXJjaGluZ1tyZXEtPnBnYnVmXSA9IEZBTFNFOwoJCQlyZXR1cm4gMDsKCQl9CgoJCWNhc2UgVlRYSU9DUFVUUEFHRTogCgkJY2FzZSBWVFhJT0NTRVRESVNQOiAKCQljYXNlIFZUWElPQ1BVVFNUQVQ6IAoJCQlyZXR1cm4gMDsKCQkJCgkJY2FzZSBWVFhJT0NDTFJDQUNIRTogCgkJewoJCQlpZiAoaTJjX3NlbmRkYXRhKHQsIDAsIE5VTV9EQVVTLCAwLCA4LCAtMSkgfHwgaTJjX3NlbmRkYXRhKHQsIDExLAoJCQkJJyAnLCcgJywnICcsJyAnLCcgJywnICcsJyAnLCcgJywnICcsJyAnLCcgJywnICcsCgkJCQknICcsJyAnLCcgJywnICcsJyAnLCcgJywnICcsJyAnLCcgJywnICcsJyAnLCcgJywgLTEpKQoJCQkJcmV0dXJuIC1FSU87CgkJCWlmIChpMmNfc2VuZGRhdGEodCwgMywgMHgyMCwgLTEpKQoJCQkJcmV0dXJuIC1FSU87CgkJCWpkZWxheSgxMCAqIENMRUFSX0RFTEFZKTsJCQkvKiBJIGhhdmUgbm8gaWRlYSBob3cgbG9uZyB3ZSBoYXZlIHRvIHdhaXQgaGVyZSAqLwoJCQlyZXR1cm4gMDsKCQl9CgoJCWNhc2UgVlRYSU9DU0VUVklSVDogCgkJewoJCQkvKiBUaGUgU0FBNTI0OSBoYXMgdmlydHVhbC1yb3cgcmVjZXB0aW9uIHR1cm5lZCBvbiBhbHdheXMgKi8KCQkJdC0+dmlydHVhbF9tb2RlID0gKGludCkobG9uZylhcmc7CgkJCXJldHVybiAwOwoJCX0KCX0KCXJldHVybiAtRUlOVkFMOwp9CgovKgogKiBUcmFuc2xhdGVzIG9sZCB2dHggSU9DVExzIHRvIG5ldyBvbmVzCiAqCiAqIFRoaXMga2VlcHMgbmV3IGtlcm5lbCB2ZXJzaW9ucyBjb21wYXRpYmxlIHdpdGggb2xkIHVzZXJzcGFjZSBwcm9ncmFtcy4KICovCnN0YXRpYyBpbmxpbmUgdW5zaWduZWQgaW50IHZ0eF9maXhfY29tbWFuZCh1bnNpZ25lZCBpbnQgY21kKQp7Cglzd2l0Y2ggKGNtZCkgewoJY2FzZSBWVFhJT0NHRVRJTkZPX09MRDoKCQljbWQgPSBWVFhJT0NHRVRJTkZPOwoJCWJyZWFrOwoJY2FzZSBWVFhJT0NDTFJQQUdFX09MRDoKCQljbWQgPSBWVFhJT0NDTFJQQUdFOwoJCWJyZWFrOwoJY2FzZSBWVFhJT0NDTFJGT1VORF9PTEQ6CgkJY21kID0gVlRYSU9DQ0xSRk9VTkQ7CgkJYnJlYWs7CgljYXNlIFZUWElPQ1BBR0VSRVFfT0xEOgoJCWNtZCA9IFZUWElPQ1BBR0VSRVE7CgkJYnJlYWs7CgljYXNlIFZUWElPQ0dFVFNUQVRfT0xEOgoJCWNtZCA9IFZUWElPQ0dFVFNUQVQ7CgkJYnJlYWs7CgljYXNlIFZUWElPQ0dFVFBBR0VfT0xEOgoJCWNtZCA9IFZUWElPQ0dFVFBBR0U7CgkJYnJlYWs7CgljYXNlIFZUWElPQ1NUT1BEQVVfT0xEOgoJCWNtZCA9IFZUWElPQ1NUT1BEQVU7CgkJYnJlYWs7CgljYXNlIFZUWElPQ1BVVFBBR0VfT0xEOgoJCWNtZCA9IFZUWElPQ1BVVFBBR0U7CgkJYnJlYWs7CgljYXNlIFZUWElPQ1NFVERJU1BfT0xEOgoJCWNtZCA9IFZUWElPQ1NFVERJU1A7CgkJYnJlYWs7CgljYXNlIFZUWElPQ1BVVFNUQVRfT0xEOgoJCWNtZCA9IFZUWElPQ1BVVFNUQVQ7CgkJYnJlYWs7CgljYXNlIFZUWElPQ0NMUkNBQ0hFX09MRDoKCQljbWQgPSBWVFhJT0NDTFJDQUNIRTsKCQlicmVhazsKCWNhc2UgVlRYSU9DU0VUVklSVF9PTEQ6CgkJY21kID0gVlRYSU9DU0VUVklSVDsKCQlicmVhazsKCX0KCXJldHVybiBjbWQ7Cn0KCi8qCiAqCUhhbmRsZSB0aGUgbG9ja2luZwogKi8KIApzdGF0aWMgaW50IHNhYTUyNDlfaW9jdGwoc3RydWN0IGlub2RlICppbm9kZSwgc3RydWN0IGZpbGUgKmZpbGUsCgkJCSB1bnNpZ25lZCBpbnQgY21kLCB1bnNpZ25lZCBsb25nIGFyZykgCnsKCXN0cnVjdCB2aWRlb19kZXZpY2UgKnZkID0gdmlkZW9fZGV2ZGF0YShmaWxlKTsKCXN0cnVjdCBzYWE1MjQ5X2RldmljZSAqdD12ZC0+cHJpdjsKCWludCBlcnI7CgkKCWNtZCA9IHZ0eF9maXhfY29tbWFuZChjbWQpOwoJZG93bigmdC0+bG9jayk7CgllcnIgPSB2aWRlb191c2VyY29weShpbm9kZSxmaWxlLGNtZCxhcmcsZG9fc2FhNTI0OV9pb2N0bCk7Cgl1cCgmdC0+bG9jayk7CglyZXR1cm4gZXJyOwp9CgpzdGF0aWMgaW50IHNhYTUyNDlfb3BlbihzdHJ1Y3QgaW5vZGUgKmlub2RlLCBzdHJ1Y3QgZmlsZSAqZmlsZSkgCnsKCXN0cnVjdCB2aWRlb19kZXZpY2UgKnZkID0gdmlkZW9fZGV2ZGF0YShmaWxlKTsKCXN0cnVjdCBzYWE1MjQ5X2RldmljZSAqdD12ZC0+cHJpdjsKCWludCBlcnIscGdidWY7CgoJZXJyID0gdmlkZW9fZXhjbHVzaXZlX29wZW4oaW5vZGUsZmlsZSk7CglpZiAoZXJyIDwgMCkKCQlyZXR1cm4gZXJyOwoJCglpZiAodC0+Y2xpZW50PT1OVUxMKSB7CgkJZXJyID0gLUVOT0RFVjsKCQlnb3RvIGZhaWw7Cgl9CgoJaWYgKGkyY19zZW5kZGF0YSh0LCAwLCAwLCAtMSkgfHwJCS8qIFNlbGVjdCBSMTEgKi8KCQkJCQkJLyogVHVybiBvZmYgcGFyaXR5IGNoZWNrcyAod2UgZG8gdGhpcyBvdXJzZWx2ZXMpICovCgkJaTJjX3NlbmRkYXRhKHQsIDEsIGRpc3BfbW9kZXNbdC0+ZGlzcF9tb2RlXVswXSwgMCwgLTEpIHx8CgkJCQkJCS8qIERpc3BsYXkgVFYtcGljdHVyZSwgbm8gdmlydHVhbCByb3dzICovCgkJaTJjX3NlbmRkYXRhKHQsIDQsIE5VTV9EQVVTLCBkaXNwX21vZGVzW3QtPmRpc3BfbW9kZV1bMV0sIGRpc3BfbW9kZXNbdC0+ZGlzcF9tb2RlXVsyXSwgNywgLTEpKSAvKiBTZXQgZGlzcGxheSB0byBwYWdlIDQgKi8KCQoJewoJCWVyciA9IC1FSU87CgkJZ290byBmYWlsOwoJfQoKCWZvciAocGdidWYgPSAwOyBwZ2J1ZiA8IE5VTV9EQVVTOyBwZ2J1ZisrKSAKCXsKCQltZW1zZXQodC0+dmRhdVtwZ2J1Zl0ucGdidWYsICcgJywgc2l6ZW9mKHQtPnZkYXVbMF0ucGdidWYpKTsKCQltZW1zZXQodC0+dmRhdVtwZ2J1Zl0uc3JlZ3MsIDAsIHNpemVvZih0LT52ZGF1WzBdLnNyZWdzKSk7CgkJbWVtc2V0KHQtPnZkYXVbcGdidWZdLmxhc3RzdGF0LCAwLCBzaXplb2YodC0+dmRhdVswXS5sYXN0c3RhdCkpOwoJCXQtPnZkYXVbcGdidWZdLmV4cGlyZSA9IDA7CgkJdC0+dmRhdVtwZ2J1Zl0uY2xyZm91bmQgPSBUUlVFOwoJCXQtPnZkYXVbcGdidWZdLnN0b3BwZWQgPSBUUlVFOwoJCXQtPmlzX3NlYXJjaGluZ1twZ2J1Zl0gPSBGQUxTRTsKCX0KCXQtPnZpcnR1YWxfbW9kZT1GQUxTRTsKCXJldHVybiAwOwoKIGZhaWw6Cgl2aWRlb19leGNsdXNpdmVfcmVsZWFzZShpbm9kZSxmaWxlKTsKCXJldHVybiBlcnI7Cn0KCgoKc3RhdGljIGludCBzYWE1MjQ5X3JlbGVhc2Uoc3RydWN0IGlub2RlICppbm9kZSwgc3RydWN0IGZpbGUgKmZpbGUpIAp7CglzdHJ1Y3QgdmlkZW9fZGV2aWNlICp2ZCA9IHZpZGVvX2RldmRhdGEoZmlsZSk7CglzdHJ1Y3Qgc2FhNTI0OV9kZXZpY2UgKnQ9dmQtPnByaXY7CglpMmNfc2VuZGRhdGEodCwgMSwgMHgyMCwgLTEpOwkJLyogVHVybiBvZmYgQ0NUICovCglpMmNfc2VuZGRhdGEodCwgNSwgMywgMywgLTEpOwkJLyogVHVybiBvZmYgVFYtZGlzcGxheSAqLwoJdmlkZW9fZXhjbHVzaXZlX3JlbGVhc2UoaW5vZGUsZmlsZSk7CglyZXR1cm4gMDsKfQoKc3RhdGljIGludCBfX2luaXQgaW5pdF9zYWFfNTI0OSAodm9pZCkKewoJcHJpbnRrKEtFUk5fSU5GTyAiU0FBNTI0OSBkcml2ZXIgKCIgSUZfTkFNRSAiIGludGVyZmFjZSkgZm9yIFZpZGVvVGV4dCB2ZXJzaW9uICVkLiVkXG4iLAoJCQlWVFhfVkVSX01BSiwgVlRYX1ZFUl9NSU4pOwoJcmV0dXJuIGkyY19hZGRfZHJpdmVyKCZpMmNfZHJpdmVyX3ZpZGVvdGV4dCk7Cn0KCnN0YXRpYyB2b2lkIF9fZXhpdCBjbGVhbnVwX3NhYV81MjQ5ICh2b2lkKSAKewoJaTJjX2RlbF9kcml2ZXIoJmkyY19kcml2ZXJfdmlkZW90ZXh0KTsKfQoKbW9kdWxlX2luaXQoaW5pdF9zYWFfNTI0OSk7Cm1vZHVsZV9leGl0KGNsZWFudXBfc2FhXzUyNDkpOwoKc3RhdGljIHN0cnVjdCBmaWxlX29wZXJhdGlvbnMgc2FhX2ZvcHMgPSB7Cgkub3duZXIJCT0gVEhJU19NT0RVTEUsCgkub3BlbgkJPSBzYWE1MjQ5X29wZW4sCgkucmVsZWFzZSAgICAgICAJPSBzYWE1MjQ5X3JlbGVhc2UsCgkuaW9jdGwgICAgICAgICAgPSBzYWE1MjQ5X2lvY3RsLAoJLmNvbXBhdF9pb2N0bAk9IHY0bF9jb21wYXRfaW9jdGwzMiwKCS5sbHNlZWsgICAgICAgICA9IG5vX2xsc2VlaywKfTsKCnN0YXRpYyBzdHJ1Y3QgdmlkZW9fZGV2aWNlIHNhYV90ZW1wbGF0ZSA9CnsKCS5vd25lcgkJPSBUSElTX01PRFVMRSwKCS5uYW1lCQk9IElGX05BTUUsCgkudHlwZQkJPSBWSURfVFlQRV9URUxFVEVYVCwJLyp8IFZJRF9UWVBFX1RVTkVSID8/ICovCgkuaGFyZHdhcmUJPSBWSURfSEFSRFdBUkVfU0FBNTI0OSwKCS5mb3BzICAgICAgICAgICA9ICZzYWFfZm9wcywKfTsKCk1PRFVMRV9MSUNFTlNFKCJHUEwiKTsK