LyoKICoKICogdGRmeGZiLmMKICoKICogQXV0aG9yOiBIYW5udSBNYWxsYXQgPGhtYWxsYXRAY2MuaHV0LmZpPgogKgogKiBDb3B5cmlnaHQgqSAxOTk5IEhhbm51IE1hbGxhdAogKiBBbGwgcmlnaHRzIHJlc2VydmVkCiAqCiAqIENyZWF0ZWQgICAgICA6IFRodSBTZXAgMjMgMTg6MTc6NDMgMTk5OSwgaG1hbGxhdAogKiBMYXN0IG1vZGlmaWVkOiBUdWUgTm92ICAyIDIxOjE5OjQ3IDE5OTksIGhtYWxsYXQKICoKICogTG90cyBvZiB0aGUgaW5mb3JtYXRpb24gaGVyZSBjb21lcyBmcm9tIHRoZSBEYXJ5bGwgU3RyYXVzcycgQmFuc2hlZSAKICogcGF0Y2hlcyB0byB0aGUgWEY4NiBzZXJ2ZXIsIGFuZCB0aGUgcmVzdCBjb21lcyBmcm9tIHRoZSAzZGZ4CiAqIEJhbnNoZWUgc3BlY2lmaWNhdGlvbi4gSSdtIHZlcnkgbXVjaCBpbmRlYnRlZCB0byBEYXJ5bGwgZm9yIGhpcwogKiB3b3JrIG9uIHRoZSBYIHNlcnZlci4KICoKICogVm9vZG9vMyBzdXBwb3J0IHdhcyBjb250cmlidXRlZCBIYXJvbGQgT2dhLiBMb3RzIG9mIGFkZGl0aW9ucwogKiAocHJvcGVyIGFjY2VsZXJhdGlvbiwgMjQgYnBwLCBoYXJkd2FyZSBjdXJzb3IpIGFuZCBidWcgZml4ZXMgYnkgQXR0aWxhCiAqIEtlc21hcmtpLiBUaGFua3MgZ3V5cyEKICoKICogVm9vZG9vMSBhbmQgVm9vZG9vMiBzdXBwb3J0IGFyZW4ndCByZWxldmFudCB0byB0aGlzIGRyaXZlciBhcyB0aGV5CiAqIGJlaGF2ZSB2ZXJ5IGRpZmZlcmVudGx5IGZyb20gdGhlIFZvb2RvbzMvNC81LiBGb3IgYW55b25lIHdhbnRpbmcgdG8KICogdXNlIGZyYW1lIGJ1ZmZlciBvbiB0aGUgVm9vZG9vMS8yLCBzZWUgdGhlIHNzdGZiIGRyaXZlciAod2hpY2ggaXMKICogbG9jYXRlZCBhdCBodHRwOi8vd3d3LnNvdXJjZWZvcmdlLm5ldC9wcm9qZWN0cy9zc3RmYikuCiAqIAogKiBXaGlsZSBJIF9hbV8gZ3JhdGVmdWwgdG8gM0RmeCBmb3IgcmVsZWFzaW5nIHRoZSBzcGVjcyBmb3IgQmFuc2hlZSwKICogSSBkbyB3aXNoIHRoZSBuZXh0IHZlcnNpb24gaXMgYSBiaXQgbW9yZSBjb21wbGV0ZS4gV2l0aG91dCB0aGUgWEY4NgogKiBwYXRjaGVzIEkgY291bGRuJ3QgaGF2ZSBnb3R0ZW4gZXZlbiB0aGlzIGZhci4uLiBmb3IgaW5zdGFuY2UsIHRoZQogKiBleHRlbnNpb25zIHRvIHRoZSBWR0EgcmVnaXN0ZXIgc2V0IGdvIGNvbXBsZXRlbHkgdW5tZW50aW9uZWQgaW4gdGhlCiAqIHNwZWMhIEFsc28sIGxvdHMgb2YgcmVmZXJlbmNlcyBhcmUgbWFkZSB0byB0aGUgJ1NTVCBjb3JlJywgYnV0IG5vCiAqIHNwZWMgaXMgcHVibGljbHkgYXZhaWxhYmxlLCBBRkFJSy4KICoKICogVGhlIHN0cnVjdHVyZSBvZiB0aGlzIGRyaXZlciBjb21lcyBwcmV0dHkgbXVjaCBmcm9tIHRoZSBQZXJtZWRpYQogKiBkcml2ZXIgYnkgSWxhcmlvIE5hcmRpbm9jY2hpLCB3aGljaCBpbiB0dXJuIGlzIGJhc2VkIG9uIHNrZWxldG9uZmIuCiAqIAogKiBUT0RPOgogKiAtIHN1cHBvcnQgZm9yIDE2LzMyIGJwcCBuZWVkcyBmaXhpbmcgKGZ1bmt5IGJvb3R1cCBwZW5ndWluKQogKiAtIG11bHRpaGVhZCBzdXBwb3J0IChiYXNpY2FsbHkgbmVlZCB0byBzdXBwb3J0IGFuIGFycmF5IG9mIGZiX2luZm9zKQogKiAtIHN1cHBvcnQgb3RoZXIgYXJjaGl0ZWN0dXJlcyAoUFBDLCBBbHBoYSk7IGRvZXMgdGhlIGZhY3QgdGhhdCB0aGUgVkdBCiAqICAgY29yZSBjYW4gYmUgYWNjZXNzZWQgb25seSB0aHJ1IEkvTyAobm90IG1lbW9yeSBtYXBwZWQpIGNvbXBsaWNhdGUKICogICB0aGluZ3M/CiAqCiAqIFZlcnNpb24gaGlzdG9yeToKICoKICogMC4xLjQgKHJlbGVhc2VkIDIwMDItMDUtMjgpIHBvcnRlZCBvdmVyIHRvIG5ldyBmYmRldiBhcGkgYnkgSmFtZXMgU2ltbW9ucwogKgogKiAwLjEuMyAocmVsZWFzZWQgMTk5OS0xMS0wMikgYWRkZWQgQXR0aWxhJ3MgcGFubmluZyBzdXBwb3J0LCBjb2RlCiAqCQkJICAgICAgIHJlb3JnLCBod2N1cnNvciBhZGRyZXNzIHBhZ2Ugc2l6ZSBhbGlnbm1lbnQKICogICAgICAgICAgICAgICAgICAgICAgICAgICAgIChmb3IgbW1hcGluZyBib3RoIGZyYW1lIGJ1ZmZlciBhbmQgcmVncyksCiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbmQgbXkgY2hhbmdlcyB0byBnZXQgcmlkIG9mIGhhcmRjb2RlZAogKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVkdBIGkvbyByZWdpc3RlciBsb2NhdGlvbnMgKHVzZXMgUENJCiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25maWd1cmF0aW9uIGluZm8gbm93KQogKiAwLjEuMiAocmVsZWFzZWQgMTk5OS0xMC0xOSkgYWRkZWQgQXR0aWxhIEtlc21hcmtpJ3MgYnVnIGZpeGVzIGFuZAogKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW1wcm92ZW1lbnRzCiAqIDAuMS4xIChyZWxlYXNlZCAxOTk5LTEwLTA3KSBhZGRlZCBWb29kb28zIHN1cHBvcnQgYnkgSGFyb2xkIE9nYS4KICogMC4xLjAgKHJlbGVhc2VkIDE5OTktMTAtMDYpIGluaXRpYWwgdmVyc2lvbgogKgogKi8KCiNpbmNsdWRlIDxsaW51eC9jb25maWcuaD4KI2luY2x1ZGUgPGxpbnV4L21vZHVsZS5oPgojaW5jbHVkZSA8bGludXgva2VybmVsLmg+CiNpbmNsdWRlIDxsaW51eC9lcnJuby5oPgojaW5jbHVkZSA8bGludXgvc3RyaW5nLmg+CiNpbmNsdWRlIDxsaW51eC9tbS5oPgojaW5jbHVkZSA8bGludXgvdHR5Lmg+CiNpbmNsdWRlIDxsaW51eC9zbGFiLmg+CiNpbmNsdWRlIDxsaW51eC9kZWxheS5oPgojaW5jbHVkZSA8bGludXgvaW50ZXJydXB0Lmg+CiNpbmNsdWRlIDxsaW51eC9mYi5oPgojaW5jbHVkZSA8bGludXgvaW5pdC5oPgojaW5jbHVkZSA8bGludXgvcGNpLmg+CiNpbmNsdWRlIDxsaW51eC9udnJhbS5oPgojaW5jbHVkZSA8YXNtL2lvLmg+CiNpbmNsdWRlIDxsaW51eC90aW1lci5oPgojaW5jbHVkZSA8bGludXgvc3BpbmxvY2suaD4KCiNpbmNsdWRlIDx2aWRlby90ZGZ4Lmg+CgojdW5kZWYgVERGWEZCX0RFQlVHIAojaWZkZWYgVERGWEZCX0RFQlVHCiNkZWZpbmUgRFBSSU5USyhhLGIuLi4pIHByaW50ayhLRVJOX0RFQlVHICJmYjogJXM6ICIgYSwgX19GVU5DVElPTl9fICwgIyMgYikKI2Vsc2UKI2RlZmluZSBEUFJJTlRLKGEsYi4uLikKI2VuZGlmIAoKI2RlZmluZSBCQU5TSEVFX01BWF9QSVhDTE9DSyAyNzAwMDAKI2RlZmluZSBWT09ET08zX01BWF9QSVhDTE9DSyAzMDAwMDAKI2RlZmluZSBWT09ET081X01BWF9QSVhDTE9DSyAzNTAwMDAKCnN0YXRpYyBzdHJ1Y3QgZmJfZml4X3NjcmVlbmluZm8gdGRmeF9maXggX19kZXZpbml0ZGF0YSA9IHsKCS5pZCA9CQkiM0RmeCIsCgkudHlwZSA9CQlGQl9UWVBFX1BBQ0tFRF9QSVhFTFMsCgkudmlzdWFsID0JRkJfVklTVUFMX1BTRVVET0NPTE9SLCAKCS55cGFuc3RlcCA9CTEsCgkueXdyYXBzdGVwID0JMSwgCgkuYWNjZWwgPQlGQl9BQ0NFTF8zREZYX0JBTlNIRUUKfTsKCnN0YXRpYyBzdHJ1Y3QgZmJfdmFyX3NjcmVlbmluZm8gdGRmeF92YXIgX19kZXZpbml0ZGF0YSA9IHsKCS8qICI2NDB4NDgwLCA4IGJwcCBAIDYwIEh6ICovCgkueHJlcyA9CQk2NDAsCgkueXJlcyA9CQk0ODAsCgkueHJlc192aXJ0dWFsID0JNjQwLAoJLnlyZXNfdmlydHVhbCA9CTEwMjQsCgkuYml0c19wZXJfcGl4ZWwgPTgsCgkucmVkID0JCXswLCA4LCAwfSwKCS5ibHVlID0JCXswLCA4LCAwfSwKCS5ncmVlbiA9CXswLCA4LCAwfSwKCS5hY3RpdmF0ZSA9CUZCX0FDVElWQVRFX05PVywKCS5oZWlnaHQgPQktMSwKCS53aWR0aCA9CS0xLAoJLmFjY2VsX2ZsYWdzID0JRkJfQUNDRUxGX1RFWFQsCgkucGl4Y2xvY2sgPQkzOTcyMiwKCS5sZWZ0X21hcmdpbiA9CTQwLAoJLnJpZ2h0X21hcmdpbiA9CTI0LAoJLnVwcGVyX21hcmdpbiA9CTMyLAoJLmxvd2VyX21hcmdpbiA9CTExLAoJLmhzeW5jX2xlbiA9CTk2LAoJLnZzeW5jX2xlbiA9CTIsCgkudm1vZGUgPQlGQl9WTU9ERV9OT05JTlRFUkxBQ0VECn07CgovKgogKiBQQ0kgZHJpdmVyIHByb3RvdHlwZXMKICovCnN0YXRpYyBpbnQgX19kZXZpbml0IHRkZnhmYl9wcm9iZShzdHJ1Y3QgcGNpX2RldiAqcGRldiwKCQkJCSAgY29uc3Qgc3RydWN0IHBjaV9kZXZpY2VfaWQgKmlkKTsKc3RhdGljIHZvaWQgX19kZXZleGl0IHRkZnhmYl9yZW1vdmUoc3RydWN0IHBjaV9kZXYgKnBkZXYpOwoKc3RhdGljIHN0cnVjdCBwY2lfZGV2aWNlX2lkIHRkZnhmYl9pZF90YWJsZVtdID0gewoJeyBQQ0lfVkVORE9SX0lEXzNERlgsIFBDSV9ERVZJQ0VfSURfM0RGWF9CQU5TSEVFLAoJICBQQ0lfQU5ZX0lELCBQQ0lfQU5ZX0lELCBQQ0lfQkFTRV9DTEFTU19ESVNQTEFZIDw8IDE2LAoJICAweGZmMDAwMCwgMCB9LAoJeyBQQ0lfVkVORE9SX0lEXzNERlgsIFBDSV9ERVZJQ0VfSURfM0RGWF9WT09ET08zLAoJICBQQ0lfQU5ZX0lELCBQQ0lfQU5ZX0lELCBQQ0lfQkFTRV9DTEFTU19ESVNQTEFZIDw8IDE2LAoJICAweGZmMDAwMCwgMCB9LAoJeyBQQ0lfVkVORE9SX0lEXzNERlgsIFBDSV9ERVZJQ0VfSURfM0RGWF9WT09ET081LAoJICBQQ0lfQU5ZX0lELCBQQ0lfQU5ZX0lELCBQQ0lfQkFTRV9DTEFTU19ESVNQTEFZIDw8IDE2LAoJICAweGZmMDAwMCwgMCB9LAoJeyAwLCB9Cn07CgpzdGF0aWMgc3RydWN0IHBjaV9kcml2ZXIgdGRmeGZiX2RyaXZlciA9IHsKCS5uYW1lCQk9ICJ0ZGZ4ZmIiLAoJLmlkX3RhYmxlIAk9IHRkZnhmYl9pZF90YWJsZSwKCS5wcm9iZSAJCT0gdGRmeGZiX3Byb2JlLAoJLnJlbW92ZSAJPSBfX2RldmV4aXRfcCh0ZGZ4ZmJfcmVtb3ZlKSwKfTsKCk1PRFVMRV9ERVZJQ0VfVEFCTEUocGNpLCB0ZGZ4ZmJfaWRfdGFibGUpOwoKLyoKICogIEZyYW1lIGJ1ZmZlciBkZXZpY2UgQVBJCiAqLwpzdGF0aWMgaW50IHRkZnhmYl9jaGVja192YXIoc3RydWN0IGZiX3Zhcl9zY3JlZW5pbmZvICp2YXIsIHN0cnVjdCBmYl9pbmZvICpmYik7IApzdGF0aWMgaW50IHRkZnhmYl9zZXRfcGFyKHN0cnVjdCBmYl9pbmZvICppbmZvKTsgCnN0YXRpYyBpbnQgdGRmeGZiX3NldGNvbHJlZyh1X2ludCByZWdubywgdV9pbnQgcmVkLCB1X2ludCBncmVlbiwgdV9pbnQgYmx1ZSwgCgkJCSAgICB1X2ludCB0cmFuc3AsIHN0cnVjdCBmYl9pbmZvICppbmZvKTsgCnN0YXRpYyBpbnQgdGRmeGZiX2JsYW5rKGludCBibGFuaywgc3RydWN0IGZiX2luZm8gKmluZm8pOyAKc3RhdGljIGludCB0ZGZ4ZmJfcGFuX2Rpc3BsYXkoc3RydWN0IGZiX3Zhcl9zY3JlZW5pbmZvICp2YXIsIHN0cnVjdCBmYl9pbmZvICppbmZvKTsKc3RhdGljIGludCBiYW5zaGVlX3dhaXRfaWRsZShzdHJ1Y3QgZmJfaW5mbyAqaW5mbyk7CiNpZmRlZiBDT05GSUdfRkJfM0RGWF9BQ0NFTApzdGF0aWMgdm9pZCB0ZGZ4ZmJfZmlsbHJlY3Qoc3RydWN0IGZiX2luZm8gKmluZm8sIGNvbnN0IHN0cnVjdCBmYl9maWxscmVjdCAqcmVjdCk7CnN0YXRpYyB2b2lkIHRkZnhmYl9jb3B5YXJlYShzdHJ1Y3QgZmJfaW5mbyAqaW5mbywgY29uc3Qgc3RydWN0IGZiX2NvcHlhcmVhICphcmVhKTsgIApzdGF0aWMgdm9pZCB0ZGZ4ZmJfaW1hZ2VibGl0KHN0cnVjdCBmYl9pbmZvICppbmZvLCBjb25zdCBzdHJ1Y3QgZmJfaW1hZ2UgKmltYWdlKTsgCiNlbmRpZiAvKiBDT05GSUdfRkJfM0RGWF9BQ0NFTCAqLwoKc3RhdGljIHN0cnVjdCBmYl9vcHMgdGRmeGZiX29wcyA9IHsKCS5vd25lcgkJPSBUSElTX01PRFVMRSwKCS5mYl9jaGVja192YXIJPSB0ZGZ4ZmJfY2hlY2tfdmFyLAoJLmZiX3NldF9wYXIJPSB0ZGZ4ZmJfc2V0X3BhciwKCS5mYl9zZXRjb2xyZWcJPSB0ZGZ4ZmJfc2V0Y29scmVnLAoJLmZiX2JsYW5rCT0gdGRmeGZiX2JsYW5rLAoJLmZiX3Bhbl9kaXNwbGF5CT0gdGRmeGZiX3Bhbl9kaXNwbGF5LAoJLmZiX3N5bmMJPSBiYW5zaGVlX3dhaXRfaWRsZSwKI2lmZGVmIENPTkZJR19GQl8zREZYX0FDQ0VMCgkuZmJfZmlsbHJlY3QJPSB0ZGZ4ZmJfZmlsbHJlY3QsCgkuZmJfY29weWFyZWEJPSB0ZGZ4ZmJfY29weWFyZWEsCgkuZmJfaW1hZ2VibGl0CT0gdGRmeGZiX2ltYWdlYmxpdCwKI2Vsc2UKCS5mYl9maWxscmVjdAk9IGNmYl9maWxscmVjdCwKCS5mYl9jb3B5YXJlYQk9IGNmYl9jb3B5YXJlYSwKCS5mYl9pbWFnZWJsaXQJPSBjZmJfaW1hZ2VibGl0LAojZW5kaWYKCS5mYl9jdXJzb3IJPSBzb2Z0X2N1cnNvciwKfTsKCi8qCiAqIGRvX3h4eDogSGFyZHdhcmUtc3BlY2lmaWMgZnVuY3Rpb25zCiAqLwpzdGF0aWMgdTMyIGRvX2NhbGNfcGxsKGludCBmcmVxLCBpbnQgKmZyZXFfb3V0KTsKc3RhdGljIHZvaWQgIGRvX3dyaXRlX3JlZ3Moc3RydWN0IGZiX2luZm8gKmluZm8sIHN0cnVjdCBiYW5zaGVlX3JlZyAqcmVnKTsKc3RhdGljIHVuc2lnbmVkIGxvbmcgZG9fbGZiX3NpemUoc3RydWN0IHRkZnhfcGFyICpwYXIsIHVuc2lnbmVkIHNob3J0KTsKCi8qCiAqIERyaXZlciBkYXRhIAogKi8Kc3RhdGljIGludCAgbm9wYW4gICA9IDA7CnN0YXRpYyBpbnQgIG5vd3JhcCAgPSAxOyAgICAgIC8vIG5vdCBpbXBsZW1lbnRlZCAoeWV0KQpzdGF0aWMgY2hhciAqbW9kZV9vcHRpb24gX19kZXZpbml0ZGF0YSA9IE5VTEw7CgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIAogKiAgICAgICAgICAgICAgICAgICAgICBIYXJkd2FyZS1zcGVjaWZpYyBmdW5jaW9ucwogKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgojaWZkZWYgVkdBX1JFR19JTyAKc3RhdGljIGlubGluZSAgdTggdmdhX2luYihzdHJ1Y3QgdGRmeF9wYXIgKnBhciwgdTMyIHJlZykgeyByZXR1cm4gaW5iKHJlZyk7IH0KCnN0YXRpYyBpbmxpbmUgdm9pZCB2Z2Ffb3V0YihzdHJ1Y3QgdGRmeF9wYXIgKnBhciwgdTMyIHJlZywgIHU4IHZhbCkgeyBvdXRiKHZhbCwgcmVnKTsgfQojZWxzZQpzdGF0aWMgaW5saW5lICB1OCB2Z2FfaW5iKHN0cnVjdCB0ZGZ4X3BhciAqcGFyLCB1MzIgcmVnKSB7IAoJcmV0dXJuIGluYihwYXItPmlvYmFzZSArIHJlZyAtIDB4MzAwKTsgCn0Kc3RhdGljIGlubGluZSB2b2lkIHZnYV9vdXRiKHN0cnVjdCB0ZGZ4X3BhciAqcGFyLCB1MzIgcmVnLCAgdTggdmFsKSB7IAoJb3V0Yih2YWwsIHBhci0+aW9iYXNlICsgcmVnIC0gMHgzMDApOyAKfQojZW5kaWYKCnN0YXRpYyBpbmxpbmUgdm9pZCBncmFfb3V0YihzdHJ1Y3QgdGRmeF9wYXIgKnBhciwgdTMyIGlkeCwgdTggdmFsKSB7Cgl2Z2Ffb3V0YihwYXIsIEdSQV9JLCBpZHgpOyB2Z2Ffb3V0YihwYXIsIEdSQV9ELCB2YWwpOwp9CgpzdGF0aWMgaW5saW5lIHZvaWQgc2VxX291dGIoc3RydWN0IHRkZnhfcGFyICpwYXIsIHUzMiBpZHgsIHU4IHZhbCkgewoJdmdhX291dGIocGFyLCBTRVFfSSwgaWR4KTsgdmdhX291dGIocGFyLCBTRVFfRCwgdmFsKTsKfQoKc3RhdGljIGlubGluZSB1OCBzZXFfaW5iKHN0cnVjdCB0ZGZ4X3BhciAqcGFyLCB1MzIgaWR4KSB7Cgl2Z2Ffb3V0YihwYXIsIFNFUV9JLCBpZHgpOyByZXR1cm4gdmdhX2luYihwYXIsIFNFUV9EKTsKfQoKc3RhdGljIGlubGluZSB2b2lkIGNydF9vdXRiKHN0cnVjdCB0ZGZ4X3BhciAqcGFyLCB1MzIgaWR4LCB1OCB2YWwpIHsKCXZnYV9vdXRiKHBhciwgQ1JUX0ksIGlkeCk7IHZnYV9vdXRiKHBhciwgQ1JUX0QsIHZhbCk7Cn0KCnN0YXRpYyBpbmxpbmUgdTggY3J0X2luYihzdHJ1Y3QgdGRmeF9wYXIgKnBhciwgdTMyIGlkeCkgewoJdmdhX291dGIocGFyLCBDUlRfSSwgaWR4KTsgcmV0dXJuIHZnYV9pbmIocGFyLCBDUlRfRCk7Cn0KCnN0YXRpYyBpbmxpbmUgdm9pZCBhdHRfb3V0YihzdHJ1Y3QgdGRmeF9wYXIgKnBhciwgdTMyIGlkeCwgdTggdmFsKSAKewoJdW5zaWduZWQgY2hhciB0bXA7CgkKCXRtcCA9IHZnYV9pbmIocGFyLCBJUzFfUik7Cgl2Z2Ffb3V0YihwYXIsIEFUVF9JVywgaWR4KTsKCXZnYV9vdXRiKHBhciwgQVRUX0lXLCB2YWwpOwp9CgpzdGF0aWMgaW5saW5lIHZvaWQgdmdhX2Rpc2FibGVfdmlkZW8oc3RydWN0IHRkZnhfcGFyICpwYXIpCnsKCXVuc2lnbmVkIGNoYXIgczsKCglzID0gc2VxX2luYihwYXIsIDB4MDEpIHwgMHgyMDsKCXNlcV9vdXRiKHBhciwgMHgwMCwgMHgwMSk7CglzZXFfb3V0YihwYXIsIDB4MDEsIHMpOwoJc2VxX291dGIocGFyLCAweDAwLCAweDAzKTsKfQoKc3RhdGljIGlubGluZSB2b2lkIHZnYV9lbmFibGVfdmlkZW8oc3RydWN0IHRkZnhfcGFyICpwYXIpCnsKCXVuc2lnbmVkIGNoYXIgczsKCglzID0gc2VxX2luYihwYXIsIDB4MDEpICYgMHhkZjsKCXNlcV9vdXRiKHBhciwgMHgwMCwgMHgwMSk7CglzZXFfb3V0YihwYXIsIDB4MDEsIHMpOwoJc2VxX291dGIocGFyLCAweDAwLCAweDAzKTsKfQoKc3RhdGljIGlubGluZSB2b2lkIHZnYV9lbmFibGVfcGFsZXR0ZShzdHJ1Y3QgdGRmeF9wYXIgKnBhcikKewoJdmdhX2luYihwYXIsIElTMV9SKTsKCXZnYV9vdXRiKHBhciwgQVRUX0lXLCAweDIwKTsKfQoKc3RhdGljIGlubGluZSB1MzIgdGRmeF9pbmwoc3RydWN0IHRkZnhfcGFyICpwYXIsIHVuc2lnbmVkIGludCByZWcpIAp7CglyZXR1cm4gcmVhZGwocGFyLT5yZWdiYXNlX3ZpcnQgKyByZWcpOwp9CgpzdGF0aWMgaW5saW5lIHZvaWQgdGRmeF9vdXRsKHN0cnVjdCB0ZGZ4X3BhciAqcGFyLCB1bnNpZ25lZCBpbnQgcmVnLCB1MzIgdmFsKQp7Cgl3cml0ZWwodmFsLCBwYXItPnJlZ2Jhc2VfdmlydCArIHJlZyk7Cn0KCnN0YXRpYyBpbmxpbmUgdm9pZCBiYW5zaGVlX21ha2Vfcm9vbShzdHJ1Y3QgdGRmeF9wYXIgKnBhciwgaW50IHNpemUpCnsKCS8qIE5vdGU6IFRoZSBWb29kb28zJ3Mgb25ib2FyZCBGSUZPIGhhcyAzMiBzbG90cy4gVGhpcyBsb29wCgkgKiB3b24ndCBxdWl0IGlmIHlvdSBhc2sgZm9yIG1vcmUuICovCgl3aGlsZSgodGRmeF9pbmwocGFyLCBTVEFUVVMpICYgMHgxZikgPCBzaXplLTEpOwp9CiAKc3RhdGljIGludCBiYW5zaGVlX3dhaXRfaWRsZShzdHJ1Y3QgZmJfaW5mbyAqaW5mbykKewoJc3RydWN0IHRkZnhfcGFyICpwYXIgPSAoc3RydWN0IHRkZnhfcGFyICopIGluZm8tPnBhcjsgCglpbnQgaSA9IDA7CgoJYmFuc2hlZV9tYWtlX3Jvb20ocGFyLCAxKTsKCXRkZnhfb3V0bChwYXIsIENPTU1BTkRfM0QsIENPTU1BTkRfM0RfTk9QKTsKCgl3aGlsZSgxKSB7CgkJaSA9ICh0ZGZ4X2lubChwYXIsIFNUQVRVUykgJiBTVEFUVVNfQlVTWSkgPyAwIDogaSArIDE7CgkJaWYoaSA9PSAzKSBicmVhazsKCX0KCXJldHVybiAwOwp9CgovKgogKiBTZXQgdGhlIGNvbG9yIG9mIGEgcGFsZXR0ZSBlbnRyeSBpbiA4YnBwIG1vZGUgCiAqLwpzdGF0aWMgaW5saW5lIHZvaWQgZG9fc2V0cGFsZW50cnkoc3RydWN0IHRkZnhfcGFyICpwYXIsIHVuc2lnbmVkIHJlZ25vLCB1MzIgYykKeyAgCgliYW5zaGVlX21ha2Vfcm9vbShwYXIsIDIpOwoJdGRmeF9vdXRsKHBhciwgREFDQUREUiwgcmVnbm8pOwoJdGRmeF9vdXRsKHBhciwgREFDREFUQSwgYyk7Cn0KCnN0YXRpYyB1MzIgZG9fY2FsY19wbGwoaW50IGZyZXEsIGludCogZnJlcV9vdXQpIAp7CglpbnQgbSwgbiwgaywgYmVzdF9tLCBiZXN0X24sIGJlc3RfaywgZl9jdXIsIGJlc3RfZXJyb3I7CglpbnQgZnJlZiA9IDE0MzE4OwogIAoJLyogdGhpcyByZWFsbHkgY291bGQgYmUgZG9uZSB3aXRoIG1vcmUgaW50ZWxsaWdlbmNlIC0tCgkgICAyNTUqNjMqNCA9IDY0MjYwIGl0ZXJhdGlvbnMgaXMgc2lsbHkgKi8KCWJlc3RfZXJyb3IgPSBmcmVxOwoJYmVzdF9uID0gYmVzdF9tID0gYmVzdF9rID0gMDsKCWZvciAobiA9IDE7IG4gPCAyNTY7IG4rKykgewoJCWZvciAobSA9IDE7IG0gPCA2NDsgbSsrKSB7CgkJCWZvciAoayA9IDA7IGsgPCA0OyBrKyspIHsKCQkJCWZfY3VyID0gZnJlZioobiArIDIpLyhtICsgMikvKDEgPDwgayk7CgkJCQlpZiAoYWJzKGZfY3VyIC0gZnJlcSkgPCBiZXN0X2Vycm9yKSB7CgkJCQkJYmVzdF9lcnJvciA9IGFicyhmX2N1ci1mcmVxKTsKCQkJCQliZXN0X24gPSBuOwoJCQkJCWJlc3RfbSA9IG07CgkJCQkJYmVzdF9rID0gazsKCQkJCX0KCQkJfQoJCX0KCX0KCW4gPSBiZXN0X247CgltID0gYmVzdF9tOwoJayA9IGJlc3RfazsKCSpmcmVxX291dCA9IGZyZWYqKG4gKyAyKS8obSArIDIpLygxIDw8IGspOwoJcmV0dXJuIChuIDw8IDgpIHwgKG0gPDwgMikgfCBrOwp9CgpzdGF0aWMgdm9pZCBkb193cml0ZV9yZWdzKHN0cnVjdCBmYl9pbmZvICppbmZvLCBzdHJ1Y3QgYmFuc2hlZV9yZWcqIHJlZykgCnsKCXN0cnVjdCB0ZGZ4X3BhciAqcGFyID0gKHN0cnVjdCB0ZGZ4X3BhciAqKSBpbmZvLT5wYXI7IAoJaW50IGk7CgoJYmFuc2hlZV93YWl0X2lkbGUoaW5mbyk7CgoJdGRmeF9vdXRsKHBhciwgTUlTQ0lOSVQxLCB0ZGZ4X2lubChwYXIsIE1JU0NJTklUMSkgfCAweDAxKTsKCgljcnRfb3V0YihwYXIsIDB4MTEsIGNydF9pbmIocGFyLCAweDExKSAmIDB4N2YpOyAvKiBDUlQgdW5wcm90ZWN0ICovCgoJYmFuc2hlZV9tYWtlX3Jvb20ocGFyLCAzKTsKCXRkZnhfb3V0bChwYXIsIFZHQUlOSVQxLAlyZWctPnZnYWluaXQxICYgIDB4MDAxRkZGRkYpOwoJdGRmeF9vdXRsKHBhciwgVklEUFJPQ0NGRywJcmVnLT52aWRjZmcgICAmIH4weDAwMDAwMDAxKTsKI2lmIDAKCXRkZnhfb3V0bChwYXIsIFBMTENUUkwxLCByZWctPm1lbXBsbCk7Cgl0ZGZ4X291dGwocGFyLCBQTExDVFJMMiwgcmVnLT5nZnhwbGwpOwojZW5kaWYKCXRkZnhfb3V0bChwYXIsIFBMTENUUkwwLAlyZWctPnZpZHBsbCk7CgoJdmdhX291dGIocGFyLCBNSVNDX1csIHJlZy0+bWlzY1sweDAwXSB8IDB4MDEpOwoKCWZvciAoaSA9IDA7IGkgPCA1OyBpKyspCgkJc2VxX291dGIocGFyLCBpLCByZWctPnNlcVtpXSk7CgoJZm9yIChpID0gMDsgaSA8IDI1OyBpKyspCgkJY3J0X291dGIocGFyLCBpLCByZWctPmNydFtpXSk7CgoJZm9yIChpID0gMDsgaSA8IDk7IGkrKykKCQlncmFfb3V0YihwYXIsIGksIHJlZy0+Z3JhW2ldKTsKCglmb3IgKGkgPSAwOyBpIDwgMjE7IGkrKykKCQlhdHRfb3V0YihwYXIsIGksIHJlZy0+YXR0W2ldKTsKCgljcnRfb3V0YihwYXIsIDB4MWEsIHJlZy0+ZXh0WzBdKTsKCWNydF9vdXRiKHBhciwgMHgxYiwgcmVnLT5leHRbMV0pOwoKCXZnYV9lbmFibGVfcGFsZXR0ZShwYXIpOwoJdmdhX2VuYWJsZV92aWRlbyhwYXIpOwoKCWJhbnNoZWVfbWFrZV9yb29tKHBhciwgMTEpOwoJdGRmeF9vdXRsKHBhciwgCVZHQUlOSVQwLCAgICAgIHJlZy0+dmdhaW5pdDApOwoJdGRmeF9vdXRsKHBhciwJREFDTU9ERSwgICAgICAgcmVnLT5kYWNtb2RlKTsKCXRkZnhfb3V0bChwYXIsCVZJRERFU0tTVFJJREUsIHJlZy0+c3RyaWRlKTsKCXRkZnhfb3V0bChwYXIsCUhXQ1VSUEFUQUREUiwgIDApOwogICAKCXRkZnhfb3V0bChwYXIsCVZJRFNDUkVFTlNJWkUscmVnLT5zY3JlZW5zaXplKTsKCXRkZnhfb3V0bChwYXIsCVZJRERFU0tTVEFSVCwJcmVnLT5zdGFydGFkZHIpOwoJdGRmeF9vdXRsKHBhciwJVklEUFJPQ0NGRywJcmVnLT52aWRjZmcpOwoJdGRmeF9vdXRsKHBhciwJVkdBSU5JVDEsCXJlZy0+dmdhaW5pdDEpOyAgCgl0ZGZ4X291dGwocGFyLAlNSVNDSU5JVDAsCXJlZy0+bWlzY2luaXQwKTsJCgoJYmFuc2hlZV9tYWtlX3Jvb20ocGFyLAk4KTsKCXRkZnhfb3V0bChwYXIsCVNSQ0JBU0UsICAgICAgICAgcmVnLT5zcmNiYXNlKTsKCXRkZnhfb3V0bChwYXIsCURTVEJBU0UsICAgICAgICAgcmVnLT5kc3RiYXNlKTsKCXRkZnhfb3V0bChwYXIsCUNPTU1BTkRFWFRSQV8yRCwgMCk7Cgl0ZGZ4X291dGwocGFyLAlDTElQME1JTiwgICAgICAgIDApOwoJdGRmeF9vdXRsKHBhciwJQ0xJUDBNQVgsICAgICAgICAweDBmZmYwZmZmKTsKCXRkZnhfb3V0bChwYXIsCUNMSVAxTUlOLCAgICAgICAgMCk7Cgl0ZGZ4X291dGwocGFyLAlDTElQMU1BWCwgICAgICAgIDB4MGZmZjBmZmYpOwoJdGRmeF9vdXRsKHBhciwJU1JDWFksCSAgIDApOwoKCWJhbnNoZWVfd2FpdF9pZGxlKGluZm8pOwp9CgpzdGF0aWMgdW5zaWduZWQgbG9uZyBkb19sZmJfc2l6ZShzdHJ1Y3QgdGRmeF9wYXIgKnBhciwgdW5zaWduZWQgc2hvcnQgZGV2X2lkKSAKewoJdTMyIGRyYW1pbml0MCA9IDA7Cgl1MzIgZHJhbWluaXQxID0gMDsKCXUzMiBtaXNjaW5pdDEgPSAwOwoJdTMyIGxmYnNpemUgICA9IDA7CglpbnQgc2dyYW1fcCAgID0gMDsKCglkcmFtaW5pdDAgPSB0ZGZ4X2lubChwYXIsIERSQU1JTklUMCk7ICAKCWRyYW1pbml0MSA9IHRkZnhfaW5sKHBhciwgRFJBTUlOSVQxKTsKIAoJaWYgKChkZXZfaWQgPT0gUENJX0RFVklDRV9JRF8zREZYX0JBTlNIRUUpIHx8CgkgICAgKGRldl9pZCA9PSBQQ0lfREVWSUNFX0lEXzNERlhfVk9PRE9PMykpIHsgICAgICAgICAgICAgCSAKCQlzZ3JhbV9wID0gKGRyYW1pbml0MSAmIERSQU1JTklUMV9NRU1fU0RSQU0pID8gMCA6IDE7CiAgCglsZmJzaXplID0gc2dyYW1fcCA/CgkJKCgoZHJhbWluaXQwICYgRFJBTUlOSVQwX1NHUkFNX05VTSkgID8gMiA6IDEpICogCgkJKChkcmFtaW5pdDAgJiBEUkFNSU5JVDBfU0dSQU1fVFlQRSkgPyA4IDogNCkgKiAxMDI0ICogMTAyNCkgOgoJCTE2ICogMTAyNCAqIDEwMjQ7Cgl9IGVsc2UgewoJCS8qIFZvb2RvbzQvNSAqLwoJCXUzMiBjaGlwcywgcHNpemUsIGJhbmtzOwoKCQljaGlwcyA9ICgoZHJhbWluaXQwICYgKDEgPDwgMjYpKSA9PSAwKSA/IDQgOiA4OwoJCXBzaXplID0gMSA8PCAoKGRyYW1pbml0MCAmIDB4MzgwMDAwMDApID4+IDI4KTsKCQliYW5rcyA9ICgoZHJhbWluaXQwICYgKDEgPDwgMzApKSA9PSAwKSA/IDIgOiA0OwoJCWxmYnNpemUgPSBjaGlwcyAqIHBzaXplICogYmFua3M7CgkJbGZic2l6ZSA8PD0gMjA7Cgl9ICAgICAgICAgICAgICAgICAKCS8qIGRpc2FibGUgYmxvY2sgd3JpdGVzIGZvciBTRFJBTSAod2h5PykgKi8KCW1pc2Npbml0MSA9IHRkZnhfaW5sKHBhciwgTUlTQ0lOSVQxKTsKCW1pc2Npbml0MSB8PSBzZ3JhbV9wID8gMCA6IE1JU0NJTklUMV8yREJMT0NLX0RJUzsKCW1pc2Npbml0MSB8PSBNSVNDSU5JVDFfQ0xVVF9JTlY7CgoJYmFuc2hlZV9tYWtlX3Jvb20ocGFyLCAxKTsgCgl0ZGZ4X291dGwocGFyLCBNSVNDSU5JVDEsIG1pc2Npbml0MSk7CglyZXR1cm4gbGZic2l6ZTsKfQoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLwoKc3RhdGljIGludCB0ZGZ4ZmJfY2hlY2tfdmFyKHN0cnVjdCBmYl92YXJfc2NyZWVuaW5mbyAqdmFyLHN0cnVjdCBmYl9pbmZvICppbmZvKSAKewoJc3RydWN0IHRkZnhfcGFyICpwYXIgPSAoc3RydWN0IHRkZnhfcGFyICopIGluZm8tPnBhcjsgCgl1MzIgbHBpdGNoOwoKCWlmICh2YXItPmJpdHNfcGVyX3BpeGVsICE9IDggICYmIHZhci0+Yml0c19wZXJfcGl4ZWwgIT0gMTYgJiYKCSAgICB2YXItPmJpdHNfcGVyX3BpeGVsICE9IDI0ICYmIHZhci0+Yml0c19wZXJfcGl4ZWwgIT0gMzIpIHsKCQlEUFJJTlRLKCJkZXB0aCBub3Qgc3VwcG9ydGVkOiAldVxuIiwgdmFyLT5iaXRzX3Blcl9waXhlbCk7CgkJcmV0dXJuIC1FSU5WQUw7Cgl9CgoJaWYgKHZhci0+eHJlcyAhPSB2YXItPnhyZXNfdmlydHVhbCkKCQl2YXItPnhyZXNfdmlydHVhbCA9IHZhci0+eHJlczsKCglpZiAodmFyLT55cmVzID4gdmFyLT55cmVzX3ZpcnR1YWwpCgkJdmFyLT55cmVzX3ZpcnR1YWwgPSB2YXItPnlyZXM7CgoJaWYgKHZhci0+eG9mZnNldCkgewoJCURQUklOVEsoInhvZmZzZXQgbm90IHN1cHBvcnRlZFxuIik7CgkJcmV0dXJuIC1FSU5WQUw7Cgl9CgoJLyogQmFuc2hlZSBkb2Vzbid0IHN1cHBvcnQgaW50ZXJsYWNlLCBidXQgVm9vZG9vNC81IGFuZCBwcm9iYWJseSBWb29kb28zIGRvLiAqLwoJLyogbm8gZGlyZWN0IGluZm9ybWF0aW9uIGFib3V0IGRldmljZSBpZCBub3c/IHVzZSBtYXhfcGl4Y2xvY2sgZm9yIHRoaXMuLi4gKi8KCWlmICgoKHZhci0+dm1vZGUgJiBGQl9WTU9ERV9NQVNLKSA9PSBGQl9WTU9ERV9JTlRFUkxBQ0VEKSAmJgoJCQkocGFyLT5tYXhfcGl4Y2xvY2sgPCBWT09ET08zX01BWF9QSVhDTE9DSykpIHsKCQlEUFJJTlRLKCJpbnRlcmxhY2Ugbm90IHN1cHBvcnRlZFxuIik7CgkJcmV0dXJuIC1FSU5WQUw7Cgl9CgoJdmFyLT54cmVzID0gKHZhci0+eHJlcyArIDE1KSAmIH4xNTsgLyogY291bGQgc29tZXRpbWVzIGJlIDggKi8KCWxwaXRjaCA9IHZhci0+eHJlcyAqICgodmFyLT5iaXRzX3Blcl9waXhlbCArIDcpPj4zKTsKICAKCWlmICh2YXItPnhyZXMgPCAzMjAgfHwgdmFyLT54cmVzID4gMjA0OCkgewoJCURQUklOVEsoIndpZHRoIG5vdCBzdXBwb3J0ZWQ6ICV1XG4iLCB2YXItPnhyZXMpOwoJCXJldHVybiAtRUlOVkFMOwoJfQogIAoJaWYgKHZhci0+eXJlcyA8IDIwMCB8fCB2YXItPnlyZXMgPiAyMDQ4KSB7CgkJRFBSSU5USygiaGVpZ2h0IG5vdCBzdXBwb3J0ZWQ6ICV1XG4iLCB2YXItPnlyZXMpOwoJCXJldHVybiAtRUlOVkFMOwoJfQogIAoJaWYgKGxwaXRjaCAqIHZhci0+eXJlc192aXJ0dWFsID4gaW5mby0+Zml4LnNtZW1fbGVuKSB7CgkJdmFyLT55cmVzX3ZpcnR1YWwgPSBpbmZvLT5maXguc21lbV9sZW4vbHBpdGNoOwoJCWlmICh2YXItPnlyZXNfdmlydHVhbCA8IHZhci0+eXJlcykgewoJCQlEUFJJTlRLKCJubyBtZW1vcnkgZm9yIHNjcmVlbiAoJXV4JXV4JXUpXG4iLAoJCQl2YXItPnhyZXMsIHZhci0+eXJlc192aXJ0dWFsLCB2YXItPmJpdHNfcGVyX3BpeGVsKTsKCQkJcmV0dXJuIC1FSU5WQUw7CgkJfQoJfQogIAoJaWYgKFBJQ09TMktIWih2YXItPnBpeGNsb2NrKSA+IHBhci0+bWF4X3BpeGNsb2NrKSB7CgkJRFBSSU5USygicGl4Y2xvY2sgdG9vIGhpZ2ggKCVsZEtIeilcbiIsUElDT1MyS0haKHZhci0+cGl4Y2xvY2spKTsKCQlyZXR1cm4gLUVJTlZBTDsKCX0KCglzd2l0Y2godmFyLT5iaXRzX3Blcl9waXhlbCkgewoJCWNhc2UgODoKCQkJdmFyLT5yZWQubGVuZ3RoID0gdmFyLT5ncmVlbi5sZW5ndGggPSB2YXItPmJsdWUubGVuZ3RoID0gODsKCQkJYnJlYWs7CgkJY2FzZSAxNjoKCQkJdmFyLT5yZWQub2Zmc2V0ICAgPSAxMTsKCQkJdmFyLT5yZWQubGVuZ3RoICAgPSA1OwoJCQl2YXItPmdyZWVuLm9mZnNldCA9IDU7CgkJCXZhci0+Z3JlZW4ubGVuZ3RoID0gNjsKCQkJdmFyLT5ibHVlLm9mZnNldCAgPSAwOwoJCQl2YXItPmJsdWUubGVuZ3RoICA9IDU7CgkJCWJyZWFrOwoJCWNhc2UgMjQ6CgkJCXZhci0+cmVkLm9mZnNldD0xNjsKCQkJdmFyLT5ncmVlbi5vZmZzZXQ9ODsKCQkJdmFyLT5ibHVlLm9mZnNldD0wOwoJCQl2YXItPnJlZC5sZW5ndGggPSB2YXItPmdyZWVuLmxlbmd0aCA9IHZhci0+Ymx1ZS5sZW5ndGggPSA4OwoJCWNhc2UgMzI6CgkJCXZhci0+cmVkLm9mZnNldCAgID0gMTY7CgkJCXZhci0+Z3JlZW4ub2Zmc2V0ID0gODsKCQkJdmFyLT5ibHVlLm9mZnNldCAgPSAwOwoJCQl2YXItPnJlZC5sZW5ndGggPSB2YXItPmdyZWVuLmxlbmd0aCA9IHZhci0+Ymx1ZS5sZW5ndGggPSA4OwoJCQlicmVhazsKCX0KCXZhci0+aGVpZ2h0ID0gdmFyLT53aWR0aCA9IC0xOwogIAoJdmFyLT5hY2NlbF9mbGFncyA9IEZCX0FDQ0VMRl9URVhUOwoJCglEUFJJTlRLKCJDaGVja2luZyBncmFwaGljcyBtb2RlIGF0ICVkeCVkIGRlcHRoICVkXG4iLCAgdmFyLT54cmVzLCB2YXItPnlyZXMsIHZhci0+Yml0c19wZXJfcGl4ZWwpOwoJcmV0dXJuIDA7Cn0KCnN0YXRpYyBpbnQgdGRmeGZiX3NldF9wYXIoc3RydWN0IGZiX2luZm8gKmluZm8pCnsKCXN0cnVjdCB0ZGZ4X3BhciAqcGFyID0gKHN0cnVjdCB0ZGZ4X3BhciAqKSBpbmZvLT5wYXI7CQoJdTMyIGhkaXNwZW5kLCBoc3luY3N0YSwgaHN5bmNlbmQsIGh0b3RhbDsKCXUzMiBoZCwgaHMsIGhlLCBodCwgaGJzLCBoYmU7Cgl1MzIgdmQsIHZzLCB2ZSwgdnQsIHZicywgdmJlOwoJc3RydWN0IGJhbnNoZWVfcmVnIHJlZzsKCWludCBmb3V0LCBmcmVxOwoJdTMyIHdkLCBjcHA7CiAgCglwYXItPmJhc2VsaW5lICA9IDA7CiAKCW1lbXNldCgmcmVnLCAwLCBzaXplb2YocmVnKSk7CgljcHAgPSAoaW5mby0+dmFyLmJpdHNfcGVyX3BpeGVsICsgNykvODsKIAoJcmVnLnZpZGNmZyA9IFZJRENGR19WSURQUk9DX0VOQUJMRSB8IFZJRENGR19ERVNLX0VOQUJMRSB8IFZJRENGR19DVVJTX1gxMSB8ICgoY3BwIC0gMSkgPDwgVklEQ0ZHX1BJWEZNVF9TSElGVCkgfCAoY3BwICE9IDEgPyBWSURDRkdfQ0xVVF9CWVBBU1MgOiAwKTsKCgkvKiBQTEwgc2V0dGluZ3MgKi8KCWZyZXEgPSBQSUNPUzJLSFooaW5mby0+dmFyLnBpeGNsb2NrKTsKCglyZWcuZGFjbW9kZSA9IDA7CglyZWcudmlkY2ZnICAmPSB+VklEQ0ZHXzJYOwoKCWhkaXNwZW5kID0gaW5mby0+dmFyLnhyZXM7Cgloc3luY3N0YSA9IGhkaXNwZW5kICsgaW5mby0+dmFyLnJpZ2h0X21hcmdpbjsKCWhzeW5jZW5kID0gaHN5bmNzdGEgKyBpbmZvLT52YXIuaHN5bmNfbGVuOwoJaHRvdGFsICAgPSBoc3luY2VuZCArIGluZm8tPnZhci5sZWZ0X21hcmdpbjsJCgoJaWYgKGZyZXEgPiBwYXItPm1heF9waXhjbG9jay8yKSB7CgkJZnJlcSA9IGZyZXEgPiBwYXItPm1heF9waXhjbG9jayA/IHBhci0+bWF4X3BpeGNsb2NrIDogZnJlcTsKCQlyZWcuZGFjbW9kZSB8PSBEQUNNT0RFXzJYOwoJCXJlZy52aWRjZmcgIHw9IFZJRENGR18yWDsKCQloZGlzcGVuZCA+Pj0gMTsKCQloc3luY3N0YSA+Pj0gMTsKCQloc3luY2VuZCA+Pj0gMTsKCQlodG90YWwgICA+Pj0gMTsKCX0KICAKCWhkICA9IHdkID0gKGhkaXNwZW5kID4+IDMpIC0gMTsKCWhzICA9IChoc3luY3N0YSA+PiAzKSAtIDE7CgloZSAgPSAoaHN5bmNlbmQgPj4gMykgLSAxOwoJaHQgID0gKGh0b3RhbCA+PiAzKSAtIDE7CgloYnMgPSBoZDsKCWhiZSA9IGh0OwoKCWlmICgoaW5mby0+dmFyLnZtb2RlICYgRkJfVk1PREVfTUFTSykgPT0gRkJfVk1PREVfRE9VQkxFKSB7CgkJdmJzID0gdmQgPSAoaW5mby0+dmFyLnlyZXMgPDwgMSkgLSAxOwoJCXZzICA9IHZkICsgKGluZm8tPnZhci5sb3dlcl9tYXJnaW4gPDwgMSk7CgkJdmUgID0gdnMgKyAoaW5mby0+dmFyLnZzeW5jX2xlbiA8PCAxKTsKCQl2YmUgPSB2dCA9IHZlICsgKGluZm8tPnZhci51cHBlcl9tYXJnaW4gPDwgMSkgLSAxOwoJfSBlbHNlIHsKCQl2YnMgPSB2ZCA9IGluZm8tPnZhci55cmVzIC0gMTsKCQl2cyAgPSB2ZCArIGluZm8tPnZhci5sb3dlcl9tYXJnaW47CgkJdmUgID0gdnMgKyBpbmZvLT52YXIudnN5bmNfbGVuOwoJCXZiZSA9IHZ0ID0gdmUgKyBpbmZvLT52YXIudXBwZXJfbWFyZ2luIC0gMTsKCX0KICAKCS8qIHRoaXMgaXMgYWxsIHByZXR0eSBzdGFuZGFyZCBWR0EgcmVnaXN0ZXIgc3R1ZmZpbmcgKi8KCXJlZy5taXNjWzB4MDBdID0gMHgwZiB8IAoJCQkoaW5mby0+dmFyLnhyZXMgPCA0MDAgPyAweGEwIDoKCQkJIGluZm8tPnZhci54cmVzIDwgNDgwID8gMHg2MCA6CgkJCSBpbmZvLT52YXIueHJlcyA8IDc2OCA/IDB4ZTAgOiAweDIwKTsKICAgICAKCXJlZy5ncmFbMHgwMF0gPSAweDAwOwoJcmVnLmdyYVsweDAxXSA9IDB4MDA7CglyZWcuZ3JhWzB4MDJdID0gMHgwMDsKCXJlZy5ncmFbMHgwM10gPSAweDAwOwoJcmVnLmdyYVsweDA0XSA9IDB4MDA7CglyZWcuZ3JhWzB4MDVdID0gMHg0MDsKCXJlZy5ncmFbMHgwNl0gPSAweDA1OwoJcmVnLmdyYVsweDA3XSA9IDB4MGY7CglyZWcuZ3JhWzB4MDhdID0gMHhmZjsKCglyZWcuYXR0WzB4MDBdID0gMHgwMDsKCXJlZy5hdHRbMHgwMV0gPSAweDAxOwoJcmVnLmF0dFsweDAyXSA9IDB4MDI7CglyZWcuYXR0WzB4MDNdID0gMHgwMzsKCXJlZy5hdHRbMHgwNF0gPSAweDA0OwoJcmVnLmF0dFsweDA1XSA9IDB4MDU7CglyZWcuYXR0WzB4MDZdID0gMHgwNjsKCXJlZy5hdHRbMHgwN10gPSAweDA3OwoJcmVnLmF0dFsweDA4XSA9IDB4MDg7CglyZWcuYXR0WzB4MDldID0gMHgwOTsKCXJlZy5hdHRbMHgwYV0gPSAweDBhOwoJcmVnLmF0dFsweDBiXSA9IDB4MGI7CglyZWcuYXR0WzB4MGNdID0gMHgwYzsKCXJlZy5hdHRbMHgwZF0gPSAweDBkOwoJcmVnLmF0dFsweDBlXSA9IDB4MGU7CglyZWcuYXR0WzB4MGZdID0gMHgwZjsKCXJlZy5hdHRbMHgxMF0gPSAweDQxOwoJcmVnLmF0dFsweDExXSA9IDB4MDA7CglyZWcuYXR0WzB4MTJdID0gMHgwZjsKCXJlZy5hdHRbMHgxM10gPSAweDAwOwoJcmVnLmF0dFsweDE0XSA9IDB4MDA7CgoJcmVnLnNlcVsweDAwXSA9IDB4MDM7CglyZWcuc2VxWzB4MDFdID0gMHgwMTsgLyogZml4bWU6IGNsa2RpdjI/ICovCglyZWcuc2VxWzB4MDJdID0gMHgwZjsKCXJlZy5zZXFbMHgwM10gPSAweDAwOwoJcmVnLnNlcVsweDA0XSA9IDB4MGU7CgoJcmVnLmNydFsweDAwXSA9IGh0IC0gNDsKCXJlZy5jcnRbMHgwMV0gPSBoZDsKCXJlZy5jcnRbMHgwMl0gPSBoYnM7CglyZWcuY3J0WzB4MDNdID0gMHg4MCB8IChoYmUgJiAweDFmKTsKCXJlZy5jcnRbMHgwNF0gPSBoczsKCXJlZy5jcnRbMHgwNV0gPSAoKGhiZSAmIDB4MjApIDw8IDIpIHwgKGhlICYgMHgxZik7IAoJcmVnLmNydFsweDA2XSA9IHZ0OwoJcmVnLmNydFsweDA3XSA9ICgodnMgJiAweDIwMCkgPj4gMikgfAoJCQkoKHZkICYgMHgyMDApID4+IDMpIHwKCQkJKCh2dCAmIDB4MjAwKSA+PiA0KSB8IDB4MTAgfAoJCQkoKHZicyAmIDB4MTAwKSA+PiA1KSB8CgkJCSgodnMgICYgMHgxMDApID4+IDYpIHwKCQkJKCh2ZCAgJiAweDEwMCkgPj4gNykgfAoJCQkoKHZ0ICAmIDB4MTAwKSA+PiA4KTsKCXJlZy5jcnRbMHgwOF0gPSAweDAwOwoJcmVnLmNydFsweDA5XSA9IDB4NDAgfCAoKHZicyAmIDB4MjAwKSA+PiA0KTsgCglyZWcuY3J0WzB4MGFdID0gMHgwMDsKCXJlZy5jcnRbMHgwYl0gPSAweDAwOwoJcmVnLmNydFsweDBjXSA9IDB4MDA7CglyZWcuY3J0WzB4MGRdID0gMHgwMDsKCXJlZy5jcnRbMHgwZV0gPSAweDAwOwoJcmVnLmNydFsweDBmXSA9IDB4MDA7CglyZWcuY3J0WzB4MTBdID0gdnM7CglyZWcuY3J0WzB4MTFdID0gKHZlICYgMHgwZikgfCAweDIwOyAKCXJlZy5jcnRbMHgxMl0gPSB2ZDsKCXJlZy5jcnRbMHgxM10gPSB3ZDsKCXJlZy5jcnRbMHgxNF0gPSAweDAwOwoJcmVnLmNydFsweDE1XSA9IHZiczsKCXJlZy5jcnRbMHgxNl0gPSB2YmUgKyAxOyAKCXJlZy5jcnRbMHgxN10gPSAweGMzOwoJcmVnLmNydFsweDE4XSA9IDB4ZmY7CiAKCS8qIEJhbnNoZWUncyBub252Z2Egc3R1ZmYgKi8KCXJlZy5leHRbMHgwMF0gPSAoKChodCAgJiAweDEwMCkgPj4gOCkgfCAKCQkJKChoZCAgJiAweDEwMCkgPj4gNikgfAoJCQkoKGhicyAmIDB4MTAwKSA+PiA0KSB8CgkJCSgoaGJlICYgIDB4NDApID4+IDEpIHwKCQkJKChocyAgJiAweDEwMCkgPj4gMikgfAoJCQkoKGhlICAmICAweDIwKSA8PCAyKSk7IAoJcmVnLmV4dFsweDAxXSA9ICgoKHZ0ICAmIDB4NDAwKSA+PiAxMCkgfAoJCQkoKHZkICAmIDB4NDAwKSA+PiAgOCkgfCAKCQkJKCh2YnMgJiAweDQwMCkgPj4gIDYpIHwKCQkJKCh2YmUgJiAweDQwMCkgPj4gIDQpKTsKCglyZWcudmdhaW5pdDAgPSAJVkdBSU5JVDBfOEJJVF9EQUMgICAgIHwKCQkJVkdBSU5JVDBfRVhUX0VOQUJMRSAgIHwKCQkJVkdBSU5JVDBfV0FLRVVQXzNDMyAgIHwKCQkJVkdBSU5JVDBfQUxUX1JFQURCQUNLIHwKCQkJVkdBSU5JVDBfRVhUU0hJRlRPVVQ7CglyZWcudmdhaW5pdDEgPSB0ZGZ4X2lubChwYXIsIFZHQUlOSVQxKSAmIDB4MWZmZmZmOwoKCXJlZy5jdXJzbG9jICAgPSAwOwogICAKCXJlZy5jdXJzYzAgICAgPSAwOyAKCXJlZy5jdXJzYzEgICAgPSAweGZmZmZmZjsKICAgCglyZWcuc3RyaWRlICAgID0gaW5mby0+dmFyLnhyZXMgKiBjcHA7CglyZWcuc3RhcnRhZGRyID0gcGFyLT5iYXNlbGluZSAqIHJlZy5zdHJpZGU7CglyZWcuc3JjYmFzZSAgID0gcmVnLnN0YXJ0YWRkcjsKCXJlZy5kc3RiYXNlICAgPSByZWcuc3RhcnRhZGRyOwoKCS8qIFBMTCBzZXR0aW5ncyAqLwoJZnJlcSA9IFBJQ09TMktIWihpbmZvLT52YXIucGl4Y2xvY2spOwoKCXJlZy5kYWNtb2RlICY9IH5EQUNNT0RFXzJYOwoJcmVnLnZpZGNmZyAgJj0gflZJRENGR18yWDsKCWlmIChmcmVxID4gcGFyLT5tYXhfcGl4Y2xvY2svMikgewoJCWZyZXEgPSBmcmVxID4gcGFyLT5tYXhfcGl4Y2xvY2sgPyBwYXItPm1heF9waXhjbG9jayA6IGZyZXE7CgkJcmVnLmRhY21vZGUgfD0gREFDTU9ERV8yWDsKCQlyZWcudmlkY2ZnICB8PSBWSURDRkdfMlg7Cgl9CglyZWcudmlkcGxsID0gZG9fY2FsY19wbGwoZnJlcSwgJmZvdXQpOwojaWYgMAoJcmVnLm1lbXBsbCA9IGRvX2NhbGNfcGxsKC4uLiwgJmZvdXQpOwoJcmVnLmdmeHBsbCA9IGRvX2NhbGNfcGxsKC4uLiwgJmZvdXQpOwojZW5kaWYKCglpZiAoKGluZm8tPnZhci52bW9kZSAmIEZCX1ZNT0RFX01BU0spID09IEZCX1ZNT0RFX0RPVUJMRSkgewoJCXJlZy5zY3JlZW5zaXplID0gaW5mby0+dmFyLnhyZXMgfCAoaW5mby0+dmFyLnlyZXMgPDwgMTMpOwoJCXJlZy52aWRjZmcgfD0gVklEQ0ZHX0hBTEZfTU9ERTsKCQlyZWcuY3J0WzB4MDldIHw9IDB4ODA7Cgl9IGVsc2UgewoJCXJlZy5zY3JlZW5zaXplID0gaW5mby0+dmFyLnhyZXMgfCAoaW5mby0+dmFyLnlyZXMgPDwgMTIpOwoJCXJlZy52aWRjZmcgJj0gflZJRENGR19IQUxGX01PREU7Cgl9CglpZiAoKGluZm8tPnZhci52bW9kZSAmIEZCX1ZNT0RFX01BU0spID09IEZCX1ZNT0RFX0lOVEVSTEFDRUQpCgkJcmVnLnZpZGNmZyB8PSBWSURDRkdfSU5URVJMQUNFOwoJcmVnLm1pc2Npbml0MCA9IHRkZnhfaW5sKHBhciwgTUlTQ0lOSVQwKTsKCiNpZiBkZWZpbmVkKF9fQklHX0VORElBTikKCXN3aXRjaCAoaW5mby0+dmFyLmJpdHNfcGVyX3BpeGVsKSB7CgkJY2FzZSA4OgoJCWNhc2UgMjQ6CgkJCXJlZy5taXNjaW5pdDAgJj0gfigxIDw8IDMwKTsKCQkJcmVnLm1pc2Npbml0MCAmPSB+KDEgPDwgMzEpOwoJCQlicmVhazsKCQljYXNlIDE2OgoJCQlyZWcubWlzY2luaXQwIHw9ICgxIDw8IDMwKTsKCQkJcmVnLm1pc2Npbml0MCB8PSAoMSA8PCAzMSk7CgkJCWJyZWFrOwoJCWNhc2UgMzI6CgkJCXJlZy5taXNjaW5pdDAgfD0gKDEgPDwgMzApOwoJCQlyZWcubWlzY2luaXQwICY9IH4oMSA8PCAzMSk7CgkJCWJyZWFrOwoJfQojZW5kaWYgCglkb193cml0ZV9yZWdzKGluZm8sICZyZWcpOwoKCS8qIE5vdyBjaGFuZ2UgZmJfZml4X3NjcmVlbmluZm8gYWNjb3JkaW5nIHRvIGNoYW5nZXMgaW4gcGFyICovCglpbmZvLT5maXgubGluZV9sZW5ndGggPSBpbmZvLT52YXIueHJlcyAqICgoaW5mby0+dmFyLmJpdHNfcGVyX3BpeGVsICsgNyk+PjMpOwoJaW5mby0+Zml4LnZpc3VhbCA9IChpbmZvLT52YXIuYml0c19wZXJfcGl4ZWwgPT0gOCkgCgkJCQk/IEZCX1ZJU1VBTF9QU0VVRE9DT0xPUgoJCQkJOiBGQl9WSVNVQUxfVFJVRUNPTE9SOwoJRFBSSU5USygiR3JhcGhpY3MgbW9kZSBpcyBub3cgc2V0IGF0ICVkeCVkIGRlcHRoICVkXG4iLCBpbmZvLT52YXIueHJlcywgaW5mby0+dmFyLnlyZXMsIGluZm8tPnZhci5iaXRzX3Blcl9waXhlbCk7CglyZXR1cm4gMDsJCn0KCi8qIEEgaGFuZHkgbWFjcm8gc2hhbWVsZXNzbHkgcGluY2hlZCBmcm9tIG1hdHJveGZiICovCiNkZWZpbmUgQ05WVF9UT0hXKHZhbCx3aWR0aCkgKCgoKHZhbCk8PCh3aWR0aCkpKzB4N0ZGRi0odmFsKSk+PjE2KQoKc3RhdGljIGludCB0ZGZ4ZmJfc2V0Y29scmVnKHVuc2lnbmVkIHJlZ25vLCB1bnNpZ25lZCByZWQsIHVuc2lnbmVkIGdyZWVuLCAgCgkJCSAgICB1bnNpZ25lZCBibHVlLHVuc2lnbmVkIHRyYW5zcCxzdHJ1Y3QgZmJfaW5mbyAqaW5mbykgCnsKCXN0cnVjdCB0ZGZ4X3BhciAqcGFyID0gKHN0cnVjdCB0ZGZ4X3BhciAqKSBpbmZvLT5wYXI7Cgl1MzIgcmdiY29sOwogICAKCWlmIChyZWdubyA+PSBpbmZvLT5jbWFwLmxlbiB8fCByZWdubyA+IDI1NSkgcmV0dXJuIDE7CiAgIAoJc3dpdGNoIChpbmZvLT5maXgudmlzdWFsKSB7CgkJY2FzZSBGQl9WSVNVQUxfUFNFVURPQ09MT1I6CgkJCXJnYmNvbCA9KCgodTMyKXJlZCAgICYgMHhmZjAwKSA8PCA4KSB8CgkJCQkoKCh1MzIpZ3JlZW4gJiAweGZmMDApIDw8IDApIHwKCQkJCSgoKHUzMilibHVlICAmIDB4ZmYwMCkgPj4gOCk7CgkJCWRvX3NldHBhbGVudHJ5KHBhciwgcmVnbm8sIHJnYmNvbCk7CgkJCWJyZWFrOwoJCS8qIFRydWVjb2xvciBoYXMgbm8gaGFyZHdhcmUgY29sb3IgcGFsZXR0ZXMuICovCgkJY2FzZSBGQl9WSVNVQUxfVFJVRUNPTE9SOgoJCQlyZ2Jjb2wgPSAoQ05WVF9UT0hXKCByZWQsIGluZm8tPnZhci5yZWQubGVuZ3RoKSA8PCBpbmZvLT52YXIucmVkLm9mZnNldCkgfAoJCQkJIChDTlZUX1RPSFcoIGdyZWVuLCBpbmZvLT52YXIuZ3JlZW4ubGVuZ3RoKSA8PCBpbmZvLT52YXIuZ3JlZW4ub2Zmc2V0KSB8CgkJCQkgKENOVlRfVE9IVyggYmx1ZSwgaW5mby0+dmFyLmJsdWUubGVuZ3RoKSA8PCBpbmZvLT52YXIuYmx1ZS5vZmZzZXQpIHwKCQkJCSAoQ05WVF9UT0hXKCB0cmFuc3AsIGluZm8tPnZhci50cmFuc3AubGVuZ3RoKSA8PCBpbmZvLT52YXIudHJhbnNwLm9mZnNldCk7CgkJCQkoKHUzMiopKGluZm8tPnBzZXVkb19wYWxldHRlKSlbcmVnbm9dID0gcmdiY29sOwoJCQlicmVhazsKCQlkZWZhdWx0OgoJCQlEUFJJTlRLKCJiYWQgZGVwdGggJXVcbiIsIGluZm8tPnZhci5iaXRzX3Blcl9waXhlbCk7CgkJCWJyZWFrOwoJfQoJcmV0dXJuIDA7Cn0KCi8qIDAgdW5ibGFuaywgMSBibGFuaywgMiBubyB2c3luYywgMyBubyBoc3luYywgNCBvZmYgKi8Kc3RhdGljIGludCB0ZGZ4ZmJfYmxhbmsoaW50IGJsYW5rLCBzdHJ1Y3QgZmJfaW5mbyAqaW5mbykKeyAKCXN0cnVjdCB0ZGZ4X3BhciAqcGFyID0gKHN0cnVjdCB0ZGZ4X3BhciAqKSBpbmZvLT5wYXI7Cgl1MzIgZGFjbW9kZSwgc3RhdGUgPSAwLCB2Z2FibGFuayA9IDA7CgoJZGFjbW9kZSA9IHRkZnhfaW5sKHBhciwgREFDTU9ERSk7CgoJc3dpdGNoIChibGFuaykgewoJCWNhc2UgRkJfQkxBTktfVU5CTEFOSzogLyogU2NyZWVuOiBPbjsgSFN5bmM6IE9uLCBWU3luYzogT24gKi8KCQkJc3RhdGUgICAgPSAwOwoJCQl2Z2FibGFuayA9IDA7CgkJCWJyZWFrOwoJCWNhc2UgRkJfQkxBTktfTk9STUFMOiAvKiBTY3JlZW46IE9mZjsgSFN5bmM6IE9uLCBWU3luYzogT24gKi8KCQkJc3RhdGUgICAgPSAwOwoJCQl2Z2FibGFuayA9IDE7CgkJCWJyZWFrOwoJCWNhc2UgRkJfQkxBTktfVlNZTkNfU1VTUEVORDogLyogU2NyZWVuOiBPZmY7IEhTeW5jOiBPbiwgVlN5bmM6IE9mZiAqLwoJCQlzdGF0ZSAgICA9IEJJVCgzKTsKCQkJdmdhYmxhbmsgPSAxOwoJCQlicmVhazsKCQljYXNlIEZCX0JMQU5LX0hTWU5DX1NVU1BFTkQ6IC8qIFNjcmVlbjogT2ZmOyBIU3luYzogT2ZmLCBWU3luYzogT24gKi8KCQkJc3RhdGUgICAgPSBCSVQoMSk7CgkJCXZnYWJsYW5rID0gMTsKCQkJYnJlYWs7CgkJY2FzZSBGQl9CTEFOS19QT1dFUkRPV046IC8qIFNjcmVlbjogT2ZmOyBIU3luYzogT2ZmLCBWU3luYzogT2ZmICovCgkJCXN0YXRlICAgID0gQklUKDEpIHwgQklUKDMpOwoJCQl2Z2FibGFuayA9IDE7CgkJCWJyZWFrOwoJfQoKCWRhY21vZGUgJj0gfihCSVQoMSkgfCBCSVQoMykpOwoJZGFjbW9kZSB8PSBzdGF0ZTsKCWJhbnNoZWVfbWFrZV9yb29tKHBhciwgMSk7IAoJdGRmeF9vdXRsKHBhciwgREFDTU9ERSwgZGFjbW9kZSk7CglpZiAodmdhYmxhbmspIAoJCXZnYV9kaXNhYmxlX3ZpZGVvKHBhcik7CgllbHNlCgkJdmdhX2VuYWJsZV92aWRlbyhwYXIpOwoJcmV0dXJuIDA7Cn0KCi8qICAgCiAqIFNldCB0aGUgc3RhcnRpbmcgcG9zaXRpb24gb2YgdGhlIHZpc2libGUgc2NyZWVuIHRvIHZhci0+eW9mZnNldAogKi8gICAKc3RhdGljIGludCB0ZGZ4ZmJfcGFuX2Rpc3BsYXkoc3RydWN0IGZiX3Zhcl9zY3JlZW5pbmZvICp2YXIsCgkJCSAgICAgIHN0cnVjdCBmYl9pbmZvICppbmZvKSAKewoJc3RydWN0IHRkZnhfcGFyICpwYXIgPSAoc3RydWN0IHRkZnhfcGFyICopIGluZm8tPnBhcjsKCXUzMiBhZGRyOyAgCQoKCWlmIChub3BhbiB8fCB2YXItPnhvZmZzZXQgfHwgKHZhci0+eW9mZnNldCA+IHZhci0+eXJlc192aXJ0dWFsKSkKCQlyZXR1cm4gLUVJTlZBTDsKCWlmICgodmFyLT55b2Zmc2V0ICsgdmFyLT55cmVzID4gdmFyLT55cmVzX3ZpcnR1YWwgJiYgbm93cmFwKSkKCQlyZXR1cm4gLUVJTlZBTDsKCglhZGRyID0gdmFyLT55b2Zmc2V0ICogaW5mby0+Zml4LmxpbmVfbGVuZ3RoOwoJYmFuc2hlZV9tYWtlX3Jvb20ocGFyLCAxKTsKCXRkZnhfb3V0bChwYXIsIFZJRERFU0tTVEFSVCwgYWRkcik7CiAgIAoJaW5mby0+dmFyLnhvZmZzZXQgPSB2YXItPnhvZmZzZXQ7CglpbmZvLT52YXIueW9mZnNldCA9IHZhci0+eW9mZnNldDsgCglyZXR1cm4gMDsKfQoKI2lmZGVmIENPTkZJR19GQl8zREZYX0FDQ0VMCi8qCiAqIEZpbGxSZWN0IDJEIGNvbW1hbmQgKHNvbGlkZmlsbCBvciBpbnZlcnQgKHZpYSBST1BfWE9SKSkgICAKICovCnN0YXRpYyB2b2lkIHRkZnhmYl9maWxscmVjdChzdHJ1Y3QgZmJfaW5mbyAqaW5mbywgY29uc3Qgc3RydWN0IGZiX2ZpbGxyZWN0ICpyZWN0KSAKewoJc3RydWN0IHRkZnhfcGFyICpwYXIgPSAoc3RydWN0IHRkZnhfcGFyICopIGluZm8tPnBhcjsKCXUzMiBicHAgPSBpbmZvLT52YXIuYml0c19wZXJfcGl4ZWw7Cgl1MzIgc3RyaWRlID0gaW5mby0+Zml4LmxpbmVfbGVuZ3RoOwoJdTMyIGZtdD0gc3RyaWRlIHwgKChicHArKChicHA9PTgpID8gMCA6IDgpKSA8PCAxMyk7IAoJaW50IHRkZnhfcm9wOwogICAJCglpZiAocmVjdC0+cm9wID09IFJPUF9DT1BZKSAKCQl0ZGZ4X3JvcCA9IFRERlhfUk9QX0NPUFk7CgllbHNlIAkJCSAKCQl0ZGZ4X3JvcCA9IFRERlhfUk9QX1hPUjsKCgliYW5zaGVlX21ha2Vfcm9vbShwYXIsIDUpOwoJdGRmeF9vdXRsKHBhciwJRFNURk9STUFULCBmbXQpOwoJaWYgKGluZm8tPmZpeC52aXN1YWwgPT0gRkJfVklTVUFMX1BTRVVET0NPTE9SKSB7CgkJdGRmeF9vdXRsKHBhciwJQ09MT1JGT1JFLCByZWN0LT5jb2xvcik7Cgl9IGVsc2UgeyAvKiBGQl9WSVNVQUxfVFJVRUNPTE9SICovCgkJdGRmeF9vdXRsKHBhciwgQ09MT1JGT1JFLCAoKHUzMiopKGluZm8tPnBzZXVkb19wYWxldHRlKSlbcmVjdC0+Y29sb3JdKTsKCX0KCXRkZnhfb3V0bChwYXIsCUNPTU1BTkRfMkQsIENPTU1BTkRfMkRfRklMTFJFQ1QgfCAodGRmeF9yb3AgPDwgMjQpKTsKCXRkZnhfb3V0bChwYXIsCURTVFNJWkUsICAgIHJlY3QtPndpZHRoIHwgKHJlY3QtPmhlaWdodCA8PCAxNikpOwoJdGRmeF9vdXRsKHBhciwJTEFVTkNIXzJELCAgcmVjdC0+ZHggfCAocmVjdC0+ZHkgPDwgMTYpKTsKfQoKLyoKICogU2NyZWVuLXRvLVNjcmVlbiBCaXRCbHQgMkQgY29tbWFuZCAoZm9yIHRoZSBibW92ZSBmYiBvcC4pIAogKi8Kc3RhdGljIHZvaWQgdGRmeGZiX2NvcHlhcmVhKHN0cnVjdCBmYl9pbmZvICppbmZvLCBjb25zdCBzdHJ1Y3QgZmJfY29weWFyZWEgKmFyZWEpICAKewoJc3RydWN0IHRkZnhfcGFyICpwYXIgPSAoc3RydWN0IHRkZnhfcGFyICopIGluZm8tPnBhcjsKICAgCXUzMiBzeCA9IGFyZWEtPnN4LCBzeSA9IGFyZWEtPnN5LCBkeCA9IGFyZWEtPmR4LCBkeSA9IGFyZWEtPmR5OwoJdTMyIGJwcCA9IGluZm8tPnZhci5iaXRzX3Blcl9waXhlbDsKCXUzMiBzdHJpZGUgPSBpbmZvLT5maXgubGluZV9sZW5ndGg7Cgl1MzIgYmxpdGNtZCA9IENPTU1BTkRfMkRfUzJTX0JJVEJMVCB8IChUREZYX1JPUF9DT1BZIDw8IDI0KTsKCXUzMiBmbXQgPSBzdHJpZGUgfCAoKGJwcCsoKGJwcD09OCkgPyAwIDogOCkpIDw8IDEzKTsgCgkKCWlmIChhcmVhLT5zeCA8PSBhcmVhLT5keCkgewoJCS8vLVggCgkJYmxpdGNtZCB8PSBCSVQoMTQpOwoJCXN4ICs9IGFyZWEtPndpZHRoIC0gMTsKCQlkeCArPSBhcmVhLT53aWR0aCAtIDE7Cgl9CglpZiAoYXJlYS0+c3kgPD0gYXJlYS0+ZHkpIHsKCQkvLy1ZICAKCQlibGl0Y21kIHw9IEJJVCgxNSk7CgkJc3kgKz0gYXJlYS0+aGVpZ2h0IC0gMTsKCQlkeSArPSBhcmVhLT5oZWlnaHQgLSAxOwoJfQogICAKCWJhbnNoZWVfbWFrZV9yb29tKHBhciwgNik7CgoJdGRmeF9vdXRsKHBhciwJU1JDRk9STUFULCBmbXQpOwoJdGRmeF9vdXRsKHBhciwJRFNURk9STUFULCBmbXQpOwoJdGRmeF9vdXRsKHBhciwJQ09NTUFORF8yRCwgYmxpdGNtZCk7IAoJdGRmeF9vdXRsKHBhciwJRFNUU0laRSwgICBhcmVhLT53aWR0aCB8IChhcmVhLT5oZWlnaHQgPDwgMTYpKTsKCXRkZnhfb3V0bChwYXIsCURTVFhZLCAgICAgZHggfCAoZHkgPDwgMTYpKTsKCXRkZnhfb3V0bChwYXIsCUxBVU5DSF8yRCwgc3ggfCAoc3kgPDwgMTYpKTsgCn0KCnN0YXRpYyB2b2lkIHRkZnhmYl9pbWFnZWJsaXQoc3RydWN0IGZiX2luZm8gKmluZm8sIGNvbnN0IHN0cnVjdCBmYl9pbWFnZSAqaW1hZ2UpIAp7CglzdHJ1Y3QgdGRmeF9wYXIgKnBhciA9IChzdHJ1Y3QgdGRmeF9wYXIgKikgaW5mby0+cGFyOwoJaW50IHNpemUgPSBpbWFnZS0+aGVpZ2h0ICogKChpbWFnZS0+d2lkdGggKiBpbWFnZS0+ZGVwdGggKyA3KT4+Myk7CglpbnQgZmlmb19mcmVlOwoJaW50IGksIHN0cmlkZSA9IGluZm8tPmZpeC5saW5lX2xlbmd0aDsKCXUzMiBicHAgPSBpbmZvLT52YXIuYml0c19wZXJfcGl4ZWw7Cgl1MzIgZHN0Zm10ID0gc3RyaWRlIHwgKChicHArKChicHA9PTgpID8gMCA6IDgpKSA8PCAxMyk7IAoJdTggKmNoYXJkYXRhID0gKHU4ICopIGltYWdlLT5kYXRhOwoJdTMyIHNyY2ZtdDsKCglpZiAoaW1hZ2UtPmRlcHRoICE9IDEpIHsKCQkvL2JhbnNoZWVfbWFrZV9yb29tKHBhciwgNiArICgoc2l6ZSArIDMpID4+IDIpKTsKCQkvL3NyY2ZtdCA9IHN0cmlkZSB8ICgoYnBwKygoYnBwPT04KSA/IDAgOiA4KSkgPDwgMTMpIHwgMHg0MDAwMDA7CgkJY2ZiX2ltYWdlYmxpdChpbmZvLCBpbWFnZSk7CgkJcmV0dXJuOwoJfSBlbHNlIHsKCQliYW5zaGVlX21ha2Vfcm9vbShwYXIsIDgpOwoJCXN3aXRjaCAoaW5mby0+Zml4LnZpc3VhbCkgewoJCQljYXNlIEZCX1ZJU1VBTF9QU0VVRE9DT0xPUjoKCQl0ZGZ4X291dGwocGFyLCBDT0xPUkZPUkUsIGltYWdlLT5mZ19jb2xvcik7CgkJdGRmeF9vdXRsKHBhciwgQ09MT1JCQUNLLCBpbWFnZS0+YmdfY29sb3IpOwoJCQkJYnJlYWs7CgkJCWNhc2UgRkJfVklTVUFMX1RSVUVDT0xPUjoKCQkJZGVmYXVsdDoKCQkJCXRkZnhfb3V0bChwYXIsIENPTE9SRk9SRSwgKCh1MzIqKShpbmZvLT5wc2V1ZG9fcGFsZXR0ZSkpW2ltYWdlLT5mZ19jb2xvcl0pOwoJCQkJdGRmeF9vdXRsKHBhciwgQ09MT1JCQUNLLCAoKHUzMiopKGluZm8tPnBzZXVkb19wYWxldHRlKSlbaW1hZ2UtPmJnX2NvbG9yXSk7CgkJfQojaWZkZWYgX19CSUdfRU5ESUFOCgkJc3JjZm10ID0gMHg0MDAwMDAgfCBCSVQoMjApOwojZWxzZQoJCXNyY2ZtdCA9IDB4NDAwMDAwOwojZW5kaWYKCX0JCgoJdGRmeF9vdXRsKHBhciwJU1JDWFksICAgICAwKTsKCXRkZnhfb3V0bChwYXIsCURTVFhZLCAgICAgaW1hZ2UtPmR4IHwgKGltYWdlLT5keSA8PCAxNikpOwoJdGRmeF9vdXRsKHBhciwJQ09NTUFORF8yRCwgQ09NTUFORF8yRF9IMlNfQklUQkxUIHwgKFRERlhfUk9QX0NPUFkgPDwgMjQpKTsKCXRkZnhfb3V0bChwYXIsCVNSQ0ZPUk1BVCwgc3JjZm10KTsKCXRkZnhfb3V0bChwYXIsCURTVEZPUk1BVCwgZHN0Zm10KTsKCXRkZnhfb3V0bChwYXIsCURTVFNJWkUsICAgaW1hZ2UtPndpZHRoIHwgKGltYWdlLT5oZWlnaHQgPDwgMTYpKTsKCgkvKiBBIGNvdW50IG9mIGhvdyBtYW55IGZyZWUgRklGTyBlbnRyaWVzIHdlJ3ZlIHJlcXVlc3RlZC4KCSAqIFdoZW4gdGhpcyBnb2VzIG5lZ2F0aXZlLCB3ZSBuZWVkIHRvIHJlcXVlc3QgbW9yZS4gKi8KCWZpZm9fZnJlZSA9IDA7CgoJLyogU2VuZCBmb3VyIGJ5dGVzIGF0IGEgdGltZSBvZiBkYXRhICovCQoJZm9yIChpID0gKHNpemUgPj4gMikgOyBpID4gMDsgaS0tKSB7IAoJCWlmKC0tZmlmb19mcmVlIDwgMCkgewoJCQlmaWZvX2ZyZWU9MzE7CgkJCWJhbnNoZWVfbWFrZV9yb29tKHBhcixmaWZvX2ZyZWUpOwoJCX0KCQl0ZGZ4X291dGwocGFyLAlMQVVOQ0hfMkQsKih1MzIqKWNoYXJkYXRhKTsKCQljaGFyZGF0YSArPSA0OyAKCX0JCgoJLyogU2VuZCB0aGUgbGVmdG92ZXJzIG5vdyAqLwkKCWJhbnNoZWVfbWFrZV9yb29tKHBhciwzKTsKCWkgPSBzaXplJTQ7CQoJc3dpdGNoIChpKSB7CgkJY2FzZSAwOiBicmVhazsKCQljYXNlIDE6ICB0ZGZ4X291dGwocGFyLAlMQVVOQ0hfMkQsKmNoYXJkYXRhKTsgYnJlYWs7CgkJY2FzZSAyOiAgdGRmeF9vdXRsKHBhciwJTEFVTkNIXzJELCoodTE2KiljaGFyZGF0YSk7IGJyZWFrOwoJCWNhc2UgMzogIHRkZnhfb3V0bChwYXIsCUxBVU5DSF8yRCwqKHUxNiopY2hhcmRhdGEgfCAoKGNoYXJkYXRhWzNdKSA8PCAyNCkpOyBicmVhazsKCX0KfQojZW5kaWYgLyogQ09ORklHX0ZCXzNERlhfQUNDRUwgKi8KCiNpZmRlZiBUREZYX0hBUkRXQVJFX0NVUlNPUgpzdGF0aWMgaW50IHRkZnhmYl9jdXJzb3Ioc3RydWN0IGZiX2luZm8gKmluZm8sIHN0cnVjdCBmYl9jdXJzb3IgKmN1cnNvcikKewoJc3RydWN0IHRkZnhfcGFyICpwYXIgPSAoc3RydWN0IHRkZnhfcGFyICopIGluZm8tPnBhcjsKCXVuc2lnbmVkIGxvbmcgZmxhZ3M7CgoJLyoKCSAqIElmIHRoZSBjdXJzb3IgaXMgbm90IGJlIGNoYW5nZWQgdGhpcyBtZWFucyBlaXRoZXIgd2Ugd2FudCB0aGUgCgkgKiBjdXJyZW50IGN1cnNvciBzdGF0ZSAoaWYgZW5hYmxlIGlzIHNldCkgb3Igd2Ugd2FudCB0byBxdWVyeSB3aGF0CgkgKiB3ZSBjYW4gZG8gd2l0aCB0aGUgY3Vyc29yIChpZiBlbmFibGUgaXMgbm90IHNldCkgCiAJICovCglpZiAoIWN1cnNvci0+c2V0KSByZXR1cm4gMDsKCgkvKiBUb28gbGFyZ2Ugb2YgYSBjdXJzb3IgOi0oICovCglpZiAoY3Vyc29yLT5pbWFnZS53aWR0aCA+IDY0IHx8IGN1cnNvci0+aW1hZ2UuaGVpZ2h0ID4gNjQpCgkJcmV0dXJuIC1FTlhJTzsKCgkvKiAKCSAqIElmIHdlIGFyZSBnb2luZyB0byBiZSBjaGFuZ2luZyB0aGluZ3Mgd2Ugc2hvdWxkIGRpc2FibGUKCSAqIHRoZSBjdXJzb3IgZmlyc3QgCgkgKi8KCWlmIChpbmZvLT5jdXJzb3IuZW5hYmxlKSB7CgkJc3Bpbl9sb2NrX2lycXNhdmUoJnBhci0+REFDbG9jaywgZmxhZ3MpOwoJCWluZm8tPmN1cnNvci5lbmFibGUgPSAwOwoJCWRlbF90aW1lcigmKHBhci0+aHdjdXJzb3IudGltZXIpKTsKCQl0ZGZ4X291dGwocGFyLCBWSURQUk9DQ0ZHLCBwYXItPmh3Y3Vyc29yLmRpc2FibGUpOwoJCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJnBhci0+REFDbG9jaywgZmxhZ3MpOwoJfQoKCS8qIERpc2FibGUgdGhlIEN1cnNvciAqLwoJaWYgKChjdXJzb3ItPnNldCAmJiBGQl9DVVJfU0VUQ1VSKSAmJiAhY3Vyc29yLT5lbmFibGUpCgkJcmV0dXJuIDA7CgoJLyogZml4IGN1cnNvciBjb2xvciAtIFhGcmVlODYgZm9yZ2V0cyB0byByZXN0b3JlIGl0IHByb3Blcmx5ICovCglpZiAoY3Vyc29yLT5zZXQgJiYgRkJfQ1VSX1NFVENNQVApIHsKCQlzdHJ1Y3QgZmJfY21hcCBjbWFwID0gY3Vyc29yLT5pbWFnZS5jbWFwOwoJCXVuc2lnbmVkIGxvbmcgYmdfY29sb3IsIGZnX2NvbG9yOwoKCQljbWFwLmxlbiA9IDI7IC8qIFZvb2RvbyAzKyBvbmx5IHN1cHBvcnQgMiBjb2xvciBjdXJzb3JzICovCgkJZmdfY29sb3IgPSAoKGNtYXAucmVkW2NtYXAuc3RhcnRdIDw8IDE2KSB8CgkJCSAgICAoY21hcC5ncmVlbltjbWFwLnN0YXJ0XSA8PCA4KSAgfAoJCQkgICAgKGNtYXAuYmx1ZVtjbWFwLnN0YXJ0XSkpOwoJCWJnX2NvbG9yID0gKChjbWFwLnJlZFtjbWFwLnN0YXJ0KzFdIDw8IDE2KSB8CgkJCSAgICAoY21hcC5ncmVlbltjbWFwLnN0YXJ0KzFdIDw8IDgpIHwKCQkJICAgIChjbWFwLmJsdWVbY21hcC5zdGFydCsxXSkpOwoJCWZiX2NvcHlfY21hcCgmY21hcCwgJmluZm8tPmN1cnNvci5pbWFnZS5jbWFwKTsKCQlzcGluX2xvY2tfaXJxc2F2ZSgmcGFyLT5EQUNsb2NrLCBmbGFncyk7CgkJYmFuc2hlZV9tYWtlX3Jvb20ocGFyLCAyKTsKCQl0ZGZ4X291dGwocGFyLCBIV0NVUkMwLCBiZ19jb2xvcik7CgkJdGRmeF9vdXRsKHBhciwgSFdDVVJDMSwgZmdfY29sb3IpOwoJCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJnBhci0+REFDbG9jaywgZmxhZ3MpOwoJfQoKCWlmIChjdXJzb3ItPnNldCAmJiBGQl9DVVJfU0VUUE9TKSB7CgkJaW50IHgsIHk7CgoJCXggPSBjdXJzb3ItPmltYWdlLmR4OwoJCXkgPSBjdXJzb3ItPmltYWdlLmR5OwoJCXkgLT0gaW5mby0+dmFyLnlvZmZzZXQ7CgkJaW5mby0+Y3Vyc29yLmltYWdlLmR4ID0geDsKCQlpbmZvLT5jdXJzb3IuaW1hZ2UuZHkgPSB5OwoJCXggKz0gNjM7CgkJeSArPSA2MzsKCQlzcGluX2xvY2tfaXJxc2F2ZSgmcGFyLT5EQUNsb2NrLCBmbGFncyk7CgkJYmFuc2hlZV9tYWtlX3Jvb20ocGFyLCAxKTsKCQl0ZGZ4X291dGwocGFyLCBIV0NVUkxPQywgKHkgPDwgMTYpICsgeCk7CgkJc3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmcGFyLT5EQUNsb2NrLCBmbGFncyk7Cgl9CgoJLyogTm90IHN1cHBvcnRlZCBzbyB3ZSBmYWtlIGl0ICovCglpZiAoY3Vyc29yLT5zZXQgJiYgRkJfQ1VSX1NFVEhPVCkgewoJCWluZm8tPmN1cnNvci5ob3QueCA9IGN1cnNvci0+aG90Lng7CgkJaW5mby0+Y3Vyc29yLmhvdC55ID0gY3Vyc29yLT5ob3QueTsKCX0KCglpZiAoY3Vyc29yLT5zZXQgJiYgRkJfQ1VSX1NFVFNIQVBFKSB7CgkJLyoKCSAJICogVm9vZG9vIDMgYW5kIGFib3ZlIGNhcmRzIHVzZSAyIG1vbm9jaHJvbWUgY3Vyc29yIHBhdHRlcm5zLgoJCSAqICAgIFRoZSByZWFzb24gaXMgc28gdGhlIGNhcmQgY2FuIGZldGNoIDggd29yZHMgYXQgYSB0aW1lCgkJICogYW5kIGFyZSBzdG9yZWQgb24gY2hpcCBmb3IgdXNlIGZvciB0aGUgbmV4dCA4IHNjYW5saW5lcy4KCQkgKiBUaGlzIHJlZHVjZXMgdGhlIG51bWJlciBvZiB0aW1lcyBmb3IgYWNjZXNzIHRvIGRyYXcgdGhlCgkJICogY3Vyc29yIGZvciBlYWNoIHNjcmVlbiByZWZyZXNoLgoJCSAqICAgIEVhY2ggcGF0dGVybiBpcyBhIGJpdG1hcCBvZiA2NCBiaXQgd2lkZSBhbmQgNjQgYml0IGhpZ2gKCQkgKiAodG90YWwgb2YgODE5MiBiaXRzIG9yIDEwMjQgS2J5dGVzKS4gVGhlIHR3byBwYXR0ZXJucyBhcmUKCQkgKiBzdG9yZWQgaW4gc3VjaCBhIHdheSB0aGF0IHBhdHRlcm4gMCBhbHdheXMgcmVzaWRlcyBpbiB0aGUKCQkgKiBsb3dlciBoYWxmIChsZWFzdCBzaWduaWZpY2FudCA2NCBiaXRzKSBvZiBhIDEyOCBiaXQgd29yZAoJCSAqIGFuZCBwYXR0ZXJuIDEgdGhlIHVwcGVyIGhhbGYuIElmIHlvdSBleGFtaW5lIHRoZSBkYXRhIG9mCgkJICogdGhlIGN1cnNvciBpbWFnZSB0aGUgZ3JhcGhpY3MgY2FyZCB1c2VzIHRoZW4gZnJvbSB0aGUKCQkgKiBiZWdpbmluZyB5b3Ugc2VlIGxpbmUgb25lIG9mIHBhdHRlcm4gMCwgbGluZSBvbmUgb2YKCQkgKiBwYXR0ZXJuIDEsIGxpbmUgdHdvIG9mIHBhdHRlcm4gMCwgbGluZSB0d28gb2YgcGF0dGVybiAxLAoJCSAqIGV0YyBldGMuIFRoZSBsaW5lYXIgc3RyaWRlIGZvciB0aGUgY3Vyc29yIGlzIGFsd2F5cyAxNiBieXRlcwoJCSAqICgxMjggYml0cykgd2hpY2ggaXMgdGhlIG1heGltdW0gY3Vyc29yIHdpZHRoIHRpbWVzIHR3byBmb3IKCQkgKiB0aGUgdHdvIG1vbm9jaHJvbWUgcGF0dGVybnMuCgkJICovCgkJdTggKmN1cnNvcmJhc2UgPSAodTggKikgaW5mby0+Y3Vyc29yLmltYWdlLmRhdGE7CgkJY2hhciAqYml0bWFwID0gKGNoYXIgKiljdXJzb3ItPmltYWdlLmRhdGE7CgkJY2hhciAqbWFzayA9IChjaGFyICopIGN1cnNvci0+bWFzazsKCQlpbnQgaSwgaiwgaywgaCA9IDA7CgoJCWZvciAoaSA9IDA7IGkgPCA2NDsgaSsrKSB7CgkJCWlmIChpIDwgY3Vyc29yLT5pbWFnZS5oZWlnaHQpIHsKCQkJCWogPSAoY3Vyc29yLT5pbWFnZS53aWR0aCArIDcpID4+IDM7CgkJCQlrID0gOCAtIGo7CgoJCQkJZm9yICg7aiA+IDA7IGotLSkgewoJCQkJLyogUGF0dGVybiAwLiBDb3B5IHRoZSBjdXJzb3IgYml0bWFwIHRvIGl0ICovCgkJCQkJZmJfd3JpdGViKCpiaXRtYXAsIGN1cnNvcmJhc2UgKyBoKTsKCQkJCQliaXRtYXArKzsKCQkJCS8qIFBhdHRlcm4gMS4gQ29weSB0aGUgY3Vyc29yIG1hc2sgdG8gaXQgKi8KCQkJCQlmYl93cml0ZWIoKm1hc2ssIGN1cnNvcmJhc2UgKyBoICsgOCk7CgkJCQkJbWFzaysrOwoJCQkJCWgrKzsKCQkJCX0KCQkJCWZvciAoO2sgPiAwOyBrLS0pIHsKCQkJCQlmYl93cml0ZWIoMCwgY3Vyc29yYmFzZSArIGgpOwoJCQkJCWZiX3dyaXRlYih+MCwgY3Vyc29yYmFzZSArIGggKyA4KTsKCQkJCQloKys7CgkJCQl9CgkJCX0gZWxzZSB7CgkJCQlmYl93cml0ZWwoMCwgY3Vyc29yYmFzZSArIGgpOwoJCQkJZmJfd3JpdGVsKDAsIGN1cnNvcmJhc2UgKyBoICsgNCk7CgkJCQlmYl93cml0ZWwofjAsIGN1cnNvcmJhc2UgKyBoICsgOCk7CgkJCQlmYl93cml0ZWwofjAsIGN1cnNvcmJhc2UgKyBoICsgMTIpOwoJCQkJaCArPSAxNjsKCQkJfQoJCX0KCX0KCS8qIFR1cm4gdGhlIGN1cnNvciBvbiAqLwoJY3Vyc29yLT5lbmFibGUgPSAxOwoJaW5mby0+Y3Vyc29yID0gKmN1cnNvcjsKCW1vZF90aW1lcigmcGFyLT5od2N1cnNvci50aW1lciwgamlmZmllcytIWi8yKTsKCXNwaW5fbG9ja19pcnFzYXZlKCZwYXItPkRBQ2xvY2ssIGZsYWdzKTsKCWJhbnNoZWVfbWFrZV9yb29tKHBhciwgMSk7Cgl0ZGZ4X291dGwocGFyLCBWSURQUk9DQ0ZHLCBwYXItPmh3Y3Vyc29yLmVuYWJsZSk7CglzcGluX3VubG9ja19pcnFyZXN0b3JlKCZwYXItPkRBQ2xvY2ssIGZsYWdzKTsKCXJldHVybiAwOwp9CiNlbmRpZgoKLyoqCiAqICAgICAgdGRmeGZiX3Byb2JlIC0gRGV2aWNlIEluaXRpYWxpemlhdGlvbgogKgogKiAgICAgIEBwZGV2OiAgUENJIERldmljZSB0byBpbml0aWFsaXplCiAqICAgICAgQGlkOiAgICBQQ0kgRGV2aWNlIElECiAqCiAqICAgICAgSW5pdGlhbGl6ZXMgYW5kIGFsbG9jYXRlcyByZXNvdXJjZXMgZm9yIFBDSSBkZXZpY2UgQHBkZXYuCiAqCiAqLwpzdGF0aWMgaW50IF9fZGV2aW5pdCB0ZGZ4ZmJfcHJvYmUoc3RydWN0IHBjaV9kZXYgKnBkZXYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzdHJ1Y3QgcGNpX2RldmljZV9pZCAqaWQpCnsKCXN0cnVjdCB0ZGZ4X3BhciAqZGVmYXVsdF9wYXI7CglzdHJ1Y3QgZmJfaW5mbyAqaW5mbzsKCWludCBzaXplLCBlcnIsIGxwaXRjaDsKCglpZiAoKGVyciA9IHBjaV9lbmFibGVfZGV2aWNlKHBkZXYpKSkgewoJCXByaW50ayhLRVJOX1dBUk5JTkcgInRkZnhmYjogQ2FuJ3QgZW5hYmxlIHBkZXY6ICVkXG4iLCBlcnIpOwoJCXJldHVybiBlcnI7Cgl9CgoJc2l6ZSA9IHNpemVvZihzdHJ1Y3QgdGRmeF9wYXIpKzI1NipzaXplb2YodTMyKTsKCglpbmZvID0gZnJhbWVidWZmZXJfYWxsb2Moc2l6ZSwgJnBkZXYtPmRldik7CgoJaWYgKCFpbmZvKQlyZXR1cm4gLUVOT01FTTsKCQkKCWRlZmF1bHRfcGFyID0gaW5mby0+cGFyOwogCgkvKiBDb25maWd1cmUgdGhlIGRlZmF1bHQgZmJfZml4X3NjcmVlbmluZm8gZmlyc3QgKi8KCXN3aXRjaCAocGRldi0+ZGV2aWNlKSB7CgkJY2FzZSBQQ0lfREVWSUNFX0lEXzNERlhfQkFOU0hFRToJCgkJCXN0cmNhdCh0ZGZ4X2ZpeC5pZCwgIiBCYW5zaGVlIik7CgkJCWRlZmF1bHRfcGFyLT5tYXhfcGl4Y2xvY2sgPSBCQU5TSEVFX01BWF9QSVhDTE9DSzsKCQkJYnJlYWs7CgkJY2FzZSBQQ0lfREVWSUNFX0lEXzNERlhfVk9PRE9PMzoKCQkJc3RyY2F0KHRkZnhfZml4LmlkLCAiIFZvb2RvbzMiKTsKCQkJZGVmYXVsdF9wYXItPm1heF9waXhjbG9jayA9IFZPT0RPTzNfTUFYX1BJWENMT0NLOwoJCQlicmVhazsKCQljYXNlIFBDSV9ERVZJQ0VfSURfM0RGWF9WT09ET081OgoJCQlzdHJjYXQodGRmeF9maXguaWQsICIgVm9vZG9vNSIpOwoJCQlkZWZhdWx0X3Bhci0+bWF4X3BpeGNsb2NrID0gVk9PRE9PNV9NQVhfUElYQ0xPQ0s7CgkJCWJyZWFrOwoJfQoKCXRkZnhfZml4Lm1taW9fc3RhcnQgPSBwY2lfcmVzb3VyY2Vfc3RhcnQocGRldiwgMCk7Cgl0ZGZ4X2ZpeC5tbWlvX2xlbiA9IHBjaV9yZXNvdXJjZV9sZW4ocGRldiwgMCk7CglkZWZhdWx0X3Bhci0+cmVnYmFzZV92aXJ0ID0gaW9yZW1hcF9ub2NhY2hlKHRkZnhfZml4Lm1taW9fc3RhcnQsIHRkZnhfZml4Lm1taW9fbGVuKTsKCWlmICghZGVmYXVsdF9wYXItPnJlZ2Jhc2VfdmlydCkgewoJCXByaW50aygiZmI6IENhbid0IHJlbWFwICVzIHJlZ2lzdGVyIGFyZWEuXG4iLCB0ZGZ4X2ZpeC5pZCk7CgkJZ290byBvdXRfZXJyOwoJfQogICAgCglpZiAoIXJlcXVlc3RfbWVtX3JlZ2lvbihwY2lfcmVzb3VyY2Vfc3RhcnQocGRldiwgMCksCgkgICAgcGNpX3Jlc291cmNlX2xlbihwZGV2LCAwKSwgInRkZnggcmVnYmFzZSIpKSB7CgkJcHJpbnRrKEtFUk5fV0FSTklORyAidGRmeGZiOiBDYW4ndCByZXNlcnZlIHJlZ2Jhc2VcbiIpOwoJCWdvdG8gb3V0X2VycjsKCX0gCgoJdGRmeF9maXguc21lbV9zdGFydCA9IHBjaV9yZXNvdXJjZV9zdGFydChwZGV2LCAxKTsKCWlmICghKHRkZnhfZml4LnNtZW1fbGVuID0gZG9fbGZiX3NpemUoZGVmYXVsdF9wYXIsIHBkZXYtPmRldmljZSkpKSB7CgkJcHJpbnRrKCJmYjogQ2FuJ3QgY291bnQgJXMgbWVtb3J5LlxuIiwgdGRmeF9maXguaWQpOwoJCXJlbGVhc2VfbWVtX3JlZ2lvbihwY2lfcmVzb3VyY2Vfc3RhcnQocGRldiwgMCksCgkJCQkgICBwY2lfcmVzb3VyY2VfbGVuKHBkZXYsIDApKTsKCQlnb3RvIG91dF9lcnI7CQoJfQoKCWlmICghcmVxdWVzdF9tZW1fcmVnaW9uKHBjaV9yZXNvdXJjZV9zdGFydChwZGV2LCAxKSwKCSAgICAgcGNpX3Jlc291cmNlX2xlbihwZGV2LCAxKSwgInRkZnggc21lbSIpKSB7CgkJcHJpbnRrKEtFUk5fV0FSTklORyAidGRmeGZiOiBDYW4ndCByZXNlcnZlIHNtZW1cbiIpOwoJCXJlbGVhc2VfbWVtX3JlZ2lvbihwY2lfcmVzb3VyY2Vfc3RhcnQocGRldiwgMCksCgkJCQkgICBwY2lfcmVzb3VyY2VfbGVuKHBkZXYsIDApKTsKCQlnb3RvIG91dF9lcnI7Cgl9CgoJaW5mby0+c2NyZWVuX2Jhc2UgPSBpb3JlbWFwX25vY2FjaGUodGRmeF9maXguc21lbV9zdGFydCwgCgkJCQkJICAgIHRkZnhfZml4LnNtZW1fbGVuKTsKCWlmICghaW5mby0+c2NyZWVuX2Jhc2UpIHsKCQlwcmludGsoImZiOiBDYW4ndCByZW1hcCAlcyBmcmFtZWJ1ZmZlci5cbiIsIHRkZnhfZml4LmlkKTsKCQlyZWxlYXNlX21lbV9yZWdpb24ocGNpX3Jlc291cmNlX3N0YXJ0KHBkZXYsIDEpLAoJCQkJICAgcGNpX3Jlc291cmNlX2xlbihwZGV2LCAxKSk7CgkJcmVsZWFzZV9tZW1fcmVnaW9uKHBjaV9yZXNvdXJjZV9zdGFydChwZGV2LCAwKSwKCQkJCSAgIHBjaV9yZXNvdXJjZV9sZW4ocGRldiwgMCkpOwoJCWdvdG8gb3V0X2VycjsKCX0KCglkZWZhdWx0X3Bhci0+aW9iYXNlID0gcGNpX3Jlc291cmNlX3N0YXJ0KHBkZXYsIDIpOwogICAgCglpZiAoIXJlcXVlc3RfcmVnaW9uKHBjaV9yZXNvdXJjZV9zdGFydChwZGV2LCAyKSwKCSAgICBwY2lfcmVzb3VyY2VfbGVuKHBkZXYsIDIpLCAidGRmeCBpb2Jhc2UiKSkgewoJCXByaW50ayhLRVJOX1dBUk5JTkcgInRkZnhmYjogQ2FuJ3QgcmVzZXJ2ZSBpb2Jhc2VcbiIpOwoJCXJlbGVhc2VfbWVtX3JlZ2lvbihwY2lfcmVzb3VyY2Vfc3RhcnQocGRldiwgMSksCgkJCQkgICBwY2lfcmVzb3VyY2VfbGVuKHBkZXYsIDEpKTsKCQlyZWxlYXNlX21lbV9yZWdpb24ocGNpX3Jlc291cmNlX3N0YXJ0KHBkZXYsIDApLAoJCQkJICAgcGNpX3Jlc291cmNlX2xlbihwZGV2LCAwKSk7CgkJZ290byBvdXRfZXJyOwoJfQoKCXByaW50aygiZmI6ICVzIG1lbW9yeSA9ICVkS1xuIiwgdGRmeF9maXguaWQsIHRkZnhfZml4LnNtZW1fbGVuID4+IDEwKTsKCgl0ZGZ4X2ZpeC55cGFuc3RlcAk9IG5vcGFuID8gMCA6IDE7Cgl0ZGZ4X2ZpeC55d3JhcHN0ZXAJPSBub3dyYXAgPyAwIDogMTsKICAgCglpbmZvLT5mYm9wcwkJPSAmdGRmeGZiX29wczsKCWluZm8tPmZpeAkJPSB0ZGZ4X2ZpeDsgCQoJaW5mby0+cHNldWRvX3BhbGV0dGUJPSAodm9pZCAqKShkZWZhdWx0X3BhciArIDEpOyAKCWluZm8tPmZsYWdzCQk9IEZCSU5GT19ERUZBVUxUIHwgRkJJTkZPX0hXQUNDRUxfWVBBTjsKI2lmZGVmIENPTkZJR19GQl8zREZYX0FDQ0VMCglpbmZvLT5mbGFncyAgICAgICAgICAgICB8PSBGQklORk9fSFdBQ0NFTF9GSUxMUkVDVCB8CgkJRkJJTkZPX0hXQUNDRUxfQ09QWUFSRUEgfCBGQklORk9fSFdBQ0NFTF9JTUFHRUJMSVQ7CiNlbmRpZgoKCWlmICghbW9kZV9vcHRpb24pCgkJbW9kZV9vcHRpb24gPSAiNjQweDQ4MEA2MCI7CgkgCgllcnIgPSBmYl9maW5kX21vZGUoJmluZm8tPnZhciwgaW5mbywgbW9kZV9vcHRpb24sIE5VTEwsIDAsIE5VTEwsIDgpOyAKCWlmICghZXJyIHx8IGVyciA9PSA0KQoJCWluZm8tPnZhciA9IHRkZnhfdmFyOwoKCS8qIG1heGltaXplIHZpcnR1YWwgdmVydGljYWwgbGVuZ3RoICovCglscGl0Y2ggPSBpbmZvLT52YXIueHJlc192aXJ0dWFsICogKChpbmZvLT52YXIuYml0c19wZXJfcGl4ZWwgKyA3KSA+PiAzKTsKCWluZm8tPnZhci55cmVzX3ZpcnR1YWwgPSBpbmZvLT5maXguc21lbV9sZW4vbHBpdGNoOwoJaWYgKGluZm8tPnZhci55cmVzX3ZpcnR1YWwgPCBpbmZvLT52YXIueXJlcykKCQlnb3RvIG91dF9lcnI7CgojaWZkZWYgQ09ORklHX0ZCXzNERlhfQUNDRUwKCS8qCgkgKiBGSVhNRTogTGltaXQgdmFyLT55cmVzX3ZpcnR1YWwgdG8gNDA5NiBiZWNhdXNlIG9mIHNjcmVlbiBhcnRpZmFjdHMKCSAqIGR1cmluZyBzY3JvbGxpbmcuIFRoaXMgaXMgb25seSBwcmVzZW50IGlmIDJEIGFjY2VsZXJhdGlvbiBpcwoJICogZW5hYmxlZC4KCSAqLwoJaWYgKGluZm8tPnZhci55cmVzX3ZpcnR1YWwgPiA0MDk2KQoJCWluZm8tPnZhci55cmVzX3ZpcnR1YWwgPSA0MDk2OwojZW5kaWYgLyogQ09ORklHX0ZCXzNERlhfQUNDRUwgKi8KCglpZiAoZmJfYWxsb2NfY21hcCgmaW5mby0+Y21hcCwgMjU2LCAwKSA8IDApIHsKCQlwcmludGsoS0VSTl9XQVJOSU5HICJ0ZGZ4ZmI6IENhbid0IGFsbG9jYXRlIGNvbG9yIG1hcFxuIik7CgkJZ290byBvdXRfZXJyOwoJfQoKCWlmIChyZWdpc3Rlcl9mcmFtZWJ1ZmZlcihpbmZvKSA8IDApIHsKCQlwcmludGsoInRkZnhmYjogY2FuJ3QgcmVnaXN0ZXIgZnJhbWVidWZmZXJcbiIpOwoJCWZiX2RlYWxsb2NfY21hcCgmaW5mby0+Y21hcCk7CgkJZ290byBvdXRfZXJyOwoJfQoJLyoKCSAqIE91ciBkcml2ZXIgZGF0YQoJICovCglwY2lfc2V0X2RydmRhdGEocGRldiwgaW5mbyk7CglyZXR1cm4gMDsgCgpvdXRfZXJyOgoJLyoKCSAqIENsZWFudXAgYWZ0ZXIgYW55dGhpbmcgdGhhdCB3YXMgcmVtYXBwZWQvYWxsb2NhdGVkLgoJICovCglpZiAoZGVmYXVsdF9wYXItPnJlZ2Jhc2VfdmlydCkKCQlpb3VubWFwKGRlZmF1bHRfcGFyLT5yZWdiYXNlX3ZpcnQpOwoJaWYgKGluZm8tPnNjcmVlbl9iYXNlKQoJCWlvdW5tYXAoaW5mby0+c2NyZWVuX2Jhc2UpOwoJZnJhbWVidWZmZXJfcmVsZWFzZShpbmZvKTsKCXJldHVybiAtRU5YSU87Cn0KCiNpZm5kZWYgTU9EVUxFCnZvaWQgdGRmeGZiX3NldHVwKGNoYXIgKm9wdGlvbnMpCnsKCWNoYXIqIHRoaXNfb3B0OwoKCWlmICghb3B0aW9ucyB8fCAhKm9wdGlvbnMpCgkJcmV0dXJuOwoKCXdoaWxlICgodGhpc19vcHQgPSBzdHJzZXAoJm9wdGlvbnMsICIsIikpICE9IE5VTEwpIHsKCQlpZiAoISp0aGlzX29wdCkKCQkJY29udGludWU7CgkJaWYoIXN0cmNtcCh0aGlzX29wdCwgIm5vcGFuIikpIHsKCQkJbm9wYW4gPSAxOwoJCX0gZWxzZSBpZighc3RyY21wKHRoaXNfb3B0LCAibm93cmFwIikpIHsKCQkJbm93cmFwID0gMTsKCQl9IGVsc2UgewoJCQltb2RlX29wdGlvbiA9IHRoaXNfb3B0OwoJCX0KCX0KfQojZW5kaWYKCi8qKgogKiAgICAgIHRkZnhmYl9yZW1vdmUgLSBEZXZpY2UgcmVtb3ZhbAogKgogKiAgICAgIEBwZGV2OiAgUENJIERldmljZSB0byBjbGVhbnVwCiAqCiAqICAgICAgUmVsZWFzZXMgYWxsIHJlc291cmNlcyBhbGxvY2F0ZWQgZHVyaW5nIHRoZSBjb3Vyc2Ugb2YgdGhlIGRyaXZlcidzCiAqICAgICAgbGlmZXRpbWUgZm9yIHRoZSBQQ0kgZGV2aWNlIEBwZGV2LgogKgogKi8Kc3RhdGljIHZvaWQgX19kZXZleGl0IHRkZnhmYl9yZW1vdmUoc3RydWN0IHBjaV9kZXYgKnBkZXYpCnsKCXN0cnVjdCBmYl9pbmZvICppbmZvID0gcGNpX2dldF9kcnZkYXRhKHBkZXYpOwoJc3RydWN0IHRkZnhfcGFyICpwYXIgPSAoc3RydWN0IHRkZnhfcGFyICopIGluZm8tPnBhcjsKCgl1bnJlZ2lzdGVyX2ZyYW1lYnVmZmVyKGluZm8pOwoJaW91bm1hcChwYXItPnJlZ2Jhc2VfdmlydCk7Cglpb3VubWFwKGluZm8tPnNjcmVlbl9iYXNlKTsKCgkvKiBDbGVhbiB1cCBhZnRlciByZXNlcnZlZCByZWdpb25zICovCglyZWxlYXNlX3JlZ2lvbihwY2lfcmVzb3VyY2Vfc3RhcnQocGRldiwgMiksCgkJICAgICAgIHBjaV9yZXNvdXJjZV9sZW4ocGRldiwgMikpOwoJcmVsZWFzZV9tZW1fcmVnaW9uKHBjaV9yZXNvdXJjZV9zdGFydChwZGV2LCAxKSwKCQkJICAgcGNpX3Jlc291cmNlX2xlbihwZGV2LCAxKSk7CglyZWxlYXNlX21lbV9yZWdpb24ocGNpX3Jlc291cmNlX3N0YXJ0KHBkZXYsIDApLAoJCQkgICBwY2lfcmVzb3VyY2VfbGVuKHBkZXYsIDApKTsKCXBjaV9zZXRfZHJ2ZGF0YShwZGV2LCBOVUxMKTsKCWZyYW1lYnVmZmVyX3JlbGVhc2UoaW5mbyk7Cn0KCnN0YXRpYyBpbnQgX19pbml0IHRkZnhmYl9pbml0KHZvaWQpCnsKI2lmbmRlZiBNT0RVTEUKCWNoYXIgKm9wdGlvbiA9IE5VTEw7CgoJaWYgKGZiX2dldF9vcHRpb25zKCJ0ZGZ4ZmIiLCAmb3B0aW9uKSkKCQlyZXR1cm4gLUVOT0RFVjsKCgl0ZGZ4ZmJfc2V0dXAob3B0aW9uKTsKI2VuZGlmCiAgICAgICAgcmV0dXJuIHBjaV9yZWdpc3Rlcl9kcml2ZXIoJnRkZnhmYl9kcml2ZXIpOwp9CgpzdGF0aWMgdm9pZCBfX2V4aXQgdGRmeGZiX2V4aXQodm9pZCkKewogICAgICAgIHBjaV91bnJlZ2lzdGVyX2RyaXZlcigmdGRmeGZiX2RyaXZlcik7Cn0KCk1PRFVMRV9BVVRIT1IoIkhhbm51IE1hbGxhdCA8aG1hbGxhdEBjYy5odXQuZmk+Iik7Ck1PRFVMRV9ERVNDUklQVElPTigiM0RmeCBmcmFtZWJ1ZmZlciBkZXZpY2UgZHJpdmVyIik7Ck1PRFVMRV9MSUNFTlNFKCJHUEwiKTsKIAptb2R1bGVfaW5pdCh0ZGZ4ZmJfaW5pdCk7Cm1vZHVsZV9leGl0KHRkZnhmYl9leGl0KTsK