LyoKICogZHJpdmVycy9pMmMvaTJjLWlibV9paWMuYwogKgogKiBTdXBwb3J0IGZvciB0aGUgSUlDIHBlcmlwaGVyYWwgb24gSUJNIFBQQyA0eHgKICoKICogQ29weXJpZ2h0IChjKSAyMDAzLCAyMDA0IFp1bHR5cyBUZWNobm9sb2dpZXMuCiAqIEV1Z2VuZSBTdXJvdmVnaW4gPGV1Z2VuZS5zdXJvdmVnaW5AenVsdHlzLmNvbT4gb3IgPGVic0BlYnNob21lLm5ldD4KICoKICogQmFzZWQgb24gb3JpZ2luYWwgd29yayBieSAKICogCUlhbiBEYVNpbHZhICA8aWRhc2lsdmFAbXZpc3RhLmNvbT4KICogICAgICBBcm1pbiBLdXN0ZXIgPGFrdXN0ZXJAbXZpc3RhLmNvbT4KICogCU1hdHQgUG9ydGVyICA8bXBvcnRlckBtdmlzdGEuY29tPgogKgogKiAgICAgIENvcHlyaWdodCAyMDAwLTIwMDMgTW9udGFWaXN0YSBTb2Z0d2FyZSBJbmMuCiAqCiAqIE9yaWdpbmFsIGRyaXZlciB2ZXJzaW9uIHdhcyBoaWdobHkgbGV2ZXJhZ2VkIGZyb20gaTJjLWVsZWt0b3IuYwogKgogKiAgIAlDb3B5cmlnaHQgMTk5NS05NyBTaW1vbiBHLiBWb2dsCiAqICAgICAgICAgICAgICAgIDE5OTgtOTkgSGFucyBCZXJnbHVuZAogKgogKiAgIAlXaXRoIHNvbWUgY2hhbmdlcyBmcm9tIEt59nN0aSBN5Gxra2kgPGttYWxra2lAY2MuaHV0LmZpPiAKICoJYW5kIGV2ZW4gRnJvZG8gTG9vaWphYXJkIDxmcm9kb2xAZGRzLm5sPgogKgogKiBUaGlzIHByb2dyYW0gaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgIHRoZSB0ZXJtcyBvZiAgdGhlIEdOVSBHZW5lcmFsICBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlCiAqIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgIGVpdGhlciB2ZXJzaW9uIDIgb2YgdGhlICBMaWNlbnNlLCBvciAoYXQgeW91cgogKiBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKi8KCiNpbmNsdWRlIDxsaW51eC9tb2R1bGUuaD4KI2luY2x1ZGUgPGxpbnV4L2tlcm5lbC5oPgojaW5jbHVkZSA8bGludXgvaW9wb3J0Lmg+CiNpbmNsdWRlIDxsaW51eC9kZWxheS5oPgojaW5jbHVkZSA8bGludXgvc2xhYi5oPgojaW5jbHVkZSA8bGludXgvaW5pdC5oPgojaW5jbHVkZSA8bGludXgvaW50ZXJydXB0Lmg+CiNpbmNsdWRlIDxhc20vaXJxLmg+CiNpbmNsdWRlIDxhc20vaW8uaD4KI2luY2x1ZGUgPGxpbnV4L2kyYy5oPgojaW5jbHVkZSA8bGludXgvaTJjLWlkLmg+CiNpbmNsdWRlIDxhc20vb2NwLmg+CiNpbmNsdWRlIDxhc20vaWJtNHh4Lmg+CgojaW5jbHVkZSAiaTJjLWlibV9paWMuaCIKCiNkZWZpbmUgRFJJVkVSX1ZFUlNJT04gIjIuMSIKCk1PRFVMRV9ERVNDUklQVElPTigiSUJNIElJQyBkcml2ZXIgdiIgRFJJVkVSX1ZFUlNJT04pOwpNT0RVTEVfTElDRU5TRSgiR1BMIik7CgpzdGF0aWMgaW50IGlpY19mb3JjZV9wb2xsOwptb2R1bGVfcGFyYW0oaWljX2ZvcmNlX3BvbGwsIGJvb2wsIDApOwpNT0RVTEVfUEFSTV9ERVNDKGlpY19mb3JjZV9wb2xsLCAiRm9yY2UgcG9sbGluZyBtb2RlIik7CgpzdGF0aWMgaW50IGlpY19mb3JjZV9mYXN0Owptb2R1bGVfcGFyYW0oaWljX2ZvcmNlX2Zhc3QsIGJvb2wsIDApOwpNT0RVTEVfUEFSTV9ERVNDKGlpY19mYXN0X3BvbGwsICJGb3JjZSBmYXN0IG1vZGUgKDQwMCBrSHopIik7CgojZGVmaW5lIERCR19MRVZFTCAwCgojaWZkZWYgREJHCiN1bmRlZiBEQkcKI2VuZGlmCgojaWZkZWYgREJHMgojdW5kZWYgREJHMgojZW5kaWYKCiNpZiBEQkdfTEVWRUwgPiAwCiMgIGRlZmluZSBEQkcoZix4Li4uKQlwcmludGsoS0VSTl9ERUJVRyAiaWJtLWlpYyIgZiwgIyN4KQojZWxzZQojICBkZWZpbmUgREJHKGYseC4uLikJKCh2b2lkKTApCiNlbmRpZgojaWYgREJHX0xFVkVMID4gMQojICBkZWZpbmUgREJHMihmLHguLi4pIAlEQkcoZiwgIyN4KQojZWxzZQojICBkZWZpbmUgREJHMihmLHguLi4pIAkoKHZvaWQpMCkKI2VuZGlmCiNpZiBEQkdfTEVWRUwgPiAyCnN0YXRpYyB2b2lkIGR1bXBfaWljX3JlZ3MoY29uc3QgY2hhciogaGVhZGVyLCBzdHJ1Y3QgaWJtX2lpY19wcml2YXRlKiBkZXYpCnsKCXZvbGF0aWxlIHN0cnVjdCBpaWNfcmVncyBfX2lvbWVtICppaWMgPSBkZXYtPnZhZGRyOwoJcHJpbnRrKEtFUk5fREVCVUcgImlibS1paWMlZDogJXNcbiIsIGRldi0+aWR4LCBoZWFkZXIpOwoJcHJpbnRrKEtFUk5fREVCVUcgIiAgY250bCAgICAgPSAweCUwMngsIG1kY250bCA9IDB4JTAyeFxuIgoJICAgICAgIEtFUk5fREVCVUcgIiAgc3RzICAgICAgPSAweCUwMngsIGV4dHN0cyA9IDB4JTAyeFxuIgoJICAgICAgIEtFUk5fREVCVUcgIiAgY2xrZGl2ICAgPSAweCUwMngsIHhmcmNudCA9IDB4JTAyeFxuIgoJICAgICAgIEtFUk5fREVCVUcgIiAgeHRjbnRsc3MgPSAweCUwMngsIGRpcmVjdGNudGwgPSAweCUwMnhcbiIsCgkJaW5fOCgmaWljLT5jbnRsKSwgaW5fOCgmaWljLT5tZGNudGwpLCBpbl84KCZpaWMtPnN0cyksIAoJCWluXzgoJmlpYy0+ZXh0c3RzKSwgaW5fOCgmaWljLT5jbGtkaXYpLCBpbl84KCZpaWMtPnhmcmNudCksIAoJCWluXzgoJmlpYy0+eHRjbnRsc3MpLCBpbl84KCZpaWMtPmRpcmVjdGNudGwpKTsKfQojICBkZWZpbmUgRFVNUF9SRUdTKGgsZGV2KQlkdW1wX2lpY19yZWdzKChoKSwoZGV2KSkKI2Vsc2UKIyAgZGVmaW5lIERVTVBfUkVHUyhoLGRldikJKCh2b2lkKTApCiNlbmRpZgoKLyogQnVzIHRpbWluZ3MgKGluIG5zKSBmb3IgYml0LWJhbmdpbmcgKi8Kc3RhdGljIHN0cnVjdCBpMmNfdGltaW5ncyB7Cgl1bnNpZ25lZCBpbnQgaGRfc3RhOwoJdW5zaWduZWQgaW50IHN1X3N0bzsKCXVuc2lnbmVkIGludCBsb3c7Cgl1bnNpZ25lZCBpbnQgaGlnaDsKCXVuc2lnbmVkIGludCBidWY7Cn0gdGltaW5ncyBbXSA9IHsKLyogU3RhbmRhcmQgbW9kZSAoMTAwIEtIeikgKi8KewoJLmhkX3N0YQk9IDQwMDAsCgkuc3Vfc3RvCT0gNDAwMCwKCS5sb3cJPSA0NzAwLAoJLmhpZ2gJPSA0MDAwLAoJLmJ1Zgk9IDQ3MDAsCn0sCi8qIEZhc3QgbW9kZSAoNDAwIEtIeikgKi8KewoJLmhkX3N0YSA9IDYwMCwKCS5zdV9zdG8JPSA2MDAsCgkubG93IAk9IDEzMDAsCgkuaGlnaCAJPSA2MDAsCgkuYnVmCT0gMTMwMCwKfX07CgovKiBFbmFibGUvZGlzYWJsZSBpbnRlcnJ1cHQgZ2VuZXJhdGlvbiAqLwpzdGF0aWMgaW5saW5lIHZvaWQgaWljX2ludGVycnVwdF9tb2RlKHN0cnVjdCBpYm1faWljX3ByaXZhdGUqIGRldiwgaW50IGVuYWJsZSkKewoJb3V0XzgoJmRldi0+dmFkZHItPmludG1zaywgZW5hYmxlID8gSU5UUk1TS19FSU1UQyA6IDApOwp9CiAKLyoKICogSW5pdGlhbGl6ZSBJSUMgaW50ZXJmYWNlLgogKi8Kc3RhdGljIHZvaWQgaWljX2Rldl9pbml0KHN0cnVjdCBpYm1faWljX3ByaXZhdGUqIGRldikKewoJdm9sYXRpbGUgc3RydWN0IGlpY19yZWdzIF9faW9tZW0gKmlpYyA9IGRldi0+dmFkZHI7CgoJREJHKCIlZDogaW5pdFxuIiwgZGV2LT5pZHgpOwoJCgkvKiBDbGVhciBtYXN0ZXIgYWRkcmVzcyAqLwoJb3V0XzgoJmlpYy0+bG1hZHIsIDApOwoJb3V0XzgoJmlpYy0+aG1hZHIsIDApOwoKCS8qIENsZWFyIHNsYXZlIGFkZHJlc3MgKi8KCW91dF84KCZpaWMtPmxzYWRyLCAwKTsKCW91dF84KCZpaWMtPmhzYWRyLCAwKTsKCgkvKiBDbGVhciBzdGF0dXMgJiBleHRlbmRlZCBzdGF0dXMgKi8KCW91dF84KCZpaWMtPnN0cywgU1RTX1NDTVAgfCBTVFNfSVJRQSk7CglvdXRfOCgmaWljLT5leHRzdHMsIEVYVFNUU19JUlFQIHwgRVhUU1RTX0lSUUQgfCBFWFRTVFNfTEEKCQkJICAgIHwgRVhUU1RTX0lDVCB8IEVYVFNUU19YRlJBKTsKCgkvKiBTZXQgY2xvY2sgZGl2aWRlciAqLwoJb3V0XzgoJmlpYy0+Y2xrZGl2LCBkZXYtPmNsY2tkaXYpOwoKCS8qIENsZWFyIHRyYW5zZmVyIGNvdW50ICovCglvdXRfOCgmaWljLT54ZnJjbnQsIDApOwoKCS8qIENsZWFyIGV4dGVuZGVkIGNvbnRyb2wgYW5kIHN0YXR1cyAqLwoJb3V0XzgoJmlpYy0+eHRjbnRsc3MsIFhUQ05UTFNTX1NSQyB8IFhUQ05UTFNTX1NSUyB8IFhUQ05UTFNTX1NXQwoJCQkgICAgfCBYVENOVExTU19TV1MpOwoKCS8qIENsZWFyIGNvbnRyb2wgcmVnaXN0ZXIgKi8KCW91dF84KCZpaWMtPmNudGwsIDApOwoJCgkvKiBFbmFibGUgaW50ZXJydXB0cyBpZiBwb3NzaWJsZSAqLwoJaWljX2ludGVycnVwdF9tb2RlKGRldiwgZGV2LT5pcnEgPj0gMCk7CgoJLyogU2V0IG1vZGUgY29udHJvbCAqLwoJb3V0XzgoJmlpYy0+bWRjbnRsLCBNRENOVExfRk1EQiB8IE1EQ05UTF9FSU5UIHwgTURDTlRMX0VVQlMKCQkJICAgIHwgKGRldi0+ZmFzdF9tb2RlID8gTURDTlRMX0ZTTSA6IDApKTsKCglEVU1QX1JFR1MoImlpY19pbml0IiwgZGV2KTsKfQoKLyogCiAqIFJlc2V0IElJQyBpbnRlcmZhY2UKICovCnN0YXRpYyB2b2lkIGlpY19kZXZfcmVzZXQoc3RydWN0IGlibV9paWNfcHJpdmF0ZSogZGV2KQp7Cgl2b2xhdGlsZSBzdHJ1Y3QgaWljX3JlZ3MgX19pb21lbSAqaWljID0gZGV2LT52YWRkcjsKCWludCBpOwoJdTggZGM7CgkKCURCRygiJWQ6IHNvZnQgcmVzZXRcbiIsIGRldi0+aWR4KTsKCURVTVBfUkVHUygicmVzZXQiLCBkZXYpOwoJCiAgICAJLyogUGxhY2UgY2hpcCBpbiB0aGUgcmVzZXQgc3RhdGUgKi8KCW91dF84KCZpaWMtPnh0Y250bHNzLCBYVENOVExTU19TUlNUKTsKCQoJLyogQ2hlY2sgaWYgYnVzIGlzIGZyZWUgKi8KCWRjID0gaW5fOCgmaWljLT5kaXJlY3RjbnRsKTsJCglpZiAoIURJUkNUTkxfRlJFRShkYykpewoJCURCRygiJWQ6IHRyeWluZyB0byByZWdhaW4gYnVzIGNvbnRyb2xcbiIsIGRldi0+aWR4KTsKCQoJCS8qIFRyeSB0byBzZXQgYnVzIGZyZWUgc3RhdGUgKi8KCQlvdXRfOCgmaWljLT5kaXJlY3RjbnRsLCBESVJDTlRMX1NEQUMgfCBESVJDTlRMX1NDQyk7CQoJCgkJLyogV2FpdCB1bnRpbCB3ZSByZWdhaW4gYnVzIGNvbnRyb2wgKi8KCQlmb3IgKGkgPSAwOyBpIDwgMTAwOyArK2kpewoJCQlkYyA9IGluXzgoJmlpYy0+ZGlyZWN0Y250bCk7CgkJCWlmIChESVJDVE5MX0ZSRUUoZGMpKQoJCQkJYnJlYWs7CgkJCQoJCQkvKiBUb2dnbGUgU0NMIGxpbmUgKi8KCQkJZGMgXj0gRElSQ05UTF9TQ0M7CgkJCW91dF84KCZpaWMtPmRpcmVjdGNudGwsIGRjKTsKCQkJdWRlbGF5KDEwKTsKCQkJZGMgXj0gRElSQ05UTF9TQ0M7CgkJCW91dF84KCZpaWMtPmRpcmVjdGNudGwsIGRjKTsKCQkJCgkJCS8qIGJlIG5pY2UgKi8KCQkJY29uZF9yZXNjaGVkKCk7CgkJfQoJfQoJCgkvKiBSZW1vdmUgcmVzZXQgKi8KCW91dF84KCZpaWMtPnh0Y250bHNzLCAwKTsKCQoJLyogUmVpbml0aWFsaXplIGludGVyZmFjZSAqLwoJaWljX2Rldl9pbml0KGRldik7Cn0KCi8qCiAqIERvIDAtbGVuZ3RoIHRyYW5zYWN0aW9uIHVzaW5nIGJpdC1iYW5naW5nIHRocm91Z2ggSUlDX0RJUkVDVENOVEwgcmVnaXN0ZXIuCiAqLwoKLyogV2FpdCBmb3IgU0NMIGFuZC9vciBTREEgdG8gYmUgaGlnaCAqLwpzdGF0aWMgaW50IGlpY19kY193YWl0KHZvbGF0aWxlIHN0cnVjdCBpaWNfcmVncyBfX2lvbWVtICppaWMsIHU4IG1hc2spCnsKCXVuc2lnbmVkIGxvbmcgeCA9IGppZmZpZXMgKyBIWiAvIDI4ICsgMjsKCXdoaWxlICgoaW5fOCgmaWljLT5kaXJlY3RjbnRsKSAmIG1hc2spICE9IG1hc2spewoJCWlmICh1bmxpa2VseSh0aW1lX2FmdGVyKGppZmZpZXMsIHgpKSkKCQkJcmV0dXJuIC0xOwoJCWNvbmRfcmVzY2hlZCgpOwoJfQoJcmV0dXJuIDA7Cn0KCnN0YXRpYyBpbnQgaWljX3NtYnVzX3F1aWNrKHN0cnVjdCBpYm1faWljX3ByaXZhdGUqIGRldiwgY29uc3Qgc3RydWN0IGkyY19tc2cqIHApCnsKCXZvbGF0aWxlIHN0cnVjdCBpaWNfcmVncyBfX2lvbWVtICppaWMgPSBkZXYtPnZhZGRyOwoJY29uc3Qgc3RydWN0IGkyY190aW1pbmdzKiB0ID0gJnRpbWluZ3NbZGV2LT5mYXN0X21vZGUgPyAxIDogMF07Cgl1OCBtYXNrLCB2LCBzZGE7CglpbnQgaSwgcmVzOwoKCS8qIE9ubHkgNy1iaXQgYWRkcmVzc2VzIGFyZSBzdXBwb3J0ZWQgKi8KCWlmICh1bmxpa2VseShwLT5mbGFncyAmIEkyQ19NX1RFTikpewoJCURCRygiJWQ6IHNtYnVzX3F1aWNrIC0gMTAgYml0IGFkZHJlc3NlcyBhcmUgbm90IHN1cHBvcnRlZFxuIiwKCQkJZGV2LT5pZHgpOwoJCXJldHVybiAtRUlOVkFMOwoJfQoKCURCRygiJWQ6IHNtYnVzX3F1aWNrKDB4JTAyeClcbiIsIGRldi0+aWR4LCBwLT5hZGRyKTsKCgkvKiBSZXNldCBJSUMgaW50ZXJmYWNlICovCglvdXRfOCgmaWljLT54dGNudGxzcywgWFRDTlRMU1NfU1JTVCk7CgoJLyogV2FpdCBmb3IgYnVzIHRvIGJlY29tZSBmcmVlICovCglvdXRfOCgmaWljLT5kaXJlY3RjbnRsLCBESVJDTlRMX1NEQUMgfCBESVJDTlRMX1NDQyk7CglpZiAodW5saWtlbHkoaWljX2RjX3dhaXQoaWljLCBESVJDTlRMX01TREEgfCBESVJDTlRMX01TQykpKQoJCWdvdG8gZXJyOwoJbmRlbGF5KHQtPmJ1Zik7CgoJLyogU1RBUlQgKi8KCW91dF84KCZpaWMtPmRpcmVjdGNudGwsIERJUkNOVExfU0NDKTsKCXNkYSA9IDA7CgluZGVsYXkodC0+aGRfc3RhKTsKCgkvKiBTZW5kIGFkZHJlc3MgKi8KCXYgPSAodTgpKChwLT5hZGRyIDw8IDEpIHwgKChwLT5mbGFncyAmIEkyQ19NX1JEKSA/IDEgOiAwKSk7Cglmb3IgKGkgPSAwLCBtYXNrID0gMHg4MDsgaSA8IDg7ICsraSwgbWFzayA+Pj0gMSl7CgkJb3V0XzgoJmlpYy0+ZGlyZWN0Y250bCwgc2RhKTsKCQluZGVsYXkodC0+bG93IC8gMik7CgkJc2RhID0gKHYgJiBtYXNrKSA/IERJUkNOVExfU0RBQyA6IDA7CgkJb3V0XzgoJmlpYy0+ZGlyZWN0Y250bCwgc2RhKTsKCQluZGVsYXkodC0+bG93IC8gMik7CgoJCW91dF84KCZpaWMtPmRpcmVjdGNudGwsIERJUkNOVExfU0NDIHwgc2RhKTsKCQlpZiAodW5saWtlbHkoaWljX2RjX3dhaXQoaWljLCBESVJDTlRMX01TQykpKQoJCQlnb3RvIGVycjsKCQluZGVsYXkodC0+aGlnaCk7Cgl9CgoJLyogQUNLICovCglvdXRfOCgmaWljLT5kaXJlY3RjbnRsLCBzZGEpOwoJbmRlbGF5KHQtPmxvdyAvIDIpOwoJb3V0XzgoJmlpYy0+ZGlyZWN0Y250bCwgRElSQ05UTF9TREFDKTsKCW5kZWxheSh0LT5sb3cgLyAyKTsKCW91dF84KCZpaWMtPmRpcmVjdGNudGwsIERJUkNOVExfU0RBQyB8IERJUkNOVExfU0NDKTsKCWlmICh1bmxpa2VseShpaWNfZGNfd2FpdChpaWMsIERJUkNOVExfTVNDKSkpCgkJZ290byBlcnI7CglyZXMgPSAoaW5fOCgmaWljLT5kaXJlY3RjbnRsKSAmIERJUkNOVExfTVNEQSkgPyAtRVJFTU9URUlPIDogMTsKCW5kZWxheSh0LT5oaWdoKTsKCgkvKiBTVE9QICovCglvdXRfOCgmaWljLT5kaXJlY3RjbnRsLCAwKTsKCW5kZWxheSh0LT5sb3cpOwoJb3V0XzgoJmlpYy0+ZGlyZWN0Y250bCwgRElSQ05UTF9TQ0MpOwoJaWYgKHVubGlrZWx5KGlpY19kY193YWl0KGlpYywgRElSQ05UTF9NU0MpKSkKCQlnb3RvIGVycjsKCW5kZWxheSh0LT5zdV9zdG8pOwoJb3V0XzgoJmlpYy0+ZGlyZWN0Y250bCwgRElSQ05UTF9TREFDIHwgRElSQ05UTF9TQ0MpOwoKCW5kZWxheSh0LT5idWYpOwoKCURCRygiJWQ6IHNtYnVzX3F1aWNrIC0+ICVzXG4iLCBkZXYtPmlkeCwgcmVzID8gIk5BQ0siIDogIkFDSyIpOwpvdXQ6CgkvKiBSZW1vdmUgcmVzZXQgKi8KCW91dF84KCZpaWMtPnh0Y250bHNzLCAwKTsKCgkvKiBSZWluaXRpYWxpemUgaW50ZXJmYWNlICovCglpaWNfZGV2X2luaXQoZGV2KTsKCglyZXR1cm4gcmVzOwplcnI6CglEQkcoIiVkOiBzbWJ1c19xdWljayAtIGJ1cyBpcyBzdHVja1xuIiwgZGV2LT5pZHgpOwoJcmVzID0gLUVSRU1PVEVJTzsKCWdvdG8gb3V0Owp9CgovKgogKiBJSUMgaW50ZXJydXB0IGhhbmRsZXIKICovCnN0YXRpYyBpcnFyZXR1cm5fdCBpaWNfaGFuZGxlcihpbnQgaXJxLCB2b2lkICpkZXZfaWQsIHN0cnVjdCBwdF9yZWdzICpyZWdzKQp7CglzdHJ1Y3QgaWJtX2lpY19wcml2YXRlKiBkZXYgPSAoc3RydWN0IGlibV9paWNfcHJpdmF0ZSopZGV2X2lkOwoJdm9sYXRpbGUgc3RydWN0IGlpY19yZWdzIF9faW9tZW0gKmlpYyA9IGRldi0+dmFkZHI7CgkKCURCRzIoIiVkOiBpcnEgaGFuZGxlciwgU1RTID0gMHglMDJ4LCBFWFRTVFMgPSAweCUwMnhcbiIsIAoJICAgICBkZXYtPmlkeCwgaW5fOCgmaWljLT5zdHMpLCBpbl84KCZpaWMtPmV4dHN0cykpOwoJCgkvKiBBY2tub3dsZWRnZSBJUlEgYW5kIHdha2V1cCBpaWNfd2FpdF9mb3JfdGMgKi8KCW91dF84KCZpaWMtPnN0cywgU1RTX0lSUUEgfCBTVFNfU0NNUCk7Cgl3YWtlX3VwX2ludGVycnVwdGlibGUoJmRldi0+d3EpOwoJCglyZXR1cm4gSVJRX0hBTkRMRUQ7Cn0KCi8qCiAqIEdldCBtYXN0ZXIgdHJhbnNmZXIgcmVzdWx0IGFuZCBjbGVhciBlcnJvcnMgaWYgYW55LgogKiBSZXR1cm5zIHRoZSBudW1iZXIgb2YgYWN0dWFsbHkgdHJhbnNmZXJyZWQgYnl0ZXMgb3IgZXJyb3IgKDwwKQogKi8Kc3RhdGljIGludCBpaWNfeGZlcl9yZXN1bHQoc3RydWN0IGlibV9paWNfcHJpdmF0ZSogZGV2KQp7Cgl2b2xhdGlsZSBzdHJ1Y3QgaWljX3JlZ3MgX19pb21lbSAqaWljID0gZGV2LT52YWRkcjsJCgkKCWlmICh1bmxpa2VseShpbl84KCZpaWMtPnN0cykgJiBTVFNfRVJSKSl7CgkJREJHKCIlZDogeGZlciBlcnJvciwgRVhUU1RTID0gMHglMDJ4XG4iLCBkZXYtPmlkeCwgCgkJCWluXzgoJmlpYy0+ZXh0c3RzKSk7CgkJCQkKCQkvKiBDbGVhciBlcnJvcnMgYW5kIHBvc3NpYmxlIHBlbmRpbmcgSVJRcyAqLwoJCW91dF84KCZpaWMtPmV4dHN0cywgRVhUU1RTX0lSUVAgfCBFWFRTVFNfSVJRRCB8IAoJCQlFWFRTVFNfTEEgfCBFWFRTVFNfSUNUIHwgRVhUU1RTX1hGUkEpOwoJCQkKCQkvKiBGbHVzaCBtYXN0ZXIgZGF0YSBidWZmZXIgKi8KCQlvdXRfOCgmaWljLT5tZGNudGwsIGluXzgoJmlpYy0+bWRjbnRsKSB8IE1EQ05UTF9GTURCKTsKCQkKCQkvKiBJcyBidXMgZnJlZT8KCQkgKiBJZiBlcnJvciBoYXBwZW5lZCBkdXJpbmcgY29tYmluZWQgeGZlcgoJCSAqIElJQyBpbnRlcmZhY2UgaXMgdXN1YWxseSBzdHVjayBpbiBzb21lIHN0cmFuZ2UKCQkgKiBzdGF0ZSwgdGhlIG9ubHkgd2F5IG91dCAtIHNvZnQgcmVzZXQuCgkJICovCgkJaWYgKChpbl84KCZpaWMtPmV4dHN0cykgJiBFWFRTVFNfQkNTX01BU0spICE9IEVYVFNUU19CQ1NfRlJFRSl7CgkJCURCRygiJWQ6IGJ1cyBpcyBzdHVjaywgcmVzZXR0aW5nXG4iLCBkZXYtPmlkeCk7CgkJCWlpY19kZXZfcmVzZXQoZGV2KTsKCQl9CgkJcmV0dXJuIC1FUkVNT1RFSU87Cgl9CgllbHNlCgkJcmV0dXJuIGluXzgoJmlpYy0+eGZyY250KSAmIFhGUkNOVF9NVENfTUFTSzsKfQoKLyoKICogVHJ5IHRvIGFib3J0IGFjdGl2ZSB0cmFuc2Zlci4KICovCnN0YXRpYyB2b2lkIGlpY19hYm9ydF94ZmVyKHN0cnVjdCBpYm1faWljX3ByaXZhdGUqIGRldikKewoJdm9sYXRpbGUgc3RydWN0IGlpY19yZWdzIF9faW9tZW0gKmlpYyA9IGRldi0+dmFkZHI7Cgl1bnNpZ25lZCBsb25nIHg7CgkKCURCRygiJWQ6IGlpY19hYm9ydF94ZmVyXG4iLCBkZXYtPmlkeCk7CgkKCW91dF84KCZpaWMtPmNudGwsIENOVExfSE1UKTsKCQoJLyoKCSAqIFdhaXQgZm9yIHRoZSBhYm9ydCBjb21tYW5kIHRvIGNvbXBsZXRlLgoJICogSXQncyBub3Qgd29ydGggdG8gYmUgb3B0aW1pemVkLCBqdXN0IHBvbGwgKHRpbWVvdXQgPj0gMSB0aWNrKQoJICovCgl4ID0gamlmZmllcyArIDI7Cgl3aGlsZSAoKGluXzgoJmlpYy0+ZXh0c3RzKSAmIEVYVFNUU19CQ1NfTUFTSykgIT0gRVhUU1RTX0JDU19GUkVFKXsKCQlpZiAodGltZV9hZnRlcihqaWZmaWVzLCB4KSl7CgkJCURCRygiJWQ6IGFib3J0IHRpbWVvdXQsIHJlc2V0dGluZy4uLlxuIiwgZGV2LT5pZHgpOwoJCQlpaWNfZGV2X3Jlc2V0KGRldik7CgkJCXJldHVybjsKCQl9CgkJc2NoZWR1bGUoKTsKCX0KCgkvKiBKdXN0IHRvIGNsZWFyIGVycm9ycyAqLwoJaWljX3hmZXJfcmVzdWx0KGRldik7Cn0KCi8qCiAqIFdhaXQgZm9yIG1hc3RlciB0cmFuc2ZlciB0byBjb21wbGV0ZS4KICogSXQgcHV0cyBjdXJyZW50IHByb2Nlc3MgdG8gc2xlZXAgdW50aWwgd2UgZ2V0IGludGVycnVwdCBvciB0aW1lb3V0IGV4cGlyZXMuCiAqIFJldHVybnMgdGhlIG51bWJlciBvZiB0cmFuc2ZlcnJlZCBieXRlcyBvciBlcnJvciAoPDApCiAqLwpzdGF0aWMgaW50IGlpY193YWl0X2Zvcl90YyhzdHJ1Y3QgaWJtX2lpY19wcml2YXRlKiBkZXYpewoJCgl2b2xhdGlsZSBzdHJ1Y3QgaWljX3JlZ3MgX19pb21lbSAqaWljID0gZGV2LT52YWRkcjsKCWludCByZXQgPSAwOwoJCglpZiAoZGV2LT5pcnEgPj0gMCl7CgkJLyogSW50ZXJydXB0IG1vZGUgKi8KCQlyZXQgPSB3YWl0X2V2ZW50X2ludGVycnVwdGlibGVfdGltZW91dChkZXYtPndxLCAKCQkJIShpbl84KCZpaWMtPnN0cykgJiBTVFNfUFQpLCBkZXYtPmFkYXAudGltZW91dCAqIEhaKTsKCgkJaWYgKHVubGlrZWx5KHJldCA8IDApKQoJCQlEQkcoIiVkOiB3YWl0IGludGVycnVwdGVkXG4iLCBkZXYtPmlkeCk7CgkJZWxzZSBpZiAodW5saWtlbHkoaW5fOCgmaWljLT5zdHMpICYgU1RTX1BUKSl7CgkJCURCRygiJWQ6IHdhaXQgdGltZW91dFxuIiwgZGV2LT5pZHgpOwoJCQlyZXQgPSAtRVRJTUVET1VUOwoJCX0KCX0KCWVsc2UgewoJCS8qIFBvbGxpbmcgbW9kZSAqLwoJCXVuc2lnbmVkIGxvbmcgeCA9IGppZmZpZXMgKyBkZXYtPmFkYXAudGltZW91dCAqIEhaOwoJCQoJCXdoaWxlIChpbl84KCZpaWMtPnN0cykgJiBTVFNfUFQpewoJCQlpZiAodW5saWtlbHkodGltZV9hZnRlcihqaWZmaWVzLCB4KSkpewoJCQkJREJHKCIlZDogcG9sbCB0aW1lb3V0XG4iLCBkZXYtPmlkeCk7CgkJCQlyZXQgPSAtRVRJTUVET1VUOwoJCQkJYnJlYWs7CgkJCX0KCQkKCQkJaWYgKHVubGlrZWx5KHNpZ25hbF9wZW5kaW5nKGN1cnJlbnQpKSl7CgkJCQlEQkcoIiVkOiBwb2xsIGludGVycnVwdGVkXG4iLCBkZXYtPmlkeCk7CgkJCQlyZXQgPSAtRVJFU1RBUlRTWVM7CgkJCQlicmVhazsKCQkJfQoJCQlzY2hlZHVsZSgpOwoJCX0JCgl9CgkKCWlmICh1bmxpa2VseShyZXQgPCAwKSkKCQlpaWNfYWJvcnRfeGZlcihkZXYpOwoJZWxzZQoJCXJldCA9IGlpY194ZmVyX3Jlc3VsdChkZXYpOwoJCglEQkcyKCIlZDogaWljX3dhaXRfZm9yX3RjIC0+ICVkXG4iLCBkZXYtPmlkeCwgcmV0KTsKCQoJcmV0dXJuIHJldDsKfQoKLyoKICogTG93IGxldmVsIG1hc3RlciB0cmFuc2ZlciByb3V0aW5lCiAqLwpzdGF0aWMgaW50IGlpY194ZmVyX2J5dGVzKHN0cnVjdCBpYm1faWljX3ByaXZhdGUqIGRldiwgc3RydWN0IGkyY19tc2cqIHBtLCAKCQkJICBpbnQgY29tYmluZWRfeGZlcikKewoJdm9sYXRpbGUgc3RydWN0IGlpY19yZWdzIF9faW9tZW0gKmlpYyA9IGRldi0+dmFkZHI7CgljaGFyKiBidWYgPSBwbS0+YnVmOwoJaW50IGksIGosIGxvb3BzLCByZXQgPSAwOwoJaW50IGxlbiA9IHBtLT5sZW47CgoJdTggY250bCA9IChpbl84KCZpaWMtPmNudGwpICYgQ05UTF9BTUQpIHwgQ05UTF9QVDsKCWlmIChwbS0+ZmxhZ3MgJiBJMkNfTV9SRCkKCQljbnRsIHw9IENOVExfUlc7CgkKCWxvb3BzID0gKGxlbiArIDMpIC8gNDsKCWZvciAoaSA9IDA7IGkgPCBsb29wczsgKytpLCBsZW4gLT0gNCl7CgkJaW50IGNvdW50ID0gbGVuID4gNCA/IDQgOiBsZW47CgkJdTggY21kID0gY250bCB8ICgoY291bnQgLSAxKSA8PCBDTlRMX1RDVF9TSElGVCk7CgkJCgkJaWYgKCEoY250bCAmIENOVExfUlcpKQoJCQlmb3IgKGogPSAwOyBqIDwgY291bnQ7ICsraikKCQkJCW91dF84KCh2b2lkIF9faW9tZW0gKikmaWljLT5tZGJ1ZiwgKmJ1ZisrKTsKCQkKCQlpZiAoaSA8IGxvb3BzIC0gMSkKCQkJY21kIHw9IENOVExfQ0hUOwoJCWVsc2UgaWYgKGNvbWJpbmVkX3hmZXIpCgkJCWNtZCB8PSBDTlRMX1JQU1Q7CgkJCgkJREJHMigiJWQ6IHhmZXJfYnl0ZXMsICVkLCBDTlRMID0gMHglMDJ4XG4iLCBkZXYtPmlkeCwgY291bnQsIGNtZCk7CgkJCgkJLyogU3RhcnQgdHJhbnNmZXIgKi8KCQlvdXRfOCgmaWljLT5jbnRsLCBjbWQpOwoJCQoJCS8qIFdhaXQgZm9yIGNvbXBsZXRpb24gKi8KCQlyZXQgPSBpaWNfd2FpdF9mb3JfdGMoZGV2KTsKCgkJaWYgKHVubGlrZWx5KHJldCA8IDApKQoJCQlicmVhazsKCQllbHNlIGlmICh1bmxpa2VseShyZXQgIT0gY291bnQpKXsKCQkJREJHKCIlZDogeGZlcl9ieXRlcywgcmVxdWVzdGVkICVkLCB0cmFuc2ZlcmVkICVkXG4iLCAKCQkJCWRldi0+aWR4LCBjb3VudCwgcmV0KTsKCQkJCgkJCS8qIElmIGl0J3Mgbm90IGEgbGFzdCBwYXJ0IG9mIHhmZXIsIGFib3J0IGl0ICovCgkJCWlmIChjb21iaW5lZF94ZmVyIHx8IChpIDwgbG9vcHMgLSAxKSkKICAgIAkJCQlpaWNfYWJvcnRfeGZlcihkZXYpOwoJCQkJCgkJCXJldCA9IC1FUkVNT1RFSU87CgkJCWJyZWFrOwkJCQkKCQl9CgkJCgkJaWYgKGNudGwgJiBDTlRMX1JXKQoJCQlmb3IgKGogPSAwOyBqIDwgY291bnQ7ICsraikKCQkJCSpidWYrKyA9IGluXzgoKHZvaWQgX19pb21lbSAqKSZpaWMtPm1kYnVmKTsKCX0KCQoJcmV0dXJuIHJldCA+IDAgPyAwIDogcmV0Owp9CgovKgogKiBTZXQgdGFyZ2V0IHNsYXZlIGFkZHJlc3MgZm9yIG1hc3RlciB0cmFuc2ZlcgogKi8Kc3RhdGljIGlubGluZSB2b2lkIGlpY19hZGRyZXNzKHN0cnVjdCBpYm1faWljX3ByaXZhdGUqIGRldiwgc3RydWN0IGkyY19tc2cqIG1zZykKewoJdm9sYXRpbGUgc3RydWN0IGlpY19yZWdzIF9faW9tZW0gKmlpYyA9IGRldi0+dmFkZHI7Cgl1MTYgYWRkciA9IG1zZy0+YWRkcjsKCQoJREJHMigiJWQ6IGlpY19hZGRyZXNzLCAweCUwM3ggKCVkLWJpdClcbiIsIGRldi0+aWR4LCAKCQlhZGRyLCBtc2ctPmZsYWdzICYgSTJDX01fVEVOID8gMTAgOiA3KTsKCQoJaWYgKG1zZy0+ZmxhZ3MgJiBJMkNfTV9URU4pewoJICAgIG91dF84KCZpaWMtPmNudGwsIENOVExfQU1EKTsKCSAgICBvdXRfOCgmaWljLT5sbWFkciwgYWRkcik7CgkgICAgb3V0XzgoJmlpYy0+aG1hZHIsIDB4ZjAgfCAoKGFkZHIgPj4gNykgJiAweDA2KSk7Cgl9CgllbHNlIHsKCSAgICBvdXRfOCgmaWljLT5jbnRsLCAwKTsKCSAgICBvdXRfOCgmaWljLT5sbWFkciwgYWRkciA8PCAxKTsKCX0KfQoKc3RhdGljIGlubGluZSBpbnQgaWljX2ludmFsaWRfYWRkcmVzcyhjb25zdCBzdHJ1Y3QgaTJjX21zZyogcCkKewoJcmV0dXJuIChwLT5hZGRyID4gMHgzZmYpIHx8ICghKHAtPmZsYWdzICYgSTJDX01fVEVOKSAmJiAocC0+YWRkciA+IDB4N2YpKTsKfQoKc3RhdGljIGlubGluZSBpbnQgaWljX2FkZHJlc3NfbmVxKGNvbnN0IHN0cnVjdCBpMmNfbXNnKiBwMSwgCgkJCQkgIGNvbnN0IHN0cnVjdCBpMmNfbXNnKiBwMikKewoJcmV0dXJuIChwMS0+YWRkciAhPSBwMi0+YWRkcikgCgkJfHwgKChwMS0+ZmxhZ3MgJiBJMkNfTV9URU4pICE9IChwMi0+ZmxhZ3MgJiBJMkNfTV9URU4pKTsKfSAKCi8qCiAqIEdlbmVyaWMgbWFzdGVyIHRyYW5zZmVyIGVudHJ5cG9pbnQuIAogKiBSZXR1cm5zIHRoZSBudW1iZXIgb2YgcHJvY2Vzc2VkIG1lc3NhZ2VzIG9yIGVycm9yICg8MCkKICovCnN0YXRpYyBpbnQgaWljX3hmZXIoc3RydWN0IGkyY19hZGFwdGVyICphZGFwLCBzdHJ1Y3QgaTJjX21zZyAqbXNncywgaW50IG51bSkKewogICAgCXN0cnVjdCBpYm1faWljX3ByaXZhdGUqIGRldiA9IChzdHJ1Y3QgaWJtX2lpY19wcml2YXRlKikoaTJjX2dldF9hZGFwZGF0YShhZGFwKSk7Cgl2b2xhdGlsZSBzdHJ1Y3QgaWljX3JlZ3MgX19pb21lbSAqaWljID0gZGV2LT52YWRkcjsKCWludCBpLCByZXQgPSAwOwoJCglEQkcyKCIlZDogaWljX3hmZXIsICVkIG1zZyhzKVxuIiwgZGV2LT5pZHgsIG51bSk7CgkKCWlmICghbnVtKQoJCXJldHVybiAwOwoJCgkvKiBDaGVjayB0aGUgc2FuaXR5IG9mIHRoZSBwYXNzZWQgbWVzc2FnZXMuCgkgKiBVaGgsIGdlbmVyaWMgaTJjIGxheWVyIGlzIG1vcmUgc3VpdGFibGUgcGxhY2UgZm9yIHN1Y2ggY29kZS4uLgoJICovCglpZiAodW5saWtlbHkoaWljX2ludmFsaWRfYWRkcmVzcygmbXNnc1swXSkpKXsKCQlEQkcoIiVkOiBpbnZhbGlkIGFkZHJlc3MgMHglMDN4ICglZC1iaXQpXG4iLCBkZXYtPmlkeCwgCgkJCW1zZ3NbMF0uYWRkciwgbXNnc1swXS5mbGFncyAmIEkyQ19NX1RFTiA/IDEwIDogNyk7CgkJcmV0dXJuIC1FSU5WQUw7Cgl9CQkKCWZvciAoaSA9IDA7IGkgPCBudW07ICsraSl7CgkJaWYgKHVubGlrZWx5KG1zZ3NbaV0ubGVuIDw9IDApKXsKCQkJaWYgKG51bSA9PSAxICYmICFtc2dzWzBdLmxlbil7CgkJCQkvKiBTcGVjaWFsIGNhc2UgZm9yIEkyQ19TTUJVU19RVUlDSyBlbXVsYXRpb24uCgkJCQkgKiBJQk0gSUlDIGRvZXNuJ3Qgc3VwcG9ydCAwLWxlbmd0aCB0cmFuc2FjdGlvbnMKCQkJCSAqIHNvIHdlIGhhdmUgdG8gZW11bGF0ZSB0aGVtIHVzaW5nIGJpdC1iYW5naW5nLgoJCQkJICovCgkJCQlyZXR1cm4gaWljX3NtYnVzX3F1aWNrKGRldiwgJm1zZ3NbMF0pOwoJCQl9CgkJCURCRygiJWQ6IGludmFsaWQgbGVuICVkIGluIG1zZ1slZF1cbiIsIGRldi0+aWR4LCAKCQkJCW1zZ3NbaV0ubGVuLCBpKTsKCQkJcmV0dXJuIC1FSU5WQUw7CgkJfQoJCWlmICh1bmxpa2VseShpaWNfYWRkcmVzc19uZXEoJm1zZ3NbMF0sICZtc2dzW2ldKSkpewoJCQlEQkcoIiVkOiBpbnZhbGlkIGFkZHIgaW4gbXNnWyVkXVxuIiwgZGV2LT5pZHgsIGkpOwoJCQlyZXR1cm4gLUVJTlZBTDsKCQl9Cgl9CgkKCS8qIENoZWNrIGJ1cyBzdGF0ZSAqLwoJaWYgKHVubGlrZWx5KChpbl84KCZpaWMtPmV4dHN0cykgJiBFWFRTVFNfQkNTX01BU0spICE9IEVYVFNUU19CQ1NfRlJFRSkpewoJCURCRygiJWQ6IGlpY194ZmVyLCBidXMgaXMgbm90IGZyZWVcbiIsIGRldi0+aWR4KTsKCQkKCQkvKiBVc3VhbGx5IGl0IG1lYW5zIHNvbWV0aGluZyBzZXJpb3VzIGhhcyBoYXBwZW5kLgoJCSAqIFdlICpjYW5ub3QqIGhhdmUgdW5maW5pc2hlZCBwcmV2aW91cyB0cmFuc2ZlcgoJCSAqIHNvIGl0IGRvZXNuJ3QgbWFrZSBhbnkgc2Vuc2UgdG8gdHJ5IHRvIHN0b3AgaXQuCgkJICogUHJvYmFibHkgd2Ugd2VyZSBub3QgYWJsZSB0byByZWNvdmVyIGZyb20gdGhlIAoJCSAqIHByZXZpb3VzIGVycm9yLgoJCSAqIFRoZSBvbmx5ICpyZWFzb25hYmxlKiB0aGluZyBJIGNhbiB0aGluayBvZiBoZXJlCgkJICogaXMgc29mdCByZXNldC4gIC0tZWJzCgkJICovCgkJaWljX2Rldl9yZXNldChkZXYpOwoJCQoJCWlmICgoaW5fOCgmaWljLT5leHRzdHMpICYgRVhUU1RTX0JDU19NQVNLKSAhPSBFWFRTVFNfQkNTX0ZSRUUpewoJCQlEQkcoIiVkOiBpaWNfeGZlciwgYnVzIGlzIHN0aWxsIG5vdCBmcmVlXG4iLCBkZXYtPmlkeCk7CgkJCXJldHVybiAtRVJFTU9URUlPOwoJCX0KCX0gCgllbHNlIHsKCQkvKiBGbHVzaCBtYXN0ZXIgZGF0YSBidWZmZXIgKGp1c3QgaW4gY2FzZSkgKi8KCQlvdXRfOCgmaWljLT5tZGNudGwsIGluXzgoJmlpYy0+bWRjbnRsKSB8IE1EQ05UTF9GTURCKTsKCX0KCQoJLyogTG9hZCBzbGF2ZSBhZGRyZXNzICovCglpaWNfYWRkcmVzcyhkZXYsICZtc2dzWzBdKTsKCQoJLyogRG8gcmVhbCB0cmFuc2ZlciAqLwogICAgCWZvciAoaSA9IDA7IGkgPCBudW0gJiYgIXJldDsgKytpKQoJCXJldCA9IGlpY194ZmVyX2J5dGVzKGRldiwgJm1zZ3NbaV0sIGkgPCBudW0gLSAxKTsKCglyZXR1cm4gcmV0IDwgMCA/IHJldCA6IG51bTsKfQoKc3RhdGljIHUzMiBpaWNfZnVuYyhzdHJ1Y3QgaTJjX2FkYXB0ZXIgKmFkYXApCnsKCXJldHVybiBJMkNfRlVOQ19JMkMgfCBJMkNfRlVOQ19TTUJVU19FTVVMIHwgSTJDX0ZVTkNfMTBCSVRfQUREUjsKfQoKc3RhdGljIHN0cnVjdCBpMmNfYWxnb3JpdGhtIGlpY19hbGdvID0gewoJLm1hc3Rlcl94ZmVyIAk9IGlpY194ZmVyLAoJLmZ1bmN0aW9uYWxpdHkJPSBpaWNfZnVuYwp9OwoKLyoKICogQ2FsY3VsYXRlcyBJSUN4X0NMQ0tESVYgdmFsdWUgZm9yIGEgc3BlY2lmaWMgT1BCIGNsb2NrIGZyZXF1ZW5jeQogKi8Kc3RhdGljIGlubGluZSB1OCBpaWNfY2xja2Rpdih1bnNpZ25lZCBpbnQgb3BiKQp7CgkvKiBDb21wYXRpYmlsaXR5IGtsdWRnZSwgc2hvdWxkIGdvIGF3YXkgYWZ0ZXIgYWxsIGNhcmRzCgkgKiBhcmUgZml4ZWQgdG8gZmlsbCBjb3JyZWN0IHZhbHVlIGZvciBvcGJmcmVxLgoJICogUHJldmlvdXMgZHJpdmVyIHZlcnNpb24gdXNlZCBoYXJkY29kZWQgZGl2aWRlciB2YWx1ZSA0LAoJICogaXQgY29ycmVzcG9uZHMgdG8gT1BCIGZyZXF1ZW5jeSBmcm9tIHRoZSByYW5nZSAoNDAsIDUwXSBNSHoKCSAqLwoJaWYgKCFvcGIpewoJCXByaW50ayhLRVJOX1dBUk5JTkcgImlibS1paWM6IHVzaW5nIGNvbXBhdGliaWxpdHkgdmFsdWUgZm9yIE9QQiBmcmVxLCIKCQkJIiBmaXggeW91ciBib2FyZCBzcGVjaWZpYyBzZXR1cFxuIik7CgkJb3BiID0gNTAwMDAwMDA7Cgl9CgoJLyogQ29udmVydCB0byBNSHogKi8KCW9wYiAvPSAxMDAwMDAwOwoJCglpZiAob3BiIDwgMjAgfHwgb3BiID4gMTUwKXsKCQlwcmludGsoS0VSTl9DUklUICJpYm0taWljOiBpbnZhbGlkIE9QQiBjbG9jayBmcmVxdWVuY3kgJXUgTUh6XG4iLAoJCQlvcGIpOwoJCW9wYiA9IG9wYiA8IDIwID8gMjAgOiAxNTA7Cgl9CglyZXR1cm4gKHU4KSgob3BiICsgOSkgLyAxMCAtIDEpOwp9CgovKgogKiBSZWdpc3RlciBzaW5nbGUgSUlDIGludGVyZmFjZQogKi8Kc3RhdGljIGludCBfX2RldmluaXQgaWljX3Byb2JlKHN0cnVjdCBvY3BfZGV2aWNlICpvY3ApewoKCXN0cnVjdCBpYm1faWljX3ByaXZhdGUqIGRldjsKCXN0cnVjdCBpMmNfYWRhcHRlciogYWRhcDsKCXN0cnVjdCBvY3BfZnVuY19paWNfZGF0YSogaWljX2RhdGEgPSBvY3AtPmRlZi0+YWRkaXRpb25zOwoJaW50IHJldDsKCQoJaWYgKCFpaWNfZGF0YSkKCQlwcmludGsoS0VSTl9XQVJOSU5HImlibS1paWMlZDogbWlzc2luZyBhZGRpdGlvbmFsIGRhdGEhXG4iLAoJCQlvY3AtPmRlZi0+aW5kZXgpOwoKCWlmICghKGRldiA9IGt6YWxsb2Moc2l6ZW9mKCpkZXYpLCBHRlBfS0VSTkVMKSkpIHsKCQlwcmludGsoS0VSTl9DUklUICJpYm0taWljJWQ6IGZhaWxlZCB0byBhbGxvY2F0ZSBkZXZpY2UgZGF0YVxuIiwKCQkJb2NwLT5kZWYtPmluZGV4KTsKCQlyZXR1cm4gLUVOT01FTTsKCX0KCglkZXYtPmlkeCA9IG9jcC0+ZGVmLT5pbmRleDsKCW9jcF9zZXRfZHJ2ZGF0YShvY3AsIGRldik7CgkKCWlmICghKGRldi0+dmFkZHIgPSBpb3JlbWFwKG9jcC0+ZGVmLT5wYWRkciwgc2l6ZW9mKHN0cnVjdCBpaWNfcmVncykpKSl7CgkJcHJpbnRrKEtFUk5fQ1JJVCAiaWJtLWlpYyVkOiBmYWlsZWQgdG8gaW9yZW1hcCBkZXZpY2UgcmVnaXN0ZXJzXG4iLAoJCQlkZXYtPmlkeCk7CgkJcmV0ID0gLUVOWElPOwoJCWdvdG8gZmFpbDI7Cgl9CgkKCWluaXRfd2FpdHF1ZXVlX2hlYWQoJmRldi0+d3EpOwoKCWRldi0+aXJxID0gaWljX2ZvcmNlX3BvbGwgPyAtMSA6IG9jcC0+ZGVmLT5pcnE7CglpZiAoZGV2LT5pcnEgPj0gMCl7CgkJLyogRGlzYWJsZSBpbnRlcnJ1cHRzIHVudGlsIHdlIGZpbmlzaCBpbml0aWFsaXphdGlvbiwKCQkgICBhc3N1bWVzIGxldmVsLXNlbnNpdGl2ZSBJUlEgc2V0dXAuLi4KCQkgKi8KCQlpaWNfaW50ZXJydXB0X21vZGUoZGV2LCAwKTsKCQlpZiAocmVxdWVzdF9pcnEoZGV2LT5pcnEsIGlpY19oYW5kbGVyLCAwLCAiSUJNIElJQyIsIGRldikpewoJCQlwcmludGsoS0VSTl9FUlIgImlibS1paWMlZDogcmVxdWVzdF9pcnEgJWQgZmFpbGVkXG4iLCAKCQkJCWRldi0+aWR4LCBkZXYtPmlycSk7CgkJCS8qIEZhbGxiYWNrIHRvIHRoZSBwb2xsaW5nIG1vZGUgKi8JCgkJCWRldi0+aXJxID0gLTE7CgkJfQoJfQoJCglpZiAoZGV2LT5pcnEgPCAwKQoJCXByaW50ayhLRVJOX1dBUk5JTkcgImlibS1paWMlZDogdXNpbmcgcG9sbGluZyBtb2RlXG4iLCAKCQkJZGV2LT5pZHgpOwoJCQoJLyogQm9hcmQgc3BlY2lmaWMgc2V0dGluZ3MgKi8KCWRldi0+ZmFzdF9tb2RlID0gaWljX2ZvcmNlX2Zhc3QgPyAxIDogKGlpY19kYXRhID8gaWljX2RhdGEtPmZhc3RfbW9kZSA6IDApOwoJCgkvKiBjbGNrZGl2IGlzIHRoZSBzYW1lIGZvciAqYWxsKiBJSUMgaW50ZXJmYWNlcywgCgkgKiBidXQgSSdkIHJhdGhlciBtYWtlIGEgY29weSB0aGFuIGludHJvZHVjZSBhbm90aGVyIGdsb2JhbC4gLS1lYnMKCSAqLwoJZGV2LT5jbGNrZGl2ID0gaWljX2NsY2tkaXYob2NwX3N5c19pbmZvLm9wYl9idXNfZnJlcSk7CglEQkcoIiVkOiBjbGNrZGl2ID0gJWRcbiIsIGRldi0+aWR4LCBkZXYtPmNsY2tkaXYpOwoJCgkvKiBJbml0aWFsaXplIElJQyBpbnRlcmZhY2UgKi8KCWlpY19kZXZfaW5pdChkZXYpOwoJCgkvKiBSZWdpc3RlciBpdCB3aXRoIGkyYyBsYXllciAqLwoJYWRhcCA9ICZkZXYtPmFkYXA7CglzdHJjcHkoYWRhcC0+bmFtZSwgIklCTSBJSUMiKTsKCWkyY19zZXRfYWRhcGRhdGEoYWRhcCwgZGV2KTsKCWFkYXAtPmlkID0gSTJDX0hXX09DUDsKCWFkYXAtPmNsYXNzID0gSTJDX0NMQVNTX0hXTU9OOwoJYWRhcC0+YWxnbyA9ICZpaWNfYWxnbzsKCWFkYXAtPmNsaWVudF9yZWdpc3RlciA9IE5VTEw7CglhZGFwLT5jbGllbnRfdW5yZWdpc3RlciA9IE5VTEw7CglhZGFwLT50aW1lb3V0ID0gMTsKCWFkYXAtPnJldHJpZXMgPSAxOwoKCWlmICgocmV0ID0gaTJjX2FkZF9hZGFwdGVyKGFkYXApKSAhPSAwKXsKCQlwcmludGsoS0VSTl9DUklUICJpYm0taWljJWQ6IGZhaWxlZCB0byByZWdpc3RlciBpMmMgYWRhcHRlclxuIiwKCQkJZGV2LT5pZHgpOwoJCWdvdG8gZmFpbDsKCX0KCQoJcHJpbnRrKEtFUk5fSU5GTyAiaWJtLWlpYyVkOiB1c2luZyAlcyBtb2RlXG4iLCBkZXYtPmlkeCwKCQlkZXYtPmZhc3RfbW9kZSA/ICJmYXN0ICg0MDAga0h6KSIgOiAic3RhbmRhcmQgKDEwMCBrSHopIik7CgoJcmV0dXJuIDA7CgpmYWlsOgkKCWlmIChkZXYtPmlycSA+PSAwKXsKCQlpaWNfaW50ZXJydXB0X21vZGUoZGV2LCAwKTsKCQlmcmVlX2lycShkZXYtPmlycSwgZGV2KTsKCX0JCgoJaW91bm1hcChkZXYtPnZhZGRyKTsKZmFpbDI6CQoJb2NwX3NldF9kcnZkYXRhKG9jcCwgTlVMTCk7CglrZnJlZShkZXYpOwkKCXJldHVybiByZXQ7Cn0KCi8qCiAqIENsZWFudXAgaW5pdGlhbGl6ZWQgSUlDIGludGVyZmFjZQogKi8Kc3RhdGljIHZvaWQgX19kZXZleGl0IGlpY19yZW1vdmUoc3RydWN0IG9jcF9kZXZpY2UgKm9jcCkKewoJc3RydWN0IGlibV9paWNfcHJpdmF0ZSogZGV2ID0gKHN0cnVjdCBpYm1faWljX3ByaXZhdGUqKW9jcF9nZXRfZHJ2ZGF0YShvY3ApOwoJQlVHX09OKGRldiA9PSBOVUxMKTsKCWlmIChpMmNfZGVsX2FkYXB0ZXIoJmRldi0+YWRhcCkpewoJCXByaW50ayhLRVJOX0NSSVQgImlibS1paWMlZDogZmFpbGVkIHRvIGRlbGV0ZSBpMmMgYWRhcHRlciA6KFxuIiwKCQkJZGV2LT5pZHgpOwoJCS8qIFRoYXQncyAqdmVyeSogYmFkLCBqdXN0IHNodXRkb3duIElSUSAuLi4gKi8KCQlpZiAoZGV2LT5pcnEgPj0gMCl7CgkJICAgIGlpY19pbnRlcnJ1cHRfbW9kZShkZXYsIDApOwkKCQkgICAgZnJlZV9pcnEoZGV2LT5pcnEsIGRldik7CgkJICAgIGRldi0+aXJxID0gLTE7CgkJfQoJfSBlbHNlIHsKCQlpZiAoZGV2LT5pcnEgPj0gMCl7CgkJICAgIGlpY19pbnRlcnJ1cHRfbW9kZShkZXYsIDApOwkKCQkgICAgZnJlZV9pcnEoZGV2LT5pcnEsIGRldik7CgkJfQoJCWlvdW5tYXAoZGV2LT52YWRkcik7CgkJa2ZyZWUoZGV2KTsKCX0KfQoKc3RhdGljIHN0cnVjdCBvY3BfZGV2aWNlX2lkIGlibV9paWNfaWRzW10gX19kZXZpbml0ZGF0YSA9IAp7Cgl7IC52ZW5kb3IgPSBPQ1BfVkVORE9SX0lCTSwgLmZ1bmN0aW9uID0gT0NQX0ZVTkNfSUlDIH0sCgl7IC52ZW5kb3IgPSBPQ1BfVkVORE9SX0lOVkFMSUQgfQp9OwoKTU9EVUxFX0RFVklDRV9UQUJMRShvY3AsIGlibV9paWNfaWRzKTsKCnN0YXRpYyBzdHJ1Y3Qgb2NwX2RyaXZlciBpYm1faWljX2RyaXZlciA9CnsKCS5uYW1lIAkJPSAiaWljIiwKCS5pZF90YWJsZQk9IGlibV9paWNfaWRzLAoJLnByb2JlCQk9IGlpY19wcm9iZSwKCS5yZW1vdmUJCT0gX19kZXZleGl0X3AoaWljX3JlbW92ZSksCiNpZiBkZWZpbmVkKENPTkZJR19QTSkKCS5zdXNwZW5kCT0gTlVMTCwKCS5yZXN1bWUJCT0gTlVMTCwKI2VuZGlmCn07CgpzdGF0aWMgaW50IF9faW5pdCBpaWNfaW5pdCh2b2lkKQp7CglwcmludGsoS0VSTl9JTkZPICJJQk0gSUlDIGRyaXZlciB2IiBEUklWRVJfVkVSU0lPTiAiXG4iKTsKCXJldHVybiBvY3BfcmVnaXN0ZXJfZHJpdmVyKCZpYm1faWljX2RyaXZlcik7Cn0KCnN0YXRpYyB2b2lkIF9fZXhpdCBpaWNfZXhpdCh2b2lkKQp7CglvY3BfdW5yZWdpc3Rlcl9kcml2ZXIoJmlibV9paWNfZHJpdmVyKTsKfQoKbW9kdWxlX2luaXQoaWljX2luaXQpOwptb2R1bGVfZXhpdChpaWNfZXhpdCk7Cg==