LyoKICogcmFpZDEuYyA6IE11bHRpcGxlIERldmljZXMgZHJpdmVyIGZvciBMaW51eAogKgogKiBDb3B5cmlnaHQgKEMpIDE5OTksIDIwMDAsIDIwMDEgSW5nbyBNb2xuYXIsIFJlZCBIYXQKICoKICogQ29weXJpZ2h0IChDKSAxOTk2LCAxOTk3LCAxOTk4IEluZ28gTW9sbmFyLCBNaWd1ZWwgZGUgSWNhemEsIEdhZGkgT3htYW4KICoKICogUkFJRC0xIG1hbmFnZW1lbnQgZnVuY3Rpb25zLgogKgogKiBCZXR0ZXIgcmVhZC1iYWxhbmNpbmcgY29kZSB3cml0dGVuIGJ5IE1pa2EgS3VvcHBhbGEgPG1pa3VAaWtpLmZpPiwgMjAwMAogKgogKiBGaXhlcyB0byByZWNvbnN0cnVjdGlvbiBieSBKYWtvYiDYc3RlcmdhYXJkIiA8amFrb2JAb3N0ZW5mZWxkLmRrPgogKiBWYXJpb3VzIGZpeGVzIGJ5IE5laWwgQnJvd24gPG5laWxiQGNzZS51bnN3LmVkdS5hdT4KICoKICogQ2hhbmdlcyBieSBQZXRlciBULiBCcmV1ZXIgPHB0YkBpdC51YzNtLmVzPiAzMS8xLzIwMDMgdG8gc3VwcG9ydAogKiBiaXRtYXBwZWQgaW50ZWxsaWdlbmNlIGluIHJlc3luYzoKICoKICogICAgICAtIGJpdG1hcCBtYXJrZWQgZHVyaW5nIG5vcm1hbCBpL28KICogICAgICAtIGJpdG1hcCB1c2VkIHRvIHNraXAgbm9uZGlydHkgYmxvY2tzIGR1cmluZyBzeW5jCiAqCiAqIEFkZGl0aW9ucyB0byBiaXRtYXAgY29kZSwgKEMpIDIwMDMtMjAwNCBQYXVsIENsZW1lbnRzLCBTdGVlbEV5ZSBUZWNobm9sb2d5OgogKiAtIHBlcnNpc3RlbnQgYml0bWFwIGNvZGUKICoKICogVGhpcyBwcm9ncmFtIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkKICogaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkKICogdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyIHZlcnNpb24gMiwgb3IgKGF0IHlvdXIgb3B0aW9uKQogKiBhbnkgbGF0ZXIgdmVyc2lvbi4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogKGZvciBleGFtcGxlIC91c3Ivc3JjL2xpbnV4L0NPUFlJTkcpOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlCiAqIFNvZnR3YXJlIEZvdW5kYXRpb24sIEluYy4sIDY3NSBNYXNzIEF2ZSwgQ2FtYnJpZGdlLCBNQSAwMjEzOSwgVVNBLgogKi8KCiNpbmNsdWRlICJkbS1iaW8tbGlzdC5oIgojaW5jbHVkZSA8bGludXgvcmFpZC9yYWlkMS5oPgojaW5jbHVkZSA8bGludXgvcmFpZC9iaXRtYXAuaD4KCiNkZWZpbmUgREVCVUcgMAojaWYgREVCVUcKI2RlZmluZSBQUklOVEsoeC4uLikgcHJpbnRrKHgpCiNlbHNlCiNkZWZpbmUgUFJJTlRLKHguLi4pCiNlbmRpZgoKLyoKICogTnVtYmVyIG9mIGd1YXJhbnRlZWQgcjFiaW9zIGluIGNhc2Ugb2YgZXh0cmVtZSBWTSBsb2FkOgogKi8KI2RlZmluZQlOUl9SQUlEMV9CSU9TIDI1NgoKc3RhdGljIG1ka19wZXJzb25hbGl0eV90IHJhaWQxX3BlcnNvbmFsaXR5OwoKc3RhdGljIHZvaWQgdW5wbHVnX3NsYXZlcyhtZGRldl90ICptZGRldik7CgoKc3RhdGljIHZvaWQgKiByMWJpb19wb29sX2FsbG9jKHVuc2lnbmVkIGludCBfX25vY2FzdCBnZnBfZmxhZ3MsIHZvaWQgKmRhdGEpCnsKCXN0cnVjdCBwb29sX2luZm8gKnBpID0gZGF0YTsKCXIxYmlvX3QgKnIxX2JpbzsKCWludCBzaXplID0gb2Zmc2V0b2YocjFiaW9fdCwgYmlvc1twaS0+cmFpZF9kaXNrc10pOwoKCS8qIGFsbG9jYXRlIGEgcjFiaW8gd2l0aCByb29tIGZvciByYWlkX2Rpc2tzIGVudHJpZXMgaW4gdGhlIGJpb3MgYXJyYXkgKi8KCXIxX2JpbyA9IGttYWxsb2Moc2l6ZSwgZ2ZwX2ZsYWdzKTsKCWlmIChyMV9iaW8pCgkJbWVtc2V0KHIxX2JpbywgMCwgc2l6ZSk7CgllbHNlCgkJdW5wbHVnX3NsYXZlcyhwaS0+bWRkZXYpOwoKCXJldHVybiByMV9iaW87Cn0KCnN0YXRpYyB2b2lkIHIxYmlvX3Bvb2xfZnJlZSh2b2lkICpyMV9iaW8sIHZvaWQgKmRhdGEpCnsKCWtmcmVlKHIxX2Jpbyk7Cn0KCiNkZWZpbmUgUkVTWU5DX0JMT0NLX1NJWkUgKDY0KjEwMjQpCi8vI2RlZmluZSBSRVNZTkNfQkxPQ0tfU0laRSBQQUdFX1NJWkUKI2RlZmluZSBSRVNZTkNfU0VDVE9SUyAoUkVTWU5DX0JMT0NLX1NJWkUgPj4gOSkKI2RlZmluZSBSRVNZTkNfUEFHRVMgKChSRVNZTkNfQkxPQ0tfU0laRSArIFBBR0VfU0laRS0xKSAvIFBBR0VfU0laRSkKI2RlZmluZSBSRVNZTkNfV0lORE9XICgyMDQ4KjEwMjQpCgpzdGF0aWMgdm9pZCAqIHIxYnVmX3Bvb2xfYWxsb2ModW5zaWduZWQgaW50IF9fbm9jYXN0IGdmcF9mbGFncywgdm9pZCAqZGF0YSkKewoJc3RydWN0IHBvb2xfaW5mbyAqcGkgPSBkYXRhOwoJc3RydWN0IHBhZ2UgKnBhZ2U7CglyMWJpb190ICpyMV9iaW87CglzdHJ1Y3QgYmlvICpiaW87CglpbnQgaSwgajsKCglyMV9iaW8gPSByMWJpb19wb29sX2FsbG9jKGdmcF9mbGFncywgcGkpOwoJaWYgKCFyMV9iaW8pIHsKCQl1bnBsdWdfc2xhdmVzKHBpLT5tZGRldik7CgkJcmV0dXJuIE5VTEw7Cgl9CgoJLyoKCSAqIEFsbG9jYXRlIGJpb3MgOiAxIGZvciByZWFkaW5nLCBuLTEgZm9yIHdyaXRpbmcKCSAqLwoJZm9yIChqID0gcGktPnJhaWRfZGlza3MgOyBqLS0gOyApIHsKCQliaW8gPSBiaW9fYWxsb2MoZ2ZwX2ZsYWdzLCBSRVNZTkNfUEFHRVMpOwoJCWlmICghYmlvKQoJCQlnb3RvIG91dF9mcmVlX2JpbzsKCQlyMV9iaW8tPmJpb3Nbal0gPSBiaW87Cgl9CgkvKgoJICogQWxsb2NhdGUgUkVTWU5DX1BBR0VTIGRhdGEgcGFnZXMgYW5kIGF0dGFjaCB0aGVtIHRvCgkgKiB0aGUgZmlyc3QgYmlvOwoJICovCgliaW8gPSByMV9iaW8tPmJpb3NbMF07Cglmb3IgKGkgPSAwOyBpIDwgUkVTWU5DX1BBR0VTOyBpKyspIHsKCQlwYWdlID0gYWxsb2NfcGFnZShnZnBfZmxhZ3MpOwoJCWlmICh1bmxpa2VseSghcGFnZSkpCgkJCWdvdG8gb3V0X2ZyZWVfcGFnZXM7CgoJCWJpby0+YmlfaW9fdmVjW2ldLmJ2X3BhZ2UgPSBwYWdlOwoJfQoKCXIxX2Jpby0+bWFzdGVyX2JpbyA9IE5VTEw7CgoJcmV0dXJuIHIxX2JpbzsKCm91dF9mcmVlX3BhZ2VzOgoJZm9yICggOyBpID4gMCA7IGktLSkKCQlfX2ZyZWVfcGFnZShiaW8tPmJpX2lvX3ZlY1tpLTFdLmJ2X3BhZ2UpOwpvdXRfZnJlZV9iaW86Cgl3aGlsZSAoICsraiA8IHBpLT5yYWlkX2Rpc2tzICkKCQliaW9fcHV0KHIxX2Jpby0+Ymlvc1tqXSk7CglyMWJpb19wb29sX2ZyZWUocjFfYmlvLCBkYXRhKTsKCXJldHVybiBOVUxMOwp9CgpzdGF0aWMgdm9pZCByMWJ1Zl9wb29sX2ZyZWUodm9pZCAqX19yMV9iaW8sIHZvaWQgKmRhdGEpCnsKCXN0cnVjdCBwb29sX2luZm8gKnBpID0gZGF0YTsKCWludCBpOwoJcjFiaW9fdCAqcjFiaW8gPSBfX3IxX2JpbzsKCXN0cnVjdCBiaW8gKmJpbyA9IHIxYmlvLT5iaW9zWzBdOwoKCWZvciAoaSA9IDA7IGkgPCBSRVNZTkNfUEFHRVM7IGkrKykgewoJCV9fZnJlZV9wYWdlKGJpby0+YmlfaW9fdmVjW2ldLmJ2X3BhZ2UpOwoJCWJpby0+YmlfaW9fdmVjW2ldLmJ2X3BhZ2UgPSBOVUxMOwoJfQoJZm9yIChpPTAgOyBpIDwgcGktPnJhaWRfZGlza3M7IGkrKykKCQliaW9fcHV0KHIxYmlvLT5iaW9zW2ldKTsKCglyMWJpb19wb29sX2ZyZWUocjFiaW8sIGRhdGEpOwp9CgpzdGF0aWMgdm9pZCBwdXRfYWxsX2Jpb3MoY29uZl90ICpjb25mLCByMWJpb190ICpyMV9iaW8pCnsKCWludCBpOwoKCWZvciAoaSA9IDA7IGkgPCBjb25mLT5yYWlkX2Rpc2tzOyBpKyspIHsKCQlzdHJ1Y3QgYmlvICoqYmlvID0gcjFfYmlvLT5iaW9zICsgaTsKCQlpZiAoKmJpbykKCQkJYmlvX3B1dCgqYmlvKTsKCQkqYmlvID0gTlVMTDsKCX0KfQoKc3RhdGljIGlubGluZSB2b2lkIGZyZWVfcjFiaW8ocjFiaW9fdCAqcjFfYmlvKQp7Cgl1bnNpZ25lZCBsb25nIGZsYWdzOwoKCWNvbmZfdCAqY29uZiA9IG1kZGV2X3RvX2NvbmYocjFfYmlvLT5tZGRldik7CgoJLyoKCSAqIFdha2UgdXAgYW55IHBvc3NpYmxlIHJlc3luYyB0aHJlYWQgdGhhdCB3YWl0cyBmb3IgdGhlIGRldmljZQoJICogdG8gZ28gaWRsZS4KCSAqLwoJc3Bpbl9sb2NrX2lycXNhdmUoJmNvbmYtPnJlc3luY19sb2NrLCBmbGFncyk7CglpZiAoIS0tY29uZi0+bnJfcGVuZGluZykgewoJCXdha2VfdXAoJmNvbmYtPndhaXRfaWRsZSk7CgkJd2FrZV91cCgmY29uZi0+d2FpdF9yZXN1bWUpOwoJfQoJc3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmY29uZi0+cmVzeW5jX2xvY2ssIGZsYWdzKTsKCglwdXRfYWxsX2Jpb3MoY29uZiwgcjFfYmlvKTsKCW1lbXBvb2xfZnJlZShyMV9iaW8sIGNvbmYtPnIxYmlvX3Bvb2wpOwp9CgpzdGF0aWMgaW5saW5lIHZvaWQgcHV0X2J1ZihyMWJpb190ICpyMV9iaW8pCnsKCWNvbmZfdCAqY29uZiA9IG1kZGV2X3RvX2NvbmYocjFfYmlvLT5tZGRldik7Cgl1bnNpZ25lZCBsb25nIGZsYWdzOwoKCW1lbXBvb2xfZnJlZShyMV9iaW8sIGNvbmYtPnIxYnVmX3Bvb2wpOwoKCXNwaW5fbG9ja19pcnFzYXZlKCZjb25mLT5yZXN5bmNfbG9jaywgZmxhZ3MpOwoJaWYgKCFjb25mLT5iYXJyaWVyKQoJCUJVRygpOwoJLS1jb25mLT5iYXJyaWVyOwoJd2FrZV91cCgmY29uZi0+d2FpdF9yZXN1bWUpOwoJd2FrZV91cCgmY29uZi0+d2FpdF9pZGxlKTsKCglpZiAoIS0tY29uZi0+bnJfcGVuZGluZykgewoJCXdha2VfdXAoJmNvbmYtPndhaXRfaWRsZSk7CgkJd2FrZV91cCgmY29uZi0+d2FpdF9yZXN1bWUpOwoJfQoJc3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmY29uZi0+cmVzeW5jX2xvY2ssIGZsYWdzKTsKfQoKc3RhdGljIHZvaWQgcmVzY2hlZHVsZV9yZXRyeShyMWJpb190ICpyMV9iaW8pCnsKCXVuc2lnbmVkIGxvbmcgZmxhZ3M7CgltZGRldl90ICptZGRldiA9IHIxX2Jpby0+bWRkZXY7Cgljb25mX3QgKmNvbmYgPSBtZGRldl90b19jb25mKG1kZGV2KTsKCglzcGluX2xvY2tfaXJxc2F2ZSgmY29uZi0+ZGV2aWNlX2xvY2ssIGZsYWdzKTsKCWxpc3RfYWRkKCZyMV9iaW8tPnJldHJ5X2xpc3QsICZjb25mLT5yZXRyeV9saXN0KTsKCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJmNvbmYtPmRldmljZV9sb2NrLCBmbGFncyk7CgoJbWRfd2FrZXVwX3RocmVhZChtZGRldi0+dGhyZWFkKTsKfQoKLyoKICogcmFpZF9lbmRfYmlvX2lvKCkgaXMgY2FsbGVkIHdoZW4gd2UgaGF2ZSBmaW5pc2hlZCBzZXJ2aWNpbmcgYSBtaXJyb3JlZAogKiBvcGVyYXRpb24gYW5kIGFyZSByZWFkeSB0byByZXR1cm4gYSBzdWNjZXNzL2ZhaWx1cmUgY29kZSB0byB0aGUgYnVmZmVyCiAqIGNhY2hlIGxheWVyLgogKi8Kc3RhdGljIHZvaWQgcmFpZF9lbmRfYmlvX2lvKHIxYmlvX3QgKnIxX2JpbykKewoJc3RydWN0IGJpbyAqYmlvID0gcjFfYmlvLT5tYXN0ZXJfYmlvOwoKCWJpb19lbmRpbyhiaW8sIGJpby0+Ymlfc2l6ZSwKCQl0ZXN0X2JpdChSMUJJT19VcHRvZGF0ZSwgJnIxX2Jpby0+c3RhdGUpID8gMCA6IC1FSU8pOwoJZnJlZV9yMWJpbyhyMV9iaW8pOwp9CgovKgogKiBVcGRhdGUgZGlzayBoZWFkIHBvc2l0aW9uIGVzdGltYXRvciBiYXNlZCBvbiBJUlEgY29tcGxldGlvbiBpbmZvLgogKi8Kc3RhdGljIGlubGluZSB2b2lkIHVwZGF0ZV9oZWFkX3BvcyhpbnQgZGlzaywgcjFiaW9fdCAqcjFfYmlvKQp7Cgljb25mX3QgKmNvbmYgPSBtZGRldl90b19jb25mKHIxX2Jpby0+bWRkZXYpOwoKCWNvbmYtPm1pcnJvcnNbZGlza10uaGVhZF9wb3NpdGlvbiA9CgkJcjFfYmlvLT5zZWN0b3IgKyAocjFfYmlvLT5zZWN0b3JzKTsKfQoKc3RhdGljIGludCByYWlkMV9lbmRfcmVhZF9yZXF1ZXN0KHN0cnVjdCBiaW8gKmJpbywgdW5zaWduZWQgaW50IGJ5dGVzX2RvbmUsIGludCBlcnJvcikKewoJaW50IHVwdG9kYXRlID0gdGVzdF9iaXQoQklPX1VQVE9EQVRFLCAmYmlvLT5iaV9mbGFncyk7CglyMWJpb190ICogcjFfYmlvID0gKHIxYmlvX3QgKikoYmlvLT5iaV9wcml2YXRlKTsKCWludCBtaXJyb3I7Cgljb25mX3QgKmNvbmYgPSBtZGRldl90b19jb25mKHIxX2Jpby0+bWRkZXYpOwoKCWlmIChiaW8tPmJpX3NpemUpCgkJcmV0dXJuIDE7CgkKCW1pcnJvciA9IHIxX2Jpby0+cmVhZF9kaXNrOwoJLyoKCSAqIHRoaXMgYnJhbmNoIGlzIG91ciAnb25lIG1pcnJvciBJTyBoYXMgZmluaXNoZWQnIGV2ZW50IGhhbmRsZXI6CgkgKi8KCWlmICghdXB0b2RhdGUpCgkJbWRfZXJyb3IocjFfYmlvLT5tZGRldiwgY29uZi0+bWlycm9yc1ttaXJyb3JdLnJkZXYpOwoJZWxzZQoJCS8qCgkJICogU2V0IFIxQklPX1VwdG9kYXRlIGluIG91ciBtYXN0ZXIgYmlvLCBzbyB0aGF0CgkJICogd2Ugd2lsbCByZXR1cm4gYSBnb29kIGVycm9yIGNvZGUgZm9yIHRvIHRoZSBoaWdoZXIKCQkgKiBsZXZlbHMgZXZlbiBpZiBJTyBvbiBzb21lIG90aGVyIG1pcnJvcmVkIGJ1ZmZlciBmYWlscy4KCQkgKgoJCSAqIFRoZSAnbWFzdGVyJyByZXByZXNlbnRzIHRoZSBjb21wb3NpdGUgSU8gb3BlcmF0aW9uIHRvCgkJICogdXNlci1zaWRlLiBTbyBpZiBzb21ldGhpbmcgd2FpdHMgZm9yIElPLCB0aGVuIGl0IHdpbGwKCQkgKiB3YWl0IGZvciB0aGUgJ21hc3RlcicgYmlvLgoJCSAqLwoJCXNldF9iaXQoUjFCSU9fVXB0b2RhdGUsICZyMV9iaW8tPnN0YXRlKTsKCgl1cGRhdGVfaGVhZF9wb3MobWlycm9yLCByMV9iaW8pOwoKCS8qCgkgKiB3ZSBoYXZlIG9ubHkgb25lIGJpbyBvbiB0aGUgcmVhZCBzaWRlCgkgKi8KCWlmICh1cHRvZGF0ZSkKCQlyYWlkX2VuZF9iaW9faW8ocjFfYmlvKTsKCWVsc2UgewoJCS8qCgkJICogb29wcywgcmVhZCBlcnJvcjoKCQkgKi8KCQljaGFyIGJbQkRFVk5BTUVfU0laRV07CgkJaWYgKHByaW50a19yYXRlbGltaXQoKSkKCQkJcHJpbnRrKEtFUk5fRVJSICJyYWlkMTogJXM6IHJlc2NoZWR1bGluZyBzZWN0b3IgJWxsdVxuIiwKCQkJICAgICAgIGJkZXZuYW1lKGNvbmYtPm1pcnJvcnNbbWlycm9yXS5yZGV2LT5iZGV2LGIpLCAodW5zaWduZWQgbG9uZyBsb25nKXIxX2Jpby0+c2VjdG9yKTsKCQlyZXNjaGVkdWxlX3JldHJ5KHIxX2Jpbyk7Cgl9CgoJcmRldl9kZWNfcGVuZGluZyhjb25mLT5taXJyb3JzW21pcnJvcl0ucmRldiwgY29uZi0+bWRkZXYpOwoJcmV0dXJuIDA7Cn0KCnN0YXRpYyBpbnQgcmFpZDFfZW5kX3dyaXRlX3JlcXVlc3Qoc3RydWN0IGJpbyAqYmlvLCB1bnNpZ25lZCBpbnQgYnl0ZXNfZG9uZSwgaW50IGVycm9yKQp7CglpbnQgdXB0b2RhdGUgPSB0ZXN0X2JpdChCSU9fVVBUT0RBVEUsICZiaW8tPmJpX2ZsYWdzKTsKCXIxYmlvX3QgKiByMV9iaW8gPSAocjFiaW9fdCAqKShiaW8tPmJpX3ByaXZhdGUpOwoJaW50IG1pcnJvcjsKCWNvbmZfdCAqY29uZiA9IG1kZGV2X3RvX2NvbmYocjFfYmlvLT5tZGRldik7CgoJaWYgKGJpby0+Ymlfc2l6ZSkKCQlyZXR1cm4gMTsKCglmb3IgKG1pcnJvciA9IDA7IG1pcnJvciA8IGNvbmYtPnJhaWRfZGlza3M7IG1pcnJvcisrKQoJCWlmIChyMV9iaW8tPmJpb3NbbWlycm9yXSA9PSBiaW8pCgkJCWJyZWFrOwoKCS8qCgkgKiB0aGlzIGJyYW5jaCBpcyBvdXIgJ29uZSBtaXJyb3IgSU8gaGFzIGZpbmlzaGVkJyBldmVudCBoYW5kbGVyOgoJICovCglpZiAoIXVwdG9kYXRlKSB7CgkJbWRfZXJyb3IocjFfYmlvLT5tZGRldiwgY29uZi0+bWlycm9yc1ttaXJyb3JdLnJkZXYpOwoJCS8qIGFuIEkvTyBmYWlsZWQsIHdlIGNhbid0IGNsZWFyIHRoZSBiaXRtYXAgKi8KCQlzZXRfYml0KFIxQklPX0RlZ3JhZGVkLCAmcjFfYmlvLT5zdGF0ZSk7Cgl9IGVsc2UKCQkvKgoJCSAqIFNldCBSMUJJT19VcHRvZGF0ZSBpbiBvdXIgbWFzdGVyIGJpbywgc28gdGhhdAoJCSAqIHdlIHdpbGwgcmV0dXJuIGEgZ29vZCBlcnJvciBjb2RlIGZvciB0byB0aGUgaGlnaGVyCgkJICogbGV2ZWxzIGV2ZW4gaWYgSU8gb24gc29tZSBvdGhlciBtaXJyb3JlZCBidWZmZXIgZmFpbHMuCgkJICoKCQkgKiBUaGUgJ21hc3RlcicgcmVwcmVzZW50cyB0aGUgY29tcG9zaXRlIElPIG9wZXJhdGlvbiB0bwoJCSAqIHVzZXItc2lkZS4gU28gaWYgc29tZXRoaW5nIHdhaXRzIGZvciBJTywgdGhlbiBpdCB3aWxsCgkJICogd2FpdCBmb3IgdGhlICdtYXN0ZXInIGJpby4KCQkgKi8KCQlzZXRfYml0KFIxQklPX1VwdG9kYXRlLCAmcjFfYmlvLT5zdGF0ZSk7CgoJdXBkYXRlX2hlYWRfcG9zKG1pcnJvciwgcjFfYmlvKTsKCgkvKgoJICoKCSAqIExldCdzIHNlZSBpZiBhbGwgbWlycm9yZWQgd3JpdGUgb3BlcmF0aW9ucyBoYXZlIGZpbmlzaGVkCgkgKiBhbHJlYWR5LgoJICovCglpZiAoYXRvbWljX2RlY19hbmRfdGVzdCgmcjFfYmlvLT5yZW1haW5pbmcpKSB7CgkJLyogY2xlYXIgdGhlIGJpdG1hcCBpZiBhbGwgd3JpdGVzIGNvbXBsZXRlIHN1Y2Nlc3NmdWxseSAqLwoJCWJpdG1hcF9lbmR3cml0ZShyMV9iaW8tPm1kZGV2LT5iaXRtYXAsIHIxX2Jpby0+c2VjdG9yLAoJCQkJcjFfYmlvLT5zZWN0b3JzLAoJCQkJIXRlc3RfYml0KFIxQklPX0RlZ3JhZGVkLCAmcjFfYmlvLT5zdGF0ZSkpOwoJCW1kX3dyaXRlX2VuZChyMV9iaW8tPm1kZGV2KTsKCQlyYWlkX2VuZF9iaW9faW8ocjFfYmlvKTsKCX0KCglyZGV2X2RlY19wZW5kaW5nKGNvbmYtPm1pcnJvcnNbbWlycm9yXS5yZGV2LCBjb25mLT5tZGRldik7CglyZXR1cm4gMDsKfQoKCi8qCiAqIFRoaXMgcm91dGluZSByZXR1cm5zIHRoZSBkaXNrIGZyb20gd2hpY2ggdGhlIHJlcXVlc3RlZCByZWFkIHNob3VsZAogKiBiZSBkb25lLiBUaGVyZSBpcyBhIHBlci1hcnJheSAnbmV4dCBleHBlY3RlZCBzZXF1ZW50aWFsIElPJyBzZWN0b3IKICogbnVtYmVyIC0gaWYgdGhpcyBtYXRjaGVzIG9uIHRoZSBuZXh0IElPIHRoZW4gd2UgdXNlIHRoZSBsYXN0IGRpc2suCiAqIFRoZXJlIGlzIGFsc28gYSBwZXItZGlzayAnbGFzdCBrbm93IGhlYWQgcG9zaXRpb24nIHNlY3RvciB0aGF0IGlzCiAqIG1haW50YWluZWQgZnJvbSBJUlEgY29udGV4dHMsIGJvdGggdGhlIG5vcm1hbCBhbmQgdGhlIHJlc3luYyBJTwogKiBjb21wbGV0aW9uIGhhbmRsZXJzIHVwZGF0ZSB0aGlzIHBvc2l0aW9uIGNvcnJlY3RseS4gSWYgdGhlcmUgaXMgbm8KICogcGVyZmVjdCBzZXF1ZW50aWFsIG1hdGNoIHRoZW4gd2UgcGljayB0aGUgZGlzayB3aG9zZSBoZWFkIGlzIGNsb3Nlc3QuCiAqCiAqIElmIHRoZXJlIGFyZSAyIG1pcnJvcnMgaW4gdGhlIHNhbWUgMiBkZXZpY2VzLCBwZXJmb3JtYW5jZSBkZWdyYWRlcwogKiBiZWNhdXNlIHBvc2l0aW9uIGlzIG1pcnJvciwgbm90IGRldmljZSBiYXNlZC4KICoKICogVGhlIHJkZXYgZm9yIHRoZSBkZXZpY2Ugc2VsZWN0ZWQgd2lsbCBoYXZlIG5yX3BlbmRpbmcgaW5jcmVtZW50ZWQuCiAqLwpzdGF0aWMgaW50IHJlYWRfYmFsYW5jZShjb25mX3QgKmNvbmYsIHIxYmlvX3QgKnIxX2JpbykKewoJY29uc3QgdW5zaWduZWQgbG9uZyB0aGlzX3NlY3RvciA9IHIxX2Jpby0+c2VjdG9yOwoJaW50IG5ld19kaXNrID0gY29uZi0+bGFzdF91c2VkLCBkaXNrID0gbmV3X2Rpc2s7Cgljb25zdCBpbnQgc2VjdG9ycyA9IHIxX2Jpby0+c2VjdG9yczsKCXNlY3Rvcl90IG5ld19kaXN0YW5jZSwgY3VycmVudF9kaXN0YW5jZTsKCW1ka19yZGV2X3QgKm5ld19yZGV2LCAqcmRldjsKCglyY3VfcmVhZF9sb2NrKCk7CgkvKgoJICogQ2hlY2sgaWYgaXQgaWYgd2UgY2FuIGJhbGFuY2UuIFdlIGNhbiBiYWxhbmNlIG9uIHRoZSB3aG9sZQoJICogZGV2aWNlIGlmIG5vIHJlc3luYyBpcyBnb2luZyBvbiwgb3IgYmVsb3cgdGhlIHJlc3luYyB3aW5kb3cuCgkgKiBXZSB0YWtlIHRoZSBmaXJzdCByZWFkYWJsZSBkaXNrIHdoZW4gYWJvdmUgdGhlIHJlc3luYyB3aW5kb3cuCgkgKi8KIHJldHJ5OgoJaWYgKGNvbmYtPm1kZGV2LT5yZWNvdmVyeV9jcCA8IE1heFNlY3RvciAmJgoJICAgICh0aGlzX3NlY3RvciArIHNlY3RvcnMgPj0gY29uZi0+bmV4dF9yZXN5bmMpKSB7CgkJLyogQ2hvb3NlIHRoZSBmaXJzdCBvcGVyYXRpb24gZGV2aWNlLCBmb3IgY29uc2lzdGFuY3kgKi8KCQluZXdfZGlzayA9IDA7CgoJCXdoaWxlICgobmV3X3JkZXY9Y29uZi0+bWlycm9yc1tuZXdfZGlza10ucmRldikgPT0gTlVMTCB8fAoJCSAgICAgICAhbmV3X3JkZXYtPmluX3N5bmMpIHsKCQkJbmV3X2Rpc2srKzsKCQkJaWYgKG5ld19kaXNrID09IGNvbmYtPnJhaWRfZGlza3MpIHsKCQkJCW5ld19kaXNrID0gLTE7CgkJCQlicmVhazsKCQkJfQoJCX0KCQlnb3RvIHJiX291dDsKCX0KCgoJLyogbWFrZSBzdXJlIHRoZSBkaXNrIGlzIG9wZXJhdGlvbmFsICovCgl3aGlsZSAoKG5ld19yZGV2PWNvbmYtPm1pcnJvcnNbbmV3X2Rpc2tdLnJkZXYpID09IE5VTEwgfHwKCSAgICAgICAhbmV3X3JkZXYtPmluX3N5bmMpIHsKCQlpZiAobmV3X2Rpc2sgPD0gMCkKCQkJbmV3X2Rpc2sgPSBjb25mLT5yYWlkX2Rpc2tzOwoJCW5ld19kaXNrLS07CgkJaWYgKG5ld19kaXNrID09IGRpc2spIHsKCQkJbmV3X2Rpc2sgPSAtMTsKCQkJZ290byByYl9vdXQ7CgkJfQoJfQoJZGlzayA9IG5ld19kaXNrOwoJLyogbm93IGRpc2sgPT0gbmV3X2Rpc2sgPT0gc3RhcnRpbmcgcG9pbnQgZm9yIHNlYXJjaCAqLwoKCS8qCgkgKiBEb24ndCBjaGFuZ2UgdG8gYW5vdGhlciBkaXNrIGZvciBzZXF1ZW50aWFsIHJlYWRzOgoJICovCglpZiAoY29uZi0+bmV4dF9zZXFfc2VjdCA9PSB0aGlzX3NlY3RvcikKCQlnb3RvIHJiX291dDsKCWlmICh0aGlzX3NlY3RvciA9PSBjb25mLT5taXJyb3JzW25ld19kaXNrXS5oZWFkX3Bvc2l0aW9uKQoJCWdvdG8gcmJfb3V0OwoKCWN1cnJlbnRfZGlzdGFuY2UgPSBhYnModGhpc19zZWN0b3IgLSBjb25mLT5taXJyb3JzW2Rpc2tdLmhlYWRfcG9zaXRpb24pOwoKCS8qIEZpbmQgdGhlIGRpc2sgd2hvc2UgaGVhZCBpcyBjbG9zZXN0ICovCgoJZG8gewoJCWlmIChkaXNrIDw9IDApCgkJCWRpc2sgPSBjb25mLT5yYWlkX2Rpc2tzOwoJCWRpc2stLTsKCgkJaWYgKChyZGV2PWNvbmYtPm1pcnJvcnNbZGlza10ucmRldikgPT0gTlVMTCB8fAoJCSAgICAhcmRldi0+aW5fc3luYykKCQkJY29udGludWU7CgoJCWlmICghYXRvbWljX3JlYWQoJnJkZXYtPm5yX3BlbmRpbmcpKSB7CgkJCW5ld19kaXNrID0gZGlzazsKCQkJbmV3X3JkZXYgPSByZGV2OwoJCQlicmVhazsKCQl9CgkJbmV3X2Rpc3RhbmNlID0gYWJzKHRoaXNfc2VjdG9yIC0gY29uZi0+bWlycm9yc1tkaXNrXS5oZWFkX3Bvc2l0aW9uKTsKCQlpZiAobmV3X2Rpc3RhbmNlIDwgY3VycmVudF9kaXN0YW5jZSkgewoJCQljdXJyZW50X2Rpc3RhbmNlID0gbmV3X2Rpc3RhbmNlOwoJCQluZXdfZGlzayA9IGRpc2s7CgkJCW5ld19yZGV2ID0gcmRldjsKCQl9Cgl9IHdoaWxlIChkaXNrICE9IGNvbmYtPmxhc3RfdXNlZCk7CgpyYl9vdXQ6CgoKCWlmIChuZXdfZGlzayA+PSAwKSB7CgkJY29uZi0+bmV4dF9zZXFfc2VjdCA9IHRoaXNfc2VjdG9yICsgc2VjdG9yczsKCQljb25mLT5sYXN0X3VzZWQgPSBuZXdfZGlzazsKCQlhdG9taWNfaW5jKCZuZXdfcmRldi0+bnJfcGVuZGluZyk7CgkJaWYgKCFuZXdfcmRldi0+aW5fc3luYykgewoJCQkvKiBjYW5ub3QgcmlzayByZXR1cm5pbmcgYSBkZXZpY2UgdGhhdCBmYWlsZWQKCQkJICogYmVmb3JlIHdlIGluYydlZCBucl9wZW5kaW5nCgkJCSAqLwoJCQlhdG9taWNfZGVjKCZuZXdfcmRldi0+bnJfcGVuZGluZyk7CgkJCWdvdG8gcmV0cnk7CgkJfQoJfQoJcmN1X3JlYWRfdW5sb2NrKCk7CgoJcmV0dXJuIG5ld19kaXNrOwp9CgpzdGF0aWMgdm9pZCB1bnBsdWdfc2xhdmVzKG1kZGV2X3QgKm1kZGV2KQp7Cgljb25mX3QgKmNvbmYgPSBtZGRldl90b19jb25mKG1kZGV2KTsKCWludCBpOwoKCXJjdV9yZWFkX2xvY2soKTsKCWZvciAoaT0wOyBpPG1kZGV2LT5yYWlkX2Rpc2tzOyBpKyspIHsKCQltZGtfcmRldl90ICpyZGV2ID0gY29uZi0+bWlycm9yc1tpXS5yZGV2OwoJCWlmIChyZGV2ICYmICFyZGV2LT5mYXVsdHkgJiYgYXRvbWljX3JlYWQoJnJkZXYtPm5yX3BlbmRpbmcpKSB7CgkJCXJlcXVlc3RfcXVldWVfdCAqcl9xdWV1ZSA9IGJkZXZfZ2V0X3F1ZXVlKHJkZXYtPmJkZXYpOwoKCQkJYXRvbWljX2luYygmcmRldi0+bnJfcGVuZGluZyk7CgkJCXJjdV9yZWFkX3VubG9jaygpOwoKCQkJaWYgKHJfcXVldWUtPnVucGx1Z19mbikKCQkJCXJfcXVldWUtPnVucGx1Z19mbihyX3F1ZXVlKTsKCgkJCXJkZXZfZGVjX3BlbmRpbmcocmRldiwgbWRkZXYpOwoJCQlyY3VfcmVhZF9sb2NrKCk7CgkJfQoJfQoJcmN1X3JlYWRfdW5sb2NrKCk7Cn0KCnN0YXRpYyB2b2lkIHJhaWQxX3VucGx1ZyhyZXF1ZXN0X3F1ZXVlX3QgKnEpCnsKCW1kZGV2X3QgKm1kZGV2ID0gcS0+cXVldWVkYXRhOwoKCXVucGx1Z19zbGF2ZXMobWRkZXYpOwoJbWRfd2FrZXVwX3RocmVhZChtZGRldi0+dGhyZWFkKTsKfQoKc3RhdGljIGludCByYWlkMV9pc3N1ZV9mbHVzaChyZXF1ZXN0X3F1ZXVlX3QgKnEsIHN0cnVjdCBnZW5kaXNrICpkaXNrLAoJCQkgICAgIHNlY3Rvcl90ICplcnJvcl9zZWN0b3IpCnsKCW1kZGV2X3QgKm1kZGV2ID0gcS0+cXVldWVkYXRhOwoJY29uZl90ICpjb25mID0gbWRkZXZfdG9fY29uZihtZGRldik7CglpbnQgaSwgcmV0ID0gMDsKCglyY3VfcmVhZF9sb2NrKCk7Cglmb3IgKGk9MDsgaTxtZGRldi0+cmFpZF9kaXNrcyAmJiByZXQgPT0gMDsgaSsrKSB7CgkJbWRrX3JkZXZfdCAqcmRldiA9IGNvbmYtPm1pcnJvcnNbaV0ucmRldjsKCQlpZiAocmRldiAmJiAhcmRldi0+ZmF1bHR5KSB7CgkJCXN0cnVjdCBibG9ja19kZXZpY2UgKmJkZXYgPSByZGV2LT5iZGV2OwoJCQlyZXF1ZXN0X3F1ZXVlX3QgKnJfcXVldWUgPSBiZGV2X2dldF9xdWV1ZShiZGV2KTsKCgkJCWlmICghcl9xdWV1ZS0+aXNzdWVfZmx1c2hfZm4pCgkJCQlyZXQgPSAtRU9QTk9UU1VQUDsKCQkJZWxzZSB7CgkJCQlhdG9taWNfaW5jKCZyZGV2LT5ucl9wZW5kaW5nKTsKCQkJCXJjdV9yZWFkX3VubG9jaygpOwoJCQkJcmV0ID0gcl9xdWV1ZS0+aXNzdWVfZmx1c2hfZm4ocl9xdWV1ZSwgYmRldi0+YmRfZGlzaywKCQkJCQkJCSAgICAgIGVycm9yX3NlY3Rvcik7CgkJCQlyZGV2X2RlY19wZW5kaW5nKHJkZXYsIG1kZGV2KTsKCQkJCXJjdV9yZWFkX2xvY2soKTsKCQkJfQoJCX0KCX0KCXJjdV9yZWFkX3VubG9jaygpOwoJcmV0dXJuIHJldDsKfQoKLyoKICogVGhyb3R0bGUgcmVzeW5jIGRlcHRoLCBzbyB0aGF0IHdlIGNhbiBib3RoIGdldCBwcm9wZXIgb3ZlcmxhcHBpbmcgb2YKICogcmVxdWVzdHMsIGJ1dCBhcmUgc3RpbGwgYWJsZSB0byBoYW5kbGUgbm9ybWFsIHJlcXVlc3RzIHF1aWNrbHkuCiAqLwojZGVmaW5lIFJFU1lOQ19ERVBUSCAzMgoKc3RhdGljIHZvaWQgZGV2aWNlX2JhcnJpZXIoY29uZl90ICpjb25mLCBzZWN0b3JfdCBzZWN0KQp7CglzcGluX2xvY2tfaXJxKCZjb25mLT5yZXN5bmNfbG9jayk7Cgl3YWl0X2V2ZW50X2xvY2tfaXJxKGNvbmYtPndhaXRfaWRsZSwgIXdhaXRxdWV1ZV9hY3RpdmUoJmNvbmYtPndhaXRfcmVzdW1lKSwKCQkJICAgIGNvbmYtPnJlc3luY19sb2NrLCByYWlkMV91bnBsdWcoY29uZi0+bWRkZXYtPnF1ZXVlKSk7CgkKCWlmICghY29uZi0+YmFycmllcisrKSB7CgkJd2FpdF9ldmVudF9sb2NrX2lycShjb25mLT53YWl0X2lkbGUsICFjb25mLT5ucl9wZW5kaW5nLAoJCQkJICAgIGNvbmYtPnJlc3luY19sb2NrLCByYWlkMV91bnBsdWcoY29uZi0+bWRkZXYtPnF1ZXVlKSk7CgkJaWYgKGNvbmYtPm5yX3BlbmRpbmcpCgkJCUJVRygpOwoJfQoJd2FpdF9ldmVudF9sb2NrX2lycShjb25mLT53YWl0X3Jlc3VtZSwgY29uZi0+YmFycmllciA8IFJFU1lOQ19ERVBUSCwKCQkJICAgIGNvbmYtPnJlc3luY19sb2NrLCByYWlkMV91bnBsdWcoY29uZi0+bWRkZXYtPnF1ZXVlKSk7Cgljb25mLT5uZXh0X3Jlc3luYyA9IHNlY3Q7CglzcGluX3VubG9ja19pcnEoJmNvbmYtPnJlc3luY19sb2NrKTsKfQoKc3RhdGljIGludCBtYWtlX3JlcXVlc3QocmVxdWVzdF9xdWV1ZV90ICpxLCBzdHJ1Y3QgYmlvICogYmlvKQp7CgltZGRldl90ICptZGRldiA9IHEtPnF1ZXVlZGF0YTsKCWNvbmZfdCAqY29uZiA9IG1kZGV2X3RvX2NvbmYobWRkZXYpOwoJbWlycm9yX2luZm9fdCAqbWlycm9yOwoJcjFiaW9fdCAqcjFfYmlvOwoJc3RydWN0IGJpbyAqcmVhZF9iaW87CglpbnQgaSwgdGFyZ2V0cyA9IDAsIGRpc2tzOwoJbWRrX3JkZXZfdCAqcmRldjsKCXN0cnVjdCBiaXRtYXAgKmJpdG1hcCA9IG1kZGV2LT5iaXRtYXA7Cgl1bnNpZ25lZCBsb25nIGZsYWdzOwoJc3RydWN0IGJpb19saXN0IGJsOwoKCgkvKgoJICogUmVnaXN0ZXIgdGhlIG5ldyByZXF1ZXN0IGFuZCB3YWl0IGlmIHRoZSByZWNvbnN0cnVjdGlvbgoJICogdGhyZWFkIGhhcyBwdXQgdXAgYSBiYXIgZm9yIG5ldyByZXF1ZXN0cy4KCSAqIENvbnRpbnVlIGltbWVkaWF0ZWx5IGlmIG5vIHJlc3luYyBpcyBhY3RpdmUgY3VycmVudGx5LgoJICovCgltZF93cml0ZV9zdGFydChtZGRldiwgYmlvKTsgLyogd2FpdCBvbiBzdXBlcmJsb2NrIHVwZGF0ZSBlYXJseSAqLwoKCXNwaW5fbG9ja19pcnEoJmNvbmYtPnJlc3luY19sb2NrKTsKCXdhaXRfZXZlbnRfbG9ja19pcnEoY29uZi0+d2FpdF9yZXN1bWUsICFjb25mLT5iYXJyaWVyLCBjb25mLT5yZXN5bmNfbG9jaywgKTsKCWNvbmYtPm5yX3BlbmRpbmcrKzsKCXNwaW5fdW5sb2NrX2lycSgmY29uZi0+cmVzeW5jX2xvY2spOwoKCWlmIChiaW9fZGF0YV9kaXIoYmlvKT09V1JJVEUpIHsKCQlkaXNrX3N0YXRfaW5jKG1kZGV2LT5nZW5kaXNrLCB3cml0ZXMpOwoJCWRpc2tfc3RhdF9hZGQobWRkZXYtPmdlbmRpc2ssIHdyaXRlX3NlY3RvcnMsIGJpb19zZWN0b3JzKGJpbykpOwoJfSBlbHNlIHsKCQlkaXNrX3N0YXRfaW5jKG1kZGV2LT5nZW5kaXNrLCByZWFkcyk7CgkJZGlza19zdGF0X2FkZChtZGRldi0+Z2VuZGlzaywgcmVhZF9zZWN0b3JzLCBiaW9fc2VjdG9ycyhiaW8pKTsKCX0KCgkvKgoJICogbWFrZV9yZXF1ZXN0KCkgY2FuIGFib3J0IHRoZSBvcGVyYXRpb24gd2hlbiBSRUFEQSBpcyBiZWluZwoJICogdXNlZCBhbmQgbm8gZW1wdHkgcmVxdWVzdCBpcyBhdmFpbGFibGUuCgkgKgoJICovCglyMV9iaW8gPSBtZW1wb29sX2FsbG9jKGNvbmYtPnIxYmlvX3Bvb2wsIEdGUF9OT0lPKTsKCglyMV9iaW8tPm1hc3Rlcl9iaW8gPSBiaW87CglyMV9iaW8tPnNlY3RvcnMgPSBiaW8tPmJpX3NpemUgPj4gOTsKCXIxX2Jpby0+c3RhdGUgPSAwOwoJcjFfYmlvLT5tZGRldiA9IG1kZGV2OwoJcjFfYmlvLT5zZWN0b3IgPSBiaW8tPmJpX3NlY3RvcjsKCglyMV9iaW8tPnN0YXRlID0gMDsKCglpZiAoYmlvX2RhdGFfZGlyKGJpbykgPT0gUkVBRCkgewoJCS8qCgkJICogcmVhZCBiYWxhbmNpbmcgbG9naWM6CgkJICovCgkJaW50IHJkaXNrID0gcmVhZF9iYWxhbmNlKGNvbmYsIHIxX2Jpbyk7CgoJCWlmIChyZGlzayA8IDApIHsKCQkJLyogY291bGRuJ3QgZmluZCBhbnl3aGVyZSB0byByZWFkIGZyb20gKi8KCQkJcmFpZF9lbmRfYmlvX2lvKHIxX2Jpbyk7CgkJCXJldHVybiAwOwoJCX0KCQltaXJyb3IgPSBjb25mLT5taXJyb3JzICsgcmRpc2s7CgoJCXIxX2Jpby0+cmVhZF9kaXNrID0gcmRpc2s7CgoJCXJlYWRfYmlvID0gYmlvX2Nsb25lKGJpbywgR0ZQX05PSU8pOwoKCQlyMV9iaW8tPmJpb3NbcmRpc2tdID0gcmVhZF9iaW87CgoJCXJlYWRfYmlvLT5iaV9zZWN0b3IgPSByMV9iaW8tPnNlY3RvciArIG1pcnJvci0+cmRldi0+ZGF0YV9vZmZzZXQ7CgkJcmVhZF9iaW8tPmJpX2JkZXYgPSBtaXJyb3ItPnJkZXYtPmJkZXY7CgkJcmVhZF9iaW8tPmJpX2VuZF9pbyA9IHJhaWQxX2VuZF9yZWFkX3JlcXVlc3Q7CgkJcmVhZF9iaW8tPmJpX3J3ID0gUkVBRDsKCQlyZWFkX2Jpby0+YmlfcHJpdmF0ZSA9IHIxX2JpbzsKCgkJZ2VuZXJpY19tYWtlX3JlcXVlc3QocmVhZF9iaW8pOwoJCXJldHVybiAwOwoJfQoKCS8qCgkgKiBXUklURToKCSAqLwoJLyogZmlyc3Qgc2VsZWN0IHRhcmdldCBkZXZpY2VzIHVuZGVyIHNwaW5sb2NrIGFuZAoJICogaW5jIHJlZmNvdW50IG9uIHRoZWlyIHJkZXYuICBSZWNvcmQgdGhlbSBieSBzZXR0aW5nCgkgKiBiaW9zW3hdIHRvIGJpbwoJICovCglkaXNrcyA9IGNvbmYtPnJhaWRfZGlza3M7CiNpZiAwCgl7IHN0YXRpYyBpbnQgZmlyc3Q9MTsKCWlmIChmaXJzdCkgcHJpbnRrKCJGaXJzdCBXcml0ZSBzZWN0b3IgJWxsdSBkaXNrcyAlZFxuIiwKCQkJICAodW5zaWduZWQgbG9uZyBsb25nKXIxX2Jpby0+c2VjdG9yLCBkaXNrcyk7CglmaXJzdCA9IDA7Cgl9CiNlbmRpZgoJcmN1X3JlYWRfbG9jaygpOwoJZm9yIChpID0gMDsgIGkgPCBkaXNrczsgaSsrKSB7CgkJaWYgKChyZGV2PWNvbmYtPm1pcnJvcnNbaV0ucmRldikgIT0gTlVMTCAmJgoJCSAgICAhcmRldi0+ZmF1bHR5KSB7CgkJCWF0b21pY19pbmMoJnJkZXYtPm5yX3BlbmRpbmcpOwoJCQlpZiAocmRldi0+ZmF1bHR5KSB7CgkJCQlhdG9taWNfZGVjKCZyZGV2LT5ucl9wZW5kaW5nKTsKCQkJCXIxX2Jpby0+Ymlvc1tpXSA9IE5VTEw7CgkJCX0gZWxzZQoJCQkJcjFfYmlvLT5iaW9zW2ldID0gYmlvOwoJCQl0YXJnZXRzKys7CgkJfSBlbHNlCgkJCXIxX2Jpby0+Ymlvc1tpXSA9IE5VTEw7Cgl9CglyY3VfcmVhZF91bmxvY2soKTsKCglpZiAodGFyZ2V0cyA8IGNvbmYtPnJhaWRfZGlza3MpIHsKCQkvKiBhcnJheSBpcyBkZWdyYWRlZCwgd2Ugd2lsbCBub3QgY2xlYXIgdGhlIGJpdG1hcAoJCSAqIG9uIEkvTyBjb21wbGV0aW9uIChzZWUgcmFpZDFfZW5kX3dyaXRlX3JlcXVlc3QpICovCgkJc2V0X2JpdChSMUJJT19EZWdyYWRlZCwgJnIxX2Jpby0+c3RhdGUpOwoJfQoKCWF0b21pY19zZXQoJnIxX2Jpby0+cmVtYWluaW5nLCAwKTsKCgliaW9fbGlzdF9pbml0KCZibCk7Cglmb3IgKGkgPSAwOyBpIDwgZGlza3M7IGkrKykgewoJCXN0cnVjdCBiaW8gKm1iaW87CgkJaWYgKCFyMV9iaW8tPmJpb3NbaV0pCgkJCWNvbnRpbnVlOwoKCQltYmlvID0gYmlvX2Nsb25lKGJpbywgR0ZQX05PSU8pOwoJCXIxX2Jpby0+Ymlvc1tpXSA9IG1iaW87CgoJCW1iaW8tPmJpX3NlY3Rvcgk9IHIxX2Jpby0+c2VjdG9yICsgY29uZi0+bWlycm9yc1tpXS5yZGV2LT5kYXRhX29mZnNldDsKCQltYmlvLT5iaV9iZGV2ID0gY29uZi0+bWlycm9yc1tpXS5yZGV2LT5iZGV2OwoJCW1iaW8tPmJpX2VuZF9pbwk9IHJhaWQxX2VuZF93cml0ZV9yZXF1ZXN0OwoJCW1iaW8tPmJpX3J3ID0gV1JJVEU7CgkJbWJpby0+YmlfcHJpdmF0ZSA9IHIxX2JpbzsKCgkJYXRvbWljX2luYygmcjFfYmlvLT5yZW1haW5pbmcpOwoKCQliaW9fbGlzdF9hZGQoJmJsLCBtYmlvKTsKCX0KCgliaXRtYXBfc3RhcnR3cml0ZShiaXRtYXAsIGJpby0+Ymlfc2VjdG9yLCByMV9iaW8tPnNlY3RvcnMpOwoJc3Bpbl9sb2NrX2lycXNhdmUoJmNvbmYtPmRldmljZV9sb2NrLCBmbGFncyk7CgliaW9fbGlzdF9tZXJnZSgmY29uZi0+cGVuZGluZ19iaW9fbGlzdCwgJmJsKTsKCWJpb19saXN0X2luaXQoJmJsKTsKCglibGtfcGx1Z19kZXZpY2UobWRkZXYtPnF1ZXVlKTsKCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJmNvbmYtPmRldmljZV9sb2NrLCBmbGFncyk7CgojaWYgMAoJd2hpbGUgKChiaW8gPSBiaW9fbGlzdF9wb3AoJmJsKSkgIT0gTlVMTCkKCQlnZW5lcmljX21ha2VfcmVxdWVzdChiaW8pOwojZW5kaWYKCglyZXR1cm4gMDsKfQoKc3RhdGljIHZvaWQgc3RhdHVzKHN0cnVjdCBzZXFfZmlsZSAqc2VxLCBtZGRldl90ICptZGRldikKewoJY29uZl90ICpjb25mID0gbWRkZXZfdG9fY29uZihtZGRldik7CglpbnQgaTsKCglzZXFfcHJpbnRmKHNlcSwgIiBbJWQvJWRdIFsiLCBjb25mLT5yYWlkX2Rpc2tzLAoJCQkJCQljb25mLT53b3JraW5nX2Rpc2tzKTsKCWZvciAoaSA9IDA7IGkgPCBjb25mLT5yYWlkX2Rpc2tzOyBpKyspCgkJc2VxX3ByaW50ZihzZXEsICIlcyIsCgkJCSAgICAgIGNvbmYtPm1pcnJvcnNbaV0ucmRldiAmJgoJCQkgICAgICBjb25mLT5taXJyb3JzW2ldLnJkZXYtPmluX3N5bmMgPyAiVSIgOiAiXyIpOwoJc2VxX3ByaW50ZihzZXEsICJdIik7Cn0KCgpzdGF0aWMgdm9pZCBlcnJvcihtZGRldl90ICptZGRldiwgbWRrX3JkZXZfdCAqcmRldikKewoJY2hhciBiW0JERVZOQU1FX1NJWkVdOwoJY29uZl90ICpjb25mID0gbWRkZXZfdG9fY29uZihtZGRldik7CgoJLyoKCSAqIElmIGl0IGlzIG5vdCBvcGVyYXRpb25hbCwgdGhlbiB3ZSBoYXZlIGFscmVhZHkgbWFya2VkIGl0IGFzIGRlYWQKCSAqIGVsc2UgaWYgaXQgaXMgdGhlIGxhc3Qgd29ya2luZyBkaXNrcywgaWdub3JlIHRoZSBlcnJvciwgbGV0IHRoZQoJICogbmV4dCBsZXZlbCB1cCBrbm93LgoJICogZWxzZSBtYXJrIHRoZSBkcml2ZSBhcyBmYWlsZWQKCSAqLwoJaWYgKHJkZXYtPmluX3N5bmMKCSAgICAmJiBjb25mLT53b3JraW5nX2Rpc2tzID09IDEpCgkJLyoKCQkgKiBEb24ndCBmYWlsIHRoZSBkcml2ZSwgYWN0IGFzIHRob3VnaCB3ZSB3ZXJlIGp1c3QgYQoJCSAqIG5vcm1hbCBzaW5nbGUgZHJpdmUKCQkgKi8KCQlyZXR1cm47CglpZiAocmRldi0+aW5fc3luYykgewoJCW1kZGV2LT5kZWdyYWRlZCsrOwoJCWNvbmYtPndvcmtpbmdfZGlza3MtLTsKCQkvKgoJCSAqIGlmIHJlY292ZXJ5IGlzIHJ1bm5pbmcsIG1ha2Ugc3VyZSBpdCBhYm9ydHMuCgkJICovCgkJc2V0X2JpdChNRF9SRUNPVkVSWV9FUlIsICZtZGRldi0+cmVjb3ZlcnkpOwoJfQoJcmRldi0+aW5fc3luYyA9IDA7CglyZGV2LT5mYXVsdHkgPSAxOwoJbWRkZXYtPnNiX2RpcnR5ID0gMTsKCXByaW50ayhLRVJOX0FMRVJUICJyYWlkMTogRGlzayBmYWlsdXJlIG9uICVzLCBkaXNhYmxpbmcgZGV2aWNlLiBcbiIKCQkiCU9wZXJhdGlvbiBjb250aW51aW5nIG9uICVkIGRldmljZXNcbiIsCgkJYmRldm5hbWUocmRldi0+YmRldixiKSwgY29uZi0+d29ya2luZ19kaXNrcyk7Cn0KCnN0YXRpYyB2b2lkIHByaW50X2NvbmYoY29uZl90ICpjb25mKQp7CglpbnQgaTsKCW1pcnJvcl9pbmZvX3QgKnRtcDsKCglwcmludGsoIlJBSUQxIGNvbmYgcHJpbnRvdXQ6XG4iKTsKCWlmICghY29uZikgewoJCXByaW50aygiKCFjb25mKVxuIik7CgkJcmV0dXJuOwoJfQoJcHJpbnRrKCIgLS0tIHdkOiVkIHJkOiVkXG4iLCBjb25mLT53b3JraW5nX2Rpc2tzLAoJCWNvbmYtPnJhaWRfZGlza3MpOwoKCWZvciAoaSA9IDA7IGkgPCBjb25mLT5yYWlkX2Rpc2tzOyBpKyspIHsKCQljaGFyIGJbQkRFVk5BTUVfU0laRV07CgkJdG1wID0gY29uZi0+bWlycm9ycyArIGk7CgkJaWYgKHRtcC0+cmRldikKCQkJcHJpbnRrKCIgZGlzayAlZCwgd286JWQsIG86JWQsIGRldjolc1xuIiwKCQkJCWksICF0bXAtPnJkZXYtPmluX3N5bmMsICF0bXAtPnJkZXYtPmZhdWx0eSwKCQkJCWJkZXZuYW1lKHRtcC0+cmRldi0+YmRldixiKSk7Cgl9Cn0KCnN0YXRpYyB2b2lkIGNsb3NlX3N5bmMoY29uZl90ICpjb25mKQp7CglzcGluX2xvY2tfaXJxKCZjb25mLT5yZXN5bmNfbG9jayk7Cgl3YWl0X2V2ZW50X2xvY2tfaXJxKGNvbmYtPndhaXRfcmVzdW1lLCAhY29uZi0+YmFycmllciwKCQkJICAgIGNvbmYtPnJlc3luY19sb2NrLCAJcmFpZDFfdW5wbHVnKGNvbmYtPm1kZGV2LT5xdWV1ZSkpOwoJc3Bpbl91bmxvY2tfaXJxKCZjb25mLT5yZXN5bmNfbG9jayk7CgoJaWYgKGNvbmYtPmJhcnJpZXIpIEJVRygpOwoJaWYgKHdhaXRxdWV1ZV9hY3RpdmUoJmNvbmYtPndhaXRfaWRsZSkpIEJVRygpOwoKCW1lbXBvb2xfZGVzdHJveShjb25mLT5yMWJ1Zl9wb29sKTsKCWNvbmYtPnIxYnVmX3Bvb2wgPSBOVUxMOwp9CgpzdGF0aWMgaW50IHJhaWQxX3NwYXJlX2FjdGl2ZShtZGRldl90ICptZGRldikKewoJaW50IGk7Cgljb25mX3QgKmNvbmYgPSBtZGRldi0+cHJpdmF0ZTsKCW1pcnJvcl9pbmZvX3QgKnRtcDsKCgkvKgoJICogRmluZCBhbGwgZmFpbGVkIGRpc2tzIHdpdGhpbiB0aGUgUkFJRDEgY29uZmlndXJhdGlvbiAKCSAqIGFuZCBtYXJrIHRoZW0gcmVhZGFibGUKCSAqLwoJZm9yIChpID0gMDsgaSA8IGNvbmYtPnJhaWRfZGlza3M7IGkrKykgewoJCXRtcCA9IGNvbmYtPm1pcnJvcnMgKyBpOwoJCWlmICh0bXAtPnJkZXYgCgkJICAgICYmICF0bXAtPnJkZXYtPmZhdWx0eQoJCSAgICAmJiAhdG1wLT5yZGV2LT5pbl9zeW5jKSB7CgkJCWNvbmYtPndvcmtpbmdfZGlza3MrKzsKCQkJbWRkZXYtPmRlZ3JhZGVkLS07CgkJCXRtcC0+cmRldi0+aW5fc3luYyA9IDE7CgkJfQoJfQoKCXByaW50X2NvbmYoY29uZik7CglyZXR1cm4gMDsKfQoKCnN0YXRpYyBpbnQgcmFpZDFfYWRkX2Rpc2sobWRkZXZfdCAqbWRkZXYsIG1ka19yZGV2X3QgKnJkZXYpCnsKCWNvbmZfdCAqY29uZiA9IG1kZGV2LT5wcml2YXRlOwoJaW50IGZvdW5kID0gMDsKCWludCBtaXJyb3IgPSAwOwoJbWlycm9yX2luZm9fdCAqcDsKCglpZiAocmRldi0+c2F2ZWRfcmFpZF9kaXNrID49IDAgJiYKCSAgICBjb25mLT5taXJyb3JzW3JkZXYtPnNhdmVkX3JhaWRfZGlza10ucmRldiA9PSBOVUxMKQoJCW1pcnJvciA9IHJkZXYtPnNhdmVkX3JhaWRfZGlzazsKCWZvciAobWlycm9yPTA7IG1pcnJvciA8IG1kZGV2LT5yYWlkX2Rpc2tzOyBtaXJyb3IrKykKCQlpZiAoICEocD1jb25mLT5taXJyb3JzK21pcnJvciktPnJkZXYpIHsKCgkJCWJsa19xdWV1ZV9zdGFja19saW1pdHMobWRkZXYtPnF1ZXVlLAoJCQkJCSAgICAgICByZGV2LT5iZGV2LT5iZF9kaXNrLT5xdWV1ZSk7CgkJCS8qIGFzIHdlIGRvbid0IGhvbm91ciBtZXJnZV9idmVjX2ZuLCB3ZSBtdXN0IG5ldmVyIHJpc2sKCQkJICogdmlvbGF0aW5nIGl0LCBzbyBsaW1pdCAtPm1heF9zZWN0b3IgdG8gb25lIFBBR0UsIGFzCgkJCSAqIGEgb25lIHBhZ2UgcmVxdWVzdCBpcyBuZXZlciBpbiB2aW9sYXRpb24uCgkJCSAqLwoJCQlpZiAocmRldi0+YmRldi0+YmRfZGlzay0+cXVldWUtPm1lcmdlX2J2ZWNfZm4gJiYKCQkJICAgIG1kZGV2LT5xdWV1ZS0+bWF4X3NlY3RvcnMgPiAoUEFHRV9TSVpFPj45KSkKCQkJCWJsa19xdWV1ZV9tYXhfc2VjdG9ycyhtZGRldi0+cXVldWUsIFBBR0VfU0laRT4+OSk7CgoJCQlwLT5oZWFkX3Bvc2l0aW9uID0gMDsKCQkJcmRldi0+cmFpZF9kaXNrID0gbWlycm9yOwoJCQlmb3VuZCA9IDE7CgkJCWlmIChyZGV2LT5zYXZlZF9yYWlkX2Rpc2sgIT0gbWlycm9yKQoJCQkJY29uZi0+ZnVsbHN5bmMgPSAxOwoJCQlwLT5yZGV2ID0gcmRldjsKCQkJYnJlYWs7CgkJfQoKCXByaW50X2NvbmYoY29uZik7CglyZXR1cm4gZm91bmQ7Cn0KCnN0YXRpYyBpbnQgcmFpZDFfcmVtb3ZlX2Rpc2sobWRkZXZfdCAqbWRkZXYsIGludCBudW1iZXIpCnsKCWNvbmZfdCAqY29uZiA9IG1kZGV2LT5wcml2YXRlOwoJaW50IGVyciA9IDA7CgltZGtfcmRldl90ICpyZGV2OwoJbWlycm9yX2luZm9fdCAqcCA9IGNvbmYtPm1pcnJvcnMrIG51bWJlcjsKCglwcmludF9jb25mKGNvbmYpOwoJcmRldiA9IHAtPnJkZXY7CglpZiAocmRldikgewoJCWlmIChyZGV2LT5pbl9zeW5jIHx8CgkJICAgIGF0b21pY19yZWFkKCZyZGV2LT5ucl9wZW5kaW5nKSkgewoJCQllcnIgPSAtRUJVU1k7CgkJCWdvdG8gYWJvcnQ7CgkJfQoJCXAtPnJkZXYgPSBOVUxMOwoJCXN5bmNocm9uaXplX3JjdSgpOwoJCWlmIChhdG9taWNfcmVhZCgmcmRldi0+bnJfcGVuZGluZykpIHsKCQkJLyogbG9zdCB0aGUgcmFjZSwgdHJ5IGxhdGVyICovCgkJCWVyciA9IC1FQlVTWTsKCQkJcC0+cmRldiA9IHJkZXY7CgkJfQoJfQphYm9ydDoKCglwcmludF9jb25mKGNvbmYpOwoJcmV0dXJuIGVycjsKfQoKCnN0YXRpYyBpbnQgZW5kX3N5bmNfcmVhZChzdHJ1Y3QgYmlvICpiaW8sIHVuc2lnbmVkIGludCBieXRlc19kb25lLCBpbnQgZXJyb3IpCnsKCWludCB1cHRvZGF0ZSA9IHRlc3RfYml0KEJJT19VUFRPREFURSwgJmJpby0+YmlfZmxhZ3MpOwoJcjFiaW9fdCAqIHIxX2JpbyA9IChyMWJpb190ICopKGJpby0+YmlfcHJpdmF0ZSk7Cgljb25mX3QgKmNvbmYgPSBtZGRldl90b19jb25mKHIxX2Jpby0+bWRkZXYpOwoKCWlmIChiaW8tPmJpX3NpemUpCgkJcmV0dXJuIDE7CgoJaWYgKHIxX2Jpby0+Ymlvc1tyMV9iaW8tPnJlYWRfZGlza10gIT0gYmlvKQoJCUJVRygpOwoJdXBkYXRlX2hlYWRfcG9zKHIxX2Jpby0+cmVhZF9kaXNrLCByMV9iaW8pOwoJLyoKCSAqIHdlIGhhdmUgcmVhZCBhIGJsb2NrLCBub3cgaXQgbmVlZHMgdG8gYmUgcmUtd3JpdHRlbiwKCSAqIG9yIHJlLXJlYWQgaWYgdGhlIHJlYWQgZmFpbGVkLgoJICogV2UgZG9uJ3QgZG8gbXVjaCBoZXJlLCBqdXN0IHNjaGVkdWxlIGhhbmRsaW5nIGJ5IHJhaWQxZAoJICovCglpZiAoIXVwdG9kYXRlKSB7CgkJbWRfZXJyb3IocjFfYmlvLT5tZGRldiwKCQkJIGNvbmYtPm1pcnJvcnNbcjFfYmlvLT5yZWFkX2Rpc2tdLnJkZXYpOwoJCXNldF9iaXQoUjFCSU9fRGVncmFkZWQsICZyMV9iaW8tPnN0YXRlKTsKCX0gZWxzZQoJCXNldF9iaXQoUjFCSU9fVXB0b2RhdGUsICZyMV9iaW8tPnN0YXRlKTsKCXJkZXZfZGVjX3BlbmRpbmcoY29uZi0+bWlycm9yc1tyMV9iaW8tPnJlYWRfZGlza10ucmRldiwgY29uZi0+bWRkZXYpOwoJcmVzY2hlZHVsZV9yZXRyeShyMV9iaW8pOwoJcmV0dXJuIDA7Cn0KCnN0YXRpYyBpbnQgZW5kX3N5bmNfd3JpdGUoc3RydWN0IGJpbyAqYmlvLCB1bnNpZ25lZCBpbnQgYnl0ZXNfZG9uZSwgaW50IGVycm9yKQp7CglpbnQgdXB0b2RhdGUgPSB0ZXN0X2JpdChCSU9fVVBUT0RBVEUsICZiaW8tPmJpX2ZsYWdzKTsKCXIxYmlvX3QgKiByMV9iaW8gPSAocjFiaW9fdCAqKShiaW8tPmJpX3ByaXZhdGUpOwoJbWRkZXZfdCAqbWRkZXYgPSByMV9iaW8tPm1kZGV2OwoJY29uZl90ICpjb25mID0gbWRkZXZfdG9fY29uZihtZGRldik7CglpbnQgaTsKCWludCBtaXJyb3I9MDsKCglpZiAoYmlvLT5iaV9zaXplKQoJCXJldHVybiAxOwoKCWZvciAoaSA9IDA7IGkgPCBjb25mLT5yYWlkX2Rpc2tzOyBpKyspCgkJaWYgKHIxX2Jpby0+Ymlvc1tpXSA9PSBiaW8pIHsKCQkJbWlycm9yID0gaTsKCQkJYnJlYWs7CgkJfQoJaWYgKCF1cHRvZGF0ZSkgewoJCW1kX2Vycm9yKG1kZGV2LCBjb25mLT5taXJyb3JzW21pcnJvcl0ucmRldik7CgkJc2V0X2JpdChSMUJJT19EZWdyYWRlZCwgJnIxX2Jpby0+c3RhdGUpOwoJfQoJdXBkYXRlX2hlYWRfcG9zKG1pcnJvciwgcjFfYmlvKTsKCglpZiAoYXRvbWljX2RlY19hbmRfdGVzdCgmcjFfYmlvLT5yZW1haW5pbmcpKSB7CgkJbWRfZG9uZV9zeW5jKG1kZGV2LCByMV9iaW8tPnNlY3RvcnMsIHVwdG9kYXRlKTsKCQlwdXRfYnVmKHIxX2Jpbyk7Cgl9CglyZGV2X2RlY19wZW5kaW5nKGNvbmYtPm1pcnJvcnNbbWlycm9yXS5yZGV2LCBtZGRldik7CglyZXR1cm4gMDsKfQoKc3RhdGljIHZvaWQgc3luY19yZXF1ZXN0X3dyaXRlKG1kZGV2X3QgKm1kZGV2LCByMWJpb190ICpyMV9iaW8pCnsKCWNvbmZfdCAqY29uZiA9IG1kZGV2X3RvX2NvbmYobWRkZXYpOwoJaW50IGk7CglpbnQgZGlza3MgPSBjb25mLT5yYWlkX2Rpc2tzOwoJc3RydWN0IGJpbyAqYmlvLCAqd2JpbzsKCgliaW8gPSByMV9iaW8tPmJpb3NbcjFfYmlvLT5yZWFkX2Rpc2tdOwoKLyoKCWlmIChyMV9iaW8tPnNlY3RvciA9PSAwKSBwcmludGsoIkZpcnN0IHN5bmMgd3JpdGUgc3RhcnRzc1xuIik7CiovCgkvKgoJICogc2NoZWR1bGUgd3JpdGVzCgkgKi8KCWlmICghdGVzdF9iaXQoUjFCSU9fVXB0b2RhdGUsICZyMV9iaW8tPnN0YXRlKSkgewoJCS8qCgkJICogVGhlcmUgaXMgbm8gcG9pbnQgdHJ5aW5nIGEgcmVhZC1mb3ItcmVjb25zdHJ1Y3QgYXMKCQkgKiByZWNvbnN0cnVjdCBpcyBhYm91dCB0byBiZSBhYm9ydGVkCgkJICovCgkJY2hhciBiW0JERVZOQU1FX1NJWkVdOwoJCXByaW50ayhLRVJOX0FMRVJUICJyYWlkMTogJXM6IHVucmVjb3ZlcmFibGUgSS9PIHJlYWQgZXJyb3IiCgkJCSIgZm9yIGJsb2NrICVsbHVcbiIsCgkJCWJkZXZuYW1lKGJpby0+YmlfYmRldixiKSwgCgkJCSh1bnNpZ25lZCBsb25nIGxvbmcpcjFfYmlvLT5zZWN0b3IpOwoJCW1kX2RvbmVfc3luYyhtZGRldiwgcjFfYmlvLT5zZWN0b3JzLCAwKTsKCQlwdXRfYnVmKHIxX2Jpbyk7CgkJcmV0dXJuOwoJfQoKCWF0b21pY19zZXQoJnIxX2Jpby0+cmVtYWluaW5nLCAxKTsKCWZvciAoaSA9IDA7IGkgPCBkaXNrcyA7IGkrKykgewoJCXdiaW8gPSByMV9iaW8tPmJpb3NbaV07CgkJaWYgKHdiaW8tPmJpX2VuZF9pbyAhPSBlbmRfc3luY193cml0ZSkKCQkJY29udGludWU7CgoJCWF0b21pY19pbmMoJmNvbmYtPm1pcnJvcnNbaV0ucmRldi0+bnJfcGVuZGluZyk7CgkJYXRvbWljX2luYygmcjFfYmlvLT5yZW1haW5pbmcpOwoJCW1kX3N5bmNfYWNjdChjb25mLT5taXJyb3JzW2ldLnJkZXYtPmJkZXYsIHdiaW8tPmJpX3NpemUgPj4gOSk7CgoJCWdlbmVyaWNfbWFrZV9yZXF1ZXN0KHdiaW8pOwoJfQoKCWlmIChhdG9taWNfZGVjX2FuZF90ZXN0KCZyMV9iaW8tPnJlbWFpbmluZykpIHsKCQkvKiBpZiB3ZSdyZSBoZXJlLCBhbGwgd3JpdGUocykgaGF2ZSBjb21wbGV0ZWQsIHNvIGNsZWFuIHVwICovCgkJbWRfZG9uZV9zeW5jKG1kZGV2LCByMV9iaW8tPnNlY3RvcnMsIDEpOwoJCXB1dF9idWYocjFfYmlvKTsKCX0KfQoKLyoKICogVGhpcyBpcyBhIGtlcm5lbCB0aHJlYWQgd2hpY2g6CiAqCiAqCTEuCVJldHJpZXMgZmFpbGVkIHJlYWQgb3BlcmF0aW9ucyBvbiB3b3JraW5nIG1pcnJvcnMuCiAqCTIuCVVwZGF0ZXMgdGhlIHJhaWQgc3VwZXJibG9jayB3aGVuIHByb2JsZW1zIGVuY291bnRlci4KICoJMy4JUGVyZm9ybXMgd3JpdGVzIGZvbGxvd2luZyByZWFkcyBmb3IgYXJyYXkgc3luY3JvbmlzaW5nLgogKi8KCnN0YXRpYyB2b2lkIHJhaWQxZChtZGRldl90ICptZGRldikKewoJcjFiaW9fdCAqcjFfYmlvOwoJc3RydWN0IGJpbyAqYmlvOwoJdW5zaWduZWQgbG9uZyBmbGFnczsKCWNvbmZfdCAqY29uZiA9IG1kZGV2X3RvX2NvbmYobWRkZXYpOwoJc3RydWN0IGxpc3RfaGVhZCAqaGVhZCA9ICZjb25mLT5yZXRyeV9saXN0OwoJaW50IHVucGx1Zz0wOwoJbWRrX3JkZXZfdCAqcmRldjsKCgltZF9jaGVja19yZWNvdmVyeShtZGRldik7CgkKCWZvciAoOzspIHsKCQljaGFyIGJbQkRFVk5BTUVfU0laRV07CgkJc3Bpbl9sb2NrX2lycXNhdmUoJmNvbmYtPmRldmljZV9sb2NrLCBmbGFncyk7CgoJCWlmIChjb25mLT5wZW5kaW5nX2Jpb19saXN0LmhlYWQpIHsKCQkJYmlvID0gYmlvX2xpc3RfZ2V0KCZjb25mLT5wZW5kaW5nX2Jpb19saXN0KTsKCQkJYmxrX3JlbW92ZV9wbHVnKG1kZGV2LT5xdWV1ZSk7CgkJCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJmNvbmYtPmRldmljZV9sb2NrLCBmbGFncyk7CgkJCS8qIGZsdXNoIGFueSBwZW5kaW5nIGJpdG1hcCB3cml0ZXMgdG8gZGlzayBiZWZvcmUgcHJvY2VlZGluZyB3LyBJL08gKi8KCQkJaWYgKGJpdG1hcF91bnBsdWcobWRkZXYtPmJpdG1hcCkgIT0gMCkKCQkJCXByaW50aygiJXM6IGJpdG1hcCBmaWxlIHdyaXRlIGZhaWxlZCFcbiIsIG1kbmFtZShtZGRldikpOwoKCQkJd2hpbGUgKGJpbykgeyAvKiBzdWJtaXQgcGVuZGluZyB3cml0ZXMgKi8KCQkJCXN0cnVjdCBiaW8gKm5leHQgPSBiaW8tPmJpX25leHQ7CgkJCQliaW8tPmJpX25leHQgPSBOVUxMOwoJCQkJZ2VuZXJpY19tYWtlX3JlcXVlc3QoYmlvKTsKCQkJCWJpbyA9IG5leHQ7CgkJCX0KCQkJdW5wbHVnID0gMTsKCgkJCWNvbnRpbnVlOwoJCX0KCgkJaWYgKGxpc3RfZW1wdHkoaGVhZCkpCgkJCWJyZWFrOwoJCXIxX2JpbyA9IGxpc3RfZW50cnkoaGVhZC0+cHJldiwgcjFiaW9fdCwgcmV0cnlfbGlzdCk7CgkJbGlzdF9kZWwoaGVhZC0+cHJldik7CgkJc3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmY29uZi0+ZGV2aWNlX2xvY2ssIGZsYWdzKTsKCgkJbWRkZXYgPSByMV9iaW8tPm1kZGV2OwoJCWNvbmYgPSBtZGRldl90b19jb25mKG1kZGV2KTsKCQlpZiAodGVzdF9iaXQoUjFCSU9fSXNTeW5jLCAmcjFfYmlvLT5zdGF0ZSkpIHsKCQkJc3luY19yZXF1ZXN0X3dyaXRlKG1kZGV2LCByMV9iaW8pOwoJCQl1bnBsdWcgPSAxOwoJCX0gZWxzZSB7CgkJCWludCBkaXNrOwoJCQliaW8gPSByMV9iaW8tPmJpb3NbcjFfYmlvLT5yZWFkX2Rpc2tdOwoJCQlpZiAoKGRpc2s9cmVhZF9iYWxhbmNlKGNvbmYsIHIxX2JpbykpID09IC0xKSB7CgkJCQlwcmludGsoS0VSTl9BTEVSVCAicmFpZDE6ICVzOiB1bnJlY292ZXJhYmxlIEkvTyIKCQkJCSAgICAgICAiIHJlYWQgZXJyb3IgZm9yIGJsb2NrICVsbHVcbiIsCgkJCQkgICAgICAgYmRldm5hbWUoYmlvLT5iaV9iZGV2LGIpLAoJCQkJICAgICAgICh1bnNpZ25lZCBsb25nIGxvbmcpcjFfYmlvLT5zZWN0b3IpOwoJCQkJcmFpZF9lbmRfYmlvX2lvKHIxX2Jpbyk7CgkJCX0gZWxzZSB7CgkJCQlyMV9iaW8tPmJpb3NbcjFfYmlvLT5yZWFkX2Rpc2tdID0gTlVMTDsKCQkJCXIxX2Jpby0+cmVhZF9kaXNrID0gZGlzazsKCQkJCWJpb19wdXQoYmlvKTsKCQkJCWJpbyA9IGJpb19jbG9uZShyMV9iaW8tPm1hc3Rlcl9iaW8sIEdGUF9OT0lPKTsKCQkJCXIxX2Jpby0+Ymlvc1tyMV9iaW8tPnJlYWRfZGlza10gPSBiaW87CgkJCQlyZGV2ID0gY29uZi0+bWlycm9yc1tkaXNrXS5yZGV2OwoJCQkJaWYgKHByaW50a19yYXRlbGltaXQoKSkKCQkJCQlwcmludGsoS0VSTl9FUlIgInJhaWQxOiAlczogcmVkaXJlY3Rpbmcgc2VjdG9yICVsbHUgdG8iCgkJCQkJICAgICAgICIgYW5vdGhlciBtaXJyb3JcbiIsCgkJCQkJICAgICAgIGJkZXZuYW1lKHJkZXYtPmJkZXYsYiksCgkJCQkJICAgICAgICh1bnNpZ25lZCBsb25nIGxvbmcpcjFfYmlvLT5zZWN0b3IpOwoJCQkJYmlvLT5iaV9zZWN0b3IgPSByMV9iaW8tPnNlY3RvciArIHJkZXYtPmRhdGFfb2Zmc2V0OwoJCQkJYmlvLT5iaV9iZGV2ID0gcmRldi0+YmRldjsKCQkJCWJpby0+YmlfZW5kX2lvID0gcmFpZDFfZW5kX3JlYWRfcmVxdWVzdDsKCQkJCWJpby0+YmlfcncgPSBSRUFEOwoJCQkJYmlvLT5iaV9wcml2YXRlID0gcjFfYmlvOwoJCQkJdW5wbHVnID0gMTsKCQkJCWdlbmVyaWNfbWFrZV9yZXF1ZXN0KGJpbyk7CgkJCX0KCQl9Cgl9CglzcGluX3VubG9ja19pcnFyZXN0b3JlKCZjb25mLT5kZXZpY2VfbG9jaywgZmxhZ3MpOwoJaWYgKHVucGx1ZykKCQl1bnBsdWdfc2xhdmVzKG1kZGV2KTsKfQoKCnN0YXRpYyBpbnQgaW5pdF9yZXN5bmMoY29uZl90ICpjb25mKQp7CglpbnQgYnVmZnM7CgoJYnVmZnMgPSBSRVNZTkNfV0lORE9XIC8gUkVTWU5DX0JMT0NLX1NJWkU7CglpZiAoY29uZi0+cjFidWZfcG9vbCkKCQlCVUcoKTsKCWNvbmYtPnIxYnVmX3Bvb2wgPSBtZW1wb29sX2NyZWF0ZShidWZmcywgcjFidWZfcG9vbF9hbGxvYywgcjFidWZfcG9vbF9mcmVlLAoJCQkJCSAgY29uZi0+cG9vbGluZm8pOwoJaWYgKCFjb25mLT5yMWJ1Zl9wb29sKQoJCXJldHVybiAtRU5PTUVNOwoJY29uZi0+bmV4dF9yZXN5bmMgPSAwOwoJcmV0dXJuIDA7Cn0KCi8qCiAqIHBlcmZvcm0gYSAic3luYyIgb24gb25lICJibG9jayIKICoKICogV2UgbmVlZCB0byBtYWtlIHN1cmUgdGhhdCBubyBub3JtYWwgSS9PIHJlcXVlc3QgLSBwYXJ0aWN1bGFybHkgd3JpdGUKICogcmVxdWVzdHMgLSBjb25mbGljdCB3aXRoIGFjdGl2ZSBzeW5jIHJlcXVlc3RzLgogKgogKiBUaGlzIGlzIGFjaGlldmVkIGJ5IHRyYWNraW5nIHBlbmRpbmcgcmVxdWVzdHMgYW5kIGEgJ2JhcnJpZXInIGNvbmNlcHQKICogdGhhdCBjYW4gYmUgaW5zdGFsbGVkIHRvIGV4Y2x1ZGUgbm9ybWFsIElPIHJlcXVlc3RzLgogKi8KCnN0YXRpYyBzZWN0b3JfdCBzeW5jX3JlcXVlc3QobWRkZXZfdCAqbWRkZXYsIHNlY3Rvcl90IHNlY3Rvcl9uciwgaW50ICpza2lwcGVkLCBpbnQgZ29fZmFzdGVyKQp7Cgljb25mX3QgKmNvbmYgPSBtZGRldl90b19jb25mKG1kZGV2KTsKCW1pcnJvcl9pbmZvX3QgKm1pcnJvcjsKCXIxYmlvX3QgKnIxX2JpbzsKCXN0cnVjdCBiaW8gKmJpbzsKCXNlY3Rvcl90IG1heF9zZWN0b3IsIG5yX3NlY3RvcnM7CglpbnQgZGlzazsKCWludCBpOwoJaW50IHdyaXRlX3RhcmdldHMgPSAwOwoJaW50IHN5bmNfYmxvY2tzOwoKCWlmICghY29uZi0+cjFidWZfcG9vbCkKCXsKLyoKCQlwcmludGsoInN5bmMgc3RhcnQgLSBiaXRtYXAgJXBcbiIsIG1kZGV2LT5iaXRtYXApOwoqLwoJCWlmIChpbml0X3Jlc3luYyhjb25mKSkKCQkJcmV0dXJuIDA7Cgl9CgoJbWF4X3NlY3RvciA9IG1kZGV2LT5zaXplIDw8IDE7CglpZiAoc2VjdG9yX25yID49IG1heF9zZWN0b3IpIHsKCQkvKiBJZiB3ZSBhYm9ydGVkLCB3ZSBuZWVkIHRvIGFib3J0IHRoZQoJCSAqIHN5bmMgb24gdGhlICdjdXJyZW50JyBiaXRtYXAgY2h1bmsgKHRoZXJlIHdpbGwKCQkgKiBvbmx5IGJlIG9uZSBpbiByYWlkMSByZXN5bmMuCgkJICogV2UgY2FuIGZpbmQgdGhlIGN1cnJlbnQgYWRkZXNzIGluIG1kZGV2LT5jdXJyX3Jlc3luYwoJCSAqLwoJCWlmIChtZGRldi0+Y3Vycl9yZXN5bmMgPCBtYXhfc2VjdG9yKSAvKiBhYm9ydGVkICovCgkJCWJpdG1hcF9lbmRfc3luYyhtZGRldi0+Yml0bWFwLCBtZGRldi0+Y3Vycl9yZXN5bmMsCgkJCQkJCSZzeW5jX2Jsb2NrcywgMSk7CgkJZWxzZSAvKiBjb21wbGV0ZWQgc3luYyAqLwoJCQljb25mLT5mdWxsc3luYyA9IDA7CgoJCWJpdG1hcF9jbG9zZV9zeW5jKG1kZGV2LT5iaXRtYXApOwoJCWNsb3NlX3N5bmMoY29uZik7CgkJcmV0dXJuIDA7Cgl9CgoJaWYgKCFiaXRtYXBfc3RhcnRfc3luYyhtZGRldi0+Yml0bWFwLCBzZWN0b3JfbnIsICZzeW5jX2Jsb2NrcywgbWRkZXYtPmRlZ3JhZGVkKSAmJgoJICAgICFjb25mLT5mdWxsc3luYykgewoJCS8qIFdlIGNhbiBza2lwIHRoaXMgYmxvY2ssIGFuZCBwcm9iYWJseSBzZXZlcmFsIG1vcmUgKi8KCQkqc2tpcHBlZCA9IDE7CgkJcmV0dXJuIHN5bmNfYmxvY2tzOwoJfQoJLyoKCSAqIElmIHRoZXJlIGlzIG5vbi1yZXN5bmMgYWN0aXZpdHkgd2FpdGluZyBmb3IgdXMgdGhlbgoJICogcHV0IGluIGEgZGVsYXkgdG8gdGhyb3R0bGUgcmVzeW5jLgoJICovCglpZiAoIWdvX2Zhc3RlciAmJiB3YWl0cXVldWVfYWN0aXZlKCZjb25mLT53YWl0X3Jlc3VtZSkpCgkJbXNsZWVwX2ludGVycnVwdGlibGUoMTAwMCk7CglkZXZpY2VfYmFycmllcihjb25mLCBzZWN0b3JfbnIgKyBSRVNZTkNfU0VDVE9SUyk7CgoJLyoKCSAqIElmIHJlY29uc3RydWN0aW5nLCBhbmQgPjEgd29ya2luZyBkaXNjLAoJICogY291bGQgZGVkaWNhdGUgb25lIHRvIHJlYnVpbGQgYW5kIG90aGVycyB0bwoJICogc2VydmljZSByZWFkIHJlcXVlc3RzIC4uCgkgKi8KCWRpc2sgPSBjb25mLT5sYXN0X3VzZWQ7CgkvKiBtYWtlIHN1cmUgZGlzayBpcyBvcGVyYXRpb25hbCAqLwoKCXdoaWxlIChjb25mLT5taXJyb3JzW2Rpc2tdLnJkZXYgPT0gTlVMTCB8fAoJICAgICAgICFjb25mLT5taXJyb3JzW2Rpc2tdLnJkZXYtPmluX3N5bmMpIHsKCQlpZiAoZGlzayA8PSAwKQoJCQlkaXNrID0gY29uZi0+cmFpZF9kaXNrczsKCQlkaXNrLS07CgkJaWYgKGRpc2sgPT0gY29uZi0+bGFzdF91c2VkKQoJCQlicmVhazsKCX0KCWNvbmYtPmxhc3RfdXNlZCA9IGRpc2s7CglhdG9taWNfaW5jKCZjb25mLT5taXJyb3JzW2Rpc2tdLnJkZXYtPm5yX3BlbmRpbmcpOwoKCgltaXJyb3IgPSBjb25mLT5taXJyb3JzICsgZGlzazsKCglyMV9iaW8gPSBtZW1wb29sX2FsbG9jKGNvbmYtPnIxYnVmX3Bvb2wsIEdGUF9OT0lPKTsKCglzcGluX2xvY2tfaXJxKCZjb25mLT5yZXN5bmNfbG9jayk7Cgljb25mLT5ucl9wZW5kaW5nKys7CglzcGluX3VubG9ja19pcnEoJmNvbmYtPnJlc3luY19sb2NrKTsKCglyMV9iaW8tPm1kZGV2ID0gbWRkZXY7CglyMV9iaW8tPnNlY3RvciA9IHNlY3Rvcl9ucjsKCXIxX2Jpby0+c3RhdGUgPSAwOwoJc2V0X2JpdChSMUJJT19Jc1N5bmMsICZyMV9iaW8tPnN0YXRlKTsKCXIxX2Jpby0+cmVhZF9kaXNrID0gZGlzazsKCglmb3IgKGk9MDsgaSA8IGNvbmYtPnJhaWRfZGlza3M7IGkrKykgewoJCWJpbyA9IHIxX2Jpby0+Ymlvc1tpXTsKCgkJLyogdGFrZSBmcm9tIGJpb19pbml0ICovCgkJYmlvLT5iaV9uZXh0ID0gTlVMTDsKCQliaW8tPmJpX2ZsYWdzIHw9IDEgPDwgQklPX1VQVE9EQVRFOwoJCWJpby0+YmlfcncgPSAwOwoJCWJpby0+YmlfdmNudCA9IDA7CgkJYmlvLT5iaV9pZHggPSAwOwoJCWJpby0+YmlfcGh5c19zZWdtZW50cyA9IDA7CgkJYmlvLT5iaV9od19zZWdtZW50cyA9IDA7CgkJYmlvLT5iaV9zaXplID0gMDsKCQliaW8tPmJpX2VuZF9pbyA9IE5VTEw7CgkJYmlvLT5iaV9wcml2YXRlID0gTlVMTDsKCgkJaWYgKGkgPT0gZGlzaykgewoJCQliaW8tPmJpX3J3ID0gUkVBRDsKCQkJYmlvLT5iaV9lbmRfaW8gPSBlbmRfc3luY19yZWFkOwoJCX0gZWxzZSBpZiAoY29uZi0+bWlycm9yc1tpXS5yZGV2ICYmCgkJCSAgICFjb25mLT5taXJyb3JzW2ldLnJkZXYtPmZhdWx0eSAmJgoJCQkgICAoIWNvbmYtPm1pcnJvcnNbaV0ucmRldi0+aW5fc3luYyB8fAoJCQkgICAgc2VjdG9yX25yICsgUkVTWU5DX1NFQ1RPUlMgPiBtZGRldi0+cmVjb3ZlcnlfY3ApKSB7CgkJCWJpby0+YmlfcncgPSBXUklURTsKCQkJYmlvLT5iaV9lbmRfaW8gPSBlbmRfc3luY193cml0ZTsKCQkJd3JpdGVfdGFyZ2V0cyArKzsKCQl9IGVsc2UKCQkJY29udGludWU7CgkJYmlvLT5iaV9zZWN0b3IgPSBzZWN0b3JfbnIgKyBjb25mLT5taXJyb3JzW2ldLnJkZXYtPmRhdGFfb2Zmc2V0OwoJCWJpby0+YmlfYmRldiA9IGNvbmYtPm1pcnJvcnNbaV0ucmRldi0+YmRldjsKCQliaW8tPmJpX3ByaXZhdGUgPSByMV9iaW87Cgl9CgoJaWYgKHdyaXRlX3RhcmdldHMgKyAxIDwgY29uZi0+cmFpZF9kaXNrcykKCQkvKiBhcnJheSBkZWdyYWRlZCwgY2FuJ3QgY2xlYXIgYml0bWFwICovCgkJc2V0X2JpdChSMUJJT19EZWdyYWRlZCwgJnIxX2Jpby0+c3RhdGUpOwoKCWlmICh3cml0ZV90YXJnZXRzID09IDApIHsKCQkvKiBUaGVyZSBpcyBub3doZXJlIHRvIHdyaXRlLCBzbyBhbGwgbm9uLXN5bmMKCQkgKiBkcml2ZXMgbXVzdCBiZSBmYWlsZWQgLSBzbyB3ZSBhcmUgZmluaXNoZWQKCQkgKi8KCQlzZWN0b3JfdCBydiA9IG1heF9zZWN0b3IgLSBzZWN0b3JfbnI7CgkJKnNraXBwZWQgPSAxOwoJCXB1dF9idWYocjFfYmlvKTsKCQlyZGV2X2RlY19wZW5kaW5nKGNvbmYtPm1pcnJvcnNbZGlza10ucmRldiwgbWRkZXYpOwoJCXJldHVybiBydjsKCX0KCglucl9zZWN0b3JzID0gMDsKCXN5bmNfYmxvY2tzID0gMDsKCWRvIHsKCQlzdHJ1Y3QgcGFnZSAqcGFnZTsKCQlpbnQgbGVuID0gUEFHRV9TSVpFOwoJCWlmIChzZWN0b3JfbnIgKyAobGVuPj45KSA+IG1heF9zZWN0b3IpCgkJCWxlbiA9IChtYXhfc2VjdG9yIC0gc2VjdG9yX25yKSA8PCA5OwoJCWlmIChsZW4gPT0gMCkKCQkJYnJlYWs7CgkJaWYgKHN5bmNfYmxvY2tzID09IDApIHsKCQkJaWYgKCFiaXRtYXBfc3RhcnRfc3luYyhtZGRldi0+Yml0bWFwLCBzZWN0b3JfbnIsCgkJCQkJJnN5bmNfYmxvY2tzLCBtZGRldi0+ZGVncmFkZWQpICYmCgkJCQkJIWNvbmYtPmZ1bGxzeW5jKQoJCQkJYnJlYWs7CgkJCWlmIChzeW5jX2Jsb2NrcyA8IChQQUdFX1NJWkU+PjkpKQoJCQkJQlVHKCk7CgkJCWlmIChsZW4gPiAoc3luY19ibG9ja3M8PDkpKQoJCQkJbGVuID0gc3luY19ibG9ja3M8PDk7CgkJfQoKCQlmb3IgKGk9MCA7IGkgPCBjb25mLT5yYWlkX2Rpc2tzOyBpKyspIHsKCQkJYmlvID0gcjFfYmlvLT5iaW9zW2ldOwoJCQlpZiAoYmlvLT5iaV9lbmRfaW8pIHsKCQkJCXBhZ2UgPSByMV9iaW8tPmJpb3NbMF0tPmJpX2lvX3ZlY1tiaW8tPmJpX3ZjbnRdLmJ2X3BhZ2U7CgkJCQlpZiAoYmlvX2FkZF9wYWdlKGJpbywgcGFnZSwgbGVuLCAwKSA9PSAwKSB7CgkJCQkJLyogc3RvcCBoZXJlICovCgkJCQkJcjFfYmlvLT5iaW9zWzBdLT5iaV9pb192ZWNbYmlvLT5iaV92Y250XS5idl9wYWdlID0gcGFnZTsKCQkJCQl3aGlsZSAoaSA+IDApIHsKCQkJCQkJaS0tOwoJCQkJCQliaW8gPSByMV9iaW8tPmJpb3NbaV07CgkJCQkJCWlmIChiaW8tPmJpX2VuZF9pbz09TlVMTCkKCQkJCQkJCWNvbnRpbnVlOwoJCQkJCQkvKiByZW1vdmUgbGFzdCBwYWdlIGZyb20gdGhpcyBiaW8gKi8KCQkJCQkJYmlvLT5iaV92Y250LS07CgkJCQkJCWJpby0+Ymlfc2l6ZSAtPSBsZW47CgkJCQkJCWJpby0+YmlfZmxhZ3MgJj0gfigxPDwgQklPX1NFR19WQUxJRCk7CgkJCQkJfQoJCQkJCWdvdG8gYmlvX2Z1bGw7CgkJCQl9CgkJCX0KCQl9CgkJbnJfc2VjdG9ycyArPSBsZW4+Pjk7CgkJc2VjdG9yX25yICs9IGxlbj4+OTsKCQlzeW5jX2Jsb2NrcyAtPSAobGVuPj45KTsKCX0gd2hpbGUgKHIxX2Jpby0+Ymlvc1tkaXNrXS0+YmlfdmNudCA8IFJFU1lOQ19QQUdFUyk7CiBiaW9fZnVsbDoKCWJpbyA9IHIxX2Jpby0+Ymlvc1tkaXNrXTsKCXIxX2Jpby0+c2VjdG9ycyA9IG5yX3NlY3RvcnM7CgoJbWRfc3luY19hY2N0KG1pcnJvci0+cmRldi0+YmRldiwgbnJfc2VjdG9ycyk7CgoJZ2VuZXJpY19tYWtlX3JlcXVlc3QoYmlvKTsKCglyZXR1cm4gbnJfc2VjdG9yczsKfQoKc3RhdGljIGludCBydW4obWRkZXZfdCAqbWRkZXYpCnsKCWNvbmZfdCAqY29uZjsKCWludCBpLCBqLCBkaXNrX2lkeDsKCW1pcnJvcl9pbmZvX3QgKmRpc2s7CgltZGtfcmRldl90ICpyZGV2OwoJc3RydWN0IGxpc3RfaGVhZCAqdG1wOwoKCWlmIChtZGRldi0+bGV2ZWwgIT0gMSkgewoJCXByaW50aygicmFpZDE6ICVzOiByYWlkIGxldmVsIG5vdCBzZXQgdG8gbWlycm9yaW5nICglZClcbiIsCgkJICAgICAgIG1kbmFtZShtZGRldiksIG1kZGV2LT5sZXZlbCk7CgkJZ290byBvdXQ7Cgl9CgkvKgoJICogY29weSB0aGUgYWxyZWFkeSB2ZXJpZmllZCBkZXZpY2VzIGludG8gb3VyIHByaXZhdGUgUkFJRDEKCSAqIGJvb2trZWVwaW5nIGFyZWEuIFt3aGF0ZXZlciB3ZSBhbGxvY2F0ZSBpbiBydW4oKSwKCSAqIHNob3VsZCBiZSBmcmVlZCBpbiBzdG9wKCldCgkgKi8KCWNvbmYgPSBrbWFsbG9jKHNpemVvZihjb25mX3QpLCBHRlBfS0VSTkVMKTsKCW1kZGV2LT5wcml2YXRlID0gY29uZjsKCWlmICghY29uZikKCQlnb3RvIG91dF9ub19tZW07CgoJbWVtc2V0KGNvbmYsIDAsIHNpemVvZigqY29uZikpOwoJY29uZi0+bWlycm9ycyA9IGttYWxsb2Moc2l6ZW9mKHN0cnVjdCBtaXJyb3JfaW5mbykqbWRkZXYtPnJhaWRfZGlza3MsIAoJCQkJIEdGUF9LRVJORUwpOwoJaWYgKCFjb25mLT5taXJyb3JzKQoJCWdvdG8gb3V0X25vX21lbTsKCgltZW1zZXQoY29uZi0+bWlycm9ycywgMCwgc2l6ZW9mKHN0cnVjdCBtaXJyb3JfaW5mbykqbWRkZXYtPnJhaWRfZGlza3MpOwoKCWNvbmYtPnBvb2xpbmZvID0ga21hbGxvYyhzaXplb2YoKmNvbmYtPnBvb2xpbmZvKSwgR0ZQX0tFUk5FTCk7CglpZiAoIWNvbmYtPnBvb2xpbmZvKQoJCWdvdG8gb3V0X25vX21lbTsKCWNvbmYtPnBvb2xpbmZvLT5tZGRldiA9IG1kZGV2OwoJY29uZi0+cG9vbGluZm8tPnJhaWRfZGlza3MgPSBtZGRldi0+cmFpZF9kaXNrczsKCWNvbmYtPnIxYmlvX3Bvb2wgPSBtZW1wb29sX2NyZWF0ZShOUl9SQUlEMV9CSU9TLCByMWJpb19wb29sX2FsbG9jLAoJCQkJCSAgcjFiaW9fcG9vbF9mcmVlLAoJCQkJCSAgY29uZi0+cG9vbGluZm8pOwoJaWYgKCFjb25mLT5yMWJpb19wb29sKQoJCWdvdG8gb3V0X25vX21lbTsKCglJVEVSQVRFX1JERVYobWRkZXYsIHJkZXYsIHRtcCkgewoJCWRpc2tfaWR4ID0gcmRldi0+cmFpZF9kaXNrOwoJCWlmIChkaXNrX2lkeCA+PSBtZGRldi0+cmFpZF9kaXNrcwoJCSAgICB8fCBkaXNrX2lkeCA8IDApCgkJCWNvbnRpbnVlOwoJCWRpc2sgPSBjb25mLT5taXJyb3JzICsgZGlza19pZHg7CgoJCWRpc2stPnJkZXYgPSByZGV2OwoKCQlibGtfcXVldWVfc3RhY2tfbGltaXRzKG1kZGV2LT5xdWV1ZSwKCQkJCSAgICAgICByZGV2LT5iZGV2LT5iZF9kaXNrLT5xdWV1ZSk7CgkJLyogYXMgd2UgZG9uJ3QgaG9ub3VyIG1lcmdlX2J2ZWNfZm4sIHdlIG11c3QgbmV2ZXIgcmlzawoJCSAqIHZpb2xhdGluZyBpdCwgc28gbGltaXQgLT5tYXhfc2VjdG9yIHRvIG9uZSBQQUdFLCBhcwoJCSAqIGEgb25lIHBhZ2UgcmVxdWVzdCBpcyBuZXZlciBpbiB2aW9sYXRpb24uCgkJICovCgkJaWYgKHJkZXYtPmJkZXYtPmJkX2Rpc2stPnF1ZXVlLT5tZXJnZV9idmVjX2ZuICYmCgkJICAgIG1kZGV2LT5xdWV1ZS0+bWF4X3NlY3RvcnMgPiAoUEFHRV9TSVpFPj45KSkKCQkJYmxrX3F1ZXVlX21heF9zZWN0b3JzKG1kZGV2LT5xdWV1ZSwgUEFHRV9TSVpFPj45KTsKCgkJZGlzay0+aGVhZF9wb3NpdGlvbiA9IDA7CgkJaWYgKCFyZGV2LT5mYXVsdHkgJiYgcmRldi0+aW5fc3luYykKCQkJY29uZi0+d29ya2luZ19kaXNrcysrOwoJfQoJY29uZi0+cmFpZF9kaXNrcyA9IG1kZGV2LT5yYWlkX2Rpc2tzOwoJY29uZi0+bWRkZXYgPSBtZGRldjsKCXNwaW5fbG9ja19pbml0KCZjb25mLT5kZXZpY2VfbG9jayk7CglJTklUX0xJU1RfSEVBRCgmY29uZi0+cmV0cnlfbGlzdCk7CglpZiAoY29uZi0+d29ya2luZ19kaXNrcyA9PSAxKQoJCW1kZGV2LT5yZWNvdmVyeV9jcCA9IE1heFNlY3RvcjsKCglzcGluX2xvY2tfaW5pdCgmY29uZi0+cmVzeW5jX2xvY2spOwoJaW5pdF93YWl0cXVldWVfaGVhZCgmY29uZi0+d2FpdF9pZGxlKTsKCWluaXRfd2FpdHF1ZXVlX2hlYWQoJmNvbmYtPndhaXRfcmVzdW1lKTsKCgliaW9fbGlzdF9pbml0KCZjb25mLT5wZW5kaW5nX2Jpb19saXN0KTsKCWJpb19saXN0X2luaXQoJmNvbmYtPmZsdXNoaW5nX2Jpb19saXN0KTsKCglpZiAoIWNvbmYtPndvcmtpbmdfZGlza3MpIHsKCQlwcmludGsoS0VSTl9FUlIgInJhaWQxOiBubyBvcGVyYXRpb25hbCBtaXJyb3JzIGZvciAlc1xuIiwKCQkJbWRuYW1lKG1kZGV2KSk7CgkJZ290byBvdXRfZnJlZV9jb25mOwoJfQoKCW1kZGV2LT5kZWdyYWRlZCA9IDA7Cglmb3IgKGkgPSAwOyBpIDwgY29uZi0+cmFpZF9kaXNrczsgaSsrKSB7CgoJCWRpc2sgPSBjb25mLT5taXJyb3JzICsgaTsKCgkJaWYgKCFkaXNrLT5yZGV2KSB7CgkJCWRpc2stPmhlYWRfcG9zaXRpb24gPSAwOwoJCQltZGRldi0+ZGVncmFkZWQrKzsKCQl9Cgl9CgoJLyoKCSAqIGZpbmQgdGhlIGZpcnN0IHdvcmtpbmcgb25lIGFuZCB1c2UgaXQgYXMgYSBzdGFydGluZyBwb2ludAoJICogdG8gcmVhZCBiYWxhbmNpbmcuCgkgKi8KCWZvciAoaiA9IDA7IGogPCBjb25mLT5yYWlkX2Rpc2tzICYmCgkJICAgICAoIWNvbmYtPm1pcnJvcnNbal0ucmRldiB8fAoJCSAgICAgICFjb25mLT5taXJyb3JzW2pdLnJkZXYtPmluX3N5bmMpIDsgaisrKQoJCS8qIG5vdGhpbmcgKi87Cgljb25mLT5sYXN0X3VzZWQgPSBqOwoKCgltZGRldi0+dGhyZWFkID0gbWRfcmVnaXN0ZXJfdGhyZWFkKHJhaWQxZCwgbWRkZXYsICIlc19yYWlkMSIpOwoJaWYgKCFtZGRldi0+dGhyZWFkKSB7CgkJcHJpbnRrKEtFUk5fRVJSCgkJICAgICAgICJyYWlkMTogY291bGRuJ3QgYWxsb2NhdGUgdGhyZWFkIGZvciAlc1xuIiwKCQkgICAgICAgbWRuYW1lKG1kZGV2KSk7CgkJZ290byBvdXRfZnJlZV9jb25mOwoJfQoJaWYgKG1kZGV2LT5iaXRtYXApIG1kZGV2LT50aHJlYWQtPnRpbWVvdXQgPSBtZGRldi0+Yml0bWFwLT5kYWVtb25fc2xlZXAgKiBIWjsKCglwcmludGsoS0VSTl9JTkZPIAoJCSJyYWlkMTogcmFpZCBzZXQgJXMgYWN0aXZlIHdpdGggJWQgb3V0IG9mICVkIG1pcnJvcnNcbiIsCgkJbWRuYW1lKG1kZGV2KSwgbWRkZXYtPnJhaWRfZGlza3MgLSBtZGRldi0+ZGVncmFkZWQsIAoJCW1kZGV2LT5yYWlkX2Rpc2tzKTsKCS8qCgkgKiBPaywgZXZlcnl0aGluZyBpcyBqdXN0IGZpbmUgbm93CgkgKi8KCW1kZGV2LT5hcnJheV9zaXplID0gbWRkZXYtPnNpemU7CgoJbWRkZXYtPnF1ZXVlLT51bnBsdWdfZm4gPSByYWlkMV91bnBsdWc7CgltZGRldi0+cXVldWUtPmlzc3VlX2ZsdXNoX2ZuID0gcmFpZDFfaXNzdWVfZmx1c2g7CgoJcmV0dXJuIDA7CgpvdXRfbm9fbWVtOgoJcHJpbnRrKEtFUk5fRVJSICJyYWlkMTogY291bGRuJ3QgYWxsb2NhdGUgbWVtb3J5IGZvciAlc1xuIiwKCSAgICAgICBtZG5hbWUobWRkZXYpKTsKCm91dF9mcmVlX2NvbmY6CglpZiAoY29uZikgewoJCWlmIChjb25mLT5yMWJpb19wb29sKQoJCQltZW1wb29sX2Rlc3Ryb3koY29uZi0+cjFiaW9fcG9vbCk7CgkJa2ZyZWUoY29uZi0+bWlycm9ycyk7CgkJa2ZyZWUoY29uZi0+cG9vbGluZm8pOwoJCWtmcmVlKGNvbmYpOwoJCW1kZGV2LT5wcml2YXRlID0gTlVMTDsKCX0Kb3V0OgoJcmV0dXJuIC1FSU87Cn0KCnN0YXRpYyBpbnQgc3RvcChtZGRldl90ICptZGRldikKewoJY29uZl90ICpjb25mID0gbWRkZXZfdG9fY29uZihtZGRldik7CgoJbWRfdW5yZWdpc3Rlcl90aHJlYWQobWRkZXYtPnRocmVhZCk7CgltZGRldi0+dGhyZWFkID0gTlVMTDsKCWJsa19zeW5jX3F1ZXVlKG1kZGV2LT5xdWV1ZSk7IC8qIHRoZSB1bnBsdWcgZm4gcmVmZXJlbmNlcyAnY29uZicqLwoJaWYgKGNvbmYtPnIxYmlvX3Bvb2wpCgkJbWVtcG9vbF9kZXN0cm95KGNvbmYtPnIxYmlvX3Bvb2wpOwoJa2ZyZWUoY29uZi0+bWlycm9ycyk7CglrZnJlZShjb25mLT5wb29saW5mbyk7CglrZnJlZShjb25mKTsKCW1kZGV2LT5wcml2YXRlID0gTlVMTDsKCXJldHVybiAwOwp9CgpzdGF0aWMgaW50IHJhaWQxX3Jlc2l6ZShtZGRldl90ICptZGRldiwgc2VjdG9yX3Qgc2VjdG9ycykKewoJLyogbm8gcmVzeW5jIGlzIGhhcHBlbmluZywgYW5kIHRoZXJlIGlzIGVub3VnaCBzcGFjZQoJICogb24gYWxsIGRldmljZXMsIHNvIHdlIGNhbiByZXNpemUuCgkgKiBXZSBuZWVkIHRvIG1ha2Ugc3VyZSByZXN5bmMgY292ZXJzIGFueSBuZXcgc3BhY2UuCgkgKiBJZiB0aGUgYXJyYXkgaXMgc2hyaW5raW5nIHdlIHNob3VsZCBwb3NzaWJseSB3YWl0IHVudGlsCgkgKiBhbnkgaW8gaW4gdGhlIHJlbW92ZWQgc3BhY2UgY29tcGxldGVzLCBidXQgaXQgaGFyZGx5IHNlZW1zCgkgKiB3b3J0aCBpdC4KCSAqLwoJbWRkZXYtPmFycmF5X3NpemUgPSBzZWN0b3JzPj4xOwoJc2V0X2NhcGFjaXR5KG1kZGV2LT5nZW5kaXNrLCBtZGRldi0+YXJyYXlfc2l6ZSA8PCAxKTsKCW1kZGV2LT5jaGFuZ2VkID0gMTsKCWlmIChtZGRldi0+YXJyYXlfc2l6ZSA+IG1kZGV2LT5zaXplICYmIG1kZGV2LT5yZWNvdmVyeV9jcCA9PSBNYXhTZWN0b3IpIHsKCQltZGRldi0+cmVjb3ZlcnlfY3AgPSBtZGRldi0+c2l6ZSA8PCAxOwoJCXNldF9iaXQoTURfUkVDT1ZFUllfTkVFREVELCAmbWRkZXYtPnJlY292ZXJ5KTsKCX0KCW1kZGV2LT5zaXplID0gbWRkZXYtPmFycmF5X3NpemU7CgltZGRldi0+cmVzeW5jX21heF9zZWN0b3JzID0gc2VjdG9yczsKCXJldHVybiAwOwp9CgpzdGF0aWMgaW50IHJhaWQxX3Jlc2hhcGUobWRkZXZfdCAqbWRkZXYsIGludCByYWlkX2Rpc2tzKQp7CgkvKiBXZSBuZWVkIHRvOgoJICogMS8gcmVzaXplIHRoZSByMWJpb19wb29sCgkgKiAyLyByZXNpemUgY29uZi0+bWlycm9ycwoJICoKCSAqIFdlIGFsbG9jYXRlIGEgbmV3IHIxYmlvX3Bvb2wgaWYgd2UgY2FuLgoJICogVGhlbiByYWlzZSBhIGRldmljZSBiYXJyaWVyIGFuZCB3YWl0IHVudGlsIGFsbCBJTyBzdG9wcy4KCSAqIFRoZW4gcmVzaXplIGNvbmYtPm1pcnJvcnMgYW5kIHN3YXAgaW4gdGhlIG5ldyByMWJpbyBwb29sLgoJICoKCSAqIEF0IHRoZSBzYW1lIHRpbWUsIHdlICJwYWNrIiB0aGUgZGV2aWNlcyBzbyB0aGF0IGFsbCB0aGUgbWlzc2luZwoJICogZGV2aWNlcyBoYXZlIHRoZSBoaWdoZXIgcmFpZF9kaXNrIG51bWJlcnMuCgkgKi8KCW1lbXBvb2xfdCAqbmV3cG9vbCwgKm9sZHBvb2w7CglzdHJ1Y3QgcG9vbF9pbmZvICpuZXdwb29saW5mbzsKCW1pcnJvcl9pbmZvX3QgKm5ld21pcnJvcnM7Cgljb25mX3QgKmNvbmYgPSBtZGRldl90b19jb25mKG1kZGV2KTsKCWludCBjbnQ7CgoJaW50IGQsIGQyOwoKCWlmIChyYWlkX2Rpc2tzIDwgY29uZi0+cmFpZF9kaXNrcykgewoJCWNudD0wOwoJCWZvciAoZD0gMDsgZCA8IGNvbmYtPnJhaWRfZGlza3M7IGQrKykKCQkJaWYgKGNvbmYtPm1pcnJvcnNbZF0ucmRldikKCQkJCWNudCsrOwoJCWlmIChjbnQgPiByYWlkX2Rpc2tzKQoJCQlyZXR1cm4gLUVCVVNZOwoJfQoKCW5ld3Bvb2xpbmZvID0ga21hbGxvYyhzaXplb2YoKm5ld3Bvb2xpbmZvKSwgR0ZQX0tFUk5FTCk7CglpZiAoIW5ld3Bvb2xpbmZvKQoJCXJldHVybiAtRU5PTUVNOwoJbmV3cG9vbGluZm8tPm1kZGV2ID0gbWRkZXY7CgluZXdwb29saW5mby0+cmFpZF9kaXNrcyA9IHJhaWRfZGlza3M7CgoJbmV3cG9vbCA9IG1lbXBvb2xfY3JlYXRlKE5SX1JBSUQxX0JJT1MsIHIxYmlvX3Bvb2xfYWxsb2MsCgkJCQkgcjFiaW9fcG9vbF9mcmVlLCBuZXdwb29saW5mbyk7CglpZiAoIW5ld3Bvb2wpIHsKCQlrZnJlZShuZXdwb29saW5mbyk7CgkJcmV0dXJuIC1FTk9NRU07Cgl9CgluZXdtaXJyb3JzID0ga21hbGxvYyhzaXplb2Yoc3RydWN0IG1pcnJvcl9pbmZvKSAqIHJhaWRfZGlza3MsIEdGUF9LRVJORUwpOwoJaWYgKCFuZXdtaXJyb3JzKSB7CgkJa2ZyZWUobmV3cG9vbGluZm8pOwoJCW1lbXBvb2xfZGVzdHJveShuZXdwb29sKTsKCQlyZXR1cm4gLUVOT01FTTsKCX0KCW1lbXNldChuZXdtaXJyb3JzLCAwLCBzaXplb2Yoc3RydWN0IG1pcnJvcl9pbmZvKSpyYWlkX2Rpc2tzKTsKCglzcGluX2xvY2tfaXJxKCZjb25mLT5yZXN5bmNfbG9jayk7Cgljb25mLT5iYXJyaWVyKys7Cgl3YWl0X2V2ZW50X2xvY2tfaXJxKGNvbmYtPndhaXRfaWRsZSwgIWNvbmYtPm5yX3BlbmRpbmcsCgkJCSAgICBjb25mLT5yZXN5bmNfbG9jaywgcmFpZDFfdW5wbHVnKG1kZGV2LT5xdWV1ZSkpOwoJc3Bpbl91bmxvY2tfaXJxKCZjb25mLT5yZXN5bmNfbG9jayk7CgoJLyogb2ssIGV2ZXJ5dGhpbmcgaXMgc3RvcHBlZCAqLwoJb2xkcG9vbCA9IGNvbmYtPnIxYmlvX3Bvb2w7Cgljb25mLT5yMWJpb19wb29sID0gbmV3cG9vbDsKCglmb3IgKGQ9ZDI9MDsgZCA8IGNvbmYtPnJhaWRfZGlza3M7IGQrKykKCQlpZiAoY29uZi0+bWlycm9yc1tkXS5yZGV2KSB7CgkJCWNvbmYtPm1pcnJvcnNbZF0ucmRldi0+cmFpZF9kaXNrID0gZDI7CgkJCW5ld21pcnJvcnNbZDIrK10ucmRldiA9IGNvbmYtPm1pcnJvcnNbZF0ucmRldjsKCQl9CglrZnJlZShjb25mLT5taXJyb3JzKTsKCWNvbmYtPm1pcnJvcnMgPSBuZXdtaXJyb3JzOwoJa2ZyZWUoY29uZi0+cG9vbGluZm8pOwoJY29uZi0+cG9vbGluZm8gPSBuZXdwb29saW5mbzsKCgltZGRldi0+ZGVncmFkZWQgKz0gKHJhaWRfZGlza3MgLSBjb25mLT5yYWlkX2Rpc2tzKTsKCWNvbmYtPnJhaWRfZGlza3MgPSBtZGRldi0+cmFpZF9kaXNrcyA9IHJhaWRfZGlza3M7CgoJY29uZi0+bGFzdF91c2VkID0gMDsgLyoganVzdCBtYWtlIHN1cmUgaXQgaXMgaW4tcmFuZ2UgKi8KCXNwaW5fbG9ja19pcnEoJmNvbmYtPnJlc3luY19sb2NrKTsKCWNvbmYtPmJhcnJpZXItLTsKCXNwaW5fdW5sb2NrX2lycSgmY29uZi0+cmVzeW5jX2xvY2spOwoJd2FrZV91cCgmY29uZi0+d2FpdF9yZXN1bWUpOwoJd2FrZV91cCgmY29uZi0+d2FpdF9pZGxlKTsKCgoJc2V0X2JpdChNRF9SRUNPVkVSWV9ORUVERUQsICZtZGRldi0+cmVjb3ZlcnkpOwoJbWRfd2FrZXVwX3RocmVhZChtZGRldi0+dGhyZWFkKTsKCgltZW1wb29sX2Rlc3Ryb3kob2xkcG9vbCk7CglyZXR1cm4gMDsKfQoKCnN0YXRpYyBtZGtfcGVyc29uYWxpdHlfdCByYWlkMV9wZXJzb25hbGl0eSA9CnsKCS5uYW1lCQk9ICJyYWlkMSIsCgkub3duZXIJCT0gVEhJU19NT0RVTEUsCgkubWFrZV9yZXF1ZXN0CT0gbWFrZV9yZXF1ZXN0LAoJLnJ1bgkJPSBydW4sCgkuc3RvcAkJPSBzdG9wLAoJLnN0YXR1cwkJPSBzdGF0dXMsCgkuZXJyb3JfaGFuZGxlcgk9IGVycm9yLAoJLmhvdF9hZGRfZGlzawk9IHJhaWQxX2FkZF9kaXNrLAoJLmhvdF9yZW1vdmVfZGlzaz0gcmFpZDFfcmVtb3ZlX2Rpc2ssCgkuc3BhcmVfYWN0aXZlCT0gcmFpZDFfc3BhcmVfYWN0aXZlLAoJLnN5bmNfcmVxdWVzdAk9IHN5bmNfcmVxdWVzdCwKCS5yZXNpemUJCT0gcmFpZDFfcmVzaXplLAoJLnJlc2hhcGUJPSByYWlkMV9yZXNoYXBlLAp9OwoKc3RhdGljIGludCBfX2luaXQgcmFpZF9pbml0KHZvaWQpCnsKCXJldHVybiByZWdpc3Rlcl9tZF9wZXJzb25hbGl0eShSQUlEMSwgJnJhaWQxX3BlcnNvbmFsaXR5KTsKfQoKc3RhdGljIHZvaWQgcmFpZF9leGl0KHZvaWQpCnsKCXVucmVnaXN0ZXJfbWRfcGVyc29uYWxpdHkoUkFJRDEpOwp9Cgptb2R1bGVfaW5pdChyYWlkX2luaXQpOwptb2R1bGVfZXhpdChyYWlkX2V4aXQpOwpNT0RVTEVfTElDRU5TRSgiR1BMIik7Ck1PRFVMRV9BTElBUygibWQtcGVyc29uYWxpdHktMyIpOyAvKiBSQUlEMSAqLwo=