LyoKICogQ29weXJpZ2h0IChjKSBJbnRlbCBDb3JwLiAyMDA3LgogKiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKgogKiBJbnRlbCBmdW5kZWQgVHVuZ3N0ZW4gR3JhcGhpY3MgKGh0dHA6Ly93d3cudHVuZ3N0ZW5ncmFwaGljcy5jb20pIHRvCiAqIGRldmVsb3AgdGhpcyBkcml2ZXIuCiAqCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBWZXJtaWxpb24gUmFuZ2UgZmIgZHJpdmVyLgogKiBUaGUgVmVybWlsaW9uIFJhbmdlIGZiIGRyaXZlciBpcyBmcmVlIHNvZnR3YXJlOwogKiB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5CiAqIGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5CiAqIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlciB2ZXJzaW9uIDIgb2YgdGhlIExpY2Vuc2UsIG9yCiAqIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoZSBWZXJtaWxpb24gUmFuZ2UgZmIgZHJpdmVyIGlzIGRpc3RyaWJ1dGVkCiAqIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsCiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUKICogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogYWxvbmcgd2l0aCB0aGlzIGRyaXZlcjsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZQogKiBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgIDAyMTEwLTEzMDEgIFVTQQogKgogKiBBdXRob3JzOgogKiAgIFRob21hcyBIZWxsc3Ry9m0gPHRob21hcy1hdC10dW5nc3RlbmdyYXBoaWNzLWRvdC1jb20+CiAqICAgTWljaGVsIETkbnplciA8bWljaGVsLWF0LXR1bmdzdGVuZ3JhcGhpY3MtZG90LWNvbT4KICogICBBbGFuIEhvdXJpaGFuZSA8YWxhbmgtYXQtdHVuZ3N0ZW5ncmFwaGljcy1kb3QtY29tPgogKi8KCiNpbmNsdWRlIDxsaW51eC9tb2R1bGUuaD4KI2luY2x1ZGUgPGxpbnV4L2tlcm5lbC5oPgojaW5jbHVkZSA8bGludXgvZXJybm8uaD4KI2luY2x1ZGUgPGxpbnV4L3N0cmluZy5oPgojaW5jbHVkZSA8bGludXgvZGVsYXkuaD4KI2luY2x1ZGUgPGxpbnV4L21tLmg+CiNpbmNsdWRlIDxsaW51eC9mYi5oPgojaW5jbHVkZSA8bGludXgvcGNpLmg+CiNpbmNsdWRlIDxhc20vY2FjaGVmbHVzaC5oPgojaW5jbHVkZSA8YXNtL3RsYmZsdXNoLmg+CiNpbmNsdWRlIDxsaW51eC9tbXpvbmUuaD4KCi8qICNkZWZpbmUgVkVSTUlMSU9OX0RFQlVHICovCgojaW5jbHVkZSAidmVybWlsaW9uLmgiCgojZGVmaW5lIE1PRFVMRV9OQU1FICJ2bWxmYiIKCiNkZWZpbmUgVk1MX1RPSFcoX3ZhbCwgX3dpZHRoKSAoKCgoX3ZhbCkgPDwgKF93aWR0aCkpICsgMHg3RkZGIC0gKF92YWwpKSA+PiAxNikKCnN0YXRpYyBzdHJ1Y3QgbXV0ZXggdm1sX211dGV4OwpzdGF0aWMgc3RydWN0IGxpc3RfaGVhZCBnbG9iYWxfbm9fbW9kZTsKc3RhdGljIHN0cnVjdCBsaXN0X2hlYWQgZ2xvYmFsX2hhc19tb2RlOwpzdGF0aWMgc3RydWN0IGZiX29wcyB2bWxmYl9vcHM7CnN0YXRpYyBzdHJ1Y3Qgdm1sX3N5cyAqc3Vic3lzID0gTlVMTDsKc3RhdGljIGNoYXIgKnZtbF9kZWZhdWx0X21vZGUgPSAiMTAyNHg3NjhANjAiOwpzdGF0aWMgc3RydWN0IGZiX3ZpZGVvbW9kZSBkZWZhdWx0bW9kZSA9IHsKCU5VTEwsIDYwLCAxMDI0LCA3NjgsIDEyODk2LCAxNDQsIDI0LCAyOSwgMywgMTM2LCA2LAoJMCwgRkJfVk1PREVfTk9OSU5URVJMQUNFRAp9OwoKc3RhdGljIHUzMiB2bWxfbWVtX3JlcXVlc3RlZCA9ICgxMCAqIDEwMjQgKiAxMDI0KTsKc3RhdGljIHUzMiB2bWxfbWVtX2NvbnRpZyA9ICg0ICogMTAyNCAqIDEwMjQpOwpzdGF0aWMgdTMyIHZtbF9tZW1fbWluID0gKDQgKiAxMDI0ICogMTAyNCk7CgpzdGF0aWMgdTMyIHZtbF9jbG9ja3NbXSA9IHsKCTY3NTAsCgkxMzUwMCwKCTI3MDAwLAoJMjk3MDAsCgkzNzEyNSwKCTU0MDAwLAoJNTk0MDAsCgk3NDI1MCwKCTEyMDAwMCwKCTE0ODUwMAp9OwoKc3RhdGljIHUzMiB2bWxfbnVtX2Nsb2NrcyA9IEFSUkFZX1NJWkUodm1sX2Nsb2Nrcyk7CgovKgogKiBBbGxvY2F0ZSBhIGNvbnRpZ3VvdXMgdnJhbSBhcmVhIGFuZCBtYWtlIGl0cyBsaW5lYXIga2VybmVsIG1hcAogKiB1bmNhY2hlZC4KICovCgpzdGF0aWMgaW50IHZtbGZiX2FsbG9jX3ZyYW1fYXJlYShzdHJ1Y3QgdnJhbV9hcmVhICp2YSwgdW5zaWduZWQgbWF4X29yZGVyLAoJCQkJIHVuc2lnbmVkIG1pbl9vcmRlcikKewoJZ2ZwX3QgZmxhZ3M7Cgl1bnNpZ25lZCBsb25nIGk7CglwZ3Byb3RfdCB3Y19wYWdlcHJvdDsKCgl3Y19wYWdlcHJvdCA9IFBBR0VfS0VSTkVMX05PQ0FDSEU7CgltYXhfb3JkZXIrKzsKCWRvIHsKCQkvKgoJCSAqIFJlYWxseSB0cnkgaGFyZCB0byBnZXQgdGhlIG5lZWRlZCBtZW1vcnkuCgkJICogV2UgbmVlZCBtZW1vcnkgYmVsb3cgdGhlIGZpcnN0IDMyTUIsIHNvIHdlCgkJICogYWRkIHRoZSBfX0dGUF9ETUEgZmxhZyB0aGF0IGd1YXJhbnRlZXMgdGhhdCB3ZSBhcmUKCQkgKiBiZWxvdyB0aGUgZmlyc3QgMTZNQi4KCQkgKi8KCgkJZmxhZ3MgPSBfX0dGUF9ETUEgfCBfX0dGUF9ISUdIOwoJCXZhLT5sb2dpY2FsID0KCQkJIF9fZ2V0X2ZyZWVfcGFnZXMoZmxhZ3MsIC0tbWF4X29yZGVyKTsKCX0gd2hpbGUgKHZhLT5sb2dpY2FsID09IDAgJiYgbWF4X29yZGVyID4gbWluX29yZGVyKTsKCglpZiAoIXZhLT5sb2dpY2FsKQoJCXJldHVybiAtRU5PTUVNOwoKCXZhLT5waHlzID0gdmlydF90b19waHlzKCh2b2lkICopdmEtPmxvZ2ljYWwpOwoJdmEtPnNpemUgPSBQQUdFX1NJWkUgPDwgbWF4X29yZGVyOwoJdmEtPm9yZGVyID0gbWF4X29yZGVyOwoKCS8qCgkgKiBJdCBzZWVtcyBsaWtlIF9fZ2V0X2ZyZWVfcGFnZXMgb25seSB1cHMgdGhlIHVzYWdlIGNvdW50CgkgKiBvZiB0aGUgZmlyc3QgcGFnZS4gVGhpcyBkb2Vzbid0IHdvcmsgd2l0aCBub3BhZ2UgbWFwcGluZywgc28KCSAqIHVwIHRoZSB1c2FnZSBjb3VudCBvbmNlIG1vcmUuCgkgKi8KCgltZW1zZXQoKHZvaWQgKil2YS0+bG9naWNhbCwgMHgwMCwgdmEtPnNpemUpOwoJZm9yIChpID0gdmEtPmxvZ2ljYWw7IGkgPCB2YS0+bG9naWNhbCArIHZhLT5zaXplOyBpICs9IFBBR0VfU0laRSkgewoJCWdldF9wYWdlKHZpcnRfdG9fcGFnZShpKSk7Cgl9CgoJLyoKCSAqIENoYW5nZSBjYWNoaW5nIHBvbGljeSBvZiB0aGUgbGluZWFyIGtlcm5lbCBtYXAgdG8gYXZvaWQKCSAqIG1hcHBpbmcgdHlwZSBjb25mbGljdHMgd2l0aCB1c2VyLXNwYWNlIG1hcHBpbmdzLgoJICogVGhlIGZpcnN0IGdsb2JhbF9mbHVzaF90bGIoKSBpcyByZWFsbHkgb25seSB0aGVyZSB0byBkbyBhIGdsb2JhbAoJICogd2JpbnZkKCkuCgkgKi8KCglnbG9iYWxfZmx1c2hfdGxiKCk7CgljaGFuZ2VfcGFnZV9hdHRyKHZpcnRfdG9fcGFnZSh2YS0+bG9naWNhbCksIHZhLT5zaXplID4+IFBBR0VfU0hJRlQsCgkJCSB3Y19wYWdlcHJvdCk7CglnbG9iYWxfZmx1c2hfdGxiKCk7CgoJcHJpbnRrKEtFUk5fREVCVUcgTU9EVUxFX05BTUUKCSAgICAgICAiOiBBbGxvY2F0ZWQgJWxkIGJ5dGVzIHZyYW0gYXJlYSBhdCAweCUwOGx4XG4iLAoJICAgICAgIHZhLT5zaXplLCB2YS0+cGh5cyk7CgoJcmV0dXJuIDA7Cn0KCi8qCiAqIEZyZWUgYSBjb250aWd1b3VzIHZyYW0gYXJlYSBhbmQgcmVzZXQgaXRzIGxpbmVhciBrZXJuZWwgbWFwCiAqIG1hcHBpbmcgdHlwZS4KICovCgpzdGF0aWMgdm9pZCB2bWxmYl9mcmVlX3ZyYW1fYXJlYShzdHJ1Y3QgdnJhbV9hcmVhICp2YSkKewoJdW5zaWduZWQgbG9uZyBqOwoKCWlmICh2YS0+bG9naWNhbCkgewoKCQkvKgoJCSAqIFJlc2V0IHRoZSBsaW5lYXIga2VybmVsIG1hcCBjYWNoaW5nIHBvbGljeS4KCQkgKi8KCgkJY2hhbmdlX3BhZ2VfYXR0cih2aXJ0X3RvX3BhZ2UodmEtPmxvZ2ljYWwpLAoJCQkJIHZhLT5zaXplID4+IFBBR0VfU0hJRlQsIFBBR0VfS0VSTkVMKTsKCQlnbG9iYWxfZmx1c2hfdGxiKCk7CgoJCS8qCgkJICogRGVjcmVhc2UgdGhlIHVzYWdlIGNvdW50IG9uIHRoZSBwYWdlcyB3ZSd2ZSB1c2VkCgkJICogdG8gY29tcGVuc2F0ZSBmb3IgdXBwaW5nIHdoZW4gYWxsb2NhdGluZy4KCQkgKi8KCgkJZm9yIChqID0gdmEtPmxvZ2ljYWw7IGogPCB2YS0+bG9naWNhbCArIHZhLT5zaXplOwoJCSAgICAgaiArPSBQQUdFX1NJWkUpIHsKCQkJKHZvaWQpcHV0X3BhZ2VfdGVzdHplcm8odmlydF90b19wYWdlKGopKTsKCQl9CgoJCXByaW50ayhLRVJOX0RFQlVHIE1PRFVMRV9OQU1FCgkJICAgICAgICI6IEZyZWVpbmcgJWxkIGJ5dGVzIHZyYW0gYXJlYSBhdCAweCUwOGx4XG4iLAoJCSAgICAgICB2YS0+c2l6ZSwgdmEtPnBoeXMpOwoJCWZyZWVfcGFnZXModmEtPmxvZ2ljYWwsIHZhLT5vcmRlcik7CgoJCXZhLT5sb2dpY2FsID0gMDsKCX0KfQoKLyoKICogRnJlZSBhbGxvY2F0ZWQgdnJhbS4KICovCgpzdGF0aWMgdm9pZCB2bWxmYl9mcmVlX3ZyYW0oc3RydWN0IHZtbF9pbmZvICp2aW5mbykKewoJaW50IGk7CgoJZm9yIChpID0gMDsgaSA8IHZpbmZvLT5udW1fYXJlYXM7ICsraSkgewoJCXZtbGZiX2ZyZWVfdnJhbV9hcmVhKCZ2aW5mby0+dnJhbVtpXSk7Cgl9Cgl2aW5mby0+bnVtX2FyZWFzID0gMDsKfQoKLyoKICogQWxsb2NhdGUgdnJhbS4gQ3VycmVudGx5IHdlIHRyeSB0byBhbGxvY2F0ZSBjb250aWd1b3VzIGFyZWFzIGZyb20gdGhlCiAqIF9fR0ZQX0RNQSB6b25lIGFuZCBwdXp6bGUgdGhlbSB0b2dldGhlci4gQSBiZXR0ZXIgYXBwcm9hY2ggd291bGQgYmUgdG8KICogYWxsb2NhdGUgb25lIGNvbnRpZ3VvdXMgYXJlYSBmb3Igc2Nhbm91dCBhbmQgdXNlIG9uZS1wYWdlIGFsbG9jYXRpb25zIGZvcgogKiBvZmZzY3JlZW4gYXJlYXMuIFRoaXMgcmVxdWlyZXMgdXNlci1zcGFjZSBhbmQgR1BVIHZpcnR1YWwgbWFwcGluZ3MuCiAqLwoKc3RhdGljIGludCB2bWxmYl9hbGxvY192cmFtKHN0cnVjdCB2bWxfaW5mbyAqdmluZm8sCgkJCSAgICBzaXplX3QgcmVxdWVzdGVkLAoJCQkgICAgc2l6ZV90IG1pbl90b3RhbCwgc2l6ZV90IG1pbl9jb250aWcpCnsKCWludCBpLCBqOwoJaW50IG9yZGVyOwoJaW50IGNvbnRpZ3VvdXM7CglpbnQgZXJyOwoJc3RydWN0IHZyYW1fYXJlYSAqdmE7CglzdHJ1Y3QgdnJhbV9hcmVhICp2YTI7CgoJdmluZm8tPm51bV9hcmVhcyA9IDA7Cglmb3IgKGkgPSAwOyBpIDwgVk1MX1ZSQU1fQVJFQVM7ICsraSkgewoJCXZhID0gJnZpbmZvLT52cmFtW2ldOwoJCW9yZGVyID0gMDsKCgkJd2hpbGUgKHJlcXVlc3RlZCA+IChQQUdFX1NJWkUgPDwgb3JkZXIpICYmIG9yZGVyIDwgTUFYX09SREVSKQoJCQlvcmRlcisrOwoKCQllcnIgPSB2bWxmYl9hbGxvY192cmFtX2FyZWEodmEsIG9yZGVyLCAwKTsKCgkJaWYgKGVycikKCQkJYnJlYWs7CgoJCWlmIChpID09IDApIHsKCQkJdmluZm8tPnZyYW1fc3RhcnQgPSB2YS0+cGh5czsKCQkJdmluZm8tPnZyYW1fbG9naWNhbCA9ICh2b2lkIF9faW9tZW0gKikgdmEtPmxvZ2ljYWw7CgkJCXZpbmZvLT52cmFtX2NvbnRpZ19zaXplID0gdmEtPnNpemU7CgkJCXZpbmZvLT5udW1fYXJlYXMgPSAxOwoJCX0gZWxzZSB7CgkJCWNvbnRpZ3VvdXMgPSAwOwoKCQkJZm9yIChqID0gMDsgaiA8IGk7ICsraikgewoJCQkJdmEyID0gJnZpbmZvLT52cmFtW2pdOwoJCQkJaWYgKHZhLT5waHlzICsgdmEtPnNpemUgPT0gdmEyLT5waHlzIHx8CgkJCQkgICAgdmEyLT5waHlzICsgdmEyLT5zaXplID09IHZhLT5waHlzKSB7CgkJCQkJY29udGlndW91cyA9IDE7CgkJCQkJYnJlYWs7CgkJCQl9CgkJCX0KCgkJCWlmIChjb250aWd1b3VzKSB7CgkJCQl2aW5mby0+bnVtX2FyZWFzKys7CgkJCQlpZiAodmEtPnBoeXMgPCB2aW5mby0+dnJhbV9zdGFydCkgewoJCQkJCXZpbmZvLT52cmFtX3N0YXJ0ID0gdmEtPnBoeXM7CgkJCQkJdmluZm8tPnZyYW1fbG9naWNhbCA9CgkJCQkJCSh2b2lkIF9faW9tZW0gKil2YS0+bG9naWNhbDsKCQkJCX0KCQkJCXZpbmZvLT52cmFtX2NvbnRpZ19zaXplICs9IHZhLT5zaXplOwoJCQl9IGVsc2UgewoJCQkJdm1sZmJfZnJlZV92cmFtX2FyZWEodmEpOwoJCQkJYnJlYWs7CgkJCX0KCQl9CgoJCWlmIChyZXF1ZXN0ZWQgPCB2YS0+c2l6ZSkKCQkJYnJlYWs7CgkJZWxzZQoJCQlyZXF1ZXN0ZWQgLT0gdmEtPnNpemU7Cgl9CgoJaWYgKHZpbmZvLT52cmFtX2NvbnRpZ19zaXplID4gbWluX3RvdGFsICYmCgkgICAgdmluZm8tPnZyYW1fY29udGlnX3NpemUgPiBtaW5fY29udGlnKSB7CgoJCXByaW50ayhLRVJOX0RFQlVHIE1PRFVMRV9OQU1FCgkJICAgICAgICI6IENvbnRpZ3VvdXMgdnJhbTogJWxkIGJ5dGVzIGF0IHBoeXNpY2FsIDB4JTA4bHguXG4iLAoJCSAgICAgICAodW5zaWduZWQgbG9uZyl2aW5mby0+dnJhbV9jb250aWdfc2l6ZSwKCQkgICAgICAgKHVuc2lnbmVkIGxvbmcpdmluZm8tPnZyYW1fc3RhcnQpOwoKCQlyZXR1cm4gMDsKCX0KCglwcmludGsoS0VSTl9FUlIgTU9EVUxFX05BTUUKCSAgICAgICAiOiBDb3VsZCBub3QgYWxsb2NhdGUgcmVxdWVzdGVkIG1pbmltYWwgYW1vdW50IG9mIHZyYW0uXG4iKTsKCgl2bWxmYl9mcmVlX3ZyYW0odmluZm8pOwoKCXJldHVybiAtRU5PTUVNOwp9CgovKgogKiBGaW5kIHRoZSBHUFUgdG8gdXNlIHdpdGggb3VyIGRpc3BsYXkgY29udHJvbGxlci4KICovCgpzdGF0aWMgaW50IHZtbGZiX2dldF9ncHUoc3RydWN0IHZtbF9wYXIgKnBhcikKewoJbXV0ZXhfbG9jaygmdm1sX211dGV4KTsKCglwYXItPmdwdSA9IHBjaV9nZXRfZGV2aWNlKFBDSV9WRU5ET1JfSURfSU5URUwsIFZNTF9ERVZJQ0VfR1BVLCBOVUxMKTsKCglpZiAoIXBhci0+Z3B1KSB7CgkJbXV0ZXhfdW5sb2NrKCZ2bWxfbXV0ZXgpOwoJCXJldHVybiAtRU5PREVWOwoJfQoKCW11dGV4X3VubG9jaygmdm1sX211dGV4KTsKCglpZiAocGNpX2VuYWJsZV9kZXZpY2UocGFyLT5ncHUpIDwgMCkKCQlyZXR1cm4gLUVOT0RFVjsKCglyZXR1cm4gMDsKfQoKLyoKICogRmluZCBhIGNvbnRpZ3VvdXMgdnJhbSBhcmVhIHRoYXQgY29udGFpbnMgYSBnaXZlbiBvZmZzZXQgZnJvbSB2cmFtIHN0YXJ0LgogKi8Kc3RhdGljIGludCB2bWxmYl92cmFtX29mZnNldChzdHJ1Y3Qgdm1sX2luZm8gKnZpbmZvLCB1bnNpZ25lZCBsb25nIG9mZnNldCkKewoJdW5zaWduZWQgbG9uZyBhb2Zmc2V0OwoJdW5zaWduZWQgaTsKCglmb3IgKGkgPSAwOyBpIDwgdmluZm8tPm51bV9hcmVhczsgKytpKSB7CgkJYW9mZnNldCA9IG9mZnNldCAtICh2aW5mby0+dnJhbVtpXS5waHlzIC0gdmluZm8tPnZyYW1fc3RhcnQpOwoKCQlpZiAoYW9mZnNldCA8IHZpbmZvLT52cmFtW2ldLnNpemUpIHsKCQkJcmV0dXJuIDA7CgkJfQoJfQoKCXJldHVybiAtRUlOVkFMOwp9CgovKgogKiBSZW1hcCB0aGUgTU1JTyByZWdpc3RlciBzcGFjZXMgb2YgdGhlIFZEQyBhbmQgdGhlIEdQVS4KICovCgpzdGF0aWMgaW50IHZtbGZiX2VuYWJsZV9tbWlvKHN0cnVjdCB2bWxfcGFyICpwYXIpCnsKCWludCBlcnI7CgoJcGFyLT52ZGNfbWVtX2Jhc2UgPSBwY2lfcmVzb3VyY2Vfc3RhcnQocGFyLT52ZGMsIDApOwoJcGFyLT52ZGNfbWVtX3NpemUgPSBwY2lfcmVzb3VyY2VfbGVuKHBhci0+dmRjLCAwKTsKCWlmICghcmVxdWVzdF9tZW1fcmVnaW9uKHBhci0+dmRjX21lbV9iYXNlLCBwYXItPnZkY19tZW1fc2l6ZSwgInZtbGZiIikpIHsKCQlwcmludGsoS0VSTl9FUlIgTU9EVUxFX05BTUUKCQkgICAgICAgIjogQ291bGQgbm90IGNsYWltIGRpc3BsYXkgY29udHJvbGxlciBNTUlPLlxuIik7CgkJcmV0dXJuIC1FQlVTWTsKCX0KCXBhci0+dmRjX21lbSA9IGlvcmVtYXBfbm9jYWNoZShwYXItPnZkY19tZW1fYmFzZSwgcGFyLT52ZGNfbWVtX3NpemUpOwoJaWYgKHBhci0+dmRjX21lbSA9PSBOVUxMKSB7CgkJcHJpbnRrKEtFUk5fRVJSIE1PRFVMRV9OQU1FCgkJICAgICAgICI6IENvdWxkIG5vdCBtYXAgZGlzcGxheSBjb250cm9sbGVyIE1NSU8uXG4iKTsKCQllcnIgPSAtRU5PTUVNOwoJCWdvdG8gb3V0X2Vycl8wOwoJfQoKCXBhci0+Z3B1X21lbV9iYXNlID0gcGNpX3Jlc291cmNlX3N0YXJ0KHBhci0+Z3B1LCAwKTsKCXBhci0+Z3B1X21lbV9zaXplID0gcGNpX3Jlc291cmNlX2xlbihwYXItPmdwdSwgMCk7CglpZiAoIXJlcXVlc3RfbWVtX3JlZ2lvbihwYXItPmdwdV9tZW1fYmFzZSwgcGFyLT5ncHVfbWVtX3NpemUsICJ2bWxmYiIpKSB7CgkJcHJpbnRrKEtFUk5fRVJSIE1PRFVMRV9OQU1FICI6IENvdWxkIG5vdCBjbGFpbSBHUFUgTU1JTy5cbiIpOwoJCWVyciA9IC1FQlVTWTsKCQlnb3RvIG91dF9lcnJfMTsKCX0KCXBhci0+Z3B1X21lbSA9IGlvcmVtYXBfbm9jYWNoZShwYXItPmdwdV9tZW1fYmFzZSwgcGFyLT5ncHVfbWVtX3NpemUpOwoJaWYgKHBhci0+Z3B1X21lbSA9PSBOVUxMKSB7CgkJcHJpbnRrKEtFUk5fRVJSIE1PRFVMRV9OQU1FICI6IENvdWxkIG5vdCBtYXAgR1BVIE1NSU8uXG4iKTsKCQllcnIgPSAtRU5PTUVNOwoJCWdvdG8gb3V0X2Vycl8yOwoJfQoKCXJldHVybiAwOwoKb3V0X2Vycl8yOgoJcmVsZWFzZV9tZW1fcmVnaW9uKHBhci0+Z3B1X21lbV9iYXNlLCBwYXItPmdwdV9tZW1fc2l6ZSk7Cm91dF9lcnJfMToKCWlvdW5tYXAocGFyLT52ZGNfbWVtKTsKb3V0X2Vycl8wOgoJcmVsZWFzZV9tZW1fcmVnaW9uKHBhci0+dmRjX21lbV9iYXNlLCBwYXItPnZkY19tZW1fc2l6ZSk7CglyZXR1cm4gZXJyOwp9CgovKgogKiBVbm1hcCB0aGUgVkRDIGFuZCBHUFUgcmVnaXN0ZXIgc3BhY2VzLgogKi8KCnN0YXRpYyB2b2lkIHZtbGZiX2Rpc2FibGVfbW1pbyhzdHJ1Y3Qgdm1sX3BhciAqcGFyKQp7Cglpb3VubWFwKHBhci0+Z3B1X21lbSk7CglyZWxlYXNlX21lbV9yZWdpb24ocGFyLT5ncHVfbWVtX2Jhc2UsIHBhci0+Z3B1X21lbV9zaXplKTsKCWlvdW5tYXAocGFyLT52ZGNfbWVtKTsKCXJlbGVhc2VfbWVtX3JlZ2lvbihwYXItPnZkY19tZW1fYmFzZSwgcGFyLT52ZGNfbWVtX3NpemUpOwp9CgovKgogKiBSZWxlYXNlIGFuZCB1bmluaXQgdGhlIFZEQyBhbmQgR1BVLgogKi8KCnN0YXRpYyB2b2lkIHZtbGZiX3JlbGVhc2VfZGV2aWNlcyhzdHJ1Y3Qgdm1sX3BhciAqcGFyKQp7CglpZiAoYXRvbWljX2RlY19hbmRfdGVzdCgmcGFyLT5yZWZjb3VudCkpIHsKCQlwY2lfc2V0X2RydmRhdGEocGFyLT52ZGMsIE5VTEwpOwoJCXBjaV9kaXNhYmxlX2RldmljZShwYXItPmdwdSk7CgkJcGNpX2Rpc2FibGVfZGV2aWNlKHBhci0+dmRjKTsKCX0KfQoKLyoKICogRnJlZSB1cCBhbGxvY2F0ZWQgcmVzb3VyY2VzIGZvciBhIGRldmljZS4KICovCgpzdGF0aWMgdm9pZCBfX2RldmV4aXQgdm1sX3BjaV9yZW1vdmUoc3RydWN0IHBjaV9kZXYgKmRldikKewoJc3RydWN0IGZiX2luZm8gKmluZm87CglzdHJ1Y3Qgdm1sX2luZm8gKnZpbmZvOwoJc3RydWN0IHZtbF9wYXIgKnBhcjsKCglpbmZvID0gcGNpX2dldF9kcnZkYXRhKGRldik7CglpZiAoaW5mbykgewoJCXZpbmZvID0gY29udGFpbmVyX29mKGluZm8sIHN0cnVjdCB2bWxfaW5mbywgaW5mbyk7CgkJcGFyID0gdmluZm8tPnBhcjsKCQltdXRleF9sb2NrKCZ2bWxfbXV0ZXgpOwoJCXVucmVnaXN0ZXJfZnJhbWVidWZmZXIoaW5mbyk7CgkJZmJfZGVhbGxvY19jbWFwKCZpbmZvLT5jbWFwKTsKCQl2bWxmYl9mcmVlX3ZyYW0odmluZm8pOwoJCXZtbGZiX2Rpc2FibGVfbW1pbyhwYXIpOwoJCXZtbGZiX3JlbGVhc2VfZGV2aWNlcyhwYXIpOwoJCWtmcmVlKHZpbmZvKTsKCQlrZnJlZShwYXIpOwoJCW11dGV4X3VubG9jaygmdm1sX211dGV4KTsKCX0KfQoKc3RhdGljIHZvaWQgdm1sZmJfc2V0X3ByZWZfcGl4ZWxfZm9ybWF0KHN0cnVjdCBmYl92YXJfc2NyZWVuaW5mbyAqdmFyKQp7Cglzd2l0Y2ggKHZhci0+Yml0c19wZXJfcGl4ZWwpIHsKCWNhc2UgMTY6CgkJdmFyLT5ibHVlLm9mZnNldCA9IDA7CgkJdmFyLT5ibHVlLmxlbmd0aCA9IDU7CgkJdmFyLT5ncmVlbi5vZmZzZXQgPSA1OwoJCXZhci0+Z3JlZW4ubGVuZ3RoID0gNTsKCQl2YXItPnJlZC5vZmZzZXQgPSAxMDsKCQl2YXItPnJlZC5sZW5ndGggPSA1OwoJCXZhci0+dHJhbnNwLm9mZnNldCA9IDE1OwoJCXZhci0+dHJhbnNwLmxlbmd0aCA9IDE7CgkJYnJlYWs7CgljYXNlIDMyOgoJCXZhci0+Ymx1ZS5vZmZzZXQgPSAwOwoJCXZhci0+Ymx1ZS5sZW5ndGggPSA4OwoJCXZhci0+Z3JlZW4ub2Zmc2V0ID0gODsKCQl2YXItPmdyZWVuLmxlbmd0aCA9IDg7CgkJdmFyLT5yZWQub2Zmc2V0ID0gMTY7CgkJdmFyLT5yZWQubGVuZ3RoID0gODsKCQl2YXItPnRyYW5zcC5vZmZzZXQgPSAyNDsKCQl2YXItPnRyYW5zcC5sZW5ndGggPSAwOwoJCWJyZWFrOwoJZGVmYXVsdDoKCQlicmVhazsKCX0KCgl2YXItPmJsdWUubXNiX3JpZ2h0ID0gdmFyLT5ncmVlbi5tc2JfcmlnaHQgPQoJICAgIHZhci0+cmVkLm1zYl9yaWdodCA9IHZhci0+dHJhbnNwLm1zYl9yaWdodCA9IDA7Cn0KCi8qCiAqIERldmljZSBpbml0aWFsaXphdGlvbi4KICogV2UgaW5pdGlhbGl6ZSBvbmUgdm1sX3BhciBzdHJ1Y3QgcGVyIGRldmljZSBhbmQgb25lIHZtbF9pbmZvCiAqIHN0cnVjdCBwZXIgcGlwZS4gQ3VycmVudGx5IHdlIGhhdmUgb25seSBvbmUgcGlwZS4KICovCgpzdGF0aWMgaW50IF9fZGV2aW5pdCB2bWxfcGNpX3Byb2JlKHN0cnVjdCBwY2lfZGV2ICpkZXYsCgkJCQkgICBjb25zdCBzdHJ1Y3QgcGNpX2RldmljZV9pZCAqaWQpCnsKCXN0cnVjdCB2bWxfaW5mbyAqdmluZm87CglzdHJ1Y3QgZmJfaW5mbyAqaW5mbzsKCXN0cnVjdCB2bWxfcGFyICpwYXI7CglpbnQgZXJyID0gMDsKCglwYXIgPSBremFsbG9jKHNpemVvZigqcGFyKSwgR0ZQX0tFUk5FTCk7CglpZiAocGFyID09IE5VTEwpCgkJcmV0dXJuIC1FTk9NRU07CgoJdmluZm8gPSBremFsbG9jKHNpemVvZigqdmluZm8pLCBHRlBfS0VSTkVMKTsKCWlmICh2aW5mbyA9PSBOVUxMKSB7CgkJZXJyID0gLUVOT01FTTsKCQlnb3RvIG91dF9lcnJfMDsKCX0KCgl2aW5mby0+cGFyID0gcGFyOwoJcGFyLT52ZGMgPSBkZXY7CglhdG9taWNfc2V0KCZwYXItPnJlZmNvdW50LCAxKTsKCglzd2l0Y2ggKGlkLT5kZXZpY2UpIHsKCWNhc2UgVk1MX0RFVklDRV9WREM6CgkJaWYgKChlcnIgPSB2bWxmYl9nZXRfZ3B1KHBhcikpKQoJCQlnb3RvIG91dF9lcnJfMTsKCQlwY2lfc2V0X2RydmRhdGEoZGV2LCAmdmluZm8tPmluZm8pOwoJCWJyZWFrOwoJZGVmYXVsdDoKCQllcnIgPSAtRU5PREVWOwoJCWdvdG8gb3V0X2Vycl8xOwoJCWJyZWFrOwoJfQoKCWluZm8gPSAmdmluZm8tPmluZm87CglpbmZvLT5mbGFncyA9IEZCSU5GT19ERUZBVUxUIHwgRkJJTkZPX1BBUlRJQUxfUEFOX09LOwoKCWVyciA9IHZtbGZiX2VuYWJsZV9tbWlvKHBhcik7CglpZiAoZXJyKQoJCWdvdG8gb3V0X2Vycl8yOwoKCWVyciA9IHZtbGZiX2FsbG9jX3ZyYW0odmluZm8sIHZtbF9tZW1fcmVxdWVzdGVkLAoJCQkgICAgICAgdm1sX21lbV9jb250aWcsIHZtbF9tZW1fbWluKTsKCWlmIChlcnIpCgkJZ290byBvdXRfZXJyXzM7CgoJc3RyY3B5KGluZm8tPmZpeC5pZCwgIlZlcm1pbGlvbiBSYW5nZSIpOwoJaW5mby0+Zml4Lm1taW9fc3RhcnQgPSAwOwoJaW5mby0+Zml4Lm1taW9fbGVuID0gMDsKCWluZm8tPmZpeC5zbWVtX3N0YXJ0ID0gdmluZm8tPnZyYW1fc3RhcnQ7CglpbmZvLT5maXguc21lbV9sZW4gPSB2aW5mby0+dnJhbV9jb250aWdfc2l6ZTsKCWluZm8tPmZpeC50eXBlID0gRkJfVFlQRV9QQUNLRURfUElYRUxTOwoJaW5mby0+Zml4LnZpc3VhbCA9IEZCX1ZJU1VBTF9UUlVFQ09MT1I7CglpbmZvLT5maXgueXBhbnN0ZXAgPSAxOwoJaW5mby0+Zml4LnhwYW5zdGVwID0gMTsKCWluZm8tPmZpeC55d3JhcHN0ZXAgPSAwOwoJaW5mby0+Zml4LmFjY2VsID0gRkJfQUNDRUxfTk9ORTsKCWluZm8tPnNjcmVlbl9iYXNlID0gdmluZm8tPnZyYW1fbG9naWNhbDsKCWluZm8tPnBzZXVkb19wYWxldHRlID0gdmluZm8tPnBzZXVkb19wYWxldHRlOwoJaW5mby0+cGFyID0gcGFyOwoJaW5mby0+ZmJvcHMgPSAmdm1sZmJfb3BzOwoJaW5mby0+ZGV2aWNlID0gJmRldi0+ZGV2OwoKCUlOSVRfTElTVF9IRUFEKCZ2aW5mby0+aGVhZCk7Cgl2aW5mby0+cGlwZV9kaXNhYmxlZCA9IDE7Cgl2aW5mby0+Y3VyX2JsYW5rX21vZGUgPSBGQl9CTEFOS19VTkJMQU5LOwoKCWluZm8tPnZhci5ncmF5c2NhbGUgPSAwOwoJaW5mby0+dmFyLmJpdHNfcGVyX3BpeGVsID0gMTY7Cgl2bWxmYl9zZXRfcHJlZl9waXhlbF9mb3JtYXQoJmluZm8tPnZhcik7CgoJaWYgKCFmYl9maW5kX21vZGUKCSAgICAoJmluZm8tPnZhciwgaW5mbywgdm1sX2RlZmF1bHRfbW9kZSwgTlVMTCwgMCwgJmRlZmF1bHRtb2RlLCAxNikpIHsKCQlwcmludGsoS0VSTl9FUlIgTU9EVUxFX05BTUUgIjogQ291bGQgbm90IGZpbmQgaW5pdGlhbCBtb2RlXG4iKTsKCX0KCglpZiAoZmJfYWxsb2NfY21hcCgmaW5mby0+Y21hcCwgMjU2LCAxKSA8IDApIHsKCQllcnIgPSAtRU5PTUVNOwoJCWdvdG8gb3V0X2Vycl80OwoJfQoKCWVyciA9IHJlZ2lzdGVyX2ZyYW1lYnVmZmVyKGluZm8pOwoJaWYgKGVycikgewoJCXByaW50ayhLRVJOX0VSUiBNT0RVTEVfTkFNRSAiOiBSZWdpc3RlciBmcmFtZWJ1ZmZlciBlcnJvci5cbiIpOwoJCWdvdG8gb3V0X2Vycl81OwoJfQoKCXByaW50aygiSW5pdGlhbGl6ZWQgdm1sZmJcbiIpOwoKCXJldHVybiAwOwoKb3V0X2Vycl81OgoJZmJfZGVhbGxvY19jbWFwKCZpbmZvLT5jbWFwKTsKb3V0X2Vycl80OgoJdm1sZmJfZnJlZV92cmFtKHZpbmZvKTsKb3V0X2Vycl8zOgoJdm1sZmJfZGlzYWJsZV9tbWlvKHBhcik7Cm91dF9lcnJfMjoKCXZtbGZiX3JlbGVhc2VfZGV2aWNlcyhwYXIpOwpvdXRfZXJyXzE6CglrZnJlZSh2aW5mbyk7Cm91dF9lcnJfMDoKCWtmcmVlKHBhcik7CglyZXR1cm4gZXJyOwp9CgpzdGF0aWMgaW50IHZtbGZiX29wZW4oc3RydWN0IGZiX2luZm8gKmluZm8sIGludCB1c2VyKQp7CgkvKgoJICogU2F2ZSByZWdpc3RlcnMgaGVyZT8KCSAqLwoJcmV0dXJuIDA7Cn0KCnN0YXRpYyBpbnQgdm1sZmJfcmVsZWFzZShzdHJ1Y3QgZmJfaW5mbyAqaW5mbywgaW50IHVzZXIpCnsKCS8qCgkgKiBSZXN0b3JlIHJlZ2lzdGVycyBoZXJlLgoJICovCgoJcmV0dXJuIDA7Cn0KCnN0YXRpYyBpbnQgdm1sX25lYXJlc3RfY2xvY2soaW50IGNsb2NrKQp7CgoJaW50IGk7CglpbnQgY3VyX2luZGV4OwoJaW50IGN1cl9kaWZmOwoJaW50IGRpZmY7CgoJY3VyX2luZGV4ID0gMDsKCWN1cl9kaWZmID0gY2xvY2sgLSB2bWxfY2xvY2tzWzBdOwoJY3VyX2RpZmYgPSAoY3VyX2RpZmYgPCAwKSA/IC1jdXJfZGlmZiA6IGN1cl9kaWZmOwoJZm9yIChpID0gMTsgaSA8IHZtbF9udW1fY2xvY2tzOyArK2kpIHsKCQlkaWZmID0gY2xvY2sgLSB2bWxfY2xvY2tzW2ldOwoJCWRpZmYgPSAoZGlmZiA8IDApID8gLWRpZmYgOiBkaWZmOwoJCWlmIChkaWZmIDwgY3VyX2RpZmYpIHsKCQkJY3VyX2luZGV4ID0gaTsKCQkJY3VyX2RpZmYgPSBkaWZmOwoJCX0KCX0KCXJldHVybiB2bWxfY2xvY2tzW2N1cl9pbmRleF07Cn0KCnN0YXRpYyBpbnQgdm1sZmJfY2hlY2tfdmFyX2xvY2tlZChzdHJ1Y3QgZmJfdmFyX3NjcmVlbmluZm8gKnZhciwKCQkJCSAgc3RydWN0IHZtbF9pbmZvICp2aW5mbykKewoJdTMyIHBpdGNoOwoJdTY0IG1lbTsKCWludCBuZWFyZXN0X2Nsb2NrOwoJaW50IGNsb2NrOwoJaW50IGNsb2NrX2RpZmY7CglzdHJ1Y3QgZmJfdmFyX3NjcmVlbmluZm8gdjsKCgl2ID0gKnZhcjsKCWNsb2NrID0gUElDT1MyS0haKHZhci0+cGl4Y2xvY2spOwoKCWlmIChzdWJzeXMgJiYgc3Vic3lzLT5uZWFyZXN0X2Nsb2NrKSB7CgkJbmVhcmVzdF9jbG9jayA9IHN1YnN5cy0+bmVhcmVzdF9jbG9jayhzdWJzeXMsIGNsb2NrKTsKCX0gZWxzZSB7CgkJbmVhcmVzdF9jbG9jayA9IHZtbF9uZWFyZXN0X2Nsb2NrKGNsb2NrKTsKCX0KCgkvKgoJICogQWNjZXB0IGEgMjAlIGRpZmYuCgkgKi8KCgljbG9ja19kaWZmID0gbmVhcmVzdF9jbG9jayAtIGNsb2NrOwoJY2xvY2tfZGlmZiA9IChjbG9ja19kaWZmIDwgMCkgPyAtY2xvY2tfZGlmZiA6IGNsb2NrX2RpZmY7CglpZiAoY2xvY2tfZGlmZiA+IGNsb2NrIC8gNSkgewojaWYgMAoJCXByaW50ayhLRVJOX0RFQlVHIE1PRFVMRV9OQU1FICI6IERpZmYgZmFpbHVyZS4gJWQgJWRcbiIsY2xvY2tfZGlmZixjbG9jayk7CiNlbmRpZgoJCXJldHVybiAtRUlOVkFMOwoJfQoKCXYucGl4Y2xvY2sgPSBLSFoyUElDT1MobmVhcmVzdF9jbG9jayk7CgoJaWYgKHZhci0+eHJlcyA+IFZNTF9NQVhfWFJFUyB8fCB2YXItPnlyZXMgPiBWTUxfTUFYX1lSRVMpIHsKCQlwcmludGsoS0VSTl9ERUJVRyBNT0RVTEVfTkFNRSAiOiBSZXNvbHV0aW9uIGZhaWx1cmUuXG4iKTsKCQlyZXR1cm4gLUVJTlZBTDsKCX0KCWlmICh2YXItPnhyZXNfdmlydHVhbCA+IFZNTF9NQVhfWFJFU19WSVJUVUFMKSB7CgkJcHJpbnRrKEtFUk5fREVCVUcgTU9EVUxFX05BTUUKCQkgICAgICAgIjogVmlydHVhbCByZXNvbHV0aW9uIGZhaWx1cmUuXG4iKTsKCQlyZXR1cm4gLUVJTlZBTDsKCX0KCXN3aXRjaCAodi5iaXRzX3Blcl9waXhlbCkgewoJY2FzZSAwIC4uLiAxNjoKCQl2LmJpdHNfcGVyX3BpeGVsID0gMTY7CgkJYnJlYWs7CgljYXNlIDE3IC4uLiAzMjoKCQl2LmJpdHNfcGVyX3BpeGVsID0gMzI7CgkJYnJlYWs7CglkZWZhdWx0OgoJCXByaW50ayhLRVJOX0RFQlVHIE1PRFVMRV9OQU1FICI6IEludmFsaWQgYnBwOiAlZC5cbiIsCgkJICAgICAgIHZhci0+Yml0c19wZXJfcGl4ZWwpOwoJCXJldHVybiAtRUlOVkFMOwoJfQoKCXBpdGNoID0gX19BTElHTl9NQVNLKCh2YXItPnhyZXMgKiB2YXItPmJpdHNfcGVyX3BpeGVsKSA+PiAzLCAweDNGKTsKCW1lbSA9IHBpdGNoICogdmFyLT55cmVzX3ZpcnR1YWw7CglpZiAobWVtID4gdmluZm8tPnZyYW1fY29udGlnX3NpemUpIHsKCQlyZXR1cm4gLUVOT01FTTsKCX0KCglzd2l0Y2ggKHYuYml0c19wZXJfcGl4ZWwpIHsKCWNhc2UgMTY6CgkJaWYgKHZhci0+Ymx1ZS5vZmZzZXQgIT0gMCB8fAoJCSAgICB2YXItPmJsdWUubGVuZ3RoICE9IDUgfHwKCQkgICAgdmFyLT5ncmVlbi5vZmZzZXQgIT0gNSB8fAoJCSAgICB2YXItPmdyZWVuLmxlbmd0aCAhPSA1IHx8CgkJICAgIHZhci0+cmVkLm9mZnNldCAhPSAxMCB8fAoJCSAgICB2YXItPnJlZC5sZW5ndGggIT0gNSB8fAoJCSAgICB2YXItPnRyYW5zcC5vZmZzZXQgIT0gMTUgfHwgdmFyLT50cmFuc3AubGVuZ3RoICE9IDEpIHsKCQkJdm1sZmJfc2V0X3ByZWZfcGl4ZWxfZm9ybWF0KCZ2KTsKCQl9CgkJYnJlYWs7CgljYXNlIDMyOgoJCWlmICh2YXItPmJsdWUub2Zmc2V0ICE9IDAgfHwKCQkgICAgdmFyLT5ibHVlLmxlbmd0aCAhPSA4IHx8CgkJICAgIHZhci0+Z3JlZW4ub2Zmc2V0ICE9IDggfHwKCQkgICAgdmFyLT5ncmVlbi5sZW5ndGggIT0gOCB8fAoJCSAgICB2YXItPnJlZC5vZmZzZXQgIT0gMTYgfHwKCQkgICAgdmFyLT5yZWQubGVuZ3RoICE9IDggfHwKCQkgICAgKHZhci0+dHJhbnNwLmxlbmd0aCAhPSAwICYmIHZhci0+dHJhbnNwLmxlbmd0aCAhPSA4KSB8fAoJCSAgICAodmFyLT50cmFuc3AubGVuZ3RoID09IDggJiYgdmFyLT50cmFuc3Aub2Zmc2V0ICE9IDI0KSkgewoJCQl2bWxmYl9zZXRfcHJlZl9waXhlbF9mb3JtYXQoJnYpOwoJCX0KCQlicmVhazsKCWRlZmF1bHQ6CgkJcmV0dXJuIC1FSU5WQUw7Cgl9CgoJKnZhciA9IHY7CgoJcmV0dXJuIDA7Cn0KCnN0YXRpYyBpbnQgdm1sZmJfY2hlY2tfdmFyKHN0cnVjdCBmYl92YXJfc2NyZWVuaW5mbyAqdmFyLCBzdHJ1Y3QgZmJfaW5mbyAqaW5mbykKewoJc3RydWN0IHZtbF9pbmZvICp2aW5mbyA9IGNvbnRhaW5lcl9vZihpbmZvLCBzdHJ1Y3Qgdm1sX2luZm8sIGluZm8pOwoJaW50IHJldDsKCgltdXRleF9sb2NrKCZ2bWxfbXV0ZXgpOwoJcmV0ID0gdm1sZmJfY2hlY2tfdmFyX2xvY2tlZCh2YXIsIHZpbmZvKTsKCW11dGV4X3VubG9jaygmdm1sX211dGV4KTsKCglyZXR1cm4gcmV0Owp9CgpzdGF0aWMgdm9pZCB2bWxfd2FpdF92Ymxhbmsoc3RydWN0IHZtbF9pbmZvICp2aW5mbykKewoJLyogV2FpdCBmb3IgdmJsYW5rLiBGb3Igbm93LCBqdXN0IHdhaXQgZm9yIGEgNTBIeiBjeWNsZSAoMjBtcykpICovCgltZGVsYXkoMjApOwp9CgpzdGF0aWMgdm9pZCB2bWxmYl9kaXNhYmxlX3BpcGUoc3RydWN0IHZtbF9pbmZvICp2aW5mbykKewoJc3RydWN0IHZtbF9wYXIgKnBhciA9IHZpbmZvLT5wYXI7CgoJLyogRGlzYWJsZSB0aGUgTURWTyBwYWQgKi8KCVZNTF9XUklURTMyKHBhciwgVk1MX1JDT01QU1RBVCwgMCk7Cgl3aGlsZSAoIShWTUxfUkVBRDMyKHBhciwgVk1MX1JDT01QU1RBVCkgJiBWTUxfTURWT19WRENfSV9SQ09NUCkpIDsKCgkvKiBEaXNhYmxlIGRpc3BsYXkgcGxhbmVzICovCglWTUxfV1JJVEUzMihwYXIsIFZNTF9EU1BDQ05UUiwKCQkgICAgVk1MX1JFQUQzMihwYXIsIFZNTF9EU1BDQ05UUikgJiB+Vk1MX0dGWF9FTkFCTEUpOwoJKHZvaWQpVk1MX1JFQUQzMihwYXIsIFZNTF9EU1BDQ05UUik7CgkvKiBXYWl0IGZvciB2YmxhbmsgZm9yIHRoZSBkaXNhYmxlIHRvIHRha2UgZWZmZWN0ICovCgl2bWxfd2FpdF92YmxhbmsodmluZm8pOwoKCS8qIE5leHQsIGRpc2FibGUgZGlzcGxheSBwaXBlcyAqLwoJVk1MX1dSSVRFMzIocGFyLCBWTUxfUElQRUFDT05GLCAwKTsKCSh2b2lkKVZNTF9SRUFEMzIocGFyLCBWTUxfUElQRUFDT05GKTsKCgl2aW5mby0+cGlwZV9kaXNhYmxlZCA9IDE7Cn0KCiNpZmRlZiBWRVJNSUxJT05fREVCVUcKc3RhdGljIHZvaWQgdm1sX2R1bXBfcmVncyhzdHJ1Y3Qgdm1sX2luZm8gKnZpbmZvKQp7CglzdHJ1Y3Qgdm1sX3BhciAqcGFyID0gdmluZm8tPnBhcjsKCglwcmludGsoS0VSTl9ERUJVRyBNT0RVTEVfTkFNRSAiOiBNb2Rlc2V0dGluZyByZWdpc3RlciBkdW1wOlxuIik7CglwcmludGsoS0VSTl9ERUJVRyBNT0RVTEVfTkFNRSAiOiBcdEhUT1RBTF9BICAgICAgICAgOiAweCUwOHhcbiIsCgkgICAgICAgKHVuc2lnbmVkKVZNTF9SRUFEMzIocGFyLCBWTUxfSFRPVEFMX0EpKTsKCXByaW50ayhLRVJOX0RFQlVHIE1PRFVMRV9OQU1FICI6IFx0SEJMQU5LX0EgICAgICAgICA6IDB4JTA4eFxuIiwKCSAgICAgICAodW5zaWduZWQpVk1MX1JFQUQzMihwYXIsIFZNTF9IQkxBTktfQSkpOwoJcHJpbnRrKEtFUk5fREVCVUcgTU9EVUxFX05BTUUgIjogXHRIU1lOQ19BICAgICAgICAgIDogMHglMDh4XG4iLAoJICAgICAgICh1bnNpZ25lZClWTUxfUkVBRDMyKHBhciwgVk1MX0hTWU5DX0EpKTsKCXByaW50ayhLRVJOX0RFQlVHIE1PRFVMRV9OQU1FICI6IFx0VlRPVEFMX0EgICAgICAgICA6IDB4JTA4eFxuIiwKCSAgICAgICAodW5zaWduZWQpVk1MX1JFQUQzMihwYXIsIFZNTF9WVE9UQUxfQSkpOwoJcHJpbnRrKEtFUk5fREVCVUcgTU9EVUxFX05BTUUgIjogXHRWQkxBTktfQSAgICAgICAgIDogMHglMDh4XG4iLAoJICAgICAgICh1bnNpZ25lZClWTUxfUkVBRDMyKHBhciwgVk1MX1ZCTEFOS19BKSk7CglwcmludGsoS0VSTl9ERUJVRyBNT0RVTEVfTkFNRSAiOiBcdFZTWU5DX0EgICAgICAgICAgOiAweCUwOHhcbiIsCgkgICAgICAgKHVuc2lnbmVkKVZNTF9SRUFEMzIocGFyLCBWTUxfVlNZTkNfQSkpOwoJcHJpbnRrKEtFUk5fREVCVUcgTU9EVUxFX05BTUUgIjogXHREU1BDU1RSSURFICAgICAgIDogMHglMDh4XG4iLAoJICAgICAgICh1bnNpZ25lZClWTUxfUkVBRDMyKHBhciwgVk1MX0RTUENTVFJJREUpKTsKCXByaW50ayhLRVJOX0RFQlVHIE1PRFVMRV9OQU1FICI6IFx0RFNQQ1NJWkUgICAgICAgICA6IDB4JTA4eFxuIiwKCSAgICAgICAodW5zaWduZWQpVk1MX1JFQUQzMihwYXIsIFZNTF9EU1BDU0laRSkpOwoJcHJpbnRrKEtFUk5fREVCVUcgTU9EVUxFX05BTUUgIjogXHREU1BDUE9TICAgICAgICAgIDogMHglMDh4XG4iLAoJICAgICAgICh1bnNpZ25lZClWTUxfUkVBRDMyKHBhciwgVk1MX0RTUENQT1MpKTsKCXByaW50ayhLRVJOX0RFQlVHIE1PRFVMRV9OQU1FICI6IFx0RFNQQVJCICAgICAgICAgICA6IDB4JTA4eFxuIiwKCSAgICAgICAodW5zaWduZWQpVk1MX1JFQUQzMihwYXIsIFZNTF9EU1BBUkIpKTsKCXByaW50ayhLRVJOX0RFQlVHIE1PRFVMRV9OQU1FICI6IFx0RFNQQ0FERFIgICAgICAgICA6IDB4JTA4eFxuIiwKCSAgICAgICAodW5zaWduZWQpVk1MX1JFQUQzMihwYXIsIFZNTF9EU1BDQUREUikpOwoJcHJpbnRrKEtFUk5fREVCVUcgTU9EVUxFX05BTUUgIjogXHRCQ0xSUEFUX0EgICAgICAgIDogMHglMDh4XG4iLAoJICAgICAgICh1bnNpZ25lZClWTUxfUkVBRDMyKHBhciwgVk1MX0JDTFJQQVRfQSkpOwoJcHJpbnRrKEtFUk5fREVCVUcgTU9EVUxFX05BTUUgIjogXHRDQU5WU0NMUl9BICAgICAgIDogMHglMDh4XG4iLAoJICAgICAgICh1bnNpZ25lZClWTUxfUkVBRDMyKHBhciwgVk1MX0NBTlZTQ0xSX0EpKTsKCXByaW50ayhLRVJOX0RFQlVHIE1PRFVMRV9OQU1FICI6IFx0UElQRUFTUkMgICAgICAgICA6IDB4JTA4eFxuIiwKCSAgICAgICAodW5zaWduZWQpVk1MX1JFQUQzMihwYXIsIFZNTF9QSVBFQVNSQykpOwoJcHJpbnRrKEtFUk5fREVCVUcgTU9EVUxFX05BTUUgIjogXHRQSVBFQUNPTkYgICAgICAgIDogMHglMDh4XG4iLAoJICAgICAgICh1bnNpZ25lZClWTUxfUkVBRDMyKHBhciwgVk1MX1BJUEVBQ09ORikpOwoJcHJpbnRrKEtFUk5fREVCVUcgTU9EVUxFX05BTUUgIjogXHREU1BDQ05UUiAgICAgICAgIDogMHglMDh4XG4iLAoJICAgICAgICh1bnNpZ25lZClWTUxfUkVBRDMyKHBhciwgVk1MX0RTUENDTlRSKSk7CglwcmludGsoS0VSTl9ERUJVRyBNT0RVTEVfTkFNRSAiOiBcdFJDT01QU1RBVCAgICAgICAgOiAweCUwOHhcbiIsCgkgICAgICAgKHVuc2lnbmVkKVZNTF9SRUFEMzIocGFyLCBWTUxfUkNPTVBTVEFUKSk7CglwcmludGsoS0VSTl9ERUJVRyBNT0RVTEVfTkFNRSAiOiBFbmQgb2YgbW9kZXNldHRpbmcgcmVnaXN0ZXIgZHVtcC5cbiIpOwp9CiNlbmRpZgoKc3RhdGljIGludCB2bWxmYl9zZXRfcGFyX2xvY2tlZChzdHJ1Y3Qgdm1sX2luZm8gKnZpbmZvKQp7CglzdHJ1Y3Qgdm1sX3BhciAqcGFyID0gdmluZm8tPnBhcjsKCXN0cnVjdCBmYl9pbmZvICppbmZvID0gJnZpbmZvLT5pbmZvOwoJc3RydWN0IGZiX3Zhcl9zY3JlZW5pbmZvICp2YXIgPSAmaW5mby0+dmFyOwoJdTMyIGh0b3RhbCwgaGFjdGl2ZSwgaGJsYW5rX3N0YXJ0LCBoYmxhbmtfZW5kLCBoc3luY19zdGFydCwgaHN5bmNfZW5kOwoJdTMyIHZ0b3RhbCwgdmFjdGl2ZSwgdmJsYW5rX3N0YXJ0LCB2YmxhbmtfZW5kLCB2c3luY19zdGFydCwgdnN5bmNfZW5kOwoJdTMyIGRzcGNudHI7CglpbnQgY2xvY2s7CgoJdmluZm8tPmJ5dGVzX3Blcl9waXhlbCA9IHZhci0+Yml0c19wZXJfcGl4ZWwgPj4gMzsKCXZpbmZvLT5zdHJpZGUgPQoJICAgIF9fQUxJR05fTUFTSyh2YXItPnhyZXNfdmlydHVhbCAqIHZpbmZvLT5ieXRlc19wZXJfcGl4ZWwsIDB4M0YpOwoJaW5mby0+Zml4LmxpbmVfbGVuZ3RoID0gdmluZm8tPnN0cmlkZTsKCglpZiAoIXN1YnN5cykKCQlyZXR1cm4gMDsKCglodG90YWwgPQoJICAgIHZhci0+eHJlcyArIHZhci0+cmlnaHRfbWFyZ2luICsgdmFyLT5oc3luY19sZW4gKyB2YXItPmxlZnRfbWFyZ2luOwoJaGFjdGl2ZSA9IHZhci0+eHJlczsKCWhibGFua19zdGFydCA9IHZhci0+eHJlczsKCWhibGFua19lbmQgPSBodG90YWw7Cgloc3luY19zdGFydCA9IGhhY3RpdmUgKyB2YXItPnJpZ2h0X21hcmdpbjsKCWhzeW5jX2VuZCA9IGhzeW5jX3N0YXJ0ICsgdmFyLT5oc3luY19sZW47CgoJdnRvdGFsID0KCSAgICB2YXItPnlyZXMgKyB2YXItPmxvd2VyX21hcmdpbiArIHZhci0+dnN5bmNfbGVuICsgdmFyLT51cHBlcl9tYXJnaW47Cgl2YWN0aXZlID0gdmFyLT55cmVzOwoJdmJsYW5rX3N0YXJ0ID0gdmFyLT55cmVzOwoJdmJsYW5rX2VuZCA9IHZ0b3RhbDsKCXZzeW5jX3N0YXJ0ID0gdmFjdGl2ZSArIHZhci0+bG93ZXJfbWFyZ2luOwoJdnN5bmNfZW5kID0gdnN5bmNfc3RhcnQgKyB2YXItPnZzeW5jX2xlbjsKCglkc3BjbnRyID0gVk1MX0dGWF9FTkFCTEUgfCBWTUxfR0ZYX0dBTU1BQllQQVNTOwoJY2xvY2sgPSBQSUNPUzJLSFoodmFyLT5waXhjbG9jayk7CgoJaWYgKHN1YnN5cy0+bmVhcmVzdF9jbG9jaykgewoJCWNsb2NrID0gc3Vic3lzLT5uZWFyZXN0X2Nsb2NrKHN1YnN5cywgY2xvY2spOwoJfSBlbHNlIHsKCQljbG9jayA9IHZtbF9uZWFyZXN0X2Nsb2NrKGNsb2NrKTsKCX0KCXByaW50ayhLRVJOX0RFQlVHIE1PRFVMRV9OQU1FCgkgICAgICAgIjogU2V0IG1vZGUgSGZyZXEgOiAlZCBrSHosIFZmcmVxIDogJWQgSHouXG4iLCBjbG9jayAvIGh0b3RhbCwKCSAgICAgICAoKGNsb2NrIC8gaHRvdGFsKSAqIDEwMDApIC8gdnRvdGFsKTsKCglzd2l0Y2ggKHZhci0+Yml0c19wZXJfcGl4ZWwpIHsKCWNhc2UgMTY6CgkJZHNwY250ciB8PSBWTUxfR0ZYX0FSR0IxNTU1OwoJCWJyZWFrOwoJY2FzZSAzMjoKCQlpZiAodmFyLT50cmFuc3AubGVuZ3RoID09IDgpCgkJCWRzcGNudHIgfD0gVk1MX0dGWF9BUkdCODg4OCB8IFZNTF9HRlhfQUxQSEFNVUxUOwoJCWVsc2UKCQkJZHNwY250ciB8PSBWTUxfR0ZYX1JHQjA4ODg7CgkJYnJlYWs7CglkZWZhdWx0OgoJCXJldHVybiAtRUlOVkFMOwoJfQoKCXZtbGZiX2Rpc2FibGVfcGlwZSh2aW5mbyk7CgltYigpOwoKCWlmIChzdWJzeXMtPnNldF9jbG9jaykKCQlzdWJzeXMtPnNldF9jbG9jayhzdWJzeXMsIGNsb2NrKTsKCWVsc2UKCQlyZXR1cm4gLUVJTlZBTDsKCglWTUxfV1JJVEUzMihwYXIsIFZNTF9IVE9UQUxfQSwgKChodG90YWwgLSAxKSA8PCAxNikgfCAoaGFjdGl2ZSAtIDEpKTsKCVZNTF9XUklURTMyKHBhciwgVk1MX0hCTEFOS19BLAoJCSAgICAoKGhibGFua19lbmQgLSAxKSA8PCAxNikgfCAoaGJsYW5rX3N0YXJ0IC0gMSkpOwoJVk1MX1dSSVRFMzIocGFyLCBWTUxfSFNZTkNfQSwKCQkgICAgKChoc3luY19lbmQgLSAxKSA8PCAxNikgfCAoaHN5bmNfc3RhcnQgLSAxKSk7CglWTUxfV1JJVEUzMihwYXIsIFZNTF9WVE9UQUxfQSwgKCh2dG90YWwgLSAxKSA8PCAxNikgfCAodmFjdGl2ZSAtIDEpKTsKCVZNTF9XUklURTMyKHBhciwgVk1MX1ZCTEFOS19BLAoJCSAgICAoKHZibGFua19lbmQgLSAxKSA8PCAxNikgfCAodmJsYW5rX3N0YXJ0IC0gMSkpOwoJVk1MX1dSSVRFMzIocGFyLCBWTUxfVlNZTkNfQSwKCQkgICAgKCh2c3luY19lbmQgLSAxKSA8PCAxNikgfCAodnN5bmNfc3RhcnQgLSAxKSk7CglWTUxfV1JJVEUzMihwYXIsIFZNTF9EU1BDU1RSSURFLCB2aW5mby0+c3RyaWRlKTsKCVZNTF9XUklURTMyKHBhciwgVk1MX0RTUENTSVpFLAoJCSAgICAoKHZhci0+eXJlcyAtIDEpIDw8IDE2KSB8ICh2YXItPnhyZXMgLSAxKSk7CglWTUxfV1JJVEUzMihwYXIsIFZNTF9EU1BDUE9TLCAweDAwMDAwMDAwKTsKCVZNTF9XUklURTMyKHBhciwgVk1MX0RTUEFSQiwgVk1MX0ZJRk9fREVGQVVMVCk7CglWTUxfV1JJVEUzMihwYXIsIFZNTF9CQ0xSUEFUX0EsIDB4MDAwMDAwMDApOwoJVk1MX1dSSVRFMzIocGFyLCBWTUxfQ0FOVlNDTFJfQSwgMHgwMDAwMDAwMCk7CglWTUxfV1JJVEUzMihwYXIsIFZNTF9QSVBFQVNSQywKCQkgICAgKCh2YXItPnhyZXMgLSAxKSA8PCAxNikgfCAodmFyLT55cmVzIC0gMSkpOwoKCXdtYigpOwoJVk1MX1dSSVRFMzIocGFyLCBWTUxfUElQRUFDT05GLCBWTUxfUElQRV9FTkFCTEUpOwoJd21iKCk7CglWTUxfV1JJVEUzMihwYXIsIFZNTF9EU1BDQ05UUiwgZHNwY250cik7Cgl3bWIoKTsKCVZNTF9XUklURTMyKHBhciwgVk1MX0RTUENBRERSLCAodTMyKSB2aW5mby0+dnJhbV9zdGFydCArCgkJICAgIHZhci0+eW9mZnNldCAqIHZpbmZvLT5zdHJpZGUgKwoJCSAgICB2YXItPnhvZmZzZXQgKiB2aW5mby0+Ynl0ZXNfcGVyX3BpeGVsKTsKCglWTUxfV1JJVEUzMihwYXIsIFZNTF9SQ09NUFNUQVQsIFZNTF9NRFZPX1BBRF9FTkFCTEUpOwoKCXdoaWxlICghKFZNTF9SRUFEMzIocGFyLCBWTUxfUkNPTVBTVEFUKSAmCgkJIChWTUxfTURWT19WRENfSV9SQ09NUCB8IFZNTF9NRFZPX1BBRF9FTkFCTEUpKSkgOwoKCXZpbmZvLT5waXBlX2Rpc2FibGVkID0gMDsKI2lmZGVmIFZFUk1JTElPTl9ERUJVRwoJdm1sX2R1bXBfcmVncyh2aW5mbyk7CiNlbmRpZgoKCXJldHVybiAwOwp9CgpzdGF0aWMgaW50IHZtbGZiX3NldF9wYXIoc3RydWN0IGZiX2luZm8gKmluZm8pCnsKCXN0cnVjdCB2bWxfaW5mbyAqdmluZm8gPSBjb250YWluZXJfb2YoaW5mbywgc3RydWN0IHZtbF9pbmZvLCBpbmZvKTsKCWludCByZXQ7CgoJbXV0ZXhfbG9jaygmdm1sX211dGV4KTsKCWxpc3RfZGVsKCZ2aW5mby0+aGVhZCk7CglsaXN0X2FkZCgmdmluZm8tPmhlYWQsIChzdWJzeXMpID8gJmdsb2JhbF9oYXNfbW9kZSA6ICZnbG9iYWxfbm9fbW9kZSk7CglyZXQgPSB2bWxmYl9zZXRfcGFyX2xvY2tlZCh2aW5mbyk7CgoJbXV0ZXhfdW5sb2NrKCZ2bWxfbXV0ZXgpOwoJcmV0dXJuIHJldDsKfQoKc3RhdGljIGludCB2bWxmYl9ibGFua19sb2NrZWQoc3RydWN0IHZtbF9pbmZvICp2aW5mbykKewoJc3RydWN0IHZtbF9wYXIgKnBhciA9IHZpbmZvLT5wYXI7Cgl1MzIgY3VyID0gVk1MX1JFQUQzMihwYXIsIFZNTF9QSVBFQUNPTkYpOwoKCXN3aXRjaCAodmluZm8tPmN1cl9ibGFua19tb2RlKSB7CgljYXNlIEZCX0JMQU5LX1VOQkxBTks6CgkJaWYgKHZpbmZvLT5waXBlX2Rpc2FibGVkKSB7CgkJCXZtbGZiX3NldF9wYXJfbG9ja2VkKHZpbmZvKTsKCQl9CgkJVk1MX1dSSVRFMzIocGFyLCBWTUxfUElQRUFDT05GLCBjdXIgJiB+Vk1MX1BJUEVfRk9SQ0VfQk9SREVSKTsKCQkodm9pZClWTUxfUkVBRDMyKHBhciwgVk1MX1BJUEVBQ09ORik7CgkJYnJlYWs7CgljYXNlIEZCX0JMQU5LX05PUk1BTDoKCQlpZiAodmluZm8tPnBpcGVfZGlzYWJsZWQpIHsKCQkJdm1sZmJfc2V0X3Bhcl9sb2NrZWQodmluZm8pOwoJCX0KCQlWTUxfV1JJVEUzMihwYXIsIFZNTF9QSVBFQUNPTkYsIGN1ciB8IFZNTF9QSVBFX0ZPUkNFX0JPUkRFUik7CgkJKHZvaWQpVk1MX1JFQUQzMihwYXIsIFZNTF9QSVBFQUNPTkYpOwoJCWJyZWFrOwoJY2FzZSBGQl9CTEFOS19WU1lOQ19TVVNQRU5EOgoJY2FzZSBGQl9CTEFOS19IU1lOQ19TVVNQRU5EOgoJCWlmICghdmluZm8tPnBpcGVfZGlzYWJsZWQpIHsKCQkJdm1sZmJfZGlzYWJsZV9waXBlKHZpbmZvKTsKCQl9CgkJYnJlYWs7CgljYXNlIEZCX0JMQU5LX1BPV0VSRE9XTjoKCQlpZiAoIXZpbmZvLT5waXBlX2Rpc2FibGVkKSB7CgkJCXZtbGZiX2Rpc2FibGVfcGlwZSh2aW5mbyk7CgkJfQoJCWJyZWFrOwoJZGVmYXVsdDoKCQlyZXR1cm4gLUVJTlZBTDsKCX0KCglyZXR1cm4gMDsKfQoKc3RhdGljIGludCB2bWxmYl9ibGFuayhpbnQgYmxhbmtfbW9kZSwgc3RydWN0IGZiX2luZm8gKmluZm8pCnsKCXN0cnVjdCB2bWxfaW5mbyAqdmluZm8gPSBjb250YWluZXJfb2YoaW5mbywgc3RydWN0IHZtbF9pbmZvLCBpbmZvKTsKCWludCByZXQ7CgoJbXV0ZXhfbG9jaygmdm1sX211dGV4KTsKCXZpbmZvLT5jdXJfYmxhbmtfbW9kZSA9IGJsYW5rX21vZGU7CglyZXQgPSB2bWxmYl9ibGFua19sb2NrZWQodmluZm8pOwoJbXV0ZXhfdW5sb2NrKCZ2bWxfbXV0ZXgpOwoJcmV0dXJuIHJldDsKfQoKc3RhdGljIGludCB2bWxmYl9wYW5fZGlzcGxheShzdHJ1Y3QgZmJfdmFyX3NjcmVlbmluZm8gKnZhciwKCQkJICAgICBzdHJ1Y3QgZmJfaW5mbyAqaW5mbykKewoJc3RydWN0IHZtbF9pbmZvICp2aW5mbyA9IGNvbnRhaW5lcl9vZihpbmZvLCBzdHJ1Y3Qgdm1sX2luZm8sIGluZm8pOwoJc3RydWN0IHZtbF9wYXIgKnBhciA9IHZpbmZvLT5wYXI7CgoJbXV0ZXhfbG9jaygmdm1sX211dGV4KTsKCVZNTF9XUklURTMyKHBhciwgVk1MX0RTUENBRERSLCAodTMyKSB2aW5mby0+dnJhbV9zdGFydCArCgkJICAgIHZhci0+eW9mZnNldCAqIHZpbmZvLT5zdHJpZGUgKwoJCSAgICB2YXItPnhvZmZzZXQgKiB2aW5mby0+Ynl0ZXNfcGVyX3BpeGVsKTsKCSh2b2lkKVZNTF9SRUFEMzIocGFyLCBWTUxfRFNQQ0FERFIpOwoJbXV0ZXhfdW5sb2NrKCZ2bWxfbXV0ZXgpOwoKCXJldHVybiAwOwp9CgpzdGF0aWMgaW50IHZtbGZiX3NldGNvbHJlZyh1X2ludCByZWdubywgdV9pbnQgcmVkLCB1X2ludCBncmVlbiwgdV9pbnQgYmx1ZSwKCQkJICAgdV9pbnQgdHJhbnNwLCBzdHJ1Y3QgZmJfaW5mbyAqaW5mbykKewoJdTMyIHY7CgoJaWYgKHJlZ25vID49IDE2KQoJCXJldHVybiAtRUlOVkFMOwoKCWlmIChpbmZvLT52YXIuZ3JheXNjYWxlKSB7CgkJcmVkID0gZ3JlZW4gPSBibHVlID0gKHJlZCAqIDc3ICsgZ3JlZW4gKiAxNTEgKyBibHVlICogMjgpID4+IDg7Cgl9CgoJaWYgKGluZm8tPmZpeC52aXN1YWwgIT0gRkJfVklTVUFMX1RSVUVDT0xPUikKCQlyZXR1cm4gLUVJTlZBTDsKCglyZWQgPSBWTUxfVE9IVyhyZWQsIGluZm8tPnZhci5yZWQubGVuZ3RoKTsKCWJsdWUgPSBWTUxfVE9IVyhibHVlLCBpbmZvLT52YXIuYmx1ZS5sZW5ndGgpOwoJZ3JlZW4gPSBWTUxfVE9IVyhncmVlbiwgaW5mby0+dmFyLmdyZWVuLmxlbmd0aCk7Cgl0cmFuc3AgPSBWTUxfVE9IVyh0cmFuc3AsIGluZm8tPnZhci50cmFuc3AubGVuZ3RoKTsKCgl2ID0gKHJlZCA8PCBpbmZvLT52YXIucmVkLm9mZnNldCkgfAoJICAgIChncmVlbiA8PCBpbmZvLT52YXIuZ3JlZW4ub2Zmc2V0KSB8CgkgICAgKGJsdWUgPDwgaW5mby0+dmFyLmJsdWUub2Zmc2V0KSB8CgkgICAgKHRyYW5zcCA8PCBpbmZvLT52YXIudHJhbnNwLm9mZnNldCk7CgoJc3dpdGNoIChpbmZvLT52YXIuYml0c19wZXJfcGl4ZWwpIHsKCWNhc2UgMTY6CgkJKCh1MzIgKikgaW5mby0+cHNldWRvX3BhbGV0dGUpW3JlZ25vXSA9IHY7CgkJYnJlYWs7CgljYXNlIDI0OgoJY2FzZSAzMjoKCQkoKHUzMiAqKSBpbmZvLT5wc2V1ZG9fcGFsZXR0ZSlbcmVnbm9dID0gdjsKCQlicmVhazsKCX0KCXJldHVybiAwOwp9CgpzdGF0aWMgaW50IHZtbGZiX21tYXAoc3RydWN0IGZiX2luZm8gKmluZm8sIHN0cnVjdCB2bV9hcmVhX3N0cnVjdCAqdm1hKQp7CglzdHJ1Y3Qgdm1sX2luZm8gKnZpbmZvID0gY29udGFpbmVyX29mKGluZm8sIHN0cnVjdCB2bWxfaW5mbywgaW5mbyk7Cgl1bnNpZ25lZCBsb25nIHNpemUgPSB2bWEtPnZtX2VuZCAtIHZtYS0+dm1fc3RhcnQ7Cgl1bnNpZ25lZCBsb25nIG9mZnNldCA9IHZtYS0+dm1fcGdvZmYgPDwgUEFHRV9TSElGVDsKCWludCByZXQ7CgoJaWYgKHZtYS0+dm1fcGdvZmYgPiAofjBVTCA+PiBQQUdFX1NISUZUKSkKCQlyZXR1cm4gLUVJTlZBTDsKCWlmIChvZmZzZXQgKyBzaXplID4gdmluZm8tPnZyYW1fY29udGlnX3NpemUpCgkJcmV0dXJuIC1FSU5WQUw7CglyZXQgPSB2bWxmYl92cmFtX29mZnNldCh2aW5mbywgb2Zmc2V0KTsKCWlmIChyZXQpCgkJcmV0dXJuIC1FSU5WQUw7CglvZmZzZXQgKz0gdmluZm8tPnZyYW1fc3RhcnQ7CglwZ3Byb3RfdmFsKHZtYS0+dm1fcGFnZV9wcm90KSB8PSBfUEFHRV9QQ0Q7CglwZ3Byb3RfdmFsKHZtYS0+dm1fcGFnZV9wcm90KSAmPSB+X1BBR0VfUFdUOwoJdm1hLT52bV9mbGFncyB8PSBWTV9SRVNFUlZFRCB8IFZNX0lPOwoJaWYgKHJlbWFwX3Bmbl9yYW5nZSh2bWEsIHZtYS0+dm1fc3RhcnQsIG9mZnNldCA+PiBQQUdFX1NISUZULAoJCQkJCQlzaXplLCB2bWEtPnZtX3BhZ2VfcHJvdCkpCgkJcmV0dXJuIC1FQUdBSU47CglyZXR1cm4gMDsKfQoKc3RhdGljIGludCB2bWxmYl9zeW5jKHN0cnVjdCBmYl9pbmZvICppbmZvKQp7CglyZXR1cm4gMDsKfQoKc3RhdGljIGludCB2bWxmYl9jdXJzb3Ioc3RydWN0IGZiX2luZm8gKmluZm8sIHN0cnVjdCBmYl9jdXJzb3IgKmN1cnNvcikKewoJcmV0dXJuIC1FSU5WQUw7CS8qIGp1c3QgdG8gZm9yY2Ugc29mdF9jdXJzb3IoKSBjYWxsICovCn0KCnN0YXRpYyBzdHJ1Y3QgZmJfb3BzIHZtbGZiX29wcyA9IHsKCS5vd25lciA9IFRISVNfTU9EVUxFLAoJLmZiX29wZW4gPSB2bWxmYl9vcGVuLAoJLmZiX3JlbGVhc2UgPSB2bWxmYl9yZWxlYXNlLAoJLmZiX2NoZWNrX3ZhciA9IHZtbGZiX2NoZWNrX3ZhciwKCS5mYl9zZXRfcGFyID0gdm1sZmJfc2V0X3BhciwKCS5mYl9ibGFuayA9IHZtbGZiX2JsYW5rLAoJLmZiX3Bhbl9kaXNwbGF5ID0gdm1sZmJfcGFuX2Rpc3BsYXksCgkuZmJfZmlsbHJlY3QgPSBjZmJfZmlsbHJlY3QsCgkuZmJfY29weWFyZWEgPSBjZmJfY29weWFyZWEsCgkuZmJfaW1hZ2VibGl0ID0gY2ZiX2ltYWdlYmxpdCwKCS5mYl9jdXJzb3IgPSB2bWxmYl9jdXJzb3IsCgkuZmJfc3luYyA9IHZtbGZiX3N5bmMsCgkuZmJfbW1hcCA9IHZtbGZiX21tYXAsCgkuZmJfc2V0Y29scmVnID0gdm1sZmJfc2V0Y29scmVnCn07CgpzdGF0aWMgc3RydWN0IHBjaV9kZXZpY2VfaWQgdm1sX2lkc1tdID0gewoJe1BDSV9ERVZJQ0UoUENJX1ZFTkRPUl9JRF9JTlRFTCwgVk1MX0RFVklDRV9WREMpfSwKCXswfQp9OwoKc3RhdGljIHN0cnVjdCBwY2lfZHJpdmVyIHZtbGZiX3BjaV9kcml2ZXIgPSB7CgkubmFtZSA9ICJ2bWxmYiIsCgkuaWRfdGFibGUgPSB2bWxfaWRzLAoJLnByb2JlID0gdm1sX3BjaV9wcm9iZSwKCS5yZW1vdmUgPSBfX2RldmV4aXRfcCh2bWxfcGNpX3JlbW92ZSkKfTsKCnN0YXRpYyB2b2lkIF9fZXhpdCB2bWxmYl9jbGVhbnVwKHZvaWQpCnsKCXBjaV91bnJlZ2lzdGVyX2RyaXZlcigmdm1sZmJfcGNpX2RyaXZlcik7Cn0KCnN0YXRpYyBpbnQgX19pbml0IHZtbGZiX2luaXQodm9pZCkKewoKI2lmbmRlZiBNT0RVTEUKCWNoYXIgKm9wdGlvbiA9IE5VTEw7CgoJaWYgKGZiX2dldF9vcHRpb25zKE1PRFVMRV9OQU1FLCAmb3B0aW9uKSkKCQlyZXR1cm4gLUVOT0RFVjsKI2VuZGlmCgoJcHJpbnRrKEtFUk5fREVCVUcgTU9EVUxFX05BTUUgIjogaW5pdGlhbGl6aW5nXG4iKTsKCW11dGV4X2luaXQoJnZtbF9tdXRleCk7CglJTklUX0xJU1RfSEVBRCgmZ2xvYmFsX25vX21vZGUpOwoJSU5JVF9MSVNUX0hFQUQoJmdsb2JhbF9oYXNfbW9kZSk7CgoJcmV0dXJuIHBjaV9yZWdpc3Rlcl9kcml2ZXIoJnZtbGZiX3BjaV9kcml2ZXIpOwp9CgppbnQgdm1sZmJfcmVnaXN0ZXJfc3Vic3lzKHN0cnVjdCB2bWxfc3lzICpzeXMpCnsKCXN0cnVjdCB2bWxfaW5mbyAqZW50cnk7CglzdHJ1Y3QgbGlzdF9oZWFkICpsaXN0OwoJdTMyIHNhdmVfYWN0aXZhdGU7CgoJbXV0ZXhfbG9jaygmdm1sX211dGV4KTsKCWlmIChzdWJzeXMgIT0gTlVMTCkgewoJCXN1YnN5cy0+cmVzdG9yZShzdWJzeXMpOwoJfQoJc3Vic3lzID0gc3lzOwoJc3Vic3lzLT5zYXZlKHN1YnN5cyk7CgoJLyoKCSAqIFdlIG5lZWQgdG8gcmVzdGFydCBsaXN0IHRyYXZlcnNhbCBmb3IgZWFjaCBpdGVtLCBzaW5jZSB3ZQoJICogcmVsZWFzZSB0aGUgbGlzdCBtdXRleCBpbiB0aGUgbG9vcC4KCSAqLwoKCWxpc3QgPSBnbG9iYWxfbm9fbW9kZS5uZXh0OwoJd2hpbGUgKGxpc3QgIT0gJmdsb2JhbF9ub19tb2RlKSB7CgkJbGlzdF9kZWxfaW5pdChsaXN0KTsKCQllbnRyeSA9IGxpc3RfZW50cnkobGlzdCwgc3RydWN0IHZtbF9pbmZvLCBoZWFkKTsKCgkJLyoKCQkgKiBGaXJzdCwgdHJ5IHRoZSBjdXJyZW50IG1vZGUgd2hpY2ggbWlnaHQgbm90IGJlCgkJICogY29tcGxldGVseSB2YWxpZGF0ZWQgd2l0aCByZXNwZWN0IHRvIHRoZSBwaXhlbCBjbG9jay4KCQkgKi8KCgkJaWYgKCF2bWxmYl9jaGVja192YXJfbG9ja2VkKCZlbnRyeS0+aW5mby52YXIsIGVudHJ5KSkgewoJCQl2bWxmYl9zZXRfcGFyX2xvY2tlZChlbnRyeSk7CgkJCWxpc3RfYWRkX3RhaWwobGlzdCwgJmdsb2JhbF9oYXNfbW9kZSk7CgkJfSBlbHNlIHsKCgkJCS8qCgkJCSAqIERpZG4ndCB3b3JrLiBUcnkgdG8gZmluZCBhbm90aGVyIG1vZGUsCgkJCSAqIHRoYXQgbWF0Y2hlcyB0aGlzIHN1YnN5cy4KCQkJICovCgoJCQltdXRleF91bmxvY2soJnZtbF9tdXRleCk7CgkJCXNhdmVfYWN0aXZhdGUgPSBlbnRyeS0+aW5mby52YXIuYWN0aXZhdGU7CgkJCWVudHJ5LT5pbmZvLnZhci5iaXRzX3Blcl9waXhlbCA9IDE2OwoJCQl2bWxmYl9zZXRfcHJlZl9waXhlbF9mb3JtYXQoJmVudHJ5LT5pbmZvLnZhcik7CgkJCWlmIChmYl9maW5kX21vZGUoJmVudHJ5LT5pbmZvLnZhciwKCQkJCQkgJmVudHJ5LT5pbmZvLAoJCQkJCSB2bWxfZGVmYXVsdF9tb2RlLCBOVUxMLCAwLCBOVUxMLCAxNikpIHsKCQkJCWVudHJ5LT5pbmZvLnZhci5hY3RpdmF0ZSB8PQoJCQkJICAgIEZCX0FDVElWQVRFX0ZPUkNFIHwgRkJfQUNUSVZBVEVfTk9XOwoJCQkJZmJfc2V0X3ZhcigmZW50cnktPmluZm8sICZlbnRyeS0+aW5mby52YXIpOwoJCQl9IGVsc2UgewoJCQkJcHJpbnRrKEtFUk5fRVJSIE1PRFVMRV9OQU1FCgkJCQkgICAgICAgIjogU29ycnkuIG5vIG1vZGUgZm91bmQgZm9yIHRoaXMgc3Vic3lzLlxuIik7CgkJCX0KCQkJZW50cnktPmluZm8udmFyLmFjdGl2YXRlID0gc2F2ZV9hY3RpdmF0ZTsKCQkJbXV0ZXhfbG9jaygmdm1sX211dGV4KTsKCQl9CgkJdm1sZmJfYmxhbmtfbG9ja2VkKGVudHJ5KTsKCQlsaXN0ID0gZ2xvYmFsX25vX21vZGUubmV4dDsKCX0KCW11dGV4X3VubG9jaygmdm1sX211dGV4KTsKCglwcmludGsoS0VSTl9ERUJVRyBNT0RVTEVfTkFNRSAiOiBSZWdpc3RlcmVkICVzIHN1YnN5c3RlbS5cbiIsCgkJCQlzdWJzeXMtPm5hbWUgPyBzdWJzeXMtPm5hbWUgOiAidW5rbm93biIpOwoJcmV0dXJuIDA7Cn0KCkVYUE9SVF9TWU1CT0xfR1BMKHZtbGZiX3JlZ2lzdGVyX3N1YnN5cyk7Cgp2b2lkIHZtbGZiX3VucmVnaXN0ZXJfc3Vic3lzKHN0cnVjdCB2bWxfc3lzICpzeXMpCnsKCXN0cnVjdCB2bWxfaW5mbyAqZW50cnksICpuZXh0OwoKCW11dGV4X2xvY2soJnZtbF9tdXRleCk7CglpZiAoc3Vic3lzICE9IHN5cykgewoJCW11dGV4X3VubG9jaygmdm1sX211dGV4KTsKCQlyZXR1cm47Cgl9CglzdWJzeXMtPnJlc3RvcmUoc3Vic3lzKTsKCXN1YnN5cyA9IE5VTEw7CglsaXN0X2Zvcl9lYWNoX2VudHJ5X3NhZmUoZW50cnksIG5leHQsICZnbG9iYWxfaGFzX21vZGUsIGhlYWQpIHsKCQlwcmludGsoS0VSTl9ERUJVRyBNT0RVTEVfTkFNRSAiOiBzdWJzeXMgZGlzYWJsZSBwaXBlXG4iKTsKCQl2bWxmYl9kaXNhYmxlX3BpcGUoZW50cnkpOwoJCWxpc3RfZGVsKCZlbnRyeS0+aGVhZCk7CgkJbGlzdF9hZGRfdGFpbCgmZW50cnktPmhlYWQsICZnbG9iYWxfbm9fbW9kZSk7Cgl9CgltdXRleF91bmxvY2soJnZtbF9tdXRleCk7Cn0KCkVYUE9SVF9TWU1CT0xfR1BMKHZtbGZiX3VucmVnaXN0ZXJfc3Vic3lzKTsKCm1vZHVsZV9pbml0KHZtbGZiX2luaXQpOwptb2R1bGVfZXhpdCh2bWxmYl9jbGVhbnVwKTsKCk1PRFVMRV9BVVRIT1IoIlR1bmdzdGVuIEdyYXBoaWNzIik7Ck1PRFVMRV9ERVNDUklQVElPTigiSW5pdGlhbGl6YXRpb24gb2YgdGhlIFZlcm1pbGlvbiBkaXNwbGF5IGRldmljZXMiKTsKTU9EVUxFX1ZFUlNJT04oIjEuMC4wIik7Ck1PRFVMRV9MSUNFTlNFKCJHUEwiKTsK