LyoKICoJRXhlY3V0aXZlIE9TTQogKgogKiAJQ29weXJpZ2h0IChDKSAxOTk5LTIwMDIJUmVkIEhhdCBTb2Z0d2FyZQogKgogKglXcml0dGVuIGJ5IEFsYW4gQ294LCBCdWlsZGluZyBOdW1iZXIgVGhyZWUgTHRkCiAqCiAqCVRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqCXVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZQogKglGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlciB2ZXJzaW9uIDIgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyCiAqCW9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqCUEgbG90IG9mIHRoZSBJMk8gbWVzc2FnZSBzaWRlIGNvZGUgZnJvbSB0aGlzIGlzIHRha2VuIGZyb20gdGhlIFJlZAogKglDcmVlayBSQ1BDSTQ1IGFkYXB0ZXIgZHJpdmVyIGJ5IFJlZCBDcmVlayBDb21tdW5pY2F0aW9ucwogKgogKglGaXhlcy9hZGRpdGlvbnM6CiAqCQlQaGlsaXBwIFJ1bXBmCiAqCQlKdWhhIFNpZXbkbmVuIDxKdWhhLlNpZXZhbmVuQGNzLkhlbHNpbmtpLkZJPgogKgkJQXV2byBI5GtraW5lbiA8QXV2by5IYWtraW5lbkBjcy5IZWxzaW5raS5GST4KICoJCURlZXBhayBTYXhlbmEgPGRlZXBha0BwbGV4aXR5Lm5ldD4KICoJCUJvamkgVCBLYW5uYW50aGFuYW0gPGJvamkudC5rYW5uYW50aGFuYW1AaW50ZWwuY29tPgogKgkJQWxhbiBDb3ggPGFsYW5AcmVkaGF0LmNvbT46CiAqCQkJUG9ydGVkIHRvIExpbnV4IDIuNS4KICoJCU1hcmt1cyBMaWRlbCA8TWFya3VzLkxpZGVsQHNoYWRvd2Nvbm5lY3QuY29tPjoKICoJCQlNaW5vciBmaXhlcyBmb3IgMi42LgogKgkJTWFya3VzIExpZGVsIDxNYXJrdXMuTGlkZWxAc2hhZG93Y29ubmVjdC5jb20+OgogKgkJCVN1cHBvcnQgZm9yIHN5c2ZzIGluY2x1ZGVkLgogKi8KCiNpbmNsdWRlIDxsaW51eC9tb2R1bGUuaD4KI2luY2x1ZGUgPGxpbnV4L2kyby5oPgojaW5jbHVkZSA8bGludXgvZGVsYXkuaD4KCiNkZWZpbmUgT1NNX05BTUUgImV4ZWMtb3NtIgoKc3RydWN0IGkyb19kcml2ZXIgaTJvX2V4ZWNfZHJpdmVyOwoKc3RhdGljIGludCBpMm9fZXhlY19sY3Rfbm90aWZ5KHN0cnVjdCBpMm9fY29udHJvbGxlciAqYywgdTMyIGNoYW5nZV9pbmQpOwoKLyogTW9kdWxlIGludGVybmFsIGZ1bmN0aW9ucyBmcm9tIG90aGVyIHNvdXJjZXMgKi8KZXh0ZXJuIGludCBpMm9fZGV2aWNlX3BhcnNlX2xjdChzdHJ1Y3QgaTJvX2NvbnRyb2xsZXIgKik7CgovKiBnbG9iYWwgd2FpdCBsaXN0IGZvciBQT1NUIFdBSVQgKi8Kc3RhdGljIExJU1RfSEVBRChpMm9fZXhlY193YWl0X2xpc3QpOwoKLyogV2FpdCBzdHJ1Y3QgbmVlZGVkIGZvciBQT1NUIFdBSVQgKi8Kc3RydWN0IGkyb19leGVjX3dhaXQgewoJd2FpdF9xdWV1ZV9oZWFkX3QgKndxOwkvKiBQb2ludGVyIHRvIFdhaXQgcXVldWUgKi8KCXN0cnVjdCBpMm9fZG1hIGRtYTsJLyogRE1BIGJ1ZmZlcnMgdG8gZnJlZSBvbiBmYWlsdXJlICovCgl1MzIgdGNudHh0OwkJLyogdHJhbnNhY3Rpb24gY29udGV4dCBmcm9tIHJlcGx5ICovCglpbnQgY29tcGxldGU7CQkvKiAxIGlmIHJlcGx5IHJlY2VpdmVkIG90aGVyd2lzZSAwICovCgl1MzIgbTsJCQkvKiBtZXNzYWdlIGlkICovCglzdHJ1Y3QgaTJvX21lc3NhZ2UgX19pb21lbSAqbXNnOwkvKiBwb2ludGVyIHRvIHRoZSByZXBseSBtZXNzYWdlICovCglzdHJ1Y3QgbGlzdF9oZWFkIGxpc3Q7CS8qIG5vZGUgaW4gZ2xvYmFsIHdhaXQgbGlzdCAqLwp9OwoKLyogRXhlYyBPU00gY2xhc3MgaGFuZGxpbmcgZGVmaW5pdGlvbiAqLwpzdGF0aWMgc3RydWN0IGkyb19jbGFzc19pZCBpMm9fZXhlY19jbGFzc19pZFtdID0gewoJe0kyT19DTEFTU19FWEVDVVRJVkV9LAoJe0kyT19DTEFTU19FTkR9Cn07CgovKioKICoJaTJvX2V4ZWNfd2FpdF9hbGxvYyAtIEFsbG9jYXRlIGEgaTJvX2V4ZWNfd2FpdCBzdHJ1Y3QgYW4gaW5pdGlhbGl6ZSBpdAogKgogKglBbGxvY2F0ZSB0aGUgaTJvX2V4ZWNfd2FpdCBzdHJ1Y3QgYW5kIGluaXRpYWxpemUgdGhlIHdhaXQuCiAqCiAqCVJldHVybnMgaTJvX2V4ZWNfd2FpdCBwb2ludGVyIG9uIHN1Y2Nlc3Mgb3IgbmVnYXRpdmUgZXJyb3IgY29kZSBvbgogKglmYWlsdXJlLgogKi8Kc3RhdGljIHN0cnVjdCBpMm9fZXhlY193YWl0ICppMm9fZXhlY193YWl0X2FsbG9jKHZvaWQpCnsKCXN0cnVjdCBpMm9fZXhlY193YWl0ICp3YWl0OwoKCXdhaXQgPSBrbWFsbG9jKHNpemVvZigqd2FpdCksIEdGUF9LRVJORUwpOwoJaWYgKCF3YWl0KQoJCXJldHVybiBFUlJfUFRSKC1FTk9NRU0pOwoKCW1lbXNldCh3YWl0LCAwLCBzaXplb2YoKndhaXQpKTsKCglJTklUX0xJU1RfSEVBRCgmd2FpdC0+bGlzdCk7CgoJcmV0dXJuIHdhaXQ7Cn07CgovKioKICoJaTJvX2V4ZWNfd2FpdF9mcmVlIC0gRnJlZSBhIGkyb19leGVjX3dhaXQgc3RydWN0CiAqCUBpMm9fZXhlY193YWl0OiBJMk8gd2FpdCBkYXRhIHdoaWNoIHNob3VsZCBiZSBjbGVhbmVkIHVwCiAqLwpzdGF0aWMgdm9pZCBpMm9fZXhlY193YWl0X2ZyZWUoc3RydWN0IGkyb19leGVjX3dhaXQgKndhaXQpCnsKCWtmcmVlKHdhaXQpOwp9OwoKLyoqCiAqIAlpMm9fbXNnX3Bvc3Rfd2FpdF9tZW0gLSBQb3N0IGFuZCB3YWl0IGEgbWVzc2FnZSB3aXRoIERNQSBidWZmZXJzCiAqCUBjOiBjb250cm9sbGVyCiAqCUBtOiBtZXNzYWdlIHRvIHBvc3QKICoJQHRpbWVvdXQ6IHRpbWUgaW4gc2Vjb25kcyB0byB3YWl0CiAqCUBkbWE6IGkyb19kbWEgc3RydWN0IG9mIHRoZSBETUEgYnVmZmVyIHRvIGZyZWUgb24gZmFpbHVyZQogKgogKiAJVGhpcyBBUEkgYWxsb3dzIGFuIE9TTSB0byBwb3N0IGEgbWVzc2FnZSBhbmQgdGhlbiBiZSB0b2xkIHdoZXRoZXIgb3IKICoJbm90IHRoZSBzeXN0ZW0gcmVjZWl2ZWQgYSBzdWNjZXNzZnVsIHJlcGx5LiBJZiB0aGUgbWVzc2FnZSB0aW1lcyBvdXQKICoJdGhlbiB0aGUgdmFsdWUgJy1FVElNRURPVVQnIGlzIHJldHVybmVkLiBUaGlzIGlzIGEgc3BlY2lhbCBjYXNlLiBJbgogKgl0aGlzIHNpdHVhdGlvbiB0aGUgbWVzc2FnZSBtYXkgKHNob3VsZCkgY29tcGxldGUgYXQgYW4gaW5kZWZpbml0ZSB0aW1lCiAqCWluIHRoZSBmdXR1cmUuIFdoZW4gaXQgY29tcGxldGVzIGl0IHdpbGwgdXNlIHRoZSBtZW1vcnkgYnVmZmVyCiAqCWF0dGFjaGVkIHRvIHRoZSByZXF1ZXN0LiBJZiAtRVRJTUVET1VUIGlzIHJldHVybmVkIHRoZW4gdGhlIG1lbW9yeQogKglidWZmZXIgbXVzdCBub3QgYmUgZnJlZWQuIEluc3RlYWQgdGhlIGV2ZW50IGNvbXBsZXRpb24gd2lsbCBmcmVlIHRoZW0KICoJZm9yIHlvdS4gSW4gYWxsIG90aGVyIGNhc2VzIHRoZSBidWZmZXIgYXJlIHlvdXIgcHJvYmxlbS4KICoKICoJUmV0dXJucyAwIG9uIHN1Y2Nlc3MsIG5lZ2F0aXZlIGVycm9yIGNvZGUgb24gdGltZW91dCBvciBwb3NpdGl2ZSBlcnJvcgogKgljb2RlIGZyb20gcmVwbHkuCiAqLwppbnQgaTJvX21zZ19wb3N0X3dhaXRfbWVtKHN0cnVjdCBpMm9fY29udHJvbGxlciAqYywgdTMyIG0sIHVuc2lnbmVkIGxvbmcKCQkJICB0aW1lb3V0LCBzdHJ1Y3QgaTJvX2RtYSAqZG1hKQp7CglERUNMQVJFX1dBSVRfUVVFVUVfSEVBRCh3cSk7CglzdHJ1Y3QgaTJvX2V4ZWNfd2FpdCAqd2FpdDsKCXN0YXRpYyB1MzIgdGNudHh0ID0gMHg4MDAwMDAwMDsKCXN0cnVjdCBpMm9fbWVzc2FnZSBfX2lvbWVtICptc2cgPSBpMm9fbXNnX2luX3RvX3ZpcnQoYywgbSk7CglpbnQgcmMgPSAwOwoKCXdhaXQgPSBpMm9fZXhlY193YWl0X2FsbG9jKCk7CglpZiAoIXdhaXQpCgkJcmV0dXJuIC1FTk9NRU07CgoJaWYgKHRjbnR4dCA9PSAweGZmZmZmZmZmKQoJCXRjbnR4dCA9IDB4ODAwMDAwMDA7CgoJaWYgKGRtYSkKCQl3YWl0LT5kbWEgPSAqZG1hOwoKCS8qCgkgKiBGaWxsIGluIHRoZSBtZXNzYWdlIGluaXRpYXRvciBjb250ZXh0IGFuZCB0cmFuc2FjdGlvbiBjb250ZXh0LgoJICogV2Ugd2lsbCBvbmx5IHVzZSB0cmFuc2FjdGlvbiBjb250ZXh0cyA+PSAweDgwMDAwMDAwIGZvciBQT1NUIFdBSVQsCgkgKiBzbyB3ZSBjb3VsZCBmaW5kIGEgUE9TVCBXQUlUIHJlcGx5IGVhc2llciBpbiB0aGUgcmVwbHkgaGFuZGxlci4KCSAqLwoJd3JpdGVsKGkyb19leGVjX2RyaXZlci5jb250ZXh0LCAmbXNnLT51LnMuaWNudHh0KTsKCXdhaXQtPnRjbnR4dCA9IHRjbnR4dCsrOwoJd3JpdGVsKHdhaXQtPnRjbnR4dCwgJm1zZy0+dS5zLnRjbnR4dCk7CgoJLyoKCSAqIFBvc3QgdGhlIG1lc3NhZ2UgdG8gdGhlIGNvbnRyb2xsZXIuIEF0IHNvbWUgcG9pbnQgbGF0ZXIgaXQgd2lsbAoJICogcmV0dXJuLiBJZiB3ZSB0aW1lIG91dCBiZWZvcmUgaXQgcmV0dXJucyB0aGVuIGNvbXBsZXRlIHdpbGwgYmUgemVyby4KCSAqLwoJaTJvX21zZ19wb3N0KGMsIG0pOwoKCWlmICghd2FpdC0+Y29tcGxldGUpIHsKCQl3YWl0LT53cSA9ICZ3cTsKCQkvKgoJCSAqIHdlIGFkZCBlbGVtZW50cyBhZGQgdGhlIGhlYWQsIGJlY2F1c2UgaWYgYSBlbnRyeSBpbiB0aGUgbGlzdAoJCSAqIHdpbGwgbmV2ZXIgYmUgcmVtb3ZlZCwgd2UgaGF2ZSB0byBpdGVyYXRlIG92ZXIgaXQgZXZlcnkgdGltZQoJCSAqLwoJCWxpc3RfYWRkKCZ3YWl0LT5saXN0LCAmaTJvX2V4ZWNfd2FpdF9saXN0KTsKCgkJd2FpdF9ldmVudF9pbnRlcnJ1cHRpYmxlX3RpbWVvdXQod3EsIHdhaXQtPmNvbXBsZXRlLAoJCQl0aW1lb3V0ICogSFopOwoKCQl3YWl0LT53cSA9IE5VTEw7Cgl9CgoJYmFycmllcigpOwoKCWlmICh3YWl0LT5jb21wbGV0ZSkgewoJCXJjID0gcmVhZGwoJndhaXQtPm1zZy0+Ym9keVswXSkgPj4gMjQ7CgkJaTJvX2ZsdXNoX3JlcGx5KGMsIHdhaXQtPm0pOwoJCWkyb19leGVjX3dhaXRfZnJlZSh3YWl0KTsKCX0gZWxzZSB7CgkJLyoKCQkgKiBXZSBjYW5ub3QgcmVtb3ZlIGl0IG5vdy4gVGhpcyBpcyBpbXBvcnRhbnQuIFdoZW4gaXQgZG9lcwoJCSAqIHRlcm1pbmF0ZSAod2hpY2ggaXQgbXVzdCBkbyBpZiB0aGUgY29udHJvbGxlciBoYXMgbm90CgkJICogZGllZC4uLikgdGhlbiBpdCB3aWxsIG90aGVyd2lzZSBzY3JpYmJsZSBvbiBzdHVmZi4KCQkgKgoJCSAqIEZJWE1FOiB0cnkgYWJvcnQgbWVzc2FnZQoJCSAqLwoJCWlmIChkbWEpCgkJCWRtYS0+dmlydCA9IE5VTEw7CgoJCXJjID0gLUVUSU1FRE9VVDsKCX0KCglyZXR1cm4gcmM7Cn07CgovKioKICoJaTJvX21zZ19wb3N0X3dhaXRfY29tcGxldGUgLSBSZXBseSB0byBhIGkyb19tc2dfcG9zdCByZXF1ZXN0IGZyb20gSU9QCiAqCUBjOiBJMk8gY29udHJvbGxlciB3aGljaCBhbnN3ZXJzCiAqCUBtOiBtZXNzYWdlIGlkCiAqCUBtc2c6IHBvaW50ZXIgdG8gdGhlIEkyTyByZXBseSBtZXNzYWdlCiAqCUBjb250ZXh0OiB0cmFuc2FjdGlvbiBjb250ZXh0IG9mIHJlcXVlc3QKICoKICoJVGhpcyBmdW5jdGlvbiBpcyBjYWxsZWQgaW4gaW50ZXJydXB0IGNvbnRleHQgb25seS4gSWYgdGhlIHJlcGx5IHJlYWNoZWQKICoJYmVmb3JlIHRoZSB0aW1lb3V0LCB0aGUgaTJvX2V4ZWNfd2FpdCBzdHJ1Y3QgaXMgZmlsbGVkIHdpdGggdGhlIG1lc3NhZ2UKICoJYW5kIHRoZSB0YXNrIHdpbGwgYmUgd2FrZWQgdXAuIFRoZSB0YXNrIGlzIG5vdyByZXNwb25zaWJsZSBmb3IgcmV0dXJuaW5nCiAqCXRoZSBtZXNzYWdlIG0gYmFjayB0byB0aGUgY29udHJvbGxlciEgSWYgdGhlIG1lc3NhZ2UgcmVhY2hlcyB1cyBhZnRlcgogKgl0aGUgdGltZW91dCBjbGVhbiB1cCB0aGUgaTJvX2V4ZWNfd2FpdCBzdHJ1Y3QgKGluY2x1ZGluZyBhbGxvY2F0ZWQKICoJRE1BIGJ1ZmZlcikuCiAqCiAqCVJldHVybiAwIG9uIHN1Y2Nlc3MgYW5kIGlmIHRoZSBtZXNzYWdlIG0gc2hvdWxkIG5vdCBiZSBnaXZlbiBiYWNrIHRvIHRoZQogKglJMk8gY29udHJvbGxlciwgb3IgPjAgb24gc3VjY2VzcyBhbmQgaWYgdGhlIG1lc3NhZ2Ugc2hvdWxkIGJlIGdpdmVuIGJhY2sKICoJYWZ0ZXJ3b3Jkcy4gUmV0dXJucyBuZWdhdGl2ZSBlcnJvciBjb2RlIG9uIGZhaWx1cmUuIEluIHRoaXMgY2FzZSB0aGUKICoJbWVzc2FnZSBtdXN0IGFsc28gYmUgZ2l2ZW4gYmFjayB0byB0aGUgY29udHJvbGxlci4KICovCnN0YXRpYyBpbnQgaTJvX21zZ19wb3N0X3dhaXRfY29tcGxldGUoc3RydWN0IGkyb19jb250cm9sbGVyICpjLCB1MzIgbSwKCQkJCSAgICAgIHN0cnVjdCBpMm9fbWVzc2FnZSBfX2lvbWVtICptc2csCgkJCQkgICAgICB1MzIgY29udGV4dCkKewoJc3RydWN0IGkyb19leGVjX3dhaXQgKndhaXQsICp0bXA7Cgl1bnNpZ25lZCBsb25nIGZsYWdzOwoJc3RhdGljIHNwaW5sb2NrX3QgbG9jayA9IFNQSU5fTE9DS19VTkxPQ0tFRDsKCWludCByYyA9IDE7CgoJLyoKCSAqIFdlIG5lZWQgdG8gc2VhcmNoIHRocm91Z2ggdGhlIGkyb19leGVjX3dhaXRfbGlzdCB0byBzZWUgaWYgdGhlIGdpdmVuCgkgKiBtZXNzYWdlIGlzIHN0aWxsIG91dHN0YW5kaW5nLiBJZiBub3QsIGl0IG1lYW5zIHRoYXQgdGhlIElPUCB0b29rCgkgKiBsb25nZXIgdG8gcmVzcG9uZCB0byB0aGUgbWVzc2FnZSB0aGFuIHdlIGhhZCBhbGxvd2VkIGFuZCB0aW1lciBoYXMKCSAqIGFscmVhZHkgZXhwaXJlZC4gTm90IG11Y2ggd2UgY2FuIGRvIGFib3V0IHRoYXQgZXhjZXB0IGxvZyBpdCBmb3IKCSAqIGRlYnVnIHB1cnBvc2VzLCBpbmNyZWFzZSB0aW1lb3V0LCBhbmQgcmVjb21waWxlLgoJICovCglzcGluX2xvY2tfaXJxc2F2ZSgmbG9jaywgZmxhZ3MpOwoJbGlzdF9mb3JfZWFjaF9lbnRyeV9zYWZlKHdhaXQsIHRtcCwgJmkyb19leGVjX3dhaXRfbGlzdCwgbGlzdCkgewoJCWlmICh3YWl0LT50Y250eHQgPT0gY29udGV4dCkgewoJCQlsaXN0X2RlbCgmd2FpdC0+bGlzdCk7CgoJCQlzcGluX3VubG9ja19pcnFyZXN0b3JlKCZsb2NrLCBmbGFncyk7CgoJCQl3YWl0LT5tID0gbTsKCQkJd2FpdC0+bXNnID0gbXNnOwoJCQl3YWl0LT5jb21wbGV0ZSA9IDE7CgoJCQliYXJyaWVyKCk7CgoJCQlpZiAod2FpdC0+d3EpIHsKCQkJCXdha2VfdXBfaW50ZXJydXB0aWJsZSh3YWl0LT53cSk7CgkJCQlyYyA9IDA7CgkJCX0gZWxzZSB7CgkJCQlzdHJ1Y3QgZGV2aWNlICpkZXY7CgoJCQkJZGV2ID0gJmMtPnBkZXYtPmRldjsKCgkJCQlwcl9kZWJ1ZygiJXM6IHRpbWVkb3V0IHJlcGx5IHJlY2VpdmVkIVxuIiwKCQkJCQkgYy0+bmFtZSk7CgkJCQlpMm9fZG1hX2ZyZWUoZGV2LCAmd2FpdC0+ZG1hKTsKCQkJCWkyb19leGVjX3dhaXRfZnJlZSh3YWl0KTsKCQkJCXJjID0gLTE7CgkJCX0KCgkJCXJldHVybiByYzsKCQl9Cgl9CgoJc3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmbG9jaywgZmxhZ3MpOwoKCW9zbV93YXJuKCIlczogQm9ndXMgcmVwbHkgaW4gUE9TVCBXQUlUICh0ci1jb250ZXh0OiAlMDh4KSFcbiIsIGMtPm5hbWUsCgkJIGNvbnRleHQpOwoKCXJldHVybiAtMTsKfTsKCi8qKgogKglpMm9fZXhlY19zaG93X3ZlbmRvcl9pZCAtIERpc3BsYXlzIFZlbmRvciBJRCBvZiBjb250cm9sbGVyCiAqCUBkOiBkZXZpY2Ugb2Ygd2hpY2ggdGhlIFZlbmRvciBJRCBzaG91bGQgYmUgZGlzcGxheWVkCiAqCUBidWY6IGJ1ZmZlciBpbnRvIHdoaWNoIHRoZSBWZW5kb3IgSUQgc2hvdWxkIGJlIHByaW50ZWQKICoKICoJUmV0dXJucyBudW1iZXIgb2YgYnl0ZXMgcHJpbnRlZCBpbnRvIGJ1ZmZlci4KICovCnN0YXRpYyBzc2l6ZV90IGkyb19leGVjX3Nob3dfdmVuZG9yX2lkKHN0cnVjdCBkZXZpY2UgKmQsIGNoYXIgKmJ1ZikKewoJc3RydWN0IGkyb19kZXZpY2UgKmRldiA9IHRvX2kyb19kZXZpY2UoZCk7Cgl1MTYgaWQ7CgoJaWYgKGkyb19wYXJtX2ZpZWxkX2dldChkZXYsIDB4MDAwMCwgMCwgJmlkLCAyKSkgewoJCXNwcmludGYoYnVmLCAiMHglMDR4IiwgaWQpOwoJCXJldHVybiBzdHJsZW4oYnVmKSArIDE7Cgl9CgoJcmV0dXJuIDA7Cn07CgovKioKICoJaTJvX2V4ZWNfc2hvd19wcm9kdWN0X2lkIC0gRGlzcGxheXMgUHJvZHVjdCBJRCBvZiBjb250cm9sbGVyCiAqCUBkOiBkZXZpY2Ugb2Ygd2hpY2ggdGhlIFByb2R1Y3QgSUQgc2hvdWxkIGJlIGRpc3BsYXllZAogKglAYnVmOiBidWZmZXIgaW50byB3aGljaCB0aGUgUHJvZHVjdCBJRCBzaG91bGQgYmUgcHJpbnRlZAogKgogKglSZXR1cm5zIG51bWJlciBvZiBieXRlcyBwcmludGVkIGludG8gYnVmZmVyLgogKi8Kc3RhdGljIHNzaXplX3QgaTJvX2V4ZWNfc2hvd19wcm9kdWN0X2lkKHN0cnVjdCBkZXZpY2UgKmQsIGNoYXIgKmJ1ZikKewoJc3RydWN0IGkyb19kZXZpY2UgKmRldiA9IHRvX2kyb19kZXZpY2UoZCk7Cgl1MTYgaWQ7CgoJaWYgKGkyb19wYXJtX2ZpZWxkX2dldChkZXYsIDB4MDAwMCwgMSwgJmlkLCAyKSkgewoJCXNwcmludGYoYnVmLCAiMHglMDR4IiwgaWQpOwoJCXJldHVybiBzdHJsZW4oYnVmKSArIDE7Cgl9CgoJcmV0dXJuIDA7Cn07CgovKiBFeGVjLU9TTSBkZXZpY2UgYXR0cmlidXRlcyAqLwpzdGF0aWMgREVWSUNFX0FUVFIodmVuZG9yX2lkLCBTX0lSVUdPLCBpMm9fZXhlY19zaG93X3ZlbmRvcl9pZCwgTlVMTCk7CnN0YXRpYyBERVZJQ0VfQVRUUihwcm9kdWN0X2lkLCBTX0lSVUdPLCBpMm9fZXhlY19zaG93X3Byb2R1Y3RfaWQsIE5VTEwpOwoKLyoqCiAqCWkyb19leGVjX3Byb2JlIC0gQ2FsbGVkIGlmIGEgbmV3IEkyTyBkZXZpY2UgKGV4ZWN1dGl2ZSBjbGFzcykgYXBwZWFycwogKglAZGV2OiBJMk8gZGV2aWNlIHdoaWNoIHNob3VsZCBiZSBwcm9iZWQKICoKICoJUmVnaXN0ZXJzIGV2ZW50IG5vdGlmaWNhdGlvbiBmb3IgZXZlcnkgZXZlbnQgZnJvbSBFeGVjdXRpdmUgZGV2aWNlLiBUaGUKICoJcmV0dXJuIGlzIGFsd2F5cyAwLCBiZWNhdXNlIHdlIHdhbnQgYWxsIGRldmljZXMgb2YgY2xhc3MgRXhlY3V0aXZlLgogKgogKglSZXR1cm5zIDAgb24gc3VjY2Vzcy4KICovCnN0YXRpYyBpbnQgaTJvX2V4ZWNfcHJvYmUoc3RydWN0IGRldmljZSAqZGV2KQp7CglzdHJ1Y3QgaTJvX2RldmljZSAqaTJvX2RldiA9IHRvX2kyb19kZXZpY2UoZGV2KTsKCXN0cnVjdCBpMm9fY29udHJvbGxlciAqYyA9IGkyb19kZXYtPmlvcDsKCglpMm9fZXZlbnRfcmVnaXN0ZXIoaTJvX2RldiwgJmkyb19leGVjX2RyaXZlciwgMCwgMHhmZmZmZmZmZik7CgoJYy0+ZXhlYyA9IGkyb19kZXY7CgoJaTJvX2V4ZWNfbGN0X25vdGlmeShjLCBjLT5sY3QtPmNoYW5nZV9pbmQgKyAxKTsKCglkZXZpY2VfY3JlYXRlX2ZpbGUoZGV2LCAmZGV2X2F0dHJfdmVuZG9yX2lkKTsKCWRldmljZV9jcmVhdGVfZmlsZShkZXYsICZkZXZfYXR0cl9wcm9kdWN0X2lkKTsKCglyZXR1cm4gMDsKfTsKCi8qKgogKglpMm9fZXhlY19yZW1vdmUgLSBDYWxsZWQgb24gSTJPIGRldmljZSByZW1vdmFsCiAqCUBkZXY6IEkyTyBkZXZpY2Ugd2hpY2ggd2FzIHJlbW92ZWQKICoKICoJVW5yZWdpc3RlcnMgZXZlbnQgbm90aWZpY2F0aW9uIGZyb20gRXhlY3V0aXZlIEkyTyBkZXZpY2UuCiAqCiAqCVJldHVybnMgMCBvbiBzdWNjZXNzLgogKi8Kc3RhdGljIGludCBpMm9fZXhlY19yZW1vdmUoc3RydWN0IGRldmljZSAqZGV2KQp7CglkZXZpY2VfcmVtb3ZlX2ZpbGUoZGV2LCAmZGV2X2F0dHJfcHJvZHVjdF9pZCk7CglkZXZpY2VfcmVtb3ZlX2ZpbGUoZGV2LCAmZGV2X2F0dHJfdmVuZG9yX2lkKTsKCglpMm9fZXZlbnRfcmVnaXN0ZXIodG9faTJvX2RldmljZShkZXYpLCAmaTJvX2V4ZWNfZHJpdmVyLCAwLCAwKTsKCglyZXR1cm4gMDsKfTsKCi8qKgogKglpMm9fZXhlY19sY3RfbW9kaWZpZWQgLSBDYWxsZWQgb24gTENUIE5PVElGWSByZXBseQogKglAYzogSTJPIGNvbnRyb2xsZXIgb24gd2hpY2ggdGhlIExDVCBoYXMgbW9kaWZpZWQKICoKICoJVGhpcyBmdW5jdGlvbiBoYW5kbGVzIGFzeW5jaHJvbnVzIExDVCBOT1RJRlkgcmVwbGllcy4gSXQgcGFyc2VzIHRoZQogKgluZXcgTENUIGFuZCBpZiB0aGUgYnVmZmVyIGZvciB0aGUgTENUIHdhcyB0byBzbWFsbCBzZW5kcyBhIExDVCBOT1RJRlkKICoJYWdhaW4sIG90aGVyd2lzZSBzZW5kIExDVCBOT1RJRlkgdG8gZ2V0IGluZm9ybWVkIG9uIG5leHQgTENUIGNoYW5nZS4KICovCnN0YXRpYyB2b2lkIGkyb19leGVjX2xjdF9tb2RpZmllZChzdHJ1Y3QgaTJvX2NvbnRyb2xsZXIgKmMpCnsKCXUzMiBjaGFuZ2VfaW5kID0gMDsKCglpZiAoaTJvX2RldmljZV9wYXJzZV9sY3QoYykgIT0gLUVBR0FJTikKCQljaGFuZ2VfaW5kID0gYy0+bGN0LT5jaGFuZ2VfaW5kICsgMTsKCglpMm9fZXhlY19sY3Rfbm90aWZ5KGMsIGNoYW5nZV9pbmQpOwp9OwoKLyoqCiAqCWkyb19leGVjX3JlcGx5IC0gIEkyTyBFeGVjdXRpdmUgcmVwbHkgaGFuZGxlcgogKglAYzogSTJPIGNvbnRyb2xsZXIgZnJvbSB3aGljaCB0aGUgcmVwbHkgY29tZXMKICoJQG06IG1lc3NhZ2UgaWQKICoJQG1zZzogcG9pbnRlciB0byB0aGUgSTJPIHJlcGx5IG1lc3NhZ2UKICoKICoJVGhpcyBmdW5jdGlvbiBpcyBhbHdheXMgY2FsbGVkIGZyb20gaW50ZXJydXB0IGNvbnRleHQuIElmIGEgUE9TVCBXQUlUCiAqCXJlcGx5IHdhcyByZWNlaXZlZCwgcGFzcyBpdCB0byB0aGUgY29tcGxldGUgZnVuY3Rpb24uIElmIGEgTENUIE5PVElGWQogKglyZXBseSB3YXMgcmVjZWl2ZWQsIGEgbmV3IGV2ZW50IGlzIGNyZWF0ZWQgdG8gaGFuZGxlIHRoZSB1cGRhdGUuCiAqCiAqCVJldHVybnMgMCBvbiBzdWNjZXNzIGFuZCBpZiB0aGUgcmVwbHkgc2hvdWxkIG5vdCBiZSBmbHVzaGVkIG9yID4gMAogKglvbiBzdWNjZXNzIGFuZCBpZiB0aGUgcmVwbHkgc2hvdWxkIGJlIGZsdXNoZWQuIFJldHVybnMgbmVnYXRpdmUgZXJyb3IKICoJY29kZSBvbiBmYWlsdXJlIGFuZCBpZiB0aGUgcmVwbHkgc2hvdWxkIGJlIGZsdXNoZWQuCiAqLwpzdGF0aWMgaW50IGkyb19leGVjX3JlcGx5KHN0cnVjdCBpMm9fY29udHJvbGxlciAqYywgdTMyIG0sCgkJCSAgc3RydWN0IGkyb19tZXNzYWdlIF9faW9tZW0gKm1zZykKewoJdTMyIGNvbnRleHQ7CgoJaWYgKHJlYWRsKCZtc2ctPnUuaGVhZFswXSkgJiBNU0dfRkFJTCkgewoJCS8qCgkJICogSWYgRmFpbCBiaXQgaXMgc2V0IHdlIG11c3QgdGFrZSB0aGUgdHJhbnNhY3Rpb24gY29udGV4dCBvZgoJCSAqIHRoZSBwcmVzZXJ2ZWQgbWVzc2FnZSB0byBmaW5kIHRoZSByaWdodCByZXF1ZXN0IGFnYWluLgoJCSAqLwoJCXN0cnVjdCBpMm9fbWVzc2FnZSBfX2lvbWVtICpwbXNnOwoJCXUzMiBwbTsKCgkJcG0gPSByZWFkbCgmbXNnLT5ib2R5WzNdKTsKCgkJcG1zZyA9IGkyb19tc2dfaW5fdG9fdmlydChjLCBwbSk7CgoJCWkyb19yZXBvcnRfc3RhdHVzKEtFUk5fSU5GTywgImkyb19jb3JlIiwgbXNnKTsKCgkJY29udGV4dCA9IHJlYWRsKCZwbXNnLT51LnMudGNudHh0KTsKCgkJLyogUmVsZWFzZSB0aGUgcHJlc2VydmVkIG1zZyAqLwoJCWkyb19tc2dfbm9wKGMsIHBtKTsKCX0gZWxzZQoJCWNvbnRleHQgPSByZWFkbCgmbXNnLT51LnMudGNudHh0KTsKCglpZiAoY29udGV4dCAmIDB4ODAwMDAwMDApCgkJcmV0dXJuIGkyb19tc2dfcG9zdF93YWl0X2NvbXBsZXRlKGMsIG0sIG1zZywgY29udGV4dCk7CgoJaWYgKChyZWFkbCgmbXNnLT51LmhlYWRbMV0pID4+IDI0KSA9PSBJMk9fQ01EX0xDVF9OT1RJRlkpIHsKCQlzdHJ1Y3Qgd29ya19zdHJ1Y3QgKndvcms7CgoJCXByX2RlYnVnKCIlczogTENUIG5vdGlmeSByZWNlaXZlZFxuIiwgYy0+bmFtZSk7CgoJCXdvcmsgPSBrbWFsbG9jKHNpemVvZigqd29yayksIEdGUF9BVE9NSUMpOwoJCWlmICghd29yaykKCQkJcmV0dXJuIC1FTk9NRU07CgoJCUlOSVRfV09SSyh3b3JrLCAodm9pZCAoKikodm9pZCAqKSlpMm9fZXhlY19sY3RfbW9kaWZpZWQsIGMpOwoJCXF1ZXVlX3dvcmsoaTJvX2V4ZWNfZHJpdmVyLmV2ZW50X3F1ZXVlLCB3b3JrKTsKCQlyZXR1cm4gMTsKCX0KCgkvKgoJICogSWYgdGhpcyBoYXBwZW5zLCB3ZSB3YW50IHRvIGR1bXAgdGhlIG1lc3NhZ2UgdG8gdGhlIHN5c2xvZyBzbwoJICogaXQgY2FuIGJlIHNlbnQgYmFjayB0byB0aGUgY2FyZCBtYW51ZmFjdHVyZXIgYnkgdGhlIGVuZCB1c2VyCgkgKiB0byBhaWQgaW4gZGVidWdnaW5nLgoJICoKCSAqLwoJcHJpbnRrKEtFUk5fV0FSTklORyAiJXM6IFVuc29saWNpdGVkIG1lc3NhZ2UgcmVwbHkgc2VudCB0byBjb3JlISIKCSAgICAgICAiTWVzc2FnZSBkdW1wZWQgdG8gc3lzbG9nXG4iLCBjLT5uYW1lKTsKCWkyb19kdW1wX21lc3NhZ2UobXNnKTsKCglyZXR1cm4gLUVGQVVMVDsKfQoKLyoqCiAqCWkyb19leGVjX2V2ZW50IC0gRXZlbnQgaGFuZGxpbmcgZnVuY3Rpb24KICoJQGV2dDogRXZlbnQgd2hpY2ggb2NjdXJzCiAqCiAqCUhhbmRsZXMgZXZlbnRzIHNlbmQgYnkgdGhlIEV4ZWN1dGl2ZSBkZXZpY2UuIEF0IHRoZSBtb21lbnQgZG9lcyBub3QgZG8KICoJYW55dGhpbmcgdXNlZnVsLgogKi8Kc3RhdGljIHZvaWQgaTJvX2V4ZWNfZXZlbnQoc3RydWN0IGkyb19ldmVudCAqZXZ0KQp7CglpZihsaWtlbHkoZXZ0LT5pMm9fZGV2KSkKCQlvc21faW5mbygiRXZlbnQgcmVjZWl2ZWQgZnJvbSBkZXZpY2U6ICVkXG4iLAoJCQkgZXZ0LT5pMm9fZGV2LT5sY3RfZGF0YS50aWQpOwoJa2ZyZWUoZXZ0KTsKfTsKCi8qKgogKglpMm9fZXhlY19sY3RfZ2V0IC0gR2V0IHRoZSBJT1AncyBMb2dpY2FsIENvbmZpZ3VyYXRpb24gVGFibGUKICoJQGM6IEkyTyBjb250cm9sbGVyIGZyb20gd2hpY2ggdGhlIExDVCBzaG91bGQgYmUgZmV0Y2hlZAogKgogKglTZW5kIGEgTENUIE5PVElGWSByZXF1ZXN0IHRvIHRoZSBjb250cm9sbGVyLCBhbmQgd2FpdAogKglJMk9fVElNRU9VVF9MQ1RfR0VUIHNlY29uZHMgdW50aWwgYXJyaXZhbCBvZiByZXNwb25zZS4gSWYgdGhlIExDVCBpcwogKgl0byBsYXJnZSwgcmV0cnkgaXQuCiAqCiAqCVJldHVybnMgMCBvbiBzdWNjZXNzIG9yIG5lZ2F0aXZlIGVycm9yIGNvZGUgb24gZmFpbHVyZS4KICovCmludCBpMm9fZXhlY19sY3RfZ2V0KHN0cnVjdCBpMm9fY29udHJvbGxlciAqYykKewoJc3RydWN0IGkyb19tZXNzYWdlIF9faW9tZW0gKm1zZzsKCXUzMiBtOwoJaW50IGkgPSAwOwoJaW50IHJjID0gLUVBR0FJTjsKCglmb3IgKGkgPSAxOyBpIDw9IEkyT19MQ1RfR0VUX1RSSUVTOyBpKyspIHsKCQltID0gaTJvX21zZ19nZXRfd2FpdChjLCAmbXNnLCBJMk9fVElNRU9VVF9NRVNTQUdFX0dFVCk7CgkJaWYgKG0gPT0gSTJPX1FVRVVFX0VNUFRZKQoJCQlyZXR1cm4gLUVUSU1FRE9VVDsKCgkJd3JpdGVsKEVJR0hUX1dPUkRfTVNHX1NJWkUgfCBTR0xfT0ZGU0VUXzYsICZtc2ctPnUuaGVhZFswXSk7CgkJd3JpdGVsKEkyT19DTURfTENUX05PVElGWSA8PCAyNCB8IEhPU1RfVElEIDw8IDEyIHwgQURBUFRFUl9USUQsCgkJICAgICAgICZtc2ctPnUuaGVhZFsxXSk7CgkJd3JpdGVsKDB4ZmZmZmZmZmYsICZtc2ctPmJvZHlbMF0pOwoJCXdyaXRlbCgweDAwMDAwMDAwLCAmbXNnLT5ib2R5WzFdKTsKCQl3cml0ZWwoMHhkMDAwMDAwMCB8IGMtPmRsY3QubGVuLCAmbXNnLT5ib2R5WzJdKTsKCQl3cml0ZWwoYy0+ZGxjdC5waHlzLCAmbXNnLT5ib2R5WzNdKTsKCgkJcmMgPSBpMm9fbXNnX3Bvc3Rfd2FpdChjLCBtLCBJMk9fVElNRU9VVF9MQ1RfR0VUKTsKCQlpZiAocmMgPCAwKQoJCQlicmVhazsKCgkJcmMgPSBpMm9fZGV2aWNlX3BhcnNlX2xjdChjKTsKCQlpZiAocmMgIT0gLUVBR0FJTikKCQkJYnJlYWs7Cgl9CgoJcmV0dXJuIHJjOwp9CgovKioKICoJaTJvX2V4ZWNfbGN0X25vdGlmeSAtIFNlbmQgYSBhc3luY2hyb251cyBMQ1QgTk9USUZZIHJlcXVlc3QKICoJQGM6IEkyTyBjb250cm9sbGVyIHRvIHdoaWNoIHRoZSByZXF1ZXN0IHNob3VsZCBiZSBzZW5kCiAqCUBjaGFuZ2VfaW5kOiBjaGFuZ2UgaW5kaWNhdG9yCiAqCiAqCVRoaXMgZnVuY3Rpb24gc2VuZHMgYSBMQ1QgTk9USUZZIHJlcXVlc3QgdG8gdGhlIEkyTyBjb250cm9sbGVyIHdpdGgKICoJdGhlIGNoYW5nZSBpbmRpY2F0b3IgY2hhbmdlX2luZC4gSWYgdGhlIGNoYW5nZV9pbmQgPT0gMCB0aGUgY29udHJvbGxlcgogKglyZXBsaWVzIGltbWVkaWF0ZWx5IGFmdGVyIHRoZSByZXF1ZXN0LiBJZiBjaGFuZ2VfaW5kID4gMCB0aGUgcmVwbHkgaXMKICoJc2VuZCBhZnRlciBjaGFuZ2UgaW5kaWNhdG9yIG9mIHRoZSBMQ1QgaXMgPiBjaGFuZ2VfaW5kLgogKi8Kc3RhdGljIGludCBpMm9fZXhlY19sY3Rfbm90aWZ5KHN0cnVjdCBpMm9fY29udHJvbGxlciAqYywgdTMyIGNoYW5nZV9pbmQpCnsKCWkyb19zdGF0dXNfYmxvY2sgKnNiID0gYy0+c3RhdHVzX2Jsb2NrLnZpcnQ7CglzdHJ1Y3QgZGV2aWNlICpkZXY7CglzdHJ1Y3QgaTJvX21lc3NhZ2UgX19pb21lbSAqbXNnOwoJdTMyIG07CgoJZGV2ID0gJmMtPnBkZXYtPmRldjsKCglpZiAoaTJvX2RtYV9yZWFsbG9jKGRldiwgJmMtPmRsY3QsIHNiLT5leHBlY3RlZF9sY3Rfc2l6ZSwgR0ZQX0tFUk5FTCkpCgkJcmV0dXJuIC1FTk9NRU07CgoJbSA9IGkyb19tc2dfZ2V0X3dhaXQoYywgJm1zZywgSTJPX1RJTUVPVVRfTUVTU0FHRV9HRVQpOwoJaWYgKG0gPT0gSTJPX1FVRVVFX0VNUFRZKQoJCXJldHVybiAtRVRJTUVET1VUOwoKCXdyaXRlbChFSUdIVF9XT1JEX01TR19TSVpFIHwgU0dMX09GRlNFVF82LCAmbXNnLT51LmhlYWRbMF0pOwoJd3JpdGVsKEkyT19DTURfTENUX05PVElGWSA8PCAyNCB8IEhPU1RfVElEIDw8IDEyIHwgQURBUFRFUl9USUQsCgkgICAgICAgJm1zZy0+dS5oZWFkWzFdKTsKCXdyaXRlbChpMm9fZXhlY19kcml2ZXIuY29udGV4dCwgJm1zZy0+dS5zLmljbnR4dCk7Cgl3cml0ZWwoMCwgJm1zZy0+dS5zLnRjbnR4dCk7CS8qIEZJWE1FICovCgl3cml0ZWwoMHhmZmZmZmZmZiwgJm1zZy0+Ym9keVswXSk7Cgl3cml0ZWwoY2hhbmdlX2luZCwgJm1zZy0+Ym9keVsxXSk7Cgl3cml0ZWwoMHhkMDAwMDAwMCB8IGMtPmRsY3QubGVuLCAmbXNnLT5ib2R5WzJdKTsKCXdyaXRlbChjLT5kbGN0LnBoeXMsICZtc2ctPmJvZHlbM10pOwoKCWkyb19tc2dfcG9zdChjLCBtKTsKCglyZXR1cm4gMDsKfTsKCi8qIEV4ZWMgT1NNIGRyaXZlciBzdHJ1Y3QgKi8Kc3RydWN0IGkyb19kcml2ZXIgaTJvX2V4ZWNfZHJpdmVyID0gewoJLm5hbWUgPSBPU01fTkFNRSwKCS5yZXBseSA9IGkyb19leGVjX3JlcGx5LAoJLmV2ZW50ID0gaTJvX2V4ZWNfZXZlbnQsCgkuY2xhc3NlcyA9IGkyb19leGVjX2NsYXNzX2lkLAoJLmRyaXZlciA9IHsKCQkgICAucHJvYmUgPSBpMm9fZXhlY19wcm9iZSwKCQkgICAucmVtb3ZlID0gaTJvX2V4ZWNfcmVtb3ZlLAoJCSAgIH0sCn07CgovKioKICoJaTJvX2V4ZWNfaW5pdCAtIFJlZ2lzdGVycyB0aGUgRXhlYyBPU00KICoKICoJUmVnaXN0ZXJzIHRoZSBFeGVjIE9TTSBpbiB0aGUgSTJPIGNvcmUuCiAqCiAqCVJldHVybnMgMCBvbiBzdWNjZXNzIG9yIG5lZ2F0aXZlIGVycm9yIGNvZGUgb24gZmFpbHVyZS4KICovCmludCBfX2luaXQgaTJvX2V4ZWNfaW5pdCh2b2lkKQp7CglyZXR1cm4gaTJvX2RyaXZlcl9yZWdpc3RlcigmaTJvX2V4ZWNfZHJpdmVyKTsKfTsKCi8qKgogKglpMm9fZXhlY19leGl0IC0gUmVtb3ZlcyB0aGUgRXhlYyBPU00KICoKICoJVW5yZWdpc3RlcnMgdGhlIEV4ZWMgT1NNIGZyb20gdGhlIEkyTyBjb3JlLgogKi8Kdm9pZCBfX2V4aXQgaTJvX2V4ZWNfZXhpdCh2b2lkKQp7CglpMm9fZHJpdmVyX3VucmVnaXN0ZXIoJmkyb19leGVjX2RyaXZlcik7Cn07CgpFWFBPUlRfU1lNQk9MKGkyb19tc2dfcG9zdF93YWl0X21lbSk7CkVYUE9SVF9TWU1CT0woaTJvX2V4ZWNfbGN0X2dldCk7Cg==