LyoKICogUGVyZm9ybWFuY2UgZXZlbnRzIGNvcmUgY29kZToKICoKICogIENvcHlyaWdodCAoQykgMjAwOCBUaG9tYXMgR2xlaXhuZXIgPHRnbHhAbGludXRyb25peC5kZT4KICogIENvcHlyaWdodCAoQykgMjAwOC0yMDA5IFJlZCBIYXQsIEluYy4sIEluZ28gTW9sbmFyCiAqICBDb3B5cmlnaHQgKEMpIDIwMDgtMjAwOSBSZWQgSGF0LCBJbmMuLCBQZXRlciBaaWpsc3RyYSA8cHppamxzdHJAcmVkaGF0LmNvbT4KICogIENvcHlyaWdodCAgqSAgMjAwOSBQYXVsIE1hY2tlcnJhcywgSUJNIENvcnAuIDxwYXVsdXNAYXUxLmlibS5jb20+CiAqCiAqIEZvciBsaWNlbnNpbmcgZGV0YWlscyBzZWUga2VybmVsLWJhc2UvQ09QWUlORwogKi8KCiNpbmNsdWRlIDxsaW51eC9mcy5oPgojaW5jbHVkZSA8bGludXgvbW0uaD4KI2luY2x1ZGUgPGxpbnV4L2NwdS5oPgojaW5jbHVkZSA8bGludXgvc21wLmg+CiNpbmNsdWRlIDxsaW51eC9maWxlLmg+CiNpbmNsdWRlIDxsaW51eC9wb2xsLmg+CiNpbmNsdWRlIDxsaW51eC9zeXNmcy5oPgojaW5jbHVkZSA8bGludXgvZGNhY2hlLmg+CiNpbmNsdWRlIDxsaW51eC9wZXJjcHUuaD4KI2luY2x1ZGUgPGxpbnV4L3B0cmFjZS5oPgojaW5jbHVkZSA8bGludXgvdm1zdGF0Lmg+CiNpbmNsdWRlIDxsaW51eC92bWFsbG9jLmg+CiNpbmNsdWRlIDxsaW51eC9oYXJkaXJxLmg+CiNpbmNsdWRlIDxsaW51eC9yY3VsaXN0Lmg+CiNpbmNsdWRlIDxsaW51eC91YWNjZXNzLmg+CiNpbmNsdWRlIDxsaW51eC9zeXNjYWxscy5oPgojaW5jbHVkZSA8bGludXgvYW5vbl9pbm9kZXMuaD4KI2luY2x1ZGUgPGxpbnV4L2tlcm5lbF9zdGF0Lmg+CiNpbmNsdWRlIDxsaW51eC9wZXJmX2V2ZW50Lmg+CgojaW5jbHVkZSA8YXNtL2lycV9yZWdzLmg+CgovKgogKiBFYWNoIENQVSBoYXMgYSBsaXN0IG9mIHBlciBDUFUgZXZlbnRzOgogKi8KREVGSU5FX1BFUl9DUFUoc3RydWN0IHBlcmZfY3B1X2NvbnRleHQsIHBlcmZfY3B1X2NvbnRleHQpOwoKaW50IHBlcmZfbWF4X2V2ZW50cyBfX3JlYWRfbW9zdGx5ID0gMTsKc3RhdGljIGludCBwZXJmX3Jlc2VydmVkX3BlcmNwdSBfX3JlYWRfbW9zdGx5OwpzdGF0aWMgaW50IHBlcmZfb3ZlcmNvbW1pdCBfX3JlYWRfbW9zdGx5ID0gMTsKCnN0YXRpYyBhdG9taWNfdCBucl9ldmVudHMgX19yZWFkX21vc3RseTsKc3RhdGljIGF0b21pY190IG5yX21tYXBfZXZlbnRzIF9fcmVhZF9tb3N0bHk7CnN0YXRpYyBhdG9taWNfdCBucl9jb21tX2V2ZW50cyBfX3JlYWRfbW9zdGx5OwpzdGF0aWMgYXRvbWljX3QgbnJfdGFza19ldmVudHMgX19yZWFkX21vc3RseTsKCi8qCiAqIHBlcmYgZXZlbnQgcGFyYW5vaWEgbGV2ZWw6CiAqICAtMSAtIG5vdCBwYXJhbm9pZCBhdCBhbGwKICogICAwIC0gZGlzYWxsb3cgcmF3IHRyYWNlcG9pbnQgYWNjZXNzIGZvciB1bnByaXYKICogICAxIC0gZGlzYWxsb3cgY3B1IGV2ZW50cyBmb3IgdW5wcml2CiAqICAgMiAtIGRpc2FsbG93IGtlcm5lbCBwcm9maWxpbmcgZm9yIHVucHJpdgogKi8KaW50IHN5c2N0bF9wZXJmX2V2ZW50X3BhcmFub2lkIF9fcmVhZF9tb3N0bHkgPSAxOwoKc3RhdGljIGlubGluZSBib29sIHBlcmZfcGFyYW5vaWRfdHJhY2Vwb2ludF9yYXcodm9pZCkKewoJcmV0dXJuIHN5c2N0bF9wZXJmX2V2ZW50X3BhcmFub2lkID4gLTE7Cn0KCnN0YXRpYyBpbmxpbmUgYm9vbCBwZXJmX3BhcmFub2lkX2NwdSh2b2lkKQp7CglyZXR1cm4gc3lzY3RsX3BlcmZfZXZlbnRfcGFyYW5vaWQgPiAwOwp9CgpzdGF0aWMgaW5saW5lIGJvb2wgcGVyZl9wYXJhbm9pZF9rZXJuZWwodm9pZCkKewoJcmV0dXJuIHN5c2N0bF9wZXJmX2V2ZW50X3BhcmFub2lkID4gMTsKfQoKaW50IHN5c2N0bF9wZXJmX2V2ZW50X21sb2NrIF9fcmVhZF9tb3N0bHkgPSA1MTI7IC8qICdmcmVlJyBrYiBwZXIgdXNlciAqLwoKLyoKICogbWF4IHBlcmYgZXZlbnQgc2FtcGxlIHJhdGUKICovCmludCBzeXNjdGxfcGVyZl9ldmVudF9zYW1wbGVfcmF0ZSBfX3JlYWRfbW9zdGx5ID0gMTAwMDAwOwoKc3RhdGljIGF0b21pYzY0X3QgcGVyZl9ldmVudF9pZDsKCi8qCiAqIExvY2sgZm9yIChzeXNhZG1pbi1jb25maWd1cmFibGUpIGV2ZW50IHJlc2VydmF0aW9uczoKICovCnN0YXRpYyBERUZJTkVfU1BJTkxPQ0socGVyZl9yZXNvdXJjZV9sb2NrKTsKCi8qCiAqIEFyY2hpdGVjdHVyZSBwcm92aWRlZCBBUElzIC0gd2VhayBhbGlhc2VzOgogKi8KZXh0ZXJuIF9fd2VhayBjb25zdCBzdHJ1Y3QgcG11ICpod19wZXJmX2V2ZW50X2luaXQoc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50KQp7CglyZXR1cm4gTlVMTDsKfQoKdm9pZCBfX3dlYWsgaHdfcGVyZl9kaXNhYmxlKHZvaWQpCQl7IGJhcnJpZXIoKTsgfQp2b2lkIF9fd2VhayBod19wZXJmX2VuYWJsZSh2b2lkKQkJeyBiYXJyaWVyKCk7IH0KCnZvaWQgX193ZWFrIGh3X3BlcmZfZXZlbnRfc2V0dXAoaW50IGNwdSkJeyBiYXJyaWVyKCk7IH0Kdm9pZCBfX3dlYWsgaHdfcGVyZl9ldmVudF9zZXR1cF9vbmxpbmUoaW50IGNwdSkJeyBiYXJyaWVyKCk7IH0KCmludCBfX3dlYWsKaHdfcGVyZl9ncm91cF9zY2hlZF9pbihzdHJ1Y3QgcGVyZl9ldmVudCAqZ3JvdXBfbGVhZGVyLAoJICAgICAgIHN0cnVjdCBwZXJmX2NwdV9jb250ZXh0ICpjcHVjdHgsCgkgICAgICAgc3RydWN0IHBlcmZfZXZlbnRfY29udGV4dCAqY3R4LCBpbnQgY3B1KQp7CglyZXR1cm4gMDsKfQoKdm9pZCBfX3dlYWsgcGVyZl9ldmVudF9wcmludF9kZWJ1Zyh2b2lkKQl7IH0KCnN0YXRpYyBERUZJTkVfUEVSX0NQVShpbnQsIHBlcmZfZGlzYWJsZV9jb3VudCk7Cgp2b2lkIF9fcGVyZl9kaXNhYmxlKHZvaWQpCnsKCV9fZ2V0X2NwdV92YXIocGVyZl9kaXNhYmxlX2NvdW50KSsrOwp9Cgpib29sIF9fcGVyZl9lbmFibGUodm9pZCkKewoJcmV0dXJuICEtLV9fZ2V0X2NwdV92YXIocGVyZl9kaXNhYmxlX2NvdW50KTsKfQoKdm9pZCBwZXJmX2Rpc2FibGUodm9pZCkKewoJX19wZXJmX2Rpc2FibGUoKTsKCWh3X3BlcmZfZGlzYWJsZSgpOwp9Cgp2b2lkIHBlcmZfZW5hYmxlKHZvaWQpCnsKCWlmIChfX3BlcmZfZW5hYmxlKCkpCgkJaHdfcGVyZl9lbmFibGUoKTsKfQoKc3RhdGljIHZvaWQgZ2V0X2N0eChzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0ICpjdHgpCnsKCVdBUk5fT04oIWF0b21pY19pbmNfbm90X3plcm8oJmN0eC0+cmVmY291bnQpKTsKfQoKc3RhdGljIHZvaWQgZnJlZV9jdHgoc3RydWN0IHJjdV9oZWFkICpoZWFkKQp7CglzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0ICpjdHg7CgoJY3R4ID0gY29udGFpbmVyX29mKGhlYWQsIHN0cnVjdCBwZXJmX2V2ZW50X2NvbnRleHQsIHJjdV9oZWFkKTsKCWtmcmVlKGN0eCk7Cn0KCnN0YXRpYyB2b2lkIHB1dF9jdHgoc3RydWN0IHBlcmZfZXZlbnRfY29udGV4dCAqY3R4KQp7CglpZiAoYXRvbWljX2RlY19hbmRfdGVzdCgmY3R4LT5yZWZjb3VudCkpIHsKCQlpZiAoY3R4LT5wYXJlbnRfY3R4KQoJCQlwdXRfY3R4KGN0eC0+cGFyZW50X2N0eCk7CgkJaWYgKGN0eC0+dGFzaykKCQkJcHV0X3Rhc2tfc3RydWN0KGN0eC0+dGFzayk7CgkJY2FsbF9yY3UoJmN0eC0+cmN1X2hlYWQsIGZyZWVfY3R4KTsKCX0KfQoKc3RhdGljIHZvaWQgdW5jbG9uZV9jdHgoc3RydWN0IHBlcmZfZXZlbnRfY29udGV4dCAqY3R4KQp7CglpZiAoY3R4LT5wYXJlbnRfY3R4KSB7CgkJcHV0X2N0eChjdHgtPnBhcmVudF9jdHgpOwoJCWN0eC0+cGFyZW50X2N0eCA9IE5VTEw7Cgl9Cn0KCi8qCiAqIElmIHdlIGluaGVyaXQgZXZlbnRzIHdlIHdhbnQgdG8gcmV0dXJuIHRoZSBwYXJlbnQgZXZlbnQgaWQKICogdG8gdXNlcnNwYWNlLgogKi8Kc3RhdGljIHU2NCBwcmltYXJ5X2V2ZW50X2lkKHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCkKewoJdTY0IGlkID0gZXZlbnQtPmlkOwoKCWlmIChldmVudC0+cGFyZW50KQoJCWlkID0gZXZlbnQtPnBhcmVudC0+aWQ7CgoJcmV0dXJuIGlkOwp9CgovKgogKiBHZXQgdGhlIHBlcmZfZXZlbnRfY29udGV4dCBmb3IgYSB0YXNrIGFuZCBsb2NrIGl0LgogKiBUaGlzIGhhcyB0byBjb3BlIHdpdGggd2l0aCB0aGUgZmFjdCB0aGF0IHVudGlsIGl0IGlzIGxvY2tlZCwKICogdGhlIGNvbnRleHQgY291bGQgZ2V0IG1vdmVkIHRvIGFub3RoZXIgdGFzay4KICovCnN0YXRpYyBzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0ICoKcGVyZl9sb2NrX3Rhc2tfY29udGV4dChzdHJ1Y3QgdGFza19zdHJ1Y3QgKnRhc2ssIHVuc2lnbmVkIGxvbmcgKmZsYWdzKQp7CglzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0ICpjdHg7CgoJcmN1X3JlYWRfbG9jaygpOwogcmV0cnk6CgljdHggPSByY3VfZGVyZWZlcmVuY2UodGFzay0+cGVyZl9ldmVudF9jdHhwKTsKCWlmIChjdHgpIHsKCQkvKgoJCSAqIElmIHRoaXMgY29udGV4dCBpcyBhIGNsb25lIG9mIGFub3RoZXIsIGl0IG1pZ2h0CgkJICogZ2V0IHN3YXBwZWQgZm9yIGFub3RoZXIgdW5kZXJuZWF0aCB1cyBieQoJCSAqIHBlcmZfZXZlbnRfdGFza19zY2hlZF9vdXQsIHRob3VnaCB0aGUKCQkgKiByY3VfcmVhZF9sb2NrKCkgcHJvdGVjdHMgdXMgZnJvbSBhbnkgY29udGV4dAoJCSAqIGdldHRpbmcgZnJlZWQuICBMb2NrIHRoZSBjb250ZXh0IGFuZCBjaGVjayBpZiBpdAoJCSAqIGdvdCBzd2FwcGVkIGJlZm9yZSB3ZSBjb3VsZCBnZXQgdGhlIGxvY2ssIGFuZCByZXRyeQoJCSAqIGlmIHNvLiAgSWYgd2UgbG9ja2VkIHRoZSByaWdodCBjb250ZXh0LCB0aGVuIGl0CgkJICogY2FuJ3QgZ2V0IHN3YXBwZWQgb24gdXMgYW55IG1vcmUuCgkJICovCgkJc3Bpbl9sb2NrX2lycXNhdmUoJmN0eC0+bG9jaywgKmZsYWdzKTsKCQlpZiAoY3R4ICE9IHJjdV9kZXJlZmVyZW5jZSh0YXNrLT5wZXJmX2V2ZW50X2N0eHApKSB7CgkJCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJmN0eC0+bG9jaywgKmZsYWdzKTsKCQkJZ290byByZXRyeTsKCQl9CgoJCWlmICghYXRvbWljX2luY19ub3RfemVybygmY3R4LT5yZWZjb3VudCkpIHsKCQkJc3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmY3R4LT5sb2NrLCAqZmxhZ3MpOwoJCQljdHggPSBOVUxMOwoJCX0KCX0KCXJjdV9yZWFkX3VubG9jaygpOwoJcmV0dXJuIGN0eDsKfQoKLyoKICogR2V0IHRoZSBjb250ZXh0IGZvciBhIHRhc2sgYW5kIGluY3JlbWVudCBpdHMgcGluX2NvdW50IHNvIGl0CiAqIGNhbid0IGdldCBzd2FwcGVkIHRvIGFub3RoZXIgdGFzay4gIFRoaXMgYWxzbyBpbmNyZW1lbnRzIGl0cwogKiByZWZlcmVuY2UgY291bnQgc28gdGhhdCB0aGUgY29udGV4dCBjYW4ndCBnZXQgZnJlZWQuCiAqLwpzdGF0aWMgc3RydWN0IHBlcmZfZXZlbnRfY29udGV4dCAqcGVyZl9waW5fdGFza19jb250ZXh0KHN0cnVjdCB0YXNrX3N0cnVjdCAqdGFzaykKewoJc3RydWN0IHBlcmZfZXZlbnRfY29udGV4dCAqY3R4OwoJdW5zaWduZWQgbG9uZyBmbGFnczsKCgljdHggPSBwZXJmX2xvY2tfdGFza19jb250ZXh0KHRhc2ssICZmbGFncyk7CglpZiAoY3R4KSB7CgkJKytjdHgtPnBpbl9jb3VudDsKCQlzcGluX3VubG9ja19pcnFyZXN0b3JlKCZjdHgtPmxvY2ssIGZsYWdzKTsKCX0KCXJldHVybiBjdHg7Cn0KCnN0YXRpYyB2b2lkIHBlcmZfdW5waW5fY29udGV4dChzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0ICpjdHgpCnsKCXVuc2lnbmVkIGxvbmcgZmxhZ3M7CgoJc3Bpbl9sb2NrX2lycXNhdmUoJmN0eC0+bG9jaywgZmxhZ3MpOwoJLS1jdHgtPnBpbl9jb3VudDsKCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJmN0eC0+bG9jaywgZmxhZ3MpOwoJcHV0X2N0eChjdHgpOwp9CgovKgogKiBBZGQgYSBldmVudCBmcm9tIHRoZSBsaXN0cyBmb3IgaXRzIGNvbnRleHQuCiAqIE11c3QgYmUgY2FsbGVkIHdpdGggY3R4LT5tdXRleCBhbmQgY3R4LT5sb2NrIGhlbGQuCiAqLwpzdGF0aWMgdm9pZApsaXN0X2FkZF9ldmVudChzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQsIHN0cnVjdCBwZXJmX2V2ZW50X2NvbnRleHQgKmN0eCkKewoJc3RydWN0IHBlcmZfZXZlbnQgKmdyb3VwX2xlYWRlciA9IGV2ZW50LT5ncm91cF9sZWFkZXI7CgoJLyoKCSAqIERlcGVuZGluZyBvbiB3aGV0aGVyIGl0IGlzIGEgc3RhbmRhbG9uZSBvciBzaWJsaW5nIGV2ZW50LAoJICogYWRkIGl0IHN0cmFpZ2h0IHRvIHRoZSBjb250ZXh0J3MgZXZlbnQgbGlzdCwgb3IgdG8gdGhlIGdyb3VwCgkgKiBsZWFkZXIncyBzaWJsaW5nIGxpc3Q6CgkgKi8KCWlmIChncm91cF9sZWFkZXIgPT0gZXZlbnQpCgkJbGlzdF9hZGRfdGFpbCgmZXZlbnQtPmdyb3VwX2VudHJ5LCAmY3R4LT5ncm91cF9saXN0KTsKCWVsc2UgewoJCWxpc3RfYWRkX3RhaWwoJmV2ZW50LT5ncm91cF9lbnRyeSwgJmdyb3VwX2xlYWRlci0+c2libGluZ19saXN0KTsKCQlncm91cF9sZWFkZXItPm5yX3NpYmxpbmdzKys7Cgl9CgoJbGlzdF9hZGRfcmN1KCZldmVudC0+ZXZlbnRfZW50cnksICZjdHgtPmV2ZW50X2xpc3QpOwoJY3R4LT5ucl9ldmVudHMrKzsKCWlmIChldmVudC0+YXR0ci5pbmhlcml0X3N0YXQpCgkJY3R4LT5ucl9zdGF0Kys7Cn0KCi8qCiAqIFJlbW92ZSBhIGV2ZW50IGZyb20gdGhlIGxpc3RzIGZvciBpdHMgY29udGV4dC4KICogTXVzdCBiZSBjYWxsZWQgd2l0aCBjdHgtPm11dGV4IGFuZCBjdHgtPmxvY2sgaGVsZC4KICovCnN0YXRpYyB2b2lkCmxpc3RfZGVsX2V2ZW50KHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCwgc3RydWN0IHBlcmZfZXZlbnRfY29udGV4dCAqY3R4KQp7CglzdHJ1Y3QgcGVyZl9ldmVudCAqc2libGluZywgKnRtcDsKCglpZiAobGlzdF9lbXB0eSgmZXZlbnQtPmdyb3VwX2VudHJ5KSkKCQlyZXR1cm47CgljdHgtPm5yX2V2ZW50cy0tOwoJaWYgKGV2ZW50LT5hdHRyLmluaGVyaXRfc3RhdCkKCQljdHgtPm5yX3N0YXQtLTsKCglsaXN0X2RlbF9pbml0KCZldmVudC0+Z3JvdXBfZW50cnkpOwoJbGlzdF9kZWxfcmN1KCZldmVudC0+ZXZlbnRfZW50cnkpOwoKCWlmIChldmVudC0+Z3JvdXBfbGVhZGVyICE9IGV2ZW50KQoJCWV2ZW50LT5ncm91cF9sZWFkZXItPm5yX3NpYmxpbmdzLS07CgoJLyoKCSAqIElmIHRoaXMgd2FzIGEgZ3JvdXAgZXZlbnQgd2l0aCBzaWJsaW5nIGV2ZW50cyB0aGVuCgkgKiB1cGdyYWRlIHRoZSBzaWJsaW5ncyB0byBzaW5nbGV0b24gZXZlbnRzIGJ5IGFkZGluZyB0aGVtCgkgKiB0byB0aGUgY29udGV4dCBsaXN0IGRpcmVjdGx5OgoJICovCglsaXN0X2Zvcl9lYWNoX2VudHJ5X3NhZmUoc2libGluZywgdG1wLCAmZXZlbnQtPnNpYmxpbmdfbGlzdCwgZ3JvdXBfZW50cnkpIHsKCgkJbGlzdF9tb3ZlX3RhaWwoJnNpYmxpbmctPmdyb3VwX2VudHJ5LCAmY3R4LT5ncm91cF9saXN0KTsKCQlzaWJsaW5nLT5ncm91cF9sZWFkZXIgPSBzaWJsaW5nOwoJfQp9CgpzdGF0aWMgdm9pZApldmVudF9zY2hlZF9vdXQoc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50LAoJCSAgc3RydWN0IHBlcmZfY3B1X2NvbnRleHQgKmNwdWN0eCwKCQkgIHN0cnVjdCBwZXJmX2V2ZW50X2NvbnRleHQgKmN0eCkKewoJaWYgKGV2ZW50LT5zdGF0ZSAhPSBQRVJGX0VWRU5UX1NUQVRFX0FDVElWRSkKCQlyZXR1cm47CgoJZXZlbnQtPnN0YXRlID0gUEVSRl9FVkVOVF9TVEFURV9JTkFDVElWRTsKCWlmIChldmVudC0+cGVuZGluZ19kaXNhYmxlKSB7CgkJZXZlbnQtPnBlbmRpbmdfZGlzYWJsZSA9IDA7CgkJZXZlbnQtPnN0YXRlID0gUEVSRl9FVkVOVF9TVEFURV9PRkY7Cgl9CglldmVudC0+dHN0YW1wX3N0b3BwZWQgPSBjdHgtPnRpbWU7CglldmVudC0+cG11LT5kaXNhYmxlKGV2ZW50KTsKCWV2ZW50LT5vbmNwdSA9IC0xOwoKCWlmICghaXNfc29mdHdhcmVfZXZlbnQoZXZlbnQpKQoJCWNwdWN0eC0+YWN0aXZlX29uY3B1LS07CgljdHgtPm5yX2FjdGl2ZS0tOwoJaWYgKGV2ZW50LT5hdHRyLmV4Y2x1c2l2ZSB8fCAhY3B1Y3R4LT5hY3RpdmVfb25jcHUpCgkJY3B1Y3R4LT5leGNsdXNpdmUgPSAwOwp9CgpzdGF0aWMgdm9pZApncm91cF9zY2hlZF9vdXQoc3RydWN0IHBlcmZfZXZlbnQgKmdyb3VwX2V2ZW50LAoJCXN0cnVjdCBwZXJmX2NwdV9jb250ZXh0ICpjcHVjdHgsCgkJc3RydWN0IHBlcmZfZXZlbnRfY29udGV4dCAqY3R4KQp7CglzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQ7CgoJaWYgKGdyb3VwX2V2ZW50LT5zdGF0ZSAhPSBQRVJGX0VWRU5UX1NUQVRFX0FDVElWRSkKCQlyZXR1cm47CgoJZXZlbnRfc2NoZWRfb3V0KGdyb3VwX2V2ZW50LCBjcHVjdHgsIGN0eCk7CgoJLyoKCSAqIFNjaGVkdWxlIG91dCBzaWJsaW5ncyAoaWYgYW55KToKCSAqLwoJbGlzdF9mb3JfZWFjaF9lbnRyeShldmVudCwgJmdyb3VwX2V2ZW50LT5zaWJsaW5nX2xpc3QsIGdyb3VwX2VudHJ5KQoJCWV2ZW50X3NjaGVkX291dChldmVudCwgY3B1Y3R4LCBjdHgpOwoKCWlmIChncm91cF9ldmVudC0+YXR0ci5leGNsdXNpdmUpCgkJY3B1Y3R4LT5leGNsdXNpdmUgPSAwOwp9CgovKgogKiBDcm9zcyBDUFUgY2FsbCB0byByZW1vdmUgYSBwZXJmb3JtYW5jZSBldmVudAogKgogKiBXZSBkaXNhYmxlIHRoZSBldmVudCBvbiB0aGUgaGFyZHdhcmUgbGV2ZWwgZmlyc3QuIEFmdGVyIHRoYXQgd2UKICogcmVtb3ZlIGl0IGZyb20gdGhlIGNvbnRleHQgbGlzdC4KICovCnN0YXRpYyB2b2lkIF9fcGVyZl9ldmVudF9yZW1vdmVfZnJvbV9jb250ZXh0KHZvaWQgKmluZm8pCnsKCXN0cnVjdCBwZXJmX2NwdV9jb250ZXh0ICpjcHVjdHggPSAmX19nZXRfY3B1X3ZhcihwZXJmX2NwdV9jb250ZXh0KTsKCXN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCA9IGluZm87CglzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0ICpjdHggPSBldmVudC0+Y3R4OwoKCS8qCgkgKiBJZiB0aGlzIGlzIGEgdGFzayBjb250ZXh0LCB3ZSBuZWVkIHRvIGNoZWNrIHdoZXRoZXIgaXQgaXMKCSAqIHRoZSBjdXJyZW50IHRhc2sgY29udGV4dCBvZiB0aGlzIGNwdS4gSWYgbm90IGl0IGhhcyBiZWVuCgkgKiBzY2hlZHVsZWQgb3V0IGJlZm9yZSB0aGUgc21wIGNhbGwgYXJyaXZlZC4KCSAqLwoJaWYgKGN0eC0+dGFzayAmJiBjcHVjdHgtPnRhc2tfY3R4ICE9IGN0eCkKCQlyZXR1cm47CgoJc3Bpbl9sb2NrKCZjdHgtPmxvY2spOwoJLyoKCSAqIFByb3RlY3QgdGhlIGxpc3Qgb3BlcmF0aW9uIGFnYWluc3QgTk1JIGJ5IGRpc2FibGluZyB0aGUKCSAqIGV2ZW50cyBvbiBhIGdsb2JhbCBsZXZlbC4KCSAqLwoJcGVyZl9kaXNhYmxlKCk7CgoJZXZlbnRfc2NoZWRfb3V0KGV2ZW50LCBjcHVjdHgsIGN0eCk7CgoJbGlzdF9kZWxfZXZlbnQoZXZlbnQsIGN0eCk7CgoJaWYgKCFjdHgtPnRhc2spIHsKCQkvKgoJCSAqIEFsbG93IG1vcmUgcGVyIHRhc2sgZXZlbnRzIHdpdGggcmVzcGVjdCB0byB0aGUKCQkgKiByZXNlcnZhdGlvbjoKCQkgKi8KCQljcHVjdHgtPm1heF9wZXJ0YXNrID0KCQkJbWluKHBlcmZfbWF4X2V2ZW50cyAtIGN0eC0+bnJfZXZlbnRzLAoJCQkgICAgcGVyZl9tYXhfZXZlbnRzIC0gcGVyZl9yZXNlcnZlZF9wZXJjcHUpOwoJfQoKCXBlcmZfZW5hYmxlKCk7CglzcGluX3VubG9jaygmY3R4LT5sb2NrKTsKfQoKCi8qCiAqIFJlbW92ZSB0aGUgZXZlbnQgZnJvbSBhIHRhc2sncyAob3IgYSBDUFUncykgbGlzdCBvZiBldmVudHMuCiAqCiAqIE11c3QgYmUgY2FsbGVkIHdpdGggY3R4LT5tdXRleCBoZWxkLgogKgogKiBDUFUgZXZlbnRzIGFyZSByZW1vdmVkIHdpdGggYSBzbXAgY2FsbC4gRm9yIHRhc2sgZXZlbnRzIHdlIG9ubHkKICogY2FsbCB3aGVuIHRoZSB0YXNrIGlzIG9uIGEgQ1BVLgogKgogKiBJZiBldmVudC0+Y3R4IGlzIGEgY2xvbmVkIGNvbnRleHQsIGNhbGxlcnMgbXVzdCBtYWtlIHN1cmUgdGhhdAogKiBldmVyeSB0YXNrIHN0cnVjdCB0aGF0IGV2ZW50LT5jdHgtPnRhc2sgY291bGQgcG9zc2libHkgcG9pbnQgdG8KICogcmVtYWlucyB2YWxpZC4gIFRoaXMgaXMgT0sgd2hlbiBjYWxsZWQgZnJvbSBwZXJmX3JlbGVhc2Ugc2luY2UKICogdGhhdCBvbmx5IGNhbGxzIHVzIG9uIHRoZSB0b3AtbGV2ZWwgY29udGV4dCwgd2hpY2ggY2FuJ3QgYmUgYSBjbG9uZS4KICogV2hlbiBjYWxsZWQgZnJvbSBwZXJmX2V2ZW50X2V4aXRfdGFzaywgaXQncyBPSyBiZWNhdXNlIHRoZQogKiBjb250ZXh0IGhhcyBiZWVuIGRldGFjaGVkIGZyb20gaXRzIHRhc2suCiAqLwpzdGF0aWMgdm9pZCBwZXJmX2V2ZW50X3JlbW92ZV9mcm9tX2NvbnRleHQoc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50KQp7CglzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0ICpjdHggPSBldmVudC0+Y3R4OwoJc3RydWN0IHRhc2tfc3RydWN0ICp0YXNrID0gY3R4LT50YXNrOwoKCWlmICghdGFzaykgewoJCS8qCgkJICogUGVyIGNwdSBldmVudHMgYXJlIHJlbW92ZWQgdmlhIGFuIHNtcCBjYWxsIGFuZAoJCSAqIHRoZSByZW1vdmFsIGlzIGFsd2F5cyBzdWNjZXNzZnVsLgoJCSAqLwoJCXNtcF9jYWxsX2Z1bmN0aW9uX3NpbmdsZShldmVudC0+Y3B1LAoJCQkJCSBfX3BlcmZfZXZlbnRfcmVtb3ZlX2Zyb21fY29udGV4dCwKCQkJCQkgZXZlbnQsIDEpOwoJCXJldHVybjsKCX0KCnJldHJ5OgoJdGFza19vbmNwdV9mdW5jdGlvbl9jYWxsKHRhc2ssIF9fcGVyZl9ldmVudF9yZW1vdmVfZnJvbV9jb250ZXh0LAoJCQkJIGV2ZW50KTsKCglzcGluX2xvY2tfaXJxKCZjdHgtPmxvY2spOwoJLyoKCSAqIElmIHRoZSBjb250ZXh0IGlzIGFjdGl2ZSB3ZSBuZWVkIHRvIHJldHJ5IHRoZSBzbXAgY2FsbC4KCSAqLwoJaWYgKGN0eC0+bnJfYWN0aXZlICYmICFsaXN0X2VtcHR5KCZldmVudC0+Z3JvdXBfZW50cnkpKSB7CgkJc3Bpbl91bmxvY2tfaXJxKCZjdHgtPmxvY2spOwoJCWdvdG8gcmV0cnk7Cgl9CgoJLyoKCSAqIFRoZSBsb2NrIHByZXZlbnRzIHRoYXQgdGhpcyBjb250ZXh0IGlzIHNjaGVkdWxlZCBpbiBzbyB3ZQoJICogY2FuIHJlbW92ZSB0aGUgZXZlbnQgc2FmZWx5LCBpZiB0aGUgY2FsbCBhYm92ZSBkaWQgbm90CgkgKiBzdWNjZWVkLgoJICovCglpZiAoIWxpc3RfZW1wdHkoJmV2ZW50LT5ncm91cF9lbnRyeSkpIHsKCQlsaXN0X2RlbF9ldmVudChldmVudCwgY3R4KTsKCX0KCXNwaW5fdW5sb2NrX2lycSgmY3R4LT5sb2NrKTsKfQoKc3RhdGljIGlubGluZSB1NjQgcGVyZl9jbG9jayh2b2lkKQp7CglyZXR1cm4gY3B1X2Nsb2NrKHNtcF9wcm9jZXNzb3JfaWQoKSk7Cn0KCi8qCiAqIFVwZGF0ZSB0aGUgcmVjb3JkIG9mIHRoZSBjdXJyZW50IHRpbWUgaW4gYSBjb250ZXh0LgogKi8Kc3RhdGljIHZvaWQgdXBkYXRlX2NvbnRleHRfdGltZShzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0ICpjdHgpCnsKCXU2NCBub3cgPSBwZXJmX2Nsb2NrKCk7CgoJY3R4LT50aW1lICs9IG5vdyAtIGN0eC0+dGltZXN0YW1wOwoJY3R4LT50aW1lc3RhbXAgPSBub3c7Cn0KCi8qCiAqIFVwZGF0ZSB0aGUgdG90YWxfdGltZV9lbmFibGVkIGFuZCB0b3RhbF90aW1lX3J1bm5pbmcgZmllbGRzIGZvciBhIGV2ZW50LgogKi8Kc3RhdGljIHZvaWQgdXBkYXRlX2V2ZW50X3RpbWVzKHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCkKewoJc3RydWN0IHBlcmZfZXZlbnRfY29udGV4dCAqY3R4ID0gZXZlbnQtPmN0eDsKCXU2NCBydW5fZW5kOwoKCWlmIChldmVudC0+c3RhdGUgPCBQRVJGX0VWRU5UX1NUQVRFX0lOQUNUSVZFIHx8CgkgICAgZXZlbnQtPmdyb3VwX2xlYWRlci0+c3RhdGUgPCBQRVJGX0VWRU5UX1NUQVRFX0lOQUNUSVZFKQoJCXJldHVybjsKCglldmVudC0+dG90YWxfdGltZV9lbmFibGVkID0gY3R4LT50aW1lIC0gZXZlbnQtPnRzdGFtcF9lbmFibGVkOwoKCWlmIChldmVudC0+c3RhdGUgPT0gUEVSRl9FVkVOVF9TVEFURV9JTkFDVElWRSkKCQlydW5fZW5kID0gZXZlbnQtPnRzdGFtcF9zdG9wcGVkOwoJZWxzZQoJCXJ1bl9lbmQgPSBjdHgtPnRpbWU7CgoJZXZlbnQtPnRvdGFsX3RpbWVfcnVubmluZyA9IHJ1bl9lbmQgLSBldmVudC0+dHN0YW1wX3J1bm5pbmc7Cn0KCi8qCiAqIFVwZGF0ZSB0b3RhbF90aW1lX2VuYWJsZWQgYW5kIHRvdGFsX3RpbWVfcnVubmluZyBmb3IgYWxsIGV2ZW50cyBpbiBhIGdyb3VwLgogKi8Kc3RhdGljIHZvaWQgdXBkYXRlX2dyb3VwX3RpbWVzKHN0cnVjdCBwZXJmX2V2ZW50ICpsZWFkZXIpCnsKCXN0cnVjdCBwZXJmX2V2ZW50ICpldmVudDsKCgl1cGRhdGVfZXZlbnRfdGltZXMobGVhZGVyKTsKCWxpc3RfZm9yX2VhY2hfZW50cnkoZXZlbnQsICZsZWFkZXItPnNpYmxpbmdfbGlzdCwgZ3JvdXBfZW50cnkpCgkJdXBkYXRlX2V2ZW50X3RpbWVzKGV2ZW50KTsKfQoKLyoKICogQ3Jvc3MgQ1BVIGNhbGwgdG8gZGlzYWJsZSBhIHBlcmZvcm1hbmNlIGV2ZW50CiAqLwpzdGF0aWMgdm9pZCBfX3BlcmZfZXZlbnRfZGlzYWJsZSh2b2lkICppbmZvKQp7CglzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQgPSBpbmZvOwoJc3RydWN0IHBlcmZfY3B1X2NvbnRleHQgKmNwdWN0eCA9ICZfX2dldF9jcHVfdmFyKHBlcmZfY3B1X2NvbnRleHQpOwoJc3RydWN0IHBlcmZfZXZlbnRfY29udGV4dCAqY3R4ID0gZXZlbnQtPmN0eDsKCgkvKgoJICogSWYgdGhpcyBpcyBhIHBlci10YXNrIGV2ZW50LCBuZWVkIHRvIGNoZWNrIHdoZXRoZXIgdGhpcwoJICogZXZlbnQncyB0YXNrIGlzIHRoZSBjdXJyZW50IHRhc2sgb24gdGhpcyBjcHUuCgkgKi8KCWlmIChjdHgtPnRhc2sgJiYgY3B1Y3R4LT50YXNrX2N0eCAhPSBjdHgpCgkJcmV0dXJuOwoKCXNwaW5fbG9jaygmY3R4LT5sb2NrKTsKCgkvKgoJICogSWYgdGhlIGV2ZW50IGlzIG9uLCB0dXJuIGl0IG9mZi4KCSAqIElmIGl0IGlzIGluIGVycm9yIHN0YXRlLCBsZWF2ZSBpdCBpbiBlcnJvciBzdGF0ZS4KCSAqLwoJaWYgKGV2ZW50LT5zdGF0ZSA+PSBQRVJGX0VWRU5UX1NUQVRFX0lOQUNUSVZFKSB7CgkJdXBkYXRlX2NvbnRleHRfdGltZShjdHgpOwoJCXVwZGF0ZV9ncm91cF90aW1lcyhldmVudCk7CgkJaWYgKGV2ZW50ID09IGV2ZW50LT5ncm91cF9sZWFkZXIpCgkJCWdyb3VwX3NjaGVkX291dChldmVudCwgY3B1Y3R4LCBjdHgpOwoJCWVsc2UKCQkJZXZlbnRfc2NoZWRfb3V0KGV2ZW50LCBjcHVjdHgsIGN0eCk7CgkJZXZlbnQtPnN0YXRlID0gUEVSRl9FVkVOVF9TVEFURV9PRkY7Cgl9CgoJc3Bpbl91bmxvY2soJmN0eC0+bG9jayk7Cn0KCi8qCiAqIERpc2FibGUgYSBldmVudC4KICoKICogSWYgZXZlbnQtPmN0eCBpcyBhIGNsb25lZCBjb250ZXh0LCBjYWxsZXJzIG11c3QgbWFrZSBzdXJlIHRoYXQKICogZXZlcnkgdGFzayBzdHJ1Y3QgdGhhdCBldmVudC0+Y3R4LT50YXNrIGNvdWxkIHBvc3NpYmx5IHBvaW50IHRvCiAqIHJlbWFpbnMgdmFsaWQuICBUaGlzIGNvbmRpdGlvbiBpcyBzYXRpc2lmZWQgd2hlbiBjYWxsZWQgdGhyb3VnaAogKiBwZXJmX2V2ZW50X2Zvcl9lYWNoX2NoaWxkIG9yIHBlcmZfZXZlbnRfZm9yX2VhY2ggYmVjYXVzZSB0aGV5CiAqIGhvbGQgdGhlIHRvcC1sZXZlbCBldmVudCdzIGNoaWxkX211dGV4LCBzbyBhbnkgZGVzY2VuZGFudCB0aGF0CiAqIGdvZXMgdG8gZXhpdCB3aWxsIGJsb2NrIGluIHN5bmNfY2hpbGRfZXZlbnQuCiAqIFdoZW4gY2FsbGVkIGZyb20gcGVyZl9wZW5kaW5nX2V2ZW50IGl0J3MgT0sgYmVjYXVzZSBldmVudC0+Y3R4CiAqIGlzIHRoZSBjdXJyZW50IGNvbnRleHQgb24gdGhpcyBDUFUgYW5kIHByZWVtcHRpb24gaXMgZGlzYWJsZWQsCiAqIGhlbmNlIHdlIGNhbid0IGdldCBpbnRvIHBlcmZfZXZlbnRfdGFza19zY2hlZF9vdXQgZm9yIHRoaXMgY29udGV4dC4KICovCnN0YXRpYyB2b2lkIHBlcmZfZXZlbnRfZGlzYWJsZShzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQpCnsKCXN0cnVjdCBwZXJmX2V2ZW50X2NvbnRleHQgKmN0eCA9IGV2ZW50LT5jdHg7CglzdHJ1Y3QgdGFza19zdHJ1Y3QgKnRhc2sgPSBjdHgtPnRhc2s7CgoJaWYgKCF0YXNrKSB7CgkJLyoKCQkgKiBEaXNhYmxlIHRoZSBldmVudCBvbiB0aGUgY3B1IHRoYXQgaXQncyBvbgoJCSAqLwoJCXNtcF9jYWxsX2Z1bmN0aW9uX3NpbmdsZShldmVudC0+Y3B1LCBfX3BlcmZfZXZlbnRfZGlzYWJsZSwKCQkJCQkgZXZlbnQsIDEpOwoJCXJldHVybjsKCX0KCiByZXRyeToKCXRhc2tfb25jcHVfZnVuY3Rpb25fY2FsbCh0YXNrLCBfX3BlcmZfZXZlbnRfZGlzYWJsZSwgZXZlbnQpOwoKCXNwaW5fbG9ja19pcnEoJmN0eC0+bG9jayk7CgkvKgoJICogSWYgdGhlIGV2ZW50IGlzIHN0aWxsIGFjdGl2ZSwgd2UgbmVlZCB0byByZXRyeSB0aGUgY3Jvc3MtY2FsbC4KCSAqLwoJaWYgKGV2ZW50LT5zdGF0ZSA9PSBQRVJGX0VWRU5UX1NUQVRFX0FDVElWRSkgewoJCXNwaW5fdW5sb2NrX2lycSgmY3R4LT5sb2NrKTsKCQlnb3RvIHJldHJ5OwoJfQoKCS8qCgkgKiBTaW5jZSB3ZSBoYXZlIHRoZSBsb2NrIHRoaXMgY29udGV4dCBjYW4ndCBiZSBzY2hlZHVsZWQKCSAqIGluLCBzbyB3ZSBjYW4gY2hhbmdlIHRoZSBzdGF0ZSBzYWZlbHkuCgkgKi8KCWlmIChldmVudC0+c3RhdGUgPT0gUEVSRl9FVkVOVF9TVEFURV9JTkFDVElWRSkgewoJCXVwZGF0ZV9ncm91cF90aW1lcyhldmVudCk7CgkJZXZlbnQtPnN0YXRlID0gUEVSRl9FVkVOVF9TVEFURV9PRkY7Cgl9CgoJc3Bpbl91bmxvY2tfaXJxKCZjdHgtPmxvY2spOwp9CgpzdGF0aWMgaW50CmV2ZW50X3NjaGVkX2luKHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCwKCQkgc3RydWN0IHBlcmZfY3B1X2NvbnRleHQgKmNwdWN0eCwKCQkgc3RydWN0IHBlcmZfZXZlbnRfY29udGV4dCAqY3R4LAoJCSBpbnQgY3B1KQp7CglpZiAoZXZlbnQtPnN0YXRlIDw9IFBFUkZfRVZFTlRfU1RBVEVfT0ZGKQoJCXJldHVybiAwOwoKCWV2ZW50LT5zdGF0ZSA9IFBFUkZfRVZFTlRfU1RBVEVfQUNUSVZFOwoJZXZlbnQtPm9uY3B1ID0gY3B1OwkvKiBUT0RPOiBwdXQgJ2NwdScgaW50byBjcHVjdHgtPmNwdSAqLwoJLyoKCSAqIFRoZSBuZXcgc3RhdGUgbXVzdCBiZSB2aXNpYmxlIGJlZm9yZSB3ZSB0dXJuIGl0IG9uIGluIHRoZSBoYXJkd2FyZToKCSAqLwoJc21wX3dtYigpOwoKCWlmIChldmVudC0+cG11LT5lbmFibGUoZXZlbnQpKSB7CgkJZXZlbnQtPnN0YXRlID0gUEVSRl9FVkVOVF9TVEFURV9JTkFDVElWRTsKCQlldmVudC0+b25jcHUgPSAtMTsKCQlyZXR1cm4gLUVBR0FJTjsKCX0KCglldmVudC0+dHN0YW1wX3J1bm5pbmcgKz0gY3R4LT50aW1lIC0gZXZlbnQtPnRzdGFtcF9zdG9wcGVkOwoKCWlmICghaXNfc29mdHdhcmVfZXZlbnQoZXZlbnQpKQoJCWNwdWN0eC0+YWN0aXZlX29uY3B1Kys7CgljdHgtPm5yX2FjdGl2ZSsrOwoKCWlmIChldmVudC0+YXR0ci5leGNsdXNpdmUpCgkJY3B1Y3R4LT5leGNsdXNpdmUgPSAxOwoKCXJldHVybiAwOwp9CgpzdGF0aWMgaW50Cmdyb3VwX3NjaGVkX2luKHN0cnVjdCBwZXJmX2V2ZW50ICpncm91cF9ldmVudCwKCSAgICAgICBzdHJ1Y3QgcGVyZl9jcHVfY29udGV4dCAqY3B1Y3R4LAoJICAgICAgIHN0cnVjdCBwZXJmX2V2ZW50X2NvbnRleHQgKmN0eCwKCSAgICAgICBpbnQgY3B1KQp7CglzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQsICpwYXJ0aWFsX2dyb3VwOwoJaW50IHJldDsKCglpZiAoZ3JvdXBfZXZlbnQtPnN0YXRlID09IFBFUkZfRVZFTlRfU1RBVEVfT0ZGKQoJCXJldHVybiAwOwoKCXJldCA9IGh3X3BlcmZfZ3JvdXBfc2NoZWRfaW4oZ3JvdXBfZXZlbnQsIGNwdWN0eCwgY3R4LCBjcHUpOwoJaWYgKHJldCkKCQlyZXR1cm4gcmV0IDwgMCA/IHJldCA6IDA7CgoJaWYgKGV2ZW50X3NjaGVkX2luKGdyb3VwX2V2ZW50LCBjcHVjdHgsIGN0eCwgY3B1KSkKCQlyZXR1cm4gLUVBR0FJTjsKCgkvKgoJICogU2NoZWR1bGUgaW4gc2libGluZ3MgYXMgb25lIGdyb3VwIChpZiBhbnkpOgoJICovCglsaXN0X2Zvcl9lYWNoX2VudHJ5KGV2ZW50LCAmZ3JvdXBfZXZlbnQtPnNpYmxpbmdfbGlzdCwgZ3JvdXBfZW50cnkpIHsKCQlpZiAoZXZlbnRfc2NoZWRfaW4oZXZlbnQsIGNwdWN0eCwgY3R4LCBjcHUpKSB7CgkJCXBhcnRpYWxfZ3JvdXAgPSBldmVudDsKCQkJZ290byBncm91cF9lcnJvcjsKCQl9Cgl9CgoJcmV0dXJuIDA7Cgpncm91cF9lcnJvcjoKCS8qCgkgKiBHcm91cHMgY2FuIGJlIHNjaGVkdWxlZCBpbiBhcyBvbmUgdW5pdCBvbmx5LCBzbyB1bmRvIGFueQoJICogcGFydGlhbCBncm91cCBiZWZvcmUgcmV0dXJuaW5nOgoJICovCglsaXN0X2Zvcl9lYWNoX2VudHJ5KGV2ZW50LCAmZ3JvdXBfZXZlbnQtPnNpYmxpbmdfbGlzdCwgZ3JvdXBfZW50cnkpIHsKCQlpZiAoZXZlbnQgPT0gcGFydGlhbF9ncm91cCkKCQkJYnJlYWs7CgkJZXZlbnRfc2NoZWRfb3V0KGV2ZW50LCBjcHVjdHgsIGN0eCk7Cgl9CglldmVudF9zY2hlZF9vdXQoZ3JvdXBfZXZlbnQsIGNwdWN0eCwgY3R4KTsKCglyZXR1cm4gLUVBR0FJTjsKfQoKLyoKICogUmV0dXJuIDEgZm9yIGEgZ3JvdXAgY29uc2lzdGluZyBlbnRpcmVseSBvZiBzb2Z0d2FyZSBldmVudHMsCiAqIDAgaWYgdGhlIGdyb3VwIGNvbnRhaW5zIGFueSBoYXJkd2FyZSBldmVudHMuCiAqLwpzdGF0aWMgaW50IGlzX3NvZnR3YXJlX29ubHlfZ3JvdXAoc3RydWN0IHBlcmZfZXZlbnQgKmxlYWRlcikKewoJc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50OwoKCWlmICghaXNfc29mdHdhcmVfZXZlbnQobGVhZGVyKSkKCQlyZXR1cm4gMDsKCglsaXN0X2Zvcl9lYWNoX2VudHJ5KGV2ZW50LCAmbGVhZGVyLT5zaWJsaW5nX2xpc3QsIGdyb3VwX2VudHJ5KQoJCWlmICghaXNfc29mdHdhcmVfZXZlbnQoZXZlbnQpKQoJCQlyZXR1cm4gMDsKCglyZXR1cm4gMTsKfQoKLyoKICogV29yayBvdXQgd2hldGhlciB3ZSBjYW4gcHV0IHRoaXMgZXZlbnQgZ3JvdXAgb24gdGhlIENQVSBub3cuCiAqLwpzdGF0aWMgaW50IGdyb3VwX2Nhbl9nb19vbihzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQsCgkJCSAgIHN0cnVjdCBwZXJmX2NwdV9jb250ZXh0ICpjcHVjdHgsCgkJCSAgIGludCBjYW5fYWRkX2h3KQp7CgkvKgoJICogR3JvdXBzIGNvbnNpc3RpbmcgZW50aXJlbHkgb2Ygc29mdHdhcmUgZXZlbnRzIGNhbiBhbHdheXMgZ28gb24uCgkgKi8KCWlmIChpc19zb2Z0d2FyZV9vbmx5X2dyb3VwKGV2ZW50KSkKCQlyZXR1cm4gMTsKCS8qCgkgKiBJZiBhbiBleGNsdXNpdmUgZ3JvdXAgaXMgYWxyZWFkeSBvbiwgbm8gb3RoZXIgaGFyZHdhcmUKCSAqIGV2ZW50cyBjYW4gZ28gb24uCgkgKi8KCWlmIChjcHVjdHgtPmV4Y2x1c2l2ZSkKCQlyZXR1cm4gMDsKCS8qCgkgKiBJZiB0aGlzIGdyb3VwIGlzIGV4Y2x1c2l2ZSBhbmQgdGhlcmUgYXJlIGFscmVhZHkKCSAqIGV2ZW50cyBvbiB0aGUgQ1BVLCBpdCBjYW4ndCBnbyBvbi4KCSAqLwoJaWYgKGV2ZW50LT5hdHRyLmV4Y2x1c2l2ZSAmJiBjcHVjdHgtPmFjdGl2ZV9vbmNwdSkKCQlyZXR1cm4gMDsKCS8qCgkgKiBPdGhlcndpc2UsIHRyeSB0byBhZGQgaXQgaWYgYWxsIHByZXZpb3VzIGdyb3VwcyB3ZXJlIGFibGUKCSAqIHRvIGdvIG9uLgoJICovCglyZXR1cm4gY2FuX2FkZF9odzsKfQoKc3RhdGljIHZvaWQgYWRkX2V2ZW50X3RvX2N0eChzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQsCgkJCSAgICAgICBzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0ICpjdHgpCnsKCWxpc3RfYWRkX2V2ZW50KGV2ZW50LCBjdHgpOwoJZXZlbnQtPnRzdGFtcF9lbmFibGVkID0gY3R4LT50aW1lOwoJZXZlbnQtPnRzdGFtcF9ydW5uaW5nID0gY3R4LT50aW1lOwoJZXZlbnQtPnRzdGFtcF9zdG9wcGVkID0gY3R4LT50aW1lOwp9CgovKgogKiBDcm9zcyBDUFUgY2FsbCB0byBpbnN0YWxsIGFuZCBlbmFibGUgYSBwZXJmb3JtYW5jZSBldmVudAogKgogKiBNdXN0IGJlIGNhbGxlZCB3aXRoIGN0eC0+bXV0ZXggaGVsZAogKi8Kc3RhdGljIHZvaWQgX19wZXJmX2luc3RhbGxfaW5fY29udGV4dCh2b2lkICppbmZvKQp7CglzdHJ1Y3QgcGVyZl9jcHVfY29udGV4dCAqY3B1Y3R4ID0gJl9fZ2V0X2NwdV92YXIocGVyZl9jcHVfY29udGV4dCk7CglzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQgPSBpbmZvOwoJc3RydWN0IHBlcmZfZXZlbnRfY29udGV4dCAqY3R4ID0gZXZlbnQtPmN0eDsKCXN0cnVjdCBwZXJmX2V2ZW50ICpsZWFkZXIgPSBldmVudC0+Z3JvdXBfbGVhZGVyOwoJaW50IGNwdSA9IHNtcF9wcm9jZXNzb3JfaWQoKTsKCWludCBlcnI7CgoJLyoKCSAqIElmIHRoaXMgaXMgYSB0YXNrIGNvbnRleHQsIHdlIG5lZWQgdG8gY2hlY2sgd2hldGhlciBpdCBpcwoJICogdGhlIGN1cnJlbnQgdGFzayBjb250ZXh0IG9mIHRoaXMgY3B1LiBJZiBub3QgaXQgaGFzIGJlZW4KCSAqIHNjaGVkdWxlZCBvdXQgYmVmb3JlIHRoZSBzbXAgY2FsbCBhcnJpdmVkLgoJICogT3IgcG9zc2libHkgdGhpcyBpcyB0aGUgcmlnaHQgY29udGV4dCBidXQgaXQgaXNuJ3QKCSAqIG9uIHRoaXMgY3B1IGJlY2F1c2UgaXQgaGFkIG5vIGV2ZW50cy4KCSAqLwoJaWYgKGN0eC0+dGFzayAmJiBjcHVjdHgtPnRhc2tfY3R4ICE9IGN0eCkgewoJCWlmIChjcHVjdHgtPnRhc2tfY3R4IHx8IGN0eC0+dGFzayAhPSBjdXJyZW50KQoJCQlyZXR1cm47CgkJY3B1Y3R4LT50YXNrX2N0eCA9IGN0eDsKCX0KCglzcGluX2xvY2soJmN0eC0+bG9jayk7CgljdHgtPmlzX2FjdGl2ZSA9IDE7Cgl1cGRhdGVfY29udGV4dF90aW1lKGN0eCk7CgoJLyoKCSAqIFByb3RlY3QgdGhlIGxpc3Qgb3BlcmF0aW9uIGFnYWluc3QgTk1JIGJ5IGRpc2FibGluZyB0aGUKCSAqIGV2ZW50cyBvbiBhIGdsb2JhbCBsZXZlbC4gTk9QIGZvciBub24gTk1JIGJhc2VkIGV2ZW50cy4KCSAqLwoJcGVyZl9kaXNhYmxlKCk7CgoJYWRkX2V2ZW50X3RvX2N0eChldmVudCwgY3R4KTsKCgkvKgoJICogRG9uJ3QgcHV0IHRoZSBldmVudCBvbiBpZiBpdCBpcyBkaXNhYmxlZCBvciBpZgoJICogaXQgaXMgaW4gYSBncm91cCBhbmQgdGhlIGdyb3VwIGlzbid0IG9uLgoJICovCglpZiAoZXZlbnQtPnN0YXRlICE9IFBFUkZfRVZFTlRfU1RBVEVfSU5BQ1RJVkUgfHwKCSAgICAobGVhZGVyICE9IGV2ZW50ICYmIGxlYWRlci0+c3RhdGUgIT0gUEVSRl9FVkVOVF9TVEFURV9BQ1RJVkUpKQoJCWdvdG8gdW5sb2NrOwoKCS8qCgkgKiBBbiBleGNsdXNpdmUgZXZlbnQgY2FuJ3QgZ28gb24gaWYgdGhlcmUgYXJlIGFscmVhZHkgYWN0aXZlCgkgKiBoYXJkd2FyZSBldmVudHMsIGFuZCBubyBoYXJkd2FyZSBldmVudCBjYW4gZ28gb24gaWYgdGhlcmUKCSAqIGlzIGFscmVhZHkgYW4gZXhjbHVzaXZlIGV2ZW50IG9uLgoJICovCglpZiAoIWdyb3VwX2Nhbl9nb19vbihldmVudCwgY3B1Y3R4LCAxKSkKCQllcnIgPSAtRUVYSVNUOwoJZWxzZQoJCWVyciA9IGV2ZW50X3NjaGVkX2luKGV2ZW50LCBjcHVjdHgsIGN0eCwgY3B1KTsKCglpZiAoZXJyKSB7CgkJLyoKCQkgKiBUaGlzIGV2ZW50IGNvdWxkbid0IGdvIG9uLiAgSWYgaXQgaXMgaW4gYSBncm91cAoJCSAqIHRoZW4gd2UgaGF2ZSB0byBwdWxsIHRoZSB3aG9sZSBncm91cCBvZmYuCgkJICogSWYgdGhlIGV2ZW50IGdyb3VwIGlzIHBpbm5lZCB0aGVuIHB1dCBpdCBpbiBlcnJvciBzdGF0ZS4KCQkgKi8KCQlpZiAobGVhZGVyICE9IGV2ZW50KQoJCQlncm91cF9zY2hlZF9vdXQobGVhZGVyLCBjcHVjdHgsIGN0eCk7CgkJaWYgKGxlYWRlci0+YXR0ci5waW5uZWQpIHsKCQkJdXBkYXRlX2dyb3VwX3RpbWVzKGxlYWRlcik7CgkJCWxlYWRlci0+c3RhdGUgPSBQRVJGX0VWRU5UX1NUQVRFX0VSUk9SOwoJCX0KCX0KCglpZiAoIWVyciAmJiAhY3R4LT50YXNrICYmIGNwdWN0eC0+bWF4X3BlcnRhc2spCgkJY3B1Y3R4LT5tYXhfcGVydGFzay0tOwoKIHVubG9jazoKCXBlcmZfZW5hYmxlKCk7CgoJc3Bpbl91bmxvY2soJmN0eC0+bG9jayk7Cn0KCi8qCiAqIEF0dGFjaCBhIHBlcmZvcm1hbmNlIGV2ZW50IHRvIGEgY29udGV4dAogKgogKiBGaXJzdCB3ZSBhZGQgdGhlIGV2ZW50IHRvIHRoZSBsaXN0IHdpdGggdGhlIGhhcmR3YXJlIGVuYWJsZSBiaXQKICogaW4gZXZlbnQtPmh3X2NvbmZpZyBjbGVhcmVkLgogKgogKiBJZiB0aGUgZXZlbnQgaXMgYXR0YWNoZWQgdG8gYSB0YXNrIHdoaWNoIGlzIG9uIGEgQ1BVIHdlIHVzZSBhIHNtcAogKiBjYWxsIHRvIGVuYWJsZSBpdCBpbiB0aGUgdGFzayBjb250ZXh0LiBUaGUgdGFzayBtaWdodCBoYXZlIGJlZW4KICogc2NoZWR1bGVkIGF3YXksIGJ1dCB3ZSBjaGVjayB0aGlzIGluIHRoZSBzbXAgY2FsbCBhZ2Fpbi4KICoKICogTXVzdCBiZSBjYWxsZWQgd2l0aCBjdHgtPm11dGV4IGhlbGQuCiAqLwpzdGF0aWMgdm9pZApwZXJmX2luc3RhbGxfaW5fY29udGV4dChzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0ICpjdHgsCgkJCXN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCwKCQkJaW50IGNwdSkKewoJc3RydWN0IHRhc2tfc3RydWN0ICp0YXNrID0gY3R4LT50YXNrOwoKCWlmICghdGFzaykgewoJCS8qCgkJICogUGVyIGNwdSBldmVudHMgYXJlIGluc3RhbGxlZCB2aWEgYW4gc21wIGNhbGwgYW5kCgkJICogdGhlIGluc3RhbGwgaXMgYWx3YXlzIHN1Y2Nlc3NmdWwuCgkJICovCgkJc21wX2NhbGxfZnVuY3Rpb25fc2luZ2xlKGNwdSwgX19wZXJmX2luc3RhbGxfaW5fY29udGV4dCwKCQkJCQkgZXZlbnQsIDEpOwoJCXJldHVybjsKCX0KCnJldHJ5OgoJdGFza19vbmNwdV9mdW5jdGlvbl9jYWxsKHRhc2ssIF9fcGVyZl9pbnN0YWxsX2luX2NvbnRleHQsCgkJCQkgZXZlbnQpOwoKCXNwaW5fbG9ja19pcnEoJmN0eC0+bG9jayk7CgkvKgoJICogd2UgbmVlZCB0byByZXRyeSB0aGUgc21wIGNhbGwuCgkgKi8KCWlmIChjdHgtPmlzX2FjdGl2ZSAmJiBsaXN0X2VtcHR5KCZldmVudC0+Z3JvdXBfZW50cnkpKSB7CgkJc3Bpbl91bmxvY2tfaXJxKCZjdHgtPmxvY2spOwoJCWdvdG8gcmV0cnk7Cgl9CgoJLyoKCSAqIFRoZSBsb2NrIHByZXZlbnRzIHRoYXQgdGhpcyBjb250ZXh0IGlzIHNjaGVkdWxlZCBpbiBzbyB3ZQoJICogY2FuIGFkZCB0aGUgZXZlbnQgc2FmZWx5LCBpZiBpdCB0aGUgY2FsbCBhYm92ZSBkaWQgbm90CgkgKiBzdWNjZWVkLgoJICovCglpZiAobGlzdF9lbXB0eSgmZXZlbnQtPmdyb3VwX2VudHJ5KSkKCQlhZGRfZXZlbnRfdG9fY3R4KGV2ZW50LCBjdHgpOwoJc3Bpbl91bmxvY2tfaXJxKCZjdHgtPmxvY2spOwp9CgovKgogKiBQdXQgYSBldmVudCBpbnRvIGluYWN0aXZlIHN0YXRlIGFuZCB1cGRhdGUgdGltZSBmaWVsZHMuCiAqIEVuYWJsaW5nIHRoZSBsZWFkZXIgb2YgYSBncm91cCBlZmZlY3RpdmVseSBlbmFibGVzIGFsbAogKiB0aGUgZ3JvdXAgbWVtYmVycyB0aGF0IGFyZW4ndCBleHBsaWNpdGx5IGRpc2FibGVkLCBzbyB3ZQogKiBoYXZlIHRvIHVwZGF0ZSB0aGVpciAtPnRzdGFtcF9lbmFibGVkIGFsc28uCiAqIE5vdGU6IHRoaXMgd29ya3MgZm9yIGdyb3VwIG1lbWJlcnMgYXMgd2VsbCBhcyBncm91cCBsZWFkZXJzCiAqIHNpbmNlIHRoZSBub24tbGVhZGVyIG1lbWJlcnMnIHNpYmxpbmdfbGlzdHMgd2lsbCBiZSBlbXB0eS4KICovCnN0YXRpYyB2b2lkIF9fcGVyZl9ldmVudF9tYXJrX2VuYWJsZWQoc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50LAoJCQkJCXN0cnVjdCBwZXJmX2V2ZW50X2NvbnRleHQgKmN0eCkKewoJc3RydWN0IHBlcmZfZXZlbnQgKnN1YjsKCglldmVudC0+c3RhdGUgPSBQRVJGX0VWRU5UX1NUQVRFX0lOQUNUSVZFOwoJZXZlbnQtPnRzdGFtcF9lbmFibGVkID0gY3R4LT50aW1lIC0gZXZlbnQtPnRvdGFsX3RpbWVfZW5hYmxlZDsKCWxpc3RfZm9yX2VhY2hfZW50cnkoc3ViLCAmZXZlbnQtPnNpYmxpbmdfbGlzdCwgZ3JvdXBfZW50cnkpCgkJaWYgKHN1Yi0+c3RhdGUgPj0gUEVSRl9FVkVOVF9TVEFURV9JTkFDVElWRSkKCQkJc3ViLT50c3RhbXBfZW5hYmxlZCA9CgkJCQljdHgtPnRpbWUgLSBzdWItPnRvdGFsX3RpbWVfZW5hYmxlZDsKfQoKLyoKICogQ3Jvc3MgQ1BVIGNhbGwgdG8gZW5hYmxlIGEgcGVyZm9ybWFuY2UgZXZlbnQKICovCnN0YXRpYyB2b2lkIF9fcGVyZl9ldmVudF9lbmFibGUodm9pZCAqaW5mbykKewoJc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50ID0gaW5mbzsKCXN0cnVjdCBwZXJmX2NwdV9jb250ZXh0ICpjcHVjdHggPSAmX19nZXRfY3B1X3ZhcihwZXJmX2NwdV9jb250ZXh0KTsKCXN0cnVjdCBwZXJmX2V2ZW50X2NvbnRleHQgKmN0eCA9IGV2ZW50LT5jdHg7CglzdHJ1Y3QgcGVyZl9ldmVudCAqbGVhZGVyID0gZXZlbnQtPmdyb3VwX2xlYWRlcjsKCWludCBlcnI7CgoJLyoKCSAqIElmIHRoaXMgaXMgYSBwZXItdGFzayBldmVudCwgbmVlZCB0byBjaGVjayB3aGV0aGVyIHRoaXMKCSAqIGV2ZW50J3MgdGFzayBpcyB0aGUgY3VycmVudCB0YXNrIG9uIHRoaXMgY3B1LgoJICovCglpZiAoY3R4LT50YXNrICYmIGNwdWN0eC0+dGFza19jdHggIT0gY3R4KSB7CgkJaWYgKGNwdWN0eC0+dGFza19jdHggfHwgY3R4LT50YXNrICE9IGN1cnJlbnQpCgkJCXJldHVybjsKCQljcHVjdHgtPnRhc2tfY3R4ID0gY3R4OwoJfQoKCXNwaW5fbG9jaygmY3R4LT5sb2NrKTsKCWN0eC0+aXNfYWN0aXZlID0gMTsKCXVwZGF0ZV9jb250ZXh0X3RpbWUoY3R4KTsKCglpZiAoZXZlbnQtPnN0YXRlID49IFBFUkZfRVZFTlRfU1RBVEVfSU5BQ1RJVkUpCgkJZ290byB1bmxvY2s7CglfX3BlcmZfZXZlbnRfbWFya19lbmFibGVkKGV2ZW50LCBjdHgpOwoKCS8qCgkgKiBJZiB0aGUgZXZlbnQgaXMgaW4gYSBncm91cCBhbmQgaXNuJ3QgdGhlIGdyb3VwIGxlYWRlciwKCSAqIHRoZW4gZG9uJ3QgcHV0IGl0IG9uIHVubGVzcyB0aGUgZ3JvdXAgaXMgb24uCgkgKi8KCWlmIChsZWFkZXIgIT0gZXZlbnQgJiYgbGVhZGVyLT5zdGF0ZSAhPSBQRVJGX0VWRU5UX1NUQVRFX0FDVElWRSkKCQlnb3RvIHVubG9jazsKCglpZiAoIWdyb3VwX2Nhbl9nb19vbihldmVudCwgY3B1Y3R4LCAxKSkgewoJCWVyciA9IC1FRVhJU1Q7Cgl9IGVsc2UgewoJCXBlcmZfZGlzYWJsZSgpOwoJCWlmIChldmVudCA9PSBsZWFkZXIpCgkJCWVyciA9IGdyb3VwX3NjaGVkX2luKGV2ZW50LCBjcHVjdHgsIGN0eCwKCQkJCQkgICAgIHNtcF9wcm9jZXNzb3JfaWQoKSk7CgkJZWxzZQoJCQllcnIgPSBldmVudF9zY2hlZF9pbihldmVudCwgY3B1Y3R4LCBjdHgsCgkJCQkJICAgICAgIHNtcF9wcm9jZXNzb3JfaWQoKSk7CgkJcGVyZl9lbmFibGUoKTsKCX0KCglpZiAoZXJyKSB7CgkJLyoKCQkgKiBJZiB0aGlzIGV2ZW50IGNhbid0IGdvIG9uIGFuZCBpdCdzIHBhcnQgb2YgYQoJCSAqIGdyb3VwLCB0aGVuIHRoZSB3aG9sZSBncm91cCBoYXMgdG8gY29tZSBvZmYuCgkJICovCgkJaWYgKGxlYWRlciAhPSBldmVudCkKCQkJZ3JvdXBfc2NoZWRfb3V0KGxlYWRlciwgY3B1Y3R4LCBjdHgpOwoJCWlmIChsZWFkZXItPmF0dHIucGlubmVkKSB7CgkJCXVwZGF0ZV9ncm91cF90aW1lcyhsZWFkZXIpOwoJCQlsZWFkZXItPnN0YXRlID0gUEVSRl9FVkVOVF9TVEFURV9FUlJPUjsKCQl9Cgl9CgogdW5sb2NrOgoJc3Bpbl91bmxvY2soJmN0eC0+bG9jayk7Cn0KCi8qCiAqIEVuYWJsZSBhIGV2ZW50LgogKgogKiBJZiBldmVudC0+Y3R4IGlzIGEgY2xvbmVkIGNvbnRleHQsIGNhbGxlcnMgbXVzdCBtYWtlIHN1cmUgdGhhdAogKiBldmVyeSB0YXNrIHN0cnVjdCB0aGF0IGV2ZW50LT5jdHgtPnRhc2sgY291bGQgcG9zc2libHkgcG9pbnQgdG8KICogcmVtYWlucyB2YWxpZC4gIFRoaXMgY29uZGl0aW9uIGlzIHNhdGlzZmllZCB3aGVuIGNhbGxlZCB0aHJvdWdoCiAqIHBlcmZfZXZlbnRfZm9yX2VhY2hfY2hpbGQgb3IgcGVyZl9ldmVudF9mb3JfZWFjaCBhcyBkZXNjcmliZWQKICogZm9yIHBlcmZfZXZlbnRfZGlzYWJsZS4KICovCnN0YXRpYyB2b2lkIHBlcmZfZXZlbnRfZW5hYmxlKHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCkKewoJc3RydWN0IHBlcmZfZXZlbnRfY29udGV4dCAqY3R4ID0gZXZlbnQtPmN0eDsKCXN0cnVjdCB0YXNrX3N0cnVjdCAqdGFzayA9IGN0eC0+dGFzazsKCglpZiAoIXRhc2spIHsKCQkvKgoJCSAqIEVuYWJsZSB0aGUgZXZlbnQgb24gdGhlIGNwdSB0aGF0IGl0J3Mgb24KCQkgKi8KCQlzbXBfY2FsbF9mdW5jdGlvbl9zaW5nbGUoZXZlbnQtPmNwdSwgX19wZXJmX2V2ZW50X2VuYWJsZSwKCQkJCQkgZXZlbnQsIDEpOwoJCXJldHVybjsKCX0KCglzcGluX2xvY2tfaXJxKCZjdHgtPmxvY2spOwoJaWYgKGV2ZW50LT5zdGF0ZSA+PSBQRVJGX0VWRU5UX1NUQVRFX0lOQUNUSVZFKQoJCWdvdG8gb3V0OwoKCS8qCgkgKiBJZiB0aGUgZXZlbnQgaXMgaW4gZXJyb3Igc3RhdGUsIGNsZWFyIHRoYXQgZmlyc3QuCgkgKiBUaGF0IHdheSwgaWYgd2Ugc2VlIHRoZSBldmVudCBpbiBlcnJvciBzdGF0ZSBiZWxvdywgd2UKCSAqIGtub3cgdGhhdCBpdCBoYXMgZ29uZSBiYWNrIGludG8gZXJyb3Igc3RhdGUsIGFzIGRpc3RpbmN0CgkgKiBmcm9tIHRoZSB0YXNrIGhhdmluZyBiZWVuIHNjaGVkdWxlZCBhd2F5IGJlZm9yZSB0aGUKCSAqIGNyb3NzLWNhbGwgYXJyaXZlZC4KCSAqLwoJaWYgKGV2ZW50LT5zdGF0ZSA9PSBQRVJGX0VWRU5UX1NUQVRFX0VSUk9SKQoJCWV2ZW50LT5zdGF0ZSA9IFBFUkZfRVZFTlRfU1RBVEVfT0ZGOwoKIHJldHJ5OgoJc3Bpbl91bmxvY2tfaXJxKCZjdHgtPmxvY2spOwoJdGFza19vbmNwdV9mdW5jdGlvbl9jYWxsKHRhc2ssIF9fcGVyZl9ldmVudF9lbmFibGUsIGV2ZW50KTsKCglzcGluX2xvY2tfaXJxKCZjdHgtPmxvY2spOwoKCS8qCgkgKiBJZiB0aGUgY29udGV4dCBpcyBhY3RpdmUgYW5kIHRoZSBldmVudCBpcyBzdGlsbCBvZmYsCgkgKiB3ZSBuZWVkIHRvIHJldHJ5IHRoZSBjcm9zcy1jYWxsLgoJICovCglpZiAoY3R4LT5pc19hY3RpdmUgJiYgZXZlbnQtPnN0YXRlID09IFBFUkZfRVZFTlRfU1RBVEVfT0ZGKQoJCWdvdG8gcmV0cnk7CgoJLyoKCSAqIFNpbmNlIHdlIGhhdmUgdGhlIGxvY2sgdGhpcyBjb250ZXh0IGNhbid0IGJlIHNjaGVkdWxlZAoJICogaW4sIHNvIHdlIGNhbiBjaGFuZ2UgdGhlIHN0YXRlIHNhZmVseS4KCSAqLwoJaWYgKGV2ZW50LT5zdGF0ZSA9PSBQRVJGX0VWRU5UX1NUQVRFX09GRikKCQlfX3BlcmZfZXZlbnRfbWFya19lbmFibGVkKGV2ZW50LCBjdHgpOwoKIG91dDoKCXNwaW5fdW5sb2NrX2lycSgmY3R4LT5sb2NrKTsKfQoKc3RhdGljIGludCBwZXJmX2V2ZW50X3JlZnJlc2goc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50LCBpbnQgcmVmcmVzaCkKewoJLyoKCSAqIG5vdCBzdXBwb3J0ZWQgb24gaW5oZXJpdGVkIGV2ZW50cwoJICovCglpZiAoZXZlbnQtPmF0dHIuaW5oZXJpdCkKCQlyZXR1cm4gLUVJTlZBTDsKCglhdG9taWNfYWRkKHJlZnJlc2gsICZldmVudC0+ZXZlbnRfbGltaXQpOwoJcGVyZl9ldmVudF9lbmFibGUoZXZlbnQpOwoKCXJldHVybiAwOwp9Cgp2b2lkIF9fcGVyZl9ldmVudF9zY2hlZF9vdXQoc3RydWN0IHBlcmZfZXZlbnRfY29udGV4dCAqY3R4LAoJCQkgICAgICBzdHJ1Y3QgcGVyZl9jcHVfY29udGV4dCAqY3B1Y3R4KQp7CglzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQ7CgoJc3Bpbl9sb2NrKCZjdHgtPmxvY2spOwoJY3R4LT5pc19hY3RpdmUgPSAwOwoJaWYgKGxpa2VseSghY3R4LT5ucl9ldmVudHMpKQoJCWdvdG8gb3V0OwoJdXBkYXRlX2NvbnRleHRfdGltZShjdHgpOwoKCXBlcmZfZGlzYWJsZSgpOwoJaWYgKGN0eC0+bnJfYWN0aXZlKQoJCWxpc3RfZm9yX2VhY2hfZW50cnkoZXZlbnQsICZjdHgtPmdyb3VwX2xpc3QsIGdyb3VwX2VudHJ5KQoJCQlncm91cF9zY2hlZF9vdXQoZXZlbnQsIGNwdWN0eCwgY3R4KTsKCglwZXJmX2VuYWJsZSgpOwogb3V0OgoJc3Bpbl91bmxvY2soJmN0eC0+bG9jayk7Cn0KCi8qCiAqIFRlc3Qgd2hldGhlciB0d28gY29udGV4dHMgYXJlIGVxdWl2YWxlbnQsIGkuZS4gd2hldGhlciB0aGV5CiAqIGhhdmUgYm90aCBiZWVuIGNsb25lZCBmcm9tIHRoZSBzYW1lIHZlcnNpb24gb2YgdGhlIHNhbWUgY29udGV4dAogKiBhbmQgdGhleSBib3RoIGhhdmUgdGhlIHNhbWUgbnVtYmVyIG9mIGVuYWJsZWQgZXZlbnRzLgogKiBJZiB0aGUgbnVtYmVyIG9mIGVuYWJsZWQgZXZlbnRzIGlzIHRoZSBzYW1lLCB0aGVuIHRoZSBzZXQKICogb2YgZW5hYmxlZCBldmVudHMgc2hvdWxkIGJlIHRoZSBzYW1lLCBiZWNhdXNlIHRoZXNlIGFyZSBib3RoCiAqIGluaGVyaXRlZCBjb250ZXh0cywgdGhlcmVmb3JlIHdlIGNhbid0IGFjY2VzcyBpbmRpdmlkdWFsIGV2ZW50cwogKiBpbiB0aGVtIGRpcmVjdGx5IHdpdGggYW4gZmQ7IHdlIGNhbiBvbmx5IGVuYWJsZS9kaXNhYmxlIGFsbAogKiBldmVudHMgdmlhIHByY3RsLCBvciBlbmFibGUvZGlzYWJsZSBhbGwgZXZlbnRzIGluIGEgZmFtaWx5CiAqIHZpYSBpb2N0bCwgd2hpY2ggd2lsbCBoYXZlIHRoZSBzYW1lIGVmZmVjdCBvbiBib3RoIGNvbnRleHRzLgogKi8Kc3RhdGljIGludCBjb250ZXh0X2VxdWl2KHN0cnVjdCBwZXJmX2V2ZW50X2NvbnRleHQgKmN0eDEsCgkJCSBzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0ICpjdHgyKQp7CglyZXR1cm4gY3R4MS0+cGFyZW50X2N0eCAmJiBjdHgxLT5wYXJlbnRfY3R4ID09IGN0eDItPnBhcmVudF9jdHgKCQkmJiBjdHgxLT5wYXJlbnRfZ2VuID09IGN0eDItPnBhcmVudF9nZW4KCQkmJiAhY3R4MS0+cGluX2NvdW50ICYmICFjdHgyLT5waW5fY291bnQ7Cn0KCnN0YXRpYyB2b2lkIF9fcGVyZl9ldmVudF9yZWFkKHZvaWQgKmV2ZW50KTsKCnN0YXRpYyB2b2lkIF9fcGVyZl9ldmVudF9zeW5jX3N0YXQoc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50LAoJCQkJICAgICBzdHJ1Y3QgcGVyZl9ldmVudCAqbmV4dF9ldmVudCkKewoJdTY0IHZhbHVlOwoKCWlmICghZXZlbnQtPmF0dHIuaW5oZXJpdF9zdGF0KQoJCXJldHVybjsKCgkvKgoJICogVXBkYXRlIHRoZSBldmVudCB2YWx1ZSwgd2UgY2Fubm90IHVzZSBwZXJmX2V2ZW50X3JlYWQoKQoJICogYmVjYXVzZSB3ZSdyZSBpbiB0aGUgbWlkZGxlIG9mIGEgY29udGV4dCBzd2l0Y2ggYW5kIGhhdmUgSVJRcwoJICogZGlzYWJsZWQsIHdoaWNoIHVwc2V0cyBzbXBfY2FsbF9mdW5jdGlvbl9zaW5nbGUoKSwgaG93ZXZlcgoJICogd2Uga25vdyB0aGUgZXZlbnQgbXVzdCBiZSBvbiB0aGUgY3VycmVudCBDUFUsIHRoZXJlZm9yZSB3ZQoJICogZG9uJ3QgbmVlZCB0byB1c2UgaXQuCgkgKi8KCXN3aXRjaCAoZXZlbnQtPnN0YXRlKSB7CgljYXNlIFBFUkZfRVZFTlRfU1RBVEVfQUNUSVZFOgoJCV9fcGVyZl9ldmVudF9yZWFkKGV2ZW50KTsKCQlicmVhazsKCgljYXNlIFBFUkZfRVZFTlRfU1RBVEVfSU5BQ1RJVkU6CgkJdXBkYXRlX2V2ZW50X3RpbWVzKGV2ZW50KTsKCQlicmVhazsKCglkZWZhdWx0OgoJCWJyZWFrOwoJfQoKCS8qCgkgKiBJbiBvcmRlciB0byBrZWVwIHBlci10YXNrIHN0YXRzIHJlbGlhYmxlIHdlIG5lZWQgdG8gZmxpcCB0aGUgZXZlbnQKCSAqIHZhbHVlcyB3aGVuIHdlIGZsaXAgdGhlIGNvbnRleHRzLgoJICovCgl2YWx1ZSA9IGF0b21pYzY0X3JlYWQoJm5leHRfZXZlbnQtPmNvdW50KTsKCXZhbHVlID0gYXRvbWljNjRfeGNoZygmZXZlbnQtPmNvdW50LCB2YWx1ZSk7CglhdG9taWM2NF9zZXQoJm5leHRfZXZlbnQtPmNvdW50LCB2YWx1ZSk7CgoJc3dhcChldmVudC0+dG90YWxfdGltZV9lbmFibGVkLCBuZXh0X2V2ZW50LT50b3RhbF90aW1lX2VuYWJsZWQpOwoJc3dhcChldmVudC0+dG90YWxfdGltZV9ydW5uaW5nLCBuZXh0X2V2ZW50LT50b3RhbF90aW1lX3J1bm5pbmcpOwoKCS8qCgkgKiBTaW5jZSB3ZSBzd2l6emxlZCB0aGUgdmFsdWVzLCB1cGRhdGUgdGhlIHVzZXIgdmlzaWJsZSBkYXRhIHRvby4KCSAqLwoJcGVyZl9ldmVudF91cGRhdGVfdXNlcnBhZ2UoZXZlbnQpOwoJcGVyZl9ldmVudF91cGRhdGVfdXNlcnBhZ2UobmV4dF9ldmVudCk7Cn0KCiNkZWZpbmUgbGlzdF9uZXh0X2VudHJ5KHBvcywgbWVtYmVyKSBcCglsaXN0X2VudHJ5KHBvcy0+bWVtYmVyLm5leHQsIHR5cGVvZigqcG9zKSwgbWVtYmVyKQoKc3RhdGljIHZvaWQgcGVyZl9ldmVudF9zeW5jX3N0YXQoc3RydWN0IHBlcmZfZXZlbnRfY29udGV4dCAqY3R4LAoJCQkJICAgc3RydWN0IHBlcmZfZXZlbnRfY29udGV4dCAqbmV4dF9jdHgpCnsKCXN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCwgKm5leHRfZXZlbnQ7CgoJaWYgKCFjdHgtPm5yX3N0YXQpCgkJcmV0dXJuOwoKCWV2ZW50ID0gbGlzdF9maXJzdF9lbnRyeSgmY3R4LT5ldmVudF9saXN0LAoJCQkJICAgc3RydWN0IHBlcmZfZXZlbnQsIGV2ZW50X2VudHJ5KTsKCgluZXh0X2V2ZW50ID0gbGlzdF9maXJzdF9lbnRyeSgmbmV4dF9jdHgtPmV2ZW50X2xpc3QsCgkJCQkJc3RydWN0IHBlcmZfZXZlbnQsIGV2ZW50X2VudHJ5KTsKCgl3aGlsZSAoJmV2ZW50LT5ldmVudF9lbnRyeSAhPSAmY3R4LT5ldmVudF9saXN0ICYmCgkgICAgICAgJm5leHRfZXZlbnQtPmV2ZW50X2VudHJ5ICE9ICZuZXh0X2N0eC0+ZXZlbnRfbGlzdCkgewoKCQlfX3BlcmZfZXZlbnRfc3luY19zdGF0KGV2ZW50LCBuZXh0X2V2ZW50KTsKCgkJZXZlbnQgPSBsaXN0X25leHRfZW50cnkoZXZlbnQsIGV2ZW50X2VudHJ5KTsKCQluZXh0X2V2ZW50ID0gbGlzdF9uZXh0X2VudHJ5KG5leHRfZXZlbnQsIGV2ZW50X2VudHJ5KTsKCX0KfQoKLyoKICogQ2FsbGVkIGZyb20gc2NoZWR1bGVyIHRvIHJlbW92ZSB0aGUgZXZlbnRzIG9mIHRoZSBjdXJyZW50IHRhc2ssCiAqIHdpdGggaW50ZXJydXB0cyBkaXNhYmxlZC4KICoKICogV2Ugc3RvcCBlYWNoIGV2ZW50IGFuZCB1cGRhdGUgdGhlIGV2ZW50IHZhbHVlIGluIGV2ZW50LT5jb3VudC4KICoKICogVGhpcyBkb2VzIG5vdCBwcm90ZWN0IHVzIGFnYWluc3QgTk1JLCBidXQgZGlzYWJsZSgpCiAqIHNldHMgdGhlIGRpc2FibGVkIGJpdCBpbiB0aGUgY29udHJvbCBmaWVsZCBvZiBldmVudCBfYmVmb3JlXwogKiBhY2Nlc3NpbmcgdGhlIGV2ZW50IGNvbnRyb2wgcmVnaXN0ZXIuIElmIGEgTk1JIGhpdHMsIHRoZW4gaXQgd2lsbAogKiBub3QgcmVzdGFydCB0aGUgZXZlbnQuCiAqLwp2b2lkIHBlcmZfZXZlbnRfdGFza19zY2hlZF9vdXQoc3RydWN0IHRhc2tfc3RydWN0ICp0YXNrLAoJCQkJIHN0cnVjdCB0YXNrX3N0cnVjdCAqbmV4dCwgaW50IGNwdSkKewoJc3RydWN0IHBlcmZfY3B1X2NvbnRleHQgKmNwdWN0eCA9ICZwZXJfY3B1KHBlcmZfY3B1X2NvbnRleHQsIGNwdSk7CglzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0ICpjdHggPSB0YXNrLT5wZXJmX2V2ZW50X2N0eHA7CglzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0ICpuZXh0X2N0eDsKCXN0cnVjdCBwZXJmX2V2ZW50X2NvbnRleHQgKnBhcmVudDsKCXN0cnVjdCBwdF9yZWdzICpyZWdzOwoJaW50IGRvX3N3aXRjaCA9IDE7CgoJcmVncyA9IHRhc2tfcHRfcmVncyh0YXNrKTsKCXBlcmZfc3dfZXZlbnQoUEVSRl9DT1VOVF9TV19DT05URVhUX1NXSVRDSEVTLCAxLCAxLCByZWdzLCAwKTsKCglpZiAobGlrZWx5KCFjdHggfHwgIWNwdWN0eC0+dGFza19jdHgpKQoJCXJldHVybjsKCgl1cGRhdGVfY29udGV4dF90aW1lKGN0eCk7CgoJcmN1X3JlYWRfbG9jaygpOwoJcGFyZW50ID0gcmN1X2RlcmVmZXJlbmNlKGN0eC0+cGFyZW50X2N0eCk7CgluZXh0X2N0eCA9IG5leHQtPnBlcmZfZXZlbnRfY3R4cDsKCWlmIChwYXJlbnQgJiYgbmV4dF9jdHggJiYKCSAgICByY3VfZGVyZWZlcmVuY2UobmV4dF9jdHgtPnBhcmVudF9jdHgpID09IHBhcmVudCkgewoJCS8qCgkJICogTG9va3MgbGlrZSB0aGUgdHdvIGNvbnRleHRzIGFyZSBjbG9uZXMsIHNvIHdlIG1pZ2h0IGJlCgkJICogYWJsZSB0byBvcHRpbWl6ZSB0aGUgY29udGV4dCBzd2l0Y2guICBXZSBsb2NrIGJvdGgKCQkgKiBjb250ZXh0cyBhbmQgY2hlY2sgdGhhdCB0aGV5IGFyZSBjbG9uZXMgdW5kZXIgdGhlCgkJICogbG9jayAoaW5jbHVkaW5nIHJlLWNoZWNraW5nIHRoYXQgbmVpdGhlciBoYXMgYmVlbgoJCSAqIHVuY2xvbmVkIGluIHRoZSBtZWFudGltZSkuICBJdCBkb2Vzbid0IG1hdHRlciB3aGljaAoJCSAqIG9yZGVyIHdlIHRha2UgdGhlIGxvY2tzIGJlY2F1c2Ugbm8gb3RoZXIgY3B1IGNvdWxkCgkJICogYmUgdHJ5aW5nIHRvIGxvY2sgYm90aCBvZiB0aGVzZSB0YXNrcy4KCQkgKi8KCQlzcGluX2xvY2soJmN0eC0+bG9jayk7CgkJc3Bpbl9sb2NrX25lc3RlZCgmbmV4dF9jdHgtPmxvY2ssIFNJTkdMRV9ERVBUSF9ORVNUSU5HKTsKCQlpZiAoY29udGV4dF9lcXVpdihjdHgsIG5leHRfY3R4KSkgewoJCQkvKgoJCQkgKiBYWFggZG8gd2UgbmVlZCBhIG1lbW9yeSBiYXJyaWVyIG9mIHNvcnRzCgkJCSAqIHdydCB0byByY3VfZGVyZWZlcmVuY2UoKSBvZiBwZXJmX2V2ZW50X2N0eHAKCQkJICovCgkJCXRhc2stPnBlcmZfZXZlbnRfY3R4cCA9IG5leHRfY3R4OwoJCQluZXh0LT5wZXJmX2V2ZW50X2N0eHAgPSBjdHg7CgkJCWN0eC0+dGFzayA9IG5leHQ7CgkJCW5leHRfY3R4LT50YXNrID0gdGFzazsKCQkJZG9fc3dpdGNoID0gMDsKCgkJCXBlcmZfZXZlbnRfc3luY19zdGF0KGN0eCwgbmV4dF9jdHgpOwoJCX0KCQlzcGluX3VubG9jaygmbmV4dF9jdHgtPmxvY2spOwoJCXNwaW5fdW5sb2NrKCZjdHgtPmxvY2spOwoJfQoJcmN1X3JlYWRfdW5sb2NrKCk7CgoJaWYgKGRvX3N3aXRjaCkgewoJCV9fcGVyZl9ldmVudF9zY2hlZF9vdXQoY3R4LCBjcHVjdHgpOwoJCWNwdWN0eC0+dGFza19jdHggPSBOVUxMOwoJfQp9CgovKgogKiBDYWxsZWQgd2l0aCBJUlFzIGRpc2FibGVkCiAqLwpzdGF0aWMgdm9pZCBfX3BlcmZfZXZlbnRfdGFza19zY2hlZF9vdXQoc3RydWN0IHBlcmZfZXZlbnRfY29udGV4dCAqY3R4KQp7CglzdHJ1Y3QgcGVyZl9jcHVfY29udGV4dCAqY3B1Y3R4ID0gJl9fZ2V0X2NwdV92YXIocGVyZl9jcHVfY29udGV4dCk7CgoJaWYgKCFjcHVjdHgtPnRhc2tfY3R4KQoJCXJldHVybjsKCglpZiAoV0FSTl9PTl9PTkNFKGN0eCAhPSBjcHVjdHgtPnRhc2tfY3R4KSkKCQlyZXR1cm47CgoJX19wZXJmX2V2ZW50X3NjaGVkX291dChjdHgsIGNwdWN0eCk7CgljcHVjdHgtPnRhc2tfY3R4ID0gTlVMTDsKfQoKLyoKICogQ2FsbGVkIHdpdGggSVJRcyBkaXNhYmxlZAogKi8Kc3RhdGljIHZvaWQgcGVyZl9ldmVudF9jcHVfc2NoZWRfb3V0KHN0cnVjdCBwZXJmX2NwdV9jb250ZXh0ICpjcHVjdHgpCnsKCV9fcGVyZl9ldmVudF9zY2hlZF9vdXQoJmNwdWN0eC0+Y3R4LCBjcHVjdHgpOwp9CgpzdGF0aWMgdm9pZApfX3BlcmZfZXZlbnRfc2NoZWRfaW4oc3RydWN0IHBlcmZfZXZlbnRfY29udGV4dCAqY3R4LAoJCQlzdHJ1Y3QgcGVyZl9jcHVfY29udGV4dCAqY3B1Y3R4LCBpbnQgY3B1KQp7CglzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQ7CglpbnQgY2FuX2FkZF9odyA9IDE7CgoJc3Bpbl9sb2NrKCZjdHgtPmxvY2spOwoJY3R4LT5pc19hY3RpdmUgPSAxOwoJaWYgKGxpa2VseSghY3R4LT5ucl9ldmVudHMpKQoJCWdvdG8gb3V0OwoKCWN0eC0+dGltZXN0YW1wID0gcGVyZl9jbG9jaygpOwoKCXBlcmZfZGlzYWJsZSgpOwoKCS8qCgkgKiBGaXJzdCBnbyB0aHJvdWdoIHRoZSBsaXN0IGFuZCBwdXQgb24gYW55IHBpbm5lZCBncm91cHMKCSAqIGluIG9yZGVyIHRvIGdpdmUgdGhlbSB0aGUgYmVzdCBjaGFuY2Ugb2YgZ29pbmcgb24uCgkgKi8KCWxpc3RfZm9yX2VhY2hfZW50cnkoZXZlbnQsICZjdHgtPmdyb3VwX2xpc3QsIGdyb3VwX2VudHJ5KSB7CgkJaWYgKGV2ZW50LT5zdGF0ZSA8PSBQRVJGX0VWRU5UX1NUQVRFX09GRiB8fAoJCSAgICAhZXZlbnQtPmF0dHIucGlubmVkKQoJCQljb250aW51ZTsKCQlpZiAoZXZlbnQtPmNwdSAhPSAtMSAmJiBldmVudC0+Y3B1ICE9IGNwdSkKCQkJY29udGludWU7CgoJCWlmIChncm91cF9jYW5fZ29fb24oZXZlbnQsIGNwdWN0eCwgMSkpCgkJCWdyb3VwX3NjaGVkX2luKGV2ZW50LCBjcHVjdHgsIGN0eCwgY3B1KTsKCgkJLyoKCQkgKiBJZiB0aGlzIHBpbm5lZCBncm91cCBoYXNuJ3QgYmVlbiBzY2hlZHVsZWQsCgkJICogcHV0IGl0IGluIGVycm9yIHN0YXRlLgoJCSAqLwoJCWlmIChldmVudC0+c3RhdGUgPT0gUEVSRl9FVkVOVF9TVEFURV9JTkFDVElWRSkgewoJCQl1cGRhdGVfZ3JvdXBfdGltZXMoZXZlbnQpOwoJCQlldmVudC0+c3RhdGUgPSBQRVJGX0VWRU5UX1NUQVRFX0VSUk9SOwoJCX0KCX0KCglsaXN0X2Zvcl9lYWNoX2VudHJ5KGV2ZW50LCAmY3R4LT5ncm91cF9saXN0LCBncm91cF9lbnRyeSkgewoJCS8qCgkJICogSWdub3JlIGV2ZW50cyBpbiBPRkYgb3IgRVJST1Igc3RhdGUsIGFuZAoJCSAqIGlnbm9yZSBwaW5uZWQgZXZlbnRzIHNpbmNlIHdlIGRpZCB0aGVtIGFscmVhZHkuCgkJICovCgkJaWYgKGV2ZW50LT5zdGF0ZSA8PSBQRVJGX0VWRU5UX1NUQVRFX09GRiB8fAoJCSAgICBldmVudC0+YXR0ci5waW5uZWQpCgkJCWNvbnRpbnVlOwoKCQkvKgoJCSAqIExpc3RlbiB0byB0aGUgJ2NwdScgc2NoZWR1bGluZyBmaWx0ZXIgY29uc3RyYWludAoJCSAqIG9mIGV2ZW50czoKCQkgKi8KCQlpZiAoZXZlbnQtPmNwdSAhPSAtMSAmJiBldmVudC0+Y3B1ICE9IGNwdSkKCQkJY29udGludWU7CgoJCWlmIChncm91cF9jYW5fZ29fb24oZXZlbnQsIGNwdWN0eCwgY2FuX2FkZF9odykpCgkJCWlmIChncm91cF9zY2hlZF9pbihldmVudCwgY3B1Y3R4LCBjdHgsIGNwdSkpCgkJCQljYW5fYWRkX2h3ID0gMDsKCX0KCXBlcmZfZW5hYmxlKCk7CiBvdXQ6CglzcGluX3VubG9jaygmY3R4LT5sb2NrKTsKfQoKLyoKICogQ2FsbGVkIGZyb20gc2NoZWR1bGVyIHRvIGFkZCB0aGUgZXZlbnRzIG9mIHRoZSBjdXJyZW50IHRhc2sKICogd2l0aCBpbnRlcnJ1cHRzIGRpc2FibGVkLgogKgogKiBXZSByZXN0b3JlIHRoZSBldmVudCB2YWx1ZSBhbmQgdGhlbiBlbmFibGUgaXQuCiAqCiAqIFRoaXMgZG9lcyBub3QgcHJvdGVjdCB1cyBhZ2FpbnN0IE5NSSwgYnV0IGVuYWJsZSgpCiAqIHNldHMgdGhlIGVuYWJsZWQgYml0IGluIHRoZSBjb250cm9sIGZpZWxkIG9mIGV2ZW50IF9iZWZvcmVfCiAqIGFjY2Vzc2luZyB0aGUgZXZlbnQgY29udHJvbCByZWdpc3Rlci4gSWYgYSBOTUkgaGl0cywgdGhlbiBpdCB3aWxsCiAqIGtlZXAgdGhlIGV2ZW50IHJ1bm5pbmcuCiAqLwp2b2lkIHBlcmZfZXZlbnRfdGFza19zY2hlZF9pbihzdHJ1Y3QgdGFza19zdHJ1Y3QgKnRhc2ssIGludCBjcHUpCnsKCXN0cnVjdCBwZXJmX2NwdV9jb250ZXh0ICpjcHVjdHggPSAmcGVyX2NwdShwZXJmX2NwdV9jb250ZXh0LCBjcHUpOwoJc3RydWN0IHBlcmZfZXZlbnRfY29udGV4dCAqY3R4ID0gdGFzay0+cGVyZl9ldmVudF9jdHhwOwoKCWlmIChsaWtlbHkoIWN0eCkpCgkJcmV0dXJuOwoJaWYgKGNwdWN0eC0+dGFza19jdHggPT0gY3R4KQoJCXJldHVybjsKCV9fcGVyZl9ldmVudF9zY2hlZF9pbihjdHgsIGNwdWN0eCwgY3B1KTsKCWNwdWN0eC0+dGFza19jdHggPSBjdHg7Cn0KCnN0YXRpYyB2b2lkIHBlcmZfZXZlbnRfY3B1X3NjaGVkX2luKHN0cnVjdCBwZXJmX2NwdV9jb250ZXh0ICpjcHVjdHgsIGludCBjcHUpCnsKCXN0cnVjdCBwZXJmX2V2ZW50X2NvbnRleHQgKmN0eCA9ICZjcHVjdHgtPmN0eDsKCglfX3BlcmZfZXZlbnRfc2NoZWRfaW4oY3R4LCBjcHVjdHgsIGNwdSk7Cn0KCiNkZWZpbmUgTUFYX0lOVEVSUlVQVFMgKH4wVUxMKQoKc3RhdGljIHZvaWQgcGVyZl9sb2dfdGhyb3R0bGUoc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50LCBpbnQgZW5hYmxlKTsKCnN0YXRpYyB2b2lkIHBlcmZfYWRqdXN0X3BlcmlvZChzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQsIHU2NCBldmVudHMpCnsKCXN0cnVjdCBod19wZXJmX2V2ZW50ICpod2MgPSAmZXZlbnQtPmh3OwoJdTY0IHBlcmlvZCwgc2FtcGxlX3BlcmlvZDsKCXM2NCBkZWx0YTsKCglldmVudHMgKj0gaHdjLT5zYW1wbGVfcGVyaW9kOwoJcGVyaW9kID0gZGl2NjRfdTY0KGV2ZW50cywgZXZlbnQtPmF0dHIuc2FtcGxlX2ZyZXEpOwoKCWRlbHRhID0gKHM2NCkocGVyaW9kIC0gaHdjLT5zYW1wbGVfcGVyaW9kKTsKCWRlbHRhID0gKGRlbHRhICsgNykgLyA4OyAvKiBsb3cgcGFzcyBmaWx0ZXIgKi8KCglzYW1wbGVfcGVyaW9kID0gaHdjLT5zYW1wbGVfcGVyaW9kICsgZGVsdGE7CgoJaWYgKCFzYW1wbGVfcGVyaW9kKQoJCXNhbXBsZV9wZXJpb2QgPSAxOwoKCWh3Yy0+c2FtcGxlX3BlcmlvZCA9IHNhbXBsZV9wZXJpb2Q7Cn0KCnN0YXRpYyB2b2lkIHBlcmZfY3R4X2FkanVzdF9mcmVxKHN0cnVjdCBwZXJmX2V2ZW50X2NvbnRleHQgKmN0eCkKewoJc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50OwoJc3RydWN0IGh3X3BlcmZfZXZlbnQgKmh3YzsKCXU2NCBpbnRlcnJ1cHRzLCBmcmVxOwoKCXNwaW5fbG9jaygmY3R4LT5sb2NrKTsKCWxpc3RfZm9yX2VhY2hfZW50cnlfcmN1KGV2ZW50LCAmY3R4LT5ldmVudF9saXN0LCBldmVudF9lbnRyeSkgewoJCWlmIChldmVudC0+c3RhdGUgIT0gUEVSRl9FVkVOVF9TVEFURV9BQ1RJVkUpCgkJCWNvbnRpbnVlOwoKCQlod2MgPSAmZXZlbnQtPmh3OwoKCQlpbnRlcnJ1cHRzID0gaHdjLT5pbnRlcnJ1cHRzOwoJCWh3Yy0+aW50ZXJydXB0cyA9IDA7CgoJCS8qCgkJICogdW50aHJvdHRsZSBldmVudHMgb24gdGhlIHRpY2sKCQkgKi8KCQlpZiAoaW50ZXJydXB0cyA9PSBNQVhfSU5URVJSVVBUUykgewoJCQlwZXJmX2xvZ190aHJvdHRsZShldmVudCwgMSk7CgkJCWV2ZW50LT5wbXUtPnVudGhyb3R0bGUoZXZlbnQpOwoJCQlpbnRlcnJ1cHRzID0gMipzeXNjdGxfcGVyZl9ldmVudF9zYW1wbGVfcmF0ZS9IWjsKCQl9CgoJCWlmICghZXZlbnQtPmF0dHIuZnJlcSB8fCAhZXZlbnQtPmF0dHIuc2FtcGxlX2ZyZXEpCgkJCWNvbnRpbnVlOwoKCQkvKgoJCSAqIGlmIHRoZSBzcGVjaWZpZWQgZnJlcSA8IEhaIHRoZW4gd2UgbmVlZCB0byBza2lwIHRpY2tzCgkJICovCgkJaWYgKGV2ZW50LT5hdHRyLnNhbXBsZV9mcmVxIDwgSFopIHsKCQkJZnJlcSA9IGV2ZW50LT5hdHRyLnNhbXBsZV9mcmVxOwoKCQkJaHdjLT5mcmVxX2NvdW50ICs9IGZyZXE7CgkJCWh3Yy0+ZnJlcV9pbnRlcnJ1cHRzICs9IGludGVycnVwdHM7CgoJCQlpZiAoaHdjLT5mcmVxX2NvdW50IDwgSFopCgkJCQljb250aW51ZTsKCgkJCWludGVycnVwdHMgPSBod2MtPmZyZXFfaW50ZXJydXB0czsKCQkJaHdjLT5mcmVxX2ludGVycnVwdHMgPSAwOwoJCQlod2MtPmZyZXFfY291bnQgLT0gSFo7CgkJfSBlbHNlCgkJCWZyZXEgPSBIWjsKCgkJcGVyZl9hZGp1c3RfcGVyaW9kKGV2ZW50LCBmcmVxICogaW50ZXJydXB0cyk7CgoJCS8qCgkJICogSW4gb3JkZXIgdG8gYXZvaWQgYmVpbmcgc3RhbGxlZCBieSBhbiAoYWNjaWRlbnRhbCkgaHVnZQoJCSAqIHNhbXBsZSBwZXJpb2QsIGZvcmNlIHJlc2V0IHRoZSBzYW1wbGUgcGVyaW9kIGlmIHdlIGRpZG4ndAoJCSAqIGdldCBhbnkgZXZlbnRzIGluIHRoaXMgZnJlcSBwZXJpb2QuCgkJICovCgkJaWYgKCFpbnRlcnJ1cHRzKSB7CgkJCXBlcmZfZGlzYWJsZSgpOwoJCQlldmVudC0+cG11LT5kaXNhYmxlKGV2ZW50KTsKCQkJYXRvbWljNjRfc2V0KCZod2MtPnBlcmlvZF9sZWZ0LCAwKTsKCQkJZXZlbnQtPnBtdS0+ZW5hYmxlKGV2ZW50KTsKCQkJcGVyZl9lbmFibGUoKTsKCQl9Cgl9CglzcGluX3VubG9jaygmY3R4LT5sb2NrKTsKfQoKLyoKICogUm91bmQtcm9iaW4gYSBjb250ZXh0J3MgZXZlbnRzOgogKi8Kc3RhdGljIHZvaWQgcm90YXRlX2N0eChzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0ICpjdHgpCnsKCXN0cnVjdCBwZXJmX2V2ZW50ICpldmVudDsKCglpZiAoIWN0eC0+bnJfZXZlbnRzKQoJCXJldHVybjsKCglzcGluX2xvY2soJmN0eC0+bG9jayk7CgkvKgoJICogUm90YXRlIHRoZSBmaXJzdCBlbnRyeSBsYXN0ICh3b3JrcyBqdXN0IGZpbmUgZm9yIGdyb3VwIGV2ZW50cyB0b28pOgoJICovCglwZXJmX2Rpc2FibGUoKTsKCWxpc3RfZm9yX2VhY2hfZW50cnkoZXZlbnQsICZjdHgtPmdyb3VwX2xpc3QsIGdyb3VwX2VudHJ5KSB7CgkJbGlzdF9tb3ZlX3RhaWwoJmV2ZW50LT5ncm91cF9lbnRyeSwgJmN0eC0+Z3JvdXBfbGlzdCk7CgkJYnJlYWs7Cgl9CglwZXJmX2VuYWJsZSgpOwoKCXNwaW5fdW5sb2NrKCZjdHgtPmxvY2spOwp9Cgp2b2lkIHBlcmZfZXZlbnRfdGFza190aWNrKHN0cnVjdCB0YXNrX3N0cnVjdCAqY3VyciwgaW50IGNwdSkKewoJc3RydWN0IHBlcmZfY3B1X2NvbnRleHQgKmNwdWN0eDsKCXN0cnVjdCBwZXJmX2V2ZW50X2NvbnRleHQgKmN0eDsKCglpZiAoIWF0b21pY19yZWFkKCZucl9ldmVudHMpKQoJCXJldHVybjsKCgljcHVjdHggPSAmcGVyX2NwdShwZXJmX2NwdV9jb250ZXh0LCBjcHUpOwoJY3R4ID0gY3Vyci0+cGVyZl9ldmVudF9jdHhwOwoKCXBlcmZfY3R4X2FkanVzdF9mcmVxKCZjcHVjdHgtPmN0eCk7CglpZiAoY3R4KQoJCXBlcmZfY3R4X2FkanVzdF9mcmVxKGN0eCk7CgoJcGVyZl9ldmVudF9jcHVfc2NoZWRfb3V0KGNwdWN0eCk7CglpZiAoY3R4KQoJCV9fcGVyZl9ldmVudF90YXNrX3NjaGVkX291dChjdHgpOwoKCXJvdGF0ZV9jdHgoJmNwdWN0eC0+Y3R4KTsKCWlmIChjdHgpCgkJcm90YXRlX2N0eChjdHgpOwoKCXBlcmZfZXZlbnRfY3B1X3NjaGVkX2luKGNwdWN0eCwgY3B1KTsKCWlmIChjdHgpCgkJcGVyZl9ldmVudF90YXNrX3NjaGVkX2luKGN1cnIsIGNwdSk7Cn0KCi8qCiAqIEVuYWJsZSBhbGwgb2YgYSB0YXNrJ3MgZXZlbnRzIHRoYXQgaGF2ZSBiZWVuIG1hcmtlZCBlbmFibGUtb24tZXhlYy4KICogVGhpcyBleHBlY3RzIHRhc2sgPT0gY3VycmVudC4KICovCnN0YXRpYyB2b2lkIHBlcmZfZXZlbnRfZW5hYmxlX29uX2V4ZWMoc3RydWN0IHRhc2tfc3RydWN0ICp0YXNrKQp7CglzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0ICpjdHg7CglzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQ7Cgl1bnNpZ25lZCBsb25nIGZsYWdzOwoJaW50IGVuYWJsZWQgPSAwOwoKCWxvY2FsX2lycV9zYXZlKGZsYWdzKTsKCWN0eCA9IHRhc2stPnBlcmZfZXZlbnRfY3R4cDsKCWlmICghY3R4IHx8ICFjdHgtPm5yX2V2ZW50cykKCQlnb3RvIG91dDsKCglfX3BlcmZfZXZlbnRfdGFza19zY2hlZF9vdXQoY3R4KTsKCglzcGluX2xvY2soJmN0eC0+bG9jayk7CgoJbGlzdF9mb3JfZWFjaF9lbnRyeShldmVudCwgJmN0eC0+Z3JvdXBfbGlzdCwgZ3JvdXBfZW50cnkpIHsKCQlpZiAoIWV2ZW50LT5hdHRyLmVuYWJsZV9vbl9leGVjKQoJCQljb250aW51ZTsKCQlldmVudC0+YXR0ci5lbmFibGVfb25fZXhlYyA9IDA7CgkJaWYgKGV2ZW50LT5zdGF0ZSA+PSBQRVJGX0VWRU5UX1NUQVRFX0lOQUNUSVZFKQoJCQljb250aW51ZTsKCQlfX3BlcmZfZXZlbnRfbWFya19lbmFibGVkKGV2ZW50LCBjdHgpOwoJCWVuYWJsZWQgPSAxOwoJfQoKCS8qCgkgKiBVbmNsb25lIHRoaXMgY29udGV4dCBpZiB3ZSBlbmFibGVkIGFueSBldmVudC4KCSAqLwoJaWYgKGVuYWJsZWQpCgkJdW5jbG9uZV9jdHgoY3R4KTsKCglzcGluX3VubG9jaygmY3R4LT5sb2NrKTsKCglwZXJmX2V2ZW50X3Rhc2tfc2NoZWRfaW4odGFzaywgc21wX3Byb2Nlc3Nvcl9pZCgpKTsKIG91dDoKCWxvY2FsX2lycV9yZXN0b3JlKGZsYWdzKTsKfQoKLyoKICogQ3Jvc3MgQ1BVIGNhbGwgdG8gcmVhZCB0aGUgaGFyZHdhcmUgZXZlbnQKICovCnN0YXRpYyB2b2lkIF9fcGVyZl9ldmVudF9yZWFkKHZvaWQgKmluZm8pCnsKCXN0cnVjdCBwZXJmX2NwdV9jb250ZXh0ICpjcHVjdHggPSAmX19nZXRfY3B1X3ZhcihwZXJmX2NwdV9jb250ZXh0KTsKCXN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCA9IGluZm87CglzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0ICpjdHggPSBldmVudC0+Y3R4OwoJdW5zaWduZWQgbG9uZyBmbGFnczsKCgkvKgoJICogSWYgdGhpcyBpcyBhIHRhc2sgY29udGV4dCwgd2UgbmVlZCB0byBjaGVjayB3aGV0aGVyIGl0IGlzCgkgKiB0aGUgY3VycmVudCB0YXNrIGNvbnRleHQgb2YgdGhpcyBjcHUuICBJZiBub3QgaXQgaGFzIGJlZW4KCSAqIHNjaGVkdWxlZCBvdXQgYmVmb3JlIHRoZSBzbXAgY2FsbCBhcnJpdmVkLiAgSW4gdGhhdCBjYXNlCgkgKiBldmVudC0+Y291bnQgd291bGQgaGF2ZSBiZWVuIHVwZGF0ZWQgdG8gYSByZWNlbnQgc2FtcGxlCgkgKiB3aGVuIHRoZSBldmVudCB3YXMgc2NoZWR1bGVkIG91dC4KCSAqLwoJaWYgKGN0eC0+dGFzayAmJiBjcHVjdHgtPnRhc2tfY3R4ICE9IGN0eCkKCQlyZXR1cm47CgoJbG9jYWxfaXJxX3NhdmUoZmxhZ3MpOwoJaWYgKGN0eC0+aXNfYWN0aXZlKQoJCXVwZGF0ZV9jb250ZXh0X3RpbWUoY3R4KTsKCWV2ZW50LT5wbXUtPnJlYWQoZXZlbnQpOwoJdXBkYXRlX2V2ZW50X3RpbWVzKGV2ZW50KTsKCWxvY2FsX2lycV9yZXN0b3JlKGZsYWdzKTsKfQoKc3RhdGljIHU2NCBwZXJmX2V2ZW50X3JlYWQoc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50KQp7CgkvKgoJICogSWYgZXZlbnQgaXMgZW5hYmxlZCBhbmQgY3VycmVudGx5IGFjdGl2ZSBvbiBhIENQVSwgdXBkYXRlIHRoZQoJICogdmFsdWUgaW4gdGhlIGV2ZW50IHN0cnVjdHVyZToKCSAqLwoJaWYgKGV2ZW50LT5zdGF0ZSA9PSBQRVJGX0VWRU5UX1NUQVRFX0FDVElWRSkgewoJCXNtcF9jYWxsX2Z1bmN0aW9uX3NpbmdsZShldmVudC0+b25jcHUsCgkJCQkJIF9fcGVyZl9ldmVudF9yZWFkLCBldmVudCwgMSk7Cgl9IGVsc2UgaWYgKGV2ZW50LT5zdGF0ZSA9PSBQRVJGX0VWRU5UX1NUQVRFX0lOQUNUSVZFKSB7CgkJdXBkYXRlX2V2ZW50X3RpbWVzKGV2ZW50KTsKCX0KCglyZXR1cm4gYXRvbWljNjRfcmVhZCgmZXZlbnQtPmNvdW50KTsKfQoKLyoKICogSW5pdGlhbGl6ZSB0aGUgcGVyZl9ldmVudCBjb250ZXh0IGluIGEgdGFza19zdHJ1Y3Q6CiAqLwpzdGF0aWMgdm9pZApfX3BlcmZfZXZlbnRfaW5pdF9jb250ZXh0KHN0cnVjdCBwZXJmX2V2ZW50X2NvbnRleHQgKmN0eCwKCQkJICAgIHN0cnVjdCB0YXNrX3N0cnVjdCAqdGFzaykKewoJbWVtc2V0KGN0eCwgMCwgc2l6ZW9mKCpjdHgpKTsKCXNwaW5fbG9ja19pbml0KCZjdHgtPmxvY2spOwoJbXV0ZXhfaW5pdCgmY3R4LT5tdXRleCk7CglJTklUX0xJU1RfSEVBRCgmY3R4LT5ncm91cF9saXN0KTsKCUlOSVRfTElTVF9IRUFEKCZjdHgtPmV2ZW50X2xpc3QpOwoJYXRvbWljX3NldCgmY3R4LT5yZWZjb3VudCwgMSk7CgljdHgtPnRhc2sgPSB0YXNrOwp9CgpzdGF0aWMgc3RydWN0IHBlcmZfZXZlbnRfY29udGV4dCAqZmluZF9nZXRfY29udGV4dChwaWRfdCBwaWQsIGludCBjcHUpCnsKCXN0cnVjdCBwZXJmX2V2ZW50X2NvbnRleHQgKmN0eDsKCXN0cnVjdCBwZXJmX2NwdV9jb250ZXh0ICpjcHVjdHg7CglzdHJ1Y3QgdGFza19zdHJ1Y3QgKnRhc2s7Cgl1bnNpZ25lZCBsb25nIGZsYWdzOwoJaW50IGVycjsKCgkvKgoJICogSWYgY3B1IGlzIG5vdCBhIHdpbGRjYXJkIHRoZW4gdGhpcyBpcyBhIHBlcmNwdSBldmVudDoKCSAqLwoJaWYgKGNwdSAhPSAtMSkgewoJCS8qIE11c3QgYmUgcm9vdCB0byBvcGVyYXRlIG9uIGEgQ1BVIGV2ZW50OiAqLwoJCWlmIChwZXJmX3BhcmFub2lkX2NwdSgpICYmICFjYXBhYmxlKENBUF9TWVNfQURNSU4pKQoJCQlyZXR1cm4gRVJSX1BUUigtRUFDQ0VTKTsKCgkJaWYgKGNwdSA8IDAgfHwgY3B1ID4gbnVtX3Bvc3NpYmxlX2NwdXMoKSkKCQkJcmV0dXJuIEVSUl9QVFIoLUVJTlZBTCk7CgoJCS8qCgkJICogV2UgY291bGQgYmUgY2xldmVyIGFuZCBhbGxvdyB0byBhdHRhY2ggYSBldmVudCB0byBhbgoJCSAqIG9mZmxpbmUgQ1BVIGFuZCBhY3RpdmF0ZSBpdCB3aGVuIHRoZSBDUFUgY29tZXMgdXAsIGJ1dAoJCSAqIHRoYXQncyBmb3IgbGF0ZXIuCgkJICovCgkJaWYgKCFjcHVfaXNzZXQoY3B1LCBjcHVfb25saW5lX21hcCkpCgkJCXJldHVybiBFUlJfUFRSKC1FTk9ERVYpOwoKCQljcHVjdHggPSAmcGVyX2NwdShwZXJmX2NwdV9jb250ZXh0LCBjcHUpOwoJCWN0eCA9ICZjcHVjdHgtPmN0eDsKCQlnZXRfY3R4KGN0eCk7CgoJCXJldHVybiBjdHg7Cgl9CgoJcmN1X3JlYWRfbG9jaygpOwoJaWYgKCFwaWQpCgkJdGFzayA9IGN1cnJlbnQ7CgllbHNlCgkJdGFzayA9IGZpbmRfdGFza19ieV92cGlkKHBpZCk7CglpZiAodGFzaykKCQlnZXRfdGFza19zdHJ1Y3QodGFzayk7CglyY3VfcmVhZF91bmxvY2soKTsKCglpZiAoIXRhc2spCgkJcmV0dXJuIEVSUl9QVFIoLUVTUkNIKTsKCgkvKgoJICogQ2FuJ3QgYXR0YWNoIGV2ZW50cyB0byBhIGR5aW5nIHRhc2suCgkgKi8KCWVyciA9IC1FU1JDSDsKCWlmICh0YXNrLT5mbGFncyAmIFBGX0VYSVRJTkcpCgkJZ290byBlcnJvdXQ7CgoJLyogUmV1c2UgcHRyYWNlIHBlcm1pc3Npb24gY2hlY2tzIGZvciBub3cuICovCgllcnIgPSAtRUFDQ0VTOwoJaWYgKCFwdHJhY2VfbWF5X2FjY2Vzcyh0YXNrLCBQVFJBQ0VfTU9ERV9SRUFEKSkKCQlnb3RvIGVycm91dDsKCiByZXRyeToKCWN0eCA9IHBlcmZfbG9ja190YXNrX2NvbnRleHQodGFzaywgJmZsYWdzKTsKCWlmIChjdHgpIHsKCQl1bmNsb25lX2N0eChjdHgpOwoJCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJmN0eC0+bG9jaywgZmxhZ3MpOwoJfQoKCWlmICghY3R4KSB7CgkJY3R4ID0ga21hbGxvYyhzaXplb2Yoc3RydWN0IHBlcmZfZXZlbnRfY29udGV4dCksIEdGUF9LRVJORUwpOwoJCWVyciA9IC1FTk9NRU07CgkJaWYgKCFjdHgpCgkJCWdvdG8gZXJyb3V0OwoJCV9fcGVyZl9ldmVudF9pbml0X2NvbnRleHQoY3R4LCB0YXNrKTsKCQlnZXRfY3R4KGN0eCk7CgkJaWYgKGNtcHhjaGcoJnRhc2stPnBlcmZfZXZlbnRfY3R4cCwgTlVMTCwgY3R4KSkgewoJCQkvKgoJCQkgKiBXZSByYWNlZCB3aXRoIHNvbWUgb3RoZXIgdGFzazsgdXNlCgkJCSAqIHRoZSBjb250ZXh0IHRoZXkgc2V0LgoJCQkgKi8KCQkJa2ZyZWUoY3R4KTsKCQkJZ290byByZXRyeTsKCQl9CgkJZ2V0X3Rhc2tfc3RydWN0KHRhc2spOwoJfQoKCXB1dF90YXNrX3N0cnVjdCh0YXNrKTsKCXJldHVybiBjdHg7CgogZXJyb3V0OgoJcHV0X3Rhc2tfc3RydWN0KHRhc2spOwoJcmV0dXJuIEVSUl9QVFIoZXJyKTsKfQoKc3RhdGljIHZvaWQgZnJlZV9ldmVudF9yY3Uoc3RydWN0IHJjdV9oZWFkICpoZWFkKQp7CglzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQ7CgoJZXZlbnQgPSBjb250YWluZXJfb2YoaGVhZCwgc3RydWN0IHBlcmZfZXZlbnQsIHJjdV9oZWFkKTsKCWlmIChldmVudC0+bnMpCgkJcHV0X3BpZF9ucyhldmVudC0+bnMpOwoJa2ZyZWUoZXZlbnQpOwp9CgpzdGF0aWMgdm9pZCBwZXJmX3BlbmRpbmdfc3luYyhzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQpOwoKc3RhdGljIHZvaWQgZnJlZV9ldmVudChzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQpCnsKCXBlcmZfcGVuZGluZ19zeW5jKGV2ZW50KTsKCglpZiAoIWV2ZW50LT5wYXJlbnQpIHsKCQlhdG9taWNfZGVjKCZucl9ldmVudHMpOwoJCWlmIChldmVudC0+YXR0ci5tbWFwKQoJCQlhdG9taWNfZGVjKCZucl9tbWFwX2V2ZW50cyk7CgkJaWYgKGV2ZW50LT5hdHRyLmNvbW0pCgkJCWF0b21pY19kZWMoJm5yX2NvbW1fZXZlbnRzKTsKCQlpZiAoZXZlbnQtPmF0dHIudGFzaykKCQkJYXRvbWljX2RlYygmbnJfdGFza19ldmVudHMpOwoJfQoKCWlmIChldmVudC0+b3V0cHV0KSB7CgkJZnB1dChldmVudC0+b3V0cHV0LT5maWxwKTsKCQlldmVudC0+b3V0cHV0ID0gTlVMTDsKCX0KCglpZiAoZXZlbnQtPmRlc3Ryb3kpCgkJZXZlbnQtPmRlc3Ryb3koZXZlbnQpOwoKCXB1dF9jdHgoZXZlbnQtPmN0eCk7CgljYWxsX3JjdSgmZXZlbnQtPnJjdV9oZWFkLCBmcmVlX2V2ZW50X3JjdSk7Cn0KCi8qCiAqIENhbGxlZCB3aGVuIHRoZSBsYXN0IHJlZmVyZW5jZSB0byB0aGUgZmlsZSBpcyBnb25lLgogKi8Kc3RhdGljIGludCBwZXJmX3JlbGVhc2Uoc3RydWN0IGlub2RlICppbm9kZSwgc3RydWN0IGZpbGUgKmZpbGUpCnsKCXN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCA9IGZpbGUtPnByaXZhdGVfZGF0YTsKCXN0cnVjdCBwZXJmX2V2ZW50X2NvbnRleHQgKmN0eCA9IGV2ZW50LT5jdHg7CgoJZmlsZS0+cHJpdmF0ZV9kYXRhID0gTlVMTDsKCglXQVJOX09OX09OQ0UoY3R4LT5wYXJlbnRfY3R4KTsKCW11dGV4X2xvY2soJmN0eC0+bXV0ZXgpOwoJcGVyZl9ldmVudF9yZW1vdmVfZnJvbV9jb250ZXh0KGV2ZW50KTsKCW11dGV4X3VubG9jaygmY3R4LT5tdXRleCk7CgoJbXV0ZXhfbG9jaygmZXZlbnQtPm93bmVyLT5wZXJmX2V2ZW50X211dGV4KTsKCWxpc3RfZGVsX2luaXQoJmV2ZW50LT5vd25lcl9lbnRyeSk7CgltdXRleF91bmxvY2soJmV2ZW50LT5vd25lci0+cGVyZl9ldmVudF9tdXRleCk7CglwdXRfdGFza19zdHJ1Y3QoZXZlbnQtPm93bmVyKTsKCglmcmVlX2V2ZW50KGV2ZW50KTsKCglyZXR1cm4gMDsKfQoKc3RhdGljIGludCBwZXJmX2V2ZW50X3JlYWRfc2l6ZShzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQpCnsKCWludCBlbnRyeSA9IHNpemVvZih1NjQpOyAvKiB2YWx1ZSAqLwoJaW50IHNpemUgPSAwOwoJaW50IG5yID0gMTsKCglpZiAoZXZlbnQtPmF0dHIucmVhZF9mb3JtYXQgJiBQRVJGX0ZPUk1BVF9UT1RBTF9USU1FX0VOQUJMRUQpCgkJc2l6ZSArPSBzaXplb2YodTY0KTsKCglpZiAoZXZlbnQtPmF0dHIucmVhZF9mb3JtYXQgJiBQRVJGX0ZPUk1BVF9UT1RBTF9USU1FX1JVTk5JTkcpCgkJc2l6ZSArPSBzaXplb2YodTY0KTsKCglpZiAoZXZlbnQtPmF0dHIucmVhZF9mb3JtYXQgJiBQRVJGX0ZPUk1BVF9JRCkKCQllbnRyeSArPSBzaXplb2YodTY0KTsKCglpZiAoZXZlbnQtPmF0dHIucmVhZF9mb3JtYXQgJiBQRVJGX0ZPUk1BVF9HUk9VUCkgewoJCW5yICs9IGV2ZW50LT5ncm91cF9sZWFkZXItPm5yX3NpYmxpbmdzOwoJCXNpemUgKz0gc2l6ZW9mKHU2NCk7Cgl9CgoJc2l6ZSArPSBlbnRyeSAqIG5yOwoKCXJldHVybiBzaXplOwp9CgpzdGF0aWMgdTY0IHBlcmZfZXZlbnRfcmVhZF92YWx1ZShzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQpCnsKCXN0cnVjdCBwZXJmX2V2ZW50ICpjaGlsZDsKCXU2NCB0b3RhbCA9IDA7CgoJdG90YWwgKz0gcGVyZl9ldmVudF9yZWFkKGV2ZW50KTsKCWxpc3RfZm9yX2VhY2hfZW50cnkoY2hpbGQsICZldmVudC0+Y2hpbGRfbGlzdCwgY2hpbGRfbGlzdCkKCQl0b3RhbCArPSBwZXJmX2V2ZW50X3JlYWQoY2hpbGQpOwoKCXJldHVybiB0b3RhbDsKfQoKc3RhdGljIGludCBwZXJmX2V2ZW50X3JlYWRfZW50cnkoc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50LAoJCQkJICAgdTY0IHJlYWRfZm9ybWF0LCBjaGFyIF9fdXNlciAqYnVmKQp7CglpbnQgbiA9IDAsIGNvdW50ID0gMDsKCXU2NCB2YWx1ZXNbMl07CgoJdmFsdWVzW24rK10gPSBwZXJmX2V2ZW50X3JlYWRfdmFsdWUoZXZlbnQpOwoJaWYgKHJlYWRfZm9ybWF0ICYgUEVSRl9GT1JNQVRfSUQpCgkJdmFsdWVzW24rK10gPSBwcmltYXJ5X2V2ZW50X2lkKGV2ZW50KTsKCgljb3VudCA9IG4gKiBzaXplb2YodTY0KTsKCglpZiAoY29weV90b191c2VyKGJ1ZiwgdmFsdWVzLCBjb3VudCkpCgkJcmV0dXJuIC1FRkFVTFQ7CgoJcmV0dXJuIGNvdW50Owp9CgpzdGF0aWMgaW50IHBlcmZfZXZlbnRfcmVhZF9ncm91cChzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQsCgkJCQkgICB1NjQgcmVhZF9mb3JtYXQsIGNoYXIgX191c2VyICpidWYpCnsKCXN0cnVjdCBwZXJmX2V2ZW50ICpsZWFkZXIgPSBldmVudC0+Z3JvdXBfbGVhZGVyLCAqc3ViOwoJaW50IG4gPSAwLCBzaXplID0gMCwgZXJyID0gLUVGQVVMVDsKCXU2NCB2YWx1ZXNbM107CgoJdmFsdWVzW24rK10gPSAxICsgbGVhZGVyLT5ucl9zaWJsaW5nczsKCWlmIChyZWFkX2Zvcm1hdCAmIFBFUkZfRk9STUFUX1RPVEFMX1RJTUVfRU5BQkxFRCkgewoJCXZhbHVlc1tuKytdID0gbGVhZGVyLT50b3RhbF90aW1lX2VuYWJsZWQgKwoJCQlhdG9taWM2NF9yZWFkKCZsZWFkZXItPmNoaWxkX3RvdGFsX3RpbWVfZW5hYmxlZCk7Cgl9CglpZiAocmVhZF9mb3JtYXQgJiBQRVJGX0ZPUk1BVF9UT1RBTF9USU1FX1JVTk5JTkcpIHsKCQl2YWx1ZXNbbisrXSA9IGxlYWRlci0+dG90YWxfdGltZV9ydW5uaW5nICsKCQkJYXRvbWljNjRfcmVhZCgmbGVhZGVyLT5jaGlsZF90b3RhbF90aW1lX3J1bm5pbmcpOwoJfQoKCXNpemUgPSBuICogc2l6ZW9mKHU2NCk7CgoJaWYgKGNvcHlfdG9fdXNlcihidWYsIHZhbHVlcywgc2l6ZSkpCgkJcmV0dXJuIC1FRkFVTFQ7CgoJZXJyID0gcGVyZl9ldmVudF9yZWFkX2VudHJ5KGxlYWRlciwgcmVhZF9mb3JtYXQsIGJ1ZiArIHNpemUpOwoJaWYgKGVyciA8IDApCgkJcmV0dXJuIGVycjsKCglzaXplICs9IGVycjsKCglsaXN0X2Zvcl9lYWNoX2VudHJ5KHN1YiwgJmxlYWRlci0+c2libGluZ19saXN0LCBncm91cF9lbnRyeSkgewoJCWVyciA9IHBlcmZfZXZlbnRfcmVhZF9lbnRyeShzdWIsIHJlYWRfZm9ybWF0LAoJCQkJYnVmICsgc2l6ZSk7CgkJaWYgKGVyciA8IDApCgkJCXJldHVybiBlcnI7CgoJCXNpemUgKz0gZXJyOwoJfQoKCXJldHVybiBzaXplOwp9CgpzdGF0aWMgaW50IHBlcmZfZXZlbnRfcmVhZF9vbmUoc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50LAoJCQkJIHU2NCByZWFkX2Zvcm1hdCwgY2hhciBfX3VzZXIgKmJ1ZikKewoJdTY0IHZhbHVlc1s0XTsKCWludCBuID0gMDsKCgl2YWx1ZXNbbisrXSA9IHBlcmZfZXZlbnRfcmVhZF92YWx1ZShldmVudCk7CglpZiAocmVhZF9mb3JtYXQgJiBQRVJGX0ZPUk1BVF9UT1RBTF9USU1FX0VOQUJMRUQpIHsKCQl2YWx1ZXNbbisrXSA9IGV2ZW50LT50b3RhbF90aW1lX2VuYWJsZWQgKwoJCQlhdG9taWM2NF9yZWFkKCZldmVudC0+Y2hpbGRfdG90YWxfdGltZV9lbmFibGVkKTsKCX0KCWlmIChyZWFkX2Zvcm1hdCAmIFBFUkZfRk9STUFUX1RPVEFMX1RJTUVfUlVOTklORykgewoJCXZhbHVlc1tuKytdID0gZXZlbnQtPnRvdGFsX3RpbWVfcnVubmluZyArCgkJCWF0b21pYzY0X3JlYWQoJmV2ZW50LT5jaGlsZF90b3RhbF90aW1lX3J1bm5pbmcpOwoJfQoJaWYgKHJlYWRfZm9ybWF0ICYgUEVSRl9GT1JNQVRfSUQpCgkJdmFsdWVzW24rK10gPSBwcmltYXJ5X2V2ZW50X2lkKGV2ZW50KTsKCglpZiAoY29weV90b191c2VyKGJ1ZiwgdmFsdWVzLCBuICogc2l6ZW9mKHU2NCkpKQoJCXJldHVybiAtRUZBVUxUOwoKCXJldHVybiBuICogc2l6ZW9mKHU2NCk7Cn0KCi8qCiAqIFJlYWQgdGhlIHBlcmZvcm1hbmNlIGV2ZW50IC0gc2ltcGxlIG5vbiBibG9ja2luZyB2ZXJzaW9uIGZvciBub3cKICovCnN0YXRpYyBzc2l6ZV90CnBlcmZfcmVhZF9odyhzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQsIGNoYXIgX191c2VyICpidWYsIHNpemVfdCBjb3VudCkKewoJdTY0IHJlYWRfZm9ybWF0ID0gZXZlbnQtPmF0dHIucmVhZF9mb3JtYXQ7CglpbnQgcmV0OwoKCS8qCgkgKiBSZXR1cm4gZW5kLW9mLWZpbGUgZm9yIGEgcmVhZCBvbiBhIGV2ZW50IHRoYXQgaXMgaW4KCSAqIGVycm9yIHN0YXRlIChpLmUuIGJlY2F1c2UgaXQgd2FzIHBpbm5lZCBidXQgaXQgY291bGRuJ3QgYmUKCSAqIHNjaGVkdWxlZCBvbiB0byB0aGUgQ1BVIGF0IHNvbWUgcG9pbnQpLgoJICovCglpZiAoZXZlbnQtPnN0YXRlID09IFBFUkZfRVZFTlRfU1RBVEVfRVJST1IpCgkJcmV0dXJuIDA7CgoJaWYgKGNvdW50IDwgcGVyZl9ldmVudF9yZWFkX3NpemUoZXZlbnQpKQoJCXJldHVybiAtRU5PU1BDOwoKCVdBUk5fT05fT05DRShldmVudC0+Y3R4LT5wYXJlbnRfY3R4KTsKCW11dGV4X2xvY2soJmV2ZW50LT5jaGlsZF9tdXRleCk7CglpZiAocmVhZF9mb3JtYXQgJiBQRVJGX0ZPUk1BVF9HUk9VUCkKCQlyZXQgPSBwZXJmX2V2ZW50X3JlYWRfZ3JvdXAoZXZlbnQsIHJlYWRfZm9ybWF0LCBidWYpOwoJZWxzZQoJCXJldCA9IHBlcmZfZXZlbnRfcmVhZF9vbmUoZXZlbnQsIHJlYWRfZm9ybWF0LCBidWYpOwoJbXV0ZXhfdW5sb2NrKCZldmVudC0+Y2hpbGRfbXV0ZXgpOwoKCXJldHVybiByZXQ7Cn0KCnN0YXRpYyBzc2l6ZV90CnBlcmZfcmVhZChzdHJ1Y3QgZmlsZSAqZmlsZSwgY2hhciBfX3VzZXIgKmJ1Ziwgc2l6ZV90IGNvdW50LCBsb2ZmX3QgKnBwb3MpCnsKCXN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCA9IGZpbGUtPnByaXZhdGVfZGF0YTsKCglyZXR1cm4gcGVyZl9yZWFkX2h3KGV2ZW50LCBidWYsIGNvdW50KTsKfQoKc3RhdGljIHVuc2lnbmVkIGludCBwZXJmX3BvbGwoc3RydWN0IGZpbGUgKmZpbGUsIHBvbGxfdGFibGUgKndhaXQpCnsKCXN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCA9IGZpbGUtPnByaXZhdGVfZGF0YTsKCXN0cnVjdCBwZXJmX21tYXBfZGF0YSAqZGF0YTsKCXVuc2lnbmVkIGludCBldmVudHMgPSBQT0xMX0hVUDsKCglyY3VfcmVhZF9sb2NrKCk7CglkYXRhID0gcmN1X2RlcmVmZXJlbmNlKGV2ZW50LT5kYXRhKTsKCWlmIChkYXRhKQoJCWV2ZW50cyA9IGF0b21pY194Y2hnKCZkYXRhLT5wb2xsLCAwKTsKCXJjdV9yZWFkX3VubG9jaygpOwoKCXBvbGxfd2FpdChmaWxlLCAmZXZlbnQtPndhaXRxLCB3YWl0KTsKCglyZXR1cm4gZXZlbnRzOwp9CgpzdGF0aWMgdm9pZCBwZXJmX2V2ZW50X3Jlc2V0KHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCkKewoJKHZvaWQpcGVyZl9ldmVudF9yZWFkKGV2ZW50KTsKCWF0b21pYzY0X3NldCgmZXZlbnQtPmNvdW50LCAwKTsKCXBlcmZfZXZlbnRfdXBkYXRlX3VzZXJwYWdlKGV2ZW50KTsKfQoKLyoKICogSG9sZGluZyB0aGUgdG9wLWxldmVsIGV2ZW50J3MgY2hpbGRfbXV0ZXggbWVhbnMgdGhhdCBhbnkKICogZGVzY2VuZGFudCBwcm9jZXNzIHRoYXQgaGFzIGluaGVyaXRlZCB0aGlzIGV2ZW50IHdpbGwgYmxvY2sKICogaW4gc3luY19jaGlsZF9ldmVudCBpZiBpdCBnb2VzIHRvIGV4aXQsIHRodXMgc2F0aXNmeWluZyB0aGUKICogdGFzayBleGlzdGVuY2UgcmVxdWlyZW1lbnRzIG9mIHBlcmZfZXZlbnRfZW5hYmxlL2Rpc2FibGUuCiAqLwpzdGF0aWMgdm9pZCBwZXJmX2V2ZW50X2Zvcl9lYWNoX2NoaWxkKHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCwKCQkJCQl2b2lkICgqZnVuYykoc3RydWN0IHBlcmZfZXZlbnQgKikpCnsKCXN0cnVjdCBwZXJmX2V2ZW50ICpjaGlsZDsKCglXQVJOX09OX09OQ0UoZXZlbnQtPmN0eC0+cGFyZW50X2N0eCk7CgltdXRleF9sb2NrKCZldmVudC0+Y2hpbGRfbXV0ZXgpOwoJZnVuYyhldmVudCk7CglsaXN0X2Zvcl9lYWNoX2VudHJ5KGNoaWxkLCAmZXZlbnQtPmNoaWxkX2xpc3QsIGNoaWxkX2xpc3QpCgkJZnVuYyhjaGlsZCk7CgltdXRleF91bmxvY2soJmV2ZW50LT5jaGlsZF9tdXRleCk7Cn0KCnN0YXRpYyB2b2lkIHBlcmZfZXZlbnRfZm9yX2VhY2goc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50LAoJCQkJICB2b2lkICgqZnVuYykoc3RydWN0IHBlcmZfZXZlbnQgKikpCnsKCXN0cnVjdCBwZXJmX2V2ZW50X2NvbnRleHQgKmN0eCA9IGV2ZW50LT5jdHg7CglzdHJ1Y3QgcGVyZl9ldmVudCAqc2libGluZzsKCglXQVJOX09OX09OQ0UoY3R4LT5wYXJlbnRfY3R4KTsKCW11dGV4X2xvY2soJmN0eC0+bXV0ZXgpOwoJZXZlbnQgPSBldmVudC0+Z3JvdXBfbGVhZGVyOwoKCXBlcmZfZXZlbnRfZm9yX2VhY2hfY2hpbGQoZXZlbnQsIGZ1bmMpOwoJZnVuYyhldmVudCk7CglsaXN0X2Zvcl9lYWNoX2VudHJ5KHNpYmxpbmcsICZldmVudC0+c2libGluZ19saXN0LCBncm91cF9lbnRyeSkKCQlwZXJmX2V2ZW50X2Zvcl9lYWNoX2NoaWxkKGV2ZW50LCBmdW5jKTsKCW11dGV4X3VubG9jaygmY3R4LT5tdXRleCk7Cn0KCnN0YXRpYyBpbnQgcGVyZl9ldmVudF9wZXJpb2Qoc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50LCB1NjQgX191c2VyICphcmcpCnsKCXN0cnVjdCBwZXJmX2V2ZW50X2NvbnRleHQgKmN0eCA9IGV2ZW50LT5jdHg7Cgl1bnNpZ25lZCBsb25nIHNpemU7CglpbnQgcmV0ID0gMDsKCXU2NCB2YWx1ZTsKCglpZiAoIWV2ZW50LT5hdHRyLnNhbXBsZV9wZXJpb2QpCgkJcmV0dXJuIC1FSU5WQUw7CgoJc2l6ZSA9IGNvcHlfZnJvbV91c2VyKCZ2YWx1ZSwgYXJnLCBzaXplb2YodmFsdWUpKTsKCWlmIChzaXplICE9IHNpemVvZih2YWx1ZSkpCgkJcmV0dXJuIC1FRkFVTFQ7CgoJaWYgKCF2YWx1ZSkKCQlyZXR1cm4gLUVJTlZBTDsKCglzcGluX2xvY2tfaXJxKCZjdHgtPmxvY2spOwoJaWYgKGV2ZW50LT5hdHRyLmZyZXEpIHsKCQlpZiAodmFsdWUgPiBzeXNjdGxfcGVyZl9ldmVudF9zYW1wbGVfcmF0ZSkgewoJCQlyZXQgPSAtRUlOVkFMOwoJCQlnb3RvIHVubG9jazsKCQl9CgoJCWV2ZW50LT5hdHRyLnNhbXBsZV9mcmVxID0gdmFsdWU7Cgl9IGVsc2UgewoJCWV2ZW50LT5hdHRyLnNhbXBsZV9wZXJpb2QgPSB2YWx1ZTsKCQlldmVudC0+aHcuc2FtcGxlX3BlcmlvZCA9IHZhbHVlOwoJfQp1bmxvY2s6CglzcGluX3VubG9ja19pcnEoJmN0eC0+bG9jayk7CgoJcmV0dXJuIHJldDsKfQoKaW50IHBlcmZfZXZlbnRfc2V0X291dHB1dChzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQsIGludCBvdXRwdXRfZmQpOwoKc3RhdGljIGxvbmcgcGVyZl9pb2N0bChzdHJ1Y3QgZmlsZSAqZmlsZSwgdW5zaWduZWQgaW50IGNtZCwgdW5zaWduZWQgbG9uZyBhcmcpCnsKCXN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCA9IGZpbGUtPnByaXZhdGVfZGF0YTsKCXZvaWQgKCpmdW5jKShzdHJ1Y3QgcGVyZl9ldmVudCAqKTsKCXUzMiBmbGFncyA9IGFyZzsKCglzd2l0Y2ggKGNtZCkgewoJY2FzZSBQRVJGX0VWRU5UX0lPQ19FTkFCTEU6CgkJZnVuYyA9IHBlcmZfZXZlbnRfZW5hYmxlOwoJCWJyZWFrOwoJY2FzZSBQRVJGX0VWRU5UX0lPQ19ESVNBQkxFOgoJCWZ1bmMgPSBwZXJmX2V2ZW50X2Rpc2FibGU7CgkJYnJlYWs7CgljYXNlIFBFUkZfRVZFTlRfSU9DX1JFU0VUOgoJCWZ1bmMgPSBwZXJmX2V2ZW50X3Jlc2V0OwoJCWJyZWFrOwoKCWNhc2UgUEVSRl9FVkVOVF9JT0NfUkVGUkVTSDoKCQlyZXR1cm4gcGVyZl9ldmVudF9yZWZyZXNoKGV2ZW50LCBhcmcpOwoKCWNhc2UgUEVSRl9FVkVOVF9JT0NfUEVSSU9EOgoJCXJldHVybiBwZXJmX2V2ZW50X3BlcmlvZChldmVudCwgKHU2NCBfX3VzZXIgKilhcmcpOwoKCWNhc2UgUEVSRl9FVkVOVF9JT0NfU0VUX09VVFBVVDoKCQlyZXR1cm4gcGVyZl9ldmVudF9zZXRfb3V0cHV0KGV2ZW50LCBhcmcpOwoKCWRlZmF1bHQ6CgkJcmV0dXJuIC1FTk9UVFk7Cgl9CgoJaWYgKGZsYWdzICYgUEVSRl9JT0NfRkxBR19HUk9VUCkKCQlwZXJmX2V2ZW50X2Zvcl9lYWNoKGV2ZW50LCBmdW5jKTsKCWVsc2UKCQlwZXJmX2V2ZW50X2Zvcl9lYWNoX2NoaWxkKGV2ZW50LCBmdW5jKTsKCglyZXR1cm4gMDsKfQoKaW50IHBlcmZfZXZlbnRfdGFza19lbmFibGUodm9pZCkKewoJc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50OwoKCW11dGV4X2xvY2soJmN1cnJlbnQtPnBlcmZfZXZlbnRfbXV0ZXgpOwoJbGlzdF9mb3JfZWFjaF9lbnRyeShldmVudCwgJmN1cnJlbnQtPnBlcmZfZXZlbnRfbGlzdCwgb3duZXJfZW50cnkpCgkJcGVyZl9ldmVudF9mb3JfZWFjaF9jaGlsZChldmVudCwgcGVyZl9ldmVudF9lbmFibGUpOwoJbXV0ZXhfdW5sb2NrKCZjdXJyZW50LT5wZXJmX2V2ZW50X211dGV4KTsKCglyZXR1cm4gMDsKfQoKaW50IHBlcmZfZXZlbnRfdGFza19kaXNhYmxlKHZvaWQpCnsKCXN0cnVjdCBwZXJmX2V2ZW50ICpldmVudDsKCgltdXRleF9sb2NrKCZjdXJyZW50LT5wZXJmX2V2ZW50X211dGV4KTsKCWxpc3RfZm9yX2VhY2hfZW50cnkoZXZlbnQsICZjdXJyZW50LT5wZXJmX2V2ZW50X2xpc3QsIG93bmVyX2VudHJ5KQoJCXBlcmZfZXZlbnRfZm9yX2VhY2hfY2hpbGQoZXZlbnQsIHBlcmZfZXZlbnRfZGlzYWJsZSk7CgltdXRleF91bmxvY2soJmN1cnJlbnQtPnBlcmZfZXZlbnRfbXV0ZXgpOwoKCXJldHVybiAwOwp9CgojaWZuZGVmIFBFUkZfRVZFTlRfSU5ERVhfT0ZGU0VUCiMgZGVmaW5lIFBFUkZfRVZFTlRfSU5ERVhfT0ZGU0VUIDAKI2VuZGlmCgpzdGF0aWMgaW50IHBlcmZfZXZlbnRfaW5kZXgoc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50KQp7CglpZiAoZXZlbnQtPnN0YXRlICE9IFBFUkZfRVZFTlRfU1RBVEVfQUNUSVZFKQoJCXJldHVybiAwOwoKCXJldHVybiBldmVudC0+aHcuaWR4ICsgMSAtIFBFUkZfRVZFTlRfSU5ERVhfT0ZGU0VUOwp9CgovKgogKiBDYWxsZXJzIG5lZWQgdG8gZW5zdXJlIHRoZXJlIGNhbiBiZSBubyBuZXN0aW5nIG9mIHRoaXMgZnVuY3Rpb24sIG90aGVyd2lzZQogKiB0aGUgc2VxbG9jayBsb2dpYyBnb2VzIGJhZC4gV2UgY2FuIG5vdCBzZXJpYWxpemUgdGhpcyBiZWNhdXNlIHRoZSBhcmNoCiAqIGNvZGUgY2FsbHMgdGhpcyBmcm9tIE5NSSBjb250ZXh0LgogKi8Kdm9pZCBwZXJmX2V2ZW50X3VwZGF0ZV91c2VycGFnZShzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQpCnsKCXN0cnVjdCBwZXJmX2V2ZW50X21tYXBfcGFnZSAqdXNlcnBnOwoJc3RydWN0IHBlcmZfbW1hcF9kYXRhICpkYXRhOwoKCXJjdV9yZWFkX2xvY2soKTsKCWRhdGEgPSByY3VfZGVyZWZlcmVuY2UoZXZlbnQtPmRhdGEpOwoJaWYgKCFkYXRhKQoJCWdvdG8gdW5sb2NrOwoKCXVzZXJwZyA9IGRhdGEtPnVzZXJfcGFnZTsKCgkvKgoJICogRGlzYWJsZSBwcmVlbXB0aW9uIHNvIGFzIHRvIG5vdCBsZXQgdGhlIGNvcnJlc3BvbmRpbmcgdXNlci1zcGFjZQoJICogc3BpbiB0b28gbG9uZyBpZiB3ZSBnZXQgcHJlZW1wdGVkLgoJICovCglwcmVlbXB0X2Rpc2FibGUoKTsKCSsrdXNlcnBnLT5sb2NrOwoJYmFycmllcigpOwoJdXNlcnBnLT5pbmRleCA9IHBlcmZfZXZlbnRfaW5kZXgoZXZlbnQpOwoJdXNlcnBnLT5vZmZzZXQgPSBhdG9taWM2NF9yZWFkKCZldmVudC0+Y291bnQpOwoJaWYgKGV2ZW50LT5zdGF0ZSA9PSBQRVJGX0VWRU5UX1NUQVRFX0FDVElWRSkKCQl1c2VycGctPm9mZnNldCAtPSBhdG9taWM2NF9yZWFkKCZldmVudC0+aHcucHJldl9jb3VudCk7CgoJdXNlcnBnLT50aW1lX2VuYWJsZWQgPSBldmVudC0+dG90YWxfdGltZV9lbmFibGVkICsKCQkJYXRvbWljNjRfcmVhZCgmZXZlbnQtPmNoaWxkX3RvdGFsX3RpbWVfZW5hYmxlZCk7CgoJdXNlcnBnLT50aW1lX3J1bm5pbmcgPSBldmVudC0+dG90YWxfdGltZV9ydW5uaW5nICsKCQkJYXRvbWljNjRfcmVhZCgmZXZlbnQtPmNoaWxkX3RvdGFsX3RpbWVfcnVubmluZyk7CgoJYmFycmllcigpOwoJKyt1c2VycGctPmxvY2s7CglwcmVlbXB0X2VuYWJsZSgpOwp1bmxvY2s6CglyY3VfcmVhZF91bmxvY2soKTsKfQoKc3RhdGljIHVuc2lnbmVkIGxvbmcgcGVyZl9kYXRhX3NpemUoc3RydWN0IHBlcmZfbW1hcF9kYXRhICpkYXRhKQp7CglyZXR1cm4gZGF0YS0+bnJfcGFnZXMgPDwgKFBBR0VfU0hJRlQgKyBkYXRhLT5kYXRhX29yZGVyKTsKfQoKI2lmbmRlZiBDT05GSUdfUEVSRl9VU0VfVk1BTExPQwoKLyoKICogQmFjayBwZXJmX21tYXAoKSB3aXRoIHJlZ3VsYXIgR0ZQX0tFUk5FTC0wIHBhZ2VzLgogKi8KCnN0YXRpYyBzdHJ1Y3QgcGFnZSAqCnBlcmZfbW1hcF90b19wYWdlKHN0cnVjdCBwZXJmX21tYXBfZGF0YSAqZGF0YSwgdW5zaWduZWQgbG9uZyBwZ29mZikKewoJaWYgKHBnb2ZmID4gZGF0YS0+bnJfcGFnZXMpCgkJcmV0dXJuIE5VTEw7CgoJaWYgKHBnb2ZmID09IDApCgkJcmV0dXJuIHZpcnRfdG9fcGFnZShkYXRhLT51c2VyX3BhZ2UpOwoKCXJldHVybiB2aXJ0X3RvX3BhZ2UoZGF0YS0+ZGF0YV9wYWdlc1twZ29mZiAtIDFdKTsKfQoKc3RhdGljIHN0cnVjdCBwZXJmX21tYXBfZGF0YSAqCnBlcmZfbW1hcF9kYXRhX2FsbG9jKHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCwgaW50IG5yX3BhZ2VzKQp7CglzdHJ1Y3QgcGVyZl9tbWFwX2RhdGEgKmRhdGE7Cgl1bnNpZ25lZCBsb25nIHNpemU7CglpbnQgaTsKCglXQVJOX09OKGF0b21pY19yZWFkKCZldmVudC0+bW1hcF9jb3VudCkpOwoKCXNpemUgPSBzaXplb2Yoc3RydWN0IHBlcmZfbW1hcF9kYXRhKTsKCXNpemUgKz0gbnJfcGFnZXMgKiBzaXplb2Yodm9pZCAqKTsKCglkYXRhID0ga3phbGxvYyhzaXplLCBHRlBfS0VSTkVMKTsKCWlmICghZGF0YSkKCQlnb3RvIGZhaWw7CgoJZGF0YS0+dXNlcl9wYWdlID0gKHZvaWQgKilnZXRfemVyb2VkX3BhZ2UoR0ZQX0tFUk5FTCk7CglpZiAoIWRhdGEtPnVzZXJfcGFnZSkKCQlnb3RvIGZhaWxfdXNlcl9wYWdlOwoKCWZvciAoaSA9IDA7IGkgPCBucl9wYWdlczsgaSsrKSB7CgkJZGF0YS0+ZGF0YV9wYWdlc1tpXSA9ICh2b2lkICopZ2V0X3plcm9lZF9wYWdlKEdGUF9LRVJORUwpOwoJCWlmICghZGF0YS0+ZGF0YV9wYWdlc1tpXSkKCQkJZ290byBmYWlsX2RhdGFfcGFnZXM7Cgl9CgoJZGF0YS0+ZGF0YV9vcmRlciA9IDA7CglkYXRhLT5ucl9wYWdlcyA9IG5yX3BhZ2VzOwoKCXJldHVybiBkYXRhOwoKZmFpbF9kYXRhX3BhZ2VzOgoJZm9yIChpLS07IGkgPj0gMDsgaS0tKQoJCWZyZWVfcGFnZSgodW5zaWduZWQgbG9uZylkYXRhLT5kYXRhX3BhZ2VzW2ldKTsKCglmcmVlX3BhZ2UoKHVuc2lnbmVkIGxvbmcpZGF0YS0+dXNlcl9wYWdlKTsKCmZhaWxfdXNlcl9wYWdlOgoJa2ZyZWUoZGF0YSk7CgpmYWlsOgoJcmV0dXJuIE5VTEw7Cn0KCnN0YXRpYyB2b2lkIHBlcmZfbW1hcF9mcmVlX3BhZ2UodW5zaWduZWQgbG9uZyBhZGRyKQp7CglzdHJ1Y3QgcGFnZSAqcGFnZSA9IHZpcnRfdG9fcGFnZSgodm9pZCAqKWFkZHIpOwoKCXBhZ2UtPm1hcHBpbmcgPSBOVUxMOwoJX19mcmVlX3BhZ2UocGFnZSk7Cn0KCnN0YXRpYyB2b2lkIHBlcmZfbW1hcF9kYXRhX2ZyZWUoc3RydWN0IHBlcmZfbW1hcF9kYXRhICpkYXRhKQp7CglpbnQgaTsKCglwZXJmX21tYXBfZnJlZV9wYWdlKCh1bnNpZ25lZCBsb25nKWRhdGEtPnVzZXJfcGFnZSk7Cglmb3IgKGkgPSAwOyBpIDwgZGF0YS0+bnJfcGFnZXM7IGkrKykKCQlwZXJmX21tYXBfZnJlZV9wYWdlKCh1bnNpZ25lZCBsb25nKWRhdGEtPmRhdGFfcGFnZXNbaV0pOwp9CgojZWxzZQoKLyoKICogQmFjayBwZXJmX21tYXAoKSB3aXRoIHZtYWxsb2MgbWVtb3J5LgogKgogKiBSZXF1aXJlZCBmb3IgYXJjaGl0ZWN0dXJlcyB0aGF0IGhhdmUgZC1jYWNoZSBhbGlhc2luZyBpc3N1ZXMuCiAqLwoKc3RhdGljIHN0cnVjdCBwYWdlICoKcGVyZl9tbWFwX3RvX3BhZ2Uoc3RydWN0IHBlcmZfbW1hcF9kYXRhICpkYXRhLCB1bnNpZ25lZCBsb25nIHBnb2ZmKQp7CglpZiAocGdvZmYgPiAoMVVMIDw8IGRhdGEtPmRhdGFfb3JkZXIpKQoJCXJldHVybiBOVUxMOwoKCXJldHVybiB2bWFsbG9jX3RvX3BhZ2UoKHZvaWQgKilkYXRhLT51c2VyX3BhZ2UgKyBwZ29mZiAqIFBBR0VfU0laRSk7Cn0KCnN0YXRpYyB2b2lkIHBlcmZfbW1hcF91bm1hcmtfcGFnZSh2b2lkICphZGRyKQp7CglzdHJ1Y3QgcGFnZSAqcGFnZSA9IHZtYWxsb2NfdG9fcGFnZShhZGRyKTsKCglwYWdlLT5tYXBwaW5nID0gTlVMTDsKfQoKc3RhdGljIHZvaWQgcGVyZl9tbWFwX2RhdGFfZnJlZV93b3JrKHN0cnVjdCB3b3JrX3N0cnVjdCAqd29yaykKewoJc3RydWN0IHBlcmZfbW1hcF9kYXRhICpkYXRhOwoJdm9pZCAqYmFzZTsKCWludCBpLCBucjsKCglkYXRhID0gY29udGFpbmVyX29mKHdvcmssIHN0cnVjdCBwZXJmX21tYXBfZGF0YSwgd29yayk7CgluciA9IDEgPDwgZGF0YS0+ZGF0YV9vcmRlcjsKCgliYXNlID0gZGF0YS0+dXNlcl9wYWdlOwoJZm9yIChpID0gMDsgaSA8IG5yICsgMTsgaSsrKQoJCXBlcmZfbW1hcF91bm1hcmtfcGFnZShiYXNlICsgKGkgKiBQQUdFX1NJWkUpKTsKCgl2ZnJlZShiYXNlKTsKfQoKc3RhdGljIHZvaWQgcGVyZl9tbWFwX2RhdGFfZnJlZShzdHJ1Y3QgcGVyZl9tbWFwX2RhdGEgKmRhdGEpCnsKCXNjaGVkdWxlX3dvcmsoJmRhdGEtPndvcmspOwp9CgpzdGF0aWMgc3RydWN0IHBlcmZfbW1hcF9kYXRhICoKcGVyZl9tbWFwX2RhdGFfYWxsb2Moc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50LCBpbnQgbnJfcGFnZXMpCnsKCXN0cnVjdCBwZXJmX21tYXBfZGF0YSAqZGF0YTsKCXVuc2lnbmVkIGxvbmcgc2l6ZTsKCXZvaWQgKmFsbF9idWY7CgoJV0FSTl9PTihhdG9taWNfcmVhZCgmZXZlbnQtPm1tYXBfY291bnQpKTsKCglzaXplID0gc2l6ZW9mKHN0cnVjdCBwZXJmX21tYXBfZGF0YSk7CglzaXplICs9IHNpemVvZih2b2lkICopOwoKCWRhdGEgPSBremFsbG9jKHNpemUsIEdGUF9LRVJORUwpOwoJaWYgKCFkYXRhKQoJCWdvdG8gZmFpbDsKCglJTklUX1dPUksoJmRhdGEtPndvcmssIHBlcmZfbW1hcF9kYXRhX2ZyZWVfd29yayk7CgoJYWxsX2J1ZiA9IHZtYWxsb2NfdXNlcigobnJfcGFnZXMgKyAxKSAqIFBBR0VfU0laRSk7CglpZiAoIWFsbF9idWYpCgkJZ290byBmYWlsX2FsbF9idWY7CgoJZGF0YS0+dXNlcl9wYWdlID0gYWxsX2J1ZjsKCWRhdGEtPmRhdGFfcGFnZXNbMF0gPSBhbGxfYnVmICsgUEFHRV9TSVpFOwoJZGF0YS0+ZGF0YV9vcmRlciA9IGlsb2cyKG5yX3BhZ2VzKTsKCWRhdGEtPm5yX3BhZ2VzID0gMTsKCglyZXR1cm4gZGF0YTsKCmZhaWxfYWxsX2J1ZjoKCWtmcmVlKGRhdGEpOwoKZmFpbDoKCXJldHVybiBOVUxMOwp9CgojZW5kaWYKCnN0YXRpYyBpbnQgcGVyZl9tbWFwX2ZhdWx0KHN0cnVjdCB2bV9hcmVhX3N0cnVjdCAqdm1hLCBzdHJ1Y3Qgdm1fZmF1bHQgKnZtZikKewoJc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50ID0gdm1hLT52bV9maWxlLT5wcml2YXRlX2RhdGE7CglzdHJ1Y3QgcGVyZl9tbWFwX2RhdGEgKmRhdGE7CglpbnQgcmV0ID0gVk1fRkFVTFRfU0lHQlVTOwoKCWlmICh2bWYtPmZsYWdzICYgRkFVTFRfRkxBR19NS1dSSVRFKSB7CgkJaWYgKHZtZi0+cGdvZmYgPT0gMCkKCQkJcmV0ID0gMDsKCQlyZXR1cm4gcmV0OwoJfQoKCXJjdV9yZWFkX2xvY2soKTsKCWRhdGEgPSByY3VfZGVyZWZlcmVuY2UoZXZlbnQtPmRhdGEpOwoJaWYgKCFkYXRhKQoJCWdvdG8gdW5sb2NrOwoKCWlmICh2bWYtPnBnb2ZmICYmICh2bWYtPmZsYWdzICYgRkFVTFRfRkxBR19XUklURSkpCgkJZ290byB1bmxvY2s7CgoJdm1mLT5wYWdlID0gcGVyZl9tbWFwX3RvX3BhZ2UoZGF0YSwgdm1mLT5wZ29mZik7CglpZiAoIXZtZi0+cGFnZSkKCQlnb3RvIHVubG9jazsKCglnZXRfcGFnZSh2bWYtPnBhZ2UpOwoJdm1mLT5wYWdlLT5tYXBwaW5nID0gdm1hLT52bV9maWxlLT5mX21hcHBpbmc7Cgl2bWYtPnBhZ2UtPmluZGV4ICAgPSB2bWYtPnBnb2ZmOwoKCXJldCA9IDA7CnVubG9jazoKCXJjdV9yZWFkX3VubG9jaygpOwoKCXJldHVybiByZXQ7Cn0KCnN0YXRpYyB2b2lkCnBlcmZfbW1hcF9kYXRhX2luaXQoc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50LCBzdHJ1Y3QgcGVyZl9tbWFwX2RhdGEgKmRhdGEpCnsKCWxvbmcgbWF4X3NpemUgPSBwZXJmX2RhdGFfc2l6ZShkYXRhKTsKCglhdG9taWNfc2V0KCZkYXRhLT5sb2NrLCAtMSk7CgoJaWYgKGV2ZW50LT5hdHRyLndhdGVybWFyaykgewoJCWRhdGEtPndhdGVybWFyayA9IG1pbl90KGxvbmcsIG1heF9zaXplLAoJCQkJCWV2ZW50LT5hdHRyLndha2V1cF93YXRlcm1hcmspOwoJfQoKCWlmICghZGF0YS0+d2F0ZXJtYXJrKQoJCWRhdGEtPndhdGVybWFyayA9IG1heF90KGxvbmcsIFBBR0VfU0laRSwgbWF4X3NpemUgLyAyKTsKCgoJcmN1X2Fzc2lnbl9wb2ludGVyKGV2ZW50LT5kYXRhLCBkYXRhKTsKfQoKc3RhdGljIHZvaWQgcGVyZl9tbWFwX2RhdGFfZnJlZV9yY3Uoc3RydWN0IHJjdV9oZWFkICpyY3VfaGVhZCkKewoJc3RydWN0IHBlcmZfbW1hcF9kYXRhICpkYXRhOwoKCWRhdGEgPSBjb250YWluZXJfb2YocmN1X2hlYWQsIHN0cnVjdCBwZXJmX21tYXBfZGF0YSwgcmN1X2hlYWQpOwoJcGVyZl9tbWFwX2RhdGFfZnJlZShkYXRhKTsKCWtmcmVlKGRhdGEpOwp9CgpzdGF0aWMgdm9pZCBwZXJmX21tYXBfZGF0YV9yZWxlYXNlKHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCkKewoJc3RydWN0IHBlcmZfbW1hcF9kYXRhICpkYXRhID0gZXZlbnQtPmRhdGE7CgoJV0FSTl9PTihhdG9taWNfcmVhZCgmZXZlbnQtPm1tYXBfY291bnQpKTsKCglyY3VfYXNzaWduX3BvaW50ZXIoZXZlbnQtPmRhdGEsIE5VTEwpOwoJY2FsbF9yY3UoJmRhdGEtPnJjdV9oZWFkLCBwZXJmX21tYXBfZGF0YV9mcmVlX3JjdSk7Cn0KCnN0YXRpYyB2b2lkIHBlcmZfbW1hcF9vcGVuKHN0cnVjdCB2bV9hcmVhX3N0cnVjdCAqdm1hKQp7CglzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQgPSB2bWEtPnZtX2ZpbGUtPnByaXZhdGVfZGF0YTsKCglhdG9taWNfaW5jKCZldmVudC0+bW1hcF9jb3VudCk7Cn0KCnN0YXRpYyB2b2lkIHBlcmZfbW1hcF9jbG9zZShzdHJ1Y3Qgdm1fYXJlYV9zdHJ1Y3QgKnZtYSkKewoJc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50ID0gdm1hLT52bV9maWxlLT5wcml2YXRlX2RhdGE7CgoJV0FSTl9PTl9PTkNFKGV2ZW50LT5jdHgtPnBhcmVudF9jdHgpOwoJaWYgKGF0b21pY19kZWNfYW5kX211dGV4X2xvY2soJmV2ZW50LT5tbWFwX2NvdW50LCAmZXZlbnQtPm1tYXBfbXV0ZXgpKSB7CgkJdW5zaWduZWQgbG9uZyBzaXplID0gcGVyZl9kYXRhX3NpemUoZXZlbnQtPmRhdGEpOwoJCXN0cnVjdCB1c2VyX3N0cnVjdCAqdXNlciA9IGN1cnJlbnRfdXNlcigpOwoKCQlhdG9taWNfbG9uZ19zdWIoKHNpemUgPj4gUEFHRV9TSElGVCkgKyAxLCAmdXNlci0+bG9ja2VkX3ZtKTsKCQl2bWEtPnZtX21tLT5sb2NrZWRfdm0gLT0gZXZlbnQtPmRhdGEtPm5yX2xvY2tlZDsKCQlwZXJmX21tYXBfZGF0YV9yZWxlYXNlKGV2ZW50KTsKCQltdXRleF91bmxvY2soJmV2ZW50LT5tbWFwX211dGV4KTsKCX0KfQoKc3RhdGljIGNvbnN0IHN0cnVjdCB2bV9vcGVyYXRpb25zX3N0cnVjdCBwZXJmX21tYXBfdm1vcHMgPSB7Cgkub3BlbgkJPSBwZXJmX21tYXBfb3BlbiwKCS5jbG9zZQkJPSBwZXJmX21tYXBfY2xvc2UsCgkuZmF1bHQJCT0gcGVyZl9tbWFwX2ZhdWx0LAoJLnBhZ2VfbWt3cml0ZQk9IHBlcmZfbW1hcF9mYXVsdCwKfTsKCnN0YXRpYyBpbnQgcGVyZl9tbWFwKHN0cnVjdCBmaWxlICpmaWxlLCBzdHJ1Y3Qgdm1fYXJlYV9zdHJ1Y3QgKnZtYSkKewoJc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50ID0gZmlsZS0+cHJpdmF0ZV9kYXRhOwoJdW5zaWduZWQgbG9uZyB1c2VyX2xvY2tlZCwgdXNlcl9sb2NrX2xpbWl0OwoJc3RydWN0IHVzZXJfc3RydWN0ICp1c2VyID0gY3VycmVudF91c2VyKCk7Cgl1bnNpZ25lZCBsb25nIGxvY2tlZCwgbG9ja19saW1pdDsKCXN0cnVjdCBwZXJmX21tYXBfZGF0YSAqZGF0YTsKCXVuc2lnbmVkIGxvbmcgdm1hX3NpemU7Cgl1bnNpZ25lZCBsb25nIG5yX3BhZ2VzOwoJbG9uZyB1c2VyX2V4dHJhLCBleHRyYTsKCWludCByZXQgPSAwOwoKCWlmICghKHZtYS0+dm1fZmxhZ3MgJiBWTV9TSEFSRUQpKQoJCXJldHVybiAtRUlOVkFMOwoKCXZtYV9zaXplID0gdm1hLT52bV9lbmQgLSB2bWEtPnZtX3N0YXJ0OwoJbnJfcGFnZXMgPSAodm1hX3NpemUgLyBQQUdFX1NJWkUpIC0gMTsKCgkvKgoJICogSWYgd2UgaGF2ZSBkYXRhIHBhZ2VzIGVuc3VyZSB0aGV5J3JlIGEgcG93ZXItb2YtdHdvIG51bWJlciwgc28gd2UKCSAqIGNhbiBkbyBiaXRtYXNrcyBpbnN0ZWFkIG9mIG1vZHVsby4KCSAqLwoJaWYgKG5yX3BhZ2VzICE9IDAgJiYgIWlzX3Bvd2VyX29mXzIobnJfcGFnZXMpKQoJCXJldHVybiAtRUlOVkFMOwoKCWlmICh2bWFfc2l6ZSAhPSBQQUdFX1NJWkUgKiAoMSArIG5yX3BhZ2VzKSkKCQlyZXR1cm4gLUVJTlZBTDsKCglpZiAodm1hLT52bV9wZ29mZiAhPSAwKQoJCXJldHVybiAtRUlOVkFMOwoKCVdBUk5fT05fT05DRShldmVudC0+Y3R4LT5wYXJlbnRfY3R4KTsKCW11dGV4X2xvY2soJmV2ZW50LT5tbWFwX211dGV4KTsKCWlmIChldmVudC0+b3V0cHV0KSB7CgkJcmV0ID0gLUVJTlZBTDsKCQlnb3RvIHVubG9jazsKCX0KCglpZiAoYXRvbWljX2luY19ub3RfemVybygmZXZlbnQtPm1tYXBfY291bnQpKSB7CgkJaWYgKG5yX3BhZ2VzICE9IGV2ZW50LT5kYXRhLT5ucl9wYWdlcykKCQkJcmV0ID0gLUVJTlZBTDsKCQlnb3RvIHVubG9jazsKCX0KCgl1c2VyX2V4dHJhID0gbnJfcGFnZXMgKyAxOwoJdXNlcl9sb2NrX2xpbWl0ID0gc3lzY3RsX3BlcmZfZXZlbnRfbWxvY2sgPj4gKFBBR0VfU0hJRlQgLSAxMCk7CgoJLyoKCSAqIEluY3JlYXNlIHRoZSBsaW1pdCBsaW5lYXJseSB3aXRoIG1vcmUgQ1BVczoKCSAqLwoJdXNlcl9sb2NrX2xpbWl0ICo9IG51bV9vbmxpbmVfY3B1cygpOwoKCXVzZXJfbG9ja2VkID0gYXRvbWljX2xvbmdfcmVhZCgmdXNlci0+bG9ja2VkX3ZtKSArIHVzZXJfZXh0cmE7CgoJZXh0cmEgPSAwOwoJaWYgKHVzZXJfbG9ja2VkID4gdXNlcl9sb2NrX2xpbWl0KQoJCWV4dHJhID0gdXNlcl9sb2NrZWQgLSB1c2VyX2xvY2tfbGltaXQ7CgoJbG9ja19saW1pdCA9IGN1cnJlbnQtPnNpZ25hbC0+cmxpbVtSTElNSVRfTUVNTE9DS10ucmxpbV9jdXI7Cglsb2NrX2xpbWl0ID4+PSBQQUdFX1NISUZUOwoJbG9ja2VkID0gdm1hLT52bV9tbS0+bG9ja2VkX3ZtICsgZXh0cmE7CgoJaWYgKChsb2NrZWQgPiBsb2NrX2xpbWl0KSAmJiBwZXJmX3BhcmFub2lkX3RyYWNlcG9pbnRfcmF3KCkgJiYKCQkhY2FwYWJsZShDQVBfSVBDX0xPQ0spKSB7CgkJcmV0ID0gLUVQRVJNOwoJCWdvdG8gdW5sb2NrOwoJfQoKCVdBUk5fT04oZXZlbnQtPmRhdGEpOwoKCWRhdGEgPSBwZXJmX21tYXBfZGF0YV9hbGxvYyhldmVudCwgbnJfcGFnZXMpOwoJcmV0ID0gLUVOT01FTTsKCWlmICghZGF0YSkKCQlnb3RvIHVubG9jazsKCglyZXQgPSAwOwoJcGVyZl9tbWFwX2RhdGFfaW5pdChldmVudCwgZGF0YSk7CgoJYXRvbWljX3NldCgmZXZlbnQtPm1tYXBfY291bnQsIDEpOwoJYXRvbWljX2xvbmdfYWRkKHVzZXJfZXh0cmEsICZ1c2VyLT5sb2NrZWRfdm0pOwoJdm1hLT52bV9tbS0+bG9ja2VkX3ZtICs9IGV4dHJhOwoJZXZlbnQtPmRhdGEtPm5yX2xvY2tlZCA9IGV4dHJhOwoJaWYgKHZtYS0+dm1fZmxhZ3MgJiBWTV9XUklURSkKCQlldmVudC0+ZGF0YS0+d3JpdGFibGUgPSAxOwoKdW5sb2NrOgoJbXV0ZXhfdW5sb2NrKCZldmVudC0+bW1hcF9tdXRleCk7CgoJdm1hLT52bV9mbGFncyB8PSBWTV9SRVNFUlZFRDsKCXZtYS0+dm1fb3BzID0gJnBlcmZfbW1hcF92bW9wczsKCglyZXR1cm4gcmV0Owp9CgpzdGF0aWMgaW50IHBlcmZfZmFzeW5jKGludCBmZCwgc3RydWN0IGZpbGUgKmZpbHAsIGludCBvbikKewoJc3RydWN0IGlub2RlICppbm9kZSA9IGZpbHAtPmZfcGF0aC5kZW50cnktPmRfaW5vZGU7CglzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQgPSBmaWxwLT5wcml2YXRlX2RhdGE7CglpbnQgcmV0dmFsOwoKCW11dGV4X2xvY2soJmlub2RlLT5pX211dGV4KTsKCXJldHZhbCA9IGZhc3luY19oZWxwZXIoZmQsIGZpbHAsIG9uLCAmZXZlbnQtPmZhc3luYyk7CgltdXRleF91bmxvY2soJmlub2RlLT5pX211dGV4KTsKCglpZiAocmV0dmFsIDwgMCkKCQlyZXR1cm4gcmV0dmFsOwoKCXJldHVybiAwOwp9CgpzdGF0aWMgY29uc3Qgc3RydWN0IGZpbGVfb3BlcmF0aW9ucyBwZXJmX2ZvcHMgPSB7CgkucmVsZWFzZQkJPSBwZXJmX3JlbGVhc2UsCgkucmVhZAkJCT0gcGVyZl9yZWFkLAoJLnBvbGwJCQk9IHBlcmZfcG9sbCwKCS51bmxvY2tlZF9pb2N0bAkJPSBwZXJmX2lvY3RsLAoJLmNvbXBhdF9pb2N0bAkJPSBwZXJmX2lvY3RsLAoJLm1tYXAJCQk9IHBlcmZfbW1hcCwKCS5mYXN5bmMJCQk9IHBlcmZfZmFzeW5jLAp9OwoKLyoKICogUGVyZiBldmVudCB3YWtldXAKICoKICogSWYgdGhlcmUncyBkYXRhLCBlbnN1cmUgd2Ugc2V0IHRoZSBwb2xsKCkgc3RhdGUgYW5kIHB1Ymxpc2ggZXZlcnl0aGluZwogKiB0byB1c2VyLXNwYWNlIGJlZm9yZSB3YWtpbmcgZXZlcnlib2R5IHVwLgogKi8KCnZvaWQgcGVyZl9ldmVudF93YWtldXAoc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50KQp7Cgl3YWtlX3VwX2FsbCgmZXZlbnQtPndhaXRxKTsKCglpZiAoZXZlbnQtPnBlbmRpbmdfa2lsbCkgewoJCWtpbGxfZmFzeW5jKCZldmVudC0+ZmFzeW5jLCBTSUdJTywgZXZlbnQtPnBlbmRpbmdfa2lsbCk7CgkJZXZlbnQtPnBlbmRpbmdfa2lsbCA9IDA7Cgl9Cn0KCi8qCiAqIFBlbmRpbmcgd2FrZXVwcwogKgogKiBIYW5kbGUgdGhlIGNhc2Ugd2hlcmUgd2UgbmVlZCB0byB3YWtldXAgdXAgZnJvbSBOTUkgKG9yIHJxLT5sb2NrKSBjb250ZXh0LgogKgogKiBUaGUgTk1JIGJpdCBtZWFucyB3ZSBjYW5ub3QgcG9zc2libHkgdGFrZSBsb2Nrcy4gVGhlcmVmb3JlLCBtYWludGFpbiBhCiAqIHNpbmdsZSBsaW5rZWQgbGlzdCBhbmQgdXNlIGNtcHhjaGcoKSB0byBhZGQgZW50cmllcyBsb2NrbGVzcy4KICovCgpzdGF0aWMgdm9pZCBwZXJmX3BlbmRpbmdfZXZlbnQoc3RydWN0IHBlcmZfcGVuZGluZ19lbnRyeSAqZW50cnkpCnsKCXN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCA9IGNvbnRhaW5lcl9vZihlbnRyeSwKCQkJc3RydWN0IHBlcmZfZXZlbnQsIHBlbmRpbmcpOwoKCWlmIChldmVudC0+cGVuZGluZ19kaXNhYmxlKSB7CgkJZXZlbnQtPnBlbmRpbmdfZGlzYWJsZSA9IDA7CgkJX19wZXJmX2V2ZW50X2Rpc2FibGUoZXZlbnQpOwoJfQoKCWlmIChldmVudC0+cGVuZGluZ193YWtldXApIHsKCQlldmVudC0+cGVuZGluZ193YWtldXAgPSAwOwoJCXBlcmZfZXZlbnRfd2FrZXVwKGV2ZW50KTsKCX0KfQoKI2RlZmluZSBQRU5ESU5HX1RBSUwgKChzdHJ1Y3QgcGVyZl9wZW5kaW5nX2VudHJ5ICopLTFVTCkKCnN0YXRpYyBERUZJTkVfUEVSX0NQVShzdHJ1Y3QgcGVyZl9wZW5kaW5nX2VudHJ5ICosIHBlcmZfcGVuZGluZ19oZWFkKSA9IHsKCVBFTkRJTkdfVEFJTCwKfTsKCnN0YXRpYyB2b2lkIHBlcmZfcGVuZGluZ19xdWV1ZShzdHJ1Y3QgcGVyZl9wZW5kaW5nX2VudHJ5ICplbnRyeSwKCQkJICAgICAgIHZvaWQgKCpmdW5jKShzdHJ1Y3QgcGVyZl9wZW5kaW5nX2VudHJ5ICopKQp7CglzdHJ1Y3QgcGVyZl9wZW5kaW5nX2VudHJ5ICoqaGVhZDsKCglpZiAoY21weGNoZygmZW50cnktPm5leHQsIE5VTEwsIFBFTkRJTkdfVEFJTCkgIT0gTlVMTCkKCQlyZXR1cm47CgoJZW50cnktPmZ1bmMgPSBmdW5jOwoKCWhlYWQgPSAmZ2V0X2NwdV92YXIocGVyZl9wZW5kaW5nX2hlYWQpOwoKCWRvIHsKCQllbnRyeS0+bmV4dCA9ICpoZWFkOwoJfSB3aGlsZSAoY21weGNoZyhoZWFkLCBlbnRyeS0+bmV4dCwgZW50cnkpICE9IGVudHJ5LT5uZXh0KTsKCglzZXRfcGVyZl9ldmVudF9wZW5kaW5nKCk7CgoJcHV0X2NwdV92YXIocGVyZl9wZW5kaW5nX2hlYWQpOwp9CgpzdGF0aWMgaW50IF9fcGVyZl9wZW5kaW5nX3J1bih2b2lkKQp7CglzdHJ1Y3QgcGVyZl9wZW5kaW5nX2VudHJ5ICpsaXN0OwoJaW50IG5yID0gMDsKCglsaXN0ID0geGNoZygmX19nZXRfY3B1X3ZhcihwZXJmX3BlbmRpbmdfaGVhZCksIFBFTkRJTkdfVEFJTCk7Cgl3aGlsZSAobGlzdCAhPSBQRU5ESU5HX1RBSUwpIHsKCQl2b2lkICgqZnVuYykoc3RydWN0IHBlcmZfcGVuZGluZ19lbnRyeSAqKTsKCQlzdHJ1Y3QgcGVyZl9wZW5kaW5nX2VudHJ5ICplbnRyeSA9IGxpc3Q7CgoJCWxpc3QgPSBsaXN0LT5uZXh0OwoKCQlmdW5jID0gZW50cnktPmZ1bmM7CgkJZW50cnktPm5leHQgPSBOVUxMOwoJCS8qCgkJICogRW5zdXJlIHdlIG9ic2VydmUgdGhlIHVucXVldWUgYmVmb3JlIHdlIGlzc3VlIHRoZSB3YWtldXAsCgkJICogc28gdGhhdCB3ZSB3b24ndCBiZSB3YWl0aW5nIGZvcmV2ZXIuCgkJICogLS0gc2VlIHBlcmZfbm90X3BlbmRpbmcoKS4KCQkgKi8KCQlzbXBfd21iKCk7CgoJCWZ1bmMoZW50cnkpOwoJCW5yKys7Cgl9CgoJcmV0dXJuIG5yOwp9CgpzdGF0aWMgaW5saW5lIGludCBwZXJmX25vdF9wZW5kaW5nKHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCkKewoJLyoKCSAqIElmIHdlIGZsdXNoIG9uIHdoYXRldmVyIGNwdSB3ZSBydW4sIHRoZXJlIGlzIGEgY2hhbmNlIHdlIGRvbid0CgkgKiBuZWVkIHRvIHdhaXQuCgkgKi8KCWdldF9jcHUoKTsKCV9fcGVyZl9wZW5kaW5nX3J1bigpOwoJcHV0X2NwdSgpOwoKCS8qCgkgKiBFbnN1cmUgd2Ugc2VlIHRoZSBwcm9wZXIgcXVldWUgc3RhdGUgYmVmb3JlIGdvaW5nIHRvIHNsZWVwCgkgKiBzbyB0aGF0IHdlIGRvIG5vdCBtaXNzIHRoZSB3YWtldXAuIC0tIHNlZSBwZXJmX3BlbmRpbmdfaGFuZGxlKCkKCSAqLwoJc21wX3JtYigpOwoJcmV0dXJuIGV2ZW50LT5wZW5kaW5nLm5leHQgPT0gTlVMTDsKfQoKc3RhdGljIHZvaWQgcGVyZl9wZW5kaW5nX3N5bmMoc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50KQp7Cgl3YWl0X2V2ZW50KGV2ZW50LT53YWl0cSwgcGVyZl9ub3RfcGVuZGluZyhldmVudCkpOwp9Cgp2b2lkIHBlcmZfZXZlbnRfZG9fcGVuZGluZyh2b2lkKQp7CglfX3BlcmZfcGVuZGluZ19ydW4oKTsKfQoKLyoKICogQ2FsbGNoYWluIHN1cHBvcnQgLS0gYXJjaCBzcGVjaWZpYwogKi8KCl9fd2VhayBzdHJ1Y3QgcGVyZl9jYWxsY2hhaW5fZW50cnkgKnBlcmZfY2FsbGNoYWluKHN0cnVjdCBwdF9yZWdzICpyZWdzKQp7CglyZXR1cm4gTlVMTDsKfQoKLyoKICogT3V0cHV0CiAqLwpzdGF0aWMgYm9vbCBwZXJmX291dHB1dF9zcGFjZShzdHJ1Y3QgcGVyZl9tbWFwX2RhdGEgKmRhdGEsIHVuc2lnbmVkIGxvbmcgdGFpbCwKCQkJICAgICAgdW5zaWduZWQgbG9uZyBvZmZzZXQsIHVuc2lnbmVkIGxvbmcgaGVhZCkKewoJdW5zaWduZWQgbG9uZyBtYXNrOwoKCWlmICghZGF0YS0+d3JpdGFibGUpCgkJcmV0dXJuIHRydWU7CgoJbWFzayA9IHBlcmZfZGF0YV9zaXplKGRhdGEpIC0gMTsKCglvZmZzZXQgPSAob2Zmc2V0IC0gdGFpbCkgJiBtYXNrOwoJaGVhZCAgID0gKGhlYWQgICAtIHRhaWwpICYgbWFzazsKCglpZiAoKGludCkoaGVhZCAtIG9mZnNldCkgPCAwKQoJCXJldHVybiBmYWxzZTsKCglyZXR1cm4gdHJ1ZTsKfQoKc3RhdGljIHZvaWQgcGVyZl9vdXRwdXRfd2FrZXVwKHN0cnVjdCBwZXJmX291dHB1dF9oYW5kbGUgKmhhbmRsZSkKewoJYXRvbWljX3NldCgmaGFuZGxlLT5kYXRhLT5wb2xsLCBQT0xMX0lOKTsKCglpZiAoaGFuZGxlLT5ubWkpIHsKCQloYW5kbGUtPmV2ZW50LT5wZW5kaW5nX3dha2V1cCA9IDE7CgkJcGVyZl9wZW5kaW5nX3F1ZXVlKCZoYW5kbGUtPmV2ZW50LT5wZW5kaW5nLAoJCQkJICAgcGVyZl9wZW5kaW5nX2V2ZW50KTsKCX0gZWxzZQoJCXBlcmZfZXZlbnRfd2FrZXVwKGhhbmRsZS0+ZXZlbnQpOwp9CgovKgogKiBDdXJpb3VzIGxvY2tpbmcgY29uc3RydWN0LgogKgogKiBXZSBuZWVkIHRvIGVuc3VyZSBhIGxhdGVyIGV2ZW50X2lkIGRvZXNuJ3QgcHVibGlzaCBhIGhlYWQgd2hlbiBhIGZvcm1lcgogKiBldmVudF9pZCBpc24ndCBkb25lIHdyaXRpbmcuIEhvd2V2ZXIgc2luY2Ugd2UgbmVlZCB0byBkZWFsIHdpdGggTk1JcyB3ZQogKiBjYW5ub3QgZnVsbHkgc2VyaWFsaXplIHRoaW5ncy4KICoKICogV2hhdCB3ZSBkbyBpcyBzZXJpYWxpemUgYmV0d2VlbiBDUFVzIHNvIHdlIG9ubHkgaGF2ZSB0byBkZWFsIHdpdGggTk1JCiAqIG5lc3Rpbmcgb24gYSBzaW5nbGUgQ1BVLgogKgogKiBXZSBvbmx5IHB1Ymxpc2ggdGhlIGhlYWQgKGFuZCBnZW5lcmF0ZSBhIHdha2V1cCkgd2hlbiB0aGUgb3V0ZXItbW9zdAogKiBldmVudF9pZCBjb21wbGV0ZXMuCiAqLwpzdGF0aWMgdm9pZCBwZXJmX291dHB1dF9sb2NrKHN0cnVjdCBwZXJmX291dHB1dF9oYW5kbGUgKmhhbmRsZSkKewoJc3RydWN0IHBlcmZfbW1hcF9kYXRhICpkYXRhID0gaGFuZGxlLT5kYXRhOwoJaW50IGNwdTsKCgloYW5kbGUtPmxvY2tlZCA9IDA7CgoJbG9jYWxfaXJxX3NhdmUoaGFuZGxlLT5mbGFncyk7CgljcHUgPSBzbXBfcHJvY2Vzc29yX2lkKCk7CgoJaWYgKGluX25taSgpICYmIGF0b21pY19yZWFkKCZkYXRhLT5sb2NrKSA9PSBjcHUpCgkJcmV0dXJuOwoKCXdoaWxlIChhdG9taWNfY21weGNoZygmZGF0YS0+bG9jaywgLTEsIGNwdSkgIT0gLTEpCgkJY3B1X3JlbGF4KCk7CgoJaGFuZGxlLT5sb2NrZWQgPSAxOwp9CgpzdGF0aWMgdm9pZCBwZXJmX291dHB1dF91bmxvY2soc3RydWN0IHBlcmZfb3V0cHV0X2hhbmRsZSAqaGFuZGxlKQp7CglzdHJ1Y3QgcGVyZl9tbWFwX2RhdGEgKmRhdGEgPSBoYW5kbGUtPmRhdGE7Cgl1bnNpZ25lZCBsb25nIGhlYWQ7CglpbnQgY3B1OwoKCWRhdGEtPmRvbmVfaGVhZCA9IGRhdGEtPmhlYWQ7CgoJaWYgKCFoYW5kbGUtPmxvY2tlZCkKCQlnb3RvIG91dDsKCmFnYWluOgoJLyoKCSAqIFRoZSB4Y2hnIGltcGxpZXMgYSBmdWxsIGJhcnJpZXIgdGhhdCBlbnN1cmVzIGFsbCB3cml0ZXMgYXJlIGRvbmUKCSAqIGJlZm9yZSB3ZSBwdWJsaXNoIHRoZSBuZXcgaGVhZCwgbWF0Y2hlZCBieSBhIHJtYigpIGluIHVzZXJzcGFjZSB3aGVuCgkgKiByZWFkaW5nIHRoaXMgcG9zaXRpb24uCgkgKi8KCXdoaWxlICgoaGVhZCA9IGF0b21pY19sb25nX3hjaGcoJmRhdGEtPmRvbmVfaGVhZCwgMCkpKQoJCWRhdGEtPnVzZXJfcGFnZS0+ZGF0YV9oZWFkID0gaGVhZDsKCgkvKgoJICogTk1JIGNhbiBoYXBwZW4gaGVyZSwgd2hpY2ggbWVhbnMgd2UgY2FuIG1pc3MgYSBkb25lX2hlYWQgdXBkYXRlLgoJICovCgoJY3B1ID0gYXRvbWljX3hjaGcoJmRhdGEtPmxvY2ssIC0xKTsKCVdBUk5fT05fT05DRShjcHUgIT0gc21wX3Byb2Nlc3Nvcl9pZCgpKTsKCgkvKgoJICogVGhlcmVmb3JlIHdlIGhhdmUgdG8gdmFsaWRhdGUgd2UgZGlkIG5vdCBpbmRlZWQgZG8gc28uCgkgKi8KCWlmICh1bmxpa2VseShhdG9taWNfbG9uZ19yZWFkKCZkYXRhLT5kb25lX2hlYWQpKSkgewoJCS8qCgkJICogU2luY2Ugd2UgaGFkIGl0IGxvY2tlZCwgd2UgY2FuIGxvY2sgaXQgYWdhaW4uCgkJICovCgkJd2hpbGUgKGF0b21pY19jbXB4Y2hnKCZkYXRhLT5sb2NrLCAtMSwgY3B1KSAhPSAtMSkKCQkJY3B1X3JlbGF4KCk7CgoJCWdvdG8gYWdhaW47Cgl9CgoJaWYgKGF0b21pY194Y2hnKCZkYXRhLT53YWtldXAsIDApKQoJCXBlcmZfb3V0cHV0X3dha2V1cChoYW5kbGUpOwpvdXQ6Cglsb2NhbF9pcnFfcmVzdG9yZShoYW5kbGUtPmZsYWdzKTsKfQoKdm9pZCBwZXJmX291dHB1dF9jb3B5KHN0cnVjdCBwZXJmX291dHB1dF9oYW5kbGUgKmhhbmRsZSwKCQkgICAgICBjb25zdCB2b2lkICpidWYsIHVuc2lnbmVkIGludCBsZW4pCnsKCXVuc2lnbmVkIGludCBwYWdlc19tYXNrOwoJdW5zaWduZWQgbG9uZyBvZmZzZXQ7Cgl1bnNpZ25lZCBpbnQgc2l6ZTsKCXZvaWQgKipwYWdlczsKCglvZmZzZXQJCT0gaGFuZGxlLT5vZmZzZXQ7CglwYWdlc19tYXNrCT0gaGFuZGxlLT5kYXRhLT5ucl9wYWdlcyAtIDE7CglwYWdlcwkJPSBoYW5kbGUtPmRhdGEtPmRhdGFfcGFnZXM7CgoJZG8gewoJCXVuc2lnbmVkIGxvbmcgcGFnZV9vZmZzZXQ7CgkJdW5zaWduZWQgbG9uZyBwYWdlX3NpemU7CgkJaW50IG5yOwoKCQlucgkgICAgPSAob2Zmc2V0ID4+IFBBR0VfU0hJRlQpICYgcGFnZXNfbWFzazsKCQlwYWdlX3NpemUgICA9IDFVTCA8PCAoaGFuZGxlLT5kYXRhLT5kYXRhX29yZGVyICsgUEFHRV9TSElGVCk7CgkJcGFnZV9vZmZzZXQgPSBvZmZzZXQgJiAocGFnZV9zaXplIC0gMSk7CgkJc2l6ZQkgICAgPSBtaW5fdCh1bnNpZ25lZCBpbnQsIHBhZ2Vfc2l6ZSAtIHBhZ2Vfb2Zmc2V0LCBsZW4pOwoKCQltZW1jcHkocGFnZXNbbnJdICsgcGFnZV9vZmZzZXQsIGJ1Ziwgc2l6ZSk7CgoJCWxlbgkgICAgLT0gc2l6ZTsKCQlidWYJICAgICs9IHNpemU7CgkJb2Zmc2V0CSAgICArPSBzaXplOwoJfSB3aGlsZSAobGVuKTsKCgloYW5kbGUtPm9mZnNldCA9IG9mZnNldDsKCgkvKgoJICogQ2hlY2sgd2UgZGlkbid0IGNvcHkgcGFzdCBvdXIgcmVzZXJ2YXRpb24gd2luZG93LCB0YWtpbmcgdGhlCgkgKiBwb3NzaWJsZSB1bnNpZ25lZCBpbnQgd3JhcCBpbnRvIGFjY291bnQuCgkgKi8KCVdBUk5fT05fT05DRSgoKGxvbmcpKGhhbmRsZS0+aGVhZCAtIGhhbmRsZS0+b2Zmc2V0KSkgPCAwKTsKfQoKaW50IHBlcmZfb3V0cHV0X2JlZ2luKHN0cnVjdCBwZXJmX291dHB1dF9oYW5kbGUgKmhhbmRsZSwKCQkgICAgICBzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQsIHVuc2lnbmVkIGludCBzaXplLAoJCSAgICAgIGludCBubWksIGludCBzYW1wbGUpCnsKCXN0cnVjdCBwZXJmX2V2ZW50ICpvdXRwdXRfZXZlbnQ7CglzdHJ1Y3QgcGVyZl9tbWFwX2RhdGEgKmRhdGE7Cgl1bnNpZ25lZCBsb25nIHRhaWwsIG9mZnNldCwgaGVhZDsKCWludCBoYXZlX2xvc3Q7CglzdHJ1Y3QgewoJCXN0cnVjdCBwZXJmX2V2ZW50X2hlYWRlciBoZWFkZXI7CgkJdTY0CQkJIGlkOwoJCXU2NAkJCSBsb3N0OwoJfSBsb3N0X2V2ZW50OwoKCXJjdV9yZWFkX2xvY2soKTsKCS8qCgkgKiBGb3IgaW5oZXJpdGVkIGV2ZW50cyB3ZSBzZW5kIGFsbCB0aGUgb3V0cHV0IHRvd2FyZHMgdGhlIHBhcmVudC4KCSAqLwoJaWYgKGV2ZW50LT5wYXJlbnQpCgkJZXZlbnQgPSBldmVudC0+cGFyZW50OwoKCW91dHB1dF9ldmVudCA9IHJjdV9kZXJlZmVyZW5jZShldmVudC0+b3V0cHV0KTsKCWlmIChvdXRwdXRfZXZlbnQpCgkJZXZlbnQgPSBvdXRwdXRfZXZlbnQ7CgoJZGF0YSA9IHJjdV9kZXJlZmVyZW5jZShldmVudC0+ZGF0YSk7CglpZiAoIWRhdGEpCgkJZ290byBvdXQ7CgoJaGFuZGxlLT5kYXRhCT0gZGF0YTsKCWhhbmRsZS0+ZXZlbnQJPSBldmVudDsKCWhhbmRsZS0+bm1pCT0gbm1pOwoJaGFuZGxlLT5zYW1wbGUJPSBzYW1wbGU7CgoJaWYgKCFkYXRhLT5ucl9wYWdlcykKCQlnb3RvIGZhaWw7CgoJaGF2ZV9sb3N0ID0gYXRvbWljX3JlYWQoJmRhdGEtPmxvc3QpOwoJaWYgKGhhdmVfbG9zdCkKCQlzaXplICs9IHNpemVvZihsb3N0X2V2ZW50KTsKCglwZXJmX291dHB1dF9sb2NrKGhhbmRsZSk7CgoJZG8gewoJCS8qCgkJICogVXNlcnNwYWNlIGNvdWxkIGNob29zZSB0byBpc3N1ZSBhIG1iKCkgYmVmb3JlIHVwZGF0aW5nIHRoZQoJCSAqIHRhaWwgcG9pbnRlci4gU28gdGhhdCBhbGwgcmVhZHMgd2lsbCBiZSBjb21wbGV0ZWQgYmVmb3JlIHRoZQoJCSAqIHdyaXRlIGlzIGlzc3VlZC4KCQkgKi8KCQl0YWlsID0gQUNDRVNTX09OQ0UoZGF0YS0+dXNlcl9wYWdlLT5kYXRhX3RhaWwpOwoJCXNtcF9ybWIoKTsKCQlvZmZzZXQgPSBoZWFkID0gYXRvbWljX2xvbmdfcmVhZCgmZGF0YS0+aGVhZCk7CgkJaGVhZCArPSBzaXplOwoJCWlmICh1bmxpa2VseSghcGVyZl9vdXRwdXRfc3BhY2UoZGF0YSwgdGFpbCwgb2Zmc2V0LCBoZWFkKSkpCgkJCWdvdG8gZmFpbDsKCX0gd2hpbGUgKGF0b21pY19sb25nX2NtcHhjaGcoJmRhdGEtPmhlYWQsIG9mZnNldCwgaGVhZCkgIT0gb2Zmc2V0KTsKCgloYW5kbGUtPm9mZnNldAk9IG9mZnNldDsKCWhhbmRsZS0+aGVhZAk9IGhlYWQ7CgoJaWYgKGhlYWQgLSB0YWlsID4gZGF0YS0+d2F0ZXJtYXJrKQoJCWF0b21pY19zZXQoJmRhdGEtPndha2V1cCwgMSk7CgoJaWYgKGhhdmVfbG9zdCkgewoJCWxvc3RfZXZlbnQuaGVhZGVyLnR5cGUgPSBQRVJGX1JFQ09SRF9MT1NUOwoJCWxvc3RfZXZlbnQuaGVhZGVyLm1pc2MgPSAwOwoJCWxvc3RfZXZlbnQuaGVhZGVyLnNpemUgPSBzaXplb2YobG9zdF9ldmVudCk7CgkJbG9zdF9ldmVudC5pZCAgICAgICAgICA9IGV2ZW50LT5pZDsKCQlsb3N0X2V2ZW50Lmxvc3QgICAgICAgID0gYXRvbWljX3hjaGcoJmRhdGEtPmxvc3QsIDApOwoKCQlwZXJmX291dHB1dF9wdXQoaGFuZGxlLCBsb3N0X2V2ZW50KTsKCX0KCglyZXR1cm4gMDsKCmZhaWw6CglhdG9taWNfaW5jKCZkYXRhLT5sb3N0KTsKCXBlcmZfb3V0cHV0X3VubG9jayhoYW5kbGUpOwpvdXQ6CglyY3VfcmVhZF91bmxvY2soKTsKCglyZXR1cm4gLUVOT1NQQzsKfQoKdm9pZCBwZXJmX291dHB1dF9lbmQoc3RydWN0IHBlcmZfb3V0cHV0X2hhbmRsZSAqaGFuZGxlKQp7CglzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQgPSBoYW5kbGUtPmV2ZW50OwoJc3RydWN0IHBlcmZfbW1hcF9kYXRhICpkYXRhID0gaGFuZGxlLT5kYXRhOwoKCWludCB3YWtldXBfZXZlbnRzID0gZXZlbnQtPmF0dHIud2FrZXVwX2V2ZW50czsKCglpZiAoaGFuZGxlLT5zYW1wbGUgJiYgd2FrZXVwX2V2ZW50cykgewoJCWludCBldmVudHMgPSBhdG9taWNfaW5jX3JldHVybigmZGF0YS0+ZXZlbnRzKTsKCQlpZiAoZXZlbnRzID49IHdha2V1cF9ldmVudHMpIHsKCQkJYXRvbWljX3N1Yih3YWtldXBfZXZlbnRzLCAmZGF0YS0+ZXZlbnRzKTsKCQkJYXRvbWljX3NldCgmZGF0YS0+d2FrZXVwLCAxKTsKCQl9Cgl9CgoJcGVyZl9vdXRwdXRfdW5sb2NrKGhhbmRsZSk7CglyY3VfcmVhZF91bmxvY2soKTsKfQoKc3RhdGljIHUzMiBwZXJmX2V2ZW50X3BpZChzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQsIHN0cnVjdCB0YXNrX3N0cnVjdCAqcCkKewoJLyoKCSAqIG9ubHkgdG9wIGxldmVsIGV2ZW50cyBoYXZlIHRoZSBwaWQgbmFtZXNwYWNlIHRoZXkgd2VyZSBjcmVhdGVkIGluCgkgKi8KCWlmIChldmVudC0+cGFyZW50KQoJCWV2ZW50ID0gZXZlbnQtPnBhcmVudDsKCglyZXR1cm4gdGFza190Z2lkX25yX25zKHAsIGV2ZW50LT5ucyk7Cn0KCnN0YXRpYyB1MzIgcGVyZl9ldmVudF90aWQoc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50LCBzdHJ1Y3QgdGFza19zdHJ1Y3QgKnApCnsKCS8qCgkgKiBvbmx5IHRvcCBsZXZlbCBldmVudHMgaGF2ZSB0aGUgcGlkIG5hbWVzcGFjZSB0aGV5IHdlcmUgY3JlYXRlZCBpbgoJICovCglpZiAoZXZlbnQtPnBhcmVudCkKCQlldmVudCA9IGV2ZW50LT5wYXJlbnQ7CgoJcmV0dXJuIHRhc2tfcGlkX25yX25zKHAsIGV2ZW50LT5ucyk7Cn0KCnN0YXRpYyB2b2lkIHBlcmZfb3V0cHV0X3JlYWRfb25lKHN0cnVjdCBwZXJmX291dHB1dF9oYW5kbGUgKmhhbmRsZSwKCQkJCSBzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQpCnsKCXU2NCByZWFkX2Zvcm1hdCA9IGV2ZW50LT5hdHRyLnJlYWRfZm9ybWF0OwoJdTY0IHZhbHVlc1s0XTsKCWludCBuID0gMDsKCgl2YWx1ZXNbbisrXSA9IGF0b21pYzY0X3JlYWQoJmV2ZW50LT5jb3VudCk7CglpZiAocmVhZF9mb3JtYXQgJiBQRVJGX0ZPUk1BVF9UT1RBTF9USU1FX0VOQUJMRUQpIHsKCQl2YWx1ZXNbbisrXSA9IGV2ZW50LT50b3RhbF90aW1lX2VuYWJsZWQgKwoJCQlhdG9taWM2NF9yZWFkKCZldmVudC0+Y2hpbGRfdG90YWxfdGltZV9lbmFibGVkKTsKCX0KCWlmIChyZWFkX2Zvcm1hdCAmIFBFUkZfRk9STUFUX1RPVEFMX1RJTUVfUlVOTklORykgewoJCXZhbHVlc1tuKytdID0gZXZlbnQtPnRvdGFsX3RpbWVfcnVubmluZyArCgkJCWF0b21pYzY0X3JlYWQoJmV2ZW50LT5jaGlsZF90b3RhbF90aW1lX3J1bm5pbmcpOwoJfQoJaWYgKHJlYWRfZm9ybWF0ICYgUEVSRl9GT1JNQVRfSUQpCgkJdmFsdWVzW24rK10gPSBwcmltYXJ5X2V2ZW50X2lkKGV2ZW50KTsKCglwZXJmX291dHB1dF9jb3B5KGhhbmRsZSwgdmFsdWVzLCBuICogc2l6ZW9mKHU2NCkpOwp9CgovKgogKiBYWFggUEVSRl9GT1JNQVRfR1JPVVAgdnMgaW5oZXJpdGVkIGV2ZW50cyBzZWVtcyBkaWZmaWN1bHQuCiAqLwpzdGF0aWMgdm9pZCBwZXJmX291dHB1dF9yZWFkX2dyb3VwKHN0cnVjdCBwZXJmX291dHB1dF9oYW5kbGUgKmhhbmRsZSwKCQkJICAgIHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCkKewoJc3RydWN0IHBlcmZfZXZlbnQgKmxlYWRlciA9IGV2ZW50LT5ncm91cF9sZWFkZXIsICpzdWI7Cgl1NjQgcmVhZF9mb3JtYXQgPSBldmVudC0+YXR0ci5yZWFkX2Zvcm1hdDsKCXU2NCB2YWx1ZXNbNV07CglpbnQgbiA9IDA7CgoJdmFsdWVzW24rK10gPSAxICsgbGVhZGVyLT5ucl9zaWJsaW5nczsKCglpZiAocmVhZF9mb3JtYXQgJiBQRVJGX0ZPUk1BVF9UT1RBTF9USU1FX0VOQUJMRUQpCgkJdmFsdWVzW24rK10gPSBsZWFkZXItPnRvdGFsX3RpbWVfZW5hYmxlZDsKCglpZiAocmVhZF9mb3JtYXQgJiBQRVJGX0ZPUk1BVF9UT1RBTF9USU1FX1JVTk5JTkcpCgkJdmFsdWVzW24rK10gPSBsZWFkZXItPnRvdGFsX3RpbWVfcnVubmluZzsKCglpZiAobGVhZGVyICE9IGV2ZW50KQoJCWxlYWRlci0+cG11LT5yZWFkKGxlYWRlcik7CgoJdmFsdWVzW24rK10gPSBhdG9taWM2NF9yZWFkKCZsZWFkZXItPmNvdW50KTsKCWlmIChyZWFkX2Zvcm1hdCAmIFBFUkZfRk9STUFUX0lEKQoJCXZhbHVlc1tuKytdID0gcHJpbWFyeV9ldmVudF9pZChsZWFkZXIpOwoKCXBlcmZfb3V0cHV0X2NvcHkoaGFuZGxlLCB2YWx1ZXMsIG4gKiBzaXplb2YodTY0KSk7CgoJbGlzdF9mb3JfZWFjaF9lbnRyeShzdWIsICZsZWFkZXItPnNpYmxpbmdfbGlzdCwgZ3JvdXBfZW50cnkpIHsKCQluID0gMDsKCgkJaWYgKHN1YiAhPSBldmVudCkKCQkJc3ViLT5wbXUtPnJlYWQoc3ViKTsKCgkJdmFsdWVzW24rK10gPSBhdG9taWM2NF9yZWFkKCZzdWItPmNvdW50KTsKCQlpZiAocmVhZF9mb3JtYXQgJiBQRVJGX0ZPUk1BVF9JRCkKCQkJdmFsdWVzW24rK10gPSBwcmltYXJ5X2V2ZW50X2lkKHN1Yik7CgoJCXBlcmZfb3V0cHV0X2NvcHkoaGFuZGxlLCB2YWx1ZXMsIG4gKiBzaXplb2YodTY0KSk7Cgl9Cn0KCnN0YXRpYyB2b2lkIHBlcmZfb3V0cHV0X3JlYWQoc3RydWN0IHBlcmZfb3V0cHV0X2hhbmRsZSAqaGFuZGxlLAoJCQkgICAgIHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCkKewoJaWYgKGV2ZW50LT5hdHRyLnJlYWRfZm9ybWF0ICYgUEVSRl9GT1JNQVRfR1JPVVApCgkJcGVyZl9vdXRwdXRfcmVhZF9ncm91cChoYW5kbGUsIGV2ZW50KTsKCWVsc2UKCQlwZXJmX291dHB1dF9yZWFkX29uZShoYW5kbGUsIGV2ZW50KTsKfQoKdm9pZCBwZXJmX291dHB1dF9zYW1wbGUoc3RydWN0IHBlcmZfb3V0cHV0X2hhbmRsZSAqaGFuZGxlLAoJCQlzdHJ1Y3QgcGVyZl9ldmVudF9oZWFkZXIgKmhlYWRlciwKCQkJc3RydWN0IHBlcmZfc2FtcGxlX2RhdGEgKmRhdGEsCgkJCXN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCkKewoJdTY0IHNhbXBsZV90eXBlID0gZGF0YS0+dHlwZTsKCglwZXJmX291dHB1dF9wdXQoaGFuZGxlLCAqaGVhZGVyKTsKCglpZiAoc2FtcGxlX3R5cGUgJiBQRVJGX1NBTVBMRV9JUCkKCQlwZXJmX291dHB1dF9wdXQoaGFuZGxlLCBkYXRhLT5pcCk7CgoJaWYgKHNhbXBsZV90eXBlICYgUEVSRl9TQU1QTEVfVElEKQoJCXBlcmZfb3V0cHV0X3B1dChoYW5kbGUsIGRhdGEtPnRpZF9lbnRyeSk7CgoJaWYgKHNhbXBsZV90eXBlICYgUEVSRl9TQU1QTEVfVElNRSkKCQlwZXJmX291dHB1dF9wdXQoaGFuZGxlLCBkYXRhLT50aW1lKTsKCglpZiAoc2FtcGxlX3R5cGUgJiBQRVJGX1NBTVBMRV9BRERSKQoJCXBlcmZfb3V0cHV0X3B1dChoYW5kbGUsIGRhdGEtPmFkZHIpOwoKCWlmIChzYW1wbGVfdHlwZSAmIFBFUkZfU0FNUExFX0lEKQoJCXBlcmZfb3V0cHV0X3B1dChoYW5kbGUsIGRhdGEtPmlkKTsKCglpZiAoc2FtcGxlX3R5cGUgJiBQRVJGX1NBTVBMRV9TVFJFQU1fSUQpCgkJcGVyZl9vdXRwdXRfcHV0KGhhbmRsZSwgZGF0YS0+c3RyZWFtX2lkKTsKCglpZiAoc2FtcGxlX3R5cGUgJiBQRVJGX1NBTVBMRV9DUFUpCgkJcGVyZl9vdXRwdXRfcHV0KGhhbmRsZSwgZGF0YS0+Y3B1X2VudHJ5KTsKCglpZiAoc2FtcGxlX3R5cGUgJiBQRVJGX1NBTVBMRV9QRVJJT0QpCgkJcGVyZl9vdXRwdXRfcHV0KGhhbmRsZSwgZGF0YS0+cGVyaW9kKTsKCglpZiAoc2FtcGxlX3R5cGUgJiBQRVJGX1NBTVBMRV9SRUFEKQoJCXBlcmZfb3V0cHV0X3JlYWQoaGFuZGxlLCBldmVudCk7CgoJaWYgKHNhbXBsZV90eXBlICYgUEVSRl9TQU1QTEVfQ0FMTENIQUlOKSB7CgkJaWYgKGRhdGEtPmNhbGxjaGFpbikgewoJCQlpbnQgc2l6ZSA9IDE7CgoJCQlpZiAoZGF0YS0+Y2FsbGNoYWluKQoJCQkJc2l6ZSArPSBkYXRhLT5jYWxsY2hhaW4tPm5yOwoKCQkJc2l6ZSAqPSBzaXplb2YodTY0KTsKCgkJCXBlcmZfb3V0cHV0X2NvcHkoaGFuZGxlLCBkYXRhLT5jYWxsY2hhaW4sIHNpemUpOwoJCX0gZWxzZSB7CgkJCXU2NCBuciA9IDA7CgkJCXBlcmZfb3V0cHV0X3B1dChoYW5kbGUsIG5yKTsKCQl9Cgl9CgoJaWYgKHNhbXBsZV90eXBlICYgUEVSRl9TQU1QTEVfUkFXKSB7CgkJaWYgKGRhdGEtPnJhdykgewoJCQlwZXJmX291dHB1dF9wdXQoaGFuZGxlLCBkYXRhLT5yYXctPnNpemUpOwoJCQlwZXJmX291dHB1dF9jb3B5KGhhbmRsZSwgZGF0YS0+cmF3LT5kYXRhLAoJCQkJCSBkYXRhLT5yYXctPnNpemUpOwoJCX0gZWxzZSB7CgkJCXN0cnVjdCB7CgkJCQl1MzIJc2l6ZTsKCQkJCXUzMglkYXRhOwoJCQl9IHJhdyA9IHsKCQkJCS5zaXplID0gc2l6ZW9mKHUzMiksCgkJCQkuZGF0YSA9IDAsCgkJCX07CgkJCXBlcmZfb3V0cHV0X3B1dChoYW5kbGUsIHJhdyk7CgkJfQoJfQp9Cgp2b2lkIHBlcmZfcHJlcGFyZV9zYW1wbGUoc3RydWN0IHBlcmZfZXZlbnRfaGVhZGVyICpoZWFkZXIsCgkJCSBzdHJ1Y3QgcGVyZl9zYW1wbGVfZGF0YSAqZGF0YSwKCQkJIHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCwKCQkJIHN0cnVjdCBwdF9yZWdzICpyZWdzKQp7Cgl1NjQgc2FtcGxlX3R5cGUgPSBldmVudC0+YXR0ci5zYW1wbGVfdHlwZTsKCglkYXRhLT50eXBlID0gc2FtcGxlX3R5cGU7CgoJaGVhZGVyLT50eXBlID0gUEVSRl9SRUNPUkRfU0FNUExFOwoJaGVhZGVyLT5zaXplID0gc2l6ZW9mKCpoZWFkZXIpOwoKCWhlYWRlci0+bWlzYyA9IDA7CgloZWFkZXItPm1pc2MgfD0gcGVyZl9taXNjX2ZsYWdzKHJlZ3MpOwoKCWlmIChzYW1wbGVfdHlwZSAmIFBFUkZfU0FNUExFX0lQKSB7CgkJZGF0YS0+aXAgPSBwZXJmX2luc3RydWN0aW9uX3BvaW50ZXIocmVncyk7CgoJCWhlYWRlci0+c2l6ZSArPSBzaXplb2YoZGF0YS0+aXApOwoJfQoKCWlmIChzYW1wbGVfdHlwZSAmIFBFUkZfU0FNUExFX1RJRCkgewoJCS8qIG5hbWVzcGFjZSBpc3N1ZXMgKi8KCQlkYXRhLT50aWRfZW50cnkucGlkID0gcGVyZl9ldmVudF9waWQoZXZlbnQsIGN1cnJlbnQpOwoJCWRhdGEtPnRpZF9lbnRyeS50aWQgPSBwZXJmX2V2ZW50X3RpZChldmVudCwgY3VycmVudCk7CgoJCWhlYWRlci0+c2l6ZSArPSBzaXplb2YoZGF0YS0+dGlkX2VudHJ5KTsKCX0KCglpZiAoc2FtcGxlX3R5cGUgJiBQRVJGX1NBTVBMRV9USU1FKSB7CgkJZGF0YS0+dGltZSA9IHBlcmZfY2xvY2soKTsKCgkJaGVhZGVyLT5zaXplICs9IHNpemVvZihkYXRhLT50aW1lKTsKCX0KCglpZiAoc2FtcGxlX3R5cGUgJiBQRVJGX1NBTVBMRV9BRERSKQoJCWhlYWRlci0+c2l6ZSArPSBzaXplb2YoZGF0YS0+YWRkcik7CgoJaWYgKHNhbXBsZV90eXBlICYgUEVSRl9TQU1QTEVfSUQpIHsKCQlkYXRhLT5pZCA9IHByaW1hcnlfZXZlbnRfaWQoZXZlbnQpOwoKCQloZWFkZXItPnNpemUgKz0gc2l6ZW9mKGRhdGEtPmlkKTsKCX0KCglpZiAoc2FtcGxlX3R5cGUgJiBQRVJGX1NBTVBMRV9TVFJFQU1fSUQpIHsKCQlkYXRhLT5zdHJlYW1faWQgPSBldmVudC0+aWQ7CgoJCWhlYWRlci0+c2l6ZSArPSBzaXplb2YoZGF0YS0+c3RyZWFtX2lkKTsKCX0KCglpZiAoc2FtcGxlX3R5cGUgJiBQRVJGX1NBTVBMRV9DUFUpIHsKCQlkYXRhLT5jcHVfZW50cnkuY3B1CQk9IHJhd19zbXBfcHJvY2Vzc29yX2lkKCk7CgkJZGF0YS0+Y3B1X2VudHJ5LnJlc2VydmVkCT0gMDsKCgkJaGVhZGVyLT5zaXplICs9IHNpemVvZihkYXRhLT5jcHVfZW50cnkpOwoJfQoKCWlmIChzYW1wbGVfdHlwZSAmIFBFUkZfU0FNUExFX1BFUklPRCkKCQloZWFkZXItPnNpemUgKz0gc2l6ZW9mKGRhdGEtPnBlcmlvZCk7CgoJaWYgKHNhbXBsZV90eXBlICYgUEVSRl9TQU1QTEVfUkVBRCkKCQloZWFkZXItPnNpemUgKz0gcGVyZl9ldmVudF9yZWFkX3NpemUoZXZlbnQpOwoKCWlmIChzYW1wbGVfdHlwZSAmIFBFUkZfU0FNUExFX0NBTExDSEFJTikgewoJCWludCBzaXplID0gMTsKCgkJZGF0YS0+Y2FsbGNoYWluID0gcGVyZl9jYWxsY2hhaW4ocmVncyk7CgoJCWlmIChkYXRhLT5jYWxsY2hhaW4pCgkJCXNpemUgKz0gZGF0YS0+Y2FsbGNoYWluLT5ucjsKCgkJaGVhZGVyLT5zaXplICs9IHNpemUgKiBzaXplb2YodTY0KTsKCX0KCglpZiAoc2FtcGxlX3R5cGUgJiBQRVJGX1NBTVBMRV9SQVcpIHsKCQlpbnQgc2l6ZSA9IHNpemVvZih1MzIpOwoKCQlpZiAoZGF0YS0+cmF3KQoJCQlzaXplICs9IGRhdGEtPnJhdy0+c2l6ZTsKCQllbHNlCgkJCXNpemUgKz0gc2l6ZW9mKHUzMik7CgoJCVdBUk5fT05fT05DRShzaXplICYgKHNpemVvZih1NjQpLTEpKTsKCQloZWFkZXItPnNpemUgKz0gc2l6ZTsKCX0KfQoKc3RhdGljIHZvaWQgcGVyZl9ldmVudF9vdXRwdXQoc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50LCBpbnQgbm1pLAoJCQkJc3RydWN0IHBlcmZfc2FtcGxlX2RhdGEgKmRhdGEsCgkJCQlzdHJ1Y3QgcHRfcmVncyAqcmVncykKewoJc3RydWN0IHBlcmZfb3V0cHV0X2hhbmRsZSBoYW5kbGU7CglzdHJ1Y3QgcGVyZl9ldmVudF9oZWFkZXIgaGVhZGVyOwoKCXBlcmZfcHJlcGFyZV9zYW1wbGUoJmhlYWRlciwgZGF0YSwgZXZlbnQsIHJlZ3MpOwoKCWlmIChwZXJmX291dHB1dF9iZWdpbigmaGFuZGxlLCBldmVudCwgaGVhZGVyLnNpemUsIG5taSwgMSkpCgkJcmV0dXJuOwoKCXBlcmZfb3V0cHV0X3NhbXBsZSgmaGFuZGxlLCAmaGVhZGVyLCBkYXRhLCBldmVudCk7CgoJcGVyZl9vdXRwdXRfZW5kKCZoYW5kbGUpOwp9CgovKgogKiByZWFkIGV2ZW50X2lkCiAqLwoKc3RydWN0IHBlcmZfcmVhZF9ldmVudCB7CglzdHJ1Y3QgcGVyZl9ldmVudF9oZWFkZXIJaGVhZGVyOwoKCXUzMgkJCQlwaWQ7Cgl1MzIJCQkJdGlkOwp9OwoKc3RhdGljIHZvaWQKcGVyZl9ldmVudF9yZWFkX2V2ZW50KHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCwKCQkJc3RydWN0IHRhc2tfc3RydWN0ICp0YXNrKQp7CglzdHJ1Y3QgcGVyZl9vdXRwdXRfaGFuZGxlIGhhbmRsZTsKCXN0cnVjdCBwZXJmX3JlYWRfZXZlbnQgcmVhZF9ldmVudCA9IHsKCQkuaGVhZGVyID0gewoJCQkudHlwZSA9IFBFUkZfUkVDT1JEX1JFQUQsCgkJCS5taXNjID0gMCwKCQkJLnNpemUgPSBzaXplb2YocmVhZF9ldmVudCkgKyBwZXJmX2V2ZW50X3JlYWRfc2l6ZShldmVudCksCgkJfSwKCQkucGlkID0gcGVyZl9ldmVudF9waWQoZXZlbnQsIHRhc2spLAoJCS50aWQgPSBwZXJmX2V2ZW50X3RpZChldmVudCwgdGFzayksCgl9OwoJaW50IHJldDsKCglyZXQgPSBwZXJmX291dHB1dF9iZWdpbigmaGFuZGxlLCBldmVudCwgcmVhZF9ldmVudC5oZWFkZXIuc2l6ZSwgMCwgMCk7CglpZiAocmV0KQoJCXJldHVybjsKCglwZXJmX291dHB1dF9wdXQoJmhhbmRsZSwgcmVhZF9ldmVudCk7CglwZXJmX291dHB1dF9yZWFkKCZoYW5kbGUsIGV2ZW50KTsKCglwZXJmX291dHB1dF9lbmQoJmhhbmRsZSk7Cn0KCi8qCiAqIHRhc2sgdHJhY2tpbmcgLS0gZm9yay9leGl0CiAqCiAqIGVuYWJsZWQgYnk6IGF0dHIuY29tbSB8IGF0dHIubW1hcCB8IGF0dHIudGFzawogKi8KCnN0cnVjdCBwZXJmX3Rhc2tfZXZlbnQgewoJc3RydWN0IHRhc2tfc3RydWN0CQkqdGFzazsKCXN0cnVjdCBwZXJmX2V2ZW50X2NvbnRleHQJKnRhc2tfY3R4OwoKCXN0cnVjdCB7CgkJc3RydWN0IHBlcmZfZXZlbnRfaGVhZGVyCWhlYWRlcjsKCgkJdTMyCQkJCXBpZDsKCQl1MzIJCQkJcHBpZDsKCQl1MzIJCQkJdGlkOwoJCXUzMgkJCQlwdGlkOwoJCXU2NAkJCQl0aW1lOwoJfSBldmVudF9pZDsKfTsKCnN0YXRpYyB2b2lkIHBlcmZfZXZlbnRfdGFza19vdXRwdXQoc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50LAoJCQkJICAgICBzdHJ1Y3QgcGVyZl90YXNrX2V2ZW50ICp0YXNrX2V2ZW50KQp7CglzdHJ1Y3QgcGVyZl9vdXRwdXRfaGFuZGxlIGhhbmRsZTsKCWludCBzaXplOwoJc3RydWN0IHRhc2tfc3RydWN0ICp0YXNrID0gdGFza19ldmVudC0+dGFzazsKCWludCByZXQ7CgoJc2l6ZSAgPSB0YXNrX2V2ZW50LT5ldmVudF9pZC5oZWFkZXIuc2l6ZTsKCXJldCA9IHBlcmZfb3V0cHV0X2JlZ2luKCZoYW5kbGUsIGV2ZW50LCBzaXplLCAwLCAwKTsKCglpZiAocmV0KQoJCXJldHVybjsKCgl0YXNrX2V2ZW50LT5ldmVudF9pZC5waWQgPSBwZXJmX2V2ZW50X3BpZChldmVudCwgdGFzayk7Cgl0YXNrX2V2ZW50LT5ldmVudF9pZC5wcGlkID0gcGVyZl9ldmVudF9waWQoZXZlbnQsIGN1cnJlbnQpOwoKCXRhc2tfZXZlbnQtPmV2ZW50X2lkLnRpZCA9IHBlcmZfZXZlbnRfdGlkKGV2ZW50LCB0YXNrKTsKCXRhc2tfZXZlbnQtPmV2ZW50X2lkLnB0aWQgPSBwZXJmX2V2ZW50X3RpZChldmVudCwgY3VycmVudCk7CgoJdGFza19ldmVudC0+ZXZlbnRfaWQudGltZSA9IHBlcmZfY2xvY2soKTsKCglwZXJmX291dHB1dF9wdXQoJmhhbmRsZSwgdGFza19ldmVudC0+ZXZlbnRfaWQpOwoKCXBlcmZfb3V0cHV0X2VuZCgmaGFuZGxlKTsKfQoKc3RhdGljIGludCBwZXJmX2V2ZW50X3Rhc2tfbWF0Y2goc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50KQp7CglpZiAoZXZlbnQtPmF0dHIuY29tbSB8fCBldmVudC0+YXR0ci5tbWFwIHx8IGV2ZW50LT5hdHRyLnRhc2spCgkJcmV0dXJuIDE7CgoJcmV0dXJuIDA7Cn0KCnN0YXRpYyB2b2lkIHBlcmZfZXZlbnRfdGFza19jdHgoc3RydWN0IHBlcmZfZXZlbnRfY29udGV4dCAqY3R4LAoJCQkJICBzdHJ1Y3QgcGVyZl90YXNrX2V2ZW50ICp0YXNrX2V2ZW50KQp7CglzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQ7CgoJaWYgKHN5c3RlbV9zdGF0ZSAhPSBTWVNURU1fUlVOTklORyB8fCBsaXN0X2VtcHR5KCZjdHgtPmV2ZW50X2xpc3QpKQoJCXJldHVybjsKCglyY3VfcmVhZF9sb2NrKCk7CglsaXN0X2Zvcl9lYWNoX2VudHJ5X3JjdShldmVudCwgJmN0eC0+ZXZlbnRfbGlzdCwgZXZlbnRfZW50cnkpIHsKCQlpZiAocGVyZl9ldmVudF90YXNrX21hdGNoKGV2ZW50KSkKCQkJcGVyZl9ldmVudF90YXNrX291dHB1dChldmVudCwgdGFza19ldmVudCk7Cgl9CglyY3VfcmVhZF91bmxvY2soKTsKfQoKc3RhdGljIHZvaWQgcGVyZl9ldmVudF90YXNrX2V2ZW50KHN0cnVjdCBwZXJmX3Rhc2tfZXZlbnQgKnRhc2tfZXZlbnQpCnsKCXN0cnVjdCBwZXJmX2NwdV9jb250ZXh0ICpjcHVjdHg7CglzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0ICpjdHggPSB0YXNrX2V2ZW50LT50YXNrX2N0eDsKCgljcHVjdHggPSAmZ2V0X2NwdV92YXIocGVyZl9jcHVfY29udGV4dCk7CglwZXJmX2V2ZW50X3Rhc2tfY3R4KCZjcHVjdHgtPmN0eCwgdGFza19ldmVudCk7CglwdXRfY3B1X3ZhcihwZXJmX2NwdV9jb250ZXh0KTsKCglyY3VfcmVhZF9sb2NrKCk7CglpZiAoIWN0eCkKCQljdHggPSByY3VfZGVyZWZlcmVuY2UodGFza19ldmVudC0+dGFzay0+cGVyZl9ldmVudF9jdHhwKTsKCWlmIChjdHgpCgkJcGVyZl9ldmVudF90YXNrX2N0eChjdHgsIHRhc2tfZXZlbnQpOwoJcmN1X3JlYWRfdW5sb2NrKCk7Cn0KCnN0YXRpYyB2b2lkIHBlcmZfZXZlbnRfdGFzayhzdHJ1Y3QgdGFza19zdHJ1Y3QgKnRhc2ssCgkJCSAgICAgIHN0cnVjdCBwZXJmX2V2ZW50X2NvbnRleHQgKnRhc2tfY3R4LAoJCQkgICAgICBpbnQgbmV3KQp7CglzdHJ1Y3QgcGVyZl90YXNrX2V2ZW50IHRhc2tfZXZlbnQ7CgoJaWYgKCFhdG9taWNfcmVhZCgmbnJfY29tbV9ldmVudHMpICYmCgkgICAgIWF0b21pY19yZWFkKCZucl9tbWFwX2V2ZW50cykgJiYKCSAgICAhYXRvbWljX3JlYWQoJm5yX3Rhc2tfZXZlbnRzKSkKCQlyZXR1cm47CgoJdGFza19ldmVudCA9IChzdHJ1Y3QgcGVyZl90YXNrX2V2ZW50KXsKCQkudGFzawkgID0gdGFzaywKCQkudGFza19jdHggPSB0YXNrX2N0eCwKCQkuZXZlbnRfaWQgICAgPSB7CgkJCS5oZWFkZXIgPSB7CgkJCQkudHlwZSA9IG5ldyA/IFBFUkZfUkVDT1JEX0ZPUksgOiBQRVJGX1JFQ09SRF9FWElULAoJCQkJLm1pc2MgPSAwLAoJCQkJLnNpemUgPSBzaXplb2YodGFza19ldmVudC5ldmVudF9pZCksCgkJCX0sCgkJCS8qIC5waWQgICovCgkJCS8qIC5wcGlkICovCgkJCS8qIC50aWQgICovCgkJCS8qIC5wdGlkICovCgkJfSwKCX07CgoJcGVyZl9ldmVudF90YXNrX2V2ZW50KCZ0YXNrX2V2ZW50KTsKfQoKdm9pZCBwZXJmX2V2ZW50X2Zvcmsoc3RydWN0IHRhc2tfc3RydWN0ICp0YXNrKQp7CglwZXJmX2V2ZW50X3Rhc2sodGFzaywgTlVMTCwgMSk7Cn0KCi8qCiAqIGNvbW0gdHJhY2tpbmcKICovCgpzdHJ1Y3QgcGVyZl9jb21tX2V2ZW50IHsKCXN0cnVjdCB0YXNrX3N0cnVjdAkqdGFzazsKCWNoYXIJCQkqY29tbTsKCWludAkJCWNvbW1fc2l6ZTsKCglzdHJ1Y3QgewoJCXN0cnVjdCBwZXJmX2V2ZW50X2hlYWRlcgloZWFkZXI7CgoJCXUzMgkJCQlwaWQ7CgkJdTMyCQkJCXRpZDsKCX0gZXZlbnRfaWQ7Cn07CgpzdGF0aWMgdm9pZCBwZXJmX2V2ZW50X2NvbW1fb3V0cHV0KHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCwKCQkJCSAgICAgc3RydWN0IHBlcmZfY29tbV9ldmVudCAqY29tbV9ldmVudCkKewoJc3RydWN0IHBlcmZfb3V0cHV0X2hhbmRsZSBoYW5kbGU7CglpbnQgc2l6ZSA9IGNvbW1fZXZlbnQtPmV2ZW50X2lkLmhlYWRlci5zaXplOwoJaW50IHJldCA9IHBlcmZfb3V0cHV0X2JlZ2luKCZoYW5kbGUsIGV2ZW50LCBzaXplLCAwLCAwKTsKCglpZiAocmV0KQoJCXJldHVybjsKCgljb21tX2V2ZW50LT5ldmVudF9pZC5waWQgPSBwZXJmX2V2ZW50X3BpZChldmVudCwgY29tbV9ldmVudC0+dGFzayk7Cgljb21tX2V2ZW50LT5ldmVudF9pZC50aWQgPSBwZXJmX2V2ZW50X3RpZChldmVudCwgY29tbV9ldmVudC0+dGFzayk7CgoJcGVyZl9vdXRwdXRfcHV0KCZoYW5kbGUsIGNvbW1fZXZlbnQtPmV2ZW50X2lkKTsKCXBlcmZfb3V0cHV0X2NvcHkoJmhhbmRsZSwgY29tbV9ldmVudC0+Y29tbSwKCQkJCSAgIGNvbW1fZXZlbnQtPmNvbW1fc2l6ZSk7CglwZXJmX291dHB1dF9lbmQoJmhhbmRsZSk7Cn0KCnN0YXRpYyBpbnQgcGVyZl9ldmVudF9jb21tX21hdGNoKHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCkKewoJaWYgKGV2ZW50LT5hdHRyLmNvbW0pCgkJcmV0dXJuIDE7CgoJcmV0dXJuIDA7Cn0KCnN0YXRpYyB2b2lkIHBlcmZfZXZlbnRfY29tbV9jdHgoc3RydWN0IHBlcmZfZXZlbnRfY29udGV4dCAqY3R4LAoJCQkJICBzdHJ1Y3QgcGVyZl9jb21tX2V2ZW50ICpjb21tX2V2ZW50KQp7CglzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQ7CgoJaWYgKHN5c3RlbV9zdGF0ZSAhPSBTWVNURU1fUlVOTklORyB8fCBsaXN0X2VtcHR5KCZjdHgtPmV2ZW50X2xpc3QpKQoJCXJldHVybjsKCglyY3VfcmVhZF9sb2NrKCk7CglsaXN0X2Zvcl9lYWNoX2VudHJ5X3JjdShldmVudCwgJmN0eC0+ZXZlbnRfbGlzdCwgZXZlbnRfZW50cnkpIHsKCQlpZiAocGVyZl9ldmVudF9jb21tX21hdGNoKGV2ZW50KSkKCQkJcGVyZl9ldmVudF9jb21tX291dHB1dChldmVudCwgY29tbV9ldmVudCk7Cgl9CglyY3VfcmVhZF91bmxvY2soKTsKfQoKc3RhdGljIHZvaWQgcGVyZl9ldmVudF9jb21tX2V2ZW50KHN0cnVjdCBwZXJmX2NvbW1fZXZlbnQgKmNvbW1fZXZlbnQpCnsKCXN0cnVjdCBwZXJmX2NwdV9jb250ZXh0ICpjcHVjdHg7CglzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0ICpjdHg7Cgl1bnNpZ25lZCBpbnQgc2l6ZTsKCWNoYXIgY29tbVtUQVNLX0NPTU1fTEVOXTsKCgltZW1zZXQoY29tbSwgMCwgc2l6ZW9mKGNvbW0pKTsKCXN0cm5jcHkoY29tbSwgY29tbV9ldmVudC0+dGFzay0+Y29tbSwgc2l6ZW9mKGNvbW0pKTsKCXNpemUgPSBBTElHTihzdHJsZW4oY29tbSkrMSwgc2l6ZW9mKHU2NCkpOwoKCWNvbW1fZXZlbnQtPmNvbW0gPSBjb21tOwoJY29tbV9ldmVudC0+Y29tbV9zaXplID0gc2l6ZTsKCgljb21tX2V2ZW50LT5ldmVudF9pZC5oZWFkZXIuc2l6ZSA9IHNpemVvZihjb21tX2V2ZW50LT5ldmVudF9pZCkgKyBzaXplOwoKCWNwdWN0eCA9ICZnZXRfY3B1X3ZhcihwZXJmX2NwdV9jb250ZXh0KTsKCXBlcmZfZXZlbnRfY29tbV9jdHgoJmNwdWN0eC0+Y3R4LCBjb21tX2V2ZW50KTsKCXB1dF9jcHVfdmFyKHBlcmZfY3B1X2NvbnRleHQpOwoKCXJjdV9yZWFkX2xvY2soKTsKCS8qCgkgKiBkb2Vzbid0IHJlYWxseSBtYXR0ZXIgd2hpY2ggb2YgdGhlIGNoaWxkIGNvbnRleHRzIHRoZQoJICogZXZlbnRzIGVuZHMgdXAgaW4uCgkgKi8KCWN0eCA9IHJjdV9kZXJlZmVyZW5jZShjdXJyZW50LT5wZXJmX2V2ZW50X2N0eHApOwoJaWYgKGN0eCkKCQlwZXJmX2V2ZW50X2NvbW1fY3R4KGN0eCwgY29tbV9ldmVudCk7CglyY3VfcmVhZF91bmxvY2soKTsKfQoKdm9pZCBwZXJmX2V2ZW50X2NvbW0oc3RydWN0IHRhc2tfc3RydWN0ICp0YXNrKQp7CglzdHJ1Y3QgcGVyZl9jb21tX2V2ZW50IGNvbW1fZXZlbnQ7CgoJaWYgKHRhc2stPnBlcmZfZXZlbnRfY3R4cCkKCQlwZXJmX2V2ZW50X2VuYWJsZV9vbl9leGVjKHRhc2spOwoKCWlmICghYXRvbWljX3JlYWQoJm5yX2NvbW1fZXZlbnRzKSkKCQlyZXR1cm47CgoJY29tbV9ldmVudCA9IChzdHJ1Y3QgcGVyZl9jb21tX2V2ZW50KXsKCQkudGFzawk9IHRhc2ssCgkJLyogLmNvbW0gICAgICAqLwoJCS8qIC5jb21tX3NpemUgKi8KCQkuZXZlbnRfaWQgID0gewoJCQkuaGVhZGVyID0gewoJCQkJLnR5cGUgPSBQRVJGX1JFQ09SRF9DT01NLAoJCQkJLm1pc2MgPSAwLAoJCQkJLyogLnNpemUgKi8KCQkJfSwKCQkJLyogLnBpZCAqLwoJCQkvKiAudGlkICovCgkJfSwKCX07CgoJcGVyZl9ldmVudF9jb21tX2V2ZW50KCZjb21tX2V2ZW50KTsKfQoKLyoKICogbW1hcCB0cmFja2luZwogKi8KCnN0cnVjdCBwZXJmX21tYXBfZXZlbnQgewoJc3RydWN0IHZtX2FyZWFfc3RydWN0CSp2bWE7CgoJY29uc3QgY2hhcgkJKmZpbGVfbmFtZTsKCWludAkJCWZpbGVfc2l6ZTsKCglzdHJ1Y3QgewoJCXN0cnVjdCBwZXJmX2V2ZW50X2hlYWRlcgloZWFkZXI7CgoJCXUzMgkJCQlwaWQ7CgkJdTMyCQkJCXRpZDsKCQl1NjQJCQkJc3RhcnQ7CgkJdTY0CQkJCWxlbjsKCQl1NjQJCQkJcGdvZmY7Cgl9IGV2ZW50X2lkOwp9OwoKc3RhdGljIHZvaWQgcGVyZl9ldmVudF9tbWFwX291dHB1dChzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQsCgkJCQkgICAgIHN0cnVjdCBwZXJmX21tYXBfZXZlbnQgKm1tYXBfZXZlbnQpCnsKCXN0cnVjdCBwZXJmX291dHB1dF9oYW5kbGUgaGFuZGxlOwoJaW50IHNpemUgPSBtbWFwX2V2ZW50LT5ldmVudF9pZC5oZWFkZXIuc2l6ZTsKCWludCByZXQgPSBwZXJmX291dHB1dF9iZWdpbigmaGFuZGxlLCBldmVudCwgc2l6ZSwgMCwgMCk7CgoJaWYgKHJldCkKCQlyZXR1cm47CgoJbW1hcF9ldmVudC0+ZXZlbnRfaWQucGlkID0gcGVyZl9ldmVudF9waWQoZXZlbnQsIGN1cnJlbnQpOwoJbW1hcF9ldmVudC0+ZXZlbnRfaWQudGlkID0gcGVyZl9ldmVudF90aWQoZXZlbnQsIGN1cnJlbnQpOwoKCXBlcmZfb3V0cHV0X3B1dCgmaGFuZGxlLCBtbWFwX2V2ZW50LT5ldmVudF9pZCk7CglwZXJmX291dHB1dF9jb3B5KCZoYW5kbGUsIG1tYXBfZXZlbnQtPmZpbGVfbmFtZSwKCQkJCSAgIG1tYXBfZXZlbnQtPmZpbGVfc2l6ZSk7CglwZXJmX291dHB1dF9lbmQoJmhhbmRsZSk7Cn0KCnN0YXRpYyBpbnQgcGVyZl9ldmVudF9tbWFwX21hdGNoKHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCwKCQkJCSAgIHN0cnVjdCBwZXJmX21tYXBfZXZlbnQgKm1tYXBfZXZlbnQpCnsKCWlmIChldmVudC0+YXR0ci5tbWFwKQoJCXJldHVybiAxOwoKCXJldHVybiAwOwp9CgpzdGF0aWMgdm9pZCBwZXJmX2V2ZW50X21tYXBfY3R4KHN0cnVjdCBwZXJmX2V2ZW50X2NvbnRleHQgKmN0eCwKCQkJCSAgc3RydWN0IHBlcmZfbW1hcF9ldmVudCAqbW1hcF9ldmVudCkKewoJc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50OwoKCWlmIChzeXN0ZW1fc3RhdGUgIT0gU1lTVEVNX1JVTk5JTkcgfHwgbGlzdF9lbXB0eSgmY3R4LT5ldmVudF9saXN0KSkKCQlyZXR1cm47CgoJcmN1X3JlYWRfbG9jaygpOwoJbGlzdF9mb3JfZWFjaF9lbnRyeV9yY3UoZXZlbnQsICZjdHgtPmV2ZW50X2xpc3QsIGV2ZW50X2VudHJ5KSB7CgkJaWYgKHBlcmZfZXZlbnRfbW1hcF9tYXRjaChldmVudCwgbW1hcF9ldmVudCkpCgkJCXBlcmZfZXZlbnRfbW1hcF9vdXRwdXQoZXZlbnQsIG1tYXBfZXZlbnQpOwoJfQoJcmN1X3JlYWRfdW5sb2NrKCk7Cn0KCnN0YXRpYyB2b2lkIHBlcmZfZXZlbnRfbW1hcF9ldmVudChzdHJ1Y3QgcGVyZl9tbWFwX2V2ZW50ICptbWFwX2V2ZW50KQp7CglzdHJ1Y3QgcGVyZl9jcHVfY29udGV4dCAqY3B1Y3R4OwoJc3RydWN0IHBlcmZfZXZlbnRfY29udGV4dCAqY3R4OwoJc3RydWN0IHZtX2FyZWFfc3RydWN0ICp2bWEgPSBtbWFwX2V2ZW50LT52bWE7CglzdHJ1Y3QgZmlsZSAqZmlsZSA9IHZtYS0+dm1fZmlsZTsKCXVuc2lnbmVkIGludCBzaXplOwoJY2hhciB0bXBbMTZdOwoJY2hhciAqYnVmID0gTlVMTDsKCWNvbnN0IGNoYXIgKm5hbWU7CgoJbWVtc2V0KHRtcCwgMCwgc2l6ZW9mKHRtcCkpOwoKCWlmIChmaWxlKSB7CgkJLyoKCQkgKiBkX3BhdGggd29ya3MgZnJvbSB0aGUgZW5kIG9mIHRoZSBidWZmZXIgYmFja3dhcmRzLCBzbyB3ZQoJCSAqIG5lZWQgdG8gYWRkIGVub3VnaCB6ZXJvIGJ5dGVzIGFmdGVyIHRoZSBzdHJpbmcgdG8gaGFuZGxlCgkJICogdGhlIDY0Yml0IGFsaWdubWVudCB3ZSBkbyBsYXRlci4KCQkgKi8KCQlidWYgPSBremFsbG9jKFBBVEhfTUFYICsgc2l6ZW9mKHU2NCksIEdGUF9LRVJORUwpOwoJCWlmICghYnVmKSB7CgkJCW5hbWUgPSBzdHJuY3B5KHRtcCwgIi8vZW5vbWVtIiwgc2l6ZW9mKHRtcCkpOwoJCQlnb3RvIGdvdF9uYW1lOwoJCX0KCQluYW1lID0gZF9wYXRoKCZmaWxlLT5mX3BhdGgsIGJ1ZiwgUEFUSF9NQVgpOwoJCWlmIChJU19FUlIobmFtZSkpIHsKCQkJbmFtZSA9IHN0cm5jcHkodG1wLCAiLy90b29sb25nIiwgc2l6ZW9mKHRtcCkpOwoJCQlnb3RvIGdvdF9uYW1lOwoJCX0KCX0gZWxzZSB7CgkJaWYgKGFyY2hfdm1hX25hbWUobW1hcF9ldmVudC0+dm1hKSkgewoJCQluYW1lID0gc3RybmNweSh0bXAsIGFyY2hfdm1hX25hbWUobW1hcF9ldmVudC0+dm1hKSwKCQkJCSAgICAgICBzaXplb2YodG1wKSk7CgkJCWdvdG8gZ290X25hbWU7CgkJfQoKCQlpZiAoIXZtYS0+dm1fbW0pIHsKCQkJbmFtZSA9IHN0cm5jcHkodG1wLCAiW3Zkc29dIiwgc2l6ZW9mKHRtcCkpOwoJCQlnb3RvIGdvdF9uYW1lOwoJCX0KCgkJbmFtZSA9IHN0cm5jcHkodG1wLCAiLy9hbm9uIiwgc2l6ZW9mKHRtcCkpOwoJCWdvdG8gZ290X25hbWU7Cgl9Cgpnb3RfbmFtZToKCXNpemUgPSBBTElHTihzdHJsZW4obmFtZSkrMSwgc2l6ZW9mKHU2NCkpOwoKCW1tYXBfZXZlbnQtPmZpbGVfbmFtZSA9IG5hbWU7CgltbWFwX2V2ZW50LT5maWxlX3NpemUgPSBzaXplOwoKCW1tYXBfZXZlbnQtPmV2ZW50X2lkLmhlYWRlci5zaXplID0gc2l6ZW9mKG1tYXBfZXZlbnQtPmV2ZW50X2lkKSArIHNpemU7CgoJY3B1Y3R4ID0gJmdldF9jcHVfdmFyKHBlcmZfY3B1X2NvbnRleHQpOwoJcGVyZl9ldmVudF9tbWFwX2N0eCgmY3B1Y3R4LT5jdHgsIG1tYXBfZXZlbnQpOwoJcHV0X2NwdV92YXIocGVyZl9jcHVfY29udGV4dCk7CgoJcmN1X3JlYWRfbG9jaygpOwoJLyoKCSAqIGRvZXNuJ3QgcmVhbGx5IG1hdHRlciB3aGljaCBvZiB0aGUgY2hpbGQgY29udGV4dHMgdGhlCgkgKiBldmVudHMgZW5kcyB1cCBpbi4KCSAqLwoJY3R4ID0gcmN1X2RlcmVmZXJlbmNlKGN1cnJlbnQtPnBlcmZfZXZlbnRfY3R4cCk7CglpZiAoY3R4KQoJCXBlcmZfZXZlbnRfbW1hcF9jdHgoY3R4LCBtbWFwX2V2ZW50KTsKCXJjdV9yZWFkX3VubG9jaygpOwoKCWtmcmVlKGJ1Zik7Cn0KCnZvaWQgX19wZXJmX2V2ZW50X21tYXAoc3RydWN0IHZtX2FyZWFfc3RydWN0ICp2bWEpCnsKCXN0cnVjdCBwZXJmX21tYXBfZXZlbnQgbW1hcF9ldmVudDsKCglpZiAoIWF0b21pY19yZWFkKCZucl9tbWFwX2V2ZW50cykpCgkJcmV0dXJuOwoKCW1tYXBfZXZlbnQgPSAoc3RydWN0IHBlcmZfbW1hcF9ldmVudCl7CgkJLnZtYQk9IHZtYSwKCQkvKiAuZmlsZV9uYW1lICovCgkJLyogLmZpbGVfc2l6ZSAqLwoJCS5ldmVudF9pZCAgPSB7CgkJCS5oZWFkZXIgPSB7CgkJCQkudHlwZSA9IFBFUkZfUkVDT1JEX01NQVAsCgkJCQkubWlzYyA9IDAsCgkJCQkvKiAuc2l6ZSAqLwoJCQl9LAoJCQkvKiAucGlkICovCgkJCS8qIC50aWQgKi8KCQkJLnN0YXJ0ICA9IHZtYS0+dm1fc3RhcnQsCgkJCS5sZW4gICAgPSB2bWEtPnZtX2VuZCAtIHZtYS0+dm1fc3RhcnQsCgkJCS5wZ29mZiAgPSB2bWEtPnZtX3Bnb2ZmLAoJCX0sCgl9OwoKCXBlcmZfZXZlbnRfbW1hcF9ldmVudCgmbW1hcF9ldmVudCk7Cn0KCi8qCiAqIElSUSB0aHJvdHRsZSBsb2dnaW5nCiAqLwoKc3RhdGljIHZvaWQgcGVyZl9sb2dfdGhyb3R0bGUoc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50LCBpbnQgZW5hYmxlKQp7CglzdHJ1Y3QgcGVyZl9vdXRwdXRfaGFuZGxlIGhhbmRsZTsKCWludCByZXQ7CgoJc3RydWN0IHsKCQlzdHJ1Y3QgcGVyZl9ldmVudF9oZWFkZXIJaGVhZGVyOwoJCXU2NAkJCQl0aW1lOwoJCXU2NAkJCQlpZDsKCQl1NjQJCQkJc3RyZWFtX2lkOwoJfSB0aHJvdHRsZV9ldmVudCA9IHsKCQkuaGVhZGVyID0gewoJCQkudHlwZSA9IFBFUkZfUkVDT1JEX1RIUk9UVExFLAoJCQkubWlzYyA9IDAsCgkJCS5zaXplID0gc2l6ZW9mKHRocm90dGxlX2V2ZW50KSwKCQl9LAoJCS50aW1lCQk9IHBlcmZfY2xvY2soKSwKCQkuaWQJCT0gcHJpbWFyeV9ldmVudF9pZChldmVudCksCgkJLnN0cmVhbV9pZAk9IGV2ZW50LT5pZCwKCX07CgoJaWYgKGVuYWJsZSkKCQl0aHJvdHRsZV9ldmVudC5oZWFkZXIudHlwZSA9IFBFUkZfUkVDT1JEX1VOVEhST1RUTEU7CgoJcmV0ID0gcGVyZl9vdXRwdXRfYmVnaW4oJmhhbmRsZSwgZXZlbnQsIHNpemVvZih0aHJvdHRsZV9ldmVudCksIDEsIDApOwoJaWYgKHJldCkKCQlyZXR1cm47CgoJcGVyZl9vdXRwdXRfcHV0KCZoYW5kbGUsIHRocm90dGxlX2V2ZW50KTsKCXBlcmZfb3V0cHV0X2VuZCgmaGFuZGxlKTsKfQoKLyoKICogR2VuZXJpYyBldmVudCBvdmVyZmxvdyBoYW5kbGluZywgc2FtcGxpbmcuCiAqLwoKc3RhdGljIGludCBfX3BlcmZfZXZlbnRfb3ZlcmZsb3coc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50LCBpbnQgbm1pLAoJCQkJICAgaW50IHRocm90dGxlLCBzdHJ1Y3QgcGVyZl9zYW1wbGVfZGF0YSAqZGF0YSwKCQkJCSAgIHN0cnVjdCBwdF9yZWdzICpyZWdzKQp7CglpbnQgZXZlbnRzID0gYXRvbWljX3JlYWQoJmV2ZW50LT5ldmVudF9saW1pdCk7CglzdHJ1Y3QgaHdfcGVyZl9ldmVudCAqaHdjID0gJmV2ZW50LT5odzsKCWludCByZXQgPSAwOwoKCXRocm90dGxlID0gKHRocm90dGxlICYmIGV2ZW50LT5wbXUtPnVudGhyb3R0bGUgIT0gTlVMTCk7CgoJaWYgKCF0aHJvdHRsZSkgewoJCWh3Yy0+aW50ZXJydXB0cysrOwoJfSBlbHNlIHsKCQlpZiAoaHdjLT5pbnRlcnJ1cHRzICE9IE1BWF9JTlRFUlJVUFRTKSB7CgkJCWh3Yy0+aW50ZXJydXB0cysrOwoJCQlpZiAoSFogKiBod2MtPmludGVycnVwdHMgPgoJCQkJCSh1NjQpc3lzY3RsX3BlcmZfZXZlbnRfc2FtcGxlX3JhdGUpIHsKCQkJCWh3Yy0+aW50ZXJydXB0cyA9IE1BWF9JTlRFUlJVUFRTOwoJCQkJcGVyZl9sb2dfdGhyb3R0bGUoZXZlbnQsIDApOwoJCQkJcmV0ID0gMTsKCQkJfQoJCX0gZWxzZSB7CgkJCS8qCgkJCSAqIEtlZXAgcmUtZGlzYWJsaW5nIGV2ZW50cyBldmVuIHRob3VnaCBvbiB0aGUgcHJldmlvdXMKCQkJICogcGFzcyB3ZSBkaXNhYmxlZCBpdCAtIGp1c3QgaW4gY2FzZSB3ZSByYWNlZCB3aXRoIGEKCQkJICogc2NoZWQtaW4gYW5kIHRoZSBldmVudCBnb3QgZW5hYmxlZCBhZ2FpbjoKCQkJICovCgkJCXJldCA9IDE7CgkJfQoJfQoKCWlmIChldmVudC0+YXR0ci5mcmVxKSB7CgkJdTY0IG5vdyA9IHBlcmZfY2xvY2soKTsKCQlzNjQgZGVsdGEgPSBub3cgLSBod2MtPmZyZXFfc3RhbXA7CgoJCWh3Yy0+ZnJlcV9zdGFtcCA9IG5vdzsKCgkJaWYgKGRlbHRhID4gMCAmJiBkZWx0YSA8IFRJQ0tfTlNFQykKCQkJcGVyZl9hZGp1c3RfcGVyaW9kKGV2ZW50LCBOU0VDX1BFUl9TRUMgLyAoaW50KWRlbHRhKTsKCX0KCgkvKgoJICogWFhYIGV2ZW50X2xpbWl0IG1pZ2h0IG5vdCBxdWl0ZSB3b3JrIGFzIGV4cGVjdGVkIG9uIGluaGVyaXRlZAoJICogZXZlbnRzCgkgKi8KCglldmVudC0+cGVuZGluZ19raWxsID0gUE9MTF9JTjsKCWlmIChldmVudHMgJiYgYXRvbWljX2RlY19hbmRfdGVzdCgmZXZlbnQtPmV2ZW50X2xpbWl0KSkgewoJCXJldCA9IDE7CgkJZXZlbnQtPnBlbmRpbmdfa2lsbCA9IFBPTExfSFVQOwoJCWlmIChubWkpIHsKCQkJZXZlbnQtPnBlbmRpbmdfZGlzYWJsZSA9IDE7CgkJCXBlcmZfcGVuZGluZ19xdWV1ZSgmZXZlbnQtPnBlbmRpbmcsCgkJCQkJICAgcGVyZl9wZW5kaW5nX2V2ZW50KTsKCQl9IGVsc2UKCQkJcGVyZl9ldmVudF9kaXNhYmxlKGV2ZW50KTsKCX0KCglwZXJmX2V2ZW50X291dHB1dChldmVudCwgbm1pLCBkYXRhLCByZWdzKTsKCXJldHVybiByZXQ7Cn0KCmludCBwZXJmX2V2ZW50X292ZXJmbG93KHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCwgaW50IG5taSwKCQkJICBzdHJ1Y3QgcGVyZl9zYW1wbGVfZGF0YSAqZGF0YSwKCQkJICBzdHJ1Y3QgcHRfcmVncyAqcmVncykKewoJcmV0dXJuIF9fcGVyZl9ldmVudF9vdmVyZmxvdyhldmVudCwgbm1pLCAxLCBkYXRhLCByZWdzKTsKfQoKLyoKICogR2VuZXJpYyBzb2Z0d2FyZSBldmVudCBpbmZyYXN0cnVjdHVyZQogKi8KCi8qCiAqIFdlIGRpcmVjdGx5IGluY3JlbWVudCBldmVudC0+Y291bnQgYW5kIGtlZXAgYSBzZWNvbmQgdmFsdWUgaW4KICogZXZlbnQtPmh3LnBlcmlvZF9sZWZ0IHRvIGNvdW50IGludGVydmFscy4gVGhpcyBwZXJpb2QgZXZlbnQKICogaXMga2VwdCBpbiB0aGUgcmFuZ2UgWy1zYW1wbGVfcGVyaW9kLCAwXSBzbyB0aGF0IHdlIGNhbiB1c2UgdGhlCiAqIHNpZ24gYXMgdHJpZ2dlci4KICovCgpzdGF0aWMgdTY0IHBlcmZfc3dldmVudF9zZXRfcGVyaW9kKHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCkKewoJc3RydWN0IGh3X3BlcmZfZXZlbnQgKmh3YyA9ICZldmVudC0+aHc7Cgl1NjQgcGVyaW9kID0gaHdjLT5sYXN0X3BlcmlvZDsKCXU2NCBuciwgb2Zmc2V0OwoJczY0IG9sZCwgdmFsOwoKCWh3Yy0+bGFzdF9wZXJpb2QgPSBod2MtPnNhbXBsZV9wZXJpb2Q7CgphZ2FpbjoKCW9sZCA9IHZhbCA9IGF0b21pYzY0X3JlYWQoJmh3Yy0+cGVyaW9kX2xlZnQpOwoJaWYgKHZhbCA8IDApCgkJcmV0dXJuIDA7CgoJbnIgPSBkaXY2NF91NjQocGVyaW9kICsgdmFsLCBwZXJpb2QpOwoJb2Zmc2V0ID0gbnIgKiBwZXJpb2Q7Cgl2YWwgLT0gb2Zmc2V0OwoJaWYgKGF0b21pYzY0X2NtcHhjaGcoJmh3Yy0+cGVyaW9kX2xlZnQsIG9sZCwgdmFsKSAhPSBvbGQpCgkJZ290byBhZ2FpbjsKCglyZXR1cm4gbnI7Cn0KCnN0YXRpYyB2b2lkIHBlcmZfc3dldmVudF9vdmVyZmxvdyhzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQsCgkJCQkgICAgaW50IG5taSwgc3RydWN0IHBlcmZfc2FtcGxlX2RhdGEgKmRhdGEsCgkJCQkgICAgc3RydWN0IHB0X3JlZ3MgKnJlZ3MpCnsKCXN0cnVjdCBod19wZXJmX2V2ZW50ICpod2MgPSAmZXZlbnQtPmh3OwoJaW50IHRocm90dGxlID0gMDsKCXU2NCBvdmVyZmxvdzsKCglkYXRhLT5wZXJpb2QgPSBldmVudC0+aHcubGFzdF9wZXJpb2Q7CglvdmVyZmxvdyA9IHBlcmZfc3dldmVudF9zZXRfcGVyaW9kKGV2ZW50KTsKCglpZiAoaHdjLT5pbnRlcnJ1cHRzID09IE1BWF9JTlRFUlJVUFRTKQoJCXJldHVybjsKCglmb3IgKDsgb3ZlcmZsb3c7IG92ZXJmbG93LS0pIHsKCQlpZiAoX19wZXJmX2V2ZW50X292ZXJmbG93KGV2ZW50LCBubWksIHRocm90dGxlLAoJCQkJCSAgICBkYXRhLCByZWdzKSkgewoJCQkvKgoJCQkgKiBXZSBpbmhpYml0IHRoZSBvdmVyZmxvdyBmcm9tIGhhcHBlbmluZyB3aGVuCgkJCSAqIGh3Yy0+aW50ZXJydXB0cyA9PSBNQVhfSU5URVJSVVBUUy4KCQkJICovCgkJCWJyZWFrOwoJCX0KCQl0aHJvdHRsZSA9IDE7Cgl9Cn0KCnN0YXRpYyB2b2lkIHBlcmZfc3dldmVudF91bnRocm90dGxlKHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCkKewoJLyoKCSAqIE5vdGhpbmcgdG8gZG8sIHdlIGFscmVhZHkgcmVzZXQgaHdjLT5pbnRlcnJ1cHRzLgoJICovCn0KCnN0YXRpYyB2b2lkIHBlcmZfc3dldmVudF9hZGQoc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50LCB1NjQgbnIsCgkJCSAgICAgICBpbnQgbm1pLCBzdHJ1Y3QgcGVyZl9zYW1wbGVfZGF0YSAqZGF0YSwKCQkJICAgICAgIHN0cnVjdCBwdF9yZWdzICpyZWdzKQp7CglzdHJ1Y3QgaHdfcGVyZl9ldmVudCAqaHdjID0gJmV2ZW50LT5odzsKCglhdG9taWM2NF9hZGQobnIsICZldmVudC0+Y291bnQpOwoKCWlmICghaHdjLT5zYW1wbGVfcGVyaW9kKQoJCXJldHVybjsKCglpZiAoIXJlZ3MpCgkJcmV0dXJuOwoKCWlmICghYXRvbWljNjRfYWRkX25lZ2F0aXZlKG5yLCAmaHdjLT5wZXJpb2RfbGVmdCkpCgkJcGVyZl9zd2V2ZW50X292ZXJmbG93KGV2ZW50LCBubWksIGRhdGEsIHJlZ3MpOwp9CgpzdGF0aWMgaW50IHBlcmZfc3dldmVudF9pc19jb3VudGluZyhzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQpCnsKCS8qCgkgKiBUaGUgZXZlbnQgaXMgYWN0aXZlLCB3ZSdyZSBnb29kIQoJICovCglpZiAoZXZlbnQtPnN0YXRlID09IFBFUkZfRVZFTlRfU1RBVEVfQUNUSVZFKQoJCXJldHVybiAxOwoKCS8qCgkgKiBUaGUgZXZlbnQgaXMgb2ZmL2Vycm9yLCBub3QgY291bnRpbmcuCgkgKi8KCWlmIChldmVudC0+c3RhdGUgIT0gUEVSRl9FVkVOVF9TVEFURV9JTkFDVElWRSkKCQlyZXR1cm4gMDsKCgkvKgoJICogVGhlIGV2ZW50IGlzIGluYWN0aXZlLCBpZiB0aGUgY29udGV4dCBpcyBhY3RpdmUKCSAqIHdlJ3JlIHBhcnQgb2YgYSBncm91cCB0aGF0IGRpZG4ndCBtYWtlIGl0IG9uIHRoZSAncG11JywKCSAqIG5vdCBjb3VudGluZy4KCSAqLwoJaWYgKGV2ZW50LT5jdHgtPmlzX2FjdGl2ZSkKCQlyZXR1cm4gMDsKCgkvKgoJICogV2UncmUgaW5hY3RpdmUgYW5kIHRoZSBjb250ZXh0IGlzIHRvbywgdGhpcyBtZWFucyB0aGUKCSAqIHRhc2sgaXMgc2NoZWR1bGVkIG91dCwgd2UncmUgY291bnRpbmcgZXZlbnRzIHRoYXQgaGFwcGVuCgkgKiB0byB1cywgbGlrZSBtaWdyYXRpb24gZXZlbnRzLgoJICovCglyZXR1cm4gMTsKfQoKc3RhdGljIGludCBwZXJmX3N3ZXZlbnRfbWF0Y2goc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50LAoJCQkJZW51bSBwZXJmX3R5cGVfaWQgdHlwZSwKCQkJCXUzMiBldmVudF9pZCwgc3RydWN0IHB0X3JlZ3MgKnJlZ3MpCnsKCWlmICghcGVyZl9zd2V2ZW50X2lzX2NvdW50aW5nKGV2ZW50KSkKCQlyZXR1cm4gMDsKCglpZiAoZXZlbnQtPmF0dHIudHlwZSAhPSB0eXBlKQoJCXJldHVybiAwOwoJaWYgKGV2ZW50LT5hdHRyLmNvbmZpZyAhPSBldmVudF9pZCkKCQlyZXR1cm4gMDsKCglpZiAocmVncykgewoJCWlmIChldmVudC0+YXR0ci5leGNsdWRlX3VzZXIgJiYgdXNlcl9tb2RlKHJlZ3MpKQoJCQlyZXR1cm4gMDsKCgkJaWYgKGV2ZW50LT5hdHRyLmV4Y2x1ZGVfa2VybmVsICYmICF1c2VyX21vZGUocmVncykpCgkJCXJldHVybiAwOwoJfQoKCXJldHVybiAxOwp9CgpzdGF0aWMgdm9pZCBwZXJmX3N3ZXZlbnRfY3R4X2V2ZW50KHN0cnVjdCBwZXJmX2V2ZW50X2NvbnRleHQgKmN0eCwKCQkJCSAgICAgZW51bSBwZXJmX3R5cGVfaWQgdHlwZSwKCQkJCSAgICAgdTMyIGV2ZW50X2lkLCB1NjQgbnIsIGludCBubWksCgkJCQkgICAgIHN0cnVjdCBwZXJmX3NhbXBsZV9kYXRhICpkYXRhLAoJCQkJICAgICBzdHJ1Y3QgcHRfcmVncyAqcmVncykKewoJc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50OwoKCWlmIChzeXN0ZW1fc3RhdGUgIT0gU1lTVEVNX1JVTk5JTkcgfHwgbGlzdF9lbXB0eSgmY3R4LT5ldmVudF9saXN0KSkKCQlyZXR1cm47CgoJcmN1X3JlYWRfbG9jaygpOwoJbGlzdF9mb3JfZWFjaF9lbnRyeV9yY3UoZXZlbnQsICZjdHgtPmV2ZW50X2xpc3QsIGV2ZW50X2VudHJ5KSB7CgkJaWYgKHBlcmZfc3dldmVudF9tYXRjaChldmVudCwgdHlwZSwgZXZlbnRfaWQsIHJlZ3MpKQoJCQlwZXJmX3N3ZXZlbnRfYWRkKGV2ZW50LCBuciwgbm1pLCBkYXRhLCByZWdzKTsKCX0KCXJjdV9yZWFkX3VubG9jaygpOwp9CgpzdGF0aWMgaW50ICpwZXJmX3N3ZXZlbnRfcmVjdXJzaW9uX2NvbnRleHQoc3RydWN0IHBlcmZfY3B1X2NvbnRleHQgKmNwdWN0eCkKewoJaWYgKGluX25taSgpKQoJCXJldHVybiAmY3B1Y3R4LT5yZWN1cnNpb25bM107CgoJaWYgKGluX2lycSgpKQoJCXJldHVybiAmY3B1Y3R4LT5yZWN1cnNpb25bMl07CgoJaWYgKGluX3NvZnRpcnEoKSkKCQlyZXR1cm4gJmNwdWN0eC0+cmVjdXJzaW9uWzFdOwoKCXJldHVybiAmY3B1Y3R4LT5yZWN1cnNpb25bMF07Cn0KCnN0YXRpYyB2b2lkIGRvX3BlcmZfc3dfZXZlbnQoZW51bSBwZXJmX3R5cGVfaWQgdHlwZSwgdTMyIGV2ZW50X2lkLAoJCQkJICAgIHU2NCBuciwgaW50IG5taSwKCQkJCSAgICBzdHJ1Y3QgcGVyZl9zYW1wbGVfZGF0YSAqZGF0YSwKCQkJCSAgICBzdHJ1Y3QgcHRfcmVncyAqcmVncykKewoJc3RydWN0IHBlcmZfY3B1X2NvbnRleHQgKmNwdWN0eCA9ICZnZXRfY3B1X3ZhcihwZXJmX2NwdV9jb250ZXh0KTsKCWludCAqcmVjdXJzaW9uID0gcGVyZl9zd2V2ZW50X3JlY3Vyc2lvbl9jb250ZXh0KGNwdWN0eCk7CglzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0ICpjdHg7CgoJaWYgKCpyZWN1cnNpb24pCgkJZ290byBvdXQ7CgoJKCpyZWN1cnNpb24pKys7CgliYXJyaWVyKCk7CgoJcGVyZl9zd2V2ZW50X2N0eF9ldmVudCgmY3B1Y3R4LT5jdHgsIHR5cGUsIGV2ZW50X2lkLAoJCQkJIG5yLCBubWksIGRhdGEsIHJlZ3MpOwoJcmN1X3JlYWRfbG9jaygpOwoJLyoKCSAqIGRvZXNuJ3QgcmVhbGx5IG1hdHRlciB3aGljaCBvZiB0aGUgY2hpbGQgY29udGV4dHMgdGhlCgkgKiBldmVudHMgZW5kcyB1cCBpbi4KCSAqLwoJY3R4ID0gcmN1X2RlcmVmZXJlbmNlKGN1cnJlbnQtPnBlcmZfZXZlbnRfY3R4cCk7CglpZiAoY3R4KQoJCXBlcmZfc3dldmVudF9jdHhfZXZlbnQoY3R4LCB0eXBlLCBldmVudF9pZCwgbnIsIG5taSwgZGF0YSwgcmVncyk7CglyY3VfcmVhZF91bmxvY2soKTsKCgliYXJyaWVyKCk7CgkoKnJlY3Vyc2lvbiktLTsKCm91dDoKCXB1dF9jcHVfdmFyKHBlcmZfY3B1X2NvbnRleHQpOwp9Cgp2b2lkIF9fcGVyZl9zd19ldmVudCh1MzIgZXZlbnRfaWQsIHU2NCBuciwgaW50IG5taSwKCQkJICAgIHN0cnVjdCBwdF9yZWdzICpyZWdzLCB1NjQgYWRkcikKewoJc3RydWN0IHBlcmZfc2FtcGxlX2RhdGEgZGF0YSA9IHsKCQkuYWRkciA9IGFkZHIsCgl9OwoKCWRvX3BlcmZfc3dfZXZlbnQoUEVSRl9UWVBFX1NPRlRXQVJFLCBldmVudF9pZCwgbnIsIG5taSwKCQkJCSZkYXRhLCByZWdzKTsKfQoKc3RhdGljIHZvaWQgcGVyZl9zd2V2ZW50X3JlYWQoc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50KQp7Cn0KCnN0YXRpYyBpbnQgcGVyZl9zd2V2ZW50X2VuYWJsZShzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQpCnsKCXN0cnVjdCBod19wZXJmX2V2ZW50ICpod2MgPSAmZXZlbnQtPmh3OwoKCWlmIChod2MtPnNhbXBsZV9wZXJpb2QpIHsKCQlod2MtPmxhc3RfcGVyaW9kID0gaHdjLT5zYW1wbGVfcGVyaW9kOwoJCXBlcmZfc3dldmVudF9zZXRfcGVyaW9kKGV2ZW50KTsKCX0KCXJldHVybiAwOwp9CgpzdGF0aWMgdm9pZCBwZXJmX3N3ZXZlbnRfZGlzYWJsZShzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQpCnsKfQoKc3RhdGljIGNvbnN0IHN0cnVjdCBwbXUgcGVyZl9vcHNfZ2VuZXJpYyA9IHsKCS5lbmFibGUJCT0gcGVyZl9zd2V2ZW50X2VuYWJsZSwKCS5kaXNhYmxlCT0gcGVyZl9zd2V2ZW50X2Rpc2FibGUsCgkucmVhZAkJPSBwZXJmX3N3ZXZlbnRfcmVhZCwKCS51bnRocm90dGxlCT0gcGVyZl9zd2V2ZW50X3VudGhyb3R0bGUsCn07CgovKgogKiBocnRpbWVyIGJhc2VkIHN3ZXZlbnQgY2FsbGJhY2sKICovCgpzdGF0aWMgZW51bSBocnRpbWVyX3Jlc3RhcnQgcGVyZl9zd2V2ZW50X2hydGltZXIoc3RydWN0IGhydGltZXIgKmhydGltZXIpCnsKCWVudW0gaHJ0aW1lcl9yZXN0YXJ0IHJldCA9IEhSVElNRVJfUkVTVEFSVDsKCXN0cnVjdCBwZXJmX3NhbXBsZV9kYXRhIGRhdGE7CglzdHJ1Y3QgcHRfcmVncyAqcmVnczsKCXN0cnVjdCBwZXJmX2V2ZW50ICpldmVudDsKCXU2NCBwZXJpb2Q7CgoJZXZlbnQJPSBjb250YWluZXJfb2YoaHJ0aW1lciwgc3RydWN0IHBlcmZfZXZlbnQsIGh3LmhydGltZXIpOwoJZXZlbnQtPnBtdS0+cmVhZChldmVudCk7CgoJZGF0YS5hZGRyID0gMDsKCXJlZ3MgPSBnZXRfaXJxX3JlZ3MoKTsKCS8qCgkgKiBJbiBjYXNlIHdlIGV4Y2x1ZGUga2VybmVsIElQcyBvciBhcmUgc29tZWhvdyBub3QgaW4gaW50ZXJydXB0CgkgKiBjb250ZXh0LCBwcm92aWRlIHRoZSBuZXh0IGJlc3QgdGhpbmcsIHRoZSB1c2VyIElQLgoJICovCglpZiAoKGV2ZW50LT5hdHRyLmV4Y2x1ZGVfa2VybmVsIHx8ICFyZWdzKSAmJgoJCQkhZXZlbnQtPmF0dHIuZXhjbHVkZV91c2VyKQoJCXJlZ3MgPSB0YXNrX3B0X3JlZ3MoY3VycmVudCk7CgoJaWYgKHJlZ3MpIHsKCQlpZiAoIShldmVudC0+YXR0ci5leGNsdWRlX2lkbGUgJiYgY3VycmVudC0+cGlkID09IDApKQoJCQlpZiAocGVyZl9ldmVudF9vdmVyZmxvdyhldmVudCwgMCwgJmRhdGEsIHJlZ3MpKQoJCQkJcmV0ID0gSFJUSU1FUl9OT1JFU1RBUlQ7Cgl9CgoJcGVyaW9kID0gbWF4X3QodTY0LCAxMDAwMCwgZXZlbnQtPmh3LnNhbXBsZV9wZXJpb2QpOwoJaHJ0aW1lcl9mb3J3YXJkX25vdyhocnRpbWVyLCBuc190b19rdGltZShwZXJpb2QpKTsKCglyZXR1cm4gcmV0Owp9CgpzdGF0aWMgdm9pZCBwZXJmX3N3ZXZlbnRfc3RhcnRfaHJ0aW1lcihzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQpCnsKCXN0cnVjdCBod19wZXJmX2V2ZW50ICpod2MgPSAmZXZlbnQtPmh3OwoKCWhydGltZXJfaW5pdCgmaHdjLT5ocnRpbWVyLCBDTE9DS19NT05PVE9OSUMsIEhSVElNRVJfTU9ERV9SRUwpOwoJaHdjLT5ocnRpbWVyLmZ1bmN0aW9uID0gcGVyZl9zd2V2ZW50X2hydGltZXI7CglpZiAoaHdjLT5zYW1wbGVfcGVyaW9kKSB7CgkJdTY0IHBlcmlvZDsKCgkJaWYgKGh3Yy0+cmVtYWluaW5nKSB7CgkJCWlmIChod2MtPnJlbWFpbmluZyA8IDApCgkJCQlwZXJpb2QgPSAxMDAwMDsKCQkJZWxzZQoJCQkJcGVyaW9kID0gaHdjLT5yZW1haW5pbmc7CgkJCWh3Yy0+cmVtYWluaW5nID0gMDsKCQl9IGVsc2UgewoJCQlwZXJpb2QgPSBtYXhfdCh1NjQsIDEwMDAwLCBod2MtPnNhbXBsZV9wZXJpb2QpOwoJCX0KCQlfX2hydGltZXJfc3RhcnRfcmFuZ2VfbnMoJmh3Yy0+aHJ0aW1lciwKCQkJCW5zX3RvX2t0aW1lKHBlcmlvZCksIDAsCgkJCQlIUlRJTUVSX01PREVfUkVMLCAwKTsKCX0KfQoKc3RhdGljIHZvaWQgcGVyZl9zd2V2ZW50X2NhbmNlbF9ocnRpbWVyKHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCkKewoJc3RydWN0IGh3X3BlcmZfZXZlbnQgKmh3YyA9ICZldmVudC0+aHc7CgoJaWYgKGh3Yy0+c2FtcGxlX3BlcmlvZCkgewoJCWt0aW1lX3QgcmVtYWluaW5nID0gaHJ0aW1lcl9nZXRfcmVtYWluaW5nKCZod2MtPmhydGltZXIpOwoJCWh3Yy0+cmVtYWluaW5nID0ga3RpbWVfdG9fbnMocmVtYWluaW5nKTsKCgkJaHJ0aW1lcl9jYW5jZWwoJmh3Yy0+aHJ0aW1lcik7Cgl9Cn0KCi8qCiAqIFNvZnR3YXJlIGV2ZW50OiBjcHUgd2FsbCB0aW1lIGNsb2NrCiAqLwoKc3RhdGljIHZvaWQgY3B1X2Nsb2NrX3BlcmZfZXZlbnRfdXBkYXRlKHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCkKewoJaW50IGNwdSA9IHJhd19zbXBfcHJvY2Vzc29yX2lkKCk7CglzNjQgcHJldjsKCXU2NCBub3c7CgoJbm93ID0gY3B1X2Nsb2NrKGNwdSk7CglwcmV2ID0gYXRvbWljNjRfcmVhZCgmZXZlbnQtPmh3LnByZXZfY291bnQpOwoJYXRvbWljNjRfc2V0KCZldmVudC0+aHcucHJldl9jb3VudCwgbm93KTsKCWF0b21pYzY0X2FkZChub3cgLSBwcmV2LCAmZXZlbnQtPmNvdW50KTsKfQoKc3RhdGljIGludCBjcHVfY2xvY2tfcGVyZl9ldmVudF9lbmFibGUoc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50KQp7CglzdHJ1Y3QgaHdfcGVyZl9ldmVudCAqaHdjID0gJmV2ZW50LT5odzsKCWludCBjcHUgPSByYXdfc21wX3Byb2Nlc3Nvcl9pZCgpOwoKCWF0b21pYzY0X3NldCgmaHdjLT5wcmV2X2NvdW50LCBjcHVfY2xvY2soY3B1KSk7CglwZXJmX3N3ZXZlbnRfc3RhcnRfaHJ0aW1lcihldmVudCk7CgoJcmV0dXJuIDA7Cn0KCnN0YXRpYyB2b2lkIGNwdV9jbG9ja19wZXJmX2V2ZW50X2Rpc2FibGUoc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50KQp7CglwZXJmX3N3ZXZlbnRfY2FuY2VsX2hydGltZXIoZXZlbnQpOwoJY3B1X2Nsb2NrX3BlcmZfZXZlbnRfdXBkYXRlKGV2ZW50KTsKfQoKc3RhdGljIHZvaWQgY3B1X2Nsb2NrX3BlcmZfZXZlbnRfcmVhZChzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQpCnsKCWNwdV9jbG9ja19wZXJmX2V2ZW50X3VwZGF0ZShldmVudCk7Cn0KCnN0YXRpYyBjb25zdCBzdHJ1Y3QgcG11IHBlcmZfb3BzX2NwdV9jbG9jayA9IHsKCS5lbmFibGUJCT0gY3B1X2Nsb2NrX3BlcmZfZXZlbnRfZW5hYmxlLAoJLmRpc2FibGUJPSBjcHVfY2xvY2tfcGVyZl9ldmVudF9kaXNhYmxlLAoJLnJlYWQJCT0gY3B1X2Nsb2NrX3BlcmZfZXZlbnRfcmVhZCwKfTsKCi8qCiAqIFNvZnR3YXJlIGV2ZW50OiB0YXNrIHRpbWUgY2xvY2sKICovCgpzdGF0aWMgdm9pZCB0YXNrX2Nsb2NrX3BlcmZfZXZlbnRfdXBkYXRlKHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCwgdTY0IG5vdykKewoJdTY0IHByZXY7CglzNjQgZGVsdGE7CgoJcHJldiA9IGF0b21pYzY0X3hjaGcoJmV2ZW50LT5ody5wcmV2X2NvdW50LCBub3cpOwoJZGVsdGEgPSBub3cgLSBwcmV2OwoJYXRvbWljNjRfYWRkKGRlbHRhLCAmZXZlbnQtPmNvdW50KTsKfQoKc3RhdGljIGludCB0YXNrX2Nsb2NrX3BlcmZfZXZlbnRfZW5hYmxlKHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCkKewoJc3RydWN0IGh3X3BlcmZfZXZlbnQgKmh3YyA9ICZldmVudC0+aHc7Cgl1NjQgbm93OwoKCW5vdyA9IGV2ZW50LT5jdHgtPnRpbWU7CgoJYXRvbWljNjRfc2V0KCZod2MtPnByZXZfY291bnQsIG5vdyk7CgoJcGVyZl9zd2V2ZW50X3N0YXJ0X2hydGltZXIoZXZlbnQpOwoKCXJldHVybiAwOwp9CgpzdGF0aWMgdm9pZCB0YXNrX2Nsb2NrX3BlcmZfZXZlbnRfZGlzYWJsZShzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQpCnsKCXBlcmZfc3dldmVudF9jYW5jZWxfaHJ0aW1lcihldmVudCk7Cgl0YXNrX2Nsb2NrX3BlcmZfZXZlbnRfdXBkYXRlKGV2ZW50LCBldmVudC0+Y3R4LT50aW1lKTsKCn0KCnN0YXRpYyB2b2lkIHRhc2tfY2xvY2tfcGVyZl9ldmVudF9yZWFkKHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCkKewoJdTY0IHRpbWU7CgoJaWYgKCFpbl9ubWkoKSkgewoJCXVwZGF0ZV9jb250ZXh0X3RpbWUoZXZlbnQtPmN0eCk7CgkJdGltZSA9IGV2ZW50LT5jdHgtPnRpbWU7Cgl9IGVsc2UgewoJCXU2NCBub3cgPSBwZXJmX2Nsb2NrKCk7CgkJdTY0IGRlbHRhID0gbm93IC0gZXZlbnQtPmN0eC0+dGltZXN0YW1wOwoJCXRpbWUgPSBldmVudC0+Y3R4LT50aW1lICsgZGVsdGE7Cgl9CgoJdGFza19jbG9ja19wZXJmX2V2ZW50X3VwZGF0ZShldmVudCwgdGltZSk7Cn0KCnN0YXRpYyBjb25zdCBzdHJ1Y3QgcG11IHBlcmZfb3BzX3Rhc2tfY2xvY2sgPSB7CgkuZW5hYmxlCQk9IHRhc2tfY2xvY2tfcGVyZl9ldmVudF9lbmFibGUsCgkuZGlzYWJsZQk9IHRhc2tfY2xvY2tfcGVyZl9ldmVudF9kaXNhYmxlLAoJLnJlYWQJCT0gdGFza19jbG9ja19wZXJmX2V2ZW50X3JlYWQsCn07CgojaWZkZWYgQ09ORklHX0VWRU5UX1BST0ZJTEUKdm9pZCBwZXJmX3RwX2V2ZW50KGludCBldmVudF9pZCwgdTY0IGFkZHIsIHU2NCBjb3VudCwgdm9pZCAqcmVjb3JkLAoJCQkgIGludCBlbnRyeV9zaXplKQp7CglzdHJ1Y3QgcGVyZl9yYXdfcmVjb3JkIHJhdyA9IHsKCQkuc2l6ZSA9IGVudHJ5X3NpemUsCgkJLmRhdGEgPSByZWNvcmQsCgl9OwoKCXN0cnVjdCBwZXJmX3NhbXBsZV9kYXRhIGRhdGEgPSB7CgkJLmFkZHIgPSBhZGRyLAoJCS5yYXcgPSAmcmF3LAoJfTsKCglzdHJ1Y3QgcHRfcmVncyAqcmVncyA9IGdldF9pcnFfcmVncygpOwoKCWlmICghcmVncykKCQlyZWdzID0gdGFza19wdF9yZWdzKGN1cnJlbnQpOwoKCWRvX3BlcmZfc3dfZXZlbnQoUEVSRl9UWVBFX1RSQUNFUE9JTlQsIGV2ZW50X2lkLCBjb3VudCwgMSwKCQkJCSZkYXRhLCByZWdzKTsKfQpFWFBPUlRfU1lNQk9MX0dQTChwZXJmX3RwX2V2ZW50KTsKCmV4dGVybiBpbnQgZnRyYWNlX3Byb2ZpbGVfZW5hYmxlKGludCk7CmV4dGVybiB2b2lkIGZ0cmFjZV9wcm9maWxlX2Rpc2FibGUoaW50KTsKCnN0YXRpYyB2b2lkIHRwX3BlcmZfZXZlbnRfZGVzdHJveShzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQpCnsKCWZ0cmFjZV9wcm9maWxlX2Rpc2FibGUoZXZlbnQtPmF0dHIuY29uZmlnKTsKfQoKc3RhdGljIGNvbnN0IHN0cnVjdCBwbXUgKnRwX3BlcmZfZXZlbnRfaW5pdChzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQpCnsKCS8qCgkgKiBSYXcgdHJhY2Vwb2ludCBkYXRhIGlzIGEgc2V2ZXJlIGRhdGEgbGVhaywgb25seSBhbGxvdyByb290IHRvCgkgKiBoYXZlIHRoZXNlLgoJICovCglpZiAoKGV2ZW50LT5hdHRyLnNhbXBsZV90eXBlICYgUEVSRl9TQU1QTEVfUkFXKSAmJgoJCQlwZXJmX3BhcmFub2lkX3RyYWNlcG9pbnRfcmF3KCkgJiYKCQkJIWNhcGFibGUoQ0FQX1NZU19BRE1JTikpCgkJcmV0dXJuIEVSUl9QVFIoLUVQRVJNKTsKCglpZiAoZnRyYWNlX3Byb2ZpbGVfZW5hYmxlKGV2ZW50LT5hdHRyLmNvbmZpZykpCgkJcmV0dXJuIE5VTEw7CgoJZXZlbnQtPmRlc3Ryb3kgPSB0cF9wZXJmX2V2ZW50X2Rlc3Ryb3k7CgoJcmV0dXJuICZwZXJmX29wc19nZW5lcmljOwp9CiNlbHNlCnN0YXRpYyBjb25zdCBzdHJ1Y3QgcG11ICp0cF9wZXJmX2V2ZW50X2luaXQoc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50KQp7CglyZXR1cm4gTlVMTDsKfQojZW5kaWYKCmF0b21pY190IHBlcmZfc3dldmVudF9lbmFibGVkW1BFUkZfQ09VTlRfU1dfTUFYXTsKCnN0YXRpYyB2b2lkIHN3X3BlcmZfZXZlbnRfZGVzdHJveShzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQpCnsKCXU2NCBldmVudF9pZCA9IGV2ZW50LT5hdHRyLmNvbmZpZzsKCglXQVJOX09OKGV2ZW50LT5wYXJlbnQpOwoKCWF0b21pY19kZWMoJnBlcmZfc3dldmVudF9lbmFibGVkW2V2ZW50X2lkXSk7Cn0KCnN0YXRpYyBjb25zdCBzdHJ1Y3QgcG11ICpzd19wZXJmX2V2ZW50X2luaXQoc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50KQp7Cgljb25zdCBzdHJ1Y3QgcG11ICpwbXUgPSBOVUxMOwoJdTY0IGV2ZW50X2lkID0gZXZlbnQtPmF0dHIuY29uZmlnOwoKCS8qCgkgKiBTb2Z0d2FyZSBldmVudHMgKGN1cnJlbnRseSkgY2FuJ3QgaW4gZ2VuZXJhbCBkaXN0aW5ndWlzaAoJICogYmV0d2VlbiB1c2VyLCBrZXJuZWwgYW5kIGh5cGVydmlzb3IgZXZlbnRzLgoJICogSG93ZXZlciwgY29udGV4dCBzd2l0Y2hlcyBhbmQgY3B1IG1pZ3JhdGlvbnMgYXJlIGNvbnNpZGVyZWQKCSAqIHRvIGJlIGtlcm5lbCBldmVudHMsIGFuZCBwYWdlIGZhdWx0cyBhcmUgbmV2ZXIgaHlwZXJ2aXNvcgoJICogZXZlbnRzLgoJICovCglzd2l0Y2ggKGV2ZW50X2lkKSB7CgljYXNlIFBFUkZfQ09VTlRfU1dfQ1BVX0NMT0NLOgoJCXBtdSA9ICZwZXJmX29wc19jcHVfY2xvY2s7CgoJCWJyZWFrOwoJY2FzZSBQRVJGX0NPVU5UX1NXX1RBU0tfQ0xPQ0s6CgkJLyoKCQkgKiBJZiB0aGUgdXNlciBpbnN0YW50aWF0ZXMgdGhpcyBhcyBhIHBlci1jcHUgZXZlbnQsCgkJICogdXNlIHRoZSBjcHVfY2xvY2sgZXZlbnQgaW5zdGVhZC4KCQkgKi8KCQlpZiAoZXZlbnQtPmN0eC0+dGFzaykKCQkJcG11ID0gJnBlcmZfb3BzX3Rhc2tfY2xvY2s7CgkJZWxzZQoJCQlwbXUgPSAmcGVyZl9vcHNfY3B1X2Nsb2NrOwoKCQlicmVhazsKCWNhc2UgUEVSRl9DT1VOVF9TV19QQUdFX0ZBVUxUUzoKCWNhc2UgUEVSRl9DT1VOVF9TV19QQUdFX0ZBVUxUU19NSU46CgljYXNlIFBFUkZfQ09VTlRfU1dfUEFHRV9GQVVMVFNfTUFKOgoJY2FzZSBQRVJGX0NPVU5UX1NXX0NPTlRFWFRfU1dJVENIRVM6CgljYXNlIFBFUkZfQ09VTlRfU1dfQ1BVX01JR1JBVElPTlM6CgkJaWYgKCFldmVudC0+cGFyZW50KSB7CgkJCWF0b21pY19pbmMoJnBlcmZfc3dldmVudF9lbmFibGVkW2V2ZW50X2lkXSk7CgkJCWV2ZW50LT5kZXN0cm95ID0gc3dfcGVyZl9ldmVudF9kZXN0cm95OwoJCX0KCQlwbXUgPSAmcGVyZl9vcHNfZ2VuZXJpYzsKCQlicmVhazsKCX0KCglyZXR1cm4gcG11Owp9CgovKgogKiBBbGxvY2F0ZSBhbmQgaW5pdGlhbGl6ZSBhIGV2ZW50IHN0cnVjdHVyZQogKi8Kc3RhdGljIHN0cnVjdCBwZXJmX2V2ZW50ICoKcGVyZl9ldmVudF9hbGxvYyhzdHJ1Y3QgcGVyZl9ldmVudF9hdHRyICphdHRyLAoJCSAgIGludCBjcHUsCgkJICAgc3RydWN0IHBlcmZfZXZlbnRfY29udGV4dCAqY3R4LAoJCSAgIHN0cnVjdCBwZXJmX2V2ZW50ICpncm91cF9sZWFkZXIsCgkJICAgc3RydWN0IHBlcmZfZXZlbnQgKnBhcmVudF9ldmVudCwKCQkgICBnZnBfdCBnZnBmbGFncykKewoJY29uc3Qgc3RydWN0IHBtdSAqcG11OwoJc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50OwoJc3RydWN0IGh3X3BlcmZfZXZlbnQgKmh3YzsKCWxvbmcgZXJyOwoKCWV2ZW50ID0ga3phbGxvYyhzaXplb2YoKmV2ZW50KSwgZ2ZwZmxhZ3MpOwoJaWYgKCFldmVudCkKCQlyZXR1cm4gRVJSX1BUUigtRU5PTUVNKTsKCgkvKgoJICogU2luZ2xlIGV2ZW50cyBhcmUgdGhlaXIgb3duIGdyb3VwIGxlYWRlcnMsIHdpdGggYW4KCSAqIGVtcHR5IHNpYmxpbmcgbGlzdDoKCSAqLwoJaWYgKCFncm91cF9sZWFkZXIpCgkJZ3JvdXBfbGVhZGVyID0gZXZlbnQ7CgoJbXV0ZXhfaW5pdCgmZXZlbnQtPmNoaWxkX211dGV4KTsKCUlOSVRfTElTVF9IRUFEKCZldmVudC0+Y2hpbGRfbGlzdCk7CgoJSU5JVF9MSVNUX0hFQUQoJmV2ZW50LT5ncm91cF9lbnRyeSk7CglJTklUX0xJU1RfSEVBRCgmZXZlbnQtPmV2ZW50X2VudHJ5KTsKCUlOSVRfTElTVF9IRUFEKCZldmVudC0+c2libGluZ19saXN0KTsKCWluaXRfd2FpdHF1ZXVlX2hlYWQoJmV2ZW50LT53YWl0cSk7CgoJbXV0ZXhfaW5pdCgmZXZlbnQtPm1tYXBfbXV0ZXgpOwoKCWV2ZW50LT5jcHUJCT0gY3B1OwoJZXZlbnQtPmF0dHIJCT0gKmF0dHI7CglldmVudC0+Z3JvdXBfbGVhZGVyCT0gZ3JvdXBfbGVhZGVyOwoJZXZlbnQtPnBtdQkJPSBOVUxMOwoJZXZlbnQtPmN0eAkJPSBjdHg7CglldmVudC0+b25jcHUJCT0gLTE7CgoJZXZlbnQtPnBhcmVudAkJPSBwYXJlbnRfZXZlbnQ7CgoJZXZlbnQtPm5zCQk9IGdldF9waWRfbnMoY3VycmVudC0+bnNwcm94eS0+cGlkX25zKTsKCWV2ZW50LT5pZAkJPSBhdG9taWM2NF9pbmNfcmV0dXJuKCZwZXJmX2V2ZW50X2lkKTsKCglldmVudC0+c3RhdGUJCT0gUEVSRl9FVkVOVF9TVEFURV9JTkFDVElWRTsKCglpZiAoYXR0ci0+ZGlzYWJsZWQpCgkJZXZlbnQtPnN0YXRlID0gUEVSRl9FVkVOVF9TVEFURV9PRkY7CgoJcG11ID0gTlVMTDsKCglod2MgPSAmZXZlbnQtPmh3OwoJaHdjLT5zYW1wbGVfcGVyaW9kID0gYXR0ci0+c2FtcGxlX3BlcmlvZDsKCWlmIChhdHRyLT5mcmVxICYmIGF0dHItPnNhbXBsZV9mcmVxKQoJCWh3Yy0+c2FtcGxlX3BlcmlvZCA9IDE7Cglod2MtPmxhc3RfcGVyaW9kID0gaHdjLT5zYW1wbGVfcGVyaW9kOwoKCWF0b21pYzY0X3NldCgmaHdjLT5wZXJpb2RfbGVmdCwgaHdjLT5zYW1wbGVfcGVyaW9kKTsKCgkvKgoJICogd2UgY3VycmVudGx5IGRvIG5vdCBzdXBwb3J0IFBFUkZfRk9STUFUX0dST1VQIG9uIGluaGVyaXRlZCBldmVudHMKCSAqLwoJaWYgKGF0dHItPmluaGVyaXQgJiYgKGF0dHItPnJlYWRfZm9ybWF0ICYgUEVSRl9GT1JNQVRfR1JPVVApKQoJCWdvdG8gZG9uZTsKCglzd2l0Y2ggKGF0dHItPnR5cGUpIHsKCWNhc2UgUEVSRl9UWVBFX1JBVzoKCWNhc2UgUEVSRl9UWVBFX0hBUkRXQVJFOgoJY2FzZSBQRVJGX1RZUEVfSFdfQ0FDSEU6CgkJcG11ID0gaHdfcGVyZl9ldmVudF9pbml0KGV2ZW50KTsKCQlicmVhazsKCgljYXNlIFBFUkZfVFlQRV9TT0ZUV0FSRToKCQlwbXUgPSBzd19wZXJmX2V2ZW50X2luaXQoZXZlbnQpOwoJCWJyZWFrOwoKCWNhc2UgUEVSRl9UWVBFX1RSQUNFUE9JTlQ6CgkJcG11ID0gdHBfcGVyZl9ldmVudF9pbml0KGV2ZW50KTsKCQlicmVhazsKCglkZWZhdWx0OgoJCWJyZWFrOwoJfQpkb25lOgoJZXJyID0gMDsKCWlmICghcG11KQoJCWVyciA9IC1FSU5WQUw7CgllbHNlIGlmIChJU19FUlIocG11KSkKCQllcnIgPSBQVFJfRVJSKHBtdSk7CgoJaWYgKGVycikgewoJCWlmIChldmVudC0+bnMpCgkJCXB1dF9waWRfbnMoZXZlbnQtPm5zKTsKCQlrZnJlZShldmVudCk7CgkJcmV0dXJuIEVSUl9QVFIoZXJyKTsKCX0KCglldmVudC0+cG11ID0gcG11OwoKCWlmICghZXZlbnQtPnBhcmVudCkgewoJCWF0b21pY19pbmMoJm5yX2V2ZW50cyk7CgkJaWYgKGV2ZW50LT5hdHRyLm1tYXApCgkJCWF0b21pY19pbmMoJm5yX21tYXBfZXZlbnRzKTsKCQlpZiAoZXZlbnQtPmF0dHIuY29tbSkKCQkJYXRvbWljX2luYygmbnJfY29tbV9ldmVudHMpOwoJCWlmIChldmVudC0+YXR0ci50YXNrKQoJCQlhdG9taWNfaW5jKCZucl90YXNrX2V2ZW50cyk7Cgl9CgoJcmV0dXJuIGV2ZW50Owp9CgpzdGF0aWMgaW50IHBlcmZfY29weV9hdHRyKHN0cnVjdCBwZXJmX2V2ZW50X2F0dHIgX191c2VyICp1YXR0ciwKCQkJICBzdHJ1Y3QgcGVyZl9ldmVudF9hdHRyICphdHRyKQp7Cgl1MzIgc2l6ZTsKCWludCByZXQ7CgoJaWYgKCFhY2Nlc3Nfb2soVkVSSUZZX1dSSVRFLCB1YXR0ciwgUEVSRl9BVFRSX1NJWkVfVkVSMCkpCgkJcmV0dXJuIC1FRkFVTFQ7CgoJLyoKCSAqIHplcm8gdGhlIGZ1bGwgc3RydWN0dXJlLCBzbyB0aGF0IGEgc2hvcnQgY29weSB3aWxsIGJlIG5pY2UuCgkgKi8KCW1lbXNldChhdHRyLCAwLCBzaXplb2YoKmF0dHIpKTsKCglyZXQgPSBnZXRfdXNlcihzaXplLCAmdWF0dHItPnNpemUpOwoJaWYgKHJldCkKCQlyZXR1cm4gcmV0OwoKCWlmIChzaXplID4gUEFHRV9TSVpFKQkvKiBzaWxseSBsYXJnZSAqLwoJCWdvdG8gZXJyX3NpemU7CgoJaWYgKCFzaXplKQkJLyogYWJpIGNvbXBhdCAqLwoJCXNpemUgPSBQRVJGX0FUVFJfU0laRV9WRVIwOwoKCWlmIChzaXplIDwgUEVSRl9BVFRSX1NJWkVfVkVSMCkKCQlnb3RvIGVycl9zaXplOwoKCS8qCgkgKiBJZiB3ZSdyZSBoYW5kZWQgYSBiaWdnZXIgc3RydWN0IHRoYW4gd2Uga25vdyBvZiwKCSAqIGVuc3VyZSBhbGwgdGhlIHVua25vd24gYml0cyBhcmUgMCAtIGkuZS4gbmV3CgkgKiB1c2VyLXNwYWNlIGRvZXMgbm90IHJlbHkgb24gYW55IGtlcm5lbCBmZWF0dXJlCgkgKiBleHRlbnNpb25zIHdlIGRvbnQga25vdyBhYm91dCB5ZXQuCgkgKi8KCWlmIChzaXplID4gc2l6ZW9mKCphdHRyKSkgewoJCXVuc2lnbmVkIGNoYXIgX191c2VyICphZGRyOwoJCXVuc2lnbmVkIGNoYXIgX191c2VyICplbmQ7CgkJdW5zaWduZWQgY2hhciB2YWw7CgoJCWFkZHIgPSAodm9pZCBfX3VzZXIgKil1YXR0ciArIHNpemVvZigqYXR0cik7CgkJZW5kICA9ICh2b2lkIF9fdXNlciAqKXVhdHRyICsgc2l6ZTsKCgkJZm9yICg7IGFkZHIgPCBlbmQ7IGFkZHIrKykgewoJCQlyZXQgPSBnZXRfdXNlcih2YWwsIGFkZHIpOwoJCQlpZiAocmV0KQoJCQkJcmV0dXJuIHJldDsKCQkJaWYgKHZhbCkKCQkJCWdvdG8gZXJyX3NpemU7CgkJfQoJCXNpemUgPSBzaXplb2YoKmF0dHIpOwoJfQoKCXJldCA9IGNvcHlfZnJvbV91c2VyKGF0dHIsIHVhdHRyLCBzaXplKTsKCWlmIChyZXQpCgkJcmV0dXJuIC1FRkFVTFQ7CgoJLyoKCSAqIElmIHRoZSB0eXBlIGV4aXN0cywgdGhlIGNvcnJlc3BvbmRpbmcgY3JlYXRpb24gd2lsbCB2ZXJpZnkKCSAqIHRoZSBhdHRyLT5jb25maWcuCgkgKi8KCWlmIChhdHRyLT50eXBlID49IFBFUkZfVFlQRV9NQVgpCgkJcmV0dXJuIC1FSU5WQUw7CgoJaWYgKGF0dHItPl9fcmVzZXJ2ZWRfMSB8fCBhdHRyLT5fX3Jlc2VydmVkXzIgfHwgYXR0ci0+X19yZXNlcnZlZF8zKQoJCXJldHVybiAtRUlOVkFMOwoKCWlmIChhdHRyLT5zYW1wbGVfdHlwZSAmIH4oUEVSRl9TQU1QTEVfTUFYLTEpKQoJCXJldHVybiAtRUlOVkFMOwoKCWlmIChhdHRyLT5yZWFkX2Zvcm1hdCAmIH4oUEVSRl9GT1JNQVRfTUFYLTEpKQoJCXJldHVybiAtRUlOVkFMOwoKb3V0OgoJcmV0dXJuIHJldDsKCmVycl9zaXplOgoJcHV0X3VzZXIoc2l6ZW9mKCphdHRyKSwgJnVhdHRyLT5zaXplKTsKCXJldCA9IC1FMkJJRzsKCWdvdG8gb3V0Owp9CgppbnQgcGVyZl9ldmVudF9zZXRfb3V0cHV0KHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCwgaW50IG91dHB1dF9mZCkKewoJc3RydWN0IHBlcmZfZXZlbnQgKm91dHB1dF9ldmVudCA9IE5VTEw7CglzdHJ1Y3QgZmlsZSAqb3V0cHV0X2ZpbGUgPSBOVUxMOwoJc3RydWN0IHBlcmZfZXZlbnQgKm9sZF9vdXRwdXQ7CglpbnQgZnB1dF9uZWVkZWQgPSAwOwoJaW50IHJldCA9IC1FSU5WQUw7CgoJaWYgKCFvdXRwdXRfZmQpCgkJZ290byBzZXQ7CgoJb3V0cHV0X2ZpbGUgPSBmZ2V0X2xpZ2h0KG91dHB1dF9mZCwgJmZwdXRfbmVlZGVkKTsKCWlmICghb3V0cHV0X2ZpbGUpCgkJcmV0dXJuIC1FQkFERjsKCglpZiAob3V0cHV0X2ZpbGUtPmZfb3AgIT0gJnBlcmZfZm9wcykKCQlnb3RvIG91dDsKCglvdXRwdXRfZXZlbnQgPSBvdXRwdXRfZmlsZS0+cHJpdmF0ZV9kYXRhOwoKCS8qIERvbid0IGNoYWluIG91dHB1dCBmZHMgKi8KCWlmIChvdXRwdXRfZXZlbnQtPm91dHB1dCkKCQlnb3RvIG91dDsKCgkvKiBEb24ndCBzZXQgYW4gb3V0cHV0IGZkIHdoZW4gd2UgYWxyZWFkeSBoYXZlIGFuIG91dHB1dCBjaGFubmVsICovCglpZiAoZXZlbnQtPmRhdGEpCgkJZ290byBvdXQ7CgoJYXRvbWljX2xvbmdfaW5jKCZvdXRwdXRfZmlsZS0+Zl9jb3VudCk7CgpzZXQ6CgltdXRleF9sb2NrKCZldmVudC0+bW1hcF9tdXRleCk7CglvbGRfb3V0cHV0ID0gZXZlbnQtPm91dHB1dDsKCXJjdV9hc3NpZ25fcG9pbnRlcihldmVudC0+b3V0cHV0LCBvdXRwdXRfZXZlbnQpOwoJbXV0ZXhfdW5sb2NrKCZldmVudC0+bW1hcF9tdXRleCk7CgoJaWYgKG9sZF9vdXRwdXQpIHsKCQkvKgoJCSAqIHdlIG5lZWQgdG8gbWFrZSBzdXJlIG5vIGV4aXN0aW5nIHBlcmZfb3V0cHV0XyooKQoJCSAqIGlzIHN0aWxsIHJlZmVyZW5jaW5nIHRoaXMgZXZlbnQuCgkJICovCgkJc3luY2hyb25pemVfcmN1KCk7CgkJZnB1dChvbGRfb3V0cHV0LT5maWxwKTsKCX0KCglyZXQgPSAwOwpvdXQ6CglmcHV0X2xpZ2h0KG91dHB1dF9maWxlLCBmcHV0X25lZWRlZCk7CglyZXR1cm4gcmV0Owp9CgovKioKICogc3lzX3BlcmZfZXZlbnRfb3BlbiAtIG9wZW4gYSBwZXJmb3JtYW5jZSBldmVudCwgYXNzb2NpYXRlIGl0IHRvIGEgdGFzay9jcHUKICoKICogQGF0dHJfdXB0cjoJZXZlbnRfaWQgdHlwZSBhdHRyaWJ1dGVzIGZvciBtb25pdG9yaW5nL3NhbXBsaW5nCiAqIEBwaWQ6CQl0YXJnZXQgcGlkCiAqIEBjcHU6CQl0YXJnZXQgY3B1CiAqIEBncm91cF9mZDoJCWdyb3VwIGxlYWRlciBldmVudCBmZAogKi8KU1lTQ0FMTF9ERUZJTkU1KHBlcmZfZXZlbnRfb3BlbiwKCQlzdHJ1Y3QgcGVyZl9ldmVudF9hdHRyIF9fdXNlciAqLCBhdHRyX3VwdHIsCgkJcGlkX3QsIHBpZCwgaW50LCBjcHUsIGludCwgZ3JvdXBfZmQsIHVuc2lnbmVkIGxvbmcsIGZsYWdzKQp7CglzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQsICpncm91cF9sZWFkZXI7CglzdHJ1Y3QgcGVyZl9ldmVudF9hdHRyIGF0dHI7CglzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0ICpjdHg7CglzdHJ1Y3QgZmlsZSAqZXZlbnRfZmlsZSA9IE5VTEw7CglzdHJ1Y3QgZmlsZSAqZ3JvdXBfZmlsZSA9IE5VTEw7CglpbnQgZnB1dF9uZWVkZWQgPSAwOwoJaW50IGZwdXRfbmVlZGVkMiA9IDA7CglpbnQgZXJyOwoKCS8qIGZvciBmdXR1cmUgZXhwYW5kYWJpbGl0eS4uLiAqLwoJaWYgKGZsYWdzICYgfihQRVJGX0ZMQUdfRkRfTk9fR1JPVVAgfCBQRVJGX0ZMQUdfRkRfT1VUUFVUKSkKCQlyZXR1cm4gLUVJTlZBTDsKCgllcnIgPSBwZXJmX2NvcHlfYXR0cihhdHRyX3VwdHIsICZhdHRyKTsKCWlmIChlcnIpCgkJcmV0dXJuIGVycjsKCglpZiAoIWF0dHIuZXhjbHVkZV9rZXJuZWwpIHsKCQlpZiAocGVyZl9wYXJhbm9pZF9rZXJuZWwoKSAmJiAhY2FwYWJsZShDQVBfU1lTX0FETUlOKSkKCQkJcmV0dXJuIC1FQUNDRVM7Cgl9CgoJaWYgKGF0dHIuZnJlcSkgewoJCWlmIChhdHRyLnNhbXBsZV9mcmVxID4gc3lzY3RsX3BlcmZfZXZlbnRfc2FtcGxlX3JhdGUpCgkJCXJldHVybiAtRUlOVkFMOwoJfQoKCS8qCgkgKiBHZXQgdGhlIHRhcmdldCBjb250ZXh0ICh0YXNrIG9yIHBlcmNwdSk6CgkgKi8KCWN0eCA9IGZpbmRfZ2V0X2NvbnRleHQocGlkLCBjcHUpOwoJaWYgKElTX0VSUihjdHgpKQoJCXJldHVybiBQVFJfRVJSKGN0eCk7CgoJLyoKCSAqIExvb2sgdXAgdGhlIGdyb3VwIGxlYWRlciAod2Ugd2lsbCBhdHRhY2ggdGhpcyBldmVudCB0byBpdCk6CgkgKi8KCWdyb3VwX2xlYWRlciA9IE5VTEw7CglpZiAoZ3JvdXBfZmQgIT0gLTEgJiYgIShmbGFncyAmIFBFUkZfRkxBR19GRF9OT19HUk9VUCkpIHsKCQllcnIgPSAtRUlOVkFMOwoJCWdyb3VwX2ZpbGUgPSBmZ2V0X2xpZ2h0KGdyb3VwX2ZkLCAmZnB1dF9uZWVkZWQpOwoJCWlmICghZ3JvdXBfZmlsZSkKCQkJZ290byBlcnJfcHV0X2NvbnRleHQ7CgkJaWYgKGdyb3VwX2ZpbGUtPmZfb3AgIT0gJnBlcmZfZm9wcykKCQkJZ290byBlcnJfcHV0X2NvbnRleHQ7CgoJCWdyb3VwX2xlYWRlciA9IGdyb3VwX2ZpbGUtPnByaXZhdGVfZGF0YTsKCQkvKgoJCSAqIERvIG5vdCBhbGxvdyBhIHJlY3Vyc2l2ZSBoaWVyYXJjaHkgKHRoaXMgbmV3IHNpYmxpbmcKCQkgKiBiZWNvbWluZyBwYXJ0IG9mIGFub3RoZXIgZ3JvdXAtc2libGluZyk6CgkJICovCgkJaWYgKGdyb3VwX2xlYWRlci0+Z3JvdXBfbGVhZGVyICE9IGdyb3VwX2xlYWRlcikKCQkJZ290byBlcnJfcHV0X2NvbnRleHQ7CgkJLyoKCQkgKiBEbyBub3QgYWxsb3cgdG8gYXR0YWNoIHRvIGEgZ3JvdXAgaW4gYSBkaWZmZXJlbnQKCQkgKiB0YXNrIG9yIENQVSBjb250ZXh0OgoJCSAqLwoJCWlmIChncm91cF9sZWFkZXItPmN0eCAhPSBjdHgpCgkJCWdvdG8gZXJyX3B1dF9jb250ZXh0OwoJCS8qCgkJICogT25seSBhIGdyb3VwIGxlYWRlciBjYW4gYmUgZXhjbHVzaXZlIG9yIHBpbm5lZAoJCSAqLwoJCWlmIChhdHRyLmV4Y2x1c2l2ZSB8fCBhdHRyLnBpbm5lZCkKCQkJZ290byBlcnJfcHV0X2NvbnRleHQ7Cgl9CgoJZXZlbnQgPSBwZXJmX2V2ZW50X2FsbG9jKCZhdHRyLCBjcHUsIGN0eCwgZ3JvdXBfbGVhZGVyLAoJCQkJICAgICBOVUxMLCBHRlBfS0VSTkVMKTsKCWVyciA9IFBUUl9FUlIoZXZlbnQpOwoJaWYgKElTX0VSUihldmVudCkpCgkJZ290byBlcnJfcHV0X2NvbnRleHQ7CgoJZXJyID0gYW5vbl9pbm9kZV9nZXRmZCgiW3BlcmZfZXZlbnRdIiwgJnBlcmZfZm9wcywgZXZlbnQsIDApOwoJaWYgKGVyciA8IDApCgkJZ290byBlcnJfZnJlZV9wdXRfY29udGV4dDsKCglldmVudF9maWxlID0gZmdldF9saWdodChlcnIsICZmcHV0X25lZWRlZDIpOwoJaWYgKCFldmVudF9maWxlKQoJCWdvdG8gZXJyX2ZyZWVfcHV0X2NvbnRleHQ7CgoJaWYgKGZsYWdzICYgUEVSRl9GTEFHX0ZEX09VVFBVVCkgewoJCWVyciA9IHBlcmZfZXZlbnRfc2V0X291dHB1dChldmVudCwgZ3JvdXBfZmQpOwoJCWlmIChlcnIpCgkJCWdvdG8gZXJyX2ZwdXRfZnJlZV9wdXRfY29udGV4dDsKCX0KCglldmVudC0+ZmlscCA9IGV2ZW50X2ZpbGU7CglXQVJOX09OX09OQ0UoY3R4LT5wYXJlbnRfY3R4KTsKCW11dGV4X2xvY2soJmN0eC0+bXV0ZXgpOwoJcGVyZl9pbnN0YWxsX2luX2NvbnRleHQoY3R4LCBldmVudCwgY3B1KTsKCSsrY3R4LT5nZW5lcmF0aW9uOwoJbXV0ZXhfdW5sb2NrKCZjdHgtPm11dGV4KTsKCglldmVudC0+b3duZXIgPSBjdXJyZW50OwoJZ2V0X3Rhc2tfc3RydWN0KGN1cnJlbnQpOwoJbXV0ZXhfbG9jaygmY3VycmVudC0+cGVyZl9ldmVudF9tdXRleCk7CglsaXN0X2FkZF90YWlsKCZldmVudC0+b3duZXJfZW50cnksICZjdXJyZW50LT5wZXJmX2V2ZW50X2xpc3QpOwoJbXV0ZXhfdW5sb2NrKCZjdXJyZW50LT5wZXJmX2V2ZW50X211dGV4KTsKCmVycl9mcHV0X2ZyZWVfcHV0X2NvbnRleHQ6CglmcHV0X2xpZ2h0KGV2ZW50X2ZpbGUsIGZwdXRfbmVlZGVkMik7CgplcnJfZnJlZV9wdXRfY29udGV4dDoKCWlmIChlcnIgPCAwKQoJCWtmcmVlKGV2ZW50KTsKCmVycl9wdXRfY29udGV4dDoKCWlmIChlcnIgPCAwKQoJCXB1dF9jdHgoY3R4KTsKCglmcHV0X2xpZ2h0KGdyb3VwX2ZpbGUsIGZwdXRfbmVlZGVkKTsKCglyZXR1cm4gZXJyOwp9CgovKgogKiBpbmhlcml0IGEgZXZlbnQgZnJvbSBwYXJlbnQgdGFzayB0byBjaGlsZCB0YXNrOgogKi8Kc3RhdGljIHN0cnVjdCBwZXJmX2V2ZW50ICoKaW5oZXJpdF9ldmVudChzdHJ1Y3QgcGVyZl9ldmVudCAqcGFyZW50X2V2ZW50LAoJICAgICAgc3RydWN0IHRhc2tfc3RydWN0ICpwYXJlbnQsCgkgICAgICBzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0ICpwYXJlbnRfY3R4LAoJICAgICAgc3RydWN0IHRhc2tfc3RydWN0ICpjaGlsZCwKCSAgICAgIHN0cnVjdCBwZXJmX2V2ZW50ICpncm91cF9sZWFkZXIsCgkgICAgICBzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0ICpjaGlsZF9jdHgpCnsKCXN0cnVjdCBwZXJmX2V2ZW50ICpjaGlsZF9ldmVudDsKCgkvKgoJICogSW5zdGVhZCBvZiBjcmVhdGluZyByZWN1cnNpdmUgaGllcmFyY2hpZXMgb2YgZXZlbnRzLAoJICogd2UgbGluayBpbmhlcml0ZWQgZXZlbnRzIGJhY2sgdG8gdGhlIG9yaWdpbmFsIHBhcmVudCwKCSAqIHdoaWNoIGhhcyBhIGZpbHAgZm9yIHN1cmUsIHdoaWNoIHdlIHVzZSBhcyB0aGUgcmVmZXJlbmNlCgkgKiBjb3VudDoKCSAqLwoJaWYgKHBhcmVudF9ldmVudC0+cGFyZW50KQoJCXBhcmVudF9ldmVudCA9IHBhcmVudF9ldmVudC0+cGFyZW50OwoKCWNoaWxkX2V2ZW50ID0gcGVyZl9ldmVudF9hbGxvYygmcGFyZW50X2V2ZW50LT5hdHRyLAoJCQkJCSAgIHBhcmVudF9ldmVudC0+Y3B1LCBjaGlsZF9jdHgsCgkJCQkJICAgZ3JvdXBfbGVhZGVyLCBwYXJlbnRfZXZlbnQsCgkJCQkJICAgR0ZQX0tFUk5FTCk7CglpZiAoSVNfRVJSKGNoaWxkX2V2ZW50KSkKCQlyZXR1cm4gY2hpbGRfZXZlbnQ7CglnZXRfY3R4KGNoaWxkX2N0eCk7CgoJLyoKCSAqIE1ha2UgdGhlIGNoaWxkIHN0YXRlIGZvbGxvdyB0aGUgc3RhdGUgb2YgdGhlIHBhcmVudCBldmVudCwKCSAqIG5vdCBpdHMgYXR0ci5kaXNhYmxlZCBiaXQuICBXZSBob2xkIHRoZSBwYXJlbnQncyBtdXRleCwKCSAqIHNvIHdlIHdvbid0IHJhY2Ugd2l0aCBwZXJmX2V2ZW50X3tlbiwgZGlzfWFibGVfZmFtaWx5LgoJICovCglpZiAocGFyZW50X2V2ZW50LT5zdGF0ZSA+PSBQRVJGX0VWRU5UX1NUQVRFX0lOQUNUSVZFKQoJCWNoaWxkX2V2ZW50LT5zdGF0ZSA9IFBFUkZfRVZFTlRfU1RBVEVfSU5BQ1RJVkU7CgllbHNlCgkJY2hpbGRfZXZlbnQtPnN0YXRlID0gUEVSRl9FVkVOVF9TVEFURV9PRkY7CgoJaWYgKHBhcmVudF9ldmVudC0+YXR0ci5mcmVxKQoJCWNoaWxkX2V2ZW50LT5ody5zYW1wbGVfcGVyaW9kID0gcGFyZW50X2V2ZW50LT5ody5zYW1wbGVfcGVyaW9kOwoKCS8qCgkgKiBMaW5rIGl0IHVwIGluIHRoZSBjaGlsZCdzIGNvbnRleHQ6CgkgKi8KCWFkZF9ldmVudF90b19jdHgoY2hpbGRfZXZlbnQsIGNoaWxkX2N0eCk7CgoJLyoKCSAqIEdldCBhIHJlZmVyZW5jZSB0byB0aGUgcGFyZW50IGZpbHAgLSB3ZSB3aWxsIGZwdXQgaXQKCSAqIHdoZW4gdGhlIGNoaWxkIGV2ZW50IGV4aXRzLiBUaGlzIGlzIHNhZmUgdG8gZG8gYmVjYXVzZQoJICogd2UgYXJlIGluIHRoZSBwYXJlbnQgYW5kIHdlIGtub3cgdGhhdCB0aGUgZmlscCBzdGlsbAoJICogZXhpc3RzIGFuZCBoYXMgYSBub256ZXJvIGNvdW50OgoJICovCglhdG9taWNfbG9uZ19pbmMoJnBhcmVudF9ldmVudC0+ZmlscC0+Zl9jb3VudCk7CgoJLyoKCSAqIExpbmsgdGhpcyBpbnRvIHRoZSBwYXJlbnQgZXZlbnQncyBjaGlsZCBsaXN0CgkgKi8KCVdBUk5fT05fT05DRShwYXJlbnRfZXZlbnQtPmN0eC0+cGFyZW50X2N0eCk7CgltdXRleF9sb2NrKCZwYXJlbnRfZXZlbnQtPmNoaWxkX211dGV4KTsKCWxpc3RfYWRkX3RhaWwoJmNoaWxkX2V2ZW50LT5jaGlsZF9saXN0LCAmcGFyZW50X2V2ZW50LT5jaGlsZF9saXN0KTsKCW11dGV4X3VubG9jaygmcGFyZW50X2V2ZW50LT5jaGlsZF9tdXRleCk7CgoJcmV0dXJuIGNoaWxkX2V2ZW50Owp9CgpzdGF0aWMgaW50IGluaGVyaXRfZ3JvdXAoc3RydWN0IHBlcmZfZXZlbnQgKnBhcmVudF9ldmVudCwKCSAgICAgIHN0cnVjdCB0YXNrX3N0cnVjdCAqcGFyZW50LAoJICAgICAgc3RydWN0IHBlcmZfZXZlbnRfY29udGV4dCAqcGFyZW50X2N0eCwKCSAgICAgIHN0cnVjdCB0YXNrX3N0cnVjdCAqY2hpbGQsCgkgICAgICBzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0ICpjaGlsZF9jdHgpCnsKCXN0cnVjdCBwZXJmX2V2ZW50ICpsZWFkZXI7CglzdHJ1Y3QgcGVyZl9ldmVudCAqc3ViOwoJc3RydWN0IHBlcmZfZXZlbnQgKmNoaWxkX2N0cjsKCglsZWFkZXIgPSBpbmhlcml0X2V2ZW50KHBhcmVudF9ldmVudCwgcGFyZW50LCBwYXJlbnRfY3R4LAoJCQkJIGNoaWxkLCBOVUxMLCBjaGlsZF9jdHgpOwoJaWYgKElTX0VSUihsZWFkZXIpKQoJCXJldHVybiBQVFJfRVJSKGxlYWRlcik7CglsaXN0X2Zvcl9lYWNoX2VudHJ5KHN1YiwgJnBhcmVudF9ldmVudC0+c2libGluZ19saXN0LCBncm91cF9lbnRyeSkgewoJCWNoaWxkX2N0ciA9IGluaGVyaXRfZXZlbnQoc3ViLCBwYXJlbnQsIHBhcmVudF9jdHgsCgkJCQkJICAgIGNoaWxkLCBsZWFkZXIsIGNoaWxkX2N0eCk7CgkJaWYgKElTX0VSUihjaGlsZF9jdHIpKQoJCQlyZXR1cm4gUFRSX0VSUihjaGlsZF9jdHIpOwoJfQoJcmV0dXJuIDA7Cn0KCnN0YXRpYyB2b2lkIHN5bmNfY2hpbGRfZXZlbnQoc3RydWN0IHBlcmZfZXZlbnQgKmNoaWxkX2V2ZW50LAoJCQkgICAgICAgc3RydWN0IHRhc2tfc3RydWN0ICpjaGlsZCkKewoJc3RydWN0IHBlcmZfZXZlbnQgKnBhcmVudF9ldmVudCA9IGNoaWxkX2V2ZW50LT5wYXJlbnQ7Cgl1NjQgY2hpbGRfdmFsOwoKCWlmIChjaGlsZF9ldmVudC0+YXR0ci5pbmhlcml0X3N0YXQpCgkJcGVyZl9ldmVudF9yZWFkX2V2ZW50KGNoaWxkX2V2ZW50LCBjaGlsZCk7CgoJY2hpbGRfdmFsID0gYXRvbWljNjRfcmVhZCgmY2hpbGRfZXZlbnQtPmNvdW50KTsKCgkvKgoJICogQWRkIGJhY2sgdGhlIGNoaWxkJ3MgY291bnQgdG8gdGhlIHBhcmVudCdzIGNvdW50OgoJICovCglhdG9taWM2NF9hZGQoY2hpbGRfdmFsLCAmcGFyZW50X2V2ZW50LT5jb3VudCk7CglhdG9taWM2NF9hZGQoY2hpbGRfZXZlbnQtPnRvdGFsX3RpbWVfZW5hYmxlZCwKCQkgICAgICZwYXJlbnRfZXZlbnQtPmNoaWxkX3RvdGFsX3RpbWVfZW5hYmxlZCk7CglhdG9taWM2NF9hZGQoY2hpbGRfZXZlbnQtPnRvdGFsX3RpbWVfcnVubmluZywKCQkgICAgICZwYXJlbnRfZXZlbnQtPmNoaWxkX3RvdGFsX3RpbWVfcnVubmluZyk7CgoJLyoKCSAqIFJlbW92ZSB0aGlzIGV2ZW50IGZyb20gdGhlIHBhcmVudCdzIGxpc3QKCSAqLwoJV0FSTl9PTl9PTkNFKHBhcmVudF9ldmVudC0+Y3R4LT5wYXJlbnRfY3R4KTsKCW11dGV4X2xvY2soJnBhcmVudF9ldmVudC0+Y2hpbGRfbXV0ZXgpOwoJbGlzdF9kZWxfaW5pdCgmY2hpbGRfZXZlbnQtPmNoaWxkX2xpc3QpOwoJbXV0ZXhfdW5sb2NrKCZwYXJlbnRfZXZlbnQtPmNoaWxkX211dGV4KTsKCgkvKgoJICogUmVsZWFzZSB0aGUgcGFyZW50IGV2ZW50LCBpZiB0aGlzIHdhcyB0aGUgbGFzdAoJICogcmVmZXJlbmNlIHRvIGl0LgoJICovCglmcHV0KHBhcmVudF9ldmVudC0+ZmlscCk7Cn0KCnN0YXRpYyB2b2lkCl9fcGVyZl9ldmVudF9leGl0X3Rhc2soc3RydWN0IHBlcmZfZXZlbnQgKmNoaWxkX2V2ZW50LAoJCQkgc3RydWN0IHBlcmZfZXZlbnRfY29udGV4dCAqY2hpbGRfY3R4LAoJCQkgc3RydWN0IHRhc2tfc3RydWN0ICpjaGlsZCkKewoJc3RydWN0IHBlcmZfZXZlbnQgKnBhcmVudF9ldmVudDsKCgl1cGRhdGVfZXZlbnRfdGltZXMoY2hpbGRfZXZlbnQpOwoJcGVyZl9ldmVudF9yZW1vdmVfZnJvbV9jb250ZXh0KGNoaWxkX2V2ZW50KTsKCglwYXJlbnRfZXZlbnQgPSBjaGlsZF9ldmVudC0+cGFyZW50OwoJLyoKCSAqIEl0IGNhbiBoYXBwZW4gdGhhdCBwYXJlbnQgZXhpdHMgZmlyc3QsIGFuZCBoYXMgZXZlbnRzCgkgKiB0aGF0IGFyZSBzdGlsbCBhcm91bmQgZHVlIHRvIHRoZSBjaGlsZCByZWZlcmVuY2UuIFRoZXNlCgkgKiBldmVudHMgbmVlZCB0byBiZSB6YXBwZWQgLSBidXQgb3RoZXJ3aXNlIGxpbmdlci4KCSAqLwoJaWYgKHBhcmVudF9ldmVudCkgewoJCXN5bmNfY2hpbGRfZXZlbnQoY2hpbGRfZXZlbnQsIGNoaWxkKTsKCQlmcmVlX2V2ZW50KGNoaWxkX2V2ZW50KTsKCX0KfQoKLyoKICogV2hlbiBhIGNoaWxkIHRhc2sgZXhpdHMsIGZlZWQgYmFjayBldmVudCB2YWx1ZXMgdG8gcGFyZW50IGV2ZW50cy4KICovCnZvaWQgcGVyZl9ldmVudF9leGl0X3Rhc2soc3RydWN0IHRhc2tfc3RydWN0ICpjaGlsZCkKewoJc3RydWN0IHBlcmZfZXZlbnQgKmNoaWxkX2V2ZW50LCAqdG1wOwoJc3RydWN0IHBlcmZfZXZlbnRfY29udGV4dCAqY2hpbGRfY3R4OwoJdW5zaWduZWQgbG9uZyBmbGFnczsKCglpZiAobGlrZWx5KCFjaGlsZC0+cGVyZl9ldmVudF9jdHhwKSkgewoJCXBlcmZfZXZlbnRfdGFzayhjaGlsZCwgTlVMTCwgMCk7CgkJcmV0dXJuOwoJfQoKCWxvY2FsX2lycV9zYXZlKGZsYWdzKTsKCS8qCgkgKiBXZSBjYW4ndCByZXNjaGVkdWxlIGhlcmUgYmVjYXVzZSBpbnRlcnJ1cHRzIGFyZSBkaXNhYmxlZCwKCSAqIGFuZCBlaXRoZXIgY2hpbGQgaXMgY3VycmVudCBvciBpdCBpcyBhIHRhc2sgdGhhdCBjYW4ndCBiZQoJICogc2NoZWR1bGVkLCBzbyB3ZSBhcmUgbm93IHNhZmUgZnJvbSByZXNjaGVkdWxpbmcgY2hhbmdpbmcKCSAqIG91ciBjb250ZXh0LgoJICovCgljaGlsZF9jdHggPSBjaGlsZC0+cGVyZl9ldmVudF9jdHhwOwoJX19wZXJmX2V2ZW50X3Rhc2tfc2NoZWRfb3V0KGNoaWxkX2N0eCk7CgoJLyoKCSAqIFRha2UgdGhlIGNvbnRleHQgbG9jayBoZXJlIHNvIHRoYXQgaWYgZmluZF9nZXRfY29udGV4dCBpcwoJICogcmVhZGluZyBjaGlsZC0+cGVyZl9ldmVudF9jdHhwLCB3ZSB3YWl0IHVudGlsIGl0IGhhcwoJICogaW5jcmVtZW50ZWQgdGhlIGNvbnRleHQncyByZWZjb3VudCBiZWZvcmUgd2UgZG8gcHV0X2N0eCBiZWxvdy4KCSAqLwoJc3Bpbl9sb2NrKCZjaGlsZF9jdHgtPmxvY2spOwoJY2hpbGQtPnBlcmZfZXZlbnRfY3R4cCA9IE5VTEw7CgkvKgoJICogSWYgdGhpcyBjb250ZXh0IGlzIGEgY2xvbmU7IHVuY2xvbmUgaXQgc28gaXQgY2FuJ3QgZ2V0CgkgKiBzd2FwcGVkIHRvIGFub3RoZXIgcHJvY2VzcyB3aGlsZSB3ZSdyZSByZW1vdmluZyBhbGwKCSAqIHRoZSBldmVudHMgZnJvbSBpdC4KCSAqLwoJdW5jbG9uZV9jdHgoY2hpbGRfY3R4KTsKCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJmNoaWxkX2N0eC0+bG9jaywgZmxhZ3MpOwoKCS8qCgkgKiBSZXBvcnQgdGhlIHRhc2sgZGVhZCBhZnRlciB1bnNjaGVkdWxpbmcgdGhlIGV2ZW50cyBzbyB0aGF0IHdlCgkgKiB3b24ndCBnZXQgYW55IHNhbXBsZXMgYWZ0ZXIgUEVSRl9SRUNPUkRfRVhJVC4gV2UgY2FuIGhvd2V2ZXIgc3RpbGwKCSAqIGdldCBhIGZldyBQRVJGX1JFQ09SRF9SRUFEIGV2ZW50cy4KCSAqLwoJcGVyZl9ldmVudF90YXNrKGNoaWxkLCBjaGlsZF9jdHgsIDApOwoKCS8qCgkgKiBXZSBjYW4gcmVjdXJzZSBvbiB0aGUgc2FtZSBsb2NrIHR5cGUgdGhyb3VnaDoKCSAqCgkgKiAgIF9fcGVyZl9ldmVudF9leGl0X3Rhc2soKQoJICogICAgIHN5bmNfY2hpbGRfZXZlbnQoKQoJICogICAgICAgZnB1dChwYXJlbnRfZXZlbnQtPmZpbHApCgkgKiAgICAgICAgIHBlcmZfcmVsZWFzZSgpCgkgKiAgICAgICAgICAgbXV0ZXhfbG9jaygmY3R4LT5tdXRleCkKCSAqCgkgKiBCdXQgc2luY2UgaXRzIHRoZSBwYXJlbnQgY29udGV4dCBpdCB3b24ndCBiZSB0aGUgc2FtZSBpbnN0YW5jZS4KCSAqLwoJbXV0ZXhfbG9ja19uZXN0ZWQoJmNoaWxkX2N0eC0+bXV0ZXgsIFNJTkdMRV9ERVBUSF9ORVNUSU5HKTsKCmFnYWluOgoJbGlzdF9mb3JfZWFjaF9lbnRyeV9zYWZlKGNoaWxkX2V2ZW50LCB0bXAsICZjaGlsZF9jdHgtPmdyb3VwX2xpc3QsCgkJCQkgZ3JvdXBfZW50cnkpCgkJX19wZXJmX2V2ZW50X2V4aXRfdGFzayhjaGlsZF9ldmVudCwgY2hpbGRfY3R4LCBjaGlsZCk7CgoJLyoKCSAqIElmIHRoZSBsYXN0IGV2ZW50IHdhcyBhIGdyb3VwIGV2ZW50LCBpdCB3aWxsIGhhdmUgYXBwZW5kZWQgYWxsCgkgKiBpdHMgc2libGluZ3MgdG8gdGhlIGxpc3QsIGJ1dCB3ZSBvYnRhaW5lZCAndG1wJyBiZWZvcmUgdGhhdCB3aGljaAoJICogd2lsbCBzdGlsbCBwb2ludCB0byB0aGUgbGlzdCBoZWFkIHRlcm1pbmF0aW5nIHRoZSBpdGVyYXRpb24uCgkgKi8KCWlmICghbGlzdF9lbXB0eSgmY2hpbGRfY3R4LT5ncm91cF9saXN0KSkKCQlnb3RvIGFnYWluOwoKCW11dGV4X3VubG9jaygmY2hpbGRfY3R4LT5tdXRleCk7CgoJcHV0X2N0eChjaGlsZF9jdHgpOwp9CgovKgogKiBmcmVlIGFuIHVuZXhwb3NlZCwgdW51c2VkIGNvbnRleHQgYXMgY3JlYXRlZCBieSBpbmhlcml0YW5jZSBieQogKiBpbml0X3Rhc2sgYmVsb3csIHVzZWQgYnkgZm9yaygpIGluIGNhc2Ugb2YgZmFpbC4KICovCnZvaWQgcGVyZl9ldmVudF9mcmVlX3Rhc2soc3RydWN0IHRhc2tfc3RydWN0ICp0YXNrKQp7CglzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0ICpjdHggPSB0YXNrLT5wZXJmX2V2ZW50X2N0eHA7CglzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQsICp0bXA7CgoJaWYgKCFjdHgpCgkJcmV0dXJuOwoKCW11dGV4X2xvY2soJmN0eC0+bXV0ZXgpOwphZ2FpbjoKCWxpc3RfZm9yX2VhY2hfZW50cnlfc2FmZShldmVudCwgdG1wLCAmY3R4LT5ncm91cF9saXN0LCBncm91cF9lbnRyeSkgewoJCXN0cnVjdCBwZXJmX2V2ZW50ICpwYXJlbnQgPSBldmVudC0+cGFyZW50OwoKCQlpZiAoV0FSTl9PTl9PTkNFKCFwYXJlbnQpKQoJCQljb250aW51ZTsKCgkJbXV0ZXhfbG9jaygmcGFyZW50LT5jaGlsZF9tdXRleCk7CgkJbGlzdF9kZWxfaW5pdCgmZXZlbnQtPmNoaWxkX2xpc3QpOwoJCW11dGV4X3VubG9jaygmcGFyZW50LT5jaGlsZF9tdXRleCk7CgoJCWZwdXQocGFyZW50LT5maWxwKTsKCgkJbGlzdF9kZWxfZXZlbnQoZXZlbnQsIGN0eCk7CgkJZnJlZV9ldmVudChldmVudCk7Cgl9CgoJaWYgKCFsaXN0X2VtcHR5KCZjdHgtPmdyb3VwX2xpc3QpKQoJCWdvdG8gYWdhaW47CgoJbXV0ZXhfdW5sb2NrKCZjdHgtPm11dGV4KTsKCglwdXRfY3R4KGN0eCk7Cn0KCi8qCiAqIEluaXRpYWxpemUgdGhlIHBlcmZfZXZlbnQgY29udGV4dCBpbiB0YXNrX3N0cnVjdAogKi8KaW50IHBlcmZfZXZlbnRfaW5pdF90YXNrKHN0cnVjdCB0YXNrX3N0cnVjdCAqY2hpbGQpCnsKCXN0cnVjdCBwZXJmX2V2ZW50X2NvbnRleHQgKmNoaWxkX2N0eCwgKnBhcmVudF9jdHg7CglzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0ICpjbG9uZWRfY3R4OwoJc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50OwoJc3RydWN0IHRhc2tfc3RydWN0ICpwYXJlbnQgPSBjdXJyZW50OwoJaW50IGluaGVyaXRlZF9hbGwgPSAxOwoJaW50IHJldCA9IDA7CgoJY2hpbGQtPnBlcmZfZXZlbnRfY3R4cCA9IE5VTEw7CgoJbXV0ZXhfaW5pdCgmY2hpbGQtPnBlcmZfZXZlbnRfbXV0ZXgpOwoJSU5JVF9MSVNUX0hFQUQoJmNoaWxkLT5wZXJmX2V2ZW50X2xpc3QpOwoKCWlmIChsaWtlbHkoIXBhcmVudC0+cGVyZl9ldmVudF9jdHhwKSkKCQlyZXR1cm4gMDsKCgkvKgoJICogVGhpcyBpcyBleGVjdXRlZCBmcm9tIHRoZSBwYXJlbnQgdGFzayBjb250ZXh0LCBzbyBpbmhlcml0CgkgKiBldmVudHMgdGhhdCBoYXZlIGJlZW4gbWFya2VkIGZvciBjbG9uaW5nLgoJICogRmlyc3QgYWxsb2NhdGUgYW5kIGluaXRpYWxpemUgYSBjb250ZXh0IGZvciB0aGUgY2hpbGQuCgkgKi8KCgljaGlsZF9jdHggPSBrbWFsbG9jKHNpemVvZihzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0KSwgR0ZQX0tFUk5FTCk7CglpZiAoIWNoaWxkX2N0eCkKCQlyZXR1cm4gLUVOT01FTTsKCglfX3BlcmZfZXZlbnRfaW5pdF9jb250ZXh0KGNoaWxkX2N0eCwgY2hpbGQpOwoJY2hpbGQtPnBlcmZfZXZlbnRfY3R4cCA9IGNoaWxkX2N0eDsKCWdldF90YXNrX3N0cnVjdChjaGlsZCk7CgoJLyoKCSAqIElmIHRoZSBwYXJlbnQncyBjb250ZXh0IGlzIGEgY2xvbmUsIHBpbiBpdCBzbyBpdCB3b24ndCBnZXQKCSAqIHN3YXBwZWQgdW5kZXIgdXMuCgkgKi8KCXBhcmVudF9jdHggPSBwZXJmX3Bpbl90YXNrX2NvbnRleHQocGFyZW50KTsKCgkvKgoJICogTm8gbmVlZCB0byBjaGVjayBpZiBwYXJlbnRfY3R4ICE9IE5VTEwgaGVyZTsgc2luY2Ugd2Ugc2F3CgkgKiBpdCBub24tTlVMTCBlYXJsaWVyLCB0aGUgb25seSByZWFzb24gZm9yIGl0IHRvIGJlY29tZSBOVUxMCgkgKiBpcyBpZiB3ZSBleGl0LCBhbmQgc2luY2Ugd2UncmUgY3VycmVudGx5IGluIHRoZSBtaWRkbGUgb2YKCSAqIGEgZm9yayB3ZSBjYW4ndCBiZSBleGl0aW5nIGF0IHRoZSBzYW1lIHRpbWUuCgkgKi8KCgkvKgoJICogTG9jayB0aGUgcGFyZW50IGxpc3QuIE5vIG5lZWQgdG8gbG9jayB0aGUgY2hpbGQgLSBub3QgUElECgkgKiBoYXNoZWQgeWV0IGFuZCBub3QgcnVubmluZywgc28gbm9ib2R5IGNhbiBhY2Nlc3MgaXQuCgkgKi8KCW11dGV4X2xvY2soJnBhcmVudF9jdHgtPm11dGV4KTsKCgkvKgoJICogV2UgZG9udCBoYXZlIHRvIGRpc2FibGUgTk1JcyAtIHdlIGFyZSBvbmx5IGxvb2tpbmcgYXQKCSAqIHRoZSBsaXN0LCBub3QgbWFuaXB1bGF0aW5nIGl0OgoJICovCglsaXN0X2Zvcl9lYWNoX2VudHJ5KGV2ZW50LCAmcGFyZW50X2N0eC0+Z3JvdXBfbGlzdCwgZ3JvdXBfZW50cnkpIHsKCgkJaWYgKCFldmVudC0+YXR0ci5pbmhlcml0KSB7CgkJCWluaGVyaXRlZF9hbGwgPSAwOwoJCQljb250aW51ZTsKCQl9CgoJCXJldCA9IGluaGVyaXRfZ3JvdXAoZXZlbnQsIHBhcmVudCwgcGFyZW50X2N0eCwKCQkJCQkgICAgIGNoaWxkLCBjaGlsZF9jdHgpOwoJCWlmIChyZXQpIHsKCQkJaW5oZXJpdGVkX2FsbCA9IDA7CgkJCWJyZWFrOwoJCX0KCX0KCglpZiAoaW5oZXJpdGVkX2FsbCkgewoJCS8qCgkJICogTWFyayB0aGUgY2hpbGQgY29udGV4dCBhcyBhIGNsb25lIG9mIHRoZSBwYXJlbnQKCQkgKiBjb250ZXh0LCBvciBvZiB3aGF0ZXZlciB0aGUgcGFyZW50IGlzIGEgY2xvbmUgb2YuCgkJICogTm90ZSB0aGF0IGlmIHRoZSBwYXJlbnQgaXMgYSBjbG9uZSwgaXQgY291bGQgZ2V0CgkJICogdW5jbG9uZWQgYXQgYW55IHBvaW50LCBidXQgdGhhdCBkb2Vzbid0IG1hdHRlcgoJCSAqIGJlY2F1c2UgdGhlIGxpc3Qgb2YgZXZlbnRzIGFuZCB0aGUgZ2VuZXJhdGlvbgoJCSAqIGNvdW50IGNhbid0IGhhdmUgY2hhbmdlZCBzaW5jZSB3ZSB0b29rIHRoZSBtdXRleC4KCQkgKi8KCQljbG9uZWRfY3R4ID0gcmN1X2RlcmVmZXJlbmNlKHBhcmVudF9jdHgtPnBhcmVudF9jdHgpOwoJCWlmIChjbG9uZWRfY3R4KSB7CgkJCWNoaWxkX2N0eC0+cGFyZW50X2N0eCA9IGNsb25lZF9jdHg7CgkJCWNoaWxkX2N0eC0+cGFyZW50X2dlbiA9IHBhcmVudF9jdHgtPnBhcmVudF9nZW47CgkJfSBlbHNlIHsKCQkJY2hpbGRfY3R4LT5wYXJlbnRfY3R4ID0gcGFyZW50X2N0eDsKCQkJY2hpbGRfY3R4LT5wYXJlbnRfZ2VuID0gcGFyZW50X2N0eC0+Z2VuZXJhdGlvbjsKCQl9CgkJZ2V0X2N0eChjaGlsZF9jdHgtPnBhcmVudF9jdHgpOwoJfQoKCW11dGV4X3VubG9jaygmcGFyZW50X2N0eC0+bXV0ZXgpOwoKCXBlcmZfdW5waW5fY29udGV4dChwYXJlbnRfY3R4KTsKCglyZXR1cm4gcmV0Owp9CgpzdGF0aWMgdm9pZCBfX2NwdWluaXQgcGVyZl9ldmVudF9pbml0X2NwdShpbnQgY3B1KQp7CglzdHJ1Y3QgcGVyZl9jcHVfY29udGV4dCAqY3B1Y3R4OwoKCWNwdWN0eCA9ICZwZXJfY3B1KHBlcmZfY3B1X2NvbnRleHQsIGNwdSk7CglfX3BlcmZfZXZlbnRfaW5pdF9jb250ZXh0KCZjcHVjdHgtPmN0eCwgTlVMTCk7CgoJc3Bpbl9sb2NrKCZwZXJmX3Jlc291cmNlX2xvY2spOwoJY3B1Y3R4LT5tYXhfcGVydGFzayA9IHBlcmZfbWF4X2V2ZW50cyAtIHBlcmZfcmVzZXJ2ZWRfcGVyY3B1OwoJc3Bpbl91bmxvY2soJnBlcmZfcmVzb3VyY2VfbG9jayk7CgoJaHdfcGVyZl9ldmVudF9zZXR1cChjcHUpOwp9CgojaWZkZWYgQ09ORklHX0hPVFBMVUdfQ1BVCnN0YXRpYyB2b2lkIF9fcGVyZl9ldmVudF9leGl0X2NwdSh2b2lkICppbmZvKQp7CglzdHJ1Y3QgcGVyZl9jcHVfY29udGV4dCAqY3B1Y3R4ID0gJl9fZ2V0X2NwdV92YXIocGVyZl9jcHVfY29udGV4dCk7CglzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0ICpjdHggPSAmY3B1Y3R4LT5jdHg7CglzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQsICp0bXA7CgoJbGlzdF9mb3JfZWFjaF9lbnRyeV9zYWZlKGV2ZW50LCB0bXAsICZjdHgtPmdyb3VwX2xpc3QsIGdyb3VwX2VudHJ5KQoJCV9fcGVyZl9ldmVudF9yZW1vdmVfZnJvbV9jb250ZXh0KGV2ZW50KTsKfQpzdGF0aWMgdm9pZCBwZXJmX2V2ZW50X2V4aXRfY3B1KGludCBjcHUpCnsKCXN0cnVjdCBwZXJmX2NwdV9jb250ZXh0ICpjcHVjdHggPSAmcGVyX2NwdShwZXJmX2NwdV9jb250ZXh0LCBjcHUpOwoJc3RydWN0IHBlcmZfZXZlbnRfY29udGV4dCAqY3R4ID0gJmNwdWN0eC0+Y3R4OwoKCW11dGV4X2xvY2soJmN0eC0+bXV0ZXgpOwoJc21wX2NhbGxfZnVuY3Rpb25fc2luZ2xlKGNwdSwgX19wZXJmX2V2ZW50X2V4aXRfY3B1LCBOVUxMLCAxKTsKCW11dGV4X3VubG9jaygmY3R4LT5tdXRleCk7Cn0KI2Vsc2UKc3RhdGljIGlubGluZSB2b2lkIHBlcmZfZXZlbnRfZXhpdF9jcHUoaW50IGNwdSkgeyB9CiNlbmRpZgoKc3RhdGljIGludCBfX2NwdWluaXQKcGVyZl9jcHVfbm90aWZ5KHN0cnVjdCBub3RpZmllcl9ibG9jayAqc2VsZiwgdW5zaWduZWQgbG9uZyBhY3Rpb24sIHZvaWQgKmhjcHUpCnsKCXVuc2lnbmVkIGludCBjcHUgPSAobG9uZyloY3B1OwoKCXN3aXRjaCAoYWN0aW9uKSB7CgoJY2FzZSBDUFVfVVBfUFJFUEFSRToKCWNhc2UgQ1BVX1VQX1BSRVBBUkVfRlJPWkVOOgoJCXBlcmZfZXZlbnRfaW5pdF9jcHUoY3B1KTsKCQlicmVhazsKCgljYXNlIENQVV9PTkxJTkU6CgljYXNlIENQVV9PTkxJTkVfRlJPWkVOOgoJCWh3X3BlcmZfZXZlbnRfc2V0dXBfb25saW5lKGNwdSk7CgkJYnJlYWs7CgoJY2FzZSBDUFVfRE9XTl9QUkVQQVJFOgoJY2FzZSBDUFVfRE9XTl9QUkVQQVJFX0ZST1pFTjoKCQlwZXJmX2V2ZW50X2V4aXRfY3B1KGNwdSk7CgkJYnJlYWs7CgoJZGVmYXVsdDoKCQlicmVhazsKCX0KCglyZXR1cm4gTk9USUZZX09LOwp9CgovKgogKiBUaGlzIGhhcyB0byBoYXZlIGEgaGlnaGVyIHByaW9yaXR5IHRoYW4gbWlncmF0aW9uX25vdGlmaWVyIGluIHNjaGVkLmMuCiAqLwpzdGF0aWMgc3RydWN0IG5vdGlmaWVyX2Jsb2NrIF9fY3B1aW5pdGRhdGEgcGVyZl9jcHVfbmIgPSB7Cgkubm90aWZpZXJfY2FsbAkJPSBwZXJmX2NwdV9ub3RpZnksCgkucHJpb3JpdHkJCT0gMjAsCn07Cgp2b2lkIF9faW5pdCBwZXJmX2V2ZW50X2luaXQodm9pZCkKewoJcGVyZl9jcHVfbm90aWZ5KCZwZXJmX2NwdV9uYiwgKHVuc2lnbmVkIGxvbmcpQ1BVX1VQX1BSRVBBUkUsCgkJCSh2b2lkICopKGxvbmcpc21wX3Byb2Nlc3Nvcl9pZCgpKTsKCXBlcmZfY3B1X25vdGlmeSgmcGVyZl9jcHVfbmIsICh1bnNpZ25lZCBsb25nKUNQVV9PTkxJTkUsCgkJCSh2b2lkICopKGxvbmcpc21wX3Byb2Nlc3Nvcl9pZCgpKTsKCXJlZ2lzdGVyX2NwdV9ub3RpZmllcigmcGVyZl9jcHVfbmIpOwp9CgpzdGF0aWMgc3NpemVfdCBwZXJmX3Nob3dfcmVzZXJ2ZV9wZXJjcHUoc3RydWN0IHN5c2Rldl9jbGFzcyAqY2xhc3MsIGNoYXIgKmJ1ZikKewoJcmV0dXJuIHNwcmludGYoYnVmLCAiJWRcbiIsIHBlcmZfcmVzZXJ2ZWRfcGVyY3B1KTsKfQoKc3RhdGljIHNzaXplX3QKcGVyZl9zZXRfcmVzZXJ2ZV9wZXJjcHUoc3RydWN0IHN5c2Rldl9jbGFzcyAqY2xhc3MsCgkJCWNvbnN0IGNoYXIgKmJ1ZiwKCQkJc2l6ZV90IGNvdW50KQp7CglzdHJ1Y3QgcGVyZl9jcHVfY29udGV4dCAqY3B1Y3R4OwoJdW5zaWduZWQgbG9uZyB2YWw7CglpbnQgZXJyLCBjcHUsIG1wdDsKCgllcnIgPSBzdHJpY3Rfc3RydG91bChidWYsIDEwLCAmdmFsKTsKCWlmIChlcnIpCgkJcmV0dXJuIGVycjsKCWlmICh2YWwgPiBwZXJmX21heF9ldmVudHMpCgkJcmV0dXJuIC1FSU5WQUw7CgoJc3Bpbl9sb2NrKCZwZXJmX3Jlc291cmNlX2xvY2spOwoJcGVyZl9yZXNlcnZlZF9wZXJjcHUgPSB2YWw7Cglmb3JfZWFjaF9vbmxpbmVfY3B1KGNwdSkgewoJCWNwdWN0eCA9ICZwZXJfY3B1KHBlcmZfY3B1X2NvbnRleHQsIGNwdSk7CgkJc3Bpbl9sb2NrX2lycSgmY3B1Y3R4LT5jdHgubG9jayk7CgkJbXB0ID0gbWluKHBlcmZfbWF4X2V2ZW50cyAtIGNwdWN0eC0+Y3R4Lm5yX2V2ZW50cywKCQkJICBwZXJmX21heF9ldmVudHMgLSBwZXJmX3Jlc2VydmVkX3BlcmNwdSk7CgkJY3B1Y3R4LT5tYXhfcGVydGFzayA9IG1wdDsKCQlzcGluX3VubG9ja19pcnEoJmNwdWN0eC0+Y3R4LmxvY2spOwoJfQoJc3Bpbl91bmxvY2soJnBlcmZfcmVzb3VyY2VfbG9jayk7CgoJcmV0dXJuIGNvdW50Owp9CgpzdGF0aWMgc3NpemVfdCBwZXJmX3Nob3dfb3ZlcmNvbW1pdChzdHJ1Y3Qgc3lzZGV2X2NsYXNzICpjbGFzcywgY2hhciAqYnVmKQp7CglyZXR1cm4gc3ByaW50ZihidWYsICIlZFxuIiwgcGVyZl9vdmVyY29tbWl0KTsKfQoKc3RhdGljIHNzaXplX3QKcGVyZl9zZXRfb3ZlcmNvbW1pdChzdHJ1Y3Qgc3lzZGV2X2NsYXNzICpjbGFzcywgY29uc3QgY2hhciAqYnVmLCBzaXplX3QgY291bnQpCnsKCXVuc2lnbmVkIGxvbmcgdmFsOwoJaW50IGVycjsKCgllcnIgPSBzdHJpY3Rfc3RydG91bChidWYsIDEwLCAmdmFsKTsKCWlmIChlcnIpCgkJcmV0dXJuIGVycjsKCWlmICh2YWwgPiAxKQoJCXJldHVybiAtRUlOVkFMOwoKCXNwaW5fbG9jaygmcGVyZl9yZXNvdXJjZV9sb2NrKTsKCXBlcmZfb3ZlcmNvbW1pdCA9IHZhbDsKCXNwaW5fdW5sb2NrKCZwZXJmX3Jlc291cmNlX2xvY2spOwoKCXJldHVybiBjb3VudDsKfQoKc3RhdGljIFNZU0RFVl9DTEFTU19BVFRSKAoJCQkJcmVzZXJ2ZV9wZXJjcHUsCgkJCQkwNjQ0LAoJCQkJcGVyZl9zaG93X3Jlc2VydmVfcGVyY3B1LAoJCQkJcGVyZl9zZXRfcmVzZXJ2ZV9wZXJjcHUKCQkJKTsKCnN0YXRpYyBTWVNERVZfQ0xBU1NfQVRUUigKCQkJCW92ZXJjb21taXQsCgkJCQkwNjQ0LAoJCQkJcGVyZl9zaG93X292ZXJjb21taXQsCgkJCQlwZXJmX3NldF9vdmVyY29tbWl0CgkJCSk7CgpzdGF0aWMgc3RydWN0IGF0dHJpYnV0ZSAqcGVyZmNsYXNzX2F0dHJzW10gPSB7CgkmYXR0cl9yZXNlcnZlX3BlcmNwdS5hdHRyLAoJJmF0dHJfb3ZlcmNvbW1pdC5hdHRyLAoJTlVMTAp9OwoKc3RhdGljIHN0cnVjdCBhdHRyaWJ1dGVfZ3JvdXAgcGVyZmNsYXNzX2F0dHJfZ3JvdXAgPSB7CgkuYXR0cnMJCQk9IHBlcmZjbGFzc19hdHRycywKCS5uYW1lCQkJPSAicGVyZl9ldmVudHMiLAp9OwoKc3RhdGljIGludCBfX2luaXQgcGVyZl9ldmVudF9zeXNmc19pbml0KHZvaWQpCnsKCXJldHVybiBzeXNmc19jcmVhdGVfZ3JvdXAoJmNwdV9zeXNkZXZfY2xhc3Mua3NldC5rb2JqLAoJCQkJICAmcGVyZmNsYXNzX2F0dHJfZ3JvdXApOwp9CmRldmljZV9pbml0Y2FsbChwZXJmX2V2ZW50X3N5c2ZzX2luaXQpOwo=