LyoKICogJElkOiBkYjkuYyx2IDEuMTMgMjAwMi8wNC8wNyAyMDoxMzozNyB2b2p0ZWNoIEV4cCAkCiAqCiAqICBDb3B5cmlnaHQgKGMpIDE5OTktMjAwMSBWb2p0ZWNoIFBhdmxpawogKgogKiAgQmFzZWQgb24gdGhlIHdvcmsgb2Y6CiAqCUFuZHJlZSBCb3JybWFubgkJTWF0cyBTavZ2YWxsCiAqLwoKLyoKICogQXRhcmksIEFtc3RyYWQsIENvbW1vZG9yZSwgQW1pZ2EsIFNlZ2EsIGV0Yy4gam95c3RpY2sgZHJpdmVyIGZvciBMaW51eAogKi8KCi8qCiAqIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5CiAqIGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5CiAqIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlciB2ZXJzaW9uIDIgb2YgdGhlIExpY2Vuc2UsIG9yCiAqIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlCiAqIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIGFsb25nIHdpdGggdGhpcyBwcm9ncmFtOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDU5IFRlbXBsZSBQbGFjZSwgU3VpdGUgMzMwLCBCb3N0b24sIE1BIDAyMTExLTEzMDcgVVNBCiAqCiAqIFNob3VsZCB5b3UgbmVlZCB0byBjb250YWN0IG1lLCB0aGUgYXV0aG9yLCB5b3UgY2FuIGRvIHNvIGVpdGhlciBieQogKiBlLW1haWwgLSBtYWlsIHlvdXIgbWVzc2FnZSB0byA8dm9qdGVjaEB1Y3cuY3o+LCBvciBieSBwYXBlciBtYWlsOgogKiBWb2p0ZWNoIFBhdmxpaywgU2ltdW5rb3ZhIDE1OTQsIFByYWd1ZSA4LCAxODIgMDAgQ3plY2ggUmVwdWJsaWMKICovCgojaW5jbHVkZSA8bGludXgva2VybmVsLmg+CiNpbmNsdWRlIDxsaW51eC9tb2R1bGUuaD4KI2luY2x1ZGUgPGxpbnV4L21vZHVsZXBhcmFtLmg+CiNpbmNsdWRlIDxsaW51eC9kZWxheS5oPgojaW5jbHVkZSA8bGludXgvaW5pdC5oPgojaW5jbHVkZSA8bGludXgvcGFycG9ydC5oPgojaW5jbHVkZSA8bGludXgvaW5wdXQuaD4KI2luY2x1ZGUgPGxpbnV4L211dGV4Lmg+CgpNT0RVTEVfQVVUSE9SKCJWb2p0ZWNoIFBhdmxpayA8dm9qdGVjaEB1Y3cuY3o+Iik7Ck1PRFVMRV9ERVNDUklQVElPTigiQXRhcmksIEFtc3RyYWQsIENvbW1vZG9yZSwgQW1pZ2EsIFNlZ2EsIGV0Yy4gam95c3RpY2sgZHJpdmVyIik7Ck1PRFVMRV9MSUNFTlNFKCJHUEwiKTsKCnN0cnVjdCBkYjlfY29uZmlnIHsKCWludCBhcmdzWzJdOwoJaW50IG5hcmdzOwp9OwoKI2RlZmluZSBEQjlfTUFYX1BPUlRTCQkzCnN0YXRpYyBzdHJ1Y3QgZGI5X2NvbmZpZyBkYjlbREI5X01BWF9QT1JUU10gX19pbml0ZGF0YTsKCm1vZHVsZV9wYXJhbV9hcnJheV9uYW1lZChkZXYsIGRiOVswXS5hcmdzLCBpbnQsICZkYjlbMF0ubmFyZ3MsIDApOwpNT0RVTEVfUEFSTV9ERVNDKGRldiwgIkRlc2NyaWJlcyBmaXJzdCBhdHRhY2hlZCBkZXZpY2UgKDxwYXJwb3J0Iz4sPHR5cGU+KSIpOwptb2R1bGVfcGFyYW1fYXJyYXlfbmFtZWQoZGV2MiwgZGI5WzFdLmFyZ3MsIGludCwgJmRiOVswXS5uYXJncywgMCk7Ck1PRFVMRV9QQVJNX0RFU0MoZGV2MiwgIkRlc2NyaWJlcyBzZWNvbmQgYXR0YWNoZWQgZGV2aWNlICg8cGFycG9ydCM+LDx0eXBlPikiKTsKbW9kdWxlX3BhcmFtX2FycmF5X25hbWVkKGRldjMsIGRiOVsyXS5hcmdzLCBpbnQsICZkYjlbMl0ubmFyZ3MsIDApOwpNT0RVTEVfUEFSTV9ERVNDKGRldjMsICJEZXNjcmliZXMgdGhpcmQgYXR0YWNoZWQgZGV2aWNlICg8cGFycG9ydCM+LDx0eXBlPikiKTsKCiNkZWZpbmUgREI5X0FSR19QQVJQT1JUCQkwCiNkZWZpbmUgREI5X0FSR19NT0RFCQkxCgojZGVmaW5lIERCOV9NVUxUSV9TVElDSwkJMHgwMQojZGVmaW5lIERCOV9NVUxUSTJfU1RJQ0sJMHgwMgojZGVmaW5lIERCOV9HRU5FU0lTX1BBRAkJMHgwMwojZGVmaW5lIERCOV9HRU5FU0lTNV9QQUQJMHgwNQojZGVmaW5lIERCOV9HRU5FU0lTNl9QQUQJMHgwNgojZGVmaW5lIERCOV9TQVRVUk5fUEFECQkweDA3CiNkZWZpbmUgREI5X01VTFRJXzA4MDIJCTB4MDgKI2RlZmluZSBEQjlfTVVMVElfMDgwMl8yCTB4MDkKI2RlZmluZSBEQjlfQ0QzMl9QQUQJCTB4MEEKI2RlZmluZSBEQjlfU0FUVVJOX0RQUAkJMHgwQgojZGVmaW5lIERCOV9TQVRVUk5fRFBQXzIJMHgwQwojZGVmaW5lIERCOV9NQVhfUEFECQkweDBECgojZGVmaW5lIERCOV9VUAkJCTB4MDEKI2RlZmluZSBEQjlfRE9XTgkJMHgwMgojZGVmaW5lIERCOV9MRUZUCQkweDA0CiNkZWZpbmUgREI5X1JJR0hUCQkweDA4CiNkZWZpbmUgREI5X0ZJUkUxCQkweDEwCiNkZWZpbmUgREI5X0ZJUkUyCQkweDIwCiNkZWZpbmUgREI5X0ZJUkUzCQkweDQwCiNkZWZpbmUgREI5X0ZJUkU0CQkweDgwCgojZGVmaW5lIERCOV9OT1JNQUwJCTB4MGEKI2RlZmluZSBEQjlfTk9TRUxFQ1QJCTB4MDgKCiNkZWZpbmUgREI5X0dFTkVTSVM2X0RFTEFZCTE0CiNkZWZpbmUgREI5X1JFRlJFU0hfVElNRQlIWi8xMDAKCiNkZWZpbmUgREI5X01BWF9ERVZJQ0VTCQkyCgpzdHJ1Y3QgZGI5X21vZGVfZGF0YSB7Cgljb25zdCBjaGFyICpuYW1lOwoJY29uc3Qgc2hvcnQgKmJ1dHRvbnM7CglpbnQgbl9idXR0b25zOwoJaW50IG5fcGFkczsKCWludCBuX2F4aXM7CglpbnQgYmlkaXJlY3Rpb25hbDsKCWludCByZXZlcnNlOwp9OwoKc3RydWN0IGRiOSB7CglzdHJ1Y3QgaW5wdXRfZGV2ICpkZXZbREI5X01BWF9ERVZJQ0VTXTsKCXN0cnVjdCB0aW1lcl9saXN0IHRpbWVyOwoJc3RydWN0IHBhcmRldmljZSAqcGQ7CglpbnQgbW9kZTsKCWludCB1c2VkOwoJc3RydWN0IG11dGV4IG11dGV4OwoJY2hhciBwaHlzW0RCOV9NQVhfREVWSUNFU11bMzJdOwp9OwoKc3RhdGljIHN0cnVjdCBkYjkgKmRiOV9iYXNlWzNdOwoKc3RhdGljIGNvbnN0IHNob3J0IGRiOV9tdWx0aV9idG5bXSA9IHsgQlROX1RSSUdHRVIsIEJUTl9USFVNQiB9OwpzdGF0aWMgY29uc3Qgc2hvcnQgZGI5X2dlbmVzaXNfYnRuW10gPSB7IEJUTl9TVEFSVCwgQlROX0EsIEJUTl9CLCBCVE5fQywgQlROX1gsIEJUTl9ZLCBCVE5fWiwgQlROX01PREUgfTsKc3RhdGljIGNvbnN0IHNob3J0IGRiOV9jZDMyX2J0bltdID0geyBCVE5fQSwgQlROX0IsIEJUTl9DLCBCVE5fWCwgQlROX1ksIEJUTl9aLCBCVE5fVEwsIEJUTl9UUiwgQlROX1NUQVJUIH07CnN0YXRpYyBjb25zdCBzaG9ydCBkYjlfYWJzW10gPSB7IEFCU19YLCBBQlNfWSwgQUJTX1JYLCBBQlNfUlksIEFCU19SWiwgQUJTX1osIEFCU19IQVQwWCwgQUJTX0hBVDBZLCBBQlNfSEFUMVgsIEFCU19IQVQxWSB9OwoKc3RhdGljIGNvbnN0IHN0cnVjdCBkYjlfbW9kZV9kYXRhIGRiOV9tb2Rlc1tdID0gewoJeyBOVUxMLAkJCQkJIE5VTEwsCQkgIDAsICAwLCAgMCwgIDAsICAwIH0sCgl7ICJNdWx0aXN5c3RlbSBqb3lzdGljayIsCQkgZGI5X211bHRpX2J0biwJICAxLCAgMSwgIDIsICAxLCAgMSB9LAoJeyAiTXVsdGlzeXN0ZW0gam95c3RpY2sgKDIgZmlyZSkiLAkgZGI5X211bHRpX2J0biwJICAyLCAgMSwgIDIsICAxLCAgMSB9LAoJeyAiR2VuZXNpcyBwYWQiLAkJCSBkYjlfZ2VuZXNpc19idG4sIDQsICAxLCAgMiwgIDEsICAxIH0sCgl7IE5VTEwsCQkJCQkgTlVMTCwJCSAgMCwgIDAsICAwLCAgMCwgIDAgfSwKCXsgIkdlbmVzaXMgNSBwYWQiLAkJCSBkYjlfZ2VuZXNpc19idG4sIDYsICAxLCAgMiwgIDEsICAxIH0sCgl7ICJHZW5lc2lzIDYgcGFkIiwJCQkgZGI5X2dlbmVzaXNfYnRuLCA4LCAgMSwgIDIsICAxLCAgMSB9LAoJeyAiU2F0dXJuIHBhZCIsCQkJCSBkYjlfY2QzMl9idG4sCSAgOSwgIDYsICA3LCAgMCwgIDEgfSwKCXsgIk11bHRpc3lzdGVtICgwLjguMC4yKSBqb3lzdGljayIsCSBkYjlfbXVsdGlfYnRuLAkgIDEsICAxLCAgMiwgIDEsICAxIH0sCgl7ICJNdWx0aXN5c3RlbSAoMC44LjAuMi1kdWFsKSBqb3lzdGljayIsIGRiOV9tdWx0aV9idG4sCSAgMSwgIDIsICAyLCAgMSwgIDEgfSwKCXsgIkFtaWdhIENELTMyIHBhZCIsCQkJIGRiOV9jZDMyX2J0biwJICA3LCAgMSwgIDIsICAxLCAgMSB9LAoJeyAiU2F0dXJuIGRwcCIsCQkJCSBkYjlfY2QzMl9idG4sCSAgOSwgIDYsICA3LCAgMCwgIDAgfSwKCXsgIlNhdHVybiBkcHAgZHVhbCIsCQkJIGRiOV9jZDMyX2J0biwJICA5LCAgMTIsIDcsICAwLCAgMCB9LAp9OwoKLyoKICogU2F0dXJuIGNvbnRyb2xsZXJzCiAqLwojZGVmaW5lIERCOV9TQVRVUk5fREVMQVkgMzAwCnN0YXRpYyBjb25zdCBpbnQgZGI5X3NhdHVybl9ieXRlW10gPSB7IDEsIDEsIDEsIDIsIDIsIDIsIDIsIDIsIDEgfTsKc3RhdGljIGNvbnN0IHVuc2lnbmVkIGNoYXIgZGI5X3NhdHVybl9tYXNrW10gPSB7IDB4MDQsIDB4MDEsIDB4MDIsIDB4NDAsIDB4MjAsIDB4MTAsIDB4MDgsIDB4ODAsIDB4MDggfTsKCi8qCiAqIGRiOV9zYXR1cm5fd3JpdGVfc3ViKCkgd3JpdGVzIDIgYml0IGRhdGEuCiAqLwpzdGF0aWMgdm9pZCBkYjlfc2F0dXJuX3dyaXRlX3N1YihzdHJ1Y3QgcGFycG9ydCAqcG9ydCwgaW50IHR5cGUsIHVuc2lnbmVkIGNoYXIgZGF0YSwgaW50IHBvd2VyZWQsIGludCBwd3Jfc3ViKQp7Cgl1bnNpZ25lZCBjaGFyIGM7CgoJc3dpdGNoICh0eXBlKSB7CgljYXNlIDE6IC8qIERQUDEgKi8KCQljID0gMHg4MCB8IDB4MzAgfCAocG93ZXJlZCA/IDB4MDggOiAwKSB8IChwd3Jfc3ViID8gMHgwNCA6IDApIHwgZGF0YTsKCQlwYXJwb3J0X3dyaXRlX2RhdGEocG9ydCwgYyk7CgkJYnJlYWs7CgljYXNlIDI6IC8qIERQUDIgKi8KCQljID0gMHg0MCB8IGRhdGEgPDwgNCB8IChwb3dlcmVkID8gMHgwOCA6IDApIHwgKHB3cl9zdWIgPyAweDA0IDogMCkgfCAweDAzOwoJCXBhcnBvcnRfd3JpdGVfZGF0YShwb3J0LCBjKTsKCQlicmVhazsKCWNhc2UgMDoJLyogREI5ICovCgkJYyA9ICgoKChkYXRhICYgMikgPyAyIDogMCkgfCAoKGRhdGEgJiAxKSA/IDQgOiAwKSkgXiAweDAyKSB8ICFwb3dlcmVkOwoJCXBhcnBvcnRfd3JpdGVfY29udHJvbChwb3J0LCBjKTsKCQlicmVhazsKCX0KfQoKLyoKICogZ2Nfc2F0dXJuX3JlYWRfc3ViKCkgcmVhZHMgNCBiaXQgZGF0YS4KICovCnN0YXRpYyB1bnNpZ25lZCBjaGFyIGRiOV9zYXR1cm5fcmVhZF9zdWIoc3RydWN0IHBhcnBvcnQgKnBvcnQsIGludCB0eXBlKQp7Cgl1bnNpZ25lZCBjaGFyIGRhdGE7CgoJaWYgKHR5cGUpIHsKCQkvKiBEUFAgKi8KCQlkYXRhID0gcGFycG9ydF9yZWFkX3N0YXR1cyhwb3J0KSBeIDB4ODA7CgkJcmV0dXJuIChkYXRhICYgMHg4MCA/IDEgOiAwKSB8IChkYXRhICYgMHg0MCA/IDIgOiAwKQoJCSAgICAgfCAoZGF0YSAmIDB4MjAgPyA0IDogMCkgfCAoZGF0YSAmIDB4MTAgPyA4IDogMCk7Cgl9IGVsc2UgewoJCS8qIERCOSAqLwoJCWRhdGEgPSBwYXJwb3J0X3JlYWRfZGF0YShwb3J0KSAmIDB4MGY7CgkJcmV0dXJuIChkYXRhICYgMHg4ID8gMSA6IDApIHwgKGRhdGEgJiAweDQgPyAyIDogMCkKCQkgICAgIHwgKGRhdGEgJiAweDIgPyA0IDogMCkgfCAoZGF0YSAmIDB4MSA/IDggOiAwKTsKCX0KfQoKLyoKICogZGI5X3NhdHVybl9yZWFkX2FuYWxvZygpIHNlbmRzIGNsb2NrIGFuZCByZWFkcyA4IGJpdCBkYXRhLgogKi8Kc3RhdGljIHVuc2lnbmVkIGNoYXIgZGI5X3NhdHVybl9yZWFkX2FuYWxvZyhzdHJ1Y3QgcGFycG9ydCAqcG9ydCwgaW50IHR5cGUsIGludCBwb3dlcmVkKQp7Cgl1bnNpZ25lZCBjaGFyIGRhdGE7CgoJZGI5X3NhdHVybl93cml0ZV9zdWIocG9ydCwgdHlwZSwgMCwgcG93ZXJlZCwgMCk7Cgl1ZGVsYXkoREI5X1NBVFVSTl9ERUxBWSk7CglkYXRhID0gZGI5X3NhdHVybl9yZWFkX3N1Yihwb3J0LCB0eXBlKSA8PCA0OwoJZGI5X3NhdHVybl93cml0ZV9zdWIocG9ydCwgdHlwZSwgMiwgcG93ZXJlZCwgMCk7Cgl1ZGVsYXkoREI5X1NBVFVSTl9ERUxBWSk7CglkYXRhIHw9IGRiOV9zYXR1cm5fcmVhZF9zdWIocG9ydCwgdHlwZSk7CglyZXR1cm4gZGF0YTsKfQoKLyoKICogZGI5X3NhdHVybl9yZWFkX3BhY2tldCgpIHJlYWRzIHdob2xlIHNhdHVybiBwYWNrZXQgYXQgY29ubmVjdG9yCiAqIGFuZCByZXR1cm5zIGRldmljZSBpZGVudGlmaWVyIGNvZGUuCiAqLwpzdGF0aWMgdW5zaWduZWQgY2hhciBkYjlfc2F0dXJuX3JlYWRfcGFja2V0KHN0cnVjdCBwYXJwb3J0ICpwb3J0LCB1bnNpZ25lZCBjaGFyICpkYXRhLCBpbnQgdHlwZSwgaW50IHBvd2VyZWQpCnsKCWludCBpLCBqOwoJdW5zaWduZWQgY2hhciB0bXA7CgoJZGI5X3NhdHVybl93cml0ZV9zdWIocG9ydCwgdHlwZSwgMywgcG93ZXJlZCwgMCk7CglkYXRhWzBdID0gZGI5X3NhdHVybl9yZWFkX3N1Yihwb3J0LCB0eXBlKTsKCXN3aXRjaCAoZGF0YVswXSAmIDB4MGYpIHsKCWNhc2UgMHhmOgoJCS8qIDExMTEgIG5vIHBhZCAqLwoJCXJldHVybiBkYXRhWzBdID0gMHhmZjsKCWNhc2UgMHg0OiBjYXNlIDB4NCB8IDB4ODoKCQkvKiA/MTAwIDogZGlnaXRhbCBjb250cm9sbGVyICovCgkJZGI5X3NhdHVybl93cml0ZV9zdWIocG9ydCwgdHlwZSwgMCwgcG93ZXJlZCwgMSk7CgkJZGF0YVsyXSA9IGRiOV9zYXR1cm5fcmVhZF9zdWIocG9ydCwgdHlwZSkgPDwgNDsKCQlkYjlfc2F0dXJuX3dyaXRlX3N1Yihwb3J0LCB0eXBlLCAyLCBwb3dlcmVkLCAxKTsKCQlkYXRhWzFdID0gZGI5X3NhdHVybl9yZWFkX3N1Yihwb3J0LCB0eXBlKSA8PCA0OwoJCWRiOV9zYXR1cm5fd3JpdGVfc3ViKHBvcnQsIHR5cGUsIDEsIHBvd2VyZWQsIDEpOwoJCWRhdGFbMV0gfD0gZGI5X3NhdHVybl9yZWFkX3N1Yihwb3J0LCB0eXBlKTsKCQlkYjlfc2F0dXJuX3dyaXRlX3N1Yihwb3J0LCB0eXBlLCAzLCBwb3dlcmVkLCAxKTsKCQkvKiBkYXRhWzJdIHw9IGRiOV9zYXR1cm5fcmVhZF9zdWIocG9ydCwgdHlwZSk7ICovCgkJZGF0YVsyXSB8PSBkYXRhWzBdOwoJCXJldHVybiBkYXRhWzBdID0gMHgwMjsKCWNhc2UgMHgxOgoJCS8qIDAwMDEgOiBhbmFsb2cgY29udHJvbGxlciBvciBtdWx0aXRhcCAqLwoJCWRiOV9zYXR1cm5fd3JpdGVfc3ViKHBvcnQsIHR5cGUsIDIsIHBvd2VyZWQsIDApOwoJCXVkZWxheShEQjlfU0FUVVJOX0RFTEFZKTsKCQlkYXRhWzBdID0gZGI5X3NhdHVybl9yZWFkX2FuYWxvZyhwb3J0LCB0eXBlLCBwb3dlcmVkKTsKCQlpZiAoZGF0YVswXSAhPSAweDQxKSB7CgkJCS8qIHJlYWQgYW5hbG9nIGNvbnRyb2xsZXIgKi8KCQkJZm9yIChpID0gMDsgaSA8IChkYXRhWzBdICYgMHgwZik7IGkrKykKCQkJCWRhdGFbaSArIDFdID0gZGI5X3NhdHVybl9yZWFkX2FuYWxvZyhwb3J0LCB0eXBlLCBwb3dlcmVkKTsKCQkJZGI5X3NhdHVybl93cml0ZV9zdWIocG9ydCwgdHlwZSwgMywgcG93ZXJlZCwgMCk7CgkJCXJldHVybiBkYXRhWzBdOwoJCX0gZWxzZSB7CgkJCS8qIHJlYWQgbXVsdGl0YXAgKi8KCQkJaWYgKGRiOV9zYXR1cm5fcmVhZF9hbmFsb2cocG9ydCwgdHlwZSwgcG93ZXJlZCkgIT0gMHg2MCkKCQkJCXJldHVybiBkYXRhWzBdID0gMHhmZjsKCQkJZm9yIChpID0gMDsgaSA8IDYwOyBpICs9IDEwKSB7CgkJCQlkYXRhW2ldID0gZGI5X3NhdHVybl9yZWFkX2FuYWxvZyhwb3J0LCB0eXBlLCBwb3dlcmVkKTsKCQkJCWlmIChkYXRhW2ldICE9IDB4ZmYpCgkJCQkJLyogcmVhZCBlYWNoIHBhZCAqLwoJCQkJCWZvciAoaiA9IDA7IGogPCAoZGF0YVtpXSAmIDB4MGYpOyBqKyspCgkJCQkJCWRhdGFbaSArIGogKyAxXSA9IGRiOV9zYXR1cm5fcmVhZF9hbmFsb2cocG9ydCwgdHlwZSwgcG93ZXJlZCk7CgkJCX0KCQkJZGI5X3NhdHVybl93cml0ZV9zdWIocG9ydCwgdHlwZSwgMywgcG93ZXJlZCwgMCk7CgkJCXJldHVybiAweDQxOwoJCX0KCWNhc2UgMHgwOgoJCS8qIDAwMDAgOiBtb3VzZSAqLwoJCWRiOV9zYXR1cm5fd3JpdGVfc3ViKHBvcnQsIHR5cGUsIDIsIHBvd2VyZWQsIDApOwoJCXVkZWxheShEQjlfU0FUVVJOX0RFTEFZKTsKCQl0bXAgPSBkYjlfc2F0dXJuX3JlYWRfYW5hbG9nKHBvcnQsIHR5cGUsIHBvd2VyZWQpOwoJCWlmICh0bXAgPT0gMHhmZikgewoJCQlmb3IgKGkgPSAwOyBpIDwgMzsgaSsrKQoJCQkJZGF0YVtpICsgMV0gPSBkYjlfc2F0dXJuX3JlYWRfYW5hbG9nKHBvcnQsIHR5cGUsIHBvd2VyZWQpOwoJCQlkYjlfc2F0dXJuX3dyaXRlX3N1Yihwb3J0LCB0eXBlLCAzLCBwb3dlcmVkLCAwKTsKCQkJcmV0dXJuIGRhdGFbMF0gPSAweGUzOwoJCX0KCWRlZmF1bHQ6CgkJcmV0dXJuIGRhdGFbMF07Cgl9Cn0KCi8qCiAqIGRiOV9zYXR1cm5fcmVwb3J0KCkgYW5hbHl6ZXMgcGFja2V0IGFuZCByZXBvcnRzLgogKi8Kc3RhdGljIGludCBkYjlfc2F0dXJuX3JlcG9ydCh1bnNpZ25lZCBjaGFyIGlkLCB1bnNpZ25lZCBjaGFyIGRhdGFbNjBdLCBzdHJ1Y3QgaW5wdXRfZGV2ICpkZXZzW10sIGludCBuLCBpbnQgbWF4X3BhZHMpCnsKCXN0cnVjdCBpbnB1dF9kZXYgKmRldjsKCWludCB0bXAsIGksIGo7CgoJdG1wID0gKGlkID09IDB4NDEpID8gNjAgOiAxMDsKCWZvciAoaiA9IDA7IGogPCB0bXAgJiYgbiA8IG1heF9wYWRzOyBqICs9IDEwLCBuKyspIHsKCQlkZXYgPSBkZXZzW25dOwoJCXN3aXRjaCAoZGF0YVtqXSkgewoJCWNhc2UgMHgxNjogLyogbXVsdGkgY29udHJvbGxlciAoYW5hbG9nIDQgYXhpcykgKi8KCQkJaW5wdXRfcmVwb3J0X2FicyhkZXYsIGRiOV9hYnNbNV0sIGRhdGFbaiArIDZdKTsKCQljYXNlIDB4MTU6IC8qIG1pc3Npb24gc3RpY2sgKGFuYWxvZyAzIGF4aXMpICovCgkJCWlucHV0X3JlcG9ydF9hYnMoZGV2LCBkYjlfYWJzWzNdLCBkYXRhW2ogKyA0XSk7CgkJCWlucHV0X3JlcG9ydF9hYnMoZGV2LCBkYjlfYWJzWzRdLCBkYXRhW2ogKyA1XSk7CgkJY2FzZSAweDEzOiAvKiByYWNpbmcgY29udHJvbGxlciAoYW5hbG9nIDEgYXhpcykgKi8KCQkJaW5wdXRfcmVwb3J0X2FicyhkZXYsIGRiOV9hYnNbMl0sIGRhdGFbaiArIDNdKTsKCQljYXNlIDB4MzQ6IC8qIHNhdHVybiBrZXlib2FyZCAodWRsciBaWEMgQVNEIFFFIEVzYykgKi8KCQljYXNlIDB4MDI6IC8qIGRpZ2l0YWwgcGFkIChkaWdpdGFsIDIgYXhpcyArIGJ1dHRvbnMpICovCgkJCWlucHV0X3JlcG9ydF9hYnMoZGV2LCBkYjlfYWJzWzBdLCAhKGRhdGFbaiArIDFdICYgMTI4KSAtICEoZGF0YVtqICsgMV0gJiA2NCkpOwoJCQlpbnB1dF9yZXBvcnRfYWJzKGRldiwgZGI5X2Fic1sxXSwgIShkYXRhW2ogKyAxXSAmIDMyKSAtICEoZGF0YVtqICsgMV0gJiAxNikpOwoJCQlmb3IgKGkgPSAwOyBpIDwgOTsgaSsrKQoJCQkJaW5wdXRfcmVwb3J0X2tleShkZXYsIGRiOV9jZDMyX2J0bltpXSwgfmRhdGFbaiArIGRiOV9zYXR1cm5fYnl0ZVtpXV0gJiBkYjlfc2F0dXJuX21hc2tbaV0pOwoJCQlicmVhazsKCQljYXNlIDB4MTk6IC8qIG1pc3Npb24gc3RpY2sgeDIgKGFuYWxvZyA2IGF4aXMgKyBidXR0b25zKSAqLwoJCQlpbnB1dF9yZXBvcnRfYWJzKGRldiwgZGI5X2Fic1swXSwgIShkYXRhW2ogKyAxXSAmIDEyOCkgLSAhKGRhdGFbaiArIDFdICYgNjQpKTsKCQkJaW5wdXRfcmVwb3J0X2FicyhkZXYsIGRiOV9hYnNbMV0sICEoZGF0YVtqICsgMV0gJiAzMikgLSAhKGRhdGFbaiArIDFdICYgMTYpKTsKCQkJZm9yIChpID0gMDsgaSA8IDk7IGkrKykKCQkJCWlucHV0X3JlcG9ydF9rZXkoZGV2LCBkYjlfY2QzMl9idG5baV0sIH5kYXRhW2ogKyBkYjlfc2F0dXJuX2J5dGVbaV1dICYgZGI5X3NhdHVybl9tYXNrW2ldKTsKCQkJaW5wdXRfcmVwb3J0X2FicyhkZXYsIGRiOV9hYnNbMl0sIGRhdGFbaiArIDNdKTsKCQkJaW5wdXRfcmVwb3J0X2FicyhkZXYsIGRiOV9hYnNbM10sIGRhdGFbaiArIDRdKTsKCQkJaW5wdXRfcmVwb3J0X2FicyhkZXYsIGRiOV9hYnNbNF0sIGRhdGFbaiArIDVdKTsKCQkJLyoKCQkJaW5wdXRfcmVwb3J0X2FicyhkZXYsIGRiOV9hYnNbOF0sIChkYXRhW2ogKyA2XSAmIDEyOCA/IDAgOiAxKSAtIChkYXRhW2ogKyA2XSAmIDY0ID8gMCA6IDEpKTsKCQkJaW5wdXRfcmVwb3J0X2FicyhkZXYsIGRiOV9hYnNbOV0sIChkYXRhW2ogKyA2XSAmIDMyID8gMCA6IDEpIC0gKGRhdGFbaiArIDZdICYgMTYgPyAwIDogMSkpOwoJCQkqLwoJCQlpbnB1dF9yZXBvcnRfYWJzKGRldiwgZGI5X2Fic1s2XSwgZGF0YVtqICsgN10pOwoJCQlpbnB1dF9yZXBvcnRfYWJzKGRldiwgZGI5X2Fic1s3XSwgZGF0YVtqICsgOF0pOwoJCQlpbnB1dF9yZXBvcnRfYWJzKGRldiwgZGI5X2Fic1s1XSwgZGF0YVtqICsgOV0pOwoJCQlicmVhazsKCQljYXNlIDB4ZDM6IC8qIHNhbmt5byBmZiAoYW5hbG9nIDEgYXhpcyArIHN0b3AgYnRuKSAqLwoJCQlpbnB1dF9yZXBvcnRfa2V5KGRldiwgQlROX0EsIGRhdGFbaiArIDNdICYgMHg4MCk7CgkJCWlucHV0X3JlcG9ydF9hYnMoZGV2LCBkYjlfYWJzWzJdLCBkYXRhW2ogKyAzXSAmIDB4N2YpOwoJCQlicmVhazsKCQljYXNlIDB4ZTM6IC8qIHNodXR0bGUgbW91c2UgKGFuYWxvZyAyIGF4aXMgKyBidXR0b25zLiBzaWduZWQgdmFsdWUpICovCgkJCWlucHV0X3JlcG9ydF9rZXkoZGV2LCBCVE5fU1RBUlQsIGRhdGFbaiArIDFdICYgMHgwOCk7CgkJCWlucHV0X3JlcG9ydF9rZXkoZGV2LCBCVE5fQSwgZGF0YVtqICsgMV0gJiAweDA0KTsKCQkJaW5wdXRfcmVwb3J0X2tleShkZXYsIEJUTl9DLCBkYXRhW2ogKyAxXSAmIDB4MDIpOwoJCQlpbnB1dF9yZXBvcnRfa2V5KGRldiwgQlROX0IsIGRhdGFbaiArIDFdICYgMHgwMSk7CgkJCWlucHV0X3JlcG9ydF9hYnMoZGV2LCBkYjlfYWJzWzJdLCBkYXRhW2ogKyAyXSBeIDB4ODApOwoJCQlpbnB1dF9yZXBvcnRfYWJzKGRldiwgZGI5X2Fic1szXSwgKDB4ZmYtKGRhdGFbaiArIDNdIF4gMHg4MCkpKzEpOyAvKiAqLwoJCQlicmVhazsKCQljYXNlIDB4ZmY6CgkJZGVmYXVsdDogLyogbm8gcGFkICovCgkJCWlucHV0X3JlcG9ydF9hYnMoZGV2LCBkYjlfYWJzWzBdLCAwKTsKCQkJaW5wdXRfcmVwb3J0X2FicyhkZXYsIGRiOV9hYnNbMV0sIDApOwoJCQlmb3IgKGkgPSAwOyBpIDwgOTsgaSsrKQoJCQkJaW5wdXRfcmVwb3J0X2tleShkZXYsIGRiOV9jZDMyX2J0bltpXSwgMCk7CgkJCWJyZWFrOwoJCX0KCX0KCXJldHVybiBuOwp9CgpzdGF0aWMgaW50IGRiOV9zYXR1cm4oaW50IG1vZGUsIHN0cnVjdCBwYXJwb3J0ICpwb3J0LCBzdHJ1Y3QgaW5wdXRfZGV2ICpkZXZzW10pCnsKCXVuc2lnbmVkIGNoYXIgaWQsIGRhdGFbNjBdOwoJaW50IHR5cGUsIG4sIG1heF9wYWRzOwoJaW50IHRtcCwgaTsKCglzd2l0Y2ggKG1vZGUpIHsKCWNhc2UgREI5X1NBVFVSTl9QQUQ6CgkJdHlwZSA9IDA7CgkJbiA9IDE7CgkJYnJlYWs7CgljYXNlIERCOV9TQVRVUk5fRFBQOgoJCXR5cGUgPSAxOwoJCW4gPSAxOwoJCWJyZWFrOwoJY2FzZSBEQjlfU0FUVVJOX0RQUF8yOgoJCXR5cGUgPSAxOwoJCW4gPSAyOwoJCWJyZWFrOwoJZGVmYXVsdDoKCQlyZXR1cm4gLTE7Cgl9CgltYXhfcGFkcyA9IG1pbihkYjlfbW9kZXNbbW9kZV0ubl9wYWRzLCBEQjlfTUFYX0RFVklDRVMpOwoJZm9yICh0bXAgPSAwLCBpID0gMDsgaSA8IG47IGkrKykgewoJCWlkID0gZGI5X3NhdHVybl9yZWFkX3BhY2tldChwb3J0LCBkYXRhLCB0eXBlICsgaSwgMSk7CgkJdG1wID0gZGI5X3NhdHVybl9yZXBvcnQoaWQsIGRhdGEsIGRldnMsIHRtcCwgbWF4X3BhZHMpOwoJfQoJcmV0dXJuIDA7Cn0KCnN0YXRpYyB2b2lkIGRiOV90aW1lcih1bnNpZ25lZCBsb25nIHByaXZhdGUpCnsKCXN0cnVjdCBkYjkgKmRiOSA9ICh2b2lkICopIHByaXZhdGU7CglzdHJ1Y3QgcGFycG9ydCAqcG9ydCA9IGRiOS0+cGQtPnBvcnQ7CglzdHJ1Y3QgaW5wdXRfZGV2ICpkZXYgPSBkYjktPmRldlswXTsKCXN0cnVjdCBpbnB1dF9kZXYgKmRldjIgPSBkYjktPmRldlsxXTsKCWludCBkYXRhLCBpOwoKCXN3aXRjaCAoZGI5LT5tb2RlKSB7CgkJY2FzZSBEQjlfTVVMVElfMDgwMl8yOgoKCQkJZGF0YSA9IHBhcnBvcnRfcmVhZF9kYXRhKHBvcnQpID4+IDM7CgoJCQlpbnB1dF9yZXBvcnRfYWJzKGRldjIsIEFCU19YLCAoZGF0YSAmIERCOV9SSUdIVCA/IDAgOiAxKSAtIChkYXRhICYgREI5X0xFRlQgPyAwIDogMSkpOwoJCQlpbnB1dF9yZXBvcnRfYWJzKGRldjIsIEFCU19ZLCAoZGF0YSAmIERCOV9ET1dOICA/IDAgOiAxKSAtIChkYXRhICYgREI5X1VQICAgPyAwIDogMSkpOwoJCQlpbnB1dF9yZXBvcnRfa2V5KGRldjIsIEJUTl9UUklHR0VSLCB+ZGF0YSAmIERCOV9GSVJFMSk7CgoJCWNhc2UgREI5X01VTFRJXzA4MDI6CgoJCQlkYXRhID0gcGFycG9ydF9yZWFkX3N0YXR1cyhwb3J0KSA+PiAzOwoKCQkJaW5wdXRfcmVwb3J0X2FicyhkZXYsIEFCU19YLCAoZGF0YSAmIERCOV9SSUdIVCA/IDAgOiAxKSAtIChkYXRhICYgREI5X0xFRlQgPyAwIDogMSkpOwoJCQlpbnB1dF9yZXBvcnRfYWJzKGRldiwgQUJTX1ksIChkYXRhICYgREI5X0RPV04gID8gMCA6IDEpIC0gKGRhdGEgJiBEQjlfVVAgICA/IDAgOiAxKSk7CgkJCWlucHV0X3JlcG9ydF9rZXkoZGV2LCBCVE5fVFJJR0dFUiwgZGF0YSAmIERCOV9GSVJFMSk7CgkJCWJyZWFrOwoKCQljYXNlIERCOV9NVUxUSV9TVElDSzoKCgkJCWRhdGEgPSBwYXJwb3J0X3JlYWRfZGF0YShwb3J0KTsKCgkJCWlucHV0X3JlcG9ydF9hYnMoZGV2LCBBQlNfWCwgKGRhdGEgJiBEQjlfUklHSFQgPyAwIDogMSkgLSAoZGF0YSAmIERCOV9MRUZUID8gMCA6IDEpKTsKCQkJaW5wdXRfcmVwb3J0X2FicyhkZXYsIEFCU19ZLCAoZGF0YSAmIERCOV9ET1dOICA/IDAgOiAxKSAtIChkYXRhICYgREI5X1VQICAgPyAwIDogMSkpOwoJCQlpbnB1dF9yZXBvcnRfa2V5KGRldiwgQlROX1RSSUdHRVIsIH5kYXRhICYgREI5X0ZJUkUxKTsKCQkJYnJlYWs7CgoJCWNhc2UgREI5X01VTFRJMl9TVElDSzoKCgkJCWRhdGEgPSBwYXJwb3J0X3JlYWRfZGF0YShwb3J0KTsKCgkJCWlucHV0X3JlcG9ydF9hYnMoZGV2LCBBQlNfWCwgKGRhdGEgJiBEQjlfUklHSFQgPyAwIDogMSkgLSAoZGF0YSAmIERCOV9MRUZUID8gMCA6IDEpKTsKCQkJaW5wdXRfcmVwb3J0X2FicyhkZXYsIEFCU19ZLCAoZGF0YSAmIERCOV9ET1dOICA/IDAgOiAxKSAtIChkYXRhICYgREI5X1VQICAgPyAwIDogMSkpOwoJCQlpbnB1dF9yZXBvcnRfa2V5KGRldiwgQlROX1RSSUdHRVIsIH5kYXRhICYgREI5X0ZJUkUxKTsKCQkJaW5wdXRfcmVwb3J0X2tleShkZXYsIEJUTl9USFVNQiwgICB+ZGF0YSAmIERCOV9GSVJFMik7CgkJCWJyZWFrOwoKCQljYXNlIERCOV9HRU5FU0lTX1BBRDoKCgkJCXBhcnBvcnRfd3JpdGVfY29udHJvbChwb3J0LCBEQjlfTk9TRUxFQ1QpOwoJCQlkYXRhID0gcGFycG9ydF9yZWFkX2RhdGEocG9ydCk7CgoJCQlpbnB1dF9yZXBvcnRfYWJzKGRldiwgQUJTX1gsIChkYXRhICYgREI5X1JJR0hUID8gMCA6IDEpIC0gKGRhdGEgJiBEQjlfTEVGVCA/IDAgOiAxKSk7CgkJCWlucHV0X3JlcG9ydF9hYnMoZGV2LCBBQlNfWSwgKGRhdGEgJiBEQjlfRE9XTiAgPyAwIDogMSkgLSAoZGF0YSAmIERCOV9VUCAgID8gMCA6IDEpKTsKCQkJaW5wdXRfcmVwb3J0X2tleShkZXYsIEJUTl9CLCB+ZGF0YSAmIERCOV9GSVJFMSk7CgkJCWlucHV0X3JlcG9ydF9rZXkoZGV2LCBCVE5fQywgfmRhdGEgJiBEQjlfRklSRTIpOwoKCQkJcGFycG9ydF93cml0ZV9jb250cm9sKHBvcnQsIERCOV9OT1JNQUwpOwoJCQlkYXRhID0gcGFycG9ydF9yZWFkX2RhdGEocG9ydCk7CgoJCQlpbnB1dF9yZXBvcnRfa2V5KGRldiwgQlROX0EsICAgICB+ZGF0YSAmIERCOV9GSVJFMSk7CgkJCWlucHV0X3JlcG9ydF9rZXkoZGV2LCBCVE5fU1RBUlQsIH5kYXRhICYgREI5X0ZJUkUyKTsKCQkJYnJlYWs7CgoJCWNhc2UgREI5X0dFTkVTSVM1X1BBRDoKCgkJCXBhcnBvcnRfd3JpdGVfY29udHJvbChwb3J0LCBEQjlfTk9TRUxFQ1QpOwoJCQlkYXRhID0gcGFycG9ydF9yZWFkX2RhdGEocG9ydCk7CgoJCQlpbnB1dF9yZXBvcnRfYWJzKGRldiwgQUJTX1gsIChkYXRhICYgREI5X1JJR0hUID8gMCA6IDEpIC0gKGRhdGEgJiBEQjlfTEVGVCA/IDAgOiAxKSk7CgkJCWlucHV0X3JlcG9ydF9hYnMoZGV2LCBBQlNfWSwgKGRhdGEgJiBEQjlfRE9XTiAgPyAwIDogMSkgLSAoZGF0YSAmIERCOV9VUCAgID8gMCA6IDEpKTsKCQkJaW5wdXRfcmVwb3J0X2tleShkZXYsIEJUTl9CLCB+ZGF0YSAmIERCOV9GSVJFMSk7CgkJCWlucHV0X3JlcG9ydF9rZXkoZGV2LCBCVE5fQywgfmRhdGEgJiBEQjlfRklSRTIpOwoKCQkJcGFycG9ydF93cml0ZV9jb250cm9sKHBvcnQsIERCOV9OT1JNQUwpOwoJCQlkYXRhID0gcGFycG9ydF9yZWFkX2RhdGEocG9ydCk7CgoJCQlpbnB1dF9yZXBvcnRfa2V5KGRldiwgQlROX0EsICAgICB+ZGF0YSAmIERCOV9GSVJFMSk7CgkJCWlucHV0X3JlcG9ydF9rZXkoZGV2LCBCVE5fWCwgICAgIH5kYXRhICYgREI5X0ZJUkUyKTsKCQkJaW5wdXRfcmVwb3J0X2tleShkZXYsIEJUTl9ZLCAgICAgfmRhdGEgJiBEQjlfTEVGVCk7CgkJCWlucHV0X3JlcG9ydF9rZXkoZGV2LCBCVE5fU1RBUlQsIH5kYXRhICYgREI5X1JJR0hUKTsKCQkJYnJlYWs7CgoJCWNhc2UgREI5X0dFTkVTSVM2X1BBRDoKCgkJCXBhcnBvcnRfd3JpdGVfY29udHJvbChwb3J0LCBEQjlfTk9TRUxFQ1QpOyAvKiAxICovCgkJCXVkZWxheShEQjlfR0VORVNJUzZfREVMQVkpOwoJCQlkYXRhID0gcGFycG9ydF9yZWFkX2RhdGEocG9ydCk7CgoJCQlpbnB1dF9yZXBvcnRfYWJzKGRldiwgQUJTX1gsIChkYXRhICYgREI5X1JJR0hUID8gMCA6IDEpIC0gKGRhdGEgJiBEQjlfTEVGVCA/IDAgOiAxKSk7CgkJCWlucHV0X3JlcG9ydF9hYnMoZGV2LCBBQlNfWSwgKGRhdGEgJiBEQjlfRE9XTiAgPyAwIDogMSkgLSAoZGF0YSAmIERCOV9VUCAgID8gMCA6IDEpKTsKCQkJaW5wdXRfcmVwb3J0X2tleShkZXYsIEJUTl9CLCB+ZGF0YSAmIERCOV9GSVJFMSk7CgkJCWlucHV0X3JlcG9ydF9rZXkoZGV2LCBCVE5fQywgfmRhdGEgJiBEQjlfRklSRTIpOwoKCQkJcGFycG9ydF93cml0ZV9jb250cm9sKHBvcnQsIERCOV9OT1JNQUwpOwoJCQl1ZGVsYXkoREI5X0dFTkVTSVM2X0RFTEFZKTsKCQkJZGF0YSA9IHBhcnBvcnRfcmVhZF9kYXRhKHBvcnQpOwoKCQkJaW5wdXRfcmVwb3J0X2tleShkZXYsIEJUTl9BLCB+ZGF0YSAmIERCOV9GSVJFMSk7CgkJCWlucHV0X3JlcG9ydF9rZXkoZGV2LCBCVE5fU1RBUlQsIH5kYXRhICYgREI5X0ZJUkUyKTsKCgkJCXBhcnBvcnRfd3JpdGVfY29udHJvbChwb3J0LCBEQjlfTk9TRUxFQ1QpOyAvKiAyICovCgkJCXVkZWxheShEQjlfR0VORVNJUzZfREVMQVkpOwoJCQlwYXJwb3J0X3dyaXRlX2NvbnRyb2wocG9ydCwgREI5X05PUk1BTCk7CgkJCXVkZWxheShEQjlfR0VORVNJUzZfREVMQVkpOwoJCQlwYXJwb3J0X3dyaXRlX2NvbnRyb2wocG9ydCwgREI5X05PU0VMRUNUKTsgLyogMyAqLwoJCQl1ZGVsYXkoREI5X0dFTkVTSVM2X0RFTEFZKTsKCQkJZGF0YT1wYXJwb3J0X3JlYWRfZGF0YShwb3J0KTsKCgkJCWlucHV0X3JlcG9ydF9rZXkoZGV2LCBCVE5fWCwgICAgfmRhdGEgJiBEQjlfTEVGVCk7CgkJCWlucHV0X3JlcG9ydF9rZXkoZGV2LCBCVE5fWSwgICAgfmRhdGEgJiBEQjlfRE9XTik7CgkJCWlucHV0X3JlcG9ydF9rZXkoZGV2LCBCVE5fWiwgICAgfmRhdGEgJiBEQjlfVVApOwoJCQlpbnB1dF9yZXBvcnRfa2V5KGRldiwgQlROX01PREUsIH5kYXRhICYgREI5X1JJR0hUKTsKCgkJCXBhcnBvcnRfd3JpdGVfY29udHJvbChwb3J0LCBEQjlfTk9STUFMKTsKCQkJdWRlbGF5KERCOV9HRU5FU0lTNl9ERUxBWSk7CgkJCXBhcnBvcnRfd3JpdGVfY29udHJvbChwb3J0LCBEQjlfTk9TRUxFQ1QpOyAvKiA0ICovCgkJCXVkZWxheShEQjlfR0VORVNJUzZfREVMQVkpOwoJCQlwYXJwb3J0X3dyaXRlX2NvbnRyb2wocG9ydCwgREI5X05PUk1BTCk7CgkJCWJyZWFrOwoKCQljYXNlIERCOV9TQVRVUk5fUEFEOgoJCWNhc2UgREI5X1NBVFVSTl9EUFA6CgkJY2FzZSBEQjlfU0FUVVJOX0RQUF8yOgoKCQkJZGI5X3NhdHVybihkYjktPm1vZGUsIHBvcnQsIGRiOS0+ZGV2KTsKCQkJYnJlYWs7CgoJCWNhc2UgREI5X0NEMzJfUEFEOgoKCQkJZGF0YSA9IHBhcnBvcnRfcmVhZF9kYXRhKHBvcnQpOwoKCQkJaW5wdXRfcmVwb3J0X2FicyhkZXYsIEFCU19YLCAoZGF0YSAmIERCOV9SSUdIVCA/IDAgOiAxKSAtIChkYXRhICYgREI5X0xFRlQgPyAwIDogMSkpOwoJCQlpbnB1dF9yZXBvcnRfYWJzKGRldiwgQUJTX1ksIChkYXRhICYgREI5X0RPV04gID8gMCA6IDEpIC0gKGRhdGEgJiBEQjlfVVAgICA/IDAgOiAxKSk7CgoJCQlwYXJwb3J0X3dyaXRlX2NvbnRyb2wocG9ydCwgMHgwYSk7CgoJCQlmb3IgKGkgPSAwOyBpIDwgNzsgaSsrKSB7CgkJCQlkYXRhID0gcGFycG9ydF9yZWFkX2RhdGEocG9ydCk7CgkJCQlwYXJwb3J0X3dyaXRlX2NvbnRyb2wocG9ydCwgMHgwMik7CgkJCQlwYXJwb3J0X3dyaXRlX2NvbnRyb2wocG9ydCwgMHgwYSk7CgkJCQlpbnB1dF9yZXBvcnRfa2V5KGRldiwgZGI5X2NkMzJfYnRuW2ldLCB+ZGF0YSAmIERCOV9GSVJFMik7CgkJCX0KCgkJCXBhcnBvcnRfd3JpdGVfY29udHJvbChwb3J0LCAweDAwKTsKCQkJYnJlYWs7CgkJfQoKCWlucHV0X3N5bmMoZGV2KTsKCgltb2RfdGltZXIoJmRiOS0+dGltZXIsIGppZmZpZXMgKyBEQjlfUkVGUkVTSF9USU1FKTsKfQoKc3RhdGljIGludCBkYjlfb3BlbihzdHJ1Y3QgaW5wdXRfZGV2ICpkZXYpCnsKCXN0cnVjdCBkYjkgKmRiOSA9IGRldi0+cHJpdmF0ZTsKCXN0cnVjdCBwYXJwb3J0ICpwb3J0ID0gZGI5LT5wZC0+cG9ydDsKCWludCBlcnI7CgoJZXJyID0gbXV0ZXhfbG9ja19pbnRlcnJ1cHRpYmxlKCZkYjktPm11dGV4KTsKCWlmIChlcnIpCgkJcmV0dXJuIGVycjsKCglpZiAoIWRiOS0+dXNlZCsrKSB7CgkJcGFycG9ydF9jbGFpbShkYjktPnBkKTsKCQlwYXJwb3J0X3dyaXRlX2RhdGEocG9ydCwgMHhmZik7CgkJaWYgKGRiOV9tb2Rlc1tkYjktPm1vZGVdLnJldmVyc2UpIHsKCQkJcGFycG9ydF9kYXRhX3JldmVyc2UocG9ydCk7CgkJCXBhcnBvcnRfd3JpdGVfY29udHJvbChwb3J0LCBEQjlfTk9STUFMKTsKCQl9CgkJbW9kX3RpbWVyKCZkYjktPnRpbWVyLCBqaWZmaWVzICsgREI5X1JFRlJFU0hfVElNRSk7Cgl9CgoJbXV0ZXhfdW5sb2NrKCZkYjktPm11dGV4KTsKCXJldHVybiAwOwp9CgpzdGF0aWMgdm9pZCBkYjlfY2xvc2Uoc3RydWN0IGlucHV0X2RldiAqZGV2KQp7CglzdHJ1Y3QgZGI5ICpkYjkgPSBkZXYtPnByaXZhdGU7CglzdHJ1Y3QgcGFycG9ydCAqcG9ydCA9IGRiOS0+cGQtPnBvcnQ7CgoJbXV0ZXhfbG9jaygmZGI5LT5tdXRleCk7CglpZiAoIS0tZGI5LT51c2VkKSB7CgkJZGVsX3RpbWVyX3N5bmMoJmRiOS0+dGltZXIpOwoJCXBhcnBvcnRfd3JpdGVfY29udHJvbChwb3J0LCAweDAwKTsKCQlwYXJwb3J0X2RhdGFfZm9yd2FyZChwb3J0KTsKCQlwYXJwb3J0X3JlbGVhc2UoZGI5LT5wZCk7Cgl9CgltdXRleF91bmxvY2soJmRiOS0+bXV0ZXgpOwp9CgpzdGF0aWMgc3RydWN0IGRiOSBfX2luaXQgKmRiOV9wcm9iZShpbnQgcGFycG9ydCwgaW50IG1vZGUpCnsKCXN0cnVjdCBkYjkgKmRiOTsKCWNvbnN0IHN0cnVjdCBkYjlfbW9kZV9kYXRhICpkYjlfbW9kZTsKCXN0cnVjdCBwYXJwb3J0ICpwcDsKCXN0cnVjdCBwYXJkZXZpY2UgKnBkOwoJc3RydWN0IGlucHV0X2RldiAqaW5wdXRfZGV2OwoJaW50IGksIGo7CglpbnQgZXJyOwoKCWlmIChtb2RlIDwgMSB8fCBtb2RlID49IERCOV9NQVhfUEFEIHx8ICFkYjlfbW9kZXNbbW9kZV0ubl9idXR0b25zKSB7CgkJcHJpbnRrKEtFUk5fRVJSICJkYjkuYzogQmFkIGRldmljZSB0eXBlICVkXG4iLCBtb2RlKTsKCQllcnIgPSAtRUlOVkFMOwoJCWdvdG8gZXJyX291dDsKCX0KCglkYjlfbW9kZSA9ICZkYjlfbW9kZXNbbW9kZV07CgoJcHAgPSBwYXJwb3J0X2ZpbmRfbnVtYmVyKHBhcnBvcnQpOwoJaWYgKCFwcCkgewoJCXByaW50ayhLRVJOX0VSUiAiZGI5LmM6IG5vIHN1Y2ggcGFycG9ydFxuIik7CgkJZXJyID0gLUVOT0RFVjsKCQlnb3RvIGVycl9vdXQ7Cgl9CgoJaWYgKGRiOV9tb2RlLT5iaWRpcmVjdGlvbmFsICYmICEocHAtPm1vZGVzICYgUEFSUE9SVF9NT0RFX1RSSVNUQVRFKSkgewoJCXByaW50ayhLRVJOX0VSUiAiZGI5LmM6IHNwZWNpZmllZCBwYXJwb3J0IGlzIG5vdCBiaWRpcmVjdGlvbmFsXG4iKTsKCQllcnIgPSAtRUlOVkFMOwoJCWdvdG8gZXJyX3B1dF9wcDsKCX0KCglwZCA9IHBhcnBvcnRfcmVnaXN0ZXJfZGV2aWNlKHBwLCAiZGI5IiwgTlVMTCwgTlVMTCwgTlVMTCwgUEFSUE9SVF9ERVZfRVhDTCwgTlVMTCk7CglpZiAoIXBkKSB7CgkJcHJpbnRrKEtFUk5fRVJSICJkYjkuYzogcGFycG9ydCBidXN5IGFscmVhZHkgLSBscC5vIGxvYWRlZD9cbiIpOwoJCWVyciA9IC1FQlVTWTsKCQlnb3RvIGVycl9wdXRfcHA7Cgl9CgoJZGI5ID0ga3phbGxvYyhzaXplb2Yoc3RydWN0IGRiOSksIEdGUF9LRVJORUwpOwoJaWYgKCFkYjkpIHsKCQlwcmludGsoS0VSTl9FUlIgImRiOS5jOiBOb3QgZW5vdWdoIG1lbW9yeVxuIik7CgkJZXJyID0gLUVOT01FTTsKCQlnb3RvIGVycl91bnJlZ19wYXJkZXY7Cgl9CgoJbXV0ZXhfaW5pdCgmZGI5LT5tdXRleCk7CglkYjktPnBkID0gcGQ7CglkYjktPm1vZGUgPSBtb2RlOwoJaW5pdF90aW1lcigmZGI5LT50aW1lcik7CglkYjktPnRpbWVyLmRhdGEgPSAobG9uZykgZGI5OwoJZGI5LT50aW1lci5mdW5jdGlvbiA9IGRiOV90aW1lcjsKCglmb3IgKGkgPSAwOyBpIDwgKG1pbihkYjlfbW9kZS0+bl9wYWRzLCBEQjlfTUFYX0RFVklDRVMpKTsgaSsrKSB7CgoJCWRiOS0+ZGV2W2ldID0gaW5wdXRfZGV2ID0gaW5wdXRfYWxsb2NhdGVfZGV2aWNlKCk7CgkJaWYgKCFpbnB1dF9kZXYpIHsKCQkJcHJpbnRrKEtFUk5fRVJSICJkYjkuYzogTm90IGVub3VnaCBtZW1vcnkgZm9yIGlucHV0IGRldmljZVxuIik7CgkJCWVyciA9IC1FTk9NRU07CgkJCWdvdG8gZXJyX3VucmVnX2RldnM7CgkJfQoKCQlzbnByaW50ZihkYjktPnBoeXNbaV0sIHNpemVvZihkYjktPnBoeXNbaV0pLAoJCQkgIiVzL2lucHV0JWQiLCBkYjktPnBkLT5wb3J0LT5uYW1lLCBpKTsKCgkJaW5wdXRfZGV2LT5uYW1lID0gZGI5X21vZGUtPm5hbWU7CgkJaW5wdXRfZGV2LT5waHlzID0gZGI5LT5waHlzW2ldOwoJCWlucHV0X2Rldi0+aWQuYnVzdHlwZSA9IEJVU19QQVJQT1JUOwoJCWlucHV0X2Rldi0+aWQudmVuZG9yID0gMHgwMDAyOwoJCWlucHV0X2Rldi0+aWQucHJvZHVjdCA9IG1vZGU7CgkJaW5wdXRfZGV2LT5pZC52ZXJzaW9uID0gMHgwMTAwOwoJCWlucHV0X2Rldi0+cHJpdmF0ZSA9IGRiOTsKCgkJaW5wdXRfZGV2LT5vcGVuID0gZGI5X29wZW47CgkJaW5wdXRfZGV2LT5jbG9zZSA9IGRiOV9jbG9zZTsKCgkJaW5wdXRfZGV2LT5ldmJpdFswXSA9IEJJVChFVl9LRVkpIHwgQklUKEVWX0FCUyk7CgkJZm9yIChqID0gMDsgaiA8IGRiOV9tb2RlLT5uX2J1dHRvbnM7IGorKykKCQkJc2V0X2JpdChkYjlfbW9kZS0+YnV0dG9uc1tqXSwgaW5wdXRfZGV2LT5rZXliaXQpOwoJCWZvciAoaiA9IDA7IGogPCBkYjlfbW9kZS0+bl9heGlzOyBqKyspIHsKCQkJaWYgKGogPCAyKQoJCQkJaW5wdXRfc2V0X2Fic19wYXJhbXMoaW5wdXRfZGV2LCBkYjlfYWJzW2pdLCAtMSwgMSwgMCwgMCk7CgkJCWVsc2UKCQkJCWlucHV0X3NldF9hYnNfcGFyYW1zKGlucHV0X2RldiwgZGI5X2Fic1tqXSwgMSwgMjU1LCAwLCAwKTsKCQl9CgoJCWVyciA9IGlucHV0X3JlZ2lzdGVyX2RldmljZShpbnB1dF9kZXYpOwoJCWlmIChlcnIpCgkJCWdvdG8gZXJyX2ZyZWVfZGV2OwoJfQoKCXBhcnBvcnRfcHV0X3BvcnQocHApOwoJcmV0dXJuIGRiOTsKCiBlcnJfZnJlZV9kZXY6CglpbnB1dF9mcmVlX2RldmljZShkYjktPmRldltpXSk7CiBlcnJfdW5yZWdfZGV2czoKCXdoaWxlICgtLWkgPj0gMCkKCQlpbnB1dF91bnJlZ2lzdGVyX2RldmljZShkYjktPmRldltpXSk7CglrZnJlZShkYjkpOwogZXJyX3VucmVnX3BhcmRldjoKCXBhcnBvcnRfdW5yZWdpc3Rlcl9kZXZpY2UocGQpOwogZXJyX3B1dF9wcDoKCXBhcnBvcnRfcHV0X3BvcnQocHApOwogZXJyX291dDoKCXJldHVybiBFUlJfUFRSKGVycik7Cn0KCnN0YXRpYyB2b2lkIGRiOV9yZW1vdmUoc3RydWN0IGRiOSAqZGI5KQp7CglpbnQgaTsKCglmb3IgKGkgPSAwOyBpIDwgbWluKGRiOV9tb2Rlc1tkYjktPm1vZGVdLm5fcGFkcywgREI5X01BWF9ERVZJQ0VTKTsgaSsrKQoJCWlucHV0X3VucmVnaXN0ZXJfZGV2aWNlKGRiOS0+ZGV2W2ldKTsKCXBhcnBvcnRfdW5yZWdpc3Rlcl9kZXZpY2UoZGI5LT5wZCk7CglrZnJlZShkYjkpOwp9CgpzdGF0aWMgaW50IF9faW5pdCBkYjlfaW5pdCh2b2lkKQp7CglpbnQgaTsKCWludCBoYXZlX2RldiA9IDA7CglpbnQgZXJyID0gMDsKCglmb3IgKGkgPSAwOyBpIDwgREI5X01BWF9QT1JUUzsgaSsrKSB7CgkJaWYgKGRiOVtpXS5uYXJncyA9PSAwIHx8IGRiOVtpXS5hcmdzW0RCOV9BUkdfUEFSUE9SVF0gPCAwKQoJCQljb250aW51ZTsKCgkJaWYgKGRiOVtpXS5uYXJncyA8IDIpIHsKCQkJcHJpbnRrKEtFUk5fRVJSICJkYjkuYzogRGV2aWNlIHR5cGUgbXVzdCBiZSBzcGVjaWZpZWQuXG4iKTsKCQkJZXJyID0gLUVJTlZBTDsKCQkJYnJlYWs7CgkJfQoKCQlkYjlfYmFzZVtpXSA9IGRiOV9wcm9iZShkYjlbaV0uYXJnc1tEQjlfQVJHX1BBUlBPUlRdLAoJCQkJCWRiOVtpXS5hcmdzW0RCOV9BUkdfTU9ERV0pOwoJCWlmIChJU19FUlIoZGI5X2Jhc2VbaV0pKSB7CgkJCWVyciA9IFBUUl9FUlIoZGI5X2Jhc2VbaV0pOwoJCQlicmVhazsKCQl9CgoJCWhhdmVfZGV2ID0gMTsKCX0KCglpZiAoZXJyKSB7CgkJd2hpbGUgKC0taSA+PSAwKQoJCQlpZiAoZGI5X2Jhc2VbaV0pCgkJCQlkYjlfcmVtb3ZlKGRiOV9iYXNlW2ldKTsKCQlyZXR1cm4gZXJyOwoJfQoKCXJldHVybiBoYXZlX2RldiA/IDAgOiAtRU5PREVWOwp9CgpzdGF0aWMgdm9pZCBfX2V4aXQgZGI5X2V4aXQodm9pZCkKewoJaW50IGk7CgoJZm9yIChpID0gMDsgaSA8IERCOV9NQVhfUE9SVFM7IGkrKykKCQlpZiAoZGI5X2Jhc2VbaV0pCgkJCWRiOV9yZW1vdmUoZGI5X2Jhc2VbaV0pOwp9Cgptb2R1bGVfaW5pdChkYjlfaW5pdCk7Cm1vZHVsZV9leGl0KGRiOV9leGl0KTsK