LyoKICAgIDw6Y29weXJpZ2h0LUJSQ006MjAxMzpEVUFML0dQTDpzdGFuZGFyZAogICAgCiAgICAgICBDb3B5cmlnaHQgKGMpIDIwMTMgQnJvYWRjb20gQ29ycG9yYXRpb24KICAgICAgIEFsbCBSaWdodHMgUmVzZXJ2ZWQKICAgIAogICAgVW5sZXNzIHlvdSBhbmQgQnJvYWRjb20gZXhlY3V0ZSBhIHNlcGFyYXRlIHdyaXR0ZW4gc29mdHdhcmUgbGljZW5zZQogICAgYWdyZWVtZW50IGdvdmVybmluZyB1c2Ugb2YgdGhpcyBzb2Z0d2FyZSwgdGhpcyBzb2Z0d2FyZSBpcyBsaWNlbnNlZAogICAgdG8geW91IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyCiAgICAodGhlICJHUEwiKSwgYXZhaWxhYmxlIGF0IGh0dHA6Ly93d3cuYnJvYWRjb20uY29tL2xpY2Vuc2VzL0dQTHYyLnBocCwKICAgIHdpdGggdGhlIGZvbGxvd2luZyBhZGRlZCB0byBzdWNoIGxpY2Vuc2U6CiAgICAKICAgICAgIEFzIGEgc3BlY2lhbCBleGNlcHRpb24sIHRoZSBjb3B5cmlnaHQgaG9sZGVycyBvZiB0aGlzIHNvZnR3YXJlIGdpdmUKICAgICAgIHlvdSBwZXJtaXNzaW9uIHRvIGxpbmsgdGhpcyBzb2Z0d2FyZSB3aXRoIGluZGVwZW5kZW50IG1vZHVsZXMsIGFuZAogICAgICAgdG8gY29weSBhbmQgZGlzdHJpYnV0ZSB0aGUgcmVzdWx0aW5nIGV4ZWN1dGFibGUgdW5kZXIgdGVybXMgb2YgeW91cgogICAgICAgY2hvaWNlLCBwcm92aWRlZCB0aGF0IHlvdSBhbHNvIG1lZXQsIGZvciBlYWNoIGxpbmtlZCBpbmRlcGVuZGVudAogICAgICAgbW9kdWxlLCB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YgdGhlIGxpY2Vuc2Ugb2YgdGhhdCBtb2R1bGUuCiAgICAgICBBbiBpbmRlcGVuZGVudCBtb2R1bGUgaXMgYSBtb2R1bGUgd2hpY2ggaXMgbm90IGRlcml2ZWQgZnJvbSB0aGlzCiAgICAgICBzb2Z0d2FyZS4gIFRoZSBzcGVjaWFsIGV4Y2VwdGlvbiBkb2VzIG5vdCBhcHBseSB0byBhbnkgbW9kaWZpY2F0aW9ucwogICAgICAgb2YgdGhlIHNvZnR3YXJlLgogICAgCiAgICBOb3Qgd2l0aHN0YW5kaW5nIHRoZSBhYm92ZSwgdW5kZXIgbm8gY2lyY3Vtc3RhbmNlcyBtYXkgeW91IGNvbWJpbmUKICAgIHRoaXMgc29mdHdhcmUgaW4gYW55IHdheSB3aXRoIGFueSBvdGhlciBCcm9hZGNvbSBzb2Z0d2FyZSBwcm92aWRlZAogICAgdW5kZXIgYSBsaWNlbnNlIG90aGVyIHRoYW4gdGhlIEdQTCwgd2l0aG91dCBCcm9hZGNvbSdzIGV4cHJlc3MgcHJpb3IKICAgIHdyaXR0ZW4gY29uc2VudC4KICAgIAogICAgOj4gCgoqLwoKI2luY2x1ZGUgImJic2kuaCIKI2luY2x1ZGUgPGxpbnV4L3NwaS9zcGkuaD4KCiNpZiBMSU5VWF9WRVJTSU9OX0NPREUgPj0gS0VSTkVMX1ZFUlNJT04oMiw2LDMwKQojZWxzZQp0eXBlZGVmIHVuc2lnbmVkIGxvbmcgdWludHB0cl90OwojZW5kaWYgLy8gTElOVVhfVkVSU0lPTl9DT0RFID49IEtFUk5FTF9WRVJTSU9OKDIsNiwzMCkKCiNkZWZpbmUgTU9DQV9SRCh4KSAgICAoKCgoc3RydWN0IG1vY2FfcGxhdGZvcm1fZGF0YSAqKXByaXYtPnBkZXYtPmRldi5wbGF0Zm9ybV9kYXRhKS0+dXNlX3NwaSA9PSAwKSA/IFwKICAgICAgICAgICAgICAgICAgICAgICAoKigodm9sYXRpbGUgdWludDMyX3QgKikoKHVuc2lnbmVkIGxvbmcpKHgpKSkpIDogXAogICAgICAgICAgICAgICAgICAgICAgICgodWludDMyX3Qpa2VyU3lzQmNtU3BpU2xhdmVSZWFkUmVnMzIoKChzdHJ1Y3QgbW9jYV9wbGF0Zm9ybV9kYXRhICopcHJpdi0+cGRldi0+ZGV2LnBsYXRmb3JtX2RhdGEpLT5zcGksICh1aW50MzJfdCkoeCkpKSkKCiNkZWZpbmUgTU9DQV9SRDgoeCwgeSkgKCgoKHN0cnVjdCBtb2NhX3BsYXRmb3JtX2RhdGEgKilwcml2LT5wZGV2LT5kZXYucGxhdGZvcm1fZGF0YSktPnVzZV9zcGkgPT0gMCkgPyBcCiAgICAgICAgICAgICAgICAgICAgICAgICgqKHkpID0gKigodm9sYXRpbGUgdW5zaWduZWQgY2hhciAqKSgodW5zaWduZWQgbG9uZykoeCkpKSkgOiBcCiAgICAgICAgICAgICAgICAgICAgICAgIChrZXJTeXNCY21TcGlTbGF2ZVJlYWQoKChzdHJ1Y3QgbW9jYV9wbGF0Zm9ybV9kYXRhICopcHJpdi0+cGRldi0+ZGV2LnBsYXRmb3JtX2RhdGEpLT5zcGksICh1bnNpZ25lZCBsb25nKSh4KSwgeSwgMSkpKQoKI2RlZmluZSBNT0NBX1dSKHgseSkgICBkbyB7ICgoKChzdHJ1Y3QgbW9jYV9wbGF0Zm9ybV9kYXRhICopcHJpdi0+cGRldi0+ZGV2LnBsYXRmb3JtX2RhdGEpLT51c2Vfc3BpID09IDApID8gXAogICAgICAgICAgICAgICAgICAgICAgICAgICAgKCooKHZvbGF0aWxlIHVpbnQzMl90ICopKCh1bnNpZ25lZCBsb25nKSh4KSkpKSA9ICh5KSA6IFwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGtlclN5c0JjbVNwaVNsYXZlV3JpdGVSZWczMigoKHN0cnVjdCBtb2NhX3BsYXRmb3JtX2RhdGEgKilwcml2LT5wZGV2LT5kZXYucGxhdGZvcm1fZGF0YSktPnNwaSwgKHVpbnQzMl90KSh4KSwgKHkpKSk7IH0gd2hpbGUoMCkKCiNkZWZpbmUgTU9DQV9XUjgoeCx5KSAgICBkbyB7ICgoKChzdHJ1Y3QgbW9jYV9wbGF0Zm9ybV9kYXRhICopcHJpdi0+cGRldi0+ZGV2LnBsYXRmb3JtX2RhdGEpLT51c2Vfc3BpID09IDApID8gXAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKCooKHZvbGF0aWxlIHVuc2lnbmVkIGNoYXIgKikoKHVuc2lnbmVkIGxvbmcpKHgpKSkpID0gKHVuc2lnbmVkIGNoYXIpKHkpIDogXAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAga2VyU3lzQmNtU3BpU2xhdmVXcml0ZSgoKHN0cnVjdCBtb2NhX3BsYXRmb3JtX2RhdGEgKilwcml2LT5wZGV2LT5kZXYucGxhdGZvcm1fZGF0YSktPnNwaSwgKHVuc2lnbmVkIGxvbmcpKHgpLCAoeSksIDEpKTsgfSB3aGlsZSgwKQoKI2RlZmluZSBNT0NBX1dSMTYoeCx5KSAgIGRvIHsgKCgoKHN0cnVjdCBtb2NhX3BsYXRmb3JtX2RhdGEgKilwcml2LT5wZGV2LT5kZXYucGxhdGZvcm1fZGF0YSktPnVzZV9zcGkgPT0gMCkgPyBcCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoKigodm9sYXRpbGUgdW5zaWduZWQgc2hvcnQgKikoKHVuc2lnbmVkIGxvbmcpKHgpKSkpID0gKHVuc2lnbmVkIHNob3J0KSh5KSA6IFwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGtlclN5c0JjbVNwaVNsYXZlV3JpdGUoKChzdHJ1Y3QgbW9jYV9wbGF0Zm9ybV9kYXRhICopcHJpdi0+cGRldi0+ZGV2LnBsYXRmb3JtX2RhdGEpLT5zcGksICh1bnNpZ25lZCBsb25nKSh4KSwgKHkpLCAyKSk7IH0gd2hpbGUoMCkKCiNkZWZpbmUgTU9DQV9XUl9CTE9DSyhhZGRyLCBzcmMsIGxlbikgZG8geyBrZXJTeXNCY21TcGlTbGF2ZVdyaXRlQnVmKCgoc3RydWN0IG1vY2FfcGxhdGZvcm1fZGF0YSAqKXByaXYtPnBkZXYtPmRldi5wbGF0Zm9ybV9kYXRhKS0+c3BpLCBhZGRyLCBzcmMsIGxlbiwgNCk7IH0gd2hpbGUoMCkKI2RlZmluZSBNT0NBX1JEX0JMT0NLKGFkZHIsIGRzdCwgbGVuKSBkbyB7IGtlclN5c0JjbVNwaVNsYXZlUmVhZEJ1ZigoKHN0cnVjdCBtb2NhX3BsYXRmb3JtX2RhdGEgKilwcml2LT5wZGV2LT5kZXYucGxhdGZvcm1fZGF0YSktPnNwaSwgYWRkciwgZHN0LCBsZW4sIDQpOyB9IHdoaWxlKDApCgoKI2RlZmluZSBJMkNfUkQoeCkJCU1PQ0FfUkQoeCkKI2RlZmluZSBJMkNfV1IoeCwgeSkJCU1PQ0FfV1IoeCwgeSkKCiNkZWZpbmUgTU9DQV9CUENNX05VTSAgICAgICAgIDUKI2RlZmluZSBNT0NBX0JQQ01fWk9ORVNfTlVNICAgOAoKI2RlZmluZSBNT0NBX0NQVV9DTE9DS19OVU0gIDEKI2RlZmluZSBNT0NBX1BIWV9DTE9DS19OVU0gIDIKCnR5cGVkZWYgZW51bSBfUE1CX0NPTU1BTkRfRV8KewogICBQTUJfQ09NTUFORF9QSFkxX09OPTAsCiAgIFBNQl9DT01NQU5EX1BBUlRJQUxfT04sCiAgIFBNQl9DT01NQU5EX1BIWTFfT0ZGLAogICBQTUJfQ09NTUFORF9BTExfT0ZGLAoKICAgUE1CX0NPTU1BTkRfTEFTVAp9IFBNQl9DT01NQU5EX0U7Cgp0eXBlZGVmIGVudW0gX1BNQl9HSVZFX09XTkVSU0hJUF9FXwp7CiAgIFBNQl9HSVZFX09XTkVSU0hJUF8yX0hPU1QgPSAwLAogICBQTUJfR0lWRV9PV05FUlNISVBfMl9GVywKCiAgIFBNQl9HRVRfT1dORVJTSElQX0xBU1QKfSBQTUJfR0lWRV9PV05FUlNISVBfRTsKCnN0cnVjdCBtb2NhXzY4MHhfY2xrCnsKCXN0cnVjdCBkZXZpY2UgKmRldjsKCXVpbnQzMl90ICAgICAgIGNsb2NrX251bTsKfTsKCnN0YXRpYyB1aW50MzJfdCB6b25lX2FsbF9vZmZfYml0bWFza1tNT0NBX0JQQ01fTlVNXSA9IHsgMHhGRiwgMHhGRiwgMHhGRiwgMHhGRiwgMHhGRiB9OwpzdGF0aWMgdWludDMyX3Qgem9uZV9wYXJ0aWFsX29uX2JpdG1hc2tbTU9DQV9CUENNX05VTV0gID0geyAweDQxLCAweEZDLCAweEZGLCAweEZGLCAweDAwIH07CnN0YXRpYyB1aW50MzJfdCB6b25lX3BoeTFfYml0bWFza1tNT0NBX0JQQ01fTlVNXSAgPSB7IDB4MDAsIDB4MDAsIDB4MDAsIDB4MDAsIDB4RkYgfTsKCgpzdGF0aWMgdm9pZCBib2d1c19yZWxlYXNlKHN0cnVjdCBkZXZpY2UgKmRldikKewp9CgpzdGF0aWMgc3RydWN0IG1vY2FfcGxhdGZvcm1fZGF0YSBtb2NhX2xhbl9kYXRhID0gewoJLm1hY2FkZHJfaGkgPQkJMHgwMDAwMDEwMiwKCS5tYWNhZGRyX2xvID0JCTB4MDMwNDAwMDAsCgoJLmJjbTM0NTBfaTJjX2Jhc2UgPSAgMHgxMDQwNjIwMCwKCS5iY20zNDUwX2kyY19hZGRyID0gIDB4NzAsCgkuaHdfcmV2ICA9ICAgICBIV1JFVl9NT0NBXzIwX0dFTjIyLAoJLnJmX2JhbmQgPSAgICAgTU9DQV9CQU5EX0VYVF9ELAoJLmNoaXBfaWQgPSAgICAgMCwKCS51c2VfZG1hICAgICAgICAgICA9IDAsCgkudXNlX3NwaSAgICAgICAgICAgPSAxLAoJLmRldklkICAgICAgICAgICAgPSBNT0NBX0RFVklDRV9JRF9VTlJFR0lTVEVSRUQsIC8vIEZpbGxlZCBpbiBkeW5hbWljYWxseQojaWZkZWYgQ09ORklHX1NNUAoJLnNtcF9wcm9jZXNzb3JfaWQgPSAxLAojZW5kaWYKfTsKCnN0YXRpYyBzdHJ1Y3QgcmVzb3VyY2UgbW9jYV9sYW5fcmVzb3VyY2VzW10gPSB7CglbMF0gPSB7CgkJLnN0YXJ0ID0gMHgxMDYwMDAwMCwKCQkuZW5kID0gICAweDEwN2ZmZDk3LAoJCS5mbGFncyA9IElPUkVTT1VSQ0VfTUVNLAoJfSwKCVsxXSA9IHsgLyogTm90IHVzZWQgZm9yIDY4MDIsIGRlZmluZSBmb3IgYm1vY2EgKi8KCQkuc3RhcnQgPSAwLAoJCS5lbmQgPSAwLAoJCS5mbGFncyA9IElPUkVTT1VSQ0VfSVJRLAoJfQp9OwoKc3RhdGljIHN0cnVjdCBwbGF0Zm9ybV9kZXZpY2UgbW9jYV9sYW5fcGxhdF9kZXYgPSB7CgkubmFtZSA9ICJibW9jYSIsCgkuaWQgPSAwLAoJLm51bV9yZXNvdXJjZXMgPSBBUlJBWV9TSVpFKG1vY2FfbGFuX3Jlc291cmNlcyksCgkucmVzb3VyY2UgPSBtb2NhX2xhbl9yZXNvdXJjZXMsCgkuZGV2ID0gewoJCS5wbGF0Zm9ybV9kYXRhID0gJm1vY2FfbGFuX2RhdGEsCgkJLnJlbGVhc2UgPSBib2d1c19yZWxlYXNlLAoJfSwKfTsKCnN0YXRpYyBzdHJ1Y3QgbW9jYV9wbGF0Zm9ybV9kYXRhIG1vY2Ffd2FuX2RhdGEgPSB7CgkubWFjYWRkcl9oaSAgICAgICA9IDB4MDAwMDAxMDIsCgkubWFjYWRkcl9sbyAgICAgICA9IDB4MDMwNDAwMDAsCgoJLmJjbTM0NTBfaTJjX2Jhc2UgPSAgMHgxMDQwNjIwMCwKCS5iY20zNDUwX2kyY19hZGRyID0gIDB4NzAsCgkuaHdfcmV2ICA9IEhXUkVWX01PQ0FfMjBfR0VOMjIsCgkuY2hpcF9pZCA9IDAsCgkKCS5yZl9iYW5kID0gTU9DQV9CQU5EX0VYVF9ELAoKCS51c2VfZG1hICAgICAgICAgICA9IDAsCgkudXNlX3NwaSAgICAgICAgICAgPSAxLAoJLmRldklkICAgICAgICAgICAgPSBNT0NBX0RFVklDRV9JRF9VTlJFR0lTVEVSRUQsIC8vIEZpbGxlZCBpbiBkeW5hbWljYWxseQoKI2lmZGVmIENPTkZJR19TTVAKCS5zbXBfcHJvY2Vzc29yX2lkID0gMSwKI2VuZGlmCn07CgpzdGF0aWMgc3RydWN0IHJlc291cmNlIG1vY2Ffd2FuX3Jlc291cmNlc1tdID0gewoJWzBdID0gewoJCS5zdGFydCA9IDB4MTA2MDAwMDAsCgkJLmVuZCA9ICAgMHgxMDdmZmQ5NywKCQkuZmxhZ3MgPSBJT1JFU09VUkNFX01FTSwKCX0sCglbMV0gPSB7IC8qIE5vdCB1c2VkIGZvciA2ODAyLCBkZWZpbmUgZm9yIGJtb2NhICovCgkJLnN0YXJ0ID0gMCwKCQkuZW5kID0gMCwKCQkuZmxhZ3MgPSBJT1JFU09VUkNFX0lSUSwKCX0KfTsKCnN0YXRpYyBzdHJ1Y3QgcGxhdGZvcm1fZGV2aWNlIG1vY2Ffd2FuX3BsYXRfZGV2ID0gewoJLm5hbWUgICAgICAgICAgPSAiYm1vY2EiLAoJLmlkICAgICAgICAgICAgPSAxLAoJLm51bV9yZXNvdXJjZXMgPSBBUlJBWV9TSVpFKG1vY2Ffd2FuX3Jlc291cmNlcyksCgkucmVzb3VyY2UgICAgICA9IG1vY2Ffd2FuX3Jlc291cmNlcywKCS5kZXYgICAgICAgICAgID0gewoJCS5wbGF0Zm9ybV9kYXRhID0gJm1vY2Ffd2FuX2RhdGEsCgkJLnJlbGVhc2UgICAgICAgPSBib2d1c19yZWxlYXNlLAoJfSwKfTsKCi8qIE1vQ0EgQ2xvY2sgRnVuY3Rpb25zICovCnN0cnVjdCBjbGsgKm1vY2FfY2xrX2dldChzdHJ1Y3QgZGV2aWNlICpkZXYsIGNvbnN0IGNoYXIgKmlkKQp7CgkvLyBXZSdyZSBub3QgYWN0dWFsbHkgdXNpbmcgdGhlICJzdHJ1Y3QgY2xrIiBmb3IgYW55dGhpbmcKCS8vIFdlJ2xsIHVzZSBvdXIgb3duIHN0cnVjdHVyZQoJc3RydWN0IG1vY2FfNjgweF9jbGsgKiBwY2xrID0ga3phbGxvYyhzaXplb2Yoc3RydWN0IG1vY2FfNjgweF9jbGspLCBHRlBfS0VSTkVMKTsKCglwY2xrLT5kZXYgPSBkZXY7CgoJaWYgKCFzdHJjbXAoaWQsICJtb2NhLWNwdSIpKQoJCXBjbGstPmNsb2NrX251bSA9IE1PQ0FfQ1BVX0NMT0NLX05VTTsKCWVsc2UgaWYgKCFzdHJjbXAoaWQsICJtb2NhLXBoeSIpKQoJCXBjbGstPmNsb2NrX251bSA9IE1PQ0FfUEhZX0NMT0NLX05VTTsKCWVsc2UKCXsKCQlrZnJlZShwY2xrKTsKCQlyZXR1cm4oTlVMTCk7Cgl9CgoJcmV0dXJuKChzdHJ1Y3QgY2xrICopcGNsayk7Cn0KCmludCBtb2NhX2Nsa19lbmFibGUoc3RydWN0IGNsayAqY2xrKQp7CglyZXR1cm4gMDsKfQoKdm9pZCBtb2NhX2Nsa19kaXNhYmxlKHN0cnVjdCBjbGsgKmNsaykKewp9Cgp2b2lkIG1vY2FfY2xrX3B1dChzdHJ1Y3QgY2xrICpjbGspCnsKCWtmcmVlKChzdHJ1Y3QgbW9jYV82ODB4X2NsayAqKWNsayk7Cn0KCnN0cnVjdCBtb2NhXzY4MDJjMF9jbG9ja19wYXJhbXMKewoJdWludDMyX3QgICAgICAgIGNwdV9oejsKCXVpbnQzMl90ICAgICAgICBwZGl2OwoJdWludDMyX3QgICAgICAgIG5kaXY7Cgl1aW50MzJfdCAgICAgICAgcGxsX21kaXZzWzZdOwp9OwoKI2RlZmluZSBOVU1fNjgwMkMwX0NMT0NLX09QVElPTlMgMgpzdHJ1Y3QgbW9jYV82ODAyYzBfY2xvY2tfcGFyYW1zIG1vY2FfNjgwMmMwX2Nsb2NrX3BhcmFtc1tOVU1fNjgwMkMwX0NMT0NLX09QVElPTlNdID0KewoJeyAgLy8gVkNPIG9mIDIyMDAsIGRlZmF1bHQKCQk0NDAwMDAwMDAsICAgICAgICAgICAgIC8vIGNwdV9oegoJCTEsICAgICAgICAgICAgICAgICAgICAgLy8gcGRpdgoJCTQ0LCAgICAgICAgICAgICAgICAgICAgLy8gbmRpdgoJCXs1LCAyMiwgNywgNywgNDQsIDQ0fSAgLy8gcGxsX21kaXZzWzZdCgl9LAoJeyAgLy8gVkNPIG9mIDI0MDAKCQk0MDAwMDAwMDAsICAgICAgICAgICAgIC8vIGNwdV9oegoJCTEsICAgICAgICAgICAgICAgICAgICAgLy8gcGRpdgoJCTQ4LCAgICAgICAgICAgICAgICAgICAgLy8gbmRpdgoJCXs2LCAyNCwgOCwgOCwgNDgsIDQ4fSAgLy8gcGxsX21kaXZzWzZdCgl9LAp9OwoKaW50IG1vY2FfY2xrX3NldF9yYXRlKHN0cnVjdCBjbGsgKmNsaywgdW5zaWduZWQgbG9uZyByYXRlKQp7CgkvLyBUaGUgTU9DQV9SRC9NT0NBX1dSIG1hY3JvcyBuZWVkIGEgdmFsaWQgJ3ByaXYtPnBkZXYtPmRldicKCXN0YXRpYyBzdHJ1Y3QgbW9jYV9wcml2X2RhdGEgZHVtbXlfcHJpdjsgCglzdGF0aWMgc3RydWN0IHBsYXRmb3JtX2RldmljZSBkdW1teV9wZDsKCXN0cnVjdCBtb2NhX3ByaXZfZGF0YSAqcHJpdiA9ICZkdW1teV9wcml2OwoJc3RydWN0IG1vY2FfNjgweF9jbGsgKiBwY2xrID0gKHN0cnVjdCBtb2NhXzY4MHhfY2xrICopIGNsazsKCXN0cnVjdCBtb2NhX3BsYXRmb3JtX2RhdGEgKiBwTW9jYURhdGEgPSAoc3RydWN0IG1vY2FfcGxhdGZvcm1fZGF0YSAqKXBjbGstPmRldi0+cGxhdGZvcm1fZGF0YTsKCXN0cnVjdCBtb2NhXzY4MDJjMF9jbG9ja19wYXJhbXMgKiBwX2Nsb2NrX2RhdGEgPSAmbW9jYV82ODAyYzBfY2xvY2tfcGFyYW1zWzBdOwoJdWludDMyX3QgaTsKCXVpbnQzMl90IGFkZHI7Cgl1aW50MzJfdCBkYXRhOwoJaW50IHJldCA9IC0xOwoKCXByaXYtPnBkZXYgPSAmZHVtbXlfcGQ7Cglwcml2LT5wZGV2LT5kZXYgPSAqcGNsay0+ZGV2OwoKCWlmIChwY2xrLT5jbG9ja19udW0gPT0gTU9DQV9DUFVfQ0xPQ0tfTlVNKQoJewoJCWlmICgocE1vY2FEYXRhLT5jaGlwX2lkICYgMHhGRkZGRkZGMCkgPT0gMHg2ODAyMDBDMCkKCQl7CgkJCWlmIChyYXRlID09IDApCgkJCXsKCQkJCXJhdGUgPSA0NDAwMDAwMDA7CgkJCX0KCQkJCgkJCWZvciAoaSA9IDA7IGkgPCBOVU1fNjgwMkMwX0NMT0NLX09QVElPTlM7IGkrKykKCQkJewoJCQkJaWYgKG1vY2FfNjgwMmMwX2Nsb2NrX3BhcmFtc1tpXS5jcHVfaHogPT0gcmF0ZSkKCQkJCXsKCQkJCQlwX2Nsb2NrX2RhdGEgPSAmbW9jYV82ODAyYzBfY2xvY2tfcGFyYW1zW2ldOwoJCQkJCXJldCA9IDA7CgkJCQl9CgkJCX0KCgkJCS8vIDEuIFNldCBQT1NUX0RJVklERVJfSE9MRF9DSHggKGJpdCBbMTJdIGluIGVhY2ggUExMX0NIQU5ORUxfQ1RSTF9DSF94IAoJCQkvLyAgICByZWdpc3RlcikgIC8vIHRoaXMgd2lsbCB6ZXJvIHRoZSBvdXRwdXQgY2hhbm5lbHMKCQkJZm9yIChhZGRyID0gMHgxMDEwMDAzYzsgYWRkciA8PSAweDEwMTAwMDUwOyBhZGRyICs9IDQpCgkJCXsKCQkJCU1PQ0FfU0VUKGFkZHIsICgxIDw8IDEyKSk7CgkJCX0KCgkJCS8vMi4gUHJvZ3JhbSBuZXcgUERJVi9ORElWIHZhbHVlLCB0aGlzIHdpbGwgbG9zZSBsb2NrIGFuZCAKCQkJLy8gICB0cmlnZ2VyIGEgbmV3IFBMTCBsb2NrIHByb2Nlc3MgZm9yIGEgbmV3IFZDTyBmcmVxdWVuY3kKCQkJTU9DQV9XUigweDEwMTAwMDU4LCAoKHBfY2xvY2tfZGF0YS0+cGRpdiA8PCAxMCkgfCBwX2Nsb2NrX2RhdGEtPm5kaXYpKTsKCgkJCS8vMy4gV2FpdCA+MTAgdXNlYyBmb3IgbG9jayB0aW1lIC8vIG1heCBsb2NrIHRpbWUgcGVyIGRhdGEgc2hlZXQgaXMgNDYwL0ZyZWYsIAoJCQkvLyAgIE9yIGFsdGVybmF0aXZlbHkgbW9uaXRvciBDTEtHRU5fUExMX1NZUypfUExMX0xPQ0tfU1RBVFVTIHRvIGNoZWNrIGlmIFBMTCBoYXMgbG9ja2VkCgkJCWRhdGEgPSAwOwoJCQlpID0gMDsKCQkJd2hpbGUgKChkYXRhICYgMHgxKSA9PSAwKQoJCQl7CgkJCQkvKiBUaGlzIHR5cGljYWxseSBpcyBvbmx5IHJlYWQgb25jZSAqLwoJCQkJZGF0YSA9IE1PQ0FfUkQoMHgxMDEwMDA2MCk7IC8vIENMS0dFTl9QTExfU1lTMV9QTExfTE9DS19TVEFUVVMKCgkJCQlpZiAoaSsrID4gMTApCgkJCQl7CgkJCQkJcHJpbnRrKCJNb0NBIFNZUzEgUExMIE5PVCBMT0NLRUQhXG4iKTsKCQkJCQlicmVhazsKCQkJCX0KCQkJfQoKCQkJLy80LiBDb25maWd1cmUgbmV3IE1ESVYgdmFsdWUgYWxvbmcgd2l0aCBzZXQgUE9TVF9ESVZJREVSX0xPQURfRU5fQ0h4IAoJCQkvLyAgIChiaXQgWzEzXT0xLCB3aGlsZSBrZWVwIGJpdFsxMl09MSkgaW4gZWFjaCBQTExfQ0hBTk5FTF9DVFJMX0NIX3ggcmVnaXN0ZXIKCQkJaSA9IDA7CgkJCWZvciAoYWRkciA9IDB4MTAxMDAwM2M7IGFkZHIgPD0gMHgxMDEwMDA1MDsgYWRkciArPSA0KQoJCQl7CgkJCQlkYXRhID0gTU9DQV9SRChhZGRyKTsKCQkJCWRhdGEgfD0gKDEgPDwgMTMpOwoJCQkJZGF0YSAmPSB+KDB4RkYgPDwgMSk7CgkJCQlkYXRhIHw9IChwX2Nsb2NrX2RhdGEtPnBsbF9tZGl2c1tpXSA8PCAxKTsKCQkJCU1PQ0FfV1IoYWRkciwgZGF0YSk7CgkJCQlpKys7CgkJCX0KCgkJCS8vNS4gQ2xlYXIgYml0cyBbMTJdIGFuZCBiaXQgWzEzXSBpbiBlYWNoIFBMTF9DSEFOTkVMX0NUUkxfQ0hfeAoJCQlmb3IgKGFkZHIgPSAweDEwMTAwMDNjOyBhZGRyIDw9IDB4MTAxMDAwNTA7IGFkZHIgKz0gNCkKCQkJewoJCQkJTU9DQV9VTlNFVChhZGRyLCAoKDEgPDwgMTMpIHwgKDEgPDwgMTIpKSk7CgkJCX0KCgkJfQoJfQoKCXJldHVybihyZXQpOwp9CgpzdGF0aWMgdm9pZCBtb2NhX2VuYWJsZV9pcnEoc3RydWN0IG1vY2FfcHJpdl9kYXRhICpwcml2KQp7CglrZXJTeXNNb2NhSG9zdEludHJFbmFibGUoKChzdHJ1Y3QgbW9jYV9wbGF0Zm9ybV9kYXRhICopcHJpdi0+cGRldi0+ZGV2LnBsYXRmb3JtX2RhdGEpLT5zcGkpOwp9CgpzdGF0aWMgdm9pZCBtb2NhX2Rpc2FibGVfaXJxKHN0cnVjdCBtb2NhX3ByaXZfZGF0YSAqcHJpdikKewoJa2VyU3lzTW9jYUhvc3RJbnRyRGlzYWJsZSgoKHN0cnVjdCBtb2NhX3BsYXRmb3JtX2RhdGEgKilwcml2LT5wZGV2LT5kZXYucGxhdGZvcm1fZGF0YSktPnNwaSk7Cn0KCnN0YXRpYyB2b2lkIG1vY2FfcG1iX2J1c3lfd2FpdChzdHJ1Y3QgbW9jYV9wcml2X2RhdGEgKnByaXYpCnsKCSNpZiAwCgl1aW50MzJfdCBkYXRhOwoKCS8qIFBvc3NpYmxlIHRpbWUgc2F2ZXI6IFRoZSByZWdpc3RlciBhY2Nlc3MgdGltZSBvdmVyIFNQSSBtYXkgCgkgICBhbHdheXMgYmUgZW5vdWdoIHRvIGd1YXJhbnRlZSB0aGF0IHRoZSB3cml0ZSB3aWxsIGNvbXBsZXRlIAoJICAgaW4gdGltZSB3aXRob3V0IGhhdmluZyB0byBjaGVjayB0aGUgc3RhdHVzLiAqLwoJZG8KCXsKCQlkYXRhID0gTU9DQV9SRChwcml2LT5iYXNlICsgcHJpdi0+cmVncy0+cG1iX21hc3Rlcl9zdGF0dXMpOwoJfSB3aGlsZSAoZGF0YSAmIDB4MSk7CgkjZW5kaWYKfQoKdm9pZCBtb2NhX3BtYl9kZWxheShzdHJ1Y3QgbW9jYV9wcml2X2RhdGEgKnByaXYpCnsKCXVuc2lnbmVkIGludCBkYXRhOwoJaW50IGksIGo7CgkKCU1PQ0FfV1IocHJpdi0+YmFzZSArIHByaXYtPnJlZ3MtPnBtYl9tYXN0ZXJfd2RhdGFfb2Zmc2V0LCAweEZGNDQ0MDAwKTsKCQoJZm9yIChpID0gMDsgaSA8IE1PQ0FfQlBDTV9OVU07IGkrKykKCXsKCQlmb3IgKGogPSAwOyBqIDwgTU9DQV9CUENNX1pPTkVTX05VTTsgaisrKQoJCXsKCQkJZGF0YSA9IDB4MTAwMDEyICsgaio0ICsgaSoweDEwMDA7IDsKCQkJTU9DQV9XUihwcml2LT5iYXNlICsgcHJpdi0+cmVncy0+cG1iX21hc3Rlcl9jbWRfb2Zmc2V0LCBkYXRhKTsKCQkJbW9jYV9wbWJfYnVzeV93YWl0KHByaXYpOwoJCX0KCX0KfQoKc3RhdGljIHZvaWQgbW9jYV9wbWJfY29udHJvbChzdHJ1Y3QgbW9jYV9wcml2X2RhdGEgKnByaXYsIFBNQl9DT01NQU5EX0UgY21kKQp7CglpbnQgaSwgajsKCXVpbnQzMl90ICogcF96b25lX2NvbnRyb2w7Cgl1aW50MzJfdCBkYXRhOwoKCXN3aXRjaCAoY21kKQoJewoJCWNhc2UgUE1CX0NPTU1BTkRfQUxMX09GRjoKCQkJLy8gVHVybiBvZmYgem9uZSBjb21tYW5kCgkJCU1PQ0FfV1IocHJpdi0+YmFzZSArIHByaXYtPnJlZ3MtPnBtYl9tYXN0ZXJfd2RhdGFfb2Zmc2V0LCAweEEwMCk7CgkJCXBfem9uZV9jb250cm9sID0gJnpvbmVfYWxsX29mZl9iaXRtYXNrWzBdOwoJCQlicmVhazsKCgkJY2FzZSBQTUJfQ09NTUFORF9QSFkxX09GRjoKCQkJLy8gVHVybiBvZmYgem9uZSBjb21tYW5kCgkJCU1PQ0FfV1IocHJpdi0+YmFzZSArIHByaXYtPnJlZ3MtPnBtYl9tYXN0ZXJfd2RhdGFfb2Zmc2V0LCAweEEwMCk7CgkJCXBfem9uZV9jb250cm9sID0gJnpvbmVfcGh5MV9iaXRtYXNrWzBdOwoJCQlicmVhazsKCQkgCgkgY2FzZSBQTUJfQ09NTUFORF9QSFkxX09OOgoJCQkvLyBUdXJuIG9uIHpvbmUgY29tbWFuZAoJCQlNT0NBX1dSKHByaXYtPmJhc2UgKyBwcml2LT5yZWdzLT5wbWJfbWFzdGVyX3dkYXRhX29mZnNldCwgMHhDMDApOwoJCQlwX3pvbmVfY29udHJvbCA9ICZ6b25lX3BoeTFfYml0bWFza1swXTsKCQkJYnJlYWs7CgkJIAoJIGNhc2UgUE1CX0NPTU1BTkRfUEFSVElBTF9PTjoKCQkJLy8gVHVybiBvbiB6b25lIGNvbW1hbmQKCQkJTU9DQV9XUihwcml2LT5iYXNlICsgcHJpdi0+cmVncy0+cG1iX21hc3Rlcl93ZGF0YV9vZmZzZXQsIDB4QzAwKTsKCQkJcF96b25lX2NvbnRyb2wgPSAmem9uZV9wYXJ0aWFsX29uX2JpdG1hc2tbMF07CgkJCWJyZWFrOwoJCSAKCQkgCgkJZGVmYXVsdDoKCQkJcHJpbnRrKEtFUk5fV0FSTklORyAiJXM6IGlsbGVnYWwgY21kOiAlMDh4XG4iLAoJCQkJX19GVU5DVElPTl9fLCBjbWQpOwoJCQlyZXR1cm47Cgl9CgoJZm9yIChpID0gMDsgaSA8IE1PQ0FfQlBDTV9OVU07IGkrKykKCXsKCQlmb3IgKGogPSAwOyBqIDwgTU9DQV9CUENNX1pPTkVTX05VTTsgaisrKQoJCXsKCQkJaWYgKCpwX3pvbmVfY29udHJvbCAmICgxIDw8IGopKQoJCQl7CgkJCQkvLyB6b25lIGFkZHJlc3MgaW4gYnBjbXMKCQkJCWRhdGEgPSAoMHgxIDw8IDIwKSArIDE2ICsgKGkgKiA0MDk2KSArIChqICogNCk7CgkJCQlNT0NBX1dSKHByaXYtPmJhc2UgKyBwcml2LT5yZWdzLT5wbWJfbWFzdGVyX2NtZF9vZmZzZXQsIGRhdGEpOwoJCQkJbW9jYV9wbWJfYnVzeV93YWl0KHByaXYpOwoJCQl9CgkJfQoJCXBfem9uZV9jb250cm9sKys7Cgl9Cgp9CgpzdGF0aWMgdm9pZCBtb2NhX3BtYl9naXZlX2NudHJsKHN0cnVjdCBtb2NhX3ByaXZfZGF0YSAqcHJpdiwgUE1CX0dJVkVfT1dORVJTSElQX0UgY21kKQp7CglpbnQgaTsKCXVpbnQzMl90IGRhdGE7CgoJLyogUGFzcyBjb250cm9sIG92ZXIgdGhlIG1lbW9yaWVzIHRvIHRoZSBGVyAqLwoJTU9DQV9XUihwcml2LT5iYXNlICsgcHJpdi0+cmVncy0+cG1iX21hc3Rlcl93ZGF0YV9vZmZzZXQsIGNtZCk7Cglmb3IgKGkgPSAwOyBpIDwgMzsgaSsrKQoJewoJCWRhdGEgPSAweDEwMDAwMiArIGkqMHgxMDAwOwoJCU1PQ0FfV1IocHJpdi0+YmFzZSArIHByaXYtPnJlZ3MtPnBtYl9tYXN0ZXJfY21kX29mZnNldCwgZGF0YSk7ICAgCgkJbW9jYV9wbWJfYnVzeV93YWl0KHByaXYpOwoJfQoJbW9jYV9wbWJfYnVzeV93YWl0KHByaXYpOwp9CgpzdGF0aWMgdm9pZCBtb2NhX2h3X3Jlc2V0KHN0cnVjdCBtb2NhX3ByaXZfZGF0YSAqcHJpdikKewovLwl1bnNpZ25lZCBsb25nIGZsYWdzOwovLyAgIHVpbnQzMl90IGNoaXBpZDsKICAKCgkvKiBkaXNhYmxlIGFuZCBjbGVhciBhbGwgaW50ZXJydXB0cyAqLwoJTU9DQV9XUihwcml2LT5iYXNlICsgcHJpdi0+cmVncy0+bDJfbWFza19zZXRfb2Zmc2V0LCAweGZmZmZmZmZmKTsKCU1PQ0FfUkQocHJpdi0+YmFzZSArIHByaXYtPnJlZ3MtPmwyX21hc2tfc2V0X29mZnNldCk7CgoJLyogYXNzZXJ0IHJlc2V0cyAqLwoKCS8qIHJlc2V0IENQVSBmaXJzdCwgYm90aCBDUFVzIGZvciBNb0NBIDIwIEhXICovCglpZiAocHJpdi0+aHdfcmV2ID09IEhXUkVWX01PQ0FfMjBfR0VOMjIpCgkJTU9DQV9TRVQocHJpdi0+YmFzZSArIHByaXYtPnJlZ3MtPnN3X3Jlc2V0X29mZnNldCwgNSk7CgllbHNlCgkJTU9DQV9TRVQocHJpdi0+YmFzZSArIHByaXYtPnJlZ3MtPnN3X3Jlc2V0X29mZnNldCwgMSk7CgoJTU9DQV9SRChwcml2LT5iYXNlICsgcHJpdi0+cmVncy0+c3dfcmVzZXRfb2Zmc2V0KTsKCgl1ZGVsYXkoMjApOwoKCS8qIHJlc2V0IGV2ZXJ5dGhpbmcgZWxzZSBleGNlcHQgY2xvY2tzICovCglNT0NBX1NFVChwcml2LT5iYXNlICsgcHJpdi0+cmVncy0+c3dfcmVzZXRfb2Zmc2V0LCAKCQl+KCgxIDw8IDMpIHwgKDEgPDwgNykgfCAoMSA8PCAxNSkgfCAoMSA8PCAxNikpKTsKCU1PQ0FfUkQocHJpdi0+YmFzZSArIHByaXYtPnJlZ3MtPnN3X3Jlc2V0X29mZnNldCk7CgoJdWRlbGF5KDIwKTsKCgkvKiBkaXNhYmxlIGNsb2NrcyAqLwoJTU9DQV9TRVQocHJpdi0+YmFzZSArIHByaXYtPnJlZ3MtPnN3X3Jlc2V0X29mZnNldCwgCgkJfigoMSA8PCAzKSB8ICgxIDw8IDE1KSB8ICgxIDw8IDE2KSkpOwoJTU9DQV9SRChwcml2LT5iYXNlICsgcHJpdi0+cmVncy0+c3dfcmVzZXRfb2Zmc2V0KTsKCglNT0NBX1dSKHByaXYtPmJhc2UgKyBwcml2LT5yZWdzLT5sMl9jbGVhcl9vZmZzZXQsIDB4ZmZmZmZmZmYpOwoJTU9DQV9SRChwcml2LT5iYXNlICsgcHJpdi0+cmVncy0+bDJfY2xlYXJfb2Zmc2V0KTsKCgkvKiBQb3dlciBkb3duIGFsbCB6b25lcyAqLwoJLy8gIFRoZSBob3N0IGNhbid0IGdpdmUgdG8gaXRzZWxmIHBlcm1pc3Npb24uCgltb2NhX3BtYl9jb250cm9sKHByaXYsIFBNQl9DT01NQU5EX0FMTF9PRkYpOwoKCS8qIFBvd2VyIGRvd24gYWxsIFNZU19DVFJMIG1lbW9yaWVzICovCglNT0NBX1dSKDB4MTAxMDAwNjgsIDEpOyAgIC8vIENMS0dFTl9QTExfU1lTMV9QTExfUFdSRE4KCU1PQ0FfU0VUKDB4MTAxMDAwMGMsIDEpOyAgLy8gQ0xLR0VOX1BMTF9TWVMwX1BMTF9DSEFOTkVMX0NUUkxfQ0hfMwoKfQoKc3RhdGljIHVuc2lnbmVkIGludCBtb2NhX2dldF9waHlfZnJlcShzdHJ1Y3QgbW9jYV9wcml2X2RhdGEgKnByaXYpCnsKCXVuc2lnbmVkIGludCB4ID0gTU9DQV9SRCgweDEwMTAwMDQ0KTsgLy8gQ0xLR0VOX1BMTF9TWVMxX1BMTF9DSEFOTkVMX0NUUkxfQ0hfMgoKCXggPSAoeCA+PiAxKSAmIDB4RkY7IC8vIEdldCB0aGUgTURJVl9DSDIgZmllbGQKCglpZiAoIXgpCgkJcmV0dXJuIDA7CgoJcmV0dXJuKDI0MDAgLyB4KTsgCn0KCgpzdGF0aWMgdm9pZCBtb2NhX3BzX1Bvd2VyQ3RybFBIWTEoc3RydWN0IG1vY2FfcHJpdl9kYXRhICpwcml2LCAgUE1CX0NPTU1BTkRfRSBjbWQpCnsKCXVpbnQzMl90IHBsbF9jdHJsXzMsIHBsbF9jdHJsXzUsIHN3X3Jlc2V0OyAKCXBsbF9jdHJsXzMgPSBNT0NBX1JEICgweDEwMTAwMDQ4KTsKCXBsbF9jdHJsXzUgPSBNT0NBX1JEICgweDEwMTAwMDUwKTsKCXN3X3Jlc2V0ID0gTU9DQV9SRCAocHJpdi0+YmFzZSArIHByaXYtPnJlZ3MtPnN3X3Jlc2V0X29mZnNldCk7CgoJLy8gZW5hYmxlIFBMTCAKCU1PQ0FfVU5TRVQoMHgxMDEwMDA0OCwgMSk7ICAvLyBDTEtHRU5fUExMX1NZUzFfUExMX0NIQU5ORUxfQ1RSTF9DSF8zIAoJTU9DQV9VTlNFVCgweDEwMTAwMDUwLCAxKTsgIC8vIENMS0dFTl9QTExfU1lTMV9QTExfQ0hBTk5FTF9DVFJMX0NIXzUgCgoJdWRlbGF5KDEpOwoKCS8vIGRlIGFzc2VydCBtb2NhX3BoeTFfZGlzYWJsZV9jbGsKCU1PQ0FfVU5TRVQocHJpdi0+YmFzZSArIHByaXYtPnJlZ3MtPnN3X3Jlc2V0X29mZnNldCwgKDEgPDwgOSkpOwoKCW1vY2FfcG1iX2NvbnRyb2wocHJpdiwgY21kKTsKCglNT0NBX1dSICgweDEwMTAwMDQ4LCBwbGxfY3RybF8zKTsKCU1PQ0FfV1IgKDB4MTAxMDAwNTAsIHBsbF9jdHJsXzUpOwoKCXVkZWxheSgxKTsKCQoJTU9DQV9XUiAocHJpdi0+YmFzZSArIHByaXYtPnJlZ3MtPnN3X3Jlc2V0X29mZnNldCwgc3dfcmVzZXQpOwkKfQoKCnN0YXRpYyB2b2lkIG1vY2FfZ3BoeV9pbml0KHN0cnVjdCBtb2NhX3ByaXZfZGF0YSAqcHJpdikKewoJc3RydWN0IG1vY2FfcGxhdGZvcm1fZGF0YSAqIHBNb2NhRGF0YSA9IChzdHJ1Y3QgbW9jYV9wbGF0Zm9ybV9kYXRhICopcHJpdi0+cGRldi0+ZGV2LnBsYXRmb3JtX2RhdGE7Cgl1MzIgcG9ydF9tb2RlOwoJdTMyIHJnbWlpMF9vbjsKCXUzMiByZ21paTFfb247Cgl1MzIgZ3BoeV9lbmFibGVkID0gMDsKCglwb3J0X21vZGUgPSBNT0NBX1JEKDB4MTA4MDAwMDApICYgMHgzOwoJcmdtaWkwX29uID0gTU9DQV9SRCgweDEwODAwMDBjKSAmIDB4MTsKCXJnbWlpMV9vbiA9IE1PQ0FfUkQoMHgxMDgwMDAxOCkgJiAweDE7CgoJaWYgKChwTW9jYURhdGEtPmNoaXBfaWQgJiAweEZGRkVGRkYwKSA9PSAweDY4MDIwMEMwKQoJewoJCWlmICgocG9ydF9tb2RlID09IDApIHx8CgkJICAgICgocG9ydF9tb2RlID09IDEpICYmIHJnbWlpMF9vbikgfHwKCQkgICAgKChwb3J0X21vZGUgPT0gMikgJiYgcmdtaWkxX29uKSkKCQl7CgkJCWdwaHlfZW5hYmxlZCA9IDE7CgkJfQoJfQoJZWxzZQoJewoJCWlmICgocG9ydF9tb2RlID09IDApIHx8CgkJICAgICgocG9ydF9tb2RlICE9IDMpICYmIHJnbWlpMV9vbikpCgkJewoJCQlncGh5X2VuYWJsZWQgPSAxOwoJCX0KCX0KCglpZiAoZ3BoeV9lbmFibGVkKQoJewoJCU1PQ0FfVU5TRVQoMHgxMDgwMDAwNCwgMHhGKTsKCQltc2xlZXAoMTApOwoJCU1PQ0FfV1IoMHgxMDQwNDMxYywgMHhGRkZGRkZGRik7Cgl9Cn0KCi8qIGNhbGxlZCBhbnkgdGltZSB3ZSBzdGFydC9yZXN0YXJ0L3N0b3AgTW9DQSAqLwpzdGF0aWMgdm9pZCBtb2NhX2h3X2luaXQoc3RydWN0IG1vY2FfcHJpdl9kYXRhICpwcml2LCBpbnQgYWN0aW9uKQp7Cgl1MzIgbWFzazsKCXUzMiB0ZW1wOwoJdTMyIGRhdGE7Cgl1MzIgY291bnQgPSAwOwoJc3RydWN0IG1vY2FfcGxhdGZvcm1fZGF0YSAqIHBNb2NhRGF0YSA9IChzdHJ1Y3QgbW9jYV9wbGF0Zm9ybV9kYXRhICopcHJpdi0+cGRldi0+ZGV2LnBsYXRmb3JtX2RhdGE7CgoJaWYgKGFjdGlvbiA9PSBNT0NBX0VOQUJMRSAmJiAhcHJpdi0+ZW5hYmxlZCkgewoJCW1vY2FfY2xrX2VuYWJsZShwcml2LT5jbGspOwoKCQlNT0NBX1dSKDB4MTA0MDQzMWMsIH4oMSA8PCAyNikpOyAvLyBTVU5fVE9QX0NUUkxfU1dfSU5JVF8wX0NMRUFSIC0tPiBEbyB0aGlzIGF0IHN0YXJ0IG9mIHNlcXVlbmNlLCBkb24ndCB0b3VjaCBncGh5X3N3X2luaXQKCQl1ZGVsYXkoMjApOwoJCW1vY2FfZ3BoeV9pbml0KHByaXYpOwogICAKCQlwcml2LT5lbmFibGVkID0gMTsKCX0KCgkvKiBjbG9jayBub3QgZW5hYmxlZCwgcmVnaXN0ZXIgYWNjZXNzZXMgd2lsbCBmYWlsIHdpdGggYnVzIGVycm9yICovCglpZiAoIXByaXYtPmVuYWJsZWQpCgkJcmV0dXJuOwoKCW1vY2FfaHdfcmVzZXQocHJpdik7Cgl1ZGVsYXkoMSk7CgoJaWYgKGFjdGlvbiA9PSBNT0NBX0VOQUJMRSkgewoKCQkvKiBQb3dlciB1cCBhbGwgem9uZXMgKi8KCQltb2NhX3BtYl9jb250cm9sKHByaXYsIFBNQl9DT01NQU5EX1BBUlRJQUxfT04pOwoKCQlNT0NBX1VOU0VUKDB4MTAxMDAwMGMsIDEpOyAgLy8gQ0xLR0VOX1BMTF9TWVMwX1BMTF9DSEFOTkVMX0NUUkxfQ0hfMyAKCgkJTU9DQV9XUigweDEwMTAwMDZDLCAxKTsgIC8vIENMS0dFTl9QTExfU1lTMV9QTExfUkVTRVQgCgkJTU9DQV9XUigweDEwMTAwMDY4LCAwKTsgIC8vIENMS0dFTl9QTExfU1lTMV9QTExfUFdSRE4gCgkJZGF0YSA9IDA7CgkJd2hpbGUgKChkYXRhICYgMHgxKSA9PSAwKQoJCXsKCQkJLyogVGhpcyB0eXBpY2FsbHkgaXMgb25seSByZWFkIG9uY2UgKi8KCQkJZGF0YSA9IE1PQ0FfUkQoMHgxMDEwMDA2MCk7IC8vIENMS0dFTl9QTExfU1lTMV9QTExfTE9DS19TVEFUVVMKCgkJCWlmIChjb3VudCsrID4gMTApCgkJCQlicmVhazsKCQl9CgkJTU9DQV9XUigweDEwMTAwMDZDLCAwKTsgIC8vIENMS0dFTl9QTExfU1lTMV9QTExfUkVTRVQgCgoJCWlmIChwcml2LT5ib25kZWRfbW9kZSkgewoJCQlNT0NBX1VOU0VUKDB4MTAxMDAwNDgsIDEpOyAgLy8gQ0xLR0VOX1BMTF9TWVMxX1BMTF9DSEFOTkVMX0NUUkxfQ0hfMyAKCQkJTU9DQV9VTlNFVCgweDEwMTAwMDUwLCAxKTsgIC8vIENMS0dFTl9QTExfU1lTMV9QTExfQ0hBTk5FTF9DVFJMX0NIXzUgCgkJfSBlbHNlIHsKCQkJTU9DQV9TRVQoMHgxMDEwMDA0OCwgMSk7ICAvLyBDTEtHRU5fUExMX1NZUzFfUExMX0NIQU5ORUxfQ1RSTF9DSF8zIAoJCQlNT0NBX1NFVCgweDEwMTAwMDUwLCAxKTsgIC8vIENMS0dFTl9QTExfU1lTMV9QTExfQ0hBTk5FTF9DVFJMX0NIXzUgCgkJfQoJCXVkZWxheSgxKTsKCgkJLyogZGVhc3NlcnQgbW9jYV9zeXNfcmVzZXQsIHN5c3RlbSBjbG9jaywgcGh5MCwgcGh5MCBjbG9jayAqLwoJCW1hc2sgPSAoMSA8PCAxKSB8ICgxIDw8IDcpIHwgKDEgPDwgNCkgfCAoMSA8PCA4KTsKCgkJLyogZGVhc3NlcnQgcGh5MSBhbmQgcGh5MSBjbG9jayBpbiBib25kZWQgbW9kZSAqLwoJCWlmIChwcml2LT5ib25kZWRfbW9kZSkKCQkJbWFzayB8PSAoMSA8PCA1KSB8ICgxIDw8IDkpOwoKCQlNT0NBX1VOU0VUKHByaXYtPmJhc2UgKyBwcml2LT5yZWdzLT5zd19yZXNldF9vZmZzZXQsIG1hc2spOwoJCU1PQ0FfUkQocHJpdi0+YmFzZSArIHByaXYtPnJlZ3MtPnN3X3Jlc2V0X29mZnNldCk7CgkJCiAgICAgICAgLy8gQmVmb3JlIHBvd2VyIG9mZiB0aGUgbWVtb3JpZXMsIG1vY2FfcGh5MV9kaXNhYmxlX2Nsay4gICAgCgkJaWYgKHByaXYtPmJvbmRlZF9tb2RlPT0wKQoJCQltb2NhX3BzX1Bvd2VyQ3RybFBIWTEocHJpdiwgUE1CX0NPTU1BTkRfUEhZMV9PRkYpOwoJCWVsc2UKCQkJbW9jYV9wc19Qb3dlckN0cmxQSFkxKHByaXYsIFBNQl9DT01NQU5EX1BIWTFfT04pOwoKICAgICAgICAKCQltb2NhX3BtYl9naXZlX2NudHJsKHByaXYsIFBNQl9HSVZFX09XTkVSU0hJUF8yX0ZXKTsKCQkJCgkJLyogQ2hlY2sgZm9yIDY4MDIvNjgwMyBBMCBjaGlwIG9ubHkgd2l0aCBYdGFsIG1vZCAqLwoJCWlmICgocE1vY2FEYXRhLT5jaGlwX2lkICYgMHhGRkZFRkZGRikgPT0gMHg2ODAyMDBBMCkKCQl7CgkJCWRhdGEgPSBNT0NBX1JEKDB4MTA0MDQwMWMpOwoJCQlpZiAoKGRhdGEgJiAweDcpID09IDB4MikgewoJCQkJLyogMjVNSHogKi8KCQkJCXByaW50aygiTW9DQSBydW5uaW5nIHdpdGggMjVNSHogWFRBTFxuIik7CgkJCQlNT0NBX1dSKHByaXYtPmJhc2UgKyBwcml2LT5yZWdzLT5ob3N0Mm1vY2FfbW1wX291dGJveF8wX29mZnNldCwgMSk7CgkJCX0gZWxzZSB7CgkJCQlwcmludGsoIk1vQ0EgPT0gNTBNSHogWFRBTFxuIik7CgkJCQkvKiA1ME1IeiBjbG9jayBjaGFuZ2Ugb25seSAqLwoJCQkJTU9DQV9XUihwcml2LT5iYXNlICsgcHJpdi0+cmVncy0+aG9zdDJtb2NhX21tcF9vdXRib3hfMF9vZmZzZXQsIDApOwoJCQkJLy9Ob3RlOiBUaGUgcmUtY29uZmlndXJhdGlvbiBpcyBpbiBORElWX0lOVCwgbm90IFBESVYuCgkJCQkvL2BDTEtHRU5fUkVHX1NUQVJUICsgYENMS0dFTl9QTExfU1lTMV9QTExfRElWICgzMidoMTAxMDAwNTgpIFswOTowMF0gPSAxMJJkNDgKCQkJCXRlbXAgPSBNT0NBX1JEKDB4MTAxMDAwNTgpOwoJCQkJdGVtcCA9ICh0ZW1wICYgMHhGRkZGRkMwMCkgKyA0ODsKCQkJCU1PQ0FfV1IoMHgxMDEwMDA1OCwgdGVtcCk7CgoJCQkJLy9gQ0xLR0VOX1JFR19TVEFSVCArIGBDTEtHRU5fUExMX1NZUzBfUExMX0RJViAoMzInaDEwMTAwMDE4KSBbMDk6MDBdID0gMTCSZDQwCgkJCQl0ZW1wID0gTU9DQV9SRCgweDEwMTAwMDE4KTsKCQkJCXRlbXAgPSAodGVtcCAmIDB4RkZGRkZDMDApICsgNDA7CgkJCQlNT0NBX1dSKDB4MTAxMDAwMTgsIHRlbXApOwoKCQkJCS8vYENMS0dFTl9SRUdfU1RBUlQgKyBgQ0xLR0VOX1BMTF9TWVMxX1BMTF9DSEFOTkVMX0NUUkxfQ0hfNCAoMzInaDEwMTAwMDRDKSBbMDg6MDFdID0gOJJkNDgKCQkJCXRlbXAgPSBNT0NBX1JEKDB4MTAxMDAwNGMpOwoJCQkJdGVtcCA9ICh0ZW1wICYgMHhGRkZGRkUwMSkgKyAoNDggPDwgMSk7CgkJCQlNT0NBX1dSKDB4MTAxMDAwNGMsIHRlbXApOwoKCQkJCS8vYENMS0dFTl9SRUdfU1RBUlQgKyBgQ0xLR0VOX1BMTF9TWVMxX1BMTF9DSEFOTkVMX0NUUkxfQ0hfNSAoMzInaDEwMTAwMDUwKSBbMDg6MDFdID0gOJJkNDgKCQkJCXRlbXAgPSBNT0NBX1JEKDB4MTAxMDAwNTApOwoJCQkJdGVtcCA9ICh0ZW1wICYgMHhGRkZGRkUwMSkgKyAoNDggPDwgMSk7CgkJCQlNT0NBX1dSKDB4MTAxMDAwNTAsIHRlbXApOwoKCQkJCS8vIFRoZW4gUmVzdGFydCB0aGUgUExMLgoKCQkJCS8vYENMS0dFTl9SRUdfU1RBUlQgKyBgQ0xLR0VOX1BMTF9TWVMwX1BMTF9SRVNFVCAoMzInaDEwMTAwMDJDKSBbMF0gPSAxkmIxCgkJCQlNT0NBX1NFVCgweDEwMTAwMDJjLCAxKTsKCQkJCS8vYENMS0dFTl9SRUdfU1RBUlQgKyBgQ0xLR0VOX1BMTF9TWVMxX1BMTF9SRVNFVCAoMzInaDEwMTAwMDZDKSBbMF0gPSAxkmIxCgkJCQlNT0NBX1NFVCgweDEwMTAwMDZjLCAxKTsKCgkJCQl1ZGVsYXkoMSk7CgoJCQkJLy9gQ0xLR0VOX1JFR19TVEFSVCArIGBDTEtHRU5fUExMX1NZUzBfUExMX1JFU0VUICgzMidoMTAxMDAwMkMpIFswXSA9IDGSYjAKCQkJCU1PQ0FfVU5TRVQoMHgxMDEwMDAyYywgMSk7CgkJCQkvL2BDTEtHRU5fUkVHX1NUQVJUICsgYENMS0dFTl9QTExfU1lTMV9QTExfUkVTRVQgKDMyJ2gxMDEwMDA2QykgWzBdID0gMZJiMAoJCQkJTU9DQV9VTlNFVCgweDEwMTAwMDZjLCAxKTsKCQkJfQoJCX0KCgkJLy8gQ0xLR0VOX1BMTF9TWVMxX1BMTF9TU0NfTU9ERV9DT05UUk9MX0hJR0gKCQlkYXRhID0gTU9DQV9SRCgweDEwMTAwMDcwKTsKCQlkYXRhID0gKGRhdGEgJiAweEZGRkYwMDAwKSB8IDB4N2RkOwoJCU1PQ0FfV1IoMHgxMDEwMDA3MCwgZGF0YSk7CgoJCS8vIENMS0dFTl9QTExfU1lTMV9QTExfU1NDX01PREVfQ09OVFJPTF9MT1cKCQlkYXRhID0gTU9DQV9SRCgweDEwMTAwMDc0KTsKCQlkYXRhID0gKGRhdGEgJiAweGZmYzAwMDAwKSB8IDB4M2Q3MTsKCQlNT0NBX1dSKDB4MTAxMDAwNzQsIGRhdGEpOwoKCQkvLyBDTEtHRU5fUExMX1NZUzFfUExMX1NTQ19NT0RFX0NPTlRST0xfTE9XCgkJTU9DQV9TRVQoMHgxMDEwMDA3NCwgKDEgPDwgMjIpKTsKCX0KCgoJaWYgKHByaXYtPmh3X3JldiA8PSBIV1JFVl9NT0NBXzIwX0dFTjIxKSB7CgkvKiBjbGVhciBqdW5rIG91dCBvZiBHUDAvR1AxICovCgkJTU9DQV9XUihwcml2LT5iYXNlICsgcHJpdi0+cmVncy0+Z3AwX29mZnNldCwgMHhmZmZmZmZmZik7CgkJTU9DQV9XUihwcml2LT5iYXNlICsgcHJpdi0+cmVncy0+Z3AxX29mZnNldCwgMHgwKTsKCQkvKiBzZXQgdXAgYWN0aXZpdHkgTEVEIGZvciA1MCUgZHV0eSBjeWNsZSAqLwoJCU1PQ0FfV1IocHJpdi0+YmFzZSArIHByaXYtPnJlZ3MtPmxlZF9jdHJsX29mZnNldCwKCQkJMHg0MDAwNDAwMCk7Cgl9CgoJLyogZW5hYmxlIERNQSBjb21wbGV0aW9uIGludGVycnVwdHMgKi8KCW1hc2sgPSBNMkhfUkVRIHwgTTJIX1JFU1AgfCBNMkhfQVNTRVJUIHwgTTJIX1dEVF9DUFUxIHwKCQlNMkhfTkVYVENIVU5LIHwgTTJIX0RNQTsKCglpZiAocHJpdi0+aHdfcmV2ID49IEhXUkVWX01PQ0FfMjBfR0VOMjEpCgkJbWFzayB8PSBNMkhfV0RUX0NQVTAgfCBNMkhfTkVYVENIVU5LX0NQVTAgfAoJCQlNMkhfUkVRX0NQVTAgfCBNMkhfUkVTUF9DUFUwIHwgTTJIX0FTU0VSVF9DUFUwOwoKCU1PQ0FfV1IocHJpdi0+YmFzZSArIHByaXYtPnJlZ3MtPnJpbmdiZWxsX29mZnNldCwgMCk7CglNT0NBX1dSKHByaXYtPmJhc2UgKyBwcml2LT5yZWdzLT5sMl9tYXNrX2NsZWFyX29mZnNldCwgbWFzayk7CglNT0NBX1JEKHByaXYtPmJhc2UgKyBwcml2LT5yZWdzLT5sMl9tYXNrX2NsZWFyX29mZnNldCk7CgoKCS8qIFNldCBwaW5tdXhpbmcgZm9yIE1vQ0EgaW50ZXJydXB0IGFuZCBmbG93IGNvbnRyb2wgKi8KCU1PQ0FfVU5TRVQoMHgxMDQwNDExMCwgMHhGMDAwMDBGRik7CglNT0NBX1NFVCgweDEwNDA0MTEwLCAweDEwMDAwMDIyKTsKIAoJLyogU2V0IHBpbm11eGluZyBmb3IgTW9DQSBJSUMgY29udHJvbCAqLwoJaWYgKCgocE1vY2FEYXRhLT5jaGlwX2lkICYgMHhGRkZGRkZGMCkgPT0gMHg2ODAyMDBDMCkgfHwgCgkgICAgKChwTW9jYURhdGEtPmNoaXBfaWQgJiAweEZGRkZGRkYwKSA9PSAweDY4MDMwMEMwKSkKCXsKCQlNT0NBX1VOU0VUKDB4MTA0MDQxMDAsIDB4RkYpOyAgLy8gcGluIG11eGluZwoJCU1PQ0FfU0VUKDB4MTA0MDQxMDAsIDB4MjIpOyAgLy8gcGluIG11eGluZwoJfQoKCU1PQ0FfV1IoMHgxMDBiMDMxOCwgMik7CgoJaWYgKGFjdGlvbiA9PSBNT0NBX0RJU0FCTEUgJiYgcHJpdi0+ZW5hYmxlZCkgewoJCXByaXYtPmVuYWJsZWQgPSAwOwoJCW1vY2FfY2xrX2Rpc2FibGUocHJpdi0+Y2xrKTsKCX0KfQoKc3RhdGljIHZvaWQgbW9jYV9yaW5nYmVsbChzdHJ1Y3QgbW9jYV9wcml2X2RhdGEgKnByaXYsIHVpbnQzMl90IG1hc2spCnsKCU1PQ0FfV1IocHJpdi0+YmFzZSArIHByaXYtPnJlZ3MtPnJpbmdiZWxsX29mZnNldCwgbWFzayk7Cn0KCnN0YXRpYyB1aW50MzJfdCBtb2NhX3N0YXJ0X21pcHMoc3RydWN0IG1vY2FfcHJpdl9kYXRhICpwcml2LCB1bnNpZ25lZCBpbnQgY3B1KQp7CglpZiAocHJpdi0+aHdfcmV2ID09IEhXUkVWX01PQ0FfMjBfR0VOMjIpIHsKCQlpZiAoY3B1ID09IDEpCgkJCU1PQ0FfVU5TRVQocHJpdi0+YmFzZSArIHByaXYtPnJlZ3MtPnN3X3Jlc2V0X29mZnNldCwKCQkJCSgxIDw8IDApKTsKCQllbHNlIHsKCQkJbW9jYV9tbXBfaW5pdChwcml2LCAxKTsKCQkJTU9DQV9VTlNFVChwcml2LT5iYXNlICsgcHJpdi0+cmVncy0+c3dfcmVzZXRfb2Zmc2V0LAoJCQkJKDEgPDwgMikpOwoJCX0KCX0gZWxzZQoJCU1PQ0FfVU5TRVQocHJpdi0+YmFzZSArIHByaXYtPnJlZ3MtPnN3X3Jlc2V0X29mZnNldCwgKDEgPDwgMCkpOwoJTU9DQV9SRChwcml2LT5iYXNlICsgcHJpdi0+cmVncy0+c3dfcmVzZXRfb2Zmc2V0KTsKCglyZXR1cm4oMCk7Cn0KCnN0YXRpYyB2b2lkIG1vY2FfbTJtX3hmZXIoc3RydWN0IG1vY2FfcHJpdl9kYXRhICpwcml2LAoJdWludDMyX3QgZHN0LCB1aW50MzJfdCBzcmMsIHVpbnQzMl90IGN0bCkKewoJdWludDMyX3Qgc3RhdHVzOwoKCU1PQ0FfV1IocHJpdi0+YmFzZSArIHByaXYtPnJlZ3MtPm0ybV9zcmNfb2Zmc2V0LCBzcmMpOwoJTU9DQV9XUihwcml2LT5iYXNlICsgcHJpdi0+cmVncy0+bTJtX2RzdF9vZmZzZXQsIGRzdCk7CglNT0NBX1dSKHByaXYtPmJhc2UgKyBwcml2LT5yZWdzLT5tMm1fc3RhdHVzX29mZnNldCwgMCk7CglNT0NBX1JEKHByaXYtPmJhc2UgKyBwcml2LT5yZWdzLT5tMm1fc3RhdHVzX29mZnNldCk7CglNT0NBX1dSKHByaXYtPmJhc2UgKyBwcml2LT5yZWdzLT5tMm1fY21kX29mZnNldCwgY3RsKTsKCglkbyB7CgkJc3RhdHVzID0gTU9DQV9SRChwcml2LT5iYXNlICsgcHJpdi0+cmVncy0+bTJtX3N0YXR1c19vZmZzZXQpOwoJfSB3aGlsZShzdGF0dXMgPT0gMCk7Cgp9CgpzdGF0aWMgdm9pZCBtb2NhX3dyaXRlX21lbShzdHJ1Y3QgbW9jYV9wcml2X2RhdGEgKnByaXYsCgl1aW50MzJfdCBkc3Rfb2Zmc2V0LCB2b2lkICpzcmMsIHVuc2lnbmVkIGludCBsZW4pCnsKCXN0cnVjdCBtb2NhX3BsYXRmb3JtX2RhdGEgKnBkID0gcHJpdi0+cGRldi0+ZGV2LnBsYXRmb3JtX2RhdGE7CgoJaWYoKGRzdF9vZmZzZXQgPj0gcHJpdi0+cmVncy0+Y250bF9tZW1fb2Zmc2V0K3ByaXYtPnJlZ3MtPmNudGxfbWVtX3NpemUpIHx8CgkJKChkc3Rfb2Zmc2V0ICsgbGVuKSA+IHByaXYtPnJlZ3MtPmNudGxfbWVtX29mZnNldCtwcml2LT5yZWdzLT5jbnRsX21lbV9zaXplKSkgewoJCXByaW50ayhLRVJOX1dBUk5JTkcgIiVzOiBjb3B5IHBhc3QgZW5kIG9mIGNudGwgbWVtb3J5OiAlMDh4XG4iLAoJCQlfX0ZVTkNUSU9OX18sIGRzdF9vZmZzZXQpOwoJCXJldHVybjsKCX0KCglpZiAoIDEgPT0gcGQtPnVzZV9kbWEgKQoJewoJCWRtYV9hZGRyX3QgcGE7CgoJCXBhID0gZG1hX21hcF9zaW5nbGUoJnByaXYtPnBkZXYtPmRldiwgc3JjLCBsZW4sIERNQV9UT19ERVZJQ0UpOwoJCW11dGV4X2xvY2soJnByaXYtPmNvcHlfbXV0ZXgpOwoJCW1vY2FfbTJtX3hmZXIocHJpdiwgZHN0X29mZnNldCArIHByaXYtPnJlZ3MtPmRhdGFfbWVtX29mZnNldCwgKHVpbnQzMl90KXBhLCBsZW4gfCBNMk1fV1JJVEUpOwoJCW11dGV4X3VubG9jaygmcHJpdi0+Y29weV9tdXRleCk7CgkJZG1hX3VubWFwX3NpbmdsZSgmcHJpdi0+cGRldi0+ZGV2LCBwYSwgbGVuLCBETUFfVE9fREVWSUNFKTsKCX0KCWVsc2UKCXsKCQl1aW50cHRyX3QgYWRkciA9ICh1aW50cHRyX3QpcHJpdi0+YmFzZSArIHByaXYtPnJlZ3MtPmRhdGFfbWVtX29mZnNldCArIGRzdF9vZmZzZXQ7CgkJdWludDMyX3QgKmRhdGEgPSBzcmM7CgkJaW50IGk7CgoJCW11dGV4X2xvY2soJnByaXYtPmNvcHlfbXV0ZXgpOwoJCWlmICgoKHN0cnVjdCBtb2NhX3BsYXRmb3JtX2RhdGEgKilwcml2LT5wZGV2LT5kZXYucGxhdGZvcm1fZGF0YSktPnVzZV9zcGkgPT0gMSkKCQl7CgkJCXNyYyA9IGRhdGE7CgkJCU1PQ0FfV1JfQkxPQ0soYWRkciwgc3JjLCBsZW4pOwoJCX0KCQllbHNlCgkJewoJCQlmb3IoaSA9IDA7IGkgPCBsZW47IGkgKz0gNCwgYWRkciArPSA0LCBkYXRhKyspCgkJCQlNT0NBX1dSKGFkZHIsICpkYXRhKTsKCQkJTU9DQV9SRChhZGRyIC0gNCk7CS8qIGZsdXNoIHdyaXRlICovCgkJfQoKCQltdXRleF91bmxvY2soJnByaXYtPmNvcHlfbXV0ZXgpOwoJfQp9CgpzdGF0aWMgdm9pZCBtb2NhX3JlYWRfbWVtKHN0cnVjdCBtb2NhX3ByaXZfZGF0YSAqcHJpdiwKCXZvaWQgKmRzdCwgdWludDMyX3Qgc3JjX29mZnNldCwgdW5zaWduZWQgaW50IGxlbikKewoJc3RydWN0IG1vY2FfcGxhdGZvcm1fZGF0YSAqcGQgPSBwcml2LT5wZGV2LT5kZXYucGxhdGZvcm1fZGF0YTsKICAgIAoJaWYoKHNyY19vZmZzZXQgPj0gcHJpdi0+cmVncy0+Y250bF9tZW1fb2Zmc2V0K3ByaXYtPnJlZ3MtPmNudGxfbWVtX3NpemUpIHx8CgkJKChzcmNfb2Zmc2V0ICsgbGVuKSA+IHByaXYtPnJlZ3MtPmNudGxfbWVtX29mZnNldCtwcml2LT5yZWdzLT5jbnRsX21lbV9zaXplKSkgewoJCXByaW50ayhLRVJOX1dBUk5JTkcgIiVzOiBjb3B5IHBhc3QgZW5kIG9mIGNudGwgbWVtb3J5OiAlMDh4XG4iLAoJCQlfX0ZVTkNUSU9OX18sIHNyY19vZmZzZXQpOwoJCXJldHVybjsKCX0KCglpZiAoIDEgPT0gcGQtPnVzZV9kbWEgKQoJewoJCWRtYV9hZGRyX3QgcGE7CgoJCXBhID0gZG1hX21hcF9zaW5nbGUoJnByaXYtPnBkZXYtPmRldiwgZHN0LCBsZW4sIERNQV9GUk9NX0RFVklDRSk7CgkJbXV0ZXhfbG9jaygmcHJpdi0+Y29weV9tdXRleCk7CgkJbW9jYV9tMm1feGZlcihwcml2LCAodWludDMyX3QpcGEsIHNyY19vZmZzZXQgKyBwcml2LT5yZWdzLT5kYXRhX21lbV9vZmZzZXQsIGxlbiB8IE0yTV9SRUFEKTsKCQltdXRleF91bmxvY2soJnByaXYtPmNvcHlfbXV0ZXgpOwoJCWRtYV91bm1hcF9zaW5nbGUoJnByaXYtPnBkZXYtPmRldiwgcGEsIGxlbiwgRE1BX0ZST01fREVWSUNFKTsKCX0KCWVsc2UKCXsKCQl1aW50cHRyX3QgYWRkciA9IHByaXYtPnJlZ3MtPmRhdGFfbWVtX29mZnNldCArIHNyY19vZmZzZXQ7CgkJdWludDMyX3QgKmRhdGEgPSBkc3Q7CgkJaW50IGk7CgoJCW11dGV4X2xvY2soJnByaXYtPmNvcHlfbXV0ZXgpOwoJCWlmICgoKHN0cnVjdCBtb2NhX3BsYXRmb3JtX2RhdGEgKilwcml2LT5wZGV2LT5kZXYucGxhdGZvcm1fZGF0YSktPnVzZV9zcGkgPT0gMSkKCQl7CgkJCU1PQ0FfUkRfQkxPQ0soKHVpbnRwdHJfdClwcml2LT5iYXNlICsgYWRkciwgZHN0LCBsZW4pOwoJCX0KCQllbHNlCgkJewoJCQlmb3IoaSA9IDA7IGkgPCBsZW47IGkgKz0gNCwgYWRkciArPSA0LCBkYXRhKyspCgkJCQkqZGF0YSA9IE1PQ0FfUkQoKHVpbnRwdHJfdClwcml2LT5iYXNlICsgYWRkcik7CgkJfQoJCW11dGV4X3VubG9jaygmcHJpdi0+Y29weV9tdXRleCk7Cgl9Cn0KCnN0YXRpYyB2b2lkIG1vY2Ffd3JpdGVfc2coc3RydWN0IG1vY2FfcHJpdl9kYXRhICpwcml2LAoJdWludDMyX3QgZHN0X29mZnNldCwgc3RydWN0IHNjYXR0ZXJsaXN0ICpzZywgaW50IG5lbnRzKQp7CglpbnQgajsKCXVpbnRwdHJfdCBhZGRyID0gcHJpdi0+cmVncy0+ZGF0YV9tZW1fb2Zmc2V0ICsgZHN0X29mZnNldDsKCXN0cnVjdCBtb2NhX3BsYXRmb3JtX2RhdGEgKnBkID0gcHJpdi0+cGRldi0+ZGV2LnBsYXRmb3JtX2RhdGE7CgoJZG1hX21hcF9zZygmcHJpdi0+cGRldi0+ZGV2LCBzZywgbmVudHMsIERNQV9UT19ERVZJQ0UpOwoKCW11dGV4X2xvY2soJnByaXYtPmNvcHlfbXV0ZXgpOwoJZm9yKGogPSAwOyBqIDwgbmVudHM7IGorKykKCXsKCQlpZiAoIDEgPT0gcGQtPnVzZV9kbWEgKQoJCXsKCQkgICAgLy8gcHJpbnRrKCJYWFggY29weWluZyBwYWdlICVkLCBQQSAlMDh4XG4iLCBqLCAoaW50KXNnW2pdLmRtYV9hZGRyZXNzKTsKCQkJbW9jYV9tMm1feGZlcihwcml2LCBhZGRyLCAodWludDMyX3Qpc2dbal0uZG1hX2FkZHJlc3MsIAoJCQkJc2dbal0ubGVuZ3RoIHwgTTJNX1dSSVRFKTsKCgkJCWFkZHIgKz0gc2dbal0ubGVuZ3RoOwoJCX0KCQllbHNlCgkJewoJCQl1bnNpZ25lZCBsb25nICpkYXRhID0gKHZvaWQgKilwaHlzX3RvX3ZpcnQoc2dbal0uZG1hX2FkZHJlc3MpOwogICAgICAgICAvL3ByaW50aygiJXM6IFdyaXRpbmcgMHglbHggdG8gYWRkciAweCUwOGx4IChsZW4gPSAlZClcbiIsIF9fRlVOQ1RJT05fXywgKmRhdGEsICgodW5zaWduZWQgbG9uZylwcml2LT5iYXNlKSArIGFkZHIsIHNnW2pdLmxlbmd0aCk7CgkJCU1PQ0FfV1JfQkxPQ0soKCh1bnNpZ25lZCBsb25nKXByaXYtPmJhc2UpICsgYWRkciwgZGF0YSwgc2dbal0ubGVuZ3RoKTsKCQkJYWRkciArPSBzZ1tqXS5sZW5ndGg7CgkJfQoJfQoJbXV0ZXhfdW5sb2NrKCZwcml2LT5jb3B5X211dGV4KTsKCglkbWFfdW5tYXBfc2coJnByaXYtPnBkZXYtPmRldiwgc2csIG5lbnRzLCBETUFfVE9fREVWSUNFKTsKfQoKLyogTk9URTogdGhpcyBmdW5jdGlvbiBpcyBub3QgdGVzdGVkICovCiNpZiAwCnN0YXRpYyB2b2lkIG1vY2FfcmVhZF9zZyhzdHJ1Y3QgbW9jYV9wcml2X2RhdGEgKnByaXYsCgl1aW50MzJfdCBzcmNfb2Zmc2V0LCBzdHJ1Y3Qgc2NhdHRlcmxpc3QgKnNnLCBpbnQgbmVudHMpCnsKCWludCBqOwoJdWludHB0cl90IGFkZHIgPSBwcml2LT5kYXRhX21lbV9vZmZzZXQgKyBzcmNfb2Zmc2V0OwoKCWRtYV9tYXBfc2coJnByaXYtPnBkZXYtPmRldiwgc2csIG5lbnRzLCBETUFfRlJPTV9ERVZJQ0UpOwoKCW11dGV4X2xvY2soJnByaXYtPmNvcHlfbXV0ZXgpOwoJZm9yKGogPSAwOyBqIDwgbmVudHM7IGorKykgewojaWYgMCAvL1VTRV9ETUEKCQkgcHJpbnRrKCJYWFggY29weWluZyBwYWdlICVkLCBQQSAlMDh4XG4iLCBqLCAoaW50KXNnW2pdLmRtYV9hZGRyZXNzKTsKCQltb2NhX20ybV94ZmVyKHByaXYsIGFkZHIsICh1aW50MzJfdClzZ1tqXS5kbWFfYWRkcmVzcywKCQkJc2dbal0ubGVuZ3RoIHwgTTJNX1JFQUQpOwoKCQlhZGRyICs9IHNnW2pdLmxlbmd0aDsKI2Vsc2UKCQl1aW50MzJfdCAqZGF0YSA9ICh2b2lkICopcGh5c190b192aXJ0KHNnW2pdLmRtYV9hZGRyZXNzKTsKCQl1bnNpZ25lZCBpbnQgbGVuID0gc2dbal0ubGVuZ3RoOwoJCWludCBpOwoKCQlmb3IoaSA9IDA7IGkgPCBsZW47IGkgKz0gNCwgYWRkciArPSA0LCBkYXRhKyspIHsKCQkJKmRhdGEgPSBjcHVfdG9fYmUzMigKCQkJCU1PQ0FfUkQoKHVpbnRwdHJfdClwcml2LT5iYXNlICsgYWRkcikpOwoJCQkvL3ByaW50aygiTW9DQSBSRUFEOiBBRCAweCV4ICA9IDB4JXggKDB4JXgpXG4iLCAocHJpdi0+YmFzZSArIGFkZHIpLCBNT0NBX1JEKCh1aW50cHRyX3QpcHJpdi0+YmFzZSArIGFkZHIpLCAqZGF0YSk7CgkJIH0KI2VuZGlmCgl9CgltdXRleF91bmxvY2soJnByaXYtPmNvcHlfbXV0ZXgpOwoKCWRtYV91bm1hcF9zZygmcHJpdi0+cGRldi0+ZGV2LCBzZywgbmVudHMsIERNQV9GUk9NX0RFVklDRSk7Cn0KI2VuZGlmCgpzdGF0aWMgdm9pZCBtb2NhX3JlYWRfbWFjX2FkZHIoc3RydWN0IG1vY2FfcHJpdl9kYXRhICpwcml2LCB1aW50MzJfdCAqIGhpLCB1aW50MzJfdCAqIGxvKQp7CglzdHJ1Y3QgbmV0X2RldmljZSAqIHBkZXYgOwoJY2hhcgkJCQkJIG1vY2FOYW1lWzddIDsKCglpZiAocHJpdiA9PSBOVUxMKQoJCXNwcmludGYgKG1vY2FOYW1lLCAibW9jYSV1IiwgMCkgOwoJZWxzZQoJCXNwcmludGYgKG1vY2FOYW1lLCAibW9jYSV1IiwgKChzdHJ1Y3QgbW9jYV9wbGF0Zm9ybV9kYXRhICopcHJpdi0+cGRldi0+ZGV2LnBsYXRmb3JtX2RhdGEpLT5kZXZJZCkgOwoKI2lmIExJTlVYX1ZFUlNJT05fQ09ERSA+PSBLRVJORUxfVkVSU0lPTigyLCA2LCAyOSkKCXBkZXYgPSBkZXZfZ2V0X2J5X25hbWUgKCAmaW5pdF9uZXQsIG1vY2FOYW1lICkgOwojZWxzZQoJcGRldiA9IGRldl9nZXRfYnlfbmFtZSAoIG1vY2FOYW1lICkgOwojZW5kaWYKCglpZiAoKHBkZXYgIT0gTlVMTCkgJiYgKGxvICE9IE5VTEwpICYmIChoaSAhPSBOVUxMKSkgewoJCW1hY190b191MzIoaGksIGxvLCBwZGV2LT5kZXZfYWRkcik7Cgl9Cn0KCgojaWYgZGVmaW5lZChEU0xfTU9DQSkKCi8qCiAqIFRoaXMgaGVscGVyIGZ1bmN0aW9uIHdhcyBhZGRlZCB0byBhbGxvdyB0aGUgZW5ldCBkcml2ZXIgdG8gY29tcGlsZSBpbgogKiBjb25zdW1lciBlbnZpcm9ubWVudCBmb3IgNjh4eCBwcm9maWxlcy4KICovCnZvaWQgbW9jYV9nZXRfZmNfYml0cyh2b2lkICogYXJnLCB1bnNpZ25lZCBsb25nICptb2NhX2ZjX3JlZykKewoJc3RydWN0IG1vY2FfcHJpdl9kYXRhICogICAgIHByaXY7CglzdHJ1Y3QgbW9jYV9wbGF0Zm9ybV9kYXRhICogcE1vY2FEYXRhOwoJdW5zaWduZWQgbG9uZyAgICAgICAgICAgICAgIGZsYWdzOwoKCWlmIChhcmcgPT0gTlVMTCkgewoJCXJldHVybjsKCX0KCglwcml2ID0gKHN0cnVjdCBtb2NhX3ByaXZfZGF0YSAqKSBhcmc7CglwTW9jYURhdGEgPSAoc3RydWN0IG1vY2FfcGxhdGZvcm1fZGF0YSAqKXByaXYtPnBkZXYtPmRldi5wbGF0Zm9ybV9kYXRhOwoKCSptb2NhX2ZjX3JlZyA9IDA7CglpZiAocHJpdiAhPSBOVUxMKQoJewoJCS8qIFdlIGNhbid0IHJlYWQgbW9jYSBjb3JlIHJlZ3MgdW5sZXNzIHRoZSBjb3JlJ3MgY2xvY2tzIGFyZSBvbi4gKi8KCQlzcGluX2xvY2tfaXJxc2F2ZSgmcHJpdi0+Y2xvY2tfbG9jaywgZmxhZ3MpOwoJCWlmIChwcml2LT5ydW5uaW5nKSB7CgkJCSptb2NhX2ZjX3JlZyA9IE1PQ0FfUkQocHJpdi0+YmFzZStwcml2LT5yZWdzLT5zaWRlYmFuZF9nbWlpX2ZjX29mZnNldCk7CgkJfQoJCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJnByaXYtPmNsb2NrX2xvY2ssIGZsYWdzKTsKCX0KfQoKI2VuZGlmIC8qIERTTF9NT0NBICovCgpzdGF0aWMgaW50IF9fZGV2aW5pdCBibW9jYV9zcGlfcHJvYmUoc3RydWN0IHNwaV9kZXZpY2UgKnNwaSkgewoJLy8gVE9ETyhhcGVud2Fycik6IG1hdGNoIG9uZSBzcGkgZGV2aWNlIHRvIG9uZSBtb2NhIGRldmljZSBzdHJ1Y3QuCgkvLyBJIGhhcHBlbiB0byBrbm93IHRoYXQgcmlnaHQgbm93IHRoZSBzeXN0ZW0gb25seSByZWdpc3RlcnMgb25lIG9mCgkvLyBtb2NhX2xhbiBvciBtb2NhX3dhbiwgbmV2ZXIgYm90aCwgYW5kIHRoZXJlIGlzIG5ldmVyIG1vcmUgdGhhbgoJLy8gb25lIG1vY2EgY2hpcCBwcmVzZW50IG9uIG91ciBzeXN0ZW1zLCBzbyB0aGlzIGlzIG9rYXkgZm9yIG5vdy4KCXVpbnQzMl90IHZhbCA9IGtlclN5c0JjbVNwaVNsYXZlUmVhZFJlZzMyKHNwaSwgMHgxMDQwNDAwMCk7Cglwcl9pbmZvKCJibW9jYV9zcGlfcHJvYmUgYnVzPSVkIGNoaXBfc2VsZWN0PSVkOiBpZD0lMDh4ICVzXG4iLAoJCXNwaS0+bWFzdGVyLT5idXNfbnVtLCBzcGktPmNoaXBfc2VsZWN0LCB2YWwsCgkJdmFsICE9IDAgPyAieWVzIiA6ICJubyIpOwoJaWYgKHZhbCA9PSAwKSByZXR1cm4gLUVOT0RFVjsKCW1vY2FfbGFuX2RhdGEuc3BpID0gc3BpOwoJbW9jYV93YW5fZGF0YS5zcGkgPSBzcGk7CglyZXR1cm4gMDsgLy8gc3VjY2Vzcwp9CgpzdGF0aWMgaW50IF9fZGV2ZXhpdCBibW9jYV9zcGlfcmVtb3ZlKHN0cnVjdCBzcGlfZGV2aWNlICpzcGkpIHsKCXByX2luZm8oImJtb2NhX3NwaV9yZW1vdmVcbiIpOwoJaWYgKG1vY2FfbGFuX2RhdGEuc3BpID09IHNwaSkgbW9jYV9sYW5fZGF0YS5zcGkgPSBOVUxMOwoJaWYgKG1vY2Ffd2FuX2RhdGEuc3BpID09IHNwaSkgbW9jYV93YW5fZGF0YS5zcGkgPSBOVUxMOwoJcmV0dXJuIDA7IC8vIHN1Y2Nlc3MKfQoKc3RhdGljIHN0cnVjdCBzcGlfZHJpdmVyIGJtb2NhX3NwaV9kcml2ZXIgPSB7CiAgLmRyaXZlciA9IHsKICAgIC5uYW1lID0gImJtb2NhIiwKICAgIC5vd25lciA9IFRISVNfTU9EVUxFLAogIH0sCiAgLnByb2JlID0gYm1vY2Ffc3BpX3Byb2JlLAogIC5yZW1vdmUgPSBfX2RldmV4aXRfcChibW9jYV9zcGlfcmVtb3ZlKSwKfTsKCi8vZXh0ZXJuIHZvaWQgYmNtZW5ldF9yZWdpc3Rlcl9tb2NhX2ZjX2JpdHNfY2Iodm9pZCBjYih2b2lkICosIHVuc2lnbmVkIGxvbmcgKiksIGludCBpc1dhbiwgdm9pZCAqIGFyZyk7CgpzdGF0aWMgdm9pZCBtb2NhX21lbV9pbml0XzY4MHhDMCggc3RydWN0IG1vY2FfcHJpdl9kYXRhICpwcml2ICkKewoJLy8gRGUtYXNzZXJ0IHJlc2V0IChhbGwgbWVtb3JpZXMgYXJlIE9GRiBieSBkZWZhdWx0IEZvcmNlX1NQX29mZiA9MSwgRm9yY2VfUmZfb2ZmID0xKQoJTU9DQV9VTlNFVChwcml2LT5iYXNlICsgcHJpdi0+cmVncy0+c3dfcmVzZXRfb2Zmc2V0LCAoKDEgPDwgMTUpIHwgKDEgPDwgMTYpKSk7CgoJbW9jYV9wbWJfZGVsYXkocHJpdik7Cgltb2NhX3BtYl9jb250cm9sKHByaXYsIFBNQl9DT01NQU5EX0FMTF9PRkYpOwoKCS8vV3JpdGUgRm9yY2VfU1Bfb24gPTAsIEZvcmNlX1NQX29mZiA9MCwgRm9yY2VfUkZfb24gPTAsIEZvcmNlX1JGX29mZiA9MAoJTU9DQV9VTlNFVChwcml2LT5iYXNlICsgMHgwMDFmZmQxNCwgKCgxIDw8IDEwKSB8ICgxIDw8IDExKSkpOwoJbW9jYV9wbWJfY29udHJvbChwcml2LCBQTUJfQ09NTUFORF9QQVJUSUFMX09OKTsKfQoKc3RhdGljIGludCAgaHdfc3BlY2lmaWNfaW5pdCggc3RydWN0IG1vY2FfcHJpdl9kYXRhICpwcml2ICkKewojaWZkZWYgRFNMX01PQ0EKCXN0cnVjdCBtb2NhX3BsYXRmb3JtX2RhdGEgKnBNb2NhRGF0YTsKCXUzMiBwb3J0X21vZGU7CgoJcE1vY2FEYXRhID0gKHN0cnVjdCBtb2NhX3BsYXRmb3JtX2RhdGEgKilwcml2LT5wZGV2LT5kZXYucGxhdGZvcm1fZGF0YTsKCgkvKiBmaWxsIGluIHRoZSBod19yZXYgZmllbGQgKi8KCXBNb2NhRGF0YS0+Y2hpcF9pZCA9IE1PQ0FfUkQoMHgxMDQwNDAwNCkgKyAweEEwOwoJcHJfaW5mbygicmVhZCBtb2NhIGNoaXAgaWQ6ICUwOHhcbiIsIHBNb2NhRGF0YS0+Y2hpcF9pZCk7CglpZiAoKHBNb2NhRGF0YS0+Y2hpcF9pZCAmIDB4RkZGRTAwMDApICE9IDB4NjgwMjAwMDApIHsgLyogNjgwMiBvciA2ODAzICovCgkJcHJpbnRrKEtFUk5fRVJSICJibW9jYTogTm8gTW9DQSBjaGlwIGZvdW5kXG4iKTsKCQlyZXR1cm4gLUVGQVVMVDsKCX0KCglNT0NBX1dSKDB4MTA0MDQzMWMsIDB4MEZGRkZGRkYpOyAvLyBTVU5fVE9QX0NUUkxfU1dfSU5JVF8wX0NMRUFSCglNT0NBX1dSKDB4MTA0MDQwYTQsIDB4MDEpOyAgICAgICAvLyBHRU5FUkFMX0NUUkxfTk9fU0NBTl8wCgkvKiBQb3dlciBkb3duIEdQSFkgTERPIHJlZ3VsYXRvciB0byBzYXZlIHBvd2VyICovCglNT0NBX1dSKDB4MTA0MDQwYTgsIDB4MDMpOyAgICAgICAvLyBHRU5FUkFMX0NUUkxfTk9fU0NBTl8xCglNT0NBX1dSKDB4MTA0MDQxMDAsIDB4MTExMTAwMTEpOyAvLyBQSU5fTVVYX0NUUkxfMAoJTU9DQV9XUigweDEwNDA0MTA0LCAweDExMTExMTExKTsgLy8gUElOX01VWF9DVFJMXzEKCgkvKiBUaGUgZGVmaW5pdGlvbiBvZiBQT1JUX01PREUgaGFzIGNoYW5nZWQgZnJvbSBjaGlwIHJldmlzaW9uIEIwIHRvIEMwCgkgKiAqLwoJaWYgKChwTW9jYURhdGEtPmNoaXBfaWQgJiAweEZGRkVGRkYwKSA9PSAweDY4MDIwMEMwKQoJCXBvcnRfbW9kZSA9IDI7IC8qIFJHTUlJXzEgPC0+IEdQSFksIFJHTUlJXzAgPC0+IE1vQ0EgKi8KCWVsc2UKCQlwb3J0X21vZGUgPSAzOyAvKiBSR01JSV8wIDwtPiBNb0NBICovCgoJTU9DQV9XUigweDEwODAwMDAwLCBwb3J0X21vZGUpOyAgLy8gRU1VWF9DTlRSTAoJTU9DQV9XUigweDEwODAwMDBjLCAweDExKTsgICAgICAgLy8gUkdNSUlfMF9DTlRSTAoJTU9DQV9XUigweDEwODAwMDE0LCAweGMwKTsgICAgICAgLy8gUkdNSUlfMF9SWF9DTEtfREVMQVlfQ05UUkwKCgkvKiBTaHV0ZG93biBHUEhZIHRvIHNhdmUgcG93ZXIgKi8KCU1PQ0FfV1IoMHgxMDgwMDAwNCwgTU9DQV9SRCgweDEwODAwMDA0KSB8IDB4Rik7IC8vIEVQT1JUX1JFR19HUEhZX0NOVFJMCgkvKiBEaXNhYmxlIFVBUlRzIHRvIHNhdmUgcG93ZXIgKi8KCU1PQ0FfV1IoMHgxMDQwNjE4MCwgMHg0MDAwKTsgLy8gUE1fQ09ORklHCgoJaWYgKCgocE1vY2FEYXRhLT5jaGlwX2lkICYgMHhGRkZGRkZGMCkgPT0gMHg2ODAyMDBDMCkgfHwgKChwTW9jYURhdGEtPmNoaXBfaWQgJiAweEZGRkZGRkYwKSA9PSAweDY4MDMwMEMwKSkKCXsKCQlwcml2LT5pMmNfYmFzZSA9IE5VTEw7IAoKCQkvKiBJbml0aWFsaXplIDY4MHggQ08gbWVtb3J5ICovCgkJbW9jYV9tZW1faW5pdF82ODB4QzAocHJpdik7Cgl9CgoJcE1vY2FEYXRhLT5od19yZXYgPSBIV1JFVl9NT0NBXzIwX0dFTjIyOwoKCS8qIFBvd2VyIGRvd24gYWxsIExFQVAgbWVtb3JpZXMgKi8KCU1PQ0FfV1IoMHgxMDEwMDBlNCwgMHg2KTsgLy8gQ0xLR0VOX0xFQVBfVE9QX0lOU1RfREFUQSAgIAoJTU9DQV9XUigweDEwMTAwMGU4LCAweDYpOyAvLyBDTEtHRU5fTEVBUF9UT1BfSU5TVF9IQUIgCglNT0NBX1dSKDB4MTAxMDAwZWMsIDB4Nik7IC8vIENMS0dFTl9MRUFQX1RPUF9JTlNUX1BST0cwCglNT0NBX1dSKDB4MTAxMDAwZjAsIDB4Nik7IC8vIENMS0dFTl9MRUFQX1RPUF9JTlNUX1BST0cxICAgCglNT0NBX1dSKDB4MTAxMDAwZjQsIDB4Nik7IC8vIENMS0dFTl9MRUFQX1RPUF9JTlNUX1BST0cyICAKCU1PQ0FfV1IoMHgxMDEwMDBmOCwgMHg2KTsgLy8gQ0xLR0VOX0xFQVBfVE9QX0lOU1RfUk9NCglNT0NBX1dSKDB4MTAxMDAwZmMsIDB4Nik7IC8vIENMS0dFTl9MRUFQX1RPUF9JTlNUX1NIQVJFRCAgCglNT0NBX1dSKDB4MTAxMDAxNjQsIDB4Myk7IC8vIENMS0dFTl9TWVNfQ1RSTF9JTlNUX1BPV0VSX1NXSVRDSF9NRU1PUlkgCgoJLyogRGlzYWJsZSBjbGtvYnN2IG91dHB1dCBwaW4gdG8gc2F2ZSBwb3dlciAqLwoJTU9DQV9XUigweDEwMTAwMTNDLCAweDEpOyAvLyBDTEtHRU5fUEFEX0NMT0NLX0RJU0FCTEUKCS8qIERpc2FibGUgTEVBUCBjbG9ja3MgdG8gc2F2ZSBwb3dlciAqLwoJTU9DQV9XUigweDEwMTAwMEQ0LCAweDcpOyAvLyBDTEtHRU5fTEVBUF9UT1BfSU5TVF9DTE9DS19ESVNBQkxFCgovLwliY21lbmV0X3JlZ2lzdGVyX21vY2FfZmNfYml0c19jYigKLy8JCW1vY2FfZ2V0X2ZjX2JpdHMsIHBNb2NhRGF0YS0+dXNlX3NwaSA/IDEgOiAwLCAodm9pZCAqKXByaXYpOwojZW5kaWYKCglyZXR1cm4gMDsKfQoKc3RhdGljIGludCBtb2NhX3BsYXRmb3JtX2Rldl9yZWdpc3Rlcih2b2lkKQp7CglzdHJ1Y3QgbW9jYV9wbGF0Zm9ybV9kYXRhICpwTW9jYURhdGE7CglzdHJ1Y3QgcGxhdGZvcm1fZGV2aWNlICpwUGxhdGZvcm1EZXY7CglCUF9NT0NBX0lORk8gbW9jYUluZm9bQlBfTU9DQV9NQVhfTlVNXTsKCWludCBtb2NhQ2hpcE51bSA9IEJQX01PQ0FfTUFYX05VTTsKCWludCBpOwoJaW50IHJldCA9IDA7ICAgCgoJQnBHZXRNb2NhSW5mbyhtb2NhSW5mbywgJm1vY2FDaGlwTnVtKTsKCglyZXQgPSBzcGlfcmVnaXN0ZXJfZHJpdmVyKCZibW9jYV9zcGlfZHJpdmVyKTsKCWlmIChyZXQgPCAwKSByZXR1cm4gcmV0OwoKCWZvciAoaSA9IDA7IGkgPCBtb2NhQ2hpcE51bTsgaSsrKSB7CgkJc3dpdGNoIChtb2NhSW5mb1tpXS50eXBlKSB7CgkJCWNhc2UgQlBfTU9DQV9UWVBFX1dBTjoKCQkJCXBNb2NhRGF0YSA9ICZtb2NhX3dhbl9kYXRhOwoJCQkJcFBsYXRmb3JtRGV2ID0gJm1vY2Ffd2FuX3BsYXRfZGV2OwoJCQkJYnJlYWs7CgoJCQljYXNlIEJQX01PQ0FfVFlQRV9MQU46CgkJCQlwTW9jYURhdGEgPSAmbW9jYV9sYW5fZGF0YTsKCQkJCXBQbGF0Zm9ybURldiA9ICZtb2NhX2xhbl9wbGF0X2RldjsKCQkJCWJyZWFrOwoKCQkJZGVmYXVsdDoKCQkJCXByaW50ayhLRVJOX0VSUiAiYm1vY2E6IHVucmVjb2duaXplZCBNb0NBIHR5cGUgJWRcbiIsCgkJCQkJbW9jYUluZm9baV0udHlwZSk7CgkJCQlyZXR1cm4oLTEpOwoJCQkJYnJlYWs7CgkJfQoKCQlyZXQgPSBwbGF0Zm9ybV9kZXZpY2VfcmVnaXN0ZXIocFBsYXRmb3JtRGV2KTsKCQlpZiAocmV0IDwgMCkgewoJCQlzcGlfdW5yZWdpc3Rlcl9kcml2ZXIoJmJtb2NhX3NwaV9kcml2ZXIpOwoJCQlyZXR1cm4ocmV0KTsKCQl9CgkJZWxzZSB7CgkJCXBNb2NhRGF0YS0+ZGV2SWQgPSBpOwoKCQkJLyogTWFwIHRoZSBib2FyZCBwYXJhbXMgUkYgQmFuZCB0byB0aGUgYm1vY2EuaCB2YWx1ZSAqLwoJCQlzd2l0Y2ggKG1vY2FJbmZvW2ldLnJmQmFuZCkKCQkJewoJCQkJY2FzZSBCUF9NT0NBX1JGX0JBTkRfRF9MT1c6CgkJCQkJcE1vY2FEYXRhLT5yZl9iYW5kID0gTU9DQV9CQU5EX0RfTE9XOwoJCQkJCWJyZWFrOwoJCQkJY2FzZSBCUF9NT0NBX1JGX0JBTkRfRF9ISUdIOgoJCQkJCXBNb2NhRGF0YS0+cmZfYmFuZCA9IE1PQ0FfQkFORF9EX0hJR0g7CgkJCQkJYnJlYWs7CgkJCQljYXNlIEJQX01PQ0FfUkZfQkFORF9FWFRfRDoKCQkJCQlwTW9jYURhdGEtPnJmX2JhbmQgPSBNT0NBX0JBTkRfRVhUX0Q7CgkJCQkJYnJlYWs7CgkJCQljYXNlIEJQX01PQ0FfUkZfQkFORF9FOgoJCQkJCXBNb2NhRGF0YS0+cmZfYmFuZCA9IE1PQ0FfQkFORF9FOwoJCQkJCWJyZWFrOwoJCQkJY2FzZSBCUF9NT0NBX1JGX0JBTkRfRjogICAgCgkJCQkJcE1vY2FEYXRhLT5yZl9iYW5kID0gTU9DQV9CQU5EX0Y7CgkJCQkJYnJlYWs7CgkJCQlkZWZhdWx0OgoJCQkJCS8qIERvIG5vdGhpbmcgKi8KCQkJCQlicmVhazsKCQkJfQoJCQlwcmludGsoS0VSTl9JTkZPICJibW9jYTogRm91bmQgTW9DQSBkZXZpY2UgJWQvJWQgIFJGIEJhbmQgJWRcbiIsCgkJCQlpLCBtb2NhQ2hpcE51bSwgbW9jYUluZm9baV0ucmZCYW5kKTsKCQl9Cgl9CgoJcmV0dXJuKHJldCk7Cn0KCnN0YXRpYyB2b2lkIG1vY2FfcGxhdGZvcm1fZGV2X3VucmVnaXN0ZXIodm9pZCkKewoJc3BpX3VucmVnaXN0ZXJfZHJpdmVyKCZibW9jYV9zcGlfZHJpdmVyKTsKCglpZiAobW9jYV9sYW5fZGF0YS5kZXZJZCAhPSBNT0NBX0RFVklDRV9JRF9VTlJFR0lTVEVSRUQpCgkJcGxhdGZvcm1fZGV2aWNlX3VucmVnaXN0ZXIoJm1vY2FfbGFuX3BsYXRfZGV2KTsKCglpZiAobW9jYV93YW5fZGF0YS5kZXZJZCAhPSBNT0NBX0RFVklDRV9JRF9VTlJFR0lTVEVSRUQpCgkJcGxhdGZvcm1fZGV2aWNlX3VucmVnaXN0ZXIoJm1vY2Ffd2FuX3BsYXRfZGV2KTsKfQoKc3RhdGljIHZvaWQgbW9jYV8zNDUwX3dyaXRlKHN0cnVjdCBtb2NhX3ByaXZfZGF0YSAqcHJpdiwgdTggYWRkciwgdTMyIGRhdGEpCnsKCS8qIGNvbW1lbnQgb3V0IGZvciBub3cuIFdlIGRvbid0IHVzZSBpMmMgb24gdGhlIDYzMjY4QkhSIGJvYXJkICovCiNpZmRlZiBNT0NBXzM0NTBfVVNFX0kyQwoJaWYgKCgoc3RydWN0IG1vY2FfcGxhdGZvcm1fZGF0YSAqKXByaXYtPnBkZXYtPmRldi5wbGF0Zm9ybV9kYXRhKS0+dXNlX3NwaSA9PSAwKQoJCWJjbTM0NTBfd3JpdGVfcmVnKGFkZHIsIGRhdGEpOwoJZWxzZQojZW5kaWYKCXsKCQlpZiAocHJpdi0+aTJjX2Jhc2UgIT0gTlVMTCkKCQkJbW9jYV8zNDUwX3dyaXRlX2kyYyhwcml2LCBhZGRyLCBkYXRhKTsKCX0KfQoKc3RhdGljIHUzMiBtb2NhXzM0NTBfcmVhZChzdHJ1Y3QgbW9jYV9wcml2X2RhdGEgKnByaXYsIHU4IGFkZHIpCnsKCS8qIGNvbW1lbnQgb3V0IGZvciBub3cuIFdlIGRvbid0IHVzZSBpMmMgb24gdGhlIDYzMjY4QkhSIGJvYXJkICovCiNpZmRlZiBNT0NBXzM0NTBfVVNFX0kyQwoJaWYgKCgoc3RydWN0IG1vY2FfcGxhdGZvcm1fZGF0YSAqKXByaXYtPnBkZXYtPmRldi5wbGF0Zm9ybV9kYXRhKS0+dXNlX3NwaSA9PSAwKQoJCXJldHVybihiY20zNDUwX3JlYWRfcmVnKGFkZHIpKTsKCWVsc2UKI2VuZGlmCgl7CgkJaWYgKHByaXYtPmkyY19iYXNlICE9IE5VTEwpCgkJCXJldHVybihtb2NhXzM0NTBfcmVhZF9pMmMocHJpdiwgYWRkcikpOwoJCWVsc2UKCQkJcmV0dXJuKDB4ZmZmZmZmZmYpOwoJfQp9Cg==