LyoKICogJElkOiBkYjkuYyx2IDEuMTMgMjAwMi8wNC8wNyAyMDoxMzozNyB2b2p0ZWNoIEV4cCAkCiAqCiAqICBDb3B5cmlnaHQgKGMpIDE5OTktMjAwMSBWb2p0ZWNoIFBhdmxpawogKgogKiAgQmFzZWQgb24gdGhlIHdvcmsgb2Y6CiAqCUFuZHJlZSBCb3JybWFubgkJTWF0cyBTavZ2YWxsCiAqLwoKLyoKICogQXRhcmksIEFtc3RyYWQsIENvbW1vZG9yZSwgQW1pZ2EsIFNlZ2EsIGV0Yy4gam95c3RpY2sgZHJpdmVyIGZvciBMaW51eAogKi8KCi8qCiAqIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5CiAqIGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5CiAqIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlciB2ZXJzaW9uIDIgb2YgdGhlIExpY2Vuc2UsIG9yCiAqIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlCiAqIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIGFsb25nIHdpdGggdGhpcyBwcm9ncmFtOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDU5IFRlbXBsZSBQbGFjZSwgU3VpdGUgMzMwLCBCb3N0b24sIE1BIDAyMTExLTEzMDcgVVNBCiAqCiAqIFNob3VsZCB5b3UgbmVlZCB0byBjb250YWN0IG1lLCB0aGUgYXV0aG9yLCB5b3UgY2FuIGRvIHNvIGVpdGhlciBieQogKiBlLW1haWwgLSBtYWlsIHlvdXIgbWVzc2FnZSB0byA8dm9qdGVjaEB1Y3cuY3o+LCBvciBieSBwYXBlciBtYWlsOgogKiBWb2p0ZWNoIFBhdmxpaywgU2ltdW5rb3ZhIDE1OTQsIFByYWd1ZSA4LCAxODIgMDAgQ3plY2ggUmVwdWJsaWMKICovCgojaW5jbHVkZSA8bGludXgva2VybmVsLmg+CiNpbmNsdWRlIDxsaW51eC9tb2R1bGUuaD4KI2luY2x1ZGUgPGxpbnV4L21vZHVsZXBhcmFtLmg+CiNpbmNsdWRlIDxsaW51eC9kZWxheS5oPgojaW5jbHVkZSA8bGludXgvaW5pdC5oPgojaW5jbHVkZSA8bGludXgvcGFycG9ydC5oPgojaW5jbHVkZSA8bGludXgvaW5wdXQuaD4KI2luY2x1ZGUgPGxpbnV4L211dGV4Lmg+CgpNT0RVTEVfQVVUSE9SKCJWb2p0ZWNoIFBhdmxpayA8dm9qdGVjaEB1Y3cuY3o+Iik7Ck1PRFVMRV9ERVNDUklQVElPTigiQXRhcmksIEFtc3RyYWQsIENvbW1vZG9yZSwgQW1pZ2EsIFNlZ2EsIGV0Yy4gam95c3RpY2sgZHJpdmVyIik7Ck1PRFVMRV9MSUNFTlNFKCJHUEwiKTsKCnN0cnVjdCBkYjlfY29uZmlnIHsKCWludCBhcmdzWzJdOwoJaW50IG5hcmdzOwp9OwoKI2RlZmluZSBEQjlfTUFYX1BPUlRTCQkzCnN0YXRpYyBzdHJ1Y3QgZGI5X2NvbmZpZyBkYjlbREI5X01BWF9QT1JUU10gX19pbml0ZGF0YTsKCm1vZHVsZV9wYXJhbV9hcnJheV9uYW1lZChkZXYsIGRiOVswXS5hcmdzLCBpbnQsICZkYjlbMF0ubmFyZ3MsIDApOwpNT0RVTEVfUEFSTV9ERVNDKGRldiwgIkRlc2NyaWJlcyBmaXJzdCBhdHRhY2hlZCBkZXZpY2UgKDxwYXJwb3J0Iz4sPHR5cGU+KSIpOwptb2R1bGVfcGFyYW1fYXJyYXlfbmFtZWQoZGV2MiwgZGI5WzFdLmFyZ3MsIGludCwgJmRiOVswXS5uYXJncywgMCk7Ck1PRFVMRV9QQVJNX0RFU0MoZGV2MiwgIkRlc2NyaWJlcyBzZWNvbmQgYXR0YWNoZWQgZGV2aWNlICg8cGFycG9ydCM+LDx0eXBlPikiKTsKbW9kdWxlX3BhcmFtX2FycmF5X25hbWVkKGRldjMsIGRiOVsyXS5hcmdzLCBpbnQsICZkYjlbMl0ubmFyZ3MsIDApOwpNT0RVTEVfUEFSTV9ERVNDKGRldjMsICJEZXNjcmliZXMgdGhpcmQgYXR0YWNoZWQgZGV2aWNlICg8cGFycG9ydCM+LDx0eXBlPikiKTsKCl9fb2Jzb2xldGVfc2V0dXAoImRiOT0iKTsKX19vYnNvbGV0ZV9zZXR1cCgiZGI5XzI9Iik7Cl9fb2Jzb2xldGVfc2V0dXAoImRiOV8zPSIpOwoKI2RlZmluZSBEQjlfQVJHX1BBUlBPUlQJCTAKI2RlZmluZSBEQjlfQVJHX01PREUJCTEKCiNkZWZpbmUgREI5X01VTFRJX1NUSUNLCQkweDAxCiNkZWZpbmUgREI5X01VTFRJMl9TVElDSwkweDAyCiNkZWZpbmUgREI5X0dFTkVTSVNfUEFECQkweDAzCiNkZWZpbmUgREI5X0dFTkVTSVM1X1BBRAkweDA1CiNkZWZpbmUgREI5X0dFTkVTSVM2X1BBRAkweDA2CiNkZWZpbmUgREI5X1NBVFVSTl9QQUQJCTB4MDcKI2RlZmluZSBEQjlfTVVMVElfMDgwMgkJMHgwOAojZGVmaW5lIERCOV9NVUxUSV8wODAyXzIJMHgwOQojZGVmaW5lIERCOV9DRDMyX1BBRAkJMHgwQQojZGVmaW5lIERCOV9TQVRVUk5fRFBQCQkweDBCCiNkZWZpbmUgREI5X1NBVFVSTl9EUFBfMgkweDBDCiNkZWZpbmUgREI5X01BWF9QQUQJCTB4MEQKCiNkZWZpbmUgREI5X1VQCQkJMHgwMQojZGVmaW5lIERCOV9ET1dOCQkweDAyCiNkZWZpbmUgREI5X0xFRlQJCTB4MDQKI2RlZmluZSBEQjlfUklHSFQJCTB4MDgKI2RlZmluZSBEQjlfRklSRTEJCTB4MTAKI2RlZmluZSBEQjlfRklSRTIJCTB4MjAKI2RlZmluZSBEQjlfRklSRTMJCTB4NDAKI2RlZmluZSBEQjlfRklSRTQJCTB4ODAKCiNkZWZpbmUgREI5X05PUk1BTAkJMHgwYQojZGVmaW5lIERCOV9OT1NFTEVDVAkJMHgwOAoKI2RlZmluZSBEQjlfR0VORVNJUzZfREVMQVkJMTQKI2RlZmluZSBEQjlfUkVGUkVTSF9USU1FCUhaLzEwMAoKI2RlZmluZSBEQjlfTUFYX0RFVklDRVMJCTIKCnN0cnVjdCBkYjlfbW9kZV9kYXRhIHsKCWNvbnN0IGNoYXIgKm5hbWU7Cgljb25zdCBzaG9ydCAqYnV0dG9uczsKCWludCBuX2J1dHRvbnM7CglpbnQgbl9wYWRzOwoJaW50IG5fYXhpczsKCWludCBiaWRpcmVjdGlvbmFsOwoJaW50IHJldmVyc2U7Cn07CgpzdHJ1Y3QgZGI5IHsKCXN0cnVjdCBpbnB1dF9kZXYgKmRldltEQjlfTUFYX0RFVklDRVNdOwoJc3RydWN0IHRpbWVyX2xpc3QgdGltZXI7CglzdHJ1Y3QgcGFyZGV2aWNlICpwZDsKCWludCBtb2RlOwoJaW50IHVzZWQ7CglzdHJ1Y3QgbXV0ZXggbXV0ZXg7CgljaGFyIHBoeXNbREI5X01BWF9ERVZJQ0VTXVszMl07Cn07CgpzdGF0aWMgc3RydWN0IGRiOSAqZGI5X2Jhc2VbM107CgpzdGF0aWMgY29uc3Qgc2hvcnQgZGI5X211bHRpX2J0bltdID0geyBCVE5fVFJJR0dFUiwgQlROX1RIVU1CIH07CnN0YXRpYyBjb25zdCBzaG9ydCBkYjlfZ2VuZXNpc19idG5bXSA9IHsgQlROX1NUQVJULCBCVE5fQSwgQlROX0IsIEJUTl9DLCBCVE5fWCwgQlROX1ksIEJUTl9aLCBCVE5fTU9ERSB9OwpzdGF0aWMgY29uc3Qgc2hvcnQgZGI5X2NkMzJfYnRuW10gPSB7IEJUTl9BLCBCVE5fQiwgQlROX0MsIEJUTl9YLCBCVE5fWSwgQlROX1osIEJUTl9UTCwgQlROX1RSLCBCVE5fU1RBUlQgfTsKc3RhdGljIGNvbnN0IHNob3J0IGRiOV9hYnNbXSA9IHsgQUJTX1gsIEFCU19ZLCBBQlNfUlgsIEFCU19SWSwgQUJTX1JaLCBBQlNfWiwgQUJTX0hBVDBYLCBBQlNfSEFUMFksIEFCU19IQVQxWCwgQUJTX0hBVDFZIH07CgpzdGF0aWMgY29uc3Qgc3RydWN0IGRiOV9tb2RlX2RhdGEgZGI5X21vZGVzW10gPSB7Cgl7IE5VTEwsCQkJCQkgTlVMTCwJCSAgMCwgIDAsICAwLCAgMCwgIDAgfSwKCXsgIk11bHRpc3lzdGVtIGpveXN0aWNrIiwJCSBkYjlfbXVsdGlfYnRuLAkgIDEsICAxLCAgMiwgIDEsICAxIH0sCgl7ICJNdWx0aXN5c3RlbSBqb3lzdGljayAoMiBmaXJlKSIsCSBkYjlfbXVsdGlfYnRuLAkgIDIsICAxLCAgMiwgIDEsICAxIH0sCgl7ICJHZW5lc2lzIHBhZCIsCQkJIGRiOV9nZW5lc2lzX2J0biwgNCwgIDEsICAyLCAgMSwgIDEgfSwKCXsgTlVMTCwJCQkJCSBOVUxMLAkJICAwLCAgMCwgIDAsICAwLCAgMCB9LAoJeyAiR2VuZXNpcyA1IHBhZCIsCQkJIGRiOV9nZW5lc2lzX2J0biwgNiwgIDEsICAyLCAgMSwgIDEgfSwKCXsgIkdlbmVzaXMgNiBwYWQiLAkJCSBkYjlfZ2VuZXNpc19idG4sIDgsICAxLCAgMiwgIDEsICAxIH0sCgl7ICJTYXR1cm4gcGFkIiwJCQkJIGRiOV9jZDMyX2J0biwJICA5LCAgNiwgIDcsICAwLCAgMSB9LAoJeyAiTXVsdGlzeXN0ZW0gKDAuOC4wLjIpIGpveXN0aWNrIiwJIGRiOV9tdWx0aV9idG4sCSAgMSwgIDEsICAyLCAgMSwgIDEgfSwKCXsgIk11bHRpc3lzdGVtICgwLjguMC4yLWR1YWwpIGpveXN0aWNrIiwgZGI5X211bHRpX2J0biwJICAxLCAgMiwgIDIsICAxLCAgMSB9LAoJeyAiQW1pZ2EgQ0QtMzIgcGFkIiwJCQkgZGI5X2NkMzJfYnRuLAkgIDcsICAxLCAgMiwgIDEsICAxIH0sCgl7ICJTYXR1cm4gZHBwIiwJCQkJIGRiOV9jZDMyX2J0biwJICA5LCAgNiwgIDcsICAwLCAgMCB9LAoJeyAiU2F0dXJuIGRwcCBkdWFsIiwJCQkgZGI5X2NkMzJfYnRuLAkgIDksICAxMiwgNywgIDAsICAwIH0sCn07CgovKgogKiBTYXR1cm4gY29udHJvbGxlcnMKICovCiNkZWZpbmUgREI5X1NBVFVSTl9ERUxBWSAzMDAKc3RhdGljIGNvbnN0IGludCBkYjlfc2F0dXJuX2J5dGVbXSA9IHsgMSwgMSwgMSwgMiwgMiwgMiwgMiwgMiwgMSB9OwpzdGF0aWMgY29uc3QgdW5zaWduZWQgY2hhciBkYjlfc2F0dXJuX21hc2tbXSA9IHsgMHgwNCwgMHgwMSwgMHgwMiwgMHg0MCwgMHgyMCwgMHgxMCwgMHgwOCwgMHg4MCwgMHgwOCB9OwoKLyoKICogZGI5X3NhdHVybl93cml0ZV9zdWIoKSB3cml0ZXMgMiBiaXQgZGF0YS4KICovCnN0YXRpYyB2b2lkIGRiOV9zYXR1cm5fd3JpdGVfc3ViKHN0cnVjdCBwYXJwb3J0ICpwb3J0LCBpbnQgdHlwZSwgdW5zaWduZWQgY2hhciBkYXRhLCBpbnQgcG93ZXJlZCwgaW50IHB3cl9zdWIpCnsKCXVuc2lnbmVkIGNoYXIgYzsKCglzd2l0Y2ggKHR5cGUpIHsKCWNhc2UgMTogLyogRFBQMSAqLwoJCWMgPSAweDgwIHwgMHgzMCB8IChwb3dlcmVkID8gMHgwOCA6IDApIHwgKHB3cl9zdWIgPyAweDA0IDogMCkgfCBkYXRhOwoJCXBhcnBvcnRfd3JpdGVfZGF0YShwb3J0LCBjKTsKCQlicmVhazsKCWNhc2UgMjogLyogRFBQMiAqLwoJCWMgPSAweDQwIHwgZGF0YSA8PCA0IHwgKHBvd2VyZWQgPyAweDA4IDogMCkgfCAocHdyX3N1YiA/IDB4MDQgOiAwKSB8IDB4MDM7CgkJcGFycG9ydF93cml0ZV9kYXRhKHBvcnQsIGMpOwoJCWJyZWFrOwoJY2FzZSAwOgkvKiBEQjkgKi8KCQljID0gKCgoKGRhdGEgJiAyKSA/IDIgOiAwKSB8ICgoZGF0YSAmIDEpID8gNCA6IDApKSBeIDB4MDIpIHwgIXBvd2VyZWQ7CgkJcGFycG9ydF93cml0ZV9jb250cm9sKHBvcnQsIGMpOwoJCWJyZWFrOwoJfQp9CgovKgogKiBnY19zYXR1cm5fcmVhZF9zdWIoKSByZWFkcyA0IGJpdCBkYXRhLgogKi8Kc3RhdGljIHVuc2lnbmVkIGNoYXIgZGI5X3NhdHVybl9yZWFkX3N1YihzdHJ1Y3QgcGFycG9ydCAqcG9ydCwgaW50IHR5cGUpCnsKCXVuc2lnbmVkIGNoYXIgZGF0YTsKCglpZiAodHlwZSkgewoJCS8qIERQUCAqLwoJCWRhdGEgPSBwYXJwb3J0X3JlYWRfc3RhdHVzKHBvcnQpIF4gMHg4MDsKCQlyZXR1cm4gKGRhdGEgJiAweDgwID8gMSA6IDApIHwgKGRhdGEgJiAweDQwID8gMiA6IDApCgkJICAgICB8IChkYXRhICYgMHgyMCA/IDQgOiAwKSB8IChkYXRhICYgMHgxMCA/IDggOiAwKTsKCX0gZWxzZSB7CgkJLyogREI5ICovCgkJZGF0YSA9IHBhcnBvcnRfcmVhZF9kYXRhKHBvcnQpICYgMHgwZjsKCQlyZXR1cm4gKGRhdGEgJiAweDggPyAxIDogMCkgfCAoZGF0YSAmIDB4NCA/IDIgOiAwKQoJCSAgICAgfCAoZGF0YSAmIDB4MiA/IDQgOiAwKSB8IChkYXRhICYgMHgxID8gOCA6IDApOwoJfQp9CgovKgogKiBkYjlfc2F0dXJuX3JlYWRfYW5hbG9nKCkgc2VuZHMgY2xvY2sgYW5kIHJlYWRzIDggYml0IGRhdGEuCiAqLwpzdGF0aWMgdW5zaWduZWQgY2hhciBkYjlfc2F0dXJuX3JlYWRfYW5hbG9nKHN0cnVjdCBwYXJwb3J0ICpwb3J0LCBpbnQgdHlwZSwgaW50IHBvd2VyZWQpCnsKCXVuc2lnbmVkIGNoYXIgZGF0YTsKCglkYjlfc2F0dXJuX3dyaXRlX3N1Yihwb3J0LCB0eXBlLCAwLCBwb3dlcmVkLCAwKTsKCXVkZWxheShEQjlfU0FUVVJOX0RFTEFZKTsKCWRhdGEgPSBkYjlfc2F0dXJuX3JlYWRfc3ViKHBvcnQsIHR5cGUpIDw8IDQ7CglkYjlfc2F0dXJuX3dyaXRlX3N1Yihwb3J0LCB0eXBlLCAyLCBwb3dlcmVkLCAwKTsKCXVkZWxheShEQjlfU0FUVVJOX0RFTEFZKTsKCWRhdGEgfD0gZGI5X3NhdHVybl9yZWFkX3N1Yihwb3J0LCB0eXBlKTsKCXJldHVybiBkYXRhOwp9CgovKgogKiBkYjlfc2F0dXJuX3JlYWRfcGFja2V0KCkgcmVhZHMgd2hvbGUgc2F0dXJuIHBhY2tldCBhdCBjb25uZWN0b3IKICogYW5kIHJldHVybnMgZGV2aWNlIGlkZW50aWZpZXIgY29kZS4KICovCnN0YXRpYyB1bnNpZ25lZCBjaGFyIGRiOV9zYXR1cm5fcmVhZF9wYWNrZXQoc3RydWN0IHBhcnBvcnQgKnBvcnQsIHVuc2lnbmVkIGNoYXIgKmRhdGEsIGludCB0eXBlLCBpbnQgcG93ZXJlZCkKewoJaW50IGksIGo7Cgl1bnNpZ25lZCBjaGFyIHRtcDsKCglkYjlfc2F0dXJuX3dyaXRlX3N1Yihwb3J0LCB0eXBlLCAzLCBwb3dlcmVkLCAwKTsKCWRhdGFbMF0gPSBkYjlfc2F0dXJuX3JlYWRfc3ViKHBvcnQsIHR5cGUpOwoJc3dpdGNoIChkYXRhWzBdICYgMHgwZikgewoJY2FzZSAweGY6CgkJLyogMTExMSAgbm8gcGFkICovCgkJcmV0dXJuIGRhdGFbMF0gPSAweGZmOwoJY2FzZSAweDQ6IGNhc2UgMHg0IHwgMHg4OgoJCS8qID8xMDAgOiBkaWdpdGFsIGNvbnRyb2xsZXIgKi8KCQlkYjlfc2F0dXJuX3dyaXRlX3N1Yihwb3J0LCB0eXBlLCAwLCBwb3dlcmVkLCAxKTsKCQlkYXRhWzJdID0gZGI5X3NhdHVybl9yZWFkX3N1Yihwb3J0LCB0eXBlKSA8PCA0OwoJCWRiOV9zYXR1cm5fd3JpdGVfc3ViKHBvcnQsIHR5cGUsIDIsIHBvd2VyZWQsIDEpOwoJCWRhdGFbMV0gPSBkYjlfc2F0dXJuX3JlYWRfc3ViKHBvcnQsIHR5cGUpIDw8IDQ7CgkJZGI5X3NhdHVybl93cml0ZV9zdWIocG9ydCwgdHlwZSwgMSwgcG93ZXJlZCwgMSk7CgkJZGF0YVsxXSB8PSBkYjlfc2F0dXJuX3JlYWRfc3ViKHBvcnQsIHR5cGUpOwoJCWRiOV9zYXR1cm5fd3JpdGVfc3ViKHBvcnQsIHR5cGUsIDMsIHBvd2VyZWQsIDEpOwoJCS8qIGRhdGFbMl0gfD0gZGI5X3NhdHVybl9yZWFkX3N1Yihwb3J0LCB0eXBlKTsgKi8KCQlkYXRhWzJdIHw9IGRhdGFbMF07CgkJcmV0dXJuIGRhdGFbMF0gPSAweDAyOwoJY2FzZSAweDE6CgkJLyogMDAwMSA6IGFuYWxvZyBjb250cm9sbGVyIG9yIG11bHRpdGFwICovCgkJZGI5X3NhdHVybl93cml0ZV9zdWIocG9ydCwgdHlwZSwgMiwgcG93ZXJlZCwgMCk7CgkJdWRlbGF5KERCOV9TQVRVUk5fREVMQVkpOwoJCWRhdGFbMF0gPSBkYjlfc2F0dXJuX3JlYWRfYW5hbG9nKHBvcnQsIHR5cGUsIHBvd2VyZWQpOwoJCWlmIChkYXRhWzBdICE9IDB4NDEpIHsKCQkJLyogcmVhZCBhbmFsb2cgY29udHJvbGxlciAqLwoJCQlmb3IgKGkgPSAwOyBpIDwgKGRhdGFbMF0gJiAweDBmKTsgaSsrKQoJCQkJZGF0YVtpICsgMV0gPSBkYjlfc2F0dXJuX3JlYWRfYW5hbG9nKHBvcnQsIHR5cGUsIHBvd2VyZWQpOwoJCQlkYjlfc2F0dXJuX3dyaXRlX3N1Yihwb3J0LCB0eXBlLCAzLCBwb3dlcmVkLCAwKTsKCQkJcmV0dXJuIGRhdGFbMF07CgkJfSBlbHNlIHsKCQkJLyogcmVhZCBtdWx0aXRhcCAqLwoJCQlpZiAoZGI5X3NhdHVybl9yZWFkX2FuYWxvZyhwb3J0LCB0eXBlLCBwb3dlcmVkKSAhPSAweDYwKQoJCQkJcmV0dXJuIGRhdGFbMF0gPSAweGZmOwoJCQlmb3IgKGkgPSAwOyBpIDwgNjA7IGkgKz0gMTApIHsKCQkJCWRhdGFbaV0gPSBkYjlfc2F0dXJuX3JlYWRfYW5hbG9nKHBvcnQsIHR5cGUsIHBvd2VyZWQpOwoJCQkJaWYgKGRhdGFbaV0gIT0gMHhmZikKCQkJCQkvKiByZWFkIGVhY2ggcGFkICovCgkJCQkJZm9yIChqID0gMDsgaiA8IChkYXRhW2ldICYgMHgwZik7IGorKykKCQkJCQkJZGF0YVtpICsgaiArIDFdID0gZGI5X3NhdHVybl9yZWFkX2FuYWxvZyhwb3J0LCB0eXBlLCBwb3dlcmVkKTsKCQkJfQoJCQlkYjlfc2F0dXJuX3dyaXRlX3N1Yihwb3J0LCB0eXBlLCAzLCBwb3dlcmVkLCAwKTsKCQkJcmV0dXJuIDB4NDE7CgkJfQoJY2FzZSAweDA6CgkJLyogMDAwMCA6IG1vdXNlICovCgkJZGI5X3NhdHVybl93cml0ZV9zdWIocG9ydCwgdHlwZSwgMiwgcG93ZXJlZCwgMCk7CgkJdWRlbGF5KERCOV9TQVRVUk5fREVMQVkpOwoJCXRtcCA9IGRiOV9zYXR1cm5fcmVhZF9hbmFsb2cocG9ydCwgdHlwZSwgcG93ZXJlZCk7CgkJaWYgKHRtcCA9PSAweGZmKSB7CgkJCWZvciAoaSA9IDA7IGkgPCAzOyBpKyspCgkJCQlkYXRhW2kgKyAxXSA9IGRiOV9zYXR1cm5fcmVhZF9hbmFsb2cocG9ydCwgdHlwZSwgcG93ZXJlZCk7CgkJCWRiOV9zYXR1cm5fd3JpdGVfc3ViKHBvcnQsIHR5cGUsIDMsIHBvd2VyZWQsIDApOwoJCQlyZXR1cm4gZGF0YVswXSA9IDB4ZTM7CgkJfQoJZGVmYXVsdDoKCQlyZXR1cm4gZGF0YVswXTsKCX0KfQoKLyoKICogZGI5X3NhdHVybl9yZXBvcnQoKSBhbmFseXplcyBwYWNrZXQgYW5kIHJlcG9ydHMuCiAqLwpzdGF0aWMgaW50IGRiOV9zYXR1cm5fcmVwb3J0KHVuc2lnbmVkIGNoYXIgaWQsIHVuc2lnbmVkIGNoYXIgZGF0YVs2MF0sIHN0cnVjdCBpbnB1dF9kZXYgKmRldnNbXSwgaW50IG4sIGludCBtYXhfcGFkcykKewoJc3RydWN0IGlucHV0X2RldiAqZGV2OwoJaW50IHRtcCwgaSwgajsKCgl0bXAgPSAoaWQgPT0gMHg0MSkgPyA2MCA6IDEwOwoJZm9yIChqID0gMDsgaiA8IHRtcCAmJiBuIDwgbWF4X3BhZHM7IGogKz0gMTAsIG4rKykgewoJCWRldiA9IGRldnNbbl07CgkJc3dpdGNoIChkYXRhW2pdKSB7CgkJY2FzZSAweDE2OiAvKiBtdWx0aSBjb250cm9sbGVyIChhbmFsb2cgNCBheGlzKSAqLwoJCQlpbnB1dF9yZXBvcnRfYWJzKGRldiwgZGI5X2Fic1s1XSwgZGF0YVtqICsgNl0pOwoJCWNhc2UgMHgxNTogLyogbWlzc2lvbiBzdGljayAoYW5hbG9nIDMgYXhpcykgKi8KCQkJaW5wdXRfcmVwb3J0X2FicyhkZXYsIGRiOV9hYnNbM10sIGRhdGFbaiArIDRdKTsKCQkJaW5wdXRfcmVwb3J0X2FicyhkZXYsIGRiOV9hYnNbNF0sIGRhdGFbaiArIDVdKTsKCQljYXNlIDB4MTM6IC8qIHJhY2luZyBjb250cm9sbGVyIChhbmFsb2cgMSBheGlzKSAqLwoJCQlpbnB1dF9yZXBvcnRfYWJzKGRldiwgZGI5X2Fic1syXSwgZGF0YVtqICsgM10pOwoJCWNhc2UgMHgzNDogLyogc2F0dXJuIGtleWJvYXJkICh1ZGxyIFpYQyBBU0QgUUUgRXNjKSAqLwoJCWNhc2UgMHgwMjogLyogZGlnaXRhbCBwYWQgKGRpZ2l0YWwgMiBheGlzICsgYnV0dG9ucykgKi8KCQkJaW5wdXRfcmVwb3J0X2FicyhkZXYsIGRiOV9hYnNbMF0sICEoZGF0YVtqICsgMV0gJiAxMjgpIC0gIShkYXRhW2ogKyAxXSAmIDY0KSk7CgkJCWlucHV0X3JlcG9ydF9hYnMoZGV2LCBkYjlfYWJzWzFdLCAhKGRhdGFbaiArIDFdICYgMzIpIC0gIShkYXRhW2ogKyAxXSAmIDE2KSk7CgkJCWZvciAoaSA9IDA7IGkgPCA5OyBpKyspCgkJCQlpbnB1dF9yZXBvcnRfa2V5KGRldiwgZGI5X2NkMzJfYnRuW2ldLCB+ZGF0YVtqICsgZGI5X3NhdHVybl9ieXRlW2ldXSAmIGRiOV9zYXR1cm5fbWFza1tpXSk7CgkJCWJyZWFrOwoJCWNhc2UgMHgxOTogLyogbWlzc2lvbiBzdGljayB4MiAoYW5hbG9nIDYgYXhpcyArIGJ1dHRvbnMpICovCgkJCWlucHV0X3JlcG9ydF9hYnMoZGV2LCBkYjlfYWJzWzBdLCAhKGRhdGFbaiArIDFdICYgMTI4KSAtICEoZGF0YVtqICsgMV0gJiA2NCkpOwoJCQlpbnB1dF9yZXBvcnRfYWJzKGRldiwgZGI5X2Fic1sxXSwgIShkYXRhW2ogKyAxXSAmIDMyKSAtICEoZGF0YVtqICsgMV0gJiAxNikpOwoJCQlmb3IgKGkgPSAwOyBpIDwgOTsgaSsrKQoJCQkJaW5wdXRfcmVwb3J0X2tleShkZXYsIGRiOV9jZDMyX2J0bltpXSwgfmRhdGFbaiArIGRiOV9zYXR1cm5fYnl0ZVtpXV0gJiBkYjlfc2F0dXJuX21hc2tbaV0pOwoJCQlpbnB1dF9yZXBvcnRfYWJzKGRldiwgZGI5X2Fic1syXSwgZGF0YVtqICsgM10pOwoJCQlpbnB1dF9yZXBvcnRfYWJzKGRldiwgZGI5X2Fic1szXSwgZGF0YVtqICsgNF0pOwoJCQlpbnB1dF9yZXBvcnRfYWJzKGRldiwgZGI5X2Fic1s0XSwgZGF0YVtqICsgNV0pOwoJCQkvKgoJCQlpbnB1dF9yZXBvcnRfYWJzKGRldiwgZGI5X2Fic1s4XSwgKGRhdGFbaiArIDZdICYgMTI4ID8gMCA6IDEpIC0gKGRhdGFbaiArIDZdICYgNjQgPyAwIDogMSkpOwoJCQlpbnB1dF9yZXBvcnRfYWJzKGRldiwgZGI5X2Fic1s5XSwgKGRhdGFbaiArIDZdICYgMzIgPyAwIDogMSkgLSAoZGF0YVtqICsgNl0gJiAxNiA/IDAgOiAxKSk7CgkJCSovCgkJCWlucHV0X3JlcG9ydF9hYnMoZGV2LCBkYjlfYWJzWzZdLCBkYXRhW2ogKyA3XSk7CgkJCWlucHV0X3JlcG9ydF9hYnMoZGV2LCBkYjlfYWJzWzddLCBkYXRhW2ogKyA4XSk7CgkJCWlucHV0X3JlcG9ydF9hYnMoZGV2LCBkYjlfYWJzWzVdLCBkYXRhW2ogKyA5XSk7CgkJCWJyZWFrOwoJCWNhc2UgMHhkMzogLyogc2Fua3lvIGZmIChhbmFsb2cgMSBheGlzICsgc3RvcCBidG4pICovCgkJCWlucHV0X3JlcG9ydF9rZXkoZGV2LCBCVE5fQSwgZGF0YVtqICsgM10gJiAweDgwKTsKCQkJaW5wdXRfcmVwb3J0X2FicyhkZXYsIGRiOV9hYnNbMl0sIGRhdGFbaiArIDNdICYgMHg3Zik7CgkJCWJyZWFrOwoJCWNhc2UgMHhlMzogLyogc2h1dHRsZSBtb3VzZSAoYW5hbG9nIDIgYXhpcyArIGJ1dHRvbnMuIHNpZ25lZCB2YWx1ZSkgKi8KCQkJaW5wdXRfcmVwb3J0X2tleShkZXYsIEJUTl9TVEFSVCwgZGF0YVtqICsgMV0gJiAweDA4KTsKCQkJaW5wdXRfcmVwb3J0X2tleShkZXYsIEJUTl9BLCBkYXRhW2ogKyAxXSAmIDB4MDQpOwoJCQlpbnB1dF9yZXBvcnRfa2V5KGRldiwgQlROX0MsIGRhdGFbaiArIDFdICYgMHgwMik7CgkJCWlucHV0X3JlcG9ydF9rZXkoZGV2LCBCVE5fQiwgZGF0YVtqICsgMV0gJiAweDAxKTsKCQkJaW5wdXRfcmVwb3J0X2FicyhkZXYsIGRiOV9hYnNbMl0sIGRhdGFbaiArIDJdIF4gMHg4MCk7CgkJCWlucHV0X3JlcG9ydF9hYnMoZGV2LCBkYjlfYWJzWzNdLCAoMHhmZi0oZGF0YVtqICsgM10gXiAweDgwKSkrMSk7IC8qICovCgkJCWJyZWFrOwoJCWNhc2UgMHhmZjoKCQlkZWZhdWx0OiAvKiBubyBwYWQgKi8KCQkJaW5wdXRfcmVwb3J0X2FicyhkZXYsIGRiOV9hYnNbMF0sIDApOwoJCQlpbnB1dF9yZXBvcnRfYWJzKGRldiwgZGI5X2Fic1sxXSwgMCk7CgkJCWZvciAoaSA9IDA7IGkgPCA5OyBpKyspCgkJCQlpbnB1dF9yZXBvcnRfa2V5KGRldiwgZGI5X2NkMzJfYnRuW2ldLCAwKTsKCQkJYnJlYWs7CgkJfQoJfQoJcmV0dXJuIG47Cn0KCnN0YXRpYyBpbnQgZGI5X3NhdHVybihpbnQgbW9kZSwgc3RydWN0IHBhcnBvcnQgKnBvcnQsIHN0cnVjdCBpbnB1dF9kZXYgKmRldnNbXSkKewoJdW5zaWduZWQgY2hhciBpZCwgZGF0YVs2MF07CglpbnQgdHlwZSwgbiwgbWF4X3BhZHM7CglpbnQgdG1wLCBpOwoKCXN3aXRjaCAobW9kZSkgewoJY2FzZSBEQjlfU0FUVVJOX1BBRDoKCQl0eXBlID0gMDsKCQluID0gMTsKCQlicmVhazsKCWNhc2UgREI5X1NBVFVSTl9EUFA6CgkJdHlwZSA9IDE7CgkJbiA9IDE7CgkJYnJlYWs7CgljYXNlIERCOV9TQVRVUk5fRFBQXzI6CgkJdHlwZSA9IDE7CgkJbiA9IDI7CgkJYnJlYWs7CglkZWZhdWx0OgoJCXJldHVybiAtMTsKCX0KCW1heF9wYWRzID0gbWluKGRiOV9tb2Rlc1ttb2RlXS5uX3BhZHMsIERCOV9NQVhfREVWSUNFUyk7Cglmb3IgKHRtcCA9IDAsIGkgPSAwOyBpIDwgbjsgaSsrKSB7CgkJaWQgPSBkYjlfc2F0dXJuX3JlYWRfcGFja2V0KHBvcnQsIGRhdGEsIHR5cGUgKyBpLCAxKTsKCQl0bXAgPSBkYjlfc2F0dXJuX3JlcG9ydChpZCwgZGF0YSwgZGV2cywgdG1wLCBtYXhfcGFkcyk7Cgl9CglyZXR1cm4gMDsKfQoKc3RhdGljIHZvaWQgZGI5X3RpbWVyKHVuc2lnbmVkIGxvbmcgcHJpdmF0ZSkKewoJc3RydWN0IGRiOSAqZGI5ID0gKHZvaWQgKikgcHJpdmF0ZTsKCXN0cnVjdCBwYXJwb3J0ICpwb3J0ID0gZGI5LT5wZC0+cG9ydDsKCXN0cnVjdCBpbnB1dF9kZXYgKmRldiA9IGRiOS0+ZGV2WzBdOwoJc3RydWN0IGlucHV0X2RldiAqZGV2MiA9IGRiOS0+ZGV2WzFdOwoJaW50IGRhdGEsIGk7CgoJc3dpdGNoIChkYjktPm1vZGUpIHsKCQljYXNlIERCOV9NVUxUSV8wODAyXzI6CgoJCQlkYXRhID0gcGFycG9ydF9yZWFkX2RhdGEocG9ydCkgPj4gMzsKCgkJCWlucHV0X3JlcG9ydF9hYnMoZGV2MiwgQUJTX1gsIChkYXRhICYgREI5X1JJR0hUID8gMCA6IDEpIC0gKGRhdGEgJiBEQjlfTEVGVCA/IDAgOiAxKSk7CgkJCWlucHV0X3JlcG9ydF9hYnMoZGV2MiwgQUJTX1ksIChkYXRhICYgREI5X0RPV04gID8gMCA6IDEpIC0gKGRhdGEgJiBEQjlfVVAgICA/IDAgOiAxKSk7CgkJCWlucHV0X3JlcG9ydF9rZXkoZGV2MiwgQlROX1RSSUdHRVIsIH5kYXRhICYgREI5X0ZJUkUxKTsKCgkJY2FzZSBEQjlfTVVMVElfMDgwMjoKCgkJCWRhdGEgPSBwYXJwb3J0X3JlYWRfc3RhdHVzKHBvcnQpID4+IDM7CgoJCQlpbnB1dF9yZXBvcnRfYWJzKGRldiwgQUJTX1gsIChkYXRhICYgREI5X1JJR0hUID8gMCA6IDEpIC0gKGRhdGEgJiBEQjlfTEVGVCA/IDAgOiAxKSk7CgkJCWlucHV0X3JlcG9ydF9hYnMoZGV2LCBBQlNfWSwgKGRhdGEgJiBEQjlfRE9XTiAgPyAwIDogMSkgLSAoZGF0YSAmIERCOV9VUCAgID8gMCA6IDEpKTsKCQkJaW5wdXRfcmVwb3J0X2tleShkZXYsIEJUTl9UUklHR0VSLCBkYXRhICYgREI5X0ZJUkUxKTsKCQkJYnJlYWs7CgoJCWNhc2UgREI5X01VTFRJX1NUSUNLOgoKCQkJZGF0YSA9IHBhcnBvcnRfcmVhZF9kYXRhKHBvcnQpOwoKCQkJaW5wdXRfcmVwb3J0X2FicyhkZXYsIEFCU19YLCAoZGF0YSAmIERCOV9SSUdIVCA/IDAgOiAxKSAtIChkYXRhICYgREI5X0xFRlQgPyAwIDogMSkpOwoJCQlpbnB1dF9yZXBvcnRfYWJzKGRldiwgQUJTX1ksIChkYXRhICYgREI5X0RPV04gID8gMCA6IDEpIC0gKGRhdGEgJiBEQjlfVVAgICA/IDAgOiAxKSk7CgkJCWlucHV0X3JlcG9ydF9rZXkoZGV2LCBCVE5fVFJJR0dFUiwgfmRhdGEgJiBEQjlfRklSRTEpOwoJCQlicmVhazsKCgkJY2FzZSBEQjlfTVVMVEkyX1NUSUNLOgoKCQkJZGF0YSA9IHBhcnBvcnRfcmVhZF9kYXRhKHBvcnQpOwoKCQkJaW5wdXRfcmVwb3J0X2FicyhkZXYsIEFCU19YLCAoZGF0YSAmIERCOV9SSUdIVCA/IDAgOiAxKSAtIChkYXRhICYgREI5X0xFRlQgPyAwIDogMSkpOwoJCQlpbnB1dF9yZXBvcnRfYWJzKGRldiwgQUJTX1ksIChkYXRhICYgREI5X0RPV04gID8gMCA6IDEpIC0gKGRhdGEgJiBEQjlfVVAgICA/IDAgOiAxKSk7CgkJCWlucHV0X3JlcG9ydF9rZXkoZGV2LCBCVE5fVFJJR0dFUiwgfmRhdGEgJiBEQjlfRklSRTEpOwoJCQlpbnB1dF9yZXBvcnRfa2V5KGRldiwgQlROX1RIVU1CLCAgIH5kYXRhICYgREI5X0ZJUkUyKTsKCQkJYnJlYWs7CgoJCWNhc2UgREI5X0dFTkVTSVNfUEFEOgoKCQkJcGFycG9ydF93cml0ZV9jb250cm9sKHBvcnQsIERCOV9OT1NFTEVDVCk7CgkJCWRhdGEgPSBwYXJwb3J0X3JlYWRfZGF0YShwb3J0KTsKCgkJCWlucHV0X3JlcG9ydF9hYnMoZGV2LCBBQlNfWCwgKGRhdGEgJiBEQjlfUklHSFQgPyAwIDogMSkgLSAoZGF0YSAmIERCOV9MRUZUID8gMCA6IDEpKTsKCQkJaW5wdXRfcmVwb3J0X2FicyhkZXYsIEFCU19ZLCAoZGF0YSAmIERCOV9ET1dOICA/IDAgOiAxKSAtIChkYXRhICYgREI5X1VQICAgPyAwIDogMSkpOwoJCQlpbnB1dF9yZXBvcnRfa2V5KGRldiwgQlROX0IsIH5kYXRhICYgREI5X0ZJUkUxKTsKCQkJaW5wdXRfcmVwb3J0X2tleShkZXYsIEJUTl9DLCB+ZGF0YSAmIERCOV9GSVJFMik7CgoJCQlwYXJwb3J0X3dyaXRlX2NvbnRyb2wocG9ydCwgREI5X05PUk1BTCk7CgkJCWRhdGEgPSBwYXJwb3J0X3JlYWRfZGF0YShwb3J0KTsKCgkJCWlucHV0X3JlcG9ydF9rZXkoZGV2LCBCVE5fQSwgICAgIH5kYXRhICYgREI5X0ZJUkUxKTsKCQkJaW5wdXRfcmVwb3J0X2tleShkZXYsIEJUTl9TVEFSVCwgfmRhdGEgJiBEQjlfRklSRTIpOwoJCQlicmVhazsKCgkJY2FzZSBEQjlfR0VORVNJUzVfUEFEOgoKCQkJcGFycG9ydF93cml0ZV9jb250cm9sKHBvcnQsIERCOV9OT1NFTEVDVCk7CgkJCWRhdGEgPSBwYXJwb3J0X3JlYWRfZGF0YShwb3J0KTsKCgkJCWlucHV0X3JlcG9ydF9hYnMoZGV2LCBBQlNfWCwgKGRhdGEgJiBEQjlfUklHSFQgPyAwIDogMSkgLSAoZGF0YSAmIERCOV9MRUZUID8gMCA6IDEpKTsKCQkJaW5wdXRfcmVwb3J0X2FicyhkZXYsIEFCU19ZLCAoZGF0YSAmIERCOV9ET1dOICA/IDAgOiAxKSAtIChkYXRhICYgREI5X1VQICAgPyAwIDogMSkpOwoJCQlpbnB1dF9yZXBvcnRfa2V5KGRldiwgQlROX0IsIH5kYXRhICYgREI5X0ZJUkUxKTsKCQkJaW5wdXRfcmVwb3J0X2tleShkZXYsIEJUTl9DLCB+ZGF0YSAmIERCOV9GSVJFMik7CgoJCQlwYXJwb3J0X3dyaXRlX2NvbnRyb2wocG9ydCwgREI5X05PUk1BTCk7CgkJCWRhdGEgPSBwYXJwb3J0X3JlYWRfZGF0YShwb3J0KTsKCgkJCWlucHV0X3JlcG9ydF9rZXkoZGV2LCBCVE5fQSwgICAgIH5kYXRhICYgREI5X0ZJUkUxKTsKCQkJaW5wdXRfcmVwb3J0X2tleShkZXYsIEJUTl9YLCAgICAgfmRhdGEgJiBEQjlfRklSRTIpOwoJCQlpbnB1dF9yZXBvcnRfa2V5KGRldiwgQlROX1ksICAgICB+ZGF0YSAmIERCOV9MRUZUKTsKCQkJaW5wdXRfcmVwb3J0X2tleShkZXYsIEJUTl9TVEFSVCwgfmRhdGEgJiBEQjlfUklHSFQpOwoJCQlicmVhazsKCgkJY2FzZSBEQjlfR0VORVNJUzZfUEFEOgoKCQkJcGFycG9ydF93cml0ZV9jb250cm9sKHBvcnQsIERCOV9OT1NFTEVDVCk7IC8qIDEgKi8KCQkJdWRlbGF5KERCOV9HRU5FU0lTNl9ERUxBWSk7CgkJCWRhdGEgPSBwYXJwb3J0X3JlYWRfZGF0YShwb3J0KTsKCgkJCWlucHV0X3JlcG9ydF9hYnMoZGV2LCBBQlNfWCwgKGRhdGEgJiBEQjlfUklHSFQgPyAwIDogMSkgLSAoZGF0YSAmIERCOV9MRUZUID8gMCA6IDEpKTsKCQkJaW5wdXRfcmVwb3J0X2FicyhkZXYsIEFCU19ZLCAoZGF0YSAmIERCOV9ET1dOICA/IDAgOiAxKSAtIChkYXRhICYgREI5X1VQICAgPyAwIDogMSkpOwoJCQlpbnB1dF9yZXBvcnRfa2V5KGRldiwgQlROX0IsIH5kYXRhICYgREI5X0ZJUkUxKTsKCQkJaW5wdXRfcmVwb3J0X2tleShkZXYsIEJUTl9DLCB+ZGF0YSAmIERCOV9GSVJFMik7CgoJCQlwYXJwb3J0X3dyaXRlX2NvbnRyb2wocG9ydCwgREI5X05PUk1BTCk7CgkJCXVkZWxheShEQjlfR0VORVNJUzZfREVMQVkpOwoJCQlkYXRhID0gcGFycG9ydF9yZWFkX2RhdGEocG9ydCk7CgoJCQlpbnB1dF9yZXBvcnRfa2V5KGRldiwgQlROX0EsIH5kYXRhICYgREI5X0ZJUkUxKTsKCQkJaW5wdXRfcmVwb3J0X2tleShkZXYsIEJUTl9TVEFSVCwgfmRhdGEgJiBEQjlfRklSRTIpOwoKCQkJcGFycG9ydF93cml0ZV9jb250cm9sKHBvcnQsIERCOV9OT1NFTEVDVCk7IC8qIDIgKi8KCQkJdWRlbGF5KERCOV9HRU5FU0lTNl9ERUxBWSk7CgkJCXBhcnBvcnRfd3JpdGVfY29udHJvbChwb3J0LCBEQjlfTk9STUFMKTsKCQkJdWRlbGF5KERCOV9HRU5FU0lTNl9ERUxBWSk7CgkJCXBhcnBvcnRfd3JpdGVfY29udHJvbChwb3J0LCBEQjlfTk9TRUxFQ1QpOyAvKiAzICovCgkJCXVkZWxheShEQjlfR0VORVNJUzZfREVMQVkpOwoJCQlkYXRhPXBhcnBvcnRfcmVhZF9kYXRhKHBvcnQpOwoKCQkJaW5wdXRfcmVwb3J0X2tleShkZXYsIEJUTl9YLCAgICB+ZGF0YSAmIERCOV9MRUZUKTsKCQkJaW5wdXRfcmVwb3J0X2tleShkZXYsIEJUTl9ZLCAgICB+ZGF0YSAmIERCOV9ET1dOKTsKCQkJaW5wdXRfcmVwb3J0X2tleShkZXYsIEJUTl9aLCAgICB+ZGF0YSAmIERCOV9VUCk7CgkJCWlucHV0X3JlcG9ydF9rZXkoZGV2LCBCVE5fTU9ERSwgfmRhdGEgJiBEQjlfUklHSFQpOwoKCQkJcGFycG9ydF93cml0ZV9jb250cm9sKHBvcnQsIERCOV9OT1JNQUwpOwoJCQl1ZGVsYXkoREI5X0dFTkVTSVM2X0RFTEFZKTsKCQkJcGFycG9ydF93cml0ZV9jb250cm9sKHBvcnQsIERCOV9OT1NFTEVDVCk7IC8qIDQgKi8KCQkJdWRlbGF5KERCOV9HRU5FU0lTNl9ERUxBWSk7CgkJCXBhcnBvcnRfd3JpdGVfY29udHJvbChwb3J0LCBEQjlfTk9STUFMKTsKCQkJYnJlYWs7CgoJCWNhc2UgREI5X1NBVFVSTl9QQUQ6CgkJY2FzZSBEQjlfU0FUVVJOX0RQUDoKCQljYXNlIERCOV9TQVRVUk5fRFBQXzI6CgoJCQlkYjlfc2F0dXJuKGRiOS0+bW9kZSwgcG9ydCwgZGI5LT5kZXYpOwoJCQlicmVhazsKCgkJY2FzZSBEQjlfQ0QzMl9QQUQ6CgoJCQlkYXRhID0gcGFycG9ydF9yZWFkX2RhdGEocG9ydCk7CgoJCQlpbnB1dF9yZXBvcnRfYWJzKGRldiwgQUJTX1gsIChkYXRhICYgREI5X1JJR0hUID8gMCA6IDEpIC0gKGRhdGEgJiBEQjlfTEVGVCA/IDAgOiAxKSk7CgkJCWlucHV0X3JlcG9ydF9hYnMoZGV2LCBBQlNfWSwgKGRhdGEgJiBEQjlfRE9XTiAgPyAwIDogMSkgLSAoZGF0YSAmIERCOV9VUCAgID8gMCA6IDEpKTsKCgkJCXBhcnBvcnRfd3JpdGVfY29udHJvbChwb3J0LCAweDBhKTsKCgkJCWZvciAoaSA9IDA7IGkgPCA3OyBpKyspIHsKCQkJCWRhdGEgPSBwYXJwb3J0X3JlYWRfZGF0YShwb3J0KTsKCQkJCXBhcnBvcnRfd3JpdGVfY29udHJvbChwb3J0LCAweDAyKTsKCQkJCXBhcnBvcnRfd3JpdGVfY29udHJvbChwb3J0LCAweDBhKTsKCQkJCWlucHV0X3JlcG9ydF9rZXkoZGV2LCBkYjlfY2QzMl9idG5baV0sIH5kYXRhICYgREI5X0ZJUkUyKTsKCQkJfQoKCQkJcGFycG9ydF93cml0ZV9jb250cm9sKHBvcnQsIDB4MDApOwoJCQlicmVhazsKCQl9CgoJaW5wdXRfc3luYyhkZXYpOwoKCW1vZF90aW1lcigmZGI5LT50aW1lciwgamlmZmllcyArIERCOV9SRUZSRVNIX1RJTUUpOwp9CgpzdGF0aWMgaW50IGRiOV9vcGVuKHN0cnVjdCBpbnB1dF9kZXYgKmRldikKewoJc3RydWN0IGRiOSAqZGI5ID0gZGV2LT5wcml2YXRlOwoJc3RydWN0IHBhcnBvcnQgKnBvcnQgPSBkYjktPnBkLT5wb3J0OwoJaW50IGVycjsKCgllcnIgPSBtdXRleF9sb2NrX2ludGVycnVwdGlibGUoJmRiOS0+bXV0ZXgpOwoJaWYgKGVycikKCQlyZXR1cm4gZXJyOwoKCWlmICghZGI5LT51c2VkKyspIHsKCQlwYXJwb3J0X2NsYWltKGRiOS0+cGQpOwoJCXBhcnBvcnRfd3JpdGVfZGF0YShwb3J0LCAweGZmKTsKCQlpZiAoZGI5X21vZGVzW2RiOS0+bW9kZV0ucmV2ZXJzZSkgewoJCQlwYXJwb3J0X2RhdGFfcmV2ZXJzZShwb3J0KTsKCQkJcGFycG9ydF93cml0ZV9jb250cm9sKHBvcnQsIERCOV9OT1JNQUwpOwoJCX0KCQltb2RfdGltZXIoJmRiOS0+dGltZXIsIGppZmZpZXMgKyBEQjlfUkVGUkVTSF9USU1FKTsKCX0KCgltdXRleF91bmxvY2soJmRiOS0+bXV0ZXgpOwoJcmV0dXJuIDA7Cn0KCnN0YXRpYyB2b2lkIGRiOV9jbG9zZShzdHJ1Y3QgaW5wdXRfZGV2ICpkZXYpCnsKCXN0cnVjdCBkYjkgKmRiOSA9IGRldi0+cHJpdmF0ZTsKCXN0cnVjdCBwYXJwb3J0ICpwb3J0ID0gZGI5LT5wZC0+cG9ydDsKCgltdXRleF9sb2NrKCZkYjktPm11dGV4KTsKCWlmICghLS1kYjktPnVzZWQpIHsKCQlkZWxfdGltZXJfc3luYygmZGI5LT50aW1lcik7CgkJcGFycG9ydF93cml0ZV9jb250cm9sKHBvcnQsIDB4MDApOwoJCXBhcnBvcnRfZGF0YV9mb3J3YXJkKHBvcnQpOwoJCXBhcnBvcnRfcmVsZWFzZShkYjktPnBkKTsKCX0KCW11dGV4X3VubG9jaygmZGI5LT5tdXRleCk7Cn0KCnN0YXRpYyBzdHJ1Y3QgZGI5IF9faW5pdCAqZGI5X3Byb2JlKGludCBwYXJwb3J0LCBpbnQgbW9kZSkKewoJc3RydWN0IGRiOSAqZGI5OwoJY29uc3Qgc3RydWN0IGRiOV9tb2RlX2RhdGEgKmRiOV9tb2RlOwoJc3RydWN0IHBhcnBvcnQgKnBwOwoJc3RydWN0IHBhcmRldmljZSAqcGQ7CglzdHJ1Y3QgaW5wdXRfZGV2ICppbnB1dF9kZXY7CglpbnQgaSwgajsKCWludCBlcnI7CgoJaWYgKG1vZGUgPCAxIHx8IG1vZGUgPj0gREI5X01BWF9QQUQgfHwgIWRiOV9tb2Rlc1ttb2RlXS5uX2J1dHRvbnMpIHsKCQlwcmludGsoS0VSTl9FUlIgImRiOS5jOiBCYWQgZGV2aWNlIHR5cGUgJWRcbiIsIG1vZGUpOwoJCWVyciA9IC1FSU5WQUw7CgkJZ290byBlcnJfb3V0OwoJfQoKCWRiOV9tb2RlID0gJmRiOV9tb2Rlc1ttb2RlXTsKCglwcCA9IHBhcnBvcnRfZmluZF9udW1iZXIocGFycG9ydCk7CglpZiAoIXBwKSB7CgkJcHJpbnRrKEtFUk5fRVJSICJkYjkuYzogbm8gc3VjaCBwYXJwb3J0XG4iKTsKCQllcnIgPSAtRU5PREVWOwoJCWdvdG8gZXJyX291dDsKCX0KCglpZiAoZGI5X21vZGVbbW9kZV0uYmlkaXJlY3Rpb25hbCAmJiAhKHBwLT5tb2RlcyAmIFBBUlBPUlRfTU9ERV9UUklTVEFURSkpIHsKCQlwcmludGsoS0VSTl9FUlIgImRiOS5jOiBzcGVjaWZpZWQgcGFycG9ydCBpcyBub3QgYmlkaXJlY3Rpb25hbFxuIik7CgkJZXJyID0gLUVJTlZBTDsKCQlnb3RvIGVycl9wdXRfcHA7Cgl9CgoJcGQgPSBwYXJwb3J0X3JlZ2lzdGVyX2RldmljZShwcCwgImRiOSIsIE5VTEwsIE5VTEwsIE5VTEwsIFBBUlBPUlRfREVWX0VYQ0wsIE5VTEwpOwoJaWYgKCFwZCkgewoJCXByaW50ayhLRVJOX0VSUiAiZGI5LmM6IHBhcnBvcnQgYnVzeSBhbHJlYWR5IC0gbHAubyBsb2FkZWQ/XG4iKTsKCQllcnIgPSAtRUJVU1k7CgkJZ290byBlcnJfcHV0X3BwOwoJfQoKCWRiOSA9IGt6YWxsb2Moc2l6ZW9mKHN0cnVjdCBkYjkpLCBHRlBfS0VSTkVMKTsKCWlmICghZGI5KSB7CgkJcHJpbnRrKEtFUk5fRVJSICJkYjkuYzogTm90IGVub3VnaCBtZW1vcnlcbiIpOwoJCWVyciA9IC1FTk9NRU07CgkJZ290byBlcnJfdW5yZWdfcGFyZGV2OwoJfQoKCW11dGV4X2luaXQoJmRiOS0+bXV0ZXgpOwoJZGI5LT5wZCA9IHBkOwoJZGI5LT5tb2RlID0gbW9kZTsKCWluaXRfdGltZXIoJmRiOS0+dGltZXIpOwoJZGI5LT50aW1lci5kYXRhID0gKGxvbmcpIGRiOTsKCWRiOS0+dGltZXIuZnVuY3Rpb24gPSBkYjlfdGltZXI7CgoJZm9yIChpID0gMDsgaSA8IChtaW4oZGI5X21vZGUtPm5fcGFkcywgREI5X01BWF9ERVZJQ0VTKSk7IGkrKykgewoKCQlkYjktPmRldltpXSA9IGlucHV0X2RldiA9IGlucHV0X2FsbG9jYXRlX2RldmljZSgpOwoJCWlmICghaW5wdXRfZGV2KSB7CgkJCXByaW50ayhLRVJOX0VSUiAiZGI5LmM6IE5vdCBlbm91Z2ggbWVtb3J5IGZvciBpbnB1dCBkZXZpY2VcbiIpOwoJCQllcnIgPSAtRU5PTUVNOwoJCQlnb3RvIGVycl91bnJlZ19kZXZzOwoJCX0KCgkJc3ByaW50ZihkYjktPnBoeXNbaV0sICIlcy9pbnB1dCVkIiwgZGI5LT5wZC0+cG9ydC0+bmFtZSwgaSk7CgoJCWlucHV0X2Rldi0+bmFtZSA9IGRiOV9tb2RlLT5uYW1lOwoJCWlucHV0X2Rldi0+cGh5cyA9IGRiOS0+cGh5c1tpXTsKCQlpbnB1dF9kZXYtPmlkLmJ1c3R5cGUgPSBCVVNfUEFSUE9SVDsKCQlpbnB1dF9kZXYtPmlkLnZlbmRvciA9IDB4MDAwMjsKCQlpbnB1dF9kZXYtPmlkLnByb2R1Y3QgPSBtb2RlOwoJCWlucHV0X2Rldi0+aWQudmVyc2lvbiA9IDB4MDEwMDsKCQlpbnB1dF9kZXYtPnByaXZhdGUgPSBkYjk7CgoJCWlucHV0X2Rldi0+b3BlbiA9IGRiOV9vcGVuOwoJCWlucHV0X2Rldi0+Y2xvc2UgPSBkYjlfY2xvc2U7CgoJCWlucHV0X2Rldi0+ZXZiaXRbMF0gPSBCSVQoRVZfS0VZKSB8IEJJVChFVl9BQlMpOwoJCWZvciAoaiA9IDA7IGogPCBkYjlfbW9kZS0+bl9idXR0b25zOyBqKyspCgkJCXNldF9iaXQoZGI5X21vZGUtPmJ1dHRvbnNbal0sIGlucHV0X2Rldi0+a2V5Yml0KTsKCQlmb3IgKGogPSAwOyBqIDwgZGI5X21vZGUtPm5fYXhpczsgaisrKSB7CgkJCWlmIChqIDwgMikKCQkJCWlucHV0X3NldF9hYnNfcGFyYW1zKGlucHV0X2RldiwgZGI5X2Fic1tqXSwgLTEsIDEsIDAsIDApOwoJCQllbHNlCgkJCQlpbnB1dF9zZXRfYWJzX3BhcmFtcyhpbnB1dF9kZXYsIGRiOV9hYnNbal0sIDEsIDI1NSwgMCwgMCk7CgkJfQoKCQllcnIgPSBpbnB1dF9yZWdpc3Rlcl9kZXZpY2UoaW5wdXRfZGV2KTsKCQlpZiAoZXJyKQoJCQlnb3RvIGVycl9mcmVlX2RldjsKCX0KCglwYXJwb3J0X3B1dF9wb3J0KHBwKTsKCXJldHVybiBkYjk7CgogZXJyX2ZyZWVfZGV2OgoJaW5wdXRfZnJlZV9kZXZpY2UoZGI5LT5kZXZbaV0pOwogZXJyX3VucmVnX2RldnM6Cgl3aGlsZSAoLS1pID49IDApCgkJaW5wdXRfdW5yZWdpc3Rlcl9kZXZpY2UoZGI5LT5kZXZbaV0pOwoJa2ZyZWUoZGI5KTsKIGVycl91bnJlZ19wYXJkZXY6CglwYXJwb3J0X3VucmVnaXN0ZXJfZGV2aWNlKHBkKTsKIGVycl9wdXRfcHA6CglwYXJwb3J0X3B1dF9wb3J0KHBwKTsKIGVycl9vdXQ6CglyZXR1cm4gRVJSX1BUUihlcnIpOwp9CgpzdGF0aWMgdm9pZCBkYjlfcmVtb3ZlKHN0cnVjdCBkYjkgKmRiOSkKewoJaW50IGk7CgoJZm9yIChpID0gMDsgaSA8IG1pbihkYjlfbW9kZXNbZGI5LT5tb2RlXS5uX3BhZHMsIERCOV9NQVhfREVWSUNFUyk7IGkrKykKCQlpbnB1dF91bnJlZ2lzdGVyX2RldmljZShkYjktPmRldltpXSk7CglwYXJwb3J0X3VucmVnaXN0ZXJfZGV2aWNlKGRiOS0+cGQpOwoJa2ZyZWUoZGI5KTsKfQoKc3RhdGljIGludCBfX2luaXQgZGI5X2luaXQodm9pZCkKewoJaW50IGk7CglpbnQgaGF2ZV9kZXYgPSAwOwoJaW50IGVyciA9IDA7CgoJZm9yIChpID0gMDsgaSA8IERCOV9NQVhfUE9SVFM7IGkrKykgewoJCWlmIChkYjlbaV0ubmFyZ3MgPT0gMCB8fCBkYjlbaV0uYXJnc1tEQjlfQVJHX1BBUlBPUlRdIDwgMCkKCQkJY29udGludWU7CgoJCWlmIChkYjlbaV0ubmFyZ3MgPCAyKSB7CgkJCXByaW50ayhLRVJOX0VSUiAiZGI5LmM6IERldmljZSB0eXBlIG11c3QgYmUgc3BlY2lmaWVkLlxuIik7CgkJCWVyciA9IC1FSU5WQUw7CgkJCWJyZWFrOwoJCX0KCgkJZGI5X2Jhc2VbaV0gPSBkYjlfcHJvYmUoZGI5W2ldLmFyZ3NbREI5X0FSR19QQVJQT1JUXSwKCQkJCQlkYjlbaV0uYXJnc1tEQjlfQVJHX01PREVdKTsKCQlpZiAoSVNfRVJSKGRiOV9iYXNlW2ldKSkgewoJCQllcnIgPSBQVFJfRVJSKGRiOV9iYXNlW2ldKTsKCQkJYnJlYWs7CgkJfQoKCQloYXZlX2RldiA9IDE7Cgl9CgoJaWYgKGVycikgewoJCXdoaWxlICgtLWkgPj0gMCkKCQkJaWYgKGRiOV9iYXNlW2ldKQoJCQkJZGI5X3JlbW92ZShkYjlfYmFzZVtpXSk7CgkJcmV0dXJuIGVycjsKCX0KCglyZXR1cm4gaGF2ZV9kZXYgPyAwIDogLUVOT0RFVjsKfQoKc3RhdGljIHZvaWQgX19leGl0IGRiOV9leGl0KHZvaWQpCnsKCWludCBpOwoKCWZvciAoaSA9IDA7IGkgPCBEQjlfTUFYX1BPUlRTOyBpKyspCgkJaWYgKGRiOV9iYXNlW2ldKQoJCQlkYjlfcmVtb3ZlKGRiOV9iYXNlW2ldKTsKfQoKbW9kdWxlX2luaXQoZGI5X2luaXQpOwptb2R1bGVfZXhpdChkYjlfZXhpdCk7Cg==