LyoKICogUGVyZm9ybWFuY2UgZXZlbnRzIGNvcmUgY29kZToKICoKICogIENvcHlyaWdodCAoQykgMjAwOCBUaG9tYXMgR2xlaXhuZXIgPHRnbHhAbGludXRyb25peC5kZT4KICogIENvcHlyaWdodCAoQykgMjAwOC0yMDA5IFJlZCBIYXQsIEluYy4sIEluZ28gTW9sbmFyCiAqICBDb3B5cmlnaHQgKEMpIDIwMDgtMjAwOSBSZWQgSGF0LCBJbmMuLCBQZXRlciBaaWpsc3RyYSA8cHppamxzdHJAcmVkaGF0LmNvbT4KICogIENvcHlyaWdodCAgqSAgMjAwOSBQYXVsIE1hY2tlcnJhcywgSUJNIENvcnAuIDxwYXVsdXNAYXUxLmlibS5jb20+CiAqCiAqIEZvciBsaWNlbnNpbmcgZGV0YWlscyBzZWUga2VybmVsLWJhc2UvQ09QWUlORwogKi8KCiNpbmNsdWRlIDxsaW51eC9mcy5oPgojaW5jbHVkZSA8bGludXgvbW0uaD4KI2luY2x1ZGUgPGxpbnV4L2NwdS5oPgojaW5jbHVkZSA8bGludXgvc21wLmg+CiNpbmNsdWRlIDxsaW51eC9maWxlLmg+CiNpbmNsdWRlIDxsaW51eC9wb2xsLmg+CiNpbmNsdWRlIDxsaW51eC9zeXNmcy5oPgojaW5jbHVkZSA8bGludXgvZGNhY2hlLmg+CiNpbmNsdWRlIDxsaW51eC9wZXJjcHUuaD4KI2luY2x1ZGUgPGxpbnV4L3B0cmFjZS5oPgojaW5jbHVkZSA8bGludXgvdm1zdGF0Lmg+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+Y3R4OwoJc3RydWN0IHRhc2tfc3RydWN0ICp0YXNrID0gY3R4LT50YXNrOwoKCWlmICghdGFzaykgewoJCS8qCgkJICogUGVyIGNwdSBldmVudHMgYXJlIHJlbW92ZWQgdmlhIGFuIHNtcCBjYWxsIGFuZAoJCSAqIHRoZSByZW1vdmFsIGlzIGFsd2F5cyBzdWNlc3NmdWwuCgkJICovCgkJc21wX2NhbGxfZnVuY3Rpb25fc2luZ2xlKGV2ZW50LT5jcHUsCgkJCQkJIF9fcGVyZl9ldmVudF9yZW1vdmVfZnJvbV9jb250ZXh0LAoJCQkJCSBldmVudCwgMSk7CgkJcmV0dXJuOwoJfQoKcmV0cnk6Cgl0YXNrX29uY3B1X2Z1bmN0aW9uX2NhbGwodGFzaywgX19wZXJmX2V2ZW50X3JlbW92ZV9mcm9tX2NvbnRleHQsCgkJCQkgZXZlbnQpOwoKCXNwaW5fbG9ja19pcnEoJmN0eC0+bG9jayk7CgkvKgoJICogSWYgdGhlIGNvbnRleHQgaXMgYWN0aXZlIHdlIG5lZWQgdG8gcmV0cnkgdGhlIHNtcCBjYWxsLgoJICovCglpZiAoY3R4LT5ucl9hY3RpdmUgJiYgIWxpc3RfZW1wdHkoJmV2ZW50LT5ncm91cF9lbnRyeSkpIHsKCQlzcGluX3VubG9ja19pcnEoJmN0eC0+bG9jayk7CgkJZ290byByZXRyeTsKCX0KCgkvKgoJICogVGhlIGxvY2sgcHJldmVudHMgdGhhdCB0aGlzIGNvbnRleHQgaXMgc2NoZWR1bGVkIGluIHNvIHdlCgkgKiBjYW4gcmVtb3ZlIHRoZSBldmVudCBzYWZlbHksIGlmIHRoZSBjYWxsIGFib3ZlIGRpZCBub3QKCSAqIHN1Y2NlZWQuCgkgKi8KCWlmICghbGlzdF9lbXB0eSgmZXZlbnQtPmdyb3VwX2VudHJ5KSkgewoJCWxpc3RfZGVsX2V2ZW50KGV2ZW50LCBjdHgpOwoJfQoJc3Bpbl91bmxvY2tfaXJxKCZjdHgtPmxvY2spOwp9CgpzdGF0aWMgaW5saW5lIHU2NCBwZXJmX2Nsb2NrKHZvaWQpCnsKCXJldHVybiBjcHVfY2xvY2soc21wX3Byb2Nlc3Nvcl9pZCgpKTsKfQoKLyoKICogVXBkYXRlIHRoZSByZWNvcmQgb2YgdGhlIGN1cnJlbnQgdGltZSBpbiBhIGNvbnRleHQuCiAqLwpzdGF0aWMgdm9pZCB1cGRhdGVfY29udGV4dF90aW1lKHN0cnVjdCBwZXJmX2V2ZW50X2NvbnRleHQgKmN0eCkKewoJdTY0IG5vdyA9IHBlcmZfY2xvY2soKTsKCgljdHgtPnRpbWUgKz0gbm93IC0gY3R4LT50aW1lc3RhbXA7CgljdHgtPnRpbWVzdGFtcCA9IG5vdzsKfQoKLyoKICogVXBkYXRlIHRoZSB0b3RhbF90aW1lX2VuYWJsZWQgYW5kIHRvdGFsX3RpbWVfcnVubmluZyBmaWVsZHMgZm9yIGEgZXZlbnQuCiAqLwpzdGF0aWMgdm9pZCB1cGRhdGVfZXZlbnRfdGltZXMoc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50KQp7CglzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0ICpjdHggPSBldmVudC0+Y3R4OwoJdTY0IHJ1bl9lbmQ7CgoJaWYgKGV2ZW50LT5zdGF0ZSA8IFBFUkZfRVZFTlRfU1RBVEVfSU5BQ1RJVkUgfHwKCSAgICBldmVudC0+Z3JvdXBfbGVhZGVyLT5zdGF0ZSA8IFBFUkZfRVZFTlRfU1RBVEVfSU5BQ1RJVkUpCgkJcmV0dXJuOwoKCWV2ZW50LT50b3RhbF90aW1lX2VuYWJsZWQgPSBjdHgtPnRpbWUgLSBldmVudC0+dHN0YW1wX2VuYWJsZWQ7CgoJaWYgKGV2ZW50LT5zdGF0ZSA9PSBQRVJGX0VWRU5UX1NUQVRFX0lOQUNUSVZFKQoJCXJ1bl9lbmQgPSBldmVudC0+dHN0YW1wX3N0b3BwZWQ7CgllbHNlCgkJcnVuX2VuZCA9IGN0eC0+dGltZTsKCglldmVudC0+dG90YWxfdGltZV9ydW5uaW5nID0gcnVuX2VuZCAtIGV2ZW50LT50c3RhbXBfcnVubmluZzsKfQoKLyoKICogVXBkYXRlIHRvdGFsX3RpbWVfZW5hYmxlZCBhbmQgdG90YWxfdGltZV9ydW5uaW5nIGZvciBhbGwgZXZlbnRzIGluIGEgZ3JvdXAuCiAqLwpzdGF0aWMgdm9pZCB1cGRhdGVfZ3JvdXBfdGltZXMoc3RydWN0IHBlcmZfZXZlbnQgKmxlYWRlcikKewoJc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50OwoKCXVwZGF0ZV9ldmVudF90aW1lcyhsZWFkZXIpOwoJbGlzdF9mb3JfZWFjaF9lbnRyeShldmVudCwgJmxlYWRlci0+c2libGluZ19saXN0LCBncm91cF9lbnRyeSkKCQl1cGRhdGVfZXZlbnRfdGltZXMoZXZlbnQpOwp9CgovKgogKiBDcm9zcyBDUFUgY2FsbCB0byBkaXNhYmxlIGEgcGVyZm9ybWFuY2UgZXZlbnQKICovCnN0YXRpYyB2b2lkIF9fcGVyZl9ldmVudF9kaXNhYmxlKHZvaWQgKmluZm8pCnsKCXN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCA9IGluZm87CglzdHJ1Y3QgcGVyZl9jcHVfY29udGV4dCAqY3B1Y3R4ID0gJl9fZ2V0X2NwdV92YXIocGVyZl9jcHVfY29udGV4dCk7CglzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0ICpjdHggPSBldmVudC0+Y3R4OwoKCS8qCgkgKiBJZiB0aGlzIGlzIGEgcGVyLXRhc2sgZXZlbnQsIG5lZWQgdG8gY2hlY2sgd2hldGhlciB0aGlzCgkgKiBldmVudCdzIHRhc2sgaXMgdGhlIGN1cnJlbnQgdGFzayBvbiB0aGlzIGNwdS4KCSAqLwoJaWYgKGN0eC0+dGFzayAmJiBjcHVjdHgtPnRhc2tfY3R4ICE9IGN0eCkKCQlyZXR1cm47CgoJc3Bpbl9sb2NrKCZjdHgtPmxvY2spOwoKCS8qCgkgKiBJZiB0aGUgZXZlbnQgaXMgb24sIHR1cm4gaXQgb2ZmLgoJICogSWYgaXQgaXMgaW4gZXJyb3Igc3RhdGUsIGxlYXZlIGl0IGluIGVycm9yIHN0YXRlLgoJICovCglpZiAoZXZlbnQtPnN0YXRlID49IFBFUkZfRVZFTlRfU1RBVEVfSU5BQ1RJVkUpIHsKCQl1cGRhdGVfY29udGV4dF90aW1lKGN0eCk7CgkJdXBkYXRlX2dyb3VwX3RpbWVzKGV2ZW50KTsKCQlpZiAoZXZlbnQgPT0gZXZlbnQtPmdyb3VwX2xlYWRlcikKCQkJZ3JvdXBfc2NoZWRfb3V0KGV2ZW50LCBjcHVjdHgsIGN0eCk7CgkJZWxzZQoJCQlldmVudF9zY2hlZF9vdXQoZXZlbnQsIGNwdWN0eCwgY3R4KTsKCQlldmVudC0+c3RhdGUgPSBQRVJGX0VWRU5UX1NUQVRFX09GRjsKCX0KCglzcGluX3VubG9jaygmY3R4LT5sb2NrKTsKfQoKLyoKICogRGlzYWJsZSBhIGV2ZW50LgogKgogKiBJZiBldmVudC0+Y3R4IGlzIGEgY2xvbmVkIGNvbnRleHQsIGNhbGxlcnMgbXVzdCBtYWtlIHN1cmUgdGhhdAogKiBldmVyeSB0YXNrIHN0cnVjdCB0aGF0IGV2ZW50LT5jdHgtPnRhc2sgY291bGQgcG9zc2libHkgcG9pbnQgdG8KICogcmVtYWlucyB2YWxpZC4gIFRoaXMgY29uZGl0aW9uIGlzIHNhdGlzaWZlZCB3aGVuIGNhbGxlZCB0aHJvdWdoCiAqIHBlcmZfZXZlbnRfZm9yX2VhY2hfY2hpbGQgb3IgcGVyZl9ldmVudF9mb3JfZWFjaCBiZWNhdXNlIHRoZXkKICogaG9sZCB0aGUgdG9wLWxldmVsIGV2ZW50J3MgY2hpbGRfbXV0ZXgsIHNvIGFueSBkZXNjZW5kYW50IHRoYXQKICogZ29lcyB0byBleGl0IHdpbGwgYmxvY2sgaW4gc3luY19jaGlsZF9ldmVudC4KICogV2hlbiBjYWxsZWQgZnJvbSBwZXJmX3BlbmRpbmdfZXZlbnQgaXQncyBPSyBiZWNhdXNlIGV2ZW50LT5jdHgKICogaXMgdGhlIGN1cnJlbnQgY29udGV4dCBvbiB0aGlzIENQVSBhbmQgcHJlZW1wdGlvbiBpcyBkaXNhYmxlZCwKICogaGVuY2Ugd2UgY2FuJ3QgZ2V0IGludG8gcGVyZl9ldmVudF90YXNrX3NjaGVkX291dCBmb3IgdGhpcyBjb250ZXh0LgogKi8Kc3RhdGljIHZvaWQgcGVyZl9ldmVudF9kaXNhYmxlKHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCkKewoJc3RydWN0IHBlcmZfZXZlbnRfY29udGV4dCAqY3R4ID0gZXZlbnQtPmN0eDsKCXN0cnVjdCB0YXNrX3N0cnVjdCAqdGFzayA9IGN0eC0+dGFzazsKCglpZiAoIXRhc2spIHsKCQkvKgoJCSAqIERpc2FibGUgdGhlIGV2ZW50IG9uIHRoZSBjcHUgdGhhdCBpdCdzIG9uCgkJICovCgkJc21wX2NhbGxfZnVuY3Rpb25fc2luZ2xlKGV2ZW50LT5jcHUsIF9fcGVyZl9ldmVudF9kaXNhYmxlLAoJCQkJCSBldmVudCwgMSk7CgkJcmV0dXJuOwoJfQoKIHJldHJ5OgoJdGFza19vbmNwdV9mdW5jdGlvbl9jYWxsKHRhc2ssIF9fcGVyZl9ldmVudF9kaXNhYmxlLCBldmVudCk7CgoJc3Bpbl9sb2NrX2lycSgmY3R4LT5sb2NrKTsKCS8qCgkgKiBJZiB0aGUgZXZlbnQgaXMgc3RpbGwgYWN0aXZlLCB3ZSBuZWVkIHRvIHJldHJ5IHRoZSBjcm9zcy1jYWxsLgoJICovCglpZiAoZXZlbnQtPnN0YXRlID09IFBFUkZfRVZFTlRfU1RBVEVfQUNUSVZFKSB7CgkJc3Bpbl91bmxvY2tfaXJxKCZjdHgtPmxvY2spOwoJCWdvdG8gcmV0cnk7Cgl9CgoJLyoKCSAqIFNpbmNlIHdlIGhhdmUgdGhlIGxvY2sgdGhpcyBjb250ZXh0IGNhbid0IGJlIHNjaGVkdWxlZAoJICogaW4sIHNvIHdlIGNhbiBjaGFuZ2UgdGhlIHN0YXRlIHNhZmVseS4KCSAqLwoJaWYgKGV2ZW50LT5zdGF0ZSA9PSBQRVJGX0VWRU5UX1NUQVRFX0lOQUNUSVZFKSB7CgkJdXBkYXRlX2dyb3VwX3RpbWVzKGV2ZW50KTsKCQlldmVudC0+c3RhdGUgPSBQRVJGX0VWRU5UX1NUQVRFX09GRjsKCX0KCglzcGluX3VubG9ja19pcnEoJmN0eC0+bG9jayk7Cn0KCnN0YXRpYyBpbnQKZXZlbnRfc2NoZWRfaW4oc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50LAoJCSBzdHJ1Y3QgcGVyZl9jcHVfY29udGV4dCAqY3B1Y3R4LAoJCSBzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0ICpjdHgsCgkJIGludCBjcHUpCnsKCWlmIChldmVudC0+c3RhdGUgPD0gUEVSRl9FVkVOVF9TVEFURV9PRkYpCgkJcmV0dXJuIDA7CgoJZXZlbnQtPnN0YXRlID0gUEVSRl9FVkVOVF9TVEFURV9BQ1RJVkU7CglldmVudC0+b25jcHUgPSBjcHU7CS8qIFRPRE86IHB1dCAnY3B1JyBpbnRvIGNwdWN0eC0+Y3B1ICovCgkvKgoJICogVGhlIG5ldyBzdGF0ZSBtdXN0IGJlIHZpc2libGUgYmVmb3JlIHdlIHR1cm4gaXQgb24gaW4gdGhlIGhhcmR3YXJlOgoJICovCglzbXBfd21iKCk7CgoJaWYgKGV2ZW50LT5wbXUtPmVuYWJsZShldmVudCkpIHsKCQlldmVudC0+c3RhdGUgPSBQRVJGX0VWRU5UX1NUQVRFX0lOQUNUSVZFOwoJCWV2ZW50LT5vbmNwdSA9IC0xOwoJCXJldHVybiAtRUFHQUlOOwoJfQoKCWV2ZW50LT50c3RhbXBfcnVubmluZyArPSBjdHgtPnRpbWUgLSBldmVudC0+dHN0YW1wX3N0b3BwZWQ7CgoJaWYgKCFpc19zb2Z0d2FyZV9ldmVudChldmVudCkpCgkJY3B1Y3R4LT5hY3RpdmVfb25jcHUrKzsKCWN0eC0+bnJfYWN0aXZlKys7CgoJaWYgKGV2ZW50LT5hdHRyLmV4Y2x1c2l2ZSkKCQljcHVjdHgtPmV4Y2x1c2l2ZSA9IDE7CgoJcmV0dXJuIDA7Cn0KCnN0YXRpYyBpbnQKZ3JvdXBfc2NoZWRfaW4oc3RydWN0IHBlcmZfZXZlbnQgKmdyb3VwX2V2ZW50LAoJICAgICAgIHN0cnVjdCBwZXJmX2NwdV9jb250ZXh0ICpjcHVjdHgsCgkgICAgICAgc3RydWN0IHBlcmZfZXZlbnRfY29udGV4dCAqY3R4LAoJICAgICAgIGludCBjcHUpCnsKCXN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCwgKnBhcnRpYWxfZ3JvdXA7CglpbnQgcmV0OwoKCWlmIChncm91cF9ldmVudC0+c3RhdGUgPT0gUEVSRl9FVkVOVF9TVEFURV9PRkYpCgkJcmV0dXJuIDA7CgoJcmV0ID0gaHdfcGVyZl9ncm91cF9zY2hlZF9pbihncm91cF9ldmVudCwgY3B1Y3R4LCBjdHgsIGNwdSk7CglpZiAocmV0KQoJCXJldHVybiByZXQgPCAwID8gcmV0IDogMDsKCglpZiAoZXZlbnRfc2NoZWRfaW4oZ3JvdXBfZXZlbnQsIGNwdWN0eCwgY3R4LCBjcHUpKQoJCXJldHVybiAtRUFHQUlOOwoKCS8qCgkgKiBTY2hlZHVsZSBpbiBzaWJsaW5ncyBhcyBvbmUgZ3JvdXAgKGlmIGFueSk6CgkgKi8KCWxpc3RfZm9yX2VhY2hfZW50cnkoZXZlbnQsICZncm91cF9ldmVudC0+c2libGluZ19saXN0LCBncm91cF9lbnRyeSkgewoJCWlmIChldmVudF9zY2hlZF9pbihldmVudCwgY3B1Y3R4LCBjdHgsIGNwdSkpIHsKCQkJcGFydGlhbF9ncm91cCA9IGV2ZW50OwoJCQlnb3RvIGdyb3VwX2Vycm9yOwoJCX0KCX0KCglyZXR1cm4gMDsKCmdyb3VwX2Vycm9yOgoJLyoKCSAqIEdyb3VwcyBjYW4gYmUgc2NoZWR1bGVkIGluIGFzIG9uZSB1bml0IG9ubHksIHNvIHVuZG8gYW55CgkgKiBwYXJ0aWFsIGdyb3VwIGJlZm9yZSByZXR1cm5pbmc6CgkgKi8KCWxpc3RfZm9yX2VhY2hfZW50cnkoZXZlbnQsICZncm91cF9ldmVudC0+c2libGluZ19saXN0LCBncm91cF9lbnRyeSkgewoJCWlmIChldmVudCA9PSBwYXJ0aWFsX2dyb3VwKQoJCQlicmVhazsKCQlldmVudF9zY2hlZF9vdXQoZXZlbnQsIGNwdWN0eCwgY3R4KTsKCX0KCWV2ZW50X3NjaGVkX291dChncm91cF9ldmVudCwgY3B1Y3R4LCBjdHgpOwoKCXJldHVybiAtRUFHQUlOOwp9CgovKgogKiBSZXR1cm4gMSBmb3IgYSBncm91cCBjb25zaXN0aW5nIGVudGlyZWx5IG9mIHNvZnR3YXJlIGV2ZW50cywKICogMCBpZiB0aGUgZ3JvdXAgY29udGFpbnMgYW55IGhhcmR3YXJlIGV2ZW50cy4KICovCnN0YXRpYyBpbnQgaXNfc29mdHdhcmVfb25seV9ncm91cChzdHJ1Y3QgcGVyZl9ldmVudCAqbGVhZGVyKQp7CglzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQ7CgoJaWYgKCFpc19zb2Z0d2FyZV9ldmVudChsZWFkZXIpKQoJCXJldHVybiAwOwoKCWxpc3RfZm9yX2VhY2hfZW50cnkoZXZlbnQsICZsZWFkZXItPnNpYmxpbmdfbGlzdCwgZ3JvdXBfZW50cnkpCgkJaWYgKCFpc19zb2Z0d2FyZV9ldmVudChldmVudCkpCgkJCXJldHVybiAwOwoKCXJldHVybiAxOwp9CgovKgogKiBXb3JrIG91dCB3aGV0aGVyIHdlIGNhbiBwdXQgdGhpcyBldmVudCBncm91cCBvbiB0aGUgQ1BVIG5vdy4KICovCnN0YXRpYyBpbnQgZ3JvdXBfY2FuX2dvX29uKHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCwKCQkJICAgc3RydWN0IHBlcmZfY3B1X2NvbnRleHQgKmNwdWN0eCwKCQkJICAgaW50IGNhbl9hZGRfaHcpCnsKCS8qCgkgKiBHcm91cHMgY29uc2lzdGluZyBlbnRpcmVseSBvZiBzb2Z0d2FyZSBldmVudHMgY2FuIGFsd2F5cyBnbyBvbi4KCSAqLwoJaWYgKGlzX3NvZnR3YXJlX29ubHlfZ3JvdXAoZXZlbnQpKQoJCXJldHVybiAxOwoJLyoKCSAqIElmIGFuIGV4Y2x1c2l2ZSBncm91cCBpcyBhbHJlYWR5IG9uLCBubyBvdGhlciBoYXJkd2FyZQoJICogZXZlbnRzIGNhbiBnbyBvbi4KCSAqLwoJaWYgKGNwdWN0eC0+ZXhjbHVzaXZlKQoJCXJldHVybiAwOwoJLyoKCSAqIElmIHRoaXMgZ3JvdXAgaXMgZXhjbHVzaXZlIGFuZCB0aGVyZSBhcmUgYWxyZWFkeQoJICogZXZlbnRzIG9uIHRoZSBDUFUsIGl0IGNhbid0IGdvIG9uLgoJICovCglpZiAoZXZlbnQtPmF0dHIuZXhjbHVzaXZlICYmIGNwdWN0eC0+YWN0aXZlX29uY3B1KQoJCXJldHVybiAwOwoJLyoKCSAqIE90aGVyd2lzZSwgdHJ5IHRvIGFkZCBpdCBpZiBhbGwgcHJldmlvdXMgZ3JvdXBzIHdlcmUgYWJsZQoJICogdG8gZ28gb24uCgkgKi8KCXJldHVybiBjYW5fYWRkX2h3Owp9CgpzdGF0aWMgdm9pZCBhZGRfZXZlbnRfdG9fY3R4KHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCwKCQkJICAgICAgIHN0cnVjdCBwZXJmX2V2ZW50X2NvbnRleHQgKmN0eCkKewoJbGlzdF9hZGRfZXZlbnQoZXZlbnQsIGN0eCk7CglldmVudC0+dHN0YW1wX2VuYWJsZWQgPSBjdHgtPnRpbWU7CglldmVudC0+dHN0YW1wX3J1bm5pbmcgPSBjdHgtPnRpbWU7CglldmVudC0+dHN0YW1wX3N0b3BwZWQgPSBjdHgtPnRpbWU7Cn0KCi8qCiAqIENyb3NzIENQVSBjYWxsIHRvIGluc3RhbGwgYW5kIGVuYWJsZSBhIHBlcmZvcm1hbmNlIGV2ZW50CiAqCiAqIE11c3QgYmUgY2FsbGVkIHdpdGggY3R4LT5tdXRleCBoZWxkCiAqLwpzdGF0aWMgdm9pZCBfX3BlcmZfaW5zdGFsbF9pbl9jb250ZXh0KHZvaWQgKmluZm8pCnsKCXN0cnVjdCBwZXJmX2NwdV9jb250ZXh0ICpjcHVjdHggPSAmX19nZXRfY3B1X3ZhcihwZXJmX2NwdV9jb250ZXh0KTsKCXN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCA9IGluZm87CglzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0ICpjdHggPSBldmVudC0+Y3R4OwoJc3RydWN0IHBlcmZfZXZlbnQgKmxlYWRlciA9IGV2ZW50LT5ncm91cF9sZWFkZXI7CglpbnQgY3B1ID0gc21wX3Byb2Nlc3Nvcl9pZCgpOwoJaW50IGVycjsKCgkvKgoJICogSWYgdGhpcyBpcyBhIHRhc2sgY29udGV4dCwgd2UgbmVlZCB0byBjaGVjayB3aGV0aGVyIGl0IGlzCgkgKiB0aGUgY3VycmVudCB0YXNrIGNvbnRleHQgb2YgdGhpcyBjcHUuIElmIG5vdCBpdCBoYXMgYmVlbgoJICogc2NoZWR1bGVkIG91dCBiZWZvcmUgdGhlIHNtcCBjYWxsIGFycml2ZWQuCgkgKiBPciBwb3NzaWJseSB0aGlzIGlzIHRoZSByaWdodCBjb250ZXh0IGJ1dCBpdCBpc24ndAoJICogb24gdGhpcyBjcHUgYmVjYXVzZSBpdCBoYWQgbm8gZXZlbnRzLgoJICovCglpZiAoY3R4LT50YXNrICYmIGNwdWN0eC0+dGFza19jdHggIT0gY3R4KSB7CgkJaWYgKGNwdWN0eC0+dGFza19jdHggfHwgY3R4LT50YXNrICE9IGN1cnJlbnQpCgkJCXJldHVybjsKCQljcHVjdHgtPnRhc2tfY3R4ID0gY3R4OwoJfQoKCXNwaW5fbG9jaygmY3R4LT5sb2NrKTsKCWN0eC0+aXNfYWN0aXZlID0gMTsKCXVwZGF0ZV9jb250ZXh0X3RpbWUoY3R4KTsKCgkvKgoJICogUHJvdGVjdCB0aGUgbGlzdCBvcGVyYXRpb24gYWdhaW5zdCBOTUkgYnkgZGlzYWJsaW5nIHRoZQoJICogZXZlbnRzIG9uIGEgZ2xvYmFsIGxldmVsLiBOT1AgZm9yIG5vbiBOTUkgYmFzZWQgZXZlbnRzLgoJICovCglwZXJmX2Rpc2FibGUoKTsKCglhZGRfZXZlbnRfdG9fY3R4KGV2ZW50LCBjdHgpOwoKCS8qCgkgKiBEb24ndCBwdXQgdGhlIGV2ZW50IG9uIGlmIGl0IGlzIGRpc2FibGVkIG9yIGlmCgkgKiBpdCBpcyBpbiBhIGdyb3VwIGFuZCB0aGUgZ3JvdXAgaXNuJ3Qgb24uCgkgKi8KCWlmIChldmVudC0+c3RhdGUgIT0gUEVSRl9FVkVOVF9TVEFURV9JTkFDVElWRSB8fAoJICAgIChsZWFkZXIgIT0gZXZlbnQgJiYgbGVhZGVyLT5zdGF0ZSAhPSBQRVJGX0VWRU5UX1NUQVRFX0FDVElWRSkpCgkJZ290byB1bmxvY2s7CgoJLyoKCSAqIEFuIGV4Y2x1c2l2ZSBldmVudCBjYW4ndCBnbyBvbiBpZiB0aGVyZSBhcmUgYWxyZWFkeSBhY3RpdmUKCSAqIGhhcmR3YXJlIGV2ZW50cywgYW5kIG5vIGhhcmR3YXJlIGV2ZW50IGNhbiBnbyBvbiBpZiB0aGVyZQoJICogaXMgYWxyZWFkeSBhbiBleGNsdXNpdmUgZXZlbnQgb24uCgkgKi8KCWlmICghZ3JvdXBfY2FuX2dvX29uKGV2ZW50LCBjcHVjdHgsIDEpKQoJCWVyciA9IC1FRVhJU1Q7CgllbHNlCgkJZXJyID0gZXZlbnRfc2NoZWRfaW4oZXZlbnQsIGNwdWN0eCwgY3R4LCBjcHUpOwoKCWlmIChlcnIpIHsKCQkvKgoJCSAqIFRoaXMgZXZlbnQgY291bGRuJ3QgZ28gb24uICBJZiBpdCBpcyBpbiBhIGdyb3VwCgkJICogdGhlbiB3ZSBoYXZlIHRvIHB1bGwgdGhlIHdob2xlIGdyb3VwIG9mZi4KCQkgKiBJZiB0aGUgZXZlbnQgZ3JvdXAgaXMgcGlubmVkIHRoZW4gcHV0IGl0IGluIGVycm9yIHN0YXRlLgoJCSAqLwoJCWlmIChsZWFkZXIgIT0gZXZlbnQpCgkJCWdyb3VwX3NjaGVkX291dChsZWFkZXIsIGNwdWN0eCwgY3R4KTsKCQlpZiAobGVhZGVyLT5hdHRyLnBpbm5lZCkgewoJCQl1cGRhdGVfZ3JvdXBfdGltZXMobGVhZGVyKTsKCQkJbGVhZGVyLT5zdGF0ZSA9IFBFUkZfRVZFTlRfU1RBVEVfRVJST1I7CgkJfQoJfQoKCWlmICghZXJyICYmICFjdHgtPnRhc2sgJiYgY3B1Y3R4LT5tYXhfcGVydGFzaykKCQljcHVjdHgtPm1heF9wZXJ0YXNrLS07CgogdW5sb2NrOgoJcGVyZl9lbmFibGUoKTsKCglzcGluX3VubG9jaygmY3R4LT5sb2NrKTsKfQoKLyoKICogQXR0YWNoIGEgcGVyZm9ybWFuY2UgZXZlbnQgdG8gYSBjb250ZXh0CiAqCiAqIEZpcnN0IHdlIGFkZCB0aGUgZXZlbnQgdG8gdGhlIGxpc3Qgd2l0aCB0aGUgaGFyZHdhcmUgZW5hYmxlIGJpdAogKiBpbiBldmVudC0+aHdfY29uZmlnIGNsZWFyZWQuCiAqCiAqIElmIHRoZSBldmVudCBpcyBhdHRhY2hlZCB0byBhIHRhc2sgd2hpY2ggaXMgb24gYSBDUFUgd2UgdXNlIGEgc21wCiAqIGNhbGwgdG8gZW5hYmxlIGl0IGluIHRoZSB0YXNrIGNvbnRleHQuIFRoZSB0YXNrIG1pZ2h0IGhhdmUgYmVlbgogKiBzY2hlZHVsZWQgYXdheSwgYnV0IHdlIGNoZWNrIHRoaXMgaW4gdGhlIHNtcCBjYWxsIGFnYWluLgogKgogKiBNdXN0IGJlIGNhbGxlZCB3aXRoIGN0eC0+bXV0ZXggaGVsZC4KICovCnN0YXRpYyB2b2lkCnBlcmZfaW5zdGFsbF9pbl9jb250ZXh0KHN0cnVjdCBwZXJmX2V2ZW50X2NvbnRleHQgKmN0eCwKCQkJc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50LAoJCQlpbnQgY3B1KQp7CglzdHJ1Y3QgdGFza19zdHJ1Y3QgKnRhc2sgPSBjdHgtPnRhc2s7CgoJaWYgKCF0YXNrKSB7CgkJLyoKCQkgKiBQZXIgY3B1IGV2ZW50cyBhcmUgaW5zdGFsbGVkIHZpYSBhbiBzbXAgY2FsbCBhbmQKCQkgKiB0aGUgaW5zdGFsbCBpcyBhbHdheXMgc3VjZXNzZnVsLgoJCSAqLwoJCXNtcF9jYWxsX2Z1bmN0aW9uX3NpbmdsZShjcHUsIF9fcGVyZl9pbnN0YWxsX2luX2NvbnRleHQsCgkJCQkJIGV2ZW50LCAxKTsKCQlyZXR1cm47Cgl9CgpyZXRyeToKCXRhc2tfb25jcHVfZnVuY3Rpb25fY2FsbCh0YXNrLCBfX3BlcmZfaW5zdGFsbF9pbl9jb250ZXh0LAoJCQkJIGV2ZW50KTsKCglzcGluX2xvY2tfaXJxKCZjdHgtPmxvY2spOwoJLyoKCSAqIHdlIG5lZWQgdG8gcmV0cnkgdGhlIHNtcCBjYWxsLgoJICovCglpZiAoY3R4LT5pc19hY3RpdmUgJiYgbGlzdF9lbXB0eSgmZXZlbnQtPmdyb3VwX2VudHJ5KSkgewoJCXNwaW5fdW5sb2NrX2lycSgmY3R4LT5sb2NrKTsKCQlnb3RvIHJldHJ5OwoJfQoKCS8qCgkgKiBUaGUgbG9jayBwcmV2ZW50cyB0aGF0IHRoaXMgY29udGV4dCBpcyBzY2hlZHVsZWQgaW4gc28gd2UKCSAqIGNhbiBhZGQgdGhlIGV2ZW50IHNhZmVseSwgaWYgaXQgdGhlIGNhbGwgYWJvdmUgZGlkIG5vdAoJICogc3VjY2VlZC4KCSAqLwoJaWYgKGxpc3RfZW1wdHkoJmV2ZW50LT5ncm91cF9lbnRyeSkpCgkJYWRkX2V2ZW50X3RvX2N0eChldmVudCwgY3R4KTsKCXNwaW5fdW5sb2NrX2lycSgmY3R4LT5sb2NrKTsKfQoKLyoKICogUHV0IGEgZXZlbnQgaW50byBpbmFjdGl2ZSBzdGF0ZSBhbmQgdXBkYXRlIHRpbWUgZmllbGRzLgogKiBFbmFibGluZyB0aGUgbGVhZGVyIG9mIGEgZ3JvdXAgZWZmZWN0aXZlbHkgZW5hYmxlcyBhbGwKICogdGhlIGdyb3VwIG1lbWJlcnMgdGhhdCBhcmVuJ3QgZXhwbGljaXRseSBkaXNhYmxlZCwgc28gd2UKICogaGF2ZSB0byB1cGRhdGUgdGhlaXIgLT50c3RhbXBfZW5hYmxlZCBhbHNvLgogKiBOb3RlOiB0aGlzIHdvcmtzIGZvciBncm91cCBtZW1iZXJzIGFzIHdlbGwgYXMgZ3JvdXAgbGVhZGVycwogKiBzaW5jZSB0aGUgbm9uLWxlYWRlciBtZW1iZXJzJyBzaWJsaW5nX2xpc3RzIHdpbGwgYmUgZW1wdHkuCiAqLwpzdGF0aWMgdm9pZCBfX3BlcmZfZXZlbnRfbWFya19lbmFibGVkKHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCwKCQkJCQlzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0ICpjdHgpCnsKCXN0cnVjdCBwZXJmX2V2ZW50ICpzdWI7CgoJZXZlbnQtPnN0YXRlID0gUEVSRl9FVkVOVF9TVEFURV9JTkFDVElWRTsKCWV2ZW50LT50c3RhbXBfZW5hYmxlZCA9IGN0eC0+dGltZSAtIGV2ZW50LT50b3RhbF90aW1lX2VuYWJsZWQ7CglsaXN0X2Zvcl9lYWNoX2VudHJ5KHN1YiwgJmV2ZW50LT5zaWJsaW5nX2xpc3QsIGdyb3VwX2VudHJ5KQoJCWlmIChzdWItPnN0YXRlID49IFBFUkZfRVZFTlRfU1RBVEVfSU5BQ1RJVkUpCgkJCXN1Yi0+dHN0YW1wX2VuYWJsZWQgPQoJCQkJY3R4LT50aW1lIC0gc3ViLT50b3RhbF90aW1lX2VuYWJsZWQ7Cn0KCi8qCiAqIENyb3NzIENQVSBjYWxsIHRvIGVuYWJsZSBhIHBlcmZvcm1hbmNlIGV2ZW50CiAqLwpzdGF0aWMgdm9pZCBfX3BlcmZfZXZlbnRfZW5hYmxlKHZvaWQgKmluZm8pCnsKCXN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCA9IGluZm87CglzdHJ1Y3QgcGVyZl9jcHVfY29udGV4dCAqY3B1Y3R4ID0gJl9fZ2V0X2NwdV92YXIocGVyZl9jcHVfY29udGV4dCk7CglzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0ICpjdHggPSBldmVudC0+Y3R4OwoJc3RydWN0IHBlcmZfZXZlbnQgKmxlYWRlciA9IGV2ZW50LT5ncm91cF9sZWFkZXI7CglpbnQgZXJyOwoKCS8qCgkgKiBJZiB0aGlzIGlzIGEgcGVyLXRhc2sgZXZlbnQsIG5lZWQgdG8gY2hlY2sgd2hldGhlciB0aGlzCgkgKiBldmVudCdzIHRhc2sgaXMgdGhlIGN1cnJlbnQgdGFzayBvbiB0aGlzIGNwdS4KCSAqLwoJaWYgKGN0eC0+dGFzayAmJiBjcHVjdHgtPnRhc2tfY3R4ICE9IGN0eCkgewoJCWlmIChjcHVjdHgtPnRhc2tfY3R4IHx8IGN0eC0+dGFzayAhPSBjdXJyZW50KQoJCQlyZXR1cm47CgkJY3B1Y3R4LT50YXNrX2N0eCA9IGN0eDsKCX0KCglzcGluX2xvY2soJmN0eC0+bG9jayk7CgljdHgtPmlzX2FjdGl2ZSA9IDE7Cgl1cGRhdGVfY29udGV4dF90aW1lKGN0eCk7CgoJaWYgKGV2ZW50LT5zdGF0ZSA+PSBQRVJGX0VWRU5UX1NUQVRFX0lOQUNUSVZFKQoJCWdvdG8gdW5sb2NrOwoJX19wZXJmX2V2ZW50X21hcmtfZW5hYmxlZChldmVudCwgY3R4KTsKCgkvKgoJICogSWYgdGhlIGV2ZW50IGlzIGluIGEgZ3JvdXAgYW5kIGlzbid0IHRoZSBncm91cCBsZWFkZXIsCgkgKiB0aGVuIGRvbid0IHB1dCBpdCBvbiB1bmxlc3MgdGhlIGdyb3VwIGlzIG9uLgoJICovCglpZiAobGVhZGVyICE9IGV2ZW50ICYmIGxlYWRlci0+c3RhdGUgIT0gUEVSRl9FVkVOVF9TVEFURV9BQ1RJVkUpCgkJZ290byB1bmxvY2s7CgoJaWYgKCFncm91cF9jYW5fZ29fb24oZXZlbnQsIGNwdWN0eCwgMSkpIHsKCQllcnIgPSAtRUVYSVNUOwoJfSBlbHNlIHsKCQlwZXJmX2Rpc2FibGUoKTsKCQlpZiAoZXZlbnQgPT0gbGVhZGVyKQoJCQllcnIgPSBncm91cF9zY2hlZF9pbihldmVudCwgY3B1Y3R4LCBjdHgsCgkJCQkJICAgICBzbXBfcHJvY2Vzc29yX2lkKCkpOwoJCWVsc2UKCQkJZXJyID0gZXZlbnRfc2NoZWRfaW4oZXZlbnQsIGNwdWN0eCwgY3R4LAoJCQkJCSAgICAgICBzbXBfcHJvY2Vzc29yX2lkKCkpOwoJCXBlcmZfZW5hYmxlKCk7Cgl9CgoJaWYgKGVycikgewoJCS8qCgkJICogSWYgdGhpcyBldmVudCBjYW4ndCBnbyBvbiBhbmQgaXQncyBwYXJ0IG9mIGEKCQkgKiBncm91cCwgdGhlbiB0aGUgd2hvbGUgZ3JvdXAgaGFzIHRvIGNvbWUgb2ZmLgoJCSAqLwoJCWlmIChsZWFkZXIgIT0gZXZlbnQpCgkJCWdyb3VwX3NjaGVkX291dChsZWFkZXIsIGNwdWN0eCwgY3R4KTsKCQlpZiAobGVhZGVyLT5hdHRyLnBpbm5lZCkgewoJCQl1cGRhdGVfZ3JvdXBfdGltZXMobGVhZGVyKTsKCQkJbGVhZGVyLT5zdGF0ZSA9IFBFUkZfRVZFTlRfU1RBVEVfRVJST1I7CgkJfQoJfQoKIHVubG9jazoKCXNwaW5fdW5sb2NrKCZjdHgtPmxvY2spOwp9CgovKgogKiBFbmFibGUgYSBldmVudC4KICoKICogSWYgZXZlbnQtPmN0eCBpcyBhIGNsb25lZCBjb250ZXh0LCBjYWxsZXJzIG11c3QgbWFrZSBzdXJlIHRoYXQKICogZXZlcnkgdGFzayBzdHJ1Y3QgdGhhdCBldmVudC0+Y3R4LT50YXNrIGNvdWxkIHBvc3NpYmx5IHBvaW50IHRvCiAqIHJlbWFpbnMgdmFsaWQuICBUaGlzIGNvbmRpdGlvbiBpcyBzYXRpc2ZpZWQgd2hlbiBjYWxsZWQgdGhyb3VnaAogKiBwZXJmX2V2ZW50X2Zvcl9lYWNoX2NoaWxkIG9yIHBlcmZfZXZlbnRfZm9yX2VhY2ggYXMgZGVzY3JpYmVkCiAqIGZvciBwZXJmX2V2ZW50X2Rpc2FibGUuCiAqLwpzdGF0aWMgdm9pZCBwZXJmX2V2ZW50X2VuYWJsZShzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQpCnsKCXN0cnVjdCBwZXJmX2V2ZW50X2NvbnRleHQgKmN0eCA9IGV2ZW50LT5jdHg7CglzdHJ1Y3QgdGFza19zdHJ1Y3QgKnRhc2sgPSBjdHgtPnRhc2s7CgoJaWYgKCF0YXNrKSB7CgkJLyoKCQkgKiBFbmFibGUgdGhlIGV2ZW50IG9uIHRoZSBjcHUgdGhhdCBpdCdzIG9uCgkJICovCgkJc21wX2NhbGxfZnVuY3Rpb25fc2luZ2xlKGV2ZW50LT5jcHUsIF9fcGVyZl9ldmVudF9lbmFibGUsCgkJCQkJIGV2ZW50LCAxKTsKCQlyZXR1cm47Cgl9CgoJc3Bpbl9sb2NrX2lycSgmY3R4LT5sb2NrKTsKCWlmIChldmVudC0+c3RhdGUgPj0gUEVSRl9FVkVOVF9TVEFURV9JTkFDVElWRSkKCQlnb3RvIG91dDsKCgkvKgoJICogSWYgdGhlIGV2ZW50IGlzIGluIGVycm9yIHN0YXRlLCBjbGVhciB0aGF0IGZpcnN0LgoJICogVGhhdCB3YXksIGlmIHdlIHNlZSB0aGUgZXZlbnQgaW4gZXJyb3Igc3RhdGUgYmVsb3csIHdlCgkgKiBrbm93IHRoYXQgaXQgaGFzIGdvbmUgYmFjayBpbnRvIGVycm9yIHN0YXRlLCBhcyBkaXN0aW5jdAoJICogZnJvbSB0aGUgdGFzayBoYXZpbmcgYmVlbiBzY2hlZHVsZWQgYXdheSBiZWZvcmUgdGhlCgkgKiBjcm9zcy1jYWxsIGFycml2ZWQuCgkgKi8KCWlmIChldmVudC0+c3RhdGUgPT0gUEVSRl9FVkVOVF9TVEFURV9FUlJPUikKCQlldmVudC0+c3RhdGUgPSBQRVJGX0VWRU5UX1NUQVRFX09GRjsKCiByZXRyeToKCXNwaW5fdW5sb2NrX2lycSgmY3R4LT5sb2NrKTsKCXRhc2tfb25jcHVfZnVuY3Rpb25fY2FsbCh0YXNrLCBfX3BlcmZfZXZlbnRfZW5hYmxlLCBldmVudCk7CgoJc3Bpbl9sb2NrX2lycSgmY3R4LT5sb2NrKTsKCgkvKgoJICogSWYgdGhlIGNvbnRleHQgaXMgYWN0aXZlIGFuZCB0aGUgZXZlbnQgaXMgc3RpbGwgb2ZmLAoJICogd2UgbmVlZCB0byByZXRyeSB0aGUgY3Jvc3MtY2FsbC4KCSAqLwoJaWYgKGN0eC0+aXNfYWN0aXZlICYmIGV2ZW50LT5zdGF0ZSA9PSBQRVJGX0VWRU5UX1NUQVRFX09GRikKCQlnb3RvIHJldHJ5OwoKCS8qCgkgKiBTaW5jZSB3ZSBoYXZlIHRoZSBsb2NrIHRoaXMgY29udGV4dCBjYW4ndCBiZSBzY2hlZHVsZWQKCSAqIGluLCBzbyB3ZSBjYW4gY2hhbmdlIHRoZSBzdGF0ZSBzYWZlbHkuCgkgKi8KCWlmIChldmVudC0+c3RhdGUgPT0gUEVSRl9FVkVOVF9TVEFURV9PRkYpCgkJX19wZXJmX2V2ZW50X21hcmtfZW5hYmxlZChldmVudCwgY3R4KTsKCiBvdXQ6CglzcGluX3VubG9ja19pcnEoJmN0eC0+bG9jayk7Cn0KCnN0YXRpYyBpbnQgcGVyZl9ldmVudF9yZWZyZXNoKHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCwgaW50IHJlZnJlc2gpCnsKCS8qCgkgKiBub3Qgc3VwcG9ydGVkIG9uIGluaGVyaXRlZCBldmVudHMKCSAqLwoJaWYgKGV2ZW50LT5hdHRyLmluaGVyaXQpCgkJcmV0dXJuIC1FSU5WQUw7CgoJYXRvbWljX2FkZChyZWZyZXNoLCAmZXZlbnQtPmV2ZW50X2xpbWl0KTsKCXBlcmZfZXZlbnRfZW5hYmxlKGV2ZW50KTsKCglyZXR1cm4gMDsKfQoKdm9pZCBfX3BlcmZfZXZlbnRfc2NoZWRfb3V0KHN0cnVjdCBwZXJmX2V2ZW50X2NvbnRleHQgKmN0eCwKCQkJICAgICAgc3RydWN0IHBlcmZfY3B1X2NvbnRleHQgKmNwdWN0eCkKewoJc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50OwoKCXNwaW5fbG9jaygmY3R4LT5sb2NrKTsKCWN0eC0+aXNfYWN0aXZlID0gMDsKCWlmIChsaWtlbHkoIWN0eC0+bnJfZXZlbnRzKSkKCQlnb3RvIG91dDsKCXVwZGF0ZV9jb250ZXh0X3RpbWUoY3R4KTsKCglwZXJmX2Rpc2FibGUoKTsKCWlmIChjdHgtPm5yX2FjdGl2ZSkgewoJCWxpc3RfZm9yX2VhY2hfZW50cnkoZXZlbnQsICZjdHgtPmdyb3VwX2xpc3QsIGdyb3VwX2VudHJ5KSB7CgkJCWlmIChldmVudCAhPSBldmVudC0+Z3JvdXBfbGVhZGVyKQoJCQkJZXZlbnRfc2NoZWRfb3V0KGV2ZW50LCBjcHVjdHgsIGN0eCk7CgkJCWVsc2UKCQkJCWdyb3VwX3NjaGVkX291dChldmVudCwgY3B1Y3R4LCBjdHgpOwoJCX0KCX0KCXBlcmZfZW5hYmxlKCk7CiBvdXQ6CglzcGluX3VubG9jaygmY3R4LT5sb2NrKTsKfQoKLyoKICogVGVzdCB3aGV0aGVyIHR3byBjb250ZXh0cyBhcmUgZXF1aXZhbGVudCwgaS5lLiB3aGV0aGVyIHRoZXkKICogaGF2ZSBib3RoIGJlZW4gY2xvbmVkIGZyb20gdGhlIHNhbWUgdmVyc2lvbiBvZiB0aGUgc2FtZSBjb250ZXh0CiAqIGFuZCB0aGV5IGJvdGggaGF2ZSB0aGUgc2FtZSBudW1iZXIgb2YgZW5hYmxlZCBldmVudHMuCiAqIElmIHRoZSBudW1iZXIgb2YgZW5hYmxlZCBldmVudHMgaXMgdGhlIHNhbWUsIHRoZW4gdGhlIHNldAogKiBvZiBlbmFibGVkIGV2ZW50cyBzaG91bGQgYmUgdGhlIHNhbWUsIGJlY2F1c2UgdGhlc2UgYXJlIGJvdGgKICogaW5oZXJpdGVkIGNvbnRleHRzLCB0aGVyZWZvcmUgd2UgY2FuJ3QgYWNjZXNzIGluZGl2aWR1YWwgZXZlbnRzCiAqIGluIHRoZW0gZGlyZWN0bHkgd2l0aCBhbiBmZDsgd2UgY2FuIG9ubHkgZW5hYmxlL2Rpc2FibGUgYWxsCiAqIGV2ZW50cyB2aWEgcHJjdGwsIG9yIGVuYWJsZS9kaXNhYmxlIGFsbCBldmVudHMgaW4gYSBmYW1pbHkKICogdmlhIGlvY3RsLCB3aGljaCB3aWxsIGhhdmUgdGhlIHNhbWUgZWZmZWN0IG9uIGJvdGggY29udGV4dHMuCiAqLwpzdGF0aWMgaW50IGNvbnRleHRfZXF1aXYoc3RydWN0IHBlcmZfZXZlbnRfY29udGV4dCAqY3R4MSwKCQkJIHN0cnVjdCBwZXJmX2V2ZW50X2NvbnRleHQgKmN0eDIpCnsKCXJldHVybiBjdHgxLT5wYXJlbnRfY3R4ICYmIGN0eDEtPnBhcmVudF9jdHggPT0gY3R4Mi0+cGFyZW50X2N0eAoJCSYmIGN0eDEtPnBhcmVudF9nZW4gPT0gY3R4Mi0+cGFyZW50X2dlbgoJCSYmICFjdHgxLT5waW5fY291bnQgJiYgIWN0eDItPnBpbl9jb3VudDsKfQoKc3RhdGljIHZvaWQgX19wZXJmX2V2ZW50X3JlYWQodm9pZCAqZXZlbnQpOwoKc3RhdGljIHZvaWQgX19wZXJmX2V2ZW50X3N5bmNfc3RhdChzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQsCgkJCQkgICAgIHN0cnVjdCBwZXJmX2V2ZW50ICpuZXh0X2V2ZW50KQp7Cgl1NjQgdmFsdWU7CgoJaWYgKCFldmVudC0+YXR0ci5pbmhlcml0X3N0YXQpCgkJcmV0dXJuOwoKCS8qCgkgKiBVcGRhdGUgdGhlIGV2ZW50IHZhbHVlLCB3ZSBjYW5ub3QgdXNlIHBlcmZfZXZlbnRfcmVhZCgpCgkgKiBiZWNhdXNlIHdlJ3JlIGluIHRoZSBtaWRkbGUgb2YgYSBjb250ZXh0IHN3aXRjaCBhbmQgaGF2ZSBJUlFzCgkgKiBkaXNhYmxlZCwgd2hpY2ggdXBzZXRzIHNtcF9jYWxsX2Z1bmN0aW9uX3NpbmdsZSgpLCBob3dldmVyCgkgKiB3ZSBrbm93IHRoZSBldmVudCBtdXN0IGJlIG9uIHRoZSBjdXJyZW50IENQVSwgdGhlcmVmb3JlIHdlCgkgKiBkb24ndCBuZWVkIHRvIHVzZSBpdC4KCSAqLwoJc3dpdGNoIChldmVudC0+c3RhdGUpIHsKCWNhc2UgUEVSRl9FVkVOVF9TVEFURV9BQ1RJVkU6CgkJX19wZXJmX2V2ZW50X3JlYWQoZXZlbnQpOwoJCWJyZWFrOwoKCWNhc2UgUEVSRl9FVkVOVF9TVEFURV9JTkFDVElWRToKCQl1cGRhdGVfZXZlbnRfdGltZXMoZXZlbnQpOwoJCWJyZWFrOwoKCWRlZmF1bHQ6CgkJYnJlYWs7Cgl9CgoJLyoKCSAqIEluIG9yZGVyIHRvIGtlZXAgcGVyLXRhc2sgc3RhdHMgcmVsaWFibGUgd2UgbmVlZCB0byBmbGlwIHRoZSBldmVudAoJICogdmFsdWVzIHdoZW4gd2UgZmxpcCB0aGUgY29udGV4dHMuCgkgKi8KCXZhbHVlID0gYXRvbWljNjRfcmVhZCgmbmV4dF9ldmVudC0+Y291bnQpOwoJdmFsdWUgPSBhdG9taWM2NF94Y2hnKCZldmVudC0+Y291bnQsIHZhbHVlKTsKCWF0b21pYzY0X3NldCgmbmV4dF9ldmVudC0+Y291bnQsIHZhbHVlKTsKCglzd2FwKGV2ZW50LT50b3RhbF90aW1lX2VuYWJsZWQsIG5leHRfZXZlbnQtPnRvdGFsX3RpbWVfZW5hYmxlZCk7Cglzd2FwKGV2ZW50LT50b3RhbF90aW1lX3J1bm5pbmcsIG5leHRfZXZlbnQtPnRvdGFsX3RpbWVfcnVubmluZyk7CgoJLyoKCSAqIFNpbmNlIHdlIHN3aXp6bGVkIHRoZSB2YWx1ZXMsIHVwZGF0ZSB0aGUgdXNlciB2aXNpYmxlIGRhdGEgdG9vLgoJICovCglwZXJmX2V2ZW50X3VwZGF0ZV91c2VycGFnZShldmVudCk7CglwZXJmX2V2ZW50X3VwZGF0ZV91c2VycGFnZShuZXh0X2V2ZW50KTsKfQoKI2RlZmluZSBsaXN0X25leHRfZW50cnkocG9zLCBtZW1iZXIpIFwKCWxpc3RfZW50cnkocG9zLT5tZW1iZXIubmV4dCwgdHlwZW9mKCpwb3MpLCBtZW1iZXIpCgpzdGF0aWMgdm9pZCBwZXJmX2V2ZW50X3N5bmNfc3RhdChzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0ICpjdHgsCgkJCQkgICBzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0ICpuZXh0X2N0eCkKewoJc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50LCAqbmV4dF9ldmVudDsKCglpZiAoIWN0eC0+bnJfc3RhdCkKCQlyZXR1cm47CgoJZXZlbnQgPSBsaXN0X2ZpcnN0X2VudHJ5KCZjdHgtPmV2ZW50X2xpc3QsCgkJCQkgICBzdHJ1Y3QgcGVyZl9ldmVudCwgZXZlbnRfZW50cnkpOwoKCW5leHRfZXZlbnQgPSBsaXN0X2ZpcnN0X2VudHJ5KCZuZXh0X2N0eC0+ZXZlbnRfbGlzdCwKCQkJCQlzdHJ1Y3QgcGVyZl9ldmVudCwgZXZlbnRfZW50cnkpOwoKCXdoaWxlICgmZXZlbnQtPmV2ZW50X2VudHJ5ICE9ICZjdHgtPmV2ZW50X2xpc3QgJiYKCSAgICAgICAmbmV4dF9ldmVudC0+ZXZlbnRfZW50cnkgIT0gJm5leHRfY3R4LT5ldmVudF9saXN0KSB7CgoJCV9fcGVyZl9ldmVudF9zeW5jX3N0YXQoZXZlbnQsIG5leHRfZXZlbnQpOwoKCQlldmVudCA9IGxpc3RfbmV4dF9lbnRyeShldmVudCwgZXZlbnRfZW50cnkpOwoJCW5leHRfZXZlbnQgPSBsaXN0X25leHRfZW50cnkobmV4dF9ldmVudCwgZXZlbnRfZW50cnkpOwoJfQp9CgovKgogKiBDYWxsZWQgZnJvbSBzY2hlZHVsZXIgdG8gcmVtb3ZlIHRoZSBldmVudHMgb2YgdGhlIGN1cnJlbnQgdGFzaywKICogd2l0aCBpbnRlcnJ1cHRzIGRpc2FibGVkLgogKgogKiBXZSBzdG9wIGVhY2ggZXZlbnQgYW5kIHVwZGF0ZSB0aGUgZXZlbnQgdmFsdWUgaW4gZXZlbnQtPmNvdW50LgogKgogKiBUaGlzIGRvZXMgbm90IHByb3RlY3QgdXMgYWdhaW5zdCBOTUksIGJ1dCBkaXNhYmxlKCkKICogc2V0cyB0aGUgZGlzYWJsZWQgYml0IGluIHRoZSBjb250cm9sIGZpZWxkIG9mIGV2ZW50IF9iZWZvcmVfCiAqIGFjY2Vzc2luZyB0aGUgZXZlbnQgY29udHJvbCByZWdpc3Rlci4gSWYgYSBOTUkgaGl0cywgdGhlbiBpdCB3aWxsCiAqIG5vdCByZXN0YXJ0IHRoZSBldmVudC4KICovCnZvaWQgcGVyZl9ldmVudF90YXNrX3NjaGVkX291dChzdHJ1Y3QgdGFza19zdHJ1Y3QgKnRhc2ssCgkJCQkgc3RydWN0IHRhc2tfc3RydWN0ICpuZXh0LCBpbnQgY3B1KQp7CglzdHJ1Y3QgcGVyZl9jcHVfY29udGV4dCAqY3B1Y3R4ID0gJnBlcl9jcHUocGVyZl9jcHVfY29udGV4dCwgY3B1KTsKCXN0cnVjdCBwZXJmX2V2ZW50X2NvbnRleHQgKmN0eCA9IHRhc2stPnBlcmZfZXZlbnRfY3R4cDsKCXN0cnVjdCBwZXJmX2V2ZW50X2NvbnRleHQgKm5leHRfY3R4OwoJc3RydWN0IHBlcmZfZXZlbnRfY29udGV4dCAqcGFyZW50OwoJc3RydWN0IHB0X3JlZ3MgKnJlZ3M7CglpbnQgZG9fc3dpdGNoID0gMTsKCglyZWdzID0gdGFza19wdF9yZWdzKHRhc2spOwoJcGVyZl9zd19ldmVudChQRVJGX0NPVU5UX1NXX0NPTlRFWFRfU1dJVENIRVMsIDEsIDEsIHJlZ3MsIDApOwoKCWlmIChsaWtlbHkoIWN0eCB8fCAhY3B1Y3R4LT50YXNrX2N0eCkpCgkJcmV0dXJuOwoKCXVwZGF0ZV9jb250ZXh0X3RpbWUoY3R4KTsKCglyY3VfcmVhZF9sb2NrKCk7CglwYXJlbnQgPSByY3VfZGVyZWZlcmVuY2UoY3R4LT5wYXJlbnRfY3R4KTsKCW5leHRfY3R4ID0gbmV4dC0+cGVyZl9ldmVudF9jdHhwOwoJaWYgKHBhcmVudCAmJiBuZXh0X2N0eCAmJgoJICAgIHJjdV9kZXJlZmVyZW5jZShuZXh0X2N0eC0+cGFyZW50X2N0eCkgPT0gcGFyZW50KSB7CgkJLyoKCQkgKiBMb29rcyBsaWtlIHRoZSB0d28gY29udGV4dHMgYXJlIGNsb25lcywgc28gd2UgbWlnaHQgYmUKCQkgKiBhYmxlIHRvIG9wdGltaXplIHRoZSBjb250ZXh0IHN3aXRjaC4gIFdlIGxvY2sgYm90aAoJCSAqIGNvbnRleHRzIGFuZCBjaGVjayB0aGF0IHRoZXkgYXJlIGNsb25lcyB1bmRlciB0aGUKCQkgKiBsb2NrIChpbmNsdWRpbmcgcmUtY2hlY2tpbmcgdGhhdCBuZWl0aGVyIGhhcyBiZWVuCgkJICogdW5jbG9uZWQgaW4gdGhlIG1lYW50aW1lKS4gIEl0IGRvZXNuJ3QgbWF0dGVyIHdoaWNoCgkJICogb3JkZXIgd2UgdGFrZSB0aGUgbG9ja3MgYmVjYXVzZSBubyBvdGhlciBjcHUgY291bGQKCQkgKiBiZSB0cnlpbmcgdG8gbG9jayBib3RoIG9mIHRoZXNlIHRhc2tzLgoJCSAqLwoJCXNwaW5fbG9jaygmY3R4LT5sb2NrKTsKCQlzcGluX2xvY2tfbmVzdGVkKCZuZXh0X2N0eC0+bG9jaywgU0lOR0xFX0RFUFRIX05FU1RJTkcpOwoJCWlmIChjb250ZXh0X2VxdWl2KGN0eCwgbmV4dF9jdHgpKSB7CgkJCS8qCgkJCSAqIFhYWCBkbyB3ZSBuZWVkIGEgbWVtb3J5IGJhcnJpZXIgb2Ygc29ydHMKCQkJICogd3J0IHRvIHJjdV9kZXJlZmVyZW5jZSgpIG9mIHBlcmZfZXZlbnRfY3R4cAoJCQkgKi8KCQkJdGFzay0+cGVyZl9ldmVudF9jdHhwID0gbmV4dF9jdHg7CgkJCW5leHQtPnBlcmZfZXZlbnRfY3R4cCA9IGN0eDsKCQkJY3R4LT50YXNrID0gbmV4dDsKCQkJbmV4dF9jdHgtPnRhc2sgPSB0YXNrOwoJCQlkb19zd2l0Y2ggPSAwOwoKCQkJcGVyZl9ldmVudF9zeW5jX3N0YXQoY3R4LCBuZXh0X2N0eCk7CgkJfQoJCXNwaW5fdW5sb2NrKCZuZXh0X2N0eC0+bG9jayk7CgkJc3Bpbl91bmxvY2soJmN0eC0+bG9jayk7Cgl9CglyY3VfcmVhZF91bmxvY2soKTsKCglpZiAoZG9fc3dpdGNoKSB7CgkJX19wZXJmX2V2ZW50X3NjaGVkX291dChjdHgsIGNwdWN0eCk7CgkJY3B1Y3R4LT50YXNrX2N0eCA9IE5VTEw7Cgl9Cn0KCi8qCiAqIENhbGxlZCB3aXRoIElSUXMgZGlzYWJsZWQKICovCnN0YXRpYyB2b2lkIF9fcGVyZl9ldmVudF90YXNrX3NjaGVkX291dChzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0ICpjdHgpCnsKCXN0cnVjdCBwZXJmX2NwdV9jb250ZXh0ICpjcHVjdHggPSAmX19nZXRfY3B1X3ZhcihwZXJmX2NwdV9jb250ZXh0KTsKCglpZiAoIWNwdWN0eC0+dGFza19jdHgpCgkJcmV0dXJuOwoKCWlmIChXQVJOX09OX09OQ0UoY3R4ICE9IGNwdWN0eC0+dGFza19jdHgpKQoJCXJldHVybjsKCglfX3BlcmZfZXZlbnRfc2NoZWRfb3V0KGN0eCwgY3B1Y3R4KTsKCWNwdWN0eC0+dGFza19jdHggPSBOVUxMOwp9CgovKgogKiBDYWxsZWQgd2l0aCBJUlFzIGRpc2FibGVkCiAqLwpzdGF0aWMgdm9pZCBwZXJmX2V2ZW50X2NwdV9zY2hlZF9vdXQoc3RydWN0IHBlcmZfY3B1X2NvbnRleHQgKmNwdWN0eCkKewoJX19wZXJmX2V2ZW50X3NjaGVkX291dCgmY3B1Y3R4LT5jdHgsIGNwdWN0eCk7Cn0KCnN0YXRpYyB2b2lkCl9fcGVyZl9ldmVudF9zY2hlZF9pbihzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0ICpjdHgsCgkJCXN0cnVjdCBwZXJmX2NwdV9jb250ZXh0ICpjcHVjdHgsIGludCBjcHUpCnsKCXN0cnVjdCBwZXJmX2V2ZW50ICpldmVudDsKCWludCBjYW5fYWRkX2h3ID0gMTsKCglzcGluX2xvY2soJmN0eC0+bG9jayk7CgljdHgtPmlzX2FjdGl2ZSA9IDE7CglpZiAobGlrZWx5KCFjdHgtPm5yX2V2ZW50cykpCgkJZ290byBvdXQ7CgoJY3R4LT50aW1lc3RhbXAgPSBwZXJmX2Nsb2NrKCk7CgoJcGVyZl9kaXNhYmxlKCk7CgoJLyoKCSAqIEZpcnN0IGdvIHRocm91Z2ggdGhlIGxpc3QgYW5kIHB1dCBvbiBhbnkgcGlubmVkIGdyb3VwcwoJICogaW4gb3JkZXIgdG8gZ2l2ZSB0aGVtIHRoZSBiZXN0IGNoYW5jZSBvZiBnb2luZyBvbi4KCSAqLwoJbGlzdF9mb3JfZWFjaF9lbnRyeShldmVudCwgJmN0eC0+Z3JvdXBfbGlzdCwgZ3JvdXBfZW50cnkpIHsKCQlpZiAoZXZlbnQtPnN0YXRlIDw9IFBFUkZfRVZFTlRfU1RBVEVfT0ZGIHx8CgkJICAgICFldmVudC0+YXR0ci5waW5uZWQpCgkJCWNvbnRpbnVlOwoJCWlmIChldmVudC0+Y3B1ICE9IC0xICYmIGV2ZW50LT5jcHUgIT0gY3B1KQoJCQljb250aW51ZTsKCgkJaWYgKGV2ZW50ICE9IGV2ZW50LT5ncm91cF9sZWFkZXIpCgkJCWV2ZW50X3NjaGVkX2luKGV2ZW50LCBjcHVjdHgsIGN0eCwgY3B1KTsKCQllbHNlIHsKCQkJaWYgKGdyb3VwX2Nhbl9nb19vbihldmVudCwgY3B1Y3R4LCAxKSkKCQkJCWdyb3VwX3NjaGVkX2luKGV2ZW50LCBjcHVjdHgsIGN0eCwgY3B1KTsKCQl9CgoJCS8qCgkJICogSWYgdGhpcyBwaW5uZWQgZ3JvdXAgaGFzbid0IGJlZW4gc2NoZWR1bGVkLAoJCSAqIHB1dCBpdCBpbiBlcnJvciBzdGF0ZS4KCQkgKi8KCQlpZiAoZXZlbnQtPnN0YXRlID09IFBFUkZfRVZFTlRfU1RBVEVfSU5BQ1RJVkUpIHsKCQkJdXBkYXRlX2dyb3VwX3RpbWVzKGV2ZW50KTsKCQkJZXZlbnQtPnN0YXRlID0gUEVSRl9FVkVOVF9TVEFURV9FUlJPUjsKCQl9Cgl9CgoJbGlzdF9mb3JfZWFjaF9lbnRyeShldmVudCwgJmN0eC0+Z3JvdXBfbGlzdCwgZ3JvdXBfZW50cnkpIHsKCQkvKgoJCSAqIElnbm9yZSBldmVudHMgaW4gT0ZGIG9yIEVSUk9SIHN0YXRlLCBhbmQKCQkgKiBpZ25vcmUgcGlubmVkIGV2ZW50cyBzaW5jZSB3ZSBkaWQgdGhlbSBhbHJlYWR5LgoJCSAqLwoJCWlmIChldmVudC0+c3RhdGUgPD0gUEVSRl9FVkVOVF9TVEFURV9PRkYgfHwKCQkgICAgZXZlbnQtPmF0dHIucGlubmVkKQoJCQljb250aW51ZTsKCgkJLyoKCQkgKiBMaXN0ZW4gdG8gdGhlICdjcHUnIHNjaGVkdWxpbmcgZmlsdGVyIGNvbnN0cmFpbnQKCQkgKiBvZiBldmVudHM6CgkJICovCgkJaWYgKGV2ZW50LT5jcHUgIT0gLTEgJiYgZXZlbnQtPmNwdSAhPSBjcHUpCgkJCWNvbnRpbnVlOwoKCQlpZiAoZXZlbnQgIT0gZXZlbnQtPmdyb3VwX2xlYWRlcikgewoJCQlpZiAoZXZlbnRfc2NoZWRfaW4oZXZlbnQsIGNwdWN0eCwgY3R4LCBjcHUpKQoJCQkJY2FuX2FkZF9odyA9IDA7CgkJfSBlbHNlIHsKCQkJaWYgKGdyb3VwX2Nhbl9nb19vbihldmVudCwgY3B1Y3R4LCBjYW5fYWRkX2h3KSkgewoJCQkJaWYgKGdyb3VwX3NjaGVkX2luKGV2ZW50LCBjcHVjdHgsIGN0eCwgY3B1KSkKCQkJCQljYW5fYWRkX2h3ID0gMDsKCQkJfQoJCX0KCX0KCXBlcmZfZW5hYmxlKCk7CiBvdXQ6CglzcGluX3VubG9jaygmY3R4LT5sb2NrKTsKfQoKLyoKICogQ2FsbGVkIGZyb20gc2NoZWR1bGVyIHRvIGFkZCB0aGUgZXZlbnRzIG9mIHRoZSBjdXJyZW50IHRhc2sKICogd2l0aCBpbnRlcnJ1cHRzIGRpc2FibGVkLgogKgogKiBXZSByZXN0b3JlIHRoZSBldmVudCB2YWx1ZSBhbmQgdGhlbiBlbmFibGUgaXQuCiAqCiAqIFRoaXMgZG9lcyBub3QgcHJvdGVjdCB1cyBhZ2FpbnN0IE5NSSwgYnV0IGVuYWJsZSgpCiAqIHNldHMgdGhlIGVuYWJsZWQgYml0IGluIHRoZSBjb250cm9sIGZpZWxkIG9mIGV2ZW50IF9iZWZvcmVfCiAqIGFjY2Vzc2luZyB0aGUgZXZlbnQgY29udHJvbCByZWdpc3Rlci4gSWYgYSBOTUkgaGl0cywgdGhlbiBpdCB3aWxsCiAqIGtlZXAgdGhlIGV2ZW50IHJ1bm5pbmcuCiAqLwp2b2lkIHBlcmZfZXZlbnRfdGFza19zY2hlZF9pbihzdHJ1Y3QgdGFza19zdHJ1Y3QgKnRhc2ssIGludCBjcHUpCnsKCXN0cnVjdCBwZXJmX2NwdV9jb250ZXh0ICpjcHVjdHggPSAmcGVyX2NwdShwZXJmX2NwdV9jb250ZXh0LCBjcHUpOwoJc3RydWN0IHBlcmZfZXZlbnRfY29udGV4dCAqY3R4ID0gdGFzay0+cGVyZl9ldmVudF9jdHhwOwoKCWlmIChsaWtlbHkoIWN0eCkpCgkJcmV0dXJuOwoJaWYgKGNwdWN0eC0+dGFza19jdHggPT0gY3R4KQoJCXJldHVybjsKCV9fcGVyZl9ldmVudF9zY2hlZF9pbihjdHgsIGNwdWN0eCwgY3B1KTsKCWNwdWN0eC0+dGFza19jdHggPSBjdHg7Cn0KCnN0YXRpYyB2b2lkIHBlcmZfZXZlbnRfY3B1X3NjaGVkX2luKHN0cnVjdCBwZXJmX2NwdV9jb250ZXh0ICpjcHVjdHgsIGludCBjcHUpCnsKCXN0cnVjdCBwZXJmX2V2ZW50X2NvbnRleHQgKmN0eCA9ICZjcHVjdHgtPmN0eDsKCglfX3BlcmZfZXZlbnRfc2NoZWRfaW4oY3R4LCBjcHVjdHgsIGNwdSk7Cn0KCiNkZWZpbmUgTUFYX0lOVEVSUlVQVFMgKH4wVUxMKQoKc3RhdGljIHZvaWQgcGVyZl9sb2dfdGhyb3R0bGUoc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50LCBpbnQgZW5hYmxlKTsKCnN0YXRpYyB2b2lkIHBlcmZfYWRqdXN0X3BlcmlvZChzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQsIHU2NCBldmVudHMpCnsKCXN0cnVjdCBod19wZXJmX2V2ZW50ICpod2MgPSAmZXZlbnQtPmh3OwoJdTY0IHBlcmlvZCwgc2FtcGxlX3BlcmlvZDsKCXM2NCBkZWx0YTsKCglldmVudHMgKj0gaHdjLT5zYW1wbGVfcGVyaW9kOwoJcGVyaW9kID0gZGl2NjRfdTY0KGV2ZW50cywgZXZlbnQtPmF0dHIuc2FtcGxlX2ZyZXEpOwoKCWRlbHRhID0gKHM2NCkocGVyaW9kIC0gaHdjLT5zYW1wbGVfcGVyaW9kKTsKCWRlbHRhID0gKGRlbHRhICsgNykgLyA4OyAvKiBsb3cgcGFzcyBmaWx0ZXIgKi8KCglzYW1wbGVfcGVyaW9kID0gaHdjLT5zYW1wbGVfcGVyaW9kICsgZGVsdGE7CgoJaWYgKCFzYW1wbGVfcGVyaW9kKQoJCXNhbXBsZV9wZXJpb2QgPSAxOwoKCWh3Yy0+c2FtcGxlX3BlcmlvZCA9IHNhbXBsZV9wZXJpb2Q7Cn0KCnN0YXRpYyB2b2lkIHBlcmZfY3R4X2FkanVzdF9mcmVxKHN0cnVjdCBwZXJmX2V2ZW50X2NvbnRleHQgKmN0eCkKewoJc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50OwoJc3RydWN0IGh3X3BlcmZfZXZlbnQgKmh3YzsKCXU2NCBpbnRlcnJ1cHRzLCBmcmVxOwoKCXNwaW5fbG9jaygmY3R4LT5sb2NrKTsKCWxpc3RfZm9yX2VhY2hfZW50cnkoZXZlbnQsICZjdHgtPmdyb3VwX2xpc3QsIGdyb3VwX2VudHJ5KSB7CgkJaWYgKGV2ZW50LT5zdGF0ZSAhPSBQRVJGX0VWRU5UX1NUQVRFX0FDVElWRSkKCQkJY29udGludWU7CgoJCWh3YyA9ICZldmVudC0+aHc7CgoJCWludGVycnVwdHMgPSBod2MtPmludGVycnVwdHM7CgkJaHdjLT5pbnRlcnJ1cHRzID0gMDsKCgkJLyoKCQkgKiB1bnRocm90dGxlIGV2ZW50cyBvbiB0aGUgdGljawoJCSAqLwoJCWlmIChpbnRlcnJ1cHRzID09IE1BWF9JTlRFUlJVUFRTKSB7CgkJCXBlcmZfbG9nX3Rocm90dGxlKGV2ZW50LCAxKTsKCQkJZXZlbnQtPnBtdS0+dW50aHJvdHRsZShldmVudCk7CgkJCWludGVycnVwdHMgPSAyKnN5c2N0bF9wZXJmX2V2ZW50X3NhbXBsZV9yYXRlL0haOwoJCX0KCgkJaWYgKCFldmVudC0+YXR0ci5mcmVxIHx8ICFldmVudC0+YXR0ci5zYW1wbGVfZnJlcSkKCQkJY29udGludWU7CgoJCS8qCgkJICogaWYgdGhlIHNwZWNpZmllZCBmcmVxIDwgSFogdGhlbiB3ZSBuZWVkIHRvIHNraXAgdGlja3MKCQkgKi8KCQlpZiAoZXZlbnQtPmF0dHIuc2FtcGxlX2ZyZXEgPCBIWikgewoJCQlmcmVxID0gZXZlbnQtPmF0dHIuc2FtcGxlX2ZyZXE7CgoJCQlod2MtPmZyZXFfY291bnQgKz0gZnJlcTsKCQkJaHdjLT5mcmVxX2ludGVycnVwdHMgKz0gaW50ZXJydXB0czsKCgkJCWlmIChod2MtPmZyZXFfY291bnQgPCBIWikKCQkJCWNvbnRpbnVlOwoKCQkJaW50ZXJydXB0cyA9IGh3Yy0+ZnJlcV9pbnRlcnJ1cHRzOwoJCQlod2MtPmZyZXFfaW50ZXJydXB0cyA9IDA7CgkJCWh3Yy0+ZnJlcV9jb3VudCAtPSBIWjsKCQl9IGVsc2UKCQkJZnJlcSA9IEhaOwoKCQlwZXJmX2FkanVzdF9wZXJpb2QoZXZlbnQsIGZyZXEgKiBpbnRlcnJ1cHRzKTsKCgkJLyoKCQkgKiBJbiBvcmRlciB0byBhdm9pZCBiZWluZyBzdGFsbGVkIGJ5IGFuIChhY2NpZGVudGFsKSBodWdlCgkJICogc2FtcGxlIHBlcmlvZCwgZm9yY2UgcmVzZXQgdGhlIHNhbXBsZSBwZXJpb2QgaWYgd2UgZGlkbid0CgkJICogZ2V0IGFueSBldmVudHMgaW4gdGhpcyBmcmVxIHBlcmlvZC4KCQkgKi8KCQlpZiAoIWludGVycnVwdHMpIHsKCQkJcGVyZl9kaXNhYmxlKCk7CgkJCWV2ZW50LT5wbXUtPmRpc2FibGUoZXZlbnQpOwoJCQlhdG9taWM2NF9zZXQoJmh3Yy0+cGVyaW9kX2xlZnQsIDApOwoJCQlldmVudC0+cG11LT5lbmFibGUoZXZlbnQpOwoJCQlwZXJmX2VuYWJsZSgpOwoJCX0KCX0KCXNwaW5fdW5sb2NrKCZjdHgtPmxvY2spOwp9CgovKgogKiBSb3VuZC1yb2JpbiBhIGNvbnRleHQncyBldmVudHM6CiAqLwpzdGF0aWMgdm9pZCByb3RhdGVfY3R4KHN0cnVjdCBwZXJmX2V2ZW50X2NvbnRleHQgKmN0eCkKewoJc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50OwoKCWlmICghY3R4LT5ucl9ldmVudHMpCgkJcmV0dXJuOwoKCXNwaW5fbG9jaygmY3R4LT5sb2NrKTsKCS8qCgkgKiBSb3RhdGUgdGhlIGZpcnN0IGVudHJ5IGxhc3QgKHdvcmtzIGp1c3QgZmluZSBmb3IgZ3JvdXAgZXZlbnRzIHRvbyk6CgkgKi8KCXBlcmZfZGlzYWJsZSgpOwoJbGlzdF9mb3JfZWFjaF9lbnRyeShldmVudCwgJmN0eC0+Z3JvdXBfbGlzdCwgZ3JvdXBfZW50cnkpIHsKCQlsaXN0X21vdmVfdGFpbCgmZXZlbnQtPmdyb3VwX2VudHJ5LCAmY3R4LT5ncm91cF9saXN0KTsKCQlicmVhazsKCX0KCXBlcmZfZW5hYmxlKCk7CgoJc3Bpbl91bmxvY2soJmN0eC0+bG9jayk7Cn0KCnZvaWQgcGVyZl9ldmVudF90YXNrX3RpY2soc3RydWN0IHRhc2tfc3RydWN0ICpjdXJyLCBpbnQgY3B1KQp7CglzdHJ1Y3QgcGVyZl9jcHVfY29udGV4dCAqY3B1Y3R4OwoJc3RydWN0IHBlcmZfZXZlbnRfY29udGV4dCAqY3R4OwoKCWlmICghYXRvbWljX3JlYWQoJm5yX2V2ZW50cykpCgkJcmV0dXJuOwoKCWNwdWN0eCA9ICZwZXJfY3B1KHBlcmZfY3B1X2NvbnRleHQsIGNwdSk7CgljdHggPSBjdXJyLT5wZXJmX2V2ZW50X2N0eHA7CgoJcGVyZl9jdHhfYWRqdXN0X2ZyZXEoJmNwdWN0eC0+Y3R4KTsKCWlmIChjdHgpCgkJcGVyZl9jdHhfYWRqdXN0X2ZyZXEoY3R4KTsKCglwZXJmX2V2ZW50X2NwdV9zY2hlZF9vdXQoY3B1Y3R4KTsKCWlmIChjdHgpCgkJX19wZXJmX2V2ZW50X3Rhc2tfc2NoZWRfb3V0KGN0eCk7CgoJcm90YXRlX2N0eCgmY3B1Y3R4LT5jdHgpOwoJaWYgKGN0eCkKCQlyb3RhdGVfY3R4KGN0eCk7CgoJcGVyZl9ldmVudF9jcHVfc2NoZWRfaW4oY3B1Y3R4LCBjcHUpOwoJaWYgKGN0eCkKCQlwZXJmX2V2ZW50X3Rhc2tfc2NoZWRfaW4oY3VyciwgY3B1KTsKfQoKLyoKICogRW5hYmxlIGFsbCBvZiBhIHRhc2sncyBldmVudHMgdGhhdCBoYXZlIGJlZW4gbWFya2VkIGVuYWJsZS1vbi1leGVjLgogKiBUaGlzIGV4cGVjdHMgdGFzayA9PSBjdXJyZW50LgogKi8Kc3RhdGljIHZvaWQgcGVyZl9ldmVudF9lbmFibGVfb25fZXhlYyhzdHJ1Y3QgdGFza19zdHJ1Y3QgKnRhc2spCnsKCXN0cnVjdCBwZXJmX2V2ZW50X2NvbnRleHQgKmN0eDsKCXN0cnVjdCBwZXJmX2V2ZW50ICpldmVudDsKCXVuc2lnbmVkIGxvbmcgZmxhZ3M7CglpbnQgZW5hYmxlZCA9IDA7CgoJbG9jYWxfaXJxX3NhdmUoZmxhZ3MpOwoJY3R4ID0gdGFzay0+cGVyZl9ldmVudF9jdHhwOwoJaWYgKCFjdHggfHwgIWN0eC0+bnJfZXZlbnRzKQoJCWdvdG8gb3V0OwoKCV9fcGVyZl9ldmVudF90YXNrX3NjaGVkX291dChjdHgpOwoKCXNwaW5fbG9jaygmY3R4LT5sb2NrKTsKCglsaXN0X2Zvcl9lYWNoX2VudHJ5KGV2ZW50LCAmY3R4LT5ncm91cF9saXN0LCBncm91cF9lbnRyeSkgewoJCWlmICghZXZlbnQtPmF0dHIuZW5hYmxlX29uX2V4ZWMpCgkJCWNvbnRpbnVlOwoJCWV2ZW50LT5hdHRyLmVuYWJsZV9vbl9leGVjID0gMDsKCQlpZiAoZXZlbnQtPnN0YXRlID49IFBFUkZfRVZFTlRfU1RBVEVfSU5BQ1RJVkUpCgkJCWNvbnRpbnVlOwoJCV9fcGVyZl9ldmVudF9tYXJrX2VuYWJsZWQoZXZlbnQsIGN0eCk7CgkJZW5hYmxlZCA9IDE7Cgl9CgoJLyoKCSAqIFVuY2xvbmUgdGhpcyBjb250ZXh0IGlmIHdlIGVuYWJsZWQgYW55IGV2ZW50LgoJICovCglpZiAoZW5hYmxlZCkKCQl1bmNsb25lX2N0eChjdHgpOwoKCXNwaW5fdW5sb2NrKCZjdHgtPmxvY2spOwoKCXBlcmZfZXZlbnRfdGFza19zY2hlZF9pbih0YXNrLCBzbXBfcHJvY2Vzc29yX2lkKCkpOwogb3V0OgoJbG9jYWxfaXJxX3Jlc3RvcmUoZmxhZ3MpOwp9CgovKgogKiBDcm9zcyBDUFUgY2FsbCB0byByZWFkIHRoZSBoYXJkd2FyZSBldmVudAogKi8Kc3RhdGljIHZvaWQgX19wZXJmX2V2ZW50X3JlYWQodm9pZCAqaW5mbykKewoJc3RydWN0IHBlcmZfY3B1X2NvbnRleHQgKmNwdWN0eCA9ICZfX2dldF9jcHVfdmFyKHBlcmZfY3B1X2NvbnRleHQpOwoJc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50ID0gaW5mbzsKCXN0cnVjdCBwZXJmX2V2ZW50X2NvbnRleHQgKmN0eCA9IGV2ZW50LT5jdHg7Cgl1bnNpZ25lZCBsb25nIGZsYWdzOwoKCS8qCgkgKiBJZiB0aGlzIGlzIGEgdGFzayBjb250ZXh0LCB3ZSBuZWVkIHRvIGNoZWNrIHdoZXRoZXIgaXQgaXMKCSAqIHRoZSBjdXJyZW50IHRhc2sgY29udGV4dCBvZiB0aGlzIGNwdS4gIElmIG5vdCBpdCBoYXMgYmVlbgoJICogc2NoZWR1bGVkIG91dCBiZWZvcmUgdGhlIHNtcCBjYWxsIGFycml2ZWQuICBJbiB0aGF0IGNhc2UKCSAqIGV2ZW50LT5jb3VudCB3b3VsZCBoYXZlIGJlZW4gdXBkYXRlZCB0byBhIHJlY2VudCBzYW1wbGUKCSAqIHdoZW4gdGhlIGV2ZW50IHdhcyBzY2hlZHVsZWQgb3V0LgoJICovCglpZiAoY3R4LT50YXNrICYmIGNwdWN0eC0+dGFza19jdHggIT0gY3R4KQoJCXJldHVybjsKCglsb2NhbF9pcnFfc2F2ZShmbGFncyk7CglpZiAoY3R4LT5pc19hY3RpdmUpCgkJdXBkYXRlX2NvbnRleHRfdGltZShjdHgpOwoJZXZlbnQtPnBtdS0+cmVhZChldmVudCk7Cgl1cGRhdGVfZXZlbnRfdGltZXMoZXZlbnQpOwoJbG9jYWxfaXJxX3Jlc3RvcmUoZmxhZ3MpOwp9CgpzdGF0aWMgdTY0IHBlcmZfZXZlbnRfcmVhZChzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQpCnsKCS8qCgkgKiBJZiBldmVudCBpcyBlbmFibGVkIGFuZCBjdXJyZW50bHkgYWN0aXZlIG9uIGEgQ1BVLCB1cGRhdGUgdGhlCgkgKiB2YWx1ZSBpbiB0aGUgZXZlbnQgc3RydWN0dXJlOgoJICovCglpZiAoZXZlbnQtPnN0YXRlID09IFBFUkZfRVZFTlRfU1RBVEVfQUNUSVZFKSB7CgkJc21wX2NhbGxfZnVuY3Rpb25fc2luZ2xlKGV2ZW50LT5vbmNwdSwKCQkJCQkgX19wZXJmX2V2ZW50X3JlYWQsIGV2ZW50LCAxKTsKCX0gZWxzZSBpZiAoZXZlbnQtPnN0YXRlID09IFBFUkZfRVZFTlRfU1RBVEVfSU5BQ1RJVkUpIHsKCQl1cGRhdGVfZXZlbnRfdGltZXMoZXZlbnQpOwoJfQoKCXJldHVybiBhdG9taWM2NF9yZWFkKCZldmVudC0+Y291bnQpOwp9CgovKgogKiBJbml0aWFsaXplIHRoZSBwZXJmX2V2ZW50IGNvbnRleHQgaW4gYSB0YXNrX3N0cnVjdDoKICovCnN0YXRpYyB2b2lkCl9fcGVyZl9ldmVudF9pbml0X2NvbnRleHQoc3RydWN0IHBlcmZfZXZlbnRfY29udGV4dCAqY3R4LAoJCQkgICAgc3RydWN0IHRhc2tfc3RydWN0ICp0YXNrKQp7CgltZW1zZXQoY3R4LCAwLCBzaXplb2YoKmN0eCkpOwoJc3Bpbl9sb2NrX2luaXQoJmN0eC0+bG9jayk7CgltdXRleF9pbml0KCZjdHgtPm11dGV4KTsKCUlOSVRfTElTVF9IRUFEKCZjdHgtPmdyb3VwX2xpc3QpOwoJSU5JVF9MSVNUX0hFQUQoJmN0eC0+ZXZlbnRfbGlzdCk7CglhdG9taWNfc2V0KCZjdHgtPnJlZmNvdW50LCAxKTsKCWN0eC0+dGFzayA9IHRhc2s7Cn0KCnN0YXRpYyBzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0ICpmaW5kX2dldF9jb250ZXh0KHBpZF90IHBpZCwgaW50IGNwdSkKewoJc3RydWN0IHBlcmZfZXZlbnRfY29udGV4dCAqY3R4OwoJc3RydWN0IHBlcmZfY3B1X2NvbnRleHQgKmNwdWN0eDsKCXN0cnVjdCB0YXNrX3N0cnVjdCAqdGFzazsKCXVuc2lnbmVkIGxvbmcgZmxhZ3M7CglpbnQgZXJyOwoKCS8qCgkgKiBJZiBjcHUgaXMgbm90IGEgd2lsZGNhcmQgdGhlbiB0aGlzIGlzIGEgcGVyY3B1IGV2ZW50OgoJICovCglpZiAoY3B1ICE9IC0xKSB7CgkJLyogTXVzdCBiZSByb290IHRvIG9wZXJhdGUgb24gYSBDUFUgZXZlbnQ6ICovCgkJaWYgKHBlcmZfcGFyYW5vaWRfY3B1KCkgJiYgIWNhcGFibGUoQ0FQX1NZU19BRE1JTikpCgkJCXJldHVybiBFUlJfUFRSKC1FQUNDRVMpOwoKCQlpZiAoY3B1IDwgMCB8fCBjcHUgPiBudW1fcG9zc2libGVfY3B1cygpKQoJCQlyZXR1cm4gRVJSX1BUUigtRUlOVkFMKTsKCgkJLyoKCQkgKiBXZSBjb3VsZCBiZSBjbGV2ZXIgYW5kIGFsbG93IHRvIGF0dGFjaCBhIGV2ZW50IHRvIGFuCgkJICogb2ZmbGluZSBDUFUgYW5kIGFjdGl2YXRlIGl0IHdoZW4gdGhlIENQVSBjb21lcyB1cCwgYnV0CgkJICogdGhhdCdzIGZvciBsYXRlci4KCQkgKi8KCQlpZiAoIWNwdV9pc3NldChjcHUsIGNwdV9vbmxpbmVfbWFwKSkKCQkJcmV0dXJuIEVSUl9QVFIoLUVOT0RFVik7CgoJCWNwdWN0eCA9ICZwZXJfY3B1KHBlcmZfY3B1X2NvbnRleHQsIGNwdSk7CgkJY3R4ID0gJmNwdWN0eC0+Y3R4OwoJCWdldF9jdHgoY3R4KTsKCgkJcmV0dXJuIGN0eDsKCX0KCglyY3VfcmVhZF9sb2NrKCk7CglpZiAoIXBpZCkKCQl0YXNrID0gY3VycmVudDsKCWVsc2UKCQl0YXNrID0gZmluZF90YXNrX2J5X3ZwaWQocGlkKTsKCWlmICh0YXNrKQoJCWdldF90YXNrX3N0cnVjdCh0YXNrKTsKCXJjdV9yZWFkX3VubG9jaygpOwoKCWlmICghdGFzaykKCQlyZXR1cm4gRVJSX1BUUigtRVNSQ0gpOwoKCS8qCgkgKiBDYW4ndCBhdHRhY2ggZXZlbnRzIHRvIGEgZHlpbmcgdGFzay4KCSAqLwoJZXJyID0gLUVTUkNIOwoJaWYgKHRhc2stPmZsYWdzICYgUEZfRVhJVElORykKCQlnb3RvIGVycm91dDsKCgkvKiBSZXVzZSBwdHJhY2UgcGVybWlzc2lvbiBjaGVja3MgZm9yIG5vdy4gKi8KCWVyciA9IC1FQUNDRVM7CglpZiAoIXB0cmFjZV9tYXlfYWNjZXNzKHRhc2ssIFBUUkFDRV9NT0RFX1JFQUQpKQoJCWdvdG8gZXJyb3V0OwoKIHJldHJ5OgoJY3R4ID0gcGVyZl9sb2NrX3Rhc2tfY29udGV4dCh0YXNrLCAmZmxhZ3MpOwoJaWYgKGN0eCkgewoJCXVuY2xvbmVfY3R4KGN0eCk7CgkJc3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmY3R4LT5sb2NrLCBmbGFncyk7Cgl9CgoJaWYgKCFjdHgpIHsKCQljdHggPSBrbWFsbG9jKHNpemVvZihzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0KSwgR0ZQX0tFUk5FTCk7CgkJZXJyID0gLUVOT01FTTsKCQlpZiAoIWN0eCkKCQkJZ290byBlcnJvdXQ7CgkJX19wZXJmX2V2ZW50X2luaXRfY29udGV4dChjdHgsIHRhc2spOwoJCWdldF9jdHgoY3R4KTsKCQlpZiAoY21weGNoZygmdGFzay0+cGVyZl9ldmVudF9jdHhwLCBOVUxMLCBjdHgpKSB7CgkJCS8qCgkJCSAqIFdlIHJhY2VkIHdpdGggc29tZSBvdGhlciB0YXNrOyB1c2UKCQkJICogdGhlIGNvbnRleHQgdGhleSBzZXQuCgkJCSAqLwoJCQlrZnJlZShjdHgpOwoJCQlnb3RvIHJldHJ5OwoJCX0KCQlnZXRfdGFza19zdHJ1Y3QodGFzayk7Cgl9CgoJcHV0X3Rhc2tfc3RydWN0KHRhc2spOwoJcmV0dXJuIGN0eDsKCiBlcnJvdXQ6CglwdXRfdGFza19zdHJ1Y3QodGFzayk7CglyZXR1cm4gRVJSX1BUUihlcnIpOwp9CgpzdGF0aWMgdm9pZCBmcmVlX2V2ZW50X3JjdShzdHJ1Y3QgcmN1X2hlYWQgKmhlYWQpCnsKCXN0cnVjdCBwZXJmX2V2ZW50ICpldmVudDsKCglldmVudCA9IGNvbnRhaW5lcl9vZihoZWFkLCBzdHJ1Y3QgcGVyZl9ldmVudCwgcmN1X2hlYWQpOwoJaWYgKGV2ZW50LT5ucykKCQlwdXRfcGlkX25zKGV2ZW50LT5ucyk7CglrZnJlZShldmVudCk7Cn0KCnN0YXRpYyB2b2lkIHBlcmZfcGVuZGluZ19zeW5jKHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCk7CgpzdGF0aWMgdm9pZCBmcmVlX2V2ZW50KHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCkKewoJcGVyZl9wZW5kaW5nX3N5bmMoZXZlbnQpOwoKCWlmICghZXZlbnQtPnBhcmVudCkgewoJCWF0b21pY19kZWMoJm5yX2V2ZW50cyk7CgkJaWYgKGV2ZW50LT5hdHRyLm1tYXApCgkJCWF0b21pY19kZWMoJm5yX21tYXBfZXZlbnRzKTsKCQlpZiAoZXZlbnQtPmF0dHIuY29tbSkKCQkJYXRvbWljX2RlYygmbnJfY29tbV9ldmVudHMpOwoJCWlmIChldmVudC0+YXR0ci50YXNrKQoJCQlhdG9taWNfZGVjKCZucl90YXNrX2V2ZW50cyk7Cgl9CgoJaWYgKGV2ZW50LT5vdXRwdXQpIHsKCQlmcHV0KGV2ZW50LT5vdXRwdXQtPmZpbHApOwoJCWV2ZW50LT5vdXRwdXQgPSBOVUxMOwoJfQoKCWlmIChldmVudC0+ZGVzdHJveSkKCQlldmVudC0+ZGVzdHJveShldmVudCk7CgoJcHV0X2N0eChldmVudC0+Y3R4KTsKCWNhbGxfcmN1KCZldmVudC0+cmN1X2hlYWQsIGZyZWVfZXZlbnRfcmN1KTsKfQoKLyoKICogQ2FsbGVkIHdoZW4gdGhlIGxhc3QgcmVmZXJlbmNlIHRvIHRoZSBmaWxlIGlzIGdvbmUuCiAqLwpzdGF0aWMgaW50IHBlcmZfcmVsZWFzZShzdHJ1Y3QgaW5vZGUgKmlub2RlLCBzdHJ1Y3QgZmlsZSAqZmlsZSkKewoJc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50ID0gZmlsZS0+cHJpdmF0ZV9kYXRhOwoJc3RydWN0IHBlcmZfZXZlbnRfY29udGV4dCAqY3R4ID0gZXZlbnQtPmN0eDsKCglmaWxlLT5wcml2YXRlX2RhdGEgPSBOVUxMOwoKCVdBUk5fT05fT05DRShjdHgtPnBhcmVudF9jdHgpOwoJbXV0ZXhfbG9jaygmY3R4LT5tdXRleCk7CglwZXJmX2V2ZW50X3JlbW92ZV9mcm9tX2NvbnRleHQoZXZlbnQpOwoJbXV0ZXhfdW5sb2NrKCZjdHgtPm11dGV4KTsKCgltdXRleF9sb2NrKCZldmVudC0+b3duZXItPnBlcmZfZXZlbnRfbXV0ZXgpOwoJbGlzdF9kZWxfaW5pdCgmZXZlbnQtPm93bmVyX2VudHJ5KTsKCW11dGV4X3VubG9jaygmZXZlbnQtPm93bmVyLT5wZXJmX2V2ZW50X211dGV4KTsKCXB1dF90YXNrX3N0cnVjdChldmVudC0+b3duZXIpOwoKCWZyZWVfZXZlbnQoZXZlbnQpOwoKCXJldHVybiAwOwp9CgpzdGF0aWMgaW50IHBlcmZfZXZlbnRfcmVhZF9zaXplKHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCkKewoJaW50IGVudHJ5ID0gc2l6ZW9mKHU2NCk7IC8qIHZhbHVlICovCglpbnQgc2l6ZSA9IDA7CglpbnQgbnIgPSAxOwoKCWlmIChldmVudC0+YXR0ci5yZWFkX2Zvcm1hdCAmIFBFUkZfRk9STUFUX1RPVEFMX1RJTUVfRU5BQkxFRCkKCQlzaXplICs9IHNpemVvZih1NjQpOwoKCWlmIChldmVudC0+YXR0ci5yZWFkX2Zvcm1hdCAmIFBFUkZfRk9STUFUX1RPVEFMX1RJTUVfUlVOTklORykKCQlzaXplICs9IHNpemVvZih1NjQpOwoKCWlmIChldmVudC0+YXR0ci5yZWFkX2Zvcm1hdCAmIFBFUkZfRk9STUFUX0lEKQoJCWVudHJ5ICs9IHNpemVvZih1NjQpOwoKCWlmIChldmVudC0+YXR0ci5yZWFkX2Zvcm1hdCAmIFBFUkZfRk9STUFUX0dST1VQKSB7CgkJbnIgKz0gZXZlbnQtPmdyb3VwX2xlYWRlci0+bnJfc2libGluZ3M7CgkJc2l6ZSArPSBzaXplb2YodTY0KTsKCX0KCglzaXplICs9IGVudHJ5ICogbnI7CgoJcmV0dXJuIHNpemU7Cn0KCnN0YXRpYyB1NjQgcGVyZl9ldmVudF9yZWFkX3ZhbHVlKHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCkKewoJc3RydWN0IHBlcmZfZXZlbnQgKmNoaWxkOwoJdTY0IHRvdGFsID0gMDsKCgl0b3RhbCArPSBwZXJmX2V2ZW50X3JlYWQoZXZlbnQpOwoJbGlzdF9mb3JfZWFjaF9lbnRyeShjaGlsZCwgJmV2ZW50LT5jaGlsZF9saXN0LCBjaGlsZF9saXN0KQoJCXRvdGFsICs9IHBlcmZfZXZlbnRfcmVhZChjaGlsZCk7CgoJcmV0dXJuIHRvdGFsOwp9CgpzdGF0aWMgaW50IHBlcmZfZXZlbnRfcmVhZF9lbnRyeShzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQsCgkJCQkgICB1NjQgcmVhZF9mb3JtYXQsIGNoYXIgX191c2VyICpidWYpCnsKCWludCBuID0gMCwgY291bnQgPSAwOwoJdTY0IHZhbHVlc1syXTsKCgl2YWx1ZXNbbisrXSA9IHBlcmZfZXZlbnRfcmVhZF92YWx1ZShldmVudCk7CglpZiAocmVhZF9mb3JtYXQgJiBQRVJGX0ZPUk1BVF9JRCkKCQl2YWx1ZXNbbisrXSA9IHByaW1hcnlfZXZlbnRfaWQoZXZlbnQpOwoKCWNvdW50ID0gbiAqIHNpemVvZih1NjQpOwoKCWlmIChjb3B5X3RvX3VzZXIoYnVmLCB2YWx1ZXMsIGNvdW50KSkKCQlyZXR1cm4gLUVGQVVMVDsKCglyZXR1cm4gY291bnQ7Cn0KCnN0YXRpYyBpbnQgcGVyZl9ldmVudF9yZWFkX2dyb3VwKHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCwKCQkJCSAgIHU2NCByZWFkX2Zvcm1hdCwgY2hhciBfX3VzZXIgKmJ1ZikKewoJc3RydWN0IHBlcmZfZXZlbnQgKmxlYWRlciA9IGV2ZW50LT5ncm91cF9sZWFkZXIsICpzdWI7CglpbnQgbiA9IDAsIHNpemUgPSAwLCBlcnIgPSAtRUZBVUxUOwoJdTY0IHZhbHVlc1szXTsKCgl2YWx1ZXNbbisrXSA9IDEgKyBsZWFkZXItPm5yX3NpYmxpbmdzOwoJaWYgKHJlYWRfZm9ybWF0ICYgUEVSRl9GT1JNQVRfVE9UQUxfVElNRV9FTkFCTEVEKSB7CgkJdmFsdWVzW24rK10gPSBsZWFkZXItPnRvdGFsX3RpbWVfZW5hYmxlZCArCgkJCWF0b21pYzY0X3JlYWQoJmxlYWRlci0+Y2hpbGRfdG90YWxfdGltZV9lbmFibGVkKTsKCX0KCWlmIChyZWFkX2Zvcm1hdCAmIFBFUkZfRk9STUFUX1RPVEFMX1RJTUVfUlVOTklORykgewoJCXZhbHVlc1tuKytdID0gbGVhZGVyLT50b3RhbF90aW1lX3J1bm5pbmcgKwoJCQlhdG9taWM2NF9yZWFkKCZsZWFkZXItPmNoaWxkX3RvdGFsX3RpbWVfcnVubmluZyk7Cgl9CgoJc2l6ZSA9IG4gKiBzaXplb2YodTY0KTsKCglpZiAoY29weV90b191c2VyKGJ1ZiwgdmFsdWVzLCBzaXplKSkKCQlyZXR1cm4gLUVGQVVMVDsKCgllcnIgPSBwZXJmX2V2ZW50X3JlYWRfZW50cnkobGVhZGVyLCByZWFkX2Zvcm1hdCwgYnVmICsgc2l6ZSk7CglpZiAoZXJyIDwgMCkKCQlyZXR1cm4gZXJyOwoKCXNpemUgKz0gZXJyOwoKCWxpc3RfZm9yX2VhY2hfZW50cnkoc3ViLCAmbGVhZGVyLT5zaWJsaW5nX2xpc3QsIGdyb3VwX2VudHJ5KSB7CgkJZXJyID0gcGVyZl9ldmVudF9yZWFkX2VudHJ5KHN1YiwgcmVhZF9mb3JtYXQsCgkJCQlidWYgKyBzaXplKTsKCQlpZiAoZXJyIDwgMCkKCQkJcmV0dXJuIGVycjsKCgkJc2l6ZSArPSBlcnI7Cgl9CgoJcmV0dXJuIHNpemU7Cn0KCnN0YXRpYyBpbnQgcGVyZl9ldmVudF9yZWFkX29uZShzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQsCgkJCQkgdTY0IHJlYWRfZm9ybWF0LCBjaGFyIF9fdXNlciAqYnVmKQp7Cgl1NjQgdmFsdWVzWzRdOwoJaW50IG4gPSAwOwoKCXZhbHVlc1tuKytdID0gcGVyZl9ldmVudF9yZWFkX3ZhbHVlKGV2ZW50KTsKCWlmIChyZWFkX2Zvcm1hdCAmIFBFUkZfRk9STUFUX1RPVEFMX1RJTUVfRU5BQkxFRCkgewoJCXZhbHVlc1tuKytdID0gZXZlbnQtPnRvdGFsX3RpbWVfZW5hYmxlZCArCgkJCWF0b21pYzY0X3JlYWQoJmV2ZW50LT5jaGlsZF90b3RhbF90aW1lX2VuYWJsZWQpOwoJfQoJaWYgKHJlYWRfZm9ybWF0ICYgUEVSRl9GT1JNQVRfVE9UQUxfVElNRV9SVU5OSU5HKSB7CgkJdmFsdWVzW24rK10gPSBldmVudC0+dG90YWxfdGltZV9ydW5uaW5nICsKCQkJYXRvbWljNjRfcmVhZCgmZXZlbnQtPmNoaWxkX3RvdGFsX3RpbWVfcnVubmluZyk7Cgl9CglpZiAocmVhZF9mb3JtYXQgJiBQRVJGX0ZPUk1BVF9JRCkKCQl2YWx1ZXNbbisrXSA9IHByaW1hcnlfZXZlbnRfaWQoZXZlbnQpOwoKCWlmIChjb3B5X3RvX3VzZXIoYnVmLCB2YWx1ZXMsIG4gKiBzaXplb2YodTY0KSkpCgkJcmV0dXJuIC1FRkFVTFQ7CgoJcmV0dXJuIG4gKiBzaXplb2YodTY0KTsKfQoKLyoKICogUmVhZCB0aGUgcGVyZm9ybWFuY2UgZXZlbnQgLSBzaW1wbGUgbm9uIGJsb2NraW5nIHZlcnNpb24gZm9yIG5vdwogKi8Kc3RhdGljIHNzaXplX3QKcGVyZl9yZWFkX2h3KHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCwgY2hhciBfX3VzZXIgKmJ1Ziwgc2l6ZV90IGNvdW50KQp7Cgl1NjQgcmVhZF9mb3JtYXQgPSBldmVudC0+YXR0ci5yZWFkX2Zvcm1hdDsKCWludCByZXQ7CgoJLyoKCSAqIFJldHVybiBlbmQtb2YtZmlsZSBmb3IgYSByZWFkIG9uIGEgZXZlbnQgdGhhdCBpcyBpbgoJICogZXJyb3Igc3RhdGUgKGkuZS4gYmVjYXVzZSBpdCB3YXMgcGlubmVkIGJ1dCBpdCBjb3VsZG4ndCBiZQoJICogc2NoZWR1bGVkIG9uIHRvIHRoZSBDUFUgYXQgc29tZSBwb2ludCkuCgkgKi8KCWlmIChldmVudC0+c3RhdGUgPT0gUEVSRl9FVkVOVF9TVEFURV9FUlJPUikKCQlyZXR1cm4gMDsKCglpZiAoY291bnQgPCBwZXJmX2V2ZW50X3JlYWRfc2l6ZShldmVudCkpCgkJcmV0dXJuIC1FTk9TUEM7CgoJV0FSTl9PTl9PTkNFKGV2ZW50LT5jdHgtPnBhcmVudF9jdHgpOwoJbXV0ZXhfbG9jaygmZXZlbnQtPmNoaWxkX211dGV4KTsKCWlmIChyZWFkX2Zvcm1hdCAmIFBFUkZfRk9STUFUX0dST1VQKQoJCXJldCA9IHBlcmZfZXZlbnRfcmVhZF9ncm91cChldmVudCwgcmVhZF9mb3JtYXQsIGJ1Zik7CgllbHNlCgkJcmV0ID0gcGVyZl9ldmVudF9yZWFkX29uZShldmVudCwgcmVhZF9mb3JtYXQsIGJ1Zik7CgltdXRleF91bmxvY2soJmV2ZW50LT5jaGlsZF9tdXRleCk7CgoJcmV0dXJuIHJldDsKfQoKc3RhdGljIHNzaXplX3QKcGVyZl9yZWFkKHN0cnVjdCBmaWxlICpmaWxlLCBjaGFyIF9fdXNlciAqYnVmLCBzaXplX3QgY291bnQsIGxvZmZfdCAqcHBvcykKewoJc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50ID0gZmlsZS0+cHJpdmF0ZV9kYXRhOwoKCXJldHVybiBwZXJmX3JlYWRfaHcoZXZlbnQsIGJ1ZiwgY291bnQpOwp9CgpzdGF0aWMgdW5zaWduZWQgaW50IHBlcmZfcG9sbChzdHJ1Y3QgZmlsZSAqZmlsZSwgcG9sbF90YWJsZSAqd2FpdCkKewoJc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50ID0gZmlsZS0+cHJpdmF0ZV9kYXRhOwoJc3RydWN0IHBlcmZfbW1hcF9kYXRhICpkYXRhOwoJdW5zaWduZWQgaW50IGV2ZW50cyA9IFBPTExfSFVQOwoKCXJjdV9yZWFkX2xvY2soKTsKCWRhdGEgPSByY3VfZGVyZWZlcmVuY2UoZXZlbnQtPmRhdGEpOwoJaWYgKGRhdGEpCgkJZXZlbnRzID0gYXRvbWljX3hjaGcoJmRhdGEtPnBvbGwsIDApOwoJcmN1X3JlYWRfdW5sb2NrKCk7CgoJcG9sbF93YWl0KGZpbGUsICZldmVudC0+d2FpdHEsIHdhaXQpOwoKCXJldHVybiBldmVudHM7Cn0KCnN0YXRpYyB2b2lkIHBlcmZfZXZlbnRfcmVzZXQoc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50KQp7Cgkodm9pZClwZXJmX2V2ZW50X3JlYWQoZXZlbnQpOwoJYXRvbWljNjRfc2V0KCZldmVudC0+Y291bnQsIDApOwoJcGVyZl9ldmVudF91cGRhdGVfdXNlcnBhZ2UoZXZlbnQpOwp9CgovKgogKiBIb2xkaW5nIHRoZSB0b3AtbGV2ZWwgZXZlbnQncyBjaGlsZF9tdXRleCBtZWFucyB0aGF0IGFueQogKiBkZXNjZW5kYW50IHByb2Nlc3MgdGhhdCBoYXMgaW5oZXJpdGVkIHRoaXMgZXZlbnQgd2lsbCBibG9jawogKiBpbiBzeW5jX2NoaWxkX2V2ZW50IGlmIGl0IGdvZXMgdG8gZXhpdCwgdGh1cyBzYXRpc2Z5aW5nIHRoZQogKiB0YXNrIGV4aXN0ZW5jZSByZXF1aXJlbWVudHMgb2YgcGVyZl9ldmVudF9lbmFibGUvZGlzYWJsZS4KICovCnN0YXRpYyB2b2lkIHBlcmZfZXZlbnRfZm9yX2VhY2hfY2hpbGQoc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50LAoJCQkJCXZvaWQgKCpmdW5jKShzdHJ1Y3QgcGVyZl9ldmVudCAqKSkKewoJc3RydWN0IHBlcmZfZXZlbnQgKmNoaWxkOwoKCVdBUk5fT05fT05DRShldmVudC0+Y3R4LT5wYXJlbnRfY3R4KTsKCW11dGV4X2xvY2soJmV2ZW50LT5jaGlsZF9tdXRleCk7CglmdW5jKGV2ZW50KTsKCWxpc3RfZm9yX2VhY2hfZW50cnkoY2hpbGQsICZldmVudC0+Y2hpbGRfbGlzdCwgY2hpbGRfbGlzdCkKCQlmdW5jKGNoaWxkKTsKCW11dGV4X3VubG9jaygmZXZlbnQtPmNoaWxkX211dGV4KTsKfQoKc3RhdGljIHZvaWQgcGVyZl9ldmVudF9mb3JfZWFjaChzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQsCgkJCQkgIHZvaWQgKCpmdW5jKShzdHJ1Y3QgcGVyZl9ldmVudCAqKSkKewoJc3RydWN0IHBlcmZfZXZlbnRfY29udGV4dCAqY3R4ID0gZXZlbnQtPmN0eDsKCXN0cnVjdCBwZXJmX2V2ZW50ICpzaWJsaW5nOwoKCVdBUk5fT05fT05DRShjdHgtPnBhcmVudF9jdHgpOwoJbXV0ZXhfbG9jaygmY3R4LT5tdXRleCk7CglldmVudCA9IGV2ZW50LT5ncm91cF9sZWFkZXI7CgoJcGVyZl9ldmVudF9mb3JfZWFjaF9jaGlsZChldmVudCwgZnVuYyk7CglmdW5jKGV2ZW50KTsKCWxpc3RfZm9yX2VhY2hfZW50cnkoc2libGluZywgJmV2ZW50LT5zaWJsaW5nX2xpc3QsIGdyb3VwX2VudHJ5KQoJCXBlcmZfZXZlbnRfZm9yX2VhY2hfY2hpbGQoZXZlbnQsIGZ1bmMpOwoJbXV0ZXhfdW5sb2NrKCZjdHgtPm11dGV4KTsKfQoKc3RhdGljIGludCBwZXJmX2V2ZW50X3BlcmlvZChzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQsIHU2NCBfX3VzZXIgKmFyZykKewoJc3RydWN0IHBlcmZfZXZlbnRfY29udGV4dCAqY3R4ID0gZXZlbnQtPmN0eDsKCXVuc2lnbmVkIGxvbmcgc2l6ZTsKCWludCByZXQgPSAwOwoJdTY0IHZhbHVlOwoKCWlmICghZXZlbnQtPmF0dHIuc2FtcGxlX3BlcmlvZCkKCQlyZXR1cm4gLUVJTlZBTDsKCglzaXplID0gY29weV9mcm9tX3VzZXIoJnZhbHVlLCBhcmcsIHNpemVvZih2YWx1ZSkpOwoJaWYgKHNpemUgIT0gc2l6ZW9mKHZhbHVlKSkKCQlyZXR1cm4gLUVGQVVMVDsKCglpZiAoIXZhbHVlKQoJCXJldHVybiAtRUlOVkFMOwoKCXNwaW5fbG9ja19pcnEoJmN0eC0+bG9jayk7CglpZiAoZXZlbnQtPmF0dHIuZnJlcSkgewoJCWlmICh2YWx1ZSA+IHN5c2N0bF9wZXJmX2V2ZW50X3NhbXBsZV9yYXRlKSB7CgkJCXJldCA9IC1FSU5WQUw7CgkJCWdvdG8gdW5sb2NrOwoJCX0KCgkJZXZlbnQtPmF0dHIuc2FtcGxlX2ZyZXEgPSB2YWx1ZTsKCX0gZWxzZSB7CgkJZXZlbnQtPmF0dHIuc2FtcGxlX3BlcmlvZCA9IHZhbHVlOwoJCWV2ZW50LT5ody5zYW1wbGVfcGVyaW9kID0gdmFsdWU7Cgl9CnVubG9jazoKCXNwaW5fdW5sb2NrX2lycSgmY3R4LT5sb2NrKTsKCglyZXR1cm4gcmV0Owp9CgppbnQgcGVyZl9ldmVudF9zZXRfb3V0cHV0KHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCwgaW50IG91dHB1dF9mZCk7CgpzdGF0aWMgbG9uZyBwZXJmX2lvY3RsKHN0cnVjdCBmaWxlICpmaWxlLCB1bnNpZ25lZCBpbnQgY21kLCB1bnNpZ25lZCBsb25nIGFyZykKewoJc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50ID0gZmlsZS0+cHJpdmF0ZV9kYXRhOwoJdm9pZCAoKmZ1bmMpKHN0cnVjdCBwZXJmX2V2ZW50ICopOwoJdTMyIGZsYWdzID0gYXJnOwoKCXN3aXRjaCAoY21kKSB7CgljYXNlIFBFUkZfRVZFTlRfSU9DX0VOQUJMRToKCQlmdW5jID0gcGVyZl9ldmVudF9lbmFibGU7CgkJYnJlYWs7CgljYXNlIFBFUkZfRVZFTlRfSU9DX0RJU0FCTEU6CgkJZnVuYyA9IHBlcmZfZXZlbnRfZGlzYWJsZTsKCQlicmVhazsKCWNhc2UgUEVSRl9FVkVOVF9JT0NfUkVTRVQ6CgkJZnVuYyA9IHBlcmZfZXZlbnRfcmVzZXQ7CgkJYnJlYWs7CgoJY2FzZSBQRVJGX0VWRU5UX0lPQ19SRUZSRVNIOgoJCXJldHVybiBwZXJmX2V2ZW50X3JlZnJlc2goZXZlbnQsIGFyZyk7CgoJY2FzZSBQRVJGX0VWRU5UX0lPQ19QRVJJT0Q6CgkJcmV0dXJuIHBlcmZfZXZlbnRfcGVyaW9kKGV2ZW50LCAodTY0IF9fdXNlciAqKWFyZyk7CgoJY2FzZSBQRVJGX0VWRU5UX0lPQ19TRVRfT1VUUFVUOgoJCXJldHVybiBwZXJmX2V2ZW50X3NldF9vdXRwdXQoZXZlbnQsIGFyZyk7CgoJZGVmYXVsdDoKCQlyZXR1cm4gLUVOT1RUWTsKCX0KCglpZiAoZmxhZ3MgJiBQRVJGX0lPQ19GTEFHX0dST1VQKQoJCXBlcmZfZXZlbnRfZm9yX2VhY2goZXZlbnQsIGZ1bmMpOwoJZWxzZQoJCXBlcmZfZXZlbnRfZm9yX2VhY2hfY2hpbGQoZXZlbnQsIGZ1bmMpOwoKCXJldHVybiAwOwp9CgppbnQgcGVyZl9ldmVudF90YXNrX2VuYWJsZSh2b2lkKQp7CglzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQ7CgoJbXV0ZXhfbG9jaygmY3VycmVudC0+cGVyZl9ldmVudF9tdXRleCk7CglsaXN0X2Zvcl9lYWNoX2VudHJ5KGV2ZW50LCAmY3VycmVudC0+cGVyZl9ldmVudF9saXN0LCBvd25lcl9lbnRyeSkKCQlwZXJmX2V2ZW50X2Zvcl9lYWNoX2NoaWxkKGV2ZW50LCBwZXJmX2V2ZW50X2VuYWJsZSk7CgltdXRleF91bmxvY2soJmN1cnJlbnQtPnBlcmZfZXZlbnRfbXV0ZXgpOwoKCXJldHVybiAwOwp9CgppbnQgcGVyZl9ldmVudF90YXNrX2Rpc2FibGUodm9pZCkKewoJc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50OwoKCW11dGV4X2xvY2soJmN1cnJlbnQtPnBlcmZfZXZlbnRfbXV0ZXgpOwoJbGlzdF9mb3JfZWFjaF9lbnRyeShldmVudCwgJmN1cnJlbnQtPnBlcmZfZXZlbnRfbGlzdCwgb3duZXJfZW50cnkpCgkJcGVyZl9ldmVudF9mb3JfZWFjaF9jaGlsZChldmVudCwgcGVyZl9ldmVudF9kaXNhYmxlKTsKCW11dGV4X3VubG9jaygmY3VycmVudC0+cGVyZl9ldmVudF9tdXRleCk7CgoJcmV0dXJuIDA7Cn0KCiNpZm5kZWYgUEVSRl9FVkVOVF9JTkRFWF9PRkZTRVQKIyBkZWZpbmUgUEVSRl9FVkVOVF9JTkRFWF9PRkZTRVQgMAojZW5kaWYKCnN0YXRpYyBpbnQgcGVyZl9ldmVudF9pbmRleChzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQpCnsKCWlmIChldmVudC0+c3RhdGUgIT0gUEVSRl9FVkVOVF9TVEFURV9BQ1RJVkUpCgkJcmV0dXJuIDA7CgoJcmV0dXJuIGV2ZW50LT5ody5pZHggKyAxIC0gUEVSRl9FVkVOVF9JTkRFWF9PRkZTRVQ7Cn0KCi8qCiAqIENhbGxlcnMgbmVlZCB0byBlbnN1cmUgdGhlcmUgY2FuIGJlIG5vIG5lc3Rpbmcgb2YgdGhpcyBmdW5jdGlvbiwgb3RoZXJ3aXNlCiAqIHRoZSBzZXFsb2NrIGxvZ2ljIGdvZXMgYmFkLiBXZSBjYW4gbm90IHNlcmlhbGl6ZSB0aGlzIGJlY2F1c2UgdGhlIGFyY2gKICogY29kZSBjYWxscyB0aGlzIGZyb20gTk1JIGNvbnRleHQuCiAqLwp2b2lkIHBlcmZfZXZlbnRfdXBkYXRlX3VzZXJwYWdlKHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCkKewoJc3RydWN0IHBlcmZfZXZlbnRfbW1hcF9wYWdlICp1c2VycGc7CglzdHJ1Y3QgcGVyZl9tbWFwX2RhdGEgKmRhdGE7CgoJcmN1X3JlYWRfbG9jaygpOwoJZGF0YSA9IHJjdV9kZXJlZmVyZW5jZShldmVudC0+ZGF0YSk7CglpZiAoIWRhdGEpCgkJZ290byB1bmxvY2s7CgoJdXNlcnBnID0gZGF0YS0+dXNlcl9wYWdlOwoKCS8qCgkgKiBEaXNhYmxlIHByZWVtcHRpb24gc28gYXMgdG8gbm90IGxldCB0aGUgY29ycmVzcG9uZGluZyB1c2VyLXNwYWNlCgkgKiBzcGluIHRvbyBsb25nIGlmIHdlIGdldCBwcmVlbXB0ZWQuCgkgKi8KCXByZWVtcHRfZGlzYWJsZSgpOwoJKyt1c2VycGctPmxvY2s7CgliYXJyaWVyKCk7Cgl1c2VycGctPmluZGV4ID0gcGVyZl9ldmVudF9pbmRleChldmVudCk7Cgl1c2VycGctPm9mZnNldCA9IGF0b21pYzY0X3JlYWQoJmV2ZW50LT5jb3VudCk7CglpZiAoZXZlbnQtPnN0YXRlID09IFBFUkZfRVZFTlRfU1RBVEVfQUNUSVZFKQoJCXVzZXJwZy0+b2Zmc2V0IC09IGF0b21pYzY0X3JlYWQoJmV2ZW50LT5ody5wcmV2X2NvdW50KTsKCgl1c2VycGctPnRpbWVfZW5hYmxlZCA9IGV2ZW50LT50b3RhbF90aW1lX2VuYWJsZWQgKwoJCQlhdG9taWM2NF9yZWFkKCZldmVudC0+Y2hpbGRfdG90YWxfdGltZV9lbmFibGVkKTsKCgl1c2VycGctPnRpbWVfcnVubmluZyA9IGV2ZW50LT50b3RhbF90aW1lX3J1bm5pbmcgKwoJCQlhdG9taWM2NF9yZWFkKCZldmVudC0+Y2hpbGRfdG90YWxfdGltZV9ydW5uaW5nKTsKCgliYXJyaWVyKCk7CgkrK3VzZXJwZy0+bG9jazsKCXByZWVtcHRfZW5hYmxlKCk7CnVubG9jazoKCXJjdV9yZWFkX3VubG9jaygpOwp9CgpzdGF0aWMgaW50IHBlcmZfbW1hcF9mYXVsdChzdHJ1Y3Qgdm1fYXJlYV9zdHJ1Y3QgKnZtYSwgc3RydWN0IHZtX2ZhdWx0ICp2bWYpCnsKCXN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCA9IHZtYS0+dm1fZmlsZS0+cHJpdmF0ZV9kYXRhOwoJc3RydWN0IHBlcmZfbW1hcF9kYXRhICpkYXRhOwoJaW50IHJldCA9IFZNX0ZBVUxUX1NJR0JVUzsKCglpZiAodm1mLT5mbGFncyAmIEZBVUxUX0ZMQUdfTUtXUklURSkgewoJCWlmICh2bWYtPnBnb2ZmID09IDApCgkJCXJldCA9IDA7CgkJcmV0dXJuIHJldDsKCX0KCglyY3VfcmVhZF9sb2NrKCk7CglkYXRhID0gcmN1X2RlcmVmZXJlbmNlKGV2ZW50LT5kYXRhKTsKCWlmICghZGF0YSkKCQlnb3RvIHVubG9jazsKCglpZiAodm1mLT5wZ29mZiA9PSAwKSB7CgkJdm1mLT5wYWdlID0gdmlydF90b19wYWdlKGRhdGEtPnVzZXJfcGFnZSk7Cgl9IGVsc2UgewoJCWludCBuciA9IHZtZi0+cGdvZmYgLSAxOwoKCQlpZiAoKHVuc2lnbmVkKW5yID4gZGF0YS0+bnJfcGFnZXMpCgkJCWdvdG8gdW5sb2NrOwoKCQlpZiAodm1mLT5mbGFncyAmIEZBVUxUX0ZMQUdfV1JJVEUpCgkJCWdvdG8gdW5sb2NrOwoKCQl2bWYtPnBhZ2UgPSB2aXJ0X3RvX3BhZ2UoZGF0YS0+ZGF0YV9wYWdlc1tucl0pOwoJfQoKCWdldF9wYWdlKHZtZi0+cGFnZSk7Cgl2bWYtPnBhZ2UtPm1hcHBpbmcgPSB2bWEtPnZtX2ZpbGUtPmZfbWFwcGluZzsKCXZtZi0+cGFnZS0+aW5kZXggICA9IHZtZi0+cGdvZmY7CgoJcmV0ID0gMDsKdW5sb2NrOgoJcmN1X3JlYWRfdW5sb2NrKCk7CgoJcmV0dXJuIHJldDsKfQoKc3RhdGljIGludCBwZXJmX21tYXBfZGF0YV9hbGxvYyhzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQsIGludCBucl9wYWdlcykKewoJc3RydWN0IHBlcmZfbW1hcF9kYXRhICpkYXRhOwoJdW5zaWduZWQgbG9uZyBzaXplOwoJaW50IGk7CgoJV0FSTl9PTihhdG9taWNfcmVhZCgmZXZlbnQtPm1tYXBfY291bnQpKTsKCglzaXplID0gc2l6ZW9mKHN0cnVjdCBwZXJmX21tYXBfZGF0YSk7CglzaXplICs9IG5yX3BhZ2VzICogc2l6ZW9mKHZvaWQgKik7CgoJZGF0YSA9IGt6YWxsb2Moc2l6ZSwgR0ZQX0tFUk5FTCk7CglpZiAoIWRhdGEpCgkJZ290byBmYWlsOwoKCWRhdGEtPnVzZXJfcGFnZSA9ICh2b2lkICopZ2V0X3plcm9lZF9wYWdlKEdGUF9LRVJORUwpOwoJaWYgKCFkYXRhLT51c2VyX3BhZ2UpCgkJZ290byBmYWlsX3VzZXJfcGFnZTsKCglmb3IgKGkgPSAwOyBpIDwgbnJfcGFnZXM7IGkrKykgewoJCWRhdGEtPmRhdGFfcGFnZXNbaV0gPSAodm9pZCAqKWdldF96ZXJvZWRfcGFnZShHRlBfS0VSTkVMKTsKCQlpZiAoIWRhdGEtPmRhdGFfcGFnZXNbaV0pCgkJCWdvdG8gZmFpbF9kYXRhX3BhZ2VzOwoJfQoKCWRhdGEtPm5yX3BhZ2VzID0gbnJfcGFnZXM7CglhdG9taWNfc2V0KCZkYXRhLT5sb2NrLCAtMSk7CgoJaWYgKGV2ZW50LT5hdHRyLndhdGVybWFyaykgewoJCWRhdGEtPndhdGVybWFyayA9IG1pbl90KGxvbmcsIFBBR0VfU0laRSAqIG5yX3BhZ2VzLAoJCQkJICAgICAgZXZlbnQtPmF0dHIud2FrZXVwX3dhdGVybWFyayk7Cgl9CglpZiAoIWRhdGEtPndhdGVybWFyaykKCQlkYXRhLT53YXRlcm1hcmsgPSBtYXgoUEFHRV9TSVpFLCBQQUdFX1NJWkUgKiBucl9wYWdlcyAvIDQpOwoKCXJjdV9hc3NpZ25fcG9pbnRlcihldmVudC0+ZGF0YSwgZGF0YSk7CgoJcmV0dXJuIDA7CgpmYWlsX2RhdGFfcGFnZXM6Cglmb3IgKGktLTsgaSA+PSAwOyBpLS0pCgkJZnJlZV9wYWdlKCh1bnNpZ25lZCBsb25nKWRhdGEtPmRhdGFfcGFnZXNbaV0pOwoKCWZyZWVfcGFnZSgodW5zaWduZWQgbG9uZylkYXRhLT51c2VyX3BhZ2UpOwoKZmFpbF91c2VyX3BhZ2U6CglrZnJlZShkYXRhKTsKCmZhaWw6CglyZXR1cm4gLUVOT01FTTsKfQoKc3RhdGljIHZvaWQgcGVyZl9tbWFwX2ZyZWVfcGFnZSh1bnNpZ25lZCBsb25nIGFkZHIpCnsKCXN0cnVjdCBwYWdlICpwYWdlID0gdmlydF90b19wYWdlKCh2b2lkICopYWRkcik7CgoJcGFnZS0+bWFwcGluZyA9IE5VTEw7CglfX2ZyZWVfcGFnZShwYWdlKTsKfQoKc3RhdGljIHZvaWQgX19wZXJmX21tYXBfZGF0YV9mcmVlKHN0cnVjdCByY3VfaGVhZCAqcmN1X2hlYWQpCnsKCXN0cnVjdCBwZXJmX21tYXBfZGF0YSAqZGF0YTsKCWludCBpOwoKCWRhdGEgPSBjb250YWluZXJfb2YocmN1X2hlYWQsIHN0cnVjdCBwZXJmX21tYXBfZGF0YSwgcmN1X2hlYWQpOwoKCXBlcmZfbW1hcF9mcmVlX3BhZ2UoKHVuc2lnbmVkIGxvbmcpZGF0YS0+dXNlcl9wYWdlKTsKCWZvciAoaSA9IDA7IGkgPCBkYXRhLT5ucl9wYWdlczsgaSsrKQoJCXBlcmZfbW1hcF9mcmVlX3BhZ2UoKHVuc2lnbmVkIGxvbmcpZGF0YS0+ZGF0YV9wYWdlc1tpXSk7CgoJa2ZyZWUoZGF0YSk7Cn0KCnN0YXRpYyB2b2lkIHBlcmZfbW1hcF9kYXRhX2ZyZWUoc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50KQp7CglzdHJ1Y3QgcGVyZl9tbWFwX2RhdGEgKmRhdGEgPSBldmVudC0+ZGF0YTsKCglXQVJOX09OKGF0b21pY19yZWFkKCZldmVudC0+bW1hcF9jb3VudCkpOwoKCXJjdV9hc3NpZ25fcG9pbnRlcihldmVudC0+ZGF0YSwgTlVMTCk7CgljYWxsX3JjdSgmZGF0YS0+cmN1X2hlYWQsIF9fcGVyZl9tbWFwX2RhdGFfZnJlZSk7Cn0KCnN0YXRpYyB2b2lkIHBlcmZfbW1hcF9vcGVuKHN0cnVjdCB2bV9hcmVhX3N0cnVjdCAqdm1hKQp7CglzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQgPSB2bWEtPnZtX2ZpbGUtPnByaXZhdGVfZGF0YTsKCglhdG9taWNfaW5jKCZldmVudC0+bW1hcF9jb3VudCk7Cn0KCnN0YXRpYyB2b2lkIHBlcmZfbW1hcF9jbG9zZShzdHJ1Y3Qgdm1fYXJlYV9zdHJ1Y3QgKnZtYSkKewoJc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50ID0gdm1hLT52bV9maWxlLT5wcml2YXRlX2RhdGE7CgoJV0FSTl9PTl9PTkNFKGV2ZW50LT5jdHgtPnBhcmVudF9jdHgpOwoJaWYgKGF0b21pY19kZWNfYW5kX211dGV4X2xvY2soJmV2ZW50LT5tbWFwX2NvdW50LCAmZXZlbnQtPm1tYXBfbXV0ZXgpKSB7CgkJc3RydWN0IHVzZXJfc3RydWN0ICp1c2VyID0gY3VycmVudF91c2VyKCk7CgoJCWF0b21pY19sb25nX3N1YihldmVudC0+ZGF0YS0+bnJfcGFnZXMgKyAxLCAmdXNlci0+bG9ja2VkX3ZtKTsKCQl2bWEtPnZtX21tLT5sb2NrZWRfdm0gLT0gZXZlbnQtPmRhdGEtPm5yX2xvY2tlZDsKCQlwZXJmX21tYXBfZGF0YV9mcmVlKGV2ZW50KTsKCQltdXRleF91bmxvY2soJmV2ZW50LT5tbWFwX211dGV4KTsKCX0KfQoKc3RhdGljIHN0cnVjdCB2bV9vcGVyYXRpb25zX3N0cnVjdCBwZXJmX21tYXBfdm1vcHMgPSB7Cgkub3BlbgkJPSBwZXJmX21tYXBfb3BlbiwKCS5jbG9zZQkJPSBwZXJmX21tYXBfY2xvc2UsCgkuZmF1bHQJCT0gcGVyZl9tbWFwX2ZhdWx0LAoJLnBhZ2VfbWt3cml0ZQk9IHBlcmZfbW1hcF9mYXVsdCwKfTsKCnN0YXRpYyBpbnQgcGVyZl9tbWFwKHN0cnVjdCBmaWxlICpmaWxlLCBzdHJ1Y3Qgdm1fYXJlYV9zdHJ1Y3QgKnZtYSkKewoJc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50ID0gZmlsZS0+cHJpdmF0ZV9kYXRhOwoJdW5zaWduZWQgbG9uZyB1c2VyX2xvY2tlZCwgdXNlcl9sb2NrX2xpbWl0OwoJc3RydWN0IHVzZXJfc3RydWN0ICp1c2VyID0gY3VycmVudF91c2VyKCk7Cgl1bnNpZ25lZCBsb25nIGxvY2tlZCwgbG9ja19saW1pdDsKCXVuc2lnbmVkIGxvbmcgdm1hX3NpemU7Cgl1bnNpZ25lZCBsb25nIG5yX3BhZ2VzOwoJbG9uZyB1c2VyX2V4dHJhLCBleHRyYTsKCWludCByZXQgPSAwOwoKCWlmICghKHZtYS0+dm1fZmxhZ3MgJiBWTV9TSEFSRUQpKQoJCXJldHVybiAtRUlOVkFMOwoKCXZtYV9zaXplID0gdm1hLT52bV9lbmQgLSB2bWEtPnZtX3N0YXJ0OwoJbnJfcGFnZXMgPSAodm1hX3NpemUgLyBQQUdFX1NJWkUpIC0gMTsKCgkvKgoJICogSWYgd2UgaGF2ZSBkYXRhIHBhZ2VzIGVuc3VyZSB0aGV5J3JlIGEgcG93ZXItb2YtdHdvIG51bWJlciwgc28gd2UKCSAqIGNhbiBkbyBiaXRtYXNrcyBpbnN0ZWFkIG9mIG1vZHVsby4KCSAqLwoJaWYgKG5yX3BhZ2VzICE9IDAgJiYgIWlzX3Bvd2VyX29mXzIobnJfcGFnZXMpKQoJCXJldHVybiAtRUlOVkFMOwoKCWlmICh2bWFfc2l6ZSAhPSBQQUdFX1NJWkUgKiAoMSArIG5yX3BhZ2VzKSkKCQlyZXR1cm4gLUVJTlZBTDsKCglpZiAodm1hLT52bV9wZ29mZiAhPSAwKQoJCXJldHVybiAtRUlOVkFMOwoKCVdBUk5fT05fT05DRShldmVudC0+Y3R4LT5wYXJlbnRfY3R4KTsKCW11dGV4X2xvY2soJmV2ZW50LT5tbWFwX211dGV4KTsKCWlmIChldmVudC0+b3V0cHV0KSB7CgkJcmV0ID0gLUVJTlZBTDsKCQlnb3RvIHVubG9jazsKCX0KCglpZiAoYXRvbWljX2luY19ub3RfemVybygmZXZlbnQtPm1tYXBfY291bnQpKSB7CgkJaWYgKG5yX3BhZ2VzICE9IGV2ZW50LT5kYXRhLT5ucl9wYWdlcykKCQkJcmV0ID0gLUVJTlZBTDsKCQlnb3RvIHVubG9jazsKCX0KCgl1c2VyX2V4dHJhID0gbnJfcGFnZXMgKyAxOwoJdXNlcl9sb2NrX2xpbWl0ID0gc3lzY3RsX3BlcmZfZXZlbnRfbWxvY2sgPj4gKFBBR0VfU0hJRlQgLSAxMCk7CgoJLyoKCSAqIEluY3JlYXNlIHRoZSBsaW1pdCBsaW5lYXJseSB3aXRoIG1vcmUgQ1BVczoKCSAqLwoJdXNlcl9sb2NrX2xpbWl0ICo9IG51bV9vbmxpbmVfY3B1cygpOwoKCXVzZXJfbG9ja2VkID0gYXRvbWljX2xvbmdfcmVhZCgmdXNlci0+bG9ja2VkX3ZtKSArIHVzZXJfZXh0cmE7CgoJZXh0cmEgPSAwOwoJaWYgKHVzZXJfbG9ja2VkID4gdXNlcl9sb2NrX2xpbWl0KQoJCWV4dHJhID0gdXNlcl9sb2NrZWQgLSB1c2VyX2xvY2tfbGltaXQ7CgoJbG9ja19saW1pdCA9IGN1cnJlbnQtPnNpZ25hbC0+cmxpbVtSTElNSVRfTUVNTE9DS10ucmxpbV9jdXI7Cglsb2NrX2xpbWl0ID4+PSBQQUdFX1NISUZUOwoJbG9ja2VkID0gdm1hLT52bV9tbS0+bG9ja2VkX3ZtICsgZXh0cmE7CgoJaWYgKChsb2NrZWQgPiBsb2NrX2xpbWl0KSAmJiBwZXJmX3BhcmFub2lkX3RyYWNlcG9pbnRfcmF3KCkgJiYKCQkhY2FwYWJsZShDQVBfSVBDX0xPQ0spKSB7CgkJcmV0ID0gLUVQRVJNOwoJCWdvdG8gdW5sb2NrOwoJfQoKCVdBUk5fT04oZXZlbnQtPmRhdGEpOwoJcmV0ID0gcGVyZl9tbWFwX2RhdGFfYWxsb2MoZXZlbnQsIG5yX3BhZ2VzKTsKCWlmIChyZXQpCgkJZ290byB1bmxvY2s7CgoJYXRvbWljX3NldCgmZXZlbnQtPm1tYXBfY291bnQsIDEpOwoJYXRvbWljX2xvbmdfYWRkKHVzZXJfZXh0cmEsICZ1c2VyLT5sb2NrZWRfdm0pOwoJdm1hLT52bV9tbS0+bG9ja2VkX3ZtICs9IGV4dHJhOwoJZXZlbnQtPmRhdGEtPm5yX2xvY2tlZCA9IGV4dHJhOwoJaWYgKHZtYS0+dm1fZmxhZ3MgJiBWTV9XUklURSkKCQlldmVudC0+ZGF0YS0+d3JpdGFibGUgPSAxOwoKdW5sb2NrOgoJbXV0ZXhfdW5sb2NrKCZldmVudC0+bW1hcF9tdXRleCk7CgoJdm1hLT52bV9mbGFncyB8PSBWTV9SRVNFUlZFRDsKCXZtYS0+dm1fb3BzID0gJnBlcmZfbW1hcF92bW9wczsKCglyZXR1cm4gcmV0Owp9CgpzdGF0aWMgaW50IHBlcmZfZmFzeW5jKGludCBmZCwgc3RydWN0IGZpbGUgKmZpbHAsIGludCBvbikKewoJc3RydWN0IGlub2RlICppbm9kZSA9IGZpbHAtPmZfcGF0aC5kZW50cnktPmRfaW5vZGU7CglzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQgPSBmaWxwLT5wcml2YXRlX2RhdGE7CglpbnQgcmV0dmFsOwoKCW11dGV4X2xvY2soJmlub2RlLT5pX211dGV4KTsKCXJldHZhbCA9IGZhc3luY19oZWxwZXIoZmQsIGZpbHAsIG9uLCAmZXZlbnQtPmZhc3luYyk7CgltdXRleF91bmxvY2soJmlub2RlLT5pX211dGV4KTsKCglpZiAocmV0dmFsIDwgMCkKCQlyZXR1cm4gcmV0dmFsOwoKCXJldHVybiAwOwp9CgpzdGF0aWMgY29uc3Qgc3RydWN0IGZpbGVfb3BlcmF0aW9ucyBwZXJmX2ZvcHMgPSB7CgkucmVsZWFzZQkJPSBwZXJmX3JlbGVhc2UsCgkucmVhZAkJCT0gcGVyZl9yZWFkLAoJLnBvbGwJCQk9IHBlcmZfcG9sbCwKCS51bmxvY2tlZF9pb2N0bAkJPSBwZXJmX2lvY3RsLAoJLmNvbXBhdF9pb2N0bAkJPSBwZXJmX2lvY3RsLAoJLm1tYXAJCQk9IHBlcmZfbW1hcCwKCS5mYXN5bmMJCQk9IHBlcmZfZmFzeW5jLAp9OwoKLyoKICogUGVyZiBldmVudCB3YWtldXAKICoKICogSWYgdGhlcmUncyBkYXRhLCBlbnN1cmUgd2Ugc2V0IHRoZSBwb2xsKCkgc3RhdGUgYW5kIHB1Ymxpc2ggZXZlcnl0aGluZwogKiB0byB1c2VyLXNwYWNlIGJlZm9yZSB3YWtpbmcgZXZlcnlib2R5IHVwLgogKi8KCnZvaWQgcGVyZl9ldmVudF93YWtldXAoc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50KQp7Cgl3YWtlX3VwX2FsbCgmZXZlbnQtPndhaXRxKTsKCglpZiAoZXZlbnQtPnBlbmRpbmdfa2lsbCkgewoJCWtpbGxfZmFzeW5jKCZldmVudC0+ZmFzeW5jLCBTSUdJTywgZXZlbnQtPnBlbmRpbmdfa2lsbCk7CgkJZXZlbnQtPnBlbmRpbmdfa2lsbCA9IDA7Cgl9Cn0KCi8qCiAqIFBlbmRpbmcgd2FrZXVwcwogKgogKiBIYW5kbGUgdGhlIGNhc2Ugd2hlcmUgd2UgbmVlZCB0byB3YWtldXAgdXAgZnJvbSBOTUkgKG9yIHJxLT5sb2NrKSBjb250ZXh0LgogKgogKiBUaGUgTk1JIGJpdCBtZWFucyB3ZSBjYW5ub3QgcG9zc2libHkgdGFrZSBsb2Nrcy4gVGhlcmVmb3JlLCBtYWludGFpbiBhCiAqIHNpbmdsZSBsaW5rZWQgbGlzdCBhbmQgdXNlIGNtcHhjaGcoKSB0byBhZGQgZW50cmllcyBsb2NrbGVzcy4KICovCgpzdGF0aWMgdm9pZCBwZXJmX3BlbmRpbmdfZXZlbnQoc3RydWN0IHBlcmZfcGVuZGluZ19lbnRyeSAqZW50cnkpCnsKCXN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCA9IGNvbnRhaW5lcl9vZihlbnRyeSwKCQkJc3RydWN0IHBlcmZfZXZlbnQsIHBlbmRpbmcpOwoKCWlmIChldmVudC0+cGVuZGluZ19kaXNhYmxlKSB7CgkJZXZlbnQtPnBlbmRpbmdfZGlzYWJsZSA9IDA7CgkJX19wZXJmX2V2ZW50X2Rpc2FibGUoZXZlbnQpOwoJfQoKCWlmIChldmVudC0+cGVuZGluZ193YWtldXApIHsKCQlldmVudC0+cGVuZGluZ193YWtldXAgPSAwOwoJCXBlcmZfZXZlbnRfd2FrZXVwKGV2ZW50KTsKCX0KfQoKI2RlZmluZSBQRU5ESU5HX1RBSUwgKChzdHJ1Y3QgcGVyZl9wZW5kaW5nX2VudHJ5ICopLTFVTCkKCnN0YXRpYyBERUZJTkVfUEVSX0NQVShzdHJ1Y3QgcGVyZl9wZW5kaW5nX2VudHJ5ICosIHBlcmZfcGVuZGluZ19oZWFkKSA9IHsKCVBFTkRJTkdfVEFJTCwKfTsKCnN0YXRpYyB2b2lkIHBlcmZfcGVuZGluZ19xdWV1ZShzdHJ1Y3QgcGVyZl9wZW5kaW5nX2VudHJ5ICplbnRyeSwKCQkJICAgICAgIHZvaWQgKCpmdW5jKShzdHJ1Y3QgcGVyZl9wZW5kaW5nX2VudHJ5ICopKQp7CglzdHJ1Y3QgcGVyZl9wZW5kaW5nX2VudHJ5ICoqaGVhZDsKCglpZiAoY21weGNoZygmZW50cnktPm5leHQsIE5VTEwsIFBFTkRJTkdfVEFJTCkgIT0gTlVMTCkKCQlyZXR1cm47CgoJZW50cnktPmZ1bmMgPSBmdW5jOwoKCWhlYWQgPSAmZ2V0X2NwdV92YXIocGVyZl9wZW5kaW5nX2hlYWQpOwoKCWRvIHsKCQllbnRyeS0+bmV4dCA9ICpoZWFkOwoJfSB3aGlsZSAoY21weGNoZyhoZWFkLCBlbnRyeS0+bmV4dCwgZW50cnkpICE9IGVudHJ5LT5uZXh0KTsKCglzZXRfcGVyZl9ldmVudF9wZW5kaW5nKCk7CgoJcHV0X2NwdV92YXIocGVyZl9wZW5kaW5nX2hlYWQpOwp9CgpzdGF0aWMgaW50IF9fcGVyZl9wZW5kaW5nX3J1bih2b2lkKQp7CglzdHJ1Y3QgcGVyZl9wZW5kaW5nX2VudHJ5ICpsaXN0OwoJaW50IG5yID0gMDsKCglsaXN0ID0geGNoZygmX19nZXRfY3B1X3ZhcihwZXJmX3BlbmRpbmdfaGVhZCksIFBFTkRJTkdfVEFJTCk7Cgl3aGlsZSAobGlzdCAhPSBQRU5ESU5HX1RBSUwpIHsKCQl2b2lkICgqZnVuYykoc3RydWN0IHBlcmZfcGVuZGluZ19lbnRyeSAqKTsKCQlzdHJ1Y3QgcGVyZl9wZW5kaW5nX2VudHJ5ICplbnRyeSA9IGxpc3Q7CgoJCWxpc3QgPSBsaXN0LT5uZXh0OwoKCQlmdW5jID0gZW50cnktPmZ1bmM7CgkJZW50cnktPm5leHQgPSBOVUxMOwoJCS8qCgkJICogRW5zdXJlIHdlIG9ic2VydmUgdGhlIHVucXVldWUgYmVmb3JlIHdlIGlzc3VlIHRoZSB3YWtldXAsCgkJICogc28gdGhhdCB3ZSB3b24ndCBiZSB3YWl0aW5nIGZvcmV2ZXIuCgkJICogLS0gc2VlIHBlcmZfbm90X3BlbmRpbmcoKS4KCQkgKi8KCQlzbXBfd21iKCk7CgoJCWZ1bmMoZW50cnkpOwoJCW5yKys7Cgl9CgoJcmV0dXJuIG5yOwp9CgpzdGF0aWMgaW5saW5lIGludCBwZXJmX25vdF9wZW5kaW5nKHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCkKewoJLyoKCSAqIElmIHdlIGZsdXNoIG9uIHdoYXRldmVyIGNwdSB3ZSBydW4sIHRoZXJlIGlzIGEgY2hhbmNlIHdlIGRvbid0CgkgKiBuZWVkIHRvIHdhaXQuCgkgKi8KCWdldF9jcHUoKTsKCV9fcGVyZl9wZW5kaW5nX3J1bigpOwoJcHV0X2NwdSgpOwoKCS8qCgkgKiBFbnN1cmUgd2Ugc2VlIHRoZSBwcm9wZXIgcXVldWUgc3RhdGUgYmVmb3JlIGdvaW5nIHRvIHNsZWVwCgkgKiBzbyB0aGF0IHdlIGRvIG5vdCBtaXNzIHRoZSB3YWtldXAuIC0tIHNlZSBwZXJmX3BlbmRpbmdfaGFuZGxlKCkKCSAqLwoJc21wX3JtYigpOwoJcmV0dXJuIGV2ZW50LT5wZW5kaW5nLm5leHQgPT0gTlVMTDsKfQoKc3RhdGljIHZvaWQgcGVyZl9wZW5kaW5nX3N5bmMoc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50KQp7Cgl3YWl0X2V2ZW50KGV2ZW50LT53YWl0cSwgcGVyZl9ub3RfcGVuZGluZyhldmVudCkpOwp9Cgp2b2lkIHBlcmZfZXZlbnRfZG9fcGVuZGluZyh2b2lkKQp7CglfX3BlcmZfcGVuZGluZ19ydW4oKTsKfQoKLyoKICogQ2FsbGNoYWluIHN1cHBvcnQgLS0gYXJjaCBzcGVjaWZpYwogKi8KCl9fd2VhayBzdHJ1Y3QgcGVyZl9jYWxsY2hhaW5fZW50cnkgKnBlcmZfY2FsbGNoYWluKHN0cnVjdCBwdF9yZWdzICpyZWdzKQp7CglyZXR1cm4gTlVMTDsKfQoKLyoKICogT3V0cHV0CiAqLwpzdGF0aWMgYm9vbCBwZXJmX291dHB1dF9zcGFjZShzdHJ1Y3QgcGVyZl9tbWFwX2RhdGEgKmRhdGEsIHVuc2lnbmVkIGxvbmcgdGFpbCwKCQkJICAgICAgdW5zaWduZWQgbG9uZyBvZmZzZXQsIHVuc2lnbmVkIGxvbmcgaGVhZCkKewoJdW5zaWduZWQgbG9uZyBtYXNrOwoKCWlmICghZGF0YS0+d3JpdGFibGUpCgkJcmV0dXJuIHRydWU7CgoJbWFzayA9IChkYXRhLT5ucl9wYWdlcyA8PCBQQUdFX1NISUZUKSAtIDE7CgoJb2Zmc2V0ID0gKG9mZnNldCAtIHRhaWwpICYgbWFzazsKCWhlYWQgICA9IChoZWFkICAgLSB0YWlsKSAmIG1hc2s7CgoJaWYgKChpbnQpKGhlYWQgLSBvZmZzZXQpIDwgMCkKCQlyZXR1cm4gZmFsc2U7CgoJcmV0dXJuIHRydWU7Cn0KCnN0YXRpYyB2b2lkIHBlcmZfb3V0cHV0X3dha2V1cChzdHJ1Y3QgcGVyZl9vdXRwdXRfaGFuZGxlICpoYW5kbGUpCnsKCWF0b21pY19zZXQoJmhhbmRsZS0+ZGF0YS0+cG9sbCwgUE9MTF9JTik7CgoJaWYgKGhhbmRsZS0+bm1pKSB7CgkJaGFuZGxlLT5ldmVudC0+cGVuZGluZ193YWtldXAgPSAxOwoJCXBlcmZfcGVuZGluZ19xdWV1ZSgmaGFuZGxlLT5ldmVudC0+cGVuZGluZywKCQkJCSAgIHBlcmZfcGVuZGluZ19ldmVudCk7Cgl9IGVsc2UKCQlwZXJmX2V2ZW50X3dha2V1cChoYW5kbGUtPmV2ZW50KTsKfQoKLyoKICogQ3VyaW91cyBsb2NraW5nIGNvbnN0cnVjdC4KICoKICogV2UgbmVlZCB0byBlbnN1cmUgYSBsYXRlciBldmVudF9pZCBkb2Vzbid0IHB1Ymxpc2ggYSBoZWFkIHdoZW4gYSBmb3JtZXIKICogZXZlbnRfaWQgaXNuJ3QgZG9uZSB3cml0aW5nLiBIb3dldmVyIHNpbmNlIHdlIG5lZWQgdG8gZGVhbCB3aXRoIE5NSXMgd2UKICogY2Fubm90IGZ1bGx5IHNlcmlhbGl6ZSB0aGluZ3MuCiAqCiAqIFdoYXQgd2UgZG8gaXMgc2VyaWFsaXplIGJldHdlZW4gQ1BVcyBzbyB3ZSBvbmx5IGhhdmUgdG8gZGVhbCB3aXRoIE5NSQogKiBuZXN0aW5nIG9uIGEgc2luZ2xlIENQVS4KICoKICogV2Ugb25seSBwdWJsaXNoIHRoZSBoZWFkIChhbmQgZ2VuZXJhdGUgYSB3YWtldXApIHdoZW4gdGhlIG91dGVyLW1vc3QKICogZXZlbnRfaWQgY29tcGxldGVzLgogKi8Kc3RhdGljIHZvaWQgcGVyZl9vdXRwdXRfbG9jayhzdHJ1Y3QgcGVyZl9vdXRwdXRfaGFuZGxlICpoYW5kbGUpCnsKCXN0cnVjdCBwZXJmX21tYXBfZGF0YSAqZGF0YSA9IGhhbmRsZS0+ZGF0YTsKCWludCBjcHU7CgoJaGFuZGxlLT5sb2NrZWQgPSAwOwoKCWxvY2FsX2lycV9zYXZlKGhhbmRsZS0+ZmxhZ3MpOwoJY3B1ID0gc21wX3Byb2Nlc3Nvcl9pZCgpOwoKCWlmIChpbl9ubWkoKSAmJiBhdG9taWNfcmVhZCgmZGF0YS0+bG9jaykgPT0gY3B1KQoJCXJldHVybjsKCgl3aGlsZSAoYXRvbWljX2NtcHhjaGcoJmRhdGEtPmxvY2ssIC0xLCBjcHUpICE9IC0xKQoJCWNwdV9yZWxheCgpOwoKCWhhbmRsZS0+bG9ja2VkID0gMTsKfQoKc3RhdGljIHZvaWQgcGVyZl9vdXRwdXRfdW5sb2NrKHN0cnVjdCBwZXJmX291dHB1dF9oYW5kbGUgKmhhbmRsZSkKewoJc3RydWN0IHBlcmZfbW1hcF9kYXRhICpkYXRhID0gaGFuZGxlLT5kYXRhOwoJdW5zaWduZWQgbG9uZyBoZWFkOwoJaW50IGNwdTsKCglkYXRhLT5kb25lX2hlYWQgPSBkYXRhLT5oZWFkOwoKCWlmICghaGFuZGxlLT5sb2NrZWQpCgkJZ290byBvdXQ7CgphZ2FpbjoKCS8qCgkgKiBUaGUgeGNoZyBpbXBsaWVzIGEgZnVsbCBiYXJyaWVyIHRoYXQgZW5zdXJlcyBhbGwgd3JpdGVzIGFyZSBkb25lCgkgKiBiZWZvcmUgd2UgcHVibGlzaCB0aGUgbmV3IGhlYWQsIG1hdGNoZWQgYnkgYSBybWIoKSBpbiB1c2Vyc3BhY2Ugd2hlbgoJICogcmVhZGluZyB0aGlzIHBvc2l0aW9uLgoJICovCgl3aGlsZSAoKGhlYWQgPSBhdG9taWNfbG9uZ194Y2hnKCZkYXRhLT5kb25lX2hlYWQsIDApKSkKCQlkYXRhLT51c2VyX3BhZ2UtPmRhdGFfaGVhZCA9IGhlYWQ7CgoJLyoKCSAqIE5NSSBjYW4gaGFwcGVuIGhlcmUsIHdoaWNoIG1lYW5zIHdlIGNhbiBtaXNzIGEgZG9uZV9oZWFkIHVwZGF0ZS4KCSAqLwoKCWNwdSA9IGF0b21pY194Y2hnKCZkYXRhLT5sb2NrLCAtMSk7CglXQVJOX09OX09OQ0UoY3B1ICE9IHNtcF9wcm9jZXNzb3JfaWQoKSk7CgoJLyoKCSAqIFRoZXJlZm9yZSB3ZSBoYXZlIHRvIHZhbGlkYXRlIHdlIGRpZCBub3QgaW5kZWVkIGRvIHNvLgoJICovCglpZiAodW5saWtlbHkoYXRvbWljX2xvbmdfcmVhZCgmZGF0YS0+ZG9uZV9oZWFkKSkpIHsKCQkvKgoJCSAqIFNpbmNlIHdlIGhhZCBpdCBsb2NrZWQsIHdlIGNhbiBsb2NrIGl0IGFnYWluLgoJCSAqLwoJCXdoaWxlIChhdG9taWNfY21weGNoZygmZGF0YS0+bG9jaywgLTEsIGNwdSkgIT0gLTEpCgkJCWNwdV9yZWxheCgpOwoKCQlnb3RvIGFnYWluOwoJfQoKCWlmIChhdG9taWNfeGNoZygmZGF0YS0+d2FrZXVwLCAwKSkKCQlwZXJmX291dHB1dF93YWtldXAoaGFuZGxlKTsKb3V0OgoJbG9jYWxfaXJxX3Jlc3RvcmUoaGFuZGxlLT5mbGFncyk7Cn0KCnZvaWQgcGVyZl9vdXRwdXRfY29weShzdHJ1Y3QgcGVyZl9vdXRwdXRfaGFuZGxlICpoYW5kbGUsCgkJICAgICAgY29uc3Qgdm9pZCAqYnVmLCB1bnNpZ25lZCBpbnQgbGVuKQp7Cgl1bnNpZ25lZCBpbnQgcGFnZXNfbWFzazsKCXVuc2lnbmVkIGludCBvZmZzZXQ7Cgl1bnNpZ25lZCBpbnQgc2l6ZTsKCXZvaWQgKipwYWdlczsKCglvZmZzZXQJCT0gaGFuZGxlLT5vZmZzZXQ7CglwYWdlc19tYXNrCT0gaGFuZGxlLT5kYXRhLT5ucl9wYWdlcyAtIDE7CglwYWdlcwkJPSBoYW5kbGUtPmRhdGEtPmRhdGFfcGFnZXM7CgoJZG8gewoJCXVuc2lnbmVkIGludCBwYWdlX29mZnNldDsKCQlpbnQgbnI7CgoJCW5yCSAgICA9IChvZmZzZXQgPj4gUEFHRV9TSElGVCkgJiBwYWdlc19tYXNrOwoJCXBhZ2Vfb2Zmc2V0ID0gb2Zmc2V0ICYgKFBBR0VfU0laRSAtIDEpOwoJCXNpemUJICAgID0gbWluX3QodW5zaWduZWQgaW50LCBQQUdFX1NJWkUgLSBwYWdlX29mZnNldCwgbGVuKTsKCgkJbWVtY3B5KHBhZ2VzW25yXSArIHBhZ2Vfb2Zmc2V0LCBidWYsIHNpemUpOwoKCQlsZW4JICAgIC09IHNpemU7CgkJYnVmCSAgICArPSBzaXplOwoJCW9mZnNldAkgICAgKz0gc2l6ZTsKCX0gd2hpbGUgKGxlbik7CgoJaGFuZGxlLT5vZmZzZXQgPSBvZmZzZXQ7CgoJLyoKCSAqIENoZWNrIHdlIGRpZG4ndCBjb3B5IHBhc3Qgb3VyIHJlc2VydmF0aW9uIHdpbmRvdywgdGFraW5nIHRoZQoJICogcG9zc2libGUgdW5zaWduZWQgaW50IHdyYXAgaW50byBhY2NvdW50LgoJICovCglXQVJOX09OX09OQ0UoKChsb25nKShoYW5kbGUtPmhlYWQgLSBoYW5kbGUtPm9mZnNldCkpIDwgMCk7Cn0KCmludCBwZXJmX291dHB1dF9iZWdpbihzdHJ1Y3QgcGVyZl9vdXRwdXRfaGFuZGxlICpoYW5kbGUsCgkJICAgICAgc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50LCB1bnNpZ25lZCBpbnQgc2l6ZSwKCQkgICAgICBpbnQgbm1pLCBpbnQgc2FtcGxlKQp7CglzdHJ1Y3QgcGVyZl9ldmVudCAqb3V0cHV0X2V2ZW50OwoJc3RydWN0IHBlcmZfbW1hcF9kYXRhICpkYXRhOwoJdW5zaWduZWQgbG9uZyB0YWlsLCBvZmZzZXQsIGhlYWQ7CglpbnQgaGF2ZV9sb3N0OwoJc3RydWN0IHsKCQlzdHJ1Y3QgcGVyZl9ldmVudF9oZWFkZXIgaGVhZGVyOwoJCXU2NAkJCSBpZDsKCQl1NjQJCQkgbG9zdDsKCX0gbG9zdF9ldmVudDsKCglyY3VfcmVhZF9sb2NrKCk7CgkvKgoJICogRm9yIGluaGVyaXRlZCBldmVudHMgd2Ugc2VuZCBhbGwgdGhlIG91dHB1dCB0b3dhcmRzIHRoZSBwYXJlbnQuCgkgKi8KCWlmIChldmVudC0+cGFyZW50KQoJCWV2ZW50ID0gZXZlbnQtPnBhcmVudDsKCglvdXRwdXRfZXZlbnQgPSByY3VfZGVyZWZlcmVuY2UoZXZlbnQtPm91dHB1dCk7CglpZiAob3V0cHV0X2V2ZW50KQoJCWV2ZW50ID0gb3V0cHV0X2V2ZW50OwoKCWRhdGEgPSByY3VfZGVyZWZlcmVuY2UoZXZlbnQtPmRhdGEpOwoJaWYgKCFkYXRhKQoJCWdvdG8gb3V0OwoKCWhhbmRsZS0+ZGF0YQk9IGRhdGE7CgloYW5kbGUtPmV2ZW50CT0gZXZlbnQ7CgloYW5kbGUtPm5taQk9IG5taTsKCWhhbmRsZS0+c2FtcGxlCT0gc2FtcGxlOwoKCWlmICghZGF0YS0+bnJfcGFnZXMpCgkJZ290byBmYWlsOwoKCWhhdmVfbG9zdCA9IGF0b21pY19yZWFkKCZkYXRhLT5sb3N0KTsKCWlmIChoYXZlX2xvc3QpCgkJc2l6ZSArPSBzaXplb2YobG9zdF9ldmVudCk7CgoJcGVyZl9vdXRwdXRfbG9jayhoYW5kbGUpOwoKCWRvIHsKCQkvKgoJCSAqIFVzZXJzcGFjZSBjb3VsZCBjaG9vc2UgdG8gaXNzdWUgYSBtYigpIGJlZm9yZSB1cGRhdGluZyB0aGUKCQkgKiB0YWlsIHBvaW50ZXIuIFNvIHRoYXQgYWxsIHJlYWRzIHdpbGwgYmUgY29tcGxldGVkIGJlZm9yZSB0aGUKCQkgKiB3cml0ZSBpcyBpc3N1ZWQuCgkJICovCgkJdGFpbCA9IEFDQ0VTU19PTkNFKGRhdGEtPnVzZXJfcGFnZS0+ZGF0YV90YWlsKTsKCQlzbXBfcm1iKCk7CgkJb2Zmc2V0ID0gaGVhZCA9IGF0b21pY19sb25nX3JlYWQoJmRhdGEtPmhlYWQpOwoJCWhlYWQgKz0gc2l6ZTsKCQlpZiAodW5saWtlbHkoIXBlcmZfb3V0cHV0X3NwYWNlKGRhdGEsIHRhaWwsIG9mZnNldCwgaGVhZCkpKQoJCQlnb3RvIGZhaWw7Cgl9IHdoaWxlIChhdG9taWNfbG9uZ19jbXB4Y2hnKCZkYXRhLT5oZWFkLCBvZmZzZXQsIGhlYWQpICE9IG9mZnNldCk7CgoJaGFuZGxlLT5vZmZzZXQJPSBvZmZzZXQ7CgloYW5kbGUtPmhlYWQJPSBoZWFkOwoKCWlmIChoZWFkIC0gdGFpbCA+IGRhdGEtPndhdGVybWFyaykKCQlhdG9taWNfc2V0KCZkYXRhLT53YWtldXAsIDEpOwoKCWlmIChoYXZlX2xvc3QpIHsKCQlsb3N0X2V2ZW50LmhlYWRlci50eXBlID0gUEVSRl9SRUNPUkRfTE9TVDsKCQlsb3N0X2V2ZW50LmhlYWRlci5taXNjID0gMDsKCQlsb3N0X2V2ZW50LmhlYWRlci5zaXplID0gc2l6ZW9mKGxvc3RfZXZlbnQpOwoJCWxvc3RfZXZlbnQuaWQgICAgICAgICAgPSBldmVudC0+aWQ7CgkJbG9zdF9ldmVudC5sb3N0ICAgICAgICA9IGF0b21pY194Y2hnKCZkYXRhLT5sb3N0LCAwKTsKCgkJcGVyZl9vdXRwdXRfcHV0KGhhbmRsZSwgbG9zdF9ldmVudCk7Cgl9CgoJcmV0dXJuIDA7CgpmYWlsOgoJYXRvbWljX2luYygmZGF0YS0+bG9zdCk7CglwZXJmX291dHB1dF91bmxvY2soaGFuZGxlKTsKb3V0OgoJcmN1X3JlYWRfdW5sb2NrKCk7CgoJcmV0dXJuIC1FTk9TUEM7Cn0KCnZvaWQgcGVyZl9vdXRwdXRfZW5kKHN0cnVjdCBwZXJmX291dHB1dF9oYW5kbGUgKmhhbmRsZSkKewoJc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50ID0gaGFuZGxlLT5ldmVudDsKCXN0cnVjdCBwZXJmX21tYXBfZGF0YSAqZGF0YSA9IGhhbmRsZS0+ZGF0YTsKCglpbnQgd2FrZXVwX2V2ZW50cyA9IGV2ZW50LT5hdHRyLndha2V1cF9ldmVudHM7CgoJaWYgKGhhbmRsZS0+c2FtcGxlICYmIHdha2V1cF9ldmVudHMpIHsKCQlpbnQgZXZlbnRzID0gYXRvbWljX2luY19yZXR1cm4oJmRhdGEtPmV2ZW50cyk7CgkJaWYgKGV2ZW50cyA+PSB3YWtldXBfZXZlbnRzKSB7CgkJCWF0b21pY19zdWIod2FrZXVwX2V2ZW50cywgJmRhdGEtPmV2ZW50cyk7CgkJCWF0b21pY19zZXQoJmRhdGEtPndha2V1cCwgMSk7CgkJfQoJfQoKCXBlcmZfb3V0cHV0X3VubG9jayhoYW5kbGUpOwoJcmN1X3JlYWRfdW5sb2NrKCk7Cn0KCnN0YXRpYyB1MzIgcGVyZl9ldmVudF9waWQoc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50LCBzdHJ1Y3QgdGFza19zdHJ1Y3QgKnApCnsKCS8qCgkgKiBvbmx5IHRvcCBsZXZlbCBldmVudHMgaGF2ZSB0aGUgcGlkIG5hbWVzcGFjZSB0aGV5IHdlcmUgY3JlYXRlZCBpbgoJICovCglpZiAoZXZlbnQtPnBhcmVudCkKCQlldmVudCA9IGV2ZW50LT5wYXJlbnQ7CgoJcmV0dXJuIHRhc2tfdGdpZF9ucl9ucyhwLCBldmVudC0+bnMpOwp9CgpzdGF0aWMgdTMyIHBlcmZfZXZlbnRfdGlkKHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCwgc3RydWN0IHRhc2tfc3RydWN0ICpwKQp7CgkvKgoJICogb25seSB0b3AgbGV2ZWwgZXZlbnRzIGhhdmUgdGhlIHBpZCBuYW1lc3BhY2UgdGhleSB3ZXJlIGNyZWF0ZWQgaW4KCSAqLwoJaWYgKGV2ZW50LT5wYXJlbnQpCgkJZXZlbnQgPSBldmVudC0+cGFyZW50OwoKCXJldHVybiB0YXNrX3BpZF9ucl9ucyhwLCBldmVudC0+bnMpOwp9CgpzdGF0aWMgdm9pZCBwZXJmX291dHB1dF9yZWFkX29uZShzdHJ1Y3QgcGVyZl9vdXRwdXRfaGFuZGxlICpoYW5kbGUsCgkJCQkgc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50KQp7Cgl1NjQgcmVhZF9mb3JtYXQgPSBldmVudC0+YXR0ci5yZWFkX2Zvcm1hdDsKCXU2NCB2YWx1ZXNbNF07CglpbnQgbiA9IDA7CgoJdmFsdWVzW24rK10gPSBhdG9taWM2NF9yZWFkKCZldmVudC0+Y291bnQpOwoJaWYgKHJlYWRfZm9ybWF0ICYgUEVSRl9GT1JNQVRfVE9UQUxfVElNRV9FTkFCTEVEKSB7CgkJdmFsdWVzW24rK10gPSBldmVudC0+dG90YWxfdGltZV9lbmFibGVkICsKCQkJYXRvbWljNjRfcmVhZCgmZXZlbnQtPmNoaWxkX3RvdGFsX3RpbWVfZW5hYmxlZCk7Cgl9CglpZiAocmVhZF9mb3JtYXQgJiBQRVJGX0ZPUk1BVF9UT1RBTF9USU1FX1JVTk5JTkcpIHsKCQl2YWx1ZXNbbisrXSA9IGV2ZW50LT50b3RhbF90aW1lX3J1bm5pbmcgKwoJCQlhdG9taWM2NF9yZWFkKCZldmVudC0+Y2hpbGRfdG90YWxfdGltZV9ydW5uaW5nKTsKCX0KCWlmIChyZWFkX2Zvcm1hdCAmIFBFUkZfRk9STUFUX0lEKQoJCXZhbHVlc1tuKytdID0gcHJpbWFyeV9ldmVudF9pZChldmVudCk7CgoJcGVyZl9vdXRwdXRfY29weShoYW5kbGUsIHZhbHVlcywgbiAqIHNpemVvZih1NjQpKTsKfQoKLyoKICogWFhYIFBFUkZfRk9STUFUX0dST1VQIHZzIGluaGVyaXRlZCBldmVudHMgc2VlbXMgZGlmZmljdWx0LgogKi8Kc3RhdGljIHZvaWQgcGVyZl9vdXRwdXRfcmVhZF9ncm91cChzdHJ1Y3QgcGVyZl9vdXRwdXRfaGFuZGxlICpoYW5kbGUsCgkJCSAgICBzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQpCnsKCXN0cnVjdCBwZXJmX2V2ZW50ICpsZWFkZXIgPSBldmVudC0+Z3JvdXBfbGVhZGVyLCAqc3ViOwoJdTY0IHJlYWRfZm9ybWF0ID0gZXZlbnQtPmF0dHIucmVhZF9mb3JtYXQ7Cgl1NjQgdmFsdWVzWzVdOwoJaW50IG4gPSAwOwoKCXZhbHVlc1tuKytdID0gMSArIGxlYWRlci0+bnJfc2libGluZ3M7CgoJaWYgKHJlYWRfZm9ybWF0ICYgUEVSRl9GT1JNQVRfVE9UQUxfVElNRV9FTkFCTEVEKQoJCXZhbHVlc1tuKytdID0gbGVhZGVyLT50b3RhbF90aW1lX2VuYWJsZWQ7CgoJaWYgKHJlYWRfZm9ybWF0ICYgUEVSRl9GT1JNQVRfVE9UQUxfVElNRV9SVU5OSU5HKQoJCXZhbHVlc1tuKytdID0gbGVhZGVyLT50b3RhbF90aW1lX3J1bm5pbmc7CgoJaWYgKGxlYWRlciAhPSBldmVudCkKCQlsZWFkZXItPnBtdS0+cmVhZChsZWFkZXIpOwoKCXZhbHVlc1tuKytdID0gYXRvbWljNjRfcmVhZCgmbGVhZGVyLT5jb3VudCk7CglpZiAocmVhZF9mb3JtYXQgJiBQRVJGX0ZPUk1BVF9JRCkKCQl2YWx1ZXNbbisrXSA9IHByaW1hcnlfZXZlbnRfaWQobGVhZGVyKTsKCglwZXJmX291dHB1dF9jb3B5KGhhbmRsZSwgdmFsdWVzLCBuICogc2l6ZW9mKHU2NCkpOwoKCWxpc3RfZm9yX2VhY2hfZW50cnkoc3ViLCAmbGVhZGVyLT5zaWJsaW5nX2xpc3QsIGdyb3VwX2VudHJ5KSB7CgkJbiA9IDA7CgoJCWlmIChzdWIgIT0gZXZlbnQpCgkJCXN1Yi0+cG11LT5yZWFkKHN1Yik7CgoJCXZhbHVlc1tuKytdID0gYXRvbWljNjRfcmVhZCgmc3ViLT5jb3VudCk7CgkJaWYgKHJlYWRfZm9ybWF0ICYgUEVSRl9GT1JNQVRfSUQpCgkJCXZhbHVlc1tuKytdID0gcHJpbWFyeV9ldmVudF9pZChzdWIpOwoKCQlwZXJmX291dHB1dF9jb3B5KGhhbmRsZSwgdmFsdWVzLCBuICogc2l6ZW9mKHU2NCkpOwoJfQp9CgpzdGF0aWMgdm9pZCBwZXJmX291dHB1dF9yZWFkKHN0cnVjdCBwZXJmX291dHB1dF9oYW5kbGUgKmhhbmRsZSwKCQkJICAgICBzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQpCnsKCWlmIChldmVudC0+YXR0ci5yZWFkX2Zvcm1hdCAmIFBFUkZfRk9STUFUX0dST1VQKQoJCXBlcmZfb3V0cHV0X3JlYWRfZ3JvdXAoaGFuZGxlLCBldmVudCk7CgllbHNlCgkJcGVyZl9vdXRwdXRfcmVhZF9vbmUoaGFuZGxlLCBldmVudCk7Cn0KCnZvaWQgcGVyZl9vdXRwdXRfc2FtcGxlKHN0cnVjdCBwZXJmX291dHB1dF9oYW5kbGUgKmhhbmRsZSwKCQkJc3RydWN0IHBlcmZfZXZlbnRfaGVhZGVyICpoZWFkZXIsCgkJCXN0cnVjdCBwZXJmX3NhbXBsZV9kYXRhICpkYXRhLAoJCQlzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQpCnsKCXU2NCBzYW1wbGVfdHlwZSA9IGRhdGEtPnR5cGU7CgoJcGVyZl9vdXRwdXRfcHV0KGhhbmRsZSwgKmhlYWRlcik7CgoJaWYgKHNhbXBsZV90eXBlICYgUEVSRl9TQU1QTEVfSVApCgkJcGVyZl9vdXRwdXRfcHV0KGhhbmRsZSwgZGF0YS0+aXApOwoKCWlmIChzYW1wbGVfdHlwZSAmIFBFUkZfU0FNUExFX1RJRCkKCQlwZXJmX291dHB1dF9wdXQoaGFuZGxlLCBkYXRhLT50aWRfZW50cnkpOwoKCWlmIChzYW1wbGVfdHlwZSAmIFBFUkZfU0FNUExFX1RJTUUpCgkJcGVyZl9vdXRwdXRfcHV0KGhhbmRsZSwgZGF0YS0+dGltZSk7CgoJaWYgKHNhbXBsZV90eXBlICYgUEVSRl9TQU1QTEVfQUREUikKCQlwZXJmX291dHB1dF9wdXQoaGFuZGxlLCBkYXRhLT5hZGRyKTsKCglpZiAoc2FtcGxlX3R5cGUgJiBQRVJGX1NBTVBMRV9JRCkKCQlwZXJmX291dHB1dF9wdXQoaGFuZGxlLCBkYXRhLT5pZCk7CgoJaWYgKHNhbXBsZV90eXBlICYgUEVSRl9TQU1QTEVfU1RSRUFNX0lEKQoJCXBlcmZfb3V0cHV0X3B1dChoYW5kbGUsIGRhdGEtPnN0cmVhbV9pZCk7CgoJaWYgKHNhbXBsZV90eXBlICYgUEVSRl9TQU1QTEVfQ1BVKQoJCXBlcmZfb3V0cHV0X3B1dChoYW5kbGUsIGRhdGEtPmNwdV9lbnRyeSk7CgoJaWYgKHNhbXBsZV90eXBlICYgUEVSRl9TQU1QTEVfUEVSSU9EKQoJCXBlcmZfb3V0cHV0X3B1dChoYW5kbGUsIGRhdGEtPnBlcmlvZCk7CgoJaWYgKHNhbXBsZV90eXBlICYgUEVSRl9TQU1QTEVfUkVBRCkKCQlwZXJmX291dHB1dF9yZWFkKGhhbmRsZSwgZXZlbnQpOwoKCWlmIChzYW1wbGVfdHlwZSAmIFBFUkZfU0FNUExFX0NBTExDSEFJTikgewoJCWlmIChkYXRhLT5jYWxsY2hhaW4pIHsKCQkJaW50IHNpemUgPSAxOwoKCQkJaWYgKGRhdGEtPmNhbGxjaGFpbikKCQkJCXNpemUgKz0gZGF0YS0+Y2FsbGNoYWluLT5ucjsKCgkJCXNpemUgKj0gc2l6ZW9mKHU2NCk7CgoJCQlwZXJmX291dHB1dF9jb3B5KGhhbmRsZSwgZGF0YS0+Y2FsbGNoYWluLCBzaXplKTsKCQl9IGVsc2UgewoJCQl1NjQgbnIgPSAwOwoJCQlwZXJmX291dHB1dF9wdXQoaGFuZGxlLCBucik7CgkJfQoJfQoKCWlmIChzYW1wbGVfdHlwZSAmIFBFUkZfU0FNUExFX1JBVykgewoJCWlmIChkYXRhLT5yYXcpIHsKCQkJcGVyZl9vdXRwdXRfcHV0KGhhbmRsZSwgZGF0YS0+cmF3LT5zaXplKTsKCQkJcGVyZl9vdXRwdXRfY29weShoYW5kbGUsIGRhdGEtPnJhdy0+ZGF0YSwKCQkJCQkgZGF0YS0+cmF3LT5zaXplKTsKCQl9IGVsc2UgewoJCQlzdHJ1Y3QgewoJCQkJdTMyCXNpemU7CgkJCQl1MzIJZGF0YTsKCQkJfSByYXcgPSB7CgkJCQkuc2l6ZSA9IHNpemVvZih1MzIpLAoJCQkJLmRhdGEgPSAwLAoJCQl9OwoJCQlwZXJmX291dHB1dF9wdXQoaGFuZGxlLCByYXcpOwoJCX0KCX0KfQoKdm9pZCBwZXJmX3ByZXBhcmVfc2FtcGxlKHN0cnVjdCBwZXJmX2V2ZW50X2hlYWRlciAqaGVhZGVyLAoJCQkgc3RydWN0IHBlcmZfc2FtcGxlX2RhdGEgKmRhdGEsCgkJCSBzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQsCgkJCSBzdHJ1Y3QgcHRfcmVncyAqcmVncykKewoJdTY0IHNhbXBsZV90eXBlID0gZXZlbnQtPmF0dHIuc2FtcGxlX3R5cGU7CgoJZGF0YS0+dHlwZSA9IHNhbXBsZV90eXBlOwoKCWhlYWRlci0+dHlwZSA9IFBFUkZfUkVDT1JEX1NBTVBMRTsKCWhlYWRlci0+c2l6ZSA9IHNpemVvZigqaGVhZGVyKTsKCgloZWFkZXItPm1pc2MgPSAwOwoJaGVhZGVyLT5taXNjIHw9IHBlcmZfbWlzY19mbGFncyhyZWdzKTsKCglpZiAoc2FtcGxlX3R5cGUgJiBQRVJGX1NBTVBMRV9JUCkgewoJCWRhdGEtPmlwID0gcGVyZl9pbnN0cnVjdGlvbl9wb2ludGVyKHJlZ3MpOwoKCQloZWFkZXItPnNpemUgKz0gc2l6ZW9mKGRhdGEtPmlwKTsKCX0KCglpZiAoc2FtcGxlX3R5cGUgJiBQRVJGX1NBTVBMRV9USUQpIHsKCQkvKiBuYW1lc3BhY2UgaXNzdWVzICovCgkJZGF0YS0+dGlkX2VudHJ5LnBpZCA9IHBlcmZfZXZlbnRfcGlkKGV2ZW50LCBjdXJyZW50KTsKCQlkYXRhLT50aWRfZW50cnkudGlkID0gcGVyZl9ldmVudF90aWQoZXZlbnQsIGN1cnJlbnQpOwoKCQloZWFkZXItPnNpemUgKz0gc2l6ZW9mKGRhdGEtPnRpZF9lbnRyeSk7Cgl9CgoJaWYgKHNhbXBsZV90eXBlICYgUEVSRl9TQU1QTEVfVElNRSkgewoJCWRhdGEtPnRpbWUgPSBwZXJmX2Nsb2NrKCk7CgoJCWhlYWRlci0+c2l6ZSArPSBzaXplb2YoZGF0YS0+dGltZSk7Cgl9CgoJaWYgKHNhbXBsZV90eXBlICYgUEVSRl9TQU1QTEVfQUREUikKCQloZWFkZXItPnNpemUgKz0gc2l6ZW9mKGRhdGEtPmFkZHIpOwoKCWlmIChzYW1wbGVfdHlwZSAmIFBFUkZfU0FNUExFX0lEKSB7CgkJZGF0YS0+aWQgPSBwcmltYXJ5X2V2ZW50X2lkKGV2ZW50KTsKCgkJaGVhZGVyLT5zaXplICs9IHNpemVvZihkYXRhLT5pZCk7Cgl9CgoJaWYgKHNhbXBsZV90eXBlICYgUEVSRl9TQU1QTEVfU1RSRUFNX0lEKSB7CgkJZGF0YS0+c3RyZWFtX2lkID0gZXZlbnQtPmlkOwoKCQloZWFkZXItPnNpemUgKz0gc2l6ZW9mKGRhdGEtPnN0cmVhbV9pZCk7Cgl9CgoJaWYgKHNhbXBsZV90eXBlICYgUEVSRl9TQU1QTEVfQ1BVKSB7CgkJZGF0YS0+Y3B1X2VudHJ5LmNwdQkJPSByYXdfc21wX3Byb2Nlc3Nvcl9pZCgpOwoJCWRhdGEtPmNwdV9lbnRyeS5yZXNlcnZlZAk9IDA7CgoJCWhlYWRlci0+c2l6ZSArPSBzaXplb2YoZGF0YS0+Y3B1X2VudHJ5KTsKCX0KCglpZiAoc2FtcGxlX3R5cGUgJiBQRVJGX1NBTVBMRV9QRVJJT0QpCgkJaGVhZGVyLT5zaXplICs9IHNpemVvZihkYXRhLT5wZXJpb2QpOwoKCWlmIChzYW1wbGVfdHlwZSAmIFBFUkZfU0FNUExFX1JFQUQpCgkJaGVhZGVyLT5zaXplICs9IHBlcmZfZXZlbnRfcmVhZF9zaXplKGV2ZW50KTsKCglpZiAoc2FtcGxlX3R5cGUgJiBQRVJGX1NBTVBMRV9DQUxMQ0hBSU4pIHsKCQlpbnQgc2l6ZSA9IDE7CgoJCWRhdGEtPmNhbGxjaGFpbiA9IHBlcmZfY2FsbGNoYWluKHJlZ3MpOwoKCQlpZiAoZGF0YS0+Y2FsbGNoYWluKQoJCQlzaXplICs9IGRhdGEtPmNhbGxjaGFpbi0+bnI7CgoJCWhlYWRlci0+c2l6ZSArPSBzaXplICogc2l6ZW9mKHU2NCk7Cgl9CgoJaWYgKHNhbXBsZV90eXBlICYgUEVSRl9TQU1QTEVfUkFXKSB7CgkJaW50IHNpemUgPSBzaXplb2YodTMyKTsKCgkJaWYgKGRhdGEtPnJhdykKCQkJc2l6ZSArPSBkYXRhLT5yYXctPnNpemU7CgkJZWxzZQoJCQlzaXplICs9IHNpemVvZih1MzIpOwoKCQlXQVJOX09OX09OQ0Uoc2l6ZSAmIChzaXplb2YodTY0KS0xKSk7CgkJaGVhZGVyLT5zaXplICs9IHNpemU7Cgl9Cn0KCnN0YXRpYyB2b2lkIHBlcmZfZXZlbnRfb3V0cHV0KHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCwgaW50IG5taSwKCQkJCXN0cnVjdCBwZXJmX3NhbXBsZV9kYXRhICpkYXRhLAoJCQkJc3RydWN0IHB0X3JlZ3MgKnJlZ3MpCnsKCXN0cnVjdCBwZXJmX291dHB1dF9oYW5kbGUgaGFuZGxlOwoJc3RydWN0IHBlcmZfZXZlbnRfaGVhZGVyIGhlYWRlcjsKCglwZXJmX3ByZXBhcmVfc2FtcGxlKCZoZWFkZXIsIGRhdGEsIGV2ZW50LCByZWdzKTsKCglpZiAocGVyZl9vdXRwdXRfYmVnaW4oJmhhbmRsZSwgZXZlbnQsIGhlYWRlci5zaXplLCBubWksIDEpKQoJCXJldHVybjsKCglwZXJmX291dHB1dF9zYW1wbGUoJmhhbmRsZSwgJmhlYWRlciwgZGF0YSwgZXZlbnQpOwoKCXBlcmZfb3V0cHV0X2VuZCgmaGFuZGxlKTsKfQoKLyoKICogcmVhZCBldmVudF9pZAogKi8KCnN0cnVjdCBwZXJmX3JlYWRfZXZlbnQgewoJc3RydWN0IHBlcmZfZXZlbnRfaGVhZGVyCWhlYWRlcjsKCgl1MzIJCQkJcGlkOwoJdTMyCQkJCXRpZDsKfTsKCnN0YXRpYyB2b2lkCnBlcmZfZXZlbnRfcmVhZF9ldmVudChzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQsCgkJCXN0cnVjdCB0YXNrX3N0cnVjdCAqdGFzaykKewoJc3RydWN0IHBlcmZfb3V0cHV0X2hhbmRsZSBoYW5kbGU7CglzdHJ1Y3QgcGVyZl9yZWFkX2V2ZW50IHJlYWRfZXZlbnQgPSB7CgkJLmhlYWRlciA9IHsKCQkJLnR5cGUgPSBQRVJGX1JFQ09SRF9SRUFELAoJCQkubWlzYyA9IDAsCgkJCS5zaXplID0gc2l6ZW9mKHJlYWRfZXZlbnQpICsgcGVyZl9ldmVudF9yZWFkX3NpemUoZXZlbnQpLAoJCX0sCgkJLnBpZCA9IHBlcmZfZXZlbnRfcGlkKGV2ZW50LCB0YXNrKSwKCQkudGlkID0gcGVyZl9ldmVudF90aWQoZXZlbnQsIHRhc2spLAoJfTsKCWludCByZXQ7CgoJcmV0ID0gcGVyZl9vdXRwdXRfYmVnaW4oJmhhbmRsZSwgZXZlbnQsIHJlYWRfZXZlbnQuaGVhZGVyLnNpemUsIDAsIDApOwoJaWYgKHJldCkKCQlyZXR1cm47CgoJcGVyZl9vdXRwdXRfcHV0KCZoYW5kbGUsIHJlYWRfZXZlbnQpOwoJcGVyZl9vdXRwdXRfcmVhZCgmaGFuZGxlLCBldmVudCk7CgoJcGVyZl9vdXRwdXRfZW5kKCZoYW5kbGUpOwp9CgovKgogKiB0YXNrIHRyYWNraW5nIC0tIGZvcmsvZXhpdAogKgogKiBlbmFibGVkIGJ5OiBhdHRyLmNvbW0gfCBhdHRyLm1tYXAgfCBhdHRyLnRhc2sKICovCgpzdHJ1Y3QgcGVyZl90YXNrX2V2ZW50IHsKCXN0cnVjdCB0YXNrX3N0cnVjdAkJKnRhc2s7CglzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0CSp0YXNrX2N0eDsKCglzdHJ1Y3QgewoJCXN0cnVjdCBwZXJmX2V2ZW50X2hlYWRlcgloZWFkZXI7CgoJCXUzMgkJCQlwaWQ7CgkJdTMyCQkJCXBwaWQ7CgkJdTMyCQkJCXRpZDsKCQl1MzIJCQkJcHRpZDsKCQl1NjQJCQkJdGltZTsKCX0gZXZlbnRfaWQ7Cn07CgpzdGF0aWMgdm9pZCBwZXJmX2V2ZW50X3Rhc2tfb3V0cHV0KHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCwKCQkJCSAgICAgc3RydWN0IHBlcmZfdGFza19ldmVudCAqdGFza19ldmVudCkKewoJc3RydWN0IHBlcmZfb3V0cHV0X2hhbmRsZSBoYW5kbGU7CglpbnQgc2l6ZTsKCXN0cnVjdCB0YXNrX3N0cnVjdCAqdGFzayA9IHRhc2tfZXZlbnQtPnRhc2s7CglpbnQgcmV0OwoKCXNpemUgID0gdGFza19ldmVudC0+ZXZlbnRfaWQuaGVhZGVyLnNpemU7CglyZXQgPSBwZXJmX291dHB1dF9iZWdpbigmaGFuZGxlLCBldmVudCwgc2l6ZSwgMCwgMCk7CgoJaWYgKHJldCkKCQlyZXR1cm47CgoJdGFza19ldmVudC0+ZXZlbnRfaWQucGlkID0gcGVyZl9ldmVudF9waWQoZXZlbnQsIHRhc2spOwoJdGFza19ldmVudC0+ZXZlbnRfaWQucHBpZCA9IHBlcmZfZXZlbnRfcGlkKGV2ZW50LCBjdXJyZW50KTsKCgl0YXNrX2V2ZW50LT5ldmVudF9pZC50aWQgPSBwZXJmX2V2ZW50X3RpZChldmVudCwgdGFzayk7Cgl0YXNrX2V2ZW50LT5ldmVudF9pZC5wdGlkID0gcGVyZl9ldmVudF90aWQoZXZlbnQsIGN1cnJlbnQpOwoKCXRhc2tfZXZlbnQtPmV2ZW50X2lkLnRpbWUgPSBwZXJmX2Nsb2NrKCk7CgoJcGVyZl9vdXRwdXRfcHV0KCZoYW5kbGUsIHRhc2tfZXZlbnQtPmV2ZW50X2lkKTsKCglwZXJmX291dHB1dF9lbmQoJmhhbmRsZSk7Cn0KCnN0YXRpYyBpbnQgcGVyZl9ldmVudF90YXNrX21hdGNoKHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCkKewoJaWYgKGV2ZW50LT5hdHRyLmNvbW0gfHwgZXZlbnQtPmF0dHIubW1hcCB8fCBldmVudC0+YXR0ci50YXNrKQoJCXJldHVybiAxOwoKCXJldHVybiAwOwp9CgpzdGF0aWMgdm9pZCBwZXJmX2V2ZW50X3Rhc2tfY3R4KHN0cnVjdCBwZXJmX2V2ZW50X2NvbnRleHQgKmN0eCwKCQkJCSAgc3RydWN0IHBlcmZfdGFza19ldmVudCAqdGFza19ldmVudCkKewoJc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50OwoKCWlmIChzeXN0ZW1fc3RhdGUgIT0gU1lTVEVNX1JVTk5JTkcgfHwgbGlzdF9lbXB0eSgmY3R4LT5ldmVudF9saXN0KSkKCQlyZXR1cm47CgoJcmN1X3JlYWRfbG9jaygpOwoJbGlzdF9mb3JfZWFjaF9lbnRyeV9yY3UoZXZlbnQsICZjdHgtPmV2ZW50X2xpc3QsIGV2ZW50X2VudHJ5KSB7CgkJaWYgKHBlcmZfZXZlbnRfdGFza19tYXRjaChldmVudCkpCgkJCXBlcmZfZXZlbnRfdGFza19vdXRwdXQoZXZlbnQsIHRhc2tfZXZlbnQpOwoJfQoJcmN1X3JlYWRfdW5sb2NrKCk7Cn0KCnN0YXRpYyB2b2lkIHBlcmZfZXZlbnRfdGFza19ldmVudChzdHJ1Y3QgcGVyZl90YXNrX2V2ZW50ICp0YXNrX2V2ZW50KQp7CglzdHJ1Y3QgcGVyZl9jcHVfY29udGV4dCAqY3B1Y3R4OwoJc3RydWN0IHBlcmZfZXZlbnRfY29udGV4dCAqY3R4ID0gdGFza19ldmVudC0+dGFza19jdHg7CgoJY3B1Y3R4ID0gJmdldF9jcHVfdmFyKHBlcmZfY3B1X2NvbnRleHQpOwoJcGVyZl9ldmVudF90YXNrX2N0eCgmY3B1Y3R4LT5jdHgsIHRhc2tfZXZlbnQpOwoJcHV0X2NwdV92YXIocGVyZl9jcHVfY29udGV4dCk7CgoJcmN1X3JlYWRfbG9jaygpOwoJaWYgKCFjdHgpCgkJY3R4ID0gcmN1X2RlcmVmZXJlbmNlKHRhc2tfZXZlbnQtPnRhc2stPnBlcmZfZXZlbnRfY3R4cCk7CglpZiAoY3R4KQoJCXBlcmZfZXZlbnRfdGFza19jdHgoY3R4LCB0YXNrX2V2ZW50KTsKCXJjdV9yZWFkX3VubG9jaygpOwp9CgpzdGF0aWMgdm9pZCBwZXJmX2V2ZW50X3Rhc2soc3RydWN0IHRhc2tfc3RydWN0ICp0YXNrLAoJCQkgICAgICBzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0ICp0YXNrX2N0eCwKCQkJICAgICAgaW50IG5ldykKewoJc3RydWN0IHBlcmZfdGFza19ldmVudCB0YXNrX2V2ZW50OwoKCWlmICghYXRvbWljX3JlYWQoJm5yX2NvbW1fZXZlbnRzKSAmJgoJICAgICFhdG9taWNfcmVhZCgmbnJfbW1hcF9ldmVudHMpICYmCgkgICAgIWF0b21pY19yZWFkKCZucl90YXNrX2V2ZW50cykpCgkJcmV0dXJuOwoKCXRhc2tfZXZlbnQgPSAoc3RydWN0IHBlcmZfdGFza19ldmVudCl7CgkJLnRhc2sJICA9IHRhc2ssCgkJLnRhc2tfY3R4ID0gdGFza19jdHgsCgkJLmV2ZW50X2lkICAgID0gewoJCQkuaGVhZGVyID0gewoJCQkJLnR5cGUgPSBuZXcgPyBQRVJGX1JFQ09SRF9GT1JLIDogUEVSRl9SRUNPUkRfRVhJVCwKCQkJCS5taXNjID0gMCwKCQkJCS5zaXplID0gc2l6ZW9mKHRhc2tfZXZlbnQuZXZlbnRfaWQpLAoJCQl9LAoJCQkvKiAucGlkICAqLwoJCQkvKiAucHBpZCAqLwoJCQkvKiAudGlkICAqLwoJCQkvKiAucHRpZCAqLwoJCX0sCgl9OwoKCXBlcmZfZXZlbnRfdGFza19ldmVudCgmdGFza19ldmVudCk7Cn0KCnZvaWQgcGVyZl9ldmVudF9mb3JrKHN0cnVjdCB0YXNrX3N0cnVjdCAqdGFzaykKewoJcGVyZl9ldmVudF90YXNrKHRhc2ssIE5VTEwsIDEpOwp9CgovKgogKiBjb21tIHRyYWNraW5nCiAqLwoKc3RydWN0IHBlcmZfY29tbV9ldmVudCB7CglzdHJ1Y3QgdGFza19zdHJ1Y3QJKnRhc2s7CgljaGFyCQkJKmNvbW07CglpbnQJCQljb21tX3NpemU7CgoJc3RydWN0IHsKCQlzdHJ1Y3QgcGVyZl9ldmVudF9oZWFkZXIJaGVhZGVyOwoKCQl1MzIJCQkJcGlkOwoJCXUzMgkJCQl0aWQ7Cgl9IGV2ZW50X2lkOwp9OwoKc3RhdGljIHZvaWQgcGVyZl9ldmVudF9jb21tX291dHB1dChzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQsCgkJCQkgICAgIHN0cnVjdCBwZXJmX2NvbW1fZXZlbnQgKmNvbW1fZXZlbnQpCnsKCXN0cnVjdCBwZXJmX291dHB1dF9oYW5kbGUgaGFuZGxlOwoJaW50IHNpemUgPSBjb21tX2V2ZW50LT5ldmVudF9pZC5oZWFkZXIuc2l6ZTsKCWludCByZXQgPSBwZXJmX291dHB1dF9iZWdpbigmaGFuZGxlLCBldmVudCwgc2l6ZSwgMCwgMCk7CgoJaWYgKHJldCkKCQlyZXR1cm47CgoJY29tbV9ldmVudC0+ZXZlbnRfaWQucGlkID0gcGVyZl9ldmVudF9waWQoZXZlbnQsIGNvbW1fZXZlbnQtPnRhc2spOwoJY29tbV9ldmVudC0+ZXZlbnRfaWQudGlkID0gcGVyZl9ldmVudF90aWQoZXZlbnQsIGNvbW1fZXZlbnQtPnRhc2spOwoKCXBlcmZfb3V0cHV0X3B1dCgmaGFuZGxlLCBjb21tX2V2ZW50LT5ldmVudF9pZCk7CglwZXJmX291dHB1dF9jb3B5KCZoYW5kbGUsIGNvbW1fZXZlbnQtPmNvbW0sCgkJCQkgICBjb21tX2V2ZW50LT5jb21tX3NpemUpOwoJcGVyZl9vdXRwdXRfZW5kKCZoYW5kbGUpOwp9CgpzdGF0aWMgaW50IHBlcmZfZXZlbnRfY29tbV9tYXRjaChzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQpCnsKCWlmIChldmVudC0+YXR0ci5jb21tKQoJCXJldHVybiAxOwoKCXJldHVybiAwOwp9CgpzdGF0aWMgdm9pZCBwZXJmX2V2ZW50X2NvbW1fY3R4KHN0cnVjdCBwZXJmX2V2ZW50X2NvbnRleHQgKmN0eCwKCQkJCSAgc3RydWN0IHBlcmZfY29tbV9ldmVudCAqY29tbV9ldmVudCkKewoJc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50OwoKCWlmIChzeXN0ZW1fc3RhdGUgIT0gU1lTVEVNX1JVTk5JTkcgfHwgbGlzdF9lbXB0eSgmY3R4LT5ldmVudF9saXN0KSkKCQlyZXR1cm47CgoJcmN1X3JlYWRfbG9jaygpOwoJbGlzdF9mb3JfZWFjaF9lbnRyeV9yY3UoZXZlbnQsICZjdHgtPmV2ZW50X2xpc3QsIGV2ZW50X2VudHJ5KSB7CgkJaWYgKHBlcmZfZXZlbnRfY29tbV9tYXRjaChldmVudCkpCgkJCXBlcmZfZXZlbnRfY29tbV9vdXRwdXQoZXZlbnQsIGNvbW1fZXZlbnQpOwoJfQoJcmN1X3JlYWRfdW5sb2NrKCk7Cn0KCnN0YXRpYyB2b2lkIHBlcmZfZXZlbnRfY29tbV9ldmVudChzdHJ1Y3QgcGVyZl9jb21tX2V2ZW50ICpjb21tX2V2ZW50KQp7CglzdHJ1Y3QgcGVyZl9jcHVfY29udGV4dCAqY3B1Y3R4OwoJc3RydWN0IHBlcmZfZXZlbnRfY29udGV4dCAqY3R4OwoJdW5zaWduZWQgaW50IHNpemU7CgljaGFyIGNvbW1bVEFTS19DT01NX0xFTl07CgoJbWVtc2V0KGNvbW0sIDAsIHNpemVvZihjb21tKSk7CglzdHJuY3B5KGNvbW0sIGNvbW1fZXZlbnQtPnRhc2stPmNvbW0sIHNpemVvZihjb21tKSk7CglzaXplID0gQUxJR04oc3RybGVuKGNvbW0pKzEsIHNpemVvZih1NjQpKTsKCgljb21tX2V2ZW50LT5jb21tID0gY29tbTsKCWNvbW1fZXZlbnQtPmNvbW1fc2l6ZSA9IHNpemU7CgoJY29tbV9ldmVudC0+ZXZlbnRfaWQuaGVhZGVyLnNpemUgPSBzaXplb2YoY29tbV9ldmVudC0+ZXZlbnRfaWQpICsgc2l6ZTsKCgljcHVjdHggPSAmZ2V0X2NwdV92YXIocGVyZl9jcHVfY29udGV4dCk7CglwZXJmX2V2ZW50X2NvbW1fY3R4KCZjcHVjdHgtPmN0eCwgY29tbV9ldmVudCk7CglwdXRfY3B1X3ZhcihwZXJmX2NwdV9jb250ZXh0KTsKCglyY3VfcmVhZF9sb2NrKCk7CgkvKgoJICogZG9lc24ndCByZWFsbHkgbWF0dGVyIHdoaWNoIG9mIHRoZSBjaGlsZCBjb250ZXh0cyB0aGUKCSAqIGV2ZW50cyBlbmRzIHVwIGluLgoJICovCgljdHggPSByY3VfZGVyZWZlcmVuY2UoY3VycmVudC0+cGVyZl9ldmVudF9jdHhwKTsKCWlmIChjdHgpCgkJcGVyZl9ldmVudF9jb21tX2N0eChjdHgsIGNvbW1fZXZlbnQpOwoJcmN1X3JlYWRfdW5sb2NrKCk7Cn0KCnZvaWQgcGVyZl9ldmVudF9jb21tKHN0cnVjdCB0YXNrX3N0cnVjdCAqdGFzaykKewoJc3RydWN0IHBlcmZfY29tbV9ldmVudCBjb21tX2V2ZW50OwoKCWlmICh0YXNrLT5wZXJmX2V2ZW50X2N0eHApCgkJcGVyZl9ldmVudF9lbmFibGVfb25fZXhlYyh0YXNrKTsKCglpZiAoIWF0b21pY19yZWFkKCZucl9jb21tX2V2ZW50cykpCgkJcmV0dXJuOwoKCWNvbW1fZXZlbnQgPSAoc3RydWN0IHBlcmZfY29tbV9ldmVudCl7CgkJLnRhc2sJPSB0YXNrLAoJCS8qIC5jb21tICAgICAgKi8KCQkvKiAuY29tbV9zaXplICovCgkJLmV2ZW50X2lkICA9IHsKCQkJLmhlYWRlciA9IHsKCQkJCS50eXBlID0gUEVSRl9SRUNPUkRfQ09NTSwKCQkJCS5taXNjID0gMCwKCQkJCS8qIC5zaXplICovCgkJCX0sCgkJCS8qIC5waWQgKi8KCQkJLyogLnRpZCAqLwoJCX0sCgl9OwoKCXBlcmZfZXZlbnRfY29tbV9ldmVudCgmY29tbV9ldmVudCk7Cn0KCi8qCiAqIG1tYXAgdHJhY2tpbmcKICovCgpzdHJ1Y3QgcGVyZl9tbWFwX2V2ZW50IHsKCXN0cnVjdCB2bV9hcmVhX3N0cnVjdAkqdm1hOwoKCWNvbnN0IGNoYXIJCSpmaWxlX25hbWU7CglpbnQJCQlmaWxlX3NpemU7CgoJc3RydWN0IHsKCQlzdHJ1Y3QgcGVyZl9ldmVudF9oZWFkZXIJaGVhZGVyOwoKCQl1MzIJCQkJcGlkOwoJCXUzMgkJCQl0aWQ7CgkJdTY0CQkJCXN0YXJ0OwoJCXU2NAkJCQlsZW47CgkJdTY0CQkJCXBnb2ZmOwoJfSBldmVudF9pZDsKfTsKCnN0YXRpYyB2b2lkIHBlcmZfZXZlbnRfbW1hcF9vdXRwdXQoc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50LAoJCQkJICAgICBzdHJ1Y3QgcGVyZl9tbWFwX2V2ZW50ICptbWFwX2V2ZW50KQp7CglzdHJ1Y3QgcGVyZl9vdXRwdXRfaGFuZGxlIGhhbmRsZTsKCWludCBzaXplID0gbW1hcF9ldmVudC0+ZXZlbnRfaWQuaGVhZGVyLnNpemU7CglpbnQgcmV0ID0gcGVyZl9vdXRwdXRfYmVnaW4oJmhhbmRsZSwgZXZlbnQsIHNpemUsIDAsIDApOwoKCWlmIChyZXQpCgkJcmV0dXJuOwoKCW1tYXBfZXZlbnQtPmV2ZW50X2lkLnBpZCA9IHBlcmZfZXZlbnRfcGlkKGV2ZW50LCBjdXJyZW50KTsKCW1tYXBfZXZlbnQtPmV2ZW50X2lkLnRpZCA9IHBlcmZfZXZlbnRfdGlkKGV2ZW50LCBjdXJyZW50KTsKCglwZXJmX291dHB1dF9wdXQoJmhhbmRsZSwgbW1hcF9ldmVudC0+ZXZlbnRfaWQpOwoJcGVyZl9vdXRwdXRfY29weSgmaGFuZGxlLCBtbWFwX2V2ZW50LT5maWxlX25hbWUsCgkJCQkgICBtbWFwX2V2ZW50LT5maWxlX3NpemUpOwoJcGVyZl9vdXRwdXRfZW5kKCZoYW5kbGUpOwp9CgpzdGF0aWMgaW50IHBlcmZfZXZlbnRfbW1hcF9tYXRjaChzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQsCgkJCQkgICBzdHJ1Y3QgcGVyZl9tbWFwX2V2ZW50ICptbWFwX2V2ZW50KQp7CglpZiAoZXZlbnQtPmF0dHIubW1hcCkKCQlyZXR1cm4gMTsKCglyZXR1cm4gMDsKfQoKc3RhdGljIHZvaWQgcGVyZl9ldmVudF9tbWFwX2N0eChzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0ICpjdHgsCgkJCQkgIHN0cnVjdCBwZXJmX21tYXBfZXZlbnQgKm1tYXBfZXZlbnQpCnsKCXN0cnVjdCBwZXJmX2V2ZW50ICpldmVudDsKCglpZiAoc3lzdGVtX3N0YXRlICE9IFNZU1RFTV9SVU5OSU5HIHx8IGxpc3RfZW1wdHkoJmN0eC0+ZXZlbnRfbGlzdCkpCgkJcmV0dXJuOwoKCXJjdV9yZWFkX2xvY2soKTsKCWxpc3RfZm9yX2VhY2hfZW50cnlfcmN1KGV2ZW50LCAmY3R4LT5ldmVudF9saXN0LCBldmVudF9lbnRyeSkgewoJCWlmIChwZXJmX2V2ZW50X21tYXBfbWF0Y2goZXZlbnQsIG1tYXBfZXZlbnQpKQoJCQlwZXJmX2V2ZW50X21tYXBfb3V0cHV0KGV2ZW50LCBtbWFwX2V2ZW50KTsKCX0KCXJjdV9yZWFkX3VubG9jaygpOwp9CgpzdGF0aWMgdm9pZCBwZXJmX2V2ZW50X21tYXBfZXZlbnQoc3RydWN0IHBlcmZfbW1hcF9ldmVudCAqbW1hcF9ldmVudCkKewoJc3RydWN0IHBlcmZfY3B1X2NvbnRleHQgKmNwdWN0eDsKCXN0cnVjdCBwZXJmX2V2ZW50X2NvbnRleHQgKmN0eDsKCXN0cnVjdCB2bV9hcmVhX3N0cnVjdCAqdm1hID0gbW1hcF9ldmVudC0+dm1hOwoJc3RydWN0IGZpbGUgKmZpbGUgPSB2bWEtPnZtX2ZpbGU7Cgl1bnNpZ25lZCBpbnQgc2l6ZTsKCWNoYXIgdG1wWzE2XTsKCWNoYXIgKmJ1ZiA9IE5VTEw7Cgljb25zdCBjaGFyICpuYW1lOwoKCW1lbXNldCh0bXAsIDAsIHNpemVvZih0bXApKTsKCglpZiAoZmlsZSkgewoJCS8qCgkJICogZF9wYXRoIHdvcmtzIGZyb20gdGhlIGVuZCBvZiB0aGUgYnVmZmVyIGJhY2t3YXJkcywgc28gd2UKCQkgKiBuZWVkIHRvIGFkZCBlbm91Z2ggemVybyBieXRlcyBhZnRlciB0aGUgc3RyaW5nIHRvIGhhbmRsZQoJCSAqIHRoZSA2NGJpdCBhbGlnbm1lbnQgd2UgZG8gbGF0ZXIuCgkJICovCgkJYnVmID0ga3phbGxvYyhQQVRIX01BWCArIHNpemVvZih1NjQpLCBHRlBfS0VSTkVMKTsKCQlpZiAoIWJ1ZikgewoJCQluYW1lID0gc3RybmNweSh0bXAsICIvL2Vub21lbSIsIHNpemVvZih0bXApKTsKCQkJZ290byBnb3RfbmFtZTsKCQl9CgkJbmFtZSA9IGRfcGF0aCgmZmlsZS0+Zl9wYXRoLCBidWYsIFBBVEhfTUFYKTsKCQlpZiAoSVNfRVJSKG5hbWUpKSB7CgkJCW5hbWUgPSBzdHJuY3B5KHRtcCwgIi8vdG9vbG9uZyIsIHNpemVvZih0bXApKTsKCQkJZ290byBnb3RfbmFtZTsKCQl9Cgl9IGVsc2UgewoJCWlmIChhcmNoX3ZtYV9uYW1lKG1tYXBfZXZlbnQtPnZtYSkpIHsKCQkJbmFtZSA9IHN0cm5jcHkodG1wLCBhcmNoX3ZtYV9uYW1lKG1tYXBfZXZlbnQtPnZtYSksCgkJCQkgICAgICAgc2l6ZW9mKHRtcCkpOwoJCQlnb3RvIGdvdF9uYW1lOwoJCX0KCgkJaWYgKCF2bWEtPnZtX21tKSB7CgkJCW5hbWUgPSBzdHJuY3B5KHRtcCwgIlt2ZHNvXSIsIHNpemVvZih0bXApKTsKCQkJZ290byBnb3RfbmFtZTsKCQl9CgoJCW5hbWUgPSBzdHJuY3B5KHRtcCwgIi8vYW5vbiIsIHNpemVvZih0bXApKTsKCQlnb3RvIGdvdF9uYW1lOwoJfQoKZ290X25hbWU6CglzaXplID0gQUxJR04oc3RybGVuKG5hbWUpKzEsIHNpemVvZih1NjQpKTsKCgltbWFwX2V2ZW50LT5maWxlX25hbWUgPSBuYW1lOwoJbW1hcF9ldmVudC0+ZmlsZV9zaXplID0gc2l6ZTsKCgltbWFwX2V2ZW50LT5ldmVudF9pZC5oZWFkZXIuc2l6ZSA9IHNpemVvZihtbWFwX2V2ZW50LT5ldmVudF9pZCkgKyBzaXplOwoKCWNwdWN0eCA9ICZnZXRfY3B1X3ZhcihwZXJmX2NwdV9jb250ZXh0KTsKCXBlcmZfZXZlbnRfbW1hcF9jdHgoJmNwdWN0eC0+Y3R4LCBtbWFwX2V2ZW50KTsKCXB1dF9jcHVfdmFyKHBlcmZfY3B1X2NvbnRleHQpOwoKCXJjdV9yZWFkX2xvY2soKTsKCS8qCgkgKiBkb2Vzbid0IHJlYWxseSBtYXR0ZXIgd2hpY2ggb2YgdGhlIGNoaWxkIGNvbnRleHRzIHRoZQoJICogZXZlbnRzIGVuZHMgdXAgaW4uCgkgKi8KCWN0eCA9IHJjdV9kZXJlZmVyZW5jZShjdXJyZW50LT5wZXJmX2V2ZW50X2N0eHApOwoJaWYgKGN0eCkKCQlwZXJmX2V2ZW50X21tYXBfY3R4KGN0eCwgbW1hcF9ldmVudCk7CglyY3VfcmVhZF91bmxvY2soKTsKCglrZnJlZShidWYpOwp9Cgp2b2lkIF9fcGVyZl9ldmVudF9tbWFwKHN0cnVjdCB2bV9hcmVhX3N0cnVjdCAqdm1hKQp7CglzdHJ1Y3QgcGVyZl9tbWFwX2V2ZW50IG1tYXBfZXZlbnQ7CgoJaWYgKCFhdG9taWNfcmVhZCgmbnJfbW1hcF9ldmVudHMpKQoJCXJldHVybjsKCgltbWFwX2V2ZW50ID0gKHN0cnVjdCBwZXJmX21tYXBfZXZlbnQpewoJCS52bWEJPSB2bWEsCgkJLyogLmZpbGVfbmFtZSAqLwoJCS8qIC5maWxlX3NpemUgKi8KCQkuZXZlbnRfaWQgID0gewoJCQkuaGVhZGVyID0gewoJCQkJLnR5cGUgPSBQRVJGX1JFQ09SRF9NTUFQLAoJCQkJLm1pc2MgPSAwLAoJCQkJLyogLnNpemUgKi8KCQkJfSwKCQkJLyogLnBpZCAqLwoJCQkvKiAudGlkICovCgkJCS5zdGFydCAgPSB2bWEtPnZtX3N0YXJ0LAoJCQkubGVuICAgID0gdm1hLT52bV9lbmQgLSB2bWEtPnZtX3N0YXJ0LAoJCQkucGdvZmYgID0gdm1hLT52bV9wZ29mZiwKCQl9LAoJfTsKCglwZXJmX2V2ZW50X21tYXBfZXZlbnQoJm1tYXBfZXZlbnQpOwp9CgovKgogKiBJUlEgdGhyb3R0bGUgbG9nZ2luZwogKi8KCnN0YXRpYyB2b2lkIHBlcmZfbG9nX3Rocm90dGxlKHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCwgaW50IGVuYWJsZSkKewoJc3RydWN0IHBlcmZfb3V0cHV0X2hhbmRsZSBoYW5kbGU7CglpbnQgcmV0OwoKCXN0cnVjdCB7CgkJc3RydWN0IHBlcmZfZXZlbnRfaGVhZGVyCWhlYWRlcjsKCQl1NjQJCQkJdGltZTsKCQl1NjQJCQkJaWQ7CgkJdTY0CQkJCXN0cmVhbV9pZDsKCX0gdGhyb3R0bGVfZXZlbnQgPSB7CgkJLmhlYWRlciA9IHsKCQkJLnR5cGUgPSBQRVJGX1JFQ09SRF9USFJPVFRMRSwKCQkJLm1pc2MgPSAwLAoJCQkuc2l6ZSA9IHNpemVvZih0aHJvdHRsZV9ldmVudCksCgkJfSwKCQkudGltZQkJPSBwZXJmX2Nsb2NrKCksCgkJLmlkCQk9IHByaW1hcnlfZXZlbnRfaWQoZXZlbnQpLAoJCS5zdHJlYW1faWQJPSBldmVudC0+aWQsCgl9OwoKCWlmIChlbmFibGUpCgkJdGhyb3R0bGVfZXZlbnQuaGVhZGVyLnR5cGUgPSBQRVJGX1JFQ09SRF9VTlRIUk9UVExFOwoKCXJldCA9IHBlcmZfb3V0cHV0X2JlZ2luKCZoYW5kbGUsIGV2ZW50LCBzaXplb2YodGhyb3R0bGVfZXZlbnQpLCAxLCAwKTsKCWlmIChyZXQpCgkJcmV0dXJuOwoKCXBlcmZfb3V0cHV0X3B1dCgmaGFuZGxlLCB0aHJvdHRsZV9ldmVudCk7CglwZXJmX291dHB1dF9lbmQoJmhhbmRsZSk7Cn0KCi8qCiAqIEdlbmVyaWMgZXZlbnQgb3ZlcmZsb3cgaGFuZGxpbmcsIHNhbXBsaW5nLgogKi8KCnN0YXRpYyBpbnQgX19wZXJmX2V2ZW50X292ZXJmbG93KHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCwgaW50IG5taSwKCQkJCSAgIGludCB0aHJvdHRsZSwgc3RydWN0IHBlcmZfc2FtcGxlX2RhdGEgKmRhdGEsCgkJCQkgICBzdHJ1Y3QgcHRfcmVncyAqcmVncykKewoJaW50IGV2ZW50cyA9IGF0b21pY19yZWFkKCZldmVudC0+ZXZlbnRfbGltaXQpOwoJc3RydWN0IGh3X3BlcmZfZXZlbnQgKmh3YyA9ICZldmVudC0+aHc7CglpbnQgcmV0ID0gMDsKCgl0aHJvdHRsZSA9ICh0aHJvdHRsZSAmJiBldmVudC0+cG11LT51bnRocm90dGxlICE9IE5VTEwpOwoKCWlmICghdGhyb3R0bGUpIHsKCQlod2MtPmludGVycnVwdHMrKzsKCX0gZWxzZSB7CgkJaWYgKGh3Yy0+aW50ZXJydXB0cyAhPSBNQVhfSU5URVJSVVBUUykgewoJCQlod2MtPmludGVycnVwdHMrKzsKCQkJaWYgKEhaICogaHdjLT5pbnRlcnJ1cHRzID4KCQkJCQkodTY0KXN5c2N0bF9wZXJmX2V2ZW50X3NhbXBsZV9yYXRlKSB7CgkJCQlod2MtPmludGVycnVwdHMgPSBNQVhfSU5URVJSVVBUUzsKCQkJCXBlcmZfbG9nX3Rocm90dGxlKGV2ZW50LCAwKTsKCQkJCXJldCA9IDE7CgkJCX0KCQl9IGVsc2UgewoJCQkvKgoJCQkgKiBLZWVwIHJlLWRpc2FibGluZyBldmVudHMgZXZlbiB0aG91Z2ggb24gdGhlIHByZXZpb3VzCgkJCSAqIHBhc3Mgd2UgZGlzYWJsZWQgaXQgLSBqdXN0IGluIGNhc2Ugd2UgcmFjZWQgd2l0aCBhCgkJCSAqIHNjaGVkLWluIGFuZCB0aGUgZXZlbnQgZ290IGVuYWJsZWQgYWdhaW46CgkJCSAqLwoJCQlyZXQgPSAxOwoJCX0KCX0KCglpZiAoZXZlbnQtPmF0dHIuZnJlcSkgewoJCXU2NCBub3cgPSBwZXJmX2Nsb2NrKCk7CgkJczY0IGRlbHRhID0gbm93IC0gaHdjLT5mcmVxX3N0YW1wOwoKCQlod2MtPmZyZXFfc3RhbXAgPSBub3c7CgoJCWlmIChkZWx0YSA+IDAgJiYgZGVsdGEgPCBUSUNLX05TRUMpCgkJCXBlcmZfYWRqdXN0X3BlcmlvZChldmVudCwgTlNFQ19QRVJfU0VDIC8gKGludClkZWx0YSk7Cgl9CgoJLyoKCSAqIFhYWCBldmVudF9saW1pdCBtaWdodCBub3QgcXVpdGUgd29yayBhcyBleHBlY3RlZCBvbiBpbmhlcml0ZWQKCSAqIGV2ZW50cwoJICovCgoJZXZlbnQtPnBlbmRpbmdfa2lsbCA9IFBPTExfSU47CglpZiAoZXZlbnRzICYmIGF0b21pY19kZWNfYW5kX3Rlc3QoJmV2ZW50LT5ldmVudF9saW1pdCkpIHsKCQlyZXQgPSAxOwoJCWV2ZW50LT5wZW5kaW5nX2tpbGwgPSBQT0xMX0hVUDsKCQlpZiAobm1pKSB7CgkJCWV2ZW50LT5wZW5kaW5nX2Rpc2FibGUgPSAxOwoJCQlwZXJmX3BlbmRpbmdfcXVldWUoJmV2ZW50LT5wZW5kaW5nLAoJCQkJCSAgIHBlcmZfcGVuZGluZ19ldmVudCk7CgkJfSBlbHNlCgkJCXBlcmZfZXZlbnRfZGlzYWJsZShldmVudCk7Cgl9CgoJcGVyZl9ldmVudF9vdXRwdXQoZXZlbnQsIG5taSwgZGF0YSwgcmVncyk7CglyZXR1cm4gcmV0Owp9CgppbnQgcGVyZl9ldmVudF9vdmVyZmxvdyhzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQsIGludCBubWksCgkJCSAgc3RydWN0IHBlcmZfc2FtcGxlX2RhdGEgKmRhdGEsCgkJCSAgc3RydWN0IHB0X3JlZ3MgKnJlZ3MpCnsKCXJldHVybiBfX3BlcmZfZXZlbnRfb3ZlcmZsb3coZXZlbnQsIG5taSwgMSwgZGF0YSwgcmVncyk7Cn0KCi8qCiAqIEdlbmVyaWMgc29mdHdhcmUgZXZlbnQgaW5mcmFzdHJ1Y3R1cmUKICovCgovKgogKiBXZSBkaXJlY3RseSBpbmNyZW1lbnQgZXZlbnQtPmNvdW50IGFuZCBrZWVwIGEgc2Vjb25kIHZhbHVlIGluCiAqIGV2ZW50LT5ody5wZXJpb2RfbGVmdCB0byBjb3VudCBpbnRlcnZhbHMuIFRoaXMgcGVyaW9kIGV2ZW50CiAqIGlzIGtlcHQgaW4gdGhlIHJhbmdlIFstc2FtcGxlX3BlcmlvZCwgMF0gc28gdGhhdCB3ZSBjYW4gdXNlIHRoZQogKiBzaWduIGFzIHRyaWdnZXIuCiAqLwoKc3RhdGljIHU2NCBwZXJmX3N3ZXZlbnRfc2V0X3BlcmlvZChzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQpCnsKCXN0cnVjdCBod19wZXJmX2V2ZW50ICpod2MgPSAmZXZlbnQtPmh3OwoJdTY0IHBlcmlvZCA9IGh3Yy0+bGFzdF9wZXJpb2Q7Cgl1NjQgbnIsIG9mZnNldDsKCXM2NCBvbGQsIHZhbDsKCglod2MtPmxhc3RfcGVyaW9kID0gaHdjLT5zYW1wbGVfcGVyaW9kOwoKYWdhaW46CglvbGQgPSB2YWwgPSBhdG9taWM2NF9yZWFkKCZod2MtPnBlcmlvZF9sZWZ0KTsKCWlmICh2YWwgPCAwKQoJCXJldHVybiAwOwoKCW5yID0gZGl2NjRfdTY0KHBlcmlvZCArIHZhbCwgcGVyaW9kKTsKCW9mZnNldCA9IG5yICogcGVyaW9kOwoJdmFsIC09IG9mZnNldDsKCWlmIChhdG9taWM2NF9jbXB4Y2hnKCZod2MtPnBlcmlvZF9sZWZ0LCBvbGQsIHZhbCkgIT0gb2xkKQoJCWdvdG8gYWdhaW47CgoJcmV0dXJuIG5yOwp9CgpzdGF0aWMgdm9pZCBwZXJmX3N3ZXZlbnRfb3ZlcmZsb3coc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50LAoJCQkJICAgIGludCBubWksIHN0cnVjdCBwZXJmX3NhbXBsZV9kYXRhICpkYXRhLAoJCQkJICAgIHN0cnVjdCBwdF9yZWdzICpyZWdzKQp7CglzdHJ1Y3QgaHdfcGVyZl9ldmVudCAqaHdjID0gJmV2ZW50LT5odzsKCWludCB0aHJvdHRsZSA9IDA7Cgl1NjQgb3ZlcmZsb3c7CgoJZGF0YS0+cGVyaW9kID0gZXZlbnQtPmh3Lmxhc3RfcGVyaW9kOwoJb3ZlcmZsb3cgPSBwZXJmX3N3ZXZlbnRfc2V0X3BlcmlvZChldmVudCk7CgoJaWYgKGh3Yy0+aW50ZXJydXB0cyA9PSBNQVhfSU5URVJSVVBUUykKCQlyZXR1cm47CgoJZm9yICg7IG92ZXJmbG93OyBvdmVyZmxvdy0tKSB7CgkJaWYgKF9fcGVyZl9ldmVudF9vdmVyZmxvdyhldmVudCwgbm1pLCB0aHJvdHRsZSwKCQkJCQkgICAgZGF0YSwgcmVncykpIHsKCQkJLyoKCQkJICogV2UgaW5oaWJpdCB0aGUgb3ZlcmZsb3cgZnJvbSBoYXBwZW5pbmcgd2hlbgoJCQkgKiBod2MtPmludGVycnVwdHMgPT0gTUFYX0lOVEVSUlVQVFMuCgkJCSAqLwoJCQlicmVhazsKCQl9CgkJdGhyb3R0bGUgPSAxOwoJfQp9CgpzdGF0aWMgdm9pZCBwZXJmX3N3ZXZlbnRfdW50aHJvdHRsZShzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQpCnsKCS8qCgkgKiBOb3RoaW5nIHRvIGRvLCB3ZSBhbHJlYWR5IHJlc2V0IGh3Yy0+aW50ZXJydXB0cy4KCSAqLwp9CgpzdGF0aWMgdm9pZCBwZXJmX3N3ZXZlbnRfYWRkKHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCwgdTY0IG5yLAoJCQkgICAgICAgaW50IG5taSwgc3RydWN0IHBlcmZfc2FtcGxlX2RhdGEgKmRhdGEsCgkJCSAgICAgICBzdHJ1Y3QgcHRfcmVncyAqcmVncykKewoJc3RydWN0IGh3X3BlcmZfZXZlbnQgKmh3YyA9ICZldmVudC0+aHc7CgoJYXRvbWljNjRfYWRkKG5yLCAmZXZlbnQtPmNvdW50KTsKCglpZiAoIWh3Yy0+c2FtcGxlX3BlcmlvZCkKCQlyZXR1cm47CgoJaWYgKCFyZWdzKQoJCXJldHVybjsKCglpZiAoIWF0b21pYzY0X2FkZF9uZWdhdGl2ZShuciwgJmh3Yy0+cGVyaW9kX2xlZnQpKQoJCXBlcmZfc3dldmVudF9vdmVyZmxvdyhldmVudCwgbm1pLCBkYXRhLCByZWdzKTsKfQoKc3RhdGljIGludCBwZXJmX3N3ZXZlbnRfaXNfY291bnRpbmcoc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50KQp7CgkvKgoJICogVGhlIGV2ZW50IGlzIGFjdGl2ZSwgd2UncmUgZ29vZCEKCSAqLwoJaWYgKGV2ZW50LT5zdGF0ZSA9PSBQRVJGX0VWRU5UX1NUQVRFX0FDVElWRSkKCQlyZXR1cm4gMTsKCgkvKgoJICogVGhlIGV2ZW50IGlzIG9mZi9lcnJvciwgbm90IGNvdW50aW5nLgoJICovCglpZiAoZXZlbnQtPnN0YXRlICE9IFBFUkZfRVZFTlRfU1RBVEVfSU5BQ1RJVkUpCgkJcmV0dXJuIDA7CgoJLyoKCSAqIFRoZSBldmVudCBpcyBpbmFjdGl2ZSwgaWYgdGhlIGNvbnRleHQgaXMgYWN0aXZlCgkgKiB3ZSdyZSBwYXJ0IG9mIGEgZ3JvdXAgdGhhdCBkaWRuJ3QgbWFrZSBpdCBvbiB0aGUgJ3BtdScsCgkgKiBub3QgY291bnRpbmcuCgkgKi8KCWlmIChldmVudC0+Y3R4LT5pc19hY3RpdmUpCgkJcmV0dXJuIDA7CgoJLyoKCSAqIFdlJ3JlIGluYWN0aXZlIGFuZCB0aGUgY29udGV4dCBpcyB0b28sIHRoaXMgbWVhbnMgdGhlCgkgKiB0YXNrIGlzIHNjaGVkdWxlZCBvdXQsIHdlJ3JlIGNvdW50aW5nIGV2ZW50cyB0aGF0IGhhcHBlbgoJICogdG8gdXMsIGxpa2UgbWlncmF0aW9uIGV2ZW50cy4KCSAqLwoJcmV0dXJuIDE7Cn0KCnN0YXRpYyBpbnQgcGVyZl9zd2V2ZW50X21hdGNoKHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCwKCQkJCWVudW0gcGVyZl90eXBlX2lkIHR5cGUsCgkJCQl1MzIgZXZlbnRfaWQsIHN0cnVjdCBwdF9yZWdzICpyZWdzKQp7CglpZiAoIXBlcmZfc3dldmVudF9pc19jb3VudGluZyhldmVudCkpCgkJcmV0dXJuIDA7CgoJaWYgKGV2ZW50LT5hdHRyLnR5cGUgIT0gdHlwZSkKCQlyZXR1cm4gMDsKCWlmIChldmVudC0+YXR0ci5jb25maWcgIT0gZXZlbnRfaWQpCgkJcmV0dXJuIDA7CgoJaWYgKHJlZ3MpIHsKCQlpZiAoZXZlbnQtPmF0dHIuZXhjbHVkZV91c2VyICYmIHVzZXJfbW9kZShyZWdzKSkKCQkJcmV0dXJuIDA7CgoJCWlmIChldmVudC0+YXR0ci5leGNsdWRlX2tlcm5lbCAmJiAhdXNlcl9tb2RlKHJlZ3MpKQoJCQlyZXR1cm4gMDsKCX0KCglyZXR1cm4gMTsKfQoKc3RhdGljIHZvaWQgcGVyZl9zd2V2ZW50X2N0eF9ldmVudChzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0ICpjdHgsCgkJCQkgICAgIGVudW0gcGVyZl90eXBlX2lkIHR5cGUsCgkJCQkgICAgIHUzMiBldmVudF9pZCwgdTY0IG5yLCBpbnQgbm1pLAoJCQkJICAgICBzdHJ1Y3QgcGVyZl9zYW1wbGVfZGF0YSAqZGF0YSwKCQkJCSAgICAgc3RydWN0IHB0X3JlZ3MgKnJlZ3MpCnsKCXN0cnVjdCBwZXJmX2V2ZW50ICpldmVudDsKCglpZiAoc3lzdGVtX3N0YXRlICE9IFNZU1RFTV9SVU5OSU5HIHx8IGxpc3RfZW1wdHkoJmN0eC0+ZXZlbnRfbGlzdCkpCgkJcmV0dXJuOwoKCXJjdV9yZWFkX2xvY2soKTsKCWxpc3RfZm9yX2VhY2hfZW50cnlfcmN1KGV2ZW50LCAmY3R4LT5ldmVudF9saXN0LCBldmVudF9lbnRyeSkgewoJCWlmIChwZXJmX3N3ZXZlbnRfbWF0Y2goZXZlbnQsIHR5cGUsIGV2ZW50X2lkLCByZWdzKSkKCQkJcGVyZl9zd2V2ZW50X2FkZChldmVudCwgbnIsIG5taSwgZGF0YSwgcmVncyk7Cgl9CglyY3VfcmVhZF91bmxvY2soKTsKfQoKc3RhdGljIGludCAqcGVyZl9zd2V2ZW50X3JlY3Vyc2lvbl9jb250ZXh0KHN0cnVjdCBwZXJmX2NwdV9jb250ZXh0ICpjcHVjdHgpCnsKCWlmIChpbl9ubWkoKSkKCQlyZXR1cm4gJmNwdWN0eC0+cmVjdXJzaW9uWzNdOwoKCWlmIChpbl9pcnEoKSkKCQlyZXR1cm4gJmNwdWN0eC0+cmVjdXJzaW9uWzJdOwoKCWlmIChpbl9zb2Z0aXJxKCkpCgkJcmV0dXJuICZjcHVjdHgtPnJlY3Vyc2lvblsxXTsKCglyZXR1cm4gJmNwdWN0eC0+cmVjdXJzaW9uWzBdOwp9CgpzdGF0aWMgdm9pZCBkb19wZXJmX3N3X2V2ZW50KGVudW0gcGVyZl90eXBlX2lkIHR5cGUsIHUzMiBldmVudF9pZCwKCQkJCSAgICB1NjQgbnIsIGludCBubWksCgkJCQkgICAgc3RydWN0IHBlcmZfc2FtcGxlX2RhdGEgKmRhdGEsCgkJCQkgICAgc3RydWN0IHB0X3JlZ3MgKnJlZ3MpCnsKCXN0cnVjdCBwZXJmX2NwdV9jb250ZXh0ICpjcHVjdHggPSAmZ2V0X2NwdV92YXIocGVyZl9jcHVfY29udGV4dCk7CglpbnQgKnJlY3Vyc2lvbiA9IHBlcmZfc3dldmVudF9yZWN1cnNpb25fY29udGV4dChjcHVjdHgpOwoJc3RydWN0IHBlcmZfZXZlbnRfY29udGV4dCAqY3R4OwoKCWlmICgqcmVjdXJzaW9uKQoJCWdvdG8gb3V0OwoKCSgqcmVjdXJzaW9uKSsrOwoJYmFycmllcigpOwoKCXBlcmZfc3dldmVudF9jdHhfZXZlbnQoJmNwdWN0eC0+Y3R4LCB0eXBlLCBldmVudF9pZCwKCQkJCSBuciwgbm1pLCBkYXRhLCByZWdzKTsKCXJjdV9yZWFkX2xvY2soKTsKCS8qCgkgKiBkb2Vzbid0IHJlYWxseSBtYXR0ZXIgd2hpY2ggb2YgdGhlIGNoaWxkIGNvbnRleHRzIHRoZQoJICogZXZlbnRzIGVuZHMgdXAgaW4uCgkgKi8KCWN0eCA9IHJjdV9kZXJlZmVyZW5jZShjdXJyZW50LT5wZXJmX2V2ZW50X2N0eHApOwoJaWYgKGN0eCkKCQlwZXJmX3N3ZXZlbnRfY3R4X2V2ZW50KGN0eCwgdHlwZSwgZXZlbnRfaWQsIG5yLCBubWksIGRhdGEsIHJlZ3MpOwoJcmN1X3JlYWRfdW5sb2NrKCk7CgoJYmFycmllcigpOwoJKCpyZWN1cnNpb24pLS07CgpvdXQ6CglwdXRfY3B1X3ZhcihwZXJmX2NwdV9jb250ZXh0KTsKfQoKdm9pZCBfX3BlcmZfc3dfZXZlbnQodTMyIGV2ZW50X2lkLCB1NjQgbnIsIGludCBubWksCgkJCSAgICBzdHJ1Y3QgcHRfcmVncyAqcmVncywgdTY0IGFkZHIpCnsKCXN0cnVjdCBwZXJmX3NhbXBsZV9kYXRhIGRhdGEgPSB7CgkJLmFkZHIgPSBhZGRyLAoJfTsKCglkb19wZXJmX3N3X2V2ZW50KFBFUkZfVFlQRV9TT0ZUV0FSRSwgZXZlbnRfaWQsIG5yLCBubWksCgkJCQkmZGF0YSwgcmVncyk7Cn0KCnN0YXRpYyB2b2lkIHBlcmZfc3dldmVudF9yZWFkKHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCkKewp9CgpzdGF0aWMgaW50IHBlcmZfc3dldmVudF9lbmFibGUoc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50KQp7CglzdHJ1Y3QgaHdfcGVyZl9ldmVudCAqaHdjID0gJmV2ZW50LT5odzsKCglpZiAoaHdjLT5zYW1wbGVfcGVyaW9kKSB7CgkJaHdjLT5sYXN0X3BlcmlvZCA9IGh3Yy0+c2FtcGxlX3BlcmlvZDsKCQlwZXJmX3N3ZXZlbnRfc2V0X3BlcmlvZChldmVudCk7Cgl9CglyZXR1cm4gMDsKfQoKc3RhdGljIHZvaWQgcGVyZl9zd2V2ZW50X2Rpc2FibGUoc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50KQp7Cn0KCnN0YXRpYyBjb25zdCBzdHJ1Y3QgcG11IHBlcmZfb3BzX2dlbmVyaWMgPSB7CgkuZW5hYmxlCQk9IHBlcmZfc3dldmVudF9lbmFibGUsCgkuZGlzYWJsZQk9IHBlcmZfc3dldmVudF9kaXNhYmxlLAoJLnJlYWQJCT0gcGVyZl9zd2V2ZW50X3JlYWQsCgkudW50aHJvdHRsZQk9IHBlcmZfc3dldmVudF91bnRocm90dGxlLAp9OwoKLyoKICogaHJ0aW1lciBiYXNlZCBzd2V2ZW50IGNhbGxiYWNrCiAqLwoKc3RhdGljIGVudW0gaHJ0aW1lcl9yZXN0YXJ0IHBlcmZfc3dldmVudF9ocnRpbWVyKHN0cnVjdCBocnRpbWVyICpocnRpbWVyKQp7CgllbnVtIGhydGltZXJfcmVzdGFydCByZXQgPSBIUlRJTUVSX1JFU1RBUlQ7CglzdHJ1Y3QgcGVyZl9zYW1wbGVfZGF0YSBkYXRhOwoJc3RydWN0IHB0X3JlZ3MgKnJlZ3M7CglzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQ7Cgl1NjQgcGVyaW9kOwoKCWV2ZW50CT0gY29udGFpbmVyX29mKGhydGltZXIsIHN0cnVjdCBwZXJmX2V2ZW50LCBody5ocnRpbWVyKTsKCWV2ZW50LT5wbXUtPnJlYWQoZXZlbnQpOwoKCWRhdGEuYWRkciA9IDA7CglyZWdzID0gZ2V0X2lycV9yZWdzKCk7CgkvKgoJICogSW4gY2FzZSB3ZSBleGNsdWRlIGtlcm5lbCBJUHMgb3IgYXJlIHNvbWVob3cgbm90IGluIGludGVycnVwdAoJICogY29udGV4dCwgcHJvdmlkZSB0aGUgbmV4dCBiZXN0IHRoaW5nLCB0aGUgdXNlciBJUC4KCSAqLwoJaWYgKChldmVudC0+YXR0ci5leGNsdWRlX2tlcm5lbCB8fCAhcmVncykgJiYKCQkJIWV2ZW50LT5hdHRyLmV4Y2x1ZGVfdXNlcikKCQlyZWdzID0gdGFza19wdF9yZWdzKGN1cnJlbnQpOwoKCWlmIChyZWdzKSB7CgkJaWYgKHBlcmZfZXZlbnRfb3ZlcmZsb3coZXZlbnQsIDAsICZkYXRhLCByZWdzKSkKCQkJcmV0ID0gSFJUSU1FUl9OT1JFU1RBUlQ7Cgl9CgoJcGVyaW9kID0gbWF4X3QodTY0LCAxMDAwMCwgZXZlbnQtPmh3LnNhbXBsZV9wZXJpb2QpOwoJaHJ0aW1lcl9mb3J3YXJkX25vdyhocnRpbWVyLCBuc190b19rdGltZShwZXJpb2QpKTsKCglyZXR1cm4gcmV0Owp9CgovKgogKiBTb2Z0d2FyZSBldmVudDogY3B1IHdhbGwgdGltZSBjbG9jawogKi8KCnN0YXRpYyB2b2lkIGNwdV9jbG9ja19wZXJmX2V2ZW50X3VwZGF0ZShzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQpCnsKCWludCBjcHUgPSByYXdfc21wX3Byb2Nlc3Nvcl9pZCgpOwoJczY0IHByZXY7Cgl1NjQgbm93OwoKCW5vdyA9IGNwdV9jbG9jayhjcHUpOwoJcHJldiA9IGF0b21pYzY0X3JlYWQoJmV2ZW50LT5ody5wcmV2X2NvdW50KTsKCWF0b21pYzY0X3NldCgmZXZlbnQtPmh3LnByZXZfY291bnQsIG5vdyk7CglhdG9taWM2NF9hZGQobm93IC0gcHJldiwgJmV2ZW50LT5jb3VudCk7Cn0KCnN0YXRpYyBpbnQgY3B1X2Nsb2NrX3BlcmZfZXZlbnRfZW5hYmxlKHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCkKewoJc3RydWN0IGh3X3BlcmZfZXZlbnQgKmh3YyA9ICZldmVudC0+aHc7CglpbnQgY3B1ID0gcmF3X3NtcF9wcm9jZXNzb3JfaWQoKTsKCglhdG9taWM2NF9zZXQoJmh3Yy0+cHJldl9jb3VudCwgY3B1X2Nsb2NrKGNwdSkpOwoJaHJ0aW1lcl9pbml0KCZod2MtPmhydGltZXIsIENMT0NLX01PTk9UT05JQywgSFJUSU1FUl9NT0RFX1JFTCk7Cglod2MtPmhydGltZXIuZnVuY3Rpb24gPSBwZXJmX3N3ZXZlbnRfaHJ0aW1lcjsKCWlmIChod2MtPnNhbXBsZV9wZXJpb2QpIHsKCQl1NjQgcGVyaW9kID0gbWF4X3QodTY0LCAxMDAwMCwgaHdjLT5zYW1wbGVfcGVyaW9kKTsKCQlfX2hydGltZXJfc3RhcnRfcmFuZ2VfbnMoJmh3Yy0+aHJ0aW1lciwKCQkJCW5zX3RvX2t0aW1lKHBlcmlvZCksIDAsCgkJCQlIUlRJTUVSX01PREVfUkVMLCAwKTsKCX0KCglyZXR1cm4gMDsKfQoKc3RhdGljIHZvaWQgY3B1X2Nsb2NrX3BlcmZfZXZlbnRfZGlzYWJsZShzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQpCnsKCWlmIChldmVudC0+aHcuc2FtcGxlX3BlcmlvZCkKCQlocnRpbWVyX2NhbmNlbCgmZXZlbnQtPmh3LmhydGltZXIpOwoJY3B1X2Nsb2NrX3BlcmZfZXZlbnRfdXBkYXRlKGV2ZW50KTsKfQoKc3RhdGljIHZvaWQgY3B1X2Nsb2NrX3BlcmZfZXZlbnRfcmVhZChzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQpCnsKCWNwdV9jbG9ja19wZXJmX2V2ZW50X3VwZGF0ZShldmVudCk7Cn0KCnN0YXRpYyBjb25zdCBzdHJ1Y3QgcG11IHBlcmZfb3BzX2NwdV9jbG9jayA9IHsKCS5lbmFibGUJCT0gY3B1X2Nsb2NrX3BlcmZfZXZlbnRfZW5hYmxlLAoJLmRpc2FibGUJPSBjcHVfY2xvY2tfcGVyZl9ldmVudF9kaXNhYmxlLAoJLnJlYWQJCT0gY3B1X2Nsb2NrX3BlcmZfZXZlbnRfcmVhZCwKfTsKCi8qCiAqIFNvZnR3YXJlIGV2ZW50OiB0YXNrIHRpbWUgY2xvY2sKICovCgpzdGF0aWMgdm9pZCB0YXNrX2Nsb2NrX3BlcmZfZXZlbnRfdXBkYXRlKHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCwgdTY0IG5vdykKewoJdTY0IHByZXY7CglzNjQgZGVsdGE7CgoJcHJldiA9IGF0b21pYzY0X3hjaGcoJmV2ZW50LT5ody5wcmV2X2NvdW50LCBub3cpOwoJZGVsdGEgPSBub3cgLSBwcmV2OwoJYXRvbWljNjRfYWRkKGRlbHRhLCAmZXZlbnQtPmNvdW50KTsKfQoKc3RhdGljIGludCB0YXNrX2Nsb2NrX3BlcmZfZXZlbnRfZW5hYmxlKHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCkKewoJc3RydWN0IGh3X3BlcmZfZXZlbnQgKmh3YyA9ICZldmVudC0+aHc7Cgl1NjQgbm93OwoKCW5vdyA9IGV2ZW50LT5jdHgtPnRpbWU7CgoJYXRvbWljNjRfc2V0KCZod2MtPnByZXZfY291bnQsIG5vdyk7CglocnRpbWVyX2luaXQoJmh3Yy0+aHJ0aW1lciwgQ0xPQ0tfTU9OT1RPTklDLCBIUlRJTUVSX01PREVfUkVMKTsKCWh3Yy0+aHJ0aW1lci5mdW5jdGlvbiA9IHBlcmZfc3dldmVudF9ocnRpbWVyOwoJaWYgKGh3Yy0+c2FtcGxlX3BlcmlvZCkgewoJCXU2NCBwZXJpb2QgPSBtYXhfdCh1NjQsIDEwMDAwLCBod2MtPnNhbXBsZV9wZXJpb2QpOwoJCV9faHJ0aW1lcl9zdGFydF9yYW5nZV9ucygmaHdjLT5ocnRpbWVyLAoJCQkJbnNfdG9fa3RpbWUocGVyaW9kKSwgMCwKCQkJCUhSVElNRVJfTU9ERV9SRUwsIDApOwoJfQoKCXJldHVybiAwOwp9CgpzdGF0aWMgdm9pZCB0YXNrX2Nsb2NrX3BlcmZfZXZlbnRfZGlzYWJsZShzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQpCnsKCWlmIChldmVudC0+aHcuc2FtcGxlX3BlcmlvZCkKCQlocnRpbWVyX2NhbmNlbCgmZXZlbnQtPmh3LmhydGltZXIpOwoJdGFza19jbG9ja19wZXJmX2V2ZW50X3VwZGF0ZShldmVudCwgZXZlbnQtPmN0eC0+dGltZSk7Cgp9CgpzdGF0aWMgdm9pZCB0YXNrX2Nsb2NrX3BlcmZfZXZlbnRfcmVhZChzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQpCnsKCXU2NCB0aW1lOwoKCWlmICghaW5fbm1pKCkpIHsKCQl1cGRhdGVfY29udGV4dF90aW1lKGV2ZW50LT5jdHgpOwoJCXRpbWUgPSBldmVudC0+Y3R4LT50aW1lOwoJfSBlbHNlIHsKCQl1NjQgbm93ID0gcGVyZl9jbG9jaygpOwoJCXU2NCBkZWx0YSA9IG5vdyAtIGV2ZW50LT5jdHgtPnRpbWVzdGFtcDsKCQl0aW1lID0gZXZlbnQtPmN0eC0+dGltZSArIGRlbHRhOwoJfQoKCXRhc2tfY2xvY2tfcGVyZl9ldmVudF91cGRhdGUoZXZlbnQsIHRpbWUpOwp9CgpzdGF0aWMgY29uc3Qgc3RydWN0IHBtdSBwZXJmX29wc190YXNrX2Nsb2NrID0gewoJLmVuYWJsZQkJPSB0YXNrX2Nsb2NrX3BlcmZfZXZlbnRfZW5hYmxlLAoJLmRpc2FibGUJPSB0YXNrX2Nsb2NrX3BlcmZfZXZlbnRfZGlzYWJsZSwKCS5yZWFkCQk9IHRhc2tfY2xvY2tfcGVyZl9ldmVudF9yZWFkLAp9OwoKI2lmZGVmIENPTkZJR19FVkVOVF9QUk9GSUxFCnZvaWQgcGVyZl90cF9ldmVudChpbnQgZXZlbnRfaWQsIHU2NCBhZGRyLCB1NjQgY291bnQsIHZvaWQgKnJlY29yZCwKCQkJICBpbnQgZW50cnlfc2l6ZSkKewoJc3RydWN0IHBlcmZfcmF3X3JlY29yZCByYXcgPSB7CgkJLnNpemUgPSBlbnRyeV9zaXplLAoJCS5kYXRhID0gcmVjb3JkLAoJfTsKCglzdHJ1Y3QgcGVyZl9zYW1wbGVfZGF0YSBkYXRhID0gewoJCS5hZGRyID0gYWRkciwKCQkucmF3ID0gJnJhdywKCX07CgoJc3RydWN0IHB0X3JlZ3MgKnJlZ3MgPSBnZXRfaXJxX3JlZ3MoKTsKCglpZiAoIXJlZ3MpCgkJcmVncyA9IHRhc2tfcHRfcmVncyhjdXJyZW50KTsKCglkb19wZXJmX3N3X2V2ZW50KFBFUkZfVFlQRV9UUkFDRVBPSU5ULCBldmVudF9pZCwgY291bnQsIDEsCgkJCQkmZGF0YSwgcmVncyk7Cn0KRVhQT1JUX1NZTUJPTF9HUEwocGVyZl90cF9ldmVudCk7CgpleHRlcm4gaW50IGZ0cmFjZV9wcm9maWxlX2VuYWJsZShpbnQpOwpleHRlcm4gdm9pZCBmdHJhY2VfcHJvZmlsZV9kaXNhYmxlKGludCk7CgpzdGF0aWMgdm9pZCB0cF9wZXJmX2V2ZW50X2Rlc3Ryb3koc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50KQp7CglmdHJhY2VfcHJvZmlsZV9kaXNhYmxlKGV2ZW50LT5hdHRyLmNvbmZpZyk7Cn0KCnN0YXRpYyBjb25zdCBzdHJ1Y3QgcG11ICp0cF9wZXJmX2V2ZW50X2luaXQoc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50KQp7CgkvKgoJICogUmF3IHRyYWNlcG9pbnQgZGF0YSBpcyBhIHNldmVyZSBkYXRhIGxlYWssIG9ubHkgYWxsb3cgcm9vdCB0bwoJICogaGF2ZSB0aGVzZS4KCSAqLwoJaWYgKChldmVudC0+YXR0ci5zYW1wbGVfdHlwZSAmIFBFUkZfU0FNUExFX1JBVykgJiYKCQkJcGVyZl9wYXJhbm9pZF90cmFjZXBvaW50X3JhdygpICYmCgkJCSFjYXBhYmxlKENBUF9TWVNfQURNSU4pKQoJCXJldHVybiBFUlJfUFRSKC1FUEVSTSk7CgoJaWYgKGZ0cmFjZV9wcm9maWxlX2VuYWJsZShldmVudC0+YXR0ci5jb25maWcpKQoJCXJldHVybiBOVUxMOwoKCWV2ZW50LT5kZXN0cm95ID0gdHBfcGVyZl9ldmVudF9kZXN0cm95OwoKCXJldHVybiAmcGVyZl9vcHNfZ2VuZXJpYzsKfQojZWxzZQpzdGF0aWMgY29uc3Qgc3RydWN0IHBtdSAqdHBfcGVyZl9ldmVudF9pbml0KHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCkKewoJcmV0dXJuIE5VTEw7Cn0KI2VuZGlmCgphdG9taWNfdCBwZXJmX3N3ZXZlbnRfZW5hYmxlZFtQRVJGX0NPVU5UX1NXX01BWF07CgpzdGF0aWMgdm9pZCBzd19wZXJmX2V2ZW50X2Rlc3Ryb3koc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50KQp7Cgl1NjQgZXZlbnRfaWQgPSBldmVudC0+YXR0ci5jb25maWc7CgoJV0FSTl9PTihldmVudC0+cGFyZW50KTsKCglhdG9taWNfZGVjKCZwZXJmX3N3ZXZlbnRfZW5hYmxlZFtldmVudF9pZF0pOwp9CgpzdGF0aWMgY29uc3Qgc3RydWN0IHBtdSAqc3dfcGVyZl9ldmVudF9pbml0KHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCkKewoJY29uc3Qgc3RydWN0IHBtdSAqcG11ID0gTlVMTDsKCXU2NCBldmVudF9pZCA9IGV2ZW50LT5hdHRyLmNvbmZpZzsKCgkvKgoJICogU29mdHdhcmUgZXZlbnRzIChjdXJyZW50bHkpIGNhbid0IGluIGdlbmVyYWwgZGlzdGluZ3Vpc2gKCSAqIGJldHdlZW4gdXNlciwga2VybmVsIGFuZCBoeXBlcnZpc29yIGV2ZW50cy4KCSAqIEhvd2V2ZXIsIGNvbnRleHQgc3dpdGNoZXMgYW5kIGNwdSBtaWdyYXRpb25zIGFyZSBjb25zaWRlcmVkCgkgKiB0byBiZSBrZXJuZWwgZXZlbnRzLCBhbmQgcGFnZSBmYXVsdHMgYXJlIG5ldmVyIGh5cGVydmlzb3IKCSAqIGV2ZW50cy4KCSAqLwoJc3dpdGNoIChldmVudF9pZCkgewoJY2FzZSBQRVJGX0NPVU5UX1NXX0NQVV9DTE9DSzoKCQlwbXUgPSAmcGVyZl9vcHNfY3B1X2Nsb2NrOwoKCQlicmVhazsKCWNhc2UgUEVSRl9DT1VOVF9TV19UQVNLX0NMT0NLOgoJCS8qCgkJICogSWYgdGhlIHVzZXIgaW5zdGFudGlhdGVzIHRoaXMgYXMgYSBwZXItY3B1IGV2ZW50LAoJCSAqIHVzZSB0aGUgY3B1X2Nsb2NrIGV2ZW50IGluc3RlYWQuCgkJICovCgkJaWYgKGV2ZW50LT5jdHgtPnRhc2spCgkJCXBtdSA9ICZwZXJmX29wc190YXNrX2Nsb2NrOwoJCWVsc2UKCQkJcG11ID0gJnBlcmZfb3BzX2NwdV9jbG9jazsKCgkJYnJlYWs7CgljYXNlIFBFUkZfQ09VTlRfU1dfUEFHRV9GQVVMVFM6CgljYXNlIFBFUkZfQ09VTlRfU1dfUEFHRV9GQVVMVFNfTUlOOgoJY2FzZSBQRVJGX0NPVU5UX1NXX1BBR0VfRkFVTFRTX01BSjoKCWNhc2UgUEVSRl9DT1VOVF9TV19DT05URVhUX1NXSVRDSEVTOgoJY2FzZSBQRVJGX0NPVU5UX1NXX0NQVV9NSUdSQVRJT05TOgoJCWlmICghZXZlbnQtPnBhcmVudCkgewoJCQlhdG9taWNfaW5jKCZwZXJmX3N3ZXZlbnRfZW5hYmxlZFtldmVudF9pZF0pOwoJCQlldmVudC0+ZGVzdHJveSA9IHN3X3BlcmZfZXZlbnRfZGVzdHJveTsKCQl9CgkJcG11ID0gJnBlcmZfb3BzX2dlbmVyaWM7CgkJYnJlYWs7Cgl9CgoJcmV0dXJuIHBtdTsKfQoKLyoKICogQWxsb2NhdGUgYW5kIGluaXRpYWxpemUgYSBldmVudCBzdHJ1Y3R1cmUKICovCnN0YXRpYyBzdHJ1Y3QgcGVyZl9ldmVudCAqCnBlcmZfZXZlbnRfYWxsb2Moc3RydWN0IHBlcmZfZXZlbnRfYXR0ciAqYXR0ciwKCQkgICBpbnQgY3B1LAoJCSAgIHN0cnVjdCBwZXJmX2V2ZW50X2NvbnRleHQgKmN0eCwKCQkgICBzdHJ1Y3QgcGVyZl9ldmVudCAqZ3JvdXBfbGVhZGVyLAoJCSAgIHN0cnVjdCBwZXJmX2V2ZW50ICpwYXJlbnRfZXZlbnQsCgkJICAgZ2ZwX3QgZ2ZwZmxhZ3MpCnsKCWNvbnN0IHN0cnVjdCBwbXUgKnBtdTsKCXN0cnVjdCBwZXJmX2V2ZW50ICpldmVudDsKCXN0cnVjdCBod19wZXJmX2V2ZW50ICpod2M7Cglsb25nIGVycjsKCglldmVudCA9IGt6YWxsb2Moc2l6ZW9mKCpldmVudCksIGdmcGZsYWdzKTsKCWlmICghZXZlbnQpCgkJcmV0dXJuIEVSUl9QVFIoLUVOT01FTSk7CgoJLyoKCSAqIFNpbmdsZSBldmVudHMgYXJlIHRoZWlyIG93biBncm91cCBsZWFkZXJzLCB3aXRoIGFuCgkgKiBlbXB0eSBzaWJsaW5nIGxpc3Q6CgkgKi8KCWlmICghZ3JvdXBfbGVhZGVyKQoJCWdyb3VwX2xlYWRlciA9IGV2ZW50OwoKCW11dGV4X2luaXQoJmV2ZW50LT5jaGlsZF9tdXRleCk7CglJTklUX0xJU1RfSEVBRCgmZXZlbnQtPmNoaWxkX2xpc3QpOwoKCUlOSVRfTElTVF9IRUFEKCZldmVudC0+Z3JvdXBfZW50cnkpOwoJSU5JVF9MSVNUX0hFQUQoJmV2ZW50LT5ldmVudF9lbnRyeSk7CglJTklUX0xJU1RfSEVBRCgmZXZlbnQtPnNpYmxpbmdfbGlzdCk7Cglpbml0X3dhaXRxdWV1ZV9oZWFkKCZldmVudC0+d2FpdHEpOwoKCW11dGV4X2luaXQoJmV2ZW50LT5tbWFwX211dGV4KTsKCglldmVudC0+Y3B1CQk9IGNwdTsKCWV2ZW50LT5hdHRyCQk9ICphdHRyOwoJZXZlbnQtPmdyb3VwX2xlYWRlcgk9IGdyb3VwX2xlYWRlcjsKCWV2ZW50LT5wbXUJCT0gTlVMTDsKCWV2ZW50LT5jdHgJCT0gY3R4OwoJZXZlbnQtPm9uY3B1CQk9IC0xOwoKCWV2ZW50LT5wYXJlbnQJCT0gcGFyZW50X2V2ZW50OwoKCWV2ZW50LT5ucwkJPSBnZXRfcGlkX25zKGN1cnJlbnQtPm5zcHJveHktPnBpZF9ucyk7CglldmVudC0+aWQJCT0gYXRvbWljNjRfaW5jX3JldHVybigmcGVyZl9ldmVudF9pZCk7CgoJZXZlbnQtPnN0YXRlCQk9IFBFUkZfRVZFTlRfU1RBVEVfSU5BQ1RJVkU7CgoJaWYgKGF0dHItPmRpc2FibGVkKQoJCWV2ZW50LT5zdGF0ZSA9IFBFUkZfRVZFTlRfU1RBVEVfT0ZGOwoKCXBtdSA9IE5VTEw7CgoJaHdjID0gJmV2ZW50LT5odzsKCWh3Yy0+c2FtcGxlX3BlcmlvZCA9IGF0dHItPnNhbXBsZV9wZXJpb2Q7CglpZiAoYXR0ci0+ZnJlcSAmJiBhdHRyLT5zYW1wbGVfZnJlcSkKCQlod2MtPnNhbXBsZV9wZXJpb2QgPSAxOwoJaHdjLT5sYXN0X3BlcmlvZCA9IGh3Yy0+c2FtcGxlX3BlcmlvZDsKCglhdG9taWM2NF9zZXQoJmh3Yy0+cGVyaW9kX2xlZnQsIGh3Yy0+c2FtcGxlX3BlcmlvZCk7CgoJLyoKCSAqIHdlIGN1cnJlbnRseSBkbyBub3Qgc3VwcG9ydCBQRVJGX0ZPUk1BVF9HUk9VUCBvbiBpbmhlcml0ZWQgZXZlbnRzCgkgKi8KCWlmIChhdHRyLT5pbmhlcml0ICYmIChhdHRyLT5yZWFkX2Zvcm1hdCAmIFBFUkZfRk9STUFUX0dST1VQKSkKCQlnb3RvIGRvbmU7CgoJc3dpdGNoIChhdHRyLT50eXBlKSB7CgljYXNlIFBFUkZfVFlQRV9SQVc6CgljYXNlIFBFUkZfVFlQRV9IQVJEV0FSRToKCWNhc2UgUEVSRl9UWVBFX0hXX0NBQ0hFOgoJCXBtdSA9IGh3X3BlcmZfZXZlbnRfaW5pdChldmVudCk7CgkJYnJlYWs7CgoJY2FzZSBQRVJGX1RZUEVfU09GVFdBUkU6CgkJcG11ID0gc3dfcGVyZl9ldmVudF9pbml0KGV2ZW50KTsKCQlicmVhazsKCgljYXNlIFBFUkZfVFlQRV9UUkFDRVBPSU5UOgoJCXBtdSA9IHRwX3BlcmZfZXZlbnRfaW5pdChldmVudCk7CgkJYnJlYWs7CgoJZGVmYXVsdDoKCQlicmVhazsKCX0KZG9uZToKCWVyciA9IDA7CglpZiAoIXBtdSkKCQllcnIgPSAtRUlOVkFMOwoJZWxzZSBpZiAoSVNfRVJSKHBtdSkpCgkJZXJyID0gUFRSX0VSUihwbXUpOwoKCWlmIChlcnIpIHsKCQlpZiAoZXZlbnQtPm5zKQoJCQlwdXRfcGlkX25zKGV2ZW50LT5ucyk7CgkJa2ZyZWUoZXZlbnQpOwoJCXJldHVybiBFUlJfUFRSKGVycik7Cgl9CgoJZXZlbnQtPnBtdSA9IHBtdTsKCglpZiAoIWV2ZW50LT5wYXJlbnQpIHsKCQlhdG9taWNfaW5jKCZucl9ldmVudHMpOwoJCWlmIChldmVudC0+YXR0ci5tbWFwKQoJCQlhdG9taWNfaW5jKCZucl9tbWFwX2V2ZW50cyk7CgkJaWYgKGV2ZW50LT5hdHRyLmNvbW0pCgkJCWF0b21pY19pbmMoJm5yX2NvbW1fZXZlbnRzKTsKCQlpZiAoZXZlbnQtPmF0dHIudGFzaykKCQkJYXRvbWljX2luYygmbnJfdGFza19ldmVudHMpOwoJfQoKCXJldHVybiBldmVudDsKfQoKc3RhdGljIGludCBwZXJmX2NvcHlfYXR0cihzdHJ1Y3QgcGVyZl9ldmVudF9hdHRyIF9fdXNlciAqdWF0dHIsCgkJCSAgc3RydWN0IHBlcmZfZXZlbnRfYXR0ciAqYXR0cikKewoJdTMyIHNpemU7CglpbnQgcmV0OwoKCWlmICghYWNjZXNzX29rKFZFUklGWV9XUklURSwgdWF0dHIsIFBFUkZfQVRUUl9TSVpFX1ZFUjApKQoJCXJldHVybiAtRUZBVUxUOwoKCS8qCgkgKiB6ZXJvIHRoZSBmdWxsIHN0cnVjdHVyZSwgc28gdGhhdCBhIHNob3J0IGNvcHkgd2lsbCBiZSBuaWNlLgoJICovCgltZW1zZXQoYXR0ciwgMCwgc2l6ZW9mKCphdHRyKSk7CgoJcmV0ID0gZ2V0X3VzZXIoc2l6ZSwgJnVhdHRyLT5zaXplKTsKCWlmIChyZXQpCgkJcmV0dXJuIHJldDsKCglpZiAoc2l6ZSA+IFBBR0VfU0laRSkJLyogc2lsbHkgbGFyZ2UgKi8KCQlnb3RvIGVycl9zaXplOwoKCWlmICghc2l6ZSkJCS8qIGFiaSBjb21wYXQgKi8KCQlzaXplID0gUEVSRl9BVFRSX1NJWkVfVkVSMDsKCglpZiAoc2l6ZSA8IFBFUkZfQVRUUl9TSVpFX1ZFUjApCgkJZ290byBlcnJfc2l6ZTsKCgkvKgoJICogSWYgd2UncmUgaGFuZGVkIGEgYmlnZ2VyIHN0cnVjdCB0aGFuIHdlIGtub3cgb2YsCgkgKiBlbnN1cmUgYWxsIHRoZSB1bmtub3duIGJpdHMgYXJlIDAgLSBpLmUuIG5ldwoJICogdXNlci1zcGFjZSBkb2VzIG5vdCByZWx5IG9uIGFueSBrZXJuZWwgZmVhdHVyZQoJICogZXh0ZW5zaW9ucyB3ZSBkb250IGtub3cgYWJvdXQgeWV0LgoJICovCglpZiAoc2l6ZSA+IHNpemVvZigqYXR0cikpIHsKCQl1bnNpZ25lZCBjaGFyIF9fdXNlciAqYWRkcjsKCQl1bnNpZ25lZCBjaGFyIF9fdXNlciAqZW5kOwoJCXVuc2lnbmVkIGNoYXIgdmFsOwoKCQlhZGRyID0gKHZvaWQgX191c2VyICopdWF0dHIgKyBzaXplb2YoKmF0dHIpOwoJCWVuZCAgPSAodm9pZCBfX3VzZXIgKil1YXR0ciArIHNpemU7CgoJCWZvciAoOyBhZGRyIDwgZW5kOyBhZGRyKyspIHsKCQkJcmV0ID0gZ2V0X3VzZXIodmFsLCBhZGRyKTsKCQkJaWYgKHJldCkKCQkJCXJldHVybiByZXQ7CgkJCWlmICh2YWwpCgkJCQlnb3RvIGVycl9zaXplOwoJCX0KCQlzaXplID0gc2l6ZW9mKCphdHRyKTsKCX0KCglyZXQgPSBjb3B5X2Zyb21fdXNlcihhdHRyLCB1YXR0ciwgc2l6ZSk7CglpZiAocmV0KQoJCXJldHVybiAtRUZBVUxUOwoKCS8qCgkgKiBJZiB0aGUgdHlwZSBleGlzdHMsIHRoZSBjb3JyZXNwb25kaW5nIGNyZWF0aW9uIHdpbGwgdmVyaWZ5CgkgKiB0aGUgYXR0ci0+Y29uZmlnLgoJICovCglpZiAoYXR0ci0+dHlwZSA+PSBQRVJGX1RZUEVfTUFYKQoJCXJldHVybiAtRUlOVkFMOwoKCWlmIChhdHRyLT5fX3Jlc2VydmVkXzEgfHwgYXR0ci0+X19yZXNlcnZlZF8yIHx8IGF0dHItPl9fcmVzZXJ2ZWRfMykKCQlyZXR1cm4gLUVJTlZBTDsKCglpZiAoYXR0ci0+c2FtcGxlX3R5cGUgJiB+KFBFUkZfU0FNUExFX01BWC0xKSkKCQlyZXR1cm4gLUVJTlZBTDsKCglpZiAoYXR0ci0+cmVhZF9mb3JtYXQgJiB+KFBFUkZfRk9STUFUX01BWC0xKSkKCQlyZXR1cm4gLUVJTlZBTDsKCm91dDoKCXJldHVybiByZXQ7CgplcnJfc2l6ZToKCXB1dF91c2VyKHNpemVvZigqYXR0ciksICZ1YXR0ci0+c2l6ZSk7CglyZXQgPSAtRTJCSUc7Cglnb3RvIG91dDsKfQoKaW50IHBlcmZfZXZlbnRfc2V0X291dHB1dChzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQsIGludCBvdXRwdXRfZmQpCnsKCXN0cnVjdCBwZXJmX2V2ZW50ICpvdXRwdXRfZXZlbnQgPSBOVUxMOwoJc3RydWN0IGZpbGUgKm91dHB1dF9maWxlID0gTlVMTDsKCXN0cnVjdCBwZXJmX2V2ZW50ICpvbGRfb3V0cHV0OwoJaW50IGZwdXRfbmVlZGVkID0gMDsKCWludCByZXQgPSAtRUlOVkFMOwoKCWlmICghb3V0cHV0X2ZkKQoJCWdvdG8gc2V0OwoKCW91dHB1dF9maWxlID0gZmdldF9saWdodChvdXRwdXRfZmQsICZmcHV0X25lZWRlZCk7CglpZiAoIW91dHB1dF9maWxlKQoJCXJldHVybiAtRUJBREY7CgoJaWYgKG91dHB1dF9maWxlLT5mX29wICE9ICZwZXJmX2ZvcHMpCgkJZ290byBvdXQ7CgoJb3V0cHV0X2V2ZW50ID0gb3V0cHV0X2ZpbGUtPnByaXZhdGVfZGF0YTsKCgkvKiBEb24ndCBjaGFpbiBvdXRwdXQgZmRzICovCglpZiAob3V0cHV0X2V2ZW50LT5vdXRwdXQpCgkJZ290byBvdXQ7CgoJLyogRG9uJ3Qgc2V0IGFuIG91dHB1dCBmZCB3aGVuIHdlIGFscmVhZHkgaGF2ZSBhbiBvdXRwdXQgY2hhbm5lbCAqLwoJaWYgKGV2ZW50LT5kYXRhKQoJCWdvdG8gb3V0OwoKCWF0b21pY19sb25nX2luYygmb3V0cHV0X2ZpbGUtPmZfY291bnQpOwoKc2V0OgoJbXV0ZXhfbG9jaygmZXZlbnQtPm1tYXBfbXV0ZXgpOwoJb2xkX291dHB1dCA9IGV2ZW50LT5vdXRwdXQ7CglyY3VfYXNzaWduX3BvaW50ZXIoZXZlbnQtPm91dHB1dCwgb3V0cHV0X2V2ZW50KTsKCW11dGV4X3VubG9jaygmZXZlbnQtPm1tYXBfbXV0ZXgpOwoKCWlmIChvbGRfb3V0cHV0KSB7CgkJLyoKCQkgKiB3ZSBuZWVkIHRvIG1ha2Ugc3VyZSBubyBleGlzdGluZyBwZXJmX291dHB1dF8qKCkKCQkgKiBpcyBzdGlsbCByZWZlcmVuY2luZyB0aGlzIGV2ZW50LgoJCSAqLwoJCXN5bmNocm9uaXplX3JjdSgpOwoJCWZwdXQob2xkX291dHB1dC0+ZmlscCk7Cgl9CgoJcmV0ID0gMDsKb3V0OgoJZnB1dF9saWdodChvdXRwdXRfZmlsZSwgZnB1dF9uZWVkZWQpOwoJcmV0dXJuIHJldDsKfQoKLyoqCiAqIHN5c19wZXJmX2V2ZW50X29wZW4gLSBvcGVuIGEgcGVyZm9ybWFuY2UgZXZlbnQsIGFzc29jaWF0ZSBpdCB0byBhIHRhc2svY3B1CiAqCiAqIEBhdHRyX3VwdHI6CWV2ZW50X2lkIHR5cGUgYXR0cmlidXRlcyBmb3IgbW9uaXRvcmluZy9zYW1wbGluZwogKiBAcGlkOgkJdGFyZ2V0IHBpZAogKiBAY3B1OgkJdGFyZ2V0IGNwdQogKiBAZ3JvdXBfZmQ6CQlncm91cCBsZWFkZXIgZXZlbnQgZmQKICovClNZU0NBTExfREVGSU5FNShwZXJmX2V2ZW50X29wZW4sCgkJc3RydWN0IHBlcmZfZXZlbnRfYXR0ciBfX3VzZXIgKiwgYXR0cl91cHRyLAoJCXBpZF90LCBwaWQsIGludCwgY3B1LCBpbnQsIGdyb3VwX2ZkLCB1bnNpZ25lZCBsb25nLCBmbGFncykKewoJc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50LCAqZ3JvdXBfbGVhZGVyOwoJc3RydWN0IHBlcmZfZXZlbnRfYXR0ciBhdHRyOwoJc3RydWN0IHBlcmZfZXZlbnRfY29udGV4dCAqY3R4OwoJc3RydWN0IGZpbGUgKmV2ZW50X2ZpbGUgPSBOVUxMOwoJc3RydWN0IGZpbGUgKmdyb3VwX2ZpbGUgPSBOVUxMOwoJaW50IGZwdXRfbmVlZGVkID0gMDsKCWludCBmcHV0X25lZWRlZDIgPSAwOwoJaW50IGVycjsKCgkvKiBmb3IgZnV0dXJlIGV4cGFuZGFiaWxpdHkuLi4gKi8KCWlmIChmbGFncyAmIH4oUEVSRl9GTEFHX0ZEX05PX0dST1VQIHwgUEVSRl9GTEFHX0ZEX09VVFBVVCkpCgkJcmV0dXJuIC1FSU5WQUw7CgoJZXJyID0gcGVyZl9jb3B5X2F0dHIoYXR0cl91cHRyLCAmYXR0cik7CglpZiAoZXJyKQoJCXJldHVybiBlcnI7CgoJaWYgKCFhdHRyLmV4Y2x1ZGVfa2VybmVsKSB7CgkJaWYgKHBlcmZfcGFyYW5vaWRfa2VybmVsKCkgJiYgIWNhcGFibGUoQ0FQX1NZU19BRE1JTikpCgkJCXJldHVybiAtRUFDQ0VTOwoJfQoKCWlmIChhdHRyLmZyZXEpIHsKCQlpZiAoYXR0ci5zYW1wbGVfZnJlcSA+IHN5c2N0bF9wZXJmX2V2ZW50X3NhbXBsZV9yYXRlKQoJCQlyZXR1cm4gLUVJTlZBTDsKCX0KCgkvKgoJICogR2V0IHRoZSB0YXJnZXQgY29udGV4dCAodGFzayBvciBwZXJjcHUpOgoJICovCgljdHggPSBmaW5kX2dldF9jb250ZXh0KHBpZCwgY3B1KTsKCWlmIChJU19FUlIoY3R4KSkKCQlyZXR1cm4gUFRSX0VSUihjdHgpOwoKCS8qCgkgKiBMb29rIHVwIHRoZSBncm91cCBsZWFkZXIgKHdlIHdpbGwgYXR0YWNoIHRoaXMgZXZlbnQgdG8gaXQpOgoJICovCglncm91cF9sZWFkZXIgPSBOVUxMOwoJaWYgKGdyb3VwX2ZkICE9IC0xICYmICEoZmxhZ3MgJiBQRVJGX0ZMQUdfRkRfTk9fR1JPVVApKSB7CgkJZXJyID0gLUVJTlZBTDsKCQlncm91cF9maWxlID0gZmdldF9saWdodChncm91cF9mZCwgJmZwdXRfbmVlZGVkKTsKCQlpZiAoIWdyb3VwX2ZpbGUpCgkJCWdvdG8gZXJyX3B1dF9jb250ZXh0OwoJCWlmIChncm91cF9maWxlLT5mX29wICE9ICZwZXJmX2ZvcHMpCgkJCWdvdG8gZXJyX3B1dF9jb250ZXh0OwoKCQlncm91cF9sZWFkZXIgPSBncm91cF9maWxlLT5wcml2YXRlX2RhdGE7CgkJLyoKCQkgKiBEbyBub3QgYWxsb3cgYSByZWN1cnNpdmUgaGllcmFyY2h5ICh0aGlzIG5ldyBzaWJsaW5nCgkJICogYmVjb21pbmcgcGFydCBvZiBhbm90aGVyIGdyb3VwLXNpYmxpbmcpOgoJCSAqLwoJCWlmIChncm91cF9sZWFkZXItPmdyb3VwX2xlYWRlciAhPSBncm91cF9sZWFkZXIpCgkJCWdvdG8gZXJyX3B1dF9jb250ZXh0OwoJCS8qCgkJICogRG8gbm90IGFsbG93IHRvIGF0dGFjaCB0byBhIGdyb3VwIGluIGEgZGlmZmVyZW50CgkJICogdGFzayBvciBDUFUgY29udGV4dDoKCQkgKi8KCQlpZiAoZ3JvdXBfbGVhZGVyLT5jdHggIT0gY3R4KQoJCQlnb3RvIGVycl9wdXRfY29udGV4dDsKCQkvKgoJCSAqIE9ubHkgYSBncm91cCBsZWFkZXIgY2FuIGJlIGV4Y2x1c2l2ZSBvciBwaW5uZWQKCQkgKi8KCQlpZiAoYXR0ci5leGNsdXNpdmUgfHwgYXR0ci5waW5uZWQpCgkJCWdvdG8gZXJyX3B1dF9jb250ZXh0OwoJfQoKCWV2ZW50ID0gcGVyZl9ldmVudF9hbGxvYygmYXR0ciwgY3B1LCBjdHgsIGdyb3VwX2xlYWRlciwKCQkJCSAgICAgTlVMTCwgR0ZQX0tFUk5FTCk7CgllcnIgPSBQVFJfRVJSKGV2ZW50KTsKCWlmIChJU19FUlIoZXZlbnQpKQoJCWdvdG8gZXJyX3B1dF9jb250ZXh0OwoKCWVyciA9IGFub25faW5vZGVfZ2V0ZmQoIltwZXJmX2V2ZW50XSIsICZwZXJmX2ZvcHMsIGV2ZW50LCAwKTsKCWlmIChlcnIgPCAwKQoJCWdvdG8gZXJyX2ZyZWVfcHV0X2NvbnRleHQ7CgoJZXZlbnRfZmlsZSA9IGZnZXRfbGlnaHQoZXJyLCAmZnB1dF9uZWVkZWQyKTsKCWlmICghZXZlbnRfZmlsZSkKCQlnb3RvIGVycl9mcmVlX3B1dF9jb250ZXh0OwoKCWlmIChmbGFncyAmIFBFUkZfRkxBR19GRF9PVVRQVVQpIHsKCQllcnIgPSBwZXJmX2V2ZW50X3NldF9vdXRwdXQoZXZlbnQsIGdyb3VwX2ZkKTsKCQlpZiAoZXJyKQoJCQlnb3RvIGVycl9mcHV0X2ZyZWVfcHV0X2NvbnRleHQ7Cgl9CgoJZXZlbnQtPmZpbHAgPSBldmVudF9maWxlOwoJV0FSTl9PTl9PTkNFKGN0eC0+cGFyZW50X2N0eCk7CgltdXRleF9sb2NrKCZjdHgtPm11dGV4KTsKCXBlcmZfaW5zdGFsbF9pbl9jb250ZXh0KGN0eCwgZXZlbnQsIGNwdSk7CgkrK2N0eC0+Z2VuZXJhdGlvbjsKCW11dGV4X3VubG9jaygmY3R4LT5tdXRleCk7CgoJZXZlbnQtPm93bmVyID0gY3VycmVudDsKCWdldF90YXNrX3N0cnVjdChjdXJyZW50KTsKCW11dGV4X2xvY2soJmN1cnJlbnQtPnBlcmZfZXZlbnRfbXV0ZXgpOwoJbGlzdF9hZGRfdGFpbCgmZXZlbnQtPm93bmVyX2VudHJ5LCAmY3VycmVudC0+cGVyZl9ldmVudF9saXN0KTsKCW11dGV4X3VubG9jaygmY3VycmVudC0+cGVyZl9ldmVudF9tdXRleCk7CgplcnJfZnB1dF9mcmVlX3B1dF9jb250ZXh0OgoJZnB1dF9saWdodChldmVudF9maWxlLCBmcHV0X25lZWRlZDIpOwoKZXJyX2ZyZWVfcHV0X2NvbnRleHQ6CglpZiAoZXJyIDwgMCkKCQlrZnJlZShldmVudCk7CgplcnJfcHV0X2NvbnRleHQ6CglpZiAoZXJyIDwgMCkKCQlwdXRfY3R4KGN0eCk7CgoJZnB1dF9saWdodChncm91cF9maWxlLCBmcHV0X25lZWRlZCk7CgoJcmV0dXJuIGVycjsKfQoKLyoKICogaW5oZXJpdCBhIGV2ZW50IGZyb20gcGFyZW50IHRhc2sgdG8gY2hpbGQgdGFzazoKICovCnN0YXRpYyBzdHJ1Y3QgcGVyZl9ldmVudCAqCmluaGVyaXRfZXZlbnQoc3RydWN0IHBlcmZfZXZlbnQgKnBhcmVudF9ldmVudCwKCSAgICAgIHN0cnVjdCB0YXNrX3N0cnVjdCAqcGFyZW50LAoJICAgICAgc3RydWN0IHBlcmZfZXZlbnRfY29udGV4dCAqcGFyZW50X2N0eCwKCSAgICAgIHN0cnVjdCB0YXNrX3N0cnVjdCAqY2hpbGQsCgkgICAgICBzdHJ1Y3QgcGVyZl9ldmVudCAqZ3JvdXBfbGVhZGVyLAoJICAgICAgc3RydWN0IHBlcmZfZXZlbnRfY29udGV4dCAqY2hpbGRfY3R4KQp7CglzdHJ1Y3QgcGVyZl9ldmVudCAqY2hpbGRfZXZlbnQ7CgoJLyoKCSAqIEluc3RlYWQgb2YgY3JlYXRpbmcgcmVjdXJzaXZlIGhpZXJhcmNoaWVzIG9mIGV2ZW50cywKCSAqIHdlIGxpbmsgaW5oZXJpdGVkIGV2ZW50cyBiYWNrIHRvIHRoZSBvcmlnaW5hbCBwYXJlbnQsCgkgKiB3aGljaCBoYXMgYSBmaWxwIGZvciBzdXJlLCB3aGljaCB3ZSB1c2UgYXMgdGhlIHJlZmVyZW5jZQoJICogY291bnQ6CgkgKi8KCWlmIChwYXJlbnRfZXZlbnQtPnBhcmVudCkKCQlwYXJlbnRfZXZlbnQgPSBwYXJlbnRfZXZlbnQtPnBhcmVudDsKCgljaGlsZF9ldmVudCA9IHBlcmZfZXZlbnRfYWxsb2MoJnBhcmVudF9ldmVudC0+YXR0ciwKCQkJCQkgICBwYXJlbnRfZXZlbnQtPmNwdSwgY2hpbGRfY3R4LAoJCQkJCSAgIGdyb3VwX2xlYWRlciwgcGFyZW50X2V2ZW50LAoJCQkJCSAgIEdGUF9LRVJORUwpOwoJaWYgKElTX0VSUihjaGlsZF9ldmVudCkpCgkJcmV0dXJuIGNoaWxkX2V2ZW50OwoJZ2V0X2N0eChjaGlsZF9jdHgpOwoKCS8qCgkgKiBNYWtlIHRoZSBjaGlsZCBzdGF0ZSBmb2xsb3cgdGhlIHN0YXRlIG9mIHRoZSBwYXJlbnQgZXZlbnQsCgkgKiBub3QgaXRzIGF0dHIuZGlzYWJsZWQgYml0LiAgV2UgaG9sZCB0aGUgcGFyZW50J3MgbXV0ZXgsCgkgKiBzbyB3ZSB3b24ndCByYWNlIHdpdGggcGVyZl9ldmVudF97ZW4sIGRpc31hYmxlX2ZhbWlseS4KCSAqLwoJaWYgKHBhcmVudF9ldmVudC0+c3RhdGUgPj0gUEVSRl9FVkVOVF9TVEFURV9JTkFDVElWRSkKCQljaGlsZF9ldmVudC0+c3RhdGUgPSBQRVJGX0VWRU5UX1NUQVRFX0lOQUNUSVZFOwoJZWxzZQoJCWNoaWxkX2V2ZW50LT5zdGF0ZSA9IFBFUkZfRVZFTlRfU1RBVEVfT0ZGOwoKCWlmIChwYXJlbnRfZXZlbnQtPmF0dHIuZnJlcSkKCQljaGlsZF9ldmVudC0+aHcuc2FtcGxlX3BlcmlvZCA9IHBhcmVudF9ldmVudC0+aHcuc2FtcGxlX3BlcmlvZDsKCgkvKgoJICogTGluayBpdCB1cCBpbiB0aGUgY2hpbGQncyBjb250ZXh0OgoJICovCglhZGRfZXZlbnRfdG9fY3R4KGNoaWxkX2V2ZW50LCBjaGlsZF9jdHgpOwoKCS8qCgkgKiBHZXQgYSByZWZlcmVuY2UgdG8gdGhlIHBhcmVudCBmaWxwIC0gd2Ugd2lsbCBmcHV0IGl0CgkgKiB3aGVuIHRoZSBjaGlsZCBldmVudCBleGl0cy4gVGhpcyBpcyBzYWZlIHRvIGRvIGJlY2F1c2UKCSAqIHdlIGFyZSBpbiB0aGUgcGFyZW50IGFuZCB3ZSBrbm93IHRoYXQgdGhlIGZpbHAgc3RpbGwKCSAqIGV4aXN0cyBhbmQgaGFzIGEgbm9uemVybyBjb3VudDoKCSAqLwoJYXRvbWljX2xvbmdfaW5jKCZwYXJlbnRfZXZlbnQtPmZpbHAtPmZfY291bnQpOwoKCS8qCgkgKiBMaW5rIHRoaXMgaW50byB0aGUgcGFyZW50IGV2ZW50J3MgY2hpbGQgbGlzdAoJICovCglXQVJOX09OX09OQ0UocGFyZW50X2V2ZW50LT5jdHgtPnBhcmVudF9jdHgpOwoJbXV0ZXhfbG9jaygmcGFyZW50X2V2ZW50LT5jaGlsZF9tdXRleCk7CglsaXN0X2FkZF90YWlsKCZjaGlsZF9ldmVudC0+Y2hpbGRfbGlzdCwgJnBhcmVudF9ldmVudC0+Y2hpbGRfbGlzdCk7CgltdXRleF91bmxvY2soJnBhcmVudF9ldmVudC0+Y2hpbGRfbXV0ZXgpOwoKCXJldHVybiBjaGlsZF9ldmVudDsKfQoKc3RhdGljIGludCBpbmhlcml0X2dyb3VwKHN0cnVjdCBwZXJmX2V2ZW50ICpwYXJlbnRfZXZlbnQsCgkgICAgICBzdHJ1Y3QgdGFza19zdHJ1Y3QgKnBhcmVudCwKCSAgICAgIHN0cnVjdCBwZXJmX2V2ZW50X2NvbnRleHQgKnBhcmVudF9jdHgsCgkgICAgICBzdHJ1Y3QgdGFza19zdHJ1Y3QgKmNoaWxkLAoJICAgICAgc3RydWN0IHBlcmZfZXZlbnRfY29udGV4dCAqY2hpbGRfY3R4KQp7CglzdHJ1Y3QgcGVyZl9ldmVudCAqbGVhZGVyOwoJc3RydWN0IHBlcmZfZXZlbnQgKnN1YjsKCXN0cnVjdCBwZXJmX2V2ZW50ICpjaGlsZF9jdHI7CgoJbGVhZGVyID0gaW5oZXJpdF9ldmVudChwYXJlbnRfZXZlbnQsIHBhcmVudCwgcGFyZW50X2N0eCwKCQkJCSBjaGlsZCwgTlVMTCwgY2hpbGRfY3R4KTsKCWlmIChJU19FUlIobGVhZGVyKSkKCQlyZXR1cm4gUFRSX0VSUihsZWFkZXIpOwoJbGlzdF9mb3JfZWFjaF9lbnRyeShzdWIsICZwYXJlbnRfZXZlbnQtPnNpYmxpbmdfbGlzdCwgZ3JvdXBfZW50cnkpIHsKCQljaGlsZF9jdHIgPSBpbmhlcml0X2V2ZW50KHN1YiwgcGFyZW50LCBwYXJlbnRfY3R4LAoJCQkJCSAgICBjaGlsZCwgbGVhZGVyLCBjaGlsZF9jdHgpOwoJCWlmIChJU19FUlIoY2hpbGRfY3RyKSkKCQkJcmV0dXJuIFBUUl9FUlIoY2hpbGRfY3RyKTsKCX0KCXJldHVybiAwOwp9CgpzdGF0aWMgdm9pZCBzeW5jX2NoaWxkX2V2ZW50KHN0cnVjdCBwZXJmX2V2ZW50ICpjaGlsZF9ldmVudCwKCQkJICAgICAgIHN0cnVjdCB0YXNrX3N0cnVjdCAqY2hpbGQpCnsKCXN0cnVjdCBwZXJmX2V2ZW50ICpwYXJlbnRfZXZlbnQgPSBjaGlsZF9ldmVudC0+cGFyZW50OwoJdTY0IGNoaWxkX3ZhbDsKCglpZiAoY2hpbGRfZXZlbnQtPmF0dHIuaW5oZXJpdF9zdGF0KQoJCXBlcmZfZXZlbnRfcmVhZF9ldmVudChjaGlsZF9ldmVudCwgY2hpbGQpOwoKCWNoaWxkX3ZhbCA9IGF0b21pYzY0X3JlYWQoJmNoaWxkX2V2ZW50LT5jb3VudCk7CgoJLyoKCSAqIEFkZCBiYWNrIHRoZSBjaGlsZCdzIGNvdW50IHRvIHRoZSBwYXJlbnQncyBjb3VudDoKCSAqLwoJYXRvbWljNjRfYWRkKGNoaWxkX3ZhbCwgJnBhcmVudF9ldmVudC0+Y291bnQpOwoJYXRvbWljNjRfYWRkKGNoaWxkX2V2ZW50LT50b3RhbF90aW1lX2VuYWJsZWQsCgkJICAgICAmcGFyZW50X2V2ZW50LT5jaGlsZF90b3RhbF90aW1lX2VuYWJsZWQpOwoJYXRvbWljNjRfYWRkKGNoaWxkX2V2ZW50LT50b3RhbF90aW1lX3J1bm5pbmcsCgkJICAgICAmcGFyZW50X2V2ZW50LT5jaGlsZF90b3RhbF90aW1lX3J1bm5pbmcpOwoKCS8qCgkgKiBSZW1vdmUgdGhpcyBldmVudCBmcm9tIHRoZSBwYXJlbnQncyBsaXN0CgkgKi8KCVdBUk5fT05fT05DRShwYXJlbnRfZXZlbnQtPmN0eC0+cGFyZW50X2N0eCk7CgltdXRleF9sb2NrKCZwYXJlbnRfZXZlbnQtPmNoaWxkX211dGV4KTsKCWxpc3RfZGVsX2luaXQoJmNoaWxkX2V2ZW50LT5jaGlsZF9saXN0KTsKCW11dGV4X3VubG9jaygmcGFyZW50X2V2ZW50LT5jaGlsZF9tdXRleCk7CgoJLyoKCSAqIFJlbGVhc2UgdGhlIHBhcmVudCBldmVudCwgaWYgdGhpcyB3YXMgdGhlIGxhc3QKCSAqIHJlZmVyZW5jZSB0byBpdC4KCSAqLwoJZnB1dChwYXJlbnRfZXZlbnQtPmZpbHApOwp9CgpzdGF0aWMgdm9pZApfX3BlcmZfZXZlbnRfZXhpdF90YXNrKHN0cnVjdCBwZXJmX2V2ZW50ICpjaGlsZF9ldmVudCwKCQkJIHN0cnVjdCBwZXJmX2V2ZW50X2NvbnRleHQgKmNoaWxkX2N0eCwKCQkJIHN0cnVjdCB0YXNrX3N0cnVjdCAqY2hpbGQpCnsKCXN0cnVjdCBwZXJmX2V2ZW50ICpwYXJlbnRfZXZlbnQ7CgoJdXBkYXRlX2V2ZW50X3RpbWVzKGNoaWxkX2V2ZW50KTsKCXBlcmZfZXZlbnRfcmVtb3ZlX2Zyb21fY29udGV4dChjaGlsZF9ldmVudCk7CgoJcGFyZW50X2V2ZW50ID0gY2hpbGRfZXZlbnQtPnBhcmVudDsKCS8qCgkgKiBJdCBjYW4gaGFwcGVuIHRoYXQgcGFyZW50IGV4aXRzIGZpcnN0LCBhbmQgaGFzIGV2ZW50cwoJICogdGhhdCBhcmUgc3RpbGwgYXJvdW5kIGR1ZSB0byB0aGUgY2hpbGQgcmVmZXJlbmNlLiBUaGVzZQoJICogZXZlbnRzIG5lZWQgdG8gYmUgemFwcGVkIC0gYnV0IG90aGVyd2lzZSBsaW5nZXIuCgkgKi8KCWlmIChwYXJlbnRfZXZlbnQpIHsKCQlzeW5jX2NoaWxkX2V2ZW50KGNoaWxkX2V2ZW50LCBjaGlsZCk7CgkJZnJlZV9ldmVudChjaGlsZF9ldmVudCk7Cgl9Cn0KCi8qCiAqIFdoZW4gYSBjaGlsZCB0YXNrIGV4aXRzLCBmZWVkIGJhY2sgZXZlbnQgdmFsdWVzIHRvIHBhcmVudCBldmVudHMuCiAqLwp2b2lkIHBlcmZfZXZlbnRfZXhpdF90YXNrKHN0cnVjdCB0YXNrX3N0cnVjdCAqY2hpbGQpCnsKCXN0cnVjdCBwZXJmX2V2ZW50ICpjaGlsZF9ldmVudCwgKnRtcDsKCXN0cnVjdCBwZXJmX2V2ZW50X2NvbnRleHQgKmNoaWxkX2N0eDsKCXVuc2lnbmVkIGxvbmcgZmxhZ3M7CgoJaWYgKGxpa2VseSghY2hpbGQtPnBlcmZfZXZlbnRfY3R4cCkpIHsKCQlwZXJmX2V2ZW50X3Rhc2soY2hpbGQsIE5VTEwsIDApOwoJCXJldHVybjsKCX0KCglsb2NhbF9pcnFfc2F2ZShmbGFncyk7CgkvKgoJICogV2UgY2FuJ3QgcmVzY2hlZHVsZSBoZXJlIGJlY2F1c2UgaW50ZXJydXB0cyBhcmUgZGlzYWJsZWQsCgkgKiBhbmQgZWl0aGVyIGNoaWxkIGlzIGN1cnJlbnQgb3IgaXQgaXMgYSB0YXNrIHRoYXQgY2FuJ3QgYmUKCSAqIHNjaGVkdWxlZCwgc28gd2UgYXJlIG5vdyBzYWZlIGZyb20gcmVzY2hlZHVsaW5nIGNoYW5naW5nCgkgKiBvdXIgY29udGV4dC4KCSAqLwoJY2hpbGRfY3R4ID0gY2hpbGQtPnBlcmZfZXZlbnRfY3R4cDsKCV9fcGVyZl9ldmVudF90YXNrX3NjaGVkX291dChjaGlsZF9jdHgpOwoKCS8qCgkgKiBUYWtlIHRoZSBjb250ZXh0IGxvY2sgaGVyZSBzbyB0aGF0IGlmIGZpbmRfZ2V0X2NvbnRleHQgaXMKCSAqIHJlYWRpbmcgY2hpbGQtPnBlcmZfZXZlbnRfY3R4cCwgd2Ugd2FpdCB1bnRpbCBpdCBoYXMKCSAqIGluY3JlbWVudGVkIHRoZSBjb250ZXh0J3MgcmVmY291bnQgYmVmb3JlIHdlIGRvIHB1dF9jdHggYmVsb3cuCgkgKi8KCXNwaW5fbG9jaygmY2hpbGRfY3R4LT5sb2NrKTsKCWNoaWxkLT5wZXJmX2V2ZW50X2N0eHAgPSBOVUxMOwoJLyoKCSAqIElmIHRoaXMgY29udGV4dCBpcyBhIGNsb25lOyB1bmNsb25lIGl0IHNvIGl0IGNhbid0IGdldAoJICogc3dhcHBlZCB0byBhbm90aGVyIHByb2Nlc3Mgd2hpbGUgd2UncmUgcmVtb3ZpbmcgYWxsCgkgKiB0aGUgZXZlbnRzIGZyb20gaXQuCgkgKi8KCXVuY2xvbmVfY3R4KGNoaWxkX2N0eCk7CglzcGluX3VubG9ja19pcnFyZXN0b3JlKCZjaGlsZF9jdHgtPmxvY2ssIGZsYWdzKTsKCgkvKgoJICogUmVwb3J0IHRoZSB0YXNrIGRlYWQgYWZ0ZXIgdW5zY2hlZHVsaW5nIHRoZSBldmVudHMgc28gdGhhdCB3ZQoJICogd29uJ3QgZ2V0IGFueSBzYW1wbGVzIGFmdGVyIFBFUkZfUkVDT1JEX0VYSVQuIFdlIGNhbiBob3dldmVyIHN0aWxsCgkgKiBnZXQgYSBmZXcgUEVSRl9SRUNPUkRfUkVBRCBldmVudHMuCgkgKi8KCXBlcmZfZXZlbnRfdGFzayhjaGlsZCwgY2hpbGRfY3R4LCAwKTsKCgkvKgoJICogV2UgY2FuIHJlY3Vyc2Ugb24gdGhlIHNhbWUgbG9jayB0eXBlIHRocm91Z2g6CgkgKgoJICogICBfX3BlcmZfZXZlbnRfZXhpdF90YXNrKCkKCSAqICAgICBzeW5jX2NoaWxkX2V2ZW50KCkKCSAqICAgICAgIGZwdXQocGFyZW50X2V2ZW50LT5maWxwKQoJICogICAgICAgICBwZXJmX3JlbGVhc2UoKQoJICogICAgICAgICAgIG11dGV4X2xvY2soJmN0eC0+bXV0ZXgpCgkgKgoJICogQnV0IHNpbmNlIGl0cyB0aGUgcGFyZW50IGNvbnRleHQgaXQgd29uJ3QgYmUgdGhlIHNhbWUgaW5zdGFuY2UuCgkgKi8KCW11dGV4X2xvY2tfbmVzdGVkKCZjaGlsZF9jdHgtPm11dGV4LCBTSU5HTEVfREVQVEhfTkVTVElORyk7CgphZ2FpbjoKCWxpc3RfZm9yX2VhY2hfZW50cnlfc2FmZShjaGlsZF9ldmVudCwgdG1wLCAmY2hpbGRfY3R4LT5ncm91cF9saXN0LAoJCQkJIGdyb3VwX2VudHJ5KQoJCV9fcGVyZl9ldmVudF9leGl0X3Rhc2soY2hpbGRfZXZlbnQsIGNoaWxkX2N0eCwgY2hpbGQpOwoKCS8qCgkgKiBJZiB0aGUgbGFzdCBldmVudCB3YXMgYSBncm91cCBldmVudCwgaXQgd2lsbCBoYXZlIGFwcGVuZGVkIGFsbAoJICogaXRzIHNpYmxpbmdzIHRvIHRoZSBsaXN0LCBidXQgd2Ugb2J0YWluZWQgJ3RtcCcgYmVmb3JlIHRoYXQgd2hpY2gKCSAqIHdpbGwgc3RpbGwgcG9pbnQgdG8gdGhlIGxpc3QgaGVhZCB0ZXJtaW5hdGluZyB0aGUgaXRlcmF0aW9uLgoJICovCglpZiAoIWxpc3RfZW1wdHkoJmNoaWxkX2N0eC0+Z3JvdXBfbGlzdCkpCgkJZ290byBhZ2FpbjsKCgltdXRleF91bmxvY2soJmNoaWxkX2N0eC0+bXV0ZXgpOwoKCXB1dF9jdHgoY2hpbGRfY3R4KTsKfQoKLyoKICogZnJlZSBhbiB1bmV4cG9zZWQsIHVudXNlZCBjb250ZXh0IGFzIGNyZWF0ZWQgYnkgaW5oZXJpdGFuY2UgYnkKICogaW5pdF90YXNrIGJlbG93LCB1c2VkIGJ5IGZvcmsoKSBpbiBjYXNlIG9mIGZhaWwuCiAqLwp2b2lkIHBlcmZfZXZlbnRfZnJlZV90YXNrKHN0cnVjdCB0YXNrX3N0cnVjdCAqdGFzaykKewoJc3RydWN0IHBlcmZfZXZlbnRfY29udGV4dCAqY3R4ID0gdGFzay0+cGVyZl9ldmVudF9jdHhwOwoJc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50LCAqdG1wOwoKCWlmICghY3R4KQoJCXJldHVybjsKCgltdXRleF9sb2NrKCZjdHgtPm11dGV4KTsKYWdhaW46CglsaXN0X2Zvcl9lYWNoX2VudHJ5X3NhZmUoZXZlbnQsIHRtcCwgJmN0eC0+Z3JvdXBfbGlzdCwgZ3JvdXBfZW50cnkpIHsKCQlzdHJ1Y3QgcGVyZl9ldmVudCAqcGFyZW50ID0gZXZlbnQtPnBhcmVudDsKCgkJaWYgKFdBUk5fT05fT05DRSghcGFyZW50KSkKCQkJY29udGludWU7CgoJCW11dGV4X2xvY2soJnBhcmVudC0+Y2hpbGRfbXV0ZXgpOwoJCWxpc3RfZGVsX2luaXQoJmV2ZW50LT5jaGlsZF9saXN0KTsKCQltdXRleF91bmxvY2soJnBhcmVudC0+Y2hpbGRfbXV0ZXgpOwoKCQlmcHV0KHBhcmVudC0+ZmlscCk7CgoJCWxpc3RfZGVsX2V2ZW50KGV2ZW50LCBjdHgpOwoJCWZyZWVfZXZlbnQoZXZlbnQpOwoJfQoKCWlmICghbGlzdF9lbXB0eSgmY3R4LT5ncm91cF9saXN0KSkKCQlnb3RvIGFnYWluOwoKCW11dGV4X3VubG9jaygmY3R4LT5tdXRleCk7CgoJcHV0X2N0eChjdHgpOwp9CgovKgogKiBJbml0aWFsaXplIHRoZSBwZXJmX2V2ZW50IGNvbnRleHQgaW4gdGFza19zdHJ1Y3QKICovCmludCBwZXJmX2V2ZW50X2luaXRfdGFzayhzdHJ1Y3QgdGFza19zdHJ1Y3QgKmNoaWxkKQp7CglzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0ICpjaGlsZF9jdHgsICpwYXJlbnRfY3R4OwoJc3RydWN0IHBlcmZfZXZlbnRfY29udGV4dCAqY2xvbmVkX2N0eDsKCXN0cnVjdCBwZXJmX2V2ZW50ICpldmVudDsKCXN0cnVjdCB0YXNrX3N0cnVjdCAqcGFyZW50ID0gY3VycmVudDsKCWludCBpbmhlcml0ZWRfYWxsID0gMTsKCWludCByZXQgPSAwOwoKCWNoaWxkLT5wZXJmX2V2ZW50X2N0eHAgPSBOVUxMOwoKCW11dGV4X2luaXQoJmNoaWxkLT5wZXJmX2V2ZW50X211dGV4KTsKCUlOSVRfTElTVF9IRUFEKCZjaGlsZC0+cGVyZl9ldmVudF9saXN0KTsKCglpZiAobGlrZWx5KCFwYXJlbnQtPnBlcmZfZXZlbnRfY3R4cCkpCgkJcmV0dXJuIDA7CgoJLyoKCSAqIFRoaXMgaXMgZXhlY3V0ZWQgZnJvbSB0aGUgcGFyZW50IHRhc2sgY29udGV4dCwgc28gaW5oZXJpdAoJICogZXZlbnRzIHRoYXQgaGF2ZSBiZWVuIG1hcmtlZCBmb3IgY2xvbmluZy4KCSAqIEZpcnN0IGFsbG9jYXRlIGFuZCBpbml0aWFsaXplIGEgY29udGV4dCBmb3IgdGhlIGNoaWxkLgoJICovCgoJY2hpbGRfY3R4ID0ga21hbGxvYyhzaXplb2Yoc3RydWN0IHBlcmZfZXZlbnRfY29udGV4dCksIEdGUF9LRVJORUwpOwoJaWYgKCFjaGlsZF9jdHgpCgkJcmV0dXJuIC1FTk9NRU07CgoJX19wZXJmX2V2ZW50X2luaXRfY29udGV4dChjaGlsZF9jdHgsIGNoaWxkKTsKCWNoaWxkLT5wZXJmX2V2ZW50X2N0eHAgPSBjaGlsZF9jdHg7CglnZXRfdGFza19zdHJ1Y3QoY2hpbGQpOwoKCS8qCgkgKiBJZiB0aGUgcGFyZW50J3MgY29udGV4dCBpcyBhIGNsb25lLCBwaW4gaXQgc28gaXQgd29uJ3QgZ2V0CgkgKiBzd2FwcGVkIHVuZGVyIHVzLgoJICovCglwYXJlbnRfY3R4ID0gcGVyZl9waW5fdGFza19jb250ZXh0KHBhcmVudCk7CgoJLyoKCSAqIE5vIG5lZWQgdG8gY2hlY2sgaWYgcGFyZW50X2N0eCAhPSBOVUxMIGhlcmU7IHNpbmNlIHdlIHNhdwoJICogaXQgbm9uLU5VTEwgZWFybGllciwgdGhlIG9ubHkgcmVhc29uIGZvciBpdCB0byBiZWNvbWUgTlVMTAoJICogaXMgaWYgd2UgZXhpdCwgYW5kIHNpbmNlIHdlJ3JlIGN1cnJlbnRseSBpbiB0aGUgbWlkZGxlIG9mCgkgKiBhIGZvcmsgd2UgY2FuJ3QgYmUgZXhpdGluZyBhdCB0aGUgc2FtZSB0aW1lLgoJICovCgoJLyoKCSAqIExvY2sgdGhlIHBhcmVudCBsaXN0LiBObyBuZWVkIHRvIGxvY2sgdGhlIGNoaWxkIC0gbm90IFBJRAoJICogaGFzaGVkIHlldCBhbmQgbm90IHJ1bm5pbmcsIHNvIG5vYm9keSBjYW4gYWNjZXNzIGl0LgoJICovCgltdXRleF9sb2NrKCZwYXJlbnRfY3R4LT5tdXRleCk7CgoJLyoKCSAqIFdlIGRvbnQgaGF2ZSB0byBkaXNhYmxlIE5NSXMgLSB3ZSBhcmUgb25seSBsb29raW5nIGF0CgkgKiB0aGUgbGlzdCwgbm90IG1hbmlwdWxhdGluZyBpdDoKCSAqLwoJbGlzdF9mb3JfZWFjaF9lbnRyeV9yY3UoZXZlbnQsICZwYXJlbnRfY3R4LT5ldmVudF9saXN0LCBldmVudF9lbnRyeSkgewoJCWlmIChldmVudCAhPSBldmVudC0+Z3JvdXBfbGVhZGVyKQoJCQljb250aW51ZTsKCgkJaWYgKCFldmVudC0+YXR0ci5pbmhlcml0KSB7CgkJCWluaGVyaXRlZF9hbGwgPSAwOwoJCQljb250aW51ZTsKCQl9CgoJCXJldCA9IGluaGVyaXRfZ3JvdXAoZXZlbnQsIHBhcmVudCwgcGFyZW50X2N0eCwKCQkJCQkgICAgIGNoaWxkLCBjaGlsZF9jdHgpOwoJCWlmIChyZXQpIHsKCQkJaW5oZXJpdGVkX2FsbCA9IDA7CgkJCWJyZWFrOwoJCX0KCX0KCglpZiAoaW5oZXJpdGVkX2FsbCkgewoJCS8qCgkJICogTWFyayB0aGUgY2hpbGQgY29udGV4dCBhcyBhIGNsb25lIG9mIHRoZSBwYXJlbnQKCQkgKiBjb250ZXh0LCBvciBvZiB3aGF0ZXZlciB0aGUgcGFyZW50IGlzIGEgY2xvbmUgb2YuCgkJICogTm90ZSB0aGF0IGlmIHRoZSBwYXJlbnQgaXMgYSBjbG9uZSwgaXQgY291bGQgZ2V0CgkJICogdW5jbG9uZWQgYXQgYW55IHBvaW50LCBidXQgdGhhdCBkb2Vzbid0IG1hdHRlcgoJCSAqIGJlY2F1c2UgdGhlIGxpc3Qgb2YgZXZlbnRzIGFuZCB0aGUgZ2VuZXJhdGlvbgoJCSAqIGNvdW50IGNhbid0IGhhdmUgY2hhbmdlZCBzaW5jZSB3ZSB0b29rIHRoZSBtdXRleC4KCQkgKi8KCQljbG9uZWRfY3R4ID0gcmN1X2RlcmVmZXJlbmNlKHBhcmVudF9jdHgtPnBhcmVudF9jdHgpOwoJCWlmIChjbG9uZWRfY3R4KSB7CgkJCWNoaWxkX2N0eC0+cGFyZW50X2N0eCA9IGNsb25lZF9jdHg7CgkJCWNoaWxkX2N0eC0+cGFyZW50X2dlbiA9IHBhcmVudF9jdHgtPnBhcmVudF9nZW47CgkJfSBlbHNlIHsKCQkJY2hpbGRfY3R4LT5wYXJlbnRfY3R4ID0gcGFyZW50X2N0eDsKCQkJY2hpbGRfY3R4LT5wYXJlbnRfZ2VuID0gcGFyZW50X2N0eC0+Z2VuZXJhdGlvbjsKCQl9CgkJZ2V0X2N0eChjaGlsZF9jdHgtPnBhcmVudF9jdHgpOwoJfQoKCW11dGV4X3VubG9jaygmcGFyZW50X2N0eC0+bXV0ZXgpOwoKCXBlcmZfdW5waW5fY29udGV4dChwYXJlbnRfY3R4KTsKCglyZXR1cm4gcmV0Owp9CgpzdGF0aWMgdm9pZCBfX2NwdWluaXQgcGVyZl9ldmVudF9pbml0X2NwdShpbnQgY3B1KQp7CglzdHJ1Y3QgcGVyZl9jcHVfY29udGV4dCAqY3B1Y3R4OwoKCWNwdWN0eCA9ICZwZXJfY3B1KHBlcmZfY3B1X2NvbnRleHQsIGNwdSk7CglfX3BlcmZfZXZlbnRfaW5pdF9jb250ZXh0KCZjcHVjdHgtPmN0eCwgTlVMTCk7CgoJc3Bpbl9sb2NrKCZwZXJmX3Jlc291cmNlX2xvY2spOwoJY3B1Y3R4LT5tYXhfcGVydGFzayA9IHBlcmZfbWF4X2V2ZW50cyAtIHBlcmZfcmVzZXJ2ZWRfcGVyY3B1OwoJc3Bpbl91bmxvY2soJnBlcmZfcmVzb3VyY2VfbG9jayk7CgoJaHdfcGVyZl9ldmVudF9zZXR1cChjcHUpOwp9CgojaWZkZWYgQ09ORklHX0hPVFBMVUdfQ1BVCnN0YXRpYyB2b2lkIF9fcGVyZl9ldmVudF9leGl0X2NwdSh2b2lkICppbmZvKQp7CglzdHJ1Y3QgcGVyZl9jcHVfY29udGV4dCAqY3B1Y3R4ID0gJl9fZ2V0X2NwdV92YXIocGVyZl9jcHVfY29udGV4dCk7CglzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0ICpjdHggPSAmY3B1Y3R4LT5jdHg7CglzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQsICp0bXA7CgoJbGlzdF9mb3JfZWFjaF9lbnRyeV9zYWZlKGV2ZW50LCB0bXAsICZjdHgtPmdyb3VwX2xpc3QsIGdyb3VwX2VudHJ5KQoJCV9fcGVyZl9ldmVudF9yZW1vdmVfZnJvbV9jb250ZXh0KGV2ZW50KTsKfQpzdGF0aWMgdm9pZCBwZXJmX2V2ZW50X2V4aXRfY3B1KGludCBjcHUpCnsKCXN0cnVjdCBwZXJmX2NwdV9jb250ZXh0ICpjcHVjdHggPSAmcGVyX2NwdShwZXJmX2NwdV9jb250ZXh0LCBjcHUpOwoJc3RydWN0IHBlcmZfZXZlbnRfY29udGV4dCAqY3R4ID0gJmNwdWN0eC0+Y3R4OwoKCW11dGV4X2xvY2soJmN0eC0+bXV0ZXgpOwoJc21wX2NhbGxfZnVuY3Rpb25fc2luZ2xlKGNwdSwgX19wZXJmX2V2ZW50X2V4aXRfY3B1LCBOVUxMLCAxKTsKCW11dGV4X3VubG9jaygmY3R4LT5tdXRleCk7Cn0KI2Vsc2UKc3RhdGljIGlubGluZSB2b2lkIHBlcmZfZXZlbnRfZXhpdF9jcHUoaW50IGNwdSkgeyB9CiNlbmRpZgoKc3RhdGljIGludCBfX2NwdWluaXQKcGVyZl9jcHVfbm90aWZ5KHN0cnVjdCBub3RpZmllcl9ibG9jayAqc2VsZiwgdW5zaWduZWQgbG9uZyBhY3Rpb24sIHZvaWQgKmhjcHUpCnsKCXVuc2lnbmVkIGludCBjcHUgPSAobG9uZyloY3B1OwoKCXN3aXRjaCAoYWN0aW9uKSB7CgoJY2FzZSBDUFVfVVBfUFJFUEFSRToKCWNhc2UgQ1BVX1VQX1BSRVBBUkVfRlJPWkVOOgoJCXBlcmZfZXZlbnRfaW5pdF9jcHUoY3B1KTsKCQlicmVhazsKCgljYXNlIENQVV9PTkxJTkU6CgljYXNlIENQVV9PTkxJTkVfRlJPWkVOOgoJCWh3X3BlcmZfZXZlbnRfc2V0dXBfb25saW5lKGNwdSk7CgkJYnJlYWs7CgoJY2FzZSBDUFVfRE9XTl9QUkVQQVJFOgoJY2FzZSBDUFVfRE9XTl9QUkVQQVJFX0ZST1pFTjoKCQlwZXJmX2V2ZW50X2V4aXRfY3B1KGNwdSk7CgkJYnJlYWs7CgoJZGVmYXVsdDoKCQlicmVhazsKCX0KCglyZXR1cm4gTk9USUZZX09LOwp9CgovKgogKiBUaGlzIGhhcyB0byBoYXZlIGEgaGlnaGVyIHByaW9yaXR5IHRoYW4gbWlncmF0aW9uX25vdGlmaWVyIGluIHNjaGVkLmMuCiAqLwpzdGF0aWMgc3RydWN0IG5vdGlmaWVyX2Jsb2NrIF9fY3B1aW5pdGRhdGEgcGVyZl9jcHVfbmIgPSB7Cgkubm90aWZpZXJfY2FsbAkJPSBwZXJmX2NwdV9ub3RpZnksCgkucHJpb3JpdHkJCT0gMjAsCn07Cgp2b2lkIF9faW5pdCBwZXJmX2V2ZW50X2luaXQodm9pZCkKewoJcGVyZl9jcHVfbm90aWZ5KCZwZXJmX2NwdV9uYiwgKHVuc2lnbmVkIGxvbmcpQ1BVX1VQX1BSRVBBUkUsCgkJCSh2b2lkICopKGxvbmcpc21wX3Byb2Nlc3Nvcl9pZCgpKTsKCXBlcmZfY3B1X25vdGlmeSgmcGVyZl9jcHVfbmIsICh1bnNpZ25lZCBsb25nKUNQVV9PTkxJTkUsCgkJCSh2b2lkICopKGxvbmcpc21wX3Byb2Nlc3Nvcl9pZCgpKTsKCXJlZ2lzdGVyX2NwdV9ub3RpZmllcigmcGVyZl9jcHVfbmIpOwp9CgpzdGF0aWMgc3NpemVfdCBwZXJmX3Nob3dfcmVzZXJ2ZV9wZXJjcHUoc3RydWN0IHN5c2Rldl9jbGFzcyAqY2xhc3MsIGNoYXIgKmJ1ZikKewoJcmV0dXJuIHNwcmludGYoYnVmLCAiJWRcbiIsIHBlcmZfcmVzZXJ2ZWRfcGVyY3B1KTsKfQoKc3RhdGljIHNzaXplX3QKcGVyZl9zZXRfcmVzZXJ2ZV9wZXJjcHUoc3RydWN0IHN5c2Rldl9jbGFzcyAqY2xhc3MsCgkJCWNvbnN0IGNoYXIgKmJ1ZiwKCQkJc2l6ZV90IGNvdW50KQp7CglzdHJ1Y3QgcGVyZl9jcHVfY29udGV4dCAqY3B1Y3R4OwoJdW5zaWduZWQgbG9uZyB2YWw7CglpbnQgZXJyLCBjcHUsIG1wdDsKCgllcnIgPSBzdHJpY3Rfc3RydG91bChidWYsIDEwLCAmdmFsKTsKCWlmIChlcnIpCgkJcmV0dXJuIGVycjsKCWlmICh2YWwgPiBwZXJmX21heF9ldmVudHMpCgkJcmV0dXJuIC1FSU5WQUw7CgoJc3Bpbl9sb2NrKCZwZXJmX3Jlc291cmNlX2xvY2spOwoJcGVyZl9yZXNlcnZlZF9wZXJjcHUgPSB2YWw7Cglmb3JfZWFjaF9vbmxpbmVfY3B1KGNwdSkgewoJCWNwdWN0eCA9ICZwZXJfY3B1KHBlcmZfY3B1X2NvbnRleHQsIGNwdSk7CgkJc3Bpbl9sb2NrX2lycSgmY3B1Y3R4LT5jdHgubG9jayk7CgkJbXB0ID0gbWluKHBlcmZfbWF4X2V2ZW50cyAtIGNwdWN0eC0+Y3R4Lm5yX2V2ZW50cywKCQkJICBwZXJmX21heF9ldmVudHMgLSBwZXJmX3Jlc2VydmVkX3BlcmNwdSk7CgkJY3B1Y3R4LT5tYXhfcGVydGFzayA9IG1wdDsKCQlzcGluX3VubG9ja19pcnEoJmNwdWN0eC0+Y3R4LmxvY2spOwoJfQoJc3Bpbl91bmxvY2soJnBlcmZfcmVzb3VyY2VfbG9jayk7CgoJcmV0dXJuIGNvdW50Owp9CgpzdGF0aWMgc3NpemVfdCBwZXJmX3Nob3dfb3ZlcmNvbW1pdChzdHJ1Y3Qgc3lzZGV2X2NsYXNzICpjbGFzcywgY2hhciAqYnVmKQp7CglyZXR1cm4gc3ByaW50ZihidWYsICIlZFxuIiwgcGVyZl9vdmVyY29tbWl0KTsKfQoKc3RhdGljIHNzaXplX3QKcGVyZl9zZXRfb3ZlcmNvbW1pdChzdHJ1Y3Qgc3lzZGV2X2NsYXNzICpjbGFzcywgY29uc3QgY2hhciAqYnVmLCBzaXplX3QgY291bnQpCnsKCXVuc2lnbmVkIGxvbmcgdmFsOwoJaW50IGVycjsKCgllcnIgPSBzdHJpY3Rfc3RydG91bChidWYsIDEwLCAmdmFsKTsKCWlmIChlcnIpCgkJcmV0dXJuIGVycjsKCWlmICh2YWwgPiAxKQoJCXJldHVybiAtRUlOVkFMOwoKCXNwaW5fbG9jaygmcGVyZl9yZXNvdXJjZV9sb2NrKTsKCXBlcmZfb3ZlcmNvbW1pdCA9IHZhbDsKCXNwaW5fdW5sb2NrKCZwZXJmX3Jlc291cmNlX2xvY2spOwoKCXJldHVybiBjb3VudDsKfQoKc3RhdGljIFNZU0RFVl9DTEFTU19BVFRSKAoJCQkJcmVzZXJ2ZV9wZXJjcHUsCgkJCQkwNjQ0LAoJCQkJcGVyZl9zaG93X3Jlc2VydmVfcGVyY3B1LAoJCQkJcGVyZl9zZXRfcmVzZXJ2ZV9wZXJjcHUKCQkJKTsKCnN0YXRpYyBTWVNERVZfQ0xBU1NfQVRUUigKCQkJCW92ZXJjb21taXQsCgkJCQkwNjQ0LAoJCQkJcGVyZl9zaG93X292ZXJjb21taXQsCgkJCQlwZXJmX3NldF9vdmVyY29tbWl0CgkJCSk7CgpzdGF0aWMgc3RydWN0IGF0dHJpYnV0ZSAqcGVyZmNsYXNzX2F0dHJzW10gPSB7CgkmYXR0cl9yZXNlcnZlX3BlcmNwdS5hdHRyLAoJJmF0dHJfb3ZlcmNvbW1pdC5hdHRyLAoJTlVMTAp9OwoKc3RhdGljIHN0cnVjdCBhdHRyaWJ1dGVfZ3JvdXAgcGVyZmNsYXNzX2F0dHJfZ3JvdXAgPSB7CgkuYXR0cnMJCQk9IHBlcmZjbGFzc19hdHRycywKCS5uYW1lCQkJPSAicGVyZl9ldmVudHMiLAp9OwoKc3RhdGljIGludCBfX2luaXQgcGVyZl9ldmVudF9zeXNmc19pbml0KHZvaWQpCnsKCXJldHVybiBzeXNmc19jcmVhdGVfZ3JvdXAoJmNwdV9zeXNkZXZfY2xhc3Mua3NldC5rb2JqLAoJCQkJICAmcGVyZmNsYXNzX2F0dHJfZ3JvdXApOwp9CmRldmljZV9pbml0Y2FsbChwZXJmX2V2ZW50X3N5c2ZzX2luaXQpOwo=