LyoKICogTW9kaWZpZWQgaW4gb3JkZXIgdG8ga2VlcCBpdCBjb21wYXRpYmxlIGJvdGggd2l0aCBuZXcgYW5kIG9sZCB2aWRlb3RleHQgSU9DVExzIGJ5CiAqIE1pY2hhZWwgR2VuZyA8bGludXhATWljaGFlbEdlbmcuZGU+CiAqCiAqCUNsZWFuZWQgdXAgdG8gdXNlIGV4aXN0aW5nIHZpZGVvZGV2IGludGVyZmFjZSBhbmQgYWxsb3cgdGhlIGlkZWEKICoJb2YgbXVsdGlwbGUgdGVsZXRleHQgZGVjb2RlcnMgb24gdGhlIHZpZGVvNGxpbnV4IGlmYWNlLiBDaGFuZ2VkIGkyYwogKgl0byBjb3ZlciBhZGRyZXNzaW5nIGNsYXNoZXMgb24gZGV2aWNlIGJ1c3Nlcy4gSXQncyBhbHNvIHJlYnVpbHQgc28KICoJeW91IGNhbiBhZGQgYXJiaXRhcnkgbXVsdGlwbGUgdGVsZXRleHQgZGV2aWNlcyB0byBMaW51eCB2aWRlbzRsaW51eAogKglub3cgKHdlbGwgMzIgYW55d2F5KS4KICoKICoJQWxhbiBDb3ggPEFsYW4uQ294QGxpbnV4Lm9yZz4KICoKICoJVGhlIG9yaWdpbmFsIGRyaXZlciB3YXMgaGVhdmlseSBtb2RpZmllZCB0byBtYXRjaCB0aGUgaTJjIGludGVyZmFjZQogKglJdCB3YXMgdHJ1bmNhdGVkIHRvIHVzZSB0aGUgV2luVFYgYm9hcmRzLCB0b28uCiAqCiAqCUNvcHlyaWdodCAoYykgMTk5OCBSaWNoYXJkIEd1ZW50aGVyIDxyaWNoYXJkLmd1ZW50aGVyQHN0dWRlbnQudW5pLXR1ZWJpbmdlbi5kZT4KICoKICogJElkOiBzYWE1MjQ5LmMsdiAxLjEgMTk5OC8wMy8zMCAyMjoyMzoyMyBhbGFuIEV4cCAkCiAqCiAqCURlcml2ZWQgRnJvbQogKgogKiB2dHguYzoKICogVGhpcyBpcyBhIGxvYWRhYmxlIGNoYXJhY3Rlci1kZXZpY2UtZHJpdmVyIGZvciB2aWRlb3RleHQtaW50ZXJmYWNlcwogKiAoYWthIHRlbGV0ZXh0KS4gUGxlYXNlIGNoZWNrIHRoZSBNYWtlZmlsZS9SRUFETUUgZm9yIGEgbGlzdCBvZiBzdXBwb3J0ZWQKICogaW50ZXJmYWNlcy4KICoKICogQ29weXJpZ2h0IChjKSAxOTk0LTk3IE1hcnRpbiBCdWNrICA8bWFydGluLTIuYnVja0BzdHVkZW50LnVuaS11bG0uZGU+CiAqCiAqCiAqIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5CiAqIGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5CiAqIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlciB2ZXJzaW9uIDIgb2YgdGhlIExpY2Vuc2UsIG9yCiAqIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlCiAqIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIGFsb25nIHdpdGggdGhpcyBwcm9ncmFtOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDU5IFRlbXBsZSBQbGFjZSAtIFN1aXRlIDMzMCwgQm9zdG9uLCBNQSAwMjExMS0xMzA3LAogKiBVU0EuCiAqLwoKI2luY2x1ZGUgPGxpbnV4L21vZHVsZS5oPgojaW5jbHVkZSA8bGludXgva2VybmVsLmg+CiNpbmNsdWRlIDxsaW51eC9zY2hlZC5oPgojaW5jbHVkZSA8bGludXgvbW0uaD4KI2luY2x1ZGUgPGxpbnV4L2Vycm5vLmg+CiNpbmNsdWRlIDxsaW51eC9kZWxheS5oPgojaW5jbHVkZSA8bGludXgvaW9wb3J0Lmg+CiNpbmNsdWRlIDxsaW51eC9zbGFiLmg+CiNpbmNsdWRlIDxsaW51eC9pbml0Lmg+CiNpbmNsdWRlIDxzdGRhcmcuaD4KI2luY2x1ZGUgPGxpbnV4L2kyYy5oPgojaW5jbHVkZSA8bGludXgvdmlkZW90ZXh0Lmg+CiNpbmNsdWRlIDxsaW51eC92aWRlb2Rldi5oPgojaW5jbHVkZSA8bGludXgvbXV0ZXguaD4KCgojaW5jbHVkZSA8YXNtL2lvLmg+CiNpbmNsdWRlIDxhc20vdWFjY2Vzcy5oPgoKI2RlZmluZSBWVFhfVkVSX01BSiAxCiNkZWZpbmUgVlRYX1ZFUl9NSU4gOAoKCgojZGVmaW5lIE5VTV9EQVVTIDQKI2RlZmluZSBOVU1fQlVGUyA4CiNkZWZpbmUgSUZfTkFNRSAiU0FBNTI0OSIKCnN0YXRpYyBjb25zdCBpbnQgZGlzcF9tb2Rlc1s4XVszXSA9IAp7Cgl7IDB4NDYsIDB4MDMsIDB4MDMgfSwJLyogRElTUE9GRiAqLwoJeyAweDQ2LCAweGNjLCAweGNjIH0sCS8qIERJU1BOT1JNICovCgl7IDB4NDQsIDB4MGYsIDB4MGYgfSwJLyogRElTUFRSQU5TICovCgl7IDB4NDYsIDB4Y2MsIDB4NDYgfSwJLyogRElTUElOUyAqLwoJeyAweDQ0LCAweDAzLCAweDAzIH0sCS8qIERJU1BPRkYsIGludGVybGFjZWQgKi8KCXsgMHg0NCwgMHhjYywgMHhjYyB9LAkvKiBESVNQTk9STSwgaW50ZXJsYWNlZCAqLwoJeyAweDQ0LCAweDBmLCAweDBmIH0sCS8qIERJU1BUUkFOUywgaW50ZXJsYWNlZCAqLwoJeyAweDQ0LCAweGNjLCAweDQ2IH0JLyogRElTUElOUywgaW50ZXJsYWNlZCAqLwp9OwoKCgojZGVmaW5lIFBBR0VfV0FJVCAoMzAwKkhaLzEwMDApCQkJLyogVGltZSBiZXR3ZWVuIHJlcXVlc3RpbmcgcGFnZSBhbmQgKi8KCQkJCQkJLyogY2hlY2tpbmcgc3RhdHVzIGJpdHMgKi8KI2RlZmluZSBQR0JVRl9FWFBJUkUgKDE1KkhaKQkJCS8qIFRpbWUgdG8gd2FpdCBiZWZvcmUgcmV0cmFuc21pdHRpbmcgKi8KCQkJCQkJLyogcGFnZSByZWdhcmRsZXNzIG9mIGluZm9iaXRzICovCnR5cGVkZWYgc3RydWN0IHsKCXU4IHBnYnVmW1ZUWF9WSVJUVUFMU0laRV07CQkvKiBQYWdlLWJ1ZmZlciAqLwoJdTggbGFzdHN0YXRbMTBdOwkJCS8qIExhc3QgdmFsdWUgb2YgaW5mb2JpdHMgZm9yIERBVSAqLwoJdTggc3JlZ3NbN107CQkJCS8qIFBhZ2UtcmVxdWVzdCByZWdpc3RlcnMgKi8KCXVuc2lnbmVkIGxvbmcgZXhwaXJlOwkJCS8qIFRpbWUgd2hlbiBwYWdlIHdpbGwgYmUgZXhwaXJlZCAqLwoJdW5zaWduZWQgY2xyZm91bmQgOiAxOwkJCS8qIFZUWElPQ0NMUkZPVU5EIGhhcyBiZWVuIGNhbGxlZCAqLwoJdW5zaWduZWQgc3RvcHBlZCA6IDE7CQkJLyogVlRYSU9DU1RPUERBVSBoYXMgYmVlbiBjYWxsZWQgKi8KfSB2ZGF1X3Q7CgpzdHJ1Y3Qgc2FhNTI0OV9kZXZpY2UKewoJdmRhdV90IHZkYXVbTlVNX0RBVVNdOwkJCS8qIERhdGEgZm9yIHZpcnR1YWwgREFVcyAodGhlIDUyNDkgb25seSBoYXMgb25lICovCgkJCQkJCS8qIHJlYWwgREFVLCBzbyB3ZSBoYXZlIHRvIHNpbXVsYXRlIHNvbWUgbW9yZSkgKi8KCWludCB2dHhfdXNlX2NvdW50OwoJaW50IGlzX3NlYXJjaGluZ1tOVU1fREFVU107CglpbnQgZGlzcF9tb2RlOwoJaW50IHZpcnR1YWxfbW9kZTsKCXN0cnVjdCBpMmNfY2xpZW50ICpjbGllbnQ7CglzdHJ1Y3QgbXV0ZXggbG9jazsKfTsKCgojZGVmaW5lIENDVFdSIDM0CQkvKiBJskMgd3JpdGUvcmVhZC1hZGRyZXNzIG9mIHZ0eC1jaGlwICovCiNkZWZpbmUgQ0NUUkQgMzUKI2RlZmluZSBOT0FDS19SRVBFQVQgMTAJCS8qIFJldHJ5IGFjY2VzcyB0aGlzIG1hbnkgdGltZXMgb24gZmFpbHVyZSAqLwojZGVmaW5lIENMRUFSX0RFTEFZIChIWi8yMCkJLyogVGltZSByZXF1aXJlZCB0byBjbGVhciBhIHBhZ2UgKi8KI2RlZmluZSBSRUFEWV9USU1FT1VUICgzMCpIWi8xMDAwKQkvKiBUaW1lIHRvIHdhaXQgZm9yIHJlYWR5IHNpZ25hbCBvZiBJskMtYnVzIGludGVyZmFjZSAqLwojZGVmaW5lIElOSVRfREVMQVkgNTAwCQkvKiBUaW1lIGluIHVzZWMgdG8gd2FpdCBhdCBpbml0aWFsaXphdGlvbiBvZiBDRUEgaW50ZXJmYWNlICovCiNkZWZpbmUgU1RBUlRfREVMQVkgMTAJCS8qIFRpbWUgaW4gdXNlYyB0byB3YWl0IGJlZm9yZSBzdGFydGluZyB3cml0ZS1jeWNsZSAoQ0VBKSAqLwoKI2RlZmluZSBWVFhfREVWX01JTk9SIDAKCi8qIEdlbmVyYWwgZGVmaW5lcyBhbmQgZGVidWdnaW5nIHN1cHBvcnQgKi8KCiNpZm5kZWYgRkFMU0UKI2RlZmluZSBGQUxTRSAwCiNkZWZpbmUgVFJVRSAxCiNlbmRpZgoKI2RlZmluZSBSRVNDSEVEIGRvIHsgY29uZF9yZXNjaGVkKCk7IH0gd2hpbGUoMCkKCnN0YXRpYyBzdHJ1Y3QgdmlkZW9fZGV2aWNlIHNhYV90ZW1wbGF0ZTsJLyogRGVjbGFyZWQgbmVhciBib3R0b20gKi8KCi8qIEFkZHJlc3NlcyB0byBzY2FuICovCnN0YXRpYyB1bnNpZ25lZCBzaG9ydCBub3JtYWxfaTJjW10gPSB7MzQ+PjEsSTJDX0NMSUVOVF9FTkR9OwpJMkNfQ0xJRU5UX0lOU01PRDsKCnN0YXRpYyBzdHJ1Y3QgaTJjX2NsaWVudCBjbGllbnRfdGVtcGxhdGU7CgpzdGF0aWMgaW50IHNhYTUyNDlfYXR0YWNoKHN0cnVjdCBpMmNfYWRhcHRlciAqYWRhcCwgaW50IGFkZHIsIGludCBraW5kKQp7CglpbnQgcGdidWY7CglpbnQgZXJyOwoJc3RydWN0IGkyY19jbGllbnQgKmNsaWVudDsKCXN0cnVjdCB2aWRlb19kZXZpY2UgKnZkOwoJc3RydWN0IHNhYTUyNDlfZGV2aWNlICp0OwoKCXByaW50ayhLRVJOX0lORk8gInNhYTUyNDk6IHRlbGV0ZXh0IGNoaXAgZm91bmQuXG4iKTsKCWNsaWVudD1rbWFsbG9jKHNpemVvZigqY2xpZW50KSwgR0ZQX0tFUk5FTCk7CglpZihjbGllbnQ9PU5VTEwpCgkJcmV0dXJuIC1FTk9NRU07CiAgICAgICAgY2xpZW50X3RlbXBsYXRlLmFkYXB0ZXIgPSBhZGFwOwogICAgICAgIGNsaWVudF90ZW1wbGF0ZS5hZGRyID0gYWRkcjsKCW1lbWNweShjbGllbnQsICZjbGllbnRfdGVtcGxhdGUsIHNpemVvZigqY2xpZW50KSk7Cgl0ID0ga3phbGxvYyhzaXplb2YoKnQpLCBHRlBfS0VSTkVMKTsKCWlmKHQ9PU5VTEwpCgl7CgkJa2ZyZWUoY2xpZW50KTsKCQlyZXR1cm4gLUVOT01FTTsKCX0KCXN0cmxjcHkoY2xpZW50LT5uYW1lLCBJRl9OQU1FLCBJMkNfTkFNRV9TSVpFKTsKCW11dGV4X2luaXQoJnQtPmxvY2spOwoJCgkvKgoJICoJTm93IGNyZWF0ZSBhIHZpZGVvNGxpbnV4IGRldmljZQoJICovCgkgCgl2ZCA9IGttYWxsb2Moc2l6ZW9mKHN0cnVjdCB2aWRlb19kZXZpY2UpLCBHRlBfS0VSTkVMKTsKCWlmKHZkPT1OVUxMKQoJewoJCWtmcmVlKHQpOwoJCWtmcmVlKGNsaWVudCk7CgkJcmV0dXJuIC1FTk9NRU07Cgl9CglpMmNfc2V0X2NsaWVudGRhdGEoY2xpZW50LCB2ZCk7CgltZW1jcHkodmQsICZzYWFfdGVtcGxhdGUsIHNpemVvZigqdmQpKTsKCQkKCWZvciAocGdidWYgPSAwOyBwZ2J1ZiA8IE5VTV9EQVVTOyBwZ2J1ZisrKSAKCXsKCQltZW1zZXQodC0+dmRhdVtwZ2J1Zl0ucGdidWYsICcgJywgc2l6ZW9mKHQtPnZkYXVbMF0ucGdidWYpKTsKCQltZW1zZXQodC0+dmRhdVtwZ2J1Zl0uc3JlZ3MsIDAsIHNpemVvZih0LT52ZGF1WzBdLnNyZWdzKSk7CgkJbWVtc2V0KHQtPnZkYXVbcGdidWZdLmxhc3RzdGF0LCAwLCBzaXplb2YodC0+dmRhdVswXS5sYXN0c3RhdCkpOwoJCXQtPnZkYXVbcGdidWZdLmV4cGlyZSA9IDA7CgkJdC0+dmRhdVtwZ2J1Zl0uY2xyZm91bmQgPSBUUlVFOwoJCXQtPnZkYXVbcGdidWZdLnN0b3BwZWQgPSBUUlVFOwoJCXQtPmlzX3NlYXJjaGluZ1twZ2J1Zl0gPSBGQUxTRTsKCX0KCXZkLT5wcml2PXQ7CQoJIAoJCgkvKgoJICoJUmVnaXN0ZXIgaXQKCSAqLwoKCWlmKChlcnI9dmlkZW9fcmVnaXN0ZXJfZGV2aWNlKHZkLCBWRkxfVFlQRV9WVFgsLTEpKTwwKQoJewoJCWtmcmVlKHQpOwoJCWtmcmVlKHZkKTsKCQlrZnJlZShjbGllbnQpOwoJCXJldHVybiBlcnI7Cgl9Cgl0LT5jbGllbnQgPSBjbGllbnQ7CglpMmNfYXR0YWNoX2NsaWVudChjbGllbnQpOwoJcmV0dXJuIDA7Cn0KCi8qCiAqCVdlIGRvIG1vc3Qgb2YgdGhlIGhhcmQgd29yayB3aGVuIHdlIGJlY29tZSBhIGRldmljZSBvbiB0aGUgaTJjLgogKi8KIApzdGF0aWMgaW50IHNhYTUyNDlfcHJvYmUoc3RydWN0IGkyY19hZGFwdGVyICphZGFwKQp7CglpZiAoYWRhcC0+Y2xhc3MgJiBJMkNfQ0xBU1NfVFZfQU5BTE9HKQoJCXJldHVybiBpMmNfcHJvYmUoYWRhcCwgJmFkZHJfZGF0YSwgc2FhNTI0OV9hdHRhY2gpOwoJcmV0dXJuIDA7Cn0KCnN0YXRpYyBpbnQgc2FhNTI0OV9kZXRhY2goc3RydWN0IGkyY19jbGllbnQgKmNsaWVudCkKewoJc3RydWN0IHZpZGVvX2RldmljZSAqdmQgPSBpMmNfZ2V0X2NsaWVudGRhdGEoY2xpZW50KTsKCWkyY19kZXRhY2hfY2xpZW50KGNsaWVudCk7Cgl2aWRlb191bnJlZ2lzdGVyX2RldmljZSh2ZCk7CglrZnJlZSh2ZC0+cHJpdik7CglrZnJlZSh2ZCk7CglrZnJlZShjbGllbnQpOwoJcmV0dXJuIDA7Cn0KCi8qIG5ldyBJMkMgZHJpdmVyIHN1cHBvcnQgKi8KCnN0YXRpYyBzdHJ1Y3QgaTJjX2RyaXZlciBpMmNfZHJpdmVyX3ZpZGVvdGV4dCA9IAp7CgkuZHJpdmVyID0gewoJCS5uYW1lIAk9IElGX05BTUUsCQkvKiBuYW1lICovCgl9LAoJLmlkIAkJPSBJMkNfRFJJVkVSSURfU0FBNTI0OSwgLyogaW4gaTJjLmggKi8KCS5hdHRhY2hfYWRhcHRlciA9IHNhYTUyNDlfcHJvYmUsCgkuZGV0YWNoX2NsaWVudCAgPSBzYWE1MjQ5X2RldGFjaCwKfTsKCnN0YXRpYyBzdHJ1Y3QgaTJjX2NsaWVudCBjbGllbnRfdGVtcGxhdGUgPSB7CgkuZHJpdmVyCQk9ICZpMmNfZHJpdmVyX3ZpZGVvdGV4dCwKCS5uYW1lCQk9ICIodW5zZXQpIiwKfTsKCi8qCiAqCVdhaXQgdGhlIGdpdmVuIG51bWJlciBvZiBqaWZmaWVzICgxMG1zKS4gVGhpcyBjYWxscyB0aGUgc2NoZWR1bGVyLCBzbyB0aGUgYWN0dWFsCiAqCWRlbGF5IG1heSBiZSBsb25nZXIuCiAqLwoKc3RhdGljIHZvaWQgamRlbGF5KHVuc2lnbmVkIGxvbmcgZGVsYXkpIAp7CglzaWdzZXRfdCBvbGRibG9ja2VkID0gY3VycmVudC0+YmxvY2tlZDsKCglzcGluX2xvY2tfaXJxKCZjdXJyZW50LT5zaWdoYW5kLT5zaWdsb2NrKTsKCXNpZ2ZpbGxzZXQoJmN1cnJlbnQtPmJsb2NrZWQpOwoJcmVjYWxjX3NpZ3BlbmRpbmcoKTsKCXNwaW5fdW5sb2NrX2lycSgmY3VycmVudC0+c2lnaGFuZC0+c2lnbG9jayk7Cgltc2xlZXBfaW50ZXJydXB0aWJsZShqaWZmaWVzX3RvX21zZWNzKGRlbGF5KSk7CgoJc3Bpbl9sb2NrX2lycSgmY3VycmVudC0+c2lnaGFuZC0+c2lnbG9jayk7CgljdXJyZW50LT5ibG9ja2VkID0gb2xkYmxvY2tlZDsKCXJlY2FsY19zaWdwZW5kaW5nKCk7CglzcGluX3VubG9ja19pcnEoJmN1cnJlbnQtPnNpZ2hhbmQtPnNpZ2xvY2spOwp9CgoKLyoKICoJSTJDIGludGVyZmFjZXMKICovCiAKc3RhdGljIGludCBpMmNfc2VuZGJ1ZihzdHJ1Y3Qgc2FhNTI0OV9kZXZpY2UgKnQsIGludCByZWcsIGludCBjb3VudCwgdTggKmRhdGEpIAp7CgljaGFyIGJ1Zls2NF07CgkKCWJ1ZlswXSA9IHJlZzsKCW1lbWNweShidWYrMSwgZGF0YSwgY291bnQpOwoJCglpZihpMmNfbWFzdGVyX3NlbmQodC0+Y2xpZW50LCBidWYsIGNvdW50KzEpPT1jb3VudCsxKQoJCXJldHVybiAwOwoJcmV0dXJuIC0xOwp9CgpzdGF0aWMgaW50IGkyY19zZW5kZGF0YShzdHJ1Y3Qgc2FhNTI0OV9kZXZpY2UgKnQsIC4uLikKewoJdW5zaWduZWQgY2hhciBidWZbNjRdOwoJaW50IHY7CglpbnQgY3Q9MDsKCXZhX2xpc3QgYXJncDsKCXZhX3N0YXJ0KGFyZ3AsdCk7CgkKCXdoaWxlKCh2PXZhX2FyZyhhcmdwLGludCkpIT0tMSkKCQlidWZbY3QrK109djsKCXJldHVybiBpMmNfc2VuZGJ1Zih0LCBidWZbMF0sIGN0LTEsIGJ1ZisxKTsKfQoKLyogR2V0IGNvdW50IG51bWJlciBvZiBieXRlcyBmcm9tIEmyQy1kZXZpY2UgYXQgYWRkcmVzcyBhZHIsIHN0b3JlIHRoZW0gaW4gYnVmLiBTdGFydCAmIHN0b3AKICogaGFuZHNoYWtpbmcgaXMgZG9uZSBieSB0aGlzIHJvdXRpbmUsIGFjayB3aWxsIGJlIHNlbnQgYWZ0ZXIgdGhlIGxhc3QgYnl0ZSB0byBpbmhpYml0IGZ1cnRoZXIKICogc2VuZGluZyBvZiBkYXRhLiBJZiB1YWNjZXNzIGlzIFRSVUUsIGRhdGEgaXMgd3JpdHRlbiB0byB1c2VyLXNwYWNlIHdpdGggcHV0X3VzZXIuCiAqIFJldHVybnMgLTEgaWYgSbJDLWRldmljZSBkaWRuJ3Qgc2VuZCBhY2tub3dsZWRnZSwgMCBvdGhlcndpc2UKICovCgpzdGF0aWMgaW50IGkyY19nZXRkYXRhKHN0cnVjdCBzYWE1MjQ5X2RldmljZSAqdCwgaW50IGNvdW50LCB1OCAqYnVmKSAKewoJaWYoaTJjX21hc3Rlcl9yZWN2KHQtPmNsaWVudCwgYnVmLCBjb3VudCkhPWNvdW50KQoJCXJldHVybiAtMTsKCXJldHVybiAwOwp9CgoKLyoKICoJU3RhbmRhcmQgY2hhcmFjdGVyLWRldmljZS1kcml2ZXIgZnVuY3Rpb25zCiAqLwoKc3RhdGljIGludCBkb19zYWE1MjQ5X2lvY3RsKHN0cnVjdCBpbm9kZSAqaW5vZGUsIHN0cnVjdCBmaWxlICpmaWxlLAoJCQkgICAgdW5zaWduZWQgaW50IGNtZCwgdm9pZCAqYXJnKQp7CglzdGF0aWMgaW50IHZpcnR1YWxfbW9kZSA9IEZBTFNFOwoJc3RydWN0IHZpZGVvX2RldmljZSAqdmQgPSB2aWRlb19kZXZkYXRhKGZpbGUpOwoJc3RydWN0IHNhYTUyNDlfZGV2aWNlICp0PXZkLT5wcml2OwoKCXN3aXRjaChjbWQpIAoJewoJCWNhc2UgVlRYSU9DR0VUSU5GTzogCgkJewoJCQl2dHhfaW5mb190ICppbmZvID0gYXJnOwoJCQlpbmZvLT52ZXJzaW9uX21ham9yID0gVlRYX1ZFUl9NQUo7CgkJCWluZm8tPnZlcnNpb25fbWlub3IgPSBWVFhfVkVSX01JTjsKCQkJaW5mby0+bnVtcGFnZXMgPSBOVU1fREFVUzsKCQkJLyppbmZvLT5jY3RfdHlwZSA9IENDVF9UWVBFOyovCgkJCXJldHVybiAwOwoJCX0KCgkJY2FzZSBWVFhJT0NDTFJQQUdFOiAKCQl7CgkJCXZ0eF9wYWdlcmVxX3QgKnJlcSA9IGFyZzsKICAgICAgCgkJCWlmIChyZXEtPnBnYnVmIDwgMCB8fCByZXEtPnBnYnVmID49IE5VTV9EQVVTKQoJCQkJcmV0dXJuIC1FSU5WQUw7CgkJCW1lbXNldCh0LT52ZGF1W3JlcS0+cGdidWZdLnBnYnVmLCAnICcsIHNpemVvZih0LT52ZGF1WzBdLnBnYnVmKSk7CgkJCXQtPnZkYXVbcmVxLT5wZ2J1Zl0uY2xyZm91bmQgPSBUUlVFOwoJCQlyZXR1cm4gMDsKCQl9CgoJCWNhc2UgVlRYSU9DQ0xSRk9VTkQ6IAoJCXsKCQkJdnR4X3BhZ2VyZXFfdCAqcmVxID0gYXJnOwogICAgICAKCQkJaWYgKHJlcS0+cGdidWYgPCAwIHx8IHJlcS0+cGdidWYgPj0gTlVNX0RBVVMpCgkJCQlyZXR1cm4gLUVJTlZBTDsKCQkJdC0+dmRhdVtyZXEtPnBnYnVmXS5jbHJmb3VuZCA9IFRSVUU7CgkJCXJldHVybiAwOwoJCX0KCgkJY2FzZSBWVFhJT0NQQUdFUkVROiAKCQl7CgkJCXZ0eF9wYWdlcmVxX3QgKnJlcSA9IGFyZzsKCQkJaWYgKCEocmVxLT5wYWdlbWFzayAmIFBHTUFTS19QQUdFKSkKCQkJCXJlcS0+cGFnZSA9IDA7CgkJCWlmICghKHJlcS0+cGFnZW1hc2sgJiBQR01BU0tfSE9VUikpCgkJCQlyZXEtPmhvdXIgPSAwOwoJCQlpZiAoIShyZXEtPnBhZ2VtYXNrICYgUEdNQVNLX01JTlVURSkpCgkJCQlyZXEtPm1pbnV0ZSA9IDA7CgkJCWlmIChyZXEtPnBhZ2UgPCAwIHx8IHJlcS0+cGFnZSA+IDB4OGZmKSAvKiA3RkYgPz8gKi8KCQkJCXJldHVybiAtRUlOVkFMOwoJCQlyZXEtPnBhZ2UgJj0gMHg3ZmY7CgkJCWlmIChyZXEtPmhvdXIgPCAwIHx8IHJlcS0+aG91ciA+IDB4M2YgfHwgcmVxLT5taW51dGUgPCAwIHx8IHJlcS0+bWludXRlID4gMHg3ZiB8fAoJCQkJcmVxLT5wYWdlbWFzayA8IDAgfHwgcmVxLT5wYWdlbWFzayA+PSBQR01BU0tfTUFYIHx8IHJlcS0+cGdidWYgPCAwIHx8IHJlcS0+cGdidWYgPj0gTlVNX0RBVVMpCgkJCQlyZXR1cm4gLUVJTlZBTDsKCQkJdC0+dmRhdVtyZXEtPnBnYnVmXS5zcmVnc1swXSA9IChyZXEtPnBhZ2VtYXNrICYgUEdfSFVORCA/IDB4MTAgOiAwKSB8IChyZXEtPnBhZ2UgLyAweDEwMCk7CgkJCXQtPnZkYXVbcmVxLT5wZ2J1Zl0uc3JlZ3NbMV0gPSAocmVxLT5wYWdlbWFzayAmIFBHX1RFTiA/IDB4MTAgOiAwKSB8ICgocmVxLT5wYWdlIC8gMHgxMCkgJiAweGYpOwoJCQl0LT52ZGF1W3JlcS0+cGdidWZdLnNyZWdzWzJdID0gKHJlcS0+cGFnZW1hc2sgJiBQR19VTklUID8gMHgxMCA6IDApIHwgKHJlcS0+cGFnZSAmIDB4Zik7CgkJCXQtPnZkYXVbcmVxLT5wZ2J1Zl0uc3JlZ3NbM10gPSAocmVxLT5wYWdlbWFzayAmIEhSX1RFTiA/IDB4MTAgOiAwKSB8IChyZXEtPmhvdXIgLyAweDEwKTsKCQkJdC0+dmRhdVtyZXEtPnBnYnVmXS5zcmVnc1s0XSA9IChyZXEtPnBhZ2VtYXNrICYgSFJfVU5JVCA/IDB4MTAgOiAwKSB8IChyZXEtPmhvdXIgJiAweGYpOwoJCQl0LT52ZGF1W3JlcS0+cGdidWZdLnNyZWdzWzVdID0gKHJlcS0+cGFnZW1hc2sgJiBNSU5fVEVOID8gMHgxMCA6IDApIHwgKHJlcS0+bWludXRlIC8gMHgxMCk7CgkJCXQtPnZkYXVbcmVxLT5wZ2J1Zl0uc3JlZ3NbNl0gPSAocmVxLT5wYWdlbWFzayAmIE1JTl9VTklUID8gMHgxMCA6IDApIHwgKHJlcS0+bWludXRlICYgMHhmKTsKCQkJdC0+dmRhdVtyZXEtPnBnYnVmXS5zdG9wcGVkID0gRkFMU0U7CgkJCXQtPnZkYXVbcmVxLT5wZ2J1Zl0uY2xyZm91bmQgPSBUUlVFOwoJCQl0LT5pc19zZWFyY2hpbmdbcmVxLT5wZ2J1Zl0gPSBUUlVFOwoJCQlyZXR1cm4gMDsKCQl9CgoJCWNhc2UgVlRYSU9DR0VUU1RBVDogCgkJewoJCQl2dHhfcGFnZXJlcV90ICpyZXEgPSBhcmc7CgkJCXU4IGluZm9iaXRzWzEwXTsKCQkJdnR4X3BhZ2VpbmZvX3QgaW5mbzsKCQkJaW50IGE7CgoJCQlpZiAocmVxLT5wZ2J1ZiA8IDAgfHwgcmVxLT5wZ2J1ZiA+PSBOVU1fREFVUykKCQkJCXJldHVybiAtRUlOVkFMOwoJCQlpZiAoIXQtPnZkYXVbcmVxLT5wZ2J1Zl0uc3RvcHBlZCkgCgkJCXsKCQkJCWlmIChpMmNfc2VuZGRhdGEodCwgMiwgMCwgLTEpIHx8CgkJCQkJaTJjX3NlbmRidWYodCwgMywgc2l6ZW9mKHQtPnZkYXVbMF0uc3JlZ3MpLCB0LT52ZGF1W3JlcS0+cGdidWZdLnNyZWdzKSB8fAoJCQkJCWkyY19zZW5kZGF0YSh0LCA4LCAwLCAyNSwgMCwgJyAnLCAnICcsICcgJywgJyAnLCAnICcsICcgJywgJyAnLCAnICcsICcgJywgLTEpIHx8CgkJCQkJaTJjX3NlbmRkYXRhKHQsIDIsIDAsIHQtPnZkYXVbcmVxLT5wZ2J1Zl0uc3JlZ3NbMF0gfCA4LCAtMSkgfHwKCQkJCQlpMmNfc2VuZGRhdGEodCwgOCwgMCwgMjUsIDAsIC0xKSkKCQkJCQlyZXR1cm4gLUVJTzsKCQkJCWpkZWxheShQQUdFX1dBSVQpOwoJCQkJaWYgKGkyY19nZXRkYXRhKHQsIDEwLCBpbmZvYml0cykpCgkJCQkJcmV0dXJuIC1FSU87CgoJCQkJaWYgKCEoaW5mb2JpdHNbOF0gJiAweDEwKSAmJiAhKGluZm9iaXRzWzddICYgMHhmMCkgJiYJLyogY2hlY2sgRk9VTkQtYml0ICovCgkJCQkJKG1lbWNtcChpbmZvYml0cywgdC0+dmRhdVtyZXEtPnBnYnVmXS5sYXN0c3RhdCwgc2l6ZW9mKGluZm9iaXRzKSkgfHwgCgkJCQkJdGltZV9hZnRlcl9lcShqaWZmaWVzLCB0LT52ZGF1W3JlcS0+cGdidWZdLmV4cGlyZSkpKQoJCQkJewkJLyogY2hlY2sgaWYgbmV3IHBhZ2UgYXJyaXZlZCAqLwoJCQkJCWlmIChpMmNfc2VuZGRhdGEodCwgOCwgMCwgMCwgMCwgLTEpIHx8CgkJCQkJCWkyY19nZXRkYXRhKHQsIFZUWF9QQUdFU0laRSwgdC0+dmRhdVtyZXEtPnBnYnVmXS5wZ2J1ZikpCgkJCQkJCXJldHVybiAtRUlPOwoJCQkJCXQtPnZkYXVbcmVxLT5wZ2J1Zl0uZXhwaXJlID0gamlmZmllcyArIFBHQlVGX0VYUElSRTsKCQkJCQltZW1zZXQodC0+dmRhdVtyZXEtPnBnYnVmXS5wZ2J1ZiArIFZUWF9QQUdFU0laRSwgJyAnLCBWVFhfVklSVFVBTFNJWkUgLSBWVFhfUEFHRVNJWkUpOwoJCQkJCWlmICh0LT52aXJ0dWFsX21vZGUpIAoJCQkJCXsKCQkJCQkJLyogUGFja2V0IFgvMjQgKi8KCQkJCQkJaWYgKGkyY19zZW5kZGF0YSh0LCA4LCAwLCAweDIwLCAwLCAtMSkgfHwKCQkJCQkJCWkyY19nZXRkYXRhKHQsIDQwLCB0LT52ZGF1W3JlcS0+cGdidWZdLnBnYnVmICsgVlRYX1BBR0VTSVpFICsgMjAgKiA0MCkpCgkJCQkJCQlyZXR1cm4gLUVJTzsKCQkJCQkJLyogUGFja2V0IFgvMjcvMCAqLwoJCQkJCQlpZiAoaTJjX3NlbmRkYXRhKHQsIDgsIDAsIDB4MjEsIDAsIC0xKSB8fAoJCQkJCQkJaTJjX2dldGRhdGEodCwgNDAsIHQtPnZkYXVbcmVxLT5wZ2J1Zl0ucGdidWYgKyBWVFhfUEFHRVNJWkUgKyAxNiAqIDQwKSkKCQkJCQkJCXJldHVybiAtRUlPOwoJCQkJCQkvKiBQYWNrZXQgOC8zMC8wLi4uOC8zMC8xNQoJCQkJCQkgKiBGSVhNRTogQUZBSUssIHRoZSA1MjQ5IGRvZXMgaGFtbWluZy1kZWNvZGluZyBmb3Igc29tZSBieXRlcyBpbiBwYWNrZXQgOC8zMCwKCQkJCQkJICogICAgICAgIHNvIHdlIHNob3VsZCB1bmRvIHRoaXMgaGVyZS4KCQkJCQkJICovCgkJCQkJCWlmIChpMmNfc2VuZGRhdGEodCwgOCwgMCwgMHgyMiwgMCwgLTEpIHx8CgkJCQkJCQlpMmNfZ2V0ZGF0YSh0LCA0MCwgdC0+dmRhdVtyZXEtPnBnYnVmXS5wZ2J1ZiArIFZUWF9QQUdFU0laRSArIDIzICogNDApKQoJCQkJCQkJcmV0dXJuIC1FSU87CgkJCQkJfQoJCQkJCXQtPnZkYXVbcmVxLT5wZ2J1Zl0uY2xyZm91bmQgPSBGQUxTRTsKCQkJCQltZW1jcHkodC0+dmRhdVtyZXEtPnBnYnVmXS5sYXN0c3RhdCwgaW5mb2JpdHMsIHNpemVvZihpbmZvYml0cykpOwoJCQkJfQoJCQkJZWxzZQoJCQkJewoJCQkJCW1lbWNweShpbmZvYml0cywgdC0+dmRhdVtyZXEtPnBnYnVmXS5sYXN0c3RhdCwgc2l6ZW9mKGluZm9iaXRzKSk7CgkJCQl9CgkJCX0KCQkJZWxzZQoJCQl7CgkJCQltZW1jcHkoaW5mb2JpdHMsIHQtPnZkYXVbcmVxLT5wZ2J1Zl0ubGFzdHN0YXQsIHNpemVvZihpbmZvYml0cykpOwoJCQl9CgoJCQlpbmZvLnBhZ2VudW0gPSAoKGluZm9iaXRzWzhdIDw8IDgpICYgMHg3MDApIHwgKChpbmZvYml0c1sxXSA8PCA0KSAmIDB4ZjApIHwgKGluZm9iaXRzWzBdICYgMHgwZik7CgkJCWlmIChpbmZvLnBhZ2VudW0gPCAweDEwMCkKCQkJCWluZm8ucGFnZW51bSArPSAweDgwMDsKCQkJaW5mby5ob3VyID0gKChpbmZvYml0c1s1XSA8PCA0KSAmIDB4MzApIHwgKGluZm9iaXRzWzRdICYgMHgwZik7CgkJCWluZm8ubWludXRlID0gKChpbmZvYml0c1szXSA8PCA0KSAmIDB4NzApIHwgKGluZm9iaXRzWzJdICYgMHgwZik7CgkJCWluZm8uY2hhcnNldCA9ICgoaW5mb2JpdHNbN10gPj4gMSkgJiA3KTsKCQkJaW5mby5kZWxldGUgPSAhIShpbmZvYml0c1szXSAmIDgpOwoJCQlpbmZvLmhlYWRsaW5lID0gISEoaW5mb2JpdHNbNV0gJiA0KTsKCQkJaW5mby5zdWJ0aXRsZSA9ICEhKGluZm9iaXRzWzVdICYgOCk7CgkJCWluZm8uc3VwcF9oZWFkZXIgPSAhIShpbmZvYml0c1s2XSAmIDEpOwoJCQlpbmZvLnVwZGF0ZSA9ICEhKGluZm9iaXRzWzZdICYgMik7CgkJCWluZm8uaW50ZXJfc2VxID0gISEoaW5mb2JpdHNbNl0gJiA0KTsKCQkJaW5mby5kaXNfZGlzcCA9ICEhKGluZm9iaXRzWzZdICYgOCk7CgkJCWluZm8uc2VyaWFsID0gISEoaW5mb2JpdHNbN10gJiAxKTsKCQkJaW5mby5ub3Rmb3VuZCA9ICEhKGluZm9iaXRzWzhdICYgMHgxMCk7CgkJCWluZm8ucGJsZiA9ICEhKGluZm9iaXRzWzldICYgMHgyMCk7CgkJCWluZm8uaGFtbWluZyA9IDA7CgkJCWZvciAoYSA9IDA7IGEgPD0gNzsgYSsrKSAKCQkJewoJCQkJaWYgKGluZm9iaXRzW2FdICYgMHhmMCkgCgkJCQl7CgkJCQkJaW5mby5oYW1taW5nID0gMTsKCQkJCQlicmVhazsKCQkJCX0KCQkJfQoJCQlpZiAodC0+dmRhdVtyZXEtPnBnYnVmXS5jbHJmb3VuZCkKCQkJCWluZm8ubm90Zm91bmQgPSAxOwoJCQlpZihjb3B5X3RvX3VzZXIocmVxLT5idWZmZXIsICZpbmZvLCBzaXplb2YodnR4X3BhZ2VpbmZvX3QpKSkKCQkJCXJldHVybiAtRUZBVUxUOwoJCQlpZiAoIWluZm8uaGFtbWluZyAmJiAhaW5mby5ub3Rmb3VuZCkgCgkJCXsKCQkJCXQtPmlzX3NlYXJjaGluZ1tyZXEtPnBnYnVmXSA9IEZBTFNFOwoJCQl9CgkJCXJldHVybiAwOwoJCX0KCgkJY2FzZSBWVFhJT0NHRVRQQUdFOiAKCQl7CgkJCXZ0eF9wYWdlcmVxX3QgKnJlcSA9IGFyZzsKCQkJaW50IHN0YXJ0LCBlbmQ7CgoJCQlpZiAocmVxLT5wZ2J1ZiA8IDAgfHwgcmVxLT5wZ2J1ZiA+PSBOVU1fREFVUyB8fCByZXEtPnN0YXJ0IDwgMCB8fAoJCQkJcmVxLT5zdGFydCA+IHJlcS0+ZW5kIHx8IHJlcS0+ZW5kID49ICh2aXJ0dWFsX21vZGUgPyBWVFhfVklSVFVBTFNJWkUgOiBWVFhfUEFHRVNJWkUpKQoJCQkJcmV0dXJuIC1FSU5WQUw7CgkJCWlmKGNvcHlfdG9fdXNlcihyZXEtPmJ1ZmZlciwgJnQtPnZkYXVbcmVxLT5wZ2J1Zl0ucGdidWZbcmVxLT5zdGFydF0sIHJlcS0+ZW5kIC0gcmVxLT5zdGFydCArIDEpKQoJCQkJcmV0dXJuIC1FRkFVTFQ7CgkJCQkKCQkJIC8qIAoJCQkgICoJQWx3YXlzIHJlYWQgdGhlIHRpbWUgZGlyZWN0bHkgZnJvbSBTQUE1MjQ5CgkJCSAgKi8KCQkJICAKCQkJaWYgKHJlcS0+c3RhcnQgPD0gMzkgJiYgcmVxLT5lbmQgPj0gMzIpIAoJCQl7CgkJCQlpbnQgbGVuOwoJCQkJY2hhciBidWZbMTZdOyAgCgkJCQlzdGFydCA9IG1heChyZXEtPnN0YXJ0LCAzMik7CgkJCQllbmQgPSBtaW4ocmVxLT5lbmQsIDM5KTsKCQkJCWxlbj1lbmQtc3RhcnQrMTsKCQkJCWlmIChpMmNfc2VuZGRhdGEodCwgOCwgMCwgMCwgc3RhcnQsIC0xKSB8fAoJCQkJCWkyY19nZXRkYXRhKHQsIGxlbiwgYnVmKSkKCQkJCQlyZXR1cm4gLUVJTzsKCQkJCWlmKGNvcHlfdG9fdXNlcihyZXEtPmJ1ZmZlcitzdGFydC1yZXEtPnN0YXJ0LCBidWYsIGxlbikpCgkJCQkJcmV0dXJuIC1FRkFVTFQ7CgkJCX0KCQkJLyogSW5zZXJ0IHRoZSBjdXJyZW50IGhlYWRlciBpZiBEQVUgaXMgc3RpbGwgc2VhcmNoaW5nIGZvciBhIHBhZ2UgKi8KCQkJaWYgKHJlcS0+c3RhcnQgPD0gMzEgJiYgcmVxLT5lbmQgPj0gNyAmJiB0LT5pc19zZWFyY2hpbmdbcmVxLT5wZ2J1Zl0pIAoJCQl7CgkJCQljaGFyIGJ1ZlszMl07CgkJCQlpbnQgbGVuOwoJCQkJc3RhcnQgPSBtYXgocmVxLT5zdGFydCwgNyk7CgkJCQllbmQgPSBtaW4ocmVxLT5lbmQsIDMxKTsKCQkJCWxlbj1lbmQtc3RhcnQrMTsKCQkJCWlmIChpMmNfc2VuZGRhdGEodCwgOCwgMCwgMCwgc3RhcnQsIC0xKSB8fAoJCQkJCWkyY19nZXRkYXRhKHQsIGxlbiwgYnVmKSkKCQkJCQlyZXR1cm4gLUVJTzsKCQkJCWlmKGNvcHlfdG9fdXNlcihyZXEtPmJ1ZmZlcitzdGFydC1yZXEtPnN0YXJ0LCBidWYsIGxlbikpCgkJCQkJcmV0dXJuIC1FRkFVTFQ7CgkJCX0KCQkJcmV0dXJuIDA7CgkJfQoKCQljYXNlIFZUWElPQ1NUT1BEQVU6IAoJCXsKCQkJdnR4X3BhZ2VyZXFfdCAqcmVxID0gYXJnOwoKCQkJaWYgKHJlcS0+cGdidWYgPCAwIHx8IHJlcS0+cGdidWYgPj0gTlVNX0RBVVMpCgkJCQlyZXR1cm4gLUVJTlZBTDsKCQkJdC0+dmRhdVtyZXEtPnBnYnVmXS5zdG9wcGVkID0gVFJVRTsKCQkJdC0+aXNfc2VhcmNoaW5nW3JlcS0+cGdidWZdID0gRkFMU0U7CgkJCXJldHVybiAwOwoJCX0KCgkJY2FzZSBWVFhJT0NQVVRQQUdFOiAKCQljYXNlIFZUWElPQ1NFVERJU1A6IAoJCWNhc2UgVlRYSU9DUFVUU1RBVDogCgkJCXJldHVybiAwOwoJCQkKCQljYXNlIFZUWElPQ0NMUkNBQ0hFOiAKCQl7CgkJCWlmIChpMmNfc2VuZGRhdGEodCwgMCwgTlVNX0RBVVMsIDAsIDgsIC0xKSB8fCBpMmNfc2VuZGRhdGEodCwgMTEsCgkJCQknICcsJyAnLCcgJywnICcsJyAnLCcgJywnICcsJyAnLCcgJywnICcsJyAnLCcgJywKCQkJCScgJywnICcsJyAnLCcgJywnICcsJyAnLCcgJywnICcsJyAnLCcgJywnICcsJyAnLCAtMSkpCgkJCQlyZXR1cm4gLUVJTzsKCQkJaWYgKGkyY19zZW5kZGF0YSh0LCAzLCAweDIwLCAtMSkpCgkJCQlyZXR1cm4gLUVJTzsKCQkJamRlbGF5KDEwICogQ0xFQVJfREVMQVkpOwkJCS8qIEkgaGF2ZSBubyBpZGVhIGhvdyBsb25nIHdlIGhhdmUgdG8gd2FpdCBoZXJlICovCgkJCXJldHVybiAwOwoJCX0KCgkJY2FzZSBWVFhJT0NTRVRWSVJUOiAKCQl7CgkJCS8qIFRoZSBTQUE1MjQ5IGhhcyB2aXJ0dWFsLXJvdyByZWNlcHRpb24gdHVybmVkIG9uIGFsd2F5cyAqLwoJCQl0LT52aXJ0dWFsX21vZGUgPSAoaW50KShsb25nKWFyZzsKCQkJcmV0dXJuIDA7CgkJfQoJfQoJcmV0dXJuIC1FSU5WQUw7Cn0KCi8qCiAqIFRyYW5zbGF0ZXMgb2xkIHZ0eCBJT0NUTHMgdG8gbmV3IG9uZXMKICoKICogVGhpcyBrZWVwcyBuZXcga2VybmVsIHZlcnNpb25zIGNvbXBhdGlibGUgd2l0aCBvbGQgdXNlcnNwYWNlIHByb2dyYW1zLgogKi8Kc3RhdGljIGlubGluZSB1bnNpZ25lZCBpbnQgdnR4X2ZpeF9jb21tYW5kKHVuc2lnbmVkIGludCBjbWQpCnsKCXN3aXRjaCAoY21kKSB7CgljYXNlIFZUWElPQ0dFVElORk9fT0xEOgoJCWNtZCA9IFZUWElPQ0dFVElORk87CgkJYnJlYWs7CgljYXNlIFZUWElPQ0NMUlBBR0VfT0xEOgoJCWNtZCA9IFZUWElPQ0NMUlBBR0U7CgkJYnJlYWs7CgljYXNlIFZUWElPQ0NMUkZPVU5EX09MRDoKCQljbWQgPSBWVFhJT0NDTFJGT1VORDsKCQlicmVhazsKCWNhc2UgVlRYSU9DUEFHRVJFUV9PTEQ6CgkJY21kID0gVlRYSU9DUEFHRVJFUTsKCQlicmVhazsKCWNhc2UgVlRYSU9DR0VUU1RBVF9PTEQ6CgkJY21kID0gVlRYSU9DR0VUU1RBVDsKCQlicmVhazsKCWNhc2UgVlRYSU9DR0VUUEFHRV9PTEQ6CgkJY21kID0gVlRYSU9DR0VUUEFHRTsKCQlicmVhazsKCWNhc2UgVlRYSU9DU1RPUERBVV9PTEQ6CgkJY21kID0gVlRYSU9DU1RPUERBVTsKCQlicmVhazsKCWNhc2UgVlRYSU9DUFVUUEFHRV9PTEQ6CgkJY21kID0gVlRYSU9DUFVUUEFHRTsKCQlicmVhazsKCWNhc2UgVlRYSU9DU0VURElTUF9PTEQ6CgkJY21kID0gVlRYSU9DU0VURElTUDsKCQlicmVhazsKCWNhc2UgVlRYSU9DUFVUU1RBVF9PTEQ6CgkJY21kID0gVlRYSU9DUFVUU1RBVDsKCQlicmVhazsKCWNhc2UgVlRYSU9DQ0xSQ0FDSEVfT0xEOgoJCWNtZCA9IFZUWElPQ0NMUkNBQ0hFOwoJCWJyZWFrOwoJY2FzZSBWVFhJT0NTRVRWSVJUX09MRDoKCQljbWQgPSBWVFhJT0NTRVRWSVJUOwoJCWJyZWFrOwoJfQoJcmV0dXJuIGNtZDsKfQoKLyoKICoJSGFuZGxlIHRoZSBsb2NraW5nCiAqLwogCnN0YXRpYyBpbnQgc2FhNTI0OV9pb2N0bChzdHJ1Y3QgaW5vZGUgKmlub2RlLCBzdHJ1Y3QgZmlsZSAqZmlsZSwKCQkJIHVuc2lnbmVkIGludCBjbWQsIHVuc2lnbmVkIGxvbmcgYXJnKSAKewoJc3RydWN0IHZpZGVvX2RldmljZSAqdmQgPSB2aWRlb19kZXZkYXRhKGZpbGUpOwoJc3RydWN0IHNhYTUyNDlfZGV2aWNlICp0PXZkLT5wcml2OwoJaW50IGVycjsKCQoJY21kID0gdnR4X2ZpeF9jb21tYW5kKGNtZCk7CgltdXRleF9sb2NrKCZ0LT5sb2NrKTsKCWVyciA9IHZpZGVvX3VzZXJjb3B5KGlub2RlLGZpbGUsY21kLGFyZyxkb19zYWE1MjQ5X2lvY3RsKTsKCW11dGV4X3VubG9jaygmdC0+bG9jayk7CglyZXR1cm4gZXJyOwp9CgpzdGF0aWMgaW50IHNhYTUyNDlfb3BlbihzdHJ1Y3QgaW5vZGUgKmlub2RlLCBzdHJ1Y3QgZmlsZSAqZmlsZSkgCnsKCXN0cnVjdCB2aWRlb19kZXZpY2UgKnZkID0gdmlkZW9fZGV2ZGF0YShmaWxlKTsKCXN0cnVjdCBzYWE1MjQ5X2RldmljZSAqdD12ZC0+cHJpdjsKCWludCBlcnIscGdidWY7CgoJZXJyID0gdmlkZW9fZXhjbHVzaXZlX29wZW4oaW5vZGUsZmlsZSk7CglpZiAoZXJyIDwgMCkKCQlyZXR1cm4gZXJyOwoJCglpZiAodC0+Y2xpZW50PT1OVUxMKSB7CgkJZXJyID0gLUVOT0RFVjsKCQlnb3RvIGZhaWw7Cgl9CgoJaWYgKGkyY19zZW5kZGF0YSh0LCAwLCAwLCAtMSkgfHwJCS8qIFNlbGVjdCBSMTEgKi8KCQkJCQkJLyogVHVybiBvZmYgcGFyaXR5IGNoZWNrcyAod2UgZG8gdGhpcyBvdXJzZWx2ZXMpICovCgkJaTJjX3NlbmRkYXRhKHQsIDEsIGRpc3BfbW9kZXNbdC0+ZGlzcF9tb2RlXVswXSwgMCwgLTEpIHx8CgkJCQkJCS8qIERpc3BsYXkgVFYtcGljdHVyZSwgbm8gdmlydHVhbCByb3dzICovCgkJaTJjX3NlbmRkYXRhKHQsIDQsIE5VTV9EQVVTLCBkaXNwX21vZGVzW3QtPmRpc3BfbW9kZV1bMV0sIGRpc3BfbW9kZXNbdC0+ZGlzcF9tb2RlXVsyXSwgNywgLTEpKSAvKiBTZXQgZGlzcGxheSB0byBwYWdlIDQgKi8KCQoJewoJCWVyciA9IC1FSU87CgkJZ290byBmYWlsOwoJfQoKCWZvciAocGdidWYgPSAwOyBwZ2J1ZiA8IE5VTV9EQVVTOyBwZ2J1ZisrKSAKCXsKCQltZW1zZXQodC0+dmRhdVtwZ2J1Zl0ucGdidWYsICcgJywgc2l6ZW9mKHQtPnZkYXVbMF0ucGdidWYpKTsKCQltZW1zZXQodC0+dmRhdVtwZ2J1Zl0uc3JlZ3MsIDAsIHNpemVvZih0LT52ZGF1WzBdLnNyZWdzKSk7CgkJbWVtc2V0KHQtPnZkYXVbcGdidWZdLmxhc3RzdGF0LCAwLCBzaXplb2YodC0+dmRhdVswXS5sYXN0c3RhdCkpOwoJCXQtPnZkYXVbcGdidWZdLmV4cGlyZSA9IDA7CgkJdC0+dmRhdVtwZ2J1Zl0uY2xyZm91bmQgPSBUUlVFOwoJCXQtPnZkYXVbcGdidWZdLnN0b3BwZWQgPSBUUlVFOwoJCXQtPmlzX3NlYXJjaGluZ1twZ2J1Zl0gPSBGQUxTRTsKCX0KCXQtPnZpcnR1YWxfbW9kZT1GQUxTRTsKCXJldHVybiAwOwoKIGZhaWw6Cgl2aWRlb19leGNsdXNpdmVfcmVsZWFzZShpbm9kZSxmaWxlKTsKCXJldHVybiBlcnI7Cn0KCgoKc3RhdGljIGludCBzYWE1MjQ5X3JlbGVhc2Uoc3RydWN0IGlub2RlICppbm9kZSwgc3RydWN0IGZpbGUgKmZpbGUpIAp7CglzdHJ1Y3QgdmlkZW9fZGV2aWNlICp2ZCA9IHZpZGVvX2RldmRhdGEoZmlsZSk7CglzdHJ1Y3Qgc2FhNTI0OV9kZXZpY2UgKnQ9dmQtPnByaXY7CglpMmNfc2VuZGRhdGEodCwgMSwgMHgyMCwgLTEpOwkJLyogVHVybiBvZmYgQ0NUICovCglpMmNfc2VuZGRhdGEodCwgNSwgMywgMywgLTEpOwkJLyogVHVybiBvZmYgVFYtZGlzcGxheSAqLwoJdmlkZW9fZXhjbHVzaXZlX3JlbGVhc2UoaW5vZGUsZmlsZSk7CglyZXR1cm4gMDsKfQoKc3RhdGljIGludCBfX2luaXQgaW5pdF9zYWFfNTI0OSAodm9pZCkKewoJcHJpbnRrKEtFUk5fSU5GTyAiU0FBNTI0OSBkcml2ZXIgKCIgSUZfTkFNRSAiIGludGVyZmFjZSkgZm9yIFZpZGVvVGV4dCB2ZXJzaW9uICVkLiVkXG4iLAoJCQlWVFhfVkVSX01BSiwgVlRYX1ZFUl9NSU4pOwoJcmV0dXJuIGkyY19hZGRfZHJpdmVyKCZpMmNfZHJpdmVyX3ZpZGVvdGV4dCk7Cn0KCnN0YXRpYyB2b2lkIF9fZXhpdCBjbGVhbnVwX3NhYV81MjQ5ICh2b2lkKSAKewoJaTJjX2RlbF9kcml2ZXIoJmkyY19kcml2ZXJfdmlkZW90ZXh0KTsKfQoKbW9kdWxlX2luaXQoaW5pdF9zYWFfNTI0OSk7Cm1vZHVsZV9leGl0KGNsZWFudXBfc2FhXzUyNDkpOwoKc3RhdGljIHN0cnVjdCBmaWxlX29wZXJhdGlvbnMgc2FhX2ZvcHMgPSB7Cgkub3duZXIJCT0gVEhJU19NT0RVTEUsCgkub3BlbgkJPSBzYWE1MjQ5X29wZW4sCgkucmVsZWFzZSAgICAgICAJPSBzYWE1MjQ5X3JlbGVhc2UsCgkuaW9jdGwgICAgICAgICAgPSBzYWE1MjQ5X2lvY3RsLAoJLmNvbXBhdF9pb2N0bAk9IHY0bF9jb21wYXRfaW9jdGwzMiwKCS5sbHNlZWsgICAgICAgICA9IG5vX2xsc2VlaywKfTsKCnN0YXRpYyBzdHJ1Y3QgdmlkZW9fZGV2aWNlIHNhYV90ZW1wbGF0ZSA9CnsKCS5vd25lcgkJPSBUSElTX01PRFVMRSwKCS5uYW1lCQk9IElGX05BTUUsCgkudHlwZQkJPSBWSURfVFlQRV9URUxFVEVYVCwJLyp8IFZJRF9UWVBFX1RVTkVSID8/ICovCgkuaGFyZHdhcmUJPSBWSURfSEFSRFdBUkVfU0FBNTI0OSwKCS5mb3BzICAgICAgICAgICA9ICZzYWFfZm9wcywKfTsKCk1PRFVMRV9MSUNFTlNFKCJHUEwiKTsK