LyogaTJjLWNvcmUuYyAtIGEgZGV2aWNlIGRyaXZlciBmb3IgdGhlIGlpYy1idXMgaW50ZXJmYWNlCQkgICAgICovCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KLyogICBDb3B5cmlnaHQgKEMpIDE5OTUtOTkgU2ltb24gRy4gVm9nbAoKICAgIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5CiAgICBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieQogICAgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyIHZlcnNpb24gMiBvZiB0aGUgTGljZW5zZSwgb3IKICAgIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCgogICAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsCiAgICBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogICAgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZQogICAgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KCiAgICBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogICAgYWxvbmcgd2l0aCB0aGlzIHByb2dyYW07IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICAgIEZvdW5kYXRpb24sIEluYy4sIDY3NSBNYXNzIEF2ZSwgQ2FtYnJpZGdlLCBNQSAwMjEzOSwgVVNBLgkJICAgICAqLwovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgovKiBXaXRoIHNvbWUgY2hhbmdlcyBmcm9tIEt59nN0aSBN5Gxra2kgPGttYWxra2lAY2MuaHV0LmZpPi4KICAgQWxsIFNNQnVzLXJlbGF0ZWQgdGhpbmdzIGFyZSB3cml0dGVuIGJ5IEZyb2RvIExvb2lqYWFyZCA8ZnJvZG9sQGRkcy5ubD4KICAgU01CdXMgMi4wIHN1cHBvcnQgYnkgTWFyayBTdHVkZWJha2VyIDxtZHN4eXoxMjNAeWFob28uY29tPiAgICAgICAgICAgICAgICAqLwoKI2luY2x1ZGUgPGxpbnV4L21vZHVsZS5oPgojaW5jbHVkZSA8bGludXgva2VybmVsLmg+CiNpbmNsdWRlIDxsaW51eC9lcnJuby5oPgojaW5jbHVkZSA8bGludXgvc2xhYi5oPgojaW5jbHVkZSA8bGludXgvaTJjLmg+CiNpbmNsdWRlIDxsaW51eC9pbml0Lmg+CiNpbmNsdWRlIDxsaW51eC9pZHIuaD4KI2luY2x1ZGUgPGxpbnV4L3NlcV9maWxlLmg+CiNpbmNsdWRlIDxhc20vdWFjY2Vzcy5oPgoKCnN0YXRpYyBMSVNUX0hFQUQoYWRhcHRlcnMpOwpzdGF0aWMgTElTVF9IRUFEKGRyaXZlcnMpOwpzdGF0aWMgREVDTEFSRV9NVVRFWChjb3JlX2xpc3RzKTsKc3RhdGljIERFRklORV9JRFIoaTJjX2FkYXB0ZXJfaWRyKTsKCi8qIG1hdGNoIGFsd2F5cyBzdWNjZWVkcywgYXMgd2Ugd2FudCB0aGUgcHJvYmUoKSB0byB0ZWxsIGlmIHdlIHJlYWxseSBhY2NlcHQgdGhpcyBtYXRjaCAqLwpzdGF0aWMgaW50IGkyY19kZXZpY2VfbWF0Y2goc3RydWN0IGRldmljZSAqZGV2LCBzdHJ1Y3QgZGV2aWNlX2RyaXZlciAqZHJ2KQp7CglyZXR1cm4gMTsKfQoKc3RhdGljIGludCBpMmNfYnVzX3N1c3BlbmQoc3RydWN0IGRldmljZSAqIGRldiwgcG1fbWVzc2FnZV90IHN0YXRlKQp7CglpbnQgcmMgPSAwOwoKCWlmIChkZXYtPmRyaXZlciAmJiBkZXYtPmRyaXZlci0+c3VzcGVuZCkKCQlyYyA9IGRldi0+ZHJpdmVyLT5zdXNwZW5kKGRldixzdGF0ZSwwKTsKCXJldHVybiByYzsKfQoKc3RhdGljIGludCBpMmNfYnVzX3Jlc3VtZShzdHJ1Y3QgZGV2aWNlICogZGV2KQp7CglpbnQgcmMgPSAwOwoJCglpZiAoZGV2LT5kcml2ZXIgJiYgZGV2LT5kcml2ZXItPnJlc3VtZSkKCQlyYyA9IGRldi0+ZHJpdmVyLT5yZXN1bWUoZGV2LDApOwoJcmV0dXJuIHJjOwp9CgpzdGF0aWMgc3RydWN0IGJ1c190eXBlIGkyY19idXNfdHlwZSA9IHsKCS5uYW1lID0JCSJpMmMiLAoJLm1hdGNoID0JaTJjX2RldmljZV9tYXRjaCwKCS5zdXNwZW5kID0gICAgICBpMmNfYnVzX3N1c3BlbmQsCgkucmVzdW1lID0gICAgICAgaTJjX2J1c19yZXN1bWUsCn07CgpzdGF0aWMgaW50IGkyY19kZXZpY2VfcHJvYmUoc3RydWN0IGRldmljZSAqZGV2KQp7CglyZXR1cm4gLUVOT0RFVjsKfQoKc3RhdGljIGludCBpMmNfZGV2aWNlX3JlbW92ZShzdHJ1Y3QgZGV2aWNlICpkZXYpCnsKCXJldHVybiAwOwp9CgpzdGF0aWMgdm9pZCBpMmNfYWRhcHRlcl9kZXZfcmVsZWFzZShzdHJ1Y3QgZGV2aWNlICpkZXYpCnsKCXN0cnVjdCBpMmNfYWRhcHRlciAqYWRhcCA9IGRldl90b19pMmNfYWRhcHRlcihkZXYpOwoJY29tcGxldGUoJmFkYXAtPmRldl9yZWxlYXNlZCk7Cn0KCnN0YXRpYyBzdHJ1Y3QgZGV2aWNlX2RyaXZlciBpMmNfYWRhcHRlcl9kcml2ZXIgPSB7CgkubmFtZSA9CSJpMmNfYWRhcHRlciIsCgkuYnVzID0gJmkyY19idXNfdHlwZSwKCS5wcm9iZSA9IGkyY19kZXZpY2VfcHJvYmUsCgkucmVtb3ZlID0gaTJjX2RldmljZV9yZW1vdmUsCn07CgpzdGF0aWMgdm9pZCBpMmNfYWRhcHRlcl9jbGFzc19kZXZfcmVsZWFzZShzdHJ1Y3QgY2xhc3NfZGV2aWNlICpkZXYpCnsKCXN0cnVjdCBpMmNfYWRhcHRlciAqYWRhcCA9IGNsYXNzX2Rldl90b19pMmNfYWRhcHRlcihkZXYpOwoJY29tcGxldGUoJmFkYXAtPmNsYXNzX2Rldl9yZWxlYXNlZCk7Cn0KCnN0YXRpYyBzdHJ1Y3QgY2xhc3MgaTJjX2FkYXB0ZXJfY2xhc3MgPSB7CgkubmFtZSA9CQkiaTJjLWFkYXB0ZXIiLAoJLnJlbGVhc2UgPQkmaTJjX2FkYXB0ZXJfY2xhc3NfZGV2X3JlbGVhc2UsCn07CgpzdGF0aWMgc3NpemVfdCBzaG93X2FkYXB0ZXJfbmFtZShzdHJ1Y3QgZGV2aWNlICpkZXYsIHN0cnVjdCBkZXZpY2VfYXR0cmlidXRlICphdHRyLCBjaGFyICpidWYpCnsKCXN0cnVjdCBpMmNfYWRhcHRlciAqYWRhcCA9IGRldl90b19pMmNfYWRhcHRlcihkZXYpOwoJcmV0dXJuIHNwcmludGYoYnVmLCAiJXNcbiIsIGFkYXAtPm5hbWUpOwp9CnN0YXRpYyBERVZJQ0VfQVRUUihuYW1lLCBTX0lSVUdPLCBzaG93X2FkYXB0ZXJfbmFtZSwgTlVMTCk7CgoKc3RhdGljIHZvaWQgaTJjX2NsaWVudF9yZWxlYXNlKHN0cnVjdCBkZXZpY2UgKmRldikKewoJc3RydWN0IGkyY19jbGllbnQgKmNsaWVudCA9IHRvX2kyY19jbGllbnQoZGV2KTsKCWNvbXBsZXRlKCZjbGllbnQtPnJlbGVhc2VkKTsKfQoKc3RhdGljIHNzaXplX3Qgc2hvd19jbGllbnRfbmFtZShzdHJ1Y3QgZGV2aWNlICpkZXYsIHN0cnVjdCBkZXZpY2VfYXR0cmlidXRlICphdHRyLCBjaGFyICpidWYpCnsKCXN0cnVjdCBpMmNfY2xpZW50ICpjbGllbnQgPSB0b19pMmNfY2xpZW50KGRldik7CglyZXR1cm4gc3ByaW50ZihidWYsICIlc1xuIiwgY2xpZW50LT5uYW1lKTsKfQoKLyogCiAqIFdlIGNhbid0IHVzZSB0aGUgREVWSUNFX0FUVFIoKSBtYWNybyBoZXJlIGFzIHdlIHdhbnQgdGhlIHNhbWUgZmlsZW5hbWUgZm9yIGEKICogZGlmZmVyZW50IHR5cGUgb2YgYSBkZXZpY2UuICBTbyBiZXdhcmUgaWYgdGhlIERFVklDRV9BVFRSKCkgbWFjcm8gZXZlcgogKiBjaGFuZ2VzLCB0aGlzIGRlZmluaXRpb24gd2lsbCBhbHNvIGhhdmUgdG8gY2hhbmdlLgogKi8Kc3RhdGljIHN0cnVjdCBkZXZpY2VfYXR0cmlidXRlIGRldl9hdHRyX2NsaWVudF9uYW1lID0gewoJLmF0dHIJPSB7Lm5hbWUgPSAibmFtZSIsIC5tb2RlID0gU19JUlVHTywgLm93bmVyID0gVEhJU19NT0RVTEUgfSwKCS5zaG93CT0gJnNob3dfY2xpZW50X25hbWUsCn07CgoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAqIHJlZ2lzdGVyaW5nIGZ1bmN0aW9ucyAKICogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIAogKi8KCi8qIC0tLS0tCiAqIGkyY19hZGRfYWRhcHRlciBpcyBjYWxsZWQgZnJvbSB3aXRoaW4gdGhlIGFsZ29yaXRobSBsYXllciwKICogd2hlbiBhIG5ldyBodyBhZGFwdGVyIHJlZ2lzdGVycy4gQSBuZXcgZGV2aWNlIGlzIHJlZ2lzdGVyIHRvIGJlCiAqIGF2YWlsYWJsZSBmb3IgY2xpZW50cy4KICovCmludCBpMmNfYWRkX2FkYXB0ZXIoc3RydWN0IGkyY19hZGFwdGVyICphZGFwKQp7CglpbnQgaWQsIHJlcyA9IDA7CglzdHJ1Y3QgbGlzdF9oZWFkICAgKml0ZW07CglzdHJ1Y3QgaTJjX2RyaXZlciAgKmRyaXZlcjsKCglkb3duKCZjb3JlX2xpc3RzKTsKCglpZiAoaWRyX3ByZV9nZXQoJmkyY19hZGFwdGVyX2lkciwgR0ZQX0tFUk5FTCkgPT0gMCkgewoJCXJlcyA9IC1FTk9NRU07CgkJZ290byBvdXRfdW5sb2NrOwoJfQoKCXJlcyA9IGlkcl9nZXRfbmV3KCZpMmNfYWRhcHRlcl9pZHIsIGFkYXAsICZpZCk7CglpZiAocmVzIDwgMCkgewoJCWlmIChyZXMgPT0gLUVBR0FJTikKCQkJcmVzID0gLUVOT01FTTsKCQlnb3RvIG91dF91bmxvY2s7Cgl9CgoJYWRhcC0+bnIgPSAgaWQgJiBNQVhfSURfTUFTSzsKCWluaXRfTVVURVgoJmFkYXAtPmJ1c19sb2NrKTsKCWluaXRfTVVURVgoJmFkYXAtPmNsaXN0X2xvY2spOwoJbGlzdF9hZGRfdGFpbCgmYWRhcC0+bGlzdCwmYWRhcHRlcnMpOwoJSU5JVF9MSVNUX0hFQUQoJmFkYXAtPmNsaWVudHMpOwoKCS8qIEFkZCB0aGUgYWRhcHRlciB0byB0aGUgZHJpdmVyIGNvcmUuCgkgKiBJZiB0aGUgcGFyZW50IHBvaW50ZXIgaXMgbm90IHNldCB1cCwKCSAqIHdlIGFkZCB0aGlzIGFkYXB0ZXIgdG8gdGhlIGhvc3QgYnVzLgoJICovCglpZiAoYWRhcC0+ZGV2LnBhcmVudCA9PSBOVUxMKQoJCWFkYXAtPmRldi5wYXJlbnQgPSAmcGxhdGZvcm1fYnVzOwoJc3ByaW50ZihhZGFwLT5kZXYuYnVzX2lkLCAiaTJjLSVkIiwgYWRhcC0+bnIpOwoJYWRhcC0+ZGV2LmRyaXZlciA9ICZpMmNfYWRhcHRlcl9kcml2ZXI7CglhZGFwLT5kZXYucmVsZWFzZSA9ICZpMmNfYWRhcHRlcl9kZXZfcmVsZWFzZTsKCWRldmljZV9yZWdpc3RlcigmYWRhcC0+ZGV2KTsKCWRldmljZV9jcmVhdGVfZmlsZSgmYWRhcC0+ZGV2LCAmZGV2X2F0dHJfbmFtZSk7CgoJLyogQWRkIHRoaXMgYWRhcHRlciB0byB0aGUgaTJjX2FkYXB0ZXIgY2xhc3MgKi8KCW1lbXNldCgmYWRhcC0+Y2xhc3NfZGV2LCAweDAwLCBzaXplb2Yoc3RydWN0IGNsYXNzX2RldmljZSkpOwoJYWRhcC0+Y2xhc3NfZGV2LmRldiA9ICZhZGFwLT5kZXY7CglhZGFwLT5jbGFzc19kZXYuY2xhc3MgPSAmaTJjX2FkYXB0ZXJfY2xhc3M7CglzdHJsY3B5KGFkYXAtPmNsYXNzX2Rldi5jbGFzc19pZCwgYWRhcC0+ZGV2LmJ1c19pZCwgQlVTX0lEX1NJWkUpOwoJY2xhc3NfZGV2aWNlX3JlZ2lzdGVyKCZhZGFwLT5jbGFzc19kZXYpOwoKCS8qIGluZm9ybSBkcml2ZXJzIG9mIG5ldyBhZGFwdGVycyAqLwoJbGlzdF9mb3JfZWFjaChpdGVtLCZkcml2ZXJzKSB7CgkJZHJpdmVyID0gbGlzdF9lbnRyeShpdGVtLCBzdHJ1Y3QgaTJjX2RyaXZlciwgbGlzdCk7CgkJaWYgKGRyaXZlci0+ZmxhZ3MgJiBJMkNfREZfTk9USUZZKQoJCQkvKiBXZSBpZ25vcmUgdGhlIHJldHVybiBjb2RlOyBpZiBpdCBmYWlscywgdG9vIGJhZCAqLwoJCQlkcml2ZXItPmF0dGFjaF9hZGFwdGVyKGFkYXApOwoJfQoKCWRldl9kYmcoJmFkYXAtPmRldiwgInJlZ2lzdGVyZWQgYXMgYWRhcHRlciAjJWRcbiIsIGFkYXAtPm5yKTsKCm91dF91bmxvY2s6Cgl1cCgmY29yZV9saXN0cyk7CglyZXR1cm4gcmVzOwp9CgoKaW50IGkyY19kZWxfYWRhcHRlcihzdHJ1Y3QgaTJjX2FkYXB0ZXIgKmFkYXApCnsKCXN0cnVjdCBsaXN0X2hlYWQgICppdGVtLCAqX247CglzdHJ1Y3QgaTJjX2FkYXB0ZXIgKmFkYXBfZnJvbV9saXN0OwoJc3RydWN0IGkyY19kcml2ZXIgKmRyaXZlcjsKCXN0cnVjdCBpMmNfY2xpZW50ICpjbGllbnQ7CglpbnQgcmVzID0gMDsKCglkb3duKCZjb3JlX2xpc3RzKTsKCgkvKiBGaXJzdCBtYWtlIHN1cmUgdGhhdCB0aGlzIGFkYXB0ZXIgd2FzIGV2ZXIgYWRkZWQgKi8KCWxpc3RfZm9yX2VhY2hfZW50cnkoYWRhcF9mcm9tX2xpc3QsICZhZGFwdGVycywgbGlzdCkgewoJCWlmIChhZGFwX2Zyb21fbGlzdCA9PSBhZGFwKQoJCQlicmVhazsKCX0KCWlmIChhZGFwX2Zyb21fbGlzdCAhPSBhZGFwKSB7CgkJcHJfZGVidWcoIkkyQzogQXR0ZW1wdGluZyB0byBkZWxldGUgYW4gdW5yZWdpc3RlcmVkICIKCQkJICJhZGFwdGVyXG4iKTsKCQlyZXMgPSAtRUlOVkFMOwoJCWdvdG8gb3V0X3VubG9jazsKCX0KCglsaXN0X2Zvcl9lYWNoKGl0ZW0sJmRyaXZlcnMpIHsKCQlkcml2ZXIgPSBsaXN0X2VudHJ5KGl0ZW0sIHN0cnVjdCBpMmNfZHJpdmVyLCBsaXN0KTsKCQlpZiAoZHJpdmVyLT5kZXRhY2hfYWRhcHRlcikKCQkJaWYgKChyZXMgPSBkcml2ZXItPmRldGFjaF9hZGFwdGVyKGFkYXApKSkgewoJCQkJZGV2X3dhcm4oJmFkYXAtPmRldiwgImNhbid0IGRldGFjaCBhZGFwdGVyICIKCQkJCQkgIndoaWxlIGRldGFjaGluZyBkcml2ZXIgJXM6IGRyaXZlciAiCgkJCQkJICJub3QgZGV0YWNoZWQhXG4iLCBkcml2ZXItPm5hbWUpOwoJCQkJZ290byBvdXRfdW5sb2NrOwoJCQl9Cgl9CgoJLyogZGV0YWNoIGFueSBhY3RpdmUgY2xpZW50cy4gVGhpcyBtdXN0IGJlIGRvbmUgZmlyc3QsIGJlY2F1c2UKCSAqIGl0IGNhbiBmYWlsOyBpbiB3aGljaCBjYXNlIHdlIGdpdmUgdXAuICovCglsaXN0X2Zvcl9lYWNoX3NhZmUoaXRlbSwgX24sICZhZGFwLT5jbGllbnRzKSB7CgkJY2xpZW50ID0gbGlzdF9lbnRyeShpdGVtLCBzdHJ1Y3QgaTJjX2NsaWVudCwgbGlzdCk7CgoJCS8qIGRldGFjaGluZyBkZXZpY2VzIGlzIHVuY29uZGl0aW9uYWwgb2YgdGhlIHNldCBub3RpZnkKCQkgKiBmbGFnLCBhcyBfYWxsXyBjbGllbnRzIHRoYXQgcmVzaWRlIG9uIHRoZSBhZGFwdGVyCgkJICogbXVzdCBiZSBkZWxldGVkLCBhcyB0aGlzIHdvdWxkIGNhdXNlIGludmFsaWQgc3RhdGVzLgoJCSAqLwoJCWlmICgocmVzPWNsaWVudC0+ZHJpdmVyLT5kZXRhY2hfY2xpZW50KGNsaWVudCkpKSB7CgkJCWRldl9lcnIoJmFkYXAtPmRldiwgImFkYXB0ZXIgbm90ICIKCQkJCSJ1bnJlZ2lzdGVyZWQsIGJlY2F1c2UgY2xpZW50IGF0ICIKCQkJCSJhZGRyZXNzICUwMnggY2FuJ3QgYmUgZGV0YWNoZWQuICIsCgkJCQljbGllbnQtPmFkZHIpOwoJCQlnb3RvIG91dF91bmxvY2s7CgkJfQoJfQoKCS8qIGNsZWFuIHVwIHRoZSBzeXNmcyByZXByZXNlbnRhdGlvbiAqLwoJaW5pdF9jb21wbGV0aW9uKCZhZGFwLT5kZXZfcmVsZWFzZWQpOwoJaW5pdF9jb21wbGV0aW9uKCZhZGFwLT5jbGFzc19kZXZfcmVsZWFzZWQpOwoJY2xhc3NfZGV2aWNlX3VucmVnaXN0ZXIoJmFkYXAtPmNsYXNzX2Rldik7CglkZXZpY2VfcmVtb3ZlX2ZpbGUoJmFkYXAtPmRldiwgJmRldl9hdHRyX25hbWUpOwoJZGV2aWNlX3VucmVnaXN0ZXIoJmFkYXAtPmRldik7CglsaXN0X2RlbCgmYWRhcC0+bGlzdCk7CgoJLyogd2FpdCBmb3Igc3lzZnMgdG8gZHJvcCBhbGwgcmVmZXJlbmNlcyAqLwoJd2FpdF9mb3JfY29tcGxldGlvbigmYWRhcC0+ZGV2X3JlbGVhc2VkKTsKCXdhaXRfZm9yX2NvbXBsZXRpb24oJmFkYXAtPmNsYXNzX2Rldl9yZWxlYXNlZCk7CgoJLyogZnJlZSBkeW5hbWljYWxseSBhbGxvY2F0ZWQgYnVzIGlkICovCglpZHJfcmVtb3ZlKCZpMmNfYWRhcHRlcl9pZHIsIGFkYXAtPm5yKTsKCglkZXZfZGJnKCZhZGFwLT5kZXYsICJhZGFwdGVyIHVucmVnaXN0ZXJlZFxuIik7Cgogb3V0X3VubG9jazoKCXVwKCZjb3JlX2xpc3RzKTsKCXJldHVybiByZXM7Cn0KCgovKiAtLS0tLQogKiBXaGF0IGZvbGxvd3MgaXMgdGhlICJ1cHdhcmRzIiBpbnRlcmZhY2U6IGNvbW1hbmRzIGZvciB0YWxraW5nIHRvIGNsaWVudHMsCiAqIHdoaWNoIGltcGxlbWVudCB0aGUgZnVuY3Rpb25zIHRvIGFjY2VzcyB0aGUgcGh5c2ljYWwgaW5mb3JtYXRpb24gb2YgdGhlCiAqIGNoaXBzLgogKi8KCmludCBpMmNfYWRkX2RyaXZlcihzdHJ1Y3QgaTJjX2RyaXZlciAqZHJpdmVyKQp7CglzdHJ1Y3QgbGlzdF9oZWFkICAgKml0ZW07CglzdHJ1Y3QgaTJjX2FkYXB0ZXIgKmFkYXB0ZXI7CglpbnQgcmVzID0gMDsKCglkb3duKCZjb3JlX2xpc3RzKTsKCgkvKiBhZGQgdGhlIGRyaXZlciB0byB0aGUgbGlzdCBvZiBpMmMgZHJpdmVycyBpbiB0aGUgZHJpdmVyIGNvcmUgKi8KCWRyaXZlci0+ZHJpdmVyLm5hbWUgPSBkcml2ZXItPm5hbWU7Cglkcml2ZXItPmRyaXZlci5idXMgPSAmaTJjX2J1c190eXBlOwoJZHJpdmVyLT5kcml2ZXIucHJvYmUgPSBpMmNfZGV2aWNlX3Byb2JlOwoJZHJpdmVyLT5kcml2ZXIucmVtb3ZlID0gaTJjX2RldmljZV9yZW1vdmU7CgoJcmVzID0gZHJpdmVyX3JlZ2lzdGVyKCZkcml2ZXItPmRyaXZlcik7CglpZiAocmVzKQoJCWdvdG8gb3V0X3VubG9jazsKCQoJbGlzdF9hZGRfdGFpbCgmZHJpdmVyLT5saXN0LCZkcml2ZXJzKTsKCXByX2RlYnVnKCJpMmMtY29yZTogZHJpdmVyICVzIHJlZ2lzdGVyZWQuXG4iLCBkcml2ZXItPm5hbWUpOwoKCS8qIG5vdyBsb29rIGZvciBpbnN0YW5jZXMgb2YgZHJpdmVyIG9uIG91ciBhZGFwdGVycyAqLwoJaWYgKGRyaXZlci0+ZmxhZ3MgJiBJMkNfREZfTk9USUZZKSB7CgkJbGlzdF9mb3JfZWFjaChpdGVtLCZhZGFwdGVycykgewoJCQlhZGFwdGVyID0gbGlzdF9lbnRyeShpdGVtLCBzdHJ1Y3QgaTJjX2FkYXB0ZXIsIGxpc3QpOwoJCQlkcml2ZXItPmF0dGFjaF9hZGFwdGVyKGFkYXB0ZXIpOwoJCX0KCX0KCiBvdXRfdW5sb2NrOgoJdXAoJmNvcmVfbGlzdHMpOwoJcmV0dXJuIHJlczsKfQoKaW50IGkyY19kZWxfZHJpdmVyKHN0cnVjdCBpMmNfZHJpdmVyICpkcml2ZXIpCnsKCXN0cnVjdCBsaXN0X2hlYWQgICAqaXRlbTEsICppdGVtMiwgKl9uOwoJc3RydWN0IGkyY19jbGllbnQgICpjbGllbnQ7CglzdHJ1Y3QgaTJjX2FkYXB0ZXIgKmFkYXA7CgkKCWludCByZXMgPSAwOwoKCWRvd24oJmNvcmVfbGlzdHMpOwoKCS8qIEhhdmUgYSBsb29rIGF0IGVhY2ggYWRhcHRlciwgaWYgY2xpZW50cyBvZiB0aGlzIGRyaXZlciBhcmUgc3RpbGwKCSAqIGF0dGFjaGVkLiBJZiBzbywgZGV0YWNoIHRoZW0gdG8gYmUgYWJsZSB0byBraWxsIHRoZSBkcml2ZXIgCgkgKiBhZnRlcndhcmRzLgoJICovCglwcl9kZWJ1ZygiaTJjLWNvcmU6IHVucmVnaXN0ZXJfZHJpdmVyIC0gbG9va2luZyBmb3IgY2xpZW50cy5cbiIpOwoJLyogcmVtb3ZpbmcgY2xpZW50cyBkb2VzIG5vdCBkZXBlbmQgb24gdGhlIG5vdGlmeSBmbGFnLCBlbHNlIAoJICogaW52YWxpZCBvcGVyYXRpb24gbWlnaHQgKHdpbGwhKSByZXN1bHQsIHdoZW4gdXNpbmcgc3RhbGUgY2xpZW50CgkgKiBwb2ludGVycy4KCSAqLwoJbGlzdF9mb3JfZWFjaChpdGVtMSwmYWRhcHRlcnMpIHsKCQlhZGFwID0gbGlzdF9lbnRyeShpdGVtMSwgc3RydWN0IGkyY19hZGFwdGVyLCBsaXN0KTsKCQlkZXZfZGJnKCZhZGFwLT5kZXYsICJleGFtaW5pbmcgYWRhcHRlclxuIik7CgkJaWYgKGRyaXZlci0+ZGV0YWNoX2FkYXB0ZXIpIHsKCQkJaWYgKChyZXMgPSBkcml2ZXItPmRldGFjaF9hZGFwdGVyKGFkYXApKSkgewoJCQkJZGV2X3dhcm4oJmFkYXAtPmRldiwgIndoaWxlIHVucmVnaXN0ZXJpbmcgIgoJCQkJICAgICAgICJkdW1teSBkcml2ZXIgJXMsIGFkYXB0ZXIgY291bGQgIgoJCQkJICAgICAgICJub3QgYmUgZGV0YWNoZWQgcHJvcGVybHk7IGRyaXZlciAiCgkJCQkgICAgICAgIm5vdCB1bmxvYWRlZCEiLGRyaXZlci0+bmFtZSk7CgkJCQlnb3RvIG91dF91bmxvY2s7CgkJCX0KCQl9IGVsc2UgewoJCQlsaXN0X2Zvcl9lYWNoX3NhZmUoaXRlbTIsIF9uLCAmYWRhcC0+Y2xpZW50cykgewoJCQkJY2xpZW50ID0gbGlzdF9lbnRyeShpdGVtMiwgc3RydWN0IGkyY19jbGllbnQsIGxpc3QpOwoJCQkJaWYgKGNsaWVudC0+ZHJpdmVyICE9IGRyaXZlcikKCQkJCQljb250aW51ZTsKCQkJCXByX2RlYnVnKCJpMmMtY29yZS5vOiBkZXRhY2hpbmcgY2xpZW50ICVzOlxuIiwgY2xpZW50LT5uYW1lKTsKCQkJCWlmICgocmVzID0gZHJpdmVyLT5kZXRhY2hfY2xpZW50KGNsaWVudCkpKSB7CgkJCQkJZGV2X2VycigmYWRhcC0+ZGV2LCAid2hpbGUgIgoJCQkJCQkidW5yZWdpc3RlcmluZyBkcml2ZXIgIgoJCQkJCQkiYCVzJywgdGhlIGNsaWVudCBhdCAiCgkJCQkJCSJhZGRyZXNzICUwMnggb2YgIgoJCQkJCQkiYWRhcHRlciBjb3VsZCBub3QgIgoJCQkJCQkiYmUgZGV0YWNoZWQ7IGRyaXZlciAiCgkJCQkJCSJub3QgdW5sb2FkZWQhIiwKCQkJCQkJZHJpdmVyLT5uYW1lLAoJCQkJCQljbGllbnQtPmFkZHIpOwoJCQkJCWdvdG8gb3V0X3VubG9jazsKCQkJCX0KCQkJfQoJCX0KCX0KCglkcml2ZXJfdW5yZWdpc3RlcigmZHJpdmVyLT5kcml2ZXIpOwoJbGlzdF9kZWwoJmRyaXZlci0+bGlzdCk7Cglwcl9kZWJ1ZygiaTJjLWNvcmU6IGRyaXZlciB1bnJlZ2lzdGVyZWQ6ICVzXG4iLCBkcml2ZXItPm5hbWUpOwoKIG91dF91bmxvY2s6Cgl1cCgmY29yZV9saXN0cyk7CglyZXR1cm4gMDsKfQoKc3RhdGljIGludCBfX2kyY19jaGVja19hZGRyKHN0cnVjdCBpMmNfYWRhcHRlciAqYWRhcHRlciwgdW5zaWduZWQgaW50IGFkZHIpCnsKCXN0cnVjdCBsaXN0X2hlYWQgICAqaXRlbTsKCXN0cnVjdCBpMmNfY2xpZW50ICAqY2xpZW50OwoKCWxpc3RfZm9yX2VhY2goaXRlbSwmYWRhcHRlci0+Y2xpZW50cykgewoJCWNsaWVudCA9IGxpc3RfZW50cnkoaXRlbSwgc3RydWN0IGkyY19jbGllbnQsIGxpc3QpOwoJCWlmIChjbGllbnQtPmFkZHIgPT0gYWRkcikKCQkJcmV0dXJuIC1FQlVTWTsKCX0KCXJldHVybiAwOwp9CgppbnQgaTJjX2NoZWNrX2FkZHIoc3RydWN0IGkyY19hZGFwdGVyICphZGFwdGVyLCBpbnQgYWRkcikKewoJaW50IHJ2YWw7CgoJZG93bigmYWRhcHRlci0+Y2xpc3RfbG9jayk7CglydmFsID0gX19pMmNfY2hlY2tfYWRkcihhZGFwdGVyLCBhZGRyKTsKCXVwKCZhZGFwdGVyLT5jbGlzdF9sb2NrKTsKCglyZXR1cm4gcnZhbDsKfQoKaW50IGkyY19hdHRhY2hfY2xpZW50KHN0cnVjdCBpMmNfY2xpZW50ICpjbGllbnQpCnsKCXN0cnVjdCBpMmNfYWRhcHRlciAqYWRhcHRlciA9IGNsaWVudC0+YWRhcHRlcjsKCglkb3duKCZhZGFwdGVyLT5jbGlzdF9sb2NrKTsKCWlmIChfX2kyY19jaGVja19hZGRyKGNsaWVudC0+YWRhcHRlciwgY2xpZW50LT5hZGRyKSkgewoJCXVwKCZhZGFwdGVyLT5jbGlzdF9sb2NrKTsKCQlyZXR1cm4gLUVCVVNZOwoJfQoJbGlzdF9hZGRfdGFpbCgmY2xpZW50LT5saXN0LCZhZGFwdGVyLT5jbGllbnRzKTsKCXVwKCZhZGFwdGVyLT5jbGlzdF9sb2NrKTsKCQoJaWYgKGFkYXB0ZXItPmNsaWVudF9yZWdpc3RlcikgIHsKCQlpZiAoYWRhcHRlci0+Y2xpZW50X3JlZ2lzdGVyKGNsaWVudCkpICB7CgkJCWRldl93YXJuKCZhZGFwdGVyLT5kZXYsICJ3YXJuaW5nOiBjbGllbnRfcmVnaXN0ZXIgIgoJCQkJInNlZW1zIHRvIGhhdmUgZmFpbGVkIGZvciBjbGllbnQgJTAyeFxuIiwKCQkJCWNsaWVudC0+YWRkcik7CgkJfQoJfQoKCWRldl9kYmcoJmFkYXB0ZXItPmRldiwgImNsaWVudCBbJXNdIHJlZ2lzdGVyZWQgdG8gYWRhcHRlclxuIiwKCQljbGllbnQtPm5hbWUpOwoKCWlmIChjbGllbnQtPmZsYWdzICYgSTJDX0NMSUVOVF9BTExPV19VU0UpCgkJY2xpZW50LT51c2FnZV9jb3VudCA9IDA7CgoJY2xpZW50LT5kZXYucGFyZW50ID0gJmNsaWVudC0+YWRhcHRlci0+ZGV2OwoJY2xpZW50LT5kZXYuZHJpdmVyID0gJmNsaWVudC0+ZHJpdmVyLT5kcml2ZXI7CgljbGllbnQtPmRldi5idXMgPSAmaTJjX2J1c190eXBlOwoJY2xpZW50LT5kZXYucmVsZWFzZSA9ICZpMmNfY2xpZW50X3JlbGVhc2U7CgkKCXNucHJpbnRmKCZjbGllbnQtPmRldi5idXNfaWRbMF0sIHNpemVvZihjbGllbnQtPmRldi5idXNfaWQpLAoJCSIlZC0lMDR4IiwgaTJjX2FkYXB0ZXJfaWQoYWRhcHRlciksIGNsaWVudC0+YWRkcik7Cglwcl9kZWJ1ZygicmVnaXN0ZXJpbmcgJXNcbiIsIGNsaWVudC0+ZGV2LmJ1c19pZCk7CglkZXZpY2VfcmVnaXN0ZXIoJmNsaWVudC0+ZGV2KTsKCWRldmljZV9jcmVhdGVfZmlsZSgmY2xpZW50LT5kZXYsICZkZXZfYXR0cl9jbGllbnRfbmFtZSk7CgkKCXJldHVybiAwOwp9CgoKaW50IGkyY19kZXRhY2hfY2xpZW50KHN0cnVjdCBpMmNfY2xpZW50ICpjbGllbnQpCnsKCXN0cnVjdCBpMmNfYWRhcHRlciAqYWRhcHRlciA9IGNsaWVudC0+YWRhcHRlcjsKCWludCByZXMgPSAwOwoJCglpZiAoKGNsaWVudC0+ZmxhZ3MgJiBJMkNfQ0xJRU5UX0FMTE9XX1VTRSkgJiYgKGNsaWVudC0+dXNhZ2VfY291bnQgPiAwKSkKCQlyZXR1cm4gLUVCVVNZOwoKCWlmIChhZGFwdGVyLT5jbGllbnRfdW5yZWdpc3RlcikgIHsKCQlyZXMgPSBhZGFwdGVyLT5jbGllbnRfdW5yZWdpc3RlcihjbGllbnQpOwoJCWlmIChyZXMpIHsKCQkJZGV2X2VycigmY2xpZW50LT5kZXYsCgkJCQkiY2xpZW50X3VucmVnaXN0ZXIgWyVzXSBmYWlsZWQsICIKCQkJCSJjbGllbnQgbm90IGRldGFjaGVkXG4iLCBjbGllbnQtPm5hbWUpOwoJCQlnb3RvIG91dDsKCQl9Cgl9CgoJZG93bigmYWRhcHRlci0+Y2xpc3RfbG9jayk7CglsaXN0X2RlbCgmY2xpZW50LT5saXN0KTsKCWluaXRfY29tcGxldGlvbigmY2xpZW50LT5yZWxlYXNlZCk7CglkZXZpY2VfcmVtb3ZlX2ZpbGUoJmNsaWVudC0+ZGV2LCAmZGV2X2F0dHJfY2xpZW50X25hbWUpOwoJZGV2aWNlX3VucmVnaXN0ZXIoJmNsaWVudC0+ZGV2KTsKCXVwKCZhZGFwdGVyLT5jbGlzdF9sb2NrKTsKCXdhaXRfZm9yX2NvbXBsZXRpb24oJmNsaWVudC0+cmVsZWFzZWQpOwoKIG91dDoKCXJldHVybiByZXM7Cn0KCnN0YXRpYyBpbnQgaTJjX2luY191c2VfY2xpZW50KHN0cnVjdCBpMmNfY2xpZW50ICpjbGllbnQpCnsKCglpZiAoIXRyeV9tb2R1bGVfZ2V0KGNsaWVudC0+ZHJpdmVyLT5vd25lcikpCgkJcmV0dXJuIC1FTk9ERVY7CglpZiAoIXRyeV9tb2R1bGVfZ2V0KGNsaWVudC0+YWRhcHRlci0+b3duZXIpKSB7CgkJbW9kdWxlX3B1dChjbGllbnQtPmRyaXZlci0+b3duZXIpOwoJCXJldHVybiAtRU5PREVWOwoJfQoKCXJldHVybiAwOwp9CgpzdGF0aWMgdm9pZCBpMmNfZGVjX3VzZV9jbGllbnQoc3RydWN0IGkyY19jbGllbnQgKmNsaWVudCkKewoJbW9kdWxlX3B1dChjbGllbnQtPmRyaXZlci0+b3duZXIpOwoJbW9kdWxlX3B1dChjbGllbnQtPmFkYXB0ZXItPm93bmVyKTsKfQoKaW50IGkyY191c2VfY2xpZW50KHN0cnVjdCBpMmNfY2xpZW50ICpjbGllbnQpCnsKCWludCByZXQ7CgoJcmV0ID0gaTJjX2luY191c2VfY2xpZW50KGNsaWVudCk7CglpZiAocmV0KQoJCXJldHVybiByZXQ7CgoJaWYgKGNsaWVudC0+ZmxhZ3MgJiBJMkNfQ0xJRU5UX0FMTE9XX1VTRSkgewoJCWlmIChjbGllbnQtPmZsYWdzICYgSTJDX0NMSUVOVF9BTExPV19NVUxUSVBMRV9VU0UpCgkJCWNsaWVudC0+dXNhZ2VfY291bnQrKzsKCQllbHNlIGlmIChjbGllbnQtPnVzYWdlX2NvdW50ID4gMCkgCgkJCWdvdG8gYnVzeTsKCQllbHNlIAoJCQljbGllbnQtPnVzYWdlX2NvdW50Kys7Cgl9CgoJcmV0dXJuIDA7CiBidXN5OgoJaTJjX2RlY191c2VfY2xpZW50KGNsaWVudCk7CglyZXR1cm4gLUVCVVNZOwp9CgppbnQgaTJjX3JlbGVhc2VfY2xpZW50KHN0cnVjdCBpMmNfY2xpZW50ICpjbGllbnQpCnsKCWlmKGNsaWVudC0+ZmxhZ3MgJiBJMkNfQ0xJRU5UX0FMTE9XX1VTRSkgewoJCWlmKGNsaWVudC0+dXNhZ2VfY291bnQ+MCkKCQkJY2xpZW50LT51c2FnZV9jb3VudC0tOwoJCWVsc2UgewoJCQlwcl9kZWJ1ZygiaTJjLWNvcmU6ICVzIHVzZWQgb25lIHRvbyBtYW55IHRpbWVzXG4iLAoJCQkJX19GVU5DVElPTl9fKTsKCQkJcmV0dXJuIC1FUEVSTTsKCQl9Cgl9CgkKCWkyY19kZWNfdXNlX2NsaWVudChjbGllbnQpOwoJCglyZXR1cm4gMDsKfQoKdm9pZCBpMmNfY2xpZW50c19jb21tYW5kKHN0cnVjdCBpMmNfYWRhcHRlciAqYWRhcCwgdW5zaWduZWQgaW50IGNtZCwgdm9pZCAqYXJnKQp7CglzdHJ1Y3QgbGlzdF9oZWFkICAqaXRlbTsKCXN0cnVjdCBpMmNfY2xpZW50ICpjbGllbnQ7CgoJZG93bigmYWRhcC0+Y2xpc3RfbG9jayk7CglsaXN0X2Zvcl9lYWNoKGl0ZW0sJmFkYXAtPmNsaWVudHMpIHsKCQljbGllbnQgPSBsaXN0X2VudHJ5KGl0ZW0sIHN0cnVjdCBpMmNfY2xpZW50LCBsaXN0KTsKCQlpZiAoIXRyeV9tb2R1bGVfZ2V0KGNsaWVudC0+ZHJpdmVyLT5vd25lcikpCgkJCWNvbnRpbnVlOwoJCWlmIChOVUxMICE9IGNsaWVudC0+ZHJpdmVyLT5jb21tYW5kKSB7CgkJCXVwKCZhZGFwLT5jbGlzdF9sb2NrKTsKCQkJY2xpZW50LT5kcml2ZXItPmNvbW1hbmQoY2xpZW50LGNtZCxhcmcpOwoJCQlkb3duKCZhZGFwLT5jbGlzdF9sb2NrKTsKCQl9CgkJbW9kdWxlX3B1dChjbGllbnQtPmRyaXZlci0+b3duZXIpOwogICAgICAgfQogICAgICAgdXAoJmFkYXAtPmNsaXN0X2xvY2spOwp9CgpzdGF0aWMgaW50IF9faW5pdCBpMmNfaW5pdCh2b2lkKQp7CglpbnQgcmV0dmFsOwoKCXJldHZhbCA9IGJ1c19yZWdpc3RlcigmaTJjX2J1c190eXBlKTsKCWlmIChyZXR2YWwpCgkJcmV0dXJuIHJldHZhbDsKCXJldHZhbCA9IGRyaXZlcl9yZWdpc3RlcigmaTJjX2FkYXB0ZXJfZHJpdmVyKTsKCWlmIChyZXR2YWwpCgkJcmV0dXJuIHJldHZhbDsKCXJldHVybiBjbGFzc19yZWdpc3RlcigmaTJjX2FkYXB0ZXJfY2xhc3MpOwp9CgpzdGF0aWMgdm9pZCBfX2V4aXQgaTJjX2V4aXQodm9pZCkKewoJY2xhc3NfdW5yZWdpc3RlcigmaTJjX2FkYXB0ZXJfY2xhc3MpOwoJZHJpdmVyX3VucmVnaXN0ZXIoJmkyY19hZGFwdGVyX2RyaXZlcik7CglidXNfdW5yZWdpc3RlcigmaTJjX2J1c190eXBlKTsKfQoKc3Vic3lzX2luaXRjYWxsKGkyY19pbml0KTsKbW9kdWxlX2V4aXQoaTJjX2V4aXQpOwoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogKiB0aGUgZnVuY3Rpb25hbCBpbnRlcmZhY2UgdG8gdGhlIGkyYyBidXNzZXMuCiAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICovCgppbnQgaTJjX3RyYW5zZmVyKHN0cnVjdCBpMmNfYWRhcHRlciAqIGFkYXAsIHN0cnVjdCBpMmNfbXNnICptc2dzLCBpbnQgbnVtKQp7CglpbnQgcmV0OwoKCWlmIChhZGFwLT5hbGdvLT5tYXN0ZXJfeGZlcikgewojaWZkZWYgREVCVUcKCQlmb3IgKHJldCA9IDA7IHJldCA8IG51bTsgcmV0KyspIHsKCQkJZGV2X2RiZygmYWRhcC0+ZGV2LCAibWFzdGVyX3hmZXJbJWRdICVjLCBhZGRyPTB4JTAyeCwgIgoJCQkJImxlbj0lZFxuIiwgcmV0LCBtc2dzW3JldF0uZmxhZ3MgJiBJMkNfTV9SRCA/CgkJCQknUicgOiAnVycsIG1zZ3NbcmV0XS5hZGRyLCBtc2dzW3JldF0ubGVuKTsKCQl9CiNlbmRpZgoKCQlkb3duKCZhZGFwLT5idXNfbG9jayk7CgkJcmV0ID0gYWRhcC0+YWxnby0+bWFzdGVyX3hmZXIoYWRhcCxtc2dzLG51bSk7CgkJdXAoJmFkYXAtPmJ1c19sb2NrKTsKCgkJcmV0dXJuIHJldDsKCX0gZWxzZSB7CgkJZGV2X2RiZygmYWRhcC0+ZGV2LCAiSTJDIGxldmVsIHRyYW5zZmVycyBub3Qgc3VwcG9ydGVkXG4iKTsKCQlyZXR1cm4gLUVOT1NZUzsKCX0KfQoKaW50IGkyY19tYXN0ZXJfc2VuZChzdHJ1Y3QgaTJjX2NsaWVudCAqY2xpZW50LGNvbnN0IGNoYXIgKmJ1ZiAsaW50IGNvdW50KQp7CglpbnQgcmV0OwoJc3RydWN0IGkyY19hZGFwdGVyICphZGFwPWNsaWVudC0+YWRhcHRlcjsKCXN0cnVjdCBpMmNfbXNnIG1zZzsKCgltc2cuYWRkciA9IGNsaWVudC0+YWRkcjsKCW1zZy5mbGFncyA9IGNsaWVudC0+ZmxhZ3MgJiBJMkNfTV9URU47Cgltc2cubGVuID0gY291bnQ7Cgltc2cuYnVmID0gKGNoYXIgKilidWY7CgkKCXJldCA9IGkyY190cmFuc2ZlcihhZGFwLCAmbXNnLCAxKTsKCgkvKiBJZiBldmVyeXRoaW5nIHdlbnQgb2sgKGkuZS4gMSBtc2cgdHJhbnNtaXR0ZWQpLCByZXR1cm4gI2J5dGVzCgkgICB0cmFuc21pdHRlZCwgZWxzZSBlcnJvciBjb2RlLiAqLwoJcmV0dXJuIChyZXQgPT0gMSkgPyBjb3VudCA6IHJldDsKfQoKaW50IGkyY19tYXN0ZXJfcmVjdihzdHJ1Y3QgaTJjX2NsaWVudCAqY2xpZW50LCBjaGFyICpidWYgLGludCBjb3VudCkKewoJc3RydWN0IGkyY19hZGFwdGVyICphZGFwPWNsaWVudC0+YWRhcHRlcjsKCXN0cnVjdCBpMmNfbXNnIG1zZzsKCWludCByZXQ7CgoJbXNnLmFkZHIgPSBjbGllbnQtPmFkZHI7Cgltc2cuZmxhZ3MgPSBjbGllbnQtPmZsYWdzICYgSTJDX01fVEVOOwoJbXNnLmZsYWdzIHw9IEkyQ19NX1JEOwoJbXNnLmxlbiA9IGNvdW50OwoJbXNnLmJ1ZiA9IGJ1ZjsKCglyZXQgPSBpMmNfdHJhbnNmZXIoYWRhcCwgJm1zZywgMSk7CgoJLyogSWYgZXZlcnl0aGluZyB3ZW50IG9rIChpLmUuIDEgbXNnIHRyYW5zbWl0dGVkKSwgcmV0dXJuICNieXRlcwoJICAgdHJhbnNtaXR0ZWQsIGVsc2UgZXJyb3IgY29kZS4gKi8KCXJldHVybiAocmV0ID09IDEpID8gY291bnQgOiByZXQ7Cn0KCgppbnQgaTJjX2NvbnRyb2woc3RydWN0IGkyY19jbGllbnQgKmNsaWVudCwKCXVuc2lnbmVkIGludCBjbWQsIHVuc2lnbmVkIGxvbmcgYXJnKQp7CglpbnQgcmV0ID0gMDsKCXN0cnVjdCBpMmNfYWRhcHRlciAqYWRhcCA9IGNsaWVudC0+YWRhcHRlcjsKCglkZXZfZGJnKCZjbGllbnQtPmFkYXB0ZXItPmRldiwgImkyYyBpb2N0bCwgY21kOiAweCV4LCBhcmc6ICUjbHhcbiIsIGNtZCwgYXJnKTsKCXN3aXRjaCAoY21kKSB7CgkJY2FzZSBJMkNfUkVUUklFUzoKCQkJYWRhcC0+cmV0cmllcyA9IGFyZzsKCQkJYnJlYWs7CgkJY2FzZSBJMkNfVElNRU9VVDoKCQkJYWRhcC0+dGltZW91dCA9IGFyZzsKCQkJYnJlYWs7CgkJZGVmYXVsdDoKCQkJaWYgKGFkYXAtPmFsZ28tPmFsZ29fY29udHJvbCE9TlVMTCkKCQkJCXJldCA9IGFkYXAtPmFsZ28tPmFsZ29fY29udHJvbChhZGFwLGNtZCxhcmcpOwoJfQoJcmV0dXJuIHJldDsKfQoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogKiB0aGUgaTJjIGFkZHJlc3Mgc2Nhbm5pbmcgZnVuY3Rpb24KICogV2lsbCBub3Qgd29yayBmb3IgMTAtYml0IGFkZHJlc3NlcyEKICogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogKi8KaW50IGkyY19wcm9iZShzdHJ1Y3QgaTJjX2FkYXB0ZXIgKmFkYXB0ZXIsCgkgICAgICBzdHJ1Y3QgaTJjX2NsaWVudF9hZGRyZXNzX2RhdGEgKmFkZHJlc3NfZGF0YSwKCSAgICAgIGludCAoKmZvdW5kX3Byb2MpIChzdHJ1Y3QgaTJjX2FkYXB0ZXIgKiwgaW50LCBpbnQpKQp7CglpbnQgYWRkcixpLGZvdW5kLGVycjsKCWludCBhZGFwX2lkID0gaTJjX2FkYXB0ZXJfaWQoYWRhcHRlcik7CgoJLyogRm9yZ2V0IGl0IGlmIHdlIGNhbid0IHByb2JlIHVzaW5nIFNNQlVTX1FVSUNLICovCglpZiAoISBpMmNfY2hlY2tfZnVuY3Rpb25hbGl0eShhZGFwdGVyLEkyQ19GVU5DX1NNQlVTX1FVSUNLKSkKCQlyZXR1cm4gLTE7CgoJZm9yIChhZGRyID0gMHgwMDsgYWRkciA8PSAweDdmOyBhZGRyKyspIHsKCgkJLyogU2tpcCBpZiBhbHJlYWR5IGluIHVzZSAqLwoJCWlmIChpMmNfY2hlY2tfYWRkcihhZGFwdGVyLGFkZHIpKQoJCQljb250aW51ZTsKCgkJLyogSWYgaXQgaXMgaW4gb25lIG9mIHRoZSBmb3JjZSBlbnRyaWVzLCB3ZSBkb24ndCBkbyBhbnkgZGV0ZWN0aW9uCgkJICAgYXQgYWxsICovCgkJZm91bmQgPSAwOwoKCQlmb3IgKGkgPSAwOyAhZm91bmQgJiYgKGFkZHJlc3NfZGF0YS0+Zm9yY2VbaV0gIT0gSTJDX0NMSUVOVF9FTkQpOyBpICs9IDIpIHsKCQkJaWYgKCgoYWRhcF9pZCA9PSBhZGRyZXNzX2RhdGEtPmZvcmNlW2ldKSB8fCAKCQkJICAgICAoYWRkcmVzc19kYXRhLT5mb3JjZVtpXSA9PSBBTllfSTJDX0JVUykpICYmCgkJCSAgICAgKGFkZHIgPT0gYWRkcmVzc19kYXRhLT5mb3JjZVtpKzFdKSkgewoJCQkJZGV2X2RiZygmYWRhcHRlci0+ZGV2LCAiZm91bmQgZm9yY2UgcGFyYW1ldGVyIGZvciBhZGFwdGVyICVkLCBhZGRyICUwNHhcbiIsCgkJCQkJYWRhcF9pZCwgYWRkcik7CgkJCQlpZiAoKGVyciA9IGZvdW5kX3Byb2MoYWRhcHRlcixhZGRyLDApKSkKCQkJCQlyZXR1cm4gZXJyOwoJCQkJZm91bmQgPSAxOwoJCQl9CgkJfQoJCWlmIChmb3VuZCkgCgkJCWNvbnRpbnVlOwoKCQkvKiBJZiB0aGlzIGFkZHJlc3MgaXMgaW4gb25lIG9mIHRoZSBpZ25vcmVzLCB3ZSBjYW4gZm9yZ2V0IGFib3V0CgkJICAgaXQgcmlnaHQgbm93ICovCgkJZm9yIChpID0gMDsKCQkgICAgICFmb3VuZCAmJiAoYWRkcmVzc19kYXRhLT5pZ25vcmVbaV0gIT0gSTJDX0NMSUVOVF9FTkQpOwoJCSAgICAgaSArPSAyKSB7CgkJCWlmICgoKGFkYXBfaWQgPT0gYWRkcmVzc19kYXRhLT5pZ25vcmVbaV0pIHx8IAoJCQkgICAgKChhZGRyZXNzX2RhdGEtPmlnbm9yZVtpXSA9PSBBTllfSTJDX0JVUykpKSAmJgoJCQkgICAgKGFkZHIgPT0gYWRkcmVzc19kYXRhLT5pZ25vcmVbaSsxXSkpIHsKCQkJCWRldl9kYmcoJmFkYXB0ZXItPmRldiwgImZvdW5kIGlnbm9yZSBwYXJhbWV0ZXIgZm9yIGFkYXB0ZXIgJWQsICIKCQkJCQkiYWRkciAlMDR4XG4iLCBhZGFwX2lkICxhZGRyKTsKCQkJCWZvdW5kID0gMTsKCQkJfQoJCX0KCQlpZiAoZm91bmQpIAoJCQljb250aW51ZTsKCgkJLyogTm93LCB3ZSB3aWxsIGRvIGEgZGV0ZWN0aW9uLCBidXQgb25seSBpZiBpdCBpcyBpbiB0aGUgbm9ybWFsIG9yIAoJCSAgIHByb2JlIGVudHJpZXMgKi8gIAoJCWZvciAoaSA9IDA7CgkJICAgICAhZm91bmQgJiYgKGFkZHJlc3NfZGF0YS0+bm9ybWFsX2kyY1tpXSAhPSBJMkNfQ0xJRU5UX0VORCk7CgkJICAgICBpICs9IDEpIHsKCQkJaWYgKGFkZHIgPT0gYWRkcmVzc19kYXRhLT5ub3JtYWxfaTJjW2ldKSB7CgkJCQlmb3VuZCA9IDE7CgkJCQlkZXZfZGJnKCZhZGFwdGVyLT5kZXYsICJmb3VuZCBub3JtYWwgaTJjIGVudHJ5IGZvciBhZGFwdGVyICVkLCAiCgkJCQkJImFkZHIgJTAyeFxuIiwgYWRhcF9pZCwgYWRkcik7CgkJCX0KCQl9CgoJCWZvciAoaSA9IDA7CgkJICAgICAhZm91bmQgJiYgKGFkZHJlc3NfZGF0YS0+cHJvYmVbaV0gIT0gSTJDX0NMSUVOVF9FTkQpOwoJCSAgICAgaSArPSAyKSB7CgkJCWlmICgoKGFkYXBfaWQgPT0gYWRkcmVzc19kYXRhLT5wcm9iZVtpXSkgfHwKCQkJICAgICgoYWRkcmVzc19kYXRhLT5wcm9iZVtpXSA9PSBBTllfSTJDX0JVUykpKSAmJgoJCQkgICAgKGFkZHIgPT0gYWRkcmVzc19kYXRhLT5wcm9iZVtpKzFdKSkgewoJCQkJZm91bmQgPSAxOwoJCQkJZGV2X2RiZygmYWRhcHRlci0+ZGV2LCAiZm91bmQgcHJvYmUgcGFyYW1ldGVyIGZvciBhZGFwdGVyICVkLCAiCgkJCQkJImFkZHIgJTA0eFxuIiwgYWRhcF9pZCxhZGRyKTsKCQkJfQoJCX0KCQlpZiAoIWZvdW5kKSAKCQkJY29udGludWU7CgoJCS8qIE9LLCBzbyB3ZSByZWFsbHkgc2hvdWxkIGV4YW1pbmUgdGhpcyBhZGRyZXNzLiBGaXJzdCBjaGVjawoJCSAgIHdoZXRoZXIgdGhlcmUgaXMgc29tZSBjbGllbnQgaGVyZSBhdCBhbGwhICovCgkJaWYgKGkyY19zbWJ1c194ZmVyKGFkYXB0ZXIsYWRkciwwLDAsMCxJMkNfU01CVVNfUVVJQ0ssTlVMTCkgPj0gMCkKCQkJaWYgKChlcnIgPSBmb3VuZF9wcm9jKGFkYXB0ZXIsYWRkciwtMSkpKQoJCQkJcmV0dXJuIGVycjsKCX0KCXJldHVybiAwOwp9CgovKgogKiByZXR1cm4gaWQgbnVtYmVyIGZvciBhIHNwZWNpZmljIGFkYXB0ZXIKICovCmludCBpMmNfYWRhcHRlcl9pZChzdHJ1Y3QgaTJjX2FkYXB0ZXIgKmFkYXApCnsKCXJldHVybiBhZGFwLT5ucjsKfQoKc3RydWN0IGkyY19hZGFwdGVyKiBpMmNfZ2V0X2FkYXB0ZXIoaW50IGlkKQp7CglzdHJ1Y3QgaTJjX2FkYXB0ZXIgKmFkYXB0ZXI7CgkKCWRvd24oJmNvcmVfbGlzdHMpOwoJYWRhcHRlciA9IChzdHJ1Y3QgaTJjX2FkYXB0ZXIgKilpZHJfZmluZCgmaTJjX2FkYXB0ZXJfaWRyLCBpZCk7CglpZiAoYWRhcHRlciAmJiAhdHJ5X21vZHVsZV9nZXQoYWRhcHRlci0+b3duZXIpKQoJCWFkYXB0ZXIgPSBOVUxMOwoKCXVwKCZjb3JlX2xpc3RzKTsKCXJldHVybiBhZGFwdGVyOwp9Cgp2b2lkIGkyY19wdXRfYWRhcHRlcihzdHJ1Y3QgaTJjX2FkYXB0ZXIgKmFkYXApCnsKCW1vZHVsZV9wdXQoYWRhcC0+b3duZXIpOwp9CgovKiBUaGUgU01CdXMgcGFydHMgKi8KCiNkZWZpbmUgUE9MWSAgICAoMHgxMDcwVSA8PCAzKSAKc3RhdGljIHU4CmNyYzgodTE2IGRhdGEpCnsKCWludCBpOwogIAoJZm9yKGkgPSAwOyBpIDwgODsgaSsrKSB7CgkJaWYgKGRhdGEgJiAweDgwMDApIAoJCQlkYXRhID0gZGF0YSBeIFBPTFk7CgkJZGF0YSA9IGRhdGEgPDwgMTsKCX0KCXJldHVybiAodTgpKGRhdGEgPj4gOCk7Cn0KCi8qIENSQyBvdmVyIGNvdW50IGJ5dGVzIGluIHRoZSBmaXJzdCBhcnJheSBwbHVzIHRoZSBieXRlcyBpbiB0aGUgcmVzdAogICBhcnJheSBpZiBpdCBpcyBub24tbnVsbC4gcmVzdFswXSBpcyB0aGUgKGxlbmd0aCBvZiByZXN0KSAtIDEKICAgYW5kIGlzIGluY2x1ZGVkLiAqLwpzdGF0aWMgdTggaTJjX3NtYnVzX3BhcnRpYWxfcGVjKHU4IGNyYywgaW50IGNvdW50LCB1OCAqZmlyc3QsIHU4ICpyZXN0KQp7CglpbnQgaTsKCglmb3IoaSA9IDA7IGkgPCBjb3VudDsgaSsrKQoJCWNyYyA9IGNyYzgoKGNyYyBeIGZpcnN0W2ldKSA8PCA4KTsKCWlmKHJlc3QgIT0gTlVMTCkKCQlmb3IoaSA9IDA7IGkgPD0gcmVzdFswXTsgaSsrKQoJCQljcmMgPSBjcmM4KChjcmMgXiByZXN0W2ldKSA8PCA4KTsKCXJldHVybiBjcmM7Cn0KCnN0YXRpYyB1OCBpMmNfc21idXNfcGVjKGludCBjb3VudCwgdTggKmZpcnN0LCB1OCAqcmVzdCkKewoJcmV0dXJuIGkyY19zbWJ1c19wYXJ0aWFsX3BlYygwLCBjb3VudCwgZmlyc3QsIHJlc3QpOwp9CgovKiBSZXR1cm5zIG5ldyAic2l6ZSIgKHRyYW5zYWN0aW9uIHR5cGUpCiAgIE5vdGUgdGhhdCB3ZSBjb252ZXJ0IGJ5dGUgdG8gYnl0ZV9kYXRhIGFuZCBieXRlX2RhdGEgdG8gd29yZF9kYXRhCiAgIHJhdGhlciB0aGFuIGludmVudCBuZXcgeHh4X1BFQyB0cmFuc2FjdGlvbnMuICovCnN0YXRpYyBpbnQgaTJjX3NtYnVzX2FkZF9wZWModTE2IGFkZHIsIHU4IGNvbW1hbmQsIGludCBzaXplLAoJCQkgICAgIHVuaW9uIGkyY19zbWJ1c19kYXRhICpkYXRhKQp7Cgl1OCBidWZbM107CgoJYnVmWzBdID0gYWRkciA8PCAxOwoJYnVmWzFdID0gY29tbWFuZDsKCXN3aXRjaChzaXplKSB7CgkJY2FzZSBJMkNfU01CVVNfQllURToKCQkJZGF0YS0+Ynl0ZSA9IGkyY19zbWJ1c19wZWMoMiwgYnVmLCBOVUxMKTsKCQkJc2l6ZSA9IEkyQ19TTUJVU19CWVRFX0RBVEE7CgkJCWJyZWFrOwoJCWNhc2UgSTJDX1NNQlVTX0JZVEVfREFUQToKCQkJYnVmWzJdID0gZGF0YS0+Ynl0ZTsKCQkJZGF0YS0+d29yZCA9IGJ1ZlsyXSB8fAoJCQkgICAgICAgICAgICAoaTJjX3NtYnVzX3BlYygzLCBidWYsIE5VTEwpIDw8IDgpOwoJCQlzaXplID0gSTJDX1NNQlVTX1dPUkRfREFUQTsKCQkJYnJlYWs7CgkJY2FzZSBJMkNfU01CVVNfV09SRF9EQVRBOgoJCQkvKiB1bnN1cHBvcnRlZCAqLwoJCQlicmVhazsKCQljYXNlIEkyQ19TTUJVU19CTE9DS19EQVRBOgoJCQlkYXRhLT5ibG9ja1tkYXRhLT5ibG9ja1swXSArIDFdID0KCQkJICAgICAgICAgICAgIGkyY19zbWJ1c19wZWMoMiwgYnVmLCBkYXRhLT5ibG9jayk7CgkJCXNpemUgPSBJMkNfU01CVVNfQkxPQ0tfREFUQV9QRUM7CgkJCWJyZWFrOwoJfQoJcmV0dXJuIHNpemU7CQp9CgpzdGF0aWMgaW50IGkyY19zbWJ1c19jaGVja19wZWModTE2IGFkZHIsIHU4IGNvbW1hbmQsIGludCBzaXplLCB1OCBwYXJ0aWFsLAoJCQkgICAgICAgdW5pb24gaTJjX3NtYnVzX2RhdGEgKmRhdGEpCnsKCXU4IGJ1ZlszXSwgcnBlYywgY3BlYzsKCglidWZbMV0gPSBjb21tYW5kOwoJc3dpdGNoKHNpemUpIHsKCQljYXNlIEkyQ19TTUJVU19CWVRFX0RBVEE6CgkJCWJ1ZlswXSA9IChhZGRyIDw8IDEpIHwgMTsKCQkJY3BlYyA9IGkyY19zbWJ1c19wZWMoMiwgYnVmLCBOVUxMKTsKCQkJcnBlYyA9IGRhdGEtPmJ5dGU7CgkJCWJyZWFrOwoJCWNhc2UgSTJDX1NNQlVTX1dPUkRfREFUQToKCQkJYnVmWzBdID0gKGFkZHIgPDwgMSkgfCAxOwoJCQlidWZbMl0gPSBkYXRhLT53b3JkICYgMHhmZjsKCQkJY3BlYyA9IGkyY19zbWJ1c19wZWMoMywgYnVmLCBOVUxMKTsKCQkJcnBlYyA9IGRhdGEtPndvcmQgPj4gODsKCQkJYnJlYWs7CgkJY2FzZSBJMkNfU01CVVNfV09SRF9EQVRBX1BFQzoKCQkJLyogdW5zdXBwb3J0ZWQgKi8KCQkJY3BlYyA9IHJwZWMgPSAwOwoJCQlicmVhazsKCQljYXNlIEkyQ19TTUJVU19QUk9DX0NBTExfUEVDOgoJCQkvKiB1bnN1cHBvcnRlZCAqLwoJCQljcGVjID0gcnBlYyA9IDA7CgkJCWJyZWFrOwoJCWNhc2UgSTJDX1NNQlVTX0JMT0NLX0RBVEFfUEVDOgoJCQlidWZbMF0gPSAoYWRkciA8PCAxKTsKCQkJYnVmWzJdID0gKGFkZHIgPDwgMSkgfCAxOwoJCQljcGVjID0gaTJjX3NtYnVzX3BlYygzLCBidWYsIGRhdGEtPmJsb2NrKTsKCQkJcnBlYyA9IGRhdGEtPmJsb2NrW2RhdGEtPmJsb2NrWzBdICsgMV07CgkJCWJyZWFrOwoJCWNhc2UgSTJDX1NNQlVTX0JMT0NLX1BST0NfQ0FMTF9QRUM6CgkJCWJ1ZlswXSA9IChhZGRyIDw8IDEpIHwgMTsKCQkJcnBlYyA9IGkyY19zbWJ1c19wYXJ0aWFsX3BlYyhwYXJ0aWFsLCAxLAoJCQkgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ1ZiwgZGF0YS0+YmxvY2spOwoJCQljcGVjID0gZGF0YS0+YmxvY2tbZGF0YS0+YmxvY2tbMF0gKyAxXTsKCQkJYnJlYWs7CgkJZGVmYXVsdDoKCQkJY3BlYyA9IHJwZWMgPSAwOwoJCQlicmVhazsKCX0KCWlmIChycGVjICE9IGNwZWMpIHsKCQlwcl9kZWJ1ZygiaTJjLWNvcmU6IEJhZCBQRUMgMHglMDJ4IHZzLiAweCUwMnhcbiIsCgkJCXJwZWMsIGNwZWMpOwoJCXJldHVybiAtMTsKCX0KCXJldHVybiAwOwkKfQoKczMyIGkyY19zbWJ1c193cml0ZV9xdWljayhzdHJ1Y3QgaTJjX2NsaWVudCAqY2xpZW50LCB1OCB2YWx1ZSkKewoJcmV0dXJuIGkyY19zbWJ1c194ZmVyKGNsaWVudC0+YWRhcHRlcixjbGllbnQtPmFkZHIsY2xpZW50LT5mbGFncywKIAkgICAgICAgICAgICAgICAgICAgICAgdmFsdWUsMCxJMkNfU01CVVNfUVVJQ0ssTlVMTCk7Cn0KCnMzMiBpMmNfc21idXNfcmVhZF9ieXRlKHN0cnVjdCBpMmNfY2xpZW50ICpjbGllbnQpCnsKCXVuaW9uIGkyY19zbWJ1c19kYXRhIGRhdGE7CglpZiAoaTJjX3NtYnVzX3hmZXIoY2xpZW50LT5hZGFwdGVyLGNsaWVudC0+YWRkcixjbGllbnQtPmZsYWdzLAoJICAgICAgICAgICAgICAgICAgIEkyQ19TTUJVU19SRUFELDAsSTJDX1NNQlVTX0JZVEUsICZkYXRhKSkKCQlyZXR1cm4gLTE7CgllbHNlCgkJcmV0dXJuIDB4MEZGICYgZGF0YS5ieXRlOwp9CgpzMzIgaTJjX3NtYnVzX3dyaXRlX2J5dGUoc3RydWN0IGkyY19jbGllbnQgKmNsaWVudCwgdTggdmFsdWUpCnsKCXVuaW9uIGkyY19zbWJ1c19kYXRhIGRhdGE7CS8qIG9ubHkgZm9yIFBFQyAqLwoJcmV0dXJuIGkyY19zbWJ1c194ZmVyKGNsaWVudC0+YWRhcHRlcixjbGllbnQtPmFkZHIsY2xpZW50LT5mbGFncywKCSAgICAgICAgICAgICAgICAgICAgICBJMkNfU01CVVNfV1JJVEUsdmFsdWUsIEkyQ19TTUJVU19CWVRFLCZkYXRhKTsKfQoKczMyIGkyY19zbWJ1c19yZWFkX2J5dGVfZGF0YShzdHJ1Y3QgaTJjX2NsaWVudCAqY2xpZW50LCB1OCBjb21tYW5kKQp7Cgl1bmlvbiBpMmNfc21idXNfZGF0YSBkYXRhOwoJaWYgKGkyY19zbWJ1c194ZmVyKGNsaWVudC0+YWRhcHRlcixjbGllbnQtPmFkZHIsY2xpZW50LT5mbGFncywKCSAgICAgICAgICAgICAgICAgICBJMkNfU01CVVNfUkVBRCxjb21tYW5kLCBJMkNfU01CVVNfQllURV9EQVRBLCZkYXRhKSkKCQlyZXR1cm4gLTE7CgllbHNlCgkJcmV0dXJuIDB4MEZGICYgZGF0YS5ieXRlOwp9CgpzMzIgaTJjX3NtYnVzX3dyaXRlX2J5dGVfZGF0YShzdHJ1Y3QgaTJjX2NsaWVudCAqY2xpZW50LCB1OCBjb21tYW5kLCB1OCB2YWx1ZSkKewoJdW5pb24gaTJjX3NtYnVzX2RhdGEgZGF0YTsKCWRhdGEuYnl0ZSA9IHZhbHVlOwoJcmV0dXJuIGkyY19zbWJ1c194ZmVyKGNsaWVudC0+YWRhcHRlcixjbGllbnQtPmFkZHIsY2xpZW50LT5mbGFncywKCSAgICAgICAgICAgICAgICAgICAgICBJMkNfU01CVVNfV1JJVEUsY29tbWFuZCwKCSAgICAgICAgICAgICAgICAgICAgICBJMkNfU01CVVNfQllURV9EQVRBLCZkYXRhKTsKfQoKczMyIGkyY19zbWJ1c19yZWFkX3dvcmRfZGF0YShzdHJ1Y3QgaTJjX2NsaWVudCAqY2xpZW50LCB1OCBjb21tYW5kKQp7Cgl1bmlvbiBpMmNfc21idXNfZGF0YSBkYXRhOwoJaWYgKGkyY19zbWJ1c194ZmVyKGNsaWVudC0+YWRhcHRlcixjbGllbnQtPmFkZHIsY2xpZW50LT5mbGFncywKCSAgICAgICAgICAgICAgICAgICBJMkNfU01CVVNfUkVBRCxjb21tYW5kLCBJMkNfU01CVVNfV09SRF9EQVRBLCAmZGF0YSkpCgkJcmV0dXJuIC0xOwoJZWxzZQoJCXJldHVybiAweDBGRkZGICYgZGF0YS53b3JkOwp9CgpzMzIgaTJjX3NtYnVzX3dyaXRlX3dvcmRfZGF0YShzdHJ1Y3QgaTJjX2NsaWVudCAqY2xpZW50LCB1OCBjb21tYW5kLCB1MTYgdmFsdWUpCnsKCXVuaW9uIGkyY19zbWJ1c19kYXRhIGRhdGE7CglkYXRhLndvcmQgPSB2YWx1ZTsKCXJldHVybiBpMmNfc21idXNfeGZlcihjbGllbnQtPmFkYXB0ZXIsY2xpZW50LT5hZGRyLGNsaWVudC0+ZmxhZ3MsCgkgICAgICAgICAgICAgICAgICAgICAgSTJDX1NNQlVTX1dSSVRFLGNvbW1hbmQsCgkgICAgICAgICAgICAgICAgICAgICAgSTJDX1NNQlVTX1dPUkRfREFUQSwmZGF0YSk7Cn0KCnMzMiBpMmNfc21idXNfd3JpdGVfYmxvY2tfZGF0YShzdHJ1Y3QgaTJjX2NsaWVudCAqY2xpZW50LCB1OCBjb21tYW5kLAoJCQkgICAgICAgdTggbGVuZ3RoLCB1OCAqdmFsdWVzKQp7Cgl1bmlvbiBpMmNfc21idXNfZGF0YSBkYXRhOwoJaW50IGk7CglpZiAobGVuZ3RoID4gSTJDX1NNQlVTX0JMT0NLX01BWCkKCQlsZW5ndGggPSBJMkNfU01CVVNfQkxPQ0tfTUFYOwoJZm9yIChpID0gMTsgaSA8PSBsZW5ndGg7IGkrKykKCQlkYXRhLmJsb2NrW2ldID0gdmFsdWVzW2ktMV07CglkYXRhLmJsb2NrWzBdID0gbGVuZ3RoOwoJcmV0dXJuIGkyY19zbWJ1c194ZmVyKGNsaWVudC0+YWRhcHRlcixjbGllbnQtPmFkZHIsY2xpZW50LT5mbGFncywKCQkJICAgICAgSTJDX1NNQlVTX1dSSVRFLGNvbW1hbmQsCgkJCSAgICAgIEkyQ19TTUJVU19CTE9DS19EQVRBLCZkYXRhKTsKfQoKLyogUmV0dXJucyB0aGUgbnVtYmVyIG9mIHJlYWQgYnl0ZXMgKi8KczMyIGkyY19zbWJ1c19yZWFkX2kyY19ibG9ja19kYXRhKHN0cnVjdCBpMmNfY2xpZW50ICpjbGllbnQsIHU4IGNvbW1hbmQsIHU4ICp2YWx1ZXMpCnsKCXVuaW9uIGkyY19zbWJ1c19kYXRhIGRhdGE7CglpbnQgaTsKCWlmIChpMmNfc21idXNfeGZlcihjbGllbnQtPmFkYXB0ZXIsY2xpZW50LT5hZGRyLGNsaWVudC0+ZmxhZ3MsCgkgICAgICAgICAgICAgICAgICAgICAgSTJDX1NNQlVTX1JFQUQsY29tbWFuZCwKCSAgICAgICAgICAgICAgICAgICAgICBJMkNfU01CVVNfSTJDX0JMT0NLX0RBVEEsJmRhdGEpKQoJCXJldHVybiAtMTsKCWVsc2UgewoJCWZvciAoaSA9IDE7IGkgPD0gZGF0YS5ibG9ja1swXTsgaSsrKQoJCQl2YWx1ZXNbaS0xXSA9IGRhdGEuYmxvY2tbaV07CgkJcmV0dXJuIGRhdGEuYmxvY2tbMF07Cgl9Cn0KCi8qIFNpbXVsYXRlIGEgU01CdXMgY29tbWFuZCB1c2luZyB0aGUgaTJjIHByb3RvY29sIAogICBObyBjaGVja2luZyBvZiBwYXJhbWV0ZXJzIGlzIGRvbmUhICAqLwpzdGF0aWMgczMyIGkyY19zbWJ1c194ZmVyX2VtdWxhdGVkKHN0cnVjdCBpMmNfYWRhcHRlciAqIGFkYXB0ZXIsIHUxNiBhZGRyLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBzaG9ydCBmbGFncywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGFyIHJlYWRfd3JpdGUsIHU4IGNvbW1hbmQsIGludCBzaXplLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bmlvbiBpMmNfc21idXNfZGF0YSAqIGRhdGEpCnsKCS8qIFNvIHdlIG5lZWQgdG8gZ2VuZXJhdGUgYSBzZXJpZXMgb2YgbXNncy4gSW4gdGhlIGNhc2Ugb2Ygd3JpdGluZywgd2UKCSAgbmVlZCB0byB1c2Ugb25seSBvbmUgbWVzc2FnZTsgd2hlbiByZWFkaW5nLCB3ZSBuZWVkIHR3by4gV2UgaW5pdGlhbGl6ZQoJICBtb3N0IHRoaW5ncyB3aXRoIHNhbmUgZGVmYXVsdHMsIHRvIGtlZXAgdGhlIGNvZGUgYmVsb3cgc29tZXdoYXQKCSAgc2ltcGxlci4gKi8KCXVuc2lnbmVkIGNoYXIgbXNnYnVmMFszNF07Cgl1bnNpZ25lZCBjaGFyIG1zZ2J1ZjFbMzRdOwoJaW50IG51bSA9IHJlYWRfd3JpdGUgPT0gSTJDX1NNQlVTX1JFQUQ/MjoxOwoJc3RydWN0IGkyY19tc2cgbXNnWzJdID0geyB7IGFkZHIsIGZsYWdzLCAxLCBtc2didWYwIH0sIAoJICAgICAgICAgICAgICAgICAgICAgICAgICB7IGFkZHIsIGZsYWdzIHwgSTJDX01fUkQsIDAsIG1zZ2J1ZjEgfQoJICAgICAgICAgICAgICAgICAgICAgICAgfTsKCWludCBpOwoKCW1zZ2J1ZjBbMF0gPSBjb21tYW5kOwoJc3dpdGNoKHNpemUpIHsKCWNhc2UgSTJDX1NNQlVTX1FVSUNLOgoJCW1zZ1swXS5sZW4gPSAwOwoJCS8qIFNwZWNpYWwgY2FzZTogVGhlIHJlYWQvd3JpdGUgZmllbGQgaXMgdXNlZCBhcyBkYXRhICovCgkJbXNnWzBdLmZsYWdzID0gZmxhZ3MgfCAocmVhZF93cml0ZT09STJDX1NNQlVTX1JFQUQpP0kyQ19NX1JEOjA7CgkJbnVtID0gMTsKCQlicmVhazsKCWNhc2UgSTJDX1NNQlVTX0JZVEU6CgkJaWYgKHJlYWRfd3JpdGUgPT0gSTJDX1NNQlVTX1JFQUQpIHsKCQkJLyogU3BlY2lhbCBjYXNlOiBvbmx5IGEgcmVhZCEgKi8KCQkJbXNnWzBdLmZsYWdzID0gSTJDX01fUkQgfCBmbGFnczsKCQkJbnVtID0gMTsKCQl9CgkJYnJlYWs7CgljYXNlIEkyQ19TTUJVU19CWVRFX0RBVEE6CgkJaWYgKHJlYWRfd3JpdGUgPT0gSTJDX1NNQlVTX1JFQUQpCgkJCW1zZ1sxXS5sZW4gPSAxOwoJCWVsc2UgewoJCQltc2dbMF0ubGVuID0gMjsKCQkJbXNnYnVmMFsxXSA9IGRhdGEtPmJ5dGU7CgkJfQoJCWJyZWFrOwoJY2FzZSBJMkNfU01CVVNfV09SRF9EQVRBOgoJCWlmIChyZWFkX3dyaXRlID09IEkyQ19TTUJVU19SRUFEKQoJCQltc2dbMV0ubGVuID0gMjsKCQllbHNlIHsKCQkJbXNnWzBdLmxlbj0zOwoJCQltc2didWYwWzFdID0gZGF0YS0+d29yZCAmIDB4ZmY7CgkJCW1zZ2J1ZjBbMl0gPSAoZGF0YS0+d29yZCA+PiA4KSAmIDB4ZmY7CgkJfQoJCWJyZWFrOwoJY2FzZSBJMkNfU01CVVNfUFJPQ19DQUxMOgoJCW51bSA9IDI7IC8qIFNwZWNpYWwgY2FzZSAqLwoJCXJlYWRfd3JpdGUgPSBJMkNfU01CVVNfUkVBRDsKCQltc2dbMF0ubGVuID0gMzsKCQltc2dbMV0ubGVuID0gMjsKCQltc2didWYwWzFdID0gZGF0YS0+d29yZCAmIDB4ZmY7CgkJbXNnYnVmMFsyXSA9IChkYXRhLT53b3JkID4+IDgpICYgMHhmZjsKCQlicmVhazsKCWNhc2UgSTJDX1NNQlVTX0JMT0NLX0RBVEE6CgljYXNlIEkyQ19TTUJVU19CTE9DS19EQVRBX1BFQzoKCQlpZiAocmVhZF93cml0ZSA9PSBJMkNfU01CVVNfUkVBRCkgewoJCQlkZXZfZXJyKCZhZGFwdGVyLT5kZXYsICJCbG9jayByZWFkIG5vdCBzdXBwb3J0ZWQgIgoJCQkgICAgICAgInVuZGVyIEkyQyBlbXVsYXRpb24hXG4iKTsKCQkJcmV0dXJuIC0xOwoJCX0gZWxzZSB7CgkJCW1zZ1swXS5sZW4gPSBkYXRhLT5ibG9ja1swXSArIDI7CgkJCWlmIChtc2dbMF0ubGVuID4gSTJDX1NNQlVTX0JMT0NLX01BWCArIDIpIHsKCQkJCWRldl9lcnIoJmFkYXB0ZXItPmRldiwgInNtYnVzX2FjY2VzcyBjYWxsZWQgd2l0aCAiCgkJCQkgICAgICAgImludmFsaWQgYmxvY2sgd3JpdGUgc2l6ZSAoJWQpXG4iLAoJCQkJICAgICAgIGRhdGEtPmJsb2NrWzBdKTsKCQkJCXJldHVybiAtMTsKCQkJfQoJCQlpZihzaXplID09IEkyQ19TTUJVU19CTE9DS19EQVRBX1BFQykKCQkJCShtc2dbMF0ubGVuKSsrOwoJCQlmb3IgKGkgPSAxOyBpIDw9IG1zZ1swXS5sZW47IGkrKykKCQkJCW1zZ2J1ZjBbaV0gPSBkYXRhLT5ibG9ja1tpLTFdOwoJCX0KCQlicmVhazsKCWNhc2UgSTJDX1NNQlVTX0JMT0NLX1BST0NfQ0FMTDoKCWNhc2UgSTJDX1NNQlVTX0JMT0NLX1BST0NfQ0FMTF9QRUM6CgkJZGV2X2RiZygmYWRhcHRlci0+ZGV2LCAiQmxvY2sgcHJvY2VzcyBjYWxsIG5vdCBzdXBwb3J0ZWQgIgoJCSAgICAgICAidW5kZXIgSTJDIGVtdWxhdGlvbiFcbiIpOwoJCXJldHVybiAtMTsKCWNhc2UgSTJDX1NNQlVTX0kyQ19CTE9DS19EQVRBOgoJCWlmIChyZWFkX3dyaXRlID09IEkyQ19TTUJVU19SRUFEKSB7CgkJCW1zZ1sxXS5sZW4gPSBJMkNfU01CVVNfSTJDX0JMT0NLX01BWDsKCQl9IGVsc2UgewoJCQltc2dbMF0ubGVuID0gZGF0YS0+YmxvY2tbMF0gKyAxOwoJCQlpZiAobXNnWzBdLmxlbiA+IEkyQ19TTUJVU19JMkNfQkxPQ0tfTUFYICsgMSkgewoJCQkJZGV2X2VycigmYWRhcHRlci0+ZGV2LCAiaTJjX3NtYnVzX3hmZXJfZW11bGF0ZWQgY2FsbGVkIHdpdGggIgoJCQkJICAgICAgICJpbnZhbGlkIGJsb2NrIHdyaXRlIHNpemUgKCVkKVxuIiwKCQkJCSAgICAgICBkYXRhLT5ibG9ja1swXSk7CgkJCQlyZXR1cm4gLTE7CgkJCX0KCQkJZm9yIChpID0gMTsgaSA8PSBkYXRhLT5ibG9ja1swXTsgaSsrKQoJCQkJbXNnYnVmMFtpXSA9IGRhdGEtPmJsb2NrW2ldOwoJCX0KCQlicmVhazsKCWRlZmF1bHQ6CgkJZGV2X2VycigmYWRhcHRlci0+ZGV2LCAic21idXNfYWNjZXNzIGNhbGxlZCB3aXRoIGludmFsaWQgc2l6ZSAoJWQpXG4iLAoJCSAgICAgICBzaXplKTsKCQlyZXR1cm4gLTE7Cgl9CgoJaWYgKGkyY190cmFuc2ZlcihhZGFwdGVyLCBtc2csIG51bSkgPCAwKQoJCXJldHVybiAtMTsKCglpZiAocmVhZF93cml0ZSA9PSBJMkNfU01CVVNfUkVBRCkKCQlzd2l0Y2goc2l6ZSkgewoJCQljYXNlIEkyQ19TTUJVU19CWVRFOgoJCQkJZGF0YS0+Ynl0ZSA9IG1zZ2J1ZjBbMF07CgkJCQlicmVhazsKCQkJY2FzZSBJMkNfU01CVVNfQllURV9EQVRBOgoJCQkJZGF0YS0+Ynl0ZSA9IG1zZ2J1ZjFbMF07CgkJCQlicmVhazsKCQkJY2FzZSBJMkNfU01CVVNfV09SRF9EQVRBOiAKCQkJY2FzZSBJMkNfU01CVVNfUFJPQ19DQUxMOgoJCQkJZGF0YS0+d29yZCA9IG1zZ2J1ZjFbMF0gfCAobXNnYnVmMVsxXSA8PCA4KTsKCQkJCWJyZWFrOwoJCQljYXNlIEkyQ19TTUJVU19JMkNfQkxPQ0tfREFUQToKCQkJCS8qIGZpeGVkIGF0IDMyIGZvciBub3cgKi8KCQkJCWRhdGEtPmJsb2NrWzBdID0gSTJDX1NNQlVTX0kyQ19CTE9DS19NQVg7CgkJCQlmb3IgKGkgPSAwOyBpIDwgSTJDX1NNQlVTX0kyQ19CTE9DS19NQVg7IGkrKykKCQkJCQlkYXRhLT5ibG9ja1tpKzFdID0gbXNnYnVmMVtpXTsKCQkJCWJyZWFrOwoJCX0KCXJldHVybiAwOwp9CgoKczMyIGkyY19zbWJ1c194ZmVyKHN0cnVjdCBpMmNfYWRhcHRlciAqIGFkYXB0ZXIsIHUxNiBhZGRyLCB1bnNpZ25lZCBzaG9ydCBmbGFncywKICAgICAgICAgICAgICAgICAgIGNoYXIgcmVhZF93cml0ZSwgdTggY29tbWFuZCwgaW50IHNpemUsIAogICAgICAgICAgICAgICAgICAgdW5pb24gaTJjX3NtYnVzX2RhdGEgKiBkYXRhKQp7CglzMzIgcmVzOwoJaW50IHN3cGVjID0gMDsKCXU4IHBhcnRpYWwgPSAwOwoKCWZsYWdzICY9IEkyQ19NX1RFTiB8IEkyQ19DTElFTlRfUEVDOwoJaWYoKGZsYWdzICYgSTJDX0NMSUVOVF9QRUMpICYmCgkgICAhKGkyY19jaGVja19mdW5jdGlvbmFsaXR5KGFkYXB0ZXIsIEkyQ19GVU5DX1NNQlVTX0hXUEVDX0NBTEMpKSkgewoJCXN3cGVjID0gMTsKCQlpZihyZWFkX3dyaXRlID09IEkyQ19TTUJVU19SRUFEICYmCgkJICAgc2l6ZSA9PSBJMkNfU01CVVNfQkxPQ0tfREFUQSkKCQkJc2l6ZSA9IEkyQ19TTUJVU19CTE9DS19EQVRBX1BFQzsKCQllbHNlIGlmKHNpemUgPT0gSTJDX1NNQlVTX1BST0NfQ0FMTCkKCQkJc2l6ZSA9IEkyQ19TTUJVU19QUk9DX0NBTExfUEVDOwoJCWVsc2UgaWYoc2l6ZSA9PSBJMkNfU01CVVNfQkxPQ0tfUFJPQ19DQUxMKSB7CgkJCWkyY19zbWJ1c19hZGRfcGVjKGFkZHIsIGNvbW1hbmQsCgkJICAgICAgICAgICAgICAgICAgICAgICAgICBJMkNfU01CVVNfQkxPQ0tfREFUQSwgZGF0YSk7CgkJCXBhcnRpYWwgPSBkYXRhLT5ibG9ja1tkYXRhLT5ibG9ja1swXSArIDFdOwoJCQlzaXplID0gSTJDX1NNQlVTX0JMT0NLX1BST0NfQ0FMTF9QRUM7CgkJfSBlbHNlIGlmKHJlYWRfd3JpdGUgPT0gSTJDX1NNQlVTX1dSSVRFICYmCgkJICAgICAgICAgIHNpemUgIT0gSTJDX1NNQlVTX1FVSUNLICYmCgkJICAgICAgICAgIHNpemUgIT0gSTJDX1NNQlVTX0kyQ19CTE9DS19EQVRBKQoJCQlzaXplID0gaTJjX3NtYnVzX2FkZF9wZWMoYWRkciwgY29tbWFuZCwgc2l6ZSwgZGF0YSk7Cgl9CgoJaWYgKGFkYXB0ZXItPmFsZ28tPnNtYnVzX3hmZXIpIHsKCQlkb3duKCZhZGFwdGVyLT5idXNfbG9jayk7CgkJcmVzID0gYWRhcHRlci0+YWxnby0+c21idXNfeGZlcihhZGFwdGVyLGFkZHIsZmxhZ3MscmVhZF93cml0ZSwKCQkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbW1hbmQsc2l6ZSxkYXRhKTsKCQl1cCgmYWRhcHRlci0+YnVzX2xvY2spOwoJfSBlbHNlCgkJcmVzID0gaTJjX3NtYnVzX3hmZXJfZW11bGF0ZWQoYWRhcHRlcixhZGRyLGZsYWdzLHJlYWRfd3JpdGUsCgkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbW1hbmQsc2l6ZSxkYXRhKTsKCglpZihyZXMgPj0gMCAmJiBzd3BlYyAmJgoJICAgc2l6ZSAhPSBJMkNfU01CVVNfUVVJQ0sgJiYgc2l6ZSAhPSBJMkNfU01CVVNfSTJDX0JMT0NLX0RBVEEgJiYKCSAgIChyZWFkX3dyaXRlID09IEkyQ19TTUJVU19SRUFEIHx8IHNpemUgPT0gSTJDX1NNQlVTX1BST0NfQ0FMTF9QRUMgfHwKCSAgICBzaXplID09IEkyQ19TTUJVU19CTE9DS19QUk9DX0NBTExfUEVDKSkgewoJCWlmKGkyY19zbWJ1c19jaGVja19wZWMoYWRkciwgY29tbWFuZCwgc2l6ZSwgcGFydGlhbCwgZGF0YSkpCgkJCXJldHVybiAtMTsKCX0KCXJldHVybiByZXM7Cn0KCgpFWFBPUlRfU1lNQk9MKGkyY19hZGRfYWRhcHRlcik7CkVYUE9SVF9TWU1CT0woaTJjX2RlbF9hZGFwdGVyKTsKRVhQT1JUX1NZTUJPTChpMmNfYWRkX2RyaXZlcik7CkVYUE9SVF9TWU1CT0woaTJjX2RlbF9kcml2ZXIpOwpFWFBPUlRfU1lNQk9MKGkyY19hdHRhY2hfY2xpZW50KTsKRVhQT1JUX1NZTUJPTChpMmNfZGV0YWNoX2NsaWVudCk7CkVYUE9SVF9TWU1CT0woaTJjX3VzZV9jbGllbnQpOwpFWFBPUlRfU1lNQk9MKGkyY19yZWxlYXNlX2NsaWVudCk7CkVYUE9SVF9TWU1CT0woaTJjX2NsaWVudHNfY29tbWFuZCk7CkVYUE9SVF9TWU1CT0woaTJjX2NoZWNrX2FkZHIpOwoKRVhQT1JUX1NZTUJPTChpMmNfbWFzdGVyX3NlbmQpOwpFWFBPUlRfU1lNQk9MKGkyY19tYXN0ZXJfcmVjdik7CkVYUE9SVF9TWU1CT0woaTJjX2NvbnRyb2wpOwpFWFBPUlRfU1lNQk9MKGkyY190cmFuc2Zlcik7CkVYUE9SVF9TWU1CT0woaTJjX2FkYXB0ZXJfaWQpOwpFWFBPUlRfU1lNQk9MKGkyY19nZXRfYWRhcHRlcik7CkVYUE9SVF9TWU1CT0woaTJjX3B1dF9hZGFwdGVyKTsKRVhQT1JUX1NZTUJPTChpMmNfcHJvYmUpOwoKRVhQT1JUX1NZTUJPTChpMmNfc21idXNfeGZlcik7CkVYUE9SVF9TWU1CT0woaTJjX3NtYnVzX3dyaXRlX3F1aWNrKTsKRVhQT1JUX1NZTUJPTChpMmNfc21idXNfcmVhZF9ieXRlKTsKRVhQT1JUX1NZTUJPTChpMmNfc21idXNfd3JpdGVfYnl0ZSk7CkVYUE9SVF9TWU1CT0woaTJjX3NtYnVzX3JlYWRfYnl0ZV9kYXRhKTsKRVhQT1JUX1NZTUJPTChpMmNfc21idXNfd3JpdGVfYnl0ZV9kYXRhKTsKRVhQT1JUX1NZTUJPTChpMmNfc21idXNfcmVhZF93b3JkX2RhdGEpOwpFWFBPUlRfU1lNQk9MKGkyY19zbWJ1c193cml0ZV93b3JkX2RhdGEpOwpFWFBPUlRfU1lNQk9MKGkyY19zbWJ1c193cml0ZV9ibG9ja19kYXRhKTsKRVhQT1JUX1NZTUJPTChpMmNfc21idXNfcmVhZF9pMmNfYmxvY2tfZGF0YSk7CgpNT0RVTEVfQVVUSE9SKCJTaW1vbiBHLiBWb2dsIDxzaW1vbkB0ay51bmktbGluei5hYy5hdD4iKTsKTU9EVUxFX0RFU0NSSVBUSU9OKCJJMkMtQnVzIG1haW4gbW9kdWxlIik7Ck1PRFVMRV9MSUNFTlNFKCJHUEwiKTsK