LyoKICogbGludXgvZHJpdmVycy92aWRlby9zM2MyNDEwZmIuYwogKglDb3B5cmlnaHQgKGMpIEFybmF1ZCBQYXRhcmQsIEJlbiBEb29rcwogKgogKiBUaGlzIGZpbGUgaXMgc3ViamVjdCB0byB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlLiAgU2VlIHRoZSBmaWxlIENPUFlJTkcgaW4gdGhlIG1haW4gZGlyZWN0b3J5IG9mIHRoaXMgYXJjaGl2ZSBmb3IKICogbW9yZSBkZXRhaWxzLgogKgogKgkgICAgUzNDMjQxMCBMQ0QgQ29udHJvbGxlciBGcmFtZSBCdWZmZXIgRHJpdmVyCiAqCSAgICBiYXNlZCBvbiBza2VsZXRvbmZiLmMsIHNhMTEwMGZiLmMgYW5kIG90aGVycwogKgogKiBDaGFuZ2VMb2cKICogMjAwNS0wNC0wNzogQXJuYXVkIFBhdGFyZCA8YXJuYXVkLnBhdGFyZEBydHAtbmV0Lm9yZz4KICogICAgICAtIHUzMiBzdGF0ZSAtPiBwbV9tZXNzYWdlX3Qgc3RhdGUKICogICAgICAtIFMzQzI0MTBfe1ZBLFNafV9MQ0QgLT4gUzNDMjRYWAogKgogKiAyMDA1LTAzLTE1OiBBcm5hdWQgUGF0YXJkIDxhcm5hdWQucGF0YXJkQHJ0cC1uZXQub3JnPgogKiAgICAgIC0gUmVtb3ZlZCB0aGUgaW9jdGwKICogICAgICAtIHVzZSByZWFkbC93cml0ZWwgaW5zdGVhZCBvZiBfX3Jhd193cml0ZWwvX19yYXdfcmVhZGwKICoKICogMjAwNC0xMi0wNDogQXJuYXVkIFBhdGFyZCA8YXJuYXVkLnBhdGFyZEBydHAtbmV0Lm9yZz4KICogICAgICAtIEFkZGVkIHRoZSBwb3NzaWJpbGl0eSB0byBzZXQgb24gb3Igb2ZmIHRoZQogKiAgICAgIGRlYnVnZ2luZyBtZXNhYWdlcwogKiAgICAgIC0gUmVwbGFjZWQgMCBhbmQgMSBieSBvbiBvciBvZmYgd2hlbiByZWFkaW5nIHRoZQogKiAgICAgIC9zeXMgZmlsZXMKICoKICogMjAwNS0wMy0yMzogQmVuIERvb2tzIDxiZW4tbGludXhAZmx1ZmYub3JnPgogKgktIGFkZGVkIG5vbiAxNmJwcCBtb2RlcwogKgktIHVwZGF0ZWQgcGxhdGZvcm0gaW5mb3JtYXRpb24gZm9yIHJhbmdlIG9mIHgveS9icHAKICoJLSBhZGQgY29kZSB0byBlbnN1cmUgcGFsZXR0ZSBpcyB3cml0dGVuIGNvcnJlY3RseQogKgktIGFkZCBwaXhlbCBjbG9jayBkaXZpc29yIGNvbnRyb2wKICoKICogMjAwNC0xMS0xMTogQXJuYXVkIFBhdGFyZCA8YXJuYXVkLnBhdGFyZEBydHAtbmV0Lm9yZz4KICogCS0gUmVtb3ZlZCB0aGUgdXNlIG9mIGN1cnJjb24gYXMgaXQgbm8gbW9yZSBleGlzdAogKiAJLSBBZGRlZCBMQ0QgcG93ZXIgc3lzZnMgaW50ZXJmYWNlCiAqCiAqIDIwMDQtMTEtMDM6IEJlbiBEb29rcyA8YmVuLWxpbnV4QGZsdWZmLm9yZz4KICoJLSBtaW5vciBjbGVhbnVwcwogKgktIGFkZCBzdXNwZW5kL3Jlc3VtZSBzdXBwb3J0CiAqCS0gczNjMjQxMGZiX3NldGNvbHJlZygpIG5vdCB2YWxpZCBpbiA+OGJwcCBtb2RlcwogKgktIHJlbW92ZWQgbGFzdCBDT05GSUdfRkJfUzNDMjQxMF9GSVhFRAogKgktIGVuc3VyZSBsY2QgY29udHJvbGxlciBzdG9wcGVkIGJlZm9yZSBjbGVhbnVwCiAqCS0gYWRkZWQgc3lzZnMgaW50ZXJmYWNlIGZvciBiYWNrbGlnaHQgcG93ZXIKICoJLSBhZGRlZCBtYXNrIGZvciBncGlvIGNvbmZpZ3VyYXRpb24KICoJLSBlbnN1cmVkIElSUXMgZGlzYWJsZWQgZHVyaW5nIEdQSU8gY29uZmlndXJhdGlvbgogKgktIGRpc2FibGUgVFBBTCBiZWZvcmUgZW5hYmxpbmcgdmlkZW8KICoKICogMjAwNC0wOS0yMDogQXJuYXVkIFBhdGFyZCA8YXJuYXVkLnBhdGFyZEBydHAtbmV0Lm9yZz4KICogICAgICAtIFN1cHByZXNzIGNvbW1hbmQgbGluZSBvcHRpb25zCiAqCiAqIDIwMDQtMDktMTU6IEFybmF1ZCBQYXRhcmQgPGFybmF1ZC5wYXRhcmRAcnRwLW5ldC5vcmc+CiAqIAktIGNvZGUgY2xlYW51cAogKgogKiAyMDA0LTA5LTA3OiBBcm5hdWQgUGF0YXJkIDxhcm5hdWQucGF0YXJkQHJ0cC1uZXQub3JnPgogKiAJLSBSZW5hbWVkIGZyb20gaDE5NDBmYi5jIHRvIHMzYzI0MTBmYi5jCiAqIAktIEFkZCBzdXBwb3J0IGZvciBkaWZmZXJlbnQgZGV2aWNlcwogKiAJLSBCYWNrbGlnaHQgc3VwcG9ydAogKgogKiAyMDA0LTA5LTA1OiBIZXJiZXJ0IFD2dHpsIDxoZXJiZXJ0QDEzdGhmbG9vci5hdD4KICoJLSBhZGRlZCBjbG9jayAoZGUtKWFsbG9jYXRpb24gY29kZQogKgktIGFkZGVkIGZpeGVtIGZibWVtIG9wdGlvbgogKgogKiAyMDA0LTA3LTI3OiBBcm5hdWQgUGF0YXJkIDxhcm5hdWQucGF0YXJkQHJ0cC1uZXQub3JnPgogKgktIGNvZGUgY2xlYW51cAogKgktIGFkZGVkIGEgZm9yZ290dGVuIHJldHVybiBpbiBoMTk0MGZiX2luaXQKICoKICogMjAwNC0wNy0xOTogSGVyYmVydCBQ9nR6bCA8aGVyYmVydEAxM3RoZmxvb3IuYXQ+CiAqCS0gY29kZSBjbGVhbnVwIGFuZCBleHRlbmRlZCBkZWJ1Z2dpbmcKICoKICogMjAwNC0wNy0xNTogQXJuYXVkIFBhdGFyZCA8YXJuYXVkLnBhdGFyZEBydHAtbmV0Lm9yZz4KICoJLSBGaXJzdCB2ZXJzaW9uCiAqLwoKI2luY2x1ZGUgPGxpbnV4L21vZHVsZS5oPgojaW5jbHVkZSA8bGludXgva2VybmVsLmg+CiNpbmNsdWRlIDxsaW51eC9lcnJuby5oPgojaW5jbHVkZSA8bGludXgvc3RyaW5nLmg+CiNpbmNsdWRlIDxsaW51eC9tbS5oPgojaW5jbHVkZSA8bGludXgvdHR5Lmg+CiNpbmNsdWRlIDxsaW51eC9zbGFiLmg+CiNpbmNsdWRlIDxsaW51eC9kZWxheS5oPgojaW5jbHVkZSA8bGludXgvZmIuaD4KI2luY2x1ZGUgPGxpbnV4L2luaXQuaD4KI2luY2x1ZGUgPGxpbnV4L2RtYS1tYXBwaW5nLmg+CiNpbmNsdWRlIDxsaW51eC9pbnRlcnJ1cHQuaD4KI2luY2x1ZGUgPGxpbnV4L3dvcmtxdWV1ZS5oPgojaW5jbHVkZSA8bGludXgvd2FpdC5oPgojaW5jbHVkZSA8bGludXgvcGxhdGZvcm1fZGV2aWNlLmg+CiNpbmNsdWRlIDxsaW51eC9jbGsuaD4KCiNpbmNsdWRlIDxhc20vaW8uaD4KI2luY2x1ZGUgPGFzbS91YWNjZXNzLmg+CiNpbmNsdWRlIDxhc20vZGl2NjQuaD4KCiNpbmNsdWRlIDxhc20vbWFjaC9tYXAuaD4KI2luY2x1ZGUgPGFzbS9hcmNoL3JlZ3MtbGNkLmg+CiNpbmNsdWRlIDxhc20vYXJjaC9yZWdzLWdwaW8uaD4KI2luY2x1ZGUgPGFzbS9hcmNoL2ZiLmg+CgojaWZkZWYgQ09ORklHX1BNCiNpbmNsdWRlIDxsaW51eC9wbS5oPgojZW5kaWYKCiNpbmNsdWRlICJzM2MyNDEwZmIuaCIKCgpzdGF0aWMgc3RydWN0IHMzYzI0MTBmYl9tYWNoX2luZm8gKm1hY2hfaW5mbzsKCi8qIERlYnVnZ2luZyBzdHVmZiAqLwojaWZkZWYgQ09ORklHX0ZCX1MzQzI0MTBfREVCVUcKc3RhdGljIGludCBkZWJ1ZwkgICA9IDE7CiNlbHNlCnN0YXRpYyBpbnQgZGVidWcJICAgPSAwOwojZW5kaWYKCiNkZWZpbmUgZHByaW50ayhtc2cuLi4pCWlmIChkZWJ1ZykgeyBwcmludGsoS0VSTl9ERUJVRyAiczNjMjQxMGZiOiAiIG1zZyk7IH0KCi8qIHVzZWZ1bCBmdW5jdGlvbnMgKi8KCi8qIHMzYzI0MTBmYl9zZXRfbGNkYWRkcgogKgogKiBpbml0aWFsaXNlIGxjZCBjb250cm9sbGVyIGFkZHJlc3MgcG9pbnRlcnMKKi8KCnN0YXRpYyB2b2lkIHMzYzI0MTBmYl9zZXRfbGNkYWRkcihzdHJ1Y3QgczNjMjQxMGZiX2luZm8gKmZiaSkKewoJc3RydWN0IGZiX3Zhcl9zY3JlZW5pbmZvICp2YXIgPSAmZmJpLT5mYi0+dmFyOwoJdW5zaWduZWQgbG9uZyBzYWRkcjEsIHNhZGRyMiwgc2FkZHIzOwoKCXNhZGRyMSAgPSBmYmktPmZiLT5maXguc21lbV9zdGFydCA+PiAxOwoJc2FkZHIyICA9IGZiaS0+ZmItPmZpeC5zbWVtX3N0YXJ0OwoJc2FkZHIyICs9ICh2YXItPnhyZXMgKiB2YXItPnlyZXMgKiB2YXItPmJpdHNfcGVyX3BpeGVsKS84OwoJc2FkZHIyPj49IDE7CgoJc2FkZHIzID0gIFMzQzI0MTBfT0ZGU0laRSgwKSB8IFMzQzI0MTBfUEFHRVdJRFRIKHZhci0+eHJlcyk7CgoJZHByaW50aygiTENEU0FERFIxID0gMHglMDhseFxuIiwgc2FkZHIxKTsKCWRwcmludGsoIkxDRFNBRERSMiA9IDB4JTA4bHhcbiIsIHNhZGRyMik7CglkcHJpbnRrKCJMQ0RTQUREUjMgPSAweCUwOGx4XG4iLCBzYWRkcjMpOwoKCXdyaXRlbChzYWRkcjEsIFMzQzI0MTBfTENEU0FERFIxKTsKCXdyaXRlbChzYWRkcjIsIFMzQzI0MTBfTENEU0FERFIyKTsKCXdyaXRlbChzYWRkcjMsIFMzQzI0MTBfTENEU0FERFIzKTsKfQoKLyogczNjMjQxMGZiX2NhbGNfcGl4Y2xrKCkKICoKICogY2FsY3VsYXRlIGRpdmlzb3IgZm9yIGNsay0+cGl4Y2xrCiovCgpzdGF0aWMgdW5zaWduZWQgaW50IHMzYzI0MTBmYl9jYWxjX3BpeGNsayhzdHJ1Y3QgczNjMjQxMGZiX2luZm8gKmZiaSwKCQkJCQkgIHVuc2lnbmVkIGxvbmcgcGl4Y2xrKQp7Cgl1bnNpZ25lZCBsb25nIGNsayA9IGNsa19nZXRfcmF0ZShmYmktPmNsayk7Cgl1bnNpZ25lZCBsb25nIGxvbmcgZGl2OwoKCS8qIHBpeGNsayBpcyBpbiBwaWNvc2VvbmNkcywgb3VyIGNsb2NrIGlzIGluIEh6CgkgKgoJICogSHogLT4gcGljb3NlY29uZHMgaXMgLyAxMF4tMTIKCSAqLwoKCWRpdiA9ICh1bnNpZ25lZCBsb25nIGxvbmcpY2xrICogcGl4Y2xrOwoJZG9fZGl2KGRpdiwxMDAwMDAwVUwpOwoJZG9fZGl2KGRpdiwxMDAwMDAwVUwpOwoKCWRwcmludGsoInBpeGNsayAlbGQsIGRpdmlzb3IgaXMgJWxkXG4iLCBwaXhjbGssIChsb25nKWRpdik7CglyZXR1cm4gZGl2Owp9CgovKgogKglzM2MyNDEwZmJfY2hlY2tfdmFyKCk6CiAqCUdldCB0aGUgdmlkZW8gcGFyYW1zIG91dCBvZiAndmFyJy4gSWYgYSB2YWx1ZSBkb2Vzbid0IGZpdCwgcm91bmQgaXQgdXAsCiAqCWlmIGl0J3MgdG9vIGJpZywgcmV0dXJuIC1FSU5WQUwuCiAqCiAqLwpzdGF0aWMgaW50IHMzYzI0MTBmYl9jaGVja192YXIoc3RydWN0IGZiX3Zhcl9zY3JlZW5pbmZvICp2YXIsCgkJCSAgICAgICBzdHJ1Y3QgZmJfaW5mbyAqaW5mbykKewoJc3RydWN0IHMzYzI0MTBmYl9pbmZvICpmYmkgPSBpbmZvLT5wYXI7CgoJZHByaW50aygiY2hlY2tfdmFyKHZhcj0lcCwgaW5mbz0lcClcbiIsIHZhciwgaW5mbyk7CgoJLyogdmFsaWRhdGUgeC95IHJlc29sdXRpb24gKi8KCglpZiAodmFyLT55cmVzID4gZmJpLT5tYWNoX2luZm8tPnlyZXMubWF4KQoJCXZhci0+eXJlcyA9IGZiaS0+bWFjaF9pbmZvLT55cmVzLm1heDsKCWVsc2UgaWYgKHZhci0+eXJlcyA8IGZiaS0+bWFjaF9pbmZvLT55cmVzLm1pbikKCQl2YXItPnlyZXMgPSBmYmktPm1hY2hfaW5mby0+eXJlcy5taW47CgoJaWYgKHZhci0+eHJlcyA+IGZiaS0+bWFjaF9pbmZvLT54cmVzLm1heCkKCQl2YXItPnlyZXMgPSBmYmktPm1hY2hfaW5mby0+eHJlcy5tYXg7CgllbHNlIGlmICh2YXItPnhyZXMgPCBmYmktPm1hY2hfaW5mby0+eHJlcy5taW4pCgkJdmFyLT54cmVzID0gZmJpLT5tYWNoX2luZm8tPnhyZXMubWluOwoKCS8qIHZhbGlkYXRlIGJwcCAqLwoKCWlmICh2YXItPmJpdHNfcGVyX3BpeGVsID4gZmJpLT5tYWNoX2luZm8tPmJwcC5tYXgpCgkJdmFyLT5iaXRzX3Blcl9waXhlbCA9IGZiaS0+bWFjaF9pbmZvLT5icHAubWF4OwoJZWxzZSBpZiAodmFyLT5iaXRzX3Blcl9waXhlbCA8IGZiaS0+bWFjaF9pbmZvLT5icHAubWluKQoJCXZhci0+Yml0c19wZXJfcGl4ZWwgPSBmYmktPm1hY2hfaW5mby0+YnBwLm1pbjsKCgkvKiBzZXQgci9nL2IgcG9zaXRpb25zICovCgoJaWYgKHZhci0+Yml0c19wZXJfcGl4ZWwgPT0gMTYpIHsKCQl2YXItPnJlZC5vZmZzZXQJCT0gMTE7CgkJdmFyLT5ncmVlbi5vZmZzZXQJPSA1OwoJCXZhci0+Ymx1ZS5vZmZzZXQJPSAwOwoJCXZhci0+cmVkLmxlbmd0aAkJPSA1OwoJCXZhci0+Z3JlZW4ubGVuZ3RoCT0gNjsKCQl2YXItPmJsdWUubGVuZ3RoCT0gNTsKCQl2YXItPnRyYW5zcC5sZW5ndGgJPSAwOwoJfSBlbHNlIHsKCQl2YXItPnJlZC5sZW5ndGgJCT0gdmFyLT5iaXRzX3Blcl9waXhlbDsKCQl2YXItPnJlZC5vZmZzZXQJCT0gMDsKCQl2YXItPmdyZWVuLmxlbmd0aAk9IHZhci0+Yml0c19wZXJfcGl4ZWw7CgkJdmFyLT5ncmVlbi5vZmZzZXQJPSAwOwoJCXZhci0+Ymx1ZS5sZW5ndGgJPSB2YXItPmJpdHNfcGVyX3BpeGVsOwoJCXZhci0+Ymx1ZS5vZmZzZXQJPSAwOwoJCXZhci0+dHJhbnNwLmxlbmd0aAk9IDA7Cgl9CgoJcmV0dXJuIDA7Cn0KCi8qIHMzYzI0MTBmYl9hY3RpdmF0ZV92YXIKICoKICogYWN0aXZhdGUgKHNldCkgdGhlIGNvbnRyb2xsZXIgZnJvbSB0aGUgZ2l2ZW4gZnJhbWVidWZmZXIKICogaW5mb3JtYXRpb24KKi8KCnN0YXRpYyB2b2lkIHMzYzI0MTBmYl9hY3RpdmF0ZV92YXIoc3RydWN0IHMzYzI0MTBmYl9pbmZvICpmYmksCgkJCQkgICBzdHJ1Y3QgZmJfdmFyX3NjcmVlbmluZm8gKnZhcikKewoJZmJpLT5yZWdzLmxjZGNvbjEgJj0gflMzQzI0MTBfTENEQ09OMV9NT0RFTUFTSzsKCglkcHJpbnRrKCIlczogdmFyLT54cmVzICA9ICVkXG4iLCBfX0ZVTkNUSU9OX18sIHZhci0+eHJlcyk7CglkcHJpbnRrKCIlczogdmFyLT55cmVzICA9ICVkXG4iLCBfX0ZVTkNUSU9OX18sIHZhci0+eXJlcyk7CglkcHJpbnRrKCIlczogdmFyLT5icHAgICA9ICVkXG4iLCBfX0ZVTkNUSU9OX18sIHZhci0+Yml0c19wZXJfcGl4ZWwpOwoKCXN3aXRjaCAodmFyLT5iaXRzX3Blcl9waXhlbCkgewoJY2FzZSAxOgoJCWZiaS0+cmVncy5sY2Rjb24xIHw9IFMzQzI0MTBfTENEQ09OMV9URlQxQlBQOwoJCWJyZWFrOwoJY2FzZSAyOgoJCWZiaS0+cmVncy5sY2Rjb24xIHw9IFMzQzI0MTBfTENEQ09OMV9URlQyQlBQOwoJCWJyZWFrOwoJY2FzZSA0OgoJCWZiaS0+cmVncy5sY2Rjb24xIHw9IFMzQzI0MTBfTENEQ09OMV9URlQ0QlBQOwoJCWJyZWFrOwoJY2FzZSA4OgoJCWZiaS0+cmVncy5sY2Rjb24xIHw9IFMzQzI0MTBfTENEQ09OMV9URlQ4QlBQOwoJCWJyZWFrOwoJY2FzZSAxNjoKCQlmYmktPnJlZ3MubGNkY29uMSB8PSBTM0MyNDEwX0xDRENPTjFfVEZUMTZCUFA7CgkJYnJlYWs7Cgl9CgoJLyogY2hlY2sgdG8gc2VlIGlmIHdlIG5lZWQgdG8gdXBkYXRlIHN5bmMvYm9yZGVycyAqLwoKCWlmICghZmJpLT5tYWNoX2luZm8tPmZpeGVkX3N5bmNzKSB7CgkJZHByaW50aygic2V0dGluZyB2ZXJ0OiB1cD0lZCwgbG93PSVkLCBzeW5jPSVkXG4iLAoJCQl2YXItPnVwcGVyX21hcmdpbiwgdmFyLT5sb3dlcl9tYXJnaW4sCgkJCXZhci0+dnN5bmNfbGVuKTsKCgkJZHByaW50aygic2V0dGluZyBob3J6OiBsZnQ9JWQsIHJ0PSVkLCBzeW5jPSVkXG4iLAoJCQl2YXItPmxlZnRfbWFyZ2luLCB2YXItPnJpZ2h0X21hcmdpbiwKCQkJdmFyLT5oc3luY19sZW4pOwoKCQlmYmktPnJlZ3MubGNkY29uMiA9CgkJCVMzQzI0MTBfTENEQ09OMl9WQlBEKHZhci0+dXBwZXJfbWFyZ2luIC0gMSkgfAoJCQlTM0MyNDEwX0xDRENPTjJfVkZQRCh2YXItPmxvd2VyX21hcmdpbiAtIDEpIHwKCQkJUzNDMjQxMF9MQ0RDT04yX1ZTUFcodmFyLT52c3luY19sZW4gLSAxKTsKCgkJZmJpLT5yZWdzLmxjZGNvbjMgPQoJCQlTM0MyNDEwX0xDRENPTjNfSEJQRCh2YXItPnJpZ2h0X21hcmdpbiAtIDEpIHwKCQkJUzNDMjQxMF9MQ0RDT04zX0hGUEQodmFyLT5sZWZ0X21hcmdpbiAtIDEpOwoKCQlmYmktPnJlZ3MubGNkY29uNCAmPSB+UzNDMjQxMF9MQ0RDT040X0hTUFcoMHhmZik7CgkJZmJpLT5yZWdzLmxjZGNvbjQgfD0gIFMzQzI0MTBfTENEQ09ONF9IU1BXKHZhci0+aHN5bmNfbGVuIC0gMSk7Cgl9CgoJLyogdXBkYXRlIFgvWSBpbmZvICovCgoJZmJpLT5yZWdzLmxjZGNvbjIgJj0gflMzQzI0MTBfTENEQ09OMl9MSU5FVkFMKDB4M2ZmKTsKCWZiaS0+cmVncy5sY2Rjb24yIHw9ICBTM0MyNDEwX0xDRENPTjJfTElORVZBTCh2YXItPnlyZXMgLSAxKTsKCglmYmktPnJlZ3MubGNkY29uMyAmPSB+UzNDMjQxMF9MQ0RDT04zX0hPWlZBTCgweDdmZik7CglmYmktPnJlZ3MubGNkY29uMyB8PSAgUzNDMjQxMF9MQ0RDT04zX0hPWlZBTCh2YXItPnhyZXMgLSAxKTsKCglpZiAodmFyLT5waXhjbG9jayA+IDApIHsKCQlpbnQgY2xrZGl2ID0gczNjMjQxMGZiX2NhbGNfcGl4Y2xrKGZiaSwgdmFyLT5waXhjbG9jayk7CgoJCWNsa2RpdiA9IChjbGtkaXYgLyAyKSAtMTsKCQlpZiAoY2xrZGl2IDwgMCkKCQkJY2xrZGl2ID0gMDsKCgkJZmJpLT5yZWdzLmxjZGNvbjEgJj0gflMzQzI0MTBfTENEQ09OMV9DTEtWQUwoMHgzZmYpOwoJCWZiaS0+cmVncy5sY2Rjb24xIHw9ICBTM0MyNDEwX0xDRENPTjFfQ0xLVkFMKGNsa2Rpdik7Cgl9CgoJLyogd3JpdGUgbmV3IHJlZ2lzdGVycyAqLwoKCWRwcmludGsoIm5ldyByZWdpc3RlciBzZXQ6XG4iKTsKCWRwcmludGsoImxjZGNvblsxXSA9IDB4JTA4bHhcbiIsIGZiaS0+cmVncy5sY2Rjb24xKTsKCWRwcmludGsoImxjZGNvblsyXSA9IDB4JTA4bHhcbiIsIGZiaS0+cmVncy5sY2Rjb24yKTsKCWRwcmludGsoImxjZGNvblszXSA9IDB4JTA4bHhcbiIsIGZiaS0+cmVncy5sY2Rjb24zKTsKCWRwcmludGsoImxjZGNvbls0XSA9IDB4JTA4bHhcbiIsIGZiaS0+cmVncy5sY2Rjb240KTsKCWRwcmludGsoImxjZGNvbls1XSA9IDB4JTA4bHhcbiIsIGZiaS0+cmVncy5sY2Rjb241KTsKCgl3cml0ZWwoZmJpLT5yZWdzLmxjZGNvbjEgJiB+UzNDMjQxMF9MQ0RDT04xX0VOVklELCBTM0MyNDEwX0xDRENPTjEpOwoJd3JpdGVsKGZiaS0+cmVncy5sY2Rjb24yLCBTM0MyNDEwX0xDRENPTjIpOwoJd3JpdGVsKGZiaS0+cmVncy5sY2Rjb24zLCBTM0MyNDEwX0xDRENPTjMpOwoJd3JpdGVsKGZiaS0+cmVncy5sY2Rjb240LCBTM0MyNDEwX0xDRENPTjQpOwoJd3JpdGVsKGZiaS0+cmVncy5sY2Rjb241LCBTM0MyNDEwX0xDRENPTjUpOwoKCS8qIHNldCBsY2QgYWRkcmVzcyBwb2ludGVycyAqLwoJczNjMjQxMGZiX3NldF9sY2RhZGRyKGZiaSk7CgoJd3JpdGVsKGZiaS0+cmVncy5sY2Rjb24xLCBTM0MyNDEwX0xDRENPTjEpOwp9CgoKLyoKICogICAgICBzM2MyNDEwZmJfc2V0X3BhciAtIE9wdGlvbmFsIGZ1bmN0aW9uLiBBbHRlcnMgdGhlIGhhcmR3YXJlIHN0YXRlLgogKiAgICAgIEBpbmZvOiBmcmFtZSBidWZmZXIgc3RydWN0dXJlIHRoYXQgcmVwcmVzZW50cyBhIHNpbmdsZSBmcmFtZSBidWZmZXIKICoKICovCnN0YXRpYyBpbnQgczNjMjQxMGZiX3NldF9wYXIoc3RydWN0IGZiX2luZm8gKmluZm8pCnsKCXN0cnVjdCBzM2MyNDEwZmJfaW5mbyAqZmJpID0gaW5mby0+cGFyOwoJc3RydWN0IGZiX3Zhcl9zY3JlZW5pbmZvICp2YXIgPSAmaW5mby0+dmFyOwoKCWlmICh2YXItPmJpdHNfcGVyX3BpeGVsID09IDE2KQoJCWZiaS0+ZmItPmZpeC52aXN1YWwgPSBGQl9WSVNVQUxfVFJVRUNPTE9SOwoJZWxzZQoJCWZiaS0+ZmItPmZpeC52aXN1YWwgPSBGQl9WSVNVQUxfUFNFVURPQ09MT1I7CgoJZmJpLT5mYi0+Zml4LmxpbmVfbGVuZ3RoICAgICA9ICh2YXItPndpZHRoKnZhci0+Yml0c19wZXJfcGl4ZWwpLzg7CgoJLyogYWN0aXZhdGUgdGhpcyBuZXcgY29uZmlndXJhdGlvbiAqLwoKCXMzYzI0MTBmYl9hY3RpdmF0ZV92YXIoZmJpLCB2YXIpOwoJcmV0dXJuIDA7Cn0KCnN0YXRpYyB2b2lkIHNjaGVkdWxlX3BhbGV0dGVfdXBkYXRlKHN0cnVjdCBzM2MyNDEwZmJfaW5mbyAqZmJpLAoJCQkJICAgIHVuc2lnbmVkIGludCByZWdubywgdW5zaWduZWQgaW50IHZhbCkKewoJdW5zaWduZWQgbG9uZyBmbGFnczsKCXVuc2lnbmVkIGxvbmcgaXJxZW47CgoJbG9jYWxfaXJxX3NhdmUoZmxhZ3MpOwoKCWZiaS0+cGFsZXR0ZV9idWZmZXJbcmVnbm9dID0gdmFsOwoKCWlmICghZmJpLT5wYWxldHRlX3JlYWR5KSB7CgkJZmJpLT5wYWxldHRlX3JlYWR5ID0gMTsKCgkJLyogZW5hYmxlIElSUSAqLwoJCWlycWVuID0gcmVhZGwoUzNDMjQxMF9MQ0RJTlRNU0spOwoJCWlycWVuICY9IH5TM0MyNDEwX0xDRElOVF9GUlNZTkM7CgkJd3JpdGVsKGlycWVuLCBTM0MyNDEwX0xDRElOVE1TSyk7Cgl9CgoJbG9jYWxfaXJxX3Jlc3RvcmUoZmxhZ3MpOwp9CgovKiBmcm9tIHB4YWZiLmMgKi8Kc3RhdGljIGlubGluZSB1bnNpZ25lZCBpbnQgY2hhbl90b19maWVsZCh1bnNpZ25lZCBpbnQgY2hhbiwgc3RydWN0IGZiX2JpdGZpZWxkICpiZikKewoJY2hhbiAmPSAweGZmZmY7CgljaGFuID4+PSAxNiAtIGJmLT5sZW5ndGg7CglyZXR1cm4gY2hhbiA8PCBiZi0+b2Zmc2V0Owp9CgpzdGF0aWMgaW50IHMzYzI0MTBmYl9zZXRjb2xyZWcodW5zaWduZWQgcmVnbm8sCgkJCSAgICAgICB1bnNpZ25lZCByZWQsIHVuc2lnbmVkIGdyZWVuLCB1bnNpZ25lZCBibHVlLAoJCQkgICAgICAgdW5zaWduZWQgdHJhbnNwLCBzdHJ1Y3QgZmJfaW5mbyAqaW5mbykKewoJc3RydWN0IHMzYzI0MTBmYl9pbmZvICpmYmkgPSBpbmZvLT5wYXI7Cgl1bnNpZ25lZCBpbnQgdmFsOwoKCS8qIGRwcmludGsoInNldGNvbDogcmVnbm89JWQsIHJnYj0lZCwlZCwlZFxuIiwgcmVnbm8sIHJlZCwgZ3JlZW4sIGJsdWUpOyAqLwoKCXN3aXRjaCAoZmJpLT5mYi0+Zml4LnZpc3VhbCkgewoJY2FzZSBGQl9WSVNVQUxfVFJVRUNPTE9SOgoJCS8qIHRydWUtY29sb3VyLCB1c2UgcHNldW8tcGFsZXR0ZSAqLwoKCQlpZiAocmVnbm8gPCAxNikgewoJCQl1MzIgKnBhbCA9IGZiaS0+ZmItPnBzZXVkb19wYWxldHRlOwoKCQkJdmFsICA9IGNoYW5fdG9fZmllbGQocmVkLCAgICZmYmktPmZiLT52YXIucmVkKTsKCQkJdmFsIHw9IGNoYW5fdG9fZmllbGQoZ3JlZW4sICZmYmktPmZiLT52YXIuZ3JlZW4pOwoJCQl2YWwgfD0gY2hhbl90b19maWVsZChibHVlLCAgJmZiaS0+ZmItPnZhci5ibHVlKTsKCgkJCXBhbFtyZWdub10gPSB2YWw7CgkJfQoJCWJyZWFrOwoKCWNhc2UgRkJfVklTVUFMX1BTRVVET0NPTE9SOgoJCWlmIChyZWdubyA8IDI1NikgewoJCQkvKiBjdXJyZW50bHkgYXNzdW1lIFJHQiA1LTYtNSBtb2RlICovCgoJCQl2YWwgID0gKChyZWQgICA+PiAgMCkgJiAweGY4MDApOwoJCQl2YWwgfD0gKChncmVlbiA+PiAgNSkgJiAweDA3ZTApOwoJCQl2YWwgfD0gKChibHVlICA+PiAxMSkgJiAweDAwMWYpOwoKCQkJd3JpdGVsKHZhbCwgUzNDMjQxMF9URlRQQUwocmVnbm8pKTsKCQkJc2NoZWR1bGVfcGFsZXR0ZV91cGRhdGUoZmJpLCByZWdubywgdmFsKTsKCQl9CgoJCWJyZWFrOwoKCWRlZmF1bHQ6CgkJcmV0dXJuIDE7ICAgLyogdW5rbm93biB0eXBlICovCgl9CgoJcmV0dXJuIDA7Cn0KCgovKioKICogICAgICBzM2MyNDEwZmJfYmxhbmsKICoJQGJsYW5rX21vZGU6IHRoZSBibGFuayBtb2RlIHdlIHdhbnQuCiAqCUBpbmZvOiBmcmFtZSBidWZmZXIgc3RydWN0dXJlIHRoYXQgcmVwcmVzZW50cyBhIHNpbmdsZSBmcmFtZSBidWZmZXIKICoKICoJQmxhbmsgdGhlIHNjcmVlbiBpZiBibGFua19tb2RlICE9IDAsIGVsc2UgdW5ibGFuay4gUmV0dXJuIDAgaWYKICoJYmxhbmtpbmcgc3VjY2VlZGVkLCAhPSAwIGlmIHVuLS9ibGFua2luZyBmYWlsZWQgZHVlIHRvIGUuZy4gYQogKgl2aWRlbyBtb2RlIHdoaWNoIGRvZXNuJ3Qgc3VwcG9ydCBpdC4gSW1wbGVtZW50cyBWRVNBIHN1c3BlbmQKICoJYW5kIHBvd2VyZG93biBtb2RlcyBvbiBoYXJkd2FyZSB0aGF0IHN1cHBvcnRzIGRpc2FibGluZyBoc3luYy92c3luYzoKICoJYmxhbmtfbW9kZSA9PSAyOiBzdXNwZW5kIHZzeW5jCiAqCWJsYW5rX21vZGUgPT0gMzogc3VzcGVuZCBoc3luYwogKglibGFua19tb2RlID09IDQ6IHBvd2VyZG93bgogKgogKglSZXR1cm5zIG5lZ2F0aXZlIGVycm5vIG9uIGVycm9yLCBvciB6ZXJvIG9uIHN1Y2Nlc3MuCiAqCiAqLwpzdGF0aWMgaW50IHMzYzI0MTBmYl9ibGFuayhpbnQgYmxhbmtfbW9kZSwgc3RydWN0IGZiX2luZm8gKmluZm8pCnsKCWRwcmludGsoImJsYW5rKG1vZGU9JWQsIGluZm89JXApXG4iLCBibGFua19tb2RlLCBpbmZvKTsKCglpZiAobWFjaF9pbmZvID09IE5VTEwpCgkJcmV0dXJuIC1FSU5WQUw7CgoJaWYgKGJsYW5rX21vZGUgPT0gRkJfQkxBTktfVU5CTEFOSykKCQl3cml0ZWwoMHgwLCBTM0MyNDEwX1RQQUwpOwoJZWxzZSB7CgkJZHByaW50aygic2V0dGluZyBUUEFMIHRvIG91dHB1dCAweDAwMDAwMFxuIik7CgkJd3JpdGVsKFMzQzI0MTBfVFBBTF9FTiwgUzNDMjQxMF9UUEFMKTsKCX0KCglyZXR1cm4gMDsKfQoKc3RhdGljIGludCBzM2MyNDEwZmJfZGVidWdfc2hvdyhzdHJ1Y3QgZGV2aWNlICpkZXYsIHN0cnVjdCBkZXZpY2VfYXR0cmlidXRlICphdHRyLCBjaGFyICpidWYpCnsKCXJldHVybiBzbnByaW50ZihidWYsIFBBR0VfU0laRSwgIiVzXG4iLCBkZWJ1ZyA/ICJvbiIgOiAib2ZmIik7Cn0Kc3RhdGljIGludCBzM2MyNDEwZmJfZGVidWdfc3RvcmUoc3RydWN0IGRldmljZSAqZGV2LCBzdHJ1Y3QgZGV2aWNlX2F0dHJpYnV0ZSAqYXR0ciwKCQkJCQkgICBjb25zdCBjaGFyICpidWYsIHNpemVfdCBsZW4pCnsKCWlmIChtYWNoX2luZm8gPT0gTlVMTCkKCQlyZXR1cm4gLUVJTlZBTDsKCglpZiAobGVuIDwgMSkKCQlyZXR1cm4gLUVJTlZBTDsKCglpZiAoc3RybmljbXAoYnVmLCAib24iLCAyKSA9PSAwIHx8CgkgICAgc3RybmljbXAoYnVmLCAiMSIsIDEpID09IDApIHsKCQlkZWJ1ZyA9IDE7CgkJcHJpbnRrKEtFUk5fREVCVUcgInMzYzI0MTBmYjogRGVidWcgT24iKTsKCX0gZWxzZSBpZiAoc3RybmljbXAoYnVmLCAib2ZmIiwgMykgPT0gMCB8fAoJCSAgIHN0cm5pY21wKGJ1ZiwgIjAiLCAxKSA9PSAwKSB7CgkJZGVidWcgPSAwOwoJCXByaW50ayhLRVJOX0RFQlVHICJzM2MyNDEwZmI6IERlYnVnIE9mZiIpOwoJfSBlbHNlIHsKCQlyZXR1cm4gLUVJTlZBTDsKCX0KCglyZXR1cm4gbGVuOwp9CgoKc3RhdGljIERFVklDRV9BVFRSKGRlYnVnLCAwNjY2LAoJCSAgIHMzYzI0MTBmYl9kZWJ1Z19zaG93LAoJCSAgIHMzYzI0MTBmYl9kZWJ1Z19zdG9yZSk7CgpzdGF0aWMgc3RydWN0IGZiX29wcyBzM2MyNDEwZmJfb3BzID0gewoJLm93bmVyCQk9IFRISVNfTU9EVUxFLAoJLmZiX2NoZWNrX3Zhcgk9IHMzYzI0MTBmYl9jaGVja192YXIsCgkuZmJfc2V0X3Bhcgk9IHMzYzI0MTBmYl9zZXRfcGFyLAoJLmZiX2JsYW5rCT0gczNjMjQxMGZiX2JsYW5rLAoJLmZiX3NldGNvbHJlZwk9IHMzYzI0MTBmYl9zZXRjb2xyZWcsCgkuZmJfZmlsbHJlY3QJPSBjZmJfZmlsbHJlY3QsCgkuZmJfY29weWFyZWEJPSBjZmJfY29weWFyZWEsCgkuZmJfaW1hZ2VibGl0CT0gY2ZiX2ltYWdlYmxpdCwKfTsKCgovKgogKiBzM2MyNDEwZmJfbWFwX3ZpZGVvX21lbW9yeSgpOgogKglBbGxvY2F0ZXMgdGhlIERSQU0gbWVtb3J5IGZvciB0aGUgZnJhbWUgYnVmZmVyLiAgVGhpcyBidWZmZXIgaXMKICoJcmVtYXBwZWQgaW50byBhIG5vbi1jYWNoZWQsIG5vbi1idWZmZXJlZCwgbWVtb3J5IHJlZ2lvbiB0bwogKglhbGxvdyBwYWxldHRlIGFuZCBwaXhlbCB3cml0ZXMgdG8gb2NjdXIgd2l0aG91dCBmbHVzaGluZyB0aGUKICoJY2FjaGUuICBPbmNlIHRoaXMgYXJlYSBpcyByZW1hcHBlZCwgYWxsIHZpcnR1YWwgbWVtb3J5CiAqCWFjY2VzcyB0byB0aGUgdmlkZW8gbWVtb3J5IHNob3VsZCBvY2N1ciBhdCB0aGUgbmV3IHJlZ2lvbi4KICovCnN0YXRpYyBpbnQgX19pbml0IHMzYzI0MTBmYl9tYXBfdmlkZW9fbWVtb3J5KHN0cnVjdCBzM2MyNDEwZmJfaW5mbyAqZmJpKQp7CglkcHJpbnRrKCJtYXBfdmlkZW9fbWVtb3J5KGZiaT0lcClcbiIsIGZiaSk7CgoJZmJpLT5tYXBfc2l6ZSA9IFBBR0VfQUxJR04oZmJpLT5mYi0+Zml4LnNtZW1fbGVuICsgUEFHRV9TSVpFKTsKCWZiaS0+bWFwX2NwdSAgPSBkbWFfYWxsb2Nfd3JpdGVjb21iaW5lKGZiaS0+ZGV2LCBmYmktPm1hcF9zaXplLAoJCQkJCSAgICAgICAmZmJpLT5tYXBfZG1hLCBHRlBfS0VSTkVMKTsKCglmYmktPm1hcF9zaXplID0gZmJpLT5mYi0+Zml4LnNtZW1fbGVuOwoKCWlmIChmYmktPm1hcF9jcHUpIHsKCQkvKiBwcmV2ZW50IGluaXRpYWwgZ2FyYmFnZSBvbiBzY3JlZW4gKi8KCQlkcHJpbnRrKCJtYXBfdmlkZW9fbWVtb3J5OiBjbGVhciAlcDolMDh4XG4iLAoJCQlmYmktPm1hcF9jcHUsIGZiaS0+bWFwX3NpemUpOwoJCW1lbXNldChmYmktPm1hcF9jcHUsIDB4ZjAsIGZiaS0+bWFwX3NpemUpOwoKCQlmYmktPnNjcmVlbl9kbWEJCT0gZmJpLT5tYXBfZG1hOwoJCWZiaS0+ZmItPnNjcmVlbl9iYXNlCT0gZmJpLT5tYXBfY3B1OwoJCWZiaS0+ZmItPmZpeC5zbWVtX3N0YXJ0ICA9IGZiaS0+c2NyZWVuX2RtYTsKCgkJZHByaW50aygibWFwX3ZpZGVvX21lbW9yeTogZG1hPSUwOHggY3B1PSVwIHNpemU9JTA4eFxuIiwKCQkJZmJpLT5tYXBfZG1hLCBmYmktPm1hcF9jcHUsIGZiaS0+ZmItPmZpeC5zbWVtX2xlbik7Cgl9CgoJcmV0dXJuIGZiaS0+bWFwX2NwdSA/IDAgOiAtRU5PTUVNOwp9CgpzdGF0aWMgaW5saW5lIHZvaWQgczNjMjQxMGZiX3VubWFwX3ZpZGVvX21lbW9yeShzdHJ1Y3QgczNjMjQxMGZiX2luZm8gKmZiaSkKewoJZG1hX2ZyZWVfd3JpdGVjb21iaW5lKGZiaS0+ZGV2LGZiaS0+bWFwX3NpemUsZmJpLT5tYXBfY3B1LCBmYmktPm1hcF9kbWEpOwp9CgpzdGF0aWMgaW5saW5lIHZvaWQgbW9kaWZ5X2dwaW8odm9pZCBfX2lvbWVtICpyZWcsCgkJCSAgICAgICB1bnNpZ25lZCBsb25nIHNldCwgdW5zaWduZWQgbG9uZyBtYXNrKQp7Cgl1bnNpZ25lZCBsb25nIHRtcDsKCgl0bXAgPSByZWFkbChyZWcpICYgfm1hc2s7Cgl3cml0ZWwodG1wIHwgc2V0LCByZWcpOwp9CgoKLyoKICogczNjMjQxMGZiX2luaXRfcmVnaXN0ZXJzIC0gSW5pdGlhbGlzZSBhbGwgTENELXJlbGF0ZWQgcmVnaXN0ZXJzCiAqLwoKc3RhdGljIGludCBzM2MyNDEwZmJfaW5pdF9yZWdpc3RlcnMoc3RydWN0IHMzYzI0MTBmYl9pbmZvICpmYmkpCnsKCXVuc2lnbmVkIGxvbmcgZmxhZ3M7CgoJLyogSW5pdGlhbGlzZSBMQ0Qgd2l0aCB2YWx1ZXMgZnJvbSBoYXJldCAqLwoKCWxvY2FsX2lycV9zYXZlKGZsYWdzKTsKCgkvKiBtb2RpZnkgdGhlIGdwaW8ocykgd2l0aCBpbnRlcnJ1cHRzIHNldCAoYmpkKSAqLwoKCW1vZGlmeV9ncGlvKFMzQzI0MTBfR1BDVVAsICBtYWNoX2luZm8tPmdwY3VwLCAgbWFjaF9pbmZvLT5ncGN1cF9tYXNrKTsKCW1vZGlmeV9ncGlvKFMzQzI0MTBfR1BDQ09OLCBtYWNoX2luZm8tPmdwY2NvbiwgbWFjaF9pbmZvLT5ncGNjb25fbWFzayk7Cgltb2RpZnlfZ3BpbyhTM0MyNDEwX0dQRFVQLCAgbWFjaF9pbmZvLT5ncGR1cCwgIG1hY2hfaW5mby0+Z3BkdXBfbWFzayk7Cgltb2RpZnlfZ3BpbyhTM0MyNDEwX0dQRENPTiwgbWFjaF9pbmZvLT5ncGRjb24sIG1hY2hfaW5mby0+Z3BkY29uX21hc2spOwoKCWxvY2FsX2lycV9yZXN0b3JlKGZsYWdzKTsKCgl3cml0ZWwoZmJpLT5yZWdzLmxjZGNvbjEsIFMzQzI0MTBfTENEQ09OMSk7Cgl3cml0ZWwoZmJpLT5yZWdzLmxjZGNvbjIsIFMzQzI0MTBfTENEQ09OMik7Cgl3cml0ZWwoZmJpLT5yZWdzLmxjZGNvbjMsIFMzQzI0MTBfTENEQ09OMyk7Cgl3cml0ZWwoZmJpLT5yZWdzLmxjZGNvbjQsIFMzQzI0MTBfTENEQ09ONCk7Cgl3cml0ZWwoZmJpLT5yZWdzLmxjZGNvbjUsIFMzQzI0MTBfTENEQ09ONSk7CgogCXMzYzI0MTBmYl9zZXRfbGNkYWRkcihmYmkpOwoKCWRwcmludGsoIkxQQ1NFTCAgICA9IDB4JTA4bHhcbiIsIG1hY2hfaW5mby0+bHBjc2VsKTsKCXdyaXRlbChtYWNoX2luZm8tPmxwY3NlbCwgUzNDMjQxMF9MUENTRUwpOwoKCWRwcmludGsoInJlcGxhY2luZyBUUEFMICUwOHhcbiIsIHJlYWRsKFMzQzI0MTBfVFBBTCkpOwoKCS8qIGVuc3VyZSB0ZW1wb3JhcnkgcGFsZXR0ZSBkaXNhYmxlZCAqLwoJd3JpdGVsKDB4MDAsIFMzQzI0MTBfVFBBTCk7CgoJLyogRW5hYmxlIHZpZGVvIGJ5IHNldHRpbmcgdGhlIEVOVklEIGJpdCB0byAxICovCglmYmktPnJlZ3MubGNkY29uMSB8PSBTM0MyNDEwX0xDRENPTjFfRU5WSUQ7Cgl3cml0ZWwoZmJpLT5yZWdzLmxjZGNvbjEsIFMzQzI0MTBfTENEQ09OMSk7CglyZXR1cm4gMDsKfQoKc3RhdGljIHZvaWQgczNjMjQxMGZiX3dyaXRlX3BhbGV0dGUoc3RydWN0IHMzYzI0MTBmYl9pbmZvICpmYmkpCnsKCXVuc2lnbmVkIGludCBpOwoJdW5zaWduZWQgbG9uZyBlbnQ7CgoJZmJpLT5wYWxldHRlX3JlYWR5ID0gMDsKCglmb3IgKGkgPSAwOyBpIDwgMjU2OyBpKyspIHsKCQlpZiAoKGVudCA9IGZiaS0+cGFsZXR0ZV9idWZmZXJbaV0pID09IFBBTEVUVEVfQlVGRl9DTEVBUikKCQkJY29udGludWU7CgoJCXdyaXRlbChlbnQsIFMzQzI0MTBfVEZUUEFMKGkpKTsKCgkJLyogaXQgc2VlbXMgdGhlIG9ubHkgd2F5IHRvIGtub3cgZXhhY3RseQoJCSAqIGlmIHRoZSBwYWxldHRlIHdyb3RlIG9rLCBpcyB0byBjaGVjawoJCSAqIHRvIHNlZSBpZiB0aGUgdmFsdWUgdmVyaWZpZXMgb2sKCQkgKi8KCgkJaWYgKHJlYWR3KFMzQzI0MTBfVEZUUEFMKGkpKSA9PSBlbnQpCgkJCWZiaS0+cGFsZXR0ZV9idWZmZXJbaV0gPSBQQUxFVFRFX0JVRkZfQ0xFQVI7CgkJZWxzZQoJCQlmYmktPnBhbGV0dGVfcmVhZHkgPSAxOyAgIC8qIHJldHJ5ICovCgl9Cn0KCnN0YXRpYyBpcnFyZXR1cm5fdCBzM2MyNDEwZmJfaXJxKGludCBpcnEsIHZvaWQgKmRldl9pZCwgc3RydWN0IHB0X3JlZ3MgKnIpCnsKCXN0cnVjdCBzM2MyNDEwZmJfaW5mbyAqZmJpID0gZGV2X2lkOwoJdW5zaWduZWQgbG9uZyBsY2RpcnEgPSByZWFkbChTM0MyNDEwX0xDRElOVFBORCk7CgoJaWYgKGxjZGlycSAmIFMzQzI0MTBfTENESU5UX0ZSU1lOQykgewoJCWlmIChmYmktPnBhbGV0dGVfcmVhZHkpCgkJCXMzYzI0MTBmYl93cml0ZV9wYWxldHRlKGZiaSk7CgoJCXdyaXRlbChTM0MyNDEwX0xDRElOVF9GUlNZTkMsIFMzQzI0MTBfTENESU5UUE5EKTsKCQl3cml0ZWwoUzNDMjQxMF9MQ0RJTlRfRlJTWU5DLCBTM0MyNDEwX0xDRFNSQ1BORCk7Cgl9CgoJcmV0dXJuIElSUV9IQU5ETEVEOwp9CgpzdGF0aWMgY2hhciBkcml2ZXJfbmFtZVtdPSJzM2MyNDEwZmIiOwoKc3RhdGljIGludCBfX2luaXQgczNjMjQxMGZiX3Byb2JlKHN0cnVjdCBwbGF0Zm9ybV9kZXZpY2UgKnBkZXYpCnsKCXN0cnVjdCBzM2MyNDEwZmJfaW5mbyAqaW5mbzsKCXN0cnVjdCBmYl9pbmZvCSAgICpmYmluZm87CglzdHJ1Y3QgczNjMjQxMGZiX2h3ICptcmVnczsKCWludCByZXQ7CglpbnQgaXJxOwoJaW50IGk7CgoJbWFjaF9pbmZvID0gcGRldi0+ZGV2LnBsYXRmb3JtX2RhdGE7CglpZiAobWFjaF9pbmZvID09IE5VTEwpIHsKCQlkZXZfZXJyKCZwZGV2LT5kZXYsIm5vIHBsYXRmb3JtIGRhdGEgZm9yIGxjZCwgY2Fubm90IGF0dGFjaFxuIik7CgkJcmV0dXJuIC1FSU5WQUw7Cgl9CgoJbXJlZ3MgPSAmbWFjaF9pbmZvLT5yZWdzOwoKCWlycSA9IHBsYXRmb3JtX2dldF9pcnEocGRldiwgMCk7CglpZiAoaXJxIDwgMCkgewoJCWRldl9lcnIoJnBkZXYtPmRldiwgIm5vIGlycSBmb3IgZGV2aWNlXG4iKTsKCQlyZXR1cm4gLUVOT0VOVDsKCX0KCglmYmluZm8gPSBmcmFtZWJ1ZmZlcl9hbGxvYyhzaXplb2Yoc3RydWN0IHMzYzI0MTBmYl9pbmZvKSwgJnBkZXYtPmRldik7CglpZiAoIWZiaW5mbykgewoJCXJldHVybiAtRU5PTUVNOwoJfQoKCglpbmZvID0gZmJpbmZvLT5wYXI7CglpbmZvLT5mYiA9IGZiaW5mbzsKCXBsYXRmb3JtX3NldF9kcnZkYXRhKHBkZXYsIGZiaW5mbyk7CgoJZHByaW50aygiZGV2aW5pdFxuIik7CgoJc3RyY3B5KGZiaW5mby0+Zml4LmlkLCBkcml2ZXJfbmFtZSk7CgoJbWVtY3B5KCZpbmZvLT5yZWdzLCAmbWFjaF9pbmZvLT5yZWdzLCBzaXplb2YoaW5mby0+cmVncykpOwoKCWluZm8tPm1hY2hfaW5mbwkJICAgID0gcGRldi0+ZGV2LnBsYXRmb3JtX2RhdGE7CgoJZmJpbmZvLT5maXgudHlwZQkgICAgPSBGQl9UWVBFX1BBQ0tFRF9QSVhFTFM7CglmYmluZm8tPmZpeC50eXBlX2F1eAkgICAgPSAwOwoJZmJpbmZvLT5maXgueHBhbnN0ZXAJICAgID0gMDsKCWZiaW5mby0+Zml4LnlwYW5zdGVwCSAgICA9IDA7CglmYmluZm8tPmZpeC55d3JhcHN0ZXAJICAgID0gMDsKCWZiaW5mby0+Zml4LmFjY2VsCSAgICA9IEZCX0FDQ0VMX05PTkU7CgoJZmJpbmZvLT52YXIubm9uc3RkCSAgICA9IDA7CglmYmluZm8tPnZhci5hY3RpdmF0ZQkgICAgPSBGQl9BQ1RJVkFURV9OT1c7CglmYmluZm8tPnZhci5oZWlnaHQJICAgID0gbWFjaF9pbmZvLT5oZWlnaHQ7CglmYmluZm8tPnZhci53aWR0aAkgICAgPSBtYWNoX2luZm8tPndpZHRoOwoJZmJpbmZvLT52YXIuYWNjZWxfZmxhZ3MgICAgID0gMDsKCWZiaW5mby0+dmFyLnZtb2RlCSAgICA9IEZCX1ZNT0RFX05PTklOVEVSTEFDRUQ7CgoJZmJpbmZvLT5mYm9wcwkJICAgID0gJnMzYzI0MTBmYl9vcHM7CglmYmluZm8tPmZsYWdzCQkgICAgPSBGQklORk9fRkxBR19ERUZBVUxUOwoJZmJpbmZvLT5wc2V1ZG9fcGFsZXR0ZSAgICAgID0gJmluZm8tPnBzZXVkb19wYWw7CgoJZmJpbmZvLT52YXIueHJlcwkgICAgPSBtYWNoX2luZm8tPnhyZXMuZGVmdmFsOwoJZmJpbmZvLT52YXIueHJlc192aXJ0dWFsICAgID0gbWFjaF9pbmZvLT54cmVzLmRlZnZhbDsKCWZiaW5mby0+dmFyLnlyZXMJICAgID0gbWFjaF9pbmZvLT55cmVzLmRlZnZhbDsKCWZiaW5mby0+dmFyLnlyZXNfdmlydHVhbCAgICA9IG1hY2hfaW5mby0+eXJlcy5kZWZ2YWw7CglmYmluZm8tPnZhci5iaXRzX3Blcl9waXhlbCAgPSBtYWNoX2luZm8tPmJwcC5kZWZ2YWw7CgoJZmJpbmZvLT52YXIudXBwZXJfbWFyZ2luICAgID0gUzNDMjQxMF9MQ0RDT04yX0dFVF9WQlBEKG1yZWdzLT5sY2Rjb24yKSArIDE7CglmYmluZm8tPnZhci5sb3dlcl9tYXJnaW4gICAgPSBTM0MyNDEwX0xDRENPTjJfR0VUX1ZGUEQobXJlZ3MtPmxjZGNvbjIpICsgMTsKCWZiaW5mby0+dmFyLnZzeW5jX2xlbgkgICAgPSBTM0MyNDEwX0xDRENPTjJfR0VUX1ZTUFcobXJlZ3MtPmxjZGNvbjIpICsgMTsKCglmYmluZm8tPnZhci5sZWZ0X21hcmdpbgkgICAgPSBTM0MyNDEwX0xDRENPTjNfR0VUX0hGUEQobXJlZ3MtPmxjZGNvbjMpICsgMTsKCWZiaW5mby0+dmFyLnJpZ2h0X21hcmdpbiAgICA9IFMzQzI0MTBfTENEQ09OM19HRVRfSEJQRChtcmVncy0+bGNkY29uMykgKyAxOwoJZmJpbmZvLT52YXIuaHN5bmNfbGVuCSAgICA9IFMzQzI0MTBfTENEQ09ONF9HRVRfSFNQVyhtcmVncy0+bGNkY29uNCkgKyAxOwoKCWZiaW5mby0+dmFyLnJlZC5vZmZzZXQgICAgICA9IDExOwoJZmJpbmZvLT52YXIuZ3JlZW4ub2Zmc2V0ICAgID0gNTsKCWZiaW5mby0+dmFyLmJsdWUub2Zmc2V0ICAgICA9IDA7CglmYmluZm8tPnZhci50cmFuc3Aub2Zmc2V0ICAgPSAwOwoJZmJpbmZvLT52YXIucmVkLmxlbmd0aCAgICAgID0gNTsKCWZiaW5mby0+dmFyLmdyZWVuLmxlbmd0aCAgICA9IDY7CglmYmluZm8tPnZhci5ibHVlLmxlbmd0aCAgICAgPSA1OwoJZmJpbmZvLT52YXIudHJhbnNwLmxlbmd0aCAgID0gMDsKCWZiaW5mby0+Zml4LnNtZW1fbGVuICAgICAgICA9CW1hY2hfaW5mby0+eHJlcy5tYXggKgoJCQkJCW1hY2hfaW5mby0+eXJlcy5tYXggKgoJCQkJCW1hY2hfaW5mby0+YnBwLm1heCAvIDg7CgoJZm9yIChpID0gMDsgaSA8IDI1NjsgaSsrKQoJCWluZm8tPnBhbGV0dGVfYnVmZmVyW2ldID0gUEFMRVRURV9CVUZGX0NMRUFSOwoKCWlmICghcmVxdWVzdF9tZW1fcmVnaW9uKCh1bnNpZ25lZCBsb25nKVMzQzI0WFhfVkFfTENELCBTWl8xTSwgInMzYzI0MTAtbGNkIikpIHsKCQlyZXQgPSAtRUJVU1k7CgkJZ290byBkZWFsbG9jX2ZiOwoJfQoKCglkcHJpbnRrKCJnb3QgTENEIHJlZ2lvblxuIik7CgoJcmV0ID0gcmVxdWVzdF9pcnEoaXJxLCBzM2MyNDEwZmJfaXJxLCBTQV9JTlRFUlJVUFQsIHBkZXYtPm5hbWUsIGluZm8pOwoJaWYgKHJldCkgewoJCWRldl9lcnIoJnBkZXYtPmRldiwgImNhbm5vdCBnZXQgaXJxICVkIC0gZXJyICVkXG4iLCBpcnEsIHJldCk7CgkJcmV0ID0gLUVCVVNZOwoJCWdvdG8gcmVsZWFzZV9tZW07Cgl9CgoJaW5mby0+Y2xrID0gY2xrX2dldChOVUxMLCAibGNkIik7CglpZiAoIWluZm8tPmNsayB8fCBJU19FUlIoaW5mby0+Y2xrKSkgewoJCXByaW50ayhLRVJOX0VSUiAiZmFpbGVkIHRvIGdldCBsY2QgY2xvY2sgc291cmNlXG4iKTsKCQlyZXQgPSAtRU5PRU5UOwoJCWdvdG8gcmVsZWFzZV9pcnE7Cgl9CgoJY2xrX2VuYWJsZShpbmZvLT5jbGspOwoJZHByaW50aygiZ290IGFuZCBlbmFibGVkIGNsb2NrXG4iKTsKCgltc2xlZXAoMSk7CgoJLyogSW5pdGlhbGl6ZSB2aWRlbyBtZW1vcnkgKi8KCXJldCA9IHMzYzI0MTBmYl9tYXBfdmlkZW9fbWVtb3J5KGluZm8pOwoJaWYgKHJldCkgewoJCXByaW50ayggS0VSTl9FUlIgIkZhaWxlZCB0byBhbGxvY2F0ZSB2aWRlbyBSQU06ICVkXG4iLCByZXQpOwoJCXJldCA9IC1FTk9NRU07CgkJZ290byByZWxlYXNlX2Nsb2NrOwoJfQoJZHByaW50aygiZ290IHZpZGVvIG1lbW9yeVxuIik7CgoJcmV0ID0gczNjMjQxMGZiX2luaXRfcmVnaXN0ZXJzKGluZm8pOwoKCXJldCA9IHMzYzI0MTBmYl9jaGVja192YXIoJmZiaW5mby0+dmFyLCBmYmluZm8pOwoKCXJldCA9IHJlZ2lzdGVyX2ZyYW1lYnVmZmVyKGZiaW5mbyk7CglpZiAocmV0IDwgMCkgewoJCXByaW50ayhLRVJOX0VSUiAiRmFpbGVkIHRvIHJlZ2lzdGVyIGZyYW1lYnVmZmVyIGRldmljZTogJWRcbiIsIHJldCk7CgkJZ290byBmcmVlX3ZpZGVvX21lbW9yeTsKCX0KCgkvKiBjcmVhdGUgZGV2aWNlIGZpbGVzICovCglkZXZpY2VfY3JlYXRlX2ZpbGUoJnBkZXYtPmRldiwgJmRldl9hdHRyX2RlYnVnKTsKCglwcmludGsoS0VSTl9JTkZPICJmYiVkOiAlcyBmcmFtZSBidWZmZXIgZGV2aWNlXG4iLAoJCWZiaW5mby0+bm9kZSwgZmJpbmZvLT5maXguaWQpOwoKCXJldHVybiAwOwoKZnJlZV92aWRlb19tZW1vcnk6CglzM2MyNDEwZmJfdW5tYXBfdmlkZW9fbWVtb3J5KGluZm8pOwpyZWxlYXNlX2Nsb2NrOgoJY2xrX2Rpc2FibGUoaW5mby0+Y2xrKTsKCWNsa19wdXQoaW5mby0+Y2xrKTsKcmVsZWFzZV9pcnE6CglmcmVlX2lycShpcnEsaW5mbyk7CnJlbGVhc2VfbWVtOgogCXJlbGVhc2VfbWVtX3JlZ2lvbigodW5zaWduZWQgbG9uZylTM0MyNFhYX1ZBX0xDRCwgUzNDMjRYWF9TWl9MQ0QpOwpkZWFsbG9jX2ZiOgoJZnJhbWVidWZmZXJfcmVsZWFzZShmYmluZm8pOwoJcmV0dXJuIHJldDsKfQoKLyogczNjMjQxMGZiX3N0b3BfbGNkCiAqCiAqIHNodXRkb3duIHRoZSBsY2QgY29udHJvbGxlcgoqLwoKc3RhdGljIHZvaWQgczNjMjQxMGZiX3N0b3BfbGNkKHZvaWQpCnsKCXVuc2lnbmVkIGxvbmcgZmxhZ3M7Cgl1bnNpZ25lZCBsb25nIHRtcDsKCglsb2NhbF9pcnFfc2F2ZShmbGFncyk7CgoJdG1wID0gcmVhZGwoUzNDMjQxMF9MQ0RDT04xKTsKCXdyaXRlbCh0bXAgJiB+UzNDMjQxMF9MQ0RDT04xX0VOVklELCBTM0MyNDEwX0xDRENPTjEpOwoKCWxvY2FsX2lycV9yZXN0b3JlKGZsYWdzKTsKfQoKLyoKICogIENsZWFudXAKICovCnN0YXRpYyBpbnQgczNjMjQxMGZiX3JlbW92ZShzdHJ1Y3QgcGxhdGZvcm1fZGV2aWNlICpwZGV2KQp7CglzdHJ1Y3QgZmJfaW5mbwkgICAqZmJpbmZvID0gcGxhdGZvcm1fZ2V0X2RydmRhdGEocGRldik7CglzdHJ1Y3QgczNjMjQxMGZiX2luZm8gKmluZm8gPSBmYmluZm8tPnBhcjsKCWludCBpcnE7CgoJczNjMjQxMGZiX3N0b3BfbGNkKCk7Cgltc2xlZXAoMSk7CgoJczNjMjQxMGZiX3VubWFwX3ZpZGVvX21lbW9yeShpbmZvKTsKCiAJaWYgKGluZm8tPmNsaykgewogCQljbGtfZGlzYWJsZShpbmZvLT5jbGspOwogCQljbGtfcHV0KGluZm8tPmNsayk7CiAJCWluZm8tPmNsayA9IE5VTEw7Cgl9CgoJaXJxID0gcGxhdGZvcm1fZ2V0X2lycShwZGV2LCAwKTsKCWZyZWVfaXJxKGlycSxpbmZvKTsKCXJlbGVhc2VfbWVtX3JlZ2lvbigodW5zaWduZWQgbG9uZylTM0MyNFhYX1ZBX0xDRCwgUzNDMjRYWF9TWl9MQ0QpOwoJdW5yZWdpc3Rlcl9mcmFtZWJ1ZmZlcihmYmluZm8pOwoKCXJldHVybiAwOwp9CgojaWZkZWYgQ09ORklHX1BNCgovKiBzdXNwZW5kIGFuZCByZXN1bWUgc3VwcG9ydCBmb3IgdGhlIGxjZCBjb250cm9sbGVyICovCgpzdGF0aWMgaW50IHMzYzI0MTBmYl9zdXNwZW5kKHN0cnVjdCBwbGF0Zm9ybV9kZXZpY2UgKmRldiwgcG1fbWVzc2FnZV90IHN0YXRlKQp7CglzdHJ1Y3QgZmJfaW5mbwkgICAqZmJpbmZvID0gcGxhdGZvcm1fZ2V0X2RydmRhdGEoZGV2KTsKCXN0cnVjdCBzM2MyNDEwZmJfaW5mbyAqaW5mbyA9IGZiaW5mby0+cGFyOwoKCXMzYzI0MTBmYl9zdG9wX2xjZCgpOwoKCS8qIHNsZWVwIGJlZm9yZSBkaXNhYmxpbmcgdGhlIGNsb2NrLCB3ZSBuZWVkIHRvIGVuc3VyZQoJICogdGhlIExDRCBETUEgZW5naW5lIGlzIG5vdCBnb2luZyB0byBnZXQgYmFjayBvbiB0aGUgYnVzCgkgKiBiZWZvcmUgdGhlIGNsb2NrIGdvZXMgb2ZmIGFnYWluIChiamQpICovCgoJbXNsZWVwKDEpOwoJY2xrX2Rpc2FibGUoaW5mby0+Y2xrKTsKCglyZXR1cm4gMDsKfQoKc3RhdGljIGludCBzM2MyNDEwZmJfcmVzdW1lKHN0cnVjdCBwbGF0Zm9ybV9kZXZpY2UgKmRldikKewoJc3RydWN0IGZiX2luZm8JICAgKmZiaW5mbyA9IHBsYXRmb3JtX2dldF9kcnZkYXRhKGRldik7CglzdHJ1Y3QgczNjMjQxMGZiX2luZm8gKmluZm8gPSBmYmluZm8tPnBhcjsKCgljbGtfZW5hYmxlKGluZm8tPmNsayk7Cgltc2xlZXAoMSk7CgoJczNjMjQxMGZiX2luaXRfcmVnaXN0ZXJzKGluZm8pOwoKCXJldHVybiAwOwp9CgojZWxzZQojZGVmaW5lIHMzYzI0MTBmYl9zdXNwZW5kIE5VTEwKI2RlZmluZSBzM2MyNDEwZmJfcmVzdW1lICBOVUxMCiNlbmRpZgoKc3RhdGljIHN0cnVjdCBwbGF0Zm9ybV9kcml2ZXIgczNjMjQxMGZiX2RyaXZlciA9IHsKCS5wcm9iZQkJPSBzM2MyNDEwZmJfcHJvYmUsCgkucmVtb3ZlCQk9IHMzYzI0MTBmYl9yZW1vdmUsCgkuc3VzcGVuZAk9IHMzYzI0MTBmYl9zdXNwZW5kLAoJLnJlc3VtZQkJPSBzM2MyNDEwZmJfcmVzdW1lLAoJLmRyaXZlcgkJPSB7CgkJLm5hbWUJPSAiczNjMjQxMC1sY2QiLAoJCS5vd25lcgk9IFRISVNfTU9EVUxFLAoJfSwKfTsKCmludCBfX2RldmluaXQgczNjMjQxMGZiX2luaXQodm9pZCkKewoJcmV0dXJuIHBsYXRmb3JtX2RyaXZlcl9yZWdpc3RlcigmczNjMjQxMGZiX2RyaXZlcik7Cn0KCnN0YXRpYyB2b2lkIF9fZXhpdCBzM2MyNDEwZmJfY2xlYW51cCh2b2lkKQp7CglwbGF0Zm9ybV9kcml2ZXJfdW5yZWdpc3RlcigmczNjMjQxMGZiX2RyaXZlcik7Cn0KCgptb2R1bGVfaW5pdChzM2MyNDEwZmJfaW5pdCk7Cm1vZHVsZV9leGl0KHMzYzI0MTBmYl9jbGVhbnVwKTsKCk1PRFVMRV9BVVRIT1IoIkFybmF1ZCBQYXRhcmQgPGFybmF1ZC5wYXRhcmRAcnRwLW5ldC5vcmc+LCBCZW4gRG9va3MgPGJlbi1saW51eEBmbHVmZi5vcmc+Iik7Ck1PRFVMRV9ERVNDUklQVElPTigiRnJhbWVidWZmZXIgZHJpdmVyIGZvciB0aGUgczNjMjQxMCIpOwpNT0RVTEVfTElDRU5TRSgiR1BMIik7Cg==