LyoKICogSTJPIENvbmZpZ3VyYXRpb24gSW50ZXJmYWNlIERyaXZlcgogKgogKiAoQykgQ29weXJpZ2h0IDE5OTktMjAwMiAgUmVkIEhhdAogKgogKiBXcml0dGVuIGJ5IEFsYW4gQ294LCBCdWlsZGluZyBOdW1iZXIgVGhyZWUgTHRkCiAqCiAqIEZpeGVzL2FkZGl0aW9uczoKICoJRGVlcGFrIFNheGVuYSAoMDQvMjAvMTk5OSk6CiAqCQlBZGRlZCBiYXNpYyBpb2N0bCgpIHN1cHBvcnQKICoJRGVlcGFrIFNheGVuYSAoMDYvMDcvMTk5OSk6CiAqCQlBZGRlZCBzb2Z0d2FyZSBkb3dubG9hZCBpb2N0bCAoc3RpbGwgdGVzdGluZykKICoJQXV2byBI5GtraW5lbiAoMDkvMTAvMTk5OSk6CiAqCQlDaGFuZ2VzIHRvIGkyb19jZmdfcmVwbHkoKSwgaW9jdGxfcGFybXMoKQogKgkJQWRkZWQgaW9jdF92YWxpZGF0ZSgpCiAqCVRhbmVsaSBW5Gjka2FuZ2FzICgwOS8zMC8xOTk5KToKICoJCUZpeGVkIGlvY3RsX3N3ZGwoKQogKglUYW5lbGkgVuRo5GthbmdhcyAoMTAvMDQvMTk5OSk6CiAqCQlDaGFuZ2VkIGlvY3RsX3N3ZGwoKSwgaW1wbGVtZW50ZWQgaW9jdGxfc3d1bCgpIGFuZCBpb2N0bF9zd2RlbCgpCiAqCURlZXBhayBTYXhlbmEgKDExLzE4LzE5OTkpOgogKgkJQWRkZWQgZXZlbnQgbWFuYWdtZW5ldCBzdXBwb3J0CiAqCUFsYW4gQ294IDxhbGFuQHJlZGhhdC5jb20+OgogKgkJMi40IHJld3JpdGUgcG9ydGVkIHRvIDIuNQogKglNYXJrdXMgTGlkZWwgPE1hcmt1cy5MaWRlbEBzaGFkb3djb25uZWN0LmNvbT46CiAqCQlBZGRlZCBwYXNzLXRocnUgc3VwcG9ydCBmb3IgQWRhcHRlYydzIHJhaWR1dGlscwogKgogKiBUaGlzIHByb2dyYW0gaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIgdmVyc2lvbgogKiAyIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKi8KCiNpbmNsdWRlIDxsaW51eC9taXNjZGV2aWNlLmg+CiNpbmNsdWRlIDxsaW51eC9zbXBfbG9jay5oPgojaW5jbHVkZSA8bGludXgvY29tcGF0Lmg+CgojaW5jbHVkZSA8YXNtL3VhY2Nlc3MuaD4KCiNpbmNsdWRlICJjb3JlLmgiCgojZGVmaW5lIFNHX1RBQkxFU0laRQkJMzAKCnN0YXRpYyBpbnQgaTJvX2NmZ19pb2N0bChzdHJ1Y3QgaW5vZGUgKiwgc3RydWN0IGZpbGUgKiwgdW5zaWduZWQgaW50LAoJCQkgdW5zaWduZWQgbG9uZyk7CgpzdGF0aWMgc3BpbmxvY2tfdCBpMm9fY29uZmlnX2xvY2s7CgojZGVmaW5lIE1PRElOQyh4LHkpICgoeCkgPSAoKHgpICsgMSkgJSAoeSkpCgpzdHJ1Y3Qgc2dfc2ltcGxlX2VsZW1lbnQgewoJdTMyIGZsYWdfY291bnQ7Cgl1MzIgYWRkcl9idXM7Cn07CgpzdHJ1Y3QgaTJvX2NmZ19pbmZvIHsKCXN0cnVjdCBmaWxlICpmcDsKCXN0cnVjdCBmYXN5bmNfc3RydWN0ICpmYXN5bmM7CglzdHJ1Y3QgaTJvX2V2dF9pbmZvIGV2ZW50X3FbSTJPX0VWVF9RX0xFTl07Cgl1MTYgcV9pbjsJCS8vIFF1ZXVlIGhlYWQgaW5kZXgKCXUxNiBxX291dDsJCS8vIFF1ZXVlIHRhaWwgaW5kZXgKCXUxNiBxX2xlbjsJCS8vIFF1ZXVlIGxlbmd0aAoJdTE2IHFfbG9zdDsJCS8vIE51bWJlciBvZiBsb3N0IGV2ZW50cwoJdWxvbmcgcV9pZDsJCS8vIEV2ZW50IHF1ZXVlIElELi4udXNlZCBhcyB0eF9jb250ZXh0CglzdHJ1Y3QgaTJvX2NmZ19pbmZvICpuZXh0Owp9OwpzdGF0aWMgc3RydWN0IGkyb19jZmdfaW5mbyAqb3Blbl9maWxlcyA9IE5VTEw7CnN0YXRpYyB1bG9uZyBpMm9fY2ZnX2luZm9faWQgPSAwOwoKc3RhdGljIGludCBpMm9fY2ZnX2dldGlvcHModW5zaWduZWQgbG9uZyBhcmcpCnsKCXN0cnVjdCBpMm9fY29udHJvbGxlciAqYzsKCXU4IF9fdXNlciAqdXNlcl9pb3BfdGFibGUgPSAodm9pZCBfX3VzZXIgKilhcmc7Cgl1OCB0bXBbTUFYX0kyT19DT05UUk9MTEVSU107CglpbnQgcmV0ID0gMDsKCgltZW1zZXQodG1wLCAwLCBNQVhfSTJPX0NPTlRST0xMRVJTKTsKCglsaXN0X2Zvcl9lYWNoX2VudHJ5KGMsICZpMm9fY29udHJvbGxlcnMsIGxpc3QpCgkgICAgdG1wW2MtPnVuaXRdID0gMTsKCglpZiAoY29weV90b191c2VyKHVzZXJfaW9wX3RhYmxlLCB0bXAsIE1BWF9JMk9fQ09OVFJPTExFUlMpKQoJCXJldCA9IC1FRkFVTFQ7CgoJcmV0dXJuIHJldDsKfTsKCnN0YXRpYyBpbnQgaTJvX2NmZ19nZXRocnQodW5zaWduZWQgbG9uZyBhcmcpCnsKCXN0cnVjdCBpMm9fY29udHJvbGxlciAqYzsKCXN0cnVjdCBpMm9fY21kX2hydGxjdCBfX3VzZXIgKmNtZCA9IChzdHJ1Y3QgaTJvX2NtZF9ocnRsY3QgX191c2VyICopYXJnOwoJc3RydWN0IGkyb19jbWRfaHJ0bGN0IGtjbWQ7CglpMm9faHJ0ICpocnQ7CglpbnQgbGVuOwoJdTMyIHJlc2xlbjsKCWludCByZXQgPSAwOwoKCWlmIChjb3B5X2Zyb21fdXNlcigma2NtZCwgY21kLCBzaXplb2Yoc3RydWN0IGkyb19jbWRfaHJ0bGN0KSkpCgkJcmV0dXJuIC1FRkFVTFQ7CgoJaWYgKGdldF91c2VyKHJlc2xlbiwga2NtZC5yZXNsZW4pIDwgMCkKCQlyZXR1cm4gLUVGQVVMVDsKCglpZiAoa2NtZC5yZXNidWYgPT0gTlVMTCkKCQlyZXR1cm4gLUVGQVVMVDsKCgljID0gaTJvX2ZpbmRfaW9wKGtjbWQuaW9wKTsKCWlmICghYykKCQlyZXR1cm4gLUVOWElPOwoKCWhydCA9IChpMm9faHJ0ICopIGMtPmhydC52aXJ0OwoKCWxlbiA9IDggKyAoKGhydC0+ZW50cnlfbGVuICogaHJ0LT5udW1fZW50cmllcykgPDwgMik7CgoJLyogV2UgZGlkIGEgZ2V0IHVzZXIuLi5zbyBhc3N1bWluZyBtZW0gaXMgb2suLi5pcyB0aGlzIGJhZD8gKi8KCXB1dF91c2VyKGxlbiwga2NtZC5yZXNsZW4pOwoJaWYgKGxlbiA+IHJlc2xlbikKCQlyZXQgPSAtRU5PQlVGUzsKCWlmIChjb3B5X3RvX3VzZXIoa2NtZC5yZXNidWYsICh2b2lkICopaHJ0LCBsZW4pKQoJCXJldCA9IC1FRkFVTFQ7CgoJcmV0dXJuIHJldDsKfTsKCnN0YXRpYyBpbnQgaTJvX2NmZ19nZXRsY3QodW5zaWduZWQgbG9uZyBhcmcpCnsKCXN0cnVjdCBpMm9fY29udHJvbGxlciAqYzsKCXN0cnVjdCBpMm9fY21kX2hydGxjdCBfX3VzZXIgKmNtZCA9IChzdHJ1Y3QgaTJvX2NtZF9ocnRsY3QgX191c2VyICopYXJnOwoJc3RydWN0IGkyb19jbWRfaHJ0bGN0IGtjbWQ7CglpMm9fbGN0ICpsY3Q7CglpbnQgbGVuOwoJaW50IHJldCA9IDA7Cgl1MzIgcmVzbGVuOwoKCWlmIChjb3B5X2Zyb21fdXNlcigma2NtZCwgY21kLCBzaXplb2Yoc3RydWN0IGkyb19jbWRfaHJ0bGN0KSkpCgkJcmV0dXJuIC1FRkFVTFQ7CgoJaWYgKGdldF91c2VyKHJlc2xlbiwga2NtZC5yZXNsZW4pIDwgMCkKCQlyZXR1cm4gLUVGQVVMVDsKCglpZiAoa2NtZC5yZXNidWYgPT0gTlVMTCkKCQlyZXR1cm4gLUVGQVVMVDsKCgljID0gaTJvX2ZpbmRfaW9wKGtjbWQuaW9wKTsKCWlmICghYykKCQlyZXR1cm4gLUVOWElPOwoKCWxjdCA9IChpMm9fbGN0ICopIGMtPmxjdDsKCglsZW4gPSAodW5zaWduZWQgaW50KWxjdC0+dGFibGVfc2l6ZSA8PCAyOwoJcHV0X3VzZXIobGVuLCBrY21kLnJlc2xlbik7CglpZiAobGVuID4gcmVzbGVuKQoJCXJldCA9IC1FTk9CVUZTOwoJZWxzZSBpZiAoY29weV90b191c2VyKGtjbWQucmVzYnVmLCBsY3QsIGxlbikpCgkJcmV0ID0gLUVGQVVMVDsKCglyZXR1cm4gcmV0Owp9OwoKc3RhdGljIGludCBpMm9fY2ZnX3Bhcm1zKHVuc2lnbmVkIGxvbmcgYXJnLCB1bnNpZ25lZCBpbnQgdHlwZSkKewoJaW50IHJldCA9IDA7CglzdHJ1Y3QgaTJvX2NvbnRyb2xsZXIgKmM7CglzdHJ1Y3QgaTJvX2RldmljZSAqZGV2OwoJc3RydWN0IGkyb19jbWRfcHNldGdldCBfX3VzZXIgKmNtZCA9CgkgICAgKHN0cnVjdCBpMm9fY21kX3BzZXRnZXQgX191c2VyICopYXJnOwoJc3RydWN0IGkyb19jbWRfcHNldGdldCBrY21kOwoJdTMyIHJlc2xlbjsKCXU4ICpvcHM7Cgl1OCAqcmVzOwoJaW50IGxlbiA9IDA7CgoJdTMyIGkyb19jbWQgPSAodHlwZSA9PSBJMk9QQVJNR0VUID8KCQkgICAgICAgSTJPX0NNRF9VVElMX1BBUkFNU19HRVQgOiBJMk9fQ01EX1VUSUxfUEFSQU1TX1NFVCk7CgoJaWYgKGNvcHlfZnJvbV91c2VyKCZrY21kLCBjbWQsIHNpemVvZihzdHJ1Y3QgaTJvX2NtZF9wc2V0Z2V0KSkpCgkJcmV0dXJuIC1FRkFVTFQ7CgoJaWYgKGdldF91c2VyKHJlc2xlbiwga2NtZC5yZXNsZW4pKQoJCXJldHVybiAtRUZBVUxUOwoKCWMgPSBpMm9fZmluZF9pb3Aoa2NtZC5pb3ApOwoJaWYgKCFjKQoJCXJldHVybiAtRU5YSU87CgoJZGV2ID0gaTJvX2lvcF9maW5kX2RldmljZShjLCBrY21kLnRpZCk7CglpZiAoIWRldikKCQlyZXR1cm4gLUVOWElPOwoKCW9wcyA9IGttYWxsb2Moa2NtZC5vcGxlbiwgR0ZQX0tFUk5FTCk7CglpZiAoIW9wcykKCQlyZXR1cm4gLUVOT01FTTsKCglpZiAoY29weV9mcm9tX3VzZXIob3BzLCBrY21kLm9wYnVmLCBrY21kLm9wbGVuKSkgewoJCWtmcmVlKG9wcyk7CgkJcmV0dXJuIC1FRkFVTFQ7Cgl9CgoJLyoKCSAqIEl0J3MgcG9zc2libGUgdG8gaGF2ZSBhIF92ZXJ5XyBsYXJnZSB0YWJsZQoJICogYW5kIHRoYXQgdGhlIHVzZXIgYXNrcyBmb3IgYWxsIG9mIGl0IGF0IG9uY2UuLi4KCSAqLwoJcmVzID0ga21hbGxvYyg2NTUzNiwgR0ZQX0tFUk5FTCk7CglpZiAoIXJlcykgewoJCWtmcmVlKG9wcyk7CgkJcmV0dXJuIC1FTk9NRU07Cgl9CgoJbGVuID0gaTJvX3Bhcm1faXNzdWUoZGV2LCBpMm9fY21kLCBvcHMsIGtjbWQub3BsZW4sIHJlcywgNjU1MzYpOwoJa2ZyZWUob3BzKTsKCglpZiAobGVuIDwgMCkgewoJCWtmcmVlKHJlcyk7CgkJcmV0dXJuIC1FQUdBSU47Cgl9CgoJcHV0X3VzZXIobGVuLCBrY21kLnJlc2xlbik7CglpZiAobGVuID4gcmVzbGVuKQoJCXJldCA9IC1FTk9CVUZTOwoJZWxzZSBpZiAoY29weV90b191c2VyKGtjbWQucmVzYnVmLCByZXMsIGxlbikpCgkJcmV0ID0gLUVGQVVMVDsKCglrZnJlZShyZXMpOwoKCXJldHVybiByZXQ7Cn07CgpzdGF0aWMgaW50IGkyb19jZmdfc3dkbCh1bnNpZ25lZCBsb25nIGFyZykKewoJc3RydWN0IGkyb19zd194ZmVyIGt4ZmVyOwoJc3RydWN0IGkyb19zd194ZmVyIF9fdXNlciAqcHhmZXIgPSAoc3RydWN0IGkyb19zd194ZmVyIF9fdXNlciAqKWFyZzsKCXVuc2lnbmVkIGNoYXIgbWF4ZnJhZyA9IDAsIGN1cmZyYWcgPSAxOwoJc3RydWN0IGkyb19kbWEgYnVmZmVyOwoJc3RydWN0IGkyb19tZXNzYWdlICptc2c7Cgl1bnNpZ25lZCBpbnQgc3RhdHVzID0gMCwgc3dsZW4gPSAwLCBmcmFnc2l6ZSA9IDgxOTI7CglzdHJ1Y3QgaTJvX2NvbnRyb2xsZXIgKmM7CgoJaWYgKGNvcHlfZnJvbV91c2VyKCZreGZlciwgcHhmZXIsIHNpemVvZihzdHJ1Y3QgaTJvX3N3X3hmZXIpKSkKCQlyZXR1cm4gLUVGQVVMVDsKCglpZiAoZ2V0X3VzZXIoc3dsZW4sIGt4ZmVyLnN3bGVuKSA8IDApCgkJcmV0dXJuIC1FRkFVTFQ7CgoJaWYgKGdldF91c2VyKG1heGZyYWcsIGt4ZmVyLm1heGZyYWcpIDwgMCkKCQlyZXR1cm4gLUVGQVVMVDsKCglpZiAoZ2V0X3VzZXIoY3VyZnJhZywga3hmZXIuY3VyZnJhZykgPCAwKQoJCXJldHVybiAtRUZBVUxUOwoKCWlmIChjdXJmcmFnID09IG1heGZyYWcpCgkJZnJhZ3NpemUgPSBzd2xlbiAtIChtYXhmcmFnIC0gMSkgKiA4MTkyOwoKCWlmICgha3hmZXIuYnVmIHx8ICFhY2Nlc3Nfb2soVkVSSUZZX1JFQUQsIGt4ZmVyLmJ1ZiwgZnJhZ3NpemUpKQoJCXJldHVybiAtRUZBVUxUOwoKCWMgPSBpMm9fZmluZF9pb3Aoa3hmZXIuaW9wKTsKCWlmICghYykKCQlyZXR1cm4gLUVOWElPOwoKCW1zZyA9IGkyb19tc2dfZ2V0X3dhaXQoYywgSTJPX1RJTUVPVVRfTUVTU0FHRV9HRVQpOwoJaWYgKElTX0VSUihtc2cpKQoJCXJldHVybiBQVFJfRVJSKG1zZyk7CgoJaWYgKGkyb19kbWFfYWxsb2MoJmMtPnBkZXYtPmRldiwgJmJ1ZmZlciwgZnJhZ3NpemUsIEdGUF9LRVJORUwpKSB7CgkJaTJvX21zZ19ub3AoYywgbXNnKTsKCQlyZXR1cm4gLUVOT01FTTsKCX0KCglpZiAoX19jb3B5X2Zyb21fdXNlcihidWZmZXIudmlydCwga3hmZXIuYnVmLCBmcmFnc2l6ZSkpIHsKCQlpMm9fbXNnX25vcChjLCBtc2cpOwoJCWkyb19kbWFfZnJlZSgmYy0+cGRldi0+ZGV2LCAmYnVmZmVyKTsKCQlyZXR1cm4gLUVGQVVMVDsKCX0KCgltc2ctPnUuaGVhZFswXSA9IGNwdV90b19sZTMyKE5JTkVfV09SRF9NU0dfU0laRSB8IFNHTF9PRkZTRVRfNyk7Cgltc2ctPnUuaGVhZFsxXSA9CgkgICAgY3B1X3RvX2xlMzIoSTJPX0NNRF9TV19ET1dOTE9BRCA8PCAyNCB8IEhPU1RfVElEIDw8IDEyIHwKCQkJQURBUFRFUl9USUQpOwoJbXNnLT51LmhlYWRbMl0gPSBjcHVfdG9fbGUzMihpMm9fY29uZmlnX2RyaXZlci5jb250ZXh0KTsKCW1zZy0+dS5oZWFkWzNdID0gY3B1X3RvX2xlMzIoMCk7Cgltc2ctPmJvZHlbMF0gPQoJICAgIGNwdV90b19sZTMyKCgoKHUzMikga3hmZXIuZmxhZ3MpIDw8IDI0KSB8ICgoKHUzMikga3hmZXIuCgkJCQkJCQlzd190eXBlKSA8PCAxNikgfAoJCQkoKCh1MzIpIG1heGZyYWcpIDw8IDgpIHwgKCgodTMyKSBjdXJmcmFnKSkpOwoJbXNnLT5ib2R5WzFdID0gY3B1X3RvX2xlMzIoc3dsZW4pOwoJbXNnLT5ib2R5WzJdID0gY3B1X3RvX2xlMzIoa3hmZXIuc3dfaWQpOwoJbXNnLT5ib2R5WzNdID0gY3B1X3RvX2xlMzIoMHhEMDAwMDAwMCB8IGZyYWdzaXplKTsKCW1zZy0+Ym9keVs0XSA9IGNwdV90b19sZTMyKGJ1ZmZlci5waHlzKTsKCglvc21fZGVidWcoInN3ZGwgZnJhZyAlZC8lZCAoc2l6ZSAlZClcbiIsIGN1cmZyYWcsIG1heGZyYWcsIGZyYWdzaXplKTsKCXN0YXR1cyA9IGkyb19tc2dfcG9zdF93YWl0X21lbShjLCBtc2csIDYwLCAmYnVmZmVyKTsKCglpZiAoc3RhdHVzICE9IC1FVElNRURPVVQpCgkJaTJvX2RtYV9mcmVlKCZjLT5wZGV2LT5kZXYsICZidWZmZXIpOwoKCWlmIChzdGF0dXMgIT0gSTJPX1BPU1RfV0FJVF9PSykgewoJCS8vIGl0IGZhaWxzIGlmIHlvdSB0cnkgYW5kIHNlbmQgZnJhZ3Mgb3V0IG9mIG9yZGVyCgkJLy8gYW5kIGZvciBzb21lIHlldCB1bmtub3duIHJlYXNvbnMgdG9vCgkJb3NtX2luZm8oInN3ZGwgZmFpbGVkLCBEZXRhaWxlZFN0YXR1cyA9ICVkXG4iLCBzdGF0dXMpOwoJCXJldHVybiBzdGF0dXM7Cgl9CgoJcmV0dXJuIDA7Cn07CgpzdGF0aWMgaW50IGkyb19jZmdfc3d1bCh1bnNpZ25lZCBsb25nIGFyZykKewoJc3RydWN0IGkyb19zd194ZmVyIGt4ZmVyOwoJc3RydWN0IGkyb19zd194ZmVyIF9fdXNlciAqcHhmZXIgPSAoc3RydWN0IGkyb19zd194ZmVyIF9fdXNlciAqKWFyZzsKCXVuc2lnbmVkIGNoYXIgbWF4ZnJhZyA9IDAsIGN1cmZyYWcgPSAxOwoJc3RydWN0IGkyb19kbWEgYnVmZmVyOwoJc3RydWN0IGkyb19tZXNzYWdlICptc2c7Cgl1bnNpZ25lZCBpbnQgc3RhdHVzID0gMCwgc3dsZW4gPSAwLCBmcmFnc2l6ZSA9IDgxOTI7CglzdHJ1Y3QgaTJvX2NvbnRyb2xsZXIgKmM7CglpbnQgcmV0ID0gMDsKCglpZiAoY29weV9mcm9tX3VzZXIoJmt4ZmVyLCBweGZlciwgc2l6ZW9mKHN0cnVjdCBpMm9fc3dfeGZlcikpKQoJCWdvdG8gcmV0dXJuX2ZhdWx0OwoKCWlmIChnZXRfdXNlcihzd2xlbiwga3hmZXIuc3dsZW4pIDwgMCkKCQlnb3RvIHJldHVybl9mYXVsdDsKCglpZiAoZ2V0X3VzZXIobWF4ZnJhZywga3hmZXIubWF4ZnJhZykgPCAwKQoJCWdvdG8gcmV0dXJuX2ZhdWx0OwoKCWlmIChnZXRfdXNlcihjdXJmcmFnLCBreGZlci5jdXJmcmFnKSA8IDApCgkJZ290byByZXR1cm5fZmF1bHQ7CgoJaWYgKGN1cmZyYWcgPT0gbWF4ZnJhZykKCQlmcmFnc2l6ZSA9IHN3bGVuIC0gKG1heGZyYWcgLSAxKSAqIDgxOTI7CgoJaWYgKCFreGZlci5idWYpCgkJZ290byByZXR1cm5fZmF1bHQ7CgoJYyA9IGkyb19maW5kX2lvcChreGZlci5pb3ApOwoJaWYgKCFjKQoJCXJldHVybiAtRU5YSU87CgoJbXNnID0gaTJvX21zZ19nZXRfd2FpdChjLCBJMk9fVElNRU9VVF9NRVNTQUdFX0dFVCk7CglpZiAoSVNfRVJSKG1zZykpCgkJcmV0dXJuIFBUUl9FUlIobXNnKTsKCglpZiAoaTJvX2RtYV9hbGxvYygmYy0+cGRldi0+ZGV2LCAmYnVmZmVyLCBmcmFnc2l6ZSwgR0ZQX0tFUk5FTCkpIHsKCQlpMm9fbXNnX25vcChjLCBtc2cpOwoJCXJldHVybiAtRU5PTUVNOwoJfQoKCW1zZy0+dS5oZWFkWzBdID0gY3B1X3RvX2xlMzIoTklORV9XT1JEX01TR19TSVpFIHwgU0dMX09GRlNFVF83KTsKCW1zZy0+dS5oZWFkWzFdID0KCSAgICBjcHVfdG9fbGUzMihJMk9fQ01EX1NXX1VQTE9BRCA8PCAyNCB8IEhPU1RfVElEIDw8IDEyIHwgQURBUFRFUl9USUQpOwoJbXNnLT51LmhlYWRbMl0gPSBjcHVfdG9fbGUzMihpMm9fY29uZmlnX2RyaXZlci5jb250ZXh0KTsKCW1zZy0+dS5oZWFkWzNdID0gY3B1X3RvX2xlMzIoMCk7Cgltc2ctPmJvZHlbMF0gPQoJICAgIGNwdV90b19sZTMyKCh1MzIpIGt4ZmVyLmZsYWdzIDw8IDI0IHwgKHUzMikga3hmZXIuCgkJCXN3X3R5cGUgPDwgMTYgfCAodTMyKSBtYXhmcmFnIDw8IDggfCAodTMyKSBjdXJmcmFnKTsKCW1zZy0+Ym9keVsxXSA9IGNwdV90b19sZTMyKHN3bGVuKTsKCW1zZy0+Ym9keVsyXSA9IGNwdV90b19sZTMyKGt4ZmVyLnN3X2lkKTsKCW1zZy0+Ym9keVszXSA9IGNwdV90b19sZTMyKDB4RDAwMDAwMDAgfCBmcmFnc2l6ZSk7Cgltc2ctPmJvZHlbNF0gPSBjcHVfdG9fbGUzMihidWZmZXIucGh5cyk7CgoJb3NtX2RlYnVnKCJzd3VsIGZyYWcgJWQvJWQgKHNpemUgJWQpXG4iLCBjdXJmcmFnLCBtYXhmcmFnLCBmcmFnc2l6ZSk7CglzdGF0dXMgPSBpMm9fbXNnX3Bvc3Rfd2FpdF9tZW0oYywgbXNnLCA2MCwgJmJ1ZmZlcik7CgoJaWYgKHN0YXR1cyAhPSBJMk9fUE9TVF9XQUlUX09LKSB7CgkJaWYgKHN0YXR1cyAhPSAtRVRJTUVET1VUKQoJCQlpMm9fZG1hX2ZyZWUoJmMtPnBkZXYtPmRldiwgJmJ1ZmZlcik7CgoJCW9zbV9pbmZvKCJzd3VsIGZhaWxlZCwgRGV0YWlsZWRTdGF0dXMgPSAlZFxuIiwgc3RhdHVzKTsKCQlyZXR1cm4gc3RhdHVzOwoJfQoKCWlmIChjb3B5X3RvX3VzZXIoa3hmZXIuYnVmLCBidWZmZXIudmlydCwgZnJhZ3NpemUpKQoJCXJldCA9IC1FRkFVTFQ7CgoJaTJvX2RtYV9mcmVlKCZjLT5wZGV2LT5kZXYsICZidWZmZXIpOwoKICAgICAgcmV0dXJuX3JldDoKCXJldHVybiByZXQ7CiAgICAgIHJldHVybl9mYXVsdDoKCXJldCA9IC1FRkFVTFQ7Cglnb3RvIHJldHVybl9yZXQ7Cn07CgpzdGF0aWMgaW50IGkyb19jZmdfc3dkZWwodW5zaWduZWQgbG9uZyBhcmcpCnsKCXN0cnVjdCBpMm9fY29udHJvbGxlciAqYzsKCXN0cnVjdCBpMm9fc3dfeGZlciBreGZlcjsKCXN0cnVjdCBpMm9fc3dfeGZlciBfX3VzZXIgKnB4ZmVyID0gKHN0cnVjdCBpMm9fc3dfeGZlciBfX3VzZXIgKilhcmc7CglzdHJ1Y3QgaTJvX21lc3NhZ2UgKm1zZzsKCXVuc2lnbmVkIGludCBzd2xlbjsKCWludCB0b2tlbjsKCglpZiAoY29weV9mcm9tX3VzZXIoJmt4ZmVyLCBweGZlciwgc2l6ZW9mKHN0cnVjdCBpMm9fc3dfeGZlcikpKQoJCXJldHVybiAtRUZBVUxUOwoKCWlmIChnZXRfdXNlcihzd2xlbiwga3hmZXIuc3dsZW4pIDwgMCkKCQlyZXR1cm4gLUVGQVVMVDsKCgljID0gaTJvX2ZpbmRfaW9wKGt4ZmVyLmlvcCk7CglpZiAoIWMpCgkJcmV0dXJuIC1FTlhJTzsKCgltc2cgPSBpMm9fbXNnX2dldF93YWl0KGMsIEkyT19USU1FT1VUX01FU1NBR0VfR0VUKTsKCWlmIChJU19FUlIobXNnKSkKCQlyZXR1cm4gUFRSX0VSUihtc2cpOwoKCW1zZy0+dS5oZWFkWzBdID0gY3B1X3RvX2xlMzIoU0VWRU5fV09SRF9NU0dfU0laRSB8IFNHTF9PRkZTRVRfMCk7Cgltc2ctPnUuaGVhZFsxXSA9CgkgICAgY3B1X3RvX2xlMzIoSTJPX0NNRF9TV19SRU1PVkUgPDwgMjQgfCBIT1NUX1RJRCA8PCAxMiB8IEFEQVBURVJfVElEKTsKCW1zZy0+dS5oZWFkWzJdID0gY3B1X3RvX2xlMzIoaTJvX2NvbmZpZ19kcml2ZXIuY29udGV4dCk7Cgltc2ctPnUuaGVhZFszXSA9IGNwdV90b19sZTMyKDApOwoJbXNnLT5ib2R5WzBdID0KCSAgICBjcHVfdG9fbGUzMigodTMyKSBreGZlci5mbGFncyA8PCAyNCB8ICh1MzIpIGt4ZmVyLnN3X3R5cGUgPDwgMTYpOwoJbXNnLT5ib2R5WzFdID0gY3B1X3RvX2xlMzIoc3dsZW4pOwoJbXNnLT5ib2R5WzJdID0gY3B1X3RvX2xlMzIoa3hmZXIuc3dfaWQpOwoKCXRva2VuID0gaTJvX21zZ19wb3N0X3dhaXQoYywgbXNnLCAxMCk7CgoJaWYgKHRva2VuICE9IEkyT19QT1NUX1dBSVRfT0spIHsKCQlvc21faW5mbygic3dkZWwgZmFpbGVkLCBEZXRhaWxlZFN0YXR1cyA9ICVkXG4iLCB0b2tlbik7CgkJcmV0dXJuIC1FVElNRURPVVQ7Cgl9CgoJcmV0dXJuIDA7Cn07CgpzdGF0aWMgaW50IGkyb19jZmdfdmFsaWRhdGUodW5zaWduZWQgbG9uZyBhcmcpCnsKCWludCB0b2tlbjsKCWludCBpb3AgPSAoaW50KWFyZzsKCXN0cnVjdCBpMm9fbWVzc2FnZSAqbXNnOwoJc3RydWN0IGkyb19jb250cm9sbGVyICpjOwoKCWMgPSBpMm9fZmluZF9pb3AoaW9wKTsKCWlmICghYykKCQlyZXR1cm4gLUVOWElPOwoKCW1zZyA9IGkyb19tc2dfZ2V0X3dhaXQoYywgSTJPX1RJTUVPVVRfTUVTU0FHRV9HRVQpOwoJaWYgKElTX0VSUihtc2cpKQoJCXJldHVybiBQVFJfRVJSKG1zZyk7CgoJbXNnLT51LmhlYWRbMF0gPSBjcHVfdG9fbGUzMihGT1VSX1dPUkRfTVNHX1NJWkUgfCBTR0xfT0ZGU0VUXzApOwoJbXNnLT51LmhlYWRbMV0gPQoJICAgIGNwdV90b19sZTMyKEkyT19DTURfQ09ORklHX1ZBTElEQVRFIDw8IDI0IHwgSE9TVF9USUQgPDwgMTIgfCBpb3ApOwoJbXNnLT51LmhlYWRbMl0gPSBjcHVfdG9fbGUzMihpMm9fY29uZmlnX2RyaXZlci5jb250ZXh0KTsKCW1zZy0+dS5oZWFkWzNdID0gY3B1X3RvX2xlMzIoMCk7CgoJdG9rZW4gPSBpMm9fbXNnX3Bvc3Rfd2FpdChjLCBtc2csIDEwKTsKCglpZiAodG9rZW4gIT0gSTJPX1BPU1RfV0FJVF9PSykgewoJCW9zbV9pbmZvKCJDYW4ndCB2YWxpZGF0ZSBjb25maWd1cmF0aW9uLCBFcnJvclN0YXR1cyA9ICVkXG4iLAoJCQkgdG9rZW4pOwoJCXJldHVybiAtRVRJTUVET1VUOwoJfQoKCXJldHVybiAwOwp9OwoKc3RhdGljIGludCBpMm9fY2ZnX2V2dF9yZWcodW5zaWduZWQgbG9uZyBhcmcsIHN0cnVjdCBmaWxlICpmcCkKewoJc3RydWN0IGkyb19tZXNzYWdlICptc2c7CglzdHJ1Y3QgaTJvX2V2dF9pZCBfX3VzZXIgKnBkZXNjID0gKHN0cnVjdCBpMm9fZXZ0X2lkIF9fdXNlciAqKWFyZzsKCXN0cnVjdCBpMm9fZXZ0X2lkIGtkZXNjOwoJc3RydWN0IGkyb19jb250cm9sbGVyICpjOwoJc3RydWN0IGkyb19kZXZpY2UgKmQ7CgoJaWYgKGNvcHlfZnJvbV91c2VyKCZrZGVzYywgcGRlc2MsIHNpemVvZihzdHJ1Y3QgaTJvX2V2dF9pZCkpKQoJCXJldHVybiAtRUZBVUxUOwoKCS8qIElPUCBleGlzdHM/ICovCgljID0gaTJvX2ZpbmRfaW9wKGtkZXNjLmlvcCk7CglpZiAoIWMpCgkJcmV0dXJuIC1FTlhJTzsKCgkvKiBEZXZpY2UgZXhpc3RzPyAqLwoJZCA9IGkyb19pb3BfZmluZF9kZXZpY2UoYywga2Rlc2MudGlkKTsKCWlmICghZCkKCQlyZXR1cm4gLUVOT0RFVjsKCgltc2cgPSBpMm9fbXNnX2dldF93YWl0KGMsIEkyT19USU1FT1VUX01FU1NBR0VfR0VUKTsKCWlmIChJU19FUlIobXNnKSkKCQlyZXR1cm4gUFRSX0VSUihtc2cpOwoKCW1zZy0+dS5oZWFkWzBdID0gY3B1X3RvX2xlMzIoRk9VUl9XT1JEX01TR19TSVpFIHwgU0dMX09GRlNFVF8wKTsKCW1zZy0+dS5oZWFkWzFdID0KCSAgICBjcHVfdG9fbGUzMihJMk9fQ01EX1VUSUxfRVZUX1JFR0lTVEVSIDw8IDI0IHwgSE9TVF9USUQgPDwgMTIgfAoJCQlrZGVzYy50aWQpOwoJbXNnLT51LmhlYWRbMl0gPSBjcHVfdG9fbGUzMihpMm9fY29uZmlnX2RyaXZlci5jb250ZXh0KTsKCW1zZy0+dS5oZWFkWzNdID0gY3B1X3RvX2xlMzIoaTJvX2NudHh0X2xpc3RfYWRkKGMsIGZwLT5wcml2YXRlX2RhdGEpKTsKCW1zZy0+Ym9keVswXSA9IGNwdV90b19sZTMyKGtkZXNjLmV2dF9tYXNrKTsKCglpMm9fbXNnX3Bvc3QoYywgbXNnKTsKCglyZXR1cm4gMDsKfQoKc3RhdGljIGludCBpMm9fY2ZnX2V2dF9nZXQodW5zaWduZWQgbG9uZyBhcmcsIHN0cnVjdCBmaWxlICpmcCkKewoJc3RydWN0IGkyb19jZmdfaW5mbyAqcCA9IE5VTEw7CglzdHJ1Y3QgaTJvX2V2dF9nZXQgX191c2VyICp1Z2V0ID0gKHN0cnVjdCBpMm9fZXZ0X2dldCBfX3VzZXIgKilhcmc7CglzdHJ1Y3QgaTJvX2V2dF9nZXQga2dldDsKCXVuc2lnbmVkIGxvbmcgZmxhZ3M7CgoJZm9yIChwID0gb3Blbl9maWxlczsgcDsgcCA9IHAtPm5leHQpCgkJaWYgKHAtPnFfaWQgPT0gKHVsb25nKSBmcC0+cHJpdmF0ZV9kYXRhKQoJCQlicmVhazsKCglpZiAoIXAtPnFfbGVuKQoJCXJldHVybiAtRU5PRU5UOwoKCW1lbWNweSgma2dldC5pbmZvLCAmcC0+ZXZlbnRfcVtwLT5xX291dF0sIHNpemVvZihzdHJ1Y3QgaTJvX2V2dF9pbmZvKSk7CglNT0RJTkMocC0+cV9vdXQsIEkyT19FVlRfUV9MRU4pOwoJc3Bpbl9sb2NrX2lycXNhdmUoJmkyb19jb25maWdfbG9jaywgZmxhZ3MpOwoJcC0+cV9sZW4tLTsKCWtnZXQucGVuZGluZyA9IHAtPnFfbGVuOwoJa2dldC5sb3N0ID0gcC0+cV9sb3N0OwoJc3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmaTJvX2NvbmZpZ19sb2NrLCBmbGFncyk7CgoJaWYgKGNvcHlfdG9fdXNlcih1Z2V0LCAma2dldCwgc2l6ZW9mKHN0cnVjdCBpMm9fZXZ0X2dldCkpKQoJCXJldHVybiAtRUZBVUxUOwoJcmV0dXJuIDA7Cn0KCiNpZmRlZiBDT05GSUdfQ09NUEFUCnN0YXRpYyBpbnQgaTJvX2NmZ19wYXNzdGhydTMyKHN0cnVjdCBmaWxlICpmaWxlLCB1bnNpZ25lZCBjbW5kLAoJCQkgICAgICB1bnNpZ25lZCBsb25nIGFyZykKewoJc3RydWN0IGkyb19jbWRfcGFzc3RocnUzMiBfX3VzZXIgKmNtZDsKCXN0cnVjdCBpMm9fY29udHJvbGxlciAqYzsKCXUzMiBfX3VzZXIgKnVzZXJfbXNnOwoJdTMyICpyZXBseSA9IE5VTEw7Cgl1MzIgX191c2VyICp1c2VyX3JlcGx5ID0gTlVMTDsKCXUzMiBzaXplID0gMDsKCXUzMiByZXBseV9zaXplID0gMDsKCXUzMiByY29kZSA9IDA7CglzdHJ1Y3QgaTJvX2RtYSBzZ19saXN0W1NHX1RBQkxFU0laRV07Cgl1MzIgc2dfb2Zmc2V0ID0gMDsKCXUzMiBzZ19jb3VudCA9IDA7Cgl1MzIgaSA9IDA7Cgl1MzIgc2dfaW5kZXggPSAwOwoJaTJvX3N0YXR1c19ibG9jayAqc2I7CglzdHJ1Y3QgaTJvX21lc3NhZ2UgKm1zZzsKCXVuc2lnbmVkIGludCBpb3A7CgoJY21kID0gKHN0cnVjdCBpMm9fY21kX3Bhc3N0aHJ1MzIgX191c2VyICopYXJnOwoKCWlmIChnZXRfdXNlcihpb3AsICZjbWQtPmlvcCkgfHwgZ2V0X3VzZXIoaSwgJmNtZC0+bXNnKSkKCQlyZXR1cm4gLUVGQVVMVDsKCgl1c2VyX21zZyA9IGNvbXBhdF9wdHIoaSk7CgoJYyA9IGkyb19maW5kX2lvcChpb3ApOwoJaWYgKCFjKSB7CgkJb3NtX2RlYnVnKCJjb250cm9sbGVyICVkIG5vdCBmb3VuZFxuIiwgaW9wKTsKCQlyZXR1cm4gLUVOWElPOwoJfQoKCXNiID0gYy0+c3RhdHVzX2Jsb2NrLnZpcnQ7CgoJaWYgKGdldF91c2VyKHNpemUsICZ1c2VyX21zZ1swXSkpIHsKCQlvc21fd2FybigidW5hYmxlIHRvIGdldCBzaXplIVxuIik7CgkJcmV0dXJuIC1FRkFVTFQ7Cgl9CglzaXplID0gc2l6ZSA+PiAxNjsKCglpZiAoc2l6ZSA+IHNiLT5pbmJvdW5kX2ZyYW1lX3NpemUpIHsKCQlvc21fd2Fybigic2l6ZSBvZiBtZXNzYWdlID4gaW5ib3VuZF9mcmFtZV9zaXplIik7CgkJcmV0dXJuIC1FRkFVTFQ7Cgl9CgoJdXNlcl9yZXBseSA9ICZ1c2VyX21zZ1tzaXplXTsKCglzaXplIDw8PSAyOwkJLy8gQ29udmVydCB0byBieXRlcwoKCW1zZyA9IGkyb19tc2dfZ2V0X3dhaXQoYywgSTJPX1RJTUVPVVRfTUVTU0FHRV9HRVQpOwoJaWYgKElTX0VSUihtc2cpKQoJCXJldHVybiBQVFJfRVJSKG1zZyk7CgoJcmNvZGUgPSAtRUZBVUxUOwoJLyogQ29weSBpbiB0aGUgdXNlcidzIEkyTyBjb21tYW5kICovCglpZiAoY29weV9mcm9tX3VzZXIobXNnLCB1c2VyX21zZywgc2l6ZSkpIHsKCQlvc21fd2FybigidW5hYmxlIHRvIGNvcHkgdXNlciBtZXNzYWdlXG4iKTsKCQlnb3RvIG91dDsKCX0KCWkyb19kdW1wX21lc3NhZ2UobXNnKTsKCglpZiAoZ2V0X3VzZXIocmVwbHlfc2l6ZSwgJnVzZXJfcmVwbHlbMF0pIDwgMCkKCQlnb3RvIG91dDsKCglyZXBseV9zaXplID4+PSAxNjsKCXJlcGx5X3NpemUgPDw9IDI7CgoJcmNvZGUgPSAtRU5PTUVNOwoJcmVwbHkgPSBremFsbG9jKHJlcGx5X3NpemUsIEdGUF9LRVJORUwpOwoJaWYgKCFyZXBseSkgewoJCXByaW50ayhLRVJOX1dBUk5JTkcgIiVzOiBDb3VsZCBub3QgYWxsb2NhdGUgcmVwbHkgYnVmZmVyXG4iLAoJCSAgICAgICBjLT5uYW1lKTsKCQlnb3RvIG91dDsKCX0KCglzZ19vZmZzZXQgPSAobXNnLT51LmhlYWRbMF0gPj4gNCkgJiAweDBmOwoKCW1lbXNldChzZ19saXN0LCAwLCBzaXplb2Yoc2dfbGlzdFswXSkgKiBTR19UQUJMRVNJWkUpOwoJaWYgKHNnX29mZnNldCkgewoJCXN0cnVjdCBzZ19zaW1wbGVfZWxlbWVudCAqc2c7CgoJCWlmIChzZ19vZmZzZXQgKiA0ID49IHNpemUpIHsKCQkJcmNvZGUgPSAtRUZBVUxUOwoJCQlnb3RvIGNsZWFudXA7CgkJfQoJCS8vIFRPRE8gNjRiaXQgZml4CgkJc2cgPSAoc3RydWN0IHNnX3NpbXBsZV9lbGVtZW50ICopKCgmbXNnLT51LmhlYWRbMF0pICsKCQkJCQkJICBzZ19vZmZzZXQpOwoJCXNnX2NvdW50ID0KCQkgICAgKHNpemUgLSBzZ19vZmZzZXQgKiA0KSAvIHNpemVvZihzdHJ1Y3Qgc2dfc2ltcGxlX2VsZW1lbnQpOwoJCWlmIChzZ19jb3VudCA+IFNHX1RBQkxFU0laRSkgewoJCQlwcmludGsoS0VSTl9ERUJVRyAiJXM6SU9DVEwgU0cgTGlzdCB0b28gbGFyZ2UgKCV1KVxuIiwKCQkJICAgICAgIGMtPm5hbWUsIHNnX2NvdW50KTsKCQkJcmNvZGUgPSAtRUlOVkFMOwoJCQlnb3RvIGNsZWFudXA7CgkJfQoKCQlmb3IgKGkgPSAwOyBpIDwgc2dfY291bnQ7IGkrKykgewoJCQlpbnQgc2dfc2l6ZTsKCQkJc3RydWN0IGkyb19kbWEgKnA7CgoJCQlpZiAoIShzZ1tpXS5mbGFnX2NvdW50ICYgMHgxMDAwMDAwMAoJCQkgICAgICAvKkkyT19TR0xfRkxBR1NfU0lNUExFX0FERFJFU1NfRUxFTUVOVCAqLyApKSB7CgkJCQlwcmludGsoS0VSTl9ERUJVRwoJCQkJICAgICAgICIlczpCYWQgU0cgZWxlbWVudCAlZCAtIG5vdCBzaW1wbGUgKCV4KVxuIiwKCQkJCSAgICAgICBjLT5uYW1lLCBpLCBzZ1tpXS5mbGFnX2NvdW50KTsKCQkJCXJjb2RlID0gLUVJTlZBTDsKCQkJCWdvdG8gY2xlYW51cDsKCQkJfQoJCQlzZ19zaXplID0gc2dbaV0uZmxhZ19jb3VudCAmIDB4ZmZmZmZmOwoJCQlwID0gJihzZ19saXN0W3NnX2luZGV4XSk7CgkJCS8qIEFsbG9jYXRlIG1lbW9yeSBmb3IgdGhlIHRyYW5zZmVyICovCgkJCWlmIChpMm9fZG1hX2FsbG9jCgkJCSAgICAoJmMtPnBkZXYtPmRldiwgcCwgc2dfc2l6ZSwKCQkJICAgICBQQ0lfRE1BX0JJRElSRUNUSU9OQUwpKSB7CgkJCQlwcmludGsoS0VSTl9ERUJVRwoJCQkJICAgICAgICIlczogQ291bGQgbm90IGFsbG9jYXRlIFNHIGJ1ZmZlciAtIHNpemUgPSAlZCBidWZmZXIgbnVtYmVyICVkIG9mICVkXG4iLAoJCQkJICAgICAgIGMtPm5hbWUsIHNnX3NpemUsIGksIHNnX2NvdW50KTsKCQkJCXJjb2RlID0gLUVOT01FTTsKCQkJCWdvdG8gc2dfbGlzdF9jbGVhbnVwOwoJCQl9CgkJCXNnX2luZGV4Kys7CgkJCS8qIENvcHkgaW4gdGhlIHVzZXIncyBTRyBidWZmZXIgaWYgbmVjZXNzYXJ5ICovCgkJCWlmIChzZ1tpXS4KCQkJICAgIGZsYWdfY291bnQgJiAweDA0MDAwMDAwIC8qSTJPX1NHTF9GTEFHU19ESVIgKi8gKSB7CgkJCQkvLyBUT0RPIDY0Yml0IGZpeAoJCQkJaWYgKGNvcHlfZnJvbV91c2VyCgkJCQkgICAgKHAtPnZpcnQsCgkJCQkgICAgICh2b2lkIF9fdXNlciAqKSh1bnNpZ25lZCBsb25nKXNnW2ldLgoJCQkJICAgICBhZGRyX2J1cywgc2dfc2l6ZSkpIHsKCQkJCQlwcmludGsoS0VSTl9ERUJVRwoJCQkJCSAgICAgICAiJXM6IENvdWxkIG5vdCBjb3B5IFNHIGJ1ZiAlZCBGUk9NIHVzZXJcbiIsCgkJCQkJICAgICAgIGMtPm5hbWUsIGkpOwoJCQkJCXJjb2RlID0gLUVGQVVMVDsKCQkJCQlnb3RvIHNnX2xpc3RfY2xlYW51cDsKCQkJCX0KCQkJfQoJCQkvL1RPRE8gNjRiaXQgZml4CgkJCXNnW2ldLmFkZHJfYnVzID0gKHUzMikgcC0+cGh5czsKCQl9Cgl9CgoJcmNvZGUgPSBpMm9fbXNnX3Bvc3Rfd2FpdChjLCBtc2csIDYwKTsKCW1zZyA9IE5VTEw7CglpZiAocmNvZGUpIHsKCQlyZXBseVs0XSA9ICgodTMyKSByY29kZSkgPDwgMjQ7CgkJZ290byBzZ19saXN0X2NsZWFudXA7Cgl9CgoJaWYgKHNnX29mZnNldCkgewoJCXUzMiBybXNnW0kyT19PVVRCT1VORF9NU0dfRlJBTUVfU0laRV07CgkJLyogQ29weSBiYWNrIHRoZSBTY2F0dGVyIEdhdGhlciBidWZmZXJzIGJhY2sgdG8gdXNlciBzcGFjZSAqLwoJCXUzMiBqOwoJCS8vIFRPRE8gNjRiaXQgZml4CgkJc3RydWN0IHNnX3NpbXBsZV9lbGVtZW50ICpzZzsKCQlpbnQgc2dfc2l6ZTsKCgkJLy8gcmUtYWNxdWlyZSB0aGUgb3JpZ2luYWwgbWVzc2FnZSB0byBoYW5kbGUgY29ycmVjdGx5IHRoZSBzZyBjb3B5IG9wZXJhdGlvbgoJCW1lbXNldCgmcm1zZywgMCwgSTJPX09VVEJPVU5EX01TR19GUkFNRV9TSVpFICogNCk7CgkJLy8gZ2V0IHVzZXIgbXNnIHNpemUgaW4gdTMycwoJCWlmIChnZXRfdXNlcihzaXplLCAmdXNlcl9tc2dbMF0pKSB7CgkJCXJjb2RlID0gLUVGQVVMVDsKCQkJZ290byBzZ19saXN0X2NsZWFudXA7CgkJfQoJCXNpemUgPSBzaXplID4+IDE2OwoJCXNpemUgKj0gNDsKCQkvKiBDb3B5IGluIHRoZSB1c2VyJ3MgSTJPIGNvbW1hbmQgKi8KCQlpZiAoY29weV9mcm9tX3VzZXIocm1zZywgdXNlcl9tc2csIHNpemUpKSB7CgkJCXJjb2RlID0gLUVGQVVMVDsKCQkJZ290byBzZ19saXN0X2NsZWFudXA7CgkJfQoJCXNnX2NvdW50ID0KCQkgICAgKHNpemUgLSBzZ19vZmZzZXQgKiA0KSAvIHNpemVvZihzdHJ1Y3Qgc2dfc2ltcGxlX2VsZW1lbnQpOwoKCQkvLyBUT0RPIDY0Yml0IGZpeAoJCXNnID0gKHN0cnVjdCBzZ19zaW1wbGVfZWxlbWVudCAqKShybXNnICsgc2dfb2Zmc2V0KTsKCQlmb3IgKGogPSAwOyBqIDwgc2dfY291bnQ7IGorKykgewoJCQkvKiBDb3B5IG91dCB0aGUgU0cgbGlzdCB0byB1c2VyJ3MgYnVmZmVyIGlmIG5lY2Vzc2FyeSAqLwoJCQlpZiAoIQoJCQkgICAgKHNnW2pdLgoJCQkgICAgIGZsYWdfY291bnQgJiAweDQwMDAwMDAgLypJMk9fU0dMX0ZMQUdTX0RJUiAqLyApKSB7CgkJCQlzZ19zaXplID0gc2dbal0uZmxhZ19jb3VudCAmIDB4ZmZmZmZmOwoJCQkJLy8gVE9ETyA2NGJpdCBmaXgKCQkJCWlmIChjb3B5X3RvX3VzZXIKCQkJCSAgICAoKHZvaWQgX191c2VyICopKHU2NCkgc2dbal0uYWRkcl9idXMsCgkJCQkgICAgIHNnX2xpc3Rbal0udmlydCwgc2dfc2l6ZSkpIHsKCQkJCQlwcmludGsoS0VSTl9XQVJOSU5HCgkJCQkJICAgICAgICIlczogQ291bGQgbm90IGNvcHkgJXAgVE8gdXNlciAleFxuIiwKCQkJCQkgICAgICAgYy0+bmFtZSwgc2dfbGlzdFtqXS52aXJ0LAoJCQkJCSAgICAgICBzZ1tqXS5hZGRyX2J1cyk7CgkJCQkJcmNvZGUgPSAtRUZBVUxUOwoJCQkJCWdvdG8gc2dfbGlzdF9jbGVhbnVwOwoJCQkJfQoJCQl9CgkJfQoJfQoKc2dfbGlzdF9jbGVhbnVwOgoJLyogQ29weSBiYWNrIHRoZSByZXBseSB0byB1c2VyIHNwYWNlICovCglpZiAocmVwbHlfc2l6ZSkgewoJCS8vIHdlIHdyb3RlIG91ciBvd24gdmFsdWVzIGZvciBjb250ZXh0IC0gbm93IHJlc3RvcmUgdGhlIHVzZXIgc3VwcGxpZWQgb25lcwoJCWlmIChjb3B5X2Zyb21fdXNlcihyZXBseSArIDIsIHVzZXJfbXNnICsgMiwgc2l6ZW9mKHUzMikgKiAyKSkgewoJCQlwcmludGsoS0VSTl9XQVJOSU5HCgkJCSAgICAgICAiJXM6IENvdWxkIG5vdCBjb3B5IG1lc3NhZ2UgY29udGV4dCBGUk9NIHVzZXJcbiIsCgkJCSAgICAgICBjLT5uYW1lKTsKCQkJcmNvZGUgPSAtRUZBVUxUOwoJCX0KCQlpZiAoY29weV90b191c2VyKHVzZXJfcmVwbHksIHJlcGx5LCByZXBseV9zaXplKSkgewoJCQlwcmludGsoS0VSTl9XQVJOSU5HCgkJCSAgICAgICAiJXM6IENvdWxkIG5vdCBjb3B5IHJlcGx5IFRPIHVzZXJcbiIsIGMtPm5hbWUpOwoJCQlyY29kZSA9IC1FRkFVTFQ7CgkJfQoJfQoJZm9yIChpID0gMDsgaSA8IHNnX2luZGV4OyBpKyspCgkJaTJvX2RtYV9mcmVlKCZjLT5wZGV2LT5kZXYsICZzZ19saXN0W2ldKTsKCmNsZWFudXA6CglrZnJlZShyZXBseSk7Cm91dDoKCWlmIChtc2cpCgkJaTJvX21zZ19ub3AoYywgbXNnKTsKCXJldHVybiByY29kZTsKfQoKc3RhdGljIGxvbmcgaTJvX2NmZ19jb21wYXRfaW9jdGwoc3RydWN0IGZpbGUgKmZpbGUsIHVuc2lnbmVkIGNtZCwKCQkJCSB1bnNpZ25lZCBsb25nIGFyZykKewoJaW50IHJldDsKCWxvY2tfa2VybmVsKCk7Cglzd2l0Y2ggKGNtZCkgewoJY2FzZSBJMk9HRVRJT1BTOgoJCXJldCA9IGkyb19jZmdfaW9jdGwoTlVMTCwgZmlsZSwgY21kLCBhcmcpOwoJCWJyZWFrOwoJY2FzZSBJMk9QQVNTVEhSVTMyOgoJCXJldCA9IGkyb19jZmdfcGFzc3RocnUzMihmaWxlLCBjbWQsIGFyZyk7CgkJYnJlYWs7CglkZWZhdWx0OgoJCXJldCA9IC1FTk9JT0NUTENNRDsKCQlicmVhazsKCX0KCXVubG9ja19rZXJuZWwoKTsKCXJldHVybiByZXQ7Cn0KCiNlbmRpZgoKI2lmZGVmIENPTkZJR19JMk9fRVhUX0FEQVBURUMKc3RhdGljIGludCBpMm9fY2ZnX3Bhc3N0aHJ1KHVuc2lnbmVkIGxvbmcgYXJnKQp7CglzdHJ1Y3QgaTJvX2NtZF9wYXNzdGhydSBfX3VzZXIgKmNtZCA9CgkgICAgKHN0cnVjdCBpMm9fY21kX3Bhc3N0aHJ1IF9fdXNlciAqKWFyZzsKCXN0cnVjdCBpMm9fY29udHJvbGxlciAqYzsKCXUzMiBfX3VzZXIgKnVzZXJfbXNnOwoJdTMyICpyZXBseSA9IE5VTEw7Cgl1MzIgX191c2VyICp1c2VyX3JlcGx5ID0gTlVMTDsKCXUzMiBzaXplID0gMDsKCXUzMiByZXBseV9zaXplID0gMDsKCXUzMiByY29kZSA9IDA7Cgl2b2lkICpzZ19saXN0W1NHX1RBQkxFU0laRV07Cgl1MzIgc2dfb2Zmc2V0ID0gMDsKCXUzMiBzZ19jb3VudCA9IDA7CglpbnQgc2dfaW5kZXggPSAwOwoJdTMyIGkgPSAwOwoJdm9pZCAqcCA9IE5VTEw7CglpMm9fc3RhdHVzX2Jsb2NrICpzYjsKCXN0cnVjdCBpMm9fbWVzc2FnZSAqbXNnOwoJdW5zaWduZWQgaW50IGlvcDsKCglpZiAoZ2V0X3VzZXIoaW9wLCAmY21kLT5pb3ApIHx8IGdldF91c2VyKHVzZXJfbXNnLCAmY21kLT5tc2cpKQoJCXJldHVybiAtRUZBVUxUOwoKCWMgPSBpMm9fZmluZF9pb3AoaW9wKTsKCWlmICghYykgewoJCW9zbV93YXJuKCJjb250cm9sbGVyICVkIG5vdCBmb3VuZFxuIiwgaW9wKTsKCQlyZXR1cm4gLUVOWElPOwoJfQoKCXNiID0gYy0+c3RhdHVzX2Jsb2NrLnZpcnQ7CgoJaWYgKGdldF91c2VyKHNpemUsICZ1c2VyX21zZ1swXSkpCgkJcmV0dXJuIC1FRkFVTFQ7CglzaXplID0gc2l6ZSA+PiAxNjsKCglpZiAoc2l6ZSA+IHNiLT5pbmJvdW5kX2ZyYW1lX3NpemUpIHsKCQlvc21fd2Fybigic2l6ZSBvZiBtZXNzYWdlID4gaW5ib3VuZF9mcmFtZV9zaXplIik7CgkJcmV0dXJuIC1FRkFVTFQ7Cgl9CgoJdXNlcl9yZXBseSA9ICZ1c2VyX21zZ1tzaXplXTsKCglzaXplIDw8PSAyOwkJLy8gQ29udmVydCB0byBieXRlcwoKCW1zZyA9IGkyb19tc2dfZ2V0X3dhaXQoYywgSTJPX1RJTUVPVVRfTUVTU0FHRV9HRVQpOwoJaWYgKElTX0VSUihtc2cpKQoJCXJldHVybiBQVFJfRVJSKG1zZyk7CgoJcmNvZGUgPSAtRUZBVUxUOwoJLyogQ29weSBpbiB0aGUgdXNlcidzIEkyTyBjb21tYW5kICovCglpZiAoY29weV9mcm9tX3VzZXIobXNnLCB1c2VyX21zZywgc2l6ZSkpCgkJZ290byBvdXQ7CgoJaWYgKGdldF91c2VyKHJlcGx5X3NpemUsICZ1c2VyX3JlcGx5WzBdKSA8IDApCgkJZ290byBvdXQ7CgoJcmVwbHlfc2l6ZSA+Pj0gMTY7CglyZXBseV9zaXplIDw8PSAyOwoKCXJlcGx5ID0ga3phbGxvYyhyZXBseV9zaXplLCBHRlBfS0VSTkVMKTsKCWlmICghcmVwbHkpIHsKCQlwcmludGsoS0VSTl9XQVJOSU5HICIlczogQ291bGQgbm90IGFsbG9jYXRlIHJlcGx5IGJ1ZmZlclxuIiwKCQkgICAgICAgYy0+bmFtZSk7CgkJcmNvZGUgPSAtRU5PTUVNOwoJCWdvdG8gb3V0OwoJfQoKCXNnX29mZnNldCA9IChtc2ctPnUuaGVhZFswXSA+PiA0KSAmIDB4MGY7CgoJbWVtc2V0KHNnX2xpc3QsIDAsIHNpemVvZihzZ19saXN0WzBdKSAqIFNHX1RBQkxFU0laRSk7CglpZiAoc2dfb2Zmc2V0KSB7CgkJc3RydWN0IHNnX3NpbXBsZV9lbGVtZW50ICpzZzsKCgkJaWYgKHNnX29mZnNldCAqIDQgPj0gc2l6ZSkgewoJCQlyY29kZSA9IC1FRkFVTFQ7CgkJCWdvdG8gY2xlYW51cDsKCQl9CgkJLy8gVE9ETyA2NGJpdCBmaXgKCQlzZyA9IChzdHJ1Y3Qgc2dfc2ltcGxlX2VsZW1lbnQgKikoKCZtc2ctPnUuaGVhZFswXSkgKwoJCQkJCQkgIHNnX29mZnNldCk7CgkJc2dfY291bnQgPQoJCSAgICAoc2l6ZSAtIHNnX29mZnNldCAqIDQpIC8gc2l6ZW9mKHN0cnVjdCBzZ19zaW1wbGVfZWxlbWVudCk7CgkJaWYgKHNnX2NvdW50ID4gU0dfVEFCTEVTSVpFKSB7CgkJCXByaW50ayhLRVJOX0RFQlVHICIlczpJT0NUTCBTRyBMaXN0IHRvbyBsYXJnZSAoJXUpXG4iLAoJCQkgICAgICAgYy0+bmFtZSwgc2dfY291bnQpOwoJCQlyY29kZSA9IC1FSU5WQUw7CgkJCWdvdG8gY2xlYW51cDsKCQl9CgoJCWZvciAoaSA9IDA7IGkgPCBzZ19jb3VudDsgaSsrKSB7CgkJCWludCBzZ19zaXplOwoKCQkJaWYgKCEoc2dbaV0uZmxhZ19jb3VudCAmIDB4MTAwMDAwMDAKCQkJICAgICAgLypJMk9fU0dMX0ZMQUdTX1NJTVBMRV9BRERSRVNTX0VMRU1FTlQgKi8gKSkgewoJCQkJcHJpbnRrKEtFUk5fREVCVUcKCQkJCSAgICAgICAiJXM6QmFkIFNHIGVsZW1lbnQgJWQgLSBub3Qgc2ltcGxlICgleClcbiIsCgkJCQkgICAgICAgYy0+bmFtZSwgaSwgc2dbaV0uZmxhZ19jb3VudCk7CgkJCQlyY29kZSA9IC1FSU5WQUw7CgkJCQlnb3RvIHNnX2xpc3RfY2xlYW51cDsKCQkJfQoJCQlzZ19zaXplID0gc2dbaV0uZmxhZ19jb3VudCAmIDB4ZmZmZmZmOwoJCQkvKiBBbGxvY2F0ZSBtZW1vcnkgZm9yIHRoZSB0cmFuc2ZlciAqLwoJCQlwID0ga21hbGxvYyhzZ19zaXplLCBHRlBfS0VSTkVMKTsKCQkJaWYgKCFwKSB7CgkJCQlwcmludGsoS0VSTl9ERUJVRwoJCQkJICAgICAgICIlczogQ291bGQgbm90IGFsbG9jYXRlIFNHIGJ1ZmZlciAtIHNpemUgPSAlZCBidWZmZXIgbnVtYmVyICVkIG9mICVkXG4iLAoJCQkJICAgICAgIGMtPm5hbWUsIHNnX3NpemUsIGksIHNnX2NvdW50KTsKCQkJCXJjb2RlID0gLUVOT01FTTsKCQkJCWdvdG8gc2dfbGlzdF9jbGVhbnVwOwoJCQl9CgkJCXNnX2xpc3Rbc2dfaW5kZXgrK10gPSBwOwkvLyBzZ2xpc3QgaW5kZXhlZCB3aXRoIGlucHV0IGZyYW1lLCBub3Qgb3VyIGludGVybmFsIGZyYW1lLgoJCQkvKiBDb3B5IGluIHRoZSB1c2VyJ3MgU0cgYnVmZmVyIGlmIG5lY2Vzc2FyeSAqLwoJCQlpZiAoc2dbaV0uCgkJCSAgICBmbGFnX2NvdW50ICYgMHgwNDAwMDAwMCAvKkkyT19TR0xfRkxBR1NfRElSICovICkgewoJCQkJLy8gVE9ETyA2NGJpdCBmaXgKCQkJCWlmIChjb3B5X2Zyb21fdXNlcgoJCQkJICAgIChwLCAodm9pZCBfX3VzZXIgKilzZ1tpXS5hZGRyX2J1cywKCQkJCSAgICAgc2dfc2l6ZSkpIHsKCQkJCQlwcmludGsoS0VSTl9ERUJVRwoJCQkJCSAgICAgICAiJXM6IENvdWxkIG5vdCBjb3B5IFNHIGJ1ZiAlZCBGUk9NIHVzZXJcbiIsCgkJCQkJICAgICAgIGMtPm5hbWUsIGkpOwoJCQkJCXJjb2RlID0gLUVGQVVMVDsKCQkJCQlnb3RvIHNnX2xpc3RfY2xlYW51cDsKCQkJCX0KCQkJfQoJCQkvL1RPRE8gNjRiaXQgZml4CgkJCXNnW2ldLmFkZHJfYnVzID0gdmlydF90b19idXMocCk7CgkJfQoJfQoKCXJjb2RlID0gaTJvX21zZ19wb3N0X3dhaXQoYywgbXNnLCA2MCk7Cgltc2cgPSBOVUxMOwoJaWYgKHJjb2RlKSB7CgkJcmVwbHlbNF0gPSAoKHUzMikgcmNvZGUpIDw8IDI0OwoJCWdvdG8gc2dfbGlzdF9jbGVhbnVwOwoJfQoKCWlmIChzZ19vZmZzZXQpIHsKCQl1MzIgcm1zZ1sxMjhdOwoJCS8qIENvcHkgYmFjayB0aGUgU2NhdHRlciBHYXRoZXIgYnVmZmVycyBiYWNrIHRvIHVzZXIgc3BhY2UgKi8KCQl1MzIgajsKCQkvLyBUT0RPIDY0Yml0IGZpeAoJCXN0cnVjdCBzZ19zaW1wbGVfZWxlbWVudCAqc2c7CgkJaW50IHNnX3NpemU7CgoJCS8vIHJlLWFjcXVpcmUgdGhlIG9yaWdpbmFsIG1lc3NhZ2UgdG8gaGFuZGxlIGNvcnJlY3RseSB0aGUgc2cgY29weSBvcGVyYXRpb24KCQltZW1zZXQoJnJtc2csIDAsIEkyT19PVVRCT1VORF9NU0dfRlJBTUVfU0laRSAqIDQpOwoJCS8vIGdldCB1c2VyIG1zZyBzaXplIGluIHUzMnMKCQlpZiAoZ2V0X3VzZXIoc2l6ZSwgJnVzZXJfbXNnWzBdKSkgewoJCQlyY29kZSA9IC1FRkFVTFQ7CgkJCWdvdG8gc2dfbGlzdF9jbGVhbnVwOwoJCX0KCQlzaXplID0gc2l6ZSA+PiAxNjsKCQlzaXplICo9IDQ7CgkJLyogQ29weSBpbiB0aGUgdXNlcidzIEkyTyBjb21tYW5kICovCgkJaWYgKGNvcHlfZnJvbV91c2VyKHJtc2csIHVzZXJfbXNnLCBzaXplKSkgewoJCQlyY29kZSA9IC1FRkFVTFQ7CgkJCWdvdG8gc2dfbGlzdF9jbGVhbnVwOwoJCX0KCQlzZ19jb3VudCA9CgkJICAgIChzaXplIC0gc2dfb2Zmc2V0ICogNCkgLyBzaXplb2Yoc3RydWN0IHNnX3NpbXBsZV9lbGVtZW50KTsKCgkJLy8gVE9ETyA2NGJpdCBmaXgKCQlzZyA9IChzdHJ1Y3Qgc2dfc2ltcGxlX2VsZW1lbnQgKikocm1zZyArIHNnX29mZnNldCk7CgkJZm9yIChqID0gMDsgaiA8IHNnX2NvdW50OyBqKyspIHsKCQkJLyogQ29weSBvdXQgdGhlIFNHIGxpc3QgdG8gdXNlcidzIGJ1ZmZlciBpZiBuZWNlc3NhcnkgKi8KCQkJaWYgKCEKCQkJICAgIChzZ1tqXS4KCQkJICAgICBmbGFnX2NvdW50ICYgMHg0MDAwMDAwIC8qSTJPX1NHTF9GTEFHU19ESVIgKi8gKSkgewoJCQkJc2dfc2l6ZSA9IHNnW2pdLmZsYWdfY291bnQgJiAweGZmZmZmZjsKCQkJCS8vIFRPRE8gNjRiaXQgZml4CgkJCQlpZiAoY29weV90b191c2VyCgkJCQkgICAgKCh2b2lkIF9fdXNlciAqKXNnW2pdLmFkZHJfYnVzLCBzZ19saXN0W2pdLAoJCQkJICAgICBzZ19zaXplKSkgewoJCQkJCXByaW50ayhLRVJOX1dBUk5JTkcKCQkJCQkgICAgICAgIiVzOiBDb3VsZCBub3QgY29weSAlcCBUTyB1c2VyICV4XG4iLAoJCQkJCSAgICAgICBjLT5uYW1lLCBzZ19saXN0W2pdLAoJCQkJCSAgICAgICBzZ1tqXS5hZGRyX2J1cyk7CgkJCQkJcmNvZGUgPSAtRUZBVUxUOwoJCQkJCWdvdG8gc2dfbGlzdF9jbGVhbnVwOwoJCQkJfQoJCQl9CgkJfQoJfQoKc2dfbGlzdF9jbGVhbnVwOgoJLyogQ29weSBiYWNrIHRoZSByZXBseSB0byB1c2VyIHNwYWNlICovCglpZiAocmVwbHlfc2l6ZSkgewoJCS8vIHdlIHdyb3RlIG91ciBvd24gdmFsdWVzIGZvciBjb250ZXh0IC0gbm93IHJlc3RvcmUgdGhlIHVzZXIgc3VwcGxpZWQgb25lcwoJCWlmIChjb3B5X2Zyb21fdXNlcihyZXBseSArIDIsIHVzZXJfbXNnICsgMiwgc2l6ZW9mKHUzMikgKiAyKSkgewoJCQlwcmludGsoS0VSTl9XQVJOSU5HCgkJCSAgICAgICAiJXM6IENvdWxkIG5vdCBjb3B5IG1lc3NhZ2UgY29udGV4dCBGUk9NIHVzZXJcbiIsCgkJCSAgICAgICBjLT5uYW1lKTsKCQkJcmNvZGUgPSAtRUZBVUxUOwoJCX0KCQlpZiAoY29weV90b191c2VyKHVzZXJfcmVwbHksIHJlcGx5LCByZXBseV9zaXplKSkgewoJCQlwcmludGsoS0VSTl9XQVJOSU5HCgkJCSAgICAgICAiJXM6IENvdWxkIG5vdCBjb3B5IHJlcGx5IFRPIHVzZXJcbiIsIGMtPm5hbWUpOwoJCQlyY29kZSA9IC1FRkFVTFQ7CgkJfQoJfQoKCWZvciAoaSA9IDA7IGkgPCBzZ19pbmRleDsgaSsrKQoJCWtmcmVlKHNnX2xpc3RbaV0pOwoKY2xlYW51cDoKCWtmcmVlKHJlcGx5KTsKb3V0OgoJaWYgKG1zZykKCQlpMm9fbXNnX25vcChjLCBtc2cpOwoJcmV0dXJuIHJjb2RlOwp9CiNlbmRpZgoKLyoKICogSU9DVEwgSGFuZGxlcgogKi8Kc3RhdGljIGludCBpMm9fY2ZnX2lvY3RsKHN0cnVjdCBpbm9kZSAqaW5vZGUsIHN0cnVjdCBmaWxlICpmcCwgdW5zaWduZWQgaW50IGNtZCwKCQkJIHVuc2lnbmVkIGxvbmcgYXJnKQp7CglpbnQgcmV0OwoKCXN3aXRjaCAoY21kKSB7CgljYXNlIEkyT0dFVElPUFM6CgkJcmV0ID0gaTJvX2NmZ19nZXRpb3BzKGFyZyk7CgkJYnJlYWs7CgoJY2FzZSBJMk9IUlRHRVQ6CgkJcmV0ID0gaTJvX2NmZ19nZXRocnQoYXJnKTsKCQlicmVhazsKCgljYXNlIEkyT0xDVEdFVDoKCQlyZXQgPSBpMm9fY2ZnX2dldGxjdChhcmcpOwoJCWJyZWFrOwoKCWNhc2UgSTJPUEFSTVNFVDoKCQlyZXQgPSBpMm9fY2ZnX3Bhcm1zKGFyZywgSTJPUEFSTVNFVCk7CgkJYnJlYWs7CgoJY2FzZSBJMk9QQVJNR0VUOgoJCXJldCA9IGkyb19jZmdfcGFybXMoYXJnLCBJMk9QQVJNR0VUKTsKCQlicmVhazsKCgljYXNlIEkyT1NXREw6CgkJcmV0ID0gaTJvX2NmZ19zd2RsKGFyZyk7CgkJYnJlYWs7CgoJY2FzZSBJMk9TV1VMOgoJCXJldCA9IGkyb19jZmdfc3d1bChhcmcpOwoJCWJyZWFrOwoKCWNhc2UgSTJPU1dERUw6CgkJcmV0ID0gaTJvX2NmZ19zd2RlbChhcmcpOwoJCWJyZWFrOwoKCWNhc2UgSTJPVkFMSURBVEU6CgkJcmV0ID0gaTJvX2NmZ192YWxpZGF0ZShhcmcpOwoJCWJyZWFrOwoKCWNhc2UgSTJPRVZUUkVHOgoJCXJldCA9IGkyb19jZmdfZXZ0X3JlZyhhcmcsIGZwKTsKCQlicmVhazsKCgljYXNlIEkyT0VWVEdFVDoKCQlyZXQgPSBpMm9fY2ZnX2V2dF9nZXQoYXJnLCBmcCk7CgkJYnJlYWs7CgojaWZkZWYgQ09ORklHX0kyT19FWFRfQURBUFRFQwoJY2FzZSBJMk9QQVNTVEhSVToKCQlyZXQgPSBpMm9fY2ZnX3Bhc3N0aHJ1KGFyZyk7CgkJYnJlYWs7CiNlbmRpZgoKCWRlZmF1bHQ6CgkJb3NtX2RlYnVnKCJ1bmtub3duIGlvY3RsIGNhbGxlZCFcbiIpOwoJCXJldCA9IC1FSU5WQUw7Cgl9CgoJcmV0dXJuIHJldDsKfQoKc3RhdGljIGludCBjZmdfb3BlbihzdHJ1Y3QgaW5vZGUgKmlub2RlLCBzdHJ1Y3QgZmlsZSAqZmlsZSkKewoJc3RydWN0IGkyb19jZmdfaW5mbyAqdG1wID0KCSAgICAoc3RydWN0IGkyb19jZmdfaW5mbyAqKWttYWxsb2Moc2l6ZW9mKHN0cnVjdCBpMm9fY2ZnX2luZm8pLAoJCQkJCSAgIEdGUF9LRVJORUwpOwoJdW5zaWduZWQgbG9uZyBmbGFnczsKCglpZiAoIXRtcCkKCQlyZXR1cm4gLUVOT01FTTsKCglmaWxlLT5wcml2YXRlX2RhdGEgPSAodm9pZCAqKShpMm9fY2ZnX2luZm9faWQrKyk7Cgl0bXAtPmZwID0gZmlsZTsKCXRtcC0+ZmFzeW5jID0gTlVMTDsKCXRtcC0+cV9pZCA9ICh1bG9uZykgZmlsZS0+cHJpdmF0ZV9kYXRhOwoJdG1wLT5xX2xlbiA9IDA7Cgl0bXAtPnFfaW4gPSAwOwoJdG1wLT5xX291dCA9IDA7Cgl0bXAtPnFfbG9zdCA9IDA7Cgl0bXAtPm5leHQgPSBvcGVuX2ZpbGVzOwoKCXNwaW5fbG9ja19pcnFzYXZlKCZpMm9fY29uZmlnX2xvY2ssIGZsYWdzKTsKCW9wZW5fZmlsZXMgPSB0bXA7CglzcGluX3VubG9ja19pcnFyZXN0b3JlKCZpMm9fY29uZmlnX2xvY2ssIGZsYWdzKTsKCglyZXR1cm4gMDsKfQoKc3RhdGljIGludCBjZmdfZmFzeW5jKGludCBmZCwgc3RydWN0IGZpbGUgKmZwLCBpbnQgb24pCnsKCXVsb25nIGlkID0gKHVsb25nKSBmcC0+cHJpdmF0ZV9kYXRhOwoJc3RydWN0IGkyb19jZmdfaW5mbyAqcDsKCglmb3IgKHAgPSBvcGVuX2ZpbGVzOyBwOyBwID0gcC0+bmV4dCkKCQlpZiAocC0+cV9pZCA9PSBpZCkKCQkJYnJlYWs7CgoJaWYgKCFwKQoJCXJldHVybiAtRUJBREY7CgoJcmV0dXJuIGZhc3luY19oZWxwZXIoZmQsIGZwLCBvbiwgJnAtPmZhc3luYyk7Cn0KCnN0YXRpYyBpbnQgY2ZnX3JlbGVhc2Uoc3RydWN0IGlub2RlICppbm9kZSwgc3RydWN0IGZpbGUgKmZpbGUpCnsKCXVsb25nIGlkID0gKHVsb25nKSBmaWxlLT5wcml2YXRlX2RhdGE7CglzdHJ1Y3QgaTJvX2NmZ19pbmZvICpwMSwgKnAyOwoJdW5zaWduZWQgbG9uZyBmbGFnczsKCglsb2NrX2tlcm5lbCgpOwoJcDEgPSBwMiA9IE5VTEw7CgoJc3Bpbl9sb2NrX2lycXNhdmUoJmkyb19jb25maWdfbG9jaywgZmxhZ3MpOwoJZm9yIChwMSA9IG9wZW5fZmlsZXM7IHAxOykgewoJCWlmIChwMS0+cV9pZCA9PSBpZCkgewoKCQkJaWYgKHAxLT5mYXN5bmMpCgkJCQljZmdfZmFzeW5jKC0xLCBmaWxlLCAwKTsKCQkJaWYgKHAyKQoJCQkJcDItPm5leHQgPSBwMS0+bmV4dDsKCQkJZWxzZQoJCQkJb3Blbl9maWxlcyA9IHAxLT5uZXh0OwoKCQkJa2ZyZWUocDEpOwoJCQlicmVhazsKCQl9CgkJcDIgPSBwMTsKCQlwMSA9IHAxLT5uZXh0OwoJfQoJc3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmaTJvX2NvbmZpZ19sb2NrLCBmbGFncyk7Cgl1bmxvY2tfa2VybmVsKCk7CgoJcmV0dXJuIDA7Cn0KCnN0YXRpYyBjb25zdCBzdHJ1Y3QgZmlsZV9vcGVyYXRpb25zIGNvbmZpZ19mb3BzID0gewoJLm93bmVyID0gVEhJU19NT0RVTEUsCgkubGxzZWVrID0gbm9fbGxzZWVrLAoJLmlvY3RsID0gaTJvX2NmZ19pb2N0bCwKI2lmZGVmIENPTkZJR19DT01QQVQKCS5jb21wYXRfaW9jdGwgPSBpMm9fY2ZnX2NvbXBhdF9pb2N0bCwKI2VuZGlmCgkub3BlbiA9IGNmZ19vcGVuLAoJLnJlbGVhc2UgPSBjZmdfcmVsZWFzZSwKCS5mYXN5bmMgPSBjZmdfZmFzeW5jLAp9OwoKc3RhdGljIHN0cnVjdCBtaXNjZGV2aWNlIGkyb19taXNjZGV2ID0gewoJSTJPX01JTk9SLAoJImkyb2N0bCIsCgkmY29uZmlnX2ZvcHMKfTsKCnN0YXRpYyBpbnQgX19pbml0IGkyb19jb25maWdfb2xkX2luaXQodm9pZCkKewoJc3Bpbl9sb2NrX2luaXQoJmkyb19jb25maWdfbG9jayk7CgoJaWYgKG1pc2NfcmVnaXN0ZXIoJmkyb19taXNjZGV2KSA8IDApIHsKCQlvc21fZXJyKCJjYW4ndCByZWdpc3RlciBkZXZpY2UuXG4iKTsKCQlyZXR1cm4gLUVCVVNZOwoJfQoKCXJldHVybiAwOwp9CgpzdGF0aWMgdm9pZCBpMm9fY29uZmlnX29sZF9leGl0KHZvaWQpCnsKCW1pc2NfZGVyZWdpc3RlcigmaTJvX21pc2NkZXYpOwp9CgpNT0RVTEVfQVVUSE9SKCJSZWQgSGF0IFNvZnR3YXJlIik7Cg==