LyoKICogRGV2aWNlIGRyaXZlciBmb3IgdGhlIGkyYyB0aGVybW9zdGF0IGZvdW5kIG9uIHRoZSBpQm9vayBHNCwgQWxib29rIEc0CiAqCiAqIENvcHlyaWdodCAoQykgMjAwMywgMjAwNCBDb2xpbiBMZXJveSwgUmFzbXVzIFJvaGRlLCBCZW5qYW1pbiBIZXJyZW5zY2htaWR0CiAqCiAqIERvY3VtZW50YXRpb24gZnJvbQogKiBodHRwOi8vd3d3LmFuYWxvZy5jb20vVXBsb2FkZWRGaWxlcy9EYXRhX1NoZWV0cy8xMTUyNTQxNzVBRFQ3NDY3X3ByYS5wZGYKICogaHR0cDovL3d3dy5hbmFsb2cuY29tL1VwbG9hZGVkRmlsZXMvRGF0YV9TaGVldHMvMzY4NjIyMTE3MTE2N0FEVDc0NjBfYi5wZGYKICoKICovCgojaW5jbHVkZSA8bGludXgvY29uZmlnLmg+CiNpbmNsdWRlIDxsaW51eC90eXBlcy5oPgojaW5jbHVkZSA8bGludXgvbW9kdWxlLmg+CiNpbmNsdWRlIDxsaW51eC9lcnJuby5oPgojaW5jbHVkZSA8bGludXgva2VybmVsLmg+CiNpbmNsdWRlIDxsaW51eC9kZWxheS5oPgojaW5jbHVkZSA8bGludXgvc2NoZWQuaD4KI2luY2x1ZGUgPGxpbnV4L2kyYy5oPgojaW5jbHVkZSA8bGludXgvc2xhYi5oPgojaW5jbHVkZSA8bGludXgvaW5pdC5oPgojaW5jbHVkZSA8bGludXgvc3BpbmxvY2suaD4KI2luY2x1ZGUgPGxpbnV4L3NtcF9sb2NrLmg+CiNpbmNsdWRlIDxsaW51eC93YWl0Lmg+CiNpbmNsdWRlIDxsaW51eC9zdXNwZW5kLmg+CiNpbmNsdWRlIDxsaW51eC9rdGhyZWFkLmg+CiNpbmNsdWRlIDxsaW51eC9tb2R1bGVwYXJhbS5oPgoKI2luY2x1ZGUgPGFzbS9wcm9tLmg+CiNpbmNsdWRlIDxhc20vbWFjaGRlcC5oPgojaW5jbHVkZSA8YXNtL2lvLmg+CiNpbmNsdWRlIDxhc20vc3lzdGVtLmg+CiNpbmNsdWRlIDxhc20vc2VjdGlvbnMuaD4KI2luY2x1ZGUgPGFzbS9vZl9kZXZpY2UuaD4KCiN1bmRlZiBERUJVRwoKI2RlZmluZSBDT05GSUdfUkVHICAgMHg0MAojZGVmaW5lIE1BTlVBTF9NQVNLICAweGUwCiNkZWZpbmUgQVVUT19NQVNLICAgIDB4MjAKCnN0YXRpYyB1OCBURU1QX1JFR1szXSAgICA9IHsweDI2LCAweDI1LCAweDI3fTsgLyogbG9jYWwsIGNwdSwgZ3B1ICovCnN0YXRpYyB1OCBMSU1JVF9SRUdbM10gICA9IHsweDZiLCAweDZhLCAweDZjfTsgLyogbG9jYWwsIGNwdSwgZ3B1ICovCnN0YXRpYyB1OCBNQU5VQUxfTU9ERVsyXSA9IHsweDVjLCAweDVkfTsgICAgICAgCnN0YXRpYyB1OCBSRU1fQ09OVFJPTFsyXSA9IHsweDAwLCAweDQwfTsKc3RhdGljIHU4IEZBTl9TUEVFRFsyXSAgID0gezB4MjgsIDB4MmF9OwpzdGF0aWMgdTggRkFOX1NQRF9TRVRbMl0gPSB7MHgzMCwgMHgzMX07CgpzdGF0aWMgdTggZGVmYXVsdF9saW1pdHNfbG9jYWxbM10gPSB7NzAsIDUwLCA3MH07ICAgIC8qIGxvY2FsLCBjcHUsIGdwdSAqLwpzdGF0aWMgdTggZGVmYXVsdF9saW1pdHNfY2hpcFszXSA9IHs4MCwgNjUsIDgwfTsgICAgLyogbG9jYWwsIGNwdSwgZ3B1ICovCgpzdGF0aWMgaW50IGxpbWl0X2FkanVzdCA9IDA7CnN0YXRpYyBpbnQgZmFuX3NwZWVkID0gLTE7CgpNT0RVTEVfQVVUSE9SKCJDb2xpbiBMZXJveSA8Y29saW5AY29saW5vLm5ldD4iKTsKTU9EVUxFX0RFU0NSSVBUSU9OKCJEcml2ZXIgZm9yIEFEVDc0NnggdGhlcm1vc3RhdCBpbiBpQm9vayBHNCBhbmQgIgoJCSAgICJQb3dlcmJvb2sgRzQgQWx1Iik7Ck1PRFVMRV9MSUNFTlNFKCJHUEwiKTsKCm1vZHVsZV9wYXJhbShsaW1pdF9hZGp1c3QsIGludCwgMDY0NCk7Ck1PRFVMRV9QQVJNX0RFU0MobGltaXRfYWRqdXN0LCJBZGp1c3QgbWF4aW11bSB0ZW1wZXJhdHVyZXMgKDUwIGNwdSwgNzAgZ3B1KSAiCgkJICJieSBOIGRlZ3JlZXMuIik7Cgptb2R1bGVfcGFyYW0oZmFuX3NwZWVkLCBpbnQsIDA2NDQpOwpNT0RVTEVfUEFSTV9ERVNDKGZhbl9zcGVlZCwiU3BlY2lmeSBzdGFydGluZyBmYW4gc3BlZWQgKDAtMjU1KSAiCgkJICIoZGVmYXVsdCA2NCkiKTsKCnN0cnVjdCB0aGVybW9zdGF0IHsKCXN0cnVjdCBpMmNfY2xpZW50CWNsdDsKCXU4CQkJdGVtcHNbM107Cgl1OAkJCWNhY2hlZF90ZW1wWzNdOwoJdTgJCQlpbml0aWFsX2xpbWl0c1szXTsKCXU4CQkJbGltaXRzWzNdOwoJaW50CQkJbGFzdF9zcGVlZFsyXTsKCWludAkJCWxhc3RfdmFyWzJdOwp9OwoKc3RhdGljIGVudW0ge0FEVDc0NjAsIEFEVDc0Njd9IHRoZXJtX3R5cGU7CnN0YXRpYyBpbnQgdGhlcm1fYnVzLCB0aGVybV9hZGRyZXNzOwpzdGF0aWMgc3RydWN0IG9mX2RldmljZSAqIG9mX2RldjsKc3RhdGljIHN0cnVjdCB0aGVybW9zdGF0KiB0aGVybW9zdGF0OwpzdGF0aWMgc3RydWN0IHRhc2tfc3RydWN0ICp0aHJlYWRfdGhlcm0gPSBOVUxMOwoKc3RhdGljIGludCBhdHRhY2hfb25lX3RoZXJtb3N0YXQoc3RydWN0IGkyY19hZGFwdGVyICphZGFwdGVyLCBpbnQgYWRkciwKCQkJCSBpbnQgYnVzbm8pOwoKc3RhdGljIHZvaWQgd3JpdGVfYm90aF9mYW5fc3BlZWQoc3RydWN0IHRoZXJtb3N0YXQgKnRoLCBpbnQgc3BlZWQpOwpzdGF0aWMgdm9pZCB3cml0ZV9mYW5fc3BlZWQoc3RydWN0IHRoZXJtb3N0YXQgKnRoLCBpbnQgc3BlZWQsIGludCBmYW4pOwoKc3RhdGljIGludAp3cml0ZV9yZWcoc3RydWN0IHRoZXJtb3N0YXQqIHRoLCBpbnQgcmVnLCB1OCBkYXRhKQp7Cgl1OCB0bXBbMl07CglpbnQgcmM7CgkKCXRtcFswXSA9IHJlZzsKCXRtcFsxXSA9IGRhdGE7CglyYyA9IGkyY19tYXN0ZXJfc2VuZCgmdGgtPmNsdCwgKGNvbnN0IGNoYXIgKil0bXAsIDIpOwoJaWYgKHJjIDwgMCkKCQlyZXR1cm4gcmM7CglpZiAocmMgIT0gMikKCQlyZXR1cm4gLUVOT0RFVjsKCXJldHVybiAwOwp9CgpzdGF0aWMgaW50CnJlYWRfcmVnKHN0cnVjdCB0aGVybW9zdGF0KiB0aCwgaW50IHJlZykKewoJdTggcmVnX2FkZHIsIGRhdGE7CglpbnQgcmM7CgoJcmVnX2FkZHIgPSAodTgpcmVnOwoJcmMgPSBpMmNfbWFzdGVyX3NlbmQoJnRoLT5jbHQsICZyZWdfYWRkciwgMSk7CglpZiAocmMgPCAwKQoJCXJldHVybiByYzsKCWlmIChyYyAhPSAxKQoJCXJldHVybiAtRU5PREVWOwoJcmMgPSBpMmNfbWFzdGVyX3JlY3YoJnRoLT5jbHQsIChjaGFyICopJmRhdGEsIDEpOwoJaWYgKHJjIDwgMCkKCQlyZXR1cm4gcmM7CglyZXR1cm4gZGF0YTsKfQoKc3RhdGljIGludAphdHRhY2hfdGhlcm1vc3RhdChzdHJ1Y3QgaTJjX2FkYXB0ZXIgKmFkYXB0ZXIpCnsKCXVuc2lnbmVkIGxvbmcgYnVzX25vOwoKCWlmIChzdHJuY21wKGFkYXB0ZXItPm5hbWUsICJ1bmktbiIsIDUpKQoJCXJldHVybiAtRU5PREVWOwoJYnVzX25vID0gc2ltcGxlX3N0cnRvdWwoYWRhcHRlci0+bmFtZSArIDYsIE5VTEwsIDEwKTsKCWlmIChidXNfbm8gIT0gdGhlcm1fYnVzKQoJCXJldHVybiAtRU5PREVWOwoJcmV0dXJuIGF0dGFjaF9vbmVfdGhlcm1vc3RhdChhZGFwdGVyLCB0aGVybV9hZGRyZXNzLCBidXNfbm8pOwp9CgpzdGF0aWMgaW50CmRldGFjaF90aGVybW9zdGF0KHN0cnVjdCBpMmNfYWRhcHRlciAqYWRhcHRlcikKewoJc3RydWN0IHRoZXJtb3N0YXQqIHRoOwoJaW50IGk7CgkKCWlmICh0aGVybW9zdGF0ID09IE5VTEwpCgkJcmV0dXJuIDA7CgoJdGggPSB0aGVybW9zdGF0OwoKCWlmICh0aHJlYWRfdGhlcm0gIT0gTlVMTCkgewoJCWt0aHJlYWRfc3RvcCh0aHJlYWRfdGhlcm0pOwoJfQoJCQoJcHJpbnRrKEtFUk5fSU5GTyAiYWR0NzQ2eDogUHV0dGluZyBtYXggdGVtcGVyYXR1cmVzIGJhY2sgZnJvbSAiCgkJCSAiJWQsICVkLCAlZCB0byAlZCwgJWQsICVkXG4iLAoJCXRoLT5saW1pdHNbMF0sIHRoLT5saW1pdHNbMV0sIHRoLT5saW1pdHNbMl0sCgkJdGgtPmluaXRpYWxfbGltaXRzWzBdLCB0aC0+aW5pdGlhbF9saW1pdHNbMV0sCgkJdGgtPmluaXRpYWxfbGltaXRzWzJdKTsKCQoJZm9yIChpID0gMDsgaSA8IDM7IGkrKykKCQl3cml0ZV9yZWcodGgsIExJTUlUX1JFR1tpXSwgdGgtPmluaXRpYWxfbGltaXRzW2ldKTsKCgl3cml0ZV9ib3RoX2Zhbl9zcGVlZCh0aCwgLTEpOwoKCWkyY19kZXRhY2hfY2xpZW50KCZ0aC0+Y2x0KTsKCgl0aGVybW9zdGF0ID0gTlVMTDsKCglrZnJlZSh0aCk7CgoJcmV0dXJuIDA7Cn0KCnN0YXRpYyBzdHJ1Y3QgaTJjX2RyaXZlciB0aGVybW9zdGF0X2RyaXZlciA9IHsgIAoJLm93bmVyCQk9IFRISVNfTU9EVUxFLAoJLm5hbWUJCT0gInRoZXJtX2FkdDc0NngiLAoJLmZsYWdzCQk9IEkyQ19ERl9OT1RJRlksCgkuYXR0YWNoX2FkYXB0ZXIJPSBhdHRhY2hfdGhlcm1vc3RhdCwKCS5kZXRhY2hfYWRhcHRlcgk9IGRldGFjaF90aGVybW9zdGF0LAp9OwoKc3RhdGljIGludCByZWFkX2Zhbl9zcGVlZChzdHJ1Y3QgdGhlcm1vc3RhdCAqdGgsIHU4IGFkZHIpCnsKCXU4IHRtcFsyXTsKCXUxNiByZXM7CgkKCS8qIHNob3VsZCBzdGFydCB3aXRoIGxvdyBieXRlICovCgl0bXBbMV0gPSByZWFkX3JlZyh0aCwgYWRkcik7Cgl0bXBbMF0gPSByZWFkX3JlZyh0aCwgYWRkciArIDEpOwoJCglyZXMgPSB0bXBbMV0gKyAodG1wWzBdIDw8IDgpOwoJLyogImEgdmFsdWUgb2YgMHhmZmZmIG1lYW5zIHRoYXQgdGhlIGZhbiBoYXMgc3RvcHBlZCIgKi8KCXJldHVybiAocmVzID09IDB4ZmZmZiA/IDAgOiAoOTAwMDAqNjApL3Jlcyk7Cn0KCnN0YXRpYyB2b2lkIHdyaXRlX2JvdGhfZmFuX3NwZWVkKHN0cnVjdCB0aGVybW9zdGF0ICp0aCwgaW50IHNwZWVkKQp7Cgl3cml0ZV9mYW5fc3BlZWQodGgsIHNwZWVkLCAwKTsKCWlmICh0aGVybV90eXBlID09IEFEVDc0NjApCgkJd3JpdGVfZmFuX3NwZWVkKHRoLCBzcGVlZCwgMSk7Cn0KCnN0YXRpYyB2b2lkIHdyaXRlX2Zhbl9zcGVlZChzdHJ1Y3QgdGhlcm1vc3RhdCAqdGgsIGludCBzcGVlZCwgaW50IGZhbikKewoJdTggbWFudWFsOwoJCglpZiAoc3BlZWQgPiAweGZmKSAKCQlzcGVlZCA9IDB4ZmY7CgllbHNlIGlmIChzcGVlZCA8IC0xKSAKCQlzcGVlZCA9IDA7CgkKCWlmICh0aGVybV90eXBlID09IEFEVDc0NjcgJiYgZmFuID09IDEpCgkJcmV0dXJuOwoJCglpZiAodGgtPmxhc3Rfc3BlZWRbZmFuXSAhPSBzcGVlZCkgewoJCWlmIChzcGVlZCA9PSAtMSkKCQkJcHJpbnRrKEtFUk5fREVCVUcgImFkdDc0Nng6IFNldHRpbmcgc3BlZWQgdG8gYXV0b21hdGljICIKCQkJCSJmb3IgJXMgZmFuLlxuIiwgZmFuPyJHUFUiOiJDUFUiKTsKCQllbHNlCgkJCXByaW50ayhLRVJOX0RFQlVHICJhZHQ3NDZ4OiBTZXR0aW5nIHNwZWVkIHRvICVkICIKCQkJCSJmb3IgJXMgZmFuLlxuIiwgc3BlZWQsIGZhbj8iR1BVIjoiQ1BVIik7Cgl9IGVsc2UKCQlyZXR1cm47CgkKCWlmIChzcGVlZCA+PSAwKSB7CgkJbWFudWFsID0gcmVhZF9yZWcodGgsIE1BTlVBTF9NT0RFW2Zhbl0pOwoJCXdyaXRlX3JlZyh0aCwgTUFOVUFMX01PREVbZmFuXSwgbWFudWFsfE1BTlVBTF9NQVNLKTsKCQl3cml0ZV9yZWcodGgsIEZBTl9TUERfU0VUW2Zhbl0sIHNwZWVkKTsKCX0gZWxzZSB7CgkJLyogYmFjayB0byBhdXRvbWF0aWMgKi8KCQlpZih0aGVybV90eXBlID09IEFEVDc0NjApIHsKCQkJbWFudWFsID0gcmVhZF9yZWcodGgsCgkJCQlNQU5VQUxfTU9ERVtmYW5dKSAmICh+TUFOVUFMX01BU0spOwoKCQkJd3JpdGVfcmVnKHRoLAoJCQkJTUFOVUFMX01PREVbZmFuXSwgbWFudWFsfFJFTV9DT05UUk9MW2Zhbl0pOwoJCX0gZWxzZSB7CgkJCW1hbnVhbCA9IHJlYWRfcmVnKHRoLCBNQU5VQUxfTU9ERVtmYW5dKTsKCQkJd3JpdGVfcmVnKHRoLCBNQU5VQUxfTU9ERVtmYW5dLCBtYW51YWwmKH5BVVRPX01BU0spKTsKCQl9Cgl9CgkKCXRoLT5sYXN0X3NwZWVkW2Zhbl0gPSBzcGVlZDsJCQkKfQoKc3RhdGljIHZvaWQgcmVhZF9zZW5zb3JzKHN0cnVjdCB0aGVybW9zdGF0ICp0aCkKewoJaW50IGkgPSAwOwoKCWZvciAoaSA9IDA7IGkgPCAzOyBpKyspCgkJdGgtPnRlbXBzW2ldICA9IHJlYWRfcmVnKHRoLCBURU1QX1JFR1tpXSk7Cn0KCiNpZmRlZiBERUJVRwpzdGF0aWMgdm9pZCBkaXNwbGF5X3N0YXRzKHN0cnVjdCB0aGVybW9zdGF0ICp0aCkKewoJaWYgKHRoLT50ZW1wc1swXSAhPSB0aC0+Y2FjaGVkX3RlbXBbMF0KCXx8ICB0aC0+dGVtcHNbMV0gIT0gdGgtPmNhY2hlZF90ZW1wWzFdCgl8fCAgdGgtPnRlbXBzWzJdICE9IHRoLT5jYWNoZWRfdGVtcFsyXSkgewoJCXByaW50ayhLRVJOX0lORk8gImFkdDc0Nng6IFRlbXBlcmF0dXJlIGluZm9zOiIKCQkJCSAiIHRoZXJtb3N0YXRzOiAlZCwlZCwlZDsiCgkJCQkgIiBsaW1pdHM6ICVkLCVkLCVkOyIKCQkJCSAiIGZhbiBzcGVlZDogJWQgUlBNXG4iLAoJCQkJIHRoLT50ZW1wc1swXSwgdGgtPnRlbXBzWzFdLCB0aC0+dGVtcHNbMl0sCgkJCQkgdGgtPmxpbWl0c1swXSwgIHRoLT5saW1pdHNbMV0sICB0aC0+bGltaXRzWzJdLAoJCQkJIHJlYWRfZmFuX3NwZWVkKHRoLCBGQU5fU1BFRURbMF0pKTsKCX0KCXRoLT5jYWNoZWRfdGVtcFswXSA9IHRoLT50ZW1wc1swXTsKCXRoLT5jYWNoZWRfdGVtcFsxXSA9IHRoLT50ZW1wc1sxXTsKCXRoLT5jYWNoZWRfdGVtcFsyXSA9IHRoLT50ZW1wc1syXTsKfQojZW5kaWYKCnN0YXRpYyB2b2lkIHVwZGF0ZV9mYW5zX3NwZWVkIChzdHJ1Y3QgdGhlcm1vc3RhdCAqdGgpCnsKCWludCBsYXN0dmFyID0gMDsgLyogbGFzdCB2YXJpYXRpb24sIGZvciBpQm9vayAqLwoJaW50IGkgPSAwOwoKCS8qIHdlIGRvbid0IGNhcmUgYWJvdXQgbG9jYWwgc2Vuc29yLCBzbyB3ZSBzdGFydCBhdCBzZW5zb3IgMSAqLwoJZm9yIChpID0gMTsgaSA8IDM7IGkrKykgewoJCWludCBzdGFydGVkID0gMDsKCQlpbnQgZmFuX251bWJlciA9ICh0aGVybV90eXBlID09IEFEVDc0NjAgJiYgaSA9PSAyKTsKCQlpbnQgdmFyID0gdGgtPnRlbXBzW2ldIC0gdGgtPmxpbWl0c1tpXTsKCgkJaWYgKHZhciA+IC0xKSB7CgkJCWludCBzdGVwID0gKDI1NSAtIGZhbl9zcGVlZCkgLyA3OwoJCQlpbnQgbmV3X3NwZWVkID0gMDsKCgkJCS8qIGh5c3RlcmVzaXMgOiBjaGFuZ2UgZmFuIHNwZWVkIG9ubHkgaWYgdmFyaWF0aW9uIGlzCgkJCSAqIG1vcmUgdGhhbiB0d28gZGVncmVlcyAqLwoJCQlpZiAoYWJzKHZhciAtIHRoLT5sYXN0X3ZhcltmYW5fbnVtYmVyXSkgPCAyKQoJCQkJY29udGludWU7CgoJCQlzdGFydGVkID0gMTsKCQkJbmV3X3NwZWVkID0gZmFuX3NwZWVkICsgKCh2YXItMSkqc3RlcCk7CgoJCQlpZiAobmV3X3NwZWVkIDwgZmFuX3NwZWVkKQoJCQkJbmV3X3NwZWVkID0gZmFuX3NwZWVkOwoJCQlpZiAobmV3X3NwZWVkID4gMjU1KQoJCQkJbmV3X3NwZWVkID0gMjU1OwoKCQkJcHJpbnRrKEtFUk5fREVCVUcgImFkdDc0Nng6IHNldHRpbmcgZmFucyBzcGVlZCB0byAlZCAiCgkJCQkJICIobGltaXQgZXhjZWVkZWQgYnkgJWQgb24gJXMpIFxuIiwKCQkJCQluZXdfc3BlZWQsIHZhciwKCQkJCQlmYW5fbnVtYmVyPyJHUFUvcHdyIjoiQ1BVIik7CgkJCXdyaXRlX2JvdGhfZmFuX3NwZWVkKHRoLCBuZXdfc3BlZWQpOwoJCQl0aC0+bGFzdF92YXJbZmFuX251bWJlcl0gPSB2YXI7CgkJfSBlbHNlIGlmICh2YXIgPCAtMikgewoJCQkvKiBkb24ndCBzdG9wIGZhbiBpZiBHUFUvcG93ZXIgaXMgY29sZCBhbmQgQ1BVIGlzIG5vdAoJCQkgKiBzbyBjb2xkIChsYXN0dmFyID49IC0xKSAqLwoJCQlpZiAoaSA9PSAyICYmIGxhc3R2YXIgPCAtMSkgewoJCQkJaWYgKHRoLT5sYXN0X3NwZWVkW2Zhbl9udW1iZXJdICE9IDApCgkJCQkJcHJpbnRrKEtFUk5fREVCVUcgImFkdDc0Nng6IFN0b3BwaW5nICIKCQkJCQkJImZhbnMuXG4iKTsKCQkJCXdyaXRlX2JvdGhfZmFuX3NwZWVkKHRoLCAwKTsKCQkJfQoJCX0KCgkJbGFzdHZhciA9IHZhcjsKCgkJaWYgKHN0YXJ0ZWQpCgkJCXJldHVybjsgLyogd2UgZG9uJ3Qgd2FudCB0byByZS1zdG9wIHRoZSBmYW4KCQkJCSogaWYgQ1BVIGlzIGhlYXRpbmcgYW5kIEdQVS9wb3dlciBpcyBub3QgKi8KCX0KfQoKc3RhdGljIGludCBtb25pdG9yX3Rhc2sodm9pZCAqYXJnKQp7CglzdHJ1Y3QgdGhlcm1vc3RhdCogdGggPSBhcmc7CgoJd2hpbGUoIWt0aHJlYWRfc2hvdWxkX3N0b3AoKSkgewoJCWlmIChjdXJyZW50LT5mbGFncyAmIFBGX0ZSRUVaRSkKCQkJcmVmcmlnZXJhdG9yKFBGX0ZSRUVaRSk7CgoJCW1zbGVlcF9pbnRlcnJ1cHRpYmxlKDIwMDApOwoKI2lmbmRlZiBERUJVRwoJCWlmIChmYW5fc3BlZWQgIT0gLTEpCgkJCXJlYWRfc2Vuc29ycyh0aCk7CiNlbHNlCgkJcmVhZF9zZW5zb3JzKHRoKTsKI2VuZGlmCQkKCgkJaWYgKGZhbl9zcGVlZCAhPSAtMSkKCQkJdXBkYXRlX2ZhbnNfc3BlZWQodGgpOwoKI2lmZGVmIERFQlVHCgkJZGlzcGxheV9zdGF0cyh0aCk7CiNlbmRpZgoKCX0KCglyZXR1cm4gMDsKfQoKc3RhdGljIHZvaWQgc2V0X2xpbWl0KHN0cnVjdCB0aGVybW9zdGF0ICp0aCwgaW50IGkpCnsKCQkvKiBTZXQgQ1BVIGxpbWl0IGhpZ2hlciB0byBhdm9pZCBwb3dlcmRvd25zICovIAoJCXRoLT5saW1pdHNbaV0gPSBkZWZhdWx0X2xpbWl0c19jaGlwW2ldICsgbGltaXRfYWRqdXN0OwoJCXdyaXRlX3JlZyh0aCwgTElNSVRfUkVHW2ldLCB0aC0+bGltaXRzW2ldKTsKCQkKCQkvKiBzZXQgb3VyIGxpbWl0cyB0byBub3JtYWwgKi8KCQl0aC0+bGltaXRzW2ldID0gZGVmYXVsdF9saW1pdHNfbG9jYWxbaV0gKyBsaW1pdF9hZGp1c3Q7Cn0KCnN0YXRpYyBpbnQgYXR0YWNoX29uZV90aGVybW9zdGF0KHN0cnVjdCBpMmNfYWRhcHRlciAqYWRhcHRlciwgaW50IGFkZHIsCgkJCQkgaW50IGJ1c25vKQp7CglzdHJ1Y3QgdGhlcm1vc3RhdCogdGg7CglpbnQgcmM7CglpbnQgaTsKCglpZiAodGhlcm1vc3RhdCkKCQlyZXR1cm4gMDsKCgl0aCA9IChzdHJ1Y3QgdGhlcm1vc3RhdCAqKQoJCWttYWxsb2Moc2l6ZW9mKHN0cnVjdCB0aGVybW9zdGF0KSwgR0ZQX0tFUk5FTCk7CgoJaWYgKCF0aCkKCQlyZXR1cm4gLUVOT01FTTsKCgltZW1zZXQodGgsIDAsIHNpemVvZigqdGgpKTsKCXRoLT5jbHQuYWRkciA9IGFkZHI7Cgl0aC0+Y2x0LmFkYXB0ZXIgPSBhZGFwdGVyOwoJdGgtPmNsdC5kcml2ZXIgPSAmdGhlcm1vc3RhdF9kcml2ZXI7CglzdHJjcHkodGgtPmNsdC5uYW1lLCAidGhlcm1vc3RhdCIpOwoKCXJjID0gcmVhZF9yZWcodGgsIDApOwoJaWYgKHJjIDwgMCkgewoJCXByaW50ayhLRVJOX0VSUiAiYWR0NzQ2eDogVGhlcm1vc3RhdCBmYWlsZWQgdG8gcmVhZCBjb25maWcgIgoJCQkJImZyb20gYnVzICVkICFcbiIsCgkJCQlidXNubyk7CgkJa2ZyZWUodGgpOwoJCXJldHVybiAtRU5PREVWOwoJfQoKCS8qIGZvcmNlIG1hbnVhbCBjb250cm9sIHRvIHN0YXJ0IHRoZSBmYW4gcXVpZXRlciAqLwoJaWYgKGZhbl9zcGVlZCA9PSAtMSkKCQlmYW5fc3BlZWQgPSA2NDsKCQoJaWYodGhlcm1fdHlwZSA9PSBBRFQ3NDYwKSB7CgkJcHJpbnRrKEtFUk5fSU5GTyAiYWR0NzQ2eDogQURUNzQ2MCBpbml0aWFsaXppbmdcbiIpOwoJCS8qIFRoZSA3NDYwIG5lZWRzIHRvIGJlIHN0YXJ0ZWQgZXhwbGljaXRseSAqLwoJCXdyaXRlX3JlZyh0aCwgQ09ORklHX1JFRywgMSk7Cgl9IGVsc2UKCQlwcmludGsoS0VSTl9JTkZPICJhZHQ3NDZ4OiBBRFQ3NDY3IGluaXRpYWxpemluZ1xuIik7CgoJZm9yIChpID0gMDsgaSA8IDM7IGkrKykgewoJCXRoLT5pbml0aWFsX2xpbWl0c1tpXSA9IHJlYWRfcmVnKHRoLCBMSU1JVF9SRUdbaV0pOwoJCXNldF9saW1pdCh0aCwgaSk7Cgl9CgkKCXByaW50ayhLRVJOX0lORk8gImFkdDc0Nng6IExvd2VyaW5nIG1heCB0ZW1wZXJhdHVyZXMgZnJvbSAlZCwgJWQsICVkIgoJCQkgIiB0byAlZCwgJWQsICVkXG4iLAoJCQkgdGgtPmluaXRpYWxfbGltaXRzWzBdLCB0aC0+aW5pdGlhbF9saW1pdHNbMV0sCgkJCSB0aC0+aW5pdGlhbF9saW1pdHNbMl0sIHRoLT5saW1pdHNbMF0sIHRoLT5saW1pdHNbMV0sCgkJCSB0aC0+bGltaXRzWzJdKTsKCgl0aGVybW9zdGF0ID0gdGg7CgoJaWYgKGkyY19hdHRhY2hfY2xpZW50KCZ0aC0+Y2x0KSkgewoJCXByaW50ayhLRVJOX0lORk8gImFkdDc0Nng6IFRoZXJtb3N0YXQgZmFpbGVkIHRvIGF0dGFjaCAiCgkJCQkgImNsaWVudCAhXG4iKTsKCQl0aGVybW9zdGF0ID0gTlVMTDsKCQlrZnJlZSh0aCk7CgkJcmV0dXJuIC1FTk9ERVY7Cgl9CgoJLyogYmUgc3VyZSB0byByZWFsbHkgd3JpdGUgZmFuIHNwZWVkIHRoZSBmaXJzdCB0aW1lICovCgl0aC0+bGFzdF9zcGVlZFswXSA9IC0yOwoJdGgtPmxhc3Rfc3BlZWRbMV0gPSAtMjsKCXRoLT5sYXN0X3ZhclswXSA9IC04MDsKCXRoLT5sYXN0X3ZhclsxXSA9IC04MDsKCglpZiAoZmFuX3NwZWVkICE9IC0xKSB7CgkJLyogbWFudWFsIG1vZGUsIHN0b3AgZmFucyAqLwoJCXdyaXRlX2JvdGhfZmFuX3NwZWVkKHRoLCAwKTsKCX0gZWxzZSB7CgkJLyogYXV0b21hdGljIG1vZGUgKi8KCQl3cml0ZV9ib3RoX2Zhbl9zcGVlZCh0aCwgLTEpOwoJfQoJCgl0aHJlYWRfdGhlcm0gPSBrdGhyZWFkX3J1bihtb25pdG9yX3Rhc2ssIHRoLCAia2ZhbmQiKTsKCglpZiAodGhyZWFkX3RoZXJtID09IEVSUl9QVFIoLUVOT01FTSkpIHsKCQlwcmludGsoS0VSTl9JTkZPICJhZHQ3NDZ4OiBLdGhyZWFkIGNyZWF0aW9uIGZhaWxlZFxuIik7CgkJdGhyZWFkX3RoZXJtID0gTlVMTDsKCQlyZXR1cm4gLUVOT01FTTsKCX0KCglyZXR1cm4gMDsKfQoKLyogCiAqIE5vdywgdW5mb3J0dW5hdGVseSwgc3lzZnMgZG9lc24ndCBnaXZlIHVzIGEgbmljZSB2b2lkICogd2UgY291bGQKICogcGFzcyBhcm91bmQgdG8gdGhlIGF0dHJpYnV0ZSBmdW5jdGlvbnMsIHNvIHdlIGRvbid0IHJlYWxseSBoYXZlCiAqIGNob2ljZSBidXQgaW1wbGVtZW50IGEgYnVuY2ggb2YgdGhlbS4uLgogKgogKi8KI2RlZmluZSBCVUlMRF9TSE9XX0ZVTkNfSU5UKG5hbWUsIGRhdGEpCQkJCVwKc3RhdGljIHNzaXplX3Qgc2hvd18jI25hbWUoc3RydWN0IGRldmljZSAqZGV2LCBjaGFyICpidWYpCVwKewkJCQkJCQkJXAoJcmV0dXJuIHNwcmludGYoYnVmLCAiJWRcbiIsIGRhdGEpOwkJCVwKfQoKI2RlZmluZSBCVUlMRF9TSE9XX0ZVTkNfRkFOKG5hbWUsIGRhdGEpCQkJCVwKc3RhdGljIHNzaXplX3Qgc2hvd18jI25hbWUoc3RydWN0IGRldmljZSAqZGV2LCBjaGFyICpidWYpICAgICAgIFwKewkJCQkJCQkJXAoJcmV0dXJuIHNwcmludGYoYnVmLCAiJWQgKCVkIHJwbSlcbiIsIAkJCVwKCQl0aGVybW9zdGF0LT5sYXN0X3NwZWVkW2RhdGFdLAkJCVwKCQlyZWFkX2Zhbl9zcGVlZCh0aGVybW9zdGF0LCBGQU5fU1BFRURbZGF0YV0pCVwKCQkpOwkJCQkJCVwKfQoKI2RlZmluZSBCVUlMRF9TVE9SRV9GVU5DX0RFRyhuYW1lLCBkYXRhKQkJCVwKc3RhdGljIHNzaXplX3Qgc3RvcmVfIyNuYW1lKHN0cnVjdCBkZXZpY2UgKmRldiwgY29uc3QgY2hhciAqYnVmLCBzaXplX3QgbikgXAp7CQkJCQkJCQlcCglpbnQgdmFsOwkJCQkJCVwKCWludCBpOwkJCQkJCQlcCgl2YWwgPSBzaW1wbGVfc3RydG9sKGJ1ZiwgTlVMTCwgMTApOwkJCVwKCXByaW50ayhLRVJOX0lORk8gIkFkanVzdGluZyBsaW1pdHMgYnkgJWSwQ1xuIiwgdmFsKTsJXAoJbGltaXRfYWRqdXN0ID0gdmFsOwkJCQkJXAoJZm9yIChpPTA7IGkgPCAzOyBpKyspCQkJCQlcCgkJc2V0X2xpbWl0KHRoZXJtb3N0YXQsIGkpOwkJCVwKCXJldHVybiBuOwkJCQkJCVwKfQoKI2RlZmluZSBCVUlMRF9TVE9SRV9GVU5DX0lOVChuYW1lLCBkYXRhKQkJCVwKc3RhdGljIHNzaXplX3Qgc3RvcmVfIyNuYW1lKHN0cnVjdCBkZXZpY2UgKmRldiwgY29uc3QgY2hhciAqYnVmLCBzaXplX3QgbikgXAp7CQkJCQkJCQlcCgl1MzIgdmFsOwkJCQkJCVwKCXZhbCA9IHNpbXBsZV9zdHJ0b3VsKGJ1ZiwgTlVMTCwgMTApOwkJCVwKCWlmICh2YWwgPCAwIHx8IHZhbCA+IDI1NSkJCQkJXAoJCXJldHVybiAtRUlOVkFMOwkJCQkJXAoJcHJpbnRrKEtFUk5fSU5GTyAiU2V0dGluZyBzcGVjaWZpZWQgZmFuIHNwZWVkIHRvICVkXG4iLCB2YWwpOwlcCglkYXRhID0gdmFsOwkJCQkJCVwKCXJldHVybiBuOwkJCQkJCVwKfQoKQlVJTERfU0hPV19GVU5DX0lOVChjcHVfdGVtcGVyYXR1cmUsCSAocmVhZF9yZWcodGhlcm1vc3RhdCwgVEVNUF9SRUdbMV0pKSkKQlVJTERfU0hPV19GVU5DX0lOVChncHVfdGVtcGVyYXR1cmUsCSAocmVhZF9yZWcodGhlcm1vc3RhdCwgVEVNUF9SRUdbMl0pKSkKQlVJTERfU0hPV19GVU5DX0lOVChjcHVfbGltaXQsCQkgdGhlcm1vc3RhdC0+bGltaXRzWzFdKQpCVUlMRF9TSE9XX0ZVTkNfSU5UKGdwdV9saW1pdCwJCSB0aGVybW9zdGF0LT5saW1pdHNbMl0pCgpCVUlMRF9TSE9XX0ZVTkNfSU5UKHNwZWNpZmllZF9mYW5fc3BlZWQsIGZhbl9zcGVlZCkKQlVJTERfU0hPV19GVU5DX0ZBTihjcHVfZmFuX3NwZWVkLAkgMCkKQlVJTERfU0hPV19GVU5DX0ZBTihncHVfZmFuX3NwZWVkLAkgMSkKCkJVSUxEX1NUT1JFX0ZVTkNfSU5UKHNwZWNpZmllZF9mYW5fc3BlZWQsZmFuX3NwZWVkKQpCVUlMRF9TSE9XX0ZVTkNfSU5UKGxpbWl0X2FkanVzdCwJIGxpbWl0X2FkanVzdCkKQlVJTERfU1RPUkVfRlVOQ19ERUcobGltaXRfYWRqdXN0LAkgdGhlcm1vc3RhdCkKCQkKc3RhdGljIERFVklDRV9BVFRSKGNwdV90ZW1wZXJhdHVyZSwJU19JUlVHTywKCQkgICBzaG93X2NwdV90ZW1wZXJhdHVyZSxOVUxMKTsKc3RhdGljIERFVklDRV9BVFRSKGdwdV90ZW1wZXJhdHVyZSwJU19JUlVHTywKCQkgICBzaG93X2dwdV90ZW1wZXJhdHVyZSxOVUxMKTsKc3RhdGljIERFVklDRV9BVFRSKGNwdV9saW1pdCwJCVNfSVJVR08sCgkJICAgc2hvd19jcHVfbGltaXQsCU5VTEwpOwpzdGF0aWMgREVWSUNFX0FUVFIoZ3B1X2xpbWl0LAkJU19JUlVHTywKCQkgICBzaG93X2dwdV9saW1pdCwJTlVMTCk7CgpzdGF0aWMgREVWSUNFX0FUVFIoc3BlY2lmaWVkX2Zhbl9zcGVlZCwJU19JUlVTUnxTX0lXVVNSfFNfSVJHUlB8U19JUk9USCwKCQkgICBzaG93X3NwZWNpZmllZF9mYW5fc3BlZWQsc3RvcmVfc3BlY2lmaWVkX2Zhbl9zcGVlZCk7CgpzdGF0aWMgREVWSUNFX0FUVFIoY3B1X2Zhbl9zcGVlZCwJU19JUlVHTywKCQkgICBzaG93X2NwdV9mYW5fc3BlZWQsCU5VTEwpOwpzdGF0aWMgREVWSUNFX0FUVFIoZ3B1X2Zhbl9zcGVlZCwJU19JUlVHTywKCQkgICBzaG93X2dwdV9mYW5fc3BlZWQsCU5VTEwpOwoKc3RhdGljIERFVklDRV9BVFRSKGxpbWl0X2FkanVzdCwJU19JUlVTUnxTX0lXVVNSfFNfSVJHUlB8U19JUk9USCwKCQkgICBzaG93X2xpbWl0X2FkanVzdCwJc3RvcmVfbGltaXRfYWRqdXN0KTsKCgpzdGF0aWMgaW50IF9faW5pdAp0aGVybW9zdGF0X2luaXQodm9pZCkKewoJc3RydWN0IGRldmljZV9ub2RlKiBucDsKCXUzMiAqcHJvcDsKCQoJbnAgPSBvZl9maW5kX25vZGVfYnlfbmFtZShOVUxMLCAiZmFuIik7CglpZiAoIW5wKQoJCXJldHVybiAtRU5PREVWOwoJaWYgKGRldmljZV9pc19jb21wYXRpYmxlKG5wLCAiYWR0NzQ2MCIpKQoJCXRoZXJtX3R5cGUgPSBBRFQ3NDYwOwoJZWxzZSBpZiAoZGV2aWNlX2lzX2NvbXBhdGlibGUobnAsICJhZHQ3NDY3IikpCgkJdGhlcm1fdHlwZSA9IEFEVDc0Njc7CgllbHNlCgkJcmV0dXJuIC1FTk9ERVY7CgoJcHJvcCA9ICh1MzIgKilnZXRfcHJvcGVydHkobnAsICJyZWciLCBOVUxMKTsKCWlmICghcHJvcCkKCQlyZXR1cm4gLUVOT0RFVjsKCgkvKiBsb29rIGZvciBidXMgZWl0aGVyIGJ5IHBhdGggb3IgdXNpbmcgInJlZyIgKi8KCWlmIChzdHJzdHIobnAtPmZ1bGxfbmFtZSwgIi9pMmMtYnVzQCIpICE9IE5VTEwpIHsKCQljb25zdCBjaGFyICp0bXBfYnVzID0gKHN0cnN0cihucC0+ZnVsbF9uYW1lLCAiL2kyYy1idXNAIikgKyA5KTsKCQl0aGVybV9idXMgPSB0bXBfYnVzWzBdLScwJzsKCX0gZWxzZSB7CgkJdGhlcm1fYnVzID0gKCgqcHJvcCkgPj4gOCkgJiAweDBmOwoJfQoKCXRoZXJtX2FkZHJlc3MgPSAoKCpwcm9wKSAmIDB4ZmYpID4+IDE7CgoJcHJpbnRrKEtFUk5fSU5GTyAiYWR0NzQ2eDogVGhlcm1vc3RhdCBidXM6ICVkLCBhZGRyZXNzOiAweCUwMngsICIKCQkJICJsaW1pdF9hZGp1c3Q6ICVkLCBmYW5fc3BlZWQ6ICVkXG4iLAoJCQkgdGhlcm1fYnVzLCB0aGVybV9hZGRyZXNzLCBsaW1pdF9hZGp1c3QsIGZhbl9zcGVlZCk7CgoJb2ZfZGV2ID0gb2ZfcGxhdGZvcm1fZGV2aWNlX2NyZWF0ZShucCwgInRlbXBlcmF0dXJlcyIpOwoJCglpZiAob2ZfZGV2ID09IE5VTEwpIHsKCQlwcmludGsoS0VSTl9FUlIgIkNhbid0IHJlZ2lzdGVyIHRlbXBlcmF0dXJlcyBkZXZpY2UgIVxuIik7CgkJcmV0dXJuIC1FTk9ERVY7Cgl9CgkKCWRldmljZV9jcmVhdGVfZmlsZSgmb2ZfZGV2LT5kZXYsICZkZXZfYXR0cl9jcHVfdGVtcGVyYXR1cmUpOwoJZGV2aWNlX2NyZWF0ZV9maWxlKCZvZl9kZXYtPmRldiwgJmRldl9hdHRyX2dwdV90ZW1wZXJhdHVyZSk7CglkZXZpY2VfY3JlYXRlX2ZpbGUoJm9mX2Rldi0+ZGV2LCAmZGV2X2F0dHJfY3B1X2xpbWl0KTsKCWRldmljZV9jcmVhdGVfZmlsZSgmb2ZfZGV2LT5kZXYsICZkZXZfYXR0cl9ncHVfbGltaXQpOwoJZGV2aWNlX2NyZWF0ZV9maWxlKCZvZl9kZXYtPmRldiwgJmRldl9hdHRyX2xpbWl0X2FkanVzdCk7CglkZXZpY2VfY3JlYXRlX2ZpbGUoJm9mX2Rldi0+ZGV2LCAmZGV2X2F0dHJfc3BlY2lmaWVkX2Zhbl9zcGVlZCk7CglkZXZpY2VfY3JlYXRlX2ZpbGUoJm9mX2Rldi0+ZGV2LCAmZGV2X2F0dHJfY3B1X2Zhbl9zcGVlZCk7CglpZih0aGVybV90eXBlID09IEFEVDc0NjApCgkJZGV2aWNlX2NyZWF0ZV9maWxlKCZvZl9kZXYtPmRldiwgJmRldl9hdHRyX2dwdV9mYW5fc3BlZWQpOwoKI2lmbmRlZiBDT05GSUdfSTJDX0tFWVdFU1QKCXJlcXVlc3RfbW9kdWxlKCJpMmMta2V5d2VzdCIpOwojZW5kaWYKCglyZXR1cm4gaTJjX2FkZF9kcml2ZXIoJnRoZXJtb3N0YXRfZHJpdmVyKTsKfQoKc3RhdGljIHZvaWQgX19leGl0CnRoZXJtb3N0YXRfZXhpdCh2b2lkKQp7CglpZiAob2ZfZGV2KSB7CgkJZGV2aWNlX3JlbW92ZV9maWxlKCZvZl9kZXYtPmRldiwgJmRldl9hdHRyX2NwdV90ZW1wZXJhdHVyZSk7CgkJZGV2aWNlX3JlbW92ZV9maWxlKCZvZl9kZXYtPmRldiwgJmRldl9hdHRyX2dwdV90ZW1wZXJhdHVyZSk7CgkJZGV2aWNlX3JlbW92ZV9maWxlKCZvZl9kZXYtPmRldiwgJmRldl9hdHRyX2NwdV9saW1pdCk7CgkJZGV2aWNlX3JlbW92ZV9maWxlKCZvZl9kZXYtPmRldiwgJmRldl9hdHRyX2dwdV9saW1pdCk7CgkJZGV2aWNlX3JlbW92ZV9maWxlKCZvZl9kZXYtPmRldiwgJmRldl9hdHRyX2xpbWl0X2FkanVzdCk7CgkJZGV2aWNlX3JlbW92ZV9maWxlKCZvZl9kZXYtPmRldiwgJmRldl9hdHRyX3NwZWNpZmllZF9mYW5fc3BlZWQpOwoJCWRldmljZV9yZW1vdmVfZmlsZSgmb2ZfZGV2LT5kZXYsICZkZXZfYXR0cl9jcHVfZmFuX3NwZWVkKTsKCgkJaWYodGhlcm1fdHlwZSA9PSBBRFQ3NDYwKQoJCQlkZXZpY2VfcmVtb3ZlX2ZpbGUoJm9mX2Rldi0+ZGV2LAoJCQkJCSAgICZkZXZfYXR0cl9ncHVfZmFuX3NwZWVkKTsKCgkJb2ZfZGV2aWNlX3VucmVnaXN0ZXIob2ZfZGV2KTsKCX0KCWkyY19kZWxfZHJpdmVyKCZ0aGVybW9zdGF0X2RyaXZlcik7Cn0KCm1vZHVsZV9pbml0KHRoZXJtb3N0YXRfaW5pdCk7Cm1vZHVsZV9leGl0KHRoZXJtb3N0YXRfZXhpdCk7Cg==