LyoKICogRHJpdmVyIGZvciB0aGUgU0FBNTI0NkEgb3IgU0FBNTI4MSBUZWxldGV4dCAoPVZpZGVvdGV4dCkgZGVjb2RlciBjaGlwcyBmcm9tCiAqIFBoaWxpcHMuCiAqCiAqIE9ubHkgY2FwdHVyaW5nIG9mIFRlbGV0ZXh0IHBhZ2VzIGlzIHRlc3RlZC4gVGhlIHZpZGVvdGV4dCBjaGlwcyBhbHNvIGhhdmUgYQogKiBUViBvdXRwdXQgYnV0IG15IGhhcmR3YXJlIGRvZXNuJ3QgdXNlIGl0LiBGb3IgdGhpcyByZWFzb24gdGhpcyBkcml2ZXIgZG9lcwogKiBub3Qgc3VwcG9ydCBjaGFuZ2luZyBhbnkgVFYgZGlzcGxheSBzZXR0aW5ncy4KICoKICogQ29weXJpZ2h0IChDKSAyMDA0IE1pY2hhZWwgR2VuZyA8bGludXhATWljaGFlbEdlbmcuZGU+CiAqCiAqIERlcml2ZWQgZnJvbQogKgogKiBzYWE1MjQ5IGRyaXZlcgogKiBDb3B5cmlnaHQgKEMpIDE5OTggUmljaGFyZCBHdWVudGhlcgogKiA8cmljaGFyZC5ndWVudGhlckBzdHVkZW50LnVuaS10dWViaW5nZW4uZGU+CiAqCiAqIHdpdGggY2hhbmdlcyBieQogKiBBbGFuIENveCA8QWxhbi5Db3hAbGludXgub3JnPgogKgogKiBhbmQKICoKICogdnR4LmMKICogQ29weXJpZ2h0IChDKSAxOTk0LTk3IE1hcnRpbiBCdWNrICA8bWFydGluLTIuYnVja0BzdHVkZW50LnVuaS11bG0uZGU+CiAqCiAqIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5CiAqIGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5CiAqIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlciB2ZXJzaW9uIDIgb2YgdGhlIExpY2Vuc2UsIG9yCiAqIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlCiAqIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIGFsb25nIHdpdGggdGhpcyBwcm9ncmFtOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDU5IFRlbXBsZSBQbGFjZSAtIFN1aXRlIDMzMCwgQm9zdG9uLCBNQSAwMjExMS0xMzA3LAogKiBVU0EuCiAqLwoKI2luY2x1ZGUgPGxpbnV4L21vZHVsZS5oPgojaW5jbHVkZSA8bGludXgva2VybmVsLmg+CiNpbmNsdWRlIDxsaW51eC9zY2hlZC5oPgojaW5jbHVkZSA8bGludXgvbW0uaD4KI2luY2x1ZGUgPGxpbnV4L2luaXQuaD4KI2luY2x1ZGUgPGxpbnV4L2kyYy5oPgojaW5jbHVkZSA8bGludXgvdmlkZW90ZXh0Lmg+CiNpbmNsdWRlIDxsaW51eC92aWRlb2Rldi5oPgojaW5jbHVkZSA8bGludXgvbXV0ZXguaD4KCiNpbmNsdWRlICJzYWE1MjQ2YS5oIgoKTU9EVUxFX0FVVEhPUigiTWljaGFlbCBHZW5nIDxsaW51eEBNaWNoYWVsR2VuZy5kZT4iKTsKTU9EVUxFX0RFU0NSSVBUSU9OKCJQaGlsaXBzIFNBQTUyNDZBLCBTQUE1MjgxIFRlbGV0ZXh0IGRlY29kZXIgZHJpdmVyIik7Ck1PRFVMRV9MSUNFTlNFKCJHUEwiKTsKCnN0cnVjdCBzYWE1MjQ2YV9kZXZpY2UKewoJdTggICAgIHBnYnVmW05VTV9EQVVTXVtWVFhfVklSVFVBTFNJWkVdOwoJaW50ICAgIGlzX3NlYXJjaGluZ1tOVU1fREFVU107CglzdHJ1Y3QgaTJjX2NsaWVudCAqY2xpZW50OwoJc3RydWN0IG11dGV4IGxvY2s7Cn07CgpzdGF0aWMgc3RydWN0IHZpZGVvX2RldmljZSBzYWFfdGVtcGxhdGU7CS8qIERlY2xhcmVkIG5lYXIgYm90dG9tICovCgovKiBBZGRyZXNzZXMgdG8gc2NhbiAqLwpzdGF0aWMgdW5zaWduZWQgc2hvcnQgbm9ybWFsX2kyY1tdCSA9IHsgSTJDX0FERFJFU1MsIEkyQ19DTElFTlRfRU5EIH07CkkyQ19DTElFTlRfSU5TTU9EOwoKc3RhdGljIHN0cnVjdCBpMmNfY2xpZW50IGNsaWVudF90ZW1wbGF0ZTsKCnN0YXRpYyBpbnQgc2FhNTI0NmFfYXR0YWNoKHN0cnVjdCBpMmNfYWRhcHRlciAqYWRhcCwgaW50IGFkZHIsIGludCBraW5kKQp7CglpbnQgcGdidWY7CglpbnQgZXJyOwoJc3RydWN0IGkyY19jbGllbnQgKmNsaWVudDsKCXN0cnVjdCB2aWRlb19kZXZpY2UgKnZkOwoJc3RydWN0IHNhYTUyNDZhX2RldmljZSAqdDsKCglwcmludGsoS0VSTl9JTkZPICJzYWE1MjQ2YTogdGVsZXRleHQgY2hpcCBmb3VuZC5cbiIpOwoJY2xpZW50PWttYWxsb2Moc2l6ZW9mKCpjbGllbnQpLCBHRlBfS0VSTkVMKTsKCWlmKGNsaWVudD09TlVMTCkKCQlyZXR1cm4gLUVOT01FTTsKCWNsaWVudF90ZW1wbGF0ZS5hZGFwdGVyID0gYWRhcDsKCWNsaWVudF90ZW1wbGF0ZS5hZGRyID0gYWRkcjsKCW1lbWNweShjbGllbnQsICZjbGllbnRfdGVtcGxhdGUsIHNpemVvZigqY2xpZW50KSk7Cgl0ID0ga3phbGxvYyhzaXplb2YoKnQpLCBHRlBfS0VSTkVMKTsKCWlmKHQ9PU5VTEwpCgl7CgkJa2ZyZWUoY2xpZW50KTsKCQlyZXR1cm4gLUVOT01FTTsKCX0KCXN0cmxjcHkoY2xpZW50LT5uYW1lLCBJRl9OQU1FLCBJMkNfTkFNRV9TSVpFKTsKCW11dGV4X2luaXQoJnQtPmxvY2spOwoKCS8qCgkgKglOb3cgY3JlYXRlIGEgdmlkZW80bGludXggZGV2aWNlCgkgKi8KCgl2ZCA9IHZpZGVvX2RldmljZV9hbGxvYygpOwoJaWYodmQ9PU5VTEwpCgl7CgkJa2ZyZWUodCk7CgkJa2ZyZWUoY2xpZW50KTsKCQlyZXR1cm4gLUVOT01FTTsKCX0KCWkyY19zZXRfY2xpZW50ZGF0YShjbGllbnQsIHZkKTsKCW1lbWNweSh2ZCwgJnNhYV90ZW1wbGF0ZSwgc2l6ZW9mKCp2ZCkpOwoKCWZvciAocGdidWYgPSAwOyBwZ2J1ZiA8IE5VTV9EQVVTOyBwZ2J1ZisrKQoJewoJCW1lbXNldCh0LT5wZ2J1ZltwZ2J1Zl0sICcgJywgc2l6ZW9mKHQtPnBnYnVmWzBdKSk7CgkJdC0+aXNfc2VhcmNoaW5nW3BnYnVmXSA9IEZBTFNFOwoJfQoJdmQtPnByaXY9dDsKCgoJLyoKCSAqCVJlZ2lzdGVyIGl0CgkgKi8KCglpZigoZXJyPXZpZGVvX3JlZ2lzdGVyX2RldmljZSh2ZCwgVkZMX1RZUEVfVlRYLC0xKSk8MCkKCXsKCQlrZnJlZSh0KTsKCQlrZnJlZShjbGllbnQpOwoJCXZpZGVvX2RldmljZV9yZWxlYXNlKHZkKTsKCQlyZXR1cm4gZXJyOwoJfQoJdC0+Y2xpZW50ID0gY2xpZW50OwoJaTJjX2F0dGFjaF9jbGllbnQoY2xpZW50KTsKCXJldHVybiAwOwp9CgovKgogKglXZSBkbyBtb3N0IG9mIHRoZSBoYXJkIHdvcmsgd2hlbiB3ZSBiZWNvbWUgYSBkZXZpY2Ugb24gdGhlIGkyYy4KICovCnN0YXRpYyBpbnQgc2FhNTI0NmFfcHJvYmUoc3RydWN0IGkyY19hZGFwdGVyICphZGFwKQp7CglpZiAoYWRhcC0+Y2xhc3MgJiBJMkNfQ0xBU1NfVFZfQU5BTE9HKQoJCXJldHVybiBpMmNfcHJvYmUoYWRhcCwgJmFkZHJfZGF0YSwgc2FhNTI0NmFfYXR0YWNoKTsKCXJldHVybiAwOwp9CgpzdGF0aWMgaW50IHNhYTUyNDZhX2RldGFjaChzdHJ1Y3QgaTJjX2NsaWVudCAqY2xpZW50KQp7CglzdHJ1Y3QgdmlkZW9fZGV2aWNlICp2ZCA9IGkyY19nZXRfY2xpZW50ZGF0YShjbGllbnQpOwoJaTJjX2RldGFjaF9jbGllbnQoY2xpZW50KTsKCXZpZGVvX3VucmVnaXN0ZXJfZGV2aWNlKHZkKTsKCWtmcmVlKHZkLT5wcml2KTsKCWtmcmVlKGNsaWVudCk7CglyZXR1cm4gMDsKfQoKLyoKICoJSTJDIGludGVyZmFjZXMKICovCgpzdGF0aWMgc3RydWN0IGkyY19kcml2ZXIgaTJjX2RyaXZlcl92aWRlb3RleHQgPQp7CgkuZHJpdmVyID0gewoJCS5uYW1lIAk9IElGX05BTUUsCQkvKiBuYW1lICovCgl9LAoJLmlkIAkJPSBJMkNfRFJJVkVSSURfU0FBNTI0OSwgLyogaW4gaTJjLmggKi8KCS5hdHRhY2hfYWRhcHRlciA9IHNhYTUyNDZhX3Byb2JlLAoJLmRldGFjaF9jbGllbnQgID0gc2FhNTI0NmFfZGV0YWNoLAp9OwoKc3RhdGljIHN0cnVjdCBpMmNfY2xpZW50IGNsaWVudF90ZW1wbGF0ZSA9IHsKCS5kcml2ZXIJCT0gJmkyY19kcml2ZXJfdmlkZW90ZXh0LAoJLm5hbWUJCT0gIih1bnNldCkiLAp9OwoKc3RhdGljIGludCBpMmNfc2VuZGJ1ZihzdHJ1Y3Qgc2FhNTI0NmFfZGV2aWNlICp0LCBpbnQgcmVnLCBpbnQgY291bnQsIHU4ICpkYXRhKQp7CgljaGFyIGJ1Zls2NF07CgoJYnVmWzBdID0gcmVnOwoJbWVtY3B5KGJ1ZisxLCBkYXRhLCBjb3VudCk7CgoJaWYoaTJjX21hc3Rlcl9zZW5kKHQtPmNsaWVudCwgYnVmLCBjb3VudCsxKT09Y291bnQrMSkKCQlyZXR1cm4gMDsKCXJldHVybiAtMTsKfQoKc3RhdGljIGludCBpMmNfc2VuZGRhdGEoc3RydWN0IHNhYTUyNDZhX2RldmljZSAqdCwgLi4uKQp7Cgl1bnNpZ25lZCBjaGFyIGJ1Zls2NF07CglpbnQgdjsKCWludCBjdD0wOwoJdmFfbGlzdCBhcmdwOwoJdmFfc3RhcnQoYXJncCx0KTsKCgl3aGlsZSgodj12YV9hcmcoYXJncCxpbnQpKSE9LTEpCgkJYnVmW2N0KytdPXY7CglyZXR1cm4gaTJjX3NlbmRidWYodCwgYnVmWzBdLCBjdC0xLCBidWYrMSk7Cn0KCi8qIEdldCBjb3VudCBudW1iZXIgb2YgYnl0ZXMgZnJvbSBJskMtZGV2aWNlIGF0IGFkZHJlc3MgYWRyLCBzdG9yZSB0aGVtIGluIGJ1Zi4KICogU3RhcnQgJiBzdG9wIGhhbmRzaGFraW5nIGlzIGRvbmUgYnkgdGhpcyByb3V0aW5lLCBhY2sgd2lsbCBiZSBzZW50IGFmdGVyIHRoZQogKiBsYXN0IGJ5dGUgdG8gaW5oaWJpdCBmdXJ0aGVyIHNlbmRpbmcgb2YgZGF0YS4gSWYgdWFjY2VzcyBpcyBUUlVFLCBkYXRhIGlzCiAqIHdyaXR0ZW4gdG8gdXNlci1zcGFjZSB3aXRoIHB1dF91c2VyLiBSZXR1cm5zIC0xIGlmIEmyQy1kZXZpY2UgZGlkbid0IHNlbmQKICogYWNrbm93bGVkZ2UsIDAgb3RoZXJ3aXNlCiAqLwpzdGF0aWMgaW50IGkyY19nZXRkYXRhKHN0cnVjdCBzYWE1MjQ2YV9kZXZpY2UgKnQsIGludCBjb3VudCwgdTggKmJ1ZikKewoJaWYoaTJjX21hc3Rlcl9yZWN2KHQtPmNsaWVudCwgYnVmLCBjb3VudCkhPWNvdW50KQoJCXJldHVybiAtMTsKCXJldHVybiAwOwp9CgovKiBXaGVuIGEgcGFnZSBpcyBmb3VuZCB0aGVuIHRoZSBub3QgRk9VTkQgYml0IGluIG9uZSBvZiB0aGUgc3RhdHVzIHJlZ2lzdGVycwogKiBvZiB0aGUgU0FBNTI2NEEgY2hpcCBpcyBjbGVhcmVkLiBVbmZvcnR1bmF0ZWx5IHRoaXMgYml0IGlzIG5vdCBzZXQKICogYXV0b21hdGljYWxseSB3aGVuIGEgbmV3IHBhZ2UgaXMgcmVxdWVzdGVkLiBJbnN0ZWFkIHRoaXMgZnVuY3Rpb24gbXVzdCBiZQogKiBjYWxsZWQgYWZ0ZXIgYSBwYWdlIGhhcyBiZWVuIHJlcXVlc3RlZC4KICoKICogUmV0dXJuIHZhbHVlOiAwIGlmIHN1Y2Nlc3NmdWwKICovCnN0YXRpYyBpbnQgc2FhNTI0NmFfY2xlYXJfZm91bmRfYml0KHN0cnVjdCBzYWE1MjQ2YV9kZXZpY2UgKnQsCgl1bnNpZ25lZCBjaGFyIGRhdV9ubykKewoJdW5zaWduZWQgY2hhciByb3dfMjVfY29sdW1uXzg7CgoJaWYgKGkyY19zZW5kZGF0YSh0LCBTQUE1MjQ2QV9SRUdJU1RFUl9SOCwKCgkJZGF1X25vIHwKCQlSOF9ET19OT1RfQ0xFQVJfTUVNT1JZLAoKCQlSOV9DVVJTRVJfUk9XXzI1LAoKCQlSMTBfQ1VSU0VSX0NPTFVNTl84LAoKCQlDT01NQU5EX0VORCkgfHwKCQlpMmNfZ2V0ZGF0YSh0LCAxLCAmcm93XzI1X2NvbHVtbl84KSkKCXsKCQlyZXR1cm4gLUVJTzsKCX0KCXJvd18yNV9jb2x1bW5fOCB8PSBST1cyNV9DT0xVTU44X1BBR0VfTk9UX0ZPVU5EOwoJaWYgKGkyY19zZW5kZGF0YSh0LCBTQUE1MjQ2QV9SRUdJU1RFUl9SOCwKCgkJZGF1X25vIHwKCQlSOF9ET19OT1RfQ0xFQVJfTUVNT1JZLAoKCQlSOV9DVVJTRVJfUk9XXzI1LAoKCQlSMTBfQ1VSU0VSX0NPTFVNTl84LAoKCQlyb3dfMjVfY29sdW1uXzgsCgoJCUNPTU1BTkRfRU5EKSkKCXsKCQlyZXR1cm4gLUVJTzsKCX0KCglyZXR1cm4gMDsKfQoKLyogUmVxdWVzdHMgb25lIHZpZGVvdGV4dCBwYWdlIGFzIGRlc2NyaWJlZCBpbiByZXEuIFRoZSBmaWVsZHMgb2YgcmVxIGFyZQogKiBjaGVja2VkIGFuZCBhbiBlcnJvciBpcyByZXR1cm5lZCBpZiBzb21ldGhpbmcgaXMgaW52YWxpZC4KICoKICogUmV0dXJuIHZhbHVlOiAwIGlmIHN1Y2Nlc3NmdWwKICovCnN0YXRpYyBpbnQgc2FhNTI0NmFfcmVxdWVzdF9wYWdlKHN0cnVjdCBzYWE1MjQ2YV9kZXZpY2UgKnQsCiAgICB2dHhfcGFnZXJlcV90ICpyZXEpCnsKCWlmIChyZXEtPnBhZ2VtYXNrIDwgMCB8fCByZXEtPnBhZ2VtYXNrID49IFBHTUFTS19NQVgpCgkJcmV0dXJuIC1FSU5WQUw7CglpZiAocmVxLT5wYWdlbWFzayAmIFBHTUFTS19QQUdFKQoJCWlmIChyZXEtPnBhZ2UgPCAwIHx8IHJlcS0+cGFnZSA+IFBBR0VfTUFYKQoJCQlyZXR1cm4gLUVJTlZBTDsKCWlmIChyZXEtPnBhZ2VtYXNrICYgUEdNQVNLX0hPVVIpCgkJaWYgKHJlcS0+aG91ciA8IDAgfHwgcmVxLT5ob3VyID4gSE9VUl9NQVgpCgkJCXJldHVybiAtRUlOVkFMOwoJaWYgKHJlcS0+cGFnZW1hc2sgJiBQR01BU0tfTUlOVVRFKQoJCWlmIChyZXEtPm1pbnV0ZSA8IDAgfHwgcmVxLT5taW51dGUgPiBNSU5VVEVfTUFYKQoJCQlyZXR1cm4gLUVJTlZBTDsKCWlmIChyZXEtPnBnYnVmIDwgMCB8fCByZXEtPnBnYnVmID49IE5VTV9EQVVTKQoJCXJldHVybiAtRUlOVkFMOwoKCWlmIChpMmNfc2VuZGRhdGEodCwgU0FBNTI0NkFfUkVHSVNURVJfUjIsCgoJCVIyX0lOX1IzX1NFTEVDVF9QQUdFX0hVTkRSRURTIHwKCQlyZXEtPnBnYnVmIDw8IDQgfAoJCVIyX0JBTktfMCB8CgkJUjJfSEFNTUlOR19DSEVDS19PRkYsCgoJCUhVTkRSRURTX09GX1BBR0UocmVxLT5wYWdlKSB8CgkJUjNfSE9MRF9QQUdFIHwKCQkocmVxLT5wYWdlbWFzayAmIFBHX0hVTkQgPwoJCQlSM19QQUdFX0hVTkRSRURTX0RPX0NBUkUgOgoJCQlSM19QQUdFX0hVTkRSRURTX0RPX05PVF9DQVJFKSwKCgkJVEVOU19PRl9QQUdFKHJlcS0+cGFnZSkgfAoJCShyZXEtPnBhZ2VtYXNrICYgUEdfVEVOID8KCQkJUjNfUEFHRV9URU5TX0RPX0NBUkUgOgoJCQlSM19QQUdFX1RFTlNfRE9fTk9UX0NBUkUpLAoKCQlVTklUU19PRl9QQUdFKHJlcS0+cGFnZSkgfAoJCShyZXEtPnBhZ2VtYXNrICYgUEdfVU5JVCA/CgkJCVIzX1BBR0VfVU5JVFNfRE9fQ0FSRSA6CgkJCVIzX1BBR0VfVU5JVFNfRE9fTk9UX0NBUkUpLAoKCQlURU5TX09GX0hPVVIocmVxLT5ob3VyKSB8CgkJKHJlcS0+cGFnZW1hc2sgJiBIUl9URU4gPwoJCQlSM19IT1VSU19URU5TX0RPX0NBUkUgOgoJCQlSM19IT1VSU19URU5TX0RPX05PVF9DQVJFKSwKCgkJVU5JVFNfT0ZfSE9VUihyZXEtPmhvdXIpIHwKCQkocmVxLT5wYWdlbWFzayAmIEhSX1VOSVQgPwoJCQlSM19IT1VSU19VTklUU19ET19DQVJFIDoKCQkJUjNfSE9VUlNfVU5JVFNfRE9fTk9UX0NBUkUpLAoKCQlURU5TX09GX01JTlVURShyZXEtPm1pbnV0ZSkgfAoJCShyZXEtPnBhZ2VtYXNrICYgTUlOX1RFTiA/CgkJCVIzX01JTlVURVNfVEVOU19ET19DQVJFIDoKCQkJUjNfTUlOVVRFU19URU5TX0RPX05PVF9DQVJFKSwKCgkJVU5JVFNfT0ZfTUlOVVRFKHJlcS0+bWludXRlKSB8CgkJKHJlcS0+cGFnZW1hc2sgJiBNSU5fVU5JVCA/CgkJCVIzX01JTlVURVNfVU5JVFNfRE9fQ0FSRSA6CgkJCVIzX01JTlVURVNfVU5JVFNfRE9fTk9UX0NBUkUpLAoKCQlDT01NQU5EX0VORCkgfHwgaTJjX3NlbmRkYXRhKHQsIFNBQTUyNDZBX1JFR0lTVEVSX1IyLAoKCQlSMl9JTl9SM19TRUxFQ1RfUEFHRV9IVU5EUkVEUyB8CgkJcmVxLT5wZ2J1ZiA8PCA0IHwKCQlSMl9CQU5LXzAgfAoJCVIyX0hBTU1JTkdfQ0hFQ0tfT0ZGLAoKCQlIVU5EUkVEU19PRl9QQUdFKHJlcS0+cGFnZSkgfAoJCVIzX1VQREFURV9QQUdFIHwKCQkocmVxLT5wYWdlbWFzayAmIFBHX0hVTkQgPwoJCQlSM19QQUdFX0hVTkRSRURTX0RPX0NBUkUgOgoJCQlSM19QQUdFX0hVTkRSRURTX0RPX05PVF9DQVJFKSwKCgkJQ09NTUFORF9FTkQpKQoJewoJCXJldHVybiAtRUlPOwoJfQoKCXQtPmlzX3NlYXJjaGluZ1tyZXEtPnBnYnVmXSA9IFRSVUU7CglyZXR1cm4gMDsKfQoKLyogVGhpcyByb3V0aW5lIGRlY29kZXMgdGhlIHBhZ2UgbnVtYmVyIGZyb20gdGhlIGluZm9iaXRzIGNvbnRhaW5lZCBpbiBsaW5lIDI1LgogKgogKiBQYXJhbWV0ZXJzOgogKiBpbmZvYml0czogbXVzdCBiZSBiaXRzIDAgdG8gOSBvZiBjb2x1bW4gMjUKICoKICogUmV0dXJuIHZhbHVlOiBwYWdlIG51bWJlciBjb2RlZCBpbiBoZXhhZGVjaW1hbCwgaS4gZS4gcGFnZSAxMjMgaXMgY29kZWQgMHgxMjMKICovCnN0YXRpYyBpbmxpbmUgaW50IHNhYTUyNDZhX2V4dHJhY3RfcGFnZW51bV9mcm9tX2luZm9iaXRzKAogICAgdW5zaWduZWQgY2hhciBpbmZvYml0c1sxMF0pCnsKCWludCBwYWdlX2h1bmRyZWRzLCBwYWdlX3RlbnMsIHBhZ2VfdW5pdHM7CgoJcGFnZV91bml0cyAgICA9IGluZm9iaXRzWzBdICYgUk9XMjVfQ09MVU1OMF9QQUdFX1VOSVRTOwoJcGFnZV90ZW5zICAgICA9IGluZm9iaXRzWzFdICYgUk9XMjVfQ09MVU1OMV9QQUdFX1RFTlM7CglwYWdlX2h1bmRyZWRzID0gaW5mb2JpdHNbOF0gJiBST1cyNV9DT0xVTU44X1BBR0VfSFVORFJFRFM7CgoJLyogcGFnZSAweC4uIG1lYW5zIHBhZ2UgOC4uICovCglpZiAocGFnZV9odW5kcmVkcyA9PSAwKQoJCXBhZ2VfaHVuZHJlZHMgPSA4OwoKCXJldHVybigocGFnZV9odW5kcmVkcyA8PCA4KSB8IChwYWdlX3RlbnMgPDwgNCkgfCBwYWdlX3VuaXRzKTsKfQoKLyogRGVjb2RlcyB0aGUgaG91ciBmcm9tIHRoZSBpbmZvYml0cyBjb250YWluZWQgaW4gbGluZSAyNS4KICoKICogUGFyYW1ldGVyczoKICogaW5mb2JpdHM6IG11c3QgYmUgYml0cyAwIHRvIDkgb2YgY29sdW1uIDI1CiAqCiAqIFJldHVybjogaG91ciBjb2RlZCBpbiBoZXhhZGVjaW1hbCwgaS4gZS4gMTJoIGlzIGNvZGVkIDB4MTIKICovCnN0YXRpYyBpbmxpbmUgaW50IHNhYTUyNDZhX2V4dHJhY3RfaG91cl9mcm9tX2luZm9iaXRzKAogICAgdW5zaWduZWQgY2hhciBpbmZvYml0c1sxMF0pCnsKCWludCBob3VyX3RlbnMsIGhvdXJfdW5pdHM7CgoJaG91cl91bml0cyA9IGluZm9iaXRzWzRdICYgUk9XMjVfQ09MVU1ONF9IT1VSX1VOSVRTOwoJaG91cl90ZW5zICA9IGluZm9iaXRzWzVdICYgUk9XMjVfQ09MVU1ONV9IT1VSX1RFTlM7CgoJcmV0dXJuKChob3VyX3RlbnMgPDwgNCkgfCBob3VyX3VuaXRzKTsKfQoKLyogRGVjb2RlcyB0aGUgbWludXRlcyBmcm9tIHRoZSBpbmZvYml0cyBjb250YWluZWQgaW4gbGluZSAyNS4KICoKICogUGFyYW1ldGVyczoKICogaW5mb2JpdHM6IG11c3QgYmUgYml0cyAwIHRvIDkgb2YgY29sdW1uIDI1CiAqCiAqIFJldHVybjogbWludXRlcyBjb2RlZCBpbiBoZXhhZGVjaW1hbCwgaS4gZS4gMTBtaW4gaXMgY29kZWQgMHgxMAogKi8Kc3RhdGljIGlubGluZSBpbnQgc2FhNTI0NmFfZXh0cmFjdF9taW51dGVzX2Zyb21faW5mb2JpdHMoCiAgICB1bnNpZ25lZCBjaGFyIGluZm9iaXRzWzEwXSkKewoJaW50IG1pbnV0ZXNfdGVucywgbWludXRlc191bml0czsKCgltaW51dGVzX3VuaXRzID0gaW5mb2JpdHNbMl0gJiBST1cyNV9DT0xVTU4yX01JTlVURVNfVU5JVFM7CgltaW51dGVzX3RlbnMgID0gaW5mb2JpdHNbM10gJiBST1cyNV9DT0xVTU4zX01JTlVURVNfVEVOUzsKCglyZXR1cm4oKG1pbnV0ZXNfdGVucyA8PCA0KSB8IG1pbnV0ZXNfdW5pdHMpOwp9CgovKiBSZWFkcyB0aGUgc3RhdHVzIGJpdHMgY29udGFpbmVkIGluIHRoZSBmaXJzdCAxMCBjb2x1bW5zIG9mIHRoZSBmaXJzdCBsaW5lCiAqIGFuZCBleHRyYWN0cyB0aGUgaW5mb3JtYXRpb24gaW50byBpbmZvLgogKgogKiBSZXR1cm4gdmFsdWU6IDAgaWYgc3VjY2Vzc2Z1bAogKi8Kc3RhdGljIGlubGluZSBpbnQgc2FhNTI0NmFfZ2V0X3N0YXR1cyhzdHJ1Y3Qgc2FhNTI0NmFfZGV2aWNlICp0LAogICAgdnR4X3BhZ2VpbmZvX3QgKmluZm8sIHVuc2lnbmVkIGNoYXIgZGF1X25vKQp7Cgl1bnNpZ25lZCBjaGFyIGluZm9iaXRzWzEwXTsKCWludCBjb2x1bW47CgoJaWYgKGRhdV9ubyA+PSBOVU1fREFVUykKCQlyZXR1cm4gLUVJTlZBTDsKCglpZiAoaTJjX3NlbmRkYXRhKHQsIFNBQTUyNDZBX1JFR0lTVEVSX1I4LAoKCQlkYXVfbm8gfAoJCVI4X0RPX05PVF9DTEVBUl9NRU1PUlksCgoJCVI5X0NVUlNFUl9ST1dfMjUsCgoJCVIxMF9DVVJTRVJfQ09MVU1OXzAsCgoJCUNPTU1BTkRfRU5EKSB8fAoJCWkyY19nZXRkYXRhKHQsIDEwLCBpbmZvYml0cykpCgl7CgkJcmV0dXJuIC1FSU87Cgl9CgoJaW5mby0+cGFnZW51bSA9IHNhYTUyNDZhX2V4dHJhY3RfcGFnZW51bV9mcm9tX2luZm9iaXRzKGluZm9iaXRzKTsKCWluZm8tPmhvdXIgICAgPSBzYWE1MjQ2YV9leHRyYWN0X2hvdXJfZnJvbV9pbmZvYml0cyhpbmZvYml0cyk7CglpbmZvLT5taW51dGUgID0gc2FhNTI0NmFfZXh0cmFjdF9taW51dGVzX2Zyb21faW5mb2JpdHMoaW5mb2JpdHMpOwoJaW5mby0+Y2hhcnNldCA9ICgoaW5mb2JpdHNbN10gJiBST1cyNV9DT0xVTU43X0NIQVJBQ1RFUl9TRVQpID4+IDEpOwoJaW5mby0+ZGVsZXRlID0gISEoaW5mb2JpdHNbM10gJiBST1cyNV9DT0xVTU4zX0RFTEVURV9QQUdFKTsKCWluZm8tPmhlYWRsaW5lID0gISEoaW5mb2JpdHNbNV0gJiBST1cyNV9DT0xVTU41X0lOU0VSVF9IRUFETElORSk7CglpbmZvLT5zdWJ0aXRsZSA9ICEhKGluZm9iaXRzWzVdICYgUk9XMjVfQ09MVU1ONV9JTlNFUlRfU1VCVElUTEUpOwoJaW5mby0+c3VwcF9oZWFkZXIgPSAhIShpbmZvYml0c1s2XSAmIFJPVzI1X0NPTFVNTjZfU1VQUFJFU1NfSEVBREVSKTsKCWluZm8tPnVwZGF0ZSA9ICEhKGluZm9iaXRzWzZdICYgUk9XMjVfQ09MVU1ONl9VUERBVEVfUEFHRSk7CglpbmZvLT5pbnRlcl9zZXEgPSAhIShpbmZvYml0c1s2XSAmIFJPVzI1X0NPTFVNTjZfSU5URVJSVVBURURfU0VRVUVOQ0UpOwoJaW5mby0+ZGlzX2Rpc3AgPSAhIShpbmZvYml0c1s2XSAmIFJPVzI1X0NPTFVNTjZfU1VQUFJFU1NfRElTUExBWSk7CglpbmZvLT5zZXJpYWwgPSAhIShpbmZvYml0c1s3XSAmIFJPVzI1X0NPTFVNTjdfU0VSSUFMX01PREUpOwoJaW5mby0+bm90Zm91bmQgPSAhIShpbmZvYml0c1s4XSAmIFJPVzI1X0NPTFVNTjhfUEFHRV9OT1RfRk9VTkQpOwoJaW5mby0+cGJsZiA9ICEhKGluZm9iaXRzWzldICYgUk9XMjVfQ09MVU1OOV9QQUdFX0JFSU5HX0xPT0tFRF9GT1IpOwoJaW5mby0+aGFtbWluZyA9IDA7Cglmb3IgKGNvbHVtbiA9IDA7IGNvbHVtbiA8PSA3OyBjb2x1bW4rKykgewoJCWlmIChpbmZvYml0c1tjb2x1bW5dICYgUk9XMjVfQ09MVU1OMF9UT183X0hBTU1JTkdfRVJST1IpIHsKCQkJaW5mby0+aGFtbWluZyA9IDE7CgkJCWJyZWFrOwoJCX0KCX0KCWlmICghaW5mby0+aGFtbWluZyAmJiAhaW5mby0+bm90Zm91bmQpCgkJdC0+aXNfc2VhcmNoaW5nW2RhdV9ub10gPSBGQUxTRTsKCXJldHVybiAwOwp9CgovKiBSZWFkcyAxIHZpZGVvdGV4dCBwYWdlIGJ1ZmZlciBvZiB0aGUgU0FBNTI0NkEuCiAqCiAqIHJlcSBpcyB1c2VkIGJvdGggYXMgaW5wdXQgYW5kIGFzIG91dHB1dC4gSXQgY29udGFpbnMgaW5mb3JtYXRpb24gd2hpY2ggcGFydAogKiBtdXN0IGJlIHJlYWQuIFRoZSB2aWRlb3RleHQgcGFnZSBpcyBjb3BpZWQgaW50byByZXEtPmJ1ZmZlci4KICoKICogUmV0dXJuIHZhbHVlOiAwIGlmIHN1Y2Nlc3NmdWwKICovCnN0YXRpYyBpbmxpbmUgaW50IHNhYTUyNDZhX2dldF9wYWdlKHN0cnVjdCBzYWE1MjQ2YV9kZXZpY2UgKnQsCgl2dHhfcGFnZXJlcV90ICpyZXEpCnsKCWludCBzdGFydCwgZW5kLCBzaXplOwoJY2hhciAqYnVmOwoJaW50IGVycjsKCglpZiAocmVxLT5wZ2J1ZiA8IDAgfHwgcmVxLT5wZ2J1ZiA+PSBOVU1fREFVUyB8fAoJICAgIHJlcS0+c3RhcnQgPCAwIHx8IHJlcS0+c3RhcnQgPiByZXEtPmVuZCB8fCByZXEtPmVuZCA+PSBWVFhfUEFHRVNJWkUpCgkJcmV0dXJuIC1FSU5WQUw7CgoJYnVmID0ga21hbGxvYyhWVFhfUEFHRVNJWkUsIEdGUF9LRVJORUwpOwoJaWYgKCFidWYpCgkJcmV0dXJuIC1FTk9NRU07CgoJLyogUmVhZCAibm9ybWFsIiBwYXJ0IG9mIHBhZ2UgKi8KCWVyciA9IC1FSU87CgoJZW5kID0gbWluKHJlcS0+ZW5kLCBWVFhfUEFHRVNJWkUgLSAxKTsKCWlmIChpMmNfc2VuZGRhdGEodCwgU0FBNTI0NkFfUkVHSVNURVJfUjgsCgkJCXJlcS0+cGdidWYgfCBSOF9ET19OT1RfQ0xFQVJfTUVNT1JZLAoJCQlST1cocmVxLT5zdGFydCksIENPTFVNTihyZXEtPnN0YXJ0KSwgQ09NTUFORF9FTkQpKQoJCWdvdG8gb3V0OwoJaWYgKGkyY19nZXRkYXRhKHQsIGVuZCAtIHJlcS0+c3RhcnQgKyAxLCBidWYpKQoJCWdvdG8gb3V0OwoJZXJyID0gLUVGQVVMVDsKCWlmIChjb3B5X3RvX3VzZXIocmVxLT5idWZmZXIsIGJ1ZiwgZW5kIC0gcmVxLT5zdGFydCArIDEpKQoJCWdvdG8gb3V0OwoKCS8qIEFsd2F5cyBnZXQgdGhlIHRpbWUgZnJvbSBidWZmZXIgNCwgc2luY2UgdGhpcyBzdHVwaWQgU0FBNTI0NkEgb25seQoJICogdXBkYXRlcyB0aGUgY3VycmVudGx5IGRpc3BsYXllZCBidWZmZXIuLi4KCSAqLwoJaWYgKFJFUV9DT05UQUlOU19USU1FKHJlcSkpIHsKCQlzdGFydCA9IG1heChyZXEtPnN0YXJ0LCBQT1NfVElNRV9TVEFSVCk7CgkJZW5kICAgPSBtaW4ocmVxLT5lbmQsICAgUE9TX1RJTUVfRU5EKTsKCQlzaXplID0gZW5kIC0gc3RhcnQgKyAxOwoJCWVyciA9IC1FSU5WQUw7CgkJaWYgKHNpemUgPCAwKQoJCQlnb3RvIG91dDsKCQllcnIgPSAtRUlPOwoJCWlmIChpMmNfc2VuZGRhdGEodCwgU0FBNTI0NkFfUkVHSVNURVJfUjgsCgkJCQlSOF9BQ1RJVkVfQ0hBUFRFUl80IHwgUjhfRE9fTk9UX0NMRUFSX01FTU9SWSwKCQkJCVI5X0NVUlNFUl9ST1dfMCwgc3RhcnQsIENPTU1BTkRfRU5EKSkKCQkJZ290byBvdXQ7CgkJaWYgKGkyY19nZXRkYXRhKHQsIHNpemUsIGJ1ZikpCgkJCWdvdG8gb3V0OwoJCWVyciA9IC1FRkFVTFQ7CgkJaWYgKGNvcHlfdG9fdXNlcihyZXEtPmJ1ZmZlciArIHN0YXJ0IC0gcmVxLT5zdGFydCwgYnVmLCBzaXplKSkKCQkJZ290byBvdXQ7Cgl9CgkvKiBJbnNlcnQgdGhlIGhlYWRlciBmcm9tIGJ1ZmZlciA0IG9ubHksIGlmIGFjcXVpc2l0aW9uIGNpcmN1aXQgaXMgc3RpbGwgc2VhcmNoaW5nIGZvciBhIHBhZ2UgKi8KCWlmIChSRVFfQ09OVEFJTlNfSEVBREVSKHJlcSkgJiYgdC0+aXNfc2VhcmNoaW5nW3JlcS0+cGdidWZdKSB7CgkJc3RhcnQgPSBtYXgocmVxLT5zdGFydCwgUE9TX0hFQURFUl9TVEFSVCk7CgkJZW5kICAgPSBtaW4ocmVxLT5lbmQsICAgUE9TX0hFQURFUl9FTkQpOwoJCXNpemUgPSBlbmQgLSBzdGFydCArIDE7CgkJZXJyID0gLUVJTlZBTDsKCQlpZiAoc2l6ZSA8IDApCgkJCWdvdG8gb3V0OwoJCWVyciA9IC1FSU87CgkJaWYgKGkyY19zZW5kZGF0YSh0LCBTQUE1MjQ2QV9SRUdJU1RFUl9SOCwKCQkJCVI4X0FDVElWRV9DSEFQVEVSXzQgfCBSOF9ET19OT1RfQ0xFQVJfTUVNT1JZLAoJCQkJUjlfQ1VSU0VSX1JPV18wLCBzdGFydCwgQ09NTUFORF9FTkQpKQoJCQlnb3RvIG91dDsKCQlpZiAoaTJjX2dldGRhdGEodCwgZW5kIC0gc3RhcnQgKyAxLCBidWYpKQoJCQlnb3RvIG91dDsKCQllcnIgPSAtRUZBVUxUOwoJCWlmIChjb3B5X3RvX3VzZXIocmVxLT5idWZmZXIgKyBzdGFydCAtIHJlcS0+c3RhcnQsIGJ1Ziwgc2l6ZSkpCgkJCWdvdG8gb3V0OwoJfQoJZXJyID0gMDsKb3V0OgoJa2ZyZWUoYnVmKTsKCXJldHVybiBlcnI7Cn0KCi8qIFN0b3BzIHRoZSBhY3F1aXNpdGlvbiBjaXJjdWl0IGdpdmVuIGluIGRhdV9uby4gVGhlIHBhZ2UgYnVmZmVyIGFzc29jaWF0ZWQKICogd2l0aCB0aGlzIGFjcXVpc2l0aW9uIGNpcmN1aXQgd2lsbCBubyBtb3JlIGJlIHVwZGF0ZWQuIFRoZSBvdGhlciBkYXVzIGFyZQogKiBub3QgYWZmZWN0ZWQuCiAqCiAqIFJldHVybiB2YWx1ZTogMCBpZiBzdWNjZXNzZnVsCiAqLwpzdGF0aWMgaW5saW5lIGludCBzYWE1MjQ2YV9zdG9wX2RhdShzdHJ1Y3Qgc2FhNTI0NmFfZGV2aWNlICp0LAogICAgdW5zaWduZWQgY2hhciBkYXVfbm8pCnsKCWlmIChkYXVfbm8gPj0gTlVNX0RBVVMpCgkJcmV0dXJuIC1FSU5WQUw7CglpZiAoaTJjX3NlbmRkYXRhKHQsIFNBQTUyNDZBX1JFR0lTVEVSX1IyLAoKCQlSMl9JTl9SM19TRUxFQ1RfUEFHRV9IVU5EUkVEUyB8CgkJZGF1X25vIDw8IDQgfAoJCVIyX0JBTktfMCB8CgkJUjJfSEFNTUlOR19DSEVDS19PRkYsCgoJCVIzX1BBR0VfSFVORFJFRFNfMCB8CgkJUjNfSE9MRF9QQUdFIHwKCQlSM19QQUdFX0hVTkRSRURTX0RPX05PVF9DQVJFLAoKCQlDT01NQU5EX0VORCkpCgl7CgkJcmV0dXJuIC1FSU87Cgl9Cgl0LT5pc19zZWFyY2hpbmdbZGF1X25vXSA9IEZBTFNFOwoJcmV0dXJuIDA7Cn0KCi8qICBIYW5kbGVzIGlvY3RscyBkZWZpbmVkIGluIHZpZGVvdGV4dC5oCiAqCiAqICBSZXR1cm5zIDAgaWYgc3VjY2Vzc2Z1bAogKi8Kc3RhdGljIGludCBkb19zYWE1MjQ2YV9pb2N0bChzdHJ1Y3QgaW5vZGUgKmlub2RlLCBzdHJ1Y3QgZmlsZSAqZmlsZSwKCQkJICAgIHVuc2lnbmVkIGludCBjbWQsIHZvaWQgKmFyZykKewoJc3RydWN0IHZpZGVvX2RldmljZSAqdmQgPSB2aWRlb19kZXZkYXRhKGZpbGUpOwoJc3RydWN0IHNhYTUyNDZhX2RldmljZSAqdD12ZC0+cHJpdjsKCXN3aXRjaChjbWQpCgl7CgkJY2FzZSBWVFhJT0NHRVRJTkZPOgoJCXsKCQkJdnR4X2luZm9fdCAqaW5mbyA9IGFyZzsKCgkJCWluZm8tPnZlcnNpb25fbWFqb3IgPSBNQUpPUl9WRVJTSU9OOwoJCQlpbmZvLT52ZXJzaW9uX21pbm9yID0gTUlOT1JfVkVSU0lPTjsKCQkJaW5mby0+bnVtcGFnZXMgPSBOVU1fREFVUzsKCQkJcmV0dXJuIDA7CgkJfQoKCQljYXNlIFZUWElPQ0NMUlBBR0U6CgkJewoJCQl2dHhfcGFnZXJlcV90ICpyZXEgPSBhcmc7CgoJCQlpZiAocmVxLT5wZ2J1ZiA8IDAgfHwgcmVxLT5wZ2J1ZiA+PSBOVU1fREFVUykKCQkJCXJldHVybiAtRUlOVkFMOwoJCQltZW1zZXQodC0+cGdidWZbcmVxLT5wZ2J1Zl0sICcgJywgc2l6ZW9mKHQtPnBnYnVmWzBdKSk7CgkJCXJldHVybiAwOwoJCX0KCgkJY2FzZSBWVFhJT0NDTFJGT1VORDoKCQl7CgkJCXZ0eF9wYWdlcmVxX3QgKnJlcSA9IGFyZzsKCgkJCWlmIChyZXEtPnBnYnVmIDwgMCB8fCByZXEtPnBnYnVmID49IE5VTV9EQVVTKQoJCQkJcmV0dXJuIC1FSU5WQUw7CgkJCXJldHVybihzYWE1MjQ2YV9jbGVhcl9mb3VuZF9iaXQodCwgcmVxLT5wZ2J1ZikpOwoJCX0KCgkJY2FzZSBWVFhJT0NQQUdFUkVROgoJCXsKCQkJdnR4X3BhZ2VyZXFfdCAqcmVxID0gYXJnOwoKCQkJcmV0dXJuKHNhYTUyNDZhX3JlcXVlc3RfcGFnZSh0LCByZXEpKTsKCQl9CgoJCWNhc2UgVlRYSU9DR0VUU1RBVDoKCQl7CgkJCXZ0eF9wYWdlcmVxX3QgKnJlcSA9IGFyZzsKCQkJdnR4X3BhZ2VpbmZvX3QgaW5mbzsKCQkJaW50IHJ2YWw7CgoJCQlpZiAoKHJ2YWwgPSBzYWE1MjQ2YV9nZXRfc3RhdHVzKHQsICZpbmZvLCByZXEtPnBnYnVmKSkpCgkJCQlyZXR1cm4gcnZhbDsKCQkJaWYoY29weV90b191c2VyKHJlcS0+YnVmZmVyLCAmaW5mbywKCQkJCXNpemVvZih2dHhfcGFnZWluZm9fdCkpKQoJCQkJcmV0dXJuIC1FRkFVTFQ7CgkJCXJldHVybiAwOwoJCX0KCgkJY2FzZSBWVFhJT0NHRVRQQUdFOgoJCXsKCQkJdnR4X3BhZ2VyZXFfdCAqcmVxID0gYXJnOwoKCQkJcmV0dXJuKHNhYTUyNDZhX2dldF9wYWdlKHQsIHJlcSkpOwoJCX0KCgkJY2FzZSBWVFhJT0NTVE9QREFVOgoJCXsKCQkJdnR4X3BhZ2VyZXFfdCAqcmVxID0gYXJnOwoKCQkJcmV0dXJuKHNhYTUyNDZhX3N0b3BfZGF1KHQsIHJlcS0+cGdidWYpKTsKCQl9CgoJCWNhc2UgVlRYSU9DUFVUUEFHRToKCQljYXNlIFZUWElPQ1NFVERJU1A6CgkJY2FzZSBWVFhJT0NQVVRTVEFUOgoJCQlyZXR1cm4gMDsKCgkJY2FzZSBWVFhJT0NDTFJDQUNIRToKCQl7CgkJCXJldHVybiAwOwoJCX0KCgkJY2FzZSBWVFhJT0NTRVRWSVJUOgoJCXsKCQkJLyogSSBkbyBub3Qga25vdyB3aGF0ICJ2aXJ0dWFsIG1vZGUiIG1lYW5zICovCgkJCXJldHVybiAwOwoJCX0KCX0KCXJldHVybiAtRUlOVkFMOwp9CgovKgogKiBUcmFuc2xhdGVzIG9sZCB2dHggSU9DVExzIHRvIG5ldyBvbmVzCiAqCiAqIFRoaXMga2VlcHMgbmV3IGtlcm5lbCB2ZXJzaW9ucyBjb21wYXRpYmxlIHdpdGggb2xkIHVzZXJzcGFjZSBwcm9ncmFtcy4KICovCnN0YXRpYyBpbmxpbmUgdW5zaWduZWQgaW50IHZ0eF9maXhfY29tbWFuZCh1bnNpZ25lZCBpbnQgY21kKQp7Cglzd2l0Y2ggKGNtZCkgewoJY2FzZSBWVFhJT0NHRVRJTkZPX09MRDoKCQljbWQgPSBWVFhJT0NHRVRJTkZPOwoJCWJyZWFrOwoJY2FzZSBWVFhJT0NDTFJQQUdFX09MRDoKCQljbWQgPSBWVFhJT0NDTFJQQUdFOwoJCWJyZWFrOwoJY2FzZSBWVFhJT0NDTFJGT1VORF9PTEQ6CgkJY21kID0gVlRYSU9DQ0xSRk9VTkQ7CgkJYnJlYWs7CgljYXNlIFZUWElPQ1BBR0VSRVFfT0xEOgoJCWNtZCA9IFZUWElPQ1BBR0VSRVE7CgkJYnJlYWs7CgljYXNlIFZUWElPQ0dFVFNUQVRfT0xEOgoJCWNtZCA9IFZUWElPQ0dFVFNUQVQ7CgkJYnJlYWs7CgljYXNlIFZUWElPQ0dFVFBBR0VfT0xEOgoJCWNtZCA9IFZUWElPQ0dFVFBBR0U7CgkJYnJlYWs7CgljYXNlIFZUWElPQ1NUT1BEQVVfT0xEOgoJCWNtZCA9IFZUWElPQ1NUT1BEQVU7CgkJYnJlYWs7CgljYXNlIFZUWElPQ1BVVFBBR0VfT0xEOgoJCWNtZCA9IFZUWElPQ1BVVFBBR0U7CgkJYnJlYWs7CgljYXNlIFZUWElPQ1NFVERJU1BfT0xEOgoJCWNtZCA9IFZUWElPQ1NFVERJU1A7CgkJYnJlYWs7CgljYXNlIFZUWElPQ1BVVFNUQVRfT0xEOgoJCWNtZCA9IFZUWElPQ1BVVFNUQVQ7CgkJYnJlYWs7CgljYXNlIFZUWElPQ0NMUkNBQ0hFX09MRDoKCQljbWQgPSBWVFhJT0NDTFJDQUNIRTsKCQlicmVhazsKCWNhc2UgVlRYSU9DU0VUVklSVF9PTEQ6CgkJY21kID0gVlRYSU9DU0VUVklSVDsKCQlicmVhazsKCX0KCXJldHVybiBjbWQ7Cn0KCi8qCiAqCUhhbmRsZSB0aGUgbG9ja2luZwogKi8Kc3RhdGljIGludCBzYWE1MjQ2YV9pb2N0bChzdHJ1Y3QgaW5vZGUgKmlub2RlLCBzdHJ1Y3QgZmlsZSAqZmlsZSwKCQkJIHVuc2lnbmVkIGludCBjbWQsIHVuc2lnbmVkIGxvbmcgYXJnKQp7CglzdHJ1Y3QgdmlkZW9fZGV2aWNlICp2ZCA9IHZpZGVvX2RldmRhdGEoZmlsZSk7CglzdHJ1Y3Qgc2FhNTI0NmFfZGV2aWNlICp0ID0gdmQtPnByaXY7CglpbnQgZXJyOwoKCWNtZCA9IHZ0eF9maXhfY29tbWFuZChjbWQpOwoJbXV0ZXhfbG9jaygmdC0+bG9jayk7CgllcnIgPSB2aWRlb191c2VyY29weShpbm9kZSwgZmlsZSwgY21kLCBhcmcsIGRvX3NhYTUyNDZhX2lvY3RsKTsKCW11dGV4X3VubG9jaygmdC0+bG9jayk7CglyZXR1cm4gZXJyOwp9CgpzdGF0aWMgaW50IHNhYTUyNDZhX29wZW4oc3RydWN0IGlub2RlICppbm9kZSwgc3RydWN0IGZpbGUgKmZpbGUpCnsKCXN0cnVjdCB2aWRlb19kZXZpY2UgKnZkID0gdmlkZW9fZGV2ZGF0YShmaWxlKTsKCXN0cnVjdCBzYWE1MjQ2YV9kZXZpY2UgKnQgPSB2ZC0+cHJpdjsKCWludCBlcnI7CgoJZXJyID0gdmlkZW9fZXhjbHVzaXZlX29wZW4oaW5vZGUsZmlsZSk7CglpZiAoZXJyIDwgMCkKCQlyZXR1cm4gZXJyOwoKCWlmICh0LT5jbGllbnQ9PU5VTEwpIHsKCQllcnIgPSAtRU5PREVWOwoJCWdvdG8gZmFpbDsKCX0KCglpZiAoaTJjX3NlbmRkYXRhKHQsIFNBQTUyNDZBX1JFR0lTVEVSX1IwLAoKCQlSMF9TRUxFQ1RfUjExIHwKCQlSMF9QTExfVElNRV9DT05TVEFOVF9MT05HIHwKCQlSMF9FTkFCTEVfbk9ERF9FVkVOX09VVFBVVCB8CgkJUjBfRU5BQkxFX0hEUl9QT0xMIHwKCQlSMF9ET19OT1RfRk9SQ0Vfbk9ERF9FVkVOX0xPV19JRl9QSUNUVVJFX0RJU1BMQVlFRCB8CgkJUjBfTk9fRlJFRV9SVU5fUExMIHwKCQlSMF9OT19BVVRPTUFUSUNfRkFTVEVYVF9QUk9NUFQsCgoJCVIxX05PTl9JTlRFUkxBQ0VEXzMxMl8zMTJfTElORVMgfAoJCVIxX0RFVyB8CgkJUjFfRVhURU5ERURfUEFDS0VUX0RJU0FCTEUgfAoJCVIxX0RBVVNfQUxMX09OIHwKCQlSMV84X0JJVFNfTk9fUEFSSVRZIHwKCQlSMV9WQ1NfVE9fU0NTLAoKCQlDT01NQU5EX0VORCkgfHwKCQlpMmNfc2VuZGRhdGEodCwgU0FBNTI0NkFfUkVHSVNURVJfUjQsCgoJCS8qIFdlIGRvIG5vdCBjYXJlIG11Y2ggZm9yIHRoZSBUViBkaXNwbGF5IGJ1dCBuZXZlcnRoZWxlc3Mgd2UKCQkgKiBuZWVkIHRoZSBjdXJyZW50bHkgZGlzcGxheWVkIHBhZ2UgbGF0ZXIgYmVjYXVzZSBvbmx5IG9uIHRoYXQKCQkgKiBwYWdlIHRoZSB0aW1lIGlzIHVwZGF0ZWQuICovCgkJUjRfRElTUExBWV9QQUdFXzQsCgoJCUNPTU1BTkRfRU5EKSkKCXsKCQllcnIgPSAtRUlPOwoJCWdvdG8gZmFpbDsKCX0KCglyZXR1cm4gMDsKCmZhaWw6Cgl2aWRlb19leGNsdXNpdmVfcmVsZWFzZShpbm9kZSxmaWxlKTsKCXJldHVybiBlcnI7Cn0KCnN0YXRpYyBpbnQgc2FhNTI0NmFfcmVsZWFzZShzdHJ1Y3QgaW5vZGUgKmlub2RlLCBzdHJ1Y3QgZmlsZSAqZmlsZSkKewoJc3RydWN0IHZpZGVvX2RldmljZSAqdmQgPSB2aWRlb19kZXZkYXRhKGZpbGUpOwoJc3RydWN0IHNhYTUyNDZhX2RldmljZSAqdCA9IHZkLT5wcml2OwoKCS8qIFN0b3AgYWxsIGFjcXVpc2l0aW9uIGNpcmN1aXRzLiAqLwoJaTJjX3NlbmRkYXRhKHQsIFNBQTUyNDZBX1JFR0lTVEVSX1IxLAoKCQlSMV9JTlRFUkxBQ0VEXzMxMl9BTkRfSEFMRl8zMTJfQU5EX0hBTEZfTElORVMgfAoJCVIxX0RFVyB8CgkJUjFfRVhURU5ERURfUEFDS0VUX0RJU0FCTEUgfAoJCVIxX0RBVVNfQUxMX09GRiB8CgkJUjFfOF9CSVRTX05PX1BBUklUWSB8CgkJUjFfVkNTX1RPX1NDUywKCgkJQ09NTUFORF9FTkQpOwoJdmlkZW9fZXhjbHVzaXZlX3JlbGVhc2UoaW5vZGUsZmlsZSk7CglyZXR1cm4gMDsKfQoKc3RhdGljIGludCBfX2luaXQgaW5pdF9zYWFfNTI0NmEgKHZvaWQpCnsKCXByaW50ayhLRVJOX0lORk8KCQkiU0FBNTI0NkEgKG9yIGNvbXBhdGlibGUpIFRlbGV0ZXh0IGRlY29kZXIgZHJpdmVyIHZlcnNpb24gJWQuJWRcbiIsCgkJTUFKT1JfVkVSU0lPTiwgTUlOT1JfVkVSU0lPTik7CglyZXR1cm4gaTJjX2FkZF9kcml2ZXIoJmkyY19kcml2ZXJfdmlkZW90ZXh0KTsKfQoKc3RhdGljIHZvaWQgX19leGl0IGNsZWFudXBfc2FhXzUyNDZhICh2b2lkKQp7CglpMmNfZGVsX2RyaXZlcigmaTJjX2RyaXZlcl92aWRlb3RleHQpOwp9Cgptb2R1bGVfaW5pdChpbml0X3NhYV81MjQ2YSk7Cm1vZHVsZV9leGl0KGNsZWFudXBfc2FhXzUyNDZhKTsKCnN0YXRpYyBzdHJ1Y3QgZmlsZV9vcGVyYXRpb25zIHNhYV9mb3BzID0gewoJLm93bmVyCSA9IFRISVNfTU9EVUxFLAoJLm9wZW4JID0gc2FhNTI0NmFfb3BlbiwKCS5yZWxlYXNlID0gc2FhNTI0NmFfcmVsZWFzZSwKCS5pb2N0bAkgPSBzYWE1MjQ2YV9pb2N0bCwKCS5sbHNlZWsJID0gbm9fbGxzZWVrLAp9OwoKc3RhdGljIHN0cnVjdCB2aWRlb19kZXZpY2Ugc2FhX3RlbXBsYXRlID0KewoJLm93bmVyCSAgPSBUSElTX01PRFVMRSwKCS5uYW1lCSAgPSBJRl9OQU1FLAoJLnR5cGUJICA9IFZJRF9UWVBFX1RFTEVURVhULAoJLmhhcmR3YXJlID0gVklEX0hBUkRXQVJFX1NBQTUyNDksCgkuZm9wcwkgID0gJnNhYV9mb3BzLAoJLnJlbGVhc2UgID0gdmlkZW9fZGV2aWNlX3JlbGVhc2UsCgkubWlub3IgICAgPSAtMSwKfTsK