LyoKICogJElkOiBkYjkuYyx2IDEuMTMgMjAwMi8wNC8wNyAyMDoxMzozNyB2b2p0ZWNoIEV4cCAkCiAqCiAqICBDb3B5cmlnaHQgKGMpIDE5OTktMjAwMSBWb2p0ZWNoIFBhdmxpawogKgogKiAgQmFzZWQgb24gdGhlIHdvcmsgb2Y6CiAqCUFuZHJlZSBCb3JybWFubgkJTWF0cyBTavZ2YWxsCiAqLwoKLyoKICogQXRhcmksIEFtc3RyYWQsIENvbW1vZG9yZSwgQW1pZ2EsIFNlZ2EsIGV0Yy4gam95c3RpY2sgZHJpdmVyIGZvciBMaW51eAogKi8KCi8qCiAqIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5CiAqIGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5CiAqIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlciB2ZXJzaW9uIDIgb2YgdGhlIExpY2Vuc2UsIG9yCiAqIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlCiAqIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIGFsb25nIHdpdGggdGhpcyBwcm9ncmFtOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDU5IFRlbXBsZSBQbGFjZSwgU3VpdGUgMzMwLCBCb3N0b24sIE1BIDAyMTExLTEzMDcgVVNBCiAqCiAqIFNob3VsZCB5b3UgbmVlZCB0byBjb250YWN0IG1lLCB0aGUgYXV0aG9yLCB5b3UgY2FuIGRvIHNvIGVpdGhlciBieQogKiBlLW1haWwgLSBtYWlsIHlvdXIgbWVzc2FnZSB0byA8dm9qdGVjaEB1Y3cuY3o+LCBvciBieSBwYXBlciBtYWlsOgogKiBWb2p0ZWNoIFBhdmxpaywgU2ltdW5rb3ZhIDE1OTQsIFByYWd1ZSA4LCAxODIgMDAgQ3plY2ggUmVwdWJsaWMKICovCgojaW5jbHVkZSA8bGludXgva2VybmVsLmg+CiNpbmNsdWRlIDxsaW51eC9tb2R1bGUuaD4KI2luY2x1ZGUgPGxpbnV4L21vZHVsZXBhcmFtLmg+CiNpbmNsdWRlIDxsaW51eC9kZWxheS5oPgojaW5jbHVkZSA8bGludXgvaW5pdC5oPgojaW5jbHVkZSA8bGludXgvcGFycG9ydC5oPgojaW5jbHVkZSA8bGludXgvaW5wdXQuaD4KCk1PRFVMRV9BVVRIT1IoIlZvanRlY2ggUGF2bGlrIDx2b2p0ZWNoQHVjdy5jej4iKTsKTU9EVUxFX0RFU0NSSVBUSU9OKCJBdGFyaSwgQW1zdHJhZCwgQ29tbW9kb3JlLCBBbWlnYSwgU2VnYSwgZXRjLiBqb3lzdGljayBkcml2ZXIiKTsKTU9EVUxFX0xJQ0VOU0UoIkdQTCIpOwoKc3RydWN0IGRiOV9jb25maWcgewoJaW50IGFyZ3NbMl07CglpbnQgbmFyZ3M7Cn07CgojZGVmaW5lIERCOV9NQVhfUE9SVFMJCTMKc3RhdGljIHN0cnVjdCBkYjlfY29uZmlnIGRiOVtEQjlfTUFYX1BPUlRTXSBfX2luaXRkYXRhOwoKbW9kdWxlX3BhcmFtX2FycmF5X25hbWVkKGRldiwgZGI5WzBdLmFyZ3MsIGludCwgJmRiOVswXS5uYXJncywgMCk7Ck1PRFVMRV9QQVJNX0RFU0MoZGV2LCAiRGVzY3JpYmVzIGZpcnN0IGF0dGFjaGVkIGRldmljZSAoPHBhcnBvcnQjPiw8dHlwZT4pIik7Cm1vZHVsZV9wYXJhbV9hcnJheV9uYW1lZChkZXYyLCBkYjlbMV0uYXJncywgaW50LCAmZGI5WzBdLm5hcmdzLCAwKTsKTU9EVUxFX1BBUk1fREVTQyhkZXYyLCAiRGVzY3JpYmVzIHNlY29uZCBhdHRhY2hlZCBkZXZpY2UgKDxwYXJwb3J0Iz4sPHR5cGU+KSIpOwptb2R1bGVfcGFyYW1fYXJyYXlfbmFtZWQoZGV2MywgZGI5WzJdLmFyZ3MsIGludCwgJmRiOVsyXS5uYXJncywgMCk7Ck1PRFVMRV9QQVJNX0RFU0MoZGV2MywgIkRlc2NyaWJlcyB0aGlyZCBhdHRhY2hlZCBkZXZpY2UgKDxwYXJwb3J0Iz4sPHR5cGU+KSIpOwoKX19vYnNvbGV0ZV9zZXR1cCgiZGI5PSIpOwpfX29ic29sZXRlX3NldHVwKCJkYjlfMj0iKTsKX19vYnNvbGV0ZV9zZXR1cCgiZGI5XzM9Iik7CgojZGVmaW5lIERCOV9BUkdfUEFSUE9SVAkJMAojZGVmaW5lIERCOV9BUkdfTU9ERQkJMQoKI2RlZmluZSBEQjlfTVVMVElfU1RJQ0sJCTB4MDEKI2RlZmluZSBEQjlfTVVMVEkyX1NUSUNLCTB4MDIKI2RlZmluZSBEQjlfR0VORVNJU19QQUQJCTB4MDMKI2RlZmluZSBEQjlfR0VORVNJUzVfUEFECTB4MDUKI2RlZmluZSBEQjlfR0VORVNJUzZfUEFECTB4MDYKI2RlZmluZSBEQjlfU0FUVVJOX1BBRAkJMHgwNwojZGVmaW5lIERCOV9NVUxUSV8wODAyCQkweDA4CiNkZWZpbmUgREI5X01VTFRJXzA4MDJfMgkweDA5CiNkZWZpbmUgREI5X0NEMzJfUEFECQkweDBBCiNkZWZpbmUgREI5X1NBVFVSTl9EUFAJCTB4MEIKI2RlZmluZSBEQjlfU0FUVVJOX0RQUF8yCTB4MEMKI2RlZmluZSBEQjlfTUFYX1BBRAkJMHgwRAoKI2RlZmluZSBEQjlfVVAJCQkweDAxCiNkZWZpbmUgREI5X0RPV04JCTB4MDIKI2RlZmluZSBEQjlfTEVGVAkJMHgwNAojZGVmaW5lIERCOV9SSUdIVAkJMHgwOAojZGVmaW5lIERCOV9GSVJFMQkJMHgxMAojZGVmaW5lIERCOV9GSVJFMgkJMHgyMAojZGVmaW5lIERCOV9GSVJFMwkJMHg0MAojZGVmaW5lIERCOV9GSVJFNAkJMHg4MAoKI2RlZmluZSBEQjlfTk9STUFMCQkweDBhCiNkZWZpbmUgREI5X05PU0VMRUNUCQkweDA4CgojZGVmaW5lIERCOV9HRU5FU0lTNl9ERUxBWQkxNAojZGVmaW5lIERCOV9SRUZSRVNIX1RJTUUJSFovMTAwCgojZGVmaW5lIERCOV9NQVhfREVWSUNFUwkJMgoKc3RydWN0IGRiOV9tb2RlX2RhdGEgewoJY29uc3QgY2hhciAqbmFtZTsKCWNvbnN0IHNob3J0ICpidXR0b25zOwoJaW50IG5fYnV0dG9uczsKCWludCBuX3BhZHM7CglpbnQgbl9heGlzOwoJaW50IGJpZGlyZWN0aW9uYWw7CglpbnQgcmV2ZXJzZTsKfTsKCnN0cnVjdCBkYjkgewoJc3RydWN0IGlucHV0X2RldiAqZGV2W0RCOV9NQVhfREVWSUNFU107CglzdHJ1Y3QgdGltZXJfbGlzdCB0aW1lcjsKCXN0cnVjdCBwYXJkZXZpY2UgKnBkOwoJaW50IG1vZGU7CglpbnQgdXNlZDsKCXN0cnVjdCBzZW1hcGhvcmUgc2VtOwoJY2hhciBwaHlzW0RCOV9NQVhfREVWSUNFU11bMzJdOwp9OwoKc3RhdGljIHN0cnVjdCBkYjkgKmRiOV9iYXNlWzNdOwoKc3RhdGljIGNvbnN0IHNob3J0IGRiOV9tdWx0aV9idG5bXSA9IHsgQlROX1RSSUdHRVIsIEJUTl9USFVNQiB9OwpzdGF0aWMgY29uc3Qgc2hvcnQgZGI5X2dlbmVzaXNfYnRuW10gPSB7IEJUTl9TVEFSVCwgQlROX0EsIEJUTl9CLCBCVE5fQywgQlROX1gsIEJUTl9ZLCBCVE5fWiwgQlROX01PREUgfTsKc3RhdGljIGNvbnN0IHNob3J0IGRiOV9jZDMyX2J0bltdID0geyBCVE5fQSwgQlROX0IsIEJUTl9DLCBCVE5fWCwgQlROX1ksIEJUTl9aLCBCVE5fVEwsIEJUTl9UUiwgQlROX1NUQVJUIH07CnN0YXRpYyBjb25zdCBzaG9ydCBkYjlfYWJzW10gPSB7IEFCU19YLCBBQlNfWSwgQUJTX1JYLCBBQlNfUlksIEFCU19SWiwgQUJTX1osIEFCU19IQVQwWCwgQUJTX0hBVDBZLCBBQlNfSEFUMVgsIEFCU19IQVQxWSB9OwoKc3RhdGljIGNvbnN0IHN0cnVjdCBkYjlfbW9kZV9kYXRhIGRiOV9tb2Rlc1tdID0gewoJeyBOVUxMLAkJCQkJIE5VTEwsCQkgIDAsICAwLCAgMCwgIDAsICAwIH0sCgl7ICJNdWx0aXN5c3RlbSBqb3lzdGljayIsCQkgZGI5X211bHRpX2J0biwJICAxLCAgMSwgIDIsICAxLCAgMSB9LAoJeyAiTXVsdGlzeXN0ZW0gam95c3RpY2sgKDIgZmlyZSkiLAkgZGI5X211bHRpX2J0biwJICAyLCAgMSwgIDIsICAxLCAgMSB9LAoJeyAiR2VuZXNpcyBwYWQiLAkJCSBkYjlfZ2VuZXNpc19idG4sIDQsICAxLCAgMiwgIDEsICAxIH0sCgl7IE5VTEwsCQkJCQkgTlVMTCwJCSAgMCwgIDAsICAwLCAgMCwgIDAgfSwKCXsgIkdlbmVzaXMgNSBwYWQiLAkJCSBkYjlfZ2VuZXNpc19idG4sIDYsICAxLCAgMiwgIDEsICAxIH0sCgl7ICJHZW5lc2lzIDYgcGFkIiwJCQkgZGI5X2dlbmVzaXNfYnRuLCA4LCAgMSwgIDIsICAxLCAgMSB9LAoJeyAiU2F0dXJuIHBhZCIsCQkJCSBkYjlfY2QzMl9idG4sCSAgOSwgIDYsICA3LCAgMCwgIDEgfSwKCXsgIk11bHRpc3lzdGVtICgwLjguMC4yKSBqb3lzdGljayIsCSBkYjlfbXVsdGlfYnRuLAkgIDEsICAxLCAgMiwgIDEsICAxIH0sCgl7ICJNdWx0aXN5c3RlbSAoMC44LjAuMi1kdWFsKSBqb3lzdGljayIsIGRiOV9tdWx0aV9idG4sCSAgMSwgIDIsICAyLCAgMSwgIDEgfSwKCXsgIkFtaWdhIENELTMyIHBhZCIsCQkJIGRiOV9jZDMyX2J0biwJICA3LCAgMSwgIDIsICAxLCAgMSB9LAoJeyAiU2F0dXJuIGRwcCIsCQkJCSBkYjlfY2QzMl9idG4sCSAgOSwgIDYsICA3LCAgMCwgIDAgfSwKCXsgIlNhdHVybiBkcHAgZHVhbCIsCQkJIGRiOV9jZDMyX2J0biwJICA5LCAgMTIsIDcsICAwLCAgMCB9LAp9OwoKLyoKICogU2F0dXJuIGNvbnRyb2xsZXJzCiAqLwojZGVmaW5lIERCOV9TQVRVUk5fREVMQVkgMzAwCnN0YXRpYyBjb25zdCBpbnQgZGI5X3NhdHVybl9ieXRlW10gPSB7IDEsIDEsIDEsIDIsIDIsIDIsIDIsIDIsIDEgfTsKc3RhdGljIGNvbnN0IHVuc2lnbmVkIGNoYXIgZGI5X3NhdHVybl9tYXNrW10gPSB7IDB4MDQsIDB4MDEsIDB4MDIsIDB4NDAsIDB4MjAsIDB4MTAsIDB4MDgsIDB4ODAsIDB4MDggfTsKCi8qCiAqIGRiOV9zYXR1cm5fd3JpdGVfc3ViKCkgd3JpdGVzIDIgYml0IGRhdGEuCiAqLwpzdGF0aWMgdm9pZCBkYjlfc2F0dXJuX3dyaXRlX3N1YihzdHJ1Y3QgcGFycG9ydCAqcG9ydCwgaW50IHR5cGUsIHVuc2lnbmVkIGNoYXIgZGF0YSwgaW50IHBvd2VyZWQsIGludCBwd3Jfc3ViKQp7Cgl1bnNpZ25lZCBjaGFyIGM7CgoJc3dpdGNoICh0eXBlKSB7CgljYXNlIDE6IC8qIERQUDEgKi8KCQljID0gMHg4MCB8IDB4MzAgfCAocG93ZXJlZCA/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+cG9ydDsKCWludCBlcnI7CgoJZXJyID0gZG93bl9pbnRlcnJ1cHRpYmxlKCZkYjktPnNlbSk7CglpZiAoZXJyKQoJCXJldHVybiBlcnI7CgoJaWYgKCFkYjktPnVzZWQrKykgewoJCXBhcnBvcnRfY2xhaW0oZGI5LT5wZCk7CgkJcGFycG9ydF93cml0ZV9kYXRhKHBvcnQsIDB4ZmYpOwoJCWlmIChkYjlfbW9kZXNbZGI5LT5tb2RlXS5yZXZlcnNlKSB7CgkJCXBhcnBvcnRfZGF0YV9yZXZlcnNlKHBvcnQpOwoJCQlwYXJwb3J0X3dyaXRlX2NvbnRyb2wocG9ydCwgREI5X05PUk1BTCk7CgkJfQoJCW1vZF90aW1lcigmZGI5LT50aW1lciwgamlmZmllcyArIERCOV9SRUZSRVNIX1RJTUUpOwoJfQoKCXVwKCZkYjktPnNlbSk7CglyZXR1cm4gMDsKfQoKc3RhdGljIHZvaWQgZGI5X2Nsb3NlKHN0cnVjdCBpbnB1dF9kZXYgKmRldikKewoJc3RydWN0IGRiOSAqZGI5ID0gZGV2LT5wcml2YXRlOwoJc3RydWN0IHBhcnBvcnQgKnBvcnQgPSBkYjktPnBkLT5wb3J0OwoKCWRvd24oJmRiOS0+c2VtKTsKCWlmICghLS1kYjktPnVzZWQpIHsKCQlkZWxfdGltZXJfc3luYygmZGI5LT50aW1lcik7CgkJcGFycG9ydF93cml0ZV9jb250cm9sKHBvcnQsIDB4MDApOwoJCXBhcnBvcnRfZGF0YV9mb3J3YXJkKHBvcnQpOwoJCXBhcnBvcnRfcmVsZWFzZShkYjktPnBkKTsKCX0KCXVwKCZkYjktPnNlbSk7Cn0KCnN0YXRpYyBzdHJ1Y3QgZGI5IF9faW5pdCAqZGI5X3Byb2JlKGludCBwYXJwb3J0LCBpbnQgbW9kZSkKewoJc3RydWN0IGRiOSAqZGI5OwoJY29uc3Qgc3RydWN0IGRiOV9tb2RlX2RhdGEgKmRiOV9tb2RlOwoJc3RydWN0IHBhcnBvcnQgKnBwOwoJc3RydWN0IHBhcmRldmljZSAqcGQ7CglzdHJ1Y3QgaW5wdXRfZGV2ICppbnB1dF9kZXY7CglpbnQgaSwgajsKCWludCBlcnI7CgoJaWYgKG1vZGUgPCAxIHx8IG1vZGUgPj0gREI5X01BWF9QQUQgfHwgIWRiOV9tb2Rlc1ttb2RlXS5uX2J1dHRvbnMpIHsKCQlwcmludGsoS0VSTl9FUlIgImRiOS5jOiBCYWQgZGV2aWNlIHR5cGUgJWRcbiIsIG1vZGUpOwoJCWVyciA9IC1FSU5WQUw7CgkJZ290byBlcnJfb3V0OwoJfQoKCWRiOV9tb2RlID0gJmRiOV9tb2Rlc1ttb2RlXTsKCglwcCA9IHBhcnBvcnRfZmluZF9udW1iZXIocGFycG9ydCk7CglpZiAoIXBwKSB7CgkJcHJpbnRrKEtFUk5fRVJSICJkYjkuYzogbm8gc3VjaCBwYXJwb3J0XG4iKTsKCQllcnIgPSAtRU5PREVWOwoJCWdvdG8gZXJyX291dDsKCX0KCglpZiAoZGI5X21vZGVbbW9kZV0uYmlkaXJlY3Rpb25hbCAmJiAhKHBwLT5tb2RlcyAmIFBBUlBPUlRfTU9ERV9UUklTVEFURSkpIHsKCQlwcmludGsoS0VSTl9FUlIgImRiOS5jOiBzcGVjaWZpZWQgcGFycG9ydCBpcyBub3QgYmlkaXJlY3Rpb25hbFxuIik7CgkJZXJyID0gLUVJTlZBTDsKCQlnb3RvIGVycl9wdXRfcHA7Cgl9CgoJcGQgPSBwYXJwb3J0X3JlZ2lzdGVyX2RldmljZShwcCwgImRiOSIsIE5VTEwsIE5VTEwsIE5VTEwsIFBBUlBPUlRfREVWX0VYQ0wsIE5VTEwpOwoJaWYgKCFwZCkgewoJCXByaW50ayhLRVJOX0VSUiAiZGI5LmM6IHBhcnBvcnQgYnVzeSBhbHJlYWR5IC0gbHAubyBsb2FkZWQ/XG4iKTsKCQllcnIgPSAtRUJVU1k7CgkJZ290byBlcnJfcHV0X3BwOwoJfQoKCWRiOSA9IGt6YWxsb2Moc2l6ZW9mKHN0cnVjdCBkYjkpLCBHRlBfS0VSTkVMKTsKCWlmICghZGI5KSB7CgkJcHJpbnRrKEtFUk5fRVJSICJkYjkuYzogTm90IGVub3VnaCBtZW1vcnlcbiIpOwoJCWVyciA9IC1FTk9NRU07CgkJZ290byBlcnJfdW5yZWdfcGFyZGV2OwoJfQoKCWluaXRfTVVURVgoJmRiOS0+c2VtKTsKCWRiOS0+cGQgPSBwZDsKCWRiOS0+bW9kZSA9IG1vZGU7Cglpbml0X3RpbWVyKCZkYjktPnRpbWVyKTsKCWRiOS0+dGltZXIuZGF0YSA9IChsb25nKSBkYjk7CglkYjktPnRpbWVyLmZ1bmN0aW9uID0gZGI5X3RpbWVyOwoKCWZvciAoaSA9IDA7IGkgPCAobWluKGRiOV9tb2RlLT5uX3BhZHMsIERCOV9NQVhfREVWSUNFUykpOyBpKyspIHsKCgkJZGI5LT5kZXZbaV0gPSBpbnB1dF9kZXYgPSBpbnB1dF9hbGxvY2F0ZV9kZXZpY2UoKTsKCQlpZiAoIWlucHV0X2RldikgewoJCQlwcmludGsoS0VSTl9FUlIgImRiOS5jOiBOb3QgZW5vdWdoIG1lbW9yeSBmb3IgaW5wdXQgZGV2aWNlXG4iKTsKCQkJZXJyID0gLUVOT01FTTsKCQkJZ290byBlcnJfdW5yZWdfZGV2czsKCQl9CgoJCXNwcmludGYoZGI5LT5waHlzW2ldLCAiJXMvaW5wdXQlZCIsIGRiOS0+cGQtPnBvcnQtPm5hbWUsIGkpOwoKCQlpbnB1dF9kZXYtPm5hbWUgPSBkYjlfbW9kZS0+bmFtZTsKCQlpbnB1dF9kZXYtPnBoeXMgPSBkYjktPnBoeXNbaV07CgkJaW5wdXRfZGV2LT5pZC5idXN0eXBlID0gQlVTX1BBUlBPUlQ7CgkJaW5wdXRfZGV2LT5pZC52ZW5kb3IgPSAweDAwMDI7CgkJaW5wdXRfZGV2LT5pZC5wcm9kdWN0ID0gbW9kZTsKCQlpbnB1dF9kZXYtPmlkLnZlcnNpb24gPSAweDAxMDA7CgkJaW5wdXRfZGV2LT5wcml2YXRlID0gZGI5OwoKCQlpbnB1dF9kZXYtPm9wZW4gPSBkYjlfb3BlbjsKCQlpbnB1dF9kZXYtPmNsb3NlID0gZGI5X2Nsb3NlOwoKCQlpbnB1dF9kZXYtPmV2Yml0WzBdID0gQklUKEVWX0tFWSkgfCBCSVQoRVZfQUJTKTsKCQlmb3IgKGogPSAwOyBqIDwgZGI5X21vZGUtPm5fYnV0dG9uczsgaisrKQoJCQlzZXRfYml0KGRiOV9tb2RlLT5idXR0b25zW2pdLCBpbnB1dF9kZXYtPmtleWJpdCk7CgkJZm9yIChqID0gMDsgaiA8IGRiOV9tb2RlLT5uX2F4aXM7IGorKykgewoJCQlpZiAoaiA8IDIpCgkJCQlpbnB1dF9zZXRfYWJzX3BhcmFtcyhpbnB1dF9kZXYsIGRiOV9hYnNbal0sIC0xLCAxLCAwLCAwKTsKCQkJZWxzZQoJCQkJaW5wdXRfc2V0X2Fic19wYXJhbXMoaW5wdXRfZGV2LCBkYjlfYWJzW2pdLCAxLCAyNTUsIDAsIDApOwoJCX0KCgkJZXJyID0gaW5wdXRfcmVnaXN0ZXJfZGV2aWNlKGlucHV0X2Rldik7CgkJaWYgKGVycikKCQkJZ290byBlcnJfZnJlZV9kZXY7Cgl9CgoJcGFycG9ydF9wdXRfcG9ydChwcCk7CglyZXR1cm4gZGI5OwoKIGVycl9mcmVlX2RldjoKCWlucHV0X2ZyZWVfZGV2aWNlKGRiOS0+ZGV2W2ldKTsKIGVycl91bnJlZ19kZXZzOgoJd2hpbGUgKC0taSA+PSAwKQoJCWlucHV0X3VucmVnaXN0ZXJfZGV2aWNlKGRiOS0+ZGV2W2ldKTsKCWtmcmVlKGRiOSk7CiBlcnJfdW5yZWdfcGFyZGV2OgoJcGFycG9ydF91bnJlZ2lzdGVyX2RldmljZShwZCk7CiBlcnJfcHV0X3BwOgoJcGFycG9ydF9wdXRfcG9ydChwcCk7CiBlcnJfb3V0OgoJcmV0dXJuIEVSUl9QVFIoZXJyKTsKfQoKc3RhdGljIHZvaWQgZGI5X3JlbW92ZShzdHJ1Y3QgZGI5ICpkYjkpCnsKCWludCBpOwoKCWZvciAoaSA9IDA7IGkgPCBtaW4oZGI5X21vZGVzW2RiOS0+bW9kZV0ubl9wYWRzLCBEQjlfTUFYX0RFVklDRVMpOyBpKyspCgkJaW5wdXRfdW5yZWdpc3Rlcl9kZXZpY2UoZGI5LT5kZXZbaV0pOwoJcGFycG9ydF91bnJlZ2lzdGVyX2RldmljZShkYjktPnBkKTsKCWtmcmVlKGRiOSk7Cn0KCnN0YXRpYyBpbnQgX19pbml0IGRiOV9pbml0KHZvaWQpCnsKCWludCBpOwoJaW50IGhhdmVfZGV2ID0gMDsKCWludCBlcnIgPSAwOwoKCWZvciAoaSA9IDA7IGkgPCBEQjlfTUFYX1BPUlRTOyBpKyspIHsKCQlpZiAoZGI5W2ldLm5hcmdzID09IDAgfHwgZGI5W2ldLmFyZ3NbREI5X0FSR19QQVJQT1JUXSA8IDApCgkJCWNvbnRpbnVlOwoKCQlpZiAoZGI5W2ldLm5hcmdzIDwgMikgewoJCQlwcmludGsoS0VSTl9FUlIgImRiOS5jOiBEZXZpY2UgdHlwZSBtdXN0IGJlIHNwZWNpZmllZC5cbiIpOwoJCQllcnIgPSAtRUlOVkFMOwoJCQlicmVhazsKCQl9CgoJCWRiOV9iYXNlW2ldID0gZGI5X3Byb2JlKGRiOVtpXS5hcmdzW0RCOV9BUkdfUEFSUE9SVF0sCgkJCQkJZGI5W2ldLmFyZ3NbREI5X0FSR19NT0RFXSk7CgkJaWYgKElTX0VSUihkYjlfYmFzZVtpXSkpIHsKCQkJZXJyID0gUFRSX0VSUihkYjlfYmFzZVtpXSk7CgkJCWJyZWFrOwoJCX0KCgkJaGF2ZV9kZXYgPSAxOwoJfQoKCWlmIChlcnIpIHsKCQl3aGlsZSAoLS1pID49IDApCgkJCWlmIChkYjlfYmFzZVtpXSkKCQkJCWRiOV9yZW1vdmUoZGI5X2Jhc2VbaV0pOwoJCXJldHVybiBlcnI7Cgl9CgoJcmV0dXJuIGhhdmVfZGV2ID8gMCA6IC1FTk9ERVY7Cn0KCnN0YXRpYyB2b2lkIF9fZXhpdCBkYjlfZXhpdCh2b2lkKQp7CglpbnQgaTsKCglmb3IgKGkgPSAwOyBpIDwgREI5X01BWF9QT1JUUzsgaSsrKQoJCWlmIChkYjlfYmFzZVtpXSkKCQkJZGI5X3JlbW92ZShkYjlfYmFzZVtpXSk7Cn0KCm1vZHVsZV9pbml0KGRiOV9pbml0KTsKbW9kdWxlX2V4aXQoZGI5X2V4aXQpOwo=