LyoKICogSTJPIENvbmZpZ3VyYXRpb24gSW50ZXJmYWNlIERyaXZlcgogKgogKiAoQykgQ29weXJpZ2h0IDE5OTktMjAwMiAgUmVkIEhhdAogKgogKiBXcml0dGVuIGJ5IEFsYW4gQ294LCBCdWlsZGluZyBOdW1iZXIgVGhyZWUgTHRkCiAqCiAqIEZpeGVzL2FkZGl0aW9uczoKICoJRGVlcGFrIFNheGVuYSAoMDQvMjAvMTk5OSk6CiAqCQlBZGRlZCBiYXNpYyBpb2N0bCgpIHN1cHBvcnQKICoJRGVlcGFrIFNheGVuYSAoMDYvMDcvMTk5OSk6CiAqCQlBZGRlZCBzb2Z0d2FyZSBkb3dubG9hZCBpb2N0bCAoc3RpbGwgdGVzdGluZykKICoJQXV2byBI5GtraW5lbiAoMDkvMTAvMTk5OSk6CiAqCQlDaGFuZ2VzIHRvIGkyb19jZmdfcmVwbHkoKSwgaW9jdGxfcGFybXMoKQogKgkJQWRkZWQgaW9jdF92YWxpZGF0ZSgpCiAqCVRhbmVsaSBW5Gjka2FuZ2FzICgwOS8zMC8xOTk5KToKICoJCUZpeGVkIGlvY3RsX3N3ZGwoKQogKglUYW5lbGkgVuRo5GthbmdhcyAoMTAvMDQvMTk5OSk6CiAqCQlDaGFuZ2VkIGlvY3RsX3N3ZGwoKSwgaW1wbGVtZW50ZWQgaW9jdGxfc3d1bCgpIGFuZCBpb2N0bF9zd2RlbCgpCiAqCURlZXBhayBTYXhlbmEgKDExLzE4LzE5OTkpOgogKgkJQWRkZWQgZXZlbnQgbWFuYWdtZW5ldCBzdXBwb3J0CiAqCUFsYW4gQ294IDxhbGFuQHJlZGhhdC5jb20+OgogKgkJMi40IHJld3JpdGUgcG9ydGVkIHRvIDIuNQogKglNYXJrdXMgTGlkZWwgPE1hcmt1cy5MaWRlbEBzaGFkb3djb25uZWN0LmNvbT46CiAqCQlBZGRlZCBwYXNzLXRocnUgc3VwcG9ydCBmb3IgQWRhcHRlYydzIHJhaWR1dGlscwogKgogKiBUaGlzIHByb2dyYW0gaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIgdmVyc2lvbgogKiAyIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKi8KCiNpbmNsdWRlIDxsaW51eC9taXNjZGV2aWNlLmg+CiNpbmNsdWRlIDxsaW51eC9zbXBfbG9jay5oPgojaW5jbHVkZSA8bGludXgvY29tcGF0Lmg+CgojaW5jbHVkZSA8YXNtL3VhY2Nlc3MuaD4KCiNpbmNsdWRlICJjb3JlLmgiCgojZGVmaW5lIFNHX1RBQkxFU0laRQkJMzAKCnN0YXRpYyBpbnQgaTJvX2NmZ19pb2N0bChzdHJ1Y3QgaW5vZGUgKmlub2RlLCBzdHJ1Y3QgZmlsZSAqZnAsIHVuc2lnbmVkIGludCBjbWQsCgkJCSB1bnNpZ25lZCBsb25nIGFyZyk7CgpzdGF0aWMgc3BpbmxvY2tfdCBpMm9fY29uZmlnX2xvY2s7CgojZGVmaW5lIE1PRElOQyh4LHkpICgoeCkgPSAoKHgpICsgMSkgJSAoeSkpCgpzdHJ1Y3Qgc2dfc2ltcGxlX2VsZW1lbnQgewoJdTMyIGZsYWdfY291bnQ7Cgl1MzIgYWRkcl9idXM7Cn07CgpzdHJ1Y3QgaTJvX2NmZ19pbmZvIHsKCXN0cnVjdCBmaWxlICpmcDsKCXN0cnVjdCBmYXN5bmNfc3RydWN0ICpmYXN5bmM7CglzdHJ1Y3QgaTJvX2V2dF9pbmZvIGV2ZW50X3FbSTJPX0VWVF9RX0xFTl07Cgl1MTYgcV9pbjsJCS8vIFF1ZXVlIGhlYWQgaW5kZXgKCXUxNiBxX291dDsJCS8vIFF1ZXVlIHRhaWwgaW5kZXgKCXUxNiBxX2xlbjsJCS8vIFF1ZXVlIGxlbmd0aAoJdTE2IHFfbG9zdDsJCS8vIE51bWJlciBvZiBsb3N0IGV2ZW50cwoJdWxvbmcgcV9pZDsJCS8vIEV2ZW50IHF1ZXVlIElELi4udXNlZCBhcyB0eF9jb250ZXh0CglzdHJ1Y3QgaTJvX2NmZ19pbmZvICpuZXh0Owp9OwpzdGF0aWMgc3RydWN0IGkyb19jZmdfaW5mbyAqb3Blbl9maWxlcyA9IE5VTEw7CnN0YXRpYyB1bG9uZyBpMm9fY2ZnX2luZm9faWQgPSAwOwoKc3RhdGljIGludCBpMm9fY2ZnX2dldGlvcHModW5zaWduZWQgbG9uZyBhcmcpCnsKCXN0cnVjdCBpMm9fY29udHJvbGxlciAqYzsKCXU4IF9fdXNlciAqdXNlcl9pb3BfdGFibGUgPSAodm9pZCBfX3VzZXIgKilhcmc7Cgl1OCB0bXBbTUFYX0kyT19DT05UUk9MTEVSU107CglpbnQgcmV0ID0gMDsKCgltZW1zZXQodG1wLCAwLCBNQVhfSTJPX0NPTlRST0xMRVJTKTsKCglsaXN0X2Zvcl9lYWNoX2VudHJ5KGMsICZpMm9fY29udHJvbGxlcnMsIGxpc3QpCgkgICAgdG1wW2MtPnVuaXRdID0gMTsKCglpZiAoY29weV90b191c2VyKHVzZXJfaW9wX3RhYmxlLCB0bXAsIE1BWF9JMk9fQ09OVFJPTExFUlMpKQoJCXJldCA9IC1FRkFVTFQ7CgoJcmV0dXJuIHJldDsKfTsKCnN0YXRpYyBpbnQgaTJvX2NmZ19nZXRocnQodW5zaWduZWQgbG9uZyBhcmcpCnsKCXN0cnVjdCBpMm9fY29udHJvbGxlciAqYzsKCXN0cnVjdCBpMm9fY21kX2hydGxjdCBfX3VzZXIgKmNtZCA9IChzdHJ1Y3QgaTJvX2NtZF9ocnRsY3QgX191c2VyICopYXJnOwoJc3RydWN0IGkyb19jbWRfaHJ0bGN0IGtjbWQ7CglpMm9faHJ0ICpocnQ7CglpbnQgbGVuOwoJdTMyIHJlc2xlbjsKCWludCByZXQgPSAwOwoKCWlmIChjb3B5X2Zyb21fdXNlcigma2NtZCwgY21kLCBzaXplb2Yoc3RydWN0IGkyb19jbWRfaHJ0bGN0KSkpCgkJcmV0dXJuIC1FRkFVTFQ7CgoJaWYgKGdldF91c2VyKHJlc2xlbiwga2NtZC5yZXNsZW4pIDwgMCkKCQlyZXR1cm4gLUVGQVVMVDsKCglpZiAoa2NtZC5yZXNidWYgPT0gTlVMTCkKCQlyZXR1cm4gLUVGQVVMVDsKCgljID0gaTJvX2ZpbmRfaW9wKGtjbWQuaW9wKTsKCWlmICghYykKCQlyZXR1cm4gLUVOWElPOwoKCWhydCA9IChpMm9faHJ0ICopIGMtPmhydC52aXJ0OwoKCWxlbiA9IDggKyAoKGhydC0+ZW50cnlfbGVuICogaHJ0LT5udW1fZW50cmllcykgPDwgMik7CgoJLyogV2UgZGlkIGEgZ2V0IHVzZXIuLi5zbyBhc3N1bWluZyBtZW0gaXMgb2suLi5pcyB0aGlzIGJhZD8gKi8KCXB1dF91c2VyKGxlbiwga2NtZC5yZXNsZW4pOwoJaWYgKGxlbiA+IHJlc2xlbikKCQlyZXQgPSAtRU5PQlVGUzsKCWlmIChjb3B5X3RvX3VzZXIoa2NtZC5yZXNidWYsICh2b2lkICopaHJ0LCBsZW4pKQoJCXJldCA9IC1FRkFVTFQ7CgoJcmV0dXJuIHJldDsKfTsKCnN0YXRpYyBpbnQgaTJvX2NmZ19nZXRsY3QodW5zaWduZWQgbG9uZyBhcmcpCnsKCXN0cnVjdCBpMm9fY29udHJvbGxlciAqYzsKCXN0cnVjdCBpMm9fY21kX2hydGxjdCBfX3VzZXIgKmNtZCA9IChzdHJ1Y3QgaTJvX2NtZF9ocnRsY3QgX191c2VyICopYXJnOwoJc3RydWN0IGkyb19jbWRfaHJ0bGN0IGtjbWQ7CglpMm9fbGN0ICpsY3Q7CglpbnQgbGVuOwoJaW50IHJldCA9IDA7Cgl1MzIgcmVzbGVuOwoKCWlmIChjb3B5X2Zyb21fdXNlcigma2NtZCwgY21kLCBzaXplb2Yoc3RydWN0IGkyb19jbWRfaHJ0bGN0KSkpCgkJcmV0dXJuIC1FRkFVTFQ7CgoJaWYgKGdldF91c2VyKHJlc2xlbiwga2NtZC5yZXNsZW4pIDwgMCkKCQlyZXR1cm4gLUVGQVVMVDsKCglpZiAoa2NtZC5yZXNidWYgPT0gTlVMTCkKCQlyZXR1cm4gLUVGQVVMVDsKCgljID0gaTJvX2ZpbmRfaW9wKGtjbWQuaW9wKTsKCWlmICghYykKCQlyZXR1cm4gLUVOWElPOwoKCWxjdCA9IChpMm9fbGN0ICopIGMtPmxjdDsKCglsZW4gPSAodW5zaWduZWQgaW50KWxjdC0+dGFibGVfc2l6ZSA8PCAyOwoJcHV0X3VzZXIobGVuLCBrY21kLnJlc2xlbik7CglpZiAobGVuID4gcmVzbGVuKQoJCXJldCA9IC1FTk9CVUZTOwoJZWxzZSBpZiAoY29weV90b191c2VyKGtjbWQucmVzYnVmLCBsY3QsIGxlbikpCgkJcmV0ID0gLUVGQVVMVDsKCglyZXR1cm4gcmV0Owp9OwoKc3RhdGljIGludCBpMm9fY2ZnX3Bhcm1zKHVuc2lnbmVkIGxvbmcgYXJnLCB1bnNpZ25lZCBpbnQgdHlwZSkKewoJaW50IHJldCA9IDA7CglzdHJ1Y3QgaTJvX2NvbnRyb2xsZXIgKmM7CglzdHJ1Y3QgaTJvX2RldmljZSAqZGV2OwoJc3RydWN0IGkyb19jbWRfcHNldGdldCBfX3VzZXIgKmNtZCA9CgkgICAgKHN0cnVjdCBpMm9fY21kX3BzZXRnZXQgX191c2VyICopYXJnOwoJc3RydWN0IGkyb19jbWRfcHNldGdldCBrY21kOwoJdTMyIHJlc2xlbjsKCXU4ICpvcHM7Cgl1OCAqcmVzOwoJaW50IGxlbiA9IDA7CgoJdTMyIGkyb19jbWQgPSAodHlwZSA9PSBJMk9QQVJNR0VUID8KCQkgICAgICAgSTJPX0NNRF9VVElMX1BBUkFNU19HRVQgOiBJMk9fQ01EX1VUSUxfUEFSQU1TX1NFVCk7CgoJaWYgKGNvcHlfZnJvbV91c2VyKCZrY21kLCBjbWQsIHNpemVvZihzdHJ1Y3QgaTJvX2NtZF9wc2V0Z2V0KSkpCgkJcmV0dXJuIC1FRkFVTFQ7CgoJaWYgKGdldF91c2VyKHJlc2xlbiwga2NtZC5yZXNsZW4pKQoJCXJldHVybiAtRUZBVUxUOwoKCWMgPSBpMm9fZmluZF9pb3Aoa2NtZC5pb3ApOwoJaWYgKCFjKQoJCXJldHVybiAtRU5YSU87CgoJZGV2ID0gaTJvX2lvcF9maW5kX2RldmljZShjLCBrY21kLnRpZCk7CglpZiAoIWRldikKCQlyZXR1cm4gLUVOWElPOwoKCW9wcyA9ICh1OCAqKSBrbWFsbG9jKGtjbWQub3BsZW4sIEdGUF9LRVJORUwpOwoJaWYgKCFvcHMpCgkJcmV0dXJuIC1FTk9NRU07CgoJaWYgKGNvcHlfZnJvbV91c2VyKG9wcywga2NtZC5vcGJ1Ziwga2NtZC5vcGxlbikpIHsKCQlrZnJlZShvcHMpOwoJCXJldHVybiAtRUZBVUxUOwoJfQoKCS8qCgkgKiBJdCdzIHBvc3NpYmxlIHRvIGhhdmUgYSBfdmVyeV8gbGFyZ2UgdGFibGUKCSAqIGFuZCB0aGF0IHRoZSB1c2VyIGFza3MgZm9yIGFsbCBvZiBpdCBhdCBvbmNlLi4uCgkgKi8KCXJlcyA9ICh1OCAqKSBrbWFsbG9jKDY1NTM2LCBHRlBfS0VSTkVMKTsKCWlmICghcmVzKSB7CgkJa2ZyZWUob3BzKTsKCQlyZXR1cm4gLUVOT01FTTsKCX0KCglsZW4gPSBpMm9fcGFybV9pc3N1ZShkZXYsIGkyb19jbWQsIG9wcywga2NtZC5vcGxlbiwgcmVzLCA2NTUzNik7CglrZnJlZShvcHMpOwoKCWlmIChsZW4gPCAwKSB7CgkJa2ZyZWUocmVzKTsKCQlyZXR1cm4gLUVBR0FJTjsKCX0KCglwdXRfdXNlcihsZW4sIGtjbWQucmVzbGVuKTsKCWlmIChsZW4gPiByZXNsZW4pCgkJcmV0ID0gLUVOT0JVRlM7CgllbHNlIGlmIChjb3B5X3RvX3VzZXIoa2NtZC5yZXNidWYsIHJlcywgbGVuKSkKCQlyZXQgPSAtRUZBVUxUOwoKCWtmcmVlKHJlcyk7CgoJcmV0dXJuIHJldDsKfTsKCnN0YXRpYyBpbnQgaTJvX2NmZ19zd2RsKHVuc2lnbmVkIGxvbmcgYXJnKQp7CglzdHJ1Y3QgaTJvX3N3X3hmZXIga3hmZXI7CglzdHJ1Y3QgaTJvX3N3X3hmZXIgX191c2VyICpweGZlciA9IChzdHJ1Y3QgaTJvX3N3X3hmZXIgX191c2VyICopYXJnOwoJdW5zaWduZWQgY2hhciBtYXhmcmFnID0gMCwgY3VyZnJhZyA9IDE7CglzdHJ1Y3QgaTJvX2RtYSBidWZmZXI7CglzdHJ1Y3QgaTJvX21lc3NhZ2UgX19pb21lbSAqbXNnOwoJdTMyIG07Cgl1bnNpZ25lZCBpbnQgc3RhdHVzID0gMCwgc3dsZW4gPSAwLCBmcmFnc2l6ZSA9IDgxOTI7CglzdHJ1Y3QgaTJvX2NvbnRyb2xsZXIgKmM7CgoJaWYgKGNvcHlfZnJvbV91c2VyKCZreGZlciwgcHhmZXIsIHNpemVvZihzdHJ1Y3QgaTJvX3N3X3hmZXIpKSkKCQlyZXR1cm4gLUVGQVVMVDsKCglpZiAoZ2V0X3VzZXIoc3dsZW4sIGt4ZmVyLnN3bGVuKSA8IDApCgkJcmV0dXJuIC1FRkFVTFQ7CgoJaWYgKGdldF91c2VyKG1heGZyYWcsIGt4ZmVyLm1heGZyYWcpIDwgMCkKCQlyZXR1cm4gLUVGQVVMVDsKCglpZiAoZ2V0X3VzZXIoY3VyZnJhZywga3hmZXIuY3VyZnJhZykgPCAwKQoJCXJldHVybiAtRUZBVUxUOwoKCWlmIChjdXJmcmFnID09IG1heGZyYWcpCgkJZnJhZ3NpemUgPSBzd2xlbiAtIChtYXhmcmFnIC0gMSkgKiA4MTkyOwoKCWlmICgha3hmZXIuYnVmIHx8ICFhY2Nlc3Nfb2soVkVSSUZZX1JFQUQsIGt4ZmVyLmJ1ZiwgZnJhZ3NpemUpKQoJCXJldHVybiAtRUZBVUxUOwoKCWMgPSBpMm9fZmluZF9pb3Aoa3hmZXIuaW9wKTsKCWlmICghYykKCQlyZXR1cm4gLUVOWElPOwoKCW0gPSBpMm9fbXNnX2dldF93YWl0KGMsICZtc2csIEkyT19USU1FT1VUX01FU1NBR0VfR0VUKTsKCWlmIChtID09IEkyT19RVUVVRV9FTVBUWSkKCQlyZXR1cm4gLUVCVVNZOwoKCWlmIChpMm9fZG1hX2FsbG9jKCZjLT5wZGV2LT5kZXYsICZidWZmZXIsIGZyYWdzaXplLCBHRlBfS0VSTkVMKSkgewoJCWkyb19tc2dfbm9wKGMsIG0pOwoJCXJldHVybiAtRU5PTUVNOwoJfQoKCV9fY29weV9mcm9tX3VzZXIoYnVmZmVyLnZpcnQsIGt4ZmVyLmJ1ZiwgZnJhZ3NpemUpOwoKCXdyaXRlbChOSU5FX1dPUkRfTVNHX1NJWkUgfCBTR0xfT0ZGU0VUXzcsICZtc2ctPnUuaGVhZFswXSk7Cgl3cml0ZWwoSTJPX0NNRF9TV19ET1dOTE9BRCA8PCAyNCB8IEhPU1RfVElEIDw8IDEyIHwgQURBUFRFUl9USUQsCgkgICAgICAgJm1zZy0+dS5oZWFkWzFdKTsKCXdyaXRlbChpMm9fY29uZmlnX2RyaXZlci5jb250ZXh0LCAmbXNnLT51LmhlYWRbMl0pOwoJd3JpdGVsKDAsICZtc2ctPnUuaGVhZFszXSk7Cgl3cml0ZWwoKCgodTMyKSBreGZlci5mbGFncykgPDwgMjQpIHwgKCgodTMyKSBreGZlci5zd190eXBlKSA8PCAxNikgfAoJICAgICAgICgoKHUzMikgbWF4ZnJhZykgPDwgOCkgfCAoKCh1MzIpIGN1cmZyYWcpKSwgJm1zZy0+Ym9keVswXSk7Cgl3cml0ZWwoc3dsZW4sICZtc2ctPmJvZHlbMV0pOwoJd3JpdGVsKGt4ZmVyLnN3X2lkLCAmbXNnLT5ib2R5WzJdKTsKCXdyaXRlbCgweEQwMDAwMDAwIHwgZnJhZ3NpemUsICZtc2ctPmJvZHlbM10pOwoJd3JpdGVsKGJ1ZmZlci5waHlzLCAmbXNnLT5ib2R5WzRdKTsKCglvc21fZGVidWcoInN3ZGwgZnJhZyAlZC8lZCAoc2l6ZSAlZClcbiIsIGN1cmZyYWcsIG1heGZyYWcsIGZyYWdzaXplKTsKCXN0YXR1cyA9IGkyb19tc2dfcG9zdF93YWl0X21lbShjLCBtLCA2MCwgJmJ1ZmZlcik7CgoJaWYgKHN0YXR1cyAhPSAtRVRJTUVET1VUKQoJCWkyb19kbWFfZnJlZSgmYy0+cGRldi0+ZGV2LCAmYnVmZmVyKTsKCglpZiAoc3RhdHVzICE9IEkyT19QT1NUX1dBSVRfT0spIHsKCQkvLyBpdCBmYWlscyBpZiB5b3UgdHJ5IGFuZCBzZW5kIGZyYWdzIG91dCBvZiBvcmRlcgoJCS8vIGFuZCBmb3Igc29tZSB5ZXQgdW5rbm93biByZWFzb25zIHRvbwoJCW9zbV9pbmZvKCJzd2RsIGZhaWxlZCwgRGV0YWlsZWRTdGF0dXMgPSAlZFxuIiwgc3RhdHVzKTsKCQlyZXR1cm4gc3RhdHVzOwoJfQoKCXJldHVybiAwOwp9OwoKc3RhdGljIGludCBpMm9fY2ZnX3N3dWwodW5zaWduZWQgbG9uZyBhcmcpCnsKCXN0cnVjdCBpMm9fc3dfeGZlciBreGZlcjsKCXN0cnVjdCBpMm9fc3dfeGZlciBfX3VzZXIgKnB4ZmVyID0gKHN0cnVjdCBpMm9fc3dfeGZlciBfX3VzZXIgKilhcmc7Cgl1bnNpZ25lZCBjaGFyIG1heGZyYWcgPSAwLCBjdXJmcmFnID0gMTsKCXN0cnVjdCBpMm9fZG1hIGJ1ZmZlcjsKCXN0cnVjdCBpMm9fbWVzc2FnZSBfX2lvbWVtICptc2c7Cgl1MzIgbTsKCXVuc2lnbmVkIGludCBzdGF0dXMgPSAwLCBzd2xlbiA9IDAsIGZyYWdzaXplID0gODE5MjsKCXN0cnVjdCBpMm9fY29udHJvbGxlciAqYzsKCWludCByZXQgPSAwOwoKCWlmIChjb3B5X2Zyb21fdXNlcigma3hmZXIsIHB4ZmVyLCBzaXplb2Yoc3RydWN0IGkyb19zd194ZmVyKSkpCgkJZ290byByZXR1cm5fZmF1bHQ7CgoJaWYgKGdldF91c2VyKHN3bGVuLCBreGZlci5zd2xlbikgPCAwKQoJCWdvdG8gcmV0dXJuX2ZhdWx0OwoKCWlmIChnZXRfdXNlcihtYXhmcmFnLCBreGZlci5tYXhmcmFnKSA8IDApCgkJZ290byByZXR1cm5fZmF1bHQ7CgoJaWYgKGdldF91c2VyKGN1cmZyYWcsIGt4ZmVyLmN1cmZyYWcpIDwgMCkKCQlnb3RvIHJldHVybl9mYXVsdDsKCglpZiAoY3VyZnJhZyA9PSBtYXhmcmFnKQoJCWZyYWdzaXplID0gc3dsZW4gLSAobWF4ZnJhZyAtIDEpICogODE5MjsKCglpZiAoIWt4ZmVyLmJ1ZikKCQlnb3RvIHJldHVybl9mYXVsdDsKCgljID0gaTJvX2ZpbmRfaW9wKGt4ZmVyLmlvcCk7CglpZiAoIWMpCgkJcmV0dXJuIC1FTlhJTzsKCgltID0gaTJvX21zZ19nZXRfd2FpdChjLCAmbXNnLCBJMk9fVElNRU9VVF9NRVNTQUdFX0dFVCk7CglpZiAobSA9PSBJMk9fUVVFVUVfRU1QVFkpCgkJcmV0dXJuIC1FQlVTWTsKCglpZiAoaTJvX2RtYV9hbGxvYygmYy0+cGRldi0+ZGV2LCAmYnVmZmVyLCBmcmFnc2l6ZSwgR0ZQX0tFUk5FTCkpIHsKCQlpMm9fbXNnX25vcChjLCBtKTsKCQlyZXR1cm4gLUVOT01FTTsKCX0KCgl3cml0ZWwoTklORV9XT1JEX01TR19TSVpFIHwgU0dMX09GRlNFVF83LCAmbXNnLT51LmhlYWRbMF0pOwoJd3JpdGVsKEkyT19DTURfU1dfVVBMT0FEIDw8IDI0IHwgSE9TVF9USUQgPDwgMTIgfCBBREFQVEVSX1RJRCwKCSAgICAgICAmbXNnLT51LmhlYWRbMV0pOwoJd3JpdGVsKGkyb19jb25maWdfZHJpdmVyLmNvbnRleHQsICZtc2ctPnUuaGVhZFsyXSk7Cgl3cml0ZWwoMCwgJm1zZy0+dS5oZWFkWzNdKTsKCXdyaXRlbCgodTMyKSBreGZlci5mbGFncyA8PCAyNCB8ICh1MzIpIGt4ZmVyLgoJICAgICAgIHN3X3R5cGUgPDwgMTYgfCAodTMyKSBtYXhmcmFnIDw8IDggfCAodTMyKSBjdXJmcmFnLAoJICAgICAgICZtc2ctPmJvZHlbMF0pOwoJd3JpdGVsKHN3bGVuLCAmbXNnLT5ib2R5WzFdKTsKCXdyaXRlbChreGZlci5zd19pZCwgJm1zZy0+Ym9keVsyXSk7Cgl3cml0ZWwoMHhEMDAwMDAwMCB8IGZyYWdzaXplLCAmbXNnLT5ib2R5WzNdKTsKCXdyaXRlbChidWZmZXIucGh5cywgJm1zZy0+Ym9keVs0XSk7CgoJb3NtX2RlYnVnKCJzd3VsIGZyYWcgJWQvJWQgKHNpemUgJWQpXG4iLCBjdXJmcmFnLCBtYXhmcmFnLCBmcmFnc2l6ZSk7CglzdGF0dXMgPSBpMm9fbXNnX3Bvc3Rfd2FpdF9tZW0oYywgbSwgNjAsICZidWZmZXIpOwoKCWlmIChzdGF0dXMgIT0gSTJPX1BPU1RfV0FJVF9PSykgewoJCWlmIChzdGF0dXMgIT0gLUVUSU1FRE9VVCkKCQkJaTJvX2RtYV9mcmVlKCZjLT5wZGV2LT5kZXYsICZidWZmZXIpOwoKCQlvc21faW5mbygic3d1bCBmYWlsZWQsIERldGFpbGVkU3RhdHVzID0gJWRcbiIsIHN0YXR1cyk7CgkJcmV0dXJuIHN0YXR1czsKCX0KCglpZiAoY29weV90b191c2VyKGt4ZmVyLmJ1ZiwgYnVmZmVyLnZpcnQsIGZyYWdzaXplKSkKCQlyZXQgPSAtRUZBVUxUOwoKCWkyb19kbWFfZnJlZSgmYy0+cGRldi0+ZGV2LCAmYnVmZmVyKTsKCiAgICAgIHJldHVybl9yZXQ6CglyZXR1cm4gcmV0OwogICAgICByZXR1cm5fZmF1bHQ6CglyZXQgPSAtRUZBVUxUOwoJZ290byByZXR1cm5fcmV0Owp9OwoKc3RhdGljIGludCBpMm9fY2ZnX3N3ZGVsKHVuc2lnbmVkIGxvbmcgYXJnKQp7CglzdHJ1Y3QgaTJvX2NvbnRyb2xsZXIgKmM7CglzdHJ1Y3QgaTJvX3N3X3hmZXIga3hmZXI7CglzdHJ1Y3QgaTJvX3N3X3hmZXIgX191c2VyICpweGZlciA9IChzdHJ1Y3QgaTJvX3N3X3hmZXIgX191c2VyICopYXJnOwoJc3RydWN0IGkyb19tZXNzYWdlIF9faW9tZW0gKm1zZzsKCXUzMiBtOwoJdW5zaWduZWQgaW50IHN3bGVuOwoJaW50IHRva2VuOwoKCWlmIChjb3B5X2Zyb21fdXNlcigma3hmZXIsIHB4ZmVyLCBzaXplb2Yoc3RydWN0IGkyb19zd194ZmVyKSkpCgkJcmV0dXJuIC1FRkFVTFQ7CgoJaWYgKGdldF91c2VyKHN3bGVuLCBreGZlci5zd2xlbikgPCAwKQoJCXJldHVybiAtRUZBVUxUOwoKCWMgPSBpMm9fZmluZF9pb3Aoa3hmZXIuaW9wKTsKCWlmICghYykKCQlyZXR1cm4gLUVOWElPOwoKCW0gPSBpMm9fbXNnX2dldF93YWl0KGMsICZtc2csIEkyT19USU1FT1VUX01FU1NBR0VfR0VUKTsKCWlmIChtID09IEkyT19RVUVVRV9FTVBUWSkKCQlyZXR1cm4gLUVCVVNZOwoKCXdyaXRlbChTRVZFTl9XT1JEX01TR19TSVpFIHwgU0dMX09GRlNFVF8wLCAmbXNnLT51LmhlYWRbMF0pOwoJd3JpdGVsKEkyT19DTURfU1dfUkVNT1ZFIDw8IDI0IHwgSE9TVF9USUQgPDwgMTIgfCBBREFQVEVSX1RJRCwKCSAgICAgICAmbXNnLT51LmhlYWRbMV0pOwoJd3JpdGVsKGkyb19jb25maWdfZHJpdmVyLmNvbnRleHQsICZtc2ctPnUuaGVhZFsyXSk7Cgl3cml0ZWwoMCwgJm1zZy0+dS5oZWFkWzNdKTsKCXdyaXRlbCgodTMyKSBreGZlci5mbGFncyA8PCAyNCB8ICh1MzIpIGt4ZmVyLnN3X3R5cGUgPDwgMTYsCgkgICAgICAgJm1zZy0+Ym9keVswXSk7Cgl3cml0ZWwoc3dsZW4sICZtc2ctPmJvZHlbMV0pOwoJd3JpdGVsKGt4ZmVyLnN3X2lkLCAmbXNnLT5ib2R5WzJdKTsKCgl0b2tlbiA9IGkyb19tc2dfcG9zdF93YWl0KGMsIG0sIDEwKTsKCglpZiAodG9rZW4gIT0gSTJPX1BPU1RfV0FJVF9PSykgewoJCW9zbV9pbmZvKCJzd2RlbCBmYWlsZWQsIERldGFpbGVkU3RhdHVzID0gJWRcbiIsIHRva2VuKTsKCQlyZXR1cm4gLUVUSU1FRE9VVDsKCX0KCglyZXR1cm4gMDsKfTsKCnN0YXRpYyBpbnQgaTJvX2NmZ192YWxpZGF0ZSh1bnNpZ25lZCBsb25nIGFyZykKewoJaW50IHRva2VuOwoJaW50IGlvcCA9IChpbnQpYXJnOwoJc3RydWN0IGkyb19tZXNzYWdlIF9faW9tZW0gKm1zZzsKCXUzMiBtOwoJc3RydWN0IGkyb19jb250cm9sbGVyICpjOwoKCWMgPSBpMm9fZmluZF9pb3AoaW9wKTsKCWlmICghYykKCQlyZXR1cm4gLUVOWElPOwoKCW0gPSBpMm9fbXNnX2dldF93YWl0KGMsICZtc2csIEkyT19USU1FT1VUX01FU1NBR0VfR0VUKTsKCWlmIChtID09IEkyT19RVUVVRV9FTVBUWSkKCQlyZXR1cm4gLUVCVVNZOwoKCXdyaXRlbChGT1VSX1dPUkRfTVNHX1NJWkUgfCBTR0xfT0ZGU0VUXzAsICZtc2ctPnUuaGVhZFswXSk7Cgl3cml0ZWwoSTJPX0NNRF9DT05GSUdfVkFMSURBVEUgPDwgMjQgfCBIT1NUX1RJRCA8PCAxMiB8IGlvcCwKCSAgICAgICAmbXNnLT51LmhlYWRbMV0pOwoJd3JpdGVsKGkyb19jb25maWdfZHJpdmVyLmNvbnRleHQsICZtc2ctPnUuaGVhZFsyXSk7Cgl3cml0ZWwoMCwgJm1zZy0+dS5oZWFkWzNdKTsKCgl0b2tlbiA9IGkyb19tc2dfcG9zdF93YWl0KGMsIG0sIDEwKTsKCglpZiAodG9rZW4gIT0gSTJPX1BPU1RfV0FJVF9PSykgewoJCW9zbV9pbmZvKCJDYW4ndCB2YWxpZGF0ZSBjb25maWd1cmF0aW9uLCBFcnJvclN0YXR1cyA9ICVkXG4iLAoJCQkgdG9rZW4pOwoJCXJldHVybiAtRVRJTUVET1VUOwoJfQoKCXJldHVybiAwOwp9OwoKc3RhdGljIGludCBpMm9fY2ZnX2V2dF9yZWcodW5zaWduZWQgbG9uZyBhcmcsIHN0cnVjdCBmaWxlICpmcCkKewoJc3RydWN0IGkyb19tZXNzYWdlIF9faW9tZW0gKm1zZzsKCXUzMiBtOwoJc3RydWN0IGkyb19ldnRfaWQgX191c2VyICpwZGVzYyA9IChzdHJ1Y3QgaTJvX2V2dF9pZCBfX3VzZXIgKilhcmc7CglzdHJ1Y3QgaTJvX2V2dF9pZCBrZGVzYzsKCXN0cnVjdCBpMm9fY29udHJvbGxlciAqYzsKCXN0cnVjdCBpMm9fZGV2aWNlICpkOwoKCWlmIChjb3B5X2Zyb21fdXNlcigma2Rlc2MsIHBkZXNjLCBzaXplb2Yoc3RydWN0IGkyb19ldnRfaWQpKSkKCQlyZXR1cm4gLUVGQVVMVDsKCgkvKiBJT1AgZXhpc3RzPyAqLwoJYyA9IGkyb19maW5kX2lvcChrZGVzYy5pb3ApOwoJaWYgKCFjKQoJCXJldHVybiAtRU5YSU87CgoJLyogRGV2aWNlIGV4aXN0cz8gKi8KCWQgPSBpMm9faW9wX2ZpbmRfZGV2aWNlKGMsIGtkZXNjLnRpZCk7CglpZiAoIWQpCgkJcmV0dXJuIC1FTk9ERVY7CgoJbSA9IGkyb19tc2dfZ2V0X3dhaXQoYywgJm1zZywgSTJPX1RJTUVPVVRfTUVTU0FHRV9HRVQpOwoJaWYgKG0gPT0gSTJPX1FVRVVFX0VNUFRZKQoJCXJldHVybiAtRUJVU1k7CgoJd3JpdGVsKEZPVVJfV09SRF9NU0dfU0laRSB8IFNHTF9PRkZTRVRfMCwgJm1zZy0+dS5oZWFkWzBdKTsKCXdyaXRlbChJMk9fQ01EX1VUSUxfRVZUX1JFR0lTVEVSIDw8IDI0IHwgSE9TVF9USUQgPDwgMTIgfCBrZGVzYy50aWQsCgkgICAgICAgJm1zZy0+dS5oZWFkWzFdKTsKCXdyaXRlbChpMm9fY29uZmlnX2RyaXZlci5jb250ZXh0LCAmbXNnLT51LmhlYWRbMl0pOwoJd3JpdGVsKGkyb19jbnR4dF9saXN0X2FkZChjLCBmcC0+cHJpdmF0ZV9kYXRhKSwgJm1zZy0+dS5oZWFkWzNdKTsKCXdyaXRlbChrZGVzYy5ldnRfbWFzaywgJm1zZy0+Ym9keVswXSk7CgoJaTJvX21zZ19wb3N0KGMsIG0pOwoKCXJldHVybiAwOwp9CgpzdGF0aWMgaW50IGkyb19jZmdfZXZ0X2dldCh1bnNpZ25lZCBsb25nIGFyZywgc3RydWN0IGZpbGUgKmZwKQp7CglzdHJ1Y3QgaTJvX2NmZ19pbmZvICpwID0gTlVMTDsKCXN0cnVjdCBpMm9fZXZ0X2dldCBfX3VzZXIgKnVnZXQgPSAoc3RydWN0IGkyb19ldnRfZ2V0IF9fdXNlciAqKWFyZzsKCXN0cnVjdCBpMm9fZXZ0X2dldCBrZ2V0OwoJdW5zaWduZWQgbG9uZyBmbGFnczsKCglmb3IgKHAgPSBvcGVuX2ZpbGVzOyBwOyBwID0gcC0+bmV4dCkKCQlpZiAocC0+cV9pZCA9PSAodWxvbmcpIGZwLT5wcml2YXRlX2RhdGEpCgkJCWJyZWFrOwoKCWlmICghcC0+cV9sZW4pCgkJcmV0dXJuIC1FTk9FTlQ7CgoJbWVtY3B5KCZrZ2V0LmluZm8sICZwLT5ldmVudF9xW3AtPnFfb3V0XSwgc2l6ZW9mKHN0cnVjdCBpMm9fZXZ0X2luZm8pKTsKCU1PRElOQyhwLT5xX291dCwgSTJPX0VWVF9RX0xFTik7CglzcGluX2xvY2tfaXJxc2F2ZSgmaTJvX2NvbmZpZ19sb2NrLCBmbGFncyk7CglwLT5xX2xlbi0tOwoJa2dldC5wZW5kaW5nID0gcC0+cV9sZW47CglrZ2V0Lmxvc3QgPSBwLT5xX2xvc3Q7CglzcGluX3VubG9ja19pcnFyZXN0b3JlKCZpMm9fY29uZmlnX2xvY2ssIGZsYWdzKTsKCglpZiAoY29weV90b191c2VyKHVnZXQsICZrZ2V0LCBzaXplb2Yoc3RydWN0IGkyb19ldnRfZ2V0KSkpCgkJcmV0dXJuIC1FRkFVTFQ7CglyZXR1cm4gMDsKfQoKI2lmZGVmIENPTkZJR19JMk9fRVhUX0FEQVBURUMKI2lmZGVmIENPTkZJR19DT01QQVQKc3RhdGljIGludCBpMm9fY2ZnX3Bhc3N0aHJ1MzIoc3RydWN0IGZpbGUgKmZpbGUsIHVuc2lnbmVkIGNtbmQsCgkJCSAgICAgIHVuc2lnbmVkIGxvbmcgYXJnKQp7CglzdHJ1Y3QgaTJvX2NtZF9wYXNzdGhydTMyIF9fdXNlciAqY21kOwoJc3RydWN0IGkyb19jb250cm9sbGVyICpjOwoJdTMyIF9fdXNlciAqdXNlcl9tc2c7Cgl1MzIgKnJlcGx5ID0gTlVMTDsKCXUzMiBfX3VzZXIgKnVzZXJfcmVwbHkgPSBOVUxMOwoJdTMyIHNpemUgPSAwOwoJdTMyIHJlcGx5X3NpemUgPSAwOwoJdTMyIHJjb2RlID0gMDsKCXN0cnVjdCBpMm9fZG1hIHNnX2xpc3RbU0dfVEFCTEVTSVpFXTsKCXUzMiBzZ19vZmZzZXQgPSAwOwoJdTMyIHNnX2NvdW50ID0gMDsKCXUzMiBpID0gMDsKCXUzMiBzZ19pbmRleCA9IDA7CglpMm9fc3RhdHVzX2Jsb2NrICpzYjsKCXN0cnVjdCBpMm9fbWVzc2FnZSAqbXNnOwoJdTMyIG07Cgl1bnNpZ25lZCBpbnQgaW9wOwoKCWNtZCA9IChzdHJ1Y3QgaTJvX2NtZF9wYXNzdGhydTMyIF9fdXNlciAqKWFyZzsKCglpZiAoZ2V0X3VzZXIoaW9wLCAmY21kLT5pb3ApIHx8IGdldF91c2VyKGksICZjbWQtPm1zZykpCgkJcmV0dXJuIC1FRkFVTFQ7CgoJdXNlcl9tc2cgPSBjb21wYXRfcHRyKGkpOwoKCWMgPSBpMm9fZmluZF9pb3AoaW9wKTsKCWlmICghYykgewoJCW9zbV9kZWJ1ZygiY29udHJvbGxlciAlZCBub3QgZm91bmRcbiIsIGlvcCk7CgkJcmV0dXJuIC1FTlhJTzsKCX0KCgltID0gaTJvX21zZ19nZXRfd2FpdChjLCAmbXNnLCBJMk9fVElNRU9VVF9NRVNTQUdFX0dFVCk7CgoJc2IgPSBjLT5zdGF0dXNfYmxvY2sudmlydDsKCglpZiAoZ2V0X3VzZXIoc2l6ZSwgJnVzZXJfbXNnWzBdKSkgewoJCW9zbV93YXJuKCJ1bmFibGUgdG8gZ2V0IHNpemUhXG4iKTsKCQlyZXR1cm4gLUVGQVVMVDsKCX0KCXNpemUgPSBzaXplID4+IDE2OwoKCWlmIChzaXplID4gc2ItPmluYm91bmRfZnJhbWVfc2l6ZSkgewoJCW9zbV93YXJuKCJzaXplIG9mIG1lc3NhZ2UgPiBpbmJvdW5kX2ZyYW1lX3NpemUiKTsKCQlyZXR1cm4gLUVGQVVMVDsKCX0KCgl1c2VyX3JlcGx5ID0gJnVzZXJfbXNnW3NpemVdOwoKCXNpemUgPDw9IDI7CQkvLyBDb252ZXJ0IHRvIGJ5dGVzCgoJLyogQ29weSBpbiB0aGUgdXNlcidzIEkyTyBjb21tYW5kICovCglpZiAoY29weV9mcm9tX3VzZXIobXNnLCB1c2VyX21zZywgc2l6ZSkpIHsKCQlvc21fd2FybigidW5hYmxlIHRvIGNvcHkgdXNlciBtZXNzYWdlXG4iKTsKCQlyZXR1cm4gLUVGQVVMVDsKCX0KCWkyb19kdW1wX21lc3NhZ2UobXNnKTsKCglpZiAoZ2V0X3VzZXIocmVwbHlfc2l6ZSwgJnVzZXJfcmVwbHlbMF0pIDwgMCkKCQlyZXR1cm4gLUVGQVVMVDsKCglyZXBseV9zaXplID4+PSAxNjsKCXJlcGx5X3NpemUgPDw9IDI7CgoJcmVwbHkgPSBrbWFsbG9jKHJlcGx5X3NpemUsIEdGUF9LRVJORUwpOwoJaWYgKCFyZXBseSkgewoJCXByaW50ayhLRVJOX1dBUk5JTkcgIiVzOiBDb3VsZCBub3QgYWxsb2NhdGUgcmVwbHkgYnVmZmVyXG4iLAoJCSAgICAgICBjLT5uYW1lKTsKCQlyZXR1cm4gLUVOT01FTTsKCX0KCW1lbXNldChyZXBseSwgMCwgcmVwbHlfc2l6ZSk7CgoJc2dfb2Zmc2V0ID0gKG1zZy0+dS5oZWFkWzBdID4+IDQpICYgMHgwZjsKCgl3cml0ZWwoaTJvX2NvbmZpZ19kcml2ZXIuY29udGV4dCwgJm1zZy0+dS5zLmljbnR4dCk7Cgl3cml0ZWwoaTJvX2NudHh0X2xpc3RfYWRkKGMsIHJlcGx5KSwgJm1zZy0+dS5zLnRjbnR4dCk7CgoJbWVtc2V0KHNnX2xpc3QsIDAsIHNpemVvZihzZ19saXN0WzBdKSAqIFNHX1RBQkxFU0laRSk7CglpZiAoc2dfb2Zmc2V0KSB7CgkJc3RydWN0IHNnX3NpbXBsZV9lbGVtZW50ICpzZzsKCgkJaWYgKHNnX29mZnNldCAqIDQgPj0gc2l6ZSkgewoJCQlyY29kZSA9IC1FRkFVTFQ7CgkJCWdvdG8gY2xlYW51cDsKCQl9CgkJLy8gVE9ETyA2NGJpdCBmaXgKCQlzZyA9IChzdHJ1Y3Qgc2dfc2ltcGxlX2VsZW1lbnQgKikoKCZtc2ctPnUuaGVhZFswXSkgKwoJCQkJCQkgIHNnX29mZnNldCk7CgkJc2dfY291bnQgPQoJCSAgICAoc2l6ZSAtIHNnX29mZnNldCAqIDQpIC8gc2l6ZW9mKHN0cnVjdCBzZ19zaW1wbGVfZWxlbWVudCk7CgkJaWYgKHNnX2NvdW50ID4gU0dfVEFCTEVTSVpFKSB7CgkJCXByaW50ayhLRVJOX0RFQlVHICIlczpJT0NUTCBTRyBMaXN0IHRvbyBsYXJnZSAoJXUpXG4iLAoJCQkgICAgICAgYy0+bmFtZSwgc2dfY291bnQpOwoJCQlyY29kZSA9IC1FSU5WQUw7CgkJCWdvdG8gY2xlYW51cDsKCQl9CgoJCWZvciAoaSA9IDA7IGkgPCBzZ19jb3VudDsgaSsrKSB7CgkJCWludCBzZ19zaXplOwoJCQlzdHJ1Y3QgaTJvX2RtYSAqcDsKCgkJCWlmICghKHNnW2ldLmZsYWdfY291bnQgJiAweDEwMDAwMDAwCgkJCSAgICAgIC8qSTJPX1NHTF9GTEFHU19TSU1QTEVfQUREUkVTU19FTEVNRU5UICovICkpIHsKCQkJCXByaW50ayhLRVJOX0RFQlVHCgkJCQkgICAgICAgIiVzOkJhZCBTRyBlbGVtZW50ICVkIC0gbm90IHNpbXBsZSAoJXgpXG4iLAoJCQkJICAgICAgIGMtPm5hbWUsIGksIHNnW2ldLmZsYWdfY291bnQpOwoJCQkJcmNvZGUgPSAtRUlOVkFMOwoJCQkJZ290byBjbGVhbnVwOwoJCQl9CgkJCXNnX3NpemUgPSBzZ1tpXS5mbGFnX2NvdW50ICYgMHhmZmZmZmY7CgkJCXAgPSAmKHNnX2xpc3Rbc2dfaW5kZXgrK10pOwoJCQkvKiBBbGxvY2F0ZSBtZW1vcnkgZm9yIHRoZSB0cmFuc2ZlciAqLwoJCQlpZiAoaTJvX2RtYV9hbGxvYwoJCQkgICAgKCZjLT5wZGV2LT5kZXYsIHAsIHNnX3NpemUsCgkJCSAgICAgUENJX0RNQV9CSURJUkVDVElPTkFMKSkgewoJCQkJcHJpbnRrKEtFUk5fREVCVUcKCQkJCSAgICAgICAiJXM6IENvdWxkIG5vdCBhbGxvY2F0ZSBTRyBidWZmZXIgLSBzaXplID0gJWQgYnVmZmVyIG51bWJlciAlZCBvZiAlZFxuIiwKCQkJCSAgICAgICBjLT5uYW1lLCBzZ19zaXplLCBpLCBzZ19jb3VudCk7CgkJCQlyY29kZSA9IC1FTk9NRU07CgkJCQlnb3RvIHNnX2xpc3RfY2xlYW51cDsKCQkJfQoJCQkvKiBDb3B5IGluIHRoZSB1c2VyJ3MgU0cgYnVmZmVyIGlmIG5lY2Vzc2FyeSAqLwoJCQlpZiAoc2dbaV0uCgkJCSAgICBmbGFnX2NvdW50ICYgMHgwNDAwMDAwMCAvKkkyT19TR0xfRkxBR1NfRElSICovICkgewoJCQkJLy8gVE9ETyA2NGJpdCBmaXgKCQkJCWlmIChjb3B5X2Zyb21fdXNlcgoJCQkJICAgIChwLT52aXJ0LAoJCQkJICAgICAodm9pZCBfX3VzZXIgKikodW5zaWduZWQgbG9uZylzZ1tpXS4KCQkJCSAgICAgYWRkcl9idXMsIHNnX3NpemUpKSB7CgkJCQkJcHJpbnRrKEtFUk5fREVCVUcKCQkJCQkgICAgICAgIiVzOiBDb3VsZCBub3QgY29weSBTRyBidWYgJWQgRlJPTSB1c2VyXG4iLAoJCQkJCSAgICAgICBjLT5uYW1lLCBpKTsKCQkJCQlyY29kZSA9IC1FRkFVTFQ7CgkJCQkJZ290byBzZ19saXN0X2NsZWFudXA7CgkJCQl9CgkJCX0KCQkJLy9UT0RPIDY0Yml0IGZpeAoJCQlzZ1tpXS5hZGRyX2J1cyA9ICh1MzIpIHAtPnBoeXM7CgkJfQoJfQoKCXJjb2RlID0gaTJvX21zZ19wb3N0X3dhaXQoYywgbSwgNjApOwoJaWYgKHJjb2RlKQoJCWdvdG8gc2dfbGlzdF9jbGVhbnVwOwoKCWlmIChzZ19vZmZzZXQpIHsKCQl1MzIgbXNnW0kyT19PVVRCT1VORF9NU0dfRlJBTUVfU0laRV07CgkJLyogQ29weSBiYWNrIHRoZSBTY2F0dGVyIEdhdGhlciBidWZmZXJzIGJhY2sgdG8gdXNlciBzcGFjZSAqLwoJCXUzMiBqOwoJCS8vIFRPRE8gNjRiaXQgZml4CgkJc3RydWN0IHNnX3NpbXBsZV9lbGVtZW50ICpzZzsKCQlpbnQgc2dfc2l6ZTsKCgkJLy8gcmUtYWNxdWlyZSB0aGUgb3JpZ2luYWwgbWVzc2FnZSB0byBoYW5kbGUgY29ycmVjdGx5IHRoZSBzZyBjb3B5IG9wZXJhdGlvbgoJCW1lbXNldCgmbXNnLCAwLCBJMk9fT1VUQk9VTkRfTVNHX0ZSQU1FX1NJWkUgKiA0KTsKCQkvLyBnZXQgdXNlciBtc2cgc2l6ZSBpbiB1MzJzCgkJaWYgKGdldF91c2VyKHNpemUsICZ1c2VyX21zZ1swXSkpIHsKCQkJcmNvZGUgPSAtRUZBVUxUOwoJCQlnb3RvIHNnX2xpc3RfY2xlYW51cDsKCQl9CgkJc2l6ZSA9IHNpemUgPj4gMTY7CgkJc2l6ZSAqPSA0OwoJCS8qIENvcHkgaW4gdGhlIHVzZXIncyBJMk8gY29tbWFuZCAqLwoJCWlmIChjb3B5X2Zyb21fdXNlcihtc2csIHVzZXJfbXNnLCBzaXplKSkgewoJCQlyY29kZSA9IC1FRkFVTFQ7CgkJCWdvdG8gc2dfbGlzdF9jbGVhbnVwOwoJCX0KCQlzZ19jb3VudCA9CgkJICAgIChzaXplIC0gc2dfb2Zmc2V0ICogNCkgLyBzaXplb2Yoc3RydWN0IHNnX3NpbXBsZV9lbGVtZW50KTsKCgkJLy8gVE9ETyA2NGJpdCBmaXgKCQlzZyA9IChzdHJ1Y3Qgc2dfc2ltcGxlX2VsZW1lbnQgKikobXNnICsgc2dfb2Zmc2V0KTsKCQlmb3IgKGogPSAwOyBqIDwgc2dfY291bnQ7IGorKykgewoJCQkvKiBDb3B5IG91dCB0aGUgU0cgbGlzdCB0byB1c2VyJ3MgYnVmZmVyIGlmIG5lY2Vzc2FyeSAqLwoJCQlpZiAoIQoJCQkgICAgKHNnW2pdLgoJCQkgICAgIGZsYWdfY291bnQgJiAweDQwMDAwMDAgLypJMk9fU0dMX0ZMQUdTX0RJUiAqLyApKSB7CgkJCQlzZ19zaXplID0gc2dbal0uZmxhZ19jb3VudCAmIDB4ZmZmZmZmOwoJCQkJLy8gVE9ETyA2NGJpdCBmaXgKCQkJCWlmIChjb3B5X3RvX3VzZXIKCQkJCSAgICAoKHZvaWQgX191c2VyICopKHU2NCkgc2dbal0uYWRkcl9idXMsCgkJCQkgICAgIHNnX2xpc3Rbal0udmlydCwgc2dfc2l6ZSkpIHsKCQkJCQlwcmludGsoS0VSTl9XQVJOSU5HCgkJCQkJICAgICAgICIlczogQ291bGQgbm90IGNvcHkgJXAgVE8gdXNlciAleFxuIiwKCQkJCQkgICAgICAgYy0+bmFtZSwgc2dfbGlzdFtqXS52aXJ0LAoJCQkJCSAgICAgICBzZ1tqXS5hZGRyX2J1cyk7CgkJCQkJcmNvZGUgPSAtRUZBVUxUOwoJCQkJCWdvdG8gc2dfbGlzdF9jbGVhbnVwOwoJCQkJfQoJCQl9CgkJfQoJfQoKCS8qIENvcHkgYmFjayB0aGUgcmVwbHkgdG8gdXNlciBzcGFjZSAqLwoJaWYgKHJlcGx5X3NpemUpIHsKCQkvLyB3ZSB3cm90ZSBvdXIgb3duIHZhbHVlcyBmb3IgY29udGV4dCAtIG5vdyByZXN0b3JlIHRoZSB1c2VyIHN1cHBsaWVkIG9uZXMKCQlpZiAoY29weV9mcm9tX3VzZXIocmVwbHkgKyAyLCB1c2VyX21zZyArIDIsIHNpemVvZih1MzIpICogMikpIHsKCQkJcHJpbnRrKEtFUk5fV0FSTklORwoJCQkgICAgICAgIiVzOiBDb3VsZCBub3QgY29weSBtZXNzYWdlIGNvbnRleHQgRlJPTSB1c2VyXG4iLAoJCQkgICAgICAgYy0+bmFtZSk7CgkJCXJjb2RlID0gLUVGQVVMVDsKCQkJZ290byBzZ19saXN0X2NsZWFudXA7CgkJfQoJCWlmIChjb3B5X3RvX3VzZXIodXNlcl9yZXBseSwgcmVwbHksIHJlcGx5X3NpemUpKSB7CgkJCXByaW50ayhLRVJOX1dBUk5JTkcKCQkJICAgICAgICIlczogQ291bGQgbm90IGNvcHkgcmVwbHkgVE8gdXNlclxuIiwgYy0+bmFtZSk7CgkJCXJjb2RlID0gLUVGQVVMVDsKCQl9Cgl9CgogICAgICBzZ19saXN0X2NsZWFudXA6Cglmb3IgKGkgPSAwOyBpIDwgc2dfaW5kZXg7IGkrKykKCQlpMm9fZG1hX2ZyZWUoJmMtPnBkZXYtPmRldiwgJnNnX2xpc3RbaV0pOwoKICAgICAgY2xlYW51cDoKCWtmcmVlKHJlcGx5KTsKCXJldHVybiByY29kZTsKfQoKc3RhdGljIGxvbmcgaTJvX2NmZ19jb21wYXRfaW9jdGwoc3RydWN0IGZpbGUgKmZpbGUsIHVuc2lnbmVkIGNtZCwKCQkJCSB1bnNpZ25lZCBsb25nIGFyZykKewoJaW50IHJldDsKCWxvY2tfa2VybmVsKCk7Cglzd2l0Y2ggKGNtZCkgewoJY2FzZSBJMk9HRVRJT1BTOgoJCXJldCA9IGkyb19jZmdfaW9jdGwoTlVMTCwgZmlsZSwgY21kLCBhcmcpOwoJCWJyZWFrOwoJY2FzZSBJMk9QQVNTVEhSVTMyOgoJCXJldCA9IGkyb19jZmdfcGFzc3RocnUzMihmaWxlLCBjbWQsIGFyZyk7CgkJYnJlYWs7CglkZWZhdWx0OgoJCXJldCA9IC1FTk9JT0NUTENNRDsKCQlicmVhazsKCX0KCXVubG9ja19rZXJuZWwoKTsKCXJldHVybiByZXQ7Cn0KCiNlbmRpZgoKc3RhdGljIGludCBpMm9fY2ZnX3Bhc3N0aHJ1KHVuc2lnbmVkIGxvbmcgYXJnKQp7CglzdHJ1Y3QgaTJvX2NtZF9wYXNzdGhydSBfX3VzZXIgKmNtZCA9CgkgICAgKHN0cnVjdCBpMm9fY21kX3Bhc3N0aHJ1IF9fdXNlciAqKWFyZzsKCXN0cnVjdCBpMm9fY29udHJvbGxlciAqYzsKCXUzMiBfX3VzZXIgKnVzZXJfbXNnOwoJdTMyICpyZXBseSA9IE5VTEw7Cgl1MzIgX191c2VyICp1c2VyX3JlcGx5ID0gTlVMTDsKCXUzMiBzaXplID0gMDsKCXUzMiByZXBseV9zaXplID0gMDsKCXUzMiByY29kZSA9IDA7Cgl2b2lkICpzZ19saXN0W1NHX1RBQkxFU0laRV07Cgl1MzIgc2dfb2Zmc2V0ID0gMDsKCXUzMiBzZ19jb3VudCA9IDA7CglpbnQgc2dfaW5kZXggPSAwOwoJdTMyIGkgPSAwOwoJdm9pZCAqcCA9IE5VTEw7CglpMm9fc3RhdHVzX2Jsb2NrICpzYjsKCXN0cnVjdCBpMm9fbWVzc2FnZSBfX2lvbWVtICptc2c7Cgl1MzIgbTsKCXVuc2lnbmVkIGludCBpb3A7CgoJaWYgKGdldF91c2VyKGlvcCwgJmNtZC0+aW9wKSB8fCBnZXRfdXNlcih1c2VyX21zZywgJmNtZC0+bXNnKSkKCQlyZXR1cm4gLUVGQVVMVDsKCgljID0gaTJvX2ZpbmRfaW9wKGlvcCk7CglpZiAoIWMpIHsKCQlvc21fd2FybigiY29udHJvbGxlciAlZCBub3QgZm91bmRcbiIsIGlvcCk7CgkJcmV0dXJuIC1FTlhJTzsKCX0KCgltID0gaTJvX21zZ19nZXRfd2FpdChjLCAmbXNnLCBJMk9fVElNRU9VVF9NRVNTQUdFX0dFVCk7CgoJc2IgPSBjLT5zdGF0dXNfYmxvY2sudmlydDsKCglpZiAoZ2V0X3VzZXIoc2l6ZSwgJnVzZXJfbXNnWzBdKSkKCQlyZXR1cm4gLUVGQVVMVDsKCXNpemUgPSBzaXplID4+IDE2OwoKCWlmIChzaXplID4gc2ItPmluYm91bmRfZnJhbWVfc2l6ZSkgewoJCW9zbV93YXJuKCJzaXplIG9mIG1lc3NhZ2UgPiBpbmJvdW5kX2ZyYW1lX3NpemUiKTsKCQlyZXR1cm4gLUVGQVVMVDsKCX0KCgl1c2VyX3JlcGx5ID0gJnVzZXJfbXNnW3NpemVdOwoKCXNpemUgPDw9IDI7CQkvLyBDb252ZXJ0IHRvIGJ5dGVzCgoJLyogQ29weSBpbiB0aGUgdXNlcidzIEkyTyBjb21tYW5kICovCglpZiAoY29weV9mcm9tX3VzZXIobXNnLCB1c2VyX21zZywgc2l6ZSkpCgkJcmV0dXJuIC1FRkFVTFQ7CgoJaWYgKGdldF91c2VyKHJlcGx5X3NpemUsICZ1c2VyX3JlcGx5WzBdKSA8IDApCgkJcmV0dXJuIC1FRkFVTFQ7CgoJcmVwbHlfc2l6ZSA+Pj0gMTY7CglyZXBseV9zaXplIDw8PSAyOwoKCXJlcGx5ID0ga21hbGxvYyhyZXBseV9zaXplLCBHRlBfS0VSTkVMKTsKCWlmICghcmVwbHkpIHsKCQlwcmludGsoS0VSTl9XQVJOSU5HICIlczogQ291bGQgbm90IGFsbG9jYXRlIHJlcGx5IGJ1ZmZlclxuIiwKCQkgICAgICAgYy0+bmFtZSk7CgkJcmV0dXJuIC1FTk9NRU07Cgl9CgltZW1zZXQocmVwbHksIDAsIHJlcGx5X3NpemUpOwoKCXNnX29mZnNldCA9IChtc2ctPnUuaGVhZFswXSA+PiA0KSAmIDB4MGY7CgoJd3JpdGVsKGkyb19jb25maWdfZHJpdmVyLmNvbnRleHQsICZtc2ctPnUucy5pY250eHQpOwoJd3JpdGVsKGkyb19jbnR4dF9saXN0X2FkZChjLCByZXBseSksICZtc2ctPnUucy50Y250eHQpOwoKCW1lbXNldChzZ19saXN0LCAwLCBzaXplb2Yoc2dfbGlzdFswXSkgKiBTR19UQUJMRVNJWkUpOwoJaWYgKHNnX29mZnNldCkgewoJCXN0cnVjdCBzZ19zaW1wbGVfZWxlbWVudCAqc2c7CgoJCWlmIChzZ19vZmZzZXQgKiA0ID49IHNpemUpIHsKCQkJcmNvZGUgPSAtRUZBVUxUOwoJCQlnb3RvIGNsZWFudXA7CgkJfQoJCS8vIFRPRE8gNjRiaXQgZml4CgkJc2cgPSAoc3RydWN0IHNnX3NpbXBsZV9lbGVtZW50ICopKCgmbXNnLT51LmhlYWRbMF0pICsKCQkJCQkJICBzZ19vZmZzZXQpOwoJCXNnX2NvdW50ID0KCQkgICAgKHNpemUgLSBzZ19vZmZzZXQgKiA0KSAvIHNpemVvZihzdHJ1Y3Qgc2dfc2ltcGxlX2VsZW1lbnQpOwoJCWlmIChzZ19jb3VudCA+IFNHX1RBQkxFU0laRSkgewoJCQlwcmludGsoS0VSTl9ERUJVRyAiJXM6SU9DVEwgU0cgTGlzdCB0b28gbGFyZ2UgKCV1KVxuIiwKCQkJICAgICAgIGMtPm5hbWUsIHNnX2NvdW50KTsKCQkJcmNvZGUgPSAtRUlOVkFMOwoJCQlnb3RvIGNsZWFudXA7CgkJfQoKCQlmb3IgKGkgPSAwOyBpIDwgc2dfY291bnQ7IGkrKykgewoJCQlpbnQgc2dfc2l6ZTsKCgkJCWlmICghKHNnW2ldLmZsYWdfY291bnQgJiAweDEwMDAwMDAwCgkJCSAgICAgIC8qSTJPX1NHTF9GTEFHU19TSU1QTEVfQUREUkVTU19FTEVNRU5UICovICkpIHsKCQkJCXByaW50ayhLRVJOX0RFQlVHCgkJCQkgICAgICAgIiVzOkJhZCBTRyBlbGVtZW50ICVkIC0gbm90IHNpbXBsZSAoJXgpXG4iLAoJCQkJICAgICAgIGMtPm5hbWUsIGksIHNnW2ldLmZsYWdfY291bnQpOwoJCQkJcmNvZGUgPSAtRUlOVkFMOwoJCQkJZ290byBzZ19saXN0X2NsZWFudXA7CgkJCX0KCQkJc2dfc2l6ZSA9IHNnW2ldLmZsYWdfY291bnQgJiAweGZmZmZmZjsKCQkJLyogQWxsb2NhdGUgbWVtb3J5IGZvciB0aGUgdHJhbnNmZXIgKi8KCQkJcCA9IGttYWxsb2Moc2dfc2l6ZSwgR0ZQX0tFUk5FTCk7CgkJCWlmICghcCkgewoJCQkJcHJpbnRrKEtFUk5fREVCVUcKCQkJCSAgICAgICAiJXM6IENvdWxkIG5vdCBhbGxvY2F0ZSBTRyBidWZmZXIgLSBzaXplID0gJWQgYnVmZmVyIG51bWJlciAlZCBvZiAlZFxuIiwKCQkJCSAgICAgICBjLT5uYW1lLCBzZ19zaXplLCBpLCBzZ19jb3VudCk7CgkJCQlyY29kZSA9IC1FTk9NRU07CgkJCQlnb3RvIHNnX2xpc3RfY2xlYW51cDsKCQkJfQoJCQlzZ19saXN0W3NnX2luZGV4KytdID0gcDsJLy8gc2dsaXN0IGluZGV4ZWQgd2l0aCBpbnB1dCBmcmFtZSwgbm90IG91ciBpbnRlcm5hbCBmcmFtZS4KCQkJLyogQ29weSBpbiB0aGUgdXNlcidzIFNHIGJ1ZmZlciBpZiBuZWNlc3NhcnkgKi8KCQkJaWYgKHNnW2ldLgoJCQkgICAgZmxhZ19jb3VudCAmIDB4MDQwMDAwMDAgLypJMk9fU0dMX0ZMQUdTX0RJUiAqLyApIHsKCQkJCS8vIFRPRE8gNjRiaXQgZml4CgkJCQlpZiAoY29weV9mcm9tX3VzZXIKCQkJCSAgICAocCwgKHZvaWQgX191c2VyICopc2dbaV0uYWRkcl9idXMsCgkJCQkgICAgIHNnX3NpemUpKSB7CgkJCQkJcHJpbnRrKEtFUk5fREVCVUcKCQkJCQkgICAgICAgIiVzOiBDb3VsZCBub3QgY29weSBTRyBidWYgJWQgRlJPTSB1c2VyXG4iLAoJCQkJCSAgICAgICBjLT5uYW1lLCBpKTsKCQkJCQlyY29kZSA9IC1FRkFVTFQ7CgkJCQkJZ290byBzZ19saXN0X2NsZWFudXA7CgkJCQl9CgkJCX0KCQkJLy9UT0RPIDY0Yml0IGZpeAoJCQlzZ1tpXS5hZGRyX2J1cyA9IHZpcnRfdG9fYnVzKHApOwoJCX0KCX0KCglyY29kZSA9IGkyb19tc2dfcG9zdF93YWl0KGMsIG0sIDYwKTsKCWlmIChyY29kZSkKCQlnb3RvIHNnX2xpc3RfY2xlYW51cDsKCglpZiAoc2dfb2Zmc2V0KSB7CgkJdTMyIG1zZ1sxMjhdOwoJCS8qIENvcHkgYmFjayB0aGUgU2NhdHRlciBHYXRoZXIgYnVmZmVycyBiYWNrIHRvIHVzZXIgc3BhY2UgKi8KCQl1MzIgajsKCQkvLyBUT0RPIDY0Yml0IGZpeAoJCXN0cnVjdCBzZ19zaW1wbGVfZWxlbWVudCAqc2c7CgkJaW50IHNnX3NpemU7CgoJCS8vIHJlLWFjcXVpcmUgdGhlIG9yaWdpbmFsIG1lc3NhZ2UgdG8gaGFuZGxlIGNvcnJlY3RseSB0aGUgc2cgY29weSBvcGVyYXRpb24KCQltZW1zZXQoJm1zZywgMCwgSTJPX09VVEJPVU5EX01TR19GUkFNRV9TSVpFICogNCk7CgkJLy8gZ2V0IHVzZXIgbXNnIHNpemUgaW4gdTMycwoJCWlmIChnZXRfdXNlcihzaXplLCAmdXNlcl9tc2dbMF0pKSB7CgkJCXJjb2RlID0gLUVGQVVMVDsKCQkJZ290byBzZ19saXN0X2NsZWFudXA7CgkJfQoJCXNpemUgPSBzaXplID4+IDE2OwoJCXNpemUgKj0gNDsKCQkvKiBDb3B5IGluIHRoZSB1c2VyJ3MgSTJPIGNvbW1hbmQgKi8KCQlpZiAoY29weV9mcm9tX3VzZXIobXNnLCB1c2VyX21zZywgc2l6ZSkpIHsKCQkJcmNvZGUgPSAtRUZBVUxUOwoJCQlnb3RvIHNnX2xpc3RfY2xlYW51cDsKCQl9CgkJc2dfY291bnQgPQoJCSAgICAoc2l6ZSAtIHNnX29mZnNldCAqIDQpIC8gc2l6ZW9mKHN0cnVjdCBzZ19zaW1wbGVfZWxlbWVudCk7CgoJCS8vIFRPRE8gNjRiaXQgZml4CgkJc2cgPSAoc3RydWN0IHNnX3NpbXBsZV9lbGVtZW50ICopKG1zZyArIHNnX29mZnNldCk7CgkJZm9yIChqID0gMDsgaiA8IHNnX2NvdW50OyBqKyspIHsKCQkJLyogQ29weSBvdXQgdGhlIFNHIGxpc3QgdG8gdXNlcidzIGJ1ZmZlciBpZiBuZWNlc3NhcnkgKi8KCQkJaWYgKCEKCQkJICAgIChzZ1tqXS4KCQkJICAgICBmbGFnX2NvdW50ICYgMHg0MDAwMDAwIC8qSTJPX1NHTF9GTEFHU19ESVIgKi8gKSkgewoJCQkJc2dfc2l6ZSA9IHNnW2pdLmZsYWdfY291bnQgJiAweGZmZmZmZjsKCQkJCS8vIFRPRE8gNjRiaXQgZml4CgkJCQlpZiAoY29weV90b191c2VyCgkJCQkgICAgKCh2b2lkIF9fdXNlciAqKXNnW2pdLmFkZHJfYnVzLCBzZ19saXN0W2pdLAoJCQkJICAgICBzZ19zaXplKSkgewoJCQkJCXByaW50ayhLRVJOX1dBUk5JTkcKCQkJCQkgICAgICAgIiVzOiBDb3VsZCBub3QgY29weSAlcCBUTyB1c2VyICV4XG4iLAoJCQkJCSAgICAgICBjLT5uYW1lLCBzZ19saXN0W2pdLAoJCQkJCSAgICAgICBzZ1tqXS5hZGRyX2J1cyk7CgkJCQkJcmNvZGUgPSAtRUZBVUxUOwoJCQkJCWdvdG8gc2dfbGlzdF9jbGVhbnVwOwoJCQkJfQoJCQl9CgkJfQoJfQoKCS8qIENvcHkgYmFjayB0aGUgcmVwbHkgdG8gdXNlciBzcGFjZSAqLwoJaWYgKHJlcGx5X3NpemUpIHsKCQkvLyB3ZSB3cm90ZSBvdXIgb3duIHZhbHVlcyBmb3IgY29udGV4dCAtIG5vdyByZXN0b3JlIHRoZSB1c2VyIHN1cHBsaWVkIG9uZXMKCQlpZiAoY29weV9mcm9tX3VzZXIocmVwbHkgKyAyLCB1c2VyX21zZyArIDIsIHNpemVvZih1MzIpICogMikpIHsKCQkJcHJpbnRrKEtFUk5fV0FSTklORwoJCQkgICAgICAgIiVzOiBDb3VsZCBub3QgY29weSBtZXNzYWdlIGNvbnRleHQgRlJPTSB1c2VyXG4iLAoJCQkgICAgICAgYy0+bmFtZSk7CgkJCXJjb2RlID0gLUVGQVVMVDsKCQl9CgkJaWYgKGNvcHlfdG9fdXNlcih1c2VyX3JlcGx5LCByZXBseSwgcmVwbHlfc2l6ZSkpIHsKCQkJcHJpbnRrKEtFUk5fV0FSTklORwoJCQkgICAgICAgIiVzOiBDb3VsZCBub3QgY29weSByZXBseSBUTyB1c2VyXG4iLCBjLT5uYW1lKTsKCQkJcmNvZGUgPSAtRUZBVUxUOwoJCX0KCX0KCiAgICAgIHNnX2xpc3RfY2xlYW51cDoKCWZvciAoaSA9IDA7IGkgPCBzZ19pbmRleDsgaSsrKQoJCWtmcmVlKHNnX2xpc3RbaV0pOwoKICAgICAgY2xlYW51cDoKCWtmcmVlKHJlcGx5KTsKCXJldHVybiByY29kZTsKfQojZW5kaWYKCi8qCiAqIElPQ1RMIEhhbmRsZXIKICovCnN0YXRpYyBpbnQgaTJvX2NmZ19pb2N0bChzdHJ1Y3QgaW5vZGUgKmlub2RlLCBzdHJ1Y3QgZmlsZSAqZnAsIHVuc2lnbmVkIGludCBjbWQsCgkJCSB1bnNpZ25lZCBsb25nIGFyZykKewoJaW50IHJldDsKCglzd2l0Y2ggKGNtZCkgewoJY2FzZSBJMk9HRVRJT1BTOgoJCXJldCA9IGkyb19jZmdfZ2V0aW9wcyhhcmcpOwoJCWJyZWFrOwoKCWNhc2UgSTJPSFJUR0VUOgoJCXJldCA9IGkyb19jZmdfZ2V0aHJ0KGFyZyk7CgkJYnJlYWs7CgoJY2FzZSBJMk9MQ1RHRVQ6CgkJcmV0ID0gaTJvX2NmZ19nZXRsY3QoYXJnKTsKCQlicmVhazsKCgljYXNlIEkyT1BBUk1TRVQ6CgkJcmV0ID0gaTJvX2NmZ19wYXJtcyhhcmcsIEkyT1BBUk1TRVQpOwoJCWJyZWFrOwoKCWNhc2UgSTJPUEFSTUdFVDoKCQlyZXQgPSBpMm9fY2ZnX3Bhcm1zKGFyZywgSTJPUEFSTUdFVCk7CgkJYnJlYWs7CgoJY2FzZSBJMk9TV0RMOgoJCXJldCA9IGkyb19jZmdfc3dkbChhcmcpOwoJCWJyZWFrOwoKCWNhc2UgSTJPU1dVTDoKCQlyZXQgPSBpMm9fY2ZnX3N3dWwoYXJnKTsKCQlicmVhazsKCgljYXNlIEkyT1NXREVMOgoJCXJldCA9IGkyb19jZmdfc3dkZWwoYXJnKTsKCQlicmVhazsKCgljYXNlIEkyT1ZBTElEQVRFOgoJCXJldCA9IGkyb19jZmdfdmFsaWRhdGUoYXJnKTsKCQlicmVhazsKCgljYXNlIEkyT0VWVFJFRzoKCQlyZXQgPSBpMm9fY2ZnX2V2dF9yZWcoYXJnLCBmcCk7CgkJYnJlYWs7CgoJY2FzZSBJMk9FVlRHRVQ6CgkJcmV0ID0gaTJvX2NmZ19ldnRfZ2V0KGFyZywgZnApOwoJCWJyZWFrOwoKI2lmZGVmIENPTkZJR19JMk9fRVhUX0FEQVBURUMKCWNhc2UgSTJPUEFTU1RIUlU6CgkJcmV0ID0gaTJvX2NmZ19wYXNzdGhydShhcmcpOwoJCWJyZWFrOwojZW5kaWYKCglkZWZhdWx0OgoJCW9zbV9kZWJ1ZygidW5rbm93biBpb2N0bCBjYWxsZWQhXG4iKTsKCQlyZXQgPSAtRUlOVkFMOwoJfQoKCXJldHVybiByZXQ7Cn0KCnN0YXRpYyBpbnQgY2ZnX29wZW4oc3RydWN0IGlub2RlICppbm9kZSwgc3RydWN0IGZpbGUgKmZpbGUpCnsKCXN0cnVjdCBpMm9fY2ZnX2luZm8gKnRtcCA9CgkgICAgKHN0cnVjdCBpMm9fY2ZnX2luZm8gKilrbWFsbG9jKHNpemVvZihzdHJ1Y3QgaTJvX2NmZ19pbmZvKSwKCQkJCQkgICBHRlBfS0VSTkVMKTsKCXVuc2lnbmVkIGxvbmcgZmxhZ3M7CgoJaWYgKCF0bXApCgkJcmV0dXJuIC1FTk9NRU07CgoJZmlsZS0+cHJpdmF0ZV9kYXRhID0gKHZvaWQgKikoaTJvX2NmZ19pbmZvX2lkKyspOwoJdG1wLT5mcCA9IGZpbGU7Cgl0bXAtPmZhc3luYyA9IE5VTEw7Cgl0bXAtPnFfaWQgPSAodWxvbmcpIGZpbGUtPnByaXZhdGVfZGF0YTsKCXRtcC0+cV9sZW4gPSAwOwoJdG1wLT5xX2luID0gMDsKCXRtcC0+cV9vdXQgPSAwOwoJdG1wLT5xX2xvc3QgPSAwOwoJdG1wLT5uZXh0ID0gb3Blbl9maWxlczsKCglzcGluX2xvY2tfaXJxc2F2ZSgmaTJvX2NvbmZpZ19sb2NrLCBmbGFncyk7CglvcGVuX2ZpbGVzID0gdG1wOwoJc3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmaTJvX2NvbmZpZ19sb2NrLCBmbGFncyk7CgoJcmV0dXJuIDA7Cn0KCnN0YXRpYyBpbnQgY2ZnX2Zhc3luYyhpbnQgZmQsIHN0cnVjdCBmaWxlICpmcCwgaW50IG9uKQp7Cgl1bG9uZyBpZCA9ICh1bG9uZykgZnAtPnByaXZhdGVfZGF0YTsKCXN0cnVjdCBpMm9fY2ZnX2luZm8gKnA7CgoJZm9yIChwID0gb3Blbl9maWxlczsgcDsgcCA9IHAtPm5leHQpCgkJaWYgKHAtPnFfaWQgPT0gaWQpCgkJCWJyZWFrOwoKCWlmICghcCkKCQlyZXR1cm4gLUVCQURGOwoKCXJldHVybiBmYXN5bmNfaGVscGVyKGZkLCBmcCwgb24sICZwLT5mYXN5bmMpOwp9CgpzdGF0aWMgaW50IGNmZ19yZWxlYXNlKHN0cnVjdCBpbm9kZSAqaW5vZGUsIHN0cnVjdCBmaWxlICpmaWxlKQp7Cgl1bG9uZyBpZCA9ICh1bG9uZykgZmlsZS0+cHJpdmF0ZV9kYXRhOwoJc3RydWN0IGkyb19jZmdfaW5mbyAqcDEsICpwMjsKCXVuc2lnbmVkIGxvbmcgZmxhZ3M7CgoJbG9ja19rZXJuZWwoKTsKCXAxID0gcDIgPSBOVUxMOwoKCXNwaW5fbG9ja19pcnFzYXZlKCZpMm9fY29uZmlnX2xvY2ssIGZsYWdzKTsKCWZvciAocDEgPSBvcGVuX2ZpbGVzOyBwMTspIHsKCQlpZiAocDEtPnFfaWQgPT0gaWQpIHsKCgkJCWlmIChwMS0+ZmFzeW5jKQoJCQkJY2ZnX2Zhc3luYygtMSwgZmlsZSwgMCk7CgkJCWlmIChwMikKCQkJCXAyLT5uZXh0ID0gcDEtPm5leHQ7CgkJCWVsc2UKCQkJCW9wZW5fZmlsZXMgPSBwMS0+bmV4dDsKCgkJCWtmcmVlKHAxKTsKCQkJYnJlYWs7CgkJfQoJCXAyID0gcDE7CgkJcDEgPSBwMS0+bmV4dDsKCX0KCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJmkyb19jb25maWdfbG9jaywgZmxhZ3MpOwoJdW5sb2NrX2tlcm5lbCgpOwoKCXJldHVybiAwOwp9CgpzdGF0aWMgc3RydWN0IGZpbGVfb3BlcmF0aW9ucyBjb25maWdfZm9wcyA9IHsKCS5vd25lciA9IFRISVNfTU9EVUxFLAoJLmxsc2VlayA9IG5vX2xsc2VlaywKCS5pb2N0bCA9IGkyb19jZmdfaW9jdGwsCiNpZmRlZiBDT05GSUdfQ09NUEFUCgkuY29tcGF0X2lvY3RsID0gaTJvX2NmZ19jb21wYXRfaW9jdGwsCiNlbmRpZgoJLm9wZW4gPSBjZmdfb3BlbiwKCS5yZWxlYXNlID0gY2ZnX3JlbGVhc2UsCgkuZmFzeW5jID0gY2ZnX2Zhc3luYywKfTsKCnN0YXRpYyBzdHJ1Y3QgbWlzY2RldmljZSBpMm9fbWlzY2RldiA9IHsKCUkyT19NSU5PUiwKCSJpMm9jdGwiLAoJJmNvbmZpZ19mb3BzCn07CgpzdGF0aWMgaW50IF9faW5pdCBpMm9fY29uZmlnX29sZF9pbml0KHZvaWQpCnsKCXNwaW5fbG9ja19pbml0KCZpMm9fY29uZmlnX2xvY2spOwoKCWlmIChtaXNjX3JlZ2lzdGVyKCZpMm9fbWlzY2RldikgPCAwKSB7CgkJb3NtX2VycigiY2FuJ3QgcmVnaXN0ZXIgZGV2aWNlLlxuIik7CgkJcmV0dXJuIC1FQlVTWTsKCX0KCglyZXR1cm4gMDsKfQoKc3RhdGljIHZvaWQgaTJvX2NvbmZpZ19vbGRfZXhpdCh2b2lkKQp7CgltaXNjX2RlcmVnaXN0ZXIoJmkyb19taXNjZGV2KTsKfQoKTU9EVUxFX0FVVEhPUigiUmVkIEhhdCBTb2Z0d2FyZSIpOwo=