LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICAgICAKICogRmlsZW5hbWU6ICAgICAgaXJ0dHAuYwogKiBWZXJzaW9uOiAgICAgICAxLjIKICogRGVzY3JpcHRpb246ICAgVGlueSBUcmFuc3BvcnQgUHJvdG9jb2wgKFRUUCkgaW1wbGVtZW50YXRpb24KICogU3RhdHVzOiAgICAgICAgU3RhYmxlCiAqIEF1dGhvcjogICAgICAgIERhZyBCcmF0dGxpIDxkYWdiQGNzLnVpdC5ubz4KICogQ3JlYXRlZCBhdDogICAgU3VuIEF1ZyAzMSAyMDoxNDozMSAxOTk3CiAqIE1vZGlmaWVkIGF0OiAgIFdlZCBKYW4gIDUgMTE6MzE6MjcgMjAwMAogKiBNb2RpZmllZCBieTogICBEYWcgQnJhdHRsaSA8ZGFnYkBjcy51aXQubm8+CiAqIAogKiAgICAgQ29weXJpZ2h0IChjKSAxOTk4LTIwMDAgRGFnIEJyYXR0bGkgPGRhZ2JAY3MudWl0Lm5vPiwgCiAqICAgICBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiAgICAgQ29weXJpZ2h0IChjKSAyMDAwLTIwMDMgSmVhbiBUb3VycmlsaGVzIDxqdEBocGwuaHAuY29tPgogKiAgICAgCiAqICAgICBUaGlzIHByb2dyYW0gaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIAogKiAgICAgbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgCiAqICAgICBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyIHZlcnNpb24gMiBvZiAKICogICAgIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiAgICAgTmVpdGhlciBEYWcgQnJhdHRsaSBub3IgVW5pdmVyc2l0eSBvZiBUcm9tc/ggYWRtaXQgbGlhYmlsaXR5IG5vcgogKiAgICAgcHJvdmlkZSB3YXJyYW50eSBmb3IgYW55IG9mIHRoaXMgc29mdHdhcmUuIFRoaXMgbWF0ZXJpYWwgaXMgCiAqICAgICBwcm92aWRlZCAiQVMtSVMiIGFuZCBhdCBubyBjaGFyZ2UuCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCiNpbmNsdWRlIDxsaW51eC9za2J1ZmYuaD4KI2luY2x1ZGUgPGxpbnV4L2luaXQuaD4KI2luY2x1ZGUgPGxpbnV4L3NlcV9maWxlLmg+CgojaW5jbHVkZSA8YXNtL2J5dGVvcmRlci5oPgojaW5jbHVkZSA8YXNtL3VuYWxpZ25lZC5oPgoKI2luY2x1ZGUgPG5ldC9pcmRhL2lyZGEuaD4KI2luY2x1ZGUgPG5ldC9pcmRhL2lybGFwLmg+CiNpbmNsdWRlIDxuZXQvaXJkYS9pcmxtcC5oPgojaW5jbHVkZSA8bmV0L2lyZGEvcGFyYW1ldGVycy5oPgojaW5jbHVkZSA8bmV0L2lyZGEvaXJ0dHAuaD4KCnN0YXRpYyBzdHJ1Y3QgaXJ0dHBfY2IgKmlydHRwOwoKc3RhdGljIHZvaWQgX19pcnR0cF9jbG9zZV90c2FwKHN0cnVjdCB0c2FwX2NiICpzZWxmKTsKCnN0YXRpYyBpbnQgaXJ0dHBfZGF0YV9pbmRpY2F0aW9uKHZvaWQgKmluc3RhbmNlLCB2b2lkICpzYXAsIAoJCQkJIHN0cnVjdCBza19idWZmICpza2IpOwpzdGF0aWMgaW50IGlydHRwX3VkYXRhX2luZGljYXRpb24odm9pZCAqaW5zdGFuY2UsIHZvaWQgKnNhcCwgCgkJCQkgIHN0cnVjdCBza19idWZmICpza2IpOwpzdGF0aWMgdm9pZCBpcnR0cF9kaXNjb25uZWN0X2luZGljYXRpb24odm9pZCAqaW5zdGFuY2UsIHZvaWQgKnNhcCwgIAoJCQkJCUxNX1JFQVNPTiByZWFzb24sIHN0cnVjdCBza19idWZmICopOwpzdGF0aWMgdm9pZCBpcnR0cF9jb25uZWN0X2luZGljYXRpb24odm9pZCAqaW5zdGFuY2UsIHZvaWQgKnNhcCwgCgkJCQkgICAgIHN0cnVjdCBxb3NfaW5mbyAqcW9zLCBfX3UzMiBtYXhfc2R1X3NpemUsCgkJCQkgICAgIF9fdTggaGVhZGVyX3NpemUsIHN0cnVjdCBza19idWZmICpza2IpOwpzdGF0aWMgdm9pZCBpcnR0cF9jb25uZWN0X2NvbmZpcm0odm9pZCAqaW5zdGFuY2UsIHZvaWQgKnNhcCwgCgkJCQkgIHN0cnVjdCBxb3NfaW5mbyAqcW9zLCBfX3UzMiBtYXhfc2R1X3NpemUsIAoJCQkJICBfX3U4IGhlYWRlcl9zaXplLCBzdHJ1Y3Qgc2tfYnVmZiAqc2tiKTsKc3RhdGljIHZvaWQgaXJ0dHBfcnVuX3R4X3F1ZXVlKHN0cnVjdCB0c2FwX2NiICpzZWxmKTsKc3RhdGljIHZvaWQgaXJ0dHBfcnVuX3J4X3F1ZXVlKHN0cnVjdCB0c2FwX2NiICpzZWxmKTsKCnN0YXRpYyB2b2lkIGlydHRwX2ZsdXNoX3F1ZXVlcyhzdHJ1Y3QgdHNhcF9jYiAqc2VsZik7CnN0YXRpYyB2b2lkIGlydHRwX2ZyYWdtZW50X3NrYihzdHJ1Y3QgdHNhcF9jYiAqc2VsZiwgc3RydWN0IHNrX2J1ZmYgKnNrYik7CnN0YXRpYyBzdHJ1Y3Qgc2tfYnVmZiAqaXJ0dHBfcmVhc3NlbWJsZV9za2Ioc3RydWN0IHRzYXBfY2IgKnNlbGYpOwpzdGF0aWMgdm9pZCBpcnR0cF90b2RvX2V4cGlyZWQodW5zaWduZWQgbG9uZyBkYXRhKTsKc3RhdGljIGludCBpcnR0cF9wYXJhbV9tYXhfc2R1X3NpemUodm9pZCAqaW5zdGFuY2UsIGlyZGFfcGFyYW1fdCAqcGFyYW0sIAoJCQkJICAgIGludCBnZXQpOwoKc3RhdGljIHZvaWQgaXJ0dHBfZmxvd19pbmRpY2F0aW9uKHZvaWQgKmluc3RhbmNlLCB2b2lkICpzYXAsIExPQ0FMX0ZMT1cgZmxvdyk7CnN0YXRpYyB2b2lkIGlydHRwX3N0YXR1c19pbmRpY2F0aW9uKHZvaWQgKmluc3RhbmNlLAoJCQkJICAgIExJTktfU1RBVFVTIGxpbmssIExPQ0tfU1RBVFVTIGxvY2spOwoKLyogSW5mb3JtYXRpb24gZm9yIHBhcnNpbmcgcGFyYW1ldGVycyBpbiBJclRUUCAqLwpzdGF0aWMgcGlfbWlub3JfaW5mb190IHBpX21pbm9yX2NhbGxfdGFibGVbXSA9IHsKCXsgTlVMTCwgMCB9LCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIDB4MDAgKi8KCXsgaXJ0dHBfcGFyYW1fbWF4X3NkdV9zaXplLCBQVl9JTlRFR0VSIHwgUFZfQklHX0VORElBTiB9IC8qIDB4MDEgKi8KfTsKc3RhdGljIHBpX21ham9yX2luZm9fdCBwaV9tYWpvcl9jYWxsX3RhYmxlW10gPSB7eyBwaV9taW5vcl9jYWxsX3RhYmxlLCAyIH19OwpzdGF0aWMgcGlfcGFyYW1faW5mb190IHBhcmFtX2luZm8gPSB7IHBpX21ham9yX2NhbGxfdGFibGUsIDEsIDB4MGYsIDQgfTsKCi8qKioqKioqKioqKioqKioqKioqKioqKiogR0xPQkFMIFBST0NFRFVSRVMgKioqKioqKioqKioqKioqKioqKioqKioqLwoKLyoKICogRnVuY3Rpb24gaXJ0dHBfaW5pdCAodm9pZCkKICoKICogICAgSW5pdGlhbGl6ZSB0aGUgSXJUVFAgbGF5ZXIuIENhbGxlZCBieSBtb2R1bGUgaW5pdGlhbGl6YXRpb24gY29kZQogKgogKi8KaW50IF9faW5pdCBpcnR0cF9pbml0KHZvaWQpCnsKCWlydHRwID0ga21hbGxvYyhzaXplb2Yoc3RydWN0IGlydHRwX2NiKSwgR0ZQX0tFUk5FTCk7CglpZiAoaXJ0dHAgPT0gTlVMTCkKCQlyZXR1cm4gLUVOT01FTTsKCW1lbXNldChpcnR0cCwgMCwgc2l6ZW9mKHN0cnVjdCBpcnR0cF9jYikpOwoKCWlydHRwLT5tYWdpYyA9IFRUUF9NQUdJQzsKCglpcnR0cC0+dHNhcHMgPSBoYXNoYmluX25ldyhIQl9MT0NLKTsKCWlmICghaXJ0dHAtPnRzYXBzKSB7CgkJSVJEQV9FUlJPUigiJXM6IGNhbid0IGFsbG9jYXRlIElyVFRQIGhhc2hiaW4hXG4iLAoJCQkgICBfX0ZVTkNUSU9OX18pOwoJCWtmcmVlKGlydHRwKTsKCQlyZXR1cm4gLUVOT01FTTsKCX0KCglyZXR1cm4gMDsKfQoKLyoKICogRnVuY3Rpb24gaXJ0dHBfY2xlYW51cCAodm9pZCkKICoKICogICAgQ2FsbGVkIGJ5IG1vZHVsZSBkZXN0cnVjdGlvbi9jbGVhbnVwIGNvZGUKICoKICovCnZvaWQgX19leGl0IGlydHRwX2NsZWFudXAodm9pZCkgCnsKCS8qIENoZWNrIGZvciBtYWluIHN0cnVjdHVyZSAqLwoJSVJEQV9BU1NFUlQoaXJ0dHAtPm1hZ2ljID09IFRUUF9NQUdJQywgcmV0dXJuOyk7CgoJLyoKCSAqICBEZWxldGUgaGFzaGJpbiBhbmQgY2xvc2UgYWxsIFRTQVAgaW5zdGFuY2VzIGluIGl0CgkgKi8KCWhhc2hiaW5fZGVsZXRlKGlydHRwLT50c2FwcywgKEZSRUVfRlVOQykgX19pcnR0cF9jbG9zZV90c2FwKTsKCglpcnR0cC0+bWFnaWMgPSAwOwoKCS8qIERlLWFsbG9jYXRlIG1haW4gc3RydWN0dXJlICovCglrZnJlZShpcnR0cCk7CgoJaXJ0dHAgPSBOVUxMOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqIFNVQlJPVVRJTkVTICoqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCi8qCiAqIEZ1bmN0aW9uIGlydHRwX3N0YXJ0X3RvZG9fdGltZXIgKHNlbGYsIHRpbWVvdXQpCiAqCiAqICAgIFN0YXJ0IHRvZG8gdGltZXIuCiAqCiAqIE1hZGUgaXQgbW9yZSBlZmZpZW50IGFuZCB1bnNlbnNpdGl2ZSB0byByYWNlIGNvbmRpdGlvbnMgLSBKZWFuIElJCiAqLwpzdGF0aWMgaW5saW5lIHZvaWQgaXJ0dHBfc3RhcnRfdG9kb190aW1lcihzdHJ1Y3QgdHNhcF9jYiAqc2VsZiwgaW50IHRpbWVvdXQpCnsKCS8qIFNldCBuZXcgdmFsdWUgZm9yIHRpbWVyICovCgltb2RfdGltZXIoJnNlbGYtPnRvZG9fdGltZXIsIGppZmZpZXMgKyB0aW1lb3V0KTsKfQoKLyoKICogRnVuY3Rpb24gaXJ0dHBfdG9kb19leHBpcmVkIChkYXRhKQogKgogKiAgICBUb2RvIHRpbWVyIGhhcyBleHBpcmVkIQogKgogKiBPbmUgb2YgdGhlIHJlc3RyaWN0aW9uIG9mIHRoZSB0aW1lciBpcyB0aGF0IGl0IGlzIHJ1biBvbmx5IG9uIHRoZSB0aW1lcgogKiBpbnRlcnJ1cHQgd2hpY2ggcnVuIGV2ZXJ5IDEwbXMuIFRoaXMgbWVhbiB0aGF0IGV2ZW4gaWYgeW91IHNldCB0aGUgdGltZXIKICogd2l0aCBhIGRlbGF5IG9mIDAsIGl0IG1heSB0YWtlIHVwIHRvIDEwbXMgYmVmb3JlIGl0J3MgcnVuLgogKiBTbywgdG8gbWluaW1pc2UgbGF0ZW5jeSBhbmQga2VlcCBjYWNoZSBmcmVzaCwgd2UgdHJ5IHRvIGF2b2lkIHVzaW5nCiAqIGl0IGFzIG11Y2ggYXMgcG9zc2libGUuCiAqIE5vdGUgOiB3ZSBjYW4ndCB1c2UgdGFza2xldHMsIGJlY2F1c2UgdGhleSBjYW4ndCBiZSBhc3luY2hyb25vdXNseQogKiBraWxsZWQgKG5lZWQgdXNlciBjb250ZXh0KSwgYW5kIHdlIGNhbid0IGd1YXJhbnRlZSB0aGF0IGhlcmUuLi4KICogSmVhbiBJSQogKi8Kc3RhdGljIHZvaWQgaXJ0dHBfdG9kb19leHBpcmVkKHVuc2lnbmVkIGxvbmcgZGF0YSkKewoJc3RydWN0IHRzYXBfY2IgKnNlbGYgPSAoc3RydWN0IHRzYXBfY2IgKikgZGF0YTsKCgkvKiBDaGVjayB0aGF0IHdlIHN0aWxsIGV4aXN0ICovCglpZiAoIXNlbGYgfHwgc2VsZi0+bWFnaWMgIT0gVFRQX1RTQVBfTUFHSUMpCgkJcmV0dXJuOwoKCUlSREFfREVCVUcoNCwgIiVzKGluc3RhbmNlPSVwKVxuIiwgX19GVU5DVElPTl9fLCBzZWxmKTsKCgkvKiBUcnkgdG8gbWFrZSBzb21lIHByb2dyZXNzLCBlc3BlY2lhbGx5IG9uIFR4IHNpZGUgLSBKZWFuIElJICovCglpcnR0cF9ydW5fcnhfcXVldWUoc2VsZik7CglpcnR0cF9ydW5fdHhfcXVldWUoc2VsZik7CgoJLyogQ2hlY2sgaWYgdGltZSBmb3IgZGlzY29ubmVjdCAqLwoJaWYgKHRlc3RfYml0KDAsICZzZWxmLT5kaXNjb25uZWN0X3BlbmQpKSB7CgkJLyogQ2hlY2sgaWYgaXQncyBwb3NzaWJsZSB0byBkaXNjb25uZWN0IHlldCAqLwoJCWlmIChza2JfcXVldWVfZW1wdHkoJnNlbGYtPnR4X3F1ZXVlKSkgewoJCQkvKiBNYWtlIHN1cmUgZGlzY29ubmVjdCBpcyBub3QgcGVuZGluZyBhbnltb3JlICovCgkJCWNsZWFyX2JpdCgwLCAmc2VsZi0+ZGlzY29ubmVjdF9wZW5kKTsJLyogRkFMU0UgKi8KCgkJCS8qIE5vdGUgOiBzZWxmLT5kaXNjb25uZWN0X3NrYiBtYXkgYmUgTlVMTCAqLwoJCQlpcnR0cF9kaXNjb25uZWN0X3JlcXVlc3Qoc2VsZiwgc2VsZi0+ZGlzY29ubmVjdF9za2IsCgkJCQkJCSBQX05PUk1BTCk7CgkJCXNlbGYtPmRpc2Nvbm5lY3Rfc2tiID0gTlVMTDsKCQl9IGVsc2UgewoJCQkvKiBUcnkgYWdhaW4gbGF0ZXIgKi8KCQkJaXJ0dHBfc3RhcnRfdG9kb190aW1lcihzZWxmLCBIWi8xMCk7CgoJCQkvKiBObyByZWFzb24gdG8gdHJ5IGFuZCBjbG9zZSBub3cgKi8KCQkJcmV0dXJuOwoJCX0KCX0KCgkvKiBDaGVjayBpZiBpdCdzIGNsb3NpbmcgdGltZSAqLwoJaWYgKHNlbGYtPmNsb3NlX3BlbmQpCgkJLyogRmluaXNoIGNsZWFudXAgKi8KCQlpcnR0cF9jbG9zZV90c2FwKHNlbGYpOwp9CgovKgogKiBGdW5jdGlvbiBpcnR0cF9mbHVzaF9xdWV1ZXMgKHNlbGYpCiAqCiAqICAgICBGbHVzaGVzIChyZW1vdmVzIGFsbCBmcmFtZXMpIGluIHRyYW5zaXR0LWJ1ZmZlciAodHhfbGlzdCkKICovCnZvaWQgaXJ0dHBfZmx1c2hfcXVldWVzKHN0cnVjdCB0c2FwX2NiICpzZWxmKQp7CglzdHJ1Y3Qgc2tfYnVmZiogc2tiOwoKCUlSREFfREVCVUcoNCwgIiVzKClcbiIsIF9fRlVOQ1RJT05fXyk7CgoJSVJEQV9BU1NFUlQoc2VsZiAhPSBOVUxMLCByZXR1cm47KTsKCUlSREFfQVNTRVJUKHNlbGYtPm1hZ2ljID09IFRUUF9UU0FQX01BR0lDLCByZXR1cm47KTsKCgkvKiBEZWFsbG9jYXRlIGZyYW1lcyB3YWl0aW5nIHRvIGJlIHNlbnQgKi8KCXdoaWxlICgoc2tiID0gc2tiX2RlcXVldWUoJnNlbGYtPnR4X3F1ZXVlKSkgIT0gTlVMTCkKCQlkZXZfa2ZyZWVfc2tiKHNrYik7CgoJLyogRGVhbGxvY2F0ZSByZWNlaXZlZCBmcmFtZXMgKi8KCXdoaWxlICgoc2tiID0gc2tiX2RlcXVldWUoJnNlbGYtPnJ4X3F1ZXVlKSkgIT0gTlVMTCkKCQlkZXZfa2ZyZWVfc2tiKHNrYik7CgoJLyogRGVhbGxvY2F0ZSByZWNlaXZlZCBmcmFnbWVudHMgKi8KCXdoaWxlICgoc2tiID0gc2tiX2RlcXVldWUoJnNlbGYtPnJ4X2ZyYWdtZW50cykpICE9IE5VTEwpCgkJZGV2X2tmcmVlX3NrYihza2IpOwp9CgovKgogKiBGdW5jdGlvbiBpcnR0cF9yZWFzc2VtYmxlIChzZWxmKQogKgogKiAgICBNYWtlcyBhIG5ldyAoY29udGludW91cykgc2tiIG9mIGFsbCB0aGUgZnJhZ21lbnRzIGluIHRoZSBmcmFnbWVudAogKiAgICBxdWV1ZQogKgogKi8Kc3RhdGljIHN0cnVjdCBza19idWZmICppcnR0cF9yZWFzc2VtYmxlX3NrYihzdHJ1Y3QgdHNhcF9jYiAqc2VsZikKewoJc3RydWN0IHNrX2J1ZmYgKnNrYiwgKmZyYWc7CglpbnQgbiA9IDA7ICAvKiBGcmFnbWVudCBpbmRleCAqLwoKCUlSREFfQVNTRVJUKHNlbGYgIT0gTlVMTCwgcmV0dXJuIE5VTEw7KTsKCUlSREFfQVNTRVJUKHNlbGYtPm1hZ2ljID09IFRUUF9UU0FQX01BR0lDLCByZXR1cm4gTlVMTDspOwoKCUlSREFfREVCVUcoMiwgIiVzKCksIHNlbGYtPnJ4X3NkdV9zaXplPSVkXG4iLCBfX0ZVTkNUSU9OX18sCgkJICAgc2VsZi0+cnhfc2R1X3NpemUpOwoKCXNrYiA9IGRldl9hbGxvY19za2IoVFRQX0hFQURFUiArIHNlbGYtPnJ4X3NkdV9zaXplKTsKCWlmICghc2tiKQoJCXJldHVybiBOVUxMOwoKCS8qCgkgKiBOZWVkIHRvIHJlc2VydmUgc3BhY2UgZm9yIFRUUCBoZWFkZXIgaW4gY2FzZSB0aGlzIHNrYiBuZWVkcyB0bwoJICogYmUgcmVxdWV1ZWQgaW4gY2FzZSBkZWxpdmVyeSBmYWlsZXMKCSAqLwoJc2tiX3Jlc2VydmUoc2tiLCBUVFBfSEVBREVSKTsKCXNrYl9wdXQoc2tiLCBzZWxmLT5yeF9zZHVfc2l6ZSk7CgoJLyoKCSAqICBDb3B5IGFsbCBmcmFnbWVudHMgdG8gYSBuZXcgYnVmZmVyCgkgKi8KCXdoaWxlICgoZnJhZyA9IHNrYl9kZXF1ZXVlKCZzZWxmLT5yeF9mcmFnbWVudHMpKSAhPSBOVUxMKSB7CgkJbWVtY3B5KHNrYi0+ZGF0YStuLCBmcmFnLT5kYXRhLCBmcmFnLT5sZW4pOwoJCW4gKz0gZnJhZy0+bGVuOwoKCQlkZXZfa2ZyZWVfc2tiKGZyYWcpOwoJfQoKCUlSREFfREVCVUcoMiwKCQkgICAiJXMoKSwgZnJhbWUgbGVuPSVkLCByeF9zZHVfc2l6ZT0lZCwgcnhfbWF4X3NkdV9zaXplPSVkXG4iLAoJCSAgIF9fRlVOQ1RJT05fXywgbiwgc2VsZi0+cnhfc2R1X3NpemUsIHNlbGYtPnJ4X21heF9zZHVfc2l6ZSk7CgkvKiBOb3RlIDogaXJ0dHBfcnVuX3J4X3F1ZXVlKCkgY2FsY3VsYXRlIHNlbGYtPnJ4X3NkdV9zaXplCgkgKiBieSBzdW1taW5nIHRoZSBzaXplIG9mIGFsbCBmcmFnbWVudHMsIHNvIHdlIHNob3VsZCBhbHdheXMKCSAqIGhhdmUgbiA9PSBzZWxmLT5yeF9zZHVfc2l6ZSwgZXhjZXB0IGluIGNhc2VzIHdoZXJlIHdlCgkgKiBkcm9wZWQgdGhlIGxhc3QgZnJhZ21lbnQgKHdoZW4gc2VsZi0+cnhfc2R1X3NpemUgZXhjZWVkCgkgKiBzZWxmLT5yeF9tYXhfc2R1X3NpemUpLCB3aGVyZSBuIDwgc2VsZi0+cnhfc2R1X3NpemUuCgkgKiBKZWFuIElJICovCglJUkRBX0FTU0VSVChuIDw9IHNlbGYtPnJ4X3NkdV9zaXplLCBuID0gc2VsZi0+cnhfc2R1X3NpemU7KTsKCgkvKiBTZXQgdGhlIG5ldyBsZW5ndGggKi8KCXNrYl90cmltKHNrYiwgbik7CgoJc2VsZi0+cnhfc2R1X3NpemUgPSAwOwoKCXJldHVybiBza2I7Cn0KCi8qCiAqIEZ1bmN0aW9uIGlydHRwX2ZyYWdtZW50X3NrYiAoc2tiKQogKgogKiAgICBGcmFnbWVudHMgYSBmcmFtZSBhbmQgcXVldWVzIGFsbCB0aGUgZnJhZ21lbnRzIGZvciB0cmFuc21pc3Npb24KICoKICovCnN0YXRpYyBpbmxpbmUgdm9pZCBpcnR0cF9mcmFnbWVudF9za2Ioc3RydWN0IHRzYXBfY2IgKnNlbGYsCgkJCQkgICAgICBzdHJ1Y3Qgc2tfYnVmZiAqc2tiKQp7CglzdHJ1Y3Qgc2tfYnVmZiAqZnJhZzsKCV9fdTggKmZyYW1lOwoKCUlSREFfREVCVUcoMiwgIiVzKClcbiIsIF9fRlVOQ1RJT05fXyk7CgoJSVJEQV9BU1NFUlQoc2VsZiAhPSBOVUxMLCByZXR1cm47KTsKCUlSREFfQVNTRVJUKHNlbGYtPm1hZ2ljID09IFRUUF9UU0FQX01BR0lDLCByZXR1cm47KTsKCUlSREFfQVNTRVJUKHNrYiAhPSBOVUxMLCByZXR1cm47KTsKCgkvKgoJICogIFNwbGl0IGZyYW1lIGludG8gYSBudW1iZXIgb2Ygc2VnbWVudHMKCSAqLwoJd2hpbGUgKHNrYi0+bGVuID4gc2VsZi0+bWF4X3NlZ19zaXplKSB7CgkJSVJEQV9ERUJVRygyLCAiJXMoKSwgZnJhZ21lbnRpbmcgLi4uXG4iLCBfX0ZVTkNUSU9OX18pOwoKCQkvKiBNYWtlIG5ldyBzZWdtZW50ICovCgkJZnJhZyA9IGFsbG9jX3NrYihzZWxmLT5tYXhfc2VnX3NpemUrc2VsZi0+bWF4X2hlYWRlcl9zaXplLAoJCQkJIEdGUF9BVE9NSUMpOwoJCWlmICghZnJhZykKCQkJcmV0dXJuOwoKCQlza2JfcmVzZXJ2ZShmcmFnLCBzZWxmLT5tYXhfaGVhZGVyX3NpemUpOwoKCQkvKiBDb3B5IGRhdGEgZnJvbSB0aGUgb3JpZ2luYWwgc2tiIGludG8gdGhpcyBmcmFnbWVudC4gKi8KCQltZW1jcHkoc2tiX3B1dChmcmFnLCBzZWxmLT5tYXhfc2VnX3NpemUpLCBza2ItPmRhdGEsCgkJICAgICAgIHNlbGYtPm1heF9zZWdfc2l6ZSk7CgoJCS8qIEluc2VydCBUVFAgaGVhZGVyLCB3aXRoIHRoZSBtb3JlIGJpdCBzZXQgKi8KCQlmcmFtZSA9IHNrYl9wdXNoKGZyYWcsIFRUUF9IRUFERVIpOwoJCWZyYW1lWzBdID0gVFRQX01PUkU7CgoJCS8qIEhpZGUgdGhlIGNvcGllZCBkYXRhIGZyb20gdGhlIG9yaWdpbmFsIHNrYiAqLwoJCXNrYl9wdWxsKHNrYiwgc2VsZi0+bWF4X3NlZ19zaXplKTsKCgkJLyogUXVldWUgZnJhZ21lbnQgKi8KCQlza2JfcXVldWVfdGFpbCgmc2VsZi0+dHhfcXVldWUsIGZyYWcpOwoJfQoJLyogUXVldWUgd2hhdCBpcyBsZWZ0IG9mIHRoZSBvcmlnaW5hbCBza2IgKi8KCUlSREFfREVCVUcoMiwgIiVzKCksIHF1ZXVpbmcgbGFzdCBzZWdtZW50XG4iLCBfX0ZVTkNUSU9OX18pOwoKCWZyYW1lID0gc2tiX3B1c2goc2tiLCBUVFBfSEVBREVSKTsKCWZyYW1lWzBdID0gMHgwMDsgLyogQ2xlYXIgbW9yZSBiaXQgKi8KCgkvKiBRdWV1ZSBmcmFnbWVudCAqLwoJc2tiX3F1ZXVlX3RhaWwoJnNlbGYtPnR4X3F1ZXVlLCBza2IpOwp9CgovKgogKiBGdW5jdGlvbiBpcnR0cF9wYXJhbV9tYXhfc2R1X3NpemUgKHNlbGYsIHBhcmFtKQogKgogKiAgICBIYW5kbGUgdGhlIE1heFNkdVNpemUgcGFyYW1ldGVyIGluIHRoZSBjb25uZWN0IGZyYW1lcywgdGhpcyBmdW5jdGlvbgogKiAgICB3aWxsIGJlIGNhbGxlZCBib3RoIHdoZW4gdGhpcyBwYXJhbWV0ZXIgbmVlZHMgdG8gYmUgaW5zZXJ0ZWQgaW50bywgYW5kCiAqICAgIGV4dHJhY3RlZCBmcm9tIHRoZSBjb25uZWN0IGZyYW1lcwogKi8Kc3RhdGljIGludCBpcnR0cF9wYXJhbV9tYXhfc2R1X3NpemUodm9pZCAqaW5zdGFuY2UsIGlyZGFfcGFyYW1fdCAqcGFyYW0sCgkJCQkgICAgaW50IGdldCkKewoJc3RydWN0IHRzYXBfY2IgKnNlbGY7CgoJc2VsZiA9IChzdHJ1Y3QgdHNhcF9jYiAqKSBpbnN0YW5jZTsKCglJUkRBX0FTU0VSVChzZWxmICE9IE5VTEwsIHJldHVybiAtMTspOwoJSVJEQV9BU1NFUlQoc2VsZi0+bWFnaWMgPT0gVFRQX1RTQVBfTUFHSUMsIHJldHVybiAtMTspOwoKCWlmIChnZXQpCgkJcGFyYW0tPnB2LmkgPSBzZWxmLT50eF9tYXhfc2R1X3NpemU7CgllbHNlCgkJc2VsZi0+dHhfbWF4X3NkdV9zaXplID0gcGFyYW0tPnB2Lmk7CgoJSVJEQV9ERUJVRygxLCAiJXMoKSwgTWF4U2R1U2l6ZT0lZFxuIiwgX19GVU5DVElPTl9fLCBwYXJhbS0+cHYuaSk7CgoJcmV0dXJuIDA7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKiogQ0xJRU5UIENBTExTICoqKioqKioqKioqKioqKioqKioqKioqKioqKi8KLyoqKioqKioqKioqKioqKioqKioqKioqKioqIExNUCBDQUxMQkFDS1MgKioqKioqKioqKioqKioqKioqKioqKioqKiovCi8qIEV2ZXJ5dGhpbmcgaXMgaGFwcGlseSBtaXhlZCB1cC4gV2FpdGluZyBmb3IgbmV4dCBjbGVhbiB1cCAtIEplYW4gSUkgKi8KCi8qCiAqIEZ1bmN0aW9uIGlydHRwX29wZW5fdHNhcCAoc3RzYXAsIG5vdGlmeSkKICoKICogICAgQ3JlYXRlIFRTQVAgY29ubmVjdGlvbiBlbmRwb2ludCwKICovCnN0cnVjdCB0c2FwX2NiICppcnR0cF9vcGVuX3RzYXAoX191OCBzdHNhcF9zZWwsIGludCBjcmVkaXQsIG5vdGlmeV90ICpub3RpZnkpCnsKCXN0cnVjdCB0c2FwX2NiICpzZWxmOwoJc3RydWN0IGxzYXBfY2IgKmxzYXA7Cglub3RpZnlfdCB0dHBfbm90aWZ5OwoKCUlSREFfQVNTRVJUKGlydHRwLT5tYWdpYyA9PSBUVFBfTUFHSUMsIHJldHVybiBOVUxMOyk7CgoJLyogVGhlIElyTE1QIHNwZWMgKElyTE1QIDEuMSBwMTApIHNheXMgdGhhdCB3ZSBoYXZlIHRoZSByaWdodCB0bwoJICogdXNlIG9ubHkgMHgwMS0weDZGLiBPZiBjb3Vyc2UsIHdlIGNhbiB1c2UgTFNBUF9BTlkgYXMgd2VsbC4KCSAqIEplYW5JSSAqLwoJaWYoKHN0c2FwX3NlbCAhPSBMU0FQX0FOWSkgJiYKCSAgICgoc3RzYXBfc2VsIDwgMHgwMSkgfHwgKHN0c2FwX3NlbCA+PSAweDcwKSkpIHsKCQlJUkRBX0RFQlVHKDAsICIlcygpLCBpbnZhbGlkIHRzYXAhXG4iLCBfX0ZVTkNUSU9OX18pOwoJCXJldHVybiBOVUxMOwoJfQoKCXNlbGYgPSBrbWFsbG9jKHNpemVvZihzdHJ1Y3QgdHNhcF9jYiksIEdGUF9BVE9NSUMpOwoJaWYgKHNlbGYgPT0gTlVMTCkgewoJCUlSREFfREVCVUcoMCwgIiVzKCksIHVuYWJsZSB0byBrbWFsbG9jIVxuIiwgX19GVU5DVElPTl9fKTsKCQlyZXR1cm4gTlVMTDsKCX0KCW1lbXNldChzZWxmLCAwLCBzaXplb2Yoc3RydWN0IHRzYXBfY2IpKTsKCXNwaW5fbG9ja19pbml0KCZzZWxmLT5sb2NrKTsKCgkvKiBJbml0aWFsaXNlIHRvZG8gdGltZXIgKi8KCWluaXRfdGltZXIoJnNlbGYtPnRvZG9fdGltZXIpOwoJc2VsZi0+dG9kb190aW1lci5kYXRhICAgICA9ICh1bnNpZ25lZCBsb25nKSBzZWxmOwoJc2VsZi0+dG9kb190aW1lci5mdW5jdGlvbiA9ICZpcnR0cF90b2RvX2V4cGlyZWQ7CgoJLyogSW5pdGlhbGl6ZSBjYWxsYmFja3MgZm9yIElyTE1QIHRvIHVzZSAqLwoJaXJkYV9ub3RpZnlfaW5pdCgmdHRwX25vdGlmeSk7Cgl0dHBfbm90aWZ5LmNvbm5lY3RfY29uZmlybSA9IGlydHRwX2Nvbm5lY3RfY29uZmlybTsKCXR0cF9ub3RpZnkuY29ubmVjdF9pbmRpY2F0aW9uID0gaXJ0dHBfY29ubmVjdF9pbmRpY2F0aW9uOwoJdHRwX25vdGlmeS5kaXNjb25uZWN0X2luZGljYXRpb24gPSBpcnR0cF9kaXNjb25uZWN0X2luZGljYXRpb247Cgl0dHBfbm90aWZ5LmRhdGFfaW5kaWNhdGlvbiA9IGlydHRwX2RhdGFfaW5kaWNhdGlvbjsKCXR0cF9ub3RpZnkudWRhdGFfaW5kaWNhdGlvbiA9IGlydHRwX3VkYXRhX2luZGljYXRpb247Cgl0dHBfbm90aWZ5LmZsb3dfaW5kaWNhdGlvbiA9IGlydHRwX2Zsb3dfaW5kaWNhdGlvbjsKCWlmKG5vdGlmeS0+c3RhdHVzX2luZGljYXRpb24gIT0gTlVMTCkKCQl0dHBfbm90aWZ5LnN0YXR1c19pbmRpY2F0aW9uID0gaXJ0dHBfc3RhdHVzX2luZGljYXRpb247Cgl0dHBfbm90aWZ5Lmluc3RhbmNlID0gc2VsZjsKCXN0cm5jcHkodHRwX25vdGlmeS5uYW1lLCBub3RpZnktPm5hbWUsIE5PVElGWV9NQVhfTkFNRSk7CgoJc2VsZi0+bWFnaWMgPSBUVFBfVFNBUF9NQUdJQzsKCXNlbGYtPmNvbm5lY3RlZCA9IEZBTFNFOwoKCXNrYl9xdWV1ZV9oZWFkX2luaXQoJnNlbGYtPnJ4X3F1ZXVlKTsKCXNrYl9xdWV1ZV9oZWFkX2luaXQoJnNlbGYtPnR4X3F1ZXVlKTsKCXNrYl9xdWV1ZV9oZWFkX2luaXQoJnNlbGYtPnJ4X2ZyYWdtZW50cyk7CgkvKgoJICogIENyZWF0ZSBMU0FQIGF0IElyTE1QIGxheWVyCgkgKi8KCWxzYXAgPSBpcmxtcF9vcGVuX2xzYXAoc3RzYXBfc2VsLCAmdHRwX25vdGlmeSwgMCk7CglpZiAobHNhcCA9PSBOVUxMKSB7CgkJSVJEQV9XQVJOSU5HKCIlczogdW5hYmxlIHRvIGFsbG9jYXRlIExTQVAhIVxuIiwgX19GVU5DVElPTl9fKTsKCQlyZXR1cm4gTlVMTDsKCX0KCgkvKgoJICogIElmIHVzZXIgc3BlY2lmaWVkIExTQVBfQU5ZIGFzIHNvdXJjZSBUU0FQIHNlbGVjdG9yLCB0aGVuIElyTE1QCgkgKiAgd2lsbCByZXBsYWNlIGl0IHdpdGggd2hhdGV2ZXIgc291cmNlIHNlbGVjdG9yIHdoaWNoIGlzIGZyZWUsIHNvCgkgKiAgdGhlIHN0c2FwX3NlbCB3ZSBoYXZlIG1pZ2h0IG5vdCBiZSB2YWxpZCBhbnltb3JlCgkgKi8KCXNlbGYtPnN0c2FwX3NlbCA9IGxzYXAtPnNsc2FwX3NlbDsKCUlSREFfREVCVUcoNCwgIiVzKCksIHN0c2FwX3NlbD0lMDJ4XG4iLCBfX0ZVTkNUSU9OX18sIHNlbGYtPnN0c2FwX3NlbCk7CgoJc2VsZi0+bm90aWZ5ID0gKm5vdGlmeTsKCXNlbGYtPmxzYXAgPSBsc2FwOwoKCWhhc2hiaW5faW5zZXJ0KGlydHRwLT50c2FwcywgKGlyZGFfcXVldWVfdCAqKSBzZWxmLCAobG9uZykgc2VsZiwgTlVMTCk7CgoJaWYgKGNyZWRpdCA+IFRUUF9SWF9NQVhfQ1JFRElUKQoJCXNlbGYtPmluaXRpYWxfY3JlZGl0ID0gVFRQX1JYX01BWF9DUkVESVQ7CgllbHNlCgkJc2VsZi0+aW5pdGlhbF9jcmVkaXQgPSBjcmVkaXQ7CgoJcmV0dXJuIHNlbGY7Cn0KRVhQT1JUX1NZTUJPTChpcnR0cF9vcGVuX3RzYXApOwoKLyoKICogRnVuY3Rpb24gaXJ0dHBfY2xvc2UgKGhhbmRsZSkKICoKICogICAgUmVtb3ZlIGFuIGluc3RhbmNlIG9mIGEgVFNBUC4gVGhpcyBmdW5jdGlvbiBzaG91bGQgb25seSBkZWFsIHdpdGggdGhlCiAqICAgIGRlYWxsb2NhdGlvbiBvZiB0aGUgVFNBUCwgYW5kIHJlc2V0dGluZyBvZiB0aGUgVFNBUHMgdmFsdWVzOwogKgogKi8Kc3RhdGljIHZvaWQgX19pcnR0cF9jbG9zZV90c2FwKHN0cnVjdCB0c2FwX2NiICpzZWxmKQp7CgkvKiBGaXJzdCBtYWtlIHN1cmUgd2UncmUgY29ubmVjdGVkLiAqLwoJSVJEQV9BU1NFUlQoc2VsZiAhPSBOVUxMLCByZXR1cm47KTsKCUlSREFfQVNTRVJUKHNlbGYtPm1hZ2ljID09IFRUUF9UU0FQX01BR0lDLCByZXR1cm47KTsKCglpcnR0cF9mbHVzaF9xdWV1ZXMoc2VsZik7CgoJZGVsX3RpbWVyKCZzZWxmLT50b2RvX3RpbWVyKTsKCgkvKiBUaGlzIG9uZSB3b24ndCBiZSBjbGVhbmVkIHVwIGlmIHdlIGFyZSBkaXNjb25uZWN0X3BlbmQgKyBjbG9zZV9wZW5kCgkgKiBhbmQgd2UgcmVjZWl2ZSBhIGRpc2Nvbm5lY3RfaW5kaWNhdGlvbiAqLwoJaWYgKHNlbGYtPmRpc2Nvbm5lY3Rfc2tiKQoJCWRldl9rZnJlZV9za2Ioc2VsZi0+ZGlzY29ubmVjdF9za2IpOwoKCXNlbGYtPmNvbm5lY3RlZCA9IEZBTFNFOwoJc2VsZi0+bWFnaWMgPSB+VFRQX1RTQVBfTUFHSUM7CgoJa2ZyZWUoc2VsZik7Cn0KCi8qCiAqIEZ1bmN0aW9uIGlydHRwX2Nsb3NlIChzZWxmKQogKgogKiAgICBSZW1vdmUgVFNBUCBmcm9tIGxpc3Qgb2YgYWxsIFRTQVBzIGFuZCB0aGVuIGRlYWxsb2NhdGUgYWxsIHJlc291cmNlcwogKiAgICBhc3NvY2lhdGVkIHdpdGggdGhpcyBUU0FQCiAqCiAqIE5vdGUgOiBiZWNhdXNlIHdlICpmcmVlKiB0aGUgdHNhcCBzdHJ1Y3R1cmUsIGl0IGlzIHRoZSByZXNwb25zaWJpbGl0eQogKiBvZiB0aGUgY2FsbGVyIHRvIG1ha2Ugc3VyZSB3ZSBhcmUgY2FsbGVkIG9ubHkgb25jZSBhbmQgdG8gZGVhbCB3aXRoCiAqIHBvc3NpYmxlIHJhY2UgY29uZGl0aW9ucy4gLSBKZWFuIElJCiAqLwppbnQgaXJ0dHBfY2xvc2VfdHNhcChzdHJ1Y3QgdHNhcF9jYiAqc2VsZikKewoJc3RydWN0IHRzYXBfY2IgKnRzYXA7CgoJSVJEQV9ERUJVRyg0LCAiJXMoKVxuIiwgX19GVU5DVElPTl9fKTsKCglJUkRBX0FTU0VSVChzZWxmICE9IE5VTEwsIHJldHVybiAtMTspOwoJSVJEQV9BU1NFUlQoc2VsZi0+bWFnaWMgPT0gVFRQX1RTQVBfTUFHSUMsIHJldHVybiAtMTspOwoKCS8qIE1ha2Ugc3VyZSB0c2FwIGhhcyBiZWVuIGRpc2Nvbm5lY3RlZCAqLwoJaWYgKHNlbGYtPmNvbm5lY3RlZCkgewoJCS8qIENoZWNrIGlmIGRpc2Nvbm5lY3QgaXMgbm90IHBlbmRpbmcgKi8KCQlpZiAoIXRlc3RfYml0KDAsICZzZWxmLT5kaXNjb25uZWN0X3BlbmQpKSB7CgkJCUlSREFfV0FSTklORygiJXM6IFRTQVAgc3RpbGwgY29ubmVjdGVkIVxuIiwKCQkJCSAgICAgX19GVU5DVElPTl9fKTsKCQkJaXJ0dHBfZGlzY29ubmVjdF9yZXF1ZXN0KHNlbGYsIE5VTEwsIFBfTk9STUFMKTsKCQl9CgkJc2VsZi0+Y2xvc2VfcGVuZCA9IFRSVUU7CgkJaXJ0dHBfc3RhcnRfdG9kb190aW1lcihzZWxmLCBIWi8xMCk7CgoJCXJldHVybiAwOyAvKiBXaWxsIGJlIGJhY2shICovCgl9CgoJdHNhcCA9IGhhc2hiaW5fcmVtb3ZlKGlydHRwLT50c2FwcywgKGxvbmcpIHNlbGYsIE5VTEwpOwoKCUlSREFfQVNTRVJUKHRzYXAgPT0gc2VsZiwgcmV0dXJuIC0xOyk7CgoJLyogQ2xvc2UgY29ycmVzcG9uZGluZyBMU0FQICovCglpZiAoc2VsZi0+bHNhcCkgewoJCWlybG1wX2Nsb3NlX2xzYXAoc2VsZi0+bHNhcCk7CgkJc2VsZi0+bHNhcCA9IE5VTEw7Cgl9CgoJX19pcnR0cF9jbG9zZV90c2FwKHNlbGYpOwoKCXJldHVybiAwOwp9CkVYUE9SVF9TWU1CT0woaXJ0dHBfY2xvc2VfdHNhcCk7CgovKgogKiBGdW5jdGlvbiBpcnR0cF91ZGF0YV9yZXF1ZXN0IChzZWxmLCBza2IpCiAqCiAqICAgIFNlbmQgdW5yZWxpYWJsZSBkYXRhIG9uIHRoaXMgVFNBUAogKgogKi8KaW50IGlydHRwX3VkYXRhX3JlcXVlc3Qoc3RydWN0IHRzYXBfY2IgKnNlbGYsIHN0cnVjdCBza19idWZmICpza2IpCnsKCUlSREFfQVNTRVJUKHNlbGYgIT0gTlVMTCwgcmV0dXJuIC0xOyk7CglJUkRBX0FTU0VSVChzZWxmLT5tYWdpYyA9PSBUVFBfVFNBUF9NQUdJQywgcmV0dXJuIC0xOyk7CglJUkRBX0FTU0VSVChza2IgIT0gTlVMTCwgcmV0dXJuIC0xOyk7CgoJSVJEQV9ERUJVRyg0LCAiJXMoKVxuIiwgX19GVU5DVElPTl9fKTsKCgkvKiBDaGVjayB0aGF0IG5vdGhpbmcgYmFkIGhhcHBlbnMgKi8KCWlmICgoc2tiLT5sZW4gPT0gMCkgfHwgKCFzZWxmLT5jb25uZWN0ZWQpKSB7CgkJSVJEQV9ERUJVRygxLCAiJXMoKSwgTm8gZGF0YSwgb3Igbm90IGNvbm5lY3RlZFxuIiwKCQkJICAgX19GVU5DVElPTl9fKTsKCQlnb3RvIGVycjsKCX0KCglpZiAoc2tiLT5sZW4gPiBzZWxmLT5tYXhfc2VnX3NpemUpIHsKCQlJUkRBX0RFQlVHKDEsICIlcygpLCBVRGF0YSBpcyB0byBsYXJnZSBmb3IgSXJMQVAhXG4iLAoJCQkgICBfX0ZVTkNUSU9OX18pOwoJCWdvdG8gZXJyOwoJfQoKCWlybG1wX3VkYXRhX3JlcXVlc3Qoc2VsZi0+bHNhcCwgc2tiKTsKCXNlbGYtPnN0YXRzLnR4X3BhY2tldHMrKzsKCglyZXR1cm4gMDsKCmVycjoKCWRldl9rZnJlZV9za2Ioc2tiKTsKCXJldHVybiAtMTsKfQpFWFBPUlRfU1lNQk9MKGlydHRwX3VkYXRhX3JlcXVlc3QpOwoKCi8qCiAqIEZ1bmN0aW9uIGlydHRwX2RhdGFfcmVxdWVzdCAoaGFuZGxlLCBza2IpCiAqCiAqICAgIFF1ZXVlIGZyYW1lIGZvciB0cmFuc21pc3Npb24uIElmIFNBUiBpcyBlbmFibGVkLCBmcmFnZW1lbnQgdGhlIGZyYW1lCiAqICAgIGFuZCBxdWV1ZSB0aGUgZnJhZ21lbnRzIGZvciB0cmFuc21pc3Npb24KICovCmludCBpcnR0cF9kYXRhX3JlcXVlc3Qoc3RydWN0IHRzYXBfY2IgKnNlbGYsIHN0cnVjdCBza19idWZmICpza2IpCnsKCV9fdTggKmZyYW1lOwoJaW50IHJldDsKCglJUkRBX0FTU0VSVChzZWxmICE9IE5VTEwsIHJldHVybiAtMTspOwoJSVJEQV9BU1NFUlQoc2VsZi0+bWFnaWMgPT0gVFRQX1RTQVBfTUFHSUMsIHJldHVybiAtMTspOwoJSVJEQV9BU1NFUlQoc2tiICE9IE5VTEwsIHJldHVybiAtMTspOwoKCUlSREFfREVCVUcoMiwgIiVzKCkgOiBxdWV1ZSBsZW4gPSAlZFxuIiwgX19GVU5DVElPTl9fLAoJCSAgIHNrYl9xdWV1ZV9sZW4oJnNlbGYtPnR4X3F1ZXVlKSk7CgoJLyogQ2hlY2sgdGhhdCBub3RoaW5nIGJhZCBoYXBwZW5zICovCglpZiAoKHNrYi0+bGVuID09IDApIHx8ICghc2VsZi0+Y29ubmVjdGVkKSkgewoJCUlSREFfV0FSTklORygiJXM6IE5vIGRhdGEsIG9yIG5vdCBjb25uZWN0ZWRcbiIsIF9fRlVOQ1RJT05fXyk7CgkJcmV0ID0gLUVOT1RDT05OOwoJCWdvdG8gZXJyOwoJfQoKCS8qCgkgKiAgQ2hlY2sgaWYgU0FSIGlzIGRpc2FibGVkLCBhbmQgdGhlIGZyYW1lIGlzIGxhcmdlciB0aGFuIHdoYXQgZml0cwoJICogIGluc2lkZSBhbiBJckxBUCBmcmFtZQoJICovCglpZiAoKHNlbGYtPnR4X21heF9zZHVfc2l6ZSA9PSAwKSAmJiAoc2tiLT5sZW4gPiBzZWxmLT5tYXhfc2VnX3NpemUpKSB7CgkJSVJEQV9FUlJPUigiJXM6IFNBUiBkaXNhYmxlZCwgYW5kIGRhdGEgaXMgdG8gbGFyZ2UgZm9yIElyTEFQIVxuIiwKCQkJICAgX19GVU5DVElPTl9fKTsKCQlyZXQgPSAtRU1TR1NJWkU7CgkJZ290byBlcnI7Cgl9CgoJLyoKCSAqICBDaGVjayBpZiBTQVIgaXMgZW5hYmxlZCwgYW5kIHRoZSBmcmFtZSBpcyBsYXJnZXIgdGhhbiB0aGUKCSAqICBUeE1heFNkdVNpemUKCSAqLwoJaWYgKChzZWxmLT50eF9tYXhfc2R1X3NpemUgIT0gMCkgJiYKCSAgICAoc2VsZi0+dHhfbWF4X3NkdV9zaXplICE9IFRUUF9TQVJfVU5CT1VORCkgJiYKCSAgICAoc2tiLT5sZW4gPiBzZWxmLT50eF9tYXhfc2R1X3NpemUpKQoJewoJCUlSREFfRVJST1IoIiVzOiBTQVIgZW5hYmxlZCwgYnV0IGRhdGEgaXMgbGFyZ2VyIHRoYW4gVHhNYXhTZHVTaXplIVxuIiwKCQkJICAgX19GVU5DVElPTl9fKTsKCQlyZXQgPSAtRU1TR1NJWkU7CgkJZ290byBlcnI7Cgl9CgkvKgoJICogIENoZWNrIGlmIHRyYW5zbWl0IHF1ZXVlIGlzIGZ1bGwKCSAqLwoJaWYgKHNrYl9xdWV1ZV9sZW4oJnNlbGYtPnR4X3F1ZXVlKSA+PSBUVFBfVFhfTUFYX1FVRVVFKSB7CgkJLyoKCQkgKiAgR2l2ZSBpdCBhIGNoYW5jZSB0byBlbXB0eSBpdHNlbGYKCQkgKi8KCQlpcnR0cF9ydW5fdHhfcXVldWUoc2VsZik7CgoJCS8qIERyb3AgcGFja2V0LiBUaGlzIGVycm9yIGNvZGUgc2hvdWxkIHRyaWdnZXIgdGhlIGNhbGxlcgoJCSAqIHRvIHJlc2VuZCB0aGUgZGF0YSBpbiB0aGUgY2xpZW50IGNvZGUgLSBKZWFuIElJICovCgkJcmV0ID0gLUVOT0JVRlM7CgkJZ290byBlcnI7Cgl9CgoJLyogUXVldWUgZnJhbWUsIG9yIHF1ZXVlIGZyYW1lIHNlZ21lbnRzICovCglpZiAoKHNlbGYtPnR4X21heF9zZHVfc2l6ZSA9PSAwKSB8fCAoc2tiLT5sZW4gPCBzZWxmLT5tYXhfc2VnX3NpemUpKSB7CgkJLyogUXVldWUgZnJhbWUgKi8KCQlJUkRBX0FTU0VSVChza2JfaGVhZHJvb20oc2tiKSA+PSBUVFBfSEVBREVSLCByZXR1cm4gLTE7KTsKCQlmcmFtZSA9IHNrYl9wdXNoKHNrYiwgVFRQX0hFQURFUik7CgkJZnJhbWVbMF0gPSAweDAwOyAvKiBDbGVhciBtb3JlIGJpdCAqLwoKCQlza2JfcXVldWVfdGFpbCgmc2VsZi0+dHhfcXVldWUsIHNrYik7Cgl9IGVsc2UgewoJCS8qCgkJICogIEZyYWdtZW50IHRoZSBmcmFtZSwgdGhpcyBmdW5jdGlvbiB3aWxsIGFsc28gcXVldWUgdGhlCgkJICogIGZyYWdtZW50cywgd2UgZG9uJ3QgY2FyZSBhYm91dCB0aGUgZmFjdCB0aGUgdHJhbnNtaXQKCQkgKiAgcXVldWUgbWF5IGJlIG92ZXJmaWxsZWQgYnkgYWxsIHRoZSBzZWdtZW50cyBmb3IgYSBsaXR0bGUKCQkgKiAgd2hpbGUKCQkgKi8KCQlpcnR0cF9mcmFnbWVudF9za2Ioc2VsZiwgc2tiKTsKCX0KCgkvKiBDaGVjayBpZiB3ZSBjYW4gYWNjZXB0IG1vcmUgZGF0YSBmcm9tIGNsaWVudCAqLwoJaWYgKCghc2VsZi0+dHhfc2R1X2J1c3kpICYmCgkgICAgKHNrYl9xdWV1ZV9sZW4oJnNlbGYtPnR4X3F1ZXVlKSA+IFRUUF9UWF9ISUdIX1RIUkVTSE9MRCkpIHsKCQkvKiBUeCBxdWV1ZSBmaWxsaW5nIHVwLCBzbyBzdG9wIGNsaWVudC4gKi8KCQlpZiAoc2VsZi0+bm90aWZ5LmZsb3dfaW5kaWNhdGlvbikgewoJCQlzZWxmLT5ub3RpZnkuZmxvd19pbmRpY2F0aW9uKHNlbGYtPm5vdGlmeS5pbnN0YW5jZSwKCQkJCQkJICAgICBzZWxmLCBGTE9XX1NUT1ApOwoJCX0KCQkvKiBzZWxmLT50eF9zZHVfYnVzeSBpcyB0aGUgc3RhdGUgb2YgdGhlIGNsaWVudC4KCQkgKiBVcGRhdGUgc3RhdGUgYWZ0ZXIgbm90aWZ5aW5nIGNsaWVudCB0byBhdm9pZAoJCSAqIHJhY2UgY29uZGl0aW9uIHdpdGggaXJ0dHBfZmxvd19pbmRpY2F0aW9uKCkuCgkJICogSWYgdGhlIHF1ZXVlIGVtcHR5IGl0c2VsZiBhZnRlciBvdXIgdGVzdCBidXQgYmVmb3JlCgkJICogd2Ugc2V0IHRoZSBmbGFnLCB3ZSB3aWxsIGZpeCBvdXJzZWx2ZXMgYmVsb3cgaW4KCQkgKiBpcnR0cF9ydW5fdHhfcXVldWUoKS4KCQkgKiBKZWFuIElJICovCgkJc2VsZi0+dHhfc2R1X2J1c3kgPSBUUlVFOwoJfQoKCS8qIFRyeSB0byBtYWtlIHNvbWUgcHJvZ3Jlc3MgKi8KCWlydHRwX3J1bl90eF9xdWV1ZShzZWxmKTsKCglyZXR1cm4gMDsKCmVycjoKCWRldl9rZnJlZV9za2Ioc2tiKTsKCXJldHVybiByZXQ7Cn0KRVhQT1JUX1NZTUJPTChpcnR0cF9kYXRhX3JlcXVlc3QpOwoKLyoKICogRnVuY3Rpb24gaXJ0dHBfcnVuX3R4X3F1ZXVlIChzZWxmKQogKgogKiAgICBUcmFuc21pdCBwYWNrZXRzIHF1ZXVlZCBmb3IgdHJhbnNtaXNzaW9uIChpZiBwb3NzaWJsZSkKICoKICovCnN0YXRpYyB2b2lkIGlydHRwX3J1bl90eF9xdWV1ZShzdHJ1Y3QgdHNhcF9jYiAqc2VsZikKewoJc3RydWN0IHNrX2J1ZmYgKnNrYjsKCXVuc2lnbmVkIGxvbmcgZmxhZ3M7CglpbnQgbjsKCglJUkRBX0RFQlVHKDIsICIlcygpIDogc2VuZF9jcmVkaXQgPSAlZCwgcXVldWVfbGVuID0gJWRcbiIsCgkJICAgX19GVU5DVElPTl9fLAoJCSAgIHNlbGYtPnNlbmRfY3JlZGl0LCBza2JfcXVldWVfbGVuKCZzZWxmLT50eF9xdWV1ZSkpOwoKCS8qIEdldCBleGNsdXNpdmUgYWNjZXNzIHRvIHRoZSB0eCBxdWV1ZSwgb3RoZXJ3aXNlIGRvbid0IHRvdWNoIGl0ICovCglpZiAoaXJkYV9sb2NrKCZzZWxmLT50eF9xdWV1ZV9sb2NrKSA9PSBGQUxTRSkKCQlyZXR1cm47CgoJLyogVHJ5IHRvIHNlbmQgb3V0IGZyYW1lcyBhcyBsb25nIGFzIHdlIGhhdmUgY3JlZGl0cwoJICogYW5kIGFzIGxvbmcgYXMgTEFQIGlzIG5vdCBmdWxsLiBJZiBMQVAgaXMgZnVsbCwgaXQgd2lsbAoJICogcG9sbCB1cyB0aHJvdWdoIGlydHRwX2Zsb3dfaW5kaWNhdGlvbigpIC0gSmVhbiBJSSAqLwoJd2hpbGUgKChzZWxmLT5zZW5kX2NyZWRpdCA+IDApICYmCgkgICAgICAgKCFpcmxtcF9sYXBfdHhfcXVldWVfZnVsbChzZWxmLT5sc2FwKSkgJiYKCSAgICAgICAoc2tiID0gc2tiX2RlcXVldWUoJnNlbGYtPnR4X3F1ZXVlKSkpCgl7CgkJLyoKCQkgKiAgU2luY2Ugd2UgY2FuIHRyYW5zbWl0IGFuZCByZWNlaXZlIGZyYW1lcyBjb25jdXJyZW50bHksCgkJICogIHRoZSBjb2RlIGJlbG93IGlzIGEgY3JpdGljYWwgcmVnaW9uIGFuZCB3ZSBtdXN0IGFzc3VyZSB0aGF0CgkJICogIG5vYm9keSBtZXNzZXMgd2l0aCB0aGUgY3JlZGl0cyB3aGlsZSB3ZSB1cGRhdGUgdGhlbS4KCQkgKi8KCQlzcGluX2xvY2tfaXJxc2F2ZSgmc2VsZi0+bG9jaywgZmxhZ3MpOwoKCQluID0gc2VsZi0+YXZhaWxfY3JlZGl0OwoJCXNlbGYtPmF2YWlsX2NyZWRpdCA9IDA7CgoJCS8qIE9ubHkgcm9vbSBmb3IgMTI3IGNyZWRpdHMgaW4gZnJhbWUgKi8KCQlpZiAobiA+IDEyNykgewoJCQlzZWxmLT5hdmFpbF9jcmVkaXQgPSBuLTEyNzsKCQkJbiA9IDEyNzsKCQl9CgkJc2VsZi0+cmVtb3RlX2NyZWRpdCArPSBuOwoJCXNlbGYtPnNlbmRfY3JlZGl0LS07CgoJCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJnNlbGYtPmxvY2ssIGZsYWdzKTsKCgkJLyoKCQkgKiAgTW9yZSBiaXQgbXVzdCBiZSBzZXQgYnkgdGhlIGRhdGFfcmVxdWVzdCgpIG9yIGZyYWdtZW50KCkKCQkgKiAgZnVuY3Rpb25zCgkJICovCgkJc2tiLT5kYXRhWzBdIHw9IChuICYgMHg3Zik7CgoJCS8qIERldGFjaCBmcm9tIHNvY2tldC4KCQkgKiBUaGUgY3VycmVudCBza2IgaGFzIGEgcmVmZXJlbmNlIHRvIHRoZSBzb2NrZXQgdGhhdCBzZW50CgkJICogaXQgKHNrYi0+c2spLiBXaGVuIHdlIHBhc3MgaXQgdG8gSXJMTVAsIHRoZSBza2Igd2lsbCBiZQoJCSAqIHN0b3JlZCBpbiBpbiBJckxBUCAoc2VsZi0+d3hfbGlzdCkuIFdoZW4gd2UgYXJlIHdpdGhpbgoJCSAqIElyTEFQLCB3ZSBsb3NlIHRoZSBub3Rpb24gb2Ygc29ja2V0LCBzbyB3ZSBzaG91bGQgbm90CgkJICogaGF2ZSBhIHJlZmVyZW5jZSB0byBhIHNvY2tldC4gU28sIHdlIGRyb3AgaXQgaGVyZS4KCQkgKgoJCSAqIFdoeSBkb2VzIGl0IG1hdHRlciA/CgkJICogV2hlbiB0aGUgc2tiIGlzIGZyZWVkIChrZnJlZV9za2IpLCBpZiBpdCBpcyBhc3NvY2lhdGVkCgkJICogd2l0aCBhIHNvY2tldCwgaXQgcmVsZWFzZSBidWZmZXIgc3BhY2Ugb24gdGhlIHNvY2tldAoJCSAqICh0aHJvdWdoIHNvY2tfd2ZyZWUoKSBhbmQgc29ja19kZWZfd3JpdGVfc3BhY2UoKSkuCgkJICogSWYgdGhlIHNvY2tldCBubyBsb25nZXIgZXhpc3QsIHdlIG1heSBjcmFzaC4gSGFyZC4KCQkgKiBXaGVuIHdlIGNsb3NlIGEgc29ja2V0LCB3ZSBtYWtlIHN1cmUgdGhhdCBhc3NvY2lhdGVkIHBhY2tldHMKCQkgKiBpbiBJclRUUCBhcmUgZnJlZWQuIEhvd2V2ZXIsIHdlIGhhdmUgbm8gd2F5IHRvIGNhbmNlbAoJCSAqIHRoZSBwYWNrZXQgdGhhdCB3ZSBoYXZlIHBhc3NlZCB0byBJckxBUC4gU28sIGlmIGEgcGFja2V0CgkJICogcmVtYWlucyBpbiBJckxBUCAocmV0cnkgb24gdGhlIGxpbmsgb3IgZWxzZSkgYWZ0ZXIgd2UKCQkgKiBjbG9zZSB0aGUgc29ja2V0LCB3ZSBhcmUgZGVhZCAhCgkJICogSmVhbiBJSSAqLwoJCWlmIChza2ItPnNrICE9IE5VTEwpIHsKCQkJLyogSXJTT0NLIGFwcGxpY2F0aW9uLCBJck9CRVgsIC4uLiAqLwoJCQlza2Jfb3JwaGFuKHNrYik7CgkJfQoJCQkvKiBJckNPTU0gb3ZlciBJclRUUCwgSXJMQU4sIC4uLiAqLwoKCQkvKiBQYXNzIHRoZSBza2IgdG8gSXJMTVAgLSBkb25lICovCgkJaXJsbXBfZGF0YV9yZXF1ZXN0KHNlbGYtPmxzYXAsIHNrYik7CgkJc2VsZi0+c3RhdHMudHhfcGFja2V0cysrOwoJfQoKCS8qIENoZWNrIGlmIHdlIGNhbiBhY2NlcHQgbW9yZSBmcmFtZXMgZnJvbSBjbGllbnQuCgkgKiBXZSBkb24ndCB3YW50IHRvIHdhaXQgdW50aWwgdGhlIHRvZG8gdGltZXIgdG8gZG8gdGhhdCwgYW5kIHdlCgkgKiBjYW4ndCB1c2UgdGFza2xldHMgKGdyci4uLiksIHNvIHdlIGFyZSBvYmxpZ2VkIHRvIGdpdmUgY29udHJvbAoJICogdG8gY2xpZW50LiBUaGF0J3Mgb2ssIHRoaXMgdGVzdCB3aWxsIGJlIHRydWUgbm90IHRvbyBvZnRlbgoJICogKG1heCBvbmNlIHBlciBMQVAgd2luZG93KSBhbmQgd2UgYXJlIGNhbGxlZCBmcm9tIHBsYWNlcwoJICogd2hlcmUgd2UgY2FuIHNwZW5kIGEgYml0IG9mIHRpbWUgZG9pbmcgc3R1ZmYuIC0gSmVhbiBJSSAqLwoJaWYgKChzZWxmLT50eF9zZHVfYnVzeSkgJiYKCSAgICAoc2tiX3F1ZXVlX2xlbigmc2VsZi0+dHhfcXVldWUpIDwgVFRQX1RYX0xPV19USFJFU0hPTEQpICYmCgkgICAgKCFzZWxmLT5jbG9zZV9wZW5kKSkKCXsKCQlpZiAoc2VsZi0+bm90aWZ5LmZsb3dfaW5kaWNhdGlvbikKCQkJc2VsZi0+bm90aWZ5LmZsb3dfaW5kaWNhdGlvbihzZWxmLT5ub3RpZnkuaW5zdGFuY2UsCgkJCQkJCSAgICAgc2VsZiwgRkxPV19TVEFSVCk7CgoJCS8qIHNlbGYtPnR4X3NkdV9idXN5IGlzIHRoZSBzdGF0ZSBvZiB0aGUgY2xpZW50LgoJCSAqIFdlIGRvbid0IHJlYWxseSBoYXZlIGEgcmFjZSBoZXJlLCBidXQgaXQncyBhbHdheXMgc2FmZXIKCQkgKiB0byB1cGRhdGUgb3VyIHN0YXRlIGFmdGVyIHRoZSBjbGllbnQgLSBKZWFuIElJICovCgkJc2VsZi0+dHhfc2R1X2J1c3kgPSBGQUxTRTsKCX0KCgkvKiBSZXNldCBsb2NrICovCglzZWxmLT50eF9xdWV1ZV9sb2NrID0gMDsKfQoKLyoKICogRnVuY3Rpb24gaXJ0dHBfZ2l2ZV9jcmVkaXQgKHNlbGYpCiAqCiAqICAgIFNlbmQgYSBkYXRhbGVzcyBmbG93ZGF0YSBUVFAtUERVIGFuZCBnaXZlIGF2YWlsYWJsZSBjcmVkaXQgdG8gcGVlcgogKiAgICBUU0FQCiAqLwpzdGF0aWMgaW5saW5lIHZvaWQgaXJ0dHBfZ2l2ZV9jcmVkaXQoc3RydWN0IHRzYXBfY2IgKnNlbGYpCnsKCXN0cnVjdCBza19idWZmICp0eF9za2IgPSBOVUxMOwoJdW5zaWduZWQgbG9uZyBmbGFnczsKCWludCBuOwoKCUlSREFfQVNTRVJUKHNlbGYgIT0gTlVMTCwgcmV0dXJuOyk7CglJUkRBX0FTU0VSVChzZWxmLT5tYWdpYyA9PSBUVFBfVFNBUF9NQUdJQywgcmV0dXJuOyk7CgoJSVJEQV9ERUJVRyg0LCAiJXMoKSBzZW5kPSVkLGF2YWlsPSVkLHJlbW90ZT0lZFxuIiwKCQkgICBfX0ZVTkNUSU9OX18sCgkJICAgc2VsZi0+c2VuZF9jcmVkaXQsIHNlbGYtPmF2YWlsX2NyZWRpdCwgc2VsZi0+cmVtb3RlX2NyZWRpdCk7CgoJLyogR2l2ZSBjcmVkaXQgdG8gcGVlciAqLwoJdHhfc2tiID0gYWxsb2Nfc2tiKDY0LCBHRlBfQVRPTUlDKTsKCWlmICghdHhfc2tiKQoJCXJldHVybjsKCgkvKiBSZXNlcnZlIHNwYWNlIGZvciBMTVAsIGFuZCBMQVAgaGVhZGVyICovCglza2JfcmVzZXJ2ZSh0eF9za2IsIHNlbGYtPm1heF9oZWFkZXJfc2l6ZSk7CgoJLyoKCSAqICBTaW5jZSB3ZSBjYW4gdHJhbnNtaXQgYW5kIHJlY2VpdmUgZnJhbWVzIGNvbmN1cnJlbnRseSwKCSAqICB0aGUgY29kZSBiZWxvdyBpcyBhIGNyaXRpY2FsIHJlZ2lvbiBhbmQgd2UgbXVzdCBhc3N1cmUgdGhhdAoJICogIG5vYm9keSBtZXNzZXMgd2l0aCB0aGUgY3JlZGl0cyB3aGlsZSB3ZSB1cGRhdGUgdGhlbS4KCSAqLwoJc3Bpbl9sb2NrX2lycXNhdmUoJnNlbGYtPmxvY2ssIGZsYWdzKTsKCgluID0gc2VsZi0+YXZhaWxfY3JlZGl0OwoJc2VsZi0+YXZhaWxfY3JlZGl0ID0gMDsKCgkvKiBPbmx5IHNwYWNlIGZvciAxMjcgY3JlZGl0cyBpbiBmcmFtZSAqLwoJaWYgKG4gPiAxMjcpIHsKCQlzZWxmLT5hdmFpbF9jcmVkaXQgPSBuIC0gMTI3OwoJCW4gPSAxMjc7Cgl9CglzZWxmLT5yZW1vdGVfY3JlZGl0ICs9IG47CgoJc3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmc2VsZi0+bG9jaywgZmxhZ3MpOwoKCXNrYl9wdXQodHhfc2tiLCAxKTsKCXR4X3NrYi0+ZGF0YVswXSA9IChfX3U4KSAobiAmIDB4N2YpOwoKCWlybG1wX2RhdGFfcmVxdWVzdChzZWxmLT5sc2FwLCB0eF9za2IpOwoJc2VsZi0+c3RhdHMudHhfcGFja2V0cysrOwp9CgovKgogKiBGdW5jdGlvbiBpcnR0cF91ZGF0YV9pbmRpY2F0aW9uIChpbnN0YW5jZSwgc2FwLCBza2IpCiAqCiAqICAgIFJlY2VpdmVkIHNvbWUgdW5pdC1kYXRhICh1bnJlbGlhYmxlKQogKgogKi8Kc3RhdGljIGludCBpcnR0cF91ZGF0YV9pbmRpY2F0aW9uKHZvaWQgKmluc3RhbmNlLCB2b2lkICpzYXAsCgkJCQkgIHN0cnVjdCBza19idWZmICpza2IpCnsKCXN0cnVjdCB0c2FwX2NiICpzZWxmOwoJaW50IGVycjsKCglJUkRBX0RFQlVHKDQsICIlcygpXG4iLCBfX0ZVTkNUSU9OX18pOwoKCXNlbGYgPSAoc3RydWN0IHRzYXBfY2IgKikgaW5zdGFuY2U7CgoJSVJEQV9BU1NFUlQoc2VsZiAhPSBOVUxMLCByZXR1cm4gLTE7KTsKCUlSREFfQVNTRVJUKHNlbGYtPm1hZ2ljID09IFRUUF9UU0FQX01BR0lDLCByZXR1cm4gLTE7KTsKCUlSREFfQVNTRVJUKHNrYiAhPSBOVUxMLCByZXR1cm4gLTE7KTsKCglzZWxmLT5zdGF0cy5yeF9wYWNrZXRzKys7CgoJLyogSnVzdCBwYXNzIGRhdGEgdG8gbGF5ZXIgYWJvdmUgKi8KCWlmIChzZWxmLT5ub3RpZnkudWRhdGFfaW5kaWNhdGlvbikgewoJCWVyciA9IHNlbGYtPm5vdGlmeS51ZGF0YV9pbmRpY2F0aW9uKHNlbGYtPm5vdGlmeS5pbnN0YW5jZSwKCQkJCQkJICAgIHNlbGYsc2tiKTsKCQkvKiBTYW1lIGNvbW1lbnQgYXMgaW4gaXJ0dHBfZG9fZGF0YV9pbmRpY2F0aW9uKCkgKi8KCQlpZiAoIWVycikgCgkJCXJldHVybiAwOwoJfQoJLyogRWl0aGVyIG5vIGhhbmRsZXIsIG9yIGhhbmRsZXIgcmV0dXJucyBhbiBlcnJvciAqLwoJZGV2X2tmcmVlX3NrYihza2IpOwoKCXJldHVybiAwOwp9CgovKgogKiBGdW5jdGlvbiBpcnR0cF9kYXRhX2luZGljYXRpb24gKGluc3RhbmNlLCBzYXAsIHNrYikKICoKICogICAgUmVjZWl2ZSBzZWdtZW50IGZyb20gSXJMTVAuCiAqCiAqLwpzdGF0aWMgaW50IGlydHRwX2RhdGFfaW5kaWNhdGlvbih2b2lkICppbnN0YW5jZSwgdm9pZCAqc2FwLAoJCQkJIHN0cnVjdCBza19idWZmICpza2IpCnsKCXN0cnVjdCB0c2FwX2NiICpzZWxmOwoJdW5zaWduZWQgbG9uZyBmbGFnczsKCWludCBuOwoKCXNlbGYgPSAoc3RydWN0IHRzYXBfY2IgKikgaW5zdGFuY2U7CgoJbiA9IHNrYi0+ZGF0YVswXSAmIDB4N2Y7ICAgICAvKiBFeHRyYWN0IHRoZSBjcmVkaXRzICovCgoJc2VsZi0+c3RhdHMucnhfcGFja2V0cysrOwoKCS8qICBEZWFsIHdpdGggaW5ib3VuZCBjcmVkaXQKCSAqICBTaW5jZSB3ZSBjYW4gdHJhbnNtaXQgYW5kIHJlY2VpdmUgZnJhbWVzIGNvbmN1cnJlbnRseSwKCSAqICB0aGUgY29kZSBiZWxvdyBpcyBhIGNyaXRpY2FsIHJlZ2lvbiBhbmQgd2UgbXVzdCBhc3N1cmUgdGhhdAoJICogIG5vYm9keSBtZXNzZXMgd2l0aCB0aGUgY3JlZGl0cyB3aGlsZSB3ZSB1cGRhdGUgdGhlbS4KCSAqLwoJc3Bpbl9sb2NrX2lycXNhdmUoJnNlbGYtPmxvY2ssIGZsYWdzKTsKCXNlbGYtPnNlbmRfY3JlZGl0ICs9IG47CglpZiAoc2tiLT5sZW4gPiAxKQoJCXNlbGYtPnJlbW90ZV9jcmVkaXQtLTsKCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJnNlbGYtPmxvY2ssIGZsYWdzKTsKCgkvKgoJICogIERhdGEgb3IgZGF0YWxlc3MgcGFja2V0PyBEYXRhbGVzcyBmcmFtZXMgY29udGFpbnMgb25seSB0aGUKCSAqICBUVFBfSEVBREVSLgoJICovCglpZiAoc2tiLT5sZW4gPiAxKSB7CgkJLyoKCQkgKiAgV2UgZG9uJ3QgcmVtb3ZlIHRoZSBUVFAgaGVhZGVyLCBzaW5jZSB3ZSBtdXN0IHByZXNlcnZlIHRoZQoJCSAqICBtb3JlIGJpdCwgc28gdGhlIGRlZnJhZ21lbnQgcm91dGluZyBrbm93cyB3aGF0IHRvIGRvCgkJICovCgkJc2tiX3F1ZXVlX3RhaWwoJnNlbGYtPnJ4X3F1ZXVlLCBza2IpOwoJfSBlbHNlIHsKCQkvKiBEYXRhbGVzcyBmbG93ZGF0YSBUVFAtUERVICovCgkJZGV2X2tmcmVlX3NrYihza2IpOwoJfQoKCgkvKiBQdXNoIGRhdGEgdG8gdGhlIGhpZ2hlciBsYXllci4KCSAqIFdlIGRvIGl0IHN5bmNocm9ub3VzbHkgYmVjYXVzZSBydW5uaW5nIHRoZSB0b2RvIHRpbWVyIGZvciBlYWNoCgkgKiByZWNlaXZlIHBhY2tldCB3b3VsZCBiZSB0b28gbXVjaCBvdmVyaGVhZCBhbmQgbGF0ZW5jeS4KCSAqIEJ5IHBhc3NpbmcgY29udHJvbCB0byB0aGUgaGlnaGVyIGxheWVyLCB3ZSBydW4gdGhlIHJpc2sgdGhhdAoJICogaXQgbWF5IHRha2UgdGltZSBvciBncmFiIGEgbG9jay4gTW9zdCBvZnRlbiwgdGhlIGhpZ2hlciBsYXllcgoJICogd2lsbCBvbmx5IHB1dCBwYWNrZXQgaW4gYSBxdWV1ZS4KCSAqIEFueXdheSwgcGFja2V0cyBhcmUgb25seSBkcmlwcGluZyB0aHJvdWdoIHRoZSBJckRBLCBzbyB3ZSBjYW4KCSAqIGhhdmUgdGltZSBiZWZvcmUgdGhlIG5leHQgcGFja2V0LgoJICogRnVydGhlciwgd2UgYXJlIHJ1biBmcm9tIE5FVF9CSCwgc28gdGhlIHdvcnNlIHRoYXQgY2FuIGhhcHBlbiBpcwoJICogdXMgbWlzc2luZyB0aGUgb3B0aW1hbCB0aW1lIHRvIHNlbmQgYmFjayB0aGUgUEYgYml0IGluIExBUC4KCSAqIEplYW4gSUkgKi8KCWlydHRwX3J1bl9yeF9xdWV1ZShzZWxmKTsKCgkvKiBXZSBub3cgZ2l2ZSBjcmVkaXRzIHRvIHBlZXIgaW4gaXJ0dHBfcnVuX3J4X3F1ZXVlKCkuCgkgKiBXZSBuZWVkIHRvIHNlbmQgY3JlZGl0ICpOT1cqLCBvdGhlcndpc2Ugd2UgYXJlIGdvaW5nCgkgKiB0byBtaXNzIHRoZSBuZXh0IFR4IHdpbmRvdy4gVGhlIHRvZG8gdGltZXIgbWF5IHRha2UKCSAqIGEgd2hpbGUgYmVmb3JlIGl0J3MgcnVuLi4uIC0gSmVhbiBJSSAqLwoKCS8qCgkgKiBJZiB0aGUgcGVlciBkZXZpY2UgaGFzIGdpdmVuIHVzIHNvbWUgY3JlZGl0cyBhbmQgd2UgZGlkbid0IGhhdmUKICAgICAgICAgKiBhbnlvbmUgZnJvbSBiZWZvcmUsIHRoZW4gd2UgbmVlZCB0byBzaGVkdWxlIHRoZSB0eCBxdWV1ZS4KCSAqIFdlIG5lZWQgdG8gZG8gdGhhdCBiZWNhdXNlIG91ciBUeCBoYXZlIHN0b3BwZWQgKHNvIHdlIG1heSBub3QKCSAqIGdldCBhbnkgTEFQIGZsb3cgaW5kaWNhdGlvbikgYW5kIHRoZSB1c2VyIG1heSBiZSBzdG9wcGVkIGFzCgkgKiB3ZWxsLiAtIEplYW4gSUkKCSAqLwoJaWYgKHNlbGYtPnNlbmRfY3JlZGl0ID09IG4pIHsKCQkvKiBSZXN0YXJ0IHB1c2hpbmcgc3R1ZmYgdG8gTEFQICovCgkJaXJ0dHBfcnVuX3R4X3F1ZXVlKHNlbGYpOwoJCS8qIE5vdGUgOiB3ZSBkb24ndCB3YW50IHRvIHNjaGVkdWxlIHRoZSB0b2RvIHRpbWVyCgkJICogYmVjYXVzZSBpdCBoYXMgaG9ycmlibGUgbGF0ZW5jeS4gTm8gdGFza2xldHMKCQkgKiBiZWNhdXNlIHRoZSB0YXNrbGV0IEFQSSBpcyBicm9rZW4uIC0gSmVhbiBJSSAqLwoJfQoKCXJldHVybiAwOwp9CgovKgogKiBGdW5jdGlvbiBpcnR0cF9zdGF0dXNfaW5kaWNhdGlvbiAoc2VsZiwgcmVhc29uKQogKgogKiAgICBTdGF0dXNfaW5kaWNhdGlvbiwganVzdCBwYXNzIHRvIHRoZSBoaWdoZXIgbGF5ZXIuLi4KICoKICovCnN0YXRpYyB2b2lkIGlydHRwX3N0YXR1c19pbmRpY2F0aW9uKHZvaWQgKmluc3RhbmNlLAoJCQkJICAgIExJTktfU1RBVFVTIGxpbmssIExPQ0tfU1RBVFVTIGxvY2spCnsKCXN0cnVjdCB0c2FwX2NiICpzZWxmOwoKCUlSREFfREVCVUcoNCwgIiVzKClcbiIsIF9fRlVOQ1RJT05fXyk7CgoJc2VsZiA9IChzdHJ1Y3QgdHNhcF9jYiAqKSBpbnN0YW5jZTsKCglJUkRBX0FTU0VSVChzZWxmICE9IE5VTEwsIHJldHVybjspOwoJSVJEQV9BU1NFUlQoc2VsZi0+bWFnaWMgPT0gVFRQX1RTQVBfTUFHSUMsIHJldHVybjspOwoKCS8qIENoZWNrIGlmIGNsaWVudCBoYXMgYWxyZWFkeSBjbG9zZWQgdGhlIFRTQVAgYW5kIGdvbmUgYXdheSAqLwoJaWYgKHNlbGYtPmNsb3NlX3BlbmQpCgkJcmV0dXJuOwoKCS8qCgkgKiAgSW5mb3JtIHNlcnZpY2UgdXNlciBpZiBoZSBoYXMgcmVxdWVzdGVkIGl0CgkgKi8KCWlmIChzZWxmLT5ub3RpZnkuc3RhdHVzX2luZGljYXRpb24gIT0gTlVMTCkKCQlzZWxmLT5ub3RpZnkuc3RhdHVzX2luZGljYXRpb24oc2VsZi0+bm90aWZ5Lmluc3RhbmNlLAoJCQkJCSAgICAgICBsaW5rLCBsb2NrKTsKCWVsc2UKCQlJUkRBX0RFQlVHKDIsICIlcygpLCBubyBoYW5kbGVyXG4iLCBfX0ZVTkNUSU9OX18pOwp9CgovKgogKiBGdW5jdGlvbiBpcnR0cF9mbG93X2luZGljYXRpb24gKHNlbGYsIHJlYXNvbikKICoKICogICAgRmxvd19pbmRpY2F0aW9uIDogSXJMQVAgdGVsbHMgdXMgdG8gc2VuZCBtb3JlIGRhdGEuCiAqCiAqLwpzdGF0aWMgdm9pZCBpcnR0cF9mbG93X2luZGljYXRpb24odm9pZCAqaW5zdGFuY2UsIHZvaWQgKnNhcCwgTE9DQUxfRkxPVyBmbG93KQp7CglzdHJ1Y3QgdHNhcF9jYiAqc2VsZjsKCglzZWxmID0gKHN0cnVjdCB0c2FwX2NiICopIGluc3RhbmNlOwoKCUlSREFfQVNTRVJUKHNlbGYgIT0gTlVMTCwgcmV0dXJuOyk7CglJUkRBX0FTU0VSVChzZWxmLT5tYWdpYyA9PSBUVFBfVFNBUF9NQUdJQywgcmV0dXJuOyk7CgoJSVJEQV9ERUJVRyg0LCAiJXMoaW5zdGFuY2U9JXApXG4iLCBfX0ZVTkNUSU9OX18sIHNlbGYpOwoKCS8qIFdlIGFyZSAicG9sbGVkIiBkaXJlY3RseSBmcm9tIExBUCwgYW5kIHRoZSBMQVAgd2FudCB0byBmaWxsCgkgKiBpdHMgVHggd2luZG93LiBXZSB3YW50IHRvIGRvIG91ciBiZXN0IHRvIHNlbmQgaXQgZGF0YSwgc28gdGhhdAoJICogd2UgbWF4aW1pc2UgdGhlIHdpbmRvdy4gT24gdGhlIG90aGVyIGhhbmQsIHdlIHdhbnQgdG8gbGltaXQgdGhlCgkgKiBhbW91bnQgb2Ygd29yayBoZXJlIHNvIHRoYXQgTEFQIGRvZXNuJ3QgaGFuZyBmb3JldmVyIHdhaXRpbmcKCSAqIGZvciBwYWNrZXRzLiAtIEplYW4gSUkgKi8KCgkvKiBUcnkgdG8gc2VuZCBzb21lIHBhY2tldHMuIEN1cnJlbnRseSwgTEFQIGNhbGxzIHVzIGV2ZXJ5IHRpbWUKCSAqIHRoZXJlIGlzIG9uZSBmcmVlIHNsb3QsIHNvIHdlIHdpbGwgc2VuZCBvbmx5IG9uZSBwYWNrZXQuCgkgKiBUaGlzIGFsbG93IHRoZSBzY2hlZHVsZXIgdG8gZG8gaXRzIHJvdW5kIHJvYmluIC0gSmVhbiBJSSAqLwoJaXJ0dHBfcnVuX3R4X3F1ZXVlKHNlbGYpOwoKCS8qIE5vdGUgcmVnYXJkaW5nIHRoZSBpbnRlcnJhY3Rpb24gd2l0aCBoaWdoZXIgbGF5ZXIuCgkgKiBpcnR0cF9ydW5fdHhfcXVldWUoKSBtYXkgY2FsbCB0aGUgY2xpZW50IHdoZW4gaXRzIHF1ZXVlCgkgKiBzdGFydCB0byBlbXB0eSwgdmlhIG5vdGlmeS5mbG93X2luZGljYXRpb24oKS4gSW5pdGlhbGx5LgoJICogSSB3YW50ZWQgdGhpcyB0byBoYXBwZW4gaW4gYSB0YXNrbGV0LCB0byBhdm9pZCBjbGllbnQKCSAqIGdyYWJiaW5nIHRoZSBDUFUsIGJ1dCB3ZSBjYW4ndCB1c2UgdGFza2xldHMgc2FmZWx5LiBBbmQgdGltZXIKCSAqIGlzIGRlZmluaXRlbHkgdG9vIHNsb3cuCgkgKiBUaGlzIHdpbGwgaGFwcGVuIG9ubHkgb25jZSBwZXIgTEFQIHdpbmRvdywgYW5kIHVzdWFsbHkgYXQKCSAqIHRoZSB0aGlyZCBwYWNrZXQgKHVubGVzcyB3aW5kb3cgaXMgc21hbGxlcikuIExBUCBpcyBzdGlsbAoJICogZG9pbmcgbXR0IGFuZCBzZW5kaW5nIGZpcnN0IHBhY2tldCBzbyBpdCdzIHNvcnQgb2YgT0sKCSAqIHRvIGRvIHRoYXQuIEplYW4gSUkgKi8KCgkvKiBJZiB3ZSBuZWVkIHRvIHNlbmQgZGlzY29ubmVjdC4gdHJ5IHRvIGRvIGl0IG5vdyAqLwoJaWYoc2VsZi0+ZGlzY29ubmVjdF9wZW5kKQoJCWlydHRwX3N0YXJ0X3RvZG9fdGltZXIoc2VsZiwgMCk7Cn0KCi8qCiAqIEZ1bmN0aW9uIGlydHRwX2Zsb3dfcmVxdWVzdCAoc2VsZiwgY29tbWFuZCkKICoKICogICAgVGhpcyBmdW5jdGlvbiBjb3VsZCBiZSB1c2VkIGJ5IHRoZSB1cHBlciBsYXllcnMgdG8gdGVsbCBJclRUUCB0byBzdG9wCiAqICAgIGRlbGl2ZXJpbmcgZnJhbWVzIGlmIHRoZSByZWNlaXZlIHF1ZXVlcyBhcmUgc3RhcnRpbmcgdG8gZ2V0IGZ1bGwsIG9yCiAqICAgIHRvIHRlbGwgSXJUVFAgdG8gc3RhcnQgZGVsaXZlcmluZyBmcmFtZXMgYWdhaW4uCiAqLwp2b2lkIGlydHRwX2Zsb3dfcmVxdWVzdChzdHJ1Y3QgdHNhcF9jYiAqc2VsZiwgTE9DQUxfRkxPVyBmbG93KQp7CglJUkRBX0RFQlVHKDEsICIlcygpXG4iLCBfX0ZVTkNUSU9OX18pOwoKCUlSREFfQVNTRVJUKHNlbGYgIT0gTlVMTCwgcmV0dXJuOyk7CglJUkRBX0FTU0VSVChzZWxmLT5tYWdpYyA9PSBUVFBfVFNBUF9NQUdJQywgcmV0dXJuOyk7CgoJc3dpdGNoIChmbG93KSB7CgljYXNlIEZMT1dfU1RPUDoKCQlJUkRBX0RFQlVHKDEsICIlcygpLCBmbG93IHN0b3BcbiIsIF9fRlVOQ1RJT05fXyk7CgkJc2VsZi0+cnhfc2R1X2J1c3kgPSBUUlVFOwoJCWJyZWFrOwoJY2FzZSBGTE9XX1NUQVJUOgoJCUlSREFfREVCVUcoMSwgIiVzKCksIGZsb3cgc3RhcnRcbiIsIF9fRlVOQ1RJT05fXyk7CgkJc2VsZi0+cnhfc2R1X2J1c3kgPSBGQUxTRTsKCgkJLyogQ2xpZW50IHNheSBoZSBjYW4gYWNjZXB0IG1vcmUgZGF0YSwgdHJ5IHRvIGZyZWUgb3VyCgkJICogcXVldWVzIEFTQVAgLSBKZWFuIElJICovCgkJaXJ0dHBfcnVuX3J4X3F1ZXVlKHNlbGYpOwoKCQlicmVhazsKCWRlZmF1bHQ6CgkJSVJEQV9ERUJVRygxLCAiJXMoKSwgVW5rbm93biBmbG93IGNvbW1hbmQhXG4iLCBfX0ZVTkNUSU9OX18pOwoJfQp9CkVYUE9SVF9TWU1CT0woaXJ0dHBfZmxvd19yZXF1ZXN0KTsKCi8qCiAqIEZ1bmN0aW9uIGlydHRwX2Nvbm5lY3RfcmVxdWVzdCAoc2VsZiwgZHRzYXBfc2VsLCBkYWRkciwgcW9zKQogKgogKiAgICBUcnkgdG8gY29ubmVjdCB0byByZW1vdGUgZGVzdGluYXRpb24gVFNBUCBzZWxlY3RvcgogKgogKi8KaW50IGlydHRwX2Nvbm5lY3RfcmVxdWVzdChzdHJ1Y3QgdHNhcF9jYiAqc2VsZiwgX191OCBkdHNhcF9zZWwsCgkJCSAgX191MzIgc2FkZHIsIF9fdTMyIGRhZGRyLAoJCQkgIHN0cnVjdCBxb3NfaW5mbyAqcW9zLCBfX3UzMiBtYXhfc2R1X3NpemUsCgkJCSAgc3RydWN0IHNrX2J1ZmYgKnVzZXJkYXRhKQp7CglzdHJ1Y3Qgc2tfYnVmZiAqdHhfc2tiOwoJX191OCAqZnJhbWU7CglfX3U4IG47CgoJSVJEQV9ERUJVRyg0LCAiJXMoKSwgbWF4X3NkdV9zaXplPSVkXG4iLCBfX0ZVTkNUSU9OX18sIG1heF9zZHVfc2l6ZSk7CgoJSVJEQV9BU1NFUlQoc2VsZiAhPSBOVUxMLCByZXR1cm4gLUVCQURSOyk7CglJUkRBX0FTU0VSVChzZWxmLT5tYWdpYyA9PSBUVFBfVFNBUF9NQUdJQywgcmV0dXJuIC1FQkFEUjspOwoKCWlmIChzZWxmLT5jb25uZWN0ZWQpIHsKCQlpZih1c2VyZGF0YSkKCQkJZGV2X2tmcmVlX3NrYih1c2VyZGF0YSk7CgkJcmV0dXJuIC1FSVNDT05OOwoJfQoKCS8qIEFueSB1c2VyZGF0YSBzdXBwbGllZD8gKi8KCWlmICh1c2VyZGF0YSA9PSBOVUxMKSB7CgkJdHhfc2tiID0gYWxsb2Nfc2tiKDY0LCBHRlBfQVRPTUlDKTsKCQlpZiAoIXR4X3NrYikKCQkJcmV0dXJuIC1FTk9NRU07CgoJCS8qIFJlc2VydmUgc3BhY2UgZm9yIE1VWF9DT05UUk9MIGFuZCBMQVAgaGVhZGVyICovCgkJc2tiX3Jlc2VydmUodHhfc2tiLCBUVFBfTUFYX0hFQURFUik7Cgl9IGVsc2UgewoJCXR4X3NrYiA9IHVzZXJkYXRhOwoJCS8qCgkJICogIENoZWNrIHRoYXQgdGhlIGNsaWVudCBoYXMgcmVzZXJ2ZWQgZW5vdWdoIHNwYWNlIGZvcgoJCSAqICBoZWFkZXJzCgkJICovCgkJSVJEQV9BU1NFUlQoc2tiX2hlYWRyb29tKHVzZXJkYXRhKSA+PSBUVFBfTUFYX0hFQURFUiwKCQkJeyBkZXZfa2ZyZWVfc2tiKHVzZXJkYXRhKTsgcmV0dXJuIC0xOyB9ICk7Cgl9CgoJLyogSW5pdGlhbGl6ZSBjb25uZWN0aW9uIHBhcmFtZXRlcnMgKi8KCXNlbGYtPmNvbm5lY3RlZCA9IEZBTFNFOwoJc2VsZi0+YXZhaWxfY3JlZGl0ID0gMDsKCXNlbGYtPnJ4X21heF9zZHVfc2l6ZSA9IG1heF9zZHVfc2l6ZTsKCXNlbGYtPnJ4X3NkdV9zaXplID0gMDsKCXNlbGYtPnJ4X3NkdV9idXN5ID0gRkFMU0U7CglzZWxmLT5kdHNhcF9zZWwgPSBkdHNhcF9zZWw7CgoJbiA9IHNlbGYtPmluaXRpYWxfY3JlZGl0OwoKCXNlbGYtPnJlbW90ZV9jcmVkaXQgPSAwOwoJc2VsZi0+c2VuZF9jcmVkaXQgPSAwOwoKCS8qCgkgKiAgR2l2ZSBhd2F5IG1heCAxMjcgY3JlZGl0cyBmb3Igbm93CgkgKi8KCWlmIChuID4gMTI3KSB7CgkJc2VsZi0+YXZhaWxfY3JlZGl0PW4tMTI3OwoJCW4gPSAxMjc7Cgl9CgoJc2VsZi0+cmVtb3RlX2NyZWRpdCA9IG47CgoJLyogU0FSIGVuYWJsZWQ/ICovCglpZiAobWF4X3NkdV9zaXplID4gMCkgewoJCUlSREFfQVNTRVJUKHNrYl9oZWFkcm9vbSh0eF9za2IpID49IChUVFBfTUFYX0hFQURFUiArIFRUUF9TQVJfSEVBREVSKSwKCQkJeyBkZXZfa2ZyZWVfc2tiKHR4X3NrYik7IHJldHVybiAtMTsgfSApOwoKCQkvKiBJbnNlcnQgU0FSIHBhcmFtZXRlcnMgKi8KCQlmcmFtZSA9IHNrYl9wdXNoKHR4X3NrYiwgVFRQX0hFQURFUitUVFBfU0FSX0hFQURFUik7CgoJCWZyYW1lWzBdID0gVFRQX1BBUkFNRVRFUlMgfCBuOwoJCWZyYW1lWzFdID0gMHgwNDsgLyogTGVuZ3RoICovCgkJZnJhbWVbMl0gPSAweDAxOyAvKiBNYXhTZHVTaXplICovCgkJZnJhbWVbM10gPSAweDAyOyAvKiBWYWx1ZSBsZW5ndGggKi8KCgkJcHV0X3VuYWxpZ25lZChjcHVfdG9fYmUxNigoX191MTYpIG1heF9zZHVfc2l6ZSksCgkJCSAgICAgIChfX3UxNiAqKShmcmFtZSs0KSk7Cgl9IGVsc2UgewoJCS8qIEluc2VydCBwbGFpbiBUVFAgaGVhZGVyICovCgkJZnJhbWUgPSBza2JfcHVzaCh0eF9za2IsIFRUUF9IRUFERVIpOwoKCQkvKiBJbnNlcnQgaW5pdGlhbCBjcmVkaXQgaW4gZnJhbWUgKi8KCQlmcmFtZVswXSA9IG4gJiAweDdmOwoJfQoKCS8qIENvbm5lY3Qgd2l0aCBJckxNUC4gTm8gUW9TIHBhcmFtZXRlcnMgZm9yIG5vdyAqLwoJcmV0dXJuIGlybG1wX2Nvbm5lY3RfcmVxdWVzdChzZWxmLT5sc2FwLCBkdHNhcF9zZWwsIHNhZGRyLCBkYWRkciwgcW9zLAoJCQkJICAgICB0eF9za2IpOwp9CkVYUE9SVF9TWU1CT0woaXJ0dHBfY29ubmVjdF9yZXF1ZXN0KTsKCi8qCiAqIEZ1bmN0aW9uIGlydHRwX2Nvbm5lY3RfY29uZmlybSAoaGFuZGxlLCBxb3MsIHNrYikKICoKICogICAgU2V2aWNlIHVzZXIgY29uZmlybXMgVFNBUCBjb25uZWN0aW9uIHdpdGggcGVlci4KICoKICovCnN0YXRpYyB2b2lkIGlydHRwX2Nvbm5lY3RfY29uZmlybSh2b2lkICppbnN0YW5jZSwgdm9pZCAqc2FwLAoJCQkJICBzdHJ1Y3QgcW9zX2luZm8gKnFvcywgX191MzIgbWF4X3NlZ19zaXplLAoJCQkJICBfX3U4IG1heF9oZWFkZXJfc2l6ZSwgc3RydWN0IHNrX2J1ZmYgKnNrYikKewoJc3RydWN0IHRzYXBfY2IgKnNlbGY7CglpbnQgcGFyYW1ldGVyczsKCWludCByZXQ7CglfX3U4IHBsZW47CglfX3U4IG47CgoJSVJEQV9ERUJVRyg0LCAiJXMoKVxuIiwgX19GVU5DVElPTl9fKTsKCglzZWxmID0gKHN0cnVjdCB0c2FwX2NiICopIGluc3RhbmNlOwoKCUlSREFfQVNTRVJUKHNlbGYgIT0gTlVMTCwgcmV0dXJuOyk7CglJUkRBX0FTU0VSVChzZWxmLT5tYWdpYyA9PSBUVFBfVFNBUF9NQUdJQywgcmV0dXJuOyk7CglJUkRBX0FTU0VSVChza2IgIT0gTlVMTCwgcmV0dXJuOyk7CgoJc2VsZi0+bWF4X3NlZ19zaXplID0gbWF4X3NlZ19zaXplIC0gVFRQX0hFQURFUjsKCXNlbGYtPm1heF9oZWFkZXJfc2l6ZSA9IG1heF9oZWFkZXJfc2l6ZSArIFRUUF9IRUFERVI7CgoJLyoKCSAqICBDaGVjayBpZiB3ZSBoYXZlIGdvdCBzb21lIFFvUyBwYXJhbWV0ZXJzIGJhY2shIFRoaXMgc2hvdWxkIGJlIHRoZQoJICogIG5lZ290aWF0ZWQgUW9TIGZvciB0aGUgbGluay4KCSAqLwoJaWYgKHFvcykgewoJCUlSREFfREVCVUcoNCwgIklyVFRQLCBOZWdvdGlhdGVkIEJBVURfUkFURTogJTAyeFxuIiwKCQkgICAgICAgcW9zLT5iYXVkX3JhdGUuYml0cyk7CgkJSVJEQV9ERUJVRyg0LCAiSXJUVFAsIE5lZ290aWF0ZWQgQkFVRF9SQVRFOiAlZCBicHMuXG4iLAoJCSAgICAgICBxb3MtPmJhdWRfcmF0ZS52YWx1ZSk7Cgl9CgoJbiA9IHNrYi0+ZGF0YVswXSAmIDB4N2Y7CgoJSVJEQV9ERUJVRyg0LCAiJXMoKSwgSW5pdGlhbCBzZW5kX2NyZWRpdD0lZFxuIiwgX19GVU5DVElPTl9fLCBuKTsKCglzZWxmLT5zZW5kX2NyZWRpdCA9IG47CglzZWxmLT50eF9tYXhfc2R1X3NpemUgPSAwOwoJc2VsZi0+Y29ubmVjdGVkID0gVFJVRTsKCglwYXJhbWV0ZXJzID0gc2tiLT5kYXRhWzBdICYgMHg4MDsKCglJUkRBX0FTU0VSVChza2ItPmxlbiA+PSBUVFBfSEVBREVSLCByZXR1cm47KTsKCXNrYl9wdWxsKHNrYiwgVFRQX0hFQURFUik7CgoJaWYgKHBhcmFtZXRlcnMpIHsKCQlwbGVuID0gc2tiLT5kYXRhWzBdOwoKCQlyZXQgPSBpcmRhX3BhcmFtX2V4dHJhY3RfYWxsKHNlbGYsIHNrYi0+ZGF0YSsxLAoJCQkJCSAgICAgSVJEQV9NSU4oc2tiLT5sZW4tMSwgcGxlbiksCgkJCQkJICAgICAmcGFyYW1faW5mbyk7CgoJCS8qIEFueSBlcnJvcnMgaW4gdGhlIHBhcmFtZXRlciBsaXN0PyAqLwoJCWlmIChyZXQgPCAwKSB7CgkJCUlSREFfV0FSTklORygiJXM6IGVycm9yIGV4dHJhY3RpbmcgcGFyYW1ldGVyc1xuIiwKCQkJCSAgICAgX19GVU5DVElPTl9fKTsKCQkJZGV2X2tmcmVlX3NrYihza2IpOwoKCQkJLyogRG8gbm90IGFjY2VwdCB0aGlzIGNvbm5lY3Rpb24gYXR0ZW1wdCAqLwoJCQlyZXR1cm47CgkJfQoJCS8qIFJlbW92ZSBwYXJhbWV0ZXJzICovCgkJc2tiX3B1bGwoc2tiLCBJUkRBX01JTihza2ItPmxlbiwgcGxlbisxKSk7Cgl9CgoJSVJEQV9ERUJVRyg0LCAiJXMoKSBzZW5kPSVkLGF2YWlsPSVkLHJlbW90ZT0lZFxuIiwgX19GVU5DVElPTl9fLAoJICAgICAgc2VsZi0+c2VuZF9jcmVkaXQsIHNlbGYtPmF2YWlsX2NyZWRpdCwgc2VsZi0+cmVtb3RlX2NyZWRpdCk7CgoJSVJEQV9ERUJVRygyLCAiJXMoKSwgTWF4U2R1U2l6ZT0lZFxuIiwgX19GVU5DVElPTl9fLAoJCSAgIHNlbGYtPnR4X21heF9zZHVfc2l6ZSk7CgoJaWYgKHNlbGYtPm5vdGlmeS5jb25uZWN0X2NvbmZpcm0pIHsKCQlzZWxmLT5ub3RpZnkuY29ubmVjdF9jb25maXJtKHNlbGYtPm5vdGlmeS5pbnN0YW5jZSwgc2VsZiwgcW9zLAoJCQkJCSAgICAgc2VsZi0+dHhfbWF4X3NkdV9zaXplLAoJCQkJCSAgICAgc2VsZi0+bWF4X2hlYWRlcl9zaXplLCBza2IpOwoJfSBlbHNlCgkJZGV2X2tmcmVlX3NrYihza2IpOwp9CgovKgogKiBGdW5jdGlvbiBpcnR0cF9jb25uZWN0X2luZGljYXRpb24gKGhhbmRsZSwgc2tiKQogKgogKiAgICBTb21lIG90aGVyIGRldmljZSBpcyBjb25uZWN0aW5nIHRvIHRoaXMgVFNBUAogKgogKi8Kdm9pZCBpcnR0cF9jb25uZWN0X2luZGljYXRpb24odm9pZCAqaW5zdGFuY2UsIHZvaWQgKnNhcCwgc3RydWN0IHFvc19pbmZvICpxb3MsCgkJCSAgICAgIF9fdTMyIG1heF9zZWdfc2l6ZSwgX191OCBtYXhfaGVhZGVyX3NpemUsCgkJCSAgICAgIHN0cnVjdCBza19idWZmICpza2IpCnsKCXN0cnVjdCB0c2FwX2NiICpzZWxmOwoJc3RydWN0IGxzYXBfY2IgKmxzYXA7CglpbnQgcGFyYW1ldGVyczsKCWludCByZXQ7CglfX3U4IHBsZW47CglfX3U4IG47CgoJc2VsZiA9IChzdHJ1Y3QgdHNhcF9jYiAqKSBpbnN0YW5jZTsKCglJUkRBX0FTU0VSVChzZWxmICE9IE5VTEwsIHJldHVybjspOwoJSVJEQV9BU1NFUlQoc2VsZi0+bWFnaWMgPT0gVFRQX1RTQVBfTUFHSUMsIHJldHVybjspOwoJSVJEQV9BU1NFUlQoc2tiICE9IE5VTEwsIHJldHVybjspOwoKCWxzYXAgPSAoc3RydWN0IGxzYXBfY2IgKikgc2FwOwoKCXNlbGYtPm1heF9zZWdfc2l6ZSA9IG1heF9zZWdfc2l6ZSAtIFRUUF9IRUFERVI7CglzZWxmLT5tYXhfaGVhZGVyX3NpemUgPSBtYXhfaGVhZGVyX3NpemUrVFRQX0hFQURFUjsKCglJUkRBX0RFQlVHKDQsICIlcygpLCBUU0FQIHNlbD0lMDJ4XG4iLCBfX0ZVTkNUSU9OX18sIHNlbGYtPnN0c2FwX3NlbCk7CgoJLyogTmVlZCB0byB1cGRhdGUgZHRzYXBfc2VsIGlmIGl0cyBlcXVhbCB0byBMU0FQX0FOWSAqLwoJc2VsZi0+ZHRzYXBfc2VsID0gbHNhcC0+ZGxzYXBfc2VsOwoKCW4gPSBza2ItPmRhdGFbMF0gJiAweDdmOwoKCXNlbGYtPnNlbmRfY3JlZGl0ID0gbjsKCXNlbGYtPnR4X21heF9zZHVfc2l6ZSA9IDA7CgoJcGFyYW1ldGVycyA9IHNrYi0+ZGF0YVswXSAmIDB4ODA7CgoJSVJEQV9BU1NFUlQoc2tiLT5sZW4gPj0gVFRQX0hFQURFUiwgcmV0dXJuOyk7Cglza2JfcHVsbChza2IsIFRUUF9IRUFERVIpOwoKCWlmIChwYXJhbWV0ZXJzKSB7CgkJcGxlbiA9IHNrYi0+ZGF0YVswXTsKCgkJcmV0ID0gaXJkYV9wYXJhbV9leHRyYWN0X2FsbChzZWxmLCBza2ItPmRhdGErMSwKCQkJCQkgICAgIElSREFfTUlOKHNrYi0+bGVuLTEsIHBsZW4pLAoJCQkJCSAgICAgJnBhcmFtX2luZm8pOwoKCQkvKiBBbnkgZXJyb3JzIGluIHRoZSBwYXJhbWV0ZXIgbGlzdD8gKi8KCQlpZiAocmV0IDwgMCkgewoJCQlJUkRBX1dBUk5JTkcoIiVzOiBlcnJvciBleHRyYWN0aW5nIHBhcmFtZXRlcnNcbiIsCgkJCQkgICAgIF9fRlVOQ1RJT05fXyk7CgkJCWRldl9rZnJlZV9za2Ioc2tiKTsKCgkJCS8qIERvIG5vdCBhY2NlcHQgdGhpcyBjb25uZWN0aW9uIGF0dGVtcHQgKi8KCQkJcmV0dXJuOwoJCX0KCgkJLyogUmVtb3ZlIHBhcmFtZXRlcnMgKi8KCQlza2JfcHVsbChza2IsIElSREFfTUlOKHNrYi0+bGVuLCBwbGVuKzEpKTsKCX0KCglpZiAoc2VsZi0+bm90aWZ5LmNvbm5lY3RfaW5kaWNhdGlvbikgewoJCXNlbGYtPm5vdGlmeS5jb25uZWN0X2luZGljYXRpb24oc2VsZi0+bm90aWZ5Lmluc3RhbmNlLCBzZWxmLAoJCQkJCQlxb3MsIHNlbGYtPnR4X21heF9zZHVfc2l6ZSwKCQkJCQkJc2VsZi0+bWF4X2hlYWRlcl9zaXplLCBza2IpOwoJfSBlbHNlCgkJZGV2X2tmcmVlX3NrYihza2IpOwp9CgovKgogKiBGdW5jdGlvbiBpcnR0cF9jb25uZWN0X3Jlc3BvbnNlIChoYW5kbGUsIHVzZXJkYXRhKQogKgogKiAgICBTZXJ2aWNlIHVzZXIgaXMgYWNjZXB0aW5nIHRoZSBjb25uZWN0aW9uLCBqdXN0IHBhc3MgaXQgZG93biB0bwogKiAgICBJckxNUCEKICoKICovCmludCBpcnR0cF9jb25uZWN0X3Jlc3BvbnNlKHN0cnVjdCB0c2FwX2NiICpzZWxmLCBfX3UzMiBtYXhfc2R1X3NpemUsCgkJCSAgIHN0cnVjdCBza19idWZmICp1c2VyZGF0YSkKewoJc3RydWN0IHNrX2J1ZmYgKnR4X3NrYjsKCV9fdTggKmZyYW1lOwoJaW50IHJldDsKCV9fdTggbjsKCglJUkRBX0FTU0VSVChzZWxmICE9IE5VTEwsIHJldHVybiAtMTspOwoJSVJEQV9BU1NFUlQoc2VsZi0+bWFnaWMgPT0gVFRQX1RTQVBfTUFHSUMsIHJldHVybiAtMTspOwoKCUlSREFfREVCVUcoNCwgIiVzKCksIFNvdXJjZSBUU0FQIHNlbGVjdG9yPSUwMnhcbiIsIF9fRlVOQ1RJT05fXywKCQkgICBzZWxmLT5zdHNhcF9zZWwpOwoKCS8qIEFueSB1c2VyZGF0YSBzdXBwbGllZD8gKi8KCWlmICh1c2VyZGF0YSA9PSBOVUxMKSB7CgkJdHhfc2tiID0gYWxsb2Nfc2tiKDY0LCBHRlBfQVRPTUlDKTsKCQlpZiAoIXR4X3NrYikKCQkJcmV0dXJuIC1FTk9NRU07CgoJCS8qIFJlc2VydmUgc3BhY2UgZm9yIE1VWF9DT05UUk9MIGFuZCBMQVAgaGVhZGVyICovCgkJc2tiX3Jlc2VydmUodHhfc2tiLCBUVFBfTUFYX0hFQURFUik7Cgl9IGVsc2UgewoJCXR4X3NrYiA9IHVzZXJkYXRhOwoJCS8qCgkJICogIENoZWNrIHRoYXQgdGhlIGNsaWVudCBoYXMgcmVzZXJ2ZWQgZW5vdWdoIHNwYWNlIGZvcgoJCSAqICBoZWFkZXJzCgkJICovCgkJSVJEQV9BU1NFUlQoc2tiX2hlYWRyb29tKHVzZXJkYXRhKSA+PSBUVFBfTUFYX0hFQURFUiwKCQkJeyBkZXZfa2ZyZWVfc2tiKHVzZXJkYXRhKTsgcmV0dXJuIC0xOyB9ICk7Cgl9CgoJc2VsZi0+YXZhaWxfY3JlZGl0ID0gMDsKCXNlbGYtPnJlbW90ZV9jcmVkaXQgPSAwOwoJc2VsZi0+cnhfbWF4X3NkdV9zaXplID0gbWF4X3NkdV9zaXplOwoJc2VsZi0+cnhfc2R1X3NpemUgPSAwOwoJc2VsZi0+cnhfc2R1X2J1c3kgPSBGQUxTRTsKCgluID0gc2VsZi0+aW5pdGlhbF9jcmVkaXQ7CgoJLyogRnJhbWUgaGFzIG9ubHkgc3BhY2UgZm9yIG1heCAxMjcgY3JlZGl0cyAoNyBiaXRzKSAqLwoJaWYgKG4gPiAxMjcpIHsKCQlzZWxmLT5hdmFpbF9jcmVkaXQgPSBuIC0gMTI3OwoJCW4gPSAxMjc7Cgl9CgoJc2VsZi0+cmVtb3RlX2NyZWRpdCA9IG47CglzZWxmLT5jb25uZWN0ZWQgPSBUUlVFOwoKCS8qIFNBUiBlbmFibGVkPyAqLwoJaWYgKG1heF9zZHVfc2l6ZSA+IDApIHsKCQlJUkRBX0FTU0VSVChza2JfaGVhZHJvb20odHhfc2tiKSA+PSAoVFRQX01BWF9IRUFERVIgKyBUVFBfU0FSX0hFQURFUiksCgkJCXsgZGV2X2tmcmVlX3NrYih0eF9za2IpOyByZXR1cm4gLTE7IH0gKTsKCgkJLyogSW5zZXJ0IFRUUCBoZWFkZXIgd2l0aCBTQVIgcGFyYW1ldGVycyAqLwoJCWZyYW1lID0gc2tiX3B1c2godHhfc2tiLCBUVFBfSEVBREVSK1RUUF9TQVJfSEVBREVSKTsKCgkJZnJhbWVbMF0gPSBUVFBfUEFSQU1FVEVSUyB8IG47CgkJZnJhbWVbMV0gPSAweDA0OyAvKiBMZW5ndGggKi8KCgkJLyogaXJkYV9wYXJhbV9pbnNlcnQoc2VsZiwgSVJUVFBfTUFYX1NEVV9TSVpFLCBmcmFtZSsxLCAgKi8KLyoJCQkJICBUVFBfU0FSX0hFQURFUiwgJnBhcmFtX2luZm8pICovCgoJCWZyYW1lWzJdID0gMHgwMTsgLyogTWF4U2R1U2l6ZSAqLwoJCWZyYW1lWzNdID0gMHgwMjsgLyogVmFsdWUgbGVuZ3RoICovCgoJCXB1dF91bmFsaWduZWQoY3B1X3RvX2JlMTYoKF9fdTE2KSBtYXhfc2R1X3NpemUpLAoJCQkgICAgICAoX191MTYgKikoZnJhbWUrNCkpOwoJfSBlbHNlIHsKCQkvKiBJbnNlcnQgVFRQIGhlYWRlciAqLwoJCWZyYW1lID0gc2tiX3B1c2godHhfc2tiLCBUVFBfSEVBREVSKTsKCgkJZnJhbWVbMF0gPSBuICYgMHg3ZjsKCX0KCglyZXQgPSBpcmxtcF9jb25uZWN0X3Jlc3BvbnNlKHNlbGYtPmxzYXAsIHR4X3NrYik7CgoJcmV0dXJuIHJldDsKfQpFWFBPUlRfU1lNQk9MKGlydHRwX2Nvbm5lY3RfcmVzcG9uc2UpOwoKLyoKICogRnVuY3Rpb24gaXJ0dHBfZHVwIChzZWxmLCBpbnN0YW5jZSkKICoKICogICAgRHVwbGljYXRlIFRTQVAsIGNhbiBiZSB1c2VkIGJ5IHNlcnZlcnMgdG8gY29uZmlybSBhIGNvbm5lY3Rpb24gb24gYQogKiAgICBuZXcgVFNBUCBzbyBpdCBjYW4ga2VlcCBsaXN0ZW5pbmcgb24gdGhlIG9sZCBvbmUuCiAqLwpzdHJ1Y3QgdHNhcF9jYiAqaXJ0dHBfZHVwKHN0cnVjdCB0c2FwX2NiICpvcmlnLCB2b2lkICppbnN0YW5jZSkKewoJc3RydWN0IHRzYXBfY2IgKm5ldzsKCXVuc2lnbmVkIGxvbmcgZmxhZ3M7CgoJSVJEQV9ERUJVRygxLCAiJXMoKVxuIiwgX19GVU5DVElPTl9fKTsKCgkvKiBQcm90ZWN0IG91ciBhY2Nlc3MgdG8gdGhlIG9sZCB0c2FwIGluc3RhbmNlICovCglzcGluX2xvY2tfaXJxc2F2ZSgmaXJ0dHAtPnRzYXBzLT5oYl9zcGlubG9jaywgZmxhZ3MpOwoKCS8qIEZpbmQgdGhlIG9sZCBpbnN0YW5jZSAqLwoJaWYgKCFoYXNoYmluX2ZpbmQoaXJ0dHAtPnRzYXBzLCAobG9uZykgb3JpZywgTlVMTCkpIHsKCQlJUkRBX0RFQlVHKDAsICIlcygpLCB1bmFibGUgdG8gZmluZCBUU0FQXG4iLCBfX0ZVTkNUSU9OX18pOwoJCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJmlydHRwLT50c2Fwcy0+aGJfc3BpbmxvY2ssIGZsYWdzKTsKCQlyZXR1cm4gTlVMTDsKCX0KCgkvKiBBbGxvY2F0ZSBhIG5ldyBpbnN0YW5jZSAqLwoJbmV3ID0ga21hbGxvYyhzaXplb2Yoc3RydWN0IHRzYXBfY2IpLCBHRlBfQVRPTUlDKTsKCWlmICghbmV3KSB7CgkJSVJEQV9ERUJVRygwLCAiJXMoKSwgdW5hYmxlIHRvIGttYWxsb2NcbiIsIF9fRlVOQ1RJT05fXyk7CgkJc3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmaXJ0dHAtPnRzYXBzLT5oYl9zcGlubG9jaywgZmxhZ3MpOwoJCXJldHVybiBOVUxMOwoJfQoJLyogRHVwICovCgltZW1jcHkobmV3LCBvcmlnLCBzaXplb2Yoc3RydWN0IHRzYXBfY2IpKTsKCgkvKiBXZSBkb24ndCBuZWVkIHRoZSBvbGQgaW5zdGFuY2UgYW55IG1vcmUgKi8KCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJmlydHRwLT50c2Fwcy0+aGJfc3BpbmxvY2ssIGZsYWdzKTsKCgkvKiBUcnkgdG8gZHVwIHRoZSBMU0FQIChtYXkgZmFpbCBpZiB3ZSB3ZXJlIHRvbyBzbG93KSAqLwoJbmV3LT5sc2FwID0gaXJsbXBfZHVwKG9yaWctPmxzYXAsIG5ldyk7CglpZiAoIW5ldy0+bHNhcCkgewoJCUlSREFfREVCVUcoMCwgIiVzKCksIGR1cCBmYWlsZWQhXG4iLCBfX0ZVTkNUSU9OX18pOwoJCWtmcmVlKG5ldyk7CgkJcmV0dXJuIE5VTEw7Cgl9CgoJLyogTm90IGV2ZXJ5dGhpbmcgc2hvdWxkIGJlIGNvcGllZCAqLwoJbmV3LT5ub3RpZnkuaW5zdGFuY2UgPSBpbnN0YW5jZTsKCWluaXRfdGltZXIoJm5ldy0+dG9kb190aW1lcik7CgoJc2tiX3F1ZXVlX2hlYWRfaW5pdCgmbmV3LT5yeF9xdWV1ZSk7Cglza2JfcXVldWVfaGVhZF9pbml0KCZuZXctPnR4X3F1ZXVlKTsKCXNrYl9xdWV1ZV9oZWFkX2luaXQoJm5ldy0+cnhfZnJhZ21lbnRzKTsKCgkvKiBUaGlzIGlzIGxvY2tlZCAqLwoJaGFzaGJpbl9pbnNlcnQoaXJ0dHAtPnRzYXBzLCAoaXJkYV9xdWV1ZV90ICopIG5ldywgKGxvbmcpIG5ldywgTlVMTCk7CgoJcmV0dXJuIG5ldzsKfQpFWFBPUlRfU1lNQk9MKGlydHRwX2R1cCk7CgovKgogKiBGdW5jdGlvbiBpcnR0cF9kaXNjb25uZWN0X3JlcXVlc3QgKHNlbGYpCiAqCiAqICAgIENsb3NlIHRoaXMgY29ubmVjdGlvbiBwbGVhc2UhIElmIHByaW9yaXR5IGlzIGhpZ2gsIHRoZSBxdWV1ZWQgZGF0YQogKiAgICBzZWdtZW50cywgaWYgYW55LCB3aWxsIGJlIGRlYWxsb2NhdGVkIGZpcnN0CiAqCiAqLwppbnQgaXJ0dHBfZGlzY29ubmVjdF9yZXF1ZXN0KHN0cnVjdCB0c2FwX2NiICpzZWxmLCBzdHJ1Y3Qgc2tfYnVmZiAqdXNlcmRhdGEsCgkJCSAgICAgaW50IHByaW9yaXR5KQp7CglpbnQgcmV0OwoKCUlSREFfQVNTRVJUKHNlbGYgIT0gTlVMTCwgcmV0dXJuIC0xOyk7CglJUkRBX0FTU0VSVChzZWxmLT5tYWdpYyA9PSBUVFBfVFNBUF9NQUdJQywgcmV0dXJuIC0xOyk7CgoJLyogQWxyZWFkeSBkaXNjb25uZWN0ZWQ/ICovCglpZiAoIXNlbGYtPmNvbm5lY3RlZCkgewoJCUlSREFfREVCVUcoNCwgIiVzKCksIGFscmVhZHkgZGlzY29ubmVjdGVkIVxuIiwgX19GVU5DVElPTl9fKTsKCQlpZiAodXNlcmRhdGEpCgkJCWRldl9rZnJlZV9za2IodXNlcmRhdGEpOwoJCXJldHVybiAtMTsKCX0KCgkvKiBEaXNjb25uZWN0IGFscmVhZHkgcGVuZGluZyA/CgkgKiBXZSBuZWVkIHRvIHVzZSBhbiBhdG9taWMgb3BlcmF0aW9uIHRvIHByZXZlbnQgcmVlbnRyeS4gVGhpcwoJICogZnVuY3Rpb24gbWF5IGJlIGNhbGxlZCBmcm9tIHZhcmlvdXMgY29udGV4dCwgbGlrZSB1c2VyLCB0aW1lcgoJICogZm9yIGZvbGxvd2luZyBhIGRpc2Nvbm5lY3RfaW5kaWNhdGlvbigpIChpLmUuIG5ldF9iaCkuCgkgKiBKZWFuIElJICovCglpZih0ZXN0X2FuZF9zZXRfYml0KDAsICZzZWxmLT5kaXNjb25uZWN0X3BlbmQpKSB7CgkJSVJEQV9ERUJVRygwLCAiJXMoKSwgZGlzY29ubmVjdCBhbHJlYWR5IHBlbmRpbmdcbiIsCgkJCSAgIF9fRlVOQ1RJT05fXyk7CgkJaWYgKHVzZXJkYXRhKQoJCQlkZXZfa2ZyZWVfc2tiKHVzZXJkYXRhKTsKCgkJLyogVHJ5IHRvIG1ha2Ugc29tZSBwcm9ncmVzcyAqLwoJCWlydHRwX3J1bl90eF9xdWV1ZShzZWxmKTsKCQlyZXR1cm4gLTE7Cgl9CgoJLyoKCSAqICBDaGVjayBpZiB0aGVyZSBpcyBzdGlsbCBkYXRhIHNlZ21lbnRzIGluIHRoZSB0cmFuc21pdCBxdWV1ZQoJICovCglpZiAoIXNrYl9xdWV1ZV9lbXB0eSgmc2VsZi0+dHhfcXVldWUpKSB7CgkJaWYgKHByaW9yaXR5ID09IFBfSElHSCkgewoJCQkvKgoJCQkgKiAgTm8gbmVlZCB0byBzZW5kIHRoZSBxdWV1ZWQgZGF0YSwgaWYgd2UgYXJlCgkJCSAqICBkaXNjb25uZWN0aW5nIHJpZ2h0IG5vdyBzaW5jZSB0aGUgZGF0YSB3aWxsCgkJCSAqICBub3QgaGF2ZSBhbnkgdXNhYmxlIGNvbm5lY3Rpb24gdG8gYmUgc2VudCBvbgoJCQkgKi8KCQkJSVJEQV9ERUJVRygxLCAiJXMoKTogSGlnaCBwcmlvcml0eSEhKClcbiIsIF9fRlVOQ1RJT05fXyk7CgkJCWlydHRwX2ZsdXNoX3F1ZXVlcyhzZWxmKTsKCQl9IGVsc2UgaWYgKHByaW9yaXR5ID09IFBfTk9STUFMKSB7CgkJCS8qCgkJCSAqICBNdXN0IGRlbGF5IGRpc2Nvbm5lY3QgdW50aWwgYWZ0ZXIgYWxsIGRhdGEgc2VnbWVudHMKCQkJICogIGhhdmUgYmVlbiBzZW50IGFuZCB0aGUgdHhfcXVldWUgaXMgZW1wdHkKCQkJICovCgkJCS8qIFdlJ2xsIHJldXNlIHRoaXMgb25lIGxhdGVyIGZvciB0aGUgZGlzY29ubmVjdCAqLwoJCQlzZWxmLT5kaXNjb25uZWN0X3NrYiA9IHVzZXJkYXRhOyAgLyogTWF5IGJlIE5VTEwgKi8KCgkJCWlydHRwX3J1bl90eF9xdWV1ZShzZWxmKTsKCgkJCWlydHRwX3N0YXJ0X3RvZG9fdGltZXIoc2VsZiwgSFovMTApOwoJCQlyZXR1cm4gLTE7CgkJfQoJfQoJLyogTm90ZSA6IHdlIGRvbid0IG5lZWQgdG8gY2hlY2sgaWYgc2VsZi0+cnhfcXVldWUgaXMgZnVsbCBhbmQgdGhlCgkgKiBzdGF0ZSBvZiBzZWxmLT5yeF9zZHVfYnVzeSBiZWNhdXNlIHRoZSBkaXNjb25uZWN0IHJlc3BvbnNlIHdpbGwKCSAqIGJlIHNlbnQgYXQgdGhlIExNUCBsZXZlbCAoc28gZXZlbiBpZiB0aGUgcGVlciBoYXMgaXRzIFR4IHF1ZXVlCgkgKiBmdWxsIG9mIGRhdGEpLiAtIEplYW4gSUkgKi8KCglJUkRBX0RFQlVHKDEsICIlcygpLCBEaXNjb25uZWN0aW5nIC4uLlxuIiwgX19GVU5DVElPTl9fKTsKCXNlbGYtPmNvbm5lY3RlZCA9IEZBTFNFOwoKCWlmICghdXNlcmRhdGEpIHsKCQlzdHJ1Y3Qgc2tfYnVmZiAqdHhfc2tiOwoJCXR4X3NrYiA9IGFsbG9jX3NrYig2NCwgR0ZQX0FUT01JQyk7CgkJaWYgKCF0eF9za2IpCgkJCXJldHVybiAtRU5PTUVNOwoKCQkvKgoJCSAqICBSZXNlcnZlIHNwYWNlIGZvciBNVVggYW5kIExBUCBoZWFkZXIKCQkgKi8KCQlza2JfcmVzZXJ2ZSh0eF9za2IsIFRUUF9NQVhfSEVBREVSKTsKCgkJdXNlcmRhdGEgPSB0eF9za2I7Cgl9CglyZXQgPSBpcmxtcF9kaXNjb25uZWN0X3JlcXVlc3Qoc2VsZi0+bHNhcCwgdXNlcmRhdGEpOwoKCS8qIFRoZSBkaXNjb25uZWN0IGlzIG5vIGxvbmdlciBwZW5kaW5nICovCgljbGVhcl9iaXQoMCwgJnNlbGYtPmRpc2Nvbm5lY3RfcGVuZCk7CS8qIEZBTFNFICovCgoJcmV0dXJuIHJldDsKfQpFWFBPUlRfU1lNQk9MKGlydHRwX2Rpc2Nvbm5lY3RfcmVxdWVzdCk7CgovKgogKiBGdW5jdGlvbiBpcnR0cF9kaXNjb25uZWN0X2luZGljYXRpb24gKHNlbGYsIHJlYXNvbikKICoKICogICAgRGlzY29ubmVjdCBpbmRpY2F0aW9uLCBUU0FQIGRpc2Nvbm5lY3RlZCBieSBwZWVyPwogKgogKi8Kdm9pZCBpcnR0cF9kaXNjb25uZWN0X2luZGljYXRpb24odm9pZCAqaW5zdGFuY2UsIHZvaWQgKnNhcCwgTE1fUkVBU09OIHJlYXNvbiwKCQkJCSBzdHJ1Y3Qgc2tfYnVmZiAqc2tiKQp7CglzdHJ1Y3QgdHNhcF9jYiAqc2VsZjsKCglJUkRBX0RFQlVHKDQsICIlcygpXG4iLCBfX0ZVTkNUSU9OX18pOwoKCXNlbGYgPSAoc3RydWN0IHRzYXBfY2IgKikgaW5zdGFuY2U7CgoJSVJEQV9BU1NFUlQoc2VsZiAhPSBOVUxMLCByZXR1cm47KTsKCUlSREFfQVNTRVJUKHNlbGYtPm1hZ2ljID09IFRUUF9UU0FQX01BR0lDLCByZXR1cm47KTsKCgkvKiBQcmV2ZW50IGhpZ2hlciBsYXllciB0byBzZW5kIG1vcmUgZGF0YSAqLwoJc2VsZi0+Y29ubmVjdGVkID0gRkFMU0U7CgoJLyogQ2hlY2sgaWYgY2xpZW50IGhhcyBhbHJlYWR5IHRyaWVkIHRvIGNsb3NlIHRoZSBUU0FQICovCglpZiAoc2VsZi0+Y2xvc2VfcGVuZCkgewoJCS8qIEluIHRoaXMgY2FzZSwgdGhlIGhpZ2hlciBsYXllciBpcyBwcm9iYWJseSBnb25lLiBEb24ndAoJCSAqIGJvdGhlciBpdCBhbmQgY2xlYW4gdXAgdGhlIHJlbWFpbnMgLSBKZWFuIElJICovCgkJaWYgKHNrYikKCQkJZGV2X2tmcmVlX3NrYihza2IpOwoJCWlydHRwX2Nsb3NlX3RzYXAoc2VsZik7CgkJcmV0dXJuOwoJfQoKCS8qIElmIHdlIGFyZSBoZXJlLCB3ZSBhc3N1bWUgdGhhdCBpcyB0aGUgaGlnaGVyIGxheWVyIGlzIHN0aWxsCgkgKiB3YWl0aW5nIGZvciB0aGUgZGlzY29ubmVjdCBub3RpZmljYXRpb24gYW5kIGFibGUgdG8gcHJvY2VzcyBpdCwKCSAqIGV2ZW4gaWYgaGUgdHJpZWQgdG8gZGlzY29ubmVjdC4gT3RoZXJ3aXNlLCBpdCB3b3VsZCBoYXZlIGFscmVhZHkKCSAqIGF0dGVtcHRlZCB0byBjbG9zZSB0aGUgdHNhcCBhbmQgc2VsZi0+Y2xvc2VfcGVuZCB3b3VsZCBiZSBUUlVFLgoJICogSmVhbiBJSSAqLwoKCS8qIE5vIG5lZWQgdG8gbm90aWZ5IHRoZSBjbGllbnQgaWYgaGFzIGFscmVhZHkgdHJpZWQgdG8gZGlzY29ubmVjdCAqLwoJaWYoc2VsZi0+bm90aWZ5LmRpc2Nvbm5lY3RfaW5kaWNhdGlvbikKCQlzZWxmLT5ub3RpZnkuZGlzY29ubmVjdF9pbmRpY2F0aW9uKHNlbGYtPm5vdGlmeS5pbnN0YW5jZSwgc2VsZiwKCQkJCQkJICAgcmVhc29uLCBza2IpOwoJZWxzZQoJCWlmIChza2IpCgkJCWRldl9rZnJlZV9za2Ioc2tiKTsKfQoKLyoKICogRnVuY3Rpb24gaXJ0dHBfZG9fZGF0YV9pbmRpY2F0aW9uIChzZWxmLCBza2IpCiAqCiAqICAgIFRyeSB0byBkZWxpdmVyIHJlYXNzZW1ibGVkIHNrYiB0byBsYXllciBhYm92ZSwgYW5kIHJlcXVldWUgaXQgaWYgdGhhdAogKiAgICBmb3Igc29tZSByZWFzb24gc2hvdWxkIGZhaWwuIFdlIG1hcmsgcnggc2R1IGFzIGJ1c3kgdG8gYXBwbHkgYmFjawogKiAgICBwcmVzc3VyZSBpcyBuZWNlc3NhcnkuCiAqLwpzdGF0aWMgdm9pZCBpcnR0cF9kb19kYXRhX2luZGljYXRpb24oc3RydWN0IHRzYXBfY2IgKnNlbGYsIHN0cnVjdCBza19idWZmICpza2IpCnsKCWludCBlcnI7CgoJLyogQ2hlY2sgaWYgY2xpZW50IGhhcyBhbHJlYWR5IGNsb3NlZCB0aGUgVFNBUCBhbmQgZ29uZSBhd2F5ICovCglpZiAoc2VsZi0+Y2xvc2VfcGVuZCkgewoJCWRldl9rZnJlZV9za2Ioc2tiKTsKCQlyZXR1cm47Cgl9CgoJZXJyID0gc2VsZi0+bm90aWZ5LmRhdGFfaW5kaWNhdGlvbihzZWxmLT5ub3RpZnkuaW5zdGFuY2UsIHNlbGYsIHNrYik7CgoJLyogVXN1YWxseSB0aGUgbGF5ZXIgYWJvdmUgd2lsbCBub3RpZnkgdGhhdCBpdCdzIGlucHV0IHF1ZXVlIGlzCgkgKiBzdGFydGluZyB0byBnZXQgZmlsbGVkIGJ5IHVzaW5nIHRoZSBmbG93IHJlcXVlc3QsIGJ1dCB0aGlzIG1heQoJICogYmUgZGlmZmljdWx0LCBzbyBpdCBjYW4gaW5zdGVhZCBqdXN0IHJlZnVzZSB0byBlYXQgaXQgYW5kIGp1c3QKCSAqIGdpdmUgYW4gZXJyb3IgYmFjawoJICovCglpZiAoZXJyKSB7CgkJSVJEQV9ERUJVRygwLCAiJXMoKSByZXF1ZXVlaW5nIHNrYiFcbiIsIF9fRlVOQ1RJT05fXyk7CgoJCS8qIE1ha2Ugc3VyZSB3ZSB0YWtlIGEgYnJlYWsgKi8KCQlzZWxmLT5yeF9zZHVfYnVzeSA9IFRSVUU7CgoJCS8qIE5lZWQgdG8gcHVzaCB0aGUgaGVhZGVyIGluIGFnYWluICovCgkJc2tiX3B1c2goc2tiLCBUVFBfSEVBREVSKTsKCQlza2ItPmRhdGFbMF0gPSAweDAwOyAvKiBNYWtlIHN1cmUgTU9SRSBiaXQgaXMgY2xlYXJlZCAqLwoKCQkvKiBQdXQgc2tiIGJhY2sgb24gcXVldWUgKi8KCQlza2JfcXVldWVfaGVhZCgmc2VsZi0+cnhfcXVldWUsIHNrYik7Cgl9Cn0KCi8qCiAqIEZ1bmN0aW9uIGlydHRwX3J1bl9yeF9xdWV1ZSAoc2VsZikKICoKICogICAgIENoZWNrIGlmIHdlIGhhdmUgYW55IGZyYW1lcyB0byBiZSB0cmFuc21pdHRlZCwgb3IgaWYgd2UgaGF2ZSBhbnkKICogICAgIGF2YWlsYWJsZSBjcmVkaXQgdG8gZ2l2ZSBhd2F5LgogKi8Kdm9pZCBpcnR0cF9ydW5fcnhfcXVldWUoc3RydWN0IHRzYXBfY2IgKnNlbGYpCnsKCXN0cnVjdCBza19idWZmICpza2I7CglpbnQgbW9yZSA9IDA7CgoJSVJEQV9ERUJVRygyLCAiJXMoKSBzZW5kPSVkLGF2YWlsPSVkLHJlbW90ZT0lZFxuIiwgX19GVU5DVElPTl9fLAoJCSAgIHNlbGYtPnNlbmRfY3JlZGl0LCBzZWxmLT5hdmFpbF9jcmVkaXQsIHNlbGYtPnJlbW90ZV9jcmVkaXQpOwoKCS8qIEdldCBleGNsdXNpdmUgYWNjZXNzIHRvIHRoZSByeCBxdWV1ZSwgb3RoZXJ3aXNlIGRvbid0IHRvdWNoIGl0ICovCglpZiAoaXJkYV9sb2NrKCZzZWxmLT5yeF9xdWV1ZV9sb2NrKSA9PSBGQUxTRSkKCQlyZXR1cm47CgoJLyoKCSAqICBSZWFzc2VtYmxlIGFsbCBmcmFtZXMgaW4gcmVjZWl2ZSBxdWV1ZSBhbmQgZGVsaXZlciB0aGVtCgkgKi8KCXdoaWxlICghc2VsZi0+cnhfc2R1X2J1c3kgJiYgKHNrYiA9IHNrYl9kZXF1ZXVlKCZzZWxmLT5yeF9xdWV1ZSkpKSB7CgkJLyogVGhpcyBiaXQgd2lsbCB0ZWxsIHVzIGlmIGl0J3MgdGhlIGxhc3QgZnJhZ21lbnQgb3Igbm90ICovCgkJbW9yZSA9IHNrYi0+ZGF0YVswXSAmIDB4ODA7CgoJCS8qIFJlbW92ZSBUVFAgaGVhZGVyICovCgkJc2tiX3B1bGwoc2tiLCBUVFBfSEVBREVSKTsKCgkJLyogQWRkIHRoZSBsZW5ndGggb2YgdGhlIHJlbWFpbmluZyBkYXRhICovCgkJc2VsZi0+cnhfc2R1X3NpemUgKz0gc2tiLT5sZW47CgoJCS8qCgkJICogSWYgU0FSIGlzIGRpc2FibGVkLCBvciB1c2VyIGhhcyByZXF1ZXN0ZWQgbm8gcmVhc3NlbWJseQoJCSAqIG9mIHJlY2VpdmVkIGZyYWdtZW50cyB0aGVuIHdlIGp1c3QgZGVsaXZlciB0aGVtCgkJICogaW1tZWRpYXRlbHkuIFRoaXMgY2FuIGJlIHJlcXVlc3RlZCBieSBjbGllbnRzIHRoYXQKCQkgKiBpbXBsZW1lbnRzIGJ5dGUgc3RyZWFtcyB3aXRob3V0IGFueSBtZXNzYWdlIGJvdW5kYXJpZXMKCQkgKi8KCQlpZiAoc2VsZi0+cnhfbWF4X3NkdV9zaXplID09IFRUUF9TQVJfRElTQUJMRSkgewoJCQlpcnR0cF9kb19kYXRhX2luZGljYXRpb24oc2VsZiwgc2tiKTsKCQkJc2VsZi0+cnhfc2R1X3NpemUgPSAwOwoKCQkJY29udGludWU7CgkJfQoKCQkvKiBDaGVjayBpZiB0aGlzIGlzIGEgZnJhZ21lbnQsIGFuZCBub3QgdGhlIGxhc3QgZnJhZ21lbnQgKi8KCQlpZiAobW9yZSkgewoJCQkvKgoJCQkgKiAgUXVldWUgdGhlIGZyYWdtZW50IGlmIHdlIHN0aWxsIGFyZSB3aXRoaW4gdGhlCgkJCSAqICBsaW1pdHMgb2YgdGhlIG1heGltdW0gc2l6ZSBvZiB0aGUgcnhfc2R1CgkJCSAqLwoJCQlpZiAoc2VsZi0+cnhfc2R1X3NpemUgPD0gc2VsZi0+cnhfbWF4X3NkdV9zaXplKSB7CgkJCQlJUkRBX0RFQlVHKDQsICIlcygpLCBxdWV1ZWluZyBmcmFnXG4iLAoJCQkJCSAgIF9fRlVOQ1RJT05fXyk7CgkJCQlza2JfcXVldWVfdGFpbCgmc2VsZi0+cnhfZnJhZ21lbnRzLCBza2IpOwoJCQl9IGVsc2UgewoJCQkJLyogRnJlZSB0aGUgcGFydCBvZiB0aGUgU0RVIHRoYXQgaXMgdG9vIGJpZyAqLwoJCQkJZGV2X2tmcmVlX3NrYihza2IpOwoJCQl9CgkJCWNvbnRpbnVlOwoJCX0KCQkvKgoJCSAqICBUaGlzIGlzIHRoZSBsYXN0IGZyYWdtZW50LCBzbyB0aW1lIHRvIHJlYXNzZW1ibGUhCgkJICovCgkJaWYgKChzZWxmLT5yeF9zZHVfc2l6ZSA8PSBzZWxmLT5yeF9tYXhfc2R1X3NpemUpIHx8CgkJICAgIChzZWxmLT5yeF9tYXhfc2R1X3NpemUgPT0gVFRQX1NBUl9VTkJPVU5EKSkKCQl7CgkJCS8qCgkJCSAqIEEgbGl0dGxlIG9wdGltaXppbmcuIE9ubHkgcXVldWUgdGhlIGZyYWdtZW50IGlmCgkJCSAqIHRoZXJlIGFyZSBvdGhlciBmcmFnbWVudHMuIFNpbmNlIGlmIHRoaXMgaXMgdGhlCgkJCSAqIGxhc3QgYW5kIG9ubHkgZnJhZ21lbnQsIHRoZXJlIGlzIG5vIG5lZWQgdG8KCQkJICogcmVhc3NlbWJsZSA6LSkKCQkJICovCgkJCWlmICghc2tiX3F1ZXVlX2VtcHR5KCZzZWxmLT5yeF9mcmFnbWVudHMpKSB7CgkJCQlza2JfcXVldWVfdGFpbCgmc2VsZi0+cnhfZnJhZ21lbnRzLAoJCQkJCSAgICAgICBza2IpOwoKCQkJCXNrYiA9IGlydHRwX3JlYXNzZW1ibGVfc2tiKHNlbGYpOwoJCQl9CgoJCQkvKiBOb3cgd2UgY2FuIGRlbGl2ZXIgdGhlIHJlYXNzZW1ibGVkIHNrYiAqLwoJCQlpcnR0cF9kb19kYXRhX2luZGljYXRpb24oc2VsZiwgc2tiKTsKCQl9IGVsc2UgewoJCQlJUkRBX0RFQlVHKDEsICIlcygpLCBUcnVuY2F0ZWQgZnJhbWVcbiIsIF9fRlVOQ1RJT05fXyk7CgoJCQkvKiBGcmVlIHRoZSBwYXJ0IG9mIHRoZSBTRFUgdGhhdCBpcyB0b28gYmlnICovCgkJCWRldl9rZnJlZV9za2Ioc2tiKTsKCgkJCS8qIERlbGl2ZXIgb25seSB0aGUgdmFsaWQgYnV0IHRydW5jYXRlZCBwYXJ0IG9mIFNEVSAqLwoJCQlza2IgPSBpcnR0cF9yZWFzc2VtYmxlX3NrYihzZWxmKTsKCgkJCWlydHRwX2RvX2RhdGFfaW5kaWNhdGlvbihzZWxmLCBza2IpOwoJCX0KCQlzZWxmLT5yeF9zZHVfc2l6ZSA9IDA7Cgl9CgoJLyoKCSAqIEl0J3Mgbm90IHRyaXZpYWwgdG8ga2VlcCB0cmFjayBvZiBob3cgbWFueSBjcmVkaXRzIGFyZSBhdmFpbGFibGUKCSAqIGJ5IGluY3JlbWVudGluZyBhdCBlYWNoIHBhY2tldCwgYmVjYXVzZSBkZWxpdmVyeSBtYXkgZmFpbAoJICogKGlydHRwX2RvX2RhdGFfaW5kaWNhdGlvbigpIG1heSByZXF1ZXVlIHRoZSBmcmFtZSkgYW5kIGJlY2F1c2UKCSAqIHdlIG5lZWQgdG8gdGFrZSBjYXJlIG9mIGZyYWdtZW50YXRpb24uCgkgKiBXZSB3YW50IHRoZSBvdGhlciBzaWRlIHRvIHNlbmQgdXAgdG8gaW5pdGlhbF9jcmVkaXQgcGFja2V0cy4KCSAqIFdlIGhhdmUgc29tZSBmcmFtZXMgaW4gb3VyIHF1ZXVlcywgYW5kIHdlIGhhdmUgYWxyZWFkeSBhbGxvd2VkIGl0CgkgKiB0byBzZW5kIHJlbW90ZV9jcmVkaXQuCgkgKiBObyBuZWVkIHRvIHNwaW5sb2NrLCB3cml0ZSBpcyBhdG9taWMgYW5kIHNlbGYgY29ycmVjdGluZy4uLgoJICogSmVhbiBJSQoJICovCglzZWxmLT5hdmFpbF9jcmVkaXQgPSAoc2VsZi0+aW5pdGlhbF9jcmVkaXQgLQoJCQkgICAgICAoc2VsZi0+cmVtb3RlX2NyZWRpdCArCgkJCSAgICAgICBza2JfcXVldWVfbGVuKCZzZWxmLT5yeF9xdWV1ZSkgKwoJCQkgICAgICAgc2tiX3F1ZXVlX2xlbigmc2VsZi0+cnhfZnJhZ21lbnRzKSkpOwoKCS8qIERvIHdlIGhhdmUgdG9vIG11Y2ggY3JlZGl0cyB0byBzZW5kIHRvIHBlZXIgPyAqLwoJaWYgKChzZWxmLT5yZW1vdGVfY3JlZGl0IDw9IFRUUF9SWF9NSU5fQ1JFRElUKSAmJgoJICAgIChzZWxmLT5hdmFpbF9jcmVkaXQgPiAwKSkgewoJCS8qIFNlbmQgZXhwbGljaXQgY3JlZGl0IGZyYW1lICovCgkJaXJ0dHBfZ2l2ZV9jcmVkaXQoc2VsZik7CgkJLyogTm90ZSA6IGRvICpOT1QqIGNoZWNrIGlmIHR4X3F1ZXVlIGlzIG5vbi1lbXB0eSwgdGhhdAoJCSAqIHdpbGwgcHJvZHVjZSBkZWFkbG9ja3MuIEkgcmVwZWF0IDogc2VuZCBhIGNyZWRpdCBmcmFtZQoJCSAqIGV2ZW4gaWYgd2UgaGF2ZSBzb21ldGhpbmcgdG8gc2VuZCBpbiBvdXIgVHggcXVldWUuCgkJICogSWYgd2UgaGF2ZSBjcmVkaXRzLCBpdCBtZWFucyB0aGF0IG91ciBUeCBxdWV1ZSBpcyBibG9ja2VkLgoJCSAqCgkJICogTGV0J3Mgc3VwcG9zZSB0aGUgcGVlciBjYW4ndCBrZWVwIHVwIHdpdGggb3VyIFR4LiBIZSB3aWxsCgkJICogZmxvdyBjb250cm9sIHVzIGJ5IG5vdCBzZW5kaW5nIHVzIGFueSBjcmVkaXRzLCBhbmQgd2UKCQkgKiB3aWxsIHN0b3AgVHggYW5kIHN0YXJ0IGFjY3VtdWxhdGluZyBjcmVkaXRzIGhlcmUuCgkJICogVXAgdG8gdGhlIHBvaW50IHdoZXJlIHRoZSBwZWVyIHdpbGwgc3RvcCBpdHMgVHggcXVldWUsCgkJICogZm9yIGxhY2sgb2YgY3JlZGl0cy4KCQkgKiBMZXQncyBhc3N1bWUgdGhlIHBlZXIgYXBwbGljYXRpb24gaXMgc2luZ2xlIHRocmVhZGVkLgoJCSAqIEl0IHdpbGwgYmxvY2sgb24gVHggYW5kIG5ldmVyIGNvbnN1bWUgYW55IFJ4IGJ1ZmZlci4KCQkgKiBEZWFkbG9jay4gR3VhcmFudGVlZC4gLSBKZWFuIElJCgkJICovCgl9CgoJLyogUmVzZXQgbG9jayAqLwoJc2VsZi0+cnhfcXVldWVfbG9jayA9IDA7Cn0KCiNpZmRlZiBDT05GSUdfUFJPQ19GUwpzdHJ1Y3QgaXJ0dHBfaXRlcl9zdGF0ZSB7CglpbnQgaWQ7Cn07CgpzdGF0aWMgdm9pZCAqaXJ0dHBfc2VxX3N0YXJ0KHN0cnVjdCBzZXFfZmlsZSAqc2VxLCBsb2ZmX3QgKnBvcykKewoJc3RydWN0IGlydHRwX2l0ZXJfc3RhdGUgKml0ZXIgPSBzZXEtPnByaXZhdGU7CglzdHJ1Y3QgdHNhcF9jYiAqc2VsZjsKCgkvKiBQcm90ZWN0IG91ciBhY2Nlc3MgdG8gdGhlIHRzYXAgbGlzdCAqLwoJc3Bpbl9sb2NrX2lycSgmaXJ0dHAtPnRzYXBzLT5oYl9zcGlubG9jayk7CglpdGVyLT5pZCA9IDA7CgoJZm9yIChzZWxmID0gKHN0cnVjdCB0c2FwX2NiICopIGhhc2hiaW5fZ2V0X2ZpcnN0KGlydHRwLT50c2Fwcyk7IAoJICAgICBzZWxmICE9IE5VTEw7CgkgICAgIHNlbGYgPSAoc3RydWN0IHRzYXBfY2IgKikgaGFzaGJpbl9nZXRfbmV4dChpcnR0cC0+dHNhcHMpKSB7CgkJaWYgKGl0ZXItPmlkID09ICpwb3MpCgkJCWJyZWFrOwoJCSsraXRlci0+aWQ7Cgl9CgkJCglyZXR1cm4gc2VsZjsKfQoKc3RhdGljIHZvaWQgKmlydHRwX3NlcV9uZXh0KHN0cnVjdCBzZXFfZmlsZSAqc2VxLCB2b2lkICp2LCBsb2ZmX3QgKnBvcykKewoJc3RydWN0IGlydHRwX2l0ZXJfc3RhdGUgKml0ZXIgPSBzZXEtPnByaXZhdGU7CgoJKysqcG9zOwoJKytpdGVyLT5pZDsKCXJldHVybiAodm9pZCAqKSBoYXNoYmluX2dldF9uZXh0KGlydHRwLT50c2Fwcyk7Cn0KCnN0YXRpYyB2b2lkIGlydHRwX3NlcV9zdG9wKHN0cnVjdCBzZXFfZmlsZSAqc2VxLCB2b2lkICp2KQp7CglzcGluX3VubG9ja19pcnEoJmlydHRwLT50c2Fwcy0+aGJfc3BpbmxvY2spOwp9CgpzdGF0aWMgaW50IGlydHRwX3NlcV9zaG93KHN0cnVjdCBzZXFfZmlsZSAqc2VxLCB2b2lkICp2KQp7Cgljb25zdCBzdHJ1Y3QgaXJ0dHBfaXRlcl9zdGF0ZSAqaXRlciA9IHNlcS0+cHJpdmF0ZTsKCWNvbnN0IHN0cnVjdCB0c2FwX2NiICpzZWxmID0gdjsKCglzZXFfcHJpbnRmKHNlcSwgIlRTQVAgJWQsICIsIGl0ZXItPmlkKTsKCXNlcV9wcmludGYoc2VxLCAic3RzYXBfc2VsOiAlMDJ4LCAiLAoJCSAgIHNlbGYtPnN0c2FwX3NlbCk7CglzZXFfcHJpbnRmKHNlcSwgImR0c2FwX3NlbDogJTAyeFxuIiwKCQkgICBzZWxmLT5kdHNhcF9zZWwpOwoJc2VxX3ByaW50ZihzZXEsICIgIGNvbm5lY3RlZDogJXMsICIsCgkJICAgc2VsZi0+Y29ubmVjdGVkPyAiVFJVRSI6IkZBTFNFIik7CglzZXFfcHJpbnRmKHNlcSwgImF2YWlsIGNyZWRpdDogJWQsICIsCgkJICAgc2VsZi0+YXZhaWxfY3JlZGl0KTsKCXNlcV9wcmludGYoc2VxLCAicmVtb3RlIGNyZWRpdDogJWQsICIsCgkJICAgc2VsZi0+cmVtb3RlX2NyZWRpdCk7CglzZXFfcHJpbnRmKHNlcSwgInNlbmQgY3JlZGl0OiAlZFxuIiwKCQkgICBzZWxmLT5zZW5kX2NyZWRpdCk7CglzZXFfcHJpbnRmKHNlcSwgIiAgdHggcGFja2V0czogJWxkLCAiLAoJCSAgIHNlbGYtPnN0YXRzLnR4X3BhY2tldHMpOwoJc2VxX3ByaW50ZihzZXEsICJyeCBwYWNrZXRzOiAlbGQsICIsCgkJICAgc2VsZi0+c3RhdHMucnhfcGFja2V0cyk7CglzZXFfcHJpbnRmKHNlcSwgInR4X3F1ZXVlIGxlbjogJWQgIiwKCQkgICBza2JfcXVldWVfbGVuKCZzZWxmLT50eF9xdWV1ZSkpOwoJc2VxX3ByaW50ZihzZXEsICJyeF9xdWV1ZSBsZW46ICVkXG4iLAoJCSAgIHNrYl9xdWV1ZV9sZW4oJnNlbGYtPnJ4X3F1ZXVlKSk7CglzZXFfcHJpbnRmKHNlcSwgIiAgdHhfc2R1X2J1c3k6ICVzLCAiLAoJCSAgIHNlbGYtPnR4X3NkdV9idXN5PyAiVFJVRSI6IkZBTFNFIik7CglzZXFfcHJpbnRmKHNlcSwgInJ4X3NkdV9idXN5OiAlc1xuIiwKCQkgICBzZWxmLT5yeF9zZHVfYnVzeT8gIlRSVUUiOiJGQUxTRSIpOwoJc2VxX3ByaW50ZihzZXEsICIgIG1heF9zZWdfc2l6ZTogJWQsICIsCgkJICAgc2VsZi0+bWF4X3NlZ19zaXplKTsKCXNlcV9wcmludGYoc2VxLCAidHhfbWF4X3NkdV9zaXplOiAlZCwgIiwKCQkgICBzZWxmLT50eF9tYXhfc2R1X3NpemUpOwoJc2VxX3ByaW50ZihzZXEsICJyeF9tYXhfc2R1X3NpemU6ICVkXG4iLAoJCSAgIHNlbGYtPnJ4X21heF9zZHVfc2l6ZSk7CgoJc2VxX3ByaW50ZihzZXEsICIgIFVzZWQgYnkgKCVzKVxuXG4iLAoJCSAgIHNlbGYtPm5vdGlmeS5uYW1lKTsKCXJldHVybiAwOwp9CgpzdGF0aWMgc3RydWN0IHNlcV9vcGVyYXRpb25zIGlydHRwX3NlcV9vcHMgPSB7Cgkuc3RhcnQgID0gaXJ0dHBfc2VxX3N0YXJ0LAoJLm5leHQgICA9IGlydHRwX3NlcV9uZXh0LAoJLnN0b3AgICA9IGlydHRwX3NlcV9zdG9wLAoJLnNob3cgICA9IGlydHRwX3NlcV9zaG93LAp9OwoKc3RhdGljIGludCBpcnR0cF9zZXFfb3BlbihzdHJ1Y3QgaW5vZGUgKmlub2RlLCBzdHJ1Y3QgZmlsZSAqZmlsZSkKewoJc3RydWN0IHNlcV9maWxlICpzZXE7CglpbnQgcmMgPSAtRU5PTUVNOwoJc3RydWN0IGlydHRwX2l0ZXJfc3RhdGUgKnM7CgoJcyA9IGttYWxsb2Moc2l6ZW9mKCpzKSwgR0ZQX0tFUk5FTCk7CglpZiAoIXMpCgkJZ290byBvdXQ7CgoJcmMgPSBzZXFfb3BlbihmaWxlLCAmaXJ0dHBfc2VxX29wcyk7CglpZiAocmMpCgkJZ290byBvdXRfa2ZyZWU7CgoJc2VxCSAgICAgPSBmaWxlLT5wcml2YXRlX2RhdGE7CglzZXEtPnByaXZhdGUgPSBzOwoJbWVtc2V0KHMsIDAsIHNpemVvZigqcykpOwpvdXQ6CglyZXR1cm4gcmM7Cm91dF9rZnJlZToKCWtmcmVlKHMpOwoJZ290byBvdXQ7Cn0KCnN0cnVjdCBmaWxlX29wZXJhdGlvbnMgaXJ0dHBfc2VxX2ZvcHMgPSB7Cgkub3duZXIJCT0gVEhJU19NT0RVTEUsCgkub3BlbiAgICAgICAgICAgPSBpcnR0cF9zZXFfb3BlbiwKCS5yZWFkICAgICAgICAgICA9IHNlcV9yZWFkLAoJLmxsc2VlayAgICAgICAgID0gc2VxX2xzZWVrLAoJLnJlbGVhc2UJPSBzZXFfcmVsZWFzZV9wcml2YXRlLAp9OwoKI2VuZGlmIC8qIFBST0NfRlMgKi8K