LyoKICogbGludXgvZHJpdmVycy92aWRlby9zM2MyNDEwZmIuYwogKglDb3B5cmlnaHQgKGMpIEFybmF1ZCBQYXRhcmQsIEJlbiBEb29rcwogKgogKiBUaGlzIGZpbGUgaXMgc3ViamVjdCB0byB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlLiAgU2VlIHRoZSBmaWxlIENPUFlJTkcgaW4gdGhlIG1haW4gZGlyZWN0b3J5IG9mIHRoaXMgYXJjaGl2ZSBmb3IKICogbW9yZSBkZXRhaWxzLgogKgogKgkgICAgUzNDMjQxMCBMQ0QgQ29udHJvbGxlciBGcmFtZSBCdWZmZXIgRHJpdmVyCiAqCSAgICBiYXNlZCBvbiBza2VsZXRvbmZiLmMsIHNhMTEwMGZiLmMgYW5kIG90aGVycwogKgogKiBDaGFuZ2VMb2cKICogMjAwNS0wNC0wNzogQXJuYXVkIFBhdGFyZCA8YXJuYXVkLnBhdGFyZEBydHAtbmV0Lm9yZz4KICogICAgICAtIHUzMiBzdGF0ZSAtPiBwbV9tZXNzYWdlX3Qgc3RhdGUKICogICAgICAtIFMzQzI0MTBfe1ZBLFNafV9MQ0QgLT4gUzNDMjRYWAogKgogKiAyMDA1LTAzLTE1OiBBcm5hdWQgUGF0YXJkIDxhcm5hdWQucGF0YXJkQHJ0cC1uZXQub3JnPgogKiAgICAgIC0gUmVtb3ZlZCB0aGUgaW9jdGwKICogICAgICAtIHVzZSByZWFkbC93cml0ZWwgaW5zdGVhZCBvZiBfX3Jhd193cml0ZWwvX19yYXdfcmVhZGwKICoKICogMjAwNC0xMi0wNDogQXJuYXVkIFBhdGFyZCA8YXJuYXVkLnBhdGFyZEBydHAtbmV0Lm9yZz4KICogICAgICAtIEFkZGVkIHRoZSBwb3NzaWJpbGl0eSB0byBzZXQgb24gb3Igb2ZmIHRoZQogKiAgICAgIGRlYnVnZ2luZyBtZXNhYWdlcwogKiAgICAgIC0gUmVwbGFjZWQgMCBhbmQgMSBieSBvbiBvciBvZmYgd2hlbiByZWFkaW5nIHRoZQogKiAgICAgIC9zeXMgZmlsZXMKICoKICogMjAwNS0wMy0yMzogQmVuIERvb2tzIDxiZW4tbGludXhAZmx1ZmYub3JnPgogKgktIGFkZGVkIG5vbiAxNmJwcCBtb2RlcwogKgktIHVwZGF0ZWQgcGxhdGZvcm0gaW5mb3JtYXRpb24gZm9yIHJhbmdlIG9mIHgveS9icHAKICoJLSBhZGQgY29kZSB0byBlbnN1cmUgcGFsZXR0ZSBpcyB3cml0dGVuIGNvcnJlY3RseQogKgktIGFkZCBwaXhlbCBjbG9jayBkaXZpc29yIGNvbnRyb2wKICoKICogMjAwNC0xMS0xMTogQXJuYXVkIFBhdGFyZCA8YXJuYXVkLnBhdGFyZEBydHAtbmV0Lm9yZz4KICogCS0gUmVtb3ZlZCB0aGUgdXNlIG9mIGN1cnJjb24gYXMgaXQgbm8gbW9yZSBleGlzdAogKiAJLSBBZGRlZCBMQ0QgcG93ZXIgc3lzZnMgaW50ZXJmYWNlCiAqCiAqIDIwMDQtMTEtMDM6IEJlbiBEb29rcyA8YmVuLWxpbnV4QGZsdWZmLm9yZz4KICoJLSBtaW5vciBjbGVhbnVwcwogKgktIGFkZCBzdXNwZW5kL3Jlc3VtZSBzdXBwb3J0CiAqCS0gczNjMjQxMGZiX3NldGNvbHJlZygpIG5vdCB2YWxpZCBpbiA+OGJwcCBtb2RlcwogKgktIHJlbW92ZWQgbGFzdCBDT05GSUdfRkJfUzNDMjQxMF9GSVhFRAogKgktIGVuc3VyZSBsY2QgY29udHJvbGxlciBzdG9wcGVkIGJlZm9yZSBjbGVhbnVwCiAqCS0gYWRkZWQgc3lzZnMgaW50ZXJmYWNlIGZvciBiYWNrbGlnaHQgcG93ZXIKICoJLSBhZGRlZCBtYXNrIGZvciBncGlvIGNvbmZpZ3VyYXRpb24KICoJLSBlbnN1cmVkIElSUXMgZGlzYWJsZWQgZHVyaW5nIEdQSU8gY29uZmlndXJhdGlvbgogKgktIGRpc2FibGUgVFBBTCBiZWZvcmUgZW5hYmxpbmcgdmlkZW8KICoKICogMjAwNC0wOS0yMDogQXJuYXVkIFBhdGFyZCA8YXJuYXVkLnBhdGFyZEBydHAtbmV0Lm9yZz4KICogICAgICAtIFN1cHByZXNzIGNvbW1hbmQgbGluZSBvcHRpb25zCiAqCiAqIDIwMDQtMDktMTU6IEFybmF1ZCBQYXRhcmQgPGFybmF1ZC5wYXRhcmRAcnRwLW5ldC5vcmc+CiAqIAktIGNvZGUgY2xlYW51cAogKgogKiAyMDA0LTA5LTA3OiBBcm5hdWQgUGF0YXJkIDxhcm5hdWQucGF0YXJkQHJ0cC1uZXQub3JnPgogKiAJLSBSZW5hbWVkIGZyb20gaDE5NDBmYi5jIHRvIHMzYzI0MTBmYi5jCiAqIAktIEFkZCBzdXBwb3J0IGZvciBkaWZmZXJlbnQgZGV2aWNlcwogKiAJLSBCYWNrbGlnaHQgc3VwcG9ydAogKgogKiAyMDA0LTA5LTA1OiBIZXJiZXJ0IFD2dHpsIDxoZXJiZXJ0QDEzdGhmbG9vci5hdD4KICoJLSBhZGRlZCBjbG9jayAoZGUtKWFsbG9jYXRpb24gY29kZQogKgktIGFkZGVkIGZpeGVtIGZibWVtIG9wdGlvbgogKgogKiAyMDA0LTA3LTI3OiBBcm5hdWQgUGF0YXJkIDxhcm5hdWQucGF0YXJkQHJ0cC1uZXQub3JnPgogKgktIGNvZGUgY2xlYW51cAogKgktIGFkZGVkIGEgZm9yZ290dGVuIHJldHVybiBpbiBoMTk0MGZiX2luaXQKICoKICogMjAwNC0wNy0xOTogSGVyYmVydCBQ9nR6bCA8aGVyYmVydEAxM3RoZmxvb3IuYXQ+CiAqCS0gY29kZSBjbGVhbnVwIGFuZCBleHRlbmRlZCBkZWJ1Z2dpbmcKICoKICogMjAwNC0wNy0xNTogQXJuYXVkIFBhdGFyZCA8YXJuYXVkLnBhdGFyZEBydHAtbmV0Lm9yZz4KICoJLSBGaXJzdCB2ZXJzaW9uCiAqLwoKI2luY2x1ZGUgPGxpbnV4L21vZHVsZS5oPgojaW5jbHVkZSA8bGludXgva2VybmVsLmg+CiNpbmNsdWRlIDxsaW51eC9lcnJuby5oPgojaW5jbHVkZSA8bGludXgvc3RyaW5nLmg+CiNpbmNsdWRlIDxsaW51eC9tbS5oPgojaW5jbHVkZSA8bGludXgvdHR5Lmg+CiNpbmNsdWRlIDxsaW51eC9zbGFiLmg+CiNpbmNsdWRlIDxsaW51eC9kZWxheS5oPgojaW5jbHVkZSA8bGludXgvZmIuaD4KI2luY2x1ZGUgPGxpbnV4L2luaXQuaD4KI2luY2x1ZGUgPGxpbnV4L2RtYS1tYXBwaW5nLmg+CiNpbmNsdWRlIDxsaW51eC9zdHJpbmcuaD4KI2luY2x1ZGUgPGxpbnV4L2ludGVycnVwdC5oPgojaW5jbHVkZSA8bGludXgvd29ya3F1ZXVlLmg+CiNpbmNsdWRlIDxsaW51eC93YWl0Lmg+CgojaW5jbHVkZSA8YXNtL2lvLmg+CiNpbmNsdWRlIDxhc20vdWFjY2Vzcy5oPgojaW5jbHVkZSA8YXNtL2RpdjY0Lmg+CgojaW5jbHVkZSA8YXNtL21hY2gvbWFwLmg+CiNpbmNsdWRlIDxhc20vYXJjaC9yZWdzLWxjZC5oPgojaW5jbHVkZSA8YXNtL2FyY2gvcmVncy1ncGlvLmg+CiNpbmNsdWRlIDxhc20vYXJjaC9mYi5oPgojaW5jbHVkZSA8YXNtL2hhcmR3YXJlL2Nsb2NrLmg+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+dHJhbnNwLmxlbmd0aAk9IDA7Cgl9CgoJcmV0dXJuIDA7Cn0KCi8qIHMzYzI0MTBmYl9hY3RpdmF0ZV92YXIKICoKICogYWN0aXZhdGUgKHNldCkgdGhlIGNvbnRyb2xsZXIgZnJvbSB0aGUgZ2l2ZW4gZnJhbWVidWZmZXIKICogaW5mb3JtYXRpb24KKi8KCnN0YXRpYyBpbnQgczNjMjQxMGZiX2FjdGl2YXRlX3ZhcihzdHJ1Y3QgczNjMjQxMGZiX2luZm8gKmZiaSwKCQkJCSAgc3RydWN0IGZiX3Zhcl9zY3JlZW5pbmZvICp2YXIpCnsKCWZiaS0+cmVncy5sY2Rjb24xICY9IH5TM0MyNDEwX0xDRENPTjFfTU9ERU1BU0s7CgoJZHByaW50aygiJXM6IHZhci0+eHJlcyAgPSAlZFxuIiwgX19GVU5DVElPTl9fLCB2YXItPnhyZXMpOwoJZHByaW50aygiJXM6IHZhci0+eXJlcyAgPSAlZFxuIiwgX19GVU5DVElPTl9fLCB2YXItPnlyZXMpOwoJZHByaW50aygiJXM6IHZhci0+YnBwICAgPSAlZFxuIiwgX19GVU5DVElPTl9fLCB2YXItPmJpdHNfcGVyX3BpeGVsKTsKCglzd2l0Y2ggKHZhci0+Yml0c19wZXJfcGl4ZWwpIHsKCWNhc2UgMToKCQlmYmktPnJlZ3MubGNkY29uMSB8PSBTM0MyNDEwX0xDRENPTjFfVEZUMUJQUDsKCQlicmVhazsKCWNhc2UgMjoKCQlmYmktPnJlZ3MubGNkY29uMSB8PSBTM0MyNDEwX0xDRENPTjFfVEZUMkJQUDsKCQlicmVhazsKCWNhc2UgNDoKCQlmYmktPnJlZ3MubGNkY29uMSB8PSBTM0MyNDEwX0xDRENPTjFfVEZUNEJQUDsKCQlicmVhazsKCWNhc2UgODoKCQlmYmktPnJlZ3MubGNkY29uMSB8PSBTM0MyNDEwX0xDRENPTjFfVEZUOEJQUDsKCQlicmVhazsKCWNhc2UgMTY6CgkJZmJpLT5yZWdzLmxjZGNvbjEgfD0gUzNDMjQxMF9MQ0RDT04xX1RGVDE2QlBQOwoJCWJyZWFrOwoJfQoKCS8qIGNoZWNrIHRvIHNlZSBpZiB3ZSBuZWVkIHRvIHVwZGF0ZSBzeW5jL2JvcmRlcnMgKi8KCglpZiAoIWZiaS0+bWFjaF9pbmZvLT5maXhlZF9zeW5jcykgewoJCWRwcmludGsoInNldHRpbmcgdmVydDogdXA9JWQsIGxvdz0lZCwgc3luYz0lZFxuIiwKCQkJdmFyLT51cHBlcl9tYXJnaW4sIHZhci0+bG93ZXJfbWFyZ2luLAoJCQl2YXItPnZzeW5jX2xlbik7CgoJCWRwcmludGsoInNldHRpbmcgaG9yejogbGZ0PSVkLCBydD0lZCwgc3luYz0lZFxuIiwKCQkJdmFyLT5sZWZ0X21hcmdpbiwgdmFyLT5yaWdodF9tYXJnaW4sCgkJCXZhci0+aHN5bmNfbGVuKTsKCgkJZmJpLT5yZWdzLmxjZGNvbjIgPQoJCQlTM0MyNDEwX0xDRENPTjJfVkJQRCh2YXItPnVwcGVyX21hcmdpbiAtIDEpIHwKCQkJUzNDMjQxMF9MQ0RDT04yX1ZGUEQodmFyLT5sb3dlcl9tYXJnaW4gLSAxKSB8CgkJCVMzQzI0MTBfTENEQ09OMl9WU1BXKHZhci0+dnN5bmNfbGVuIC0gMSk7CgoJCWZiaS0+cmVncy5sY2Rjb24zID0KCQkJUzNDMjQxMF9MQ0RDT04zX0hCUEQodmFyLT5yaWdodF9tYXJnaW4gLSAxKSB8CgkJCVMzQzI0MTBfTENEQ09OM19IRlBEKHZhci0+bGVmdF9tYXJnaW4gLSAxKTsKCgkJZmJpLT5yZWdzLmxjZGNvbjQgJj0gflMzQzI0MTBfTENEQ09ONF9IU1BXKDB4ZmYpOwoJCWZiaS0+cmVncy5sY2Rjb240IHw9ICBTM0MyNDEwX0xDRENPTjRfSFNQVyh2YXItPmhzeW5jX2xlbiAtIDEpOwoJfQoKCS8qIHVwZGF0ZSBYL1kgaW5mbyAqLwoKCWZiaS0+cmVncy5sY2Rjb24yICY9IH5TM0MyNDEwX0xDRENPTjJfTElORVZBTCgweDNmZik7CglmYmktPnJlZ3MubGNkY29uMiB8PSAgUzNDMjQxMF9MQ0RDT04yX0xJTkVWQUwodmFyLT55cmVzIC0gMSk7CgoJZmJpLT5yZWdzLmxjZGNvbjMgJj0gflMzQzI0MTBfTENEQ09OM19IT1pWQUwoMHg3ZmYpOwoJZmJpLT5yZWdzLmxjZGNvbjMgfD0gIFMzQzI0MTBfTENEQ09OM19IT1pWQUwodmFyLT54cmVzIC0gMSk7CgoJaWYgKHZhci0+cGl4Y2xvY2sgPiAwKSB7CgkJaW50IGNsa2RpdiA9IHMzYzI0MTBmYl9jYWxjX3BpeGNsayhmYmksIHZhci0+cGl4Y2xvY2spOwoKCQljbGtkaXYgPSAoY2xrZGl2IC8gMikgLTE7CgkJaWYgKGNsa2RpdiA8IDApCgkJCWNsa2RpdiA9IDA7CgoJCWZiaS0+cmVncy5sY2Rjb24xICY9IH5TM0MyNDEwX0xDRENPTjFfQ0xLVkFMKDB4M2ZmKTsKCQlmYmktPnJlZ3MubGNkY29uMSB8PSAgUzNDMjQxMF9MQ0RDT04xX0NMS1ZBTChjbGtkaXYpOwoJfQoKCS8qIHdyaXRlIG5ldyByZWdpc3RlcnMgKi8KCglkcHJpbnRrKCJuZXcgcmVnaXN0ZXIgc2V0OlxuIik7CglkcHJpbnRrKCJsY2Rjb25bMV0gPSAweCUwOGx4XG4iLCBmYmktPnJlZ3MubGNkY29uMSk7CglkcHJpbnRrKCJsY2Rjb25bMl0gPSAweCUwOGx4XG4iLCBmYmktPnJlZ3MubGNkY29uMik7CglkcHJpbnRrKCJsY2Rjb25bM10gPSAweCUwOGx4XG4iLCBmYmktPnJlZ3MubGNkY29uMyk7CglkcHJpbnRrKCJsY2Rjb25bNF0gPSAweCUwOGx4XG4iLCBmYmktPnJlZ3MubGNkY29uNCk7CglkcHJpbnRrKCJsY2Rjb25bNV0gPSAweCUwOGx4XG4iLCBmYmktPnJlZ3MubGNkY29uNSk7CgoJd3JpdGVsKGZiaS0+cmVncy5sY2Rjb24xICYgflMzQzI0MTBfTENEQ09OMV9FTlZJRCwgUzNDMjQxMF9MQ0RDT04xKTsKCXdyaXRlbChmYmktPnJlZ3MubGNkY29uMiwgUzNDMjQxMF9MQ0RDT04yKTsKCXdyaXRlbChmYmktPnJlZ3MubGNkY29uMywgUzNDMjQxMF9MQ0RDT04zKTsKCXdyaXRlbChmYmktPnJlZ3MubGNkY29uNCwgUzNDMjQxMF9MQ0RDT040KTsKCXdyaXRlbChmYmktPnJlZ3MubGNkY29uNSwgUzNDMjQxMF9MQ0RDT041KTsKCgkvKiBzZXQgbGNkIGFkZHJlc3MgcG9pbnRlcnMgKi8KCXMzYzI0MTBmYl9zZXRfbGNkYWRkcihmYmkpOwoKCXdyaXRlbChmYmktPnJlZ3MubGNkY29uMSwgUzNDMjQxMF9MQ0RDT04xKTsKfQoKCi8qCiAqICAgICAgczNjMjQxMGZiX3NldF9wYXIgLSBPcHRpb25hbCBmdW5jdGlvbi4gQWx0ZXJzIHRoZSBoYXJkd2FyZSBzdGF0ZS4KICogICAgICBAaW5mbzogZnJhbWUgYnVmZmVyIHN0cnVjdHVyZSB0aGF0IHJlcHJlc2VudHMgYSBzaW5nbGUgZnJhbWUgYnVmZmVyCiAqCiAqLwpzdGF0aWMgaW50IHMzYzI0MTBmYl9zZXRfcGFyKHN0cnVjdCBmYl9pbmZvICppbmZvKQp7CglzdHJ1Y3QgczNjMjQxMGZiX2luZm8gKmZiaSA9IGluZm8tPnBhcjsKCXN0cnVjdCBmYl92YXJfc2NyZWVuaW5mbyAqdmFyID0gJmluZm8tPnZhcjsKCglpZiAodmFyLT5iaXRzX3Blcl9waXhlbCA9PSAxNikKCQlmYmktPmZiLT5maXgudmlzdWFsID0gRkJfVklTVUFMX1RSVUVDT0xPUjsKCWVsc2UKCQlmYmktPmZiLT5maXgudmlzdWFsID0gRkJfVklTVUFMX1BTRVVET0NPTE9SOwoKCWZiaS0+ZmItPmZpeC5saW5lX2xlbmd0aCAgICAgPSAodmFyLT53aWR0aCp2YXItPmJpdHNfcGVyX3BpeGVsKS84OwoKCS8qIGFjdGl2YXRlIHRoaXMgbmV3IGNvbmZpZ3VyYXRpb24gKi8KCglzM2MyNDEwZmJfYWN0aXZhdGVfdmFyKGZiaSwgdmFyKTsKCXJldHVybiAwOwp9CgpzdGF0aWMgdm9pZCBzY2hlZHVsZV9wYWxldHRlX3VwZGF0ZShzdHJ1Y3QgczNjMjQxMGZiX2luZm8gKmZiaSwKCQkJCSAgICB1bnNpZ25lZCBpbnQgcmVnbm8sIHVuc2lnbmVkIGludCB2YWwpCnsKCXVuc2lnbmVkIGxvbmcgZmxhZ3M7Cgl1bnNpZ25lZCBsb25nIGlycWVuOwoKCWxvY2FsX2lycV9zYXZlKGZsYWdzKTsKCglmYmktPnBhbGV0dGVfYnVmZmVyW3JlZ25vXSA9IHZhbDsKCglpZiAoIWZiaS0+cGFsZXR0ZV9yZWFkeSkgewoJCWZiaS0+cGFsZXR0ZV9yZWFkeSA9IDE7CgoJCS8qIGVuYWJsZSBJUlEgKi8KCQlpcnFlbiA9IHJlYWRsKFMzQzI0MTBfTENESU5UTVNLKTsKCQlpcnFlbiAmPSB+UzNDMjQxMF9MQ0RJTlRfRlJTWU5DOwoJCXdyaXRlbChpcnFlbiwgUzNDMjQxMF9MQ0RJTlRNU0spOwoJfQoKCWxvY2FsX2lycV9yZXN0b3JlKGZsYWdzKTsKfQoKLyogZnJvbSBweGFmYi5jICovCnN0YXRpYyBpbmxpbmUgdW5zaWduZWQgaW50IGNoYW5fdG9fZmllbGQodW5zaWduZWQgaW50IGNoYW4sIHN0cnVjdCBmYl9iaXRmaWVsZCAqYmYpCnsKCWNoYW4gJj0gMHhmZmZmOwoJY2hhbiA+Pj0gMTYgLSBiZi0+bGVuZ3RoOwoJcmV0dXJuIGNoYW4gPDwgYmYtPm9mZnNldDsKfQoKc3RhdGljIGludCBzM2MyNDEwZmJfc2V0Y29scmVnKHVuc2lnbmVkIHJlZ25vLAoJCQkgICAgICAgdW5zaWduZWQgcmVkLCB1bnNpZ25lZCBncmVlbiwgdW5zaWduZWQgYmx1ZSwKCQkJICAgICAgIHVuc2lnbmVkIHRyYW5zcCwgc3RydWN0IGZiX2luZm8gKmluZm8pCnsKCXN0cnVjdCBzM2MyNDEwZmJfaW5mbyAqZmJpID0gaW5mby0+cGFyOwoJdW5zaWduZWQgaW50IHZhbDsKCgkvKiBkcHJpbnRrKCJzZXRjb2w6IHJlZ25vPSVkLCByZ2I9JWQsJWQsJWRcbiIsIHJlZ25vLCByZWQsIGdyZWVuLCBibHVlKTsgKi8KCglzd2l0Y2ggKGZiaS0+ZmItPmZpeC52aXN1YWwpIHsKCWNhc2UgRkJfVklTVUFMX1RSVUVDT0xPUjoKCQkvKiB0cnVlLWNvbG91ciwgdXNlIHBzZXVvLXBhbGV0dGUgKi8KCgkJaWYgKHJlZ25vIDwgMTYpIHsKCQkJdTMyICpwYWwgPSBmYmktPmZiLT5wc2V1ZG9fcGFsZXR0ZTsKCgkJCXZhbCAgPSBjaGFuX3RvX2ZpZWxkKHJlZCwgICAmZmJpLT5mYi0+dmFyLnJlZCk7CgkJCXZhbCB8PSBjaGFuX3RvX2ZpZWxkKGdyZWVuLCAmZmJpLT5mYi0+dmFyLmdyZWVuKTsKCQkJdmFsIHw9IGNoYW5fdG9fZmllbGQoYmx1ZSwgICZmYmktPmZiLT52YXIuYmx1ZSk7CgoJCQlwYWxbcmVnbm9dID0gdmFsOwoJCX0KCQlicmVhazsKCgljYXNlIEZCX1ZJU1VBTF9QU0VVRE9DT0xPUjoKCQlpZiAocmVnbm8gPCAyNTYpIHsKCQkJLyogY3VycmVudGx5IGFzc3VtZSBSR0IgNS02LTUgbW9kZSAqLwoKCQkJdmFsICA9ICgocmVkICAgPj4gIDApICYgMHhmODAwKTsKCQkJdmFsIHw9ICgoZ3JlZW4gPj4gIDUpICYgMHgwN2UwKTsKCQkJdmFsIHw9ICgoYmx1ZSAgPj4gMTEpICYgMHgwMDFmKTsKCgkJCXdyaXRlbCh2YWwsIFMzQzI0MTBfVEZUUEFMKHJlZ25vKSk7CgkJCXNjaGVkdWxlX3BhbGV0dGVfdXBkYXRlKGZiaSwgcmVnbm8sIHZhbCk7CgkJfQoKCQlicmVhazsKCglkZWZhdWx0OgoJCXJldHVybiAxOyAgIC8qIHVua25vd24gdHlwZSAqLwoJfQoKCXJldHVybiAwOwp9CgoKLyoqCiAqICAgICAgczNjMjQxMGZiX2JsYW5rCiAqCUBibGFua19tb2RlOiB0aGUgYmxhbmsgbW9kZSB3ZSB3YW50LgogKglAaW5mbzogZnJhbWUgYnVmZmVyIHN0cnVjdHVyZSB0aGF0IHJlcHJlc2VudHMgYSBzaW5nbGUgZnJhbWUgYnVmZmVyCiAqCiAqCUJsYW5rIHRoZSBzY3JlZW4gaWYgYmxhbmtfbW9kZSAhPSAwLCBlbHNlIHVuYmxhbmsuIFJldHVybiAwIGlmCiAqCWJsYW5raW5nIHN1Y2NlZWRlZCwgIT0gMCBpZiB1bi0vYmxhbmtpbmcgZmFpbGVkIGR1ZSB0byBlLmcuIGEKICoJdmlkZW8gbW9kZSB3aGljaCBkb2Vzbid0IHN1cHBvcnQgaXQuIEltcGxlbWVudHMgVkVTQSBzdXNwZW5kCiAqCWFuZCBwb3dlcmRvd24gbW9kZXMgb24gaGFyZHdhcmUgdGhhdCBzdXBwb3J0cyBkaXNhYmxpbmcgaHN5bmMvdnN5bmM6CiAqCWJsYW5rX21vZGUgPT0gMjogc3VzcGVuZCB2c3luYwogKglibGFua19tb2RlID09IDM6IHN1c3BlbmQgaHN5bmMKICoJYmxhbmtfbW9kZSA9PSA0OiBwb3dlcmRvd24KICoKICoJUmV0dXJucyBuZWdhdGl2ZSBlcnJubyBvbiBlcnJvciwgb3IgemVybyBvbiBzdWNjZXNzLgogKgogKi8Kc3RhdGljIGludCBzM2MyNDEwZmJfYmxhbmsoaW50IGJsYW5rX21vZGUsIHN0cnVjdCBmYl9pbmZvICppbmZvKQp7CglkcHJpbnRrKCJibGFuayhtb2RlPSVkLCBpbmZvPSVwKVxuIiwgYmxhbmtfbW9kZSwgaW5mbyk7CgoJaWYgKG1hY2hfaW5mbyA9PSBOVUxMKQoJCXJldHVybiAtRUlOVkFMOwoKCWlmIChibGFua19tb2RlID09IEZCX0JMQU5LX1VOQkxBTkspCgkJd3JpdGVsKDB4MCwgUzNDMjQxMF9UUEFMKTsKCWVsc2UgewoJCWRwcmludGsoInNldHRpbmcgVFBBTCB0byBvdXRwdXQgMHgwMDAwMDBcbiIpOwoJCXdyaXRlbChTM0MyNDEwX1RQQUxfRU4sIFMzQzI0MTBfVFBBTCk7Cgl9CgoJcmV0dXJuIDA7Cn0KCnN0YXRpYyBpbnQgczNjMjQxMGZiX2RlYnVnX3Nob3coc3RydWN0IGRldmljZSAqZGV2LCBzdHJ1Y3QgZGV2aWNlX2F0dHJpYnV0ZSAqYXR0ciwgY2hhciAqYnVmKQp7CglyZXR1cm4gc25wcmludGYoYnVmLCBQQUdFX1NJWkUsICIlc1xuIiwgZGVidWcgPyAib24iIDogIm9mZiIpOwp9CnN0YXRpYyBpbnQgczNjMjQxMGZiX2RlYnVnX3N0b3JlKHN0cnVjdCBkZXZpY2UgKmRldiwgc3RydWN0IGRldmljZV9hdHRyaWJ1dGUgKmF0dHIsCgkJCQkJICAgY29uc3QgY2hhciAqYnVmLCBzaXplX3QgbGVuKQp7CglpZiAobWFjaF9pbmZvID09IE5VTEwpCgkJcmV0dXJuIC1FSU5WQUw7CgoJaWYgKGxlbiA8IDEpCgkJcmV0dXJuIC1FSU5WQUw7CgoJaWYgKHN0cm5pY21wKGJ1ZiwgIm9uIiwgMikgPT0gMCB8fAoJICAgIHN0cm5pY21wKGJ1ZiwgIjEiLCAxKSA9PSAwKSB7CgkJZGVidWcgPSAxOwoJCXByaW50ayhLRVJOX0RFQlVHICJzM2MyNDEwZmI6IERlYnVnIE9uIik7Cgl9IGVsc2UgaWYgKHN0cm5pY21wKGJ1ZiwgIm9mZiIsIDMpID09IDAgfHwKCQkgICBzdHJuaWNtcChidWYsICIwIiwgMSkgPT0gMCkgewoJCWRlYnVnID0gMDsKCQlwcmludGsoS0VSTl9ERUJVRyAiczNjMjQxMGZiOiBEZWJ1ZyBPZmYiKTsKCX0gZWxzZSB7CgkJcmV0dXJuIC1FSU5WQUw7Cgl9CgoJcmV0dXJuIGxlbjsKfQoKCnN0YXRpYyBERVZJQ0VfQVRUUihkZWJ1ZywgMDY2NiwKCQkgICBzM2MyNDEwZmJfZGVidWdfc2hvdywKCQkgICBzM2MyNDEwZmJfZGVidWdfc3RvcmUpOwoKc3RhdGljIHN0cnVjdCBmYl9vcHMgczNjMjQxMGZiX29wcyA9IHsKCS5vd25lcgkJPSBUSElTX01PRFVMRSwKCS5mYl9jaGVja192YXIJPSBzM2MyNDEwZmJfY2hlY2tfdmFyLAoJLmZiX3NldF9wYXIJPSBzM2MyNDEwZmJfc2V0X3BhciwKCS5mYl9ibGFuawk9IHMzYzI0MTBmYl9ibGFuaywKCS5mYl9zZXRjb2xyZWcJPSBzM2MyNDEwZmJfc2V0Y29scmVnLAoJLmZiX2ZpbGxyZWN0CT0gY2ZiX2ZpbGxyZWN0LAoJLmZiX2NvcHlhcmVhCT0gY2ZiX2NvcHlhcmVhLAoJLmZiX2ltYWdlYmxpdAk9IGNmYl9pbWFnZWJsaXQsCgkuZmJfY3Vyc29yCT0gc29mdF9jdXJzb3IsCn07CgoKLyoKICogczNjMjQxMGZiX21hcF92aWRlb19tZW1vcnkoKToKICoJQWxsb2NhdGVzIHRoZSBEUkFNIG1lbW9yeSBmb3IgdGhlIGZyYW1lIGJ1ZmZlci4gIFRoaXMgYnVmZmVyIGlzCiAqCXJlbWFwcGVkIGludG8gYSBub24tY2FjaGVkLCBub24tYnVmZmVyZWQsIG1lbW9yeSByZWdpb24gdG8KICoJYWxsb3cgcGFsZXR0ZSBhbmQgcGl4ZWwgd3JpdGVzIHRvIG9jY3VyIHdpdGhvdXQgZmx1c2hpbmcgdGhlCiAqCWNhY2hlLiAgT25jZSB0aGlzIGFyZWEgaXMgcmVtYXBwZWQsIGFsbCB2aXJ0dWFsIG1lbW9yeQogKglhY2Nlc3MgdG8gdGhlIHZpZGVvIG1lbW9yeSBzaG91bGQgb2NjdXIgYXQgdGhlIG5ldyByZWdpb24uCiAqLwpzdGF0aWMgaW50IF9faW5pdCBzM2MyNDEwZmJfbWFwX3ZpZGVvX21lbW9yeShzdHJ1Y3QgczNjMjQxMGZiX2luZm8gKmZiaSkKewoJZHByaW50aygibWFwX3ZpZGVvX21lbW9yeShmYmk9JXApXG4iLCBmYmkpOwoKCWZiaS0+bWFwX3NpemUgPSBQQUdFX0FMSUdOKGZiaS0+ZmItPmZpeC5zbWVtX2xlbiArIFBBR0VfU0laRSk7CglmYmktPm1hcF9jcHUgID0gZG1hX2FsbG9jX3dyaXRlY29tYmluZShmYmktPmRldiwgZmJpLT5tYXBfc2l6ZSwKCQkJCQkgICAgICAgJmZiaS0+bWFwX2RtYSwgR0ZQX0tFUk5FTCk7CgoJZmJpLT5tYXBfc2l6ZSA9IGZiaS0+ZmItPmZpeC5zbWVtX2xlbjsKCglpZiAoZmJpLT5tYXBfY3B1KSB7CgkJLyogcHJldmVudCBpbml0aWFsIGdhcmJhZ2Ugb24gc2NyZWVuICovCgkJZHByaW50aygibWFwX3ZpZGVvX21lbW9yeTogY2xlYXIgJXA6JTA4eFxuIiwKCQkJZmJpLT5tYXBfY3B1LCBmYmktPm1hcF9zaXplKTsKCQltZW1zZXQoZmJpLT5tYXBfY3B1LCAweGYwLCBmYmktPm1hcF9zaXplKTsKCgkJZmJpLT5zY3JlZW5fZG1hCQk9IGZiaS0+bWFwX2RtYTsKCQlmYmktPmZiLT5zY3JlZW5fYmFzZQk9IGZiaS0+bWFwX2NwdTsKCQlmYmktPmZiLT5maXguc21lbV9zdGFydCAgPSBmYmktPnNjcmVlbl9kbWE7CgoJCWRwcmludGsoIm1hcF92aWRlb19tZW1vcnk6IGRtYT0lMDh4IGNwdT0lcCBzaXplPSUwOHhcbiIsCgkJCWZiaS0+bWFwX2RtYSwgZmJpLT5tYXBfY3B1LCBmYmktPmZiLT5maXguc21lbV9sZW4pOwoJfQoKCXJldHVybiBmYmktPm1hcF9jcHUgPyAwIDogLUVOT01FTTsKfQoKc3RhdGljIGlubGluZSB2b2lkIHMzYzI0MTBmYl91bm1hcF92aWRlb19tZW1vcnkoc3RydWN0IHMzYzI0MTBmYl9pbmZvICpmYmkpCnsKCWRtYV9mcmVlX3dyaXRlY29tYmluZShmYmktPmRldixmYmktPm1hcF9zaXplLGZiaS0+bWFwX2NwdSwgZmJpLT5tYXBfZG1hKTsKfQoKc3RhdGljIGlubGluZSB2b2lkIG1vZGlmeV9ncGlvKHZvaWQgX19pb21lbSAqcmVnLAoJCQkgICAgICAgdW5zaWduZWQgbG9uZyBzZXQsIHVuc2lnbmVkIGxvbmcgbWFzaykKewoJdW5zaWduZWQgbG9uZyB0bXA7CgoJdG1wID0gcmVhZGwocmVnKSAmIH5tYXNrOwoJd3JpdGVsKHRtcCB8IHNldCwgcmVnKTsKfQoKCi8qCiAqIHMzYzI0MTBmYl9pbml0X3JlZ2lzdGVycyAtIEluaXRpYWxpc2UgYWxsIExDRC1yZWxhdGVkIHJlZ2lzdGVycwogKi8KCmludCBzM2MyNDEwZmJfaW5pdF9yZWdpc3RlcnMoc3RydWN0IHMzYzI0MTBmYl9pbmZvICpmYmkpCnsKCXVuc2lnbmVkIGxvbmcgZmxhZ3M7CgoJLyogSW5pdGlhbGlzZSBMQ0Qgd2l0aCB2YWx1ZXMgZnJvbSBoYXJldCAqLwoKCWxvY2FsX2lycV9zYXZlKGZsYWdzKTsKCgkvKiBtb2RpZnkgdGhlIGdwaW8ocykgd2l0aCBpbnRlcnJ1cHRzIHNldCAoYmpkKSAqLwoKCW1vZGlmeV9ncGlvKFMzQzI0MTBfR1BDVVAsICBtYWNoX2luZm8tPmdwY3VwLCAgbWFjaF9pbmZvLT5ncGN1cF9tYXNrKTsKCW1vZGlmeV9ncGlvKFMzQzI0MTBfR1BDQ09OLCBtYWNoX2luZm8tPmdwY2NvbiwgbWFjaF9pbmZvLT5ncGNjb25fbWFzayk7Cgltb2RpZnlfZ3BpbyhTM0MyNDEwX0dQRFVQLCAgbWFjaF9pbmZvLT5ncGR1cCwgIG1hY2hfaW5mby0+Z3BkdXBfbWFzayk7Cgltb2RpZnlfZ3BpbyhTM0MyNDEwX0dQRENPTiwgbWFjaF9pbmZvLT5ncGRjb24sIG1hY2hfaW5mby0+Z3BkY29uX21hc2spOwoKCWxvY2FsX2lycV9yZXN0b3JlKGZsYWdzKTsKCgl3cml0ZWwoZmJpLT5yZWdzLmxjZGNvbjEsIFMzQzI0MTBfTENEQ09OMSk7Cgl3cml0ZWwoZmJpLT5yZWdzLmxjZGNvbjIsIFMzQzI0MTBfTENEQ09OMik7Cgl3cml0ZWwoZmJpLT5yZWdzLmxjZGNvbjMsIFMzQzI0MTBfTENEQ09OMyk7Cgl3cml0ZWwoZmJpLT5yZWdzLmxjZGNvbjQsIFMzQzI0MTBfTENEQ09ONCk7Cgl3cml0ZWwoZmJpLT5yZWdzLmxjZGNvbjUsIFMzQzI0MTBfTENEQ09ONSk7CgogCXMzYzI0MTBmYl9zZXRfbGNkYWRkcihmYmkpOwoKCWRwcmludGsoIkxQQ1NFTCAgICA9IDB4JTA4bHhcbiIsIG1hY2hfaW5mby0+bHBjc2VsKTsKCXdyaXRlbChtYWNoX2luZm8tPmxwY3NlbCwgUzNDMjQxMF9MUENTRUwpOwoKCWRwcmludGsoInJlcGxhY2luZyBUUEFMICUwOHhcbiIsIHJlYWRsKFMzQzI0MTBfVFBBTCkpOwoKCS8qIGVuc3VyZSB0ZW1wb3JhcnkgcGFsZXR0ZSBkaXNhYmxlZCAqLwoJd3JpdGVsKDB4MDAsIFMzQzI0MTBfVFBBTCk7CgoJLyogRW5hYmxlIHZpZGVvIGJ5IHNldHRpbmcgdGhlIEVOVklEIGJpdCB0byAxICovCglmYmktPnJlZ3MubGNkY29uMSB8PSBTM0MyNDEwX0xDRENPTjFfRU5WSUQ7Cgl3cml0ZWwoZmJpLT5yZWdzLmxjZGNvbjEsIFMzQzI0MTBfTENEQ09OMSk7CglyZXR1cm4gMDsKfQoKc3RhdGljIHZvaWQgczNjMjQxMGZiX3dyaXRlX3BhbGV0dGUoc3RydWN0IHMzYzI0MTBmYl9pbmZvICpmYmkpCnsKCXVuc2lnbmVkIGludCBpOwoJdW5zaWduZWQgbG9uZyBlbnQ7CgoJZmJpLT5wYWxldHRlX3JlYWR5ID0gMDsKCglmb3IgKGkgPSAwOyBpIDwgMjU2OyBpKyspIHsKCQlpZiAoKGVudCA9IGZiaS0+cGFsZXR0ZV9idWZmZXJbaV0pID09IFBBTEVUVEVfQlVGRl9DTEVBUikKCQkJY29udGludWU7CgoJCXdyaXRlbChlbnQsIFMzQzI0MTBfVEZUUEFMKGkpKTsKCgkJLyogaXQgc2VlbXMgdGhlIG9ubHkgd2F5IHRvIGtub3cgZXhhY3RseQoJCSAqIGlmIHRoZSBwYWxldHRlIHdyb3RlIG9rLCBpcyB0byBjaGVjawoJCSAqIHRvIHNlZSBpZiB0aGUgdmFsdWUgdmVyaWZpZXMgb2sKCQkgKi8KCgkJaWYgKHJlYWR3KFMzQzI0MTBfVEZUUEFMKGkpKSA9PSBlbnQpCgkJCWZiaS0+cGFsZXR0ZV9idWZmZXJbaV0gPSBQQUxFVFRFX0JVRkZfQ0xFQVI7CgkJZWxzZQoJCQlmYmktPnBhbGV0dGVfcmVhZHkgPSAxOyAgIC8qIHJldHJ5ICovCgl9Cn0KCnN0YXRpYyBpcnFyZXR1cm5fdCBzM2MyNDEwZmJfaXJxKGludCBpcnEsIHZvaWQgKmRldl9pZCwgc3RydWN0IHB0X3JlZ3MgKnIpCnsKCXN0cnVjdCBzM2MyNDEwZmJfaW5mbyAqZmJpID0gZGV2X2lkOwoJdW5zaWduZWQgbG9uZyBsY2RpcnEgPSByZWFkbChTM0MyNDEwX0xDRElOVFBORCk7CgoJaWYgKGxjZGlycSAmIFMzQzI0MTBfTENESU5UX0ZSU1lOQykgewoJCWlmIChmYmktPnBhbGV0dGVfcmVhZHkpCgkJCXMzYzI0MTBmYl93cml0ZV9wYWxldHRlKGZiaSk7CgoJCXdyaXRlbChTM0MyNDEwX0xDRElOVF9GUlNZTkMsIFMzQzI0MTBfTENESU5UUE5EKTsKCQl3cml0ZWwoUzNDMjQxMF9MQ0RJTlRfRlJTWU5DLCBTM0MyNDEwX0xDRFNSQ1BORCk7Cgl9CgoJcmV0dXJuIElSUV9IQU5ETEVEOwp9CgpzdGF0aWMgY2hhciBkcml2ZXJfbmFtZVtdPSJzM2MyNDEwZmIiOwoKaW50IF9faW5pdCBzM2MyNDEwZmJfcHJvYmUoc3RydWN0IGRldmljZSAqZGV2KQp7CglzdHJ1Y3QgczNjMjQxMGZiX2luZm8gKmluZm87CglzdHJ1Y3QgZmJfaW5mbwkgICAqZmJpbmZvOwoJc3RydWN0IHBsYXRmb3JtX2RldmljZSAqcGRldiA9IHRvX3BsYXRmb3JtX2RldmljZShkZXYpOwoJc3RydWN0IHMzYzI0MTBmYl9odyAqbXJlZ3M7CglpbnQgcmV0OwoJaW50IGlycTsKCWludCBpOwoKCW1hY2hfaW5mbyA9IGRldi0+cGxhdGZvcm1fZGF0YTsKCWlmIChtYWNoX2luZm8gPT0gTlVMTCkgewoJCWRldl9lcnIoZGV2LCJubyBwbGF0Zm9ybSBkYXRhIGZvciBsY2QsIGNhbm5vdCBhdHRhY2hcbiIpOwoJCXJldHVybiAtRUlOVkFMOwoJfQoKCW1yZWdzID0gJm1hY2hfaW5mby0+cmVnczsKCglpcnEgPSBwbGF0Zm9ybV9nZXRfaXJxKHBkZXYsIDApOwoJaWYgKGlycSA8IDApIHsKCQlkZXZfZXJyKGRldiwgIm5vIGlycSBmb3IgZGV2aWNlXG4iKTsKCQlyZXR1cm4gLUVOT0VOVDsKCX0KCglmYmluZm8gPSBmcmFtZWJ1ZmZlcl9hbGxvYyhzaXplb2Yoc3RydWN0IHMzYzI0MTBmYl9pbmZvKSwgZGV2KTsKCWlmICghZmJpbmZvKSB7CgkJcmV0dXJuIC1FTk9NRU07Cgl9CgoKCWluZm8gPSBmYmluZm8tPnBhcjsKCWluZm8tPmZiID0gZmJpbmZvOwoJZGV2X3NldF9kcnZkYXRhKGRldiwgZmJpbmZvKTsKCglzM2MyNDEwZmJfaW5pdF9yZWdpc3RlcnMoaW5mbyk7CgoJZHByaW50aygiZGV2aW5pdFxuIik7CgoJc3RyY3B5KGZiaW5mby0+Zml4LmlkLCBkcml2ZXJfbmFtZSk7CgoJbWVtY3B5KCZpbmZvLT5yZWdzLCAmbWFjaF9pbmZvLT5yZWdzLCBzaXplb2YoaW5mby0+cmVncykpOwoKCWluZm8tPm1hY2hfaW5mbwkJICAgID0gZGV2LT5wbGF0Zm9ybV9kYXRhOwoKCWZiaW5mby0+Zml4LnR5cGUJICAgID0gRkJfVFlQRV9QQUNLRURfUElYRUxTOwoJZmJpbmZvLT5maXgudHlwZV9hdXgJICAgID0gMDsKCWZiaW5mby0+Zml4LnhwYW5zdGVwCSAgICA9IDA7CglmYmluZm8tPmZpeC55cGFuc3RlcAkgICAgPSAwOwoJZmJpbmZvLT5maXgueXdyYXBzdGVwCSAgICA9IDA7CglmYmluZm8tPmZpeC5hY2NlbAkgICAgPSBGQl9BQ0NFTF9OT05FOwoKCWZiaW5mby0+dmFyLm5vbnN0ZAkgICAgPSAwOwoJZmJpbmZvLT52YXIuYWN0aXZhdGUJICAgID0gRkJfQUNUSVZBVEVfTk9XOwoJZmJpbmZvLT52YXIuaGVpZ2h0CSAgICA9IG1hY2hfaW5mby0+aGVpZ2h0OwoJZmJpbmZvLT52YXIud2lkdGgJICAgID0gbWFjaF9pbmZvLT53aWR0aDsKCWZiaW5mby0+dmFyLmFjY2VsX2ZsYWdzICAgICA9IDA7CglmYmluZm8tPnZhci52bW9kZQkgICAgPSBGQl9WTU9ERV9OT05JTlRFUkxBQ0VEOwoKCWZiaW5mby0+ZmJvcHMJCSAgICA9ICZzM2MyNDEwZmJfb3BzOwoJZmJpbmZvLT5mbGFncwkJICAgID0gRkJJTkZPX0ZMQUdfREVGQVVMVDsKCWZiaW5mby0+cHNldWRvX3BhbGV0dGUgICAgICA9ICZpbmZvLT5wc2V1ZG9fcGFsOwoKCWZiaW5mby0+dmFyLnhyZXMJICAgID0gbWFjaF9pbmZvLT54cmVzLmRlZnZhbDsKCWZiaW5mby0+dmFyLnhyZXNfdmlydHVhbCAgICA9IG1hY2hfaW5mby0+eHJlcy5kZWZ2YWw7CglmYmluZm8tPnZhci55cmVzCSAgICA9IG1hY2hfaW5mby0+eXJlcy5kZWZ2YWw7CglmYmluZm8tPnZhci55cmVzX3ZpcnR1YWwgICAgPSBtYWNoX2luZm8tPnlyZXMuZGVmdmFsOwoJZmJpbmZvLT52YXIuYml0c19wZXJfcGl4ZWwgID0gbWFjaF9pbmZvLT5icHAuZGVmdmFsOwoKCWZiaW5mby0+dmFyLnVwcGVyX21hcmdpbiAgICA9IFMzQzI0MTBfTENEQ09OMl9HRVRfVkJQRChtcmVncy0+bGNkY29uMikgKzE7CglmYmluZm8tPnZhci5sb3dlcl9tYXJnaW4gICAgPSBTM0MyNDEwX0xDRENPTjJfR0VUX1ZGUEQobXJlZ3MtPmxjZGNvbjIpICsxOwoJZmJpbmZvLT52YXIudnN5bmNfbGVuCSAgICA9IFMzQzI0MTBfTENEQ09OMl9HRVRfVlNQVyhtcmVncy0+bGNkY29uMikgKyAxOwoKCWZiaW5mby0+dmFyLmxlZnRfbWFyZ2luCSAgICA9IFMzQzI0MTBfTENEQ09OM19HRVRfSEZQRChtcmVncy0+bGNkY29uMykgKyAxOwoJZmJpbmZvLT52YXIucmlnaHRfbWFyZ2luICAgID0gUzNDMjQxMF9MQ0RDT04zX0dFVF9IQlBEKG1yZWdzLT5sY2Rjb24zKSArIDE7CglmYmluZm8tPnZhci5oc3luY19sZW4JICAgID0gUzNDMjQxMF9MQ0RDT040X0dFVF9IU1BXKG1yZWdzLT5sY2Rjb240KSArIDE7CgoJZmJpbmZvLT52YXIucmVkLm9mZnNldCAgICAgID0gMTE7CglmYmluZm8tPnZhci5ncmVlbi5vZmZzZXQgICAgPSA1OwoJZmJpbmZvLT52YXIuYmx1ZS5vZmZzZXQgICAgID0gMDsKCWZiaW5mby0+dmFyLnRyYW5zcC5vZmZzZXQgICA9IDA7CglmYmluZm8tPnZhci5yZWQubGVuZ3RoICAgICAgPSA1OwoJZmJpbmZvLT52YXIuZ3JlZW4ubGVuZ3RoICAgID0gNjsKCWZiaW5mby0+dmFyLmJsdWUubGVuZ3RoICAgICA9IDU7CglmYmluZm8tPnZhci50cmFuc3AubGVuZ3RoICAgPSAwOwoJZmJpbmZvLT5maXguc21lbV9sZW4gICAgICAgID0JbWFjaF9pbmZvLT54cmVzLm1heCAqCgkJCQkJbWFjaF9pbmZvLT55cmVzLm1heCAqCgkJCQkJbWFjaF9pbmZvLT5icHAubWF4IC8gODsKCglmb3IgKGkgPSAwOyBpIDwgMjU2OyBpKyspCgkJaW5mby0+cGFsZXR0ZV9idWZmZXJbaV0gPSBQQUxFVFRFX0JVRkZfQ0xFQVI7CgoJaWYgKCFyZXF1ZXN0X21lbV9yZWdpb24oKHVuc2lnbmVkIGxvbmcpUzNDMjRYWF9WQV9MQ0QsIFNaXzFNLCAiczNjMjQxMC1sY2QiKSkgewoJCXJldCA9IC1FQlVTWTsKCQlnb3RvIGRlYWxsb2NfZmI7Cgl9CgoKCWRwcmludGsoImdvdCBMQ0QgcmVnaW9uXG4iKTsKCglyZXQgPSByZXF1ZXN0X2lycShpcnEsIHMzYzI0MTBmYl9pcnEsIFNBX0lOVEVSUlVQVCwgcGRldi0+bmFtZSwgaW5mbyk7CglpZiAocmV0KSB7CgkJZGV2X2VycihkZXYsICJjYW5ub3QgZ2V0IGlycSAlZCAtIGVyciAlZFxuIiwgaXJxLCByZXQpOwoJCXJldCA9IC1FQlVTWTsKCQlnb3RvIHJlbGVhc2VfbWVtOwoJfQoKCWluZm8tPmNsayA9IGNsa19nZXQoTlVMTCwgImxjZCIpOwoJaWYgKCFpbmZvLT5jbGsgfHwgSVNfRVJSKGluZm8tPmNsaykpIHsKCQlwcmludGsoS0VSTl9FUlIgImZhaWxlZCB0byBnZXQgbGNkIGNsb2NrIHNvdXJjZVxuIik7CgkJcmV0ID0gLUVOT0VOVDsKCQlnb3RvIHJlbGVhc2VfaXJxOwoJfQoKCWNsa191c2UoaW5mby0+Y2xrKTsKCWNsa19lbmFibGUoaW5mby0+Y2xrKTsKCWRwcmludGsoImdvdCBhbmQgZW5hYmxlZCBjbG9ja1xuIik7CgoJbXNsZWVwKDEpOwoKCS8qIEluaXRpYWxpemUgdmlkZW8gbWVtb3J5ICovCglyZXQgPSBzM2MyNDEwZmJfbWFwX3ZpZGVvX21lbW9yeShpbmZvKTsKCWlmIChyZXQpIHsKCQlwcmludGsoIEtFUk5fRVJSICJGYWlsZWQgdG8gYWxsb2NhdGUgdmlkZW8gUkFNOiAlZFxuIiwgcmV0KTsKCQlyZXQgPSAtRU5PTUVNOwoJCWdvdG8gcmVsZWFzZV9jbG9jazsKCX0KCWRwcmludGsoImdvdCB2aWRlbyBtZW1vcnlcbiIpOwoKCXJldCA9IHMzYzI0MTBmYl9pbml0X3JlZ2lzdGVycyhpbmZvKTsKCglyZXQgPSBzM2MyNDEwZmJfY2hlY2tfdmFyKCZmYmluZm8tPnZhciwgZmJpbmZvKTsKCglyZXQgPSByZWdpc3Rlcl9mcmFtZWJ1ZmZlcihmYmluZm8pOwoJaWYgKHJldCA8IDApIHsKCQlwcmludGsoS0VSTl9FUlIgIkZhaWxlZCB0byByZWdpc3RlciBmcmFtZWJ1ZmZlciBkZXZpY2U6ICVkXG4iLCByZXQpOwoJCWdvdG8gZnJlZV92aWRlb19tZW1vcnk7Cgl9CgoJLyogY3JlYXRlIGRldmljZSBmaWxlcyAqLwoJZGV2aWNlX2NyZWF0ZV9maWxlKGRldiwgJmRldl9hdHRyX2RlYnVnKTsKCglwcmludGsoS0VSTl9JTkZPICJmYiVkOiAlcyBmcmFtZSBidWZmZXIgZGV2aWNlXG4iLAoJCWZiaW5mby0+bm9kZSwgZmJpbmZvLT5maXguaWQpOwoKCXJldHVybiAwOwoKZnJlZV92aWRlb19tZW1vcnk6CglzM2MyNDEwZmJfdW5tYXBfdmlkZW9fbWVtb3J5KGluZm8pOwpyZWxlYXNlX2Nsb2NrOgoJY2xrX2Rpc2FibGUoaW5mby0+Y2xrKTsKCWNsa191bnVzZShpbmZvLT5jbGspOwoJY2xrX3B1dChpbmZvLT5jbGspOwpyZWxlYXNlX2lycToKCWZyZWVfaXJxKGlycSxpbmZvKTsKcmVsZWFzZV9tZW06CiAJcmVsZWFzZV9tZW1fcmVnaW9uKCh1bnNpZ25lZCBsb25nKVMzQzI0WFhfVkFfTENELCBTM0MyNFhYX1NaX0xDRCk7CmRlYWxsb2NfZmI6CglmcmFtZWJ1ZmZlcl9yZWxlYXNlKGZiaW5mbyk7CglyZXR1cm4gcmV0Owp9CgovKiBzM2MyNDEwZmJfc3RvcF9sY2QKICoKICogc2h1dGRvd24gdGhlIGxjZCBjb250cm9sbGVyCiovCgpzdGF0aWMgdm9pZCBzM2MyNDEwZmJfc3RvcF9sY2Qodm9pZCkKewoJdW5zaWduZWQgbG9uZyBmbGFnczsKCXVuc2lnbmVkIGxvbmcgdG1wOwoKCWxvY2FsX2lycV9zYXZlKGZsYWdzKTsKCgl0bXAgPSByZWFkbChTM0MyNDEwX0xDRENPTjEpOwoJd3JpdGVsKHRtcCAmIH5TM0MyNDEwX0xDRENPTjFfRU5WSUQsIFMzQzI0MTBfTENEQ09OMSk7CgoJbG9jYWxfaXJxX3Jlc3RvcmUoZmxhZ3MpOwp9CgovKgogKiAgQ2xlYW51cAogKi8Kc3RhdGljIGludCBzM2MyNDEwZmJfcmVtb3ZlKHN0cnVjdCBkZXZpY2UgKmRldikKewoJc3RydWN0IHBsYXRmb3JtX2RldmljZSAqcGRldiA9IHRvX3BsYXRmb3JtX2RldmljZShkZXYpOwoJc3RydWN0IGZiX2luZm8JICAgKmZiaW5mbyA9IGRldl9nZXRfZHJ2ZGF0YShkZXYpOwoJc3RydWN0IHMzYzI0MTBmYl9pbmZvICppbmZvID0gZmJpbmZvLT5wYXI7CglpbnQgaXJxOwoKCXMzYzI0MTBmYl9zdG9wX2xjZCgpOwoJbXNsZWVwKDEpOwoKCXMzYzI0MTBmYl91bm1hcF92aWRlb19tZW1vcnkoaW5mbyk7CgogCWlmIChpbmZvLT5jbGspIHsKIAkJY2xrX2Rpc2FibGUoaW5mby0+Y2xrKTsKIAkJY2xrX3VudXNlKGluZm8tPmNsayk7CiAJCWNsa19wdXQoaW5mby0+Y2xrKTsKIAkJaW5mby0+Y2xrID0gTlVMTDsKCX0KCglpcnEgPSBwbGF0Zm9ybV9nZXRfaXJxKHBkZXYsIDApOwoJZnJlZV9pcnEoaXJxLGluZm8pOwoJcmVsZWFzZV9tZW1fcmVnaW9uKCh1bnNpZ25lZCBsb25nKVMzQzI0WFhfVkFfTENELCBTM0MyNFhYX1NaX0xDRCk7Cgl1bnJlZ2lzdGVyX2ZyYW1lYnVmZmVyKGZiaW5mbyk7CgoJcmV0dXJuIDA7Cn0KCiNpZmRlZiBDT05GSUdfUE0KCi8qIHN1c3BlbmQgYW5kIHJlc3VtZSBzdXBwb3J0IGZvciB0aGUgbGNkIGNvbnRyb2xsZXIgKi8KCnN0YXRpYyBpbnQgczNjMjQxMGZiX3N1c3BlbmQoc3RydWN0IGRldmljZSAqZGV2LCBwbV9tZXNzYWdlX3Qgc3RhdGUsIHUzMiBsZXZlbCkKewoJc3RydWN0IGZiX2luZm8JICAgKmZiaW5mbyA9IGRldl9nZXRfZHJ2ZGF0YShkZXYpOwoJc3RydWN0IHMzYzI0MTBmYl9pbmZvICppbmZvID0gZmJpbmZvLT5wYXI7CgoJaWYgKGxldmVsID09IFNVU1BFTkRfRElTQUJMRSB8fCBsZXZlbCA9PSBTVVNQRU5EX1BPV0VSX0RPV04pIHsKCQlzM2MyNDEwZmJfc3RvcF9sY2QoKTsKCgkJLyogc2xlZXAgYmVmb3JlIGRpc2FibGluZyB0aGUgY2xvY2ssIHdlIG5lZWQgdG8gZW5zdXJlCgkJICogdGhlIExDRCBETUEgZW5naW5lIGlzIG5vdCBnb2luZyB0byBnZXQgYmFjayBvbiB0aGUgYnVzCgkJICogYmVmb3JlIHRoZSBjbG9jayBnb2VzIG9mZiBhZ2FpbiAoYmpkKSAqLwoKCQltc2xlZXAoMSk7CgkJY2xrX2Rpc2FibGUoaW5mby0+Y2xrKTsKCX0KCglyZXR1cm4gMDsKfQoKc3RhdGljIGludCBzM2MyNDEwZmJfcmVzdW1lKHN0cnVjdCBkZXZpY2UgKmRldiwgdTMyIGxldmVsKQp7CglzdHJ1Y3QgZmJfaW5mbwkgICAqZmJpbmZvID0gZGV2X2dldF9kcnZkYXRhKGRldik7CglzdHJ1Y3QgczNjMjQxMGZiX2luZm8gKmluZm8gPSBmYmluZm8tPnBhcjsKCglpZiAobGV2ZWwgPT0gUkVTVU1FX0VOQUJMRSkgewoJCWNsa19lbmFibGUoaW5mby0+Y2xrKTsKCQltc2xlZXAoMSk7CgoJCXMzYzI0MTBmYl9pbml0X3JlZ2lzdGVycyhpbmZvKTsKCgl9CgoJcmV0dXJuIDA7Cn0KCiNlbHNlCiNkZWZpbmUgczNjMjQxMGZiX3N1c3BlbmQgTlVMTAojZGVmaW5lIHMzYzI0MTBmYl9yZXN1bWUgIE5VTEwKI2VuZGlmCgpzdGF0aWMgc3RydWN0IGRldmljZV9kcml2ZXIgczNjMjQxMGZiX2RyaXZlciA9IHsKCS5uYW1lCQk9ICJzM2MyNDEwLWxjZCIsCgkuYnVzCQk9ICZwbGF0Zm9ybV9idXNfdHlwZSwKCS5wcm9iZQkJPSBzM2MyNDEwZmJfcHJvYmUsCgkuc3VzcGVuZAk9IHMzYzI0MTBmYl9zdXNwZW5kLAoJLnJlc3VtZQkJPSBzM2MyNDEwZmJfcmVzdW1lLAoJLnJlbW92ZQkJPSBzM2MyNDEwZmJfcmVtb3ZlCn07CgppbnQgX19kZXZpbml0IHMzYzI0MTBmYl9pbml0KHZvaWQpCnsKCXJldHVybiBkcml2ZXJfcmVnaXN0ZXIoJnMzYzI0MTBmYl9kcml2ZXIpOwp9CgpzdGF0aWMgdm9pZCBfX2V4aXQgczNjMjQxMGZiX2NsZWFudXAodm9pZCkKewoJZHJpdmVyX3VucmVnaXN0ZXIoJnMzYzI0MTBmYl9kcml2ZXIpOwp9CgoKbW9kdWxlX2luaXQoczNjMjQxMGZiX2luaXQpOwptb2R1bGVfZXhpdChzM2MyNDEwZmJfY2xlYW51cCk7CgpNT0RVTEVfQVVUSE9SKCJBcm5hdWQgUGF0YXJkIDxhcm5hdWQucGF0YXJkQHJ0cC1uZXQub3JnPiwgQmVuIERvb2tzIDxiZW4tbGludXhAZmx1ZmYub3JnPiIpOwpNT0RVTEVfREVTQ1JJUFRJT04oIkZyYW1lYnVmZmVyIGRyaXZlciBmb3IgdGhlIHMzYzI0MTAiKTsKTU9EVUxFX0xJQ0VOU0UoIkdQTCIpOwo=