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+cG9ydDsKCgltdXRleF9sb2NrKCZkYjktPm11dGV4KTsKCWlmICghLS1kYjktPnVzZWQpIHsKCQlkZWxfdGltZXJfc3luYygmZGI5LT50aW1lcik7CgkJcGFycG9ydF93cml0ZV9jb250cm9sKHBvcnQsIDB4MDApOwoJCXBhcnBvcnRfZGF0YV9mb3J3YXJkKHBvcnQpOwoJCXBhcnBvcnRfcmVsZWFzZShkYjktPnBkKTsKCX0KCW11dGV4X3VubG9jaygmZGI5LT5tdXRleCk7Cn0KCnN0YXRpYyBzdHJ1Y3QgZGI5IF9faW5pdCAqZGI5X3Byb2JlKGludCBwYXJwb3J0LCBpbnQgbW9kZSkKewoJc3RydWN0IGRiOSAqZGI5OwoJY29uc3Qgc3RydWN0IGRiOV9tb2RlX2RhdGEgKmRiOV9tb2RlOwoJc3RydWN0IHBhcnBvcnQgKnBwOwoJc3RydWN0IHBhcmRldmljZSAqcGQ7CglzdHJ1Y3QgaW5wdXRfZGV2ICppbnB1dF9kZXY7CglpbnQgaSwgajsKCWludCBlcnI7CgoJaWYgKG1vZGUgPCAxIHx8IG1vZGUgPj0gREI5X01BWF9QQUQgfHwgIWRiOV9tb2Rlc1ttb2RlXS5uX2J1dHRvbnMpIHsKCQlwcmludGsoS0VSTl9FUlIgImRiOS5jOiBCYWQgZGV2aWNlIHR5cGUgJWRcbiIsIG1vZGUpOwoJCWVyciA9IC1FSU5WQUw7CgkJZ290byBlcnJfb3V0OwoJfQoKCWRiOV9tb2RlID0gJmRiOV9tb2Rlc1ttb2RlXTsKCglwcCA9IHBhcnBvcnRfZmluZF9udW1iZXIocGFycG9ydCk7CglpZiAoIXBwKSB7CgkJcHJpbnRrKEtFUk5fRVJSICJkYjkuYzogbm8gc3VjaCBwYXJwb3J0XG4iKTsKCQllcnIgPSAtRU5PREVWOwoJCWdvdG8gZXJyX291dDsKCX0KCglpZiAoZGI5X21vZGUtPmJpZGlyZWN0aW9uYWwgJiYgIShwcC0+bW9kZXMgJiBQQVJQT1JUX01PREVfVFJJU1RBVEUpKSB7CgkJcHJpbnRrKEtFUk5fRVJSICJkYjkuYzogc3BlY2lmaWVkIHBhcnBvcnQgaXMgbm90IGJpZGlyZWN0aW9uYWxcbiIpOwoJCWVyciA9IC1FSU5WQUw7CgkJZ290byBlcnJfcHV0X3BwOwoJfQoKCXBkID0gcGFycG9ydF9yZWdpc3Rlcl9kZXZpY2UocHAsICJkYjkiLCBOVUxMLCBOVUxMLCBOVUxMLCBQQVJQT1JUX0RFVl9FWENMLCBOVUxMKTsKCWlmICghcGQpIHsKCQlwcmludGsoS0VSTl9FUlIgImRiOS5jOiBwYXJwb3J0IGJ1c3kgYWxyZWFkeSAtIGxwLm8gbG9hZGVkP1xuIik7CgkJZXJyID0gLUVCVVNZOwoJCWdvdG8gZXJyX3B1dF9wcDsKCX0KCglkYjkgPSBremFsbG9jKHNpemVvZihzdHJ1Y3QgZGI5KSwgR0ZQX0tFUk5FTCk7CglpZiAoIWRiOSkgewoJCXByaW50ayhLRVJOX0VSUiAiZGI5LmM6IE5vdCBlbm91Z2ggbWVtb3J5XG4iKTsKCQllcnIgPSAtRU5PTUVNOwoJCWdvdG8gZXJyX3VucmVnX3BhcmRldjsKCX0KCgltdXRleF9pbml0KCZkYjktPm11dGV4KTsKCWRiOS0+cGQgPSBwZDsKCWRiOS0+bW9kZSA9IG1vZGU7Cglpbml0X3RpbWVyKCZkYjktPnRpbWVyKTsKCWRiOS0+dGltZXIuZGF0YSA9IChsb25nKSBkYjk7CglkYjktPnRpbWVyLmZ1bmN0aW9uID0gZGI5X3RpbWVyOwoKCWZvciAoaSA9IDA7IGkgPCAobWluKGRiOV9tb2RlLT5uX3BhZHMsIERCOV9NQVhfREVWSUNFUykpOyBpKyspIHsKCgkJZGI5LT5kZXZbaV0gPSBpbnB1dF9kZXYgPSBpbnB1dF9hbGxvY2F0ZV9kZXZpY2UoKTsKCQlpZiAoIWlucHV0X2RldikgewoJCQlwcmludGsoS0VSTl9FUlIgImRiOS5jOiBOb3QgZW5vdWdoIG1lbW9yeSBmb3IgaW5wdXQgZGV2aWNlXG4iKTsKCQkJZXJyID0gLUVOT01FTTsKCQkJZ290byBlcnJfdW5yZWdfZGV2czsKCQl9CgoJCXNucHJpbnRmKGRiOS0+cGh5c1tpXSwgc2l6ZW9mKGRiOS0+cGh5c1tpXSksCgkJCSAiJXMvaW5wdXQlZCIsIGRiOS0+cGQtPnBvcnQtPm5hbWUsIGkpOwoKCQlpbnB1dF9kZXYtPm5hbWUgPSBkYjlfbW9kZS0+bmFtZTsKCQlpbnB1dF9kZXYtPnBoeXMgPSBkYjktPnBoeXNbaV07CgkJaW5wdXRfZGV2LT5pZC5idXN0eXBlID0gQlVTX1BBUlBPUlQ7CgkJaW5wdXRfZGV2LT5pZC52ZW5kb3IgPSAweDAwMDI7CgkJaW5wdXRfZGV2LT5pZC5wcm9kdWN0ID0gbW9kZTsKCQlpbnB1dF9kZXYtPmlkLnZlcnNpb24gPSAweDAxMDA7CgkJaW5wdXRfZGV2LT5wcml2YXRlID0gZGI5OwoKCQlpbnB1dF9kZXYtPm9wZW4gPSBkYjlfb3BlbjsKCQlpbnB1dF9kZXYtPmNsb3NlID0gZGI5X2Nsb3NlOwoKCQlpbnB1dF9kZXYtPmV2Yml0WzBdID0gQklUKEVWX0tFWSkgfCBCSVQoRVZfQUJTKTsKCQlmb3IgKGogPSAwOyBqIDwgZGI5X21vZGUtPm5fYnV0dG9uczsgaisrKQoJCQlzZXRfYml0KGRiOV9tb2RlLT5idXR0b25zW2pdLCBpbnB1dF9kZXYtPmtleWJpdCk7CgkJZm9yIChqID0gMDsgaiA8IGRiOV9tb2RlLT5uX2F4aXM7IGorKykgewoJCQlpZiAoaiA8IDIpCgkJCQlpbnB1dF9zZXRfYWJzX3BhcmFtcyhpbnB1dF9kZXYsIGRiOV9hYnNbal0sIC0xLCAxLCAwLCAwKTsKCQkJZWxzZQoJCQkJaW5wdXRfc2V0X2Fic19wYXJhbXMoaW5wdXRfZGV2LCBkYjlfYWJzW2pdLCAxLCAyNTUsIDAsIDApOwoJCX0KCgkJZXJyID0gaW5wdXRfcmVnaXN0ZXJfZGV2aWNlKGlucHV0X2Rldik7CgkJaWYgKGVycikKCQkJZ290byBlcnJfZnJlZV9kZXY7Cgl9CgoJcGFycG9ydF9wdXRfcG9ydChwcCk7CglyZXR1cm4gZGI5OwoKIGVycl9mcmVlX2RldjoKCWlucHV0X2ZyZWVfZGV2aWNlKGRiOS0+ZGV2W2ldKTsKIGVycl91bnJlZ19kZXZzOgoJd2hpbGUgKC0taSA+PSAwKQoJCWlucHV0X3VucmVnaXN0ZXJfZGV2aWNlKGRiOS0+ZGV2W2ldKTsKCWtmcmVlKGRiOSk7CiBlcnJfdW5yZWdfcGFyZGV2OgoJcGFycG9ydF91bnJlZ2lzdGVyX2RldmljZShwZCk7CiBlcnJfcHV0X3BwOgoJcGFycG9ydF9wdXRfcG9ydChwcCk7CiBlcnJfb3V0OgoJcmV0dXJuIEVSUl9QVFIoZXJyKTsKfQoKc3RhdGljIHZvaWQgZGI5X3JlbW92ZShzdHJ1Y3QgZGI5ICpkYjkpCnsKCWludCBpOwoKCWZvciAoaSA9IDA7IGkgPCBtaW4oZGI5X21vZGVzW2RiOS0+bW9kZV0ubl9wYWRzLCBEQjlfTUFYX0RFVklDRVMpOyBpKyspCgkJaW5wdXRfdW5yZWdpc3Rlcl9kZXZpY2UoZGI5LT5kZXZbaV0pOwoJcGFycG9ydF91bnJlZ2lzdGVyX2RldmljZShkYjktPnBkKTsKCWtmcmVlKGRiOSk7Cn0KCnN0YXRpYyBpbnQgX19pbml0IGRiOV9pbml0KHZvaWQpCnsKCWludCBpOwoJaW50IGhhdmVfZGV2ID0gMDsKCWludCBlcnIgPSAwOwoKCWZvciAoaSA9IDA7IGkgPCBEQjlfTUFYX1BPUlRTOyBpKyspIHsKCQlpZiAoZGI5W2ldLm5hcmdzID09IDAgfHwgZGI5W2ldLmFyZ3NbREI5X0FSR19QQVJQT1JUXSA8IDApCgkJCWNvbnRpbnVlOwoKCQlpZiAoZGI5W2ldLm5hcmdzIDwgMikgewoJCQlwcmludGsoS0VSTl9FUlIgImRiOS5jOiBEZXZpY2UgdHlwZSBtdXN0IGJlIHNwZWNpZmllZC5cbiIpOwoJCQllcnIgPSAtRUlOVkFMOwoJCQlicmVhazsKCQl9CgoJCWRiOV9iYXNlW2ldID0gZGI5X3Byb2JlKGRiOVtpXS5hcmdzW0RCOV9BUkdfUEFSUE9SVF0sCgkJCQkJZGI5W2ldLmFyZ3NbREI5X0FSR19NT0RFXSk7CgkJaWYgKElTX0VSUihkYjlfYmFzZVtpXSkpIHsKCQkJZXJyID0gUFRSX0VSUihkYjlfYmFzZVtpXSk7CgkJCWJyZWFrOwoJCX0KCgkJaGF2ZV9kZXYgPSAxOwoJfQoKCWlmIChlcnIpIHsKCQl3aGlsZSAoLS1pID49IDApCgkJCWlmIChkYjlfYmFzZVtpXSkKCQkJCWRiOV9yZW1vdmUoZGI5X2Jhc2VbaV0pOwoJCXJldHVybiBlcnI7Cgl9CgoJcmV0dXJuIGhhdmVfZGV2ID8gMCA6IC1FTk9ERVY7Cn0KCnN0YXRpYyB2b2lkIF9fZXhpdCBkYjlfZXhpdCh2b2lkKQp7CglpbnQgaTsKCglmb3IgKGkgPSAwOyBpIDwgREI5X01BWF9QT1JUUzsgaSsrKQoJCWlmIChkYjlfYmFzZVtpXSkKCQkJZGI5X3JlbW92ZShkYjlfYmFzZVtpXSk7Cn0KCm1vZHVsZV9pbml0KGRiOV9pbml0KTsKbW9kdWxlX2V4aXQoZGI5X2V4aXQpOwo=