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+cmVhZF9kaXNrLCByMV9iaW8pOwoJLyoKCSAqIHdlIGhhdmUgcmVhZCBhIGJsb2NrLCBub3cgaXQgbmVlZHMgdG8gYmUgcmUtd3JpdHRlbiwKCSAqIG9yIHJlLXJlYWQgaWYgdGhlIHJlYWQgZmFpbGVkLgoJICogV2UgZG9uJ3QgZG8gbXVjaCBoZXJlLCBqdXN0IHNjaGVkdWxlIGhhbmRsaW5nIGJ5IHJhaWQxZAoJICovCglpZiAoIXVwdG9kYXRlKSB7CgkJbWRfZXJyb3IocjFfYmlvLT5tZGRldiwKCQkJIGNvbmYtPm1pcnJvcnNbcjFfYmlvLT5yZWFkX2Rpc2tdLnJkZXYpOwoJfSBlbHNlCgkJc2V0X2JpdChSMUJJT19VcHRvZGF0ZSwgJnIxX2Jpby0+c3RhdGUpOwoJcmRldl9kZWNfcGVuZGluZyhjb25mLT5taXJyb3JzW3IxX2Jpby0+cmVhZF9kaXNrXS5yZGV2LCBjb25mLT5tZGRldik7CglyZXNjaGVkdWxlX3JldHJ5KHIxX2Jpbyk7CglyZXR1cm4gMDsKfQoKc3RhdGljIGludCBlbmRfc3luY193cml0ZShzdHJ1Y3QgYmlvICpiaW8sIHVuc2lnbmVkIGludCBieXRlc19kb25lLCBpbnQgZXJyb3IpCnsKCWludCB1cHRvZGF0ZSA9IHRlc3RfYml0KEJJT19VUFRPREFURSwgJmJpby0+YmlfZmxhZ3MpOwoJcjFiaW9fdCAqIHIxX2JpbyA9IChyMWJpb190ICopKGJpby0+YmlfcHJpdmF0ZSk7CgltZGRldl90ICptZGRldiA9IHIxX2Jpby0+bWRkZXY7Cgljb25mX3QgKmNvbmYgPSBtZGRldl90b19jb25mKG1kZGV2KTsKCWludCBpOwoJaW50IG1pcnJvcj0wOwoKCWlmIChiaW8tPmJpX3NpemUpCgkJcmV0dXJuIDE7CgoJZm9yIChpID0gMDsgaSA8IGNvbmYtPnJhaWRfZGlza3M7IGkrKykKCQlpZiAocjFfYmlvLT5iaW9zW2ldID09IGJpbykgewoJCQltaXJyb3IgPSBpOwoJCQlicmVhazsKCQl9CglpZiAoIXVwdG9kYXRlKQoJCW1kX2Vycm9yKG1kZGV2LCBjb25mLT5taXJyb3JzW21pcnJvcl0ucmRldik7CgoJdXBkYXRlX2hlYWRfcG9zKG1pcnJvciwgcjFfYmlvKTsKCglpZiAoYXRvbWljX2RlY19hbmRfdGVzdCgmcjFfYmlvLT5yZW1haW5pbmcpKSB7CgkJbWRfZG9uZV9zeW5jKG1kZGV2LCByMV9iaW8tPnNlY3RvcnMsIHVwdG9kYXRlKTsKCQlwdXRfYnVmKHIxX2Jpbyk7Cgl9CglyZGV2X2RlY19wZW5kaW5nKGNvbmYtPm1pcnJvcnNbbWlycm9yXS5yZGV2LCBtZGRldik7CglyZXR1cm4gMDsKfQoKc3RhdGljIHZvaWQgc3luY19yZXF1ZXN0X3dyaXRlKG1kZGV2X3QgKm1kZGV2LCByMWJpb190ICpyMV9iaW8pCnsKCWNvbmZfdCAqY29uZiA9IG1kZGV2X3RvX2NvbmYobWRkZXYpOwoJaW50IGk7CglpbnQgZGlza3MgPSBjb25mLT5yYWlkX2Rpc2tzOwoJc3RydWN0IGJpbyAqYmlvLCAqd2JpbzsKCgliaW8gPSByMV9iaW8tPmJpb3NbcjFfYmlvLT5yZWFkX2Rpc2tdOwoKLyoKCWlmIChyMV9iaW8tPnNlY3RvciA9PSAwKSBwcmludGsoIkZpcnN0IHN5bmMgd3JpdGUgc3RhcnRzc1xuIik7CiovCgkvKgoJICogc2NoZWR1bGUgd3JpdGVzCgkgKi8KCWlmICghdGVzdF9iaXQoUjFCSU9fVXB0b2RhdGUsICZyMV9iaW8tPnN0YXRlKSkgewoJCS8qCgkJICogVGhlcmUgaXMgbm8gcG9pbnQgdHJ5aW5nIGEgcmVhZC1mb3ItcmVjb25zdHJ1Y3QgYXMKCQkgKiByZWNvbnN0cnVjdCBpcyBhYm91dCB0byBiZSBhYm9ydGVkCgkJICovCgkJY2hhciBiW0JERVZOQU1FX1NJWkVdOwoJCXByaW50ayhLRVJOX0FMRVJUICJyYWlkMTogJXM6IHVucmVjb3ZlcmFibGUgSS9PIHJlYWQgZXJyb3IiCgkJCSIgZm9yIGJsb2NrICVsbHVcbiIsCgkJCWJkZXZuYW1lKGJpby0+YmlfYmRldixiKSwgCgkJCSh1bnNpZ25lZCBsb25nIGxvbmcpcjFfYmlvLT5zZWN0b3IpOwoJCW1kX2RvbmVfc3luYyhtZGRldiwgcjFfYmlvLT5zZWN0b3JzLCAwKTsKCQlwdXRfYnVmKHIxX2Jpbyk7CgkJcmV0dXJuOwoJfQoKCWF0b21pY19zZXQoJnIxX2Jpby0+cmVtYWluaW5nLCAxKTsKCWZvciAoaSA9IDA7IGkgPCBkaXNrcyA7IGkrKykgewoJCXdiaW8gPSByMV9iaW8tPmJpb3NbaV07CgkJaWYgKHdiaW8tPmJpX2VuZF9pbyAhPSBlbmRfc3luY193cml0ZSkKCQkJY29udGludWU7CgoJCWF0b21pY19pbmMoJmNvbmYtPm1pcnJvcnNbaV0ucmRldi0+bnJfcGVuZGluZyk7CgkJYXRvbWljX2luYygmcjFfYmlvLT5yZW1haW5pbmcpOwoJCW1kX3N5bmNfYWNjdChjb25mLT5taXJyb3JzW2ldLnJkZXYtPmJkZXYsIHdiaW8tPmJpX3NpemUgPj4gOSk7CgoJCWdlbmVyaWNfbWFrZV9yZXF1ZXN0KHdiaW8pOwoJfQoKCWlmIChhdG9taWNfZGVjX2FuZF90ZXN0KCZyMV9iaW8tPnJlbWFpbmluZykpIHsKCQkvKiBpZiB3ZSdyZSBoZXJlLCBhbGwgd3JpdGUocykgaGF2ZSBjb21wbGV0ZWQsIHNvIGNsZWFuIHVwICovCgkJbWRfZG9uZV9zeW5jKG1kZGV2LCByMV9iaW8tPnNlY3RvcnMsIDEpOwoJCXB1dF9idWYocjFfYmlvKTsKCX0KfQoKLyoKICogVGhpcyBpcyBhIGtlcm5lbCB0aHJlYWQgd2hpY2g6CiAqCiAqCTEuCVJldHJpZXMgZmFpbGVkIHJlYWQgb3BlcmF0aW9ucyBvbiB3b3JraW5nIG1pcnJvcnMuCiAqCTIuCVVwZGF0ZXMgdGhlIHJhaWQgc3VwZXJibG9jayB3aGVuIHByb2JsZW1zIGVuY291bnRlci4KICoJMy4JUGVyZm9ybXMgd3JpdGVzIGZvbGxvd2luZyByZWFkcyBmb3IgYXJyYXkgc3luY3JvbmlzaW5nLgogKi8KCnN0YXRpYyB2b2lkIHJhaWQxZChtZGRldl90ICptZGRldikKewoJcjFiaW9fdCAqcjFfYmlvOwoJc3RydWN0IGJpbyAqYmlvOwoJdW5zaWduZWQgbG9uZyBmbGFnczsKCWNvbmZfdCAqY29uZiA9IG1kZGV2X3RvX2NvbmYobWRkZXYpOwoJc3RydWN0IGxpc3RfaGVhZCAqaGVhZCA9ICZjb25mLT5yZXRyeV9saXN0OwoJaW50IHVucGx1Zz0wOwoJbWRrX3JkZXZfdCAqcmRldjsKCgltZF9jaGVja19yZWNvdmVyeShtZGRldik7CgkKCWZvciAoOzspIHsKCQljaGFyIGJbQkRFVk5BTUVfU0laRV07CgkJc3Bpbl9sb2NrX2lycXNhdmUoJmNvbmYtPmRldmljZV9sb2NrLCBmbGFncyk7CgoJCWlmIChjb25mLT5wZW5kaW5nX2Jpb19saXN0LmhlYWQpIHsKCQkJYmlvID0gYmlvX2xpc3RfZ2V0KCZjb25mLT5wZW5kaW5nX2Jpb19saXN0KTsKCQkJYmxrX3JlbW92ZV9wbHVnKG1kZGV2LT5xdWV1ZSk7CgkJCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJmNvbmYtPmRldmljZV9sb2NrLCBmbGFncyk7CgkJCS8qIGZsdXNoIGFueSBwZW5kaW5nIGJpdG1hcCB3cml0ZXMgdG8gZGlzayBiZWZvcmUgcHJvY2VlZGluZyB3LyBJL08gKi8KCQkJaWYgKGJpdG1hcF91bnBsdWcobWRkZXYtPmJpdG1hcCkgIT0gMCkKCQkJCXByaW50aygiJXM6IGJpdG1hcCBmaWxlIHdyaXRlIGZhaWxlZCFcbiIsIG1kbmFtZShtZGRldikpOwoKCQkJd2hpbGUgKGJpbykgeyAvKiBzdWJtaXQgcGVuZGluZyB3cml0ZXMgKi8KCQkJCXN0cnVjdCBiaW8gKm5leHQgPSBiaW8tPmJpX25leHQ7CgkJCQliaW8tPmJpX25leHQgPSBOVUxMOwoJCQkJZ2VuZXJpY19tYWtlX3JlcXVlc3QoYmlvKTsKCQkJCWJpbyA9IG5leHQ7CgkJCX0KCQkJdW5wbHVnID0gMTsKCgkJCWNvbnRpbnVlOwoJCX0KCgkJaWYgKGxpc3RfZW1wdHkoaGVhZCkpCgkJCWJyZWFrOwoJCXIxX2JpbyA9IGxpc3RfZW50cnkoaGVhZC0+cHJldiwgcjFiaW9fdCwgcmV0cnlfbGlzdCk7CgkJbGlzdF9kZWwoaGVhZC0+cHJldik7CgkJc3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmY29uZi0+ZGV2aWNlX2xvY2ssIGZsYWdzKTsKCgkJbWRkZXYgPSByMV9iaW8tPm1kZGV2OwoJCWNvbmYgPSBtZGRldl90b19jb25mKG1kZGV2KTsKCQlpZiAodGVzdF9iaXQoUjFCSU9fSXNTeW5jLCAmcjFfYmlvLT5zdGF0ZSkpIHsKCQkJc3luY19yZXF1ZXN0X3dyaXRlKG1kZGV2LCByMV9iaW8pOwoJCQl1bnBsdWcgPSAxOwoJCX0gZWxzZSB7CgkJCWludCBkaXNrOwoJCQliaW8gPSByMV9iaW8tPmJpb3NbcjFfYmlvLT5yZWFkX2Rpc2tdOwoJCQlpZiAoKGRpc2s9cmVhZF9iYWxhbmNlKGNvbmYsIHIxX2JpbykpID09IC0xKSB7CgkJCQlwcmludGsoS0VSTl9BTEVSVCAicmFpZDE6ICVzOiB1bnJlY292ZXJhYmxlIEkvTyIKCQkJCSAgICAgICAiIHJlYWQgZXJyb3IgZm9yIGJsb2NrICVsbHVcbiIsCgkJCQkgICAgICAgYmRldm5hbWUoYmlvLT5iaV9iZGV2LGIpLAoJCQkJICAgICAgICh1bnNpZ25lZCBsb25nIGxvbmcpcjFfYmlvLT5zZWN0b3IpOwoJCQkJcmFpZF9lbmRfYmlvX2lvKHIxX2Jpbyk7CgkJCX0gZWxzZSB7CgkJCQlyMV9iaW8tPmJpb3NbcjFfYmlvLT5yZWFkX2Rpc2tdID0gTlVMTDsKCQkJCXIxX2Jpby0+cmVhZF9kaXNrID0gZGlzazsKCQkJCWJpb19wdXQoYmlvKTsKCQkJCWJpbyA9IGJpb19jbG9uZShyMV9iaW8tPm1hc3Rlcl9iaW8sIEdGUF9OT0lPKTsKCQkJCXIxX2Jpby0+Ymlvc1tyMV9iaW8tPnJlYWRfZGlza10gPSBiaW87CgkJCQlyZGV2ID0gY29uZi0+bWlycm9yc1tkaXNrXS5yZGV2OwoJCQkJaWYgKHByaW50a19yYXRlbGltaXQoKSkKCQkJCQlwcmludGsoS0VSTl9FUlIgInJhaWQxOiAlczogcmVkaXJlY3Rpbmcgc2VjdG9yICVsbHUgdG8iCgkJCQkJICAgICAgICIgYW5vdGhlciBtaXJyb3JcbiIsCgkJCQkJICAgICAgIGJkZXZuYW1lKHJkZXYtPmJkZXYsYiksCgkJCQkJICAgICAgICh1bnNpZ25lZCBsb25nIGxvbmcpcjFfYmlvLT5zZWN0b3IpOwoJCQkJYmlvLT5iaV9zZWN0b3IgPSByMV9iaW8tPnNlY3RvciArIHJkZXYtPmRhdGFfb2Zmc2V0OwoJCQkJYmlvLT5iaV9iZGV2ID0gcmRldi0+YmRldjsKCQkJCWJpby0+YmlfZW5kX2lvID0gcmFpZDFfZW5kX3JlYWRfcmVxdWVzdDsKCQkJCWJpby0+YmlfcncgPSBSRUFEOwoJCQkJYmlvLT5iaV9wcml2YXRlID0gcjFfYmlvOwoJCQkJdW5wbHVnID0gMTsKCQkJCWdlbmVyaWNfbWFrZV9yZXF1ZXN0KGJpbyk7CgkJCX0KCQl9Cgl9CglzcGluX3VubG9ja19pcnFyZXN0b3JlKCZjb25mLT5kZXZpY2VfbG9jaywgZmxhZ3MpOwoJaWYgKHVucGx1ZykKCQl1bnBsdWdfc2xhdmVzKG1kZGV2KTsKfQoKCnN0YXRpYyBpbnQgaW5pdF9yZXN5bmMoY29uZl90ICpjb25mKQp7CglpbnQgYnVmZnM7CgoJYnVmZnMgPSBSRVNZTkNfV0lORE9XIC8gUkVTWU5DX0JMT0NLX1NJWkU7CglpZiAoY29uZi0+cjFidWZfcG9vbCkKCQlCVUcoKTsKCWNvbmYtPnIxYnVmX3Bvb2wgPSBtZW1wb29sX2NyZWF0ZShidWZmcywgcjFidWZfcG9vbF9hbGxvYywgcjFidWZfcG9vbF9mcmVlLAoJCQkJCSAgY29uZi0+cG9vbGluZm8pOwoJaWYgKCFjb25mLT5yMWJ1Zl9wb29sKQoJCXJldHVybiAtRU5PTUVNOwoJY29uZi0+bmV4dF9yZXN5bmMgPSAwOwoJcmV0dXJuIDA7Cn0KCi8qCiAqIHBlcmZvcm0gYSAic3luYyIgb24gb25lICJibG9jayIKICoKICogV2UgbmVlZCB0byBtYWtlIHN1cmUgdGhhdCBubyBub3JtYWwgSS9PIHJlcXVlc3QgLSBwYXJ0aWN1bGFybHkgd3JpdGUKICogcmVxdWVzdHMgLSBjb25mbGljdCB3aXRoIGFjdGl2ZSBzeW5jIHJlcXVlc3RzLgogKgogKiBUaGlzIGlzIGFjaGlldmVkIGJ5IHRyYWNraW5nIHBlbmRpbmcgcmVxdWVzdHMgYW5kIGEgJ2JhcnJpZXInIGNvbmNlcHQKICogdGhhdCBjYW4gYmUgaW5zdGFsbGVkIHRvIGV4Y2x1ZGUgbm9ybWFsIElPIHJlcXVlc3RzLgogKi8KCnN0YXRpYyBzZWN0b3JfdCBzeW5jX3JlcXVlc3QobWRkZXZfdCAqbWRkZXYsIHNlY3Rvcl90IHNlY3Rvcl9uciwgaW50ICpza2lwcGVkLCBpbnQgZ29fZmFzdGVyKQp7Cgljb25mX3QgKmNvbmYgPSBtZGRldl90b19jb25mKG1kZGV2KTsKCW1pcnJvcl9pbmZvX3QgKm1pcnJvcjsKCXIxYmlvX3QgKnIxX2JpbzsKCXN0cnVjdCBiaW8gKmJpbzsKCXNlY3Rvcl90IG1heF9zZWN0b3IsIG5yX3NlY3RvcnM7CglpbnQgZGlzazsKCWludCBpOwoJaW50IHdyaXRlX3RhcmdldHMgPSAwOwoJaW50IHN5bmNfYmxvY2tzOwoJaW50IHN0aWxsX2RlZ3JhZGVkID0gMDsKCglpZiAoIWNvbmYtPnIxYnVmX3Bvb2wpCgl7Ci8qCgkJcHJpbnRrKCJzeW5jIHN0YXJ0IC0gYml0bWFwICVwXG4iLCBtZGRldi0+Yml0bWFwKTsKKi8KCQlpZiAoaW5pdF9yZXN5bmMoY29uZikpCgkJCXJldHVybiAwOwoJfQoKCW1heF9zZWN0b3IgPSBtZGRldi0+c2l6ZSA8PCAxOwoJaWYgKHNlY3Rvcl9uciA+PSBtYXhfc2VjdG9yKSB7CgkJLyogSWYgd2UgYWJvcnRlZCwgd2UgbmVlZCB0byBhYm9ydCB0aGUKCQkgKiBzeW5jIG9uIHRoZSAnY3VycmVudCcgYml0bWFwIGNodW5rICh0aGVyZSB3aWxsCgkJICogb25seSBiZSBvbmUgaW4gcmFpZDEgcmVzeW5jLgoJCSAqIFdlIGNhbiBmaW5kIHRoZSBjdXJyZW50IGFkZGVzcyBpbiBtZGRldi0+Y3Vycl9yZXN5bmMKCQkgKi8KCQlpZiAobWRkZXYtPmN1cnJfcmVzeW5jIDwgbWF4X3NlY3RvcikgLyogYWJvcnRlZCAqLwoJCQliaXRtYXBfZW5kX3N5bmMobWRkZXYtPmJpdG1hcCwgbWRkZXYtPmN1cnJfcmVzeW5jLAoJCQkJCQkmc3luY19ibG9ja3MsIDEpOwoJCWVsc2UgLyogY29tcGxldGVkIHN5bmMgKi8KCQkJY29uZi0+ZnVsbHN5bmMgPSAwOwoKCQliaXRtYXBfY2xvc2Vfc3luYyhtZGRldi0+Yml0bWFwKTsKCQljbG9zZV9zeW5jKGNvbmYpOwoJCXJldHVybiAwOwoJfQoKCS8qIGJlZm9yZSBidWlsZGluZyBhIHJlcXVlc3QsIGNoZWNrIGlmIHdlIGNhbiBza2lwIHRoZXNlIGJsb2Nrcy4uCgkgKiBUaGlzIGNhbGwgdGhlIGJpdG1hcF9zdGFydF9zeW5jIGRvZXNuJ3QgYWN0dWFsbHkgcmVjb3JkIGFueXRoaW5nCgkgKi8KCWlmICghYml0bWFwX3N0YXJ0X3N5bmMobWRkZXYtPmJpdG1hcCwgc2VjdG9yX25yLCAmc3luY19ibG9ja3MsIDEpICYmCgkgICAgIWNvbmYtPmZ1bGxzeW5jKSB7CgkJLyogV2UgY2FuIHNraXAgdGhpcyBibG9jaywgYW5kIHByb2JhYmx5IHNldmVyYWwgbW9yZSAqLwoJCSpza2lwcGVkID0gMTsKCQlyZXR1cm4gc3luY19ibG9ja3M7Cgl9CgkvKgoJICogSWYgdGhlcmUgaXMgbm9uLXJlc3luYyBhY3Rpdml0eSB3YWl0aW5nIGZvciB1cyB0aGVuCgkgKiBwdXQgaW4gYSBkZWxheSB0byB0aHJvdHRsZSByZXN5bmMuCgkgKi8KCWlmICghZ29fZmFzdGVyICYmIHdhaXRxdWV1ZV9hY3RpdmUoJmNvbmYtPndhaXRfcmVzdW1lKSkKCQltc2xlZXBfaW50ZXJydXB0aWJsZSgxMDAwKTsKCWRldmljZV9iYXJyaWVyKGNvbmYsIHNlY3Rvcl9uciArIFJFU1lOQ19TRUNUT1JTKTsKCgkvKgoJICogSWYgcmVjb25zdHJ1Y3RpbmcsIGFuZCA+MSB3b3JraW5nIGRpc2MsCgkgKiBjb3VsZCBkZWRpY2F0ZSBvbmUgdG8gcmVidWlsZCBhbmQgb3RoZXJzIHRvCgkgKiBzZXJ2aWNlIHJlYWQgcmVxdWVzdHMgLi4KCSAqLwoJZGlzayA9IGNvbmYtPmxhc3RfdXNlZDsKCS8qIG1ha2Ugc3VyZSBkaXNrIGlzIG9wZXJhdGlvbmFsICovCgoJd2hpbGUgKGNvbmYtPm1pcnJvcnNbZGlza10ucmRldiA9PSBOVUxMIHx8CgkgICAgICAgIWNvbmYtPm1pcnJvcnNbZGlza10ucmRldi0+aW5fc3luYykgewoJCWlmIChkaXNrIDw9IDApCgkJCWRpc2sgPSBjb25mLT5yYWlkX2Rpc2tzOwoJCWRpc2stLTsKCQlpZiAoZGlzayA9PSBjb25mLT5sYXN0X3VzZWQpCgkJCWJyZWFrOwoJfQoJY29uZi0+bGFzdF91c2VkID0gZGlzazsKCWF0b21pY19pbmMoJmNvbmYtPm1pcnJvcnNbZGlza10ucmRldi0+bnJfcGVuZGluZyk7CgoKCW1pcnJvciA9IGNvbmYtPm1pcnJvcnMgKyBkaXNrOwoKCXIxX2JpbyA9IG1lbXBvb2xfYWxsb2MoY29uZi0+cjFidWZfcG9vbCwgR0ZQX05PSU8pOwoKCXNwaW5fbG9ja19pcnEoJmNvbmYtPnJlc3luY19sb2NrKTsKCWNvbmYtPm5yX3BlbmRpbmcrKzsKCXNwaW5fdW5sb2NrX2lycSgmY29uZi0+cmVzeW5jX2xvY2spOwoKCXIxX2Jpby0+bWRkZXYgPSBtZGRldjsKCXIxX2Jpby0+c2VjdG9yID0gc2VjdG9yX25yOwoJcjFfYmlvLT5zdGF0ZSA9IDA7CglzZXRfYml0KFIxQklPX0lzU3luYywgJnIxX2Jpby0+c3RhdGUpOwoJcjFfYmlvLT5yZWFkX2Rpc2sgPSBkaXNrOwoKCWZvciAoaT0wOyBpIDwgY29uZi0+cmFpZF9kaXNrczsgaSsrKSB7CgkJYmlvID0gcjFfYmlvLT5iaW9zW2ldOwoKCQkvKiB0YWtlIGZyb20gYmlvX2luaXQgKi8KCQliaW8tPmJpX25leHQgPSBOVUxMOwoJCWJpby0+YmlfZmxhZ3MgfD0gMSA8PCBCSU9fVVBUT0RBVEU7CgkJYmlvLT5iaV9ydyA9IDA7CgkJYmlvLT5iaV92Y250ID0gMDsKCQliaW8tPmJpX2lkeCA9IDA7CgkJYmlvLT5iaV9waHlzX3NlZ21lbnRzID0gMDsKCQliaW8tPmJpX2h3X3NlZ21lbnRzID0gMDsKCQliaW8tPmJpX3NpemUgPSAwOwoJCWJpby0+YmlfZW5kX2lvID0gTlVMTDsKCQliaW8tPmJpX3ByaXZhdGUgPSBOVUxMOwoKCQlpZiAoaSA9PSBkaXNrKSB7CgkJCWJpby0+YmlfcncgPSBSRUFEOwoJCQliaW8tPmJpX2VuZF9pbyA9IGVuZF9zeW5jX3JlYWQ7CgkJfSBlbHNlIGlmIChjb25mLT5taXJyb3JzW2ldLnJkZXYgPT0gTlVMTCB8fAoJCQkgICBjb25mLT5taXJyb3JzW2ldLnJkZXYtPmZhdWx0eSkgewoJCQlzdGlsbF9kZWdyYWRlZCA9IDE7CgkJCWNvbnRpbnVlOwoJCX0gZWxzZSBpZiAoIWNvbmYtPm1pcnJvcnNbaV0ucmRldi0+aW5fc3luYyB8fAoJCQkgICBzZWN0b3JfbnIgKyBSRVNZTkNfU0VDVE9SUyA+IG1kZGV2LT5yZWNvdmVyeV9jcCkgewoJCQliaW8tPmJpX3J3ID0gV1JJVEU7CgkJCWJpby0+YmlfZW5kX2lvID0gZW5kX3N5bmNfd3JpdGU7CgkJCXdyaXRlX3RhcmdldHMgKys7CgkJfSBlbHNlCgkJCS8qIG5vIG5lZWQgdG8gcmVhZCBvciB3cml0ZSBoZXJlICovCgkJCWNvbnRpbnVlOwoJCWJpby0+Ymlfc2VjdG9yID0gc2VjdG9yX25yICsgY29uZi0+bWlycm9yc1tpXS5yZGV2LT5kYXRhX29mZnNldDsKCQliaW8tPmJpX2JkZXYgPSBjb25mLT5taXJyb3JzW2ldLnJkZXYtPmJkZXY7CgkJYmlvLT5iaV9wcml2YXRlID0gcjFfYmlvOwoJfQoKCWlmICh3cml0ZV90YXJnZXRzID09IDApIHsKCQkvKiBUaGVyZSBpcyBub3doZXJlIHRvIHdyaXRlLCBzbyBhbGwgbm9uLXN5bmMKCQkgKiBkcml2ZXMgbXVzdCBiZSBmYWlsZWQgLSBzbyB3ZSBhcmUgZmluaXNoZWQKCQkgKi8KCQlzZWN0b3JfdCBydiA9IG1heF9zZWN0b3IgLSBzZWN0b3JfbnI7CgkJKnNraXBwZWQgPSAxOwoJCXB1dF9idWYocjFfYmlvKTsKCQlyZGV2X2RlY19wZW5kaW5nKGNvbmYtPm1pcnJvcnNbZGlza10ucmRldiwgbWRkZXYpOwoJCXJldHVybiBydjsKCX0KCglucl9zZWN0b3JzID0gMDsKCXN5bmNfYmxvY2tzID0gMDsKCWRvIHsKCQlzdHJ1Y3QgcGFnZSAqcGFnZTsKCQlpbnQgbGVuID0gUEFHRV9TSVpFOwoJCWlmIChzZWN0b3JfbnIgKyAobGVuPj45KSA+IG1heF9zZWN0b3IpCgkJCWxlbiA9IChtYXhfc2VjdG9yIC0gc2VjdG9yX25yKSA8PCA5OwoJCWlmIChsZW4gPT0gMCkKCQkJYnJlYWs7CgkJaWYgKHN5bmNfYmxvY2tzID09IDApIHsKCQkJaWYgKCFiaXRtYXBfc3RhcnRfc3luYyhtZGRldi0+Yml0bWFwLCBzZWN0b3JfbnIsCgkJCQkJJnN5bmNfYmxvY2tzLCBzdGlsbF9kZWdyYWRlZCkgJiYKCQkJCQkhY29uZi0+ZnVsbHN5bmMpCgkJCQlicmVhazsKCQkJaWYgKHN5bmNfYmxvY2tzIDwgKFBBR0VfU0laRT4+OSkpCgkJCQlCVUcoKTsKCQkJaWYgKGxlbiA+IChzeW5jX2Jsb2Nrczw8OSkpCgkJCQlsZW4gPSBzeW5jX2Jsb2Nrczw8OTsKCQl9CgoJCWZvciAoaT0wIDsgaSA8IGNvbmYtPnJhaWRfZGlza3M7IGkrKykgewoJCQliaW8gPSByMV9iaW8tPmJpb3NbaV07CgkJCWlmIChiaW8tPmJpX2VuZF9pbykgewoJCQkJcGFnZSA9IHIxX2Jpby0+Ymlvc1swXS0+YmlfaW9fdmVjW2Jpby0+YmlfdmNudF0uYnZfcGFnZTsKCQkJCWlmIChiaW9fYWRkX3BhZ2UoYmlvLCBwYWdlLCBsZW4sIDApID09IDApIHsKCQkJCQkvKiBzdG9wIGhlcmUgKi8KCQkJCQlyMV9iaW8tPmJpb3NbMF0tPmJpX2lvX3ZlY1tiaW8tPmJpX3ZjbnRdLmJ2X3BhZ2UgPSBwYWdlOwoJCQkJCXdoaWxlIChpID4gMCkgewoJCQkJCQlpLS07CgkJCQkJCWJpbyA9IHIxX2Jpby0+Ymlvc1tpXTsKCQkJCQkJaWYgKGJpby0+YmlfZW5kX2lvPT1OVUxMKQoJCQkJCQkJY29udGludWU7CgkJCQkJCS8qIHJlbW92ZSBsYXN0IHBhZ2UgZnJvbSB0aGlzIGJpbyAqLwoJCQkJCQliaW8tPmJpX3ZjbnQtLTsKCQkJCQkJYmlvLT5iaV9zaXplIC09IGxlbjsKCQkJCQkJYmlvLT5iaV9mbGFncyAmPSB+KDE8PCBCSU9fU0VHX1ZBTElEKTsKCQkJCQl9CgkJCQkJZ290byBiaW9fZnVsbDsKCQkJCX0KCQkJfQoJCX0KCQlucl9zZWN0b3JzICs9IGxlbj4+OTsKCQlzZWN0b3JfbnIgKz0gbGVuPj45OwoJCXN5bmNfYmxvY2tzIC09IChsZW4+PjkpOwoJfSB3aGlsZSAocjFfYmlvLT5iaW9zW2Rpc2tdLT5iaV92Y250IDwgUkVTWU5DX1BBR0VTKTsKIGJpb19mdWxsOgoJYmlvID0gcjFfYmlvLT5iaW9zW2Rpc2tdOwoJcjFfYmlvLT5zZWN0b3JzID0gbnJfc2VjdG9yczsKCgltZF9zeW5jX2FjY3QobWlycm9yLT5yZGV2LT5iZGV2LCBucl9zZWN0b3JzKTsKCglnZW5lcmljX21ha2VfcmVxdWVzdChiaW8pOwoKCXJldHVybiBucl9zZWN0b3JzOwp9CgpzdGF0aWMgaW50IHJ1bihtZGRldl90ICptZGRldikKewoJY29uZl90ICpjb25mOwoJaW50IGksIGosIGRpc2tfaWR4OwoJbWlycm9yX2luZm9fdCAqZGlzazsKCW1ka19yZGV2X3QgKnJkZXY7CglzdHJ1Y3QgbGlzdF9oZWFkICp0bXA7CgoJaWYgKG1kZGV2LT5sZXZlbCAhPSAxKSB7CgkJcHJpbnRrKCJyYWlkMTogJXM6IHJhaWQgbGV2ZWwgbm90IHNldCB0byBtaXJyb3JpbmcgKCVkKVxuIiwKCQkgICAgICAgbWRuYW1lKG1kZGV2KSwgbWRkZXYtPmxldmVsKTsKCQlnb3RvIG91dDsKCX0KCS8qCgkgKiBjb3B5IHRoZSBhbHJlYWR5IHZlcmlmaWVkIGRldmljZXMgaW50byBvdXIgcHJpdmF0ZSBSQUlEMQoJICogYm9va2tlZXBpbmcgYXJlYS4gW3doYXRldmVyIHdlIGFsbG9jYXRlIGluIHJ1bigpLAoJICogc2hvdWxkIGJlIGZyZWVkIGluIHN0b3AoKV0KCSAqLwoJY29uZiA9IGttYWxsb2Moc2l6ZW9mKGNvbmZfdCksIEdGUF9LRVJORUwpOwoJbWRkZXYtPnByaXZhdGUgPSBjb25mOwoJaWYgKCFjb25mKQoJCWdvdG8gb3V0X25vX21lbTsKCgltZW1zZXQoY29uZiwgMCwgc2l6ZW9mKCpjb25mKSk7Cgljb25mLT5taXJyb3JzID0ga21hbGxvYyhzaXplb2Yoc3RydWN0IG1pcnJvcl9pbmZvKSptZGRldi0+cmFpZF9kaXNrcywgCgkJCQkgR0ZQX0tFUk5FTCk7CglpZiAoIWNvbmYtPm1pcnJvcnMpCgkJZ290byBvdXRfbm9fbWVtOwoKCW1lbXNldChjb25mLT5taXJyb3JzLCAwLCBzaXplb2Yoc3RydWN0IG1pcnJvcl9pbmZvKSptZGRldi0+cmFpZF9kaXNrcyk7CgoJY29uZi0+cG9vbGluZm8gPSBrbWFsbG9jKHNpemVvZigqY29uZi0+cG9vbGluZm8pLCBHRlBfS0VSTkVMKTsKCWlmICghY29uZi0+cG9vbGluZm8pCgkJZ290byBvdXRfbm9fbWVtOwoJY29uZi0+cG9vbGluZm8tPm1kZGV2ID0gbWRkZXY7Cgljb25mLT5wb29saW5mby0+cmFpZF9kaXNrcyA9IG1kZGV2LT5yYWlkX2Rpc2tzOwoJY29uZi0+cjFiaW9fcG9vbCA9IG1lbXBvb2xfY3JlYXRlKE5SX1JBSUQxX0JJT1MsIHIxYmlvX3Bvb2xfYWxsb2MsCgkJCQkJICByMWJpb19wb29sX2ZyZWUsCgkJCQkJICBjb25mLT5wb29saW5mbyk7CglpZiAoIWNvbmYtPnIxYmlvX3Bvb2wpCgkJZ290byBvdXRfbm9fbWVtOwoKCUlURVJBVEVfUkRFVihtZGRldiwgcmRldiwgdG1wKSB7CgkJZGlza19pZHggPSByZGV2LT5yYWlkX2Rpc2s7CgkJaWYgKGRpc2tfaWR4ID49IG1kZGV2LT5yYWlkX2Rpc2tzCgkJICAgIHx8IGRpc2tfaWR4IDwgMCkKCQkJY29udGludWU7CgkJZGlzayA9IGNvbmYtPm1pcnJvcnMgKyBkaXNrX2lkeDsKCgkJZGlzay0+cmRldiA9IHJkZXY7CgoJCWJsa19xdWV1ZV9zdGFja19saW1pdHMobWRkZXYtPnF1ZXVlLAoJCQkJICAgICAgIHJkZXYtPmJkZXYtPmJkX2Rpc2stPnF1ZXVlKTsKCQkvKiBhcyB3ZSBkb24ndCBob25vdXIgbWVyZ2VfYnZlY19mbiwgd2UgbXVzdCBuZXZlciByaXNrCgkJICogdmlvbGF0aW5nIGl0LCBzbyBsaW1pdCAtPm1heF9zZWN0b3IgdG8gb25lIFBBR0UsIGFzCgkJICogYSBvbmUgcGFnZSByZXF1ZXN0IGlzIG5ldmVyIGluIHZpb2xhdGlvbi4KCQkgKi8KCQlpZiAocmRldi0+YmRldi0+YmRfZGlzay0+cXVldWUtPm1lcmdlX2J2ZWNfZm4gJiYKCQkgICAgbWRkZXYtPnF1ZXVlLT5tYXhfc2VjdG9ycyA+IChQQUdFX1NJWkU+PjkpKQoJCQlibGtfcXVldWVfbWF4X3NlY3RvcnMobWRkZXYtPnF1ZXVlLCBQQUdFX1NJWkU+PjkpOwoKCQlkaXNrLT5oZWFkX3Bvc2l0aW9uID0gMDsKCQlpZiAoIXJkZXYtPmZhdWx0eSAmJiByZGV2LT5pbl9zeW5jKQoJCQljb25mLT53b3JraW5nX2Rpc2tzKys7Cgl9Cgljb25mLT5yYWlkX2Rpc2tzID0gbWRkZXYtPnJhaWRfZGlza3M7Cgljb25mLT5tZGRldiA9IG1kZGV2OwoJc3Bpbl9sb2NrX2luaXQoJmNvbmYtPmRldmljZV9sb2NrKTsKCUlOSVRfTElTVF9IRUFEKCZjb25mLT5yZXRyeV9saXN0KTsKCWlmIChjb25mLT53b3JraW5nX2Rpc2tzID09IDEpCgkJbWRkZXYtPnJlY292ZXJ5X2NwID0gTWF4U2VjdG9yOwoKCXNwaW5fbG9ja19pbml0KCZjb25mLT5yZXN5bmNfbG9jayk7Cglpbml0X3dhaXRxdWV1ZV9oZWFkKCZjb25mLT53YWl0X2lkbGUpOwoJaW5pdF93YWl0cXVldWVfaGVhZCgmY29uZi0+d2FpdF9yZXN1bWUpOwoKCWJpb19saXN0X2luaXQoJmNvbmYtPnBlbmRpbmdfYmlvX2xpc3QpOwoJYmlvX2xpc3RfaW5pdCgmY29uZi0+Zmx1c2hpbmdfYmlvX2xpc3QpOwoKCWlmICghY29uZi0+d29ya2luZ19kaXNrcykgewoJCXByaW50ayhLRVJOX0VSUiAicmFpZDE6IG5vIG9wZXJhdGlvbmFsIG1pcnJvcnMgZm9yICVzXG4iLAoJCQltZG5hbWUobWRkZXYpKTsKCQlnb3RvIG91dF9mcmVlX2NvbmY7Cgl9CgoJbWRkZXYtPmRlZ3JhZGVkID0gMDsKCWZvciAoaSA9IDA7IGkgPCBjb25mLT5yYWlkX2Rpc2tzOyBpKyspIHsKCgkJZGlzayA9IGNvbmYtPm1pcnJvcnMgKyBpOwoKCQlpZiAoIWRpc2stPnJkZXYpIHsKCQkJZGlzay0+aGVhZF9wb3NpdGlvbiA9IDA7CgkJCW1kZGV2LT5kZWdyYWRlZCsrOwoJCX0KCX0KCgkvKgoJICogZmluZCB0aGUgZmlyc3Qgd29ya2luZyBvbmUgYW5kIHVzZSBpdCBhcyBhIHN0YXJ0aW5nIHBvaW50CgkgKiB0byByZWFkIGJhbGFuY2luZy4KCSAqLwoJZm9yIChqID0gMDsgaiA8IGNvbmYtPnJhaWRfZGlza3MgJiYKCQkgICAgICghY29uZi0+bWlycm9yc1tqXS5yZGV2IHx8CgkJICAgICAgIWNvbmYtPm1pcnJvcnNbal0ucmRldi0+aW5fc3luYykgOyBqKyspCgkJLyogbm90aGluZyAqLzsKCWNvbmYtPmxhc3RfdXNlZCA9IGo7CgoKCW1kZGV2LT50aHJlYWQgPSBtZF9yZWdpc3Rlcl90aHJlYWQocmFpZDFkLCBtZGRldiwgIiVzX3JhaWQxIik7CglpZiAoIW1kZGV2LT50aHJlYWQpIHsKCQlwcmludGsoS0VSTl9FUlIKCQkgICAgICAgInJhaWQxOiBjb3VsZG4ndCBhbGxvY2F0ZSB0aHJlYWQgZm9yICVzXG4iLAoJCSAgICAgICBtZG5hbWUobWRkZXYpKTsKCQlnb3RvIG91dF9mcmVlX2NvbmY7Cgl9CglpZiAobWRkZXYtPmJpdG1hcCkgbWRkZXYtPnRocmVhZC0+dGltZW91dCA9IG1kZGV2LT5iaXRtYXAtPmRhZW1vbl9zbGVlcCAqIEhaOwoKCXByaW50ayhLRVJOX0lORk8gCgkJInJhaWQxOiByYWlkIHNldCAlcyBhY3RpdmUgd2l0aCAlZCBvdXQgb2YgJWQgbWlycm9yc1xuIiwKCQltZG5hbWUobWRkZXYpLCBtZGRldi0+cmFpZF9kaXNrcyAtIG1kZGV2LT5kZWdyYWRlZCwgCgkJbWRkZXYtPnJhaWRfZGlza3MpOwoJLyoKCSAqIE9rLCBldmVyeXRoaW5nIGlzIGp1c3QgZmluZSBub3cKCSAqLwoJbWRkZXYtPmFycmF5X3NpemUgPSBtZGRldi0+c2l6ZTsKCgltZGRldi0+cXVldWUtPnVucGx1Z19mbiA9IHJhaWQxX3VucGx1ZzsKCW1kZGV2LT5xdWV1ZS0+aXNzdWVfZmx1c2hfZm4gPSByYWlkMV9pc3N1ZV9mbHVzaDsKCglyZXR1cm4gMDsKCm91dF9ub19tZW06CglwcmludGsoS0VSTl9FUlIgInJhaWQxOiBjb3VsZG4ndCBhbGxvY2F0ZSBtZW1vcnkgZm9yICVzXG4iLAoJICAgICAgIG1kbmFtZShtZGRldikpOwoKb3V0X2ZyZWVfY29uZjoKCWlmIChjb25mKSB7CgkJaWYgKGNvbmYtPnIxYmlvX3Bvb2wpCgkJCW1lbXBvb2xfZGVzdHJveShjb25mLT5yMWJpb19wb29sKTsKCQlrZnJlZShjb25mLT5taXJyb3JzKTsKCQlrZnJlZShjb25mLT5wb29saW5mbyk7CgkJa2ZyZWUoY29uZik7CgkJbWRkZXYtPnByaXZhdGUgPSBOVUxMOwoJfQpvdXQ6CglyZXR1cm4gLUVJTzsKfQoKc3RhdGljIGludCBzdG9wKG1kZGV2X3QgKm1kZGV2KQp7Cgljb25mX3QgKmNvbmYgPSBtZGRldl90b19jb25mKG1kZGV2KTsKCgltZF91bnJlZ2lzdGVyX3RocmVhZChtZGRldi0+dGhyZWFkKTsKCW1kZGV2LT50aHJlYWQgPSBOVUxMOwoJYmxrX3N5bmNfcXVldWUobWRkZXYtPnF1ZXVlKTsgLyogdGhlIHVucGx1ZyBmbiByZWZlcmVuY2VzICdjb25mJyovCglpZiAoY29uZi0+cjFiaW9fcG9vbCkKCQltZW1wb29sX2Rlc3Ryb3koY29uZi0+cjFiaW9fcG9vbCk7CglrZnJlZShjb25mLT5taXJyb3JzKTsKCWtmcmVlKGNvbmYtPnBvb2xpbmZvKTsKCWtmcmVlKGNvbmYpOwoJbWRkZXYtPnByaXZhdGUgPSBOVUxMOwoJcmV0dXJuIDA7Cn0KCnN0YXRpYyBpbnQgcmFpZDFfcmVzaXplKG1kZGV2X3QgKm1kZGV2LCBzZWN0b3JfdCBzZWN0b3JzKQp7CgkvKiBubyByZXN5bmMgaXMgaGFwcGVuaW5nLCBhbmQgdGhlcmUgaXMgZW5vdWdoIHNwYWNlCgkgKiBvbiBhbGwgZGV2aWNlcywgc28gd2UgY2FuIHJlc2l6ZS4KCSAqIFdlIG5lZWQgdG8gbWFrZSBzdXJlIHJlc3luYyBjb3ZlcnMgYW55IG5ldyBzcGFjZS4KCSAqIElmIHRoZSBhcnJheSBpcyBzaHJpbmtpbmcgd2Ugc2hvdWxkIHBvc3NpYmx5IHdhaXQgdW50aWwKCSAqIGFueSBpbyBpbiB0aGUgcmVtb3ZlZCBzcGFjZSBjb21wbGV0ZXMsIGJ1dCBpdCBoYXJkbHkgc2VlbXMKCSAqIHdvcnRoIGl0LgoJICovCgltZGRldi0+YXJyYXlfc2l6ZSA9IHNlY3RvcnM+PjE7CglzZXRfY2FwYWNpdHkobWRkZXYtPmdlbmRpc2ssIG1kZGV2LT5hcnJheV9zaXplIDw8IDEpOwoJbWRkZXYtPmNoYW5nZWQgPSAxOwoJaWYgKG1kZGV2LT5hcnJheV9zaXplID4gbWRkZXYtPnNpemUgJiYgbWRkZXYtPnJlY292ZXJ5X2NwID09IE1heFNlY3RvcikgewoJCW1kZGV2LT5yZWNvdmVyeV9jcCA9IG1kZGV2LT5zaXplIDw8IDE7CgkJc2V0X2JpdChNRF9SRUNPVkVSWV9ORUVERUQsICZtZGRldi0+cmVjb3ZlcnkpOwoJfQoJbWRkZXYtPnNpemUgPSBtZGRldi0+YXJyYXlfc2l6ZTsKCW1kZGV2LT5yZXN5bmNfbWF4X3NlY3RvcnMgPSBzZWN0b3JzOwoJcmV0dXJuIDA7Cn0KCnN0YXRpYyBpbnQgcmFpZDFfcmVzaGFwZShtZGRldl90ICptZGRldiwgaW50IHJhaWRfZGlza3MpCnsKCS8qIFdlIG5lZWQgdG86CgkgKiAxLyByZXNpemUgdGhlIHIxYmlvX3Bvb2wKCSAqIDIvIHJlc2l6ZSBjb25mLT5taXJyb3JzCgkgKgoJICogV2UgYWxsb2NhdGUgYSBuZXcgcjFiaW9fcG9vbCBpZiB3ZSBjYW4uCgkgKiBUaGVuIHJhaXNlIGEgZGV2aWNlIGJhcnJpZXIgYW5kIHdhaXQgdW50aWwgYWxsIElPIHN0b3BzLgoJICogVGhlbiByZXNpemUgY29uZi0+bWlycm9ycyBhbmQgc3dhcCBpbiB0aGUgbmV3IHIxYmlvIHBvb2wuCgkgKgoJICogQXQgdGhlIHNhbWUgdGltZSwgd2UgInBhY2siIHRoZSBkZXZpY2VzIHNvIHRoYXQgYWxsIHRoZSBtaXNzaW5nCgkgKiBkZXZpY2VzIGhhdmUgdGhlIGhpZ2hlciByYWlkX2Rpc2sgbnVtYmVycy4KCSAqLwoJbWVtcG9vbF90ICpuZXdwb29sLCAqb2xkcG9vbDsKCXN0cnVjdCBwb29sX2luZm8gKm5ld3Bvb2xpbmZvOwoJbWlycm9yX2luZm9fdCAqbmV3bWlycm9yczsKCWNvbmZfdCAqY29uZiA9IG1kZGV2X3RvX2NvbmYobWRkZXYpOwoJaW50IGNudDsKCglpbnQgZCwgZDI7CgoJaWYgKHJhaWRfZGlza3MgPCBjb25mLT5yYWlkX2Rpc2tzKSB7CgkJY250PTA7CgkJZm9yIChkPSAwOyBkIDwgY29uZi0+cmFpZF9kaXNrczsgZCsrKQoJCQlpZiAoY29uZi0+bWlycm9yc1tkXS5yZGV2KQoJCQkJY250Kys7CgkJaWYgKGNudCA+IHJhaWRfZGlza3MpCgkJCXJldHVybiAtRUJVU1k7Cgl9CgoJbmV3cG9vbGluZm8gPSBrbWFsbG9jKHNpemVvZigqbmV3cG9vbGluZm8pLCBHRlBfS0VSTkVMKTsKCWlmICghbmV3cG9vbGluZm8pCgkJcmV0dXJuIC1FTk9NRU07CgluZXdwb29saW5mby0+bWRkZXYgPSBtZGRldjsKCW5ld3Bvb2xpbmZvLT5yYWlkX2Rpc2tzID0gcmFpZF9kaXNrczsKCgluZXdwb29sID0gbWVtcG9vbF9jcmVhdGUoTlJfUkFJRDFfQklPUywgcjFiaW9fcG9vbF9hbGxvYywKCQkJCSByMWJpb19wb29sX2ZyZWUsIG5ld3Bvb2xpbmZvKTsKCWlmICghbmV3cG9vbCkgewoJCWtmcmVlKG5ld3Bvb2xpbmZvKTsKCQlyZXR1cm4gLUVOT01FTTsKCX0KCW5ld21pcnJvcnMgPSBrbWFsbG9jKHNpemVvZihzdHJ1Y3QgbWlycm9yX2luZm8pICogcmFpZF9kaXNrcywgR0ZQX0tFUk5FTCk7CglpZiAoIW5ld21pcnJvcnMpIHsKCQlrZnJlZShuZXdwb29saW5mbyk7CgkJbWVtcG9vbF9kZXN0cm95KG5ld3Bvb2wpOwoJCXJldHVybiAtRU5PTUVNOwoJfQoJbWVtc2V0KG5ld21pcnJvcnMsIDAsIHNpemVvZihzdHJ1Y3QgbWlycm9yX2luZm8pKnJhaWRfZGlza3MpOwoKCXNwaW5fbG9ja19pcnEoJmNvbmYtPnJlc3luY19sb2NrKTsKCWNvbmYtPmJhcnJpZXIrKzsKCXdhaXRfZXZlbnRfbG9ja19pcnEoY29uZi0+d2FpdF9pZGxlLCAhY29uZi0+bnJfcGVuZGluZywKCQkJICAgIGNvbmYtPnJlc3luY19sb2NrLCByYWlkMV91bnBsdWcobWRkZXYtPnF1ZXVlKSk7CglzcGluX3VubG9ja19pcnEoJmNvbmYtPnJlc3luY19sb2NrKTsKCgkvKiBvaywgZXZlcnl0aGluZyBpcyBzdG9wcGVkICovCglvbGRwb29sID0gY29uZi0+cjFiaW9fcG9vbDsKCWNvbmYtPnIxYmlvX3Bvb2wgPSBuZXdwb29sOwoKCWZvciAoZD1kMj0wOyBkIDwgY29uZi0+cmFpZF9kaXNrczsgZCsrKQoJCWlmIChjb25mLT5taXJyb3JzW2RdLnJkZXYpIHsKCQkJY29uZi0+bWlycm9yc1tkXS5yZGV2LT5yYWlkX2Rpc2sgPSBkMjsKCQkJbmV3bWlycm9yc1tkMisrXS5yZGV2ID0gY29uZi0+bWlycm9yc1tkXS5yZGV2OwoJCX0KCWtmcmVlKGNvbmYtPm1pcnJvcnMpOwoJY29uZi0+bWlycm9ycyA9IG5ld21pcnJvcnM7CglrZnJlZShjb25mLT5wb29saW5mbyk7Cgljb25mLT5wb29saW5mbyA9IG5ld3Bvb2xpbmZvOwoKCW1kZGV2LT5kZWdyYWRlZCArPSAocmFpZF9kaXNrcyAtIGNvbmYtPnJhaWRfZGlza3MpOwoJY29uZi0+cmFpZF9kaXNrcyA9IG1kZGV2LT5yYWlkX2Rpc2tzID0gcmFpZF9kaXNrczsKCgljb25mLT5sYXN0X3VzZWQgPSAwOyAvKiBqdXN0IG1ha2Ugc3VyZSBpdCBpcyBpbi1yYW5nZSAqLwoJc3Bpbl9sb2NrX2lycSgmY29uZi0+cmVzeW5jX2xvY2spOwoJY29uZi0+YmFycmllci0tOwoJc3Bpbl91bmxvY2tfaXJxKCZjb25mLT5yZXN5bmNfbG9jayk7Cgl3YWtlX3VwKCZjb25mLT53YWl0X3Jlc3VtZSk7Cgl3YWtlX3VwKCZjb25mLT53YWl0X2lkbGUpOwoKCglzZXRfYml0KE1EX1JFQ09WRVJZX05FRURFRCwgJm1kZGV2LT5yZWNvdmVyeSk7CgltZF93YWtldXBfdGhyZWFkKG1kZGV2LT50aHJlYWQpOwoKCW1lbXBvb2xfZGVzdHJveShvbGRwb29sKTsKCXJldHVybiAwOwp9CgoKc3RhdGljIG1ka19wZXJzb25hbGl0eV90IHJhaWQxX3BlcnNvbmFsaXR5ID0KewoJLm5hbWUJCT0gInJhaWQxIiwKCS5vd25lcgkJPSBUSElTX01PRFVMRSwKCS5tYWtlX3JlcXVlc3QJPSBtYWtlX3JlcXVlc3QsCgkucnVuCQk9IHJ1biwKCS5zdG9wCQk9IHN0b3AsCgkuc3RhdHVzCQk9IHN0YXR1cywKCS5lcnJvcl9oYW5kbGVyCT0gZXJyb3IsCgkuaG90X2FkZF9kaXNrCT0gcmFpZDFfYWRkX2Rpc2ssCgkuaG90X3JlbW92ZV9kaXNrPSByYWlkMV9yZW1vdmVfZGlzaywKCS5zcGFyZV9hY3RpdmUJPSByYWlkMV9zcGFyZV9hY3RpdmUsCgkuc3luY19yZXF1ZXN0CT0gc3luY19yZXF1ZXN0LAoJLnJlc2l6ZQkJPSByYWlkMV9yZXNpemUsCgkucmVzaGFwZQk9IHJhaWQxX3Jlc2hhcGUsCn07CgpzdGF0aWMgaW50IF9faW5pdCByYWlkX2luaXQodm9pZCkKewoJcmV0dXJuIHJlZ2lzdGVyX21kX3BlcnNvbmFsaXR5KFJBSUQxLCAmcmFpZDFfcGVyc29uYWxpdHkpOwp9CgpzdGF0aWMgdm9pZCByYWlkX2V4aXQodm9pZCkKewoJdW5yZWdpc3Rlcl9tZF9wZXJzb25hbGl0eShSQUlEMSk7Cn0KCm1vZHVsZV9pbml0KHJhaWRfaW5pdCk7Cm1vZHVsZV9leGl0KHJhaWRfZXhpdCk7Ck1PRFVMRV9MSUNFTlNFKCJHUEwiKTsKTU9EVUxFX0FMSUFTKCJtZC1wZXJzb25hbGl0eS0zIik7IC8qIFJBSUQxICovCg==