LyoKICogbGludXgvZHJpdmVycy9pbnB1dC9rZXlib2FyZC9vbWFwLWtleXBhZC5jCiAqCiAqIE9NQVAgS2V5cGFkIERyaXZlcgogKgogKiBDb3B5cmlnaHQgKEMpIDIwMDMgTm9raWEgQ29ycG9yYXRpb24KICogV3JpdHRlbiBieSBUaW1vIFRlcuRzIDxleHQtdGltby50ZXJhc0Bub2tpYS5jb20+CiAqCiAqIEFkZGVkIHN1cHBvcnQgZm9yIEgyICYgSDMgS2V5cGFkCiAqIENvcHlyaWdodCAoQykgMjAwNCBUZXhhcyBJbnN0cnVtZW50cwogKgogKiBUaGlzIHByb2dyYW0gaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeQogKiBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieQogKiB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIgdmVyc2lvbiAyIG9mIHRoZSBMaWNlbnNlLCBvcgogKiAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiBTZWUgdGhlCiAqIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIGFsb25nIHdpdGggdGhpcyBwcm9ncmFtOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDU5IFRlbXBsZSBQbGFjZSwgU3VpdGUgMzMwLCBCb3N0b24sIE1BIDAyMTExLTEzMDcgVVNBCiAqLwoKI2luY2x1ZGUgPGxpbnV4L21vZHVsZS5oPgojaW5jbHVkZSA8bGludXgvaW5pdC5oPgojaW5jbHVkZSA8bGludXgvaW50ZXJydXB0Lmg+CiNpbmNsdWRlIDxsaW51eC90eXBlcy5oPgojaW5jbHVkZSA8bGludXgvaW5wdXQuaD4KI2luY2x1ZGUgPGxpbnV4L2tlcm5lbC5oPgojaW5jbHVkZSA8bGludXgvZGVsYXkuaD4KI2luY2x1ZGUgPGxpbnV4L3BsYXRmb3JtX2RldmljZS5oPgojaW5jbHVkZSA8bGludXgvbXV0ZXguaD4KI2luY2x1ZGUgPGxpbnV4L2Vycm5vLmg+CiNpbmNsdWRlIDxhc20vYXJjaC9ncGlvLmg+CiNpbmNsdWRlIDxhc20vYXJjaC9rZXlwYWQuaD4KI2luY2x1ZGUgPGFzbS9hcmNoL21lbmVsYXVzLmg+CiNpbmNsdWRlIDxhc20vaXJxLmg+CiNpbmNsdWRlIDxhc20vaGFyZHdhcmUuaD4KI2luY2x1ZGUgPGFzbS9pby5oPgojaW5jbHVkZSA8YXNtL21hY2gtdHlwZXMuaD4KI2luY2x1ZGUgPGFzbS9hcmNoL211eC5oPgoKI3VuZGVmIE5FV19CT0FSRF9MRUFSTklOR19NT0RFCgpzdGF0aWMgdm9pZCBvbWFwX2twX3Rhc2tsZXQodW5zaWduZWQgbG9uZyk7CnN0YXRpYyB2b2lkIG9tYXBfa3BfdGltZXIodW5zaWduZWQgbG9uZyk7CgpzdGF0aWMgdW5zaWduZWQgY2hhciBrZXlwYWRfc3RhdGVbOF07CnN0YXRpYyBERUZJTkVfTVVURVgoa3BfZW5hYmxlX211dGV4KTsKc3RhdGljIGludCBrcF9lbmFibGUgPSAxOwpzdGF0aWMgaW50IGtwX2N1cl9ncm91cCA9IC0xOwoKc3RydWN0IG9tYXBfa3AgewoJc3RydWN0IGlucHV0X2RldiAqaW5wdXQ7CglzdHJ1Y3QgdGltZXJfbGlzdCB0aW1lcjsKCWludCBpcnE7Cgl1bnNpZ25lZCBpbnQgcm93czsKCXVuc2lnbmVkIGludCBjb2xzOwoJdW5zaWduZWQgbG9uZyBkZWxheTsKCXVuc2lnbmVkIGludCBkZWJvdW5jZTsKfTsKCkRFQ0xBUkVfVEFTS0xFVF9ESVNBQkxFRChrcF90YXNrbGV0LCBvbWFwX2twX3Rhc2tsZXQsIDApOwoKc3RhdGljIGludCAqa2V5bWFwOwpzdGF0aWMgdW5zaWduZWQgaW50ICpyb3dfZ3Bpb3M7CnN0YXRpYyB1bnNpZ25lZCBpbnQgKmNvbF9ncGlvczsKCiNpZmRlZiBDT05GSUdfQVJDSF9PTUFQMgpzdGF0aWMgdm9pZCBzZXRfY29sX2dwaW9fdmFsKHN0cnVjdCBvbWFwX2twICpvbWFwX2twLCB1OCB2YWx1ZSkKewoJaW50IGNvbDsKCWZvciAoY29sID0gMDsgY29sIDwgb21hcF9rcC0+Y29sczsgY29sKyspIHsKCQlpZiAodmFsdWUgJiAoMSA8PCBjb2wpKQoJCQlvbWFwX3NldF9ncGlvX2RhdGFvdXQoY29sX2dwaW9zW2NvbF0sIDEpOwoJCWVsc2UKCQkJb21hcF9zZXRfZ3Bpb19kYXRhb3V0KGNvbF9ncGlvc1tjb2xdLCAwKTsKCX0KfQoKc3RhdGljIHU4IGdldF9yb3dfZ3Bpb192YWwoc3RydWN0IG9tYXBfa3AgKm9tYXBfa3ApCnsKCWludCByb3c7Cgl1OCB2YWx1ZSA9IDA7CgoJZm9yIChyb3cgPSAwOyByb3cgPCBvbWFwX2twLT5yb3dzOyByb3crKykgewoJCWlmIChvbWFwX2dldF9ncGlvX2RhdGFpbihyb3dfZ3Bpb3Nbcm93XSkpCgkJCXZhbHVlIHw9ICgxIDw8IHJvdyk7Cgl9CglyZXR1cm4gdmFsdWU7Cn0KI2Vsc2UKI2RlZmluZQkJc2V0X2NvbF9ncGlvX3ZhbCh4LCB5KQlkbyB7fSB3aGlsZSAoMCkKI2RlZmluZQkJZ2V0X3Jvd19ncGlvX3ZhbCh4KQkwCiNlbmRpZgoKc3RhdGljIGlycXJldHVybl90IG9tYXBfa3BfaW50ZXJydXB0KGludCBpcnEsIHZvaWQgKmRldl9pZCkKewoJc3RydWN0IG9tYXBfa3AgKm9tYXBfa3AgPSBkZXZfaWQ7CgoJLyogZGlzYWJsZSBrZXlib2FyZCBpbnRlcnJ1cHQgYW5kIHNjaGVkdWxlIGZvciBoYW5kbGluZyAqLwoJaWYgKGNwdV9pc19vbWFwMjR4eCgpKSB7CgkJaW50IGk7CgkJZm9yIChpID0gMDsgaSA8IG9tYXBfa3AtPnJvd3M7IGkrKykKCQkJZGlzYWJsZV9pcnEoT01BUF9HUElPX0lSUShyb3dfZ3Bpb3NbaV0pKTsKCX0gZWxzZQoJCS8qIGRpc2FibGUga2V5Ym9hcmQgaW50ZXJydXB0IGFuZCBzY2hlZHVsZSBmb3IgaGFuZGxpbmcgKi8KCQlvbWFwX3dyaXRldygxLCBPTUFQX01QVUlPX0JBU0UgKyBPTUFQX01QVUlPX0tCRF9NQVNLSVQpOwoKCXRhc2tsZXRfc2NoZWR1bGUoJmtwX3Rhc2tsZXQpOwoKCXJldHVybiBJUlFfSEFORExFRDsKfQoKc3RhdGljIHZvaWQgb21hcF9rcF90aW1lcih1bnNpZ25lZCBsb25nIGRhdGEpCnsKCXRhc2tsZXRfc2NoZWR1bGUoJmtwX3Rhc2tsZXQpOwp9CgpzdGF0aWMgdm9pZCBvbWFwX2twX3NjYW5fa2V5cGFkKHN0cnVjdCBvbWFwX2twICpvbWFwX2twLCB1bnNpZ25lZCBjaGFyICpzdGF0ZSkKewoJaW50IGNvbCA9IDA7CgoJLyogcmVhZCB0aGUga2V5cGFkIHN0YXR1cyAqLwoJaWYgKGNwdV9pc19vbWFwMjR4eCgpKSB7CgkJaW50IGk7CgkJZm9yIChpID0gMDsgaSA8IG9tYXBfa3AtPnJvd3M7IGkrKykKCQkJZGlzYWJsZV9pcnEoT01BUF9HUElPX0lSUShyb3dfZ3Bpb3NbaV0pKTsKCgkJLyogcmVhZCB0aGUga2V5cGFkIHN0YXR1cyAqLwoJCWZvciAoY29sID0gMDsgY29sIDwgb21hcF9rcC0+Y29sczsgY29sKyspIHsKCQkJc2V0X2NvbF9ncGlvX3ZhbChvbWFwX2twLCB+KDEgPDwgY29sKSk7CgkJCXN0YXRlW2NvbF0gPSB+KGdldF9yb3dfZ3Bpb192YWwob21hcF9rcCkpICYgMHgzZjsKCQl9CgkJc2V0X2NvbF9ncGlvX3ZhbChvbWFwX2twLCAwKTsKCgl9IGVsc2UgewoJCS8qIGRpc2FibGUga2V5Ym9hcmQgaW50ZXJydXB0IGFuZCBzY2hlZHVsZSBmb3IgaGFuZGxpbmcgKi8KCQlvbWFwX3dyaXRldygxLCBPTUFQX01QVUlPX0JBU0UgKyBPTUFQX01QVUlPX0tCRF9NQVNLSVQpOwoKCQkvKiByZWFkIHRoZSBrZXlwYWQgc3RhdHVzICovCgkJb21hcF93cml0ZXcoMHhmZiwgT01BUF9NUFVJT19CQVNFICsgT01BUF9NUFVJT19LQkMpOwoJCWZvciAoY29sID0gMDsgY29sIDwgb21hcF9rcC0+Y29sczsgY29sKyspIHsKCQkJb21hcF93cml0ZXcofigxIDw8IGNvbCkgJiAweGZmLAoJCQkJICAgIE9NQVBfTVBVSU9fQkFTRSArIE9NQVBfTVBVSU9fS0JDKTsKCgkJCXVkZWxheShvbWFwX2twLT5kZWxheSk7CgoJCQlzdGF0ZVtjb2xdID0gfm9tYXBfcmVhZHcoT01BUF9NUFVJT19CQVNFICsKCQkJCQkJIE9NQVBfTVBVSU9fS0JSX0xBVENIKSAmIDB4ZmY7CgkJfQoJCW9tYXBfd3JpdGV3KDB4MDAsIE9NQVBfTVBVSU9fQkFTRSArIE9NQVBfTVBVSU9fS0JDKTsKCQl1ZGVsYXkoMik7Cgl9Cn0KCnN0YXRpYyBpbmxpbmUgaW50IG9tYXBfa3BfZmluZF9rZXkoaW50IGNvbCwgaW50IHJvdykKewoJaW50IGksIGtleTsKCglrZXkgPSBLRVkoY29sLCByb3csIDApOwoJZm9yIChpID0gMDsga2V5bWFwW2ldICE9IDA7IGkrKykKCQlpZiAoKGtleW1hcFtpXSAmIDB4ZmYwMDAwMDApID09IGtleSkKCQkJcmV0dXJuIGtleW1hcFtpXSAmIDB4MDBmZmZmZmY7CglyZXR1cm4gLTE7Cn0KCnN0YXRpYyB2b2lkIG9tYXBfa3BfdGFza2xldCh1bnNpZ25lZCBsb25nIGRhdGEpCnsKCXN0cnVjdCBvbWFwX2twICpvbWFwX2twX2RhdGEgPSAoc3RydWN0IG9tYXBfa3AgKikgZGF0YTsKCXVuc2lnbmVkIGNoYXIgbmV3X3N0YXRlWzhdLCBjaGFuZ2VkLCBrZXlfZG93biA9IDA7CglpbnQgY29sLCByb3c7CglpbnQgc3B1cmlvdXMgPSAwOwoKCS8qIGNoZWNrIGZvciBhbnkgY2hhbmdlcyAqLwoJb21hcF9rcF9zY2FuX2tleXBhZChvbWFwX2twX2RhdGEsIG5ld19zdGF0ZSk7CgoJLyogY2hlY2sgZm9yIGNoYW5nZXMgYW5kIHByaW50IHRob3NlICovCglmb3IgKGNvbCA9IDA7IGNvbCA8IG9tYXBfa3BfZGF0YS0+Y29sczsgY29sKyspIHsKCQljaGFuZ2VkID0gbmV3X3N0YXRlW2NvbF0gXiBrZXlwYWRfc3RhdGVbY29sXTsKCQlrZXlfZG93biB8PSBuZXdfc3RhdGVbY29sXTsKCQlpZiAoY2hhbmdlZCA9PSAwKQoJCQljb250aW51ZTsKCgkJZm9yIChyb3cgPSAwOyByb3cgPCBvbWFwX2twX2RhdGEtPnJvd3M7IHJvdysrKSB7CgkJCWludCBrZXk7CgkJCWlmICghKGNoYW5nZWQgJiAoMSA8PCByb3cpKSkKCQkJCWNvbnRpbnVlOwojaWZkZWYgTkVXX0JPQVJEX0xFQVJOSU5HX01PREUKCQkJcHJpbnRrKEtFUk5fSU5GTyAib21hcC1rZXlwYWQ6IGtleSAlZC0lZCAlc1xuIiwgY29sLAoJCQkgICAgICAgcm93LCAobmV3X3N0YXRlW2NvbF0gJiAoMSA8PCByb3cpKSA/CgkJCSAgICAgICAicHJlc3NlZCIgOiAicmVsZWFzZWQiKTsKI2Vsc2UKCQkJa2V5ID0gb21hcF9rcF9maW5kX2tleShjb2wsIHJvdyk7CgkJCWlmIChrZXkgPCAwKSB7CgkJCQlwcmludGsoS0VSTl9XQVJOSU5HCgkJCQkgICAgICAib21hcC1rZXlwYWQ6IFNwdXJpb3VzIGtleSBldmVudCAlZC0lZFxuIiwKCQkJCSAgICAgICBjb2wsIHJvdyk7CgkJCQkvKiBXZSBzY2FuIGFnYWluIGFmdGVyIGEgY291cGxlIG9mIHNlY29uZHMgKi8KCQkJCXNwdXJpb3VzID0gMTsKCQkJCWNvbnRpbnVlOwoJCQl9CgoJCQlpZiAoIShrcF9jdXJfZ3JvdXAgPT0gKGtleSAmIEdST1VQX01BU0spIHx8CgkJCSAgICAgIGtwX2N1cl9ncm91cCA9PSAtMSkpCgkJCQljb250aW51ZTsKCgkJCWtwX2N1cl9ncm91cCA9IGtleSAmIEdST1VQX01BU0s7CgkJCWlucHV0X3JlcG9ydF9rZXkob21hcF9rcF9kYXRhLT5pbnB1dCwga2V5ICYgfkdST1VQX01BU0ssCgkJCQkJIG5ld19zdGF0ZVtjb2xdICYgKDEgPDwgcm93KSk7CiNlbmRpZgoJCX0KCX0KCW1lbWNweShrZXlwYWRfc3RhdGUsIG5ld19zdGF0ZSwgc2l6ZW9mKGtleXBhZF9zdGF0ZSkpOwoKCWlmIChrZXlfZG93bikgewogICAgICAgICAgICAgICAgaW50IGRlbGF5ID0gSFogLyAyMDsKCQkvKiBzb21lIGtleSBpcyBwcmVzc2VkIC0ga2VlcCBpcnEgZGlzYWJsZWQgYW5kIHVzZSB0aW1lcgoJCSAqIHRvIHBvbGwgdGhlIGtleXBhZCAqLwoJCWlmIChzcHVyaW91cykKCQkJZGVsYXkgPSAyICogSFo7CgkJbW9kX3RpbWVyKCZvbWFwX2twX2RhdGEtPnRpbWVyLCBqaWZmaWVzICsgZGVsYXkpOwoJfSBlbHNlIHsKCQkvKiBlbmFibGUgaW50ZXJydXB0cyAqLwoJCWlmIChjcHVfaXNfb21hcDI0eHgoKSkgewoJCQlpbnQgaTsKCQkJZm9yIChpID0gMDsgaSA8IG9tYXBfa3BfZGF0YS0+cm93czsgaSsrKQoJCQkJZW5hYmxlX2lycShPTUFQX0dQSU9fSVJRKHJvd19ncGlvc1tpXSkpOwoJCX0gZWxzZSB7CgkJCW9tYXBfd3JpdGV3KDAsIE9NQVBfTVBVSU9fQkFTRSArIE9NQVBfTVBVSU9fS0JEX01BU0tJVCk7CgkJCWtwX2N1cl9ncm91cCA9IC0xOwoJCX0KIAl9Cn0KCnN0YXRpYyBzc2l6ZV90IG9tYXBfa3BfZW5hYmxlX3Nob3coc3RydWN0IGRldmljZSAqZGV2LAoJCQkJICAgc3RydWN0IGRldmljZV9hdHRyaWJ1dGUgKmF0dHIsIGNoYXIgKmJ1ZikKewoJcmV0dXJuIHNwcmludGYoYnVmLCAiJXVcbiIsIGtwX2VuYWJsZSk7Cn0KCnN0YXRpYyBzc2l6ZV90IG9tYXBfa3BfZW5hYmxlX3N0b3JlKHN0cnVjdCBkZXZpY2UgKmRldiwgc3RydWN0IGRldmljZV9hdHRyaWJ1dGUgKmF0dHIsCgkJCQkgICAgY29uc3QgY2hhciAqYnVmLCBzaXplX3QgY291bnQpCnsKCWludCBzdGF0ZTsKCglpZiAoc3NjYW5mKGJ1ZiwgIiV1IiwgJnN0YXRlKSAhPSAxKQoJCXJldHVybiAtRUlOVkFMOwoKCWlmICgoc3RhdGUgIT0gMSkgJiYgKHN0YXRlICE9IDApKQoJCXJldHVybiAtRUlOVkFMOwoKCW11dGV4X2xvY2soJmtwX2VuYWJsZV9tdXRleCk7CglpZiAoc3RhdGUgIT0ga3BfZW5hYmxlKSB7CgkJaWYgKHN0YXRlKQoJCQllbmFibGVfaXJxKElOVF9LRVlCT0FSRCk7CgkJZWxzZQoJCQlkaXNhYmxlX2lycShJTlRfS0VZQk9BUkQpOwoJCWtwX2VuYWJsZSA9IHN0YXRlOwoJfQoJbXV0ZXhfdW5sb2NrKCZrcF9lbmFibGVfbXV0ZXgpOwoKCXJldHVybiBzdHJubGVuKGJ1ZiwgY291bnQpOwp9CgpzdGF0aWMgREVWSUNFX0FUVFIoZW5hYmxlLCBTX0lSVUdPIHwgU19JV1VTUiwgb21hcF9rcF9lbmFibGVfc2hvdywgb21hcF9rcF9lbmFibGVfc3RvcmUpOwoKI2lmZGVmIENPTkZJR19QTQpzdGF0aWMgaW50IG9tYXBfa3Bfc3VzcGVuZChzdHJ1Y3QgcGxhdGZvcm1fZGV2aWNlICpkZXYsIHBtX21lc3NhZ2VfdCBzdGF0ZSkKewoJLyogTm90aGluZyB5ZXQgKi8KCglyZXR1cm4gMDsKfQoKc3RhdGljIGludCBvbWFwX2twX3Jlc3VtZShzdHJ1Y3QgcGxhdGZvcm1fZGV2aWNlICpkZXYpCnsKCS8qIE5vdGhpbmcgeWV0ICovCgoJcmV0dXJuIDA7Cn0KI2Vsc2UKI2RlZmluZSBvbWFwX2twX3N1c3BlbmQJTlVMTAojZGVmaW5lIG9tYXBfa3BfcmVzdW1lCU5VTEwKI2VuZGlmCgpzdGF0aWMgaW50IF9faW5pdCBvbWFwX2twX3Byb2JlKHN0cnVjdCBwbGF0Zm9ybV9kZXZpY2UgKnBkZXYpCnsKCXN0cnVjdCBvbWFwX2twICpvbWFwX2twOwoJc3RydWN0IGlucHV0X2RldiAqaW5wdXRfZGV2OwoJc3RydWN0IG9tYXBfa3BfcGxhdGZvcm1fZGF0YSAqcGRhdGEgPSAgcGRldi0+ZGV2LnBsYXRmb3JtX2RhdGE7CglpbnQgaSwgY29sX2lkeCwgcm93X2lkeCwgaXJxX2lkeCwgcmV0OwoKCWlmICghcGRhdGEtPnJvd3MgfHwgIXBkYXRhLT5jb2xzIHx8ICFwZGF0YS0+a2V5bWFwKSB7CgkJcHJpbnRrKEtFUk5fRVJSICJObyByb3dzLCBjb2xzIG9yIGtleW1hcCBmcm9tIHBkYXRhXG4iKTsKCQlyZXR1cm4gLUVJTlZBTDsKCX0KCglvbWFwX2twID0ga3phbGxvYyhzaXplb2Yoc3RydWN0IG9tYXBfa3ApLCBHRlBfS0VSTkVMKTsKCWlucHV0X2RldiA9IGlucHV0X2FsbG9jYXRlX2RldmljZSgpOwoJaWYgKCFvbWFwX2twIHx8ICFpbnB1dF9kZXYpIHsKCQlrZnJlZShvbWFwX2twKTsKCQlpbnB1dF9mcmVlX2RldmljZShpbnB1dF9kZXYpOwoJCXJldHVybiAtRU5PTUVNOwoJfQoKCXBsYXRmb3JtX3NldF9kcnZkYXRhKHBkZXYsIG9tYXBfa3ApOwoKCW9tYXBfa3AtPmlucHV0ID0gaW5wdXRfZGV2OwoKCS8qIERpc2FibGUgdGhlIGludGVycnVwdCBmb3IgdGhlIE1QVUlPIGtleWJvYXJkICovCglpZiAoIWNwdV9pc19vbWFwMjR4eCgpKQoJCW9tYXBfd3JpdGV3KDEsIE9NQVBfTVBVSU9fQkFTRSArIE9NQVBfTVBVSU9fS0JEX01BU0tJVCk7CgoJa2V5bWFwID0gcGRhdGEtPmtleW1hcDsKCglpZiAocGRhdGEtPnJlcCkKCQlzZXRfYml0KEVWX1JFUCwgaW5wdXRfZGV2LT5ldmJpdCk7CgoJaWYgKHBkYXRhLT5kZWxheSkKCQlvbWFwX2twLT5kZWxheSA9IHBkYXRhLT5kZWxheTsKCglpZiAocGRhdGEtPnJvd19ncGlvcyAmJiBwZGF0YS0+Y29sX2dwaW9zKSB7CgkJcm93X2dwaW9zID0gcGRhdGEtPnJvd19ncGlvczsKCQljb2xfZ3Bpb3MgPSBwZGF0YS0+Y29sX2dwaW9zOwoJfQoKCW9tYXBfa3AtPnJvd3MgPSBwZGF0YS0+cm93czsKCW9tYXBfa3AtPmNvbHMgPSBwZGF0YS0+Y29sczsKCglpZiAoY3B1X2lzX29tYXAyNHh4KCkpIHsKCQkvKiBDb2xzOiBvdXRwdXRzICovCgkJZm9yIChjb2xfaWR4ID0gMDsgY29sX2lkeCA8IG9tYXBfa3AtPmNvbHM7IGNvbF9pZHgrKykgewoJCQlpZiAob21hcF9yZXF1ZXN0X2dwaW8oY29sX2dwaW9zW2NvbF9pZHhdKSA8IDApIHsKCQkJCXByaW50ayhLRVJOX0VSUiAiRmFpbGVkIHRvIHJlcXVlc3QiCgkJCQkgICAgICAgIkdQSU8lZCBmb3Iga2V5cGFkXG4iLAoJCQkJICAgICAgIGNvbF9ncGlvc1tjb2xfaWR4XSk7CgkJCQlnb3RvIGVycjE7CgkJCX0KCQkJb21hcF9zZXRfZ3Bpb19kaXJlY3Rpb24oY29sX2dwaW9zW2NvbF9pZHhdLCAwKTsKCQl9CgkJLyogUm93czogaW5wdXRzICovCgkJZm9yIChyb3dfaWR4ID0gMDsgcm93X2lkeCA8IG9tYXBfa3AtPnJvd3M7IHJvd19pZHgrKykgewoJCQlpZiAob21hcF9yZXF1ZXN0X2dwaW8ocm93X2dwaW9zW3Jvd19pZHhdKSA8IDApIHsKCQkJCXByaW50ayhLRVJOX0VSUiAiRmFpbGVkIHRvIHJlcXVlc3QiCgkJCQkgICAgICAgIkdQSU8lZCBmb3Iga2V5cGFkXG4iLAoJCQkJICAgICAgIHJvd19ncGlvc1tyb3dfaWR4XSk7CgkJCQlnb3RvIGVycjI7CgkJCX0KCQkJb21hcF9zZXRfZ3Bpb19kaXJlY3Rpb24ocm93X2dwaW9zW3Jvd19pZHhdLCAxKTsKCQl9Cgl9CgoJc2V0dXBfdGltZXIoJm9tYXBfa3AtPnRpbWVyLCBvbWFwX2twX3RpbWVyLCAodW5zaWduZWQgbG9uZylvbWFwX2twKTsKCgkvKiBnZXQgdGhlIGlycSBhbmQgaW5pdCB0aW1lciovCgl0YXNrbGV0X2VuYWJsZSgma3BfdGFza2xldCk7CglrcF90YXNrbGV0LmRhdGEgPSAodW5zaWduZWQgbG9uZykgb21hcF9rcDsKCglyZXQgPSBkZXZpY2VfY3JlYXRlX2ZpbGUoJnBkZXYtPmRldiwgJmRldl9hdHRyX2VuYWJsZSk7CglpZiAocmV0IDwgMCkKCQlnb3RvIGVycjI7CgoJLyogc2V0dXAgaW5wdXQgZGV2aWNlICovCglzZXRfYml0KEVWX0tFWSwgaW5wdXRfZGV2LT5ldmJpdCk7Cglmb3IgKGkgPSAwOyBrZXltYXBbaV0gIT0gMDsgaSsrKQoJCXNldF9iaXQoa2V5bWFwW2ldICYgS0VZX01BWCwgaW5wdXRfZGV2LT5rZXliaXQpOwoJaW5wdXRfZGV2LT5uYW1lID0gIm9tYXAta2V5cGFkIjsKCWlucHV0X2Rldi0+cGh5cyA9ICJvbWFwLWtleXBhZC9pbnB1dDAiOwoJaW5wdXRfZGV2LT5jZGV2LmRldiA9ICZwZGV2LT5kZXY7CglpbnB1dF9kZXYtPnByaXZhdGUgPSBvbWFwX2twOwoKCWlucHV0X2Rldi0+aWQuYnVzdHlwZSA9IEJVU19IT1NUOwoJaW5wdXRfZGV2LT5pZC52ZW5kb3IgPSAweDAwMDE7CglpbnB1dF9kZXYtPmlkLnByb2R1Y3QgPSAweDAwMDE7CglpbnB1dF9kZXYtPmlkLnZlcnNpb24gPSAweDAxMDA7CgoJaW5wdXRfZGV2LT5rZXljb2RlID0ga2V5bWFwOwoJaW5wdXRfZGV2LT5rZXljb2Rlc2l6ZSA9IHNpemVvZih1bnNpZ25lZCBpbnQpOwoJaW5wdXRfZGV2LT5rZXljb2RlbWF4ID0gcGRhdGEtPmtleW1hcHNpemU7CgoJcmV0ID0gaW5wdXRfcmVnaXN0ZXJfZGV2aWNlKG9tYXBfa3AtPmlucHV0KTsKCWlmIChyZXQgPCAwKSB7CgkJcHJpbnRrKEtFUk5fRVJSICJVbmFibGUgdG8gcmVnaXN0ZXIgb21hcC1rZXlwYWQgaW5wdXQgZGV2aWNlXG4iKTsKCQlnb3RvIGVycjM7Cgl9CgoJaWYgKHBkYXRhLT5kYm91bmNlKQoJCW9tYXBfd3JpdGV3KDB4ZmYsIE9NQVBfTVBVSU9fQkFTRSArIE9NQVBfTVBVSU9fR1BJT19ERUJPVU5DSU5HKTsKCgkvKiBzY2FuIGN1cnJlbnQgc3RhdHVzIGFuZCBlbmFibGUgaW50ZXJydXB0ICovCglvbWFwX2twX3NjYW5fa2V5cGFkKG9tYXBfa3AsIGtleXBhZF9zdGF0ZSk7CglpZiAoIWNwdV9pc19vbWFwMjR4eCgpKSB7CgkJb21hcF9rcC0+aXJxID0gcGxhdGZvcm1fZ2V0X2lycShwZGV2LCAwKTsKCQlpZiAob21hcF9rcC0+aXJxID49IDApIHsKCQkJaWYgKHJlcXVlc3RfaXJxKG9tYXBfa3AtPmlycSwgb21hcF9rcF9pbnRlcnJ1cHQsIDAsCgkJCQkJIm9tYXAta2V5cGFkIiwgb21hcF9rcCkgPCAwKQoJCQkJZ290byBlcnI0OwoJCX0KCQlvbWFwX3dyaXRldygwLCBPTUFQX01QVUlPX0JBU0UgKyBPTUFQX01QVUlPX0tCRF9NQVNLSVQpOwoJfSBlbHNlIHsKCQlmb3IgKGlycV9pZHggPSAwOyBpcnFfaWR4IDwgb21hcF9rcC0+cm93czsgaXJxX2lkeCsrKSB7CgkJCWlmIChyZXF1ZXN0X2lycShPTUFQX0dQSU9fSVJRKHJvd19ncGlvc1tpcnFfaWR4XSksCgkJCQkgICAgICAgCW9tYXBfa3BfaW50ZXJydXB0LAoJCQkJCUlSUUZfVFJJR0dFUl9GQUxMSU5HLAoJCQkJICAgICAgIAkib21hcC1rZXlwYWQiLCBvbWFwX2twKSA8IDApCgkJCQlnb3RvIGVycjU7CgkJfQoJfQoJcmV0dXJuIDA7CmVycjU6Cglmb3IgKGkgPSBpcnFfaWR4LTE7IGkgPj0wOyBpLS0pCgkJZnJlZV9pcnEocm93X2dwaW9zW2ldLCAwKTsKZXJyNDoKCWlucHV0X3VucmVnaXN0ZXJfZGV2aWNlKG9tYXBfa3AtPmlucHV0KTsKCWlucHV0X2RldiA9IE5VTEw7CmVycjM6CglkZXZpY2VfcmVtb3ZlX2ZpbGUoJnBkZXYtPmRldiwgJmRldl9hdHRyX2VuYWJsZSk7CmVycjI6Cglmb3IgKGkgPSByb3dfaWR4LTE7IGkgPj0wOyBpLS0pCgkJb21hcF9mcmVlX2dwaW8ocm93X2dwaW9zW2ldKTsKZXJyMToKCWZvciAoaSA9IGNvbF9pZHgtMTsgaSA+PTA7IGktLSkKCQlvbWFwX2ZyZWVfZ3Bpbyhjb2xfZ3Bpb3NbaV0pOwoKCWtmcmVlKG9tYXBfa3ApOwoJaW5wdXRfZnJlZV9kZXZpY2UoaW5wdXRfZGV2KTsKCglyZXR1cm4gLUVJTlZBTDsKfQoKc3RhdGljIGludCBvbWFwX2twX3JlbW92ZShzdHJ1Y3QgcGxhdGZvcm1fZGV2aWNlICpwZGV2KQp7CglzdHJ1Y3Qgb21hcF9rcCAqb21hcF9rcCA9IHBsYXRmb3JtX2dldF9kcnZkYXRhKHBkZXYpOwoKCS8qIGRpc2FibGUga2V5cGFkIGludGVycnVwdCBoYW5kbGluZyAqLwoJdGFza2xldF9kaXNhYmxlKCZrcF90YXNrbGV0KTsKCWlmIChjcHVfaXNfb21hcDI0eHgoKSkgewoJCWludCBpOwoJCWZvciAoaSA9IDA7IGkgPCBvbWFwX2twLT5jb2xzOyBpKyspCgkgICAgCQlvbWFwX2ZyZWVfZ3Bpbyhjb2xfZ3Bpb3NbaV0pOwoJCWZvciAoaSA9IDA7IGkgPCBvbWFwX2twLT5yb3dzOyBpKyspIHsKCSAgICAJCW9tYXBfZnJlZV9ncGlvKHJvd19ncGlvc1tpXSk7CgkJCWZyZWVfaXJxKE9NQVBfR1BJT19JUlEocm93X2dwaW9zW2ldKSwgMCk7CgkJfQoJfSBlbHNlIHsKCQlvbWFwX3dyaXRldygxLCBPTUFQX01QVUlPX0JBU0UgKyBPTUFQX01QVUlPX0tCRF9NQVNLSVQpOwoJCWZyZWVfaXJxKG9tYXBfa3AtPmlycSwgMCk7Cgl9CgoJZGVsX3RpbWVyX3N5bmMoJm9tYXBfa3AtPnRpbWVyKTsKCXRhc2tsZXRfa2lsbCgma3BfdGFza2xldCk7CgoJLyogdW5yZWdpc3RlciBldmVyeXRoaW5nICovCglpbnB1dF91bnJlZ2lzdGVyX2RldmljZShvbWFwX2twLT5pbnB1dCk7CgoJa2ZyZWUob21hcF9rcCk7CgoJcmV0dXJuIDA7Cn0KCnN0YXRpYyBzdHJ1Y3QgcGxhdGZvcm1fZHJpdmVyIG9tYXBfa3BfZHJpdmVyID0gewoJLnByb2JlCQk9IG9tYXBfa3BfcHJvYmUsCgkucmVtb3ZlCQk9IG9tYXBfa3BfcmVtb3ZlLAoJLnN1c3BlbmQJPSBvbWFwX2twX3N1c3BlbmQsCgkucmVzdW1lCQk9IG9tYXBfa3BfcmVzdW1lLAoJLmRyaXZlcgkJPSB7CgkJLm5hbWUJPSAib21hcC1rZXlwYWQiLAoJfSwKfTsKCnN0YXRpYyBpbnQgX19kZXZpbml0IG9tYXBfa3BfaW5pdCh2b2lkKQp7CglwcmludGsoS0VSTl9JTkZPICJPTUFQIEtleXBhZCBEcml2ZXJcbiIpOwoJcmV0dXJuIHBsYXRmb3JtX2RyaXZlcl9yZWdpc3Rlcigmb21hcF9rcF9kcml2ZXIpOwp9CgpzdGF0aWMgdm9pZCBfX2V4aXQgb21hcF9rcF9leGl0KHZvaWQpCnsKCXBsYXRmb3JtX2RyaXZlcl91bnJlZ2lzdGVyKCZvbWFwX2twX2RyaXZlcik7Cn0KCm1vZHVsZV9pbml0KG9tYXBfa3BfaW5pdCk7Cm1vZHVsZV9leGl0KG9tYXBfa3BfZXhpdCk7CgpNT0RVTEVfQVVUSE9SKCJUaW1vIFRlcuRzIik7Ck1PRFVMRV9ERVNDUklQVElPTigiT01BUCBLZXlwYWQgRHJpdmVyIik7Ck1PRFVMRV9MSUNFTlNFKCJHUEwiKTsK