LyoKICogTW9kaWZpZWQgaW4gb3JkZXIgdG8ga2VlcCBpdCBjb21wYXRpYmxlIGJvdGggd2l0aCBuZXcgYW5kIG9sZCB2aWRlb3RleHQgSU9DVExzIGJ5CiAqIE1pY2hhZWwgR2VuZyA8bGludXhATWljaGFlbEdlbmcuZGU+CiAqCiAqCUNsZWFuZWQgdXAgdG8gdXNlIGV4aXN0aW5nIHZpZGVvZGV2IGludGVyZmFjZSBhbmQgYWxsb3cgdGhlIGlkZWEKICoJb2YgbXVsdGlwbGUgdGVsZXRleHQgZGVjb2RlcnMgb24gdGhlIHZpZGVvNGxpbnV4IGlmYWNlLiBDaGFuZ2VkIGkyYwogKgl0byBjb3ZlciBhZGRyZXNzaW5nIGNsYXNoZXMgb24gZGV2aWNlIGJ1c3Nlcy4gSXQncyBhbHNvIHJlYnVpbHQgc28KICoJeW91IGNhbiBhZGQgYXJiaXRhcnkgbXVsdGlwbGUgdGVsZXRleHQgZGV2aWNlcyB0byBMaW51eCB2aWRlbzRsaW51eAogKglub3cgKHdlbGwgMzIgYW55d2F5KS4KICoKICoJQWxhbiBDb3ggPEFsYW4uQ294QGxpbnV4Lm9yZz4KICoKICoJVGhlIG9yaWdpbmFsIGRyaXZlciB3YXMgaGVhdmlseSBtb2RpZmllZCB0byBtYXRjaCB0aGUgaTJjIGludGVyZmFjZQogKglJdCB3YXMgdHJ1bmNhdGVkIHRvIHVzZSB0aGUgV2luVFYgYm9hcmRzLCB0b28uCiAqCiAqCUNvcHlyaWdodCAoYykgMTk5OCBSaWNoYXJkIEd1ZW50aGVyIDxyaWNoYXJkLmd1ZW50aGVyQHN0dWRlbnQudW5pLXR1ZWJpbmdlbi5kZT4KICoKICogJElkOiBzYWE1MjQ5LmMsdiAxLjEgMTk5OC8wMy8zMCAyMjoyMzoyMyBhbGFuIEV4cCAkCiAqCiAqCURlcml2ZWQgRnJvbQogKgogKiB2dHguYzoKICogVGhpcyBpcyBhIGxvYWRhYmxlIGNoYXJhY3Rlci1kZXZpY2UtZHJpdmVyIGZvciB2aWRlb3RleHQtaW50ZXJmYWNlcwogKiAoYWthIHRlbGV0ZXh0KS4gUGxlYXNlIGNoZWNrIHRoZSBNYWtlZmlsZS9SRUFETUUgZm9yIGEgbGlzdCBvZiBzdXBwb3J0ZWQKICogaW50ZXJmYWNlcy4KICoKICogQ29weXJpZ2h0IChjKSAxOTk0LTk3IE1hcnRpbiBCdWNrICA8bWFydGluLTIuYnVja0BzdHVkZW50LnVuaS11bG0uZGU+CiAqCiAqCiAqIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5CiAqIGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5CiAqIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlciB2ZXJzaW9uIDIgb2YgdGhlIExpY2Vuc2UsIG9yCiAqIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlCiAqIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIGFsb25nIHdpdGggdGhpcyBwcm9ncmFtOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDU5IFRlbXBsZSBQbGFjZSAtIFN1aXRlIDMzMCwgQm9zdG9uLCBNQSAwMjExMS0xMzA3LAogKiBVU0EuCiAqLwoKI2luY2x1ZGUgPGxpbnV4L21vZHVsZS5oPgojaW5jbHVkZSA8bGludXgva2VybmVsLmg+CiNpbmNsdWRlIDxsaW51eC9zY2hlZC5oPgojaW5jbHVkZSA8bGludXgvbW0uaD4KI2luY2x1ZGUgPGxpbnV4L2Vycm5vLmg+CiNpbmNsdWRlIDxsaW51eC9kZWxheS5oPgojaW5jbHVkZSA8bGludXgvaW9wb3J0Lmg+CiNpbmNsdWRlIDxsaW51eC9zbGFiLmg+CiNpbmNsdWRlIDxsaW51eC9pbml0Lmg+CiNpbmNsdWRlIDxzdGRhcmcuaD4KI2luY2x1ZGUgPGxpbnV4L2kyYy5oPgojaW5jbHVkZSA8bGludXgvdmlkZW90ZXh0Lmg+CiNpbmNsdWRlIDxsaW51eC92aWRlb2Rldi5oPgojaW5jbHVkZSA8bWVkaWEvdjRsMi1jb21tb24uaD4KI2luY2x1ZGUgPGxpbnV4L211dGV4Lmg+CgoKI2luY2x1ZGUgPGFzbS9pby5oPgojaW5jbHVkZSA8YXNtL3VhY2Nlc3MuaD4KCiNkZWZpbmUgVlRYX1ZFUl9NQUogMQojZGVmaW5lIFZUWF9WRVJfTUlOIDgKCgoKI2RlZmluZSBOVU1fREFVUyA0CiNkZWZpbmUgTlVNX0JVRlMgOAojZGVmaW5lIElGX05BTUUgIlNBQTUyNDkiCgpzdGF0aWMgY29uc3QgaW50IGRpc3BfbW9kZXNbOF1bM10gPQp7Cgl7IDB4NDYsIDB4MDMsIDB4MDMgfSwJLyogRElTUE9GRiAqLwoJeyAweDQ2LCAweGNjLCAweGNjIH0sCS8qIERJU1BOT1JNICovCgl7IDB4NDQsIDB4MGYsIDB4MGYgfSwJLyogRElTUFRSQU5TICovCgl7IDB4NDYsIDB4Y2MsIDB4NDYgfSwJLyogRElTUElOUyAqLwoJeyAweDQ0LCAweDAzLCAweDAzIH0sCS8qIERJU1BPRkYsIGludGVybGFjZWQgKi8KCXsgMHg0NCwgMHhjYywgMHhjYyB9LAkvKiBESVNQTk9STSwgaW50ZXJsYWNlZCAqLwoJeyAweDQ0LCAweDBmLCAweDBmIH0sCS8qIERJU1BUUkFOUywgaW50ZXJsYWNlZCAqLwoJeyAweDQ0LCAweGNjLCAweDQ2IH0JLyogRElTUElOUywgaW50ZXJsYWNlZCAqLwp9OwoKCgojZGVmaW5lIFBBR0VfV0FJVCAoMzAwKkhaLzEwMDApCQkJLyogVGltZSBiZXR3ZWVuIHJlcXVlc3RpbmcgcGFnZSBhbmQgKi8KCQkJCQkJLyogY2hlY2tpbmcgc3RhdHVzIGJpdHMgKi8KI2RlZmluZSBQR0JVRl9FWFBJUkUgKDE1KkhaKQkJCS8qIFRpbWUgdG8gd2FpdCBiZWZvcmUgcmV0cmFuc21pdHRpbmcgKi8KCQkJCQkJLyogcGFnZSByZWdhcmRsZXNzIG9mIGluZm9iaXRzICovCnR5cGVkZWYgc3RydWN0IHsKCXU4IHBnYnVmW1ZUWF9WSVJUVUFMU0laRV07CQkvKiBQYWdlLWJ1ZmZlciAqLwoJdTggbGFzdHN0YXRbMTBdOwkJCS8qIExhc3QgdmFsdWUgb2YgaW5mb2JpdHMgZm9yIERBVSAqLwoJdTggc3JlZ3NbN107CQkJCS8qIFBhZ2UtcmVxdWVzdCByZWdpc3RlcnMgKi8KCXVuc2lnbmVkIGxvbmcgZXhwaXJlOwkJCS8qIFRpbWUgd2hlbiBwYWdlIHdpbGwgYmUgZXhwaXJlZCAqLwoJdW5zaWduZWQgY2xyZm91bmQgOiAxOwkJCS8qIFZUWElPQ0NMUkZPVU5EIGhhcyBiZWVuIGNhbGxlZCAqLwoJdW5zaWduZWQgc3RvcHBlZCA6IDE7CQkJLyogVlRYSU9DU1RPUERBVSBoYXMgYmVlbiBjYWxsZWQgKi8KfSB2ZGF1X3Q7CgpzdHJ1Y3Qgc2FhNTI0OV9kZXZpY2UKewoJdmRhdV90IHZkYXVbTlVNX0RBVVNdOwkJCS8qIERhdGEgZm9yIHZpcnR1YWwgREFVcyAodGhlIDUyNDkgb25seSBoYXMgb25lICovCgkJCQkJCS8qIHJlYWwgREFVLCBzbyB3ZSBoYXZlIHRvIHNpbXVsYXRlIHNvbWUgbW9yZSkgKi8KCWludCB2dHhfdXNlX2NvdW50OwoJaW50IGlzX3NlYXJjaGluZ1tOVU1fREFVU107CglpbnQgZGlzcF9tb2RlOwoJaW50IHZpcnR1YWxfbW9kZTsKCXN0cnVjdCBpMmNfY2xpZW50ICpjbGllbnQ7CglzdHJ1Y3QgbXV0ZXggbG9jazsKfTsKCgojZGVmaW5lIENDVFdSIDM0CQkvKiBJskMgd3JpdGUvcmVhZC1hZGRyZXNzIG9mIHZ0eC1jaGlwICovCiNkZWZpbmUgQ0NUUkQgMzUKI2RlZmluZSBOT0FDS19SRVBFQVQgMTAJCS8qIFJldHJ5IGFjY2VzcyB0aGlzIG1hbnkgdGltZXMgb24gZmFpbHVyZSAqLwojZGVmaW5lIENMRUFSX0RFTEFZIChIWi8yMCkJLyogVGltZSByZXF1aXJlZCB0byBjbGVhciBhIHBhZ2UgKi8KI2RlZmluZSBSRUFEWV9USU1FT1VUICgzMCpIWi8xMDAwKQkvKiBUaW1lIHRvIHdhaXQgZm9yIHJlYWR5IHNpZ25hbCBvZiBJskMtYnVzIGludGVyZmFjZSAqLwojZGVmaW5lIElOSVRfREVMQVkgNTAwCQkvKiBUaW1lIGluIHVzZWMgdG8gd2FpdCBhdCBpbml0aWFsaXphdGlvbiBvZiBDRUEgaW50ZXJmYWNlICovCiNkZWZpbmUgU1RBUlRfREVMQVkgMTAJCS8qIFRpbWUgaW4gdXNlYyB0byB3YWl0IGJlZm9yZSBzdGFydGluZyB3cml0ZS1jeWNsZSAoQ0VBKSAqLwoKI2RlZmluZSBWVFhfREVWX01JTk9SIDAKCi8qIEdlbmVyYWwgZGVmaW5lcyBhbmQgZGVidWdnaW5nIHN1cHBvcnQgKi8KCiNpZm5kZWYgRkFMU0UKI2RlZmluZSBGQUxTRSAwCiNkZWZpbmUgVFJVRSAxCiNlbmRpZgoKI2RlZmluZSBSRVNDSEVEIGRvIHsgY29uZF9yZXNjaGVkKCk7IH0gd2hpbGUoMCkKCnN0YXRpYyBzdHJ1Y3QgdmlkZW9fZGV2aWNlIHNhYV90ZW1wbGF0ZTsJLyogRGVjbGFyZWQgbmVhciBib3R0b20gKi8KCi8qIEFkZHJlc3NlcyB0byBzY2FuICovCnN0YXRpYyB1bnNpZ25lZCBzaG9ydCBub3JtYWxfaTJjW10gPSB7MzQ+PjEsSTJDX0NMSUVOVF9FTkR9OwpJMkNfQ0xJRU5UX0lOU01PRDsKCnN0YXRpYyBzdHJ1Y3QgaTJjX2NsaWVudCBjbGllbnRfdGVtcGxhdGU7CgpzdGF0aWMgaW50IHNhYTUyNDlfYXR0YWNoKHN0cnVjdCBpMmNfYWRhcHRlciAqYWRhcCwgaW50IGFkZHIsIGludCBraW5kKQp7CglpbnQgcGdidWY7CglpbnQgZXJyOwoJc3RydWN0IGkyY19jbGllbnQgKmNsaWVudDsKCXN0cnVjdCB2aWRlb19kZXZpY2UgKnZkOwoJc3RydWN0IHNhYTUyNDlfZGV2aWNlICp0OwoKCXByaW50ayhLRVJOX0lORk8gInNhYTUyNDk6IHRlbGV0ZXh0IGNoaXAgZm91bmQuXG4iKTsKCWNsaWVudD1rbWFsbG9jKHNpemVvZigqY2xpZW50KSwgR0ZQX0tFUk5FTCk7CglpZihjbGllbnQ9PU5VTEwpCgkJcmV0dXJuIC1FTk9NRU07CgljbGllbnRfdGVtcGxhdGUuYWRhcHRlciA9IGFkYXA7CgljbGllbnRfdGVtcGxhdGUuYWRkciA9IGFkZHI7CgltZW1jcHkoY2xpZW50LCAmY2xpZW50X3RlbXBsYXRlLCBzaXplb2YoKmNsaWVudCkpOwoJdCA9IGt6YWxsb2Moc2l6ZW9mKCp0KSwgR0ZQX0tFUk5FTCk7CglpZih0PT1OVUxMKQoJewoJCWtmcmVlKGNsaWVudCk7CgkJcmV0dXJuIC1FTk9NRU07Cgl9CglzdHJsY3B5KGNsaWVudC0+bmFtZSwgSUZfTkFNRSwgSTJDX05BTUVfU0laRSk7CgltdXRleF9pbml0KCZ0LT5sb2NrKTsKCgkvKgoJICoJTm93IGNyZWF0ZSBhIHZpZGVvNGxpbnV4IGRldmljZQoJICovCgoJdmQgPSBrbWFsbG9jKHNpemVvZihzdHJ1Y3QgdmlkZW9fZGV2aWNlKSwgR0ZQX0tFUk5FTCk7CglpZih2ZD09TlVMTCkKCXsKCQlrZnJlZSh0KTsKCQlrZnJlZShjbGllbnQpOwoJCXJldHVybiAtRU5PTUVNOwoJfQoJaTJjX3NldF9jbGllbnRkYXRhKGNsaWVudCwgdmQpOwoJbWVtY3B5KHZkLCAmc2FhX3RlbXBsYXRlLCBzaXplb2YoKnZkKSk7CgoJZm9yIChwZ2J1ZiA9IDA7IHBnYnVmIDwgTlVNX0RBVVM7IHBnYnVmKyspCgl7CgkJbWVtc2V0KHQtPnZkYXVbcGdidWZdLnBnYnVmLCAnICcsIHNpemVvZih0LT52ZGF1WzBdLnBnYnVmKSk7CgkJbWVtc2V0KHQtPnZkYXVbcGdidWZdLnNyZWdzLCAwLCBzaXplb2YodC0+dmRhdVswXS5zcmVncykpOwoJCW1lbXNldCh0LT52ZGF1W3BnYnVmXS5sYXN0c3RhdCwgMCwgc2l6ZW9mKHQtPnZkYXVbMF0ubGFzdHN0YXQpKTsKCQl0LT52ZGF1W3BnYnVmXS5leHBpcmUgPSAwOwoJCXQtPnZkYXVbcGdidWZdLmNscmZvdW5kID0gVFJVRTsKCQl0LT52ZGF1W3BnYnVmXS5zdG9wcGVkID0gVFJVRTsKCQl0LT5pc19zZWFyY2hpbmdbcGdidWZdID0gRkFMU0U7Cgl9Cgl2ZC0+cHJpdj10OwoKCgkvKgoJICoJUmVnaXN0ZXIgaXQKCSAqLwoKCWlmKChlcnI9dmlkZW9fcmVnaXN0ZXJfZGV2aWNlKHZkLCBWRkxfVFlQRV9WVFgsLTEpKTwwKQoJewoJCWtmcmVlKHQpOwoJCWtmcmVlKHZkKTsKCQlrZnJlZShjbGllbnQpOwoJCXJldHVybiBlcnI7Cgl9Cgl0LT5jbGllbnQgPSBjbGllbnQ7CglpMmNfYXR0YWNoX2NsaWVudChjbGllbnQpOwoJcmV0dXJuIDA7Cn0KCi8qCiAqCVdlIGRvIG1vc3Qgb2YgdGhlIGhhcmQgd29yayB3aGVuIHdlIGJlY29tZSBhIGRldmljZSBvbiB0aGUgaTJjLgogKi8KCnN0YXRpYyBpbnQgc2FhNTI0OV9wcm9iZShzdHJ1Y3QgaTJjX2FkYXB0ZXIgKmFkYXApCnsKCWlmIChhZGFwLT5jbGFzcyAmIEkyQ19DTEFTU19UVl9BTkFMT0cpCgkJcmV0dXJuIGkyY19wcm9iZShhZGFwLCAmYWRkcl9kYXRhLCBzYWE1MjQ5X2F0dGFjaCk7CglyZXR1cm4gMDsKfQoKc3RhdGljIGludCBzYWE1MjQ5X2RldGFjaChzdHJ1Y3QgaTJjX2NsaWVudCAqY2xpZW50KQp7CglzdHJ1Y3QgdmlkZW9fZGV2aWNlICp2ZCA9IGkyY19nZXRfY2xpZW50ZGF0YShjbGllbnQpOwoJaTJjX2RldGFjaF9jbGllbnQoY2xpZW50KTsKCXZpZGVvX3VucmVnaXN0ZXJfZGV2aWNlKHZkKTsKCWtmcmVlKHZkLT5wcml2KTsKCWtmcmVlKHZkKTsKCWtmcmVlKGNsaWVudCk7CglyZXR1cm4gMDsKfQoKLyogbmV3IEkyQyBkcml2ZXIgc3VwcG9ydCAqLwoKc3RhdGljIHN0cnVjdCBpMmNfZHJpdmVyIGkyY19kcml2ZXJfdmlkZW90ZXh0ID0KewoJLmRyaXZlciA9IHsKCQkubmFtZSAJPSBJRl9OQU1FLAkJLyogbmFtZSAqLwoJfSwKCS5pZCAJCT0gSTJDX0RSSVZFUklEX1NBQTUyNDksIC8qIGluIGkyYy5oICovCgkuYXR0YWNoX2FkYXB0ZXIgPSBzYWE1MjQ5X3Byb2JlLAoJLmRldGFjaF9jbGllbnQgID0gc2FhNTI0OV9kZXRhY2gsCn07CgpzdGF0aWMgc3RydWN0IGkyY19jbGllbnQgY2xpZW50X3RlbXBsYXRlID0gewoJLmRyaXZlcgkJPSAmaTJjX2RyaXZlcl92aWRlb3RleHQsCgkubmFtZQkJPSAiKHVuc2V0KSIsCn07CgovKgogKglXYWl0IHRoZSBnaXZlbiBudW1iZXIgb2YgamlmZmllcyAoMTBtcykuIFRoaXMgY2FsbHMgdGhlIHNjaGVkdWxlciwgc28gdGhlIGFjdHVhbAogKglkZWxheSBtYXkgYmUgbG9uZ2VyLgogKi8KCnN0YXRpYyB2b2lkIGpkZWxheSh1bnNpZ25lZCBsb25nIGRlbGF5KQp7CglzaWdzZXRfdCBvbGRibG9ja2VkID0gY3VycmVudC0+YmxvY2tlZDsKCglzcGluX2xvY2tfaXJxKCZjdXJyZW50LT5zaWdoYW5kLT5zaWdsb2NrKTsKCXNpZ2ZpbGxzZXQoJmN1cnJlbnQtPmJsb2NrZWQpOwoJcmVjYWxjX3NpZ3BlbmRpbmcoKTsKCXNwaW5fdW5sb2NrX2lycSgmY3VycmVudC0+c2lnaGFuZC0+c2lnbG9jayk7Cgltc2xlZXBfaW50ZXJydXB0aWJsZShqaWZmaWVzX3RvX21zZWNzKGRlbGF5KSk7CgoJc3Bpbl9sb2NrX2lycSgmY3VycmVudC0+c2lnaGFuZC0+c2lnbG9jayk7CgljdXJyZW50LT5ibG9ja2VkID0gb2xkYmxvY2tlZDsKCXJlY2FsY19zaWdwZW5kaW5nKCk7CglzcGluX3VubG9ja19pcnEoJmN1cnJlbnQtPnNpZ2hhbmQtPnNpZ2xvY2spOwp9CgoKLyoKICoJSTJDIGludGVyZmFjZXMKICovCgpzdGF0aWMgaW50IGkyY19zZW5kYnVmKHN0cnVjdCBzYWE1MjQ5X2RldmljZSAqdCwgaW50IHJlZywgaW50IGNvdW50LCB1OCAqZGF0YSkKewoJY2hhciBidWZbNjRdOwoKCWJ1ZlswXSA9IHJlZzsKCW1lbWNweShidWYrMSwgZGF0YSwgY291bnQpOwoKCWlmKGkyY19tYXN0ZXJfc2VuZCh0LT5jbGllbnQsIGJ1ZiwgY291bnQrMSk9PWNvdW50KzEpCgkJcmV0dXJuIDA7CglyZXR1cm4gLTE7Cn0KCnN0YXRpYyBpbnQgaTJjX3NlbmRkYXRhKHN0cnVjdCBzYWE1MjQ5X2RldmljZSAqdCwgLi4uKQp7Cgl1bnNpZ25lZCBjaGFyIGJ1Zls2NF07CglpbnQgdjsKCWludCBjdD0wOwoJdmFfbGlzdCBhcmdwOwoJdmFfc3RhcnQoYXJncCx0KTsKCgl3aGlsZSgodj12YV9hcmcoYXJncCxpbnQpKSE9LTEpCgkJYnVmW2N0KytdPXY7CglyZXR1cm4gaTJjX3NlbmRidWYodCwgYnVmWzBdLCBjdC0xLCBidWYrMSk7Cn0KCi8qIEdldCBjb3VudCBudW1iZXIgb2YgYnl0ZXMgZnJvbSBJskMtZGV2aWNlIGF0IGFkZHJlc3MgYWRyLCBzdG9yZSB0aGVtIGluIGJ1Zi4gU3RhcnQgJiBzdG9wCiAqIGhhbmRzaGFraW5nIGlzIGRvbmUgYnkgdGhpcyByb3V0aW5lLCBhY2sgd2lsbCBiZSBzZW50IGFmdGVyIHRoZSBsYXN0IGJ5dGUgdG8gaW5oaWJpdCBmdXJ0aGVyCiAqIHNlbmRpbmcgb2YgZGF0YS4gSWYgdWFjY2VzcyBpcyBUUlVFLCBkYXRhIGlzIHdyaXR0ZW4gdG8gdXNlci1zcGFjZSB3aXRoIHB1dF91c2VyLgogKiBSZXR1cm5zIC0xIGlmIEmyQy1kZXZpY2UgZGlkbid0IHNlbmQgYWNrbm93bGVkZ2UsIDAgb3RoZXJ3aXNlCiAqLwoKc3RhdGljIGludCBpMmNfZ2V0ZGF0YShzdHJ1Y3Qgc2FhNTI0OV9kZXZpY2UgKnQsIGludCBjb3VudCwgdTggKmJ1ZikKewoJaWYoaTJjX21hc3Rlcl9yZWN2KHQtPmNsaWVudCwgYnVmLCBjb3VudCkhPWNvdW50KQoJCXJldHVybiAtMTsKCXJldHVybiAwOwp9CgoKLyoKICoJU3RhbmRhcmQgY2hhcmFjdGVyLWRldmljZS1kcml2ZXIgZnVuY3Rpb25zCiAqLwoKc3RhdGljIGludCBkb19zYWE1MjQ5X2lvY3RsKHN0cnVjdCBpbm9kZSAqaW5vZGUsIHN0cnVjdCBmaWxlICpmaWxlLAoJCQkgICAgdW5zaWduZWQgaW50IGNtZCwgdm9pZCAqYXJnKQp7CglzdGF0aWMgaW50IHZpcnR1YWxfbW9kZSA9IEZBTFNFOwoJc3RydWN0IHZpZGVvX2RldmljZSAqdmQgPSB2aWRlb19kZXZkYXRhKGZpbGUpOwoJc3RydWN0IHNhYTUyNDlfZGV2aWNlICp0PXZkLT5wcml2OwoKCXN3aXRjaChjbWQpCgl7CgkJY2FzZSBWVFhJT0NHRVRJTkZPOgoJCXsKCQkJdnR4X2luZm9fdCAqaW5mbyA9IGFyZzsKCQkJaW5mby0+dmVyc2lvbl9tYWpvciA9IFZUWF9WRVJfTUFKOwoJCQlpbmZvLT52ZXJzaW9uX21pbm9yID0gVlRYX1ZFUl9NSU47CgkJCWluZm8tPm51bXBhZ2VzID0gTlVNX0RBVVM7CgkJCS8qaW5mby0+Y2N0X3R5cGUgPSBDQ1RfVFlQRTsqLwoJCQlyZXR1cm4gMDsKCQl9CgoJCWNhc2UgVlRYSU9DQ0xSUEFHRToKCQl7CgkJCXZ0eF9wYWdlcmVxX3QgKnJlcSA9IGFyZzsKCgkJCWlmIChyZXEtPnBnYnVmIDwgMCB8fCByZXEtPnBnYnVmID49IE5VTV9EQVVTKQoJCQkJcmV0dXJuIC1FSU5WQUw7CgkJCW1lbXNldCh0LT52ZGF1W3JlcS0+cGdidWZdLnBnYnVmLCAnICcsIHNpemVvZih0LT52ZGF1WzBdLnBnYnVmKSk7CgkJCXQtPnZkYXVbcmVxLT5wZ2J1Zl0uY2xyZm91bmQgPSBUUlVFOwoJCQlyZXR1cm4gMDsKCQl9CgoJCWNhc2UgVlRYSU9DQ0xSRk9VTkQ6CgkJewoJCQl2dHhfcGFnZXJlcV90ICpyZXEgPSBhcmc7CgoJCQlpZiAocmVxLT5wZ2J1ZiA8IDAgfHwgcmVxLT5wZ2J1ZiA+PSBOVU1fREFVUykKCQkJCXJldHVybiAtRUlOVkFMOwoJCQl0LT52ZGF1W3JlcS0+cGdidWZdLmNscmZvdW5kID0gVFJVRTsKCQkJcmV0dXJuIDA7CgkJfQoKCQljYXNlIFZUWElPQ1BBR0VSRVE6CgkJewoJCQl2dHhfcGFnZXJlcV90ICpyZXEgPSBhcmc7CgkJCWlmICghKHJlcS0+cGFnZW1hc2sgJiBQR01BU0tfUEFHRSkpCgkJCQlyZXEtPnBhZ2UgPSAwOwoJCQlpZiAoIShyZXEtPnBhZ2VtYXNrICYgUEdNQVNLX0hPVVIpKQoJCQkJcmVxLT5ob3VyID0gMDsKCQkJaWYgKCEocmVxLT5wYWdlbWFzayAmIFBHTUFTS19NSU5VVEUpKQoJCQkJcmVxLT5taW51dGUgPSAwOwoJCQlpZiAocmVxLT5wYWdlIDwgMCB8fCByZXEtPnBhZ2UgPiAweDhmZikgLyogN0ZGID8/ICovCgkJCQlyZXR1cm4gLUVJTlZBTDsKCQkJcmVxLT5wYWdlICY9IDB4N2ZmOwoJCQlpZiAocmVxLT5ob3VyIDwgMCB8fCByZXEtPmhvdXIgPiAweDNmIHx8IHJlcS0+bWludXRlIDwgMCB8fCByZXEtPm1pbnV0ZSA+IDB4N2YgfHwKCQkJCXJlcS0+cGFnZW1hc2sgPCAwIHx8IHJlcS0+cGFnZW1hc2sgPj0gUEdNQVNLX01BWCB8fCByZXEtPnBnYnVmIDwgMCB8fCByZXEtPnBnYnVmID49IE5VTV9EQVVTKQoJCQkJcmV0dXJuIC1FSU5WQUw7CgkJCXQtPnZkYXVbcmVxLT5wZ2J1Zl0uc3JlZ3NbMF0gPSAocmVxLT5wYWdlbWFzayAmIFBHX0hVTkQgPyAweDEwIDogMCkgfCAocmVxLT5wYWdlIC8gMHgxMDApOwoJCQl0LT52ZGF1W3JlcS0+cGdidWZdLnNyZWdzWzFdID0gKHJlcS0+cGFnZW1hc2sgJiBQR19URU4gPyAweDEwIDogMCkgfCAoKHJlcS0+cGFnZSAvIDB4MTApICYgMHhmKTsKCQkJdC0+dmRhdVtyZXEtPnBnYnVmXS5zcmVnc1syXSA9IChyZXEtPnBhZ2VtYXNrICYgUEdfVU5JVCA/IDB4MTAgOiAwKSB8IChyZXEtPnBhZ2UgJiAweGYpOwoJCQl0LT52ZGF1W3JlcS0+cGdidWZdLnNyZWdzWzNdID0gKHJlcS0+cGFnZW1hc2sgJiBIUl9URU4gPyAweDEwIDogMCkgfCAocmVxLT5ob3VyIC8gMHgxMCk7CgkJCXQtPnZkYXVbcmVxLT5wZ2J1Zl0uc3JlZ3NbNF0gPSAocmVxLT5wYWdlbWFzayAmIEhSX1VOSVQgPyAweDEwIDogMCkgfCAocmVxLT5ob3VyICYgMHhmKTsKCQkJdC0+dmRhdVtyZXEtPnBnYnVmXS5zcmVnc1s1XSA9IChyZXEtPnBhZ2VtYXNrICYgTUlOX1RFTiA/IDB4MTAgOiAwKSB8IChyZXEtPm1pbnV0ZSAvIDB4MTApOwoJCQl0LT52ZGF1W3JlcS0+cGdidWZdLnNyZWdzWzZdID0gKHJlcS0+cGFnZW1hc2sgJiBNSU5fVU5JVCA/IDB4MTAgOiAwKSB8IChyZXEtPm1pbnV0ZSAmIDB4Zik7CgkJCXQtPnZkYXVbcmVxLT5wZ2J1Zl0uc3RvcHBlZCA9IEZBTFNFOwoJCQl0LT52ZGF1W3JlcS0+cGdidWZdLmNscmZvdW5kID0gVFJVRTsKCQkJdC0+aXNfc2VhcmNoaW5nW3JlcS0+cGdidWZdID0gVFJVRTsKCQkJcmV0dXJuIDA7CgkJfQoKCQljYXNlIFZUWElPQ0dFVFNUQVQ6CgkJewoJCQl2dHhfcGFnZXJlcV90ICpyZXEgPSBhcmc7CgkJCXU4IGluZm9iaXRzWzEwXTsKCQkJdnR4X3BhZ2VpbmZvX3QgaW5mbzsKCQkJaW50IGE7CgoJCQlpZiAocmVxLT5wZ2J1ZiA8IDAgfHwgcmVxLT5wZ2J1ZiA+PSBOVU1fREFVUykKCQkJCXJldHVybiAtRUlOVkFMOwoJCQlpZiAoIXQtPnZkYXVbcmVxLT5wZ2J1Zl0uc3RvcHBlZCkKCQkJewoJCQkJaWYgKGkyY19zZW5kZGF0YSh0LCAyLCAwLCAtMSkgfHwKCQkJCQlpMmNfc2VuZGJ1Zih0LCAzLCBzaXplb2YodC0+dmRhdVswXS5zcmVncyksIHQtPnZkYXVbcmVxLT5wZ2J1Zl0uc3JlZ3MpIHx8CgkJCQkJaTJjX3NlbmRkYXRhKHQsIDgsIDAsIDI1LCAwLCAnICcsICcgJywgJyAnLCAnICcsICcgJywgJyAnLCAnICcsICcgJywgJyAnLCAtMSkgfHwKCQkJCQlpMmNfc2VuZGRhdGEodCwgMiwgMCwgdC0+dmRhdVtyZXEtPnBnYnVmXS5zcmVnc1swXSB8IDgsIC0xKSB8fAoJCQkJCWkyY19zZW5kZGF0YSh0LCA4LCAwLCAyNSwgMCwgLTEpKQoJCQkJCXJldHVybiAtRUlPOwoJCQkJamRlbGF5KFBBR0VfV0FJVCk7CgkJCQlpZiAoaTJjX2dldGRhdGEodCwgMTAsIGluZm9iaXRzKSkKCQkJCQlyZXR1cm4gLUVJTzsKCgkJCQlpZiAoIShpbmZvYml0c1s4XSAmIDB4MTApICYmICEoaW5mb2JpdHNbN10gJiAweGYwKSAmJgkvKiBjaGVjayBGT1VORC1iaXQgKi8KCQkJCQkobWVtY21wKGluZm9iaXRzLCB0LT52ZGF1W3JlcS0+cGdidWZdLmxhc3RzdGF0LCBzaXplb2YoaW5mb2JpdHMpKSB8fAoJCQkJCXRpbWVfYWZ0ZXJfZXEoamlmZmllcywgdC0+dmRhdVtyZXEtPnBnYnVmXS5leHBpcmUpKSkKCQkJCXsJCS8qIGNoZWNrIGlmIG5ldyBwYWdlIGFycml2ZWQgKi8KCQkJCQlpZiAoaTJjX3NlbmRkYXRhKHQsIDgsIDAsIDAsIDAsIC0xKSB8fAoJCQkJCQlpMmNfZ2V0ZGF0YSh0LCBWVFhfUEFHRVNJWkUsIHQtPnZkYXVbcmVxLT5wZ2J1Zl0ucGdidWYpKQoJCQkJCQlyZXR1cm4gLUVJTzsKCQkJCQl0LT52ZGF1W3JlcS0+cGdidWZdLmV4cGlyZSA9IGppZmZpZXMgKyBQR0JVRl9FWFBJUkU7CgkJCQkJbWVtc2V0KHQtPnZkYXVbcmVxLT5wZ2J1Zl0ucGdidWYgKyBWVFhfUEFHRVNJWkUsICcgJywgVlRYX1ZJUlRVQUxTSVpFIC0gVlRYX1BBR0VTSVpFKTsKCQkJCQlpZiAodC0+dmlydHVhbF9tb2RlKQoJCQkJCXsKCQkJCQkJLyogUGFja2V0IFgvMjQgKi8KCQkJCQkJaWYgKGkyY19zZW5kZGF0YSh0LCA4LCAwLCAweDIwLCAwLCAtMSkgfHwKCQkJCQkJCWkyY19nZXRkYXRhKHQsIDQwLCB0LT52ZGF1W3JlcS0+cGdidWZdLnBnYnVmICsgVlRYX1BBR0VTSVpFICsgMjAgKiA0MCkpCgkJCQkJCQlyZXR1cm4gLUVJTzsKCQkJCQkJLyogUGFja2V0IFgvMjcvMCAqLwoJCQkJCQlpZiAoaTJjX3NlbmRkYXRhKHQsIDgsIDAsIDB4MjEsIDAsIC0xKSB8fAoJCQkJCQkJaTJjX2dldGRhdGEodCwgNDAsIHQtPnZkYXVbcmVxLT5wZ2J1Zl0ucGdidWYgKyBWVFhfUEFHRVNJWkUgKyAxNiAqIDQwKSkKCQkJCQkJCXJldHVybiAtRUlPOwoJCQkJCQkvKiBQYWNrZXQgOC8zMC8wLi4uOC8zMC8xNQoJCQkJCQkgKiBGSVhNRTogQUZBSUssIHRoZSA1MjQ5IGRvZXMgaGFtbWluZy1kZWNvZGluZyBmb3Igc29tZSBieXRlcyBpbiBwYWNrZXQgOC8zMCwKCQkJCQkJICogICAgICAgIHNvIHdlIHNob3VsZCB1bmRvIHRoaXMgaGVyZS4KCQkJCQkJICovCgkJCQkJCWlmIChpMmNfc2VuZGRhdGEodCwgOCwgMCwgMHgyMiwgMCwgLTEpIHx8CgkJCQkJCQlpMmNfZ2V0ZGF0YSh0LCA0MCwgdC0+dmRhdVtyZXEtPnBnYnVmXS5wZ2J1ZiArIFZUWF9QQUdFU0laRSArIDIzICogNDApKQoJCQkJCQkJcmV0dXJuIC1FSU87CgkJCQkJfQoJCQkJCXQtPnZkYXVbcmVxLT5wZ2J1Zl0uY2xyZm91bmQgPSBGQUxTRTsKCQkJCQltZW1jcHkodC0+dmRhdVtyZXEtPnBnYnVmXS5sYXN0c3RhdCwgaW5mb2JpdHMsIHNpemVvZihpbmZvYml0cykpOwoJCQkJfQoJCQkJZWxzZQoJCQkJewoJCQkJCW1lbWNweShpbmZvYml0cywgdC0+dmRhdVtyZXEtPnBnYnVmXS5sYXN0c3RhdCwgc2l6ZW9mKGluZm9iaXRzKSk7CgkJCQl9CgkJCX0KCQkJZWxzZQoJCQl7CgkJCQltZW1jcHkoaW5mb2JpdHMsIHQtPnZkYXVbcmVxLT5wZ2J1Zl0ubGFzdHN0YXQsIHNpemVvZihpbmZvYml0cykpOwoJCQl9CgoJCQlpbmZvLnBhZ2VudW0gPSAoKGluZm9iaXRzWzhdIDw8IDgpICYgMHg3MDApIHwgKChpbmZvYml0c1sxXSA8PCA0KSAmIDB4ZjApIHwgKGluZm9iaXRzWzBdICYgMHgwZik7CgkJCWlmIChpbmZvLnBhZ2VudW0gPCAweDEwMCkKCQkJCWluZm8ucGFnZW51bSArPSAweDgwMDsKCQkJaW5mby5ob3VyID0gKChpbmZvYml0c1s1XSA8PCA0KSAmIDB4MzApIHwgKGluZm9iaXRzWzRdICYgMHgwZik7CgkJCWluZm8ubWludXRlID0gKChpbmZvYml0c1szXSA8PCA0KSAmIDB4NzApIHwgKGluZm9iaXRzWzJdICYgMHgwZik7CgkJCWluZm8uY2hhcnNldCA9ICgoaW5mb2JpdHNbN10gPj4gMSkgJiA3KTsKCQkJaW5mby5kZWxldGUgPSAhIShpbmZvYml0c1szXSAmIDgpOwoJCQlpbmZvLmhlYWRsaW5lID0gISEoaW5mb2JpdHNbNV0gJiA0KTsKCQkJaW5mby5zdWJ0aXRsZSA9ICEhKGluZm9iaXRzWzVdICYgOCk7CgkJCWluZm8uc3VwcF9oZWFkZXIgPSAhIShpbmZvYml0c1s2XSAmIDEpOwoJCQlpbmZvLnVwZGF0ZSA9ICEhKGluZm9iaXRzWzZdICYgMik7CgkJCWluZm8uaW50ZXJfc2VxID0gISEoaW5mb2JpdHNbNl0gJiA0KTsKCQkJaW5mby5kaXNfZGlzcCA9ICEhKGluZm9iaXRzWzZdICYgOCk7CgkJCWluZm8uc2VyaWFsID0gISEoaW5mb2JpdHNbN10gJiAxKTsKCQkJaW5mby5ub3Rmb3VuZCA9ICEhKGluZm9iaXRzWzhdICYgMHgxMCk7CgkJCWluZm8ucGJsZiA9ICEhKGluZm9iaXRzWzldICYgMHgyMCk7CgkJCWluZm8uaGFtbWluZyA9IDA7CgkJCWZvciAoYSA9IDA7IGEgPD0gNzsgYSsrKQoJCQl7CgkJCQlpZiAoaW5mb2JpdHNbYV0gJiAweGYwKQoJCQkJewoJCQkJCWluZm8uaGFtbWluZyA9IDE7CgkJCQkJYnJlYWs7CgkJCQl9CgkJCX0KCQkJaWYgKHQtPnZkYXVbcmVxLT5wZ2J1Zl0uY2xyZm91bmQpCgkJCQlpbmZvLm5vdGZvdW5kID0gMTsKCQkJaWYoY29weV90b191c2VyKHJlcS0+YnVmZmVyLCAmaW5mbywgc2l6ZW9mKHZ0eF9wYWdlaW5mb190KSkpCgkJCQlyZXR1cm4gLUVGQVVMVDsKCQkJaWYgKCFpbmZvLmhhbW1pbmcgJiYgIWluZm8ubm90Zm91bmQpCgkJCXsKCQkJCXQtPmlzX3NlYXJjaGluZ1tyZXEtPnBnYnVmXSA9IEZBTFNFOwoJCQl9CgkJCXJldHVybiAwOwoJCX0KCgkJY2FzZSBWVFhJT0NHRVRQQUdFOgoJCXsKCQkJdnR4X3BhZ2VyZXFfdCAqcmVxID0gYXJnOwoJCQlpbnQgc3RhcnQsIGVuZDsKCgkJCWlmIChyZXEtPnBnYnVmIDwgMCB8fCByZXEtPnBnYnVmID49IE5VTV9EQVVTIHx8IHJlcS0+c3RhcnQgPCAwIHx8CgkJCQlyZXEtPnN0YXJ0ID4gcmVxLT5lbmQgfHwgcmVxLT5lbmQgPj0gKHZpcnR1YWxfbW9kZSA/IFZUWF9WSVJUVUFMU0laRSA6IFZUWF9QQUdFU0laRSkpCgkJCQlyZXR1cm4gLUVJTlZBTDsKCQkJaWYoY29weV90b191c2VyKHJlcS0+YnVmZmVyLCAmdC0+dmRhdVtyZXEtPnBnYnVmXS5wZ2J1ZltyZXEtPnN0YXJ0XSwgcmVxLT5lbmQgLSByZXEtPnN0YXJ0ICsgMSkpCgkJCQlyZXR1cm4gLUVGQVVMVDsKCgkJCSAvKgoJCQkgICoJQWx3YXlzIHJlYWQgdGhlIHRpbWUgZGlyZWN0bHkgZnJvbSBTQUE1MjQ5CgkJCSAgKi8KCgkJCWlmIChyZXEtPnN0YXJ0IDw9IDM5ICYmIHJlcS0+ZW5kID49IDMyKQoJCQl7CgkJCQlpbnQgbGVuOwoJCQkJY2hhciBidWZbMTZdOwoJCQkJc3RhcnQgPSBtYXgocmVxLT5zdGFydCwgMzIpOwoJCQkJZW5kID0gbWluKHJlcS0+ZW5kLCAzOSk7CgkJCQlsZW49ZW5kLXN0YXJ0KzE7CgkJCQlpZiAoaTJjX3NlbmRkYXRhKHQsIDgsIDAsIDAsIHN0YXJ0LCAtMSkgfHwKCQkJCQlpMmNfZ2V0ZGF0YSh0LCBsZW4sIGJ1ZikpCgkJCQkJcmV0dXJuIC1FSU87CgkJCQlpZihjb3B5X3RvX3VzZXIocmVxLT5idWZmZXIrc3RhcnQtcmVxLT5zdGFydCwgYnVmLCBsZW4pKQoJCQkJCXJldHVybiAtRUZBVUxUOwoJCQl9CgkJCS8qIEluc2VydCB0aGUgY3VycmVudCBoZWFkZXIgaWYgREFVIGlzIHN0aWxsIHNlYXJjaGluZyBmb3IgYSBwYWdlICovCgkJCWlmIChyZXEtPnN0YXJ0IDw9IDMxICYmIHJlcS0+ZW5kID49IDcgJiYgdC0+aXNfc2VhcmNoaW5nW3JlcS0+cGdidWZdKQoJCQl7CgkJCQljaGFyIGJ1ZlszMl07CgkJCQlpbnQgbGVuOwoJCQkJc3RhcnQgPSBtYXgocmVxLT5zdGFydCwgNyk7CgkJCQllbmQgPSBtaW4ocmVxLT5lbmQsIDMxKTsKCQkJCWxlbj1lbmQtc3RhcnQrMTsKCQkJCWlmIChpMmNfc2VuZGRhdGEodCwgOCwgMCwgMCwgc3RhcnQsIC0xKSB8fAoJCQkJCWkyY19nZXRkYXRhKHQsIGxlbiwgYnVmKSkKCQkJCQlyZXR1cm4gLUVJTzsKCQkJCWlmKGNvcHlfdG9fdXNlcihyZXEtPmJ1ZmZlcitzdGFydC1yZXEtPnN0YXJ0LCBidWYsIGxlbikpCgkJCQkJcmV0dXJuIC1FRkFVTFQ7CgkJCX0KCQkJcmV0dXJuIDA7CgkJfQoKCQljYXNlIFZUWElPQ1NUT1BEQVU6CgkJewoJCQl2dHhfcGFnZXJlcV90ICpyZXEgPSBhcmc7CgoJCQlpZiAocmVxLT5wZ2J1ZiA8IDAgfHwgcmVxLT5wZ2J1ZiA+PSBOVU1fREFVUykKCQkJCXJldHVybiAtRUlOVkFMOwoJCQl0LT52ZGF1W3JlcS0+cGdidWZdLnN0b3BwZWQgPSBUUlVFOwoJCQl0LT5pc19zZWFyY2hpbmdbcmVxLT5wZ2J1Zl0gPSBGQUxTRTsKCQkJcmV0dXJuIDA7CgkJfQoKCQljYXNlIFZUWElPQ1BVVFBBR0U6CgkJY2FzZSBWVFhJT0NTRVRESVNQOgoJCWNhc2UgVlRYSU9DUFVUU1RBVDoKCQkJcmV0dXJuIDA7CgoJCWNhc2UgVlRYSU9DQ0xSQ0FDSEU6CgkJewoJCQlpZiAoaTJjX3NlbmRkYXRhKHQsIDAsIE5VTV9EQVVTLCAwLCA4LCAtMSkgfHwgaTJjX3NlbmRkYXRhKHQsIDExLAoJCQkJJyAnLCcgJywnICcsJyAnLCcgJywnICcsJyAnLCcgJywnICcsJyAnLCcgJywnICcsCgkJCQknICcsJyAnLCcgJywnICcsJyAnLCcgJywnICcsJyAnLCcgJywnICcsJyAnLCcgJywgLTEpKQoJCQkJcmV0dXJuIC1FSU87CgkJCWlmIChpMmNfc2VuZGRhdGEodCwgMywgMHgyMCwgLTEpKQoJCQkJcmV0dXJuIC1FSU87CgkJCWpkZWxheSgxMCAqIENMRUFSX0RFTEFZKTsJCQkvKiBJIGhhdmUgbm8gaWRlYSBob3cgbG9uZyB3ZSBoYXZlIHRvIHdhaXQgaGVyZSAqLwoJCQlyZXR1cm4gMDsKCQl9CgoJCWNhc2UgVlRYSU9DU0VUVklSVDoKCQl7CgkJCS8qIFRoZSBTQUE1MjQ5IGhhcyB2aXJ0dWFsLXJvdyByZWNlcHRpb24gdHVybmVkIG9uIGFsd2F5cyAqLwoJCQl0LT52aXJ0dWFsX21vZGUgPSAoaW50KShsb25nKWFyZzsKCQkJcmV0dXJuIDA7CgkJfQoJfQoJcmV0dXJuIC1FSU5WQUw7Cn0KCi8qCiAqIFRyYW5zbGF0ZXMgb2xkIHZ0eCBJT0NUTHMgdG8gbmV3IG9uZXMKICoKICogVGhpcyBrZWVwcyBuZXcga2VybmVsIHZlcnNpb25zIGNvbXBhdGlibGUgd2l0aCBvbGQgdXNlcnNwYWNlIHByb2dyYW1zLgogKi8Kc3RhdGljIGlubGluZSB1bnNpZ25lZCBpbnQgdnR4X2ZpeF9jb21tYW5kKHVuc2lnbmVkIGludCBjbWQpCnsKCXN3aXRjaCAoY21kKSB7CgljYXNlIFZUWElPQ0dFVElORk9fT0xEOgoJCWNtZCA9IFZUWElPQ0dFVElORk87CgkJYnJlYWs7CgljYXNlIFZUWElPQ0NMUlBBR0VfT0xEOgoJCWNtZCA9IFZUWElPQ0NMUlBBR0U7CgkJYnJlYWs7CgljYXNlIFZUWElPQ0NMUkZPVU5EX09MRDoKCQljbWQgPSBWVFhJT0NDTFJGT1VORDsKCQlicmVhazsKCWNhc2UgVlRYSU9DUEFHRVJFUV9PTEQ6CgkJY21kID0gVlRYSU9DUEFHRVJFUTsKCQlicmVhazsKCWNhc2UgVlRYSU9DR0VUU1RBVF9PTEQ6CgkJY21kID0gVlRYSU9DR0VUU1RBVDsKCQlicmVhazsKCWNhc2UgVlRYSU9DR0VUUEFHRV9PTEQ6CgkJY21kID0gVlRYSU9DR0VUUEFHRTsKCQlicmVhazsKCWNhc2UgVlRYSU9DU1RPUERBVV9PTEQ6CgkJY21kID0gVlRYSU9DU1RPUERBVTsKCQlicmVhazsKCWNhc2UgVlRYSU9DUFVUUEFHRV9PTEQ6CgkJY21kID0gVlRYSU9DUFVUUEFHRTsKCQlicmVhazsKCWNhc2UgVlRYSU9DU0VURElTUF9PTEQ6CgkJY21kID0gVlRYSU9DU0VURElTUDsKCQlicmVhazsKCWNhc2UgVlRYSU9DUFVUU1RBVF9PTEQ6CgkJY21kID0gVlRYSU9DUFVUU1RBVDsKCQlicmVhazsKCWNhc2UgVlRYSU9DQ0xSQ0FDSEVfT0xEOgoJCWNtZCA9IFZUWElPQ0NMUkNBQ0hFOwoJCWJyZWFrOwoJY2FzZSBWVFhJT0NTRVRWSVJUX09MRDoKCQljbWQgPSBWVFhJT0NTRVRWSVJUOwoJCWJyZWFrOwoJfQoJcmV0dXJuIGNtZDsKfQoKLyoKICoJSGFuZGxlIHRoZSBsb2NraW5nCiAqLwoKc3RhdGljIGludCBzYWE1MjQ5X2lvY3RsKHN0cnVjdCBpbm9kZSAqaW5vZGUsIHN0cnVjdCBmaWxlICpmaWxlLAoJCQkgdW5zaWduZWQgaW50IGNtZCwgdW5zaWduZWQgbG9uZyBhcmcpCnsKCXN0cnVjdCB2aWRlb19kZXZpY2UgKnZkID0gdmlkZW9fZGV2ZGF0YShmaWxlKTsKCXN0cnVjdCBzYWE1MjQ5X2RldmljZSAqdD12ZC0+cHJpdjsKCWludCBlcnI7CgoJY21kID0gdnR4X2ZpeF9jb21tYW5kKGNtZCk7CgltdXRleF9sb2NrKCZ0LT5sb2NrKTsKCWVyciA9IHZpZGVvX3VzZXJjb3B5KGlub2RlLGZpbGUsY21kLGFyZyxkb19zYWE1MjQ5X2lvY3RsKTsKCW11dGV4X3VubG9jaygmdC0+bG9jayk7CglyZXR1cm4gZXJyOwp9CgpzdGF0aWMgaW50IHNhYTUyNDlfb3BlbihzdHJ1Y3QgaW5vZGUgKmlub2RlLCBzdHJ1Y3QgZmlsZSAqZmlsZSkKewoJc3RydWN0IHZpZGVvX2RldmljZSAqdmQgPSB2aWRlb19kZXZkYXRhKGZpbGUpOwoJc3RydWN0IHNhYTUyNDlfZGV2aWNlICp0PXZkLT5wcml2OwoJaW50IGVycixwZ2J1ZjsKCgllcnIgPSB2aWRlb19leGNsdXNpdmVfb3Blbihpbm9kZSxmaWxlKTsKCWlmIChlcnIgPCAwKQoJCXJldHVybiBlcnI7CgoJaWYgKHQtPmNsaWVudD09TlVMTCkgewoJCWVyciA9IC1FTk9ERVY7CgkJZ290byBmYWlsOwoJfQoKCWlmIChpMmNfc2VuZGRhdGEodCwgMCwgMCwgLTEpIHx8CQkvKiBTZWxlY3QgUjExICovCgkJCQkJCS8qIFR1cm4gb2ZmIHBhcml0eSBjaGVja3MgKHdlIGRvIHRoaXMgb3Vyc2VsdmVzKSAqLwoJCWkyY19zZW5kZGF0YSh0LCAxLCBkaXNwX21vZGVzW3QtPmRpc3BfbW9kZV1bMF0sIDAsIC0xKSB8fAoJCQkJCQkvKiBEaXNwbGF5IFRWLXBpY3R1cmUsIG5vIHZpcnR1YWwgcm93cyAqLwoJCWkyY19zZW5kZGF0YSh0LCA0LCBOVU1fREFVUywgZGlzcF9tb2Rlc1t0LT5kaXNwX21vZGVdWzFdLCBkaXNwX21vZGVzW3QtPmRpc3BfbW9kZV1bMl0sIDcsIC0xKSkgLyogU2V0IGRpc3BsYXkgdG8gcGFnZSA0ICovCgoJewoJCWVyciA9IC1FSU87CgkJZ290byBmYWlsOwoJfQoKCWZvciAocGdidWYgPSAwOyBwZ2J1ZiA8IE5VTV9EQVVTOyBwZ2J1ZisrKQoJewoJCW1lbXNldCh0LT52ZGF1W3BnYnVmXS5wZ2J1ZiwgJyAnLCBzaXplb2YodC0+dmRhdVswXS5wZ2J1ZikpOwoJCW1lbXNldCh0LT52ZGF1W3BnYnVmXS5zcmVncywgMCwgc2l6ZW9mKHQtPnZkYXVbMF0uc3JlZ3MpKTsKCQltZW1zZXQodC0+dmRhdVtwZ2J1Zl0ubGFzdHN0YXQsIDAsIHNpemVvZih0LT52ZGF1WzBdLmxhc3RzdGF0KSk7CgkJdC0+dmRhdVtwZ2J1Zl0uZXhwaXJlID0gMDsKCQl0LT52ZGF1W3BnYnVmXS5jbHJmb3VuZCA9IFRSVUU7CgkJdC0+dmRhdVtwZ2J1Zl0uc3RvcHBlZCA9IFRSVUU7CgkJdC0+aXNfc2VhcmNoaW5nW3BnYnVmXSA9IEZBTFNFOwoJfQoJdC0+dmlydHVhbF9tb2RlPUZBTFNFOwoJcmV0dXJuIDA7CgogZmFpbDoKCXZpZGVvX2V4Y2x1c2l2ZV9yZWxlYXNlKGlub2RlLGZpbGUpOwoJcmV0dXJuIGVycjsKfQoKCgpzdGF0aWMgaW50IHNhYTUyNDlfcmVsZWFzZShzdHJ1Y3QgaW5vZGUgKmlub2RlLCBzdHJ1Y3QgZmlsZSAqZmlsZSkKewoJc3RydWN0IHZpZGVvX2RldmljZSAqdmQgPSB2aWRlb19kZXZkYXRhKGZpbGUpOwoJc3RydWN0IHNhYTUyNDlfZGV2aWNlICp0PXZkLT5wcml2OwoJaTJjX3NlbmRkYXRhKHQsIDEsIDB4MjAsIC0xKTsJCS8qIFR1cm4gb2ZmIENDVCAqLwoJaTJjX3NlbmRkYXRhKHQsIDUsIDMsIDMsIC0xKTsJCS8qIFR1cm4gb2ZmIFRWLWRpc3BsYXkgKi8KCXZpZGVvX2V4Y2x1c2l2ZV9yZWxlYXNlKGlub2RlLGZpbGUpOwoJcmV0dXJuIDA7Cn0KCnN0YXRpYyBpbnQgX19pbml0IGluaXRfc2FhXzUyNDkgKHZvaWQpCnsKCXByaW50ayhLRVJOX0lORk8gIlNBQTUyNDkgZHJpdmVyICgiIElGX05BTUUgIiBpbnRlcmZhY2UpIGZvciBWaWRlb1RleHQgdmVyc2lvbiAlZC4lZFxuIiwKCQkJVlRYX1ZFUl9NQUosIFZUWF9WRVJfTUlOKTsKCXJldHVybiBpMmNfYWRkX2RyaXZlcigmaTJjX2RyaXZlcl92aWRlb3RleHQpOwp9CgpzdGF0aWMgdm9pZCBfX2V4aXQgY2xlYW51cF9zYWFfNTI0OSAodm9pZCkKewoJaTJjX2RlbF9kcml2ZXIoJmkyY19kcml2ZXJfdmlkZW90ZXh0KTsKfQoKbW9kdWxlX2luaXQoaW5pdF9zYWFfNTI0OSk7Cm1vZHVsZV9leGl0KGNsZWFudXBfc2FhXzUyNDkpOwoKc3RhdGljIHN0cnVjdCBmaWxlX29wZXJhdGlvbnMgc2FhX2ZvcHMgPSB7Cgkub3duZXIJCT0gVEhJU19NT0RVTEUsCgkub3BlbgkJPSBzYWE1MjQ5X29wZW4sCgkucmVsZWFzZSAgICAgICAJPSBzYWE1MjQ5X3JlbGVhc2UsCgkuaW9jdGwgICAgICAgICAgPSBzYWE1MjQ5X2lvY3RsLAoJLmNvbXBhdF9pb2N0bAk9IHY0bF9jb21wYXRfaW9jdGwzMiwKCS5sbHNlZWsgICAgICAgICA9IG5vX2xsc2VlaywKfTsKCnN0YXRpYyBzdHJ1Y3QgdmlkZW9fZGV2aWNlIHNhYV90ZW1wbGF0ZSA9CnsKCS5vd25lcgkJPSBUSElTX01PRFVMRSwKCS5uYW1lCQk9IElGX05BTUUsCgkudHlwZQkJPSBWSURfVFlQRV9URUxFVEVYVCwJLyp8IFZJRF9UWVBFX1RVTkVSID8/ICovCgkuaGFyZHdhcmUJPSBWSURfSEFSRFdBUkVfU0FBNTI0OSwKCS5mb3BzICAgICAgICAgICA9ICZzYWFfZm9wcywKfTsKCk1PRFVMRV9MSUNFTlNFKCJHUEwiKTsK