LyoKICogTW9kaWZpZWQgaW4gb3JkZXIgdG8ga2VlcCBpdCBjb21wYXRpYmxlIGJvdGggd2l0aCBuZXcgYW5kIG9sZCB2aWRlb3RleHQgSU9DVExzIGJ5CiAqIE1pY2hhZWwgR2VuZyA8bGludXhATWljaGFlbEdlbmcuZGU+CiAqCiAqCUNsZWFuZWQgdXAgdG8gdXNlIGV4aXN0aW5nIHZpZGVvZGV2IGludGVyZmFjZSBhbmQgYWxsb3cgdGhlIGlkZWEKICoJb2YgbXVsdGlwbGUgdGVsZXRleHQgZGVjb2RlcnMgb24gdGhlIHZpZGVvNGxpbnV4IGlmYWNlLiBDaGFuZ2VkIGkyYwogKgl0byBjb3ZlciBhZGRyZXNzaW5nIGNsYXNoZXMgb24gZGV2aWNlIGJ1c3Nlcy4gSXQncyBhbHNvIHJlYnVpbHQgc28KICoJeW91IGNhbiBhZGQgYXJiaXRhcnkgbXVsdGlwbGUgdGVsZXRleHQgZGV2aWNlcyB0byBMaW51eCB2aWRlbzRsaW51eAogKglub3cgKHdlbGwgMzIgYW55d2F5KS4KICoKICoJQWxhbiBDb3ggPEFsYW4uQ294QGxpbnV4Lm9yZz4KICoKICoJVGhlIG9yaWdpbmFsIGRyaXZlciB3YXMgaGVhdmlseSBtb2RpZmllZCB0byBtYXRjaCB0aGUgaTJjIGludGVyZmFjZQogKglJdCB3YXMgdHJ1bmNhdGVkIHRvIHVzZSB0aGUgV2luVFYgYm9hcmRzLCB0b28uCiAqCiAqCUNvcHlyaWdodCAoYykgMTk5OCBSaWNoYXJkIEd1ZW50aGVyIDxyaWNoYXJkLmd1ZW50aGVyQHN0dWRlbnQudW5pLXR1ZWJpbmdlbi5kZT4KICoKICogJElkOiBzYWE1MjQ5LmMsdiAxLjEgMTk5OC8wMy8zMCAyMjoyMzoyMyBhbGFuIEV4cCAkCiAqCiAqCURlcml2ZWQgRnJvbQogKgogKiB2dHguYzoKICogVGhpcyBpcyBhIGxvYWRhYmxlIGNoYXJhY3Rlci1kZXZpY2UtZHJpdmVyIGZvciB2aWRlb3RleHQtaW50ZXJmYWNlcwogKiAoYWthIHRlbGV0ZXh0KS4gUGxlYXNlIGNoZWNrIHRoZSBNYWtlZmlsZS9SRUFETUUgZm9yIGEgbGlzdCBvZiBzdXBwb3J0ZWQKICogaW50ZXJmYWNlcy4KICoKICogQ29weXJpZ2h0IChjKSAxOTk0LTk3IE1hcnRpbiBCdWNrICA8bWFydGluLTIuYnVja0BzdHVkZW50LnVuaS11bG0uZGU+CiAqCiAqCiAqIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5CiAqIGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5CiAqIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlciB2ZXJzaW9uIDIgb2YgdGhlIExpY2Vuc2UsIG9yCiAqIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlCiAqIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIGFsb25nIHdpdGggdGhpcyBwcm9ncmFtOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDU5IFRlbXBsZSBQbGFjZSAtIFN1aXRlIDMzMCwgQm9zdG9uLCBNQSAwMjExMS0xMzA3LAogKiBVU0EuCiAqLwoKI2luY2x1ZGUgPGxpbnV4L21vZHVsZS5oPgojaW5jbHVkZSA8bGludXgva2VybmVsLmg+CiNpbmNsdWRlIDxsaW51eC9zY2hlZC5oPgojaW5jbHVkZSA8bGludXgvbW0uaD4KI2luY2x1ZGUgPGxpbnV4L2Vycm5vLmg+CiNpbmNsdWRlIDxsaW51eC9kZWxheS5oPgojaW5jbHVkZSA8bGludXgvaW9wb3J0Lmg+CiNpbmNsdWRlIDxsaW51eC9zbGFiLmg+CiNpbmNsdWRlIDxsaW51eC9pbml0Lmg+CiNpbmNsdWRlIDxzdGRhcmcuaD4KI2luY2x1ZGUgPGxpbnV4L2kyYy5oPgojaW5jbHVkZSA8bGludXgvdmlkZW90ZXh0Lmg+CiNpbmNsdWRlIDxsaW51eC92aWRlb2Rldi5oPgojaW5jbHVkZSA8bWVkaWEvdjRsMi1jb21tb24uaD4KI2luY2x1ZGUgPGxpbnV4L211dGV4Lmg+CgoKI2luY2x1ZGUgPGFzbS9pby5oPgojaW5jbHVkZSA8YXNtL3VhY2Nlc3MuaD4KCiNkZWZpbmUgVlRYX1ZFUl9NQUogMQojZGVmaW5lIFZUWF9WRVJfTUlOIDgKCgoKI2RlZmluZSBOVU1fREFVUyA0CiNkZWZpbmUgTlVNX0JVRlMgOAojZGVmaW5lIElGX05BTUUgIlNBQTUyNDkiCgpzdGF0aWMgY29uc3QgaW50IGRpc3BfbW9kZXNbOF1bM10gPQp7Cgl7IDB4NDYsIDB4MDMsIDB4MDMgfSwJLyogRElTUE9GRiAqLwoJeyAweDQ2LCAweGNjLCAweGNjIH0sCS8qIERJU1BOT1JNICovCgl7IDB4NDQsIDB4MGYsIDB4MGYgfSwJLyogRElTUFRSQU5TICovCgl7IDB4NDYsIDB4Y2MsIDB4NDYgfSwJLyogRElTUElOUyAqLwoJeyAweDQ0LCAweDAzLCAweDAzIH0sCS8qIERJU1BPRkYsIGludGVybGFjZWQgKi8KCXsgMHg0NCwgMHhjYywgMHhjYyB9LAkvKiBESVNQTk9STSwgaW50ZXJsYWNlZCAqLwoJeyAweDQ0LCAweDBmLCAweDBmIH0sCS8qIERJU1BUUkFOUywgaW50ZXJsYWNlZCAqLwoJeyAweDQ0LCAweGNjLCAweDQ2IH0JLyogRElTUElOUywgaW50ZXJsYWNlZCAqLwp9OwoKCgojZGVmaW5lIFBBR0VfV0FJVCAoMzAwKkhaLzEwMDApCQkJLyogVGltZSBiZXR3ZWVuIHJlcXVlc3RpbmcgcGFnZSBhbmQgKi8KCQkJCQkJLyogY2hlY2tpbmcgc3RhdHVzIGJpdHMgKi8KI2RlZmluZSBQR0JVRl9FWFBJUkUgKDE1KkhaKQkJCS8qIFRpbWUgdG8gd2FpdCBiZWZvcmUgcmV0cmFuc21pdHRpbmcgKi8KCQkJCQkJLyogcGFnZSByZWdhcmRsZXNzIG9mIGluZm9iaXRzICovCnR5cGVkZWYgc3RydWN0IHsKCXU4IHBnYnVmW1ZUWF9WSVJUVUFMU0laRV07CQkvKiBQYWdlLWJ1ZmZlciAqLwoJdTggbGFzdHN0YXRbMTBdOwkJCS8qIExhc3QgdmFsdWUgb2YgaW5mb2JpdHMgZm9yIERBVSAqLwoJdTggc3JlZ3NbN107CQkJCS8qIFBhZ2UtcmVxdWVzdCByZWdpc3RlcnMgKi8KCXVuc2lnbmVkIGxvbmcgZXhwaXJlOwkJCS8qIFRpbWUgd2hlbiBwYWdlIHdpbGwgYmUgZXhwaXJlZCAqLwoJdW5zaWduZWQgY2xyZm91bmQgOiAxOwkJCS8qIFZUWElPQ0NMUkZPVU5EIGhhcyBiZWVuIGNhbGxlZCAqLwoJdW5zaWduZWQgc3RvcHBlZCA6IDE7CQkJLyogVlRYSU9DU1RPUERBVSBoYXMgYmVlbiBjYWxsZWQgKi8KfSB2ZGF1X3Q7CgpzdHJ1Y3Qgc2FhNTI0OV9kZXZpY2UKewoJdmRhdV90IHZkYXVbTlVNX0RBVVNdOwkJCS8qIERhdGEgZm9yIHZpcnR1YWwgREFVcyAodGhlIDUyNDkgb25seSBoYXMgb25lICovCgkJCQkJCS8qIHJlYWwgREFVLCBzbyB3ZSBoYXZlIHRvIHNpbXVsYXRlIHNvbWUgbW9yZSkgKi8KCWludCB2dHhfdXNlX2NvdW50OwoJaW50IGlzX3NlYXJjaGluZ1tOVU1fREFVU107CglpbnQgZGlzcF9tb2RlOwoJaW50IHZpcnR1YWxfbW9kZTsKCXN0cnVjdCBpMmNfY2xpZW50ICpjbGllbnQ7CglzdHJ1Y3QgbXV0ZXggbG9jazsKfTsKCgojZGVmaW5lIENDVFdSIDM0CQkvKiBJskMgd3JpdGUvcmVhZC1hZGRyZXNzIG9mIHZ0eC1jaGlwICovCiNkZWZpbmUgQ0NUUkQgMzUKI2RlZmluZSBOT0FDS19SRVBFQVQgMTAJCS8qIFJldHJ5IGFjY2VzcyB0aGlzIG1hbnkgdGltZXMgb24gZmFpbHVyZSAqLwojZGVmaW5lIENMRUFSX0RFTEFZIChIWi8yMCkJLyogVGltZSByZXF1aXJlZCB0byBjbGVhciBhIHBhZ2UgKi8KI2RlZmluZSBSRUFEWV9USU1FT1VUICgzMCpIWi8xMDAwKQkvKiBUaW1lIHRvIHdhaXQgZm9yIHJlYWR5IHNpZ25hbCBvZiBJskMtYnVzIGludGVyZmFjZSAqLwojZGVmaW5lIElOSVRfREVMQVkgNTAwCQkvKiBUaW1lIGluIHVzZWMgdG8gd2FpdCBhdCBpbml0aWFsaXphdGlvbiBvZiBDRUEgaW50ZXJmYWNlICovCiNkZWZpbmUgU1RBUlRfREVMQVkgMTAJCS8qIFRpbWUgaW4gdXNlYyB0byB3YWl0IGJlZm9yZSBzdGFydGluZyB3cml0ZS1jeWNsZSAoQ0VBKSAqLwoKI2RlZmluZSBWVFhfREVWX01JTk9SIDAKCi8qIEdlbmVyYWwgZGVmaW5lcyBhbmQgZGVidWdnaW5nIHN1cHBvcnQgKi8KCiNkZWZpbmUgUkVTQ0hFRCBkbyB7IGNvbmRfcmVzY2hlZCgpOyB9IHdoaWxlKDApCgpzdGF0aWMgc3RydWN0IHZpZGVvX2RldmljZSBzYWFfdGVtcGxhdGU7CS8qIERlY2xhcmVkIG5lYXIgYm90dG9tICovCgovKiBBZGRyZXNzZXMgdG8gc2NhbiAqLwpzdGF0aWMgdW5zaWduZWQgc2hvcnQgbm9ybWFsX2kyY1tdID0gezM0Pj4xLEkyQ19DTElFTlRfRU5EfTsKSTJDX0NMSUVOVF9JTlNNT0Q7CgpzdGF0aWMgc3RydWN0IGkyY19jbGllbnQgY2xpZW50X3RlbXBsYXRlOwoKc3RhdGljIGludCBzYWE1MjQ5X2F0dGFjaChzdHJ1Y3QgaTJjX2FkYXB0ZXIgKmFkYXAsIGludCBhZGRyLCBpbnQga2luZCkKewoJaW50IHBnYnVmOwoJaW50IGVycjsKCXN0cnVjdCBpMmNfY2xpZW50ICpjbGllbnQ7CglzdHJ1Y3QgdmlkZW9fZGV2aWNlICp2ZDsKCXN0cnVjdCBzYWE1MjQ5X2RldmljZSAqdDsKCglwcmludGsoS0VSTl9JTkZPICJzYWE1MjQ5OiB0ZWxldGV4dCBjaGlwIGZvdW5kLlxuIik7CgljbGllbnQ9a21hbGxvYyhzaXplb2YoKmNsaWVudCksIEdGUF9LRVJORUwpOwoJaWYoY2xpZW50PT1OVUxMKQoJCXJldHVybiAtRU5PTUVNOwoJY2xpZW50X3RlbXBsYXRlLmFkYXB0ZXIgPSBhZGFwOwoJY2xpZW50X3RlbXBsYXRlLmFkZHIgPSBhZGRyOwoJbWVtY3B5KGNsaWVudCwgJmNsaWVudF90ZW1wbGF0ZSwgc2l6ZW9mKCpjbGllbnQpKTsKCXQgPSBremFsbG9jKHNpemVvZigqdCksIEdGUF9LRVJORUwpOwoJaWYodD09TlVMTCkKCXsKCQlrZnJlZShjbGllbnQpOwoJCXJldHVybiAtRU5PTUVNOwoJfQoJc3RybGNweShjbGllbnQtPm5hbWUsIElGX05BTUUsIEkyQ19OQU1FX1NJWkUpOwoJbXV0ZXhfaW5pdCgmdC0+bG9jayk7CgoJLyoKCSAqCU5vdyBjcmVhdGUgYSB2aWRlbzRsaW51eCBkZXZpY2UKCSAqLwoKCXZkID0ga21hbGxvYyhzaXplb2Yoc3RydWN0IHZpZGVvX2RldmljZSksIEdGUF9LRVJORUwpOwoJaWYodmQ9PU5VTEwpCgl7CgkJa2ZyZWUodCk7CgkJa2ZyZWUoY2xpZW50KTsKCQlyZXR1cm4gLUVOT01FTTsKCX0KCWkyY19zZXRfY2xpZW50ZGF0YShjbGllbnQsIHZkKTsKCW1lbWNweSh2ZCwgJnNhYV90ZW1wbGF0ZSwgc2l6ZW9mKCp2ZCkpOwoKCWZvciAocGdidWYgPSAwOyBwZ2J1ZiA8IE5VTV9EQVVTOyBwZ2J1ZisrKQoJewoJCW1lbXNldCh0LT52ZGF1W3BnYnVmXS5wZ2J1ZiwgJyAnLCBzaXplb2YodC0+dmRhdVswXS5wZ2J1ZikpOwoJCW1lbXNldCh0LT52ZGF1W3BnYnVmXS5zcmVncywgMCwgc2l6ZW9mKHQtPnZkYXVbMF0uc3JlZ3MpKTsKCQltZW1zZXQodC0+dmRhdVtwZ2J1Zl0ubGFzdHN0YXQsIDAsIHNpemVvZih0LT52ZGF1WzBdLmxhc3RzdGF0KSk7CgkJdC0+dmRhdVtwZ2J1Zl0uZXhwaXJlID0gMDsKCQl0LT52ZGF1W3BnYnVmXS5jbHJmb3VuZCA9IHRydWU7CgkJdC0+dmRhdVtwZ2J1Zl0uc3RvcHBlZCA9IHRydWU7CgkJdC0+aXNfc2VhcmNoaW5nW3BnYnVmXSA9IGZhbHNlOwoJfQoJdmQtPnByaXY9dDsKCgoJLyoKCSAqCVJlZ2lzdGVyIGl0CgkgKi8KCglpZigoZXJyPXZpZGVvX3JlZ2lzdGVyX2RldmljZSh2ZCwgVkZMX1RZUEVfVlRYLC0xKSk8MCkKCXsKCQlrZnJlZSh0KTsKCQlrZnJlZSh2ZCk7CgkJa2ZyZWUoY2xpZW50KTsKCQlyZXR1cm4gZXJyOwoJfQoJdC0+Y2xpZW50ID0gY2xpZW50OwoJaTJjX2F0dGFjaF9jbGllbnQoY2xpZW50KTsKCXJldHVybiAwOwp9CgovKgogKglXZSBkbyBtb3N0IG9mIHRoZSBoYXJkIHdvcmsgd2hlbiB3ZSBiZWNvbWUgYSBkZXZpY2Ugb24gdGhlIGkyYy4KICovCgpzdGF0aWMgaW50IHNhYTUyNDlfcHJvYmUoc3RydWN0IGkyY19hZGFwdGVyICphZGFwKQp7CglpZiAoYWRhcC0+Y2xhc3MgJiBJMkNfQ0xBU1NfVFZfQU5BTE9HKQoJCXJldHVybiBpMmNfcHJvYmUoYWRhcCwgJmFkZHJfZGF0YSwgc2FhNTI0OV9hdHRhY2gpOwoJcmV0dXJuIDA7Cn0KCnN0YXRpYyBpbnQgc2FhNTI0OV9kZXRhY2goc3RydWN0IGkyY19jbGllbnQgKmNsaWVudCkKewoJc3RydWN0IHZpZGVvX2RldmljZSAqdmQgPSBpMmNfZ2V0X2NsaWVudGRhdGEoY2xpZW50KTsKCWkyY19kZXRhY2hfY2xpZW50KGNsaWVudCk7Cgl2aWRlb191bnJlZ2lzdGVyX2RldmljZSh2ZCk7CglrZnJlZSh2ZC0+cHJpdik7CglrZnJlZSh2ZCk7CglrZnJlZShjbGllbnQpOwoJcmV0dXJuIDA7Cn0KCi8qIG5ldyBJMkMgZHJpdmVyIHN1cHBvcnQgKi8KCnN0YXRpYyBzdHJ1Y3QgaTJjX2RyaXZlciBpMmNfZHJpdmVyX3ZpZGVvdGV4dCA9CnsKCS5kcml2ZXIgPSB7CgkJLm5hbWUgCT0gSUZfTkFNRSwJCS8qIG5hbWUgKi8KCX0sCgkuaWQgCQk9IEkyQ19EUklWRVJJRF9TQUE1MjQ5LCAvKiBpbiBpMmMuaCAqLwoJLmF0dGFjaF9hZGFwdGVyID0gc2FhNTI0OV9wcm9iZSwKCS5kZXRhY2hfY2xpZW50ICA9IHNhYTUyNDlfZGV0YWNoLAp9OwoKc3RhdGljIHN0cnVjdCBpMmNfY2xpZW50IGNsaWVudF90ZW1wbGF0ZSA9IHsKCS5kcml2ZXIJCT0gJmkyY19kcml2ZXJfdmlkZW90ZXh0LAoJLm5hbWUJCT0gIih1bnNldCkiLAp9OwoKLyoKICoJV2FpdCB0aGUgZ2l2ZW4gbnVtYmVyIG9mIGppZmZpZXMgKDEwbXMpLiBUaGlzIGNhbGxzIHRoZSBzY2hlZHVsZXIsIHNvIHRoZSBhY3R1YWwKICoJZGVsYXkgbWF5IGJlIGxvbmdlci4KICovCgpzdGF0aWMgdm9pZCBqZGVsYXkodW5zaWduZWQgbG9uZyBkZWxheSkKewoJc2lnc2V0X3Qgb2xkYmxvY2tlZCA9IGN1cnJlbnQtPmJsb2NrZWQ7CgoJc3Bpbl9sb2NrX2lycSgmY3VycmVudC0+c2lnaGFuZC0+c2lnbG9jayk7CglzaWdmaWxsc2V0KCZjdXJyZW50LT5ibG9ja2VkKTsKCXJlY2FsY19zaWdwZW5kaW5nKCk7CglzcGluX3VubG9ja19pcnEoJmN1cnJlbnQtPnNpZ2hhbmQtPnNpZ2xvY2spOwoJbXNsZWVwX2ludGVycnVwdGlibGUoamlmZmllc190b19tc2VjcyhkZWxheSkpOwoKCXNwaW5fbG9ja19pcnEoJmN1cnJlbnQtPnNpZ2hhbmQtPnNpZ2xvY2spOwoJY3VycmVudC0+YmxvY2tlZCA9IG9sZGJsb2NrZWQ7CglyZWNhbGNfc2lncGVuZGluZygpOwoJc3Bpbl91bmxvY2tfaXJxKCZjdXJyZW50LT5zaWdoYW5kLT5zaWdsb2NrKTsKfQoKCi8qCiAqCUkyQyBpbnRlcmZhY2VzCiAqLwoKc3RhdGljIGludCBpMmNfc2VuZGJ1ZihzdHJ1Y3Qgc2FhNTI0OV9kZXZpY2UgKnQsIGludCByZWcsIGludCBjb3VudCwgdTggKmRhdGEpCnsKCWNoYXIgYnVmWzY0XTsKCglidWZbMF0gPSByZWc7CgltZW1jcHkoYnVmKzEsIGRhdGEsIGNvdW50KTsKCglpZihpMmNfbWFzdGVyX3NlbmQodC0+Y2xpZW50LCBidWYsIGNvdW50KzEpPT1jb3VudCsxKQoJCXJldHVybiAwOwoJcmV0dXJuIC0xOwp9CgpzdGF0aWMgaW50IGkyY19zZW5kZGF0YShzdHJ1Y3Qgc2FhNTI0OV9kZXZpY2UgKnQsIC4uLikKewoJdW5zaWduZWQgY2hhciBidWZbNjRdOwoJaW50IHY7CglpbnQgY3Q9MDsKCXZhX2xpc3QgYXJncDsKCXZhX3N0YXJ0KGFyZ3AsdCk7CgoJd2hpbGUoKHY9dmFfYXJnKGFyZ3AsaW50KSkhPS0xKQoJCWJ1ZltjdCsrXT12OwoJcmV0dXJuIGkyY19zZW5kYnVmKHQsIGJ1ZlswXSwgY3QtMSwgYnVmKzEpOwp9CgovKiBHZXQgY291bnQgbnVtYmVyIG9mIGJ5dGVzIGZyb20gSbJDLWRldmljZSBhdCBhZGRyZXNzIGFkciwgc3RvcmUgdGhlbSBpbiBidWYuIFN0YXJ0ICYgc3RvcAogKiBoYW5kc2hha2luZyBpcyBkb25lIGJ5IHRoaXMgcm91dGluZSwgYWNrIHdpbGwgYmUgc2VudCBhZnRlciB0aGUgbGFzdCBieXRlIHRvIGluaGliaXQgZnVydGhlcgogKiBzZW5kaW5nIG9mIGRhdGEuIElmIHVhY2Nlc3MgaXMgJ3RydWUnLCBkYXRhIGlzIHdyaXR0ZW4gdG8gdXNlci1zcGFjZSB3aXRoIHB1dF91c2VyLgogKiBSZXR1cm5zIC0xIGlmIEmyQy1kZXZpY2UgZGlkbid0IHNlbmQgYWNrbm93bGVkZ2UsIDAgb3RoZXJ3aXNlCiAqLwoKc3RhdGljIGludCBpMmNfZ2V0ZGF0YShzdHJ1Y3Qgc2FhNTI0OV9kZXZpY2UgKnQsIGludCBjb3VudCwgdTggKmJ1ZikKewoJaWYoaTJjX21hc3Rlcl9yZWN2KHQtPmNsaWVudCwgYnVmLCBjb3VudCkhPWNvdW50KQoJCXJldHVybiAtMTsKCXJldHVybiAwOwp9CgoKLyoKICoJU3RhbmRhcmQgY2hhcmFjdGVyLWRldmljZS1kcml2ZXIgZnVuY3Rpb25zCiAqLwoKc3RhdGljIGludCBkb19zYWE1MjQ5X2lvY3RsKHN0cnVjdCBpbm9kZSAqaW5vZGUsIHN0cnVjdCBmaWxlICpmaWxlLAoJCQkgICAgdW5zaWduZWQgaW50IGNtZCwgdm9pZCAqYXJnKQp7CglzdGF0aWMgaW50IHZpcnR1YWxfbW9kZSA9IGZhbHNlOwoJc3RydWN0IHZpZGVvX2RldmljZSAqdmQgPSB2aWRlb19kZXZkYXRhKGZpbGUpOwoJc3RydWN0IHNhYTUyNDlfZGV2aWNlICp0PXZkLT5wcml2OwoKCXN3aXRjaChjbWQpCgl7CgkJY2FzZSBWVFhJT0NHRVRJTkZPOgoJCXsKCQkJdnR4X2luZm9fdCAqaW5mbyA9IGFyZzsKCQkJaW5mby0+dmVyc2lvbl9tYWpvciA9IFZUWF9WRVJfTUFKOwoJCQlpbmZvLT52ZXJzaW9uX21pbm9yID0gVlRYX1ZFUl9NSU47CgkJCWluZm8tPm51bXBhZ2VzID0gTlVNX0RBVVM7CgkJCS8qaW5mby0+Y2N0X3R5cGUgPSBDQ1RfVFlQRTsqLwoJCQlyZXR1cm4gMDsKCQl9CgoJCWNhc2UgVlRYSU9DQ0xSUEFHRToKCQl7CgkJCXZ0eF9wYWdlcmVxX3QgKnJlcSA9IGFyZzsKCgkJCWlmIChyZXEtPnBnYnVmIDwgMCB8fCByZXEtPnBnYnVmID49IE5VTV9EQVVTKQoJCQkJcmV0dXJuIC1FSU5WQUw7CgkJCW1lbXNldCh0LT52ZGF1W3JlcS0+cGdidWZdLnBnYnVmLCAnICcsIHNpemVvZih0LT52ZGF1WzBdLnBnYnVmKSk7CgkJCXQtPnZkYXVbcmVxLT5wZ2J1Zl0uY2xyZm91bmQgPSB0cnVlOwoJCQlyZXR1cm4gMDsKCQl9CgoJCWNhc2UgVlRYSU9DQ0xSRk9VTkQ6CgkJewoJCQl2dHhfcGFnZXJlcV90ICpyZXEgPSBhcmc7CgoJCQlpZiAocmVxLT5wZ2J1ZiA8IDAgfHwgcmVxLT5wZ2J1ZiA+PSBOVU1fREFVUykKCQkJCXJldHVybiAtRUlOVkFMOwoJCQl0LT52ZGF1W3JlcS0+cGdidWZdLmNscmZvdW5kID0gdHJ1ZTsKCQkJcmV0dXJuIDA7CgkJfQoKCQljYXNlIFZUWElPQ1BBR0VSRVE6CgkJewoJCQl2dHhfcGFnZXJlcV90ICpyZXEgPSBhcmc7CgkJCWlmICghKHJlcS0+cGFnZW1hc2sgJiBQR01BU0tfUEFHRSkpCgkJCQlyZXEtPnBhZ2UgPSAwOwoJCQlpZiAoIShyZXEtPnBhZ2VtYXNrICYgUEdNQVNLX0hPVVIpKQoJCQkJcmVxLT5ob3VyID0gMDsKCQkJaWYgKCEocmVxLT5wYWdlbWFzayAmIFBHTUFTS19NSU5VVEUpKQoJCQkJcmVxLT5taW51dGUgPSAwOwoJCQlpZiAocmVxLT5wYWdlIDwgMCB8fCByZXEtPnBhZ2UgPiAweDhmZikgLyogN0ZGID8/ICovCgkJCQlyZXR1cm4gLUVJTlZBTDsKCQkJcmVxLT5wYWdlICY9IDB4N2ZmOwoJCQlpZiAocmVxLT5ob3VyIDwgMCB8fCByZXEtPmhvdXIgPiAweDNmIHx8IHJlcS0+bWludXRlIDwgMCB8fCByZXEtPm1pbnV0ZSA+IDB4N2YgfHwKCQkJCXJlcS0+cGFnZW1hc2sgPCAwIHx8IHJlcS0+cGFnZW1hc2sgPj0gUEdNQVNLX01BWCB8fCByZXEtPnBnYnVmIDwgMCB8fCByZXEtPnBnYnVmID49IE5VTV9EQVVTKQoJCQkJcmV0dXJuIC1FSU5WQUw7CgkJCXQtPnZkYXVbcmVxLT5wZ2J1Zl0uc3JlZ3NbMF0gPSAocmVxLT5wYWdlbWFzayAmIFBHX0hVTkQgPyAweDEwIDogMCkgfCAocmVxLT5wYWdlIC8gMHgxMDApOwoJCQl0LT52ZGF1W3JlcS0+cGdidWZdLnNyZWdzWzFdID0gKHJlcS0+cGFnZW1hc2sgJiBQR19URU4gPyAweDEwIDogMCkgfCAoKHJlcS0+cGFnZSAvIDB4MTApICYgMHhmKTsKCQkJdC0+dmRhdVtyZXEtPnBnYnVmXS5zcmVnc1syXSA9IChyZXEtPnBhZ2VtYXNrICYgUEdfVU5JVCA/IDB4MTAgOiAwKSB8IChyZXEtPnBhZ2UgJiAweGYpOwoJCQl0LT52ZGF1W3JlcS0+cGdidWZdLnNyZWdzWzNdID0gKHJlcS0+cGFnZW1hc2sgJiBIUl9URU4gPyAweDEwIDogMCkgfCAocmVxLT5ob3VyIC8gMHgxMCk7CgkJCXQtPnZkYXVbcmVxLT5wZ2J1Zl0uc3JlZ3NbNF0gPSAocmVxLT5wYWdlbWFzayAmIEhSX1VOSVQgPyAweDEwIDogMCkgfCAocmVxLT5ob3VyICYgMHhmKTsKCQkJdC0+dmRhdVtyZXEtPnBnYnVmXS5zcmVnc1s1XSA9IChyZXEtPnBhZ2VtYXNrICYgTUlOX1RFTiA/IDB4MTAgOiAwKSB8IChyZXEtPm1pbnV0ZSAvIDB4MTApOwoJCQl0LT52ZGF1W3JlcS0+cGdidWZdLnNyZWdzWzZdID0gKHJlcS0+cGFnZW1hc2sgJiBNSU5fVU5JVCA/IDB4MTAgOiAwKSB8IChyZXEtPm1pbnV0ZSAmIDB4Zik7CgkJCXQtPnZkYXVbcmVxLT5wZ2J1Zl0uc3RvcHBlZCA9IGZhbHNlOwoJCQl0LT52ZGF1W3JlcS0+cGdidWZdLmNscmZvdW5kID0gdHJ1ZTsKCQkJdC0+aXNfc2VhcmNoaW5nW3JlcS0+cGdidWZdID0gdHJ1ZTsKCQkJcmV0dXJuIDA7CgkJfQoKCQljYXNlIFZUWElPQ0dFVFNUQVQ6CgkJewoJCQl2dHhfcGFnZXJlcV90ICpyZXEgPSBhcmc7CgkJCXU4IGluZm9iaXRzWzEwXTsKCQkJdnR4X3BhZ2VpbmZvX3QgaW5mbzsKCQkJaW50IGE7CgoJCQlpZiAocmVxLT5wZ2J1ZiA8IDAgfHwgcmVxLT5wZ2J1ZiA+PSBOVU1fREFVUykKCQkJCXJldHVybiAtRUlOVkFMOwoJCQlpZiAoIXQtPnZkYXVbcmVxLT5wZ2J1Zl0uc3RvcHBlZCkKCQkJewoJCQkJaWYgKGkyY19zZW5kZGF0YSh0LCAyLCAwLCAtMSkgfHwKCQkJCQlpMmNfc2VuZGJ1Zih0LCAzLCBzaXplb2YodC0+dmRhdVswXS5zcmVncyksIHQtPnZkYXVbcmVxLT5wZ2J1Zl0uc3JlZ3MpIHx8CgkJCQkJaTJjX3NlbmRkYXRhKHQsIDgsIDAsIDI1LCAwLCAnICcsICcgJywgJyAnLCAnICcsICcgJywgJyAnLCAnICcsICcgJywgJyAnLCAtMSkgfHwKCQkJCQlpMmNfc2VuZGRhdGEodCwgMiwgMCwgdC0+dmRhdVtyZXEtPnBnYnVmXS5zcmVnc1swXSB8IDgsIC0xKSB8fAoJCQkJCWkyY19zZW5kZGF0YSh0LCA4LCAwLCAyNSwgMCwgLTEpKQoJCQkJCXJldHVybiAtRUlPOwoJCQkJamRlbGF5KFBBR0VfV0FJVCk7CgkJCQlpZiAoaTJjX2dldGRhdGEodCwgMTAsIGluZm9iaXRzKSkKCQkJCQlyZXR1cm4gLUVJTzsKCgkJCQlpZiAoIShpbmZvYml0c1s4XSAmIDB4MTApICYmICEoaW5mb2JpdHNbN10gJiAweGYwKSAmJgkvKiBjaGVjayBGT1VORC1iaXQgKi8KCQkJCQkobWVtY21wKGluZm9iaXRzLCB0LT52ZGF1W3JlcS0+cGdidWZdLmxhc3RzdGF0LCBzaXplb2YoaW5mb2JpdHMpKSB8fAoJCQkJCXRpbWVfYWZ0ZXJfZXEoamlmZmllcywgdC0+dmRhdVtyZXEtPnBnYnVmXS5leHBpcmUpKSkKCQkJCXsJCS8qIGNoZWNrIGlmIG5ldyBwYWdlIGFycml2ZWQgKi8KCQkJCQlpZiAoaTJjX3NlbmRkYXRhKHQsIDgsIDAsIDAsIDAsIC0xKSB8fAoJCQkJCQlpMmNfZ2V0ZGF0YSh0LCBWVFhfUEFHRVNJWkUsIHQtPnZkYXVbcmVxLT5wZ2J1Zl0ucGdidWYpKQoJCQkJCQlyZXR1cm4gLUVJTzsKCQkJCQl0LT52ZGF1W3JlcS0+cGdidWZdLmV4cGlyZSA9IGppZmZpZXMgKyBQR0JVRl9FWFBJUkU7CgkJCQkJbWVtc2V0KHQtPnZkYXVbcmVxLT5wZ2J1Zl0ucGdidWYgKyBWVFhfUEFHRVNJWkUsICcgJywgVlRYX1ZJUlRVQUxTSVpFIC0gVlRYX1BBR0VTSVpFKTsKCQkJCQlpZiAodC0+dmlydHVhbF9tb2RlKQoJCQkJCXsKCQkJCQkJLyogUGFja2V0IFgvMjQgKi8KCQkJCQkJaWYgKGkyY19zZW5kZGF0YSh0LCA4LCAwLCAweDIwLCAwLCAtMSkgfHwKCQkJCQkJCWkyY19nZXRkYXRhKHQsIDQwLCB0LT52ZGF1W3JlcS0+cGdidWZdLnBnYnVmICsgVlRYX1BBR0VTSVpFICsgMjAgKiA0MCkpCgkJCQkJCQlyZXR1cm4gLUVJTzsKCQkJCQkJLyogUGFja2V0IFgvMjcvMCAqLwoJCQkJCQlpZiAoaTJjX3NlbmRkYXRhKHQsIDgsIDAsIDB4MjEsIDAsIC0xKSB8fAoJCQkJCQkJaTJjX2dldGRhdGEodCwgNDAsIHQtPnZkYXVbcmVxLT5wZ2J1Zl0ucGdidWYgKyBWVFhfUEFHRVNJWkUgKyAxNiAqIDQwKSkKCQkJCQkJCXJldHVybiAtRUlPOwoJCQkJCQkvKiBQYWNrZXQgOC8zMC8wLi4uOC8zMC8xNQoJCQkJCQkgKiBGSVhNRTogQUZBSUssIHRoZSA1MjQ5IGRvZXMgaGFtbWluZy1kZWNvZGluZyBmb3Igc29tZSBieXRlcyBpbiBwYWNrZXQgOC8zMCwKCQkJCQkJICogICAgICAgIHNvIHdlIHNob3VsZCB1bmRvIHRoaXMgaGVyZS4KCQkJCQkJICovCgkJCQkJCWlmIChpMmNfc2VuZGRhdGEodCwgOCwgMCwgMHgyMiwgMCwgLTEpIHx8CgkJCQkJCQlpMmNfZ2V0ZGF0YSh0LCA0MCwgdC0+dmRhdVtyZXEtPnBnYnVmXS5wZ2J1ZiArIFZUWF9QQUdFU0laRSArIDIzICogNDApKQoJCQkJCQkJcmV0dXJuIC1FSU87CgkJCQkJfQoJCQkJCXQtPnZkYXVbcmVxLT5wZ2J1Zl0uY2xyZm91bmQgPSBmYWxzZTsKCQkJCQltZW1jcHkodC0+dmRhdVtyZXEtPnBnYnVmXS5sYXN0c3RhdCwgaW5mb2JpdHMsIHNpemVvZihpbmZvYml0cykpOwoJCQkJfQoJCQkJZWxzZQoJCQkJewoJCQkJCW1lbWNweShpbmZvYml0cywgdC0+dmRhdVtyZXEtPnBnYnVmXS5sYXN0c3RhdCwgc2l6ZW9mKGluZm9iaXRzKSk7CgkJCQl9CgkJCX0KCQkJZWxzZQoJCQl7CgkJCQltZW1jcHkoaW5mb2JpdHMsIHQtPnZkYXVbcmVxLT5wZ2J1Zl0ubGFzdHN0YXQsIHNpemVvZihpbmZvYml0cykpOwoJCQl9CgoJCQlpbmZvLnBhZ2VudW0gPSAoKGluZm9iaXRzWzhdIDw8IDgpICYgMHg3MDApIHwgKChpbmZvYml0c1sxXSA8PCA0KSAmIDB4ZjApIHwgKGluZm9iaXRzWzBdICYgMHgwZik7CgkJCWlmIChpbmZvLnBhZ2VudW0gPCAweDEwMCkKCQkJCWluZm8ucGFnZW51bSArPSAweDgwMDsKCQkJaW5mby5ob3VyID0gKChpbmZvYml0c1s1XSA8PCA0KSAmIDB4MzApIHwgKGluZm9iaXRzWzRdICYgMHgwZik7CgkJCWluZm8ubWludXRlID0gKChpbmZvYml0c1szXSA8PCA0KSAmIDB4NzApIHwgKGluZm9iaXRzWzJdICYgMHgwZik7CgkJCWluZm8uY2hhcnNldCA9ICgoaW5mb2JpdHNbN10gPj4gMSkgJiA3KTsKCQkJaW5mby5kZWxldGUgPSAhIShpbmZvYml0c1szXSAmIDgpOwoJCQlpbmZvLmhlYWRsaW5lID0gISEoaW5mb2JpdHNbNV0gJiA0KTsKCQkJaW5mby5zdWJ0aXRsZSA9ICEhKGluZm9iaXRzWzVdICYgOCk7CgkJCWluZm8uc3VwcF9oZWFkZXIgPSAhIShpbmZvYml0c1s2XSAmIDEpOwoJCQlpbmZvLnVwZGF0ZSA9ICEhKGluZm9iaXRzWzZdICYgMik7CgkJCWluZm8uaW50ZXJfc2VxID0gISEoaW5mb2JpdHNbNl0gJiA0KTsKCQkJaW5mby5kaXNfZGlzcCA9ICEhKGluZm9iaXRzWzZdICYgOCk7CgkJCWluZm8uc2VyaWFsID0gISEoaW5mb2JpdHNbN10gJiAxKTsKCQkJaW5mby5ub3Rmb3VuZCA9ICEhKGluZm9iaXRzWzhdICYgMHgxMCk7CgkJCWluZm8ucGJsZiA9ICEhKGluZm9iaXRzWzldICYgMHgyMCk7CgkJCWluZm8uaGFtbWluZyA9IDA7CgkJCWZvciAoYSA9IDA7IGEgPD0gNzsgYSsrKQoJCQl7CgkJCQlpZiAoaW5mb2JpdHNbYV0gJiAweGYwKQoJCQkJewoJCQkJCWluZm8uaGFtbWluZyA9IDE7CgkJCQkJYnJlYWs7CgkJCQl9CgkJCX0KCQkJaWYgKHQtPnZkYXVbcmVxLT5wZ2J1Zl0uY2xyZm91bmQpCgkJCQlpbmZvLm5vdGZvdW5kID0gMTsKCQkJaWYoY29weV90b191c2VyKHJlcS0+YnVmZmVyLCAmaW5mbywgc2l6ZW9mKHZ0eF9wYWdlaW5mb190KSkpCgkJCQlyZXR1cm4gLUVGQVVMVDsKCQkJaWYgKCFpbmZvLmhhbW1pbmcgJiYgIWluZm8ubm90Zm91bmQpCgkJCXsKCQkJCXQtPmlzX3NlYXJjaGluZ1tyZXEtPnBnYnVmXSA9IGZhbHNlOwoJCQl9CgkJCXJldHVybiAwOwoJCX0KCgkJY2FzZSBWVFhJT0NHRVRQQUdFOgoJCXsKCQkJdnR4X3BhZ2VyZXFfdCAqcmVxID0gYXJnOwoJCQlpbnQgc3RhcnQsIGVuZDsKCgkJCWlmIChyZXEtPnBnYnVmIDwgMCB8fCByZXEtPnBnYnVmID49IE5VTV9EQVVTIHx8IHJlcS0+c3RhcnQgPCAwIHx8CgkJCQlyZXEtPnN0YXJ0ID4gcmVxLT5lbmQgfHwgcmVxLT5lbmQgPj0gKHZpcnR1YWxfbW9kZSA/IFZUWF9WSVJUVUFMU0laRSA6IFZUWF9QQUdFU0laRSkpCgkJCQlyZXR1cm4gLUVJTlZBTDsKCQkJaWYoY29weV90b191c2VyKHJlcS0+YnVmZmVyLCAmdC0+dmRhdVtyZXEtPnBnYnVmXS5wZ2J1ZltyZXEtPnN0YXJ0XSwgcmVxLT5lbmQgLSByZXEtPnN0YXJ0ICsgMSkpCgkJCQlyZXR1cm4gLUVGQVVMVDsKCgkJCSAvKgoJCQkgICoJQWx3YXlzIHJlYWQgdGhlIHRpbWUgZGlyZWN0bHkgZnJvbSBTQUE1MjQ5CgkJCSAgKi8KCgkJCWlmIChyZXEtPnN0YXJ0IDw9IDM5ICYmIHJlcS0+ZW5kID49IDMyKQoJCQl7CgkJCQlpbnQgbGVuOwoJCQkJY2hhciBidWZbMTZdOwoJCQkJc3RhcnQgPSBtYXgocmVxLT5zdGFydCwgMzIpOwoJCQkJZW5kID0gbWluKHJlcS0+ZW5kLCAzOSk7CgkJCQlsZW49ZW5kLXN0YXJ0KzE7CgkJCQlpZiAoaTJjX3NlbmRkYXRhKHQsIDgsIDAsIDAsIHN0YXJ0LCAtMSkgfHwKCQkJCQlpMmNfZ2V0ZGF0YSh0LCBsZW4sIGJ1ZikpCgkJCQkJcmV0dXJuIC1FSU87CgkJCQlpZihjb3B5X3RvX3VzZXIocmVxLT5idWZmZXIrc3RhcnQtcmVxLT5zdGFydCwgYnVmLCBsZW4pKQoJCQkJCXJldHVybiAtRUZBVUxUOwoJCQl9CgkJCS8qIEluc2VydCB0aGUgY3VycmVudCBoZWFkZXIgaWYgREFVIGlzIHN0aWxsIHNlYXJjaGluZyBmb3IgYSBwYWdlICovCgkJCWlmIChyZXEtPnN0YXJ0IDw9IDMxICYmIHJlcS0+ZW5kID49IDcgJiYgdC0+aXNfc2VhcmNoaW5nW3JlcS0+cGdidWZdKQoJCQl7CgkJCQljaGFyIGJ1ZlszMl07CgkJCQlpbnQgbGVuOwoJCQkJc3RhcnQgPSBtYXgocmVxLT5zdGFydCwgNyk7CgkJCQllbmQgPSBtaW4ocmVxLT5lbmQsIDMxKTsKCQkJCWxlbj1lbmQtc3RhcnQrMTsKCQkJCWlmIChpMmNfc2VuZGRhdGEodCwgOCwgMCwgMCwgc3RhcnQsIC0xKSB8fAoJCQkJCWkyY19nZXRkYXRhKHQsIGxlbiwgYnVmKSkKCQkJCQlyZXR1cm4gLUVJTzsKCQkJCWlmKGNvcHlfdG9fdXNlcihyZXEtPmJ1ZmZlcitzdGFydC1yZXEtPnN0YXJ0LCBidWYsIGxlbikpCgkJCQkJcmV0dXJuIC1FRkFVTFQ7CgkJCX0KCQkJcmV0dXJuIDA7CgkJfQoKCQljYXNlIFZUWElPQ1NUT1BEQVU6CgkJewoJCQl2dHhfcGFnZXJlcV90ICpyZXEgPSBhcmc7CgoJCQlpZiAocmVxLT5wZ2J1ZiA8IDAgfHwgcmVxLT5wZ2J1ZiA+PSBOVU1fREFVUykKCQkJCXJldHVybiAtRUlOVkFMOwoJCQl0LT52ZGF1W3JlcS0+cGdidWZdLnN0b3BwZWQgPSB0cnVlOwoJCQl0LT5pc19zZWFyY2hpbmdbcmVxLT5wZ2J1Zl0gPSBmYWxzZTsKCQkJcmV0dXJuIDA7CgkJfQoKCQljYXNlIFZUWElPQ1BVVFBBR0U6CgkJY2FzZSBWVFhJT0NTRVRESVNQOgoJCWNhc2UgVlRYSU9DUFVUU1RBVDoKCQkJcmV0dXJuIDA7CgoJCWNhc2UgVlRYSU9DQ0xSQ0FDSEU6CgkJewoJCQlpZiAoaTJjX3NlbmRkYXRhKHQsIDAsIE5VTV9EQVVTLCAwLCA4LCAtMSkgfHwgaTJjX3NlbmRkYXRhKHQsIDExLAoJCQkJJyAnLCcgJywnICcsJyAnLCcgJywnICcsJyAnLCcgJywnICcsJyAnLCcgJywnICcsCgkJCQknICcsJyAnLCcgJywnICcsJyAnLCcgJywnICcsJyAnLCcgJywnICcsJyAnLCcgJywgLTEpKQoJCQkJcmV0dXJuIC1FSU87CgkJCWlmIChpMmNfc2VuZGRhdGEodCwgMywgMHgyMCwgLTEpKQoJCQkJcmV0dXJuIC1FSU87CgkJCWpkZWxheSgxMCAqIENMRUFSX0RFTEFZKTsJCQkvKiBJIGhhdmUgbm8gaWRlYSBob3cgbG9uZyB3ZSBoYXZlIHRvIHdhaXQgaGVyZSAqLwoJCQlyZXR1cm4gMDsKCQl9CgoJCWNhc2UgVlRYSU9DU0VUVklSVDoKCQl7CgkJCS8qIFRoZSBTQUE1MjQ5IGhhcyB2aXJ0dWFsLXJvdyByZWNlcHRpb24gdHVybmVkIG9uIGFsd2F5cyAqLwoJCQl0LT52aXJ0dWFsX21vZGUgPSAoaW50KShsb25nKWFyZzsKCQkJcmV0dXJuIDA7CgkJfQoJfQoJcmV0dXJuIC1FSU5WQUw7Cn0KCi8qCiAqIFRyYW5zbGF0ZXMgb2xkIHZ0eCBJT0NUTHMgdG8gbmV3IG9uZXMKICoKICogVGhpcyBrZWVwcyBuZXcga2VybmVsIHZlcnNpb25zIGNvbXBhdGlibGUgd2l0aCBvbGQgdXNlcnNwYWNlIHByb2dyYW1zLgogKi8Kc3RhdGljIGlubGluZSB1bnNpZ25lZCBpbnQgdnR4X2ZpeF9jb21tYW5kKHVuc2lnbmVkIGludCBjbWQpCnsKCXN3aXRjaCAoY21kKSB7CgljYXNlIFZUWElPQ0dFVElORk9fT0xEOgoJCWNtZCA9IFZUWElPQ0dFVElORk87CgkJYnJlYWs7CgljYXNlIFZUWElPQ0NMUlBBR0VfT0xEOgoJCWNtZCA9IFZUWElPQ0NMUlBBR0U7CgkJYnJlYWs7CgljYXNlIFZUWElPQ0NMUkZPVU5EX09MRDoKCQljbWQgPSBWVFhJT0NDTFJGT1VORDsKCQlicmVhazsKCWNhc2UgVlRYSU9DUEFHRVJFUV9PTEQ6CgkJY21kID0gVlRYSU9DUEFHRVJFUTsKCQlicmVhazsKCWNhc2UgVlRYSU9DR0VUU1RBVF9PTEQ6CgkJY21kID0gVlRYSU9DR0VUU1RBVDsKCQlicmVhazsKCWNhc2UgVlRYSU9DR0VUUEFHRV9PTEQ6CgkJY21kID0gVlRYSU9DR0VUUEFHRTsKCQlicmVhazsKCWNhc2UgVlRYSU9DU1RPUERBVV9PTEQ6CgkJY21kID0gVlRYSU9DU1RPUERBVTsKCQlicmVhazsKCWNhc2UgVlRYSU9DUFVUUEFHRV9PTEQ6CgkJY21kID0gVlRYSU9DUFVUUEFHRTsKCQlicmVhazsKCWNhc2UgVlRYSU9DU0VURElTUF9PTEQ6CgkJY21kID0gVlRYSU9DU0VURElTUDsKCQlicmVhazsKCWNhc2UgVlRYSU9DUFVUU1RBVF9PTEQ6CgkJY21kID0gVlRYSU9DUFVUU1RBVDsKCQlicmVhazsKCWNhc2UgVlRYSU9DQ0xSQ0FDSEVfT0xEOgoJCWNtZCA9IFZUWElPQ0NMUkNBQ0hFOwoJCWJyZWFrOwoJY2FzZSBWVFhJT0NTRVRWSVJUX09MRDoKCQljbWQgPSBWVFhJT0NTRVRWSVJUOwoJCWJyZWFrOwoJfQoJcmV0dXJuIGNtZDsKfQoKLyoKICoJSGFuZGxlIHRoZSBsb2NraW5nCiAqLwoKc3RhdGljIGludCBzYWE1MjQ5X2lvY3RsKHN0cnVjdCBpbm9kZSAqaW5vZGUsIHN0cnVjdCBmaWxlICpmaWxlLAoJCQkgdW5zaWduZWQgaW50IGNtZCwgdW5zaWduZWQgbG9uZyBhcmcpCnsKCXN0cnVjdCB2aWRlb19kZXZpY2UgKnZkID0gdmlkZW9fZGV2ZGF0YShmaWxlKTsKCXN0cnVjdCBzYWE1MjQ5X2RldmljZSAqdD12ZC0+cHJpdjsKCWludCBlcnI7CgoJY21kID0gdnR4X2ZpeF9jb21tYW5kKGNtZCk7CgltdXRleF9sb2NrKCZ0LT5sb2NrKTsKCWVyciA9IHZpZGVvX3VzZXJjb3B5KGlub2RlLGZpbGUsY21kLGFyZyxkb19zYWE1MjQ5X2lvY3RsKTsKCW11dGV4X3VubG9jaygmdC0+bG9jayk7CglyZXR1cm4gZXJyOwp9CgpzdGF0aWMgaW50IHNhYTUyNDlfb3BlbihzdHJ1Y3QgaW5vZGUgKmlub2RlLCBzdHJ1Y3QgZmlsZSAqZmlsZSkKewoJc3RydWN0IHZpZGVvX2RldmljZSAqdmQgPSB2aWRlb19kZXZkYXRhKGZpbGUpOwoJc3RydWN0IHNhYTUyNDlfZGV2aWNlICp0PXZkLT5wcml2OwoJaW50IGVycixwZ2J1ZjsKCgllcnIgPSB2aWRlb19leGNsdXNpdmVfb3Blbihpbm9kZSxmaWxlKTsKCWlmIChlcnIgPCAwKQoJCXJldHVybiBlcnI7CgoJaWYgKHQtPmNsaWVudD09TlVMTCkgewoJCWVyciA9IC1FTk9ERVY7CgkJZ290byBmYWlsOwoJfQoKCWlmIChpMmNfc2VuZGRhdGEodCwgMCwgMCwgLTEpIHx8CQkvKiBTZWxlY3QgUjExICovCgkJCQkJCS8qIFR1cm4gb2ZmIHBhcml0eSBjaGVja3MgKHdlIGRvIHRoaXMgb3Vyc2VsdmVzKSAqLwoJCWkyY19zZW5kZGF0YSh0LCAxLCBkaXNwX21vZGVzW3QtPmRpc3BfbW9kZV1bMF0sIDAsIC0xKSB8fAoJCQkJCQkvKiBEaXNwbGF5IFRWLXBpY3R1cmUsIG5vIHZpcnR1YWwgcm93cyAqLwoJCWkyY19zZW5kZGF0YSh0LCA0LCBOVU1fREFVUywgZGlzcF9tb2Rlc1t0LT5kaXNwX21vZGVdWzFdLCBkaXNwX21vZGVzW3QtPmRpc3BfbW9kZV1bMl0sIDcsIC0xKSkgLyogU2V0IGRpc3BsYXkgdG8gcGFnZSA0ICovCgoJewoJCWVyciA9IC1FSU87CgkJZ290byBmYWlsOwoJfQoKCWZvciAocGdidWYgPSAwOyBwZ2J1ZiA8IE5VTV9EQVVTOyBwZ2J1ZisrKQoJewoJCW1lbXNldCh0LT52ZGF1W3BnYnVmXS5wZ2J1ZiwgJyAnLCBzaXplb2YodC0+dmRhdVswXS5wZ2J1ZikpOwoJCW1lbXNldCh0LT52ZGF1W3BnYnVmXS5zcmVncywgMCwgc2l6ZW9mKHQtPnZkYXVbMF0uc3JlZ3MpKTsKCQltZW1zZXQodC0+dmRhdVtwZ2J1Zl0ubGFzdHN0YXQsIDAsIHNpemVvZih0LT52ZGF1WzBdLmxhc3RzdGF0KSk7CgkJdC0+dmRhdVtwZ2J1Zl0uZXhwaXJlID0gMDsKCQl0LT52ZGF1W3BnYnVmXS5jbHJmb3VuZCA9IHRydWU7CgkJdC0+dmRhdVtwZ2J1Zl0uc3RvcHBlZCA9IHRydWU7CgkJdC0+aXNfc2VhcmNoaW5nW3BnYnVmXSA9IGZhbHNlOwoJfQoJdC0+dmlydHVhbF9tb2RlID0gZmFsc2U7CglyZXR1cm4gMDsKCiBmYWlsOgoJdmlkZW9fZXhjbHVzaXZlX3JlbGVhc2UoaW5vZGUsZmlsZSk7CglyZXR1cm4gZXJyOwp9CgoKCnN0YXRpYyBpbnQgc2FhNTI0OV9yZWxlYXNlKHN0cnVjdCBpbm9kZSAqaW5vZGUsIHN0cnVjdCBmaWxlICpmaWxlKQp7CglzdHJ1Y3QgdmlkZW9fZGV2aWNlICp2ZCA9IHZpZGVvX2RldmRhdGEoZmlsZSk7CglzdHJ1Y3Qgc2FhNTI0OV9kZXZpY2UgKnQ9dmQtPnByaXY7CglpMmNfc2VuZGRhdGEodCwgMSwgMHgyMCwgLTEpOwkJLyogVHVybiBvZmYgQ0NUICovCglpMmNfc2VuZGRhdGEodCwgNSwgMywgMywgLTEpOwkJLyogVHVybiBvZmYgVFYtZGlzcGxheSAqLwoJdmlkZW9fZXhjbHVzaXZlX3JlbGVhc2UoaW5vZGUsZmlsZSk7CglyZXR1cm4gMDsKfQoKc3RhdGljIGludCBfX2luaXQgaW5pdF9zYWFfNTI0OSAodm9pZCkKewoJcHJpbnRrKEtFUk5fSU5GTyAiU0FBNTI0OSBkcml2ZXIgKCIgSUZfTkFNRSAiIGludGVyZmFjZSkgZm9yIFZpZGVvVGV4dCB2ZXJzaW9uICVkLiVkXG4iLAoJCQlWVFhfVkVSX01BSiwgVlRYX1ZFUl9NSU4pOwoJcmV0dXJuIGkyY19hZGRfZHJpdmVyKCZpMmNfZHJpdmVyX3ZpZGVvdGV4dCk7Cn0KCnN0YXRpYyB2b2lkIF9fZXhpdCBjbGVhbnVwX3NhYV81MjQ5ICh2b2lkKQp7CglpMmNfZGVsX2RyaXZlcigmaTJjX2RyaXZlcl92aWRlb3RleHQpOwp9Cgptb2R1bGVfaW5pdChpbml0X3NhYV81MjQ5KTsKbW9kdWxlX2V4aXQoY2xlYW51cF9zYWFfNTI0OSk7CgpzdGF0aWMgY29uc3Qgc3RydWN0IGZpbGVfb3BlcmF0aW9ucyBzYWFfZm9wcyA9IHsKCS5vd25lcgkJPSBUSElTX01PRFVMRSwKCS5vcGVuCQk9IHNhYTUyNDlfb3BlbiwKCS5yZWxlYXNlICAgICAgIAk9IHNhYTUyNDlfcmVsZWFzZSwKCS5pb2N0bCAgICAgICAgICA9IHNhYTUyNDlfaW9jdGwsCgkuY29tcGF0X2lvY3RsCT0gdjRsX2NvbXBhdF9pb2N0bDMyLAoJLmxsc2VlayAgICAgICAgID0gbm9fbGxzZWVrLAp9OwoKc3RhdGljIHN0cnVjdCB2aWRlb19kZXZpY2Ugc2FhX3RlbXBsYXRlID0KewoJLm93bmVyCQk9IFRISVNfTU9EVUxFLAoJLm5hbWUJCT0gSUZfTkFNRSwKCS50eXBlCQk9IFZJRF9UWVBFX1RFTEVURVhULAkvKnwgVklEX1RZUEVfVFVORVIgPz8gKi8KCS5mb3BzICAgICAgICAgICA9ICZzYWFfZm9wcywKfTsKCk1PRFVMRV9MSUNFTlNFKCJHUEwiKTsK