LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICAgICAKICogRmlsZW5hbWU6ICAgICAgaXJ0dHAuYwogKiBWZXJzaW9uOiAgICAgICAxLjIKICogRGVzY3JpcHRpb246ICAgVGlueSBUcmFuc3BvcnQgUHJvdG9jb2wgKFRUUCkgaW1wbGVtZW50YXRpb24KICogU3RhdHVzOiAgICAgICAgU3RhYmxlCiAqIEF1dGhvcjogICAgICAgIERhZyBCcmF0dGxpIDxkYWdiQGNzLnVpdC5ubz4KICogQ3JlYXRlZCBhdDogICAgU3VuIEF1ZyAzMSAyMDoxNDozMSAxOTk3CiAqIE1vZGlmaWVkIGF0OiAgIFdlZCBKYW4gIDUgMTE6MzE6MjcgMjAwMAogKiBNb2RpZmllZCBieTogICBEYWcgQnJhdHRsaSA8ZGFnYkBjcy51aXQubm8+CiAqIAogKiAgICAgQ29weXJpZ2h0IChjKSAxOTk4LTIwMDAgRGFnIEJyYXR0bGkgPGRhZ2JAY3MudWl0Lm5vPiwgCiAqICAgICBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiAgICAgQ29weXJpZ2h0IChjKSAyMDAwLTIwMDMgSmVhbiBUb3VycmlsaGVzIDxqdEBocGwuaHAuY29tPgogKiAgICAgCiAqICAgICBUaGlzIHByb2dyYW0gaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIAogKiAgICAgbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgCiAqICAgICBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyIHZlcnNpb24gMiBvZiAKICogICAgIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiAgICAgTmVpdGhlciBEYWcgQnJhdHRsaSBub3IgVW5pdmVyc2l0eSBvZiBUcm9tc/ggYWRtaXQgbGlhYmlsaXR5IG5vcgogKiAgICAgcHJvdmlkZSB3YXJyYW50eSBmb3IgYW55IG9mIHRoaXMgc29mdHdhcmUuIFRoaXMgbWF0ZXJpYWwgaXMgCiAqICAgICBwcm92aWRlZCAiQVMtSVMiIGFuZCBhdCBubyBjaGFyZ2UuCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCiNpbmNsdWRlIDxsaW51eC9za2J1ZmYuaD4KI2luY2x1ZGUgPGxpbnV4L2luaXQuaD4KI2luY2x1ZGUgPGxpbnV4L2ZzLmg+CiNpbmNsdWRlIDxsaW51eC9zZXFfZmlsZS5oPgoKI2luY2x1ZGUgPGFzbS9ieXRlb3JkZXIuaD4KI2luY2x1ZGUgPGFzbS91bmFsaWduZWQuaD4KCiNpbmNsdWRlIDxuZXQvaXJkYS9pcmRhLmg+CiNpbmNsdWRlIDxuZXQvaXJkYS9pcmxhcC5oPgojaW5jbHVkZSA8bmV0L2lyZGEvaXJsbXAuaD4KI2luY2x1ZGUgPG5ldC9pcmRhL3BhcmFtZXRlcnMuaD4KI2luY2x1ZGUgPG5ldC9pcmRhL2lydHRwLmg+CgpzdGF0aWMgc3RydWN0IGlydHRwX2NiICppcnR0cDsKCnN0YXRpYyB2b2lkIF9faXJ0dHBfY2xvc2VfdHNhcChzdHJ1Y3QgdHNhcF9jYiAqc2VsZik7CgpzdGF0aWMgaW50IGlydHRwX2RhdGFfaW5kaWNhdGlvbih2b2lkICppbnN0YW5jZSwgdm9pZCAqc2FwLCAKCQkJCSBzdHJ1Y3Qgc2tfYnVmZiAqc2tiKTsKc3RhdGljIGludCBpcnR0cF91ZGF0YV9pbmRpY2F0aW9uKHZvaWQgKmluc3RhbmNlLCB2b2lkICpzYXAsIAoJCQkJICBzdHJ1Y3Qgc2tfYnVmZiAqc2tiKTsKc3RhdGljIHZvaWQgaXJ0dHBfZGlzY29ubmVjdF9pbmRpY2F0aW9uKHZvaWQgKmluc3RhbmNlLCB2b2lkICpzYXAsICAKCQkJCQlMTV9SRUFTT04gcmVhc29uLCBzdHJ1Y3Qgc2tfYnVmZiAqKTsKc3RhdGljIHZvaWQgaXJ0dHBfY29ubmVjdF9pbmRpY2F0aW9uKHZvaWQgKmluc3RhbmNlLCB2b2lkICpzYXAsIAoJCQkJICAgICBzdHJ1Y3QgcW9zX2luZm8gKnFvcywgX191MzIgbWF4X3NkdV9zaXplLAoJCQkJICAgICBfX3U4IGhlYWRlcl9zaXplLCBzdHJ1Y3Qgc2tfYnVmZiAqc2tiKTsKc3RhdGljIHZvaWQgaXJ0dHBfY29ubmVjdF9jb25maXJtKHZvaWQgKmluc3RhbmNlLCB2b2lkICpzYXAsIAoJCQkJICBzdHJ1Y3QgcW9zX2luZm8gKnFvcywgX191MzIgbWF4X3NkdV9zaXplLCAKCQkJCSAgX191OCBoZWFkZXJfc2l6ZSwgc3RydWN0IHNrX2J1ZmYgKnNrYik7CnN0YXRpYyB2b2lkIGlydHRwX3J1bl90eF9xdWV1ZShzdHJ1Y3QgdHNhcF9jYiAqc2VsZik7CnN0YXRpYyB2b2lkIGlydHRwX3J1bl9yeF9xdWV1ZShzdHJ1Y3QgdHNhcF9jYiAqc2VsZik7CgpzdGF0aWMgdm9pZCBpcnR0cF9mbHVzaF9xdWV1ZXMoc3RydWN0IHRzYXBfY2IgKnNlbGYpOwpzdGF0aWMgdm9pZCBpcnR0cF9mcmFnbWVudF9za2Ioc3RydWN0IHRzYXBfY2IgKnNlbGYsIHN0cnVjdCBza19idWZmICpza2IpOwpzdGF0aWMgc3RydWN0IHNrX2J1ZmYgKmlydHRwX3JlYXNzZW1ibGVfc2tiKHN0cnVjdCB0c2FwX2NiICpzZWxmKTsKc3RhdGljIHZvaWQgaXJ0dHBfdG9kb19leHBpcmVkKHVuc2lnbmVkIGxvbmcgZGF0YSk7CnN0YXRpYyBpbnQgaXJ0dHBfcGFyYW1fbWF4X3NkdV9zaXplKHZvaWQgKmluc3RhbmNlLCBpcmRhX3BhcmFtX3QgKnBhcmFtLCAKCQkJCSAgICBpbnQgZ2V0KTsKCnN0YXRpYyB2b2lkIGlydHRwX2Zsb3dfaW5kaWNhdGlvbih2b2lkICppbnN0YW5jZSwgdm9pZCAqc2FwLCBMT0NBTF9GTE9XIGZsb3cpOwpzdGF0aWMgdm9pZCBpcnR0cF9zdGF0dXNfaW5kaWNhdGlvbih2b2lkICppbnN0YW5jZSwKCQkJCSAgICBMSU5LX1NUQVRVUyBsaW5rLCBMT0NLX1NUQVRVUyBsb2NrKTsKCi8qIEluZm9ybWF0aW9uIGZvciBwYXJzaW5nIHBhcmFtZXRlcnMgaW4gSXJUVFAgKi8Kc3RhdGljIHBpX21pbm9yX2luZm9fdCBwaV9taW5vcl9jYWxsX3RhYmxlW10gPSB7Cgl7IE5VTEwsIDAgfSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiAweDAwICovCgl7IGlydHRwX3BhcmFtX21heF9zZHVfc2l6ZSwgUFZfSU5URUdFUiB8IFBWX0JJR19FTkRJQU4gfSAvKiAweDAxICovCn07CnN0YXRpYyBwaV9tYWpvcl9pbmZvX3QgcGlfbWFqb3JfY2FsbF90YWJsZVtdID0ge3sgcGlfbWlub3JfY2FsbF90YWJsZSwgMiB9fTsKc3RhdGljIHBpX3BhcmFtX2luZm9fdCBwYXJhbV9pbmZvID0geyBwaV9tYWpvcl9jYWxsX3RhYmxlLCAxLCAweDBmLCA0IH07CgovKioqKioqKioqKioqKioqKioqKioqKioqIEdMT0JBTCBQUk9DRURVUkVTICoqKioqKioqKioqKioqKioqKioqKioqKi8KCi8qCiAqIEZ1bmN0aW9uIGlydHRwX2luaXQgKHZvaWQpCiAqCiAqICAgIEluaXRpYWxpemUgdGhlIElyVFRQIGxheWVyLiBDYWxsZWQgYnkgbW9kdWxlIGluaXRpYWxpemF0aW9uIGNvZGUKICoKICovCmludCBfX2luaXQgaXJ0dHBfaW5pdCh2b2lkKQp7CglpcnR0cCA9IGt6YWxsb2Moc2l6ZW9mKHN0cnVjdCBpcnR0cF9jYiksIEdGUF9LRVJORUwpOwoJaWYgKGlydHRwID09IE5VTEwpCgkJcmV0dXJuIC1FTk9NRU07CgoJaXJ0dHAtPm1hZ2ljID0gVFRQX01BR0lDOwoKCWlydHRwLT50c2FwcyA9IGhhc2hiaW5fbmV3KEhCX0xPQ0spOwoJaWYgKCFpcnR0cC0+dHNhcHMpIHsKCQlJUkRBX0VSUk9SKCIlczogY2FuJ3QgYWxsb2NhdGUgSXJUVFAgaGFzaGJpbiFcbiIsCgkJCSAgIF9fRlVOQ1RJT05fXyk7CgkJa2ZyZWUoaXJ0dHApOwoJCXJldHVybiAtRU5PTUVNOwoJfQoKCXJldHVybiAwOwp9CgovKgogKiBGdW5jdGlvbiBpcnR0cF9jbGVhbnVwICh2b2lkKQogKgogKiAgICBDYWxsZWQgYnkgbW9kdWxlIGRlc3RydWN0aW9uL2NsZWFudXAgY29kZQogKgogKi8Kdm9pZCBfX2V4aXQgaXJ0dHBfY2xlYW51cCh2b2lkKSAKewoJLyogQ2hlY2sgZm9yIG1haW4gc3RydWN0dXJlICovCglJUkRBX0FTU0VSVChpcnR0cC0+bWFnaWMgPT0gVFRQX01BR0lDLCByZXR1cm47KTsKCgkvKgoJICogIERlbGV0ZSBoYXNoYmluIGFuZCBjbG9zZSBhbGwgVFNBUCBpbnN0YW5jZXMgaW4gaXQKCSAqLwoJaGFzaGJpbl9kZWxldGUoaXJ0dHAtPnRzYXBzLCAoRlJFRV9GVU5DKSBfX2lydHRwX2Nsb3NlX3RzYXApOwoKCWlydHRwLT5tYWdpYyA9IDA7CgoJLyogRGUtYWxsb2NhdGUgbWFpbiBzdHJ1Y3R1cmUgKi8KCWtmcmVlKGlydHRwKTsKCglpcnR0cCA9IE5VTEw7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKiogU1VCUk9VVElORVMgKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKLyoKICogRnVuY3Rpb24gaXJ0dHBfc3RhcnRfdG9kb190aW1lciAoc2VsZiwgdGltZW91dCkKICoKICogICAgU3RhcnQgdG9kbyB0aW1lci4KICoKICogTWFkZSBpdCBtb3JlIGVmZmllbnQgYW5kIHVuc2Vuc2l0aXZlIHRvIHJhY2UgY29uZGl0aW9ucyAtIEplYW4gSUkKICovCnN0YXRpYyBpbmxpbmUgdm9pZCBpcnR0cF9zdGFydF90b2RvX3RpbWVyKHN0cnVjdCB0c2FwX2NiICpzZWxmLCBpbnQgdGltZW91dCkKewoJLyogU2V0IG5ldyB2YWx1ZSBmb3IgdGltZXIgKi8KCW1vZF90aW1lcigmc2VsZi0+dG9kb190aW1lciwgamlmZmllcyArIHRpbWVvdXQpOwp9CgovKgogKiBGdW5jdGlvbiBpcnR0cF90b2RvX2V4cGlyZWQgKGRhdGEpCiAqCiAqICAgIFRvZG8gdGltZXIgaGFzIGV4cGlyZWQhCiAqCiAqIE9uZSBvZiB0aGUgcmVzdHJpY3Rpb24gb2YgdGhlIHRpbWVyIGlzIHRoYXQgaXQgaXMgcnVuIG9ubHkgb24gdGhlIHRpbWVyCiAqIGludGVycnVwdCB3aGljaCBydW4gZXZlcnkgMTBtcy4gVGhpcyBtZWFuIHRoYXQgZXZlbiBpZiB5b3Ugc2V0IHRoZSB0aW1lcgogKiB3aXRoIGEgZGVsYXkgb2YgMCwgaXQgbWF5IHRha2UgdXAgdG8gMTBtcyBiZWZvcmUgaXQncyBydW4uCiAqIFNvLCB0byBtaW5pbWlzZSBsYXRlbmN5IGFuZCBrZWVwIGNhY2hlIGZyZXNoLCB3ZSB0cnkgdG8gYXZvaWQgdXNpbmcKICogaXQgYXMgbXVjaCBhcyBwb3NzaWJsZS4KICogTm90ZSA6IHdlIGNhbid0IHVzZSB0YXNrbGV0cywgYmVjYXVzZSB0aGV5IGNhbid0IGJlIGFzeW5jaHJvbm91c2x5CiAqIGtpbGxlZCAobmVlZCB1c2VyIGNvbnRleHQpLCBhbmQgd2UgY2FuJ3QgZ3VhcmFudGVlIHRoYXQgaGVyZS4uLgogKiBKZWFuIElJCiAqLwpzdGF0aWMgdm9pZCBpcnR0cF90b2RvX2V4cGlyZWQodW5zaWduZWQgbG9uZyBkYXRhKQp7CglzdHJ1Y3QgdHNhcF9jYiAqc2VsZiA9IChzdHJ1Y3QgdHNhcF9jYiAqKSBkYXRhOwoKCS8qIENoZWNrIHRoYXQgd2Ugc3RpbGwgZXhpc3QgKi8KCWlmICghc2VsZiB8fCBzZWxmLT5tYWdpYyAhPSBUVFBfVFNBUF9NQUdJQykKCQlyZXR1cm47CgoJSVJEQV9ERUJVRyg0LCAiJXMoaW5zdGFuY2U9JXApXG4iLCBfX0ZVTkNUSU9OX18sIHNlbGYpOwoKCS8qIFRyeSB0byBtYWtlIHNvbWUgcHJvZ3Jlc3MsIGVzcGVjaWFsbHkgb24gVHggc2lkZSAtIEplYW4gSUkgKi8KCWlydHRwX3J1bl9yeF9xdWV1ZShzZWxmKTsKCWlydHRwX3J1bl90eF9xdWV1ZShzZWxmKTsKCgkvKiBDaGVjayBpZiB0aW1lIGZvciBkaXNjb25uZWN0ICovCglpZiAodGVzdF9iaXQoMCwgJnNlbGYtPmRpc2Nvbm5lY3RfcGVuZCkpIHsKCQkvKiBDaGVjayBpZiBpdCdzIHBvc3NpYmxlIHRvIGRpc2Nvbm5lY3QgeWV0ICovCgkJaWYgKHNrYl9xdWV1ZV9lbXB0eSgmc2VsZi0+dHhfcXVldWUpKSB7CgkJCS8qIE1ha2Ugc3VyZSBkaXNjb25uZWN0IGlzIG5vdCBwZW5kaW5nIGFueW1vcmUgKi8KCQkJY2xlYXJfYml0KDAsICZzZWxmLT5kaXNjb25uZWN0X3BlbmQpOwkvKiBGQUxTRSAqLwoKCQkJLyogTm90ZSA6IHNlbGYtPmRpc2Nvbm5lY3Rfc2tiIG1heSBiZSBOVUxMICovCgkJCWlydHRwX2Rpc2Nvbm5lY3RfcmVxdWVzdChzZWxmLCBzZWxmLT5kaXNjb25uZWN0X3NrYiwKCQkJCQkJIFBfTk9STUFMKTsKCQkJc2VsZi0+ZGlzY29ubmVjdF9za2IgPSBOVUxMOwoJCX0gZWxzZSB7CgkJCS8qIFRyeSBhZ2FpbiBsYXRlciAqLwoJCQlpcnR0cF9zdGFydF90b2RvX3RpbWVyKHNlbGYsIEhaLzEwKTsKCgkJCS8qIE5vIHJlYXNvbiB0byB0cnkgYW5kIGNsb3NlIG5vdyAqLwoJCQlyZXR1cm47CgkJfQoJfQoKCS8qIENoZWNrIGlmIGl0J3MgY2xvc2luZyB0aW1lICovCglpZiAoc2VsZi0+Y2xvc2VfcGVuZCkKCQkvKiBGaW5pc2ggY2xlYW51cCAqLwoJCWlydHRwX2Nsb3NlX3RzYXAoc2VsZik7Cn0KCi8qCiAqIEZ1bmN0aW9uIGlydHRwX2ZsdXNoX3F1ZXVlcyAoc2VsZikKICoKICogICAgIEZsdXNoZXMgKHJlbW92ZXMgYWxsIGZyYW1lcykgaW4gdHJhbnNpdHQtYnVmZmVyICh0eF9saXN0KQogKi8Kdm9pZCBpcnR0cF9mbHVzaF9xdWV1ZXMoc3RydWN0IHRzYXBfY2IgKnNlbGYpCnsKCXN0cnVjdCBza19idWZmKiBza2I7CgoJSVJEQV9ERUJVRyg0LCAiJXMoKVxuIiwgX19GVU5DVElPTl9fKTsKCglJUkRBX0FTU0VSVChzZWxmICE9IE5VTEwsIHJldHVybjspOwoJSVJEQV9BU1NFUlQoc2VsZi0+bWFnaWMgPT0gVFRQX1RTQVBfTUFHSUMsIHJldHVybjspOwoKCS8qIERlYWxsb2NhdGUgZnJhbWVzIHdhaXRpbmcgdG8gYmUgc2VudCAqLwoJd2hpbGUgKChza2IgPSBza2JfZGVxdWV1ZSgmc2VsZi0+dHhfcXVldWUpKSAhPSBOVUxMKQoJCWRldl9rZnJlZV9za2Ioc2tiKTsKCgkvKiBEZWFsbG9jYXRlIHJlY2VpdmVkIGZyYW1lcyAqLwoJd2hpbGUgKChza2IgPSBza2JfZGVxdWV1ZSgmc2VsZi0+cnhfcXVldWUpKSAhPSBOVUxMKQoJCWRldl9rZnJlZV9za2Ioc2tiKTsKCgkvKiBEZWFsbG9jYXRlIHJlY2VpdmVkIGZyYWdtZW50cyAqLwoJd2hpbGUgKChza2IgPSBza2JfZGVxdWV1ZSgmc2VsZi0+cnhfZnJhZ21lbnRzKSkgIT0gTlVMTCkKCQlkZXZfa2ZyZWVfc2tiKHNrYik7Cn0KCi8qCiAqIEZ1bmN0aW9uIGlydHRwX3JlYXNzZW1ibGUgKHNlbGYpCiAqCiAqICAgIE1ha2VzIGEgbmV3IChjb250aW51b3VzKSBza2Igb2YgYWxsIHRoZSBmcmFnbWVudHMgaW4gdGhlIGZyYWdtZW50CiAqICAgIHF1ZXVlCiAqCiAqLwpzdGF0aWMgc3RydWN0IHNrX2J1ZmYgKmlydHRwX3JlYXNzZW1ibGVfc2tiKHN0cnVjdCB0c2FwX2NiICpzZWxmKQp7CglzdHJ1Y3Qgc2tfYnVmZiAqc2tiLCAqZnJhZzsKCWludCBuID0gMDsgIC8qIEZyYWdtZW50IGluZGV4ICovCgoJSVJEQV9BU1NFUlQoc2VsZiAhPSBOVUxMLCByZXR1cm4gTlVMTDspOwoJSVJEQV9BU1NFUlQoc2VsZi0+bWFnaWMgPT0gVFRQX1RTQVBfTUFHSUMsIHJldHVybiBOVUxMOyk7CgoJSVJEQV9ERUJVRygyLCAiJXMoKSwgc2VsZi0+cnhfc2R1X3NpemU9JWRcbiIsIF9fRlVOQ1RJT05fXywKCQkgICBzZWxmLT5yeF9zZHVfc2l6ZSk7CgoJc2tiID0gZGV2X2FsbG9jX3NrYihUVFBfSEVBREVSICsgc2VsZi0+cnhfc2R1X3NpemUpOwoJaWYgKCFza2IpCgkJcmV0dXJuIE5VTEw7CgoJLyoKCSAqIE5lZWQgdG8gcmVzZXJ2ZSBzcGFjZSBmb3IgVFRQIGhlYWRlciBpbiBjYXNlIHRoaXMgc2tiIG5lZWRzIHRvCgkgKiBiZSByZXF1ZXVlZCBpbiBjYXNlIGRlbGl2ZXJ5IGZhaWxlcwoJICovCglza2JfcmVzZXJ2ZShza2IsIFRUUF9IRUFERVIpOwoJc2tiX3B1dChza2IsIHNlbGYtPnJ4X3NkdV9zaXplKTsKCgkvKgoJICogIENvcHkgYWxsIGZyYWdtZW50cyB0byBhIG5ldyBidWZmZXIKCSAqLwoJd2hpbGUgKChmcmFnID0gc2tiX2RlcXVldWUoJnNlbGYtPnJ4X2ZyYWdtZW50cykpICE9IE5VTEwpIHsKCQltZW1jcHkoc2tiLT5kYXRhK24sIGZyYWctPmRhdGEsIGZyYWctPmxlbik7CgkJbiArPSBmcmFnLT5sZW47CgoJCWRldl9rZnJlZV9za2IoZnJhZyk7Cgl9CgoJSVJEQV9ERUJVRygyLAoJCSAgICIlcygpLCBmcmFtZSBsZW49JWQsIHJ4X3NkdV9zaXplPSVkLCByeF9tYXhfc2R1X3NpemU9JWRcbiIsCgkJICAgX19GVU5DVElPTl9fLCBuLCBzZWxmLT5yeF9zZHVfc2l6ZSwgc2VsZi0+cnhfbWF4X3NkdV9zaXplKTsKCS8qIE5vdGUgOiBpcnR0cF9ydW5fcnhfcXVldWUoKSBjYWxjdWxhdGUgc2VsZi0+cnhfc2R1X3NpemUKCSAqIGJ5IHN1bW1pbmcgdGhlIHNpemUgb2YgYWxsIGZyYWdtZW50cywgc28gd2Ugc2hvdWxkIGFsd2F5cwoJICogaGF2ZSBuID09IHNlbGYtPnJ4X3NkdV9zaXplLCBleGNlcHQgaW4gY2FzZXMgd2hlcmUgd2UKCSAqIGRyb3BlZCB0aGUgbGFzdCBmcmFnbWVudCAod2hlbiBzZWxmLT5yeF9zZHVfc2l6ZSBleGNlZWQKCSAqIHNlbGYtPnJ4X21heF9zZHVfc2l6ZSksIHdoZXJlIG4gPCBzZWxmLT5yeF9zZHVfc2l6ZS4KCSAqIEplYW4gSUkgKi8KCUlSREFfQVNTRVJUKG4gPD0gc2VsZi0+cnhfc2R1X3NpemUsIG4gPSBzZWxmLT5yeF9zZHVfc2l6ZTspOwoKCS8qIFNldCB0aGUgbmV3IGxlbmd0aCAqLwoJc2tiX3RyaW0oc2tiLCBuKTsKCglzZWxmLT5yeF9zZHVfc2l6ZSA9IDA7CgoJcmV0dXJuIHNrYjsKfQoKLyoKICogRnVuY3Rpb24gaXJ0dHBfZnJhZ21lbnRfc2tiIChza2IpCiAqCiAqICAgIEZyYWdtZW50cyBhIGZyYW1lIGFuZCBxdWV1ZXMgYWxsIHRoZSBmcmFnbWVudHMgZm9yIHRyYW5zbWlzc2lvbgogKgogKi8Kc3RhdGljIGlubGluZSB2b2lkIGlydHRwX2ZyYWdtZW50X3NrYihzdHJ1Y3QgdHNhcF9jYiAqc2VsZiwKCQkJCSAgICAgIHN0cnVjdCBza19idWZmICpza2IpCnsKCXN0cnVjdCBza19idWZmICpmcmFnOwoJX191OCAqZnJhbWU7CgoJSVJEQV9ERUJVRygyLCAiJXMoKVxuIiwgX19GVU5DVElPTl9fKTsKCglJUkRBX0FTU0VSVChzZWxmICE9IE5VTEwsIHJldHVybjspOwoJSVJEQV9BU1NFUlQoc2VsZi0+bWFnaWMgPT0gVFRQX1RTQVBfTUFHSUMsIHJldHVybjspOwoJSVJEQV9BU1NFUlQoc2tiICE9IE5VTEwsIHJldHVybjspOwoKCS8qCgkgKiAgU3BsaXQgZnJhbWUgaW50byBhIG51bWJlciBvZiBzZWdtZW50cwoJICovCgl3aGlsZSAoc2tiLT5sZW4gPiBzZWxmLT5tYXhfc2VnX3NpemUpIHsKCQlJUkRBX0RFQlVHKDIsICIlcygpLCBmcmFnbWVudGluZyAuLi5cbiIsIF9fRlVOQ1RJT05fXyk7CgoJCS8qIE1ha2UgbmV3IHNlZ21lbnQgKi8KCQlmcmFnID0gYWxsb2Nfc2tiKHNlbGYtPm1heF9zZWdfc2l6ZStzZWxmLT5tYXhfaGVhZGVyX3NpemUsCgkJCQkgR0ZQX0FUT01JQyk7CgkJaWYgKCFmcmFnKQoJCQlyZXR1cm47CgoJCXNrYl9yZXNlcnZlKGZyYWcsIHNlbGYtPm1heF9oZWFkZXJfc2l6ZSk7CgoJCS8qIENvcHkgZGF0YSBmcm9tIHRoZSBvcmlnaW5hbCBza2IgaW50byB0aGlzIGZyYWdtZW50LiAqLwoJCW1lbWNweShza2JfcHV0KGZyYWcsIHNlbGYtPm1heF9zZWdfc2l6ZSksIHNrYi0+ZGF0YSwKCQkgICAgICAgc2VsZi0+bWF4X3NlZ19zaXplKTsKCgkJLyogSW5zZXJ0IFRUUCBoZWFkZXIsIHdpdGggdGhlIG1vcmUgYml0IHNldCAqLwoJCWZyYW1lID0gc2tiX3B1c2goZnJhZywgVFRQX0hFQURFUik7CgkJZnJhbWVbMF0gPSBUVFBfTU9SRTsKCgkJLyogSGlkZSB0aGUgY29waWVkIGRhdGEgZnJvbSB0aGUgb3JpZ2luYWwgc2tiICovCgkJc2tiX3B1bGwoc2tiLCBzZWxmLT5tYXhfc2VnX3NpemUpOwoKCQkvKiBRdWV1ZSBmcmFnbWVudCAqLwoJCXNrYl9xdWV1ZV90YWlsKCZzZWxmLT50eF9xdWV1ZSwgZnJhZyk7Cgl9CgkvKiBRdWV1ZSB3aGF0IGlzIGxlZnQgb2YgdGhlIG9yaWdpbmFsIHNrYiAqLwoJSVJEQV9ERUJVRygyLCAiJXMoKSwgcXVldWluZyBsYXN0IHNlZ21lbnRcbiIsIF9fRlVOQ1RJT05fXyk7CgoJZnJhbWUgPSBza2JfcHVzaChza2IsIFRUUF9IRUFERVIpOwoJZnJhbWVbMF0gPSAweDAwOyAvKiBDbGVhciBtb3JlIGJpdCAqLwoKCS8qIFF1ZXVlIGZyYWdtZW50ICovCglza2JfcXVldWVfdGFpbCgmc2VsZi0+dHhfcXVldWUsIHNrYik7Cn0KCi8qCiAqIEZ1bmN0aW9uIGlydHRwX3BhcmFtX21heF9zZHVfc2l6ZSAoc2VsZiwgcGFyYW0pCiAqCiAqICAgIEhhbmRsZSB0aGUgTWF4U2R1U2l6ZSBwYXJhbWV0ZXIgaW4gdGhlIGNvbm5lY3QgZnJhbWVzLCB0aGlzIGZ1bmN0aW9uCiAqICAgIHdpbGwgYmUgY2FsbGVkIGJvdGggd2hlbiB0aGlzIHBhcmFtZXRlciBuZWVkcyB0byBiZSBpbnNlcnRlZCBpbnRvLCBhbmQKICogICAgZXh0cmFjdGVkIGZyb20gdGhlIGNvbm5lY3QgZnJhbWVzCiAqLwpzdGF0aWMgaW50IGlydHRwX3BhcmFtX21heF9zZHVfc2l6ZSh2b2lkICppbnN0YW5jZSwgaXJkYV9wYXJhbV90ICpwYXJhbSwKCQkJCSAgICBpbnQgZ2V0KQp7CglzdHJ1Y3QgdHNhcF9jYiAqc2VsZjsKCglzZWxmID0gKHN0cnVjdCB0c2FwX2NiICopIGluc3RhbmNlOwoKCUlSREFfQVNTRVJUKHNlbGYgIT0gTlVMTCwgcmV0dXJuIC0xOyk7CglJUkRBX0FTU0VSVChzZWxmLT5tYWdpYyA9PSBUVFBfVFNBUF9NQUdJQywgcmV0dXJuIC0xOyk7CgoJaWYgKGdldCkKCQlwYXJhbS0+cHYuaSA9IHNlbGYtPnR4X21heF9zZHVfc2l6ZTsKCWVsc2UKCQlzZWxmLT50eF9tYXhfc2R1X3NpemUgPSBwYXJhbS0+cHYuaTsKCglJUkRBX0RFQlVHKDEsICIlcygpLCBNYXhTZHVTaXplPSVkXG4iLCBfX0ZVTkNUSU9OX18sIHBhcmFtLT5wdi5pKTsKCglyZXR1cm4gMDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKiBDTElFTlQgQ0FMTFMgKioqKioqKioqKioqKioqKioqKioqKioqKioqLwovKioqKioqKioqKioqKioqKioqKioqKioqKiogTE1QIENBTExCQUNLUyAqKioqKioqKioqKioqKioqKioqKioqKioqKi8KLyogRXZlcnl0aGluZyBpcyBoYXBwaWx5IG1peGVkIHVwLiBXYWl0aW5nIGZvciBuZXh0IGNsZWFuIHVwIC0gSmVhbiBJSSAqLwoKLyoKICogRnVuY3Rpb24gaXJ0dHBfb3Blbl90c2FwIChzdHNhcCwgbm90aWZ5KQogKgogKiAgICBDcmVhdGUgVFNBUCBjb25uZWN0aW9uIGVuZHBvaW50LAogKi8Kc3RydWN0IHRzYXBfY2IgKmlydHRwX29wZW5fdHNhcChfX3U4IHN0c2FwX3NlbCwgaW50IGNyZWRpdCwgbm90aWZ5X3QgKm5vdGlmeSkKewoJc3RydWN0IHRzYXBfY2IgKnNlbGY7CglzdHJ1Y3QgbHNhcF9jYiAqbHNhcDsKCW5vdGlmeV90IHR0cF9ub3RpZnk7CgoJSVJEQV9BU1NFUlQoaXJ0dHAtPm1hZ2ljID09IFRUUF9NQUdJQywgcmV0dXJuIE5VTEw7KTsKCgkvKiBUaGUgSXJMTVAgc3BlYyAoSXJMTVAgMS4xIHAxMCkgc2F5cyB0aGF0IHdlIGhhdmUgdGhlIHJpZ2h0IHRvCgkgKiB1c2Ugb25seSAweDAxLTB4NkYuIE9mIGNvdXJzZSwgd2UgY2FuIHVzZSBMU0FQX0FOWSBhcyB3ZWxsLgoJICogSmVhbklJICovCglpZigoc3RzYXBfc2VsICE9IExTQVBfQU5ZKSAmJgoJICAgKChzdHNhcF9zZWwgPCAweDAxKSB8fCAoc3RzYXBfc2VsID49IDB4NzApKSkgewoJCUlSREFfREVCVUcoMCwgIiVzKCksIGludmFsaWQgdHNhcCFcbiIsIF9fRlVOQ1RJT05fXyk7CgkJcmV0dXJuIE5VTEw7Cgl9CgoJc2VsZiA9IGt6YWxsb2Moc2l6ZW9mKHN0cnVjdCB0c2FwX2NiKSwgR0ZQX0FUT01JQyk7CglpZiAoc2VsZiA9PSBOVUxMKSB7CgkJSVJEQV9ERUJVRygwLCAiJXMoKSwgdW5hYmxlIHRvIGttYWxsb2MhXG4iLCBfX0ZVTkNUSU9OX18pOwoJCXJldHVybiBOVUxMOwoJfQoJc3Bpbl9sb2NrX2luaXQoJnNlbGYtPmxvY2spOwoKCS8qIEluaXRpYWxpc2UgdG9kbyB0aW1lciAqLwoJaW5pdF90aW1lcigmc2VsZi0+dG9kb190aW1lcik7CglzZWxmLT50b2RvX3RpbWVyLmRhdGEgICAgID0gKHVuc2lnbmVkIGxvbmcpIHNlbGY7CglzZWxmLT50b2RvX3RpbWVyLmZ1bmN0aW9uID0gJmlydHRwX3RvZG9fZXhwaXJlZDsKCgkvKiBJbml0aWFsaXplIGNhbGxiYWNrcyBmb3IgSXJMTVAgdG8gdXNlICovCglpcmRhX25vdGlmeV9pbml0KCZ0dHBfbm90aWZ5KTsKCXR0cF9ub3RpZnkuY29ubmVjdF9jb25maXJtID0gaXJ0dHBfY29ubmVjdF9jb25maXJtOwoJdHRwX25vdGlmeS5jb25uZWN0X2luZGljYXRpb24gPSBpcnR0cF9jb25uZWN0X2luZGljYXRpb247Cgl0dHBfbm90aWZ5LmRpc2Nvbm5lY3RfaW5kaWNhdGlvbiA9IGlydHRwX2Rpc2Nvbm5lY3RfaW5kaWNhdGlvbjsKCXR0cF9ub3RpZnkuZGF0YV9pbmRpY2F0aW9uID0gaXJ0dHBfZGF0YV9pbmRpY2F0aW9uOwoJdHRwX25vdGlmeS51ZGF0YV9pbmRpY2F0aW9uID0gaXJ0dHBfdWRhdGFfaW5kaWNhdGlvbjsKCXR0cF9ub3RpZnkuZmxvd19pbmRpY2F0aW9uID0gaXJ0dHBfZmxvd19pbmRpY2F0aW9uOwoJaWYobm90aWZ5LT5zdGF0dXNfaW5kaWNhdGlvbiAhPSBOVUxMKQoJCXR0cF9ub3RpZnkuc3RhdHVzX2luZGljYXRpb24gPSBpcnR0cF9zdGF0dXNfaW5kaWNhdGlvbjsKCXR0cF9ub3RpZnkuaW5zdGFuY2UgPSBzZWxmOwoJc3RybmNweSh0dHBfbm90aWZ5Lm5hbWUsIG5vdGlmeS0+bmFtZSwgTk9USUZZX01BWF9OQU1FKTsKCglzZWxmLT5tYWdpYyA9IFRUUF9UU0FQX01BR0lDOwoJc2VsZi0+Y29ubmVjdGVkID0gRkFMU0U7CgoJc2tiX3F1ZXVlX2hlYWRfaW5pdCgmc2VsZi0+cnhfcXVldWUpOwoJc2tiX3F1ZXVlX2hlYWRfaW5pdCgmc2VsZi0+dHhfcXVldWUpOwoJc2tiX3F1ZXVlX2hlYWRfaW5pdCgmc2VsZi0+cnhfZnJhZ21lbnRzKTsKCS8qCgkgKiAgQ3JlYXRlIExTQVAgYXQgSXJMTVAgbGF5ZXIKCSAqLwoJbHNhcCA9IGlybG1wX29wZW5fbHNhcChzdHNhcF9zZWwsICZ0dHBfbm90aWZ5LCAwKTsKCWlmIChsc2FwID09IE5VTEwpIHsKCQlJUkRBX1dBUk5JTkcoIiVzOiB1bmFibGUgdG8gYWxsb2NhdGUgTFNBUCEhXG4iLCBfX0ZVTkNUSU9OX18pOwoJCXJldHVybiBOVUxMOwoJfQoKCS8qCgkgKiAgSWYgdXNlciBzcGVjaWZpZWQgTFNBUF9BTlkgYXMgc291cmNlIFRTQVAgc2VsZWN0b3IsIHRoZW4gSXJMTVAKCSAqICB3aWxsIHJlcGxhY2UgaXQgd2l0aCB3aGF0ZXZlciBzb3VyY2Ugc2VsZWN0b3Igd2hpY2ggaXMgZnJlZSwgc28KCSAqICB0aGUgc3RzYXBfc2VsIHdlIGhhdmUgbWlnaHQgbm90IGJlIHZhbGlkIGFueW1vcmUKCSAqLwoJc2VsZi0+c3RzYXBfc2VsID0gbHNhcC0+c2xzYXBfc2VsOwoJSVJEQV9ERUJVRyg0LCAiJXMoKSwgc3RzYXBfc2VsPSUwMnhcbiIsIF9fRlVOQ1RJT05fXywgc2VsZi0+c3RzYXBfc2VsKTsKCglzZWxmLT5ub3RpZnkgPSAqbm90aWZ5OwoJc2VsZi0+bHNhcCA9IGxzYXA7CgoJaGFzaGJpbl9pbnNlcnQoaXJ0dHAtPnRzYXBzLCAoaXJkYV9xdWV1ZV90ICopIHNlbGYsIChsb25nKSBzZWxmLCBOVUxMKTsKCglpZiAoY3JlZGl0ID4gVFRQX1JYX01BWF9DUkVESVQpCgkJc2VsZi0+aW5pdGlhbF9jcmVkaXQgPSBUVFBfUlhfTUFYX0NSRURJVDsKCWVsc2UKCQlzZWxmLT5pbml0aWFsX2NyZWRpdCA9IGNyZWRpdDsKCglyZXR1cm4gc2VsZjsKfQpFWFBPUlRfU1lNQk9MKGlydHRwX29wZW5fdHNhcCk7CgovKgogKiBGdW5jdGlvbiBpcnR0cF9jbG9zZSAoaGFuZGxlKQogKgogKiAgICBSZW1vdmUgYW4gaW5zdGFuY2Ugb2YgYSBUU0FQLiBUaGlzIGZ1bmN0aW9uIHNob3VsZCBvbmx5IGRlYWwgd2l0aCB0aGUKICogICAgZGVhbGxvY2F0aW9uIG9mIHRoZSBUU0FQLCBhbmQgcmVzZXR0aW5nIG9mIHRoZSBUU0FQcyB2YWx1ZXM7CiAqCiAqLwpzdGF0aWMgdm9pZCBfX2lydHRwX2Nsb3NlX3RzYXAoc3RydWN0IHRzYXBfY2IgKnNlbGYpCnsKCS8qIEZpcnN0IG1ha2Ugc3VyZSB3ZSdyZSBjb25uZWN0ZWQuICovCglJUkRBX0FTU0VSVChzZWxmICE9IE5VTEwsIHJldHVybjspOwoJSVJEQV9BU1NFUlQoc2VsZi0+bWFnaWMgPT0gVFRQX1RTQVBfTUFHSUMsIHJldHVybjspOwoKCWlydHRwX2ZsdXNoX3F1ZXVlcyhzZWxmKTsKCglkZWxfdGltZXIoJnNlbGYtPnRvZG9fdGltZXIpOwoKCS8qIFRoaXMgb25lIHdvbid0IGJlIGNsZWFuZWQgdXAgaWYgd2UgYXJlIGRpc2Nvbm5lY3RfcGVuZCArIGNsb3NlX3BlbmQKCSAqIGFuZCB3ZSByZWNlaXZlIGEgZGlzY29ubmVjdF9pbmRpY2F0aW9uICovCglpZiAoc2VsZi0+ZGlzY29ubmVjdF9za2IpCgkJZGV2X2tmcmVlX3NrYihzZWxmLT5kaXNjb25uZWN0X3NrYik7CgoJc2VsZi0+Y29ubmVjdGVkID0gRkFMU0U7CglzZWxmLT5tYWdpYyA9IH5UVFBfVFNBUF9NQUdJQzsKCglrZnJlZShzZWxmKTsKfQoKLyoKICogRnVuY3Rpb24gaXJ0dHBfY2xvc2UgKHNlbGYpCiAqCiAqICAgIFJlbW92ZSBUU0FQIGZyb20gbGlzdCBvZiBhbGwgVFNBUHMgYW5kIHRoZW4gZGVhbGxvY2F0ZSBhbGwgcmVzb3VyY2VzCiAqICAgIGFzc29jaWF0ZWQgd2l0aCB0aGlzIFRTQVAKICoKICogTm90ZSA6IGJlY2F1c2Ugd2UgKmZyZWUqIHRoZSB0c2FwIHN0cnVjdHVyZSwgaXQgaXMgdGhlIHJlc3BvbnNpYmlsaXR5CiAqIG9mIHRoZSBjYWxsZXIgdG8gbWFrZSBzdXJlIHdlIGFyZSBjYWxsZWQgb25seSBvbmNlIGFuZCB0byBkZWFsIHdpdGgKICogcG9zc2libGUgcmFjZSBjb25kaXRpb25zLiAtIEplYW4gSUkKICovCmludCBpcnR0cF9jbG9zZV90c2FwKHN0cnVjdCB0c2FwX2NiICpzZWxmKQp7CglzdHJ1Y3QgdHNhcF9jYiAqdHNhcDsKCglJUkRBX0RFQlVHKDQsICIlcygpXG4iLCBfX0ZVTkNUSU9OX18pOwoKCUlSREFfQVNTRVJUKHNlbGYgIT0gTlVMTCwgcmV0dXJuIC0xOyk7CglJUkRBX0FTU0VSVChzZWxmLT5tYWdpYyA9PSBUVFBfVFNBUF9NQUdJQywgcmV0dXJuIC0xOyk7CgoJLyogTWFrZSBzdXJlIHRzYXAgaGFzIGJlZW4gZGlzY29ubmVjdGVkICovCglpZiAoc2VsZi0+Y29ubmVjdGVkKSB7CgkJLyogQ2hlY2sgaWYgZGlzY29ubmVjdCBpcyBub3QgcGVuZGluZyAqLwoJCWlmICghdGVzdF9iaXQoMCwgJnNlbGYtPmRpc2Nvbm5lY3RfcGVuZCkpIHsKCQkJSVJEQV9XQVJOSU5HKCIlczogVFNBUCBzdGlsbCBjb25uZWN0ZWQhXG4iLAoJCQkJICAgICBfX0ZVTkNUSU9OX18pOwoJCQlpcnR0cF9kaXNjb25uZWN0X3JlcXVlc3Qoc2VsZiwgTlVMTCwgUF9OT1JNQUwpOwoJCX0KCQlzZWxmLT5jbG9zZV9wZW5kID0gVFJVRTsKCQlpcnR0cF9zdGFydF90b2RvX3RpbWVyKHNlbGYsIEhaLzEwKTsKCgkJcmV0dXJuIDA7IC8qIFdpbGwgYmUgYmFjayEgKi8KCX0KCgl0c2FwID0gaGFzaGJpbl9yZW1vdmUoaXJ0dHAtPnRzYXBzLCAobG9uZykgc2VsZiwgTlVMTCk7CgoJSVJEQV9BU1NFUlQodHNhcCA9PSBzZWxmLCByZXR1cm4gLTE7KTsKCgkvKiBDbG9zZSBjb3JyZXNwb25kaW5nIExTQVAgKi8KCWlmIChzZWxmLT5sc2FwKSB7CgkJaXJsbXBfY2xvc2VfbHNhcChzZWxmLT5sc2FwKTsKCQlzZWxmLT5sc2FwID0gTlVMTDsKCX0KCglfX2lydHRwX2Nsb3NlX3RzYXAoc2VsZik7CgoJcmV0dXJuIDA7Cn0KRVhQT1JUX1NZTUJPTChpcnR0cF9jbG9zZV90c2FwKTsKCi8qCiAqIEZ1bmN0aW9uIGlydHRwX3VkYXRhX3JlcXVlc3QgKHNlbGYsIHNrYikKICoKICogICAgU2VuZCB1bnJlbGlhYmxlIGRhdGEgb24gdGhpcyBUU0FQCiAqCiAqLwppbnQgaXJ0dHBfdWRhdGFfcmVxdWVzdChzdHJ1Y3QgdHNhcF9jYiAqc2VsZiwgc3RydWN0IHNrX2J1ZmYgKnNrYikKewoJSVJEQV9BU1NFUlQoc2VsZiAhPSBOVUxMLCByZXR1cm4gLTE7KTsKCUlSREFfQVNTRVJUKHNlbGYtPm1hZ2ljID09IFRUUF9UU0FQX01BR0lDLCByZXR1cm4gLTE7KTsKCUlSREFfQVNTRVJUKHNrYiAhPSBOVUxMLCByZXR1cm4gLTE7KTsKCglJUkRBX0RFQlVHKDQsICIlcygpXG4iLCBfX0ZVTkNUSU9OX18pOwoKCS8qIENoZWNrIHRoYXQgbm90aGluZyBiYWQgaGFwcGVucyAqLwoJaWYgKChza2ItPmxlbiA9PSAwKSB8fCAoIXNlbGYtPmNvbm5lY3RlZCkpIHsKCQlJUkRBX0RFQlVHKDEsICIlcygpLCBObyBkYXRhLCBvciBub3QgY29ubmVjdGVkXG4iLAoJCQkgICBfX0ZVTkNUSU9OX18pOwoJCWdvdG8gZXJyOwoJfQoKCWlmIChza2ItPmxlbiA+IHNlbGYtPm1heF9zZWdfc2l6ZSkgewoJCUlSREFfREVCVUcoMSwgIiVzKCksIFVEYXRhIGlzIHRvIGxhcmdlIGZvciBJckxBUCFcbiIsCgkJCSAgIF9fRlVOQ1RJT05fXyk7CgkJZ290byBlcnI7Cgl9CgoJaXJsbXBfdWRhdGFfcmVxdWVzdChzZWxmLT5sc2FwLCBza2IpOwoJc2VsZi0+c3RhdHMudHhfcGFja2V0cysrOwoKCXJldHVybiAwOwoKZXJyOgoJZGV2X2tmcmVlX3NrYihza2IpOwoJcmV0dXJuIC0xOwp9CkVYUE9SVF9TWU1CT0woaXJ0dHBfdWRhdGFfcmVxdWVzdCk7CgoKLyoKICogRnVuY3Rpb24gaXJ0dHBfZGF0YV9yZXF1ZXN0IChoYW5kbGUsIHNrYikKICoKICogICAgUXVldWUgZnJhbWUgZm9yIHRyYW5zbWlzc2lvbi4gSWYgU0FSIGlzIGVuYWJsZWQsIGZyYWdlbWVudCB0aGUgZnJhbWUKICogICAgYW5kIHF1ZXVlIHRoZSBmcmFnbWVudHMgZm9yIHRyYW5zbWlzc2lvbgogKi8KaW50IGlydHRwX2RhdGFfcmVxdWVzdChzdHJ1Y3QgdHNhcF9jYiAqc2VsZiwgc3RydWN0IHNrX2J1ZmYgKnNrYikKewoJX191OCAqZnJhbWU7CglpbnQgcmV0OwoKCUlSREFfQVNTRVJUKHNlbGYgIT0gTlVMTCwgcmV0dXJuIC0xOyk7CglJUkRBX0FTU0VSVChzZWxmLT5tYWdpYyA9PSBUVFBfVFNBUF9NQUdJQywgcmV0dXJuIC0xOyk7CglJUkRBX0FTU0VSVChza2IgIT0gTlVMTCwgcmV0dXJuIC0xOyk7CgoJSVJEQV9ERUJVRygyLCAiJXMoKSA6IHF1ZXVlIGxlbiA9ICVkXG4iLCBfX0ZVTkNUSU9OX18sCgkJICAgc2tiX3F1ZXVlX2xlbigmc2VsZi0+dHhfcXVldWUpKTsKCgkvKiBDaGVjayB0aGF0IG5vdGhpbmcgYmFkIGhhcHBlbnMgKi8KCWlmICgoc2tiLT5sZW4gPT0gMCkgfHwgKCFzZWxmLT5jb25uZWN0ZWQpKSB7CgkJSVJEQV9XQVJOSU5HKCIlczogTm8gZGF0YSwgb3Igbm90IGNvbm5lY3RlZFxuIiwgX19GVU5DVElPTl9fKTsKCQlyZXQgPSAtRU5PVENPTk47CgkJZ290byBlcnI7Cgl9CgoJLyoKCSAqICBDaGVjayBpZiBTQVIgaXMgZGlzYWJsZWQsIGFuZCB0aGUgZnJhbWUgaXMgbGFyZ2VyIHRoYW4gd2hhdCBmaXRzCgkgKiAgaW5zaWRlIGFuIElyTEFQIGZyYW1lCgkgKi8KCWlmICgoc2VsZi0+dHhfbWF4X3NkdV9zaXplID09IDApICYmIChza2ItPmxlbiA+IHNlbGYtPm1heF9zZWdfc2l6ZSkpIHsKCQlJUkRBX0VSUk9SKCIlczogU0FSIGRpc2FibGVkLCBhbmQgZGF0YSBpcyB0byBsYXJnZSBmb3IgSXJMQVAhXG4iLAoJCQkgICBfX0ZVTkNUSU9OX18pOwoJCXJldCA9IC1FTVNHU0laRTsKCQlnb3RvIGVycjsKCX0KCgkvKgoJICogIENoZWNrIGlmIFNBUiBpcyBlbmFibGVkLCBhbmQgdGhlIGZyYW1lIGlzIGxhcmdlciB0aGFuIHRoZQoJICogIFR4TWF4U2R1U2l6ZQoJICovCglpZiAoKHNlbGYtPnR4X21heF9zZHVfc2l6ZSAhPSAwKSAmJgoJICAgIChzZWxmLT50eF9tYXhfc2R1X3NpemUgIT0gVFRQX1NBUl9VTkJPVU5EKSAmJgoJICAgIChza2ItPmxlbiA+IHNlbGYtPnR4X21heF9zZHVfc2l6ZSkpCgl7CgkJSVJEQV9FUlJPUigiJXM6IFNBUiBlbmFibGVkLCBidXQgZGF0YSBpcyBsYXJnZXIgdGhhbiBUeE1heFNkdVNpemUhXG4iLAoJCQkgICBfX0ZVTkNUSU9OX18pOwoJCXJldCA9IC1FTVNHU0laRTsKCQlnb3RvIGVycjsKCX0KCS8qCgkgKiAgQ2hlY2sgaWYgdHJhbnNtaXQgcXVldWUgaXMgZnVsbAoJICovCglpZiAoc2tiX3F1ZXVlX2xlbigmc2VsZi0+dHhfcXVldWUpID49IFRUUF9UWF9NQVhfUVVFVUUpIHsKCQkvKgoJCSAqICBHaXZlIGl0IGEgY2hhbmNlIHRvIGVtcHR5IGl0c2VsZgoJCSAqLwoJCWlydHRwX3J1bl90eF9xdWV1ZShzZWxmKTsKCgkJLyogRHJvcCBwYWNrZXQuIFRoaXMgZXJyb3IgY29kZSBzaG91bGQgdHJpZ2dlciB0aGUgY2FsbGVyCgkJICogdG8gcmVzZW5kIHRoZSBkYXRhIGluIHRoZSBjbGllbnQgY29kZSAtIEplYW4gSUkgKi8KCQlyZXQgPSAtRU5PQlVGUzsKCQlnb3RvIGVycjsKCX0KCgkvKiBRdWV1ZSBmcmFtZSwgb3IgcXVldWUgZnJhbWUgc2VnbWVudHMgKi8KCWlmICgoc2VsZi0+dHhfbWF4X3NkdV9zaXplID09IDApIHx8IChza2ItPmxlbiA8IHNlbGYtPm1heF9zZWdfc2l6ZSkpIHsKCQkvKiBRdWV1ZSBmcmFtZSAqLwoJCUlSREFfQVNTRVJUKHNrYl9oZWFkcm9vbShza2IpID49IFRUUF9IRUFERVIsIHJldHVybiAtMTspOwoJCWZyYW1lID0gc2tiX3B1c2goc2tiLCBUVFBfSEVBREVSKTsKCQlmcmFtZVswXSA9IDB4MDA7IC8qIENsZWFyIG1vcmUgYml0ICovCgoJCXNrYl9xdWV1ZV90YWlsKCZzZWxmLT50eF9xdWV1ZSwgc2tiKTsKCX0gZWxzZSB7CgkJLyoKCQkgKiAgRnJhZ21lbnQgdGhlIGZyYW1lLCB0aGlzIGZ1bmN0aW9uIHdpbGwgYWxzbyBxdWV1ZSB0aGUKCQkgKiAgZnJhZ21lbnRzLCB3ZSBkb24ndCBjYXJlIGFib3V0IHRoZSBmYWN0IHRoZSB0cmFuc21pdAoJCSAqICBxdWV1ZSBtYXkgYmUgb3ZlcmZpbGxlZCBieSBhbGwgdGhlIHNlZ21lbnRzIGZvciBhIGxpdHRsZQoJCSAqICB3aGlsZQoJCSAqLwoJCWlydHRwX2ZyYWdtZW50X3NrYihzZWxmLCBza2IpOwoJfQoKCS8qIENoZWNrIGlmIHdlIGNhbiBhY2NlcHQgbW9yZSBkYXRhIGZyb20gY2xpZW50ICovCglpZiAoKCFzZWxmLT50eF9zZHVfYnVzeSkgJiYKCSAgICAoc2tiX3F1ZXVlX2xlbigmc2VsZi0+dHhfcXVldWUpID4gVFRQX1RYX0hJR0hfVEhSRVNIT0xEKSkgewoJCS8qIFR4IHF1ZXVlIGZpbGxpbmcgdXAsIHNvIHN0b3AgY2xpZW50LiAqLwoJCWlmIChzZWxmLT5ub3RpZnkuZmxvd19pbmRpY2F0aW9uKSB7CgkJCXNlbGYtPm5vdGlmeS5mbG93X2luZGljYXRpb24oc2VsZi0+bm90aWZ5Lmluc3RhbmNlLAoJCQkJCQkgICAgIHNlbGYsIEZMT1dfU1RPUCk7CgkJfQoJCS8qIHNlbGYtPnR4X3NkdV9idXN5IGlzIHRoZSBzdGF0ZSBvZiB0aGUgY2xpZW50LgoJCSAqIFVwZGF0ZSBzdGF0ZSBhZnRlciBub3RpZnlpbmcgY2xpZW50IHRvIGF2b2lkCgkJICogcmFjZSBjb25kaXRpb24gd2l0aCBpcnR0cF9mbG93X2luZGljYXRpb24oKS4KCQkgKiBJZiB0aGUgcXVldWUgZW1wdHkgaXRzZWxmIGFmdGVyIG91ciB0ZXN0IGJ1dCBiZWZvcmUKCQkgKiB3ZSBzZXQgdGhlIGZsYWcsIHdlIHdpbGwgZml4IG91cnNlbHZlcyBiZWxvdyBpbgoJCSAqIGlydHRwX3J1bl90eF9xdWV1ZSgpLgoJCSAqIEplYW4gSUkgKi8KCQlzZWxmLT50eF9zZHVfYnVzeSA9IFRSVUU7Cgl9CgoJLyogVHJ5IHRvIG1ha2Ugc29tZSBwcm9ncmVzcyAqLwoJaXJ0dHBfcnVuX3R4X3F1ZXVlKHNlbGYpOwoKCXJldHVybiAwOwoKZXJyOgoJZGV2X2tmcmVlX3NrYihza2IpOwoJcmV0dXJuIHJldDsKfQpFWFBPUlRfU1lNQk9MKGlydHRwX2RhdGFfcmVxdWVzdCk7CgovKgogKiBGdW5jdGlvbiBpcnR0cF9ydW5fdHhfcXVldWUgKHNlbGYpCiAqCiAqICAgIFRyYW5zbWl0IHBhY2tldHMgcXVldWVkIGZvciB0cmFuc21pc3Npb24gKGlmIHBvc3NpYmxlKQogKgogKi8Kc3RhdGljIHZvaWQgaXJ0dHBfcnVuX3R4X3F1ZXVlKHN0cnVjdCB0c2FwX2NiICpzZWxmKQp7CglzdHJ1Y3Qgc2tfYnVmZiAqc2tiOwoJdW5zaWduZWQgbG9uZyBmbGFnczsKCWludCBuOwoKCUlSREFfREVCVUcoMiwgIiVzKCkgOiBzZW5kX2NyZWRpdCA9ICVkLCBxdWV1ZV9sZW4gPSAlZFxuIiwKCQkgICBfX0ZVTkNUSU9OX18sCgkJICAgc2VsZi0+c2VuZF9jcmVkaXQsIHNrYl9xdWV1ZV9sZW4oJnNlbGYtPnR4X3F1ZXVlKSk7CgoJLyogR2V0IGV4Y2x1c2l2ZSBhY2Nlc3MgdG8gdGhlIHR4IHF1ZXVlLCBvdGhlcndpc2UgZG9uJ3QgdG91Y2ggaXQgKi8KCWlmIChpcmRhX2xvY2soJnNlbGYtPnR4X3F1ZXVlX2xvY2spID09IEZBTFNFKQoJCXJldHVybjsKCgkvKiBUcnkgdG8gc2VuZCBvdXQgZnJhbWVzIGFzIGxvbmcgYXMgd2UgaGF2ZSBjcmVkaXRzCgkgKiBhbmQgYXMgbG9uZyBhcyBMQVAgaXMgbm90IGZ1bGwuIElmIExBUCBpcyBmdWxsLCBpdCB3aWxsCgkgKiBwb2xsIHVzIHRocm91Z2ggaXJ0dHBfZmxvd19pbmRpY2F0aW9uKCkgLSBKZWFuIElJICovCgl3aGlsZSAoKHNlbGYtPnNlbmRfY3JlZGl0ID4gMCkgJiYKCSAgICAgICAoIWlybG1wX2xhcF90eF9xdWV1ZV9mdWxsKHNlbGYtPmxzYXApKSAmJgoJICAgICAgIChza2IgPSBza2JfZGVxdWV1ZSgmc2VsZi0+dHhfcXVldWUpKSkKCXsKCQkvKgoJCSAqICBTaW5jZSB3ZSBjYW4gdHJhbnNtaXQgYW5kIHJlY2VpdmUgZnJhbWVzIGNvbmN1cnJlbnRseSwKCQkgKiAgdGhlIGNvZGUgYmVsb3cgaXMgYSBjcml0aWNhbCByZWdpb24gYW5kIHdlIG11c3QgYXNzdXJlIHRoYXQKCQkgKiAgbm9ib2R5IG1lc3NlcyB3aXRoIHRoZSBjcmVkaXRzIHdoaWxlIHdlIHVwZGF0ZSB0aGVtLgoJCSAqLwoJCXNwaW5fbG9ja19pcnFzYXZlKCZzZWxmLT5sb2NrLCBmbGFncyk7CgoJCW4gPSBzZWxmLT5hdmFpbF9jcmVkaXQ7CgkJc2VsZi0+YXZhaWxfY3JlZGl0ID0gMDsKCgkJLyogT25seSByb29tIGZvciAxMjcgY3JlZGl0cyBpbiBmcmFtZSAqLwoJCWlmIChuID4gMTI3KSB7CgkJCXNlbGYtPmF2YWlsX2NyZWRpdCA9IG4tMTI3OwoJCQluID0gMTI3OwoJCX0KCQlzZWxmLT5yZW1vdGVfY3JlZGl0ICs9IG47CgkJc2VsZi0+c2VuZF9jcmVkaXQtLTsKCgkJc3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmc2VsZi0+bG9jaywgZmxhZ3MpOwoKCQkvKgoJCSAqICBNb3JlIGJpdCBtdXN0IGJlIHNldCBieSB0aGUgZGF0YV9yZXF1ZXN0KCkgb3IgZnJhZ21lbnQoKQoJCSAqICBmdW5jdGlvbnMKCQkgKi8KCQlza2ItPmRhdGFbMF0gfD0gKG4gJiAweDdmKTsKCgkJLyogRGV0YWNoIGZyb20gc29ja2V0LgoJCSAqIFRoZSBjdXJyZW50IHNrYiBoYXMgYSByZWZlcmVuY2UgdG8gdGhlIHNvY2tldCB0aGF0IHNlbnQKCQkgKiBpdCAoc2tiLT5zaykuIFdoZW4gd2UgcGFzcyBpdCB0byBJckxNUCwgdGhlIHNrYiB3aWxsIGJlCgkJICogc3RvcmVkIGluIGluIElyTEFQIChzZWxmLT53eF9saXN0KS4gV2hlbiB3ZSBhcmUgd2l0aGluCgkJICogSXJMQVAsIHdlIGxvc2UgdGhlIG5vdGlvbiBvZiBzb2NrZXQsIHNvIHdlIHNob3VsZCBub3QKCQkgKiBoYXZlIGEgcmVmZXJlbmNlIHRvIGEgc29ja2V0LiBTbywgd2UgZHJvcCBpdCBoZXJlLgoJCSAqCgkJICogV2h5IGRvZXMgaXQgbWF0dGVyID8KCQkgKiBXaGVuIHRoZSBza2IgaXMgZnJlZWQgKGtmcmVlX3NrYiksIGlmIGl0IGlzIGFzc29jaWF0ZWQKCQkgKiB3aXRoIGEgc29ja2V0LCBpdCByZWxlYXNlIGJ1ZmZlciBzcGFjZSBvbiB0aGUgc29ja2V0CgkJICogKHRocm91Z2ggc29ja193ZnJlZSgpIGFuZCBzb2NrX2RlZl93cml0ZV9zcGFjZSgpKS4KCQkgKiBJZiB0aGUgc29ja2V0IG5vIGxvbmdlciBleGlzdCwgd2UgbWF5IGNyYXNoLiBIYXJkLgoJCSAqIFdoZW4gd2UgY2xvc2UgYSBzb2NrZXQsIHdlIG1ha2Ugc3VyZSB0aGF0IGFzc29jaWF0ZWQgcGFja2V0cwoJCSAqIGluIElyVFRQIGFyZSBmcmVlZC4gSG93ZXZlciwgd2UgaGF2ZSBubyB3YXkgdG8gY2FuY2VsCgkJICogdGhlIHBhY2tldCB0aGF0IHdlIGhhdmUgcGFzc2VkIHRvIElyTEFQLiBTbywgaWYgYSBwYWNrZXQKCQkgKiByZW1haW5zIGluIElyTEFQIChyZXRyeSBvbiB0aGUgbGluayBvciBlbHNlKSBhZnRlciB3ZQoJCSAqIGNsb3NlIHRoZSBzb2NrZXQsIHdlIGFyZSBkZWFkICEKCQkgKiBKZWFuIElJICovCgkJaWYgKHNrYi0+c2sgIT0gTlVMTCkgewoJCQkvKiBJclNPQ0sgYXBwbGljYXRpb24sIElyT0JFWCwgLi4uICovCgkJCXNrYl9vcnBoYW4oc2tiKTsKCQl9CgkJCS8qIElyQ09NTSBvdmVyIElyVFRQLCBJckxBTiwgLi4uICovCgoJCS8qIFBhc3MgdGhlIHNrYiB0byBJckxNUCAtIGRvbmUgKi8KCQlpcmxtcF9kYXRhX3JlcXVlc3Qoc2VsZi0+bHNhcCwgc2tiKTsKCQlzZWxmLT5zdGF0cy50eF9wYWNrZXRzKys7Cgl9CgoJLyogQ2hlY2sgaWYgd2UgY2FuIGFjY2VwdCBtb3JlIGZyYW1lcyBmcm9tIGNsaWVudC4KCSAqIFdlIGRvbid0IHdhbnQgdG8gd2FpdCB1bnRpbCB0aGUgdG9kbyB0aW1lciB0byBkbyB0aGF0LCBhbmQgd2UKCSAqIGNhbid0IHVzZSB0YXNrbGV0cyAoZ3JyLi4uKSwgc28gd2UgYXJlIG9ibGlnZWQgdG8gZ2l2ZSBjb250cm9sCgkgKiB0byBjbGllbnQuIFRoYXQncyBvaywgdGhpcyB0ZXN0IHdpbGwgYmUgdHJ1ZSBub3QgdG9vIG9mdGVuCgkgKiAobWF4IG9uY2UgcGVyIExBUCB3aW5kb3cpIGFuZCB3ZSBhcmUgY2FsbGVkIGZyb20gcGxhY2VzCgkgKiB3aGVyZSB3ZSBjYW4gc3BlbmQgYSBiaXQgb2YgdGltZSBkb2luZyBzdHVmZi4gLSBKZWFuIElJICovCglpZiAoKHNlbGYtPnR4X3NkdV9idXN5KSAmJgoJICAgIChza2JfcXVldWVfbGVuKCZzZWxmLT50eF9xdWV1ZSkgPCBUVFBfVFhfTE9XX1RIUkVTSE9MRCkgJiYKCSAgICAoIXNlbGYtPmNsb3NlX3BlbmQpKQoJewoJCWlmIChzZWxmLT5ub3RpZnkuZmxvd19pbmRpY2F0aW9uKQoJCQlzZWxmLT5ub3RpZnkuZmxvd19pbmRpY2F0aW9uKHNlbGYtPm5vdGlmeS5pbnN0YW5jZSwKCQkJCQkJICAgICBzZWxmLCBGTE9XX1NUQVJUKTsKCgkJLyogc2VsZi0+dHhfc2R1X2J1c3kgaXMgdGhlIHN0YXRlIG9mIHRoZSBjbGllbnQuCgkJICogV2UgZG9uJ3QgcmVhbGx5IGhhdmUgYSByYWNlIGhlcmUsIGJ1dCBpdCdzIGFsd2F5cyBzYWZlcgoJCSAqIHRvIHVwZGF0ZSBvdXIgc3RhdGUgYWZ0ZXIgdGhlIGNsaWVudCAtIEplYW4gSUkgKi8KCQlzZWxmLT50eF9zZHVfYnVzeSA9IEZBTFNFOwoJfQoKCS8qIFJlc2V0IGxvY2sgKi8KCXNlbGYtPnR4X3F1ZXVlX2xvY2sgPSAwOwp9CgovKgogKiBGdW5jdGlvbiBpcnR0cF9naXZlX2NyZWRpdCAoc2VsZikKICoKICogICAgU2VuZCBhIGRhdGFsZXNzIGZsb3dkYXRhIFRUUC1QRFUgYW5kIGdpdmUgYXZhaWxhYmxlIGNyZWRpdCB0byBwZWVyCiAqICAgIFRTQVAKICovCnN0YXRpYyBpbmxpbmUgdm9pZCBpcnR0cF9naXZlX2NyZWRpdChzdHJ1Y3QgdHNhcF9jYiAqc2VsZikKewoJc3RydWN0IHNrX2J1ZmYgKnR4X3NrYiA9IE5VTEw7Cgl1bnNpZ25lZCBsb25nIGZsYWdzOwoJaW50IG47CgoJSVJEQV9BU1NFUlQoc2VsZiAhPSBOVUxMLCByZXR1cm47KTsKCUlSREFfQVNTRVJUKHNlbGYtPm1hZ2ljID09IFRUUF9UU0FQX01BR0lDLCByZXR1cm47KTsKCglJUkRBX0RFQlVHKDQsICIlcygpIHNlbmQ9JWQsYXZhaWw9JWQscmVtb3RlPSVkXG4iLAoJCSAgIF9fRlVOQ1RJT05fXywKCQkgICBzZWxmLT5zZW5kX2NyZWRpdCwgc2VsZi0+YXZhaWxfY3JlZGl0LCBzZWxmLT5yZW1vdGVfY3JlZGl0KTsKCgkvKiBHaXZlIGNyZWRpdCB0byBwZWVyICovCgl0eF9za2IgPSBhbGxvY19za2IoVFRQX01BWF9IRUFERVIsIEdGUF9BVE9NSUMpOwoJaWYgKCF0eF9za2IpCgkJcmV0dXJuOwoKCS8qIFJlc2VydmUgc3BhY2UgZm9yIExNUCwgYW5kIExBUCBoZWFkZXIgKi8KCXNrYl9yZXNlcnZlKHR4X3NrYiwgTE1QX01BWF9IRUFERVIpOwoKCS8qCgkgKiAgU2luY2Ugd2UgY2FuIHRyYW5zbWl0IGFuZCByZWNlaXZlIGZyYW1lcyBjb25jdXJyZW50bHksCgkgKiAgdGhlIGNvZGUgYmVsb3cgaXMgYSBjcml0aWNhbCByZWdpb24gYW5kIHdlIG11c3QgYXNzdXJlIHRoYXQKCSAqICBub2JvZHkgbWVzc2VzIHdpdGggdGhlIGNyZWRpdHMgd2hpbGUgd2UgdXBkYXRlIHRoZW0uCgkgKi8KCXNwaW5fbG9ja19pcnFzYXZlKCZzZWxmLT5sb2NrLCBmbGFncyk7CgoJbiA9IHNlbGYtPmF2YWlsX2NyZWRpdDsKCXNlbGYtPmF2YWlsX2NyZWRpdCA9IDA7CgoJLyogT25seSBzcGFjZSBmb3IgMTI3IGNyZWRpdHMgaW4gZnJhbWUgKi8KCWlmIChuID4gMTI3KSB7CgkJc2VsZi0+YXZhaWxfY3JlZGl0ID0gbiAtIDEyNzsKCQluID0gMTI3OwoJfQoJc2VsZi0+cmVtb3RlX2NyZWRpdCArPSBuOwoKCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJnNlbGYtPmxvY2ssIGZsYWdzKTsKCglza2JfcHV0KHR4X3NrYiwgMSk7Cgl0eF9za2ItPmRhdGFbMF0gPSAoX191OCkgKG4gJiAweDdmKTsKCglpcmxtcF9kYXRhX3JlcXVlc3Qoc2VsZi0+bHNhcCwgdHhfc2tiKTsKCXNlbGYtPnN0YXRzLnR4X3BhY2tldHMrKzsKfQoKLyoKICogRnVuY3Rpb24gaXJ0dHBfdWRhdGFfaW5kaWNhdGlvbiAoaW5zdGFuY2UsIHNhcCwgc2tiKQogKgogKiAgICBSZWNlaXZlZCBzb21lIHVuaXQtZGF0YSAodW5yZWxpYWJsZSkKICoKICovCnN0YXRpYyBpbnQgaXJ0dHBfdWRhdGFfaW5kaWNhdGlvbih2b2lkICppbnN0YW5jZSwgdm9pZCAqc2FwLAoJCQkJICBzdHJ1Y3Qgc2tfYnVmZiAqc2tiKQp7CglzdHJ1Y3QgdHNhcF9jYiAqc2VsZjsKCWludCBlcnI7CgoJSVJEQV9ERUJVRyg0LCAiJXMoKVxuIiwgX19GVU5DVElPTl9fKTsKCglzZWxmID0gKHN0cnVjdCB0c2FwX2NiICopIGluc3RhbmNlOwoKCUlSREFfQVNTRVJUKHNlbGYgIT0gTlVMTCwgcmV0dXJuIC0xOyk7CglJUkRBX0FTU0VSVChzZWxmLT5tYWdpYyA9PSBUVFBfVFNBUF9NQUdJQywgcmV0dXJuIC0xOyk7CglJUkRBX0FTU0VSVChza2IgIT0gTlVMTCwgcmV0dXJuIC0xOyk7CgoJc2VsZi0+c3RhdHMucnhfcGFja2V0cysrOwoKCS8qIEp1c3QgcGFzcyBkYXRhIHRvIGxheWVyIGFib3ZlICovCglpZiAoc2VsZi0+bm90aWZ5LnVkYXRhX2luZGljYXRpb24pIHsKCQllcnIgPSBzZWxmLT5ub3RpZnkudWRhdGFfaW5kaWNhdGlvbihzZWxmLT5ub3RpZnkuaW5zdGFuY2UsCgkJCQkJCSAgICBzZWxmLHNrYik7CgkJLyogU2FtZSBjb21tZW50IGFzIGluIGlydHRwX2RvX2RhdGFfaW5kaWNhdGlvbigpICovCgkJaWYgKCFlcnIpIAoJCQlyZXR1cm4gMDsKCX0KCS8qIEVpdGhlciBubyBoYW5kbGVyLCBvciBoYW5kbGVyIHJldHVybnMgYW4gZXJyb3IgKi8KCWRldl9rZnJlZV9za2Ioc2tiKTsKCglyZXR1cm4gMDsKfQoKLyoKICogRnVuY3Rpb24gaXJ0dHBfZGF0YV9pbmRpY2F0aW9uIChpbnN0YW5jZSwgc2FwLCBza2IpCiAqCiAqICAgIFJlY2VpdmUgc2VnbWVudCBmcm9tIElyTE1QLgogKgogKi8Kc3RhdGljIGludCBpcnR0cF9kYXRhX2luZGljYXRpb24odm9pZCAqaW5zdGFuY2UsIHZvaWQgKnNhcCwKCQkJCSBzdHJ1Y3Qgc2tfYnVmZiAqc2tiKQp7CglzdHJ1Y3QgdHNhcF9jYiAqc2VsZjsKCXVuc2lnbmVkIGxvbmcgZmxhZ3M7CglpbnQgbjsKCglzZWxmID0gKHN0cnVjdCB0c2FwX2NiICopIGluc3RhbmNlOwoKCW4gPSBza2ItPmRhdGFbMF0gJiAweDdmOyAgICAgLyogRXh0cmFjdCB0aGUgY3JlZGl0cyAqLwoKCXNlbGYtPnN0YXRzLnJ4X3BhY2tldHMrKzsKCgkvKiAgRGVhbCB3aXRoIGluYm91bmQgY3JlZGl0CgkgKiAgU2luY2Ugd2UgY2FuIHRyYW5zbWl0IGFuZCByZWNlaXZlIGZyYW1lcyBjb25jdXJyZW50bHksCgkgKiAgdGhlIGNvZGUgYmVsb3cgaXMgYSBjcml0aWNhbCByZWdpb24gYW5kIHdlIG11c3QgYXNzdXJlIHRoYXQKCSAqICBub2JvZHkgbWVzc2VzIHdpdGggdGhlIGNyZWRpdHMgd2hpbGUgd2UgdXBkYXRlIHRoZW0uCgkgKi8KCXNwaW5fbG9ja19pcnFzYXZlKCZzZWxmLT5sb2NrLCBmbGFncyk7CglzZWxmLT5zZW5kX2NyZWRpdCArPSBuOwoJaWYgKHNrYi0+bGVuID4gMSkKCQlzZWxmLT5yZW1vdGVfY3JlZGl0LS07CglzcGluX3VubG9ja19pcnFyZXN0b3JlKCZzZWxmLT5sb2NrLCBmbGFncyk7CgoJLyoKCSAqICBEYXRhIG9yIGRhdGFsZXNzIHBhY2tldD8gRGF0YWxlc3MgZnJhbWVzIGNvbnRhaW5zIG9ubHkgdGhlCgkgKiAgVFRQX0hFQURFUi4KCSAqLwoJaWYgKHNrYi0+bGVuID4gMSkgewoJCS8qCgkJICogIFdlIGRvbid0IHJlbW92ZSB0aGUgVFRQIGhlYWRlciwgc2luY2Ugd2UgbXVzdCBwcmVzZXJ2ZSB0aGUKCQkgKiAgbW9yZSBiaXQsIHNvIHRoZSBkZWZyYWdtZW50IHJvdXRpbmcga25vd3Mgd2hhdCB0byBkbwoJCSAqLwoJCXNrYl9xdWV1ZV90YWlsKCZzZWxmLT5yeF9xdWV1ZSwgc2tiKTsKCX0gZWxzZSB7CgkJLyogRGF0YWxlc3MgZmxvd2RhdGEgVFRQLVBEVSAqLwoJCWRldl9rZnJlZV9za2Ioc2tiKTsKCX0KCgoJLyogUHVzaCBkYXRhIHRvIHRoZSBoaWdoZXIgbGF5ZXIuCgkgKiBXZSBkbyBpdCBzeW5jaHJvbm91c2x5IGJlY2F1c2UgcnVubmluZyB0aGUgdG9kbyB0aW1lciBmb3IgZWFjaAoJICogcmVjZWl2ZSBwYWNrZXQgd291bGQgYmUgdG9vIG11Y2ggb3ZlcmhlYWQgYW5kIGxhdGVuY3kuCgkgKiBCeSBwYXNzaW5nIGNvbnRyb2wgdG8gdGhlIGhpZ2hlciBsYXllciwgd2UgcnVuIHRoZSByaXNrIHRoYXQKCSAqIGl0IG1heSB0YWtlIHRpbWUgb3IgZ3JhYiBhIGxvY2suIE1vc3Qgb2Z0ZW4sIHRoZSBoaWdoZXIgbGF5ZXIKCSAqIHdpbGwgb25seSBwdXQgcGFja2V0IGluIGEgcXVldWUuCgkgKiBBbnl3YXksIHBhY2tldHMgYXJlIG9ubHkgZHJpcHBpbmcgdGhyb3VnaCB0aGUgSXJEQSwgc28gd2UgY2FuCgkgKiBoYXZlIHRpbWUgYmVmb3JlIHRoZSBuZXh0IHBhY2tldC4KCSAqIEZ1cnRoZXIsIHdlIGFyZSBydW4gZnJvbSBORVRfQkgsIHNvIHRoZSB3b3JzZSB0aGF0IGNhbiBoYXBwZW4gaXMKCSAqIHVzIG1pc3NpbmcgdGhlIG9wdGltYWwgdGltZSB0byBzZW5kIGJhY2sgdGhlIFBGIGJpdCBpbiBMQVAuCgkgKiBKZWFuIElJICovCglpcnR0cF9ydW5fcnhfcXVldWUoc2VsZik7CgoJLyogV2Ugbm93IGdpdmUgY3JlZGl0cyB0byBwZWVyIGluIGlydHRwX3J1bl9yeF9xdWV1ZSgpLgoJICogV2UgbmVlZCB0byBzZW5kIGNyZWRpdCAqTk9XKiwgb3RoZXJ3aXNlIHdlIGFyZSBnb2luZwoJICogdG8gbWlzcyB0aGUgbmV4dCBUeCB3aW5kb3cuIFRoZSB0b2RvIHRpbWVyIG1heSB0YWtlCgkgKiBhIHdoaWxlIGJlZm9yZSBpdCdzIHJ1bi4uLiAtIEplYW4gSUkgKi8KCgkvKgoJICogSWYgdGhlIHBlZXIgZGV2aWNlIGhhcyBnaXZlbiB1cyBzb21lIGNyZWRpdHMgYW5kIHdlIGRpZG4ndCBoYXZlCiAgICAgICAgICogYW55b25lIGZyb20gYmVmb3JlLCB0aGVuIHdlIG5lZWQgdG8gc2hlZHVsZSB0aGUgdHggcXVldWUuCgkgKiBXZSBuZWVkIHRvIGRvIHRoYXQgYmVjYXVzZSBvdXIgVHggaGF2ZSBzdG9wcGVkIChzbyB3ZSBtYXkgbm90CgkgKiBnZXQgYW55IExBUCBmbG93IGluZGljYXRpb24pIGFuZCB0aGUgdXNlciBtYXkgYmUgc3RvcHBlZCBhcwoJICogd2VsbC4gLSBKZWFuIElJCgkgKi8KCWlmIChzZWxmLT5zZW5kX2NyZWRpdCA9PSBuKSB7CgkJLyogUmVzdGFydCBwdXNoaW5nIHN0dWZmIHRvIExBUCAqLwoJCWlydHRwX3J1bl90eF9xdWV1ZShzZWxmKTsKCQkvKiBOb3RlIDogd2UgZG9uJ3Qgd2FudCB0byBzY2hlZHVsZSB0aGUgdG9kbyB0aW1lcgoJCSAqIGJlY2F1c2UgaXQgaGFzIGhvcnJpYmxlIGxhdGVuY3kuIE5vIHRhc2tsZXRzCgkJICogYmVjYXVzZSB0aGUgdGFza2xldCBBUEkgaXMgYnJva2VuLiAtIEplYW4gSUkgKi8KCX0KCglyZXR1cm4gMDsKfQoKLyoKICogRnVuY3Rpb24gaXJ0dHBfc3RhdHVzX2luZGljYXRpb24gKHNlbGYsIHJlYXNvbikKICoKICogICAgU3RhdHVzX2luZGljYXRpb24sIGp1c3QgcGFzcyB0byB0aGUgaGlnaGVyIGxheWVyLi4uCiAqCiAqLwpzdGF0aWMgdm9pZCBpcnR0cF9zdGF0dXNfaW5kaWNhdGlvbih2b2lkICppbnN0YW5jZSwKCQkJCSAgICBMSU5LX1NUQVRVUyBsaW5rLCBMT0NLX1NUQVRVUyBsb2NrKQp7CglzdHJ1Y3QgdHNhcF9jYiAqc2VsZjsKCglJUkRBX0RFQlVHKDQsICIlcygpXG4iLCBfX0ZVTkNUSU9OX18pOwoKCXNlbGYgPSAoc3RydWN0IHRzYXBfY2IgKikgaW5zdGFuY2U7CgoJSVJEQV9BU1NFUlQoc2VsZiAhPSBOVUxMLCByZXR1cm47KTsKCUlSREFfQVNTRVJUKHNlbGYtPm1hZ2ljID09IFRUUF9UU0FQX01BR0lDLCByZXR1cm47KTsKCgkvKiBDaGVjayBpZiBjbGllbnQgaGFzIGFscmVhZHkgY2xvc2VkIHRoZSBUU0FQIGFuZCBnb25lIGF3YXkgKi8KCWlmIChzZWxmLT5jbG9zZV9wZW5kKQoJCXJldHVybjsKCgkvKgoJICogIEluZm9ybSBzZXJ2aWNlIHVzZXIgaWYgaGUgaGFzIHJlcXVlc3RlZCBpdAoJICovCglpZiAoc2VsZi0+bm90aWZ5LnN0YXR1c19pbmRpY2F0aW9uICE9IE5VTEwpCgkJc2VsZi0+bm90aWZ5LnN0YXR1c19pbmRpY2F0aW9uKHNlbGYtPm5vdGlmeS5pbnN0YW5jZSwKCQkJCQkgICAgICAgbGluaywgbG9jayk7CgllbHNlCgkJSVJEQV9ERUJVRygyLCAiJXMoKSwgbm8gaGFuZGxlclxuIiwgX19GVU5DVElPTl9fKTsKfQoKLyoKICogRnVuY3Rpb24gaXJ0dHBfZmxvd19pbmRpY2F0aW9uIChzZWxmLCByZWFzb24pCiAqCiAqICAgIEZsb3dfaW5kaWNhdGlvbiA6IElyTEFQIHRlbGxzIHVzIHRvIHNlbmQgbW9yZSBkYXRhLgogKgogKi8Kc3RhdGljIHZvaWQgaXJ0dHBfZmxvd19pbmRpY2F0aW9uKHZvaWQgKmluc3RhbmNlLCB2b2lkICpzYXAsIExPQ0FMX0ZMT1cgZmxvdykKewoJc3RydWN0IHRzYXBfY2IgKnNlbGY7CgoJc2VsZiA9IChzdHJ1Y3QgdHNhcF9jYiAqKSBpbnN0YW5jZTsKCglJUkRBX0FTU0VSVChzZWxmICE9IE5VTEwsIHJldHVybjspOwoJSVJEQV9BU1NFUlQoc2VsZi0+bWFnaWMgPT0gVFRQX1RTQVBfTUFHSUMsIHJldHVybjspOwoKCUlSREFfREVCVUcoNCwgIiVzKGluc3RhbmNlPSVwKVxuIiwgX19GVU5DVElPTl9fLCBzZWxmKTsKCgkvKiBXZSBhcmUgInBvbGxlZCIgZGlyZWN0bHkgZnJvbSBMQVAsIGFuZCB0aGUgTEFQIHdhbnQgdG8gZmlsbAoJICogaXRzIFR4IHdpbmRvdy4gV2Ugd2FudCB0byBkbyBvdXIgYmVzdCB0byBzZW5kIGl0IGRhdGEsIHNvIHRoYXQKCSAqIHdlIG1heGltaXNlIHRoZSB3aW5kb3cuIE9uIHRoZSBvdGhlciBoYW5kLCB3ZSB3YW50IHRvIGxpbWl0IHRoZQoJICogYW1vdW50IG9mIHdvcmsgaGVyZSBzbyB0aGF0IExBUCBkb2Vzbid0IGhhbmcgZm9yZXZlciB3YWl0aW5nCgkgKiBmb3IgcGFja2V0cy4gLSBKZWFuIElJICovCgoJLyogVHJ5IHRvIHNlbmQgc29tZSBwYWNrZXRzLiBDdXJyZW50bHksIExBUCBjYWxscyB1cyBldmVyeSB0aW1lCgkgKiB0aGVyZSBpcyBvbmUgZnJlZSBzbG90LCBzbyB3ZSB3aWxsIHNlbmQgb25seSBvbmUgcGFja2V0LgoJICogVGhpcyBhbGxvdyB0aGUgc2NoZWR1bGVyIHRvIGRvIGl0cyByb3VuZCByb2JpbiAtIEplYW4gSUkgKi8KCWlydHRwX3J1bl90eF9xdWV1ZShzZWxmKTsKCgkvKiBOb3RlIHJlZ2FyZGluZyB0aGUgaW50ZXJyYWN0aW9uIHdpdGggaGlnaGVyIGxheWVyLgoJICogaXJ0dHBfcnVuX3R4X3F1ZXVlKCkgbWF5IGNhbGwgdGhlIGNsaWVudCB3aGVuIGl0cyBxdWV1ZQoJICogc3RhcnQgdG8gZW1wdHksIHZpYSBub3RpZnkuZmxvd19pbmRpY2F0aW9uKCkuIEluaXRpYWxseS4KCSAqIEkgd2FudGVkIHRoaXMgdG8gaGFwcGVuIGluIGEgdGFza2xldCwgdG8gYXZvaWQgY2xpZW50CgkgKiBncmFiYmluZyB0aGUgQ1BVLCBidXQgd2UgY2FuJ3QgdXNlIHRhc2tsZXRzIHNhZmVseS4gQW5kIHRpbWVyCgkgKiBpcyBkZWZpbml0ZWx5IHRvbyBzbG93LgoJICogVGhpcyB3aWxsIGhhcHBlbiBvbmx5IG9uY2UgcGVyIExBUCB3aW5kb3csIGFuZCB1c3VhbGx5IGF0CgkgKiB0aGUgdGhpcmQgcGFja2V0ICh1bmxlc3Mgd2luZG93IGlzIHNtYWxsZXIpLiBMQVAgaXMgc3RpbGwKCSAqIGRvaW5nIG10dCBhbmQgc2VuZGluZyBmaXJzdCBwYWNrZXQgc28gaXQncyBzb3J0IG9mIE9LCgkgKiB0byBkbyB0aGF0LiBKZWFuIElJICovCgoJLyogSWYgd2UgbmVlZCB0byBzZW5kIGRpc2Nvbm5lY3QuIHRyeSB0byBkbyBpdCBub3cgKi8KCWlmKHNlbGYtPmRpc2Nvbm5lY3RfcGVuZCkKCQlpcnR0cF9zdGFydF90b2RvX3RpbWVyKHNlbGYsIDApOwp9CgovKgogKiBGdW5jdGlvbiBpcnR0cF9mbG93X3JlcXVlc3QgKHNlbGYsIGNvbW1hbmQpCiAqCiAqICAgIFRoaXMgZnVuY3Rpb24gY291bGQgYmUgdXNlZCBieSB0aGUgdXBwZXIgbGF5ZXJzIHRvIHRlbGwgSXJUVFAgdG8gc3RvcAogKiAgICBkZWxpdmVyaW5nIGZyYW1lcyBpZiB0aGUgcmVjZWl2ZSBxdWV1ZXMgYXJlIHN0YXJ0aW5nIHRvIGdldCBmdWxsLCBvcgogKiAgICB0byB0ZWxsIElyVFRQIHRvIHN0YXJ0IGRlbGl2ZXJpbmcgZnJhbWVzIGFnYWluLgogKi8Kdm9pZCBpcnR0cF9mbG93X3JlcXVlc3Qoc3RydWN0IHRzYXBfY2IgKnNlbGYsIExPQ0FMX0ZMT1cgZmxvdykKewoJSVJEQV9ERUJVRygxLCAiJXMoKVxuIiwgX19GVU5DVElPTl9fKTsKCglJUkRBX0FTU0VSVChzZWxmICE9IE5VTEwsIHJldHVybjspOwoJSVJEQV9BU1NFUlQoc2VsZi0+bWFnaWMgPT0gVFRQX1RTQVBfTUFHSUMsIHJldHVybjspOwoKCXN3aXRjaCAoZmxvdykgewoJY2FzZSBGTE9XX1NUT1A6CgkJSVJEQV9ERUJVRygxLCAiJXMoKSwgZmxvdyBzdG9wXG4iLCBfX0ZVTkNUSU9OX18pOwoJCXNlbGYtPnJ4X3NkdV9idXN5ID0gVFJVRTsKCQlicmVhazsKCWNhc2UgRkxPV19TVEFSVDoKCQlJUkRBX0RFQlVHKDEsICIlcygpLCBmbG93IHN0YXJ0XG4iLCBfX0ZVTkNUSU9OX18pOwoJCXNlbGYtPnJ4X3NkdV9idXN5ID0gRkFMU0U7CgoJCS8qIENsaWVudCBzYXkgaGUgY2FuIGFjY2VwdCBtb3JlIGRhdGEsIHRyeSB0byBmcmVlIG91cgoJCSAqIHF1ZXVlcyBBU0FQIC0gSmVhbiBJSSAqLwoJCWlydHRwX3J1bl9yeF9xdWV1ZShzZWxmKTsKCgkJYnJlYWs7CglkZWZhdWx0OgoJCUlSREFfREVCVUcoMSwgIiVzKCksIFVua25vd24gZmxvdyBjb21tYW5kIVxuIiwgX19GVU5DVElPTl9fKTsKCX0KfQpFWFBPUlRfU1lNQk9MKGlydHRwX2Zsb3dfcmVxdWVzdCk7CgovKgogKiBGdW5jdGlvbiBpcnR0cF9jb25uZWN0X3JlcXVlc3QgKHNlbGYsIGR0c2FwX3NlbCwgZGFkZHIsIHFvcykKICoKICogICAgVHJ5IHRvIGNvbm5lY3QgdG8gcmVtb3RlIGRlc3RpbmF0aW9uIFRTQVAgc2VsZWN0b3IKICoKICovCmludCBpcnR0cF9jb25uZWN0X3JlcXVlc3Qoc3RydWN0IHRzYXBfY2IgKnNlbGYsIF9fdTggZHRzYXBfc2VsLAoJCQkgIF9fdTMyIHNhZGRyLCBfX3UzMiBkYWRkciwKCQkJICBzdHJ1Y3QgcW9zX2luZm8gKnFvcywgX191MzIgbWF4X3NkdV9zaXplLAoJCQkgIHN0cnVjdCBza19idWZmICp1c2VyZGF0YSkKewoJc3RydWN0IHNrX2J1ZmYgKnR4X3NrYjsKCV9fdTggKmZyYW1lOwoJX191OCBuOwoKCUlSREFfREVCVUcoNCwgIiVzKCksIG1heF9zZHVfc2l6ZT0lZFxuIiwgX19GVU5DVElPTl9fLCBtYXhfc2R1X3NpemUpOwoKCUlSREFfQVNTRVJUKHNlbGYgIT0gTlVMTCwgcmV0dXJuIC1FQkFEUjspOwoJSVJEQV9BU1NFUlQoc2VsZi0+bWFnaWMgPT0gVFRQX1RTQVBfTUFHSUMsIHJldHVybiAtRUJBRFI7KTsKCglpZiAoc2VsZi0+Y29ubmVjdGVkKSB7CgkJaWYodXNlcmRhdGEpCgkJCWRldl9rZnJlZV9za2IodXNlcmRhdGEpOwoJCXJldHVybiAtRUlTQ09OTjsKCX0KCgkvKiBBbnkgdXNlcmRhdGEgc3VwcGxpZWQ/ICovCglpZiAodXNlcmRhdGEgPT0gTlVMTCkgewoJCXR4X3NrYiA9IGFsbG9jX3NrYihUVFBfTUFYX0hFQURFUiArIFRUUF9TQVJfSEVBREVSLAoJCQkJICAgR0ZQX0FUT01JQyk7CgkJaWYgKCF0eF9za2IpCgkJCXJldHVybiAtRU5PTUVNOwoKCQkvKiBSZXNlcnZlIHNwYWNlIGZvciBNVVhfQ09OVFJPTCBhbmQgTEFQIGhlYWRlciAqLwoJCXNrYl9yZXNlcnZlKHR4X3NrYiwgVFRQX01BWF9IRUFERVIgKyBUVFBfU0FSX0hFQURFUik7Cgl9IGVsc2UgewoJCXR4X3NrYiA9IHVzZXJkYXRhOwoJCS8qCgkJICogIENoZWNrIHRoYXQgdGhlIGNsaWVudCBoYXMgcmVzZXJ2ZWQgZW5vdWdoIHNwYWNlIGZvcgoJCSAqICBoZWFkZXJzCgkJICovCgkJSVJEQV9BU1NFUlQoc2tiX2hlYWRyb29tKHVzZXJkYXRhKSA+PSBUVFBfTUFYX0hFQURFUiwKCQkJeyBkZXZfa2ZyZWVfc2tiKHVzZXJkYXRhKTsgcmV0dXJuIC0xOyB9ICk7Cgl9CgoJLyogSW5pdGlhbGl6ZSBjb25uZWN0aW9uIHBhcmFtZXRlcnMgKi8KCXNlbGYtPmNvbm5lY3RlZCA9IEZBTFNFOwoJc2VsZi0+YXZhaWxfY3JlZGl0ID0gMDsKCXNlbGYtPnJ4X21heF9zZHVfc2l6ZSA9IG1heF9zZHVfc2l6ZTsKCXNlbGYtPnJ4X3NkdV9zaXplID0gMDsKCXNlbGYtPnJ4X3NkdV9idXN5ID0gRkFMU0U7CglzZWxmLT5kdHNhcF9zZWwgPSBkdHNhcF9zZWw7CgoJbiA9IHNlbGYtPmluaXRpYWxfY3JlZGl0OwoKCXNlbGYtPnJlbW90ZV9jcmVkaXQgPSAwOwoJc2VsZi0+c2VuZF9jcmVkaXQgPSAwOwoKCS8qCgkgKiAgR2l2ZSBhd2F5IG1heCAxMjcgY3JlZGl0cyBmb3Igbm93CgkgKi8KCWlmIChuID4gMTI3KSB7CgkJc2VsZi0+YXZhaWxfY3JlZGl0PW4tMTI3OwoJCW4gPSAxMjc7Cgl9CgoJc2VsZi0+cmVtb3RlX2NyZWRpdCA9IG47CgoJLyogU0FSIGVuYWJsZWQ/ICovCglpZiAobWF4X3NkdV9zaXplID4gMCkgewoJCUlSREFfQVNTRVJUKHNrYl9oZWFkcm9vbSh0eF9za2IpID49IChUVFBfTUFYX0hFQURFUiArIFRUUF9TQVJfSEVBREVSKSwKCQkJeyBkZXZfa2ZyZWVfc2tiKHR4X3NrYik7IHJldHVybiAtMTsgfSApOwoKCQkvKiBJbnNlcnQgU0FSIHBhcmFtZXRlcnMgKi8KCQlmcmFtZSA9IHNrYl9wdXNoKHR4X3NrYiwgVFRQX0hFQURFUitUVFBfU0FSX0hFQURFUik7CgoJCWZyYW1lWzBdID0gVFRQX1BBUkFNRVRFUlMgfCBuOwoJCWZyYW1lWzFdID0gMHgwNDsgLyogTGVuZ3RoICovCgkJZnJhbWVbMl0gPSAweDAxOyAvKiBNYXhTZHVTaXplICovCgkJZnJhbWVbM10gPSAweDAyOyAvKiBWYWx1ZSBsZW5ndGggKi8KCgkJcHV0X3VuYWxpZ25lZChjcHVfdG9fYmUxNigoX191MTYpIG1heF9zZHVfc2l6ZSksCgkJCSAgICAgIChfX2JlMTYgKikoZnJhbWUrNCkpOwoJfSBlbHNlIHsKCQkvKiBJbnNlcnQgcGxhaW4gVFRQIGhlYWRlciAqLwoJCWZyYW1lID0gc2tiX3B1c2godHhfc2tiLCBUVFBfSEVBREVSKTsKCgkJLyogSW5zZXJ0IGluaXRpYWwgY3JlZGl0IGluIGZyYW1lICovCgkJZnJhbWVbMF0gPSBuICYgMHg3ZjsKCX0KCgkvKiBDb25uZWN0IHdpdGggSXJMTVAuIE5vIFFvUyBwYXJhbWV0ZXJzIGZvciBub3cgKi8KCXJldHVybiBpcmxtcF9jb25uZWN0X3JlcXVlc3Qoc2VsZi0+bHNhcCwgZHRzYXBfc2VsLCBzYWRkciwgZGFkZHIsIHFvcywKCQkJCSAgICAgdHhfc2tiKTsKfQpFWFBPUlRfU1lNQk9MKGlydHRwX2Nvbm5lY3RfcmVxdWVzdCk7CgovKgogKiBGdW5jdGlvbiBpcnR0cF9jb25uZWN0X2NvbmZpcm0gKGhhbmRsZSwgcW9zLCBza2IpCiAqCiAqICAgIFNldmljZSB1c2VyIGNvbmZpcm1zIFRTQVAgY29ubmVjdGlvbiB3aXRoIHBlZXIuCiAqCiAqLwpzdGF0aWMgdm9pZCBpcnR0cF9jb25uZWN0X2NvbmZpcm0odm9pZCAqaW5zdGFuY2UsIHZvaWQgKnNhcCwKCQkJCSAgc3RydWN0IHFvc19pbmZvICpxb3MsIF9fdTMyIG1heF9zZWdfc2l6ZSwKCQkJCSAgX191OCBtYXhfaGVhZGVyX3NpemUsIHN0cnVjdCBza19idWZmICpza2IpCnsKCXN0cnVjdCB0c2FwX2NiICpzZWxmOwoJaW50IHBhcmFtZXRlcnM7CglpbnQgcmV0OwoJX191OCBwbGVuOwoJX191OCBuOwoKCUlSREFfREVCVUcoNCwgIiVzKClcbiIsIF9fRlVOQ1RJT05fXyk7CgoJc2VsZiA9IChzdHJ1Y3QgdHNhcF9jYiAqKSBpbnN0YW5jZTsKCglJUkRBX0FTU0VSVChzZWxmICE9IE5VTEwsIHJldHVybjspOwoJSVJEQV9BU1NFUlQoc2VsZi0+bWFnaWMgPT0gVFRQX1RTQVBfTUFHSUMsIHJldHVybjspOwoJSVJEQV9BU1NFUlQoc2tiICE9IE5VTEwsIHJldHVybjspOwoKCXNlbGYtPm1heF9zZWdfc2l6ZSA9IG1heF9zZWdfc2l6ZSAtIFRUUF9IRUFERVI7CglzZWxmLT5tYXhfaGVhZGVyX3NpemUgPSBtYXhfaGVhZGVyX3NpemUgKyBUVFBfSEVBREVSOwoKCS8qCgkgKiAgQ2hlY2sgaWYgd2UgaGF2ZSBnb3Qgc29tZSBRb1MgcGFyYW1ldGVycyBiYWNrISBUaGlzIHNob3VsZCBiZSB0aGUKCSAqICBuZWdvdGlhdGVkIFFvUyBmb3IgdGhlIGxpbmsuCgkgKi8KCWlmIChxb3MpIHsKCQlJUkRBX0RFQlVHKDQsICJJclRUUCwgTmVnb3RpYXRlZCBCQVVEX1JBVEU6ICUwMnhcbiIsCgkJICAgICAgIHFvcy0+YmF1ZF9yYXRlLmJpdHMpOwoJCUlSREFfREVCVUcoNCwgIklyVFRQLCBOZWdvdGlhdGVkIEJBVURfUkFURTogJWQgYnBzLlxuIiwKCQkgICAgICAgcW9zLT5iYXVkX3JhdGUudmFsdWUpOwoJfQoKCW4gPSBza2ItPmRhdGFbMF0gJiAweDdmOwoKCUlSREFfREVCVUcoNCwgIiVzKCksIEluaXRpYWwgc2VuZF9jcmVkaXQ9JWRcbiIsIF9fRlVOQ1RJT05fXywgbik7CgoJc2VsZi0+c2VuZF9jcmVkaXQgPSBuOwoJc2VsZi0+dHhfbWF4X3NkdV9zaXplID0gMDsKCXNlbGYtPmNvbm5lY3RlZCA9IFRSVUU7CgoJcGFyYW1ldGVycyA9IHNrYi0+ZGF0YVswXSAmIDB4ODA7CgoJSVJEQV9BU1NFUlQoc2tiLT5sZW4gPj0gVFRQX0hFQURFUiwgcmV0dXJuOyk7Cglza2JfcHVsbChza2IsIFRUUF9IRUFERVIpOwoKCWlmIChwYXJhbWV0ZXJzKSB7CgkJcGxlbiA9IHNrYi0+ZGF0YVswXTsKCgkJcmV0ID0gaXJkYV9wYXJhbV9leHRyYWN0X2FsbChzZWxmLCBza2ItPmRhdGErMSwKCQkJCQkgICAgIElSREFfTUlOKHNrYi0+bGVuLTEsIHBsZW4pLAoJCQkJCSAgICAgJnBhcmFtX2luZm8pOwoKCQkvKiBBbnkgZXJyb3JzIGluIHRoZSBwYXJhbWV0ZXIgbGlzdD8gKi8KCQlpZiAocmV0IDwgMCkgewoJCQlJUkRBX1dBUk5JTkcoIiVzOiBlcnJvciBleHRyYWN0aW5nIHBhcmFtZXRlcnNcbiIsCgkJCQkgICAgIF9fRlVOQ1RJT05fXyk7CgkJCWRldl9rZnJlZV9za2Ioc2tiKTsKCgkJCS8qIERvIG5vdCBhY2NlcHQgdGhpcyBjb25uZWN0aW9uIGF0dGVtcHQgKi8KCQkJcmV0dXJuOwoJCX0KCQkvKiBSZW1vdmUgcGFyYW1ldGVycyAqLwoJCXNrYl9wdWxsKHNrYiwgSVJEQV9NSU4oc2tiLT5sZW4sIHBsZW4rMSkpOwoJfQoKCUlSREFfREVCVUcoNCwgIiVzKCkgc2VuZD0lZCxhdmFpbD0lZCxyZW1vdGU9JWRcbiIsIF9fRlVOQ1RJT05fXywKCSAgICAgIHNlbGYtPnNlbmRfY3JlZGl0LCBzZWxmLT5hdmFpbF9jcmVkaXQsIHNlbGYtPnJlbW90ZV9jcmVkaXQpOwoKCUlSREFfREVCVUcoMiwgIiVzKCksIE1heFNkdVNpemU9JWRcbiIsIF9fRlVOQ1RJT05fXywKCQkgICBzZWxmLT50eF9tYXhfc2R1X3NpemUpOwoKCWlmIChzZWxmLT5ub3RpZnkuY29ubmVjdF9jb25maXJtKSB7CgkJc2VsZi0+bm90aWZ5LmNvbm5lY3RfY29uZmlybShzZWxmLT5ub3RpZnkuaW5zdGFuY2UsIHNlbGYsIHFvcywKCQkJCQkgICAgIHNlbGYtPnR4X21heF9zZHVfc2l6ZSwKCQkJCQkgICAgIHNlbGYtPm1heF9oZWFkZXJfc2l6ZSwgc2tiKTsKCX0gZWxzZQoJCWRldl9rZnJlZV9za2Ioc2tiKTsKfQoKLyoKICogRnVuY3Rpb24gaXJ0dHBfY29ubmVjdF9pbmRpY2F0aW9uIChoYW5kbGUsIHNrYikKICoKICogICAgU29tZSBvdGhlciBkZXZpY2UgaXMgY29ubmVjdGluZyB0byB0aGlzIFRTQVAKICoKICovCnZvaWQgaXJ0dHBfY29ubmVjdF9pbmRpY2F0aW9uKHZvaWQgKmluc3RhbmNlLCB2b2lkICpzYXAsIHN0cnVjdCBxb3NfaW5mbyAqcW9zLAoJCQkgICAgICBfX3UzMiBtYXhfc2VnX3NpemUsIF9fdTggbWF4X2hlYWRlcl9zaXplLAoJCQkgICAgICBzdHJ1Y3Qgc2tfYnVmZiAqc2tiKQp7CglzdHJ1Y3QgdHNhcF9jYiAqc2VsZjsKCXN0cnVjdCBsc2FwX2NiICpsc2FwOwoJaW50IHBhcmFtZXRlcnM7CglpbnQgcmV0OwoJX191OCBwbGVuOwoJX191OCBuOwoKCXNlbGYgPSAoc3RydWN0IHRzYXBfY2IgKikgaW5zdGFuY2U7CgoJSVJEQV9BU1NFUlQoc2VsZiAhPSBOVUxMLCByZXR1cm47KTsKCUlSREFfQVNTRVJUKHNlbGYtPm1hZ2ljID09IFRUUF9UU0FQX01BR0lDLCByZXR1cm47KTsKCUlSREFfQVNTRVJUKHNrYiAhPSBOVUxMLCByZXR1cm47KTsKCglsc2FwID0gKHN0cnVjdCBsc2FwX2NiICopIHNhcDsKCglzZWxmLT5tYXhfc2VnX3NpemUgPSBtYXhfc2VnX3NpemUgLSBUVFBfSEVBREVSOwoJc2VsZi0+bWF4X2hlYWRlcl9zaXplID0gbWF4X2hlYWRlcl9zaXplK1RUUF9IRUFERVI7CgoJSVJEQV9ERUJVRyg0LCAiJXMoKSwgVFNBUCBzZWw9JTAyeFxuIiwgX19GVU5DVElPTl9fLCBzZWxmLT5zdHNhcF9zZWwpOwoKCS8qIE5lZWQgdG8gdXBkYXRlIGR0c2FwX3NlbCBpZiBpdHMgZXF1YWwgdG8gTFNBUF9BTlkgKi8KCXNlbGYtPmR0c2FwX3NlbCA9IGxzYXAtPmRsc2FwX3NlbDsKCgluID0gc2tiLT5kYXRhWzBdICYgMHg3ZjsKCglzZWxmLT5zZW5kX2NyZWRpdCA9IG47CglzZWxmLT50eF9tYXhfc2R1X3NpemUgPSAwOwoKCXBhcmFtZXRlcnMgPSBza2ItPmRhdGFbMF0gJiAweDgwOwoKCUlSREFfQVNTRVJUKHNrYi0+bGVuID49IFRUUF9IRUFERVIsIHJldHVybjspOwoJc2tiX3B1bGwoc2tiLCBUVFBfSEVBREVSKTsKCglpZiAocGFyYW1ldGVycykgewoJCXBsZW4gPSBza2ItPmRhdGFbMF07CgoJCXJldCA9IGlyZGFfcGFyYW1fZXh0cmFjdF9hbGwoc2VsZiwgc2tiLT5kYXRhKzEsCgkJCQkJICAgICBJUkRBX01JTihza2ItPmxlbi0xLCBwbGVuKSwKCQkJCQkgICAgICZwYXJhbV9pbmZvKTsKCgkJLyogQW55IGVycm9ycyBpbiB0aGUgcGFyYW1ldGVyIGxpc3Q/ICovCgkJaWYgKHJldCA8IDApIHsKCQkJSVJEQV9XQVJOSU5HKCIlczogZXJyb3IgZXh0cmFjdGluZyBwYXJhbWV0ZXJzXG4iLAoJCQkJICAgICBfX0ZVTkNUSU9OX18pOwoJCQlkZXZfa2ZyZWVfc2tiKHNrYik7CgoJCQkvKiBEbyBub3QgYWNjZXB0IHRoaXMgY29ubmVjdGlvbiBhdHRlbXB0ICovCgkJCXJldHVybjsKCQl9CgoJCS8qIFJlbW92ZSBwYXJhbWV0ZXJzICovCgkJc2tiX3B1bGwoc2tiLCBJUkRBX01JTihza2ItPmxlbiwgcGxlbisxKSk7Cgl9CgoJaWYgKHNlbGYtPm5vdGlmeS5jb25uZWN0X2luZGljYXRpb24pIHsKCQlzZWxmLT5ub3RpZnkuY29ubmVjdF9pbmRpY2F0aW9uKHNlbGYtPm5vdGlmeS5pbnN0YW5jZSwgc2VsZiwKCQkJCQkJcW9zLCBzZWxmLT50eF9tYXhfc2R1X3NpemUsCgkJCQkJCXNlbGYtPm1heF9oZWFkZXJfc2l6ZSwgc2tiKTsKCX0gZWxzZQoJCWRldl9rZnJlZV9za2Ioc2tiKTsKfQoKLyoKICogRnVuY3Rpb24gaXJ0dHBfY29ubmVjdF9yZXNwb25zZSAoaGFuZGxlLCB1c2VyZGF0YSkKICoKICogICAgU2VydmljZSB1c2VyIGlzIGFjY2VwdGluZyB0aGUgY29ubmVjdGlvbiwganVzdCBwYXNzIGl0IGRvd24gdG8KICogICAgSXJMTVAhCiAqCiAqLwppbnQgaXJ0dHBfY29ubmVjdF9yZXNwb25zZShzdHJ1Y3QgdHNhcF9jYiAqc2VsZiwgX191MzIgbWF4X3NkdV9zaXplLAoJCQkgICBzdHJ1Y3Qgc2tfYnVmZiAqdXNlcmRhdGEpCnsKCXN0cnVjdCBza19idWZmICp0eF9za2I7CglfX3U4ICpmcmFtZTsKCWludCByZXQ7CglfX3U4IG47CgoJSVJEQV9BU1NFUlQoc2VsZiAhPSBOVUxMLCByZXR1cm4gLTE7KTsKCUlSREFfQVNTRVJUKHNlbGYtPm1hZ2ljID09IFRUUF9UU0FQX01BR0lDLCByZXR1cm4gLTE7KTsKCglJUkRBX0RFQlVHKDQsICIlcygpLCBTb3VyY2UgVFNBUCBzZWxlY3Rvcj0lMDJ4XG4iLCBfX0ZVTkNUSU9OX18sCgkJICAgc2VsZi0+c3RzYXBfc2VsKTsKCgkvKiBBbnkgdXNlcmRhdGEgc3VwcGxpZWQ/ICovCglpZiAodXNlcmRhdGEgPT0gTlVMTCkgewoJCXR4X3NrYiA9IGFsbG9jX3NrYihUVFBfTUFYX0hFQURFUiArIFRUUF9TQVJfSEVBREVSLAoJCQkJICAgR0ZQX0FUT01JQyk7CgkJaWYgKCF0eF9za2IpCgkJCXJldHVybiAtRU5PTUVNOwoKCQkvKiBSZXNlcnZlIHNwYWNlIGZvciBNVVhfQ09OVFJPTCBhbmQgTEFQIGhlYWRlciAqLwoJCXNrYl9yZXNlcnZlKHR4X3NrYiwgVFRQX01BWF9IRUFERVIgKyBUVFBfU0FSX0hFQURFUik7Cgl9IGVsc2UgewoJCXR4X3NrYiA9IHVzZXJkYXRhOwoJCS8qCgkJICogIENoZWNrIHRoYXQgdGhlIGNsaWVudCBoYXMgcmVzZXJ2ZWQgZW5vdWdoIHNwYWNlIGZvcgoJCSAqICBoZWFkZXJzCgkJICovCgkJSVJEQV9BU1NFUlQoc2tiX2hlYWRyb29tKHVzZXJkYXRhKSA+PSBUVFBfTUFYX0hFQURFUiwKCQkJeyBkZXZfa2ZyZWVfc2tiKHVzZXJkYXRhKTsgcmV0dXJuIC0xOyB9ICk7Cgl9CgoJc2VsZi0+YXZhaWxfY3JlZGl0ID0gMDsKCXNlbGYtPnJlbW90ZV9jcmVkaXQgPSAwOwoJc2VsZi0+cnhfbWF4X3NkdV9zaXplID0gbWF4X3NkdV9zaXplOwoJc2VsZi0+cnhfc2R1X3NpemUgPSAwOwoJc2VsZi0+cnhfc2R1X2J1c3kgPSBGQUxTRTsKCgluID0gc2VsZi0+aW5pdGlhbF9jcmVkaXQ7CgoJLyogRnJhbWUgaGFzIG9ubHkgc3BhY2UgZm9yIG1heCAxMjcgY3JlZGl0cyAoNyBiaXRzKSAqLwoJaWYgKG4gPiAxMjcpIHsKCQlzZWxmLT5hdmFpbF9jcmVkaXQgPSBuIC0gMTI3OwoJCW4gPSAxMjc7Cgl9CgoJc2VsZi0+cmVtb3RlX2NyZWRpdCA9IG47CglzZWxmLT5jb25uZWN0ZWQgPSBUUlVFOwoKCS8qIFNBUiBlbmFibGVkPyAqLwoJaWYgKG1heF9zZHVfc2l6ZSA+IDApIHsKCQlJUkRBX0FTU0VSVChza2JfaGVhZHJvb20odHhfc2tiKSA+PSAoVFRQX01BWF9IRUFERVIgKyBUVFBfU0FSX0hFQURFUiksCgkJCXsgZGV2X2tmcmVlX3NrYih0eF9za2IpOyByZXR1cm4gLTE7IH0gKTsKCgkJLyogSW5zZXJ0IFRUUCBoZWFkZXIgd2l0aCBTQVIgcGFyYW1ldGVycyAqLwoJCWZyYW1lID0gc2tiX3B1c2godHhfc2tiLCBUVFBfSEVBREVSK1RUUF9TQVJfSEVBREVSKTsKCgkJZnJhbWVbMF0gPSBUVFBfUEFSQU1FVEVSUyB8IG47CgkJZnJhbWVbMV0gPSAweDA0OyAvKiBMZW5ndGggKi8KCgkJLyogaXJkYV9wYXJhbV9pbnNlcnQoc2VsZiwgSVJUVFBfTUFYX1NEVV9TSVpFLCBmcmFtZSsxLCAgKi8KLyoJCQkJICBUVFBfU0FSX0hFQURFUiwgJnBhcmFtX2luZm8pICovCgoJCWZyYW1lWzJdID0gMHgwMTsgLyogTWF4U2R1U2l6ZSAqLwoJCWZyYW1lWzNdID0gMHgwMjsgLyogVmFsdWUgbGVuZ3RoICovCgoJCXB1dF91bmFsaWduZWQoY3B1X3RvX2JlMTYoKF9fdTE2KSBtYXhfc2R1X3NpemUpLAoJCQkgICAgICAoX19iZTE2ICopKGZyYW1lKzQpKTsKCX0gZWxzZSB7CgkJLyogSW5zZXJ0IFRUUCBoZWFkZXIgKi8KCQlmcmFtZSA9IHNrYl9wdXNoKHR4X3NrYiwgVFRQX0hFQURFUik7CgoJCWZyYW1lWzBdID0gbiAmIDB4N2Y7Cgl9CgoJcmV0ID0gaXJsbXBfY29ubmVjdF9yZXNwb25zZShzZWxmLT5sc2FwLCB0eF9za2IpOwoKCXJldHVybiByZXQ7Cn0KRVhQT1JUX1NZTUJPTChpcnR0cF9jb25uZWN0X3Jlc3BvbnNlKTsKCi8qCiAqIEZ1bmN0aW9uIGlydHRwX2R1cCAoc2VsZiwgaW5zdGFuY2UpCiAqCiAqICAgIER1cGxpY2F0ZSBUU0FQLCBjYW4gYmUgdXNlZCBieSBzZXJ2ZXJzIHRvIGNvbmZpcm0gYSBjb25uZWN0aW9uIG9uIGEKICogICAgbmV3IFRTQVAgc28gaXQgY2FuIGtlZXAgbGlzdGVuaW5nIG9uIHRoZSBvbGQgb25lLgogKi8Kc3RydWN0IHRzYXBfY2IgKmlydHRwX2R1cChzdHJ1Y3QgdHNhcF9jYiAqb3JpZywgdm9pZCAqaW5zdGFuY2UpCnsKCXN0cnVjdCB0c2FwX2NiICpuZXc7Cgl1bnNpZ25lZCBsb25nIGZsYWdzOwoKCUlSREFfREVCVUcoMSwgIiVzKClcbiIsIF9fRlVOQ1RJT05fXyk7CgoJLyogUHJvdGVjdCBvdXIgYWNjZXNzIHRvIHRoZSBvbGQgdHNhcCBpbnN0YW5jZSAqLwoJc3Bpbl9sb2NrX2lycXNhdmUoJmlydHRwLT50c2Fwcy0+aGJfc3BpbmxvY2ssIGZsYWdzKTsKCgkvKiBGaW5kIHRoZSBvbGQgaW5zdGFuY2UgKi8KCWlmICghaGFzaGJpbl9maW5kKGlydHRwLT50c2FwcywgKGxvbmcpIG9yaWcsIE5VTEwpKSB7CgkJSVJEQV9ERUJVRygwLCAiJXMoKSwgdW5hYmxlIHRvIGZpbmQgVFNBUFxuIiwgX19GVU5DVElPTl9fKTsKCQlzcGluX3VubG9ja19pcnFyZXN0b3JlKCZpcnR0cC0+dHNhcHMtPmhiX3NwaW5sb2NrLCBmbGFncyk7CgkJcmV0dXJuIE5VTEw7Cgl9CgoJLyogQWxsb2NhdGUgYSBuZXcgaW5zdGFuY2UgKi8KCW5ldyA9IGttYWxsb2Moc2l6ZW9mKHN0cnVjdCB0c2FwX2NiKSwgR0ZQX0FUT01JQyk7CglpZiAoIW5ldykgewoJCUlSREFfREVCVUcoMCwgIiVzKCksIHVuYWJsZSB0byBrbWFsbG9jXG4iLCBfX0ZVTkNUSU9OX18pOwoJCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJmlydHRwLT50c2Fwcy0+aGJfc3BpbmxvY2ssIGZsYWdzKTsKCQlyZXR1cm4gTlVMTDsKCX0KCS8qIER1cCAqLwoJbWVtY3B5KG5ldywgb3JpZywgc2l6ZW9mKHN0cnVjdCB0c2FwX2NiKSk7CgoJLyogV2UgZG9uJ3QgbmVlZCB0aGUgb2xkIGluc3RhbmNlIGFueSBtb3JlICovCglzcGluX3VubG9ja19pcnFyZXN0b3JlKCZpcnR0cC0+dHNhcHMtPmhiX3NwaW5sb2NrLCBmbGFncyk7CgoJLyogVHJ5IHRvIGR1cCB0aGUgTFNBUCAobWF5IGZhaWwgaWYgd2Ugd2VyZSB0b28gc2xvdykgKi8KCW5ldy0+bHNhcCA9IGlybG1wX2R1cChvcmlnLT5sc2FwLCBuZXcpOwoJaWYgKCFuZXctPmxzYXApIHsKCQlJUkRBX0RFQlVHKDAsICIlcygpLCBkdXAgZmFpbGVkIVxuIiwgX19GVU5DVElPTl9fKTsKCQlrZnJlZShuZXcpOwoJCXJldHVybiBOVUxMOwoJfQoKCS8qIE5vdCBldmVyeXRoaW5nIHNob3VsZCBiZSBjb3BpZWQgKi8KCW5ldy0+bm90aWZ5Lmluc3RhbmNlID0gaW5zdGFuY2U7Cglpbml0X3RpbWVyKCZuZXctPnRvZG9fdGltZXIpOwoKCXNrYl9xdWV1ZV9oZWFkX2luaXQoJm5ldy0+cnhfcXVldWUpOwoJc2tiX3F1ZXVlX2hlYWRfaW5pdCgmbmV3LT50eF9xdWV1ZSk7Cglza2JfcXVldWVfaGVhZF9pbml0KCZuZXctPnJ4X2ZyYWdtZW50cyk7CgoJLyogVGhpcyBpcyBsb2NrZWQgKi8KCWhhc2hiaW5faW5zZXJ0KGlydHRwLT50c2FwcywgKGlyZGFfcXVldWVfdCAqKSBuZXcsIChsb25nKSBuZXcsIE5VTEwpOwoKCXJldHVybiBuZXc7Cn0KRVhQT1JUX1NZTUJPTChpcnR0cF9kdXApOwoKLyoKICogRnVuY3Rpb24gaXJ0dHBfZGlzY29ubmVjdF9yZXF1ZXN0IChzZWxmKQogKgogKiAgICBDbG9zZSB0aGlzIGNvbm5lY3Rpb24gcGxlYXNlISBJZiBwcmlvcml0eSBpcyBoaWdoLCB0aGUgcXVldWVkIGRhdGEKICogICAgc2VnbWVudHMsIGlmIGFueSwgd2lsbCBiZSBkZWFsbG9jYXRlZCBmaXJzdAogKgogKi8KaW50IGlydHRwX2Rpc2Nvbm5lY3RfcmVxdWVzdChzdHJ1Y3QgdHNhcF9jYiAqc2VsZiwgc3RydWN0IHNrX2J1ZmYgKnVzZXJkYXRhLAoJCQkgICAgIGludCBwcmlvcml0eSkKewoJaW50IHJldDsKCglJUkRBX0FTU0VSVChzZWxmICE9IE5VTEwsIHJldHVybiAtMTspOwoJSVJEQV9BU1NFUlQoc2VsZi0+bWFnaWMgPT0gVFRQX1RTQVBfTUFHSUMsIHJldHVybiAtMTspOwoKCS8qIEFscmVhZHkgZGlzY29ubmVjdGVkPyAqLwoJaWYgKCFzZWxmLT5jb25uZWN0ZWQpIHsKCQlJUkRBX0RFQlVHKDQsICIlcygpLCBhbHJlYWR5IGRpc2Nvbm5lY3RlZCFcbiIsIF9fRlVOQ1RJT05fXyk7CgkJaWYgKHVzZXJkYXRhKQoJCQlkZXZfa2ZyZWVfc2tiKHVzZXJkYXRhKTsKCQlyZXR1cm4gLTE7Cgl9CgoJLyogRGlzY29ubmVjdCBhbHJlYWR5IHBlbmRpbmcgPwoJICogV2UgbmVlZCB0byB1c2UgYW4gYXRvbWljIG9wZXJhdGlvbiB0byBwcmV2ZW50IHJlZW50cnkuIFRoaXMKCSAqIGZ1bmN0aW9uIG1heSBiZSBjYWxsZWQgZnJvbSB2YXJpb3VzIGNvbnRleHQsIGxpa2UgdXNlciwgdGltZXIKCSAqIGZvciBmb2xsb3dpbmcgYSBkaXNjb25uZWN0X2luZGljYXRpb24oKSAoaS5lLiBuZXRfYmgpLgoJICogSmVhbiBJSSAqLwoJaWYodGVzdF9hbmRfc2V0X2JpdCgwLCAmc2VsZi0+ZGlzY29ubmVjdF9wZW5kKSkgewoJCUlSREFfREVCVUcoMCwgIiVzKCksIGRpc2Nvbm5lY3QgYWxyZWFkeSBwZW5kaW5nXG4iLAoJCQkgICBfX0ZVTkNUSU9OX18pOwoJCWlmICh1c2VyZGF0YSkKCQkJZGV2X2tmcmVlX3NrYih1c2VyZGF0YSk7CgoJCS8qIFRyeSB0byBtYWtlIHNvbWUgcHJvZ3Jlc3MgKi8KCQlpcnR0cF9ydW5fdHhfcXVldWUoc2VsZik7CgkJcmV0dXJuIC0xOwoJfQoKCS8qCgkgKiAgQ2hlY2sgaWYgdGhlcmUgaXMgc3RpbGwgZGF0YSBzZWdtZW50cyBpbiB0aGUgdHJhbnNtaXQgcXVldWUKCSAqLwoJaWYgKCFza2JfcXVldWVfZW1wdHkoJnNlbGYtPnR4X3F1ZXVlKSkgewoJCWlmIChwcmlvcml0eSA9PSBQX0hJR0gpIHsKCQkJLyoKCQkJICogIE5vIG5lZWQgdG8gc2VuZCB0aGUgcXVldWVkIGRhdGEsIGlmIHdlIGFyZQoJCQkgKiAgZGlzY29ubmVjdGluZyByaWdodCBub3cgc2luY2UgdGhlIGRhdGEgd2lsbAoJCQkgKiAgbm90IGhhdmUgYW55IHVzYWJsZSBjb25uZWN0aW9uIHRvIGJlIHNlbnQgb24KCQkJICovCgkJCUlSREFfREVCVUcoMSwgIiVzKCk6IEhpZ2ggcHJpb3JpdHkhISgpXG4iLCBfX0ZVTkNUSU9OX18pOwoJCQlpcnR0cF9mbHVzaF9xdWV1ZXMoc2VsZik7CgkJfSBlbHNlIGlmIChwcmlvcml0eSA9PSBQX05PUk1BTCkgewoJCQkvKgoJCQkgKiAgTXVzdCBkZWxheSBkaXNjb25uZWN0IHVudGlsIGFmdGVyIGFsbCBkYXRhIHNlZ21lbnRzCgkJCSAqICBoYXZlIGJlZW4gc2VudCBhbmQgdGhlIHR4X3F1ZXVlIGlzIGVtcHR5CgkJCSAqLwoJCQkvKiBXZSdsbCByZXVzZSB0aGlzIG9uZSBsYXRlciBmb3IgdGhlIGRpc2Nvbm5lY3QgKi8KCQkJc2VsZi0+ZGlzY29ubmVjdF9za2IgPSB1c2VyZGF0YTsgIC8qIE1heSBiZSBOVUxMICovCgoJCQlpcnR0cF9ydW5fdHhfcXVldWUoc2VsZik7CgoJCQlpcnR0cF9zdGFydF90b2RvX3RpbWVyKHNlbGYsIEhaLzEwKTsKCQkJcmV0dXJuIC0xOwoJCX0KCX0KCS8qIE5vdGUgOiB3ZSBkb24ndCBuZWVkIHRvIGNoZWNrIGlmIHNlbGYtPnJ4X3F1ZXVlIGlzIGZ1bGwgYW5kIHRoZQoJICogc3RhdGUgb2Ygc2VsZi0+cnhfc2R1X2J1c3kgYmVjYXVzZSB0aGUgZGlzY29ubmVjdCByZXNwb25zZSB3aWxsCgkgKiBiZSBzZW50IGF0IHRoZSBMTVAgbGV2ZWwgKHNvIGV2ZW4gaWYgdGhlIHBlZXIgaGFzIGl0cyBUeCBxdWV1ZQoJICogZnVsbCBvZiBkYXRhKS4gLSBKZWFuIElJICovCgoJSVJEQV9ERUJVRygxLCAiJXMoKSwgRGlzY29ubmVjdGluZyAuLi5cbiIsIF9fRlVOQ1RJT05fXyk7CglzZWxmLT5jb25uZWN0ZWQgPSBGQUxTRTsKCglpZiAoIXVzZXJkYXRhKSB7CgkJc3RydWN0IHNrX2J1ZmYgKnR4X3NrYjsKCQl0eF9za2IgPSBhbGxvY19za2IoTE1QX01BWF9IRUFERVIsIEdGUF9BVE9NSUMpOwoJCWlmICghdHhfc2tiKQoJCQlyZXR1cm4gLUVOT01FTTsKCgkJLyoKCQkgKiAgUmVzZXJ2ZSBzcGFjZSBmb3IgTVVYIGFuZCBMQVAgaGVhZGVyCgkJICovCgkJc2tiX3Jlc2VydmUodHhfc2tiLCBMTVBfTUFYX0hFQURFUik7CgoJCXVzZXJkYXRhID0gdHhfc2tiOwoJfQoJcmV0ID0gaXJsbXBfZGlzY29ubmVjdF9yZXF1ZXN0KHNlbGYtPmxzYXAsIHVzZXJkYXRhKTsKCgkvKiBUaGUgZGlzY29ubmVjdCBpcyBubyBsb25nZXIgcGVuZGluZyAqLwoJY2xlYXJfYml0KDAsICZzZWxmLT5kaXNjb25uZWN0X3BlbmQpOwkvKiBGQUxTRSAqLwoKCXJldHVybiByZXQ7Cn0KRVhQT1JUX1NZTUJPTChpcnR0cF9kaXNjb25uZWN0X3JlcXVlc3QpOwoKLyoKICogRnVuY3Rpb24gaXJ0dHBfZGlzY29ubmVjdF9pbmRpY2F0aW9uIChzZWxmLCByZWFzb24pCiAqCiAqICAgIERpc2Nvbm5lY3QgaW5kaWNhdGlvbiwgVFNBUCBkaXNjb25uZWN0ZWQgYnkgcGVlcj8KICoKICovCnZvaWQgaXJ0dHBfZGlzY29ubmVjdF9pbmRpY2F0aW9uKHZvaWQgKmluc3RhbmNlLCB2b2lkICpzYXAsIExNX1JFQVNPTiByZWFzb24sCgkJCQkgc3RydWN0IHNrX2J1ZmYgKnNrYikKewoJc3RydWN0IHRzYXBfY2IgKnNlbGY7CgoJSVJEQV9ERUJVRyg0LCAiJXMoKVxuIiwgX19GVU5DVElPTl9fKTsKCglzZWxmID0gKHN0cnVjdCB0c2FwX2NiICopIGluc3RhbmNlOwoKCUlSREFfQVNTRVJUKHNlbGYgIT0gTlVMTCwgcmV0dXJuOyk7CglJUkRBX0FTU0VSVChzZWxmLT5tYWdpYyA9PSBUVFBfVFNBUF9NQUdJQywgcmV0dXJuOyk7CgoJLyogUHJldmVudCBoaWdoZXIgbGF5ZXIgdG8gc2VuZCBtb3JlIGRhdGEgKi8KCXNlbGYtPmNvbm5lY3RlZCA9IEZBTFNFOwoKCS8qIENoZWNrIGlmIGNsaWVudCBoYXMgYWxyZWFkeSB0cmllZCB0byBjbG9zZSB0aGUgVFNBUCAqLwoJaWYgKHNlbGYtPmNsb3NlX3BlbmQpIHsKCQkvKiBJbiB0aGlzIGNhc2UsIHRoZSBoaWdoZXIgbGF5ZXIgaXMgcHJvYmFibHkgZ29uZS4gRG9uJ3QKCQkgKiBib3RoZXIgaXQgYW5kIGNsZWFuIHVwIHRoZSByZW1haW5zIC0gSmVhbiBJSSAqLwoJCWlmIChza2IpCgkJCWRldl9rZnJlZV9za2Ioc2tiKTsKCQlpcnR0cF9jbG9zZV90c2FwKHNlbGYpOwoJCXJldHVybjsKCX0KCgkvKiBJZiB3ZSBhcmUgaGVyZSwgd2UgYXNzdW1lIHRoYXQgaXMgdGhlIGhpZ2hlciBsYXllciBpcyBzdGlsbAoJICogd2FpdGluZyBmb3IgdGhlIGRpc2Nvbm5lY3Qgbm90aWZpY2F0aW9uIGFuZCBhYmxlIHRvIHByb2Nlc3MgaXQsCgkgKiBldmVuIGlmIGhlIHRyaWVkIHRvIGRpc2Nvbm5lY3QuIE90aGVyd2lzZSwgaXQgd291bGQgaGF2ZSBhbHJlYWR5CgkgKiBhdHRlbXB0ZWQgdG8gY2xvc2UgdGhlIHRzYXAgYW5kIHNlbGYtPmNsb3NlX3BlbmQgd291bGQgYmUgVFJVRS4KCSAqIEplYW4gSUkgKi8KCgkvKiBObyBuZWVkIHRvIG5vdGlmeSB0aGUgY2xpZW50IGlmIGhhcyBhbHJlYWR5IHRyaWVkIHRvIGRpc2Nvbm5lY3QgKi8KCWlmKHNlbGYtPm5vdGlmeS5kaXNjb25uZWN0X2luZGljYXRpb24pCgkJc2VsZi0+bm90aWZ5LmRpc2Nvbm5lY3RfaW5kaWNhdGlvbihzZWxmLT5ub3RpZnkuaW5zdGFuY2UsIHNlbGYsCgkJCQkJCSAgIHJlYXNvbiwgc2tiKTsKCWVsc2UKCQlpZiAoc2tiKQoJCQlkZXZfa2ZyZWVfc2tiKHNrYik7Cn0KCi8qCiAqIEZ1bmN0aW9uIGlydHRwX2RvX2RhdGFfaW5kaWNhdGlvbiAoc2VsZiwgc2tiKQogKgogKiAgICBUcnkgdG8gZGVsaXZlciByZWFzc2VtYmxlZCBza2IgdG8gbGF5ZXIgYWJvdmUsIGFuZCByZXF1ZXVlIGl0IGlmIHRoYXQKICogICAgZm9yIHNvbWUgcmVhc29uIHNob3VsZCBmYWlsLiBXZSBtYXJrIHJ4IHNkdSBhcyBidXN5IHRvIGFwcGx5IGJhY2sKICogICAgcHJlc3N1cmUgaXMgbmVjZXNzYXJ5LgogKi8Kc3RhdGljIHZvaWQgaXJ0dHBfZG9fZGF0YV9pbmRpY2F0aW9uKHN0cnVjdCB0c2FwX2NiICpzZWxmLCBzdHJ1Y3Qgc2tfYnVmZiAqc2tiKQp7CglpbnQgZXJyOwoKCS8qIENoZWNrIGlmIGNsaWVudCBoYXMgYWxyZWFkeSBjbG9zZWQgdGhlIFRTQVAgYW5kIGdvbmUgYXdheSAqLwoJaWYgKHNlbGYtPmNsb3NlX3BlbmQpIHsKCQlkZXZfa2ZyZWVfc2tiKHNrYik7CgkJcmV0dXJuOwoJfQoKCWVyciA9IHNlbGYtPm5vdGlmeS5kYXRhX2luZGljYXRpb24oc2VsZi0+bm90aWZ5Lmluc3RhbmNlLCBzZWxmLCBza2IpOwoKCS8qIFVzdWFsbHkgdGhlIGxheWVyIGFib3ZlIHdpbGwgbm90aWZ5IHRoYXQgaXQncyBpbnB1dCBxdWV1ZSBpcwoJICogc3RhcnRpbmcgdG8gZ2V0IGZpbGxlZCBieSB1c2luZyB0aGUgZmxvdyByZXF1ZXN0LCBidXQgdGhpcyBtYXkKCSAqIGJlIGRpZmZpY3VsdCwgc28gaXQgY2FuIGluc3RlYWQganVzdCByZWZ1c2UgdG8gZWF0IGl0IGFuZCBqdXN0CgkgKiBnaXZlIGFuIGVycm9yIGJhY2sKCSAqLwoJaWYgKGVycikgewoJCUlSREFfREVCVUcoMCwgIiVzKCkgcmVxdWV1ZWluZyBza2IhXG4iLCBfX0ZVTkNUSU9OX18pOwoKCQkvKiBNYWtlIHN1cmUgd2UgdGFrZSBhIGJyZWFrICovCgkJc2VsZi0+cnhfc2R1X2J1c3kgPSBUUlVFOwoKCQkvKiBOZWVkIHRvIHB1c2ggdGhlIGhlYWRlciBpbiBhZ2FpbiAqLwoJCXNrYl9wdXNoKHNrYiwgVFRQX0hFQURFUik7CgkJc2tiLT5kYXRhWzBdID0gMHgwMDsgLyogTWFrZSBzdXJlIE1PUkUgYml0IGlzIGNsZWFyZWQgKi8KCgkJLyogUHV0IHNrYiBiYWNrIG9uIHF1ZXVlICovCgkJc2tiX3F1ZXVlX2hlYWQoJnNlbGYtPnJ4X3F1ZXVlLCBza2IpOwoJfQp9CgovKgogKiBGdW5jdGlvbiBpcnR0cF9ydW5fcnhfcXVldWUgKHNlbGYpCiAqCiAqICAgICBDaGVjayBpZiB3ZSBoYXZlIGFueSBmcmFtZXMgdG8gYmUgdHJhbnNtaXR0ZWQsIG9yIGlmIHdlIGhhdmUgYW55CiAqICAgICBhdmFpbGFibGUgY3JlZGl0IHRvIGdpdmUgYXdheS4KICovCnZvaWQgaXJ0dHBfcnVuX3J4X3F1ZXVlKHN0cnVjdCB0c2FwX2NiICpzZWxmKQp7CglzdHJ1Y3Qgc2tfYnVmZiAqc2tiOwoJaW50IG1vcmUgPSAwOwoKCUlSREFfREVCVUcoMiwgIiVzKCkgc2VuZD0lZCxhdmFpbD0lZCxyZW1vdGU9JWRcbiIsIF9fRlVOQ1RJT05fXywKCQkgICBzZWxmLT5zZW5kX2NyZWRpdCwgc2VsZi0+YXZhaWxfY3JlZGl0LCBzZWxmLT5yZW1vdGVfY3JlZGl0KTsKCgkvKiBHZXQgZXhjbHVzaXZlIGFjY2VzcyB0byB0aGUgcnggcXVldWUsIG90aGVyd2lzZSBkb24ndCB0b3VjaCBpdCAqLwoJaWYgKGlyZGFfbG9jaygmc2VsZi0+cnhfcXVldWVfbG9jaykgPT0gRkFMU0UpCgkJcmV0dXJuOwoKCS8qCgkgKiAgUmVhc3NlbWJsZSBhbGwgZnJhbWVzIGluIHJlY2VpdmUgcXVldWUgYW5kIGRlbGl2ZXIgdGhlbQoJICovCgl3aGlsZSAoIXNlbGYtPnJ4X3NkdV9idXN5ICYmIChza2IgPSBza2JfZGVxdWV1ZSgmc2VsZi0+cnhfcXVldWUpKSkgewoJCS8qIFRoaXMgYml0IHdpbGwgdGVsbCB1cyBpZiBpdCdzIHRoZSBsYXN0IGZyYWdtZW50IG9yIG5vdCAqLwoJCW1vcmUgPSBza2ItPmRhdGFbMF0gJiAweDgwOwoKCQkvKiBSZW1vdmUgVFRQIGhlYWRlciAqLwoJCXNrYl9wdWxsKHNrYiwgVFRQX0hFQURFUik7CgoJCS8qIEFkZCB0aGUgbGVuZ3RoIG9mIHRoZSByZW1haW5pbmcgZGF0YSAqLwoJCXNlbGYtPnJ4X3NkdV9zaXplICs9IHNrYi0+bGVuOwoKCQkvKgoJCSAqIElmIFNBUiBpcyBkaXNhYmxlZCwgb3IgdXNlciBoYXMgcmVxdWVzdGVkIG5vIHJlYXNzZW1ibHkKCQkgKiBvZiByZWNlaXZlZCBmcmFnbWVudHMgdGhlbiB3ZSBqdXN0IGRlbGl2ZXIgdGhlbQoJCSAqIGltbWVkaWF0ZWx5LiBUaGlzIGNhbiBiZSByZXF1ZXN0ZWQgYnkgY2xpZW50cyB0aGF0CgkJICogaW1wbGVtZW50cyBieXRlIHN0cmVhbXMgd2l0aG91dCBhbnkgbWVzc2FnZSBib3VuZGFyaWVzCgkJICovCgkJaWYgKHNlbGYtPnJ4X21heF9zZHVfc2l6ZSA9PSBUVFBfU0FSX0RJU0FCTEUpIHsKCQkJaXJ0dHBfZG9fZGF0YV9pbmRpY2F0aW9uKHNlbGYsIHNrYik7CgkJCXNlbGYtPnJ4X3NkdV9zaXplID0gMDsKCgkJCWNvbnRpbnVlOwoJCX0KCgkJLyogQ2hlY2sgaWYgdGhpcyBpcyBhIGZyYWdtZW50LCBhbmQgbm90IHRoZSBsYXN0IGZyYWdtZW50ICovCgkJaWYgKG1vcmUpIHsKCQkJLyoKCQkJICogIFF1ZXVlIHRoZSBmcmFnbWVudCBpZiB3ZSBzdGlsbCBhcmUgd2l0aGluIHRoZQoJCQkgKiAgbGltaXRzIG9mIHRoZSBtYXhpbXVtIHNpemUgb2YgdGhlIHJ4X3NkdQoJCQkgKi8KCQkJaWYgKHNlbGYtPnJ4X3NkdV9zaXplIDw9IHNlbGYtPnJ4X21heF9zZHVfc2l6ZSkgewoJCQkJSVJEQV9ERUJVRyg0LCAiJXMoKSwgcXVldWVpbmcgZnJhZ1xuIiwKCQkJCQkgICBfX0ZVTkNUSU9OX18pOwoJCQkJc2tiX3F1ZXVlX3RhaWwoJnNlbGYtPnJ4X2ZyYWdtZW50cywgc2tiKTsKCQkJfSBlbHNlIHsKCQkJCS8qIEZyZWUgdGhlIHBhcnQgb2YgdGhlIFNEVSB0aGF0IGlzIHRvbyBiaWcgKi8KCQkJCWRldl9rZnJlZV9za2Ioc2tiKTsKCQkJfQoJCQljb250aW51ZTsKCQl9CgkJLyoKCQkgKiAgVGhpcyBpcyB0aGUgbGFzdCBmcmFnbWVudCwgc28gdGltZSB0byByZWFzc2VtYmxlIQoJCSAqLwoJCWlmICgoc2VsZi0+cnhfc2R1X3NpemUgPD0gc2VsZi0+cnhfbWF4X3NkdV9zaXplKSB8fAoJCSAgICAoc2VsZi0+cnhfbWF4X3NkdV9zaXplID09IFRUUF9TQVJfVU5CT1VORCkpCgkJewoJCQkvKgoJCQkgKiBBIGxpdHRsZSBvcHRpbWl6aW5nLiBPbmx5IHF1ZXVlIHRoZSBmcmFnbWVudCBpZgoJCQkgKiB0aGVyZSBhcmUgb3RoZXIgZnJhZ21lbnRzLiBTaW5jZSBpZiB0aGlzIGlzIHRoZQoJCQkgKiBsYXN0IGFuZCBvbmx5IGZyYWdtZW50LCB0aGVyZSBpcyBubyBuZWVkIHRvCgkJCSAqIHJlYXNzZW1ibGUgOi0pCgkJCSAqLwoJCQlpZiAoIXNrYl9xdWV1ZV9lbXB0eSgmc2VsZi0+cnhfZnJhZ21lbnRzKSkgewoJCQkJc2tiX3F1ZXVlX3RhaWwoJnNlbGYtPnJ4X2ZyYWdtZW50cywKCQkJCQkgICAgICAgc2tiKTsKCgkJCQlza2IgPSBpcnR0cF9yZWFzc2VtYmxlX3NrYihzZWxmKTsKCQkJfQoKCQkJLyogTm93IHdlIGNhbiBkZWxpdmVyIHRoZSByZWFzc2VtYmxlZCBza2IgKi8KCQkJaXJ0dHBfZG9fZGF0YV9pbmRpY2F0aW9uKHNlbGYsIHNrYik7CgkJfSBlbHNlIHsKCQkJSVJEQV9ERUJVRygxLCAiJXMoKSwgVHJ1bmNhdGVkIGZyYW1lXG4iLCBfX0ZVTkNUSU9OX18pOwoKCQkJLyogRnJlZSB0aGUgcGFydCBvZiB0aGUgU0RVIHRoYXQgaXMgdG9vIGJpZyAqLwoJCQlkZXZfa2ZyZWVfc2tiKHNrYik7CgoJCQkvKiBEZWxpdmVyIG9ubHkgdGhlIHZhbGlkIGJ1dCB0cnVuY2F0ZWQgcGFydCBvZiBTRFUgKi8KCQkJc2tiID0gaXJ0dHBfcmVhc3NlbWJsZV9za2Ioc2VsZik7CgoJCQlpcnR0cF9kb19kYXRhX2luZGljYXRpb24oc2VsZiwgc2tiKTsKCQl9CgkJc2VsZi0+cnhfc2R1X3NpemUgPSAwOwoJfQoKCS8qCgkgKiBJdCdzIG5vdCB0cml2aWFsIHRvIGtlZXAgdHJhY2sgb2YgaG93IG1hbnkgY3JlZGl0cyBhcmUgYXZhaWxhYmxlCgkgKiBieSBpbmNyZW1lbnRpbmcgYXQgZWFjaCBwYWNrZXQsIGJlY2F1c2UgZGVsaXZlcnkgbWF5IGZhaWwKCSAqIChpcnR0cF9kb19kYXRhX2luZGljYXRpb24oKSBtYXkgcmVxdWV1ZSB0aGUgZnJhbWUpIGFuZCBiZWNhdXNlCgkgKiB3ZSBuZWVkIHRvIHRha2UgY2FyZSBvZiBmcmFnbWVudGF0aW9uLgoJICogV2Ugd2FudCB0aGUgb3RoZXIgc2lkZSB0byBzZW5kIHVwIHRvIGluaXRpYWxfY3JlZGl0IHBhY2tldHMuCgkgKiBXZSBoYXZlIHNvbWUgZnJhbWVzIGluIG91ciBxdWV1ZXMsIGFuZCB3ZSBoYXZlIGFscmVhZHkgYWxsb3dlZCBpdAoJICogdG8gc2VuZCByZW1vdGVfY3JlZGl0LgoJICogTm8gbmVlZCB0byBzcGlubG9jaywgd3JpdGUgaXMgYXRvbWljIGFuZCBzZWxmIGNvcnJlY3RpbmcuLi4KCSAqIEplYW4gSUkKCSAqLwoJc2VsZi0+YXZhaWxfY3JlZGl0ID0gKHNlbGYtPmluaXRpYWxfY3JlZGl0IC0KCQkJICAgICAgKHNlbGYtPnJlbW90ZV9jcmVkaXQgKwoJCQkgICAgICAgc2tiX3F1ZXVlX2xlbigmc2VsZi0+cnhfcXVldWUpICsKCQkJICAgICAgIHNrYl9xdWV1ZV9sZW4oJnNlbGYtPnJ4X2ZyYWdtZW50cykpKTsKCgkvKiBEbyB3ZSBoYXZlIHRvbyBtdWNoIGNyZWRpdHMgdG8gc2VuZCB0byBwZWVyID8gKi8KCWlmICgoc2VsZi0+cmVtb3RlX2NyZWRpdCA8PSBUVFBfUlhfTUlOX0NSRURJVCkgJiYKCSAgICAoc2VsZi0+YXZhaWxfY3JlZGl0ID4gMCkpIHsKCQkvKiBTZW5kIGV4cGxpY2l0IGNyZWRpdCBmcmFtZSAqLwoJCWlydHRwX2dpdmVfY3JlZGl0KHNlbGYpOwoJCS8qIE5vdGUgOiBkbyAqTk9UKiBjaGVjayBpZiB0eF9xdWV1ZSBpcyBub24tZW1wdHksIHRoYXQKCQkgKiB3aWxsIHByb2R1Y2UgZGVhZGxvY2tzLiBJIHJlcGVhdCA6IHNlbmQgYSBjcmVkaXQgZnJhbWUKCQkgKiBldmVuIGlmIHdlIGhhdmUgc29tZXRoaW5nIHRvIHNlbmQgaW4gb3VyIFR4IHF1ZXVlLgoJCSAqIElmIHdlIGhhdmUgY3JlZGl0cywgaXQgbWVhbnMgdGhhdCBvdXIgVHggcXVldWUgaXMgYmxvY2tlZC4KCQkgKgoJCSAqIExldCdzIHN1cHBvc2UgdGhlIHBlZXIgY2FuJ3Qga2VlcCB1cCB3aXRoIG91ciBUeC4gSGUgd2lsbAoJCSAqIGZsb3cgY29udHJvbCB1cyBieSBub3Qgc2VuZGluZyB1cyBhbnkgY3JlZGl0cywgYW5kIHdlCgkJICogd2lsbCBzdG9wIFR4IGFuZCBzdGFydCBhY2N1bXVsYXRpbmcgY3JlZGl0cyBoZXJlLgoJCSAqIFVwIHRvIHRoZSBwb2ludCB3aGVyZSB0aGUgcGVlciB3aWxsIHN0b3AgaXRzIFR4IHF1ZXVlLAoJCSAqIGZvciBsYWNrIG9mIGNyZWRpdHMuCgkJICogTGV0J3MgYXNzdW1lIHRoZSBwZWVyIGFwcGxpY2F0aW9uIGlzIHNpbmdsZSB0aHJlYWRlZC4KCQkgKiBJdCB3aWxsIGJsb2NrIG9uIFR4IGFuZCBuZXZlciBjb25zdW1lIGFueSBSeCBidWZmZXIuCgkJICogRGVhZGxvY2suIEd1YXJhbnRlZWQuIC0gSmVhbiBJSQoJCSAqLwoJfQoKCS8qIFJlc2V0IGxvY2sgKi8KCXNlbGYtPnJ4X3F1ZXVlX2xvY2sgPSAwOwp9CgojaWZkZWYgQ09ORklHX1BST0NfRlMKc3RydWN0IGlydHRwX2l0ZXJfc3RhdGUgewoJaW50IGlkOwp9OwoKc3RhdGljIHZvaWQgKmlydHRwX3NlcV9zdGFydChzdHJ1Y3Qgc2VxX2ZpbGUgKnNlcSwgbG9mZl90ICpwb3MpCnsKCXN0cnVjdCBpcnR0cF9pdGVyX3N0YXRlICppdGVyID0gc2VxLT5wcml2YXRlOwoJc3RydWN0IHRzYXBfY2IgKnNlbGY7CgoJLyogUHJvdGVjdCBvdXIgYWNjZXNzIHRvIHRoZSB0c2FwIGxpc3QgKi8KCXNwaW5fbG9ja19pcnEoJmlydHRwLT50c2Fwcy0+aGJfc3BpbmxvY2spOwoJaXRlci0+aWQgPSAwOwoKCWZvciAoc2VsZiA9IChzdHJ1Y3QgdHNhcF9jYiAqKSBoYXNoYmluX2dldF9maXJzdChpcnR0cC0+dHNhcHMpOyAKCSAgICAgc2VsZiAhPSBOVUxMOwoJICAgICBzZWxmID0gKHN0cnVjdCB0c2FwX2NiICopIGhhc2hiaW5fZ2V0X25leHQoaXJ0dHAtPnRzYXBzKSkgewoJCWlmIChpdGVyLT5pZCA9PSAqcG9zKQoJCQlicmVhazsKCQkrK2l0ZXItPmlkOwoJfQoJCQoJcmV0dXJuIHNlbGY7Cn0KCnN0YXRpYyB2b2lkICppcnR0cF9zZXFfbmV4dChzdHJ1Y3Qgc2VxX2ZpbGUgKnNlcSwgdm9pZCAqdiwgbG9mZl90ICpwb3MpCnsKCXN0cnVjdCBpcnR0cF9pdGVyX3N0YXRlICppdGVyID0gc2VxLT5wcml2YXRlOwoKCSsrKnBvczsKCSsraXRlci0+aWQ7CglyZXR1cm4gKHZvaWQgKikgaGFzaGJpbl9nZXRfbmV4dChpcnR0cC0+dHNhcHMpOwp9CgpzdGF0aWMgdm9pZCBpcnR0cF9zZXFfc3RvcChzdHJ1Y3Qgc2VxX2ZpbGUgKnNlcSwgdm9pZCAqdikKewoJc3Bpbl91bmxvY2tfaXJxKCZpcnR0cC0+dHNhcHMtPmhiX3NwaW5sb2NrKTsKfQoKc3RhdGljIGludCBpcnR0cF9zZXFfc2hvdyhzdHJ1Y3Qgc2VxX2ZpbGUgKnNlcSwgdm9pZCAqdikKewoJY29uc3Qgc3RydWN0IGlydHRwX2l0ZXJfc3RhdGUgKml0ZXIgPSBzZXEtPnByaXZhdGU7Cgljb25zdCBzdHJ1Y3QgdHNhcF9jYiAqc2VsZiA9IHY7CgoJc2VxX3ByaW50ZihzZXEsICJUU0FQICVkLCAiLCBpdGVyLT5pZCk7CglzZXFfcHJpbnRmKHNlcSwgInN0c2FwX3NlbDogJTAyeCwgIiwKCQkgICBzZWxmLT5zdHNhcF9zZWwpOwoJc2VxX3ByaW50ZihzZXEsICJkdHNhcF9zZWw6ICUwMnhcbiIsCgkJICAgc2VsZi0+ZHRzYXBfc2VsKTsKCXNlcV9wcmludGYoc2VxLCAiICBjb25uZWN0ZWQ6ICVzLCAiLAoJCSAgIHNlbGYtPmNvbm5lY3RlZD8gIlRSVUUiOiJGQUxTRSIpOwoJc2VxX3ByaW50ZihzZXEsICJhdmFpbCBjcmVkaXQ6ICVkLCAiLAoJCSAgIHNlbGYtPmF2YWlsX2NyZWRpdCk7CglzZXFfcHJpbnRmKHNlcSwgInJlbW90ZSBjcmVkaXQ6ICVkLCAiLAoJCSAgIHNlbGYtPnJlbW90ZV9jcmVkaXQpOwoJc2VxX3ByaW50ZihzZXEsICJzZW5kIGNyZWRpdDogJWRcbiIsCgkJICAgc2VsZi0+c2VuZF9jcmVkaXQpOwoJc2VxX3ByaW50ZihzZXEsICIgIHR4IHBhY2tldHM6ICVsZCwgIiwKCQkgICBzZWxmLT5zdGF0cy50eF9wYWNrZXRzKTsKCXNlcV9wcmludGYoc2VxLCAicnggcGFja2V0czogJWxkLCAiLAoJCSAgIHNlbGYtPnN0YXRzLnJ4X3BhY2tldHMpOwoJc2VxX3ByaW50ZihzZXEsICJ0eF9xdWV1ZSBsZW46ICVkICIsCgkJICAgc2tiX3F1ZXVlX2xlbigmc2VsZi0+dHhfcXVldWUpKTsKCXNlcV9wcmludGYoc2VxLCAicnhfcXVldWUgbGVuOiAlZFxuIiwKCQkgICBza2JfcXVldWVfbGVuKCZzZWxmLT5yeF9xdWV1ZSkpOwoJc2VxX3ByaW50ZihzZXEsICIgIHR4X3NkdV9idXN5OiAlcywgIiwKCQkgICBzZWxmLT50eF9zZHVfYnVzeT8gIlRSVUUiOiJGQUxTRSIpOwoJc2VxX3ByaW50ZihzZXEsICJyeF9zZHVfYnVzeTogJXNcbiIsCgkJICAgc2VsZi0+cnhfc2R1X2J1c3k/ICJUUlVFIjoiRkFMU0UiKTsKCXNlcV9wcmludGYoc2VxLCAiICBtYXhfc2VnX3NpemU6ICVkLCAiLAoJCSAgIHNlbGYtPm1heF9zZWdfc2l6ZSk7CglzZXFfcHJpbnRmKHNlcSwgInR4X21heF9zZHVfc2l6ZTogJWQsICIsCgkJICAgc2VsZi0+dHhfbWF4X3NkdV9zaXplKTsKCXNlcV9wcmludGYoc2VxLCAicnhfbWF4X3NkdV9zaXplOiAlZFxuIiwKCQkgICBzZWxmLT5yeF9tYXhfc2R1X3NpemUpOwoKCXNlcV9wcmludGYoc2VxLCAiICBVc2VkIGJ5ICglcylcblxuIiwKCQkgICBzZWxmLT5ub3RpZnkubmFtZSk7CglyZXR1cm4gMDsKfQoKc3RhdGljIHN0cnVjdCBzZXFfb3BlcmF0aW9ucyBpcnR0cF9zZXFfb3BzID0gewoJLnN0YXJ0ICA9IGlydHRwX3NlcV9zdGFydCwKCS5uZXh0ICAgPSBpcnR0cF9zZXFfbmV4dCwKCS5zdG9wICAgPSBpcnR0cF9zZXFfc3RvcCwKCS5zaG93ICAgPSBpcnR0cF9zZXFfc2hvdywKfTsKCnN0YXRpYyBpbnQgaXJ0dHBfc2VxX29wZW4oc3RydWN0IGlub2RlICppbm9kZSwgc3RydWN0IGZpbGUgKmZpbGUpCnsKCXN0cnVjdCBzZXFfZmlsZSAqc2VxOwoJaW50IHJjID0gLUVOT01FTTsKCXN0cnVjdCBpcnR0cF9pdGVyX3N0YXRlICpzOwoKCXMgPSBremFsbG9jKHNpemVvZigqcyksIEdGUF9LRVJORUwpOwoJaWYgKCFzKQoJCWdvdG8gb3V0OwoKCXJjID0gc2VxX29wZW4oZmlsZSwgJmlydHRwX3NlcV9vcHMpOwoJaWYgKHJjKQoJCWdvdG8gb3V0X2tmcmVlOwoKCXNlcQkgICAgID0gZmlsZS0+cHJpdmF0ZV9kYXRhOwoJc2VxLT5wcml2YXRlID0gczsKb3V0OgoJcmV0dXJuIHJjOwpvdXRfa2ZyZWU6CglrZnJlZShzKTsKCWdvdG8gb3V0Owp9CgpzdHJ1Y3QgZmlsZV9vcGVyYXRpb25zIGlydHRwX3NlcV9mb3BzID0gewoJLm93bmVyCQk9IFRISVNfTU9EVUxFLAoJLm9wZW4gICAgICAgICAgID0gaXJ0dHBfc2VxX29wZW4sCgkucmVhZCAgICAgICAgICAgPSBzZXFfcmVhZCwKCS5sbHNlZWsgICAgICAgICA9IHNlcV9sc2VlaywKCS5yZWxlYXNlCT0gc2VxX3JlbGVhc2VfcHJpdmF0ZSwKfTsKCiNlbmRpZiAvKiBQUk9DX0ZTICovCg==