LyoKICogcmFpZDEuYyA6IE11bHRpcGxlIERldmljZXMgZHJpdmVyIGZvciBMaW51eAogKgogKiBDb3B5cmlnaHQgKEMpIDE5OTksIDIwMDAsIDIwMDEgSW5nbyBNb2xuYXIsIFJlZCBIYXQKICoKICogQ29weXJpZ2h0IChDKSAxOTk2LCAxOTk3LCAxOTk4IEluZ28gTW9sbmFyLCBNaWd1ZWwgZGUgSWNhemEsIEdhZGkgT3htYW4KICoKICogUkFJRC0xIG1hbmFnZW1lbnQgZnVuY3Rpb25zLgogKgogKiBCZXR0ZXIgcmVhZC1iYWxhbmNpbmcgY29kZSB3cml0dGVuIGJ5IE1pa2EgS3VvcHBhbGEgPG1pa3VAaWtpLmZpPiwgMjAwMAogKgogKiBGaXhlcyB0byByZWNvbnN0cnVjdGlvbiBieSBKYWtvYiDYc3RlcmdhYXJkIiA8amFrb2JAb3N0ZW5mZWxkLmRrPgogKiBWYXJpb3VzIGZpeGVzIGJ5IE5laWwgQnJvd24gPG5laWxiQGNzZS51bnN3LmVkdS5hdT4KICoKICogQ2hhbmdlcyBieSBQZXRlciBULiBCcmV1ZXIgPHB0YkBpdC51YzNtLmVzPiAzMS8xLzIwMDMgdG8gc3VwcG9ydAogKiBiaXRtYXBwZWQgaW50ZWxsaWdlbmNlIGluIHJlc3luYzoKICoKICogICAgICAtIGJpdG1hcCBtYXJrZWQgZHVyaW5nIG5vcm1hbCBpL28KICogICAgICAtIGJpdG1hcCB1c2VkIHRvIHNraXAgbm9uZGlydHkgYmxvY2tzIGR1cmluZyBzeW5jCiAqCiAqIEFkZGl0aW9ucyB0byBiaXRtYXAgY29kZSwgKEMpIDIwMDMtMjAwNCBQYXVsIENsZW1lbnRzLCBTdGVlbEV5ZSBUZWNobm9sb2d5OgogKiAtIHBlcnNpc3RlbnQgYml0bWFwIGNvZGUKICoKICogVGhpcyBwcm9ncmFtIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkKICogaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkKICogdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyIHZlcnNpb24gMiwgb3IgKGF0IHlvdXIgb3B0aW9uKQogKiBhbnkgbGF0ZXIgdmVyc2lvbi4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogKGZvciBleGFtcGxlIC91c3Ivc3JjL2xpbnV4L0NPUFlJTkcpOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlCiAqIFNvZnR3YXJlIEZvdW5kYXRpb24sIEluYy4sIDY3NSBNYXNzIEF2ZSwgQ2FtYnJpZGdlLCBNQSAwMjEzOSwgVVNBLgogKi8KCiNpbmNsdWRlICJkbS1iaW8tbGlzdC5oIgojaW5jbHVkZSA8bGludXgvcmFpZC9yYWlkMS5oPgojaW5jbHVkZSA8bGludXgvcmFpZC9iaXRtYXAuaD4KCiNkZWZpbmUgREVCVUcgMAojaWYgREVCVUcKI2RlZmluZSBQUklOVEsoeC4uLikgcHJpbnRrKHgpCiNlbHNlCiNkZWZpbmUgUFJJTlRLKHguLi4pCiNlbmRpZgoKLyoKICogTnVtYmVyIG9mIGd1YXJhbnRlZWQgcjFiaW9zIGluIGNhc2Ugb2YgZXh0cmVtZSBWTSBsb2FkOgogKi8KI2RlZmluZQlOUl9SQUlEMV9CSU9TIDI1NgoKCnN0YXRpYyB2b2lkIHVucGx1Z19zbGF2ZXMobWRkZXZfdCAqbWRkZXYpOwoKc3RhdGljIHZvaWQgYWxsb3dfYmFycmllcihjb25mX3QgKmNvbmYpOwpzdGF0aWMgdm9pZCBsb3dlcl9iYXJyaWVyKGNvbmZfdCAqY29uZik7CgpzdGF0aWMgdm9pZCAqIHIxYmlvX3Bvb2xfYWxsb2MoZ2ZwX3QgZ2ZwX2ZsYWdzLCB2b2lkICpkYXRhKQp7CglzdHJ1Y3QgcG9vbF9pbmZvICpwaSA9IGRhdGE7CglyMWJpb190ICpyMV9iaW87CglpbnQgc2l6ZSA9IG9mZnNldG9mKHIxYmlvX3QsIGJpb3NbcGktPnJhaWRfZGlza3NdKTsKCgkvKiBhbGxvY2F0ZSBhIHIxYmlvIHdpdGggcm9vbSBmb3IgcmFpZF9kaXNrcyBlbnRyaWVzIGluIHRoZSBiaW9zIGFycmF5ICovCglyMV9iaW8gPSBremFsbG9jKHNpemUsIGdmcF9mbGFncyk7CglpZiAoIXIxX2JpbykKCQl1bnBsdWdfc2xhdmVzKHBpLT5tZGRldik7CgoJcmV0dXJuIHIxX2JpbzsKfQoKc3RhdGljIHZvaWQgcjFiaW9fcG9vbF9mcmVlKHZvaWQgKnIxX2Jpbywgdm9pZCAqZGF0YSkKewoJa2ZyZWUocjFfYmlvKTsKfQoKI2RlZmluZSBSRVNZTkNfQkxPQ0tfU0laRSAoNjQqMTAyNCkKLy8jZGVmaW5lIFJFU1lOQ19CTE9DS19TSVpFIFBBR0VfU0laRQojZGVmaW5lIFJFU1lOQ19TRUNUT1JTIChSRVNZTkNfQkxPQ0tfU0laRSA+PiA5KQojZGVmaW5lIFJFU1lOQ19QQUdFUyAoKFJFU1lOQ19CTE9DS19TSVpFICsgUEFHRV9TSVpFLTEpIC8gUEFHRV9TSVpFKQojZGVmaW5lIFJFU1lOQ19XSU5ET1cgKDIwNDgqMTAyNCkKCnN0YXRpYyB2b2lkICogcjFidWZfcG9vbF9hbGxvYyhnZnBfdCBnZnBfZmxhZ3MsIHZvaWQgKmRhdGEpCnsKCXN0cnVjdCBwb29sX2luZm8gKnBpID0gZGF0YTsKCXN0cnVjdCBwYWdlICpwYWdlOwoJcjFiaW9fdCAqcjFfYmlvOwoJc3RydWN0IGJpbyAqYmlvOwoJaW50IGksIGo7CgoJcjFfYmlvID0gcjFiaW9fcG9vbF9hbGxvYyhnZnBfZmxhZ3MsIHBpKTsKCWlmICghcjFfYmlvKSB7CgkJdW5wbHVnX3NsYXZlcyhwaS0+bWRkZXYpOwoJCXJldHVybiBOVUxMOwoJfQoKCS8qCgkgKiBBbGxvY2F0ZSBiaW9zIDogMSBmb3IgcmVhZGluZywgbi0xIGZvciB3cml0aW5nCgkgKi8KCWZvciAoaiA9IHBpLT5yYWlkX2Rpc2tzIDsgai0tIDsgKSB7CgkJYmlvID0gYmlvX2FsbG9jKGdmcF9mbGFncywgUkVTWU5DX1BBR0VTKTsKCQlpZiAoIWJpbykKCQkJZ290byBvdXRfZnJlZV9iaW87CgkJcjFfYmlvLT5iaW9zW2pdID0gYmlvOwoJfQoJLyoKCSAqIEFsbG9jYXRlIFJFU1lOQ19QQUdFUyBkYXRhIHBhZ2VzIGFuZCBhdHRhY2ggdGhlbSB0bwoJICogdGhlIGZpcnN0IGJpby4KCSAqIElmIHRoaXMgaXMgYSB1c2VyLXJlcXVlc3RlZCBjaGVjay9yZXBhaXIsIGFsbG9jYXRlCgkgKiBSRVNZTkNfUEFHRVMgZm9yIGVhY2ggYmlvLgoJICovCglpZiAodGVzdF9iaXQoTURfUkVDT1ZFUllfUkVRVUVTVEVELCAmcGktPm1kZGV2LT5yZWNvdmVyeSkpCgkJaiA9IHBpLT5yYWlkX2Rpc2tzOwoJZWxzZQoJCWogPSAxOwoJd2hpbGUoai0tKSB7CgkJYmlvID0gcjFfYmlvLT5iaW9zW2pdOwoJCWZvciAoaSA9IDA7IGkgPCBSRVNZTkNfUEFHRVM7IGkrKykgewoJCQlwYWdlID0gYWxsb2NfcGFnZShnZnBfZmxhZ3MpOwoJCQlpZiAodW5saWtlbHkoIXBhZ2UpKQoJCQkJZ290byBvdXRfZnJlZV9wYWdlczsKCgkJCWJpby0+YmlfaW9fdmVjW2ldLmJ2X3BhZ2UgPSBwYWdlOwoJCX0KCX0KCS8qIElmIG5vdCB1c2VyLXJlcXVlc3RzLCBjb3B5IHRoZSBwYWdlIHBvaW50ZXJzIHRvIGFsbCBiaW9zICovCglpZiAoIXRlc3RfYml0KE1EX1JFQ09WRVJZX1JFUVVFU1RFRCwgJnBpLT5tZGRldi0+cmVjb3ZlcnkpKSB7CgkJZm9yIChpPTA7IGk8UkVTWU5DX1BBR0VTIDsgaSsrKQoJCQlmb3IgKGo9MTsgajxwaS0+cmFpZF9kaXNrczsgaisrKQoJCQkJcjFfYmlvLT5iaW9zW2pdLT5iaV9pb192ZWNbaV0uYnZfcGFnZSA9CgkJCQkJcjFfYmlvLT5iaW9zWzBdLT5iaV9pb192ZWNbaV0uYnZfcGFnZTsKCX0KCglyMV9iaW8tPm1hc3Rlcl9iaW8gPSBOVUxMOwoKCXJldHVybiByMV9iaW87CgpvdXRfZnJlZV9wYWdlczoKCWZvciAoaT0wOyBpIDwgUkVTWU5DX1BBR0VTIDsgaSsrKQoJCWZvciAoaj0wIDsgaiA8IHBpLT5yYWlkX2Rpc2tzOyBqKyspCgkJCXNhZmVfcHV0X3BhZ2UocjFfYmlvLT5iaW9zW2pdLT5iaV9pb192ZWNbaV0uYnZfcGFnZSk7CglqID0gLTE7Cm91dF9mcmVlX2JpbzoKCXdoaWxlICggKytqIDwgcGktPnJhaWRfZGlza3MgKQoJCWJpb19wdXQocjFfYmlvLT5iaW9zW2pdKTsKCXIxYmlvX3Bvb2xfZnJlZShyMV9iaW8sIGRhdGEpOwoJcmV0dXJuIE5VTEw7Cn0KCnN0YXRpYyB2b2lkIHIxYnVmX3Bvb2xfZnJlZSh2b2lkICpfX3IxX2Jpbywgdm9pZCAqZGF0YSkKewoJc3RydWN0IHBvb2xfaW5mbyAqcGkgPSBkYXRhOwoJaW50IGksajsKCXIxYmlvX3QgKnIxYmlvID0gX19yMV9iaW87CgoJZm9yIChpID0gMDsgaSA8IFJFU1lOQ19QQUdFUzsgaSsrKQoJCWZvciAoaiA9IHBpLT5yYWlkX2Rpc2tzOyBqLS0gOykgewoJCQlpZiAoaiA9PSAwIHx8CgkJCSAgICByMWJpby0+Ymlvc1tqXS0+YmlfaW9fdmVjW2ldLmJ2X3BhZ2UgIT0KCQkJICAgIHIxYmlvLT5iaW9zWzBdLT5iaV9pb192ZWNbaV0uYnZfcGFnZSkKCQkJCXNhZmVfcHV0X3BhZ2UocjFiaW8tPmJpb3Nbal0tPmJpX2lvX3ZlY1tpXS5idl9wYWdlKTsKCQl9Cglmb3IgKGk9MCA7IGkgPCBwaS0+cmFpZF9kaXNrczsgaSsrKQoJCWJpb19wdXQocjFiaW8tPmJpb3NbaV0pOwoKCXIxYmlvX3Bvb2xfZnJlZShyMWJpbywgZGF0YSk7Cn0KCnN0YXRpYyB2b2lkIHB1dF9hbGxfYmlvcyhjb25mX3QgKmNvbmYsIHIxYmlvX3QgKnIxX2JpbykKewoJaW50IGk7CgoJZm9yIChpID0gMDsgaSA8IGNvbmYtPnJhaWRfZGlza3M7IGkrKykgewoJCXN0cnVjdCBiaW8gKipiaW8gPSByMV9iaW8tPmJpb3MgKyBpOwoJCWlmICgqYmlvICYmICpiaW8gIT0gSU9fQkxPQ0tFRCkKCQkJYmlvX3B1dCgqYmlvKTsKCQkqYmlvID0gTlVMTDsKCX0KfQoKc3RhdGljIHZvaWQgZnJlZV9yMWJpbyhyMWJpb190ICpyMV9iaW8pCnsKCWNvbmZfdCAqY29uZiA9IG1kZGV2X3RvX2NvbmYocjFfYmlvLT5tZGRldik7CgoJLyoKCSAqIFdha2UgdXAgYW55IHBvc3NpYmxlIHJlc3luYyB0aHJlYWQgdGhhdCB3YWl0cyBmb3IgdGhlIGRldmljZQoJICogdG8gZ28gaWRsZS4KCSAqLwoJYWxsb3dfYmFycmllcihjb25mKTsKCglwdXRfYWxsX2Jpb3MoY29uZiwgcjFfYmlvKTsKCW1lbXBvb2xfZnJlZShyMV9iaW8sIGNvbmYtPnIxYmlvX3Bvb2wpOwp9CgpzdGF0aWMgdm9pZCBwdXRfYnVmKHIxYmlvX3QgKnIxX2JpbykKewoJY29uZl90ICpjb25mID0gbWRkZXZfdG9fY29uZihyMV9iaW8tPm1kZGV2KTsKCWludCBpOwoKCWZvciAoaT0wOyBpPGNvbmYtPnJhaWRfZGlza3M7IGkrKykgewoJCXN0cnVjdCBiaW8gKmJpbyA9IHIxX2Jpby0+Ymlvc1tpXTsKCQlpZiAoYmlvLT5iaV9lbmRfaW8pCgkJCXJkZXZfZGVjX3BlbmRpbmcoY29uZi0+bWlycm9yc1tpXS5yZGV2LCByMV9iaW8tPm1kZGV2KTsKCX0KCgltZW1wb29sX2ZyZWUocjFfYmlvLCBjb25mLT5yMWJ1Zl9wb29sKTsKCglsb3dlcl9iYXJyaWVyKGNvbmYpOwp9CgpzdGF0aWMgdm9pZCByZXNjaGVkdWxlX3JldHJ5KHIxYmlvX3QgKnIxX2JpbykKewoJdW5zaWduZWQgbG9uZyBmbGFnczsKCW1kZGV2X3QgKm1kZGV2ID0gcjFfYmlvLT5tZGRldjsKCWNvbmZfdCAqY29uZiA9IG1kZGV2X3RvX2NvbmYobWRkZXYpOwoKCXNwaW5fbG9ja19pcnFzYXZlKCZjb25mLT5kZXZpY2VfbG9jaywgZmxhZ3MpOwoJbGlzdF9hZGQoJnIxX2Jpby0+cmV0cnlfbGlzdCwgJmNvbmYtPnJldHJ5X2xpc3QpOwoJY29uZi0+bnJfcXVldWVkICsrOwoJc3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmY29uZi0+ZGV2aWNlX2xvY2ssIGZsYWdzKTsKCgl3YWtlX3VwKCZjb25mLT53YWl0X2JhcnJpZXIpOwoJbWRfd2FrZXVwX3RocmVhZChtZGRldi0+dGhyZWFkKTsKfQoKLyoKICogcmFpZF9lbmRfYmlvX2lvKCkgaXMgY2FsbGVkIHdoZW4gd2UgaGF2ZSBmaW5pc2hlZCBzZXJ2aWNpbmcgYSBtaXJyb3JlZAogKiBvcGVyYXRpb24gYW5kIGFyZSByZWFkeSB0byByZXR1cm4gYSBzdWNjZXNzL2ZhaWx1cmUgY29kZSB0byB0aGUgYnVmZmVyCiAqIGNhY2hlIGxheWVyLgogKi8Kc3RhdGljIHZvaWQgcmFpZF9lbmRfYmlvX2lvKHIxYmlvX3QgKnIxX2JpbykKewoJc3RydWN0IGJpbyAqYmlvID0gcjFfYmlvLT5tYXN0ZXJfYmlvOwoKCS8qIGlmIG5vYm9keSBoYXMgZG9uZSB0aGUgZmluYWwgZW5kaW8geWV0LCBkbyBpdCBub3cgKi8KCWlmICghdGVzdF9hbmRfc2V0X2JpdChSMUJJT19SZXR1cm5lZCwgJnIxX2Jpby0+c3RhdGUpKSB7CgkJUFJJTlRLKEtFUk5fREVCVUcgInJhaWQxOiBzeW5jIGVuZCAlcyBvbiBzZWN0b3JzICVsbHUtJWxsdVxuIiwKCQkJKGJpb19kYXRhX2RpcihiaW8pID09IFdSSVRFKSA/ICJ3cml0ZSIgOiAicmVhZCIsCgkJCSh1bnNpZ25lZCBsb25nIGxvbmcpIGJpby0+Ymlfc2VjdG9yLAoJCQkodW5zaWduZWQgbG9uZyBsb25nKSBiaW8tPmJpX3NlY3RvciArCgkJCQkoYmlvLT5iaV9zaXplID4+IDkpIC0gMSk7CgoJCWJpb19lbmRpbyhiaW8sCgkJCXRlc3RfYml0KFIxQklPX1VwdG9kYXRlLCAmcjFfYmlvLT5zdGF0ZSkgPyAwIDogLUVJTyk7Cgl9CglmcmVlX3IxYmlvKHIxX2Jpbyk7Cn0KCi8qCiAqIFVwZGF0ZSBkaXNrIGhlYWQgcG9zaXRpb24gZXN0aW1hdG9yIGJhc2VkIG9uIElSUSBjb21wbGV0aW9uIGluZm8uCiAqLwpzdGF0aWMgaW5saW5lIHZvaWQgdXBkYXRlX2hlYWRfcG9zKGludCBkaXNrLCByMWJpb190ICpyMV9iaW8pCnsKCWNvbmZfdCAqY29uZiA9IG1kZGV2X3RvX2NvbmYocjFfYmlvLT5tZGRldik7CgoJY29uZi0+bWlycm9yc1tkaXNrXS5oZWFkX3Bvc2l0aW9uID0KCQlyMV9iaW8tPnNlY3RvciArIChyMV9iaW8tPnNlY3RvcnMpOwp9CgpzdGF0aWMgdm9pZCByYWlkMV9lbmRfcmVhZF9yZXF1ZXN0KHN0cnVjdCBiaW8gKmJpbywgaW50IGVycm9yKQp7CglpbnQgdXB0b2RhdGUgPSB0ZXN0X2JpdChCSU9fVVBUT0RBVEUsICZiaW8tPmJpX2ZsYWdzKTsKCXIxYmlvX3QgKiByMV9iaW8gPSAocjFiaW9fdCAqKShiaW8tPmJpX3ByaXZhdGUpOwoJaW50IG1pcnJvcjsKCWNvbmZfdCAqY29uZiA9IG1kZGV2X3RvX2NvbmYocjFfYmlvLT5tZGRldik7CgoJbWlycm9yID0gcjFfYmlvLT5yZWFkX2Rpc2s7CgkvKgoJICogdGhpcyBicmFuY2ggaXMgb3VyICdvbmUgbWlycm9yIElPIGhhcyBmaW5pc2hlZCcgZXZlbnQgaGFuZGxlcjoKCSAqLwoJdXBkYXRlX2hlYWRfcG9zKG1pcnJvciwgcjFfYmlvKTsKCglpZiAodXB0b2RhdGUpCgkJc2V0X2JpdChSMUJJT19VcHRvZGF0ZSwgJnIxX2Jpby0+c3RhdGUpOwoJZWxzZSB7CgkJLyogSWYgYWxsIG90aGVyIGRldmljZXMgaGF2ZSBmYWlsZWQsIHdlIHdhbnQgdG8gcmV0dXJuCgkJICogdGhlIGVycm9yIHVwd2FyZHMgcmF0aGVyIHRoYW4gZmFpbCB0aGUgbGFzdCBkZXZpY2UuCgkJICogSGVyZSB3ZSByZWRlZmluZSAidXB0b2RhdGUiIHRvIG1lYW4gIkRvbid0IHdhbnQgdG8gcmV0cnkiCgkJICovCgkJdW5zaWduZWQgbG9uZyBmbGFnczsKCQlzcGluX2xvY2tfaXJxc2F2ZSgmY29uZi0+ZGV2aWNlX2xvY2ssIGZsYWdzKTsKCQlpZiAocjFfYmlvLT5tZGRldi0+ZGVncmFkZWQgPT0gY29uZi0+cmFpZF9kaXNrcyB8fAoJCSAgICAocjFfYmlvLT5tZGRldi0+ZGVncmFkZWQgPT0gY29uZi0+cmFpZF9kaXNrcy0xICYmCgkJICAgICAhdGVzdF9iaXQoRmF1bHR5LCAmY29uZi0+bWlycm9yc1ttaXJyb3JdLnJkZXYtPmZsYWdzKSkpCgkJCXVwdG9kYXRlID0gMTsKCQlzcGluX3VubG9ja19pcnFyZXN0b3JlKCZjb25mLT5kZXZpY2VfbG9jaywgZmxhZ3MpOwoJfQoKCWlmICh1cHRvZGF0ZSkKCQlyYWlkX2VuZF9iaW9faW8ocjFfYmlvKTsKCWVsc2UgewoJCS8qCgkJICogb29wcywgcmVhZCBlcnJvcjoKCQkgKi8KCQljaGFyIGJbQkRFVk5BTUVfU0laRV07CgkJaWYgKHByaW50a19yYXRlbGltaXQoKSkKCQkJcHJpbnRrKEtFUk5fRVJSICJyYWlkMTogJXM6IHJlc2NoZWR1bGluZyBzZWN0b3IgJWxsdVxuIiwKCQkJICAgICAgIGJkZXZuYW1lKGNvbmYtPm1pcnJvcnNbbWlycm9yXS5yZGV2LT5iZGV2LGIpLCAodW5zaWduZWQgbG9uZyBsb25nKXIxX2Jpby0+c2VjdG9yKTsKCQlyZXNjaGVkdWxlX3JldHJ5KHIxX2Jpbyk7Cgl9CgoJcmRldl9kZWNfcGVuZGluZyhjb25mLT5taXJyb3JzW21pcnJvcl0ucmRldiwgY29uZi0+bWRkZXYpOwp9CgpzdGF0aWMgdm9pZCByYWlkMV9lbmRfd3JpdGVfcmVxdWVzdChzdHJ1Y3QgYmlvICpiaW8sIGludCBlcnJvcikKewoJaW50IHVwdG9kYXRlID0gdGVzdF9iaXQoQklPX1VQVE9EQVRFLCAmYmlvLT5iaV9mbGFncyk7CglyMWJpb190ICogcjFfYmlvID0gKHIxYmlvX3QgKikoYmlvLT5iaV9wcml2YXRlKTsKCWludCBtaXJyb3IsIGJlaGluZCA9IHRlc3RfYml0KFIxQklPX0JlaGluZElPLCAmcjFfYmlvLT5zdGF0ZSk7Cgljb25mX3QgKmNvbmYgPSBtZGRldl90b19jb25mKHIxX2Jpby0+bWRkZXYpOwoJc3RydWN0IGJpbyAqdG9fcHV0ID0gTlVMTDsKCgoJZm9yIChtaXJyb3IgPSAwOyBtaXJyb3IgPCBjb25mLT5yYWlkX2Rpc2tzOyBtaXJyb3IrKykKCQlpZiAocjFfYmlvLT5iaW9zW21pcnJvcl0gPT0gYmlvKQoJCQlicmVhazsKCglpZiAoZXJyb3IgPT0gLUVPUE5PVFNVUFAgJiYgdGVzdF9iaXQoUjFCSU9fQmFycmllciwgJnIxX2Jpby0+c3RhdGUpKSB7CgkJc2V0X2JpdChCYXJyaWVyc05vdHN1cHAsICZjb25mLT5taXJyb3JzW21pcnJvcl0ucmRldi0+ZmxhZ3MpOwoJCXNldF9iaXQoUjFCSU9fQmFycmllclJldHJ5LCAmcjFfYmlvLT5zdGF0ZSk7CgkJcjFfYmlvLT5tZGRldi0+YmFycmllcnNfd29yayA9IDA7CgkJLyogRG9uJ3QgcmRldl9kZWNfcGVuZGluZyBpbiB0aGlzIGJyYW5jaCAtIGtlZXAgaXQgZm9yIHRoZSByZXRyeSAqLwoJfSBlbHNlIHsKCQkvKgoJCSAqIHRoaXMgYnJhbmNoIGlzIG91ciAnb25lIG1pcnJvciBJTyBoYXMgZmluaXNoZWQnIGV2ZW50IGhhbmRsZXI6CgkJICovCgkJcjFfYmlvLT5iaW9zW21pcnJvcl0gPSBOVUxMOwoJCXRvX3B1dCA9IGJpbzsKCQlpZiAoIXVwdG9kYXRlKSB7CgkJCW1kX2Vycm9yKHIxX2Jpby0+bWRkZXYsIGNvbmYtPm1pcnJvcnNbbWlycm9yXS5yZGV2KTsKCQkJLyogYW4gSS9PIGZhaWxlZCwgd2UgY2FuJ3QgY2xlYXIgdGhlIGJpdG1hcCAqLwoJCQlzZXRfYml0KFIxQklPX0RlZ3JhZGVkLCAmcjFfYmlvLT5zdGF0ZSk7CgkJfSBlbHNlCgkJCS8qCgkJCSAqIFNldCBSMUJJT19VcHRvZGF0ZSBpbiBvdXIgbWFzdGVyIGJpbywgc28gdGhhdAoJCQkgKiB3ZSB3aWxsIHJldHVybiBhIGdvb2QgZXJyb3IgY29kZSBmb3IgdG8gdGhlIGhpZ2hlcgoJCQkgKiBsZXZlbHMgZXZlbiBpZiBJTyBvbiBzb21lIG90aGVyIG1pcnJvcmVkIGJ1ZmZlciBmYWlscy4KCQkJICoKCQkJICogVGhlICdtYXN0ZXInIHJlcHJlc2VudHMgdGhlIGNvbXBvc2l0ZSBJTyBvcGVyYXRpb24gdG8KCQkJICogdXNlci1zaWRlLiBTbyBpZiBzb21ldGhpbmcgd2FpdHMgZm9yIElPLCB0aGVuIGl0IHdpbGwKCQkJICogd2FpdCBmb3IgdGhlICdtYXN0ZXInIGJpby4KCQkJICovCgkJCXNldF9iaXQoUjFCSU9fVXB0b2RhdGUsICZyMV9iaW8tPnN0YXRlKTsKCgkJdXBkYXRlX2hlYWRfcG9zKG1pcnJvciwgcjFfYmlvKTsKCgkJaWYgKGJlaGluZCkgewoJCQlpZiAodGVzdF9iaXQoV3JpdGVNb3N0bHksICZjb25mLT5taXJyb3JzW21pcnJvcl0ucmRldi0+ZmxhZ3MpKQoJCQkJYXRvbWljX2RlYygmcjFfYmlvLT5iZWhpbmRfcmVtYWluaW5nKTsKCgkJCS8qIEluIGJlaGluZCBtb2RlLCB3ZSBBQ0sgdGhlIG1hc3RlciBiaW8gb25jZSB0aGUgSS9PIGhhcyBzYWZlbHkKCQkJICogcmVhY2hlZCBhbGwgbm9uLXdyaXRlbW9zdGx5IGRpc2tzLiBTZXR0aW5nIHRoZSBSZXR1cm5lZCBiaXQKCQkJICogZW5zdXJlcyB0aGF0IHRoaXMgZ2V0cyBkb25lIG9ubHkgb25jZSAtLSB3ZSBkb24ndCBldmVyIHdhbnQgdG8KCQkJICogcmV0dXJuIC1FSU8gaGVyZSwgaW5zdGVhZCB3ZSdsbCB3YWl0ICovCgoJCQlpZiAoYXRvbWljX3JlYWQoJnIxX2Jpby0+YmVoaW5kX3JlbWFpbmluZykgPj0gKGF0b21pY19yZWFkKCZyMV9iaW8tPnJlbWFpbmluZyktMSkgJiYKCQkJICAgIHRlc3RfYml0KFIxQklPX1VwdG9kYXRlLCAmcjFfYmlvLT5zdGF0ZSkpIHsKCQkJCS8qIE1heWJlIHdlIGNhbiByZXR1cm4gbm93ICovCgkJCQlpZiAoIXRlc3RfYW5kX3NldF9iaXQoUjFCSU9fUmV0dXJuZWQsICZyMV9iaW8tPnN0YXRlKSkgewoJCQkJCXN0cnVjdCBiaW8gKm1iaW8gPSByMV9iaW8tPm1hc3Rlcl9iaW87CgkJCQkJUFJJTlRLKEtFUk5fREVCVUcgInJhaWQxOiBiZWhpbmQgZW5kIHdyaXRlIHNlY3RvcnMgJWxsdS0lbGx1XG4iLAoJCQkJCSAgICAgICAodW5zaWduZWQgbG9uZyBsb25nKSBtYmlvLT5iaV9zZWN0b3IsCgkJCQkJICAgICAgICh1bnNpZ25lZCBsb25nIGxvbmcpIG1iaW8tPmJpX3NlY3RvciArCgkJCQkJICAgICAgIChtYmlvLT5iaV9zaXplID4+IDkpIC0gMSk7CgkJCQkJYmlvX2VuZGlvKG1iaW8sIDApOwoJCQkJfQoJCQl9CgkJfQoJCXJkZXZfZGVjX3BlbmRpbmcoY29uZi0+bWlycm9yc1ttaXJyb3JdLnJkZXYsIGNvbmYtPm1kZGV2KTsKCX0KCS8qCgkgKgoJICogTGV0J3Mgc2VlIGlmIGFsbCBtaXJyb3JlZCB3cml0ZSBvcGVyYXRpb25zIGhhdmUgZmluaXNoZWQKCSAqIGFscmVhZHkuCgkgKi8KCWlmIChhdG9taWNfZGVjX2FuZF90ZXN0KCZyMV9iaW8tPnJlbWFpbmluZykpIHsKCQlpZiAodGVzdF9iaXQoUjFCSU9fQmFycmllclJldHJ5LCAmcjFfYmlvLT5zdGF0ZSkpCgkJCXJlc2NoZWR1bGVfcmV0cnkocjFfYmlvKTsKCQllbHNlIHsKCQkJLyogaXQgcmVhbGx5IGlzIHRoZSBlbmQgb2YgdGhpcyByZXF1ZXN0ICovCgkJCWlmICh0ZXN0X2JpdChSMUJJT19CZWhpbmRJTywgJnIxX2Jpby0+c3RhdGUpKSB7CgkJCQkvKiBmcmVlIGV4dHJhIGNvcHkgb2YgdGhlIGRhdGEgcGFnZXMgKi8KCQkJCWludCBpID0gYmlvLT5iaV92Y250OwoJCQkJd2hpbGUgKGktLSkKCQkJCQlzYWZlX3B1dF9wYWdlKGJpby0+YmlfaW9fdmVjW2ldLmJ2X3BhZ2UpOwoJCQl9CgkJCS8qIGNsZWFyIHRoZSBiaXRtYXAgaWYgYWxsIHdyaXRlcyBjb21wbGV0ZSBzdWNjZXNzZnVsbHkgKi8KCQkJYml0bWFwX2VuZHdyaXRlKHIxX2Jpby0+bWRkZXYtPmJpdG1hcCwgcjFfYmlvLT5zZWN0b3IsCgkJCQkJcjFfYmlvLT5zZWN0b3JzLAoJCQkJCSF0ZXN0X2JpdChSMUJJT19EZWdyYWRlZCwgJnIxX2Jpby0+c3RhdGUpLAoJCQkJCWJlaGluZCk7CgkJCW1kX3dyaXRlX2VuZChyMV9iaW8tPm1kZGV2KTsKCQkJcmFpZF9lbmRfYmlvX2lvKHIxX2Jpbyk7CgkJfQoJfQoKCWlmICh0b19wdXQpCgkJYmlvX3B1dCh0b19wdXQpOwp9CgoKLyoKICogVGhpcyByb3V0aW5lIHJldHVybnMgdGhlIGRpc2sgZnJvbSB3aGljaCB0aGUgcmVxdWVzdGVkIHJlYWQgc2hvdWxkCiAqIGJlIGRvbmUuIFRoZXJlIGlzIGEgcGVyLWFycmF5ICduZXh0IGV4cGVjdGVkIHNlcXVlbnRpYWwgSU8nIHNlY3RvcgogKiBudW1iZXIgLSBpZiB0aGlzIG1hdGNoZXMgb24gdGhlIG5leHQgSU8gdGhlbiB3ZSB1c2UgdGhlIGxhc3QgZGlzay4KICogVGhlcmUgaXMgYWxzbyBhIHBlci1kaXNrICdsYXN0IGtub3cgaGVhZCBwb3NpdGlvbicgc2VjdG9yIHRoYXQgaXMKICogbWFpbnRhaW5lZCBmcm9tIElSUSBjb250ZXh0cywgYm90aCB0aGUgbm9ybWFsIGFuZCB0aGUgcmVzeW5jIElPCiAqIGNvbXBsZXRpb24gaGFuZGxlcnMgdXBkYXRlIHRoaXMgcG9zaXRpb24gY29ycmVjdGx5LiBJZiB0aGVyZSBpcyBubwogKiBwZXJmZWN0IHNlcXVlbnRpYWwgbWF0Y2ggdGhlbiB3ZSBwaWNrIHRoZSBkaXNrIHdob3NlIGhlYWQgaXMgY2xvc2VzdC4KICoKICogSWYgdGhlcmUgYXJlIDIgbWlycm9ycyBpbiB0aGUgc2FtZSAyIGRldmljZXMsIHBlcmZvcm1hbmNlIGRlZ3JhZGVzCiAqIGJlY2F1c2UgcG9zaXRpb24gaXMgbWlycm9yLCBub3QgZGV2aWNlIGJhc2VkLgogKgogKiBUaGUgcmRldiBmb3IgdGhlIGRldmljZSBzZWxlY3RlZCB3aWxsIGhhdmUgbnJfcGVuZGluZyBpbmNyZW1lbnRlZC4KICovCnN0YXRpYyBpbnQgcmVhZF9iYWxhbmNlKGNvbmZfdCAqY29uZiwgcjFiaW9fdCAqcjFfYmlvKQp7Cgljb25zdCB1bnNpZ25lZCBsb25nIHRoaXNfc2VjdG9yID0gcjFfYmlvLT5zZWN0b3I7CglpbnQgbmV3X2Rpc2sgPSBjb25mLT5sYXN0X3VzZWQsIGRpc2sgPSBuZXdfZGlzazsKCWludCB3b25seV9kaXNrID0gLTE7Cgljb25zdCBpbnQgc2VjdG9ycyA9IHIxX2Jpby0+c2VjdG9yczsKCXNlY3Rvcl90IG5ld19kaXN0YW5jZSwgY3VycmVudF9kaXN0YW5jZTsKCW1ka19yZGV2X3QgKnJkZXY7CgoJcmN1X3JlYWRfbG9jaygpOwoJLyoKCSAqIENoZWNrIGlmIHdlIGNhbiBiYWxhbmNlLiBXZSBjYW4gYmFsYW5jZSBvbiB0aGUgd2hvbGUKCSAqIGRldmljZSBpZiBubyByZXN5bmMgaXMgZ29pbmcgb24sIG9yIGJlbG93IHRoZSByZXN5bmMgd2luZG93LgoJICogV2UgdGFrZSB0aGUgZmlyc3QgcmVhZGFibGUgZGlzayB3aGVuIGFib3ZlIHRoZSByZXN5bmMgd2luZG93LgoJICovCiByZXRyeToKCWlmIChjb25mLT5tZGRldi0+cmVjb3ZlcnlfY3AgPCBNYXhTZWN0b3IgJiYKCSAgICAodGhpc19zZWN0b3IgKyBzZWN0b3JzID49IGNvbmYtPm5leHRfcmVzeW5jKSkgewoJCS8qIENob29zZSB0aGUgZmlyc3Qgb3BlcmF0aW9uIGRldmljZSwgZm9yIGNvbnNpc3RhbmN5ICovCgkJbmV3X2Rpc2sgPSAwOwoKCQlmb3IgKHJkZXYgPSByY3VfZGVyZWZlcmVuY2UoY29uZi0+bWlycm9yc1tuZXdfZGlza10ucmRldik7CgkJICAgICByMV9iaW8tPmJpb3NbbmV3X2Rpc2tdID09IElPX0JMT0NLRUQgfHwKCQkgICAgICFyZGV2IHx8ICF0ZXN0X2JpdChJbl9zeW5jLCAmcmRldi0+ZmxhZ3MpCgkJCSAgICAgfHwgdGVzdF9iaXQoV3JpdGVNb3N0bHksICZyZGV2LT5mbGFncyk7CgkJICAgICByZGV2ID0gcmN1X2RlcmVmZXJlbmNlKGNvbmYtPm1pcnJvcnNbKytuZXdfZGlza10ucmRldikpIHsKCgkJCWlmIChyZGV2ICYmIHRlc3RfYml0KEluX3N5bmMsICZyZGV2LT5mbGFncykgJiYKCQkJCXIxX2Jpby0+Ymlvc1tuZXdfZGlza10gIT0gSU9fQkxPQ0tFRCkKCQkJCXdvbmx5X2Rpc2sgPSBuZXdfZGlzazsKCgkJCWlmIChuZXdfZGlzayA9PSBjb25mLT5yYWlkX2Rpc2tzIC0gMSkgewoJCQkJbmV3X2Rpc2sgPSB3b25seV9kaXNrOwoJCQkJYnJlYWs7CgkJCX0KCQl9CgkJZ290byByYl9vdXQ7Cgl9CgoKCS8qIG1ha2Ugc3VyZSB0aGUgZGlzayBpcyBvcGVyYXRpb25hbCAqLwoJZm9yIChyZGV2ID0gcmN1X2RlcmVmZXJlbmNlKGNvbmYtPm1pcnJvcnNbbmV3X2Rpc2tdLnJkZXYpOwoJICAgICByMV9iaW8tPmJpb3NbbmV3X2Rpc2tdID09IElPX0JMT0NLRUQgfHwKCSAgICAgIXJkZXYgfHwgIXRlc3RfYml0KEluX3N5bmMsICZyZGV2LT5mbGFncykgfHwKCQkgICAgIHRlc3RfYml0KFdyaXRlTW9zdGx5LCAmcmRldi0+ZmxhZ3MpOwoJICAgICByZGV2ID0gcmN1X2RlcmVmZXJlbmNlKGNvbmYtPm1pcnJvcnNbbmV3X2Rpc2tdLnJkZXYpKSB7CgoJCWlmIChyZGV2ICYmIHRlc3RfYml0KEluX3N5bmMsICZyZGV2LT5mbGFncykgJiYKCQkgICAgcjFfYmlvLT5iaW9zW25ld19kaXNrXSAhPSBJT19CTE9DS0VEKQoJCQl3b25seV9kaXNrID0gbmV3X2Rpc2s7CgoJCWlmIChuZXdfZGlzayA8PSAwKQoJCQluZXdfZGlzayA9IGNvbmYtPnJhaWRfZGlza3M7CgkJbmV3X2Rpc2stLTsKCQlpZiAobmV3X2Rpc2sgPT0gZGlzaykgewoJCQluZXdfZGlzayA9IHdvbmx5X2Rpc2s7CgkJCWJyZWFrOwoJCX0KCX0KCglpZiAobmV3X2Rpc2sgPCAwKQoJCWdvdG8gcmJfb3V0OwoKCWRpc2sgPSBuZXdfZGlzazsKCS8qIG5vdyBkaXNrID09IG5ld19kaXNrID09IHN0YXJ0aW5nIHBvaW50IGZvciBzZWFyY2ggKi8KCgkvKgoJICogRG9uJ3QgY2hhbmdlIHRvIGFub3RoZXIgZGlzayBmb3Igc2VxdWVudGlhbCByZWFkczoKCSAqLwoJaWYgKGNvbmYtPm5leHRfc2VxX3NlY3QgPT0gdGhpc19zZWN0b3IpCgkJZ290byByYl9vdXQ7CglpZiAodGhpc19zZWN0b3IgPT0gY29uZi0+bWlycm9yc1tuZXdfZGlza10uaGVhZF9wb3NpdGlvbikKCQlnb3RvIHJiX291dDsKCgljdXJyZW50X2Rpc3RhbmNlID0gYWJzKHRoaXNfc2VjdG9yIC0gY29uZi0+bWlycm9yc1tkaXNrXS5oZWFkX3Bvc2l0aW9uKTsKCgkvKiBGaW5kIHRoZSBkaXNrIHdob3NlIGhlYWQgaXMgY2xvc2VzdCAqLwoKCWRvIHsKCQlpZiAoZGlzayA8PSAwKQoJCQlkaXNrID0gY29uZi0+cmFpZF9kaXNrczsKCQlkaXNrLS07CgoJCXJkZXYgPSByY3VfZGVyZWZlcmVuY2UoY29uZi0+bWlycm9yc1tkaXNrXS5yZGV2KTsKCgkJaWYgKCFyZGV2IHx8IHIxX2Jpby0+Ymlvc1tkaXNrXSA9PSBJT19CTE9DS0VEIHx8CgkJICAgICF0ZXN0X2JpdChJbl9zeW5jLCAmcmRldi0+ZmxhZ3MpIHx8CgkJICAgIHRlc3RfYml0KFdyaXRlTW9zdGx5LCAmcmRldi0+ZmxhZ3MpKQoJCQljb250aW51ZTsKCgkJaWYgKCFhdG9taWNfcmVhZCgmcmRldi0+bnJfcGVuZGluZykpIHsKCQkJbmV3X2Rpc2sgPSBkaXNrOwoJCQlicmVhazsKCQl9CgkJbmV3X2Rpc3RhbmNlID0gYWJzKHRoaXNfc2VjdG9yIC0gY29uZi0+bWlycm9yc1tkaXNrXS5oZWFkX3Bvc2l0aW9uKTsKCQlpZiAobmV3X2Rpc3RhbmNlIDwgY3VycmVudF9kaXN0YW5jZSkgewoJCQljdXJyZW50X2Rpc3RhbmNlID0gbmV3X2Rpc3RhbmNlOwoJCQluZXdfZGlzayA9IGRpc2s7CgkJfQoJfSB3aGlsZSAoZGlzayAhPSBjb25mLT5sYXN0X3VzZWQpOwoKIHJiX291dDoKCgoJaWYgKG5ld19kaXNrID49IDApIHsKCQlyZGV2ID0gcmN1X2RlcmVmZXJlbmNlKGNvbmYtPm1pcnJvcnNbbmV3X2Rpc2tdLnJkZXYpOwoJCWlmICghcmRldikKCQkJZ290byByZXRyeTsKCQlhdG9taWNfaW5jKCZyZGV2LT5ucl9wZW5kaW5nKTsKCQlpZiAoIXRlc3RfYml0KEluX3N5bmMsICZyZGV2LT5mbGFncykpIHsKCQkJLyogY2Fubm90IHJpc2sgcmV0dXJuaW5nIGEgZGV2aWNlIHRoYXQgZmFpbGVkCgkJCSAqIGJlZm9yZSB3ZSBpbmMnZWQgbnJfcGVuZGluZwoJCQkgKi8KCQkJcmRldl9kZWNfcGVuZGluZyhyZGV2LCBjb25mLT5tZGRldik7CgkJCWdvdG8gcmV0cnk7CgkJfQoJCWNvbmYtPm5leHRfc2VxX3NlY3QgPSB0aGlzX3NlY3RvciArIHNlY3RvcnM7CgkJY29uZi0+bGFzdF91c2VkID0gbmV3X2Rpc2s7Cgl9CglyY3VfcmVhZF91bmxvY2soKTsKCglyZXR1cm4gbmV3X2Rpc2s7Cn0KCnN0YXRpYyB2b2lkIHVucGx1Z19zbGF2ZXMobWRkZXZfdCAqbWRkZXYpCnsKCWNvbmZfdCAqY29uZiA9IG1kZGV2X3RvX2NvbmYobWRkZXYpOwoJaW50IGk7CgoJcmN1X3JlYWRfbG9jaygpOwoJZm9yIChpPTA7IGk8bWRkZXYtPnJhaWRfZGlza3M7IGkrKykgewoJCW1ka19yZGV2X3QgKnJkZXYgPSByY3VfZGVyZWZlcmVuY2UoY29uZi0+bWlycm9yc1tpXS5yZGV2KTsKCQlpZiAocmRldiAmJiAhdGVzdF9iaXQoRmF1bHR5LCAmcmRldi0+ZmxhZ3MpICYmIGF0b21pY19yZWFkKCZyZGV2LT5ucl9wZW5kaW5nKSkgewoJCQlzdHJ1Y3QgcmVxdWVzdF9xdWV1ZSAqcl9xdWV1ZSA9IGJkZXZfZ2V0X3F1ZXVlKHJkZXYtPmJkZXYpOwoKCQkJYXRvbWljX2luYygmcmRldi0+bnJfcGVuZGluZyk7CgkJCXJjdV9yZWFkX3VubG9jaygpOwoKCQkJaWYgKHJfcXVldWUtPnVucGx1Z19mbikKCQkJCXJfcXVldWUtPnVucGx1Z19mbihyX3F1ZXVlKTsKCgkJCXJkZXZfZGVjX3BlbmRpbmcocmRldiwgbWRkZXYpOwoJCQlyY3VfcmVhZF9sb2NrKCk7CgkJfQoJfQoJcmN1X3JlYWRfdW5sb2NrKCk7Cn0KCnN0YXRpYyB2b2lkIHJhaWQxX3VucGx1ZyhzdHJ1Y3QgcmVxdWVzdF9xdWV1ZSAqcSkKewoJbWRkZXZfdCAqbWRkZXYgPSBxLT5xdWV1ZWRhdGE7CgoJdW5wbHVnX3NsYXZlcyhtZGRldik7CgltZF93YWtldXBfdGhyZWFkKG1kZGV2LT50aHJlYWQpOwp9CgpzdGF0aWMgaW50IHJhaWQxX2Nvbmdlc3RlZCh2b2lkICpkYXRhLCBpbnQgYml0cykKewoJbWRkZXZfdCAqbWRkZXYgPSBkYXRhOwoJY29uZl90ICpjb25mID0gbWRkZXZfdG9fY29uZihtZGRldik7CglpbnQgaSwgcmV0ID0gMDsKCglyY3VfcmVhZF9sb2NrKCk7Cglmb3IgKGkgPSAwOyBpIDwgbWRkZXYtPnJhaWRfZGlza3M7IGkrKykgewoJCW1ka19yZGV2X3QgKnJkZXYgPSByY3VfZGVyZWZlcmVuY2UoY29uZi0+bWlycm9yc1tpXS5yZGV2KTsKCQlpZiAocmRldiAmJiAhdGVzdF9iaXQoRmF1bHR5LCAmcmRldi0+ZmxhZ3MpKSB7CgkJCXN0cnVjdCByZXF1ZXN0X3F1ZXVlICpxID0gYmRldl9nZXRfcXVldWUocmRldi0+YmRldik7CgoJCQkvKiBOb3RlIHRoZSAnfHwgMScgLSB3aGVuIHJlYWRfYmFsYW5jZSBwcmVmZXJzCgkJCSAqIG5vbi1jb25nZXN0ZWQgdGFyZ2V0cywgaXQgY2FuIGJlIHJlbW92ZWQKCQkJICovCgkJCWlmICgoYml0cyAmICgxPDxCRElfd3JpdGVfY29uZ2VzdGVkKSkgfHwgMSkKCQkJCXJldCB8PSBiZGlfY29uZ2VzdGVkKCZxLT5iYWNraW5nX2Rldl9pbmZvLCBiaXRzKTsKCQkJZWxzZQoJCQkJcmV0ICY9IGJkaV9jb25nZXN0ZWQoJnEtPmJhY2tpbmdfZGV2X2luZm8sIGJpdHMpOwoJCX0KCX0KCXJjdV9yZWFkX3VubG9jaygpOwoJcmV0dXJuIHJldDsKfQoKCi8qIEJhcnJpZXJzLi4uLgogKiBTb21ldGltZXMgd2UgbmVlZCB0byBzdXNwZW5kIElPIHdoaWxlIHdlIGRvIHNvbWV0aGluZyBlbHNlLAogKiBlaXRoZXIgc29tZSByZXN5bmMvcmVjb3ZlcnksIG9yIHJlY29uZmlndXJlIHRoZSBhcnJheS4KICogVG8gZG8gdGhpcyB3ZSByYWlzZSBhICdiYXJyaWVyJy4KICogVGhlICdiYXJyaWVyJyBpcyBhIGNvdW50ZXIgdGhhdCBjYW4gYmUgcmFpc2VkIG11bHRpcGxlIHRpbWVzCiAqIHRvIGNvdW50IGhvdyBtYW55IGFjdGl2aXRpZXMgYXJlIGhhcHBlbmluZyB3aGljaCBwcmVjbHVkZQogKiBub3JtYWwgSU8uCiAqIFdlIGNhbiBvbmx5IHJhaXNlIHRoZSBiYXJyaWVyIGlmIHRoZXJlIGlzIG5vIHBlbmRpbmcgSU8uCiAqIGkuZS4gaWYgbnJfcGVuZGluZyA9PSAwLgogKiBXZSBjaG9vc2Ugb25seSB0byByYWlzZSB0aGUgYmFycmllciBpZiBuby1vbmUgaXMgd2FpdGluZyBmb3IgdGhlCiAqIGJhcnJpZXIgdG8gZ28gZG93bi4gIFRoaXMgbWVhbnMgdGhhdCBhcyBzb29uIGFzIGFuIElPIHJlcXVlc3QKICogaXMgcmVhZHksIG5vIG90aGVyIG9wZXJhdGlvbnMgd2hpY2ggcmVxdWlyZSBhIGJhcnJpZXIgd2lsbCBzdGFydAogKiB1bnRpbCB0aGUgSU8gcmVxdWVzdCBoYXMgaGFkIGEgY2hhbmNlLgogKgogKiBTbzogcmVndWxhciBJTyBjYWxscyAnd2FpdF9iYXJyaWVyJy4gIFdoZW4gdGhhdCByZXR1cm5zIHRoZXJlCiAqICAgIGlzIG5vIGJhY2tncm91cCBJTyBoYXBwZW5pbmcsICBJdCBtdXN0IGFycmFuZ2UgdG8gY2FsbAogKiAgICBhbGxvd19iYXJyaWVyIHdoZW4gaXQgaGFzIGZpbmlzaGVkIGl0cyBJTy4KICogYmFja2dyb3VwIElPIGNhbGxzIG11c3QgY2FsbCByYWlzZV9iYXJyaWVyLiAgT25jZSB0aGF0IHJldHVybnMKICogICAgdGhlcmUgaXMgbm8gbm9ybWFsIElPIGhhcHBlaW5nLiAgSXQgbXVzdCBhcnJhbmdlIHRvIGNhbGwKICogICAgbG93ZXJfYmFycmllciB3aGVuIHRoZSBwYXJ0aWN1bGFyIGJhY2tncm91bmQgSU8gY29tcGxldGVzLgogKi8KI2RlZmluZSBSRVNZTkNfREVQVEggMzIKCnN0YXRpYyB2b2lkIHJhaXNlX2JhcnJpZXIoY29uZl90ICpjb25mKQp7CglzcGluX2xvY2tfaXJxKCZjb25mLT5yZXN5bmNfbG9jayk7CgoJLyogV2FpdCB1bnRpbCBubyBibG9jayBJTyBpcyB3YWl0aW5nICovCgl3YWl0X2V2ZW50X2xvY2tfaXJxKGNvbmYtPndhaXRfYmFycmllciwgIWNvbmYtPm5yX3dhaXRpbmcsCgkJCSAgICBjb25mLT5yZXN5bmNfbG9jaywKCQkJICAgIHJhaWQxX3VucGx1Zyhjb25mLT5tZGRldi0+cXVldWUpKTsKCgkvKiBibG9jayBhbnkgbmV3IElPIGZyb20gc3RhcnRpbmcgKi8KCWNvbmYtPmJhcnJpZXIrKzsKCgkvKiBObyB3YWl0IGZvciBhbGwgcGVuZGluZyBJTyB0byBjb21wbGV0ZSAqLwoJd2FpdF9ldmVudF9sb2NrX2lycShjb25mLT53YWl0X2JhcnJpZXIsCgkJCSAgICAhY29uZi0+bnJfcGVuZGluZyAmJiBjb25mLT5iYXJyaWVyIDwgUkVTWU5DX0RFUFRILAoJCQkgICAgY29uZi0+cmVzeW5jX2xvY2ssCgkJCSAgICByYWlkMV91bnBsdWcoY29uZi0+bWRkZXYtPnF1ZXVlKSk7CgoJc3Bpbl91bmxvY2tfaXJxKCZjb25mLT5yZXN5bmNfbG9jayk7Cn0KCnN0YXRpYyB2b2lkIGxvd2VyX2JhcnJpZXIoY29uZl90ICpjb25mKQp7Cgl1bnNpZ25lZCBsb25nIGZsYWdzOwoJc3Bpbl9sb2NrX2lycXNhdmUoJmNvbmYtPnJlc3luY19sb2NrLCBmbGFncyk7Cgljb25mLT5iYXJyaWVyLS07CglzcGluX3VubG9ja19pcnFyZXN0b3JlKCZjb25mLT5yZXN5bmNfbG9jaywgZmxhZ3MpOwoJd2FrZV91cCgmY29uZi0+d2FpdF9iYXJyaWVyKTsKfQoKc3RhdGljIHZvaWQgd2FpdF9iYXJyaWVyKGNvbmZfdCAqY29uZikKewoJc3Bpbl9sb2NrX2lycSgmY29uZi0+cmVzeW5jX2xvY2spOwoJaWYgKGNvbmYtPmJhcnJpZXIpIHsKCQljb25mLT5ucl93YWl0aW5nKys7CgkJd2FpdF9ldmVudF9sb2NrX2lycShjb25mLT53YWl0X2JhcnJpZXIsICFjb25mLT5iYXJyaWVyLAoJCQkJICAgIGNvbmYtPnJlc3luY19sb2NrLAoJCQkJICAgIHJhaWQxX3VucGx1Zyhjb25mLT5tZGRldi0+cXVldWUpKTsKCQljb25mLT5ucl93YWl0aW5nLS07Cgl9Cgljb25mLT5ucl9wZW5kaW5nKys7CglzcGluX3VubG9ja19pcnEoJmNvbmYtPnJlc3luY19sb2NrKTsKfQoKc3RhdGljIHZvaWQgYWxsb3dfYmFycmllcihjb25mX3QgKmNvbmYpCnsKCXVuc2lnbmVkIGxvbmcgZmxhZ3M7CglzcGluX2xvY2tfaXJxc2F2ZSgmY29uZi0+cmVzeW5jX2xvY2ssIGZsYWdzKTsKCWNvbmYtPm5yX3BlbmRpbmctLTsKCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJmNvbmYtPnJlc3luY19sb2NrLCBmbGFncyk7Cgl3YWtlX3VwKCZjb25mLT53YWl0X2JhcnJpZXIpOwp9CgpzdGF0aWMgdm9pZCBmcmVlemVfYXJyYXkoY29uZl90ICpjb25mKQp7CgkvKiBzdG9wIHN5bmNpbyBhbmQgbm9ybWFsIElPIGFuZCB3YWl0IGZvciBldmVyeXRoaW5nIHRvCgkgKiBnbyBxdWl0ZS4KCSAqIFdlIGluY3JlbWVudCBiYXJyaWVyIGFuZCBucl93YWl0aW5nLCBhbmQgdGhlbgoJICogd2FpdCB1bnRpbCBiYXJyaWVyK25yX3BlbmRpbmcgbWF0Y2ggbnJfcXVldWVkKzIKCSAqLwoJc3Bpbl9sb2NrX2lycSgmY29uZi0+cmVzeW5jX2xvY2spOwoJY29uZi0+YmFycmllcisrOwoJY29uZi0+bnJfd2FpdGluZysrOwoJd2FpdF9ldmVudF9sb2NrX2lycShjb25mLT53YWl0X2JhcnJpZXIsCgkJCSAgICBjb25mLT5iYXJyaWVyK2NvbmYtPm5yX3BlbmRpbmcgPT0gY29uZi0+bnJfcXVldWVkKzIsCgkJCSAgICBjb25mLT5yZXN5bmNfbG9jaywKCQkJICAgIHJhaWQxX3VucGx1Zyhjb25mLT5tZGRldi0+cXVldWUpKTsKCXNwaW5fdW5sb2NrX2lycSgmY29uZi0+cmVzeW5jX2xvY2spOwp9CnN0YXRpYyB2b2lkIHVuZnJlZXplX2FycmF5KGNvbmZfdCAqY29uZikKewoJLyogcmV2ZXJzZSB0aGUgZWZmZWN0IG9mIHRoZSBmcmVlemUgKi8KCXNwaW5fbG9ja19pcnEoJmNvbmYtPnJlc3luY19sb2NrKTsKCWNvbmYtPmJhcnJpZXItLTsKCWNvbmYtPm5yX3dhaXRpbmctLTsKCXdha2VfdXAoJmNvbmYtPndhaXRfYmFycmllcik7CglzcGluX3VubG9ja19pcnEoJmNvbmYtPnJlc3luY19sb2NrKTsKfQoKCi8qIGR1cGxpY2F0ZSB0aGUgZGF0YSBwYWdlcyBmb3IgYmVoaW5kIEkvTyAqLwpzdGF0aWMgc3RydWN0IHBhZ2UgKiphbGxvY19iZWhpbmRfcGFnZXMoc3RydWN0IGJpbyAqYmlvKQp7CglpbnQgaTsKCXN0cnVjdCBiaW9fdmVjICpidmVjOwoJc3RydWN0IHBhZ2UgKipwYWdlcyA9IGt6YWxsb2MoYmlvLT5iaV92Y250ICogc2l6ZW9mKHN0cnVjdCBwYWdlICopLAoJCQkJCUdGUF9OT0lPKTsKCWlmICh1bmxpa2VseSghcGFnZXMpKQoJCWdvdG8gZG9fc3luY19pbzsKCgliaW9fZm9yX2VhY2hfc2VnbWVudChidmVjLCBiaW8sIGkpIHsKCQlwYWdlc1tpXSA9IGFsbG9jX3BhZ2UoR0ZQX05PSU8pOwoJCWlmICh1bmxpa2VseSghcGFnZXNbaV0pKQoJCQlnb3RvIGRvX3N5bmNfaW87CgkJbWVtY3B5KGttYXAocGFnZXNbaV0pICsgYnZlYy0+YnZfb2Zmc2V0LAoJCQlrbWFwKGJ2ZWMtPmJ2X3BhZ2UpICsgYnZlYy0+YnZfb2Zmc2V0LCBidmVjLT5idl9sZW4pOwoJCWt1bm1hcChwYWdlc1tpXSk7CgkJa3VubWFwKGJ2ZWMtPmJ2X3BhZ2UpOwoJfQoKCXJldHVybiBwYWdlczsKCmRvX3N5bmNfaW86CglpZiAocGFnZXMpCgkJZm9yIChpID0gMDsgaSA8IGJpby0+YmlfdmNudCAmJiBwYWdlc1tpXTsgaSsrKQoJCQlwdXRfcGFnZShwYWdlc1tpXSk7CglrZnJlZShwYWdlcyk7CglQUklOVEsoIiVkQiBiZWhpbmQgYWxsb2MgZmFpbGVkLCBkb2luZyBzeW5jIEkvT1xuIiwgYmlvLT5iaV9zaXplKTsKCXJldHVybiBOVUxMOwp9CgpzdGF0aWMgaW50IG1ha2VfcmVxdWVzdChzdHJ1Y3QgcmVxdWVzdF9xdWV1ZSAqcSwgc3RydWN0IGJpbyAqIGJpbykKewoJbWRkZXZfdCAqbWRkZXYgPSBxLT5xdWV1ZWRhdGE7Cgljb25mX3QgKmNvbmYgPSBtZGRldl90b19jb25mKG1kZGV2KTsKCW1pcnJvcl9pbmZvX3QgKm1pcnJvcjsKCXIxYmlvX3QgKnIxX2JpbzsKCXN0cnVjdCBiaW8gKnJlYWRfYmlvOwoJaW50IGksIHRhcmdldHMgPSAwLCBkaXNrczsKCW1ka19yZGV2X3QgKnJkZXY7CglzdHJ1Y3QgYml0bWFwICpiaXRtYXAgPSBtZGRldi0+Yml0bWFwOwoJdW5zaWduZWQgbG9uZyBmbGFnczsKCXN0cnVjdCBiaW9fbGlzdCBibDsKCXN0cnVjdCBwYWdlICoqYmVoaW5kX3BhZ2VzID0gTlVMTDsKCWNvbnN0IGludCBydyA9IGJpb19kYXRhX2RpcihiaW8pOwoJY29uc3QgaW50IGRvX3N5bmMgPSBiaW9fc3luYyhiaW8pOwoJaW50IGRvX2JhcnJpZXJzOwoKCS8qCgkgKiBSZWdpc3RlciB0aGUgbmV3IHJlcXVlc3QgYW5kIHdhaXQgaWYgdGhlIHJlY29uc3RydWN0aW9uCgkgKiB0aHJlYWQgaGFzIHB1dCB1cCBhIGJhciBmb3IgbmV3IHJlcXVlc3RzLgoJICogQ29udGludWUgaW1tZWRpYXRlbHkgaWYgbm8gcmVzeW5jIGlzIGFjdGl2ZSBjdXJyZW50bHkuCgkgKiBXZSB0ZXN0IGJhcnJpZXJzX3dvcmsgKmFmdGVyKiBtZF93cml0ZV9zdGFydCBhcyBtZF93cml0ZV9zdGFydAoJICogbWF5IGNhdXNlIHRoZSBmaXJzdCBzdXBlcmJsb2NrIHdyaXRlLCBhbmQgdGhhdCB3aWxsIGNoZWNrIG91dAoJICogaWYgYmFycmllcnMgd29yay4KCSAqLwoKCW1kX3dyaXRlX3N0YXJ0KG1kZGV2LCBiaW8pOyAvKiB3YWl0IG9uIHN1cGVyYmxvY2sgdXBkYXRlIGVhcmx5ICovCgoJaWYgKHVubGlrZWx5KCFtZGRldi0+YmFycmllcnNfd29yayAmJiBiaW9fYmFycmllcihiaW8pKSkgewoJCWlmIChydyA9PSBXUklURSkKCQkJbWRfd3JpdGVfZW5kKG1kZGV2KTsKCQliaW9fZW5kaW8oYmlvLCAtRU9QTk9UU1VQUCk7CgkJcmV0dXJuIDA7Cgl9CgoJd2FpdF9iYXJyaWVyKGNvbmYpOwoKCWRpc2tfc3RhdF9pbmMobWRkZXYtPmdlbmRpc2ssIGlvc1tyd10pOwoJZGlza19zdGF0X2FkZChtZGRldi0+Z2VuZGlzaywgc2VjdG9yc1tyd10sIGJpb19zZWN0b3JzKGJpbykpOwoKCS8qCgkgKiBtYWtlX3JlcXVlc3QoKSBjYW4gYWJvcnQgdGhlIG9wZXJhdGlvbiB3aGVuIFJFQURBIGlzIGJlaW5nCgkgKiB1c2VkIGFuZCBubyBlbXB0eSByZXF1ZXN0IGlzIGF2YWlsYWJsZS4KCSAqCgkgKi8KCXIxX2JpbyA9IG1lbXBvb2xfYWxsb2MoY29uZi0+cjFiaW9fcG9vbCwgR0ZQX05PSU8pOwoKCXIxX2Jpby0+bWFzdGVyX2JpbyA9IGJpbzsKCXIxX2Jpby0+c2VjdG9ycyA9IGJpby0+Ymlfc2l6ZSA+PiA5OwoJcjFfYmlvLT5zdGF0ZSA9IDA7CglyMV9iaW8tPm1kZGV2ID0gbWRkZXY7CglyMV9iaW8tPnNlY3RvciA9IGJpby0+Ymlfc2VjdG9yOwoKCWlmIChydyA9PSBSRUFEKSB7CgkJLyoKCQkgKiByZWFkIGJhbGFuY2luZyBsb2dpYzoKCQkgKi8KCQlpbnQgcmRpc2sgPSByZWFkX2JhbGFuY2UoY29uZiwgcjFfYmlvKTsKCgkJaWYgKHJkaXNrIDwgMCkgewoJCQkvKiBjb3VsZG4ndCBmaW5kIGFueXdoZXJlIHRvIHJlYWQgZnJvbSAqLwoJCQlyYWlkX2VuZF9iaW9faW8ocjFfYmlvKTsKCQkJcmV0dXJuIDA7CgkJfQoJCW1pcnJvciA9IGNvbmYtPm1pcnJvcnMgKyByZGlzazsKCgkJcjFfYmlvLT5yZWFkX2Rpc2sgPSByZGlzazsKCgkJcmVhZF9iaW8gPSBiaW9fY2xvbmUoYmlvLCBHRlBfTk9JTyk7CgoJCXIxX2Jpby0+Ymlvc1tyZGlza10gPSByZWFkX2JpbzsKCgkJcmVhZF9iaW8tPmJpX3NlY3RvciA9IHIxX2Jpby0+c2VjdG9yICsgbWlycm9yLT5yZGV2LT5kYXRhX29mZnNldDsKCQlyZWFkX2Jpby0+YmlfYmRldiA9IG1pcnJvci0+cmRldi0+YmRldjsKCQlyZWFkX2Jpby0+YmlfZW5kX2lvID0gcmFpZDFfZW5kX3JlYWRfcmVxdWVzdDsKCQlyZWFkX2Jpby0+YmlfcncgPSBSRUFEIHwgZG9fc3luYzsKCQlyZWFkX2Jpby0+YmlfcHJpdmF0ZSA9IHIxX2JpbzsKCgkJZ2VuZXJpY19tYWtlX3JlcXVlc3QocmVhZF9iaW8pOwoJCXJldHVybiAwOwoJfQoKCS8qCgkgKiBXUklURToKCSAqLwoJLyogZmlyc3Qgc2VsZWN0IHRhcmdldCBkZXZpY2VzIHVuZGVyIHNwaW5sb2NrIGFuZAoJICogaW5jIHJlZmNvdW50IG9uIHRoZWlyIHJkZXYuICBSZWNvcmQgdGhlbSBieSBzZXR0aW5nCgkgKiBiaW9zW3hdIHRvIGJpbwoJICovCglkaXNrcyA9IGNvbmYtPnJhaWRfZGlza3M7CiNpZiAwCgl7IHN0YXRpYyBpbnQgZmlyc3Q9MTsKCWlmIChmaXJzdCkgcHJpbnRrKCJGaXJzdCBXcml0ZSBzZWN0b3IgJWxsdSBkaXNrcyAlZFxuIiwKCQkJICAodW5zaWduZWQgbG9uZyBsb25nKXIxX2Jpby0+c2VjdG9yLCBkaXNrcyk7CglmaXJzdCA9IDA7Cgl9CiNlbmRpZgoJcmN1X3JlYWRfbG9jaygpOwoJZm9yIChpID0gMDsgIGkgPCBkaXNrczsgaSsrKSB7CgkJaWYgKChyZGV2PXJjdV9kZXJlZmVyZW5jZShjb25mLT5taXJyb3JzW2ldLnJkZXYpKSAhPSBOVUxMICYmCgkJICAgICF0ZXN0X2JpdChGYXVsdHksICZyZGV2LT5mbGFncykpIHsKCQkJYXRvbWljX2luYygmcmRldi0+bnJfcGVuZGluZyk7CgkJCWlmICh0ZXN0X2JpdChGYXVsdHksICZyZGV2LT5mbGFncykpIHsKCQkJCXJkZXZfZGVjX3BlbmRpbmcocmRldiwgbWRkZXYpOwoJCQkJcjFfYmlvLT5iaW9zW2ldID0gTlVMTDsKCQkJfSBlbHNlCgkJCQlyMV9iaW8tPmJpb3NbaV0gPSBiaW87CgkJCXRhcmdldHMrKzsKCQl9IGVsc2UKCQkJcjFfYmlvLT5iaW9zW2ldID0gTlVMTDsKCX0KCXJjdV9yZWFkX3VubG9jaygpOwoKCUJVR19PTih0YXJnZXRzID09IDApOyAvKiB3ZSBuZXZlciBmYWlsIHRoZSBsYXN0IGRldmljZSAqLwoKCWlmICh0YXJnZXRzIDwgY29uZi0+cmFpZF9kaXNrcykgewoJCS8qIGFycmF5IGlzIGRlZ3JhZGVkLCB3ZSB3aWxsIG5vdCBjbGVhciB0aGUgYml0bWFwCgkJICogb24gSS9PIGNvbXBsZXRpb24gKHNlZSByYWlkMV9lbmRfd3JpdGVfcmVxdWVzdCkgKi8KCQlzZXRfYml0KFIxQklPX0RlZ3JhZGVkLCAmcjFfYmlvLT5zdGF0ZSk7Cgl9CgoJLyogZG8gYmVoaW5kIEkvTyA/ICovCglpZiAoYml0bWFwICYmCgkgICAgYXRvbWljX3JlYWQoJmJpdG1hcC0+YmVoaW5kX3dyaXRlcykgPCBiaXRtYXAtPm1heF93cml0ZV9iZWhpbmQgJiYKCSAgICAoYmVoaW5kX3BhZ2VzID0gYWxsb2NfYmVoaW5kX3BhZ2VzKGJpbykpICE9IE5VTEwpCgkJc2V0X2JpdChSMUJJT19CZWhpbmRJTywgJnIxX2Jpby0+c3RhdGUpOwoKCWF0b21pY19zZXQoJnIxX2Jpby0+cmVtYWluaW5nLCAwKTsKCWF0b21pY19zZXQoJnIxX2Jpby0+YmVoaW5kX3JlbWFpbmluZywgMCk7CgoJZG9fYmFycmllcnMgPSBiaW9fYmFycmllcihiaW8pOwoJaWYgKGRvX2JhcnJpZXJzKQoJCXNldF9iaXQoUjFCSU9fQmFycmllciwgJnIxX2Jpby0+c3RhdGUpOwoKCWJpb19saXN0X2luaXQoJmJsKTsKCWZvciAoaSA9IDA7IGkgPCBkaXNrczsgaSsrKSB7CgkJc3RydWN0IGJpbyAqbWJpbzsKCQlpZiAoIXIxX2Jpby0+Ymlvc1tpXSkKCQkJY29udGludWU7CgoJCW1iaW8gPSBiaW9fY2xvbmUoYmlvLCBHRlBfTk9JTyk7CgkJcjFfYmlvLT5iaW9zW2ldID0gbWJpbzsKCgkJbWJpby0+Ymlfc2VjdG9yCT0gcjFfYmlvLT5zZWN0b3IgKyBjb25mLT5taXJyb3JzW2ldLnJkZXYtPmRhdGFfb2Zmc2V0OwoJCW1iaW8tPmJpX2JkZXYgPSBjb25mLT5taXJyb3JzW2ldLnJkZXYtPmJkZXY7CgkJbWJpby0+YmlfZW5kX2lvCT0gcmFpZDFfZW5kX3dyaXRlX3JlcXVlc3Q7CgkJbWJpby0+YmlfcncgPSBXUklURSB8IGRvX2JhcnJpZXJzIHwgZG9fc3luYzsKCQltYmlvLT5iaV9wcml2YXRlID0gcjFfYmlvOwoKCQlpZiAoYmVoaW5kX3BhZ2VzKSB7CgkJCXN0cnVjdCBiaW9fdmVjICpidmVjOwoJCQlpbnQgajsKCgkJCS8qIFllcywgSSByZWFsbHkgd2FudCB0aGUgJ19fJyB2ZXJzaW9uIHNvIHRoYXQKCQkJICogd2UgY2xlYXIgYW55IHVudXNlZCBwb2ludGVyIGluIHRoZSBpb192ZWMsIHJhdGhlcgoJCQkgKiB0aGFuIGxlYXZlIHRoZW0gdW5jaGFuZ2VkLiAgVGhpcyBpcyBpbXBvcnRhbnQKCQkJICogYmVjYXVzZSB3aGVuIHdlIGNvbWUgdG8gZnJlZSB0aGUgcGFnZXMsIHdlIHdvbid0CgkJCSAqIGtub3cgdGhlIG9yaWdpbmlhbCBiaV9pZHgsIHNvIHdlIGp1c3QgZnJlZQoJCQkgKiB0aGVtIGFsbAoJCQkgKi8KCQkJX19iaW9fZm9yX2VhY2hfc2VnbWVudChidmVjLCBtYmlvLCBqLCAwKQoJCQkJYnZlYy0+YnZfcGFnZSA9IGJlaGluZF9wYWdlc1tqXTsKCQkJaWYgKHRlc3RfYml0KFdyaXRlTW9zdGx5LCAmY29uZi0+bWlycm9yc1tpXS5yZGV2LT5mbGFncykpCgkJCQlhdG9taWNfaW5jKCZyMV9iaW8tPmJlaGluZF9yZW1haW5pbmcpOwoJCX0KCgkJYXRvbWljX2luYygmcjFfYmlvLT5yZW1haW5pbmcpOwoKCQliaW9fbGlzdF9hZGQoJmJsLCBtYmlvKTsKCX0KCWtmcmVlKGJlaGluZF9wYWdlcyk7IC8qIHRoZSBiZWhpbmQgcGFnZXMgYXJlIGF0dGFjaGVkIHRvIHRoZSBiaW9zIG5vdyAqLwoKCWJpdG1hcF9zdGFydHdyaXRlKGJpdG1hcCwgYmlvLT5iaV9zZWN0b3IsIHIxX2Jpby0+c2VjdG9ycywKCQkJCXRlc3RfYml0KFIxQklPX0JlaGluZElPLCAmcjFfYmlvLT5zdGF0ZSkpOwoJc3Bpbl9sb2NrX2lycXNhdmUoJmNvbmYtPmRldmljZV9sb2NrLCBmbGFncyk7CgliaW9fbGlzdF9tZXJnZSgmY29uZi0+cGVuZGluZ19iaW9fbGlzdCwgJmJsKTsKCWJpb19saXN0X2luaXQoJmJsKTsKCglibGtfcGx1Z19kZXZpY2UobWRkZXYtPnF1ZXVlKTsKCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJmNvbmYtPmRldmljZV9sb2NrLCBmbGFncyk7CgoJaWYgKGRvX3N5bmMpCgkJbWRfd2FrZXVwX3RocmVhZChtZGRldi0+dGhyZWFkKTsKI2lmIDAKCXdoaWxlICgoYmlvID0gYmlvX2xpc3RfcG9wKCZibCkpICE9IE5VTEwpCgkJZ2VuZXJpY19tYWtlX3JlcXVlc3QoYmlvKTsKI2VuZGlmCgoJcmV0dXJuIDA7Cn0KCnN0YXRpYyB2b2lkIHN0YXR1cyhzdHJ1Y3Qgc2VxX2ZpbGUgKnNlcSwgbWRkZXZfdCAqbWRkZXYpCnsKCWNvbmZfdCAqY29uZiA9IG1kZGV2X3RvX2NvbmYobWRkZXYpOwoJaW50IGk7CgoJc2VxX3ByaW50ZihzZXEsICIgWyVkLyVkXSBbIiwgY29uZi0+cmFpZF9kaXNrcywKCQkgICBjb25mLT5yYWlkX2Rpc2tzIC0gbWRkZXYtPmRlZ3JhZGVkKTsKCXJjdV9yZWFkX2xvY2soKTsKCWZvciAoaSA9IDA7IGkgPCBjb25mLT5yYWlkX2Rpc2tzOyBpKyspIHsKCQltZGtfcmRldl90ICpyZGV2ID0gcmN1X2RlcmVmZXJlbmNlKGNvbmYtPm1pcnJvcnNbaV0ucmRldik7CgkJc2VxX3ByaW50ZihzZXEsICIlcyIsCgkJCSAgIHJkZXYgJiYgdGVzdF9iaXQoSW5fc3luYywgJnJkZXYtPmZsYWdzKSA/ICJVIiA6ICJfIik7Cgl9CglyY3VfcmVhZF91bmxvY2soKTsKCXNlcV9wcmludGYoc2VxLCAiXSIpOwp9CgoKc3RhdGljIHZvaWQgZXJyb3IobWRkZXZfdCAqbWRkZXYsIG1ka19yZGV2X3QgKnJkZXYpCnsKCWNoYXIgYltCREVWTkFNRV9TSVpFXTsKCWNvbmZfdCAqY29uZiA9IG1kZGV2X3RvX2NvbmYobWRkZXYpOwoKCS8qCgkgKiBJZiBpdCBpcyBub3Qgb3BlcmF0aW9uYWwsIHRoZW4gd2UgaGF2ZSBhbHJlYWR5IG1hcmtlZCBpdCBhcyBkZWFkCgkgKiBlbHNlIGlmIGl0IGlzIHRoZSBsYXN0IHdvcmtpbmcgZGlza3MsIGlnbm9yZSB0aGUgZXJyb3IsIGxldCB0aGUKCSAqIG5leHQgbGV2ZWwgdXAga25vdy4KCSAqIGVsc2UgbWFyayB0aGUgZHJpdmUgYXMgZmFpbGVkCgkgKi8KCWlmICh0ZXN0X2JpdChJbl9zeW5jLCAmcmRldi0+ZmxhZ3MpCgkgICAgJiYgKGNvbmYtPnJhaWRfZGlza3MgLSBtZGRldi0+ZGVncmFkZWQpID09IDEpCgkJLyoKCQkgKiBEb24ndCBmYWlsIHRoZSBkcml2ZSwgYWN0IGFzIHRob3VnaCB3ZSB3ZXJlIGp1c3QgYQoJCSAqIG5vcm1hbCBzaW5nbGUgZHJpdmUKCQkgKi8KCQlyZXR1cm47CglpZiAodGVzdF9hbmRfY2xlYXJfYml0KEluX3N5bmMsICZyZGV2LT5mbGFncykpIHsKCQl1bnNpZ25lZCBsb25nIGZsYWdzOwoJCXNwaW5fbG9ja19pcnFzYXZlKCZjb25mLT5kZXZpY2VfbG9jaywgZmxhZ3MpOwoJCW1kZGV2LT5kZWdyYWRlZCsrOwoJCXNldF9iaXQoRmF1bHR5LCAmcmRldi0+ZmxhZ3MpOwoJCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJmNvbmYtPmRldmljZV9sb2NrLCBmbGFncyk7CgkJLyoKCQkgKiBpZiByZWNvdmVyeSBpcyBydW5uaW5nLCBtYWtlIHN1cmUgaXQgYWJvcnRzLgoJCSAqLwoJCXNldF9iaXQoTURfUkVDT1ZFUllfRVJSLCAmbWRkZXYtPnJlY292ZXJ5KTsKCX0gZWxzZQoJCXNldF9iaXQoRmF1bHR5LCAmcmRldi0+ZmxhZ3MpOwoJc2V0X2JpdChNRF9DSEFOR0VfREVWUywgJm1kZGV2LT5mbGFncyk7CglwcmludGsoS0VSTl9BTEVSVCAicmFpZDE6IERpc2sgZmFpbHVyZSBvbiAlcywgZGlzYWJsaW5nIGRldmljZS4gXG4iCgkJIglPcGVyYXRpb24gY29udGludWluZyBvbiAlZCBkZXZpY2VzXG4iLAoJCWJkZXZuYW1lKHJkZXYtPmJkZXYsYiksIGNvbmYtPnJhaWRfZGlza3MgLSBtZGRldi0+ZGVncmFkZWQpOwp9CgpzdGF0aWMgdm9pZCBwcmludF9jb25mKGNvbmZfdCAqY29uZikKewoJaW50IGk7CgoJcHJpbnRrKCJSQUlEMSBjb25mIHByaW50b3V0OlxuIik7CglpZiAoIWNvbmYpIHsKCQlwcmludGsoIighY29uZilcbiIpOwoJCXJldHVybjsKCX0KCXByaW50aygiIC0tLSB3ZDolZCByZDolZFxuIiwgY29uZi0+cmFpZF9kaXNrcyAtIGNvbmYtPm1kZGV2LT5kZWdyYWRlZCwKCQljb25mLT5yYWlkX2Rpc2tzKTsKCglyY3VfcmVhZF9sb2NrKCk7Cglmb3IgKGkgPSAwOyBpIDwgY29uZi0+cmFpZF9kaXNrczsgaSsrKSB7CgkJY2hhciBiW0JERVZOQU1FX1NJWkVdOwoJCW1ka19yZGV2X3QgKnJkZXYgPSByY3VfZGVyZWZlcmVuY2UoY29uZi0+bWlycm9yc1tpXS5yZGV2KTsKCQlpZiAocmRldikKCQkJcHJpbnRrKCIgZGlzayAlZCwgd286JWQsIG86JWQsIGRldjolc1xuIiwKCQkJICAgICAgIGksICF0ZXN0X2JpdChJbl9zeW5jLCAmcmRldi0+ZmxhZ3MpLAoJCQkgICAgICAgIXRlc3RfYml0KEZhdWx0eSwgJnJkZXYtPmZsYWdzKSwKCQkJICAgICAgIGJkZXZuYW1lKHJkZXYtPmJkZXYsYikpOwoJfQoJcmN1X3JlYWRfdW5sb2NrKCk7Cn0KCnN0YXRpYyB2b2lkIGNsb3NlX3N5bmMoY29uZl90ICpjb25mKQp7Cgl3YWl0X2JhcnJpZXIoY29uZik7CglhbGxvd19iYXJyaWVyKGNvbmYpOwoKCW1lbXBvb2xfZGVzdHJveShjb25mLT5yMWJ1Zl9wb29sKTsKCWNvbmYtPnIxYnVmX3Bvb2wgPSBOVUxMOwp9CgpzdGF0aWMgaW50IHJhaWQxX3NwYXJlX2FjdGl2ZShtZGRldl90ICptZGRldikKewoJaW50IGk7Cgljb25mX3QgKmNvbmYgPSBtZGRldi0+cHJpdmF0ZTsKCgkvKgoJICogRmluZCBhbGwgZmFpbGVkIGRpc2tzIHdpdGhpbiB0aGUgUkFJRDEgY29uZmlndXJhdGlvbiAKCSAqIGFuZCBtYXJrIHRoZW0gcmVhZGFibGUuCgkgKiBDYWxsZWQgdW5kZXIgbWRkZXYgbG9jaywgc28gcmN1IHByb3RlY3Rpb24gbm90IG5lZWRlZC4KCSAqLwoJZm9yIChpID0gMDsgaSA8IGNvbmYtPnJhaWRfZGlza3M7IGkrKykgewoJCW1ka19yZGV2X3QgKnJkZXYgPSBjb25mLT5taXJyb3JzW2ldLnJkZXY7CgkJaWYgKHJkZXYKCQkgICAgJiYgIXRlc3RfYml0KEZhdWx0eSwgJnJkZXYtPmZsYWdzKQoJCSAgICAmJiAhdGVzdF9hbmRfc2V0X2JpdChJbl9zeW5jLCAmcmRldi0+ZmxhZ3MpKSB7CgkJCXVuc2lnbmVkIGxvbmcgZmxhZ3M7CgkJCXNwaW5fbG9ja19pcnFzYXZlKCZjb25mLT5kZXZpY2VfbG9jaywgZmxhZ3MpOwoJCQltZGRldi0+ZGVncmFkZWQtLTsKCQkJc3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmY29uZi0+ZGV2aWNlX2xvY2ssIGZsYWdzKTsKCQl9Cgl9CgoJcHJpbnRfY29uZihjb25mKTsKCXJldHVybiAwOwp9CgoKc3RhdGljIGludCByYWlkMV9hZGRfZGlzayhtZGRldl90ICptZGRldiwgbWRrX3JkZXZfdCAqcmRldikKewoJY29uZl90ICpjb25mID0gbWRkZXYtPnByaXZhdGU7CglpbnQgZm91bmQgPSAwOwoJaW50IG1pcnJvciA9IDA7CgltaXJyb3JfaW5mb190ICpwOwoKCWZvciAobWlycm9yPTA7IG1pcnJvciA8IG1kZGV2LT5yYWlkX2Rpc2tzOyBtaXJyb3IrKykKCQlpZiAoICEocD1jb25mLT5taXJyb3JzK21pcnJvciktPnJkZXYpIHsKCgkJCWJsa19xdWV1ZV9zdGFja19saW1pdHMobWRkZXYtPnF1ZXVlLAoJCQkJCSAgICAgICByZGV2LT5iZGV2LT5iZF9kaXNrLT5xdWV1ZSk7CgkJCS8qIGFzIHdlIGRvbid0IGhvbm91ciBtZXJnZV9idmVjX2ZuLCB3ZSBtdXN0IG5ldmVyIHJpc2sKCQkJICogdmlvbGF0aW5nIGl0LCBzbyBsaW1pdCAtPm1heF9zZWN0b3IgdG8gb25lIFBBR0UsIGFzCgkJCSAqIGEgb25lIHBhZ2UgcmVxdWVzdCBpcyBuZXZlciBpbiB2aW9sYXRpb24uCgkJCSAqLwoJCQlpZiAocmRldi0+YmRldi0+YmRfZGlzay0+cXVldWUtPm1lcmdlX2J2ZWNfZm4gJiYKCQkJICAgIG1kZGV2LT5xdWV1ZS0+bWF4X3NlY3RvcnMgPiAoUEFHRV9TSVpFPj45KSkKCQkJCWJsa19xdWV1ZV9tYXhfc2VjdG9ycyhtZGRldi0+cXVldWUsIFBBR0VfU0laRT4+OSk7CgoJCQlwLT5oZWFkX3Bvc2l0aW9uID0gMDsKCQkJcmRldi0+cmFpZF9kaXNrID0gbWlycm9yOwoJCQlmb3VuZCA9IDE7CgkJCS8qIEFzIGFsbCBkZXZpY2VzIGFyZSBlcXVpdmFsZW50LCB3ZSBkb24ndCBuZWVkIGEgZnVsbCByZWNvdmVyeQoJCQkgKiBpZiB0aGlzIHdhcyByZWNlbnRseSBhbnkgZHJpdmUgb2YgdGhlIGFycmF5CgkJCSAqLwoJCQlpZiAocmRldi0+c2F2ZWRfcmFpZF9kaXNrIDwgMCkKCQkJCWNvbmYtPmZ1bGxzeW5jID0gMTsKCQkJcmN1X2Fzc2lnbl9wb2ludGVyKHAtPnJkZXYsIHJkZXYpOwoJCQlicmVhazsKCQl9CgoJcHJpbnRfY29uZihjb25mKTsKCXJldHVybiBmb3VuZDsKfQoKc3RhdGljIGludCByYWlkMV9yZW1vdmVfZGlzayhtZGRldl90ICptZGRldiwgaW50IG51bWJlcikKewoJY29uZl90ICpjb25mID0gbWRkZXYtPnByaXZhdGU7CglpbnQgZXJyID0gMDsKCW1ka19yZGV2X3QgKnJkZXY7CgltaXJyb3JfaW5mb190ICpwID0gY29uZi0+bWlycm9ycysgbnVtYmVyOwoKCXByaW50X2NvbmYoY29uZik7CglyZGV2ID0gcC0+cmRldjsKCWlmIChyZGV2KSB7CgkJaWYgKHRlc3RfYml0KEluX3N5bmMsICZyZGV2LT5mbGFncykgfHwKCQkgICAgYXRvbWljX3JlYWQoJnJkZXYtPm5yX3BlbmRpbmcpKSB7CgkJCWVyciA9IC1FQlVTWTsKCQkJZ290byBhYm9ydDsKCQl9CgkJcC0+cmRldiA9IE5VTEw7CgkJc3luY2hyb25pemVfcmN1KCk7CgkJaWYgKGF0b21pY19yZWFkKCZyZGV2LT5ucl9wZW5kaW5nKSkgewoJCQkvKiBsb3N0IHRoZSByYWNlLCB0cnkgbGF0ZXIgKi8KCQkJZXJyID0gLUVCVVNZOwoJCQlwLT5yZGV2ID0gcmRldjsKCQl9Cgl9CmFib3J0OgoKCXByaW50X2NvbmYoY29uZik7CglyZXR1cm4gZXJyOwp9CgoKc3RhdGljIHZvaWQgZW5kX3N5bmNfcmVhZChzdHJ1Y3QgYmlvICpiaW8sIGludCBlcnJvcikKewoJcjFiaW9fdCAqIHIxX2JpbyA9IChyMWJpb190ICopKGJpby0+YmlfcHJpdmF0ZSk7CglpbnQgaTsKCglmb3IgKGk9cjFfYmlvLT5tZGRldi0+cmFpZF9kaXNrczsgaS0tOyApCgkJaWYgKHIxX2Jpby0+Ymlvc1tpXSA9PSBiaW8pCgkJCWJyZWFrOwoJQlVHX09OKGkgPCAwKTsKCXVwZGF0ZV9oZWFkX3BvcyhpLCByMV9iaW8pOwoJLyoKCSAqIHdlIGhhdmUgcmVhZCBhIGJsb2NrLCBub3cgaXQgbmVlZHMgdG8gYmUgcmUtd3JpdHRlbiwKCSAqIG9yIHJlLXJlYWQgaWYgdGhlIHJlYWQgZmFpbGVkLgoJICogV2UgZG9uJ3QgZG8gbXVjaCBoZXJlLCBqdXN0IHNjaGVkdWxlIGhhbmRsaW5nIGJ5IHJhaWQxZAoJICovCglpZiAodGVzdF9iaXQoQklPX1VQVE9EQVRFLCAmYmlvLT5iaV9mbGFncykpCgkJc2V0X2JpdChSMUJJT19VcHRvZGF0ZSwgJnIxX2Jpby0+c3RhdGUpOwoKCWlmIChhdG9taWNfZGVjX2FuZF90ZXN0KCZyMV9iaW8tPnJlbWFpbmluZykpCgkJcmVzY2hlZHVsZV9yZXRyeShyMV9iaW8pOwp9CgpzdGF0aWMgdm9pZCBlbmRfc3luY193cml0ZShzdHJ1Y3QgYmlvICpiaW8sIGludCBlcnJvcikKewoJaW50IHVwdG9kYXRlID0gdGVzdF9iaXQoQklPX1VQVE9EQVRFLCAmYmlvLT5iaV9mbGFncyk7CglyMWJpb190ICogcjFfYmlvID0gKHIxYmlvX3QgKikoYmlvLT5iaV9wcml2YXRlKTsKCW1kZGV2X3QgKm1kZGV2ID0gcjFfYmlvLT5tZGRldjsKCWNvbmZfdCAqY29uZiA9IG1kZGV2X3RvX2NvbmYobWRkZXYpOwoJaW50IGk7CglpbnQgbWlycm9yPTA7CgoJZm9yIChpID0gMDsgaSA8IGNvbmYtPnJhaWRfZGlza3M7IGkrKykKCQlpZiAocjFfYmlvLT5iaW9zW2ldID09IGJpbykgewoJCQltaXJyb3IgPSBpOwoJCQlicmVhazsKCQl9CglpZiAoIXVwdG9kYXRlKSB7CgkJaW50IHN5bmNfYmxvY2tzID0gMDsKCQlzZWN0b3JfdCBzID0gcjFfYmlvLT5zZWN0b3I7CgkJbG9uZyBzZWN0b3JzX3RvX2dvID0gcjFfYmlvLT5zZWN0b3JzOwoJCS8qIG1ha2Ugc3VyZSB0aGVzZSBiaXRzIGRvZXNuJ3QgZ2V0IGNsZWFyZWQuICovCgkJZG8gewoJCQliaXRtYXBfZW5kX3N5bmMobWRkZXYtPmJpdG1hcCwgcywKCQkJCQkmc3luY19ibG9ja3MsIDEpOwoJCQlzICs9IHN5bmNfYmxvY2tzOwoJCQlzZWN0b3JzX3RvX2dvIC09IHN5bmNfYmxvY2tzOwoJCX0gd2hpbGUgKHNlY3RvcnNfdG9fZ28gPiAwKTsKCQltZF9lcnJvcihtZGRldiwgY29uZi0+bWlycm9yc1ttaXJyb3JdLnJkZXYpOwoJfQoKCXVwZGF0ZV9oZWFkX3BvcyhtaXJyb3IsIHIxX2Jpbyk7CgoJaWYgKGF0b21pY19kZWNfYW5kX3Rlc3QoJnIxX2Jpby0+cmVtYWluaW5nKSkgewoJCW1kX2RvbmVfc3luYyhtZGRldiwgcjFfYmlvLT5zZWN0b3JzLCB1cHRvZGF0ZSk7CgkJcHV0X2J1ZihyMV9iaW8pOwoJfQp9CgpzdGF0aWMgdm9pZCBzeW5jX3JlcXVlc3Rfd3JpdGUobWRkZXZfdCAqbWRkZXYsIHIxYmlvX3QgKnIxX2JpbykKewoJY29uZl90ICpjb25mID0gbWRkZXZfdG9fY29uZihtZGRldik7CglpbnQgaTsKCWludCBkaXNrcyA9IGNvbmYtPnJhaWRfZGlza3M7CglzdHJ1Y3QgYmlvICpiaW8sICp3YmlvOwoKCWJpbyA9IHIxX2Jpby0+Ymlvc1tyMV9iaW8tPnJlYWRfZGlza107CgoKCWlmICh0ZXN0X2JpdChNRF9SRUNPVkVSWV9SRVFVRVNURUQsICZtZGRldi0+cmVjb3ZlcnkpKSB7CgkJLyogV2UgaGF2ZSByZWFkIGFsbCByZWFkYWJsZSBkZXZpY2VzLiAgSWYgd2UgaGF2ZW4ndAoJCSAqIGdvdCB0aGUgYmxvY2ssIHRoZW4gdGhlcmUgaXMgbm8gaG9wZSBsZWZ0LgoJCSAqIElmIHdlIGhhdmUsIHRoZW4gd2Ugd2FudCB0byBkbyBhIGNvbXBhcmlzb24KCQkgKiBhbmQgc2tpcCB0aGUgd3JpdGUgaWYgZXZlcnl0aGluZyBpcyB0aGUgc2FtZS4KCQkgKiBJZiBhbnkgYmxvY2tzIGZhaWxlZCB0byByZWFkLCB0aGVuIHdlIG5lZWQgdG8KCQkgKiBhdHRlbXB0IGFuIG92ZXItd3JpdGUKCQkgKi8KCQlpbnQgcHJpbWFyeTsKCQlpZiAoIXRlc3RfYml0KFIxQklPX1VwdG9kYXRlLCAmcjFfYmlvLT5zdGF0ZSkpIHsKCQkJZm9yIChpPTA7IGk8bWRkZXYtPnJhaWRfZGlza3M7IGkrKykKCQkJCWlmIChyMV9iaW8tPmJpb3NbaV0tPmJpX2VuZF9pbyA9PSBlbmRfc3luY19yZWFkKQoJCQkJCW1kX2Vycm9yKG1kZGV2LCBjb25mLT5taXJyb3JzW2ldLnJkZXYpOwoKCQkJbWRfZG9uZV9zeW5jKG1kZGV2LCByMV9iaW8tPnNlY3RvcnMsIDEpOwoJCQlwdXRfYnVmKHIxX2Jpbyk7CgkJCXJldHVybjsKCQl9CgkJZm9yIChwcmltYXJ5PTA7IHByaW1hcnk8bWRkZXYtPnJhaWRfZGlza3M7IHByaW1hcnkrKykKCQkJaWYgKHIxX2Jpby0+Ymlvc1twcmltYXJ5XS0+YmlfZW5kX2lvID09IGVuZF9zeW5jX3JlYWQgJiYKCQkJICAgIHRlc3RfYml0KEJJT19VUFRPREFURSwgJnIxX2Jpby0+Ymlvc1twcmltYXJ5XS0+YmlfZmxhZ3MpKSB7CgkJCQlyMV9iaW8tPmJpb3NbcHJpbWFyeV0tPmJpX2VuZF9pbyA9IE5VTEw7CgkJCQlyZGV2X2RlY19wZW5kaW5nKGNvbmYtPm1pcnJvcnNbcHJpbWFyeV0ucmRldiwgbWRkZXYpOwoJCQkJYnJlYWs7CgkJCX0KCQlyMV9iaW8tPnJlYWRfZGlzayA9IHByaW1hcnk7CgkJZm9yIChpPTA7IGk8bWRkZXYtPnJhaWRfZGlza3M7IGkrKykKCQkJaWYgKHIxX2Jpby0+Ymlvc1tpXS0+YmlfZW5kX2lvID09IGVuZF9zeW5jX3JlYWQpIHsKCQkJCWludCBqOwoJCQkJaW50IHZjbnQgPSByMV9iaW8tPnNlY3RvcnMgPj4gKFBBR0VfU0hJRlQtIDkpOwoJCQkJc3RydWN0IGJpbyAqcGJpbyA9IHIxX2Jpby0+Ymlvc1twcmltYXJ5XTsKCQkJCXN0cnVjdCBiaW8gKnNiaW8gPSByMV9iaW8tPmJpb3NbaV07CgoJCQkJaWYgKHRlc3RfYml0KEJJT19VUFRPREFURSwgJnNiaW8tPmJpX2ZsYWdzKSkgewoJCQkJCWZvciAoaiA9IHZjbnQ7IGotLSA7ICkgewoJCQkJCQlzdHJ1Y3QgcGFnZSAqcCwgKnM7CgkJCQkJCXAgPSBwYmlvLT5iaV9pb192ZWNbal0uYnZfcGFnZTsKCQkJCQkJcyA9IHNiaW8tPmJpX2lvX3ZlY1tqXS5idl9wYWdlOwoJCQkJCQlpZiAobWVtY21wKHBhZ2VfYWRkcmVzcyhwKSwKCQkJCQkJCSAgIHBhZ2VfYWRkcmVzcyhzKSwKCQkJCQkJCSAgIFBBR0VfU0laRSkpCgkJCQkJCQlicmVhazsKCQkJCQl9CgkJCQl9IGVsc2UKCQkJCQlqID0gMDsKCQkJCWlmIChqID49IDApCgkJCQkJbWRkZXYtPnJlc3luY19taXNtYXRjaGVzICs9IHIxX2Jpby0+c2VjdG9yczsKCQkJCWlmIChqIDwgMCB8fCAodGVzdF9iaXQoTURfUkVDT1ZFUllfQ0hFQ0ssICZtZGRldi0+cmVjb3ZlcnkpCgkJCQkJICAgICAgJiYgdGVzdF9iaXQoQklPX1VQVE9EQVRFLCAmc2Jpby0+YmlfZmxhZ3MpKSkgewoJCQkJCXNiaW8tPmJpX2VuZF9pbyA9IE5VTEw7CgkJCQkJcmRldl9kZWNfcGVuZGluZyhjb25mLT5taXJyb3JzW2ldLnJkZXYsIG1kZGV2KTsKCQkJCX0gZWxzZSB7CgkJCQkJLyogZml4dXAgdGhlIGJpbyBmb3IgcmV1c2UgKi8KCQkJCQlzYmlvLT5iaV92Y250ID0gdmNudDsKCQkJCQlzYmlvLT5iaV9zaXplID0gcjFfYmlvLT5zZWN0b3JzIDw8IDk7CgkJCQkJc2Jpby0+YmlfaWR4ID0gMDsKCQkJCQlzYmlvLT5iaV9waHlzX3NlZ21lbnRzID0gMDsKCQkJCQlzYmlvLT5iaV9od19zZWdtZW50cyA9IDA7CgkJCQkJc2Jpby0+YmlfaHdfZnJvbnRfc2l6ZSA9IDA7CgkJCQkJc2Jpby0+YmlfaHdfYmFja19zaXplID0gMDsKCQkJCQlzYmlvLT5iaV9mbGFncyAmPSB+KEJJT19QT09MX01BU0sgLSAxKTsKCQkJCQlzYmlvLT5iaV9mbGFncyB8PSAxIDw8IEJJT19VUFRPREFURTsKCQkJCQlzYmlvLT5iaV9uZXh0ID0gTlVMTDsKCQkJCQlzYmlvLT5iaV9zZWN0b3IgPSByMV9iaW8tPnNlY3RvciArCgkJCQkJCWNvbmYtPm1pcnJvcnNbaV0ucmRldi0+ZGF0YV9vZmZzZXQ7CgkJCQkJc2Jpby0+YmlfYmRldiA9IGNvbmYtPm1pcnJvcnNbaV0ucmRldi0+YmRldjsKCQkJCQlmb3IgKGogPSAwOyBqIDwgdmNudCA7IGorKykKCQkJCQkJbWVtY3B5KHBhZ2VfYWRkcmVzcyhzYmlvLT5iaV9pb192ZWNbal0uYnZfcGFnZSksCgkJCQkJCSAgICAgICBwYWdlX2FkZHJlc3MocGJpby0+YmlfaW9fdmVjW2pdLmJ2X3BhZ2UpLAoJCQkJCQkgICAgICAgUEFHRV9TSVpFKTsKCgkJCQl9CgkJCX0KCX0KCWlmICghdGVzdF9iaXQoUjFCSU9fVXB0b2RhdGUsICZyMV9iaW8tPnN0YXRlKSkgewoJCS8qIG91Y2ggLSBmYWlsZWQgdG8gcmVhZCBhbGwgb2YgdGhhdC4KCQkgKiBUcnkgc29tZSBzeW5jaHJvbm91cyByZWFkcyBvZiBvdGhlciBkZXZpY2VzIHRvIGdldAoJCSAqIGdvb2QgZGF0YSwgbXVjaCBsaWtlIHdpdGggbm9ybWFsIHJlYWQgZXJyb3JzLiAgT25seQoJCSAqIHJlYWQgaW50byB0aGUgcGFnZXMgd2UgYWxyZWFkeSBoYXZlIHNvIHdlIGRvbid0CgkJICogbmVlZCB0byByZS1pc3N1ZSB0aGUgcmVhZCByZXF1ZXN0LgoJCSAqIFdlIGRvbid0IG5lZWQgdG8gZnJlZXplIHRoZSBhcnJheSwgYmVjYXVzZSBiZWluZyBpbiBhbgoJCSAqIGFjdGl2ZSBzeW5jIHJlcXVlc3QsIHRoZXJlIGlzIG5vIG5vcm1hbCBJTywgYW5kCgkJICogbm8gb3ZlcmxhcHBpbmcgc3luY3MuCgkJICovCgkJc2VjdG9yX3Qgc2VjdCA9IHIxX2Jpby0+c2VjdG9yOwoJCWludCBzZWN0b3JzID0gcjFfYmlvLT5zZWN0b3JzOwoJCWludCBpZHggPSAwOwoKCQl3aGlsZShzZWN0b3JzKSB7CgkJCWludCBzID0gc2VjdG9yczsKCQkJaW50IGQgPSByMV9iaW8tPnJlYWRfZGlzazsKCQkJaW50IHN1Y2Nlc3MgPSAwOwoJCQltZGtfcmRldl90ICpyZGV2OwoKCQkJaWYgKHMgPiAoUEFHRV9TSVpFPj45KSkKCQkJCXMgPSBQQUdFX1NJWkUgPj4gOTsKCQkJZG8gewoJCQkJaWYgKHIxX2Jpby0+Ymlvc1tkXS0+YmlfZW5kX2lvID09IGVuZF9zeW5jX3JlYWQpIHsKCQkJCQkvKiBObyByY3UgcHJvdGVjdGlvbiBuZWVkZWQgaGVyZSBkZXZpY2VzCgkJCQkJICogY2FuIG9ubHkgYmUgcmVtb3ZlZCB3aGVuIG5vIHJlc3luYyBpcwoJCQkJCSAqIGFjdGl2ZSwgYW5kIHJlc3luYyBpcyBjdXJyZW50bHkgYWN0aXZlCgkJCQkJICovCgkJCQkJcmRldiA9IGNvbmYtPm1pcnJvcnNbZF0ucmRldjsKCQkJCQlpZiAoc3luY19wYWdlX2lvKHJkZXYtPmJkZXYsCgkJCQkJCQkgc2VjdCArIHJkZXYtPmRhdGFfb2Zmc2V0LAoJCQkJCQkJIHM8PDksCgkJCQkJCQkgYmlvLT5iaV9pb192ZWNbaWR4XS5idl9wYWdlLAoJCQkJCQkJIFJFQUQpKSB7CgkJCQkJCXN1Y2Nlc3MgPSAxOwoJCQkJCQlicmVhazsKCQkJCQl9CgkJCQl9CgkJCQlkKys7CgkJCQlpZiAoZCA9PSBjb25mLT5yYWlkX2Rpc2tzKQoJCQkJCWQgPSAwOwoJCQl9IHdoaWxlICghc3VjY2VzcyAmJiBkICE9IHIxX2Jpby0+cmVhZF9kaXNrKTsKCgkJCWlmIChzdWNjZXNzKSB7CgkJCQlpbnQgc3RhcnQgPSBkOwoJCQkJLyogd3JpdGUgaXQgYmFjayBhbmQgcmUtcmVhZCAqLwoJCQkJc2V0X2JpdChSMUJJT19VcHRvZGF0ZSwgJnIxX2Jpby0+c3RhdGUpOwoJCQkJd2hpbGUgKGQgIT0gcjFfYmlvLT5yZWFkX2Rpc2spIHsKCQkJCQlpZiAoZCA9PSAwKQoJCQkJCQlkID0gY29uZi0+cmFpZF9kaXNrczsKCQkJCQlkLS07CgkJCQkJaWYgKHIxX2Jpby0+Ymlvc1tkXS0+YmlfZW5kX2lvICE9IGVuZF9zeW5jX3JlYWQpCgkJCQkJCWNvbnRpbnVlOwoJCQkJCXJkZXYgPSBjb25mLT5taXJyb3JzW2RdLnJkZXY7CgkJCQkJYXRvbWljX2FkZChzLCAmcmRldi0+Y29ycmVjdGVkX2Vycm9ycyk7CgkJCQkJaWYgKHN5bmNfcGFnZV9pbyhyZGV2LT5iZGV2LAoJCQkJCQkJIHNlY3QgKyByZGV2LT5kYXRhX29mZnNldCwKCQkJCQkJCSBzPDw5LAoJCQkJCQkJIGJpby0+YmlfaW9fdmVjW2lkeF0uYnZfcGFnZSwKCQkJCQkJCSBXUklURSkgPT0gMCkKCQkJCQkJbWRfZXJyb3IobWRkZXYsIHJkZXYpOwoJCQkJfQoJCQkJZCA9IHN0YXJ0OwoJCQkJd2hpbGUgKGQgIT0gcjFfYmlvLT5yZWFkX2Rpc2spIHsKCQkJCQlpZiAoZCA9PSAwKQoJCQkJCQlkID0gY29uZi0+cmFpZF9kaXNrczsKCQkJCQlkLS07CgkJCQkJaWYgKHIxX2Jpby0+Ymlvc1tkXS0+YmlfZW5kX2lvICE9IGVuZF9zeW5jX3JlYWQpCgkJCQkJCWNvbnRpbnVlOwoJCQkJCXJkZXYgPSBjb25mLT5taXJyb3JzW2RdLnJkZXY7CgkJCQkJaWYgKHN5bmNfcGFnZV9pbyhyZGV2LT5iZGV2LAoJCQkJCQkJIHNlY3QgKyByZGV2LT5kYXRhX29mZnNldCwKCQkJCQkJCSBzPDw5LAoJCQkJCQkJIGJpby0+YmlfaW9fdmVjW2lkeF0uYnZfcGFnZSwKCQkJCQkJCSBSRUFEKSA9PSAwKQoJCQkJCQltZF9lcnJvcihtZGRldiwgcmRldik7CgkJCQl9CgkJCX0gZWxzZSB7CgkJCQljaGFyIGJbQkRFVk5BTUVfU0laRV07CgkJCQkvKiBDYW5ub3QgcmVhZCBmcm9tIGFueXdoZXJlLCBhcnJheSBpcyB0b2FzdCAqLwoJCQkJbWRfZXJyb3IobWRkZXYsIGNvbmYtPm1pcnJvcnNbcjFfYmlvLT5yZWFkX2Rpc2tdLnJkZXYpOwoJCQkJcHJpbnRrKEtFUk5fQUxFUlQgInJhaWQxOiAlczogdW5yZWNvdmVyYWJsZSBJL08gcmVhZCBlcnJvciIKCQkJCSAgICAgICAiIGZvciBibG9jayAlbGx1XG4iLAoJCQkJICAgICAgIGJkZXZuYW1lKGJpby0+YmlfYmRldixiKSwKCQkJCSAgICAgICAodW5zaWduZWQgbG9uZyBsb25nKXIxX2Jpby0+c2VjdG9yKTsKCQkJCW1kX2RvbmVfc3luYyhtZGRldiwgcjFfYmlvLT5zZWN0b3JzLCAwKTsKCQkJCXB1dF9idWYocjFfYmlvKTsKCQkJCXJldHVybjsKCQkJfQoJCQlzZWN0b3JzIC09IHM7CgkJCXNlY3QgKz0gczsKCQkJaWR4ICsrOwoJCX0KCX0KCgkvKgoJICogc2NoZWR1bGUgd3JpdGVzCgkgKi8KCWF0b21pY19zZXQoJnIxX2Jpby0+cmVtYWluaW5nLCAxKTsKCWZvciAoaSA9IDA7IGkgPCBkaXNrcyA7IGkrKykgewoJCXdiaW8gPSByMV9iaW8tPmJpb3NbaV07CgkJaWYgKHdiaW8tPmJpX2VuZF9pbyA9PSBOVUxMIHx8CgkJICAgICh3YmlvLT5iaV9lbmRfaW8gPT0gZW5kX3N5bmNfcmVhZCAmJgoJCSAgICAgKGkgPT0gcjFfYmlvLT5yZWFkX2Rpc2sgfHwKCQkgICAgICAhdGVzdF9iaXQoTURfUkVDT1ZFUllfU1lOQywgJm1kZGV2LT5yZWNvdmVyeSkpKSkKCQkJY29udGludWU7CgoJCXdiaW8tPmJpX3J3ID0gV1JJVEU7CgkJd2Jpby0+YmlfZW5kX2lvID0gZW5kX3N5bmNfd3JpdGU7CgkJYXRvbWljX2luYygmcjFfYmlvLT5yZW1haW5pbmcpOwoJCW1kX3N5bmNfYWNjdChjb25mLT5taXJyb3JzW2ldLnJkZXYtPmJkZXYsIHdiaW8tPmJpX3NpemUgPj4gOSk7CgoJCWdlbmVyaWNfbWFrZV9yZXF1ZXN0KHdiaW8pOwoJfQoKCWlmIChhdG9taWNfZGVjX2FuZF90ZXN0KCZyMV9iaW8tPnJlbWFpbmluZykpIHsKCQkvKiBpZiB3ZSdyZSBoZXJlLCBhbGwgd3JpdGUocykgaGF2ZSBjb21wbGV0ZWQsIHNvIGNsZWFuIHVwICovCgkJbWRfZG9uZV9zeW5jKG1kZGV2LCByMV9iaW8tPnNlY3RvcnMsIDEpOwoJCXB1dF9idWYocjFfYmlvKTsKCX0KfQoKLyoKICogVGhpcyBpcyBhIGtlcm5lbCB0aHJlYWQgd2hpY2g6CiAqCiAqCTEuCVJldHJpZXMgZmFpbGVkIHJlYWQgb3BlcmF0aW9ucyBvbiB3b3JraW5nIG1pcnJvcnMuCiAqCTIuCVVwZGF0ZXMgdGhlIHJhaWQgc3VwZXJibG9jayB3aGVuIHByb2JsZW1zIGVuY291bnRlci4KICoJMy4JUGVyZm9ybXMgd3JpdGVzIGZvbGxvd2luZyByZWFkcyBmb3IgYXJyYXkgc3luY3JvbmlzaW5nLgogKi8KCnN0YXRpYyB2b2lkIGZpeF9yZWFkX2Vycm9yKGNvbmZfdCAqY29uZiwgaW50IHJlYWRfZGlzaywKCQkJICAgc2VjdG9yX3Qgc2VjdCwgaW50IHNlY3RvcnMpCnsKCW1kZGV2X3QgKm1kZGV2ID0gY29uZi0+bWRkZXY7Cgl3aGlsZShzZWN0b3JzKSB7CgkJaW50IHMgPSBzZWN0b3JzOwoJCWludCBkID0gcmVhZF9kaXNrOwoJCWludCBzdWNjZXNzID0gMDsKCQlpbnQgc3RhcnQ7CgkJbWRrX3JkZXZfdCAqcmRldjsKCgkJaWYgKHMgPiAoUEFHRV9TSVpFPj45KSkKCQkJcyA9IFBBR0VfU0laRSA+PiA5OwoKCQlkbyB7CgkJCS8qIE5vdGU6IG5vIHJjdSBwcm90ZWN0aW9uIG5lZWRlZCBoZXJlCgkJCSAqIGFzIHRoaXMgaXMgc3luY2hyb25vdXMgaW4gdGhlIHJhaWQxZCB0aHJlYWQKCQkJICogd2hpY2ggaXMgdGhlIHRocmVhZCB0aGF0IG1pZ2h0IHJlbW92ZQoJCQkgKiBhIGRldmljZS4gIElmIHJhaWQxZCBldmVyIGJlY29tZXMgbXVsdGktdGhyZWFkZWQuLi4uCgkJCSAqLwoJCQlyZGV2ID0gY29uZi0+bWlycm9yc1tkXS5yZGV2OwoJCQlpZiAocmRldiAmJgoJCQkgICAgdGVzdF9iaXQoSW5fc3luYywgJnJkZXYtPmZsYWdzKSAmJgoJCQkgICAgc3luY19wYWdlX2lvKHJkZXYtPmJkZXYsCgkJCQkJIHNlY3QgKyByZGV2LT5kYXRhX29mZnNldCwKCQkJCQkgczw8OSwKCQkJCQkgY29uZi0+dG1wcGFnZSwgUkVBRCkpCgkJCQlzdWNjZXNzID0gMTsKCQkJZWxzZSB7CgkJCQlkKys7CgkJCQlpZiAoZCA9PSBjb25mLT5yYWlkX2Rpc2tzKQoJCQkJCWQgPSAwOwoJCQl9CgkJfSB3aGlsZSAoIXN1Y2Nlc3MgJiYgZCAhPSByZWFkX2Rpc2spOwoKCQlpZiAoIXN1Y2Nlc3MpIHsKCQkJLyogQ2Fubm90IHJlYWQgZnJvbSBhbnl3aGVyZSAtLSBieWUgYnllIGFycmF5ICovCgkJCW1kX2Vycm9yKG1kZGV2LCBjb25mLT5taXJyb3JzW3JlYWRfZGlza10ucmRldik7CgkJCWJyZWFrOwoJCX0KCQkvKiB3cml0ZSBpdCBiYWNrIGFuZCByZS1yZWFkICovCgkJc3RhcnQgPSBkOwoJCXdoaWxlIChkICE9IHJlYWRfZGlzaykgewoJCQlpZiAoZD09MCkKCQkJCWQgPSBjb25mLT5yYWlkX2Rpc2tzOwoJCQlkLS07CgkJCXJkZXYgPSBjb25mLT5taXJyb3JzW2RdLnJkZXY7CgkJCWlmIChyZGV2ICYmCgkJCSAgICB0ZXN0X2JpdChJbl9zeW5jLCAmcmRldi0+ZmxhZ3MpKSB7CgkJCQlpZiAoc3luY19wYWdlX2lvKHJkZXYtPmJkZXYsCgkJCQkJCSBzZWN0ICsgcmRldi0+ZGF0YV9vZmZzZXQsCgkJCQkJCSBzPDw5LCBjb25mLT50bXBwYWdlLCBXUklURSkKCQkJCSAgICA9PSAwKQoJCQkJCS8qIFdlbGwsIHRoaXMgZGV2aWNlIGlzIGRlYWQgKi8KCQkJCQltZF9lcnJvcihtZGRldiwgcmRldik7CgkJCX0KCQl9CgkJZCA9IHN0YXJ0OwoJCXdoaWxlIChkICE9IHJlYWRfZGlzaykgewoJCQljaGFyIGJbQkRFVk5BTUVfU0laRV07CgkJCWlmIChkPT0wKQoJCQkJZCA9IGNvbmYtPnJhaWRfZGlza3M7CgkJCWQtLTsKCQkJcmRldiA9IGNvbmYtPm1pcnJvcnNbZF0ucmRldjsKCQkJaWYgKHJkZXYgJiYKCQkJICAgIHRlc3RfYml0KEluX3N5bmMsICZyZGV2LT5mbGFncykpIHsKCQkJCWlmIChzeW5jX3BhZ2VfaW8ocmRldi0+YmRldiwKCQkJCQkJIHNlY3QgKyByZGV2LT5kYXRhX29mZnNldCwKCQkJCQkJIHM8PDksIGNvbmYtPnRtcHBhZ2UsIFJFQUQpCgkJCQkgICAgPT0gMCkKCQkJCQkvKiBXZWxsLCB0aGlzIGRldmljZSBpcyBkZWFkICovCgkJCQkJbWRfZXJyb3IobWRkZXYsIHJkZXYpOwoJCQkJZWxzZSB7CgkJCQkJYXRvbWljX2FkZChzLCAmcmRldi0+Y29ycmVjdGVkX2Vycm9ycyk7CgkJCQkJcHJpbnRrKEtFUk5fSU5GTwoJCQkJCSAgICAgICAicmFpZDE6JXM6IHJlYWQgZXJyb3IgY29ycmVjdGVkICIKCQkJCQkgICAgICAgIiglZCBzZWN0b3JzIGF0ICVsbHUgb24gJXMpXG4iLAoJCQkJCSAgICAgICBtZG5hbWUobWRkZXYpLCBzLAoJCQkJCSAgICAgICAodW5zaWduZWQgbG9uZyBsb25nKShzZWN0ICsKCQkJCQkgICAgICAgICAgIHJkZXYtPmRhdGFfb2Zmc2V0KSwKCQkJCQkgICAgICAgYmRldm5hbWUocmRldi0+YmRldiwgYikpOwoJCQkJfQoJCQl9CgkJfQoJCXNlY3RvcnMgLT0gczsKCQlzZWN0ICs9IHM7Cgl9Cn0KCnN0YXRpYyB2b2lkIHJhaWQxZChtZGRldl90ICptZGRldikKewoJcjFiaW9fdCAqcjFfYmlvOwoJc3RydWN0IGJpbyAqYmlvOwoJdW5zaWduZWQgbG9uZyBmbGFnczsKCWNvbmZfdCAqY29uZiA9IG1kZGV2X3RvX2NvbmYobWRkZXYpOwoJc3RydWN0IGxpc3RfaGVhZCAqaGVhZCA9ICZjb25mLT5yZXRyeV9saXN0OwoJaW50IHVucGx1Zz0wOwoJbWRrX3JkZXZfdCAqcmRldjsKCgltZF9jaGVja19yZWNvdmVyeShtZGRldik7CgkKCWZvciAoOzspIHsKCQljaGFyIGJbQkRFVk5BTUVfU0laRV07CgkJc3Bpbl9sb2NrX2lycXNhdmUoJmNvbmYtPmRldmljZV9sb2NrLCBmbGFncyk7CgoJCWlmIChjb25mLT5wZW5kaW5nX2Jpb19saXN0LmhlYWQpIHsKCQkJYmlvID0gYmlvX2xpc3RfZ2V0KCZjb25mLT5wZW5kaW5nX2Jpb19saXN0KTsKCQkJYmxrX3JlbW92ZV9wbHVnKG1kZGV2LT5xdWV1ZSk7CgkJCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJmNvbmYtPmRldmljZV9sb2NrLCBmbGFncyk7CgkJCS8qIGZsdXNoIGFueSBwZW5kaW5nIGJpdG1hcCB3cml0ZXMgdG8gZGlzayBiZWZvcmUgcHJvY2VlZGluZyB3LyBJL08gKi8KCQkJYml0bWFwX3VucGx1ZyhtZGRldi0+Yml0bWFwKTsKCgkJCXdoaWxlIChiaW8pIHsgLyogc3VibWl0IHBlbmRpbmcgd3JpdGVzICovCgkJCQlzdHJ1Y3QgYmlvICpuZXh0ID0gYmlvLT5iaV9uZXh0OwoJCQkJYmlvLT5iaV9uZXh0ID0gTlVMTDsKCQkJCWdlbmVyaWNfbWFrZV9yZXF1ZXN0KGJpbyk7CgkJCQliaW8gPSBuZXh0OwoJCQl9CgkJCXVucGx1ZyA9IDE7CgoJCQljb250aW51ZTsKCQl9CgoJCWlmIChsaXN0X2VtcHR5KGhlYWQpKQoJCQlicmVhazsKCQlyMV9iaW8gPSBsaXN0X2VudHJ5KGhlYWQtPnByZXYsIHIxYmlvX3QsIHJldHJ5X2xpc3QpOwoJCWxpc3RfZGVsKGhlYWQtPnByZXYpOwoJCWNvbmYtPm5yX3F1ZXVlZC0tOwoJCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJmNvbmYtPmRldmljZV9sb2NrLCBmbGFncyk7CgoJCW1kZGV2ID0gcjFfYmlvLT5tZGRldjsKCQljb25mID0gbWRkZXZfdG9fY29uZihtZGRldik7CgkJaWYgKHRlc3RfYml0KFIxQklPX0lzU3luYywgJnIxX2Jpby0+c3RhdGUpKSB7CgkJCXN5bmNfcmVxdWVzdF93cml0ZShtZGRldiwgcjFfYmlvKTsKCQkJdW5wbHVnID0gMTsKCQl9IGVsc2UgaWYgKHRlc3RfYml0KFIxQklPX0JhcnJpZXJSZXRyeSwgJnIxX2Jpby0+c3RhdGUpKSB7CgkJCS8qIHNvbWUgcmVxdWVzdHMgaW4gdGhlIHIxYmlvIHdlcmUgQklPX1JXX0JBUlJJRVIKCQkJICogcmVxdWVzdHMgd2hpY2ggZmFpbGVkIHdpdGggLUVPUE5PVFNVUFAuICBIb2h1bW0uLgoJCQkgKiBCZXR0ZXIgcmVzdWJtaXQgd2l0aG91dCB0aGUgYmFycmllci4KCQkJICogV2Uga25vdyB3aGljaCBkZXZpY2VzIHRvIHJlc3VibWl0IGZvciwgYmVjYXVzZQoJCQkgKiBhbGwgb3RoZXJzIGhhdmUgaGFkIHRoZWlyIGJpb3NbXSBlbnRyeSBjbGVhcmVkLgoJCQkgKiBXZSBhbHJlYWR5IGhhdmUgYSBucl9wZW5kaW5nIHJlZmVyZW5jZSBvbiB0aGVzZSByZGV2cy4KCQkJICovCgkJCWludCBpOwoJCQljb25zdCBpbnQgZG9fc3luYyA9IGJpb19zeW5jKHIxX2Jpby0+bWFzdGVyX2Jpbyk7CgkJCWNsZWFyX2JpdChSMUJJT19CYXJyaWVyUmV0cnksICZyMV9iaW8tPnN0YXRlKTsKCQkJY2xlYXJfYml0KFIxQklPX0JhcnJpZXIsICZyMV9iaW8tPnN0YXRlKTsKCQkJZm9yIChpPTA7IGkgPCBjb25mLT5yYWlkX2Rpc2tzOyBpKyspCgkJCQlpZiAocjFfYmlvLT5iaW9zW2ldKQoJCQkJCWF0b21pY19pbmMoJnIxX2Jpby0+cmVtYWluaW5nKTsKCQkJZm9yIChpPTA7IGkgPCBjb25mLT5yYWlkX2Rpc2tzOyBpKyspCgkJCQlpZiAocjFfYmlvLT5iaW9zW2ldKSB7CgkJCQkJc3RydWN0IGJpb192ZWMgKmJ2ZWM7CgkJCQkJaW50IGo7CgoJCQkJCWJpbyA9IGJpb19jbG9uZShyMV9iaW8tPm1hc3Rlcl9iaW8sIEdGUF9OT0lPKTsKCQkJCQkvKiBjb3B5IHBhZ2VzIGZyb20gdGhlIGZhaWxlZCBiaW8sIGFzCgkJCQkJICogdGhpcyBtaWdodCBiZSBhIHdyaXRlLWJlaGluZCBkZXZpY2UgKi8KCQkJCQlfX2Jpb19mb3JfZWFjaF9zZWdtZW50KGJ2ZWMsIGJpbywgaiwgMCkKCQkJCQkJYnZlYy0+YnZfcGFnZSA9IGJpb19pb3ZlY19pZHgocjFfYmlvLT5iaW9zW2ldLCBqKS0+YnZfcGFnZTsKCQkJCQliaW9fcHV0KHIxX2Jpby0+Ymlvc1tpXSk7CgkJCQkJYmlvLT5iaV9zZWN0b3IgPSByMV9iaW8tPnNlY3RvciArCgkJCQkJCWNvbmYtPm1pcnJvcnNbaV0ucmRldi0+ZGF0YV9vZmZzZXQ7CgkJCQkJYmlvLT5iaV9iZGV2ID0gY29uZi0+bWlycm9yc1tpXS5yZGV2LT5iZGV2OwoJCQkJCWJpby0+YmlfZW5kX2lvID0gcmFpZDFfZW5kX3dyaXRlX3JlcXVlc3Q7CgkJCQkJYmlvLT5iaV9ydyA9IFdSSVRFIHwgZG9fc3luYzsKCQkJCQliaW8tPmJpX3ByaXZhdGUgPSByMV9iaW87CgkJCQkJcjFfYmlvLT5iaW9zW2ldID0gYmlvOwoJCQkJCWdlbmVyaWNfbWFrZV9yZXF1ZXN0KGJpbyk7CgkJCQl9CgkJfSBlbHNlIHsKCQkJaW50IGRpc2s7CgoJCQkvKiB3ZSBnb3QgYSByZWFkIGVycm9yLiBNYXliZSB0aGUgZHJpdmUgaXMgYmFkLiAgTWF5YmUganVzdAoJCQkgKiB0aGUgYmxvY2sgYW5kIHdlIGNhbiBmaXggaXQuCgkJCSAqIFdlIGZyZWV6ZSBhbGwgb3RoZXIgSU8sIGFuZCB0cnkgcmVhZGluZyB0aGUgYmxvY2sgZnJvbQoJCQkgKiBvdGhlciBkZXZpY2VzLiAgV2hlbiB3ZSBmaW5kIG9uZSwgd2UgcmUtd3JpdGUKCQkJICogYW5kIGNoZWNrIGl0IHRoYXQgZml4ZXMgdGhlIHJlYWQgZXJyb3IuCgkJCSAqIFRoaXMgaXMgYWxsIGRvbmUgc3luY2hyb25vdXNseSB3aGlsZSB0aGUgYXJyYXkgaXMKCQkJICogZnJvemVuCgkJCSAqLwoJCQlpZiAobWRkZXYtPnJvID09IDApIHsKCQkJCWZyZWV6ZV9hcnJheShjb25mKTsKCQkJCWZpeF9yZWFkX2Vycm9yKGNvbmYsIHIxX2Jpby0+cmVhZF9kaXNrLAoJCQkJCSAgICAgICByMV9iaW8tPnNlY3RvciwKCQkJCQkgICAgICAgcjFfYmlvLT5zZWN0b3JzKTsKCQkJCXVuZnJlZXplX2FycmF5KGNvbmYpOwoJCQl9CgoJCQliaW8gPSByMV9iaW8tPmJpb3NbcjFfYmlvLT5yZWFkX2Rpc2tdOwoJCQlpZiAoKGRpc2s9cmVhZF9iYWxhbmNlKGNvbmYsIHIxX2JpbykpID09IC0xKSB7CgkJCQlwcmludGsoS0VSTl9BTEVSVCAicmFpZDE6ICVzOiB1bnJlY292ZXJhYmxlIEkvTyIKCQkJCSAgICAgICAiIHJlYWQgZXJyb3IgZm9yIGJsb2NrICVsbHVcbiIsCgkJCQkgICAgICAgYmRldm5hbWUoYmlvLT5iaV9iZGV2LGIpLAoJCQkJICAgICAgICh1bnNpZ25lZCBsb25nIGxvbmcpcjFfYmlvLT5zZWN0b3IpOwoJCQkJcmFpZF9lbmRfYmlvX2lvKHIxX2Jpbyk7CgkJCX0gZWxzZSB7CgkJCQljb25zdCBpbnQgZG9fc3luYyA9IGJpb19zeW5jKHIxX2Jpby0+bWFzdGVyX2Jpbyk7CgkJCQlyMV9iaW8tPmJpb3NbcjFfYmlvLT5yZWFkX2Rpc2tdID0KCQkJCQltZGRldi0+cm8gPyBJT19CTE9DS0VEIDogTlVMTDsKCQkJCXIxX2Jpby0+cmVhZF9kaXNrID0gZGlzazsKCQkJCWJpb19wdXQoYmlvKTsKCQkJCWJpbyA9IGJpb19jbG9uZShyMV9iaW8tPm1hc3Rlcl9iaW8sIEdGUF9OT0lPKTsKCQkJCXIxX2Jpby0+Ymlvc1tyMV9iaW8tPnJlYWRfZGlza10gPSBiaW87CgkJCQlyZGV2ID0gY29uZi0+bWlycm9yc1tkaXNrXS5yZGV2OwoJCQkJaWYgKHByaW50a19yYXRlbGltaXQoKSkKCQkJCQlwcmludGsoS0VSTl9FUlIgInJhaWQxOiAlczogcmVkaXJlY3Rpbmcgc2VjdG9yICVsbHUgdG8iCgkJCQkJICAgICAgICIgYW5vdGhlciBtaXJyb3JcbiIsCgkJCQkJICAgICAgIGJkZXZuYW1lKHJkZXYtPmJkZXYsYiksCgkJCQkJICAgICAgICh1bnNpZ25lZCBsb25nIGxvbmcpcjFfYmlvLT5zZWN0b3IpOwoJCQkJYmlvLT5iaV9zZWN0b3IgPSByMV9iaW8tPnNlY3RvciArIHJkZXYtPmRhdGFfb2Zmc2V0OwoJCQkJYmlvLT5iaV9iZGV2ID0gcmRldi0+YmRldjsKCQkJCWJpby0+YmlfZW5kX2lvID0gcmFpZDFfZW5kX3JlYWRfcmVxdWVzdDsKCQkJCWJpby0+YmlfcncgPSBSRUFEIHwgZG9fc3luYzsKCQkJCWJpby0+YmlfcHJpdmF0ZSA9IHIxX2JpbzsKCQkJCXVucGx1ZyA9IDE7CgkJCQlnZW5lcmljX21ha2VfcmVxdWVzdChiaW8pOwoJCQl9CgkJfQoJfQoJc3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmY29uZi0+ZGV2aWNlX2xvY2ssIGZsYWdzKTsKCWlmICh1bnBsdWcpCgkJdW5wbHVnX3NsYXZlcyhtZGRldik7Cn0KCgpzdGF0aWMgaW50IGluaXRfcmVzeW5jKGNvbmZfdCAqY29uZikKewoJaW50IGJ1ZmZzOwoKCWJ1ZmZzID0gUkVTWU5DX1dJTkRPVyAvIFJFU1lOQ19CTE9DS19TSVpFOwoJQlVHX09OKGNvbmYtPnIxYnVmX3Bvb2wpOwoJY29uZi0+cjFidWZfcG9vbCA9IG1lbXBvb2xfY3JlYXRlKGJ1ZmZzLCByMWJ1Zl9wb29sX2FsbG9jLCByMWJ1Zl9wb29sX2ZyZWUsCgkJCQkJICBjb25mLT5wb29saW5mbyk7CglpZiAoIWNvbmYtPnIxYnVmX3Bvb2wpCgkJcmV0dXJuIC1FTk9NRU07Cgljb25mLT5uZXh0X3Jlc3luYyA9IDA7CglyZXR1cm4gMDsKfQoKLyoKICogcGVyZm9ybSBhICJzeW5jIiBvbiBvbmUgImJsb2NrIgogKgogKiBXZSBuZWVkIHRvIG1ha2Ugc3VyZSB0aGF0IG5vIG5vcm1hbCBJL08gcmVxdWVzdCAtIHBhcnRpY3VsYXJseSB3cml0ZQogKiByZXF1ZXN0cyAtIGNvbmZsaWN0IHdpdGggYWN0aXZlIHN5bmMgcmVxdWVzdHMuCiAqCiAqIFRoaXMgaXMgYWNoaWV2ZWQgYnkgdHJhY2tpbmcgcGVuZGluZyByZXF1ZXN0cyBhbmQgYSAnYmFycmllcicgY29uY2VwdAogKiB0aGF0IGNhbiBiZSBpbnN0YWxsZWQgdG8gZXhjbHVkZSBub3JtYWwgSU8gcmVxdWVzdHMuCiAqLwoKc3RhdGljIHNlY3Rvcl90IHN5bmNfcmVxdWVzdChtZGRldl90ICptZGRldiwgc2VjdG9yX3Qgc2VjdG9yX25yLCBpbnQgKnNraXBwZWQsIGludCBnb19mYXN0ZXIpCnsKCWNvbmZfdCAqY29uZiA9IG1kZGV2X3RvX2NvbmYobWRkZXYpOwoJcjFiaW9fdCAqcjFfYmlvOwoJc3RydWN0IGJpbyAqYmlvOwoJc2VjdG9yX3QgbWF4X3NlY3RvciwgbnJfc2VjdG9yczsKCWludCBkaXNrID0gLTE7CglpbnQgaTsKCWludCB3b25seSA9IC0xOwoJaW50IHdyaXRlX3RhcmdldHMgPSAwLCByZWFkX3RhcmdldHMgPSAwOwoJaW50IHN5bmNfYmxvY2tzOwoJaW50IHN0aWxsX2RlZ3JhZGVkID0gMDsKCglpZiAoIWNvbmYtPnIxYnVmX3Bvb2wpCgl7Ci8qCgkJcHJpbnRrKCJzeW5jIHN0YXJ0IC0gYml0bWFwICVwXG4iLCBtZGRldi0+Yml0bWFwKTsKKi8KCQlpZiAoaW5pdF9yZXN5bmMoY29uZikpCgkJCXJldHVybiAwOwoJfQoKCW1heF9zZWN0b3IgPSBtZGRldi0+c2l6ZSA8PCAxOwoJaWYgKHNlY3Rvcl9uciA+PSBtYXhfc2VjdG9yKSB7CgkJLyogSWYgd2UgYWJvcnRlZCwgd2UgbmVlZCB0byBhYm9ydCB0aGUKCQkgKiBzeW5jIG9uIHRoZSAnY3VycmVudCcgYml0bWFwIGNodW5rICh0aGVyZSB3aWxsCgkJICogb25seSBiZSBvbmUgaW4gcmFpZDEgcmVzeW5jLgoJCSAqIFdlIGNhbiBmaW5kIHRoZSBjdXJyZW50IGFkZGVzcyBpbiBtZGRldi0+Y3Vycl9yZXN5bmMKCQkgKi8KCQlpZiAobWRkZXYtPmN1cnJfcmVzeW5jIDwgbWF4X3NlY3RvcikgLyogYWJvcnRlZCAqLwoJCQliaXRtYXBfZW5kX3N5bmMobWRkZXYtPmJpdG1hcCwgbWRkZXYtPmN1cnJfcmVzeW5jLAoJCQkJCQkmc3luY19ibG9ja3MsIDEpOwoJCWVsc2UgLyogY29tcGxldGVkIHN5bmMgKi8KCQkJY29uZi0+ZnVsbHN5bmMgPSAwOwoKCQliaXRtYXBfY2xvc2Vfc3luYyhtZGRldi0+Yml0bWFwKTsKCQljbG9zZV9zeW5jKGNvbmYpOwoJCXJldHVybiAwOwoJfQoKCWlmIChtZGRldi0+Yml0bWFwID09IE5VTEwgJiYKCSAgICBtZGRldi0+cmVjb3ZlcnlfY3AgPT0gTWF4U2VjdG9yICYmCgkgICAgIXRlc3RfYml0KE1EX1JFQ09WRVJZX1JFUVVFU1RFRCwgJm1kZGV2LT5yZWNvdmVyeSkgJiYKCSAgICBjb25mLT5mdWxsc3luYyA9PSAwKSB7CgkJKnNraXBwZWQgPSAxOwoJCXJldHVybiBtYXhfc2VjdG9yIC0gc2VjdG9yX25yOwoJfQoJLyogYmVmb3JlIGJ1aWxkaW5nIGEgcmVxdWVzdCwgY2hlY2sgaWYgd2UgY2FuIHNraXAgdGhlc2UgYmxvY2tzLi4KCSAqIFRoaXMgY2FsbCB0aGUgYml0bWFwX3N0YXJ0X3N5bmMgZG9lc24ndCBhY3R1YWxseSByZWNvcmQgYW55dGhpbmcKCSAqLwoJaWYgKCFiaXRtYXBfc3RhcnRfc3luYyhtZGRldi0+Yml0bWFwLCBzZWN0b3JfbnIsICZzeW5jX2Jsb2NrcywgMSkgJiYKCSAgICAhY29uZi0+ZnVsbHN5bmMgJiYgIXRlc3RfYml0KE1EX1JFQ09WRVJZX1JFUVVFU1RFRCwgJm1kZGV2LT5yZWNvdmVyeSkpIHsKCQkvKiBXZSBjYW4gc2tpcCB0aGlzIGJsb2NrLCBhbmQgcHJvYmFibHkgc2V2ZXJhbCBtb3JlICovCgkJKnNraXBwZWQgPSAxOwoJCXJldHVybiBzeW5jX2Jsb2NrczsKCX0KCS8qCgkgKiBJZiB0aGVyZSBpcyBub24tcmVzeW5jIGFjdGl2aXR5IHdhaXRpbmcgZm9yIGEgdHVybiwKCSAqIGFuZCByZXN5bmMgaXMgZ29pbmcgZmFzdCBlbm91Z2gsCgkgKiB0aGVuIGxldCBpdCB0aG91Z2ggYmVmb3JlIHN0YXJ0aW5nIG9uIHRoaXMgbmV3IHN5bmMgcmVxdWVzdC4KCSAqLwoJaWYgKCFnb19mYXN0ZXIgJiYgY29uZi0+bnJfd2FpdGluZykKCQltc2xlZXBfaW50ZXJydXB0aWJsZSgxMDAwKTsKCglyYWlzZV9iYXJyaWVyKGNvbmYpOwoKCWNvbmYtPm5leHRfcmVzeW5jID0gc2VjdG9yX25yOwoKCXIxX2JpbyA9IG1lbXBvb2xfYWxsb2MoY29uZi0+cjFidWZfcG9vbCwgR0ZQX05PSU8pOwoJcmN1X3JlYWRfbG9jaygpOwoJLyoKCSAqIElmIHdlIGdldCBhIGNvcnJlY3RhYmx5IHJlYWQgZXJyb3IgZHVyaW5nIHJlc3luYyBvciByZWNvdmVyeSwKCSAqIHdlIG1pZ2h0IHdhbnQgdG8gcmVhZCBmcm9tIGEgZGlmZmVyZW50IGRldmljZS4gIFNvIHdlCgkgKiBmbGFnIGFsbCBkcml2ZXMgdGhhdCBjb3VsZCBjb25jZWl2YWJseSBiZSByZWFkIGZyb20gZm9yIFJFQUQsCgkgKiBhbmQgYW55IG90aGVycyAod2hpY2ggd2lsbCBiZSBub24tSW5fc3luYyBkZXZpY2VzKSBmb3IgV1JJVEUuCgkgKiBJZiBhIHJlYWQgZmFpbHMsIHdlIHRyeSByZWFkaW5nIGZyb20gc29tZXRoaW5nIGVsc2UgZm9yIHdoaWNoIFJFQUQKCSAqIGlzIE9LLgoJICovCgoJcjFfYmlvLT5tZGRldiA9IG1kZGV2OwoJcjFfYmlvLT5zZWN0b3IgPSBzZWN0b3JfbnI7CglyMV9iaW8tPnN0YXRlID0gMDsKCXNldF9iaXQoUjFCSU9fSXNTeW5jLCAmcjFfYmlvLT5zdGF0ZSk7CgoJZm9yIChpPTA7IGkgPCBjb25mLT5yYWlkX2Rpc2tzOyBpKyspIHsKCQltZGtfcmRldl90ICpyZGV2OwoJCWJpbyA9IHIxX2Jpby0+Ymlvc1tpXTsKCgkJLyogdGFrZSBmcm9tIGJpb19pbml0ICovCgkJYmlvLT5iaV9uZXh0ID0gTlVMTDsKCQliaW8tPmJpX2ZsYWdzIHw9IDEgPDwgQklPX1VQVE9EQVRFOwoJCWJpby0+YmlfcncgPSBSRUFEOwoJCWJpby0+YmlfdmNudCA9IDA7CgkJYmlvLT5iaV9pZHggPSAwOwoJCWJpby0+YmlfcGh5c19zZWdtZW50cyA9IDA7CgkJYmlvLT5iaV9od19zZWdtZW50cyA9IDA7CgkJYmlvLT5iaV9zaXplID0gMDsKCQliaW8tPmJpX2VuZF9pbyA9IE5VTEw7CgkJYmlvLT5iaV9wcml2YXRlID0gTlVMTDsKCgkJcmRldiA9IHJjdV9kZXJlZmVyZW5jZShjb25mLT5taXJyb3JzW2ldLnJkZXYpOwoJCWlmIChyZGV2ID09IE5VTEwgfHwKCQkJICAgdGVzdF9iaXQoRmF1bHR5LCAmcmRldi0+ZmxhZ3MpKSB7CgkJCXN0aWxsX2RlZ3JhZGVkID0gMTsKCQkJY29udGludWU7CgkJfSBlbHNlIGlmICghdGVzdF9iaXQoSW5fc3luYywgJnJkZXYtPmZsYWdzKSkgewoJCQliaW8tPmJpX3J3ID0gV1JJVEU7CgkJCWJpby0+YmlfZW5kX2lvID0gZW5kX3N5bmNfd3JpdGU7CgkJCXdyaXRlX3RhcmdldHMgKys7CgkJfSBlbHNlIHsKCQkJLyogbWF5IG5lZWQgdG8gcmVhZCBmcm9tIGhlcmUgKi8KCQkJYmlvLT5iaV9ydyA9IFJFQUQ7CgkJCWJpby0+YmlfZW5kX2lvID0gZW5kX3N5bmNfcmVhZDsKCQkJaWYgKHRlc3RfYml0KFdyaXRlTW9zdGx5LCAmcmRldi0+ZmxhZ3MpKSB7CgkJCQlpZiAod29ubHkgPCAwKQoJCQkJCXdvbmx5ID0gaTsKCQkJfSBlbHNlIHsKCQkJCWlmIChkaXNrIDwgMCkKCQkJCQlkaXNrID0gaTsKCQkJfQoJCQlyZWFkX3RhcmdldHMrKzsKCQl9CgkJYXRvbWljX2luYygmcmRldi0+bnJfcGVuZGluZyk7CgkJYmlvLT5iaV9zZWN0b3IgPSBzZWN0b3JfbnIgKyByZGV2LT5kYXRhX29mZnNldDsKCQliaW8tPmJpX2JkZXYgPSByZGV2LT5iZGV2OwoJCWJpby0+YmlfcHJpdmF0ZSA9IHIxX2JpbzsKCX0KCXJjdV9yZWFkX3VubG9jaygpOwoJaWYgKGRpc2sgPCAwKQoJCWRpc2sgPSB3b25seTsKCXIxX2Jpby0+cmVhZF9kaXNrID0gZGlzazsKCglpZiAodGVzdF9iaXQoTURfUkVDT1ZFUllfU1lOQywgJm1kZGV2LT5yZWNvdmVyeSkgJiYgcmVhZF90YXJnZXRzID4gMCkKCQkvKiBleHRyYSByZWFkIHRhcmdldHMgYXJlIGFsc28gd3JpdGUgdGFyZ2V0cyAqLwoJCXdyaXRlX3RhcmdldHMgKz0gcmVhZF90YXJnZXRzLTE7CgoJaWYgKHdyaXRlX3RhcmdldHMgPT0gMCB8fCByZWFkX3RhcmdldHMgPT0gMCkgewoJCS8qIFRoZXJlIGlzIG5vd2hlcmUgdG8gd3JpdGUsIHNvIGFsbCBub24tc3luYwoJCSAqIGRyaXZlcyBtdXN0IGJlIGZhaWxlZCAtIHNvIHdlIGFyZSBmaW5pc2hlZAoJCSAqLwoJCXNlY3Rvcl90IHJ2ID0gbWF4X3NlY3RvciAtIHNlY3Rvcl9ucjsKCQkqc2tpcHBlZCA9IDE7CgkJcHV0X2J1ZihyMV9iaW8pOwoJCXJldHVybiBydjsKCX0KCglucl9zZWN0b3JzID0gMDsKCXN5bmNfYmxvY2tzID0gMDsKCWRvIHsKCQlzdHJ1Y3QgcGFnZSAqcGFnZTsKCQlpbnQgbGVuID0gUEFHRV9TSVpFOwoJCWlmIChzZWN0b3JfbnIgKyAobGVuPj45KSA+IG1heF9zZWN0b3IpCgkJCWxlbiA9IChtYXhfc2VjdG9yIC0gc2VjdG9yX25yKSA8PCA5OwoJCWlmIChsZW4gPT0gMCkKCQkJYnJlYWs7CgkJaWYgKHN5bmNfYmxvY2tzID09IDApIHsKCQkJaWYgKCFiaXRtYXBfc3RhcnRfc3luYyhtZGRldi0+Yml0bWFwLCBzZWN0b3JfbnIsCgkJCQkJICAgICAgICZzeW5jX2Jsb2Nrcywgc3RpbGxfZGVncmFkZWQpICYmCgkJCSAgICAhY29uZi0+ZnVsbHN5bmMgJiYKCQkJICAgICF0ZXN0X2JpdChNRF9SRUNPVkVSWV9SRVFVRVNURUQsICZtZGRldi0+cmVjb3ZlcnkpKQoJCQkJYnJlYWs7CgkJCUJVR19PTihzeW5jX2Jsb2NrcyA8IChQQUdFX1NJWkU+PjkpKTsKCQkJaWYgKGxlbiA+IChzeW5jX2Jsb2Nrczw8OSkpCgkJCQlsZW4gPSBzeW5jX2Jsb2Nrczw8OTsKCQl9CgoJCWZvciAoaT0wIDsgaSA8IGNvbmYtPnJhaWRfZGlza3M7IGkrKykgewoJCQliaW8gPSByMV9iaW8tPmJpb3NbaV07CgkJCWlmIChiaW8tPmJpX2VuZF9pbykgewoJCQkJcGFnZSA9IGJpby0+YmlfaW9fdmVjW2Jpby0+YmlfdmNudF0uYnZfcGFnZTsKCQkJCWlmIChiaW9fYWRkX3BhZ2UoYmlvLCBwYWdlLCBsZW4sIDApID09IDApIHsKCQkJCQkvKiBzdG9wIGhlcmUgKi8KCQkJCQliaW8tPmJpX2lvX3ZlY1tiaW8tPmJpX3ZjbnRdLmJ2X3BhZ2UgPSBwYWdlOwoJCQkJCXdoaWxlIChpID4gMCkgewoJCQkJCQlpLS07CgkJCQkJCWJpbyA9IHIxX2Jpby0+Ymlvc1tpXTsKCQkJCQkJaWYgKGJpby0+YmlfZW5kX2lvPT1OVUxMKQoJCQkJCQkJY29udGludWU7CgkJCQkJCS8qIHJlbW92ZSBsYXN0IHBhZ2UgZnJvbSB0aGlzIGJpbyAqLwoJCQkJCQliaW8tPmJpX3ZjbnQtLTsKCQkJCQkJYmlvLT5iaV9zaXplIC09IGxlbjsKCQkJCQkJYmlvLT5iaV9mbGFncyAmPSB+KDE8PCBCSU9fU0VHX1ZBTElEKTsKCQkJCQl9CgkJCQkJZ290byBiaW9fZnVsbDsKCQkJCX0KCQkJfQoJCX0KCQlucl9zZWN0b3JzICs9IGxlbj4+OTsKCQlzZWN0b3JfbnIgKz0gbGVuPj45OwoJCXN5bmNfYmxvY2tzIC09IChsZW4+PjkpOwoJfSB3aGlsZSAocjFfYmlvLT5iaW9zW2Rpc2tdLT5iaV92Y250IDwgUkVTWU5DX1BBR0VTKTsKIGJpb19mdWxsOgoJcjFfYmlvLT5zZWN0b3JzID0gbnJfc2VjdG9yczsKCgkvKiBGb3IgYSB1c2VyLXJlcXVlc3RlZCBzeW5jLCB3ZSByZWFkIGFsbCByZWFkYWJsZSBkZXZpY2VzIGFuZCBkbyBhCgkgKiBjb21wYXJlCgkgKi8KCWlmICh0ZXN0X2JpdChNRF9SRUNPVkVSWV9SRVFVRVNURUQsICZtZGRldi0+cmVjb3ZlcnkpKSB7CgkJYXRvbWljX3NldCgmcjFfYmlvLT5yZW1haW5pbmcsIHJlYWRfdGFyZ2V0cyk7CgkJZm9yIChpPTA7IGk8Y29uZi0+cmFpZF9kaXNrczsgaSsrKSB7CgkJCWJpbyA9IHIxX2Jpby0+Ymlvc1tpXTsKCQkJaWYgKGJpby0+YmlfZW5kX2lvID09IGVuZF9zeW5jX3JlYWQpIHsKCQkJCW1kX3N5bmNfYWNjdChiaW8tPmJpX2JkZXYsIG5yX3NlY3RvcnMpOwoJCQkJZ2VuZXJpY19tYWtlX3JlcXVlc3QoYmlvKTsKCQkJfQoJCX0KCX0gZWxzZSB7CgkJYXRvbWljX3NldCgmcjFfYmlvLT5yZW1haW5pbmcsIDEpOwoJCWJpbyA9IHIxX2Jpby0+Ymlvc1tyMV9iaW8tPnJlYWRfZGlza107CgkJbWRfc3luY19hY2N0KGJpby0+YmlfYmRldiwgbnJfc2VjdG9ycyk7CgkJZ2VuZXJpY19tYWtlX3JlcXVlc3QoYmlvKTsKCgl9CglyZXR1cm4gbnJfc2VjdG9yczsKfQoKc3RhdGljIGludCBydW4obWRkZXZfdCAqbWRkZXYpCnsKCWNvbmZfdCAqY29uZjsKCWludCBpLCBqLCBkaXNrX2lkeDsKCW1pcnJvcl9pbmZvX3QgKmRpc2s7CgltZGtfcmRldl90ICpyZGV2OwoJc3RydWN0IGxpc3RfaGVhZCAqdG1wOwoKCWlmIChtZGRldi0+bGV2ZWwgIT0gMSkgewoJCXByaW50aygicmFpZDE6ICVzOiByYWlkIGxldmVsIG5vdCBzZXQgdG8gbWlycm9yaW5nICglZClcbiIsCgkJICAgICAgIG1kbmFtZShtZGRldiksIG1kZGV2LT5sZXZlbCk7CgkJZ290byBvdXQ7Cgl9CglpZiAobWRkZXYtPnJlc2hhcGVfcG9zaXRpb24gIT0gTWF4U2VjdG9yKSB7CgkJcHJpbnRrKCJyYWlkMTogJXM6IHJlc2hhcGVfcG9zaXRpb24gc2V0IGJ1dCBub3Qgc3VwcG9ydGVkXG4iLAoJCSAgICAgICBtZG5hbWUobWRkZXYpKTsKCQlnb3RvIG91dDsKCX0KCS8qCgkgKiBjb3B5IHRoZSBhbHJlYWR5IHZlcmlmaWVkIGRldmljZXMgaW50byBvdXIgcHJpdmF0ZSBSQUlEMQoJICogYm9va2tlZXBpbmcgYXJlYS4gW3doYXRldmVyIHdlIGFsbG9jYXRlIGluIHJ1bigpLAoJICogc2hvdWxkIGJlIGZyZWVkIGluIHN0b3AoKV0KCSAqLwoJY29uZiA9IGt6YWxsb2Moc2l6ZW9mKGNvbmZfdCksIEdGUF9LRVJORUwpOwoJbWRkZXYtPnByaXZhdGUgPSBjb25mOwoJaWYgKCFjb25mKQoJCWdvdG8gb3V0X25vX21lbTsKCgljb25mLT5taXJyb3JzID0ga3phbGxvYyhzaXplb2Yoc3RydWN0IG1pcnJvcl9pbmZvKSptZGRldi0+cmFpZF9kaXNrcywKCQkJCSBHRlBfS0VSTkVMKTsKCWlmICghY29uZi0+bWlycm9ycykKCQlnb3RvIG91dF9ub19tZW07CgoJY29uZi0+dG1wcGFnZSA9IGFsbG9jX3BhZ2UoR0ZQX0tFUk5FTCk7CglpZiAoIWNvbmYtPnRtcHBhZ2UpCgkJZ290byBvdXRfbm9fbWVtOwoKCWNvbmYtPnBvb2xpbmZvID0ga21hbGxvYyhzaXplb2YoKmNvbmYtPnBvb2xpbmZvKSwgR0ZQX0tFUk5FTCk7CglpZiAoIWNvbmYtPnBvb2xpbmZvKQoJCWdvdG8gb3V0X25vX21lbTsKCWNvbmYtPnBvb2xpbmZvLT5tZGRldiA9IG1kZGV2OwoJY29uZi0+cG9vbGluZm8tPnJhaWRfZGlza3MgPSBtZGRldi0+cmFpZF9kaXNrczsKCWNvbmYtPnIxYmlvX3Bvb2wgPSBtZW1wb29sX2NyZWF0ZShOUl9SQUlEMV9CSU9TLCByMWJpb19wb29sX2FsbG9jLAoJCQkJCSAgcjFiaW9fcG9vbF9mcmVlLAoJCQkJCSAgY29uZi0+cG9vbGluZm8pOwoJaWYgKCFjb25mLT5yMWJpb19wb29sKQoJCWdvdG8gb3V0X25vX21lbTsKCglJVEVSQVRFX1JERVYobWRkZXYsIHJkZXYsIHRtcCkgewoJCWRpc2tfaWR4ID0gcmRldi0+cmFpZF9kaXNrOwoJCWlmIChkaXNrX2lkeCA+PSBtZGRldi0+cmFpZF9kaXNrcwoJCSAgICB8fCBkaXNrX2lkeCA8IDApCgkJCWNvbnRpbnVlOwoJCWRpc2sgPSBjb25mLT5taXJyb3JzICsgZGlza19pZHg7CgoJCWRpc2stPnJkZXYgPSByZGV2OwoKCQlibGtfcXVldWVfc3RhY2tfbGltaXRzKG1kZGV2LT5xdWV1ZSwKCQkJCSAgICAgICByZGV2LT5iZGV2LT5iZF9kaXNrLT5xdWV1ZSk7CgkJLyogYXMgd2UgZG9uJ3QgaG9ub3VyIG1lcmdlX2J2ZWNfZm4sIHdlIG11c3QgbmV2ZXIgcmlzawoJCSAqIHZpb2xhdGluZyBpdCwgc28gbGltaXQgLT5tYXhfc2VjdG9yIHRvIG9uZSBQQUdFLCBhcwoJCSAqIGEgb25lIHBhZ2UgcmVxdWVzdCBpcyBuZXZlciBpbiB2aW9sYXRpb24uCgkJICovCgkJaWYgKHJkZXYtPmJkZXYtPmJkX2Rpc2stPnF1ZXVlLT5tZXJnZV9idmVjX2ZuICYmCgkJICAgIG1kZGV2LT5xdWV1ZS0+bWF4X3NlY3RvcnMgPiAoUEFHRV9TSVpFPj45KSkKCQkJYmxrX3F1ZXVlX21heF9zZWN0b3JzKG1kZGV2LT5xdWV1ZSwgUEFHRV9TSVpFPj45KTsKCgkJZGlzay0+aGVhZF9wb3NpdGlvbiA9IDA7Cgl9Cgljb25mLT5yYWlkX2Rpc2tzID0gbWRkZXYtPnJhaWRfZGlza3M7Cgljb25mLT5tZGRldiA9IG1kZGV2OwoJc3Bpbl9sb2NrX2luaXQoJmNvbmYtPmRldmljZV9sb2NrKTsKCUlOSVRfTElTVF9IRUFEKCZjb25mLT5yZXRyeV9saXN0KTsKCglzcGluX2xvY2tfaW5pdCgmY29uZi0+cmVzeW5jX2xvY2spOwoJaW5pdF93YWl0cXVldWVfaGVhZCgmY29uZi0+d2FpdF9iYXJyaWVyKTsKCgliaW9fbGlzdF9pbml0KCZjb25mLT5wZW5kaW5nX2Jpb19saXN0KTsKCWJpb19saXN0X2luaXQoJmNvbmYtPmZsdXNoaW5nX2Jpb19saXN0KTsKCgoJbWRkZXYtPmRlZ3JhZGVkID0gMDsKCWZvciAoaSA9IDA7IGkgPCBjb25mLT5yYWlkX2Rpc2tzOyBpKyspIHsKCgkJZGlzayA9IGNvbmYtPm1pcnJvcnMgKyBpOwoKCQlpZiAoIWRpc2stPnJkZXYgfHwKCQkgICAgIXRlc3RfYml0KEluX3N5bmMsICZkaXNrLT5yZGV2LT5mbGFncykpIHsKCQkJZGlzay0+aGVhZF9wb3NpdGlvbiA9IDA7CgkJCW1kZGV2LT5kZWdyYWRlZCsrOwoJCQlpZiAoZGlzay0+cmRldikKCQkJCWNvbmYtPmZ1bGxzeW5jID0gMTsKCQl9Cgl9CglpZiAobWRkZXYtPmRlZ3JhZGVkID09IGNvbmYtPnJhaWRfZGlza3MpIHsKCQlwcmludGsoS0VSTl9FUlIgInJhaWQxOiBubyBvcGVyYXRpb25hbCBtaXJyb3JzIGZvciAlc1xuIiwKCQkJbWRuYW1lKG1kZGV2KSk7CgkJZ290byBvdXRfZnJlZV9jb25mOwoJfQoJaWYgKGNvbmYtPnJhaWRfZGlza3MgLSBtZGRldi0+ZGVncmFkZWQgPT0gMSkKCQltZGRldi0+cmVjb3ZlcnlfY3AgPSBNYXhTZWN0b3I7CgoJLyoKCSAqIGZpbmQgdGhlIGZpcnN0IHdvcmtpbmcgb25lIGFuZCB1c2UgaXQgYXMgYSBzdGFydGluZyBwb2ludAoJICogdG8gcmVhZCBiYWxhbmNpbmcuCgkgKi8KCWZvciAoaiA9IDA7IGogPCBjb25mLT5yYWlkX2Rpc2tzICYmCgkJICAgICAoIWNvbmYtPm1pcnJvcnNbal0ucmRldiB8fAoJCSAgICAgICF0ZXN0X2JpdChJbl9zeW5jLCAmY29uZi0+bWlycm9yc1tqXS5yZGV2LT5mbGFncykpIDsgaisrKQoJCS8qIG5vdGhpbmcgKi87Cgljb25mLT5sYXN0X3VzZWQgPSBqOwoKCgltZGRldi0+dGhyZWFkID0gbWRfcmVnaXN0ZXJfdGhyZWFkKHJhaWQxZCwgbWRkZXYsICIlc19yYWlkMSIpOwoJaWYgKCFtZGRldi0+dGhyZWFkKSB7CgkJcHJpbnRrKEtFUk5fRVJSCgkJICAgICAgICJyYWlkMTogY291bGRuJ3QgYWxsb2NhdGUgdGhyZWFkIGZvciAlc1xuIiwKCQkgICAgICAgbWRuYW1lKG1kZGV2KSk7CgkJZ290byBvdXRfZnJlZV9jb25mOwoJfQoKCXByaW50ayhLRVJOX0lORk8gCgkJInJhaWQxOiByYWlkIHNldCAlcyBhY3RpdmUgd2l0aCAlZCBvdXQgb2YgJWQgbWlycm9yc1xuIiwKCQltZG5hbWUobWRkZXYpLCBtZGRldi0+cmFpZF9kaXNrcyAtIG1kZGV2LT5kZWdyYWRlZCwgCgkJbWRkZXYtPnJhaWRfZGlza3MpOwoJLyoKCSAqIE9rLCBldmVyeXRoaW5nIGlzIGp1c3QgZmluZSBub3cKCSAqLwoJbWRkZXYtPmFycmF5X3NpemUgPSBtZGRldi0+c2l6ZTsKCgltZGRldi0+cXVldWUtPnVucGx1Z19mbiA9IHJhaWQxX3VucGx1ZzsKCW1kZGV2LT5xdWV1ZS0+YmFja2luZ19kZXZfaW5mby5jb25nZXN0ZWRfZm4gPSByYWlkMV9jb25nZXN0ZWQ7CgltZGRldi0+cXVldWUtPmJhY2tpbmdfZGV2X2luZm8uY29uZ2VzdGVkX2RhdGEgPSBtZGRldjsKCglyZXR1cm4gMDsKCm91dF9ub19tZW06CglwcmludGsoS0VSTl9FUlIgInJhaWQxOiBjb3VsZG4ndCBhbGxvY2F0ZSBtZW1vcnkgZm9yICVzXG4iLAoJICAgICAgIG1kbmFtZShtZGRldikpOwoKb3V0X2ZyZWVfY29uZjoKCWlmIChjb25mKSB7CgkJaWYgKGNvbmYtPnIxYmlvX3Bvb2wpCgkJCW1lbXBvb2xfZGVzdHJveShjb25mLT5yMWJpb19wb29sKTsKCQlrZnJlZShjb25mLT5taXJyb3JzKTsKCQlzYWZlX3B1dF9wYWdlKGNvbmYtPnRtcHBhZ2UpOwoJCWtmcmVlKGNvbmYtPnBvb2xpbmZvKTsKCQlrZnJlZShjb25mKTsKCQltZGRldi0+cHJpdmF0ZSA9IE5VTEw7Cgl9Cm91dDoKCXJldHVybiAtRUlPOwp9CgpzdGF0aWMgaW50IHN0b3AobWRkZXZfdCAqbWRkZXYpCnsKCWNvbmZfdCAqY29uZiA9IG1kZGV2X3RvX2NvbmYobWRkZXYpOwoJc3RydWN0IGJpdG1hcCAqYml0bWFwID0gbWRkZXYtPmJpdG1hcDsKCWludCBiZWhpbmRfd2FpdCA9IDA7CgoJLyogd2FpdCBmb3IgYmVoaW5kIHdyaXRlcyB0byBjb21wbGV0ZSAqLwoJd2hpbGUgKGJpdG1hcCAmJiBhdG9taWNfcmVhZCgmYml0bWFwLT5iZWhpbmRfd3JpdGVzKSA+IDApIHsKCQliZWhpbmRfd2FpdCsrOwoJCXByaW50ayhLRVJOX0lORk8gInJhaWQxOiBiZWhpbmQgd3JpdGVzIGluIHByb2dyZXNzIG9uIGRldmljZSAlcywgd2FpdGluZyB0byBzdG9wICglZClcbiIsIG1kbmFtZShtZGRldiksIGJlaGluZF93YWl0KTsKCQlzZXRfY3VycmVudF9zdGF0ZShUQVNLX1VOSU5URVJSVVBUSUJMRSk7CgkJc2NoZWR1bGVfdGltZW91dChIWik7IC8qIHdhaXQgYSBzZWNvbmQgKi8KCQkvKiBuZWVkIHRvIGtpY2sgc29tZXRoaW5nIGhlcmUgdG8gbWFrZSBzdXJlIEkvTyBnb2VzPyAqLwoJfQoKCW1kX3VucmVnaXN0ZXJfdGhyZWFkKG1kZGV2LT50aHJlYWQpOwoJbWRkZXYtPnRocmVhZCA9IE5VTEw7CglibGtfc3luY19xdWV1ZShtZGRldi0+cXVldWUpOyAvKiB0aGUgdW5wbHVnIGZuIHJlZmVyZW5jZXMgJ2NvbmYnKi8KCWlmIChjb25mLT5yMWJpb19wb29sKQoJCW1lbXBvb2xfZGVzdHJveShjb25mLT5yMWJpb19wb29sKTsKCWtmcmVlKGNvbmYtPm1pcnJvcnMpOwoJa2ZyZWUoY29uZi0+cG9vbGluZm8pOwoJa2ZyZWUoY29uZik7CgltZGRldi0+cHJpdmF0ZSA9IE5VTEw7CglyZXR1cm4gMDsKfQoKc3RhdGljIGludCByYWlkMV9yZXNpemUobWRkZXZfdCAqbWRkZXYsIHNlY3Rvcl90IHNlY3RvcnMpCnsKCS8qIG5vIHJlc3luYyBpcyBoYXBwZW5pbmcsIGFuZCB0aGVyZSBpcyBlbm91Z2ggc3BhY2UKCSAqIG9uIGFsbCBkZXZpY2VzLCBzbyB3ZSBjYW4gcmVzaXplLgoJICogV2UgbmVlZCB0byBtYWtlIHN1cmUgcmVzeW5jIGNvdmVycyBhbnkgbmV3IHNwYWNlLgoJICogSWYgdGhlIGFycmF5IGlzIHNocmlua2luZyB3ZSBzaG91bGQgcG9zc2libHkgd2FpdCB1bnRpbAoJICogYW55IGlvIGluIHRoZSByZW1vdmVkIHNwYWNlIGNvbXBsZXRlcywgYnV0IGl0IGhhcmRseSBzZWVtcwoJICogd29ydGggaXQuCgkgKi8KCW1kZGV2LT5hcnJheV9zaXplID0gc2VjdG9ycz4+MTsKCXNldF9jYXBhY2l0eShtZGRldi0+Z2VuZGlzaywgbWRkZXYtPmFycmF5X3NpemUgPDwgMSk7CgltZGRldi0+Y2hhbmdlZCA9IDE7CglpZiAobWRkZXYtPmFycmF5X3NpemUgPiBtZGRldi0+c2l6ZSAmJiBtZGRldi0+cmVjb3ZlcnlfY3AgPT0gTWF4U2VjdG9yKSB7CgkJbWRkZXYtPnJlY292ZXJ5X2NwID0gbWRkZXYtPnNpemUgPDwgMTsKCQlzZXRfYml0KE1EX1JFQ09WRVJZX05FRURFRCwgJm1kZGV2LT5yZWNvdmVyeSk7Cgl9CgltZGRldi0+c2l6ZSA9IG1kZGV2LT5hcnJheV9zaXplOwoJbWRkZXYtPnJlc3luY19tYXhfc2VjdG9ycyA9IHNlY3RvcnM7CglyZXR1cm4gMDsKfQoKc3RhdGljIGludCByYWlkMV9yZXNoYXBlKG1kZGV2X3QgKm1kZGV2KQp7CgkvKiBXZSBuZWVkIHRvOgoJICogMS8gcmVzaXplIHRoZSByMWJpb19wb29sCgkgKiAyLyByZXNpemUgY29uZi0+bWlycm9ycwoJICoKCSAqIFdlIGFsbG9jYXRlIGEgbmV3IHIxYmlvX3Bvb2wgaWYgd2UgY2FuLgoJICogVGhlbiByYWlzZSBhIGRldmljZSBiYXJyaWVyIGFuZCB3YWl0IHVudGlsIGFsbCBJTyBzdG9wcy4KCSAqIFRoZW4gcmVzaXplIGNvbmYtPm1pcnJvcnMgYW5kIHN3YXAgaW4gdGhlIG5ldyByMWJpbyBwb29sLgoJICoKCSAqIEF0IHRoZSBzYW1lIHRpbWUsIHdlICJwYWNrIiB0aGUgZGV2aWNlcyBzbyB0aGF0IGFsbCB0aGUgbWlzc2luZwoJICogZGV2aWNlcyBoYXZlIHRoZSBoaWdoZXIgcmFpZF9kaXNrIG51bWJlcnMuCgkgKi8KCW1lbXBvb2xfdCAqbmV3cG9vbCwgKm9sZHBvb2w7CglzdHJ1Y3QgcG9vbF9pbmZvICpuZXdwb29saW5mbzsKCW1pcnJvcl9pbmZvX3QgKm5ld21pcnJvcnM7Cgljb25mX3QgKmNvbmYgPSBtZGRldl90b19jb25mKG1kZGV2KTsKCWludCBjbnQsIHJhaWRfZGlza3M7Cgl1bnNpZ25lZCBsb25nIGZsYWdzOwoJaW50IGQsIGQyOwoKCS8qIENhbm5vdCBjaGFuZ2UgY2h1bmtfc2l6ZSwgbGF5b3V0LCBvciBsZXZlbCAqLwoJaWYgKG1kZGV2LT5jaHVua19zaXplICE9IG1kZGV2LT5uZXdfY2h1bmsgfHwKCSAgICBtZGRldi0+bGF5b3V0ICE9IG1kZGV2LT5uZXdfbGF5b3V0IHx8CgkgICAgbWRkZXYtPmxldmVsICE9IG1kZGV2LT5uZXdfbGV2ZWwpIHsKCQltZGRldi0+bmV3X2NodW5rID0gbWRkZXYtPmNodW5rX3NpemU7CgkJbWRkZXYtPm5ld19sYXlvdXQgPSBtZGRldi0+bGF5b3V0OwoJCW1kZGV2LT5uZXdfbGV2ZWwgPSBtZGRldi0+bGV2ZWw7CgkJcmV0dXJuIC1FSU5WQUw7Cgl9CgoJbWRfYWxsb3dfd3JpdGUobWRkZXYpOwoKCXJhaWRfZGlza3MgPSBtZGRldi0+cmFpZF9kaXNrcyArIG1kZGV2LT5kZWx0YV9kaXNrczsKCglpZiAocmFpZF9kaXNrcyA8IGNvbmYtPnJhaWRfZGlza3MpIHsKCQljbnQ9MDsKCQlmb3IgKGQ9IDA7IGQgPCBjb25mLT5yYWlkX2Rpc2tzOyBkKyspCgkJCWlmIChjb25mLT5taXJyb3JzW2RdLnJkZXYpCgkJCQljbnQrKzsKCQlpZiAoY250ID4gcmFpZF9kaXNrcykKCQkJcmV0dXJuIC1FQlVTWTsKCX0KCgluZXdwb29saW5mbyA9IGttYWxsb2Moc2l6ZW9mKCpuZXdwb29saW5mbyksIEdGUF9LRVJORUwpOwoJaWYgKCFuZXdwb29saW5mbykKCQlyZXR1cm4gLUVOT01FTTsKCW5ld3Bvb2xpbmZvLT5tZGRldiA9IG1kZGV2OwoJbmV3cG9vbGluZm8tPnJhaWRfZGlza3MgPSByYWlkX2Rpc2tzOwoKCW5ld3Bvb2wgPSBtZW1wb29sX2NyZWF0ZShOUl9SQUlEMV9CSU9TLCByMWJpb19wb29sX2FsbG9jLAoJCQkJIHIxYmlvX3Bvb2xfZnJlZSwgbmV3cG9vbGluZm8pOwoJaWYgKCFuZXdwb29sKSB7CgkJa2ZyZWUobmV3cG9vbGluZm8pOwoJCXJldHVybiAtRU5PTUVNOwoJfQoJbmV3bWlycm9ycyA9IGt6YWxsb2Moc2l6ZW9mKHN0cnVjdCBtaXJyb3JfaW5mbykgKiByYWlkX2Rpc2tzLCBHRlBfS0VSTkVMKTsKCWlmICghbmV3bWlycm9ycykgewoJCWtmcmVlKG5ld3Bvb2xpbmZvKTsKCQltZW1wb29sX2Rlc3Ryb3kobmV3cG9vbCk7CgkJcmV0dXJuIC1FTk9NRU07Cgl9CgoJcmFpc2VfYmFycmllcihjb25mKTsKCgkvKiBvaywgZXZlcnl0aGluZyBpcyBzdG9wcGVkICovCglvbGRwb29sID0gY29uZi0+cjFiaW9fcG9vbDsKCWNvbmYtPnIxYmlvX3Bvb2wgPSBuZXdwb29sOwoKCWZvciAoZCA9IGQyID0gMDsgZCA8IGNvbmYtPnJhaWRfZGlza3M7IGQrKykgewoJCW1ka19yZGV2X3QgKnJkZXYgPSBjb25mLT5taXJyb3JzW2RdLnJkZXY7CgkJaWYgKHJkZXYgJiYgcmRldi0+cmFpZF9kaXNrICE9IGQyKSB7CgkJCWNoYXIgbm1bMjBdOwoJCQlzcHJpbnRmKG5tLCAicmQlZCIsIHJkZXYtPnJhaWRfZGlzayk7CgkJCXN5c2ZzX3JlbW92ZV9saW5rKCZtZGRldi0+a29iaiwgbm0pOwoJCQlyZGV2LT5yYWlkX2Rpc2sgPSBkMjsKCQkJc3ByaW50ZihubSwgInJkJWQiLCByZGV2LT5yYWlkX2Rpc2spOwoJCQlzeXNmc19yZW1vdmVfbGluaygmbWRkZXYtPmtvYmosIG5tKTsKCQkJaWYgKHN5c2ZzX2NyZWF0ZV9saW5rKCZtZGRldi0+a29iaiwKCQkJCQkgICAgICAmcmRldi0+a29iaiwgbm0pKQoJCQkJcHJpbnRrKEtFUk5fV0FSTklORwoJCQkJICAgICAgICJtZC9yYWlkMTogY2Fubm90IHJlZ2lzdGVyICIKCQkJCSAgICAgICAiJXMgZm9yICVzXG4iLAoJCQkJICAgICAgIG5tLCBtZG5hbWUobWRkZXYpKTsKCQl9CgkJaWYgKHJkZXYpCgkJCW5ld21pcnJvcnNbZDIrK10ucmRldiA9IHJkZXY7Cgl9CglrZnJlZShjb25mLT5taXJyb3JzKTsKCWNvbmYtPm1pcnJvcnMgPSBuZXdtaXJyb3JzOwoJa2ZyZWUoY29uZi0+cG9vbGluZm8pOwoJY29uZi0+cG9vbGluZm8gPSBuZXdwb29saW5mbzsKCglzcGluX2xvY2tfaXJxc2F2ZSgmY29uZi0+ZGV2aWNlX2xvY2ssIGZsYWdzKTsKCW1kZGV2LT5kZWdyYWRlZCArPSAocmFpZF9kaXNrcyAtIGNvbmYtPnJhaWRfZGlza3MpOwoJc3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmY29uZi0+ZGV2aWNlX2xvY2ssIGZsYWdzKTsKCWNvbmYtPnJhaWRfZGlza3MgPSBtZGRldi0+cmFpZF9kaXNrcyA9IHJhaWRfZGlza3M7CgltZGRldi0+ZGVsdGFfZGlza3MgPSAwOwoKCWNvbmYtPmxhc3RfdXNlZCA9IDA7IC8qIGp1c3QgbWFrZSBzdXJlIGl0IGlzIGluLXJhbmdlICovCglsb3dlcl9iYXJyaWVyKGNvbmYpOwoKCXNldF9iaXQoTURfUkVDT1ZFUllfTkVFREVELCAmbWRkZXYtPnJlY292ZXJ5KTsKCW1kX3dha2V1cF90aHJlYWQobWRkZXYtPnRocmVhZCk7CgoJbWVtcG9vbF9kZXN0cm95KG9sZHBvb2wpOwoJcmV0dXJuIDA7Cn0KCnN0YXRpYyB2b2lkIHJhaWQxX3F1aWVzY2UobWRkZXZfdCAqbWRkZXYsIGludCBzdGF0ZSkKewoJY29uZl90ICpjb25mID0gbWRkZXZfdG9fY29uZihtZGRldik7CgoJc3dpdGNoKHN0YXRlKSB7CgljYXNlIDE6CgkJcmFpc2VfYmFycmllcihjb25mKTsKCQlicmVhazsKCWNhc2UgMDoKCQlsb3dlcl9iYXJyaWVyKGNvbmYpOwoJCWJyZWFrOwoJfQp9CgoKc3RhdGljIHN0cnVjdCBtZGtfcGVyc29uYWxpdHkgcmFpZDFfcGVyc29uYWxpdHkgPQp7CgkubmFtZQkJPSAicmFpZDEiLAoJLmxldmVsCQk9IDEsCgkub3duZXIJCT0gVEhJU19NT0RVTEUsCgkubWFrZV9yZXF1ZXN0CT0gbWFrZV9yZXF1ZXN0LAoJLnJ1bgkJPSBydW4sCgkuc3RvcAkJPSBzdG9wLAoJLnN0YXR1cwkJPSBzdGF0dXMsCgkuZXJyb3JfaGFuZGxlcgk9IGVycm9yLAoJLmhvdF9hZGRfZGlzawk9IHJhaWQxX2FkZF9kaXNrLAoJLmhvdF9yZW1vdmVfZGlzaz0gcmFpZDFfcmVtb3ZlX2Rpc2ssCgkuc3BhcmVfYWN0aXZlCT0gcmFpZDFfc3BhcmVfYWN0aXZlLAoJLnN5bmNfcmVxdWVzdAk9IHN5bmNfcmVxdWVzdCwKCS5yZXNpemUJCT0gcmFpZDFfcmVzaXplLAoJLmNoZWNrX3Jlc2hhcGUJPSByYWlkMV9yZXNoYXBlLAoJLnF1aWVzY2UJPSByYWlkMV9xdWllc2NlLAp9OwoKc3RhdGljIGludCBfX2luaXQgcmFpZF9pbml0KHZvaWQpCnsKCXJldHVybiByZWdpc3Rlcl9tZF9wZXJzb25hbGl0eSgmcmFpZDFfcGVyc29uYWxpdHkpOwp9CgpzdGF0aWMgdm9pZCByYWlkX2V4aXQodm9pZCkKewoJdW5yZWdpc3Rlcl9tZF9wZXJzb25hbGl0eSgmcmFpZDFfcGVyc29uYWxpdHkpOwp9Cgptb2R1bGVfaW5pdChyYWlkX2luaXQpOwptb2R1bGVfZXhpdChyYWlkX2V4aXQpOwpNT0RVTEVfTElDRU5TRSgiR1BMIik7Ck1PRFVMRV9BTElBUygibWQtcGVyc29uYWxpdHktMyIpOyAvKiBSQUlEMSAqLwpNT0RVTEVfQUxJQVMoIm1kLXJhaWQxIik7Ck1PRFVMRV9BTElBUygibWQtbGV2ZWwtMSIpOwo=