LyoKICogcmFpZDEuYyA6IE11bHRpcGxlIERldmljZXMgZHJpdmVyIGZvciBMaW51eAogKgogKiBDb3B5cmlnaHQgKEMpIDE5OTksIDIwMDAsIDIwMDEgSW5nbyBNb2xuYXIsIFJlZCBIYXQKICoKICogQ29weXJpZ2h0IChDKSAxOTk2LCAxOTk3LCAxOTk4IEluZ28gTW9sbmFyLCBNaWd1ZWwgZGUgSWNhemEsIEdhZGkgT3htYW4KICoKICogUkFJRC0xIG1hbmFnZW1lbnQgZnVuY3Rpb25zLgogKgogKiBCZXR0ZXIgcmVhZC1iYWxhbmNpbmcgY29kZSB3cml0dGVuIGJ5IE1pa2EgS3VvcHBhbGEgPG1pa3VAaWtpLmZpPiwgMjAwMAogKgogKiBGaXhlcyB0byByZWNvbnN0cnVjdGlvbiBieSBKYWtvYiDYc3RlcmdhYXJkIiA8amFrb2JAb3N0ZW5mZWxkLmRrPgogKiBWYXJpb3VzIGZpeGVzIGJ5IE5laWwgQnJvd24gPG5laWxiQGNzZS51bnN3LmVkdS5hdT4KICoKICogQ2hhbmdlcyBieSBQZXRlciBULiBCcmV1ZXIgPHB0YkBpdC51YzNtLmVzPiAzMS8xLzIwMDMgdG8gc3VwcG9ydAogKiBiaXRtYXBwZWQgaW50ZWxsaWdlbmNlIGluIHJlc3luYzoKICoKICogICAgICAtIGJpdG1hcCBtYXJrZWQgZHVyaW5nIG5vcm1hbCBpL28KICogICAgICAtIGJpdG1hcCB1c2VkIHRvIHNraXAgbm9uZGlydHkgYmxvY2tzIGR1cmluZyBzeW5jCiAqCiAqIEFkZGl0aW9ucyB0byBiaXRtYXAgY29kZSwgKEMpIDIwMDMtMjAwNCBQYXVsIENsZW1lbnRzLCBTdGVlbEV5ZSBUZWNobm9sb2d5OgogKiAtIHBlcnNpc3RlbnQgYml0bWFwIGNvZGUKICoKICogVGhpcyBwcm9ncmFtIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkKICogaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkKICogdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyIHZlcnNpb24gMiwgb3IgKGF0IHlvdXIgb3B0aW9uKQogKiBhbnkgbGF0ZXIgdmVyc2lvbi4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogKGZvciBleGFtcGxlIC91c3Ivc3JjL2xpbnV4L0NPUFlJTkcpOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlCiAqIFNvZnR3YXJlIEZvdW5kYXRpb24sIEluYy4sIDY3NSBNYXNzIEF2ZSwgQ2FtYnJpZGdlLCBNQSAwMjEzOSwgVVNBLgogKi8KCiNpbmNsdWRlICJkbS1iaW8tbGlzdC5oIgojaW5jbHVkZSA8bGludXgvcmFpZC9yYWlkMS5oPgojaW5jbHVkZSA8bGludXgvcmFpZC9iaXRtYXAuaD4KCiNkZWZpbmUgREVCVUcgMAojaWYgREVCVUcKI2RlZmluZSBQUklOVEsoeC4uLikgcHJpbnRrKHgpCiNlbHNlCiNkZWZpbmUgUFJJTlRLKHguLi4pCiNlbmRpZgoKLyoKICogTnVtYmVyIG9mIGd1YXJhbnRlZWQgcjFiaW9zIGluIGNhc2Ugb2YgZXh0cmVtZSBWTSBsb2FkOgogKi8KI2RlZmluZQlOUl9SQUlEMV9CSU9TIDI1NgoKCnN0YXRpYyB2b2lkIHVucGx1Z19zbGF2ZXMobWRkZXZfdCAqbWRkZXYpOwoKc3RhdGljIHZvaWQgYWxsb3dfYmFycmllcihjb25mX3QgKmNvbmYpOwpzdGF0aWMgdm9pZCBsb3dlcl9iYXJyaWVyKGNvbmZfdCAqY29uZik7CgpzdGF0aWMgdm9pZCAqIHIxYmlvX3Bvb2xfYWxsb2MoZ2ZwX3QgZ2ZwX2ZsYWdzLCB2b2lkICpkYXRhKQp7CglzdHJ1Y3QgcG9vbF9pbmZvICpwaSA9IGRhdGE7CglyMWJpb190ICpyMV9iaW87CglpbnQgc2l6ZSA9IG9mZnNldG9mKHIxYmlvX3QsIGJpb3NbcGktPnJhaWRfZGlza3NdKTsKCgkvKiBhbGxvY2F0ZSBhIHIxYmlvIHdpdGggcm9vbSBmb3IgcmFpZF9kaXNrcyBlbnRyaWVzIGluIHRoZSBiaW9zIGFycmF5ICovCglyMV9iaW8gPSBremFsbG9jKHNpemUsIGdmcF9mbGFncyk7CglpZiAoIXIxX2JpbykKCQl1bnBsdWdfc2xhdmVzKHBpLT5tZGRldik7CgoJcmV0dXJuIHIxX2JpbzsKfQoKc3RhdGljIHZvaWQgcjFiaW9fcG9vbF9mcmVlKHZvaWQgKnIxX2Jpbywgdm9pZCAqZGF0YSkKewoJa2ZyZWUocjFfYmlvKTsKfQoKI2RlZmluZSBSRVNZTkNfQkxPQ0tfU0laRSAoNjQqMTAyNCkKLy8jZGVmaW5lIFJFU1lOQ19CTE9DS19TSVpFIFBBR0VfU0laRQojZGVmaW5lIFJFU1lOQ19TRUNUT1JTIChSRVNZTkNfQkxPQ0tfU0laRSA+PiA5KQojZGVmaW5lIFJFU1lOQ19QQUdFUyAoKFJFU1lOQ19CTE9DS19TSVpFICsgUEFHRV9TSVpFLTEpIC8gUEFHRV9TSVpFKQojZGVmaW5lIFJFU1lOQ19XSU5ET1cgKDIwNDgqMTAyNCkKCnN0YXRpYyB2b2lkICogcjFidWZfcG9vbF9hbGxvYyhnZnBfdCBnZnBfZmxhZ3MsIHZvaWQgKmRhdGEpCnsKCXN0cnVjdCBwb29sX2luZm8gKnBpID0gZGF0YTsKCXN0cnVjdCBwYWdlICpwYWdlOwoJcjFiaW9fdCAqcjFfYmlvOwoJc3RydWN0IGJpbyAqYmlvOwoJaW50IGksIGo7CgoJcjFfYmlvID0gcjFiaW9fcG9vbF9hbGxvYyhnZnBfZmxhZ3MsIHBpKTsKCWlmICghcjFfYmlvKSB7CgkJdW5wbHVnX3NsYXZlcyhwaS0+bWRkZXYpOwoJCXJldHVybiBOVUxMOwoJfQoKCS8qCgkgKiBBbGxvY2F0ZSBiaW9zIDogMSBmb3IgcmVhZGluZywgbi0xIGZvciB3cml0aW5nCgkgKi8KCWZvciAoaiA9IHBpLT5yYWlkX2Rpc2tzIDsgai0tIDsgKSB7CgkJYmlvID0gYmlvX2FsbG9jKGdmcF9mbGFncywgUkVTWU5DX1BBR0VTKTsKCQlpZiAoIWJpbykKCQkJZ290byBvdXRfZnJlZV9iaW87CgkJcjFfYmlvLT5iaW9zW2pdID0gYmlvOwoJfQoJLyoKCSAqIEFsbG9jYXRlIFJFU1lOQ19QQUdFUyBkYXRhIHBhZ2VzIGFuZCBhdHRhY2ggdGhlbSB0bwoJICogdGhlIGZpcnN0IGJpby4KCSAqIElmIHRoaXMgaXMgYSB1c2VyLXJlcXVlc3RlZCBjaGVjay9yZXBhaXIsIGFsbG9jYXRlCgkgKiBSRVNZTkNfUEFHRVMgZm9yIGVhY2ggYmlvLgoJICovCglpZiAodGVzdF9iaXQoTURfUkVDT1ZFUllfUkVRVUVTVEVELCAmcGktPm1kZGV2LT5yZWNvdmVyeSkpCgkJaiA9IHBpLT5yYWlkX2Rpc2tzOwoJZWxzZQoJCWogPSAxOwoJd2hpbGUoai0tKSB7CgkJYmlvID0gcjFfYmlvLT5iaW9zW2pdOwoJCWZvciAoaSA9IDA7IGkgPCBSRVNZTkNfUEFHRVM7IGkrKykgewoJCQlwYWdlID0gYWxsb2NfcGFnZShnZnBfZmxhZ3MpOwoJCQlpZiAodW5saWtlbHkoIXBhZ2UpKQoJCQkJZ290byBvdXRfZnJlZV9wYWdlczsKCgkJCWJpby0+YmlfaW9fdmVjW2ldLmJ2X3BhZ2UgPSBwYWdlOwoJCX0KCX0KCS8qIElmIG5vdCB1c2VyLXJlcXVlc3RzLCBjb3B5IHRoZSBwYWdlIHBvaW50ZXJzIHRvIGFsbCBiaW9zICovCglpZiAoIXRlc3RfYml0KE1EX1JFQ09WRVJZX1JFUVVFU1RFRCwgJnBpLT5tZGRldi0+cmVjb3ZlcnkpKSB7CgkJZm9yIChpPTA7IGk8UkVTWU5DX1BBR0VTIDsgaSsrKQoJCQlmb3IgKGo9MTsgajxwaS0+cmFpZF9kaXNrczsgaisrKQoJCQkJcjFfYmlvLT5iaW9zW2pdLT5iaV9pb192ZWNbaV0uYnZfcGFnZSA9CgkJCQkJcjFfYmlvLT5iaW9zWzBdLT5iaV9pb192ZWNbaV0uYnZfcGFnZTsKCX0KCglyMV9iaW8tPm1hc3Rlcl9iaW8gPSBOVUxMOwoKCXJldHVybiByMV9iaW87CgpvdXRfZnJlZV9wYWdlczoKCWZvciAoaT0wOyBpIDwgUkVTWU5DX1BBR0VTIDsgaSsrKQoJCWZvciAoaj0wIDsgaiA8IHBpLT5yYWlkX2Rpc2tzOyBqKyspCgkJCXNhZmVfcHV0X3BhZ2UocjFfYmlvLT5iaW9zW2pdLT5iaV9pb192ZWNbaV0uYnZfcGFnZSk7CglqID0gLTE7Cm91dF9mcmVlX2JpbzoKCXdoaWxlICggKytqIDwgcGktPnJhaWRfZGlza3MgKQoJCWJpb19wdXQocjFfYmlvLT5iaW9zW2pdKTsKCXIxYmlvX3Bvb2xfZnJlZShyMV9iaW8sIGRhdGEpOwoJcmV0dXJuIE5VTEw7Cn0KCnN0YXRpYyB2b2lkIHIxYnVmX3Bvb2xfZnJlZSh2b2lkICpfX3IxX2Jpbywgdm9pZCAqZGF0YSkKewoJc3RydWN0IHBvb2xfaW5mbyAqcGkgPSBkYXRhOwoJaW50IGksajsKCXIxYmlvX3QgKnIxYmlvID0gX19yMV9iaW87CgoJZm9yIChpID0gMDsgaSA8IFJFU1lOQ19QQUdFUzsgaSsrKQoJCWZvciAoaiA9IHBpLT5yYWlkX2Rpc2tzOyBqLS0gOykgewoJCQlpZiAoaiA9PSAwIHx8CgkJCSAgICByMWJpby0+Ymlvc1tqXS0+YmlfaW9fdmVjW2ldLmJ2X3BhZ2UgIT0KCQkJICAgIHIxYmlvLT5iaW9zWzBdLT5iaV9pb192ZWNbaV0uYnZfcGFnZSkKCQkJCXNhZmVfcHV0X3BhZ2UocjFiaW8tPmJpb3Nbal0tPmJpX2lvX3ZlY1tpXS5idl9wYWdlKTsKCQl9Cglmb3IgKGk9MCA7IGkgPCBwaS0+cmFpZF9kaXNrczsgaSsrKQoJCWJpb19wdXQocjFiaW8tPmJpb3NbaV0pOwoKCXIxYmlvX3Bvb2xfZnJlZShyMWJpbywgZGF0YSk7Cn0KCnN0YXRpYyB2b2lkIHB1dF9hbGxfYmlvcyhjb25mX3QgKmNvbmYsIHIxYmlvX3QgKnIxX2JpbykKewoJaW50IGk7CgoJZm9yIChpID0gMDsgaSA8IGNvbmYtPnJhaWRfZGlza3M7IGkrKykgewoJCXN0cnVjdCBiaW8gKipiaW8gPSByMV9iaW8tPmJpb3MgKyBpOwoJCWlmICgqYmlvICYmICpiaW8gIT0gSU9fQkxPQ0tFRCkKCQkJYmlvX3B1dCgqYmlvKTsKCQkqYmlvID0gTlVMTDsKCX0KfQoKc3RhdGljIHZvaWQgZnJlZV9yMWJpbyhyMWJpb190ICpyMV9iaW8pCnsKCWNvbmZfdCAqY29uZiA9IG1kZGV2X3RvX2NvbmYocjFfYmlvLT5tZGRldik7CgoJLyoKCSAqIFdha2UgdXAgYW55IHBvc3NpYmxlIHJlc3luYyB0aHJlYWQgdGhhdCB3YWl0cyBmb3IgdGhlIGRldmljZQoJICogdG8gZ28gaWRsZS4KCSAqLwoJYWxsb3dfYmFycmllcihjb25mKTsKCglwdXRfYWxsX2Jpb3MoY29uZiwgcjFfYmlvKTsKCW1lbXBvb2xfZnJlZShyMV9iaW8sIGNvbmYtPnIxYmlvX3Bvb2wpOwp9CgpzdGF0aWMgdm9pZCBwdXRfYnVmKHIxYmlvX3QgKnIxX2JpbykKewoJY29uZl90ICpjb25mID0gbWRkZXZfdG9fY29uZihyMV9iaW8tPm1kZGV2KTsKCWludCBpOwoKCWZvciAoaT0wOyBpPGNvbmYtPnJhaWRfZGlza3M7IGkrKykgewoJCXN0cnVjdCBiaW8gKmJpbyA9IHIxX2Jpby0+Ymlvc1tpXTsKCQlpZiAoYmlvLT5iaV9lbmRfaW8pCgkJCXJkZXZfZGVjX3BlbmRpbmcoY29uZi0+bWlycm9yc1tpXS5yZGV2LCByMV9iaW8tPm1kZGV2KTsKCX0KCgltZW1wb29sX2ZyZWUocjFfYmlvLCBjb25mLT5yMWJ1Zl9wb29sKTsKCglsb3dlcl9iYXJyaWVyKGNvbmYpOwp9CgpzdGF0aWMgdm9pZCByZXNjaGVkdWxlX3JldHJ5KHIxYmlvX3QgKnIxX2JpbykKewoJdW5zaWduZWQgbG9uZyBmbGFnczsKCW1kZGV2X3QgKm1kZGV2ID0gcjFfYmlvLT5tZGRldjsKCWNvbmZfdCAqY29uZiA9IG1kZGV2X3RvX2NvbmYobWRkZXYpOwoKCXNwaW5fbG9ja19pcnFzYXZlKCZjb25mLT5kZXZpY2VfbG9jaywgZmxhZ3MpOwoJbGlzdF9hZGQoJnIxX2Jpby0+cmV0cnlfbGlzdCwgJmNvbmYtPnJldHJ5X2xpc3QpOwoJY29uZi0+bnJfcXVldWVkICsrOwoJc3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmY29uZi0+ZGV2aWNlX2xvY2ssIGZsYWdzKTsKCgl3YWtlX3VwKCZjb25mLT53YWl0X2JhcnJpZXIpOwoJbWRfd2FrZXVwX3RocmVhZChtZGRldi0+dGhyZWFkKTsKfQoKLyoKICogcmFpZF9lbmRfYmlvX2lvKCkgaXMgY2FsbGVkIHdoZW4gd2UgaGF2ZSBmaW5pc2hlZCBzZXJ2aWNpbmcgYSBtaXJyb3JlZAogKiBvcGVyYXRpb24gYW5kIGFyZSByZWFkeSB0byByZXR1cm4gYSBzdWNjZXNzL2ZhaWx1cmUgY29kZSB0byB0aGUgYnVmZmVyCiAqIGNhY2hlIGxheWVyLgogKi8Kc3RhdGljIHZvaWQgcmFpZF9lbmRfYmlvX2lvKHIxYmlvX3QgKnIxX2JpbykKewoJc3RydWN0IGJpbyAqYmlvID0gcjFfYmlvLT5tYXN0ZXJfYmlvOwoKCS8qIGlmIG5vYm9keSBoYXMgZG9uZSB0aGUgZmluYWwgZW5kaW8geWV0LCBkbyBpdCBub3cgKi8KCWlmICghdGVzdF9hbmRfc2V0X2JpdChSMUJJT19SZXR1cm5lZCwgJnIxX2Jpby0+c3RhdGUpKSB7CgkJUFJJTlRLKEtFUk5fREVCVUcgInJhaWQxOiBzeW5jIGVuZCAlcyBvbiBzZWN0b3JzICVsbHUtJWxsdVxuIiwKCQkJKGJpb19kYXRhX2RpcihiaW8pID09IFdSSVRFKSA/ICJ3cml0ZSIgOiAicmVhZCIsCgkJCSh1bnNpZ25lZCBsb25nIGxvbmcpIGJpby0+Ymlfc2VjdG9yLAoJCQkodW5zaWduZWQgbG9uZyBsb25nKSBiaW8tPmJpX3NlY3RvciArCgkJCQkoYmlvLT5iaV9zaXplID4+IDkpIC0gMSk7CgoJCWJpb19lbmRpbyhiaW8sIGJpby0+Ymlfc2l6ZSwKCQkJdGVzdF9iaXQoUjFCSU9fVXB0b2RhdGUsICZyMV9iaW8tPnN0YXRlKSA/IDAgOiAtRUlPKTsKCX0KCWZyZWVfcjFiaW8ocjFfYmlvKTsKfQoKLyoKICogVXBkYXRlIGRpc2sgaGVhZCBwb3NpdGlvbiBlc3RpbWF0b3IgYmFzZWQgb24gSVJRIGNvbXBsZXRpb24gaW5mby4KICovCnN0YXRpYyBpbmxpbmUgdm9pZCB1cGRhdGVfaGVhZF9wb3MoaW50IGRpc2ssIHIxYmlvX3QgKnIxX2JpbykKewoJY29uZl90ICpjb25mID0gbWRkZXZfdG9fY29uZihyMV9iaW8tPm1kZGV2KTsKCgljb25mLT5taXJyb3JzW2Rpc2tdLmhlYWRfcG9zaXRpb24gPQoJCXIxX2Jpby0+c2VjdG9yICsgKHIxX2Jpby0+c2VjdG9ycyk7Cn0KCnN0YXRpYyBpbnQgcmFpZDFfZW5kX3JlYWRfcmVxdWVzdChzdHJ1Y3QgYmlvICpiaW8sIHVuc2lnbmVkIGludCBieXRlc19kb25lLCBpbnQgZXJyb3IpCnsKCWludCB1cHRvZGF0ZSA9IHRlc3RfYml0KEJJT19VUFRPREFURSwgJmJpby0+YmlfZmxhZ3MpOwoJcjFiaW9fdCAqIHIxX2JpbyA9IChyMWJpb190ICopKGJpby0+YmlfcHJpdmF0ZSk7CglpbnQgbWlycm9yOwoJY29uZl90ICpjb25mID0gbWRkZXZfdG9fY29uZihyMV9iaW8tPm1kZGV2KTsKCglpZiAoYmlvLT5iaV9zaXplKQoJCXJldHVybiAxOwoJCgltaXJyb3IgPSByMV9iaW8tPnJlYWRfZGlzazsKCS8qCgkgKiB0aGlzIGJyYW5jaCBpcyBvdXIgJ29uZSBtaXJyb3IgSU8gaGFzIGZpbmlzaGVkJyBldmVudCBoYW5kbGVyOgoJICovCgl1cGRhdGVfaGVhZF9wb3MobWlycm9yLCByMV9iaW8pOwoKCWlmICh1cHRvZGF0ZSB8fCBjb25mLT53b3JraW5nX2Rpc2tzIDw9IDEpIHsKCQkvKgoJCSAqIFNldCBSMUJJT19VcHRvZGF0ZSBpbiBvdXIgbWFzdGVyIGJpbywgc28gdGhhdAoJCSAqIHdlIHdpbGwgcmV0dXJuIGEgZ29vZCBlcnJvciBjb2RlIGZvciB0byB0aGUgaGlnaGVyCgkJICogbGV2ZWxzIGV2ZW4gaWYgSU8gb24gc29tZSBvdGhlciBtaXJyb3JlZCBidWZmZXIgZmFpbHMuCgkJICoKCQkgKiBUaGUgJ21hc3RlcicgcmVwcmVzZW50cyB0aGUgY29tcG9zaXRlIElPIG9wZXJhdGlvbiB0bwoJCSAqIHVzZXItc2lkZS4gU28gaWYgc29tZXRoaW5nIHdhaXRzIGZvciBJTywgdGhlbiBpdCB3aWxsCgkJICogd2FpdCBmb3IgdGhlICdtYXN0ZXInIGJpby4KCQkgKi8KCQlpZiAodXB0b2RhdGUpCgkJCXNldF9iaXQoUjFCSU9fVXB0b2RhdGUsICZyMV9iaW8tPnN0YXRlKTsKCgkJcmFpZF9lbmRfYmlvX2lvKHIxX2Jpbyk7Cgl9IGVsc2UgewoJCS8qCgkJICogb29wcywgcmVhZCBlcnJvcjoKCQkgKi8KCQljaGFyIGJbQkRFVk5BTUVfU0laRV07CgkJaWYgKHByaW50a19yYXRlbGltaXQoKSkKCQkJcHJpbnRrKEtFUk5fRVJSICJyYWlkMTogJXM6IHJlc2NoZWR1bGluZyBzZWN0b3IgJWxsdVxuIiwKCQkJICAgICAgIGJkZXZuYW1lKGNvbmYtPm1pcnJvcnNbbWlycm9yXS5yZGV2LT5iZGV2LGIpLCAodW5zaWduZWQgbG9uZyBsb25nKXIxX2Jpby0+c2VjdG9yKTsKCQlyZXNjaGVkdWxlX3JldHJ5KHIxX2Jpbyk7Cgl9CgoJcmRldl9kZWNfcGVuZGluZyhjb25mLT5taXJyb3JzW21pcnJvcl0ucmRldiwgY29uZi0+bWRkZXYpOwoJcmV0dXJuIDA7Cn0KCnN0YXRpYyBpbnQgcmFpZDFfZW5kX3dyaXRlX3JlcXVlc3Qoc3RydWN0IGJpbyAqYmlvLCB1bnNpZ25lZCBpbnQgYnl0ZXNfZG9uZSwgaW50IGVycm9yKQp7CglpbnQgdXB0b2RhdGUgPSB0ZXN0X2JpdChCSU9fVVBUT0RBVEUsICZiaW8tPmJpX2ZsYWdzKTsKCXIxYmlvX3QgKiByMV9iaW8gPSAocjFiaW9fdCAqKShiaW8tPmJpX3ByaXZhdGUpOwoJaW50IG1pcnJvciwgYmVoaW5kID0gdGVzdF9iaXQoUjFCSU9fQmVoaW5kSU8sICZyMV9iaW8tPnN0YXRlKTsKCWNvbmZfdCAqY29uZiA9IG1kZGV2X3RvX2NvbmYocjFfYmlvLT5tZGRldik7CglzdHJ1Y3QgYmlvICp0b19wdXQgPSBOVUxMOwoKCWlmIChiaW8tPmJpX3NpemUpCgkJcmV0dXJuIDE7CgoJZm9yIChtaXJyb3IgPSAwOyBtaXJyb3IgPCBjb25mLT5yYWlkX2Rpc2tzOyBtaXJyb3IrKykKCQlpZiAocjFfYmlvLT5iaW9zW21pcnJvcl0gPT0gYmlvKQoJCQlicmVhazsKCglpZiAoZXJyb3IgPT0gLUVPUE5PVFNVUFAgJiYgdGVzdF9iaXQoUjFCSU9fQmFycmllciwgJnIxX2Jpby0+c3RhdGUpKSB7CgkJc2V0X2JpdChCYXJyaWVyc05vdHN1cHAsICZjb25mLT5taXJyb3JzW21pcnJvcl0ucmRldi0+ZmxhZ3MpOwoJCXNldF9iaXQoUjFCSU9fQmFycmllclJldHJ5LCAmcjFfYmlvLT5zdGF0ZSk7CgkJcjFfYmlvLT5tZGRldi0+YmFycmllcnNfd29yayA9IDA7CgkJLyogRG9uJ3QgcmRldl9kZWNfcGVuZGluZyBpbiB0aGlzIGJyYW5jaCAtIGtlZXAgaXQgZm9yIHRoZSByZXRyeSAqLwoJfSBlbHNlIHsKCQkvKgoJCSAqIHRoaXMgYnJhbmNoIGlzIG91ciAnb25lIG1pcnJvciBJTyBoYXMgZmluaXNoZWQnIGV2ZW50IGhhbmRsZXI6CgkJICovCgkJcjFfYmlvLT5iaW9zW21pcnJvcl0gPSBOVUxMOwoJCXRvX3B1dCA9IGJpbzsKCQlpZiAoIXVwdG9kYXRlKSB7CgkJCW1kX2Vycm9yKHIxX2Jpby0+bWRkZXYsIGNvbmYtPm1pcnJvcnNbbWlycm9yXS5yZGV2KTsKCQkJLyogYW4gSS9PIGZhaWxlZCwgd2UgY2FuJ3QgY2xlYXIgdGhlIGJpdG1hcCAqLwoJCQlzZXRfYml0KFIxQklPX0RlZ3JhZGVkLCAmcjFfYmlvLT5zdGF0ZSk7CgkJfSBlbHNlCgkJCS8qCgkJCSAqIFNldCBSMUJJT19VcHRvZGF0ZSBpbiBvdXIgbWFzdGVyIGJpbywgc28gdGhhdAoJCQkgKiB3ZSB3aWxsIHJldHVybiBhIGdvb2QgZXJyb3IgY29kZSBmb3IgdG8gdGhlIGhpZ2hlcgoJCQkgKiBsZXZlbHMgZXZlbiBpZiBJTyBvbiBzb21lIG90aGVyIG1pcnJvcmVkIGJ1ZmZlciBmYWlscy4KCQkJICoKCQkJICogVGhlICdtYXN0ZXInIHJlcHJlc2VudHMgdGhlIGNvbXBvc2l0ZSBJTyBvcGVyYXRpb24gdG8KCQkJICogdXNlci1zaWRlLiBTbyBpZiBzb21ldGhpbmcgd2FpdHMgZm9yIElPLCB0aGVuIGl0IHdpbGwKCQkJICogd2FpdCBmb3IgdGhlICdtYXN0ZXInIGJpby4KCQkJICovCgkJCXNldF9iaXQoUjFCSU9fVXB0b2RhdGUsICZyMV9iaW8tPnN0YXRlKTsKCgkJdXBkYXRlX2hlYWRfcG9zKG1pcnJvciwgcjFfYmlvKTsKCgkJaWYgKGJlaGluZCkgewoJCQlpZiAodGVzdF9iaXQoV3JpdGVNb3N0bHksICZjb25mLT5taXJyb3JzW21pcnJvcl0ucmRldi0+ZmxhZ3MpKQoJCQkJYXRvbWljX2RlYygmcjFfYmlvLT5iZWhpbmRfcmVtYWluaW5nKTsKCgkJCS8qIEluIGJlaGluZCBtb2RlLCB3ZSBBQ0sgdGhlIG1hc3RlciBiaW8gb25jZSB0aGUgSS9PIGhhcyBzYWZlbHkKCQkJICogcmVhY2hlZCBhbGwgbm9uLXdyaXRlbW9zdGx5IGRpc2tzLiBTZXR0aW5nIHRoZSBSZXR1cm5lZCBiaXQKCQkJICogZW5zdXJlcyB0aGF0IHRoaXMgZ2V0cyBkb25lIG9ubHkgb25jZSAtLSB3ZSBkb24ndCBldmVyIHdhbnQgdG8KCQkJICogcmV0dXJuIC1FSU8gaGVyZSwgaW5zdGVhZCB3ZSdsbCB3YWl0ICovCgoJCQlpZiAoYXRvbWljX3JlYWQoJnIxX2Jpby0+YmVoaW5kX3JlbWFpbmluZykgPj0gKGF0b21pY19yZWFkKCZyMV9iaW8tPnJlbWFpbmluZyktMSkgJiYKCQkJICAgIHRlc3RfYml0KFIxQklPX1VwdG9kYXRlLCAmcjFfYmlvLT5zdGF0ZSkpIHsKCQkJCS8qIE1heWJlIHdlIGNhbiByZXR1cm4gbm93ICovCgkJCQlpZiAoIXRlc3RfYW5kX3NldF9iaXQoUjFCSU9fUmV0dXJuZWQsICZyMV9iaW8tPnN0YXRlKSkgewoJCQkJCXN0cnVjdCBiaW8gKm1iaW8gPSByMV9iaW8tPm1hc3Rlcl9iaW87CgkJCQkJUFJJTlRLKEtFUk5fREVCVUcgInJhaWQxOiBiZWhpbmQgZW5kIHdyaXRlIHNlY3RvcnMgJWxsdS0lbGx1XG4iLAoJCQkJCSAgICAgICAodW5zaWduZWQgbG9uZyBsb25nKSBtYmlvLT5iaV9zZWN0b3IsCgkJCQkJICAgICAgICh1bnNpZ25lZCBsb25nIGxvbmcpIG1iaW8tPmJpX3NlY3RvciArCgkJCQkJICAgICAgIChtYmlvLT5iaV9zaXplID4+IDkpIC0gMSk7CgkJCQkJYmlvX2VuZGlvKG1iaW8sIG1iaW8tPmJpX3NpemUsIDApOwoJCQkJfQoJCQl9CgkJfQoJCXJkZXZfZGVjX3BlbmRpbmcoY29uZi0+bWlycm9yc1ttaXJyb3JdLnJkZXYsIGNvbmYtPm1kZGV2KTsKCX0KCS8qCgkgKgoJICogTGV0J3Mgc2VlIGlmIGFsbCBtaXJyb3JlZCB3cml0ZSBvcGVyYXRpb25zIGhhdmUgZmluaXNoZWQKCSAqIGFscmVhZHkuCgkgKi8KCWlmIChhdG9taWNfZGVjX2FuZF90ZXN0KCZyMV9iaW8tPnJlbWFpbmluZykpIHsKCQlpZiAodGVzdF9iaXQoUjFCSU9fQmFycmllclJldHJ5LCAmcjFfYmlvLT5zdGF0ZSkpCgkJCXJlc2NoZWR1bGVfcmV0cnkocjFfYmlvKTsKCQllbHNlIHsKCQkJLyogaXQgcmVhbGx5IGlzIHRoZSBlbmQgb2YgdGhpcyByZXF1ZXN0ICovCgkJCWlmICh0ZXN0X2JpdChSMUJJT19CZWhpbmRJTywgJnIxX2Jpby0+c3RhdGUpKSB7CgkJCQkvKiBmcmVlIGV4dHJhIGNvcHkgb2YgdGhlIGRhdGEgcGFnZXMgKi8KCQkJCWludCBpID0gYmlvLT5iaV92Y250OwoJCQkJd2hpbGUgKGktLSkKCQkJCQlzYWZlX3B1dF9wYWdlKGJpby0+YmlfaW9fdmVjW2ldLmJ2X3BhZ2UpOwoJCQl9CgkJCS8qIGNsZWFyIHRoZSBiaXRtYXAgaWYgYWxsIHdyaXRlcyBjb21wbGV0ZSBzdWNjZXNzZnVsbHkgKi8KCQkJYml0bWFwX2VuZHdyaXRlKHIxX2Jpby0+bWRkZXYtPmJpdG1hcCwgcjFfYmlvLT5zZWN0b3IsCgkJCQkJcjFfYmlvLT5zZWN0b3JzLAoJCQkJCSF0ZXN0X2JpdChSMUJJT19EZWdyYWRlZCwgJnIxX2Jpby0+c3RhdGUpLAoJCQkJCWJlaGluZCk7CgkJCW1kX3dyaXRlX2VuZChyMV9iaW8tPm1kZGV2KTsKCQkJcmFpZF9lbmRfYmlvX2lvKHIxX2Jpbyk7CgkJfQoJfQoKCWlmICh0b19wdXQpCgkJYmlvX3B1dCh0b19wdXQpOwoKCXJldHVybiAwOwp9CgoKLyoKICogVGhpcyByb3V0aW5lIHJldHVybnMgdGhlIGRpc2sgZnJvbSB3aGljaCB0aGUgcmVxdWVzdGVkIHJlYWQgc2hvdWxkCiAqIGJlIGRvbmUuIFRoZXJlIGlzIGEgcGVyLWFycmF5ICduZXh0IGV4cGVjdGVkIHNlcXVlbnRpYWwgSU8nIHNlY3RvcgogKiBudW1iZXIgLSBpZiB0aGlzIG1hdGNoZXMgb24gdGhlIG5leHQgSU8gdGhlbiB3ZSB1c2UgdGhlIGxhc3QgZGlzay4KICogVGhlcmUgaXMgYWxzbyBhIHBlci1kaXNrICdsYXN0IGtub3cgaGVhZCBwb3NpdGlvbicgc2VjdG9yIHRoYXQgaXMKICogbWFpbnRhaW5lZCBmcm9tIElSUSBjb250ZXh0cywgYm90aCB0aGUgbm9ybWFsIGFuZCB0aGUgcmVzeW5jIElPCiAqIGNvbXBsZXRpb24gaGFuZGxlcnMgdXBkYXRlIHRoaXMgcG9zaXRpb24gY29ycmVjdGx5LiBJZiB0aGVyZSBpcyBubwogKiBwZXJmZWN0IHNlcXVlbnRpYWwgbWF0Y2ggdGhlbiB3ZSBwaWNrIHRoZSBkaXNrIHdob3NlIGhlYWQgaXMgY2xvc2VzdC4KICoKICogSWYgdGhlcmUgYXJlIDIgbWlycm9ycyBpbiB0aGUgc2FtZSAyIGRldmljZXMsIHBlcmZvcm1hbmNlIGRlZ3JhZGVzCiAqIGJlY2F1c2UgcG9zaXRpb24gaXMgbWlycm9yLCBub3QgZGV2aWNlIGJhc2VkLgogKgogKiBUaGUgcmRldiBmb3IgdGhlIGRldmljZSBzZWxlY3RlZCB3aWxsIGhhdmUgbnJfcGVuZGluZyBpbmNyZW1lbnRlZC4KICovCnN0YXRpYyBpbnQgcmVhZF9iYWxhbmNlKGNvbmZfdCAqY29uZiwgcjFiaW9fdCAqcjFfYmlvKQp7Cgljb25zdCB1bnNpZ25lZCBsb25nIHRoaXNfc2VjdG9yID0gcjFfYmlvLT5zZWN0b3I7CglpbnQgbmV3X2Rpc2sgPSBjb25mLT5sYXN0X3VzZWQsIGRpc2sgPSBuZXdfZGlzazsKCWludCB3b25seV9kaXNrID0gLTE7Cgljb25zdCBpbnQgc2VjdG9ycyA9IHIxX2Jpby0+c2VjdG9yczsKCXNlY3Rvcl90IG5ld19kaXN0YW5jZSwgY3VycmVudF9kaXN0YW5jZTsKCW1ka19yZGV2X3QgKnJkZXY7CgoJcmN1X3JlYWRfbG9jaygpOwoJLyoKCSAqIENoZWNrIGlmIHdlIGNhbiBiYWxhbmNlLiBXZSBjYW4gYmFsYW5jZSBvbiB0aGUgd2hvbGUKCSAqIGRldmljZSBpZiBubyByZXN5bmMgaXMgZ29pbmcgb24sIG9yIGJlbG93IHRoZSByZXN5bmMgd2luZG93LgoJICogV2UgdGFrZSB0aGUgZmlyc3QgcmVhZGFibGUgZGlzayB3aGVuIGFib3ZlIHRoZSByZXN5bmMgd2luZG93LgoJICovCiByZXRyeToKCWlmIChjb25mLT5tZGRldi0+cmVjb3ZlcnlfY3AgPCBNYXhTZWN0b3IgJiYKCSAgICAodGhpc19zZWN0b3IgKyBzZWN0b3JzID49IGNvbmYtPm5leHRfcmVzeW5jKSkgewoJCS8qIENob29zZSB0aGUgZmlyc3Qgb3BlcmF0aW9uIGRldmljZSwgZm9yIGNvbnNpc3RhbmN5ICovCgkJbmV3X2Rpc2sgPSAwOwoKCQlmb3IgKHJkZXYgPSByY3VfZGVyZWZlcmVuY2UoY29uZi0+bWlycm9yc1tuZXdfZGlza10ucmRldik7CgkJICAgICByMV9iaW8tPmJpb3NbbmV3X2Rpc2tdID09IElPX0JMT0NLRUQgfHwKCQkgICAgICFyZGV2IHx8ICF0ZXN0X2JpdChJbl9zeW5jLCAmcmRldi0+ZmxhZ3MpCgkJCSAgICAgfHwgdGVzdF9iaXQoV3JpdGVNb3N0bHksICZyZGV2LT5mbGFncyk7CgkJICAgICByZGV2ID0gcmN1X2RlcmVmZXJlbmNlKGNvbmYtPm1pcnJvcnNbKytuZXdfZGlza10ucmRldikpIHsKCgkJCWlmIChyZGV2ICYmIHRlc3RfYml0KEluX3N5bmMsICZyZGV2LT5mbGFncykgJiYKCQkJCXIxX2Jpby0+Ymlvc1tuZXdfZGlza10gIT0gSU9fQkxPQ0tFRCkKCQkJCXdvbmx5X2Rpc2sgPSBuZXdfZGlzazsKCgkJCWlmIChuZXdfZGlzayA9PSBjb25mLT5yYWlkX2Rpc2tzIC0gMSkgewoJCQkJbmV3X2Rpc2sgPSB3b25seV9kaXNrOwoJCQkJYnJlYWs7CgkJCX0KCQl9CgkJZ290byByYl9vdXQ7Cgl9CgoKCS8qIG1ha2Ugc3VyZSB0aGUgZGlzayBpcyBvcGVyYXRpb25hbCAqLwoJZm9yIChyZGV2ID0gcmN1X2RlcmVmZXJlbmNlKGNvbmYtPm1pcnJvcnNbbmV3X2Rpc2tdLnJkZXYpOwoJICAgICByMV9iaW8tPmJpb3NbbmV3X2Rpc2tdID09IElPX0JMT0NLRUQgfHwKCSAgICAgIXJkZXYgfHwgIXRlc3RfYml0KEluX3N5bmMsICZyZGV2LT5mbGFncykgfHwKCQkgICAgIHRlc3RfYml0KFdyaXRlTW9zdGx5LCAmcmRldi0+ZmxhZ3MpOwoJICAgICByZGV2ID0gcmN1X2RlcmVmZXJlbmNlKGNvbmYtPm1pcnJvcnNbbmV3X2Rpc2tdLnJkZXYpKSB7CgoJCWlmIChyZGV2ICYmIHRlc3RfYml0KEluX3N5bmMsICZyZGV2LT5mbGFncykgJiYKCQkgICAgcjFfYmlvLT5iaW9zW25ld19kaXNrXSAhPSBJT19CTE9DS0VEKQoJCQl3b25seV9kaXNrID0gbmV3X2Rpc2s7CgoJCWlmIChuZXdfZGlzayA8PSAwKQoJCQluZXdfZGlzayA9IGNvbmYtPnJhaWRfZGlza3M7CgkJbmV3X2Rpc2stLTsKCQlpZiAobmV3X2Rpc2sgPT0gZGlzaykgewoJCQluZXdfZGlzayA9IHdvbmx5X2Rpc2s7CgkJCWJyZWFrOwoJCX0KCX0KCglpZiAobmV3X2Rpc2sgPCAwKQoJCWdvdG8gcmJfb3V0OwoKCWRpc2sgPSBuZXdfZGlzazsKCS8qIG5vdyBkaXNrID09IG5ld19kaXNrID09IHN0YXJ0aW5nIHBvaW50IGZvciBzZWFyY2ggKi8KCgkvKgoJICogRG9uJ3QgY2hhbmdlIHRvIGFub3RoZXIgZGlzayBmb3Igc2VxdWVudGlhbCByZWFkczoKCSAqLwoJaWYgKGNvbmYtPm5leHRfc2VxX3NlY3QgPT0gdGhpc19zZWN0b3IpCgkJZ290byByYl9vdXQ7CglpZiAodGhpc19zZWN0b3IgPT0gY29uZi0+bWlycm9yc1tuZXdfZGlza10uaGVhZF9wb3NpdGlvbikKCQlnb3RvIHJiX291dDsKCgljdXJyZW50X2Rpc3RhbmNlID0gYWJzKHRoaXNfc2VjdG9yIC0gY29uZi0+bWlycm9yc1tkaXNrXS5oZWFkX3Bvc2l0aW9uKTsKCgkvKiBGaW5kIHRoZSBkaXNrIHdob3NlIGhlYWQgaXMgY2xvc2VzdCAqLwoKCWRvIHsKCQlpZiAoZGlzayA8PSAwKQoJCQlkaXNrID0gY29uZi0+cmFpZF9kaXNrczsKCQlkaXNrLS07CgoJCXJkZXYgPSByY3VfZGVyZWZlcmVuY2UoY29uZi0+bWlycm9yc1tkaXNrXS5yZGV2KTsKCgkJaWYgKCFyZGV2IHx8IHIxX2Jpby0+Ymlvc1tkaXNrXSA9PSBJT19CTE9DS0VEIHx8CgkJICAgICF0ZXN0X2JpdChJbl9zeW5jLCAmcmRldi0+ZmxhZ3MpIHx8CgkJICAgIHRlc3RfYml0KFdyaXRlTW9zdGx5LCAmcmRldi0+ZmxhZ3MpKQoJCQljb250aW51ZTsKCgkJaWYgKCFhdG9taWNfcmVhZCgmcmRldi0+bnJfcGVuZGluZykpIHsKCQkJbmV3X2Rpc2sgPSBkaXNrOwoJCQlicmVhazsKCQl9CgkJbmV3X2Rpc3RhbmNlID0gYWJzKHRoaXNfc2VjdG9yIC0gY29uZi0+bWlycm9yc1tkaXNrXS5oZWFkX3Bvc2l0aW9uKTsKCQlpZiAobmV3X2Rpc3RhbmNlIDwgY3VycmVudF9kaXN0YW5jZSkgewoJCQljdXJyZW50X2Rpc3RhbmNlID0gbmV3X2Rpc3RhbmNlOwoJCQluZXdfZGlzayA9IGRpc2s7CgkJfQoJfSB3aGlsZSAoZGlzayAhPSBjb25mLT5sYXN0X3VzZWQpOwoKIHJiX291dDoKCgoJaWYgKG5ld19kaXNrID49IDApIHsKCQlyZGV2ID0gcmN1X2RlcmVmZXJlbmNlKGNvbmYtPm1pcnJvcnNbbmV3X2Rpc2tdLnJkZXYpOwoJCWlmICghcmRldikKCQkJZ290byByZXRyeTsKCQlhdG9taWNfaW5jKCZyZGV2LT5ucl9wZW5kaW5nKTsKCQlpZiAoIXRlc3RfYml0KEluX3N5bmMsICZyZGV2LT5mbGFncykpIHsKCQkJLyogY2Fubm90IHJpc2sgcmV0dXJuaW5nIGEgZGV2aWNlIHRoYXQgZmFpbGVkCgkJCSAqIGJlZm9yZSB3ZSBpbmMnZWQgbnJfcGVuZGluZwoJCQkgKi8KCQkJcmRldl9kZWNfcGVuZGluZyhyZGV2LCBjb25mLT5tZGRldik7CgkJCWdvdG8gcmV0cnk7CgkJfQoJCWNvbmYtPm5leHRfc2VxX3NlY3QgPSB0aGlzX3NlY3RvciArIHNlY3RvcnM7CgkJY29uZi0+bGFzdF91c2VkID0gbmV3X2Rpc2s7Cgl9CglyY3VfcmVhZF91bmxvY2soKTsKCglyZXR1cm4gbmV3X2Rpc2s7Cn0KCnN0YXRpYyB2b2lkIHVucGx1Z19zbGF2ZXMobWRkZXZfdCAqbWRkZXYpCnsKCWNvbmZfdCAqY29uZiA9IG1kZGV2X3RvX2NvbmYobWRkZXYpOwoJaW50IGk7CgoJcmN1X3JlYWRfbG9jaygpOwoJZm9yIChpPTA7IGk8bWRkZXYtPnJhaWRfZGlza3M7IGkrKykgewoJCW1ka19yZGV2X3QgKnJkZXYgPSByY3VfZGVyZWZlcmVuY2UoY29uZi0+bWlycm9yc1tpXS5yZGV2KTsKCQlpZiAocmRldiAmJiAhdGVzdF9iaXQoRmF1bHR5LCAmcmRldi0+ZmxhZ3MpICYmIGF0b21pY19yZWFkKCZyZGV2LT5ucl9wZW5kaW5nKSkgewoJCQlyZXF1ZXN0X3F1ZXVlX3QgKnJfcXVldWUgPSBiZGV2X2dldF9xdWV1ZShyZGV2LT5iZGV2KTsKCgkJCWF0b21pY19pbmMoJnJkZXYtPm5yX3BlbmRpbmcpOwoJCQlyY3VfcmVhZF91bmxvY2soKTsKCgkJCWlmIChyX3F1ZXVlLT51bnBsdWdfZm4pCgkJCQlyX3F1ZXVlLT51bnBsdWdfZm4ocl9xdWV1ZSk7CgoJCQlyZGV2X2RlY19wZW5kaW5nKHJkZXYsIG1kZGV2KTsKCQkJcmN1X3JlYWRfbG9jaygpOwoJCX0KCX0KCXJjdV9yZWFkX3VubG9jaygpOwp9CgpzdGF0aWMgdm9pZCByYWlkMV91bnBsdWcocmVxdWVzdF9xdWV1ZV90ICpxKQp7CgltZGRldl90ICptZGRldiA9IHEtPnF1ZXVlZGF0YTsKCgl1bnBsdWdfc2xhdmVzKG1kZGV2KTsKCW1kX3dha2V1cF90aHJlYWQobWRkZXYtPnRocmVhZCk7Cn0KCnN0YXRpYyBpbnQgcmFpZDFfaXNzdWVfZmx1c2gocmVxdWVzdF9xdWV1ZV90ICpxLCBzdHJ1Y3QgZ2VuZGlzayAqZGlzaywKCQkJICAgICBzZWN0b3JfdCAqZXJyb3Jfc2VjdG9yKQp7CgltZGRldl90ICptZGRldiA9IHEtPnF1ZXVlZGF0YTsKCWNvbmZfdCAqY29uZiA9IG1kZGV2X3RvX2NvbmYobWRkZXYpOwoJaW50IGksIHJldCA9IDA7CgoJcmN1X3JlYWRfbG9jaygpOwoJZm9yIChpPTA7IGk8bWRkZXYtPnJhaWRfZGlza3MgJiYgcmV0ID09IDA7IGkrKykgewoJCW1ka19yZGV2X3QgKnJkZXYgPSByY3VfZGVyZWZlcmVuY2UoY29uZi0+bWlycm9yc1tpXS5yZGV2KTsKCQlpZiAocmRldiAmJiAhdGVzdF9iaXQoRmF1bHR5LCAmcmRldi0+ZmxhZ3MpKSB7CgkJCXN0cnVjdCBibG9ja19kZXZpY2UgKmJkZXYgPSByZGV2LT5iZGV2OwoJCQlyZXF1ZXN0X3F1ZXVlX3QgKnJfcXVldWUgPSBiZGV2X2dldF9xdWV1ZShiZGV2KTsKCgkJCWlmICghcl9xdWV1ZS0+aXNzdWVfZmx1c2hfZm4pCgkJCQlyZXQgPSAtRU9QTk9UU1VQUDsKCQkJZWxzZSB7CgkJCQlhdG9taWNfaW5jKCZyZGV2LT5ucl9wZW5kaW5nKTsKCQkJCXJjdV9yZWFkX3VubG9jaygpOwoJCQkJcmV0ID0gcl9xdWV1ZS0+aXNzdWVfZmx1c2hfZm4ocl9xdWV1ZSwgYmRldi0+YmRfZGlzaywKCQkJCQkJCSAgICAgIGVycm9yX3NlY3Rvcik7CgkJCQlyZGV2X2RlY19wZW5kaW5nKHJkZXYsIG1kZGV2KTsKCQkJCXJjdV9yZWFkX2xvY2soKTsKCQkJfQoJCX0KCX0KCXJjdV9yZWFkX3VubG9jaygpOwoJcmV0dXJuIHJldDsKfQoKLyogQmFycmllcnMuLi4uCiAqIFNvbWV0aW1lcyB3ZSBuZWVkIHRvIHN1c3BlbmQgSU8gd2hpbGUgd2UgZG8gc29tZXRoaW5nIGVsc2UsCiAqIGVpdGhlciBzb21lIHJlc3luYy9yZWNvdmVyeSwgb3IgcmVjb25maWd1cmUgdGhlIGFycmF5LgogKiBUbyBkbyB0aGlzIHdlIHJhaXNlIGEgJ2JhcnJpZXInLgogKiBUaGUgJ2JhcnJpZXInIGlzIGEgY291bnRlciB0aGF0IGNhbiBiZSByYWlzZWQgbXVsdGlwbGUgdGltZXMKICogdG8gY291bnQgaG93IG1hbnkgYWN0aXZpdGllcyBhcmUgaGFwcGVuaW5nIHdoaWNoIHByZWNsdWRlCiAqIG5vcm1hbCBJTy4KICogV2UgY2FuIG9ubHkgcmFpc2UgdGhlIGJhcnJpZXIgaWYgdGhlcmUgaXMgbm8gcGVuZGluZyBJTy4KICogaS5lLiBpZiBucl9wZW5kaW5nID09IDAuCiAqIFdlIGNob29zZSBvbmx5IHRvIHJhaXNlIHRoZSBiYXJyaWVyIGlmIG5vLW9uZSBpcyB3YWl0aW5nIGZvciB0aGUKICogYmFycmllciB0byBnbyBkb3duLiAgVGhpcyBtZWFucyB0aGF0IGFzIHNvb24gYXMgYW4gSU8gcmVxdWVzdAogKiBpcyByZWFkeSwgbm8gb3RoZXIgb3BlcmF0aW9ucyB3aGljaCByZXF1aXJlIGEgYmFycmllciB3aWxsIHN0YXJ0CiAqIHVudGlsIHRoZSBJTyByZXF1ZXN0IGhhcyBoYWQgYSBjaGFuY2UuCiAqCiAqIFNvOiByZWd1bGFyIElPIGNhbGxzICd3YWl0X2JhcnJpZXInLiAgV2hlbiB0aGF0IHJldHVybnMgdGhlcmUKICogICAgaXMgbm8gYmFja2dyb3VwIElPIGhhcHBlbmluZywgIEl0IG11c3QgYXJyYW5nZSB0byBjYWxsCiAqICAgIGFsbG93X2JhcnJpZXIgd2hlbiBpdCBoYXMgZmluaXNoZWQgaXRzIElPLgogKiBiYWNrZ3JvdXAgSU8gY2FsbHMgbXVzdCBjYWxsIHJhaXNlX2JhcnJpZXIuICBPbmNlIHRoYXQgcmV0dXJucwogKiAgICB0aGVyZSBpcyBubyBub3JtYWwgSU8gaGFwcGVpbmcuICBJdCBtdXN0IGFycmFuZ2UgdG8gY2FsbAogKiAgICBsb3dlcl9iYXJyaWVyIHdoZW4gdGhlIHBhcnRpY3VsYXIgYmFja2dyb3VuZCBJTyBjb21wbGV0ZXMuCiAqLwojZGVmaW5lIFJFU1lOQ19ERVBUSCAzMgoKc3RhdGljIHZvaWQgcmFpc2VfYmFycmllcihjb25mX3QgKmNvbmYpCnsKCXNwaW5fbG9ja19pcnEoJmNvbmYtPnJlc3luY19sb2NrKTsKCgkvKiBXYWl0IHVudGlsIG5vIGJsb2NrIElPIGlzIHdhaXRpbmcgKi8KCXdhaXRfZXZlbnRfbG9ja19pcnEoY29uZi0+d2FpdF9iYXJyaWVyLCAhY29uZi0+bnJfd2FpdGluZywKCQkJICAgIGNvbmYtPnJlc3luY19sb2NrLAoJCQkgICAgcmFpZDFfdW5wbHVnKGNvbmYtPm1kZGV2LT5xdWV1ZSkpOwoKCS8qIGJsb2NrIGFueSBuZXcgSU8gZnJvbSBzdGFydGluZyAqLwoJY29uZi0+YmFycmllcisrOwoKCS8qIE5vIHdhaXQgZm9yIGFsbCBwZW5kaW5nIElPIHRvIGNvbXBsZXRlICovCgl3YWl0X2V2ZW50X2xvY2tfaXJxKGNvbmYtPndhaXRfYmFycmllciwKCQkJICAgICFjb25mLT5ucl9wZW5kaW5nICYmIGNvbmYtPmJhcnJpZXIgPCBSRVNZTkNfREVQVEgsCgkJCSAgICBjb25mLT5yZXN5bmNfbG9jaywKCQkJICAgIHJhaWQxX3VucGx1Zyhjb25mLT5tZGRldi0+cXVldWUpKTsKCglzcGluX3VubG9ja19pcnEoJmNvbmYtPnJlc3luY19sb2NrKTsKfQoKc3RhdGljIHZvaWQgbG93ZXJfYmFycmllcihjb25mX3QgKmNvbmYpCnsKCXVuc2lnbmVkIGxvbmcgZmxhZ3M7CglzcGluX2xvY2tfaXJxc2F2ZSgmY29uZi0+cmVzeW5jX2xvY2ssIGZsYWdzKTsKCWNvbmYtPmJhcnJpZXItLTsKCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJmNvbmYtPnJlc3luY19sb2NrLCBmbGFncyk7Cgl3YWtlX3VwKCZjb25mLT53YWl0X2JhcnJpZXIpOwp9CgpzdGF0aWMgdm9pZCB3YWl0X2JhcnJpZXIoY29uZl90ICpjb25mKQp7CglzcGluX2xvY2tfaXJxKCZjb25mLT5yZXN5bmNfbG9jayk7CglpZiAoY29uZi0+YmFycmllcikgewoJCWNvbmYtPm5yX3dhaXRpbmcrKzsKCQl3YWl0X2V2ZW50X2xvY2tfaXJxKGNvbmYtPndhaXRfYmFycmllciwgIWNvbmYtPmJhcnJpZXIsCgkJCQkgICAgY29uZi0+cmVzeW5jX2xvY2ssCgkJCQkgICAgcmFpZDFfdW5wbHVnKGNvbmYtPm1kZGV2LT5xdWV1ZSkpOwoJCWNvbmYtPm5yX3dhaXRpbmctLTsKCX0KCWNvbmYtPm5yX3BlbmRpbmcrKzsKCXNwaW5fdW5sb2NrX2lycSgmY29uZi0+cmVzeW5jX2xvY2spOwp9CgpzdGF0aWMgdm9pZCBhbGxvd19iYXJyaWVyKGNvbmZfdCAqY29uZikKewoJdW5zaWduZWQgbG9uZyBmbGFnczsKCXNwaW5fbG9ja19pcnFzYXZlKCZjb25mLT5yZXN5bmNfbG9jaywgZmxhZ3MpOwoJY29uZi0+bnJfcGVuZGluZy0tOwoJc3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmY29uZi0+cmVzeW5jX2xvY2ssIGZsYWdzKTsKCXdha2VfdXAoJmNvbmYtPndhaXRfYmFycmllcik7Cn0KCnN0YXRpYyB2b2lkIGZyZWV6ZV9hcnJheShjb25mX3QgKmNvbmYpCnsKCS8qIHN0b3Agc3luY2lvIGFuZCBub3JtYWwgSU8gYW5kIHdhaXQgZm9yIGV2ZXJ5dGhpbmcgdG8KCSAqIGdvIHF1aXRlLgoJICogV2UgaW5jcmVtZW50IGJhcnJpZXIgYW5kIG5yX3dhaXRpbmcsIGFuZCB0aGVuCgkgKiB3YWl0IHVudGlsIGJhcnJpZXIrbnJfcGVuZGluZyBtYXRjaCBucl9xdWV1ZWQrMgoJICovCglzcGluX2xvY2tfaXJxKCZjb25mLT5yZXN5bmNfbG9jayk7Cgljb25mLT5iYXJyaWVyKys7Cgljb25mLT5ucl93YWl0aW5nKys7Cgl3YWl0X2V2ZW50X2xvY2tfaXJxKGNvbmYtPndhaXRfYmFycmllciwKCQkJICAgIGNvbmYtPmJhcnJpZXIrY29uZi0+bnJfcGVuZGluZyA9PSBjb25mLT5ucl9xdWV1ZWQrMiwKCQkJICAgIGNvbmYtPnJlc3luY19sb2NrLAoJCQkgICAgcmFpZDFfdW5wbHVnKGNvbmYtPm1kZGV2LT5xdWV1ZSkpOwoJc3Bpbl91bmxvY2tfaXJxKCZjb25mLT5yZXN5bmNfbG9jayk7Cn0Kc3RhdGljIHZvaWQgdW5mcmVlemVfYXJyYXkoY29uZl90ICpjb25mKQp7CgkvKiByZXZlcnNlIHRoZSBlZmZlY3Qgb2YgdGhlIGZyZWV6ZSAqLwoJc3Bpbl9sb2NrX2lycSgmY29uZi0+cmVzeW5jX2xvY2spOwoJY29uZi0+YmFycmllci0tOwoJY29uZi0+bnJfd2FpdGluZy0tOwoJd2FrZV91cCgmY29uZi0+d2FpdF9iYXJyaWVyKTsKCXNwaW5fdW5sb2NrX2lycSgmY29uZi0+cmVzeW5jX2xvY2spOwp9CgoKLyogZHVwbGljYXRlIHRoZSBkYXRhIHBhZ2VzIGZvciBiZWhpbmQgSS9PICovCnN0YXRpYyBzdHJ1Y3QgcGFnZSAqKmFsbG9jX2JlaGluZF9wYWdlcyhzdHJ1Y3QgYmlvICpiaW8pCnsKCWludCBpOwoJc3RydWN0IGJpb192ZWMgKmJ2ZWM7CglzdHJ1Y3QgcGFnZSAqKnBhZ2VzID0ga3phbGxvYyhiaW8tPmJpX3ZjbnQgKiBzaXplb2Yoc3RydWN0IHBhZ2UgKiksCgkJCQkJR0ZQX05PSU8pOwoJaWYgKHVubGlrZWx5KCFwYWdlcykpCgkJZ290byBkb19zeW5jX2lvOwoKCWJpb19mb3JfZWFjaF9zZWdtZW50KGJ2ZWMsIGJpbywgaSkgewoJCXBhZ2VzW2ldID0gYWxsb2NfcGFnZShHRlBfTk9JTyk7CgkJaWYgKHVubGlrZWx5KCFwYWdlc1tpXSkpCgkJCWdvdG8gZG9fc3luY19pbzsKCQltZW1jcHkoa21hcChwYWdlc1tpXSkgKyBidmVjLT5idl9vZmZzZXQsCgkJCWttYXAoYnZlYy0+YnZfcGFnZSkgKyBidmVjLT5idl9vZmZzZXQsIGJ2ZWMtPmJ2X2xlbik7CgkJa3VubWFwKHBhZ2VzW2ldKTsKCQlrdW5tYXAoYnZlYy0+YnZfcGFnZSk7Cgl9CgoJcmV0dXJuIHBhZ2VzOwoKZG9fc3luY19pbzoKCWlmIChwYWdlcykKCQlmb3IgKGkgPSAwOyBpIDwgYmlvLT5iaV92Y250ICYmIHBhZ2VzW2ldOyBpKyspCgkJCXB1dF9wYWdlKHBhZ2VzW2ldKTsKCWtmcmVlKHBhZ2VzKTsKCVBSSU5USygiJWRCIGJlaGluZCBhbGxvYyBmYWlsZWQsIGRvaW5nIHN5bmMgSS9PXG4iLCBiaW8tPmJpX3NpemUpOwoJcmV0dXJuIE5VTEw7Cn0KCnN0YXRpYyBpbnQgbWFrZV9yZXF1ZXN0KHJlcXVlc3RfcXVldWVfdCAqcSwgc3RydWN0IGJpbyAqIGJpbykKewoJbWRkZXZfdCAqbWRkZXYgPSBxLT5xdWV1ZWRhdGE7Cgljb25mX3QgKmNvbmYgPSBtZGRldl90b19jb25mKG1kZGV2KTsKCW1pcnJvcl9pbmZvX3QgKm1pcnJvcjsKCXIxYmlvX3QgKnIxX2JpbzsKCXN0cnVjdCBiaW8gKnJlYWRfYmlvOwoJaW50IGksIHRhcmdldHMgPSAwLCBkaXNrczsKCW1ka19yZGV2X3QgKnJkZXY7CglzdHJ1Y3QgYml0bWFwICpiaXRtYXAgPSBtZGRldi0+Yml0bWFwOwoJdW5zaWduZWQgbG9uZyBmbGFnczsKCXN0cnVjdCBiaW9fbGlzdCBibDsKCXN0cnVjdCBwYWdlICoqYmVoaW5kX3BhZ2VzID0gTlVMTDsKCWNvbnN0IGludCBydyA9IGJpb19kYXRhX2RpcihiaW8pOwoJaW50IGRvX2JhcnJpZXJzOwoKCS8qCgkgKiBSZWdpc3RlciB0aGUgbmV3IHJlcXVlc3QgYW5kIHdhaXQgaWYgdGhlIHJlY29uc3RydWN0aW9uCgkgKiB0aHJlYWQgaGFzIHB1dCB1cCBhIGJhciBmb3IgbmV3IHJlcXVlc3RzLgoJICogQ29udGludWUgaW1tZWRpYXRlbHkgaWYgbm8gcmVzeW5jIGlzIGFjdGl2ZSBjdXJyZW50bHkuCgkgKiBXZSB0ZXN0IGJhcnJpZXJzX3dvcmsgKmFmdGVyKiBtZF93cml0ZV9zdGFydCBhcyBtZF93cml0ZV9zdGFydAoJICogbWF5IGNhdXNlIHRoZSBmaXJzdCBzdXBlcmJsb2NrIHdyaXRlLCBhbmQgdGhhdCB3aWxsIGNoZWNrIG91dAoJICogaWYgYmFycmllcnMgd29yay4KCSAqLwoKCW1kX3dyaXRlX3N0YXJ0KG1kZGV2LCBiaW8pOyAvKiB3YWl0IG9uIHN1cGVyYmxvY2sgdXBkYXRlIGVhcmx5ICovCgoJaWYgKHVubGlrZWx5KCFtZGRldi0+YmFycmllcnNfd29yayAmJiBiaW9fYmFycmllcihiaW8pKSkgewoJCWlmIChydyA9PSBXUklURSkKCQkJbWRfd3JpdGVfZW5kKG1kZGV2KTsKCQliaW9fZW5kaW8oYmlvLCBiaW8tPmJpX3NpemUsIC1FT1BOT1RTVVBQKTsKCQlyZXR1cm4gMDsKCX0KCgl3YWl0X2JhcnJpZXIoY29uZik7CgoJZGlza19zdGF0X2luYyhtZGRldi0+Z2VuZGlzaywgaW9zW3J3XSk7CglkaXNrX3N0YXRfYWRkKG1kZGV2LT5nZW5kaXNrLCBzZWN0b3JzW3J3XSwgYmlvX3NlY3RvcnMoYmlvKSk7CgoJLyoKCSAqIG1ha2VfcmVxdWVzdCgpIGNhbiBhYm9ydCB0aGUgb3BlcmF0aW9uIHdoZW4gUkVBREEgaXMgYmVpbmcKCSAqIHVzZWQgYW5kIG5vIGVtcHR5IHJlcXVlc3QgaXMgYXZhaWxhYmxlLgoJICoKCSAqLwoJcjFfYmlvID0gbWVtcG9vbF9hbGxvYyhjb25mLT5yMWJpb19wb29sLCBHRlBfTk9JTyk7CgoJcjFfYmlvLT5tYXN0ZXJfYmlvID0gYmlvOwoJcjFfYmlvLT5zZWN0b3JzID0gYmlvLT5iaV9zaXplID4+IDk7CglyMV9iaW8tPnN0YXRlID0gMDsKCXIxX2Jpby0+bWRkZXYgPSBtZGRldjsKCXIxX2Jpby0+c2VjdG9yID0gYmlvLT5iaV9zZWN0b3I7CgoJaWYgKHJ3ID09IFJFQUQpIHsKCQkvKgoJCSAqIHJlYWQgYmFsYW5jaW5nIGxvZ2ljOgoJCSAqLwoJCWludCByZGlzayA9IHJlYWRfYmFsYW5jZShjb25mLCByMV9iaW8pOwoKCQlpZiAocmRpc2sgPCAwKSB7CgkJCS8qIGNvdWxkbid0IGZpbmQgYW55d2hlcmUgdG8gcmVhZCBmcm9tICovCgkJCXJhaWRfZW5kX2Jpb19pbyhyMV9iaW8pOwoJCQlyZXR1cm4gMDsKCQl9CgkJbWlycm9yID0gY29uZi0+bWlycm9ycyArIHJkaXNrOwoKCQlyMV9iaW8tPnJlYWRfZGlzayA9IHJkaXNrOwoKCQlyZWFkX2JpbyA9IGJpb19jbG9uZShiaW8sIEdGUF9OT0lPKTsKCgkJcjFfYmlvLT5iaW9zW3JkaXNrXSA9IHJlYWRfYmlvOwoKCQlyZWFkX2Jpby0+Ymlfc2VjdG9yID0gcjFfYmlvLT5zZWN0b3IgKyBtaXJyb3ItPnJkZXYtPmRhdGFfb2Zmc2V0OwoJCXJlYWRfYmlvLT5iaV9iZGV2ID0gbWlycm9yLT5yZGV2LT5iZGV2OwoJCXJlYWRfYmlvLT5iaV9lbmRfaW8gPSByYWlkMV9lbmRfcmVhZF9yZXF1ZXN0OwoJCXJlYWRfYmlvLT5iaV9ydyA9IFJFQUQ7CgkJcmVhZF9iaW8tPmJpX3ByaXZhdGUgPSByMV9iaW87CgoJCWdlbmVyaWNfbWFrZV9yZXF1ZXN0KHJlYWRfYmlvKTsKCQlyZXR1cm4gMDsKCX0KCgkvKgoJICogV1JJVEU6CgkgKi8KCS8qIGZpcnN0IHNlbGVjdCB0YXJnZXQgZGV2aWNlcyB1bmRlciBzcGlubG9jayBhbmQKCSAqIGluYyByZWZjb3VudCBvbiB0aGVpciByZGV2LiAgUmVjb3JkIHRoZW0gYnkgc2V0dGluZwoJICogYmlvc1t4XSB0byBiaW8KCSAqLwoJZGlza3MgPSBjb25mLT5yYWlkX2Rpc2tzOwojaWYgMAoJeyBzdGF0aWMgaW50IGZpcnN0PTE7CglpZiAoZmlyc3QpIHByaW50aygiRmlyc3QgV3JpdGUgc2VjdG9yICVsbHUgZGlza3MgJWRcbiIsCgkJCSAgKHVuc2lnbmVkIGxvbmcgbG9uZylyMV9iaW8tPnNlY3RvciwgZGlza3MpOwoJZmlyc3QgPSAwOwoJfQojZW5kaWYKCXJjdV9yZWFkX2xvY2soKTsKCWZvciAoaSA9IDA7ICBpIDwgZGlza3M7IGkrKykgewoJCWlmICgocmRldj1yY3VfZGVyZWZlcmVuY2UoY29uZi0+bWlycm9yc1tpXS5yZGV2KSkgIT0gTlVMTCAmJgoJCSAgICAhdGVzdF9iaXQoRmF1bHR5LCAmcmRldi0+ZmxhZ3MpKSB7CgkJCWF0b21pY19pbmMoJnJkZXYtPm5yX3BlbmRpbmcpOwoJCQlpZiAodGVzdF9iaXQoRmF1bHR5LCAmcmRldi0+ZmxhZ3MpKSB7CgkJCQlyZGV2X2RlY19wZW5kaW5nKHJkZXYsIG1kZGV2KTsKCQkJCXIxX2Jpby0+Ymlvc1tpXSA9IE5VTEw7CgkJCX0gZWxzZQoJCQkJcjFfYmlvLT5iaW9zW2ldID0gYmlvOwoJCQl0YXJnZXRzKys7CgkJfSBlbHNlCgkJCXIxX2Jpby0+Ymlvc1tpXSA9IE5VTEw7Cgl9CglyY3VfcmVhZF91bmxvY2soKTsKCglCVUdfT04odGFyZ2V0cyA9PSAwKTsgLyogd2UgbmV2ZXIgZmFpbCB0aGUgbGFzdCBkZXZpY2UgKi8KCglpZiAodGFyZ2V0cyA8IGNvbmYtPnJhaWRfZGlza3MpIHsKCQkvKiBhcnJheSBpcyBkZWdyYWRlZCwgd2Ugd2lsbCBub3QgY2xlYXIgdGhlIGJpdG1hcAoJCSAqIG9uIEkvTyBjb21wbGV0aW9uIChzZWUgcmFpZDFfZW5kX3dyaXRlX3JlcXVlc3QpICovCgkJc2V0X2JpdChSMUJJT19EZWdyYWRlZCwgJnIxX2Jpby0+c3RhdGUpOwoJfQoKCS8qIGRvIGJlaGluZCBJL08gPyAqLwoJaWYgKGJpdG1hcCAmJgoJICAgIGF0b21pY19yZWFkKCZiaXRtYXAtPmJlaGluZF93cml0ZXMpIDwgYml0bWFwLT5tYXhfd3JpdGVfYmVoaW5kICYmCgkgICAgKGJlaGluZF9wYWdlcyA9IGFsbG9jX2JlaGluZF9wYWdlcyhiaW8pKSAhPSBOVUxMKQoJCXNldF9iaXQoUjFCSU9fQmVoaW5kSU8sICZyMV9iaW8tPnN0YXRlKTsKCglhdG9taWNfc2V0KCZyMV9iaW8tPnJlbWFpbmluZywgMCk7CglhdG9taWNfc2V0KCZyMV9iaW8tPmJlaGluZF9yZW1haW5pbmcsIDApOwoKCWRvX2JhcnJpZXJzID0gYmlvX2JhcnJpZXIoYmlvKTsKCWlmIChkb19iYXJyaWVycykKCQlzZXRfYml0KFIxQklPX0JhcnJpZXIsICZyMV9iaW8tPnN0YXRlKTsKCgliaW9fbGlzdF9pbml0KCZibCk7Cglmb3IgKGkgPSAwOyBpIDwgZGlza3M7IGkrKykgewoJCXN0cnVjdCBiaW8gKm1iaW87CgkJaWYgKCFyMV9iaW8tPmJpb3NbaV0pCgkJCWNvbnRpbnVlOwoKCQltYmlvID0gYmlvX2Nsb25lKGJpbywgR0ZQX05PSU8pOwoJCXIxX2Jpby0+Ymlvc1tpXSA9IG1iaW87CgoJCW1iaW8tPmJpX3NlY3Rvcgk9IHIxX2Jpby0+c2VjdG9yICsgY29uZi0+bWlycm9yc1tpXS5yZGV2LT5kYXRhX29mZnNldDsKCQltYmlvLT5iaV9iZGV2ID0gY29uZi0+bWlycm9yc1tpXS5yZGV2LT5iZGV2OwoJCW1iaW8tPmJpX2VuZF9pbwk9IHJhaWQxX2VuZF93cml0ZV9yZXF1ZXN0OwoJCW1iaW8tPmJpX3J3ID0gV1JJVEUgfCBkb19iYXJyaWVyczsKCQltYmlvLT5iaV9wcml2YXRlID0gcjFfYmlvOwoKCQlpZiAoYmVoaW5kX3BhZ2VzKSB7CgkJCXN0cnVjdCBiaW9fdmVjICpidmVjOwoJCQlpbnQgajsKCgkJCS8qIFllcywgSSByZWFsbHkgd2FudCB0aGUgJ19fJyB2ZXJzaW9uIHNvIHRoYXQKCQkJICogd2UgY2xlYXIgYW55IHVudXNlZCBwb2ludGVyIGluIHRoZSBpb192ZWMsIHJhdGhlcgoJCQkgKiB0aGFuIGxlYXZlIHRoZW0gdW5jaGFuZ2VkLiAgVGhpcyBpcyBpbXBvcnRhbnQKCQkJICogYmVjYXVzZSB3aGVuIHdlIGNvbWUgdG8gZnJlZSB0aGUgcGFnZXMsIHdlIHdvbid0CgkJCSAqIGtub3cgdGhlIG9yaWdpbmlhbCBiaV9pZHgsIHNvIHdlIGp1c3QgZnJlZQoJCQkgKiB0aGVtIGFsbAoJCQkgKi8KCQkJX19iaW9fZm9yX2VhY2hfc2VnbWVudChidmVjLCBtYmlvLCBqLCAwKQoJCQkJYnZlYy0+YnZfcGFnZSA9IGJlaGluZF9wYWdlc1tqXTsKCQkJaWYgKHRlc3RfYml0KFdyaXRlTW9zdGx5LCAmY29uZi0+bWlycm9yc1tpXS5yZGV2LT5mbGFncykpCgkJCQlhdG9taWNfaW5jKCZyMV9iaW8tPmJlaGluZF9yZW1haW5pbmcpOwoJCX0KCgkJYXRvbWljX2luYygmcjFfYmlvLT5yZW1haW5pbmcpOwoKCQliaW9fbGlzdF9hZGQoJmJsLCBtYmlvKTsKCX0KCWtmcmVlKGJlaGluZF9wYWdlcyk7IC8qIHRoZSBiZWhpbmQgcGFnZXMgYXJlIGF0dGFjaGVkIHRvIHRoZSBiaW9zIG5vdyAqLwoKCWJpdG1hcF9zdGFydHdyaXRlKGJpdG1hcCwgYmlvLT5iaV9zZWN0b3IsIHIxX2Jpby0+c2VjdG9ycywKCQkJCXRlc3RfYml0KFIxQklPX0JlaGluZElPLCAmcjFfYmlvLT5zdGF0ZSkpOwoJc3Bpbl9sb2NrX2lycXNhdmUoJmNvbmYtPmRldmljZV9sb2NrLCBmbGFncyk7CgliaW9fbGlzdF9tZXJnZSgmY29uZi0+cGVuZGluZ19iaW9fbGlzdCwgJmJsKTsKCWJpb19saXN0X2luaXQoJmJsKTsKCglibGtfcGx1Z19kZXZpY2UobWRkZXYtPnF1ZXVlKTsKCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJmNvbmYtPmRldmljZV9sb2NrLCBmbGFncyk7CgojaWYgMAoJd2hpbGUgKChiaW8gPSBiaW9fbGlzdF9wb3AoJmJsKSkgIT0gTlVMTCkKCQlnZW5lcmljX21ha2VfcmVxdWVzdChiaW8pOwojZW5kaWYKCglyZXR1cm4gMDsKfQoKc3RhdGljIHZvaWQgc3RhdHVzKHN0cnVjdCBzZXFfZmlsZSAqc2VxLCBtZGRldl90ICptZGRldikKewoJY29uZl90ICpjb25mID0gbWRkZXZfdG9fY29uZihtZGRldik7CglpbnQgaTsKCglzZXFfcHJpbnRmKHNlcSwgIiBbJWQvJWRdIFsiLCBjb25mLT5yYWlkX2Rpc2tzLAoJCQkJCQljb25mLT53b3JraW5nX2Rpc2tzKTsKCWZvciAoaSA9IDA7IGkgPCBjb25mLT5yYWlkX2Rpc2tzOyBpKyspCgkJc2VxX3ByaW50ZihzZXEsICIlcyIsCgkJCSAgICAgIGNvbmYtPm1pcnJvcnNbaV0ucmRldiAmJgoJCQkgICAgICB0ZXN0X2JpdChJbl9zeW5jLCAmY29uZi0+bWlycm9yc1tpXS5yZGV2LT5mbGFncykgPyAiVSIgOiAiXyIpOwoJc2VxX3ByaW50ZihzZXEsICJdIik7Cn0KCgpzdGF0aWMgdm9pZCBlcnJvcihtZGRldl90ICptZGRldiwgbWRrX3JkZXZfdCAqcmRldikKewoJY2hhciBiW0JERVZOQU1FX1NJWkVdOwoJY29uZl90ICpjb25mID0gbWRkZXZfdG9fY29uZihtZGRldik7CgoJLyoKCSAqIElmIGl0IGlzIG5vdCBvcGVyYXRpb25hbCwgdGhlbiB3ZSBoYXZlIGFscmVhZHkgbWFya2VkIGl0IGFzIGRlYWQKCSAqIGVsc2UgaWYgaXQgaXMgdGhlIGxhc3Qgd29ya2luZyBkaXNrcywgaWdub3JlIHRoZSBlcnJvciwgbGV0IHRoZQoJICogbmV4dCBsZXZlbCB1cCBrbm93LgoJICogZWxzZSBtYXJrIHRoZSBkcml2ZSBhcyBmYWlsZWQKCSAqLwoJaWYgKHRlc3RfYml0KEluX3N5bmMsICZyZGV2LT5mbGFncykKCSAgICAmJiBjb25mLT53b3JraW5nX2Rpc2tzID09IDEpCgkJLyoKCQkgKiBEb24ndCBmYWlsIHRoZSBkcml2ZSwgYWN0IGFzIHRob3VnaCB3ZSB3ZXJlIGp1c3QgYQoJCSAqIG5vcm1hbCBzaW5nbGUgZHJpdmUKCQkgKi8KCQlyZXR1cm47CglpZiAodGVzdF9iaXQoSW5fc3luYywgJnJkZXYtPmZsYWdzKSkgewoJCW1kZGV2LT5kZWdyYWRlZCsrOwoJCWNvbmYtPndvcmtpbmdfZGlza3MtLTsKCQkvKgoJCSAqIGlmIHJlY292ZXJ5IGlzIHJ1bm5pbmcsIG1ha2Ugc3VyZSBpdCBhYm9ydHMuCgkJICovCgkJc2V0X2JpdChNRF9SRUNPVkVSWV9FUlIsICZtZGRldi0+cmVjb3ZlcnkpOwoJfQoJY2xlYXJfYml0KEluX3N5bmMsICZyZGV2LT5mbGFncyk7CglzZXRfYml0KEZhdWx0eSwgJnJkZXYtPmZsYWdzKTsKCW1kZGV2LT5zYl9kaXJ0eSA9IDE7CglwcmludGsoS0VSTl9BTEVSVCAicmFpZDE6IERpc2sgZmFpbHVyZSBvbiAlcywgZGlzYWJsaW5nIGRldmljZS4gXG4iCgkJIglPcGVyYXRpb24gY29udGludWluZyBvbiAlZCBkZXZpY2VzXG4iLAoJCWJkZXZuYW1lKHJkZXYtPmJkZXYsYiksIGNvbmYtPndvcmtpbmdfZGlza3MpOwp9CgpzdGF0aWMgdm9pZCBwcmludF9jb25mKGNvbmZfdCAqY29uZikKewoJaW50IGk7CgltaXJyb3JfaW5mb190ICp0bXA7CgoJcHJpbnRrKCJSQUlEMSBjb25mIHByaW50b3V0OlxuIik7CglpZiAoIWNvbmYpIHsKCQlwcmludGsoIighY29uZilcbiIpOwoJCXJldHVybjsKCX0KCXByaW50aygiIC0tLSB3ZDolZCByZDolZFxuIiwgY29uZi0+d29ya2luZ19kaXNrcywKCQljb25mLT5yYWlkX2Rpc2tzKTsKCglmb3IgKGkgPSAwOyBpIDwgY29uZi0+cmFpZF9kaXNrczsgaSsrKSB7CgkJY2hhciBiW0JERVZOQU1FX1NJWkVdOwoJCXRtcCA9IGNvbmYtPm1pcnJvcnMgKyBpOwoJCWlmICh0bXAtPnJkZXYpCgkJCXByaW50aygiIGRpc2sgJWQsIHdvOiVkLCBvOiVkLCBkZXY6JXNcbiIsCgkJCQlpLCAhdGVzdF9iaXQoSW5fc3luYywgJnRtcC0+cmRldi0+ZmxhZ3MpLCAhdGVzdF9iaXQoRmF1bHR5LCAmdG1wLT5yZGV2LT5mbGFncyksCgkJCQliZGV2bmFtZSh0bXAtPnJkZXYtPmJkZXYsYikpOwoJfQp9CgpzdGF0aWMgdm9pZCBjbG9zZV9zeW5jKGNvbmZfdCAqY29uZikKewoJd2FpdF9iYXJyaWVyKGNvbmYpOwoJYWxsb3dfYmFycmllcihjb25mKTsKCgltZW1wb29sX2Rlc3Ryb3koY29uZi0+cjFidWZfcG9vbCk7Cgljb25mLT5yMWJ1Zl9wb29sID0gTlVMTDsKfQoKc3RhdGljIGludCByYWlkMV9zcGFyZV9hY3RpdmUobWRkZXZfdCAqbWRkZXYpCnsKCWludCBpOwoJY29uZl90ICpjb25mID0gbWRkZXYtPnByaXZhdGU7CgltaXJyb3JfaW5mb190ICp0bXA7CgoJLyoKCSAqIEZpbmQgYWxsIGZhaWxlZCBkaXNrcyB3aXRoaW4gdGhlIFJBSUQxIGNvbmZpZ3VyYXRpb24gCgkgKiBhbmQgbWFyayB0aGVtIHJlYWRhYmxlCgkgKi8KCWZvciAoaSA9IDA7IGkgPCBjb25mLT5yYWlkX2Rpc2tzOyBpKyspIHsKCQl0bXAgPSBjb25mLT5taXJyb3JzICsgaTsKCQlpZiAodG1wLT5yZGV2IAoJCSAgICAmJiAhdGVzdF9iaXQoRmF1bHR5LCAmdG1wLT5yZGV2LT5mbGFncykKCQkgICAgJiYgIXRlc3RfYml0KEluX3N5bmMsICZ0bXAtPnJkZXYtPmZsYWdzKSkgewoJCQljb25mLT53b3JraW5nX2Rpc2tzKys7CgkJCW1kZGV2LT5kZWdyYWRlZC0tOwoJCQlzZXRfYml0KEluX3N5bmMsICZ0bXAtPnJkZXYtPmZsYWdzKTsKCQl9Cgl9CgoJcHJpbnRfY29uZihjb25mKTsKCXJldHVybiAwOwp9CgoKc3RhdGljIGludCByYWlkMV9hZGRfZGlzayhtZGRldl90ICptZGRldiwgbWRrX3JkZXZfdCAqcmRldikKewoJY29uZl90ICpjb25mID0gbWRkZXYtPnByaXZhdGU7CglpbnQgZm91bmQgPSAwOwoJaW50IG1pcnJvciA9IDA7CgltaXJyb3JfaW5mb190ICpwOwoKCWZvciAobWlycm9yPTA7IG1pcnJvciA8IG1kZGV2LT5yYWlkX2Rpc2tzOyBtaXJyb3IrKykKCQlpZiAoICEocD1jb25mLT5taXJyb3JzK21pcnJvciktPnJkZXYpIHsKCgkJCWJsa19xdWV1ZV9zdGFja19saW1pdHMobWRkZXYtPnF1ZXVlLAoJCQkJCSAgICAgICByZGV2LT5iZGV2LT5iZF9kaXNrLT5xdWV1ZSk7CgkJCS8qIGFzIHdlIGRvbid0IGhvbm91ciBtZXJnZV9idmVjX2ZuLCB3ZSBtdXN0IG5ldmVyIHJpc2sKCQkJICogdmlvbGF0aW5nIGl0LCBzbyBsaW1pdCAtPm1heF9zZWN0b3IgdG8gb25lIFBBR0UsIGFzCgkJCSAqIGEgb25lIHBhZ2UgcmVxdWVzdCBpcyBuZXZlciBpbiB2aW9sYXRpb24uCgkJCSAqLwoJCQlpZiAocmRldi0+YmRldi0+YmRfZGlzay0+cXVldWUtPm1lcmdlX2J2ZWNfZm4gJiYKCQkJICAgIG1kZGV2LT5xdWV1ZS0+bWF4X3NlY3RvcnMgPiAoUEFHRV9TSVpFPj45KSkKCQkJCWJsa19xdWV1ZV9tYXhfc2VjdG9ycyhtZGRldi0+cXVldWUsIFBBR0VfU0laRT4+OSk7CgoJCQlwLT5oZWFkX3Bvc2l0aW9uID0gMDsKCQkJcmRldi0+cmFpZF9kaXNrID0gbWlycm9yOwoJCQlmb3VuZCA9IDE7CgkJCS8qIEFzIGFsbCBkZXZpY2VzIGFyZSBlcXVpdmFsZW50LCB3ZSBkb24ndCBuZWVkIGEgZnVsbCByZWNvdmVyeQoJCQkgKiBpZiB0aGlzIHdhcyByZWNlbnRseSBhbnkgZHJpdmUgb2YgdGhlIGFycmF5CgkJCSAqLwoJCQlpZiAocmRldi0+c2F2ZWRfcmFpZF9kaXNrIDwgMCkKCQkJCWNvbmYtPmZ1bGxzeW5jID0gMTsKCQkJcmN1X2Fzc2lnbl9wb2ludGVyKHAtPnJkZXYsIHJkZXYpOwoJCQlicmVhazsKCQl9CgoJcHJpbnRfY29uZihjb25mKTsKCXJldHVybiBmb3VuZDsKfQoKc3RhdGljIGludCByYWlkMV9yZW1vdmVfZGlzayhtZGRldl90ICptZGRldiwgaW50IG51bWJlcikKewoJY29uZl90ICpjb25mID0gbWRkZXYtPnByaXZhdGU7CglpbnQgZXJyID0gMDsKCW1ka19yZGV2X3QgKnJkZXY7CgltaXJyb3JfaW5mb190ICpwID0gY29uZi0+bWlycm9ycysgbnVtYmVyOwoKCXByaW50X2NvbmYoY29uZik7CglyZGV2ID0gcC0+cmRldjsKCWlmIChyZGV2KSB7CgkJaWYgKHRlc3RfYml0KEluX3N5bmMsICZyZGV2LT5mbGFncykgfHwKCQkgICAgYXRvbWljX3JlYWQoJnJkZXYtPm5yX3BlbmRpbmcpKSB7CgkJCWVyciA9IC1FQlVTWTsKCQkJZ290byBhYm9ydDsKCQl9CgkJcC0+cmRldiA9IE5VTEw7CgkJc3luY2hyb25pemVfcmN1KCk7CgkJaWYgKGF0b21pY19yZWFkKCZyZGV2LT5ucl9wZW5kaW5nKSkgewoJCQkvKiBsb3N0IHRoZSByYWNlLCB0cnkgbGF0ZXIgKi8KCQkJZXJyID0gLUVCVVNZOwoJCQlwLT5yZGV2ID0gcmRldjsKCQl9Cgl9CmFib3J0OgoKCXByaW50X2NvbmYoY29uZik7CglyZXR1cm4gZXJyOwp9CgoKc3RhdGljIGludCBlbmRfc3luY19yZWFkKHN0cnVjdCBiaW8gKmJpbywgdW5zaWduZWQgaW50IGJ5dGVzX2RvbmUsIGludCBlcnJvcikKewoJcjFiaW9fdCAqIHIxX2JpbyA9IChyMWJpb190ICopKGJpby0+YmlfcHJpdmF0ZSk7CglpbnQgaTsKCglpZiAoYmlvLT5iaV9zaXplKQoJCXJldHVybiAxOwoKCWZvciAoaT1yMV9iaW8tPm1kZGV2LT5yYWlkX2Rpc2tzOyBpLS07ICkKCQlpZiAocjFfYmlvLT5iaW9zW2ldID09IGJpbykKCQkJYnJlYWs7CglCVUdfT04oaSA8IDApOwoJdXBkYXRlX2hlYWRfcG9zKGksIHIxX2Jpbyk7CgkvKgoJICogd2UgaGF2ZSByZWFkIGEgYmxvY2ssIG5vdyBpdCBuZWVkcyB0byBiZSByZS13cml0dGVuLAoJICogb3IgcmUtcmVhZCBpZiB0aGUgcmVhZCBmYWlsZWQuCgkgKiBXZSBkb24ndCBkbyBtdWNoIGhlcmUsIGp1c3Qgc2NoZWR1bGUgaGFuZGxpbmcgYnkgcmFpZDFkCgkgKi8KCWlmICh0ZXN0X2JpdChCSU9fVVBUT0RBVEUsICZiaW8tPmJpX2ZsYWdzKSkKCQlzZXRfYml0KFIxQklPX1VwdG9kYXRlLCAmcjFfYmlvLT5zdGF0ZSk7CgoJaWYgKGF0b21pY19kZWNfYW5kX3Rlc3QoJnIxX2Jpby0+cmVtYWluaW5nKSkKCQlyZXNjaGVkdWxlX3JldHJ5KHIxX2Jpbyk7CglyZXR1cm4gMDsKfQoKc3RhdGljIGludCBlbmRfc3luY193cml0ZShzdHJ1Y3QgYmlvICpiaW8sIHVuc2lnbmVkIGludCBieXRlc19kb25lLCBpbnQgZXJyb3IpCnsKCWludCB1cHRvZGF0ZSA9IHRlc3RfYml0KEJJT19VUFRPREFURSwgJmJpby0+YmlfZmxhZ3MpOwoJcjFiaW9fdCAqIHIxX2JpbyA9IChyMWJpb190ICopKGJpby0+YmlfcHJpdmF0ZSk7CgltZGRldl90ICptZGRldiA9IHIxX2Jpby0+bWRkZXY7Cgljb25mX3QgKmNvbmYgPSBtZGRldl90b19jb25mKG1kZGV2KTsKCWludCBpOwoJaW50IG1pcnJvcj0wOwoKCWlmIChiaW8tPmJpX3NpemUpCgkJcmV0dXJuIDE7CgoJZm9yIChpID0gMDsgaSA8IGNvbmYtPnJhaWRfZGlza3M7IGkrKykKCQlpZiAocjFfYmlvLT5iaW9zW2ldID09IGJpbykgewoJCQltaXJyb3IgPSBpOwoJCQlicmVhazsKCQl9CglpZiAoIXVwdG9kYXRlKSB7CgkJaW50IHN5bmNfYmxvY2tzID0gMDsKCQlzZWN0b3JfdCBzID0gcjFfYmlvLT5zZWN0b3I7CgkJbG9uZyBzZWN0b3JzX3RvX2dvID0gcjFfYmlvLT5zZWN0b3JzOwoJCS8qIG1ha2Ugc3VyZSB0aGVzZSBiaXRzIGRvZXNuJ3QgZ2V0IGNsZWFyZWQuICovCgkJZG8gewoJCQliaXRtYXBfZW5kX3N5bmMobWRkZXYtPmJpdG1hcCwgcywKCQkJCQkmc3luY19ibG9ja3MsIDEpOwoJCQlzICs9IHN5bmNfYmxvY2tzOwoJCQlzZWN0b3JzX3RvX2dvIC09IHN5bmNfYmxvY2tzOwoJCX0gd2hpbGUgKHNlY3RvcnNfdG9fZ28gPiAwKTsKCQltZF9lcnJvcihtZGRldiwgY29uZi0+bWlycm9yc1ttaXJyb3JdLnJkZXYpOwoJfQoKCXVwZGF0ZV9oZWFkX3BvcyhtaXJyb3IsIHIxX2Jpbyk7CgoJaWYgKGF0b21pY19kZWNfYW5kX3Rlc3QoJnIxX2Jpby0+cmVtYWluaW5nKSkgewoJCW1kX2RvbmVfc3luYyhtZGRldiwgcjFfYmlvLT5zZWN0b3JzLCB1cHRvZGF0ZSk7CgkJcHV0X2J1ZihyMV9iaW8pOwoJfQoJcmV0dXJuIDA7Cn0KCnN0YXRpYyB2b2lkIHN5bmNfcmVxdWVzdF93cml0ZShtZGRldl90ICptZGRldiwgcjFiaW9fdCAqcjFfYmlvKQp7Cgljb25mX3QgKmNvbmYgPSBtZGRldl90b19jb25mKG1kZGV2KTsKCWludCBpOwoJaW50IGRpc2tzID0gY29uZi0+cmFpZF9kaXNrczsKCXN0cnVjdCBiaW8gKmJpbywgKndiaW87CgoJYmlvID0gcjFfYmlvLT5iaW9zW3IxX2Jpby0+cmVhZF9kaXNrXTsKCgoJaWYgKHRlc3RfYml0KE1EX1JFQ09WRVJZX1JFUVVFU1RFRCwgJm1kZGV2LT5yZWNvdmVyeSkpIHsKCQkvKiBXZSBoYXZlIHJlYWQgYWxsIHJlYWRhYmxlIGRldmljZXMuICBJZiB3ZSBoYXZlbid0CgkJICogZ290IHRoZSBibG9jaywgdGhlbiB0aGVyZSBpcyBubyBob3BlIGxlZnQuCgkJICogSWYgd2UgaGF2ZSwgdGhlbiB3ZSB3YW50IHRvIGRvIGEgY29tcGFyaXNvbgoJCSAqIGFuZCBza2lwIHRoZSB3cml0ZSBpZiBldmVyeXRoaW5nIGlzIHRoZSBzYW1lLgoJCSAqIElmIGFueSBibG9ja3MgZmFpbGVkIHRvIHJlYWQsIHRoZW4gd2UgbmVlZCB0bwoJCSAqIGF0dGVtcHQgYW4gb3Zlci13cml0ZQoJCSAqLwoJCWludCBwcmltYXJ5OwoJCWlmICghdGVzdF9iaXQoUjFCSU9fVXB0b2RhdGUsICZyMV9iaW8tPnN0YXRlKSkgewoJCQlmb3IgKGk9MDsgaTxtZGRldi0+cmFpZF9kaXNrczsgaSsrKQoJCQkJaWYgKHIxX2Jpby0+Ymlvc1tpXS0+YmlfZW5kX2lvID09IGVuZF9zeW5jX3JlYWQpCgkJCQkJbWRfZXJyb3IobWRkZXYsIGNvbmYtPm1pcnJvcnNbaV0ucmRldik7CgoJCQltZF9kb25lX3N5bmMobWRkZXYsIHIxX2Jpby0+c2VjdG9ycywgMSk7CgkJCXB1dF9idWYocjFfYmlvKTsKCQkJcmV0dXJuOwoJCX0KCQlmb3IgKHByaW1hcnk9MDsgcHJpbWFyeTxtZGRldi0+cmFpZF9kaXNrczsgcHJpbWFyeSsrKQoJCQlpZiAocjFfYmlvLT5iaW9zW3ByaW1hcnldLT5iaV9lbmRfaW8gPT0gZW5kX3N5bmNfcmVhZCAmJgoJCQkgICAgdGVzdF9iaXQoQklPX1VQVE9EQVRFLCAmcjFfYmlvLT5iaW9zW3ByaW1hcnldLT5iaV9mbGFncykpIHsKCQkJCXIxX2Jpby0+Ymlvc1twcmltYXJ5XS0+YmlfZW5kX2lvID0gTlVMTDsKCQkJCXJkZXZfZGVjX3BlbmRpbmcoY29uZi0+bWlycm9yc1twcmltYXJ5XS5yZGV2LCBtZGRldik7CgkJCQlicmVhazsKCQkJfQoJCXIxX2Jpby0+cmVhZF9kaXNrID0gcHJpbWFyeTsKCQlmb3IgKGk9MDsgaTxtZGRldi0+cmFpZF9kaXNrczsgaSsrKQoJCQlpZiAocjFfYmlvLT5iaW9zW2ldLT5iaV9lbmRfaW8gPT0gZW5kX3N5bmNfcmVhZCAmJgoJCQkgICAgdGVzdF9iaXQoQklPX1VQVE9EQVRFLCAmcjFfYmlvLT5iaW9zW2ldLT5iaV9mbGFncykpIHsKCQkJCWludCBqOwoJCQkJaW50IHZjbnQgPSByMV9iaW8tPnNlY3RvcnMgPj4gKFBBR0VfU0hJRlQtIDkpOwoJCQkJc3RydWN0IGJpbyAqcGJpbyA9IHIxX2Jpby0+Ymlvc1twcmltYXJ5XTsKCQkJCXN0cnVjdCBiaW8gKnNiaW8gPSByMV9iaW8tPmJpb3NbaV07CgkJCQlmb3IgKGogPSB2Y250OyBqLS0gOyApCgkJCQkJaWYgKG1lbWNtcChwYWdlX2FkZHJlc3MocGJpby0+YmlfaW9fdmVjW2pdLmJ2X3BhZ2UpLAoJCQkJCQkgICBwYWdlX2FkZHJlc3Moc2Jpby0+YmlfaW9fdmVjW2pdLmJ2X3BhZ2UpLAoJCQkJCQkgICBQQUdFX1NJWkUpKQoJCQkJCQlicmVhazsKCQkJCWlmIChqID49IDApCgkJCQkJbWRkZXYtPnJlc3luY19taXNtYXRjaGVzICs9IHIxX2Jpby0+c2VjdG9yczsKCQkJCWlmIChqIDwgMCB8fCB0ZXN0X2JpdChNRF9SRUNPVkVSWV9DSEVDSywgJm1kZGV2LT5yZWNvdmVyeSkpIHsKCQkJCQlzYmlvLT5iaV9lbmRfaW8gPSBOVUxMOwoJCQkJCXJkZXZfZGVjX3BlbmRpbmcoY29uZi0+bWlycm9yc1tpXS5yZGV2LCBtZGRldik7CgkJCQl9IGVsc2UgewoJCQkJCS8qIGZpeHVwIHRoZSBiaW8gZm9yIHJldXNlICovCgkJCQkJc2Jpby0+YmlfdmNudCA9IHZjbnQ7CgkJCQkJc2Jpby0+Ymlfc2l6ZSA9IHIxX2Jpby0+c2VjdG9ycyA8PCA5OwoJCQkJCXNiaW8tPmJpX2lkeCA9IDA7CgkJCQkJc2Jpby0+YmlfcGh5c19zZWdtZW50cyA9IDA7CgkJCQkJc2Jpby0+YmlfaHdfc2VnbWVudHMgPSAwOwoJCQkJCXNiaW8tPmJpX2h3X2Zyb250X3NpemUgPSAwOwoJCQkJCXNiaW8tPmJpX2h3X2JhY2tfc2l6ZSA9IDA7CgkJCQkJc2Jpby0+YmlfZmxhZ3MgJj0gfihCSU9fUE9PTF9NQVNLIC0gMSk7CgkJCQkJc2Jpby0+YmlfZmxhZ3MgfD0gMSA8PCBCSU9fVVBUT0RBVEU7CgkJCQkJc2Jpby0+YmlfbmV4dCA9IE5VTEw7CgkJCQkJc2Jpby0+Ymlfc2VjdG9yID0gcjFfYmlvLT5zZWN0b3IgKwoJCQkJCQljb25mLT5taXJyb3JzW2ldLnJkZXYtPmRhdGFfb2Zmc2V0OwoJCQkJCXNiaW8tPmJpX2JkZXYgPSBjb25mLT5taXJyb3JzW2ldLnJkZXYtPmJkZXY7CgkJCQl9CgkJCX0KCX0KCWlmICghdGVzdF9iaXQoUjFCSU9fVXB0b2RhdGUsICZyMV9iaW8tPnN0YXRlKSkgewoJCS8qIG91Y2ggLSBmYWlsZWQgdG8gcmVhZCBhbGwgb2YgdGhhdC4KCQkgKiBUcnkgc29tZSBzeW5jaHJvbm91cyByZWFkcyBvZiBvdGhlciBkZXZpY2VzIHRvIGdldAoJCSAqIGdvb2QgZGF0YSwgbXVjaCBsaWtlIHdpdGggbm9ybWFsIHJlYWQgZXJyb3JzLiAgT25seQoJCSAqIHJlYWQgaW50byB0aGUgcGFnZXMgd2UgYWxyZWFkeSBoYXZlIHNvIHRoZXkgd2UgZG9uJ3QKCQkgKiBuZWVkIHRvIHJlLWlzc3VlIHRoZSByZWFkIHJlcXVlc3QuCgkJICogV2UgZG9uJ3QgbmVlZCB0byBmcmVlemUgdGhlIGFycmF5LCBiZWNhdXNlIGJlaW5nIGluIGFuCgkJICogYWN0aXZlIHN5bmMgcmVxdWVzdCwgdGhlcmUgaXMgbm8gbm9ybWFsIElPLCBhbmQKCQkgKiBubyBvdmVybGFwcGluZyBzeW5jcy4KCQkgKi8KCQlzZWN0b3JfdCBzZWN0ID0gcjFfYmlvLT5zZWN0b3I7CgkJaW50IHNlY3RvcnMgPSByMV9iaW8tPnNlY3RvcnM7CgkJaW50IGlkeCA9IDA7CgoJCXdoaWxlKHNlY3RvcnMpIHsKCQkJaW50IHMgPSBzZWN0b3JzOwoJCQlpbnQgZCA9IHIxX2Jpby0+cmVhZF9kaXNrOwoJCQlpbnQgc3VjY2VzcyA9IDA7CgkJCW1ka19yZGV2X3QgKnJkZXY7CgoJCQlpZiAocyA+IChQQUdFX1NJWkU+PjkpKQoJCQkJcyA9IFBBR0VfU0laRSA+PiA5OwoJCQlkbyB7CgkJCQlpZiAocjFfYmlvLT5iaW9zW2RdLT5iaV9lbmRfaW8gPT0gZW5kX3N5bmNfcmVhZCkgewoJCQkJCXJkZXYgPSBjb25mLT5taXJyb3JzW2RdLnJkZXY7CgkJCQkJaWYgKHN5bmNfcGFnZV9pbyhyZGV2LT5iZGV2LAoJCQkJCQkJIHNlY3QgKyByZGV2LT5kYXRhX29mZnNldCwKCQkJCQkJCSBzPDw5LAoJCQkJCQkJIGJpby0+YmlfaW9fdmVjW2lkeF0uYnZfcGFnZSwKCQkJCQkJCSBSRUFEKSkgewoJCQkJCQlzdWNjZXNzID0gMTsKCQkJCQkJYnJlYWs7CgkJCQkJfQoJCQkJfQoJCQkJZCsrOwoJCQkJaWYgKGQgPT0gY29uZi0+cmFpZF9kaXNrcykKCQkJCQlkID0gMDsKCQkJfSB3aGlsZSAoIXN1Y2Nlc3MgJiYgZCAhPSByMV9iaW8tPnJlYWRfZGlzayk7CgoJCQlpZiAoc3VjY2VzcykgewoJCQkJaW50IHN0YXJ0ID0gZDsKCQkJCS8qIHdyaXRlIGl0IGJhY2sgYW5kIHJlLXJlYWQgKi8KCQkJCXNldF9iaXQoUjFCSU9fVXB0b2RhdGUsICZyMV9iaW8tPnN0YXRlKTsKCQkJCXdoaWxlIChkICE9IHIxX2Jpby0+cmVhZF9kaXNrKSB7CgkJCQkJaWYgKGQgPT0gMCkKCQkJCQkJZCA9IGNvbmYtPnJhaWRfZGlza3M7CgkJCQkJZC0tOwoJCQkJCWlmIChyMV9iaW8tPmJpb3NbZF0tPmJpX2VuZF9pbyAhPSBlbmRfc3luY19yZWFkKQoJCQkJCQljb250aW51ZTsKCQkJCQlyZGV2ID0gY29uZi0+bWlycm9yc1tkXS5yZGV2OwoJCQkJCWF0b21pY19hZGQocywgJnJkZXYtPmNvcnJlY3RlZF9lcnJvcnMpOwoJCQkJCWlmIChzeW5jX3BhZ2VfaW8ocmRldi0+YmRldiwKCQkJCQkJCSBzZWN0ICsgcmRldi0+ZGF0YV9vZmZzZXQsCgkJCQkJCQkgczw8OSwKCQkJCQkJCSBiaW8tPmJpX2lvX3ZlY1tpZHhdLmJ2X3BhZ2UsCgkJCQkJCQkgV1JJVEUpID09IDApCgkJCQkJCW1kX2Vycm9yKG1kZGV2LCByZGV2KTsKCQkJCX0KCQkJCWQgPSBzdGFydDsKCQkJCXdoaWxlIChkICE9IHIxX2Jpby0+cmVhZF9kaXNrKSB7CgkJCQkJaWYgKGQgPT0gMCkKCQkJCQkJZCA9IGNvbmYtPnJhaWRfZGlza3M7CgkJCQkJZC0tOwoJCQkJCWlmIChyMV9iaW8tPmJpb3NbZF0tPmJpX2VuZF9pbyAhPSBlbmRfc3luY19yZWFkKQoJCQkJCQljb250aW51ZTsKCQkJCQlyZGV2ID0gY29uZi0+bWlycm9yc1tkXS5yZGV2OwoJCQkJCWlmIChzeW5jX3BhZ2VfaW8ocmRldi0+YmRldiwKCQkJCQkJCSBzZWN0ICsgcmRldi0+ZGF0YV9vZmZzZXQsCgkJCQkJCQkgczw8OSwKCQkJCQkJCSBiaW8tPmJpX2lvX3ZlY1tpZHhdLmJ2X3BhZ2UsCgkJCQkJCQkgUkVBRCkgPT0gMCkKCQkJCQkJbWRfZXJyb3IobWRkZXYsIHJkZXYpOwoJCQkJfQoJCQl9IGVsc2UgewoJCQkJY2hhciBiW0JERVZOQU1FX1NJWkVdOwoJCQkJLyogQ2Fubm90IHJlYWQgZnJvbSBhbnl3aGVyZSwgYXJyYXkgaXMgdG9hc3QgKi8KCQkJCW1kX2Vycm9yKG1kZGV2LCBjb25mLT5taXJyb3JzW3IxX2Jpby0+cmVhZF9kaXNrXS5yZGV2KTsKCQkJCXByaW50ayhLRVJOX0FMRVJUICJyYWlkMTogJXM6IHVucmVjb3ZlcmFibGUgSS9PIHJlYWQgZXJyb3IiCgkJCQkgICAgICAgIiBmb3IgYmxvY2sgJWxsdVxuIiwKCQkJCSAgICAgICBiZGV2bmFtZShiaW8tPmJpX2JkZXYsYiksCgkJCQkgICAgICAgKHVuc2lnbmVkIGxvbmcgbG9uZylyMV9iaW8tPnNlY3Rvcik7CgkJCQltZF9kb25lX3N5bmMobWRkZXYsIHIxX2Jpby0+c2VjdG9ycywgMCk7CgkJCQlwdXRfYnVmKHIxX2Jpbyk7CgkJCQlyZXR1cm47CgkJCX0KCQkJc2VjdG9ycyAtPSBzOwoJCQlzZWN0ICs9IHM7CgkJCWlkeCArKzsKCQl9Cgl9CgoJLyoKCSAqIHNjaGVkdWxlIHdyaXRlcwoJICovCglhdG9taWNfc2V0KCZyMV9iaW8tPnJlbWFpbmluZywgMSk7Cglmb3IgKGkgPSAwOyBpIDwgZGlza3MgOyBpKyspIHsKCQl3YmlvID0gcjFfYmlvLT5iaW9zW2ldOwoJCWlmICh3YmlvLT5iaV9lbmRfaW8gPT0gTlVMTCB8fAoJCSAgICAod2Jpby0+YmlfZW5kX2lvID09IGVuZF9zeW5jX3JlYWQgJiYKCQkgICAgIChpID09IHIxX2Jpby0+cmVhZF9kaXNrIHx8CgkJICAgICAgIXRlc3RfYml0KE1EX1JFQ09WRVJZX1NZTkMsICZtZGRldi0+cmVjb3ZlcnkpKSkpCgkJCWNvbnRpbnVlOwoKCQl3YmlvLT5iaV9ydyA9IFdSSVRFOwoJCXdiaW8tPmJpX2VuZF9pbyA9IGVuZF9zeW5jX3dyaXRlOwoJCWF0b21pY19pbmMoJnIxX2Jpby0+cmVtYWluaW5nKTsKCQltZF9zeW5jX2FjY3QoY29uZi0+bWlycm9yc1tpXS5yZGV2LT5iZGV2LCB3YmlvLT5iaV9zaXplID4+IDkpOwoKCQlnZW5lcmljX21ha2VfcmVxdWVzdCh3YmlvKTsKCX0KCglpZiAoYXRvbWljX2RlY19hbmRfdGVzdCgmcjFfYmlvLT5yZW1haW5pbmcpKSB7CgkJLyogaWYgd2UncmUgaGVyZSwgYWxsIHdyaXRlKHMpIGhhdmUgY29tcGxldGVkLCBzbyBjbGVhbiB1cCAqLwoJCW1kX2RvbmVfc3luYyhtZGRldiwgcjFfYmlvLT5zZWN0b3JzLCAxKTsKCQlwdXRfYnVmKHIxX2Jpbyk7Cgl9Cn0KCi8qCiAqIFRoaXMgaXMgYSBrZXJuZWwgdGhyZWFkIHdoaWNoOgogKgogKgkxLglSZXRyaWVzIGZhaWxlZCByZWFkIG9wZXJhdGlvbnMgb24gd29ya2luZyBtaXJyb3JzLgogKgkyLglVcGRhdGVzIHRoZSByYWlkIHN1cGVyYmxvY2sgd2hlbiBwcm9ibGVtcyBlbmNvdW50ZXIuCiAqCTMuCVBlcmZvcm1zIHdyaXRlcyBmb2xsb3dpbmcgcmVhZHMgZm9yIGFycmF5IHN5bmNyb25pc2luZy4KICovCgpzdGF0aWMgdm9pZCByYWlkMWQobWRkZXZfdCAqbWRkZXYpCnsKCXIxYmlvX3QgKnIxX2JpbzsKCXN0cnVjdCBiaW8gKmJpbzsKCXVuc2lnbmVkIGxvbmcgZmxhZ3M7Cgljb25mX3QgKmNvbmYgPSBtZGRldl90b19jb25mKG1kZGV2KTsKCXN0cnVjdCBsaXN0X2hlYWQgKmhlYWQgPSAmY29uZi0+cmV0cnlfbGlzdDsKCWludCB1bnBsdWc9MDsKCW1ka19yZGV2X3QgKnJkZXY7CgoJbWRfY2hlY2tfcmVjb3ZlcnkobWRkZXYpOwoJCglmb3IgKDs7KSB7CgkJY2hhciBiW0JERVZOQU1FX1NJWkVdOwoJCXNwaW5fbG9ja19pcnFzYXZlKCZjb25mLT5kZXZpY2VfbG9jaywgZmxhZ3MpOwoKCQlpZiAoY29uZi0+cGVuZGluZ19iaW9fbGlzdC5oZWFkKSB7CgkJCWJpbyA9IGJpb19saXN0X2dldCgmY29uZi0+cGVuZGluZ19iaW9fbGlzdCk7CgkJCWJsa19yZW1vdmVfcGx1ZyhtZGRldi0+cXVldWUpOwoJCQlzcGluX3VubG9ja19pcnFyZXN0b3JlKCZjb25mLT5kZXZpY2VfbG9jaywgZmxhZ3MpOwoJCQkvKiBmbHVzaCBhbnkgcGVuZGluZyBiaXRtYXAgd3JpdGVzIHRvIGRpc2sgYmVmb3JlIHByb2NlZWRpbmcgdy8gSS9PICovCgkJCWlmIChiaXRtYXBfdW5wbHVnKG1kZGV2LT5iaXRtYXApICE9IDApCgkJCQlwcmludGsoIiVzOiBiaXRtYXAgZmlsZSB3cml0ZSBmYWlsZWQhXG4iLCBtZG5hbWUobWRkZXYpKTsKCgkJCXdoaWxlIChiaW8pIHsgLyogc3VibWl0IHBlbmRpbmcgd3JpdGVzICovCgkJCQlzdHJ1Y3QgYmlvICpuZXh0ID0gYmlvLT5iaV9uZXh0OwoJCQkJYmlvLT5iaV9uZXh0ID0gTlVMTDsKCQkJCWdlbmVyaWNfbWFrZV9yZXF1ZXN0KGJpbyk7CgkJCQliaW8gPSBuZXh0OwoJCQl9CgkJCXVucGx1ZyA9IDE7CgoJCQljb250aW51ZTsKCQl9CgoJCWlmIChsaXN0X2VtcHR5KGhlYWQpKQoJCQlicmVhazsKCQlyMV9iaW8gPSBsaXN0X2VudHJ5KGhlYWQtPnByZXYsIHIxYmlvX3QsIHJldHJ5X2xpc3QpOwoJCWxpc3RfZGVsKGhlYWQtPnByZXYpOwoJCWNvbmYtPm5yX3F1ZXVlZC0tOwoJCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJmNvbmYtPmRldmljZV9sb2NrLCBmbGFncyk7CgoJCW1kZGV2ID0gcjFfYmlvLT5tZGRldjsKCQljb25mID0gbWRkZXZfdG9fY29uZihtZGRldik7CgkJaWYgKHRlc3RfYml0KFIxQklPX0lzU3luYywgJnIxX2Jpby0+c3RhdGUpKSB7CgkJCXN5bmNfcmVxdWVzdF93cml0ZShtZGRldiwgcjFfYmlvKTsKCQkJdW5wbHVnID0gMTsKCQl9IGVsc2UgaWYgKHRlc3RfYml0KFIxQklPX0JhcnJpZXJSZXRyeSwgJnIxX2Jpby0+c3RhdGUpKSB7CgkJCS8qIHNvbWUgcmVxdWVzdHMgaW4gdGhlIHIxYmlvIHdlcmUgQklPX1JXX0JBUlJJRVIKCQkJICogcmVxdWVzdHMgd2hpY2ggZmFpbGVkIHdpdGggLUVPUE5PVFNVUFAuICBIb2h1bW0uLgoJCQkgKiBCZXR0ZXIgcmVzdWJtaXQgd2l0aG91dCB0aGUgYmFycmllci4KCQkJICogV2Uga25vdyB3aGljaCBkZXZpY2VzIHRvIHJlc3VibWl0IGZvciwgYmVjYXVzZQoJCQkgKiBhbGwgb3RoZXJzIGhhdmUgaGFkIHRoZWlyIGJpb3NbXSBlbnRyeSBjbGVhcmVkLgoJCQkgKiBXZSBhbHJlYWR5IGhhdmUgYSBucl9wZW5kaW5nIHJlZmVyZW5jZSBvbiB0aGVzZSByZGV2cy4KCQkJICovCgkJCWludCBpOwoJCQljbGVhcl9iaXQoUjFCSU9fQmFycmllclJldHJ5LCAmcjFfYmlvLT5zdGF0ZSk7CgkJCWNsZWFyX2JpdChSMUJJT19CYXJyaWVyLCAmcjFfYmlvLT5zdGF0ZSk7CgkJCWZvciAoaT0wOyBpIDwgY29uZi0+cmFpZF9kaXNrczsgaSsrKQoJCQkJaWYgKHIxX2Jpby0+Ymlvc1tpXSkKCQkJCQlhdG9taWNfaW5jKCZyMV9iaW8tPnJlbWFpbmluZyk7CgkJCWZvciAoaT0wOyBpIDwgY29uZi0+cmFpZF9kaXNrczsgaSsrKQoJCQkJaWYgKHIxX2Jpby0+Ymlvc1tpXSkgewoJCQkJCXN0cnVjdCBiaW9fdmVjICpidmVjOwoJCQkJCWludCBqOwoKCQkJCQliaW8gPSBiaW9fY2xvbmUocjFfYmlvLT5tYXN0ZXJfYmlvLCBHRlBfTk9JTyk7CgkJCQkJLyogY29weSBwYWdlcyBmcm9tIHRoZSBmYWlsZWQgYmlvLCBhcwoJCQkJCSAqIHRoaXMgbWlnaHQgYmUgYSB3cml0ZS1iZWhpbmQgZGV2aWNlICovCgkJCQkJX19iaW9fZm9yX2VhY2hfc2VnbWVudChidmVjLCBiaW8sIGosIDApCgkJCQkJCWJ2ZWMtPmJ2X3BhZ2UgPSBiaW9faW92ZWNfaWR4KHIxX2Jpby0+Ymlvc1tpXSwgaiktPmJ2X3BhZ2U7CgkJCQkJYmlvX3B1dChyMV9iaW8tPmJpb3NbaV0pOwoJCQkJCWJpby0+Ymlfc2VjdG9yID0gcjFfYmlvLT5zZWN0b3IgKwoJCQkJCQljb25mLT5taXJyb3JzW2ldLnJkZXYtPmRhdGFfb2Zmc2V0OwoJCQkJCWJpby0+YmlfYmRldiA9IGNvbmYtPm1pcnJvcnNbaV0ucmRldi0+YmRldjsKCQkJCQliaW8tPmJpX2VuZF9pbyA9IHJhaWQxX2VuZF93cml0ZV9yZXF1ZXN0OwoJCQkJCWJpby0+YmlfcncgPSBXUklURTsKCQkJCQliaW8tPmJpX3ByaXZhdGUgPSByMV9iaW87CgkJCQkJcjFfYmlvLT5iaW9zW2ldID0gYmlvOwoJCQkJCWdlbmVyaWNfbWFrZV9yZXF1ZXN0KGJpbyk7CgkJCQl9CgkJfSBlbHNlIHsKCQkJaW50IGRpc2s7CgoJCQkvKiB3ZSBnb3QgYSByZWFkIGVycm9yLiBNYXliZSB0aGUgZHJpdmUgaXMgYmFkLiAgTWF5YmUganVzdAoJCQkgKiB0aGUgYmxvY2sgYW5kIHdlIGNhbiBmaXggaXQuCgkJCSAqIFdlIGZyZWV6ZSBhbGwgb3RoZXIgSU8sIGFuZCB0cnkgcmVhZGluZyB0aGUgYmxvY2sgZnJvbQoJCQkgKiBvdGhlciBkZXZpY2VzLiAgV2hlbiB3ZSBmaW5kIG9uZSwgd2UgcmUtd3JpdGUKCQkJICogYW5kIGNoZWNrIGl0IHRoYXQgZml4ZXMgdGhlIHJlYWQgZXJyb3IuCgkJCSAqIFRoaXMgaXMgYWxsIGRvbmUgc3luY2hyb25vdXNseSB3aGlsZSB0aGUgYXJyYXkgaXMKCQkJICogZnJvemVuCgkJCSAqLwoJCQlzZWN0b3JfdCBzZWN0ID0gcjFfYmlvLT5zZWN0b3I7CgkJCWludCBzZWN0b3JzID0gcjFfYmlvLT5zZWN0b3JzOwoJCQlmcmVlemVfYXJyYXkoY29uZik7CgkJCWlmIChtZGRldi0+cm8gPT0gMCkgd2hpbGUoc2VjdG9ycykgewoJCQkJaW50IHMgPSBzZWN0b3JzOwoJCQkJaW50IGQgPSByMV9iaW8tPnJlYWRfZGlzazsKCQkJCWludCBzdWNjZXNzID0gMDsKCgkJCQlpZiAocyA+IChQQUdFX1NJWkU+PjkpKQoJCQkJCXMgPSBQQUdFX1NJWkUgPj4gOTsKCgkJCQlkbyB7CgkJCQkJcmRldiA9IGNvbmYtPm1pcnJvcnNbZF0ucmRldjsKCQkJCQlpZiAocmRldiAmJgoJCQkJCSAgICB0ZXN0X2JpdChJbl9zeW5jLCAmcmRldi0+ZmxhZ3MpICYmCgkJCQkJICAgIHN5bmNfcGFnZV9pbyhyZGV2LT5iZGV2LAoJCQkJCQkJIHNlY3QgKyByZGV2LT5kYXRhX29mZnNldCwKCQkJCQkJCSBzPDw5LAoJCQkJCQkJIGNvbmYtPnRtcHBhZ2UsIFJFQUQpKQoJCQkJCQlzdWNjZXNzID0gMTsKCQkJCQllbHNlIHsKCQkJCQkJZCsrOwoJCQkJCQlpZiAoZCA9PSBjb25mLT5yYWlkX2Rpc2tzKQoJCQkJCQkJZCA9IDA7CgkJCQkJfQoJCQkJfSB3aGlsZSAoIXN1Y2Nlc3MgJiYgZCAhPSByMV9iaW8tPnJlYWRfZGlzayk7CgoJCQkJaWYgKHN1Y2Nlc3MpIHsKCQkJCQkvKiB3cml0ZSBpdCBiYWNrIGFuZCByZS1yZWFkICovCgkJCQkJaW50IHN0YXJ0ID0gZDsKCQkJCQl3aGlsZSAoZCAhPSByMV9iaW8tPnJlYWRfZGlzaykgewoJCQkJCQlpZiAoZD09MCkKCQkJCQkJCWQgPSBjb25mLT5yYWlkX2Rpc2tzOwoJCQkJCQlkLS07CgkJCQkJCXJkZXYgPSBjb25mLT5taXJyb3JzW2RdLnJkZXY7CgkJCQkJCWF0b21pY19hZGQocywgJnJkZXYtPmNvcnJlY3RlZF9lcnJvcnMpOwoJCQkJCQlpZiAocmRldiAmJgoJCQkJCQkgICAgdGVzdF9iaXQoSW5fc3luYywgJnJkZXYtPmZsYWdzKSkgewoJCQkJCQkJaWYgKHN5bmNfcGFnZV9pbyhyZGV2LT5iZGV2LAoJCQkJCQkJCQkgc2VjdCArIHJkZXYtPmRhdGFfb2Zmc2V0LAoJCQkJCQkJCQkgczw8OSwgY29uZi0+dG1wcGFnZSwgV1JJVEUpID09IDApCgkJCQkJCQkJLyogV2VsbCwgdGhpcyBkZXZpY2UgaXMgZGVhZCAqLwoJCQkJCQkJCW1kX2Vycm9yKG1kZGV2LCByZGV2KTsKCQkJCQkJfQoJCQkJCX0KCQkJCQlkID0gc3RhcnQ7CgkJCQkJd2hpbGUgKGQgIT0gcjFfYmlvLT5yZWFkX2Rpc2spIHsKCQkJCQkJaWYgKGQ9PTApCgkJCQkJCQlkID0gY29uZi0+cmFpZF9kaXNrczsKCQkJCQkJZC0tOwoJCQkJCQlyZGV2ID0gY29uZi0+bWlycm9yc1tkXS5yZGV2OwoJCQkJCQlpZiAocmRldiAmJgoJCQkJCQkgICAgdGVzdF9iaXQoSW5fc3luYywgJnJkZXYtPmZsYWdzKSkgewoJCQkJCQkJaWYgKHN5bmNfcGFnZV9pbyhyZGV2LT5iZGV2LAoJCQkJCQkJCQkgc2VjdCArIHJkZXYtPmRhdGFfb2Zmc2V0LAoJCQkJCQkJCQkgczw8OSwgY29uZi0+dG1wcGFnZSwgUkVBRCkgPT0gMCkKCQkJCQkJCQkvKiBXZWxsLCB0aGlzIGRldmljZSBpcyBkZWFkICovCgkJCQkJCQkJbWRfZXJyb3IobWRkZXYsIHJkZXYpOwoJCQkJCQkJZWxzZQoJCQkJCQkJCXByaW50ayhLRVJOX0lORk8gInJhaWQxOiVzOiByZWFkIGVycm9yIGNvcnJlY3RlZCAoJWQgc2VjdG9ycyBhdCAlbGx1IG9uICVzKVxuIiwKCQkJCQkJCQkgICAgICAgbWRuYW1lKG1kZGV2KSwgcywgKHVuc2lnbmVkIGxvbmcgbG9uZykoc2VjdCArIHJkZXYtPmRhdGFfb2Zmc2V0KSwgYmRldm5hbWUocmRldi0+YmRldiwgYikpOwoJCQkJCQl9CgkJCQkJfQoJCQkJfSBlbHNlIHsKCQkJCQkvKiBDYW5ub3QgcmVhZCBmcm9tIGFueXdoZXJlIC0tIGJ5ZSBieWUgYXJyYXkgKi8KCQkJCQltZF9lcnJvcihtZGRldiwgY29uZi0+bWlycm9yc1tyMV9iaW8tPnJlYWRfZGlza10ucmRldik7CgkJCQkJYnJlYWs7CgkJCQl9CgkJCQlzZWN0b3JzIC09IHM7CgkJCQlzZWN0ICs9IHM7CgkJCX0KCgkJCXVuZnJlZXplX2FycmF5KGNvbmYpOwoKCQkJYmlvID0gcjFfYmlvLT5iaW9zW3IxX2Jpby0+cmVhZF9kaXNrXTsKCQkJaWYgKChkaXNrPXJlYWRfYmFsYW5jZShjb25mLCByMV9iaW8pKSA9PSAtMSkgewoJCQkJcHJpbnRrKEtFUk5fQUxFUlQgInJhaWQxOiAlczogdW5yZWNvdmVyYWJsZSBJL08iCgkJCQkgICAgICAgIiByZWFkIGVycm9yIGZvciBibG9jayAlbGx1XG4iLAoJCQkJICAgICAgIGJkZXZuYW1lKGJpby0+YmlfYmRldixiKSwKCQkJCSAgICAgICAodW5zaWduZWQgbG9uZyBsb25nKXIxX2Jpby0+c2VjdG9yKTsKCQkJCXJhaWRfZW5kX2Jpb19pbyhyMV9iaW8pOwoJCQl9IGVsc2UgewoJCQkJcjFfYmlvLT5iaW9zW3IxX2Jpby0+cmVhZF9kaXNrXSA9CgkJCQkJbWRkZXYtPnJvID8gSU9fQkxPQ0tFRCA6IE5VTEw7CgkJCQlyMV9iaW8tPnJlYWRfZGlzayA9IGRpc2s7CgkJCQliaW9fcHV0KGJpbyk7CgkJCQliaW8gPSBiaW9fY2xvbmUocjFfYmlvLT5tYXN0ZXJfYmlvLCBHRlBfTk9JTyk7CgkJCQlyMV9iaW8tPmJpb3NbcjFfYmlvLT5yZWFkX2Rpc2tdID0gYmlvOwoJCQkJcmRldiA9IGNvbmYtPm1pcnJvcnNbZGlza10ucmRldjsKCQkJCWlmIChwcmludGtfcmF0ZWxpbWl0KCkpCgkJCQkJcHJpbnRrKEtFUk5fRVJSICJyYWlkMTogJXM6IHJlZGlyZWN0aW5nIHNlY3RvciAlbGx1IHRvIgoJCQkJCSAgICAgICAiIGFub3RoZXIgbWlycm9yXG4iLAoJCQkJCSAgICAgICBiZGV2bmFtZShyZGV2LT5iZGV2LGIpLAoJCQkJCSAgICAgICAodW5zaWduZWQgbG9uZyBsb25nKXIxX2Jpby0+c2VjdG9yKTsKCQkJCWJpby0+Ymlfc2VjdG9yID0gcjFfYmlvLT5zZWN0b3IgKyByZGV2LT5kYXRhX29mZnNldDsKCQkJCWJpby0+YmlfYmRldiA9IHJkZXYtPmJkZXY7CgkJCQliaW8tPmJpX2VuZF9pbyA9IHJhaWQxX2VuZF9yZWFkX3JlcXVlc3Q7CgkJCQliaW8tPmJpX3J3ID0gUkVBRDsKCQkJCWJpby0+YmlfcHJpdmF0ZSA9IHIxX2JpbzsKCQkJCXVucGx1ZyA9IDE7CgkJCQlnZW5lcmljX21ha2VfcmVxdWVzdChiaW8pOwoJCQl9CgkJfQoJfQoJc3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmY29uZi0+ZGV2aWNlX2xvY2ssIGZsYWdzKTsKCWlmICh1bnBsdWcpCgkJdW5wbHVnX3NsYXZlcyhtZGRldik7Cn0KCgpzdGF0aWMgaW50IGluaXRfcmVzeW5jKGNvbmZfdCAqY29uZikKewoJaW50IGJ1ZmZzOwoKCWJ1ZmZzID0gUkVTWU5DX1dJTkRPVyAvIFJFU1lOQ19CTE9DS19TSVpFOwoJQlVHX09OKGNvbmYtPnIxYnVmX3Bvb2wpOwoJY29uZi0+cjFidWZfcG9vbCA9IG1lbXBvb2xfY3JlYXRlKGJ1ZmZzLCByMWJ1Zl9wb29sX2FsbG9jLCByMWJ1Zl9wb29sX2ZyZWUsCgkJCQkJICBjb25mLT5wb29saW5mbyk7CglpZiAoIWNvbmYtPnIxYnVmX3Bvb2wpCgkJcmV0dXJuIC1FTk9NRU07Cgljb25mLT5uZXh0X3Jlc3luYyA9IDA7CglyZXR1cm4gMDsKfQoKLyoKICogcGVyZm9ybSBhICJzeW5jIiBvbiBvbmUgImJsb2NrIgogKgogKiBXZSBuZWVkIHRvIG1ha2Ugc3VyZSB0aGF0IG5vIG5vcm1hbCBJL08gcmVxdWVzdCAtIHBhcnRpY3VsYXJseSB3cml0ZQogKiByZXF1ZXN0cyAtIGNvbmZsaWN0IHdpdGggYWN0aXZlIHN5bmMgcmVxdWVzdHMuCiAqCiAqIFRoaXMgaXMgYWNoaWV2ZWQgYnkgdHJhY2tpbmcgcGVuZGluZyByZXF1ZXN0cyBhbmQgYSAnYmFycmllcicgY29uY2VwdAogKiB0aGF0IGNhbiBiZSBpbnN0YWxsZWQgdG8gZXhjbHVkZSBub3JtYWwgSU8gcmVxdWVzdHMuCiAqLwoKc3RhdGljIHNlY3Rvcl90IHN5bmNfcmVxdWVzdChtZGRldl90ICptZGRldiwgc2VjdG9yX3Qgc2VjdG9yX25yLCBpbnQgKnNraXBwZWQsIGludCBnb19mYXN0ZXIpCnsKCWNvbmZfdCAqY29uZiA9IG1kZGV2X3RvX2NvbmYobWRkZXYpOwoJcjFiaW9fdCAqcjFfYmlvOwoJc3RydWN0IGJpbyAqYmlvOwoJc2VjdG9yX3QgbWF4X3NlY3RvciwgbnJfc2VjdG9yczsKCWludCBkaXNrID0gLTE7CglpbnQgaTsKCWludCB3b25seSA9IC0xOwoJaW50IHdyaXRlX3RhcmdldHMgPSAwLCByZWFkX3RhcmdldHMgPSAwOwoJaW50IHN5bmNfYmxvY2tzOwoJaW50IHN0aWxsX2RlZ3JhZGVkID0gMDsKCglpZiAoIWNvbmYtPnIxYnVmX3Bvb2wpCgl7Ci8qCgkJcHJpbnRrKCJzeW5jIHN0YXJ0IC0gYml0bWFwICVwXG4iLCBtZGRldi0+Yml0bWFwKTsKKi8KCQlpZiAoaW5pdF9yZXN5bmMoY29uZikpCgkJCXJldHVybiAwOwoJfQoKCW1heF9zZWN0b3IgPSBtZGRldi0+c2l6ZSA8PCAxOwoJaWYgKHNlY3Rvcl9uciA+PSBtYXhfc2VjdG9yKSB7CgkJLyogSWYgd2UgYWJvcnRlZCwgd2UgbmVlZCB0byBhYm9ydCB0aGUKCQkgKiBzeW5jIG9uIHRoZSAnY3VycmVudCcgYml0bWFwIGNodW5rICh0aGVyZSB3aWxsCgkJICogb25seSBiZSBvbmUgaW4gcmFpZDEgcmVzeW5jLgoJCSAqIFdlIGNhbiBmaW5kIHRoZSBjdXJyZW50IGFkZGVzcyBpbiBtZGRldi0+Y3Vycl9yZXN5bmMKCQkgKi8KCQlpZiAobWRkZXYtPmN1cnJfcmVzeW5jIDwgbWF4X3NlY3RvcikgLyogYWJvcnRlZCAqLwoJCQliaXRtYXBfZW5kX3N5bmMobWRkZXYtPmJpdG1hcCwgbWRkZXYtPmN1cnJfcmVzeW5jLAoJCQkJCQkmc3luY19ibG9ja3MsIDEpOwoJCWVsc2UgLyogY29tcGxldGVkIHN5bmMgKi8KCQkJY29uZi0+ZnVsbHN5bmMgPSAwOwoKCQliaXRtYXBfY2xvc2Vfc3luYyhtZGRldi0+Yml0bWFwKTsKCQljbG9zZV9zeW5jKGNvbmYpOwoJCXJldHVybiAwOwoJfQoKCS8qIGJlZm9yZSBidWlsZGluZyBhIHJlcXVlc3QsIGNoZWNrIGlmIHdlIGNhbiBza2lwIHRoZXNlIGJsb2Nrcy4uCgkgKiBUaGlzIGNhbGwgdGhlIGJpdG1hcF9zdGFydF9zeW5jIGRvZXNuJ3QgYWN0dWFsbHkgcmVjb3JkIGFueXRoaW5nCgkgKi8KCWlmIChtZGRldi0+Yml0bWFwID09IE5VTEwgJiYKCSAgICBtZGRldi0+cmVjb3ZlcnlfY3AgPT0gTWF4U2VjdG9yICYmCgkgICAgY29uZi0+ZnVsbHN5bmMgPT0gMCkgewoJCSpza2lwcGVkID0gMTsKCQlyZXR1cm4gbWF4X3NlY3RvciAtIHNlY3Rvcl9ucjsKCX0KCWlmICghYml0bWFwX3N0YXJ0X3N5bmMobWRkZXYtPmJpdG1hcCwgc2VjdG9yX25yLCAmc3luY19ibG9ja3MsIDEpICYmCgkgICAgIWNvbmYtPmZ1bGxzeW5jICYmICF0ZXN0X2JpdChNRF9SRUNPVkVSWV9SRVFVRVNURUQsICZtZGRldi0+cmVjb3ZlcnkpKSB7CgkJLyogV2UgY2FuIHNraXAgdGhpcyBibG9jaywgYW5kIHByb2JhYmx5IHNldmVyYWwgbW9yZSAqLwoJCSpza2lwcGVkID0gMTsKCQlyZXR1cm4gc3luY19ibG9ja3M7Cgl9CgkvKgoJICogSWYgdGhlcmUgaXMgbm9uLXJlc3luYyBhY3Rpdml0eSB3YWl0aW5nIGZvciBhIHR1cm4sCgkgKiBhbmQgcmVzeW5jIGlzIGdvaW5nIGZhc3QgZW5vdWdoLAoJICogdGhlbiBsZXQgaXQgdGhvdWdoIGJlZm9yZSBzdGFydGluZyBvbiB0aGlzIG5ldyBzeW5jIHJlcXVlc3QuCgkgKi8KCWlmICghZ29fZmFzdGVyICYmIGNvbmYtPm5yX3dhaXRpbmcpCgkJbXNsZWVwX2ludGVycnVwdGlibGUoMTAwMCk7CgoJcmFpc2VfYmFycmllcihjb25mKTsKCgljb25mLT5uZXh0X3Jlc3luYyA9IHNlY3Rvcl9ucjsKCglyMV9iaW8gPSBtZW1wb29sX2FsbG9jKGNvbmYtPnIxYnVmX3Bvb2wsIEdGUF9OT0lPKTsKCXJjdV9yZWFkX2xvY2soKTsKCS8qCgkgKiBJZiB3ZSBnZXQgYSBjb3JyZWN0YWJseSByZWFkIGVycm9yIGR1cmluZyByZXN5bmMgb3IgcmVjb3ZlcnksCgkgKiB3ZSBtaWdodCB3YW50IHRvIHJlYWQgZnJvbSBhIGRpZmZlcmVudCBkZXZpY2UuICBTbyB3ZQoJICogZmxhZyBhbGwgZHJpdmVzIHRoYXQgY291bGQgY29uY2VpdmFibHkgYmUgcmVhZCBmcm9tIGZvciBSRUFELAoJICogYW5kIGFueSBvdGhlcnMgKHdoaWNoIHdpbGwgYmUgbm9uLUluX3N5bmMgZGV2aWNlcykgZm9yIFdSSVRFLgoJICogSWYgYSByZWFkIGZhaWxzLCB3ZSB0cnkgcmVhZGluZyBmcm9tIHNvbWV0aGluZyBlbHNlIGZvciB3aGljaCBSRUFECgkgKiBpcyBPSy4KCSAqLwoKCXIxX2Jpby0+bWRkZXYgPSBtZGRldjsKCXIxX2Jpby0+c2VjdG9yID0gc2VjdG9yX25yOwoJcjFfYmlvLT5zdGF0ZSA9IDA7CglzZXRfYml0KFIxQklPX0lzU3luYywgJnIxX2Jpby0+c3RhdGUpOwoKCWZvciAoaT0wOyBpIDwgY29uZi0+cmFpZF9kaXNrczsgaSsrKSB7CgkJbWRrX3JkZXZfdCAqcmRldjsKCQliaW8gPSByMV9iaW8tPmJpb3NbaV07CgoJCS8qIHRha2UgZnJvbSBiaW9faW5pdCAqLwoJCWJpby0+YmlfbmV4dCA9IE5VTEw7CgkJYmlvLT5iaV9mbGFncyB8PSAxIDw8IEJJT19VUFRPREFURTsKCQliaW8tPmJpX3J3ID0gMDsKCQliaW8tPmJpX3ZjbnQgPSAwOwoJCWJpby0+YmlfaWR4ID0gMDsKCQliaW8tPmJpX3BoeXNfc2VnbWVudHMgPSAwOwoJCWJpby0+YmlfaHdfc2VnbWVudHMgPSAwOwoJCWJpby0+Ymlfc2l6ZSA9IDA7CgkJYmlvLT5iaV9lbmRfaW8gPSBOVUxMOwoJCWJpby0+YmlfcHJpdmF0ZSA9IE5VTEw7CgoJCXJkZXYgPSByY3VfZGVyZWZlcmVuY2UoY29uZi0+bWlycm9yc1tpXS5yZGV2KTsKCQlpZiAocmRldiA9PSBOVUxMIHx8CgkJCSAgIHRlc3RfYml0KEZhdWx0eSwgJnJkZXYtPmZsYWdzKSkgewoJCQlzdGlsbF9kZWdyYWRlZCA9IDE7CgkJCWNvbnRpbnVlOwoJCX0gZWxzZSBpZiAoIXRlc3RfYml0KEluX3N5bmMsICZyZGV2LT5mbGFncykpIHsKCQkJYmlvLT5iaV9ydyA9IFdSSVRFOwoJCQliaW8tPmJpX2VuZF9pbyA9IGVuZF9zeW5jX3dyaXRlOwoJCQl3cml0ZV90YXJnZXRzICsrOwoJCX0gZWxzZSB7CgkJCS8qIG1heSBuZWVkIHRvIHJlYWQgZnJvbSBoZXJlICovCgkJCWJpby0+YmlfcncgPSBSRUFEOwoJCQliaW8tPmJpX2VuZF9pbyA9IGVuZF9zeW5jX3JlYWQ7CgkJCWlmICh0ZXN0X2JpdChXcml0ZU1vc3RseSwgJnJkZXYtPmZsYWdzKSkgewoJCQkJaWYgKHdvbmx5IDwgMCkKCQkJCQl3b25seSA9IGk7CgkJCX0gZWxzZSB7CgkJCQlpZiAoZGlzayA8IDApCgkJCQkJZGlzayA9IGk7CgkJCX0KCQkJcmVhZF90YXJnZXRzKys7CgkJfQoJCWF0b21pY19pbmMoJnJkZXYtPm5yX3BlbmRpbmcpOwoJCWJpby0+Ymlfc2VjdG9yID0gc2VjdG9yX25yICsgcmRldi0+ZGF0YV9vZmZzZXQ7CgkJYmlvLT5iaV9iZGV2ID0gcmRldi0+YmRldjsKCQliaW8tPmJpX3ByaXZhdGUgPSByMV9iaW87Cgl9CglyY3VfcmVhZF91bmxvY2soKTsKCWlmIChkaXNrIDwgMCkKCQlkaXNrID0gd29ubHk7CglyMV9iaW8tPnJlYWRfZGlzayA9IGRpc2s7CgoJaWYgKHRlc3RfYml0KE1EX1JFQ09WRVJZX1NZTkMsICZtZGRldi0+cmVjb3ZlcnkpICYmIHJlYWRfdGFyZ2V0cyA+IDApCgkJLyogZXh0cmEgcmVhZCB0YXJnZXRzIGFyZSBhbHNvIHdyaXRlIHRhcmdldHMgKi8KCQl3cml0ZV90YXJnZXRzICs9IHJlYWRfdGFyZ2V0cy0xOwoKCWlmICh3cml0ZV90YXJnZXRzID09IDAgfHwgcmVhZF90YXJnZXRzID09IDApIHsKCQkvKiBUaGVyZSBpcyBub3doZXJlIHRvIHdyaXRlLCBzbyBhbGwgbm9uLXN5bmMKCQkgKiBkcml2ZXMgbXVzdCBiZSBmYWlsZWQgLSBzbyB3ZSBhcmUgZmluaXNoZWQKCQkgKi8KCQlzZWN0b3JfdCBydiA9IG1heF9zZWN0b3IgLSBzZWN0b3JfbnI7CgkJKnNraXBwZWQgPSAxOwoJCXB1dF9idWYocjFfYmlvKTsKCQlyZXR1cm4gcnY7Cgl9CgoJbnJfc2VjdG9ycyA9IDA7CglzeW5jX2Jsb2NrcyA9IDA7CglkbyB7CgkJc3RydWN0IHBhZ2UgKnBhZ2U7CgkJaW50IGxlbiA9IFBBR0VfU0laRTsKCQlpZiAoc2VjdG9yX25yICsgKGxlbj4+OSkgPiBtYXhfc2VjdG9yKQoJCQlsZW4gPSAobWF4X3NlY3RvciAtIHNlY3Rvcl9ucikgPDwgOTsKCQlpZiAobGVuID09IDApCgkJCWJyZWFrOwoJCWlmIChzeW5jX2Jsb2NrcyA9PSAwKSB7CgkJCWlmICghYml0bWFwX3N0YXJ0X3N5bmMobWRkZXYtPmJpdG1hcCwgc2VjdG9yX25yLAoJCQkJCSAgICAgICAmc3luY19ibG9ja3MsIHN0aWxsX2RlZ3JhZGVkKSAmJgoJCQkgICAgIWNvbmYtPmZ1bGxzeW5jICYmCgkJCSAgICAhdGVzdF9iaXQoTURfUkVDT1ZFUllfUkVRVUVTVEVELCAmbWRkZXYtPnJlY292ZXJ5KSkKCQkJCWJyZWFrOwoJCQlCVUdfT04oc3luY19ibG9ja3MgPCAoUEFHRV9TSVpFPj45KSk7CgkJCWlmIChsZW4gPiAoc3luY19ibG9ja3M8PDkpKQoJCQkJbGVuID0gc3luY19ibG9ja3M8PDk7CgkJfQoKCQlmb3IgKGk9MCA7IGkgPCBjb25mLT5yYWlkX2Rpc2tzOyBpKyspIHsKCQkJYmlvID0gcjFfYmlvLT5iaW9zW2ldOwoJCQlpZiAoYmlvLT5iaV9lbmRfaW8pIHsKCQkJCXBhZ2UgPSBiaW8tPmJpX2lvX3ZlY1tiaW8tPmJpX3ZjbnRdLmJ2X3BhZ2U7CgkJCQlpZiAoYmlvX2FkZF9wYWdlKGJpbywgcGFnZSwgbGVuLCAwKSA9PSAwKSB7CgkJCQkJLyogc3RvcCBoZXJlICovCgkJCQkJYmlvLT5iaV9pb192ZWNbYmlvLT5iaV92Y250XS5idl9wYWdlID0gcGFnZTsKCQkJCQl3aGlsZSAoaSA+IDApIHsKCQkJCQkJaS0tOwoJCQkJCQliaW8gPSByMV9iaW8tPmJpb3NbaV07CgkJCQkJCWlmIChiaW8tPmJpX2VuZF9pbz09TlVMTCkKCQkJCQkJCWNvbnRpbnVlOwoJCQkJCQkvKiByZW1vdmUgbGFzdCBwYWdlIGZyb20gdGhpcyBiaW8gKi8KCQkJCQkJYmlvLT5iaV92Y250LS07CgkJCQkJCWJpby0+Ymlfc2l6ZSAtPSBsZW47CgkJCQkJCWJpby0+YmlfZmxhZ3MgJj0gfigxPDwgQklPX1NFR19WQUxJRCk7CgkJCQkJfQoJCQkJCWdvdG8gYmlvX2Z1bGw7CgkJCQl9CgkJCX0KCQl9CgkJbnJfc2VjdG9ycyArPSBsZW4+Pjk7CgkJc2VjdG9yX25yICs9IGxlbj4+OTsKCQlzeW5jX2Jsb2NrcyAtPSAobGVuPj45KTsKCX0gd2hpbGUgKHIxX2Jpby0+Ymlvc1tkaXNrXS0+YmlfdmNudCA8IFJFU1lOQ19QQUdFUyk7CiBiaW9fZnVsbDoKCXIxX2Jpby0+c2VjdG9ycyA9IG5yX3NlY3RvcnM7CgoJLyogRm9yIGEgdXNlci1yZXF1ZXN0ZWQgc3luYywgd2UgcmVhZCBhbGwgcmVhZGFibGUgZGV2aWNlcyBhbmQgZG8gYQoJICogY29tcGFyZQoJICovCglpZiAodGVzdF9iaXQoTURfUkVDT1ZFUllfUkVRVUVTVEVELCAmbWRkZXYtPnJlY292ZXJ5KSkgewoJCWF0b21pY19zZXQoJnIxX2Jpby0+cmVtYWluaW5nLCByZWFkX3RhcmdldHMpOwoJCWZvciAoaT0wOyBpPGNvbmYtPnJhaWRfZGlza3M7IGkrKykgewoJCQliaW8gPSByMV9iaW8tPmJpb3NbaV07CgkJCWlmIChiaW8tPmJpX2VuZF9pbyA9PSBlbmRfc3luY19yZWFkKSB7CgkJCQltZF9zeW5jX2FjY3QoY29uZi0+bWlycm9yc1tpXS5yZGV2LT5iZGV2LCBucl9zZWN0b3JzKTsKCQkJCWdlbmVyaWNfbWFrZV9yZXF1ZXN0KGJpbyk7CgkJCX0KCQl9Cgl9IGVsc2UgewoJCWF0b21pY19zZXQoJnIxX2Jpby0+cmVtYWluaW5nLCAxKTsKCQliaW8gPSByMV9iaW8tPmJpb3NbcjFfYmlvLT5yZWFkX2Rpc2tdOwoJCW1kX3N5bmNfYWNjdChjb25mLT5taXJyb3JzW3IxX2Jpby0+cmVhZF9kaXNrXS5yZGV2LT5iZGV2LAoJCQkgICAgIG5yX3NlY3RvcnMpOwoJCWdlbmVyaWNfbWFrZV9yZXF1ZXN0KGJpbyk7CgoJfQoKCXJldHVybiBucl9zZWN0b3JzOwp9CgpzdGF0aWMgaW50IHJ1bihtZGRldl90ICptZGRldikKewoJY29uZl90ICpjb25mOwoJaW50IGksIGosIGRpc2tfaWR4OwoJbWlycm9yX2luZm9fdCAqZGlzazsKCW1ka19yZGV2X3QgKnJkZXY7CglzdHJ1Y3QgbGlzdF9oZWFkICp0bXA7CgoJaWYgKG1kZGV2LT5sZXZlbCAhPSAxKSB7CgkJcHJpbnRrKCJyYWlkMTogJXM6IHJhaWQgbGV2ZWwgbm90IHNldCB0byBtaXJyb3JpbmcgKCVkKVxuIiwKCQkgICAgICAgbWRuYW1lKG1kZGV2KSwgbWRkZXYtPmxldmVsKTsKCQlnb3RvIG91dDsKCX0KCWlmIChtZGRldi0+cmVzaGFwZV9wb3NpdGlvbiAhPSBNYXhTZWN0b3IpIHsKCQlwcmludGsoInJhaWQxOiAlczogcmVzaGFwZV9wb3NpdGlvbiBzZXQgYnV0IG5vdCBzdXBwb3J0ZWRcbiIsCgkJICAgICAgIG1kbmFtZShtZGRldikpOwoJCWdvdG8gb3V0OwoJfQoJLyoKCSAqIGNvcHkgdGhlIGFscmVhZHkgdmVyaWZpZWQgZGV2aWNlcyBpbnRvIG91ciBwcml2YXRlIFJBSUQxCgkgKiBib29ra2VlcGluZyBhcmVhLiBbd2hhdGV2ZXIgd2UgYWxsb2NhdGUgaW4gcnVuKCksCgkgKiBzaG91bGQgYmUgZnJlZWQgaW4gc3RvcCgpXQoJICovCgljb25mID0ga3phbGxvYyhzaXplb2YoY29uZl90KSwgR0ZQX0tFUk5FTCk7CgltZGRldi0+cHJpdmF0ZSA9IGNvbmY7CglpZiAoIWNvbmYpCgkJZ290byBvdXRfbm9fbWVtOwoKCWNvbmYtPm1pcnJvcnMgPSBremFsbG9jKHNpemVvZihzdHJ1Y3QgbWlycm9yX2luZm8pKm1kZGV2LT5yYWlkX2Rpc2tzLAoJCQkJIEdGUF9LRVJORUwpOwoJaWYgKCFjb25mLT5taXJyb3JzKQoJCWdvdG8gb3V0X25vX21lbTsKCgljb25mLT50bXBwYWdlID0gYWxsb2NfcGFnZShHRlBfS0VSTkVMKTsKCWlmICghY29uZi0+dG1wcGFnZSkKCQlnb3RvIG91dF9ub19tZW07CgoJY29uZi0+cG9vbGluZm8gPSBrbWFsbG9jKHNpemVvZigqY29uZi0+cG9vbGluZm8pLCBHRlBfS0VSTkVMKTsKCWlmICghY29uZi0+cG9vbGluZm8pCgkJZ290byBvdXRfbm9fbWVtOwoJY29uZi0+cG9vbGluZm8tPm1kZGV2ID0gbWRkZXY7Cgljb25mLT5wb29saW5mby0+cmFpZF9kaXNrcyA9IG1kZGV2LT5yYWlkX2Rpc2tzOwoJY29uZi0+cjFiaW9fcG9vbCA9IG1lbXBvb2xfY3JlYXRlKE5SX1JBSUQxX0JJT1MsIHIxYmlvX3Bvb2xfYWxsb2MsCgkJCQkJICByMWJpb19wb29sX2ZyZWUsCgkJCQkJICBjb25mLT5wb29saW5mbyk7CglpZiAoIWNvbmYtPnIxYmlvX3Bvb2wpCgkJZ290byBvdXRfbm9fbWVtOwoKCUlURVJBVEVfUkRFVihtZGRldiwgcmRldiwgdG1wKSB7CgkJZGlza19pZHggPSByZGV2LT5yYWlkX2Rpc2s7CgkJaWYgKGRpc2tfaWR4ID49IG1kZGV2LT5yYWlkX2Rpc2tzCgkJICAgIHx8IGRpc2tfaWR4IDwgMCkKCQkJY29udGludWU7CgkJZGlzayA9IGNvbmYtPm1pcnJvcnMgKyBkaXNrX2lkeDsKCgkJZGlzay0+cmRldiA9IHJkZXY7CgoJCWJsa19xdWV1ZV9zdGFja19saW1pdHMobWRkZXYtPnF1ZXVlLAoJCQkJICAgICAgIHJkZXYtPmJkZXYtPmJkX2Rpc2stPnF1ZXVlKTsKCQkvKiBhcyB3ZSBkb24ndCBob25vdXIgbWVyZ2VfYnZlY19mbiwgd2UgbXVzdCBuZXZlciByaXNrCgkJICogdmlvbGF0aW5nIGl0LCBzbyBsaW1pdCAtPm1heF9zZWN0b3IgdG8gb25lIFBBR0UsIGFzCgkJICogYSBvbmUgcGFnZSByZXF1ZXN0IGlzIG5ldmVyIGluIHZpb2xhdGlvbi4KCQkgKi8KCQlpZiAocmRldi0+YmRldi0+YmRfZGlzay0+cXVldWUtPm1lcmdlX2J2ZWNfZm4gJiYKCQkgICAgbWRkZXYtPnF1ZXVlLT5tYXhfc2VjdG9ycyA+IChQQUdFX1NJWkU+PjkpKQoJCQlibGtfcXVldWVfbWF4X3NlY3RvcnMobWRkZXYtPnF1ZXVlLCBQQUdFX1NJWkU+PjkpOwoKCQlkaXNrLT5oZWFkX3Bvc2l0aW9uID0gMDsKCQlpZiAoIXRlc3RfYml0KEZhdWx0eSwgJnJkZXYtPmZsYWdzKSAmJiB0ZXN0X2JpdChJbl9zeW5jLCAmcmRldi0+ZmxhZ3MpKQoJCQljb25mLT53b3JraW5nX2Rpc2tzKys7Cgl9Cgljb25mLT5yYWlkX2Rpc2tzID0gbWRkZXYtPnJhaWRfZGlza3M7Cgljb25mLT5tZGRldiA9IG1kZGV2OwoJc3Bpbl9sb2NrX2luaXQoJmNvbmYtPmRldmljZV9sb2NrKTsKCUlOSVRfTElTVF9IRUFEKCZjb25mLT5yZXRyeV9saXN0KTsKCWlmIChjb25mLT53b3JraW5nX2Rpc2tzID09IDEpCgkJbWRkZXYtPnJlY292ZXJ5X2NwID0gTWF4U2VjdG9yOwoKCXNwaW5fbG9ja19pbml0KCZjb25mLT5yZXN5bmNfbG9jayk7Cglpbml0X3dhaXRxdWV1ZV9oZWFkKCZjb25mLT53YWl0X2JhcnJpZXIpOwoKCWJpb19saXN0X2luaXQoJmNvbmYtPnBlbmRpbmdfYmlvX2xpc3QpOwoJYmlvX2xpc3RfaW5pdCgmY29uZi0+Zmx1c2hpbmdfYmlvX2xpc3QpOwoKCWlmICghY29uZi0+d29ya2luZ19kaXNrcykgewoJCXByaW50ayhLRVJOX0VSUiAicmFpZDE6IG5vIG9wZXJhdGlvbmFsIG1pcnJvcnMgZm9yICVzXG4iLAoJCQltZG5hbWUobWRkZXYpKTsKCQlnb3RvIG91dF9mcmVlX2NvbmY7Cgl9CgoJbWRkZXYtPmRlZ3JhZGVkID0gMDsKCWZvciAoaSA9IDA7IGkgPCBjb25mLT5yYWlkX2Rpc2tzOyBpKyspIHsKCgkJZGlzayA9IGNvbmYtPm1pcnJvcnMgKyBpOwoKCQlpZiAoIWRpc2stPnJkZXYgfHwKCQkgICAgIXRlc3RfYml0KEluX3N5bmMsICZkaXNrLT5yZGV2LT5mbGFncykpIHsKCQkJZGlzay0+aGVhZF9wb3NpdGlvbiA9IDA7CgkJCW1kZGV2LT5kZWdyYWRlZCsrOwoJCX0KCX0KCgkvKgoJICogZmluZCB0aGUgZmlyc3Qgd29ya2luZyBvbmUgYW5kIHVzZSBpdCBhcyBhIHN0YXJ0aW5nIHBvaW50CgkgKiB0byByZWFkIGJhbGFuY2luZy4KCSAqLwoJZm9yIChqID0gMDsgaiA8IGNvbmYtPnJhaWRfZGlza3MgJiYKCQkgICAgICghY29uZi0+bWlycm9yc1tqXS5yZGV2IHx8CgkJICAgICAgIXRlc3RfYml0KEluX3N5bmMsICZjb25mLT5taXJyb3JzW2pdLnJkZXYtPmZsYWdzKSkgOyBqKyspCgkJLyogbm90aGluZyAqLzsKCWNvbmYtPmxhc3RfdXNlZCA9IGo7CgoKCW1kZGV2LT50aHJlYWQgPSBtZF9yZWdpc3Rlcl90aHJlYWQocmFpZDFkLCBtZGRldiwgIiVzX3JhaWQxIik7CglpZiAoIW1kZGV2LT50aHJlYWQpIHsKCQlwcmludGsoS0VSTl9FUlIKCQkgICAgICAgInJhaWQxOiBjb3VsZG4ndCBhbGxvY2F0ZSB0aHJlYWQgZm9yICVzXG4iLAoJCSAgICAgICBtZG5hbWUobWRkZXYpKTsKCQlnb3RvIG91dF9mcmVlX2NvbmY7Cgl9CgoJcHJpbnRrKEtFUk5fSU5GTyAKCQkicmFpZDE6IHJhaWQgc2V0ICVzIGFjdGl2ZSB3aXRoICVkIG91dCBvZiAlZCBtaXJyb3JzXG4iLAoJCW1kbmFtZShtZGRldiksIG1kZGV2LT5yYWlkX2Rpc2tzIC0gbWRkZXYtPmRlZ3JhZGVkLCAKCQltZGRldi0+cmFpZF9kaXNrcyk7CgkvKgoJICogT2ssIGV2ZXJ5dGhpbmcgaXMganVzdCBmaW5lIG5vdwoJICovCgltZGRldi0+YXJyYXlfc2l6ZSA9IG1kZGV2LT5zaXplOwoKCW1kZGV2LT5xdWV1ZS0+dW5wbHVnX2ZuID0gcmFpZDFfdW5wbHVnOwoJbWRkZXYtPnF1ZXVlLT5pc3N1ZV9mbHVzaF9mbiA9IHJhaWQxX2lzc3VlX2ZsdXNoOwoKCXJldHVybiAwOwoKb3V0X25vX21lbToKCXByaW50ayhLRVJOX0VSUiAicmFpZDE6IGNvdWxkbid0IGFsbG9jYXRlIG1lbW9yeSBmb3IgJXNcbiIsCgkgICAgICAgbWRuYW1lKG1kZGV2KSk7CgpvdXRfZnJlZV9jb25mOgoJaWYgKGNvbmYpIHsKCQlpZiAoY29uZi0+cjFiaW9fcG9vbCkKCQkJbWVtcG9vbF9kZXN0cm95KGNvbmYtPnIxYmlvX3Bvb2wpOwoJCWtmcmVlKGNvbmYtPm1pcnJvcnMpOwoJCXNhZmVfcHV0X3BhZ2UoY29uZi0+dG1wcGFnZSk7CgkJa2ZyZWUoY29uZi0+cG9vbGluZm8pOwoJCWtmcmVlKGNvbmYpOwoJCW1kZGV2LT5wcml2YXRlID0gTlVMTDsKCX0Kb3V0OgoJcmV0dXJuIC1FSU87Cn0KCnN0YXRpYyBpbnQgc3RvcChtZGRldl90ICptZGRldikKewoJY29uZl90ICpjb25mID0gbWRkZXZfdG9fY29uZihtZGRldik7CglzdHJ1Y3QgYml0bWFwICpiaXRtYXAgPSBtZGRldi0+Yml0bWFwOwoJaW50IGJlaGluZF93YWl0ID0gMDsKCgkvKiB3YWl0IGZvciBiZWhpbmQgd3JpdGVzIHRvIGNvbXBsZXRlICovCgl3aGlsZSAoYml0bWFwICYmIGF0b21pY19yZWFkKCZiaXRtYXAtPmJlaGluZF93cml0ZXMpID4gMCkgewoJCWJlaGluZF93YWl0Kys7CgkJcHJpbnRrKEtFUk5fSU5GTyAicmFpZDE6IGJlaGluZCB3cml0ZXMgaW4gcHJvZ3Jlc3Mgb24gZGV2aWNlICVzLCB3YWl0aW5nIHRvIHN0b3AgKCVkKVxuIiwgbWRuYW1lKG1kZGV2KSwgYmVoaW5kX3dhaXQpOwoJCXNldF9jdXJyZW50X3N0YXRlKFRBU0tfVU5JTlRFUlJVUFRJQkxFKTsKCQlzY2hlZHVsZV90aW1lb3V0KEhaKTsgLyogd2FpdCBhIHNlY29uZCAqLwoJCS8qIG5lZWQgdG8ga2ljayBzb21ldGhpbmcgaGVyZSB0byBtYWtlIHN1cmUgSS9PIGdvZXM/ICovCgl9CgoJbWRfdW5yZWdpc3Rlcl90aHJlYWQobWRkZXYtPnRocmVhZCk7CgltZGRldi0+dGhyZWFkID0gTlVMTDsKCWJsa19zeW5jX3F1ZXVlKG1kZGV2LT5xdWV1ZSk7IC8qIHRoZSB1bnBsdWcgZm4gcmVmZXJlbmNlcyAnY29uZicqLwoJaWYgKGNvbmYtPnIxYmlvX3Bvb2wpCgkJbWVtcG9vbF9kZXN0cm95KGNvbmYtPnIxYmlvX3Bvb2wpOwoJa2ZyZWUoY29uZi0+bWlycm9ycyk7CglrZnJlZShjb25mLT5wb29saW5mbyk7CglrZnJlZShjb25mKTsKCW1kZGV2LT5wcml2YXRlID0gTlVMTDsKCXJldHVybiAwOwp9CgpzdGF0aWMgaW50IHJhaWQxX3Jlc2l6ZShtZGRldl90ICptZGRldiwgc2VjdG9yX3Qgc2VjdG9ycykKewoJLyogbm8gcmVzeW5jIGlzIGhhcHBlbmluZywgYW5kIHRoZXJlIGlzIGVub3VnaCBzcGFjZQoJICogb24gYWxsIGRldmljZXMsIHNvIHdlIGNhbiByZXNpemUuCgkgKiBXZSBuZWVkIHRvIG1ha2Ugc3VyZSByZXN5bmMgY292ZXJzIGFueSBuZXcgc3BhY2UuCgkgKiBJZiB0aGUgYXJyYXkgaXMgc2hyaW5raW5nIHdlIHNob3VsZCBwb3NzaWJseSB3YWl0IHVudGlsCgkgKiBhbnkgaW8gaW4gdGhlIHJlbW92ZWQgc3BhY2UgY29tcGxldGVzLCBidXQgaXQgaGFyZGx5IHNlZW1zCgkgKiB3b3J0aCBpdC4KCSAqLwoJbWRkZXYtPmFycmF5X3NpemUgPSBzZWN0b3JzPj4xOwoJc2V0X2NhcGFjaXR5KG1kZGV2LT5nZW5kaXNrLCBtZGRldi0+YXJyYXlfc2l6ZSA8PCAxKTsKCW1kZGV2LT5jaGFuZ2VkID0gMTsKCWlmIChtZGRldi0+YXJyYXlfc2l6ZSA+IG1kZGV2LT5zaXplICYmIG1kZGV2LT5yZWNvdmVyeV9jcCA9PSBNYXhTZWN0b3IpIHsKCQltZGRldi0+cmVjb3ZlcnlfY3AgPSBtZGRldi0+c2l6ZSA8PCAxOwoJCXNldF9iaXQoTURfUkVDT1ZFUllfTkVFREVELCAmbWRkZXYtPnJlY292ZXJ5KTsKCX0KCW1kZGV2LT5zaXplID0gbWRkZXYtPmFycmF5X3NpemU7CgltZGRldi0+cmVzeW5jX21heF9zZWN0b3JzID0gc2VjdG9yczsKCXJldHVybiAwOwp9CgpzdGF0aWMgaW50IHJhaWQxX3Jlc2hhcGUobWRkZXZfdCAqbWRkZXYpCnsKCS8qIFdlIG5lZWQgdG86CgkgKiAxLyByZXNpemUgdGhlIHIxYmlvX3Bvb2wKCSAqIDIvIHJlc2l6ZSBjb25mLT5taXJyb3JzCgkgKgoJICogV2UgYWxsb2NhdGUgYSBuZXcgcjFiaW9fcG9vbCBpZiB3ZSBjYW4uCgkgKiBUaGVuIHJhaXNlIGEgZGV2aWNlIGJhcnJpZXIgYW5kIHdhaXQgdW50aWwgYWxsIElPIHN0b3BzLgoJICogVGhlbiByZXNpemUgY29uZi0+bWlycm9ycyBhbmQgc3dhcCBpbiB0aGUgbmV3IHIxYmlvIHBvb2wuCgkgKgoJICogQXQgdGhlIHNhbWUgdGltZSwgd2UgInBhY2siIHRoZSBkZXZpY2VzIHNvIHRoYXQgYWxsIHRoZSBtaXNzaW5nCgkgKiBkZXZpY2VzIGhhdmUgdGhlIGhpZ2hlciByYWlkX2Rpc2sgbnVtYmVycy4KCSAqLwoJbWVtcG9vbF90ICpuZXdwb29sLCAqb2xkcG9vbDsKCXN0cnVjdCBwb29sX2luZm8gKm5ld3Bvb2xpbmZvOwoJbWlycm9yX2luZm9fdCAqbmV3bWlycm9yczsKCWNvbmZfdCAqY29uZiA9IG1kZGV2X3RvX2NvbmYobWRkZXYpOwoJaW50IGNudCwgcmFpZF9kaXNrczsKCglpbnQgZCwgZDI7CgoJLyogQ2Fubm90IGNoYW5nZSBjaHVua19zaXplLCBsYXlvdXQsIG9yIGxldmVsICovCglpZiAobWRkZXYtPmNodW5rX3NpemUgIT0gbWRkZXYtPm5ld19jaHVuayB8fAoJICAgIG1kZGV2LT5sYXlvdXQgIT0gbWRkZXYtPm5ld19sYXlvdXQgfHwKCSAgICBtZGRldi0+bGV2ZWwgIT0gbWRkZXYtPm5ld19sZXZlbCkgewoJCW1kZGV2LT5uZXdfY2h1bmsgPSBtZGRldi0+Y2h1bmtfc2l6ZTsKCQltZGRldi0+bmV3X2xheW91dCA9IG1kZGV2LT5sYXlvdXQ7CgkJbWRkZXYtPm5ld19sZXZlbCA9IG1kZGV2LT5sZXZlbDsKCQlyZXR1cm4gLUVJTlZBTDsKCX0KCglyYWlkX2Rpc2tzID0gbWRkZXYtPnJhaWRfZGlza3MgKyBtZGRldi0+ZGVsdGFfZGlza3M7CgoJaWYgKHJhaWRfZGlza3MgPCBjb25mLT5yYWlkX2Rpc2tzKSB7CgkJY250PTA7CgkJZm9yIChkPSAwOyBkIDwgY29uZi0+cmFpZF9kaXNrczsgZCsrKQoJCQlpZiAoY29uZi0+bWlycm9yc1tkXS5yZGV2KQoJCQkJY250Kys7CgkJaWYgKGNudCA+IHJhaWRfZGlza3MpCgkJCXJldHVybiAtRUJVU1k7Cgl9CgoJbmV3cG9vbGluZm8gPSBrbWFsbG9jKHNpemVvZigqbmV3cG9vbGluZm8pLCBHRlBfS0VSTkVMKTsKCWlmICghbmV3cG9vbGluZm8pCgkJcmV0dXJuIC1FTk9NRU07CgluZXdwb29saW5mby0+bWRkZXYgPSBtZGRldjsKCW5ld3Bvb2xpbmZvLT5yYWlkX2Rpc2tzID0gcmFpZF9kaXNrczsKCgluZXdwb29sID0gbWVtcG9vbF9jcmVhdGUoTlJfUkFJRDFfQklPUywgcjFiaW9fcG9vbF9hbGxvYywKCQkJCSByMWJpb19wb29sX2ZyZWUsIG5ld3Bvb2xpbmZvKTsKCWlmICghbmV3cG9vbCkgewoJCWtmcmVlKG5ld3Bvb2xpbmZvKTsKCQlyZXR1cm4gLUVOT01FTTsKCX0KCW5ld21pcnJvcnMgPSBremFsbG9jKHNpemVvZihzdHJ1Y3QgbWlycm9yX2luZm8pICogcmFpZF9kaXNrcywgR0ZQX0tFUk5FTCk7CglpZiAoIW5ld21pcnJvcnMpIHsKCQlrZnJlZShuZXdwb29saW5mbyk7CgkJbWVtcG9vbF9kZXN0cm95KG5ld3Bvb2wpOwoJCXJldHVybiAtRU5PTUVNOwoJfQoKCXJhaXNlX2JhcnJpZXIoY29uZik7CgoJLyogb2ssIGV2ZXJ5dGhpbmcgaXMgc3RvcHBlZCAqLwoJb2xkcG9vbCA9IGNvbmYtPnIxYmlvX3Bvb2w7Cgljb25mLT5yMWJpb19wb29sID0gbmV3cG9vbDsKCglmb3IgKGQ9ZDI9MDsgZCA8IGNvbmYtPnJhaWRfZGlza3M7IGQrKykKCQlpZiAoY29uZi0+bWlycm9yc1tkXS5yZGV2KSB7CgkJCWNvbmYtPm1pcnJvcnNbZF0ucmRldi0+cmFpZF9kaXNrID0gZDI7CgkJCW5ld21pcnJvcnNbZDIrK10ucmRldiA9IGNvbmYtPm1pcnJvcnNbZF0ucmRldjsKCQl9CglrZnJlZShjb25mLT5taXJyb3JzKTsKCWNvbmYtPm1pcnJvcnMgPSBuZXdtaXJyb3JzOwoJa2ZyZWUoY29uZi0+cG9vbGluZm8pOwoJY29uZi0+cG9vbGluZm8gPSBuZXdwb29saW5mbzsKCgltZGRldi0+ZGVncmFkZWQgKz0gKHJhaWRfZGlza3MgLSBjb25mLT5yYWlkX2Rpc2tzKTsKCWNvbmYtPnJhaWRfZGlza3MgPSBtZGRldi0+cmFpZF9kaXNrcyA9IHJhaWRfZGlza3M7CgltZGRldi0+ZGVsdGFfZGlza3MgPSAwOwoKCWNvbmYtPmxhc3RfdXNlZCA9IDA7IC8qIGp1c3QgbWFrZSBzdXJlIGl0IGlzIGluLXJhbmdlICovCglsb3dlcl9iYXJyaWVyKGNvbmYpOwoKCXNldF9iaXQoTURfUkVDT1ZFUllfTkVFREVELCAmbWRkZXYtPnJlY292ZXJ5KTsKCW1kX3dha2V1cF90aHJlYWQobWRkZXYtPnRocmVhZCk7CgoJbWVtcG9vbF9kZXN0cm95KG9sZHBvb2wpOwoJcmV0dXJuIDA7Cn0KCnN0YXRpYyB2b2lkIHJhaWQxX3F1aWVzY2UobWRkZXZfdCAqbWRkZXYsIGludCBzdGF0ZSkKewoJY29uZl90ICpjb25mID0gbWRkZXZfdG9fY29uZihtZGRldik7CgoJc3dpdGNoKHN0YXRlKSB7CgljYXNlIDE6CgkJcmFpc2VfYmFycmllcihjb25mKTsKCQlicmVhazsKCWNhc2UgMDoKCQlsb3dlcl9iYXJyaWVyKGNvbmYpOwoJCWJyZWFrOwoJfQp9CgoKc3RhdGljIHN0cnVjdCBtZGtfcGVyc29uYWxpdHkgcmFpZDFfcGVyc29uYWxpdHkgPQp7CgkubmFtZQkJPSAicmFpZDEiLAoJLmxldmVsCQk9IDEsCgkub3duZXIJCT0gVEhJU19NT0RVTEUsCgkubWFrZV9yZXF1ZXN0CT0gbWFrZV9yZXF1ZXN0LAoJLnJ1bgkJPSBydW4sCgkuc3RvcAkJPSBzdG9wLAoJLnN0YXR1cwkJPSBzdGF0dXMsCgkuZXJyb3JfaGFuZGxlcgk9IGVycm9yLAoJLmhvdF9hZGRfZGlzawk9IHJhaWQxX2FkZF9kaXNrLAoJLmhvdF9yZW1vdmVfZGlzaz0gcmFpZDFfcmVtb3ZlX2Rpc2ssCgkuc3BhcmVfYWN0aXZlCT0gcmFpZDFfc3BhcmVfYWN0aXZlLAoJLnN5bmNfcmVxdWVzdAk9IHN5bmNfcmVxdWVzdCwKCS5yZXNpemUJCT0gcmFpZDFfcmVzaXplLAoJLmNoZWNrX3Jlc2hhcGUJPSByYWlkMV9yZXNoYXBlLAoJLnF1aWVzY2UJPSByYWlkMV9xdWllc2NlLAp9OwoKc3RhdGljIGludCBfX2luaXQgcmFpZF9pbml0KHZvaWQpCnsKCXJldHVybiByZWdpc3Rlcl9tZF9wZXJzb25hbGl0eSgmcmFpZDFfcGVyc29uYWxpdHkpOwp9CgpzdGF0aWMgdm9pZCByYWlkX2V4aXQodm9pZCkKewoJdW5yZWdpc3Rlcl9tZF9wZXJzb25hbGl0eSgmcmFpZDFfcGVyc29uYWxpdHkpOwp9Cgptb2R1bGVfaW5pdChyYWlkX2luaXQpOwptb2R1bGVfZXhpdChyYWlkX2V4aXQpOwpNT0RVTEVfTElDRU5TRSgiR1BMIik7Ck1PRFVMRV9BTElBUygibWQtcGVyc29uYWxpdHktMyIpOyAvKiBSQUlEMSAqLwpNT0RVTEVfQUxJQVMoIm1kLXJhaWQxIik7Ck1PRFVMRV9BTElBUygibWQtbGV2ZWwtMSIpOwo=