LyoKICogT01BUDIgUmVtb3RlIEZyYW1lIEJ1ZmZlciBJbnRlcmZhY2Ugc3VwcG9ydAogKgogKiBDb3B5cmlnaHQgKEMpIDIwMDUgTm9raWEgQ29ycG9yYXRpb24KICogQXV0aG9yOiBKdWhhIFlyavZs5CA8anVoYS55cmpvbGFAbm9raWEuY29tPgogKgkgICBJbXJlIERlYWsgPGltcmUuZGVha0Bub2tpYS5jb20+CiAqCiAqIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZQogKiBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlciB2ZXJzaW9uIDIgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyCiAqIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQKICogV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQogKiBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFsb25nCiAqIHdpdGggdGhpcyBwcm9ncmFtOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sIEluYy4sCiAqIDU5IFRlbXBsZSBQbGFjZSAtIFN1aXRlIDMzMCwgQm9zdG9uLCBNQSAgMDIxMTEtMTMwNywgVVNBLgogKi8KI2luY2x1ZGUgPGxpbnV4L21vZHVsZS5oPgojaW5jbHVkZSA8bGludXgvZGVsYXkuaD4KI2luY2x1ZGUgPGxpbnV4L2kyYy5oPgojaW5jbHVkZSA8bGludXgvZXJyLmg+CiNpbmNsdWRlIDxsaW51eC9pbnRlcnJ1cHQuaD4KI2luY2x1ZGUgPGxpbnV4L2Nsay5oPgojaW5jbHVkZSA8bGludXgvaW8uaD4KI2luY2x1ZGUgPGxpbnV4L3BsYXRmb3JtX2RldmljZS5oPgoKI2luY2x1ZGUgIm9tYXBmYi5oIgojaW5jbHVkZSAiZGlzcGMuaCIKCi8qIFRvIHdvcmsgYXJvdW5kIGFuIFJGQkkgdHJhbnNmZXIgcmF0ZSBsaW1pdGF0aW9uICovCiNkZWZpbmUgT01BUF9SRkJJX1JBVEVfTElNSVQJMQoKI2RlZmluZSBSRkJJX0JBU0UJCTB4NDgwNTA4MDAKI2RlZmluZSBSRkJJX1JFVklTSU9OCQkweDAwMDAKI2RlZmluZSBSRkJJX1NZU0NPTkZJRwkJMHgwMDEwCiNkZWZpbmUgUkZCSV9TWVNTVEFUVVMJCTB4MDAxNAojZGVmaW5lIFJGQklfQ09OVFJPTAkJMHgwMDQwCiNkZWZpbmUgUkZCSV9QSVhFTF9DTlQJCTB4MDA0NAojZGVmaW5lIFJGQklfTElORV9OVU1CRVIJMHgwMDQ4CiNkZWZpbmUgUkZCSV9DTUQJCTB4MDA0YwojZGVmaW5lIFJGQklfUEFSQU0JCTB4MDA1MAojZGVmaW5lIFJGQklfREFUQQkJMHgwMDU0CiNkZWZpbmUgUkZCSV9SRUFECQkweDAwNTgKI2RlZmluZSBSRkJJX1NUQVRVUwkJMHgwMDVjCiNkZWZpbmUgUkZCSV9DT05GSUcwCQkweDAwNjAKI2RlZmluZSBSRkJJX09OT0ZGX1RJTUUwCTB4MDA2NAojZGVmaW5lIFJGQklfQ1lDTEVfVElNRTAJMHgwMDY4CiNkZWZpbmUgUkZCSV9EQVRBX0NZQ0xFMV8wCTB4MDA2YwojZGVmaW5lIFJGQklfREFUQV9DWUNMRTJfMAkweDAwNzAKI2RlZmluZSBSRkJJX0RBVEFfQ1lDTEUzXzAJMHgwMDc0CiNkZWZpbmUgUkZCSV9WU1lOQ19XSURUSAkweDAwOTAKI2RlZmluZSBSRkJJX0hTWU5DX1dJRFRICTB4MDA5NAoKI2RlZmluZSBESVNQQ19CQVNFCQkweDQ4MDUwNDAwCiNkZWZpbmUgRElTUENfQ09OVFJPTAkJMHgwMDQwCiNkZWZpbmUgRElTUENfSVJRX0ZSQU1FTUFTSyAgICAgMHgwMDAxCgpzdGF0aWMgc3RydWN0IHsKCXZvaWQgX19pb21lbQkqYmFzZTsKCXZvaWQJCSgqbGNkY19jYWxsYmFjaykodm9pZCAqZGF0YSk7Cgl2b2lkCQkqbGNkY19jYWxsYmFja19kYXRhOwoJdW5zaWduZWQgbG9uZwlsNF9raHo7CglpbnQJCWJpdHNfcGVyX2N5Y2xlOwoJc3RydWN0IG9tYXBmYl9kZXZpY2UgKmZiZGV2OwoJc3RydWN0IGNsawkqZHNzX2ljazsKCXN0cnVjdCBjbGsJKmRzczFfZmNrOwoJdW5zaWduZWQJdGVhcnN5bmNfcGluX2NudDsKCXVuc2lnbmVkCXRlYXJzeW5jX21vZGU7Cn0gcmZiaTsKCnN0YXRpYyBpbmxpbmUgdm9pZCByZmJpX3dyaXRlX3JlZyhpbnQgaWR4LCB1MzIgdmFsKQp7CglfX3Jhd193cml0ZWwodmFsLCByZmJpLmJhc2UgKyBpZHgpOwp9CgpzdGF0aWMgaW5saW5lIHUzMiByZmJpX3JlYWRfcmVnKGludCBpZHgpCnsKCXJldHVybiBfX3Jhd19yZWFkbChyZmJpLmJhc2UgKyBpZHgpOwp9CgpzdGF0aWMgaW50IHJmYmlfZ2V0X2Nsb2Nrcyh2b2lkKQp7CglyZmJpLmRzc19pY2sgPSBjbGtfZ2V0KCZyZmJpLmZiZGV2LT5kc3NkZXYtPmRldiwgImljayIpOwoJaWYgKElTX0VSUihyZmJpLmRzc19pY2spKSB7CgkJZGV2X2VycihyZmJpLmZiZGV2LT5kZXYsICJjYW4ndCBnZXQgaWNrXG4iKTsKCQlyZXR1cm4gUFRSX0VSUihyZmJpLmRzc19pY2spOwoJfQoKCXJmYmkuZHNzMV9mY2sgPSBjbGtfZ2V0KCZyZmJpLmZiZGV2LT5kc3NkZXYtPmRldiwgImZjayIpOwoJaWYgKElTX0VSUihyZmJpLmRzczFfZmNrKSkgewoJCWRldl9lcnIocmZiaS5mYmRldi0+ZGV2LCAiY2FuJ3QgZ2V0IGRzczFfZmNrXG4iKTsKCQljbGtfcHV0KHJmYmkuZHNzX2ljayk7CgkJcmV0dXJuIFBUUl9FUlIocmZiaS5kc3MxX2Zjayk7Cgl9CgoJcmV0dXJuIDA7Cn0KCnN0YXRpYyB2b2lkIHJmYmlfcHV0X2Nsb2Nrcyh2b2lkKQp7CgljbGtfcHV0KHJmYmkuZHNzMV9mY2spOwoJY2xrX3B1dChyZmJpLmRzc19pY2spOwp9CgpzdGF0aWMgdm9pZCByZmJpX2VuYWJsZV9jbG9ja3MoaW50IGVuYWJsZSkKewoJaWYgKGVuYWJsZSkgewoJCWNsa19lbmFibGUocmZiaS5kc3NfaWNrKTsKCQljbGtfZW5hYmxlKHJmYmkuZHNzMV9mY2spOwoJfSBlbHNlIHsKCQljbGtfZGlzYWJsZShyZmJpLmRzczFfZmNrKTsKCQljbGtfZGlzYWJsZShyZmJpLmRzc19pY2spOwoJfQp9CgoKI2lmZGVmIFZFUkJPU0UKc3RhdGljIHZvaWQgcmZiaV9wcmludF90aW1pbmdzKHZvaWQpCnsKCXUzMiBsOwoJdTMyIHRpbWU7CgoJbCA9IHJmYmlfcmVhZF9yZWcoUkZCSV9DT05GSUcwKTsKCXRpbWUgPSAxMDAwMDAwMDAwIC8gcmZiaS5sNF9raHo7CglpZiAobCAmICgxIDw8IDQpKQoJCXRpbWUgKj0gMjsKCglkZXZfZGJnKHJmYmkuZmJkZXYtPmRldiwgIlRpY2sgdGltZSAldSBwc1xuIiwgdGltZSk7CglsID0gcmZiaV9yZWFkX3JlZyhSRkJJX09OT0ZGX1RJTUUwKTsKCWRldl9kYmcocmZiaS5mYmRldi0+ZGV2LAoJCSJDU09OVElNRSAlZCwgQ1NPRkZUSU1FICVkLCBXRU9OVElNRSAlZCwgV0VPRkZUSU1FICVkLCAiCgkJIlJFT05USU1FICVkLCBSRU9GRlRJTUUgJWRcbiIsCgkJbCAmIDB4MGYsIChsID4+IDQpICYgMHgzZiwgKGwgPj4gMTApICYgMHgwZiwgKGwgPj4gMTQpICYgMHgzZiwKCQkobCA+PiAyMCkgJiAweDBmLCAobCA+PiAyNCkgJiAweDNmKTsKCglsID0gcmZiaV9yZWFkX3JlZyhSRkJJX0NZQ0xFX1RJTUUwKTsKCWRldl9kYmcocmZiaS5mYmRldi0+ZGV2LAoJCSJXRUNZQ0xFVElNRSAlZCwgUkVDWUNMRVRJTUUgJWQsIENTUFVMU0VXSURUSCAlZCwgIgoJCSJBQ0NFU1NUSU1FICVkXG4iLAoJCShsICYgMHgzZiksIChsID4+IDYpICYgMHgzZiwgKGwgPj4gMTIpICYgMHgzZiwKCQkobCA+PiAyMikgJiAweDNmKTsKfQojZWxzZQpzdGF0aWMgdm9pZCByZmJpX3ByaW50X3RpbWluZ3Modm9pZCkge30KI2VuZGlmCgpzdGF0aWMgdm9pZCByZmJpX3NldF90aW1pbmdzKGNvbnN0IHN0cnVjdCBleHRpZl90aW1pbmdzICp0KQp7Cgl1MzIgbDsKCglCVUdfT04oIXQtPmNvbnZlcnRlZCk7CgoJcmZiaV9lbmFibGVfY2xvY2tzKDEpOwoJcmZiaV93cml0ZV9yZWcoUkZCSV9PTk9GRl9USU1FMCwgdC0+dGltWzBdKTsKCXJmYmlfd3JpdGVfcmVnKFJGQklfQ1lDTEVfVElNRTAsIHQtPnRpbVsxXSk7CgoJbCA9IHJmYmlfcmVhZF9yZWcoUkZCSV9DT05GSUcwKTsKCWwgJj0gfigxIDw8IDQpOwoJbCB8PSAodC0+dGltWzJdID8gMSA6IDApIDw8IDQ7CglyZmJpX3dyaXRlX3JlZyhSRkJJX0NPTkZJRzAsIGwpOwoKCXJmYmlfcHJpbnRfdGltaW5ncygpOwoJcmZiaV9lbmFibGVfY2xvY2tzKDApOwp9CgpzdGF0aWMgdm9pZCByZmJpX2dldF9jbGtfaW5mbyh1MzIgKmNsa19wZXJpb2QsIHUzMiAqbWF4X2Nsa19kaXYpCnsKCSpjbGtfcGVyaW9kID0gMTAwMDAwMDAwMCAvIHJmYmkubDRfa2h6OwoJKm1heF9jbGtfZGl2ID0gMjsKfQoKc3RhdGljIGludCBwc190b19yZmJpX3RpY2tzKGludCB0aW1lLCBpbnQgZGl2KQp7Cgl1bnNpZ25lZCBsb25nIHRpY2tfcHM7CglpbnQgcmV0OwoKCS8qIENhbGN1bGF0ZSBpbiBwaWNvc2VjcyB0byB5aWVsZCBtb3JlIGV4YWN0IHJlc3VsdHMgKi8KCXRpY2tfcHMgPSAxMDAwMDAwMDAwIC8gKHJmYmkubDRfa2h6KSAqIGRpdjsKCglyZXQgPSAodGltZSArIHRpY2tfcHMgLSAxKSAvIHRpY2tfcHM7CgoJcmV0dXJuIHJldDsKfQoKI2lmZGVmIE9NQVBfUkZCSV9SQVRFX0xJTUlUCnN0YXRpYyB1bnNpZ25lZCBsb25nIHJmYmlfZ2V0X21heF90eF9yYXRlKHZvaWQpCnsKCXVuc2lnbmVkIGxvbmcJbDRfcmF0ZSwgZHNzMV9yYXRlOwoJaW50CQltaW5fbDRfdGlja3MgPSAwOwoJaW50CQlpOwoKCS8qIEFjY29yZGluZyB0byBUSSB0aGlzIGNhbid0IGJlIGNhbGN1bGF0ZWQgc28gbWFrZSB0aGUKCSAqIGFkanVzdG1lbnRzIGZvciBhIGNvdXBsZSBvZiBrbm93biBmcmVxdWVuY2llcyBhbmQgd2FybiBmb3IKCSAqIG90aGVycy4KCSAqLwoJc3RhdGljIGNvbnN0IHN0cnVjdCB7CgkJdW5zaWduZWQgbG9uZyBsNF9jbGs7CQkvKiBIWiAqLwoJCXVuc2lnbmVkIGxvbmcgZHNzMV9jbGs7CQkvKiBIWiAqLwoJCXVuc2lnbmVkIGxvbmcgbWluX2w0X3RpY2tzOwoJfSBmdGFiW10gPSB7CgkJeyA1NSwJMTMyLAk3LCB9LAkJLyogNy44NiBNUGl4L3MgKi8KCQl7IDExMCwJMTEwLAkxMiwgfSwJCS8qIDkuMTYgTVBpeC9zICovCgkJeyAxMTAsCTEzMiwJMTAsIH0sCQkvKiAxMSAgIE1waXgvcyAqLwoJCXsgMTIwLAkxMjAsCTEwLCB9LAkJLyogMTIgICBNcGl4L3MgKi8KCQl7IDEzMywJMTMzLAkxMCwgfSwJCS8qIDEzLjMgTXBpeC9zICovCgl9OwoKCWw0X3JhdGUgPSByZmJpLmw0X2toeiAvIDEwMDA7Cglkc3MxX3JhdGUgPSBjbGtfZ2V0X3JhdGUocmZiaS5kc3MxX2ZjaykgLyAxMDAwMDAwOwoKCWZvciAoaSA9IDA7IGkgPCBBUlJBWV9TSVpFKGZ0YWIpOyBpKyspIHsKCQkvKiBVc2UgYSB3aW5kb3cgaW5zdGVhZCBvZiBhbiBleGFjdCBtYXRjaCwgdG8gYWNjb3VudAoJCSAqIGZvciBkaWZmZXJlbnQgRFBMTCBtdWx0aXBsaWVyIC8gZGl2aWRlciBwYWlycy4KCQkgKi8KCQlpZiAoYWJzKGZ0YWJbaV0ubDRfY2xrIC0gbDRfcmF0ZSkgPCAzICYmCgkJICAgIGFicyhmdGFiW2ldLmRzczFfY2xrIC0gZHNzMV9yYXRlKSA8IDMpIHsKCQkJbWluX2w0X3RpY2tzID0gZnRhYltpXS5taW5fbDRfdGlja3M7CgkJCWJyZWFrOwoJCX0KCX0KCWlmIChpID09IEFSUkFZX1NJWkUoZnRhYikpIHsKCQkvKiBDYW4ndCBiZSBzdXJlLCByZXR1cm4gYW55d2F5IHRoZSBtYXhpbXVtIG5vdAoJCSAqIHJhdGUtbGltaXRlZC4gVGhpcyBtaWdodCBjYXVzZSBhIHByb2JsZW0gb25seSBmb3IgdGhlCgkJICogdGVhcmluZyBzeW5jaHJvbmlzYXRpb24uCgkJICovCgkJZGV2X2VycihyZmJpLmZiZGV2LT5kZXYsCgkJCSJjYW4ndCBkZXRlcm1pbmUgbWF4aW11bSBSRkJJIHRyYW5zZmVyIHJhdGVcbiIpOwoJCXJldHVybiByZmJpLmw0X2toeiAqIDEwMDA7Cgl9CglyZXR1cm4gcmZiaS5sNF9raHogKiAxMDAwIC8gbWluX2w0X3RpY2tzOwp9CiNlbHNlCnN0YXRpYyBpbnQgcmZiaV9nZXRfbWF4X3R4X3JhdGUodm9pZCkKewoJcmV0dXJuIHJmYmkubDRfa2h6ICogMTAwMDsKfQojZW5kaWYKCgpzdGF0aWMgaW50IHJmYmlfY29udmVydF90aW1pbmdzKHN0cnVjdCBleHRpZl90aW1pbmdzICp0KQp7Cgl1MzIgbDsKCWludCByZW9uLCByZW9mZiwgd2Vvbiwgd2VvZmYsIGNzb24sIGNzb2ZmLCBjc19wdWxzZTsKCWludCBhY3RpbSwgcmVjeWMsIHdlY3ljOwoJaW50IGRpdiA9IHQtPmNsa19kaXY7CgoJaWYgKGRpdiA8PSAwIHx8IGRpdiA+IDIpCgkJcmV0dXJuIC0xOwoKCS8qIE1ha2Ugc3VyZSB0aGF0IGFmdGVyIGNvbnZlcnNpb24gaXQgc3RpbGwgaG9sZHMgdGhhdDoKCSAqIHdlb2ZmID4gd2VvbiwgcmVvZmYgPiByZW9uLCByZWN5YyA+PSByZW9mZiwgd2VjeWMgPj0gd2VvZmYsCgkgKiBjc29mZiA+IGNzb24sIGNzb2ZmID49IG1heCh3ZW9mZiwgcmVvZmYpLCBhY3RpbSA+IHJlb24KCSAqLwoJd2VvbiA9IHBzX3RvX3JmYmlfdGlja3ModC0+d2Vfb25fdGltZSwgZGl2KTsKCXdlb2ZmID0gcHNfdG9fcmZiaV90aWNrcyh0LT53ZV9vZmZfdGltZSwgZGl2KTsKCWlmICh3ZW9mZiA8PSB3ZW9uKQoJCXdlb2ZmID0gd2VvbiArIDE7CglpZiAod2VvbiA+IDB4MGYpCgkJcmV0dXJuIC0xOwoJaWYgKHdlb2ZmID4gMHgzZikKCQlyZXR1cm4gLTE7CgoJcmVvbiA9IHBzX3RvX3JmYmlfdGlja3ModC0+cmVfb25fdGltZSwgZGl2KTsKCXJlb2ZmID0gcHNfdG9fcmZiaV90aWNrcyh0LT5yZV9vZmZfdGltZSwgZGl2KTsKCWlmIChyZW9mZiA8PSByZW9uKQoJCXJlb2ZmID0gcmVvbiArIDE7CglpZiAocmVvbiA+IDB4MGYpCgkJcmV0dXJuIC0xOwoJaWYgKHJlb2ZmID4gMHgzZikKCQlyZXR1cm4gLTE7CgoJY3NvbiA9IHBzX3RvX3JmYmlfdGlja3ModC0+Y3Nfb25fdGltZSwgZGl2KTsKCWNzb2ZmID0gcHNfdG9fcmZiaV90aWNrcyh0LT5jc19vZmZfdGltZSwgZGl2KTsKCWlmIChjc29mZiA8PSBjc29uKQoJCWNzb2ZmID0gY3NvbiArIDE7CglpZiAoY3NvZmYgPCBtYXgod2VvZmYsIHJlb2ZmKSkKCQljc29mZiA9IG1heCh3ZW9mZiwgcmVvZmYpOwoJaWYgKGNzb24gPiAweDBmKQoJCXJldHVybiAtMTsKCWlmIChjc29mZiA+IDB4M2YpCgkJcmV0dXJuIC0xOwoKCWwgPSAgY3NvbjsKCWwgfD0gY3NvZmYgPDwgNDsKCWwgfD0gd2VvbiAgPDwgMTA7CglsIHw9IHdlb2ZmIDw8IDE0OwoJbCB8PSByZW9uICA8PCAyMDsKCWwgfD0gcmVvZmYgPDwgMjQ7CgoJdC0+dGltWzBdID0gbDsKCglhY3RpbSA9IHBzX3RvX3JmYmlfdGlja3ModC0+YWNjZXNzX3RpbWUsIGRpdik7CglpZiAoYWN0aW0gPD0gcmVvbikKCQlhY3RpbSA9IHJlb24gKyAxOwoJaWYgKGFjdGltID4gMHgzZikKCQlyZXR1cm4gLTE7CgoJd2VjeWMgPSBwc190b19yZmJpX3RpY2tzKHQtPndlX2N5Y2xlX3RpbWUsIGRpdik7CglpZiAod2VjeWMgPCB3ZW9mZikKCQl3ZWN5YyA9IHdlb2ZmOwoJaWYgKHdlY3ljID4gMHgzZikKCQlyZXR1cm4gLTE7CgoJcmVjeWMgPSBwc190b19yZmJpX3RpY2tzKHQtPnJlX2N5Y2xlX3RpbWUsIGRpdik7CglpZiAocmVjeWMgPCByZW9mZikKCQlyZWN5YyA9IHJlb2ZmOwoJaWYgKHJlY3ljID4gMHgzZikKCQlyZXR1cm4gLTE7CgoJY3NfcHVsc2UgPSBwc190b19yZmJpX3RpY2tzKHQtPmNzX3B1bHNlX3dpZHRoLCBkaXYpOwoJaWYgKGNzX3B1bHNlID4gMHgzZikKCQlyZXR1cm4gLTE7CgoJbCA9ICB3ZWN5YzsKCWwgfD0gcmVjeWMgICAgPDwgNjsKCWwgfD0gY3NfcHVsc2UgPDwgMTI7CglsIHw9IGFjdGltICAgIDw8IDIyOwoKCXQtPnRpbVsxXSA9IGw7CgoJdC0+dGltWzJdID0gZGl2IC0gMTsKCgl0LT5jb252ZXJ0ZWQgPSAxOwoKCXJldHVybiAwOwp9CgpzdGF0aWMgaW50IHJmYmlfc2V0dXBfdGVhcnN5bmModW5zaWduZWQgcGluX2NudCwKCQkJICAgICAgIHVuc2lnbmVkIGhzX3B1bHNlX3RpbWUsIHVuc2lnbmVkIHZzX3B1bHNlX3RpbWUsCgkJCSAgICAgICBpbnQgaHNfcG9sX2ludiwgaW50IHZzX3BvbF9pbnYsIGludCBleHRpZl9kaXYpCnsKCWludCBocywgdnM7CglpbnQgbWluOwoJdTMyIGw7CgoJaWYgKHBpbl9jbnQgIT0gMSAmJiBwaW5fY250ICE9IDIpCgkJcmV0dXJuIC1FSU5WQUw7CgoJaHMgPSBwc190b19yZmJpX3RpY2tzKGhzX3B1bHNlX3RpbWUsIDEpOwoJdnMgPSBwc190b19yZmJpX3RpY2tzKHZzX3B1bHNlX3RpbWUsIDEpOwoJaWYgKGhzIDwgMikKCQlyZXR1cm4gLUVET007CglpZiAocGluX2NudCA9PSAyKQoJCW1pbiA9IDI7CgllbHNlCgkJbWluID0gNDsKCWlmICh2cyA8IG1pbikKCQlyZXR1cm4gLUVET007CglpZiAodnMgPT0gaHMpCgkJcmV0dXJuIC1FSU5WQUw7CglyZmJpLnRlYXJzeW5jX3Bpbl9jbnQgPSBwaW5fY250OwoJZGV2X2RiZyhyZmJpLmZiZGV2LT5kZXYsCgkJInNldHVwX3RlYXJzeW5jOiBwaW5zICVkIGhzICVkIHZzICVkIGhzX2ludiAlZCB2c19pbnYgJWRcbiIsCgkJcGluX2NudCwgaHMsIHZzLCBoc19wb2xfaW52LCB2c19wb2xfaW52KTsKCglyZmJpX2VuYWJsZV9jbG9ja3MoMSk7CglyZmJpX3dyaXRlX3JlZyhSRkJJX0hTWU5DX1dJRFRILCBocyk7CglyZmJpX3dyaXRlX3JlZyhSRkJJX1ZTWU5DX1dJRFRILCB2cyk7CgoJbCA9IHJmYmlfcmVhZF9yZWcoUkZCSV9DT05GSUcwKTsKCWlmIChoc19wb2xfaW52KQoJCWwgJj0gfigxIDw8IDIxKTsKCWVsc2UKCQlsIHw9IDEgPDwgMjE7CglpZiAodnNfcG9sX2ludikKCQlsICY9IH4oMSA8PCAyMCk7CgllbHNlCgkJbCB8PSAxIDw8IDIwOwoJcmZiaV9lbmFibGVfY2xvY2tzKDApOwoKCXJldHVybiAwOwp9CgpzdGF0aWMgaW50IHJmYmlfZW5hYmxlX3RlYXJzeW5jKGludCBlbmFibGUsIHVuc2lnbmVkIGxpbmUpCnsKCXUzMiBsOwoKCWRldl9kYmcocmZiaS5mYmRldi0+ZGV2LCAidGVhcnN5bmMgJWQgbGluZSAlZCBtb2RlICVkXG4iLAoJCWVuYWJsZSwgbGluZSwgcmZiaS50ZWFyc3luY19tb2RlKTsKCWlmIChsaW5lID4gKDEgPDwgMTEpIC0gMSkKCQlyZXR1cm4gLUVJTlZBTDsKCglyZmJpX2VuYWJsZV9jbG9ja3MoMSk7CglsID0gcmZiaV9yZWFkX3JlZyhSRkJJX0NPTkZJRzApOwoJbCAmPSB+KDB4MyA8PCAyKTsKCWlmIChlbmFibGUpIHsKCQlyZmJpLnRlYXJzeW5jX21vZGUgPSByZmJpLnRlYXJzeW5jX3Bpbl9jbnQ7CgkJbCB8PSByZmJpLnRlYXJzeW5jX21vZGUgPDwgMjsKCX0gZWxzZQoJCXJmYmkudGVhcnN5bmNfbW9kZSA9IDA7CglyZmJpX3dyaXRlX3JlZyhSRkJJX0NPTkZJRzAsIGwpOwoJcmZiaV93cml0ZV9yZWcoUkZCSV9MSU5FX05VTUJFUiwgbGluZSk7CglyZmJpX2VuYWJsZV9jbG9ja3MoMCk7CgoJcmV0dXJuIDA7Cn0KCnN0YXRpYyB2b2lkIHJmYmlfd3JpdGVfY29tbWFuZChjb25zdCB2b2lkICpidWYsIHVuc2lnbmVkIGludCBsZW4pCnsKCXJmYmlfZW5hYmxlX2Nsb2NrcygxKTsKCWlmIChyZmJpLmJpdHNfcGVyX2N5Y2xlID09IDE2KSB7CgkJY29uc3QgdTE2ICp3ID0gYnVmOwoJCUJVR19PTihsZW4gJiAxKTsKCQlmb3IgKDsgbGVuOyBsZW4gLT0gMikKCQkJcmZiaV93cml0ZV9yZWcoUkZCSV9DTUQsICp3KyspOwoJfSBlbHNlIHsKCQljb25zdCB1OCAqYiA9IGJ1ZjsKCQlCVUdfT04ocmZiaS5iaXRzX3Blcl9jeWNsZSAhPSA4KTsKCQlmb3IgKDsgbGVuOyBsZW4tLSkKCQkJcmZiaV93cml0ZV9yZWcoUkZCSV9DTUQsICpiKyspOwoJfQoJcmZiaV9lbmFibGVfY2xvY2tzKDApOwp9CgpzdGF0aWMgdm9pZCByZmJpX3JlYWRfZGF0YSh2b2lkICpidWYsIHVuc2lnbmVkIGludCBsZW4pCnsKCXJmYmlfZW5hYmxlX2Nsb2NrcygxKTsKCWlmIChyZmJpLmJpdHNfcGVyX2N5Y2xlID09IDE2KSB7CgkJdTE2ICp3ID0gYnVmOwoJCUJVR19PTihsZW4gJiB+MSk7CgkJZm9yICg7IGxlbjsgbGVuIC09IDIpIHsKCQkJcmZiaV93cml0ZV9yZWcoUkZCSV9SRUFELCAwKTsKCQkJKncrKyA9IHJmYmlfcmVhZF9yZWcoUkZCSV9SRUFEKTsKCQl9Cgl9IGVsc2UgewoJCXU4ICpiID0gYnVmOwoJCUJVR19PTihyZmJpLmJpdHNfcGVyX2N5Y2xlICE9IDgpOwoJCWZvciAoOyBsZW47IGxlbi0tKSB7CgkJCXJmYmlfd3JpdGVfcmVnKFJGQklfUkVBRCwgMCk7CgkJCSpiKysgPSByZmJpX3JlYWRfcmVnKFJGQklfUkVBRCk7CgkJfQoJfQoJcmZiaV9lbmFibGVfY2xvY2tzKDApOwp9CgpzdGF0aWMgdm9pZCByZmJpX3dyaXRlX2RhdGEoY29uc3Qgdm9pZCAqYnVmLCB1bnNpZ25lZCBpbnQgbGVuKQp7CglyZmJpX2VuYWJsZV9jbG9ja3MoMSk7CglpZiAocmZiaS5iaXRzX3Blcl9jeWNsZSA9PSAxNikgewoJCWNvbnN0IHUxNiAqdyA9IGJ1ZjsKCQlCVUdfT04obGVuICYgMSk7CgkJZm9yICg7IGxlbjsgbGVuIC09IDIpCgkJCXJmYmlfd3JpdGVfcmVnKFJGQklfUEFSQU0sICp3KyspOwoJfSBlbHNlIHsKCQljb25zdCB1OCAqYiA9IGJ1ZjsKCQlCVUdfT04ocmZiaS5iaXRzX3Blcl9jeWNsZSAhPSA4KTsKCQlmb3IgKDsgbGVuOyBsZW4tLSkKCQkJcmZiaV93cml0ZV9yZWcoUkZCSV9QQVJBTSwgKmIrKyk7Cgl9CglyZmJpX2VuYWJsZV9jbG9ja3MoMCk7Cn0KCnN0YXRpYyB2b2lkIHJmYmlfdHJhbnNmZXJfYXJlYShpbnQgd2lkdGgsIGludCBoZWlnaHQsCgkJCQl2b2lkIChjYWxsYmFjaykodm9pZCAqIGRhdGEpLCB2b2lkICpkYXRhKQp7Cgl1MzIgdzsKCglCVUdfT04oY2FsbGJhY2sgPT0gTlVMTCk7CgoJcmZiaV9lbmFibGVfY2xvY2tzKDEpOwoJb21hcF9kaXNwY19zZXRfbGNkX3NpemUod2lkdGgsIGhlaWdodCk7CgoJcmZiaS5sY2RjX2NhbGxiYWNrID0gY2FsbGJhY2s7CglyZmJpLmxjZGNfY2FsbGJhY2tfZGF0YSA9IGRhdGE7CgoJcmZiaV93cml0ZV9yZWcoUkZCSV9QSVhFTF9DTlQsIHdpZHRoICogaGVpZ2h0KTsKCgl3ID0gcmZiaV9yZWFkX3JlZyhSRkJJX0NPTlRST0wpOwoJdyB8PSAxOwkJCQkvKiBlbmFibGUgKi8KCWlmICghcmZiaS50ZWFyc3luY19tb2RlKQoJCXcgfD0gMSA8PCA0OwkJLyogaW50ZXJuYWwgdHJpZ2dlciwgcmVzZXQgYnkgSFcgKi8KCXJmYmlfd3JpdGVfcmVnKFJGQklfQ09OVFJPTCwgdyk7CgoJb21hcF9kaXNwY19lbmFibGVfbGNkX291dCgxKTsKfQoKc3RhdGljIGlubGluZSB2b2lkIF9zdG9wX3RyYW5zZmVyKHZvaWQpCnsKCXUzMiB3OwoKCXcgPSByZmJpX3JlYWRfcmVnKFJGQklfQ09OVFJPTCk7CglyZmJpX3dyaXRlX3JlZyhSRkJJX0NPTlRST0wsIHcgJiB+KDEgPDwgMCkpOwoJcmZiaV9lbmFibGVfY2xvY2tzKDApOwp9CgpzdGF0aWMgdm9pZCByZmJpX2RtYV9jYWxsYmFjayh2b2lkICpkYXRhKQp7Cglfc3RvcF90cmFuc2ZlcigpOwoJcmZiaS5sY2RjX2NhbGxiYWNrKHJmYmkubGNkY19jYWxsYmFja19kYXRhKTsKfQoKc3RhdGljIHZvaWQgcmZiaV9zZXRfYml0c19wZXJfY3ljbGUoaW50IGJwYykKewoJdTMyIGw7CgoJcmZiaV9lbmFibGVfY2xvY2tzKDEpOwoJbCA9IHJmYmlfcmVhZF9yZWcoUkZCSV9DT05GSUcwKTsKCWwgJj0gfigweDAzIDw8IDApOwoKCXN3aXRjaCAoYnBjKSB7CgljYXNlIDg6CgkJYnJlYWs7CgljYXNlIDE2OgoJCWwgfD0gMzsKCQlicmVhazsKCWRlZmF1bHQ6CgkJQlVHKCk7Cgl9CglyZmJpX3dyaXRlX3JlZyhSRkJJX0NPTkZJRzAsIGwpOwoJcmZiaS5iaXRzX3Blcl9jeWNsZSA9IGJwYzsKCXJmYmlfZW5hYmxlX2Nsb2NrcygwKTsKfQoKc3RhdGljIGludCByZmJpX2luaXQoc3RydWN0IG9tYXBmYl9kZXZpY2UgKmZiZGV2KQp7Cgl1MzIgbDsKCWludCByOwoKCXJmYmkuZmJkZXYgPSBmYmRldjsKCXJmYmkuYmFzZSA9IGlvcmVtYXAoUkZCSV9CQVNFLCBTWl8xSyk7CglpZiAoIXJmYmkuYmFzZSkgewoJCWRldl9lcnIoZmJkZXYtPmRldiwgImNhbid0IGlvcmVtYXAgUkZCSVxuIik7CgkJcmV0dXJuIC1FTk9NRU07Cgl9CgoJaWYgKChyID0gcmZiaV9nZXRfY2xvY2tzKCkpIDwgMCkKCQlyZXR1cm4gcjsKCXJmYmlfZW5hYmxlX2Nsb2NrcygxKTsKCglyZmJpLmw0X2toeiA9IGNsa19nZXRfcmF0ZShyZmJpLmRzc19pY2spIC8gMTAwMDsKCgkvKiBSZXNldCAqLwoJcmZiaV93cml0ZV9yZWcoUkZCSV9TWVNDT05GSUcsIDEgPDwgMSk7Cgl3aGlsZSAoIShyZmJpX3JlYWRfcmVnKFJGQklfU1lTU1RBVFVTKSAmICgxIDw8IDApKSk7CgoJbCA9IHJmYmlfcmVhZF9yZWcoUkZCSV9TWVNDT05GSUcpOwoJLyogRW5hYmxlIGF1dG9pZGxlIGFuZCBzbWFydC1pZGxlICovCglsIHw9ICgxIDw8IDApIHwgKDIgPDwgMyk7CglyZmJpX3dyaXRlX3JlZyhSRkJJX1NZU0NPTkZJRywgbCk7CgoJLyogMTYtYml0IGludGVyZmFjZSwgSVRFIHRyaWdnZXIgbW9kZSwgMTYtYml0IGRhdGEgKi8KCWwgPSAoMHgwMyA8PCAwKSB8ICgweDAwIDw8IDIpIHwgKDB4MDEgPDwgNSkgfCAoMHgwMiA8PCA3KTsKCWwgfD0gKDAgPDwgOSkgfCAoMSA8PCAyMCkgfCAoMSA8PCAyMSk7CglyZmJpX3dyaXRlX3JlZyhSRkJJX0NPTkZJRzAsIGwpOwoKCXJmYmlfd3JpdGVfcmVnKFJGQklfREFUQV9DWUNMRTFfMCwgMHgwMDAwMDAxMCk7CgoJbCA9IHJmYmlfcmVhZF9yZWcoUkZCSV9DT05UUk9MKTsKCS8qIFNlbGVjdCBDUzAsIGNsZWFyIGJ5cGFzcyBtb2RlICovCglsID0gKDB4MDEgPDwgMik7CglyZmJpX3dyaXRlX3JlZyhSRkJJX0NPTlRST0wsIGwpOwoKCXIgPSBvbWFwX2Rpc3BjX3JlcXVlc3RfaXJxKERJU1BDX0lSUV9GUkFNRU1BU0ssIHJmYmlfZG1hX2NhbGxiYWNrLAoJCQkJICAgTlVMTCk7CglpZiAociA8IDApIHsKCQlkZXZfZXJyKGZiZGV2LT5kZXYsICJjYW4ndCBnZXQgRElTUEMgaXJxXG4iKTsKCQlyZmJpX2VuYWJsZV9jbG9ja3MoMCk7CgkJcmV0dXJuIHI7Cgl9CgoJbCA9IHJmYmlfcmVhZF9yZWcoUkZCSV9SRVZJU0lPTik7Cglwcl9pbmZvKCJvbWFwZmI6IFJGQkkgdmVyc2lvbiAlZC4lZCBpbml0aWFsaXplZFxuIiwKCQkobCA+PiA0KSAmIDB4MGYsIGwgJiAweDBmKTsKCglyZmJpX2VuYWJsZV9jbG9ja3MoMCk7CgoJcmV0dXJuIDA7Cn0KCnN0YXRpYyB2b2lkIHJmYmlfY2xlYW51cCh2b2lkKQp7CglvbWFwX2Rpc3BjX2ZyZWVfaXJxKERJU1BDX0lSUV9GUkFNRU1BU0ssIHJmYmlfZG1hX2NhbGxiYWNrLCBOVUxMKTsKCXJmYmlfcHV0X2Nsb2NrcygpOwoJaW91bm1hcChyZmJpLmJhc2UpOwp9Cgpjb25zdCBzdHJ1Y3QgbGNkX2N0cmxfZXh0aWYgb21hcDJfZXh0X2lmID0gewoJLmluaXQJCQk9IHJmYmlfaW5pdCwKCS5jbGVhbnVwCQk9IHJmYmlfY2xlYW51cCwKCS5nZXRfY2xrX2luZm8JCT0gcmZiaV9nZXRfY2xrX2luZm8sCgkuZ2V0X21heF90eF9yYXRlCT0gcmZiaV9nZXRfbWF4X3R4X3JhdGUsCgkuc2V0X2JpdHNfcGVyX2N5Y2xlCT0gcmZiaV9zZXRfYml0c19wZXJfY3ljbGUsCgkuY29udmVydF90aW1pbmdzCT0gcmZiaV9jb252ZXJ0X3RpbWluZ3MsCgkuc2V0X3RpbWluZ3MJCT0gcmZiaV9zZXRfdGltaW5ncywKCS53cml0ZV9jb21tYW5kCQk9IHJmYmlfd3JpdGVfY29tbWFuZCwKCS5yZWFkX2RhdGEJCT0gcmZiaV9yZWFkX2RhdGEsCgkud3JpdGVfZGF0YQkJPSByZmJpX3dyaXRlX2RhdGEsCgkudHJhbnNmZXJfYXJlYQkJPSByZmJpX3RyYW5zZmVyX2FyZWEsCgkuc2V0dXBfdGVhcnN5bmMJCT0gcmZiaV9zZXR1cF90ZWFyc3luYywKCS5lbmFibGVfdGVhcnN5bmMJPSByZmJpX2VuYWJsZV90ZWFyc3luYywKCgkubWF4X3RyYW5zbWl0X3NpemUJPSAodTMyKSB+MCwKfTsKCg==