LyoKICogcmFpZDEuYyA6IE11bHRpcGxlIERldmljZXMgZHJpdmVyIGZvciBMaW51eAogKgogKiBDb3B5cmlnaHQgKEMpIDE5OTksIDIwMDAsIDIwMDEgSW5nbyBNb2xuYXIsIFJlZCBIYXQKICoKICogQ29weXJpZ2h0IChDKSAxOTk2LCAxOTk3LCAxOTk4IEluZ28gTW9sbmFyLCBNaWd1ZWwgZGUgSWNhemEsIEdhZGkgT3htYW4KICoKICogUkFJRC0xIG1hbmFnZW1lbnQgZnVuY3Rpb25zLgogKgogKiBCZXR0ZXIgcmVhZC1iYWxhbmNpbmcgY29kZSB3cml0dGVuIGJ5IE1pa2EgS3VvcHBhbGEgPG1pa3VAaWtpLmZpPiwgMjAwMAogKgogKiBGaXhlcyB0byByZWNvbnN0cnVjdGlvbiBieSBKYWtvYiDYc3RlcmdhYXJkIiA8amFrb2JAb3N0ZW5mZWxkLmRrPgogKiBWYXJpb3VzIGZpeGVzIGJ5IE5laWwgQnJvd24gPG5laWxiQGNzZS51bnN3LmVkdS5hdT4KICoKICogQ2hhbmdlcyBieSBQZXRlciBULiBCcmV1ZXIgPHB0YkBpdC51YzNtLmVzPiAzMS8xLzIwMDMgdG8gc3VwcG9ydAogKiBiaXRtYXBwZWQgaW50ZWxsaWdlbmNlIGluIHJlc3luYzoKICoKICogICAgICAtIGJpdG1hcCBtYXJrZWQgZHVyaW5nIG5vcm1hbCBpL28KICogICAgICAtIGJpdG1hcCB1c2VkIHRvIHNraXAgbm9uZGlydHkgYmxvY2tzIGR1cmluZyBzeW5jCiAqCiAqIEFkZGl0aW9ucyB0byBiaXRtYXAgY29kZSwgKEMpIDIwMDMtMjAwNCBQYXVsIENsZW1lbnRzLCBTdGVlbEV5ZSBUZWNobm9sb2d5OgogKiAtIHBlcnNpc3RlbnQgYml0bWFwIGNvZGUKICoKICogVGhpcyBwcm9ncmFtIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkKICogaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkKICogdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyIHZlcnNpb24gMiwgb3IgKGF0IHlvdXIgb3B0aW9uKQogKiBhbnkgbGF0ZXIgdmVyc2lvbi4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogKGZvciBleGFtcGxlIC91c3Ivc3JjL2xpbnV4L0NPUFlJTkcpOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlCiAqIFNvZnR3YXJlIEZvdW5kYXRpb24sIEluYy4sIDY3NSBNYXNzIEF2ZSwgQ2FtYnJpZGdlLCBNQSAwMjEzOSwgVVNBLgogKi8KCiNpbmNsdWRlICJkbS1iaW8tbGlzdC5oIgojaW5jbHVkZSA8bGludXgvcmFpZC9yYWlkMS5oPgojaW5jbHVkZSA8bGludXgvcmFpZC9iaXRtYXAuaD4KCiNkZWZpbmUgREVCVUcgMAojaWYgREVCVUcKI2RlZmluZSBQUklOVEsoeC4uLikgcHJpbnRrKHgpCiNlbHNlCiNkZWZpbmUgUFJJTlRLKHguLi4pCiNlbmRpZgoKLyoKICogTnVtYmVyIG9mIGd1YXJhbnRlZWQgcjFiaW9zIGluIGNhc2Ugb2YgZXh0cmVtZSBWTSBsb2FkOgogKi8KI2RlZmluZQlOUl9SQUlEMV9CSU9TIDI1NgoKc3RhdGljIG1ka19wZXJzb25hbGl0eV90IHJhaWQxX3BlcnNvbmFsaXR5OwoKc3RhdGljIHZvaWQgdW5wbHVnX3NsYXZlcyhtZGRldl90ICptZGRldik7CgoKc3RhdGljIHZvaWQgKiByMWJpb19wb29sX2FsbG9jKGdmcF90IGdmcF9mbGFncywgdm9pZCAqZGF0YSkKewoJc3RydWN0IHBvb2xfaW5mbyAqcGkgPSBkYXRhOwoJcjFiaW9fdCAqcjFfYmlvOwoJaW50IHNpemUgPSBvZmZzZXRvZihyMWJpb190LCBiaW9zW3BpLT5yYWlkX2Rpc2tzXSk7CgoJLyogYWxsb2NhdGUgYSByMWJpbyB3aXRoIHJvb20gZm9yIHJhaWRfZGlza3MgZW50cmllcyBpbiB0aGUgYmlvcyBhcnJheSAqLwoJcjFfYmlvID0ga21hbGxvYyhzaXplLCBnZnBfZmxhZ3MpOwoJaWYgKHIxX2JpbykKCQltZW1zZXQocjFfYmlvLCAwLCBzaXplKTsKCWVsc2UKCQl1bnBsdWdfc2xhdmVzKHBpLT5tZGRldik7CgoJcmV0dXJuIHIxX2JpbzsKfQoKc3RhdGljIHZvaWQgcjFiaW9fcG9vbF9mcmVlKHZvaWQgKnIxX2Jpbywgdm9pZCAqZGF0YSkKewoJa2ZyZWUocjFfYmlvKTsKfQoKI2RlZmluZSBSRVNZTkNfQkxPQ0tfU0laRSAoNjQqMTAyNCkKLy8jZGVmaW5lIFJFU1lOQ19CTE9DS19TSVpFIFBBR0VfU0laRQojZGVmaW5lIFJFU1lOQ19TRUNUT1JTIChSRVNZTkNfQkxPQ0tfU0laRSA+PiA5KQojZGVmaW5lIFJFU1lOQ19QQUdFUyAoKFJFU1lOQ19CTE9DS19TSVpFICsgUEFHRV9TSVpFLTEpIC8gUEFHRV9TSVpFKQojZGVmaW5lIFJFU1lOQ19XSU5ET1cgKDIwNDgqMTAyNCkKCnN0YXRpYyB2b2lkICogcjFidWZfcG9vbF9hbGxvYyhnZnBfdCBnZnBfZmxhZ3MsIHZvaWQgKmRhdGEpCnsKCXN0cnVjdCBwb29sX2luZm8gKnBpID0gZGF0YTsKCXN0cnVjdCBwYWdlICpwYWdlOwoJcjFiaW9fdCAqcjFfYmlvOwoJc3RydWN0IGJpbyAqYmlvOwoJaW50IGksIGo7CgoJcjFfYmlvID0gcjFiaW9fcG9vbF9hbGxvYyhnZnBfZmxhZ3MsIHBpKTsKCWlmICghcjFfYmlvKSB7CgkJdW5wbHVnX3NsYXZlcyhwaS0+bWRkZXYpOwoJCXJldHVybiBOVUxMOwoJfQoKCS8qCgkgKiBBbGxvY2F0ZSBiaW9zIDogMSBmb3IgcmVhZGluZywgbi0xIGZvciB3cml0aW5nCgkgKi8KCWZvciAoaiA9IHBpLT5yYWlkX2Rpc2tzIDsgai0tIDsgKSB7CgkJYmlvID0gYmlvX2FsbG9jKGdmcF9mbGFncywgUkVTWU5DX1BBR0VTKTsKCQlpZiAoIWJpbykKCQkJZ290byBvdXRfZnJlZV9iaW87CgkJcjFfYmlvLT5iaW9zW2pdID0gYmlvOwoJfQoJLyoKCSAqIEFsbG9jYXRlIFJFU1lOQ19QQUdFUyBkYXRhIHBhZ2VzIGFuZCBhdHRhY2ggdGhlbSB0bwoJICogdGhlIGZpcnN0IGJpbzsKCSAqLwoJYmlvID0gcjFfYmlvLT5iaW9zWzBdOwoJZm9yIChpID0gMDsgaSA8IFJFU1lOQ19QQUdFUzsgaSsrKSB7CgkJcGFnZSA9IGFsbG9jX3BhZ2UoZ2ZwX2ZsYWdzKTsKCQlpZiAodW5saWtlbHkoIXBhZ2UpKQoJCQlnb3RvIG91dF9mcmVlX3BhZ2VzOwoKCQliaW8tPmJpX2lvX3ZlY1tpXS5idl9wYWdlID0gcGFnZTsKCX0KCglyMV9iaW8tPm1hc3Rlcl9iaW8gPSBOVUxMOwoKCXJldHVybiByMV9iaW87CgpvdXRfZnJlZV9wYWdlczoKCWZvciAoIDsgaSA+IDAgOyBpLS0pCgkJX19mcmVlX3BhZ2UoYmlvLT5iaV9pb192ZWNbaS0xXS5idl9wYWdlKTsKb3V0X2ZyZWVfYmlvOgoJd2hpbGUgKCArK2ogPCBwaS0+cmFpZF9kaXNrcyApCgkJYmlvX3B1dChyMV9iaW8tPmJpb3Nbal0pOwoJcjFiaW9fcG9vbF9mcmVlKHIxX2JpbywgZGF0YSk7CglyZXR1cm4gTlVMTDsKfQoKc3RhdGljIHZvaWQgcjFidWZfcG9vbF9mcmVlKHZvaWQgKl9fcjFfYmlvLCB2b2lkICpkYXRhKQp7CglzdHJ1Y3QgcG9vbF9pbmZvICpwaSA9IGRhdGE7CglpbnQgaTsKCXIxYmlvX3QgKnIxYmlvID0gX19yMV9iaW87CglzdHJ1Y3QgYmlvICpiaW8gPSByMWJpby0+Ymlvc1swXTsKCglmb3IgKGkgPSAwOyBpIDwgUkVTWU5DX1BBR0VTOyBpKyspIHsKCQlfX2ZyZWVfcGFnZShiaW8tPmJpX2lvX3ZlY1tpXS5idl9wYWdlKTsKCQliaW8tPmJpX2lvX3ZlY1tpXS5idl9wYWdlID0gTlVMTDsKCX0KCWZvciAoaT0wIDsgaSA8IHBpLT5yYWlkX2Rpc2tzOyBpKyspCgkJYmlvX3B1dChyMWJpby0+Ymlvc1tpXSk7CgoJcjFiaW9fcG9vbF9mcmVlKHIxYmlvLCBkYXRhKTsKfQoKc3RhdGljIHZvaWQgcHV0X2FsbF9iaW9zKGNvbmZfdCAqY29uZiwgcjFiaW9fdCAqcjFfYmlvKQp7CglpbnQgaTsKCglmb3IgKGkgPSAwOyBpIDwgY29uZi0+cmFpZF9kaXNrczsgaSsrKSB7CgkJc3RydWN0IGJpbyAqKmJpbyA9IHIxX2Jpby0+YmlvcyArIGk7CgkJaWYgKCpiaW8pCgkJCWJpb19wdXQoKmJpbyk7CgkJKmJpbyA9IE5VTEw7Cgl9Cn0KCnN0YXRpYyBpbmxpbmUgdm9pZCBmcmVlX3IxYmlvKHIxYmlvX3QgKnIxX2JpbykKewoJdW5zaWduZWQgbG9uZyBmbGFnczsKCgljb25mX3QgKmNvbmYgPSBtZGRldl90b19jb25mKHIxX2Jpby0+bWRkZXYpOwoKCS8qCgkgKiBXYWtlIHVwIGFueSBwb3NzaWJsZSByZXN5bmMgdGhyZWFkIHRoYXQgd2FpdHMgZm9yIHRoZSBkZXZpY2UKCSAqIHRvIGdvIGlkbGUuCgkgKi8KCXNwaW5fbG9ja19pcnFzYXZlKCZjb25mLT5yZXN5bmNfbG9jaywgZmxhZ3MpOwoJaWYgKCEtLWNvbmYtPm5yX3BlbmRpbmcpIHsKCQl3YWtlX3VwKCZjb25mLT53YWl0X2lkbGUpOwoJCXdha2VfdXAoJmNvbmYtPndhaXRfcmVzdW1lKTsKCX0KCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJmNvbmYtPnJlc3luY19sb2NrLCBmbGFncyk7CgoJcHV0X2FsbF9iaW9zKGNvbmYsIHIxX2Jpbyk7CgltZW1wb29sX2ZyZWUocjFfYmlvLCBjb25mLT5yMWJpb19wb29sKTsKfQoKc3RhdGljIGlubGluZSB2b2lkIHB1dF9idWYocjFiaW9fdCAqcjFfYmlvKQp7Cgljb25mX3QgKmNvbmYgPSBtZGRldl90b19jb25mKHIxX2Jpby0+bWRkZXYpOwoJdW5zaWduZWQgbG9uZyBmbGFnczsKCgltZW1wb29sX2ZyZWUocjFfYmlvLCBjb25mLT5yMWJ1Zl9wb29sKTsKCglzcGluX2xvY2tfaXJxc2F2ZSgmY29uZi0+cmVzeW5jX2xvY2ssIGZsYWdzKTsKCWlmICghY29uZi0+YmFycmllcikKCQlCVUcoKTsKCS0tY29uZi0+YmFycmllcjsKCXdha2VfdXAoJmNvbmYtPndhaXRfcmVzdW1lKTsKCXdha2VfdXAoJmNvbmYtPndhaXRfaWRsZSk7CgoJaWYgKCEtLWNvbmYtPm5yX3BlbmRpbmcpIHsKCQl3YWtlX3VwKCZjb25mLT53YWl0X2lkbGUpOwoJCXdha2VfdXAoJmNvbmYtPndhaXRfcmVzdW1lKTsKCX0KCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJmNvbmYtPnJlc3luY19sb2NrLCBmbGFncyk7Cn0KCnN0YXRpYyB2b2lkIHJlc2NoZWR1bGVfcmV0cnkocjFiaW9fdCAqcjFfYmlvKQp7Cgl1bnNpZ25lZCBsb25nIGZsYWdzOwoJbWRkZXZfdCAqbWRkZXYgPSByMV9iaW8tPm1kZGV2OwoJY29uZl90ICpjb25mID0gbWRkZXZfdG9fY29uZihtZGRldik7CgoJc3Bpbl9sb2NrX2lycXNhdmUoJmNvbmYtPmRldmljZV9sb2NrLCBmbGFncyk7CglsaXN0X2FkZCgmcjFfYmlvLT5yZXRyeV9saXN0LCAmY29uZi0+cmV0cnlfbGlzdCk7CglzcGluX3VubG9ja19pcnFyZXN0b3JlKCZjb25mLT5kZXZpY2VfbG9jaywgZmxhZ3MpOwoKCW1kX3dha2V1cF90aHJlYWQobWRkZXYtPnRocmVhZCk7Cn0KCi8qCiAqIHJhaWRfZW5kX2Jpb19pbygpIGlzIGNhbGxlZCB3aGVuIHdlIGhhdmUgZmluaXNoZWQgc2VydmljaW5nIGEgbWlycm9yZWQKICogb3BlcmF0aW9uIGFuZCBhcmUgcmVhZHkgdG8gcmV0dXJuIGEgc3VjY2Vzcy9mYWlsdXJlIGNvZGUgdG8gdGhlIGJ1ZmZlcgogKiBjYWNoZSBsYXllci4KICovCnN0YXRpYyB2b2lkIHJhaWRfZW5kX2Jpb19pbyhyMWJpb190ICpyMV9iaW8pCnsKCXN0cnVjdCBiaW8gKmJpbyA9IHIxX2Jpby0+bWFzdGVyX2JpbzsKCgkvKiBpZiBub2JvZHkgaGFzIGRvbmUgdGhlIGZpbmFsIGVuZGlvIHlldCwgZG8gaXQgbm93ICovCglpZiAoIXRlc3RfYW5kX3NldF9iaXQoUjFCSU9fUmV0dXJuZWQsICZyMV9iaW8tPnN0YXRlKSkgewoJCVBSSU5USyhLRVJOX0RFQlVHICJyYWlkMTogc3luYyBlbmQgJXMgb24gc2VjdG9ycyAlbGx1LSVsbHVcbiIsCgkJCShiaW9fZGF0YV9kaXIoYmlvKSA9PSBXUklURSkgPyAid3JpdGUiIDogInJlYWQiLAoJCQkodW5zaWduZWQgbG9uZyBsb25nKSBiaW8tPmJpX3NlY3RvciwKCQkJKHVuc2lnbmVkIGxvbmcgbG9uZykgYmlvLT5iaV9zZWN0b3IgKwoJCQkJKGJpby0+Ymlfc2l6ZSA+PiA5KSAtIDEpOwoKCQliaW9fZW5kaW8oYmlvLCBiaW8tPmJpX3NpemUsCgkJCXRlc3RfYml0KFIxQklPX1VwdG9kYXRlLCAmcjFfYmlvLT5zdGF0ZSkgPyAwIDogLUVJTyk7Cgl9CglmcmVlX3IxYmlvKHIxX2Jpbyk7Cn0KCi8qCiAqIFVwZGF0ZSBkaXNrIGhlYWQgcG9zaXRpb24gZXN0aW1hdG9yIGJhc2VkIG9uIElSUSBjb21wbGV0aW9uIGluZm8uCiAqLwpzdGF0aWMgaW5saW5lIHZvaWQgdXBkYXRlX2hlYWRfcG9zKGludCBkaXNrLCByMWJpb190ICpyMV9iaW8pCnsKCWNvbmZfdCAqY29uZiA9IG1kZGV2X3RvX2NvbmYocjFfYmlvLT5tZGRldik7CgoJY29uZi0+bWlycm9yc1tkaXNrXS5oZWFkX3Bvc2l0aW9uID0KCQlyMV9iaW8tPnNlY3RvciArIChyMV9iaW8tPnNlY3RvcnMpOwp9CgpzdGF0aWMgaW50IHJhaWQxX2VuZF9yZWFkX3JlcXVlc3Qoc3RydWN0IGJpbyAqYmlvLCB1bnNpZ25lZCBpbnQgYnl0ZXNfZG9uZSwgaW50IGVycm9yKQp7CglpbnQgdXB0b2RhdGUgPSB0ZXN0X2JpdChCSU9fVVBUT0RBVEUsICZiaW8tPmJpX2ZsYWdzKTsKCXIxYmlvX3QgKiByMV9iaW8gPSAocjFiaW9fdCAqKShiaW8tPmJpX3ByaXZhdGUpOwoJaW50IG1pcnJvcjsKCWNvbmZfdCAqY29uZiA9IG1kZGV2X3RvX2NvbmYocjFfYmlvLT5tZGRldik7CgoJaWYgKGJpby0+Ymlfc2l6ZSkKCQlyZXR1cm4gMTsKCQoJbWlycm9yID0gcjFfYmlvLT5yZWFkX2Rpc2s7CgkvKgoJICogdGhpcyBicmFuY2ggaXMgb3VyICdvbmUgbWlycm9yIElPIGhhcyBmaW5pc2hlZCcgZXZlbnQgaGFuZGxlcjoKCSAqLwoJaWYgKCF1cHRvZGF0ZSkKCQltZF9lcnJvcihyMV9iaW8tPm1kZGV2LCBjb25mLT5taXJyb3JzW21pcnJvcl0ucmRldik7CgllbHNlCgkJLyoKCQkgKiBTZXQgUjFCSU9fVXB0b2RhdGUgaW4gb3VyIG1hc3RlciBiaW8sIHNvIHRoYXQKCQkgKiB3ZSB3aWxsIHJldHVybiBhIGdvb2QgZXJyb3IgY29kZSBmb3IgdG8gdGhlIGhpZ2hlcgoJCSAqIGxldmVscyBldmVuIGlmIElPIG9uIHNvbWUgb3RoZXIgbWlycm9yZWQgYnVmZmVyIGZhaWxzLgoJCSAqCgkJICogVGhlICdtYXN0ZXInIHJlcHJlc2VudHMgdGhlIGNvbXBvc2l0ZSBJTyBvcGVyYXRpb24gdG8KCQkgKiB1c2VyLXNpZGUuIFNvIGlmIHNvbWV0aGluZyB3YWl0cyBmb3IgSU8sIHRoZW4gaXQgd2lsbAoJCSAqIHdhaXQgZm9yIHRoZSAnbWFzdGVyJyBiaW8uCgkJICovCgkJc2V0X2JpdChSMUJJT19VcHRvZGF0ZSwgJnIxX2Jpby0+c3RhdGUpOwoKCXVwZGF0ZV9oZWFkX3BvcyhtaXJyb3IsIHIxX2Jpbyk7CgoJLyoKCSAqIHdlIGhhdmUgb25seSBvbmUgYmlvIG9uIHRoZSByZWFkIHNpZGUKCSAqLwoJaWYgKHVwdG9kYXRlKQoJCXJhaWRfZW5kX2Jpb19pbyhyMV9iaW8pOwoJZWxzZSB7CgkJLyoKCQkgKiBvb3BzLCByZWFkIGVycm9yOgoJCSAqLwoJCWNoYXIgYltCREVWTkFNRV9TSVpFXTsKCQlpZiAocHJpbnRrX3JhdGVsaW1pdCgpKQoJCQlwcmludGsoS0VSTl9FUlIgInJhaWQxOiAlczogcmVzY2hlZHVsaW5nIHNlY3RvciAlbGx1XG4iLAoJCQkgICAgICAgYmRldm5hbWUoY29uZi0+bWlycm9yc1ttaXJyb3JdLnJkZXYtPmJkZXYsYiksICh1bnNpZ25lZCBsb25nIGxvbmcpcjFfYmlvLT5zZWN0b3IpOwoJCXJlc2NoZWR1bGVfcmV0cnkocjFfYmlvKTsKCX0KCglyZGV2X2RlY19wZW5kaW5nKGNvbmYtPm1pcnJvcnNbbWlycm9yXS5yZGV2LCBjb25mLT5tZGRldik7CglyZXR1cm4gMDsKfQoKc3RhdGljIGludCByYWlkMV9lbmRfd3JpdGVfcmVxdWVzdChzdHJ1Y3QgYmlvICpiaW8sIHVuc2lnbmVkIGludCBieXRlc19kb25lLCBpbnQgZXJyb3IpCnsKCWludCB1cHRvZGF0ZSA9IHRlc3RfYml0KEJJT19VUFRPREFURSwgJmJpby0+YmlfZmxhZ3MpOwoJcjFiaW9fdCAqIHIxX2JpbyA9IChyMWJpb190ICopKGJpby0+YmlfcHJpdmF0ZSk7CglpbnQgbWlycm9yLCBiZWhpbmQgPSB0ZXN0X2JpdChSMUJJT19CZWhpbmRJTywgJnIxX2Jpby0+c3RhdGUpOwoJY29uZl90ICpjb25mID0gbWRkZXZfdG9fY29uZihyMV9iaW8tPm1kZGV2KTsKCglpZiAoYmlvLT5iaV9zaXplKQoJCXJldHVybiAxOwoKCWZvciAobWlycm9yID0gMDsgbWlycm9yIDwgY29uZi0+cmFpZF9kaXNrczsgbWlycm9yKyspCgkJaWYgKHIxX2Jpby0+Ymlvc1ttaXJyb3JdID09IGJpbykKCQkJYnJlYWs7CgoJaWYgKGVycm9yID09IC1FTk9UU1VQUCAmJiB0ZXN0X2JpdChSMUJJT19CYXJyaWVyLCAmcjFfYmlvLT5zdGF0ZSkpIHsKCQlzZXRfYml0KEJhcnJpZXJzTm90c3VwcCwgJmNvbmYtPm1pcnJvcnNbbWlycm9yXS5yZGV2LT5mbGFncyk7CgkJc2V0X2JpdChSMUJJT19CYXJyaWVyUmV0cnksICZyMV9iaW8tPnN0YXRlKTsKCQlyMV9iaW8tPm1kZGV2LT5iYXJyaWVyc193b3JrID0gMDsKCX0gZWxzZSB7CgkJLyoKCQkgKiB0aGlzIGJyYW5jaCBpcyBvdXIgJ29uZSBtaXJyb3IgSU8gaGFzIGZpbmlzaGVkJyBldmVudCBoYW5kbGVyOgoJCSAqLwoJCXIxX2Jpby0+Ymlvc1ttaXJyb3JdID0gTlVMTDsKCQliaW9fcHV0KGJpbyk7CgkJaWYgKCF1cHRvZGF0ZSkgewoJCQltZF9lcnJvcihyMV9iaW8tPm1kZGV2LCBjb25mLT5taXJyb3JzW21pcnJvcl0ucmRldik7CgkJCS8qIGFuIEkvTyBmYWlsZWQsIHdlIGNhbid0IGNsZWFyIHRoZSBiaXRtYXAgKi8KCQkJc2V0X2JpdChSMUJJT19EZWdyYWRlZCwgJnIxX2Jpby0+c3RhdGUpOwoJCX0gZWxzZQoJCQkvKgoJCQkgKiBTZXQgUjFCSU9fVXB0b2RhdGUgaW4gb3VyIG1hc3RlciBiaW8sIHNvIHRoYXQKCQkJICogd2Ugd2lsbCByZXR1cm4gYSBnb29kIGVycm9yIGNvZGUgZm9yIHRvIHRoZSBoaWdoZXIKCQkJICogbGV2ZWxzIGV2ZW4gaWYgSU8gb24gc29tZSBvdGhlciBtaXJyb3JlZCBidWZmZXIgZmFpbHMuCgkJCSAqCgkJCSAqIFRoZSAnbWFzdGVyJyByZXByZXNlbnRzIHRoZSBjb21wb3NpdGUgSU8gb3BlcmF0aW9uIHRvCgkJCSAqIHVzZXItc2lkZS4gU28gaWYgc29tZXRoaW5nIHdhaXRzIGZvciBJTywgdGhlbiBpdCB3aWxsCgkJCSAqIHdhaXQgZm9yIHRoZSAnbWFzdGVyJyBiaW8uCgkJCSAqLwoJCQlzZXRfYml0KFIxQklPX1VwdG9kYXRlLCAmcjFfYmlvLT5zdGF0ZSk7CgoJCXVwZGF0ZV9oZWFkX3BvcyhtaXJyb3IsIHIxX2Jpbyk7CgoJCWlmIChiZWhpbmQpIHsKCQkJaWYgKHRlc3RfYml0KFdyaXRlTW9zdGx5LCAmY29uZi0+bWlycm9yc1ttaXJyb3JdLnJkZXYtPmZsYWdzKSkKCQkJCWF0b21pY19kZWMoJnIxX2Jpby0+YmVoaW5kX3JlbWFpbmluZyk7CgoJCQkvKiBJbiBiZWhpbmQgbW9kZSwgd2UgQUNLIHRoZSBtYXN0ZXIgYmlvIG9uY2UgdGhlIEkvTyBoYXMgc2FmZWx5CgkJCSAqIHJlYWNoZWQgYWxsIG5vbi13cml0ZW1vc3RseSBkaXNrcy4gU2V0dGluZyB0aGUgUmV0dXJuZWQgYml0CgkJCSAqIGVuc3VyZXMgdGhhdCB0aGlzIGdldHMgZG9uZSBvbmx5IG9uY2UgLS0gd2UgZG9uJ3QgZXZlciB3YW50IHRvCgkJCSAqIHJldHVybiAtRUlPIGhlcmUsIGluc3RlYWQgd2UnbGwgd2FpdCAqLwoKCQkJaWYgKGF0b21pY19yZWFkKCZyMV9iaW8tPmJlaGluZF9yZW1haW5pbmcpID49IChhdG9taWNfcmVhZCgmcjFfYmlvLT5yZW1haW5pbmcpLTEpICYmCgkJCSAgICB0ZXN0X2JpdChSMUJJT19VcHRvZGF0ZSwgJnIxX2Jpby0+c3RhdGUpKSB7CgkJCQkvKiBNYXliZSB3ZSBjYW4gcmV0dXJuIG5vdyAqLwoJCQkJaWYgKCF0ZXN0X2FuZF9zZXRfYml0KFIxQklPX1JldHVybmVkLCAmcjFfYmlvLT5zdGF0ZSkpIHsKCQkJCQlzdHJ1Y3QgYmlvICptYmlvID0gcjFfYmlvLT5tYXN0ZXJfYmlvOwoJCQkJCVBSSU5USyhLRVJOX0RFQlVHICJyYWlkMTogYmVoaW5kIGVuZCB3cml0ZSBzZWN0b3JzICVsbHUtJWxsdVxuIiwKCQkJCQkgICAgICAgKHVuc2lnbmVkIGxvbmcgbG9uZykgbWJpby0+Ymlfc2VjdG9yLAoJCQkJCSAgICAgICAodW5zaWduZWQgbG9uZyBsb25nKSBtYmlvLT5iaV9zZWN0b3IgKwoJCQkJCSAgICAgICAobWJpby0+Ymlfc2l6ZSA+PiA5KSAtIDEpOwoJCQkJCWJpb19lbmRpbyhtYmlvLCBtYmlvLT5iaV9zaXplLCAwKTsKCQkJCX0KCQkJfQoJCX0KCX0KCS8qCgkgKgoJICogTGV0J3Mgc2VlIGlmIGFsbCBtaXJyb3JlZCB3cml0ZSBvcGVyYXRpb25zIGhhdmUgZmluaXNoZWQKCSAqIGFscmVhZHkuCgkgKi8KCWlmIChhdG9taWNfZGVjX2FuZF90ZXN0KCZyMV9iaW8tPnJlbWFpbmluZykpIHsKCQlpZiAodGVzdF9iaXQoUjFCSU9fQmFycmllclJldHJ5LCAmcjFfYmlvLT5zdGF0ZSkpIHsKCQkJcmVzY2hlZHVsZV9yZXRyeShyMV9iaW8pOwoJCQkvKiBEb24ndCBkZWNfcGVuZGluZyB5ZXQsIHdlIHdhbnQgdG8gaG9sZAoJCQkgKiB0aGUgcmVmZXJlbmNlIG92ZXIgdGhlIHJldHJ5CgkJCSAqLwoJCQlyZXR1cm4gMDsKCQl9CgkJaWYgKHRlc3RfYml0KFIxQklPX0JlaGluZElPLCAmcjFfYmlvLT5zdGF0ZSkpIHsKCQkJLyogZnJlZSBleHRyYSBjb3B5IG9mIHRoZSBkYXRhIHBhZ2VzICovCi8qIEZJWE1FIGJpbyBoYXMgYmVlbiBmcmVlZCEhISAqLwoJCQlpbnQgaSA9IGJpby0+YmlfdmNudDsKCQkJd2hpbGUgKGktLSkKCQkJCV9fZnJlZV9wYWdlKGJpby0+YmlfaW9fdmVjW2ldLmJ2X3BhZ2UpOwoJCX0KCQkvKiBjbGVhciB0aGUgYml0bWFwIGlmIGFsbCB3cml0ZXMgY29tcGxldGUgc3VjY2Vzc2Z1bGx5ICovCgkJYml0bWFwX2VuZHdyaXRlKHIxX2Jpby0+bWRkZXYtPmJpdG1hcCwgcjFfYmlvLT5zZWN0b3IsCgkJCQlyMV9iaW8tPnNlY3RvcnMsCgkJCQkhdGVzdF9iaXQoUjFCSU9fRGVncmFkZWQsICZyMV9iaW8tPnN0YXRlKSwKCQkJCWJlaGluZCk7CgkJbWRfd3JpdGVfZW5kKHIxX2Jpby0+bWRkZXYpOwoJCXJhaWRfZW5kX2Jpb19pbyhyMV9iaW8pOwoJfQoKCXJkZXZfZGVjX3BlbmRpbmcoY29uZi0+bWlycm9yc1ttaXJyb3JdLnJkZXYsIGNvbmYtPm1kZGV2KTsKCXJldHVybiAwOwp9CgoKLyoKICogVGhpcyByb3V0aW5lIHJldHVybnMgdGhlIGRpc2sgZnJvbSB3aGljaCB0aGUgcmVxdWVzdGVkIHJlYWQgc2hvdWxkCiAqIGJlIGRvbmUuIFRoZXJlIGlzIGEgcGVyLWFycmF5ICduZXh0IGV4cGVjdGVkIHNlcXVlbnRpYWwgSU8nIHNlY3RvcgogKiBudW1iZXIgLSBpZiB0aGlzIG1hdGNoZXMgb24gdGhlIG5leHQgSU8gdGhlbiB3ZSB1c2UgdGhlIGxhc3QgZGlzay4KICogVGhlcmUgaXMgYWxzbyBhIHBlci1kaXNrICdsYXN0IGtub3cgaGVhZCBwb3NpdGlvbicgc2VjdG9yIHRoYXQgaXMKICogbWFpbnRhaW5lZCBmcm9tIElSUSBjb250ZXh0cywgYm90aCB0aGUgbm9ybWFsIGFuZCB0aGUgcmVzeW5jIElPCiAqIGNvbXBsZXRpb24gaGFuZGxlcnMgdXBkYXRlIHRoaXMgcG9zaXRpb24gY29ycmVjdGx5LiBJZiB0aGVyZSBpcyBubwogKiBwZXJmZWN0IHNlcXVlbnRpYWwgbWF0Y2ggdGhlbiB3ZSBwaWNrIHRoZSBkaXNrIHdob3NlIGhlYWQgaXMgY2xvc2VzdC4KICoKICogSWYgdGhlcmUgYXJlIDIgbWlycm9ycyBpbiB0aGUgc2FtZSAyIGRldmljZXMsIHBlcmZvcm1hbmNlIGRlZ3JhZGVzCiAqIGJlY2F1c2UgcG9zaXRpb24gaXMgbWlycm9yLCBub3QgZGV2aWNlIGJhc2VkLgogKgogKiBUaGUgcmRldiBmb3IgdGhlIGRldmljZSBzZWxlY3RlZCB3aWxsIGhhdmUgbnJfcGVuZGluZyBpbmNyZW1lbnRlZC4KICovCnN0YXRpYyBpbnQgcmVhZF9iYWxhbmNlKGNvbmZfdCAqY29uZiwgcjFiaW9fdCAqcjFfYmlvKQp7Cgljb25zdCB1bnNpZ25lZCBsb25nIHRoaXNfc2VjdG9yID0gcjFfYmlvLT5zZWN0b3I7CglpbnQgbmV3X2Rpc2sgPSBjb25mLT5sYXN0X3VzZWQsIGRpc2sgPSBuZXdfZGlzazsKCWludCB3b25seV9kaXNrID0gLTE7Cgljb25zdCBpbnQgc2VjdG9ycyA9IHIxX2Jpby0+c2VjdG9yczsKCXNlY3Rvcl90IG5ld19kaXN0YW5jZSwgY3VycmVudF9kaXN0YW5jZTsKCW1ka19yZGV2X3QgKnJkZXY7CgoJcmN1X3JlYWRfbG9jaygpOwoJLyoKCSAqIENoZWNrIGlmIHdlIGNhbiBiYWxhbmNlLiBXZSBjYW4gYmFsYW5jZSBvbiB0aGUgd2hvbGUKCSAqIGRldmljZSBpZiBubyByZXN5bmMgaXMgZ29pbmcgb24sIG9yIGJlbG93IHRoZSByZXN5bmMgd2luZG93LgoJICogV2UgdGFrZSB0aGUgZmlyc3QgcmVhZGFibGUgZGlzayB3aGVuIGFib3ZlIHRoZSByZXN5bmMgd2luZG93LgoJICovCiByZXRyeToKCWlmIChjb25mLT5tZGRldi0+cmVjb3ZlcnlfY3AgPCBNYXhTZWN0b3IgJiYKCSAgICAodGhpc19zZWN0b3IgKyBzZWN0b3JzID49IGNvbmYtPm5leHRfcmVzeW5jKSkgewoJCS8qIENob29zZSB0aGUgZmlyc3Qgb3BlcmF0aW9uIGRldmljZSwgZm9yIGNvbnNpc3RhbmN5ICovCgkJbmV3X2Rpc2sgPSAwOwoKCQlmb3IgKHJkZXYgPSByY3VfZGVyZWZlcmVuY2UoY29uZi0+bWlycm9yc1tuZXdfZGlza10ucmRldik7CgkJICAgICAhcmRldiB8fCAhdGVzdF9iaXQoSW5fc3luYywgJnJkZXYtPmZsYWdzKQoJCQkgICAgIHx8IHRlc3RfYml0KFdyaXRlTW9zdGx5LCAmcmRldi0+ZmxhZ3MpOwoJCSAgICAgcmRldiA9IHJjdV9kZXJlZmVyZW5jZShjb25mLT5taXJyb3JzWysrbmV3X2Rpc2tdLnJkZXYpKSB7CgoJCQlpZiAocmRldiAmJiB0ZXN0X2JpdChJbl9zeW5jLCAmcmRldi0+ZmxhZ3MpKQoJCQkJd29ubHlfZGlzayA9IG5ld19kaXNrOwoKCQkJaWYgKG5ld19kaXNrID09IGNvbmYtPnJhaWRfZGlza3MgLSAxKSB7CgkJCQluZXdfZGlzayA9IHdvbmx5X2Rpc2s7CgkJCQlicmVhazsKCQkJfQoJCX0KCQlnb3RvIHJiX291dDsKCX0KCgoJLyogbWFrZSBzdXJlIHRoZSBkaXNrIGlzIG9wZXJhdGlvbmFsICovCglmb3IgKHJkZXYgPSByY3VfZGVyZWZlcmVuY2UoY29uZi0+bWlycm9yc1tuZXdfZGlza10ucmRldik7CgkgICAgICFyZGV2IHx8ICF0ZXN0X2JpdChJbl9zeW5jLCAmcmRldi0+ZmxhZ3MpIHx8CgkJICAgICB0ZXN0X2JpdChXcml0ZU1vc3RseSwgJnJkZXYtPmZsYWdzKTsKCSAgICAgcmRldiA9IHJjdV9kZXJlZmVyZW5jZShjb25mLT5taXJyb3JzW25ld19kaXNrXS5yZGV2KSkgewoKCQlpZiAocmRldiAmJiB0ZXN0X2JpdChJbl9zeW5jLCAmcmRldi0+ZmxhZ3MpKQoJCQl3b25seV9kaXNrID0gbmV3X2Rpc2s7CgoJCWlmIChuZXdfZGlzayA8PSAwKQoJCQluZXdfZGlzayA9IGNvbmYtPnJhaWRfZGlza3M7CgkJbmV3X2Rpc2stLTsKCQlpZiAobmV3X2Rpc2sgPT0gZGlzaykgewoJCQluZXdfZGlzayA9IHdvbmx5X2Rpc2s7CgkJCWJyZWFrOwoJCX0KCX0KCglpZiAobmV3X2Rpc2sgPCAwKQoJCWdvdG8gcmJfb3V0OwoKCWRpc2sgPSBuZXdfZGlzazsKCS8qIG5vdyBkaXNrID09IG5ld19kaXNrID09IHN0YXJ0aW5nIHBvaW50IGZvciBzZWFyY2ggKi8KCgkvKgoJICogRG9uJ3QgY2hhbmdlIHRvIGFub3RoZXIgZGlzayBmb3Igc2VxdWVudGlhbCByZWFkczoKCSAqLwoJaWYgKGNvbmYtPm5leHRfc2VxX3NlY3QgPT0gdGhpc19zZWN0b3IpCgkJZ290byByYl9vdXQ7CglpZiAodGhpc19zZWN0b3IgPT0gY29uZi0+bWlycm9yc1tuZXdfZGlza10uaGVhZF9wb3NpdGlvbikKCQlnb3RvIHJiX291dDsKCgljdXJyZW50X2Rpc3RhbmNlID0gYWJzKHRoaXNfc2VjdG9yIC0gY29uZi0+bWlycm9yc1tkaXNrXS5oZWFkX3Bvc2l0aW9uKTsKCgkvKiBGaW5kIHRoZSBkaXNrIHdob3NlIGhlYWQgaXMgY2xvc2VzdCAqLwoKCWRvIHsKCQlpZiAoZGlzayA8PSAwKQoJCQlkaXNrID0gY29uZi0+cmFpZF9kaXNrczsKCQlkaXNrLS07CgoJCXJkZXYgPSByY3VfZGVyZWZlcmVuY2UoY29uZi0+bWlycm9yc1tkaXNrXS5yZGV2KTsKCgkJaWYgKCFyZGV2IHx8CgkJICAgICF0ZXN0X2JpdChJbl9zeW5jLCAmcmRldi0+ZmxhZ3MpIHx8CgkJICAgIHRlc3RfYml0KFdyaXRlTW9zdGx5LCAmcmRldi0+ZmxhZ3MpKQoJCQljb250aW51ZTsKCgkJaWYgKCFhdG9taWNfcmVhZCgmcmRldi0+bnJfcGVuZGluZykpIHsKCQkJbmV3X2Rpc2sgPSBkaXNrOwoJCQlicmVhazsKCQl9CgkJbmV3X2Rpc3RhbmNlID0gYWJzKHRoaXNfc2VjdG9yIC0gY29uZi0+bWlycm9yc1tkaXNrXS5oZWFkX3Bvc2l0aW9uKTsKCQlpZiAobmV3X2Rpc3RhbmNlIDwgY3VycmVudF9kaXN0YW5jZSkgewoJCQljdXJyZW50X2Rpc3RhbmNlID0gbmV3X2Rpc3RhbmNlOwoJCQluZXdfZGlzayA9IGRpc2s7CgkJfQoJfSB3aGlsZSAoZGlzayAhPSBjb25mLT5sYXN0X3VzZWQpOwoKIHJiX291dDoKCgoJaWYgKG5ld19kaXNrID49IDApIHsKCQlyZGV2ID0gcmN1X2RlcmVmZXJlbmNlKGNvbmYtPm1pcnJvcnNbbmV3X2Rpc2tdLnJkZXYpOwoJCWlmICghcmRldikKCQkJZ290byByZXRyeTsKCQlhdG9taWNfaW5jKCZyZGV2LT5ucl9wZW5kaW5nKTsKCQlpZiAoIXRlc3RfYml0KEluX3N5bmMsICZyZGV2LT5mbGFncykpIHsKCQkJLyogY2Fubm90IHJpc2sgcmV0dXJuaW5nIGEgZGV2aWNlIHRoYXQgZmFpbGVkCgkJCSAqIGJlZm9yZSB3ZSBpbmMnZWQgbnJfcGVuZGluZwoJCQkgKi8KCQkJYXRvbWljX2RlYygmcmRldi0+bnJfcGVuZGluZyk7CgkJCWdvdG8gcmV0cnk7CgkJfQoJCWNvbmYtPm5leHRfc2VxX3NlY3QgPSB0aGlzX3NlY3RvciArIHNlY3RvcnM7CgkJY29uZi0+bGFzdF91c2VkID0gbmV3X2Rpc2s7Cgl9CglyY3VfcmVhZF91bmxvY2soKTsKCglyZXR1cm4gbmV3X2Rpc2s7Cn0KCnN0YXRpYyB2b2lkIHVucGx1Z19zbGF2ZXMobWRkZXZfdCAqbWRkZXYpCnsKCWNvbmZfdCAqY29uZiA9IG1kZGV2X3RvX2NvbmYobWRkZXYpOwoJaW50IGk7CgoJcmN1X3JlYWRfbG9jaygpOwoJZm9yIChpPTA7IGk8bWRkZXYtPnJhaWRfZGlza3M7IGkrKykgewoJCW1ka19yZGV2X3QgKnJkZXYgPSByY3VfZGVyZWZlcmVuY2UoY29uZi0+bWlycm9yc1tpXS5yZGV2KTsKCQlpZiAocmRldiAmJiAhdGVzdF9iaXQoRmF1bHR5LCAmcmRldi0+ZmxhZ3MpICYmIGF0b21pY19yZWFkKCZyZGV2LT5ucl9wZW5kaW5nKSkgewoJCQlyZXF1ZXN0X3F1ZXVlX3QgKnJfcXVldWUgPSBiZGV2X2dldF9xdWV1ZShyZGV2LT5iZGV2KTsKCgkJCWF0b21pY19pbmMoJnJkZXYtPm5yX3BlbmRpbmcpOwoJCQlyY3VfcmVhZF91bmxvY2soKTsKCgkJCWlmIChyX3F1ZXVlLT51bnBsdWdfZm4pCgkJCQlyX3F1ZXVlLT51bnBsdWdfZm4ocl9xdWV1ZSk7CgoJCQlyZGV2X2RlY19wZW5kaW5nKHJkZXYsIG1kZGV2KTsKCQkJcmN1X3JlYWRfbG9jaygpOwoJCX0KCX0KCXJjdV9yZWFkX3VubG9jaygpOwp9CgpzdGF0aWMgdm9pZCByYWlkMV91bnBsdWcocmVxdWVzdF9xdWV1ZV90ICpxKQp7CgltZGRldl90ICptZGRldiA9IHEtPnF1ZXVlZGF0YTsKCgl1bnBsdWdfc2xhdmVzKG1kZGV2KTsKCW1kX3dha2V1cF90aHJlYWQobWRkZXYtPnRocmVhZCk7Cn0KCnN0YXRpYyBpbnQgcmFpZDFfaXNzdWVfZmx1c2gocmVxdWVzdF9xdWV1ZV90ICpxLCBzdHJ1Y3QgZ2VuZGlzayAqZGlzaywKCQkJICAgICBzZWN0b3JfdCAqZXJyb3Jfc2VjdG9yKQp7CgltZGRldl90ICptZGRldiA9IHEtPnF1ZXVlZGF0YTsKCWNvbmZfdCAqY29uZiA9IG1kZGV2X3RvX2NvbmYobWRkZXYpOwoJaW50IGksIHJldCA9IDA7CgoJcmN1X3JlYWRfbG9jaygpOwoJZm9yIChpPTA7IGk8bWRkZXYtPnJhaWRfZGlza3MgJiYgcmV0ID09IDA7IGkrKykgewoJCW1ka19yZGV2X3QgKnJkZXYgPSByY3VfZGVyZWZlcmVuY2UoY29uZi0+bWlycm9yc1tpXS5yZGV2KTsKCQlpZiAocmRldiAmJiAhdGVzdF9iaXQoRmF1bHR5LCAmcmRldi0+ZmxhZ3MpKSB7CgkJCXN0cnVjdCBibG9ja19kZXZpY2UgKmJkZXYgPSByZGV2LT5iZGV2OwoJCQlyZXF1ZXN0X3F1ZXVlX3QgKnJfcXVldWUgPSBiZGV2X2dldF9xdWV1ZShiZGV2KTsKCgkJCWlmICghcl9xdWV1ZS0+aXNzdWVfZmx1c2hfZm4pCgkJCQlyZXQgPSAtRU9QTk9UU1VQUDsKCQkJZWxzZSB7CgkJCQlhdG9taWNfaW5jKCZyZGV2LT5ucl9wZW5kaW5nKTsKCQkJCXJjdV9yZWFkX3VubG9jaygpOwoJCQkJcmV0ID0gcl9xdWV1ZS0+aXNzdWVfZmx1c2hfZm4ocl9xdWV1ZSwgYmRldi0+YmRfZGlzaywKCQkJCQkJCSAgICAgIGVycm9yX3NlY3Rvcik7CgkJCQlyZGV2X2RlY19wZW5kaW5nKHJkZXYsIG1kZGV2KTsKCQkJCXJjdV9yZWFkX2xvY2soKTsKCQkJfQoJCX0KCX0KCXJjdV9yZWFkX3VubG9jaygpOwoJcmV0dXJuIHJldDsKfQoKLyoKICogVGhyb3R0bGUgcmVzeW5jIGRlcHRoLCBzbyB0aGF0IHdlIGNhbiBib3RoIGdldCBwcm9wZXIgb3ZlcmxhcHBpbmcgb2YKICogcmVxdWVzdHMsIGJ1dCBhcmUgc3RpbGwgYWJsZSB0byBoYW5kbGUgbm9ybWFsIHJlcXVlc3RzIHF1aWNrbHkuCiAqLwojZGVmaW5lIFJFU1lOQ19ERVBUSCAzMgoKc3RhdGljIHZvaWQgZGV2aWNlX2JhcnJpZXIoY29uZl90ICpjb25mLCBzZWN0b3JfdCBzZWN0KQp7CglzcGluX2xvY2tfaXJxKCZjb25mLT5yZXN5bmNfbG9jayk7Cgl3YWl0X2V2ZW50X2xvY2tfaXJxKGNvbmYtPndhaXRfaWRsZSwgIXdhaXRxdWV1ZV9hY3RpdmUoJmNvbmYtPndhaXRfcmVzdW1lKSwKCQkJICAgIGNvbmYtPnJlc3luY19sb2NrLCByYWlkMV91bnBsdWcoY29uZi0+bWRkZXYtPnF1ZXVlKSk7CgkKCWlmICghY29uZi0+YmFycmllcisrKSB7CgkJd2FpdF9ldmVudF9sb2NrX2lycShjb25mLT53YWl0X2lkbGUsICFjb25mLT5ucl9wZW5kaW5nLAoJCQkJICAgIGNvbmYtPnJlc3luY19sb2NrLCByYWlkMV91bnBsdWcoY29uZi0+bWRkZXYtPnF1ZXVlKSk7CgkJaWYgKGNvbmYtPm5yX3BlbmRpbmcpCgkJCUJVRygpOwoJfQoJd2FpdF9ldmVudF9sb2NrX2lycShjb25mLT53YWl0X3Jlc3VtZSwgY29uZi0+YmFycmllciA8IFJFU1lOQ19ERVBUSCwKCQkJICAgIGNvbmYtPnJlc3luY19sb2NrLCByYWlkMV91bnBsdWcoY29uZi0+bWRkZXYtPnF1ZXVlKSk7Cgljb25mLT5uZXh0X3Jlc3luYyA9IHNlY3Q7CglzcGluX3VubG9ja19pcnEoJmNvbmYtPnJlc3luY19sb2NrKTsKfQoKLyogZHVwbGljYXRlIHRoZSBkYXRhIHBhZ2VzIGZvciBiZWhpbmQgSS9PICovCnN0YXRpYyBzdHJ1Y3QgcGFnZSAqKmFsbG9jX2JlaGluZF9wYWdlcyhzdHJ1Y3QgYmlvICpiaW8pCnsKCWludCBpOwoJc3RydWN0IGJpb192ZWMgKmJ2ZWM7CglzdHJ1Y3QgcGFnZSAqKnBhZ2VzID0ga21hbGxvYyhiaW8tPmJpX3ZjbnQgKiBzaXplb2Yoc3RydWN0IHBhZ2UgKiksCgkJCQkJR0ZQX05PSU8pOwoJaWYgKHVubGlrZWx5KCFwYWdlcykpCgkJZ290byBkb19zeW5jX2lvOwoKCW1lbXNldChwYWdlcywgMCwgYmlvLT5iaV92Y250ICogc2l6ZW9mKHN0cnVjdCBwYWdlICopKTsKCgliaW9fZm9yX2VhY2hfc2VnbWVudChidmVjLCBiaW8sIGkpIHsKCQlwYWdlc1tpXSA9IGFsbG9jX3BhZ2UoR0ZQX05PSU8pOwoJCWlmICh1bmxpa2VseSghcGFnZXNbaV0pKQoJCQlnb3RvIGRvX3N5bmNfaW87CgkJbWVtY3B5KGttYXAocGFnZXNbaV0pICsgYnZlYy0+YnZfb2Zmc2V0LAoJCQlrbWFwKGJ2ZWMtPmJ2X3BhZ2UpICsgYnZlYy0+YnZfb2Zmc2V0LCBidmVjLT5idl9sZW4pOwoJCWt1bm1hcChwYWdlc1tpXSk7CgkJa3VubWFwKGJ2ZWMtPmJ2X3BhZ2UpOwoJfQoKCXJldHVybiBwYWdlczsKCmRvX3N5bmNfaW86CglpZiAocGFnZXMpCgkJZm9yIChpID0gMDsgaSA8IGJpby0+YmlfdmNudCAmJiBwYWdlc1tpXTsgaSsrKQoJCQlfX2ZyZWVfcGFnZShwYWdlc1tpXSk7CglrZnJlZShwYWdlcyk7CglQUklOVEsoIiVkQiBiZWhpbmQgYWxsb2MgZmFpbGVkLCBkb2luZyBzeW5jIEkvT1xuIiwgYmlvLT5iaV9zaXplKTsKCXJldHVybiBOVUxMOwp9CgpzdGF0aWMgaW50IG1ha2VfcmVxdWVzdChyZXF1ZXN0X3F1ZXVlX3QgKnEsIHN0cnVjdCBiaW8gKiBiaW8pCnsKCW1kZGV2X3QgKm1kZGV2ID0gcS0+cXVldWVkYXRhOwoJY29uZl90ICpjb25mID0gbWRkZXZfdG9fY29uZihtZGRldik7CgltaXJyb3JfaW5mb190ICptaXJyb3I7CglyMWJpb190ICpyMV9iaW87CglzdHJ1Y3QgYmlvICpyZWFkX2JpbzsKCWludCBpLCB0YXJnZXRzID0gMCwgZGlza3M7CgltZGtfcmRldl90ICpyZGV2OwoJc3RydWN0IGJpdG1hcCAqYml0bWFwID0gbWRkZXYtPmJpdG1hcDsKCXVuc2lnbmVkIGxvbmcgZmxhZ3M7CglzdHJ1Y3QgYmlvX2xpc3QgYmw7CglzdHJ1Y3QgcGFnZSAqKmJlaGluZF9wYWdlcyA9IE5VTEw7Cgljb25zdCBpbnQgcncgPSBiaW9fZGF0YV9kaXIoYmlvKTsKCWludCBkb19iYXJyaWVyczsKCglpZiAodW5saWtlbHkoIW1kZGV2LT5iYXJyaWVyc193b3JrICYmIGJpb19iYXJyaWVyKGJpbykpKSB7CgkJYmlvX2VuZGlvKGJpbywgYmlvLT5iaV9zaXplLCAtRU9QTk9UU1VQUCk7CgkJcmV0dXJuIDA7Cgl9CgoJLyoKCSAqIFJlZ2lzdGVyIHRoZSBuZXcgcmVxdWVzdCBhbmQgd2FpdCBpZiB0aGUgcmVjb25zdHJ1Y3Rpb24KCSAqIHRocmVhZCBoYXMgcHV0IHVwIGEgYmFyIGZvciBuZXcgcmVxdWVzdHMuCgkgKiBDb250aW51ZSBpbW1lZGlhdGVseSBpZiBubyByZXN5bmMgaXMgYWN0aXZlIGN1cnJlbnRseS4KCSAqLwoJbWRfd3JpdGVfc3RhcnQobWRkZXYsIGJpbyk7IC8qIHdhaXQgb24gc3VwZXJibG9jayB1cGRhdGUgZWFybHkgKi8KCglzcGluX2xvY2tfaXJxKCZjb25mLT5yZXN5bmNfbG9jayk7Cgl3YWl0X2V2ZW50X2xvY2tfaXJxKGNvbmYtPndhaXRfcmVzdW1lLCAhY29uZi0+YmFycmllciwgY29uZi0+cmVzeW5jX2xvY2ssICk7Cgljb25mLT5ucl9wZW5kaW5nKys7CglzcGluX3VubG9ja19pcnEoJmNvbmYtPnJlc3luY19sb2NrKTsKCglkaXNrX3N0YXRfaW5jKG1kZGV2LT5nZW5kaXNrLCBpb3NbcnddKTsKCWRpc2tfc3RhdF9hZGQobWRkZXYtPmdlbmRpc2ssIHNlY3RvcnNbcnddLCBiaW9fc2VjdG9ycyhiaW8pKTsKCgkvKgoJICogbWFrZV9yZXF1ZXN0KCkgY2FuIGFib3J0IHRoZSBvcGVyYXRpb24gd2hlbiBSRUFEQSBpcyBiZWluZwoJICogdXNlZCBhbmQgbm8gZW1wdHkgcmVxdWVzdCBpcyBhdmFpbGFibGUuCgkgKgoJICovCglyMV9iaW8gPSBtZW1wb29sX2FsbG9jKGNvbmYtPnIxYmlvX3Bvb2wsIEdGUF9OT0lPKTsKCglyMV9iaW8tPm1hc3Rlcl9iaW8gPSBiaW87CglyMV9iaW8tPnNlY3RvcnMgPSBiaW8tPmJpX3NpemUgPj4gOTsKCXIxX2Jpby0+c3RhdGUgPSAwOwoJcjFfYmlvLT5tZGRldiA9IG1kZGV2OwoJcjFfYmlvLT5zZWN0b3IgPSBiaW8tPmJpX3NlY3RvcjsKCglpZiAocncgPT0gUkVBRCkgewoJCS8qCgkJICogcmVhZCBiYWxhbmNpbmcgbG9naWM6CgkJICovCgkJaW50IHJkaXNrID0gcmVhZF9iYWxhbmNlKGNvbmYsIHIxX2Jpbyk7CgoJCWlmIChyZGlzayA8IDApIHsKCQkJLyogY291bGRuJ3QgZmluZCBhbnl3aGVyZSB0byByZWFkIGZyb20gKi8KCQkJcmFpZF9lbmRfYmlvX2lvKHIxX2Jpbyk7CgkJCXJldHVybiAwOwoJCX0KCQltaXJyb3IgPSBjb25mLT5taXJyb3JzICsgcmRpc2s7CgoJCXIxX2Jpby0+cmVhZF9kaXNrID0gcmRpc2s7CgoJCXJlYWRfYmlvID0gYmlvX2Nsb25lKGJpbywgR0ZQX05PSU8pOwoKCQlyMV9iaW8tPmJpb3NbcmRpc2tdID0gcmVhZF9iaW87CgoJCXJlYWRfYmlvLT5iaV9zZWN0b3IgPSByMV9iaW8tPnNlY3RvciArIG1pcnJvci0+cmRldi0+ZGF0YV9vZmZzZXQ7CgkJcmVhZF9iaW8tPmJpX2JkZXYgPSBtaXJyb3ItPnJkZXYtPmJkZXY7CgkJcmVhZF9iaW8tPmJpX2VuZF9pbyA9IHJhaWQxX2VuZF9yZWFkX3JlcXVlc3Q7CgkJcmVhZF9iaW8tPmJpX3J3ID0gUkVBRDsKCQlyZWFkX2Jpby0+YmlfcHJpdmF0ZSA9IHIxX2JpbzsKCgkJZ2VuZXJpY19tYWtlX3JlcXVlc3QocmVhZF9iaW8pOwoJCXJldHVybiAwOwoJfQoKCS8qCgkgKiBXUklURToKCSAqLwoJLyogZmlyc3Qgc2VsZWN0IHRhcmdldCBkZXZpY2VzIHVuZGVyIHNwaW5sb2NrIGFuZAoJICogaW5jIHJlZmNvdW50IG9uIHRoZWlyIHJkZXYuICBSZWNvcmQgdGhlbSBieSBzZXR0aW5nCgkgKiBiaW9zW3hdIHRvIGJpbwoJICovCglkaXNrcyA9IGNvbmYtPnJhaWRfZGlza3M7CiNpZiAwCgl7IHN0YXRpYyBpbnQgZmlyc3Q9MTsKCWlmIChmaXJzdCkgcHJpbnRrKCJGaXJzdCBXcml0ZSBzZWN0b3IgJWxsdSBkaXNrcyAlZFxuIiwKCQkJICAodW5zaWduZWQgbG9uZyBsb25nKXIxX2Jpby0+c2VjdG9yLCBkaXNrcyk7CglmaXJzdCA9IDA7Cgl9CiNlbmRpZgoJcmN1X3JlYWRfbG9jaygpOwoJZm9yIChpID0gMDsgIGkgPCBkaXNrczsgaSsrKSB7CgkJaWYgKChyZGV2PXJjdV9kZXJlZmVyZW5jZShjb25mLT5taXJyb3JzW2ldLnJkZXYpKSAhPSBOVUxMICYmCgkJICAgICF0ZXN0X2JpdChGYXVsdHksICZyZGV2LT5mbGFncykpIHsKCQkJYXRvbWljX2luYygmcmRldi0+bnJfcGVuZGluZyk7CgkJCWlmICh0ZXN0X2JpdChGYXVsdHksICZyZGV2LT5mbGFncykpIHsKCQkJCWF0b21pY19kZWMoJnJkZXYtPm5yX3BlbmRpbmcpOwoJCQkJcjFfYmlvLT5iaW9zW2ldID0gTlVMTDsKCQkJfSBlbHNlCgkJCQlyMV9iaW8tPmJpb3NbaV0gPSBiaW87CgkJCXRhcmdldHMrKzsKCQl9IGVsc2UKCQkJcjFfYmlvLT5iaW9zW2ldID0gTlVMTDsKCX0KCXJjdV9yZWFkX3VubG9jaygpOwoKCUJVR19PTih0YXJnZXRzID09IDApOyAvKiB3ZSBuZXZlciBmYWlsIHRoZSBsYXN0IGRldmljZSAqLwoKCWlmICh0YXJnZXRzIDwgY29uZi0+cmFpZF9kaXNrcykgewoJCS8qIGFycmF5IGlzIGRlZ3JhZGVkLCB3ZSB3aWxsIG5vdCBjbGVhciB0aGUgYml0bWFwCgkJICogb24gSS9PIGNvbXBsZXRpb24gKHNlZSByYWlkMV9lbmRfd3JpdGVfcmVxdWVzdCkgKi8KCQlzZXRfYml0KFIxQklPX0RlZ3JhZGVkLCAmcjFfYmlvLT5zdGF0ZSk7Cgl9CgoJLyogZG8gYmVoaW5kIEkvTyA/ICovCglpZiAoYml0bWFwICYmCgkgICAgYXRvbWljX3JlYWQoJmJpdG1hcC0+YmVoaW5kX3dyaXRlcykgPCBiaXRtYXAtPm1heF93cml0ZV9iZWhpbmQgJiYKCSAgICAoYmVoaW5kX3BhZ2VzID0gYWxsb2NfYmVoaW5kX3BhZ2VzKGJpbykpICE9IE5VTEwpCgkJc2V0X2JpdChSMUJJT19CZWhpbmRJTywgJnIxX2Jpby0+c3RhdGUpOwoKCWF0b21pY19zZXQoJnIxX2Jpby0+cmVtYWluaW5nLCAwKTsKCWF0b21pY19zZXQoJnIxX2Jpby0+YmVoaW5kX3JlbWFpbmluZywgMCk7CgoJZG9fYmFycmllcnMgPSBiaW8tPmJpX3J3ICYgQklPX1JXX0JBUlJJRVI7CglpZiAoZG9fYmFycmllcnMpCgkJc2V0X2JpdChSMUJJT19CYXJyaWVyLCAmcjFfYmlvLT5zdGF0ZSk7CgoJYmlvX2xpc3RfaW5pdCgmYmwpOwoJZm9yIChpID0gMDsgaSA8IGRpc2tzOyBpKyspIHsKCQlzdHJ1Y3QgYmlvICptYmlvOwoJCWlmICghcjFfYmlvLT5iaW9zW2ldKQoJCQljb250aW51ZTsKCgkJbWJpbyA9IGJpb19jbG9uZShiaW8sIEdGUF9OT0lPKTsKCQlyMV9iaW8tPmJpb3NbaV0gPSBtYmlvOwoKCQltYmlvLT5iaV9zZWN0b3IJPSByMV9iaW8tPnNlY3RvciArIGNvbmYtPm1pcnJvcnNbaV0ucmRldi0+ZGF0YV9vZmZzZXQ7CgkJbWJpby0+YmlfYmRldiA9IGNvbmYtPm1pcnJvcnNbaV0ucmRldi0+YmRldjsKCQltYmlvLT5iaV9lbmRfaW8JPSByYWlkMV9lbmRfd3JpdGVfcmVxdWVzdDsKCQltYmlvLT5iaV9ydyA9IFdSSVRFIHwgZG9fYmFycmllcnM7CgkJbWJpby0+YmlfcHJpdmF0ZSA9IHIxX2JpbzsKCgkJaWYgKGJlaGluZF9wYWdlcykgewoJCQlzdHJ1Y3QgYmlvX3ZlYyAqYnZlYzsKCQkJaW50IGo7CgoJCQkvKiBZZXMsIEkgcmVhbGx5IHdhbnQgdGhlICdfXycgdmVyc2lvbiBzbyB0aGF0CgkJCSAqIHdlIGNsZWFyIGFueSB1bnVzZWQgcG9pbnRlciBpbiB0aGUgaW9fdmVjLCByYXRoZXIKCQkJICogdGhhbiBsZWF2ZSB0aGVtIHVuY2hhbmdlZC4gIFRoaXMgaXMgaW1wb3J0YW50CgkJCSAqIGJlY2F1c2Ugd2hlbiB3ZSBjb21lIHRvIGZyZWUgdGhlIHBhZ2VzLCB3ZSB3b24ndAoJCQkgKiBrbm93IHRoZSBvcmlnaW5pYWwgYmlfaWR4LCBzbyB3ZSBqdXN0IGZyZWUKCQkJICogdGhlbSBhbGwKCQkJICovCgkJCV9fYmlvX2Zvcl9lYWNoX3NlZ21lbnQoYnZlYywgbWJpbywgaiwgMCkKCQkJCWJ2ZWMtPmJ2X3BhZ2UgPSBiZWhpbmRfcGFnZXNbal07CgkJCWlmICh0ZXN0X2JpdChXcml0ZU1vc3RseSwgJmNvbmYtPm1pcnJvcnNbaV0ucmRldi0+ZmxhZ3MpKQoJCQkJYXRvbWljX2luYygmcjFfYmlvLT5iZWhpbmRfcmVtYWluaW5nKTsKCQl9CgoJCWF0b21pY19pbmMoJnIxX2Jpby0+cmVtYWluaW5nKTsKCgkJYmlvX2xpc3RfYWRkKCZibCwgbWJpbyk7Cgl9CglrZnJlZShiZWhpbmRfcGFnZXMpOyAvKiB0aGUgYmVoaW5kIHBhZ2VzIGFyZSBhdHRhY2hlZCB0byB0aGUgYmlvcyBub3cgKi8KCgliaXRtYXBfc3RhcnR3cml0ZShiaXRtYXAsIGJpby0+Ymlfc2VjdG9yLCByMV9iaW8tPnNlY3RvcnMsCgkJCQl0ZXN0X2JpdChSMUJJT19CZWhpbmRJTywgJnIxX2Jpby0+c3RhdGUpKTsKCXNwaW5fbG9ja19pcnFzYXZlKCZjb25mLT5kZXZpY2VfbG9jaywgZmxhZ3MpOwoJYmlvX2xpc3RfbWVyZ2UoJmNvbmYtPnBlbmRpbmdfYmlvX2xpc3QsICZibCk7CgliaW9fbGlzdF9pbml0KCZibCk7CgoJYmxrX3BsdWdfZGV2aWNlKG1kZGV2LT5xdWV1ZSk7CglzcGluX3VubG9ja19pcnFyZXN0b3JlKCZjb25mLT5kZXZpY2VfbG9jaywgZmxhZ3MpOwoKI2lmIDAKCXdoaWxlICgoYmlvID0gYmlvX2xpc3RfcG9wKCZibCkpICE9IE5VTEwpCgkJZ2VuZXJpY19tYWtlX3JlcXVlc3QoYmlvKTsKI2VuZGlmCgoJcmV0dXJuIDA7Cn0KCnN0YXRpYyB2b2lkIHN0YXR1cyhzdHJ1Y3Qgc2VxX2ZpbGUgKnNlcSwgbWRkZXZfdCAqbWRkZXYpCnsKCWNvbmZfdCAqY29uZiA9IG1kZGV2X3RvX2NvbmYobWRkZXYpOwoJaW50IGk7CgoJc2VxX3ByaW50ZihzZXEsICIgWyVkLyVkXSBbIiwgY29uZi0+cmFpZF9kaXNrcywKCQkJCQkJY29uZi0+d29ya2luZ19kaXNrcyk7Cglmb3IgKGkgPSAwOyBpIDwgY29uZi0+cmFpZF9kaXNrczsgaSsrKQoJCXNlcV9wcmludGYoc2VxLCAiJXMiLAoJCQkgICAgICBjb25mLT5taXJyb3JzW2ldLnJkZXYgJiYKCQkJICAgICAgdGVzdF9iaXQoSW5fc3luYywgJmNvbmYtPm1pcnJvcnNbaV0ucmRldi0+ZmxhZ3MpID8gIlUiIDogIl8iKTsKCXNlcV9wcmludGYoc2VxLCAiXSIpOwp9CgoKc3RhdGljIHZvaWQgZXJyb3IobWRkZXZfdCAqbWRkZXYsIG1ka19yZGV2X3QgKnJkZXYpCnsKCWNoYXIgYltCREVWTkFNRV9TSVpFXTsKCWNvbmZfdCAqY29uZiA9IG1kZGV2X3RvX2NvbmYobWRkZXYpOwoKCS8qCgkgKiBJZiBpdCBpcyBub3Qgb3BlcmF0aW9uYWwsIHRoZW4gd2UgaGF2ZSBhbHJlYWR5IG1hcmtlZCBpdCBhcyBkZWFkCgkgKiBlbHNlIGlmIGl0IGlzIHRoZSBsYXN0IHdvcmtpbmcgZGlza3MsIGlnbm9yZSB0aGUgZXJyb3IsIGxldCB0aGUKCSAqIG5leHQgbGV2ZWwgdXAga25vdy4KCSAqIGVsc2UgbWFyayB0aGUgZHJpdmUgYXMgZmFpbGVkCgkgKi8KCWlmICh0ZXN0X2JpdChJbl9zeW5jLCAmcmRldi0+ZmxhZ3MpCgkgICAgJiYgY29uZi0+d29ya2luZ19kaXNrcyA9PSAxKQoJCS8qCgkJICogRG9uJ3QgZmFpbCB0aGUgZHJpdmUsIGFjdCBhcyB0aG91Z2ggd2Ugd2VyZSBqdXN0IGEKCQkgKiBub3JtYWwgc2luZ2xlIGRyaXZlCgkJICovCgkJcmV0dXJuOwoJaWYgKHRlc3RfYml0KEluX3N5bmMsICZyZGV2LT5mbGFncykpIHsKCQltZGRldi0+ZGVncmFkZWQrKzsKCQljb25mLT53b3JraW5nX2Rpc2tzLS07CgkJLyoKCQkgKiBpZiByZWNvdmVyeSBpcyBydW5uaW5nLCBtYWtlIHN1cmUgaXQgYWJvcnRzLgoJCSAqLwoJCXNldF9iaXQoTURfUkVDT1ZFUllfRVJSLCAmbWRkZXYtPnJlY292ZXJ5KTsKCX0KCWNsZWFyX2JpdChJbl9zeW5jLCAmcmRldi0+ZmxhZ3MpOwoJc2V0X2JpdChGYXVsdHksICZyZGV2LT5mbGFncyk7CgltZGRldi0+c2JfZGlydHkgPSAxOwoJcHJpbnRrKEtFUk5fQUxFUlQgInJhaWQxOiBEaXNrIGZhaWx1cmUgb24gJXMsIGRpc2FibGluZyBkZXZpY2UuIFxuIgoJCSIJT3BlcmF0aW9uIGNvbnRpbnVpbmcgb24gJWQgZGV2aWNlc1xuIiwKCQliZGV2bmFtZShyZGV2LT5iZGV2LGIpLCBjb25mLT53b3JraW5nX2Rpc2tzKTsKfQoKc3RhdGljIHZvaWQgcHJpbnRfY29uZihjb25mX3QgKmNvbmYpCnsKCWludCBpOwoJbWlycm9yX2luZm9fdCAqdG1wOwoKCXByaW50aygiUkFJRDEgY29uZiBwcmludG91dDpcbiIpOwoJaWYgKCFjb25mKSB7CgkJcHJpbnRrKCIoIWNvbmYpXG4iKTsKCQlyZXR1cm47Cgl9CglwcmludGsoIiAtLS0gd2Q6JWQgcmQ6JWRcbiIsIGNvbmYtPndvcmtpbmdfZGlza3MsCgkJY29uZi0+cmFpZF9kaXNrcyk7CgoJZm9yIChpID0gMDsgaSA8IGNvbmYtPnJhaWRfZGlza3M7IGkrKykgewoJCWNoYXIgYltCREVWTkFNRV9TSVpFXTsKCQl0bXAgPSBjb25mLT5taXJyb3JzICsgaTsKCQlpZiAodG1wLT5yZGV2KQoJCQlwcmludGsoIiBkaXNrICVkLCB3bzolZCwgbzolZCwgZGV2OiVzXG4iLAoJCQkJaSwgIXRlc3RfYml0KEluX3N5bmMsICZ0bXAtPnJkZXYtPmZsYWdzKSwgIXRlc3RfYml0KEZhdWx0eSwgJnRtcC0+cmRldi0+ZmxhZ3MpLAoJCQkJYmRldm5hbWUodG1wLT5yZGV2LT5iZGV2LGIpKTsKCX0KfQoKc3RhdGljIHZvaWQgY2xvc2Vfc3luYyhjb25mX3QgKmNvbmYpCnsKCXNwaW5fbG9ja19pcnEoJmNvbmYtPnJlc3luY19sb2NrKTsKCXdhaXRfZXZlbnRfbG9ja19pcnEoY29uZi0+d2FpdF9yZXN1bWUsICFjb25mLT5iYXJyaWVyLAoJCQkgICAgY29uZi0+cmVzeW5jX2xvY2ssIAlyYWlkMV91bnBsdWcoY29uZi0+bWRkZXYtPnF1ZXVlKSk7CglzcGluX3VubG9ja19pcnEoJmNvbmYtPnJlc3luY19sb2NrKTsKCglpZiAoY29uZi0+YmFycmllcikgQlVHKCk7CglpZiAod2FpdHF1ZXVlX2FjdGl2ZSgmY29uZi0+d2FpdF9pZGxlKSkgQlVHKCk7CgoJbWVtcG9vbF9kZXN0cm95KGNvbmYtPnIxYnVmX3Bvb2wpOwoJY29uZi0+cjFidWZfcG9vbCA9IE5VTEw7Cn0KCnN0YXRpYyBpbnQgcmFpZDFfc3BhcmVfYWN0aXZlKG1kZGV2X3QgKm1kZGV2KQp7CglpbnQgaTsKCWNvbmZfdCAqY29uZiA9IG1kZGV2LT5wcml2YXRlOwoJbWlycm9yX2luZm9fdCAqdG1wOwoKCS8qCgkgKiBGaW5kIGFsbCBmYWlsZWQgZGlza3Mgd2l0aGluIHRoZSBSQUlEMSBjb25maWd1cmF0aW9uIAoJICogYW5kIG1hcmsgdGhlbSByZWFkYWJsZQoJICovCglmb3IgKGkgPSAwOyBpIDwgY29uZi0+cmFpZF9kaXNrczsgaSsrKSB7CgkJdG1wID0gY29uZi0+bWlycm9ycyArIGk7CgkJaWYgKHRtcC0+cmRldiAKCQkgICAgJiYgIXRlc3RfYml0KEZhdWx0eSwgJnRtcC0+cmRldi0+ZmxhZ3MpCgkJICAgICYmICF0ZXN0X2JpdChJbl9zeW5jLCAmdG1wLT5yZGV2LT5mbGFncykpIHsKCQkJY29uZi0+d29ya2luZ19kaXNrcysrOwoJCQltZGRldi0+ZGVncmFkZWQtLTsKCQkJc2V0X2JpdChJbl9zeW5jLCAmdG1wLT5yZGV2LT5mbGFncyk7CgkJfQoJfQoKCXByaW50X2NvbmYoY29uZik7CglyZXR1cm4gMDsKfQoKCnN0YXRpYyBpbnQgcmFpZDFfYWRkX2Rpc2sobWRkZXZfdCAqbWRkZXYsIG1ka19yZGV2X3QgKnJkZXYpCnsKCWNvbmZfdCAqY29uZiA9IG1kZGV2LT5wcml2YXRlOwoJaW50IGZvdW5kID0gMDsKCWludCBtaXJyb3IgPSAwOwoJbWlycm9yX2luZm9fdCAqcDsKCglpZiAocmRldi0+c2F2ZWRfcmFpZF9kaXNrID49IDAgJiYKCSAgICBjb25mLT5taXJyb3JzW3JkZXYtPnNhdmVkX3JhaWRfZGlza10ucmRldiA9PSBOVUxMKQoJCW1pcnJvciA9IHJkZXYtPnNhdmVkX3JhaWRfZGlzazsKCWZvciAobWlycm9yPTA7IG1pcnJvciA8IG1kZGV2LT5yYWlkX2Rpc2tzOyBtaXJyb3IrKykKCQlpZiAoICEocD1jb25mLT5taXJyb3JzK21pcnJvciktPnJkZXYpIHsKCgkJCWJsa19xdWV1ZV9zdGFja19saW1pdHMobWRkZXYtPnF1ZXVlLAoJCQkJCSAgICAgICByZGV2LT5iZGV2LT5iZF9kaXNrLT5xdWV1ZSk7CgkJCS8qIGFzIHdlIGRvbid0IGhvbm91ciBtZXJnZV9idmVjX2ZuLCB3ZSBtdXN0IG5ldmVyIHJpc2sKCQkJICogdmlvbGF0aW5nIGl0LCBzbyBsaW1pdCAtPm1heF9zZWN0b3IgdG8gb25lIFBBR0UsIGFzCgkJCSAqIGEgb25lIHBhZ2UgcmVxdWVzdCBpcyBuZXZlciBpbiB2aW9sYXRpb24uCgkJCSAqLwoJCQlpZiAocmRldi0+YmRldi0+YmRfZGlzay0+cXVldWUtPm1lcmdlX2J2ZWNfZm4gJiYKCQkJICAgIG1kZGV2LT5xdWV1ZS0+bWF4X3NlY3RvcnMgPiAoUEFHRV9TSVpFPj45KSkKCQkJCWJsa19xdWV1ZV9tYXhfc2VjdG9ycyhtZGRldi0+cXVldWUsIFBBR0VfU0laRT4+OSk7CgoJCQlwLT5oZWFkX3Bvc2l0aW9uID0gMDsKCQkJcmRldi0+cmFpZF9kaXNrID0gbWlycm9yOwoJCQlmb3VuZCA9IDE7CgkJCWlmIChyZGV2LT5zYXZlZF9yYWlkX2Rpc2sgIT0gbWlycm9yKQoJCQkJY29uZi0+ZnVsbHN5bmMgPSAxOwoJCQlyY3VfYXNzaWduX3BvaW50ZXIocC0+cmRldiwgcmRldik7CgkJCWJyZWFrOwoJCX0KCglwcmludF9jb25mKGNvbmYpOwoJcmV0dXJuIGZvdW5kOwp9CgpzdGF0aWMgaW50IHJhaWQxX3JlbW92ZV9kaXNrKG1kZGV2X3QgKm1kZGV2LCBpbnQgbnVtYmVyKQp7Cgljb25mX3QgKmNvbmYgPSBtZGRldi0+cHJpdmF0ZTsKCWludCBlcnIgPSAwOwoJbWRrX3JkZXZfdCAqcmRldjsKCW1pcnJvcl9pbmZvX3QgKnAgPSBjb25mLT5taXJyb3JzKyBudW1iZXI7CgoJcHJpbnRfY29uZihjb25mKTsKCXJkZXYgPSBwLT5yZGV2OwoJaWYgKHJkZXYpIHsKCQlpZiAodGVzdF9iaXQoSW5fc3luYywgJnJkZXYtPmZsYWdzKSB8fAoJCSAgICBhdG9taWNfcmVhZCgmcmRldi0+bnJfcGVuZGluZykpIHsKCQkJZXJyID0gLUVCVVNZOwoJCQlnb3RvIGFib3J0OwoJCX0KCQlwLT5yZGV2ID0gTlVMTDsKCQlzeW5jaHJvbml6ZV9yY3UoKTsKCQlpZiAoYXRvbWljX3JlYWQoJnJkZXYtPm5yX3BlbmRpbmcpKSB7CgkJCS8qIGxvc3QgdGhlIHJhY2UsIHRyeSBsYXRlciAqLwoJCQllcnIgPSAtRUJVU1k7CgkJCXAtPnJkZXYgPSByZGV2OwoJCX0KCX0KYWJvcnQ6CgoJcHJpbnRfY29uZihjb25mKTsKCXJldHVybiBlcnI7Cn0KCgpzdGF0aWMgaW50IGVuZF9zeW5jX3JlYWQoc3RydWN0IGJpbyAqYmlvLCB1bnNpZ25lZCBpbnQgYnl0ZXNfZG9uZSwgaW50IGVycm9yKQp7CglpbnQgdXB0b2RhdGUgPSB0ZXN0X2JpdChCSU9fVVBUT0RBVEUsICZiaW8tPmJpX2ZsYWdzKTsKCXIxYmlvX3QgKiByMV9iaW8gPSAocjFiaW9fdCAqKShiaW8tPmJpX3ByaXZhdGUpOwoJY29uZl90ICpjb25mID0gbWRkZXZfdG9fY29uZihyMV9iaW8tPm1kZGV2KTsKCglpZiAoYmlvLT5iaV9zaXplKQoJCXJldHVybiAxOwoKCWlmIChyMV9iaW8tPmJpb3NbcjFfYmlvLT5yZWFkX2Rpc2tdICE9IGJpbykKCQlCVUcoKTsKCXVwZGF0ZV9oZWFkX3BvcyhyMV9iaW8tPnJlYWRfZGlzaywgcjFfYmlvKTsKCS8qCgkgKiB3ZSBoYXZlIHJlYWQgYSBibG9jaywgbm93IGl0IG5lZWRzIHRvIGJlIHJlLXdyaXR0ZW4sCgkgKiBvciByZS1yZWFkIGlmIHRoZSByZWFkIGZhaWxlZC4KCSAqIFdlIGRvbid0IGRvIG11Y2ggaGVyZSwganVzdCBzY2hlZHVsZSBoYW5kbGluZyBieSByYWlkMWQKCSAqLwoJaWYgKCF1cHRvZGF0ZSkgewoJCW1kX2Vycm9yKHIxX2Jpby0+bWRkZXYsCgkJCSBjb25mLT5taXJyb3JzW3IxX2Jpby0+cmVhZF9kaXNrXS5yZGV2KTsKCX0gZWxzZQoJCXNldF9iaXQoUjFCSU9fVXB0b2RhdGUsICZyMV9iaW8tPnN0YXRlKTsKCXJkZXZfZGVjX3BlbmRpbmcoY29uZi0+bWlycm9yc1tyMV9iaW8tPnJlYWRfZGlza10ucmRldiwgY29uZi0+bWRkZXYpOwoJcmVzY2hlZHVsZV9yZXRyeShyMV9iaW8pOwoJcmV0dXJuIDA7Cn0KCnN0YXRpYyBpbnQgZW5kX3N5bmNfd3JpdGUoc3RydWN0IGJpbyAqYmlvLCB1bnNpZ25lZCBpbnQgYnl0ZXNfZG9uZSwgaW50IGVycm9yKQp7CglpbnQgdXB0b2RhdGUgPSB0ZXN0X2JpdChCSU9fVVBUT0RBVEUsICZiaW8tPmJpX2ZsYWdzKTsKCXIxYmlvX3QgKiByMV9iaW8gPSAocjFiaW9fdCAqKShiaW8tPmJpX3ByaXZhdGUpOwoJbWRkZXZfdCAqbWRkZXYgPSByMV9iaW8tPm1kZGV2OwoJY29uZl90ICpjb25mID0gbWRkZXZfdG9fY29uZihtZGRldik7CglpbnQgaTsKCWludCBtaXJyb3I9MDsKCglpZiAoYmlvLT5iaV9zaXplKQoJCXJldHVybiAxOwoKCWZvciAoaSA9IDA7IGkgPCBjb25mLT5yYWlkX2Rpc2tzOyBpKyspCgkJaWYgKHIxX2Jpby0+Ymlvc1tpXSA9PSBiaW8pIHsKCQkJbWlycm9yID0gaTsKCQkJYnJlYWs7CgkJfQoJaWYgKCF1cHRvZGF0ZSkKCQltZF9lcnJvcihtZGRldiwgY29uZi0+bWlycm9yc1ttaXJyb3JdLnJkZXYpOwoKCXVwZGF0ZV9oZWFkX3BvcyhtaXJyb3IsIHIxX2Jpbyk7CgoJaWYgKGF0b21pY19kZWNfYW5kX3Rlc3QoJnIxX2Jpby0+cmVtYWluaW5nKSkgewoJCW1kX2RvbmVfc3luYyhtZGRldiwgcjFfYmlvLT5zZWN0b3JzLCB1cHRvZGF0ZSk7CgkJcHV0X2J1ZihyMV9iaW8pOwoJfQoJcmRldl9kZWNfcGVuZGluZyhjb25mLT5taXJyb3JzW21pcnJvcl0ucmRldiwgbWRkZXYpOwoJcmV0dXJuIDA7Cn0KCnN0YXRpYyB2b2lkIHN5bmNfcmVxdWVzdF93cml0ZShtZGRldl90ICptZGRldiwgcjFiaW9fdCAqcjFfYmlvKQp7Cgljb25mX3QgKmNvbmYgPSBtZGRldl90b19jb25mKG1kZGV2KTsKCWludCBpOwoJaW50IGRpc2tzID0gY29uZi0+cmFpZF9kaXNrczsKCXN0cnVjdCBiaW8gKmJpbywgKndiaW87CgoJYmlvID0gcjFfYmlvLT5iaW9zW3IxX2Jpby0+cmVhZF9kaXNrXTsKCi8qCglpZiAocjFfYmlvLT5zZWN0b3IgPT0gMCkgcHJpbnRrKCJGaXJzdCBzeW5jIHdyaXRlIHN0YXJ0c3NcbiIpOwoqLwoJLyoKCSAqIHNjaGVkdWxlIHdyaXRlcwoJICovCglpZiAoIXRlc3RfYml0KFIxQklPX1VwdG9kYXRlLCAmcjFfYmlvLT5zdGF0ZSkpIHsKCQkvKgoJCSAqIFRoZXJlIGlzIG5vIHBvaW50IHRyeWluZyBhIHJlYWQtZm9yLXJlY29uc3RydWN0IGFzCgkJICogcmVjb25zdHJ1Y3QgaXMgYWJvdXQgdG8gYmUgYWJvcnRlZAoJCSAqLwoJCWNoYXIgYltCREVWTkFNRV9TSVpFXTsKCQlwcmludGsoS0VSTl9BTEVSVCAicmFpZDE6ICVzOiB1bnJlY292ZXJhYmxlIEkvTyByZWFkIGVycm9yIgoJCQkiIGZvciBibG9jayAlbGx1XG4iLAoJCQliZGV2bmFtZShiaW8tPmJpX2JkZXYsYiksIAoJCQkodW5zaWduZWQgbG9uZyBsb25nKXIxX2Jpby0+c2VjdG9yKTsKCQltZF9kb25lX3N5bmMobWRkZXYsIHIxX2Jpby0+c2VjdG9ycywgMCk7CgkJcHV0X2J1ZihyMV9iaW8pOwoJCXJldHVybjsKCX0KCglhdG9taWNfc2V0KCZyMV9iaW8tPnJlbWFpbmluZywgMSk7Cglmb3IgKGkgPSAwOyBpIDwgZGlza3MgOyBpKyspIHsKCQl3YmlvID0gcjFfYmlvLT5iaW9zW2ldOwoJCWlmICh3YmlvLT5iaV9lbmRfaW8gIT0gZW5kX3N5bmNfd3JpdGUpCgkJCWNvbnRpbnVlOwoKCQlhdG9taWNfaW5jKCZjb25mLT5taXJyb3JzW2ldLnJkZXYtPm5yX3BlbmRpbmcpOwoJCWF0b21pY19pbmMoJnIxX2Jpby0+cmVtYWluaW5nKTsKCQltZF9zeW5jX2FjY3QoY29uZi0+bWlycm9yc1tpXS5yZGV2LT5iZGV2LCB3YmlvLT5iaV9zaXplID4+IDkpOwoKCQlnZW5lcmljX21ha2VfcmVxdWVzdCh3YmlvKTsKCX0KCglpZiAoYXRvbWljX2RlY19hbmRfdGVzdCgmcjFfYmlvLT5yZW1haW5pbmcpKSB7CgkJLyogaWYgd2UncmUgaGVyZSwgYWxsIHdyaXRlKHMpIGhhdmUgY29tcGxldGVkLCBzbyBjbGVhbiB1cCAqLwoJCW1kX2RvbmVfc3luYyhtZGRldiwgcjFfYmlvLT5zZWN0b3JzLCAxKTsKCQlwdXRfYnVmKHIxX2Jpbyk7Cgl9Cn0KCi8qCiAqIFRoaXMgaXMgYSBrZXJuZWwgdGhyZWFkIHdoaWNoOgogKgogKgkxLglSZXRyaWVzIGZhaWxlZCByZWFkIG9wZXJhdGlvbnMgb24gd29ya2luZyBtaXJyb3JzLgogKgkyLglVcGRhdGVzIHRoZSByYWlkIHN1cGVyYmxvY2sgd2hlbiBwcm9ibGVtcyBlbmNvdW50ZXIuCiAqCTMuCVBlcmZvcm1zIHdyaXRlcyBmb2xsb3dpbmcgcmVhZHMgZm9yIGFycmF5IHN5bmNyb25pc2luZy4KICovCgpzdGF0aWMgdm9pZCByYWlkMWQobWRkZXZfdCAqbWRkZXYpCnsKCXIxYmlvX3QgKnIxX2JpbzsKCXN0cnVjdCBiaW8gKmJpbzsKCXVuc2lnbmVkIGxvbmcgZmxhZ3M7Cgljb25mX3QgKmNvbmYgPSBtZGRldl90b19jb25mKG1kZGV2KTsKCXN0cnVjdCBsaXN0X2hlYWQgKmhlYWQgPSAmY29uZi0+cmV0cnlfbGlzdDsKCWludCB1bnBsdWc9MDsKCW1ka19yZGV2X3QgKnJkZXY7CgoJbWRfY2hlY2tfcmVjb3ZlcnkobWRkZXYpOwoJCglmb3IgKDs7KSB7CgkJY2hhciBiW0JERVZOQU1FX1NJWkVdOwoJCXNwaW5fbG9ja19pcnFzYXZlKCZjb25mLT5kZXZpY2VfbG9jaywgZmxhZ3MpOwoKCQlpZiAoY29uZi0+cGVuZGluZ19iaW9fbGlzdC5oZWFkKSB7CgkJCWJpbyA9IGJpb19saXN0X2dldCgmY29uZi0+cGVuZGluZ19iaW9fbGlzdCk7CgkJCWJsa19yZW1vdmVfcGx1ZyhtZGRldi0+cXVldWUpOwoJCQlzcGluX3VubG9ja19pcnFyZXN0b3JlKCZjb25mLT5kZXZpY2VfbG9jaywgZmxhZ3MpOwoJCQkvKiBmbHVzaCBhbnkgcGVuZGluZyBiaXRtYXAgd3JpdGVzIHRvIGRpc2sgYmVmb3JlIHByb2NlZWRpbmcgdy8gSS9PICovCgkJCWlmIChiaXRtYXBfdW5wbHVnKG1kZGV2LT5iaXRtYXApICE9IDApCgkJCQlwcmludGsoIiVzOiBiaXRtYXAgZmlsZSB3cml0ZSBmYWlsZWQhXG4iLCBtZG5hbWUobWRkZXYpKTsKCgkJCXdoaWxlIChiaW8pIHsgLyogc3VibWl0IHBlbmRpbmcgd3JpdGVzICovCgkJCQlzdHJ1Y3QgYmlvICpuZXh0ID0gYmlvLT5iaV9uZXh0OwoJCQkJYmlvLT5iaV9uZXh0ID0gTlVMTDsKCQkJCWdlbmVyaWNfbWFrZV9yZXF1ZXN0KGJpbyk7CgkJCQliaW8gPSBuZXh0OwoJCQl9CgkJCXVucGx1ZyA9IDE7CgoJCQljb250aW51ZTsKCQl9CgoJCWlmIChsaXN0X2VtcHR5KGhlYWQpKQoJCQlicmVhazsKCQlyMV9iaW8gPSBsaXN0X2VudHJ5KGhlYWQtPnByZXYsIHIxYmlvX3QsIHJldHJ5X2xpc3QpOwoJCWxpc3RfZGVsKGhlYWQtPnByZXYpOwoJCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJmNvbmYtPmRldmljZV9sb2NrLCBmbGFncyk7CgoJCW1kZGV2ID0gcjFfYmlvLT5tZGRldjsKCQljb25mID0gbWRkZXZfdG9fY29uZihtZGRldik7CgkJaWYgKHRlc3RfYml0KFIxQklPX0lzU3luYywgJnIxX2Jpby0+c3RhdGUpKSB7CgkJCXN5bmNfcmVxdWVzdF93cml0ZShtZGRldiwgcjFfYmlvKTsKCQkJdW5wbHVnID0gMTsKCQl9IGVsc2UgaWYgKHRlc3RfYml0KFIxQklPX0JhcnJpZXJSZXRyeSwgJnIxX2Jpby0+c3RhdGUpKSB7CgkJCS8qIHNvbWUgcmVxdWVzdHMgaW4gdGhlIHIxYmlvIHdlcmUgQklPX1JXX0JBUlJJRVIKCQkJICogcmVxdWVzdHMgd2hpY2ggZmFpbGVkIHdpdGggLUVOT1RTVVBQLiAgSG9odW1tLi4KCQkJICogQmV0dGVyIHJlc3VibWl0IHdpdGhvdXQgdGhlIGJhcnJpZXIuCgkJCSAqIFdlIGtub3cgd2hpY2ggZGV2aWNlcyB0byByZXN1Ym1pdCBmb3IsIGJlY2F1c2UKCQkJICogYWxsIG90aGVycyBoYXZlIGhhZCB0aGVpciBiaW9zW10gZW50cnkgY2xlYXJlZC4KCQkJICovCgkJCWludCBpOwoJCQljbGVhcl9iaXQoUjFCSU9fQmFycmllclJldHJ5LCAmcjFfYmlvLT5zdGF0ZSk7CgkJCWNsZWFyX2JpdChSMUJJT19CYXJyaWVyLCAmcjFfYmlvLT5zdGF0ZSk7CgkJCWZvciAoaT0wOyBpIDwgY29uZi0+cmFpZF9kaXNrczsgaSsrKQoJCQkJaWYgKHIxX2Jpby0+Ymlvc1tpXSkgewoJCQkJCXN0cnVjdCBiaW9fdmVjICpidmVjOwoJCQkJCWludCBqOwoKCQkJCQliaW8gPSBiaW9fY2xvbmUocjFfYmlvLT5tYXN0ZXJfYmlvLCBHRlBfTk9JTyk7CgkJCQkJLyogY29weSBwYWdlcyBmcm9tIHRoZSBmYWlsZWQgYmlvLCBhcwoJCQkJCSAqIHRoaXMgbWlnaHQgYmUgYSB3cml0ZS1iZWhpbmQgZGV2aWNlICovCgkJCQkJX19iaW9fZm9yX2VhY2hfc2VnbWVudChidmVjLCBiaW8sIGosIDApCgkJCQkJCWJ2ZWMtPmJ2X3BhZ2UgPSBiaW9faW92ZWNfaWR4KHIxX2Jpby0+Ymlvc1tpXSwgaiktPmJ2X3BhZ2U7CgkJCQkJYmlvX3B1dChyMV9iaW8tPmJpb3NbaV0pOwoJCQkJCWJpby0+Ymlfc2VjdG9yID0gcjFfYmlvLT5zZWN0b3IgKwoJCQkJCQljb25mLT5taXJyb3JzW2ldLnJkZXYtPmRhdGFfb2Zmc2V0OwoJCQkJCWJpby0+YmlfYmRldiA9IGNvbmYtPm1pcnJvcnNbaV0ucmRldi0+YmRldjsKCQkJCQliaW8tPmJpX2VuZF9pbyA9IHJhaWQxX2VuZF93cml0ZV9yZXF1ZXN0OwoJCQkJCWJpby0+YmlfcncgPSBXUklURTsKCQkJCQliaW8tPmJpX3ByaXZhdGUgPSByMV9iaW87CgkJCQkJcjFfYmlvLT5iaW9zW2ldID0gYmlvOwoJCQkJCWdlbmVyaWNfbWFrZV9yZXF1ZXN0KGJpbyk7CgkJCQl9CgkJfSBlbHNlIHsKCQkJaW50IGRpc2s7CgkJCWJpbyA9IHIxX2Jpby0+Ymlvc1tyMV9iaW8tPnJlYWRfZGlza107CgkJCWlmICgoZGlzaz1yZWFkX2JhbGFuY2UoY29uZiwgcjFfYmlvKSkgPT0gLTEpIHsKCQkJCXByaW50ayhLRVJOX0FMRVJUICJyYWlkMTogJXM6IHVucmVjb3ZlcmFibGUgSS9PIgoJCQkJICAgICAgICIgcmVhZCBlcnJvciBmb3IgYmxvY2sgJWxsdVxuIiwKCQkJCSAgICAgICBiZGV2bmFtZShiaW8tPmJpX2JkZXYsYiksCgkJCQkgICAgICAgKHVuc2lnbmVkIGxvbmcgbG9uZylyMV9iaW8tPnNlY3Rvcik7CgkJCQlyYWlkX2VuZF9iaW9faW8ocjFfYmlvKTsKCQkJfSBlbHNlIHsKCQkJCXIxX2Jpby0+Ymlvc1tyMV9iaW8tPnJlYWRfZGlza10gPSBOVUxMOwoJCQkJcjFfYmlvLT5yZWFkX2Rpc2sgPSBkaXNrOwoJCQkJYmlvX3B1dChiaW8pOwoJCQkJYmlvID0gYmlvX2Nsb25lKHIxX2Jpby0+bWFzdGVyX2JpbywgR0ZQX05PSU8pOwoJCQkJcjFfYmlvLT5iaW9zW3IxX2Jpby0+cmVhZF9kaXNrXSA9IGJpbzsKCQkJCXJkZXYgPSBjb25mLT5taXJyb3JzW2Rpc2tdLnJkZXY7CgkJCQlpZiAocHJpbnRrX3JhdGVsaW1pdCgpKQoJCQkJCXByaW50ayhLRVJOX0VSUiAicmFpZDE6ICVzOiByZWRpcmVjdGluZyBzZWN0b3IgJWxsdSB0byIKCQkJCQkgICAgICAgIiBhbm90aGVyIG1pcnJvclxuIiwKCQkJCQkgICAgICAgYmRldm5hbWUocmRldi0+YmRldixiKSwKCQkJCQkgICAgICAgKHVuc2lnbmVkIGxvbmcgbG9uZylyMV9iaW8tPnNlY3Rvcik7CgkJCQliaW8tPmJpX3NlY3RvciA9IHIxX2Jpby0+c2VjdG9yICsgcmRldi0+ZGF0YV9vZmZzZXQ7CgkJCQliaW8tPmJpX2JkZXYgPSByZGV2LT5iZGV2OwoJCQkJYmlvLT5iaV9lbmRfaW8gPSByYWlkMV9lbmRfcmVhZF9yZXF1ZXN0OwoJCQkJYmlvLT5iaV9ydyA9IFJFQUQ7CgkJCQliaW8tPmJpX3ByaXZhdGUgPSByMV9iaW87CgkJCQl1bnBsdWcgPSAxOwoJCQkJZ2VuZXJpY19tYWtlX3JlcXVlc3QoYmlvKTsKCQkJfQoJCX0KCX0KCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJmNvbmYtPmRldmljZV9sb2NrLCBmbGFncyk7CglpZiAodW5wbHVnKQoJCXVucGx1Z19zbGF2ZXMobWRkZXYpOwp9CgoKc3RhdGljIGludCBpbml0X3Jlc3luYyhjb25mX3QgKmNvbmYpCnsKCWludCBidWZmczsKCglidWZmcyA9IFJFU1lOQ19XSU5ET1cgLyBSRVNZTkNfQkxPQ0tfU0laRTsKCWlmIChjb25mLT5yMWJ1Zl9wb29sKQoJCUJVRygpOwoJY29uZi0+cjFidWZfcG9vbCA9IG1lbXBvb2xfY3JlYXRlKGJ1ZmZzLCByMWJ1Zl9wb29sX2FsbG9jLCByMWJ1Zl9wb29sX2ZyZWUsCgkJCQkJICBjb25mLT5wb29saW5mbyk7CglpZiAoIWNvbmYtPnIxYnVmX3Bvb2wpCgkJcmV0dXJuIC1FTk9NRU07Cgljb25mLT5uZXh0X3Jlc3luYyA9IDA7CglyZXR1cm4gMDsKfQoKLyoKICogcGVyZm9ybSBhICJzeW5jIiBvbiBvbmUgImJsb2NrIgogKgogKiBXZSBuZWVkIHRvIG1ha2Ugc3VyZSB0aGF0IG5vIG5vcm1hbCBJL08gcmVxdWVzdCAtIHBhcnRpY3VsYXJseSB3cml0ZQogKiByZXF1ZXN0cyAtIGNvbmZsaWN0IHdpdGggYWN0aXZlIHN5bmMgcmVxdWVzdHMuCiAqCiAqIFRoaXMgaXMgYWNoaWV2ZWQgYnkgdHJhY2tpbmcgcGVuZGluZyByZXF1ZXN0cyBhbmQgYSAnYmFycmllcicgY29uY2VwdAogKiB0aGF0IGNhbiBiZSBpbnN0YWxsZWQgdG8gZXhjbHVkZSBub3JtYWwgSU8gcmVxdWVzdHMuCiAqLwoKc3RhdGljIHNlY3Rvcl90IHN5bmNfcmVxdWVzdChtZGRldl90ICptZGRldiwgc2VjdG9yX3Qgc2VjdG9yX25yLCBpbnQgKnNraXBwZWQsIGludCBnb19mYXN0ZXIpCnsKCWNvbmZfdCAqY29uZiA9IG1kZGV2X3RvX2NvbmYobWRkZXYpOwoJbWlycm9yX2luZm9fdCAqbWlycm9yOwoJcjFiaW9fdCAqcjFfYmlvOwoJc3RydWN0IGJpbyAqYmlvOwoJc2VjdG9yX3QgbWF4X3NlY3RvciwgbnJfc2VjdG9yczsKCWludCBkaXNrOwoJaW50IGk7CglpbnQgd29ubHk7CglpbnQgd3JpdGVfdGFyZ2V0cyA9IDA7CglpbnQgc3luY19ibG9ja3M7CglpbnQgc3RpbGxfZGVncmFkZWQgPSAwOwoKCWlmICghY29uZi0+cjFidWZfcG9vbCkKCXsKLyoKCQlwcmludGsoInN5bmMgc3RhcnQgLSBiaXRtYXAgJXBcbiIsIG1kZGV2LT5iaXRtYXApOwoqLwoJCWlmIChpbml0X3Jlc3luYyhjb25mKSkKCQkJcmV0dXJuIDA7Cgl9CgoJbWF4X3NlY3RvciA9IG1kZGV2LT5zaXplIDw8IDE7CglpZiAoc2VjdG9yX25yID49IG1heF9zZWN0b3IpIHsKCQkvKiBJZiB3ZSBhYm9ydGVkLCB3ZSBuZWVkIHRvIGFib3J0IHRoZQoJCSAqIHN5bmMgb24gdGhlICdjdXJyZW50JyBiaXRtYXAgY2h1bmsgKHRoZXJlIHdpbGwKCQkgKiBvbmx5IGJlIG9uZSBpbiByYWlkMSByZXN5bmMuCgkJICogV2UgY2FuIGZpbmQgdGhlIGN1cnJlbnQgYWRkZXNzIGluIG1kZGV2LT5jdXJyX3Jlc3luYwoJCSAqLwoJCWlmIChtZGRldi0+Y3Vycl9yZXN5bmMgPCBtYXhfc2VjdG9yKSAvKiBhYm9ydGVkICovCgkJCWJpdG1hcF9lbmRfc3luYyhtZGRldi0+Yml0bWFwLCBtZGRldi0+Y3Vycl9yZXN5bmMsCgkJCQkJCSZzeW5jX2Jsb2NrcywgMSk7CgkJZWxzZSAvKiBjb21wbGV0ZWQgc3luYyAqLwoJCQljb25mLT5mdWxsc3luYyA9IDA7CgoJCWJpdG1hcF9jbG9zZV9zeW5jKG1kZGV2LT5iaXRtYXApOwoJCWNsb3NlX3N5bmMoY29uZik7CgkJcmV0dXJuIDA7Cgl9CgoJLyogYmVmb3JlIGJ1aWxkaW5nIGEgcmVxdWVzdCwgY2hlY2sgaWYgd2UgY2FuIHNraXAgdGhlc2UgYmxvY2tzLi4KCSAqIFRoaXMgY2FsbCB0aGUgYml0bWFwX3N0YXJ0X3N5bmMgZG9lc24ndCBhY3R1YWxseSByZWNvcmQgYW55dGhpbmcKCSAqLwoJaWYgKCFiaXRtYXBfc3RhcnRfc3luYyhtZGRldi0+Yml0bWFwLCBzZWN0b3JfbnIsICZzeW5jX2Jsb2NrcywgMSkgJiYKCSAgICAhY29uZi0+ZnVsbHN5bmMgJiYgIXRlc3RfYml0KE1EX1JFQ09WRVJZX1JFUVVFU1RFRCwgJm1kZGV2LT5yZWNvdmVyeSkpIHsKCQkvKiBXZSBjYW4gc2tpcCB0aGlzIGJsb2NrLCBhbmQgcHJvYmFibHkgc2V2ZXJhbCBtb3JlICovCgkJKnNraXBwZWQgPSAxOwoJCXJldHVybiBzeW5jX2Jsb2NrczsKCX0KCS8qCgkgKiBJZiB0aGVyZSBpcyBub24tcmVzeW5jIGFjdGl2aXR5IHdhaXRpbmcgZm9yIHVzIHRoZW4KCSAqIHB1dCBpbiBhIGRlbGF5IHRvIHRocm90dGxlIHJlc3luYy4KCSAqLwoJaWYgKCFnb19mYXN0ZXIgJiYgd2FpdHF1ZXVlX2FjdGl2ZSgmY29uZi0+d2FpdF9yZXN1bWUpKQoJCW1zbGVlcF9pbnRlcnJ1cHRpYmxlKDEwMDApOwoJZGV2aWNlX2JhcnJpZXIoY29uZiwgc2VjdG9yX25yICsgUkVTWU5DX1NFQ1RPUlMpOwoKCS8qCgkgKiBJZiByZWNvbnN0cnVjdGluZywgYW5kID4xIHdvcmtpbmcgZGlzYywKCSAqIGNvdWxkIGRlZGljYXRlIG9uZSB0byByZWJ1aWxkIGFuZCBvdGhlcnMgdG8KCSAqIHNlcnZpY2UgcmVhZCByZXF1ZXN0cyAuLgoJICovCglkaXNrID0gY29uZi0+bGFzdF91c2VkOwoJLyogbWFrZSBzdXJlIGRpc2sgaXMgb3BlcmF0aW9uYWwgKi8KCXdvbmx5ID0gZGlzazsKCXdoaWxlIChjb25mLT5taXJyb3JzW2Rpc2tdLnJkZXYgPT0gTlVMTCB8fAoJICAgICAgICF0ZXN0X2JpdChJbl9zeW5jLCAmY29uZi0+bWlycm9yc1tkaXNrXS5yZGV2LT5mbGFncykgfHwKCSAgICAgICB0ZXN0X2JpdChXcml0ZU1vc3RseSwgJmNvbmYtPm1pcnJvcnNbZGlza10ucmRldi0+ZmxhZ3MpCgkJKSB7CgkJaWYgKGNvbmYtPm1pcnJvcnNbZGlza10ucmRldiAgJiYKCQkgICAgdGVzdF9iaXQoSW5fc3luYywgJmNvbmYtPm1pcnJvcnNbZGlza10ucmRldi0+ZmxhZ3MpKQoJCQl3b25seSA9IGRpc2s7CgkJaWYgKGRpc2sgPD0gMCkKCQkJZGlzayA9IGNvbmYtPnJhaWRfZGlza3M7CgkJZGlzay0tOwoJCWlmIChkaXNrID09IGNvbmYtPmxhc3RfdXNlZCkgewoJCQlkaXNrID0gd29ubHk7CgkJCWJyZWFrOwoJCX0KCX0KCWNvbmYtPmxhc3RfdXNlZCA9IGRpc2s7CglhdG9taWNfaW5jKCZjb25mLT5taXJyb3JzW2Rpc2tdLnJkZXYtPm5yX3BlbmRpbmcpOwoKCgltaXJyb3IgPSBjb25mLT5taXJyb3JzICsgZGlzazsKCglyMV9iaW8gPSBtZW1wb29sX2FsbG9jKGNvbmYtPnIxYnVmX3Bvb2wsIEdGUF9OT0lPKTsKCglzcGluX2xvY2tfaXJxKCZjb25mLT5yZXN5bmNfbG9jayk7Cgljb25mLT5ucl9wZW5kaW5nKys7CglzcGluX3VubG9ja19pcnEoJmNvbmYtPnJlc3luY19sb2NrKTsKCglyMV9iaW8tPm1kZGV2ID0gbWRkZXY7CglyMV9iaW8tPnNlY3RvciA9IHNlY3Rvcl9ucjsKCXIxX2Jpby0+c3RhdGUgPSAwOwoJc2V0X2JpdChSMUJJT19Jc1N5bmMsICZyMV9iaW8tPnN0YXRlKTsKCXIxX2Jpby0+cmVhZF9kaXNrID0gZGlzazsKCglmb3IgKGk9MDsgaSA8IGNvbmYtPnJhaWRfZGlza3M7IGkrKykgewoJCWJpbyA9IHIxX2Jpby0+Ymlvc1tpXTsKCgkJLyogdGFrZSBmcm9tIGJpb19pbml0ICovCgkJYmlvLT5iaV9uZXh0ID0gTlVMTDsKCQliaW8tPmJpX2ZsYWdzIHw9IDEgPDwgQklPX1VQVE9EQVRFOwoJCWJpby0+YmlfcncgPSAwOwoJCWJpby0+YmlfdmNudCA9IDA7CgkJYmlvLT5iaV9pZHggPSAwOwoJCWJpby0+YmlfcGh5c19zZWdtZW50cyA9IDA7CgkJYmlvLT5iaV9od19zZWdtZW50cyA9IDA7CgkJYmlvLT5iaV9zaXplID0gMDsKCQliaW8tPmJpX2VuZF9pbyA9IE5VTEw7CgkJYmlvLT5iaV9wcml2YXRlID0gTlVMTDsKCgkJaWYgKGkgPT0gZGlzaykgewoJCQliaW8tPmJpX3J3ID0gUkVBRDsKCQkJYmlvLT5iaV9lbmRfaW8gPSBlbmRfc3luY19yZWFkOwoJCX0gZWxzZSBpZiAoY29uZi0+bWlycm9yc1tpXS5yZGV2ID09IE5VTEwgfHwKCQkJICAgdGVzdF9iaXQoRmF1bHR5LCAmY29uZi0+bWlycm9yc1tpXS5yZGV2LT5mbGFncykpIHsKCQkJc3RpbGxfZGVncmFkZWQgPSAxOwoJCQljb250aW51ZTsKCQl9IGVsc2UgaWYgKCF0ZXN0X2JpdChJbl9zeW5jLCAmY29uZi0+bWlycm9yc1tpXS5yZGV2LT5mbGFncykgfHwKCQkJICAgc2VjdG9yX25yICsgUkVTWU5DX1NFQ1RPUlMgPiBtZGRldi0+cmVjb3ZlcnlfY3AgICB8fAoJCQkgICB0ZXN0X2JpdChNRF9SRUNPVkVSWV9SRVFVRVNURUQsICZtZGRldi0+cmVjb3ZlcnkpKSB7CgkJCWJpby0+YmlfcncgPSBXUklURTsKCQkJYmlvLT5iaV9lbmRfaW8gPSBlbmRfc3luY193cml0ZTsKCQkJd3JpdGVfdGFyZ2V0cyArKzsKCQl9IGVsc2UKCQkJLyogbm8gbmVlZCB0byByZWFkIG9yIHdyaXRlIGhlcmUgKi8KCQkJY29udGludWU7CgkJYmlvLT5iaV9zZWN0b3IgPSBzZWN0b3JfbnIgKyBjb25mLT5taXJyb3JzW2ldLnJkZXYtPmRhdGFfb2Zmc2V0OwoJCWJpby0+YmlfYmRldiA9IGNvbmYtPm1pcnJvcnNbaV0ucmRldi0+YmRldjsKCQliaW8tPmJpX3ByaXZhdGUgPSByMV9iaW87Cgl9CgoJaWYgKHdyaXRlX3RhcmdldHMgPT0gMCkgewoJCS8qIFRoZXJlIGlzIG5vd2hlcmUgdG8gd3JpdGUsIHNvIGFsbCBub24tc3luYwoJCSAqIGRyaXZlcyBtdXN0IGJlIGZhaWxlZCAtIHNvIHdlIGFyZSBmaW5pc2hlZAoJCSAqLwoJCXNlY3Rvcl90IHJ2ID0gbWF4X3NlY3RvciAtIHNlY3Rvcl9ucjsKCQkqc2tpcHBlZCA9IDE7CgkJcHV0X2J1ZihyMV9iaW8pOwoJCXJkZXZfZGVjX3BlbmRpbmcoY29uZi0+bWlycm9yc1tkaXNrXS5yZGV2LCBtZGRldik7CgkJcmV0dXJuIHJ2OwoJfQoKCW5yX3NlY3RvcnMgPSAwOwoJc3luY19ibG9ja3MgPSAwOwoJZG8gewoJCXN0cnVjdCBwYWdlICpwYWdlOwoJCWludCBsZW4gPSBQQUdFX1NJWkU7CgkJaWYgKHNlY3Rvcl9uciArIChsZW4+PjkpID4gbWF4X3NlY3RvcikKCQkJbGVuID0gKG1heF9zZWN0b3IgLSBzZWN0b3JfbnIpIDw8IDk7CgkJaWYgKGxlbiA9PSAwKQoJCQlicmVhazsKCQlpZiAoc3luY19ibG9ja3MgPT0gMCkgewoJCQlpZiAoIWJpdG1hcF9zdGFydF9zeW5jKG1kZGV2LT5iaXRtYXAsIHNlY3Rvcl9uciwKCQkJCQkgICAgICAgJnN5bmNfYmxvY2tzLCBzdGlsbF9kZWdyYWRlZCkgJiYKCQkJICAgICFjb25mLT5mdWxsc3luYyAmJgoJCQkgICAgIXRlc3RfYml0KE1EX1JFQ09WRVJZX1JFUVVFU1RFRCwgJm1kZGV2LT5yZWNvdmVyeSkpCgkJCQlicmVhazsKCQkJaWYgKHN5bmNfYmxvY2tzIDwgKFBBR0VfU0laRT4+OSkpCgkJCQlCVUcoKTsKCQkJaWYgKGxlbiA+IChzeW5jX2Jsb2Nrczw8OSkpCgkJCQlsZW4gPSBzeW5jX2Jsb2Nrczw8OTsKCQl9CgoJCWZvciAoaT0wIDsgaSA8IGNvbmYtPnJhaWRfZGlza3M7IGkrKykgewoJCQliaW8gPSByMV9iaW8tPmJpb3NbaV07CgkJCWlmIChiaW8tPmJpX2VuZF9pbykgewoJCQkJcGFnZSA9IHIxX2Jpby0+Ymlvc1swXS0+YmlfaW9fdmVjW2Jpby0+YmlfdmNudF0uYnZfcGFnZTsKCQkJCWlmIChiaW9fYWRkX3BhZ2UoYmlvLCBwYWdlLCBsZW4sIDApID09IDApIHsKCQkJCQkvKiBzdG9wIGhlcmUgKi8KCQkJCQlyMV9iaW8tPmJpb3NbMF0tPmJpX2lvX3ZlY1tiaW8tPmJpX3ZjbnRdLmJ2X3BhZ2UgPSBwYWdlOwoJCQkJCXdoaWxlIChpID4gMCkgewoJCQkJCQlpLS07CgkJCQkJCWJpbyA9IHIxX2Jpby0+Ymlvc1tpXTsKCQkJCQkJaWYgKGJpby0+YmlfZW5kX2lvPT1OVUxMKQoJCQkJCQkJY29udGludWU7CgkJCQkJCS8qIHJlbW92ZSBsYXN0IHBhZ2UgZnJvbSB0aGlzIGJpbyAqLwoJCQkJCQliaW8tPmJpX3ZjbnQtLTsKCQkJCQkJYmlvLT5iaV9zaXplIC09IGxlbjsKCQkJCQkJYmlvLT5iaV9mbGFncyAmPSB+KDE8PCBCSU9fU0VHX1ZBTElEKTsKCQkJCQl9CgkJCQkJZ290byBiaW9fZnVsbDsKCQkJCX0KCQkJfQoJCX0KCQlucl9zZWN0b3JzICs9IGxlbj4+OTsKCQlzZWN0b3JfbnIgKz0gbGVuPj45OwoJCXN5bmNfYmxvY2tzIC09IChsZW4+PjkpOwoJfSB3aGlsZSAocjFfYmlvLT5iaW9zW2Rpc2tdLT5iaV92Y250IDwgUkVTWU5DX1BBR0VTKTsKIGJpb19mdWxsOgoJYmlvID0gcjFfYmlvLT5iaW9zW2Rpc2tdOwoJcjFfYmlvLT5zZWN0b3JzID0gbnJfc2VjdG9yczsKCgltZF9zeW5jX2FjY3QobWlycm9yLT5yZGV2LT5iZGV2LCBucl9zZWN0b3JzKTsKCglnZW5lcmljX21ha2VfcmVxdWVzdChiaW8pOwoKCXJldHVybiBucl9zZWN0b3JzOwp9CgpzdGF0aWMgaW50IHJ1bihtZGRldl90ICptZGRldikKewoJY29uZl90ICpjb25mOwoJaW50IGksIGosIGRpc2tfaWR4OwoJbWlycm9yX2luZm9fdCAqZGlzazsKCW1ka19yZGV2X3QgKnJkZXY7CglzdHJ1Y3QgbGlzdF9oZWFkICp0bXA7CgoJaWYgKG1kZGV2LT5sZXZlbCAhPSAxKSB7CgkJcHJpbnRrKCJyYWlkMTogJXM6IHJhaWQgbGV2ZWwgbm90IHNldCB0byBtaXJyb3JpbmcgKCVkKVxuIiwKCQkgICAgICAgbWRuYW1lKG1kZGV2KSwgbWRkZXYtPmxldmVsKTsKCQlnb3RvIG91dDsKCX0KCS8qCgkgKiBjb3B5IHRoZSBhbHJlYWR5IHZlcmlmaWVkIGRldmljZXMgaW50byBvdXIgcHJpdmF0ZSBSQUlEMQoJICogYm9va2tlZXBpbmcgYXJlYS4gW3doYXRldmVyIHdlIGFsbG9jYXRlIGluIHJ1bigpLAoJICogc2hvdWxkIGJlIGZyZWVkIGluIHN0b3AoKV0KCSAqLwoJY29uZiA9IGttYWxsb2Moc2l6ZW9mKGNvbmZfdCksIEdGUF9LRVJORUwpOwoJbWRkZXYtPnByaXZhdGUgPSBjb25mOwoJaWYgKCFjb25mKQoJCWdvdG8gb3V0X25vX21lbTsKCgltZW1zZXQoY29uZiwgMCwgc2l6ZW9mKCpjb25mKSk7Cgljb25mLT5taXJyb3JzID0ga21hbGxvYyhzaXplb2Yoc3RydWN0IG1pcnJvcl9pbmZvKSptZGRldi0+cmFpZF9kaXNrcywgCgkJCQkgR0ZQX0tFUk5FTCk7CglpZiAoIWNvbmYtPm1pcnJvcnMpCgkJZ290byBvdXRfbm9fbWVtOwoKCW1lbXNldChjb25mLT5taXJyb3JzLCAwLCBzaXplb2Yoc3RydWN0IG1pcnJvcl9pbmZvKSptZGRldi0+cmFpZF9kaXNrcyk7CgoJY29uZi0+cG9vbGluZm8gPSBrbWFsbG9jKHNpemVvZigqY29uZi0+cG9vbGluZm8pLCBHRlBfS0VSTkVMKTsKCWlmICghY29uZi0+cG9vbGluZm8pCgkJZ290byBvdXRfbm9fbWVtOwoJY29uZi0+cG9vbGluZm8tPm1kZGV2ID0gbWRkZXY7Cgljb25mLT5wb29saW5mby0+cmFpZF9kaXNrcyA9IG1kZGV2LT5yYWlkX2Rpc2tzOwoJY29uZi0+cjFiaW9fcG9vbCA9IG1lbXBvb2xfY3JlYXRlKE5SX1JBSUQxX0JJT1MsIHIxYmlvX3Bvb2xfYWxsb2MsCgkJCQkJICByMWJpb19wb29sX2ZyZWUsCgkJCQkJICBjb25mLT5wb29saW5mbyk7CglpZiAoIWNvbmYtPnIxYmlvX3Bvb2wpCgkJZ290byBvdXRfbm9fbWVtOwoKCUlURVJBVEVfUkRFVihtZGRldiwgcmRldiwgdG1wKSB7CgkJZGlza19pZHggPSByZGV2LT5yYWlkX2Rpc2s7CgkJaWYgKGRpc2tfaWR4ID49IG1kZGV2LT5yYWlkX2Rpc2tzCgkJICAgIHx8IGRpc2tfaWR4IDwgMCkKCQkJY29udGludWU7CgkJZGlzayA9IGNvbmYtPm1pcnJvcnMgKyBkaXNrX2lkeDsKCgkJZGlzay0+cmRldiA9IHJkZXY7CgoJCWJsa19xdWV1ZV9zdGFja19saW1pdHMobWRkZXYtPnF1ZXVlLAoJCQkJICAgICAgIHJkZXYtPmJkZXYtPmJkX2Rpc2stPnF1ZXVlKTsKCQkvKiBhcyB3ZSBkb24ndCBob25vdXIgbWVyZ2VfYnZlY19mbiwgd2UgbXVzdCBuZXZlciByaXNrCgkJICogdmlvbGF0aW5nIGl0LCBzbyBsaW1pdCAtPm1heF9zZWN0b3IgdG8gb25lIFBBR0UsIGFzCgkJICogYSBvbmUgcGFnZSByZXF1ZXN0IGlzIG5ldmVyIGluIHZpb2xhdGlvbi4KCQkgKi8KCQlpZiAocmRldi0+YmRldi0+YmRfZGlzay0+cXVldWUtPm1lcmdlX2J2ZWNfZm4gJiYKCQkgICAgbWRkZXYtPnF1ZXVlLT5tYXhfc2VjdG9ycyA+IChQQUdFX1NJWkU+PjkpKQoJCQlibGtfcXVldWVfbWF4X3NlY3RvcnMobWRkZXYtPnF1ZXVlLCBQQUdFX1NJWkU+PjkpOwoKCQlkaXNrLT5oZWFkX3Bvc2l0aW9uID0gMDsKCQlpZiAoIXRlc3RfYml0KEZhdWx0eSwgJnJkZXYtPmZsYWdzKSAmJiB0ZXN0X2JpdChJbl9zeW5jLCAmcmRldi0+ZmxhZ3MpKQoJCQljb25mLT53b3JraW5nX2Rpc2tzKys7Cgl9Cgljb25mLT5yYWlkX2Rpc2tzID0gbWRkZXYtPnJhaWRfZGlza3M7Cgljb25mLT5tZGRldiA9IG1kZGV2OwoJc3Bpbl9sb2NrX2luaXQoJmNvbmYtPmRldmljZV9sb2NrKTsKCUlOSVRfTElTVF9IRUFEKCZjb25mLT5yZXRyeV9saXN0KTsKCWlmIChjb25mLT53b3JraW5nX2Rpc2tzID09IDEpCgkJbWRkZXYtPnJlY292ZXJ5X2NwID0gTWF4U2VjdG9yOwoKCXNwaW5fbG9ja19pbml0KCZjb25mLT5yZXN5bmNfbG9jayk7Cglpbml0X3dhaXRxdWV1ZV9oZWFkKCZjb25mLT53YWl0X2lkbGUpOwoJaW5pdF93YWl0cXVldWVfaGVhZCgmY29uZi0+d2FpdF9yZXN1bWUpOwoKCWJpb19saXN0X2luaXQoJmNvbmYtPnBlbmRpbmdfYmlvX2xpc3QpOwoJYmlvX2xpc3RfaW5pdCgmY29uZi0+Zmx1c2hpbmdfYmlvX2xpc3QpOwoKCWlmICghY29uZi0+d29ya2luZ19kaXNrcykgewoJCXByaW50ayhLRVJOX0VSUiAicmFpZDE6IG5vIG9wZXJhdGlvbmFsIG1pcnJvcnMgZm9yICVzXG4iLAoJCQltZG5hbWUobWRkZXYpKTsKCQlnb3RvIG91dF9mcmVlX2NvbmY7Cgl9CgoJbWRkZXYtPmRlZ3JhZGVkID0gMDsKCWZvciAoaSA9IDA7IGkgPCBjb25mLT5yYWlkX2Rpc2tzOyBpKyspIHsKCgkJZGlzayA9IGNvbmYtPm1pcnJvcnMgKyBpOwoKCQlpZiAoIWRpc2stPnJkZXYpIHsKCQkJZGlzay0+aGVhZF9wb3NpdGlvbiA9IDA7CgkJCW1kZGV2LT5kZWdyYWRlZCsrOwoJCX0KCX0KCgkvKgoJICogZmluZCB0aGUgZmlyc3Qgd29ya2luZyBvbmUgYW5kIHVzZSBpdCBhcyBhIHN0YXJ0aW5nIHBvaW50CgkgKiB0byByZWFkIGJhbGFuY2luZy4KCSAqLwoJZm9yIChqID0gMDsgaiA8IGNvbmYtPnJhaWRfZGlza3MgJiYKCQkgICAgICghY29uZi0+bWlycm9yc1tqXS5yZGV2IHx8CgkJICAgICAgIXRlc3RfYml0KEluX3N5bmMsICZjb25mLT5taXJyb3JzW2pdLnJkZXYtPmZsYWdzKSkgOyBqKyspCgkJLyogbm90aGluZyAqLzsKCWNvbmYtPmxhc3RfdXNlZCA9IGo7CgoKCW1kZGV2LT50aHJlYWQgPSBtZF9yZWdpc3Rlcl90aHJlYWQocmFpZDFkLCBtZGRldiwgIiVzX3JhaWQxIik7CglpZiAoIW1kZGV2LT50aHJlYWQpIHsKCQlwcmludGsoS0VSTl9FUlIKCQkgICAgICAgInJhaWQxOiBjb3VsZG4ndCBhbGxvY2F0ZSB0aHJlYWQgZm9yICVzXG4iLAoJCSAgICAgICBtZG5hbWUobWRkZXYpKTsKCQlnb3RvIG91dF9mcmVlX2NvbmY7Cgl9CglpZiAobWRkZXYtPmJpdG1hcCkgbWRkZXYtPnRocmVhZC0+dGltZW91dCA9IG1kZGV2LT5iaXRtYXAtPmRhZW1vbl9zbGVlcCAqIEhaOwoKCXByaW50ayhLRVJOX0lORk8gCgkJInJhaWQxOiByYWlkIHNldCAlcyBhY3RpdmUgd2l0aCAlZCBvdXQgb2YgJWQgbWlycm9yc1xuIiwKCQltZG5hbWUobWRkZXYpLCBtZGRldi0+cmFpZF9kaXNrcyAtIG1kZGV2LT5kZWdyYWRlZCwgCgkJbWRkZXYtPnJhaWRfZGlza3MpOwoJLyoKCSAqIE9rLCBldmVyeXRoaW5nIGlzIGp1c3QgZmluZSBub3cKCSAqLwoJbWRkZXYtPmFycmF5X3NpemUgPSBtZGRldi0+c2l6ZTsKCgltZGRldi0+cXVldWUtPnVucGx1Z19mbiA9IHJhaWQxX3VucGx1ZzsKCW1kZGV2LT5xdWV1ZS0+aXNzdWVfZmx1c2hfZm4gPSByYWlkMV9pc3N1ZV9mbHVzaDsKCglyZXR1cm4gMDsKCm91dF9ub19tZW06CglwcmludGsoS0VSTl9FUlIgInJhaWQxOiBjb3VsZG4ndCBhbGxvY2F0ZSBtZW1vcnkgZm9yICVzXG4iLAoJICAgICAgIG1kbmFtZShtZGRldikpOwoKb3V0X2ZyZWVfY29uZjoKCWlmIChjb25mKSB7CgkJaWYgKGNvbmYtPnIxYmlvX3Bvb2wpCgkJCW1lbXBvb2xfZGVzdHJveShjb25mLT5yMWJpb19wb29sKTsKCQlrZnJlZShjb25mLT5taXJyb3JzKTsKCQlrZnJlZShjb25mLT5wb29saW5mbyk7CgkJa2ZyZWUoY29uZik7CgkJbWRkZXYtPnByaXZhdGUgPSBOVUxMOwoJfQpvdXQ6CglyZXR1cm4gLUVJTzsKfQoKc3RhdGljIGludCBzdG9wKG1kZGV2X3QgKm1kZGV2KQp7Cgljb25mX3QgKmNvbmYgPSBtZGRldl90b19jb25mKG1kZGV2KTsKCXN0cnVjdCBiaXRtYXAgKmJpdG1hcCA9IG1kZGV2LT5iaXRtYXA7CglpbnQgYmVoaW5kX3dhaXQgPSAwOwoKCS8qIHdhaXQgZm9yIGJlaGluZCB3cml0ZXMgdG8gY29tcGxldGUgKi8KCXdoaWxlIChiaXRtYXAgJiYgYXRvbWljX3JlYWQoJmJpdG1hcC0+YmVoaW5kX3dyaXRlcykgPiAwKSB7CgkJYmVoaW5kX3dhaXQrKzsKCQlwcmludGsoS0VSTl9JTkZPICJyYWlkMTogYmVoaW5kIHdyaXRlcyBpbiBwcm9ncmVzcyBvbiBkZXZpY2UgJXMsIHdhaXRpbmcgdG8gc3RvcCAoJWQpXG4iLCBtZG5hbWUobWRkZXYpLCBiZWhpbmRfd2FpdCk7CgkJc2V0X2N1cnJlbnRfc3RhdGUoVEFTS19VTklOVEVSUlVQVElCTEUpOwoJCXNjaGVkdWxlX3RpbWVvdXQoSFopOyAvKiB3YWl0IGEgc2Vjb25kICovCgkJLyogbmVlZCB0byBraWNrIHNvbWV0aGluZyBoZXJlIHRvIG1ha2Ugc3VyZSBJL08gZ29lcz8gKi8KCX0KCgltZF91bnJlZ2lzdGVyX3RocmVhZChtZGRldi0+dGhyZWFkKTsKCW1kZGV2LT50aHJlYWQgPSBOVUxMOwoJYmxrX3N5bmNfcXVldWUobWRkZXYtPnF1ZXVlKTsgLyogdGhlIHVucGx1ZyBmbiByZWZlcmVuY2VzICdjb25mJyovCglpZiAoY29uZi0+cjFiaW9fcG9vbCkKCQltZW1wb29sX2Rlc3Ryb3koY29uZi0+cjFiaW9fcG9vbCk7CglrZnJlZShjb25mLT5taXJyb3JzKTsKCWtmcmVlKGNvbmYtPnBvb2xpbmZvKTsKCWtmcmVlKGNvbmYpOwoJbWRkZXYtPnByaXZhdGUgPSBOVUxMOwoJcmV0dXJuIDA7Cn0KCnN0YXRpYyBpbnQgcmFpZDFfcmVzaXplKG1kZGV2X3QgKm1kZGV2LCBzZWN0b3JfdCBzZWN0b3JzKQp7CgkvKiBubyByZXN5bmMgaXMgaGFwcGVuaW5nLCBhbmQgdGhlcmUgaXMgZW5vdWdoIHNwYWNlCgkgKiBvbiBhbGwgZGV2aWNlcywgc28gd2UgY2FuIHJlc2l6ZS4KCSAqIFdlIG5lZWQgdG8gbWFrZSBzdXJlIHJlc3luYyBjb3ZlcnMgYW55IG5ldyBzcGFjZS4KCSAqIElmIHRoZSBhcnJheSBpcyBzaHJpbmtpbmcgd2Ugc2hvdWxkIHBvc3NpYmx5IHdhaXQgdW50aWwKCSAqIGFueSBpbyBpbiB0aGUgcmVtb3ZlZCBzcGFjZSBjb21wbGV0ZXMsIGJ1dCBpdCBoYXJkbHkgc2VlbXMKCSAqIHdvcnRoIGl0LgoJICovCgltZGRldi0+YXJyYXlfc2l6ZSA9IHNlY3RvcnM+PjE7CglzZXRfY2FwYWNpdHkobWRkZXYtPmdlbmRpc2ssIG1kZGV2LT5hcnJheV9zaXplIDw8IDEpOwoJbWRkZXYtPmNoYW5nZWQgPSAxOwoJaWYgKG1kZGV2LT5hcnJheV9zaXplID4gbWRkZXYtPnNpemUgJiYgbWRkZXYtPnJlY292ZXJ5X2NwID09IE1heFNlY3RvcikgewoJCW1kZGV2LT5yZWNvdmVyeV9jcCA9IG1kZGV2LT5zaXplIDw8IDE7CgkJc2V0X2JpdChNRF9SRUNPVkVSWV9ORUVERUQsICZtZGRldi0+cmVjb3ZlcnkpOwoJfQoJbWRkZXYtPnNpemUgPSBtZGRldi0+YXJyYXlfc2l6ZTsKCW1kZGV2LT5yZXN5bmNfbWF4X3NlY3RvcnMgPSBzZWN0b3JzOwoJcmV0dXJuIDA7Cn0KCnN0YXRpYyBpbnQgcmFpZDFfcmVzaGFwZShtZGRldl90ICptZGRldiwgaW50IHJhaWRfZGlza3MpCnsKCS8qIFdlIG5lZWQgdG86CgkgKiAxLyByZXNpemUgdGhlIHIxYmlvX3Bvb2wKCSAqIDIvIHJlc2l6ZSBjb25mLT5taXJyb3JzCgkgKgoJICogV2UgYWxsb2NhdGUgYSBuZXcgcjFiaW9fcG9vbCBpZiB3ZSBjYW4uCgkgKiBUaGVuIHJhaXNlIGEgZGV2aWNlIGJhcnJpZXIgYW5kIHdhaXQgdW50aWwgYWxsIElPIHN0b3BzLgoJICogVGhlbiByZXNpemUgY29uZi0+bWlycm9ycyBhbmQgc3dhcCBpbiB0aGUgbmV3IHIxYmlvIHBvb2wuCgkgKgoJICogQXQgdGhlIHNhbWUgdGltZSwgd2UgInBhY2siIHRoZSBkZXZpY2VzIHNvIHRoYXQgYWxsIHRoZSBtaXNzaW5nCgkgKiBkZXZpY2VzIGhhdmUgdGhlIGhpZ2hlciByYWlkX2Rpc2sgbnVtYmVycy4KCSAqLwoJbWVtcG9vbF90ICpuZXdwb29sLCAqb2xkcG9vbDsKCXN0cnVjdCBwb29sX2luZm8gKm5ld3Bvb2xpbmZvOwoJbWlycm9yX2luZm9fdCAqbmV3bWlycm9yczsKCWNvbmZfdCAqY29uZiA9IG1kZGV2X3RvX2NvbmYobWRkZXYpOwoJaW50IGNudDsKCglpbnQgZCwgZDI7CgoJaWYgKHJhaWRfZGlza3MgPCBjb25mLT5yYWlkX2Rpc2tzKSB7CgkJY250PTA7CgkJZm9yIChkPSAwOyBkIDwgY29uZi0+cmFpZF9kaXNrczsgZCsrKQoJCQlpZiAoY29uZi0+bWlycm9yc1tkXS5yZGV2KQoJCQkJY250Kys7CgkJaWYgKGNudCA+IHJhaWRfZGlza3MpCgkJCXJldHVybiAtRUJVU1k7Cgl9CgoJbmV3cG9vbGluZm8gPSBrbWFsbG9jKHNpemVvZigqbmV3cG9vbGluZm8pLCBHRlBfS0VSTkVMKTsKCWlmICghbmV3cG9vbGluZm8pCgkJcmV0dXJuIC1FTk9NRU07CgluZXdwb29saW5mby0+bWRkZXYgPSBtZGRldjsKCW5ld3Bvb2xpbmZvLT5yYWlkX2Rpc2tzID0gcmFpZF9kaXNrczsKCgluZXdwb29sID0gbWVtcG9vbF9jcmVhdGUoTlJfUkFJRDFfQklPUywgcjFiaW9fcG9vbF9hbGxvYywKCQkJCSByMWJpb19wb29sX2ZyZWUsIG5ld3Bvb2xpbmZvKTsKCWlmICghbmV3cG9vbCkgewoJCWtmcmVlKG5ld3Bvb2xpbmZvKTsKCQlyZXR1cm4gLUVOT01FTTsKCX0KCW5ld21pcnJvcnMgPSBrbWFsbG9jKHNpemVvZihzdHJ1Y3QgbWlycm9yX2luZm8pICogcmFpZF9kaXNrcywgR0ZQX0tFUk5FTCk7CglpZiAoIW5ld21pcnJvcnMpIHsKCQlrZnJlZShuZXdwb29saW5mbyk7CgkJbWVtcG9vbF9kZXN0cm95KG5ld3Bvb2wpOwoJCXJldHVybiAtRU5PTUVNOwoJfQoJbWVtc2V0KG5ld21pcnJvcnMsIDAsIHNpemVvZihzdHJ1Y3QgbWlycm9yX2luZm8pKnJhaWRfZGlza3MpOwoKCXNwaW5fbG9ja19pcnEoJmNvbmYtPnJlc3luY19sb2NrKTsKCWNvbmYtPmJhcnJpZXIrKzsKCXdhaXRfZXZlbnRfbG9ja19pcnEoY29uZi0+d2FpdF9pZGxlLCAhY29uZi0+bnJfcGVuZGluZywKCQkJICAgIGNvbmYtPnJlc3luY19sb2NrLCByYWlkMV91bnBsdWcobWRkZXYtPnF1ZXVlKSk7CglzcGluX3VubG9ja19pcnEoJmNvbmYtPnJlc3luY19sb2NrKTsKCgkvKiBvaywgZXZlcnl0aGluZyBpcyBzdG9wcGVkICovCglvbGRwb29sID0gY29uZi0+cjFiaW9fcG9vbDsKCWNvbmYtPnIxYmlvX3Bvb2wgPSBuZXdwb29sOwoKCWZvciAoZD1kMj0wOyBkIDwgY29uZi0+cmFpZF9kaXNrczsgZCsrKQoJCWlmIChjb25mLT5taXJyb3JzW2RdLnJkZXYpIHsKCQkJY29uZi0+bWlycm9yc1tkXS5yZGV2LT5yYWlkX2Rpc2sgPSBkMjsKCQkJbmV3bWlycm9yc1tkMisrXS5yZGV2ID0gY29uZi0+bWlycm9yc1tkXS5yZGV2OwoJCX0KCWtmcmVlKGNvbmYtPm1pcnJvcnMpOwoJY29uZi0+bWlycm9ycyA9IG5ld21pcnJvcnM7CglrZnJlZShjb25mLT5wb29saW5mbyk7Cgljb25mLT5wb29saW5mbyA9IG5ld3Bvb2xpbmZvOwoKCW1kZGV2LT5kZWdyYWRlZCArPSAocmFpZF9kaXNrcyAtIGNvbmYtPnJhaWRfZGlza3MpOwoJY29uZi0+cmFpZF9kaXNrcyA9IG1kZGV2LT5yYWlkX2Rpc2tzID0gcmFpZF9kaXNrczsKCgljb25mLT5sYXN0X3VzZWQgPSAwOyAvKiBqdXN0IG1ha2Ugc3VyZSBpdCBpcyBpbi1yYW5nZSAqLwoJc3Bpbl9sb2NrX2lycSgmY29uZi0+cmVzeW5jX2xvY2spOwoJY29uZi0+YmFycmllci0tOwoJc3Bpbl91bmxvY2tfaXJxKCZjb25mLT5yZXN5bmNfbG9jayk7Cgl3YWtlX3VwKCZjb25mLT53YWl0X3Jlc3VtZSk7Cgl3YWtlX3VwKCZjb25mLT53YWl0X2lkbGUpOwoKCglzZXRfYml0KE1EX1JFQ09WRVJZX05FRURFRCwgJm1kZGV2LT5yZWNvdmVyeSk7CgltZF93YWtldXBfdGhyZWFkKG1kZGV2LT50aHJlYWQpOwoKCW1lbXBvb2xfZGVzdHJveShvbGRwb29sKTsKCXJldHVybiAwOwp9CgpzdGF0aWMgdm9pZCByYWlkMV9xdWllc2NlKG1kZGV2X3QgKm1kZGV2LCBpbnQgc3RhdGUpCnsKCWNvbmZfdCAqY29uZiA9IG1kZGV2X3RvX2NvbmYobWRkZXYpOwoKCXN3aXRjaChzdGF0ZSkgewoJY2FzZSAxOgoJCXNwaW5fbG9ja19pcnEoJmNvbmYtPnJlc3luY19sb2NrKTsKCQljb25mLT5iYXJyaWVyKys7CgkJd2FpdF9ldmVudF9sb2NrX2lycShjb25mLT53YWl0X2lkbGUsICFjb25mLT5ucl9wZW5kaW5nLAoJCQkJICAgIGNvbmYtPnJlc3luY19sb2NrLCByYWlkMV91bnBsdWcobWRkZXYtPnF1ZXVlKSk7CgkJc3Bpbl91bmxvY2tfaXJxKCZjb25mLT5yZXN5bmNfbG9jayk7CgkJYnJlYWs7CgljYXNlIDA6CgkJc3Bpbl9sb2NrX2lycSgmY29uZi0+cmVzeW5jX2xvY2spOwoJCWNvbmYtPmJhcnJpZXItLTsKCQlzcGluX3VubG9ja19pcnEoJmNvbmYtPnJlc3luY19sb2NrKTsKCQl3YWtlX3VwKCZjb25mLT53YWl0X3Jlc3VtZSk7CgkJd2FrZV91cCgmY29uZi0+d2FpdF9pZGxlKTsKCQlicmVhazsKCX0KCWlmIChtZGRldi0+dGhyZWFkKSB7CgkJaWYgKG1kZGV2LT5iaXRtYXApCgkJCW1kZGV2LT50aHJlYWQtPnRpbWVvdXQgPSBtZGRldi0+Yml0bWFwLT5kYWVtb25fc2xlZXAgKiBIWjsKCQllbHNlCgkJCW1kZGV2LT50aHJlYWQtPnRpbWVvdXQgPSBNQVhfU0NIRURVTEVfVElNRU9VVDsKCQltZF93YWtldXBfdGhyZWFkKG1kZGV2LT50aHJlYWQpOwoJfQp9CgoKc3RhdGljIG1ka19wZXJzb25hbGl0eV90IHJhaWQxX3BlcnNvbmFsaXR5ID0KewoJLm5hbWUJCT0gInJhaWQxIiwKCS5vd25lcgkJPSBUSElTX01PRFVMRSwKCS5tYWtlX3JlcXVlc3QJPSBtYWtlX3JlcXVlc3QsCgkucnVuCQk9IHJ1biwKCS5zdG9wCQk9IHN0b3AsCgkuc3RhdHVzCQk9IHN0YXR1cywKCS5lcnJvcl9oYW5kbGVyCT0gZXJyb3IsCgkuaG90X2FkZF9kaXNrCT0gcmFpZDFfYWRkX2Rpc2ssCgkuaG90X3JlbW92ZV9kaXNrPSByYWlkMV9yZW1vdmVfZGlzaywKCS5zcGFyZV9hY3RpdmUJPSByYWlkMV9zcGFyZV9hY3RpdmUsCgkuc3luY19yZXF1ZXN0CT0gc3luY19yZXF1ZXN0LAoJLnJlc2l6ZQkJPSByYWlkMV9yZXNpemUsCgkucmVzaGFwZQk9IHJhaWQxX3Jlc2hhcGUsCgkucXVpZXNjZQk9IHJhaWQxX3F1aWVzY2UsCn07CgpzdGF0aWMgaW50IF9faW5pdCByYWlkX2luaXQodm9pZCkKewoJcmV0dXJuIHJlZ2lzdGVyX21kX3BlcnNvbmFsaXR5KFJBSUQxLCAmcmFpZDFfcGVyc29uYWxpdHkpOwp9CgpzdGF0aWMgdm9pZCByYWlkX2V4aXQodm9pZCkKewoJdW5yZWdpc3Rlcl9tZF9wZXJzb25hbGl0eShSQUlEMSk7Cn0KCm1vZHVsZV9pbml0KHJhaWRfaW5pdCk7Cm1vZHVsZV9leGl0KHJhaWRfZXhpdCk7Ck1PRFVMRV9MSUNFTlNFKCJHUEwiKTsKTU9EVUxFX0FMSUFTKCJtZC1wZXJzb25hbGl0eS0zIik7IC8qIFJBSUQxICovCg==