LyoKICogIGFzdXNfYWNwaS5jIC0gQXN1cyBMYXB0b3AgQUNQSSBFeHRyYXMKICoKICoKICogIENvcHlyaWdodCAoQykgMjAwMi0yMDA1IEp1bGllbiBMZXJvdWdlLCAyMDAzLTIwMDYgS2Fyb2wgS296aW1vcgogKgogKiAgVGhpcyBwcm9ncmFtIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkKICogIGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5CiAqICB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIgdmVyc2lvbiAyIG9mIHRoZSBMaWNlbnNlLCBvcgogKiAgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KICoKICogIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiAgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUKICogIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCiAqCiAqICBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiAgYWxvbmcgd2l0aCB0aGlzIHByb2dyYW07IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogIEZvdW5kYXRpb24sIEluYy4sIDU5IFRlbXBsZSBQbGFjZSwgU3VpdGUgMzMwLCBCb3N0b24sIE1BICAwMjExMS0xMzA3ICBVU0EKICoKICoKICogIFRoZSBkZXZlbG9wbWVudCBwYWdlIGZvciB0aGlzIGRyaXZlciBpcyBsb2NhdGVkIGF0CiAqICBodHRwOi8vc291cmNlZm9yZ2UubmV0L3Byb2plY3RzL2FjcGk0YXN1cy8KICoKICogIENyZWRpdHM6CiAqICBQb250dXMgRnVjaHMgICAtIEhlbHBlciBmdW5jdGlvbnMsIGNsZWFudXAKICogIEpvaGFubiBXaWVzbmVyIC0gU21hbGwgY29tcGlsZSBmaXhlcwogKiAgSm9obiBCZWxtb250ZSAgLSBBQ1BJIGNvZGUgZm9yIFRvc2hpYmEgbGFwdG9wIHdhcyBhIGdvb2Qgc3RhcnRpbmcgcG9pbnQuCiAqICDJcmljIEJ1cmdoYXJkICAtIExFRCBkaXNwbGF5IHN1cHBvcnQgZm9yIFcxTgogKgogKi8KCiNpbmNsdWRlIDxsaW51eC9rZXJuZWwuaD4KI2luY2x1ZGUgPGxpbnV4L21vZHVsZS5oPgojaW5jbHVkZSA8bGludXgvaW5pdC5oPgojaW5jbHVkZSA8bGludXgvdHlwZXMuaD4KI2luY2x1ZGUgPGxpbnV4L3Byb2NfZnMuaD4KI2luY2x1ZGUgPGxpbnV4L2JhY2tsaWdodC5oPgojaW5jbHVkZSA8YWNwaS9hY3BpX2RyaXZlcnMuaD4KI2luY2x1ZGUgPGFjcGkvYWNwaV9idXMuaD4KI2luY2x1ZGUgPGFzbS91YWNjZXNzLmg+CgojZGVmaW5lIEFTVVNfQUNQSV9WRVJTSU9OICIwLjMwIgoKI2RlZmluZSBQUk9DX0FTVVMgICAgICAgImFzdXMiCS8vdGhlIGRpcmVjdG9yeQojZGVmaW5lIFBST0NfTUxFRCAgICAgICAibWxlZCIKI2RlZmluZSBQUk9DX1dMRUQgICAgICAgIndsZWQiCiNkZWZpbmUgUFJPQ19UTEVEICAgICAgICJ0bGVkIgojZGVmaW5lIFBST0NfQlQgICAgICAgICAiYmx1ZXRvb3RoIgojZGVmaW5lIFBST0NfTEVERCAgICAgICAibGVkZCIKI2RlZmluZSBQUk9DX0lORk8gICAgICAgImluZm8iCiNkZWZpbmUgUFJPQ19MQ0QgICAgICAgICJsY2QiCiNkZWZpbmUgUFJPQ19CUk4gICAgICAgICJicm4iCiNkZWZpbmUgUFJPQ19ESVNQICAgICAgICJkaXNwIgoKI2RlZmluZSBBQ1BJX0hPVEtfTkFNRSAgICAgICAgICAiQXN1cyBMYXB0b3AgQUNQSSBFeHRyYXMgRHJpdmVyIgojZGVmaW5lIEFDUElfSE9US19DTEFTUyAgICAgICAgICJob3RrZXkiCiNkZWZpbmUgQUNQSV9IT1RLX0RFVklDRV9OQU1FICAgIkhvdGtleSIKI2RlZmluZSBBQ1BJX0hPVEtfSElEICAgICAgICAgICAiQVRLMDEwMCIKCi8qCiAqIFNvbWUgZXZlbnRzIHdlIHVzZSwgc2FtZSBmb3IgYWxsIEFzdXMKICovCiNkZWZpbmUgQlJfVVAgICAgICAgMHgxMAojZGVmaW5lIEJSX0RPV04gICAgIDB4MjAKCi8qCiAqIEZsYWdzIGZvciBob3RrIHN0YXR1cwogKi8KI2RlZmluZSBNTEVEX09OICAgICAweDAxCS8vbWFpbCBMRUQKI2RlZmluZSBXTEVEX09OICAgICAweDAyCS8vd2lyZWxlc3MgTEVECiNkZWZpbmUgVExFRF9PTiAgICAgMHgwNAkvL3RvdWNocGFkIExFRAojZGVmaW5lIEJUX09OICAgICAgIDB4MDgJLy9pbnRlcm5hbCBCbHVldG9vdGgKCk1PRFVMRV9BVVRIT1IoIkp1bGllbiBMZXJvdWdlLCBLYXJvbCBLb3ppbW9yIik7Ck1PRFVMRV9ERVNDUklQVElPTihBQ1BJX0hPVEtfTkFNRSk7Ck1PRFVMRV9MSUNFTlNFKCJHUEwiKTsKCnN0YXRpYyB1aWRfdCBhc3VzX3VpZDsKc3RhdGljIGdpZF90IGFzdXNfZ2lkOwptb2R1bGVfcGFyYW0oYXN1c191aWQsIHVpbnQsIDApOwpNT0RVTEVfUEFSTV9ERVNDKGFzdXNfdWlkLCAiVUlEIGZvciBlbnRyaWVzIGluIC9wcm9jL2FjcGkvYXN1cy5cbiIpOwptb2R1bGVfcGFyYW0oYXN1c19naWQsIHVpbnQsIDApOwpNT0RVTEVfUEFSTV9ERVNDKGFzdXNfZ2lkLCAiR0lEIGZvciBlbnRyaWVzIGluIC9wcm9jL2FjcGkvYXN1cy5cbiIpOwoKLyogRm9yIGVhY2ggbW9kZWwsIGFsbCBmZWF0dXJlcyBpbXBsZW1lbnRlZCwgCiAqIHRob3NlIG1hcmtlZCB3aXRoIFIgYXJlIHJlbGF0aXZlIHRvIEhPVEssIEEgZm9yIGFic29sdXRlICovCnN0cnVjdCBtb2RlbF9kYXRhIHsKCWNoYXIgKm5hbWU7CQkvL25hbWUgb2YgdGhlIGxhcHRvcF9fX19fX19fX19fX19fX19BCgljaGFyICptdF9tbGVkOwkJLy9tZXRob2QgdG8gaGFuZGxlIG1sZWRfX19fX19fX19fX19fUgoJY2hhciAqbWxlZF9zdGF0dXM7CS8vbm9kZSB0byBoYW5kbGUgbWxlZCByZWFkaW5nX19fX19fX0EKCWNoYXIgKm10X3dsZWQ7CQkvL21ldGhvZCB0byBoYW5kbGUgd2xlZF9fX19fX19fX19fX19SCgljaGFyICp3bGVkX3N0YXR1czsJLy9ub2RlIHRvIGhhbmRsZSB3bGVkIHJlYWRpbmdfX19fX19fQQoJY2hhciAqbXRfdGxlZDsJCS8vbWV0aG9kIHRvIGhhbmRsZSB0bGVkX19fX19fX19fX19fX1IKCWNoYXIgKnRsZWRfc3RhdHVzOwkvL25vZGUgdG8gaGFuZGxlIHRsZWQgcmVhZGluZ19fX19fX19BCgljaGFyICptdF9sZWRkOwkJLy9tZXRob2QgdG8gaGFuZGxlIExFRCBkaXNwbGF5X19fX19fUgoJY2hhciAqbXRfYnRfc3dpdGNoOwkvL21ldGhvZCB0byBzd2l0Y2ggQmx1ZXRvb3RoIG9uL29mZl9SCgljaGFyICpidF9zdGF0dXM7CS8vbm8gbW9kZWwgY3VycmVudGx5IHN1cHBvcnRzIHRoaXNfXz8KCWNoYXIgKm10X2xjZF9zd2l0Y2g7CS8vbWV0aG9kIHRvIHR1cm4gTENEIG9uL29mZl9fX19fX19fX0EKCWNoYXIgKmxjZF9zdGF0dXM7CS8vbm9kZSB0byByZWFkIExDRCBwYW5lbCBzdGF0ZV9fX19fX0EKCWNoYXIgKmJyaWdodG5lc3NfdXA7CS8vbWV0aG9kIHRvIHNldCBicmlnaHRuZXNzIHVwX19fX19fX0EKCWNoYXIgKmJyaWdodG5lc3NfZG93bjsJLy9ndWVzcyB3aGF0ID9fX19fX19fX19fX19fX19fX19fX19fQQoJY2hhciAqYnJpZ2h0bmVzc19zZXQ7CS8vbWV0aG9kIHRvIHNldCBhYnNvbHV0ZSBicmlnaHRuZXNzX1IKCWNoYXIgKmJyaWdodG5lc3NfZ2V0OwkvL21ldGhvZCB0byBnZXQgYWJzb2x1dGUgYnJpZ2h0bmVzc19SCgljaGFyICpicmlnaHRuZXNzX3N0YXR1czsJLy9ub2RlIHRvIGdldCBicmlnaHRuZXNzX19fX19fX19fX19fQQoJY2hhciAqZGlzcGxheV9zZXQ7CS8vbWV0aG9kIHRvIHNldCB2aWRlbyBvdXRwdXRfX19fX19fX1IKCWNoYXIgKmRpc3BsYXlfZ2V0OwkvL21ldGhvZCB0byBnZXQgdmlkZW8gb3V0cHV0X19fX19fX19SCn07CgovKgogKiBUaGlzIGlzIHRoZSBtYWluIHN0cnVjdHVyZSwgd2UgY2FuIHVzZSBpdCB0byBzdG9yZSBhbnl0aGluZyBpbnRlcmVzdGluZwogKiBhYm91dCB0aGUgaG90ayBkZXZpY2UKICovCnN0cnVjdCBhc3VzX2hvdGsgewoJc3RydWN0IGFjcGlfZGV2aWNlICpkZXZpY2U7CS8vdGhlIGRldmljZSB3ZSBhcmUgaW4KCWFjcGlfaGFuZGxlIGhhbmRsZTsJLy90aGUgaGFuZGxlIG9mIHRoZSBob3RrIGRldmljZQoJY2hhciBzdGF0dXM7CQkvL3N0YXR1cyBvZiB0aGUgaG90aywgZm9yIExFRHMsIC4uLgoJdTMyIGxlZGRfc3RhdHVzOwkvL3N0YXR1cyBvZiB0aGUgTEVEIGRpc3BsYXkKCXN0cnVjdCBtb2RlbF9kYXRhICptZXRob2RzOwkvL21ldGhvZHMgYXZhaWxhYmxlIG9uIHRoZSBsYXB0b3AKCXU4IGJyaWdodG5lc3M7CQkvL2JyaWdodG5lc3MgbGV2ZWwKCWVudW0gewoJCUExeCA9IDAsCS8vQTEzNDBELCBBMTMwMEYKCQlBMngsCQkvL0EyNTAwSAoJCUE0RywJCS8vQTQ3MDBHCgkJRDF4LAkJLy9EMQoJCUwyRCwJCS8vTDIwMDBECgkJTDNDLAkJLy9MMzgwMEMKCQlMM0QsCQkvL0wzNDAwRAoJCUwzSCwJCS8vTDNILCBMMjAwMEUsIEw1RAoJCUw0UiwJCS8vTDQ1MDBSCgkJTDV4LAkJLy9MNTgwMEMgCgkJTDhMLAkJLy9MODQwMEwKCQlNMUEsCQkvL00xMzAwQQoJCU0yRSwJCS8vTTI0MDBFLCBMNDQwMEwKCQlNNk4sCQkvL002ODAwTiwgVzM0MDBOCgkJTTZSLAkJLy9NNjcwMFIsIEEzMDAwRwoJCVAzMCwJCS8vU2Ftc3VuZyBQMzAKCQlTMXgsCQkvL1MxMzAwQSwgYnV0IGFsc28gTDE0MDBCIGFuZCBNMjQwMEEgKEw4NEYpCgkJUzJ4LAkJLy9TMjAwIChKMSByZXBvcnRlZCksIFZpY3RvciBNUC1YUDcyMTAKCQlXMU4sCQkvL1cxMDAwTgoJCVc1QSwJCS8vVzVBCgkJVzNWLCAgICAgICAgICAgIC8vVzMwMzBWCgkJeHhOLAkJLy9NMjQwME4sIE0zNzAwTiwgTTUyMDBOLCBNNjgwME4sIFMxMzAwTiwgUzUyMDBOCgkJLy8oQ2VudHJpbm8pCgkJRU5EX01PREVMCgl9IG1vZGVsOwkJLy9Nb2RlbHMgY3VycmVudGx5IHN1cHBvcnRlZAoJdTE2IGV2ZW50X2NvdW50WzEyOF07CS8vY291bnQgZm9yIGVhY2ggZXZlbnQgVE9ETyBtYWtlIHRoaXMgYmV0dGVyCn07CgovKiBIZXJlIHdlIGdvICovCiNkZWZpbmUgQTF4X1BSRUZJWCAiXFxfU0IuUENJMC5JU0EuRUMwLiIKI2RlZmluZSBMM0NfUFJFRklYICJcXF9TQi5QQ0kwLlBYNDAuRUNEMC4iCiNkZWZpbmUgTTFBX1BSRUZJWCAiXFxfU0IuUENJMC5QWDQwLkVDMC4iCiNkZWZpbmUgUDMwX1BSRUZJWCAiXFxfU0IuUENJMC5MUENCLkVDMC4iCiNkZWZpbmUgUzF4X1BSRUZJWCAiXFxfU0IuUENJMC5QWDQwLiIKI2RlZmluZSBTMnhfUFJFRklYIEExeF9QUkVGSVgKI2RlZmluZSB4eE5fUFJFRklYICJcXF9TQi5QQ0kwLlNCUkcuRUMwLiIKCnN0YXRpYyBzdHJ1Y3QgbW9kZWxfZGF0YSBtb2RlbF9jb25mW0VORF9NT0RFTF0gPSB7CgkvKgoJICogVE9ETyBJIGhhdmUgc2VlbiBhIFNXQlggYW5kIEFJQlggbWV0aG9kIG9uIHNvbWUgbW9kZWxzLCBsaWtlIEwxNDAwQiwKCSAqIGl0IHNlZW1zIHRvIGJlIGEga2luZCBvZiBzd2l0Y2gsIGJ1dCB3aGF0IGZvciA/CgkgKi8KCgl7CgkgLm5hbWUgPSAiQTF4IiwKCSAubXRfbWxlZCA9ICJNTEVEIiwKCSAubWxlZF9zdGF0dXMgPSAiXFxNQUlMIiwKCSAubXRfbGNkX3N3aXRjaCA9IEExeF9QUkVGSVggIl9RMTAiLAoJIC5sY2Rfc3RhdHVzID0gIlxcQktMSSIsCgkgLmJyaWdodG5lc3NfdXAgPSBBMXhfUFJFRklYICJfUTBFIiwKCSAuYnJpZ2h0bmVzc19kb3duID0gQTF4X1BSRUZJWCAiX1EwRiJ9LAoKCXsKCSAubmFtZSA9ICJBMngiLAoJIC5tdF9tbGVkID0gIk1MRUQiLAoJIC5tdF93bGVkID0gIldMRUQiLAoJIC53bGVkX3N0YXR1cyA9ICJcXFNHNjYiLAoJIC5tdF9sY2Rfc3dpdGNoID0gIlxcUTEwIiwKCSAubGNkX3N0YXR1cyA9ICJcXEJBT0YiLAoJIC5icmlnaHRuZXNzX3NldCA9ICJTUExWIiwKCSAuYnJpZ2h0bmVzc19nZXQgPSAiR1BMViIsCgkgLmRpc3BsYXlfc2V0ID0gIlNEU1AiLAoJIC5kaXNwbGF5X2dldCA9ICJcXElORkIifSwKCgl7CgkgLm5hbWUgPSAiQTRHIiwKCSAubXRfbWxlZCA9ICJNTEVEIiwKLyogV0xFRCBwcmVzZW50LCBidXQgbm90IGNvbnRyb2xsZWQgYnkgQUNQSSAqLwoJIC5tdF9sY2Rfc3dpdGNoID0geHhOX1BSRUZJWCAiX1ExMCIsCgkgLmJyaWdodG5lc3Nfc2V0ID0gIlNQTFYiLAoJIC5icmlnaHRuZXNzX2dldCA9ICJHUExWIiwKCSAuZGlzcGxheV9zZXQgPSAiU0RTUCIsCgkgLmRpc3BsYXlfZ2V0ID0gIlxcQURWRyJ9LAoKCXsKCSAubmFtZSA9ICJEMXgiLAoJIC5tdF9tbGVkID0gIk1MRUQiLAoJIC5tdF9sY2Rfc3dpdGNoID0gIlxcUTBEIiwKCSAubGNkX3N0YXR1cyA9ICJcXEdQMTEiLAoJIC5icmlnaHRuZXNzX3VwID0gIlxcUTBDIiwKCSAuYnJpZ2h0bmVzc19kb3duID0gIlxcUTBCIiwKCSAuYnJpZ2h0bmVzc19zdGF0dXMgPSAiXFxCTFZMIiwKCSAuZGlzcGxheV9zZXQgPSAiU0RTUCIsCgkgLmRpc3BsYXlfZ2V0ID0gIlxcSU5GQiJ9LAoKCXsKCSAubmFtZSA9ICJMMkQiLAoJIC5tdF9tbGVkID0gIk1MRUQiLAoJIC5tbGVkX3N0YXR1cyA9ICJcXFNHUDYiLAoJIC5tdF93bGVkID0gIldMRUQiLAoJIC53bGVkX3N0YXR1cyA9ICJcXFJDUDMiLAoJIC5tdF9sY2Rfc3dpdGNoID0gIlxcUTEwIiwKCSAubGNkX3N0YXR1cyA9ICJcXFNHUDAiLAoJIC5icmlnaHRuZXNzX3VwID0gIlxcUTBFIiwKCSAuYnJpZ2h0bmVzc19kb3duID0gIlxcUTBGIiwKCSAuZGlzcGxheV9zZXQgPSAiU0RTUCIsCgkgLmRpc3BsYXlfZ2V0ID0gIlxcSU5GQiJ9LAoKCXsKCSAubmFtZSA9ICJMM0MiLAoJIC5tdF9tbGVkID0gIk1MRUQiLAoJIC5tdF93bGVkID0gIldMRUQiLAoJIC5tdF9sY2Rfc3dpdGNoID0gTDNDX1BSRUZJWCAiX1ExMCIsCgkgLmxjZF9zdGF0dXMgPSAiXFxHTDMyIiwKCSAuYnJpZ2h0bmVzc19zZXQgPSAiU1BMViIsCgkgLmJyaWdodG5lc3NfZ2V0ID0gIkdQTFYiLAoJIC5kaXNwbGF5X3NldCA9ICJTRFNQIiwKCSAuZGlzcGxheV9nZXQgPSAiXFxfU0IuUENJMC5QQ0kxLlZHQUMuTk1BUCJ9LAoKCXsKCSAubmFtZSA9ICJMM0QiLAoJIC5tdF9tbGVkID0gIk1MRUQiLAoJIC5tbGVkX3N0YXR1cyA9ICJcXE1BTEQiLAoJIC5tdF93bGVkID0gIldMRUQiLAoJIC5tdF9sY2Rfc3dpdGNoID0gIlxcUTEwIiwKCSAubGNkX3N0YXR1cyA9ICJcXEJLTEciLAoJIC5icmlnaHRuZXNzX3NldCA9ICJTUExWIiwKCSAuYnJpZ2h0bmVzc19nZXQgPSAiR1BMViIsCgkgLmRpc3BsYXlfc2V0ID0gIlNEU1AiLAoJIC5kaXNwbGF5X2dldCA9ICJcXElORkIifSwKCgl7CgkgLm5hbWUgPSAiTDNIIiwKCSAubXRfbWxlZCA9ICJNTEVEIiwKCSAubXRfd2xlZCA9ICJXTEVEIiwKCSAubXRfbGNkX3N3aXRjaCA9ICJFSEsiLAoJIC5sY2Rfc3RhdHVzID0gIlxcX1NCLlBDSTAuUE0uUEJDIiwKCSAuYnJpZ2h0bmVzc19zZXQgPSAiU1BMViIsCgkgLmJyaWdodG5lc3NfZ2V0ID0gIkdQTFYiLAoJIC5kaXNwbGF5X3NldCA9ICJTRFNQIiwKCSAuZGlzcGxheV9nZXQgPSAiXFxJTkZCIn0sCgoJewoJIC5uYW1lID0gIkw0UiIsCgkgLm10X21sZWQgPSAiTUxFRCIsCgkgLm10X3dsZWQgPSAiV0xFRCIsCgkgLndsZWRfc3RhdHVzID0gIlxcX1NCLlBDSTAuU0JSRy5TRzEzIiwKCSAubXRfbGNkX3N3aXRjaCA9IHh4Tl9QUkVGSVggIl9RMTAiLAoJIC5sY2Rfc3RhdHVzID0gIlxcX1NCLlBDSTAuU0JTTS5TRU80IiwKCSAuYnJpZ2h0bmVzc19zZXQgPSAiU1BMViIsCgkgLmJyaWdodG5lc3NfZ2V0ID0gIkdQTFYiLAoJIC5kaXNwbGF5X3NldCA9ICJTRFNQIiwKCSAuZGlzcGxheV9nZXQgPSAiXFxfU0IuUENJMC5QMFAxLlZHQS5HRVREIn0sCgoJewoJIC5uYW1lID0gIkw1eCIsCgkgLm10X21sZWQgPSAiTUxFRCIsCi8qIFdMRUQgcHJlc2VudCwgYnV0IG5vdCBjb250cm9sbGVkIGJ5IEFDUEkgKi8KCSAubXRfdGxlZCA9ICJUTEVEIiwKCSAubXRfbGNkX3N3aXRjaCA9ICJcXFEwRCIsCgkgLmxjZF9zdGF0dXMgPSAiXFxCQU9GIiwKCSAuYnJpZ2h0bmVzc19zZXQgPSAiU1BMViIsCgkgLmJyaWdodG5lc3NfZ2V0ID0gIkdQTFYiLAoJIC5kaXNwbGF5X3NldCA9ICJTRFNQIiwKCSAuZGlzcGxheV9nZXQgPSAiXFxJTkZCIn0sCgoJewoJIC5uYW1lID0gIkw4TCIKLyogTm8gZmVhdHVyZXMsIGJ1dCBhdCBsZWFzdCBzdXBwb3J0IHRoZSBob3RrZXlzICovCgkgfSwKCgl7CgkgLm5hbWUgPSAiTTFBIiwKCSAubXRfbWxlZCA9ICJNTEVEIiwKCSAubXRfbGNkX3N3aXRjaCA9IE0xQV9QUkVGSVggIlExMCIsCgkgLmxjZF9zdGF0dXMgPSAiXFxQTk9GIiwKCSAuYnJpZ2h0bmVzc191cCA9IE0xQV9QUkVGSVggIlEwRSIsCgkgLmJyaWdodG5lc3NfZG93biA9IE0xQV9QUkVGSVggIlEwRiIsCgkgLmJyaWdodG5lc3Nfc3RhdHVzID0gIlxcQlJJVCIsCgkgLmRpc3BsYXlfc2V0ID0gIlNEU1AiLAoJIC5kaXNwbGF5X2dldCA9ICJcXElORkIifSwKCgl7CgkgLm5hbWUgPSAiTTJFIiwKCSAubXRfbWxlZCA9ICJNTEVEIiwKCSAubXRfd2xlZCA9ICJXTEVEIiwKCSAubXRfbGNkX3N3aXRjaCA9ICJcXFExMCIsCgkgLmxjZF9zdGF0dXMgPSAiXFxHUDA2IiwKCSAuYnJpZ2h0bmVzc19zZXQgPSAiU1BMViIsCgkgLmJyaWdodG5lc3NfZ2V0ID0gIkdQTFYiLAoJIC5kaXNwbGF5X3NldCA9ICJTRFNQIiwKCSAuZGlzcGxheV9nZXQgPSAiXFxJTkZCIn0sCgoJewoJIC5uYW1lID0gIk02TiIsCgkgLm10X21sZWQgPSAiTUxFRCIsCgkgLm10X3dsZWQgPSAiV0xFRCIsCgkgLndsZWRfc3RhdHVzID0gIlxcX1NCLlBDSTAuU0JSRy5TRzEzIiwKCSAubXRfbGNkX3N3aXRjaCA9IHh4Tl9QUkVGSVggIl9RMTAiLAoJIC5sY2Rfc3RhdHVzID0gIlxcX1NCLkJLTFQiLAoJIC5icmlnaHRuZXNzX3NldCA9ICJTUExWIiwKCSAuYnJpZ2h0bmVzc19nZXQgPSAiR1BMViIsCgkgLmRpc3BsYXlfc2V0ID0gIlNEU1AiLAoJIC5kaXNwbGF5X2dldCA9ICJcXFNTVEUifSwKCgl7CgkgLm5hbWUgPSAiTTZSIiwKCSAubXRfbWxlZCA9ICJNTEVEIiwKCSAubXRfd2xlZCA9ICJXTEVEIiwKCSAubXRfbGNkX3N3aXRjaCA9IHh4Tl9QUkVGSVggIl9RMTAiLAoJIC5sY2Rfc3RhdHVzID0gIlxcX1NCLlBDSTAuU0JTTS5TRU80IiwKCSAuYnJpZ2h0bmVzc19zZXQgPSAiU1BMViIsCgkgLmJyaWdodG5lc3NfZ2V0ID0gIkdQTFYiLAoJIC5kaXNwbGF5X3NldCA9ICJTRFNQIiwKCSAuZGlzcGxheV9nZXQgPSAiXFxfU0IuUENJMC5QMFAxLlZHQS5HRVREIn0sCgoJewoJIC5uYW1lID0gIlAzMCIsCgkgLm10X3dsZWQgPSAiV0xFRCIsCgkgLm10X2xjZF9zd2l0Y2ggPSBQMzBfUFJFRklYICJfUTBFIiwKCSAubGNkX3N0YXR1cyA9ICJcXEJLTFQiLAoJIC5icmlnaHRuZXNzX3VwID0gUDMwX1BSRUZJWCAiX1E2OCIsCgkgLmJyaWdodG5lc3NfZG93biA9IFAzMF9QUkVGSVggIl9RNjkiLAoJIC5icmlnaHRuZXNzX2dldCA9ICJHUExWIiwKCSAuZGlzcGxheV9zZXQgPSAiU0RTUCIsCgkgLmRpc3BsYXlfZ2V0ID0gIlxcRE5YVCJ9LAoKCXsKCSAubmFtZSA9ICJTMXgiLAoJIC5tdF9tbGVkID0gIk1MRUQiLAoJIC5tbGVkX3N0YXR1cyA9ICJcXEVNTEUiLAoJIC5tdF93bGVkID0gIldMRUQiLAoJIC5tdF9sY2Rfc3dpdGNoID0gUzF4X1BSRUZJWCAiUTEwIiwKCSAubGNkX3N0YXR1cyA9ICJcXFBOT0YiLAoJIC5icmlnaHRuZXNzX3NldCA9ICJTUExWIiwKCSAuYnJpZ2h0bmVzc19nZXQgPSAiR1BMViJ9LAoKCXsKCSAubmFtZSA9ICJTMngiLAoJIC5tdF9tbGVkID0gIk1MRUQiLAoJIC5tbGVkX3N0YXR1cyA9ICJcXE1BSUwiLAoJIC5tdF9sY2Rfc3dpdGNoID0gUzJ4X1BSRUZJWCAiX1ExMCIsCgkgLmxjZF9zdGF0dXMgPSAiXFxCS0xJIiwKCSAuYnJpZ2h0bmVzc191cCA9IFMyeF9QUkVGSVggIl9RMEIiLAoJIC5icmlnaHRuZXNzX2Rvd24gPSBTMnhfUFJFRklYICJfUTBBIn0sCgoJewoJIC5uYW1lID0gIlcxTiIsCgkgLm10X21sZWQgPSAiTUxFRCIsCgkgLm10X3dsZWQgPSAiV0xFRCIsCgkgLm10X2xlZGQgPSAiU0xDTSIsCgkgLm10X2xjZF9zd2l0Y2ggPSB4eE5fUFJFRklYICJfUTEwIiwKCSAubGNkX3N0YXR1cyA9ICJcXEJLTFQiLAoJIC5icmlnaHRuZXNzX3NldCA9ICJTUExWIiwKCSAuYnJpZ2h0bmVzc19nZXQgPSAiR1BMViIsCgkgLmRpc3BsYXlfc2V0ID0gIlNEU1AiLAoJIC5kaXNwbGF5X2dldCA9ICJcXEFEVkcifSwKCgl7CgkgLm5hbWUgPSAiVzVBIiwKCSAubXRfYnRfc3dpdGNoID0gIkJMRUQiLAoJIC5tdF93bGVkID0gIldMRUQiLAoJIC5tdF9sY2Rfc3dpdGNoID0geHhOX1BSRUZJWCAiX1ExMCIsCgkgLmJyaWdodG5lc3Nfc2V0ID0gIlNQTFYiLAoJIC5icmlnaHRuZXNzX2dldCA9ICJHUExWIiwKCSAuZGlzcGxheV9zZXQgPSAiU0RTUCIsCgkgLmRpc3BsYXlfZ2V0ID0gIlxcQURWRyJ9LAoKCXsKCSAubmFtZSA9ICJXM1YiLAoJIC5tdF9tbGVkID0gIk1MRUQiLAoJIC5tdF93bGVkID0gIldMRUQiLAoJIC5tdF9sY2Rfc3dpdGNoID0geHhOX1BSRUZJWCAiX1ExMCIsCgkgLmxjZF9zdGF0dXMgPSAiXFxCS0xUIiwKCSAuYnJpZ2h0bmVzc19zZXQgPSAiU1BMViIsCgkgLmJyaWdodG5lc3NfZ2V0ID0gIkdQTFYiLAoJIC5kaXNwbGF5X3NldCA9ICJTRFNQIiwKCSAuZGlzcGxheV9nZXQgPSAiXFxJTkZCIn0sCgogICAgICAgewoJIC5uYW1lID0gInh4TiIsCgkgLm10X21sZWQgPSAiTUxFRCIsCi8qIFdMRUQgcHJlc2VudCwgYnV0IG5vdCBjb250cm9sbGVkIGJ5IEFDUEkgKi8KCSAubXRfbGNkX3N3aXRjaCA9IHh4Tl9QUkVGSVggIl9RMTAiLAoJIC5sY2Rfc3RhdHVzID0gIlxcQktMVCIsCgkgLmJyaWdodG5lc3Nfc2V0ID0gIlNQTFYiLAoJIC5icmlnaHRuZXNzX2dldCA9ICJHUExWIiwKCSAuZGlzcGxheV9zZXQgPSAiU0RTUCIsCgkgLmRpc3BsYXlfZ2V0ID0gIlxcQURWRyJ9Cn07CgovKiBwcm9jZGlyIHdlIHVzZSAqLwpzdGF0aWMgc3RydWN0IHByb2NfZGlyX2VudHJ5ICphc3VzX3Byb2NfZGlyOwoKc3RhdGljIHN0cnVjdCBiYWNrbGlnaHRfZGV2aWNlICphc3VzX2JhY2tsaWdodF9kZXZpY2U7CgovKgogKiBUaGlzIGhlYWRlciBpcyBtYWRlIGF2YWlsYWJsZSB0byBhbGxvdyBwcm9wZXIgY29uZmlndXJhdGlvbiBnaXZlbiBtb2RlbCwKICogcmV2aXNpb24gbnVtYmVyICwgLi4uIHRoaXMgaW5mbyBjYW5ub3QgZ28gaW4gc3RydWN0IGFzdXNfaG90ayBiZWNhdXNlIGl0IGlzCiAqIGF2YWlsYWJsZSBiZWZvcmUgdGhlIGhvdGsKICovCnN0YXRpYyBzdHJ1Y3QgYWNwaV90YWJsZV9oZWFkZXIgKmFzdXNfaW5mbzsKCi8qIFRoZSBhY3R1YWwgZGV2aWNlIHRoZSBkcml2ZXIgYmluZHMgdG8gKi8Kc3RhdGljIHN0cnVjdCBhc3VzX2hvdGsgKmhvdGs7CgovKgogKiBUaGUgaG90a2V5IGRyaXZlciBkZWNsYXJhdGlvbgogKi8Kc3RhdGljIGludCBhc3VzX2hvdGtfYWRkKHN0cnVjdCBhY3BpX2RldmljZSAqZGV2aWNlKTsKc3RhdGljIGludCBhc3VzX2hvdGtfcmVtb3ZlKHN0cnVjdCBhY3BpX2RldmljZSAqZGV2aWNlLCBpbnQgdHlwZSk7CnN0YXRpYyBzdHJ1Y3QgYWNwaV9kcml2ZXIgYXN1c19ob3RrX2RyaXZlciA9IHsKCS5uYW1lID0gQUNQSV9IT1RLX05BTUUsCgkuY2xhc3MgPSBBQ1BJX0hPVEtfQ0xBU1MsCgkuaWRzID0gQUNQSV9IT1RLX0hJRCwKCS5vcHMgPSB7CgkJLmFkZCA9IGFzdXNfaG90a19hZGQsCgkJLnJlbW92ZSA9IGFzdXNfaG90a19yZW1vdmUsCgkJfSwKfTsKCi8qIAogKiBUaGlzIGZ1bmN0aW9uIGV2YWx1YXRlcyBhbiBBQ1BJIG1ldGhvZCwgZ2l2ZW4gYW4gaW50IGFzIHBhcmFtZXRlciwgdGhlCiAqIG1ldGhvZCBpcyBzZWFyY2hlZCB3aXRoaW4gdGhlIHNjb3BlIG9mIHRoZSBoYW5kbGUsIGNhbiBiZSBOVUxMLiBUaGUgb3V0cHV0CiAqIG9mIHRoZSBtZXRob2QgaXMgd3JpdHRlbiBpcyBvdXRwdXQsIHdoaWNoIGNhbiBhbHNvIGJlIE5VTEwKICoKICogcmV0dXJucyAxIGlmIHdyaXRlIGlzIHN1Y2Nlc3NmdWwsIDAgZWxzZS4gCiAqLwpzdGF0aWMgaW50IHdyaXRlX2FjcGlfaW50KGFjcGlfaGFuZGxlIGhhbmRsZSwgY29uc3QgY2hhciAqbWV0aG9kLCBpbnQgdmFsLAoJCQkgIHN0cnVjdCBhY3BpX2J1ZmZlciAqb3V0cHV0KQp7CglzdHJ1Y3QgYWNwaV9vYmplY3RfbGlzdCBwYXJhbXM7CS8vbGlzdCBvZiBpbnB1dCBwYXJhbWV0ZXJzIChhbiBpbnQgaGVyZSkKCXVuaW9uIGFjcGlfb2JqZWN0IGluX29iajsJLy90aGUgb25seSBwYXJhbSB3ZSB1c2UKCWFjcGlfc3RhdHVzIHN0YXR1czsKCglwYXJhbXMuY291bnQgPSAxOwoJcGFyYW1zLnBvaW50ZXIgPSAmaW5fb2JqOwoJaW5fb2JqLnR5cGUgPSBBQ1BJX1RZUEVfSU5URUdFUjsKCWluX29iai5pbnRlZ2VyLnZhbHVlID0gdmFsOwoKCXN0YXR1cyA9IGFjcGlfZXZhbHVhdGVfb2JqZWN0KGhhbmRsZSwgKGNoYXIgKiltZXRob2QsICZwYXJhbXMsIG91dHB1dCk7CglyZXR1cm4gKHN0YXR1cyA9PSBBRV9PSyk7Cn0KCnN0YXRpYyBpbnQgcmVhZF9hY3BpX2ludChhY3BpX2hhbmRsZSBoYW5kbGUsIGNvbnN0IGNoYXIgKm1ldGhvZCwgaW50ICp2YWwpCnsKCXN0cnVjdCBhY3BpX2J1ZmZlciBvdXRwdXQ7Cgl1bmlvbiBhY3BpX29iamVjdCBvdXRfb2JqOwoJYWNwaV9zdGF0dXMgc3RhdHVzOwoKCW91dHB1dC5sZW5ndGggPSBzaXplb2Yob3V0X29iaik7CglvdXRwdXQucG9pbnRlciA9ICZvdXRfb2JqOwoKCXN0YXR1cyA9IGFjcGlfZXZhbHVhdGVfb2JqZWN0KGhhbmRsZSwgKGNoYXIgKiltZXRob2QsIE5VTEwsICZvdXRwdXQpOwoJKnZhbCA9IG91dF9vYmouaW50ZWdlci52YWx1ZTsKCXJldHVybiAoc3RhdHVzID09IEFFX09LKSAmJiAob3V0X29iai50eXBlID09IEFDUElfVFlQRV9JTlRFR0VSKTsKfQoKLyoKICogV2Ugd3JpdGUgb3VyIGluZm8gaW4gcGFnZSwgd2UgYmVnaW4gYXQgb2Zmc2V0IG9mZiBhbmQgY2Fubm90IHdyaXRlIG1vcmUKICogdGhhbiBjb3VudCBieXRlcy4gV2Ugc2V0IGVvZiB0byAxIGlmIHdlIGhhbmRsZSB0aG9zZSAyIHZhbHVlcy4gV2UgcmV0dXJuIHRoZQogKiBudW1iZXIgb2YgYnl0ZXMgd3JpdHRlbiBpbiBwYWdlCiAqLwpzdGF0aWMgaW50CnByb2NfcmVhZF9pbmZvKGNoYXIgKnBhZ2UsIGNoYXIgKipzdGFydCwgb2ZmX3Qgb2ZmLCBpbnQgY291bnQsIGludCAqZW9mLAoJICAgICAgIHZvaWQgKmRhdGEpCnsKCWludCBsZW4gPSAwOwoJaW50IHRlbXA7CgljaGFyIGJ1ZlsxNl07CQkvL2Vub3VnaCBmb3IgYWxsIGluZm8KCS8qCgkgKiBXZSB1c2UgdGhlIGVhc3kgd2F5LCB3ZSBkb24ndCBjYXJlIG9mIG9mZiBhbmQgY291bnQsIHNvIHdlIGRvbid0IHNldCBlb2YKCSAqIHRvIDEKCSAqLwoKCWxlbiArPSBzcHJpbnRmKHBhZ2UsIEFDUElfSE9US19OQU1FICIgIiBBU1VTX0FDUElfVkVSU0lPTiAiXG4iKTsKCWxlbiArPSBzcHJpbnRmKHBhZ2UgKyBsZW4sICJNb2RlbCByZWZlcmVuY2UgICAgOiAlc1xuIiwKCQkgICAgICAgaG90ay0+bWV0aG9kcy0+bmFtZSk7CgkvKiAKCSAqIFRoZSBTRlVOIG1ldGhvZCBwcm9iYWJseSBhbGxvd3MgdGhlIG9yaWdpbmFsIGRyaXZlciB0byBnZXQgdGhlIGxpc3QgCgkgKiBvZiBmZWF0dXJlcyBzdXBwb3J0ZWQgYnkgYSBnaXZlbiBtb2RlbC4gRm9yIG5vdywgMHgwMTAwIG9yIDB4MDgwMCAKCSAqIGJpdCBzaWduaWZpZXMgdGhhdCB0aGUgbGFwdG9wIGlzIGVxdWlwcGVkIHdpdGggYSBXaS1GaSBNaW5pUENJIGNhcmQuCgkgKiBUaGUgc2lnbmlmaWNhbmNlIG9mIG90aGVycyBpcyB5ZXQgdG8gYmUgZm91bmQuCgkgKi8KCWlmIChyZWFkX2FjcGlfaW50KGhvdGstPmhhbmRsZSwgIlNGVU4iLCAmdGVtcCkpCgkJbGVuICs9CgkJICAgIHNwcmludGYocGFnZSArIGxlbiwgIlNGVU4gdmFsdWUgICAgICAgICA6IDB4JTA0eFxuIiwgdGVtcCk7CgkvKgoJICogQW5vdGhlciB2YWx1ZSBmb3IgdXNlcnNwYWNlOiB0aGUgQVNZTSBtZXRob2QgcmV0dXJucyAweDAyIGZvcgoJICogYmF0dGVyeSBsb3cgYW5kIDB4MDQgZm9yIGJhdHRlcnkgY3JpdGljYWwsIGl0cyByZWFkaW5ncyB0ZW5kIHRvIGJlCgkgKiBtb3JlIGFjY3VyYXRlIHRoYW4gdGhvc2UgcHJvdmlkZWQgYnkgX0JTVC4gCgkgKiBOb3RlOiBzaW5jZSBub3QgYWxsIHRoZSBsYXB0b3BzIHByb3ZpZGUgdGhpcyBtZXRob2QsIGVycm9ycyBhcmUKCSAqIHNpbGVudGx5IGlnbm9yZWQuCgkgKi8KCWlmIChyZWFkX2FjcGlfaW50KGhvdGstPmhhbmRsZSwgIkFTWU0iLCAmdGVtcCkpCgkJbGVuICs9CgkJICAgIHNwcmludGYocGFnZSArIGxlbiwgIkFTWU0gdmFsdWUgICAgICAgICA6IDB4JTA0eFxuIiwgdGVtcCk7CglpZiAoYXN1c19pbmZvKSB7CgkJc25wcmludGYoYnVmLCAxNiwgIiVkIiwgYXN1c19pbmZvLT5sZW5ndGgpOwoJCWxlbiArPSBzcHJpbnRmKHBhZ2UgKyBsZW4sICJEU0RUIGxlbmd0aCAgICAgICAgOiAlc1xuIiwgYnVmKTsKCQlzbnByaW50ZihidWYsIDE2LCAiJWQiLCBhc3VzX2luZm8tPmNoZWNrc3VtKTsKCQlsZW4gKz0gc3ByaW50ZihwYWdlICsgbGVuLCAiRFNEVCBjaGVja3N1bSAgICAgIDogJXNcbiIsIGJ1Zik7CgkJc25wcmludGYoYnVmLCAxNiwgIiVkIiwgYXN1c19pbmZvLT5yZXZpc2lvbik7CgkJbGVuICs9IHNwcmludGYocGFnZSArIGxlbiwgIkRTRFQgcmV2aXNpb24gICAgICA6ICVzXG4iLCBidWYpOwoJCXNucHJpbnRmKGJ1ZiwgNywgIiVzIiwgYXN1c19pbmZvLT5vZW1faWQpOwoJCWxlbiArPSBzcHJpbnRmKHBhZ2UgKyBsZW4sICJPRU0gaWQgICAgICAgICAgICAgOiAlc1xuIiwgYnVmKTsKCQlzbnByaW50ZihidWYsIDksICIlcyIsIGFzdXNfaW5mby0+b2VtX3RhYmxlX2lkKTsKCQlsZW4gKz0gc3ByaW50ZihwYWdlICsgbGVuLCAiT0VNIHRhYmxlIGlkICAgICAgIDogJXNcbiIsIGJ1Zik7CgkJc25wcmludGYoYnVmLCAxNiwgIiV4IiwgYXN1c19pbmZvLT5vZW1fcmV2aXNpb24pOwoJCWxlbiArPSBzcHJpbnRmKHBhZ2UgKyBsZW4sICJPRU0gcmV2aXNpb24gICAgICAgOiAweCVzXG4iLCBidWYpOwoJCXNucHJpbnRmKGJ1ZiwgNSwgIiVzIiwgYXN1c19pbmZvLT5hc2xfY29tcGlsZXJfaWQpOwoJCWxlbiArPSBzcHJpbnRmKHBhZ2UgKyBsZW4sICJBU0wgY29tcCB2ZW5kb3IgaWQgOiAlc1xuIiwgYnVmKTsKCQlzbnByaW50ZihidWYsIDE2LCAiJXgiLCBhc3VzX2luZm8tPmFzbF9jb21waWxlcl9yZXZpc2lvbik7CgkJbGVuICs9IHNwcmludGYocGFnZSArIGxlbiwgIkFTTCBjb21wIHJldmlzaW9uICA6IDB4JXNcbiIsIGJ1Zik7Cgl9CgoJcmV0dXJuIGxlbjsKfQoKLyoKICogL3Byb2MgaGFuZGxlcnMKICogV2Ugd3JpdGUgb3VyIGluZm8gaW4gcGFnZSwgd2UgYmVnaW4gYXQgb2Zmc2V0IG9mZiBhbmQgY2Fubm90IHdyaXRlIG1vcmUKICogdGhhbiBjb3VudCBieXRlcy4gV2Ugc2V0IGVvZiB0byAxIGlmIHdlIGhhbmRsZSB0aG9zZSAyIHZhbHVlcy4gV2UgcmV0dXJuIHRoZQogKiBudW1iZXIgb2YgYnl0ZXMgd3JpdHRlbiBpbiBwYWdlCiAqLwoKLyogR2VuZXJpYyBMRUQgZnVuY3Rpb25zICovCnN0YXRpYyBpbnQgcmVhZF9sZWQoY29uc3QgY2hhciAqbGVkbmFtZSwgaW50IGxlZG1hc2spCnsKCWlmIChsZWRuYW1lKSB7CgkJaW50IGxlZF9zdGF0dXM7CgoJCWlmIChyZWFkX2FjcGlfaW50KE5VTEwsIGxlZG5hbWUsICZsZWRfc3RhdHVzKSkKCQkJcmV0dXJuIGxlZF9zdGF0dXM7CgkJZWxzZQoJCQlwcmludGsoS0VSTl9XQVJOSU5HICJBc3VzIEFDUEk6IEVycm9yIHJlYWRpbmcgTEVEICIKCQkJICAgICAgICJzdGF0dXNcbiIpOwoJfQoJcmV0dXJuIChob3RrLT5zdGF0dXMgJiBsZWRtYXNrKSA/IDEgOiAwOwp9CgpzdGF0aWMgaW50IHBhcnNlX2FyZyhjb25zdCBjaGFyIF9fdXNlciAqIGJ1ZiwgdW5zaWduZWQgbG9uZyBjb3VudCwgaW50ICp2YWwpCnsKCWNoYXIgc1szMl07CglpZiAoIWNvdW50KQoJCXJldHVybiAwOwoJaWYgKGNvdW50ID4gMzEpCgkJcmV0dXJuIC1FSU5WQUw7CglpZiAoY29weV9mcm9tX3VzZXIocywgYnVmLCBjb3VudCkpCgkJcmV0dXJuIC1FRkFVTFQ7CglzW2NvdW50XSA9IDA7CglpZiAoc3NjYW5mKHMsICIlaSIsIHZhbCkgIT0gMSkKCQlyZXR1cm4gLUVJTlZBTDsKCXJldHVybiBjb3VudDsKfQoKLyogRklYTUU6IGtpbGwgZXh0cmFuZW91cyBhcmdzIHNvIGl0IGNhbiBiZSBjYWxsZWQgaW5kZXBlbmRlbnRseSAqLwpzdGF0aWMgaW50CndyaXRlX2xlZChjb25zdCBjaGFyIF9fdXNlciAqIGJ1ZmZlciwgdW5zaWduZWQgbG9uZyBjb3VudCwKCSAgY2hhciAqbGVkbmFtZSwgaW50IGxlZG1hc2ssIGludCBpbnZlcnQpCnsKCWludCBydiwgdmFsdWU7CglpbnQgbGVkX291dCA9IDA7CgoJcnYgPSBwYXJzZV9hcmcoYnVmZmVyLCBjb3VudCwgJnZhbHVlKTsKCWlmIChydiA+IDApCgkJbGVkX291dCA9IHZhbHVlID8gMSA6IDA7CgoJaG90ay0+c3RhdHVzID0KCSAgICAobGVkX291dCkgPyAoaG90ay0+c3RhdHVzIHwgbGVkbWFzaykgOiAoaG90ay0+c3RhdHVzICYgfmxlZG1hc2spOwoKCWlmIChpbnZlcnQpCQkvKiBpbnZlcnQgdGFyZ2V0IHZhbHVlICovCgkJbGVkX291dCA9ICFsZWRfb3V0ICYgMHgxOwoKCWlmICghd3JpdGVfYWNwaV9pbnQoaG90ay0+aGFuZGxlLCBsZWRuYW1lLCBsZWRfb3V0LCBOVUxMKSkKCQlwcmludGsoS0VSTl9XQVJOSU5HICJBc3VzIEFDUEk6IExFRCAoJXMpIHdyaXRlIGZhaWxlZFxuIiwKCQkgICAgICAgbGVkbmFtZSk7CgoJcmV0dXJuIHJ2Owp9CgovKgogKiBQcm9jIGhhbmRsZXJzIGZvciBNTEVECiAqLwpzdGF0aWMgaW50CnByb2NfcmVhZF9tbGVkKGNoYXIgKnBhZ2UsIGNoYXIgKipzdGFydCwgb2ZmX3Qgb2ZmLCBpbnQgY291bnQsIGludCAqZW9mLAoJICAgICAgIHZvaWQgKmRhdGEpCnsKCXJldHVybiBzcHJpbnRmKHBhZ2UsICIlZFxuIiwKCQkgICAgICAgcmVhZF9sZWQoaG90ay0+bWV0aG9kcy0+bWxlZF9zdGF0dXMsIE1MRURfT04pKTsKfQoKc3RhdGljIGludApwcm9jX3dyaXRlX21sZWQoc3RydWN0IGZpbGUgKmZpbGUsIGNvbnN0IGNoYXIgX191c2VyICogYnVmZmVyLAoJCXVuc2lnbmVkIGxvbmcgY291bnQsIHZvaWQgKmRhdGEpCnsKCXJldHVybiB3cml0ZV9sZWQoYnVmZmVyLCBjb3VudCwgaG90ay0+bWV0aG9kcy0+bXRfbWxlZCwgTUxFRF9PTiwgMSk7Cn0KCi8qCiAqIFByb2MgaGFuZGxlcnMgZm9yIExFRCBkaXNwbGF5CiAqLwpzdGF0aWMgaW50CnByb2NfcmVhZF9sZWRkKGNoYXIgKnBhZ2UsIGNoYXIgKipzdGFydCwgb2ZmX3Qgb2ZmLCBpbnQgY291bnQsIGludCAqZW9mLAoJICAgICAgIHZvaWQgKmRhdGEpCnsKCXJldHVybiBzcHJpbnRmKHBhZ2UsICIweCUwOHhcbiIsIGhvdGstPmxlZGRfc3RhdHVzKTsKfQoKc3RhdGljIGludApwcm9jX3dyaXRlX2xlZGQoc3RydWN0IGZpbGUgKmZpbGUsIGNvbnN0IGNoYXIgX191c2VyICogYnVmZmVyLAoJCXVuc2lnbmVkIGxvbmcgY291bnQsIHZvaWQgKmRhdGEpCnsKCWludCBydiwgdmFsdWU7CgoJcnYgPSBwYXJzZV9hcmcoYnVmZmVyLCBjb3VudCwgJnZhbHVlKTsKCWlmIChydiA+IDApIHsKCQlpZiAoIXdyaXRlX2FjcGlfaW50CgkJICAgIChob3RrLT5oYW5kbGUsIGhvdGstPm1ldGhvZHMtPm10X2xlZGQsIHZhbHVlLCBOVUxMKSkKCQkJcHJpbnRrKEtFUk5fV0FSTklORwoJCQkgICAgICAgIkFzdXMgQUNQSTogTEVEIGRpc3BsYXkgd3JpdGUgZmFpbGVkXG4iKTsKCQllbHNlCgkJCWhvdGstPmxlZGRfc3RhdHVzID0gKHUzMikgdmFsdWU7Cgl9CglyZXR1cm4gcnY7Cn0KCi8qCiAqIFByb2MgaGFuZGxlcnMgZm9yIFdMRUQKICovCnN0YXRpYyBpbnQKcHJvY19yZWFkX3dsZWQoY2hhciAqcGFnZSwgY2hhciAqKnN0YXJ0LCBvZmZfdCBvZmYsIGludCBjb3VudCwgaW50ICplb2YsCgkgICAgICAgdm9pZCAqZGF0YSkKewoJcmV0dXJuIHNwcmludGYocGFnZSwgIiVkXG4iLAoJCSAgICAgICByZWFkX2xlZChob3RrLT5tZXRob2RzLT53bGVkX3N0YXR1cywgV0xFRF9PTikpOwp9CgpzdGF0aWMgaW50CnByb2Nfd3JpdGVfd2xlZChzdHJ1Y3QgZmlsZSAqZmlsZSwgY29uc3QgY2hhciBfX3VzZXIgKiBidWZmZXIsCgkJdW5zaWduZWQgbG9uZyBjb3VudCwgdm9pZCAqZGF0YSkKewoJcmV0dXJuIHdyaXRlX2xlZChidWZmZXIsIGNvdW50LCBob3RrLT5tZXRob2RzLT5tdF93bGVkLCBXTEVEX09OLCAwKTsKfQoKLyoKICogUHJvYyBoYW5kbGVycyBmb3IgQmx1ZXRvb3RoCiAqLwpzdGF0aWMgaW50CnByb2NfcmVhZF9ibHVldG9vdGgoY2hhciAqcGFnZSwgY2hhciAqKnN0YXJ0LCBvZmZfdCBvZmYsIGludCBjb3VudCwgaW50ICplb2YsCgkJICAgIHZvaWQgKmRhdGEpCnsKCXJldHVybiBzcHJpbnRmKHBhZ2UsICIlZFxuIiwgcmVhZF9sZWQoaG90ay0+bWV0aG9kcy0+YnRfc3RhdHVzLCBCVF9PTikpOwp9CgpzdGF0aWMgaW50CnByb2Nfd3JpdGVfYmx1ZXRvb3RoKHN0cnVjdCBmaWxlICpmaWxlLCBjb25zdCBjaGFyIF9fdXNlciAqIGJ1ZmZlciwKCQkgICAgIHVuc2lnbmVkIGxvbmcgY291bnQsIHZvaWQgKmRhdGEpCnsKCS8qIE5vdGU6IG10X2J0X3N3aXRjaCBjb250cm9scyBib3RoIGludGVybmFsIEJsdWV0b290aCBhZGFwdGVyJ3MgCgkgICBwcmVzZW5jZSBhbmQgaXRzIExFRCAqLwoJcmV0dXJuIHdyaXRlX2xlZChidWZmZXIsIGNvdW50LCBob3RrLT5tZXRob2RzLT5tdF9idF9zd2l0Y2gsIEJUX09OLCAwKTsKfQoKLyoKICogUHJvYyBoYW5kbGVycyBmb3IgVExFRAogKi8Kc3RhdGljIGludApwcm9jX3JlYWRfdGxlZChjaGFyICpwYWdlLCBjaGFyICoqc3RhcnQsIG9mZl90IG9mZiwgaW50IGNvdW50LCBpbnQgKmVvZiwKCSAgICAgICB2b2lkICpkYXRhKQp7CglyZXR1cm4gc3ByaW50ZihwYWdlLCAiJWRcbiIsCgkJICAgICAgIHJlYWRfbGVkKGhvdGstPm1ldGhvZHMtPnRsZWRfc3RhdHVzLCBUTEVEX09OKSk7Cn0KCnN0YXRpYyBpbnQKcHJvY193cml0ZV90bGVkKHN0cnVjdCBmaWxlICpmaWxlLCBjb25zdCBjaGFyIF9fdXNlciAqIGJ1ZmZlciwKCQl1bnNpZ25lZCBsb25nIGNvdW50LCB2b2lkICpkYXRhKQp7CglyZXR1cm4gd3JpdGVfbGVkKGJ1ZmZlciwgY291bnQsIGhvdGstPm1ldGhvZHMtPm10X3RsZWQsIFRMRURfT04sIDApOwp9CgpzdGF0aWMgaW50IGdldF9sY2Rfc3RhdGUodm9pZCkKewoJaW50IGxjZCA9IDA7CgoJaWYgKGhvdGstPm1vZGVsICE9IEwzSCkgewoJCS8qIFdlIGRvbid0IGhhdmUgdG8gY2hlY2sgYW55dGhpbmcgaWYgd2UgYXJlIGhlcmUgKi8KCQlpZiAoIXJlYWRfYWNwaV9pbnQoTlVMTCwgaG90ay0+bWV0aG9kcy0+bGNkX3N0YXR1cywgJmxjZCkpCgkJCXByaW50ayhLRVJOX1dBUk5JTkcKCQkJICAgICAgICJBc3VzIEFDUEk6IEVycm9yIHJlYWRpbmcgTENEIHN0YXR1c1xuIik7CgoJCWlmIChob3RrLT5tb2RlbCA9PSBMMkQpCgkJCWxjZCA9IH5sY2Q7Cgl9IGVsc2UgewkJLyogTDNIIGFuZCB0aGUgbGlrZSBoYXZlIHRvIGJlIGhhbmRsZWQgZGlmZmVyZW50bHkgKi8KCQlhY3BpX3N0YXR1cyBzdGF0dXMgPSAwOwoJCXN0cnVjdCBhY3BpX29iamVjdF9saXN0IGlucHV0OwoJCXVuaW9uIGFjcGlfb2JqZWN0IG10X3BhcmFtc1syXTsKCQlzdHJ1Y3QgYWNwaV9idWZmZXIgb3V0cHV0OwoJCXVuaW9uIGFjcGlfb2JqZWN0IG91dF9vYmo7CgoJCWlucHV0LmNvdW50ID0gMjsKCQlpbnB1dC5wb2ludGVyID0gbXRfcGFyYW1zOwoJCS8qIE5vdGU6IHRoZSBmb2xsb3dpbmcgdmFsdWVzIGFyZSBwYXJ0bHkgZ3Vlc3NlZCB1cCwgYnV0IAoJCSAgIG90aGVyd2lzZSB0aGV5IHNlZW0gdG8gd29yayAqLwoJCW10X3BhcmFtc1swXS50eXBlID0gQUNQSV9UWVBFX0lOVEVHRVI7CgkJbXRfcGFyYW1zWzBdLmludGVnZXIudmFsdWUgPSAweDAyOwoJCW10X3BhcmFtc1sxXS50eXBlID0gQUNQSV9UWVBFX0lOVEVHRVI7CgkJbXRfcGFyYW1zWzFdLmludGVnZXIudmFsdWUgPSAweDAyOwoKCQlvdXRwdXQubGVuZ3RoID0gc2l6ZW9mKG91dF9vYmopOwoJCW91dHB1dC5wb2ludGVyID0gJm91dF9vYmo7CgoJCXN0YXR1cyA9CgkJICAgIGFjcGlfZXZhbHVhdGVfb2JqZWN0KE5VTEwsIGhvdGstPm1ldGhvZHMtPmxjZF9zdGF0dXMsCgkJCQkJICZpbnB1dCwgJm91dHB1dCk7CgkJaWYgKHN0YXR1cyAhPSBBRV9PSykKCQkJcmV0dXJuIC0xOwoJCWlmIChvdXRfb2JqLnR5cGUgPT0gQUNQSV9UWVBFX0lOVEVHRVIpCgkJCS8qIFRoYXQncyB3aGF0IHRoZSBBTUwgY29kZSBkb2VzICovCgkJCWxjZCA9IG91dF9vYmouaW50ZWdlci52YWx1ZSA+PiA4OwoJfQoKCXJldHVybiAobGNkICYgMSk7Cn0KCnN0YXRpYyBpbnQgc2V0X2xjZF9zdGF0ZShpbnQgdmFsdWUpCnsKCWludCBsY2QgPSAwOwoJYWNwaV9zdGF0dXMgc3RhdHVzID0gMDsKCglsY2QgPSB2YWx1ZSA/IDEgOiAwOwoJaWYgKGxjZCAhPSBnZXRfbGNkX3N0YXRlKCkpIHsKCQkvKiBzd2l0Y2ggKi8KCQlpZiAoaG90ay0+bW9kZWwgIT0gTDNIKSB7CgkJCXN0YXR1cyA9CgkJCSAgICBhY3BpX2V2YWx1YXRlX29iamVjdChOVUxMLAoJCQkJCQkgaG90ay0+bWV0aG9kcy0+bXRfbGNkX3N3aXRjaCwKCQkJCQkJIE5VTEwsIE5VTEwpOwoJCX0gZWxzZSB7CS8qIEwzSCBhbmQgdGhlIGxpa2UgaGF2ZSB0byBiZSBoYW5kbGVkIGRpZmZlcmVudGx5ICovCgkJCWlmICghd3JpdGVfYWNwaV9pbnQKCQkJICAgIChob3RrLT5oYW5kbGUsIGhvdGstPm1ldGhvZHMtPm10X2xjZF9zd2l0Y2gsIDB4MDcsCgkJCSAgICAgTlVMTCkpCgkJCQlzdGF0dXMgPSBBRV9FUlJPUjsKCQkJLyogTDNIJ3MgQU1MIGV4ZWN1dGVzIEVISyAoMHgwNykgdXBvbiBGbitGNyBrZXlwcmVzcywgCgkJCSAgIHRoZSBleGFjdCBiZWhhdmlvdXIgaXMgc2ltdWxhdGVkIGhlcmUgKi8KCQl9CgkJaWYgKEFDUElfRkFJTFVSRShzdGF0dXMpKQoJCQlwcmludGsoS0VSTl9XQVJOSU5HICJBc3VzIEFDUEk6IEVycm9yIHN3aXRjaGluZyBMQ0RcbiIpOwoJfQoJcmV0dXJuIDA7Cgp9CgpzdGF0aWMgaW50CnByb2NfcmVhZF9sY2QoY2hhciAqcGFnZSwgY2hhciAqKnN0YXJ0LCBvZmZfdCBvZmYsIGludCBjb3VudCwgaW50ICplb2YsCgkgICAgICB2b2lkICpkYXRhKQp7CglyZXR1cm4gc3ByaW50ZihwYWdlLCAiJWRcbiIsIGdldF9sY2Rfc3RhdGUoKSk7Cn0KCnN0YXRpYyBpbnQKcHJvY193cml0ZV9sY2Qoc3RydWN0IGZpbGUgKmZpbGUsIGNvbnN0IGNoYXIgX191c2VyICogYnVmZmVyLAoJICAgICAgIHVuc2lnbmVkIGxvbmcgY291bnQsIHZvaWQgKmRhdGEpCnsKCWludCBydiwgdmFsdWU7CgoJcnYgPSBwYXJzZV9hcmcoYnVmZmVyLCBjb3VudCwgJnZhbHVlKTsKCWlmIChydiA+IDApCgkJc2V0X2xjZF9zdGF0ZSh2YWx1ZSk7CglyZXR1cm4gcnY7Cn0KCnN0YXRpYyBpbnQgcmVhZF9icmlnaHRuZXNzKHN0cnVjdCBiYWNrbGlnaHRfZGV2aWNlICpiZCkKewoJaW50IHZhbHVlOwoKCWlmIChob3RrLT5tZXRob2RzLT5icmlnaHRuZXNzX2dldCkgewkvKiBTUExWL0dQTFYgbGFwdG9wICovCgkJaWYgKCFyZWFkX2FjcGlfaW50KGhvdGstPmhhbmRsZSwgaG90ay0+bWV0aG9kcy0+YnJpZ2h0bmVzc19nZXQsCgkJCQkgICAmdmFsdWUpKQoJCQlwcmludGsoS0VSTl9XQVJOSU5HCgkJCSAgICAgICAiQXN1cyBBQ1BJOiBFcnJvciByZWFkaW5nIGJyaWdodG5lc3NcbiIpOwoJfSBlbHNlIGlmIChob3RrLT5tZXRob2RzLT5icmlnaHRuZXNzX3N0YXR1cykgewkvKiBGb3IgRDEgZm9yIGV4YW1wbGUgKi8KCQlpZiAoIXJlYWRfYWNwaV9pbnQoTlVMTCwgaG90ay0+bWV0aG9kcy0+YnJpZ2h0bmVzc19zdGF0dXMsCgkJCQkgICAmdmFsdWUpKQoJCQlwcmludGsoS0VSTl9XQVJOSU5HCgkJCSAgICAgICAiQXN1cyBBQ1BJOiBFcnJvciByZWFkaW5nIGJyaWdodG5lc3NcbiIpOwoJfSBlbHNlCQkJLyogTm8gR1BMViBtZXRob2QgKi8KCQl2YWx1ZSA9IGhvdGstPmJyaWdodG5lc3M7CglyZXR1cm4gdmFsdWU7Cn0KCi8qCiAqIENoYW5nZSB0aGUgYnJpZ2h0bmVzcyBsZXZlbAogKi8Kc3RhdGljIGludCBzZXRfYnJpZ2h0bmVzcyhpbnQgdmFsdWUpCnsKCWFjcGlfc3RhdHVzIHN0YXR1cyA9IDA7CglpbnQgcmV0ID0gMDsKCgkvKiBTUExWIGxhcHRvcCAqLwoJaWYgKGhvdGstPm1ldGhvZHMtPmJyaWdodG5lc3Nfc2V0KSB7CgkJaWYgKCF3cml0ZV9hY3BpX2ludChob3RrLT5oYW5kbGUsIGhvdGstPm1ldGhvZHMtPmJyaWdodG5lc3Nfc2V0LAoJCQkJICAgIHZhbHVlLCBOVUxMKSkKCQkJcHJpbnRrKEtFUk5fV0FSTklORwoJCQkgICAgICAgIkFzdXMgQUNQSTogRXJyb3IgY2hhbmdpbmcgYnJpZ2h0bmVzc1xuIik7CgkJCXJldCA9IC1FSU87CgkJZ290byBvdXQ7Cgl9CgoJLyogTm8gU1BMViBtZXRob2QgaWYgd2UgYXJlIGhlcmUsIGFjdCBhcyBhcHByb3ByaWF0ZSAqLwoJdmFsdWUgLT0gcmVhZF9icmlnaHRuZXNzKE5VTEwpOwoJd2hpbGUgKHZhbHVlICE9IDApIHsKCQlzdGF0dXMgPSBhY3BpX2V2YWx1YXRlX29iamVjdChOVUxMLCAodmFsdWUgPiAwKSA/CgkJCQkJICAgICAgaG90ay0+bWV0aG9kcy0+YnJpZ2h0bmVzc191cCA6CgkJCQkJICAgICAgaG90ay0+bWV0aG9kcy0+YnJpZ2h0bmVzc19kb3duLAoJCQkJCSAgICAgIE5VTEwsIE5VTEwpOwoJCSh2YWx1ZSA+IDApID8gdmFsdWUtLSA6IHZhbHVlKys7CgkJaWYgKEFDUElfRkFJTFVSRShzdGF0dXMpKQoJCQlwcmludGsoS0VSTl9XQVJOSU5HCgkJCSAgICAgICAiQXN1cyBBQ1BJOiBFcnJvciBjaGFuZ2luZyBicmlnaHRuZXNzXG4iKTsKCQkJcmV0ID0gLUVJTzsKCX0Kb3V0OgoJcmV0dXJuIHJldDsKfQoKc3RhdGljIGludCBzZXRfYnJpZ2h0bmVzc19zdGF0dXMoc3RydWN0IGJhY2tsaWdodF9kZXZpY2UgKmJkKQp7CglyZXR1cm4gc2V0X2JyaWdodG5lc3MoYmQtPnByb3BzLT5icmlnaHRuZXNzKTsKfQoKc3RhdGljIGludApwcm9jX3JlYWRfYnJuKGNoYXIgKnBhZ2UsIGNoYXIgKipzdGFydCwgb2ZmX3Qgb2ZmLCBpbnQgY291bnQsIGludCAqZW9mLAoJICAgICAgdm9pZCAqZGF0YSkKewoJcmV0dXJuIHNwcmludGYocGFnZSwgIiVkXG4iLCByZWFkX2JyaWdodG5lc3MoTlVMTCkpOwp9CgpzdGF0aWMgaW50CnByb2Nfd3JpdGVfYnJuKHN0cnVjdCBmaWxlICpmaWxlLCBjb25zdCBjaGFyIF9fdXNlciAqIGJ1ZmZlciwKCSAgICAgICB1bnNpZ25lZCBsb25nIGNvdW50LCB2b2lkICpkYXRhKQp7CglpbnQgcnYsIHZhbHVlOwoKCXJ2ID0gcGFyc2VfYXJnKGJ1ZmZlciwgY291bnQsICZ2YWx1ZSk7CglpZiAocnYgPiAwKSB7CgkJdmFsdWUgPSAoMCA8IHZhbHVlKSA/ICgoMTUgPCB2YWx1ZSkgPyAxNSA6IHZhbHVlKSA6IDA7CgkJLyogMCA8PSB2YWx1ZSA8PSAxNSAqLwoJCXNldF9icmlnaHRuZXNzKHZhbHVlKTsKCX0KCXJldHVybiBydjsKfQoKc3RhdGljIHZvaWQgc2V0X2Rpc3BsYXkoaW50IHZhbHVlKQp7CgkvKiBubyBzYW5pdHkgY2hlY2sgbmVlZGVkIGZvciBub3cgKi8KCWlmICghd3JpdGVfYWNwaV9pbnQoaG90ay0+aGFuZGxlLCBob3RrLT5tZXRob2RzLT5kaXNwbGF5X3NldCwKCQkJICAgIHZhbHVlLCBOVUxMKSkKCQlwcmludGsoS0VSTl9XQVJOSU5HICJBc3VzIEFDUEk6IEVycm9yIHNldHRpbmcgZGlzcGxheVxuIik7CglyZXR1cm47Cn0KCi8qCiAqIE5vdywgKnRoaXMqIG9uZSBjb3VsZCBiZSBtb3JlIHVzZXItZnJpZW5kbHksIGJ1dCBzbyBmYXIsIG5vLW9uZSBoYXMgCiAqIGNvbXBsYWluZWQuIFRoZSBzaWduaWZpY2FuY2Ugb2YgYml0cyBpcyB0aGUgc2FtZSBhcyBpbiBwcm9jX3dyaXRlX2Rpc3AoKQogKi8Kc3RhdGljIGludApwcm9jX3JlYWRfZGlzcChjaGFyICpwYWdlLCBjaGFyICoqc3RhcnQsIG9mZl90IG9mZiwgaW50IGNvdW50LCBpbnQgKmVvZiwKCSAgICAgICB2b2lkICpkYXRhKQp7CglpbnQgdmFsdWUgPSAwOwoKCWlmICghcmVhZF9hY3BpX2ludChob3RrLT5oYW5kbGUsIGhvdGstPm1ldGhvZHMtPmRpc3BsYXlfZ2V0LCAmdmFsdWUpKQoJCXByaW50ayhLRVJOX1dBUk5JTkcKCQkgICAgICAgIkFzdXMgQUNQSTogRXJyb3IgcmVhZGluZyBkaXNwbGF5IHN0YXR1c1xuIik7Cgl2YWx1ZSAmPSAweDA3OwkJLyogbmVlZGVkIGZvciBzb21lIG1vZGVscywgc2hvdWxkbid0IGh1cnQgb3RoZXJzICovCglyZXR1cm4gc3ByaW50ZihwYWdlLCAiJWRcbiIsIHZhbHVlKTsKfQoKLyoKICogRXhwZXJpbWVudGFsIHN1cHBvcnQgZm9yIGRpc3BsYXkgc3dpdGNoaW5nLiBBcyBvZiBub3c6IDEgc2hvdWxkIGFjdGl2YXRlIAogKiB0aGUgTENEIG91dHB1dCwgMiBzaG91bGQgZG8gZm9yIENSVCwgYW5kIDQgZm9yIFRWLU91dC4gQW55IGNvbWJpbmF0aW9uIAogKiAoYml0d2lzZSkgb2YgdGhlc2Ugd2lsbCBzdWZmaWNlLiBJIG5ldmVyIGFjdHVhbGx5IHRlc3RlZCAzIGRpc3BsYXlzIGhvb2tlZCB1cCAKICogc2ltdWx0YW5lb3VzbHksIHNvIGJlIHdhcm5lZC4gU2VlIHRoZSBhY3BpNGFzdXMgUkVBRE1FIGZvciBtb3JlIGluZm8uCiAqLwpzdGF0aWMgaW50CnByb2Nfd3JpdGVfZGlzcChzdHJ1Y3QgZmlsZSAqZmlsZSwgY29uc3QgY2hhciBfX3VzZXIgKiBidWZmZXIsCgkJdW5zaWduZWQgbG9uZyBjb3VudCwgdm9pZCAqZGF0YSkKewoJaW50IHJ2LCB2YWx1ZTsKCglydiA9IHBhcnNlX2FyZyhidWZmZXIsIGNvdW50LCAmdmFsdWUpOwoJaWYgKHJ2ID4gMCkKCQlzZXRfZGlzcGxheSh2YWx1ZSk7CglyZXR1cm4gcnY7Cn0KCnR5cGVkZWYgaW50IChwcm9jX3JlYWRmdW5jKSAoY2hhciAqcGFnZSwgY2hhciAqKnN0YXJ0LCBvZmZfdCBvZmYsIGludCBjb3VudCwKCQkJICAgICBpbnQgKmVvZiwgdm9pZCAqZGF0YSk7CnR5cGVkZWYgaW50IChwcm9jX3dyaXRlZnVuYykgKHN0cnVjdCBmaWxlICogZmlsZSwgY29uc3QgY2hhciBfX3VzZXIgKiBidWZmZXIsCgkJCSAgICAgIHVuc2lnbmVkIGxvbmcgY291bnQsIHZvaWQgKmRhdGEpOwoKc3RhdGljIGludAphc3VzX3Byb2NfYWRkKGNoYXIgKm5hbWUsIHByb2Nfd3JpdGVmdW5jICogd3JpdGVmdW5jLAoJCSAgICAgcHJvY19yZWFkZnVuYyAqIHJlYWRmdW5jLCBtb2RlX3QgbW9kZSwKCQkgICAgIHN0cnVjdCBhY3BpX2RldmljZSAqZGV2aWNlKQp7CglzdHJ1Y3QgcHJvY19kaXJfZW50cnkgKnByb2MgPQoJICAgIGNyZWF0ZV9wcm9jX2VudHJ5KG5hbWUsIG1vZGUsIGFjcGlfZGV2aWNlX2RpcihkZXZpY2UpKTsKCWlmICghcHJvYykgewoJCXByaW50ayhLRVJOX1dBUk5JTkcgIiAgVW5hYmxlIHRvIGNyZWF0ZSAlcyBmcyBlbnRyeVxuIiwgbmFtZSk7CgkJcmV0dXJuIC0xOwoJfQoJcHJvYy0+d3JpdGVfcHJvYyA9IHdyaXRlZnVuYzsKCXByb2MtPnJlYWRfcHJvYyA9IHJlYWRmdW5jOwoJcHJvYy0+ZGF0YSA9IGFjcGlfZHJpdmVyX2RhdGEoZGV2aWNlKTsKCXByb2MtPm93bmVyID0gVEhJU19NT0RVTEU7Cglwcm9jLT51aWQgPSBhc3VzX3VpZDsKCXByb2MtPmdpZCA9IGFzdXNfZ2lkOwoJcmV0dXJuIDA7Cn0KCnN0YXRpYyBpbnQgYXN1c19ob3RrX2FkZF9mcyhzdHJ1Y3QgYWNwaV9kZXZpY2UgKmRldmljZSkKewoJc3RydWN0IHByb2NfZGlyX2VudHJ5ICpwcm9jOwoJbW9kZV90IG1vZGU7CgoJLyoKCSAqIElmIHBhcmFtZXRlciB1aWQgb3IgZ2lkIGlzIG5vdCBjaGFuZ2VkLCBrZWVwIHRoZSBkZWZhdWx0IHNldHRpbmcgZm9yCgkgKiBvdXIgcHJvYyBlbnRyaWVzICgtcnctcnctcnctKSBlbHNlLCBpdCBtZWFucyB3ZSBjYXJlIGFib3V0IHNlY3VyaXR5LAoJICogYW5kIHRoZW4gc2V0IHRvIC1ydy1ydy0tLS0KCSAqLwoKCWlmICgoYXN1c191aWQgPT0gMCkgJiYgKGFzdXNfZ2lkID09IDApKSB7CgkJbW9kZSA9IFNfSUZSRUcgfCBTX0lSVUdPIHwgU19JV1VHTzsKCX0gZWxzZSB7CgkJbW9kZSA9IFNfSUZSRUcgfCBTX0lSVVNSIHwgU19JUkdSUCB8IFNfSVdVU1IgfCBTX0lXR1JQOwoJCXByaW50ayhLRVJOX1dBUk5JTkcgIiAgYXN1c191aWQgYW5kIGFzdXNfZ2lkIHBhcmFtZXRlcnMgYXJlICIKCQkgICAgICAgImRlcHJlY2F0ZWQsIHVzZSBjaG93biBhbmQgY2htb2QgaW5zdGVhZCFcbiIpOwoJfQoKCWFjcGlfZGV2aWNlX2RpcihkZXZpY2UpID0gYXN1c19wcm9jX2RpcjsKCWlmICghYWNwaV9kZXZpY2VfZGlyKGRldmljZSkpCgkJcmV0dXJuIC1FTk9ERVY7CgoJcHJvYyA9IGNyZWF0ZV9wcm9jX2VudHJ5KFBST0NfSU5GTywgbW9kZSwgYWNwaV9kZXZpY2VfZGlyKGRldmljZSkpOwoJaWYgKHByb2MpIHsKCQlwcm9jLT5yZWFkX3Byb2MgPSBwcm9jX3JlYWRfaW5mbzsKCQlwcm9jLT5kYXRhID0gYWNwaV9kcml2ZXJfZGF0YShkZXZpY2UpOwoJCXByb2MtPm93bmVyID0gVEhJU19NT0RVTEU7CgkJcHJvYy0+dWlkID0gYXN1c191aWQ7CgkJcHJvYy0+Z2lkID0gYXN1c19naWQ7Cgl9IGVsc2UgewoJCXByaW50ayhLRVJOX1dBUk5JTkcgIiAgVW5hYmxlIHRvIGNyZWF0ZSAiIFBST0NfSU5GTwoJCSAgICAgICAiIGZzIGVudHJ5XG4iKTsKCX0KCglpZiAoaG90ay0+bWV0aG9kcy0+bXRfd2xlZCkgewoJCWFzdXNfcHJvY19hZGQoUFJPQ19XTEVELCAmcHJvY193cml0ZV93bGVkLCAmcHJvY19yZWFkX3dsZWQsCgkJCSAgICAgIG1vZGUsIGRldmljZSk7Cgl9CgoJaWYgKGhvdGstPm1ldGhvZHMtPm10X2xlZGQpIHsKCQlhc3VzX3Byb2NfYWRkKFBST0NfTEVERCwgJnByb2Nfd3JpdGVfbGVkZCwgJnByb2NfcmVhZF9sZWRkLAoJCQkgICAgICBtb2RlLCBkZXZpY2UpOwoJfQoKCWlmIChob3RrLT5tZXRob2RzLT5tdF9tbGVkKSB7CgkJYXN1c19wcm9jX2FkZChQUk9DX01MRUQsICZwcm9jX3dyaXRlX21sZWQsICZwcm9jX3JlYWRfbWxlZCwKCQkJICAgICAgbW9kZSwgZGV2aWNlKTsKCX0KCglpZiAoaG90ay0+bWV0aG9kcy0+bXRfdGxlZCkgewoJCWFzdXNfcHJvY19hZGQoUFJPQ19UTEVELCAmcHJvY193cml0ZV90bGVkLCAmcHJvY19yZWFkX3RsZWQsCgkJCSAgICAgIG1vZGUsIGRldmljZSk7Cgl9CgoJaWYgKGhvdGstPm1ldGhvZHMtPm10X2J0X3N3aXRjaCkgewoJCWFzdXNfcHJvY19hZGQoUFJPQ19CVCwgJnByb2Nfd3JpdGVfYmx1ZXRvb3RoLAoJCQkgICAgICAmcHJvY19yZWFkX2JsdWV0b290aCwgbW9kZSwgZGV2aWNlKTsKCX0KCgkvKiAKCSAqIFdlIG5lZWQgYm90aCByZWFkIG5vZGUgYW5kIHdyaXRlIG1ldGhvZCBhcyBMQ0Qgc3dpdGNoIGlzIGFsc28gYWNjZXNzaWJsZQoJICogZnJvbSBrZXlib2FyZCAKCSAqLwoJaWYgKGhvdGstPm1ldGhvZHMtPm10X2xjZF9zd2l0Y2ggJiYgaG90ay0+bWV0aG9kcy0+bGNkX3N0YXR1cykgewoJCWFzdXNfcHJvY19hZGQoUFJPQ19MQ0QsICZwcm9jX3dyaXRlX2xjZCwgJnByb2NfcmVhZF9sY2QsIG1vZGUsCgkJCSAgICAgIGRldmljZSk7Cgl9CgoJaWYgKChob3RrLT5tZXRob2RzLT5icmlnaHRuZXNzX3VwICYmIGhvdGstPm1ldGhvZHMtPmJyaWdodG5lc3NfZG93bikgfHwKCSAgICAoaG90ay0+bWV0aG9kcy0+YnJpZ2h0bmVzc19nZXQgJiYgaG90ay0+bWV0aG9kcy0+YnJpZ2h0bmVzc19zZXQpKSB7CgkJYXN1c19wcm9jX2FkZChQUk9DX0JSTiwgJnByb2Nfd3JpdGVfYnJuLCAmcHJvY19yZWFkX2JybiwgbW9kZSwKCQkJICAgICAgZGV2aWNlKTsKCX0KCglpZiAoaG90ay0+bWV0aG9kcy0+ZGlzcGxheV9zZXQpIHsKCQlhc3VzX3Byb2NfYWRkKFBST0NfRElTUCwgJnByb2Nfd3JpdGVfZGlzcCwgJnByb2NfcmVhZF9kaXNwLAoJCQkgICAgICBtb2RlLCBkZXZpY2UpOwoJfQoKCXJldHVybiAwOwp9CgpzdGF0aWMgaW50IGFzdXNfaG90a19yZW1vdmVfZnMoc3RydWN0IGFjcGlfZGV2aWNlICpkZXZpY2UpCnsKCWlmIChhY3BpX2RldmljZV9kaXIoZGV2aWNlKSkgewoJCXJlbW92ZV9wcm9jX2VudHJ5KFBST0NfSU5GTywgYWNwaV9kZXZpY2VfZGlyKGRldmljZSkpOwoJCWlmIChob3RrLT5tZXRob2RzLT5tdF93bGVkKQoJCQlyZW1vdmVfcHJvY19lbnRyeShQUk9DX1dMRUQsIGFjcGlfZGV2aWNlX2RpcihkZXZpY2UpKTsKCQlpZiAoaG90ay0+bWV0aG9kcy0+bXRfbWxlZCkKCQkJcmVtb3ZlX3Byb2NfZW50cnkoUFJPQ19NTEVELCBhY3BpX2RldmljZV9kaXIoZGV2aWNlKSk7CgkJaWYgKGhvdGstPm1ldGhvZHMtPm10X3RsZWQpCgkJCXJlbW92ZV9wcm9jX2VudHJ5KFBST0NfVExFRCwgYWNwaV9kZXZpY2VfZGlyKGRldmljZSkpOwoJCWlmIChob3RrLT5tZXRob2RzLT5tdF9sZWRkKQoJCQlyZW1vdmVfcHJvY19lbnRyeShQUk9DX0xFREQsIGFjcGlfZGV2aWNlX2RpcihkZXZpY2UpKTsKCQlpZiAoaG90ay0+bWV0aG9kcy0+bXRfYnRfc3dpdGNoKQoJCQlyZW1vdmVfcHJvY19lbnRyeShQUk9DX0JULCBhY3BpX2RldmljZV9kaXIoZGV2aWNlKSk7CgkJaWYgKGhvdGstPm1ldGhvZHMtPm10X2xjZF9zd2l0Y2ggJiYgaG90ay0+bWV0aG9kcy0+bGNkX3N0YXR1cykKCQkJcmVtb3ZlX3Byb2NfZW50cnkoUFJPQ19MQ0QsIGFjcGlfZGV2aWNlX2RpcihkZXZpY2UpKTsKCQlpZiAoKGhvdGstPm1ldGhvZHMtPmJyaWdodG5lc3NfdXAKCQkgICAgICYmIGhvdGstPm1ldGhvZHMtPmJyaWdodG5lc3NfZG93bikKCQkgICAgfHwgKGhvdGstPm1ldGhvZHMtPmJyaWdodG5lc3NfZ2V0CgkJCSYmIGhvdGstPm1ldGhvZHMtPmJyaWdodG5lc3Nfc2V0KSkKCQkJcmVtb3ZlX3Byb2NfZW50cnkoUFJPQ19CUk4sIGFjcGlfZGV2aWNlX2RpcihkZXZpY2UpKTsKCQlpZiAoaG90ay0+bWV0aG9kcy0+ZGlzcGxheV9zZXQpCgkJCXJlbW92ZV9wcm9jX2VudHJ5KFBST0NfRElTUCwgYWNwaV9kZXZpY2VfZGlyKGRldmljZSkpOwoJfQoJcmV0dXJuIDA7Cn0KCnN0YXRpYyB2b2lkIGFzdXNfaG90a19ub3RpZnkoYWNwaV9oYW5kbGUgaGFuZGxlLCB1MzIgZXZlbnQsIHZvaWQgKmRhdGEpCnsKCS8qIFRPRE8gRmluZCBhIGJldHRlciB3YXkgdG8gaGFuZGxlIGV2ZW50cyBjb3VudC4gKi8KCWlmICghaG90aykKCQlyZXR1cm47CgoJaWYgKChldmVudCAmIH4oKHUzMikgQlJfVVApKSA8IDE2KSB7CgkJaG90ay0+YnJpZ2h0bmVzcyA9IChldmVudCAmIH4oKHUzMikgQlJfVVApKTsKCX0gZWxzZSBpZiAoKGV2ZW50ICYgfigodTMyKSBCUl9ET1dOKSkgPCAxNikgewoJCWhvdGstPmJyaWdodG5lc3MgPSAoZXZlbnQgJiB+KCh1MzIpIEJSX0RPV04pKTsKCX0KCglhY3BpX2J1c19nZW5lcmF0ZV9ldmVudChob3RrLT5kZXZpY2UsIGV2ZW50LAoJCQkJaG90ay0+ZXZlbnRfY291bnRbZXZlbnQgJSAxMjhdKyspOwoKCXJldHVybjsKfQoKLyoKICogTWF0Y2ggdGhlIG1vZGVsIHN0cmluZyB0byB0aGUgbGlzdCBvZiBzdXBwb3J0ZWQgbW9kZWxzLiBSZXR1cm4gRU5EX01PREVMIGlmCiAqIG5vIG1hdGNoIG9yIG1vZGVsIGlzIE5VTEwuCiAqLwpzdGF0aWMgaW50IGFzdXNfbW9kZWxfbWF0Y2goY2hhciAqbW9kZWwpCnsKCWlmIChtb2RlbCA9PSBOVUxMKQoJCXJldHVybiBFTkRfTU9ERUw7CgoJaWYgKHN0cm5jbXAobW9kZWwsICJMM0QiLCAzKSA9PSAwKQoJCXJldHVybiBMM0Q7CgllbHNlIGlmIChzdHJuY21wKG1vZGVsLCAiTDJFIiwgMykgPT0gMCB8fAoJCSBzdHJuY21wKG1vZGVsLCAiTDNIIiwgMykgPT0gMCB8fCBzdHJuY21wKG1vZGVsLCAiTDVEIiwgMykgPT0gMCkKCQlyZXR1cm4gTDNIOwoJZWxzZSBpZiAoc3RybmNtcChtb2RlbCwgIkwzIiwgMikgPT0gMCB8fCBzdHJuY21wKG1vZGVsLCAiTDJCIiwgMykgPT0gMCkKCQlyZXR1cm4gTDNDOwoJZWxzZSBpZiAoc3RybmNtcChtb2RlbCwgIkw4TCIsIDMpID09IDApCgkJcmV0dXJuIEw4TDsKCWVsc2UgaWYgKHN0cm5jbXAobW9kZWwsICJMNFIiLCAzKSA9PSAwKQoJCXJldHVybiBMNFI7CgllbHNlIGlmIChzdHJuY21wKG1vZGVsLCAiTTZOIiwgMykgPT0gMCB8fCBzdHJuY21wKG1vZGVsLCAiVzNOIiwgMykgPT0gMCkKCQlyZXR1cm4gTTZOOwoJZWxzZSBpZiAoc3RybmNtcChtb2RlbCwgIk02UiIsIDMpID09IDAgfHwgc3RybmNtcChtb2RlbCwgIkEzRyIsIDMpID09IDApCgkJcmV0dXJuIE02UjsKCWVsc2UgaWYgKHN0cm5jbXAobW9kZWwsICJNMk4iLCAzKSA9PSAwIHx8CgkJIHN0cm5jbXAobW9kZWwsICJNM04iLCAzKSA9PSAwIHx8CgkJIHN0cm5jbXAobW9kZWwsICJNNU4iLCAzKSA9PSAwIHx8CgkJIHN0cm5jbXAobW9kZWwsICJNNk4iLCAzKSA9PSAwIHx8CgkJIHN0cm5jbXAobW9kZWwsICJTMU4iLCAzKSA9PSAwIHx8CgkJIHN0cm5jbXAobW9kZWwsICJTNU4iLCAzKSA9PSAwIHx8IHN0cm5jbXAobW9kZWwsICJXMU4iLCAzKSA9PSAwKQoJCXJldHVybiB4eE47CgllbHNlIGlmIChzdHJuY21wKG1vZGVsLCAiTTEiLCAyKSA9PSAwKQoJCXJldHVybiBNMUE7CgllbHNlIGlmIChzdHJuY21wKG1vZGVsLCAiTTIiLCAyKSA9PSAwIHx8IHN0cm5jbXAobW9kZWwsICJMNEUiLCAzKSA9PSAwKQoJCXJldHVybiBNMkU7CgllbHNlIGlmIChzdHJuY21wKG1vZGVsLCAiTDIiLCAyKSA9PSAwKQoJCXJldHVybiBMMkQ7CgllbHNlIGlmIChzdHJuY21wKG1vZGVsLCAiTDgiLCAyKSA9PSAwKQoJCXJldHVybiBTMXg7CgllbHNlIGlmIChzdHJuY21wKG1vZGVsLCAiRDEiLCAyKSA9PSAwKQoJCXJldHVybiBEMXg7CgllbHNlIGlmIChzdHJuY21wKG1vZGVsLCAiQTEiLCAyKSA9PSAwKQoJCXJldHVybiBBMXg7CgllbHNlIGlmIChzdHJuY21wKG1vZGVsLCAiQTIiLCAyKSA9PSAwKQoJCXJldHVybiBBMng7CgllbHNlIGlmIChzdHJuY21wKG1vZGVsLCAiSjEiLCAyKSA9PSAwKQoJCXJldHVybiBTMng7CgllbHNlIGlmIChzdHJuY21wKG1vZGVsLCAiTDUiLCAyKSA9PSAwKQoJCXJldHVybiBMNXg7CgllbHNlIGlmIChzdHJuY21wKG1vZGVsLCAiQTRHIiwgMykgPT0gMCkKCQlyZXR1cm4gQTRHOwoJZWxzZSBpZiAoc3RybmNtcChtb2RlbCwgIlcxTiIsIDMpID09IDApCgkJcmV0dXJuIFcxTjsKCWVsc2UgaWYgKHN0cm5jbXAobW9kZWwsICJXM1YiLCAzKSA9PSAwKQoJCXJldHVybiBXM1Y7CgllbHNlIGlmIChzdHJuY21wKG1vZGVsLCAiVzVBIiwgMykgPT0gMCkKCQlyZXR1cm4gVzVBOwoJZWxzZQoJCXJldHVybiBFTkRfTU9ERUw7Cn0KCi8qCiAqIFRoaXMgZnVuY3Rpb24gaXMgdXNlZCB0byBpbml0aWFsaXplIHRoZSBob3RrIHdpdGggcmlnaHQgdmFsdWVzLiBJbiB0aGlzCiAqIG1ldGhvZCwgd2UgY2FuIG1ha2UgYWxsIHRoZSBkZXRlY3Rpb24gd2Ugd2FudCwgYW5kIG1vZGlmeSB0aGUgaG90ayBzdHJ1Y3QKICovCnN0YXRpYyBpbnQgYXN1c19ob3RrX2dldF9pbmZvKHZvaWQpCnsKCXN0cnVjdCBhY3BpX2J1ZmZlciBidWZmZXIgPSB7IEFDUElfQUxMT0NBVEVfQlVGRkVSLCBOVUxMIH07CglzdHJ1Y3QgYWNwaV9idWZmZXIgZHNkdCA9IHsgQUNQSV9BTExPQ0FURV9CVUZGRVIsIE5VTEwgfTsKCXVuaW9uIGFjcGlfb2JqZWN0ICptb2RlbCA9IE5VTEw7CglpbnQgYnN0c19yZXN1bHQ7CgljaGFyICpzdHJpbmcgPSBOVUxMOwoJYWNwaV9zdGF0dXMgc3RhdHVzOwoKCS8qCgkgKiBHZXQgRFNEVCBoZWFkZXJzIGVhcmx5IGVub3VnaCB0byBhbGxvdyBmb3IgZGlmZmVyZW50aWF0aW5nIGJldHdlZW4gCgkgKiBtb2RlbHMsIGJ1dCBsYXRlIGVub3VnaCB0byBhbGxvdyBhY3BpX2J1c19yZWdpc3Rlcl9kcml2ZXIoKSB0byBmYWlsIAoJICogYmVmb3JlIGRvaW5nIGFueXRoaW5nIEFDUEktc3BlY2lmaWMuIFNob3VsZCB3ZSBlbmNvdW50ZXIgYSBtYWNoaW5lLAoJICogd2hpY2ggbmVlZHMgc3BlY2lhbCBoYW5kbGluZyAoaS5lLiBpdHMgaG90a2V5IGRldmljZSBoYXMgYSBkaWZmZXJlbnQKCSAqIEhJRCksIHRoaXMgYml0IHdpbGwgYmUgbW92ZWQuIEEgZ2xvYmFsIHZhcmlhYmxlIGFzdXNfaW5mbyBjb250YWlucwoJICogdGhlIERTRFQgaGVhZGVyLgoJICovCglzdGF0dXMgPSBhY3BpX2dldF90YWJsZShBQ1BJX1RBQkxFX0lEX0RTRFQsIDEsICZkc2R0KTsKCWlmIChBQ1BJX0ZBSUxVUkUoc3RhdHVzKSkKCQlwcmludGsoS0VSTl9XQVJOSU5HICIgIENvdWxkbid0IGdldCB0aGUgRFNEVCB0YWJsZSBoZWFkZXJcbiIpOwoJZWxzZQoJCWFzdXNfaW5mbyA9IChzdHJ1Y3QgYWNwaV90YWJsZV9oZWFkZXIgKilkc2R0LnBvaW50ZXI7CgoJLyogV2UgaGF2ZSB0byB3cml0ZSAwIG9uIGluaXQgdGhpcyBmYXIgZm9yIGFsbCBBU1VTIG1vZGVscyAqLwoJaWYgKCF3cml0ZV9hY3BpX2ludChob3RrLT5oYW5kbGUsICJJTklUIiwgMCwgJmJ1ZmZlcikpIHsKCQlwcmludGsoS0VSTl9FUlIgIiAgSG90a2V5IGluaXRpYWxpemF0aW9uIGZhaWxlZFxuIik7CgkJcmV0dXJuIC1FTk9ERVY7Cgl9CgoJLyogVGhpcyBuZWVkcyB0byBiZSBjYWxsZWQgZm9yIHNvbWUgbGFwdG9wcyB0byBpbml0IHByb3Blcmx5ICovCglpZiAoIXJlYWRfYWNwaV9pbnQoaG90ay0+aGFuZGxlLCAiQlNUUyIsICZic3RzX3Jlc3VsdCkpCgkJcHJpbnRrKEtFUk5fV0FSTklORyAiICBFcnJvciBjYWxsaW5nIEJTVFNcbiIpOwoJZWxzZSBpZiAoYnN0c19yZXN1bHQpCgkJcHJpbnRrKEtFUk5fTk9USUNFICIgIEJTVFMgY2FsbGVkLCAweCUwMnggcmV0dXJuZWRcbiIsCgkJICAgICAgIGJzdHNfcmVzdWx0KTsKCgkvKgoJICogVHJ5IHRvIG1hdGNoIHRoZSBvYmplY3QgcmV0dXJuZWQgYnkgSU5JVCB0byB0aGUgc3BlY2lmaWMgbW9kZWwuCgkgKiBIYW5kbGUgZXZlcnkgcG9zc2libGUgb2JqZWN0IChvciB0aGUgbGFjayBvZiB0aGVyZW9mKSB0aGUgRFNEVCAKCSAqIHdyaXRlcnMgbWlnaHQgdGhyb3cgYXQgdXMuIFdoZW4gaW4gdHJvdWJsZSwgd2UgcGFzcyBOVUxMIHRvIAoJICogYXN1c19tb2RlbF9tYXRjaCgpIGFuZCB0cnkgc29tZXRoaW5nIGNvbXBsZXRlbHkgZGlmZmVyZW50LgoJICovCglpZiAoYnVmZmVyLnBvaW50ZXIpIHsKCQltb2RlbCA9ICh1bmlvbiBhY3BpX29iamVjdCAqKWJ1ZmZlci5wb2ludGVyOwoJCXN3aXRjaCAobW9kZWwtPnR5cGUpIHsKCQljYXNlIEFDUElfVFlQRV9TVFJJTkc6CgkJCXN0cmluZyA9IG1vZGVsLT5zdHJpbmcucG9pbnRlcjsKCQkJYnJlYWs7CgkJY2FzZSBBQ1BJX1RZUEVfQlVGRkVSOgoJCQlzdHJpbmcgPSBtb2RlbC0+YnVmZmVyLnBvaW50ZXI7CgkJCWJyZWFrOwoJCWRlZmF1bHQ6CgkJCWtmcmVlKG1vZGVsKTsKCQkJYnJlYWs7CgkJfQoJfQoJaG90ay0+bW9kZWwgPSBhc3VzX21vZGVsX21hdGNoKHN0cmluZyk7CglpZiAoaG90ay0+bW9kZWwgPT0gRU5EX01PREVMKSB7CS8qIG1hdGNoIGZhaWxlZCAqLwoJCWlmIChhc3VzX2luZm8gJiYKCQkgICAgc3RybmNtcChhc3VzX2luZm8tPm9lbV90YWJsZV9pZCwgIk9ERU0iLCA0KSA9PSAwKSB7CgkJCWhvdGstPm1vZGVsID0gUDMwOwoJCQlwcmludGsoS0VSTl9OT1RJQ0UKCQkJICAgICAgICIgIFNhbXN1bmcgUDMwIGRldGVjdGVkLCBzdXBwb3J0ZWRcbiIpOwoJCX0gZWxzZSB7CgkJCWhvdGstPm1vZGVsID0gTTJFOwoJCQlwcmludGsoS0VSTl9OT1RJQ0UgIiAgdW5zdXBwb3J0ZWQgbW9kZWwgJXMsIHRyeWluZyAiCgkJCSAgICAgICAiZGVmYXVsdCB2YWx1ZXNcbiIsIHN0cmluZyk7CgkJCXByaW50ayhLRVJOX05PVElDRQoJCQkgICAgICAgIiAgc2VuZCAvcHJvYy9hY3BpL2RzZHQgdG8gdGhlIGRldmVsb3BlcnNcbiIpOwoJCX0KCQlob3RrLT5tZXRob2RzID0gJm1vZGVsX2NvbmZbaG90ay0+bW9kZWxdOwoJCXJldHVybiBBRV9PSzsKCX0KCWhvdGstPm1ldGhvZHMgPSAmbW9kZWxfY29uZltob3RrLT5tb2RlbF07CglwcmludGsoS0VSTl9OT1RJQ0UgIiAgJXMgbW9kZWwgZGV0ZWN0ZWQsIHN1cHBvcnRlZFxuIiwgc3RyaW5nKTsKCgkvKiBTb3J0IG9mIHBlci1tb2RlbCBibGFja2xpc3QgKi8KCWlmIChzdHJuY21wKHN0cmluZywgIkwyQiIsIDMpID09IDApCgkJaG90ay0+bWV0aG9kcy0+bGNkX3N0YXR1cyA9IE5VTEw7CgkvKiBMMkIgaXMgc2ltaWxhciBlbm91Z2ggdG8gTDNDIHRvIHVzZSBpdHMgc2V0dGluZ3MsIHdpdGggdGhpcyBvbmx5IAoJICAgZXhjZXB0aW9uICovCgllbHNlIGlmIChzdHJuY21wKHN0cmluZywgIkEzRyIsIDMpID09IDApCgkJaG90ay0+bWV0aG9kcy0+bGNkX3N0YXR1cyA9ICJcXEJMRkciOwoJLyogQTNHIGlzIGxpa2UgTTZSICovCgllbHNlIGlmIChzdHJuY21wKHN0cmluZywgIlM1TiIsIDMpID09IDAgfHwKCQkgc3RybmNtcChzdHJpbmcsICJNNU4iLCAzKSA9PSAwIHx8CgkJIHN0cm5jbXAoc3RyaW5nLCAiVzNOIiwgMykgPT0gMCkKCQlob3RrLT5tZXRob2RzLT5tdF9tbGVkID0gTlVMTDsKCS8qIFM1TiwgTTVOIGFuZCBXM04gaGF2ZSBubyBNTEVEICovCgllbHNlIGlmIChzdHJuY21wKHN0cmluZywgIkw1RCIsIDMpID09IDApCgkJaG90ay0+bWV0aG9kcy0+bXRfd2xlZCA9IE5VTEw7CgkvKiBMNUQncyBXTEVEIGlzIG5vdCBjb250cm9sbGVkIGJ5IEFDUEkgKi8KCWVsc2UgaWYgKHN0cm5jbXAoc3RyaW5nLCAiTTJOIiwgMykgPT0gMCB8fAoJCSBzdHJuY21wKHN0cmluZywgIlczViIsIDMpID09IDAgfHwKCQkgc3RybmNtcChzdHJpbmcsICJTMU4iLCAzKSA9PSAwKQoJCWhvdGstPm1ldGhvZHMtPm10X3dsZWQgPSAiV0xFRCI7CgkvKiBNMk4sIFMxTiBhbmQgVzNWIGhhdmUgYSB1c2FibGUgV0xFRCAqLwoJZWxzZSBpZiAoYXN1c19pbmZvKSB7CgkJaWYgKHN0cm5jbXAoYXN1c19pbmZvLT5vZW1fdGFibGVfaWQsICJMMSIsIDIpID09IDApCgkJCWhvdGstPm1ldGhvZHMtPm1sZWRfc3RhdHVzID0gTlVMTDsKCQkvKiBTMTMwMEEgcmVwb3J0cyBMODRGLCBidXQgTDE0MDBCIHRvbywgYWNjb3VudCBmb3IgdGhhdCAqLwoJfQoKCWtmcmVlKG1vZGVsKTsKCglyZXR1cm4gQUVfT0s7Cn0KCnN0YXRpYyBpbnQgYXN1c19ob3RrX2NoZWNrKHZvaWQpCnsKCWludCByZXN1bHQgPSAwOwoKCXJlc3VsdCA9IGFjcGlfYnVzX2dldF9zdGF0dXMoaG90ay0+ZGV2aWNlKTsKCWlmIChyZXN1bHQpCgkJcmV0dXJuIHJlc3VsdDsKCglpZiAoaG90ay0+ZGV2aWNlLT5zdGF0dXMucHJlc2VudCkgewoJCXJlc3VsdCA9IGFzdXNfaG90a19nZXRfaW5mbygpOwoJfSBlbHNlIHsKCQlwcmludGsoS0VSTl9FUlIgIiAgSG90a2V5IGRldmljZSBub3QgcHJlc2VudCwgYWJvcnRpbmdcbiIpOwoJCXJldHVybiAtRUlOVkFMOwoJfQoKCXJldHVybiByZXN1bHQ7Cn0KCnN0YXRpYyBpbnQgYXN1c19ob3RrX2ZvdW5kOwoKc3RhdGljIGludCBhc3VzX2hvdGtfYWRkKHN0cnVjdCBhY3BpX2RldmljZSAqZGV2aWNlKQp7CglhY3BpX3N0YXR1cyBzdGF0dXMgPSBBRV9PSzsKCWludCByZXN1bHQ7CgoJaWYgKCFkZXZpY2UpCgkJcmV0dXJuIC1FSU5WQUw7CgoJcHJpbnRrKEtFUk5fTk9USUNFICJBc3VzIExhcHRvcCBBQ1BJIEV4dHJhcyB2ZXJzaW9uICVzXG4iLAoJICAgICAgIEFTVVNfQUNQSV9WRVJTSU9OKTsKCglob3RrID0KCSAgICAoc3RydWN0IGFzdXNfaG90ayAqKWttYWxsb2Moc2l6ZW9mKHN0cnVjdCBhc3VzX2hvdGspLCBHRlBfS0VSTkVMKTsKCWlmICghaG90aykKCQlyZXR1cm4gLUVOT01FTTsKCW1lbXNldChob3RrLCAwLCBzaXplb2Yoc3RydWN0IGFzdXNfaG90aykpOwoKCWhvdGstPmhhbmRsZSA9IGRldmljZS0+aGFuZGxlOwoJc3RyY3B5KGFjcGlfZGV2aWNlX25hbWUoZGV2aWNlKSwgQUNQSV9IT1RLX0RFVklDRV9OQU1FKTsKCXN0cmNweShhY3BpX2RldmljZV9jbGFzcyhkZXZpY2UpLCBBQ1BJX0hPVEtfQ0xBU1MpOwoJYWNwaV9kcml2ZXJfZGF0YShkZXZpY2UpID0gaG90azsKCWhvdGstPmRldmljZSA9IGRldmljZTsKCglyZXN1bHQgPSBhc3VzX2hvdGtfY2hlY2soKTsKCWlmIChyZXN1bHQpCgkJZ290byBlbmQ7CgoJcmVzdWx0ID0gYXN1c19ob3RrX2FkZF9mcyhkZXZpY2UpOwoJaWYgKHJlc3VsdCkKCQlnb3RvIGVuZDsKCgkvKgoJICogV2UgaW5zdGFsbCB0aGUgaGFuZGxlciwgaXQgd2lsbCByZWNlaXZlIHRoZSBob3RrIGluIHBhcmFtZXRlciwgc28sIHdlCgkgKiBjb3VsZCBhZGQgb3RoZXIgZGF0YSB0byB0aGUgaG90ayBzdHJ1Y3QKCSAqLwoJc3RhdHVzID0gYWNwaV9pbnN0YWxsX25vdGlmeV9oYW5kbGVyKGhvdGstPmhhbmRsZSwgQUNQSV9TWVNURU1fTk9USUZZLAoJCQkJCSAgICAgYXN1c19ob3RrX25vdGlmeSwgaG90ayk7CglpZiAoQUNQSV9GQUlMVVJFKHN0YXR1cykpCgkJcHJpbnRrKEtFUk5fRVJSICIgIEVycm9yIGluc3RhbGxpbmcgbm90aWZ5IGhhbmRsZXJcbiIpOwoKCS8qIEZvciBsYXB0b3BzIHdpdGhvdXQgR1BMVjogaW5pdCB0aGUgaG90ay0+YnJpZ2h0bmVzcyB2YWx1ZSAqLwoJaWYgKCghaG90ay0+bWV0aG9kcy0+YnJpZ2h0bmVzc19nZXQpCgkgICAgJiYgKCFob3RrLT5tZXRob2RzLT5icmlnaHRuZXNzX3N0YXR1cykKCSAgICAmJiAoaG90ay0+bWV0aG9kcy0+YnJpZ2h0bmVzc191cCAmJiBob3RrLT5tZXRob2RzLT5icmlnaHRuZXNzX2Rvd24pKSB7CgkJc3RhdHVzID0KCQkgICAgYWNwaV9ldmFsdWF0ZV9vYmplY3QoTlVMTCwgaG90ay0+bWV0aG9kcy0+YnJpZ2h0bmVzc19kb3duLAoJCQkJCSBOVUxMLCBOVUxMKTsKCQlpZiAoQUNQSV9GQUlMVVJFKHN0YXR1cykpCgkJCXByaW50ayhLRVJOX1dBUk5JTkcgIiAgRXJyb3IgY2hhbmdpbmcgYnJpZ2h0bmVzc1xuIik7CgkJZWxzZSB7CgkJCXN0YXR1cyA9CgkJCSAgICBhY3BpX2V2YWx1YXRlX29iamVjdChOVUxMLAoJCQkJCQkgaG90ay0+bWV0aG9kcy0+YnJpZ2h0bmVzc191cCwKCQkJCQkJIE5VTEwsIE5VTEwpOwoJCQlpZiAoQUNQSV9GQUlMVVJFKHN0YXR1cykpCgkJCQlwcmludGsoS0VSTl9XQVJOSU5HICIgIFN0cmFuZ2UsIGVycm9yIGNoYW5naW5nIgoJCQkJICAgICAgICIgYnJpZ2h0bmVzc1xuIik7CgkJfQoJfQoKCWFzdXNfaG90a19mb3VuZCA9IDE7CgoJLyogTEVEIGRpc3BsYXkgaXMgb2ZmIGJ5IGRlZmF1bHQgKi8KCWhvdGstPmxlZGRfc3RhdHVzID0gMHhGRkY7CgogICAgICBlbmQ6CglpZiAocmVzdWx0KSB7CgkJa2ZyZWUoaG90ayk7Cgl9CgoJcmV0dXJuIHJlc3VsdDsKfQoKc3RhdGljIGludCBhc3VzX2hvdGtfcmVtb3ZlKHN0cnVjdCBhY3BpX2RldmljZSAqZGV2aWNlLCBpbnQgdHlwZSkKewoJYWNwaV9zdGF0dXMgc3RhdHVzID0gMDsKCglpZiAoIWRldmljZSB8fCAhYWNwaV9kcml2ZXJfZGF0YShkZXZpY2UpKQoJCXJldHVybiAtRUlOVkFMOwoKCXN0YXR1cyA9IGFjcGlfcmVtb3ZlX25vdGlmeV9oYW5kbGVyKGhvdGstPmhhbmRsZSwgQUNQSV9TWVNURU1fTk9USUZZLAoJCQkJCSAgICBhc3VzX2hvdGtfbm90aWZ5KTsKCWlmIChBQ1BJX0ZBSUxVUkUoc3RhdHVzKSkKCQlwcmludGsoS0VSTl9FUlIgIkFzdXMgQUNQSTogRXJyb3IgcmVtb3Zpbmcgbm90aWZ5IGhhbmRsZXJcbiIpOwoKCWFzdXNfaG90a19yZW1vdmVfZnMoZGV2aWNlKTsKCglrZnJlZShob3RrKTsKCglyZXR1cm4gMDsKfQoKc3RhdGljIHN0cnVjdCBiYWNrbGlnaHRfcHJvcGVydGllcyBhc3VzX2JhY2tsaWdodF9kYXRhID0gewogICAgICAgIC5vd25lciAgICAgICAgICA9IFRISVNfTU9EVUxFLAogICAgICAgIC5nZXRfYnJpZ2h0bmVzcyA9IHJlYWRfYnJpZ2h0bmVzcywKICAgICAgICAudXBkYXRlX3N0YXR1cyAgPSBzZXRfYnJpZ2h0bmVzc19zdGF0dXMsCiAgICAgICAgLm1heF9icmlnaHRuZXNzID0gMTUsCn07CgpzdGF0aWMgdm9pZCBfX2V4aXQgYXN1c19hY3BpX2V4aXQodm9pZCkKewoJaWYgKGFzdXNfYmFja2xpZ2h0X2RldmljZSkKCQliYWNrbGlnaHRfZGV2aWNlX3VucmVnaXN0ZXIoYXN1c19iYWNrbGlnaHRfZGV2aWNlKTsKCglhY3BpX2J1c191bnJlZ2lzdGVyX2RyaXZlcigmYXN1c19ob3RrX2RyaXZlcik7CglyZW1vdmVfcHJvY19lbnRyeShQUk9DX0FTVVMsIGFjcGlfcm9vdF9kaXIpOwoKCWtmcmVlKGFzdXNfaW5mbyk7CgoJcmV0dXJuOwp9CgpzdGF0aWMgaW50IF9faW5pdCBhc3VzX2FjcGlfaW5pdCh2b2lkKQp7CglpbnQgcmVzdWx0OwoKCWlmIChhY3BpX2Rpc2FibGVkKQoJCXJldHVybiAtRU5PREVWOwoKCWlmICghYWNwaV9zcGVjaWZpY19ob3RrZXlfZW5hYmxlZCkgewoJCXByaW50ayhLRVJOX0VSUiAiVXNpbmcgZ2VuZXJpYyBob3RrZXkgZHJpdmVyXG4iKTsKCQlyZXR1cm4gLUVOT0RFVjsKCX0KCWFzdXNfcHJvY19kaXIgPSBwcm9jX21rZGlyKFBST0NfQVNVUywgYWNwaV9yb290X2Rpcik7CglpZiAoIWFzdXNfcHJvY19kaXIpIHsKCQlwcmludGsoS0VSTl9FUlIgIkFzdXMgQUNQSTogVW5hYmxlIHRvIGNyZWF0ZSAvcHJvYyBlbnRyeVxuIik7CgkJcmV0dXJuIC1FTk9ERVY7Cgl9Cglhc3VzX3Byb2NfZGlyLT5vd25lciA9IFRISVNfTU9EVUxFOwoKCXJlc3VsdCA9IGFjcGlfYnVzX3JlZ2lzdGVyX2RyaXZlcigmYXN1c19ob3RrX2RyaXZlcik7CglpZiAocmVzdWx0IDwgMCkgewoJCXJlbW92ZV9wcm9jX2VudHJ5KFBST0NfQVNVUywgYWNwaV9yb290X2Rpcik7CgkJcmV0dXJuIHJlc3VsdDsKCX0KCgkvKgoJICogVGhpcyBpcyBhIGJpdCBvZiBhIGtsdWRnZS4gIFdlIG9ubHkgd2FudCB0aGlzIG1vZHVsZSBsb2FkZWQKCSAqIGZvciBBU1VTIHN5c3RlbXMsIGJ1dCB0aGVyZSdzIGN1cnJlbnRseSBubyB3YXkgdG8gcHJvYmUgdGhlCgkgKiBBQ1BJIG5hbWVzcGFjZSBmb3IgQVNVUyBISURzLiAgU28gd2UganVzdCByZXR1cm4gZmFpbHVyZSBpZgoJICogd2UgZGlkbid0IGZpbmQgb25lLCB3aGljaCB3aWxsIGNhdXNlIHRoZSBtb2R1bGUgdG8gYmUKCSAqIHVubG9hZGVkLgoJICovCglpZiAoIWFzdXNfaG90a19mb3VuZCkgewoJCWFjcGlfYnVzX3VucmVnaXN0ZXJfZHJpdmVyKCZhc3VzX2hvdGtfZHJpdmVyKTsKCQlyZW1vdmVfcHJvY19lbnRyeShQUk9DX0FTVVMsIGFjcGlfcm9vdF9kaXIpOwoJCXJldHVybiByZXN1bHQ7Cgl9CgoJYXN1c19iYWNrbGlnaHRfZGV2aWNlID0gYmFja2xpZ2h0X2RldmljZV9yZWdpc3RlcigiYXN1cyIsIE5VTEwsCgkJCQkJCQkgICZhc3VzX2JhY2tsaWdodF9kYXRhKTsKICAgICAgICBpZiAoSVNfRVJSKGFzdXNfYmFja2xpZ2h0X2RldmljZSkpIHsKCQlwcmludGsoS0VSTl9FUlIgIkNvdWxkIG5vdCByZWdpc3RlciBhc3VzIGJhY2tsaWdodCBkZXZpY2VcbiIpOwoJCWFzdXNfYmFja2xpZ2h0X2RldmljZSA9IE5VTEw7CgkJYXN1c19hY3BpX2V4aXQoKTsKCX0KCglyZXR1cm4gMDsKfQoKbW9kdWxlX2luaXQoYXN1c19hY3BpX2luaXQpOwptb2R1bGVfZXhpdChhc3VzX2FjcGlfZXhpdCk7Cg==