LyoKICogbGludXgvZHJpdmVycy92aWRlby9zM2MyNDEwZmIuYwogKglDb3B5cmlnaHQgKGMpIEFybmF1ZCBQYXRhcmQsIEJlbiBEb29rcwogKgogKiBUaGlzIGZpbGUgaXMgc3ViamVjdCB0byB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlLiAgU2VlIHRoZSBmaWxlIENPUFlJTkcgaW4gdGhlIG1haW4gZGlyZWN0b3J5IG9mIHRoaXMgYXJjaGl2ZSBmb3IKICogbW9yZSBkZXRhaWxzLgogKgogKgkgICAgUzNDMjQxMCBMQ0QgQ29udHJvbGxlciBGcmFtZSBCdWZmZXIgRHJpdmVyCiAqCSAgICBiYXNlZCBvbiBza2VsZXRvbmZiLmMsIHNhMTEwMGZiLmMgYW5kIG90aGVycwogKgogKiBDaGFuZ2VMb2cKICogMjAwNS0wNC0wNzogQXJuYXVkIFBhdGFyZCA8YXJuYXVkLnBhdGFyZEBydHAtbmV0Lm9yZz4KICogICAgICAtIHUzMiBzdGF0ZSAtPiBwbV9tZXNzYWdlX3Qgc3RhdGUKICogICAgICAtIFMzQzI0MTBfe1ZBLFNafV9MQ0QgLT4gUzNDMjRYWAogKgogKiAyMDA1LTAzLTE1OiBBcm5hdWQgUGF0YXJkIDxhcm5hdWQucGF0YXJkQHJ0cC1uZXQub3JnPgogKiAgICAgIC0gUmVtb3ZlZCB0aGUgaW9jdGwKICogICAgICAtIHVzZSByZWFkbC93cml0ZWwgaW5zdGVhZCBvZiBfX3Jhd193cml0ZWwvX19yYXdfcmVhZGwKICoKICogMjAwNC0xMi0wNDogQXJuYXVkIFBhdGFyZCA8YXJuYXVkLnBhdGFyZEBydHAtbmV0Lm9yZz4KICogICAgICAtIEFkZGVkIHRoZSBwb3NzaWJpbGl0eSB0byBzZXQgb24gb3Igb2ZmIHRoZQogKiAgICAgIGRlYnVnZ2luZyBtZXNhYWdlcwogKiAgICAgIC0gUmVwbGFjZWQgMCBhbmQgMSBieSBvbiBvciBvZmYgd2hlbiByZWFkaW5nIHRoZQogKiAgICAgIC9zeXMgZmlsZXMKICoKICogMjAwNS0wMy0yMzogQmVuIERvb2tzIDxiZW4tbGludXhAZmx1ZmYub3JnPgogKgktIGFkZGVkIG5vbiAxNmJwcCBtb2RlcwogKgktIHVwZGF0ZWQgcGxhdGZvcm0gaW5mb3JtYXRpb24gZm9yIHJhbmdlIG9mIHgveS9icHAKICoJLSBhZGQgY29kZSB0byBlbnN1cmUgcGFsZXR0ZSBpcyB3cml0dGVuIGNvcnJlY3RseQogKgktIGFkZCBwaXhlbCBjbG9jayBkaXZpc29yIGNvbnRyb2wKICoKICogMjAwNC0xMS0xMTogQXJuYXVkIFBhdGFyZCA8YXJuYXVkLnBhdGFyZEBydHAtbmV0Lm9yZz4KICogCS0gUmVtb3ZlZCB0aGUgdXNlIG9mIGN1cnJjb24gYXMgaXQgbm8gbW9yZSBleGlzdAogKiAJLSBBZGRlZCBMQ0QgcG93ZXIgc3lzZnMgaW50ZXJmYWNlCiAqCiAqIDIwMDQtMTEtMDM6IEJlbiBEb29rcyA8YmVuLWxpbnV4QGZsdWZmLm9yZz4KICoJLSBtaW5vciBjbGVhbnVwcwogKgktIGFkZCBzdXNwZW5kL3Jlc3VtZSBzdXBwb3J0CiAqCS0gczNjMjQxMGZiX3NldGNvbHJlZygpIG5vdCB2YWxpZCBpbiA+OGJwcCBtb2RlcwogKgktIHJlbW92ZWQgbGFzdCBDT05GSUdfRkJfUzNDMjQxMF9GSVhFRAogKgktIGVuc3VyZSBsY2QgY29udHJvbGxlciBzdG9wcGVkIGJlZm9yZSBjbGVhbnVwCiAqCS0gYWRkZWQgc3lzZnMgaW50ZXJmYWNlIGZvciBiYWNrbGlnaHQgcG93ZXIKICoJLSBhZGRlZCBtYXNrIGZvciBncGlvIGNvbmZpZ3VyYXRpb24KICoJLSBlbnN1cmVkIElSUXMgZGlzYWJsZWQgZHVyaW5nIEdQSU8gY29uZmlndXJhdGlvbgogKgktIGRpc2FibGUgVFBBTCBiZWZvcmUgZW5hYmxpbmcgdmlkZW8KICoKICogMjAwNC0wOS0yMDogQXJuYXVkIFBhdGFyZCA8YXJuYXVkLnBhdGFyZEBydHAtbmV0Lm9yZz4KICogICAgICAtIFN1cHByZXNzIGNvbW1hbmQgbGluZSBvcHRpb25zCiAqCiAqIDIwMDQtMDktMTU6IEFybmF1ZCBQYXRhcmQgPGFybmF1ZC5wYXRhcmRAcnRwLW5ldC5vcmc+CiAqIAktIGNvZGUgY2xlYW51cAogKgogKiAyMDA0LTA5LTA3OiBBcm5hdWQgUGF0YXJkIDxhcm5hdWQucGF0YXJkQHJ0cC1uZXQub3JnPgogKiAJLSBSZW5hbWVkIGZyb20gaDE5NDBmYi5jIHRvIHMzYzI0MTBmYi5jCiAqIAktIEFkZCBzdXBwb3J0IGZvciBkaWZmZXJlbnQgZGV2aWNlcwogKiAJLSBCYWNrbGlnaHQgc3VwcG9ydAogKgogKiAyMDA0LTA5LTA1OiBIZXJiZXJ0IFD2dHpsIDxoZXJiZXJ0QDEzdGhmbG9vci5hdD4KICoJLSBhZGRlZCBjbG9jayAoZGUtKWFsbG9jYXRpb24gY29kZQogKgktIGFkZGVkIGZpeGVtIGZibWVtIG9wdGlvbgogKgogKiAyMDA0LTA3LTI3OiBBcm5hdWQgUGF0YXJkIDxhcm5hdWQucGF0YXJkQHJ0cC1uZXQub3JnPgogKgktIGNvZGUgY2xlYW51cAogKgktIGFkZGVkIGEgZm9yZ290dGVuIHJldHVybiBpbiBoMTk0MGZiX2luaXQKICoKICogMjAwNC0wNy0xOTogSGVyYmVydCBQ9nR6bCA8aGVyYmVydEAxM3RoZmxvb3IuYXQ+CiAqCS0gY29kZSBjbGVhbnVwIGFuZCBleHRlbmRlZCBkZWJ1Z2dpbmcKICoKICogMjAwNC0wNy0xNTogQXJuYXVkIFBhdGFyZCA8YXJuYXVkLnBhdGFyZEBydHAtbmV0Lm9yZz4KICoJLSBGaXJzdCB2ZXJzaW9uCiAqLwoKI2luY2x1ZGUgPGxpbnV4L21vZHVsZS5oPgojaW5jbHVkZSA8bGludXgva2VybmVsLmg+CiNpbmNsdWRlIDxsaW51eC9lcnJuby5oPgojaW5jbHVkZSA8bGludXgvc3RyaW5nLmg+CiNpbmNsdWRlIDxsaW51eC9tbS5oPgojaW5jbHVkZSA8bGludXgvdHR5Lmg+CiNpbmNsdWRlIDxsaW51eC9zbGFiLmg+CiNpbmNsdWRlIDxsaW51eC9kZWxheS5oPgojaW5jbHVkZSA8bGludXgvZmIuaD4KI2luY2x1ZGUgPGxpbnV4L2luaXQuaD4KI2luY2x1ZGUgPGxpbnV4L2RtYS1tYXBwaW5nLmg+CiNpbmNsdWRlIDxsaW51eC9zdHJpbmcuaD4KI2luY2x1ZGUgPGxpbnV4L2ludGVycnVwdC5oPgojaW5jbHVkZSA8bGludXgvd29ya3F1ZXVlLmg+CiNpbmNsdWRlIDxsaW51eC93YWl0Lmg+CiNpbmNsdWRlIDxsaW51eC9wbGF0Zm9ybV9kZXZpY2UuaD4KCiNpbmNsdWRlIDxhc20vaW8uaD4KI2luY2x1ZGUgPGFzbS91YWNjZXNzLmg+CiNpbmNsdWRlIDxhc20vZGl2NjQuaD4KCiNpbmNsdWRlIDxhc20vbWFjaC9tYXAuaD4KI2luY2x1ZGUgPGFzbS9hcmNoL3JlZ3MtbGNkLmg+CiNpbmNsdWRlIDxhc20vYXJjaC9yZWdzLWdwaW8uaD4KI2luY2x1ZGUgPGFzbS9hcmNoL2ZiLmg+CiNpbmNsdWRlIDxhc20vaGFyZHdhcmUvY2xvY2suaD4KCiNpZmRlZiBDT05GSUdfUE0KI2luY2x1ZGUgPGxpbnV4L3BtLmg+CiNlbmRpZgoKI2luY2x1ZGUgInMzYzI0MTBmYi5oIgoKCnN0YXRpYyBzdHJ1Y3QgczNjMjQxMGZiX21hY2hfaW5mbyAqbWFjaF9pbmZvOwoKLyogRGVidWdnaW5nIHN0dWZmICovCiNpZmRlZiBDT05GSUdfRkJfUzNDMjQxMF9ERUJVRwpzdGF0aWMgaW50IGRlYnVnCSAgID0gMTsKI2Vsc2UKc3RhdGljIGludCBkZWJ1ZwkgICA9IDA7CiNlbmRpZgoKI2RlZmluZSBkcHJpbnRrKG1zZy4uLikJaWYgKGRlYnVnKSB7IHByaW50ayhLRVJOX0RFQlVHICJzM2MyNDEwZmI6ICIgbXNnKTsgfQoKLyogdXNlZnVsIGZ1bmN0aW9ucyAqLwoKLyogczNjMjQxMGZiX3NldF9sY2RhZGRyCiAqCiAqIGluaXRpYWxpc2UgbGNkIGNvbnRyb2xsZXIgYWRkcmVzcyBwb2ludGVycwoqLwoKc3RhdGljIHZvaWQgczNjMjQxMGZiX3NldF9sY2RhZGRyKHN0cnVjdCBzM2MyNDEwZmJfaW5mbyAqZmJpKQp7CglzdHJ1Y3QgZmJfdmFyX3NjcmVlbmluZm8gKnZhciA9ICZmYmktPmZiLT52YXI7Cgl1bnNpZ25lZCBsb25nIHNhZGRyMSwgc2FkZHIyLCBzYWRkcjM7CgoJc2FkZHIxICA9IGZiaS0+ZmItPmZpeC5zbWVtX3N0YXJ0ID4+IDE7CglzYWRkcjIgID0gZmJpLT5mYi0+Zml4LnNtZW1fc3RhcnQ7CglzYWRkcjIgKz0gKHZhci0+eHJlcyAqIHZhci0+eXJlcyAqIHZhci0+Yml0c19wZXJfcGl4ZWwpLzg7CglzYWRkcjI+Pj0gMTsKCglzYWRkcjMgPSAgUzNDMjQxMF9PRkZTSVpFKDApIHwgUzNDMjQxMF9QQUdFV0lEVEgodmFyLT54cmVzKTsKCglkcHJpbnRrKCJMQ0RTQUREUjEgPSAweCUwOGx4XG4iLCBzYWRkcjEpOwoJZHByaW50aygiTENEU0FERFIyID0gMHglMDhseFxuIiwgc2FkZHIyKTsKCWRwcmludGsoIkxDRFNBRERSMyA9IDB4JTA4bHhcbiIsIHNhZGRyMyk7CgoJd3JpdGVsKHNhZGRyMSwgUzNDMjQxMF9MQ0RTQUREUjEpOwoJd3JpdGVsKHNhZGRyMiwgUzNDMjQxMF9MQ0RTQUREUjIpOwoJd3JpdGVsKHNhZGRyMywgUzNDMjQxMF9MQ0RTQUREUjMpOwp9CgovKiBzM2MyNDEwZmJfY2FsY19waXhjbGsoKQogKgogKiBjYWxjdWxhdGUgZGl2aXNvciBmb3IgY2xrLT5waXhjbGsKKi8KCnN0YXRpYyB1bnNpZ25lZCBpbnQgczNjMjQxMGZiX2NhbGNfcGl4Y2xrKHN0cnVjdCBzM2MyNDEwZmJfaW5mbyAqZmJpLAoJCQkJCSAgdW5zaWduZWQgbG9uZyBwaXhjbGspCnsKCXVuc2lnbmVkIGxvbmcgY2xrID0gY2xrX2dldF9yYXRlKGZiaS0+Y2xrKTsKCXVuc2lnbmVkIGxvbmcgbG9uZyBkaXY7CgoJLyogcGl4Y2xrIGlzIGluIHBpY29zZW9uY2RzLCBvdXIgY2xvY2sgaXMgaW4gSHoKCSAqCgkgKiBIeiAtPiBwaWNvc2Vjb25kcyBpcyAvIDEwXi0xMgoJICovCgoJZGl2ID0gKHVuc2lnbmVkIGxvbmcgbG9uZyljbGsgKiBwaXhjbGs7Cglkb19kaXYoZGl2LDEwMDAwMDBVTCk7Cglkb19kaXYoZGl2LDEwMDAwMDBVTCk7CgoJZHByaW50aygicGl4Y2xrICVsZCwgZGl2aXNvciBpcyAlbGRcbiIsIHBpeGNsaywgKGxvbmcpZGl2KTsKCXJldHVybiBkaXY7Cn0KCi8qCiAqCXMzYzI0MTBmYl9jaGVja192YXIoKToKICoJR2V0IHRoZSB2aWRlbyBwYXJhbXMgb3V0IG9mICd2YXInLiBJZiBhIHZhbHVlIGRvZXNuJ3QgZml0LCByb3VuZCBpdCB1cCwKICoJaWYgaXQncyB0b28gYmlnLCByZXR1cm4gLUVJTlZBTC4KICoKICovCnN0YXRpYyBpbnQgczNjMjQxMGZiX2NoZWNrX3ZhcihzdHJ1Y3QgZmJfdmFyX3NjcmVlbmluZm8gKnZhciwKCQkJICAgICAgIHN0cnVjdCBmYl9pbmZvICppbmZvKQp7CglzdHJ1Y3QgczNjMjQxMGZiX2luZm8gKmZiaSA9IGluZm8tPnBhcjsKCglkcHJpbnRrKCJjaGVja192YXIodmFyPSVwLCBpbmZvPSVwKVxuIiwgdmFyLCBpbmZvKTsKCgkvKiB2YWxpZGF0ZSB4L3kgcmVzb2x1dGlvbiAqLwoKCWlmICh2YXItPnlyZXMgPiBmYmktPm1hY2hfaW5mby0+eXJlcy5tYXgpCgkJdmFyLT55cmVzID0gZmJpLT5tYWNoX2luZm8tPnlyZXMubWF4OwoJZWxzZSBpZiAodmFyLT55cmVzIDwgZmJpLT5tYWNoX2luZm8tPnlyZXMubWluKQoJCXZhci0+eXJlcyA9IGZiaS0+bWFjaF9pbmZvLT55cmVzLm1pbjsKCglpZiAodmFyLT54cmVzID4gZmJpLT5tYWNoX2luZm8tPnhyZXMubWF4KQoJCXZhci0+eXJlcyA9IGZiaS0+bWFjaF9pbmZvLT54cmVzLm1heDsKCWVsc2UgaWYgKHZhci0+eHJlcyA8IGZiaS0+bWFjaF9pbmZvLT54cmVzLm1pbikKCQl2YXItPnhyZXMgPSBmYmktPm1hY2hfaW5mby0+eHJlcy5taW47CgoJLyogdmFsaWRhdGUgYnBwICovCgoJaWYgKHZhci0+Yml0c19wZXJfcGl4ZWwgPiBmYmktPm1hY2hfaW5mby0+YnBwLm1heCkKCQl2YXItPmJpdHNfcGVyX3BpeGVsID0gZmJpLT5tYWNoX2luZm8tPmJwcC5tYXg7CgllbHNlIGlmICh2YXItPmJpdHNfcGVyX3BpeGVsIDwgZmJpLT5tYWNoX2luZm8tPmJwcC5taW4pCgkJdmFyLT5iaXRzX3Blcl9waXhlbCA9IGZiaS0+bWFjaF9pbmZvLT5icHAubWluOwoKCS8qIHNldCByL2cvYiBwb3NpdGlvbnMgKi8KCglpZiAodmFyLT5iaXRzX3Blcl9waXhlbCA9PSAxNikgewoJCXZhci0+cmVkLm9mZnNldAkJPSAxMTsKCQl2YXItPmdyZWVuLm9mZnNldAk9IDU7CgkJdmFyLT5ibHVlLm9mZnNldAk9IDA7CgkJdmFyLT5yZWQubGVuZ3RoCQk9IDU7CgkJdmFyLT5ncmVlbi5sZW5ndGgJPSA2OwoJCXZhci0+Ymx1ZS5sZW5ndGgJPSA1OwoJCXZhci0+dHJhbnNwLmxlbmd0aAk9IDA7Cgl9IGVsc2UgewoJCXZhci0+cmVkLmxlbmd0aAkJPSB2YXItPmJpdHNfcGVyX3BpeGVsOwoJCXZhci0+cmVkLm9mZnNldAkJPSAwOwoJCXZhci0+Z3JlZW4ubGVuZ3RoCT0gdmFyLT5iaXRzX3Blcl9waXhlbDsKCQl2YXItPmdyZWVuLm9mZnNldAk9IDA7CgkJdmFyLT5ibHVlLmxlbmd0aAk9IHZhci0+Yml0c19wZXJfcGl4ZWw7CgkJdmFyLT5ibHVlLm9mZnNldAk9IDA7CgkJdmFyLT50cmFuc3AubGVuZ3RoCT0gMDsKCX0KCglyZXR1cm4gMDsKfQoKLyogczNjMjQxMGZiX2FjdGl2YXRlX3ZhcgogKgogKiBhY3RpdmF0ZSAoc2V0KSB0aGUgY29udHJvbGxlciBmcm9tIHRoZSBnaXZlbiBmcmFtZWJ1ZmZlcgogKiBpbmZvcm1hdGlvbgoqLwoKc3RhdGljIHZvaWQgczNjMjQxMGZiX2FjdGl2YXRlX3ZhcihzdHJ1Y3QgczNjMjQxMGZiX2luZm8gKmZiaSwKCQkJCSAgIHN0cnVjdCBmYl92YXJfc2NyZWVuaW5mbyAqdmFyKQp7CglmYmktPnJlZ3MubGNkY29uMSAmPSB+UzNDMjQxMF9MQ0RDT04xX01PREVNQVNLOwoKCWRwcmludGsoIiVzOiB2YXItPnhyZXMgID0gJWRcbiIsIF9fRlVOQ1RJT05fXywgdmFyLT54cmVzKTsKCWRwcmludGsoIiVzOiB2YXItPnlyZXMgID0gJWRcbiIsIF9fRlVOQ1RJT05fXywgdmFyLT55cmVzKTsKCWRwcmludGsoIiVzOiB2YXItPmJwcCAgID0gJWRcbiIsIF9fRlVOQ1RJT05fXywgdmFyLT5iaXRzX3Blcl9waXhlbCk7CgoJc3dpdGNoICh2YXItPmJpdHNfcGVyX3BpeGVsKSB7CgljYXNlIDE6CgkJZmJpLT5yZWdzLmxjZGNvbjEgfD0gUzNDMjQxMF9MQ0RDT04xX1RGVDFCUFA7CgkJYnJlYWs7CgljYXNlIDI6CgkJZmJpLT5yZWdzLmxjZGNvbjEgfD0gUzNDMjQxMF9MQ0RDT04xX1RGVDJCUFA7CgkJYnJlYWs7CgljYXNlIDQ6CgkJZmJpLT5yZWdzLmxjZGNvbjEgfD0gUzNDMjQxMF9MQ0RDT04xX1RGVDRCUFA7CgkJYnJlYWs7CgljYXNlIDg6CgkJZmJpLT5yZWdzLmxjZGNvbjEgfD0gUzNDMjQxMF9MQ0RDT04xX1RGVDhCUFA7CgkJYnJlYWs7CgljYXNlIDE2OgoJCWZiaS0+cmVncy5sY2Rjb24xIHw9IFMzQzI0MTBfTENEQ09OMV9URlQxNkJQUDsKCQlicmVhazsKCX0KCgkvKiBjaGVjayB0byBzZWUgaWYgd2UgbmVlZCB0byB1cGRhdGUgc3luYy9ib3JkZXJzICovCgoJaWYgKCFmYmktPm1hY2hfaW5mby0+Zml4ZWRfc3luY3MpIHsKCQlkcHJpbnRrKCJzZXR0aW5nIHZlcnQ6IHVwPSVkLCBsb3c9JWQsIHN5bmM9JWRcbiIsCgkJCXZhci0+dXBwZXJfbWFyZ2luLCB2YXItPmxvd2VyX21hcmdpbiwKCQkJdmFyLT52c3luY19sZW4pOwoKCQlkcHJpbnRrKCJzZXR0aW5nIGhvcno6IGxmdD0lZCwgcnQ9JWQsIHN5bmM9JWRcbiIsCgkJCXZhci0+bGVmdF9tYXJnaW4sIHZhci0+cmlnaHRfbWFyZ2luLAoJCQl2YXItPmhzeW5jX2xlbik7CgoJCWZiaS0+cmVncy5sY2Rjb24yID0KCQkJUzNDMjQxMF9MQ0RDT04yX1ZCUEQodmFyLT51cHBlcl9tYXJnaW4gLSAxKSB8CgkJCVMzQzI0MTBfTENEQ09OMl9WRlBEKHZhci0+bG93ZXJfbWFyZ2luIC0gMSkgfAoJCQlTM0MyNDEwX0xDRENPTjJfVlNQVyh2YXItPnZzeW5jX2xlbiAtIDEpOwoKCQlmYmktPnJlZ3MubGNkY29uMyA9CgkJCVMzQzI0MTBfTENEQ09OM19IQlBEKHZhci0+cmlnaHRfbWFyZ2luIC0gMSkgfAoJCQlTM0MyNDEwX0xDRENPTjNfSEZQRCh2YXItPmxlZnRfbWFyZ2luIC0gMSk7CgoJCWZiaS0+cmVncy5sY2Rjb240ICY9IH5TM0MyNDEwX0xDRENPTjRfSFNQVygweGZmKTsKCQlmYmktPnJlZ3MubGNkY29uNCB8PSAgUzNDMjQxMF9MQ0RDT040X0hTUFcodmFyLT5oc3luY19sZW4gLSAxKTsKCX0KCgkvKiB1cGRhdGUgWC9ZIGluZm8gKi8KCglmYmktPnJlZ3MubGNkY29uMiAmPSB+UzNDMjQxMF9MQ0RDT04yX0xJTkVWQUwoMHgzZmYpOwoJZmJpLT5yZWdzLmxjZGNvbjIgfD0gIFMzQzI0MTBfTENEQ09OMl9MSU5FVkFMKHZhci0+eXJlcyAtIDEpOwoKCWZiaS0+cmVncy5sY2Rjb24zICY9IH5TM0MyNDEwX0xDRENPTjNfSE9aVkFMKDB4N2ZmKTsKCWZiaS0+cmVncy5sY2Rjb24zIHw9ICBTM0MyNDEwX0xDRENPTjNfSE9aVkFMKHZhci0+eHJlcyAtIDEpOwoKCWlmICh2YXItPnBpeGNsb2NrID4gMCkgewoJCWludCBjbGtkaXYgPSBzM2MyNDEwZmJfY2FsY19waXhjbGsoZmJpLCB2YXItPnBpeGNsb2NrKTsKCgkJY2xrZGl2ID0gKGNsa2RpdiAvIDIpIC0xOwoJCWlmIChjbGtkaXYgPCAwKQoJCQljbGtkaXYgPSAwOwoKCQlmYmktPnJlZ3MubGNkY29uMSAmPSB+UzNDMjQxMF9MQ0RDT04xX0NMS1ZBTCgweDNmZik7CgkJZmJpLT5yZWdzLmxjZGNvbjEgfD0gIFMzQzI0MTBfTENEQ09OMV9DTEtWQUwoY2xrZGl2KTsKCX0KCgkvKiB3cml0ZSBuZXcgcmVnaXN0ZXJzICovCgoJZHByaW50aygibmV3IHJlZ2lzdGVyIHNldDpcbiIpOwoJZHByaW50aygibGNkY29uWzFdID0gMHglMDhseFxuIiwgZmJpLT5yZWdzLmxjZGNvbjEpOwoJZHByaW50aygibGNkY29uWzJdID0gMHglMDhseFxuIiwgZmJpLT5yZWdzLmxjZGNvbjIpOwoJZHByaW50aygibGNkY29uWzNdID0gMHglMDhseFxuIiwgZmJpLT5yZWdzLmxjZGNvbjMpOwoJZHByaW50aygibGNkY29uWzRdID0gMHglMDhseFxuIiwgZmJpLT5yZWdzLmxjZGNvbjQpOwoJZHByaW50aygibGNkY29uWzVdID0gMHglMDhseFxuIiwgZmJpLT5yZWdzLmxjZGNvbjUpOwoKCXdyaXRlbChmYmktPnJlZ3MubGNkY29uMSAmIH5TM0MyNDEwX0xDRENPTjFfRU5WSUQsIFMzQzI0MTBfTENEQ09OMSk7Cgl3cml0ZWwoZmJpLT5yZWdzLmxjZGNvbjIsIFMzQzI0MTBfTENEQ09OMik7Cgl3cml0ZWwoZmJpLT5yZWdzLmxjZGNvbjMsIFMzQzI0MTBfTENEQ09OMyk7Cgl3cml0ZWwoZmJpLT5yZWdzLmxjZGNvbjQsIFMzQzI0MTBfTENEQ09ONCk7Cgl3cml0ZWwoZmJpLT5yZWdzLmxjZGNvbjUsIFMzQzI0MTBfTENEQ09ONSk7CgoJLyogc2V0IGxjZCBhZGRyZXNzIHBvaW50ZXJzICovCglzM2MyNDEwZmJfc2V0X2xjZGFkZHIoZmJpKTsKCgl3cml0ZWwoZmJpLT5yZWdzLmxjZGNvbjEsIFMzQzI0MTBfTENEQ09OMSk7Cn0KCgovKgogKiAgICAgIHMzYzI0MTBmYl9zZXRfcGFyIC0gT3B0aW9uYWwgZnVuY3Rpb24uIEFsdGVycyB0aGUgaGFyZHdhcmUgc3RhdGUuCiAqICAgICAgQGluZm86IGZyYW1lIGJ1ZmZlciBzdHJ1Y3R1cmUgdGhhdCByZXByZXNlbnRzIGEgc2luZ2xlIGZyYW1lIGJ1ZmZlcgogKgogKi8Kc3RhdGljIGludCBzM2MyNDEwZmJfc2V0X3BhcihzdHJ1Y3QgZmJfaW5mbyAqaW5mbykKewoJc3RydWN0IHMzYzI0MTBmYl9pbmZvICpmYmkgPSBpbmZvLT5wYXI7CglzdHJ1Y3QgZmJfdmFyX3NjcmVlbmluZm8gKnZhciA9ICZpbmZvLT52YXI7CgoJaWYgKHZhci0+Yml0c19wZXJfcGl4ZWwgPT0gMTYpCgkJZmJpLT5mYi0+Zml4LnZpc3VhbCA9IEZCX1ZJU1VBTF9UUlVFQ09MT1I7CgllbHNlCgkJZmJpLT5mYi0+Zml4LnZpc3VhbCA9IEZCX1ZJU1VBTF9QU0VVRE9DT0xPUjsKCglmYmktPmZiLT5maXgubGluZV9sZW5ndGggICAgID0gKHZhci0+d2lkdGgqdmFyLT5iaXRzX3Blcl9waXhlbCkvODsKCgkvKiBhY3RpdmF0ZSB0aGlzIG5ldyBjb25maWd1cmF0aW9uICovCgoJczNjMjQxMGZiX2FjdGl2YXRlX3ZhcihmYmksIHZhcik7CglyZXR1cm4gMDsKfQoKc3RhdGljIHZvaWQgc2NoZWR1bGVfcGFsZXR0ZV91cGRhdGUoc3RydWN0IHMzYzI0MTBmYl9pbmZvICpmYmksCgkJCQkgICAgdW5zaWduZWQgaW50IHJlZ25vLCB1bnNpZ25lZCBpbnQgdmFsKQp7Cgl1bnNpZ25lZCBsb25nIGZsYWdzOwoJdW5zaWduZWQgbG9uZyBpcnFlbjsKCglsb2NhbF9pcnFfc2F2ZShmbGFncyk7CgoJZmJpLT5wYWxldHRlX2J1ZmZlcltyZWdub10gPSB2YWw7CgoJaWYgKCFmYmktPnBhbGV0dGVfcmVhZHkpIHsKCQlmYmktPnBhbGV0dGVfcmVhZHkgPSAxOwoKCQkvKiBlbmFibGUgSVJRICovCgkJaXJxZW4gPSByZWFkbChTM0MyNDEwX0xDRElOVE1TSyk7CgkJaXJxZW4gJj0gflMzQzI0MTBfTENESU5UX0ZSU1lOQzsKCQl3cml0ZWwoaXJxZW4sIFMzQzI0MTBfTENESU5UTVNLKTsKCX0KCglsb2NhbF9pcnFfcmVzdG9yZShmbGFncyk7Cn0KCi8qIGZyb20gcHhhZmIuYyAqLwpzdGF0aWMgaW5saW5lIHVuc2lnbmVkIGludCBjaGFuX3RvX2ZpZWxkKHVuc2lnbmVkIGludCBjaGFuLCBzdHJ1Y3QgZmJfYml0ZmllbGQgKmJmKQp7CgljaGFuICY9IDB4ZmZmZjsKCWNoYW4gPj49IDE2IC0gYmYtPmxlbmd0aDsKCXJldHVybiBjaGFuIDw8IGJmLT5vZmZzZXQ7Cn0KCnN0YXRpYyBpbnQgczNjMjQxMGZiX3NldGNvbHJlZyh1bnNpZ25lZCByZWdubywKCQkJICAgICAgIHVuc2lnbmVkIHJlZCwgdW5zaWduZWQgZ3JlZW4sIHVuc2lnbmVkIGJsdWUsCgkJCSAgICAgICB1bnNpZ25lZCB0cmFuc3AsIHN0cnVjdCBmYl9pbmZvICppbmZvKQp7CglzdHJ1Y3QgczNjMjQxMGZiX2luZm8gKmZiaSA9IGluZm8tPnBhcjsKCXVuc2lnbmVkIGludCB2YWw7CgoJLyogZHByaW50aygic2V0Y29sOiByZWdubz0lZCwgcmdiPSVkLCVkLCVkXG4iLCByZWdubywgcmVkLCBncmVlbiwgYmx1ZSk7ICovCgoJc3dpdGNoIChmYmktPmZiLT5maXgudmlzdWFsKSB7CgljYXNlIEZCX1ZJU1VBTF9UUlVFQ09MT1I6CgkJLyogdHJ1ZS1jb2xvdXIsIHVzZSBwc2V1by1wYWxldHRlICovCgoJCWlmIChyZWdubyA8IDE2KSB7CgkJCXUzMiAqcGFsID0gZmJpLT5mYi0+cHNldWRvX3BhbGV0dGU7CgoJCQl2YWwgID0gY2hhbl90b19maWVsZChyZWQsICAgJmZiaS0+ZmItPnZhci5yZWQpOwoJCQl2YWwgfD0gY2hhbl90b19maWVsZChncmVlbiwgJmZiaS0+ZmItPnZhci5ncmVlbik7CgkJCXZhbCB8PSBjaGFuX3RvX2ZpZWxkKGJsdWUsICAmZmJpLT5mYi0+dmFyLmJsdWUpOwoKCQkJcGFsW3JlZ25vXSA9IHZhbDsKCQl9CgkJYnJlYWs7CgoJY2FzZSBGQl9WSVNVQUxfUFNFVURPQ09MT1I6CgkJaWYgKHJlZ25vIDwgMjU2KSB7CgkJCS8qIGN1cnJlbnRseSBhc3N1bWUgUkdCIDUtNi01IG1vZGUgKi8KCgkJCXZhbCAgPSAoKHJlZCAgID4+ICAwKSAmIDB4ZjgwMCk7CgkJCXZhbCB8PSAoKGdyZWVuID4+ICA1KSAmIDB4MDdlMCk7CgkJCXZhbCB8PSAoKGJsdWUgID4+IDExKSAmIDB4MDAxZik7CgoJCQl3cml0ZWwodmFsLCBTM0MyNDEwX1RGVFBBTChyZWdubykpOwoJCQlzY2hlZHVsZV9wYWxldHRlX3VwZGF0ZShmYmksIHJlZ25vLCB2YWwpOwoJCX0KCgkJYnJlYWs7CgoJZGVmYXVsdDoKCQlyZXR1cm4gMTsgICAvKiB1bmtub3duIHR5cGUgKi8KCX0KCglyZXR1cm4gMDsKfQoKCi8qKgogKiAgICAgIHMzYzI0MTBmYl9ibGFuawogKglAYmxhbmtfbW9kZTogdGhlIGJsYW5rIG1vZGUgd2Ugd2FudC4KICoJQGluZm86IGZyYW1lIGJ1ZmZlciBzdHJ1Y3R1cmUgdGhhdCByZXByZXNlbnRzIGEgc2luZ2xlIGZyYW1lIGJ1ZmZlcgogKgogKglCbGFuayB0aGUgc2NyZWVuIGlmIGJsYW5rX21vZGUgIT0gMCwgZWxzZSB1bmJsYW5rLiBSZXR1cm4gMCBpZgogKglibGFua2luZyBzdWNjZWVkZWQsICE9IDAgaWYgdW4tL2JsYW5raW5nIGZhaWxlZCBkdWUgdG8gZS5nLiBhCiAqCXZpZGVvIG1vZGUgd2hpY2ggZG9lc24ndCBzdXBwb3J0IGl0LiBJbXBsZW1lbnRzIFZFU0Egc3VzcGVuZAogKglhbmQgcG93ZXJkb3duIG1vZGVzIG9uIGhhcmR3YXJlIHRoYXQgc3VwcG9ydHMgZGlzYWJsaW5nIGhzeW5jL3ZzeW5jOgogKglibGFua19tb2RlID09IDI6IHN1c3BlbmQgdnN5bmMKICoJYmxhbmtfbW9kZSA9PSAzOiBzdXNwZW5kIGhzeW5jCiAqCWJsYW5rX21vZGUgPT0gNDogcG93ZXJkb3duCiAqCiAqCVJldHVybnMgbmVnYXRpdmUgZXJybm8gb24gZXJyb3IsIG9yIHplcm8gb24gc3VjY2Vzcy4KICoKICovCnN0YXRpYyBpbnQgczNjMjQxMGZiX2JsYW5rKGludCBibGFua19tb2RlLCBzdHJ1Y3QgZmJfaW5mbyAqaW5mbykKewoJZHByaW50aygiYmxhbmsobW9kZT0lZCwgaW5mbz0lcClcbiIsIGJsYW5rX21vZGUsIGluZm8pOwoKCWlmIChtYWNoX2luZm8gPT0gTlVMTCkKCQlyZXR1cm4gLUVJTlZBTDsKCglpZiAoYmxhbmtfbW9kZSA9PSBGQl9CTEFOS19VTkJMQU5LKQoJCXdyaXRlbCgweDAsIFMzQzI0MTBfVFBBTCk7CgllbHNlIHsKCQlkcHJpbnRrKCJzZXR0aW5nIFRQQUwgdG8gb3V0cHV0IDB4MDAwMDAwXG4iKTsKCQl3cml0ZWwoUzNDMjQxMF9UUEFMX0VOLCBTM0MyNDEwX1RQQUwpOwoJfQoKCXJldHVybiAwOwp9CgpzdGF0aWMgaW50IHMzYzI0MTBmYl9kZWJ1Z19zaG93KHN0cnVjdCBkZXZpY2UgKmRldiwgc3RydWN0IGRldmljZV9hdHRyaWJ1dGUgKmF0dHIsIGNoYXIgKmJ1ZikKewoJcmV0dXJuIHNucHJpbnRmKGJ1ZiwgUEFHRV9TSVpFLCAiJXNcbiIsIGRlYnVnID8gIm9uIiA6ICJvZmYiKTsKfQpzdGF0aWMgaW50IHMzYzI0MTBmYl9kZWJ1Z19zdG9yZShzdHJ1Y3QgZGV2aWNlICpkZXYsIHN0cnVjdCBkZXZpY2VfYXR0cmlidXRlICphdHRyLAoJCQkJCSAgIGNvbnN0IGNoYXIgKmJ1Ziwgc2l6ZV90IGxlbikKewoJaWYgKG1hY2hfaW5mbyA9PSBOVUxMKQoJCXJldHVybiAtRUlOVkFMOwoKCWlmIChsZW4gPCAxKQoJCXJldHVybiAtRUlOVkFMOwoKCWlmIChzdHJuaWNtcChidWYsICJvbiIsIDIpID09IDAgfHwKCSAgICBzdHJuaWNtcChidWYsICIxIiwgMSkgPT0gMCkgewoJCWRlYnVnID0gMTsKCQlwcmludGsoS0VSTl9ERUJVRyAiczNjMjQxMGZiOiBEZWJ1ZyBPbiIpOwoJfSBlbHNlIGlmIChzdHJuaWNtcChidWYsICJvZmYiLCAzKSA9PSAwIHx8CgkJICAgc3RybmljbXAoYnVmLCAiMCIsIDEpID09IDApIHsKCQlkZWJ1ZyA9IDA7CgkJcHJpbnRrKEtFUk5fREVCVUcgInMzYzI0MTBmYjogRGVidWcgT2ZmIik7Cgl9IGVsc2UgewoJCXJldHVybiAtRUlOVkFMOwoJfQoKCXJldHVybiBsZW47Cn0KCgpzdGF0aWMgREVWSUNFX0FUVFIoZGVidWcsIDA2NjYsCgkJICAgczNjMjQxMGZiX2RlYnVnX3Nob3csCgkJICAgczNjMjQxMGZiX2RlYnVnX3N0b3JlKTsKCnN0YXRpYyBzdHJ1Y3QgZmJfb3BzIHMzYzI0MTBmYl9vcHMgPSB7Cgkub3duZXIJCT0gVEhJU19NT0RVTEUsCgkuZmJfY2hlY2tfdmFyCT0gczNjMjQxMGZiX2NoZWNrX3ZhciwKCS5mYl9zZXRfcGFyCT0gczNjMjQxMGZiX3NldF9wYXIsCgkuZmJfYmxhbmsJPSBzM2MyNDEwZmJfYmxhbmssCgkuZmJfc2V0Y29scmVnCT0gczNjMjQxMGZiX3NldGNvbHJlZywKCS5mYl9maWxscmVjdAk9IGNmYl9maWxscmVjdCwKCS5mYl9jb3B5YXJlYQk9IGNmYl9jb3B5YXJlYSwKCS5mYl9pbWFnZWJsaXQJPSBjZmJfaW1hZ2VibGl0LAp9OwoKCi8qCiAqIHMzYzI0MTBmYl9tYXBfdmlkZW9fbWVtb3J5KCk6CiAqCUFsbG9jYXRlcyB0aGUgRFJBTSBtZW1vcnkgZm9yIHRoZSBmcmFtZSBidWZmZXIuICBUaGlzIGJ1ZmZlciBpcwogKglyZW1hcHBlZCBpbnRvIGEgbm9uLWNhY2hlZCwgbm9uLWJ1ZmZlcmVkLCBtZW1vcnkgcmVnaW9uIHRvCiAqCWFsbG93IHBhbGV0dGUgYW5kIHBpeGVsIHdyaXRlcyB0byBvY2N1ciB3aXRob3V0IGZsdXNoaW5nIHRoZQogKgljYWNoZS4gIE9uY2UgdGhpcyBhcmVhIGlzIHJlbWFwcGVkLCBhbGwgdmlydHVhbCBtZW1vcnkKICoJYWNjZXNzIHRvIHRoZSB2aWRlbyBtZW1vcnkgc2hvdWxkIG9jY3VyIGF0IHRoZSBuZXcgcmVnaW9uLgogKi8Kc3RhdGljIGludCBfX2luaXQgczNjMjQxMGZiX21hcF92aWRlb19tZW1vcnkoc3RydWN0IHMzYzI0MTBmYl9pbmZvICpmYmkpCnsKCWRwcmludGsoIm1hcF92aWRlb19tZW1vcnkoZmJpPSVwKVxuIiwgZmJpKTsKCglmYmktPm1hcF9zaXplID0gUEFHRV9BTElHTihmYmktPmZiLT5maXguc21lbV9sZW4gKyBQQUdFX1NJWkUpOwoJZmJpLT5tYXBfY3B1ICA9IGRtYV9hbGxvY193cml0ZWNvbWJpbmUoZmJpLT5kZXYsIGZiaS0+bWFwX3NpemUsCgkJCQkJICAgICAgICZmYmktPm1hcF9kbWEsIEdGUF9LRVJORUwpOwoKCWZiaS0+bWFwX3NpemUgPSBmYmktPmZiLT5maXguc21lbV9sZW47CgoJaWYgKGZiaS0+bWFwX2NwdSkgewoJCS8qIHByZXZlbnQgaW5pdGlhbCBnYXJiYWdlIG9uIHNjcmVlbiAqLwoJCWRwcmludGsoIm1hcF92aWRlb19tZW1vcnk6IGNsZWFyICVwOiUwOHhcbiIsCgkJCWZiaS0+bWFwX2NwdSwgZmJpLT5tYXBfc2l6ZSk7CgkJbWVtc2V0KGZiaS0+bWFwX2NwdSwgMHhmMCwgZmJpLT5tYXBfc2l6ZSk7CgoJCWZiaS0+c2NyZWVuX2RtYQkJPSBmYmktPm1hcF9kbWE7CgkJZmJpLT5mYi0+c2NyZWVuX2Jhc2UJPSBmYmktPm1hcF9jcHU7CgkJZmJpLT5mYi0+Zml4LnNtZW1fc3RhcnQgID0gZmJpLT5zY3JlZW5fZG1hOwoKCQlkcHJpbnRrKCJtYXBfdmlkZW9fbWVtb3J5OiBkbWE9JTA4eCBjcHU9JXAgc2l6ZT0lMDh4XG4iLAoJCQlmYmktPm1hcF9kbWEsIGZiaS0+bWFwX2NwdSwgZmJpLT5mYi0+Zml4LnNtZW1fbGVuKTsKCX0KCglyZXR1cm4gZmJpLT5tYXBfY3B1ID8gMCA6IC1FTk9NRU07Cn0KCnN0YXRpYyBpbmxpbmUgdm9pZCBzM2MyNDEwZmJfdW5tYXBfdmlkZW9fbWVtb3J5KHN0cnVjdCBzM2MyNDEwZmJfaW5mbyAqZmJpKQp7CglkbWFfZnJlZV93cml0ZWNvbWJpbmUoZmJpLT5kZXYsZmJpLT5tYXBfc2l6ZSxmYmktPm1hcF9jcHUsIGZiaS0+bWFwX2RtYSk7Cn0KCnN0YXRpYyBpbmxpbmUgdm9pZCBtb2RpZnlfZ3Bpbyh2b2lkIF9faW9tZW0gKnJlZywKCQkJICAgICAgIHVuc2lnbmVkIGxvbmcgc2V0LCB1bnNpZ25lZCBsb25nIG1hc2spCnsKCXVuc2lnbmVkIGxvbmcgdG1wOwoKCXRtcCA9IHJlYWRsKHJlZykgJiB+bWFzazsKCXdyaXRlbCh0bXAgfCBzZXQsIHJlZyk7Cn0KCgovKgogKiBzM2MyNDEwZmJfaW5pdF9yZWdpc3RlcnMgLSBJbml0aWFsaXNlIGFsbCBMQ0QtcmVsYXRlZCByZWdpc3RlcnMKICovCgppbnQgczNjMjQxMGZiX2luaXRfcmVnaXN0ZXJzKHN0cnVjdCBzM2MyNDEwZmJfaW5mbyAqZmJpKQp7Cgl1bnNpZ25lZCBsb25nIGZsYWdzOwoKCS8qIEluaXRpYWxpc2UgTENEIHdpdGggdmFsdWVzIGZyb20gaGFyZXQgKi8KCglsb2NhbF9pcnFfc2F2ZShmbGFncyk7CgoJLyogbW9kaWZ5IHRoZSBncGlvKHMpIHdpdGggaW50ZXJydXB0cyBzZXQgKGJqZCkgKi8KCgltb2RpZnlfZ3BpbyhTM0MyNDEwX0dQQ1VQLCAgbWFjaF9pbmZvLT5ncGN1cCwgIG1hY2hfaW5mby0+Z3BjdXBfbWFzayk7Cgltb2RpZnlfZ3BpbyhTM0MyNDEwX0dQQ0NPTiwgbWFjaF9pbmZvLT5ncGNjb24sIG1hY2hfaW5mby0+Z3BjY29uX21hc2spOwoJbW9kaWZ5X2dwaW8oUzNDMjQxMF9HUERVUCwgIG1hY2hfaW5mby0+Z3BkdXAsICBtYWNoX2luZm8tPmdwZHVwX21hc2spOwoJbW9kaWZ5X2dwaW8oUzNDMjQxMF9HUERDT04sIG1hY2hfaW5mby0+Z3BkY29uLCBtYWNoX2luZm8tPmdwZGNvbl9tYXNrKTsKCglsb2NhbF9pcnFfcmVzdG9yZShmbGFncyk7CgoJd3JpdGVsKGZiaS0+cmVncy5sY2Rjb24xLCBTM0MyNDEwX0xDRENPTjEpOwoJd3JpdGVsKGZiaS0+cmVncy5sY2Rjb24yLCBTM0MyNDEwX0xDRENPTjIpOwoJd3JpdGVsKGZiaS0+cmVncy5sY2Rjb24zLCBTM0MyNDEwX0xDRENPTjMpOwoJd3JpdGVsKGZiaS0+cmVncy5sY2Rjb240LCBTM0MyNDEwX0xDRENPTjQpOwoJd3JpdGVsKGZiaS0+cmVncy5sY2Rjb241LCBTM0MyNDEwX0xDRENPTjUpOwoKIAlzM2MyNDEwZmJfc2V0X2xjZGFkZHIoZmJpKTsKCglkcHJpbnRrKCJMUENTRUwgICAgPSAweCUwOGx4XG4iLCBtYWNoX2luZm8tPmxwY3NlbCk7Cgl3cml0ZWwobWFjaF9pbmZvLT5scGNzZWwsIFMzQzI0MTBfTFBDU0VMKTsKCglkcHJpbnRrKCJyZXBsYWNpbmcgVFBBTCAlMDh4XG4iLCByZWFkbChTM0MyNDEwX1RQQUwpKTsKCgkvKiBlbnN1cmUgdGVtcG9yYXJ5IHBhbGV0dGUgZGlzYWJsZWQgKi8KCXdyaXRlbCgweDAwLCBTM0MyNDEwX1RQQUwpOwoKCS8qIEVuYWJsZSB2aWRlbyBieSBzZXR0aW5nIHRoZSBFTlZJRCBiaXQgdG8gMSAqLwoJZmJpLT5yZWdzLmxjZGNvbjEgfD0gUzNDMjQxMF9MQ0RDT04xX0VOVklEOwoJd3JpdGVsKGZiaS0+cmVncy5sY2Rjb24xLCBTM0MyNDEwX0xDRENPTjEpOwoJcmV0dXJuIDA7Cn0KCnN0YXRpYyB2b2lkIHMzYzI0MTBmYl93cml0ZV9wYWxldHRlKHN0cnVjdCBzM2MyNDEwZmJfaW5mbyAqZmJpKQp7Cgl1bnNpZ25lZCBpbnQgaTsKCXVuc2lnbmVkIGxvbmcgZW50OwoKCWZiaS0+cGFsZXR0ZV9yZWFkeSA9IDA7CgoJZm9yIChpID0gMDsgaSA8IDI1NjsgaSsrKSB7CgkJaWYgKChlbnQgPSBmYmktPnBhbGV0dGVfYnVmZmVyW2ldKSA9PSBQQUxFVFRFX0JVRkZfQ0xFQVIpCgkJCWNvbnRpbnVlOwoKCQl3cml0ZWwoZW50LCBTM0MyNDEwX1RGVFBBTChpKSk7CgoJCS8qIGl0IHNlZW1zIHRoZSBvbmx5IHdheSB0byBrbm93IGV4YWN0bHkKCQkgKiBpZiB0aGUgcGFsZXR0ZSB3cm90ZSBvaywgaXMgdG8gY2hlY2sKCQkgKiB0byBzZWUgaWYgdGhlIHZhbHVlIHZlcmlmaWVzIG9rCgkJICovCgoJCWlmIChyZWFkdyhTM0MyNDEwX1RGVFBBTChpKSkgPT0gZW50KQoJCQlmYmktPnBhbGV0dGVfYnVmZmVyW2ldID0gUEFMRVRURV9CVUZGX0NMRUFSOwoJCWVsc2UKCQkJZmJpLT5wYWxldHRlX3JlYWR5ID0gMTsgICAvKiByZXRyeSAqLwoJfQp9CgpzdGF0aWMgaXJxcmV0dXJuX3QgczNjMjQxMGZiX2lycShpbnQgaXJxLCB2b2lkICpkZXZfaWQsIHN0cnVjdCBwdF9yZWdzICpyKQp7CglzdHJ1Y3QgczNjMjQxMGZiX2luZm8gKmZiaSA9IGRldl9pZDsKCXVuc2lnbmVkIGxvbmcgbGNkaXJxID0gcmVhZGwoUzNDMjQxMF9MQ0RJTlRQTkQpOwoKCWlmIChsY2RpcnEgJiBTM0MyNDEwX0xDRElOVF9GUlNZTkMpIHsKCQlpZiAoZmJpLT5wYWxldHRlX3JlYWR5KQoJCQlzM2MyNDEwZmJfd3JpdGVfcGFsZXR0ZShmYmkpOwoKCQl3cml0ZWwoUzNDMjQxMF9MQ0RJTlRfRlJTWU5DLCBTM0MyNDEwX0xDRElOVFBORCk7CgkJd3JpdGVsKFMzQzI0MTBfTENESU5UX0ZSU1lOQywgUzNDMjQxMF9MQ0RTUkNQTkQpOwoJfQoKCXJldHVybiBJUlFfSEFORExFRDsKfQoKc3RhdGljIGNoYXIgZHJpdmVyX25hbWVbXT0iczNjMjQxMGZiIjsKCmludCBfX2luaXQgczNjMjQxMGZiX3Byb2JlKHN0cnVjdCBwbGF0Zm9ybV9kZXZpY2UgKnBkZXYpCnsKCXN0cnVjdCBzM2MyNDEwZmJfaW5mbyAqaW5mbzsKCXN0cnVjdCBmYl9pbmZvCSAgICpmYmluZm87CglzdHJ1Y3QgczNjMjQxMGZiX2h3ICptcmVnczsKCWludCByZXQ7CglpbnQgaXJxOwoJaW50IGk7CgoJbWFjaF9pbmZvID0gcGRldi0+ZGV2LnBsYXRmb3JtX2RhdGE7CglpZiAobWFjaF9pbmZvID09IE5VTEwpIHsKCQlkZXZfZXJyKCZwZGV2LT5kZXYsIm5vIHBsYXRmb3JtIGRhdGEgZm9yIGxjZCwgY2Fubm90IGF0dGFjaFxuIik7CgkJcmV0dXJuIC1FSU5WQUw7Cgl9CgoJbXJlZ3MgPSAmbWFjaF9pbmZvLT5yZWdzOwoKCWlycSA9IHBsYXRmb3JtX2dldF9pcnEocGRldiwgMCk7CglpZiAoaXJxIDwgMCkgewoJCWRldl9lcnIoJnBkZXYtPmRldiwgIm5vIGlycSBmb3IgZGV2aWNlXG4iKTsKCQlyZXR1cm4gLUVOT0VOVDsKCX0KCglmYmluZm8gPSBmcmFtZWJ1ZmZlcl9hbGxvYyhzaXplb2Yoc3RydWN0IHMzYzI0MTBmYl9pbmZvKSwgJnBkZXYtPmRldik7CglpZiAoIWZiaW5mbykgewoJCXJldHVybiAtRU5PTUVNOwoJfQoKCglpbmZvID0gZmJpbmZvLT5wYXI7CglpbmZvLT5mYiA9IGZiaW5mbzsKCXBsYXRmb3JtX3NldF9kcnZkYXRhKHBkZXYsIGZiaW5mbyk7CgoJczNjMjQxMGZiX2luaXRfcmVnaXN0ZXJzKGluZm8pOwoKCWRwcmludGsoImRldmluaXRcbiIpOwoKCXN0cmNweShmYmluZm8tPmZpeC5pZCwgZHJpdmVyX25hbWUpOwoKCW1lbWNweSgmaW5mby0+cmVncywgJm1hY2hfaW5mby0+cmVncywgc2l6ZW9mKGluZm8tPnJlZ3MpKTsKCglpbmZvLT5tYWNoX2luZm8JCSAgICA9IHBkZXYtPmRldi5wbGF0Zm9ybV9kYXRhOwoKCWZiaW5mby0+Zml4LnR5cGUJICAgID0gRkJfVFlQRV9QQUNLRURfUElYRUxTOwoJZmJpbmZvLT5maXgudHlwZV9hdXgJICAgID0gMDsKCWZiaW5mby0+Zml4LnhwYW5zdGVwCSAgICA9IDA7CglmYmluZm8tPmZpeC55cGFuc3RlcAkgICAgPSAwOwoJZmJpbmZvLT5maXgueXdyYXBzdGVwCSAgICA9IDA7CglmYmluZm8tPmZpeC5hY2NlbAkgICAgPSBGQl9BQ0NFTF9OT05FOwoKCWZiaW5mby0+dmFyLm5vbnN0ZAkgICAgPSAwOwoJZmJpbmZvLT52YXIuYWN0aXZhdGUJICAgID0gRkJfQUNUSVZBVEVfTk9XOwoJZmJpbmZvLT52YXIuaGVpZ2h0CSAgICA9IG1hY2hfaW5mby0+aGVpZ2h0OwoJZmJpbmZvLT52YXIud2lkdGgJICAgID0gbWFjaF9pbmZvLT53aWR0aDsKCWZiaW5mby0+dmFyLmFjY2VsX2ZsYWdzICAgICA9IDA7CglmYmluZm8tPnZhci52bW9kZQkgICAgPSBGQl9WTU9ERV9OT05JTlRFUkxBQ0VEOwoKCWZiaW5mby0+ZmJvcHMJCSAgICA9ICZzM2MyNDEwZmJfb3BzOwoJZmJpbmZvLT5mbGFncwkJICAgID0gRkJJTkZPX0ZMQUdfREVGQVVMVDsKCWZiaW5mby0+cHNldWRvX3BhbGV0dGUgICAgICA9ICZpbmZvLT5wc2V1ZG9fcGFsOwoKCWZiaW5mby0+dmFyLnhyZXMJICAgID0gbWFjaF9pbmZvLT54cmVzLmRlZnZhbDsKCWZiaW5mby0+dmFyLnhyZXNfdmlydHVhbCAgICA9IG1hY2hfaW5mby0+eHJlcy5kZWZ2YWw7CglmYmluZm8tPnZhci55cmVzCSAgICA9IG1hY2hfaW5mby0+eXJlcy5kZWZ2YWw7CglmYmluZm8tPnZhci55cmVzX3ZpcnR1YWwgICAgPSBtYWNoX2luZm8tPnlyZXMuZGVmdmFsOwoJZmJpbmZvLT52YXIuYml0c19wZXJfcGl4ZWwgID0gbWFjaF9pbmZvLT5icHAuZGVmdmFsOwoKCWZiaW5mby0+dmFyLnVwcGVyX21hcmdpbiAgICA9IFMzQzI0MTBfTENEQ09OMl9HRVRfVkJQRChtcmVncy0+bGNkY29uMikgKzE7CglmYmluZm8tPnZhci5sb3dlcl9tYXJnaW4gICAgPSBTM0MyNDEwX0xDRENPTjJfR0VUX1ZGUEQobXJlZ3MtPmxjZGNvbjIpICsxOwoJZmJpbmZvLT52YXIudnN5bmNfbGVuCSAgICA9IFMzQzI0MTBfTENEQ09OMl9HRVRfVlNQVyhtcmVncy0+bGNkY29uMikgKyAxOwoKCWZiaW5mby0+dmFyLmxlZnRfbWFyZ2luCSAgICA9IFMzQzI0MTBfTENEQ09OM19HRVRfSEZQRChtcmVncy0+bGNkY29uMykgKyAxOwoJZmJpbmZvLT52YXIucmlnaHRfbWFyZ2luICAgID0gUzNDMjQxMF9MQ0RDT04zX0dFVF9IQlBEKG1yZWdzLT5sY2Rjb24zKSArIDE7CglmYmluZm8tPnZhci5oc3luY19sZW4JICAgID0gUzNDMjQxMF9MQ0RDT040X0dFVF9IU1BXKG1yZWdzLT5sY2Rjb240KSArIDE7CgoJZmJpbmZvLT52YXIucmVkLm9mZnNldCAgICAgID0gMTE7CglmYmluZm8tPnZhci5ncmVlbi5vZmZzZXQgICAgPSA1OwoJZmJpbmZvLT52YXIuYmx1ZS5vZmZzZXQgICAgID0gMDsKCWZiaW5mby0+dmFyLnRyYW5zcC5vZmZzZXQgICA9IDA7CglmYmluZm8tPnZhci5yZWQubGVuZ3RoICAgICAgPSA1OwoJZmJpbmZvLT52YXIuZ3JlZW4ubGVuZ3RoICAgID0gNjsKCWZiaW5mby0+dmFyLmJsdWUubGVuZ3RoICAgICA9IDU7CglmYmluZm8tPnZhci50cmFuc3AubGVuZ3RoICAgPSAwOwoJZmJpbmZvLT5maXguc21lbV9sZW4gICAgICAgID0JbWFjaF9pbmZvLT54cmVzLm1heCAqCgkJCQkJbWFjaF9pbmZvLT55cmVzLm1heCAqCgkJCQkJbWFjaF9pbmZvLT5icHAubWF4IC8gODsKCglmb3IgKGkgPSAwOyBpIDwgMjU2OyBpKyspCgkJaW5mby0+cGFsZXR0ZV9idWZmZXJbaV0gPSBQQUxFVFRFX0JVRkZfQ0xFQVI7CgoJaWYgKCFyZXF1ZXN0X21lbV9yZWdpb24oKHVuc2lnbmVkIGxvbmcpUzNDMjRYWF9WQV9MQ0QsIFNaXzFNLCAiczNjMjQxMC1sY2QiKSkgewoJCXJldCA9IC1FQlVTWTsKCQlnb3RvIGRlYWxsb2NfZmI7Cgl9CgoKCWRwcmludGsoImdvdCBMQ0QgcmVnaW9uXG4iKTsKCglyZXQgPSByZXF1ZXN0X2lycShpcnEsIHMzYzI0MTBmYl9pcnEsIFNBX0lOVEVSUlVQVCwgcGRldi0+bmFtZSwgaW5mbyk7CglpZiAocmV0KSB7CgkJZGV2X2VycigmcGRldi0+ZGV2LCAiY2Fubm90IGdldCBpcnEgJWQgLSBlcnIgJWRcbiIsIGlycSwgcmV0KTsKCQlyZXQgPSAtRUJVU1k7CgkJZ290byByZWxlYXNlX21lbTsKCX0KCglpbmZvLT5jbGsgPSBjbGtfZ2V0KE5VTEwsICJsY2QiKTsKCWlmICghaW5mby0+Y2xrIHx8IElTX0VSUihpbmZvLT5jbGspKSB7CgkJcHJpbnRrKEtFUk5fRVJSICJmYWlsZWQgdG8gZ2V0IGxjZCBjbG9jayBzb3VyY2VcbiIpOwoJCXJldCA9IC1FTk9FTlQ7CgkJZ290byByZWxlYXNlX2lycTsKCX0KCgljbGtfdXNlKGluZm8tPmNsayk7CgljbGtfZW5hYmxlKGluZm8tPmNsayk7CglkcHJpbnRrKCJnb3QgYW5kIGVuYWJsZWQgY2xvY2tcbiIpOwoKCW1zbGVlcCgxKTsKCgkvKiBJbml0aWFsaXplIHZpZGVvIG1lbW9yeSAqLwoJcmV0ID0gczNjMjQxMGZiX21hcF92aWRlb19tZW1vcnkoaW5mbyk7CglpZiAocmV0KSB7CgkJcHJpbnRrKCBLRVJOX0VSUiAiRmFpbGVkIHRvIGFsbG9jYXRlIHZpZGVvIFJBTTogJWRcbiIsIHJldCk7CgkJcmV0ID0gLUVOT01FTTsKCQlnb3RvIHJlbGVhc2VfY2xvY2s7Cgl9CglkcHJpbnRrKCJnb3QgdmlkZW8gbWVtb3J5XG4iKTsKCglyZXQgPSBzM2MyNDEwZmJfaW5pdF9yZWdpc3RlcnMoaW5mbyk7CgoJcmV0ID0gczNjMjQxMGZiX2NoZWNrX3ZhcigmZmJpbmZvLT52YXIsIGZiaW5mbyk7CgoJcmV0ID0gcmVnaXN0ZXJfZnJhbWVidWZmZXIoZmJpbmZvKTsKCWlmIChyZXQgPCAwKSB7CgkJcHJpbnRrKEtFUk5fRVJSICJGYWlsZWQgdG8gcmVnaXN0ZXIgZnJhbWVidWZmZXIgZGV2aWNlOiAlZFxuIiwgcmV0KTsKCQlnb3RvIGZyZWVfdmlkZW9fbWVtb3J5OwoJfQoKCS8qIGNyZWF0ZSBkZXZpY2UgZmlsZXMgKi8KCWRldmljZV9jcmVhdGVfZmlsZSgmcGRldi0+ZGV2LCAmZGV2X2F0dHJfZGVidWcpOwoKCXByaW50ayhLRVJOX0lORk8gImZiJWQ6ICVzIGZyYW1lIGJ1ZmZlciBkZXZpY2VcbiIsCgkJZmJpbmZvLT5ub2RlLCBmYmluZm8tPmZpeC5pZCk7CgoJcmV0dXJuIDA7CgpmcmVlX3ZpZGVvX21lbW9yeToKCXMzYzI0MTBmYl91bm1hcF92aWRlb19tZW1vcnkoaW5mbyk7CnJlbGVhc2VfY2xvY2s6CgljbGtfZGlzYWJsZShpbmZvLT5jbGspOwoJY2xrX3VudXNlKGluZm8tPmNsayk7CgljbGtfcHV0KGluZm8tPmNsayk7CnJlbGVhc2VfaXJxOgoJZnJlZV9pcnEoaXJxLGluZm8pOwpyZWxlYXNlX21lbToKIAlyZWxlYXNlX21lbV9yZWdpb24oKHVuc2lnbmVkIGxvbmcpUzNDMjRYWF9WQV9MQ0QsIFMzQzI0WFhfU1pfTENEKTsKZGVhbGxvY19mYjoKCWZyYW1lYnVmZmVyX3JlbGVhc2UoZmJpbmZvKTsKCXJldHVybiByZXQ7Cn0KCi8qIHMzYzI0MTBmYl9zdG9wX2xjZAogKgogKiBzaHV0ZG93biB0aGUgbGNkIGNvbnRyb2xsZXIKKi8KCnN0YXRpYyB2b2lkIHMzYzI0MTBmYl9zdG9wX2xjZCh2b2lkKQp7Cgl1bnNpZ25lZCBsb25nIGZsYWdzOwoJdW5zaWduZWQgbG9uZyB0bXA7CgoJbG9jYWxfaXJxX3NhdmUoZmxhZ3MpOwoKCXRtcCA9IHJlYWRsKFMzQzI0MTBfTENEQ09OMSk7Cgl3cml0ZWwodG1wICYgflMzQzI0MTBfTENEQ09OMV9FTlZJRCwgUzNDMjQxMF9MQ0RDT04xKTsKCglsb2NhbF9pcnFfcmVzdG9yZShmbGFncyk7Cn0KCi8qCiAqICBDbGVhbnVwCiAqLwpzdGF0aWMgaW50IHMzYzI0MTBmYl9yZW1vdmUoc3RydWN0IHBsYXRmb3JtX2RldmljZSAqcGRldikKewoJc3RydWN0IGZiX2luZm8JICAgKmZiaW5mbyA9IHBsYXRmb3JtX2dldF9kcnZkYXRhKHBkZXYpOwoJc3RydWN0IHMzYzI0MTBmYl9pbmZvICppbmZvID0gZmJpbmZvLT5wYXI7CglpbnQgaXJxOwoKCXMzYzI0MTBmYl9zdG9wX2xjZCgpOwoJbXNsZWVwKDEpOwoKCXMzYzI0MTBmYl91bm1hcF92aWRlb19tZW1vcnkoaW5mbyk7CgogCWlmIChpbmZvLT5jbGspIHsKIAkJY2xrX2Rpc2FibGUoaW5mby0+Y2xrKTsKIAkJY2xrX3VudXNlKGluZm8tPmNsayk7CiAJCWNsa19wdXQoaW5mby0+Y2xrKTsKIAkJaW5mby0+Y2xrID0gTlVMTDsKCX0KCglpcnEgPSBwbGF0Zm9ybV9nZXRfaXJxKHBkZXYsIDApOwoJZnJlZV9pcnEoaXJxLGluZm8pOwoJcmVsZWFzZV9tZW1fcmVnaW9uKCh1bnNpZ25lZCBsb25nKVMzQzI0WFhfVkFfTENELCBTM0MyNFhYX1NaX0xDRCk7Cgl1bnJlZ2lzdGVyX2ZyYW1lYnVmZmVyKGZiaW5mbyk7CgoJcmV0dXJuIDA7Cn0KCiNpZmRlZiBDT05GSUdfUE0KCi8qIHN1c3BlbmQgYW5kIHJlc3VtZSBzdXBwb3J0IGZvciB0aGUgbGNkIGNvbnRyb2xsZXIgKi8KCnN0YXRpYyBpbnQgczNjMjQxMGZiX3N1c3BlbmQoc3RydWN0IHBsYXRmb3JtX2RldmljZSAqZGV2LCBwbV9tZXNzYWdlX3Qgc3RhdGUpCnsKCXN0cnVjdCBmYl9pbmZvCSAgICpmYmluZm8gPSBwbGF0Zm9ybV9nZXRfZHJ2ZGF0YShkZXYpOwoJc3RydWN0IHMzYzI0MTBmYl9pbmZvICppbmZvID0gZmJpbmZvLT5wYXI7CgoJczNjMjQxMGZiX3N0b3BfbGNkKCk7CgoJLyogc2xlZXAgYmVmb3JlIGRpc2FibGluZyB0aGUgY2xvY2ssIHdlIG5lZWQgdG8gZW5zdXJlCgkgKiB0aGUgTENEIERNQSBlbmdpbmUgaXMgbm90IGdvaW5nIHRvIGdldCBiYWNrIG9uIHRoZSBidXMKCSAqIGJlZm9yZSB0aGUgY2xvY2sgZ29lcyBvZmYgYWdhaW4gKGJqZCkgKi8KCgltc2xlZXAoMSk7CgljbGtfZGlzYWJsZShpbmZvLT5jbGspOwoKCXJldHVybiAwOwp9CgpzdGF0aWMgaW50IHMzYzI0MTBmYl9yZXN1bWUoc3RydWN0IHBsYXRmb3JtX2RldmljZSAqZGV2KQp7CglzdHJ1Y3QgZmJfaW5mbwkgICAqZmJpbmZvID0gcGxhdGZvcm1fZ2V0X2RydmRhdGEoZGV2KTsKCXN0cnVjdCBzM2MyNDEwZmJfaW5mbyAqaW5mbyA9IGZiaW5mby0+cGFyOwoKCWNsa19lbmFibGUoaW5mby0+Y2xrKTsKCW1zbGVlcCgxKTsKCglzM2MyNDEwZmJfaW5pdF9yZWdpc3RlcnMoaW5mbyk7CgoJcmV0dXJuIDA7Cn0KCiNlbHNlCiNkZWZpbmUgczNjMjQxMGZiX3N1c3BlbmQgTlVMTAojZGVmaW5lIHMzYzI0MTBmYl9yZXN1bWUgIE5VTEwKI2VuZGlmCgpzdGF0aWMgc3RydWN0IHBsYXRmb3JtX2RyaXZlciBzM2MyNDEwZmJfZHJpdmVyID0gewoJLnByb2JlCQk9IHMzYzI0MTBmYl9wcm9iZSwKCS5yZW1vdmUJCT0gczNjMjQxMGZiX3JlbW92ZSwKCS5zdXNwZW5kCT0gczNjMjQxMGZiX3N1c3BlbmQsCgkucmVzdW1lCQk9IHMzYzI0MTBmYl9yZXN1bWUsCgkuZHJpdmVyCQk9IHsKCQkubmFtZQk9ICJzM2MyNDEwLWxjZCIsCgkJLm93bmVyCT0gVEhJU19NT0RVTEUsCgl9LAp9OwoKaW50IF9fZGV2aW5pdCBzM2MyNDEwZmJfaW5pdCh2b2lkKQp7CglyZXR1cm4gcGxhdGZvcm1fZHJpdmVyX3JlZ2lzdGVyKCZzM2MyNDEwZmJfZHJpdmVyKTsKfQoKc3RhdGljIHZvaWQgX19leGl0IHMzYzI0MTBmYl9jbGVhbnVwKHZvaWQpCnsKCXBsYXRmb3JtX2RyaXZlcl91bnJlZ2lzdGVyKCZzM2MyNDEwZmJfZHJpdmVyKTsKfQoKCm1vZHVsZV9pbml0KHMzYzI0MTBmYl9pbml0KTsKbW9kdWxlX2V4aXQoczNjMjQxMGZiX2NsZWFudXApOwoKTU9EVUxFX0FVVEhPUigiQXJuYXVkIFBhdGFyZCA8YXJuYXVkLnBhdGFyZEBydHAtbmV0Lm9yZz4sIEJlbiBEb29rcyA8YmVuLWxpbnV4QGZsdWZmLm9yZz4iKTsKTU9EVUxFX0RFU0NSSVBUSU9OKCJGcmFtZWJ1ZmZlciBkcml2ZXIgZm9yIHRoZSBzM2MyNDEwIik7Ck1PRFVMRV9MSUNFTlNFKCJHUEwiKTsK