LyoKICogcmFpZDEuYyA6IE11bHRpcGxlIERldmljZXMgZHJpdmVyIGZvciBMaW51eAogKgogKiBDb3B5cmlnaHQgKEMpIDE5OTksIDIwMDAsIDIwMDEgSW5nbyBNb2xuYXIsIFJlZCBIYXQKICoKICogQ29weXJpZ2h0IChDKSAxOTk2LCAxOTk3LCAxOTk4IEluZ28gTW9sbmFyLCBNaWd1ZWwgZGUgSWNhemEsIEdhZGkgT3htYW4KICoKICogUkFJRC0xIG1hbmFnZW1lbnQgZnVuY3Rpb25zLgogKgogKiBCZXR0ZXIgcmVhZC1iYWxhbmNpbmcgY29kZSB3cml0dGVuIGJ5IE1pa2EgS3VvcHBhbGEgPG1pa3VAaWtpLmZpPiwgMjAwMAogKgogKiBGaXhlcyB0byByZWNvbnN0cnVjdGlvbiBieSBKYWtvYiDYc3RlcmdhYXJkIiA8amFrb2JAb3N0ZW5mZWxkLmRrPgogKiBWYXJpb3VzIGZpeGVzIGJ5IE5laWwgQnJvd24gPG5laWxiQGNzZS51bnN3LmVkdS5hdT4KICoKICogQ2hhbmdlcyBieSBQZXRlciBULiBCcmV1ZXIgPHB0YkBpdC51YzNtLmVzPiAzMS8xLzIwMDMgdG8gc3VwcG9ydAogKiBiaXRtYXBwZWQgaW50ZWxsaWdlbmNlIGluIHJlc3luYzoKICoKICogICAgICAtIGJpdG1hcCBtYXJrZWQgZHVyaW5nIG5vcm1hbCBpL28KICogICAgICAtIGJpdG1hcCB1c2VkIHRvIHNraXAgbm9uZGlydHkgYmxvY2tzIGR1cmluZyBzeW5jCiAqCiAqIEFkZGl0aW9ucyB0byBiaXRtYXAgY29kZSwgKEMpIDIwMDMtMjAwNCBQYXVsIENsZW1lbnRzLCBTdGVlbEV5ZSBUZWNobm9sb2d5OgogKiAtIHBlcnNpc3RlbnQgYml0bWFwIGNvZGUKICoKICogVGhpcyBwcm9ncmFtIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkKICogaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkKICogdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyIHZlcnNpb24gMiwgb3IgKGF0IHlvdXIgb3B0aW9uKQogKiBhbnkgbGF0ZXIgdmVyc2lvbi4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogKGZvciBleGFtcGxlIC91c3Ivc3JjL2xpbnV4L0NPUFlJTkcpOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlCiAqIFNvZnR3YXJlIEZvdW5kYXRpb24sIEluYy4sIDY3NSBNYXNzIEF2ZSwgQ2FtYnJpZGdlLCBNQSAwMjEzOSwgVVNBLgogKi8KCiNpbmNsdWRlICJkbS1iaW8tbGlzdC5oIgojaW5jbHVkZSA8bGludXgvcmFpZC9yYWlkMS5oPgojaW5jbHVkZSA8bGludXgvcmFpZC9iaXRtYXAuaD4KCiNkZWZpbmUgREVCVUcgMAojaWYgREVCVUcKI2RlZmluZSBQUklOVEsoeC4uLikgcHJpbnRrKHgpCiNlbHNlCiNkZWZpbmUgUFJJTlRLKHguLi4pCiNlbmRpZgoKLyoKICogTnVtYmVyIG9mIGd1YXJhbnRlZWQgcjFiaW9zIGluIGNhc2Ugb2YgZXh0cmVtZSBWTSBsb2FkOgogKi8KI2RlZmluZQlOUl9SQUlEMV9CSU9TIDI1NgoKc3RhdGljIG1ka19wZXJzb25hbGl0eV90IHJhaWQxX3BlcnNvbmFsaXR5OwoKc3RhdGljIHZvaWQgdW5wbHVnX3NsYXZlcyhtZGRldl90ICptZGRldik7CgpzdGF0aWMgdm9pZCBhbGxvd19iYXJyaWVyKGNvbmZfdCAqY29uZik7CnN0YXRpYyB2b2lkIGxvd2VyX2JhcnJpZXIoY29uZl90ICpjb25mKTsKCnN0YXRpYyB2b2lkICogcjFiaW9fcG9vbF9hbGxvYyhnZnBfdCBnZnBfZmxhZ3MsIHZvaWQgKmRhdGEpCnsKCXN0cnVjdCBwb29sX2luZm8gKnBpID0gZGF0YTsKCXIxYmlvX3QgKnIxX2JpbzsKCWludCBzaXplID0gb2Zmc2V0b2YocjFiaW9fdCwgYmlvc1twaS0+cmFpZF9kaXNrc10pOwoKCS8qIGFsbG9jYXRlIGEgcjFiaW8gd2l0aCByb29tIGZvciByYWlkX2Rpc2tzIGVudHJpZXMgaW4gdGhlIGJpb3MgYXJyYXkgKi8KCXIxX2JpbyA9IGttYWxsb2Moc2l6ZSwgZ2ZwX2ZsYWdzKTsKCWlmIChyMV9iaW8pCgkJbWVtc2V0KHIxX2JpbywgMCwgc2l6ZSk7CgllbHNlCgkJdW5wbHVnX3NsYXZlcyhwaS0+bWRkZXYpOwoKCXJldHVybiByMV9iaW87Cn0KCnN0YXRpYyB2b2lkIHIxYmlvX3Bvb2xfZnJlZSh2b2lkICpyMV9iaW8sIHZvaWQgKmRhdGEpCnsKCWtmcmVlKHIxX2Jpbyk7Cn0KCiNkZWZpbmUgUkVTWU5DX0JMT0NLX1NJWkUgKDY0KjEwMjQpCi8vI2RlZmluZSBSRVNZTkNfQkxPQ0tfU0laRSBQQUdFX1NJWkUKI2RlZmluZSBSRVNZTkNfU0VDVE9SUyAoUkVTWU5DX0JMT0NLX1NJWkUgPj4gOSkKI2RlZmluZSBSRVNZTkNfUEFHRVMgKChSRVNZTkNfQkxPQ0tfU0laRSArIFBBR0VfU0laRS0xKSAvIFBBR0VfU0laRSkKI2RlZmluZSBSRVNZTkNfV0lORE9XICgyMDQ4KjEwMjQpCgpzdGF0aWMgdm9pZCAqIHIxYnVmX3Bvb2xfYWxsb2MoZ2ZwX3QgZ2ZwX2ZsYWdzLCB2b2lkICpkYXRhKQp7CglzdHJ1Y3QgcG9vbF9pbmZvICpwaSA9IGRhdGE7CglzdHJ1Y3QgcGFnZSAqcGFnZTsKCXIxYmlvX3QgKnIxX2JpbzsKCXN0cnVjdCBiaW8gKmJpbzsKCWludCBpLCBqOwoKCXIxX2JpbyA9IHIxYmlvX3Bvb2xfYWxsb2MoZ2ZwX2ZsYWdzLCBwaSk7CglpZiAoIXIxX2JpbykgewoJCXVucGx1Z19zbGF2ZXMocGktPm1kZGV2KTsKCQlyZXR1cm4gTlVMTDsKCX0KCgkvKgoJICogQWxsb2NhdGUgYmlvcyA6IDEgZm9yIHJlYWRpbmcsIG4tMSBmb3Igd3JpdGluZwoJICovCglmb3IgKGogPSBwaS0+cmFpZF9kaXNrcyA7IGotLSA7ICkgewoJCWJpbyA9IGJpb19hbGxvYyhnZnBfZmxhZ3MsIFJFU1lOQ19QQUdFUyk7CgkJaWYgKCFiaW8pCgkJCWdvdG8gb3V0X2ZyZWVfYmlvOwoJCXIxX2Jpby0+Ymlvc1tqXSA9IGJpbzsKCX0KCS8qCgkgKiBBbGxvY2F0ZSBSRVNZTkNfUEFHRVMgZGF0YSBwYWdlcyBhbmQgYXR0YWNoIHRoZW0gdG8KCSAqIHRoZSBmaXJzdCBiaW8uCgkgKiBJZiB0aGlzIGlzIGEgdXNlci1yZXF1ZXN0ZWQgY2hlY2svcmVwYWlyLCBhbGxvY2F0ZQoJICogUkVTWU5DX1BBR0VTIGZvciBlYWNoIGJpby4KCSAqLwoJaWYgKHRlc3RfYml0KE1EX1JFQ09WRVJZX1JFUVVFU1RFRCwgJnBpLT5tZGRldi0+cmVjb3ZlcnkpKQoJCWogPSBwaS0+cmFpZF9kaXNrczsKCWVsc2UKCQlqID0gMTsKCXdoaWxlKGotLSkgewoJCWJpbyA9IHIxX2Jpby0+Ymlvc1tqXTsKCQlmb3IgKGkgPSAwOyBpIDwgUkVTWU5DX1BBR0VTOyBpKyspIHsKCQkJcGFnZSA9IGFsbG9jX3BhZ2UoZ2ZwX2ZsYWdzKTsKCQkJaWYgKHVubGlrZWx5KCFwYWdlKSkKCQkJCWdvdG8gb3V0X2ZyZWVfcGFnZXM7CgoJCQliaW8tPmJpX2lvX3ZlY1tpXS5idl9wYWdlID0gcGFnZTsKCQl9Cgl9CgkvKiBJZiBub3QgdXNlci1yZXF1ZXN0cywgY29weSB0aGUgcGFnZSBwb2ludGVycyB0byBhbGwgYmlvcyAqLwoJaWYgKCF0ZXN0X2JpdChNRF9SRUNPVkVSWV9SRVFVRVNURUQsICZwaS0+bWRkZXYtPnJlY292ZXJ5KSkgewoJCWZvciAoaT0wOyBpPFJFU1lOQ19QQUdFUyA7IGkrKykKCQkJZm9yIChqPTE7IGo8cGktPnJhaWRfZGlza3M7IGorKykKCQkJCXIxX2Jpby0+Ymlvc1tqXS0+YmlfaW9fdmVjW2ldLmJ2X3BhZ2UgPQoJCQkJCXIxX2Jpby0+Ymlvc1swXS0+YmlfaW9fdmVjW2ldLmJ2X3BhZ2U7Cgl9CgoJcjFfYmlvLT5tYXN0ZXJfYmlvID0gTlVMTDsKCglyZXR1cm4gcjFfYmlvOwoKb3V0X2ZyZWVfcGFnZXM6Cglmb3IgKGk9MDsgaSA8IFJFU1lOQ19QQUdFUyA7IGkrKykKCQlmb3IgKGo9MCA7IGogPCBwaS0+cmFpZF9kaXNrczsgaisrKQoJCQlfX2ZyZWVfcGFnZShyMV9iaW8tPmJpb3Nbal0tPmJpX2lvX3ZlY1tpXS5idl9wYWdlKTsKCWogPSAtMTsKb3V0X2ZyZWVfYmlvOgoJd2hpbGUgKCArK2ogPCBwaS0+cmFpZF9kaXNrcyApCgkJYmlvX3B1dChyMV9iaW8tPmJpb3Nbal0pOwoJcjFiaW9fcG9vbF9mcmVlKHIxX2JpbywgZGF0YSk7CglyZXR1cm4gTlVMTDsKfQoKc3RhdGljIHZvaWQgcjFidWZfcG9vbF9mcmVlKHZvaWQgKl9fcjFfYmlvLCB2b2lkICpkYXRhKQp7CglzdHJ1Y3QgcG9vbF9pbmZvICpwaSA9IGRhdGE7CglpbnQgaSxqOwoJcjFiaW9fdCAqcjFiaW8gPSBfX3IxX2JpbzsKCglmb3IgKGkgPSAwOyBpIDwgUkVTWU5DX1BBR0VTOyBpKyspCgkJZm9yIChqID0gcGktPnJhaWRfZGlza3M7IGotLSA7KSB7CgkJCWlmIChqID09IDAgfHwKCQkJICAgIHIxYmlvLT5iaW9zW2pdLT5iaV9pb192ZWNbaV0uYnZfcGFnZSAhPQoJCQkgICAgcjFiaW8tPmJpb3NbMF0tPmJpX2lvX3ZlY1tpXS5idl9wYWdlKQoJCQkJX19mcmVlX3BhZ2UocjFiaW8tPmJpb3Nbal0tPmJpX2lvX3ZlY1tpXS5idl9wYWdlKTsKCQl9Cglmb3IgKGk9MCA7IGkgPCBwaS0+cmFpZF9kaXNrczsgaSsrKQoJCWJpb19wdXQocjFiaW8tPmJpb3NbaV0pOwoKCXIxYmlvX3Bvb2xfZnJlZShyMWJpbywgZGF0YSk7Cn0KCnN0YXRpYyB2b2lkIHB1dF9hbGxfYmlvcyhjb25mX3QgKmNvbmYsIHIxYmlvX3QgKnIxX2JpbykKewoJaW50IGk7CgoJZm9yIChpID0gMDsgaSA8IGNvbmYtPnJhaWRfZGlza3M7IGkrKykgewoJCXN0cnVjdCBiaW8gKipiaW8gPSByMV9iaW8tPmJpb3MgKyBpOwoJCWlmICgqYmlvICYmICpiaW8gIT0gSU9fQkxPQ0tFRCkKCQkJYmlvX3B1dCgqYmlvKTsKCQkqYmlvID0gTlVMTDsKCX0KfQoKc3RhdGljIGlubGluZSB2b2lkIGZyZWVfcjFiaW8ocjFiaW9fdCAqcjFfYmlvKQp7Cgljb25mX3QgKmNvbmYgPSBtZGRldl90b19jb25mKHIxX2Jpby0+bWRkZXYpOwoKCS8qCgkgKiBXYWtlIHVwIGFueSBwb3NzaWJsZSByZXN5bmMgdGhyZWFkIHRoYXQgd2FpdHMgZm9yIHRoZSBkZXZpY2UKCSAqIHRvIGdvIGlkbGUuCgkgKi8KCWFsbG93X2JhcnJpZXIoY29uZik7CgoJcHV0X2FsbF9iaW9zKGNvbmYsIHIxX2Jpbyk7CgltZW1wb29sX2ZyZWUocjFfYmlvLCBjb25mLT5yMWJpb19wb29sKTsKfQoKc3RhdGljIGlubGluZSB2b2lkIHB1dF9idWYocjFiaW9fdCAqcjFfYmlvKQp7Cgljb25mX3QgKmNvbmYgPSBtZGRldl90b19jb25mKHIxX2Jpby0+bWRkZXYpOwoJaW50IGk7CgoJZm9yIChpPTA7IGk8Y29uZi0+cmFpZF9kaXNrczsgaSsrKSB7CgkJc3RydWN0IGJpbyAqYmlvID0gcjFfYmlvLT5iaW9zW2ldOwoJCWlmIChiaW8tPmJpX2VuZF9pbykKCQkJcmRldl9kZWNfcGVuZGluZyhjb25mLT5taXJyb3JzW2ldLnJkZXYsIHIxX2Jpby0+bWRkZXYpOwoJfQoKCW1lbXBvb2xfZnJlZShyMV9iaW8sIGNvbmYtPnIxYnVmX3Bvb2wpOwoKCWxvd2VyX2JhcnJpZXIoY29uZik7Cn0KCnN0YXRpYyB2b2lkIHJlc2NoZWR1bGVfcmV0cnkocjFiaW9fdCAqcjFfYmlvKQp7Cgl1bnNpZ25lZCBsb25nIGZsYWdzOwoJbWRkZXZfdCAqbWRkZXYgPSByMV9iaW8tPm1kZGV2OwoJY29uZl90ICpjb25mID0gbWRkZXZfdG9fY29uZihtZGRldik7CgoJc3Bpbl9sb2NrX2lycXNhdmUoJmNvbmYtPmRldmljZV9sb2NrLCBmbGFncyk7CglsaXN0X2FkZCgmcjFfYmlvLT5yZXRyeV9saXN0LCAmY29uZi0+cmV0cnlfbGlzdCk7Cgljb25mLT5ucl9xdWV1ZWQgKys7CglzcGluX3VubG9ja19pcnFyZXN0b3JlKCZjb25mLT5kZXZpY2VfbG9jaywgZmxhZ3MpOwoKCXdha2VfdXAoJmNvbmYtPndhaXRfYmFycmllcik7CgltZF93YWtldXBfdGhyZWFkKG1kZGV2LT50aHJlYWQpOwp9CgovKgogKiByYWlkX2VuZF9iaW9faW8oKSBpcyBjYWxsZWQgd2hlbiB3ZSBoYXZlIGZpbmlzaGVkIHNlcnZpY2luZyBhIG1pcnJvcmVkCiAqIG9wZXJhdGlvbiBhbmQgYXJlIHJlYWR5IHRvIHJldHVybiBhIHN1Y2Nlc3MvZmFpbHVyZSBjb2RlIHRvIHRoZSBidWZmZXIKICogY2FjaGUgbGF5ZXIuCiAqLwpzdGF0aWMgdm9pZCByYWlkX2VuZF9iaW9faW8ocjFiaW9fdCAqcjFfYmlvKQp7CglzdHJ1Y3QgYmlvICpiaW8gPSByMV9iaW8tPm1hc3Rlcl9iaW87CgoJLyogaWYgbm9ib2R5IGhhcyBkb25lIHRoZSBmaW5hbCBlbmRpbyB5ZXQsIGRvIGl0IG5vdyAqLwoJaWYgKCF0ZXN0X2FuZF9zZXRfYml0KFIxQklPX1JldHVybmVkLCAmcjFfYmlvLT5zdGF0ZSkpIHsKCQlQUklOVEsoS0VSTl9ERUJVRyAicmFpZDE6IHN5bmMgZW5kICVzIG9uIHNlY3RvcnMgJWxsdS0lbGx1XG4iLAoJCQkoYmlvX2RhdGFfZGlyKGJpbykgPT0gV1JJVEUpID8gIndyaXRlIiA6ICJyZWFkIiwKCQkJKHVuc2lnbmVkIGxvbmcgbG9uZykgYmlvLT5iaV9zZWN0b3IsCgkJCSh1bnNpZ25lZCBsb25nIGxvbmcpIGJpby0+Ymlfc2VjdG9yICsKCQkJCShiaW8tPmJpX3NpemUgPj4gOSkgLSAxKTsKCgkJYmlvX2VuZGlvKGJpbywgYmlvLT5iaV9zaXplLAoJCQl0ZXN0X2JpdChSMUJJT19VcHRvZGF0ZSwgJnIxX2Jpby0+c3RhdGUpID8gMCA6IC1FSU8pOwoJfQoJZnJlZV9yMWJpbyhyMV9iaW8pOwp9CgovKgogKiBVcGRhdGUgZGlzayBoZWFkIHBvc2l0aW9uIGVzdGltYXRvciBiYXNlZCBvbiBJUlEgY29tcGxldGlvbiBpbmZvLgogKi8Kc3RhdGljIGlubGluZSB2b2lkIHVwZGF0ZV9oZWFkX3BvcyhpbnQgZGlzaywgcjFiaW9fdCAqcjFfYmlvKQp7Cgljb25mX3QgKmNvbmYgPSBtZGRldl90b19jb25mKHIxX2Jpby0+bWRkZXYpOwoKCWNvbmYtPm1pcnJvcnNbZGlza10uaGVhZF9wb3NpdGlvbiA9CgkJcjFfYmlvLT5zZWN0b3IgKyAocjFfYmlvLT5zZWN0b3JzKTsKfQoKc3RhdGljIGludCByYWlkMV9lbmRfcmVhZF9yZXF1ZXN0KHN0cnVjdCBiaW8gKmJpbywgdW5zaWduZWQgaW50IGJ5dGVzX2RvbmUsIGludCBlcnJvcikKewoJaW50IHVwdG9kYXRlID0gdGVzdF9iaXQoQklPX1VQVE9EQVRFLCAmYmlvLT5iaV9mbGFncyk7CglyMWJpb190ICogcjFfYmlvID0gKHIxYmlvX3QgKikoYmlvLT5iaV9wcml2YXRlKTsKCWludCBtaXJyb3I7Cgljb25mX3QgKmNvbmYgPSBtZGRldl90b19jb25mKHIxX2Jpby0+bWRkZXYpOwoKCWlmIChiaW8tPmJpX3NpemUpCgkJcmV0dXJuIDE7CgkKCW1pcnJvciA9IHIxX2Jpby0+cmVhZF9kaXNrOwoJLyoKCSAqIHRoaXMgYnJhbmNoIGlzIG91ciAnb25lIG1pcnJvciBJTyBoYXMgZmluaXNoZWQnIGV2ZW50IGhhbmRsZXI6CgkgKi8KCXVwZGF0ZV9oZWFkX3BvcyhtaXJyb3IsIHIxX2Jpbyk7CgoJaWYgKHVwdG9kYXRlIHx8IGNvbmYtPndvcmtpbmdfZGlza3MgPD0gMSkgewoJCS8qCgkJICogU2V0IFIxQklPX1VwdG9kYXRlIGluIG91ciBtYXN0ZXIgYmlvLCBzbyB0aGF0CgkJICogd2Ugd2lsbCByZXR1cm4gYSBnb29kIGVycm9yIGNvZGUgZm9yIHRvIHRoZSBoaWdoZXIKCQkgKiBsZXZlbHMgZXZlbiBpZiBJTyBvbiBzb21lIG90aGVyIG1pcnJvcmVkIGJ1ZmZlciBmYWlscy4KCQkgKgoJCSAqIFRoZSAnbWFzdGVyJyByZXByZXNlbnRzIHRoZSBjb21wb3NpdGUgSU8gb3BlcmF0aW9uIHRvCgkJICogdXNlci1zaWRlLiBTbyBpZiBzb21ldGhpbmcgd2FpdHMgZm9yIElPLCB0aGVuIGl0IHdpbGwKCQkgKiB3YWl0IGZvciB0aGUgJ21hc3RlcicgYmlvLgoJCSAqLwoJCWlmICh1cHRvZGF0ZSkKCQkJc2V0X2JpdChSMUJJT19VcHRvZGF0ZSwgJnIxX2Jpby0+c3RhdGUpOwoKCQlyYWlkX2VuZF9iaW9faW8ocjFfYmlvKTsKCX0gZWxzZSB7CgkJLyoKCQkgKiBvb3BzLCByZWFkIGVycm9yOgoJCSAqLwoJCWNoYXIgYltCREVWTkFNRV9TSVpFXTsKCQlpZiAocHJpbnRrX3JhdGVsaW1pdCgpKQoJCQlwcmludGsoS0VSTl9FUlIgInJhaWQxOiAlczogcmVzY2hlZHVsaW5nIHNlY3RvciAlbGx1XG4iLAoJCQkgICAgICAgYmRldm5hbWUoY29uZi0+bWlycm9yc1ttaXJyb3JdLnJkZXYtPmJkZXYsYiksICh1bnNpZ25lZCBsb25nIGxvbmcpcjFfYmlvLT5zZWN0b3IpOwoJCXJlc2NoZWR1bGVfcmV0cnkocjFfYmlvKTsKCX0KCglyZGV2X2RlY19wZW5kaW5nKGNvbmYtPm1pcnJvcnNbbWlycm9yXS5yZGV2LCBjb25mLT5tZGRldik7CglyZXR1cm4gMDsKfQoKc3RhdGljIGludCByYWlkMV9lbmRfd3JpdGVfcmVxdWVzdChzdHJ1Y3QgYmlvICpiaW8sIHVuc2lnbmVkIGludCBieXRlc19kb25lLCBpbnQgZXJyb3IpCnsKCWludCB1cHRvZGF0ZSA9IHRlc3RfYml0KEJJT19VUFRPREFURSwgJmJpby0+YmlfZmxhZ3MpOwoJcjFiaW9fdCAqIHIxX2JpbyA9IChyMWJpb190ICopKGJpby0+YmlfcHJpdmF0ZSk7CglpbnQgbWlycm9yLCBiZWhpbmQgPSB0ZXN0X2JpdChSMUJJT19CZWhpbmRJTywgJnIxX2Jpby0+c3RhdGUpOwoJY29uZl90ICpjb25mID0gbWRkZXZfdG9fY29uZihyMV9iaW8tPm1kZGV2KTsKCglpZiAoYmlvLT5iaV9zaXplKQoJCXJldHVybiAxOwoKCWZvciAobWlycm9yID0gMDsgbWlycm9yIDwgY29uZi0+cmFpZF9kaXNrczsgbWlycm9yKyspCgkJaWYgKHIxX2Jpby0+Ymlvc1ttaXJyb3JdID09IGJpbykKCQkJYnJlYWs7CgoJaWYgKGVycm9yID09IC1FTk9UU1VQUCAmJiB0ZXN0X2JpdChSMUJJT19CYXJyaWVyLCAmcjFfYmlvLT5zdGF0ZSkpIHsKCQlzZXRfYml0KEJhcnJpZXJzTm90c3VwcCwgJmNvbmYtPm1pcnJvcnNbbWlycm9yXS5yZGV2LT5mbGFncyk7CgkJc2V0X2JpdChSMUJJT19CYXJyaWVyUmV0cnksICZyMV9iaW8tPnN0YXRlKTsKCQlyMV9iaW8tPm1kZGV2LT5iYXJyaWVyc193b3JrID0gMDsKCX0gZWxzZSB7CgkJLyoKCQkgKiB0aGlzIGJyYW5jaCBpcyBvdXIgJ29uZSBtaXJyb3IgSU8gaGFzIGZpbmlzaGVkJyBldmVudCBoYW5kbGVyOgoJCSAqLwoJCXIxX2Jpby0+Ymlvc1ttaXJyb3JdID0gTlVMTDsKCQlpZiAoIXVwdG9kYXRlKSB7CgkJCW1kX2Vycm9yKHIxX2Jpby0+bWRkZXYsIGNvbmYtPm1pcnJvcnNbbWlycm9yXS5yZGV2KTsKCQkJLyogYW4gSS9PIGZhaWxlZCwgd2UgY2FuJ3QgY2xlYXIgdGhlIGJpdG1hcCAqLwoJCQlzZXRfYml0KFIxQklPX0RlZ3JhZGVkLCAmcjFfYmlvLT5zdGF0ZSk7CgkJfSBlbHNlCgkJCS8qCgkJCSAqIFNldCBSMUJJT19VcHRvZGF0ZSBpbiBvdXIgbWFzdGVyIGJpbywgc28gdGhhdAoJCQkgKiB3ZSB3aWxsIHJldHVybiBhIGdvb2QgZXJyb3IgY29kZSBmb3IgdG8gdGhlIGhpZ2hlcgoJCQkgKiBsZXZlbHMgZXZlbiBpZiBJTyBvbiBzb21lIG90aGVyIG1pcnJvcmVkIGJ1ZmZlciBmYWlscy4KCQkJICoKCQkJICogVGhlICdtYXN0ZXInIHJlcHJlc2VudHMgdGhlIGNvbXBvc2l0ZSBJTyBvcGVyYXRpb24gdG8KCQkJICogdXNlci1zaWRlLiBTbyBpZiBzb21ldGhpbmcgd2FpdHMgZm9yIElPLCB0aGVuIGl0IHdpbGwKCQkJICogd2FpdCBmb3IgdGhlICdtYXN0ZXInIGJpby4KCQkJICovCgkJCXNldF9iaXQoUjFCSU9fVXB0b2RhdGUsICZyMV9iaW8tPnN0YXRlKTsKCgkJdXBkYXRlX2hlYWRfcG9zKG1pcnJvciwgcjFfYmlvKTsKCgkJaWYgKGJlaGluZCkgewoJCQlpZiAodGVzdF9iaXQoV3JpdGVNb3N0bHksICZjb25mLT5taXJyb3JzW21pcnJvcl0ucmRldi0+ZmxhZ3MpKQoJCQkJYXRvbWljX2RlYygmcjFfYmlvLT5iZWhpbmRfcmVtYWluaW5nKTsKCgkJCS8qIEluIGJlaGluZCBtb2RlLCB3ZSBBQ0sgdGhlIG1hc3RlciBiaW8gb25jZSB0aGUgSS9PIGhhcyBzYWZlbHkKCQkJICogcmVhY2hlZCBhbGwgbm9uLXdyaXRlbW9zdGx5IGRpc2tzLiBTZXR0aW5nIHRoZSBSZXR1cm5lZCBiaXQKCQkJICogZW5zdXJlcyB0aGF0IHRoaXMgZ2V0cyBkb25lIG9ubHkgb25jZSAtLSB3ZSBkb24ndCBldmVyIHdhbnQgdG8KCQkJICogcmV0dXJuIC1FSU8gaGVyZSwgaW5zdGVhZCB3ZSdsbCB3YWl0ICovCgoJCQlpZiAoYXRvbWljX3JlYWQoJnIxX2Jpby0+YmVoaW5kX3JlbWFpbmluZykgPj0gKGF0b21pY19yZWFkKCZyMV9iaW8tPnJlbWFpbmluZyktMSkgJiYKCQkJICAgIHRlc3RfYml0KFIxQklPX1VwdG9kYXRlLCAmcjFfYmlvLT5zdGF0ZSkpIHsKCQkJCS8qIE1heWJlIHdlIGNhbiByZXR1cm4gbm93ICovCgkJCQlpZiAoIXRlc3RfYW5kX3NldF9iaXQoUjFCSU9fUmV0dXJuZWQsICZyMV9iaW8tPnN0YXRlKSkgewoJCQkJCXN0cnVjdCBiaW8gKm1iaW8gPSByMV9iaW8tPm1hc3Rlcl9iaW87CgkJCQkJUFJJTlRLKEtFUk5fREVCVUcgInJhaWQxOiBiZWhpbmQgZW5kIHdyaXRlIHNlY3RvcnMgJWxsdS0lbGx1XG4iLAoJCQkJCSAgICAgICAodW5zaWduZWQgbG9uZyBsb25nKSBtYmlvLT5iaV9zZWN0b3IsCgkJCQkJICAgICAgICh1bnNpZ25lZCBsb25nIGxvbmcpIG1iaW8tPmJpX3NlY3RvciArCgkJCQkJICAgICAgIChtYmlvLT5iaV9zaXplID4+IDkpIC0gMSk7CgkJCQkJYmlvX2VuZGlvKG1iaW8sIG1iaW8tPmJpX3NpemUsIDApOwoJCQkJfQoJCQl9CgkJfQoJfQoJLyoKCSAqCgkgKiBMZXQncyBzZWUgaWYgYWxsIG1pcnJvcmVkIHdyaXRlIG9wZXJhdGlvbnMgaGF2ZSBmaW5pc2hlZAoJICogYWxyZWFkeS4KCSAqLwoJaWYgKGF0b21pY19kZWNfYW5kX3Rlc3QoJnIxX2Jpby0+cmVtYWluaW5nKSkgewoJCWlmICh0ZXN0X2JpdChSMUJJT19CYXJyaWVyUmV0cnksICZyMV9iaW8tPnN0YXRlKSkgewoJCQlyZXNjaGVkdWxlX3JldHJ5KHIxX2Jpbyk7CgkJCS8qIERvbid0IGRlY19wZW5kaW5nIHlldCwgd2Ugd2FudCB0byBob2xkCgkJCSAqIHRoZSByZWZlcmVuY2Ugb3ZlciB0aGUgcmV0cnkKCQkJICovCgkJCXJldHVybiAwOwoJCX0KCQlpZiAodGVzdF9iaXQoUjFCSU9fQmVoaW5kSU8sICZyMV9iaW8tPnN0YXRlKSkgewoJCQkvKiBmcmVlIGV4dHJhIGNvcHkgb2YgdGhlIGRhdGEgcGFnZXMgKi8KCQkJaW50IGkgPSBiaW8tPmJpX3ZjbnQ7CgkJCXdoaWxlIChpLS0pCgkJCQlfX2ZyZWVfcGFnZShiaW8tPmJpX2lvX3ZlY1tpXS5idl9wYWdlKTsKCQl9CgkJLyogY2xlYXIgdGhlIGJpdG1hcCBpZiBhbGwgd3JpdGVzIGNvbXBsZXRlIHN1Y2Nlc3NmdWxseSAqLwoJCWJpdG1hcF9lbmR3cml0ZShyMV9iaW8tPm1kZGV2LT5iaXRtYXAsIHIxX2Jpby0+c2VjdG9yLAoJCQkJcjFfYmlvLT5zZWN0b3JzLAoJCQkJIXRlc3RfYml0KFIxQklPX0RlZ3JhZGVkLCAmcjFfYmlvLT5zdGF0ZSksCgkJCQliZWhpbmQpOwoJCW1kX3dyaXRlX2VuZChyMV9iaW8tPm1kZGV2KTsKCQlyYWlkX2VuZF9iaW9faW8ocjFfYmlvKTsKCX0KCglpZiAocjFfYmlvLT5iaW9zW21pcnJvcl09PU5VTEwpCgkJYmlvX3B1dChiaW8pOwoKCXJkZXZfZGVjX3BlbmRpbmcoY29uZi0+bWlycm9yc1ttaXJyb3JdLnJkZXYsIGNvbmYtPm1kZGV2KTsKCXJldHVybiAwOwp9CgoKLyoKICogVGhpcyByb3V0aW5lIHJldHVybnMgdGhlIGRpc2sgZnJvbSB3aGljaCB0aGUgcmVxdWVzdGVkIHJlYWQgc2hvdWxkCiAqIGJlIGRvbmUuIFRoZXJlIGlzIGEgcGVyLWFycmF5ICduZXh0IGV4cGVjdGVkIHNlcXVlbnRpYWwgSU8nIHNlY3RvcgogKiBudW1iZXIgLSBpZiB0aGlzIG1hdGNoZXMgb24gdGhlIG5leHQgSU8gdGhlbiB3ZSB1c2UgdGhlIGxhc3QgZGlzay4KICogVGhlcmUgaXMgYWxzbyBhIHBlci1kaXNrICdsYXN0IGtub3cgaGVhZCBwb3NpdGlvbicgc2VjdG9yIHRoYXQgaXMKICogbWFpbnRhaW5lZCBmcm9tIElSUSBjb250ZXh0cywgYm90aCB0aGUgbm9ybWFsIGFuZCB0aGUgcmVzeW5jIElPCiAqIGNvbXBsZXRpb24gaGFuZGxlcnMgdXBkYXRlIHRoaXMgcG9zaXRpb24gY29ycmVjdGx5LiBJZiB0aGVyZSBpcyBubwogKiBwZXJmZWN0IHNlcXVlbnRpYWwgbWF0Y2ggdGhlbiB3ZSBwaWNrIHRoZSBkaXNrIHdob3NlIGhlYWQgaXMgY2xvc2VzdC4KICoKICogSWYgdGhlcmUgYXJlIDIgbWlycm9ycyBpbiB0aGUgc2FtZSAyIGRldmljZXMsIHBlcmZvcm1hbmNlIGRlZ3JhZGVzCiAqIGJlY2F1c2UgcG9zaXRpb24gaXMgbWlycm9yLCBub3QgZGV2aWNlIGJhc2VkLgogKgogKiBUaGUgcmRldiBmb3IgdGhlIGRldmljZSBzZWxlY3RlZCB3aWxsIGhhdmUgbnJfcGVuZGluZyBpbmNyZW1lbnRlZC4KICovCnN0YXRpYyBpbnQgcmVhZF9iYWxhbmNlKGNvbmZfdCAqY29uZiwgcjFiaW9fdCAqcjFfYmlvKQp7Cgljb25zdCB1bnNpZ25lZCBsb25nIHRoaXNfc2VjdG9yID0gcjFfYmlvLT5zZWN0b3I7CglpbnQgbmV3X2Rpc2sgPSBjb25mLT5sYXN0X3VzZWQsIGRpc2sgPSBuZXdfZGlzazsKCWludCB3b25seV9kaXNrID0gLTE7Cgljb25zdCBpbnQgc2VjdG9ycyA9IHIxX2Jpby0+c2VjdG9yczsKCXNlY3Rvcl90IG5ld19kaXN0YW5jZSwgY3VycmVudF9kaXN0YW5jZTsKCW1ka19yZGV2X3QgKnJkZXY7CgoJcmN1X3JlYWRfbG9jaygpOwoJLyoKCSAqIENoZWNrIGlmIHdlIGNhbiBiYWxhbmNlLiBXZSBjYW4gYmFsYW5jZSBvbiB0aGUgd2hvbGUKCSAqIGRldmljZSBpZiBubyByZXN5bmMgaXMgZ29pbmcgb24sIG9yIGJlbG93IHRoZSByZXN5bmMgd2luZG93LgoJICogV2UgdGFrZSB0aGUgZmlyc3QgcmVhZGFibGUgZGlzayB3aGVuIGFib3ZlIHRoZSByZXN5bmMgd2luZG93LgoJICovCiByZXRyeToKCWlmIChjb25mLT5tZGRldi0+cmVjb3ZlcnlfY3AgPCBNYXhTZWN0b3IgJiYKCSAgICAodGhpc19zZWN0b3IgKyBzZWN0b3JzID49IGNvbmYtPm5leHRfcmVzeW5jKSkgewoJCS8qIENob29zZSB0aGUgZmlyc3Qgb3BlcmF0aW9uIGRldmljZSwgZm9yIGNvbnNpc3RhbmN5ICovCgkJbmV3X2Rpc2sgPSAwOwoKCQlmb3IgKHJkZXYgPSByY3VfZGVyZWZlcmVuY2UoY29uZi0+bWlycm9yc1tuZXdfZGlza10ucmRldik7CgkJICAgICByMV9iaW8tPmJpb3NbbmV3X2Rpc2tdID09IElPX0JMT0NLRUQgfHwKCQkgICAgICFyZGV2IHx8ICF0ZXN0X2JpdChJbl9zeW5jLCAmcmRldi0+ZmxhZ3MpCgkJCSAgICAgfHwgdGVzdF9iaXQoV3JpdGVNb3N0bHksICZyZGV2LT5mbGFncyk7CgkJICAgICByZGV2ID0gcmN1X2RlcmVmZXJlbmNlKGNvbmYtPm1pcnJvcnNbKytuZXdfZGlza10ucmRldikpIHsKCgkJCWlmIChyZGV2ICYmIHRlc3RfYml0KEluX3N5bmMsICZyZGV2LT5mbGFncykgJiYKCQkJCXIxX2Jpby0+Ymlvc1tuZXdfZGlza10gIT0gSU9fQkxPQ0tFRCkKCQkJCXdvbmx5X2Rpc2sgPSBuZXdfZGlzazsKCgkJCWlmIChuZXdfZGlzayA9PSBjb25mLT5yYWlkX2Rpc2tzIC0gMSkgewoJCQkJbmV3X2Rpc2sgPSB3b25seV9kaXNrOwoJCQkJYnJlYWs7CgkJCX0KCQl9CgkJZ290byByYl9vdXQ7Cgl9CgoKCS8qIG1ha2Ugc3VyZSB0aGUgZGlzayBpcyBvcGVyYXRpb25hbCAqLwoJZm9yIChyZGV2ID0gcmN1X2RlcmVmZXJlbmNlKGNvbmYtPm1pcnJvcnNbbmV3X2Rpc2tdLnJkZXYpOwoJICAgICByMV9iaW8tPmJpb3NbbmV3X2Rpc2tdID09IElPX0JMT0NLRUQgfHwKCSAgICAgIXJkZXYgfHwgIXRlc3RfYml0KEluX3N5bmMsICZyZGV2LT5mbGFncykgfHwKCQkgICAgIHRlc3RfYml0KFdyaXRlTW9zdGx5LCAmcmRldi0+ZmxhZ3MpOwoJICAgICByZGV2ID0gcmN1X2RlcmVmZXJlbmNlKGNvbmYtPm1pcnJvcnNbbmV3X2Rpc2tdLnJkZXYpKSB7CgoJCWlmIChyZGV2ICYmIHRlc3RfYml0KEluX3N5bmMsICZyZGV2LT5mbGFncykgJiYKCQkgICAgcjFfYmlvLT5iaW9zW25ld19kaXNrXSAhPSBJT19CTE9DS0VEKQoJCQl3b25seV9kaXNrID0gbmV3X2Rpc2s7CgoJCWlmIChuZXdfZGlzayA8PSAwKQoJCQluZXdfZGlzayA9IGNvbmYtPnJhaWRfZGlza3M7CgkJbmV3X2Rpc2stLTsKCQlpZiAobmV3X2Rpc2sgPT0gZGlzaykgewoJCQluZXdfZGlzayA9IHdvbmx5X2Rpc2s7CgkJCWJyZWFrOwoJCX0KCX0KCglpZiAobmV3X2Rpc2sgPCAwKQoJCWdvdG8gcmJfb3V0OwoKCWRpc2sgPSBuZXdfZGlzazsKCS8qIG5vdyBkaXNrID09IG5ld19kaXNrID09IHN0YXJ0aW5nIHBvaW50IGZvciBzZWFyY2ggKi8KCgkvKgoJICogRG9uJ3QgY2hhbmdlIHRvIGFub3RoZXIgZGlzayBmb3Igc2VxdWVudGlhbCByZWFkczoKCSAqLwoJaWYgKGNvbmYtPm5leHRfc2VxX3NlY3QgPT0gdGhpc19zZWN0b3IpCgkJZ290byByYl9vdXQ7CglpZiAodGhpc19zZWN0b3IgPT0gY29uZi0+bWlycm9yc1tuZXdfZGlza10uaGVhZF9wb3NpdGlvbikKCQlnb3RvIHJiX291dDsKCgljdXJyZW50X2Rpc3RhbmNlID0gYWJzKHRoaXNfc2VjdG9yIC0gY29uZi0+bWlycm9yc1tkaXNrXS5oZWFkX3Bvc2l0aW9uKTsKCgkvKiBGaW5kIHRoZSBkaXNrIHdob3NlIGhlYWQgaXMgY2xvc2VzdCAqLwoKCWRvIHsKCQlpZiAoZGlzayA8PSAwKQoJCQlkaXNrID0gY29uZi0+cmFpZF9kaXNrczsKCQlkaXNrLS07CgoJCXJkZXYgPSByY3VfZGVyZWZlcmVuY2UoY29uZi0+bWlycm9yc1tkaXNrXS5yZGV2KTsKCgkJaWYgKCFyZGV2IHx8IHIxX2Jpby0+Ymlvc1tkaXNrXSA9PSBJT19CTE9DS0VEIHx8CgkJICAgICF0ZXN0X2JpdChJbl9zeW5jLCAmcmRldi0+ZmxhZ3MpIHx8CgkJICAgIHRlc3RfYml0KFdyaXRlTW9zdGx5LCAmcmRldi0+ZmxhZ3MpKQoJCQljb250aW51ZTsKCgkJaWYgKCFhdG9taWNfcmVhZCgmcmRldi0+bnJfcGVuZGluZykpIHsKCQkJbmV3X2Rpc2sgPSBkaXNrOwoJCQlicmVhazsKCQl9CgkJbmV3X2Rpc3RhbmNlID0gYWJzKHRoaXNfc2VjdG9yIC0gY29uZi0+bWlycm9yc1tkaXNrXS5oZWFkX3Bvc2l0aW9uKTsKCQlpZiAobmV3X2Rpc3RhbmNlIDwgY3VycmVudF9kaXN0YW5jZSkgewoJCQljdXJyZW50X2Rpc3RhbmNlID0gbmV3X2Rpc3RhbmNlOwoJCQluZXdfZGlzayA9IGRpc2s7CgkJfQoJfSB3aGlsZSAoZGlzayAhPSBjb25mLT5sYXN0X3VzZWQpOwoKIHJiX291dDoKCgoJaWYgKG5ld19kaXNrID49IDApIHsKCQlyZGV2ID0gcmN1X2RlcmVmZXJlbmNlKGNvbmYtPm1pcnJvcnNbbmV3X2Rpc2tdLnJkZXYpOwoJCWlmICghcmRldikKCQkJZ290byByZXRyeTsKCQlhdG9taWNfaW5jKCZyZGV2LT5ucl9wZW5kaW5nKTsKCQlpZiAoIXRlc3RfYml0KEluX3N5bmMsICZyZGV2LT5mbGFncykpIHsKCQkJLyogY2Fubm90IHJpc2sgcmV0dXJuaW5nIGEgZGV2aWNlIHRoYXQgZmFpbGVkCgkJCSAqIGJlZm9yZSB3ZSBpbmMnZWQgbnJfcGVuZGluZwoJCQkgKi8KCQkJYXRvbWljX2RlYygmcmRldi0+bnJfcGVuZGluZyk7CgkJCWdvdG8gcmV0cnk7CgkJfQoJCWNvbmYtPm5leHRfc2VxX3NlY3QgPSB0aGlzX3NlY3RvciArIHNlY3RvcnM7CgkJY29uZi0+bGFzdF91c2VkID0gbmV3X2Rpc2s7Cgl9CglyY3VfcmVhZF91bmxvY2soKTsKCglyZXR1cm4gbmV3X2Rpc2s7Cn0KCnN0YXRpYyB2b2lkIHVucGx1Z19zbGF2ZXMobWRkZXZfdCAqbWRkZXYpCnsKCWNvbmZfdCAqY29uZiA9IG1kZGV2X3RvX2NvbmYobWRkZXYpOwoJaW50IGk7CgoJcmN1X3JlYWRfbG9jaygpOwoJZm9yIChpPTA7IGk8bWRkZXYtPnJhaWRfZGlza3M7IGkrKykgewoJCW1ka19yZGV2X3QgKnJkZXYgPSByY3VfZGVyZWZlcmVuY2UoY29uZi0+bWlycm9yc1tpXS5yZGV2KTsKCQlpZiAocmRldiAmJiAhdGVzdF9iaXQoRmF1bHR5LCAmcmRldi0+ZmxhZ3MpICYmIGF0b21pY19yZWFkKCZyZGV2LT5ucl9wZW5kaW5nKSkgewoJCQlyZXF1ZXN0X3F1ZXVlX3QgKnJfcXVldWUgPSBiZGV2X2dldF9xdWV1ZShyZGV2LT5iZGV2KTsKCgkJCWF0b21pY19pbmMoJnJkZXYtPm5yX3BlbmRpbmcpOwoJCQlyY3VfcmVhZF91bmxvY2soKTsKCgkJCWlmIChyX3F1ZXVlLT51bnBsdWdfZm4pCgkJCQlyX3F1ZXVlLT51bnBsdWdfZm4ocl9xdWV1ZSk7CgoJCQlyZGV2X2RlY19wZW5kaW5nKHJkZXYsIG1kZGV2KTsKCQkJcmN1X3JlYWRfbG9jaygpOwoJCX0KCX0KCXJjdV9yZWFkX3VubG9jaygpOwp9CgpzdGF0aWMgdm9pZCByYWlkMV91bnBsdWcocmVxdWVzdF9xdWV1ZV90ICpxKQp7CgltZGRldl90ICptZGRldiA9IHEtPnF1ZXVlZGF0YTsKCgl1bnBsdWdfc2xhdmVzKG1kZGV2KTsKCW1kX3dha2V1cF90aHJlYWQobWRkZXYtPnRocmVhZCk7Cn0KCnN0YXRpYyBpbnQgcmFpZDFfaXNzdWVfZmx1c2gocmVxdWVzdF9xdWV1ZV90ICpxLCBzdHJ1Y3QgZ2VuZGlzayAqZGlzaywKCQkJICAgICBzZWN0b3JfdCAqZXJyb3Jfc2VjdG9yKQp7CgltZGRldl90ICptZGRldiA9IHEtPnF1ZXVlZGF0YTsKCWNvbmZfdCAqY29uZiA9IG1kZGV2X3RvX2NvbmYobWRkZXYpOwoJaW50IGksIHJldCA9IDA7CgoJcmN1X3JlYWRfbG9jaygpOwoJZm9yIChpPTA7IGk8bWRkZXYtPnJhaWRfZGlza3MgJiYgcmV0ID09IDA7IGkrKykgewoJCW1ka19yZGV2X3QgKnJkZXYgPSByY3VfZGVyZWZlcmVuY2UoY29uZi0+bWlycm9yc1tpXS5yZGV2KTsKCQlpZiAocmRldiAmJiAhdGVzdF9iaXQoRmF1bHR5LCAmcmRldi0+ZmxhZ3MpKSB7CgkJCXN0cnVjdCBibG9ja19kZXZpY2UgKmJkZXYgPSByZGV2LT5iZGV2OwoJCQlyZXF1ZXN0X3F1ZXVlX3QgKnJfcXVldWUgPSBiZGV2X2dldF9xdWV1ZShiZGV2KTsKCgkJCWlmICghcl9xdWV1ZS0+aXNzdWVfZmx1c2hfZm4pCgkJCQlyZXQgPSAtRU9QTk9UU1VQUDsKCQkJZWxzZSB7CgkJCQlhdG9taWNfaW5jKCZyZGV2LT5ucl9wZW5kaW5nKTsKCQkJCXJjdV9yZWFkX3VubG9jaygpOwoJCQkJcmV0ID0gcl9xdWV1ZS0+aXNzdWVfZmx1c2hfZm4ocl9xdWV1ZSwgYmRldi0+YmRfZGlzaywKCQkJCQkJCSAgICAgIGVycm9yX3NlY3Rvcik7CgkJCQlyZGV2X2RlY19wZW5kaW5nKHJkZXYsIG1kZGV2KTsKCQkJCXJjdV9yZWFkX2xvY2soKTsKCQkJfQoJCX0KCX0KCXJjdV9yZWFkX3VubG9jaygpOwoJcmV0dXJuIHJldDsKfQoKLyogQmFycmllcnMuLi4uCiAqIFNvbWV0aW1lcyB3ZSBuZWVkIHRvIHN1c3BlbmQgSU8gd2hpbGUgd2UgZG8gc29tZXRoaW5nIGVsc2UsCiAqIGVpdGhlciBzb21lIHJlc3luYy9yZWNvdmVyeSwgb3IgcmVjb25maWd1cmUgdGhlIGFycmF5LgogKiBUbyBkbyB0aGlzIHdlIHJhaXNlIGEgJ2JhcnJpZXInLgogKiBUaGUgJ2JhcnJpZXInIGlzIGEgY291bnRlciB0aGF0IGNhbiBiZSByYWlzZWQgbXVsdGlwbGUgdGltZXMKICogdG8gY291bnQgaG93IG1hbnkgYWN0aXZpdGllcyBhcmUgaGFwcGVuaW5nIHdoaWNoIHByZWNsdWRlCiAqIG5vcm1hbCBJTy4KICogV2UgY2FuIG9ubHkgcmFpc2UgdGhlIGJhcnJpZXIgaWYgdGhlcmUgaXMgbm8gcGVuZGluZyBJTy4KICogaS5lLiBpZiBucl9wZW5kaW5nID09IDAuCiAqIFdlIGNob29zZSBvbmx5IHRvIHJhaXNlIHRoZSBiYXJyaWVyIGlmIG5vLW9uZSBpcyB3YWl0aW5nIGZvciB0aGUKICogYmFycmllciB0byBnbyBkb3duLiAgVGhpcyBtZWFucyB0aGF0IGFzIHNvb24gYXMgYW4gSU8gcmVxdWVzdAogKiBpcyByZWFkeSwgbm8gb3RoZXIgb3BlcmF0aW9ucyB3aGljaCByZXF1aXJlIGEgYmFycmllciB3aWxsIHN0YXJ0CiAqIHVudGlsIHRoZSBJTyByZXF1ZXN0IGhhcyBoYWQgYSBjaGFuY2UuCiAqCiAqIFNvOiByZWd1bGFyIElPIGNhbGxzICd3YWl0X2JhcnJpZXInLiAgV2hlbiB0aGF0IHJldHVybnMgdGhlcmUKICogICAgaXMgbm8gYmFja2dyb3VwIElPIGhhcHBlbmluZywgIEl0IG11c3QgYXJyYW5nZSB0byBjYWxsCiAqICAgIGFsbG93X2JhcnJpZXIgd2hlbiBpdCBoYXMgZmluaXNoZWQgaXRzIElPLgogKiBiYWNrZ3JvdXAgSU8gY2FsbHMgbXVzdCBjYWxsIHJhaXNlX2JhcnJpZXIuICBPbmNlIHRoYXQgcmV0dXJucwogKiAgICB0aGVyZSBpcyBubyBub3JtYWwgSU8gaGFwcGVpbmcuICBJdCBtdXN0IGFycmFuZ2UgdG8gY2FsbAogKiAgICBsb3dlcl9iYXJyaWVyIHdoZW4gdGhlIHBhcnRpY3VsYXIgYmFja2dyb3VuZCBJTyBjb21wbGV0ZXMuCiAqLwojZGVmaW5lIFJFU1lOQ19ERVBUSCAzMgoKc3RhdGljIHZvaWQgcmFpc2VfYmFycmllcihjb25mX3QgKmNvbmYpCnsKCXNwaW5fbG9ja19pcnEoJmNvbmYtPnJlc3luY19sb2NrKTsKCgkvKiBXYWl0IHVudGlsIG5vIGJsb2NrIElPIGlzIHdhaXRpbmcgKi8KCXdhaXRfZXZlbnRfbG9ja19pcnEoY29uZi0+d2FpdF9iYXJyaWVyLCAhY29uZi0+bnJfd2FpdGluZywKCQkJICAgIGNvbmYtPnJlc3luY19sb2NrLAoJCQkgICAgcmFpZDFfdW5wbHVnKGNvbmYtPm1kZGV2LT5xdWV1ZSkpOwoKCS8qIGJsb2NrIGFueSBuZXcgSU8gZnJvbSBzdGFydGluZyAqLwoJY29uZi0+YmFycmllcisrOwoKCS8qIE5vIHdhaXQgZm9yIGFsbCBwZW5kaW5nIElPIHRvIGNvbXBsZXRlICovCgl3YWl0X2V2ZW50X2xvY2tfaXJxKGNvbmYtPndhaXRfYmFycmllciwKCQkJICAgICFjb25mLT5ucl9wZW5kaW5nICYmIGNvbmYtPmJhcnJpZXIgPCBSRVNZTkNfREVQVEgsCgkJCSAgICBjb25mLT5yZXN5bmNfbG9jaywKCQkJICAgIHJhaWQxX3VucGx1Zyhjb25mLT5tZGRldi0+cXVldWUpKTsKCglzcGluX3VubG9ja19pcnEoJmNvbmYtPnJlc3luY19sb2NrKTsKfQoKc3RhdGljIHZvaWQgbG93ZXJfYmFycmllcihjb25mX3QgKmNvbmYpCnsKCXVuc2lnbmVkIGxvbmcgZmxhZ3M7CglzcGluX2xvY2tfaXJxc2F2ZSgmY29uZi0+cmVzeW5jX2xvY2ssIGZsYWdzKTsKCWNvbmYtPmJhcnJpZXItLTsKCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJmNvbmYtPnJlc3luY19sb2NrLCBmbGFncyk7Cgl3YWtlX3VwKCZjb25mLT53YWl0X2JhcnJpZXIpOwp9CgpzdGF0aWMgdm9pZCB3YWl0X2JhcnJpZXIoY29uZl90ICpjb25mKQp7CglzcGluX2xvY2tfaXJxKCZjb25mLT5yZXN5bmNfbG9jayk7CglpZiAoY29uZi0+YmFycmllcikgewoJCWNvbmYtPm5yX3dhaXRpbmcrKzsKCQl3YWl0X2V2ZW50X2xvY2tfaXJxKGNvbmYtPndhaXRfYmFycmllciwgIWNvbmYtPmJhcnJpZXIsCgkJCQkgICAgY29uZi0+cmVzeW5jX2xvY2ssCgkJCQkgICAgcmFpZDFfdW5wbHVnKGNvbmYtPm1kZGV2LT5xdWV1ZSkpOwoJCWNvbmYtPm5yX3dhaXRpbmctLTsKCX0KCWNvbmYtPm5yX3BlbmRpbmcrKzsKCXNwaW5fdW5sb2NrX2lycSgmY29uZi0+cmVzeW5jX2xvY2spOwp9CgpzdGF0aWMgdm9pZCBhbGxvd19iYXJyaWVyKGNvbmZfdCAqY29uZikKewoJdW5zaWduZWQgbG9uZyBmbGFnczsKCXNwaW5fbG9ja19pcnFzYXZlKCZjb25mLT5yZXN5bmNfbG9jaywgZmxhZ3MpOwoJY29uZi0+bnJfcGVuZGluZy0tOwoJc3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmY29uZi0+cmVzeW5jX2xvY2ssIGZsYWdzKTsKCXdha2VfdXAoJmNvbmYtPndhaXRfYmFycmllcik7Cn0KCnN0YXRpYyB2b2lkIGZyZWV6ZV9hcnJheShjb25mX3QgKmNvbmYpCnsKCS8qIHN0b3Agc3luY2lvIGFuZCBub3JtYWwgSU8gYW5kIHdhaXQgZm9yIGV2ZXJ5dGhpbmcgdG8KCSAqIGdvIHF1aXRlLgoJICogV2UgaW5jcmVtZW50IGJhcnJpZXIgYW5kIG5yX3dhaXRpbmcsIGFuZCB0aGVuCgkgKiB3YWl0IHVudGlsIGJhcnJpZXIrbnJfcGVuZGluZyBtYXRjaCBucl9xdWV1ZWQrMgoJICovCglzcGluX2xvY2tfaXJxKCZjb25mLT5yZXN5bmNfbG9jayk7Cgljb25mLT5iYXJyaWVyKys7Cgljb25mLT5ucl93YWl0aW5nKys7Cgl3YWl0X2V2ZW50X2xvY2tfaXJxKGNvbmYtPndhaXRfYmFycmllciwKCQkJICAgIGNvbmYtPmJhcnJpZXIrY29uZi0+bnJfcGVuZGluZyA9PSBjb25mLT5ucl9xdWV1ZWQrMiwKCQkJICAgIGNvbmYtPnJlc3luY19sb2NrLAoJCQkgICAgcmFpZDFfdW5wbHVnKGNvbmYtPm1kZGV2LT5xdWV1ZSkpOwoJc3Bpbl91bmxvY2tfaXJxKCZjb25mLT5yZXN5bmNfbG9jayk7Cn0Kc3RhdGljIHZvaWQgdW5mcmVlemVfYXJyYXkoY29uZl90ICpjb25mKQp7CgkvKiByZXZlcnNlIHRoZSBlZmZlY3Qgb2YgdGhlIGZyZWV6ZSAqLwoJc3Bpbl9sb2NrX2lycSgmY29uZi0+cmVzeW5jX2xvY2spOwoJY29uZi0+YmFycmllci0tOwoJY29uZi0+bnJfd2FpdGluZy0tOwoJd2FrZV91cCgmY29uZi0+d2FpdF9iYXJyaWVyKTsKCXNwaW5fdW5sb2NrX2lycSgmY29uZi0+cmVzeW5jX2xvY2spOwp9CgoKLyogZHVwbGljYXRlIHRoZSBkYXRhIHBhZ2VzIGZvciBiZWhpbmQgSS9PICovCnN0YXRpYyBzdHJ1Y3QgcGFnZSAqKmFsbG9jX2JlaGluZF9wYWdlcyhzdHJ1Y3QgYmlvICpiaW8pCnsKCWludCBpOwoJc3RydWN0IGJpb192ZWMgKmJ2ZWM7CglzdHJ1Y3QgcGFnZSAqKnBhZ2VzID0ga21hbGxvYyhiaW8tPmJpX3ZjbnQgKiBzaXplb2Yoc3RydWN0IHBhZ2UgKiksCgkJCQkJR0ZQX05PSU8pOwoJaWYgKHVubGlrZWx5KCFwYWdlcykpCgkJZ290byBkb19zeW5jX2lvOwoKCW1lbXNldChwYWdlcywgMCwgYmlvLT5iaV92Y250ICogc2l6ZW9mKHN0cnVjdCBwYWdlICopKTsKCgliaW9fZm9yX2VhY2hfc2VnbWVudChidmVjLCBiaW8sIGkpIHsKCQlwYWdlc1tpXSA9IGFsbG9jX3BhZ2UoR0ZQX05PSU8pOwoJCWlmICh1bmxpa2VseSghcGFnZXNbaV0pKQoJCQlnb3RvIGRvX3N5bmNfaW87CgkJbWVtY3B5KGttYXAocGFnZXNbaV0pICsgYnZlYy0+YnZfb2Zmc2V0LAoJCQlrbWFwKGJ2ZWMtPmJ2X3BhZ2UpICsgYnZlYy0+YnZfb2Zmc2V0LCBidmVjLT5idl9sZW4pOwoJCWt1bm1hcChwYWdlc1tpXSk7CgkJa3VubWFwKGJ2ZWMtPmJ2X3BhZ2UpOwoJfQoKCXJldHVybiBwYWdlczsKCmRvX3N5bmNfaW86CglpZiAocGFnZXMpCgkJZm9yIChpID0gMDsgaSA8IGJpby0+YmlfdmNudCAmJiBwYWdlc1tpXTsgaSsrKQoJCQlfX2ZyZWVfcGFnZShwYWdlc1tpXSk7CglrZnJlZShwYWdlcyk7CglQUklOVEsoIiVkQiBiZWhpbmQgYWxsb2MgZmFpbGVkLCBkb2luZyBzeW5jIEkvT1xuIiwgYmlvLT5iaV9zaXplKTsKCXJldHVybiBOVUxMOwp9CgpzdGF0aWMgaW50IG1ha2VfcmVxdWVzdChyZXF1ZXN0X3F1ZXVlX3QgKnEsIHN0cnVjdCBiaW8gKiBiaW8pCnsKCW1kZGV2X3QgKm1kZGV2ID0gcS0+cXVldWVkYXRhOwoJY29uZl90ICpjb25mID0gbWRkZXZfdG9fY29uZihtZGRldik7CgltaXJyb3JfaW5mb190ICptaXJyb3I7CglyMWJpb190ICpyMV9iaW87CglzdHJ1Y3QgYmlvICpyZWFkX2JpbzsKCWludCBpLCB0YXJnZXRzID0gMCwgZGlza3M7CgltZGtfcmRldl90ICpyZGV2OwoJc3RydWN0IGJpdG1hcCAqYml0bWFwID0gbWRkZXYtPmJpdG1hcDsKCXVuc2lnbmVkIGxvbmcgZmxhZ3M7CglzdHJ1Y3QgYmlvX2xpc3QgYmw7CglzdHJ1Y3QgcGFnZSAqKmJlaGluZF9wYWdlcyA9IE5VTEw7Cgljb25zdCBpbnQgcncgPSBiaW9fZGF0YV9kaXIoYmlvKTsKCWludCBkb19iYXJyaWVyczsKCglpZiAodW5saWtlbHkoIW1kZGV2LT5iYXJyaWVyc193b3JrICYmIGJpb19iYXJyaWVyKGJpbykpKSB7CgkJYmlvX2VuZGlvKGJpbywgYmlvLT5iaV9zaXplLCAtRU9QTk9UU1VQUCk7CgkJcmV0dXJuIDA7Cgl9CgoJLyoKCSAqIFJlZ2lzdGVyIHRoZSBuZXcgcmVxdWVzdCBhbmQgd2FpdCBpZiB0aGUgcmVjb25zdHJ1Y3Rpb24KCSAqIHRocmVhZCBoYXMgcHV0IHVwIGEgYmFyIGZvciBuZXcgcmVxdWVzdHMuCgkgKiBDb250aW51ZSBpbW1lZGlhdGVseSBpZiBubyByZXN5bmMgaXMgYWN0aXZlIGN1cnJlbnRseS4KCSAqLwoJbWRfd3JpdGVfc3RhcnQobWRkZXYsIGJpbyk7IC8qIHdhaXQgb24gc3VwZXJibG9jayB1cGRhdGUgZWFybHkgKi8KCgl3YWl0X2JhcnJpZXIoY29uZik7CgoJZGlza19zdGF0X2luYyhtZGRldi0+Z2VuZGlzaywgaW9zW3J3XSk7CglkaXNrX3N0YXRfYWRkKG1kZGV2LT5nZW5kaXNrLCBzZWN0b3JzW3J3XSwgYmlvX3NlY3RvcnMoYmlvKSk7CgoJLyoKCSAqIG1ha2VfcmVxdWVzdCgpIGNhbiBhYm9ydCB0aGUgb3BlcmF0aW9uIHdoZW4gUkVBREEgaXMgYmVpbmcKCSAqIHVzZWQgYW5kIG5vIGVtcHR5IHJlcXVlc3QgaXMgYXZhaWxhYmxlLgoJICoKCSAqLwoJcjFfYmlvID0gbWVtcG9vbF9hbGxvYyhjb25mLT5yMWJpb19wb29sLCBHRlBfTk9JTyk7CgoJcjFfYmlvLT5tYXN0ZXJfYmlvID0gYmlvOwoJcjFfYmlvLT5zZWN0b3JzID0gYmlvLT5iaV9zaXplID4+IDk7CglyMV9iaW8tPnN0YXRlID0gMDsKCXIxX2Jpby0+bWRkZXYgPSBtZGRldjsKCXIxX2Jpby0+c2VjdG9yID0gYmlvLT5iaV9zZWN0b3I7CgoJaWYgKHJ3ID09IFJFQUQpIHsKCQkvKgoJCSAqIHJlYWQgYmFsYW5jaW5nIGxvZ2ljOgoJCSAqLwoJCWludCByZGlzayA9IHJlYWRfYmFsYW5jZShjb25mLCByMV9iaW8pOwoKCQlpZiAocmRpc2sgPCAwKSB7CgkJCS8qIGNvdWxkbid0IGZpbmQgYW55d2hlcmUgdG8gcmVhZCBmcm9tICovCgkJCXJhaWRfZW5kX2Jpb19pbyhyMV9iaW8pOwoJCQlyZXR1cm4gMDsKCQl9CgkJbWlycm9yID0gY29uZi0+bWlycm9ycyArIHJkaXNrOwoKCQlyMV9iaW8tPnJlYWRfZGlzayA9IHJkaXNrOwoKCQlyZWFkX2JpbyA9IGJpb19jbG9uZShiaW8sIEdGUF9OT0lPKTsKCgkJcjFfYmlvLT5iaW9zW3JkaXNrXSA9IHJlYWRfYmlvOwoKCQlyZWFkX2Jpby0+Ymlfc2VjdG9yID0gcjFfYmlvLT5zZWN0b3IgKyBtaXJyb3ItPnJkZXYtPmRhdGFfb2Zmc2V0OwoJCXJlYWRfYmlvLT5iaV9iZGV2ID0gbWlycm9yLT5yZGV2LT5iZGV2OwoJCXJlYWRfYmlvLT5iaV9lbmRfaW8gPSByYWlkMV9lbmRfcmVhZF9yZXF1ZXN0OwoJCXJlYWRfYmlvLT5iaV9ydyA9IFJFQUQ7CgkJcmVhZF9iaW8tPmJpX3ByaXZhdGUgPSByMV9iaW87CgoJCWdlbmVyaWNfbWFrZV9yZXF1ZXN0KHJlYWRfYmlvKTsKCQlyZXR1cm4gMDsKCX0KCgkvKgoJICogV1JJVEU6CgkgKi8KCS8qIGZpcnN0IHNlbGVjdCB0YXJnZXQgZGV2aWNlcyB1bmRlciBzcGlubG9jayBhbmQKCSAqIGluYyByZWZjb3VudCBvbiB0aGVpciByZGV2LiAgUmVjb3JkIHRoZW0gYnkgc2V0dGluZwoJICogYmlvc1t4XSB0byBiaW8KCSAqLwoJZGlza3MgPSBjb25mLT5yYWlkX2Rpc2tzOwojaWYgMAoJeyBzdGF0aWMgaW50IGZpcnN0PTE7CglpZiAoZmlyc3QpIHByaW50aygiRmlyc3QgV3JpdGUgc2VjdG9yICVsbHUgZGlza3MgJWRcbiIsCgkJCSAgKHVuc2lnbmVkIGxvbmcgbG9uZylyMV9iaW8tPnNlY3RvciwgZGlza3MpOwoJZmlyc3QgPSAwOwoJfQojZW5kaWYKCXJjdV9yZWFkX2xvY2soKTsKCWZvciAoaSA9IDA7ICBpIDwgZGlza3M7IGkrKykgewoJCWlmICgocmRldj1yY3VfZGVyZWZlcmVuY2UoY29uZi0+bWlycm9yc1tpXS5yZGV2KSkgIT0gTlVMTCAmJgoJCSAgICAhdGVzdF9iaXQoRmF1bHR5LCAmcmRldi0+ZmxhZ3MpKSB7CgkJCWF0b21pY19pbmMoJnJkZXYtPm5yX3BlbmRpbmcpOwoJCQlpZiAodGVzdF9iaXQoRmF1bHR5LCAmcmRldi0+ZmxhZ3MpKSB7CgkJCQlhdG9taWNfZGVjKCZyZGV2LT5ucl9wZW5kaW5nKTsKCQkJCXIxX2Jpby0+Ymlvc1tpXSA9IE5VTEw7CgkJCX0gZWxzZQoJCQkJcjFfYmlvLT5iaW9zW2ldID0gYmlvOwoJCQl0YXJnZXRzKys7CgkJfSBlbHNlCgkJCXIxX2Jpby0+Ymlvc1tpXSA9IE5VTEw7Cgl9CglyY3VfcmVhZF91bmxvY2soKTsKCglCVUdfT04odGFyZ2V0cyA9PSAwKTsgLyogd2UgbmV2ZXIgZmFpbCB0aGUgbGFzdCBkZXZpY2UgKi8KCglpZiAodGFyZ2V0cyA8IGNvbmYtPnJhaWRfZGlza3MpIHsKCQkvKiBhcnJheSBpcyBkZWdyYWRlZCwgd2Ugd2lsbCBub3QgY2xlYXIgdGhlIGJpdG1hcAoJCSAqIG9uIEkvTyBjb21wbGV0aW9uIChzZWUgcmFpZDFfZW5kX3dyaXRlX3JlcXVlc3QpICovCgkJc2V0X2JpdChSMUJJT19EZWdyYWRlZCwgJnIxX2Jpby0+c3RhdGUpOwoJfQoKCS8qIGRvIGJlaGluZCBJL08gPyAqLwoJaWYgKGJpdG1hcCAmJgoJICAgIGF0b21pY19yZWFkKCZiaXRtYXAtPmJlaGluZF93cml0ZXMpIDwgYml0bWFwLT5tYXhfd3JpdGVfYmVoaW5kICYmCgkgICAgKGJlaGluZF9wYWdlcyA9IGFsbG9jX2JlaGluZF9wYWdlcyhiaW8pKSAhPSBOVUxMKQoJCXNldF9iaXQoUjFCSU9fQmVoaW5kSU8sICZyMV9iaW8tPnN0YXRlKTsKCglhdG9taWNfc2V0KCZyMV9iaW8tPnJlbWFpbmluZywgMCk7CglhdG9taWNfc2V0KCZyMV9iaW8tPmJlaGluZF9yZW1haW5pbmcsIDApOwoKCWRvX2JhcnJpZXJzID0gYmlvLT5iaV9ydyAmIEJJT19SV19CQVJSSUVSOwoJaWYgKGRvX2JhcnJpZXJzKQoJCXNldF9iaXQoUjFCSU9fQmFycmllciwgJnIxX2Jpby0+c3RhdGUpOwoKCWJpb19saXN0X2luaXQoJmJsKTsKCWZvciAoaSA9IDA7IGkgPCBkaXNrczsgaSsrKSB7CgkJc3RydWN0IGJpbyAqbWJpbzsKCQlpZiAoIXIxX2Jpby0+Ymlvc1tpXSkKCQkJY29udGludWU7CgoJCW1iaW8gPSBiaW9fY2xvbmUoYmlvLCBHRlBfTk9JTyk7CgkJcjFfYmlvLT5iaW9zW2ldID0gbWJpbzsKCgkJbWJpby0+Ymlfc2VjdG9yCT0gcjFfYmlvLT5zZWN0b3IgKyBjb25mLT5taXJyb3JzW2ldLnJkZXYtPmRhdGFfb2Zmc2V0OwoJCW1iaW8tPmJpX2JkZXYgPSBjb25mLT5taXJyb3JzW2ldLnJkZXYtPmJkZXY7CgkJbWJpby0+YmlfZW5kX2lvCT0gcmFpZDFfZW5kX3dyaXRlX3JlcXVlc3Q7CgkJbWJpby0+YmlfcncgPSBXUklURSB8IGRvX2JhcnJpZXJzOwoJCW1iaW8tPmJpX3ByaXZhdGUgPSByMV9iaW87CgoJCWlmIChiZWhpbmRfcGFnZXMpIHsKCQkJc3RydWN0IGJpb192ZWMgKmJ2ZWM7CgkJCWludCBqOwoKCQkJLyogWWVzLCBJIHJlYWxseSB3YW50IHRoZSAnX18nIHZlcnNpb24gc28gdGhhdAoJCQkgKiB3ZSBjbGVhciBhbnkgdW51c2VkIHBvaW50ZXIgaW4gdGhlIGlvX3ZlYywgcmF0aGVyCgkJCSAqIHRoYW4gbGVhdmUgdGhlbSB1bmNoYW5nZWQuICBUaGlzIGlzIGltcG9ydGFudAoJCQkgKiBiZWNhdXNlIHdoZW4gd2UgY29tZSB0byBmcmVlIHRoZSBwYWdlcywgd2Ugd29uJ3QKCQkJICoga25vdyB0aGUgb3JpZ2luaWFsIGJpX2lkeCwgc28gd2UganVzdCBmcmVlCgkJCSAqIHRoZW0gYWxsCgkJCSAqLwoJCQlfX2Jpb19mb3JfZWFjaF9zZWdtZW50KGJ2ZWMsIG1iaW8sIGosIDApCgkJCQlidmVjLT5idl9wYWdlID0gYmVoaW5kX3BhZ2VzW2pdOwoJCQlpZiAodGVzdF9iaXQoV3JpdGVNb3N0bHksICZjb25mLT5taXJyb3JzW2ldLnJkZXYtPmZsYWdzKSkKCQkJCWF0b21pY19pbmMoJnIxX2Jpby0+YmVoaW5kX3JlbWFpbmluZyk7CgkJfQoKCQlhdG9taWNfaW5jKCZyMV9iaW8tPnJlbWFpbmluZyk7CgoJCWJpb19saXN0X2FkZCgmYmwsIG1iaW8pOwoJfQoJa2ZyZWUoYmVoaW5kX3BhZ2VzKTsgLyogdGhlIGJlaGluZCBwYWdlcyBhcmUgYXR0YWNoZWQgdG8gdGhlIGJpb3Mgbm93ICovCgoJYml0bWFwX3N0YXJ0d3JpdGUoYml0bWFwLCBiaW8tPmJpX3NlY3RvciwgcjFfYmlvLT5zZWN0b3JzLAoJCQkJdGVzdF9iaXQoUjFCSU9fQmVoaW5kSU8sICZyMV9iaW8tPnN0YXRlKSk7CglzcGluX2xvY2tfaXJxc2F2ZSgmY29uZi0+ZGV2aWNlX2xvY2ssIGZsYWdzKTsKCWJpb19saXN0X21lcmdlKCZjb25mLT5wZW5kaW5nX2Jpb19saXN0LCAmYmwpOwoJYmlvX2xpc3RfaW5pdCgmYmwpOwoKCWJsa19wbHVnX2RldmljZShtZGRldi0+cXVldWUpOwoJc3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmY29uZi0+ZGV2aWNlX2xvY2ssIGZsYWdzKTsKCiNpZiAwCgl3aGlsZSAoKGJpbyA9IGJpb19saXN0X3BvcCgmYmwpKSAhPSBOVUxMKQoJCWdlbmVyaWNfbWFrZV9yZXF1ZXN0KGJpbyk7CiNlbmRpZgoKCXJldHVybiAwOwp9CgpzdGF0aWMgdm9pZCBzdGF0dXMoc3RydWN0IHNlcV9maWxlICpzZXEsIG1kZGV2X3QgKm1kZGV2KQp7Cgljb25mX3QgKmNvbmYgPSBtZGRldl90b19jb25mKG1kZGV2KTsKCWludCBpOwoKCXNlcV9wcmludGYoc2VxLCAiIFslZC8lZF0gWyIsIGNvbmYtPnJhaWRfZGlza3MsCgkJCQkJCWNvbmYtPndvcmtpbmdfZGlza3MpOwoJZm9yIChpID0gMDsgaSA8IGNvbmYtPnJhaWRfZGlza3M7IGkrKykKCQlzZXFfcHJpbnRmKHNlcSwgIiVzIiwKCQkJICAgICAgY29uZi0+bWlycm9yc1tpXS5yZGV2ICYmCgkJCSAgICAgIHRlc3RfYml0KEluX3N5bmMsICZjb25mLT5taXJyb3JzW2ldLnJkZXYtPmZsYWdzKSA/ICJVIiA6ICJfIik7CglzZXFfcHJpbnRmKHNlcSwgIl0iKTsKfQoKCnN0YXRpYyB2b2lkIGVycm9yKG1kZGV2X3QgKm1kZGV2LCBtZGtfcmRldl90ICpyZGV2KQp7CgljaGFyIGJbQkRFVk5BTUVfU0laRV07Cgljb25mX3QgKmNvbmYgPSBtZGRldl90b19jb25mKG1kZGV2KTsKCgkvKgoJICogSWYgaXQgaXMgbm90IG9wZXJhdGlvbmFsLCB0aGVuIHdlIGhhdmUgYWxyZWFkeSBtYXJrZWQgaXQgYXMgZGVhZAoJICogZWxzZSBpZiBpdCBpcyB0aGUgbGFzdCB3b3JraW5nIGRpc2tzLCBpZ25vcmUgdGhlIGVycm9yLCBsZXQgdGhlCgkgKiBuZXh0IGxldmVsIHVwIGtub3cuCgkgKiBlbHNlIG1hcmsgdGhlIGRyaXZlIGFzIGZhaWxlZAoJICovCglpZiAodGVzdF9iaXQoSW5fc3luYywgJnJkZXYtPmZsYWdzKQoJICAgICYmIGNvbmYtPndvcmtpbmdfZGlza3MgPT0gMSkKCQkvKgoJCSAqIERvbid0IGZhaWwgdGhlIGRyaXZlLCBhY3QgYXMgdGhvdWdoIHdlIHdlcmUganVzdCBhCgkJICogbm9ybWFsIHNpbmdsZSBkcml2ZQoJCSAqLwoJCXJldHVybjsKCWlmICh0ZXN0X2JpdChJbl9zeW5jLCAmcmRldi0+ZmxhZ3MpKSB7CgkJbWRkZXYtPmRlZ3JhZGVkKys7CgkJY29uZi0+d29ya2luZ19kaXNrcy0tOwoJCS8qCgkJICogaWYgcmVjb3ZlcnkgaXMgcnVubmluZywgbWFrZSBzdXJlIGl0IGFib3J0cy4KCQkgKi8KCQlzZXRfYml0KE1EX1JFQ09WRVJZX0VSUiwgJm1kZGV2LT5yZWNvdmVyeSk7Cgl9CgljbGVhcl9iaXQoSW5fc3luYywgJnJkZXYtPmZsYWdzKTsKCXNldF9iaXQoRmF1bHR5LCAmcmRldi0+ZmxhZ3MpOwoJbWRkZXYtPnNiX2RpcnR5ID0gMTsKCXByaW50ayhLRVJOX0FMRVJUICJyYWlkMTogRGlzayBmYWlsdXJlIG9uICVzLCBkaXNhYmxpbmcgZGV2aWNlLiBcbiIKCQkiCU9wZXJhdGlvbiBjb250aW51aW5nIG9uICVkIGRldmljZXNcbiIsCgkJYmRldm5hbWUocmRldi0+YmRldixiKSwgY29uZi0+d29ya2luZ19kaXNrcyk7Cn0KCnN0YXRpYyB2b2lkIHByaW50X2NvbmYoY29uZl90ICpjb25mKQp7CglpbnQgaTsKCW1pcnJvcl9pbmZvX3QgKnRtcDsKCglwcmludGsoIlJBSUQxIGNvbmYgcHJpbnRvdXQ6XG4iKTsKCWlmICghY29uZikgewoJCXByaW50aygiKCFjb25mKVxuIik7CgkJcmV0dXJuOwoJfQoJcHJpbnRrKCIgLS0tIHdkOiVkIHJkOiVkXG4iLCBjb25mLT53b3JraW5nX2Rpc2tzLAoJCWNvbmYtPnJhaWRfZGlza3MpOwoKCWZvciAoaSA9IDA7IGkgPCBjb25mLT5yYWlkX2Rpc2tzOyBpKyspIHsKCQljaGFyIGJbQkRFVk5BTUVfU0laRV07CgkJdG1wID0gY29uZi0+bWlycm9ycyArIGk7CgkJaWYgKHRtcC0+cmRldikKCQkJcHJpbnRrKCIgZGlzayAlZCwgd286JWQsIG86JWQsIGRldjolc1xuIiwKCQkJCWksICF0ZXN0X2JpdChJbl9zeW5jLCAmdG1wLT5yZGV2LT5mbGFncyksICF0ZXN0X2JpdChGYXVsdHksICZ0bXAtPnJkZXYtPmZsYWdzKSwKCQkJCWJkZXZuYW1lKHRtcC0+cmRldi0+YmRldixiKSk7Cgl9Cn0KCnN0YXRpYyB2b2lkIGNsb3NlX3N5bmMoY29uZl90ICpjb25mKQp7Cgl3YWl0X2JhcnJpZXIoY29uZik7CglhbGxvd19iYXJyaWVyKGNvbmYpOwoKCW1lbXBvb2xfZGVzdHJveShjb25mLT5yMWJ1Zl9wb29sKTsKCWNvbmYtPnIxYnVmX3Bvb2wgPSBOVUxMOwp9CgpzdGF0aWMgaW50IHJhaWQxX3NwYXJlX2FjdGl2ZShtZGRldl90ICptZGRldikKewoJaW50IGk7Cgljb25mX3QgKmNvbmYgPSBtZGRldi0+cHJpdmF0ZTsKCW1pcnJvcl9pbmZvX3QgKnRtcDsKCgkvKgoJICogRmluZCBhbGwgZmFpbGVkIGRpc2tzIHdpdGhpbiB0aGUgUkFJRDEgY29uZmlndXJhdGlvbiAKCSAqIGFuZCBtYXJrIHRoZW0gcmVhZGFibGUKCSAqLwoJZm9yIChpID0gMDsgaSA8IGNvbmYtPnJhaWRfZGlza3M7IGkrKykgewoJCXRtcCA9IGNvbmYtPm1pcnJvcnMgKyBpOwoJCWlmICh0bXAtPnJkZXYgCgkJICAgICYmICF0ZXN0X2JpdChGYXVsdHksICZ0bXAtPnJkZXYtPmZsYWdzKQoJCSAgICAmJiAhdGVzdF9iaXQoSW5fc3luYywgJnRtcC0+cmRldi0+ZmxhZ3MpKSB7CgkJCWNvbmYtPndvcmtpbmdfZGlza3MrKzsKCQkJbWRkZXYtPmRlZ3JhZGVkLS07CgkJCXNldF9iaXQoSW5fc3luYywgJnRtcC0+cmRldi0+ZmxhZ3MpOwoJCX0KCX0KCglwcmludF9jb25mKGNvbmYpOwoJcmV0dXJuIDA7Cn0KCgpzdGF0aWMgaW50IHJhaWQxX2FkZF9kaXNrKG1kZGV2X3QgKm1kZGV2LCBtZGtfcmRldl90ICpyZGV2KQp7Cgljb25mX3QgKmNvbmYgPSBtZGRldi0+cHJpdmF0ZTsKCWludCBmb3VuZCA9IDA7CglpbnQgbWlycm9yID0gMDsKCW1pcnJvcl9pbmZvX3QgKnA7CgoJZm9yIChtaXJyb3I9MDsgbWlycm9yIDwgbWRkZXYtPnJhaWRfZGlza3M7IG1pcnJvcisrKQoJCWlmICggIShwPWNvbmYtPm1pcnJvcnMrbWlycm9yKS0+cmRldikgewoKCQkJYmxrX3F1ZXVlX3N0YWNrX2xpbWl0cyhtZGRldi0+cXVldWUsCgkJCQkJICAgICAgIHJkZXYtPmJkZXYtPmJkX2Rpc2stPnF1ZXVlKTsKCQkJLyogYXMgd2UgZG9uJ3QgaG9ub3VyIG1lcmdlX2J2ZWNfZm4sIHdlIG11c3QgbmV2ZXIgcmlzawoJCQkgKiB2aW9sYXRpbmcgaXQsIHNvIGxpbWl0IC0+bWF4X3NlY3RvciB0byBvbmUgUEFHRSwgYXMKCQkJICogYSBvbmUgcGFnZSByZXF1ZXN0IGlzIG5ldmVyIGluIHZpb2xhdGlvbi4KCQkJICovCgkJCWlmIChyZGV2LT5iZGV2LT5iZF9kaXNrLT5xdWV1ZS0+bWVyZ2VfYnZlY19mbiAmJgoJCQkgICAgbWRkZXYtPnF1ZXVlLT5tYXhfc2VjdG9ycyA+IChQQUdFX1NJWkU+PjkpKQoJCQkJYmxrX3F1ZXVlX21heF9zZWN0b3JzKG1kZGV2LT5xdWV1ZSwgUEFHRV9TSVpFPj45KTsKCgkJCXAtPmhlYWRfcG9zaXRpb24gPSAwOwoJCQlyZGV2LT5yYWlkX2Rpc2sgPSBtaXJyb3I7CgkJCWZvdW5kID0gMTsKCQkJLyogQXMgYWxsIGRldmljZXMgYXJlIGVxdWl2YWxlbnQsIHdlIGRvbid0IG5lZWQgYSBmdWxsIHJlY292ZXJ5CgkJCSAqIGlmIHRoaXMgd2FzIHJlY2VudGx5IGFueSBkcml2ZSBvZiB0aGUgYXJyYXkKCQkJICovCgkJCWlmIChyZGV2LT5zYXZlZF9yYWlkX2Rpc2sgPCAwKQoJCQkJY29uZi0+ZnVsbHN5bmMgPSAxOwoJCQlyY3VfYXNzaWduX3BvaW50ZXIocC0+cmRldiwgcmRldik7CgkJCWJyZWFrOwoJCX0KCglwcmludF9jb25mKGNvbmYpOwoJcmV0dXJuIGZvdW5kOwp9CgpzdGF0aWMgaW50IHJhaWQxX3JlbW92ZV9kaXNrKG1kZGV2X3QgKm1kZGV2LCBpbnQgbnVtYmVyKQp7Cgljb25mX3QgKmNvbmYgPSBtZGRldi0+cHJpdmF0ZTsKCWludCBlcnIgPSAwOwoJbWRrX3JkZXZfdCAqcmRldjsKCW1pcnJvcl9pbmZvX3QgKnAgPSBjb25mLT5taXJyb3JzKyBudW1iZXI7CgoJcHJpbnRfY29uZihjb25mKTsKCXJkZXYgPSBwLT5yZGV2OwoJaWYgKHJkZXYpIHsKCQlpZiAodGVzdF9iaXQoSW5fc3luYywgJnJkZXYtPmZsYWdzKSB8fAoJCSAgICBhdG9taWNfcmVhZCgmcmRldi0+bnJfcGVuZGluZykpIHsKCQkJZXJyID0gLUVCVVNZOwoJCQlnb3RvIGFib3J0OwoJCX0KCQlwLT5yZGV2ID0gTlVMTDsKCQlzeW5jaHJvbml6ZV9yY3UoKTsKCQlpZiAoYXRvbWljX3JlYWQoJnJkZXYtPm5yX3BlbmRpbmcpKSB7CgkJCS8qIGxvc3QgdGhlIHJhY2UsIHRyeSBsYXRlciAqLwoJCQllcnIgPSAtRUJVU1k7CgkJCXAtPnJkZXYgPSByZGV2OwoJCX0KCX0KYWJvcnQ6CgoJcHJpbnRfY29uZihjb25mKTsKCXJldHVybiBlcnI7Cn0KCgpzdGF0aWMgaW50IGVuZF9zeW5jX3JlYWQoc3RydWN0IGJpbyAqYmlvLCB1bnNpZ25lZCBpbnQgYnl0ZXNfZG9uZSwgaW50IGVycm9yKQp7CglyMWJpb190ICogcjFfYmlvID0gKHIxYmlvX3QgKikoYmlvLT5iaV9wcml2YXRlKTsKCWludCBpOwoKCWlmIChiaW8tPmJpX3NpemUpCgkJcmV0dXJuIDE7CgoJZm9yIChpPXIxX2Jpby0+bWRkZXYtPnJhaWRfZGlza3M7IGktLTsgKQoJCWlmIChyMV9iaW8tPmJpb3NbaV0gPT0gYmlvKQoJCQlicmVhazsKCUJVR19PTihpIDwgMCk7Cgl1cGRhdGVfaGVhZF9wb3MoaSwgcjFfYmlvKTsKCS8qCgkgKiB3ZSBoYXZlIHJlYWQgYSBibG9jaywgbm93IGl0IG5lZWRzIHRvIGJlIHJlLXdyaXR0ZW4sCgkgKiBvciByZS1yZWFkIGlmIHRoZSByZWFkIGZhaWxlZC4KCSAqIFdlIGRvbid0IGRvIG11Y2ggaGVyZSwganVzdCBzY2hlZHVsZSBoYW5kbGluZyBieSByYWlkMWQKCSAqLwoJaWYgKHRlc3RfYml0KEJJT19VUFRPREFURSwgJmJpby0+YmlfZmxhZ3MpKQoJCXNldF9iaXQoUjFCSU9fVXB0b2RhdGUsICZyMV9iaW8tPnN0YXRlKTsKCglpZiAoYXRvbWljX2RlY19hbmRfdGVzdCgmcjFfYmlvLT5yZW1haW5pbmcpKQoJCXJlc2NoZWR1bGVfcmV0cnkocjFfYmlvKTsKCXJldHVybiAwOwp9CgpzdGF0aWMgaW50IGVuZF9zeW5jX3dyaXRlKHN0cnVjdCBiaW8gKmJpbywgdW5zaWduZWQgaW50IGJ5dGVzX2RvbmUsIGludCBlcnJvcikKewoJaW50IHVwdG9kYXRlID0gdGVzdF9iaXQoQklPX1VQVE9EQVRFLCAmYmlvLT5iaV9mbGFncyk7CglyMWJpb190ICogcjFfYmlvID0gKHIxYmlvX3QgKikoYmlvLT5iaV9wcml2YXRlKTsKCW1kZGV2X3QgKm1kZGV2ID0gcjFfYmlvLT5tZGRldjsKCWNvbmZfdCAqY29uZiA9IG1kZGV2X3RvX2NvbmYobWRkZXYpOwoJaW50IGk7CglpbnQgbWlycm9yPTA7CgoJaWYgKGJpby0+Ymlfc2l6ZSkKCQlyZXR1cm4gMTsKCglmb3IgKGkgPSAwOyBpIDwgY29uZi0+cmFpZF9kaXNrczsgaSsrKQoJCWlmIChyMV9iaW8tPmJpb3NbaV0gPT0gYmlvKSB7CgkJCW1pcnJvciA9IGk7CgkJCWJyZWFrOwoJCX0KCWlmICghdXB0b2RhdGUpCgkJbWRfZXJyb3IobWRkZXYsIGNvbmYtPm1pcnJvcnNbbWlycm9yXS5yZGV2KTsKCgl1cGRhdGVfaGVhZF9wb3MobWlycm9yLCByMV9iaW8pOwoKCWlmIChhdG9taWNfZGVjX2FuZF90ZXN0KCZyMV9iaW8tPnJlbWFpbmluZykpIHsKCQltZF9kb25lX3N5bmMobWRkZXYsIHIxX2Jpby0+c2VjdG9ycywgdXB0b2RhdGUpOwoJCXB1dF9idWYocjFfYmlvKTsKCX0KCXJldHVybiAwOwp9CgpzdGF0aWMgdm9pZCBzeW5jX3JlcXVlc3Rfd3JpdGUobWRkZXZfdCAqbWRkZXYsIHIxYmlvX3QgKnIxX2JpbykKewoJY29uZl90ICpjb25mID0gbWRkZXZfdG9fY29uZihtZGRldik7CglpbnQgaTsKCWludCBkaXNrcyA9IGNvbmYtPnJhaWRfZGlza3M7CglzdHJ1Y3QgYmlvICpiaW8sICp3YmlvOwoKCWJpbyA9IHIxX2Jpby0+Ymlvc1tyMV9iaW8tPnJlYWRfZGlza107CgoKCWlmICh0ZXN0X2JpdChNRF9SRUNPVkVSWV9SRVFVRVNURUQsICZtZGRldi0+cmVjb3ZlcnkpKSB7CgkJLyogV2UgaGF2ZSByZWFkIGFsbCByZWFkYWJsZSBkZXZpY2VzLiAgSWYgd2UgaGF2ZW4ndAoJCSAqIGdvdCB0aGUgYmxvY2ssIHRoZW4gdGhlcmUgaXMgbm8gaG9wZSBsZWZ0LgoJCSAqIElmIHdlIGhhdmUsIHRoZW4gd2Ugd2FudCB0byBkbyBhIGNvbXBhcmlzb24KCQkgKiBhbmQgc2tpcCB0aGUgd3JpdGUgaWYgZXZlcnl0aGluZyBpcyB0aGUgc2FtZS4KCQkgKiBJZiBhbnkgYmxvY2tzIGZhaWxlZCB0byByZWFkLCB0aGVuIHdlIG5lZWQgdG8KCQkgKiBhdHRlbXB0IGFuIG92ZXItd3JpdGUKCQkgKi8KCQlpbnQgcHJpbWFyeTsKCQlpZiAoIXRlc3RfYml0KFIxQklPX1VwdG9kYXRlLCAmcjFfYmlvLT5zdGF0ZSkpIHsKCQkJZm9yIChpPTA7IGk8bWRkZXYtPnJhaWRfZGlza3M7IGkrKykKCQkJCWlmIChyMV9iaW8tPmJpb3NbaV0tPmJpX2VuZF9pbyA9PSBlbmRfc3luY19yZWFkKQoJCQkJCW1kX2Vycm9yKG1kZGV2LCBjb25mLT5taXJyb3JzW2ldLnJkZXYpOwoKCQkJbWRfZG9uZV9zeW5jKG1kZGV2LCByMV9iaW8tPnNlY3RvcnMsIDEpOwoJCQlwdXRfYnVmKHIxX2Jpbyk7CgkJCXJldHVybjsKCQl9CgkJZm9yIChwcmltYXJ5PTA7IHByaW1hcnk8bWRkZXYtPnJhaWRfZGlza3M7IHByaW1hcnkrKykKCQkJaWYgKHIxX2Jpby0+Ymlvc1twcmltYXJ5XS0+YmlfZW5kX2lvID09IGVuZF9zeW5jX3JlYWQgJiYKCQkJICAgIHRlc3RfYml0KEJJT19VUFRPREFURSwgJnIxX2Jpby0+Ymlvc1twcmltYXJ5XS0+YmlfZmxhZ3MpKSB7CgkJCQlyMV9iaW8tPmJpb3NbcHJpbWFyeV0tPmJpX2VuZF9pbyA9IE5VTEw7CgkJCQlicmVhazsKCQkJfQoJCXIxX2Jpby0+cmVhZF9kaXNrID0gcHJpbWFyeTsKCQlmb3IgKGk9MDsgaTxtZGRldi0+cmFpZF9kaXNrczsgaSsrKQoJCQlpZiAocjFfYmlvLT5iaW9zW2ldLT5iaV9lbmRfaW8gPT0gZW5kX3N5bmNfcmVhZCAmJgoJCQkgICAgdGVzdF9iaXQoQklPX1VQVE9EQVRFLCAmcjFfYmlvLT5iaW9zW2ldLT5iaV9mbGFncykpIHsKCQkJCWludCBqOwoJCQkJaW50IHZjbnQgPSByMV9iaW8tPnNlY3RvcnMgPj4gKFBBR0VfU0hJRlQtIDkpOwoJCQkJc3RydWN0IGJpbyAqcGJpbyA9IHIxX2Jpby0+Ymlvc1twcmltYXJ5XTsKCQkJCXN0cnVjdCBiaW8gKnNiaW8gPSByMV9iaW8tPmJpb3NbaV07CgkJCQlmb3IgKGogPSB2Y250OyBqLS0gOyApCgkJCQkJaWYgKG1lbWNtcChwYWdlX2FkZHJlc3MocGJpby0+YmlfaW9fdmVjW2pdLmJ2X3BhZ2UpLAoJCQkJCQkgICBwYWdlX2FkZHJlc3Moc2Jpby0+YmlfaW9fdmVjW2pdLmJ2X3BhZ2UpLAoJCQkJCQkgICBQQUdFX1NJWkUpKQoJCQkJCQlicmVhazsKCQkJCWlmIChqID49IDApCgkJCQkJbWRkZXYtPnJlc3luY19taXNtYXRjaGVzICs9IHIxX2Jpby0+c2VjdG9yczsKCQkJCWlmIChqIDwgMCB8fCB0ZXN0X2JpdChNRF9SRUNPVkVSWV9DSEVDSywgJm1kZGV2LT5yZWNvdmVyeSkpCgkJCQkJc2Jpby0+YmlfZW5kX2lvID0gTlVMTDsKCQkJCWVsc2UgewoJCQkJCS8qIGZpeHVwIHRoZSBiaW8gZm9yIHJldXNlICovCgkJCQkJc2Jpby0+YmlfdmNudCA9IHZjbnQ7CgkJCQkJc2Jpby0+Ymlfc2l6ZSA9IHIxX2Jpby0+c2VjdG9ycyA8PCA5OwoJCQkJCXNiaW8tPmJpX2lkeCA9IDA7CgkJCQkJc2Jpby0+YmlfcGh5c19zZWdtZW50cyA9IDA7CgkJCQkJc2Jpby0+YmlfaHdfc2VnbWVudHMgPSAwOwoJCQkJCXNiaW8tPmJpX2h3X2Zyb250X3NpemUgPSAwOwoJCQkJCXNiaW8tPmJpX2h3X2JhY2tfc2l6ZSA9IDA7CgkJCQkJc2Jpby0+YmlfZmxhZ3MgJj0gfihCSU9fUE9PTF9NQVNLIC0gMSk7CgkJCQkJc2Jpby0+YmlfZmxhZ3MgfD0gMSA8PCBCSU9fVVBUT0RBVEU7CgkJCQkJc2Jpby0+YmlfbmV4dCA9IE5VTEw7CgkJCQkJc2Jpby0+Ymlfc2VjdG9yID0gcjFfYmlvLT5zZWN0b3IgKwoJCQkJCQljb25mLT5taXJyb3JzW2ldLnJkZXYtPmRhdGFfb2Zmc2V0OwoJCQkJCXNiaW8tPmJpX2JkZXYgPSBjb25mLT5taXJyb3JzW2ldLnJkZXYtPmJkZXY7CgkJCQl9CgkJCX0KCX0KCWlmICghdGVzdF9iaXQoUjFCSU9fVXB0b2RhdGUsICZyMV9iaW8tPnN0YXRlKSkgewoJCS8qIG91Y2ggLSBmYWlsZWQgdG8gcmVhZCBhbGwgb2YgdGhhdC4KCQkgKiBUcnkgc29tZSBzeW5jaHJvbm91cyByZWFkcyBvZiBvdGhlciBkZXZpY2VzIHRvIGdldAoJCSAqIGdvb2QgZGF0YSwgbXVjaCBsaWtlIHdpdGggbm9ybWFsIHJlYWQgZXJyb3JzLiAgT25seQoJCSAqIHJlYWQgaW50byB0aGUgcGFnZXMgd2UgYWxyZWFkeSBoYXZlIHNvIHRoZXkgd2UgZG9uJ3QKCQkgKiBuZWVkIHRvIHJlLWlzc3VlIHRoZSByZWFkIHJlcXVlc3QuCgkJICogV2UgZG9uJ3QgbmVlZCB0byBmcmVlemUgdGhlIGFycmF5LCBiZWNhdXNlIGJlaW5nIGluIGFuCgkJICogYWN0aXZlIHN5bmMgcmVxdWVzdCwgdGhlcmUgaXMgbm8gbm9ybWFsIElPLCBhbmQKCQkgKiBubyBvdmVybGFwcGluZyBzeW5jcy4KCQkgKi8KCQlzZWN0b3JfdCBzZWN0ID0gcjFfYmlvLT5zZWN0b3I7CgkJaW50IHNlY3RvcnMgPSByMV9iaW8tPnNlY3RvcnM7CgkJaW50IGlkeCA9IDA7CgoJCXdoaWxlKHNlY3RvcnMpIHsKCQkJaW50IHMgPSBzZWN0b3JzOwoJCQlpbnQgZCA9IHIxX2Jpby0+cmVhZF9kaXNrOwoJCQlpbnQgc3VjY2VzcyA9IDA7CgkJCW1ka19yZGV2X3QgKnJkZXY7CgoJCQlpZiAocyA+IChQQUdFX1NJWkU+PjkpKQoJCQkJcyA9IFBBR0VfU0laRSA+PiA5OwoJCQlkbyB7CgkJCQlpZiAocjFfYmlvLT5iaW9zW2RdLT5iaV9lbmRfaW8gPT0gZW5kX3N5bmNfcmVhZCkgewoJCQkJCXJkZXYgPSBjb25mLT5taXJyb3JzW2RdLnJkZXY7CgkJCQkJaWYgKHN5bmNfcGFnZV9pbyhyZGV2LT5iZGV2LAoJCQkJCQkJIHNlY3QgKyByZGV2LT5kYXRhX29mZnNldCwKCQkJCQkJCSBzPDw5LAoJCQkJCQkJIGJpby0+YmlfaW9fdmVjW2lkeF0uYnZfcGFnZSwKCQkJCQkJCSBSRUFEKSkgewoJCQkJCQlzdWNjZXNzID0gMTsKCQkJCQkJYnJlYWs7CgkJCQkJfQoJCQkJfQoJCQkJZCsrOwoJCQkJaWYgKGQgPT0gY29uZi0+cmFpZF9kaXNrcykKCQkJCQlkID0gMDsKCQkJfSB3aGlsZSAoIXN1Y2Nlc3MgJiYgZCAhPSByMV9iaW8tPnJlYWRfZGlzayk7CgoJCQlpZiAoc3VjY2VzcykgewoJCQkJLyogd3JpdGUgaXQgYmFjayBhbmQgcmUtcmVhZCAqLwoJCQkJc2V0X2JpdChSMUJJT19VcHRvZGF0ZSwgJnIxX2Jpby0+c3RhdGUpOwoJCQkJd2hpbGUgKGQgIT0gcjFfYmlvLT5yZWFkX2Rpc2spIHsKCQkJCQlpZiAoZCA9PSAwKQoJCQkJCQlkID0gY29uZi0+cmFpZF9kaXNrczsKCQkJCQlkLS07CgkJCQkJaWYgKHIxX2Jpby0+Ymlvc1tkXS0+YmlfZW5kX2lvICE9IGVuZF9zeW5jX3JlYWQpCgkJCQkJCWNvbnRpbnVlOwoJCQkJCXJkZXYgPSBjb25mLT5taXJyb3JzW2RdLnJkZXY7CgkJCQkJaWYgKHN5bmNfcGFnZV9pbyhyZGV2LT5iZGV2LAoJCQkJCQkJIHNlY3QgKyByZGV2LT5kYXRhX29mZnNldCwKCQkJCQkJCSBzPDw5LAoJCQkJCQkJIGJpby0+YmlfaW9fdmVjW2lkeF0uYnZfcGFnZSwKCQkJCQkJCSBXUklURSkgPT0gMCB8fAoJCQkJCSAgICBzeW5jX3BhZ2VfaW8ocmRldi0+YmRldiwKCQkJCQkJCSBzZWN0ICsgcmRldi0+ZGF0YV9vZmZzZXQsCgkJCQkJCQkgczw8OSwKCQkJCQkJCSBiaW8tPmJpX2lvX3ZlY1tpZHhdLmJ2X3BhZ2UsCgkJCQkJCQkgUkVBRCkgPT0gMCkgewoJCQkJCQltZF9lcnJvcihtZGRldiwgcmRldik7CgkJCQkJfQoJCQkJfQoJCQl9IGVsc2UgewoJCQkJY2hhciBiW0JERVZOQU1FX1NJWkVdOwoJCQkJLyogQ2Fubm90IHJlYWQgZnJvbSBhbnl3aGVyZSwgYXJyYXkgaXMgdG9hc3QgKi8KCQkJCW1kX2Vycm9yKG1kZGV2LCBjb25mLT5taXJyb3JzW3IxX2Jpby0+cmVhZF9kaXNrXS5yZGV2KTsKCQkJCXByaW50ayhLRVJOX0FMRVJUICJyYWlkMTogJXM6IHVucmVjb3ZlcmFibGUgSS9PIHJlYWQgZXJyb3IiCgkJCQkgICAgICAgIiBmb3IgYmxvY2sgJWxsdVxuIiwKCQkJCSAgICAgICBiZGV2bmFtZShiaW8tPmJpX2JkZXYsYiksCgkJCQkgICAgICAgKHVuc2lnbmVkIGxvbmcgbG9uZylyMV9iaW8tPnNlY3Rvcik7CgkJCQltZF9kb25lX3N5bmMobWRkZXYsIHIxX2Jpby0+c2VjdG9ycywgMCk7CgkJCQlwdXRfYnVmKHIxX2Jpbyk7CgkJCQlyZXR1cm47CgkJCX0KCQkJc2VjdG9ycyAtPSBzOwoJCQlzZWN0ICs9IHM7CgkJCWlkeCArKzsKCQl9Cgl9CgoJLyoKCSAqIHNjaGVkdWxlIHdyaXRlcwoJICovCglhdG9taWNfc2V0KCZyMV9iaW8tPnJlbWFpbmluZywgMSk7Cglmb3IgKGkgPSAwOyBpIDwgZGlza3MgOyBpKyspIHsKCQl3YmlvID0gcjFfYmlvLT5iaW9zW2ldOwoJCWlmICh3YmlvLT5iaV9lbmRfaW8gPT0gTlVMTCB8fAoJCSAgICAod2Jpby0+YmlfZW5kX2lvID09IGVuZF9zeW5jX3JlYWQgJiYKCQkgICAgIChpID09IHIxX2Jpby0+cmVhZF9kaXNrIHx8CgkJICAgICAgIXRlc3RfYml0KE1EX1JFQ09WRVJZX1NZTkMsICZtZGRldi0+cmVjb3ZlcnkpKSkpCgkJCWNvbnRpbnVlOwoKCQl3YmlvLT5iaV9ydyA9IFdSSVRFOwoJCXdiaW8tPmJpX2VuZF9pbyA9IGVuZF9zeW5jX3dyaXRlOwoJCWF0b21pY19pbmMoJnIxX2Jpby0+cmVtYWluaW5nKTsKCQltZF9zeW5jX2FjY3QoY29uZi0+bWlycm9yc1tpXS5yZGV2LT5iZGV2LCB3YmlvLT5iaV9zaXplID4+IDkpOwoKCQlnZW5lcmljX21ha2VfcmVxdWVzdCh3YmlvKTsKCX0KCglpZiAoYXRvbWljX2RlY19hbmRfdGVzdCgmcjFfYmlvLT5yZW1haW5pbmcpKSB7CgkJLyogaWYgd2UncmUgaGVyZSwgYWxsIHdyaXRlKHMpIGhhdmUgY29tcGxldGVkLCBzbyBjbGVhbiB1cCAqLwoJCW1kX2RvbmVfc3luYyhtZGRldiwgcjFfYmlvLT5zZWN0b3JzLCAxKTsKCQlwdXRfYnVmKHIxX2Jpbyk7Cgl9Cn0KCi8qCiAqIFRoaXMgaXMgYSBrZXJuZWwgdGhyZWFkIHdoaWNoOgogKgogKgkxLglSZXRyaWVzIGZhaWxlZCByZWFkIG9wZXJhdGlvbnMgb24gd29ya2luZyBtaXJyb3JzLgogKgkyLglVcGRhdGVzIHRoZSByYWlkIHN1cGVyYmxvY2sgd2hlbiBwcm9ibGVtcyBlbmNvdW50ZXIuCiAqCTMuCVBlcmZvcm1zIHdyaXRlcyBmb2xsb3dpbmcgcmVhZHMgZm9yIGFycmF5IHN5bmNyb25pc2luZy4KICovCgpzdGF0aWMgdm9pZCByYWlkMWQobWRkZXZfdCAqbWRkZXYpCnsKCXIxYmlvX3QgKnIxX2JpbzsKCXN0cnVjdCBiaW8gKmJpbzsKCXVuc2lnbmVkIGxvbmcgZmxhZ3M7Cgljb25mX3QgKmNvbmYgPSBtZGRldl90b19jb25mKG1kZGV2KTsKCXN0cnVjdCBsaXN0X2hlYWQgKmhlYWQgPSAmY29uZi0+cmV0cnlfbGlzdDsKCWludCB1bnBsdWc9MDsKCW1ka19yZGV2X3QgKnJkZXY7CgoJbWRfY2hlY2tfcmVjb3ZlcnkobWRkZXYpOwoJCglmb3IgKDs7KSB7CgkJY2hhciBiW0JERVZOQU1FX1NJWkVdOwoJCXNwaW5fbG9ja19pcnFzYXZlKCZjb25mLT5kZXZpY2VfbG9jaywgZmxhZ3MpOwoKCQlpZiAoY29uZi0+cGVuZGluZ19iaW9fbGlzdC5oZWFkKSB7CgkJCWJpbyA9IGJpb19saXN0X2dldCgmY29uZi0+cGVuZGluZ19iaW9fbGlzdCk7CgkJCWJsa19yZW1vdmVfcGx1ZyhtZGRldi0+cXVldWUpOwoJCQlzcGluX3VubG9ja19pcnFyZXN0b3JlKCZjb25mLT5kZXZpY2VfbG9jaywgZmxhZ3MpOwoJCQkvKiBmbHVzaCBhbnkgcGVuZGluZyBiaXRtYXAgd3JpdGVzIHRvIGRpc2sgYmVmb3JlIHByb2NlZWRpbmcgdy8gSS9PICovCgkJCWlmIChiaXRtYXBfdW5wbHVnKG1kZGV2LT5iaXRtYXApICE9IDApCgkJCQlwcmludGsoIiVzOiBiaXRtYXAgZmlsZSB3cml0ZSBmYWlsZWQhXG4iLCBtZG5hbWUobWRkZXYpKTsKCgkJCXdoaWxlIChiaW8pIHsgLyogc3VibWl0IHBlbmRpbmcgd3JpdGVzICovCgkJCQlzdHJ1Y3QgYmlvICpuZXh0ID0gYmlvLT5iaV9uZXh0OwoJCQkJYmlvLT5iaV9uZXh0ID0gTlVMTDsKCQkJCWdlbmVyaWNfbWFrZV9yZXF1ZXN0KGJpbyk7CgkJCQliaW8gPSBuZXh0OwoJCQl9CgkJCXVucGx1ZyA9IDE7CgoJCQljb250aW51ZTsKCQl9CgoJCWlmIChsaXN0X2VtcHR5KGhlYWQpKQoJCQlicmVhazsKCQlyMV9iaW8gPSBsaXN0X2VudHJ5KGhlYWQtPnByZXYsIHIxYmlvX3QsIHJldHJ5X2xpc3QpOwoJCWxpc3RfZGVsKGhlYWQtPnByZXYpOwoJCWNvbmYtPm5yX3F1ZXVlZC0tOwoJCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJmNvbmYtPmRldmljZV9sb2NrLCBmbGFncyk7CgoJCW1kZGV2ID0gcjFfYmlvLT5tZGRldjsKCQljb25mID0gbWRkZXZfdG9fY29uZihtZGRldik7CgkJaWYgKHRlc3RfYml0KFIxQklPX0lzU3luYywgJnIxX2Jpby0+c3RhdGUpKSB7CgkJCXN5bmNfcmVxdWVzdF93cml0ZShtZGRldiwgcjFfYmlvKTsKCQkJdW5wbHVnID0gMTsKCQl9IGVsc2UgaWYgKHRlc3RfYml0KFIxQklPX0JhcnJpZXJSZXRyeSwgJnIxX2Jpby0+c3RhdGUpKSB7CgkJCS8qIHNvbWUgcmVxdWVzdHMgaW4gdGhlIHIxYmlvIHdlcmUgQklPX1JXX0JBUlJJRVIKCQkJICogcmVxdWVzdHMgd2hpY2ggZmFpbGVkIHdpdGggLUVOT1RTVVBQLiAgSG9odW1tLi4KCQkJICogQmV0dGVyIHJlc3VibWl0IHdpdGhvdXQgdGhlIGJhcnJpZXIuCgkJCSAqIFdlIGtub3cgd2hpY2ggZGV2aWNlcyB0byByZXN1Ym1pdCBmb3IsIGJlY2F1c2UKCQkJICogYWxsIG90aGVycyBoYXZlIGhhZCB0aGVpciBiaW9zW10gZW50cnkgY2xlYXJlZC4KCQkJICovCgkJCWludCBpOwoJCQljbGVhcl9iaXQoUjFCSU9fQmFycmllclJldHJ5LCAmcjFfYmlvLT5zdGF0ZSk7CgkJCWNsZWFyX2JpdChSMUJJT19CYXJyaWVyLCAmcjFfYmlvLT5zdGF0ZSk7CgkJCWZvciAoaT0wOyBpIDwgY29uZi0+cmFpZF9kaXNrczsgaSsrKQoJCQkJaWYgKHIxX2Jpby0+Ymlvc1tpXSkgewoJCQkJCXN0cnVjdCBiaW9fdmVjICpidmVjOwoJCQkJCWludCBqOwoKCQkJCQliaW8gPSBiaW9fY2xvbmUocjFfYmlvLT5tYXN0ZXJfYmlvLCBHRlBfTk9JTyk7CgkJCQkJLyogY29weSBwYWdlcyBmcm9tIHRoZSBmYWlsZWQgYmlvLCBhcwoJCQkJCSAqIHRoaXMgbWlnaHQgYmUgYSB3cml0ZS1iZWhpbmQgZGV2aWNlICovCgkJCQkJX19iaW9fZm9yX2VhY2hfc2VnbWVudChidmVjLCBiaW8sIGosIDApCgkJCQkJCWJ2ZWMtPmJ2X3BhZ2UgPSBiaW9faW92ZWNfaWR4KHIxX2Jpby0+Ymlvc1tpXSwgaiktPmJ2X3BhZ2U7CgkJCQkJYmlvX3B1dChyMV9iaW8tPmJpb3NbaV0pOwoJCQkJCWJpby0+Ymlfc2VjdG9yID0gcjFfYmlvLT5zZWN0b3IgKwoJCQkJCQljb25mLT5taXJyb3JzW2ldLnJkZXYtPmRhdGFfb2Zmc2V0OwoJCQkJCWJpby0+YmlfYmRldiA9IGNvbmYtPm1pcnJvcnNbaV0ucmRldi0+YmRldjsKCQkJCQliaW8tPmJpX2VuZF9pbyA9IHJhaWQxX2VuZF93cml0ZV9yZXF1ZXN0OwoJCQkJCWJpby0+YmlfcncgPSBXUklURTsKCQkJCQliaW8tPmJpX3ByaXZhdGUgPSByMV9iaW87CgkJCQkJcjFfYmlvLT5iaW9zW2ldID0gYmlvOwoJCQkJCWdlbmVyaWNfbWFrZV9yZXF1ZXN0KGJpbyk7CgkJCQl9CgkJfSBlbHNlIHsKCQkJaW50IGRpc2s7CgoJCQkvKiB3ZSBnb3QgYSByZWFkIGVycm9yLiBNYXliZSB0aGUgZHJpdmUgaXMgYmFkLiAgTWF5YmUganVzdAoJCQkgKiB0aGUgYmxvY2sgYW5kIHdlIGNhbiBmaXggaXQuCgkJCSAqIFdlIGZyZWV6ZSBhbGwgb3RoZXIgSU8sIGFuZCB0cnkgcmVhZGluZyB0aGUgYmxvY2sgZnJvbQoJCQkgKiBvdGhlciBkZXZpY2VzLiAgV2hlbiB3ZSBmaW5kIG9uZSwgd2UgcmUtd3JpdGUKCQkJICogYW5kIGNoZWNrIGl0IHRoYXQgZml4ZXMgdGhlIHJlYWQgZXJyb3IuCgkJCSAqIFRoaXMgaXMgYWxsIGRvbmUgc3luY2hyb25vdXNseSB3aGlsZSB0aGUgYXJyYXkgaXMKCQkJICogZnJvemVuCgkJCSAqLwoJCQlzZWN0b3JfdCBzZWN0ID0gcjFfYmlvLT5zZWN0b3I7CgkJCWludCBzZWN0b3JzID0gcjFfYmlvLT5zZWN0b3JzOwoJCQlmcmVlemVfYXJyYXkoY29uZik7CgkJCWlmIChtZGRldi0+cm8gPT0gMCkgd2hpbGUoc2VjdG9ycykgewoJCQkJaW50IHMgPSBzZWN0b3JzOwoJCQkJaW50IGQgPSByMV9iaW8tPnJlYWRfZGlzazsKCQkJCWludCBzdWNjZXNzID0gMDsKCgkJCQlpZiAocyA+IChQQUdFX1NJWkU+PjkpKQoJCQkJCXMgPSBQQUdFX1NJWkUgPj4gOTsKCgkJCQlkbyB7CgkJCQkJcmRldiA9IGNvbmYtPm1pcnJvcnNbZF0ucmRldjsKCQkJCQlpZiAocmRldiAmJgoJCQkJCSAgICB0ZXN0X2JpdChJbl9zeW5jLCAmcmRldi0+ZmxhZ3MpICYmCgkJCQkJICAgIHN5bmNfcGFnZV9pbyhyZGV2LT5iZGV2LAoJCQkJCQkJIHNlY3QgKyByZGV2LT5kYXRhX29mZnNldCwKCQkJCQkJCSBzPDw5LAoJCQkJCQkJIGNvbmYtPnRtcHBhZ2UsIFJFQUQpKQoJCQkJCQlzdWNjZXNzID0gMTsKCQkJCQllbHNlIHsKCQkJCQkJZCsrOwoJCQkJCQlpZiAoZCA9PSBjb25mLT5yYWlkX2Rpc2tzKQoJCQkJCQkJZCA9IDA7CgkJCQkJfQoJCQkJfSB3aGlsZSAoIXN1Y2Nlc3MgJiYgZCAhPSByMV9iaW8tPnJlYWRfZGlzayk7CgoJCQkJaWYgKHN1Y2Nlc3MpIHsKCQkJCQkvKiB3cml0ZSBpdCBiYWNrIGFuZCByZS1yZWFkICovCgkJCQkJd2hpbGUgKGQgIT0gcjFfYmlvLT5yZWFkX2Rpc2spIHsKCQkJCQkJaWYgKGQ9PTApCgkJCQkJCQlkID0gY29uZi0+cmFpZF9kaXNrczsKCQkJCQkJZC0tOwoJCQkJCQlyZGV2ID0gY29uZi0+bWlycm9yc1tkXS5yZGV2OwoJCQkJCQlpZiAocmRldiAmJgoJCQkJCQkgICAgdGVzdF9iaXQoSW5fc3luYywgJnJkZXYtPmZsYWdzKSkgewoJCQkJCQkJaWYgKHN5bmNfcGFnZV9pbyhyZGV2LT5iZGV2LAoJCQkJCQkJCQkgc2VjdCArIHJkZXYtPmRhdGFfb2Zmc2V0LAoJCQkJCQkJCQkgczw8OSwgY29uZi0+dG1wcGFnZSwgV1JJVEUpID09IDAgfHwKCQkJCQkJCSAgICBzeW5jX3BhZ2VfaW8ocmRldi0+YmRldiwKCQkJCQkJCQkJIHNlY3QgKyByZGV2LT5kYXRhX29mZnNldCwKCQkJCQkJCQkJIHM8PDksIGNvbmYtPnRtcHBhZ2UsIFJFQUQpID09IDApIHsKCQkJCQkJCQkvKiBXZWxsLCB0aGlzIGRldmljZSBpcyBkZWFkICovCgkJCQkJCQkJbWRfZXJyb3IobWRkZXYsIHJkZXYpOwoJCQkJCQkJfQoJCQkJCQl9CgkJCQkJfQoJCQkJfSBlbHNlIHsKCQkJCQkvKiBDYW5ub3QgcmVhZCBmcm9tIGFueXdoZXJlIC0tIGJ5ZSBieWUgYXJyYXkgKi8KCQkJCQltZF9lcnJvcihtZGRldiwgY29uZi0+bWlycm9yc1tyMV9iaW8tPnJlYWRfZGlza10ucmRldik7CgkJCQkJYnJlYWs7CgkJCQl9CgkJCQlzZWN0b3JzIC09IHM7CgkJCQlzZWN0ICs9IHM7CgkJCX0KCgkJCXVuZnJlZXplX2FycmF5KGNvbmYpOwoKCQkJYmlvID0gcjFfYmlvLT5iaW9zW3IxX2Jpby0+cmVhZF9kaXNrXTsKCQkJaWYgKChkaXNrPXJlYWRfYmFsYW5jZShjb25mLCByMV9iaW8pKSA9PSAtMSkgewoJCQkJcHJpbnRrKEtFUk5fQUxFUlQgInJhaWQxOiAlczogdW5yZWNvdmVyYWJsZSBJL08iCgkJCQkgICAgICAgIiByZWFkIGVycm9yIGZvciBibG9jayAlbGx1XG4iLAoJCQkJICAgICAgIGJkZXZuYW1lKGJpby0+YmlfYmRldixiKSwKCQkJCSAgICAgICAodW5zaWduZWQgbG9uZyBsb25nKXIxX2Jpby0+c2VjdG9yKTsKCQkJCXJhaWRfZW5kX2Jpb19pbyhyMV9iaW8pOwoJCQl9IGVsc2UgewoJCQkJcjFfYmlvLT5iaW9zW3IxX2Jpby0+cmVhZF9kaXNrXSA9CgkJCQkJbWRkZXYtPnJvID8gSU9fQkxPQ0tFRCA6IE5VTEw7CgkJCQlyMV9iaW8tPnJlYWRfZGlzayA9IGRpc2s7CgkJCQliaW9fcHV0KGJpbyk7CgkJCQliaW8gPSBiaW9fY2xvbmUocjFfYmlvLT5tYXN0ZXJfYmlvLCBHRlBfTk9JTyk7CgkJCQlyMV9iaW8tPmJpb3NbcjFfYmlvLT5yZWFkX2Rpc2tdID0gYmlvOwoJCQkJcmRldiA9IGNvbmYtPm1pcnJvcnNbZGlza10ucmRldjsKCQkJCWlmIChwcmludGtfcmF0ZWxpbWl0KCkpCgkJCQkJcHJpbnRrKEtFUk5fRVJSICJyYWlkMTogJXM6IHJlZGlyZWN0aW5nIHNlY3RvciAlbGx1IHRvIgoJCQkJCSAgICAgICAiIGFub3RoZXIgbWlycm9yXG4iLAoJCQkJCSAgICAgICBiZGV2bmFtZShyZGV2LT5iZGV2LGIpLAoJCQkJCSAgICAgICAodW5zaWduZWQgbG9uZyBsb25nKXIxX2Jpby0+c2VjdG9yKTsKCQkJCWJpby0+Ymlfc2VjdG9yID0gcjFfYmlvLT5zZWN0b3IgKyByZGV2LT5kYXRhX29mZnNldDsKCQkJCWJpby0+YmlfYmRldiA9IHJkZXYtPmJkZXY7CgkJCQliaW8tPmJpX2VuZF9pbyA9IHJhaWQxX2VuZF9yZWFkX3JlcXVlc3Q7CgkJCQliaW8tPmJpX3J3ID0gUkVBRDsKCQkJCWJpby0+YmlfcHJpdmF0ZSA9IHIxX2JpbzsKCQkJCXVucGx1ZyA9IDE7CgkJCQlnZW5lcmljX21ha2VfcmVxdWVzdChiaW8pOwoJCQl9CgkJfQoJfQoJc3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmY29uZi0+ZGV2aWNlX2xvY2ssIGZsYWdzKTsKCWlmICh1bnBsdWcpCgkJdW5wbHVnX3NsYXZlcyhtZGRldik7Cn0KCgpzdGF0aWMgaW50IGluaXRfcmVzeW5jKGNvbmZfdCAqY29uZikKewoJaW50IGJ1ZmZzOwoKCWJ1ZmZzID0gUkVTWU5DX1dJTkRPVyAvIFJFU1lOQ19CTE9DS19TSVpFOwoJaWYgKGNvbmYtPnIxYnVmX3Bvb2wpCgkJQlVHKCk7Cgljb25mLT5yMWJ1Zl9wb29sID0gbWVtcG9vbF9jcmVhdGUoYnVmZnMsIHIxYnVmX3Bvb2xfYWxsb2MsIHIxYnVmX3Bvb2xfZnJlZSwKCQkJCQkgIGNvbmYtPnBvb2xpbmZvKTsKCWlmICghY29uZi0+cjFidWZfcG9vbCkKCQlyZXR1cm4gLUVOT01FTTsKCWNvbmYtPm5leHRfcmVzeW5jID0gMDsKCXJldHVybiAwOwp9CgovKgogKiBwZXJmb3JtIGEgInN5bmMiIG9uIG9uZSAiYmxvY2siCiAqCiAqIFdlIG5lZWQgdG8gbWFrZSBzdXJlIHRoYXQgbm8gbm9ybWFsIEkvTyByZXF1ZXN0IC0gcGFydGljdWxhcmx5IHdyaXRlCiAqIHJlcXVlc3RzIC0gY29uZmxpY3Qgd2l0aCBhY3RpdmUgc3luYyByZXF1ZXN0cy4KICoKICogVGhpcyBpcyBhY2hpZXZlZCBieSB0cmFja2luZyBwZW5kaW5nIHJlcXVlc3RzIGFuZCBhICdiYXJyaWVyJyBjb25jZXB0CiAqIHRoYXQgY2FuIGJlIGluc3RhbGxlZCB0byBleGNsdWRlIG5vcm1hbCBJTyByZXF1ZXN0cy4KICovCgpzdGF0aWMgc2VjdG9yX3Qgc3luY19yZXF1ZXN0KG1kZGV2X3QgKm1kZGV2LCBzZWN0b3JfdCBzZWN0b3JfbnIsIGludCAqc2tpcHBlZCwgaW50IGdvX2Zhc3RlcikKewoJY29uZl90ICpjb25mID0gbWRkZXZfdG9fY29uZihtZGRldik7CglyMWJpb190ICpyMV9iaW87CglzdHJ1Y3QgYmlvICpiaW87CglzZWN0b3JfdCBtYXhfc2VjdG9yLCBucl9zZWN0b3JzOwoJaW50IGRpc2sgPSAtMTsKCWludCBpOwoJaW50IHdvbmx5ID0gLTE7CglpbnQgd3JpdGVfdGFyZ2V0cyA9IDAsIHJlYWRfdGFyZ2V0cyA9IDA7CglpbnQgc3luY19ibG9ja3M7CglpbnQgc3RpbGxfZGVncmFkZWQgPSAwOwoKCWlmICghY29uZi0+cjFidWZfcG9vbCkKCXsKLyoKCQlwcmludGsoInN5bmMgc3RhcnQgLSBiaXRtYXAgJXBcbiIsIG1kZGV2LT5iaXRtYXApOwoqLwoJCWlmIChpbml0X3Jlc3luYyhjb25mKSkKCQkJcmV0dXJuIDA7Cgl9CgoJbWF4X3NlY3RvciA9IG1kZGV2LT5zaXplIDw8IDE7CglpZiAoc2VjdG9yX25yID49IG1heF9zZWN0b3IpIHsKCQkvKiBJZiB3ZSBhYm9ydGVkLCB3ZSBuZWVkIHRvIGFib3J0IHRoZQoJCSAqIHN5bmMgb24gdGhlICdjdXJyZW50JyBiaXRtYXAgY2h1bmsgKHRoZXJlIHdpbGwKCQkgKiBvbmx5IGJlIG9uZSBpbiByYWlkMSByZXN5bmMuCgkJICogV2UgY2FuIGZpbmQgdGhlIGN1cnJlbnQgYWRkZXNzIGluIG1kZGV2LT5jdXJyX3Jlc3luYwoJCSAqLwoJCWlmIChtZGRldi0+Y3Vycl9yZXN5bmMgPCBtYXhfc2VjdG9yKSAvKiBhYm9ydGVkICovCgkJCWJpdG1hcF9lbmRfc3luYyhtZGRldi0+Yml0bWFwLCBtZGRldi0+Y3Vycl9yZXN5bmMsCgkJCQkJCSZzeW5jX2Jsb2NrcywgMSk7CgkJZWxzZSAvKiBjb21wbGV0ZWQgc3luYyAqLwoJCQljb25mLT5mdWxsc3luYyA9IDA7CgoJCWJpdG1hcF9jbG9zZV9zeW5jKG1kZGV2LT5iaXRtYXApOwoJCWNsb3NlX3N5bmMoY29uZik7CgkJcmV0dXJuIDA7Cgl9CgoJLyogYmVmb3JlIGJ1aWxkaW5nIGEgcmVxdWVzdCwgY2hlY2sgaWYgd2UgY2FuIHNraXAgdGhlc2UgYmxvY2tzLi4KCSAqIFRoaXMgY2FsbCB0aGUgYml0bWFwX3N0YXJ0X3N5bmMgZG9lc24ndCBhY3R1YWxseSByZWNvcmQgYW55dGhpbmcKCSAqLwoJaWYgKCFiaXRtYXBfc3RhcnRfc3luYyhtZGRldi0+Yml0bWFwLCBzZWN0b3JfbnIsICZzeW5jX2Jsb2NrcywgMSkgJiYKCSAgICAhY29uZi0+ZnVsbHN5bmMgJiYgIXRlc3RfYml0KE1EX1JFQ09WRVJZX1JFUVVFU1RFRCwgJm1kZGV2LT5yZWNvdmVyeSkpIHsKCQkvKiBXZSBjYW4gc2tpcCB0aGlzIGJsb2NrLCBhbmQgcHJvYmFibHkgc2V2ZXJhbCBtb3JlICovCgkJKnNraXBwZWQgPSAxOwoJCXJldHVybiBzeW5jX2Jsb2NrczsKCX0KCS8qCgkgKiBJZiB0aGVyZSBpcyBub24tcmVzeW5jIGFjdGl2aXR5IHdhaXRpbmcgZm9yIGEgdHVybiwKCSAqIGFuZCByZXN5bmMgaXMgZ29pbmcgZmFzdCBlbm91Z2gsCgkgKiB0aGVuIGxldCBpdCB0aG91Z2ggYmVmb3JlIHN0YXJ0aW5nIG9uIHRoaXMgbmV3IHN5bmMgcmVxdWVzdC4KCSAqLwoJaWYgKCFnb19mYXN0ZXIgJiYgY29uZi0+bnJfd2FpdGluZykKCQltc2xlZXBfaW50ZXJydXB0aWJsZSgxMDAwKTsKCglyYWlzZV9iYXJyaWVyKGNvbmYpOwoKCWNvbmYtPm5leHRfcmVzeW5jID0gc2VjdG9yX25yOwoKCXIxX2JpbyA9IG1lbXBvb2xfYWxsb2MoY29uZi0+cjFidWZfcG9vbCwgR0ZQX05PSU8pOwoJcmN1X3JlYWRfbG9jaygpOwoJLyoKCSAqIElmIHdlIGdldCBhIGNvcnJlY3RhYmx5IHJlYWQgZXJyb3IgZHVyaW5nIHJlc3luYyBvciByZWNvdmVyeSwKCSAqIHdlIG1pZ2h0IHdhbnQgdG8gcmVhZCBmcm9tIGEgZGlmZmVyZW50IGRldmljZS4gIFNvIHdlCgkgKiBmbGFnIGFsbCBkcml2ZXMgdGhhdCBjb3VsZCBjb25jZWl2YWJseSBiZSByZWFkIGZyb20gZm9yIFJFQUQsCgkgKiBhbmQgYW55IG90aGVycyAod2hpY2ggd2lsbCBiZSBub24tSW5fc3luYyBkZXZpY2VzKSBmb3IgV1JJVEUuCgkgKiBJZiBhIHJlYWQgZmFpbHMsIHdlIHRyeSByZWFkaW5nIGZyb20gc29tZXRoaW5nIGVsc2UgZm9yIHdoaWNoIFJFQUQKCSAqIGlzIE9LLgoJICovCgoJcjFfYmlvLT5tZGRldiA9IG1kZGV2OwoJcjFfYmlvLT5zZWN0b3IgPSBzZWN0b3JfbnI7CglyMV9iaW8tPnN0YXRlID0gMDsKCXNldF9iaXQoUjFCSU9fSXNTeW5jLCAmcjFfYmlvLT5zdGF0ZSk7CgoJZm9yIChpPTA7IGkgPCBjb25mLT5yYWlkX2Rpc2tzOyBpKyspIHsKCQltZGtfcmRldl90ICpyZGV2OwoJCWJpbyA9IHIxX2Jpby0+Ymlvc1tpXTsKCgkJLyogdGFrZSBmcm9tIGJpb19pbml0ICovCgkJYmlvLT5iaV9uZXh0ID0gTlVMTDsKCQliaW8tPmJpX2ZsYWdzIHw9IDEgPDwgQklPX1VQVE9EQVRFOwoJCWJpby0+YmlfcncgPSAwOwoJCWJpby0+YmlfdmNudCA9IDA7CgkJYmlvLT5iaV9pZHggPSAwOwoJCWJpby0+YmlfcGh5c19zZWdtZW50cyA9IDA7CgkJYmlvLT5iaV9od19zZWdtZW50cyA9IDA7CgkJYmlvLT5iaV9zaXplID0gMDsKCQliaW8tPmJpX2VuZF9pbyA9IE5VTEw7CgkJYmlvLT5iaV9wcml2YXRlID0gTlVMTDsKCgkJcmRldiA9IHJjdV9kZXJlZmVyZW5jZShjb25mLT5taXJyb3JzW2ldLnJkZXYpOwoJCWlmIChyZGV2ID09IE5VTEwgfHwKCQkJICAgdGVzdF9iaXQoRmF1bHR5LCAmcmRldi0+ZmxhZ3MpKSB7CgkJCXN0aWxsX2RlZ3JhZGVkID0gMTsKCQkJY29udGludWU7CgkJfSBlbHNlIGlmICghdGVzdF9iaXQoSW5fc3luYywgJnJkZXYtPmZsYWdzKSkgewoJCQliaW8tPmJpX3J3ID0gV1JJVEU7CgkJCWJpby0+YmlfZW5kX2lvID0gZW5kX3N5bmNfd3JpdGU7CgkJCXdyaXRlX3RhcmdldHMgKys7CgkJfSBlbHNlIHsKCQkJLyogbWF5IG5lZWQgdG8gcmVhZCBmcm9tIGhlcmUgKi8KCQkJYmlvLT5iaV9ydyA9IFJFQUQ7CgkJCWJpby0+YmlfZW5kX2lvID0gZW5kX3N5bmNfcmVhZDsKCQkJaWYgKHRlc3RfYml0KFdyaXRlTW9zdGx5LCAmcmRldi0+ZmxhZ3MpKSB7CgkJCQlpZiAod29ubHkgPCAwKQoJCQkJCXdvbmx5ID0gaTsKCQkJfSBlbHNlIHsKCQkJCWlmIChkaXNrIDwgMCkKCQkJCQlkaXNrID0gaTsKCQkJfQoJCQlyZWFkX3RhcmdldHMrKzsKCQl9CgkJYXRvbWljX2luYygmcmRldi0+bnJfcGVuZGluZyk7CgkJYmlvLT5iaV9zZWN0b3IgPSBzZWN0b3JfbnIgKyByZGV2LT5kYXRhX29mZnNldDsKCQliaW8tPmJpX2JkZXYgPSByZGV2LT5iZGV2OwoJCWJpby0+YmlfcHJpdmF0ZSA9IHIxX2JpbzsKCX0KCXJjdV9yZWFkX3VubG9jaygpOwoJaWYgKGRpc2sgPCAwKQoJCWRpc2sgPSB3b25seTsKCXIxX2Jpby0+cmVhZF9kaXNrID0gZGlzazsKCglpZiAodGVzdF9iaXQoTURfUkVDT1ZFUllfU1lOQywgJm1kZGV2LT5yZWNvdmVyeSkgJiYgcmVhZF90YXJnZXRzID4gMCkKCQkvKiBleHRyYSByZWFkIHRhcmdldHMgYXJlIGFsc28gd3JpdGUgdGFyZ2V0cyAqLwoJCXdyaXRlX3RhcmdldHMgKz0gcmVhZF90YXJnZXRzLTE7CgoJaWYgKHdyaXRlX3RhcmdldHMgPT0gMCB8fCByZWFkX3RhcmdldHMgPT0gMCkgewoJCS8qIFRoZXJlIGlzIG5vd2hlcmUgdG8gd3JpdGUsIHNvIGFsbCBub24tc3luYwoJCSAqIGRyaXZlcyBtdXN0IGJlIGZhaWxlZCAtIHNvIHdlIGFyZSBmaW5pc2hlZAoJCSAqLwoJCXNlY3Rvcl90IHJ2ID0gbWF4X3NlY3RvciAtIHNlY3Rvcl9ucjsKCQkqc2tpcHBlZCA9IDE7CgkJcHV0X2J1ZihyMV9iaW8pOwoJCXJldHVybiBydjsKCX0KCglucl9zZWN0b3JzID0gMDsKCXN5bmNfYmxvY2tzID0gMDsKCWRvIHsKCQlzdHJ1Y3QgcGFnZSAqcGFnZTsKCQlpbnQgbGVuID0gUEFHRV9TSVpFOwoJCWlmIChzZWN0b3JfbnIgKyAobGVuPj45KSA+IG1heF9zZWN0b3IpCgkJCWxlbiA9IChtYXhfc2VjdG9yIC0gc2VjdG9yX25yKSA8PCA5OwoJCWlmIChsZW4gPT0gMCkKCQkJYnJlYWs7CgkJaWYgKHN5bmNfYmxvY2tzID09IDApIHsKCQkJaWYgKCFiaXRtYXBfc3RhcnRfc3luYyhtZGRldi0+Yml0bWFwLCBzZWN0b3JfbnIsCgkJCQkJICAgICAgICZzeW5jX2Jsb2Nrcywgc3RpbGxfZGVncmFkZWQpICYmCgkJCSAgICAhY29uZi0+ZnVsbHN5bmMgJiYKCQkJICAgICF0ZXN0X2JpdChNRF9SRUNPVkVSWV9SRVFVRVNURUQsICZtZGRldi0+cmVjb3ZlcnkpKQoJCQkJYnJlYWs7CgkJCWlmIChzeW5jX2Jsb2NrcyA8IChQQUdFX1NJWkU+PjkpKQoJCQkJQlVHKCk7CgkJCWlmIChsZW4gPiAoc3luY19ibG9ja3M8PDkpKQoJCQkJbGVuID0gc3luY19ibG9ja3M8PDk7CgkJfQoKCQlmb3IgKGk9MCA7IGkgPCBjb25mLT5yYWlkX2Rpc2tzOyBpKyspIHsKCQkJYmlvID0gcjFfYmlvLT5iaW9zW2ldOwoJCQlpZiAoYmlvLT5iaV9lbmRfaW8pIHsKCQkJCXBhZ2UgPSBiaW8tPmJpX2lvX3ZlY1tiaW8tPmJpX3ZjbnRdLmJ2X3BhZ2U7CgkJCQlpZiAoYmlvX2FkZF9wYWdlKGJpbywgcGFnZSwgbGVuLCAwKSA9PSAwKSB7CgkJCQkJLyogc3RvcCBoZXJlICovCgkJCQkJYmlvLT5iaV9pb192ZWNbYmlvLT5iaV92Y250XS5idl9wYWdlID0gcGFnZTsKCQkJCQl3aGlsZSAoaSA+IDApIHsKCQkJCQkJaS0tOwoJCQkJCQliaW8gPSByMV9iaW8tPmJpb3NbaV07CgkJCQkJCWlmIChiaW8tPmJpX2VuZF9pbz09TlVMTCkKCQkJCQkJCWNvbnRpbnVlOwoJCQkJCQkvKiByZW1vdmUgbGFzdCBwYWdlIGZyb20gdGhpcyBiaW8gKi8KCQkJCQkJYmlvLT5iaV92Y250LS07CgkJCQkJCWJpby0+Ymlfc2l6ZSAtPSBsZW47CgkJCQkJCWJpby0+YmlfZmxhZ3MgJj0gfigxPDwgQklPX1NFR19WQUxJRCk7CgkJCQkJfQoJCQkJCWdvdG8gYmlvX2Z1bGw7CgkJCQl9CgkJCX0KCQl9CgkJbnJfc2VjdG9ycyArPSBsZW4+Pjk7CgkJc2VjdG9yX25yICs9IGxlbj4+OTsKCQlzeW5jX2Jsb2NrcyAtPSAobGVuPj45KTsKCX0gd2hpbGUgKHIxX2Jpby0+Ymlvc1tkaXNrXS0+YmlfdmNudCA8IFJFU1lOQ19QQUdFUyk7CiBiaW9fZnVsbDoKCXIxX2Jpby0+c2VjdG9ycyA9IG5yX3NlY3RvcnM7CgoJLyogRm9yIGEgdXNlci1yZXF1ZXN0ZWQgc3luYywgd2UgcmVhZCBhbGwgcmVhZGFibGUgZGV2aWNlcyBhbmQgZG8gYQoJICogY29tcGFyZQoJICovCglpZiAodGVzdF9iaXQoTURfUkVDT1ZFUllfUkVRVUVTVEVELCAmbWRkZXYtPnJlY292ZXJ5KSkgewoJCWF0b21pY19zZXQoJnIxX2Jpby0+cmVtYWluaW5nLCByZWFkX3RhcmdldHMpOwoJCWZvciAoaT0wOyBpPGNvbmYtPnJhaWRfZGlza3M7IGkrKykgewoJCQliaW8gPSByMV9iaW8tPmJpb3NbaV07CgkJCWlmIChiaW8tPmJpX2VuZF9pbyA9PSBlbmRfc3luY19yZWFkKSB7CgkJCQltZF9zeW5jX2FjY3QoY29uZi0+bWlycm9yc1tpXS5yZGV2LT5iZGV2LCBucl9zZWN0b3JzKTsKCQkJCWdlbmVyaWNfbWFrZV9yZXF1ZXN0KGJpbyk7CgkJCX0KCQl9Cgl9IGVsc2UgewoJCWF0b21pY19zZXQoJnIxX2Jpby0+cmVtYWluaW5nLCAxKTsKCQliaW8gPSByMV9iaW8tPmJpb3NbcjFfYmlvLT5yZWFkX2Rpc2tdOwoJCW1kX3N5bmNfYWNjdChjb25mLT5taXJyb3JzW3IxX2Jpby0+cmVhZF9kaXNrXS5yZGV2LT5iZGV2LAoJCQkgICAgIG5yX3NlY3RvcnMpOwoJCWdlbmVyaWNfbWFrZV9yZXF1ZXN0KGJpbyk7CgoJfQoKCXJldHVybiBucl9zZWN0b3JzOwp9CgpzdGF0aWMgaW50IHJ1bihtZGRldl90ICptZGRldikKewoJY29uZl90ICpjb25mOwoJaW50IGksIGosIGRpc2tfaWR4OwoJbWlycm9yX2luZm9fdCAqZGlzazsKCW1ka19yZGV2X3QgKnJkZXY7CglzdHJ1Y3QgbGlzdF9oZWFkICp0bXA7CgoJaWYgKG1kZGV2LT5sZXZlbCAhPSAxKSB7CgkJcHJpbnRrKCJyYWlkMTogJXM6IHJhaWQgbGV2ZWwgbm90IHNldCB0byBtaXJyb3JpbmcgKCVkKVxuIiwKCQkgICAgICAgbWRuYW1lKG1kZGV2KSwgbWRkZXYtPmxldmVsKTsKCQlnb3RvIG91dDsKCX0KCS8qCgkgKiBjb3B5IHRoZSBhbHJlYWR5IHZlcmlmaWVkIGRldmljZXMgaW50byBvdXIgcHJpdmF0ZSBSQUlEMQoJICogYm9va2tlZXBpbmcgYXJlYS4gW3doYXRldmVyIHdlIGFsbG9jYXRlIGluIHJ1bigpLAoJICogc2hvdWxkIGJlIGZyZWVkIGluIHN0b3AoKV0KCSAqLwoJY29uZiA9IGttYWxsb2Moc2l6ZW9mKGNvbmZfdCksIEdGUF9LRVJORUwpOwoJbWRkZXYtPnByaXZhdGUgPSBjb25mOwoJaWYgKCFjb25mKQoJCWdvdG8gb3V0X25vX21lbTsKCgltZW1zZXQoY29uZiwgMCwgc2l6ZW9mKCpjb25mKSk7Cgljb25mLT5taXJyb3JzID0ga21hbGxvYyhzaXplb2Yoc3RydWN0IG1pcnJvcl9pbmZvKSptZGRldi0+cmFpZF9kaXNrcywgCgkJCQkgR0ZQX0tFUk5FTCk7CglpZiAoIWNvbmYtPm1pcnJvcnMpCgkJZ290byBvdXRfbm9fbWVtOwoKCW1lbXNldChjb25mLT5taXJyb3JzLCAwLCBzaXplb2Yoc3RydWN0IG1pcnJvcl9pbmZvKSptZGRldi0+cmFpZF9kaXNrcyk7CgoJY29uZi0+dG1wcGFnZSA9IGFsbG9jX3BhZ2UoR0ZQX0tFUk5FTCk7CglpZiAoIWNvbmYtPnRtcHBhZ2UpCgkJZ290byBvdXRfbm9fbWVtOwoKCWNvbmYtPnBvb2xpbmZvID0ga21hbGxvYyhzaXplb2YoKmNvbmYtPnBvb2xpbmZvKSwgR0ZQX0tFUk5FTCk7CglpZiAoIWNvbmYtPnBvb2xpbmZvKQoJCWdvdG8gb3V0X25vX21lbTsKCWNvbmYtPnBvb2xpbmZvLT5tZGRldiA9IG1kZGV2OwoJY29uZi0+cG9vbGluZm8tPnJhaWRfZGlza3MgPSBtZGRldi0+cmFpZF9kaXNrczsKCWNvbmYtPnIxYmlvX3Bvb2wgPSBtZW1wb29sX2NyZWF0ZShOUl9SQUlEMV9CSU9TLCByMWJpb19wb29sX2FsbG9jLAoJCQkJCSAgcjFiaW9fcG9vbF9mcmVlLAoJCQkJCSAgY29uZi0+cG9vbGluZm8pOwoJaWYgKCFjb25mLT5yMWJpb19wb29sKQoJCWdvdG8gb3V0X25vX21lbTsKCglJVEVSQVRFX1JERVYobWRkZXYsIHJkZXYsIHRtcCkgewoJCWRpc2tfaWR4ID0gcmRldi0+cmFpZF9kaXNrOwoJCWlmIChkaXNrX2lkeCA+PSBtZGRldi0+cmFpZF9kaXNrcwoJCSAgICB8fCBkaXNrX2lkeCA8IDApCgkJCWNvbnRpbnVlOwoJCWRpc2sgPSBjb25mLT5taXJyb3JzICsgZGlza19pZHg7CgoJCWRpc2stPnJkZXYgPSByZGV2OwoKCQlibGtfcXVldWVfc3RhY2tfbGltaXRzKG1kZGV2LT5xdWV1ZSwKCQkJCSAgICAgICByZGV2LT5iZGV2LT5iZF9kaXNrLT5xdWV1ZSk7CgkJLyogYXMgd2UgZG9uJ3QgaG9ub3VyIG1lcmdlX2J2ZWNfZm4sIHdlIG11c3QgbmV2ZXIgcmlzawoJCSAqIHZpb2xhdGluZyBpdCwgc28gbGltaXQgLT5tYXhfc2VjdG9yIHRvIG9uZSBQQUdFLCBhcwoJCSAqIGEgb25lIHBhZ2UgcmVxdWVzdCBpcyBuZXZlciBpbiB2aW9sYXRpb24uCgkJICovCgkJaWYgKHJkZXYtPmJkZXYtPmJkX2Rpc2stPnF1ZXVlLT5tZXJnZV9idmVjX2ZuICYmCgkJICAgIG1kZGV2LT5xdWV1ZS0+bWF4X3NlY3RvcnMgPiAoUEFHRV9TSVpFPj45KSkKCQkJYmxrX3F1ZXVlX21heF9zZWN0b3JzKG1kZGV2LT5xdWV1ZSwgUEFHRV9TSVpFPj45KTsKCgkJZGlzay0+aGVhZF9wb3NpdGlvbiA9IDA7CgkJaWYgKCF0ZXN0X2JpdChGYXVsdHksICZyZGV2LT5mbGFncykgJiYgdGVzdF9iaXQoSW5fc3luYywgJnJkZXYtPmZsYWdzKSkKCQkJY29uZi0+d29ya2luZ19kaXNrcysrOwoJfQoJY29uZi0+cmFpZF9kaXNrcyA9IG1kZGV2LT5yYWlkX2Rpc2tzOwoJY29uZi0+bWRkZXYgPSBtZGRldjsKCXNwaW5fbG9ja19pbml0KCZjb25mLT5kZXZpY2VfbG9jayk7CglJTklUX0xJU1RfSEVBRCgmY29uZi0+cmV0cnlfbGlzdCk7CglpZiAoY29uZi0+d29ya2luZ19kaXNrcyA9PSAxKQoJCW1kZGV2LT5yZWNvdmVyeV9jcCA9IE1heFNlY3RvcjsKCglzcGluX2xvY2tfaW5pdCgmY29uZi0+cmVzeW5jX2xvY2spOwoJaW5pdF93YWl0cXVldWVfaGVhZCgmY29uZi0+d2FpdF9iYXJyaWVyKTsKCgliaW9fbGlzdF9pbml0KCZjb25mLT5wZW5kaW5nX2Jpb19saXN0KTsKCWJpb19saXN0X2luaXQoJmNvbmYtPmZsdXNoaW5nX2Jpb19saXN0KTsKCglpZiAoIWNvbmYtPndvcmtpbmdfZGlza3MpIHsKCQlwcmludGsoS0VSTl9FUlIgInJhaWQxOiBubyBvcGVyYXRpb25hbCBtaXJyb3JzIGZvciAlc1xuIiwKCQkJbWRuYW1lKG1kZGV2KSk7CgkJZ290byBvdXRfZnJlZV9jb25mOwoJfQoKCW1kZGV2LT5kZWdyYWRlZCA9IDA7Cglmb3IgKGkgPSAwOyBpIDwgY29uZi0+cmFpZF9kaXNrczsgaSsrKSB7CgoJCWRpc2sgPSBjb25mLT5taXJyb3JzICsgaTsKCgkJaWYgKCFkaXNrLT5yZGV2KSB7CgkJCWRpc2stPmhlYWRfcG9zaXRpb24gPSAwOwoJCQltZGRldi0+ZGVncmFkZWQrKzsKCQl9Cgl9CgoJLyoKCSAqIGZpbmQgdGhlIGZpcnN0IHdvcmtpbmcgb25lIGFuZCB1c2UgaXQgYXMgYSBzdGFydGluZyBwb2ludAoJICogdG8gcmVhZCBiYWxhbmNpbmcuCgkgKi8KCWZvciAoaiA9IDA7IGogPCBjb25mLT5yYWlkX2Rpc2tzICYmCgkJICAgICAoIWNvbmYtPm1pcnJvcnNbal0ucmRldiB8fAoJCSAgICAgICF0ZXN0X2JpdChJbl9zeW5jLCAmY29uZi0+bWlycm9yc1tqXS5yZGV2LT5mbGFncykpIDsgaisrKQoJCS8qIG5vdGhpbmcgKi87Cgljb25mLT5sYXN0X3VzZWQgPSBqOwoKCgltZGRldi0+dGhyZWFkID0gbWRfcmVnaXN0ZXJfdGhyZWFkKHJhaWQxZCwgbWRkZXYsICIlc19yYWlkMSIpOwoJaWYgKCFtZGRldi0+dGhyZWFkKSB7CgkJcHJpbnRrKEtFUk5fRVJSCgkJICAgICAgICJyYWlkMTogY291bGRuJ3QgYWxsb2NhdGUgdGhyZWFkIGZvciAlc1xuIiwKCQkgICAgICAgbWRuYW1lKG1kZGV2KSk7CgkJZ290byBvdXRfZnJlZV9jb25mOwoJfQoKCXByaW50ayhLRVJOX0lORk8gCgkJInJhaWQxOiByYWlkIHNldCAlcyBhY3RpdmUgd2l0aCAlZCBvdXQgb2YgJWQgbWlycm9yc1xuIiwKCQltZG5hbWUobWRkZXYpLCBtZGRldi0+cmFpZF9kaXNrcyAtIG1kZGV2LT5kZWdyYWRlZCwgCgkJbWRkZXYtPnJhaWRfZGlza3MpOwoJLyoKCSAqIE9rLCBldmVyeXRoaW5nIGlzIGp1c3QgZmluZSBub3cKCSAqLwoJbWRkZXYtPmFycmF5X3NpemUgPSBtZGRldi0+c2l6ZTsKCgltZGRldi0+cXVldWUtPnVucGx1Z19mbiA9IHJhaWQxX3VucGx1ZzsKCW1kZGV2LT5xdWV1ZS0+aXNzdWVfZmx1c2hfZm4gPSByYWlkMV9pc3N1ZV9mbHVzaDsKCglyZXR1cm4gMDsKCm91dF9ub19tZW06CglwcmludGsoS0VSTl9FUlIgInJhaWQxOiBjb3VsZG4ndCBhbGxvY2F0ZSBtZW1vcnkgZm9yICVzXG4iLAoJICAgICAgIG1kbmFtZShtZGRldikpOwoKb3V0X2ZyZWVfY29uZjoKCWlmIChjb25mKSB7CgkJaWYgKGNvbmYtPnIxYmlvX3Bvb2wpCgkJCW1lbXBvb2xfZGVzdHJveShjb25mLT5yMWJpb19wb29sKTsKCQlrZnJlZShjb25mLT5taXJyb3JzKTsKCQlfX2ZyZWVfcGFnZShjb25mLT50bXBwYWdlKTsKCQlrZnJlZShjb25mLT5wb29saW5mbyk7CgkJa2ZyZWUoY29uZik7CgkJbWRkZXYtPnByaXZhdGUgPSBOVUxMOwoJfQpvdXQ6CglyZXR1cm4gLUVJTzsKfQoKc3RhdGljIGludCBzdG9wKG1kZGV2X3QgKm1kZGV2KQp7Cgljb25mX3QgKmNvbmYgPSBtZGRldl90b19jb25mKG1kZGV2KTsKCXN0cnVjdCBiaXRtYXAgKmJpdG1hcCA9IG1kZGV2LT5iaXRtYXA7CglpbnQgYmVoaW5kX3dhaXQgPSAwOwoKCS8qIHdhaXQgZm9yIGJlaGluZCB3cml0ZXMgdG8gY29tcGxldGUgKi8KCXdoaWxlIChiaXRtYXAgJiYgYXRvbWljX3JlYWQoJmJpdG1hcC0+YmVoaW5kX3dyaXRlcykgPiAwKSB7CgkJYmVoaW5kX3dhaXQrKzsKCQlwcmludGsoS0VSTl9JTkZPICJyYWlkMTogYmVoaW5kIHdyaXRlcyBpbiBwcm9ncmVzcyBvbiBkZXZpY2UgJXMsIHdhaXRpbmcgdG8gc3RvcCAoJWQpXG4iLCBtZG5hbWUobWRkZXYpLCBiZWhpbmRfd2FpdCk7CgkJc2V0X2N1cnJlbnRfc3RhdGUoVEFTS19VTklOVEVSUlVQVElCTEUpOwoJCXNjaGVkdWxlX3RpbWVvdXQoSFopOyAvKiB3YWl0IGEgc2Vjb25kICovCgkJLyogbmVlZCB0byBraWNrIHNvbWV0aGluZyBoZXJlIHRvIG1ha2Ugc3VyZSBJL08gZ29lcz8gKi8KCX0KCgltZF91bnJlZ2lzdGVyX3RocmVhZChtZGRldi0+dGhyZWFkKTsKCW1kZGV2LT50aHJlYWQgPSBOVUxMOwoJYmxrX3N5bmNfcXVldWUobWRkZXYtPnF1ZXVlKTsgLyogdGhlIHVucGx1ZyBmbiByZWZlcmVuY2VzICdjb25mJyovCglpZiAoY29uZi0+cjFiaW9fcG9vbCkKCQltZW1wb29sX2Rlc3Ryb3koY29uZi0+cjFiaW9fcG9vbCk7CglrZnJlZShjb25mLT5taXJyb3JzKTsKCWtmcmVlKGNvbmYtPnBvb2xpbmZvKTsKCWtmcmVlKGNvbmYpOwoJbWRkZXYtPnByaXZhdGUgPSBOVUxMOwoJcmV0dXJuIDA7Cn0KCnN0YXRpYyBpbnQgcmFpZDFfcmVzaXplKG1kZGV2X3QgKm1kZGV2LCBzZWN0b3JfdCBzZWN0b3JzKQp7CgkvKiBubyByZXN5bmMgaXMgaGFwcGVuaW5nLCBhbmQgdGhlcmUgaXMgZW5vdWdoIHNwYWNlCgkgKiBvbiBhbGwgZGV2aWNlcywgc28gd2UgY2FuIHJlc2l6ZS4KCSAqIFdlIG5lZWQgdG8gbWFrZSBzdXJlIHJlc3luYyBjb3ZlcnMgYW55IG5ldyBzcGFjZS4KCSAqIElmIHRoZSBhcnJheSBpcyBzaHJpbmtpbmcgd2Ugc2hvdWxkIHBvc3NpYmx5IHdhaXQgdW50aWwKCSAqIGFueSBpbyBpbiB0aGUgcmVtb3ZlZCBzcGFjZSBjb21wbGV0ZXMsIGJ1dCBpdCBoYXJkbHkgc2VlbXMKCSAqIHdvcnRoIGl0LgoJICovCgltZGRldi0+YXJyYXlfc2l6ZSA9IHNlY3RvcnM+PjE7CglzZXRfY2FwYWNpdHkobWRkZXYtPmdlbmRpc2ssIG1kZGV2LT5hcnJheV9zaXplIDw8IDEpOwoJbWRkZXYtPmNoYW5nZWQgPSAxOwoJaWYgKG1kZGV2LT5hcnJheV9zaXplID4gbWRkZXYtPnNpemUgJiYgbWRkZXYtPnJlY292ZXJ5X2NwID09IE1heFNlY3RvcikgewoJCW1kZGV2LT5yZWNvdmVyeV9jcCA9IG1kZGV2LT5zaXplIDw8IDE7CgkJc2V0X2JpdChNRF9SRUNPVkVSWV9ORUVERUQsICZtZGRldi0+cmVjb3ZlcnkpOwoJfQoJbWRkZXYtPnNpemUgPSBtZGRldi0+YXJyYXlfc2l6ZTsKCW1kZGV2LT5yZXN5bmNfbWF4X3NlY3RvcnMgPSBzZWN0b3JzOwoJcmV0dXJuIDA7Cn0KCnN0YXRpYyBpbnQgcmFpZDFfcmVzaGFwZShtZGRldl90ICptZGRldiwgaW50IHJhaWRfZGlza3MpCnsKCS8qIFdlIG5lZWQgdG86CgkgKiAxLyByZXNpemUgdGhlIHIxYmlvX3Bvb2wKCSAqIDIvIHJlc2l6ZSBjb25mLT5taXJyb3JzCgkgKgoJICogV2UgYWxsb2NhdGUgYSBuZXcgcjFiaW9fcG9vbCBpZiB3ZSBjYW4uCgkgKiBUaGVuIHJhaXNlIGEgZGV2aWNlIGJhcnJpZXIgYW5kIHdhaXQgdW50aWwgYWxsIElPIHN0b3BzLgoJICogVGhlbiByZXNpemUgY29uZi0+bWlycm9ycyBhbmQgc3dhcCBpbiB0aGUgbmV3IHIxYmlvIHBvb2wuCgkgKgoJICogQXQgdGhlIHNhbWUgdGltZSwgd2UgInBhY2siIHRoZSBkZXZpY2VzIHNvIHRoYXQgYWxsIHRoZSBtaXNzaW5nCgkgKiBkZXZpY2VzIGhhdmUgdGhlIGhpZ2hlciByYWlkX2Rpc2sgbnVtYmVycy4KCSAqLwoJbWVtcG9vbF90ICpuZXdwb29sLCAqb2xkcG9vbDsKCXN0cnVjdCBwb29sX2luZm8gKm5ld3Bvb2xpbmZvOwoJbWlycm9yX2luZm9fdCAqbmV3bWlycm9yczsKCWNvbmZfdCAqY29uZiA9IG1kZGV2X3RvX2NvbmYobWRkZXYpOwoJaW50IGNudDsKCglpbnQgZCwgZDI7CgoJaWYgKHJhaWRfZGlza3MgPCBjb25mLT5yYWlkX2Rpc2tzKSB7CgkJY250PTA7CgkJZm9yIChkPSAwOyBkIDwgY29uZi0+cmFpZF9kaXNrczsgZCsrKQoJCQlpZiAoY29uZi0+bWlycm9yc1tkXS5yZGV2KQoJCQkJY250Kys7CgkJaWYgKGNudCA+IHJhaWRfZGlza3MpCgkJCXJldHVybiAtRUJVU1k7Cgl9CgoJbmV3cG9vbGluZm8gPSBrbWFsbG9jKHNpemVvZigqbmV3cG9vbGluZm8pLCBHRlBfS0VSTkVMKTsKCWlmICghbmV3cG9vbGluZm8pCgkJcmV0dXJuIC1FTk9NRU07CgluZXdwb29saW5mby0+bWRkZXYgPSBtZGRldjsKCW5ld3Bvb2xpbmZvLT5yYWlkX2Rpc2tzID0gcmFpZF9kaXNrczsKCgluZXdwb29sID0gbWVtcG9vbF9jcmVhdGUoTlJfUkFJRDFfQklPUywgcjFiaW9fcG9vbF9hbGxvYywKCQkJCSByMWJpb19wb29sX2ZyZWUsIG5ld3Bvb2xpbmZvKTsKCWlmICghbmV3cG9vbCkgewoJCWtmcmVlKG5ld3Bvb2xpbmZvKTsKCQlyZXR1cm4gLUVOT01FTTsKCX0KCW5ld21pcnJvcnMgPSBrbWFsbG9jKHNpemVvZihzdHJ1Y3QgbWlycm9yX2luZm8pICogcmFpZF9kaXNrcywgR0ZQX0tFUk5FTCk7CglpZiAoIW5ld21pcnJvcnMpIHsKCQlrZnJlZShuZXdwb29saW5mbyk7CgkJbWVtcG9vbF9kZXN0cm95KG5ld3Bvb2wpOwoJCXJldHVybiAtRU5PTUVNOwoJfQoJbWVtc2V0KG5ld21pcnJvcnMsIDAsIHNpemVvZihzdHJ1Y3QgbWlycm9yX2luZm8pKnJhaWRfZGlza3MpOwoKCXJhaXNlX2JhcnJpZXIoY29uZik7CgoJLyogb2ssIGV2ZXJ5dGhpbmcgaXMgc3RvcHBlZCAqLwoJb2xkcG9vbCA9IGNvbmYtPnIxYmlvX3Bvb2w7Cgljb25mLT5yMWJpb19wb29sID0gbmV3cG9vbDsKCglmb3IgKGQ9ZDI9MDsgZCA8IGNvbmYtPnJhaWRfZGlza3M7IGQrKykKCQlpZiAoY29uZi0+bWlycm9yc1tkXS5yZGV2KSB7CgkJCWNvbmYtPm1pcnJvcnNbZF0ucmRldi0+cmFpZF9kaXNrID0gZDI7CgkJCW5ld21pcnJvcnNbZDIrK10ucmRldiA9IGNvbmYtPm1pcnJvcnNbZF0ucmRldjsKCQl9CglrZnJlZShjb25mLT5taXJyb3JzKTsKCWNvbmYtPm1pcnJvcnMgPSBuZXdtaXJyb3JzOwoJa2ZyZWUoY29uZi0+cG9vbGluZm8pOwoJY29uZi0+cG9vbGluZm8gPSBuZXdwb29saW5mbzsKCgltZGRldi0+ZGVncmFkZWQgKz0gKHJhaWRfZGlza3MgLSBjb25mLT5yYWlkX2Rpc2tzKTsKCWNvbmYtPnJhaWRfZGlza3MgPSBtZGRldi0+cmFpZF9kaXNrcyA9IHJhaWRfZGlza3M7CgoJY29uZi0+bGFzdF91c2VkID0gMDsgLyoganVzdCBtYWtlIHN1cmUgaXQgaXMgaW4tcmFuZ2UgKi8KCWxvd2VyX2JhcnJpZXIoY29uZik7CgoJc2V0X2JpdChNRF9SRUNPVkVSWV9ORUVERUQsICZtZGRldi0+cmVjb3ZlcnkpOwoJbWRfd2FrZXVwX3RocmVhZChtZGRldi0+dGhyZWFkKTsKCgltZW1wb29sX2Rlc3Ryb3kob2xkcG9vbCk7CglyZXR1cm4gMDsKfQoKc3RhdGljIHZvaWQgcmFpZDFfcXVpZXNjZShtZGRldl90ICptZGRldiwgaW50IHN0YXRlKQp7Cgljb25mX3QgKmNvbmYgPSBtZGRldl90b19jb25mKG1kZGV2KTsKCglzd2l0Y2goc3RhdGUpIHsKCWNhc2UgMToKCQlyYWlzZV9iYXJyaWVyKGNvbmYpOwoJCWJyZWFrOwoJY2FzZSAwOgoJCWxvd2VyX2JhcnJpZXIoY29uZik7CgkJYnJlYWs7Cgl9Cn0KCgpzdGF0aWMgbWRrX3BlcnNvbmFsaXR5X3QgcmFpZDFfcGVyc29uYWxpdHkgPQp7CgkubmFtZQkJPSAicmFpZDEiLAoJLm93bmVyCQk9IFRISVNfTU9EVUxFLAoJLm1ha2VfcmVxdWVzdAk9IG1ha2VfcmVxdWVzdCwKCS5ydW4JCT0gcnVuLAoJLnN0b3AJCT0gc3RvcCwKCS5zdGF0dXMJCT0gc3RhdHVzLAoJLmVycm9yX2hhbmRsZXIJPSBlcnJvciwKCS5ob3RfYWRkX2Rpc2sJPSByYWlkMV9hZGRfZGlzaywKCS5ob3RfcmVtb3ZlX2Rpc2s9IHJhaWQxX3JlbW92ZV9kaXNrLAoJLnNwYXJlX2FjdGl2ZQk9IHJhaWQxX3NwYXJlX2FjdGl2ZSwKCS5zeW5jX3JlcXVlc3QJPSBzeW5jX3JlcXVlc3QsCgkucmVzaXplCQk9IHJhaWQxX3Jlc2l6ZSwKCS5yZXNoYXBlCT0gcmFpZDFfcmVzaGFwZSwKCS5xdWllc2NlCT0gcmFpZDFfcXVpZXNjZSwKfTsKCnN0YXRpYyBpbnQgX19pbml0IHJhaWRfaW5pdCh2b2lkKQp7CglyZXR1cm4gcmVnaXN0ZXJfbWRfcGVyc29uYWxpdHkoUkFJRDEsICZyYWlkMV9wZXJzb25hbGl0eSk7Cn0KCnN0YXRpYyB2b2lkIHJhaWRfZXhpdCh2b2lkKQp7Cgl1bnJlZ2lzdGVyX21kX3BlcnNvbmFsaXR5KFJBSUQxKTsKfQoKbW9kdWxlX2luaXQocmFpZF9pbml0KTsKbW9kdWxlX2V4aXQocmFpZF9leGl0KTsKTU9EVUxFX0xJQ0VOU0UoIkdQTCIpOwpNT0RVTEVfQUxJQVMoIm1kLXBlcnNvbmFsaXR5LTMiKTsgLyogUkFJRDEgKi8K