LyoKICogJElkOiBkYjkuYyx2IDEuMTMgMjAwMi8wNC8wNyAyMDoxMzozNyB2b2p0ZWNoIEV4cCAkCiAqCiAqICBDb3B5cmlnaHQgKGMpIDE5OTktMjAwMSBWb2p0ZWNoIFBhdmxpawogKgogKiAgQmFzZWQgb24gdGhlIHdvcmsgb2Y6CiAqCUFuZHJlZSBCb3JybWFubgkJTWF0cyBTavZ2YWxsCiAqLwoKLyoKICogQXRhcmksIEFtc3RyYWQsIENvbW1vZG9yZSwgQW1pZ2EsIFNlZ2EsIGV0Yy4gam95c3RpY2sgZHJpdmVyIGZvciBMaW51eAogKi8KCi8qCiAqIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5CiAqIGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5CiAqIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlciB2ZXJzaW9uIDIgb2YgdGhlIExpY2Vuc2UsIG9yCiAqIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlCiAqIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIGFsb25nIHdpdGggdGhpcyBwcm9ncmFtOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDU5IFRlbXBsZSBQbGFjZSwgU3VpdGUgMzMwLCBCb3N0b24sIE1BIDAyMTExLTEzMDcgVVNBCiAqCiAqIFNob3VsZCB5b3UgbmVlZCB0byBjb250YWN0IG1lLCB0aGUgYXV0aG9yLCB5b3UgY2FuIGRvIHNvIGVpdGhlciBieQogKiBlLW1haWwgLSBtYWlsIHlvdXIgbWVzc2FnZSB0byA8dm9qdGVjaEB1Y3cuY3o+LCBvciBieSBwYXBlciBtYWlsOgogKiBWb2p0ZWNoIFBhdmxpaywgU2ltdW5rb3ZhIDE1OTQsIFByYWd1ZSA4LCAxODIgMDAgQ3plY2ggUmVwdWJsaWMKICovCgojaW5jbHVkZSA8bGludXgva2VybmVsLmg+CiNpbmNsdWRlIDxsaW51eC9tb2R1bGUuaD4KI2luY2x1ZGUgPGxpbnV4L21vZHVsZXBhcmFtLmg+CiNpbmNsdWRlIDxsaW51eC9kZWxheS5oPgojaW5jbHVkZSA8bGludXgvaW5pdC5oPgojaW5jbHVkZSA8bGludXgvcGFycG9ydC5oPgojaW5jbHVkZSA8bGludXgvaW5wdXQuaD4KCk1PRFVMRV9BVVRIT1IoIlZvanRlY2ggUGF2bGlrIDx2b2p0ZWNoQHVjdy5jej4iKTsKTU9EVUxFX0RFU0NSSVBUSU9OKCJBdGFyaSwgQW1zdHJhZCwgQ29tbW9kb3JlLCBBbWlnYSwgU2VnYSwgZXRjLiBqb3lzdGljayBkcml2ZXIiKTsKTU9EVUxFX0xJQ0VOU0UoIkdQTCIpOwoKc3RydWN0IGRiOV9jb25maWcgewoJaW50IGFyZ3NbMl07CglpbnQgbmFyZ3M7Cn07CgojZGVmaW5lIERCOV9NQVhfUE9SVFMJCTMKc3RhdGljIHN0cnVjdCBkYjlfY29uZmlnIGRiOVtEQjlfTUFYX1BPUlRTXSBfX2luaXRkYXRhOwoKbW9kdWxlX3BhcmFtX2FycmF5X25hbWVkKGRldiwgZGI5WzBdLmFyZ3MsIGludCwgJmRiOVswXS5uYXJncywgMCk7Ck1PRFVMRV9QQVJNX0RFU0MoZGV2LCAiRGVzY3JpYmVzIGZpcnN0IGF0dGFjaGVkIGRldmljZSAoPHBhcnBvcnQjPiw8dHlwZT4pIik7Cm1vZHVsZV9wYXJhbV9hcnJheV9uYW1lZChkZXYyLCBkYjlbMV0uYXJncywgaW50LCAmZGI5WzBdLm5hcmdzLCAwKTsKTU9EVUxFX1BBUk1fREVTQyhkZXYyLCAiRGVzY3JpYmVzIHNlY29uZCBhdHRhY2hlZCBkZXZpY2UgKDxwYXJwb3J0Iz4sPHR5cGU+KSIpOwptb2R1bGVfcGFyYW1fYXJyYXlfbmFtZWQoZGV2MywgZGI5WzJdLmFyZ3MsIGludCwgJmRiOVsyXS5uYXJncywgMCk7Ck1PRFVMRV9QQVJNX0RFU0MoZGV2MywgIkRlc2NyaWJlcyB0aGlyZCBhdHRhY2hlZCBkZXZpY2UgKDxwYXJwb3J0Iz4sPHR5cGU+KSIpOwoKX19vYnNvbGV0ZV9zZXR1cCgiZGI5PSIpOwpfX29ic29sZXRlX3NldHVwKCJkYjlfMj0iKTsKX19vYnNvbGV0ZV9zZXR1cCgiZGI5XzM9Iik7CgojZGVmaW5lIERCOV9BUkdfUEFSUE9SVAkJMAojZGVmaW5lIERCOV9BUkdfTU9ERQkJMQoKI2RlZmluZSBEQjlfTVVMVElfU1RJQ0sJCTB4MDEKI2RlZmluZSBEQjlfTVVMVEkyX1NUSUNLCTB4MDIKI2RlZmluZSBEQjlfR0VORVNJU19QQUQJCTB4MDMKI2RlZmluZSBEQjlfR0VORVNJUzVfUEFECTB4MDUKI2RlZmluZSBEQjlfR0VORVNJUzZfUEFECTB4MDYKI2RlZmluZSBEQjlfU0FUVVJOX1BBRAkJMHgwNwojZGVmaW5lIERCOV9NVUxUSV8wODAyCQkweDA4CiNkZWZpbmUgREI5X01VTFRJXzA4MDJfMgkweDA5CiNkZWZpbmUgREI5X0NEMzJfUEFECQkweDBBCiNkZWZpbmUgREI5X1NBVFVSTl9EUFAJCTB4MEIKI2RlZmluZSBEQjlfU0FUVVJOX0RQUF8yCTB4MEMKI2RlZmluZSBEQjlfTUFYX1BBRAkJMHgwRAoKI2RlZmluZSBEQjlfVVAJCQkweDAxCiNkZWZpbmUgREI5X0RPV04JCTB4MDIKI2RlZmluZSBEQjlfTEVGVAkJMHgwNAojZGVmaW5lIERCOV9SSUdIVAkJMHgwOAojZGVmaW5lIERCOV9GSVJFMQkJMHgxMAojZGVmaW5lIERCOV9GSVJFMgkJMHgyMAojZGVmaW5lIERCOV9GSVJFMwkJMHg0MAojZGVmaW5lIERCOV9GSVJFNAkJMHg4MAoKI2RlZmluZSBEQjlfTk9STUFMCQkweDBhCiNkZWZpbmUgREI5X05PU0VMRUNUCQkweDA4CgojZGVmaW5lIERCOV9HRU5FU0lTNl9ERUxBWQkxNAojZGVmaW5lIERCOV9SRUZSRVNIX1RJTUUJSFovMTAwCgojZGVmaW5lIERCOV9NQVhfREVWSUNFUwkJMgoKc3RydWN0IGRiOV9tb2RlX2RhdGEgewoJY29uc3QgY2hhciAqbmFtZTsKCWNvbnN0IHNob3J0ICpidXR0b25zOwoJaW50IG5fYnV0dG9uczsKCWludCBuX3BhZHM7CglpbnQgbl9heGlzOwoJaW50IGJpZGlyZWN0aW9uYWw7CglpbnQgcmV2ZXJzZTsKfTsKCnN0cnVjdCBkYjkgewoJc3RydWN0IGlucHV0X2RldiAqZGV2W0RCOV9NQVhfREVWSUNFU107CglzdHJ1Y3QgdGltZXJfbGlzdCB0aW1lcjsKCXN0cnVjdCBwYXJkZXZpY2UgKnBkOwoJaW50IG1vZGU7CglpbnQgdXNlZDsKCXN0cnVjdCBzZW1hcGhvcmUgc2VtOwoJY2hhciBwaHlzW0RCOV9NQVhfREVWSUNFU11bMzJdOwp9OwoKc3RhdGljIHN0cnVjdCBkYjkgKmRiOV9iYXNlWzNdOwoKc3RhdGljIGNvbnN0IHNob3J0IGRiOV9tdWx0aV9idG5bXSA9IHsgQlROX1RSSUdHRVIsIEJUTl9USFVNQiB9OwpzdGF0aWMgY29uc3Qgc2hvcnQgZGI5X2dlbmVzaXNfYnRuW10gPSB7IEJUTl9TVEFSVCwgQlROX0EsIEJUTl9CLCBCVE5fQywgQlROX1gsIEJUTl9ZLCBCVE5fWiwgQlROX01PREUgfTsKc3RhdGljIGNvbnN0IHNob3J0IGRiOV9jZDMyX2J0bltdID0geyBCVE5fQSwgQlROX0IsIEJUTl9DLCBCVE5fWCwgQlROX1ksIEJUTl9aLCBCVE5fVEwsIEJUTl9UUiwgQlROX1NUQVJUIH07CnN0YXRpYyBjb25zdCBzaG9ydCBkYjlfYWJzW10gPSB7IEFCU19YLCBBQlNfWSwgQUJTX1JYLCBBQlNfUlksIEFCU19SWiwgQUJTX1osIEFCU19IQVQwWCwgQUJTX0hBVDBZLCBBQlNfSEFUMVgsIEFCU19IQVQxWSB9OwoKc3RhdGljIGNvbnN0IHN0cnVjdCBkYjlfbW9kZV9kYXRhIGRiOV9tb2Rlc1tdID0gewoJeyBOVUxMLAkJCQkJIE5VTEwsCQkgIDAsICAwLCAgMCwgIDAsICAwIH0sCgl7ICJNdWx0aXN5c3RlbSBqb3lzdGljayIsCQkgZGI5X211bHRpX2J0biwJICAxLCAgMSwgIDIsICAxLCAgMSB9LAoJeyAiTXVsdGlzeXN0ZW0gam95c3RpY2sgKDIgZmlyZSkiLAkgZGI5X211bHRpX2J0biwJICAyLCAgMSwgIDIsICAxLCAgMSB9LAoJeyAiR2VuZXNpcyBwYWQiLAkJCSBkYjlfZ2VuZXNpc19idG4sIDQsICAxLCAgMiwgIDEsICAxIH0sCgl7IE5VTEwsCQkJCQkgTlVMTCwJCSAgMCwgIDAsICAwLCAgMCwgIDAgfSwKCXsgIkdlbmVzaXMgNSBwYWQiLAkJCSBkYjlfZ2VuZXNpc19idG4sIDYsICAxLCAgMiwgIDEsICAxIH0sCgl7ICJHZW5lc2lzIDYgcGFkIiwJCQkgZGI5X2dlbmVzaXNfYnRuLCA4LCAgMSwgIDIsICAxLCAgMSB9LAoJeyAiU2F0dXJuIHBhZCIsCQkJCSBkYjlfY2QzMl9idG4sCSAgOSwgIDYsICA3LCAgMCwgIDEgfSwKCXsgIk11bHRpc3lzdGVtICgwLjguMC4yKSBqb3lzdGljayIsCSBkYjlfbXVsdGlfYnRuLAkgIDEsICAxLCAgMiwgIDEsICAxIH0sCgl7ICJNdWx0aXN5c3RlbSAoMC44LjAuMi1kdWFsKSBqb3lzdGljayIsIGRiOV9tdWx0aV9idG4sCSAgMSwgIDIsICAyLCAgMSwgIDEgfSwKCXsgIkFtaWdhIENELTMyIHBhZCIsCQkJIGRiOV9jZDMyX2J0biwJICA3LCAgMSwgIDIsICAxLCAgMSB9LAoJeyAiU2F0dXJuIGRwcCIsCQkJCSBkYjlfY2QzMl9idG4sCSAgOSwgIDYsICA3LCAgMCwgIDAgfSwKCXsgIlNhdHVybiBkcHAgZHVhbCIsCQkJIGRiOV9jZDMyX2J0biwJICA5LCAgMTIsIDcsICAwLCAgMCB9LAp9OwoKLyoKICogU2F0dXJuIGNvbnRyb2xsZXJzCiAqLwojZGVmaW5lIERCOV9TQVRVUk5fREVMQVkgMzAwCnN0YXRpYyBjb25zdCBpbnQgZGI5X3NhdHVybl9ieXRlW10gPSB7IDEsIDEsIDEsIDIsIDIsIDIsIDIsIDIsIDEgfTsKc3RhdGljIGNvbnN0IHVuc2lnbmVkIGNoYXIgZGI5X3NhdHVybl9tYXNrW10gPSB7IDB4MDQsIDB4MDEsIDB4MDIsIDB4NDAsIDB4MjAsIDB4MTAsIDB4MDgsIDB4ODAsIDB4MDggfTsKCi8qCiAqIGRiOV9zYXR1cm5fd3JpdGVfc3ViKCkgd3JpdGVzIDIgYml0IGRhdGEuCiAqLwpzdGF0aWMgdm9pZCBkYjlfc2F0dXJuX3dyaXRlX3N1YihzdHJ1Y3QgcGFycG9ydCAqcG9ydCwgaW50IHR5cGUsIHVuc2lnbmVkIGNoYXIgZGF0YSwgaW50IHBvd2VyZWQsIGludCBwd3Jfc3ViKQp7Cgl1bnNpZ25lZCBjaGFyIGM7CgoJc3dpdGNoICh0eXBlKSB7CgljYXNlIDE6IC8qIERQUDEgKi8KCQljID0gMHg4MCB8IDB4MzAgfCAocG93ZXJlZCA/IDB4MDggOiAwKSB8IChwd3Jfc3ViID8gMHgwNCA6IDApIHwgZGF0YTsKCQlwYXJwb3J0X3dyaXRlX2RhdGEocG9ydCwgYyk7CgkJYnJlYWs7CgljYXNlIDI6IC8qIERQUDIgKi8KCQljID0gMHg0MCB8IGRhdGEgPDwgNCB8IChwb3dlcmVkID8gMHgwOCA6IDApIHwgKHB3cl9zdWIgPyAweDA0IDogMCkgfCAweDAzOwoJCXBhcnBvcnRfd3JpdGVfZGF0YShwb3J0LCBjKTsKCQlicmVhazsKCWNhc2UgMDoJLyogREI5ICovCgkJYyA9ICgoKChkYXRhICYgMikgPyAyIDogMCkgfCAoKGRhdGEgJiAxKSA/IDQgOiAwKSkgXiAweDAyKSB8ICFwb3dlcmVkOwoJCXBhcnBvcnRfd3JpdGVfY29udHJvbChwb3J0LCBjKTsKCQlicmVhazsKCX0KfQoKLyoKICogZ2Nfc2F0dXJuX3JlYWRfc3ViKCkgcmVhZHMgNCBiaXQgZGF0YS4KICovCnN0YXRpYyB1bnNpZ25lZCBjaGFyIGRiOV9zYXR1cm5fcmVhZF9zdWIoc3RydWN0IHBhcnBvcnQgKnBvcnQsIGludCB0eXBlKQp7Cgl1bnNpZ25lZCBjaGFyIGRhdGE7CgoJaWYgKHR5cGUpIHsKCQkvKiBEUFAgKi8KCQlkYXRhID0gcGFycG9ydF9yZWFkX3N0YXR1cyhwb3J0KSBeIDB4ODA7CgkJcmV0dXJuIChkYXRhICYgMHg4MCA/IDEgOiAwKSB8IChkYXRhICYgMHg0MCA/IDIgOiAwKQoJCSAgICAgfCAoZGF0YSAmIDB4MjAgPyA0IDogMCkgfCAoZGF0YSAmIDB4MTAgPyA4IDogMCk7Cgl9IGVsc2UgewoJCS8qIERCOSAqLwoJCWRhdGEgPSBwYXJwb3J0X3JlYWRfZGF0YShwb3J0KSAmIDB4MGY7CgkJcmV0dXJuIChkYXRhICYgMHg4ID8gMSA6IDApIHwgKGRhdGEgJiAweDQgPyAyIDogMCkKCQkgICAgIHwgKGRhdGEgJiAweDIgPyA0IDogMCkgfCAoZGF0YSAmIDB4MSA/IDggOiAwKTsKCX0KfQoKLyoKICogZGI5X3NhdHVybl9yZWFkX2FuYWxvZygpIHNlbmRzIGNsb2NrIGFuZCByZWFkcyA4IGJpdCBkYXRhLgogKi8Kc3RhdGljIHVuc2lnbmVkIGNoYXIgZGI5X3NhdHVybl9yZWFkX2FuYWxvZyhzdHJ1Y3QgcGFycG9ydCAqcG9ydCwgaW50IHR5cGUsIGludCBwb3dlcmVkKQp7Cgl1bnNpZ25lZCBjaGFyIGRhdGE7CgoJZGI5X3NhdHVybl93cml0ZV9zdWIocG9ydCwgdHlwZSwgMCwgcG93ZXJlZCwgMCk7Cgl1ZGVsYXkoREI5X1NBVFVSTl9ERUxBWSk7CglkYXRhID0gZGI5X3NhdHVybl9yZWFkX3N1Yihwb3J0LCB0eXBlKSA8PCA0OwoJZGI5X3NhdHVybl93cml0ZV9zdWIocG9ydCwgdHlwZSwgMiwgcG93ZXJlZCwgMCk7Cgl1ZGVsYXkoREI5X1NBVFVSTl9ERUxBWSk7CglkYXRhIHw9IGRiOV9zYXR1cm5fcmVhZF9zdWIocG9ydCwgdHlwZSk7CglyZXR1cm4gZGF0YTsKfQoKLyoKICogZGI5X3NhdHVybl9yZWFkX3BhY2tldCgpIHJlYWRzIHdob2xlIHNhdHVybiBwYWNrZXQgYXQgY29ubmVjdG9yCiAqIGFuZCByZXR1cm5zIGRldmljZSBpZGVudGlmaWVyIGNvZGUuCiAqLwpzdGF0aWMgdW5zaWduZWQgY2hhciBkYjlfc2F0dXJuX3JlYWRfcGFja2V0KHN0cnVjdCBwYXJwb3J0ICpwb3J0LCB1bnNpZ25lZCBjaGFyICpkYXRhLCBpbnQgdHlwZSwgaW50IHBvd2VyZWQpCnsKCWludCBpLCBqOwoJdW5zaWduZWQgY2hhciB0bXA7CgoJZGI5X3NhdHVybl93cml0ZV9zdWIocG9ydCwgdHlwZSwgMywgcG93ZXJlZCwgMCk7CglkYXRhWzBdID0gZGI5X3NhdHVybl9yZWFkX3N1Yihwb3J0LCB0eXBlKTsKCXN3aXRjaCAoZGF0YVswXSAmIDB4MGYpIHsKCWNhc2UgMHhmOgoJCS8qIDExMTEgIG5vIHBhZCAqLwoJCXJldHVybiBkYXRhWzBdID0gMHhmZjsKCWNhc2UgMHg0OiBjYXNlIDB4NCB8IDB4ODoKCQkvKiA/MTAwIDogZGlnaXRhbCBjb250cm9sbGVyICovCgkJZGI5X3NhdHVybl93cml0ZV9zdWIocG9ydCwgdHlwZSwgMCwgcG93ZXJlZCwgMSk7CgkJZGF0YVsyXSA9IGRiOV9zYXR1cm5fcmVhZF9zdWIocG9ydCwgdHlwZSkgPDwgNDsKCQlkYjlfc2F0dXJuX3dyaXRlX3N1Yihwb3J0LCB0eXBlLCAyLCBwb3dlcmVkLCAxKTsKCQlkYXRhWzFdID0gZGI5X3NhdHVybl9yZWFkX3N1Yihwb3J0LCB0eXBlKSA8PCA0OwoJCWRiOV9zYXR1cm5fd3JpdGVfc3ViKHBvcnQsIHR5cGUsIDEsIHBvd2VyZWQsIDEpOwoJCWRhdGFbMV0gfD0gZGI5X3NhdHVybl9yZWFkX3N1Yihwb3J0LCB0eXBlKTsKCQlkYjlfc2F0dXJuX3dyaXRlX3N1Yihwb3J0LCB0eXBlLCAzLCBwb3dlcmVkLCAxKTsKCQkvKiBkYXRhWzJdIHw9IGRiOV9zYXR1cm5fcmVhZF9zdWIocG9ydCwgdHlwZSk7ICovCgkJZGF0YVsyXSB8PSBkYXRhWzBdOwoJCXJldHVybiBkYXRhWzBdID0gMHgwMjsKCWNhc2UgMHgxOgoJCS8qIDAwMDEgOiBhbmFsb2cgY29udHJvbGxlciBvciBtdWx0aXRhcCAqLwoJCWRiOV9zYXR1cm5fd3JpdGVfc3ViKHBvcnQsIHR5cGUsIDIsIHBvd2VyZWQsIDApOwoJCXVkZWxheShEQjlfU0FUVVJOX0RFTEFZKTsKCQlkYXRhWzBdID0gZGI5X3NhdHVybl9yZWFkX2FuYWxvZyhwb3J0LCB0eXBlLCBwb3dlcmVkKTsKCQlpZiAoZGF0YVswXSAhPSAweDQxKSB7CgkJCS8qIHJlYWQgYW5hbG9nIGNvbnRyb2xsZXIgKi8KCQkJZm9yIChpID0gMDsgaSA8IChkYXRhWzBdICYgMHgwZik7IGkrKykKCQkJCWRhdGFbaSArIDFdID0gZGI5X3NhdHVybl9yZWFkX2FuYWxvZyhwb3J0LCB0eXBlLCBwb3dlcmVkKTsKCQkJZGI5X3NhdHVybl93cml0ZV9zdWIocG9ydCwgdHlwZSwgMywgcG93ZXJlZCwgMCk7CgkJCXJldHVybiBkYXRhWzBdOwoJCX0gZWxzZSB7CgkJCS8qIHJlYWQgbXVsdGl0YXAgKi8KCQkJaWYgKGRiOV9zYXR1cm5fcmVhZF9hbmFsb2cocG9ydCwgdHlwZSwgcG93ZXJlZCkgIT0gMHg2MCkKCQkJCXJldHVybiBkYXRhWzBdID0gMHhmZjsKCQkJZm9yIChpID0gMDsgaSA8IDYwOyBpICs9IDEwKSB7CgkJCQlkYXRhW2ldID0gZGI5X3NhdHVybl9yZWFkX2FuYWxvZyhwb3J0LCB0eXBlLCBwb3dlcmVkKTsKCQkJCWlmIChkYXRhW2ldICE9IDB4ZmYpCgkJCQkJLyogcmVhZCBlYWNoIHBhZCAqLwoJCQkJCWZvciAoaiA9IDA7IGogPCAoZGF0YVtpXSAmIDB4MGYpOyBqKyspCgkJCQkJCWRhdGFbaSArIGogKyAxXSA9IGRiOV9zYXR1cm5fcmVhZF9hbmFsb2cocG9ydCwgdHlwZSwgcG93ZXJlZCk7CgkJCX0KCQkJZGI5X3NhdHVybl93cml0ZV9zdWIocG9ydCwgdHlwZSwgMywgcG93ZXJlZCwgMCk7CgkJCXJldHVybiAweDQxOwoJCX0KCWNhc2UgMHgwOgoJCS8qIDAwMDAgOiBtb3VzZSAqLwoJCWRiOV9zYXR1cm5fd3JpdGVfc3ViKHBvcnQsIHR5cGUsIDIsIHBvd2VyZWQsIDApOwoJCXVkZWxheShEQjlfU0FUVVJOX0RFTEFZKTsKCQl0bXAgPSBkYjlfc2F0dXJuX3JlYWRfYW5hbG9nKHBvcnQsIHR5cGUsIHBvd2VyZWQpOwoJCWlmICh0bXAgPT0gMHhmZikgewoJCQlmb3IgKGkgPSAwOyBpIDwgMzsgaSsrKQoJCQkJZGF0YVtpICsgMV0gPSBkYjlfc2F0dXJuX3JlYWRfYW5hbG9nKHBvcnQsIHR5cGUsIHBvd2VyZWQpOwoJCQlkYjlfc2F0dXJuX3dyaXRlX3N1Yihwb3J0LCB0eXBlLCAzLCBwb3dlcmVkLCAwKTsKCQkJcmV0dXJuIGRhdGFbMF0gPSAweGUzOwoJCX0KCWRlZmF1bHQ6CgkJcmV0dXJuIGRhdGFbMF07Cgl9Cn0KCi8qCiAqIGRiOV9zYXR1cm5fcmVwb3J0KCkgYW5hbHl6ZXMgcGFja2V0IGFuZCByZXBvcnRzLgogKi8Kc3RhdGljIGludCBkYjlfc2F0dXJuX3JlcG9ydCh1bnNpZ25lZCBjaGFyIGlkLCB1bnNpZ25lZCBjaGFyIGRhdGFbNjBdLCBzdHJ1Y3QgaW5wdXRfZGV2ICpkZXYsIGludCBuLCBpbnQgbWF4X3BhZHMpCnsKCWludCB0bXAsIGksIGo7CgoJdG1wID0gKGlkID09IDB4NDEpID8gNjAgOiAxMDsKCWZvciAoaiA9IDA7IChqIDwgdG1wKSAmJiAobiA8IG1heF9wYWRzKTsgaiArPSAxMCwgbisrKSB7CgkJc3dpdGNoIChkYXRhW2pdKSB7CgkJY2FzZSAweDE2OiAvKiBtdWx0aSBjb250cm9sbGVyIChhbmFsb2cgNCBheGlzKSAqLwoJCQlpbnB1dF9yZXBvcnRfYWJzKGRldiArIG4sIGRiOV9hYnNbNV0sIGRhdGFbaiArIDZdKTsKCQljYXNlIDB4MTU6IC8qIG1pc3Npb24gc3RpY2sgKGFuYWxvZyAzIGF4aXMpICovCgkJCWlucHV0X3JlcG9ydF9hYnMoZGV2ICsgbiwgZGI5X2Fic1szXSwgZGF0YVtqICsgNF0pOwoJCQlpbnB1dF9yZXBvcnRfYWJzKGRldiArIG4sIGRiOV9hYnNbNF0sIGRhdGFbaiArIDVdKTsKCQljYXNlIDB4MTM6IC8qIHJhY2luZyBjb250cm9sbGVyIChhbmFsb2cgMSBheGlzKSAqLwoJCQlpbnB1dF9yZXBvcnRfYWJzKGRldiArIG4sIGRiOV9hYnNbMl0sIGRhdGFbaiArIDNdKTsKCQljYXNlIDB4MzQ6IC8qIHNhdHVybiBrZXlib2FyZCAodWRsciBaWEMgQVNEIFFFIEVzYykgKi8KCQljYXNlIDB4MDI6IC8qIGRpZ2l0YWwgcGFkIChkaWdpdGFsIDIgYXhpcyArIGJ1dHRvbnMpICovCgkJCWlucHV0X3JlcG9ydF9hYnMoZGV2ICsgbiwgZGI5X2Fic1swXSwgIShkYXRhW2ogKyAxXSAmIDEyOCkgLSAhKGRhdGFbaiArIDFdICYgNjQpKTsKCQkJaW5wdXRfcmVwb3J0X2FicyhkZXYgKyBuLCBkYjlfYWJzWzFdLCAhKGRhdGFbaiArIDFdICYgMzIpIC0gIShkYXRhW2ogKyAxXSAmIDE2KSk7CgkJCWZvciAoaSA9IDA7IGkgPCA5OyBpKyspCgkJCQlpbnB1dF9yZXBvcnRfa2V5KGRldiArIG4sIGRiOV9jZDMyX2J0bltpXSwgfmRhdGFbaiArIGRiOV9zYXR1cm5fYnl0ZVtpXV0gJiBkYjlfc2F0dXJuX21hc2tbaV0pOwoJCQlicmVhazsKCQljYXNlIDB4MTk6IC8qIG1pc3Npb24gc3RpY2sgeDIgKGFuYWxvZyA2IGF4aXMgKyBidXR0b25zKSAqLwoJCQlpbnB1dF9yZXBvcnRfYWJzKGRldiArIG4sIGRiOV9hYnNbMF0sICEoZGF0YVtqICsgMV0gJiAxMjgpIC0gIShkYXRhW2ogKyAxXSAmIDY0KSk7CgkJCWlucHV0X3JlcG9ydF9hYnMoZGV2ICsgbiwgZGI5X2Fic1sxXSwgIShkYXRhW2ogKyAxXSAmIDMyKSAtICEoZGF0YVtqICsgMV0gJiAxNikpOwoJCQlmb3IgKGkgPSAwOyBpIDwgOTsgaSsrKQoJCQkJaW5wdXRfcmVwb3J0X2tleShkZXYgKyBuLCBkYjlfY2QzMl9idG5baV0sIH5kYXRhW2ogKyBkYjlfc2F0dXJuX2J5dGVbaV1dICYgZGI5X3NhdHVybl9tYXNrW2ldKTsKCQkJaW5wdXRfcmVwb3J0X2FicyhkZXYgKyBuLCBkYjlfYWJzWzJdLCBkYXRhW2ogKyAzXSk7CgkJCWlucHV0X3JlcG9ydF9hYnMoZGV2ICsgbiwgZGI5X2Fic1szXSwgZGF0YVtqICsgNF0pOwoJCQlpbnB1dF9yZXBvcnRfYWJzKGRldiArIG4sIGRiOV9hYnNbNF0sIGRhdGFbaiArIDVdKTsKCQkJLyoKCQkJaW5wdXRfcmVwb3J0X2FicyhkZXYgKyBuLCBkYjlfYWJzWzhdLCAoZGF0YVtqICsgNl0gJiAxMjggPyAwIDogMSkgLSAoZGF0YVtqICsgNl0gJiA2NCA/IDAgOiAxKSk7CgkJCWlucHV0X3JlcG9ydF9hYnMoZGV2ICsgbiwgZGI5X2Fic1s5XSwgKGRhdGFbaiArIDZdICYgMzIgPyAwIDogMSkgLSAoZGF0YVtqICsgNl0gJiAxNiA/IDAgOiAxKSk7CgkJCSovCgkJCWlucHV0X3JlcG9ydF9hYnMoZGV2ICsgbiwgZGI5X2Fic1s2XSwgZGF0YVtqICsgN10pOwoJCQlpbnB1dF9yZXBvcnRfYWJzKGRldiArIG4sIGRiOV9hYnNbN10sIGRhdGFbaiArIDhdKTsKCQkJaW5wdXRfcmVwb3J0X2FicyhkZXYgKyBuLCBkYjlfYWJzWzVdLCBkYXRhW2ogKyA5XSk7CgkJCWJyZWFrOwoJCWNhc2UgMHhkMzogLyogc2Fua3lvIGZmIChhbmFsb2cgMSBheGlzICsgc3RvcCBidG4pICovCgkJCWlucHV0X3JlcG9ydF9rZXkoZGV2ICsgbiwgQlROX0EsIGRhdGFbaiArIDNdICYgMHg4MCk7CgkJCWlucHV0X3JlcG9ydF9hYnMoZGV2ICsgbiwgZGI5X2Fic1syXSwgZGF0YVtqICsgM10gJiAweDdmKTsKCQkJYnJlYWs7CgkJY2FzZSAweGUzOiAvKiBzaHV0dGxlIG1vdXNlIChhbmFsb2cgMiBheGlzICsgYnV0dG9ucy4gc2lnbmVkIHZhbHVlKSAqLwoJCQlpbnB1dF9yZXBvcnRfa2V5KGRldiArIG4sIEJUTl9TVEFSVCwgZGF0YVtqICsgMV0gJiAweDA4KTsKCQkJaW5wdXRfcmVwb3J0X2tleShkZXYgKyBuLCBCVE5fQSwgZGF0YVtqICsgMV0gJiAweDA0KTsKCQkJaW5wdXRfcmVwb3J0X2tleShkZXYgKyBuLCBCVE5fQywgZGF0YVtqICsgMV0gJiAweDAyKTsKCQkJaW5wdXRfcmVwb3J0X2tleShkZXYgKyBuLCBCVE5fQiwgZGF0YVtqICsgMV0gJiAweDAxKTsKCQkJaW5wdXRfcmVwb3J0X2FicyhkZXYgKyBuLCBkYjlfYWJzWzJdLCBkYXRhW2ogKyAyXSBeIDB4ODApOwoJCQlpbnB1dF9yZXBvcnRfYWJzKGRldiArIG4sIGRiOV9hYnNbM10sICgweGZmLShkYXRhW2ogKyAzXSBeIDB4ODApKSsxKTsgLyogKi8KCQkJYnJlYWs7CgkJY2FzZSAweGZmOgoJCWRlZmF1bHQ6IC8qIG5vIHBhZCAqLwoJCQlpbnB1dF9yZXBvcnRfYWJzKGRldiArIG4sIGRiOV9hYnNbMF0sIDApOwoJCQlpbnB1dF9yZXBvcnRfYWJzKGRldiArIG4sIGRiOV9hYnNbMV0sIDApOwoJCQlmb3IgKGkgPSAwOyBpIDwgOTsgaSsrKQoJCQkJaW5wdXRfcmVwb3J0X2tleShkZXYgKyBuLCBkYjlfY2QzMl9idG5baV0sIDApOwoJCQlicmVhazsKCQl9Cgl9CglyZXR1cm4gbjsKfQoKc3RhdGljIGludCBkYjlfc2F0dXJuKGludCBtb2RlLCBzdHJ1Y3QgcGFycG9ydCAqcG9ydCwgc3RydWN0IGlucHV0X2RldiAqZGV2KQp7Cgl1bnNpZ25lZCBjaGFyIGlkLCBkYXRhWzYwXTsKCWludCB0eXBlLCBuLCBtYXhfcGFkczsKCWludCB0bXAsIGk7CgoJc3dpdGNoIChtb2RlKSB7CgljYXNlIERCOV9TQVRVUk5fUEFEOgoJCXR5cGUgPSAwOwoJCW4gPSAxOwoJCWJyZWFrOwoJY2FzZSBEQjlfU0FUVVJOX0RQUDoKCQl0eXBlID0gMTsKCQluID0gMTsKCQlicmVhazsKCWNhc2UgREI5X1NBVFVSTl9EUFBfMjoKCQl0eXBlID0gMTsKCQluID0gMjsKCQlicmVhazsKCWRlZmF1bHQ6CgkJcmV0dXJuIC0xOwoJfQoJbWF4X3BhZHMgPSBtaW4oZGI5X21vZGVzW21vZGVdLm5fcGFkcywgREI5X01BWF9ERVZJQ0VTKTsKCWZvciAodG1wID0gMCwgaSA9IDA7IGkgPCBuOyBpKyspIHsKCQlpZCA9IGRiOV9zYXR1cm5fcmVhZF9wYWNrZXQocG9ydCwgZGF0YSwgdHlwZSArIGksIDEpOwoJCXRtcCA9IGRiOV9zYXR1cm5fcmVwb3J0KGlkLCBkYXRhLCBkZXYsIHRtcCwgbWF4X3BhZHMpOwoJfQoJcmV0dXJuIDA7Cn0KCnN0YXRpYyB2b2lkIGRiOV90aW1lcih1bnNpZ25lZCBsb25nIHByaXZhdGUpCnsKCXN0cnVjdCBkYjkgKmRiOSA9ICh2b2lkICopIHByaXZhdGU7CglzdHJ1Y3QgcGFycG9ydCAqcG9ydCA9IGRiOS0+cGQtPnBvcnQ7CglzdHJ1Y3QgaW5wdXRfZGV2ICpkZXYgPSBkYjktPmRldlswXTsKCXN0cnVjdCBpbnB1dF9kZXYgKmRldjIgPSBkYjktPmRldlsxXTsKCWludCBkYXRhLCBpOwoKCXN3aXRjaCAoZGI5LT5tb2RlKSB7CgkJY2FzZSBEQjlfTVVMVElfMDgwMl8yOgoKCQkJZGF0YSA9IHBhcnBvcnRfcmVhZF9kYXRhKHBvcnQpID4+IDM7CgoJCQlpbnB1dF9yZXBvcnRfYWJzKGRldjIsIEFCU19YLCAoZGF0YSAmIERCOV9SSUdIVCA/IDAgOiAxKSAtIChkYXRhICYgREI5X0xFRlQgPyAwIDogMSkpOwoJCQlpbnB1dF9yZXBvcnRfYWJzKGRldjIsIEFCU19ZLCAoZGF0YSAmIERCOV9ET1dOICA/IDAgOiAxKSAtIChkYXRhICYgREI5X1VQICAgPyAwIDogMSkpOwoJCQlpbnB1dF9yZXBvcnRfa2V5KGRldjIsIEJUTl9UUklHR0VSLCB+ZGF0YSAmIERCOV9GSVJFMSk7CgoJCWNhc2UgREI5X01VTFRJXzA4MDI6CgoJCQlkYXRhID0gcGFycG9ydF9yZWFkX3N0YXR1cyhwb3J0KSA+PiAzOwoKCQkJaW5wdXRfcmVwb3J0X2FicyhkZXYsIEFCU19YLCAoZGF0YSAmIERCOV9SSUdIVCA/IDAgOiAxKSAtIChkYXRhICYgREI5X0xFRlQgPyAwIDogMSkpOwoJCQlpbnB1dF9yZXBvcnRfYWJzKGRldiwgQUJTX1ksIChkYXRhICYgREI5X0RPV04gID8gMCA6IDEpIC0gKGRhdGEgJiBEQjlfVVAgICA/IDAgOiAxKSk7CgkJCWlucHV0X3JlcG9ydF9rZXkoZGV2LCBCVE5fVFJJR0dFUiwgZGF0YSAmIERCOV9GSVJFMSk7CgkJCWJyZWFrOwoKCQljYXNlIERCOV9NVUxUSV9TVElDSzoKCgkJCWRhdGEgPSBwYXJwb3J0X3JlYWRfZGF0YShwb3J0KTsKCgkJCWlucHV0X3JlcG9ydF9hYnMoZGV2LCBBQlNfWCwgKGRhdGEgJiBEQjlfUklHSFQgPyAwIDogMSkgLSAoZGF0YSAmIERCOV9MRUZUID8gMCA6IDEpKTsKCQkJaW5wdXRfcmVwb3J0X2FicyhkZXYsIEFCU19ZLCAoZGF0YSAmIERCOV9ET1dOICA/IDAgOiAxKSAtIChkYXRhICYgREI5X1VQICAgPyAwIDogMSkpOwoJCQlpbnB1dF9yZXBvcnRfa2V5KGRldiwgQlROX1RSSUdHRVIsIH5kYXRhICYgREI5X0ZJUkUxKTsKCQkJYnJlYWs7CgoJCWNhc2UgREI5X01VTFRJMl9TVElDSzoKCgkJCWRhdGEgPSBwYXJwb3J0X3JlYWRfZGF0YShwb3J0KTsKCgkJCWlucHV0X3JlcG9ydF9hYnMoZGV2LCBBQlNfWCwgKGRhdGEgJiBEQjlfUklHSFQgPyAwIDogMSkgLSAoZGF0YSAmIERCOV9MRUZUID8gMCA6IDEpKTsKCQkJaW5wdXRfcmVwb3J0X2FicyhkZXYsIEFCU19ZLCAoZGF0YSAmIERCOV9ET1dOICA/IDAgOiAxKSAtIChkYXRhICYgREI5X1VQICAgPyAwIDogMSkpOwoJCQlpbnB1dF9yZXBvcnRfa2V5KGRldiwgQlROX1RSSUdHRVIsIH5kYXRhICYgREI5X0ZJUkUxKTsKCQkJaW5wdXRfcmVwb3J0X2tleShkZXYsIEJUTl9USFVNQiwgICB+ZGF0YSAmIERCOV9GSVJFMik7CgkJCWJyZWFrOwoKCQljYXNlIERCOV9HRU5FU0lTX1BBRDoKCgkJCXBhcnBvcnRfd3JpdGVfY29udHJvbChwb3J0LCBEQjlfTk9TRUxFQ1QpOwoJCQlkYXRhID0gcGFycG9ydF9yZWFkX2RhdGEocG9ydCk7CgoJCQlpbnB1dF9yZXBvcnRfYWJzKGRldiwgQUJTX1gsIChkYXRhICYgREI5X1JJR0hUID8gMCA6IDEpIC0gKGRhdGEgJiBEQjlfTEVGVCA/IDAgOiAxKSk7CgkJCWlucHV0X3JlcG9ydF9hYnMoZGV2LCBBQlNfWSwgKGRhdGEgJiBEQjlfRE9XTiAgPyAwIDogMSkgLSAoZGF0YSAmIERCOV9VUCAgID8gMCA6IDEpKTsKCQkJaW5wdXRfcmVwb3J0X2tleShkZXYsIEJUTl9CLCB+ZGF0YSAmIERCOV9GSVJFMSk7CgkJCWlucHV0X3JlcG9ydF9rZXkoZGV2LCBCVE5fQywgfmRhdGEgJiBEQjlfRklSRTIpOwoKCQkJcGFycG9ydF93cml0ZV9jb250cm9sKHBvcnQsIERCOV9OT1JNQUwpOwoJCQlkYXRhID0gcGFycG9ydF9yZWFkX2RhdGEocG9ydCk7CgoJCQlpbnB1dF9yZXBvcnRfa2V5KGRldiwgQlROX0EsICAgICB+ZGF0YSAmIERCOV9GSVJFMSk7CgkJCWlucHV0X3JlcG9ydF9rZXkoZGV2LCBCVE5fU1RBUlQsIH5kYXRhICYgREI5X0ZJUkUyKTsKCQkJYnJlYWs7CgoJCWNhc2UgREI5X0dFTkVTSVM1X1BBRDoKCgkJCXBhcnBvcnRfd3JpdGVfY29udHJvbChwb3J0LCBEQjlfTk9TRUxFQ1QpOwoJCQlkYXRhID0gcGFycG9ydF9yZWFkX2RhdGEocG9ydCk7CgoJCQlpbnB1dF9yZXBvcnRfYWJzKGRldiwgQUJTX1gsIChkYXRhICYgREI5X1JJR0hUID8gMCA6IDEpIC0gKGRhdGEgJiBEQjlfTEVGVCA/IDAgOiAxKSk7CgkJCWlucHV0X3JlcG9ydF9hYnMoZGV2LCBBQlNfWSwgKGRhdGEgJiBEQjlfRE9XTiAgPyAwIDogMSkgLSAoZGF0YSAmIERCOV9VUCAgID8gMCA6IDEpKTsKCQkJaW5wdXRfcmVwb3J0X2tleShkZXYsIEJUTl9CLCB+ZGF0YSAmIERCOV9GSVJFMSk7CgkJCWlucHV0X3JlcG9ydF9rZXkoZGV2LCBCVE5fQywgfmRhdGEgJiBEQjlfRklSRTIpOwoKCQkJcGFycG9ydF93cml0ZV9jb250cm9sKHBvcnQsIERCOV9OT1JNQUwpOwoJCQlkYXRhID0gcGFycG9ydF9yZWFkX2RhdGEocG9ydCk7CgoJCQlpbnB1dF9yZXBvcnRfa2V5KGRldiwgQlROX0EsICAgICB+ZGF0YSAmIERCOV9GSVJFMSk7CgkJCWlucHV0X3JlcG9ydF9rZXkoZGV2LCBCVE5fWCwgICAgIH5kYXRhICYgREI5X0ZJUkUyKTsKCQkJaW5wdXRfcmVwb3J0X2tleShkZXYsIEJUTl9ZLCAgICAgfmRhdGEgJiBEQjlfTEVGVCk7CgkJCWlucHV0X3JlcG9ydF9rZXkoZGV2LCBCVE5fU1RBUlQsIH5kYXRhICYgREI5X1JJR0hUKTsKCQkJYnJlYWs7CgoJCWNhc2UgREI5X0dFTkVTSVM2X1BBRDoKCgkJCXBhcnBvcnRfd3JpdGVfY29udHJvbChwb3J0LCBEQjlfTk9TRUxFQ1QpOyAvKiAxICovCgkJCXVkZWxheShEQjlfR0VORVNJUzZfREVMQVkpOwoJCQlkYXRhID0gcGFycG9ydF9yZWFkX2RhdGEocG9ydCk7CgoJCQlpbnB1dF9yZXBvcnRfYWJzKGRldiwgQUJTX1gsIChkYXRhICYgREI5X1JJR0hUID8gMCA6IDEpIC0gKGRhdGEgJiBEQjlfTEVGVCA/IDAgOiAxKSk7CgkJCWlucHV0X3JlcG9ydF9hYnMoZGV2LCBBQlNfWSwgKGRhdGEgJiBEQjlfRE9XTiAgPyAwIDogMSkgLSAoZGF0YSAmIERCOV9VUCAgID8gMCA6IDEpKTsKCQkJaW5wdXRfcmVwb3J0X2tleShkZXYsIEJUTl9CLCB+ZGF0YSAmIERCOV9GSVJFMSk7CgkJCWlucHV0X3JlcG9ydF9rZXkoZGV2LCBCVE5fQywgfmRhdGEgJiBEQjlfRklSRTIpOwoKCQkJcGFycG9ydF93cml0ZV9jb250cm9sKHBvcnQsIERCOV9OT1JNQUwpOwoJCQl1ZGVsYXkoREI5X0dFTkVTSVM2X0RFTEFZKTsKCQkJZGF0YSA9IHBhcnBvcnRfcmVhZF9kYXRhKHBvcnQpOwoKCQkJaW5wdXRfcmVwb3J0X2tleShkZXYsIEJUTl9BLCB+ZGF0YSAmIERCOV9GSVJFMSk7CgkJCWlucHV0X3JlcG9ydF9rZXkoZGV2LCBCVE5fU1RBUlQsIH5kYXRhICYgREI5X0ZJUkUyKTsKCgkJCXBhcnBvcnRfd3JpdGVfY29udHJvbChwb3J0LCBEQjlfTk9TRUxFQ1QpOyAvKiAyICovCgkJCXVkZWxheShEQjlfR0VORVNJUzZfREVMQVkpOwoJCQlwYXJwb3J0X3dyaXRlX2NvbnRyb2wocG9ydCwgREI5X05PUk1BTCk7CgkJCXVkZWxheShEQjlfR0VORVNJUzZfREVMQVkpOwoJCQlwYXJwb3J0X3dyaXRlX2NvbnRyb2wocG9ydCwgREI5X05PU0VMRUNUKTsgLyogMyAqLwoJCQl1ZGVsYXkoREI5X0dFTkVTSVM2X0RFTEFZKTsKCQkJZGF0YT1wYXJwb3J0X3JlYWRfZGF0YShwb3J0KTsKCgkJCWlucHV0X3JlcG9ydF9rZXkoZGV2LCBCVE5fWCwgICAgfmRhdGEgJiBEQjlfTEVGVCk7CgkJCWlucHV0X3JlcG9ydF9rZXkoZGV2LCBCVE5fWSwgICAgfmRhdGEgJiBEQjlfRE9XTik7CgkJCWlucHV0X3JlcG9ydF9rZXkoZGV2LCBCVE5fWiwgICAgfmRhdGEgJiBEQjlfVVApOwoJCQlpbnB1dF9yZXBvcnRfa2V5KGRldiwgQlROX01PREUsIH5kYXRhICYgREI5X1JJR0hUKTsKCgkJCXBhcnBvcnRfd3JpdGVfY29udHJvbChwb3J0LCBEQjlfTk9STUFMKTsKCQkJdWRlbGF5KERCOV9HRU5FU0lTNl9ERUxBWSk7CgkJCXBhcnBvcnRfd3JpdGVfY29udHJvbChwb3J0LCBEQjlfTk9TRUxFQ1QpOyAvKiA0ICovCgkJCXVkZWxheShEQjlfR0VORVNJUzZfREVMQVkpOwoJCQlwYXJwb3J0X3dyaXRlX2NvbnRyb2wocG9ydCwgREI5X05PUk1BTCk7CgkJCWJyZWFrOwoKCQljYXNlIERCOV9TQVRVUk5fUEFEOgoJCWNhc2UgREI5X1NBVFVSTl9EUFA6CgkJY2FzZSBEQjlfU0FUVVJOX0RQUF8yOgoKCQkJZGI5X3NhdHVybihkYjktPm1vZGUsIHBvcnQsIGRldik7CgkJCWJyZWFrOwoKCQljYXNlIERCOV9DRDMyX1BBRDoKCgkJCWRhdGEgPSBwYXJwb3J0X3JlYWRfZGF0YShwb3J0KTsKCgkJCWlucHV0X3JlcG9ydF9hYnMoZGV2LCBBQlNfWCwgKGRhdGEgJiBEQjlfUklHSFQgPyAwIDogMSkgLSAoZGF0YSAmIERCOV9MRUZUID8gMCA6IDEpKTsKCQkJaW5wdXRfcmVwb3J0X2FicyhkZXYsIEFCU19ZLCAoZGF0YSAmIERCOV9ET1dOICA/IDAgOiAxKSAtIChkYXRhICYgREI5X1VQICAgPyAwIDogMSkpOwoKCQkJcGFycG9ydF93cml0ZV9jb250cm9sKHBvcnQsIDB4MGEpOwoKCQkJZm9yIChpID0gMDsgaSA8IDc7IGkrKykgewoJCQkJZGF0YSA9IHBhcnBvcnRfcmVhZF9kYXRhKHBvcnQpOwoJCQkJcGFycG9ydF93cml0ZV9jb250cm9sKHBvcnQsIDB4MDIpOwoJCQkJcGFycG9ydF93cml0ZV9jb250cm9sKHBvcnQsIDB4MGEpOwoJCQkJaW5wdXRfcmVwb3J0X2tleShkZXYsIGRiOV9jZDMyX2J0bltpXSwgfmRhdGEgJiBEQjlfRklSRTIpOwoJCQl9CgoJCQlwYXJwb3J0X3dyaXRlX2NvbnRyb2wocG9ydCwgMHgwMCk7CgkJCWJyZWFrOwoJCX0KCglpbnB1dF9zeW5jKGRldik7CgoJbW9kX3RpbWVyKCZkYjktPnRpbWVyLCBqaWZmaWVzICsgREI5X1JFRlJFU0hfVElNRSk7Cn0KCnN0YXRpYyBpbnQgZGI5X29wZW4oc3RydWN0IGlucHV0X2RldiAqZGV2KQp7CglzdHJ1Y3QgZGI5ICpkYjkgPSBkZXYtPnByaXZhdGU7CglzdHJ1Y3QgcGFycG9ydCAqcG9ydCA9IGRiOS0+cGQtPnBvcnQ7CglpbnQgZXJyOwoKCWVyciA9IGRvd25faW50ZXJydXB0aWJsZSgmZGI5LT5zZW0pOwoJaWYgKGVycikKCQlyZXR1cm4gZXJyOwoKCWlmICghZGI5LT51c2VkKyspIHsKCQlwYXJwb3J0X2NsYWltKGRiOS0+cGQpOwoJCXBhcnBvcnRfd3JpdGVfZGF0YShwb3J0LCAweGZmKTsKCQlpZiAoZGI5X21vZGVzW2RiOS0+bW9kZV0ucmV2ZXJzZSkgewoJCQlwYXJwb3J0X2RhdGFfcmV2ZXJzZShwb3J0KTsKCQkJcGFycG9ydF93cml0ZV9jb250cm9sKHBvcnQsIERCOV9OT1JNQUwpOwoJCX0KCQltb2RfdGltZXIoJmRiOS0+dGltZXIsIGppZmZpZXMgKyBEQjlfUkVGUkVTSF9USU1FKTsKCX0KCgl1cCgmZGI5LT5zZW0pOwoJcmV0dXJuIDA7Cn0KCnN0YXRpYyB2b2lkIGRiOV9jbG9zZShzdHJ1Y3QgaW5wdXRfZGV2ICpkZXYpCnsKCXN0cnVjdCBkYjkgKmRiOSA9IGRldi0+cHJpdmF0ZTsKCXN0cnVjdCBwYXJwb3J0ICpwb3J0ID0gZGI5LT5wZC0+cG9ydDsKCglkb3duKCZkYjktPnNlbSk7CglpZiAoIS0tZGI5LT51c2VkKSB7CgkJZGVsX3RpbWVyX3N5bmMoJmRiOS0+dGltZXIpOwoJCXBhcnBvcnRfd3JpdGVfY29udHJvbChwb3J0LCAweDAwKTsKCQlwYXJwb3J0X2RhdGFfZm9yd2FyZChwb3J0KTsKCQlwYXJwb3J0X3JlbGVhc2UoZGI5LT5wZCk7Cgl9Cgl1cCgmZGI5LT5zZW0pOwp9CgpzdGF0aWMgc3RydWN0IGRiOSBfX2luaXQgKmRiOV9wcm9iZShpbnQgcGFycG9ydCwgaW50IG1vZGUpCnsKCXN0cnVjdCBkYjkgKmRiOTsKCWNvbnN0IHN0cnVjdCBkYjlfbW9kZV9kYXRhICpkYjlfbW9kZTsKCXN0cnVjdCBwYXJwb3J0ICpwcDsKCXN0cnVjdCBwYXJkZXZpY2UgKnBkOwoJc3RydWN0IGlucHV0X2RldiAqaW5wdXRfZGV2OwoJaW50IGksIGo7CglpbnQgZXJyOwoKCWlmIChtb2RlIDwgMSB8fCBtb2RlID49IERCOV9NQVhfUEFEIHx8ICFkYjlfbW9kZXNbbW9kZV0ubl9idXR0b25zKSB7CgkJcHJpbnRrKEtFUk5fRVJSICJkYjkuYzogQmFkIGRldmljZSB0eXBlICVkXG4iLCBtb2RlKTsKCQllcnIgPSAtRUlOVkFMOwoJCWdvdG8gZXJyX291dDsKCX0KCglkYjlfbW9kZSA9ICZkYjlfbW9kZXNbbW9kZV07CgoJcHAgPSBwYXJwb3J0X2ZpbmRfbnVtYmVyKHBhcnBvcnQpOwoJaWYgKCFwcCkgewoJCXByaW50ayhLRVJOX0VSUiAiZGI5LmM6IG5vIHN1Y2ggcGFycG9ydFxuIik7CgkJZXJyID0gLUVOT0RFVjsKCQlnb3RvIGVycl9vdXQ7Cgl9CgoJaWYgKGRiOV9tb2RlW21vZGVdLmJpZGlyZWN0aW9uYWwgJiYgIShwcC0+bW9kZXMgJiBQQVJQT1JUX01PREVfVFJJU1RBVEUpKSB7CgkJcHJpbnRrKEtFUk5fRVJSICJkYjkuYzogc3BlY2lmaWVkIHBhcnBvcnQgaXMgbm90IGJpZGlyZWN0aW9uYWxcbiIpOwoJCWVyciA9IC1FSU5WQUw7CgkJZ290byBlcnJfcHV0X3BwOwoJfQoKCXBkID0gcGFycG9ydF9yZWdpc3Rlcl9kZXZpY2UocHAsICJkYjkiLCBOVUxMLCBOVUxMLCBOVUxMLCBQQVJQT1JUX0RFVl9FWENMLCBOVUxMKTsKCWlmICghcGQpIHsKCQlwcmludGsoS0VSTl9FUlIgImRiOS5jOiBwYXJwb3J0IGJ1c3kgYWxyZWFkeSAtIGxwLm8gbG9hZGVkP1xuIik7CgkJZXJyID0gLUVCVVNZOwoJCWdvdG8gZXJyX3B1dF9wcDsKCX0KCglkYjkgPSBremFsbG9jKHNpemVvZihzdHJ1Y3QgZGI5KSwgR0ZQX0tFUk5FTCk7CglpZiAoIWRiOSkgewoJCXByaW50ayhLRVJOX0VSUiAiZGI5LmM6IE5vdCBlbm91Z2ggbWVtb3J5XG4iKTsKCQllcnIgPSAtRU5PTUVNOwoJCWdvdG8gZXJyX3VucmVnX3BhcmRldjsKCX0KCglpbml0X01VVEVYKCZkYjktPnNlbSk7CglkYjktPnBkID0gcGQ7CglkYjktPm1vZGUgPSBtb2RlOwoJaW5pdF90aW1lcigmZGI5LT50aW1lcik7CglkYjktPnRpbWVyLmRhdGEgPSAobG9uZykgZGI5OwoJZGI5LT50aW1lci5mdW5jdGlvbiA9IGRiOV90aW1lcjsKCglmb3IgKGkgPSAwOyBpIDwgKG1pbihkYjlfbW9kZS0+bl9wYWRzLCBEQjlfTUFYX0RFVklDRVMpKTsgaSsrKSB7CgoJCWRiOS0+ZGV2W2ldID0gaW5wdXRfZGV2ID0gaW5wdXRfYWxsb2NhdGVfZGV2aWNlKCk7CgkJaWYgKCFpbnB1dF9kZXYpIHsKCQkJcHJpbnRrKEtFUk5fRVJSICJkYjkuYzogTm90IGVub3VnaCBtZW1vcnkgZm9yIGlucHV0IGRldmljZVxuIik7CgkJCWVyciA9IC1FTk9NRU07CgkJCWdvdG8gZXJyX2ZyZWVfZGV2czsKCQl9CgoJCXNwcmludGYoZGI5LT5waHlzW2ldLCAiJXMvaW5wdXQlZCIsIGRiOS0+cGQtPnBvcnQtPm5hbWUsIGkpOwoKCQlpbnB1dF9kZXYtPm5hbWUgPSBkYjlfbW9kZS0+bmFtZTsKCQlpbnB1dF9kZXYtPnBoeXMgPSBkYjktPnBoeXNbaV07CgkJaW5wdXRfZGV2LT5pZC5idXN0eXBlID0gQlVTX1BBUlBPUlQ7CgkJaW5wdXRfZGV2LT5pZC52ZW5kb3IgPSAweDAwMDI7CgkJaW5wdXRfZGV2LT5pZC5wcm9kdWN0ID0gbW9kZTsKCQlpbnB1dF9kZXYtPmlkLnZlcnNpb24gPSAweDAxMDA7CgkJaW5wdXRfZGV2LT5wcml2YXRlID0gZGI5OwoKCQlpbnB1dF9kZXYtPm9wZW4gPSBkYjlfb3BlbjsKCQlpbnB1dF9kZXYtPmNsb3NlID0gZGI5X2Nsb3NlOwoKCQlpbnB1dF9kZXYtPmV2Yml0WzBdID0gQklUKEVWX0tFWSkgfCBCSVQoRVZfQUJTKTsKCQlmb3IgKGogPSAwOyBqIDwgZGI5X21vZGUtPm5fYnV0dG9uczsgaisrKQoJCQlzZXRfYml0KGRiOV9tb2RlLT5idXR0b25zW2pdLCBpbnB1dF9kZXYtPmtleWJpdCk7CgkJZm9yIChqID0gMDsgaiA8IGRiOV9tb2RlLT5uX2F4aXM7IGorKykgewoJCQlpZiAoaiA8IDIpCgkJCQlpbnB1dF9zZXRfYWJzX3BhcmFtcyhpbnB1dF9kZXYsIGRiOV9hYnNbal0sIC0xLCAxLCAwLCAwKTsKCQkJZWxzZQoJCQkJaW5wdXRfc2V0X2Fic19wYXJhbXMoaW5wdXRfZGV2LCBkYjlfYWJzW2pdLCAxLCAyNTUsIDAsIDApOwoJCX0KCgkJaW5wdXRfcmVnaXN0ZXJfZGV2aWNlKGlucHV0X2Rldik7Cgl9CgoJcGFycG9ydF9wdXRfcG9ydChwcCk7CglyZXR1cm4gZGI5OwoKIGVycl9mcmVlX2RldnM6Cgl3aGlsZSAoLS1pID49IDApCgkJaW5wdXRfdW5yZWdpc3Rlcl9kZXZpY2UoZGI5LT5kZXZbaV0pOwoJa2ZyZWUoZGI5KTsKIGVycl91bnJlZ19wYXJkZXY6CglwYXJwb3J0X3VucmVnaXN0ZXJfZGV2aWNlKHBkKTsKIGVycl9wdXRfcHA6CglwYXJwb3J0X3B1dF9wb3J0KHBwKTsKIGVycl9vdXQ6CglyZXR1cm4gRVJSX1BUUihlcnIpOwp9CgpzdGF0aWMgdm9pZCBfX2V4aXQgZGI5X3JlbW92ZShzdHJ1Y3QgZGI5ICpkYjkpCnsKCWludCBpOwoKCWZvciAoaSA9IDA7IGkgPCBtaW4oZGI5X21vZGVzW2RiOS0+bW9kZV0ubl9wYWRzLCBEQjlfTUFYX0RFVklDRVMpOyBpKyspCgkJaW5wdXRfdW5yZWdpc3Rlcl9kZXZpY2UoZGI5LT5kZXZbaV0pOwoJcGFycG9ydF91bnJlZ2lzdGVyX2RldmljZShkYjktPnBkKTsKCWtmcmVlKGRiOSk7Cn0KCnN0YXRpYyBpbnQgX19pbml0IGRiOV9pbml0KHZvaWQpCnsKCWludCBpOwoJaW50IGhhdmVfZGV2ID0gMDsKCWludCBlcnIgPSAwOwoKCWZvciAoaSA9IDA7IGkgPCBEQjlfTUFYX1BPUlRTOyBpKyspIHsKCQlpZiAoZGI5W2ldLm5hcmdzID09IDAgfHwgZGI5W2ldLmFyZ3NbREI5X0FSR19QQVJQT1JUXSA8IDApCgkJCWNvbnRpbnVlOwoKCQlpZiAoZGI5W2ldLm5hcmdzIDwgMikgewoJCQlwcmludGsoS0VSTl9FUlIgImRiOS5jOiBEZXZpY2UgdHlwZSBtdXN0IGJlIHNwZWNpZmllZC5cbiIpOwoJCQllcnIgPSAtRUlOVkFMOwoJCQlicmVhazsKCQl9CgoJCWRiOV9iYXNlW2ldID0gZGI5X3Byb2JlKGRiOVtpXS5hcmdzW0RCOV9BUkdfUEFSUE9SVF0sCgkJCQkJZGI5W2ldLmFyZ3NbREI5X0FSR19NT0RFXSk7CgkJaWYgKElTX0VSUihkYjlfYmFzZVtpXSkpIHsKCQkJZXJyID0gUFRSX0VSUihkYjlfYmFzZVtpXSk7CgkJCWJyZWFrOwoJCX0KCgkJaGF2ZV9kZXYgPSAxOwoJfQoKCWlmIChlcnIpIHsKCQl3aGlsZSAoLS1pID49IDApCgkJCWRiOV9yZW1vdmUoZGI5X2Jhc2VbaV0pOwoJCXJldHVybiBlcnI7Cgl9CgoJcmV0dXJuIGhhdmVfZGV2ID8gMCA6IC1FTk9ERVY7Cn0KCnN0YXRpYyB2b2lkIF9fZXhpdCBkYjlfZXhpdCh2b2lkKQp7CglpbnQgaTsKCglmb3IgKGkgPSAwOyBpIDwgREI5X01BWF9QT1JUUzsgaSsrKQoJCWlmIChkYjlfYmFzZVtpXSkKCQkJZGI5X3JlbW92ZShkYjlfYmFzZVtpXSk7Cn0KCm1vZHVsZV9pbml0KGRiOV9pbml0KTsKbW9kdWxlX2V4aXQoZGI5X2V4aXQpOwo=