LyoKICoJRXhlY3V0aXZlIE9TTQogKgogKiAJQ29weXJpZ2h0IChDKSAxOTk5LTIwMDIJUmVkIEhhdCBTb2Z0d2FyZQogKgogKglXcml0dGVuIGJ5IEFsYW4gQ294LCBCdWlsZGluZyBOdW1iZXIgVGhyZWUgTHRkCiAqCiAqCVRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqCXVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZQogKglGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlciB2ZXJzaW9uIDIgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyCiAqCW9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqCUEgbG90IG9mIHRoZSBJMk8gbWVzc2FnZSBzaWRlIGNvZGUgZnJvbSB0aGlzIGlzIHRha2VuIGZyb20gdGhlIFJlZAogKglDcmVlayBSQ1BDSTQ1IGFkYXB0ZXIgZHJpdmVyIGJ5IFJlZCBDcmVlayBDb21tdW5pY2F0aW9ucwogKgogKglGaXhlcy9hZGRpdGlvbnM6CiAqCQlQaGlsaXBwIFJ1bXBmCiAqCQlKdWhhIFNpZXbkbmVuIDxKdWhhLlNpZXZhbmVuQGNzLkhlbHNpbmtpLkZJPgogKgkJQXV2byBI5GtraW5lbiA8QXV2by5IYWtraW5lbkBjcy5IZWxzaW5raS5GST4KICoJCURlZXBhayBTYXhlbmEgPGRlZXBha0BwbGV4aXR5Lm5ldD4KICoJCUJvamkgVCBLYW5uYW50aGFuYW0gPGJvamkudC5rYW5uYW50aGFuYW1AaW50ZWwuY29tPgogKgkJQWxhbiBDb3ggPGFsYW5AcmVkaGF0LmNvbT46CiAqCQkJUG9ydGVkIHRvIExpbnV4IDIuNS4KICoJCU1hcmt1cyBMaWRlbCA8TWFya3VzLkxpZGVsQHNoYWRvd2Nvbm5lY3QuY29tPjoKICoJCQlNaW5vciBmaXhlcyBmb3IgMi42LgogKgkJTWFya3VzIExpZGVsIDxNYXJrdXMuTGlkZWxAc2hhZG93Y29ubmVjdC5jb20+OgogKgkJCVN1cHBvcnQgZm9yIHN5c2ZzIGluY2x1ZGVkLgogKi8KCiNpbmNsdWRlIDxsaW51eC9tb2R1bGUuaD4KI2luY2x1ZGUgPGxpbnV4L2kyby5oPgojaW5jbHVkZSA8bGludXgvZGVsYXkuaD4KI2luY2x1ZGUgPGxpbnV4L3dvcmtxdWV1ZS5oPgojaW5jbHVkZSA8bGludXgvc3RyaW5nLmg+CiNpbmNsdWRlIDxsaW51eC9zbGFiLmg+CiNpbmNsdWRlIDxsaW51eC9zY2hlZC5oPiAgIC8qIHdhaXRfZXZlbnRfaW50ZXJydXB0aWJsZV90aW1lb3V0KCkgbmVlZHMgdGhpcyAqLwojaW5jbHVkZSA8YXNtL3BhcmFtLmg+CQkvKiBIWiAqLwojaW5jbHVkZSAiY29yZS5oIgoKI2RlZmluZSBPU01fTkFNRSAiZXhlYy1vc20iCgpzdHJ1Y3QgaTJvX2RyaXZlciBpMm9fZXhlY19kcml2ZXI7CgpzdGF0aWMgaW50IGkyb19leGVjX2xjdF9ub3RpZnkoc3RydWN0IGkyb19jb250cm9sbGVyICpjLCB1MzIgY2hhbmdlX2luZCk7CgovKiBnbG9iYWwgd2FpdCBsaXN0IGZvciBQT1NUIFdBSVQgKi8Kc3RhdGljIExJU1RfSEVBRChpMm9fZXhlY193YWl0X2xpc3QpOwoKLyogV2FpdCBzdHJ1Y3QgbmVlZGVkIGZvciBQT1NUIFdBSVQgKi8Kc3RydWN0IGkyb19leGVjX3dhaXQgewoJd2FpdF9xdWV1ZV9oZWFkX3QgKndxOwkvKiBQb2ludGVyIHRvIFdhaXQgcXVldWUgKi8KCXN0cnVjdCBpMm9fZG1hIGRtYTsJLyogRE1BIGJ1ZmZlcnMgdG8gZnJlZSBvbiBmYWlsdXJlICovCgl1MzIgdGNudHh0OwkJLyogdHJhbnNhY3Rpb24gY29udGV4dCBmcm9tIHJlcGx5ICovCglpbnQgY29tcGxldGU7CQkvKiAxIGlmIHJlcGx5IHJlY2VpdmVkIG90aGVyd2lzZSAwICovCgl1MzIgbTsJCQkvKiBtZXNzYWdlIGlkICovCglzdHJ1Y3QgaTJvX21lc3NhZ2UgKm1zZzsJLyogcG9pbnRlciB0byB0aGUgcmVwbHkgbWVzc2FnZSAqLwoJc3RydWN0IGxpc3RfaGVhZCBsaXN0OwkvKiBub2RlIGluIGdsb2JhbCB3YWl0IGxpc3QgKi8KfTsKCi8qIEV4ZWMgT1NNIGNsYXNzIGhhbmRsaW5nIGRlZmluaXRpb24gKi8Kc3RhdGljIHN0cnVjdCBpMm9fY2xhc3NfaWQgaTJvX2V4ZWNfY2xhc3NfaWRbXSA9IHsKCXtJMk9fQ0xBU1NfRVhFQ1VUSVZFfSwKCXtJMk9fQ0xBU1NfRU5EfQp9OwoKLyoqCiAqCWkyb19leGVjX3dhaXRfYWxsb2MgLSBBbGxvY2F0ZSBhIGkyb19leGVjX3dhaXQgc3RydWN0IGFuIGluaXRpYWxpemUgaXQKICoKICoJQWxsb2NhdGUgdGhlIGkyb19leGVjX3dhaXQgc3RydWN0IGFuZCBpbml0aWFsaXplIHRoZSB3YWl0LgogKgogKglSZXR1cm5zIGkyb19leGVjX3dhaXQgcG9pbnRlciBvbiBzdWNjZXNzIG9yIG5lZ2F0aXZlIGVycm9yIGNvZGUgb24KICoJZmFpbHVyZS4KICovCnN0YXRpYyBzdHJ1Y3QgaTJvX2V4ZWNfd2FpdCAqaTJvX2V4ZWNfd2FpdF9hbGxvYyh2b2lkKQp7CglzdHJ1Y3QgaTJvX2V4ZWNfd2FpdCAqd2FpdDsKCgl3YWl0ID0ga21hbGxvYyhzaXplb2YoKndhaXQpLCBHRlBfS0VSTkVMKTsKCWlmICghd2FpdCkKCQlyZXR1cm4gRVJSX1BUUigtRU5PTUVNKTsKCgltZW1zZXQod2FpdCwgMCwgc2l6ZW9mKCp3YWl0KSk7CgoJSU5JVF9MSVNUX0hFQUQoJndhaXQtPmxpc3QpOwoKCXJldHVybiB3YWl0Owp9OwoKLyoqCiAqCWkyb19leGVjX3dhaXRfZnJlZSAtIEZyZWUgYSBpMm9fZXhlY193YWl0IHN0cnVjdAogKglAaTJvX2V4ZWNfd2FpdDogSTJPIHdhaXQgZGF0YSB3aGljaCBzaG91bGQgYmUgY2xlYW5lZCB1cAogKi8Kc3RhdGljIHZvaWQgaTJvX2V4ZWNfd2FpdF9mcmVlKHN0cnVjdCBpMm9fZXhlY193YWl0ICp3YWl0KQp7CglrZnJlZSh3YWl0KTsKfTsKCi8qKgogKiAJaTJvX21zZ19wb3N0X3dhaXRfbWVtIC0gUG9zdCBhbmQgd2FpdCBhIG1lc3NhZ2Ugd2l0aCBETUEgYnVmZmVycwogKglAYzogY29udHJvbGxlcgogKglAbTogbWVzc2FnZSB0byBwb3N0CiAqCUB0aW1lb3V0OiB0aW1lIGluIHNlY29uZHMgdG8gd2FpdAogKglAZG1hOiBpMm9fZG1hIHN0cnVjdCBvZiB0aGUgRE1BIGJ1ZmZlciB0byBmcmVlIG9uIGZhaWx1cmUKICoKICogCVRoaXMgQVBJIGFsbG93cyBhbiBPU00gdG8gcG9zdCBhIG1lc3NhZ2UgYW5kIHRoZW4gYmUgdG9sZCB3aGV0aGVyIG9yCiAqCW5vdCB0aGUgc3lzdGVtIHJlY2VpdmVkIGEgc3VjY2Vzc2Z1bCByZXBseS4gSWYgdGhlIG1lc3NhZ2UgdGltZXMgb3V0CiAqCXRoZW4gdGhlIHZhbHVlICctRVRJTUVET1VUJyBpcyByZXR1cm5lZC4gVGhpcyBpcyBhIHNwZWNpYWwgY2FzZS4gSW4KICoJdGhpcyBzaXR1YXRpb24gdGhlIG1lc3NhZ2UgbWF5IChzaG91bGQpIGNvbXBsZXRlIGF0IGFuIGluZGVmaW5pdGUgdGltZQogKglpbiB0aGUgZnV0dXJlLiBXaGVuIGl0IGNvbXBsZXRlcyBpdCB3aWxsIHVzZSB0aGUgbWVtb3J5IGJ1ZmZlcgogKglhdHRhY2hlZCB0byB0aGUgcmVxdWVzdC4gSWYgLUVUSU1FRE9VVCBpcyByZXR1cm5lZCB0aGVuIHRoZSBtZW1vcnkKICoJYnVmZmVyIG11c3Qgbm90IGJlIGZyZWVkLiBJbnN0ZWFkIHRoZSBldmVudCBjb21wbGV0aW9uIHdpbGwgZnJlZSB0aGVtCiAqCWZvciB5b3UuIEluIGFsbCBvdGhlciBjYXNlcyB0aGUgYnVmZmVyIGFyZSB5b3VyIHByb2JsZW0uCiAqCiAqCVJldHVybnMgMCBvbiBzdWNjZXNzLCBuZWdhdGl2ZSBlcnJvciBjb2RlIG9uIHRpbWVvdXQgb3IgcG9zaXRpdmUgZXJyb3IKICoJY29kZSBmcm9tIHJlcGx5LgogKi8KaW50IGkyb19tc2dfcG9zdF93YWl0X21lbShzdHJ1Y3QgaTJvX2NvbnRyb2xsZXIgKmMsIHUzMiBtLCB1bnNpZ25lZCBsb25nCgkJCSAgdGltZW91dCwgc3RydWN0IGkyb19kbWEgKmRtYSkKewoJREVDTEFSRV9XQUlUX1FVRVVFX0hFQUQod3EpOwoJc3RydWN0IGkyb19leGVjX3dhaXQgKndhaXQ7CglzdGF0aWMgdTMyIHRjbnR4dCA9IDB4ODAwMDAwMDA7CglzdHJ1Y3QgaTJvX21lc3NhZ2UgX19pb21lbSAqbXNnID0gaTJvX21zZ19pbl90b192aXJ0KGMsIG0pOwoJaW50IHJjID0gMDsKCgl3YWl0ID0gaTJvX2V4ZWNfd2FpdF9hbGxvYygpOwoJaWYgKCF3YWl0KQoJCXJldHVybiAtRU5PTUVNOwoKCWlmICh0Y250eHQgPT0gMHhmZmZmZmZmZikKCQl0Y250eHQgPSAweDgwMDAwMDAwOwoKCWlmIChkbWEpCgkJd2FpdC0+ZG1hID0gKmRtYTsKCgkvKgoJICogRmlsbCBpbiB0aGUgbWVzc2FnZSBpbml0aWF0b3IgY29udGV4dCBhbmQgdHJhbnNhY3Rpb24gY29udGV4dC4KCSAqIFdlIHdpbGwgb25seSB1c2UgdHJhbnNhY3Rpb24gY29udGV4dHMgPj0gMHg4MDAwMDAwMCBmb3IgUE9TVCBXQUlULAoJICogc28gd2UgY291bGQgZmluZCBhIFBPU1QgV0FJVCByZXBseSBlYXNpZXIgaW4gdGhlIHJlcGx5IGhhbmRsZXIuCgkgKi8KCXdyaXRlbChpMm9fZXhlY19kcml2ZXIuY29udGV4dCwgJm1zZy0+dS5zLmljbnR4dCk7Cgl3YWl0LT50Y250eHQgPSB0Y250eHQrKzsKCXdyaXRlbCh3YWl0LT50Y250eHQsICZtc2ctPnUucy50Y250eHQpOwoKCS8qCgkgKiBQb3N0IHRoZSBtZXNzYWdlIHRvIHRoZSBjb250cm9sbGVyLiBBdCBzb21lIHBvaW50IGxhdGVyIGl0IHdpbGwKCSAqIHJldHVybi4gSWYgd2UgdGltZSBvdXQgYmVmb3JlIGl0IHJldHVybnMgdGhlbiBjb21wbGV0ZSB3aWxsIGJlIHplcm8uCgkgKi8KCWkyb19tc2dfcG9zdChjLCBtKTsKCglpZiAoIXdhaXQtPmNvbXBsZXRlKSB7CgkJd2FpdC0+d3EgPSAmd3E7CgkJLyoKCQkgKiB3ZSBhZGQgZWxlbWVudHMgYWRkIHRoZSBoZWFkLCBiZWNhdXNlIGlmIGEgZW50cnkgaW4gdGhlIGxpc3QKCQkgKiB3aWxsIG5ldmVyIGJlIHJlbW92ZWQsIHdlIGhhdmUgdG8gaXRlcmF0ZSBvdmVyIGl0IGV2ZXJ5IHRpbWUKCQkgKi8KCQlsaXN0X2FkZCgmd2FpdC0+bGlzdCwgJmkyb19leGVjX3dhaXRfbGlzdCk7CgoJCXdhaXRfZXZlbnRfaW50ZXJydXB0aWJsZV90aW1lb3V0KHdxLCB3YWl0LT5jb21wbGV0ZSwKCQkJCQkJIHRpbWVvdXQgKiBIWik7CgoJCXdhaXQtPndxID0gTlVMTDsKCX0KCgliYXJyaWVyKCk7CgoJaWYgKHdhaXQtPmNvbXBsZXRlKSB7CgkJcmMgPSBsZTMyX3RvX2NwdSh3YWl0LT5tc2ctPmJvZHlbMF0pID4+IDI0OwoJCWkyb19mbHVzaF9yZXBseShjLCB3YWl0LT5tKTsKCQlpMm9fZXhlY193YWl0X2ZyZWUod2FpdCk7Cgl9IGVsc2UgewoJCS8qCgkJICogV2UgY2Fubm90IHJlbW92ZSBpdCBub3cuIFRoaXMgaXMgaW1wb3J0YW50LiBXaGVuIGl0IGRvZXMKCQkgKiB0ZXJtaW5hdGUgKHdoaWNoIGl0IG11c3QgZG8gaWYgdGhlIGNvbnRyb2xsZXIgaGFzIG5vdAoJCSAqIGRpZWQuLi4pIHRoZW4gaXQgd2lsbCBvdGhlcndpc2Ugc2NyaWJibGUgb24gc3R1ZmYuCgkJICoKCQkgKiBGSVhNRTogdHJ5IGFib3J0IG1lc3NhZ2UKCQkgKi8KCQlpZiAoZG1hKQoJCQlkbWEtPnZpcnQgPSBOVUxMOwoKCQlyYyA9IC1FVElNRURPVVQ7Cgl9CgoJcmV0dXJuIHJjOwp9OwoKLyoqCiAqCWkyb19tc2dfcG9zdF93YWl0X2NvbXBsZXRlIC0gUmVwbHkgdG8gYSBpMm9fbXNnX3Bvc3QgcmVxdWVzdCBmcm9tIElPUAogKglAYzogSTJPIGNvbnRyb2xsZXIgd2hpY2ggYW5zd2VycwogKglAbTogbWVzc2FnZSBpZAogKglAbXNnOiBwb2ludGVyIHRvIHRoZSBJMk8gcmVwbHkgbWVzc2FnZQogKglAY29udGV4dDogdHJhbnNhY3Rpb24gY29udGV4dCBvZiByZXF1ZXN0CiAqCiAqCVRoaXMgZnVuY3Rpb24gaXMgY2FsbGVkIGluIGludGVycnVwdCBjb250ZXh0IG9ubHkuIElmIHRoZSByZXBseSByZWFjaGVkCiAqCWJlZm9yZSB0aGUgdGltZW91dCwgdGhlIGkyb19leGVjX3dhaXQgc3RydWN0IGlzIGZpbGxlZCB3aXRoIHRoZSBtZXNzYWdlCiAqCWFuZCB0aGUgdGFzayB3aWxsIGJlIHdha2VkIHVwLiBUaGUgdGFzayBpcyBub3cgcmVzcG9uc2libGUgZm9yIHJldHVybmluZwogKgl0aGUgbWVzc2FnZSBtIGJhY2sgdG8gdGhlIGNvbnRyb2xsZXIhIElmIHRoZSBtZXNzYWdlIHJlYWNoZXMgdXMgYWZ0ZXIKICoJdGhlIHRpbWVvdXQgY2xlYW4gdXAgdGhlIGkyb19leGVjX3dhaXQgc3RydWN0IChpbmNsdWRpbmcgYWxsb2NhdGVkCiAqCURNQSBidWZmZXIpLgogKgogKglSZXR1cm4gMCBvbiBzdWNjZXNzIGFuZCBpZiB0aGUgbWVzc2FnZSBtIHNob3VsZCBub3QgYmUgZ2l2ZW4gYmFjayB0byB0aGUKICoJSTJPIGNvbnRyb2xsZXIsIG9yID4wIG9uIHN1Y2Nlc3MgYW5kIGlmIHRoZSBtZXNzYWdlIHNob3VsZCBiZSBnaXZlbiBiYWNrCiAqCWFmdGVyd29yZHMuIFJldHVybnMgbmVnYXRpdmUgZXJyb3IgY29kZSBvbiBmYWlsdXJlLiBJbiB0aGlzIGNhc2UgdGhlCiAqCW1lc3NhZ2UgbXVzdCBhbHNvIGJlIGdpdmVuIGJhY2sgdG8gdGhlIGNvbnRyb2xsZXIuCiAqLwpzdGF0aWMgaW50IGkyb19tc2dfcG9zdF93YWl0X2NvbXBsZXRlKHN0cnVjdCBpMm9fY29udHJvbGxlciAqYywgdTMyIG0sCgkJCQkgICAgICBzdHJ1Y3QgaTJvX21lc3NhZ2UgKm1zZywgdTMyIGNvbnRleHQpCnsKCXN0cnVjdCBpMm9fZXhlY193YWl0ICp3YWl0LCAqdG1wOwoJdW5zaWduZWQgbG9uZyBmbGFnczsKCXN0YXRpYyBzcGlubG9ja190IGxvY2sgPSBTUElOX0xPQ0tfVU5MT0NLRUQ7CglpbnQgcmMgPSAxOwoKCS8qCgkgKiBXZSBuZWVkIHRvIHNlYXJjaCB0aHJvdWdoIHRoZSBpMm9fZXhlY193YWl0X2xpc3QgdG8gc2VlIGlmIHRoZSBnaXZlbgoJICogbWVzc2FnZSBpcyBzdGlsbCBvdXRzdGFuZGluZy4gSWYgbm90LCBpdCBtZWFucyB0aGF0IHRoZSBJT1AgdG9vawoJICogbG9uZ2VyIHRvIHJlc3BvbmQgdG8gdGhlIG1lc3NhZ2UgdGhhbiB3ZSBoYWQgYWxsb3dlZCBhbmQgdGltZXIgaGFzCgkgKiBhbHJlYWR5IGV4cGlyZWQuIE5vdCBtdWNoIHdlIGNhbiBkbyBhYm91dCB0aGF0IGV4Y2VwdCBsb2cgaXQgZm9yCgkgKiBkZWJ1ZyBwdXJwb3NlcywgaW5jcmVhc2UgdGltZW91dCwgYW5kIHJlY29tcGlsZS4KCSAqLwoJc3Bpbl9sb2NrX2lycXNhdmUoJmxvY2ssIGZsYWdzKTsKCWxpc3RfZm9yX2VhY2hfZW50cnlfc2FmZSh3YWl0LCB0bXAsICZpMm9fZXhlY193YWl0X2xpc3QsIGxpc3QpIHsKCQlpZiAod2FpdC0+dGNudHh0ID09IGNvbnRleHQpIHsKCQkJbGlzdF9kZWwoJndhaXQtPmxpc3QpOwoKCQkJc3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmbG9jaywgZmxhZ3MpOwoKCQkJd2FpdC0+bSA9IG07CgkJCXdhaXQtPm1zZyA9IG1zZzsKCQkJd2FpdC0+Y29tcGxldGUgPSAxOwoKCQkJYmFycmllcigpOwoKCQkJaWYgKHdhaXQtPndxKSB7CgkJCQl3YWtlX3VwX2ludGVycnVwdGlibGUod2FpdC0+d3EpOwoJCQkJcmMgPSAwOwoJCQl9IGVsc2UgewoJCQkJc3RydWN0IGRldmljZSAqZGV2OwoKCQkJCWRldiA9ICZjLT5wZGV2LT5kZXY7CgoJCQkJcHJfZGVidWcoIiVzOiB0aW1lZG91dCByZXBseSByZWNlaXZlZCFcbiIsCgkJCQkJIGMtPm5hbWUpOwoJCQkJaTJvX2RtYV9mcmVlKGRldiwgJndhaXQtPmRtYSk7CgkJCQlpMm9fZXhlY193YWl0X2ZyZWUod2FpdCk7CgkJCQlyYyA9IC0xOwoJCQl9CgoJCQlyZXR1cm4gcmM7CgkJfQoJfQoKCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJmxvY2ssIGZsYWdzKTsKCglvc21fd2FybigiJXM6IEJvZ3VzIHJlcGx5IGluIFBPU1QgV0FJVCAodHItY29udGV4dDogJTA4eCkhXG4iLCBjLT5uYW1lLAoJCSBjb250ZXh0KTsKCglyZXR1cm4gLTE7Cn07CgovKioKICoJaTJvX2V4ZWNfc2hvd192ZW5kb3JfaWQgLSBEaXNwbGF5cyBWZW5kb3IgSUQgb2YgY29udHJvbGxlcgogKglAZDogZGV2aWNlIG9mIHdoaWNoIHRoZSBWZW5kb3IgSUQgc2hvdWxkIGJlIGRpc3BsYXllZAogKglAYnVmOiBidWZmZXIgaW50byB3aGljaCB0aGUgVmVuZG9yIElEIHNob3VsZCBiZSBwcmludGVkCiAqCiAqCVJldHVybnMgbnVtYmVyIG9mIGJ5dGVzIHByaW50ZWQgaW50byBidWZmZXIuCiAqLwpzdGF0aWMgc3NpemVfdCBpMm9fZXhlY19zaG93X3ZlbmRvcl9pZChzdHJ1Y3QgZGV2aWNlICpkLCBzdHJ1Y3QgZGV2aWNlX2F0dHJpYnV0ZSAqYXR0ciwgY2hhciAqYnVmKQp7CglzdHJ1Y3QgaTJvX2RldmljZSAqZGV2ID0gdG9faTJvX2RldmljZShkKTsKCXUxNiBpZDsKCglpZiAoaTJvX3Bhcm1fZmllbGRfZ2V0KGRldiwgMHgwMDAwLCAwLCAmaWQsIDIpKSB7CgkJc3ByaW50ZihidWYsICIweCUwNHgiLCBpZCk7CgkJcmV0dXJuIHN0cmxlbihidWYpICsgMTsKCX0KCglyZXR1cm4gMDsKfTsKCi8qKgogKglpMm9fZXhlY19zaG93X3Byb2R1Y3RfaWQgLSBEaXNwbGF5cyBQcm9kdWN0IElEIG9mIGNvbnRyb2xsZXIKICoJQGQ6IGRldmljZSBvZiB3aGljaCB0aGUgUHJvZHVjdCBJRCBzaG91bGQgYmUgZGlzcGxheWVkCiAqCUBidWY6IGJ1ZmZlciBpbnRvIHdoaWNoIHRoZSBQcm9kdWN0IElEIHNob3VsZCBiZSBwcmludGVkCiAqCiAqCVJldHVybnMgbnVtYmVyIG9mIGJ5dGVzIHByaW50ZWQgaW50byBidWZmZXIuCiAqLwpzdGF0aWMgc3NpemVfdCBpMm9fZXhlY19zaG93X3Byb2R1Y3RfaWQoc3RydWN0IGRldmljZSAqZCwgc3RydWN0IGRldmljZV9hdHRyaWJ1dGUgKmF0dHIsIGNoYXIgKmJ1ZikKewoJc3RydWN0IGkyb19kZXZpY2UgKmRldiA9IHRvX2kyb19kZXZpY2UoZCk7Cgl1MTYgaWQ7CgoJaWYgKGkyb19wYXJtX2ZpZWxkX2dldChkZXYsIDB4MDAwMCwgMSwgJmlkLCAyKSkgewoJCXNwcmludGYoYnVmLCAiMHglMDR4IiwgaWQpOwoJCXJldHVybiBzdHJsZW4oYnVmKSArIDE7Cgl9CgoJcmV0dXJuIDA7Cn07CgovKiBFeGVjLU9TTSBkZXZpY2UgYXR0cmlidXRlcyAqLwpzdGF0aWMgREVWSUNFX0FUVFIodmVuZG9yX2lkLCBTX0lSVUdPLCBpMm9fZXhlY19zaG93X3ZlbmRvcl9pZCwgTlVMTCk7CnN0YXRpYyBERVZJQ0VfQVRUUihwcm9kdWN0X2lkLCBTX0lSVUdPLCBpMm9fZXhlY19zaG93X3Byb2R1Y3RfaWQsIE5VTEwpOwoKLyoqCiAqCWkyb19leGVjX3Byb2JlIC0gQ2FsbGVkIGlmIGEgbmV3IEkyTyBkZXZpY2UgKGV4ZWN1dGl2ZSBjbGFzcykgYXBwZWFycwogKglAZGV2OiBJMk8gZGV2aWNlIHdoaWNoIHNob3VsZCBiZSBwcm9iZWQKICoKICoJUmVnaXN0ZXJzIGV2ZW50IG5vdGlmaWNhdGlvbiBmb3IgZXZlcnkgZXZlbnQgZnJvbSBFeGVjdXRpdmUgZGV2aWNlLiBUaGUKICoJcmV0dXJuIGlzIGFsd2F5cyAwLCBiZWNhdXNlIHdlIHdhbnQgYWxsIGRldmljZXMgb2YgY2xhc3MgRXhlY3V0aXZlLgogKgogKglSZXR1cm5zIDAgb24gc3VjY2Vzcy4KICovCnN0YXRpYyBpbnQgaTJvX2V4ZWNfcHJvYmUoc3RydWN0IGRldmljZSAqZGV2KQp7CglzdHJ1Y3QgaTJvX2RldmljZSAqaTJvX2RldiA9IHRvX2kyb19kZXZpY2UoZGV2KTsKCXN0cnVjdCBpMm9fY29udHJvbGxlciAqYyA9IGkyb19kZXYtPmlvcDsKCglpMm9fZXZlbnRfcmVnaXN0ZXIoaTJvX2RldiwgJmkyb19leGVjX2RyaXZlciwgMCwgMHhmZmZmZmZmZik7CgoJYy0+ZXhlYyA9IGkyb19kZXY7CgoJaTJvX2V4ZWNfbGN0X25vdGlmeShjLCBjLT5sY3QtPmNoYW5nZV9pbmQgKyAxKTsKCglkZXZpY2VfY3JlYXRlX2ZpbGUoZGV2LCAmZGV2X2F0dHJfdmVuZG9yX2lkKTsKCWRldmljZV9jcmVhdGVfZmlsZShkZXYsICZkZXZfYXR0cl9wcm9kdWN0X2lkKTsKCglyZXR1cm4gMDsKfTsKCi8qKgogKglpMm9fZXhlY19yZW1vdmUgLSBDYWxsZWQgb24gSTJPIGRldmljZSByZW1vdmFsCiAqCUBkZXY6IEkyTyBkZXZpY2Ugd2hpY2ggd2FzIHJlbW92ZWQKICoKICoJVW5yZWdpc3RlcnMgZXZlbnQgbm90aWZpY2F0aW9uIGZyb20gRXhlY3V0aXZlIEkyTyBkZXZpY2UuCiAqCiAqCVJldHVybnMgMCBvbiBzdWNjZXNzLgogKi8Kc3RhdGljIGludCBpMm9fZXhlY19yZW1vdmUoc3RydWN0IGRldmljZSAqZGV2KQp7CglkZXZpY2VfcmVtb3ZlX2ZpbGUoZGV2LCAmZGV2X2F0dHJfcHJvZHVjdF9pZCk7CglkZXZpY2VfcmVtb3ZlX2ZpbGUoZGV2LCAmZGV2X2F0dHJfdmVuZG9yX2lkKTsKCglpMm9fZXZlbnRfcmVnaXN0ZXIodG9faTJvX2RldmljZShkZXYpLCAmaTJvX2V4ZWNfZHJpdmVyLCAwLCAwKTsKCglyZXR1cm4gMDsKfTsKCi8qKgogKglpMm9fZXhlY19sY3RfbW9kaWZpZWQgLSBDYWxsZWQgb24gTENUIE5PVElGWSByZXBseQogKglAYzogSTJPIGNvbnRyb2xsZXIgb24gd2hpY2ggdGhlIExDVCBoYXMgbW9kaWZpZWQKICoKICoJVGhpcyBmdW5jdGlvbiBoYW5kbGVzIGFzeW5jaHJvbnVzIExDVCBOT1RJRlkgcmVwbGllcy4gSXQgcGFyc2VzIHRoZQogKgluZXcgTENUIGFuZCBpZiB0aGUgYnVmZmVyIGZvciB0aGUgTENUIHdhcyB0byBzbWFsbCBzZW5kcyBhIExDVCBOT1RJRlkKICoJYWdhaW4sIG90aGVyd2lzZSBzZW5kIExDVCBOT1RJRlkgdG8gZ2V0IGluZm9ybWVkIG9uIG5leHQgTENUIGNoYW5nZS4KICovCnN0YXRpYyB2b2lkIGkyb19leGVjX2xjdF9tb2RpZmllZChzdHJ1Y3QgaTJvX2NvbnRyb2xsZXIgKmMpCnsKCXUzMiBjaGFuZ2VfaW5kID0gMDsKCglpZiAoaTJvX2RldmljZV9wYXJzZV9sY3QoYykgIT0gLUVBR0FJTikKCQljaGFuZ2VfaW5kID0gYy0+bGN0LT5jaGFuZ2VfaW5kICsgMTsKCglpMm9fZXhlY19sY3Rfbm90aWZ5KGMsIGNoYW5nZV9pbmQpOwp9OwoKLyoqCiAqCWkyb19leGVjX3JlcGx5IC0gIEkyTyBFeGVjdXRpdmUgcmVwbHkgaGFuZGxlcgogKglAYzogSTJPIGNvbnRyb2xsZXIgZnJvbSB3aGljaCB0aGUgcmVwbHkgY29tZXMKICoJQG06IG1lc3NhZ2UgaWQKICoJQG1zZzogcG9pbnRlciB0byB0aGUgSTJPIHJlcGx5IG1lc3NhZ2UKICoKICoJVGhpcyBmdW5jdGlvbiBpcyBhbHdheXMgY2FsbGVkIGZyb20gaW50ZXJydXB0IGNvbnRleHQuIElmIGEgUE9TVCBXQUlUCiAqCXJlcGx5IHdhcyByZWNlaXZlZCwgcGFzcyBpdCB0byB0aGUgY29tcGxldGUgZnVuY3Rpb24uIElmIGEgTENUIE5PVElGWQogKglyZXBseSB3YXMgcmVjZWl2ZWQsIGEgbmV3IGV2ZW50IGlzIGNyZWF0ZWQgdG8gaGFuZGxlIHRoZSB1cGRhdGUuCiAqCiAqCVJldHVybnMgMCBvbiBzdWNjZXNzIGFuZCBpZiB0aGUgcmVwbHkgc2hvdWxkIG5vdCBiZSBmbHVzaGVkIG9yID4gMAogKglvbiBzdWNjZXNzIGFuZCBpZiB0aGUgcmVwbHkgc2hvdWxkIGJlIGZsdXNoZWQuIFJldHVybnMgbmVnYXRpdmUgZXJyb3IKICoJY29kZSBvbiBmYWlsdXJlIGFuZCBpZiB0aGUgcmVwbHkgc2hvdWxkIGJlIGZsdXNoZWQuCiAqLwpzdGF0aWMgaW50IGkyb19leGVjX3JlcGx5KHN0cnVjdCBpMm9fY29udHJvbGxlciAqYywgdTMyIG0sCgkJCSAgc3RydWN0IGkyb19tZXNzYWdlICptc2cpCnsKCXUzMiBjb250ZXh0OwoKCWlmIChsZTMyX3RvX2NwdShtc2ctPnUuaGVhZFswXSkgJiBNU0dfRkFJTCkgewoJCS8qCgkJICogSWYgRmFpbCBiaXQgaXMgc2V0IHdlIG11c3QgdGFrZSB0aGUgdHJhbnNhY3Rpb24gY29udGV4dCBvZgoJCSAqIHRoZSBwcmVzZXJ2ZWQgbWVzc2FnZSB0byBmaW5kIHRoZSByaWdodCByZXF1ZXN0IGFnYWluLgoJCSAqLwoJCXN0cnVjdCBpMm9fbWVzc2FnZSBfX2lvbWVtICpwbXNnOwoJCXUzMiBwbTsKCgkJcG0gPSBsZTMyX3RvX2NwdShtc2ctPmJvZHlbM10pOwoKCQlwbXNnID0gaTJvX21zZ19pbl90b192aXJ0KGMsIHBtKTsKCgkJaTJvX3JlcG9ydF9zdGF0dXMoS0VSTl9JTkZPLCAiaTJvX2NvcmUiLCBtc2cpOwoKCQljb250ZXh0ID0gcmVhZGwoJnBtc2ctPnUucy50Y250eHQpOwoKCQkvKiBSZWxlYXNlIHRoZSBwcmVzZXJ2ZWQgbXNnICovCgkJaTJvX21zZ19ub3AoYywgcG0pOwoJfSBlbHNlCgkJY29udGV4dCA9IGxlMzJfdG9fY3B1KG1zZy0+dS5zLnRjbnR4dCk7CgoJaWYgKGNvbnRleHQgJiAweDgwMDAwMDAwKQoJCXJldHVybiBpMm9fbXNnX3Bvc3Rfd2FpdF9jb21wbGV0ZShjLCBtLCBtc2csIGNvbnRleHQpOwoKCWlmICgobGUzMl90b19jcHUobXNnLT51LmhlYWRbMV0pID4+IDI0KSA9PSBJMk9fQ01EX0xDVF9OT1RJRlkpIHsKCQlzdHJ1Y3Qgd29ya19zdHJ1Y3QgKndvcms7CgoJCXByX2RlYnVnKCIlczogTENUIG5vdGlmeSByZWNlaXZlZFxuIiwgYy0+bmFtZSk7CgoJCXdvcmsgPSBrbWFsbG9jKHNpemVvZigqd29yayksIEdGUF9BVE9NSUMpOwoJCWlmICghd29yaykKCQkJcmV0dXJuIC1FTk9NRU07CgoJCUlOSVRfV09SSyh3b3JrLCAodm9pZCAoKikodm9pZCAqKSlpMm9fZXhlY19sY3RfbW9kaWZpZWQsIGMpOwoJCXF1ZXVlX3dvcmsoaTJvX2V4ZWNfZHJpdmVyLmV2ZW50X3F1ZXVlLCB3b3JrKTsKCQlyZXR1cm4gMTsKCX0KCgkvKgoJICogSWYgdGhpcyBoYXBwZW5zLCB3ZSB3YW50IHRvIGR1bXAgdGhlIG1lc3NhZ2UgdG8gdGhlIHN5c2xvZyBzbwoJICogaXQgY2FuIGJlIHNlbnQgYmFjayB0byB0aGUgY2FyZCBtYW51ZmFjdHVyZXIgYnkgdGhlIGVuZCB1c2VyCgkgKiB0byBhaWQgaW4gZGVidWdnaW5nLgoJICoKCSAqLwoJcHJpbnRrKEtFUk5fV0FSTklORyAiJXM6IFVuc29saWNpdGVkIG1lc3NhZ2UgcmVwbHkgc2VudCB0byBjb3JlISIKCSAgICAgICAiTWVzc2FnZSBkdW1wZWQgdG8gc3lzbG9nXG4iLCBjLT5uYW1lKTsKCWkyb19kdW1wX21lc3NhZ2UobXNnKTsKCglyZXR1cm4gLUVGQVVMVDsKfQoKLyoqCiAqCWkyb19leGVjX2V2ZW50IC0gRXZlbnQgaGFuZGxpbmcgZnVuY3Rpb24KICoJQGV2dDogRXZlbnQgd2hpY2ggb2NjdXJzCiAqCiAqCUhhbmRsZXMgZXZlbnRzIHNlbmQgYnkgdGhlIEV4ZWN1dGl2ZSBkZXZpY2UuIEF0IHRoZSBtb21lbnQgZG9lcyBub3QgZG8KICoJYW55dGhpbmcgdXNlZnVsLgogKi8Kc3RhdGljIHZvaWQgaTJvX2V4ZWNfZXZlbnQoc3RydWN0IGkyb19ldmVudCAqZXZ0KQp7CglpZiAobGlrZWx5KGV2dC0+aTJvX2RldikpCgkJb3NtX2RlYnVnKCJFdmVudCByZWNlaXZlZCBmcm9tIGRldmljZTogJWRcbiIsCgkJCSAgZXZ0LT5pMm9fZGV2LT5sY3RfZGF0YS50aWQpOwoJa2ZyZWUoZXZ0KTsKfTsKCi8qKgogKglpMm9fZXhlY19sY3RfZ2V0IC0gR2V0IHRoZSBJT1AncyBMb2dpY2FsIENvbmZpZ3VyYXRpb24gVGFibGUKICoJQGM6IEkyTyBjb250cm9sbGVyIGZyb20gd2hpY2ggdGhlIExDVCBzaG91bGQgYmUgZmV0Y2hlZAogKgogKglTZW5kIGEgTENUIE5PVElGWSByZXF1ZXN0IHRvIHRoZSBjb250cm9sbGVyLCBhbmQgd2FpdAogKglJMk9fVElNRU9VVF9MQ1RfR0VUIHNlY29uZHMgdW50aWwgYXJyaXZhbCBvZiByZXNwb25zZS4gSWYgdGhlIExDVCBpcwogKgl0byBsYXJnZSwgcmV0cnkgaXQuCiAqCiAqCVJldHVybnMgMCBvbiBzdWNjZXNzIG9yIG5lZ2F0aXZlIGVycm9yIGNvZGUgb24gZmFpbHVyZS4KICovCmludCBpMm9fZXhlY19sY3RfZ2V0KHN0cnVjdCBpMm9fY29udHJvbGxlciAqYykKewoJc3RydWN0IGkyb19tZXNzYWdlIF9faW9tZW0gKm1zZzsKCXUzMiBtOwoJaW50IGkgPSAwOwoJaW50IHJjID0gLUVBR0FJTjsKCglmb3IgKGkgPSAxOyBpIDw9IEkyT19MQ1RfR0VUX1RSSUVTOyBpKyspIHsKCQltID0gaTJvX21zZ19nZXRfd2FpdChjLCAmbXNnLCBJMk9fVElNRU9VVF9NRVNTQUdFX0dFVCk7CgkJaWYgKG0gPT0gSTJPX1FVRVVFX0VNUFRZKQoJCQlyZXR1cm4gLUVUSU1FRE9VVDsKCgkJd3JpdGVsKEVJR0hUX1dPUkRfTVNHX1NJWkUgfCBTR0xfT0ZGU0VUXzYsICZtc2ctPnUuaGVhZFswXSk7CgkJd3JpdGVsKEkyT19DTURfTENUX05PVElGWSA8PCAyNCB8IEhPU1RfVElEIDw8IDEyIHwgQURBUFRFUl9USUQsCgkJICAgICAgICZtc2ctPnUuaGVhZFsxXSk7CgkJd3JpdGVsKDB4ZmZmZmZmZmYsICZtc2ctPmJvZHlbMF0pOwoJCXdyaXRlbCgweDAwMDAwMDAwLCAmbXNnLT5ib2R5WzFdKTsKCQl3cml0ZWwoMHhkMDAwMDAwMCB8IGMtPmRsY3QubGVuLCAmbXNnLT5ib2R5WzJdKTsKCQl3cml0ZWwoYy0+ZGxjdC5waHlzLCAmbXNnLT5ib2R5WzNdKTsKCgkJcmMgPSBpMm9fbXNnX3Bvc3Rfd2FpdChjLCBtLCBJMk9fVElNRU9VVF9MQ1RfR0VUKTsKCQlpZiAocmMgPCAwKQoJCQlicmVhazsKCgkJcmMgPSBpMm9fZGV2aWNlX3BhcnNlX2xjdChjKTsKCQlpZiAocmMgIT0gLUVBR0FJTikKCQkJYnJlYWs7Cgl9CgoJcmV0dXJuIHJjOwp9CgovKioKICoJaTJvX2V4ZWNfbGN0X25vdGlmeSAtIFNlbmQgYSBhc3luY2hyb251cyBMQ1QgTk9USUZZIHJlcXVlc3QKICoJQGM6IEkyTyBjb250cm9sbGVyIHRvIHdoaWNoIHRoZSByZXF1ZXN0IHNob3VsZCBiZSBzZW5kCiAqCUBjaGFuZ2VfaW5kOiBjaGFuZ2UgaW5kaWNhdG9yCiAqCiAqCVRoaXMgZnVuY3Rpb24gc2VuZHMgYSBMQ1QgTk9USUZZIHJlcXVlc3QgdG8gdGhlIEkyTyBjb250cm9sbGVyIHdpdGgKICoJdGhlIGNoYW5nZSBpbmRpY2F0b3IgY2hhbmdlX2luZC4gSWYgdGhlIGNoYW5nZV9pbmQgPT0gMCB0aGUgY29udHJvbGxlcgogKglyZXBsaWVzIGltbWVkaWF0ZWx5IGFmdGVyIHRoZSByZXF1ZXN0LiBJZiBjaGFuZ2VfaW5kID4gMCB0aGUgcmVwbHkgaXMKICoJc2VuZCBhZnRlciBjaGFuZ2UgaW5kaWNhdG9yIG9mIHRoZSBMQ1QgaXMgPiBjaGFuZ2VfaW5kLgogKi8Kc3RhdGljIGludCBpMm9fZXhlY19sY3Rfbm90aWZ5KHN0cnVjdCBpMm9fY29udHJvbGxlciAqYywgdTMyIGNoYW5nZV9pbmQpCnsKCWkyb19zdGF0dXNfYmxvY2sgKnNiID0gYy0+c3RhdHVzX2Jsb2NrLnZpcnQ7CglzdHJ1Y3QgZGV2aWNlICpkZXY7CglzdHJ1Y3QgaTJvX21lc3NhZ2UgX19pb21lbSAqbXNnOwoJdTMyIG07CgoJZGV2ID0gJmMtPnBkZXYtPmRldjsKCglpZiAoaTJvX2RtYV9yZWFsbG9jKGRldiwgJmMtPmRsY3QsIHNiLT5leHBlY3RlZF9sY3Rfc2l6ZSwgR0ZQX0tFUk5FTCkpCgkJcmV0dXJuIC1FTk9NRU07CgoJbSA9IGkyb19tc2dfZ2V0X3dhaXQoYywgJm1zZywgSTJPX1RJTUVPVVRfTUVTU0FHRV9HRVQpOwoJaWYgKG0gPT0gSTJPX1FVRVVFX0VNUFRZKQoJCXJldHVybiAtRVRJTUVET1VUOwoKCXdyaXRlbChFSUdIVF9XT1JEX01TR19TSVpFIHwgU0dMX09GRlNFVF82LCAmbXNnLT51LmhlYWRbMF0pOwoJd3JpdGVsKEkyT19DTURfTENUX05PVElGWSA8PCAyNCB8IEhPU1RfVElEIDw8IDEyIHwgQURBUFRFUl9USUQsCgkgICAgICAgJm1zZy0+dS5oZWFkWzFdKTsKCXdyaXRlbChpMm9fZXhlY19kcml2ZXIuY29udGV4dCwgJm1zZy0+dS5zLmljbnR4dCk7Cgl3cml0ZWwoMCwgJm1zZy0+dS5zLnRjbnR4dCk7CS8qIEZJWE1FICovCgl3cml0ZWwoMHhmZmZmZmZmZiwgJm1zZy0+Ym9keVswXSk7Cgl3cml0ZWwoY2hhbmdlX2luZCwgJm1zZy0+Ym9keVsxXSk7Cgl3cml0ZWwoMHhkMDAwMDAwMCB8IGMtPmRsY3QubGVuLCAmbXNnLT5ib2R5WzJdKTsKCXdyaXRlbChjLT5kbGN0LnBoeXMsICZtc2ctPmJvZHlbM10pOwoKCWkyb19tc2dfcG9zdChjLCBtKTsKCglyZXR1cm4gMDsKfTsKCi8qIEV4ZWMgT1NNIGRyaXZlciBzdHJ1Y3QgKi8Kc3RydWN0IGkyb19kcml2ZXIgaTJvX2V4ZWNfZHJpdmVyID0gewoJLm5hbWUgPSBPU01fTkFNRSwKCS5yZXBseSA9IGkyb19leGVjX3JlcGx5LAoJLmV2ZW50ID0gaTJvX2V4ZWNfZXZlbnQsCgkuY2xhc3NlcyA9IGkyb19leGVjX2NsYXNzX2lkLAoJLmRyaXZlciA9IHsKCQkgICAucHJvYmUgPSBpMm9fZXhlY19wcm9iZSwKCQkgICAucmVtb3ZlID0gaTJvX2V4ZWNfcmVtb3ZlLAoJCSAgIH0sCn07CgovKioKICoJaTJvX2V4ZWNfaW5pdCAtIFJlZ2lzdGVycyB0aGUgRXhlYyBPU00KICoKICoJUmVnaXN0ZXJzIHRoZSBFeGVjIE9TTSBpbiB0aGUgSTJPIGNvcmUuCiAqCiAqCVJldHVybnMgMCBvbiBzdWNjZXNzIG9yIG5lZ2F0aXZlIGVycm9yIGNvZGUgb24gZmFpbHVyZS4KICovCmludCBfX2luaXQgaTJvX2V4ZWNfaW5pdCh2b2lkKQp7CglyZXR1cm4gaTJvX2RyaXZlcl9yZWdpc3RlcigmaTJvX2V4ZWNfZHJpdmVyKTsKfTsKCi8qKgogKglpMm9fZXhlY19leGl0IC0gUmVtb3ZlcyB0aGUgRXhlYyBPU00KICoKICoJVW5yZWdpc3RlcnMgdGhlIEV4ZWMgT1NNIGZyb20gdGhlIEkyTyBjb3JlLgogKi8Kdm9pZCBfX2V4aXQgaTJvX2V4ZWNfZXhpdCh2b2lkKQp7CglpMm9fZHJpdmVyX3VucmVnaXN0ZXIoJmkyb19leGVjX2RyaXZlcik7Cn07CgpFWFBPUlRfU1lNQk9MKGkyb19tc2dfcG9zdF93YWl0X21lbSk7CkVYUE9SVF9TWU1CT0woaTJvX2V4ZWNfbGN0X2dldCk7Cg==