LyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLwovKiBpMmMtaW9wM3h4LmMgaTJjIGRyaXZlciBhbGdvcml0aG1zIGZvciBJbnRlbCBYU2NhbGUgSU9QM3h4ICYgSVhQNDZ4ICAgICAgICovCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KLyogQ29weXJpZ2h0IChDKSAyMDAzIFBldGVyIE1pbG5lLCBELVRBQ1EgU29sdXRpb25zIEx0ZAogKiAgICAgICAgICAgICAgICAgICAgPFBldGVyIGRvdCBNaWxuZSBhdCBEIGh5cGhlbiBUQUNRIGRvdCBjb20+CiAqCiAqIFdpdGggYWNrbm93bGVkZ2VtZW50cyB0byBpMmMtYWxnby1pYm1fb2NwLmMgYnkgCiAqIElhbiBEYVNpbHZhLCBNb250YVZpc3RhIFNvZnR3YXJlLCBJbmMuIGlkYXNpbHZhQG12aXN0YS5jb20KICoKICogQW5kIGkyYy1hbGdvLXBjZi5jLCB3aGljaCB3YXMgY3JlYXRlZCBieSBTaW1vbiBHLiBWb2dsIGFuZCBIYW5zIEJlcmdsdW5kOgogKgogKiBDb3B5cmlnaHQgKEMpIDE5OTUtMTk5NyBTaW1vbiBHLiBWb2dsLCAxOTk4LTIwMDAgSGFucyBCZXJnbHVuZAogKiAgCiAqIEFuZCB3aGljaCBhY2tub3dsZWRnZWQgS3n2c3RpIE3kbGtraSA8a21hbGtraUBjYy5odXQuZmk+LAogKiBGcm9kbyBMb29pamFhcmQgPGZyb2RvbEBkZHMubmw+LCBNYXJ0aW4gQmFpbGV5PG1iYWlsZXlAbGl0dGxlZmVldC1pbmMuY29tPgogKgogKiBNYWpvciBjbGVhbnVwIGJ5IERlZXBhayBTYXhlbmEgPGRzYXhlbmFAcGxleGl0eS5uZXQ+LCAwMS8yMDA1OgogKgogKiAtIFVzZSBkcml2ZXIgbW9kZWwgdG8gcGFzcyBwZXItY2hpcCBpbmZvIGluc3RlYWQgb2YgaGFyZGNvZGluZyBhbmQgI2lmZGVmcwogKiAtIFVzZSBpb3JlbWFwL19fcmF3X3JlYWRsL19fcmF3X3dyaXRlbCBpbnN0ZWFkIG9mIGRpcmVjdCBkZXJlZmVyZW5jZQogKiAtIE1ha2UgaXQgd29yayB3aXRoIElYUDQ2eCBjaGlwcwogKiAtIENsZWFudXAgZnVuY3Rpb24gbmFtZXMsIGNvZGluZyBzdHlsZSwgZXRjCiAqCiAqIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5CiAqIGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5CiAqIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHZlcnNpb24gMi4KICovCgojaW5jbHVkZSA8bGludXgvY29uZmlnLmg+CiNpbmNsdWRlIDxsaW51eC9pbnRlcnJ1cHQuaD4KI2luY2x1ZGUgPGxpbnV4L2tlcm5lbC5oPgojaW5jbHVkZSA8bGludXgvbW9kdWxlLmg+CiNpbmNsdWRlIDxsaW51eC9kZWxheS5oPgojaW5jbHVkZSA8bGludXgvc2xhYi5oPgojaW5jbHVkZSA8bGludXgvaW5pdC5oPgojaW5jbHVkZSA8bGludXgvZXJybm8uaD4KI2luY2x1ZGUgPGxpbnV4L3NjaGVkLmg+CiNpbmNsdWRlIDxsaW51eC9kZXZpY2UuaD4KI2luY2x1ZGUgPGxpbnV4L2kyYy5oPgoKI2luY2x1ZGUgPGFzbS9pby5oPgoKI2luY2x1ZGUgImkyYy1pb3AzeHguaCIKCi8qIGdsb2JhbCB1bml0IGNvdW50ZXIgKi8Kc3RhdGljIGludCBpMmNfaWQgPSAwOwoKc3RhdGljIGlubGluZSB1bnNpZ25lZCBjaGFyIAppaWNfY29va19hZGRyKHN0cnVjdCBpMmNfbXNnICptc2cpIAp7Cgl1bnNpZ25lZCBjaGFyIGFkZHI7CgoJYWRkciA9IChtc2ctPmFkZHIgPDwgMSk7CgoJaWYgKG1zZy0+ZmxhZ3MgJiBJMkNfTV9SRCkKCQlhZGRyIHw9IDE7CgoJLyoKCSAqIFJlYWQgb3IgV3JpdGU/CgkgKi8KCWlmIChtc2ctPmZsYWdzICYgSTJDX01fUkVWX0RJUl9BRERSKQoJCWFkZHIgXj0gMTsKCglyZXR1cm4gYWRkcjsgICAKfQoKc3RhdGljIHZvaWQgCmlvcDN4eF9pMmNfcmVzZXQoc3RydWN0IGkyY19hbGdvX2lvcDN4eF9kYXRhICppb3AzeHhfYWRhcCkKewoJLyogRm9sbG93cyBkZXZtYW4gOS4zICovCglfX3Jhd193cml0ZWwoSU9QM1hYX0lDUl9VTklUX1JFU0VULCBpb3AzeHhfYWRhcC0+aW9hZGRyICsgQ1JfT0ZGU0VUKTsKCV9fcmF3X3dyaXRlbChJT1AzWFhfSVNSX0NMRUFSQklUUywgaW9wM3h4X2FkYXAtPmlvYWRkciArIFNSX09GRlNFVCk7CglfX3Jhd193cml0ZWwoMCwgaW9wM3h4X2FkYXAtPmlvYWRkciArIENSX09GRlNFVCk7Cn0gCgpzdGF0aWMgdm9pZCAKaW9wM3h4X2kyY19zZXRfc2xhdmVfYWRkcihzdHJ1Y3QgaTJjX2FsZ29faW9wM3h4X2RhdGEgKmlvcDN4eF9hZGFwKQp7CglfX3Jhd193cml0ZWwoTVlTQVIsIGlvcDN4eF9hZGFwLT5pb2FkZHIgKyBTQVJfT0ZGU0VUKTsKfQoKc3RhdGljIHZvaWQgCmlvcDN4eF9pMmNfZW5hYmxlKHN0cnVjdCBpMmNfYWxnb19pb3AzeHhfZGF0YSAqaW9wM3h4X2FkYXApCnsKCXUzMiBjciA9IElPUDNYWF9JQ1JfR0NEIHwgSU9QM1hYX0lDUl9TQ0xFTiB8IElPUDNYWF9JQ1JfVUU7CgoJLyogCgkgKiBFdmVyeSB0aW1lIHVuaXQgZW5hYmxlIGlzIGFzc2VydGVkLCBHUE9EIG5lZWRzIHRvIGJlIGNsZWFyZWQKCSAqIG9uIElPUDMyMSB0byBhdm9pZCBkYXRhIGNvcnJ1cHRpb24gb24gdGhlIGJ1cy4KCSAqLwojaWZkZWYgQ09ORklHX0FSQ0hfSU9QMzIxCiNkZWZpbmUgSU9QMzIxX0dQT0RfSTJDMCAgICAweDAwYzAgIC8qIGNsZWFyIHRoZXNlIGJpdHMgdG8gZW5hYmxlIGNoMCAqLwojZGVmaW5lIElPUDMyMV9HUE9EX0kyQzEgICAgMHgwMDMwICAvKiBjbGVhciB0aGVzZSBiaXRzIHRvIGVuYWJsZSBjaDEgKi8KCgkqSU9QMzIxX0dQT0QgJj0gKGlvcDN4eF9hZGFwLT5pZCA9PSAwKSA/IH5JT1AzMjFfR1BPRF9JMkMwIDogCgkJfklPUDMyMV9HUE9EX0kyQzE7CiNlbmRpZgoJLyogTkIgU1IgYml0cyBub3Qgc2FtZSBwb3NpdGlvbiBhcyBDUiBJRSBiaXRzIDotKCAqLwoJaW9wM3h4X2FkYXAtPlNSX2VuYWJsZWQgPSAKCQlJT1AzWFhfSVNSX0FMRCB8IElPUDNYWF9JU1JfQkVSUkQgfAoJCUlPUDNYWF9JU1JfUlhGVUxMIHwgSU9QM1hYX0lTUl9UWEVNUFRZOwoKCWNyIHw9IElPUDNYWF9JQ1JfQUxEX0lFIHwgSU9QM1hYX0lDUl9CRVJSX0lFIHwKCQlJT1AzWFhfSUNSX1JYRlVMTF9JRSB8IElPUDNYWF9JQ1JfVFhFTVBUWV9JRTsKCglfX3Jhd193cml0ZWwoY3IsIGlvcDN4eF9hZGFwLT5pb2FkZHIgKyBDUl9PRkZTRVQpOwp9CgpzdGF0aWMgdm9pZCAKaW9wM3h4X2kyY190cmFuc2FjdGlvbl9jbGVhbnVwKHN0cnVjdCBpMmNfYWxnb19pb3AzeHhfZGF0YSAqaW9wM3h4X2FkYXApCnsKCXVuc2lnbmVkIGxvbmcgY3IgPSBfX3Jhd19yZWFkbChpb3AzeHhfYWRhcC0+aW9hZGRyICsgQ1JfT0ZGU0VUKTsKCQoJY3IgJj0gfihJT1AzWFhfSUNSX01TVEFSVCB8IElPUDNYWF9JQ1JfVEJZVEUgfCAKCQlJT1AzWFhfSUNSX01TVE9QIHwgSU9QM1hYX0lDUl9TQ0xFTik7CgoJX19yYXdfd3JpdGVsKGNyLCBpb3AzeHhfYWRhcC0+aW9hZGRyICsgQ1JfT0ZGU0VUKTsKfQoKLyogCiAqIE5COiB0aGUgaGFuZGxlciBoYXMgdG8gY2xlYXIgdGhlIHNvdXJjZSBvZiB0aGUgaW50ZXJydXB0ISAKICogVGhlbiBpdCBwYXNzZXMgdGhlIFNSIGZsYWdzIG9mIGludGVyZXN0IHRvIEJIIHZpYSBhZGFwIGRhdGEKICovCnN0YXRpYyBpcnFyZXR1cm5fdCAKaW9wM3h4X2kyY19pcnFfaGFuZGxlcihpbnQgdGhpc19pcnEsIHZvaWQgKmRldl9pZCwgc3RydWN0IHB0X3JlZ3MgKnJlZ3MpIAp7CglzdHJ1Y3QgaTJjX2FsZ29faW9wM3h4X2RhdGEgKmlvcDN4eF9hZGFwID0gZGV2X2lkOwoJdTMyIHNyID0gX19yYXdfcmVhZGwoaW9wM3h4X2FkYXAtPmlvYWRkciArIFNSX09GRlNFVCk7CgoJaWYgKChzciAmPSBpb3AzeHhfYWRhcC0+U1JfZW5hYmxlZCkpIHsKCQlfX3Jhd193cml0ZWwoc3IsIGlvcDN4eF9hZGFwLT5pb2FkZHIgKyBTUl9PRkZTRVQpOwoJCWlvcDN4eF9hZGFwLT5TUl9yZWNlaXZlZCB8PSBzcjsKCQl3YWtlX3VwX2ludGVycnVwdGlibGUoJmlvcDN4eF9hZGFwLT53YWl0cSk7Cgl9CglyZXR1cm4gSVJRX0hBTkRMRUQ7Cn0KCi8qIGNoZWNrIGFsbCBlcnJvciBjb25kaXRpb25zLCBjbGVhciB0aGVtICwgcmVwb3J0IG1vc3QgaW1wb3J0YW50ICovCnN0YXRpYyBpbnQgCmlvcDN4eF9pMmNfZXJyb3IodTMyIHNyKQp7CglpbnQgcmMgPSAwOwoKCWlmICgoc3IgJiBJT1AzWFhfSVNSX0JFUlJEKSkgewoJCWlmICggIXJjICkgcmMgPSAtSTJDX0VSUl9CRVJSOwoJfQoJaWYgKChzciAmIElPUDNYWF9JU1JfQUxEKSkgewoJCWlmICggIXJjICkgcmMgPSAtSTJDX0VSUl9BTEQ7CQkKCX0KCXJldHVybiByYzsJCn0KCnN0YXRpYyBpbmxpbmUgdTMyIAppb3AzeHhfaTJjX2dldF9zcnN0YXQoc3RydWN0IGkyY19hbGdvX2lvcDN4eF9kYXRhICppb3AzeHhfYWRhcCkKewoJdW5zaWduZWQgbG9uZyBmbGFnczsKCXUzMiBzcjsKCglzcGluX2xvY2tfaXJxc2F2ZSgmaW9wM3h4X2FkYXAtPmxvY2ssIGZsYWdzKTsKCXNyID0gaW9wM3h4X2FkYXAtPlNSX3JlY2VpdmVkOwoJaW9wM3h4X2FkYXAtPlNSX3JlY2VpdmVkID0gMDsKCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJmlvcDN4eF9hZGFwLT5sb2NrLCBmbGFncyk7CgoJcmV0dXJuIHNyOwp9CgovKgogKiBzbGVlcCB1bnRpbCBpbnRlcnJ1cHRlZCwgdGhlbiByZWNvdmVyIGFuZCBhbmFseXNlIHRoZSBTUgogKiBzYXZlZCBieSBoYW5kbGVyCiAqLwp0eXBlZGVmIGludCAoKiBjb21wYXJlX2Z1bmMpKHVuc2lnbmVkIHRlc3QsIHVuc2lnbmVkIG1hc2spOwovKiByZXR1cm5zIDEgb24gY29ycmVjdCBjb21wYXJpc29uICovCgpzdGF0aWMgaW50IAppb3AzeHhfaTJjX3dhaXRfZXZlbnQoc3RydWN0IGkyY19hbGdvX2lvcDN4eF9kYXRhICppb3AzeHhfYWRhcCwgCgkJCSAgdW5zaWduZWQgZmxhZ3MsIHVuc2lnbmVkKiBzdGF0dXMsCgkJCSAgY29tcGFyZV9mdW5jIGNvbXBhcmUpCnsKCXVuc2lnbmVkIHNyID0gMDsKCWludCBpbnRlcnJ1cHRlZDsKCWludCBkb25lOwoJaW50IHJjID0gMDsKCglkbyB7CgkJaW50ZXJydXB0ZWQgPSB3YWl0X2V2ZW50X2ludGVycnVwdGlibGVfdGltZW91dCAoCgkJCWlvcDN4eF9hZGFwLT53YWl0cSwKCQkJKGRvbmUgPSBjb21wYXJlKCBzciA9IGlvcDN4eF9pMmNfZ2V0X3Nyc3RhdChpb3AzeHhfYWRhcCkJCQkJCSxmbGFncyApKSwKCQkJMSAqIEhaOwoJCQkpOwoJCWlmICgocmMgPSBpb3AzeHhfaTJjX2Vycm9yKHNyKSkgPCAwKSB7CgkJCSpzdGF0dXMgPSBzcjsKCQkJcmV0dXJuIHJjOwoJCX0gZWxzZSBpZiAoIWludGVycnVwdGVkKSB7CgkJCSpzdGF0dXMgPSBzcjsKCQkJcmV0dXJuIC1FVElNRURPVVQ7CgkJfQoJfSB3aGlsZSghZG9uZSk7CgoJKnN0YXR1cyA9IHNyOwoKCXJldHVybiAwOwp9CgovKgogKiBDb25jcmV0ZSBjb21wYXJlX2Z1bmNzIAogKi8Kc3RhdGljIGludCAKYWxsX2JpdHNfY2xlYXIodW5zaWduZWQgdGVzdCwgdW5zaWduZWQgbWFzaykKewoJcmV0dXJuICh0ZXN0ICYgbWFzaykgPT0gMDsKfQoKc3RhdGljIGludCAKYW55X2JpdHNfc2V0KHVuc2lnbmVkIHRlc3QsIHVuc2lnbmVkIG1hc2spCnsKCXJldHVybiAodGVzdCAmIG1hc2spICE9IDA7Cn0KCnN0YXRpYyBpbnQgCmlvcDN4eF9pMmNfd2FpdF90eF9kb25lKHN0cnVjdCBpMmNfYWxnb19pb3AzeHhfZGF0YSAqaW9wM3h4X2FkYXAsIGludCAqc3RhdHVzKQp7CglyZXR1cm4gaW9wM3h4X2kyY193YWl0X2V2ZW50KCAKCQlpb3AzeHhfYWRhcCwgCgkgICAgICAgIElPUDNYWF9JU1JfVFhFTVBUWSB8IElPUDNYWF9JU1JfQUxEIHwgSU9QM1hYX0lTUl9CRVJSRCwKCQlzdGF0dXMsIGFueV9iaXRzX3NldCk7Cn0KCnN0YXRpYyBpbnQgCmlvcDN4eF9pMmNfd2FpdF9yeF9kb25lKHN0cnVjdCBpMmNfYWxnb19pb3AzeHhfZGF0YSAqaW9wM3h4X2FkYXAsIGludCAqc3RhdHVzKQp7CglyZXR1cm4gaW9wM3h4X2kyY193YWl0X2V2ZW50KCAKCQlpb3AzeHhfYWRhcCwgCgkJSU9QM1hYX0lTUl9SWEZVTEwgfCBJT1AzWFhfSVNSX0FMRCB8IElPUDNYWF9JU1JfQkVSUkQsCgkJc3RhdHVzLAlhbnlfYml0c19zZXQpOwp9CgpzdGF0aWMgaW50IAppb3AzeHhfaTJjX3dhaXRfaWRsZShzdHJ1Y3QgaTJjX2FsZ29faW9wM3h4X2RhdGEgKmlvcDN4eF9hZGFwLCBpbnQgKnN0YXR1cykKewoJcmV0dXJuIGlvcDN4eF9pMmNfd2FpdF9ldmVudCggCgkJaW9wM3h4X2FkYXAsIElPUDNYWF9JU1JfVU5JVEJVU1ksIHN0YXR1cywgYWxsX2JpdHNfY2xlYXIpOwp9CgpzdGF0aWMgaW50IAppb3AzeHhfaTJjX3NlbmRfdGFyZ2V0X2FkZHIoc3RydWN0IGkyY19hbGdvX2lvcDN4eF9kYXRhICppb3AzeHhfYWRhcCwgCgkJCQlzdHJ1Y3QgaTJjX21zZyogbXNnKQp7Cgl1bnNpZ25lZCBsb25nIGNyID0gX19yYXdfcmVhZGwoaW9wM3h4X2FkYXAtPmlvYWRkciArIENSX09GRlNFVCk7CglpbnQgc3RhdHVzOwoJaW50IHJjOwoKCV9fcmF3X3dyaXRlbChpaWNfY29va19hZGRyKG1zZyksIGlvcDN4eF9hZGFwLT5pb2FkZHIgKyBEQlJfT0ZGU0VUKTsKCQoJY3IgJj0gfihJT1AzWFhfSUNSX01TVE9QIHwgSU9QM1hYX0lDUl9OQUNLKTsKCWNyIHw9IElPUDNYWF9JQ1JfTVNUQVJUIHwgSU9QM1hYX0lDUl9UQllURTsKCglfX3Jhd193cml0ZWwoY3IsIGlvcDN4eF9hZGFwLT5pb2FkZHIgKyBDUl9PRkZTRVQpOwoJcmMgPSBpb3AzeHhfaTJjX3dhaXRfdHhfZG9uZShpb3AzeHhfYWRhcCwgJnN0YXR1cyk7CgoJcmV0dXJuIHJjOwp9CgpzdGF0aWMgaW50IAppb3AzeHhfaTJjX3dyaXRlX2J5dGUoc3RydWN0IGkyY19hbGdvX2lvcDN4eF9kYXRhICppb3AzeHhfYWRhcCwgY2hhciBieXRlLCAKCQkJCWludCBzdG9wKQp7Cgl1bnNpZ25lZCBsb25nIGNyID0gX19yYXdfcmVhZGwoaW9wM3h4X2FkYXAtPmlvYWRkciArIENSX09GRlNFVCk7CglpbnQgc3RhdHVzOwoJaW50IHJjID0gMDsKCglfX3Jhd193cml0ZWwoYnl0ZSwgaW9wM3h4X2FkYXAtPmlvYWRkciArIERCUl9PRkZTRVQpOwoJY3IgJj0gfklPUDNYWF9JQ1JfTVNUQVJUOwoJaWYgKHN0b3ApIHsKCQljciB8PSBJT1AzWFhfSUNSX01TVE9QOwoJfSBlbHNlIHsKCQljciAmPSB+SU9QM1hYX0lDUl9NU1RPUDsKCX0KCWNyIHw9IElPUDNYWF9JQ1JfVEJZVEU7CglfX3Jhd193cml0ZWwoY3IsIGlvcDN4eF9hZGFwLT5pb2FkZHIgKyBDUl9PRkZTRVQpOwoJcmMgPSBpb3AzeHhfaTJjX3dhaXRfdHhfZG9uZShpb3AzeHhfYWRhcCwgJnN0YXR1cyk7CgoJcmV0dXJuIHJjOwp9IAoKc3RhdGljIGludCAKaW9wM3h4X2kyY19yZWFkX2J5dGUoc3RydWN0IGkyY19hbGdvX2lvcDN4eF9kYXRhICppb3AzeHhfYWRhcCwgY2hhciogYnl0ZSwgCgkJCQlpbnQgc3RvcCkKewoJdW5zaWduZWQgbG9uZyBjciA9IF9fcmF3X3JlYWRsKGlvcDN4eF9hZGFwLT5pb2FkZHIgKyBDUl9PRkZTRVQpOwoJaW50IHN0YXR1czsKCWludCByYyA9IDA7CgoJY3IgJj0gfklPUDNYWF9JQ1JfTVNUQVJUOwoKCWlmIChzdG9wKSB7CgkJY3IgfD0gSU9QM1hYX0lDUl9NU1RPUCB8IElPUDNYWF9JQ1JfTkFDSzsKCX0gZWxzZSB7CgkJY3IgJj0gfihJT1AzWFhfSUNSX01TVE9QIHwgSU9QM1hYX0lDUl9OQUNLKTsKCX0KCWNyIHw9IElPUDNYWF9JQ1JfVEJZVEU7CglfX3Jhd193cml0ZWwoY3IsIGlvcDN4eF9hZGFwLT5pb2FkZHIgKyBDUl9PRkZTRVQpOwoKCXJjID0gaW9wM3h4X2kyY193YWl0X3J4X2RvbmUoaW9wM3h4X2FkYXAsICZzdGF0dXMpOwoKCSpieXRlID0gX19yYXdfcmVhZGwoaW9wM3h4X2FkYXAtPmlvYWRkciArIERCUl9PRkZTRVQpOwoKCXJldHVybiByYzsKfQoKc3RhdGljIGludCAKaW9wM3h4X2kyY193cml0ZWJ5dGVzKHN0cnVjdCBpMmNfYWRhcHRlciAqaTJjX2FkYXAsIGNvbnN0IGNoYXIgKmJ1ZiwgaW50IGNvdW50KQp7CglzdHJ1Y3QgaTJjX2FsZ29faW9wM3h4X2RhdGEgKmlvcDN4eF9hZGFwID0gaTJjX2FkYXAtPmFsZ29fZGF0YTsKCWludCBpaTsKCWludCByYyA9IDA7CgoJZm9yIChpaSA9IDA7IHJjID09IDAgJiYgaWkgIT0gY291bnQ7ICsraWkpIAoJCXJjID0gaW9wM3h4X2kyY193cml0ZV9ieXRlKGlvcDN4eF9hZGFwLCBidWZbaWldLCBpaT09Y291bnQtMSk7CglyZXR1cm4gcmM7Cn0KCnN0YXRpYyBpbnQgCmlvcDN4eF9pMmNfcmVhZGJ5dGVzKHN0cnVjdCBpMmNfYWRhcHRlciAqaTJjX2FkYXAsIGNoYXIgKmJ1ZiwgaW50IGNvdW50KQp7CglzdHJ1Y3QgaTJjX2FsZ29faW9wM3h4X2RhdGEgKmlvcDN4eF9hZGFwID0gaTJjX2FkYXAtPmFsZ29fZGF0YTsKCWludCBpaTsKCWludCByYyA9IDA7CgoJZm9yIChpaSA9IDA7IHJjID09IDAgJiYgaWkgIT0gY291bnQ7ICsraWkpCgkJcmMgPSBpb3AzeHhfaTJjX3JlYWRfYnl0ZShpb3AzeHhfYWRhcCwgJmJ1ZltpaV0sIGlpPT1jb3VudC0xKTsKCQoJcmV0dXJuIHJjOwp9CgovKgogKiBEZXNjcmlwdGlvbjogIFRoaXMgZnVuY3Rpb24gaW1wbGVtZW50cyBjb21iaW5lZCB0cmFuc2FjdGlvbnMuICBDb21iaW5lZAogKiB0cmFuc2FjdGlvbnMgY29uc2lzdCBvZiBjb21iaW5hdGlvbnMgb2YgcmVhZGluZyBhbmQgd3JpdGluZyBibG9ja3Mgb2YgZGF0YS4KICogRlJPTSBUSEUgU0FNRSBBRERSRVNTCiAqIEVhY2ggdHJhbnNmZXIgKGkuZS4gYSByZWFkIG9yIGEgd3JpdGUpIGlzIHNlcGFyYXRlZCBieSBhIHJlcGVhdGVkIHN0YXJ0CiAqIGNvbmRpdGlvbi4KICovCnN0YXRpYyBpbnQgCmlvcDN4eF9pMmNfaGFuZGxlX21zZyhzdHJ1Y3QgaTJjX2FkYXB0ZXIgKmkyY19hZGFwLCBzdHJ1Y3QgaTJjX21zZyogcG1zZykgCnsKCXN0cnVjdCBpMmNfYWxnb19pb3AzeHhfZGF0YSAqaW9wM3h4X2FkYXAgPSBpMmNfYWRhcC0+YWxnb19kYXRhOwoJaW50IHJjOwoKCXJjID0gaW9wM3h4X2kyY19zZW5kX3RhcmdldF9hZGRyKGlvcDN4eF9hZGFwLCBwbXNnKTsKCWlmIChyYyA8IDApIHsKCQlyZXR1cm4gcmM7Cgl9CgoJaWYgKChwbXNnLT5mbGFncyZJMkNfTV9SRCkpIHsKCQlyZXR1cm4gaW9wM3h4X2kyY19yZWFkYnl0ZXMoaTJjX2FkYXAsIHBtc2ctPmJ1ZiwgcG1zZy0+bGVuKTsKCX0gZWxzZSB7CgkJcmV0dXJuIGlvcDN4eF9pMmNfd3JpdGVieXRlcyhpMmNfYWRhcCwgcG1zZy0+YnVmLCBwbXNnLT5sZW4pOwoJfQp9CgovKgogKiBtYXN0ZXJfeGZlcigpIC0gbWFpbiByZWFkL3dyaXRlIGVudHJ5CiAqLwpzdGF0aWMgaW50IAppb3AzeHhfaTJjX21hc3Rlcl94ZmVyKHN0cnVjdCBpMmNfYWRhcHRlciAqaTJjX2FkYXAsIHN0cnVjdCBpMmNfbXNnICptc2dzLCAKCQkJCWludCBudW0pCnsKCXN0cnVjdCBpMmNfYWxnb19pb3AzeHhfZGF0YSAqaW9wM3h4X2FkYXAgPSBpMmNfYWRhcC0+YWxnb19kYXRhOwoJaW50IGltID0gMDsKCWludCByZXQgPSAwOwoJaW50IHN0YXR1czsKCglpb3AzeHhfaTJjX3dhaXRfaWRsZShpb3AzeHhfYWRhcCwgJnN0YXR1cyk7Cglpb3AzeHhfaTJjX3Jlc2V0KGlvcDN4eF9hZGFwKTsKCWlvcDN4eF9pMmNfZW5hYmxlKGlvcDN4eF9hZGFwKTsKCglmb3IgKGltID0gMDsgcmV0ID09IDAgJiYgaW0gIT0gbnVtOyBpbSsrKSB7CgkJcmV0ID0gaW9wM3h4X2kyY19oYW5kbGVfbXNnKGkyY19hZGFwLCAmbXNnc1tpbV0pOwoJfQoKCWlvcDN4eF9pMmNfdHJhbnNhY3Rpb25fY2xlYW51cChpb3AzeHhfYWRhcCk7CgkKCWlmKHJldCkKCQlyZXR1cm4gcmV0OwoKCXJldHVybiBpbTsgICAKfQoKc3RhdGljIGludCAKaW9wM3h4X2kyY19hbGdvX2NvbnRyb2woc3RydWN0IGkyY19hZGFwdGVyICphZGFwdGVyLCB1bnNpZ25lZCBpbnQgY21kLAoJCQl1bnNpZ25lZCBsb25nIGFyZykKewoJcmV0dXJuIDA7Cn0KCnN0YXRpYyB1MzIgCmlvcDN4eF9pMmNfZnVuYyhzdHJ1Y3QgaTJjX2FkYXB0ZXIgKmFkYXApCnsKCXJldHVybiBJMkNfRlVOQ19JMkMgfCBJMkNfRlVOQ19TTUJVU19FTVVMOwp9CgpzdGF0aWMgc3RydWN0IGkyY19hbGdvcml0aG0gaW9wM3h4X2kyY19hbGdvID0gewoJLm5hbWUJCT0gIklPUDN4eCBJMkMgYWxnb3JpdGhtIiwKCS5pZAkJPSBJMkNfQUxHT19JT1AzWFgsCgkubWFzdGVyX3hmZXIJPSBpb3AzeHhfaTJjX21hc3Rlcl94ZmVyLAoJLmFsZ29fY29udHJvbAk9IGlvcDN4eF9pMmNfYWxnb19jb250cm9sLAoJLmZ1bmN0aW9uYWxpdHkJPSBpb3AzeHhfaTJjX2Z1bmMsCn07CgpzdGF0aWMgaW50IAppb3AzeHhfaTJjX3JlbW92ZShzdHJ1Y3QgZGV2aWNlICpkZXZpY2UpCnsKCXN0cnVjdCBwbGF0Zm9ybV9kZXZpY2UgKnBkZXYgPSB0b19wbGF0Zm9ybV9kZXZpY2UoZGV2aWNlKTsKCXN0cnVjdCBpMmNfYWRhcHRlciAqcGFkYXB0ZXIgPSBkZXZfZ2V0X2RydmRhdGEoJnBkZXYtPmRldik7CglzdHJ1Y3QgaTJjX2FsZ29faW9wM3h4X2RhdGEgKmFkYXB0ZXJfZGF0YSA9IAoJCShzdHJ1Y3QgaTJjX2FsZ29faW9wM3h4X2RhdGEgKilwYWRhcHRlci0+YWxnb19kYXRhOwoJc3RydWN0IHJlc291cmNlICpyZXMgPSBwbGF0Zm9ybV9nZXRfcmVzb3VyY2UocGRldiwgSU9SRVNPVVJDRV9NRU0sIDApOwoJdW5zaWduZWQgbG9uZyBjciA9IF9fcmF3X3JlYWRsKGFkYXB0ZXJfZGF0YS0+aW9hZGRyICsgQ1JfT0ZGU0VUKTsKCgkvKgoJICogRGlzYWJsZSB0aGUgYWN0dWFsIEhXIHVuaXQKCSAqLwoJY3IgJj0gfihJT1AzWFhfSUNSX0FMRF9JRSB8IElPUDNYWF9JQ1JfQkVSUl9JRSB8CgkJSU9QM1hYX0lDUl9SWEZVTExfSUUgfCBJT1AzWFhfSUNSX1RYRU1QVFlfSUUpOwoJX19yYXdfd3JpdGVsKGNyLCBhZGFwdGVyX2RhdGEtPmlvYWRkciArIENSX09GRlNFVCk7CgoJaW91bm1hcCgodm9pZCBfX2lvbWVtKilhZGFwdGVyX2RhdGEtPmlvYWRkcik7CglyZWxlYXNlX21lbV9yZWdpb24ocmVzLT5zdGFydCwgSU9QM1hYX0kyQ19JT19TSVpFKTsKCWtmcmVlKGFkYXB0ZXJfZGF0YSk7CglrZnJlZShwYWRhcHRlcik7CgoJZGV2X3NldF9kcnZkYXRhKCZwZGV2LT5kZXYsIE5VTEwpOwoKCXJldHVybiAwOwp9CgpzdGF0aWMgaW50IAppb3AzeHhfaTJjX3Byb2JlKHN0cnVjdCBkZXZpY2UgKmRldikKewoJc3RydWN0IHBsYXRmb3JtX2RldmljZSAqcGRldiA9IHRvX3BsYXRmb3JtX2RldmljZShkZXYpOwoJc3RydWN0IHJlc291cmNlICpyZXM7CglpbnQgcmV0OwoJc3RydWN0IGkyY19hZGFwdGVyICpuZXdfYWRhcHRlcjsKCXN0cnVjdCBpMmNfYWxnb19pb3AzeHhfZGF0YSAqYWRhcHRlcl9kYXRhOwoKCW5ld19hZGFwdGVyID0ga21hbGxvYyhzaXplb2Yoc3RydWN0IGkyY19hZGFwdGVyKSwgR0ZQX0tFUk5FTCk7CglpZiAoIW5ld19hZGFwdGVyKSB7CgkJcmV0ID0gLUVOT01FTTsKCQlnb3RvIG91dDsKCX0KCW1lbXNldCgodm9pZCopbmV3X2FkYXB0ZXIsIDAsIHNpemVvZigqbmV3X2FkYXB0ZXIpKTsKCglhZGFwdGVyX2RhdGEgPSBrbWFsbG9jKHNpemVvZihzdHJ1Y3QgaTJjX2FsZ29faW9wM3h4X2RhdGEpLCBHRlBfS0VSTkVMKTsKCWlmICghYWRhcHRlcl9kYXRhKSB7CgkJcmV0ID0gLUVOT01FTTsKCQlnb3RvIGZyZWVfYWRhcHRlcjsKCX0KCW1lbXNldCgodm9pZCopYWRhcHRlcl9kYXRhLCAwLCBzaXplb2YoKmFkYXB0ZXJfZGF0YSkpOwoKCXJlcyA9IHBsYXRmb3JtX2dldF9yZXNvdXJjZShwZGV2LCBJT1JFU09VUkNFX01FTSwgMCk7CglpZiAoIXJlcykgewoJCXJldCA9IC1FTk9ERVY7CgkJZ290byBmcmVlX2JvdGg7Cgl9CgoJaWYgKCFyZXF1ZXN0X21lbV9yZWdpb24ocmVzLT5zdGFydCwgSU9QM1hYX0kyQ19JT19TSVpFLCBwZGV2LT5uYW1lKSkgewoJCXJldCA9IC1FQlVTWTsKCQlnb3RvIGZyZWVfYm90aDsKCX0KCgkvKiBzZXQgdGhlIGFkYXB0ZXIgZW51bWVyYXRpb24gIyAqLwoJYWRhcHRlcl9kYXRhLT5pZCA9IGkyY19pZCsrOwoKCWFkYXB0ZXJfZGF0YS0+aW9hZGRyID0gKHUzMilpb3JlbWFwKHJlcy0+c3RhcnQsIElPUDNYWF9JMkNfSU9fU0laRSk7CglpZiAoIWFkYXB0ZXJfZGF0YS0+aW9hZGRyKSB7CgkJcmV0ID0gLUVOT01FTTsKCQlnb3RvIHJlbGVhc2VfcmVnaW9uOwoJfQoKCXJlcyA9IHJlcXVlc3RfaXJxKHBsYXRmb3JtX2dldF9pcnEocGRldiwgMCksIGlvcDN4eF9pMmNfaXJxX2hhbmRsZXIsIDAsIAoJCQkJcGRldi0+bmFtZSwgYWRhcHRlcl9kYXRhKTsKCWlmIChyZXMpIHsKCQlyZXQgPSAtRUlPOwoJCWdvdG8gdW5tYXA7Cgl9CgoJbWVtY3B5KG5ld19hZGFwdGVyLT5uYW1lLCBwZGV2LT5uYW1lLCBzdHJsZW4ocGRldi0+bmFtZSkpOwoJbmV3X2FkYXB0ZXItPmlkID0gSTJDX0hXX0lPUDNYWDsKCW5ld19hZGFwdGVyLT5vd25lciA9IFRISVNfTU9EVUxFOwoJbmV3X2FkYXB0ZXItPmRldi5wYXJlbnQgPSAmcGRldi0+ZGV2OwoKCS8qCgkgKiBEZWZhdWx0IHZhbHVlcy4uLnNob3VsZCB0aGVzZSBjb21lIGluIGZyb20gYm9hcmQgY29kZT8KCSAqLwoJbmV3X2FkYXB0ZXItPnRpbWVvdXQgPSAxMDA7CQoJbmV3X2FkYXB0ZXItPnJldHJpZXMgPSAzOwoJbmV3X2FkYXB0ZXItPmFsZ28gPSAmaW9wM3h4X2kyY19hbGdvOwoKCWluaXRfd2FpdHF1ZXVlX2hlYWQoJmFkYXB0ZXJfZGF0YS0+d2FpdHEpOwoJc3Bpbl9sb2NrX2luaXQoJmFkYXB0ZXJfZGF0YS0+bG9jayk7CgoJaW9wM3h4X2kyY19yZXNldChhZGFwdGVyX2RhdGEpOwoJaW9wM3h4X2kyY19zZXRfc2xhdmVfYWRkcihhZGFwdGVyX2RhdGEpOwoJaW9wM3h4X2kyY19lbmFibGUoYWRhcHRlcl9kYXRhKTsKCglkZXZfc2V0X2RydmRhdGEoJnBkZXYtPmRldiwgbmV3X2FkYXB0ZXIpOwoJbmV3X2FkYXB0ZXItPmFsZ29fZGF0YSA9IGFkYXB0ZXJfZGF0YTsKCglpMmNfYWRkX2FkYXB0ZXIobmV3X2FkYXB0ZXIpOwoKCXJldHVybiAwOwoKdW5tYXA6Cglpb3VubWFwKCh2b2lkIF9faW9tZW0qKWFkYXB0ZXJfZGF0YS0+aW9hZGRyKTsKCnJlbGVhc2VfcmVnaW9uOgoJcmVsZWFzZV9tZW1fcmVnaW9uKHJlcy0+c3RhcnQsIElPUDNYWF9JMkNfSU9fU0laRSk7CgpmcmVlX2JvdGg6CglrZnJlZShhZGFwdGVyX2RhdGEpOwoKZnJlZV9hZGFwdGVyOgoJa2ZyZWUobmV3X2FkYXB0ZXIpOwoKb3V0OgoJcmV0dXJuIHJldDsKfQoKCnN0YXRpYyBzdHJ1Y3QgZGV2aWNlX2RyaXZlciBpb3AzeHhfaTJjX2RyaXZlciA9IHsKCS5uYW1lCQk9ICJJT1AzeHgtSTJDIiwKCS5idXMJCT0gJnBsYXRmb3JtX2J1c190eXBlLAoJLnByb2JlCQk9IGlvcDN4eF9pMmNfcHJvYmUsCgkucmVtb3ZlCQk9IGlvcDN4eF9pMmNfcmVtb3ZlCn07CgpzdGF0aWMgaW50IF9faW5pdCAKaTJjX2lvcDN4eF9pbml0ICh2b2lkKQp7CglyZXR1cm4gZHJpdmVyX3JlZ2lzdGVyKCZpb3AzeHhfaTJjX2RyaXZlcik7Cn0KCnN0YXRpYyB2b2lkIF9fZXhpdCAKaTJjX2lvcDN4eF9leGl0ICh2b2lkKQp7Cglkcml2ZXJfdW5yZWdpc3RlcigmaW9wM3h4X2kyY19kcml2ZXIpOwoJcmV0dXJuOwp9Cgptb2R1bGVfaW5pdCAoaTJjX2lvcDN4eF9pbml0KTsKbW9kdWxlX2V4aXQgKGkyY19pb3AzeHhfZXhpdCk7CgpNT0RVTEVfQVVUSE9SKCJELVRBQ1EgU29sdXRpb25zIEx0ZCA8d3d3LmQtdGFjcS5jb20+Iik7Ck1PRFVMRV9ERVNDUklQVElPTigiSU9QM3h4IGlpYyBhbGdvcml0aG0gYW5kIGRyaXZlciIpOwpNT0RVTEVfTElDRU5TRSgiR1BMIik7Cg==