LyoKICogT01BUDEgU3BlY2lhbCBPcHRpbWlTZWQgU2NyZWVuIEludGVyZmFjZSBzdXBwb3J0CiAqCiAqIENvcHlyaWdodCAoQykgMjAwNC0yMDA1IE5va2lhIENvcnBvcmF0aW9uCiAqIEF1dGhvcjogSnVoYSBZcmr2bOQgPGp1aGEueXJqb2xhQG5va2lhLmNvbT4KICoKICogVGhpcyBwcm9ncmFtIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlCiAqIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyIHZlcnNpb24gMiBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIKICogb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KICoKICogVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dAogKiBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VCiAqIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYWxvbmcKICogd2l0aCB0aGlzIHByb2dyYW07IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwgSW5jLiwKICogNTkgVGVtcGxlIFBsYWNlIC0gU3VpdGUgMzMwLCBCb3N0b24sIE1BICAwMjExMS0xMzA3LCBVU0EuCiAqLwojaW5jbHVkZSA8bGludXgvbW9kdWxlLmg+CiNpbmNsdWRlIDxsaW51eC9tbS5oPgojaW5jbHVkZSA8bGludXgvY2xrLmg+CiNpbmNsdWRlIDxsaW51eC9pcnEuaD4KI2luY2x1ZGUgPGxpbnV4L2lvLmg+CiNpbmNsdWRlIDxsaW51eC9pbnRlcnJ1cHQuaD4KCiNpbmNsdWRlIDxwbGF0L2RtYS5oPgoKI2luY2x1ZGUgIm9tYXBmYi5oIgojaW5jbHVkZSAibGNkYy5oIgoKI2RlZmluZSBNT0RVTEVfTkFNRQkJIm9tYXBmYi1zb3NzaSIKCiNkZWZpbmUgT01BUF9TT1NTSV9CQVNFICAgICAgICAgMHhmZmZiYWMwMAojZGVmaW5lIFNPU1NJX0lEX1JFRwkJMHgwMAojZGVmaW5lIFNPU1NJX0lOSVQxX1JFRwkJMHgwNAojZGVmaW5lIFNPU1NJX0lOSVQyX1JFRwkJMHgwOAojZGVmaW5lIFNPU1NJX0lOSVQzX1JFRwkJMHgwYwojZGVmaW5lIFNPU1NJX0ZJRk9fUkVHCQkweDEwCiNkZWZpbmUgU09TU0lfUkVPVEFCTEVfUkVHCTB4MTQKI2RlZmluZSBTT1NTSV9URUFSSU5HX1JFRwkweDE4CiNkZWZpbmUgU09TU0lfSU5JVDFCX1JFRwkweDFjCiNkZWZpbmUgU09TU0lfRklGT0JfUkVHCQkweDIwCgojZGVmaW5lIERNQV9HU0NSICAgICAgICAgIDB4ZmZmZWRjMDQKI2RlZmluZSBETUFfTENEX0NDUiAgICAgICAweGZmZmVlM2MyCiNkZWZpbmUgRE1BX0xDRF9DVFJMICAgICAgMHhmZmZlZTNjNAojZGVmaW5lIERNQV9MQ0RfTENIX0NUUkwgIDB4ZmZmZWUzZWEKCiNkZWZpbmUgQ09ORl9TT1NTSV9SRVNFVF9SICAgICAgKDEgPDwgMjMpCgojZGVmaW5lIFJEX0FDQ0VTUwkJMAojZGVmaW5lIFdSX0FDQ0VTUwkJMQoKI2RlZmluZSBTT1NTSV9NQVhfWE1JVF9CWVRFUwkoNTEyICogMTAyNCkKCnN0YXRpYyBzdHJ1Y3QgewoJdm9pZCBfX2lvbWVtCSpiYXNlOwoJc3RydWN0IGNsawkqZmNrOwoJdW5zaWduZWQgbG9uZwlmY2tfaHo7CglzcGlubG9ja190CWxvY2s7CglpbnQJCWJ1c19waWNrX2NvdW50OwoJaW50CQlidXNfcGlja193aWR0aDsKCWludAkJdGVhcnN5bmNfbW9kZTsKCWludAkJdGVhcnN5bmNfbGluZTsKCXZvaWQJCSgqbGNkY19jYWxsYmFjaykodm9pZCAqZGF0YSk7Cgl2b2lkCQkqbGNkY19jYWxsYmFja19kYXRhOwoJaW50CQl2c3luY19kbWFfcGVuZGluZzsKCS8qIHRpbWluZyBmb3IgcmVhZCBhbmQgd3JpdGUgYWNjZXNzICovCglpbnQJCWNsa19kaXY7Cgl1OAkJY2xrX3R3MFsyXTsKCXU4CQljbGtfdHcxWzJdOwoJLyoKCSAqIGlmIGxhc3RfYWNjZXNzIGlzIHRoZSBzYW1lIGFzIGN1cnJlbnQgd2UgZG9uJ3QgaGF2ZSB0byBjaGFuZ2UKCSAqIHRoZSB0aW1pbmdzCgkgKi8KCWludAkJbGFzdF9hY2Nlc3M7CgoJc3RydWN0IG9tYXBmYl9kZXZpY2UJKmZiZGV2Owp9IHNvc3NpOwoKc3RhdGljIGlubGluZSB1MzIgc29zc2lfcmVhZF9yZWcoaW50IHJlZykKewoJcmV0dXJuIHJlYWRsKHNvc3NpLmJhc2UgKyByZWcpOwp9CgpzdGF0aWMgaW5saW5lIHUxNiBzb3NzaV9yZWFkX3JlZzE2KGludCByZWcpCnsKCXJldHVybiByZWFkdyhzb3NzaS5iYXNlICsgcmVnKTsKfQoKc3RhdGljIGlubGluZSB1OCBzb3NzaV9yZWFkX3JlZzgoaW50IHJlZykKewoJcmV0dXJuIHJlYWRiKHNvc3NpLmJhc2UgKyByZWcpOwp9CgpzdGF0aWMgaW5saW5lIHZvaWQgc29zc2lfd3JpdGVfcmVnKGludCByZWcsIHUzMiB2YWx1ZSkKewoJd3JpdGVsKHZhbHVlLCBzb3NzaS5iYXNlICsgcmVnKTsKfQoKc3RhdGljIGlubGluZSB2b2lkIHNvc3NpX3dyaXRlX3JlZzE2KGludCByZWcsIHUxNiB2YWx1ZSkKewoJd3JpdGV3KHZhbHVlLCBzb3NzaS5iYXNlICsgcmVnKTsKfQoKc3RhdGljIGlubGluZSB2b2lkIHNvc3NpX3dyaXRlX3JlZzgoaW50IHJlZywgdTggdmFsdWUpCnsKCXdyaXRlYih2YWx1ZSwgc29zc2kuYmFzZSArIHJlZyk7Cn0KCnN0YXRpYyB2b2lkIHNvc3NpX3NldF9iaXRzKGludCByZWcsIHUzMiBiaXRzKQp7Cglzb3NzaV93cml0ZV9yZWcocmVnLCBzb3NzaV9yZWFkX3JlZyhyZWcpIHwgYml0cyk7Cn0KCnN0YXRpYyB2b2lkIHNvc3NpX2NsZWFyX2JpdHMoaW50IHJlZywgdTMyIGJpdHMpCnsKCXNvc3NpX3dyaXRlX3JlZyhyZWcsIHNvc3NpX3JlYWRfcmVnKHJlZykgJiB+Yml0cyk7Cn0KCiNkZWZpbmUgSFpfVE9fUFMoeCkJKDEwMDAwMDAwMDAgLyAoeCAvIDEwMDApKQoKc3RhdGljIHUzMiBwc190b19zb3NzaV90aWNrcyh1MzIgcHMsIGludCBkaXYpCnsKCXUzMiBjbGtfcGVyaW9kID0gSFpfVE9fUFMoc29zc2kuZmNrX2h6KSAqIGRpdjsKCXJldHVybiAoY2xrX3BlcmlvZCArIHBzIC0gMSkgLyBjbGtfcGVyaW9kOwp9CgpzdGF0aWMgaW50IGNhbGNfcmRfdGltaW5ncyhzdHJ1Y3QgZXh0aWZfdGltaW5ncyAqdCkKewoJdTMyIHR3MCwgdHcxOwoJaW50IHJlb24sIHJlb2ZmLCByZWN5YywgYWN0aW07CglpbnQgZGl2ID0gdC0+Y2xrX2RpdjsKCgkvKgoJICogTWFrZSBzdXJlIHRoYXQgYWZ0ZXIgY29udmVyc2lvbiBpdCBzdGlsbCBob2xkcyB0aGF0OgoJICogcmVvZmYgPiByZW9uLCByZWN5YyA+PSByZW9mZiwgYWN0aW0gPiByZW9uCgkgKi8KCXJlb24gPSBwc190b19zb3NzaV90aWNrcyh0LT5yZV9vbl90aW1lLCBkaXYpOwoJLyogcmVvbiB3aWxsIGJlIGV4YWN0bHkgb25lIHNvc3NpIHRpY2sgKi8KCWlmIChyZW9uID4gMSkKCQlyZXR1cm4gLTE7CgoJcmVvZmYgPSBwc190b19zb3NzaV90aWNrcyh0LT5yZV9vZmZfdGltZSwgZGl2KTsKCglpZiAocmVvZmYgPD0gcmVvbikKCQlyZW9mZiA9IHJlb24gKyAxOwoKCXR3MCA9IHJlb2ZmIC0gcmVvbjsKCWlmICh0dzAgPiAweDEwKQoJCXJldHVybiAtMTsKCglyZWN5YyA9IHBzX3RvX3Nvc3NpX3RpY2tzKHQtPnJlX2N5Y2xlX3RpbWUsIGRpdik7CglpZiAocmVjeWMgPD0gcmVvZmYpCgkJcmVjeWMgPSByZW9mZiArIDE7CgoJdHcxID0gcmVjeWMgLSB0dzA7CgkvKiB2YWx1ZXMgbGVzcyB0aGVuIDMgcmVzdWx0IGluIHRoZSBTT1NTSSBibG9jayByZXNldHRpbmcgaXRzZWxmICovCglpZiAodHcxIDwgMykKCQl0dzEgPSAzOwoJaWYgKHR3MSA+IDB4NDApCgkJcmV0dXJuIC0xOwoKCWFjdGltID0gcHNfdG9fc29zc2lfdGlja3ModC0+YWNjZXNzX3RpbWUsIGRpdik7CglpZiAoYWN0aW0gPCByZW9mZikKCQlhY3RpbSsrOwoJLyoKCSAqIGFjY2VzcyB0aW1lIChkYXRhIGhvbGQgdGltZSkgd2lsbCBiZSBleGFjdGx5IG9uZSBzb3NzaQoJICogdGljawoJICovCglpZiAoYWN0aW0gLSByZW9mZiA+IDEpCgkJcmV0dXJuIC0xOwoKCXQtPnRpbVswXSA9IHR3MCAtIDE7Cgl0LT50aW1bMV0gPSB0dzEgLSAxOwoKCXJldHVybiAwOwp9CgpzdGF0aWMgaW50IGNhbGNfd3JfdGltaW5ncyhzdHJ1Y3QgZXh0aWZfdGltaW5ncyAqdCkKewoJdTMyIHR3MCwgdHcxOwoJaW50IHdlb24sIHdlb2ZmLCB3ZWN5YzsKCWludCBkaXYgPSB0LT5jbGtfZGl2OwoKCS8qCgkgKiBNYWtlIHN1cmUgdGhhdCBhZnRlciBjb252ZXJzaW9uIGl0IHN0aWxsIGhvbGRzIHRoYXQ6CgkgKiB3ZW9mZiA+IHdlb24sIHdlY3ljID49IHdlb2ZmCgkgKi8KCXdlb24gPSBwc190b19zb3NzaV90aWNrcyh0LT53ZV9vbl90aW1lLCBkaXYpOwoJLyogd2VvbiB3aWxsIGJlIGV4YWN0bHkgb25lIHNvc3NpIHRpY2sgKi8KCWlmICh3ZW9uID4gMSkKCQlyZXR1cm4gLTE7CgoJd2VvZmYgPSBwc190b19zb3NzaV90aWNrcyh0LT53ZV9vZmZfdGltZSwgZGl2KTsKCWlmICh3ZW9mZiA8PSB3ZW9uKQoJCXdlb2ZmID0gd2VvbiArIDE7Cgl0dzAgPSB3ZW9mZiAtIHdlb247CglpZiAodHcwID4gMHgxMCkKCQlyZXR1cm4gLTE7CgoJd2VjeWMgPSBwc190b19zb3NzaV90aWNrcyh0LT53ZV9jeWNsZV90aW1lLCBkaXYpOwoJaWYgKHdlY3ljIDw9IHdlb2ZmKQoJCXdlY3ljID0gd2VvZmYgKyAxOwoKCXR3MSA9IHdlY3ljIC0gdHcwOwoJLyogdmFsdWVzIGxlc3MgdGhlbiAzIHJlc3VsdCBpbiB0aGUgU09TU0kgYmxvY2sgcmVzZXR0aW5nIGl0c2VsZiAqLwoJaWYgKHR3MSA8IDMpCgkJdHcxID0gMzsKCWlmICh0dzEgPiAweDQwKQoJCXJldHVybiAtMTsKCgl0LT50aW1bMl0gPSB0dzAgLSAxOwoJdC0+dGltWzNdID0gdHcxIC0gMTsKCglyZXR1cm4gMDsKfQoKc3RhdGljIHZvaWQgX3NldF90aW1pbmcoaW50IGRpdiwgaW50IHR3MCwgaW50IHR3MSkKewoJdTMyIGw7CgojaWZkZWYgVkVSQk9TRQoJZGV2X2RiZyhzb3NzaS5mYmRldi0+ZGV2LCAiVXNpbmcgVFcwID0gJWQsIFRXMSA9ICVkLCBkaXYgPSAlZFxuIiwKCQkgdHcwICsgMSwgdHcxICsgMSwgZGl2KTsKI2VuZGlmCgoJY2xrX3NldF9yYXRlKHNvc3NpLmZjaywgc29zc2kuZmNrX2h6IC8gZGl2KTsKCWNsa19lbmFibGUoc29zc2kuZmNrKTsKCWwgPSBzb3NzaV9yZWFkX3JlZyhTT1NTSV9JTklUMV9SRUcpOwoJbCAmPSB+KCgweDBmIDw8IDIwKSB8ICgweDNmIDw8IDI0KSk7CglsIHw9ICh0dzAgPDwgMjApIHwgKHR3MSA8PCAyNCk7Cglzb3NzaV93cml0ZV9yZWcoU09TU0lfSU5JVDFfUkVHLCBsKTsKCWNsa19kaXNhYmxlKHNvc3NpLmZjayk7Cn0KCnN0YXRpYyB2b2lkIF9zZXRfYml0c19wZXJfY3ljbGUoaW50IGJ1c19waWNrX2NvdW50LCBpbnQgYnVzX3BpY2tfd2lkdGgpCnsKCXUzMiBsOwoKCWwgPSBzb3NzaV9yZWFkX3JlZyhTT1NTSV9JTklUM19SRUcpOwoJbCAmPSB+MHgzZmY7CglsIHw9ICgoYnVzX3BpY2tfY291bnQgLSAxKSA8PCA1KSB8ICgoYnVzX3BpY2tfd2lkdGggLSAxKSAmIDB4MWYpOwoJc29zc2lfd3JpdGVfcmVnKFNPU1NJX0lOSVQzX1JFRywgbCk7Cn0KCnN0YXRpYyB2b2lkIF9zZXRfdGVhcnN5bmNfbW9kZShpbnQgbW9kZSwgdW5zaWduZWQgbGluZSkKewoJdTMyIGw7CgoJbCA9IHNvc3NpX3JlYWRfcmVnKFNPU1NJX1RFQVJJTkdfUkVHKTsKCWwgJj0gfigoKDEgPDwgMTEpIC0gMSkgPDwgMTUpOwoJbCB8PSBsaW5lIDw8IDE1OwoJbCAmPSB+KDB4MyA8PCAyNik7CglsIHw9IG1vZGUgPDwgMjY7Cglzb3NzaV93cml0ZV9yZWcoU09TU0lfVEVBUklOR19SRUcsIGwpOwoJaWYgKG1vZGUpCgkJc29zc2lfc2V0X2JpdHMoU09TU0lfSU5JVDJfUkVHLCAxIDw8IDYpOwkvKiBURSBsb2dpYyAqLwoJZWxzZQoJCXNvc3NpX2NsZWFyX2JpdHMoU09TU0lfSU5JVDJfUkVHLCAxIDw8IDYpOwp9CgpzdGF0aWMgaW5saW5lIHZvaWQgc2V0X3RpbWluZyhpbnQgYWNjZXNzKQp7CglpZiAoYWNjZXNzICE9IHNvc3NpLmxhc3RfYWNjZXNzKSB7CgkJc29zc2kubGFzdF9hY2Nlc3MgPSBhY2Nlc3M7CgkJX3NldF90aW1pbmcoc29zc2kuY2xrX2RpdiwKCQkJICAgIHNvc3NpLmNsa190dzBbYWNjZXNzXSwgc29zc2kuY2xrX3R3MVthY2Nlc3NdKTsKCX0KfQoKc3RhdGljIHZvaWQgc29zc2lfc3RhcnRfdHJhbnNmZXIodm9pZCkKewoJLyogV0UgKi8KCXNvc3NpX2NsZWFyX2JpdHMoU09TU0lfSU5JVDJfUkVHLCAxIDw8IDQpOwoJLyogQ1MgYWN0aXZlIGxvdyAqLwoJc29zc2lfY2xlYXJfYml0cyhTT1NTSV9JTklUMV9SRUcsIDEgPDwgMzApOwp9CgpzdGF0aWMgdm9pZCBzb3NzaV9zdG9wX3RyYW5zZmVyKHZvaWQpCnsKCS8qIFdFICovCglzb3NzaV9zZXRfYml0cyhTT1NTSV9JTklUMl9SRUcsIDEgPDwgNCk7CgkvKiBDUyBhY3RpdmUgbG93ICovCglzb3NzaV9zZXRfYml0cyhTT1NTSV9JTklUMV9SRUcsIDEgPDwgMzApOwp9CgpzdGF0aWMgdm9pZCB3YWl0X2VuZF9vZl93cml0ZSh2b2lkKQp7CgkvKiBCZWZvcmUgcmVhZGluZyB3ZSBtdXN0IGNoZWNrIGlmIHNvbWUgd3JpdGluZ3MgYXJlIGdvaW5nIG9uICovCgl3aGlsZSAoIShzb3NzaV9yZWFkX3JlZyhTT1NTSV9JTklUMl9SRUcpICYgKDEgPDwgMykpKTsKfQoKc3RhdGljIHZvaWQgc2VuZF9kYXRhKGNvbnN0IHZvaWQgKmRhdGEsIHVuc2lnbmVkIGludCBsZW4pCnsKCXdoaWxlIChsZW4gPj0gNCkgewoJCXNvc3NpX3dyaXRlX3JlZyhTT1NTSV9GSUZPX1JFRywgKihjb25zdCB1MzIgKikgZGF0YSk7CgkJbGVuIC09IDQ7CgkJZGF0YSArPSA0OwoJfQoJd2hpbGUgKGxlbiA+PSAyKSB7CgkJc29zc2lfd3JpdGVfcmVnMTYoU09TU0lfRklGT19SRUcsICooY29uc3QgdTE2ICopIGRhdGEpOwoJCWxlbiAtPSAyOwoJCWRhdGEgKz0gMjsKCX0KCXdoaWxlIChsZW4pIHsKCQlzb3NzaV93cml0ZV9yZWc4KFNPU1NJX0ZJRk9fUkVHLCAqKGNvbnN0IHU4ICopIGRhdGEpOwoJCWxlbi0tOwoJCWRhdGErKzsKCX0KfQoKc3RhdGljIHZvaWQgc2V0X2N5Y2xlcyh1bnNpZ25lZCBpbnQgbGVuKQp7Cgl1bnNpZ25lZCBsb25nIG5yX2N5Y2xlcyA9IGxlbiAvIChzb3NzaS5idXNfcGlja193aWR0aCAvIDgpOwoKCUJVR19PTigobnJfY3ljbGVzIC0gMSkgJiB+MHgzZmZmZik7CgoJc29zc2lfY2xlYXJfYml0cyhTT1NTSV9JTklUMV9SRUcsIDB4M2ZmZmYpOwoJc29zc2lfc2V0X2JpdHMoU09TU0lfSU5JVDFfUkVHLCAobnJfY3ljbGVzIC0gMSkgJiAweDNmZmZmKTsKfQoKc3RhdGljIGludCBzb3NzaV9jb252ZXJ0X3RpbWluZ3Moc3RydWN0IGV4dGlmX3RpbWluZ3MgKnQpCnsKCWludCByID0gMDsKCWludCBkaXYgPSB0LT5jbGtfZGl2OwoKCXQtPmNvbnZlcnRlZCA9IDA7CgoJaWYgKGRpdiA8PSAwIHx8IGRpdiA+IDgpCgkJcmV0dXJuIC0xOwoKCS8qIG5vIENTIG9uIFNPU1NJLCBzbyBpZ25vcmUgY3NvbiwgY3NvZmYsIGNzX3B1bHNld2lkdGggKi8KCWlmICgociA9IGNhbGNfcmRfdGltaW5ncyh0KSkgPCAwKQoJCXJldHVybiByOwoKCWlmICgociA9IGNhbGNfd3JfdGltaW5ncyh0KSkgPCAwKQoJCXJldHVybiByOwoKCXQtPnRpbVs0XSA9IGRpdjsKCgl0LT5jb252ZXJ0ZWQgPSAxOwoKCXJldHVybiAwOwp9CgpzdGF0aWMgdm9pZCBzb3NzaV9zZXRfdGltaW5ncyhjb25zdCBzdHJ1Y3QgZXh0aWZfdGltaW5ncyAqdCkKewoJQlVHX09OKCF0LT5jb252ZXJ0ZWQpOwoKCXNvc3NpLmNsa190dzBbUkRfQUNDRVNTXSA9IHQtPnRpbVswXTsKCXNvc3NpLmNsa190dzFbUkRfQUNDRVNTXSA9IHQtPnRpbVsxXTsKCglzb3NzaS5jbGtfdHcwW1dSX0FDQ0VTU10gPSB0LT50aW1bMl07Cglzb3NzaS5jbGtfdHcxW1dSX0FDQ0VTU10gPSB0LT50aW1bM107CgoJc29zc2kuY2xrX2RpdiA9IHQtPnRpbVs0XTsKfQoKc3RhdGljIHZvaWQgc29zc2lfZ2V0X2Nsa19pbmZvKHUzMiAqY2xrX3BlcmlvZCwgdTMyICptYXhfY2xrX2RpdikKewoJKmNsa19wZXJpb2QgPSBIWl9UT19QUyhzb3NzaS5mY2tfaHopOwoJKm1heF9jbGtfZGl2ID0gODsKfQoKc3RhdGljIHZvaWQgc29zc2lfc2V0X2JpdHNfcGVyX2N5Y2xlKGludCBicGMpCnsKCWludCBidXNfcGlja19jb3VudCwgYnVzX3BpY2tfd2lkdGg7CgoJLyoKCSAqIFdlIHNldCBleHBsaWNpdGx5IHRoZSB0aGUgYnVzX3BpY2tfY291bnQgYXMgd2VsbCwgYWx0aG91Z2gKCSAqIHdpdGggcmVtYXBwaW5nL3Jlb3JkZXJpbmcgZGlzYWJsZWQgaXQgd2lsbCBiZSBjYWxjdWxhdGVkIGJ5IEhXCgkgKiBhcyAoMzIgLyBidXNfcGlja193aWR0aCkuCgkgKi8KCXN3aXRjaCAoYnBjKSB7CgljYXNlIDg6CgkJYnVzX3BpY2tfY291bnQgPSA0OwoJCWJ1c19waWNrX3dpZHRoID0gODsKCQlicmVhazsKCWNhc2UgMTY6CgkJYnVzX3BpY2tfY291bnQgPSAyOwoJCWJ1c19waWNrX3dpZHRoID0gMTY7CgkJYnJlYWs7CglkZWZhdWx0OgoJCUJVRygpOwoJCXJldHVybjsKCX0KCXNvc3NpLmJ1c19waWNrX3dpZHRoID0gYnVzX3BpY2tfd2lkdGg7Cglzb3NzaS5idXNfcGlja19jb3VudCA9IGJ1c19waWNrX2NvdW50Owp9CgpzdGF0aWMgaW50IHNvc3NpX3NldHVwX3RlYXJzeW5jKHVuc2lnbmVkIHBpbl9jbnQsCgkJCQl1bnNpZ25lZCBoc19wdWxzZV90aW1lLCB1bnNpZ25lZCB2c19wdWxzZV90aW1lLAoJCQkJaW50IGhzX3BvbF9pbnYsIGludCB2c19wb2xfaW52LCBpbnQgZGl2KQp7CglpbnQgaHMsIHZzOwoJdTMyIGw7CgoJaWYgKHBpbl9jbnQgIT0gMSB8fCBkaXYgPCAxIHx8IGRpdiA+IDgpCgkJcmV0dXJuIC1FSU5WQUw7CgoJaHMgPSBwc190b19zb3NzaV90aWNrcyhoc19wdWxzZV90aW1lLCBkaXYpOwoJdnMgPSBwc190b19zb3NzaV90aWNrcyh2c19wdWxzZV90aW1lLCBkaXYpOwoJaWYgKHZzIDwgOCB8fCB2cyA8PSBocyB8fCB2cyA+PSAoMSA8PCAxMikpCgkJcmV0dXJuIC1FRE9NOwoJdnMgLz0gODsKCXZzLS07CglpZiAoaHMgPiA4KQoJCWhzID0gODsKCWlmIChocykKCQlocy0tOwoKCWRldl9kYmcoc29zc2kuZmJkZXYtPmRldiwKCQkic2V0dXBfdGVhcnN5bmM6IGhzICVkIHZzICVkIGhzX2ludiAlZCB2c19pbnYgJWRcbiIsCgkJaHMsIHZzLCBoc19wb2xfaW52LCB2c19wb2xfaW52KTsKCgljbGtfZW5hYmxlKHNvc3NpLmZjayk7CglsID0gc29zc2lfcmVhZF9yZWcoU09TU0lfVEVBUklOR19SRUcpOwoJbCAmPSB+KCgxIDw8IDE1KSAtIDEpOwoJbCB8PSB2cyA8PCAzOwoJbCB8PSBoczsKCWlmIChoc19wb2xfaW52KQoJCWwgfD0gMSA8PCAyOTsKCWVsc2UKCQlsICY9IH4oMSA8PCAyOSk7CglpZiAodnNfcG9sX2ludikKCQlsIHw9IDEgPDwgMjg7CgllbHNlCgkJbCAmPSB+KDEgPDwgMjgpOwoJc29zc2lfd3JpdGVfcmVnKFNPU1NJX1RFQVJJTkdfUkVHLCBsKTsKCWNsa19kaXNhYmxlKHNvc3NpLmZjayk7CgoJcmV0dXJuIDA7Cn0KCnN0YXRpYyBpbnQgc29zc2lfZW5hYmxlX3RlYXJzeW5jKGludCBlbmFibGUsIHVuc2lnbmVkIGxpbmUpCnsKCWludCBtb2RlOwoKCWRldl9kYmcoc29zc2kuZmJkZXYtPmRldiwgInRlYXJzeW5jICVkIGxpbmUgJWRcbiIsIGVuYWJsZSwgbGluZSk7CglpZiAobGluZSA+PSAxIDw8IDExKQoJCXJldHVybiAtRUlOVkFMOwoJaWYgKGVuYWJsZSkgewoJCWlmIChsaW5lKQoJCQltb2RlID0gMjsJCS8qIEhTIG9yIFZTICovCgkJZWxzZQoJCQltb2RlID0gMzsJCS8qIFZTIG9ubHkgKi8KCX0gZWxzZQoJCW1vZGUgPSAwOwoJc29zc2kudGVhcnN5bmNfbGluZSA9IGxpbmU7Cglzb3NzaS50ZWFyc3luY19tb2RlID0gbW9kZTsKCglyZXR1cm4gMDsKfQoKc3RhdGljIHZvaWQgc29zc2lfd3JpdGVfY29tbWFuZChjb25zdCB2b2lkICpkYXRhLCB1bnNpZ25lZCBpbnQgbGVuKQp7CgljbGtfZW5hYmxlKHNvc3NpLmZjayk7CglzZXRfdGltaW5nKFdSX0FDQ0VTUyk7Cglfc2V0X2JpdHNfcGVyX2N5Y2xlKHNvc3NpLmJ1c19waWNrX2NvdW50LCBzb3NzaS5idXNfcGlja193aWR0aCk7CgkvKiBDTUQjL0RBVEEgKi8KCXNvc3NpX2NsZWFyX2JpdHMoU09TU0lfSU5JVDFfUkVHLCAxIDw8IDE4KTsKCXNldF9jeWNsZXMobGVuKTsKCXNvc3NpX3N0YXJ0X3RyYW5zZmVyKCk7CglzZW5kX2RhdGEoZGF0YSwgbGVuKTsKCXNvc3NpX3N0b3BfdHJhbnNmZXIoKTsKCXdhaXRfZW5kX29mX3dyaXRlKCk7CgljbGtfZGlzYWJsZShzb3NzaS5mY2spOwp9CgpzdGF0aWMgdm9pZCBzb3NzaV93cml0ZV9kYXRhKGNvbnN0IHZvaWQgKmRhdGEsIHVuc2lnbmVkIGludCBsZW4pCnsKCWNsa19lbmFibGUoc29zc2kuZmNrKTsKCXNldF90aW1pbmcoV1JfQUNDRVNTKTsKCV9zZXRfYml0c19wZXJfY3ljbGUoc29zc2kuYnVzX3BpY2tfY291bnQsIHNvc3NpLmJ1c19waWNrX3dpZHRoKTsKCS8qIENNRCMvREFUQSAqLwoJc29zc2lfc2V0X2JpdHMoU09TU0lfSU5JVDFfUkVHLCAxIDw8IDE4KTsKCXNldF9jeWNsZXMobGVuKTsKCXNvc3NpX3N0YXJ0X3RyYW5zZmVyKCk7CglzZW5kX2RhdGEoZGF0YSwgbGVuKTsKCXNvc3NpX3N0b3BfdHJhbnNmZXIoKTsKCXdhaXRfZW5kX29mX3dyaXRlKCk7CgljbGtfZGlzYWJsZShzb3NzaS5mY2spOwp9CgpzdGF0aWMgdm9pZCBzb3NzaV90cmFuc2Zlcl9hcmVhKGludCB3aWR0aCwgaW50IGhlaWdodCwKCQkJCXZvaWQgKGNhbGxiYWNrKSh2b2lkICpkYXRhKSwgdm9pZCAqZGF0YSkKewoJQlVHX09OKGNhbGxiYWNrID09IE5VTEwpOwoKCXNvc3NpLmxjZGNfY2FsbGJhY2sgPSBjYWxsYmFjazsKCXNvc3NpLmxjZGNfY2FsbGJhY2tfZGF0YSA9IGRhdGE7CgoJY2xrX2VuYWJsZShzb3NzaS5mY2spOwoJc2V0X3RpbWluZyhXUl9BQ0NFU1MpOwoJX3NldF9iaXRzX3Blcl9jeWNsZShzb3NzaS5idXNfcGlja19jb3VudCwgc29zc2kuYnVzX3BpY2tfd2lkdGgpOwoJX3NldF90ZWFyc3luY19tb2RlKHNvc3NpLnRlYXJzeW5jX21vZGUsIHNvc3NpLnRlYXJzeW5jX2xpbmUpOwoJLyogQ01EIy9EQVRBICovCglzb3NzaV9zZXRfYml0cyhTT1NTSV9JTklUMV9SRUcsIDEgPDwgMTgpOwoJc2V0X2N5Y2xlcyh3aWR0aCAqIGhlaWdodCAqIHNvc3NpLmJ1c19waWNrX3dpZHRoIC8gOCk7CgoJc29zc2lfc3RhcnRfdHJhbnNmZXIoKTsKCWlmIChzb3NzaS50ZWFyc3luY19tb2RlKSB7CgkJLyoKCQkgKiBXYWl0IGZvciB0aGUgc3luYyBzaWduYWwgYW5kIHN0YXJ0IHRoZSB0cmFuc2ZlciBvbmx5CgkJICogdGhlbi4gV2UgY2FuJ3Qgc2VlbSB0byBiZSBhYmxlIHRvIHVzZSBIVyBzeW5jIERNQSBmb3IKCQkgKiB0aGlzIHNpbmNlIExDRCBETUEgc2hvd3MgaHVnZSBsYXRlbmNpZXMsIGFzIGlmIGl0CgkJICogd291bGQgaWdub3JlIHNvbWUgb2YgdGhlIERNQSByZXF1ZXN0cyBmcm9tIFNvU1NJLgoJCSAqLwoJCXVuc2lnbmVkIGxvbmcgZmxhZ3M7CgoJCXNwaW5fbG9ja19pcnFzYXZlKCZzb3NzaS5sb2NrLCBmbGFncyk7CgkJc29zc2kudnN5bmNfZG1hX3BlbmRpbmcrKzsKCQlzcGluX3VubG9ja19pcnFyZXN0b3JlKCZzb3NzaS5sb2NrLCBmbGFncyk7Cgl9IGVsc2UKCQkvKiBKdXN0IHN0YXJ0IHRoZSB0cmFuc2ZlciByaWdodCBhd2F5LiAqLwoJCW9tYXBfZW5hYmxlX2xjZF9kbWEoKTsKfQoKc3RhdGljIHZvaWQgc29zc2lfZG1hX2NhbGxiYWNrKHZvaWQgKmRhdGEpCnsKCW9tYXBfc3RvcF9sY2RfZG1hKCk7Cglzb3NzaV9zdG9wX3RyYW5zZmVyKCk7CgljbGtfZGlzYWJsZShzb3NzaS5mY2spOwoJc29zc2kubGNkY19jYWxsYmFjayhzb3NzaS5sY2RjX2NhbGxiYWNrX2RhdGEpOwp9CgpzdGF0aWMgdm9pZCBzb3NzaV9yZWFkX2RhdGEodm9pZCAqZGF0YSwgdW5zaWduZWQgaW50IGxlbikKewoJY2xrX2VuYWJsZShzb3NzaS5mY2spOwoJc2V0X3RpbWluZyhSRF9BQ0NFU1MpOwoJX3NldF9iaXRzX3Blcl9jeWNsZShzb3NzaS5idXNfcGlja19jb3VudCwgc29zc2kuYnVzX3BpY2tfd2lkdGgpOwoJLyogQ01EIy9EQVRBICovCglzb3NzaV9zZXRfYml0cyhTT1NTSV9JTklUMV9SRUcsIDEgPDwgMTgpOwoJc2V0X2N5Y2xlcyhsZW4pOwoJc29zc2lfc3RhcnRfdHJhbnNmZXIoKTsKCXdoaWxlIChsZW4gPj0gNCkgewoJCSoodTMyICopIGRhdGEgPSBzb3NzaV9yZWFkX3JlZyhTT1NTSV9GSUZPX1JFRyk7CgkJbGVuIC09IDQ7CgkJZGF0YSArPSA0OwoJfQoJd2hpbGUgKGxlbiA+PSAyKSB7CgkJKih1MTYgKikgZGF0YSA9IHNvc3NpX3JlYWRfcmVnMTYoU09TU0lfRklGT19SRUcpOwoJCWxlbiAtPSAyOwoJCWRhdGEgKz0gMjsKCX0KCXdoaWxlIChsZW4pIHsKCQkqKHU4ICopIGRhdGEgPSBzb3NzaV9yZWFkX3JlZzgoU09TU0lfRklGT19SRUcpOwoJCWxlbi0tOwoJCWRhdGErKzsKCX0KCXNvc3NpX3N0b3BfdHJhbnNmZXIoKTsKCWNsa19kaXNhYmxlKHNvc3NpLmZjayk7Cn0KCnN0YXRpYyBpcnFyZXR1cm5fdCBzb3NzaV9tYXRjaF9pcnEoaW50IGlycSwgdm9pZCAqZGF0YSkKewoJdW5zaWduZWQgbG9uZyBmbGFnczsKCglzcGluX2xvY2tfaXJxc2F2ZSgmc29zc2kubG9jaywgZmxhZ3MpOwoJaWYgKHNvc3NpLnZzeW5jX2RtYV9wZW5kaW5nKSB7CgkJc29zc2kudnN5bmNfZG1hX3BlbmRpbmctLTsKCQlvbWFwX2VuYWJsZV9sY2RfZG1hKCk7Cgl9CglzcGluX3VubG9ja19pcnFyZXN0b3JlKCZzb3NzaS5sb2NrLCBmbGFncyk7CglyZXR1cm4gSVJRX0hBTkRMRUQ7Cn0KCnN0YXRpYyBpbnQgc29zc2lfaW5pdChzdHJ1Y3Qgb21hcGZiX2RldmljZSAqZmJkZXYpCnsKCXUzMiBsLCBrOwoJc3RydWN0IGNsayAqZmNrOwoJc3RydWN0IGNsayAqZHBsbDFvdXRfY2s7CglpbnQgcjsKCglzb3NzaS5iYXNlID0gaW9yZW1hcChPTUFQX1NPU1NJX0JBU0UsIFNaXzFLKTsKCWlmICghc29zc2kuYmFzZSkgewoJCWRldl9lcnIoZmJkZXYtPmRldiwgImNhbid0IGlvcmVtYXAgU29TU0lcbiIpOwoJCXJldHVybiAtRU5PTUVNOwoJfQoKCXNvc3NpLmZiZGV2ID0gZmJkZXY7CglzcGluX2xvY2tfaW5pdCgmc29zc2kubG9jayk7CgoJZHBsbDFvdXRfY2sgPSBjbGtfZ2V0KGZiZGV2LT5kZXYsICJja19kcGxsMW91dCIpOwoJaWYgKElTX0VSUihkcGxsMW91dF9jaykpIHsKCQlkZXZfZXJyKGZiZGV2LT5kZXYsICJjYW4ndCBnZXQgRFBMTDFPVVQgY2xvY2tcbiIpOwoJCXJldHVybiBQVFJfRVJSKGRwbGwxb3V0X2NrKTsKCX0KCS8qCgkgKiBXZSBuZWVkIHRoZSBwYXJlbnQgY2xvY2sgcmF0ZSwgd2hpY2ggd2UgbWlnaHQgZGl2aWRlIGZ1cnRoZXIKCSAqIGRlcGVuZGluZyBvbiB0aGUgdGltaW5nIHJlcXVpcmVtZW50cyBvZiB0aGUgY29udHJvbGxlci4gU2VlCgkgKiBfc2V0X3RpbWluZ3MuCgkgKi8KCXNvc3NpLmZja19oeiA9IGNsa19nZXRfcmF0ZShkcGxsMW91dF9jayk7CgljbGtfcHV0KGRwbGwxb3V0X2NrKTsKCglmY2sgPSBjbGtfZ2V0KGZiZGV2LT5kZXYsICJja19zb3NzaSIpOwoJaWYgKElTX0VSUihmY2spKSB7CgkJZGV2X2VycihmYmRldi0+ZGV2LCAiY2FuJ3QgZ2V0IFNvU1NJIGZ1bmN0aW9uYWwgY2xvY2tcbiIpOwoJCXJldHVybiBQVFJfRVJSKGZjayk7Cgl9Cglzb3NzaS5mY2sgPSBmY2s7CgoJLyogUmVzZXQgYW5kIGVuYWJsZSB0aGUgU29TU0kgbW9kdWxlICovCglsID0gb21hcF9yZWFkbChNT0RfQ09ORl9DVFJMXzEpOwoJbCB8PSBDT05GX1NPU1NJX1JFU0VUX1I7CglvbWFwX3dyaXRlbChsLCBNT0RfQ09ORl9DVFJMXzEpOwoJbCAmPSB+Q09ORl9TT1NTSV9SRVNFVF9SOwoJb21hcF93cml0ZWwobCwgTU9EX0NPTkZfQ1RSTF8xKTsKCgljbGtfZW5hYmxlKHNvc3NpLmZjayk7CglsID0gb21hcF9yZWFkbChBUk1fSURMRUNUMik7CglsICY9IH4oMSA8PCA4KTsJCQkvKiBETUFDS19SRVEgKi8KCW9tYXBfd3JpdGVsKGwsIEFSTV9JRExFQ1QyKTsKCglsID0gc29zc2lfcmVhZF9yZWcoU09TU0lfSU5JVDJfUkVHKTsKCS8qIEVuYWJsZSBhbmQgcmVzZXQgdGhlIFNvU1NJIGJsb2NrICovCglsIHw9ICgxIDw8IDApIHwgKDEgPDwgMSk7Cglzb3NzaV93cml0ZV9yZWcoU09TU0lfSU5JVDJfUkVHLCBsKTsKCS8qIFRha2UgU29TU0kgb3V0IG9mIHJlc2V0ICovCglsICY9IH4oMSA8PCAxKTsKCXNvc3NpX3dyaXRlX3JlZyhTT1NTSV9JTklUMl9SRUcsIGwpOwoKCXNvc3NpX3dyaXRlX3JlZyhTT1NTSV9JRF9SRUcsIDApOwoJbCA9IHNvc3NpX3JlYWRfcmVnKFNPU1NJX0lEX1JFRyk7CglrID0gc29zc2lfcmVhZF9yZWcoU09TU0lfSURfUkVHKTsKCglpZiAobCAhPSAweDU1NTU1NTU1IHx8IGsgIT0gMHhhYWFhYWFhYSkgewoJCWRldl9lcnIoZmJkZXYtPmRldiwKCQkJImludmFsaWQgU29TU0kgc3luYyBwYXR0ZXJuOiAlMDh4LCAlMDh4XG4iLCBsLCBrKTsKCQlyID0gLUVOT0RFVjsKCQlnb3RvIGVycjsKCX0KCglpZiAoKHIgPSBvbWFwX2xjZGNfc2V0X2RtYV9jYWxsYmFjayhzb3NzaV9kbWFfY2FsbGJhY2ssIE5VTEwpKSA8IDApIHsKCQlkZXZfZXJyKGZiZGV2LT5kZXYsICJjYW4ndCBnZXQgTENEQyBJUlFcbiIpOwoJCXIgPSAtRU5PREVWOwoJCWdvdG8gZXJyOwoJfQoKCWwgPSBzb3NzaV9yZWFkX3JlZyhTT1NTSV9JRF9SRUcpOyAvKiBDb21wb25lbnQgY29kZSAqLwoJbCA9IHNvc3NpX3JlYWRfcmVnKFNPU1NJX0lEX1JFRyk7CglkZXZfaW5mbyhmYmRldi0+ZGV2LCAiU29TU0kgdmVyc2lvbiAlZC4lZCBpbml0aWFsaXplZFxuIiwKCQlsID4+IDE2LCBsICYgMHhmZmZmKTsKCglsID0gc29zc2lfcmVhZF9yZWcoU09TU0lfSU5JVDFfUkVHKTsKCWwgfD0gKDEgPDwgMTkpOyAvKiBETUFfTU9ERSAqLwoJbCAmPSB+KDEgPDwgMzEpOyAvKiBSRU9SREVSSU5HICovCglzb3NzaV93cml0ZV9yZWcoU09TU0lfSU5JVDFfUkVHLCBsKTsKCglpZiAoKHIgPSByZXF1ZXN0X2lycShJTlRfMTYxMF9Tb1NTSV9NQVRDSCwgc29zc2lfbWF0Y2hfaXJxLAoJCQkgICAgIElSUV9UWVBFX0VER0VfRkFMTElORywKCSAgICAgInNvc3NpX21hdGNoIiwgc29zc2kuZmJkZXYtPmRldikpIDwgMCkgewoJCWRldl9lcnIoc29zc2kuZmJkZXYtPmRldiwgImNhbid0IGdldCBTb1NTSSBtYXRjaCBJUlFcbiIpOwoJCWdvdG8gZXJyOwoJfQoKCWNsa19kaXNhYmxlKHNvc3NpLmZjayk7CglyZXR1cm4gMDsKCmVycjoKCWNsa19kaXNhYmxlKHNvc3NpLmZjayk7CgljbGtfcHV0KHNvc3NpLmZjayk7CglyZXR1cm4gcjsKfQoKc3RhdGljIHZvaWQgc29zc2lfY2xlYW51cCh2b2lkKQp7CglvbWFwX2xjZGNfZnJlZV9kbWFfY2FsbGJhY2soKTsKCWNsa19wdXQoc29zc2kuZmNrKTsKCWlvdW5tYXAoc29zc2kuYmFzZSk7Cn0KCnN0cnVjdCBsY2RfY3RybF9leHRpZiBvbWFwMV9leHRfaWYgPSB7CgkuaW5pdAkJCT0gc29zc2lfaW5pdCwKCS5jbGVhbnVwCQk9IHNvc3NpX2NsZWFudXAsCgkuZ2V0X2Nsa19pbmZvCQk9IHNvc3NpX2dldF9jbGtfaW5mbywKCS5jb252ZXJ0X3RpbWluZ3MJPSBzb3NzaV9jb252ZXJ0X3RpbWluZ3MsCgkuc2V0X3RpbWluZ3MJCT0gc29zc2lfc2V0X3RpbWluZ3MsCgkuc2V0X2JpdHNfcGVyX2N5Y2xlCT0gc29zc2lfc2V0X2JpdHNfcGVyX2N5Y2xlLAoJLnNldHVwX3RlYXJzeW5jCQk9IHNvc3NpX3NldHVwX3RlYXJzeW5jLAoJLmVuYWJsZV90ZWFyc3luYwk9IHNvc3NpX2VuYWJsZV90ZWFyc3luYywKCS53cml0ZV9jb21tYW5kCQk9IHNvc3NpX3dyaXRlX2NvbW1hbmQsCgkucmVhZF9kYXRhCQk9IHNvc3NpX3JlYWRfZGF0YSwKCS53cml0ZV9kYXRhCQk9IHNvc3NpX3dyaXRlX2RhdGEsCgkudHJhbnNmZXJfYXJlYQkJPSBzb3NzaV90cmFuc2Zlcl9hcmVhLAoKCS5tYXhfdHJhbnNtaXRfc2l6ZQk9IFNPU1NJX01BWF9YTUlUX0JZVEVTLAp9OwoK