LyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLwovKiBpMmMtYWxnby1iaXQuYyBpMmMgZHJpdmVyIGFsZ29yaXRobXMgZm9yIGJpdC1zaGlmdCBhZGFwdGVycwkJICAgICAqLwovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCi8qICAgQ29weXJpZ2h0IChDKSAxOTk1LTIwMDAgU2ltb24gRy4gVm9nbAoKICAgIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5CiAgICBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieQogICAgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyIHZlcnNpb24gMiBvZiB0aGUgTGljZW5zZSwgb3IKICAgIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCgogICAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsCiAgICBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogICAgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZQogICAgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KCiAgICBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogICAgYWxvbmcgd2l0aCB0aGlzIHByb2dyYW07IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICAgIEZvdW5kYXRpb24sIEluYy4sIDY3NSBNYXNzIEF2ZSwgQ2FtYnJpZGdlLCBNQSAwMjEzOSwgVVNBLgkJICAgICAqLwovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgovKiBXaXRoIHNvbWUgY2hhbmdlcyBmcm9tIEZyb2RvIExvb2lqYWFyZCA8ZnJvZG9sQGRkcy5ubD4sIEt59nN0aSBN5Gxra2kKICAgPGttYWxra2lAY2MuaHV0LmZpPiBhbmQgSmVhbiBEZWx2YXJlIDxraGFsaUBsaW51eC1mci5vcmc+ICovCgojaW5jbHVkZSA8bGludXgva2VybmVsLmg+CiNpbmNsdWRlIDxsaW51eC9tb2R1bGUuaD4KI2luY2x1ZGUgPGxpbnV4L2RlbGF5Lmg+CiNpbmNsdWRlIDxsaW51eC9zbGFiLmg+CiNpbmNsdWRlIDxsaW51eC9pbml0Lmg+CiNpbmNsdWRlIDxsaW51eC9lcnJuby5oPgojaW5jbHVkZSA8bGludXgvc2NoZWQuaD4KI2luY2x1ZGUgPGxpbnV4L2kyYy5oPgojaW5jbHVkZSA8bGludXgvaTJjLWFsZ28tYml0Lmg+CgoKLyogLS0tLS0gZ2xvYmFsIGRlZmluZXMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KCiNpZmRlZiBERUJVRwojZGVmaW5lIGJpdF9kYmcobGV2ZWwsIGRldiwgZm9ybWF0LCBhcmdzLi4uKSBcCglkbyB7IFwKCQlpZiAoaTJjX2RlYnVnID49IGxldmVsKSBcCgkJCWRldl9kYmcoZGV2LCBmb3JtYXQsICMjYXJncyk7IFwKCX0gd2hpbGUgKDApCiNlbHNlCiNkZWZpbmUgYml0X2RiZyhsZXZlbCwgZGV2LCBmb3JtYXQsIGFyZ3MuLi4pIFwKCWRvIHt9IHdoaWxlICgwKQojZW5kaWYgLyogREVCVUcgKi8KCi8qIC0tLS0tIGdsb2JhbCB2YXJpYWJsZXMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCSovCgpzdGF0aWMgaW50IGJpdF90ZXN0OwkvKiBzZWUgaWYgdGhlIGxpbmUtc2V0dGluZyBmdW5jdGlvbnMgd29yawkqLwptb2R1bGVfcGFyYW0oYml0X3Rlc3QsIGJvb2wsIDApOwpNT0RVTEVfUEFSTV9ERVNDKGJpdF90ZXN0LCAiVGVzdCB0aGUgbGluZXMgb2YgdGhlIGJ1cyB0byBzZWUgaWYgaXQgaXMgc3R1Y2siKTsKCiNpZmRlZiBERUJVRwpzdGF0aWMgaW50IGkyY19kZWJ1ZyA9IDE7Cm1vZHVsZV9wYXJhbShpMmNfZGVidWcsIGludCwgU19JUlVHTyB8IFNfSVdVU1IpOwpNT0RVTEVfUEFSTV9ERVNDKGkyY19kZWJ1ZywKCQkgImRlYnVnIGxldmVsIC0gMCBvZmY7IDEgbm9ybWFsOyAyIHZlcmJvc2U7IDMgdmVyeSB2ZXJib3NlIik7CiNlbmRpZgoKLyogLS0tIHNldHRpbmcgc3RhdGVzIG9uIHRoZSBidXMgd2l0aCB0aGUgcmlnaHQgdGltaW5nOiAtLS0tLS0tLS0tLS0tLS0JKi8KCiNkZWZpbmUgc2V0c2RhKGFkYXAsdmFsKSBhZGFwLT5zZXRzZGEoYWRhcC0+ZGF0YSwgdmFsKQojZGVmaW5lIHNldHNjbChhZGFwLHZhbCkgYWRhcC0+c2V0c2NsKGFkYXAtPmRhdGEsIHZhbCkKI2RlZmluZSBnZXRzZGEoYWRhcCkgYWRhcC0+Z2V0c2RhKGFkYXAtPmRhdGEpCiNkZWZpbmUgZ2V0c2NsKGFkYXApIGFkYXAtPmdldHNjbChhZGFwLT5kYXRhKQoKc3RhdGljIGlubGluZSB2b2lkIHNkYWxvKHN0cnVjdCBpMmNfYWxnb19iaXRfZGF0YSAqYWRhcCkKewoJc2V0c2RhKGFkYXAsMCk7Cgl1ZGVsYXkoKGFkYXAtPnVkZWxheSArIDEpIC8gMik7Cn0KCnN0YXRpYyBpbmxpbmUgdm9pZCBzZGFoaShzdHJ1Y3QgaTJjX2FsZ29fYml0X2RhdGEgKmFkYXApCnsKCXNldHNkYShhZGFwLDEpOwoJdWRlbGF5KChhZGFwLT51ZGVsYXkgKyAxKSAvIDIpOwp9CgpzdGF0aWMgaW5saW5lIHZvaWQgc2NsbG8oc3RydWN0IGkyY19hbGdvX2JpdF9kYXRhICphZGFwKQp7CglzZXRzY2woYWRhcCwwKTsKCXVkZWxheShhZGFwLT51ZGVsYXkgLyAyKTsKfQoKLyoKICogUmFpc2Ugc2NsIGxpbmUsIGFuZCBkbyBjaGVja2luZyBmb3IgZGVsYXlzLiBUaGlzIGlzIG5lY2Vzc2FyeSBmb3Igc2xvd2VyCiAqIGRldmljZXMuCiAqLwpzdGF0aWMgaW50IHNjbGhpKHN0cnVjdCBpMmNfYWxnb19iaXRfZGF0YSAqYWRhcCkKewoJdW5zaWduZWQgbG9uZyBzdGFydDsKCglzZXRzY2woYWRhcCwxKTsKCgkvKiBOb3QgYWxsIGFkYXB0ZXJzIGhhdmUgc2NsIHNlbnNlIGxpbmUuLi4gKi8KCWlmICghYWRhcC0+Z2V0c2NsKQoJCWdvdG8gZG9uZTsKCglzdGFydD1qaWZmaWVzOwoJd2hpbGUgKCEgZ2V0c2NsKGFkYXApICkgewkKIAkJLyogdGhlIGh3IGtub3dzIGhvdyB0byByZWFkIHRoZSBjbG9jayBsaW5lLAogCQkgKiBzbyB3ZSB3YWl0IHVudGlsIGl0IGFjdHVhbGx5IGdldHMgaGlnaC4KIAkJICogVGhpcyBpcyBzYWZlciBhcyBzb21lIGNoaXBzIG1heSBob2xkIGl0IGxvdwogCQkgKiB3aGlsZSB0aGV5IGFyZSBwcm9jZXNzaW5nIGRhdGEgaW50ZXJuYWxseS4gCiAJCSAqLwoJCWlmICh0aW1lX2FmdGVyX2VxKGppZmZpZXMsIHN0YXJ0K2FkYXAtPnRpbWVvdXQpKSB7CgkJCXJldHVybiAtRVRJTUVET1VUOwoJCX0KCQljb25kX3Jlc2NoZWQoKTsKCX0KI2lmZGVmIERFQlVHCglpZiAoamlmZmllcyAhPSBzdGFydCAmJiBpMmNfZGVidWcgPj0gMykKCQlwcl9kZWJ1ZygiaTJjLWFsZ28tYml0OiBuZWVkZWQgJWxkIGppZmZpZXMgZm9yIFNDTCB0byBnbyAiCgkJCSAiaGlnaFxuIiwgamlmZmllcyAtIHN0YXJ0KTsKI2VuZGlmCgpkb25lOgoJdWRlbGF5KGFkYXAtPnVkZWxheSk7CglyZXR1cm4gMDsKfSAKCgovKiAtLS0gb3RoZXIgYXV4aWxpYXJ5IGZ1bmN0aW9ucyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQkqLwpzdGF0aWMgdm9pZCBpMmNfc3RhcnQoc3RydWN0IGkyY19hbGdvX2JpdF9kYXRhICphZGFwKSAKewoJLyogYXNzZXJ0OiBzY2wsIHNkYSBhcmUgaGlnaCAqLwoJc2V0c2RhKGFkYXAsIDApOwoJdWRlbGF5KGFkYXAtPnVkZWxheSk7CglzY2xsbyhhZGFwKTsKfQoKc3RhdGljIHZvaWQgaTJjX3JlcHN0YXJ0KHN0cnVjdCBpMmNfYWxnb19iaXRfZGF0YSAqYWRhcCkgCnsKCS8qIGFzc2VydDogc2NsIGlzIGxvdyAqLwoJc2RhaGkoYWRhcCk7CglzY2xoaShhZGFwKTsKCXNldHNkYShhZGFwLCAwKTsKCXVkZWxheShhZGFwLT51ZGVsYXkpOwoJc2NsbG8oYWRhcCk7Cn0KCgpzdGF0aWMgdm9pZCBpMmNfc3RvcChzdHJ1Y3QgaTJjX2FsZ29fYml0X2RhdGEgKmFkYXApIAp7CgkvKiBhc3NlcnQ6IHNjbCBpcyBsb3cgKi8KCXNkYWxvKGFkYXApOwoJc2NsaGkoYWRhcCk7IAoJc2V0c2RhKGFkYXAsIDEpOwoJdWRlbGF5KGFkYXAtPnVkZWxheSk7Cn0KCgoKLyogc2VuZCBhIGJ5dGUgd2l0aG91dCBzdGFydCBjb25kLiwgbG9vayBmb3IgYXJiaXRyYXRpb24sIAogICBjaGVjayBhY2tuLiBmcm9tIHNsYXZlICovCi8qIHJldHVybnM6CiAqIDEgaWYgdGhlIGRldmljZSBhY2tub3dsZWRnZWQKICogMCBpZiB0aGUgZGV2aWNlIGRpZCBub3QgYWNrCiAqIC1FVElNRURPVVQgaWYgYW4gZXJyb3Igb2NjdXJyZWQgKHdoaWxlIHJhaXNpbmcgdGhlIHNjbCBsaW5lKQogKi8Kc3RhdGljIGludCBpMmNfb3V0YihzdHJ1Y3QgaTJjX2FkYXB0ZXIgKmkyY19hZGFwLCB1bnNpZ25lZCBjaGFyIGMpCnsKCWludCBpOwoJaW50IHNiOwoJaW50IGFjazsKCXN0cnVjdCBpMmNfYWxnb19iaXRfZGF0YSAqYWRhcCA9IGkyY19hZGFwLT5hbGdvX2RhdGE7CgoJLyogYXNzZXJ0OiBzY2wgaXMgbG93ICovCglmb3IgKCBpPTcgOyBpPj0wIDsgaS0tICkgewoJCXNiID0gKGMgPj4gaSkgJiAxOwoJCXNldHNkYShhZGFwLHNiKTsKCQl1ZGVsYXkoKGFkYXAtPnVkZWxheSArIDEpIC8gMik7CgkJaWYgKHNjbGhpKGFkYXApPDApIHsgLyogdGltZWQgb3V0ICovCgkJCWJpdF9kYmcoMSwgJmkyY19hZGFwLT5kZXYsICJpMmNfb3V0YjogMHglMDJ4LCAiCgkJCQkidGltZW91dCBhdCBiaXQgIyVkXG4iLCAoaW50KWMsIGkpOwoJCQlyZXR1cm4gLUVUSU1FRE9VVDsKCQl9OwoJCS8qIGRvIGFyYml0cmF0aW9uIGhlcmU6IAoJCSAqIGlmICggc2IgJiYgISBnZXRzZGEoYWRhcCkgKSAtPiBvdWNoISBHZXQgb3V0IG9mIGhlcmUuCgkJICovCgkJc2NsbG8oYWRhcCk7Cgl9CglzZGFoaShhZGFwKTsKCWlmIChzY2xoaShhZGFwKTwwKXsgLyogdGltZW91dCAqLwoJCWJpdF9kYmcoMSwgJmkyY19hZGFwLT5kZXYsICJpMmNfb3V0YjogMHglMDJ4LCAiCgkJCSJ0aW1lb3V0IGF0IGFja1xuIiwgKGludCljKTsKCQlyZXR1cm4gLUVUSU1FRE9VVDsKCX07CgkvKiByZWFkIGFjazogU0RBIHNob3VsZCBiZSBwdWxsZWQgZG93biBieSBzbGF2ZSAqLwoJYWNrID0gIWdldHNkYShhZGFwKTsgICAgLyogYWNrOiBzZGEgaXMgcHVsbGVkIGxvdyAtPiBzdWNjZXNzICovCgliaXRfZGJnKDIsICZpMmNfYWRhcC0+ZGV2LCAiaTJjX291dGI6IDB4JTAyeCAlc1xuIiwgKGludCljLAoJCWFjayA/ICJBIiA6ICJOQSIpOwoKCXNjbGxvKGFkYXApOwoJcmV0dXJuIGFjazsKCS8qIGFzc2VydDogc2NsIGlzIGxvdyAoc2RhIHVuZGVmKSAqLwp9CgoKc3RhdGljIGludCBpMmNfaW5iKHN0cnVjdCBpMmNfYWRhcHRlciAqaTJjX2FkYXApIAp7CgkvKiByZWFkIGJ5dGUgdmlhIGkyYyBwb3J0LCB3aXRob3V0IHN0YXJ0L3N0b3Agc2VxdWVuY2UJKi8KCS8qIGFja25vd2xlZGdlIGlzIHNlbnQgaW4gaTJjX3JlYWQuCQkJKi8KCWludCBpOwoJdW5zaWduZWQgY2hhciBpbmRhdGE9MDsKCXN0cnVjdCBpMmNfYWxnb19iaXRfZGF0YSAqYWRhcCA9IGkyY19hZGFwLT5hbGdvX2RhdGE7CgoJLyogYXNzZXJ0OiBzY2wgaXMgbG93ICovCglzZGFoaShhZGFwKTsKCWZvciAoaT0wO2k8ODtpKyspIHsKCQlpZiAoc2NsaGkoYWRhcCk8MCkgeyAvKiB0aW1lb3V0ICovCgkJCWJpdF9kYmcoMSwgJmkyY19hZGFwLT5kZXYsICJpMmNfaW5iOiB0aW1lb3V0IGF0IGJpdCAiCgkJCQkiIyVkXG4iLCA3IC0gaSk7CgkJCXJldHVybiAtRVRJTUVET1VUOwoJCX07CgkJaW5kYXRhICo9IDI7CgkJaWYgKCBnZXRzZGEoYWRhcCkgKSAKCQkJaW5kYXRhIHw9IDB4MDE7CgkJc2V0c2NsKGFkYXAsIDApOwoJCXVkZWxheShpID09IDcgPyBhZGFwLT51ZGVsYXkgLyAyIDogYWRhcC0+dWRlbGF5KTsKCX0KCS8qIGFzc2VydDogc2NsIGlzIGxvdyAqLwoJcmV0dXJuIGluZGF0YTsKfQoKLyoKICogU2FuaXR5IGNoZWNrIGZvciB0aGUgYWRhcHRlciBoYXJkd2FyZSAtIGNoZWNrIHRoZSByZWFjdGlvbiBvZgogKiB0aGUgYnVzIGxpbmVzIG9ubHkgaWYgaXQgc2VlbXMgdG8gYmUgaWRsZS4KICovCnN0YXRpYyBpbnQgdGVzdF9idXMoc3RydWN0IGkyY19hbGdvX2JpdF9kYXRhICphZGFwLCBjaGFyKiBuYW1lKSB7CglpbnQgc2NsLHNkYTsKCglpZiAoYWRhcC0+Z2V0c2NsPT1OVUxMKQoJCXByX2luZm8oIiVzOiBUZXN0aW5nIFNEQSBvbmx5LCBTQ0wgaXMgbm90IHJlYWRhYmxlXG4iLCBuYW1lKTsKCglzZGE9Z2V0c2RhKGFkYXApOwoJc2NsPShhZGFwLT5nZXRzY2w9PU5VTEw/MTpnZXRzY2woYWRhcCkpOwoJaWYgKCFzY2wgfHwgIXNkYSApIHsKCQlwcmludGsoS0VSTl9XQVJOSU5HICIlczogYnVzIHNlZW1zIHRvIGJlIGJ1c3lcbiIsIG5hbWUpOwoJCWdvdG8gYmFpbG91dDsKCX0KCglzZGFsbyhhZGFwKTsKCXNkYT1nZXRzZGEoYWRhcCk7CglzY2w9KGFkYXAtPmdldHNjbD09TlVMTD8xOmdldHNjbChhZGFwKSk7CglpZiAoIDAgIT0gc2RhICkgewoJCXByaW50ayhLRVJOX1dBUk5JTkcgIiVzOiBTREEgc3R1Y2sgaGlnaCFcbiIsIG5hbWUpOwoJCWdvdG8gYmFpbG91dDsKCX0KCWlmICggMCA9PSBzY2wgKSB7CgkJcHJpbnRrKEtFUk5fV0FSTklORyAiJXM6IFNDTCB1bmV4cGVjdGVkIGxvdyAiCgkJICAgICAgICJ3aGlsZSBwdWxsaW5nIFNEQSBsb3chXG4iLCBuYW1lKTsKCQlnb3RvIGJhaWxvdXQ7Cgl9CQkKCglzZGFoaShhZGFwKTsKCXNkYT1nZXRzZGEoYWRhcCk7CglzY2w9KGFkYXAtPmdldHNjbD09TlVMTD8xOmdldHNjbChhZGFwKSk7CglpZiAoIDAgPT0gc2RhICkgewoJCXByaW50ayhLRVJOX1dBUk5JTkcgIiVzOiBTREEgc3R1Y2sgbG93IVxuIiwgbmFtZSk7CgkJZ290byBiYWlsb3V0OwoJfQoJaWYgKCAwID09IHNjbCApIHsKCQlwcmludGsoS0VSTl9XQVJOSU5HICIlczogU0NMIHVuZXhwZWN0ZWQgbG93ICIKCQkgICAgICAgIndoaWxlIHB1bGxpbmcgU0RBIGhpZ2ghXG4iLCBuYW1lKTsKCQlnb3RvIGJhaWxvdXQ7Cgl9CgoJc2NsbG8oYWRhcCk7CglzZGE9Z2V0c2RhKGFkYXApOwoJc2NsPShhZGFwLT5nZXRzY2w9PU5VTEw/MDpnZXRzY2woYWRhcCkpOwoJaWYgKCAwICE9IHNjbCApIHsKCQlwcmludGsoS0VSTl9XQVJOSU5HICIlczogU0NMIHN0dWNrIGhpZ2ghXG4iLCBuYW1lKTsKCQlnb3RvIGJhaWxvdXQ7Cgl9CglpZiAoIDAgPT0gc2RhICkgewoJCXByaW50ayhLRVJOX1dBUk5JTkcgIiVzOiBTREEgdW5leHBlY3RlZCBsb3cgIgoJCSAgICAgICAid2hpbGUgcHVsbGluZyBTQ0wgbG93IVxuIiwgbmFtZSk7CgkJZ290byBiYWlsb3V0OwoJfQoJCglzY2xoaShhZGFwKTsKCXNkYT1nZXRzZGEoYWRhcCk7CglzY2w9KGFkYXAtPmdldHNjbD09TlVMTD8xOmdldHNjbChhZGFwKSk7CglpZiAoIDAgPT0gc2NsICkgewoJCXByaW50ayhLRVJOX1dBUk5JTkcgIiVzOiBTQ0wgc3R1Y2sgbG93IVxuIiwgbmFtZSk7CgkJZ290byBiYWlsb3V0OwoJfQoJaWYgKCAwID09IHNkYSApIHsKCQlwcmludGsoS0VSTl9XQVJOSU5HICIlczogU0RBIHVuZXhwZWN0ZWQgbG93ICIKCQkgICAgICAgIndoaWxlIHB1bGxpbmcgU0NMIGhpZ2ghXG4iLCBuYW1lKTsKCQlnb3RvIGJhaWxvdXQ7Cgl9Cglwcl9pbmZvKCIlczogVGVzdCBPS1xuIiwgbmFtZSk7CglyZXR1cm4gMDsKYmFpbG91dDoKCXNkYWhpKGFkYXApOwoJc2NsaGkoYWRhcCk7CglyZXR1cm4gLUVOT0RFVjsKfQoKLyogLS0tLS0gVXRpbGl0eSBmdW5jdGlvbnMKICovCgovKiB0cnlfYWRkcmVzcyB0cmllcyB0byBjb250YWN0IGEgY2hpcCBmb3IgYSBudW1iZXIgb2YKICogdGltZXMgYmVmb3JlIGl0IGdpdmVzIHVwLgogKiByZXR1cm4gdmFsdWVzOgogKiAxIGNoaXAgYW5zd2VyZWQKICogMCBjaGlwIGRpZCBub3QgYW5zd2VyCiAqIC14IHRyYW5zbWlzc2lvbiBlcnJvcgogKi8Kc3RhdGljIGludCB0cnlfYWRkcmVzcyhzdHJ1Y3QgaTJjX2FkYXB0ZXIgKmkyY19hZGFwLAoJCSAgICAgICB1bnNpZ25lZCBjaGFyIGFkZHIsIGludCByZXRyaWVzKQp7CglzdHJ1Y3QgaTJjX2FsZ29fYml0X2RhdGEgKmFkYXAgPSBpMmNfYWRhcC0+YWxnb19kYXRhOwoJaW50IGkscmV0ID0gLTE7Cglmb3IgKGk9MDtpPD1yZXRyaWVzO2krKykgewoJCXJldCA9IGkyY19vdXRiKGkyY19hZGFwLGFkZHIpOwoJCWlmIChyZXQgPT0gMSB8fCBpID09IHJldHJpZXMpCgkJCWJyZWFrOwoJCWJpdF9kYmcoMywgJmkyY19hZGFwLT5kZXYsICJlbWl0dGluZyBzdG9wIGNvbmRpdGlvblxuIik7CgkJaTJjX3N0b3AoYWRhcCk7CgkJdWRlbGF5KGFkYXAtPnVkZWxheSk7CgkJeWllbGQoKTsKCQliaXRfZGJnKDMsICZpMmNfYWRhcC0+ZGV2LCAiZW1pdHRpbmcgc3RhcnQgY29uZGl0aW9uXG4iKTsKCQlpMmNfc3RhcnQoYWRhcCk7Cgl9CglpZiAoaSAmJiByZXQpCgkJYml0X2RiZygxLCAmaTJjX2FkYXAtPmRldiwgIlVzZWQgJWQgdHJpZXMgdG8gJXMgY2xpZW50IGF0ICIKCQkJIjB4JTAyeDogJXNcbiIsIGkgKyAxLAoJCQlhZGRyICYgMSA/ICJyZWFkIGZyb20iIDogIndyaXRlIHRvIiwgYWRkciA+PiAxLAoJCQlyZXQgPT0gMSA/ICJzdWNjZXNzIiA6ICJmYWlsZWQsIHRpbWVvdXQ/Iik7CglyZXR1cm4gcmV0Owp9CgpzdGF0aWMgaW50IHNlbmRieXRlcyhzdHJ1Y3QgaTJjX2FkYXB0ZXIgKmkyY19hZGFwLCBzdHJ1Y3QgaTJjX21zZyAqbXNnKQp7Cgljb25zdCB1bnNpZ25lZCBjaGFyICp0ZW1wID0gbXNnLT5idWY7CglpbnQgY291bnQgPSBtc2ctPmxlbjsKCXVuc2lnbmVkIHNob3J0IG5ha19vayA9IG1zZy0+ZmxhZ3MgJiBJMkNfTV9JR05PUkVfTkFLOyAKCWludCByZXR2YWw7CglpbnQgd3Jjb3VudD0wOwoKCXdoaWxlIChjb3VudCA+IDApIHsKCQlyZXR2YWwgPSBpMmNfb3V0YihpMmNfYWRhcCwgKnRlbXApOwoJCWlmICgocmV0dmFsPjApIHx8IChuYWtfb2sgJiYgKHJldHZhbD09MCkpKSAgeyAvKiBvayBvciBpZ25vcmVkIE5BSyAqLwoJCQljb3VudC0tOyAKCQkJdGVtcCsrOwoJCQl3cmNvdW50Kys7CgkJfSBlbHNlIHsgLyogYXJiaXRyYXRpb24gb3Igbm8gYWNrbm93bGVkZ2UgKi8KCQkJZGV2X2VycigmaTJjX2FkYXAtPmRldiwgInNlbmRieXRlczogZXJyb3IgLSBiYWlsb3V0LlxuIik7CgkJCXJldHVybiAocmV0dmFsPDApPyByZXR2YWwgOiAtRUZBVUxUOwoJCQkgICAgICAgIC8qIGdvdCBhIGJldHRlciBvbmUgPz8gKi8KCQl9Cgl9CglyZXR1cm4gd3Jjb3VudDsKfQoKc3RhdGljIGludCByZWFkYnl0ZXMoc3RydWN0IGkyY19hZGFwdGVyICppMmNfYWRhcCwgc3RydWN0IGkyY19tc2cgKm1zZykKewoJaW50IGludmFsOwoJaW50IHJkY291bnQ9MDsgICAJLyogY291bnRzIGJ5dGVzIHJlYWQgKi8KCXN0cnVjdCBpMmNfYWxnb19iaXRfZGF0YSAqYWRhcCA9IGkyY19hZGFwLT5hbGdvX2RhdGE7Cgl1bnNpZ25lZCBjaGFyICp0ZW1wID0gbXNnLT5idWY7CglpbnQgY291bnQgPSBtc2ctPmxlbjsKCgl3aGlsZSAoY291bnQgPiAwKSB7CgkJaW52YWwgPSBpMmNfaW5iKGkyY19hZGFwKTsKCQlpZiAoaW52YWw+PTApIHsKCQkJKnRlbXAgPSBpbnZhbDsKCQkJcmRjb3VudCsrOwoJCX0gZWxzZSB7ICAgLyogcmVhZCB0aW1lZCBvdXQgKi8KCQkJYnJlYWs7CgkJfQoKCQl0ZW1wKys7CgkJY291bnQtLTsKCgkJaWYgKG1zZy0+ZmxhZ3MgJiBJMkNfTV9OT19SRF9BQ0spIHsKCQkJYml0X2RiZygyLCAmaTJjX2FkYXAtPmRldiwgImkyY19pbmI6IDB4JTAyeFxuIiwKCQkJCWludmFsKTsKCQkJY29udGludWU7CgkJfQoKCQkvKiBhc3NlcnQ6IHNkYSBpcyBoaWdoICovCgkJaWYgKGNvdW50KQkJLyogc2VuZCBhY2sgKi8KCQkJc2V0c2RhKGFkYXAsIDApOwoJCXVkZWxheSgoYWRhcC0+dWRlbGF5ICsgMSkgLyAyKTsKCQliaXRfZGJnKDIsICZpMmNfYWRhcC0+ZGV2LCAiaTJjX2luYjogMHglMDJ4ICVzXG4iLCBpbnZhbCwKCQkJY291bnQgPyAiQSIgOiAiTkEiKTsKCQlpZiAoc2NsaGkoYWRhcCk8MCkgewkvKiB0aW1lb3V0ICovCgkJCWRldl9lcnIoJmkyY19hZGFwLT5kZXYsICJyZWFkYnl0ZXM6IHRpbWVvdXQgYXQgYWNrXG4iKTsKCQkJcmV0dXJuIC1FVElNRURPVVQ7CgkJfTsKCQlzY2xsbyhhZGFwKTsKCgkJLyogU29tZSBTTUJ1cyB0cmFuc2FjdGlvbnMgcmVxdWlyZSB0aGF0IHdlIHJlY2VpdmUgdGhlCgkJICAgdHJhbnNhY3Rpb24gbGVuZ3RoIGFzIHRoZSBmaXJzdCByZWFkIGJ5dGUuICovCgkJaWYgKHJkY291bnQgPT0gMSAmJiAobXNnLT5mbGFncyAmIEkyQ19NX1JFQ1ZfTEVOKSkgewoJCQlpZiAoaW52YWwgPD0gMCB8fCBpbnZhbCA+IEkyQ19TTUJVU19CTE9DS19NQVgpIHsKCQkJCWRldl9lcnIoJmkyY19hZGFwLT5kZXYsICJyZWFkYnl0ZXM6IGludmFsaWQgIgoJCQkJCSJibG9jayBsZW5ndGggKCVkKVxuIiwgaW52YWwpOwoJCQkJcmV0dXJuIC1FUkVNT1RFSU87CgkJCX0KCQkJLyogVGhlIG9yaWdpbmFsIGNvdW50IHZhbHVlIGFjY291bnRzIGZvciB0aGUgZXh0cmEKCQkJICAgYnl0ZXMsIHRoYXQgaXMsIGVpdGhlciAxIGZvciBhIHJlZ3VsYXIgdHJhbnNhY3Rpb24sCgkJCSAgIG9yIDIgZm9yIGEgUEVDIHRyYW5zYWN0aW9uLiAqLwoJCQljb3VudCArPSBpbnZhbDsKCQkJbXNnLT5sZW4gKz0gaW52YWw7CgkJfQoJfQoJcmV0dXJuIHJkY291bnQ7Cn0KCi8qIGRvQWRkcmVzcyBpbml0aWF0ZXMgdGhlIHRyYW5zZmVyIGJ5IGdlbmVyYXRpbmcgdGhlIHN0YXJ0IGNvbmRpdGlvbiAoaW4KICogdHJ5X2FkZHJlc3MpIGFuZCB0cmFuc21pdHMgdGhlIGFkZHJlc3MgaW4gdGhlIG5lY2Vzc2FyeSBmb3JtYXQgdG8gaGFuZGxlCiAqIHJlYWRzLCB3cml0ZXMgYXMgd2VsbCBhcyAxMGJpdC1hZGRyZXNzZXMuCiAqIHJldHVybnM6CiAqICAwIGV2ZXJ5dGhpbmcgd2VudCBva2F5LCB0aGUgY2hpcCBhY2snZWQsIG9yIElHTk9SRV9OQUsgZmxhZyB3YXMgc2V0CiAqIC14IGFuIGVycm9yIG9jY3VycmVkIChsaWtlOiAtRVJFTU9URUlPIGlmIHRoZSBkZXZpY2UgZGlkIG5vdCBhbnN3ZXIsIG9yCiAqCS1FVElNRURPVVQsIGZvciBleGFtcGxlIGlmIHRoZSBsaW5lcyBhcmUgc3R1Y2suLi4pIAogKi8Kc3RhdGljIGludCBiaXRfZG9BZGRyZXNzKHN0cnVjdCBpMmNfYWRhcHRlciAqaTJjX2FkYXAsIHN0cnVjdCBpMmNfbXNnICptc2cpCnsKCXVuc2lnbmVkIHNob3J0IGZsYWdzID0gbXNnLT5mbGFnczsKCXVuc2lnbmVkIHNob3J0IG5ha19vayA9IG1zZy0+ZmxhZ3MgJiBJMkNfTV9JR05PUkVfTkFLOwoJc3RydWN0IGkyY19hbGdvX2JpdF9kYXRhICphZGFwID0gaTJjX2FkYXAtPmFsZ29fZGF0YTsKCgl1bnNpZ25lZCBjaGFyIGFkZHI7CglpbnQgcmV0LCByZXRyaWVzOwoKCXJldHJpZXMgPSBuYWtfb2sgPyAwIDogaTJjX2FkYXAtPnJldHJpZXM7CgkKCWlmICggKGZsYWdzICYgSTJDX01fVEVOKSAgKSB7IAoJCS8qIGEgdGVuIGJpdCBhZGRyZXNzICovCgkJYWRkciA9IDB4ZjAgfCAoKCBtc2ctPmFkZHIgPj4gNykgJiAweDAzKTsKCQliaXRfZGJnKDIsICZpMmNfYWRhcC0+ZGV2LCAiYWRkcjA6ICVkXG4iLCBhZGRyKTsKCQkvKiB0cnkgZXh0ZW5kZWQgYWRkcmVzcyBjb2RlLi4uKi8KCQlyZXQgPSB0cnlfYWRkcmVzcyhpMmNfYWRhcCwgYWRkciwgcmV0cmllcyk7CgkJaWYgKChyZXQgIT0gMSkgJiYgIW5ha19vaykgIHsKCQkJZGV2X2VycigmaTJjX2FkYXAtPmRldiwKCQkJCSJkaWVkIGF0IGV4dGVuZGVkIGFkZHJlc3MgY29kZVxuIik7CgkJCXJldHVybiAtRVJFTU9URUlPOwoJCX0KCQkvKiB0aGUgcmVtYWluaW5nIDggYml0IGFkZHJlc3MgKi8KCQlyZXQgPSBpMmNfb3V0YihpMmNfYWRhcCxtc2ctPmFkZHIgJiAweDdmKTsKCQlpZiAoKHJldCAhPSAxKSAmJiAhbmFrX29rKSB7CgkJCS8qIHRoZSBjaGlwIGRpZCBub3QgYWNrIC8geG1pc3Npb24gZXJyb3Igb2NjdXJyZWQgKi8KCQkJZGV2X2VycigmaTJjX2FkYXAtPmRldiwgImRpZWQgYXQgMm5kIGFkZHJlc3MgY29kZVxuIik7CgkJCXJldHVybiAtRVJFTU9URUlPOwoJCX0KCQlpZiAoIGZsYWdzICYgSTJDX01fUkQgKSB7CgkJCWJpdF9kYmcoMywgJmkyY19hZGFwLT5kZXYsICJlbWl0dGluZyByZXBlYXRlZCAiCgkJCQkic3RhcnQgY29uZGl0aW9uXG4iKTsKCQkJaTJjX3JlcHN0YXJ0KGFkYXApOwoJCQkvKiBva2F5LCBub3cgc3dpdGNoIGludG8gcmVhZGluZyBtb2RlICovCgkJCWFkZHIgfD0gMHgwMTsKCQkJcmV0ID0gdHJ5X2FkZHJlc3MoaTJjX2FkYXAsIGFkZHIsIHJldHJpZXMpOwoJCQlpZiAoKHJldCE9MSkgJiYgIW5ha19vaykgewoJCQkJZGV2X2VycigmaTJjX2FkYXAtPmRldiwKCQkJCQkiZGllZCBhdCByZXBlYXRlZCBhZGRyZXNzIGNvZGVcbiIpOwoJCQkJcmV0dXJuIC1FUkVNT1RFSU87CgkJCX0KCQl9Cgl9IGVsc2UgewkJLyogbm9ybWFsIDdiaXQgYWRkcmVzcwkqLwoJCWFkZHIgPSAoIG1zZy0+YWRkciA8PCAxICk7CgkJaWYgKGZsYWdzICYgSTJDX01fUkQgKQoJCQlhZGRyIHw9IDE7CgkJaWYgKGZsYWdzICYgSTJDX01fUkVWX0RJUl9BRERSICkKCQkJYWRkciBePSAxOwoJCXJldCA9IHRyeV9hZGRyZXNzKGkyY19hZGFwLCBhZGRyLCByZXRyaWVzKTsKCQlpZiAoKHJldCE9MSkgJiYgIW5ha19vaykKCQkJcmV0dXJuIC1FUkVNT1RFSU87Cgl9CgoJcmV0dXJuIDA7Cn0KCnN0YXRpYyBpbnQgYml0X3hmZXIoc3RydWN0IGkyY19hZGFwdGVyICppMmNfYWRhcCwKCQkgICAgc3RydWN0IGkyY19tc2cgbXNnc1tdLCBpbnQgbnVtKQp7CglzdHJ1Y3QgaTJjX21zZyAqcG1zZzsKCXN0cnVjdCBpMmNfYWxnb19iaXRfZGF0YSAqYWRhcCA9IGkyY19hZGFwLT5hbGdvX2RhdGE7CgkKCWludCBpLHJldDsKCXVuc2lnbmVkIHNob3J0IG5ha19vazsKCgliaXRfZGJnKDMsICZpMmNfYWRhcC0+ZGV2LCAiZW1pdHRpbmcgc3RhcnQgY29uZGl0aW9uXG4iKTsKCWkyY19zdGFydChhZGFwKTsKCWZvciAoaT0wO2k8bnVtO2krKykgewoJCXBtc2cgPSAmbXNnc1tpXTsKCQluYWtfb2sgPSBwbXNnLT5mbGFncyAmIEkyQ19NX0lHTk9SRV9OQUs7IAoJCWlmICghKHBtc2ctPmZsYWdzICYgSTJDX01fTk9TVEFSVCkpIHsKCQkJaWYgKGkpIHsKCQkJCWJpdF9kYmcoMywgJmkyY19hZGFwLT5kZXYsICJlbWl0dGluZyAiCgkJCQkJInJlcGVhdGVkIHN0YXJ0IGNvbmRpdGlvblxuIik7CgkJCQlpMmNfcmVwc3RhcnQoYWRhcCk7CgkJCX0KCQkJcmV0ID0gYml0X2RvQWRkcmVzcyhpMmNfYWRhcCwgcG1zZyk7CgkJCWlmICgocmV0ICE9IDApICYmICFuYWtfb2spIHsKCQkJCWJpdF9kYmcoMSwgJmkyY19hZGFwLT5kZXYsICJOQUsgZnJvbSAiCgkJCQkJImRldmljZSBhZGRyIDB4JTAyeCBtc2cgIyVkXG4iLAoJCQkJCW1zZ3NbaV0uYWRkciwgaSk7CgkJCQlnb3RvIGJhaWxvdXQ7CgkJCX0KCQl9CgkJaWYgKHBtc2ctPmZsYWdzICYgSTJDX01fUkQgKSB7CgkJCS8qIHJlYWQgYnl0ZXMgaW50byBidWZmZXIqLwoJCQlyZXQgPSByZWFkYnl0ZXMoaTJjX2FkYXAsIHBtc2cpOwoJCQlpZiAocmV0ID49IDEpCgkJCQliaXRfZGJnKDIsICZpMmNfYWRhcC0+ZGV2LCAicmVhZCAlZCBieXRlJXNcbiIsCgkJCQkJcmV0LCByZXQgPT0gMSA/ICIiIDogInMiKTsKCQkJaWYgKHJldCA8IHBtc2ctPmxlbikgewoJCQkJaWYgKHJldCA+PSAwKQoJCQkJCXJldCA9IC1FUkVNT1RFSU87CgkJCQlnb3RvIGJhaWxvdXQ7CgkJCX0KCQl9IGVsc2UgewoJCQkvKiB3cml0ZSBieXRlcyBmcm9tIGJ1ZmZlciAqLwoJCQlyZXQgPSBzZW5kYnl0ZXMoaTJjX2FkYXAsIHBtc2cpOwoJCQlpZiAocmV0ID49IDEpCgkJCQliaXRfZGJnKDIsICZpMmNfYWRhcC0+ZGV2LCAid3JvdGUgJWQgYnl0ZSVzXG4iLAoJCQkJCXJldCwgcmV0ID09IDEgPyAiIiA6ICJzIik7CgkJCWlmIChyZXQgPCBwbXNnLT5sZW4pIHsKCQkJCWlmIChyZXQgPj0gMCkKCQkJCQlyZXQgPSAtRVJFTU9URUlPOwoJCQkJZ290byBiYWlsb3V0OwoJCQl9CgkJfQoJfQoJcmV0ID0gaTsKCmJhaWxvdXQ6CgliaXRfZGJnKDMsICZpMmNfYWRhcC0+ZGV2LCAiZW1pdHRpbmcgc3RvcCBjb25kaXRpb25cbiIpOwoJaTJjX3N0b3AoYWRhcCk7CglyZXR1cm4gcmV0Owp9CgpzdGF0aWMgdTMyIGJpdF9mdW5jKHN0cnVjdCBpMmNfYWRhcHRlciAqYWRhcCkKewoJcmV0dXJuIEkyQ19GVU5DX0kyQyB8IEkyQ19GVU5DX1NNQlVTX0VNVUwgfCAKCSAgICAgICBJMkNfRlVOQ19TTUJVU19SRUFEX0JMT0NLX0RBVEEgfAoJICAgICAgIEkyQ19GVU5DX1NNQlVTX0JMT0NLX1BST0NfQ0FMTCB8CgkgICAgICAgSTJDX0ZVTkNfMTBCSVRfQUREUiB8IEkyQ19GVU5DX1BST1RPQ09MX01BTkdMSU5HOwp9CgoKLyogLS0tLS1leHBvcnRlZCBhbGdvcml0aG0gZGF0YTogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQkqLwoKc3RhdGljIGNvbnN0IHN0cnVjdCBpMmNfYWxnb3JpdGhtIGkyY19iaXRfYWxnbyA9IHsKCS5tYXN0ZXJfeGZlcgk9IGJpdF94ZmVyLAoJLmZ1bmN0aW9uYWxpdHkJPSBiaXRfZnVuYywKfTsKCi8qIAogKiByZWdpc3RlcmluZyBmdW5jdGlvbnMgdG8gbG9hZCBhbGdvcml0aG1zIGF0IHJ1bnRpbWUgCiAqLwpzdGF0aWMgaW50IGkyY19iaXRfcHJlcGFyZV9idXMoc3RydWN0IGkyY19hZGFwdGVyICphZGFwKQp7CglzdHJ1Y3QgaTJjX2FsZ29fYml0X2RhdGEgKmJpdF9hZGFwID0gYWRhcC0+YWxnb19kYXRhOwoKCWlmIChiaXRfdGVzdCkgewoJCWludCByZXQgPSB0ZXN0X2J1cyhiaXRfYWRhcCwgYWRhcC0+bmFtZSk7CgkJaWYgKHJldDwwKQoJCQlyZXR1cm4gLUVOT0RFVjsKCX0KCgkvKiByZWdpc3RlciBuZXcgYWRhcHRlciB0byBpMmMgbW9kdWxlLi4uICovCglhZGFwLT5hbGdvID0gJmkyY19iaXRfYWxnbzsKCglhZGFwLT50aW1lb3V0ID0gMTAwOwkvKiBkZWZhdWx0IHZhbHVlcywgc2hvdWxkCSovCglhZGFwLT5yZXRyaWVzID0gMzsJLyogYmUgcmVwbGFjZWQgYnkgZGVmaW5lcwkqLwoKCXJldHVybiAwOwp9CgppbnQgaTJjX2JpdF9hZGRfYnVzKHN0cnVjdCBpMmNfYWRhcHRlciAqYWRhcCkKewoJaW50IGVycjsKCgllcnIgPSBpMmNfYml0X3ByZXBhcmVfYnVzKGFkYXApOwoJaWYgKGVycikKCQlyZXR1cm4gZXJyOwoKCXJldHVybiBpMmNfYWRkX2FkYXB0ZXIoYWRhcCk7Cn0KRVhQT1JUX1NZTUJPTChpMmNfYml0X2FkZF9idXMpOwoKaW50IGkyY19iaXRfYWRkX251bWJlcmVkX2J1cyhzdHJ1Y3QgaTJjX2FkYXB0ZXIgKmFkYXApCnsKCWludCBlcnI7CgoJZXJyID0gaTJjX2JpdF9wcmVwYXJlX2J1cyhhZGFwKTsKCWlmIChlcnIpCgkJcmV0dXJuIGVycjsKCglyZXR1cm4gaTJjX2FkZF9udW1iZXJlZF9hZGFwdGVyKGFkYXApOwp9CkVYUE9SVF9TWU1CT0woaTJjX2JpdF9hZGRfbnVtYmVyZWRfYnVzKTsKCk1PRFVMRV9BVVRIT1IoIlNpbW9uIEcuIFZvZ2wgPHNpbW9uQHRrLnVuaS1saW56LmFjLmF0PiIpOwpNT0RVTEVfREVTQ1JJUFRJT04oIkkyQy1CdXMgYml0LWJhbmdpbmcgYWxnb3JpdGhtIik7Ck1PRFVMRV9MSUNFTlNFKCJHUEwiKTsK