LyoKICogRkIgZHJpdmVyIGZvciBUd28gS1MwMTA4IExDRCBjb250cm9sbGVycyBpbiBBR00xMjY0Sy1GTCBkaXNwbGF5CiAqCiAqIENvcHlyaWdodCAoQykgMjAxNCBvbG9sb3Noa2EyODcxCiAqCiAqIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5CiAqIGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5CiAqIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlciB2ZXJzaW9uIDIgb2YgdGhlIExpY2Vuc2UsIG9yCiAqIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlCiAqIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCiAqLwoKI2luY2x1ZGUgPGxpbnV4L21vZHVsZS5oPgojaW5jbHVkZSA8bGludXgva2VybmVsLmg+CiNpbmNsdWRlIDxsaW51eC9pbml0Lmg+CiNpbmNsdWRlIDxsaW51eC9ncGlvLmg+CiNpbmNsdWRlIDxsaW51eC9kZWxheS5oPgojaW5jbHVkZSA8bGludXgvc2xhYi5oPgoKI2luY2x1ZGUgImZidGZ0LmgiCgovKiBVbmNvbW1lbnQgdGV4dCBsaW5lIHRvIHVzZSBuZWdhdGl2ZSBpbWFnZSBvbiBkaXNwbGF5ICovCi8qI2RlZmluZSBORUdBVElWRSovCgojZGVmaW5lIFdISVRFCQkweGZmCiNkZWZpbmUgQkxBQ0sJCTAKCiNkZWZpbmUgRFJWTkFNRQkJImZiX2FnbTEyNjRrLWZsIgojZGVmaW5lIFdJRFRICQk2NAojZGVmaW5lIEhFSUdIVAkJNjQKI2RlZmluZSBUT1RBTFdJRFRICShXSURUSCAqIDIpCSAvKiBiZWNhdXNlIDIgeCBrczAxMDggaW4gb25lIGRpc3BsYXkgKi8KI2RlZmluZSBGUFMJCQkyMAoKI2RlZmluZSBFUElOCQlncGlvLndyCiNkZWZpbmUgUlMJCQlncGlvLmRjCiNkZWZpbmUgUlcJCQlncGlvLmF1eFsyXQojZGVmaW5lIENTMAkJCWdwaW8uYXV4WzBdCiNkZWZpbmUgQ1MxCQkJZ3Bpby5hdXhbMV0KCgovKiBkaWZmdXNpbmcgZXJyb3IgKJNGbG95ZC1TdGVpbmJlcmeUKSAqLwojZGVmaW5lIERJRkZVU0lOR19NQVRSSVhfV0lEVEgJMgojZGVmaW5lIERJRkZVU0lOR19NQVRSSVhfSEVJR0hUCTIKCnN0YXRpYyBjb25zdCBzaWduZWQgY2hhcgpkaWZmdXNpbmdfbWF0cml4W0RJRkZVU0lOR19NQVRSSVhfV0lEVEhdW0RJRkZVU0lOR19NQVRSSVhfSEVJR0hUXSA9IHsKCXstMSwgM30sCgl7MywgMn0sCn07CgpzdGF0aWMgY29uc3QgdW5zaWduZWQgY2hhciBnYW1tYV9jb3JyZWN0aW9uX3RhYmxlW10gPSB7CjAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsCjEsIDEsIDIsIDIsIDIsIDIsIDIsIDIsIDIsIDMsIDMsIDMsIDMsIDMsIDQsIDQsIDQsIDQsIDUsIDUsIDUsIDUsIDYsCjYsIDYsIDYsIDcsIDcsIDcsIDgsIDgsIDgsIDksIDksIDksIDEwLCAxMCwgMTEsIDExLCAxMSwgMTIsIDEyLCAxMywKMTMsIDEzLCAxNCwgMTQsIDE1LCAxNSwgMTYsIDE2LCAxNywgMTcsIDE4LCAxOCwgMTksIDE5LCAyMCwgMjAsIDIxLAoyMiwgMjIsIDIzLCAyMywgMjQsIDI1LCAyNSwgMjYsIDI2LCAyNywgMjgsIDI4LCAyOSwgMzAsIDMwLCAzMSwgMzIsCjMzLCAzMywgMzQsIDM1LCAzNSwgMzYsIDM3LCAzOCwgMzksIDM5LCA0MCwgNDEsIDQyLCA0MywgNDMsIDQ0LCA0NSwKNDYsIDQ3LCA0OCwgNDksIDQ5LCA1MCwgNTEsIDUyLCA1MywgNTQsIDU1LCA1NiwgNTcsIDU4LCA1OSwgNjAsIDYxLAo2MiwgNjMsIDY0LCA2NSwgNjYsIDY3LCA2OCwgNjksIDcwLCA3MSwgNzMsIDc0LCA3NSwgNzYsIDc3LCA3OCwgNzksIDgxLAo4MiwgODMsIDg0LCA4NSwgODcsIDg4LCA4OSwgOTAsIDkxLCA5MywgOTQsIDk1LCA5NywgOTgsIDk5LCAxMDAsIDEwMiwKMTAzLCAxMDUsIDEwNiwgMTA3LCAxMDksIDExMCwgMTExLCAxMTMsIDExNCwgMTE2LCAxMTcsIDExOSwgMTIwLCAxMjEsCjEyMywgMTI0LCAxMjYsIDEyNywgMTI5LCAxMzAsIDEzMiwgMTMzLCAxMzUsIDEzNywgMTM4LCAxNDAsIDE0MSwgMTQzLAoxNDUsIDE0NiwgMTQ4LCAxNDksIDE1MSwgMTUzLCAxNTQsIDE1NiwgMTU4LCAxNTksIDE2MSwgMTYzLCAxNjUsIDE2NiwKMTY4LCAxNzAsIDE3MiwgMTczLCAxNzUsIDE3NywgMTc5LCAxODEsIDE4MiwgMTg0LCAxODYsIDE4OCwgMTkwLCAxOTIsCjE5NCwgMTk2LCAxOTcsIDE5OSwgMjAxLCAyMDMsIDIwNSwgMjA3LCAyMDksIDIxMSwgMjEzLCAyMTUsIDIxNywgMjE5LAoyMjEsIDIyMywgMjI1LCAyMjcsIDIyOSwgMjMxLCAyMzQsIDIzNiwgMjM4LCAyNDAsIDI0MiwgMjQ0LCAyNDYsIDI0OCwKMjUxLCAyNTMsIDI1NQp9OwoKc3RhdGljIGludCBpbml0X2Rpc3BsYXkoc3RydWN0IGZidGZ0X3BhciAqcGFyKQp7Cgl1OCBpOwoKCWZidGZ0X3Bhcl9kYmcoREVCVUdfSU5JVF9ESVNQTEFZLCBwYXIsICIlcygpXG4iLCBfX2Z1bmNfXyk7CgoJcGFyLT5mYnRmdG9wcy5yZXNldChwYXIpOwoKCWZvciAoaSA9IDA7IGkgPCAyOyArK2kpIHsKCQl3cml0ZV9yZWcocGFyLCBpLCAweDNmKTsgLyogZGlzcGxheSBvbiAqLwoJCXdyaXRlX3JlZyhwYXIsIGksIDB4NDApOyAvKiBzZXQgeCB0byAwICovCgkJd3JpdGVfcmVnKHBhciwgaSwgMHhiMCk7IC8qIHNldCBwYWdlIHRvIDAgKi8KCQl3cml0ZV9yZWcocGFyLCBpLCAweGMwKTsgLyogc2V0IHN0YXJ0IGxpbmUgdG8gMCAqLwoJfQoKCXJldHVybiAwOwp9CgpzdGF0aWMgdm9pZCByZXNldChzdHJ1Y3QgZmJ0ZnRfcGFyICpwYXIpCnsKCWlmIChwYXItPmdwaW8ucmVzZXQgPT0gLTEpCgkJcmV0dXJuOwoKCWRldl9kYmcocGFyLT5pbmZvLT5kZXZpY2UsICIlcygpXG4iLCBfX2Z1bmNfXyk7CgoJZ3Bpb19zZXRfdmFsdWUocGFyLT5ncGlvLnJlc2V0LCAwKTsKCXVkZWxheSgyMCk7CglncGlvX3NldF92YWx1ZShwYXItPmdwaW8ucmVzZXQsIDEpOwoJbWRlbGF5KDEyMCk7Cn0KCi8qIENoZWNrIGlmIGFsbCBuZWNlc3NhcnkgR1BJT1MgZGVmaW5lZCAqLwpzdGF0aWMgaW50IHZlcmlmeV9ncGlvcyhzdHJ1Y3QgZmJ0ZnRfcGFyICpwYXIpCnsKCWludCBpOwoKCWRldl9kYmcocGFyLT5pbmZvLT5kZXZpY2UsCgkJIiVzKClcbiIsIF9fZnVuY19fKTsKCglpZiAocGFyLT5FUElOIDwgMCkgewoJCWRldl9lcnIocGFyLT5pbmZvLT5kZXZpY2UsCgkJCSJNaXNzaW5nIGluZm8gYWJvdXQgJ3dyJyAoYWthIEUpIGdwaW8uIEFib3J0aW5nLlxuIik7CgkJcmV0dXJuIC1FSU5WQUw7Cgl9Cglmb3IgKGkgPSAwOyBpIDwgODsgKytpKSB7CgkJaWYgKHBhci0+Z3Bpby5kYltpXSA8IDApIHsKCQkJZGV2X2VycihwYXItPmluZm8tPmRldmljZSwKCQkJCSJNaXNzaW5nIGluZm8gYWJvdXQgJ2RiWyVpXScgZ3Bpby4gQWJvcnRpbmcuXG4iLAoJCQkJaSk7CgkJCXJldHVybiAtRUlOVkFMOwoJCX0KCX0KCWlmIChwYXItPkNTMCA8IDApIHsKCQlkZXZfZXJyKHBhci0+aW5mby0+ZGV2aWNlLAoJCQkiTWlzc2luZyBpbmZvIGFib3V0ICdjczAnIGdwaW8uIEFib3J0aW5nLlxuIik7CgkJcmV0dXJuIC1FSU5WQUw7Cgl9CglpZiAocGFyLT5DUzEgPCAwKSB7CgkJZGV2X2VycihwYXItPmluZm8tPmRldmljZSwKCQkJIk1pc3NpbmcgaW5mbyBhYm91dCAnY3MxJyBncGlvLiBBYm9ydGluZy5cbiIpOwoJCXJldHVybiAtRUlOVkFMOwoJfQoJaWYgKHBhci0+UlcgPCAwKSB7CgkJZGV2X2VycihwYXItPmluZm8tPmRldmljZSwKCQkJIk1pc3NpbmcgaW5mbyBhYm91dCAncncnIGdwaW8uIEFib3J0aW5nLlxuIik7CgkJcmV0dXJuIC1FSU5WQUw7Cgl9CgoJcmV0dXJuIDA7Cn0KCnN0YXRpYyB1bnNpZ25lZCBsb25nCnJlcXVlc3RfZ3Bpb3NfbWF0Y2goc3RydWN0IGZidGZ0X3BhciAqcGFyLCBjb25zdCBzdHJ1Y3QgZmJ0ZnRfZ3BpbyAqZ3BpbykKewoJZGV2X2RiZyhwYXItPmluZm8tPmRldmljZSwKCQkiJXMoJyVzJylcbiIsIF9fZnVuY19fLCBncGlvLT5uYW1lKTsKCglpZiAoc3RyY2FzZWNtcChncGlvLT5uYW1lLCAid3IiKSA9PSAwKSB7CgkJLyogbGVmdCBrczAxMDggRSBwaW4gKi8KCQlwYXItPkVQSU4gPSBncGlvLT5ncGlvOwoJCXJldHVybiBHUElPRl9PVVRfSU5JVF9MT1c7Cgl9IGVsc2UgaWYgKHN0cmNhc2VjbXAoZ3Bpby0+bmFtZSwgImNzMCIpID09IDApIHsKCQkvKiBsZWZ0IGtzMDEwOCBjb250cm9sbGVyIHBpbiAqLwoJCXBhci0+Q1MwID0gZ3Bpby0+Z3BpbzsKCQlyZXR1cm4gR1BJT0ZfT1VUX0lOSVRfSElHSDsKCX0gZWxzZSBpZiAoc3RyY2FzZWNtcChncGlvLT5uYW1lLCAiY3MxIikgPT0gMCkgewoJCS8qIHJpZ2h0IGtzMDEwOCBjb250cm9sbGVyIHBpbiAqLwoJCXBhci0+Q1MxID0gZ3Bpby0+Z3BpbzsKCQlyZXR1cm4gR1BJT0ZfT1VUX0lOSVRfSElHSDsKCX0KCgkvKiBpZiB3cml0ZSAocncgPSAwKSBlKDEtPjApIHBlcmZvcm0gd3JpdGUgKi8KCS8qIGlmIHJlYWQgKHJ3ID0gMSkgZSgwLT4xKSBzZXQgZGF0YSBvbiBEMC03Ki8KCWVsc2UgaWYgKHN0cmNhc2VjbXAoZ3Bpby0+bmFtZSwgInJ3IikgPT0gMCkgewoJCXBhci0+UlcgPSBncGlvLT5ncGlvOwoJCXJldHVybiBHUElPRl9PVVRfSU5JVF9MT1c7Cgl9CgoJcmV0dXJuIEZCVEZUX0dQSU9fTk9fTUFUQ0g7Cn0KCi8qIFRoaXMgZnVuY3Rpb24gb3NlcyB0byBlbnRlciBjb21tYW5kcwogKiBmaXJzdCBieXRlIC0gZGVzdGluYXRpb24gY29udHJvbGxlciAwIG9yIDEKICogZm9sbG93aW5nIC0gY29tbWFuZHMKICovCnN0YXRpYyB2b2lkIHdyaXRlX3JlZzhfYnVzOChzdHJ1Y3QgZmJ0ZnRfcGFyICpwYXIsIGludCBsZW4sIC4uLikKewoJdmFfbGlzdCBhcmdzOwoJaW50IGksIHJldDsKCXU4ICpidWYgPSAodTggKilwYXItPmJ1ZjsKCglpZiAodW5saWtlbHkocGFyLT5kZWJ1ZyAmIERFQlVHX1dSSVRFX1JFR0lTVEVSKSkgewoJCXZhX3N0YXJ0KGFyZ3MsIGxlbik7CgkJZm9yIChpID0gMDsgaSA8IGxlbjsgaSsrKQoJCQlidWZbaV0gPSAodTgpdmFfYXJnKGFyZ3MsIHVuc2lnbmVkIGludCk7CgoJCXZhX2VuZChhcmdzKTsKCQlmYnRmdF9wYXJfZGJnX2hleChERUJVR19XUklURV9SRUdJU1RFUiwgcGFyLAoJCQlwYXItPmluZm8tPmRldmljZSwgdTgsIGJ1ZiwgbGVuLCAiJXM6ICIsIF9fZnVuY19fKTsKCX0KCgl2YV9zdGFydChhcmdzLCBsZW4pOwoKCSpidWYgPSAodTgpdmFfYXJnKGFyZ3MsIHVuc2lnbmVkIGludCk7CgoJaWYgKCpidWYgPiAxKSB7CgkJdmFfZW5kKGFyZ3MpOwoJCWRldl9lcnIocGFyLT5pbmZvLT5kZXZpY2UsCgkJCSJJbmNvcnJlY3QgY2hpcCBzZWxlY3QgcmVxdWVzdCAoJWQpXG4iLCAqYnVmKTsKCQlyZXR1cm47Cgl9CgoJLyogc2VsZWN0IGNoaXAgKi8KCWlmICgqYnVmKSB7CgkJLyogY3MxICovCgkJZ3Bpb19zZXRfdmFsdWUocGFyLT5DUzAsIDEpOwoJCWdwaW9fc2V0X3ZhbHVlKHBhci0+Q1MxLCAwKTsKCX0gZWxzZSB7CgkJLyogY3MwICovCgkJZ3Bpb19zZXRfdmFsdWUocGFyLT5DUzAsIDApOwoJCWdwaW9fc2V0X3ZhbHVlKHBhci0+Q1MxLCAxKTsKCX0KCglncGlvX3NldF92YWx1ZShwYXItPlJTLCAwKTsgLyogUlMtPjAgKGNvbW1hbmQgbW9kZSkgKi8KCWxlbi0tOwoKCWlmIChsZW4pIHsKCQlpID0gbGVuOwoJCXdoaWxlIChpLS0pCgkJCSpidWYrKyA9ICh1OCl2YV9hcmcoYXJncywgdW5zaWduZWQgaW50KTsKCQlyZXQgPSBwYXItPmZidGZ0b3BzLndyaXRlKHBhciwgcGFyLT5idWYsIGxlbiAqIChzaXplb2YodTgpKSk7CgkJaWYgKHJldCA8IDApIHsKCQkJdmFfZW5kKGFyZ3MpOwoJCQlkZXZfZXJyKHBhci0+aW5mby0+ZGV2aWNlLAoJCQkJIndyaXRlKCkgZmFpbGVkIGFuZCByZXR1cm5lZCAlZFxuIiwgcmV0KTsKCQkJcmV0dXJuOwoJCX0KCX0KCgl2YV9lbmQoYXJncyk7Cn0KCnN0YXRpYyBzdHJ1Y3QKewoJaW50IHhzLCB5c19wYWdlLCB4ZSwgeWVfcGFnZTsKfSBhZGRyX3dpbjsKCi8qIHNhdmUgZGlzcGxheSB3cml0aW5nIHpvbmUgKi8Kc3RhdGljIHZvaWQgc2V0X2FkZHJfd2luKHN0cnVjdCBmYnRmdF9wYXIgKnBhciwgaW50IHhzLCBpbnQgeXMsIGludCB4ZSwgaW50IHllKQp7CglhZGRyX3dpbi54cyA9IHhzOwoJYWRkcl93aW4ueXNfcGFnZSA9IHlzIC8gODsKCWFkZHJfd2luLnhlID0geGU7CglhZGRyX3dpbi55ZV9wYWdlID0geWUgLyA4OwoKCWZidGZ0X3Bhcl9kYmcoREVCVUdfU0VUX0FERFJfV0lOLCBwYXIsCgkJIiVzKHhzPSVkLCB5c19wYWdlPSVkLCB4ZT0lZCwgeWVfcGFnZT0lZClcbiIsIF9fZnVuY19fLAoJCWFkZHJfd2luLnhzLCBhZGRyX3dpbi55c19wYWdlLCBhZGRyX3dpbi54ZSwgYWRkcl93aW4ueWVfcGFnZSk7Cn0KCnN0YXRpYyB2b2lkCmNvbnN0cnVjdF9saW5lX2JpdG1hcChzdHJ1Y3QgZmJ0ZnRfcGFyICpwYXIsIHU4ICpkZXN0LCBzaWduZWQgc2hvcnQgKnNyYywKCQkJCQkJaW50IHhzLCBpbnQgeGUsIGludCB5KQp7CglpbnQgeCwgaTsKCglmb3IgKHggPSB4czsgeCA8IHhlOyArK3gpIHsKCQl1OCByZXMgPSAwOwoKCQlmb3IgKGkgPSAwOyBpIDwgODsgaSsrKQoJCQlpZiAoc3JjWyh5ICogOCArIGkpICogcGFyLT5pbmZvLT52YXIueHJlcyArIHhdKQoJCQkJcmVzIHw9IDEgPDwgaTsKI2lmZGVmIE5FR0FUSVZFCgkJKmRlc3QrKyA9IHJlczsKI2Vsc2UKCQkqZGVzdCsrID0gfnJlczsKI2VuZGlmCgl9Cn0KCnN0YXRpYyBpbnQgd3JpdGVfdm1lbShzdHJ1Y3QgZmJ0ZnRfcGFyICpwYXIsIHNpemVfdCBvZmZzZXQsIHNpemVfdCBsZW4pCnsKCXUxNiAqdm1lbTE2ID0gKHUxNiAqKXBhci0+aW5mby0+c2NyZWVuX2Jhc2U7Cgl1OCAqYnVmID0gcGFyLT50eGJ1Zi5idWY7CglpbnQgeCwgeTsKCWludCByZXQgPSAwOwoKCS8qIGJ1ZmZlciB0byBjb252ZXJ0IFJHQjU2NSAtPiBncmF5c2NhbGUxNiAtPiBEaXRoZXJlZCBpbWFnZSAxYnBwICovCglzaWduZWQgc2hvcnQgKmNvbnZlcnRfYnVmID0ga21hbGxvYyhwYXItPmluZm8tPnZhci54cmVzICoKCQlwYXItPmluZm8tPnZhci55cmVzICogc2l6ZW9mKHNpZ25lZCBzaG9ydCksIEdGUF9OT0lPKTsKCglpZiAoIWNvbnZlcnRfYnVmKQoJCXJldHVybiAtRU5PTUVNOwoKCWZidGZ0X3Bhcl9kYmcoREVCVUdfV1JJVEVfVk1FTSwgcGFyLCAiJXMoKVxuIiwgX19mdW5jX18pOwoKCS8qIGNvbnZlcnRpbmcgdG8gZ3JheXNjYWxlMTYgKi8KCWZvciAoeCA9IDA7IHggPCBwYXItPmluZm8tPnZhci54cmVzOyArK3gpCgkJZm9yICh5ID0gMDsgeSA8IHBhci0+aW5mby0+dmFyLnlyZXM7ICsreSkgewoJCQl1MTYgcGl4ZWwgPSB2bWVtMTZbeSAqICBwYXItPmluZm8tPnZhci54cmVzICsgeF07CgkJCXUxNiBiID0gcGl4ZWwgJiAweDFmOwoJCQl1MTYgZyA9IChwaXhlbCAmICgweDNmIDw8IDUpKSA+PiA1OwoJCQl1MTYgciA9IChwaXhlbCAmICgweDFmIDw8ICg1ICsgNikpKSA+PiAoNSArIDYpOwoKCQkJcGl4ZWwgPSAoMjk5ICogciArIDU4NyAqIGcgKyAxMTQgKiBiKSAvIDIwMDsKCQkJaWYgKHBpeGVsID4gMjU1KQoJCQkJcGl4ZWwgPSAyNTU7CgoJCQkvKiBnYW1tYS1jb3JyZWN0aW9uIGJ5IHRhYmxlICovCgkJCWNvbnZlcnRfYnVmW3kgKiAgcGFyLT5pbmZvLT52YXIueHJlcyArIHhdID0KCQkJCShzaWduZWQgc2hvcnQpZ2FtbWFfY29ycmVjdGlvbl90YWJsZVtwaXhlbF07CgkJfQoKCS8qIEltYWdlIERpdGhlcmluZyAqLwoJZm9yICh4ID0gMDsgeCA8IHBhci0+aW5mby0+dmFyLnhyZXM7ICsreCkKCQlmb3IgKHkgPSAwOyB5IDwgcGFyLT5pbmZvLT52YXIueXJlczsgKyt5KSB7CgkJCXNpZ25lZCBzaG9ydCBwaXhlbCA9CgkJCQljb252ZXJ0X2J1Zlt5ICogIHBhci0+aW5mby0+dmFyLnhyZXMgKyB4XTsKCQkJc2lnbmVkIHNob3J0IGVycm9yX2IgPSBwaXhlbCAtIEJMQUNLOwoJCQlzaWduZWQgc2hvcnQgZXJyb3JfdyA9IHBpeGVsIC0gV0hJVEU7CgkJCXNpZ25lZCBzaG9ydCBlcnJvcjsKCQkJdTE2IGksIGo7CgoJCQkvKiB3aGF0IGNvbG9yIGNsb3NlPyAqLwoJCQlpZiAoYWJzKGVycm9yX2IpID49IGFicyhlcnJvcl93KSkgewoJCQkJLyogd2hpdGUgKi8KCQkJCWVycm9yID0gZXJyb3JfdzsKCQkJCXBpeGVsID0gMHhmZjsKCQkJfSBlbHNlIHsKCQkJCS8qIGJsYWNrICovCgkJCQllcnJvciA9IGVycm9yX2I7CgkJCQlwaXhlbCA9IDA7CgkJCX0KCgkJCWVycm9yIC89IDg7CgoJCQkvKiBkaWZmdXNpb24gbWF0cml4IHJvdyAqLwoJCQlmb3IgKGkgPSAwOyBpIDwgRElGRlVTSU5HX01BVFJJWF9XSURUSDsgKytpKQoJCQkJLyogZGlmZnVzaW9uIG1hdHJpeCBjb2x1bW4gKi8KCQkJCWZvciAoaiA9IDA7IGogPCBESUZGVVNJTkdfTUFUUklYX0hFSUdIVDsgKytqKSB7CgkJCQkJc2lnbmVkIHNob3J0ICp3cml0ZV9wb3M7CgkJCQkJc2lnbmVkIGNoYXIgY29lZmY7CgoJCQkJCS8qIHNraXAgcGl4ZWxzIG91dCBvZiB6b25lICovCgkJCQkJaWYgKHggKyBpIDwgMCB8fAoJCQkJCQl4ICsgaSA+PSBwYXItPmluZm8tPnZhci54cmVzCgkJCQkJCXx8IHkgKyBqID49IHBhci0+aW5mby0+dmFyLnlyZXMpCgkJCQkJCWNvbnRpbnVlOwoJCQkJCXdyaXRlX3BvcyA9ICZjb252ZXJ0X2J1ZlsKCQkJCQkJKHkgKyBqKSAqIHBhci0+aW5mby0+dmFyLnhyZXMgKwoJCQkJCQl4ICsgaV07CgkJCQkJY29lZmYgPSBkaWZmdXNpbmdfbWF0cml4W2ldW2pdOwoJCQkJCWlmIChjb2VmZiA9PSAtMSkKCQkJCQkJLyogcGl4ZWwgaXRzZWxmICovCgkJCQkJCSp3cml0ZV9wb3MgPSBwaXhlbDsKCQkJCQllbHNlIHsKCQkJCQkJc2lnbmVkIHNob3J0IHAgPSAqd3JpdGVfcG9zICsKCQkJCQkJCWVycm9yICogY29lZmY7CgoJCQkJCQlpZiAocCA+IFdISVRFKQoJCQkJCQkJcCA9IFdISVRFOwoJCQkJCQlpZiAocCA8IEJMQUNLKQoJCQkJCQkJcCA9IEJMQUNLOwoJCQkJCQkqd3JpdGVfcG9zID0gcDsKCQkJCQl9CgkJCQl9CgkJfQoKCSAvKiAxIHN0cmluZyA9IDIgcGFnZXMgKi8KCSBmb3IgKHkgPSBhZGRyX3dpbi55c19wYWdlOyB5IDw9IGFkZHJfd2luLnllX3BhZ2U7ICsreSkgewoJCS8qIGxlZnQgaGFsZiBvZiBkaXNwbGF5ICovCgkJaWYgKGFkZHJfd2luLnhzIDwgcGFyLT5pbmZvLT52YXIueHJlcyAvIDIpIHsKCQkJY29uc3RydWN0X2xpbmVfYml0bWFwKHBhciwgYnVmLCBjb252ZXJ0X2J1ZiwKCQkJCWFkZHJfd2luLnhzLCBwYXItPmluZm8tPnZhci54cmVzIC8gMiwgeSk7CgoJCQlsZW4gPSBwYXItPmluZm8tPnZhci54cmVzIC8gMiAtIGFkZHJfd2luLnhzOwoKCQkJLyogc2VsZWN0IGxlZnQgc2lkZSAoc2MwKQoJCQkgKiBzZXQgYWRkcgoJCQkgKi8KCQkJd3JpdGVfcmVnKHBhciwgMHgwMCwgKDEgPDwgNikgfCAodTgpYWRkcl93aW4ueHMpOwoJCQl3cml0ZV9yZWcocGFyLCAweDAwLCAoMHgxNyA8PCAzKSB8ICh1OCl5KTsKCgkJCS8qIHdyaXRlIGJpdG1hcCAqLwoJCQlncGlvX3NldF92YWx1ZShwYXItPlJTLCAxKTsgLyogUlMtPjEgKGRhdGEgbW9kZSkgKi8KCQkJcmV0ID0gcGFyLT5mYnRmdG9wcy53cml0ZShwYXIsIGJ1ZiwgbGVuKTsKCQkJaWYgKHJldCA8IDApCgkJCQlkZXZfZXJyKHBhci0+aW5mby0+ZGV2aWNlLAoJCQkJCSJ3cml0ZSBmYWlsZWQgYW5kIHJldHVybmVkOiAlZFxuIiwKCQkJCQlyZXQpOwoJCX0KCQkvKiByaWdodCBoYWxmIG9mIGRpc3BsYXkgKi8KCQlpZiAoYWRkcl93aW4ueGUgPj0gcGFyLT5pbmZvLT52YXIueHJlcyAvIDIpIHsKCQkJY29uc3RydWN0X2xpbmVfYml0bWFwKHBhciwgYnVmLAoJCQkJY29udmVydF9idWYsIHBhci0+aW5mby0+dmFyLnhyZXMgLyAyLAoJCQkJYWRkcl93aW4ueGUgKyAxLCB5KTsKCgkJCWxlbiA9IGFkZHJfd2luLnhlICsgMSAtIHBhci0+aW5mby0+dmFyLnhyZXMgLyAyOwoKCQkJLyogc2VsZWN0IHJpZ2h0IHNpZGUgKHNjMSkKCQkJICogc2V0IGFkZHIKCQkJICovCgkJCXdyaXRlX3JlZyhwYXIsIDB4MDEsIDEgPDwgNik7CgkJCXdyaXRlX3JlZyhwYXIsIDB4MDEsICgweDE3IDw8IDMpIHwgKHU4KXkpOwoKCQkJLyogd3JpdGUgYml0bWFwICovCgkJCWdwaW9fc2V0X3ZhbHVlKHBhci0+UlMsIDEpOyAvKiBSUy0+MSAoZGF0YSBtb2RlKSAqLwoJCQlwYXItPmZidGZ0b3BzLndyaXRlKHBhciwgYnVmLCBsZW4pOwoJCQlpZiAocmV0IDwgMCkKCQkJCWRldl9lcnIocGFyLT5pbmZvLT5kZXZpY2UsCgkJCQkJIndyaXRlIGZhaWxlZCBhbmQgcmV0dXJuZWQ6ICVkXG4iLAoJCQkJCXJldCk7CgkJfQoJfQoJa2ZyZWUoY29udmVydF9idWYpOwoKCWdwaW9fc2V0X3ZhbHVlKHBhci0+Q1MwLCAxKTsKCWdwaW9fc2V0X3ZhbHVlKHBhci0+Q1MxLCAxKTsKCglyZXR1cm4gcmV0Owp9CgpzdGF0aWMgaW50IHdyaXRlKHN0cnVjdCBmYnRmdF9wYXIgKnBhciwgdm9pZCAqYnVmLCBzaXplX3QgbGVuKQp7CglmYnRmdF9wYXJfZGJnX2hleChERUJVR19XUklURSwgcGFyLCBwYXItPmluZm8tPmRldmljZSwgdTgsIGJ1ZiwgbGVuLAoJCSIlcyhsZW49JWQpOiAiLCBfX2Z1bmNfXywgbGVuKTsKCglncGlvX3NldF92YWx1ZShwYXItPlJXLCAwKTsgLyogc2V0IHdyaXRlIG1vZGUgKi8KCgoJd2hpbGUgKGxlbi0tKSB7CgkJdTggaSwgZGF0YTsKCgkJZGF0YSA9ICoodTggKikgYnVmKys7CgoJCS8qIHNldCBkYXRhIGJ1cyAqLwoJCWZvciAoaSA9IDA7IGkgPCA4OyArK2kpCgkJCWdwaW9fc2V0X3ZhbHVlKHBhci0+Z3Bpby5kYltpXSwgZGF0YSAmICgxIDw8IGkpKTsKCQkvKiBzZXQgRSAqLwoJCWdwaW9fc2V0X3ZhbHVlKHBhci0+RVBJTiwgMSk7CgkJdWRlbGF5KDUpOwoJCS8qIHVuc2V0IEUgLSB3cml0ZSAqLwoJCWdwaW9fc2V0X3ZhbHVlKHBhci0+RVBJTiwgMCk7CgkJdWRlbGF5KDEpOwoJfQoKCXJldHVybiAwOwp9CgpzdGF0aWMgc3RydWN0IGZidGZ0X2Rpc3BsYXkgZGlzcGxheSA9IHsKCS5yZWd3aWR0aCA9IDgsCgkud2lkdGggPSBUT1RBTFdJRFRILAoJLmhlaWdodCA9IEhFSUdIVCwKCS5mcHMgPSBGUFMsCgkuZmJ0ZnRvcHMgPSB7CgkJLmluaXRfZGlzcGxheSA9IGluaXRfZGlzcGxheSwKCQkuc2V0X2FkZHJfd2luID0gc2V0X2FkZHJfd2luLAoJCS52ZXJpZnlfZ3Bpb3MgPSB2ZXJpZnlfZ3Bpb3MsCgkJLnJlcXVlc3RfZ3Bpb3NfbWF0Y2ggPSByZXF1ZXN0X2dwaW9zX21hdGNoLAoJCS5yZXNldCA9IHJlc2V0LAoJCS53cml0ZSA9IHdyaXRlLAoJCS53cml0ZV9yZWdpc3RlciA9IHdyaXRlX3JlZzhfYnVzOCwKCQkud3JpdGVfdm1lbSA9IHdyaXRlX3ZtZW0sCgl9LAp9OwpGQlRGVF9SRUdJU1RFUl9EUklWRVIoRFJWTkFNRSwgImRpc3BsYXl0cm9uaWMsZmJfYWdtMTI2NGstZmwiLCAmZGlzcGxheSk7CgpNT0RVTEVfQUxJQVMoInBsYXRmb3JtOiIgRFJWTkFNRSk7CgpNT0RVTEVfREVTQ1JJUFRJT04oIlR3byBLUzAxMDggTENEIGNvbnRyb2xsZXJzIGluIEFHTTEyNjRLLUZMIGRpc3BsYXkiKTsKTU9EVUxFX0FVVEhPUigib2xvbG9zaGthMjg3MSIpOwpNT0RVTEVfTElDRU5TRSgiR1BMIik7Cg==