LyoKICogJElkOiBkYjkuYyx2IDEuMTMgMjAwMi8wNC8wNyAyMDoxMzozNyB2b2p0ZWNoIEV4cCAkCiAqCiAqICBDb3B5cmlnaHQgKGMpIDE5OTktMjAwMSBWb2p0ZWNoIFBhdmxpawogKgogKiAgQmFzZWQgb24gdGhlIHdvcmsgb2Y6CiAqCUFuZHJlZSBCb3JybWFubgkJTWF0cyBTavZ2YWxsCiAqLwoKLyoKICogQXRhcmksIEFtc3RyYWQsIENvbW1vZG9yZSwgQW1pZ2EsIFNlZ2EsIGV0Yy4gam95c3RpY2sgZHJpdmVyIGZvciBMaW51eAogKi8KCi8qCiAqIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5CiAqIGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5CiAqIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlciB2ZXJzaW9uIDIgb2YgdGhlIExpY2Vuc2UsIG9yCiAqIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlCiAqIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIGFsb25nIHdpdGggdGhpcyBwcm9ncmFtOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDU5IFRlbXBsZSBQbGFjZSwgU3VpdGUgMzMwLCBCb3N0b24sIE1BIDAyMTExLTEzMDcgVVNBCiAqCiAqIFNob3VsZCB5b3UgbmVlZCB0byBjb250YWN0IG1lLCB0aGUgYXV0aG9yLCB5b3UgY2FuIGRvIHNvIGVpdGhlciBieQogKiBlLW1haWwgLSBtYWlsIHlvdXIgbWVzc2FnZSB0byA8dm9qdGVjaEB1Y3cuY3o+LCBvciBieSBwYXBlciBtYWlsOgogKiBWb2p0ZWNoIFBhdmxpaywgU2ltdW5rb3ZhIDE1OTQsIFByYWd1ZSA4LCAxODIgMDAgQ3plY2ggUmVwdWJsaWMKICovCgojaW5jbHVkZSA8bGludXgva2VybmVsLmg+CiNpbmNsdWRlIDxsaW51eC9tb2R1bGUuaD4KI2luY2x1ZGUgPGxpbnV4L21vZHVsZXBhcmFtLmg+CiNpbmNsdWRlIDxsaW51eC9kZWxheS5oPgojaW5jbHVkZSA8bGludXgvaW5pdC5oPgojaW5jbHVkZSA8bGludXgvcGFycG9ydC5oPgojaW5jbHVkZSA8bGludXgvaW5wdXQuaD4KCk1PRFVMRV9BVVRIT1IoIlZvanRlY2ggUGF2bGlrIDx2b2p0ZWNoQHVjdy5jej4iKTsKTU9EVUxFX0RFU0NSSVBUSU9OKCJBdGFyaSwgQW1zdHJhZCwgQ29tbW9kb3JlLCBBbWlnYSwgU2VnYSwgZXRjLiBqb3lzdGljayBkcml2ZXIiKTsKTU9EVUxFX0xJQ0VOU0UoIkdQTCIpOwoKc3RhdGljIGludCBkYjlbXSBfX2luaXRkYXRhID0geyAtMSwgMCB9OwpzdGF0aWMgaW50IGRiOV9uYXJncyBfX2luaXRkYXRhID0gMDsKbW9kdWxlX3BhcmFtX2FycmF5X25hbWVkKGRldiwgZGI5LCBpbnQsICZkYjlfbmFyZ3MsIDApOwpNT0RVTEVfUEFSTV9ERVNDKGRldiwgIkRlc2NyaWJlcyBmaXJzdCBhdHRhY2hlZCBkZXZpY2UgKDxwYXJwb3J0Iz4sPHR5cGU+KSIpOwoKc3RhdGljIGludCBkYjlfMltdIF9faW5pdGRhdGEgPSB7IC0xLCAwIH07CnN0YXRpYyBpbnQgZGI5X25hcmdzXzIgX19pbml0ZGF0YSA9IDA7Cm1vZHVsZV9wYXJhbV9hcnJheV9uYW1lZChkZXYyLCBkYjlfMiwgaW50LCAmZGI5X25hcmdzXzIsIDApOwpNT0RVTEVfUEFSTV9ERVNDKGRldjIsICJEZXNjcmliZXMgc2Vjb25kIGF0dGFjaGVkIGRldmljZSAoPHBhcnBvcnQjPiw8dHlwZT4pIik7CgpzdGF0aWMgaW50IGRiOV8zW10gX19pbml0ZGF0YSA9IHsgLTEsIDAgfTsKc3RhdGljIGludCBkYjlfbmFyZ3NfMyBfX2luaXRkYXRhID0gMDsKbW9kdWxlX3BhcmFtX2FycmF5X25hbWVkKGRldjMsIGRiOV8zLCBpbnQsICZkYjlfbmFyZ3NfMywgMCk7Ck1PRFVMRV9QQVJNX0RFU0MoZGV2MywgIkRlc2NyaWJlcyB0aGlyZCBhdHRhY2hlZCBkZXZpY2UgKDxwYXJwb3J0Iz4sPHR5cGU+KSIpOwoKX19vYnNvbGV0ZV9zZXR1cCgiZGI5PSIpOwpfX29ic29sZXRlX3NldHVwKCJkYjlfMj0iKTsKX19vYnNvbGV0ZV9zZXR1cCgiZGI5XzM9Iik7CgojZGVmaW5lIERCOV9NVUxUSV9TVElDSwkJMHgwMQojZGVmaW5lIERCOV9NVUxUSTJfU1RJQ0sJMHgwMgojZGVmaW5lIERCOV9HRU5FU0lTX1BBRAkJMHgwMwojZGVmaW5lIERCOV9HRU5FU0lTNV9QQUQJMHgwNQojZGVmaW5lIERCOV9HRU5FU0lTNl9QQUQJMHgwNgojZGVmaW5lIERCOV9TQVRVUk5fUEFECQkweDA3CiNkZWZpbmUgREI5X01VTFRJXzA4MDIJCTB4MDgKI2RlZmluZSBEQjlfTVVMVElfMDgwMl8yCTB4MDkKI2RlZmluZSBEQjlfQ0QzMl9QQUQJCTB4MEEKI2RlZmluZSBEQjlfU0FUVVJOX0RQUAkJMHgwQgojZGVmaW5lIERCOV9TQVRVUk5fRFBQXzIJMHgwQwojZGVmaW5lIERCOV9NQVhfUEFECQkweDBECgojZGVmaW5lIERCOV9VUAkJCTB4MDEKI2RlZmluZSBEQjlfRE9XTgkJMHgwMgojZGVmaW5lIERCOV9MRUZUCQkweDA0CiNkZWZpbmUgREI5X1JJR0hUCQkweDA4CiNkZWZpbmUgREI5X0ZJUkUxCQkweDEwCiNkZWZpbmUgREI5X0ZJUkUyCQkweDIwCiNkZWZpbmUgREI5X0ZJUkUzCQkweDQwCiNkZWZpbmUgREI5X0ZJUkU0CQkweDgwCgojZGVmaW5lIERCOV9OT1JNQUwJCTB4MGEKI2RlZmluZSBEQjlfTk9TRUxFQ1QJCTB4MDgKCiNkZWZpbmUgREI5X01BWF9ERVZJQ0VTCQkyCgojZGVmaW5lIERCOV9HRU5FU0lTNl9ERUxBWQkxNAojZGVmaW5lIERCOV9SRUZSRVNIX1RJTUUJSFovMTAwCgpzdHJ1Y3QgZGI5IHsKCXN0cnVjdCBpbnB1dF9kZXYgZGV2W0RCOV9NQVhfREVWSUNFU107CglzdHJ1Y3QgdGltZXJfbGlzdCB0aW1lcjsKCXN0cnVjdCBwYXJkZXZpY2UgKnBkOwoJaW50IG1vZGU7CglpbnQgdXNlZDsKCXN0cnVjdCBzZW1hcGhvcmUgc2VtOwoJY2hhciBwaHlzWzJdWzMyXTsKfTsKCnN0YXRpYyBzdHJ1Y3QgZGI5ICpkYjlfYmFzZVszXTsKCnN0YXRpYyBzaG9ydCBkYjlfbXVsdGlfYnRuW10gPSB7IEJUTl9UUklHR0VSLCBCVE5fVEhVTUIgfTsKc3RhdGljIHNob3J0IGRiOV9nZW5lc2lzX2J0bltdID0geyBCVE5fU1RBUlQsIEJUTl9BLCBCVE5fQiwgQlROX0MsIEJUTl9YLCBCVE5fWSwgQlROX1osIEJUTl9NT0RFIH07CnN0YXRpYyBzaG9ydCBkYjlfY2QzMl9idG5bXSA9IHsgQlROX0EsIEJUTl9CLCBCVE5fQywgQlROX1gsIEJUTl9ZLCBCVE5fWiwgQlROX1RMLCBCVE5fVFIsIEJUTl9TVEFSVCB9OwoKc3RhdGljIGNoYXIgZGI5X2J1dHRvbnNbREI5X01BWF9QQURdID0geyAwLCAxLCAyLCA0LCAwLCA2LCA4LCA5LCAxLCAxLCA3LCA5LCA5IH07CnN0YXRpYyBzaG9ydCAqZGI5X2J0bltEQjlfTUFYX1BBRF0gPSB7IE5VTEwsIGRiOV9tdWx0aV9idG4sIGRiOV9tdWx0aV9idG4sIGRiOV9nZW5lc2lzX2J0biwgTlVMTCwgZGI5X2dlbmVzaXNfYnRuLAoJCQkJCWRiOV9nZW5lc2lzX2J0biwgZGI5X2NkMzJfYnRuLCBkYjlfbXVsdGlfYnRuLCBkYjlfbXVsdGlfYnRuLCBkYjlfY2QzMl9idG4sCgkJCQkJZGI5X2NkMzJfYnRuLCBkYjlfY2QzMl9idG4gfTsKc3RhdGljIGNoYXIgKmRiOV9uYW1lW0RCOV9NQVhfUEFEXSA9IHsgTlVMTCwgIk11bHRpc3lzdGVtIGpveXN0aWNrIiwgIk11bHRpc3lzdGVtIGpveXN0aWNrICgyIGZpcmUpIiwgIkdlbmVzaXMgcGFkIiwKCQkJCSAgICAgIE5VTEwsICJHZW5lc2lzIDUgcGFkIiwgIkdlbmVzaXMgNiBwYWQiLCAiU2F0dXJuIHBhZCIsICJNdWx0aXN5c3RlbSAoMC44LjAuMikgam95c3RpY2siLAoJCQkJICAgICAiTXVsdGlzeXN0ZW0gKDAuOC4wLjItZHVhbCkgam95c3RpY2siLCAiQW1pZ2EgQ0QtMzIgcGFkIiwgIlNhdHVybiBkcHAiLCAiU2F0dXJuIGRwcCBkdWFsIiB9OwoKc3RhdGljIGNvbnN0IGludCBkYjlfbWF4X3BhZHNbREI5X01BWF9QQURdID0geyAwLCAxLCAxLCAxLCAwLCAxLCAxLCA2LCAxLCAyLCAxLCA2LCAxMiB9OwpzdGF0aWMgY29uc3QgaW50IGRiOV9udW1fYXhpc1tEQjlfTUFYX1BBRF0gPSB7IDAsIDIsIDIsIDIsIDAsIDIsIDIsIDcsIDIsIDIsIDIgLDcsIDcgfTsKc3RhdGljIGNvbnN0IHNob3J0IGRiOV9hYnNbXSA9IHsgQUJTX1gsIEFCU19ZLCBBQlNfUlgsIEFCU19SWSwgQUJTX1JaLCBBQlNfWiwgQUJTX0hBVDBYLCBBQlNfSEFUMFksIEFCU19IQVQxWCwgQUJTX0hBVDFZIH07CnN0YXRpYyBjb25zdCBpbnQgZGI5X2JpZGlyZWN0aW9uYWxbREI5X01BWF9QQURdID0geyAwLCAxLCAxLCAxLCAwLCAxLCAxLCAxLCAwLCAxLCAxLCAwLCAwIH07CnN0YXRpYyBjb25zdCBpbnQgZGI5X3JldmVyc2VbREI5X01BWF9QQURdID0geyAwLCAxLCAxLCAxLCAwLCAxLCAxLCAxLCAxLCAxLCAxLCAwLCAwIH07CgovKgogKiBTYXR1cm4gY29udHJvbGxlcnMKICovCiNkZWZpbmUgREI5X1NBVFVSTl9ERUxBWSAzMDAKc3RhdGljIGNvbnN0IGludCBkYjlfc2F0dXJuX2J5dGVbXSA9IHsgMSwgMSwgMSwgMiwgMiwgMiwgMiwgMiwgMSB9OwpzdGF0aWMgY29uc3QgdW5zaWduZWQgY2hhciBkYjlfc2F0dXJuX21hc2tbXSA9IHsgMHgwNCwgMHgwMSwgMHgwMiwgMHg0MCwgMHgyMCwgMHgxMCwgMHgwOCwgMHg4MCwgMHgwOCB9OwoKLyoKICogZGI5X3NhdHVybl93cml0ZV9zdWIoKSB3cml0ZXMgMiBiaXQgZGF0YS4KICovCnN0YXRpYyB2b2lkIGRiOV9zYXR1cm5fd3JpdGVfc3ViKHN0cnVjdCBwYXJwb3J0ICpwb3J0LCBpbnQgdHlwZSwgdW5zaWduZWQgY2hhciBkYXRhLCBpbnQgcG93ZXJlZCwgaW50IHB3cl9zdWIpCnsKCXVuc2lnbmVkIGNoYXIgYzsKCglzd2l0Y2ggKHR5cGUpIHsKCWNhc2UgMTogLyogRFBQMSAqLwoJCWMgPSAweDgwIHwgMHgzMCB8IChwb3dlcmVkID8gMHgwOCA6IDApIHwgKHB3cl9zdWIgPyAweDA0IDogMCkgfCBkYXRhOwoJCXBhcnBvcnRfd3JpdGVfZGF0YShwb3J0LCBjKTsKCQlicmVhazsKCWNhc2UgMjogLyogRFBQMiAqLwoJCWMgPSAweDQwIHwgZGF0YSA8PCA0IHwgKHBvd2VyZWQgPyAweDA4IDogMCkgfCAocHdyX3N1YiA/IDB4MDQgOiAwKSB8IDB4MDM7CgkJcGFycG9ydF93cml0ZV9kYXRhKHBvcnQsIGMpOwoJCWJyZWFrOwoJY2FzZSAwOgkvKiBEQjkgKi8KCQljID0gKCgoKGRhdGEgJiAyKSA/IDIgOiAwKSB8ICgoZGF0YSAmIDEpID8gNCA6IDApKSBeIDB4MDIpIHwgIXBvd2VyZWQ7CgkJcGFycG9ydF93cml0ZV9jb250cm9sKHBvcnQsIGMpOwoJCWJyZWFrOwoJfQp9CgovKgogKiBnY19zYXR1cm5fcmVhZF9zdWIoKSByZWFkcyA0IGJpdCBkYXRhLgogKi8Kc3RhdGljIHVuc2lnbmVkIGNoYXIgZGI5X3NhdHVybl9yZWFkX3N1YihzdHJ1Y3QgcGFycG9ydCAqcG9ydCwgaW50IHR5cGUpCnsKCXVuc2lnbmVkIGNoYXIgZGF0YTsKCglpZiAodHlwZSkgewoJCS8qIERQUCAqLwoJCWRhdGEgPSBwYXJwb3J0X3JlYWRfc3RhdHVzKHBvcnQpIF4gMHg4MDsKCQlyZXR1cm4gKGRhdGEgJiAweDgwID8gMSA6IDApIHwgKGRhdGEgJiAweDQwID8gMiA6IDApCgkJICAgICB8IChkYXRhICYgMHgyMCA/IDQgOiAwKSB8IChkYXRhICYgMHgxMCA/IDggOiAwKTsKCX0gZWxzZSB7CgkJLyogREI5ICovCgkJZGF0YSA9IHBhcnBvcnRfcmVhZF9kYXRhKHBvcnQpICYgMHgwZjsKCQlyZXR1cm4gKGRhdGEgJiAweDggPyAxIDogMCkgfCAoZGF0YSAmIDB4NCA/IDIgOiAwKQoJCSAgICAgfCAoZGF0YSAmIDB4MiA/IDQgOiAwKSB8IChkYXRhICYgMHgxID8gOCA6IDApOwoJfQp9CgovKgogKiBkYjlfc2F0dXJuX3JlYWRfYW5hbG9nKCkgc2VuZHMgY2xvY2sgYW5kIHJlYWRzIDggYml0IGRhdGEuCiAqLwpzdGF0aWMgdW5zaWduZWQgY2hhciBkYjlfc2F0dXJuX3JlYWRfYW5hbG9nKHN0cnVjdCBwYXJwb3J0ICpwb3J0LCBpbnQgdHlwZSwgaW50IHBvd2VyZWQpCnsKCXVuc2lnbmVkIGNoYXIgZGF0YTsKCglkYjlfc2F0dXJuX3dyaXRlX3N1Yihwb3J0LCB0eXBlLCAwLCBwb3dlcmVkLCAwKTsKCXVkZWxheShEQjlfU0FUVVJOX0RFTEFZKTsKCWRhdGEgPSBkYjlfc2F0dXJuX3JlYWRfc3ViKHBvcnQsIHR5cGUpIDw8IDQ7CglkYjlfc2F0dXJuX3dyaXRlX3N1Yihwb3J0LCB0eXBlLCAyLCBwb3dlcmVkLCAwKTsKCXVkZWxheShEQjlfU0FUVVJOX0RFTEFZKTsKCWRhdGEgfD0gZGI5X3NhdHVybl9yZWFkX3N1Yihwb3J0LCB0eXBlKTsKCXJldHVybiBkYXRhOwp9CgovKgogKiBkYjlfc2F0dXJuX3JlYWRfcGFja2V0KCkgcmVhZHMgd2hvbGUgc2F0dXJuIHBhY2tldCBhdCBjb25uZWN0b3IKICogYW5kIHJldHVybnMgZGV2aWNlIGlkZW50aWZpZXIgY29kZS4KICovCnN0YXRpYyB1bnNpZ25lZCBjaGFyIGRiOV9zYXR1cm5fcmVhZF9wYWNrZXQoc3RydWN0IHBhcnBvcnQgKnBvcnQsIHVuc2lnbmVkIGNoYXIgKmRhdGEsIGludCB0eXBlLCBpbnQgcG93ZXJlZCkKewoJaW50IGksIGo7Cgl1bnNpZ25lZCBjaGFyIHRtcDsKCglkYjlfc2F0dXJuX3dyaXRlX3N1Yihwb3J0LCB0eXBlLCAzLCBwb3dlcmVkLCAwKTsKCWRhdGFbMF0gPSBkYjlfc2F0dXJuX3JlYWRfc3ViKHBvcnQsIHR5cGUpOwoJc3dpdGNoIChkYXRhWzBdICYgMHgwZikgewoJY2FzZSAweGY6CgkJLyogMTExMSAgbm8gcGFkICovCgkJcmV0dXJuIGRhdGFbMF0gPSAweGZmOwoJY2FzZSAweDQ6IGNhc2UgMHg0IHwgMHg4OgoJCS8qID8xMDAgOiBkaWdpdGFsIGNvbnRyb2xsZXIgKi8KCQlkYjlfc2F0dXJuX3dyaXRlX3N1Yihwb3J0LCB0eXBlLCAwLCBwb3dlcmVkLCAxKTsKCQlkYXRhWzJdID0gZGI5X3NhdHVybl9yZWFkX3N1Yihwb3J0LCB0eXBlKSA8PCA0OwoJCWRiOV9zYXR1cm5fd3JpdGVfc3ViKHBvcnQsIHR5cGUsIDIsIHBvd2VyZWQsIDEpOwoJCWRhdGFbMV0gPSBkYjlfc2F0dXJuX3JlYWRfc3ViKHBvcnQsIHR5cGUpIDw8IDQ7CgkJZGI5X3NhdHVybl93cml0ZV9zdWIocG9ydCwgdHlwZSwgMSwgcG93ZXJlZCwgMSk7CgkJZGF0YVsxXSB8PSBkYjlfc2F0dXJuX3JlYWRfc3ViKHBvcnQsIHR5cGUpOwoJCWRiOV9zYXR1cm5fd3JpdGVfc3ViKHBvcnQsIHR5cGUsIDMsIHBvd2VyZWQsIDEpOwoJCS8qIGRhdGFbMl0gfD0gZGI5X3NhdHVybl9yZWFkX3N1Yihwb3J0LCB0eXBlKTsgKi8KCQlkYXRhWzJdIHw9IGRhdGFbMF07CgkJcmV0dXJuIGRhdGFbMF0gPSAweDAyOwoJY2FzZSAweDE6CgkJLyogMDAwMSA6IGFuYWxvZyBjb250cm9sbGVyIG9yIG11bHRpdGFwICovCgkJZGI5X3NhdHVybl93cml0ZV9zdWIocG9ydCwgdHlwZSwgMiwgcG93ZXJlZCwgMCk7CgkJdWRlbGF5KERCOV9TQVRVUk5fREVMQVkpOwoJCWRhdGFbMF0gPSBkYjlfc2F0dXJuX3JlYWRfYW5hbG9nKHBvcnQsIHR5cGUsIHBvd2VyZWQpOwoJCWlmIChkYXRhWzBdICE9IDB4NDEpIHsKCQkJLyogcmVhZCBhbmFsb2cgY29udHJvbGxlciAqLwoJCQlmb3IgKGkgPSAwOyBpIDwgKGRhdGFbMF0gJiAweDBmKTsgaSsrKQoJCQkJZGF0YVtpICsgMV0gPSBkYjlfc2F0dXJuX3JlYWRfYW5hbG9nKHBvcnQsIHR5cGUsIHBvd2VyZWQpOwoJCQlkYjlfc2F0dXJuX3dyaXRlX3N1Yihwb3J0LCB0eXBlLCAzLCBwb3dlcmVkLCAwKTsKCQkJcmV0dXJuIGRhdGFbMF07CgkJfSBlbHNlIHsKCQkJLyogcmVhZCBtdWx0aXRhcCAqLwoJCQlpZiAoZGI5X3NhdHVybl9yZWFkX2FuYWxvZyhwb3J0LCB0eXBlLCBwb3dlcmVkKSAhPSAweDYwKQoJCQkJcmV0dXJuIGRhdGFbMF0gPSAweGZmOwoJCQlmb3IgKGkgPSAwOyBpIDwgNjA7IGkgKz0gMTApIHsKCQkJCWRhdGFbaV0gPSBkYjlfc2F0dXJuX3JlYWRfYW5hbG9nKHBvcnQsIHR5cGUsIHBvd2VyZWQpOwoJCQkJaWYgKGRhdGFbaV0gIT0gMHhmZikKCQkJCQkvKiByZWFkIGVhY2ggcGFkICovCgkJCQkJZm9yIChqID0gMDsgaiA8IChkYXRhW2ldICYgMHgwZik7IGorKykKCQkJCQkJZGF0YVtpICsgaiArIDFdID0gZGI5X3NhdHVybl9yZWFkX2FuYWxvZyhwb3J0LCB0eXBlLCBwb3dlcmVkKTsKCQkJfQoJCQlkYjlfc2F0dXJuX3dyaXRlX3N1Yihwb3J0LCB0eXBlLCAzLCBwb3dlcmVkLCAwKTsKCQkJcmV0dXJuIDB4NDE7CgkJfQoJY2FzZSAweDA6CgkJLyogMDAwMCA6IG1vdXNlICovCgkJZGI5X3NhdHVybl93cml0ZV9zdWIocG9ydCwgdHlwZSwgMiwgcG93ZXJlZCwgMCk7CgkJdWRlbGF5KERCOV9TQVRVUk5fREVMQVkpOwoJCXRtcCA9IGRiOV9zYXR1cm5fcmVhZF9hbmFsb2cocG9ydCwgdHlwZSwgcG93ZXJlZCk7CgkJaWYgKHRtcCA9PSAweGZmKSB7CgkJCWZvciAoaSA9IDA7IGkgPCAzOyBpKyspCgkJCQlkYXRhW2kgKyAxXSA9IGRiOV9zYXR1cm5fcmVhZF9hbmFsb2cocG9ydCwgdHlwZSwgcG93ZXJlZCk7CgkJCWRiOV9zYXR1cm5fd3JpdGVfc3ViKHBvcnQsIHR5cGUsIDMsIHBvd2VyZWQsIDApOwoJCQlyZXR1cm4gZGF0YVswXSA9IDB4ZTM7CgkJfQoJZGVmYXVsdDoKCQlyZXR1cm4gZGF0YVswXTsKCX0KfQoKLyoKICogZGI5X3NhdHVybl9yZXBvcnQoKSBhbmFseXplcyBwYWNrZXQgYW5kIHJlcG9ydHMuCiAqLwpzdGF0aWMgaW50IGRiOV9zYXR1cm5fcmVwb3J0KHVuc2lnbmVkIGNoYXIgaWQsIHVuc2lnbmVkIGNoYXIgZGF0YVs2MF0sIHN0cnVjdCBpbnB1dF9kZXYgKmRldiwgaW50IG4sIGludCBtYXhfcGFkcykKewoJaW50IHRtcCwgaSwgajsKCgl0bXAgPSAoaWQgPT0gMHg0MSkgPyA2MCA6IDEwOwoJZm9yIChqID0gMDsgKGogPCB0bXApICYmIChuIDwgbWF4X3BhZHMpOyBqICs9IDEwLCBuKyspIHsKCQlzd2l0Y2ggKGRhdGFbal0pIHsKCQljYXNlIDB4MTY6IC8qIG11bHRpIGNvbnRyb2xsZXIgKGFuYWxvZyA0IGF4aXMpICovCgkJCWlucHV0X3JlcG9ydF9hYnMoZGV2ICsgbiwgZGI5X2Fic1s1XSwgZGF0YVtqICsgNl0pOwoJCWNhc2UgMHgxNTogLyogbWlzc2lvbiBzdGljayAoYW5hbG9nIDMgYXhpcykgKi8KCQkJaW5wdXRfcmVwb3J0X2FicyhkZXYgKyBuLCBkYjlfYWJzWzNdLCBkYXRhW2ogKyA0XSk7CgkJCWlucHV0X3JlcG9ydF9hYnMoZGV2ICsgbiwgZGI5X2Fic1s0XSwgZGF0YVtqICsgNV0pOwoJCWNhc2UgMHgxMzogLyogcmFjaW5nIGNvbnRyb2xsZXIgKGFuYWxvZyAxIGF4aXMpICovCgkJCWlucHV0X3JlcG9ydF9hYnMoZGV2ICsgbiwgZGI5X2Fic1syXSwgZGF0YVtqICsgM10pOwoJCWNhc2UgMHgzNDogLyogc2F0dXJuIGtleWJvYXJkICh1ZGxyIFpYQyBBU0QgUUUgRXNjKSAqLwoJCWNhc2UgMHgwMjogLyogZGlnaXRhbCBwYWQgKGRpZ2l0YWwgMiBheGlzICsgYnV0dG9ucykgKi8KCQkJaW5wdXRfcmVwb3J0X2FicyhkZXYgKyBuLCBkYjlfYWJzWzBdLCAhKGRhdGFbaiArIDFdICYgMTI4KSAtICEoZGF0YVtqICsgMV0gJiA2NCkpOwoJCQlpbnB1dF9yZXBvcnRfYWJzKGRldiArIG4sIGRiOV9hYnNbMV0sICEoZGF0YVtqICsgMV0gJiAzMikgLSAhKGRhdGFbaiArIDFdICYgMTYpKTsKCQkJZm9yIChpID0gMDsgaSA8IDk7IGkrKykKCQkJCWlucHV0X3JlcG9ydF9rZXkoZGV2ICsgbiwgZGI5X2NkMzJfYnRuW2ldLCB+ZGF0YVtqICsgZGI5X3NhdHVybl9ieXRlW2ldXSAmIGRiOV9zYXR1cm5fbWFza1tpXSk7CgkJCWJyZWFrOwoJCWNhc2UgMHgxOTogLyogbWlzc2lvbiBzdGljayB4MiAoYW5hbG9nIDYgYXhpcyArIGJ1dHRvbnMpICovCgkJCWlucHV0X3JlcG9ydF9hYnMoZGV2ICsgbiwgZGI5X2Fic1swXSwgIShkYXRhW2ogKyAxXSAmIDEyOCkgLSAhKGRhdGFbaiArIDFdICYgNjQpKTsKCQkJaW5wdXRfcmVwb3J0X2FicyhkZXYgKyBuLCBkYjlfYWJzWzFdLCAhKGRhdGFbaiArIDFdICYgMzIpIC0gIShkYXRhW2ogKyAxXSAmIDE2KSk7CgkJCWZvciAoaSA9IDA7IGkgPCA5OyBpKyspCgkJCQlpbnB1dF9yZXBvcnRfa2V5KGRldiArIG4sIGRiOV9jZDMyX2J0bltpXSwgfmRhdGFbaiArIGRiOV9zYXR1cm5fYnl0ZVtpXV0gJiBkYjlfc2F0dXJuX21hc2tbaV0pOwoJCQlpbnB1dF9yZXBvcnRfYWJzKGRldiArIG4sIGRiOV9hYnNbMl0sIGRhdGFbaiArIDNdKTsKCQkJaW5wdXRfcmVwb3J0X2FicyhkZXYgKyBuLCBkYjlfYWJzWzNdLCBkYXRhW2ogKyA0XSk7CgkJCWlucHV0X3JlcG9ydF9hYnMoZGV2ICsgbiwgZGI5X2Fic1s0XSwgZGF0YVtqICsgNV0pOwoJCQkvKgoJCQlpbnB1dF9yZXBvcnRfYWJzKGRldiArIG4sIGRiOV9hYnNbOF0sIChkYXRhW2ogKyA2XSAmIDEyOCA/IDAgOiAxKSAtIChkYXRhW2ogKyA2XSAmIDY0ID8gMCA6IDEpKTsKCQkJaW5wdXRfcmVwb3J0X2FicyhkZXYgKyBuLCBkYjlfYWJzWzldLCAoZGF0YVtqICsgNl0gJiAzMiA/IDAgOiAxKSAtIChkYXRhW2ogKyA2XSAmIDE2ID8gMCA6IDEpKTsKCQkJKi8KCQkJaW5wdXRfcmVwb3J0X2FicyhkZXYgKyBuLCBkYjlfYWJzWzZdLCBkYXRhW2ogKyA3XSk7CgkJCWlucHV0X3JlcG9ydF9hYnMoZGV2ICsgbiwgZGI5X2Fic1s3XSwgZGF0YVtqICsgOF0pOwoJCQlpbnB1dF9yZXBvcnRfYWJzKGRldiArIG4sIGRiOV9hYnNbNV0sIGRhdGFbaiArIDldKTsKCQkJYnJlYWs7CgkJY2FzZSAweGQzOiAvKiBzYW5reW8gZmYgKGFuYWxvZyAxIGF4aXMgKyBzdG9wIGJ0bikgKi8KCQkJaW5wdXRfcmVwb3J0X2tleShkZXYgKyBuLCBCVE5fQSwgZGF0YVtqICsgM10gJiAweDgwKTsKCQkJaW5wdXRfcmVwb3J0X2FicyhkZXYgKyBuLCBkYjlfYWJzWzJdLCBkYXRhW2ogKyAzXSAmIDB4N2YpOwoJCQlicmVhazsKCQljYXNlIDB4ZTM6IC8qIHNodXR0bGUgbW91c2UgKGFuYWxvZyAyIGF4aXMgKyBidXR0b25zLiBzaWduZWQgdmFsdWUpICovCgkJCWlucHV0X3JlcG9ydF9rZXkoZGV2ICsgbiwgQlROX1NUQVJULCBkYXRhW2ogKyAxXSAmIDB4MDgpOwoJCQlpbnB1dF9yZXBvcnRfa2V5KGRldiArIG4sIEJUTl9BLCBkYXRhW2ogKyAxXSAmIDB4MDQpOwoJCQlpbnB1dF9yZXBvcnRfa2V5KGRldiArIG4sIEJUTl9DLCBkYXRhW2ogKyAxXSAmIDB4MDIpOwoJCQlpbnB1dF9yZXBvcnRfa2V5KGRldiArIG4sIEJUTl9CLCBkYXRhW2ogKyAxXSAmIDB4MDEpOwoJCQlpbnB1dF9yZXBvcnRfYWJzKGRldiArIG4sIGRiOV9hYnNbMl0sIGRhdGFbaiArIDJdIF4gMHg4MCk7CgkJCWlucHV0X3JlcG9ydF9hYnMoZGV2ICsgbiwgZGI5X2Fic1szXSwgKDB4ZmYtKGRhdGFbaiArIDNdIF4gMHg4MCkpKzEpOyAvKiAqLwoJCQlicmVhazsKCQljYXNlIDB4ZmY6CgkJZGVmYXVsdDogLyogbm8gcGFkICovCgkJCWlucHV0X3JlcG9ydF9hYnMoZGV2ICsgbiwgZGI5X2Fic1swXSwgMCk7CgkJCWlucHV0X3JlcG9ydF9hYnMoZGV2ICsgbiwgZGI5X2Fic1sxXSwgMCk7CgkJCWZvciAoaSA9IDA7IGkgPCA5OyBpKyspCgkJCQlpbnB1dF9yZXBvcnRfa2V5KGRldiArIG4sIGRiOV9jZDMyX2J0bltpXSwgMCk7CgkJCWJyZWFrOwoJCX0KCX0KCXJldHVybiBuOwp9CgpzdGF0aWMgaW50IGRiOV9zYXR1cm4oaW50IG1vZGUsIHN0cnVjdCBwYXJwb3J0ICpwb3J0LCBzdHJ1Y3QgaW5wdXRfZGV2ICpkZXYpCnsKCXVuc2lnbmVkIGNoYXIgaWQsIGRhdGFbNjBdOwoJaW50IHR5cGUsIG4sIG1heF9wYWRzOwoJaW50IHRtcCwgaTsKCglzd2l0Y2ggKG1vZGUpIHsKCWNhc2UgREI5X1NBVFVSTl9QQUQ6CgkJdHlwZSA9IDA7CgkJbiA9IDE7CgkJYnJlYWs7CgljYXNlIERCOV9TQVRVUk5fRFBQOgoJCXR5cGUgPSAxOwoJCW4gPSAxOwoJCWJyZWFrOwoJY2FzZSBEQjlfU0FUVVJOX0RQUF8yOgoJCXR5cGUgPSAxOwoJCW4gPSAyOwoJCWJyZWFrOwoJZGVmYXVsdDoKCQlyZXR1cm4gLTE7Cgl9CgltYXhfcGFkcyA9IG1pbihkYjlfbWF4X3BhZHNbbW9kZV0sIERCOV9NQVhfREVWSUNFUyk7Cglmb3IgKHRtcCA9IDAsIGkgPSAwOyBpIDwgbjsgaSsrKSB7CgkJaWQgPSBkYjlfc2F0dXJuX3JlYWRfcGFja2V0KHBvcnQsIGRhdGEsIHR5cGUgKyBpLCAxKTsKCQl0bXAgPSBkYjlfc2F0dXJuX3JlcG9ydChpZCwgZGF0YSwgZGV2LCB0bXAsIG1heF9wYWRzKTsKCX0KCXJldHVybiAwOwp9CgpzdGF0aWMgdm9pZCBkYjlfdGltZXIodW5zaWduZWQgbG9uZyBwcml2YXRlKQp7CglzdHJ1Y3QgZGI5ICpkYjkgPSAodm9pZCAqKSBwcml2YXRlOwoJc3RydWN0IHBhcnBvcnQgKnBvcnQgPSBkYjktPnBkLT5wb3J0OwoJc3RydWN0IGlucHV0X2RldiAqZGV2ID0gZGI5LT5kZXY7CglpbnQgZGF0YSwgaTsKCglzd2l0Y2goZGI5LT5tb2RlKSB7CgkJY2FzZSBEQjlfTVVMVElfMDgwMl8yOgoKCQkJZGF0YSA9IHBhcnBvcnRfcmVhZF9kYXRhKHBvcnQpID4+IDM7CgoJCQlpbnB1dF9yZXBvcnRfYWJzKGRldiArIDEsIEFCU19YLCAoZGF0YSAmIERCOV9SSUdIVCA/IDAgOiAxKSAtIChkYXRhICYgREI5X0xFRlQgPyAwIDogMSkpOwoJCQlpbnB1dF9yZXBvcnRfYWJzKGRldiArIDEsIEFCU19ZLCAoZGF0YSAmIERCOV9ET1dOICA/IDAgOiAxKSAtIChkYXRhICYgREI5X1VQICAgPyAwIDogMSkpOwoJCQlpbnB1dF9yZXBvcnRfa2V5KGRldiArIDEsIEJUTl9UUklHR0VSLCB+ZGF0YSAmIERCOV9GSVJFMSk7CgoJCWNhc2UgREI5X01VTFRJXzA4MDI6CgoJCQlkYXRhID0gcGFycG9ydF9yZWFkX3N0YXR1cyhwb3J0KSA+PiAzOwoKCQkJaW5wdXRfcmVwb3J0X2FicyhkZXYsIEFCU19YLCAoZGF0YSAmIERCOV9SSUdIVCA/IDAgOiAxKSAtIChkYXRhICYgREI5X0xFRlQgPyAwIDogMSkpOwoJCQlpbnB1dF9yZXBvcnRfYWJzKGRldiwgQUJTX1ksIChkYXRhICYgREI5X0RPV04gID8gMCA6IDEpIC0gKGRhdGEgJiBEQjlfVVAgICA/IDAgOiAxKSk7CgkJCWlucHV0X3JlcG9ydF9rZXkoZGV2LCBCVE5fVFJJR0dFUiwgZGF0YSAmIERCOV9GSVJFMSk7CgkJCWJyZWFrOwoKCQljYXNlIERCOV9NVUxUSV9TVElDSzoKCgkJCWRhdGEgPSBwYXJwb3J0X3JlYWRfZGF0YShwb3J0KTsKCgkJCWlucHV0X3JlcG9ydF9hYnMoZGV2LCBBQlNfWCwgKGRhdGEgJiBEQjlfUklHSFQgPyAwIDogMSkgLSAoZGF0YSAmIERCOV9MRUZUID8gMCA6IDEpKTsKCQkJaW5wdXRfcmVwb3J0X2FicyhkZXYsIEFCU19ZLCAoZGF0YSAmIERCOV9ET1dOICA/IDAgOiAxKSAtIChkYXRhICYgREI5X1VQICAgPyAwIDogMSkpOwoJCQlpbnB1dF9yZXBvcnRfa2V5KGRldiwgQlROX1RSSUdHRVIsIH5kYXRhICYgREI5X0ZJUkUxKTsKCQkJYnJlYWs7CgoJCWNhc2UgREI5X01VTFRJMl9TVElDSzoKCgkJCWRhdGEgPSBwYXJwb3J0X3JlYWRfZGF0YShwb3J0KTsKCgkJCWlucHV0X3JlcG9ydF9hYnMoZGV2LCBBQlNfWCwgKGRhdGEgJiBEQjlfUklHSFQgPyAwIDogMSkgLSAoZGF0YSAmIERCOV9MRUZUID8gMCA6IDEpKTsKCQkJaW5wdXRfcmVwb3J0X2FicyhkZXYsIEFCU19ZLCAoZGF0YSAmIERCOV9ET1dOICA/IDAgOiAxKSAtIChkYXRhICYgREI5X1VQICAgPyAwIDogMSkpOwoJCQlpbnB1dF9yZXBvcnRfa2V5KGRldiwgQlROX1RSSUdHRVIsIH5kYXRhICYgREI5X0ZJUkUxKTsKCQkJaW5wdXRfcmVwb3J0X2tleShkZXYsIEJUTl9USFVNQiwgICB+ZGF0YSAmIERCOV9GSVJFMik7CgkJCWJyZWFrOwoKCQljYXNlIERCOV9HRU5FU0lTX1BBRDoKCgkJCXBhcnBvcnRfd3JpdGVfY29udHJvbChwb3J0LCBEQjlfTk9TRUxFQ1QpOwoJCQlkYXRhID0gcGFycG9ydF9yZWFkX2RhdGEocG9ydCk7CgoJCQlpbnB1dF9yZXBvcnRfYWJzKGRldiwgQUJTX1gsIChkYXRhICYgREI5X1JJR0hUID8gMCA6IDEpIC0gKGRhdGEgJiBEQjlfTEVGVCA/IDAgOiAxKSk7CgkJCWlucHV0X3JlcG9ydF9hYnMoZGV2LCBBQlNfWSwgKGRhdGEgJiBEQjlfRE9XTiAgPyAwIDogMSkgLSAoZGF0YSAmIERCOV9VUCAgID8gMCA6IDEpKTsKCQkJaW5wdXRfcmVwb3J0X2tleShkZXYsIEJUTl9CLCB+ZGF0YSAmIERCOV9GSVJFMSk7CgkJCWlucHV0X3JlcG9ydF9rZXkoZGV2LCBCVE5fQywgfmRhdGEgJiBEQjlfRklSRTIpOwoKCQkJcGFycG9ydF93cml0ZV9jb250cm9sKHBvcnQsIERCOV9OT1JNQUwpOwoJCQlkYXRhPXBhcnBvcnRfcmVhZF9kYXRhKHBvcnQpOwoKCQkJaW5wdXRfcmVwb3J0X2tleShkZXYsIEJUTl9BLCAgICAgfmRhdGEgJiBEQjlfRklSRTEpOwoJCQlpbnB1dF9yZXBvcnRfa2V5KGRldiwgQlROX1NUQVJULCB+ZGF0YSAmIERCOV9GSVJFMik7CgkJCWJyZWFrOwoKCQljYXNlIERCOV9HRU5FU0lTNV9QQUQ6CgoJCQlwYXJwb3J0X3dyaXRlX2NvbnRyb2wocG9ydCwgREI5X05PU0VMRUNUKTsKCQkJZGF0YT1wYXJwb3J0X3JlYWRfZGF0YShwb3J0KTsKCgkJCWlucHV0X3JlcG9ydF9hYnMoZGV2LCBBQlNfWCwgKGRhdGEgJiBEQjlfUklHSFQgPyAwIDogMSkgLSAoZGF0YSAmIERCOV9MRUZUID8gMCA6IDEpKTsKCQkJaW5wdXRfcmVwb3J0X2FicyhkZXYsIEFCU19ZLCAoZGF0YSAmIERCOV9ET1dOICA/IDAgOiAxKSAtIChkYXRhICYgREI5X1VQICAgPyAwIDogMSkpOwoJCQlpbnB1dF9yZXBvcnRfa2V5KGRldiwgQlROX0IsIH5kYXRhICYgREI5X0ZJUkUxKTsKCQkJaW5wdXRfcmVwb3J0X2tleShkZXYsIEJUTl9DLCB+ZGF0YSAmIERCOV9GSVJFMik7CgoJCQlwYXJwb3J0X3dyaXRlX2NvbnRyb2wocG9ydCwgREI5X05PUk1BTCk7CgkJCWRhdGE9cGFycG9ydF9yZWFkX2RhdGEocG9ydCk7CgoJCQlpbnB1dF9yZXBvcnRfa2V5KGRldiwgQlROX0EsICAgICB+ZGF0YSAmIERCOV9GSVJFMSk7CgkJCWlucHV0X3JlcG9ydF9rZXkoZGV2LCBCVE5fWCwgICAgIH5kYXRhICYgREI5X0ZJUkUyKTsKCQkJaW5wdXRfcmVwb3J0X2tleShkZXYsIEJUTl9ZLCAgICAgfmRhdGEgJiBEQjlfTEVGVCk7CgkJCWlucHV0X3JlcG9ydF9rZXkoZGV2LCBCVE5fU1RBUlQsIH5kYXRhICYgREI5X1JJR0hUKTsKCQkJYnJlYWs7CgoJCWNhc2UgREI5X0dFTkVTSVM2X1BBRDoKCgkJCXBhcnBvcnRfd3JpdGVfY29udHJvbChwb3J0LCBEQjlfTk9TRUxFQ1QpOyAvKiAxICovCgkJCXVkZWxheShEQjlfR0VORVNJUzZfREVMQVkpOwoJCQlkYXRhPXBhcnBvcnRfcmVhZF9kYXRhKHBvcnQpOwoKCQkJaW5wdXRfcmVwb3J0X2FicyhkZXYsIEFCU19YLCAoZGF0YSAmIERCOV9SSUdIVCA/IDAgOiAxKSAtIChkYXRhICYgREI5X0xFRlQgPyAwIDogMSkpOwoJCQlpbnB1dF9yZXBvcnRfYWJzKGRldiwgQUJTX1ksIChkYXRhICYgREI5X0RPV04gID8gMCA6IDEpIC0gKGRhdGEgJiBEQjlfVVAgICA/IDAgOiAxKSk7CgkJCWlucHV0X3JlcG9ydF9rZXkoZGV2LCBCVE5fQiwgfmRhdGEgJiBEQjlfRklSRTEpOwoJCQlpbnB1dF9yZXBvcnRfa2V5KGRldiwgQlROX0MsIH5kYXRhICYgREI5X0ZJUkUyKTsKCgkJCXBhcnBvcnRfd3JpdGVfY29udHJvbChwb3J0LCBEQjlfTk9STUFMKTsKCQkJdWRlbGF5KERCOV9HRU5FU0lTNl9ERUxBWSk7CgkJCWRhdGE9cGFycG9ydF9yZWFkX2RhdGEocG9ydCk7CgoJCQlpbnB1dF9yZXBvcnRfa2V5KGRldiwgQlROX0EsIH5kYXRhICYgREI5X0ZJUkUxKTsKCQkJaW5wdXRfcmVwb3J0X2tleShkZXYsIEJUTl9TVEFSVCwgfmRhdGEgJiBEQjlfRklSRTIpOwoKCQkJcGFycG9ydF93cml0ZV9jb250cm9sKHBvcnQsIERCOV9OT1NFTEVDVCk7IC8qIDIgKi8KCQkJdWRlbGF5KERCOV9HRU5FU0lTNl9ERUxBWSk7CgkJCXBhcnBvcnRfd3JpdGVfY29udHJvbChwb3J0LCBEQjlfTk9STUFMKTsKCQkJdWRlbGF5KERCOV9HRU5FU0lTNl9ERUxBWSk7CgkJCXBhcnBvcnRfd3JpdGVfY29udHJvbChwb3J0LCBEQjlfTk9TRUxFQ1QpOyAvKiAzICovCgkJCXVkZWxheShEQjlfR0VORVNJUzZfREVMQVkpOwoJCQlkYXRhPXBhcnBvcnRfcmVhZF9kYXRhKHBvcnQpOwoKCQkJaW5wdXRfcmVwb3J0X2tleShkZXYsIEJUTl9YLCAgICB+ZGF0YSAmIERCOV9MRUZUKTsKCQkJaW5wdXRfcmVwb3J0X2tleShkZXYsIEJUTl9ZLCAgICB+ZGF0YSAmIERCOV9ET1dOKTsKCQkJaW5wdXRfcmVwb3J0X2tleShkZXYsIEJUTl9aLCAgICB+ZGF0YSAmIERCOV9VUCk7CgkJCWlucHV0X3JlcG9ydF9rZXkoZGV2LCBCVE5fTU9ERSwgfmRhdGEgJiBEQjlfUklHSFQpOwoKCQkJcGFycG9ydF93cml0ZV9jb250cm9sKHBvcnQsIERCOV9OT1JNQUwpOwoJCQl1ZGVsYXkoREI5X0dFTkVTSVM2X0RFTEFZKTsKCQkJcGFycG9ydF93cml0ZV9jb250cm9sKHBvcnQsIERCOV9OT1NFTEVDVCk7IC8qIDQgKi8KCQkJdWRlbGF5KERCOV9HRU5FU0lTNl9ERUxBWSk7CgkJCXBhcnBvcnRfd3JpdGVfY29udHJvbChwb3J0LCBEQjlfTk9STUFMKTsKCQkJYnJlYWs7CgoJCWNhc2UgREI5X1NBVFVSTl9QQUQ6CgkJY2FzZSBEQjlfU0FUVVJOX0RQUDoKCQljYXNlIERCOV9TQVRVUk5fRFBQXzI6CgoJCQlkYjlfc2F0dXJuKGRiOS0+bW9kZSwgcG9ydCwgZGV2KTsKCQkJYnJlYWs7CgoJCWNhc2UgREI5X0NEMzJfUEFEOgoKCQkJZGF0YT1wYXJwb3J0X3JlYWRfZGF0YShwb3J0KTsKCgkJCWlucHV0X3JlcG9ydF9hYnMoZGV2LCBBQlNfWCwgKGRhdGEgJiBEQjlfUklHSFQgPyAwIDogMSkgLSAoZGF0YSAmIERCOV9MRUZUID8gMCA6IDEpKTsKCQkJaW5wdXRfcmVwb3J0X2FicyhkZXYsIEFCU19ZLCAoZGF0YSAmIERCOV9ET1dOICA/IDAgOiAxKSAtIChkYXRhICYgREI5X1VQICAgPyAwIDogMSkpOwoKCQkJcGFycG9ydF93cml0ZV9jb250cm9sKHBvcnQsIDB4MGEpOwoKCQkJZm9yIChpID0gMDsgaSA8IDc7IGkrKykgewoJCQkJZGF0YSA9IHBhcnBvcnRfcmVhZF9kYXRhKHBvcnQpOwoJCQkJcGFycG9ydF93cml0ZV9jb250cm9sKHBvcnQsIDB4MDIpOwoJCQkJcGFycG9ydF93cml0ZV9jb250cm9sKHBvcnQsIDB4MGEpOwoJCQkJaW5wdXRfcmVwb3J0X2tleShkZXYsIGRiOV9jZDMyX2J0bltpXSwgfmRhdGEgJiBEQjlfRklSRTIpOwoJCQkJfQoKCQkJcGFycG9ydF93cml0ZV9jb250cm9sKHBvcnQsIDB4MDApOwoJCQlicmVhazsKCQl9CgoJaW5wdXRfc3luYyhkZXYpOwoKCW1vZF90aW1lcigmZGI5LT50aW1lciwgamlmZmllcyArIERCOV9SRUZSRVNIX1RJTUUpOwp9CgpzdGF0aWMgaW50IGRiOV9vcGVuKHN0cnVjdCBpbnB1dF9kZXYgKmRldikKewoJc3RydWN0IGRiOSAqZGI5ID0gZGV2LT5wcml2YXRlOwoJc3RydWN0IHBhcnBvcnQgKnBvcnQgPSBkYjktPnBkLT5wb3J0OwoJaW50IGVycjsKCgllcnIgPSBkb3duX2ludGVycnVwdGlibGUoJmRiOS0+c2VtKTsKCWlmIChlcnIpCgkJcmV0dXJuIGVycjsKCglpZiAoIWRiOS0+dXNlZCsrKSB7CgkJcGFycG9ydF9jbGFpbShkYjktPnBkKTsKCQlwYXJwb3J0X3dyaXRlX2RhdGEocG9ydCwgMHhmZik7CgkJaWYgKGRiOV9yZXZlcnNlW2RiOS0+bW9kZV0pIHsKCQkJcGFycG9ydF9kYXRhX3JldmVyc2UocG9ydCk7CgkJCXBhcnBvcnRfd3JpdGVfY29udHJvbChwb3J0LCBEQjlfTk9STUFMKTsKCQl9CgkJbW9kX3RpbWVyKCZkYjktPnRpbWVyLCBqaWZmaWVzICsgREI5X1JFRlJFU0hfVElNRSk7Cgl9CgoJdXAoJmRiOS0+c2VtKTsKCXJldHVybiAwOwp9CgpzdGF0aWMgdm9pZCBkYjlfY2xvc2Uoc3RydWN0IGlucHV0X2RldiAqZGV2KQp7CglzdHJ1Y3QgZGI5ICpkYjkgPSBkZXYtPnByaXZhdGU7CglzdHJ1Y3QgcGFycG9ydCAqcG9ydCA9IGRiOS0+cGQtPnBvcnQ7CgoJZG93bigmZGI5LT5zZW0pOwoJaWYgKCEtLWRiOS0+dXNlZCkgewoJCWRlbF90aW1lcl9zeW5jKCZkYjktPnRpbWVyKTsKCQlwYXJwb3J0X3dyaXRlX2NvbnRyb2wocG9ydCwgMHgwMCk7CgkJcGFycG9ydF9kYXRhX2ZvcndhcmQocG9ydCk7CgkJcGFycG9ydF9yZWxlYXNlKGRiOS0+cGQpOwoJfQoJdXAoJmRiOS0+c2VtKTsKfQoKc3RhdGljIHN0cnVjdCBkYjkgX19pbml0ICpkYjlfcHJvYmUoaW50ICpjb25maWcsIGludCBuYXJncykKewoJc3RydWN0IGRiOSAqZGI5OwoJc3RydWN0IHBhcnBvcnQgKnBwOwoJaW50IGksIGo7CgoJaWYgKGNvbmZpZ1swXSA8IDApCgkJcmV0dXJuIE5VTEw7CgoJaWYgKG5hcmdzIDwgMikgewoJCXByaW50ayhLRVJOX0VSUiAiZGI5LmM6IERldmljZSB0eXBlIG11c3QgYmUgc3BlY2lmaWVkLlxuIik7CgkJcmV0dXJuIE5VTEw7Cgl9CgoJaWYgKGNvbmZpZ1sxXSA8IDEgfHwgY29uZmlnWzFdID49IERCOV9NQVhfUEFEIHx8ICFkYjlfYnV0dG9uc1tjb25maWdbMV1dKSB7CgkJcHJpbnRrKEtFUk5fRVJSICJkYjkuYzogYmFkIGNvbmZpZ1xuIik7CgkJcmV0dXJuIE5VTEw7Cgl9CgoJcHAgPSBwYXJwb3J0X2ZpbmRfbnVtYmVyKGNvbmZpZ1swXSk7CglpZiAoIXBwKSB7CgkJcHJpbnRrKEtFUk5fRVJSICJkYjkuYzogbm8gc3VjaCBwYXJwb3J0XG4iKTsKCQlyZXR1cm4gTlVMTDsKCX0KCglpZiAoZGI5X2JpZGlyZWN0aW9uYWxbY29uZmlnWzFdXSkgewoJCWlmICghKHBwLT5tb2RlcyAmIFBBUlBPUlRfTU9ERV9UUklTVEFURSkpIHsKCQkJcHJpbnRrKEtFUk5fRVJSICJkYjkuYzogc3BlY2lmaWVkIHBhcnBvcnQgaXMgbm90IGJpZGlyZWN0aW9uYWxcbiIpOwoJCQlwYXJwb3J0X3B1dF9wb3J0KHBwKTsKCQkJcmV0dXJuIE5VTEw7CgkJfQoJfQoKCWlmICghKGRiOSA9IGt6YWxsb2Moc2l6ZW9mKHN0cnVjdCBkYjkpLCBHRlBfS0VSTkVMKSkpIHsKCQlwYXJwb3J0X3B1dF9wb3J0KHBwKTsKCQlyZXR1cm4gTlVMTDsKCX0KCglpbml0X01VVEVYKCZkYjktPnNlbSk7CglkYjktPm1vZGUgPSBjb25maWdbMV07Cglpbml0X3RpbWVyKCZkYjktPnRpbWVyKTsKCWRiOS0+dGltZXIuZGF0YSA9IChsb25nKSBkYjk7CglkYjktPnRpbWVyLmZ1bmN0aW9uID0gZGI5X3RpbWVyOwoKCWRiOS0+cGQgPSBwYXJwb3J0X3JlZ2lzdGVyX2RldmljZShwcCwgImRiOSIsIE5VTEwsIE5VTEwsIE5VTEwsIFBBUlBPUlRfREVWX0VYQ0wsIE5VTEwpOwoJcGFycG9ydF9wdXRfcG9ydChwcCk7CgoJaWYgKCFkYjktPnBkKSB7CgkJcHJpbnRrKEtFUk5fRVJSICJkYjkuYzogcGFycG9ydCBidXN5IGFscmVhZHkgLSBscC5vIGxvYWRlZD9cbiIpOwoJCWtmcmVlKGRiOSk7CgkJcmV0dXJuIE5VTEw7Cgl9CgoJZm9yIChpID0gMDsgaSA8IChtaW4oZGI5X21heF9wYWRzW2RiOS0+bW9kZV0sIERCOV9NQVhfREVWSUNFUykpOyBpKyspIHsKCgkJc3ByaW50ZihkYjktPnBoeXNbaV0sICIlcy9pbnB1dCVkIiwgZGI5LT5wZC0+cG9ydC0+bmFtZSwgaSk7CgoJCWRiOS0+ZGV2W2ldLnByaXZhdGUgPSBkYjk7CgkJZGI5LT5kZXZbaV0ub3BlbiA9IGRiOV9vcGVuOwoJCWRiOS0+ZGV2W2ldLmNsb3NlID0gZGI5X2Nsb3NlOwoKCQlkYjktPmRldltpXS5uYW1lID0gZGI5X25hbWVbZGI5LT5tb2RlXTsKCQlkYjktPmRldltpXS5waHlzID0gZGI5LT5waHlzW2ldOwoJCWRiOS0+ZGV2W2ldLmlkLmJ1c3R5cGUgPSBCVVNfUEFSUE9SVDsKCQlkYjktPmRldltpXS5pZC52ZW5kb3IgPSAweDAwMDI7CgkJZGI5LT5kZXZbaV0uaWQucHJvZHVjdCA9IGNvbmZpZ1sxXTsKCQlkYjktPmRldltpXS5pZC52ZXJzaW9uID0gMHgwMTAwOwoKCQlkYjktPmRldltpXS5ldmJpdFswXSA9IEJJVChFVl9LRVkpIHwgQklUKEVWX0FCUyk7CgkJZm9yIChqID0gMDsgaiA8IGRiOV9idXR0b25zW2RiOS0+bW9kZV07IGorKykKCQkJc2V0X2JpdChkYjlfYnRuW2RiOS0+bW9kZV1bal0sIGRiOS0+ZGV2W2ldLmtleWJpdCk7CgkJZm9yIChqID0gMDsgaiA8IGRiOV9udW1fYXhpc1tkYjktPm1vZGVdOyBqKyspIHsKCQkJc2V0X2JpdChkYjlfYWJzW2pdLCBkYjktPmRldltpXS5hYnNiaXQpOwoJCQlpZiAoaiA8IDIpIHsKCQkJCWRiOS0+ZGV2W2ldLmFic21pbltkYjlfYWJzW2pdXSA9IC0xOwoJCQkJZGI5LT5kZXZbaV0uYWJzbWF4W2RiOV9hYnNbal1dID0gMTsKCQkJfSBlbHNlIHsKCQkJCWRiOS0+ZGV2W2ldLmFic21pbltkYjlfYWJzW2pdXSA9IDE7CgkJCQlkYjktPmRldltpXS5hYnNtYXhbZGI5X2Fic1tqXV0gPSAyNTU7CgkJCQlkYjktPmRldltpXS5hYnNmbGF0W2RiOV9hYnNbal1dID0gMDsKCQkJfQoJCX0KCQlpbnB1dF9yZWdpc3Rlcl9kZXZpY2UoZGI5LT5kZXYgKyBpKTsKCQlwcmludGsoS0VSTl9JTkZPICJpbnB1dDogJXMgb24gJXNcbiIsIGRiOS0+ZGV2W2ldLm5hbWUsIGRiOS0+cGQtPnBvcnQtPm5hbWUpOwoJfQoKCXJldHVybiBkYjk7Cn0KCnN0YXRpYyBpbnQgX19pbml0IGRiOV9pbml0KHZvaWQpCnsKCWRiOV9iYXNlWzBdID0gZGI5X3Byb2JlKGRiOSwgZGI5X25hcmdzKTsKCWRiOV9iYXNlWzFdID0gZGI5X3Byb2JlKGRiOV8yLCBkYjlfbmFyZ3NfMik7CglkYjlfYmFzZVsyXSA9IGRiOV9wcm9iZShkYjlfMywgZGI5X25hcmdzXzMpOwoKCWlmIChkYjlfYmFzZVswXSB8fCBkYjlfYmFzZVsxXSB8fCBkYjlfYmFzZVsyXSkKCQlyZXR1cm4gMDsKCglyZXR1cm4gLUVOT0RFVjsKfQoKc3RhdGljIHZvaWQgX19leGl0IGRiOV9leGl0KHZvaWQpCnsKCWludCBpLCBqOwoKCWZvciAoaSA9IDA7IGkgPCAzOyBpKyspCgkJaWYgKGRiOV9iYXNlW2ldKSB7CgkJCWZvciAoaiA9IDA7IGogPCBtaW4oZGI5X21heF9wYWRzW2RiOV9iYXNlW2ldLT5tb2RlXSwgREI5X01BWF9ERVZJQ0VTKTsgaisrKQoJCQkJaW5wdXRfdW5yZWdpc3Rlcl9kZXZpY2UoZGI5X2Jhc2VbaV0tPmRldiArIGopOwoJCXBhcnBvcnRfdW5yZWdpc3Rlcl9kZXZpY2UoZGI5X2Jhc2VbaV0tPnBkKTsKCX0KfQoKbW9kdWxlX2luaXQoZGI5X2luaXQpOwptb2R1bGVfZXhpdChkYjlfZXhpdCk7Cg==