LyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLwovKiBpMmMtYWxnby1iaXQuYyBpMmMgZHJpdmVyIGFsZ29yaXRobXMgZm9yIGJpdC1zaGlmdCBhZGFwdGVycwkJICAgICAqLwovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCi8qICAgQ29weXJpZ2h0IChDKSAxOTk1LTIwMDAgU2ltb24gRy4gVm9nbAoKICAgIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5CiAgICBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieQogICAgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyIHZlcnNpb24gMiBvZiB0aGUgTGljZW5zZSwgb3IKICAgIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCgogICAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsCiAgICBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogICAgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZQogICAgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KCiAgICBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogICAgYWxvbmcgd2l0aCB0aGlzIHByb2dyYW07IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICAgIEZvdW5kYXRpb24sIEluYy4sIDY3NSBNYXNzIEF2ZSwgQ2FtYnJpZGdlLCBNQSAwMjEzOSwgVVNBLgkJICAgICAqLwovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgovKiBXaXRoIHNvbWUgY2hhbmdlcyBmcm9tIEZyb2RvIExvb2lqYWFyZCA8ZnJvZG9sQGRkcy5ubD4sIEt59nN0aSBN5Gxra2kKICAgPGttYWxra2lAY2MuaHV0LmZpPiBhbmQgSmVhbiBEZWx2YXJlIDxraGFsaUBsaW51eC1mci5vcmc+ICovCgojaW5jbHVkZSA8bGludXgva2VybmVsLmg+CiNpbmNsdWRlIDxsaW51eC9tb2R1bGUuaD4KI2luY2x1ZGUgPGxpbnV4L2RlbGF5Lmg+CiNpbmNsdWRlIDxsaW51eC9zbGFiLmg+CiNpbmNsdWRlIDxsaW51eC9pbml0Lmg+CiNpbmNsdWRlIDxsaW51eC9lcnJuby5oPgojaW5jbHVkZSA8bGludXgvc2NoZWQuaD4KI2luY2x1ZGUgPGxpbnV4L2kyYy5oPgojaW5jbHVkZSA8bGludXgvaTJjLWFsZ28tYml0Lmg+CgoKLyogLS0tLS0gZ2xvYmFsIGRlZmluZXMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KCiNpZmRlZiBERUJVRwojZGVmaW5lIGJpdF9kYmcobGV2ZWwsIGRldiwgZm9ybWF0LCBhcmdzLi4uKSBcCglkbyB7IFwKCQlpZiAoaTJjX2RlYnVnID49IGxldmVsKSBcCgkJCWRldl9kYmcoZGV2LCBmb3JtYXQsICMjYXJncyk7IFwKCX0gd2hpbGUgKDApCiNlbHNlCiNkZWZpbmUgYml0X2RiZyhsZXZlbCwgZGV2LCBmb3JtYXQsIGFyZ3MuLi4pIFwKCWRvIHt9IHdoaWxlICgwKQojZW5kaWYgLyogREVCVUcgKi8KCi8qIC0tLS0tIGdsb2JhbCB2YXJpYWJsZXMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCSovCgpzdGF0aWMgaW50IGJpdF90ZXN0OwkvKiBzZWUgaWYgdGhlIGxpbmUtc2V0dGluZyBmdW5jdGlvbnMgd29yawkqLwptb2R1bGVfcGFyYW0oYml0X3Rlc3QsIGJvb2wsIDApOwpNT0RVTEVfUEFSTV9ERVNDKGJpdF90ZXN0LCAiVGVzdCB0aGUgbGluZXMgb2YgdGhlIGJ1cyB0byBzZWUgaWYgaXQgaXMgc3R1Y2siKTsKCiNpZmRlZiBERUJVRwpzdGF0aWMgaW50IGkyY19kZWJ1ZyA9IDE7Cm1vZHVsZV9wYXJhbShpMmNfZGVidWcsIGludCwgU19JUlVHTyB8IFNfSVdVU1IpOwpNT0RVTEVfUEFSTV9ERVNDKGkyY19kZWJ1ZywKCQkgImRlYnVnIGxldmVsIC0gMCBvZmY7IDEgbm9ybWFsOyAyIHZlcmJvc2U7IDMgdmVyeSB2ZXJib3NlIik7CiNlbmRpZgoKLyogLS0tIHNldHRpbmcgc3RhdGVzIG9uIHRoZSBidXMgd2l0aCB0aGUgcmlnaHQgdGltaW5nOiAtLS0tLS0tLS0tLS0tLS0JKi8KCiNkZWZpbmUgc2V0c2RhKGFkYXAsdmFsKSBhZGFwLT5zZXRzZGEoYWRhcC0+ZGF0YSwgdmFsKQojZGVmaW5lIHNldHNjbChhZGFwLHZhbCkgYWRhcC0+c2V0c2NsKGFkYXAtPmRhdGEsIHZhbCkKI2RlZmluZSBnZXRzZGEoYWRhcCkgYWRhcC0+Z2V0c2RhKGFkYXAtPmRhdGEpCiNkZWZpbmUgZ2V0c2NsKGFkYXApIGFkYXAtPmdldHNjbChhZGFwLT5kYXRhKQoKc3RhdGljIGlubGluZSB2b2lkIHNkYWxvKHN0cnVjdCBpMmNfYWxnb19iaXRfZGF0YSAqYWRhcCkKewoJc2V0c2RhKGFkYXAsMCk7Cgl1ZGVsYXkoKGFkYXAtPnVkZWxheSArIDEpIC8gMik7Cn0KCnN0YXRpYyBpbmxpbmUgdm9pZCBzZGFoaShzdHJ1Y3QgaTJjX2FsZ29fYml0X2RhdGEgKmFkYXApCnsKCXNldHNkYShhZGFwLDEpOwoJdWRlbGF5KChhZGFwLT51ZGVsYXkgKyAxKSAvIDIpOwp9CgpzdGF0aWMgaW5saW5lIHZvaWQgc2NsbG8oc3RydWN0IGkyY19hbGdvX2JpdF9kYXRhICphZGFwKQp7CglzZXRzY2woYWRhcCwwKTsKCXVkZWxheShhZGFwLT51ZGVsYXkgLyAyKTsKfQoKLyoKICogUmFpc2Ugc2NsIGxpbmUsIGFuZCBkbyBjaGVja2luZyBmb3IgZGVsYXlzLiBUaGlzIGlzIG5lY2Vzc2FyeSBmb3Igc2xvd2VyCiAqIGRldmljZXMuCiAqLwpzdGF0aWMgaW50IHNjbGhpKHN0cnVjdCBpMmNfYWxnb19iaXRfZGF0YSAqYWRhcCkKewoJdW5zaWduZWQgbG9uZyBzdGFydDsKCglzZXRzY2woYWRhcCwxKTsKCgkvKiBOb3QgYWxsIGFkYXB0ZXJzIGhhdmUgc2NsIHNlbnNlIGxpbmUuLi4gKi8KCWlmICghYWRhcC0+Z2V0c2NsKQoJCWdvdG8gZG9uZTsKCglzdGFydD1qaWZmaWVzOwoJd2hpbGUgKCEgZ2V0c2NsKGFkYXApICkgewkKIAkJLyogdGhlIGh3IGtub3dzIGhvdyB0byByZWFkIHRoZSBjbG9jayBsaW5lLAogCQkgKiBzbyB3ZSB3YWl0IHVudGlsIGl0IGFjdHVhbGx5IGdldHMgaGlnaC4KIAkJICogVGhpcyBpcyBzYWZlciBhcyBzb21lIGNoaXBzIG1heSBob2xkIGl0IGxvdwogCQkgKiB3aGlsZSB0aGV5IGFyZSBwcm9jZXNzaW5nIGRhdGEgaW50ZXJuYWxseS4gCiAJCSAqLwoJCWlmICh0aW1lX2FmdGVyX2VxKGppZmZpZXMsIHN0YXJ0K2FkYXAtPnRpbWVvdXQpKSB7CgkJCXJldHVybiAtRVRJTUVET1VUOwoJCX0KCQljb25kX3Jlc2NoZWQoKTsKCX0KI2lmZGVmIERFQlVHCglpZiAoamlmZmllcyAhPSBzdGFydCAmJiBpMmNfZGVidWcgPj0gMykKCQlwcl9kZWJ1ZygiaTJjLWFsZ28tYml0OiBuZWVkZWQgJWxkIGppZmZpZXMgZm9yIFNDTCB0byBnbyAiCgkJCSAiaGlnaFxuIiwgamlmZmllcyAtIHN0YXJ0KTsKI2VuZGlmCgpkb25lOgoJdWRlbGF5KGFkYXAtPnVkZWxheSk7CglyZXR1cm4gMDsKfSAKCgovKiAtLS0gb3RoZXIgYXV4aWxpYXJ5IGZ1bmN0aW9ucyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQkqLwpzdGF0aWMgdm9pZCBpMmNfc3RhcnQoc3RydWN0IGkyY19hbGdvX2JpdF9kYXRhICphZGFwKSAKewoJLyogYXNzZXJ0OiBzY2wsIHNkYSBhcmUgaGlnaCAqLwoJc2V0c2RhKGFkYXAsIDApOwoJdWRlbGF5KGFkYXAtPnVkZWxheSk7CglzY2xsbyhhZGFwKTsKfQoKc3RhdGljIHZvaWQgaTJjX3JlcHN0YXJ0KHN0cnVjdCBpMmNfYWxnb19iaXRfZGF0YSAqYWRhcCkgCnsKCS8qIGFzc2VydDogc2NsIGlzIGxvdyAqLwoJc2RhaGkoYWRhcCk7CglzY2xoaShhZGFwKTsKCXNldHNkYShhZGFwLCAwKTsKCXVkZWxheShhZGFwLT51ZGVsYXkpOwoJc2NsbG8oYWRhcCk7Cn0KCgpzdGF0aWMgdm9pZCBpMmNfc3RvcChzdHJ1Y3QgaTJjX2FsZ29fYml0X2RhdGEgKmFkYXApIAp7CgkvKiBhc3NlcnQ6IHNjbCBpcyBsb3cgKi8KCXNkYWxvKGFkYXApOwoJc2NsaGkoYWRhcCk7IAoJc2V0c2RhKGFkYXAsIDEpOwoJdWRlbGF5KGFkYXAtPnVkZWxheSk7Cn0KCgoKLyogc2VuZCBhIGJ5dGUgd2l0aG91dCBzdGFydCBjb25kLiwgbG9vayBmb3IgYXJiaXRyYXRpb24sIAogICBjaGVjayBhY2tuLiBmcm9tIHNsYXZlICovCi8qIHJldHVybnM6CiAqIDEgaWYgdGhlIGRldmljZSBhY2tub3dsZWRnZWQKICogMCBpZiB0aGUgZGV2aWNlIGRpZCBub3QgYWNrCiAqIC1FVElNRURPVVQgaWYgYW4gZXJyb3Igb2NjdXJyZWQgKHdoaWxlIHJhaXNpbmcgdGhlIHNjbCBsaW5lKQogKi8Kc3RhdGljIGludCBpMmNfb3V0YihzdHJ1Y3QgaTJjX2FkYXB0ZXIgKmkyY19hZGFwLCB1bnNpZ25lZCBjaGFyIGMpCnsKCWludCBpOwoJaW50IHNiOwoJaW50IGFjazsKCXN0cnVjdCBpMmNfYWxnb19iaXRfZGF0YSAqYWRhcCA9IGkyY19hZGFwLT5hbGdvX2RhdGE7CgoJLyogYXNzZXJ0OiBzY2wgaXMgbG93ICovCglmb3IgKCBpPTcgOyBpPj0wIDsgaS0tICkgewoJCXNiID0gKGMgPj4gaSkgJiAxOwoJCXNldHNkYShhZGFwLHNiKTsKCQl1ZGVsYXkoKGFkYXAtPnVkZWxheSArIDEpIC8gMik7CgkJaWYgKHNjbGhpKGFkYXApPDApIHsgLyogdGltZWQgb3V0ICovCgkJCWJpdF9kYmcoMSwgJmkyY19hZGFwLT5kZXYsICJpMmNfb3V0YjogMHglMDJ4LCAiCgkJCQkidGltZW91dCBhdCBiaXQgIyVkXG4iLCAoaW50KWMsIGkpOwoJCQlyZXR1cm4gLUVUSU1FRE9VVDsKCQl9OwoJCS8qIGRvIGFyYml0cmF0aW9uIGhlcmU6IAoJCSAqIGlmICggc2IgJiYgISBnZXRzZGEoYWRhcCkgKSAtPiBvdWNoISBHZXQgb3V0IG9mIGhlcmUuCgkJICovCgkJc2NsbG8oYWRhcCk7Cgl9CglzZGFoaShhZGFwKTsKCWlmIChzY2xoaShhZGFwKTwwKXsgLyogdGltZW91dCAqLwoJCWJpdF9kYmcoMSwgJmkyY19hZGFwLT5kZXYsICJpMmNfb3V0YjogMHglMDJ4LCAiCgkJCSJ0aW1lb3V0IGF0IGFja1xuIiwgKGludCljKTsKCQlyZXR1cm4gLUVUSU1FRE9VVDsKCX07CgkvKiByZWFkIGFjazogU0RBIHNob3VsZCBiZSBwdWxsZWQgZG93biBieSBzbGF2ZSAqLwoJYWNrID0gIWdldHNkYShhZGFwKTsgICAgLyogYWNrOiBzZGEgaXMgcHVsbGVkIGxvdyAtPiBzdWNjZXNzICovCgliaXRfZGJnKDIsICZpMmNfYWRhcC0+ZGV2LCAiaTJjX291dGI6IDB4JTAyeCAlc1xuIiwgKGludCljLAoJCWFjayA/ICJBIiA6ICJOQSIpOwoKCXNjbGxvKGFkYXApOwoJcmV0dXJuIGFjazsKCS8qIGFzc2VydDogc2NsIGlzIGxvdyAoc2RhIHVuZGVmKSAqLwp9CgoKc3RhdGljIGludCBpMmNfaW5iKHN0cnVjdCBpMmNfYWRhcHRlciAqaTJjX2FkYXApIAp7CgkvKiByZWFkIGJ5dGUgdmlhIGkyYyBwb3J0LCB3aXRob3V0IHN0YXJ0L3N0b3Agc2VxdWVuY2UJKi8KCS8qIGFja25vd2xlZGdlIGlzIHNlbnQgaW4gaTJjX3JlYWQuCQkJKi8KCWludCBpOwoJdW5zaWduZWQgY2hhciBpbmRhdGE9MDsKCXN0cnVjdCBpMmNfYWxnb19iaXRfZGF0YSAqYWRhcCA9IGkyY19hZGFwLT5hbGdvX2RhdGE7CgoJLyogYXNzZXJ0OiBzY2wgaXMgbG93ICovCglzZGFoaShhZGFwKTsKCWZvciAoaT0wO2k8ODtpKyspIHsKCQlpZiAoc2NsaGkoYWRhcCk8MCkgeyAvKiB0aW1lb3V0ICovCgkJCWJpdF9kYmcoMSwgJmkyY19hZGFwLT5kZXYsICJpMmNfaW5iOiB0aW1lb3V0IGF0IGJpdCAiCgkJCQkiIyVkXG4iLCA3IC0gaSk7CgkJCXJldHVybiAtRVRJTUVET1VUOwoJCX07CgkJaW5kYXRhICo9IDI7CgkJaWYgKCBnZXRzZGEoYWRhcCkgKSAKCQkJaW5kYXRhIHw9IDB4MDE7CgkJc2V0c2NsKGFkYXAsIDApOwoJCXVkZWxheShpID09IDcgPyBhZGFwLT51ZGVsYXkgLyAyIDogYWRhcC0+dWRlbGF5KTsKCX0KCS8qIGFzc2VydDogc2NsIGlzIGxvdyAqLwoJcmV0dXJuIGluZGF0YTsKfQoKLyoKICogU2FuaXR5IGNoZWNrIGZvciB0aGUgYWRhcHRlciBoYXJkd2FyZSAtIGNoZWNrIHRoZSByZWFjdGlvbiBvZgogKiB0aGUgYnVzIGxpbmVzIG9ubHkgaWYgaXQgc2VlbXMgdG8gYmUgaWRsZS4KICovCnN0YXRpYyBpbnQgdGVzdF9idXMoc3RydWN0IGkyY19hbGdvX2JpdF9kYXRhICphZGFwLCBjaGFyKiBuYW1lKSB7CglpbnQgc2NsLHNkYTsKCglpZiAoYWRhcC0+Z2V0c2NsPT1OVUxMKQoJCXByX2luZm8oIiVzOiBUZXN0aW5nIFNEQSBvbmx5LCBTQ0wgaXMgbm90IHJlYWRhYmxlXG4iLCBuYW1lKTsKCglzZGE9Z2V0c2RhKGFkYXApOwoJc2NsPShhZGFwLT5nZXRzY2w9PU5VTEw/MTpnZXRzY2woYWRhcCkpOwoJaWYgKCFzY2wgfHwgIXNkYSApIHsKCQlwcmludGsoS0VSTl9XQVJOSU5HICIlczogYnVzIHNlZW1zIHRvIGJlIGJ1c3lcbiIsIG5hbWUpOwoJCWdvdG8gYmFpbG91dDsKCX0KCglzZGFsbyhhZGFwKTsKCXNkYT1nZXRzZGEoYWRhcCk7CglzY2w9KGFkYXAtPmdldHNjbD09TlVMTD8xOmdldHNjbChhZGFwKSk7CglpZiAoIDAgIT0gc2RhICkgewoJCXByaW50ayhLRVJOX1dBUk5JTkcgIiVzOiBTREEgc3R1Y2sgaGlnaCFcbiIsIG5hbWUpOwoJCWdvdG8gYmFpbG91dDsKCX0KCWlmICggMCA9PSBzY2wgKSB7CgkJcHJpbnRrKEtFUk5fV0FSTklORyAiJXM6IFNDTCB1bmV4cGVjdGVkIGxvdyAiCgkJICAgICAgICJ3aGlsZSBwdWxsaW5nIFNEQSBsb3chXG4iLCBuYW1lKTsKCQlnb3RvIGJhaWxvdXQ7Cgl9CQkKCglzZGFoaShhZGFwKTsKCXNkYT1nZXRzZGEoYWRhcCk7CglzY2w9KGFkYXAtPmdldHNjbD09TlVMTD8xOmdldHNjbChhZGFwKSk7CglpZiAoIDAgPT0gc2RhICkgewoJCXByaW50ayhLRVJOX1dBUk5JTkcgIiVzOiBTREEgc3R1Y2sgbG93IVxuIiwgbmFtZSk7CgkJZ290byBiYWlsb3V0OwoJfQoJaWYgKCAwID09IHNjbCApIHsKCQlwcmludGsoS0VSTl9XQVJOSU5HICIlczogU0NMIHVuZXhwZWN0ZWQgbG93ICIKCQkgICAgICAgIndoaWxlIHB1bGxpbmcgU0RBIGhpZ2ghXG4iLCBuYW1lKTsKCQlnb3RvIGJhaWxvdXQ7Cgl9CgoJc2NsbG8oYWRhcCk7CglzZGE9Z2V0c2RhKGFkYXApOwoJc2NsPShhZGFwLT5nZXRzY2w9PU5VTEw/MDpnZXRzY2woYWRhcCkpOwoJaWYgKCAwICE9IHNjbCApIHsKCQlwcmludGsoS0VSTl9XQVJOSU5HICIlczogU0NMIHN0dWNrIGhpZ2ghXG4iLCBuYW1lKTsKCQlnb3RvIGJhaWxvdXQ7Cgl9CglpZiAoIDAgPT0gc2RhICkgewoJCXByaW50ayhLRVJOX1dBUk5JTkcgIiVzOiBTREEgdW5leHBlY3RlZCBsb3cgIgoJCSAgICAgICAid2hpbGUgcHVsbGluZyBTQ0wgbG93IVxuIiwgbmFtZSk7CgkJZ290byBiYWlsb3V0OwoJfQoJCglzY2xoaShhZGFwKTsKCXNkYT1nZXRzZGEoYWRhcCk7CglzY2w9KGFkYXAtPmdldHNjbD09TlVMTD8xOmdldHNjbChhZGFwKSk7CglpZiAoIDAgPT0gc2NsICkgewoJCXByaW50ayhLRVJOX1dBUk5JTkcgIiVzOiBTQ0wgc3R1Y2sgbG93IVxuIiwgbmFtZSk7CgkJZ290byBiYWlsb3V0OwoJfQoJaWYgKCAwID09IHNkYSApIHsKCQlwcmludGsoS0VSTl9XQVJOSU5HICIlczogU0RBIHVuZXhwZWN0ZWQgbG93ICIKCQkgICAgICAgIndoaWxlIHB1bGxpbmcgU0NMIGhpZ2ghXG4iLCBuYW1lKTsKCQlnb3RvIGJhaWxvdXQ7Cgl9Cglwcl9pbmZvKCIlczogVGVzdCBPS1xuIiwgbmFtZSk7CglyZXR1cm4gMDsKYmFpbG91dDoKCXNkYWhpKGFkYXApOwoJc2NsaGkoYWRhcCk7CglyZXR1cm4gLUVOT0RFVjsKfQoKLyogLS0tLS0gVXRpbGl0eSBmdW5jdGlvbnMKICovCgovKiB0cnlfYWRkcmVzcyB0cmllcyB0byBjb250YWN0IGEgY2hpcCBmb3IgYSBudW1iZXIgb2YKICogdGltZXMgYmVmb3JlIGl0IGdpdmVzIHVwLgogKiByZXR1cm4gdmFsdWVzOgogKiAxIGNoaXAgYW5zd2VyZWQKICogMCBjaGlwIGRpZCBub3QgYW5zd2VyCiAqIC14IHRyYW5zbWlzc2lvbiBlcnJvcgogKi8Kc3RhdGljIGludCB0cnlfYWRkcmVzcyhzdHJ1Y3QgaTJjX2FkYXB0ZXIgKmkyY19hZGFwLAoJCSAgICAgICB1bnNpZ25lZCBjaGFyIGFkZHIsIGludCByZXRyaWVzKQp7CglzdHJ1Y3QgaTJjX2FsZ29fYml0X2RhdGEgKmFkYXAgPSBpMmNfYWRhcC0+YWxnb19kYXRhOwoJaW50IGkscmV0ID0gLTE7Cglmb3IgKGk9MDtpPD1yZXRyaWVzO2krKykgewoJCXJldCA9IGkyY19vdXRiKGkyY19hZGFwLGFkZHIpOwoJCWlmIChyZXQgPT0gMSB8fCBpID09IHJldHJpZXMpCgkJCWJyZWFrOwoJCWJpdF9kYmcoMywgJmkyY19hZGFwLT5kZXYsICJlbWl0dGluZyBzdG9wIGNvbmRpdGlvblxuIik7CgkJaTJjX3N0b3AoYWRhcCk7CgkJdWRlbGF5KGFkYXAtPnVkZWxheSk7CgkJeWllbGQoKTsKCQliaXRfZGJnKDMsICZpMmNfYWRhcC0+ZGV2LCAiZW1pdHRpbmcgc3RhcnQgY29uZGl0aW9uXG4iKTsKCQlpMmNfc3RhcnQoYWRhcCk7Cgl9CglpZiAoaSAmJiByZXQpCgkJYml0X2RiZygxLCAmaTJjX2FkYXAtPmRldiwgIlVzZWQgJWQgdHJpZXMgdG8gJXMgY2xpZW50IGF0ICIKCQkJIjB4JTAyeDogJXNcbiIsIGkgKyAxLAoJCQlhZGRyICYgMSA/ICJyZWFkIGZyb20iIDogIndyaXRlIHRvIiwgYWRkciA+PiAxLAoJCQlyZXQgPT0gMSA/ICJzdWNjZXNzIiA6ICJmYWlsZWQsIHRpbWVvdXQ/Iik7CglyZXR1cm4gcmV0Owp9CgpzdGF0aWMgaW50IHNlbmRieXRlcyhzdHJ1Y3QgaTJjX2FkYXB0ZXIgKmkyY19hZGFwLCBzdHJ1Y3QgaTJjX21zZyAqbXNnKQp7Cgljb25zdCB1bnNpZ25lZCBjaGFyICp0ZW1wID0gbXNnLT5idWY7CglpbnQgY291bnQgPSBtc2ctPmxlbjsKCXVuc2lnbmVkIHNob3J0IG5ha19vayA9IG1zZy0+ZmxhZ3MgJiBJMkNfTV9JR05PUkVfTkFLOyAKCWludCByZXR2YWw7CglpbnQgd3Jjb3VudD0wOwoKCXdoaWxlIChjb3VudCA+IDApIHsKCQlyZXR2YWwgPSBpMmNfb3V0YihpMmNfYWRhcCwgKnRlbXApOwoJCWlmICgocmV0dmFsPjApIHx8IChuYWtfb2sgJiYgKHJldHZhbD09MCkpKSAgeyAvKiBvayBvciBpZ25vcmVkIE5BSyAqLwoJCQljb3VudC0tOyAKCQkJdGVtcCsrOwoJCQl3cmNvdW50Kys7CgkJfSBlbHNlIHsgLyogYXJiaXRyYXRpb24gb3Igbm8gYWNrbm93bGVkZ2UgKi8KCQkJZGV2X2VycigmaTJjX2FkYXAtPmRldiwgInNlbmRieXRlczogZXJyb3IgLSBiYWlsb3V0LlxuIik7CgkJCXJldHVybiAocmV0dmFsPDApPyByZXR2YWwgOiAtRUZBVUxUOwoJCQkgICAgICAgIC8qIGdvdCBhIGJldHRlciBvbmUgPz8gKi8KCQl9Cgl9CglyZXR1cm4gd3Jjb3VudDsKfQoKc3RhdGljIGludCBhY2tuYWsoc3RydWN0IGkyY19hZGFwdGVyICppMmNfYWRhcCwgaW50IGlzX2FjaykKewoJc3RydWN0IGkyY19hbGdvX2JpdF9kYXRhICphZGFwID0gaTJjX2FkYXAtPmFsZ29fZGF0YTsKCgkvKiBhc3NlcnQ6IHNkYSBpcyBoaWdoICovCglpZiAoaXNfYWNrKQkJLyogc2VuZCBhY2sgKi8KCQlzZXRzZGEoYWRhcCwgMCk7Cgl1ZGVsYXkoKGFkYXAtPnVkZWxheSArIDEpIC8gMik7CglpZiAoc2NsaGkoYWRhcCkgPCAwKSB7CS8qIHRpbWVvdXQgKi8KCQlkZXZfZXJyKCZpMmNfYWRhcC0+ZGV2LCAicmVhZGJ5dGVzOiBhY2svbmFrIHRpbWVvdXRcbiIpOwoJCXJldHVybiAtRVRJTUVET1VUOwoJfQoJc2NsbG8oYWRhcCk7CglyZXR1cm4gMDsKfQoKc3RhdGljIGludCByZWFkYnl0ZXMoc3RydWN0IGkyY19hZGFwdGVyICppMmNfYWRhcCwgc3RydWN0IGkyY19tc2cgKm1zZykKewoJaW50IGludmFsOwoJaW50IHJkY291bnQ9MDsgICAJLyogY291bnRzIGJ5dGVzIHJlYWQgKi8KCXVuc2lnbmVkIGNoYXIgKnRlbXAgPSBtc2ctPmJ1ZjsKCWludCBjb3VudCA9IG1zZy0+bGVuOwoJY29uc3QgdW5zaWduZWQgZmxhZ3MgPSBtc2ctPmZsYWdzOwoKCXdoaWxlIChjb3VudCA+IDApIHsKCQlpbnZhbCA9IGkyY19pbmIoaTJjX2FkYXApOwoJCWlmIChpbnZhbD49MCkgewoJCQkqdGVtcCA9IGludmFsOwoJCQlyZGNvdW50Kys7CgkJfSBlbHNlIHsgICAvKiByZWFkIHRpbWVkIG91dCAqLwoJCQlicmVhazsKCQl9CgoJCXRlbXArKzsKCQljb3VudC0tOwoKCQkvKiBTb21lIFNNQnVzIHRyYW5zYWN0aW9ucyByZXF1aXJlIHRoYXQgd2UgcmVjZWl2ZSB0aGUKCQkgICB0cmFuc2FjdGlvbiBsZW5ndGggYXMgdGhlIGZpcnN0IHJlYWQgYnl0ZS4gKi8KCQlpZiAocmRjb3VudCA9PSAxICYmIChmbGFncyAmIEkyQ19NX1JFQ1ZfTEVOKSkgewoJCQlpZiAoaW52YWwgPD0gMCB8fCBpbnZhbCA+IEkyQ19TTUJVU19CTE9DS19NQVgpIHsKCQkJCWlmICghKGZsYWdzICYgSTJDX01fTk9fUkRfQUNLKSkKCQkJCQlhY2tuYWsoaTJjX2FkYXAsIDApOwoJCQkJZGV2X2VycigmaTJjX2FkYXAtPmRldiwgInJlYWRieXRlczogaW52YWxpZCAiCgkJCQkJImJsb2NrIGxlbmd0aCAoJWQpXG4iLCBpbnZhbCk7CgkJCQlyZXR1cm4gLUVSRU1PVEVJTzsKCQkJfQoJCQkvKiBUaGUgb3JpZ2luYWwgY291bnQgdmFsdWUgYWNjb3VudHMgZm9yIHRoZSBleHRyYQoJCQkgICBieXRlcywgdGhhdCBpcywgZWl0aGVyIDEgZm9yIGEgcmVndWxhciB0cmFuc2FjdGlvbiwKCQkJICAgb3IgMiBmb3IgYSBQRUMgdHJhbnNhY3Rpb24uICovCgkJCWNvdW50ICs9IGludmFsOwoJCQltc2ctPmxlbiArPSBpbnZhbDsKCQl9CgoJCWJpdF9kYmcoMiwgJmkyY19hZGFwLT5kZXYsICJyZWFkYnl0ZXM6IDB4JTAyeCAlc1xuIiwKCQkJaW52YWwsCgkJCShmbGFncyAmIEkyQ19NX05PX1JEX0FDSykKCQkJCT8gIihubyBhY2svbmFrKSIKCQkJCTogKGNvdW50ID8gIkEiIDogIk5BIikpOwoKCQlpZiAoIShmbGFncyAmIEkyQ19NX05PX1JEX0FDSykpIHsKCQkJaW52YWwgPSBhY2tuYWsoaTJjX2FkYXAsIGNvdW50KTsKCQkJaWYgKGludmFsIDwgMCkKCQkJCXJldHVybiBpbnZhbDsKCQl9Cgl9CglyZXR1cm4gcmRjb3VudDsKfQoKLyogZG9BZGRyZXNzIGluaXRpYXRlcyB0aGUgdHJhbnNmZXIgYnkgZ2VuZXJhdGluZyB0aGUgc3RhcnQgY29uZGl0aW9uIChpbgogKiB0cnlfYWRkcmVzcykgYW5kIHRyYW5zbWl0cyB0aGUgYWRkcmVzcyBpbiB0aGUgbmVjZXNzYXJ5IGZvcm1hdCB0byBoYW5kbGUKICogcmVhZHMsIHdyaXRlcyBhcyB3ZWxsIGFzIDEwYml0LWFkZHJlc3Nlcy4KICogcmV0dXJuczoKICogIDAgZXZlcnl0aGluZyB3ZW50IG9rYXksIHRoZSBjaGlwIGFjaydlZCwgb3IgSUdOT1JFX05BSyBmbGFnIHdhcyBzZXQKICogLXggYW4gZXJyb3Igb2NjdXJyZWQgKGxpa2U6IC1FUkVNT1RFSU8gaWYgdGhlIGRldmljZSBkaWQgbm90IGFuc3dlciwgb3IKICoJLUVUSU1FRE9VVCwgZm9yIGV4YW1wbGUgaWYgdGhlIGxpbmVzIGFyZSBzdHVjay4uLikgCiAqLwpzdGF0aWMgaW50IGJpdF9kb0FkZHJlc3Moc3RydWN0IGkyY19hZGFwdGVyICppMmNfYWRhcCwgc3RydWN0IGkyY19tc2cgKm1zZykKewoJdW5zaWduZWQgc2hvcnQgZmxhZ3MgPSBtc2ctPmZsYWdzOwoJdW5zaWduZWQgc2hvcnQgbmFrX29rID0gbXNnLT5mbGFncyAmIEkyQ19NX0lHTk9SRV9OQUs7CglzdHJ1Y3QgaTJjX2FsZ29fYml0X2RhdGEgKmFkYXAgPSBpMmNfYWRhcC0+YWxnb19kYXRhOwoKCXVuc2lnbmVkIGNoYXIgYWRkcjsKCWludCByZXQsIHJldHJpZXM7CgoJcmV0cmllcyA9IG5ha19vayA/IDAgOiBpMmNfYWRhcC0+cmV0cmllczsKCQoJaWYgKCAoZmxhZ3MgJiBJMkNfTV9URU4pICApIHsgCgkJLyogYSB0ZW4gYml0IGFkZHJlc3MgKi8KCQlhZGRyID0gMHhmMCB8ICgoIG1zZy0+YWRkciA+PiA3KSAmIDB4MDMpOwoJCWJpdF9kYmcoMiwgJmkyY19hZGFwLT5kZXYsICJhZGRyMDogJWRcbiIsIGFkZHIpOwoJCS8qIHRyeSBleHRlbmRlZCBhZGRyZXNzIGNvZGUuLi4qLwoJCXJldCA9IHRyeV9hZGRyZXNzKGkyY19hZGFwLCBhZGRyLCByZXRyaWVzKTsKCQlpZiAoKHJldCAhPSAxKSAmJiAhbmFrX29rKSAgewoJCQlkZXZfZXJyKCZpMmNfYWRhcC0+ZGV2LAoJCQkJImRpZWQgYXQgZXh0ZW5kZWQgYWRkcmVzcyBjb2RlXG4iKTsKCQkJcmV0dXJuIC1FUkVNT1RFSU87CgkJfQoJCS8qIHRoZSByZW1haW5pbmcgOCBiaXQgYWRkcmVzcyAqLwoJCXJldCA9IGkyY19vdXRiKGkyY19hZGFwLG1zZy0+YWRkciAmIDB4N2YpOwoJCWlmICgocmV0ICE9IDEpICYmICFuYWtfb2spIHsKCQkJLyogdGhlIGNoaXAgZGlkIG5vdCBhY2sgLyB4bWlzc2lvbiBlcnJvciBvY2N1cnJlZCAqLwoJCQlkZXZfZXJyKCZpMmNfYWRhcC0+ZGV2LCAiZGllZCBhdCAybmQgYWRkcmVzcyBjb2RlXG4iKTsKCQkJcmV0dXJuIC1FUkVNT1RFSU87CgkJfQoJCWlmICggZmxhZ3MgJiBJMkNfTV9SRCApIHsKCQkJYml0X2RiZygzLCAmaTJjX2FkYXAtPmRldiwgImVtaXR0aW5nIHJlcGVhdGVkICIKCQkJCSJzdGFydCBjb25kaXRpb25cbiIpOwoJCQlpMmNfcmVwc3RhcnQoYWRhcCk7CgkJCS8qIG9rYXksIG5vdyBzd2l0Y2ggaW50byByZWFkaW5nIG1vZGUgKi8KCQkJYWRkciB8PSAweDAxOwoJCQlyZXQgPSB0cnlfYWRkcmVzcyhpMmNfYWRhcCwgYWRkciwgcmV0cmllcyk7CgkJCWlmICgocmV0IT0xKSAmJiAhbmFrX29rKSB7CgkJCQlkZXZfZXJyKCZpMmNfYWRhcC0+ZGV2LAoJCQkJCSJkaWVkIGF0IHJlcGVhdGVkIGFkZHJlc3MgY29kZVxuIik7CgkJCQlyZXR1cm4gLUVSRU1PVEVJTzsKCQkJfQoJCX0KCX0gZWxzZSB7CQkvKiBub3JtYWwgN2JpdCBhZGRyZXNzCSovCgkJYWRkciA9ICggbXNnLT5hZGRyIDw8IDEgKTsKCQlpZiAoZmxhZ3MgJiBJMkNfTV9SRCApCgkJCWFkZHIgfD0gMTsKCQlpZiAoZmxhZ3MgJiBJMkNfTV9SRVZfRElSX0FERFIgKQoJCQlhZGRyIF49IDE7CgkJcmV0ID0gdHJ5X2FkZHJlc3MoaTJjX2FkYXAsIGFkZHIsIHJldHJpZXMpOwoJCWlmICgocmV0IT0xKSAmJiAhbmFrX29rKQoJCQlyZXR1cm4gLUVSRU1PVEVJTzsKCX0KCglyZXR1cm4gMDsKfQoKc3RhdGljIGludCBiaXRfeGZlcihzdHJ1Y3QgaTJjX2FkYXB0ZXIgKmkyY19hZGFwLAoJCSAgICBzdHJ1Y3QgaTJjX21zZyBtc2dzW10sIGludCBudW0pCnsKCXN0cnVjdCBpMmNfbXNnICpwbXNnOwoJc3RydWN0IGkyY19hbGdvX2JpdF9kYXRhICphZGFwID0gaTJjX2FkYXAtPmFsZ29fZGF0YTsKCQoJaW50IGkscmV0OwoJdW5zaWduZWQgc2hvcnQgbmFrX29rOwoKCWJpdF9kYmcoMywgJmkyY19hZGFwLT5kZXYsICJlbWl0dGluZyBzdGFydCBjb25kaXRpb25cbiIpOwoJaTJjX3N0YXJ0KGFkYXApOwoJZm9yIChpPTA7aTxudW07aSsrKSB7CgkJcG1zZyA9ICZtc2dzW2ldOwoJCW5ha19vayA9IHBtc2ctPmZsYWdzICYgSTJDX01fSUdOT1JFX05BSzsgCgkJaWYgKCEocG1zZy0+ZmxhZ3MgJiBJMkNfTV9OT1NUQVJUKSkgewoJCQlpZiAoaSkgewoJCQkJYml0X2RiZygzLCAmaTJjX2FkYXAtPmRldiwgImVtaXR0aW5nICIKCQkJCQkicmVwZWF0ZWQgc3RhcnQgY29uZGl0aW9uXG4iKTsKCQkJCWkyY19yZXBzdGFydChhZGFwKTsKCQkJfQoJCQlyZXQgPSBiaXRfZG9BZGRyZXNzKGkyY19hZGFwLCBwbXNnKTsKCQkJaWYgKChyZXQgIT0gMCkgJiYgIW5ha19vaykgewoJCQkJYml0X2RiZygxLCAmaTJjX2FkYXAtPmRldiwgIk5BSyBmcm9tICIKCQkJCQkiZGV2aWNlIGFkZHIgMHglMDJ4IG1zZyAjJWRcbiIsCgkJCQkJbXNnc1tpXS5hZGRyLCBpKTsKCQkJCWdvdG8gYmFpbG91dDsKCQkJfQoJCX0KCQlpZiAocG1zZy0+ZmxhZ3MgJiBJMkNfTV9SRCApIHsKCQkJLyogcmVhZCBieXRlcyBpbnRvIGJ1ZmZlciovCgkJCXJldCA9IHJlYWRieXRlcyhpMmNfYWRhcCwgcG1zZyk7CgkJCWlmIChyZXQgPj0gMSkKCQkJCWJpdF9kYmcoMiwgJmkyY19hZGFwLT5kZXYsICJyZWFkICVkIGJ5dGUlc1xuIiwKCQkJCQlyZXQsIHJldCA9PSAxID8gIiIgOiAicyIpOwoJCQlpZiAocmV0IDwgcG1zZy0+bGVuKSB7CgkJCQlpZiAocmV0ID49IDApCgkJCQkJcmV0ID0gLUVSRU1PVEVJTzsKCQkJCWdvdG8gYmFpbG91dDsKCQkJfQoJCX0gZWxzZSB7CgkJCS8qIHdyaXRlIGJ5dGVzIGZyb20gYnVmZmVyICovCgkJCXJldCA9IHNlbmRieXRlcyhpMmNfYWRhcCwgcG1zZyk7CgkJCWlmIChyZXQgPj0gMSkKCQkJCWJpdF9kYmcoMiwgJmkyY19hZGFwLT5kZXYsICJ3cm90ZSAlZCBieXRlJXNcbiIsCgkJCQkJcmV0LCByZXQgPT0gMSA/ICIiIDogInMiKTsKCQkJaWYgKHJldCA8IHBtc2ctPmxlbikgewoJCQkJaWYgKHJldCA+PSAwKQoJCQkJCXJldCA9IC1FUkVNT1RFSU87CgkJCQlnb3RvIGJhaWxvdXQ7CgkJCX0KCQl9Cgl9CglyZXQgPSBpOwoKYmFpbG91dDoKCWJpdF9kYmcoMywgJmkyY19hZGFwLT5kZXYsICJlbWl0dGluZyBzdG9wIGNvbmRpdGlvblxuIik7CglpMmNfc3RvcChhZGFwKTsKCXJldHVybiByZXQ7Cn0KCnN0YXRpYyB1MzIgYml0X2Z1bmMoc3RydWN0IGkyY19hZGFwdGVyICphZGFwKQp7CglyZXR1cm4gSTJDX0ZVTkNfSTJDIHwgSTJDX0ZVTkNfU01CVVNfRU1VTCB8IAoJICAgICAgIEkyQ19GVU5DX1NNQlVTX1JFQURfQkxPQ0tfREFUQSB8CgkgICAgICAgSTJDX0ZVTkNfU01CVVNfQkxPQ0tfUFJPQ19DQUxMIHwKCSAgICAgICBJMkNfRlVOQ18xMEJJVF9BRERSIHwgSTJDX0ZVTkNfUFJPVE9DT0xfTUFOR0xJTkc7Cn0KCgovKiAtLS0tLWV4cG9ydGVkIGFsZ29yaXRobSBkYXRhOiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCSovCgpzdGF0aWMgY29uc3Qgc3RydWN0IGkyY19hbGdvcml0aG0gaTJjX2JpdF9hbGdvID0gewoJLm1hc3Rlcl94ZmVyCT0gYml0X3hmZXIsCgkuZnVuY3Rpb25hbGl0eQk9IGJpdF9mdW5jLAp9OwoKLyogCiAqIHJlZ2lzdGVyaW5nIGZ1bmN0aW9ucyB0byBsb2FkIGFsZ29yaXRobXMgYXQgcnVudGltZSAKICovCnN0YXRpYyBpbnQgaTJjX2JpdF9wcmVwYXJlX2J1cyhzdHJ1Y3QgaTJjX2FkYXB0ZXIgKmFkYXApCnsKCXN0cnVjdCBpMmNfYWxnb19iaXRfZGF0YSAqYml0X2FkYXAgPSBhZGFwLT5hbGdvX2RhdGE7CgoJaWYgKGJpdF90ZXN0KSB7CgkJaW50IHJldCA9IHRlc3RfYnVzKGJpdF9hZGFwLCBhZGFwLT5uYW1lKTsKCQlpZiAocmV0PDApCgkJCXJldHVybiAtRU5PREVWOwoJfQoKCS8qIHJlZ2lzdGVyIG5ldyBhZGFwdGVyIHRvIGkyYyBtb2R1bGUuLi4gKi8KCWFkYXAtPmFsZ28gPSAmaTJjX2JpdF9hbGdvOwoKCWFkYXAtPnRpbWVvdXQgPSAxMDA7CS8qIGRlZmF1bHQgdmFsdWVzLCBzaG91bGQJKi8KCWFkYXAtPnJldHJpZXMgPSAzOwkvKiBiZSByZXBsYWNlZCBieSBkZWZpbmVzCSovCgoJcmV0dXJuIDA7Cn0KCmludCBpMmNfYml0X2FkZF9idXMoc3RydWN0IGkyY19hZGFwdGVyICphZGFwKQp7CglpbnQgZXJyOwoKCWVyciA9IGkyY19iaXRfcHJlcGFyZV9idXMoYWRhcCk7CglpZiAoZXJyKQoJCXJldHVybiBlcnI7CgoJcmV0dXJuIGkyY19hZGRfYWRhcHRlcihhZGFwKTsKfQpFWFBPUlRfU1lNQk9MKGkyY19iaXRfYWRkX2J1cyk7CgppbnQgaTJjX2JpdF9hZGRfbnVtYmVyZWRfYnVzKHN0cnVjdCBpMmNfYWRhcHRlciAqYWRhcCkKewoJaW50IGVycjsKCgllcnIgPSBpMmNfYml0X3ByZXBhcmVfYnVzKGFkYXApOwoJaWYgKGVycikKCQlyZXR1cm4gZXJyOwoKCXJldHVybiBpMmNfYWRkX251bWJlcmVkX2FkYXB0ZXIoYWRhcCk7Cn0KRVhQT1JUX1NZTUJPTChpMmNfYml0X2FkZF9udW1iZXJlZF9idXMpOwoKTU9EVUxFX0FVVEhPUigiU2ltb24gRy4gVm9nbCA8c2ltb25AdGsudW5pLWxpbnouYWMuYXQ+Iik7Ck1PRFVMRV9ERVNDUklQVElPTigiSTJDLUJ1cyBiaXQtYmFuZ2luZyBhbGdvcml0aG0iKTsKTU9EVUxFX0xJQ0VOU0UoIkdQTCIpOwo=