LyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLwovKiBpMmMtYWxnby1iaXQuYyBpMmMgZHJpdmVyIGFsZ29yaXRobXMgZm9yIGJpdC1zaGlmdCBhZGFwdGVycwkJICAgICAqLwovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCi8qICAgQ29weXJpZ2h0IChDKSAxOTk1LTIwMDAgU2ltb24gRy4gVm9nbAoKICAgIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5CiAgICBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieQogICAgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyIHZlcnNpb24gMiBvZiB0aGUgTGljZW5zZSwgb3IKICAgIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCgogICAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsCiAgICBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogICAgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZQogICAgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KCiAgICBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogICAgYWxvbmcgd2l0aCB0aGlzIHByb2dyYW07IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICAgIEZvdW5kYXRpb24sIEluYy4sIDY3NSBNYXNzIEF2ZSwgQ2FtYnJpZGdlLCBNQSAwMjEzOSwgVVNBLgkJICAgICAqLwovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgovKiBXaXRoIHNvbWUgY2hhbmdlcyBmcm9tIEZyb2RvIExvb2lqYWFyZCA8ZnJvZG9sQGRkcy5ubD4sIEt59nN0aSBN5Gxra2kKICAgPGttYWxra2lAY2MuaHV0LmZpPiBhbmQgSmVhbiBEZWx2YXJlIDxraGFsaUBsaW51eC1mci5vcmc+ICovCgojaW5jbHVkZSA8bGludXgva2VybmVsLmg+CiNpbmNsdWRlIDxsaW51eC9tb2R1bGUuaD4KI2luY2x1ZGUgPGxpbnV4L2RlbGF5Lmg+CiNpbmNsdWRlIDxsaW51eC9zbGFiLmg+CiNpbmNsdWRlIDxsaW51eC9pbml0Lmg+CiNpbmNsdWRlIDxsaW51eC9lcnJuby5oPgojaW5jbHVkZSA8bGludXgvc2NoZWQuaD4KI2luY2x1ZGUgPGxpbnV4L2kyYy5oPgojaW5jbHVkZSA8bGludXgvaTJjLWFsZ28tYml0Lmg+CgoKLyogLS0tLS0gZ2xvYmFsIGRlZmluZXMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KI2RlZmluZSBERUIoeCkgaWYgKGkyY19kZWJ1Zz49MSkgeDsKI2RlZmluZSBERUIyKHgpIGlmIChpMmNfZGVidWc+PTIpIHg7CiNkZWZpbmUgREVCU1RBVCh4KSBpZiAoaTJjX2RlYnVnPj0zKSB4OyAvKiBwcmludCBzZXZlcmFsIHN0YXRpc3RpY2FsIHZhbHVlcyovCiNkZWZpbmUgREVCUFJPVE8oeCkgaWYgKGkyY19kZWJ1Zz49OSkgeyB4OyB9CiAJLyogZGVidWcgdGhlIHByb3RvY29sIGJ5IHNob3dpbmcgdHJhbnNmZXJyZWQgYml0cyAqLwoKCi8qIC0tLS0tIGdsb2JhbCB2YXJpYWJsZXMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCSovCgovKiBtb2R1bGUgcGFyYW1ldGVyczoKICovCnN0YXRpYyBpbnQgaTJjX2RlYnVnOwpzdGF0aWMgaW50IGJpdF90ZXN0OwkvKiBzZWUgaWYgdGhlIGxpbmUtc2V0dGluZyBmdW5jdGlvbnMgd29yawkqLwoKLyogLS0tIHNldHRpbmcgc3RhdGVzIG9uIHRoZSBidXMgd2l0aCB0aGUgcmlnaHQgdGltaW5nOiAtLS0tLS0tLS0tLS0tLS0JKi8KCiNkZWZpbmUgc2V0c2RhKGFkYXAsdmFsKSBhZGFwLT5zZXRzZGEoYWRhcC0+ZGF0YSwgdmFsKQojZGVmaW5lIHNldHNjbChhZGFwLHZhbCkgYWRhcC0+c2V0c2NsKGFkYXAtPmRhdGEsIHZhbCkKI2RlZmluZSBnZXRzZGEoYWRhcCkgYWRhcC0+Z2V0c2RhKGFkYXAtPmRhdGEpCiNkZWZpbmUgZ2V0c2NsKGFkYXApIGFkYXAtPmdldHNjbChhZGFwLT5kYXRhKQoKc3RhdGljIGlubGluZSB2b2lkIHNkYWxvKHN0cnVjdCBpMmNfYWxnb19iaXRfZGF0YSAqYWRhcCkKewoJc2V0c2RhKGFkYXAsMCk7Cgl1ZGVsYXkoYWRhcC0+dWRlbGF5KTsKfQoKc3RhdGljIGlubGluZSB2b2lkIHNkYWhpKHN0cnVjdCBpMmNfYWxnb19iaXRfZGF0YSAqYWRhcCkKewoJc2V0c2RhKGFkYXAsMSk7Cgl1ZGVsYXkoYWRhcC0+dWRlbGF5KTsKfQoKc3RhdGljIGlubGluZSB2b2lkIHNjbGxvKHN0cnVjdCBpMmNfYWxnb19iaXRfZGF0YSAqYWRhcCkKewoJc2V0c2NsKGFkYXAsMCk7Cgl1ZGVsYXkoYWRhcC0+dWRlbGF5KTsKfQoKLyoKICogUmFpc2Ugc2NsIGxpbmUsIGFuZCBkbyBjaGVja2luZyBmb3IgZGVsYXlzLiBUaGlzIGlzIG5lY2Vzc2FyeSBmb3Igc2xvd2VyCiAqIGRldmljZXMuCiAqLwpzdGF0aWMgaW50IHNjbGhpKHN0cnVjdCBpMmNfYWxnb19iaXRfZGF0YSAqYWRhcCkKewoJdW5zaWduZWQgbG9uZyBzdGFydDsKCglzZXRzY2woYWRhcCwxKTsKCgkvKiBOb3QgYWxsIGFkYXB0ZXJzIGhhdmUgc2NsIHNlbnNlIGxpbmUuLi4gKi8KCWlmICghYWRhcC0+Z2V0c2NsKQoJCWdvdG8gZG9uZTsKCglzdGFydD1qaWZmaWVzOwoJd2hpbGUgKCEgZ2V0c2NsKGFkYXApICkgewkKIAkJLyogdGhlIGh3IGtub3dzIGhvdyB0byByZWFkIHRoZSBjbG9jayBsaW5lLAogCQkgKiBzbyB3ZSB3YWl0IHVudGlsIGl0IGFjdHVhbGx5IGdldHMgaGlnaC4KIAkJICogVGhpcyBpcyBzYWZlciBhcyBzb21lIGNoaXBzIG1heSBob2xkIGl0IGxvdwogCQkgKiB3aGlsZSB0aGV5IGFyZSBwcm9jZXNzaW5nIGRhdGEgaW50ZXJuYWxseS4gCiAJCSAqLwoJCWlmICh0aW1lX2FmdGVyX2VxKGppZmZpZXMsIHN0YXJ0K2FkYXAtPnRpbWVvdXQpKSB7CgkJCXJldHVybiAtRVRJTUVET1VUOwoJCX0KCQljb25kX3Jlc2NoZWQoKTsKCX0KCURFQlNUQVQocHJpbnRrKEtFUk5fREVCVUcgIm5lZWRlZCAlbGQgamlmZmllc1xuIiwgamlmZmllcy1zdGFydCkpOwoKZG9uZToKCXVkZWxheShhZGFwLT51ZGVsYXkpOwoJcmV0dXJuIDA7Cn0gCgoKLyogLS0tIG90aGVyIGF1eGlsaWFyeSBmdW5jdGlvbnMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0JKi8Kc3RhdGljIHZvaWQgaTJjX3N0YXJ0KHN0cnVjdCBpMmNfYWxnb19iaXRfZGF0YSAqYWRhcCkgCnsKCS8qIGFzc2VydDogc2NsLCBzZGEgYXJlIGhpZ2ggKi8KCURFQlBST1RPKHByaW50aygiUyAiKSk7CglzZGFsbyhhZGFwKTsKCXNjbGxvKGFkYXApOwp9CgpzdGF0aWMgdm9pZCBpMmNfcmVwc3RhcnQoc3RydWN0IGkyY19hbGdvX2JpdF9kYXRhICphZGFwKSAKewoJLyogc2NsLCBzZGEgbWF5IG5vdCBiZSBoaWdoICovCglERUJQUk9UTyhwcmludGsoIiBTciAiKSk7CglzZXRzZGEoYWRhcCwxKTsKCXNjbGhpKGFkYXApOwoJCglzZGFsbyhhZGFwKTsKCXNjbGxvKGFkYXApOwp9CgoKc3RhdGljIHZvaWQgaTJjX3N0b3Aoc3RydWN0IGkyY19hbGdvX2JpdF9kYXRhICphZGFwKSAKewoJREVCUFJPVE8ocHJpbnRrKCJQXG4iKSk7CgkvKiBhc3NlcnQ6IHNjbCBpcyBsb3cgKi8KCXNkYWxvKGFkYXApOwoJc2NsaGkoYWRhcCk7IAoJc2RhaGkoYWRhcCk7Cn0KCgoKLyogc2VuZCBhIGJ5dGUgd2l0aG91dCBzdGFydCBjb25kLiwgbG9vayBmb3IgYXJiaXRyYXRpb24sIAogICBjaGVjayBhY2tuLiBmcm9tIHNsYXZlICovCi8qIHJldHVybnM6CiAqIDEgaWYgdGhlIGRldmljZSBhY2tub3dsZWRnZWQKICogMCBpZiB0aGUgZGV2aWNlIGRpZCBub3QgYWNrCiAqIC1FVElNRURPVVQgaWYgYW4gZXJyb3Igb2NjdXJyZWQgKHdoaWxlIHJhaXNpbmcgdGhlIHNjbCBsaW5lKQogKi8Kc3RhdGljIGludCBpMmNfb3V0YihzdHJ1Y3QgaTJjX2FkYXB0ZXIgKmkyY19hZGFwLCBjaGFyIGMpCnsKCWludCBpOwoJaW50IHNiOwoJaW50IGFjazsKCXN0cnVjdCBpMmNfYWxnb19iaXRfZGF0YSAqYWRhcCA9IGkyY19hZGFwLT5hbGdvX2RhdGE7CgoJLyogYXNzZXJ0OiBzY2wgaXMgbG93ICovCglmb3IgKCBpPTcgOyBpPj0wIDsgaS0tICkgewoJCXNiID0gYyAmICggMSA8PCBpICk7CgkJc2V0c2RhKGFkYXAsc2IpOwoJCXVkZWxheShhZGFwLT51ZGVsYXkpOwoJCURFQlBST1RPKHByaW50ayhLRVJOX0RFQlVHICIlZCIsc2IhPTApKTsKCQlpZiAoc2NsaGkoYWRhcCk8MCkgeyAvKiB0aW1lZCBvdXQgKi8KCQkJc2RhaGkoYWRhcCk7IC8qIHdlIGRvbid0IHdhbnQgdG8gYmxvY2sgdGhlIG5ldCAqLwoJCQlERUIyKHByaW50ayhLRVJOX0RFQlVHICIgaTJjX291dGI6IDB4JTAyeCwgdGltZW91dCBhdCBiaXQgIyVkXG4iLCBjJjB4ZmYsIGkpKTsKCQkJcmV0dXJuIC1FVElNRURPVVQ7CgkJfTsKCQkvKiBkbyBhcmJpdHJhdGlvbiBoZXJlOiAKCQkgKiBpZiAoIHNiICYmICEgZ2V0c2RhKGFkYXApICkgLT4gb3VjaCEgR2V0IG91dCBvZiBoZXJlLgoJCSAqLwoJCXNldHNjbChhZGFwLCAwICk7CgkJdWRlbGF5KGFkYXAtPnVkZWxheSk7Cgl9CglzZGFoaShhZGFwKTsKCWlmIChzY2xoaShhZGFwKTwwKXsgLyogdGltZW91dCAqLwoJICAgIERFQjIocHJpbnRrKEtFUk5fREVCVUcgIiBpMmNfb3V0YjogMHglMDJ4LCB0aW1lb3V0IGF0IGFja1xuIiwgYyYweGZmKSk7CgkgICAgcmV0dXJuIC1FVElNRURPVVQ7Cgl9OwoJLyogcmVhZCBhY2s6IFNEQSBzaG91bGQgYmUgcHVsbGVkIGRvd24gYnkgc2xhdmUgKi8KCWFjaz1nZXRzZGEoYWRhcCk7CS8qIGFjazogc2RhIGlzIHB1bGxlZCBsb3cgLT5zdWNjZXNzLgkgKi8KCURFQjIocHJpbnRrKEtFUk5fREVCVUcgIiBpMmNfb3V0YjogMHglMDJ4ICwgZ2V0c2RhKCkgPSAlZFxuIiwgYyAmIDB4ZmYsIGFjaykpOwoKCURFQlBST1RPKCBwcmludGsoS0VSTl9ERUJVRyAiWyUyLjJ4XSIsYyYweGZmKSApOwoJREVCUFJPVE8oaWYgKDA9PWFjayl7IHByaW50ayhLRVJOX0RFQlVHICIgQSAiKTt9IGVsc2UgcHJpbnRrKEtFUk5fREVCVUcgIiBOQSAiKSApOwoJc2NsbG8oYWRhcCk7CglyZXR1cm4gMD09YWNrOwkJLyogcmV0dXJuIDEgaWYgZGV2aWNlIGFja2VkCSAqLwoJLyogYXNzZXJ0OiBzY2wgaXMgbG93IChzZGEgdW5kZWYpICovCn0KCgpzdGF0aWMgaW50IGkyY19pbmIoc3RydWN0IGkyY19hZGFwdGVyICppMmNfYWRhcCkgCnsKCS8qIHJlYWQgYnl0ZSB2aWEgaTJjIHBvcnQsIHdpdGhvdXQgc3RhcnQvc3RvcCBzZXF1ZW5jZQkqLwoJLyogYWNrbm93bGVkZ2UgaXMgc2VudCBpbiBpMmNfcmVhZC4JCQkqLwoJaW50IGk7Cgl1bnNpZ25lZCBjaGFyIGluZGF0YT0wOwoJc3RydWN0IGkyY19hbGdvX2JpdF9kYXRhICphZGFwID0gaTJjX2FkYXAtPmFsZ29fZGF0YTsKCgkvKiBhc3NlcnQ6IHNjbCBpcyBsb3cgKi8KCXNkYWhpKGFkYXApOwoJZm9yIChpPTA7aTw4O2krKykgewoJCWlmIChzY2xoaShhZGFwKTwwKSB7IC8qIHRpbWVvdXQgKi8KCQkJREVCMihwcmludGsoS0VSTl9ERUJVRyAiIGkyY19pbmI6IHRpbWVvdXQgYXQgYml0ICMlZFxuIiwgNy1pKSk7CgkJCXJldHVybiAtRVRJTUVET1VUOwoJCX07CgkJaW5kYXRhICo9IDI7CgkJaWYgKCBnZXRzZGEoYWRhcCkgKSAKCQkJaW5kYXRhIHw9IDB4MDE7CgkJc2NsbG8oYWRhcCk7Cgl9CgkvKiBhc3NlcnQ6IHNjbCBpcyBsb3cgKi8KCURFQjIocHJpbnRrKEtFUk5fREVCVUcgImkyY19pbmI6IDB4JTAyeFxuIiwgaW5kYXRhICYgMHhmZikpOwoKCURFQlBST1RPKHByaW50ayhLRVJOX0RFQlVHICIgMHglMDJ4IiwgaW5kYXRhICYgMHhmZikpOwoJcmV0dXJuIChpbnQpIChpbmRhdGEgJiAweGZmKTsKfQoKLyoKICogU2FuaXR5IGNoZWNrIGZvciB0aGUgYWRhcHRlciBoYXJkd2FyZSAtIGNoZWNrIHRoZSByZWFjdGlvbiBvZgogKiB0aGUgYnVzIGxpbmVzIG9ubHkgaWYgaXQgc2VlbXMgdG8gYmUgaWRsZS4KICovCnN0YXRpYyBpbnQgdGVzdF9idXMoc3RydWN0IGkyY19hbGdvX2JpdF9kYXRhICphZGFwLCBjaGFyKiBuYW1lKSB7CglpbnQgc2NsLHNkYTsKCglpZiAoYWRhcC0+Z2V0c2NsPT1OVUxMKQoJCXByaW50ayhLRVJOX0lORk8gImkyYy1hbGdvLWJpdC5vOiBUZXN0aW5nIFNEQSBvbmx5LCAiCgkJCSJTQ0wgaXMgbm90IHJlYWRhYmxlLlxuIik7CgoJc2RhPWdldHNkYShhZGFwKTsKCXNjbD0oYWRhcC0+Z2V0c2NsPT1OVUxMPzE6Z2V0c2NsKGFkYXApKTsKCXByaW50ayhLRVJOX0RFQlVHICJpMmMtYWxnby1iaXQubzogKDApIHNjbD0lZCwgc2RhPSVkXG4iLHNjbCxzZGEpOwoJaWYgKCFzY2wgfHwgIXNkYSApIHsKCQlwcmludGsoS0VSTl9XQVJOSU5HICJpMmMtYWxnby1iaXQubzogJXMgc2VlbXMgdG8gYmUgYnVzeS5cbiIsIG5hbWUpOwoJCWdvdG8gYmFpbG91dDsKCX0KCglzZGFsbyhhZGFwKTsKCXNkYT1nZXRzZGEoYWRhcCk7CglzY2w9KGFkYXAtPmdldHNjbD09TlVMTD8xOmdldHNjbChhZGFwKSk7CglwcmludGsoS0VSTl9ERUJVRyAiaTJjLWFsZ28tYml0Lm86ICgxKSBzY2w9JWQsIHNkYT0lZFxuIixzY2wsc2RhKTsKCWlmICggMCAhPSBzZGEgKSB7CgkJcHJpbnRrKEtFUk5fV0FSTklORyAiaTJjLWFsZ28tYml0Lm86IFNEQSBzdHVjayBoaWdoIVxuIik7CgkJZ290byBiYWlsb3V0OwoJfQoJaWYgKCAwID09IHNjbCApIHsKCQlwcmludGsoS0VSTl9XQVJOSU5HICJpMmMtYWxnby1iaXQubzogU0NMIHVuZXhwZWN0ZWQgbG93ICIKCQkJIndoaWxlIHB1bGxpbmcgU0RBIGxvdyFcbiIpOwoJCWdvdG8gYmFpbG91dDsKCX0JCQoKCXNkYWhpKGFkYXApOwoJc2RhPWdldHNkYShhZGFwKTsKCXNjbD0oYWRhcC0+Z2V0c2NsPT1OVUxMPzE6Z2V0c2NsKGFkYXApKTsKCXByaW50ayhLRVJOX0RFQlVHICJpMmMtYWxnby1iaXQubzogKDIpIHNjbD0lZCwgc2RhPSVkXG4iLHNjbCxzZGEpOwoJaWYgKCAwID09IHNkYSApIHsKCQlwcmludGsoS0VSTl9XQVJOSU5HICJpMmMtYWxnby1iaXQubzogU0RBIHN0dWNrIGxvdyFcbiIpOwoJCWdvdG8gYmFpbG91dDsKCX0KCWlmICggMCA9PSBzY2wgKSB7CgkJcHJpbnRrKEtFUk5fV0FSTklORyAiaTJjLWFsZ28tYml0Lm86IFNDTCB1bmV4cGVjdGVkIGxvdyAiCgkJCSJ3aGlsZSBwdWxsaW5nIFNEQSBoaWdoIVxuIik7CgkJZ290byBiYWlsb3V0OwoJfQoKCXNjbGxvKGFkYXApOwoJc2RhPWdldHNkYShhZGFwKTsKCXNjbD0oYWRhcC0+Z2V0c2NsPT1OVUxMPzA6Z2V0c2NsKGFkYXApKTsKCXByaW50ayhLRVJOX0RFQlVHICJpMmMtYWxnby1iaXQubzogKDMpIHNjbD0lZCwgc2RhPSVkXG4iLHNjbCxzZGEpOwoJaWYgKCAwICE9IHNjbCApIHsKCQlwcmludGsoS0VSTl9XQVJOSU5HICJpMmMtYWxnby1iaXQubzogU0NMIHN0dWNrIGhpZ2ghXG4iKTsKCQlnb3RvIGJhaWxvdXQ7Cgl9CglpZiAoIDAgPT0gc2RhICkgewoJCXByaW50ayhLRVJOX1dBUk5JTkcgImkyYy1hbGdvLWJpdC5vOiBTREEgdW5leHBlY3RlZCBsb3cgIgoJCQkid2hpbGUgcHVsbGluZyBTQ0wgbG93IVxuIik7CgkJZ290byBiYWlsb3V0OwoJfQoJCglzY2xoaShhZGFwKTsKCXNkYT1nZXRzZGEoYWRhcCk7CglzY2w9KGFkYXAtPmdldHNjbD09TlVMTD8xOmdldHNjbChhZGFwKSk7CglwcmludGsoS0VSTl9ERUJVRyAiaTJjLWFsZ28tYml0Lm86ICg0KSBzY2w9JWQsIHNkYT0lZFxuIixzY2wsc2RhKTsKCWlmICggMCA9PSBzY2wgKSB7CgkJcHJpbnRrKEtFUk5fV0FSTklORyAiaTJjLWFsZ28tYml0Lm86IFNDTCBzdHVjayBsb3chXG4iKTsKCQlnb3RvIGJhaWxvdXQ7Cgl9CglpZiAoIDAgPT0gc2RhICkgewoJCXByaW50ayhLRVJOX1dBUk5JTkcgImkyYy1hbGdvLWJpdC5vOiBTREEgdW5leHBlY3RlZCBsb3cgIgoJCQkid2hpbGUgcHVsbGluZyBTQ0wgaGlnaCFcbiIpOwoJCWdvdG8gYmFpbG91dDsKCX0KCXByaW50ayhLRVJOX0lORk8gImkyYy1hbGdvLWJpdC5vOiAlcyBwYXNzZWQgdGVzdC5cbiIsbmFtZSk7CglyZXR1cm4gMDsKYmFpbG91dDoKCXNkYWhpKGFkYXApOwoJc2NsaGkoYWRhcCk7CglyZXR1cm4gLUVOT0RFVjsKfQoKLyogLS0tLS0gVXRpbGl0eSBmdW5jdGlvbnMKICovCgovKiB0cnlfYWRkcmVzcyB0cmllcyB0byBjb250YWN0IGEgY2hpcCBmb3IgYSBudW1iZXIgb2YKICogdGltZXMgYmVmb3JlIGl0IGdpdmVzIHVwLgogKiByZXR1cm4gdmFsdWVzOgogKiAxIGNoaXAgYW5zd2VyZWQKICogMCBjaGlwIGRpZCBub3QgYW5zd2VyCiAqIC14IHRyYW5zbWlzc2lvbiBlcnJvcgogKi8Kc3RhdGljIGludCB0cnlfYWRkcmVzcyhzdHJ1Y3QgaTJjX2FkYXB0ZXIgKmkyY19hZGFwLAoJCSAgICAgICB1bnNpZ25lZCBjaGFyIGFkZHIsIGludCByZXRyaWVzKQp7CglzdHJ1Y3QgaTJjX2FsZ29fYml0X2RhdGEgKmFkYXAgPSBpMmNfYWRhcC0+YWxnb19kYXRhOwoJaW50IGkscmV0ID0gLTE7Cglmb3IgKGk9MDtpPD1yZXRyaWVzO2krKykgewoJCXJldCA9IGkyY19vdXRiKGkyY19hZGFwLGFkZHIpOwoJCWlmIChyZXQ9PTEpCgkJCWJyZWFrOwkvKiBzdWNjZXNzISAqLwoJCWkyY19zdG9wKGFkYXApOwoJCXVkZWxheSg1LyphZGFwLT51ZGVsYXkqLyk7CgkJaWYgKGk9PXJldHJpZXMpICAvKiBubyBzdWNjZXNzICovCgkJCWJyZWFrOwoJCWkyY19zdGFydChhZGFwKTsKCQl1ZGVsYXkoYWRhcC0+dWRlbGF5KTsKCX0KCURFQjIoaWYgKGkpCgkgICAgIHByaW50ayhLRVJOX0RFQlVHICJpMmMtYWxnby1iaXQubzogVXNlZCAlZCB0cmllcyB0byAlcyBjbGllbnQgYXQgMHglMDJ4IDogJXNcbiIsCgkJICAgIGkrMSwgYWRkciAmIDEgPyAicmVhZCIgOiAid3JpdGUiLCBhZGRyPj4xLAoJCSAgICByZXQ9PTEgPyAic3VjY2VzcyIgOiByZXQ9PTAgPyAibm8gYWNrIiA6ICJmYWlsZWQsIHRpbWVvdXQ/IiApCgkgICAgKTsKCXJldHVybiByZXQ7Cn0KCnN0YXRpYyBpbnQgc2VuZGJ5dGVzKHN0cnVjdCBpMmNfYWRhcHRlciAqaTJjX2FkYXAsIHN0cnVjdCBpMmNfbXNnICptc2cpCnsKCXN0cnVjdCBpMmNfYWxnb19iaXRfZGF0YSAqYWRhcCA9IGkyY19hZGFwLT5hbGdvX2RhdGE7CgljaGFyIGM7Cgljb25zdCBjaGFyICp0ZW1wID0gbXNnLT5idWY7CglpbnQgY291bnQgPSBtc2ctPmxlbjsKCXVuc2lnbmVkIHNob3J0IG5ha19vayA9IG1zZy0+ZmxhZ3MgJiBJMkNfTV9JR05PUkVfTkFLOyAKCWludCByZXR2YWw7CglpbnQgd3Jjb3VudD0wOwoKCXdoaWxlIChjb3VudCA+IDApIHsKCQljID0gKnRlbXA7CgkJREVCMihkZXZfZGJnKCZpMmNfYWRhcC0+ZGV2LCAic2VuZGJ5dGVzOiB3cml0aW5nICUyLjJYXG4iLCBjJjB4ZmYpKTsKCQlyZXR2YWwgPSBpMmNfb3V0YihpMmNfYWRhcCxjKTsKCQlpZiAoKHJldHZhbD4wKSB8fCAobmFrX29rICYmIChyZXR2YWw9PTApKSkgIHsgLyogb2sgb3IgaWdub3JlZCBOQUsgKi8KCQkJY291bnQtLTsgCgkJCXRlbXArKzsKCQkJd3Jjb3VudCsrOwoJCX0gZWxzZSB7IC8qIGFyYml0cmF0aW9uIG9yIG5vIGFja25vd2xlZGdlICovCgkJCWRldl9lcnIoJmkyY19hZGFwLT5kZXYsICJzZW5kYnl0ZXM6IGVycm9yIC0gYmFpbG91dC5cbiIpOwoJCQlpMmNfc3RvcChhZGFwKTsKCQkJcmV0dXJuIChyZXR2YWw8MCk/IHJldHZhbCA6IC1FRkFVTFQ7CgkJCSAgICAgICAgLyogZ290IGEgYmV0dGVyIG9uZSA/PyAqLwoJCX0KCX0KCXJldHVybiB3cmNvdW50Owp9CgpzdGF0aWMgaW50IHJlYWRieXRlcyhzdHJ1Y3QgaTJjX2FkYXB0ZXIgKmkyY19hZGFwLCBzdHJ1Y3QgaTJjX21zZyAqbXNnKQp7CglpbnQgaW52YWw7CglpbnQgcmRjb3VudD0wOyAgIAkvKiBjb3VudHMgYnl0ZXMgcmVhZCAqLwoJc3RydWN0IGkyY19hbGdvX2JpdF9kYXRhICphZGFwID0gaTJjX2FkYXAtPmFsZ29fZGF0YTsKCWNoYXIgKnRlbXAgPSBtc2ctPmJ1ZjsKCWludCBjb3VudCA9IG1zZy0+bGVuOwoKCXdoaWxlIChjb3VudCA+IDApIHsKCQlpbnZhbCA9IGkyY19pbmIoaTJjX2FkYXApOwoJCWlmIChpbnZhbD49MCkgewoJCQkqdGVtcCA9IGludmFsOwoJCQlyZGNvdW50Kys7CgkJfSBlbHNlIHsgICAvKiByZWFkIHRpbWVkIG91dCAqLwoJCQlwcmludGsoS0VSTl9FUlIgImkyYy1hbGdvLWJpdC5vOiByZWFkYnl0ZXM6IGkyY19pbmIgdGltZWQgb3V0LlxuIik7CgkJCWJyZWFrOwoJCX0KCgkJdGVtcCsrOwoJCWNvdW50LS07CgoJCWlmIChtc2ctPmZsYWdzICYgSTJDX01fTk9fUkRfQUNLKQoJCQljb250aW51ZTsKCgkJaWYgKCBjb3VudCA+IDAgKSB7CQkvKiBzZW5kIGFjayAqLwoJCQlzZGFsbyhhZGFwKTsKCQkJREVCUFJPVE8ocHJpbnRrKCIgQW0gIikpOwoJCX0gZWxzZSB7CgkJCXNkYWhpKGFkYXApOwkvKiBuZWcuIGFjayBvbiBsYXN0IGJ5dGUgKi8KCQkJREVCUFJPVE8ocHJpbnRrKCIgTkFtICIpKTsKCQl9CgkJaWYgKHNjbGhpKGFkYXApPDApIHsJLyogdGltZW91dCAqLwoJCQlzZGFoaShhZGFwKTsKCQkJcHJpbnRrKEtFUk5fRVJSICJpMmMtYWxnby1iaXQubzogcmVhZGJ5dGVzOiBUaW1lb3V0IGF0IGFja1xuIik7CgkJCXJldHVybiAtRVRJTUVET1VUOwoJCX07CgkJc2NsbG8oYWRhcCk7CgkJc2RhaGkoYWRhcCk7Cgl9CglyZXR1cm4gcmRjb3VudDsKfQoKLyogZG9BZGRyZXNzIGluaXRpYXRlcyB0aGUgdHJhbnNmZXIgYnkgZ2VuZXJhdGluZyB0aGUgc3RhcnQgY29uZGl0aW9uIChpbgogKiB0cnlfYWRkcmVzcykgYW5kIHRyYW5zbWl0cyB0aGUgYWRkcmVzcyBpbiB0aGUgbmVjZXNzYXJ5IGZvcm1hdCB0byBoYW5kbGUKICogcmVhZHMsIHdyaXRlcyBhcyB3ZWxsIGFzIDEwYml0LWFkZHJlc3Nlcy4KICogcmV0dXJuczoKICogIDAgZXZlcnl0aGluZyB3ZW50IG9rYXksIHRoZSBjaGlwIGFjaydlZCwgb3IgSUdOT1JFX05BSyBmbGFnIHdhcyBzZXQKICogLXggYW4gZXJyb3Igb2NjdXJyZWQgKGxpa2U6IC1FUkVNT1RFSU8gaWYgdGhlIGRldmljZSBkaWQgbm90IGFuc3dlciwgb3IKICoJLUVUSU1FRE9VVCwgZm9yIGV4YW1wbGUgaWYgdGhlIGxpbmVzIGFyZSBzdHVjay4uLikgCiAqLwpzdGF0aWMgaW50IGJpdF9kb0FkZHJlc3Moc3RydWN0IGkyY19hZGFwdGVyICppMmNfYWRhcCwgc3RydWN0IGkyY19tc2cgKm1zZykKewoJdW5zaWduZWQgc2hvcnQgZmxhZ3MgPSBtc2ctPmZsYWdzOwoJdW5zaWduZWQgc2hvcnQgbmFrX29rID0gbXNnLT5mbGFncyAmIEkyQ19NX0lHTk9SRV9OQUs7CglzdHJ1Y3QgaTJjX2FsZ29fYml0X2RhdGEgKmFkYXAgPSBpMmNfYWRhcC0+YWxnb19kYXRhOwoKCXVuc2lnbmVkIGNoYXIgYWRkcjsKCWludCByZXQsIHJldHJpZXM7CgoJcmV0cmllcyA9IG5ha19vayA/IDAgOiBpMmNfYWRhcC0+cmV0cmllczsKCQoJaWYgKCAoZmxhZ3MgJiBJMkNfTV9URU4pICApIHsgCgkJLyogYSB0ZW4gYml0IGFkZHJlc3MgKi8KCQlhZGRyID0gMHhmMCB8ICgoIG1zZy0+YWRkciA+PiA3KSAmIDB4MDMpOwoJCURFQjIocHJpbnRrKEtFUk5fREVCVUcgImFkZHIwOiAlZFxuIixhZGRyKSk7CgkJLyogdHJ5IGV4dGVuZGVkIGFkZHJlc3MgY29kZS4uLiovCgkJcmV0ID0gdHJ5X2FkZHJlc3MoaTJjX2FkYXAsIGFkZHIsIHJldHJpZXMpOwoJCWlmICgocmV0ICE9IDEpICYmICFuYWtfb2spICB7CgkJCXByaW50ayhLRVJOX0VSUiAiZGllZCBhdCBleHRlbmRlZCBhZGRyZXNzIGNvZGUuXG4iKTsKCQkJcmV0dXJuIC1FUkVNT1RFSU87CgkJfQoJCS8qIHRoZSByZW1haW5pbmcgOCBiaXQgYWRkcmVzcyAqLwoJCXJldCA9IGkyY19vdXRiKGkyY19hZGFwLG1zZy0+YWRkciAmIDB4N2YpOwoJCWlmICgocmV0ICE9IDEpICYmICFuYWtfb2spIHsKCQkJLyogdGhlIGNoaXAgZGlkIG5vdCBhY2sgLyB4bWlzc2lvbiBlcnJvciBvY2N1cnJlZCAqLwoJCQlwcmludGsoS0VSTl9FUlIgImRpZWQgYXQgMm5kIGFkZHJlc3MgY29kZS5cbiIpOwoJCQlyZXR1cm4gLUVSRU1PVEVJTzsKCQl9CgkJaWYgKCBmbGFncyAmIEkyQ19NX1JEICkgewoJCQlpMmNfcmVwc3RhcnQoYWRhcCk7CgkJCS8qIG9rYXksIG5vdyBzd2l0Y2ggaW50byByZWFkaW5nIG1vZGUgKi8KCQkJYWRkciB8PSAweDAxOwoJCQlyZXQgPSB0cnlfYWRkcmVzcyhpMmNfYWRhcCwgYWRkciwgcmV0cmllcyk7CgkJCWlmICgocmV0IT0xKSAmJiAhbmFrX29rKSB7CgkJCQlwcmludGsoS0VSTl9FUlIgImRpZWQgYXQgZXh0ZW5kZWQgYWRkcmVzcyBjb2RlLlxuIik7CgkJCQlyZXR1cm4gLUVSRU1PVEVJTzsKCQkJfQoJCX0KCX0gZWxzZSB7CQkvKiBub3JtYWwgN2JpdCBhZGRyZXNzCSovCgkJYWRkciA9ICggbXNnLT5hZGRyIDw8IDEgKTsKCQlpZiAoZmxhZ3MgJiBJMkNfTV9SRCApCgkJCWFkZHIgfD0gMTsKCQlpZiAoZmxhZ3MgJiBJMkNfTV9SRVZfRElSX0FERFIgKQoJCQlhZGRyIF49IDE7CgkJcmV0ID0gdHJ5X2FkZHJlc3MoaTJjX2FkYXAsIGFkZHIsIHJldHJpZXMpOwoJCWlmICgocmV0IT0xKSAmJiAhbmFrX29rKQoJCQlyZXR1cm4gLUVSRU1PVEVJTzsKCX0KCglyZXR1cm4gMDsKfQoKc3RhdGljIGludCBiaXRfeGZlcihzdHJ1Y3QgaTJjX2FkYXB0ZXIgKmkyY19hZGFwLAoJCSAgICBzdHJ1Y3QgaTJjX21zZyBtc2dzW10sIGludCBudW0pCnsKCXN0cnVjdCBpMmNfbXNnICpwbXNnOwoJc3RydWN0IGkyY19hbGdvX2JpdF9kYXRhICphZGFwID0gaTJjX2FkYXAtPmFsZ29fZGF0YTsKCQoJaW50IGkscmV0OwoJdW5zaWduZWQgc2hvcnQgbmFrX29rOwoKCWkyY19zdGFydChhZGFwKTsKCWZvciAoaT0wO2k8bnVtO2krKykgewoJCXBtc2cgPSAmbXNnc1tpXTsKCQluYWtfb2sgPSBwbXNnLT5mbGFncyAmIEkyQ19NX0lHTk9SRV9OQUs7IAoJCWlmICghKHBtc2ctPmZsYWdzICYgSTJDX01fTk9TVEFSVCkpIHsKCQkJaWYgKGkpIHsKCQkJCWkyY19yZXBzdGFydChhZGFwKTsKCQkJfQoJCQlyZXQgPSBiaXRfZG9BZGRyZXNzKGkyY19hZGFwLCBwbXNnKTsKCQkJaWYgKChyZXQgIT0gMCkgJiYgIW5ha19vaykgewoJCQkgICAgREVCMihwcmludGsoS0VSTl9ERUJVRyAiaTJjLWFsZ28tYml0Lm86IE5BSyBmcm9tIGRldmljZSBhZGRyICUyLjJ4IG1zZyAjJWRcbiIKCQkJCQksbXNnc1tpXS5hZGRyLGkpKTsKCQkJICAgIHJldHVybiAocmV0PDApID8gcmV0IDogLUVSRU1PVEVJTzsKCQkJfQoJCX0KCQlpZiAocG1zZy0+ZmxhZ3MgJiBJMkNfTV9SRCApIHsKCQkJLyogcmVhZCBieXRlcyBpbnRvIGJ1ZmZlciovCgkJCXJldCA9IHJlYWRieXRlcyhpMmNfYWRhcCwgcG1zZyk7CgkJCURFQjIocHJpbnRrKEtFUk5fREVCVUcgImkyYy1hbGdvLWJpdC5vOiByZWFkICVkIGJ5dGVzLlxuIixyZXQpKTsKCQkJaWYgKHJldCA8IHBtc2ctPmxlbiApIHsKCQkJCXJldHVybiAocmV0PDApPyByZXQgOiAtRVJFTU9URUlPOwoJCQl9CgkJfSBlbHNlIHsKCQkJLyogd3JpdGUgYnl0ZXMgZnJvbSBidWZmZXIgKi8KCQkJcmV0ID0gc2VuZGJ5dGVzKGkyY19hZGFwLCBwbXNnKTsKCQkJREVCMihwcmludGsoS0VSTl9ERUJVRyAiaTJjLWFsZ28tYml0Lm86IHdyb3RlICVkIGJ5dGVzLlxuIixyZXQpKTsKCQkJaWYgKHJldCA8IHBtc2ctPmxlbiApIHsKCQkJCXJldHVybiAocmV0PDApID8gcmV0IDogLUVSRU1PVEVJTzsKCQkJfQoJCX0KCX0KCWkyY19zdG9wKGFkYXApOwoJcmV0dXJuIG51bTsKfQoKc3RhdGljIHUzMiBiaXRfZnVuYyhzdHJ1Y3QgaTJjX2FkYXB0ZXIgKmFkYXApCnsKCXJldHVybiBJMkNfRlVOQ19JMkMgfCBJMkNfRlVOQ19TTUJVU19FTVVMIHwgCgkgICAgICAgSTJDX0ZVTkNfMTBCSVRfQUREUiB8IEkyQ19GVU5DX1BST1RPQ09MX01BTkdMSU5HOwp9CgoKLyogLS0tLS1leHBvcnRlZCBhbGdvcml0aG0gZGF0YTogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQkqLwoKc3RhdGljIGNvbnN0IHN0cnVjdCBpMmNfYWxnb3JpdGhtIGkyY19iaXRfYWxnbyA9IHsKCS5tYXN0ZXJfeGZlcgk9IGJpdF94ZmVyLAoJLmZ1bmN0aW9uYWxpdHkJPSBiaXRfZnVuYywKfTsKCi8qIAogKiByZWdpc3RlcmluZyBmdW5jdGlvbnMgdG8gbG9hZCBhbGdvcml0aG1zIGF0IHJ1bnRpbWUgCiAqLwppbnQgaTJjX2JpdF9hZGRfYnVzKHN0cnVjdCBpMmNfYWRhcHRlciAqYWRhcCkKewoJc3RydWN0IGkyY19hbGdvX2JpdF9kYXRhICpiaXRfYWRhcCA9IGFkYXAtPmFsZ29fZGF0YTsKCglpZiAoYml0X3Rlc3QpIHsKCQlpbnQgcmV0ID0gdGVzdF9idXMoYml0X2FkYXAsIGFkYXAtPm5hbWUpOwoJCWlmIChyZXQ8MCkKCQkJcmV0dXJuIC1FTk9ERVY7Cgl9CgoJREVCMihkZXZfZGJnKCZhZGFwLT5kZXYsICJodyByb3V0aW5lcyByZWdpc3RlcmVkLlxuIikpOwoKCS8qIHJlZ2lzdGVyIG5ldyBhZGFwdGVyIHRvIGkyYyBtb2R1bGUuLi4gKi8KCWFkYXAtPmFsZ28gPSAmaTJjX2JpdF9hbGdvOwoKCWFkYXAtPnRpbWVvdXQgPSAxMDA7CS8qIGRlZmF1bHQgdmFsdWVzLCBzaG91bGQJKi8KCWFkYXAtPnJldHJpZXMgPSAzOwkvKiBiZSByZXBsYWNlZCBieSBkZWZpbmVzCSovCgoJcmV0dXJuIGkyY19hZGRfYWRhcHRlcihhZGFwKTsKfQpFWFBPUlRfU1lNQk9MKGkyY19iaXRfYWRkX2J1cyk7CgpNT0RVTEVfQVVUSE9SKCJTaW1vbiBHLiBWb2dsIDxzaW1vbkB0ay51bmktbGluei5hYy5hdD4iKTsKTU9EVUxFX0RFU0NSSVBUSU9OKCJJMkMtQnVzIGJpdC1iYW5naW5nIGFsZ29yaXRobSIpOwpNT0RVTEVfTElDRU5TRSgiR1BMIik7Cgptb2R1bGVfcGFyYW0oYml0X3Rlc3QsIGJvb2wsIDApOwptb2R1bGVfcGFyYW0oaTJjX2RlYnVnLCBpbnQsIFNfSVJVR08gfCBTX0lXVVNSKTsKCk1PRFVMRV9QQVJNX0RFU0MoYml0X3Rlc3QsICJUZXN0IHRoZSBsaW5lcyBvZiB0aGUgYnVzIHRvIHNlZSBpZiBpdCBpcyBzdHVjayIpOwpNT0RVTEVfUEFSTV9ERVNDKGkyY19kZWJ1ZywKCQkgImRlYnVnIGxldmVsIC0gMCBvZmY7IDEgbm9ybWFsOyAyLDMgbW9yZSB2ZXJib3NlOyA5IGJpdC1wcm90b2NvbCIpOwo=