LyoKICoJRXhlY3V0aXZlIE9TTQogKgogKiAJQ29weXJpZ2h0IChDKSAxOTk5LTIwMDIJUmVkIEhhdCBTb2Z0d2FyZQogKgogKglXcml0dGVuIGJ5IEFsYW4gQ294LCBCdWlsZGluZyBOdW1iZXIgVGhyZWUgTHRkCiAqCiAqCVRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqCXVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZQogKglGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlciB2ZXJzaW9uIDIgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyCiAqCW9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqCUEgbG90IG9mIHRoZSBJMk8gbWVzc2FnZSBzaWRlIGNvZGUgZnJvbSB0aGlzIGlzIHRha2VuIGZyb20gdGhlIFJlZAogKglDcmVlayBSQ1BDSTQ1IGFkYXB0ZXIgZHJpdmVyIGJ5IFJlZCBDcmVlayBDb21tdW5pY2F0aW9ucwogKgogKglGaXhlcy9hZGRpdGlvbnM6CiAqCQlQaGlsaXBwIFJ1bXBmCiAqCQlKdWhhIFNpZXbkbmVuIDxKdWhhLlNpZXZhbmVuQGNzLkhlbHNpbmtpLkZJPgogKgkJQXV2byBI5GtraW5lbiA8QXV2by5IYWtraW5lbkBjcy5IZWxzaW5raS5GST4KICoJCURlZXBhayBTYXhlbmEgPGRlZXBha0BwbGV4aXR5Lm5ldD4KICoJCUJvamkgVCBLYW5uYW50aGFuYW0gPGJvamkudC5rYW5uYW50aGFuYW1AaW50ZWwuY29tPgogKgkJQWxhbiBDb3ggPGFsYW5AcmVkaGF0LmNvbT46CiAqCQkJUG9ydGVkIHRvIExpbnV4IDIuNS4KICoJCU1hcmt1cyBMaWRlbCA8TWFya3VzLkxpZGVsQHNoYWRvd2Nvbm5lY3QuY29tPjoKICoJCQlNaW5vciBmaXhlcyBmb3IgMi42LgogKgkJTWFya3VzIExpZGVsIDxNYXJrdXMuTGlkZWxAc2hhZG93Y29ubmVjdC5jb20+OgogKgkJCVN1cHBvcnQgZm9yIHN5c2ZzIGluY2x1ZGVkLgogKi8KCiNpbmNsdWRlIDxsaW51eC9tb2R1bGUuaD4KI2luY2x1ZGUgPGxpbnV4L2kyby5oPgojaW5jbHVkZSA8bGludXgvZGVsYXkuaD4KI2luY2x1ZGUgPGxpbnV4L3dvcmtxdWV1ZS5oPgojaW5jbHVkZSA8bGludXgvc3RyaW5nLmg+CiNpbmNsdWRlIDxsaW51eC9zbGFiLmg+CiNpbmNsdWRlIDxhc20vcGFyYW0uaD4JCS8qIEhaICovCiNpbmNsdWRlICJjb3JlLmgiCgojZGVmaW5lIE9TTV9OQU1FICJleGVjLW9zbSIKCnN0cnVjdCBpMm9fZHJpdmVyIGkyb19leGVjX2RyaXZlcjsKCnN0YXRpYyBpbnQgaTJvX2V4ZWNfbGN0X25vdGlmeShzdHJ1Y3QgaTJvX2NvbnRyb2xsZXIgKmMsIHUzMiBjaGFuZ2VfaW5kKTsKCi8qIGdsb2JhbCB3YWl0IGxpc3QgZm9yIFBPU1QgV0FJVCAqLwpzdGF0aWMgTElTVF9IRUFEKGkyb19leGVjX3dhaXRfbGlzdCk7CgovKiBXYWl0IHN0cnVjdCBuZWVkZWQgZm9yIFBPU1QgV0FJVCAqLwpzdHJ1Y3QgaTJvX2V4ZWNfd2FpdCB7Cgl3YWl0X3F1ZXVlX2hlYWRfdCAqd3E7CS8qIFBvaW50ZXIgdG8gV2FpdCBxdWV1ZSAqLwoJc3RydWN0IGkyb19kbWEgZG1hOwkvKiBETUEgYnVmZmVycyB0byBmcmVlIG9uIGZhaWx1cmUgKi8KCXUzMiB0Y250eHQ7CQkvKiB0cmFuc2FjdGlvbiBjb250ZXh0IGZyb20gcmVwbHkgKi8KCWludCBjb21wbGV0ZTsJCS8qIDEgaWYgcmVwbHkgcmVjZWl2ZWQgb3RoZXJ3aXNlIDAgKi8KCXUzMiBtOwkJCS8qIG1lc3NhZ2UgaWQgKi8KCXN0cnVjdCBpMm9fbWVzc2FnZSAqbXNnOwkvKiBwb2ludGVyIHRvIHRoZSByZXBseSBtZXNzYWdlICovCglzdHJ1Y3QgbGlzdF9oZWFkIGxpc3Q7CS8qIG5vZGUgaW4gZ2xvYmFsIHdhaXQgbGlzdCAqLwp9OwoKLyogRXhlYyBPU00gY2xhc3MgaGFuZGxpbmcgZGVmaW5pdGlvbiAqLwpzdGF0aWMgc3RydWN0IGkyb19jbGFzc19pZCBpMm9fZXhlY19jbGFzc19pZFtdID0gewoJe0kyT19DTEFTU19FWEVDVVRJVkV9LAoJe0kyT19DTEFTU19FTkR9Cn07CgovKioKICoJaTJvX2V4ZWNfd2FpdF9hbGxvYyAtIEFsbG9jYXRlIGEgaTJvX2V4ZWNfd2FpdCBzdHJ1Y3QgYW4gaW5pdGlhbGl6ZSBpdAogKgogKglBbGxvY2F0ZSB0aGUgaTJvX2V4ZWNfd2FpdCBzdHJ1Y3QgYW5kIGluaXRpYWxpemUgdGhlIHdhaXQuCiAqCiAqCVJldHVybnMgaTJvX2V4ZWNfd2FpdCBwb2ludGVyIG9uIHN1Y2Nlc3Mgb3IgbmVnYXRpdmUgZXJyb3IgY29kZSBvbgogKglmYWlsdXJlLgogKi8Kc3RhdGljIHN0cnVjdCBpMm9fZXhlY193YWl0ICppMm9fZXhlY193YWl0X2FsbG9jKHZvaWQpCnsKCXN0cnVjdCBpMm9fZXhlY193YWl0ICp3YWl0OwoKCXdhaXQgPSBrbWFsbG9jKHNpemVvZigqd2FpdCksIEdGUF9LRVJORUwpOwoJaWYgKCF3YWl0KQoJCXJldHVybiBFUlJfUFRSKC1FTk9NRU0pOwoKCW1lbXNldCh3YWl0LCAwLCBzaXplb2YoKndhaXQpKTsKCglJTklUX0xJU1RfSEVBRCgmd2FpdC0+bGlzdCk7CgoJcmV0dXJuIHdhaXQ7Cn07CgovKioKICoJaTJvX2V4ZWNfd2FpdF9mcmVlIC0gRnJlZSBhIGkyb19leGVjX3dhaXQgc3RydWN0CiAqCUBpMm9fZXhlY193YWl0OiBJMk8gd2FpdCBkYXRhIHdoaWNoIHNob3VsZCBiZSBjbGVhbmVkIHVwCiAqLwpzdGF0aWMgdm9pZCBpMm9fZXhlY193YWl0X2ZyZWUoc3RydWN0IGkyb19leGVjX3dhaXQgKndhaXQpCnsKCWtmcmVlKHdhaXQpOwp9OwoKLyoqCiAqIAlpMm9fbXNnX3Bvc3Rfd2FpdF9tZW0gLSBQb3N0IGFuZCB3YWl0IGEgbWVzc2FnZSB3aXRoIERNQSBidWZmZXJzCiAqCUBjOiBjb250cm9sbGVyCiAqCUBtOiBtZXNzYWdlIHRvIHBvc3QKICoJQHRpbWVvdXQ6IHRpbWUgaW4gc2Vjb25kcyB0byB3YWl0CiAqCUBkbWE6IGkyb19kbWEgc3RydWN0IG9mIHRoZSBETUEgYnVmZmVyIHRvIGZyZWUgb24gZmFpbHVyZQogKgogKiAJVGhpcyBBUEkgYWxsb3dzIGFuIE9TTSB0byBwb3N0IGEgbWVzc2FnZSBhbmQgdGhlbiBiZSB0b2xkIHdoZXRoZXIgb3IKICoJbm90IHRoZSBzeXN0ZW0gcmVjZWl2ZWQgYSBzdWNjZXNzZnVsIHJlcGx5LiBJZiB0aGUgbWVzc2FnZSB0aW1lcyBvdXQKICoJdGhlbiB0aGUgdmFsdWUgJy1FVElNRURPVVQnIGlzIHJldHVybmVkLiBUaGlzIGlzIGEgc3BlY2lhbCBjYXNlLiBJbgogKgl0aGlzIHNpdHVhdGlvbiB0aGUgbWVzc2FnZSBtYXkgKHNob3VsZCkgY29tcGxldGUgYXQgYW4gaW5kZWZpbml0ZSB0aW1lCiAqCWluIHRoZSBmdXR1cmUuIFdoZW4gaXQgY29tcGxldGVzIGl0IHdpbGwgdXNlIHRoZSBtZW1vcnkgYnVmZmVyCiAqCWF0dGFjaGVkIHRvIHRoZSByZXF1ZXN0LiBJZiAtRVRJTUVET1VUIGlzIHJldHVybmVkIHRoZW4gdGhlIG1lbW9yeQogKglidWZmZXIgbXVzdCBub3QgYmUgZnJlZWQuIEluc3RlYWQgdGhlIGV2ZW50IGNvbXBsZXRpb24gd2lsbCBmcmVlIHRoZW0KICoJZm9yIHlvdS4gSW4gYWxsIG90aGVyIGNhc2VzIHRoZSBidWZmZXIgYXJlIHlvdXIgcHJvYmxlbS4KICoKICoJUmV0dXJucyAwIG9uIHN1Y2Nlc3MsIG5lZ2F0aXZlIGVycm9yIGNvZGUgb24gdGltZW91dCBvciBwb3NpdGl2ZSBlcnJvcgogKgljb2RlIGZyb20gcmVwbHkuCiAqLwppbnQgaTJvX21zZ19wb3N0X3dhaXRfbWVtKHN0cnVjdCBpMm9fY29udHJvbGxlciAqYywgdTMyIG0sIHVuc2lnbmVkIGxvbmcKCQkJICB0aW1lb3V0LCBzdHJ1Y3QgaTJvX2RtYSAqZG1hKQp7CglERUNMQVJFX1dBSVRfUVVFVUVfSEVBRCh3cSk7CglzdHJ1Y3QgaTJvX2V4ZWNfd2FpdCAqd2FpdDsKCXN0YXRpYyB1MzIgdGNudHh0ID0gMHg4MDAwMDAwMDsKCXN0cnVjdCBpMm9fbWVzc2FnZSBfX2lvbWVtICptc2cgPSBpMm9fbXNnX2luX3RvX3ZpcnQoYywgbSk7CglpbnQgcmMgPSAwOwoKCXdhaXQgPSBpMm9fZXhlY193YWl0X2FsbG9jKCk7CglpZiAoIXdhaXQpCgkJcmV0dXJuIC1FTk9NRU07CgoJaWYgKHRjbnR4dCA9PSAweGZmZmZmZmZmKQoJCXRjbnR4dCA9IDB4ODAwMDAwMDA7CgoJaWYgKGRtYSkKCQl3YWl0LT5kbWEgPSAqZG1hOwoKCS8qCgkgKiBGaWxsIGluIHRoZSBtZXNzYWdlIGluaXRpYXRvciBjb250ZXh0IGFuZCB0cmFuc2FjdGlvbiBjb250ZXh0LgoJICogV2Ugd2lsbCBvbmx5IHVzZSB0cmFuc2FjdGlvbiBjb250ZXh0cyA+PSAweDgwMDAwMDAwIGZvciBQT1NUIFdBSVQsCgkgKiBzbyB3ZSBjb3VsZCBmaW5kIGEgUE9TVCBXQUlUIHJlcGx5IGVhc2llciBpbiB0aGUgcmVwbHkgaGFuZGxlci4KCSAqLwoJd3JpdGVsKGkyb19leGVjX2RyaXZlci5jb250ZXh0LCAmbXNnLT51LnMuaWNudHh0KTsKCXdhaXQtPnRjbnR4dCA9IHRjbnR4dCsrOwoJd3JpdGVsKHdhaXQtPnRjbnR4dCwgJm1zZy0+dS5zLnRjbnR4dCk7CgoJLyoKCSAqIFBvc3QgdGhlIG1lc3NhZ2UgdG8gdGhlIGNvbnRyb2xsZXIuIEF0IHNvbWUgcG9pbnQgbGF0ZXIgaXQgd2lsbAoJICogcmV0dXJuLiBJZiB3ZSB0aW1lIG91dCBiZWZvcmUgaXQgcmV0dXJucyB0aGVuIGNvbXBsZXRlIHdpbGwgYmUgemVyby4KCSAqLwoJaTJvX21zZ19wb3N0KGMsIG0pOwoKCWlmICghd2FpdC0+Y29tcGxldGUpIHsKCQl3YWl0LT53cSA9ICZ3cTsKCQkvKgoJCSAqIHdlIGFkZCBlbGVtZW50cyBhZGQgdGhlIGhlYWQsIGJlY2F1c2UgaWYgYSBlbnRyeSBpbiB0aGUgbGlzdAoJCSAqIHdpbGwgbmV2ZXIgYmUgcmVtb3ZlZCwgd2UgaGF2ZSB0byBpdGVyYXRlIG92ZXIgaXQgZXZlcnkgdGltZQoJCSAqLwoJCWxpc3RfYWRkKCZ3YWl0LT5saXN0LCAmaTJvX2V4ZWNfd2FpdF9saXN0KTsKCgkJd2FpdF9ldmVudF9pbnRlcnJ1cHRpYmxlX3RpbWVvdXQod3EsIHdhaXQtPmNvbXBsZXRlLAoJCQkJCQkgdGltZW91dCAqIEhaKTsKCgkJd2FpdC0+d3EgPSBOVUxMOwoJfQoKCWJhcnJpZXIoKTsKCglpZiAod2FpdC0+Y29tcGxldGUpIHsKCQlyYyA9IGxlMzJfdG9fY3B1KHdhaXQtPm1zZy0+Ym9keVswXSkgPj4gMjQ7CgkJaTJvX2ZsdXNoX3JlcGx5KGMsIHdhaXQtPm0pOwoJCWkyb19leGVjX3dhaXRfZnJlZSh3YWl0KTsKCX0gZWxzZSB7CgkJLyoKCQkgKiBXZSBjYW5ub3QgcmVtb3ZlIGl0IG5vdy4gVGhpcyBpcyBpbXBvcnRhbnQuIFdoZW4gaXQgZG9lcwoJCSAqIHRlcm1pbmF0ZSAod2hpY2ggaXQgbXVzdCBkbyBpZiB0aGUgY29udHJvbGxlciBoYXMgbm90CgkJICogZGllZC4uLikgdGhlbiBpdCB3aWxsIG90aGVyd2lzZSBzY3JpYmJsZSBvbiBzdHVmZi4KCQkgKgoJCSAqIEZJWE1FOiB0cnkgYWJvcnQgbWVzc2FnZQoJCSAqLwoJCWlmIChkbWEpCgkJCWRtYS0+dmlydCA9IE5VTEw7CgoJCXJjID0gLUVUSU1FRE9VVDsKCX0KCglyZXR1cm4gcmM7Cn07CgovKioKICoJaTJvX21zZ19wb3N0X3dhaXRfY29tcGxldGUgLSBSZXBseSB0byBhIGkyb19tc2dfcG9zdCByZXF1ZXN0IGZyb20gSU9QCiAqCUBjOiBJMk8gY29udHJvbGxlciB3aGljaCBhbnN3ZXJzCiAqCUBtOiBtZXNzYWdlIGlkCiAqCUBtc2c6IHBvaW50ZXIgdG8gdGhlIEkyTyByZXBseSBtZXNzYWdlCiAqCUBjb250ZXh0OiB0cmFuc2FjdGlvbiBjb250ZXh0IG9mIHJlcXVlc3QKICoKICoJVGhpcyBmdW5jdGlvbiBpcyBjYWxsZWQgaW4gaW50ZXJydXB0IGNvbnRleHQgb25seS4gSWYgdGhlIHJlcGx5IHJlYWNoZWQKICoJYmVmb3JlIHRoZSB0aW1lb3V0LCB0aGUgaTJvX2V4ZWNfd2FpdCBzdHJ1Y3QgaXMgZmlsbGVkIHdpdGggdGhlIG1lc3NhZ2UKICoJYW5kIHRoZSB0YXNrIHdpbGwgYmUgd2FrZWQgdXAuIFRoZSB0YXNrIGlzIG5vdyByZXNwb25zaWJsZSBmb3IgcmV0dXJuaW5nCiAqCXRoZSBtZXNzYWdlIG0gYmFjayB0byB0aGUgY29udHJvbGxlciEgSWYgdGhlIG1lc3NhZ2UgcmVhY2hlcyB1cyBhZnRlcgogKgl0aGUgdGltZW91dCBjbGVhbiB1cCB0aGUgaTJvX2V4ZWNfd2FpdCBzdHJ1Y3QgKGluY2x1ZGluZyBhbGxvY2F0ZWQKICoJRE1BIGJ1ZmZlcikuCiAqCiAqCVJldHVybiAwIG9uIHN1Y2Nlc3MgYW5kIGlmIHRoZSBtZXNzYWdlIG0gc2hvdWxkIG5vdCBiZSBnaXZlbiBiYWNrIHRvIHRoZQogKglJMk8gY29udHJvbGxlciwgb3IgPjAgb24gc3VjY2VzcyBhbmQgaWYgdGhlIG1lc3NhZ2Ugc2hvdWxkIGJlIGdpdmVuIGJhY2sKICoJYWZ0ZXJ3b3Jkcy4gUmV0dXJucyBuZWdhdGl2ZSBlcnJvciBjb2RlIG9uIGZhaWx1cmUuIEluIHRoaXMgY2FzZSB0aGUKICoJbWVzc2FnZSBtdXN0IGFsc28gYmUgZ2l2ZW4gYmFjayB0byB0aGUgY29udHJvbGxlci4KICovCnN0YXRpYyBpbnQgaTJvX21zZ19wb3N0X3dhaXRfY29tcGxldGUoc3RydWN0IGkyb19jb250cm9sbGVyICpjLCB1MzIgbSwKCQkJCSAgICAgIHN0cnVjdCBpMm9fbWVzc2FnZSAqbXNnLCB1MzIgY29udGV4dCkKewoJc3RydWN0IGkyb19leGVjX3dhaXQgKndhaXQsICp0bXA7Cgl1bnNpZ25lZCBsb25nIGZsYWdzOwoJc3RhdGljIHNwaW5sb2NrX3QgbG9jayA9IFNQSU5fTE9DS19VTkxPQ0tFRDsKCWludCByYyA9IDE7CgoJLyoKCSAqIFdlIG5lZWQgdG8gc2VhcmNoIHRocm91Z2ggdGhlIGkyb19leGVjX3dhaXRfbGlzdCB0byBzZWUgaWYgdGhlIGdpdmVuCgkgKiBtZXNzYWdlIGlzIHN0aWxsIG91dHN0YW5kaW5nLiBJZiBub3QsIGl0IG1lYW5zIHRoYXQgdGhlIElPUCB0b29rCgkgKiBsb25nZXIgdG8gcmVzcG9uZCB0byB0aGUgbWVzc2FnZSB0aGFuIHdlIGhhZCBhbGxvd2VkIGFuZCB0aW1lciBoYXMKCSAqIGFscmVhZHkgZXhwaXJlZC4gTm90IG11Y2ggd2UgY2FuIGRvIGFib3V0IHRoYXQgZXhjZXB0IGxvZyBpdCBmb3IKCSAqIGRlYnVnIHB1cnBvc2VzLCBpbmNyZWFzZSB0aW1lb3V0LCBhbmQgcmVjb21waWxlLgoJICovCglzcGluX2xvY2tfaXJxc2F2ZSgmbG9jaywgZmxhZ3MpOwoJbGlzdF9mb3JfZWFjaF9lbnRyeV9zYWZlKHdhaXQsIHRtcCwgJmkyb19leGVjX3dhaXRfbGlzdCwgbGlzdCkgewoJCWlmICh3YWl0LT50Y250eHQgPT0gY29udGV4dCkgewoJCQlsaXN0X2RlbCgmd2FpdC0+bGlzdCk7CgoJCQlzcGluX3VubG9ja19pcnFyZXN0b3JlKCZsb2NrLCBmbGFncyk7CgoJCQl3YWl0LT5tID0gbTsKCQkJd2FpdC0+bXNnID0gbXNnOwoJCQl3YWl0LT5jb21wbGV0ZSA9IDE7CgoJCQliYXJyaWVyKCk7CgoJCQlpZiAod2FpdC0+d3EpIHsKCQkJCXdha2VfdXBfaW50ZXJydXB0aWJsZSh3YWl0LT53cSk7CgkJCQlyYyA9IDA7CgkJCX0gZWxzZSB7CgkJCQlzdHJ1Y3QgZGV2aWNlICpkZXY7CgoJCQkJZGV2ID0gJmMtPnBkZXYtPmRldjsKCgkJCQlwcl9kZWJ1ZygiJXM6IHRpbWVkb3V0IHJlcGx5IHJlY2VpdmVkIVxuIiwKCQkJCQkgYy0+bmFtZSk7CgkJCQlpMm9fZG1hX2ZyZWUoZGV2LCAmd2FpdC0+ZG1hKTsKCQkJCWkyb19leGVjX3dhaXRfZnJlZSh3YWl0KTsKCQkJCXJjID0gLTE7CgkJCX0KCgkJCXJldHVybiByYzsKCQl9Cgl9CgoJc3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmbG9jaywgZmxhZ3MpOwoKCW9zbV93YXJuKCIlczogQm9ndXMgcmVwbHkgaW4gUE9TVCBXQUlUICh0ci1jb250ZXh0OiAlMDh4KSFcbiIsIGMtPm5hbWUsCgkJIGNvbnRleHQpOwoKCXJldHVybiAtMTsKfTsKCi8qKgogKglpMm9fZXhlY19zaG93X3ZlbmRvcl9pZCAtIERpc3BsYXlzIFZlbmRvciBJRCBvZiBjb250cm9sbGVyCiAqCUBkOiBkZXZpY2Ugb2Ygd2hpY2ggdGhlIFZlbmRvciBJRCBzaG91bGQgYmUgZGlzcGxheWVkCiAqCUBidWY6IGJ1ZmZlciBpbnRvIHdoaWNoIHRoZSBWZW5kb3IgSUQgc2hvdWxkIGJlIHByaW50ZWQKICoKICoJUmV0dXJucyBudW1iZXIgb2YgYnl0ZXMgcHJpbnRlZCBpbnRvIGJ1ZmZlci4KICovCnN0YXRpYyBzc2l6ZV90IGkyb19leGVjX3Nob3dfdmVuZG9yX2lkKHN0cnVjdCBkZXZpY2UgKmQsIHN0cnVjdCBkZXZpY2VfYXR0cmlidXRlICphdHRyLCBjaGFyICpidWYpCnsKCXN0cnVjdCBpMm9fZGV2aWNlICpkZXYgPSB0b19pMm9fZGV2aWNlKGQpOwoJdTE2IGlkOwoKCWlmIChpMm9fcGFybV9maWVsZF9nZXQoZGV2LCAweDAwMDAsIDAsICZpZCwgMikpIHsKCQlzcHJpbnRmKGJ1ZiwgIjB4JTA0eCIsIGlkKTsKCQlyZXR1cm4gc3RybGVuKGJ1ZikgKyAxOwoJfQoKCXJldHVybiAwOwp9OwoKLyoqCiAqCWkyb19leGVjX3Nob3dfcHJvZHVjdF9pZCAtIERpc3BsYXlzIFByb2R1Y3QgSUQgb2YgY29udHJvbGxlcgogKglAZDogZGV2aWNlIG9mIHdoaWNoIHRoZSBQcm9kdWN0IElEIHNob3VsZCBiZSBkaXNwbGF5ZWQKICoJQGJ1ZjogYnVmZmVyIGludG8gd2hpY2ggdGhlIFByb2R1Y3QgSUQgc2hvdWxkIGJlIHByaW50ZWQKICoKICoJUmV0dXJucyBudW1iZXIgb2YgYnl0ZXMgcHJpbnRlZCBpbnRvIGJ1ZmZlci4KICovCnN0YXRpYyBzc2l6ZV90IGkyb19leGVjX3Nob3dfcHJvZHVjdF9pZChzdHJ1Y3QgZGV2aWNlICpkLCBzdHJ1Y3QgZGV2aWNlX2F0dHJpYnV0ZSAqYXR0ciwgY2hhciAqYnVmKQp7CglzdHJ1Y3QgaTJvX2RldmljZSAqZGV2ID0gdG9faTJvX2RldmljZShkKTsKCXUxNiBpZDsKCglpZiAoaTJvX3Bhcm1fZmllbGRfZ2V0KGRldiwgMHgwMDAwLCAxLCAmaWQsIDIpKSB7CgkJc3ByaW50ZihidWYsICIweCUwNHgiLCBpZCk7CgkJcmV0dXJuIHN0cmxlbihidWYpICsgMTsKCX0KCglyZXR1cm4gMDsKfTsKCi8qIEV4ZWMtT1NNIGRldmljZSBhdHRyaWJ1dGVzICovCnN0YXRpYyBERVZJQ0VfQVRUUih2ZW5kb3JfaWQsIFNfSVJVR08sIGkyb19leGVjX3Nob3dfdmVuZG9yX2lkLCBOVUxMKTsKc3RhdGljIERFVklDRV9BVFRSKHByb2R1Y3RfaWQsIFNfSVJVR08sIGkyb19leGVjX3Nob3dfcHJvZHVjdF9pZCwgTlVMTCk7CgovKioKICoJaTJvX2V4ZWNfcHJvYmUgLSBDYWxsZWQgaWYgYSBuZXcgSTJPIGRldmljZSAoZXhlY3V0aXZlIGNsYXNzKSBhcHBlYXJzCiAqCUBkZXY6IEkyTyBkZXZpY2Ugd2hpY2ggc2hvdWxkIGJlIHByb2JlZAogKgogKglSZWdpc3RlcnMgZXZlbnQgbm90aWZpY2F0aW9uIGZvciBldmVyeSBldmVudCBmcm9tIEV4ZWN1dGl2ZSBkZXZpY2UuIFRoZQogKglyZXR1cm4gaXMgYWx3YXlzIDAsIGJlY2F1c2Ugd2Ugd2FudCBhbGwgZGV2aWNlcyBvZiBjbGFzcyBFeGVjdXRpdmUuCiAqCiAqCVJldHVybnMgMCBvbiBzdWNjZXNzLgogKi8Kc3RhdGljIGludCBpMm9fZXhlY19wcm9iZShzdHJ1Y3QgZGV2aWNlICpkZXYpCnsKCXN0cnVjdCBpMm9fZGV2aWNlICppMm9fZGV2ID0gdG9faTJvX2RldmljZShkZXYpOwoJc3RydWN0IGkyb19jb250cm9sbGVyICpjID0gaTJvX2Rldi0+aW9wOwoKCWkyb19ldmVudF9yZWdpc3RlcihpMm9fZGV2LCAmaTJvX2V4ZWNfZHJpdmVyLCAwLCAweGZmZmZmZmZmKTsKCgljLT5leGVjID0gaTJvX2RldjsKCglpMm9fZXhlY19sY3Rfbm90aWZ5KGMsIGMtPmxjdC0+Y2hhbmdlX2luZCArIDEpOwoKCWRldmljZV9jcmVhdGVfZmlsZShkZXYsICZkZXZfYXR0cl92ZW5kb3JfaWQpOwoJZGV2aWNlX2NyZWF0ZV9maWxlKGRldiwgJmRldl9hdHRyX3Byb2R1Y3RfaWQpOwoKCXJldHVybiAwOwp9OwoKLyoqCiAqCWkyb19leGVjX3JlbW92ZSAtIENhbGxlZCBvbiBJMk8gZGV2aWNlIHJlbW92YWwKICoJQGRldjogSTJPIGRldmljZSB3aGljaCB3YXMgcmVtb3ZlZAogKgogKglVbnJlZ2lzdGVycyBldmVudCBub3RpZmljYXRpb24gZnJvbSBFeGVjdXRpdmUgSTJPIGRldmljZS4KICoKICoJUmV0dXJucyAwIG9uIHN1Y2Nlc3MuCiAqLwpzdGF0aWMgaW50IGkyb19leGVjX3JlbW92ZShzdHJ1Y3QgZGV2aWNlICpkZXYpCnsKCWRldmljZV9yZW1vdmVfZmlsZShkZXYsICZkZXZfYXR0cl9wcm9kdWN0X2lkKTsKCWRldmljZV9yZW1vdmVfZmlsZShkZXYsICZkZXZfYXR0cl92ZW5kb3JfaWQpOwoKCWkyb19ldmVudF9yZWdpc3Rlcih0b19pMm9fZGV2aWNlKGRldiksICZpMm9fZXhlY19kcml2ZXIsIDAsIDApOwoKCXJldHVybiAwOwp9OwoKLyoqCiAqCWkyb19leGVjX2xjdF9tb2RpZmllZCAtIENhbGxlZCBvbiBMQ1QgTk9USUZZIHJlcGx5CiAqCUBjOiBJMk8gY29udHJvbGxlciBvbiB3aGljaCB0aGUgTENUIGhhcyBtb2RpZmllZAogKgogKglUaGlzIGZ1bmN0aW9uIGhhbmRsZXMgYXN5bmNocm9udXMgTENUIE5PVElGWSByZXBsaWVzLiBJdCBwYXJzZXMgdGhlCiAqCW5ldyBMQ1QgYW5kIGlmIHRoZSBidWZmZXIgZm9yIHRoZSBMQ1Qgd2FzIHRvIHNtYWxsIHNlbmRzIGEgTENUIE5PVElGWQogKglhZ2Fpbiwgb3RoZXJ3aXNlIHNlbmQgTENUIE5PVElGWSB0byBnZXQgaW5mb3JtZWQgb24gbmV4dCBMQ1QgY2hhbmdlLgogKi8Kc3RhdGljIHZvaWQgaTJvX2V4ZWNfbGN0X21vZGlmaWVkKHN0cnVjdCBpMm9fY29udHJvbGxlciAqYykKewoJdTMyIGNoYW5nZV9pbmQgPSAwOwoKCWlmIChpMm9fZGV2aWNlX3BhcnNlX2xjdChjKSAhPSAtRUFHQUlOKQoJCWNoYW5nZV9pbmQgPSBjLT5sY3QtPmNoYW5nZV9pbmQgKyAxOwoKCWkyb19leGVjX2xjdF9ub3RpZnkoYywgY2hhbmdlX2luZCk7Cn07CgovKioKICoJaTJvX2V4ZWNfcmVwbHkgLSAgSTJPIEV4ZWN1dGl2ZSByZXBseSBoYW5kbGVyCiAqCUBjOiBJMk8gY29udHJvbGxlciBmcm9tIHdoaWNoIHRoZSByZXBseSBjb21lcwogKglAbTogbWVzc2FnZSBpZAogKglAbXNnOiBwb2ludGVyIHRvIHRoZSBJMk8gcmVwbHkgbWVzc2FnZQogKgogKglUaGlzIGZ1bmN0aW9uIGlzIGFsd2F5cyBjYWxsZWQgZnJvbSBpbnRlcnJ1cHQgY29udGV4dC4gSWYgYSBQT1NUIFdBSVQKICoJcmVwbHkgd2FzIHJlY2VpdmVkLCBwYXNzIGl0IHRvIHRoZSBjb21wbGV0ZSBmdW5jdGlvbi4gSWYgYSBMQ1QgTk9USUZZCiAqCXJlcGx5IHdhcyByZWNlaXZlZCwgYSBuZXcgZXZlbnQgaXMgY3JlYXRlZCB0byBoYW5kbGUgdGhlIHVwZGF0ZS4KICoKICoJUmV0dXJucyAwIG9uIHN1Y2Nlc3MgYW5kIGlmIHRoZSByZXBseSBzaG91bGQgbm90IGJlIGZsdXNoZWQgb3IgPiAwCiAqCW9uIHN1Y2Nlc3MgYW5kIGlmIHRoZSByZXBseSBzaG91bGQgYmUgZmx1c2hlZC4gUmV0dXJucyBuZWdhdGl2ZSBlcnJvcgogKgljb2RlIG9uIGZhaWx1cmUgYW5kIGlmIHRoZSByZXBseSBzaG91bGQgYmUgZmx1c2hlZC4KICovCnN0YXRpYyBpbnQgaTJvX2V4ZWNfcmVwbHkoc3RydWN0IGkyb19jb250cm9sbGVyICpjLCB1MzIgbSwKCQkJICBzdHJ1Y3QgaTJvX21lc3NhZ2UgKm1zZykKewoJdTMyIGNvbnRleHQ7CgoJaWYgKGxlMzJfdG9fY3B1KG1zZy0+dS5oZWFkWzBdKSAmIE1TR19GQUlMKSB7CgkJLyoKCQkgKiBJZiBGYWlsIGJpdCBpcyBzZXQgd2UgbXVzdCB0YWtlIHRoZSB0cmFuc2FjdGlvbiBjb250ZXh0IG9mCgkJICogdGhlIHByZXNlcnZlZCBtZXNzYWdlIHRvIGZpbmQgdGhlIHJpZ2h0IHJlcXVlc3QgYWdhaW4uCgkJICovCgkJc3RydWN0IGkyb19tZXNzYWdlIF9faW9tZW0gKnBtc2c7CgkJdTMyIHBtOwoKCQlwbSA9IGxlMzJfdG9fY3B1KG1zZy0+Ym9keVszXSk7CgoJCXBtc2cgPSBpMm9fbXNnX2luX3RvX3ZpcnQoYywgcG0pOwoKCQlpMm9fcmVwb3J0X3N0YXR1cyhLRVJOX0lORk8sICJpMm9fY29yZSIsIG1zZyk7CgoJCWNvbnRleHQgPSByZWFkbCgmcG1zZy0+dS5zLnRjbnR4dCk7CgoJCS8qIFJlbGVhc2UgdGhlIHByZXNlcnZlZCBtc2cgKi8KCQlpMm9fbXNnX25vcChjLCBwbSk7Cgl9IGVsc2UKCQljb250ZXh0ID0gbGUzMl90b19jcHUobXNnLT51LnMudGNudHh0KTsKCglpZiAoY29udGV4dCAmIDB4ODAwMDAwMDApCgkJcmV0dXJuIGkyb19tc2dfcG9zdF93YWl0X2NvbXBsZXRlKGMsIG0sIG1zZywgY29udGV4dCk7CgoJaWYgKChsZTMyX3RvX2NwdShtc2ctPnUuaGVhZFsxXSkgPj4gMjQpID09IEkyT19DTURfTENUX05PVElGWSkgewoJCXN0cnVjdCB3b3JrX3N0cnVjdCAqd29yazsKCgkJcHJfZGVidWcoIiVzOiBMQ1Qgbm90aWZ5IHJlY2VpdmVkXG4iLCBjLT5uYW1lKTsKCgkJd29yayA9IGttYWxsb2Moc2l6ZW9mKCp3b3JrKSwgR0ZQX0FUT01JQyk7CgkJaWYgKCF3b3JrKQoJCQlyZXR1cm4gLUVOT01FTTsKCgkJSU5JVF9XT1JLKHdvcmssICh2b2lkICgqKSh2b2lkICopKWkyb19leGVjX2xjdF9tb2RpZmllZCwgYyk7CgkJcXVldWVfd29yayhpMm9fZXhlY19kcml2ZXIuZXZlbnRfcXVldWUsIHdvcmspOwoJCXJldHVybiAxOwoJfQoKCS8qCgkgKiBJZiB0aGlzIGhhcHBlbnMsIHdlIHdhbnQgdG8gZHVtcCB0aGUgbWVzc2FnZSB0byB0aGUgc3lzbG9nIHNvCgkgKiBpdCBjYW4gYmUgc2VudCBiYWNrIHRvIHRoZSBjYXJkIG1hbnVmYWN0dXJlciBieSB0aGUgZW5kIHVzZXIKCSAqIHRvIGFpZCBpbiBkZWJ1Z2dpbmcuCgkgKgoJICovCglwcmludGsoS0VSTl9XQVJOSU5HICIlczogVW5zb2xpY2l0ZWQgbWVzc2FnZSByZXBseSBzZW50IHRvIGNvcmUhIgoJICAgICAgICJNZXNzYWdlIGR1bXBlZCB0byBzeXNsb2dcbiIsIGMtPm5hbWUpOwoJaTJvX2R1bXBfbWVzc2FnZShtc2cpOwoKCXJldHVybiAtRUZBVUxUOwp9CgovKioKICoJaTJvX2V4ZWNfZXZlbnQgLSBFdmVudCBoYW5kbGluZyBmdW5jdGlvbgogKglAZXZ0OiBFdmVudCB3aGljaCBvY2N1cnMKICoKICoJSGFuZGxlcyBldmVudHMgc2VuZCBieSB0aGUgRXhlY3V0aXZlIGRldmljZS4gQXQgdGhlIG1vbWVudCBkb2VzIG5vdCBkbwogKglhbnl0aGluZyB1c2VmdWwuCiAqLwpzdGF0aWMgdm9pZCBpMm9fZXhlY19ldmVudChzdHJ1Y3QgaTJvX2V2ZW50ICpldnQpCnsKCWlmIChsaWtlbHkoZXZ0LT5pMm9fZGV2KSkKCQlvc21fZGVidWcoIkV2ZW50IHJlY2VpdmVkIGZyb20gZGV2aWNlOiAlZFxuIiwKCQkJICBldnQtPmkyb19kZXYtPmxjdF9kYXRhLnRpZCk7CglrZnJlZShldnQpOwp9OwoKLyoqCiAqCWkyb19leGVjX2xjdF9nZXQgLSBHZXQgdGhlIElPUCdzIExvZ2ljYWwgQ29uZmlndXJhdGlvbiBUYWJsZQogKglAYzogSTJPIGNvbnRyb2xsZXIgZnJvbSB3aGljaCB0aGUgTENUIHNob3VsZCBiZSBmZXRjaGVkCiAqCiAqCVNlbmQgYSBMQ1QgTk9USUZZIHJlcXVlc3QgdG8gdGhlIGNvbnRyb2xsZXIsIGFuZCB3YWl0CiAqCUkyT19USU1FT1VUX0xDVF9HRVQgc2Vjb25kcyB1bnRpbCBhcnJpdmFsIG9mIHJlc3BvbnNlLiBJZiB0aGUgTENUIGlzCiAqCXRvIGxhcmdlLCByZXRyeSBpdC4KICoKICoJUmV0dXJucyAwIG9uIHN1Y2Nlc3Mgb3IgbmVnYXRpdmUgZXJyb3IgY29kZSBvbiBmYWlsdXJlLgogKi8KaW50IGkyb19leGVjX2xjdF9nZXQoc3RydWN0IGkyb19jb250cm9sbGVyICpjKQp7CglzdHJ1Y3QgaTJvX21lc3NhZ2UgX19pb21lbSAqbXNnOwoJdTMyIG07CglpbnQgaSA9IDA7CglpbnQgcmMgPSAtRUFHQUlOOwoKCWZvciAoaSA9IDE7IGkgPD0gSTJPX0xDVF9HRVRfVFJJRVM7IGkrKykgewoJCW0gPSBpMm9fbXNnX2dldF93YWl0KGMsICZtc2csIEkyT19USU1FT1VUX01FU1NBR0VfR0VUKTsKCQlpZiAobSA9PSBJMk9fUVVFVUVfRU1QVFkpCgkJCXJldHVybiAtRVRJTUVET1VUOwoKCQl3cml0ZWwoRUlHSFRfV09SRF9NU0dfU0laRSB8IFNHTF9PRkZTRVRfNiwgJm1zZy0+dS5oZWFkWzBdKTsKCQl3cml0ZWwoSTJPX0NNRF9MQ1RfTk9USUZZIDw8IDI0IHwgSE9TVF9USUQgPDwgMTIgfCBBREFQVEVSX1RJRCwKCQkgICAgICAgJm1zZy0+dS5oZWFkWzFdKTsKCQl3cml0ZWwoMHhmZmZmZmZmZiwgJm1zZy0+Ym9keVswXSk7CgkJd3JpdGVsKDB4MDAwMDAwMDAsICZtc2ctPmJvZHlbMV0pOwoJCXdyaXRlbCgweGQwMDAwMDAwIHwgYy0+ZGxjdC5sZW4sICZtc2ctPmJvZHlbMl0pOwoJCXdyaXRlbChjLT5kbGN0LnBoeXMsICZtc2ctPmJvZHlbM10pOwoKCQlyYyA9IGkyb19tc2dfcG9zdF93YWl0KGMsIG0sIEkyT19USU1FT1VUX0xDVF9HRVQpOwoJCWlmIChyYyA8IDApCgkJCWJyZWFrOwoKCQlyYyA9IGkyb19kZXZpY2VfcGFyc2VfbGN0KGMpOwoJCWlmIChyYyAhPSAtRUFHQUlOKQoJCQlicmVhazsKCX0KCglyZXR1cm4gcmM7Cn0KCi8qKgogKglpMm9fZXhlY19sY3Rfbm90aWZ5IC0gU2VuZCBhIGFzeW5jaHJvbnVzIExDVCBOT1RJRlkgcmVxdWVzdAogKglAYzogSTJPIGNvbnRyb2xsZXIgdG8gd2hpY2ggdGhlIHJlcXVlc3Qgc2hvdWxkIGJlIHNlbmQKICoJQGNoYW5nZV9pbmQ6IGNoYW5nZSBpbmRpY2F0b3IKICoKICoJVGhpcyBmdW5jdGlvbiBzZW5kcyBhIExDVCBOT1RJRlkgcmVxdWVzdCB0byB0aGUgSTJPIGNvbnRyb2xsZXIgd2l0aAogKgl0aGUgY2hhbmdlIGluZGljYXRvciBjaGFuZ2VfaW5kLiBJZiB0aGUgY2hhbmdlX2luZCA9PSAwIHRoZSBjb250cm9sbGVyCiAqCXJlcGxpZXMgaW1tZWRpYXRlbHkgYWZ0ZXIgdGhlIHJlcXVlc3QuIElmIGNoYW5nZV9pbmQgPiAwIHRoZSByZXBseSBpcwogKglzZW5kIGFmdGVyIGNoYW5nZSBpbmRpY2F0b3Igb2YgdGhlIExDVCBpcyA+IGNoYW5nZV9pbmQuCiAqLwpzdGF0aWMgaW50IGkyb19leGVjX2xjdF9ub3RpZnkoc3RydWN0IGkyb19jb250cm9sbGVyICpjLCB1MzIgY2hhbmdlX2luZCkKewoJaTJvX3N0YXR1c19ibG9jayAqc2IgPSBjLT5zdGF0dXNfYmxvY2sudmlydDsKCXN0cnVjdCBkZXZpY2UgKmRldjsKCXN0cnVjdCBpMm9fbWVzc2FnZSBfX2lvbWVtICptc2c7Cgl1MzIgbTsKCglkZXYgPSAmYy0+cGRldi0+ZGV2OwoKCWlmIChpMm9fZG1hX3JlYWxsb2MoZGV2LCAmYy0+ZGxjdCwgc2ItPmV4cGVjdGVkX2xjdF9zaXplLCBHRlBfS0VSTkVMKSkKCQlyZXR1cm4gLUVOT01FTTsKCgltID0gaTJvX21zZ19nZXRfd2FpdChjLCAmbXNnLCBJMk9fVElNRU9VVF9NRVNTQUdFX0dFVCk7CglpZiAobSA9PSBJMk9fUVVFVUVfRU1QVFkpCgkJcmV0dXJuIC1FVElNRURPVVQ7CgoJd3JpdGVsKEVJR0hUX1dPUkRfTVNHX1NJWkUgfCBTR0xfT0ZGU0VUXzYsICZtc2ctPnUuaGVhZFswXSk7Cgl3cml0ZWwoSTJPX0NNRF9MQ1RfTk9USUZZIDw8IDI0IHwgSE9TVF9USUQgPDwgMTIgfCBBREFQVEVSX1RJRCwKCSAgICAgICAmbXNnLT51LmhlYWRbMV0pOwoJd3JpdGVsKGkyb19leGVjX2RyaXZlci5jb250ZXh0LCAmbXNnLT51LnMuaWNudHh0KTsKCXdyaXRlbCgwLCAmbXNnLT51LnMudGNudHh0KTsJLyogRklYTUUgKi8KCXdyaXRlbCgweGZmZmZmZmZmLCAmbXNnLT5ib2R5WzBdKTsKCXdyaXRlbChjaGFuZ2VfaW5kLCAmbXNnLT5ib2R5WzFdKTsKCXdyaXRlbCgweGQwMDAwMDAwIHwgYy0+ZGxjdC5sZW4sICZtc2ctPmJvZHlbMl0pOwoJd3JpdGVsKGMtPmRsY3QucGh5cywgJm1zZy0+Ym9keVszXSk7CgoJaTJvX21zZ19wb3N0KGMsIG0pOwoKCXJldHVybiAwOwp9OwoKLyogRXhlYyBPU00gZHJpdmVyIHN0cnVjdCAqLwpzdHJ1Y3QgaTJvX2RyaXZlciBpMm9fZXhlY19kcml2ZXIgPSB7CgkubmFtZSA9IE9TTV9OQU1FLAoJLnJlcGx5ID0gaTJvX2V4ZWNfcmVwbHksCgkuZXZlbnQgPSBpMm9fZXhlY19ldmVudCwKCS5jbGFzc2VzID0gaTJvX2V4ZWNfY2xhc3NfaWQsCgkuZHJpdmVyID0gewoJCSAgIC5wcm9iZSA9IGkyb19leGVjX3Byb2JlLAoJCSAgIC5yZW1vdmUgPSBpMm9fZXhlY19yZW1vdmUsCgkJICAgfSwKfTsKCi8qKgogKglpMm9fZXhlY19pbml0IC0gUmVnaXN0ZXJzIHRoZSBFeGVjIE9TTQogKgogKglSZWdpc3RlcnMgdGhlIEV4ZWMgT1NNIGluIHRoZSBJMk8gY29yZS4KICoKICoJUmV0dXJucyAwIG9uIHN1Y2Nlc3Mgb3IgbmVnYXRpdmUgZXJyb3IgY29kZSBvbiBmYWlsdXJlLgogKi8KaW50IF9faW5pdCBpMm9fZXhlY19pbml0KHZvaWQpCnsKCXJldHVybiBpMm9fZHJpdmVyX3JlZ2lzdGVyKCZpMm9fZXhlY19kcml2ZXIpOwp9OwoKLyoqCiAqCWkyb19leGVjX2V4aXQgLSBSZW1vdmVzIHRoZSBFeGVjIE9TTQogKgogKglVbnJlZ2lzdGVycyB0aGUgRXhlYyBPU00gZnJvbSB0aGUgSTJPIGNvcmUuCiAqLwp2b2lkIF9fZXhpdCBpMm9fZXhlY19leGl0KHZvaWQpCnsKCWkyb19kcml2ZXJfdW5yZWdpc3RlcigmaTJvX2V4ZWNfZHJpdmVyKTsKfTsKCkVYUE9SVF9TWU1CT0woaTJvX21zZ19wb3N0X3dhaXRfbWVtKTsKRVhQT1JUX1NZTUJPTChpMm9fZXhlY19sY3RfZ2V0KTsK