LyoKICAgIDw6Y29weXJpZ2h0LUJSQ006MjAxMzpEVUFML0dQTDpzdGFuZGFyZAogICAgCiAgICAgICBDb3B5cmlnaHQgKGMpIDIwMTMgQnJvYWRjb20gQ29ycG9yYXRpb24KICAgICAgIEFsbCBSaWdodHMgUmVzZXJ2ZWQKICAgIAogICAgVW5sZXNzIHlvdSBhbmQgQnJvYWRjb20gZXhlY3V0ZSBhIHNlcGFyYXRlIHdyaXR0ZW4gc29mdHdhcmUgbGljZW5zZQogICAgYWdyZWVtZW50IGdvdmVybmluZyB1c2Ugb2YgdGhpcyBzb2Z0d2FyZSwgdGhpcyBzb2Z0d2FyZSBpcyBsaWNlbnNlZAogICAgdG8geW91IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyCiAgICAodGhlICJHUEwiKSwgYXZhaWxhYmxlIGF0IGh0dHA6Ly93d3cuYnJvYWRjb20uY29tL2xpY2Vuc2VzL0dQTHYyLnBocCwKICAgIHdpdGggdGhlIGZvbGxvd2luZyBhZGRlZCB0byBzdWNoIGxpY2Vuc2U6CiAgICAKICAgICAgIEFzIGEgc3BlY2lhbCBleGNlcHRpb24sIHRoZSBjb3B5cmlnaHQgaG9sZGVycyBvZiB0aGlzIHNvZnR3YXJlIGdpdmUKICAgICAgIHlvdSBwZXJtaXNzaW9uIHRvIGxpbmsgdGhpcyBzb2Z0d2FyZSB3aXRoIGluZGVwZW5kZW50IG1vZHVsZXMsIGFuZAogICAgICAgdG8gY29weSBhbmQgZGlzdHJpYnV0ZSB0aGUgcmVzdWx0aW5nIGV4ZWN1dGFibGUgdW5kZXIgdGVybXMgb2YgeW91cgogICAgICAgY2hvaWNlLCBwcm92aWRlZCB0aGF0IHlvdSBhbHNvIG1lZXQsIGZvciBlYWNoIGxpbmtlZCBpbmRlcGVuZGVudAogICAgICAgbW9kdWxlLCB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YgdGhlIGxpY2Vuc2Ugb2YgdGhhdCBtb2R1bGUuCiAgICAgICBBbiBpbmRlcGVuZGVudCBtb2R1bGUgaXMgYSBtb2R1bGUgd2hpY2ggaXMgbm90IGRlcml2ZWQgZnJvbSB0aGlzCiAgICAgICBzb2Z0d2FyZS4gIFRoZSBzcGVjaWFsIGV4Y2VwdGlvbiBkb2VzIG5vdCBhcHBseSB0byBhbnkgbW9kaWZpY2F0aW9ucwogICAgICAgb2YgdGhlIHNvZnR3YXJlLgogICAgCiAgICBOb3Qgd2l0aHN0YW5kaW5nIHRoZSBhYm92ZSwgdW5kZXIgbm8gY2lyY3Vtc3RhbmNlcyBtYXkgeW91IGNvbWJpbmUKICAgIHRoaXMgc29mdHdhcmUgaW4gYW55IHdheSB3aXRoIGFueSBvdGhlciBCcm9hZGNvbSBzb2Z0d2FyZSBwcm92aWRlZAogICAgdW5kZXIgYSBsaWNlbnNlIG90aGVyIHRoYW4gdGhlIEdQTCwgd2l0aG91dCBCcm9hZGNvbSdzIGV4cHJlc3MgcHJpb3IKICAgIHdyaXR0ZW4gY29uc2VudC4KICAgIAogICAgOj4gCgoqLwoKI2luY2x1ZGUgImJic2kuaCIKI2luY2x1ZGUgPGxpbnV4L3NwaS9zcGkuaD4KCiNpZiBMSU5VWF9WRVJTSU9OX0NPREUgPj0gS0VSTkVMX1ZFUlNJT04oMiw2LDMwKQojZWxzZQp0eXBlZGVmIHVuc2lnbmVkIGxvbmcgdWludHB0cl90OwojZW5kaWYgLy8gTElOVVhfVkVSU0lPTl9DT0RFID49IEtFUk5FTF9WRVJTSU9OKDIsNiwzMCkKCiNkZWZpbmUgTU9DQV9SRCh4KSAgICAoKCgoc3RydWN0IG1vY2FfcGxhdGZvcm1fZGF0YSAqKXByaXYtPnBkZXYtPmRldi5wbGF0Zm9ybV9kYXRhKS0+dXNlX3NwaSA9PSAwKSA/IFwKICAgICAgICAgICAgICAgICAgICAgICAoKigodm9sYXRpbGUgdWludDMyX3QgKikoKHVuc2lnbmVkIGxvbmcpKHgpKSkpIDogXAogICAgICAgICAgICAgICAgICAgICAgICgodWludDMyX3Qpa2VyU3lzQmNtU3BpU2xhdmVSZWFkUmVnMzIoKChzdHJ1Y3QgbW9jYV9wbGF0Zm9ybV9kYXRhICopcHJpdi0+cGRldi0+ZGV2LnBsYXRmb3JtX2RhdGEpLT5zcGksICh1aW50MzJfdCkoeCkpKSkKCiNkZWZpbmUgTU9DQV9SRDgoeCwgeSkgKCgoKHN0cnVjdCBtb2NhX3BsYXRmb3JtX2RhdGEgKilwcml2LT5wZGV2LT5kZXYucGxhdGZvcm1fZGF0YSktPnVzZV9zcGkgPT0gMCkgPyBcCiAgICAgICAgICAgICAgICAgICAgICAgICgqKHkpID0gKigodm9sYXRpbGUgdW5zaWduZWQgY2hhciAqKSgodW5zaWduZWQgbG9uZykoeCkpKSkgOiBcCiAgICAgICAgICAgICAgICAgICAgICAgIChrZXJTeXNCY21TcGlTbGF2ZVJlYWQoKChzdHJ1Y3QgbW9jYV9wbGF0Zm9ybV9kYXRhICopcHJpdi0+cGRldi0+ZGV2LnBsYXRmb3JtX2RhdGEpLT5zcGksICh1bnNpZ25lZCBsb25nKSh4KSwgeSwgMSkpKQoKI2RlZmluZSBNT0NBX1dSKHgseSkgICBkbyB7ICgoKChzdHJ1Y3QgbW9jYV9wbGF0Zm9ybV9kYXRhICopcHJpdi0+cGRldi0+ZGV2LnBsYXRmb3JtX2RhdGEpLT51c2Vfc3BpID09IDApID8gXAogICAgICAgICAgICAgICAgICAgICAgICAgICAgKCooKHZvbGF0aWxlIHVpbnQzMl90ICopKCh1bnNpZ25lZCBsb25nKSh4KSkpKSA9ICh5KSA6IFwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGtlclN5c0JjbVNwaVNsYXZlV3JpdGVSZWczMigoKHN0cnVjdCBtb2NhX3BsYXRmb3JtX2RhdGEgKilwcml2LT5wZGV2LT5kZXYucGxhdGZvcm1fZGF0YSktPnNwaSwgKHVpbnQzMl90KSh4KSwgKHkpKSk7IH0gd2hpbGUoMCkKCiNkZWZpbmUgTU9DQV9XUjgoeCx5KSAgICBkbyB7ICgoKChzdHJ1Y3QgbW9jYV9wbGF0Zm9ybV9kYXRhICopcHJpdi0+cGRldi0+ZGV2LnBsYXRmb3JtX2RhdGEpLT51c2Vfc3BpID09IDApID8gXAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKCooKHZvbGF0aWxlIHVuc2lnbmVkIGNoYXIgKikoKHVuc2lnbmVkIGxvbmcpKHgpKSkpID0gKHVuc2lnbmVkIGNoYXIpKHkpIDogXAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAga2VyU3lzQmNtU3BpU2xhdmVXcml0ZSgoKHN0cnVjdCBtb2NhX3BsYXRmb3JtX2RhdGEgKilwcml2LT5wZGV2LT5kZXYucGxhdGZvcm1fZGF0YSktPnNwaSwgKHVuc2lnbmVkIGxvbmcpKHgpLCAoeSksIDEpKTsgfSB3aGlsZSgwKQoKI2RlZmluZSBNT0NBX1dSMTYoeCx5KSAgIGRvIHsgKCgoKHN0cnVjdCBtb2NhX3BsYXRmb3JtX2RhdGEgKilwcml2LT5wZGV2LT5kZXYucGxhdGZvcm1fZGF0YSktPnVzZV9zcGkgPT0gMCkgPyBcCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoKigodm9sYXRpbGUgdW5zaWduZWQgc2hvcnQgKikoKHVuc2lnbmVkIGxvbmcpKHgpKSkpID0gKHVuc2lnbmVkIHNob3J0KSh5KSA6IFwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGtlclN5c0JjbVNwaVNsYXZlV3JpdGUoKChzdHJ1Y3QgbW9jYV9wbGF0Zm9ybV9kYXRhICopcHJpdi0+cGRldi0+ZGV2LnBsYXRmb3JtX2RhdGEpLT5zcGksICh1bnNpZ25lZCBsb25nKSh4KSwgKHkpLCAyKSk7IH0gd2hpbGUoMCkKCiNkZWZpbmUgTU9DQV9XUl9CTE9DSyhhZGRyLCBzcmMsIGxlbikgZG8geyBrZXJTeXNCY21TcGlTbGF2ZVdyaXRlQnVmKCgoc3RydWN0IG1vY2FfcGxhdGZvcm1fZGF0YSAqKXByaXYtPnBkZXYtPmRldi5wbGF0Zm9ybV9kYXRhKS0+c3BpLCBhZGRyLCBzcmMsIGxlbiwgNCk7IH0gd2hpbGUoMCkKI2RlZmluZSBNT0NBX1JEX0JMT0NLKGFkZHIsIGRzdCwgbGVuKSBkbyB7IGtlclN5c0JjbVNwaVNsYXZlUmVhZEJ1ZigoKHN0cnVjdCBtb2NhX3BsYXRmb3JtX2RhdGEgKilwcml2LT5wZGV2LT5kZXYucGxhdGZvcm1fZGF0YSktPnNwaSwgYWRkciwgZHN0LCBsZW4sIDQpOyB9IHdoaWxlKDApCgoKI2RlZmluZSBJMkNfUkQoeCkJCU1PQ0FfUkQoeCkKI2RlZmluZSBJMkNfV1IoeCwgeSkJCU1PQ0FfV1IoeCwgeSkKCiNkZWZpbmUgTU9DQV9CUENNX05VTSAgICAgICAgIDUKI2RlZmluZSBNT0NBX0JQQ01fWk9ORVNfTlVNICAgOAoKdHlwZWRlZiBlbnVtIF9QTUJfQ09NTUFORF9FXwp7CiAgIFBNQl9DT01NQU5EX0FMTF9PRkYgPSAwLAogICBQTUJfQ09NTUFORF9BTExfT04sCgogICBQTUJfQ09NTUFORF9MQVNUCn0gUE1CX0NPTU1BTkRfRTsKCnN0YXRpYyB1aW50MzJfdCB6b25lX29mZl9iaXRtYXNrW01PQ0FfQlBDTV9OVU1dID0geyAweEZGLCAweDAzLCAweDMwLCAweDAwLCAweDAwIH07CnN0YXRpYyB1aW50MzJfdCB6b25lX29uX2JpdG1hc2tbTU9DQV9CUENNX05VTV0gID0geyAweEZGLCAweEZGLCAweEZGLCAweEZGLCAweEZGIH07CgpzdGF0aWMgdm9pZCBib2d1c19yZWxlYXNlKHN0cnVjdCBkZXZpY2UgKmRldikKewp9CgpzdGF0aWMgc3RydWN0IG1vY2FfcGxhdGZvcm1fZGF0YSBtb2NhX2xhbl9kYXRhID0gewoJLm1hY2FkZHJfaGkgPQkJMHgwMDAwMDEwMiwKCS5tYWNhZGRyX2xvID0JCTB4MDMwNDAwMDAsCgoJLmJjbTM0NTBfaTJjX2Jhc2UgPSAgMHgxMDQwNjIwMCwKCS5iY20zNDUwX2kyY19hZGRyID0gIDB4NzAsCgkuaHdfcmV2ICA9ICAgICBIV1JFVl9NT0NBXzIwX0dFTjIyLAoJLnJmX2JhbmQgPSAgICAgTU9DQV9CQU5EX0VYVF9ELAoJLmNoaXBfaWQgPSAgICAgMCwKCS51c2VfZG1hICAgICAgICAgICA9IDAsCgkudXNlX3NwaSAgICAgICAgICAgPSAxLAoJLmRldklkICAgICAgICAgICAgPSBNT0NBX0RFVklDRV9JRF9VTlJFR0lTVEVSRUQsIC8vIEZpbGxlZCBpbiBkeW5hbWljYWxseQojaWZkZWYgQ09ORklHX1NNUAoJLnNtcF9wcm9jZXNzb3JfaWQgPSAxLAojZW5kaWYKfTsKCnN0YXRpYyBzdHJ1Y3QgcmVzb3VyY2UgbW9jYV9sYW5fcmVzb3VyY2VzW10gPSB7CglbMF0gPSB7CgkJLnN0YXJ0ID0gMHgxMDYwMDAwMCwKCQkuZW5kID0gICAweDEwN2ZmZDk3LAoJCS5mbGFncyA9IElPUkVTT1VSQ0VfTUVNLAoJfSwKCVsxXSA9IHsgLyogTm90IHVzZWQgZm9yIDY4MDIsIGRlZmluZSBmb3IgYm1vY2EgKi8KCQkuc3RhcnQgPSAwLAoJCS5lbmQgPSAwLAoJCS5mbGFncyA9IElPUkVTT1VSQ0VfSVJRLAoJfQp9OwoKc3RhdGljIHN0cnVjdCBwbGF0Zm9ybV9kZXZpY2UgbW9jYV9sYW5fcGxhdF9kZXYgPSB7CgkubmFtZSA9ICJibW9jYSIsCgkuaWQgPSAwLAoJLm51bV9yZXNvdXJjZXMgPSBBUlJBWV9TSVpFKG1vY2FfbGFuX3Jlc291cmNlcyksCgkucmVzb3VyY2UgPSBtb2NhX2xhbl9yZXNvdXJjZXMsCgkuZGV2ID0gewoJCS5wbGF0Zm9ybV9kYXRhID0gJm1vY2FfbGFuX2RhdGEsCgkJLnJlbGVhc2UgPSBib2d1c19yZWxlYXNlLAoJfSwKfTsKCnN0YXRpYyBzdHJ1Y3QgbW9jYV9wbGF0Zm9ybV9kYXRhIG1vY2Ffd2FuX2RhdGEgPSB7CgkubWFjYWRkcl9oaSAgICAgICA9IDB4MDAwMDAxMDIsCgkubWFjYWRkcl9sbyAgICAgICA9IDB4MDMwNDAwMDAsCgoJLmJjbTM0NTBfaTJjX2Jhc2UgPSAgMHgxMDQwNjIwMCwKCS5iY20zNDUwX2kyY19hZGRyID0gIDB4NzAsCgkuaHdfcmV2ICA9IEhXUkVWX01PQ0FfMjBfR0VOMjIsCgkuY2hpcF9pZCA9IDAsCgkKCS5yZl9iYW5kID0gTU9DQV9CQU5EX0VYVF9ELAoKCS51c2VfZG1hICAgICAgICAgICA9IDAsCgkudXNlX3NwaSAgICAgICAgICAgPSAxLAoJLmRldklkICAgICAgICAgICAgPSBNT0NBX0RFVklDRV9JRF9VTlJFR0lTVEVSRUQsIC8vIEZpbGxlZCBpbiBkeW5hbWljYWxseQoKI2lmZGVmIENPTkZJR19TTVAKCS5zbXBfcHJvY2Vzc29yX2lkID0gMSwKI2VuZGlmCn07CgpzdGF0aWMgc3RydWN0IHJlc291cmNlIG1vY2Ffd2FuX3Jlc291cmNlc1tdID0gewoJWzBdID0gewoJCS5zdGFydCA9IDB4MTA2MDAwMDAsCgkJLmVuZCA9ICAgMHgxMDdmZmQ5NywKCQkuZmxhZ3MgPSBJT1JFU09VUkNFX01FTSwKCX0sCglbMV0gPSB7IC8qIE5vdCB1c2VkIGZvciA2ODAyLCBkZWZpbmUgZm9yIGJtb2NhICovCgkJLnN0YXJ0ID0gMCwKCQkuZW5kID0gMCwKCQkuZmxhZ3MgPSBJT1JFU09VUkNFX0lSUSwKCX0KfTsKCnN0YXRpYyBzdHJ1Y3QgcGxhdGZvcm1fZGV2aWNlIG1vY2Ffd2FuX3BsYXRfZGV2ID0gewoJLm5hbWUgICAgICAgICAgPSAiYm1vY2EiLAoJLmlkICAgICAgICAgICAgPSAxLAoJLm51bV9yZXNvdXJjZXMgPSBBUlJBWV9TSVpFKG1vY2Ffd2FuX3Jlc291cmNlcyksCgkucmVzb3VyY2UgICAgICA9IG1vY2Ffd2FuX3Jlc291cmNlcywKCS5kZXYgICAgICAgICAgID0gewoJCS5wbGF0Zm9ybV9kYXRhID0gJm1vY2Ffd2FuX2RhdGEsCgkJLnJlbGVhc2UgICAgICAgPSBib2d1c19yZWxlYXNlLAoJfSwKfTsKCnN0YXRpYyB2b2lkIG1vY2FfZW5hYmxlX2lycShzdHJ1Y3QgbW9jYV9wcml2X2RhdGEgKnByaXYpCnsKCWtlclN5c01vY2FIb3N0SW50ckVuYWJsZSgoKHN0cnVjdCBtb2NhX3BsYXRmb3JtX2RhdGEgKilwcml2LT5wZGV2LT5kZXYucGxhdGZvcm1fZGF0YSktPnNwaSk7Cn0KCnN0YXRpYyB2b2lkIG1vY2FfZGlzYWJsZV9pcnEoc3RydWN0IG1vY2FfcHJpdl9kYXRhICpwcml2KQp7CglrZXJTeXNNb2NhSG9zdEludHJEaXNhYmxlKCgoc3RydWN0IG1vY2FfcGxhdGZvcm1fZGF0YSAqKXByaXYtPnBkZXYtPmRldi5wbGF0Zm9ybV9kYXRhKS0+c3BpKTsKfQoKc3RhdGljIHZvaWQgbW9jYV9wbWJfYnVzeV93YWl0KHN0cnVjdCBtb2NhX3ByaXZfZGF0YSAqcHJpdikKewoJI2lmIDAKCXVpbnQzMl90IGRhdGE7CgoJLyogUG9zc2libGUgdGltZSBzYXZlcjogVGhlIHJlZ2lzdGVyIGFjY2VzcyB0aW1lIG92ZXIgU1BJIG1heSAKCSAgIGFsd2F5cyBiZSBlbm91Z2ggdG8gZ3VhcmFudGVlIHRoYXQgdGhlIHdyaXRlIHdpbGwgY29tcGxldGUgCgkgICBpbiB0aW1lIHdpdGhvdXQgaGF2aW5nIHRvIGNoZWNrIHRoZSBzdGF0dXMuICovCglkbwoJewoJCWRhdGEgPSBNT0NBX1JEKHByaXYtPmJhc2UgKyBwcml2LT5yZWdzLT5wbWJfbWFzdGVyX3N0YXR1cyk7Cgl9IHdoaWxlIChkYXRhICYgMHgxKTsKCSNlbmRpZgp9CgpzdGF0aWMgdm9pZCBtb2NhX3BtYl9jb250cm9sKHN0cnVjdCBtb2NhX3ByaXZfZGF0YSAqcHJpdiwgUE1CX0NPTU1BTkRfRSBjbWQpCnsKCWludCBpLCBqOwoJdWludDMyX3QgKiBwX3pvbmVfY29udHJvbDsKCXVpbnQzMl90IGRhdGE7CgoJc3dpdGNoIChjbWQpCgl7CgkJY2FzZSBQTUJfQ09NTUFORF9BTExfT0ZGOgoJCQkvLyBUdXJuIG9mZiB6b25lIGNvbW1hbmQKCQkJTU9DQV9XUihwcml2LT5iYXNlICsgcHJpdi0+cmVncy0+cG1iX21hc3Rlcl93ZGF0YV9vZmZzZXQsIDB4QTAwKTsKCQkJcF96b25lX2NvbnRyb2wgPSAmem9uZV9vZmZfYml0bWFza1swXTsKCQkJYnJlYWs7CgkJY2FzZSBQTUJfQ09NTUFORF9BTExfT046CgkJCS8vIFR1cm4gb24gem9uZSBjb21tYW5kCgkJCU1PQ0FfV1IocHJpdi0+YmFzZSArIHByaXYtPnJlZ3MtPnBtYl9tYXN0ZXJfd2RhdGFfb2Zmc2V0LCAweEMwMCk7CgkJCXBfem9uZV9jb250cm9sID0gJnpvbmVfb25fYml0bWFza1swXTsKCQkJYnJlYWs7CgkJZGVmYXVsdDoKCQkJcHJpbnRrKEtFUk5fV0FSTklORyAiJXM6IGlsbGVnYWwgY21kOiAlMDh4XG4iLAoJCQkJX19GVU5DVElPTl9fLCBjbWQpOwoJCQlyZXR1cm47Cgl9CgoJZm9yIChpID0gMDsgaSA8IE1PQ0FfQlBDTV9OVU07IGkrKykKCXsKCQlmb3IgKGogPSAwOyBqIDwgTU9DQV9CUENNX1pPTkVTX05VTTsgaisrKQoJCXsKCQkJaWYgKCpwX3pvbmVfY29udHJvbCAmICgxIDw8IGopKQoJCQl7CgkJCQkvLyB6b25lIGFkZHJlc3MgaW4gYnBjbXMKCQkJCWRhdGEgPSAoMHgxIDw8IDIwKSArIDE2ICsgKGkgKiA0MDk2KSArIChqICogNCk7CgkJCQlNT0NBX1dSKHByaXYtPmJhc2UgKyBwcml2LT5yZWdzLT5wbWJfbWFzdGVyX2NtZF9vZmZzZXQsIGRhdGEpOwoJCQkJbW9jYV9wbWJfYnVzeV93YWl0KHByaXYpOwoJCQl9CgkJfQoJCXBfem9uZV9jb250cm9sKys7Cgl9Cgp9CgpzdGF0aWMgdm9pZCBtb2NhX3BtYl9naXZlX2Z3X2NudHJsKHN0cnVjdCBtb2NhX3ByaXZfZGF0YSAqcHJpdikKewoJLyogUGFzcyBjb250cm9sIG92ZXIgdGhlIG1lbW9yaWVzIHRvIHRoZSBGVyAqLwoJTU9DQV9XUihwcml2LT5iYXNlICsgcHJpdi0+cmVncy0+cG1iX21hc3Rlcl93ZGF0YV9vZmZzZXQsIDB4MSk7CglNT0NBX1dSKHByaXYtPmJhc2UgKyBwcml2LT5yZWdzLT5wbWJfbWFzdGVyX2NtZF9vZmZzZXQsIDB4MTAwMDAyKTsKCW1vY2FfcG1iX2J1c3lfd2FpdChwcml2KTsKfQoKc3RhdGljIHZvaWQgbW9jYV9od19yZXNldChzdHJ1Y3QgbW9jYV9wcml2X2RhdGEgKnByaXYpCnsKLy8JdW5zaWduZWQgbG9uZyBmbGFnczsKLy8gICB1aW50MzJfdCBjaGlwaWQ7CgoJLyogZGlzYWJsZSBhbmQgY2xlYXIgYWxsIGludGVycnVwdHMgKi8KCU1PQ0FfV1IocHJpdi0+YmFzZSArIHByaXYtPnJlZ3MtPmwyX21hc2tfc2V0X29mZnNldCwgMHhmZmZmZmZmZik7CglNT0NBX1JEKHByaXYtPmJhc2UgKyBwcml2LT5yZWdzLT5sMl9tYXNrX3NldF9vZmZzZXQpOwoKCS8qIGFzc2VydCByZXNldHMgKi8KCgkvKiByZXNldCBDUFUgZmlyc3QsIGJvdGggQ1BVcyBmb3IgTW9DQSAyMCBIVyAqLwoJaWYgKHByaXYtPmh3X3JldiA9PSBIV1JFVl9NT0NBXzIwX0dFTjIyKQoJCU1PQ0FfU0VUKHByaXYtPmJhc2UgKyBwcml2LT5yZWdzLT5zd19yZXNldF9vZmZzZXQsIDUpOwoJZWxzZQoJCU1PQ0FfU0VUKHByaXYtPmJhc2UgKyBwcml2LT5yZWdzLT5zd19yZXNldF9vZmZzZXQsIDEpOwoKCU1PQ0FfUkQocHJpdi0+YmFzZSArIHByaXYtPnJlZ3MtPnN3X3Jlc2V0X29mZnNldCk7CgoJdWRlbGF5KDIwKTsKCgkvKiByZXNldCBldmVyeXRoaW5nIGVsc2UgZXhjZXB0IGNsb2NrcyAqLwoJTU9DQV9TRVQocHJpdi0+YmFzZSArIHByaXYtPnJlZ3MtPnN3X3Jlc2V0X29mZnNldCwgfigoMSA8PCAzKSB8ICgxIDw8IDcpKSk7CglNT0NBX1JEKHByaXYtPmJhc2UgKyBwcml2LT5yZWdzLT5zd19yZXNldF9vZmZzZXQpOwoKCXVkZWxheSgyMCk7CgoJLyogZGlzYWJsZSBjbG9ja3MgKi8KCU1PQ0FfU0VUKHByaXYtPmJhc2UgKyBwcml2LT5yZWdzLT5zd19yZXNldF9vZmZzZXQsIH4oMSA8PCAzKSk7CglNT0NBX1JEKHByaXYtPmJhc2UgKyBwcml2LT5yZWdzLT5zd19yZXNldF9vZmZzZXQpOwoKCU1PQ0FfV1IocHJpdi0+YmFzZSArIHByaXYtPnJlZ3MtPmwyX2NsZWFyX29mZnNldCwgMHhmZmZmZmZmZik7CglNT0NBX1JEKHByaXYtPmJhc2UgKyBwcml2LT5yZWdzLT5sMl9jbGVhcl9vZmZzZXQpOwoKCS8qIFBvd2VyIGRvd24gYWxsIHpvbmVzICovCgltb2NhX3BtYl9jb250cm9sKHByaXYsIFBNQl9DT01NQU5EX0FMTF9PRkYpOwoKCS8qIFBvd2VyIGRvd24gYWxsIFNZU19DVFJMIG1lbW9yaWVzICovCglNT0NBX1dSKDB4MTAxMDAwNjgsIDEpOyAgIC8vIENMS0dFTl9QTExfU1lTMV9QTExfUFdSRE4KCU1PQ0FfU0VUKDB4MTAxMDAwMGMsIDEpOyAgLy8gQ0xLR0VOX1BMTF9TWVMwX1BMTF9DSEFOTkVMX0NUUkxfQ0hfMwoKfQoKc3RhdGljIHVuc2lnbmVkIGludCBtb2NhX2dldF9waHlfZnJlcShzdHJ1Y3QgbW9jYV9wcml2X2RhdGEgKnByaXYpCnsKCXVuc2lnbmVkIGludCB4ID0gTU9DQV9SRCgweDEwMTAwMDQ0KTsgLy8gQ0xLR0VOX1BMTF9TWVMxX1BMTF9DSEFOTkVMX0NUUkxfQ0hfMgoKCXggPSAoeCA+PiAxKSAmIDB4RkY7IC8vIEdldCB0aGUgTURJVl9DSDIgZmllbGQKCglyZXR1cm4oIHggPyAyNDAwIC8geCA6IDApOwp9CgovKiBjYWxsZWQgYW55IHRpbWUgd2Ugc3RhcnQvcmVzdGFydC9zdG9wIE1vQ0EgKi8Kc3RhdGljIHZvaWQgbW9jYV9od19pbml0KHN0cnVjdCBtb2NhX3ByaXZfZGF0YSAqcHJpdiwgaW50IGFjdGlvbikKewoJdTMyIG1hc2s7Cgl1MzIgdGVtcDsKCXUzMiBkYXRhOwoJdTMyIGNvdW50ID0gMDsKCXN0cnVjdCBtb2NhX3BsYXRmb3JtX2RhdGEgKiBwTW9jYURhdGEgPSAoc3RydWN0IG1vY2FfcGxhdGZvcm1fZGF0YSAqKXByaXYtPnBkZXYtPmRldi5wbGF0Zm9ybV9kYXRhOwoKCWlmIChhY3Rpb24gPT0gTU9DQV9FTkFCTEUgJiYgIXByaXYtPmVuYWJsZWQpIHsKCQljbGtfZW5hYmxlKHByaXYtPmNsayk7CgoJCU1PQ0FfV1IoMHgxMDQwNDMxOCwgMHhmZmZmZmZmZCk7IC8vIFNVTl9UT1BfQ1RSTF9TV19JTklUXzBfU0VUCgkJdWRlbGF5KDIwKTsKCQlNT0NBX1dSKDB4MTA0MDQzMWMsIDB4ZmZmZmZmZmYpOyAvLyBTVU5fVE9QX0NUUkxfU1dfSU5JVF8wX0NMRUFSIC0tPiBEbyB0aGlzIGF0IHN0YXJ0IG9mIHNlcXVlbmNlCgkJdWRlbGF5KDIwKTsKICAgCgkJcHJpdi0+ZW5hYmxlZCA9IDE7Cgl9CgoJLyogY2xvY2sgbm90IGVuYWJsZWQsIHJlZ2lzdGVyIGFjY2Vzc2VzIHdpbGwgZmFpbCB3aXRoIGJ1cyBlcnJvciAqLwoJaWYgKCFwcml2LT5lbmFibGVkKQoJCXJldHVybjsKCgltb2NhX2h3X3Jlc2V0KHByaXYpOwoJdWRlbGF5KDEpOwoKCU1PQ0FfV1IoMHgxMDgwMDAwMCwgMHgwMyk7ICAgICAgIC8vIEVNVVhfQ05UUkwKCU1PQ0FfV1IoMHgxMDgwMDAwYywgMHgxMSk7ICAgICAgIC8vIFJHTUlJXzBfQ05UUkwKCU1PQ0FfV1IoMHgxMDgwMDAxNCwgMHhjMCk7ICAgICAgIC8vIFJHTUlJXzBfUlhfQ0xLX0RFTEFZX0NOVFJMCgoJTU9DQV9XUigweDEwNDA0MGE0LCAweDAxKTsgICAgICAgLy8gR0VORVJBTF9DVFJMX05PX1NDQU5fMAoJTU9DQV9XUigweDEwNDA0MTAwLCAweDExMTEwMDExKTsgLy8gUElOX01VWF9DVFJMXzAKCU1PQ0FfV1IoMHgxMDQwNDEwNCwgMHgxMTExMTExMSk7IC8vIFBJTl9NVVhfQ1RSTF8xCgoJaWYgKGFjdGlvbiA9PSBNT0NBX0VOQUJMRSkgewoKCQkvKiBQb3dlciB1cCBhbGwgem9uZXMgKi8KCQltb2NhX3BtYl9jb250cm9sKHByaXYsIFBNQl9DT01NQU5EX0FMTF9PTik7CgkJbW9jYV9wbWJfZ2l2ZV9md19jbnRybChwcml2KTsKCgkJTU9DQV9VTlNFVCgweDEwMTAwMDBjLCAxKTsgIC8vIENMS0dFTl9QTExfU1lTMF9QTExfQ0hBTk5FTF9DVFJMX0NIXzMgCgoJCU1PQ0FfV1IoMHgxMDEwMDA2QywgMSk7ICAvLyBDTEtHRU5fUExMX1NZUzFfUExMX1JFU0VUIAoJCU1PQ0FfV1IoMHgxMDEwMDA2OCwgMCk7ICAvLyBDTEtHRU5fUExMX1NZUzFfUExMX1BXUkROIAoJCWRhdGEgPSAwOwoJCXdoaWxlICgoZGF0YSAmIDB4MSkgPT0gMCkKCQl7CgkJCS8qIFRoaXMgdHlwaWNhbGx5IGlzIG9ubHkgcmVhZCBvbmNlICovCgkJCWRhdGEgPSBNT0NBX1JEKDB4MTAxMDAwNjApOyAvLyBDTEtHRU5fUExMX1NZUzFfUExMX0xPQ0tfU1RBVFVTCgoJCQlpZiAoY291bnQrKyA+IDEwKQoJCQkJYnJlYWs7CgkJfQoJCU1PQ0FfV1IoMHgxMDEwMDA2QywgMCk7ICAvLyBDTEtHRU5fUExMX1NZUzFfUExMX1JFU0VUIAoKCQlpZiAocHJpdi0+Ym9uZGVkX21vZGUpIHsKCQkJTU9DQV9VTlNFVCgweDEwMTAwMDQ4LCAxKTsgIC8vIENMS0dFTl9QTExfU1lTMV9QTExfQ0hBTk5FTF9DVFJMX0NIXzMgCgkJCU1PQ0FfVU5TRVQoMHgxMDEwMDA1MCwgMSk7ICAvLyBDTEtHRU5fUExMX1NZUzFfUExMX0NIQU5ORUxfQ1RSTF9DSF81IAoJCX0gZWxzZSB7CgkJCU1PQ0FfU0VUKDB4MTAxMDAwNDgsIDEpOyAgLy8gQ0xLR0VOX1BMTF9TWVMxX1BMTF9DSEFOTkVMX0NUUkxfQ0hfMyAKCQkJTU9DQV9TRVQoMHgxMDEwMDA1MCwgMSk7ICAvLyBDTEtHRU5fUExMX1NZUzFfUExMX0NIQU5ORUxfQ1RSTF9DSF81IAoJCX0KCQl1ZGVsYXkoMSk7CgoJCS8qIGRlYXNzZXJ0IG1vY2Ffc3lzX3Jlc2V0LCBzeXN0ZW0gY2xvY2ssIHBoeTAgYW5kIHBoeTAgY2xvY2sgKi8KCQltYXNrID0gKDEgPDwgMSkgfCAoMSA8PCA3KSB8ICgxIDw8IDQpIHwgKDEgPDwgOCk7CgoJCS8qIGRlYXNzZXJ0IHBoeTEgYW5kIHBoeTEgY2xvY2sgaW4gYm9uZGVkIG1vZGUgKi8KCQlpZiAocHJpdi0+Ym9uZGVkX21vZGUpCgkJCW1hc2sgfD0gKDEgPDwgNSkgfCAoMSA8PCA5KTsKCgkJTU9DQV9VTlNFVChwcml2LT5iYXNlICsgcHJpdi0+cmVncy0+c3dfcmVzZXRfb2Zmc2V0LCBtYXNrKTsKCQlNT0NBX1JEKHByaXYtPmJhc2UgKyBwcml2LT5yZWdzLT5zd19yZXNldF9vZmZzZXQpOwoKCgkJLyogQ2hlY2sgZm9yIDY4MDIvNjgwMyBBMCBjaGlwIG9ubHkgd2l0aCBYdGFsIG1vZCAqLwoJCWlmICgocE1vY2FEYXRhLT5jaGlwX2lkICYgMHhGRkZFRkZGRikgPT0gMHg2ODAyMDBBMCkKCQl7CgkJCWRhdGEgPSBNT0NBX1JEKDB4MTA0MDQwMWMpOwoJCQlpZiAoKGRhdGEgJiAweDcpID09IDB4MikgewoJCQkJLyogMjVNSHogKi8KCQkJCXByaW50aygiTW9DQSBydW5uaW5nIHdpdGggMjVNSHogWFRBTFxuIik7CgkJCQlNT0NBX1dSKHByaXYtPmJhc2UgKyBwcml2LT5yZWdzLT5ob3N0Mm1vY2FfbW1wX291dGJveF8wX29mZnNldCwgMSk7CgkJCX0gZWxzZSB7CgkJCQlwcmludGsoIk1vQ0EgPT0gNTBNSHogWFRBTFxuIik7CgkJCQkvKiA1ME1IeiBjbG9jayBjaGFuZ2Ugb25seSAqLwoJCQkJTU9DQV9XUihwcml2LT5iYXNlICsgcHJpdi0+cmVncy0+aG9zdDJtb2NhX21tcF9vdXRib3hfMF9vZmZzZXQsIDApOwoJCQkJLy9Ob3RlOiBUaGUgcmUtY29uZmlndXJhdGlvbiBpcyBpbiBORElWX0lOVCwgbm90IFBESVYuCgkJCQkvL2BDTEtHRU5fUkVHX1NUQVJUICsgYENMS0dFTl9QTExfU1lTMV9QTExfRElWICgzMidoMTAxMDAwNTgpIFswOTowMF0gPSAxMJJkNDgKCQkJCXRlbXAgPSBNT0NBX1JEKDB4MTAxMDAwNTgpOwoJCQkJdGVtcCA9ICh0ZW1wICYgMHhGRkZGRkMwMCkgKyA0ODsKCQkJCU1PQ0FfV1IoMHgxMDEwMDA1OCwgdGVtcCk7CgoJCQkJLy9gQ0xLR0VOX1JFR19TVEFSVCArIGBDTEtHRU5fUExMX1NZUzBfUExMX0RJViAoMzInaDEwMTAwMDE4KSBbMDk6MDBdID0gMTCSZDQwCgkJCQl0ZW1wID0gTU9DQV9SRCgweDEwMTAwMDE4KTsKCQkJCXRlbXAgPSAodGVtcCAmIDB4RkZGRkZDMDApICsgNDA7CgkJCQlNT0NBX1dSKDB4MTAxMDAwMTgsIHRlbXApOwoKCQkJCS8vYENMS0dFTl9SRUdfU1RBUlQgKyBgQ0xLR0VOX1BMTF9TWVMxX1BMTF9DSEFOTkVMX0NUUkxfQ0hfNCAoMzInaDEwMTAwMDRDKSBbMDg6MDFdID0gOJJkNDgKCQkJCXRlbXAgPSBNT0NBX1JEKDB4MTAxMDAwNGMpOwoJCQkJdGVtcCA9ICh0ZW1wICYgMHhGRkZGRkUwMSkgKyAoNDggPDwgMSk7CgkJCQlNT0NBX1dSKDB4MTAxMDAwNGMsIHRlbXApOwoKCQkJCS8vYENMS0dFTl9SRUdfU1RBUlQgKyBgQ0xLR0VOX1BMTF9TWVMxX1BMTF9DSEFOTkVMX0NUUkxfQ0hfNSAoMzInaDEwMTAwMDUwKSBbMDg6MDFdID0gOJJkNDgKCQkJCXRlbXAgPSBNT0NBX1JEKDB4MTAxMDAwNTApOwoJCQkJdGVtcCA9ICh0ZW1wICYgMHhGRkZGRkUwMSkgKyAoNDggPDwgMSk7CgkJCQlNT0NBX1dSKDB4MTAxMDAwNTAsIHRlbXApOwoKCQkJCS8vIFRoZW4gUmVzdGFydCB0aGUgUExMLgoKCQkJCS8vYENMS0dFTl9SRUdfU1RBUlQgKyBgQ0xLR0VOX1BMTF9TWVMwX1BMTF9SRVNFVCAoMzInaDEwMTAwMDJDKSBbMF0gPSAxkmIxCgkJCQlNT0NBX1NFVCgweDEwMTAwMDJjLCAxKTsKCQkJCS8vYENMS0dFTl9SRUdfU1RBUlQgKyBgQ0xLR0VOX1BMTF9TWVMxX1BMTF9SRVNFVCAoMzInaDEwMTAwMDZDKSBbMF0gPSAxkmIxCgkJCQlNT0NBX1NFVCgweDEwMTAwMDZjLCAxKTsKCgkJCQl1ZGVsYXkoMSk7CgoJCQkJLy9gQ0xLR0VOX1JFR19TVEFSVCArIGBDTEtHRU5fUExMX1NZUzBfUExMX1JFU0VUICgzMidoMTAxMDAwMkMpIFswXSA9IDGSYjAKCQkJCU1PQ0FfVU5TRVQoMHgxMDEwMDAyYywgMSk7CgkJCQkvL2BDTEtHRU5fUkVHX1NUQVJUICsgYENMS0dFTl9QTExfU1lTMV9QTExfUkVTRVQgKDMyJ2gxMDEwMDA2QykgWzBdID0gMZJiMAoJCQkJTU9DQV9VTlNFVCgweDEwMTAwMDZjLCAxKTsKCQkJfQoJCX0KCgkJLy8gQ0xLR0VOX1BMTF9TWVMxX1BMTF9TU0NfTU9ERV9DT05UUk9MX0hJR0gKCQlkYXRhID0gTU9DQV9SRCgweDEwMTAwMDcwKTsKCQlkYXRhID0gKGRhdGEgJiAweEZGRkYwMDAwKSB8IDB4N2RkOwoJCU1PQ0FfV1IoMHgxMDEwMDA3MCwgZGF0YSk7CgoJCS8vIENMS0dFTl9QTExfU1lTMV9QTExfU1NDX01PREVfQ09OVFJPTF9MT1cKCQlkYXRhID0gTU9DQV9SRCgweDEwMTAwMDc0KTsKCQlkYXRhID0gKGRhdGEgJiAweGZmYzAwMDAwKSB8IDB4M2Q3MTsKCQlNT0NBX1dSKDB4MTAxMDAwNzQsIGRhdGEpOwoKCQkvLyBDTEtHRU5fUExMX1NZUzFfUExMX1NTQ19NT0RFX0NPTlRST0xfTE9XCgkJTU9DQV9TRVQoMHgxMDEwMDA3NCwgKDEgPDwgMjIpKTsKCQkKCQlwcmludGsoIlNldCBQTEwgU1NDIG1vZGVcbiIpOwoJfQoKCglpZiAocHJpdi0+aHdfcmV2IDw9IEhXUkVWX01PQ0FfMjBfR0VOMjEpIHsKCS8qIGNsZWFyIGp1bmsgb3V0IG9mIEdQMC9HUDEgKi8KCQlNT0NBX1dSKHByaXYtPmJhc2UgKyBwcml2LT5yZWdzLT5ncDBfb2Zmc2V0LCAweGZmZmZmZmZmKTsKCQlNT0NBX1dSKHByaXYtPmJhc2UgKyBwcml2LT5yZWdzLT5ncDFfb2Zmc2V0LCAweDApOwoJCS8qIHNldCB1cCBhY3Rpdml0eSBMRUQgZm9yIDUwJSBkdXR5IGN5Y2xlICovCgkJTU9DQV9XUihwcml2LT5iYXNlICsgcHJpdi0+cmVncy0+bGVkX2N0cmxfb2Zmc2V0LAoJCQkweDQwMDA0MDAwKTsKCX0KCgkvKiBlbmFibGUgRE1BIGNvbXBsZXRpb24gaW50ZXJydXB0cyAqLwoJbWFzayA9IE0ySF9SRVEgfCBNMkhfUkVTUCB8IE0ySF9BU1NFUlQgfCBNMkhfV0RUX0NQVTEgfAoJCU0ySF9ORVhUQ0hVTksgfCBNMkhfRE1BOwoKCWlmIChwcml2LT5od19yZXYgPj0gSFdSRVZfTU9DQV8yMF9HRU4yMSkKCQltYXNrIHw9IE0ySF9XRFRfQ1BVMCB8IE0ySF9ORVhUQ0hVTktfQ1BVMCB8CgkJCU0ySF9SRVFfQ1BVMCB8IE0ySF9SRVNQX0NQVTAgfCBNMkhfQVNTRVJUX0NQVTA7CgoJTU9DQV9XUihwcml2LT5iYXNlICsgcHJpdi0+cmVncy0+cmluZ2JlbGxfb2Zmc2V0LCAwKTsKCU1PQ0FfV1IocHJpdi0+YmFzZSArIHByaXYtPnJlZ3MtPmwyX21hc2tfY2xlYXJfb2Zmc2V0LCBtYXNrKTsKCU1PQ0FfUkQocHJpdi0+YmFzZSArIHByaXYtPnJlZ3MtPmwyX21hc2tfY2xlYXJfb2Zmc2V0KTsKCgoJLyogU2V0IHBpbm11eGluZyBmb3IgTW9DQSBpbnRlcnJ1cHQgYW5kIGZsb3cgY29udHJvbCAqLwoJTU9DQV9VTlNFVCgweDEwNDA0MTEwLCAweEYwMDAwMEZGKTsKCU1PQ0FfU0VUKDB4MTA0MDQxMTAsIDB4MTAwMDAwMjIpOwogCglNT0NBX1dSKDB4MTAwYjAzMTgsIDIpOwoKCWlmIChhY3Rpb24gPT0gTU9DQV9ESVNBQkxFICYmIHByaXYtPmVuYWJsZWQpIHsKCQlwcml2LT5lbmFibGVkID0gMDsKCQljbGtfZGlzYWJsZShwcml2LT5jbGspOwoJfQp9CgpzdGF0aWMgdm9pZCBtb2NhX3JpbmdiZWxsKHN0cnVjdCBtb2NhX3ByaXZfZGF0YSAqcHJpdiwgdWludDMyX3QgbWFzaykKewoJTU9DQV9XUihwcml2LT5iYXNlICsgcHJpdi0+cmVncy0+cmluZ2JlbGxfb2Zmc2V0LCBtYXNrKTsKfQoKc3RhdGljIHVpbnQzMl90IG1vY2Ffc3RhcnRfbWlwcyhzdHJ1Y3QgbW9jYV9wcml2X2RhdGEgKnByaXYsIHVuc2lnbmVkIGludCBjcHUpCnsKCWlmIChwcml2LT5od19yZXYgPT0gSFdSRVZfTU9DQV8yMF9HRU4yMikgewoJCWlmIChjcHUgPT0gMSkKCQkJTU9DQV9VTlNFVChwcml2LT5iYXNlICsgcHJpdi0+cmVncy0+c3dfcmVzZXRfb2Zmc2V0LAoJCQkJKDEgPDwgMCkpOwoJCWVsc2UgewoJCQltb2NhX21tcF9pbml0KHByaXYsIDEpOwoJCQlNT0NBX1VOU0VUKHByaXYtPmJhc2UgKyBwcml2LT5yZWdzLT5zd19yZXNldF9vZmZzZXQsCgkJCQkoMSA8PCAyKSk7CgkJfQoJfSBlbHNlCgkJTU9DQV9VTlNFVChwcml2LT5iYXNlICsgcHJpdi0+cmVncy0+c3dfcmVzZXRfb2Zmc2V0LCAoMSA8PCAwKSk7CglNT0NBX1JEKHByaXYtPmJhc2UgKyBwcml2LT5yZWdzLT5zd19yZXNldF9vZmZzZXQpOwoKCXJldHVybigwKTsKfQoKc3RhdGljIHZvaWQgbW9jYV9tMm1feGZlcihzdHJ1Y3QgbW9jYV9wcml2X2RhdGEgKnByaXYsCgl1aW50MzJfdCBkc3QsIHVpbnQzMl90IHNyYywgdWludDMyX3QgY3RsKQp7Cgl1aW50MzJfdCBzdGF0dXM7CgoJTU9DQV9XUihwcml2LT5iYXNlICsgcHJpdi0+cmVncy0+bTJtX3NyY19vZmZzZXQsIHNyYyk7CglNT0NBX1dSKHByaXYtPmJhc2UgKyBwcml2LT5yZWdzLT5tMm1fZHN0X29mZnNldCwgZHN0KTsKCU1PQ0FfV1IocHJpdi0+YmFzZSArIHByaXYtPnJlZ3MtPm0ybV9zdGF0dXNfb2Zmc2V0LCAwKTsKCU1PQ0FfUkQocHJpdi0+YmFzZSArIHByaXYtPnJlZ3MtPm0ybV9zdGF0dXNfb2Zmc2V0KTsKCU1PQ0FfV1IocHJpdi0+YmFzZSArIHByaXYtPnJlZ3MtPm0ybV9jbWRfb2Zmc2V0LCBjdGwpOwoKCWRvIHsKCQlzdGF0dXMgPSBNT0NBX1JEKHByaXYtPmJhc2UgKyBwcml2LT5yZWdzLT5tMm1fc3RhdHVzX29mZnNldCk7Cgl9IHdoaWxlKHN0YXR1cyA9PSAwKTsKCn0KCnN0YXRpYyB2b2lkIG1vY2Ffd3JpdGVfbWVtKHN0cnVjdCBtb2NhX3ByaXZfZGF0YSAqcHJpdiwKCXVpbnQzMl90IGRzdF9vZmZzZXQsIHZvaWQgKnNyYywgdW5zaWduZWQgaW50IGxlbikKewoJc3RydWN0IG1vY2FfcGxhdGZvcm1fZGF0YSAqcGQgPSBwcml2LT5wZGV2LT5kZXYucGxhdGZvcm1fZGF0YTsKCglpZigoZHN0X29mZnNldCA+PSBwcml2LT5yZWdzLT5jbnRsX21lbV9vZmZzZXQrcHJpdi0+cmVncy0+Y250bF9tZW1fc2l6ZSkgfHwKCQkoKGRzdF9vZmZzZXQgKyBsZW4pID4gcHJpdi0+cmVncy0+Y250bF9tZW1fb2Zmc2V0K3ByaXYtPnJlZ3MtPmNudGxfbWVtX3NpemUpKSB7CgkJcHJpbnRrKEtFUk5fV0FSTklORyAiJXM6IGNvcHkgcGFzdCBlbmQgb2YgY250bCBtZW1vcnk6ICUwOHhcbiIsCgkJCV9fRlVOQ1RJT05fXywgZHN0X29mZnNldCk7CgkJcmV0dXJuOwoJfQoKCWlmICggMSA9PSBwZC0+dXNlX2RtYSApCgl7CgkJZG1hX2FkZHJfdCBwYTsKCgkJcGEgPSBkbWFfbWFwX3NpbmdsZSgmcHJpdi0+cGRldi0+ZGV2LCBzcmMsIGxlbiwgRE1BX1RPX0RFVklDRSk7CgkJbXV0ZXhfbG9jaygmcHJpdi0+Y29weV9tdXRleCk7CgkJbW9jYV9tMm1feGZlcihwcml2LCBkc3Rfb2Zmc2V0ICsgcHJpdi0+cmVncy0+ZGF0YV9tZW1fb2Zmc2V0LCAodWludDMyX3QpcGEsIGxlbiB8IE0yTV9XUklURSk7CgkJbXV0ZXhfdW5sb2NrKCZwcml2LT5jb3B5X211dGV4KTsKCQlkbWFfdW5tYXBfc2luZ2xlKCZwcml2LT5wZGV2LT5kZXYsIHBhLCBsZW4sIERNQV9UT19ERVZJQ0UpOwoJfQoJZWxzZQoJewoJCXVpbnRwdHJfdCBhZGRyID0gKHVpbnRwdHJfdClwcml2LT5iYXNlICsgcHJpdi0+cmVncy0+ZGF0YV9tZW1fb2Zmc2V0ICsgZHN0X29mZnNldDsKCQl1aW50MzJfdCAqZGF0YSA9IHNyYzsKCQlpbnQgaTsKCgkJbXV0ZXhfbG9jaygmcHJpdi0+Y29weV9tdXRleCk7CgkJaWYgKCgoc3RydWN0IG1vY2FfcGxhdGZvcm1fZGF0YSAqKXByaXYtPnBkZXYtPmRldi5wbGF0Zm9ybV9kYXRhKS0+dXNlX3NwaSA9PSAxKQoJCXsKCQkJc3JjID0gZGF0YTsKCQkJTU9DQV9XUl9CTE9DSyhhZGRyLCBzcmMsIGxlbik7CgkJfQoJCWVsc2UKCQl7CgkJCWZvcihpID0gMDsgaSA8IGxlbjsgaSArPSA0LCBhZGRyICs9IDQsIGRhdGErKykKCQkJCU1PQ0FfV1IoYWRkciwgKmRhdGEpOwoJCQlNT0NBX1JEKGFkZHIgLSA0KTsJLyogZmx1c2ggd3JpdGUgKi8KCQl9CgoJCW11dGV4X3VubG9jaygmcHJpdi0+Y29weV9tdXRleCk7Cgl9Cn0KCnN0YXRpYyB2b2lkIG1vY2FfcmVhZF9tZW0oc3RydWN0IG1vY2FfcHJpdl9kYXRhICpwcml2LAoJdm9pZCAqZHN0LCB1aW50MzJfdCBzcmNfb2Zmc2V0LCB1bnNpZ25lZCBpbnQgbGVuKQp7CglzdHJ1Y3QgbW9jYV9wbGF0Zm9ybV9kYXRhICpwZCA9IHByaXYtPnBkZXYtPmRldi5wbGF0Zm9ybV9kYXRhOwogICAgCglpZigoc3JjX29mZnNldCA+PSBwcml2LT5yZWdzLT5jbnRsX21lbV9vZmZzZXQrcHJpdi0+cmVncy0+Y250bF9tZW1fc2l6ZSkgfHwKCQkoKHNyY19vZmZzZXQgKyBsZW4pID4gcHJpdi0+cmVncy0+Y250bF9tZW1fb2Zmc2V0K3ByaXYtPnJlZ3MtPmNudGxfbWVtX3NpemUpKSB7CgkJcHJpbnRrKEtFUk5fV0FSTklORyAiJXM6IGNvcHkgcGFzdCBlbmQgb2YgY250bCBtZW1vcnk6ICUwOHhcbiIsCgkJCV9fRlVOQ1RJT05fXywgc3JjX29mZnNldCk7CgkJcmV0dXJuOwoJfQoKCWlmICggMSA9PSBwZC0+dXNlX2RtYSApCgl7CgkJZG1hX2FkZHJfdCBwYTsKCgkJcGEgPSBkbWFfbWFwX3NpbmdsZSgmcHJpdi0+cGRldi0+ZGV2LCBkc3QsIGxlbiwgRE1BX0ZST01fREVWSUNFKTsKCQltdXRleF9sb2NrKCZwcml2LT5jb3B5X211dGV4KTsKCQltb2NhX20ybV94ZmVyKHByaXYsICh1aW50MzJfdClwYSwgc3JjX29mZnNldCArIHByaXYtPnJlZ3MtPmRhdGFfbWVtX29mZnNldCwgbGVuIHwgTTJNX1JFQUQpOwoJCW11dGV4X3VubG9jaygmcHJpdi0+Y29weV9tdXRleCk7CgkJZG1hX3VubWFwX3NpbmdsZSgmcHJpdi0+cGRldi0+ZGV2LCBwYSwgbGVuLCBETUFfRlJPTV9ERVZJQ0UpOwoJfQoJZWxzZQoJewoJCXVpbnRwdHJfdCBhZGRyID0gcHJpdi0+cmVncy0+ZGF0YV9tZW1fb2Zmc2V0ICsgc3JjX29mZnNldDsKCQl1aW50MzJfdCAqZGF0YSA9IGRzdDsKCQlpbnQgaTsKCgkJbXV0ZXhfbG9jaygmcHJpdi0+Y29weV9tdXRleCk7CgkJaWYgKCgoc3RydWN0IG1vY2FfcGxhdGZvcm1fZGF0YSAqKXByaXYtPnBkZXYtPmRldi5wbGF0Zm9ybV9kYXRhKS0+dXNlX3NwaSA9PSAxKQoJCXsKCQkJTU9DQV9SRF9CTE9DSygodWludHB0cl90KXByaXYtPmJhc2UgKyBhZGRyLCBkc3QsIGxlbik7CgkJfQoJCWVsc2UKCQl7CgkJCWZvcihpID0gMDsgaSA8IGxlbjsgaSArPSA0LCBhZGRyICs9IDQsIGRhdGErKykKCSAJCQkqZGF0YSA9IE1PQ0FfUkQoKHVpbnRwdHJfdClwcml2LT5iYXNlICsgYWRkcik7CgkJfQoJCW11dGV4X3VubG9jaygmcHJpdi0+Y29weV9tdXRleCk7Cgl9Cn0KCnN0YXRpYyB2b2lkIG1vY2Ffd3JpdGVfc2coc3RydWN0IG1vY2FfcHJpdl9kYXRhICpwcml2LAoJdWludDMyX3QgZHN0X29mZnNldCwgc3RydWN0IHNjYXR0ZXJsaXN0ICpzZywgaW50IG5lbnRzKQp7CglpbnQgajsKCXVpbnRwdHJfdCBhZGRyID0gcHJpdi0+cmVncy0+ZGF0YV9tZW1fb2Zmc2V0ICsgZHN0X29mZnNldDsKCXN0cnVjdCBtb2NhX3BsYXRmb3JtX2RhdGEgKnBkID0gcHJpdi0+cGRldi0+ZGV2LnBsYXRmb3JtX2RhdGE7CgoJZG1hX21hcF9zZygmcHJpdi0+cGRldi0+ZGV2LCBzZywgbmVudHMsIERNQV9UT19ERVZJQ0UpOwoKCW11dGV4X2xvY2soJnByaXYtPmNvcHlfbXV0ZXgpOwoJZm9yKGogPSAwOyBqIDwgbmVudHM7IGorKykKCXsKCQlpZiAoIDEgPT0gcGQtPnVzZV9kbWEgKQoJCXsKCQkgICAgLy8gcHJpbnRrKCJYWFggY29weWluZyBwYWdlICVkLCBQQSAlMDh4XG4iLCBqLCAoaW50KXNnW2pdLmRtYV9hZGRyZXNzKTsKCQkJbW9jYV9tMm1feGZlcihwcml2LCBhZGRyLCAodWludDMyX3Qpc2dbal0uZG1hX2FkZHJlc3MsIAoJCQkJc2dbal0ubGVuZ3RoIHwgTTJNX1dSSVRFKTsKCgkJCWFkZHIgKz0gc2dbal0ubGVuZ3RoOwoJCX0KCQllbHNlCgkJewoJCQl1bnNpZ25lZCBsb25nICpkYXRhID0gKHZvaWQgKilwaHlzX3RvX3ZpcnQoc2dbal0uZG1hX2FkZHJlc3MpOwogICAgICAgICAvL3ByaW50aygiJXM6IFdyaXRpbmcgMHglbHggdG8gYWRkciAweCUwOGx4IChsZW4gPSAlZClcbiIsIF9fRlVOQ1RJT05fXywgKmRhdGEsICgodW5zaWduZWQgbG9uZylwcml2LT5iYXNlKSArIGFkZHIsIHNnW2pdLmxlbmd0aCk7CgkJCU1PQ0FfV1JfQkxPQ0soKCh1bnNpZ25lZCBsb25nKXByaXYtPmJhc2UpICsgYWRkciwgZGF0YSwgc2dbal0ubGVuZ3RoKTsKCQkJYWRkciArPSBzZ1tqXS5sZW5ndGg7CgkJfQoJfQoJbXV0ZXhfdW5sb2NrKCZwcml2LT5jb3B5X211dGV4KTsKCglkbWFfdW5tYXBfc2coJnByaXYtPnBkZXYtPmRldiwgc2csIG5lbnRzLCBETUFfVE9fREVWSUNFKTsKfQoKLyogTk9URTogdGhpcyBmdW5jdGlvbiBpcyBub3QgdGVzdGVkICovCiNpZiAwCnN0YXRpYyB2b2lkIG1vY2FfcmVhZF9zZyhzdHJ1Y3QgbW9jYV9wcml2X2RhdGEgKnByaXYsCgl1aW50MzJfdCBzcmNfb2Zmc2V0LCBzdHJ1Y3Qgc2NhdHRlcmxpc3QgKnNnLCBpbnQgbmVudHMpCnsKCWludCBqOwoJdWludHB0cl90IGFkZHIgPSBwcml2LT5kYXRhX21lbV9vZmZzZXQgKyBzcmNfb2Zmc2V0OwoKCWRtYV9tYXBfc2coJnByaXYtPnBkZXYtPmRldiwgc2csIG5lbnRzLCBETUFfRlJPTV9ERVZJQ0UpOwoKCW11dGV4X2xvY2soJnByaXYtPmNvcHlfbXV0ZXgpOwoJZm9yKGogPSAwOyBqIDwgbmVudHM7IGorKykgewojaWYgMCAvL1VTRV9ETUEKCQkgcHJpbnRrKCJYWFggY29weWluZyBwYWdlICVkLCBQQSAlMDh4XG4iLCBqLCAoaW50KXNnW2pdLmRtYV9hZGRyZXNzKTsKCQltb2NhX20ybV94ZmVyKHByaXYsIGFkZHIsICh1aW50MzJfdClzZ1tqXS5kbWFfYWRkcmVzcywKCQkJc2dbal0ubGVuZ3RoIHwgTTJNX1JFQUQpOwoKCQlhZGRyICs9IHNnW2pdLmxlbmd0aDsKI2Vsc2UKCQl1aW50MzJfdCAqZGF0YSA9ICh2b2lkICopcGh5c190b192aXJ0KHNnW2pdLmRtYV9hZGRyZXNzKTsKCQl1bnNpZ25lZCBpbnQgbGVuID0gc2dbal0ubGVuZ3RoOwoJCWludCBpOwoKCQlmb3IoaSA9IDA7IGkgPCBsZW47IGkgKz0gNCwgYWRkciArPSA0LCBkYXRhKyspIHsKCQkJKmRhdGEgPSBjcHVfdG9fYmUzMigKCQkJCU1PQ0FfUkQoKHVpbnRwdHJfdClwcml2LT5iYXNlICsgYWRkcikpOwoJCQkvL3ByaW50aygiTW9DQSBSRUFEOiBBRCAweCV4ICA9IDB4JXggKDB4JXgpXG4iLCAocHJpdi0+YmFzZSArIGFkZHIpLCBNT0NBX1JEKCh1aW50cHRyX3QpcHJpdi0+YmFzZSArIGFkZHIpLCAqZGF0YSk7CgkJIH0KI2VuZGlmCgl9CgltdXRleF91bmxvY2soJnByaXYtPmNvcHlfbXV0ZXgpOwoKCWRtYV91bm1hcF9zZygmcHJpdi0+cGRldi0+ZGV2LCBzZywgbmVudHMsIERNQV9GUk9NX0RFVklDRSk7Cn0KI2VuZGlmCgpzdGF0aWMgdm9pZCBtb2NhX3JlYWRfbWFjX2FkZHIoc3RydWN0IG1vY2FfcHJpdl9kYXRhICpwcml2LCB1aW50MzJfdCAqIGhpLCB1aW50MzJfdCAqIGxvKQp7CglzdHJ1Y3QgbmV0X2RldmljZSAqIHBkZXYgOwoJY2hhcgkJCQkJIG1vY2FOYW1lWzddIDsKCglpZiAocHJpdiA9PSBOVUxMKQoJCXNwcmludGYgKG1vY2FOYW1lLCAibW9jYSV1IiwgMCkgOwoJZWxzZQoJCXNwcmludGYgKG1vY2FOYW1lLCAibW9jYSV1IiwgKChzdHJ1Y3QgbW9jYV9wbGF0Zm9ybV9kYXRhICopcHJpdi0+cGRldi0+ZGV2LnBsYXRmb3JtX2RhdGEpLT5kZXZJZCkgOwoKI2lmIExJTlVYX1ZFUlNJT05fQ09ERSA+PSBLRVJORUxfVkVSU0lPTigyLCA2LCAyOSkKCXBkZXYgPSBkZXZfZ2V0X2J5X25hbWUgKCAmaW5pdF9uZXQsIG1vY2FOYW1lICkgOwojZWxzZQoJcGRldiA9IGRldl9nZXRfYnlfbmFtZSAoIG1vY2FOYW1lICkgOwojZW5kaWYKCglpZiAoKHBkZXYgIT0gTlVMTCkgJiYgKGxvICE9IE5VTEwpICYmIChoaSAhPSBOVUxMKSkgewoJCW1hY190b191MzIoaGksIGxvLCBwZGV2LT5kZXZfYWRkcik7Cgl9Cn0KCgojaWYgZGVmaW5lZChEU0xfTU9DQSkKCi8qCiAqIFRoaXMgaGVscGVyIGZ1bmN0aW9uIHdhcyBhZGRlZCB0byBhbGxvdyB0aGUgZW5ldCBkcml2ZXIgdG8gY29tcGlsZSBpbgogKiBjb25zdW1lciBlbnZpcm9ubWVudCBmb3IgNjh4eCBwcm9maWxlcy4KICovCnZvaWQgbW9jYV9nZXRfZmNfYml0cyh2b2lkICogYXJnLCB1bnNpZ25lZCBsb25nICptb2NhX2ZjX3JlZykKewoJc3RydWN0IG1vY2FfcHJpdl9kYXRhICogICAgIHByaXY7CglzdHJ1Y3QgbW9jYV9wbGF0Zm9ybV9kYXRhICogcE1vY2FEYXRhOwoJdW5zaWduZWQgbG9uZyAgICAgICAgICAgICAgIGZsYWdzOwoKCWlmIChhcmcgPT0gTlVMTCkgewoJCXJldHVybjsKCX0KCglwcml2ID0gKHN0cnVjdCBtb2NhX3ByaXZfZGF0YSAqKSBhcmc7CglwTW9jYURhdGEgPSAoc3RydWN0IG1vY2FfcGxhdGZvcm1fZGF0YSAqKXByaXYtPnBkZXYtPmRldi5wbGF0Zm9ybV9kYXRhOwoKCSptb2NhX2ZjX3JlZyA9IDA7CglpZiAocHJpdiAhPSBOVUxMKQoJewoJCS8qIFdlIGNhbid0IHJlYWQgbW9jYSBjb3JlIHJlZ3MgdW5sZXNzIHRoZSBjb3JlJ3MgY2xvY2tzIGFyZSBvbi4gKi8KCQlzcGluX2xvY2tfaXJxc2F2ZSgmcHJpdi0+Y2xvY2tfbG9jaywgZmxhZ3MpOwoJCWlmIChwcml2LT5ydW5uaW5nKSB7CgkJCSptb2NhX2ZjX3JlZyA9IE1PQ0FfUkQocHJpdi0+YmFzZStwcml2LT5yZWdzLT5zaWRlYmFuZF9nbWlpX2ZjX29mZnNldCk7CgkJfQoJCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJnByaXYtPmNsb2NrX2xvY2ssIGZsYWdzKTsKCX0KfQoKI2VuZGlmIC8qIERTTF9NT0NBICovCgpzdGF0aWMgaW50IF9fZGV2aW5pdCBibW9jYV9zcGlfcHJvYmUoc3RydWN0IHNwaV9kZXZpY2UgKnNwaSkgewoJLy8gVE9ETyhhcGVud2Fycik6IG1hdGNoIG9uZSBzcGkgZGV2aWNlIHRvIG9uZSBtb2NhIGRldmljZSBzdHJ1Y3QuCgkvLyBJIGhhcHBlbiB0byBrbm93IHRoYXQgcmlnaHQgbm93IHRoZSBzeXN0ZW0gb25seSByZWdpc3RlcnMgb25lIG9mCgkvLyBtb2NhX2xhbiBvciBtb2NhX3dhbiwgbmV2ZXIgYm90aCwgYW5kIHRoZXJlIGlzIG5ldmVyIG1vcmUgdGhhbgoJLy8gb25lIG1vY2EgY2hpcCBwcmVzZW50IG9uIG91ciBzeXN0ZW1zLCBzbyB0aGlzIGlzIG9rYXkgZm9yIG5vdy4KCXVpbnQzMl90IHZhbCA9IGtlclN5c0JjbVNwaVNsYXZlUmVhZFJlZzMyKHNwaSwgMHgxMDQwNDAwMCk7Cglwcl9pbmZvKCJibW9jYV9zcGlfcHJvYmUgYnVzPSVkIGNoaXBfc2VsZWN0PSVkOiBpZD0lMDh4ICVzXG4iLAoJCXNwaS0+bWFzdGVyLT5idXNfbnVtLCBzcGktPmNoaXBfc2VsZWN0LCB2YWwsCgkJdmFsICE9IDAgPyAieWVzIiA6ICJubyIpOwoJaWYgKHZhbCA9PSAwKSByZXR1cm4gLUVOT0RFVjsKCW1vY2FfbGFuX2RhdGEuc3BpID0gc3BpOwoJbW9jYV93YW5fZGF0YS5zcGkgPSBzcGk7CglyZXR1cm4gMDsgLy8gc3VjY2Vzcwp9CgpzdGF0aWMgaW50IF9fZGV2ZXhpdCBibW9jYV9zcGlfcmVtb3ZlKHN0cnVjdCBzcGlfZGV2aWNlICpzcGkpIHsKCXByX2luZm8oImJtb2NhX3NwaV9yZW1vdmVcbiIpOwoJaWYgKG1vY2FfbGFuX2RhdGEuc3BpID09IHNwaSkgbW9jYV9sYW5fZGF0YS5zcGkgPSBOVUxMOwoJaWYgKG1vY2Ffd2FuX2RhdGEuc3BpID09IHNwaSkgbW9jYV93YW5fZGF0YS5zcGkgPSBOVUxMOwoJcmV0dXJuIDA7IC8vIHN1Y2Nlc3MKfQoKc3RhdGljIHN0cnVjdCBzcGlfZHJpdmVyIGJtb2NhX3NwaV9kcml2ZXIgPSB7CiAgLmRyaXZlciA9IHsKICAgIC5uYW1lID0gImJtb2NhIiwKICAgIC5vd25lciA9IFRISVNfTU9EVUxFLAogIH0sCiAgLnByb2JlID0gYm1vY2Ffc3BpX3Byb2JlLAogIC5yZW1vdmUgPSBfX2RldmV4aXRfcChibW9jYV9zcGlfcmVtb3ZlKSwKfTsKCi8vZXh0ZXJuIHZvaWQgYmNtZW5ldF9yZWdpc3Rlcl9tb2NhX2ZjX2JpdHNfY2Iodm9pZCBjYih2b2lkICosIHVuc2lnbmVkIGxvbmcgKiksIGludCBpc1dhbiwgdm9pZCAqIGFyZyk7CgpzdGF0aWMgaW50ICBod19zcGVjaWZpY19pbml0KCBzdHJ1Y3QgbW9jYV9wcml2X2RhdGEgKnByaXYgKQp7CiNpZmRlZiBEU0xfTU9DQQoJc3RydWN0IG1vY2FfcGxhdGZvcm1fZGF0YSAqcE1vY2FEYXRhOwoKCXBNb2NhRGF0YSA9IChzdHJ1Y3QgbW9jYV9wbGF0Zm9ybV9kYXRhICopcHJpdi0+cGRldi0+ZGV2LnBsYXRmb3JtX2RhdGE7CgoJLyogZmlsbCBpbiB0aGUgaHdfcmV2IGZpZWxkICovCglwTW9jYURhdGEtPmNoaXBfaWQgPSBNT0NBX1JEKDB4MTA0MDQwMDQpICsgMHhBMDsKICAgICAgICBwcl9pbmZvKCJyZWFkIG1vY2EgY2hpcCBpZDogJTA4eFxuIiwgcE1vY2FEYXRhLT5jaGlwX2lkKTsKCglwTW9jYURhdGEtPmh3X3JldiA9IEhXUkVWX01PQ0FfMjBfR0VOMjI7CgoJLyogUG93ZXIgZG93biBhbGwgTEVBUCBtZW1vcmllcyAqLwoJTU9DQV9XUigweDEwMTAwMGU0LCAweDYpOyAvLyBDTEtHRU5fTEVBUF9UT1BfSU5TVF9EQVRBICAgCglNT0NBX1dSKDB4MTAxMDAwZTgsIDB4Nik7IC8vIENMS0dFTl9MRUFQX1RPUF9JTlNUX0hBQiAKCU1PQ0FfV1IoMHgxMDEwMDBlYywgMHg2KTsgLy8gQ0xLR0VOX0xFQVBfVE9QX0lOU1RfUFJPRzAKCU1PQ0FfV1IoMHgxMDEwMDBmMCwgMHg2KTsgLy8gQ0xLR0VOX0xFQVBfVE9QX0lOU1RfUFJPRzEgICAKCU1PQ0FfV1IoMHgxMDEwMDBmNCwgMHg2KTsgLy8gQ0xLR0VOX0xFQVBfVE9QX0lOU1RfUFJPRzIgIAoJTU9DQV9XUigweDEwMTAwMGY4LCAweDYpOyAvLyBDTEtHRU5fTEVBUF9UT1BfSU5TVF9ST00KCU1PQ0FfV1IoMHgxMDEwMDBmYywgMHg2KTsgLy8gQ0xLR0VOX0xFQVBfVE9QX0lOU1RfU0hBUkVEICAKCU1PQ0FfV1IoMHgxMDEwMDE2NCwgMHgzKTsgLy8gQ0xLR0VOX1NZU19DVFJMX0lOU1RfUE9XRVJfU1dJVENIX01FTU9SWSAKCi8vCWJjbWVuZXRfcmVnaXN0ZXJfbW9jYV9mY19iaXRzX2NiKAovLwkJbW9jYV9nZXRfZmNfYml0cywgcE1vY2FEYXRhLT51c2Vfc3BpID8gMSA6IDAsICh2b2lkICopcHJpdik7CiNlbmRpZgoKCXJldHVybiAwOwp9CgpzdGF0aWMgaW50IG1vY2FfcGxhdGZvcm1fZGV2X3JlZ2lzdGVyKHZvaWQpCnsKCXN0cnVjdCBtb2NhX3BsYXRmb3JtX2RhdGEgKnBNb2NhRGF0YTsKCXN0cnVjdCBwbGF0Zm9ybV9kZXZpY2UgKnBQbGF0Zm9ybURldjsKCUJQX01PQ0FfSU5GTyBtb2NhSW5mb1tCUF9NT0NBX01BWF9OVU1dOwoJaW50IG1vY2FDaGlwTnVtID0gQlBfTU9DQV9NQVhfTlVNOwoJaW50IGk7CglpbnQgcmV0ID0gMDsgICAKCglCcEdldE1vY2FJbmZvKG1vY2FJbmZvLCAmbW9jYUNoaXBOdW0pOwoKCXJldCA9IHNwaV9yZWdpc3Rlcl9kcml2ZXIoJmJtb2NhX3NwaV9kcml2ZXIpOwoJaWYgKHJldCA8IDApIHJldHVybiByZXQ7CgoJZm9yIChpID0gMDsgaSA8IG1vY2FDaGlwTnVtOyBpKyspIHsKCQlzd2l0Y2ggKG1vY2FJbmZvW2ldLnR5cGUpIHsKCQkJY2FzZSBCUF9NT0NBX1RZUEVfV0FOOgoJCQkJcE1vY2FEYXRhID0gJm1vY2Ffd2FuX2RhdGE7CgkJCQlwUGxhdGZvcm1EZXYgPSAmbW9jYV93YW5fcGxhdF9kZXY7CgkJCQlicmVhazsKCgkJCWNhc2UgQlBfTU9DQV9UWVBFX0xBTjoKCQkJCXBNb2NhRGF0YSA9ICZtb2NhX2xhbl9kYXRhOwoJCQkJcFBsYXRmb3JtRGV2ID0gJm1vY2FfbGFuX3BsYXRfZGV2OwoJCQkJYnJlYWs7CgoJCQlkZWZhdWx0OgoJCQkJcHJpbnRrKEtFUk5fRVJSICJibW9jYTogdW5yZWNvZ25pemVkIE1vQ0EgdHlwZSAlZFxuIiwKCQkJCQltb2NhSW5mb1tpXS50eXBlKTsKCQkJCXJldHVybigtMSk7CgkJCQlicmVhazsKCQl9CgoJCXJldCA9IHBsYXRmb3JtX2RldmljZV9yZWdpc3RlcihwUGxhdGZvcm1EZXYpOwoJCWlmIChyZXQgPCAwKSB7CgkJCXNwaV91bnJlZ2lzdGVyX2RyaXZlcigmYm1vY2Ffc3BpX2RyaXZlcik7CgkJCXJldHVybihyZXQpOwoJCX0KCQllbHNlIHsKCQkJcE1vY2FEYXRhLT5kZXZJZCA9IGk7CgoJCQkvKiBNYXAgdGhlIGJvYXJkIHBhcmFtcyBSRiBCYW5kIHRvIHRoZSBibW9jYS5oIHZhbHVlICovCgkJCXN3aXRjaCAobW9jYUluZm9baV0ucmZCYW5kKQoJCQl7CgkJCQljYXNlIEJQX01PQ0FfUkZfQkFORF9EX0xPVzoKCQkJCQlwTW9jYURhdGEtPnJmX2JhbmQgPSBNT0NBX0JBTkRfRF9MT1c7CgkJCQkJYnJlYWs7CgkJCQljYXNlIEJQX01PQ0FfUkZfQkFORF9EX0hJR0g6CgkJCQkJcE1vY2FEYXRhLT5yZl9iYW5kID0gTU9DQV9CQU5EX0RfSElHSDsKCQkJCQlicmVhazsKCQkJCWNhc2UgQlBfTU9DQV9SRl9CQU5EX0VYVF9EOgoJCQkJCXBNb2NhRGF0YS0+cmZfYmFuZCA9IE1PQ0FfQkFORF9FWFRfRDsKCQkJCQlicmVhazsKCQkJCWNhc2UgQlBfTU9DQV9SRl9CQU5EX0U6CgkJCQkJcE1vY2FEYXRhLT5yZl9iYW5kID0gTU9DQV9CQU5EX0U7CgkJCQkJYnJlYWs7CgkJCQljYXNlIEJQX01PQ0FfUkZfQkFORF9GOiAgICAKCQkJCQlwTW9jYURhdGEtPnJmX2JhbmQgPSBNT0NBX0JBTkRfRjsKCQkJCQlicmVhazsKCQkJCWRlZmF1bHQ6CgkJCQkJLyogRG8gbm90aGluZyAqLwoJCQkJCWJyZWFrOwoJCQl9CgkJCXByaW50ayhLRVJOX0lORk8gImJtb2NhOiBGb3VuZCBNb0NBIGRldmljZSAlZC8lZCAgUkYgQmFuZCAlZFxuIiwKCQkJCWksIG1vY2FDaGlwTnVtLCBtb2NhSW5mb1tpXS5yZkJhbmQpOwoJCX0KCX0KCglyZXR1cm4ocmV0KTsKfQoKc3RhdGljIHZvaWQgbW9jYV9wbGF0Zm9ybV9kZXZfdW5yZWdpc3Rlcih2b2lkKQp7CglzcGlfdW5yZWdpc3Rlcl9kcml2ZXIoJmJtb2NhX3NwaV9kcml2ZXIpOwoKCWlmIChtb2NhX2xhbl9kYXRhLmRldklkICE9IE1PQ0FfREVWSUNFX0lEX1VOUkVHSVNURVJFRCkKCQlwbGF0Zm9ybV9kZXZpY2VfdW5yZWdpc3RlcigmbW9jYV9sYW5fcGxhdF9kZXYpOwoKCWlmIChtb2NhX3dhbl9kYXRhLmRldklkICE9IE1PQ0FfREVWSUNFX0lEX1VOUkVHSVNURVJFRCkKCQlwbGF0Zm9ybV9kZXZpY2VfdW5yZWdpc3RlcigmbW9jYV93YW5fcGxhdF9kZXYpOwp9CgpzdGF0aWMgdm9pZCBtb2NhXzM0NTBfd3JpdGUoc3RydWN0IG1vY2FfcHJpdl9kYXRhICpwcml2LCB1OCBhZGRyLCB1MzIgZGF0YSkKewoJLyogY29tbWVudCBvdXQgZm9yIG5vdy4gV2UgZG9uJ3QgdXNlIGkyYyBvbiB0aGUgNjMyNjhCSFIgYm9hcmQgKi8KI2lmZGVmIE1PQ0FfMzQ1MF9VU0VfSTJDCglpZiAoKChzdHJ1Y3QgbW9jYV9wbGF0Zm9ybV9kYXRhICopcHJpdi0+cGRldi0+ZGV2LnBsYXRmb3JtX2RhdGEpLT51c2Vfc3BpID09IDApCgkJYmNtMzQ1MF93cml0ZV9yZWcoYWRkciwgZGF0YSk7CgllbHNlCiNlbmRpZgoJCW1vY2FfMzQ1MF93cml0ZV9pMmMocHJpdiwgYWRkciwgZGF0YSk7Cn0KCnN0YXRpYyB1MzIgbW9jYV8zNDUwX3JlYWQoc3RydWN0IG1vY2FfcHJpdl9kYXRhICpwcml2LCB1OCBhZGRyKQp7CgkvKiBjb21tZW50IG91dCBmb3Igbm93LiBXZSBkb24ndCB1c2UgaTJjIG9uIHRoZSA2MzI2OEJIUiBib2FyZCAqLwojaWZkZWYgTU9DQV8zNDUwX1VTRV9JMkMKCWlmICgoKHN0cnVjdCBtb2NhX3BsYXRmb3JtX2RhdGEgKilwcml2LT5wZGV2LT5kZXYucGxhdGZvcm1fZGF0YSktPnVzZV9zcGkgPT0gMCkKCQlyZXR1cm4oYmNtMzQ1MF9yZWFkX3JlZyhhZGRyKSk7CgllbHNlCiNlbmRpZgoJCXJldHVybihtb2NhXzM0NTBfcmVhZF9pMmMocHJpdiwgYWRkcikpOwp9CgovKgogKiBQTSBTVFVCUwogKi8KCnN0cnVjdCBjbGsgKmNsa19nZXQoc3RydWN0IGRldmljZSAqZGV2LCBjb25zdCBjaGFyICppZCkKewoJcmV0dXJuIE5VTEw7Cn0KCmludCBjbGtfZW5hYmxlKHN0cnVjdCBjbGsgKmNsaykKewoKCXJldHVybiAwOwp9Cgp2b2lkIGNsa19kaXNhYmxlKHN0cnVjdCBjbGsgKmNsaykKewp9Cgp2b2lkIGNsa19wdXQoc3RydWN0IGNsayAqY2xrKQp7Cn0KCmludCBjbGtfc2V0X3JhdGUoc3RydWN0IGNsayAqY2xrLCB1bnNpZ25lZCBsb25nIHJhdGUpCnsKCXJldHVybiAwOwp9Cgo=