LyoKICogIEZvcmNlIGZlZWRiYWNrIHN1cHBvcnQgZm9yIFBhbnRoZXJMb3JkL0dyZWVuQXNpYSBiYXNlZCBkZXZpY2VzCiAqCiAqICBUaGUgZGV2aWNlcyBhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdmFyaW91cyBuYW1lcyBhbmQgdGhlIHNhbWUgVVNCIGRldmljZSBJRAogKiAgY2FuIGJlIHVzZWQgaW4gYm90aCBhZGFwdGVycyBhbmQgYWN0dWFsIGdhbWUgY29udHJvbGxlcnMuCiAqCiAqICAwODEwOjAwMDEgIlR3aW4gVVNCIEpveXN0aWNrIgogKiAgIC0gdGVzdGVkIHdpdGggUGFudGhlckxvcmQgVVNCL1BTMiAyaW4xIEFkYXB0ZXIKICogICAtIGNvbnRhaW5zIHR3byByZXBvcnRzLCBvbmUgZm9yIGVhY2ggcG9ydCAoSElEX1FVSVJLX01VTFRJX0lOUFVUKQogKgogKiAgMGU4ZjowMDAzICJHcmVlbkFzaWEgSW5jLiAgICBVU0IgSm95c3RpY2sgICAgICIKICogICAtIHRlc3RlZCB3aXRoIEv2bmlnIEdhbWluZyBnYW1lcGFkCiAqCiAqICAwZThmOjAwMDMgIkdBU0lBIFVTQiBHYW1lcGFkIgogKiAgIC0gYW5vdGhlciB2ZXJzaW9uIG9mIHRoZSBL9m5pZyBnYW1lcGFkCiAqCiAqICBDb3B5cmlnaHQgKGMpIDIwMDcsIDIwMDkgQW5zc2kgSGFubnVsYSA8YW5zc2kuaGFubnVsYUBnbWFpbC5jb20+CiAqLwoKLyoKICogVGhpcyBwcm9ncmFtIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkKICogaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkKICogdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyIHZlcnNpb24gMiBvZiB0aGUgTGljZW5zZSwgb3IKICogKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KICoKICogVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsCiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUKICogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogYWxvbmcgd2l0aCB0aGlzIHByb2dyYW07IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogRm91bmRhdGlvbiwgSW5jLiwgNTkgVGVtcGxlIFBsYWNlLCBTdWl0ZSAzMzAsIEJvc3RvbiwgTUEgMDIxMTEtMTMwNyBVU0EKICovCgoKLyogI2RlZmluZSBERUJVRyAqLwoKI2RlZmluZSBkZWJ1Zyhmb3JtYXQsIGFyZy4uLikgcHJfZGVidWcoImhpZC1wbGZmOiAiIGZvcm1hdCAiXG4iICwgIyMgYXJnKQoKI2luY2x1ZGUgPGxpbnV4L2lucHV0Lmg+CiNpbmNsdWRlIDxsaW51eC9zbGFiLmg+CiNpbmNsdWRlIDxsaW51eC91c2IuaD4KI2luY2x1ZGUgPGxpbnV4L2hpZC5oPgoKI2luY2x1ZGUgImhpZC1pZHMuaCIKCiNpZmRlZiBDT05GSUdfUEFOVEhFUkxPUkRfRkYKI2luY2x1ZGUgInVzYmhpZC91c2JoaWQuaCIKCnN0cnVjdCBwbGZmX2RldmljZSB7CglzdHJ1Y3QgaGlkX3JlcG9ydCAqcmVwb3J0OwoJczMyICpzdHJvbmc7CglzMzIgKndlYWs7Cn07CgpzdGF0aWMgaW50IGhpZF9wbGZmX3BsYXkoc3RydWN0IGlucHV0X2RldiAqZGV2LCB2b2lkICpkYXRhLAoJCQkgc3RydWN0IGZmX2VmZmVjdCAqZWZmZWN0KQp7CglzdHJ1Y3QgaGlkX2RldmljZSAqaGlkID0gaW5wdXRfZ2V0X2RydmRhdGEoZGV2KTsKCXN0cnVjdCBwbGZmX2RldmljZSAqcGxmZiA9IGRhdGE7CglpbnQgbGVmdCwgcmlnaHQ7CgoJbGVmdCA9IGVmZmVjdC0+dS5ydW1ibGUuc3Ryb25nX21hZ25pdHVkZTsKCXJpZ2h0ID0gZWZmZWN0LT51LnJ1bWJsZS53ZWFrX21hZ25pdHVkZTsKCWRlYnVnKCJjYWxsZWQgd2l0aCAweCUwNHggMHglMDR4IiwgbGVmdCwgcmlnaHQpOwoKCWxlZnQgPSBsZWZ0ICogMHg3ZiAvIDB4ZmZmZjsKCXJpZ2h0ID0gcmlnaHQgKiAweDdmIC8gMHhmZmZmOwoKCSpwbGZmLT5zdHJvbmcgPSBsZWZ0OwoJKnBsZmYtPndlYWsgPSByaWdodDsKCWRlYnVnKCJydW5uaW5nIHdpdGggMHglMDJ4IDB4JTAyeCIsIGxlZnQsIHJpZ2h0KTsKCXVzYmhpZF9zdWJtaXRfcmVwb3J0KGhpZCwgcGxmZi0+cmVwb3J0LCBVU0JfRElSX09VVCk7CgoJcmV0dXJuIDA7Cn0KCnN0YXRpYyBpbnQgcGxmZl9pbml0KHN0cnVjdCBoaWRfZGV2aWNlICpoaWQpCnsKCXN0cnVjdCBwbGZmX2RldmljZSAqcGxmZjsKCXN0cnVjdCBoaWRfcmVwb3J0ICpyZXBvcnQ7CglzdHJ1Y3QgaGlkX2lucHV0ICpoaWRpbnB1dDsKCXN0cnVjdCBsaXN0X2hlYWQgKnJlcG9ydF9saXN0ID0KCQkJJmhpZC0+cmVwb3J0X2VudW1bSElEX09VVFBVVF9SRVBPUlRdLnJlcG9ydF9saXN0OwoJc3RydWN0IGxpc3RfaGVhZCAqcmVwb3J0X3B0ciA9IHJlcG9ydF9saXN0OwoJc3RydWN0IGlucHV0X2RldiAqZGV2OwoJaW50IGVycm9yOwoJczMyICpzdHJvbmc7CglzMzIgKndlYWs7CgoJLyogVGhlIGRldmljZSBjb250YWlucyBvbmUgb3V0cHV0IHJlcG9ydCBwZXIgcGh5c2ljYWwgZGV2aWNlLCBhbGwKCSAgIGNvbnRhaW5pbmcgMSBmaWVsZCwgd2hpY2ggY29udGFpbnMgNCBmZjAwLjAwMDIgdXNhZ2VzIGFuZCA0IDE2Yml0CgkgICBhYnNvbHV0ZSB2YWx1ZXMuCgoJICAgVGhlIGlucHV0IHJlcG9ydHMgYWxzbyBjb250YWluIGEgZmllbGQgd2hpY2ggY29udGFpbnMKCSAgIDggZmYwMC4wMDAxIHVzYWdlcyBhbmQgOCBib29sZWFuIHZhbHVlcy4gVGhlaXIgbWVhbmluZyBpcwoJICAgY3VycmVudGx5IHVua25vd24uCgkgICAKCSAgIEEgdmVyc2lvbiBvZiB0aGUgMGU4ZjowMDAzIGV4aXN0cyB0aGF0IGhhcyBhbGwgdGhlIHZhbHVlcyBpbgoJICAgc2VwYXJhdGUgZmllbGRzIGFuZCBtaXNzZXMgdGhlIGV4dHJhIGlucHV0IGZpZWxkLCB0aHVzIHJlc2VtYmxpbmcKCSAgIFplcm9wbHVzIChoaWQtenBmZikgZGV2aWNlcy4KCSovCgoJaWYgKGxpc3RfZW1wdHkocmVwb3J0X2xpc3QpKSB7CgkJZGV2X2VycigmaGlkLT5kZXYsICJubyBvdXRwdXQgcmVwb3J0cyBmb3VuZFxuIik7CgkJcmV0dXJuIC1FTk9ERVY7Cgl9CgoJbGlzdF9mb3JfZWFjaF9lbnRyeShoaWRpbnB1dCwgJmhpZC0+aW5wdXRzLCBsaXN0KSB7CgoJCXJlcG9ydF9wdHIgPSByZXBvcnRfcHRyLT5uZXh0OwoKCQlpZiAocmVwb3J0X3B0ciA9PSByZXBvcnRfbGlzdCkgewoJCQlkZXZfZXJyKCZoaWQtPmRldiwgInJlcXVpcmVkIG91dHB1dCByZXBvcnQgaXMgIgoJCQkJCSJtaXNzaW5nXG4iKTsKCQkJcmV0dXJuIC1FTk9ERVY7CgkJfQoKCQlyZXBvcnQgPSBsaXN0X2VudHJ5KHJlcG9ydF9wdHIsIHN0cnVjdCBoaWRfcmVwb3J0LCBsaXN0KTsKCQlpZiAocmVwb3J0LT5tYXhmaWVsZCA8IDEpIHsKCQkJZGV2X2VycigmaGlkLT5kZXYsICJubyBmaWVsZHMgaW4gdGhlIHJlcG9ydFxuIik7CgkJCXJldHVybiAtRU5PREVWOwoJCX0KCgkJaWYgKHJlcG9ydC0+ZmllbGRbMF0tPnJlcG9ydF9jb3VudCA+PSA0KSB7CgkJCXJlcG9ydC0+ZmllbGRbMF0tPnZhbHVlWzBdID0gMHgwMDsKCQkJcmVwb3J0LT5maWVsZFswXS0+dmFsdWVbMV0gPSAweDAwOwoJCQlzdHJvbmcgPSAmcmVwb3J0LT5maWVsZFswXS0+dmFsdWVbMl07CgkJCXdlYWsgPSAmcmVwb3J0LT5maWVsZFswXS0+dmFsdWVbM107CgkJCWRlYnVnKCJkZXRlY3RlZCBzaW5nbGUtZmllbGQgZGV2aWNlIik7CgkJfSBlbHNlIGlmIChyZXBvcnQtPm1heGZpZWxkID49IDQgJiYgcmVwb3J0LT5maWVsZFswXS0+bWF4dXNhZ2UgPT0gMSAmJgoJCQkJcmVwb3J0LT5maWVsZFswXS0+dXNhZ2VbMF0uaGlkID09IChISURfVVBfTEVEIHwgMHg0MykpIHsKCQkJcmVwb3J0LT5maWVsZFswXS0+dmFsdWVbMF0gPSAweDAwOwoJCQlyZXBvcnQtPmZpZWxkWzFdLT52YWx1ZVswXSA9IDB4MDA7CgkJCXN0cm9uZyA9ICZyZXBvcnQtPmZpZWxkWzJdLT52YWx1ZVswXTsKCQkJd2VhayA9ICZyZXBvcnQtPmZpZWxkWzNdLT52YWx1ZVswXTsKCQkJZGVidWcoImRldGVjdGVkIDQtZmllbGQgZGV2aWNlIik7CgkJfSBlbHNlIHsKCQkJZGV2X2VycigmaGlkLT5kZXYsICJub3QgZW5vdWdoIGZpZWxkcyBvciB2YWx1ZXNcbiIpOwoJCQlyZXR1cm4gLUVOT0RFVjsKCQl9CgoJCXBsZmYgPSBremFsbG9jKHNpemVvZihzdHJ1Y3QgcGxmZl9kZXZpY2UpLCBHRlBfS0VSTkVMKTsKCQlpZiAoIXBsZmYpCgkJCXJldHVybiAtRU5PTUVNOwoKCQlkZXYgPSBoaWRpbnB1dC0+aW5wdXQ7CgoJCXNldF9iaXQoRkZfUlVNQkxFLCBkZXYtPmZmYml0KTsKCgkJZXJyb3IgPSBpbnB1dF9mZl9jcmVhdGVfbWVtbGVzcyhkZXYsIHBsZmYsIGhpZF9wbGZmX3BsYXkpOwoJCWlmIChlcnJvcikgewoJCQlrZnJlZShwbGZmKTsKCQkJcmV0dXJuIGVycm9yOwoJCX0KCgkJcGxmZi0+cmVwb3J0ID0gcmVwb3J0OwoJCXBsZmYtPnN0cm9uZyA9IHN0cm9uZzsKCQlwbGZmLT53ZWFrID0gd2VhazsKCgkJKnN0cm9uZyA9IDB4MDA7CgkJKndlYWsgPSAweDAwOwoJCXVzYmhpZF9zdWJtaXRfcmVwb3J0KGhpZCwgcGxmZi0+cmVwb3J0LCBVU0JfRElSX09VVCk7Cgl9CgoJZGV2X2luZm8oJmhpZC0+ZGV2LCAiRm9yY2UgZmVlZGJhY2sgZm9yIFBhbnRoZXJMb3JkL0dyZWVuQXNpYSAiCgkgICAgICAgImRldmljZXMgYnkgQW5zc2kgSGFubnVsYSA8YW5zc2kuaGFubnVsYUBnbWFpbC5jb20+XG4iKTsKCglyZXR1cm4gMDsKfQojZWxzZQpzdGF0aWMgaW5saW5lIGludCBwbGZmX2luaXQoc3RydWN0IGhpZF9kZXZpY2UgKmhpZCkKewoJcmV0dXJuIDA7Cn0KI2VuZGlmCgpzdGF0aWMgaW50IHBsX3Byb2JlKHN0cnVjdCBoaWRfZGV2aWNlICpoZGV2LCBjb25zdCBzdHJ1Y3QgaGlkX2RldmljZV9pZCAqaWQpCnsKCWludCByZXQ7CgoJaWYgKGlkLT5kcml2ZXJfZGF0YSkKCQloZGV2LT5xdWlya3MgfD0gSElEX1FVSVJLX01VTFRJX0lOUFVUOwoKCXJldCA9IGhpZF9wYXJzZShoZGV2KTsKCWlmIChyZXQpIHsKCQlkZXZfZXJyKCZoZGV2LT5kZXYsICJwYXJzZSBmYWlsZWRcbiIpOwoJCWdvdG8gZXJyOwoJfQoKCXJldCA9IGhpZF9od19zdGFydChoZGV2LCBISURfQ09OTkVDVF9ERUZBVUxUICYgfkhJRF9DT05ORUNUX0ZGKTsKCWlmIChyZXQpIHsKCQlkZXZfZXJyKCZoZGV2LT5kZXYsICJodyBzdGFydCBmYWlsZWRcbiIpOwoJCWdvdG8gZXJyOwoJfQoKCXBsZmZfaW5pdChoZGV2KTsKCglyZXR1cm4gMDsKZXJyOgoJcmV0dXJuIHJldDsKfQoKc3RhdGljIGNvbnN0IHN0cnVjdCBoaWRfZGV2aWNlX2lkIHBsX2RldmljZXNbXSA9IHsKCXsgSElEX1VTQl9ERVZJQ0UoVVNCX1ZFTkRPUl9JRF9HQU1FUk9OLCBVU0JfREVWSUNFX0lEX0dBTUVST05fRFVBTF9QU1hfQURBUFRPUiksCgkJLmRyaXZlcl9kYXRhID0gMSB9LCAvKiBUd2luIFVTQiBKb3lzdGljayAqLwoJeyBISURfVVNCX0RFVklDRShVU0JfVkVORE9SX0lEX0dBTUVST04sIFVTQl9ERVZJQ0VfSURfR0FNRVJPTl9EVUFMX1BDU19BREFQVE9SKSwKCQkuZHJpdmVyX2RhdGEgPSAxIH0sIC8qIFR3aW4gVVNCIEpveXN0aWNrICovCgl7IEhJRF9VU0JfREVWSUNFKFVTQl9WRU5ET1JfSURfR1JFRU5BU0lBLCAweDAwMDMpLCB9LAoJeyB9Cn07Ck1PRFVMRV9ERVZJQ0VfVEFCTEUoaGlkLCBwbF9kZXZpY2VzKTsKCnN0YXRpYyBzdHJ1Y3QgaGlkX2RyaXZlciBwbF9kcml2ZXIgPSB7CgkubmFtZSA9ICJwYW50aGVybG9yZCIsCgkuaWRfdGFibGUgPSBwbF9kZXZpY2VzLAoJLnByb2JlID0gcGxfcHJvYmUsCn07CgpzdGF0aWMgaW50IF9faW5pdCBwbF9pbml0KHZvaWQpCnsKCXJldHVybiBoaWRfcmVnaXN0ZXJfZHJpdmVyKCZwbF9kcml2ZXIpOwp9CgpzdGF0aWMgdm9pZCBfX2V4aXQgcGxfZXhpdCh2b2lkKQp7CgloaWRfdW5yZWdpc3Rlcl9kcml2ZXIoJnBsX2RyaXZlcik7Cn0KCm1vZHVsZV9pbml0KHBsX2luaXQpOwptb2R1bGVfZXhpdChwbF9leGl0KTsKTU9EVUxFX0xJQ0VOU0UoIkdQTCIpOwo=