LyoKICogUGVyZm9ybWFuY2UgY291bnRlciBjb3JlIGNvZGUKICoKICogIENvcHlyaWdodCAoQykgMjAwOCBUaG9tYXMgR2xlaXhuZXIgPHRnbHhAbGludXRyb25peC5kZT4KICogIENvcHlyaWdodCAoQykgMjAwOC0yMDA5IFJlZCBIYXQsIEluYy4sIEluZ28gTW9sbmFyCiAqICBDb3B5cmlnaHQgKEMpIDIwMDgtMjAwOSBSZWQgSGF0LCBJbmMuLCBQZXRlciBaaWpsc3RyYSA8cHppamxzdHJAcmVkaGF0LmNvbT4KICogIENvcHlyaWdodCAgqSAgMjAwOSBQYXVsIE1hY2tlcnJhcywgSUJNIENvcnAuIDxwYXVsdXNAYXUxLmlibS5jb20+CiAqCiAqICBGb3IgbGljZW5zaW5nIGRldGFpbHMgc2VlIGtlcm5lbC1iYXNlL0NPUFlJTkcKICovCgojaW5jbHVkZSA8bGludXgvZnMuaD4KI2luY2x1ZGUgPGxpbnV4L21tLmg+CiNpbmNsdWRlIDxsaW51eC9jcHUuaD4KI2luY2x1ZGUgPGxpbnV4L3NtcC5oPgojaW5jbHVkZSA8bGludXgvZmlsZS5oPgojaW5jbHVkZSA8bGludXgvcG9sbC5oPgojaW5jbHVkZSA8bGludXgvc3lzZnMuaD4KI2luY2x1ZGUgPGxpbnV4L2RjYWNoZS5oPgojaW5jbHVkZSA8bGludXgvcGVyY3B1Lmg+CiNpbmNsdWRlIDxsaW51eC9wdHJhY2UuaD4KI2luY2x1ZGUgPGxpbnV4L3Ztc3RhdC5oPgojaW5jbHVkZSA8bGludXgvaGFyZGlycS5oPgojaW5jbHVkZSA8bGludXgvcmN1bGlzdC5oPgojaW5jbHVkZSA8bGludXgvdWFjY2Vzcy5oPgojaW5jbHVkZSA8bGludXgvc3lzY2FsbHMuaD4KI2luY2x1ZGUgPGxpbnV4L2Fub25faW5vZGVzLmg+CiNpbmNsdWRlIDxsaW51eC9rZXJuZWxfc3RhdC5oPgojaW5jbHVkZSA8bGludXgvcGVyZl9jb3VudGVyLmg+CgojaW5jbHVkZSA8YXNtL2lycV9yZWdzLmg+CgovKgogKiBFYWNoIENQVSBoYXMgYSBsaXN0IG9mIHBlciBDUFUgY291bnRlcnM6CiAqLwpERUZJTkVfUEVSX0NQVShzdHJ1Y3QgcGVyZl9jcHVfY29udGV4dCwgcGVyZl9jcHVfY29udGV4dCk7CgppbnQgcGVyZl9tYXhfY291bnRlcnMgX19yZWFkX21vc3RseSA9IDE7CnN0YXRpYyBpbnQgcGVyZl9yZXNlcnZlZF9wZXJjcHUgX19yZWFkX21vc3RseTsKc3RhdGljIGludCBwZXJmX292ZXJjb21taXQgX19yZWFkX21vc3RseSA9IDE7CgpzdGF0aWMgYXRvbWljX3QgbnJfY291bnRlcnMgX19yZWFkX21vc3RseTsKc3RhdGljIGF0b21pY190IG5yX21tYXBfY291bnRlcnMgX19yZWFkX21vc3RseTsKc3RhdGljIGF0b21pY190IG5yX2NvbW1fY291bnRlcnMgX19yZWFkX21vc3RseTsKCi8qCiAqIHBlcmYgY291bnRlciBwYXJhbm9pYSBsZXZlbDoKICogIDAgLSBub3QgcGFyYW5vaWQKICogIDEgLSBkaXNhbGxvdyBjcHUgY291bnRlcnMgdG8gdW5wcml2CiAqICAyIC0gZGlzYWxsb3cga2VybmVsIHByb2ZpbGluZyB0byB1bnByaXYKICovCmludCBzeXNjdGxfcGVyZl9jb3VudGVyX3BhcmFub2lkIF9fcmVhZF9tb3N0bHk7CgpzdGF0aWMgaW5saW5lIGJvb2wgcGVyZl9wYXJhbm9pZF9jcHUodm9pZCkKewoJcmV0dXJuIHN5c2N0bF9wZXJmX2NvdW50ZXJfcGFyYW5vaWQgPiAwOwp9CgpzdGF0aWMgaW5saW5lIGJvb2wgcGVyZl9wYXJhbm9pZF9rZXJuZWwodm9pZCkKewoJcmV0dXJuIHN5c2N0bF9wZXJmX2NvdW50ZXJfcGFyYW5vaWQgPiAxOwp9CgppbnQgc3lzY3RsX3BlcmZfY291bnRlcl9tbG9jayBfX3JlYWRfbW9zdGx5ID0gNTEyOyAvKiAnZnJlZScga2IgcGVyIHVzZXIgKi8KCi8qCiAqIG1heCBwZXJmIGNvdW50ZXIgc2FtcGxlIHJhdGUKICovCmludCBzeXNjdGxfcGVyZl9jb3VudGVyX3NhbXBsZV9yYXRlIF9fcmVhZF9tb3N0bHkgPSAxMDAwMDA7CgpzdGF0aWMgYXRvbWljNjRfdCBwZXJmX2NvdW50ZXJfaWQ7CgovKgogKiBMb2NrIGZvciAoc3lzYWRtaW4tY29uZmlndXJhYmxlKSBjb3VudGVyIHJlc2VydmF0aW9uczoKICovCnN0YXRpYyBERUZJTkVfU1BJTkxPQ0socGVyZl9yZXNvdXJjZV9sb2NrKTsKCi8qCiAqIEFyY2hpdGVjdHVyZSBwcm92aWRlZCBBUElzIC0gd2VhayBhbGlhc2VzOgogKi8KZXh0ZXJuIF9fd2VhayBjb25zdCBzdHJ1Y3QgcG11ICpod19wZXJmX2NvdW50ZXJfaW5pdChzdHJ1Y3QgcGVyZl9jb3VudGVyICpjb3VudGVyKQp7CglyZXR1cm4gTlVMTDsKfQoKdm9pZCBfX3dlYWsgaHdfcGVyZl9kaXNhYmxlKHZvaWQpCQl7IGJhcnJpZXIoKTsgfQp2b2lkIF9fd2VhayBod19wZXJmX2VuYWJsZSh2b2lkKQkJeyBiYXJyaWVyKCk7IH0KCnZvaWQgX193ZWFrIGh3X3BlcmZfY291bnRlcl9zZXR1cChpbnQgY3B1KQl7IGJhcnJpZXIoKTsgfQoKaW50IF9fd2Vhawpod19wZXJmX2dyb3VwX3NjaGVkX2luKHN0cnVjdCBwZXJmX2NvdW50ZXIgKmdyb3VwX2xlYWRlciwKCSAgICAgICBzdHJ1Y3QgcGVyZl9jcHVfY29udGV4dCAqY3B1Y3R4LAoJICAgICAgIHN0cnVjdCBwZXJmX2NvdW50ZXJfY29udGV4dCAqY3R4LCBpbnQgY3B1KQp7CglyZXR1cm4gMDsKfQoKdm9pZCBfX3dlYWsgcGVyZl9jb3VudGVyX3ByaW50X2RlYnVnKHZvaWQpCXsgfQoKc3RhdGljIERFRklORV9QRVJfQ1BVKGludCwgZGlzYWJsZV9jb3VudCk7Cgp2b2lkIF9fcGVyZl9kaXNhYmxlKHZvaWQpCnsKCV9fZ2V0X2NwdV92YXIoZGlzYWJsZV9jb3VudCkrKzsKfQoKYm9vbCBfX3BlcmZfZW5hYmxlKHZvaWQpCnsKCXJldHVybiAhLS1fX2dldF9jcHVfdmFyKGRpc2FibGVfY291bnQpOwp9Cgp2b2lkIHBlcmZfZGlzYWJsZSh2b2lkKQp7CglfX3BlcmZfZGlzYWJsZSgpOwoJaHdfcGVyZl9kaXNhYmxlKCk7Cn0KCnZvaWQgcGVyZl9lbmFibGUodm9pZCkKewoJaWYgKF9fcGVyZl9lbmFibGUoKSkKCQlod19wZXJmX2VuYWJsZSgpOwp9CgpzdGF0aWMgdm9pZCBnZXRfY3R4KHN0cnVjdCBwZXJmX2NvdW50ZXJfY29udGV4dCAqY3R4KQp7CglXQVJOX09OKCFhdG9taWNfaW5jX25vdF96ZXJvKCZjdHgtPnJlZmNvdW50KSk7Cn0KCnN0YXRpYyB2b2lkIGZyZWVfY3R4KHN0cnVjdCByY3VfaGVhZCAqaGVhZCkKewoJc3RydWN0IHBlcmZfY291bnRlcl9jb250ZXh0ICpjdHg7CgoJY3R4ID0gY29udGFpbmVyX29mKGhlYWQsIHN0cnVjdCBwZXJmX2NvdW50ZXJfY29udGV4dCwgcmN1X2hlYWQpOwoJa2ZyZWUoY3R4KTsKfQoKc3RhdGljIHZvaWQgcHV0X2N0eChzdHJ1Y3QgcGVyZl9jb3VudGVyX2NvbnRleHQgKmN0eCkKewoJaWYgKGF0b21pY19kZWNfYW5kX3Rlc3QoJmN0eC0+cmVmY291bnQpKSB7CgkJaWYgKGN0eC0+cGFyZW50X2N0eCkKCQkJcHV0X2N0eChjdHgtPnBhcmVudF9jdHgpOwoJCWlmIChjdHgtPnRhc2spCgkJCXB1dF90YXNrX3N0cnVjdChjdHgtPnRhc2spOwoJCWNhbGxfcmN1KCZjdHgtPnJjdV9oZWFkLCBmcmVlX2N0eCk7Cgl9Cn0KCnN0YXRpYyB2b2lkIHVuY2xvbmVfY3R4KHN0cnVjdCBwZXJmX2NvdW50ZXJfY29udGV4dCAqY3R4KQp7CglpZiAoY3R4LT5wYXJlbnRfY3R4KSB7CgkJcHV0X2N0eChjdHgtPnBhcmVudF9jdHgpOwoJCWN0eC0+cGFyZW50X2N0eCA9IE5VTEw7Cgl9Cn0KCi8qCiAqIElmIHdlIGluaGVyaXQgY291bnRlcnMgd2Ugd2FudCB0byByZXR1cm4gdGhlIHBhcmVudCBjb3VudGVyIGlkCiAqIHRvIHVzZXJzcGFjZS4KICovCnN0YXRpYyB1NjQgcHJpbWFyeV9jb3VudGVyX2lkKHN0cnVjdCBwZXJmX2NvdW50ZXIgKmNvdW50ZXIpCnsKCXU2NCBpZCA9IGNvdW50ZXItPmlkOwoKCWlmIChjb3VudGVyLT5wYXJlbnQpCgkJaWQgPSBjb3VudGVyLT5wYXJlbnQtPmlkOwoKCXJldHVybiBpZDsKfQoKLyoKICogR2V0IHRoZSBwZXJmX2NvdW50ZXJfY29udGV4dCBmb3IgYSB0YXNrIGFuZCBsb2NrIGl0LgogKiBUaGlzIGhhcyB0byBjb3BlIHdpdGggd2l0aCB0aGUgZmFjdCB0aGF0IHVudGlsIGl0IGlzIGxvY2tlZCwKICogdGhlIGNvbnRleHQgY291bGQgZ2V0IG1vdmVkIHRvIGFub3RoZXIgdGFzay4KICovCnN0YXRpYyBzdHJ1Y3QgcGVyZl9jb3VudGVyX2NvbnRleHQgKgpwZXJmX2xvY2tfdGFza19jb250ZXh0KHN0cnVjdCB0YXNrX3N0cnVjdCAqdGFzaywgdW5zaWduZWQgbG9uZyAqZmxhZ3MpCnsKCXN0cnVjdCBwZXJmX2NvdW50ZXJfY29udGV4dCAqY3R4OwoKCXJjdV9yZWFkX2xvY2soKTsKIHJldHJ5OgoJY3R4ID0gcmN1X2RlcmVmZXJlbmNlKHRhc2stPnBlcmZfY291bnRlcl9jdHhwKTsKCWlmIChjdHgpIHsKCQkvKgoJCSAqIElmIHRoaXMgY29udGV4dCBpcyBhIGNsb25lIG9mIGFub3RoZXIsIGl0IG1pZ2h0CgkJICogZ2V0IHN3YXBwZWQgZm9yIGFub3RoZXIgdW5kZXJuZWF0aCB1cyBieQoJCSAqIHBlcmZfY291bnRlcl90YXNrX3NjaGVkX291dCwgdGhvdWdoIHRoZQoJCSAqIHJjdV9yZWFkX2xvY2soKSBwcm90ZWN0cyB1cyBmcm9tIGFueSBjb250ZXh0CgkJICogZ2V0dGluZyBmcmVlZC4gIExvY2sgdGhlIGNvbnRleHQgYW5kIGNoZWNrIGlmIGl0CgkJICogZ290IHN3YXBwZWQgYmVmb3JlIHdlIGNvdWxkIGdldCB0aGUgbG9jaywgYW5kIHJldHJ5CgkJICogaWYgc28uICBJZiB3ZSBsb2NrZWQgdGhlIHJpZ2h0IGNvbnRleHQsIHRoZW4gaXQKCQkgKiBjYW4ndCBnZXQgc3dhcHBlZCBvbiB1cyBhbnkgbW9yZS4KCQkgKi8KCQlzcGluX2xvY2tfaXJxc2F2ZSgmY3R4LT5sb2NrLCAqZmxhZ3MpOwoJCWlmIChjdHggIT0gcmN1X2RlcmVmZXJlbmNlKHRhc2stPnBlcmZfY291bnRlcl9jdHhwKSkgewoJCQlzcGluX3VubG9ja19pcnFyZXN0b3JlKCZjdHgtPmxvY2ssICpmbGFncyk7CgkJCWdvdG8gcmV0cnk7CgkJfQoKCQlpZiAoIWF0b21pY19pbmNfbm90X3plcm8oJmN0eC0+cmVmY291bnQpKSB7CgkJCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJmN0eC0+bG9jaywgKmZsYWdzKTsKCQkJY3R4ID0gTlVMTDsKCQl9Cgl9CglyY3VfcmVhZF91bmxvY2soKTsKCXJldHVybiBjdHg7Cn0KCi8qCiAqIEdldCB0aGUgY29udGV4dCBmb3IgYSB0YXNrIGFuZCBpbmNyZW1lbnQgaXRzIHBpbl9jb3VudCBzbyBpdAogKiBjYW4ndCBnZXQgc3dhcHBlZCB0byBhbm90aGVyIHRhc2suICBUaGlzIGFsc28gaW5jcmVtZW50cyBpdHMKICogcmVmZXJlbmNlIGNvdW50IHNvIHRoYXQgdGhlIGNvbnRleHQgY2FuJ3QgZ2V0IGZyZWVkLgogKi8Kc3RhdGljIHN0cnVjdCBwZXJmX2NvdW50ZXJfY29udGV4dCAqcGVyZl9waW5fdGFza19jb250ZXh0KHN0cnVjdCB0YXNrX3N0cnVjdCAqdGFzaykKewoJc3RydWN0IHBlcmZfY291bnRlcl9jb250ZXh0ICpjdHg7Cgl1bnNpZ25lZCBsb25nIGZsYWdzOwoKCWN0eCA9IHBlcmZfbG9ja190YXNrX2NvbnRleHQodGFzaywgJmZsYWdzKTsKCWlmIChjdHgpIHsKCQkrK2N0eC0+cGluX2NvdW50OwoJCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJmN0eC0+bG9jaywgZmxhZ3MpOwoJfQoJcmV0dXJuIGN0eDsKfQoKc3RhdGljIHZvaWQgcGVyZl91bnBpbl9jb250ZXh0KHN0cnVjdCBwZXJmX2NvdW50ZXJfY29udGV4dCAqY3R4KQp7Cgl1bnNpZ25lZCBsb25nIGZsYWdzOwoKCXNwaW5fbG9ja19pcnFzYXZlKCZjdHgtPmxvY2ssIGZsYWdzKTsKCS0tY3R4LT5waW5fY291bnQ7CglzcGluX3VubG9ja19pcnFyZXN0b3JlKCZjdHgtPmxvY2ssIGZsYWdzKTsKCXB1dF9jdHgoY3R4KTsKfQoKLyoKICogQWRkIGEgY291bnRlciBmcm9tIHRoZSBsaXN0cyBmb3IgaXRzIGNvbnRleHQuCiAqIE11c3QgYmUgY2FsbGVkIHdpdGggY3R4LT5tdXRleCBhbmQgY3R4LT5sb2NrIGhlbGQuCiAqLwpzdGF0aWMgdm9pZApsaXN0X2FkZF9jb3VudGVyKHN0cnVjdCBwZXJmX2NvdW50ZXIgKmNvdW50ZXIsIHN0cnVjdCBwZXJmX2NvdW50ZXJfY29udGV4dCAqY3R4KQp7CglzdHJ1Y3QgcGVyZl9jb3VudGVyICpncm91cF9sZWFkZXIgPSBjb3VudGVyLT5ncm91cF9sZWFkZXI7CgoJLyoKCSAqIERlcGVuZGluZyBvbiB3aGV0aGVyIGl0IGlzIGEgc3RhbmRhbG9uZSBvciBzaWJsaW5nIGNvdW50ZXIsCgkgKiBhZGQgaXQgc3RyYWlnaHQgdG8gdGhlIGNvbnRleHQncyBjb3VudGVyIGxpc3QsIG9yIHRvIHRoZSBncm91cAoJICogbGVhZGVyJ3Mgc2libGluZyBsaXN0OgoJICovCglpZiAoZ3JvdXBfbGVhZGVyID09IGNvdW50ZXIpCgkJbGlzdF9hZGRfdGFpbCgmY291bnRlci0+bGlzdF9lbnRyeSwgJmN0eC0+Y291bnRlcl9saXN0KTsKCWVsc2UgewoJCWxpc3RfYWRkX3RhaWwoJmNvdW50ZXItPmxpc3RfZW50cnksICZncm91cF9sZWFkZXItPnNpYmxpbmdfbGlzdCk7CgkJZ3JvdXBfbGVhZGVyLT5ucl9zaWJsaW5ncysrOwoJfQoKCWxpc3RfYWRkX3JjdSgmY291bnRlci0+ZXZlbnRfZW50cnksICZjdHgtPmV2ZW50X2xpc3QpOwoJY3R4LT5ucl9jb3VudGVycysrOwoJaWYgKGNvdW50ZXItPmF0dHIuaW5oZXJpdF9zdGF0KQoJCWN0eC0+bnJfc3RhdCsrOwp9CgovKgogKiBSZW1vdmUgYSBjb3VudGVyIGZyb20gdGhlIGxpc3RzIGZvciBpdHMgY29udGV4dC4KICogTXVzdCBiZSBjYWxsZWQgd2l0aCBjdHgtPm11dGV4IGFuZCBjdHgtPmxvY2sgaGVsZC4KICovCnN0YXRpYyB2b2lkCmxpc3RfZGVsX2NvdW50ZXIoc3RydWN0IHBlcmZfY291bnRlciAqY291bnRlciwgc3RydWN0IHBlcmZfY291bnRlcl9jb250ZXh0ICpjdHgpCnsKCXN0cnVjdCBwZXJmX2NvdW50ZXIgKnNpYmxpbmcsICp0bXA7CgoJaWYgKGxpc3RfZW1wdHkoJmNvdW50ZXItPmxpc3RfZW50cnkpKQoJCXJldHVybjsKCWN0eC0+bnJfY291bnRlcnMtLTsKCWlmIChjb3VudGVyLT5hdHRyLmluaGVyaXRfc3RhdCkKCQljdHgtPm5yX3N0YXQtLTsKCglsaXN0X2RlbF9pbml0KCZjb3VudGVyLT5saXN0X2VudHJ5KTsKCWxpc3RfZGVsX3JjdSgmY291bnRlci0+ZXZlbnRfZW50cnkpOwoKCWlmIChjb3VudGVyLT5ncm91cF9sZWFkZXIgIT0gY291bnRlcikKCQljb3VudGVyLT5ncm91cF9sZWFkZXItPm5yX3NpYmxpbmdzLS07CgoJLyoKCSAqIElmIHRoaXMgd2FzIGEgZ3JvdXAgY291bnRlciB3aXRoIHNpYmxpbmcgY291bnRlcnMgdGhlbgoJICogdXBncmFkZSB0aGUgc2libGluZ3MgdG8gc2luZ2xldG9uIGNvdW50ZXJzIGJ5IGFkZGluZyB0aGVtCgkgKiB0byB0aGUgY29udGV4dCBsaXN0IGRpcmVjdGx5OgoJICovCglsaXN0X2Zvcl9lYWNoX2VudHJ5X3NhZmUoc2libGluZywgdG1wLAoJCQkJICZjb3VudGVyLT5zaWJsaW5nX2xpc3QsIGxpc3RfZW50cnkpIHsKCgkJbGlzdF9tb3ZlX3RhaWwoJnNpYmxpbmctPmxpc3RfZW50cnksICZjdHgtPmNvdW50ZXJfbGlzdCk7CgkJc2libGluZy0+Z3JvdXBfbGVhZGVyID0gc2libGluZzsKCX0KfQoKc3RhdGljIHZvaWQKY291bnRlcl9zY2hlZF9vdXQoc3RydWN0IHBlcmZfY291bnRlciAqY291bnRlciwKCQkgIHN0cnVjdCBwZXJmX2NwdV9jb250ZXh0ICpjcHVjdHgsCgkJICBzdHJ1Y3QgcGVyZl9jb3VudGVyX2NvbnRleHQgKmN0eCkKewoJaWYgKGNvdW50ZXItPnN0YXRlICE9IFBFUkZfQ09VTlRFUl9TVEFURV9BQ1RJVkUpCgkJcmV0dXJuOwoKCWNvdW50ZXItPnN0YXRlID0gUEVSRl9DT1VOVEVSX1NUQVRFX0lOQUNUSVZFOwoJY291bnRlci0+dHN0YW1wX3N0b3BwZWQgPSBjdHgtPnRpbWU7Cgljb3VudGVyLT5wbXUtPmRpc2FibGUoY291bnRlcik7Cgljb3VudGVyLT5vbmNwdSA9IC0xOwoKCWlmICghaXNfc29mdHdhcmVfY291bnRlcihjb3VudGVyKSkKCQljcHVjdHgtPmFjdGl2ZV9vbmNwdS0tOwoJY3R4LT5ucl9hY3RpdmUtLTsKCWlmIChjb3VudGVyLT5hdHRyLmV4Y2x1c2l2ZSB8fCAhY3B1Y3R4LT5hY3RpdmVfb25jcHUpCgkJY3B1Y3R4LT5leGNsdXNpdmUgPSAwOwp9CgpzdGF0aWMgdm9pZApncm91cF9zY2hlZF9vdXQoc3RydWN0IHBlcmZfY291bnRlciAqZ3JvdXBfY291bnRlciwKCQlzdHJ1Y3QgcGVyZl9jcHVfY29udGV4dCAqY3B1Y3R4LAoJCXN0cnVjdCBwZXJmX2NvdW50ZXJfY29udGV4dCAqY3R4KQp7CglzdHJ1Y3QgcGVyZl9jb3VudGVyICpjb3VudGVyOwoKCWlmIChncm91cF9jb3VudGVyLT5zdGF0ZSAhPSBQRVJGX0NPVU5URVJfU1RBVEVfQUNUSVZFKQoJCXJldHVybjsKCgljb3VudGVyX3NjaGVkX291dChncm91cF9jb3VudGVyLCBjcHVjdHgsIGN0eCk7CgoJLyoKCSAqIFNjaGVkdWxlIG91dCBzaWJsaW5ncyAoaWYgYW55KToKCSAqLwoJbGlzdF9mb3JfZWFjaF9lbnRyeShjb3VudGVyLCAmZ3JvdXBfY291bnRlci0+c2libGluZ19saXN0LCBsaXN0X2VudHJ5KQoJCWNvdW50ZXJfc2NoZWRfb3V0KGNvdW50ZXIsIGNwdWN0eCwgY3R4KTsKCglpZiAoZ3JvdXBfY291bnRlci0+YXR0ci5leGNsdXNpdmUpCgkJY3B1Y3R4LT5leGNsdXNpdmUgPSAwOwp9CgovKgogKiBDcm9zcyBDUFUgY2FsbCB0byByZW1vdmUgYSBwZXJmb3JtYW5jZSBjb3VudGVyCiAqCiAqIFdlIGRpc2FibGUgdGhlIGNvdW50ZXIgb24gdGhlIGhhcmR3YXJlIGxldmVsIGZpcnN0LiBBZnRlciB0aGF0IHdlCiAqIHJlbW92ZSBpdCBmcm9tIHRoZSBjb250ZXh0IGxpc3QuCiAqLwpzdGF0aWMgdm9pZCBfX3BlcmZfY291bnRlcl9yZW1vdmVfZnJvbV9jb250ZXh0KHZvaWQgKmluZm8pCnsKCXN0cnVjdCBwZXJmX2NwdV9jb250ZXh0ICpjcHVjdHggPSAmX19nZXRfY3B1X3ZhcihwZXJmX2NwdV9jb250ZXh0KTsKCXN0cnVjdCBwZXJmX2NvdW50ZXIgKmNvdW50ZXIgPSBpbmZvOwoJc3RydWN0IHBlcmZfY291bnRlcl9jb250ZXh0ICpjdHggPSBjb3VudGVyLT5jdHg7CgoJLyoKCSAqIElmIHRoaXMgaXMgYSB0YXNrIGNvbnRleHQsIHdlIG5lZWQgdG8gY2hlY2sgd2hldGhlciBpdCBpcwoJICogdGhlIGN1cnJlbnQgdGFzayBjb250ZXh0IG9mIHRoaXMgY3B1LiBJZiBub3QgaXQgaGFzIGJlZW4KCSAqIHNjaGVkdWxlZCBvdXQgYmVmb3JlIHRoZSBzbXAgY2FsbCBhcnJpdmVkLgoJICovCglpZiAoY3R4LT50YXNrICYmIGNwdWN0eC0+dGFza19jdHggIT0gY3R4KQoJCXJldHVybjsKCglzcGluX2xvY2soJmN0eC0+bG9jayk7CgkvKgoJICogUHJvdGVjdCB0aGUgbGlzdCBvcGVyYXRpb24gYWdhaW5zdCBOTUkgYnkgZGlzYWJsaW5nIHRoZQoJICogY291bnRlcnMgb24gYSBnbG9iYWwgbGV2ZWwuCgkgKi8KCXBlcmZfZGlzYWJsZSgpOwoKCWNvdW50ZXJfc2NoZWRfb3V0KGNvdW50ZXIsIGNwdWN0eCwgY3R4KTsKCglsaXN0X2RlbF9jb3VudGVyKGNvdW50ZXIsIGN0eCk7CgoJaWYgKCFjdHgtPnRhc2spIHsKCQkvKgoJCSAqIEFsbG93IG1vcmUgcGVyIHRhc2sgY291bnRlcnMgd2l0aCByZXNwZWN0IHRvIHRoZQoJCSAqIHJlc2VydmF0aW9uOgoJCSAqLwoJCWNwdWN0eC0+bWF4X3BlcnRhc2sgPQoJCQltaW4ocGVyZl9tYXhfY291bnRlcnMgLSBjdHgtPm5yX2NvdW50ZXJzLAoJCQkgICAgcGVyZl9tYXhfY291bnRlcnMgLSBwZXJmX3Jlc2VydmVkX3BlcmNwdSk7Cgl9CgoJcGVyZl9lbmFibGUoKTsKCXNwaW5fdW5sb2NrKCZjdHgtPmxvY2spOwp9CgoKLyoKICogUmVtb3ZlIHRoZSBjb3VudGVyIGZyb20gYSB0YXNrJ3MgKG9yIGEgQ1BVJ3MpIGxpc3Qgb2YgY291bnRlcnMuCiAqCiAqIE11c3QgYmUgY2FsbGVkIHdpdGggY3R4LT5tdXRleCBoZWxkLgogKgogKiBDUFUgY291bnRlcnMgYXJlIHJlbW92ZWQgd2l0aCBhIHNtcCBjYWxsLiBGb3IgdGFzayBjb3VudGVycyB3ZSBvbmx5CiAqIGNhbGwgd2hlbiB0aGUgdGFzayBpcyBvbiBhIENQVS4KICoKICogSWYgY291bnRlci0+Y3R4IGlzIGEgY2xvbmVkIGNvbnRleHQsIGNhbGxlcnMgbXVzdCBtYWtlIHN1cmUgdGhhdAogKiBldmVyeSB0YXNrIHN0cnVjdCB0aGF0IGNvdW50ZXItPmN0eC0+dGFzayBjb3VsZCBwb3NzaWJseSBwb2ludCB0bwogKiByZW1haW5zIHZhbGlkLiAgVGhpcyBpcyBPSyB3aGVuIGNhbGxlZCBmcm9tIHBlcmZfcmVsZWFzZSBzaW5jZQogKiB0aGF0IG9ubHkgY2FsbHMgdXMgb24gdGhlIHRvcC1sZXZlbCBjb250ZXh0LCB3aGljaCBjYW4ndCBiZSBhIGNsb25lLgogKiBXaGVuIGNhbGxlZCBmcm9tIHBlcmZfY291bnRlcl9leGl0X3Rhc2ssIGl0J3MgT0sgYmVjYXVzZSB0aGUKICogY29udGV4dCBoYXMgYmVlbiBkZXRhY2hlZCBmcm9tIGl0cyB0YXNrLgogKi8Kc3RhdGljIHZvaWQgcGVyZl9jb3VudGVyX3JlbW92ZV9mcm9tX2NvbnRleHQoc3RydWN0IHBlcmZfY291bnRlciAqY291bnRlcikKewoJc3RydWN0IHBlcmZfY291bnRlcl9jb250ZXh0ICpjdHggPSBjb3VudGVyLT5jdHg7CglzdHJ1Y3QgdGFza19zdHJ1Y3QgKnRhc2sgPSBjdHgtPnRhc2s7CgoJaWYgKCF0YXNrKSB7CgkJLyoKCQkgKiBQZXIgY3B1IGNvdW50ZXJzIGFyZSByZW1vdmVkIHZpYSBhbiBzbXAgY2FsbCBhbmQKCQkgKiB0aGUgcmVtb3ZhbCBpcyBhbHdheXMgc3VjZXNzZnVsLgoJCSAqLwoJCXNtcF9jYWxsX2Z1bmN0aW9uX3NpbmdsZShjb3VudGVyLT5jcHUsCgkJCQkJIF9fcGVyZl9jb3VudGVyX3JlbW92ZV9mcm9tX2NvbnRleHQsCgkJCQkJIGNvdW50ZXIsIDEpOwoJCXJldHVybjsKCX0KCnJldHJ5OgoJdGFza19vbmNwdV9mdW5jdGlvbl9jYWxsKHRhc2ssIF9fcGVyZl9jb3VudGVyX3JlbW92ZV9mcm9tX2NvbnRleHQsCgkJCQkgY291bnRlcik7CgoJc3Bpbl9sb2NrX2lycSgmY3R4LT5sb2NrKTsKCS8qCgkgKiBJZiB0aGUgY29udGV4dCBpcyBhY3RpdmUgd2UgbmVlZCB0byByZXRyeSB0aGUgc21wIGNhbGwuCgkgKi8KCWlmIChjdHgtPm5yX2FjdGl2ZSAmJiAhbGlzdF9lbXB0eSgmY291bnRlci0+bGlzdF9lbnRyeSkpIHsKCQlzcGluX3VubG9ja19pcnEoJmN0eC0+bG9jayk7CgkJZ290byByZXRyeTsKCX0KCgkvKgoJICogVGhlIGxvY2sgcHJldmVudHMgdGhhdCB0aGlzIGNvbnRleHQgaXMgc2NoZWR1bGVkIGluIHNvIHdlCgkgKiBjYW4gcmVtb3ZlIHRoZSBjb3VudGVyIHNhZmVseSwgaWYgdGhlIGNhbGwgYWJvdmUgZGlkIG5vdAoJICogc3VjY2VlZC4KCSAqLwoJaWYgKCFsaXN0X2VtcHR5KCZjb3VudGVyLT5saXN0X2VudHJ5KSkgewoJCWxpc3RfZGVsX2NvdW50ZXIoY291bnRlciwgY3R4KTsKCX0KCXNwaW5fdW5sb2NrX2lycSgmY3R4LT5sb2NrKTsKfQoKc3RhdGljIGlubGluZSB1NjQgcGVyZl9jbG9jayh2b2lkKQp7CglyZXR1cm4gY3B1X2Nsb2NrKHNtcF9wcm9jZXNzb3JfaWQoKSk7Cn0KCi8qCiAqIFVwZGF0ZSB0aGUgcmVjb3JkIG9mIHRoZSBjdXJyZW50IHRpbWUgaW4gYSBjb250ZXh0LgogKi8Kc3RhdGljIHZvaWQgdXBkYXRlX2NvbnRleHRfdGltZShzdHJ1Y3QgcGVyZl9jb3VudGVyX2NvbnRleHQgKmN0eCkKewoJdTY0IG5vdyA9IHBlcmZfY2xvY2soKTsKCgljdHgtPnRpbWUgKz0gbm93IC0gY3R4LT50aW1lc3RhbXA7CgljdHgtPnRpbWVzdGFtcCA9IG5vdzsKfQoKLyoKICogVXBkYXRlIHRoZSB0b3RhbF90aW1lX2VuYWJsZWQgYW5kIHRvdGFsX3RpbWVfcnVubmluZyBmaWVsZHMgZm9yIGEgY291bnRlci4KICovCnN0YXRpYyB2b2lkIHVwZGF0ZV9jb3VudGVyX3RpbWVzKHN0cnVjdCBwZXJmX2NvdW50ZXIgKmNvdW50ZXIpCnsKCXN0cnVjdCBwZXJmX2NvdW50ZXJfY29udGV4dCAqY3R4ID0gY291bnRlci0+Y3R4OwoJdTY0IHJ1bl9lbmQ7CgoJaWYgKGNvdW50ZXItPnN0YXRlIDwgUEVSRl9DT1VOVEVSX1NUQVRFX0lOQUNUSVZFKQoJCXJldHVybjsKCgljb3VudGVyLT50b3RhbF90aW1lX2VuYWJsZWQgPSBjdHgtPnRpbWUgLSBjb3VudGVyLT50c3RhbXBfZW5hYmxlZDsKCglpZiAoY291bnRlci0+c3RhdGUgPT0gUEVSRl9DT1VOVEVSX1NUQVRFX0lOQUNUSVZFKQoJCXJ1bl9lbmQgPSBjb3VudGVyLT50c3RhbXBfc3RvcHBlZDsKCWVsc2UKCQlydW5fZW5kID0gY3R4LT50aW1lOwoKCWNvdW50ZXItPnRvdGFsX3RpbWVfcnVubmluZyA9IHJ1bl9lbmQgLSBjb3VudGVyLT50c3RhbXBfcnVubmluZzsKfQoKLyoKICogVXBkYXRlIHRvdGFsX3RpbWVfZW5hYmxlZCBhbmQgdG90YWxfdGltZV9ydW5uaW5nIGZvciBhbGwgY291bnRlcnMgaW4gYSBncm91cC4KICovCnN0YXRpYyB2b2lkIHVwZGF0ZV9ncm91cF90aW1lcyhzdHJ1Y3QgcGVyZl9jb3VudGVyICpsZWFkZXIpCnsKCXN0cnVjdCBwZXJmX2NvdW50ZXIgKmNvdW50ZXI7CgoJdXBkYXRlX2NvdW50ZXJfdGltZXMobGVhZGVyKTsKCWxpc3RfZm9yX2VhY2hfZW50cnkoY291bnRlciwgJmxlYWRlci0+c2libGluZ19saXN0LCBsaXN0X2VudHJ5KQoJCXVwZGF0ZV9jb3VudGVyX3RpbWVzKGNvdW50ZXIpOwp9CgovKgogKiBDcm9zcyBDUFUgY2FsbCB0byBkaXNhYmxlIGEgcGVyZm9ybWFuY2UgY291bnRlcgogKi8Kc3RhdGljIHZvaWQgX19wZXJmX2NvdW50ZXJfZGlzYWJsZSh2b2lkICppbmZvKQp7CglzdHJ1Y3QgcGVyZl9jb3VudGVyICpjb3VudGVyID0gaW5mbzsKCXN0cnVjdCBwZXJmX2NwdV9jb250ZXh0ICpjcHVjdHggPSAmX19nZXRfY3B1X3ZhcihwZXJmX2NwdV9jb250ZXh0KTsKCXN0cnVjdCBwZXJmX2NvdW50ZXJfY29udGV4dCAqY3R4ID0gY291bnRlci0+Y3R4OwoKCS8qCgkgKiBJZiB0aGlzIGlzIGEgcGVyLXRhc2sgY291bnRlciwgbmVlZCB0byBjaGVjayB3aGV0aGVyIHRoaXMKCSAqIGNvdW50ZXIncyB0YXNrIGlzIHRoZSBjdXJyZW50IHRhc2sgb24gdGhpcyBjcHUuCgkgKi8KCWlmIChjdHgtPnRhc2sgJiYgY3B1Y3R4LT50YXNrX2N0eCAhPSBjdHgpCgkJcmV0dXJuOwoKCXNwaW5fbG9jaygmY3R4LT5sb2NrKTsKCgkvKgoJICogSWYgdGhlIGNvdW50ZXIgaXMgb24sIHR1cm4gaXQgb2ZmLgoJICogSWYgaXQgaXMgaW4gZXJyb3Igc3RhdGUsIGxlYXZlIGl0IGluIGVycm9yIHN0YXRlLgoJICovCglpZiAoY291bnRlci0+c3RhdGUgPj0gUEVSRl9DT1VOVEVSX1NUQVRFX0lOQUNUSVZFKSB7CgkJdXBkYXRlX2NvbnRleHRfdGltZShjdHgpOwoJCXVwZGF0ZV9jb3VudGVyX3RpbWVzKGNvdW50ZXIpOwoJCWlmIChjb3VudGVyID09IGNvdW50ZXItPmdyb3VwX2xlYWRlcikKCQkJZ3JvdXBfc2NoZWRfb3V0KGNvdW50ZXIsIGNwdWN0eCwgY3R4KTsKCQllbHNlCgkJCWNvdW50ZXJfc2NoZWRfb3V0KGNvdW50ZXIsIGNwdWN0eCwgY3R4KTsKCQljb3VudGVyLT5zdGF0ZSA9IFBFUkZfQ09VTlRFUl9TVEFURV9PRkY7Cgl9CgoJc3Bpbl91bmxvY2soJmN0eC0+bG9jayk7Cn0KCi8qCiAqIERpc2FibGUgYSBjb3VudGVyLgogKgogKiBJZiBjb3VudGVyLT5jdHggaXMgYSBjbG9uZWQgY29udGV4dCwgY2FsbGVycyBtdXN0IG1ha2Ugc3VyZSB0aGF0CiAqIGV2ZXJ5IHRhc2sgc3RydWN0IHRoYXQgY291bnRlci0+Y3R4LT50YXNrIGNvdWxkIHBvc3NpYmx5IHBvaW50IHRvCiAqIHJlbWFpbnMgdmFsaWQuICBUaGlzIGNvbmRpdGlvbiBpcyBzYXRpc2lmZWQgd2hlbiBjYWxsZWQgdGhyb3VnaAogKiBwZXJmX2NvdW50ZXJfZm9yX2VhY2hfY2hpbGQgb3IgcGVyZl9jb3VudGVyX2Zvcl9lYWNoIGJlY2F1c2UgdGhleQogKiBob2xkIHRoZSB0b3AtbGV2ZWwgY291bnRlcidzIGNoaWxkX211dGV4LCBzbyBhbnkgZGVzY2VuZGFudCB0aGF0CiAqIGdvZXMgdG8gZXhpdCB3aWxsIGJsb2NrIGluIHN5bmNfY2hpbGRfY291bnRlci4KICogV2hlbiBjYWxsZWQgZnJvbSBwZXJmX3BlbmRpbmdfY291bnRlciBpdCdzIE9LIGJlY2F1c2UgY291bnRlci0+Y3R4CiAqIGlzIHRoZSBjdXJyZW50IGNvbnRleHQgb24gdGhpcyBDUFUgYW5kIHByZWVtcHRpb24gaXMgZGlzYWJsZWQsCiAqIGhlbmNlIHdlIGNhbid0IGdldCBpbnRvIHBlcmZfY291bnRlcl90YXNrX3NjaGVkX291dCBmb3IgdGhpcyBjb250ZXh0LgogKi8Kc3RhdGljIHZvaWQgcGVyZl9jb3VudGVyX2Rpc2FibGUoc3RydWN0IHBlcmZfY291bnRlciAqY291bnRlcikKewoJc3RydWN0IHBlcmZfY291bnRlcl9jb250ZXh0ICpjdHggPSBjb3VudGVyLT5jdHg7CglzdHJ1Y3QgdGFza19zdHJ1Y3QgKnRhc2sgPSBjdHgtPnRhc2s7CgoJaWYgKCF0YXNrKSB7CgkJLyoKCQkgKiBEaXNhYmxlIHRoZSBjb3VudGVyIG9uIHRoZSBjcHUgdGhhdCBpdCdzIG9uCgkJICovCgkJc21wX2NhbGxfZnVuY3Rpb25fc2luZ2xlKGNvdW50ZXItPmNwdSwgX19wZXJmX2NvdW50ZXJfZGlzYWJsZSwKCQkJCQkgY291bnRlciwgMSk7CgkJcmV0dXJuOwoJfQoKIHJldHJ5OgoJdGFza19vbmNwdV9mdW5jdGlvbl9jYWxsKHRhc2ssIF9fcGVyZl9jb3VudGVyX2Rpc2FibGUsIGNvdW50ZXIpOwoKCXNwaW5fbG9ja19pcnEoJmN0eC0+bG9jayk7CgkvKgoJICogSWYgdGhlIGNvdW50ZXIgaXMgc3RpbGwgYWN0aXZlLCB3ZSBuZWVkIHRvIHJldHJ5IHRoZSBjcm9zcy1jYWxsLgoJICovCglpZiAoY291bnRlci0+c3RhdGUgPT0gUEVSRl9DT1VOVEVSX1NUQVRFX0FDVElWRSkgewoJCXNwaW5fdW5sb2NrX2lycSgmY3R4LT5sb2NrKTsKCQlnb3RvIHJldHJ5OwoJfQoKCS8qCgkgKiBTaW5jZSB3ZSBoYXZlIHRoZSBsb2NrIHRoaXMgY29udGV4dCBjYW4ndCBiZSBzY2hlZHVsZWQKCSAqIGluLCBzbyB3ZSBjYW4gY2hhbmdlIHRoZSBzdGF0ZSBzYWZlbHkuCgkgKi8KCWlmIChjb3VudGVyLT5zdGF0ZSA9PSBQRVJGX0NPVU5URVJfU1RBVEVfSU5BQ1RJVkUpIHsKCQl1cGRhdGVfY291bnRlcl90aW1lcyhjb3VudGVyKTsKCQljb3VudGVyLT5zdGF0ZSA9IFBFUkZfQ09VTlRFUl9TVEFURV9PRkY7Cgl9CgoJc3Bpbl91bmxvY2tfaXJxKCZjdHgtPmxvY2spOwp9CgpzdGF0aWMgaW50CmNvdW50ZXJfc2NoZWRfaW4oc3RydWN0IHBlcmZfY291bnRlciAqY291bnRlciwKCQkgc3RydWN0IHBlcmZfY3B1X2NvbnRleHQgKmNwdWN0eCwKCQkgc3RydWN0IHBlcmZfY291bnRlcl9jb250ZXh0ICpjdHgsCgkJIGludCBjcHUpCnsKCWlmIChjb3VudGVyLT5zdGF0ZSA8PSBQRVJGX0NPVU5URVJfU1RBVEVfT0ZGKQoJCXJldHVybiAwOwoKCWNvdW50ZXItPnN0YXRlID0gUEVSRl9DT1VOVEVSX1NUQVRFX0FDVElWRTsKCWNvdW50ZXItPm9uY3B1ID0gY3B1OwkvKiBUT0RPOiBwdXQgJ2NwdScgaW50byBjcHVjdHgtPmNwdSAqLwoJLyoKCSAqIFRoZSBuZXcgc3RhdGUgbXVzdCBiZSB2aXNpYmxlIGJlZm9yZSB3ZSB0dXJuIGl0IG9uIGluIHRoZSBoYXJkd2FyZToKCSAqLwoJc21wX3dtYigpOwoKCWlmIChjb3VudGVyLT5wbXUtPmVuYWJsZShjb3VudGVyKSkgewoJCWNvdW50ZXItPnN0YXRlID0gUEVSRl9DT1VOVEVSX1NUQVRFX0lOQUNUSVZFOwoJCWNvdW50ZXItPm9uY3B1ID0gLTE7CgkJcmV0dXJuIC1FQUdBSU47Cgl9CgoJY291bnRlci0+dHN0YW1wX3J1bm5pbmcgKz0gY3R4LT50aW1lIC0gY291bnRlci0+dHN0YW1wX3N0b3BwZWQ7CgoJaWYgKCFpc19zb2Z0d2FyZV9jb3VudGVyKGNvdW50ZXIpKQoJCWNwdWN0eC0+YWN0aXZlX29uY3B1Kys7CgljdHgtPm5yX2FjdGl2ZSsrOwoKCWlmIChjb3VudGVyLT5hdHRyLmV4Y2x1c2l2ZSkKCQljcHVjdHgtPmV4Y2x1c2l2ZSA9IDE7CgoJcmV0dXJuIDA7Cn0KCnN0YXRpYyBpbnQKZ3JvdXBfc2NoZWRfaW4oc3RydWN0IHBlcmZfY291bnRlciAqZ3JvdXBfY291bnRlciwKCSAgICAgICBzdHJ1Y3QgcGVyZl9jcHVfY29udGV4dCAqY3B1Y3R4LAoJICAgICAgIHN0cnVjdCBwZXJmX2NvdW50ZXJfY29udGV4dCAqY3R4LAoJICAgICAgIGludCBjcHUpCnsKCXN0cnVjdCBwZXJmX2NvdW50ZXIgKmNvdW50ZXIsICpwYXJ0aWFsX2dyb3VwOwoJaW50IHJldDsKCglpZiAoZ3JvdXBfY291bnRlci0+c3RhdGUgPT0gUEVSRl9DT1VOVEVSX1NUQVRFX09GRikKCQlyZXR1cm4gMDsKCglyZXQgPSBod19wZXJmX2dyb3VwX3NjaGVkX2luKGdyb3VwX2NvdW50ZXIsIGNwdWN0eCwgY3R4LCBjcHUpOwoJaWYgKHJldCkKCQlyZXR1cm4gcmV0IDwgMCA/IHJldCA6IDA7CgoJaWYgKGNvdW50ZXJfc2NoZWRfaW4oZ3JvdXBfY291bnRlciwgY3B1Y3R4LCBjdHgsIGNwdSkpCgkJcmV0dXJuIC1FQUdBSU47CgoJLyoKCSAqIFNjaGVkdWxlIGluIHNpYmxpbmdzIGFzIG9uZSBncm91cCAoaWYgYW55KToKCSAqLwoJbGlzdF9mb3JfZWFjaF9lbnRyeShjb3VudGVyLCAmZ3JvdXBfY291bnRlci0+c2libGluZ19saXN0LCBsaXN0X2VudHJ5KSB7CgkJaWYgKGNvdW50ZXJfc2NoZWRfaW4oY291bnRlciwgY3B1Y3R4LCBjdHgsIGNwdSkpIHsKCQkJcGFydGlhbF9ncm91cCA9IGNvdW50ZXI7CgkJCWdvdG8gZ3JvdXBfZXJyb3I7CgkJfQoJfQoKCXJldHVybiAwOwoKZ3JvdXBfZXJyb3I6CgkvKgoJICogR3JvdXBzIGNhbiBiZSBzY2hlZHVsZWQgaW4gYXMgb25lIHVuaXQgb25seSwgc28gdW5kbyBhbnkKCSAqIHBhcnRpYWwgZ3JvdXAgYmVmb3JlIHJldHVybmluZzoKCSAqLwoJbGlzdF9mb3JfZWFjaF9lbnRyeShjb3VudGVyLCAmZ3JvdXBfY291bnRlci0+c2libGluZ19saXN0LCBsaXN0X2VudHJ5KSB7CgkJaWYgKGNvdW50ZXIgPT0gcGFydGlhbF9ncm91cCkKCQkJYnJlYWs7CgkJY291bnRlcl9zY2hlZF9vdXQoY291bnRlciwgY3B1Y3R4LCBjdHgpOwoJfQoJY291bnRlcl9zY2hlZF9vdXQoZ3JvdXBfY291bnRlciwgY3B1Y3R4LCBjdHgpOwoKCXJldHVybiAtRUFHQUlOOwp9CgovKgogKiBSZXR1cm4gMSBmb3IgYSBncm91cCBjb25zaXN0aW5nIGVudGlyZWx5IG9mIHNvZnR3YXJlIGNvdW50ZXJzLAogKiAwIGlmIHRoZSBncm91cCBjb250YWlucyBhbnkgaGFyZHdhcmUgY291bnRlcnMuCiAqLwpzdGF0aWMgaW50IGlzX3NvZnR3YXJlX29ubHlfZ3JvdXAoc3RydWN0IHBlcmZfY291bnRlciAqbGVhZGVyKQp7CglzdHJ1Y3QgcGVyZl9jb3VudGVyICpjb3VudGVyOwoKCWlmICghaXNfc29mdHdhcmVfY291bnRlcihsZWFkZXIpKQoJCXJldHVybiAwOwoKCWxpc3RfZm9yX2VhY2hfZW50cnkoY291bnRlciwgJmxlYWRlci0+c2libGluZ19saXN0LCBsaXN0X2VudHJ5KQoJCWlmICghaXNfc29mdHdhcmVfY291bnRlcihjb3VudGVyKSkKCQkJcmV0dXJuIDA7CgoJcmV0dXJuIDE7Cn0KCi8qCiAqIFdvcmsgb3V0IHdoZXRoZXIgd2UgY2FuIHB1dCB0aGlzIGNvdW50ZXIgZ3JvdXAgb24gdGhlIENQVSBub3cuCiAqLwpzdGF0aWMgaW50IGdyb3VwX2Nhbl9nb19vbihzdHJ1Y3QgcGVyZl9jb3VudGVyICpjb3VudGVyLAoJCQkgICBzdHJ1Y3QgcGVyZl9jcHVfY29udGV4dCAqY3B1Y3R4LAoJCQkgICBpbnQgY2FuX2FkZF9odykKewoJLyoKCSAqIEdyb3VwcyBjb25zaXN0aW5nIGVudGlyZWx5IG9mIHNvZnR3YXJlIGNvdW50ZXJzIGNhbiBhbHdheXMgZ28gb24uCgkgKi8KCWlmIChpc19zb2Z0d2FyZV9vbmx5X2dyb3VwKGNvdW50ZXIpKQoJCXJldHVybiAxOwoJLyoKCSAqIElmIGFuIGV4Y2x1c2l2ZSBncm91cCBpcyBhbHJlYWR5IG9uLCBubyBvdGhlciBoYXJkd2FyZQoJICogY291bnRlcnMgY2FuIGdvIG9uLgoJICovCglpZiAoY3B1Y3R4LT5leGNsdXNpdmUpCgkJcmV0dXJuIDA7CgkvKgoJICogSWYgdGhpcyBncm91cCBpcyBleGNsdXNpdmUgYW5kIHRoZXJlIGFyZSBhbHJlYWR5CgkgKiBjb3VudGVycyBvbiB0aGUgQ1BVLCBpdCBjYW4ndCBnbyBvbi4KCSAqLwoJaWYgKGNvdW50ZXItPmF0dHIuZXhjbHVzaXZlICYmIGNwdWN0eC0+YWN0aXZlX29uY3B1KQoJCXJldHVybiAwOwoJLyoKCSAqIE90aGVyd2lzZSwgdHJ5IHRvIGFkZCBpdCBpZiBhbGwgcHJldmlvdXMgZ3JvdXBzIHdlcmUgYWJsZQoJICogdG8gZ28gb24uCgkgKi8KCXJldHVybiBjYW5fYWRkX2h3Owp9CgpzdGF0aWMgdm9pZCBhZGRfY291bnRlcl90b19jdHgoc3RydWN0IHBlcmZfY291bnRlciAqY291bnRlciwKCQkJICAgICAgIHN0cnVjdCBwZXJmX2NvdW50ZXJfY29udGV4dCAqY3R4KQp7CglsaXN0X2FkZF9jb3VudGVyKGNvdW50ZXIsIGN0eCk7Cgljb3VudGVyLT50c3RhbXBfZW5hYmxlZCA9IGN0eC0+dGltZTsKCWNvdW50ZXItPnRzdGFtcF9ydW5uaW5nID0gY3R4LT50aW1lOwoJY291bnRlci0+dHN0YW1wX3N0b3BwZWQgPSBjdHgtPnRpbWU7Cn0KCi8qCiAqIENyb3NzIENQVSBjYWxsIHRvIGluc3RhbGwgYW5kIGVuYWJsZSBhIHBlcmZvcm1hbmNlIGNvdW50ZXIKICoKICogTXVzdCBiZSBjYWxsZWQgd2l0aCBjdHgtPm11dGV4IGhlbGQKICovCnN0YXRpYyB2b2lkIF9fcGVyZl9pbnN0YWxsX2luX2NvbnRleHQodm9pZCAqaW5mbykKewoJc3RydWN0IHBlcmZfY3B1X2NvbnRleHQgKmNwdWN0eCA9ICZfX2dldF9jcHVfdmFyKHBlcmZfY3B1X2NvbnRleHQpOwoJc3RydWN0IHBlcmZfY291bnRlciAqY291bnRlciA9IGluZm87CglzdHJ1Y3QgcGVyZl9jb3VudGVyX2NvbnRleHQgKmN0eCA9IGNvdW50ZXItPmN0eDsKCXN0cnVjdCBwZXJmX2NvdW50ZXIgKmxlYWRlciA9IGNvdW50ZXItPmdyb3VwX2xlYWRlcjsKCWludCBjcHUgPSBzbXBfcHJvY2Vzc29yX2lkKCk7CglpbnQgZXJyOwoKCS8qCgkgKiBJZiB0aGlzIGlzIGEgdGFzayBjb250ZXh0LCB3ZSBuZWVkIHRvIGNoZWNrIHdoZXRoZXIgaXQgaXMKCSAqIHRoZSBjdXJyZW50IHRhc2sgY29udGV4dCBvZiB0aGlzIGNwdS4gSWYgbm90IGl0IGhhcyBiZWVuCgkgKiBzY2hlZHVsZWQgb3V0IGJlZm9yZSB0aGUgc21wIGNhbGwgYXJyaXZlZC4KCSAqIE9yIHBvc3NpYmx5IHRoaXMgaXMgdGhlIHJpZ2h0IGNvbnRleHQgYnV0IGl0IGlzbid0CgkgKiBvbiB0aGlzIGNwdSBiZWNhdXNlIGl0IGhhZCBubyBjb3VudGVycy4KCSAqLwoJaWYgKGN0eC0+dGFzayAmJiBjcHVjdHgtPnRhc2tfY3R4ICE9IGN0eCkgewoJCWlmIChjcHVjdHgtPnRhc2tfY3R4IHx8IGN0eC0+dGFzayAhPSBjdXJyZW50KQoJCQlyZXR1cm47CgkJY3B1Y3R4LT50YXNrX2N0eCA9IGN0eDsKCX0KCglzcGluX2xvY2soJmN0eC0+bG9jayk7CgljdHgtPmlzX2FjdGl2ZSA9IDE7Cgl1cGRhdGVfY29udGV4dF90aW1lKGN0eCk7CgoJLyoKCSAqIFByb3RlY3QgdGhlIGxpc3Qgb3BlcmF0aW9uIGFnYWluc3QgTk1JIGJ5IGRpc2FibGluZyB0aGUKCSAqIGNvdW50ZXJzIG9uIGEgZ2xvYmFsIGxldmVsLiBOT1AgZm9yIG5vbiBOTUkgYmFzZWQgY291bnRlcnMuCgkgKi8KCXBlcmZfZGlzYWJsZSgpOwoKCWFkZF9jb3VudGVyX3RvX2N0eChjb3VudGVyLCBjdHgpOwoKCS8qCgkgKiBEb24ndCBwdXQgdGhlIGNvdW50ZXIgb24gaWYgaXQgaXMgZGlzYWJsZWQgb3IgaWYKCSAqIGl0IGlzIGluIGEgZ3JvdXAgYW5kIHRoZSBncm91cCBpc24ndCBvbi4KCSAqLwoJaWYgKGNvdW50ZXItPnN0YXRlICE9IFBFUkZfQ09VTlRFUl9TVEFURV9JTkFDVElWRSB8fAoJICAgIChsZWFkZXIgIT0gY291bnRlciAmJiBsZWFkZXItPnN0YXRlICE9IFBFUkZfQ09VTlRFUl9TVEFURV9BQ1RJVkUpKQoJCWdvdG8gdW5sb2NrOwoKCS8qCgkgKiBBbiBleGNsdXNpdmUgY291bnRlciBjYW4ndCBnbyBvbiBpZiB0aGVyZSBhcmUgYWxyZWFkeSBhY3RpdmUKCSAqIGhhcmR3YXJlIGNvdW50ZXJzLCBhbmQgbm8gaGFyZHdhcmUgY291bnRlciBjYW4gZ28gb24gaWYgdGhlcmUKCSAqIGlzIGFscmVhZHkgYW4gZXhjbHVzaXZlIGNvdW50ZXIgb24uCgkgKi8KCWlmICghZ3JvdXBfY2FuX2dvX29uKGNvdW50ZXIsIGNwdWN0eCwgMSkpCgkJZXJyID0gLUVFWElTVDsKCWVsc2UKCQllcnIgPSBjb3VudGVyX3NjaGVkX2luKGNvdW50ZXIsIGNwdWN0eCwgY3R4LCBjcHUpOwoKCWlmIChlcnIpIHsKCQkvKgoJCSAqIFRoaXMgY291bnRlciBjb3VsZG4ndCBnbyBvbi4gIElmIGl0IGlzIGluIGEgZ3JvdXAKCQkgKiB0aGVuIHdlIGhhdmUgdG8gcHVsbCB0aGUgd2hvbGUgZ3JvdXAgb2ZmLgoJCSAqIElmIHRoZSBjb3VudGVyIGdyb3VwIGlzIHBpbm5lZCB0aGVuIHB1dCBpdCBpbiBlcnJvciBzdGF0ZS4KCQkgKi8KCQlpZiAobGVhZGVyICE9IGNvdW50ZXIpCgkJCWdyb3VwX3NjaGVkX291dChsZWFkZXIsIGNwdWN0eCwgY3R4KTsKCQlpZiAobGVhZGVyLT5hdHRyLnBpbm5lZCkgewoJCQl1cGRhdGVfZ3JvdXBfdGltZXMobGVhZGVyKTsKCQkJbGVhZGVyLT5zdGF0ZSA9IFBFUkZfQ09VTlRFUl9TVEFURV9FUlJPUjsKCQl9Cgl9CgoJaWYgKCFlcnIgJiYgIWN0eC0+dGFzayAmJiBjcHVjdHgtPm1heF9wZXJ0YXNrKQoJCWNwdWN0eC0+bWF4X3BlcnRhc2stLTsKCiB1bmxvY2s6CglwZXJmX2VuYWJsZSgpOwoKCXNwaW5fdW5sb2NrKCZjdHgtPmxvY2spOwp9CgovKgogKiBBdHRhY2ggYSBwZXJmb3JtYW5jZSBjb3VudGVyIHRvIGEgY29udGV4dAogKgogKiBGaXJzdCB3ZSBhZGQgdGhlIGNvdW50ZXIgdG8gdGhlIGxpc3Qgd2l0aCB0aGUgaGFyZHdhcmUgZW5hYmxlIGJpdAogKiBpbiBjb3VudGVyLT5od19jb25maWcgY2xlYXJlZC4KICoKICogSWYgdGhlIGNvdW50ZXIgaXMgYXR0YWNoZWQgdG8gYSB0YXNrIHdoaWNoIGlzIG9uIGEgQ1BVIHdlIHVzZSBhIHNtcAogKiBjYWxsIHRvIGVuYWJsZSBpdCBpbiB0aGUgdGFzayBjb250ZXh0LiBUaGUgdGFzayBtaWdodCBoYXZlIGJlZW4KICogc2NoZWR1bGVkIGF3YXksIGJ1dCB3ZSBjaGVjayB0aGlzIGluIHRoZSBzbXAgY2FsbCBhZ2Fpbi4KICoKICogTXVzdCBiZSBjYWxsZWQgd2l0aCBjdHgtPm11dGV4IGhlbGQuCiAqLwpzdGF0aWMgdm9pZApwZXJmX2luc3RhbGxfaW5fY29udGV4dChzdHJ1Y3QgcGVyZl9jb3VudGVyX2NvbnRleHQgKmN0eCwKCQkJc3RydWN0IHBlcmZfY291bnRlciAqY291bnRlciwKCQkJaW50IGNwdSkKewoJc3RydWN0IHRhc2tfc3RydWN0ICp0YXNrID0gY3R4LT50YXNrOwoKCWlmICghdGFzaykgewoJCS8qCgkJICogUGVyIGNwdSBjb3VudGVycyBhcmUgaW5zdGFsbGVkIHZpYSBhbiBzbXAgY2FsbCBhbmQKCQkgKiB0aGUgaW5zdGFsbCBpcyBhbHdheXMgc3VjZXNzZnVsLgoJCSAqLwoJCXNtcF9jYWxsX2Z1bmN0aW9uX3NpbmdsZShjcHUsIF9fcGVyZl9pbnN0YWxsX2luX2NvbnRleHQsCgkJCQkJIGNvdW50ZXIsIDEpOwoJCXJldHVybjsKCX0KCnJldHJ5OgoJdGFza19vbmNwdV9mdW5jdGlvbl9jYWxsKHRhc2ssIF9fcGVyZl9pbnN0YWxsX2luX2NvbnRleHQsCgkJCQkgY291bnRlcik7CgoJc3Bpbl9sb2NrX2lycSgmY3R4LT5sb2NrKTsKCS8qCgkgKiB3ZSBuZWVkIHRvIHJldHJ5IHRoZSBzbXAgY2FsbC4KCSAqLwoJaWYgKGN0eC0+aXNfYWN0aXZlICYmIGxpc3RfZW1wdHkoJmNvdW50ZXItPmxpc3RfZW50cnkpKSB7CgkJc3Bpbl91bmxvY2tfaXJxKCZjdHgtPmxvY2spOwoJCWdvdG8gcmV0cnk7Cgl9CgoJLyoKCSAqIFRoZSBsb2NrIHByZXZlbnRzIHRoYXQgdGhpcyBjb250ZXh0IGlzIHNjaGVkdWxlZCBpbiBzbyB3ZQoJICogY2FuIGFkZCB0aGUgY291bnRlciBzYWZlbHksIGlmIGl0IHRoZSBjYWxsIGFib3ZlIGRpZCBub3QKCSAqIHN1Y2NlZWQuCgkgKi8KCWlmIChsaXN0X2VtcHR5KCZjb3VudGVyLT5saXN0X2VudHJ5KSkKCQlhZGRfY291bnRlcl90b19jdHgoY291bnRlciwgY3R4KTsKCXNwaW5fdW5sb2NrX2lycSgmY3R4LT5sb2NrKTsKfQoKLyoKICogQ3Jvc3MgQ1BVIGNhbGwgdG8gZW5hYmxlIGEgcGVyZm9ybWFuY2UgY291bnRlcgogKi8Kc3RhdGljIHZvaWQgX19wZXJmX2NvdW50ZXJfZW5hYmxlKHZvaWQgKmluZm8pCnsKCXN0cnVjdCBwZXJmX2NvdW50ZXIgKmNvdW50ZXIgPSBpbmZvOwoJc3RydWN0IHBlcmZfY3B1X2NvbnRleHQgKmNwdWN0eCA9ICZfX2dldF9jcHVfdmFyKHBlcmZfY3B1X2NvbnRleHQpOwoJc3RydWN0IHBlcmZfY291bnRlcl9jb250ZXh0ICpjdHggPSBjb3VudGVyLT5jdHg7CglzdHJ1Y3QgcGVyZl9jb3VudGVyICpsZWFkZXIgPSBjb3VudGVyLT5ncm91cF9sZWFkZXI7CglpbnQgZXJyOwoKCS8qCgkgKiBJZiB0aGlzIGlzIGEgcGVyLXRhc2sgY291bnRlciwgbmVlZCB0byBjaGVjayB3aGV0aGVyIHRoaXMKCSAqIGNvdW50ZXIncyB0YXNrIGlzIHRoZSBjdXJyZW50IHRhc2sgb24gdGhpcyBjcHUuCgkgKi8KCWlmIChjdHgtPnRhc2sgJiYgY3B1Y3R4LT50YXNrX2N0eCAhPSBjdHgpIHsKCQlpZiAoY3B1Y3R4LT50YXNrX2N0eCB8fCBjdHgtPnRhc2sgIT0gY3VycmVudCkKCQkJcmV0dXJuOwoJCWNwdWN0eC0+dGFza19jdHggPSBjdHg7Cgl9CgoJc3Bpbl9sb2NrKCZjdHgtPmxvY2spOwoJY3R4LT5pc19hY3RpdmUgPSAxOwoJdXBkYXRlX2NvbnRleHRfdGltZShjdHgpOwoKCWlmIChjb3VudGVyLT5zdGF0ZSA+PSBQRVJGX0NPVU5URVJfU1RBVEVfSU5BQ1RJVkUpCgkJZ290byB1bmxvY2s7Cgljb3VudGVyLT5zdGF0ZSA9IFBFUkZfQ09VTlRFUl9TVEFURV9JTkFDVElWRTsKCWNvdW50ZXItPnRzdGFtcF9lbmFibGVkID0gY3R4LT50aW1lIC0gY291bnRlci0+dG90YWxfdGltZV9lbmFibGVkOwoKCS8qCgkgKiBJZiB0aGUgY291bnRlciBpcyBpbiBhIGdyb3VwIGFuZCBpc24ndCB0aGUgZ3JvdXAgbGVhZGVyLAoJICogdGhlbiBkb24ndCBwdXQgaXQgb24gdW5sZXNzIHRoZSBncm91cCBpcyBvbi4KCSAqLwoJaWYgKGxlYWRlciAhPSBjb3VudGVyICYmIGxlYWRlci0+c3RhdGUgIT0gUEVSRl9DT1VOVEVSX1NUQVRFX0FDVElWRSkKCQlnb3RvIHVubG9jazsKCglpZiAoIWdyb3VwX2Nhbl9nb19vbihjb3VudGVyLCBjcHVjdHgsIDEpKSB7CgkJZXJyID0gLUVFWElTVDsKCX0gZWxzZSB7CgkJcGVyZl9kaXNhYmxlKCk7CgkJaWYgKGNvdW50ZXIgPT0gbGVhZGVyKQoJCQllcnIgPSBncm91cF9zY2hlZF9pbihjb3VudGVyLCBjcHVjdHgsIGN0eCwKCQkJCQkgICAgIHNtcF9wcm9jZXNzb3JfaWQoKSk7CgkJZWxzZQoJCQllcnIgPSBjb3VudGVyX3NjaGVkX2luKGNvdW50ZXIsIGNwdWN0eCwgY3R4LAoJCQkJCSAgICAgICBzbXBfcHJvY2Vzc29yX2lkKCkpOwoJCXBlcmZfZW5hYmxlKCk7Cgl9CgoJaWYgKGVycikgewoJCS8qCgkJICogSWYgdGhpcyBjb3VudGVyIGNhbid0IGdvIG9uIGFuZCBpdCdzIHBhcnQgb2YgYQoJCSAqIGdyb3VwLCB0aGVuIHRoZSB3aG9sZSBncm91cCBoYXMgdG8gY29tZSBvZmYuCgkJICovCgkJaWYgKGxlYWRlciAhPSBjb3VudGVyKQoJCQlncm91cF9zY2hlZF9vdXQobGVhZGVyLCBjcHVjdHgsIGN0eCk7CgkJaWYgKGxlYWRlci0+YXR0ci5waW5uZWQpIHsKCQkJdXBkYXRlX2dyb3VwX3RpbWVzKGxlYWRlcik7CgkJCWxlYWRlci0+c3RhdGUgPSBQRVJGX0NPVU5URVJfU1RBVEVfRVJST1I7CgkJfQoJfQoKIHVubG9jazoKCXNwaW5fdW5sb2NrKCZjdHgtPmxvY2spOwp9CgovKgogKiBFbmFibGUgYSBjb3VudGVyLgogKgogKiBJZiBjb3VudGVyLT5jdHggaXMgYSBjbG9uZWQgY29udGV4dCwgY2FsbGVycyBtdXN0IG1ha2Ugc3VyZSB0aGF0CiAqIGV2ZXJ5IHRhc2sgc3RydWN0IHRoYXQgY291bnRlci0+Y3R4LT50YXNrIGNvdWxkIHBvc3NpYmx5IHBvaW50IHRvCiAqIHJlbWFpbnMgdmFsaWQuICBUaGlzIGNvbmRpdGlvbiBpcyBzYXRpc2ZpZWQgd2hlbiBjYWxsZWQgdGhyb3VnaAogKiBwZXJmX2NvdW50ZXJfZm9yX2VhY2hfY2hpbGQgb3IgcGVyZl9jb3VudGVyX2Zvcl9lYWNoIGFzIGRlc2NyaWJlZAogKiBmb3IgcGVyZl9jb3VudGVyX2Rpc2FibGUuCiAqLwpzdGF0aWMgdm9pZCBwZXJmX2NvdW50ZXJfZW5hYmxlKHN0cnVjdCBwZXJmX2NvdW50ZXIgKmNvdW50ZXIpCnsKCXN0cnVjdCBwZXJmX2NvdW50ZXJfY29udGV4dCAqY3R4ID0gY291bnRlci0+Y3R4OwoJc3RydWN0IHRhc2tfc3RydWN0ICp0YXNrID0gY3R4LT50YXNrOwoKCWlmICghdGFzaykgewoJCS8qCgkJICogRW5hYmxlIHRoZSBjb3VudGVyIG9uIHRoZSBjcHUgdGhhdCBpdCdzIG9uCgkJICovCgkJc21wX2NhbGxfZnVuY3Rpb25fc2luZ2xlKGNvdW50ZXItPmNwdSwgX19wZXJmX2NvdW50ZXJfZW5hYmxlLAoJCQkJCSBjb3VudGVyLCAxKTsKCQlyZXR1cm47Cgl9CgoJc3Bpbl9sb2NrX2lycSgmY3R4LT5sb2NrKTsKCWlmIChjb3VudGVyLT5zdGF0ZSA+PSBQRVJGX0NPVU5URVJfU1RBVEVfSU5BQ1RJVkUpCgkJZ290byBvdXQ7CgoJLyoKCSAqIElmIHRoZSBjb3VudGVyIGlzIGluIGVycm9yIHN0YXRlLCBjbGVhciB0aGF0IGZpcnN0LgoJICogVGhhdCB3YXksIGlmIHdlIHNlZSB0aGUgY291bnRlciBpbiBlcnJvciBzdGF0ZSBiZWxvdywgd2UKCSAqIGtub3cgdGhhdCBpdCBoYXMgZ29uZSBiYWNrIGludG8gZXJyb3Igc3RhdGUsIGFzIGRpc3RpbmN0CgkgKiBmcm9tIHRoZSB0YXNrIGhhdmluZyBiZWVuIHNjaGVkdWxlZCBhd2F5IGJlZm9yZSB0aGUKCSAqIGNyb3NzLWNhbGwgYXJyaXZlZC4KCSAqLwoJaWYgKGNvdW50ZXItPnN0YXRlID09IFBFUkZfQ09VTlRFUl9TVEFURV9FUlJPUikKCQljb3VudGVyLT5zdGF0ZSA9IFBFUkZfQ09VTlRFUl9TVEFURV9PRkY7CgogcmV0cnk6CglzcGluX3VubG9ja19pcnEoJmN0eC0+bG9jayk7Cgl0YXNrX29uY3B1X2Z1bmN0aW9uX2NhbGwodGFzaywgX19wZXJmX2NvdW50ZXJfZW5hYmxlLCBjb3VudGVyKTsKCglzcGluX2xvY2tfaXJxKCZjdHgtPmxvY2spOwoKCS8qCgkgKiBJZiB0aGUgY29udGV4dCBpcyBhY3RpdmUgYW5kIHRoZSBjb3VudGVyIGlzIHN0aWxsIG9mZiwKCSAqIHdlIG5lZWQgdG8gcmV0cnkgdGhlIGNyb3NzLWNhbGwuCgkgKi8KCWlmIChjdHgtPmlzX2FjdGl2ZSAmJiBjb3VudGVyLT5zdGF0ZSA9PSBQRVJGX0NPVU5URVJfU1RBVEVfT0ZGKQoJCWdvdG8gcmV0cnk7CgoJLyoKCSAqIFNpbmNlIHdlIGhhdmUgdGhlIGxvY2sgdGhpcyBjb250ZXh0IGNhbid0IGJlIHNjaGVkdWxlZAoJICogaW4sIHNvIHdlIGNhbiBjaGFuZ2UgdGhlIHN0YXRlIHNhZmVseS4KCSAqLwoJaWYgKGNvdW50ZXItPnN0YXRlID09IFBFUkZfQ09VTlRFUl9TVEFURV9PRkYpIHsKCQljb3VudGVyLT5zdGF0ZSA9IFBFUkZfQ09VTlRFUl9TVEFURV9JTkFDVElWRTsKCQljb3VudGVyLT50c3RhbXBfZW5hYmxlZCA9CgkJCWN0eC0+dGltZSAtIGNvdW50ZXItPnRvdGFsX3RpbWVfZW5hYmxlZDsKCX0KIG91dDoKCXNwaW5fdW5sb2NrX2lycSgmY3R4LT5sb2NrKTsKfQoKc3RhdGljIGludCBwZXJmX2NvdW50ZXJfcmVmcmVzaChzdHJ1Y3QgcGVyZl9jb3VudGVyICpjb3VudGVyLCBpbnQgcmVmcmVzaCkKewoJLyoKCSAqIG5vdCBzdXBwb3J0ZWQgb24gaW5oZXJpdGVkIGNvdW50ZXJzCgkgKi8KCWlmIChjb3VudGVyLT5hdHRyLmluaGVyaXQpCgkJcmV0dXJuIC1FSU5WQUw7CgoJYXRvbWljX2FkZChyZWZyZXNoLCAmY291bnRlci0+ZXZlbnRfbGltaXQpOwoJcGVyZl9jb3VudGVyX2VuYWJsZShjb3VudGVyKTsKCglyZXR1cm4gMDsKfQoKdm9pZCBfX3BlcmZfY291bnRlcl9zY2hlZF9vdXQoc3RydWN0IHBlcmZfY291bnRlcl9jb250ZXh0ICpjdHgsCgkJCSAgICAgIHN0cnVjdCBwZXJmX2NwdV9jb250ZXh0ICpjcHVjdHgpCnsKCXN0cnVjdCBwZXJmX2NvdW50ZXIgKmNvdW50ZXI7CgoJc3Bpbl9sb2NrKCZjdHgtPmxvY2spOwoJY3R4LT5pc19hY3RpdmUgPSAwOwoJaWYgKGxpa2VseSghY3R4LT5ucl9jb3VudGVycykpCgkJZ290byBvdXQ7Cgl1cGRhdGVfY29udGV4dF90aW1lKGN0eCk7CgoJcGVyZl9kaXNhYmxlKCk7CglpZiAoY3R4LT5ucl9hY3RpdmUpIHsKCQlsaXN0X2Zvcl9lYWNoX2VudHJ5KGNvdW50ZXIsICZjdHgtPmNvdW50ZXJfbGlzdCwgbGlzdF9lbnRyeSkgewoJCQlpZiAoY291bnRlciAhPSBjb3VudGVyLT5ncm91cF9sZWFkZXIpCgkJCQljb3VudGVyX3NjaGVkX291dChjb3VudGVyLCBjcHVjdHgsIGN0eCk7CgkJCWVsc2UKCQkJCWdyb3VwX3NjaGVkX291dChjb3VudGVyLCBjcHVjdHgsIGN0eCk7CgkJfQoJfQoJcGVyZl9lbmFibGUoKTsKIG91dDoKCXNwaW5fdW5sb2NrKCZjdHgtPmxvY2spOwp9CgovKgogKiBUZXN0IHdoZXRoZXIgdHdvIGNvbnRleHRzIGFyZSBlcXVpdmFsZW50LCBpLmUuIHdoZXRoZXIgdGhleQogKiBoYXZlIGJvdGggYmVlbiBjbG9uZWQgZnJvbSB0aGUgc2FtZSB2ZXJzaW9uIG9mIHRoZSBzYW1lIGNvbnRleHQKICogYW5kIHRoZXkgYm90aCBoYXZlIHRoZSBzYW1lIG51bWJlciBvZiBlbmFibGVkIGNvdW50ZXJzLgogKiBJZiB0aGUgbnVtYmVyIG9mIGVuYWJsZWQgY291bnRlcnMgaXMgdGhlIHNhbWUsIHRoZW4gdGhlIHNldAogKiBvZiBlbmFibGVkIGNvdW50ZXJzIHNob3VsZCBiZSB0aGUgc2FtZSwgYmVjYXVzZSB0aGVzZSBhcmUgYm90aAogKiBpbmhlcml0ZWQgY29udGV4dHMsIHRoZXJlZm9yZSB3ZSBjYW4ndCBhY2Nlc3MgaW5kaXZpZHVhbCBjb3VudGVycwogKiBpbiB0aGVtIGRpcmVjdGx5IHdpdGggYW4gZmQ7IHdlIGNhbiBvbmx5IGVuYWJsZS9kaXNhYmxlIGFsbAogKiBjb3VudGVycyB2aWEgcHJjdGwsIG9yIGVuYWJsZS9kaXNhYmxlIGFsbCBjb3VudGVycyBpbiBhIGZhbWlseQogKiB2aWEgaW9jdGwsIHdoaWNoIHdpbGwgaGF2ZSB0aGUgc2FtZSBlZmZlY3Qgb24gYm90aCBjb250ZXh0cy4KICovCnN0YXRpYyBpbnQgY29udGV4dF9lcXVpdihzdHJ1Y3QgcGVyZl9jb3VudGVyX2NvbnRleHQgKmN0eDEsCgkJCSBzdHJ1Y3QgcGVyZl9jb3VudGVyX2NvbnRleHQgKmN0eDIpCnsKCXJldHVybiBjdHgxLT5wYXJlbnRfY3R4ICYmIGN0eDEtPnBhcmVudF9jdHggPT0gY3R4Mi0+cGFyZW50X2N0eAoJCSYmIGN0eDEtPnBhcmVudF9nZW4gPT0gY3R4Mi0+cGFyZW50X2dlbgoJCSYmICFjdHgxLT5waW5fY291bnQgJiYgIWN0eDItPnBpbl9jb3VudDsKfQoKc3RhdGljIHZvaWQgX19wZXJmX2NvdW50ZXJfcmVhZCh2b2lkICpjb3VudGVyKTsKCnN0YXRpYyB2b2lkIF9fcGVyZl9jb3VudGVyX3N5bmNfc3RhdChzdHJ1Y3QgcGVyZl9jb3VudGVyICpjb3VudGVyLAoJCQkJICAgICBzdHJ1Y3QgcGVyZl9jb3VudGVyICpuZXh0X2NvdW50ZXIpCnsKCXU2NCB2YWx1ZTsKCglpZiAoIWNvdW50ZXItPmF0dHIuaW5oZXJpdF9zdGF0KQoJCXJldHVybjsKCgkvKgoJICogVXBkYXRlIHRoZSBjb3VudGVyIHZhbHVlLCB3ZSBjYW5ub3QgdXNlIHBlcmZfY291bnRlcl9yZWFkKCkKCSAqIGJlY2F1c2Ugd2UncmUgaW4gdGhlIG1pZGRsZSBvZiBhIGNvbnRleHQgc3dpdGNoIGFuZCBoYXZlIElSUXMKCSAqIGRpc2FibGVkLCB3aGljaCB1cHNldHMgc21wX2NhbGxfZnVuY3Rpb25fc2luZ2xlKCksIGhvd2V2ZXIKCSAqIHdlIGtub3cgdGhlIGNvdW50ZXIgbXVzdCBiZSBvbiB0aGUgY3VycmVudCBDUFUsIHRoZXJlZm9yZSB3ZQoJICogZG9uJ3QgbmVlZCB0byB1c2UgaXQuCgkgKi8KCXN3aXRjaCAoY291bnRlci0+c3RhdGUpIHsKCWNhc2UgUEVSRl9DT1VOVEVSX1NUQVRFX0FDVElWRToKCQlfX3BlcmZfY291bnRlcl9yZWFkKGNvdW50ZXIpOwoJCWJyZWFrOwoKCWNhc2UgUEVSRl9DT1VOVEVSX1NUQVRFX0lOQUNUSVZFOgoJCXVwZGF0ZV9jb3VudGVyX3RpbWVzKGNvdW50ZXIpOwoJCWJyZWFrOwoKCWRlZmF1bHQ6CgkJYnJlYWs7Cgl9CgoJLyoKCSAqIEluIG9yZGVyIHRvIGtlZXAgcGVyLXRhc2sgc3RhdHMgcmVsaWFibGUgd2UgbmVlZCB0byBmbGlwIHRoZSBjb3VudGVyCgkgKiB2YWx1ZXMgd2hlbiB3ZSBmbGlwIHRoZSBjb250ZXh0cy4KCSAqLwoJdmFsdWUgPSBhdG9taWM2NF9yZWFkKCZuZXh0X2NvdW50ZXItPmNvdW50KTsKCXZhbHVlID0gYXRvbWljNjRfeGNoZygmY291bnRlci0+Y291bnQsIHZhbHVlKTsKCWF0b21pYzY0X3NldCgmbmV4dF9jb3VudGVyLT5jb3VudCwgdmFsdWUpOwoKCXN3YXAoY291bnRlci0+dG90YWxfdGltZV9lbmFibGVkLCBuZXh0X2NvdW50ZXItPnRvdGFsX3RpbWVfZW5hYmxlZCk7Cglzd2FwKGNvdW50ZXItPnRvdGFsX3RpbWVfcnVubmluZywgbmV4dF9jb3VudGVyLT50b3RhbF90aW1lX3J1bm5pbmcpOwoKCS8qCgkgKiBTaW5jZSB3ZSBzd2l6emxlZCB0aGUgdmFsdWVzLCB1cGRhdGUgdGhlIHVzZXIgdmlzaWJsZSBkYXRhIHRvby4KCSAqLwoJcGVyZl9jb3VudGVyX3VwZGF0ZV91c2VycGFnZShjb3VudGVyKTsKCXBlcmZfY291bnRlcl91cGRhdGVfdXNlcnBhZ2UobmV4dF9jb3VudGVyKTsKfQoKI2RlZmluZSBsaXN0X25leHRfZW50cnkocG9zLCBtZW1iZXIpIFwKCWxpc3RfZW50cnkocG9zLT5tZW1iZXIubmV4dCwgdHlwZW9mKCpwb3MpLCBtZW1iZXIpCgpzdGF0aWMgdm9pZCBwZXJmX2NvdW50ZXJfc3luY19zdGF0KHN0cnVjdCBwZXJmX2NvdW50ZXJfY29udGV4dCAqY3R4LAoJCQkJICAgc3RydWN0IHBlcmZfY291bnRlcl9jb250ZXh0ICpuZXh0X2N0eCkKewoJc3RydWN0IHBlcmZfY291bnRlciAqY291bnRlciwgKm5leHRfY291bnRlcjsKCglpZiAoIWN0eC0+bnJfc3RhdCkKCQlyZXR1cm47CgoJY291bnRlciA9IGxpc3RfZmlyc3RfZW50cnkoJmN0eC0+ZXZlbnRfbGlzdCwKCQkJCSAgIHN0cnVjdCBwZXJmX2NvdW50ZXIsIGV2ZW50X2VudHJ5KTsKCgluZXh0X2NvdW50ZXIgPSBsaXN0X2ZpcnN0X2VudHJ5KCZuZXh0X2N0eC0+ZXZlbnRfbGlzdCwKCQkJCQlzdHJ1Y3QgcGVyZl9jb3VudGVyLCBldmVudF9lbnRyeSk7CgoJd2hpbGUgKCZjb3VudGVyLT5ldmVudF9lbnRyeSAhPSAmY3R4LT5ldmVudF9saXN0ICYmCgkgICAgICAgJm5leHRfY291bnRlci0+ZXZlbnRfZW50cnkgIT0gJm5leHRfY3R4LT5ldmVudF9saXN0KSB7CgoJCV9fcGVyZl9jb3VudGVyX3N5bmNfc3RhdChjb3VudGVyLCBuZXh0X2NvdW50ZXIpOwoKCQljb3VudGVyID0gbGlzdF9uZXh0X2VudHJ5KGNvdW50ZXIsIGV2ZW50X2VudHJ5KTsKCQluZXh0X2NvdW50ZXIgPSBsaXN0X25leHRfZW50cnkoY291bnRlciwgZXZlbnRfZW50cnkpOwoJfQp9CgovKgogKiBDYWxsZWQgZnJvbSBzY2hlZHVsZXIgdG8gcmVtb3ZlIHRoZSBjb3VudGVycyBvZiB0aGUgY3VycmVudCB0YXNrLAogKiB3aXRoIGludGVycnVwdHMgZGlzYWJsZWQuCiAqCiAqIFdlIHN0b3AgZWFjaCBjb3VudGVyIGFuZCB1cGRhdGUgdGhlIGNvdW50ZXIgdmFsdWUgaW4gY291bnRlci0+Y291bnQuCiAqCiAqIFRoaXMgZG9lcyBub3QgcHJvdGVjdCB1cyBhZ2FpbnN0IE5NSSwgYnV0IGRpc2FibGUoKQogKiBzZXRzIHRoZSBkaXNhYmxlZCBiaXQgaW4gdGhlIGNvbnRyb2wgZmllbGQgb2YgY291bnRlciBfYmVmb3JlXwogKiBhY2Nlc3NpbmcgdGhlIGNvdW50ZXIgY29udHJvbCByZWdpc3Rlci4gSWYgYSBOTUkgaGl0cywgdGhlbiBpdCB3aWxsCiAqIG5vdCByZXN0YXJ0IHRoZSBjb3VudGVyLgogKi8Kdm9pZCBwZXJmX2NvdW50ZXJfdGFza19zY2hlZF9vdXQoc3RydWN0IHRhc2tfc3RydWN0ICp0YXNrLAoJCQkJIHN0cnVjdCB0YXNrX3N0cnVjdCAqbmV4dCwgaW50IGNwdSkKewoJc3RydWN0IHBlcmZfY3B1X2NvbnRleHQgKmNwdWN0eCA9ICZwZXJfY3B1KHBlcmZfY3B1X2NvbnRleHQsIGNwdSk7CglzdHJ1Y3QgcGVyZl9jb3VudGVyX2NvbnRleHQgKmN0eCA9IHRhc2stPnBlcmZfY291bnRlcl9jdHhwOwoJc3RydWN0IHBlcmZfY291bnRlcl9jb250ZXh0ICpuZXh0X2N0eDsKCXN0cnVjdCBwZXJmX2NvdW50ZXJfY29udGV4dCAqcGFyZW50OwoJc3RydWN0IHB0X3JlZ3MgKnJlZ3M7CglpbnQgZG9fc3dpdGNoID0gMTsKCglyZWdzID0gdGFza19wdF9yZWdzKHRhc2spOwoJcGVyZl9zd2NvdW50ZXJfZXZlbnQoUEVSRl9DT1VOVF9TV19DT05URVhUX1NXSVRDSEVTLCAxLCAxLCByZWdzLCAwKTsKCglpZiAobGlrZWx5KCFjdHggfHwgIWNwdWN0eC0+dGFza19jdHgpKQoJCXJldHVybjsKCgl1cGRhdGVfY29udGV4dF90aW1lKGN0eCk7CgoJcmN1X3JlYWRfbG9jaygpOwoJcGFyZW50ID0gcmN1X2RlcmVmZXJlbmNlKGN0eC0+cGFyZW50X2N0eCk7CgluZXh0X2N0eCA9IG5leHQtPnBlcmZfY291bnRlcl9jdHhwOwoJaWYgKHBhcmVudCAmJiBuZXh0X2N0eCAmJgoJICAgIHJjdV9kZXJlZmVyZW5jZShuZXh0X2N0eC0+cGFyZW50X2N0eCkgPT0gcGFyZW50KSB7CgkJLyoKCQkgKiBMb29rcyBsaWtlIHRoZSB0d28gY29udGV4dHMgYXJlIGNsb25lcywgc28gd2UgbWlnaHQgYmUKCQkgKiBhYmxlIHRvIG9wdGltaXplIHRoZSBjb250ZXh0IHN3aXRjaC4gIFdlIGxvY2sgYm90aAoJCSAqIGNvbnRleHRzIGFuZCBjaGVjayB0aGF0IHRoZXkgYXJlIGNsb25lcyB1bmRlciB0aGUKCQkgKiBsb2NrIChpbmNsdWRpbmcgcmUtY2hlY2tpbmcgdGhhdCBuZWl0aGVyIGhhcyBiZWVuCgkJICogdW5jbG9uZWQgaW4gdGhlIG1lYW50aW1lKS4gIEl0IGRvZXNuJ3QgbWF0dGVyIHdoaWNoCgkJICogb3JkZXIgd2UgdGFrZSB0aGUgbG9ja3MgYmVjYXVzZSBubyBvdGhlciBjcHUgY291bGQKCQkgKiBiZSB0cnlpbmcgdG8gbG9jayBib3RoIG9mIHRoZXNlIHRhc2tzLgoJCSAqLwoJCXNwaW5fbG9jaygmY3R4LT5sb2NrKTsKCQlzcGluX2xvY2tfbmVzdGVkKCZuZXh0X2N0eC0+bG9jaywgU0lOR0xFX0RFUFRIX05FU1RJTkcpOwoJCWlmIChjb250ZXh0X2VxdWl2KGN0eCwgbmV4dF9jdHgpKSB7CgkJCS8qCgkJCSAqIFhYWCBkbyB3ZSBuZWVkIGEgbWVtb3J5IGJhcnJpZXIgb2Ygc29ydHMKCQkJICogd3J0IHRvIHJjdV9kZXJlZmVyZW5jZSgpIG9mIHBlcmZfY291bnRlcl9jdHhwCgkJCSAqLwoJCQl0YXNrLT5wZXJmX2NvdW50ZXJfY3R4cCA9IG5leHRfY3R4OwoJCQluZXh0LT5wZXJmX2NvdW50ZXJfY3R4cCA9IGN0eDsKCQkJY3R4LT50YXNrID0gbmV4dDsKCQkJbmV4dF9jdHgtPnRhc2sgPSB0YXNrOwoJCQlkb19zd2l0Y2ggPSAwOwoKCQkJcGVyZl9jb3VudGVyX3N5bmNfc3RhdChjdHgsIG5leHRfY3R4KTsKCQl9CgkJc3Bpbl91bmxvY2soJm5leHRfY3R4LT5sb2NrKTsKCQlzcGluX3VubG9jaygmY3R4LT5sb2NrKTsKCX0KCXJjdV9yZWFkX3VubG9jaygpOwoKCWlmIChkb19zd2l0Y2gpIHsKCQlfX3BlcmZfY291bnRlcl9zY2hlZF9vdXQoY3R4LCBjcHVjdHgpOwoJCWNwdWN0eC0+dGFza19jdHggPSBOVUxMOwoJfQp9CgovKgogKiBDYWxsZWQgd2l0aCBJUlFzIGRpc2FibGVkCiAqLwpzdGF0aWMgdm9pZCBfX3BlcmZfY291bnRlcl90YXNrX3NjaGVkX291dChzdHJ1Y3QgcGVyZl9jb3VudGVyX2NvbnRleHQgKmN0eCkKewoJc3RydWN0IHBlcmZfY3B1X2NvbnRleHQgKmNwdWN0eCA9ICZfX2dldF9jcHVfdmFyKHBlcmZfY3B1X2NvbnRleHQpOwoKCWlmICghY3B1Y3R4LT50YXNrX2N0eCkKCQlyZXR1cm47CgoJaWYgKFdBUk5fT05fT05DRShjdHggIT0gY3B1Y3R4LT50YXNrX2N0eCkpCgkJcmV0dXJuOwoKCV9fcGVyZl9jb3VudGVyX3NjaGVkX291dChjdHgsIGNwdWN0eCk7CgljcHVjdHgtPnRhc2tfY3R4ID0gTlVMTDsKfQoKLyoKICogQ2FsbGVkIHdpdGggSVJRcyBkaXNhYmxlZAogKi8Kc3RhdGljIHZvaWQgcGVyZl9jb3VudGVyX2NwdV9zY2hlZF9vdXQoc3RydWN0IHBlcmZfY3B1X2NvbnRleHQgKmNwdWN0eCkKewoJX19wZXJmX2NvdW50ZXJfc2NoZWRfb3V0KCZjcHVjdHgtPmN0eCwgY3B1Y3R4KTsKfQoKc3RhdGljIHZvaWQKX19wZXJmX2NvdW50ZXJfc2NoZWRfaW4oc3RydWN0IHBlcmZfY291bnRlcl9jb250ZXh0ICpjdHgsCgkJCXN0cnVjdCBwZXJmX2NwdV9jb250ZXh0ICpjcHVjdHgsIGludCBjcHUpCnsKCXN0cnVjdCBwZXJmX2NvdW50ZXIgKmNvdW50ZXI7CglpbnQgY2FuX2FkZF9odyA9IDE7CgoJc3Bpbl9sb2NrKCZjdHgtPmxvY2spOwoJY3R4LT5pc19hY3RpdmUgPSAxOwoJaWYgKGxpa2VseSghY3R4LT5ucl9jb3VudGVycykpCgkJZ290byBvdXQ7CgoJY3R4LT50aW1lc3RhbXAgPSBwZXJmX2Nsb2NrKCk7CgoJcGVyZl9kaXNhYmxlKCk7CgoJLyoKCSAqIEZpcnN0IGdvIHRocm91Z2ggdGhlIGxpc3QgYW5kIHB1dCBvbiBhbnkgcGlubmVkIGdyb3VwcwoJICogaW4gb3JkZXIgdG8gZ2l2ZSB0aGVtIHRoZSBiZXN0IGNoYW5jZSBvZiBnb2luZyBvbi4KCSAqLwoJbGlzdF9mb3JfZWFjaF9lbnRyeShjb3VudGVyLCAmY3R4LT5jb3VudGVyX2xpc3QsIGxpc3RfZW50cnkpIHsKCQlpZiAoY291bnRlci0+c3RhdGUgPD0gUEVSRl9DT1VOVEVSX1NUQVRFX09GRiB8fAoJCSAgICAhY291bnRlci0+YXR0ci5waW5uZWQpCgkJCWNvbnRpbnVlOwoJCWlmIChjb3VudGVyLT5jcHUgIT0gLTEgJiYgY291bnRlci0+Y3B1ICE9IGNwdSkKCQkJY29udGludWU7CgoJCWlmIChjb3VudGVyICE9IGNvdW50ZXItPmdyb3VwX2xlYWRlcikKCQkJY291bnRlcl9zY2hlZF9pbihjb3VudGVyLCBjcHVjdHgsIGN0eCwgY3B1KTsKCQllbHNlIHsKCQkJaWYgKGdyb3VwX2Nhbl9nb19vbihjb3VudGVyLCBjcHVjdHgsIDEpKQoJCQkJZ3JvdXBfc2NoZWRfaW4oY291bnRlciwgY3B1Y3R4LCBjdHgsIGNwdSk7CgkJfQoKCQkvKgoJCSAqIElmIHRoaXMgcGlubmVkIGdyb3VwIGhhc24ndCBiZWVuIHNjaGVkdWxlZCwKCQkgKiBwdXQgaXQgaW4gZXJyb3Igc3RhdGUuCgkJICovCgkJaWYgKGNvdW50ZXItPnN0YXRlID09IFBFUkZfQ09VTlRFUl9TVEFURV9JTkFDVElWRSkgewoJCQl1cGRhdGVfZ3JvdXBfdGltZXMoY291bnRlcik7CgkJCWNvdW50ZXItPnN0YXRlID0gUEVSRl9DT1VOVEVSX1NUQVRFX0VSUk9SOwoJCX0KCX0KCglsaXN0X2Zvcl9lYWNoX2VudHJ5KGNvdW50ZXIsICZjdHgtPmNvdW50ZXJfbGlzdCwgbGlzdF9lbnRyeSkgewoJCS8qCgkJICogSWdub3JlIGNvdW50ZXJzIGluIE9GRiBvciBFUlJPUiBzdGF0ZSwgYW5kCgkJICogaWdub3JlIHBpbm5lZCBjb3VudGVycyBzaW5jZSB3ZSBkaWQgdGhlbSBhbHJlYWR5LgoJCSAqLwoJCWlmIChjb3VudGVyLT5zdGF0ZSA8PSBQRVJGX0NPVU5URVJfU1RBVEVfT0ZGIHx8CgkJICAgIGNvdW50ZXItPmF0dHIucGlubmVkKQoJCQljb250aW51ZTsKCgkJLyoKCQkgKiBMaXN0ZW4gdG8gdGhlICdjcHUnIHNjaGVkdWxpbmcgZmlsdGVyIGNvbnN0cmFpbnQKCQkgKiBvZiBjb3VudGVyczoKCQkgKi8KCQlpZiAoY291bnRlci0+Y3B1ICE9IC0xICYmIGNvdW50ZXItPmNwdSAhPSBjcHUpCgkJCWNvbnRpbnVlOwoKCQlpZiAoY291bnRlciAhPSBjb3VudGVyLT5ncm91cF9sZWFkZXIpIHsKCQkJaWYgKGNvdW50ZXJfc2NoZWRfaW4oY291bnRlciwgY3B1Y3R4LCBjdHgsIGNwdSkpCgkJCQljYW5fYWRkX2h3ID0gMDsKCQl9IGVsc2UgewoJCQlpZiAoZ3JvdXBfY2FuX2dvX29uKGNvdW50ZXIsIGNwdWN0eCwgY2FuX2FkZF9odykpIHsKCQkJCWlmIChncm91cF9zY2hlZF9pbihjb3VudGVyLCBjcHVjdHgsIGN0eCwgY3B1KSkKCQkJCQljYW5fYWRkX2h3ID0gMDsKCQkJfQoJCX0KCX0KCXBlcmZfZW5hYmxlKCk7CiBvdXQ6CglzcGluX3VubG9jaygmY3R4LT5sb2NrKTsKfQoKLyoKICogQ2FsbGVkIGZyb20gc2NoZWR1bGVyIHRvIGFkZCB0aGUgY291bnRlcnMgb2YgdGhlIGN1cnJlbnQgdGFzawogKiB3aXRoIGludGVycnVwdHMgZGlzYWJsZWQuCiAqCiAqIFdlIHJlc3RvcmUgdGhlIGNvdW50ZXIgdmFsdWUgYW5kIHRoZW4gZW5hYmxlIGl0LgogKgogKiBUaGlzIGRvZXMgbm90IHByb3RlY3QgdXMgYWdhaW5zdCBOTUksIGJ1dCBlbmFibGUoKQogKiBzZXRzIHRoZSBlbmFibGVkIGJpdCBpbiB0aGUgY29udHJvbCBmaWVsZCBvZiBjb3VudGVyIF9iZWZvcmVfCiAqIGFjY2Vzc2luZyB0aGUgY291bnRlciBjb250cm9sIHJlZ2lzdGVyLiBJZiBhIE5NSSBoaXRzLCB0aGVuIGl0IHdpbGwKICoga2VlcCB0aGUgY291bnRlciBydW5uaW5nLgogKi8Kdm9pZCBwZXJmX2NvdW50ZXJfdGFza19zY2hlZF9pbihzdHJ1Y3QgdGFza19zdHJ1Y3QgKnRhc2ssIGludCBjcHUpCnsKCXN0cnVjdCBwZXJmX2NwdV9jb250ZXh0ICpjcHVjdHggPSAmcGVyX2NwdShwZXJmX2NwdV9jb250ZXh0LCBjcHUpOwoJc3RydWN0IHBlcmZfY291bnRlcl9jb250ZXh0ICpjdHggPSB0YXNrLT5wZXJmX2NvdW50ZXJfY3R4cDsKCglpZiAobGlrZWx5KCFjdHgpKQoJCXJldHVybjsKCWlmIChjcHVjdHgtPnRhc2tfY3R4ID09IGN0eCkKCQlyZXR1cm47CglfX3BlcmZfY291bnRlcl9zY2hlZF9pbihjdHgsIGNwdWN0eCwgY3B1KTsKCWNwdWN0eC0+dGFza19jdHggPSBjdHg7Cn0KCnN0YXRpYyB2b2lkIHBlcmZfY291bnRlcl9jcHVfc2NoZWRfaW4oc3RydWN0IHBlcmZfY3B1X2NvbnRleHQgKmNwdWN0eCwgaW50IGNwdSkKewoJc3RydWN0IHBlcmZfY291bnRlcl9jb250ZXh0ICpjdHggPSAmY3B1Y3R4LT5jdHg7CgoJX19wZXJmX2NvdW50ZXJfc2NoZWRfaW4oY3R4LCBjcHVjdHgsIGNwdSk7Cn0KCiNkZWZpbmUgTUFYX0lOVEVSUlVQVFMgKH4wVUxMKQoKc3RhdGljIHZvaWQgcGVyZl9sb2dfdGhyb3R0bGUoc3RydWN0IHBlcmZfY291bnRlciAqY291bnRlciwgaW50IGVuYWJsZSk7CgpzdGF0aWMgdm9pZCBwZXJmX2FkanVzdF9wZXJpb2Qoc3RydWN0IHBlcmZfY291bnRlciAqY291bnRlciwgdTY0IGV2ZW50cykKewoJc3RydWN0IGh3X3BlcmZfY291bnRlciAqaHdjID0gJmNvdW50ZXItPmh3OwoJdTY0IHBlcmlvZCwgc2FtcGxlX3BlcmlvZDsKCXM2NCBkZWx0YTsKCglldmVudHMgKj0gaHdjLT5zYW1wbGVfcGVyaW9kOwoJcGVyaW9kID0gZGl2NjRfdTY0KGV2ZW50cywgY291bnRlci0+YXR0ci5zYW1wbGVfZnJlcSk7CgoJZGVsdGEgPSAoczY0KShwZXJpb2QgLSBod2MtPnNhbXBsZV9wZXJpb2QpOwoJZGVsdGEgPSAoZGVsdGEgKyA3KSAvIDg7IC8qIGxvdyBwYXNzIGZpbHRlciAqLwoKCXNhbXBsZV9wZXJpb2QgPSBod2MtPnNhbXBsZV9wZXJpb2QgKyBkZWx0YTsKCglpZiAoIXNhbXBsZV9wZXJpb2QpCgkJc2FtcGxlX3BlcmlvZCA9IDE7CgoJaHdjLT5zYW1wbGVfcGVyaW9kID0gc2FtcGxlX3BlcmlvZDsKfQoKc3RhdGljIHZvaWQgcGVyZl9jdHhfYWRqdXN0X2ZyZXEoc3RydWN0IHBlcmZfY291bnRlcl9jb250ZXh0ICpjdHgpCnsKCXN0cnVjdCBwZXJmX2NvdW50ZXIgKmNvdW50ZXI7CglzdHJ1Y3QgaHdfcGVyZl9jb3VudGVyICpod2M7Cgl1NjQgaW50ZXJydXB0cywgZnJlcTsKCglzcGluX2xvY2soJmN0eC0+bG9jayk7CglsaXN0X2Zvcl9lYWNoX2VudHJ5KGNvdW50ZXIsICZjdHgtPmNvdW50ZXJfbGlzdCwgbGlzdF9lbnRyeSkgewoJCWlmIChjb3VudGVyLT5zdGF0ZSAhPSBQRVJGX0NPVU5URVJfU1RBVEVfQUNUSVZFKQoJCQljb250aW51ZTsKCgkJaHdjID0gJmNvdW50ZXItPmh3OwoKCQlpbnRlcnJ1cHRzID0gaHdjLT5pbnRlcnJ1cHRzOwoJCWh3Yy0+aW50ZXJydXB0cyA9IDA7CgoJCS8qCgkJICogdW50aHJvdHRsZSBjb3VudGVycyBvbiB0aGUgdGljawoJCSAqLwoJCWlmIChpbnRlcnJ1cHRzID09IE1BWF9JTlRFUlJVUFRTKSB7CgkJCXBlcmZfbG9nX3Rocm90dGxlKGNvdW50ZXIsIDEpOwoJCQljb3VudGVyLT5wbXUtPnVudGhyb3R0bGUoY291bnRlcik7CgkJCWludGVycnVwdHMgPSAyKnN5c2N0bF9wZXJmX2NvdW50ZXJfc2FtcGxlX3JhdGUvSFo7CgkJfQoKCQlpZiAoIWNvdW50ZXItPmF0dHIuZnJlcSB8fCAhY291bnRlci0+YXR0ci5zYW1wbGVfZnJlcSkKCQkJY29udGludWU7CgoJCS8qCgkJICogaWYgdGhlIHNwZWNpZmllZCBmcmVxIDwgSFogdGhlbiB3ZSBuZWVkIHRvIHNraXAgdGlja3MKCQkgKi8KCQlpZiAoY291bnRlci0+YXR0ci5zYW1wbGVfZnJlcSA8IEhaKSB7CgkJCWZyZXEgPSBjb3VudGVyLT5hdHRyLnNhbXBsZV9mcmVxOwoKCQkJaHdjLT5mcmVxX2NvdW50ICs9IGZyZXE7CgkJCWh3Yy0+ZnJlcV9pbnRlcnJ1cHRzICs9IGludGVycnVwdHM7CgoJCQlpZiAoaHdjLT5mcmVxX2NvdW50IDwgSFopCgkJCQljb250aW51ZTsKCgkJCWludGVycnVwdHMgPSBod2MtPmZyZXFfaW50ZXJydXB0czsKCQkJaHdjLT5mcmVxX2ludGVycnVwdHMgPSAwOwoJCQlod2MtPmZyZXFfY291bnQgLT0gSFo7CgkJfSBlbHNlCgkJCWZyZXEgPSBIWjsKCgkJcGVyZl9hZGp1c3RfcGVyaW9kKGNvdW50ZXIsIGZyZXEgKiBpbnRlcnJ1cHRzKTsKCgkJLyoKCQkgKiBJbiBvcmRlciB0byBhdm9pZCBiZWluZyBzdGFsbGVkIGJ5IGFuIChhY2NpZGVudGFsKSBodWdlCgkJICogc2FtcGxlIHBlcmlvZCwgZm9yY2UgcmVzZXQgdGhlIHNhbXBsZSBwZXJpb2QgaWYgd2UgZGlkbid0CgkJICogZ2V0IGFueSBldmVudHMgaW4gdGhpcyBmcmVxIHBlcmlvZC4KCQkgKi8KCQlpZiAoIWludGVycnVwdHMpIHsKCQkJcGVyZl9kaXNhYmxlKCk7CgkJCWNvdW50ZXItPnBtdS0+ZGlzYWJsZShjb3VudGVyKTsKCQkJYXRvbWljNjRfc2V0KCZod2MtPnBlcmlvZF9sZWZ0LCAwKTsKCQkJY291bnRlci0+cG11LT5lbmFibGUoY291bnRlcik7CgkJCXBlcmZfZW5hYmxlKCk7CgkJfQoJfQoJc3Bpbl91bmxvY2soJmN0eC0+bG9jayk7Cn0KCi8qCiAqIFJvdW5kLXJvYmluIGEgY29udGV4dCdzIGNvdW50ZXJzOgogKi8Kc3RhdGljIHZvaWQgcm90YXRlX2N0eChzdHJ1Y3QgcGVyZl9jb3VudGVyX2NvbnRleHQgKmN0eCkKewoJc3RydWN0IHBlcmZfY291bnRlciAqY291bnRlcjsKCglpZiAoIWN0eC0+bnJfY291bnRlcnMpCgkJcmV0dXJuOwoKCXNwaW5fbG9jaygmY3R4LT5sb2NrKTsKCS8qCgkgKiBSb3RhdGUgdGhlIGZpcnN0IGVudHJ5IGxhc3QgKHdvcmtzIGp1c3QgZmluZSBmb3IgZ3JvdXAgY291bnRlcnMgdG9vKToKCSAqLwoJcGVyZl9kaXNhYmxlKCk7CglsaXN0X2Zvcl9lYWNoX2VudHJ5KGNvdW50ZXIsICZjdHgtPmNvdW50ZXJfbGlzdCwgbGlzdF9lbnRyeSkgewoJCWxpc3RfbW92ZV90YWlsKCZjb3VudGVyLT5saXN0X2VudHJ5LCAmY3R4LT5jb3VudGVyX2xpc3QpOwoJCWJyZWFrOwoJfQoJcGVyZl9lbmFibGUoKTsKCglzcGluX3VubG9jaygmY3R4LT5sb2NrKTsKfQoKdm9pZCBwZXJmX2NvdW50ZXJfdGFza190aWNrKHN0cnVjdCB0YXNrX3N0cnVjdCAqY3VyciwgaW50IGNwdSkKewoJc3RydWN0IHBlcmZfY3B1X2NvbnRleHQgKmNwdWN0eDsKCXN0cnVjdCBwZXJmX2NvdW50ZXJfY29udGV4dCAqY3R4OwoKCWlmICghYXRvbWljX3JlYWQoJm5yX2NvdW50ZXJzKSkKCQlyZXR1cm47CgoJY3B1Y3R4ID0gJnBlcl9jcHUocGVyZl9jcHVfY29udGV4dCwgY3B1KTsKCWN0eCA9IGN1cnItPnBlcmZfY291bnRlcl9jdHhwOwoKCXBlcmZfY3R4X2FkanVzdF9mcmVxKCZjcHVjdHgtPmN0eCk7CglpZiAoY3R4KQoJCXBlcmZfY3R4X2FkanVzdF9mcmVxKGN0eCk7CgoJcGVyZl9jb3VudGVyX2NwdV9zY2hlZF9vdXQoY3B1Y3R4KTsKCWlmIChjdHgpCgkJX19wZXJmX2NvdW50ZXJfdGFza19zY2hlZF9vdXQoY3R4KTsKCglyb3RhdGVfY3R4KCZjcHVjdHgtPmN0eCk7CglpZiAoY3R4KQoJCXJvdGF0ZV9jdHgoY3R4KTsKCglwZXJmX2NvdW50ZXJfY3B1X3NjaGVkX2luKGNwdWN0eCwgY3B1KTsKCWlmIChjdHgpCgkJcGVyZl9jb3VudGVyX3Rhc2tfc2NoZWRfaW4oY3VyciwgY3B1KTsKfQoKLyoKICogRW5hYmxlIGFsbCBvZiBhIHRhc2sncyBjb3VudGVycyB0aGF0IGhhdmUgYmVlbiBtYXJrZWQgZW5hYmxlLW9uLWV4ZWMuCiAqIFRoaXMgZXhwZWN0cyB0YXNrID09IGN1cnJlbnQuCiAqLwpzdGF0aWMgdm9pZCBwZXJmX2NvdW50ZXJfZW5hYmxlX29uX2V4ZWMoc3RydWN0IHRhc2tfc3RydWN0ICp0YXNrKQp7CglzdHJ1Y3QgcGVyZl9jb3VudGVyX2NvbnRleHQgKmN0eDsKCXN0cnVjdCBwZXJmX2NvdW50ZXIgKmNvdW50ZXI7Cgl1bnNpZ25lZCBsb25nIGZsYWdzOwoJaW50IGVuYWJsZWQgPSAwOwoKCWxvY2FsX2lycV9zYXZlKGZsYWdzKTsKCWN0eCA9IHRhc2stPnBlcmZfY291bnRlcl9jdHhwOwoJaWYgKCFjdHggfHwgIWN0eC0+bnJfY291bnRlcnMpCgkJZ290byBvdXQ7CgoJX19wZXJmX2NvdW50ZXJfdGFza19zY2hlZF9vdXQoY3R4KTsKCglzcGluX2xvY2soJmN0eC0+bG9jayk7CgoJbGlzdF9mb3JfZWFjaF9lbnRyeShjb3VudGVyLCAmY3R4LT5jb3VudGVyX2xpc3QsIGxpc3RfZW50cnkpIHsKCQlpZiAoIWNvdW50ZXItPmF0dHIuZW5hYmxlX29uX2V4ZWMpCgkJCWNvbnRpbnVlOwoJCWNvdW50ZXItPmF0dHIuZW5hYmxlX29uX2V4ZWMgPSAwOwoJCWlmIChjb3VudGVyLT5zdGF0ZSA+PSBQRVJGX0NPVU5URVJfU1RBVEVfSU5BQ1RJVkUpCgkJCWNvbnRpbnVlOwoJCWNvdW50ZXItPnN0YXRlID0gUEVSRl9DT1VOVEVSX1NUQVRFX0lOQUNUSVZFOwoJCWNvdW50ZXItPnRzdGFtcF9lbmFibGVkID0KCQkJY3R4LT50aW1lIC0gY291bnRlci0+dG90YWxfdGltZV9lbmFibGVkOwoJCWVuYWJsZWQgPSAxOwoJfQoKCS8qCgkgKiBVbmNsb25lIHRoaXMgY29udGV4dCBpZiB3ZSBlbmFibGVkIGFueSBjb3VudGVyLgoJICovCglpZiAoZW5hYmxlZCkKCQl1bmNsb25lX2N0eChjdHgpOwoKCXNwaW5fdW5sb2NrKCZjdHgtPmxvY2spOwoKCXBlcmZfY291bnRlcl90YXNrX3NjaGVkX2luKHRhc2ssIHNtcF9wcm9jZXNzb3JfaWQoKSk7CiBvdXQ6Cglsb2NhbF9pcnFfcmVzdG9yZShmbGFncyk7Cn0KCi8qCiAqIENyb3NzIENQVSBjYWxsIHRvIHJlYWQgdGhlIGhhcmR3YXJlIGNvdW50ZXIKICovCnN0YXRpYyB2b2lkIF9fcGVyZl9jb3VudGVyX3JlYWQodm9pZCAqaW5mbykKewoJc3RydWN0IHBlcmZfY291bnRlciAqY291bnRlciA9IGluZm87CglzdHJ1Y3QgcGVyZl9jb3VudGVyX2NvbnRleHQgKmN0eCA9IGNvdW50ZXItPmN0eDsKCXVuc2lnbmVkIGxvbmcgZmxhZ3M7CgoJbG9jYWxfaXJxX3NhdmUoZmxhZ3MpOwoJaWYgKGN0eC0+aXNfYWN0aXZlKQoJCXVwZGF0ZV9jb250ZXh0X3RpbWUoY3R4KTsKCWNvdW50ZXItPnBtdS0+cmVhZChjb3VudGVyKTsKCXVwZGF0ZV9jb3VudGVyX3RpbWVzKGNvdW50ZXIpOwoJbG9jYWxfaXJxX3Jlc3RvcmUoZmxhZ3MpOwp9CgpzdGF0aWMgdTY0IHBlcmZfY291bnRlcl9yZWFkKHN0cnVjdCBwZXJmX2NvdW50ZXIgKmNvdW50ZXIpCnsKCS8qCgkgKiBJZiBjb3VudGVyIGlzIGVuYWJsZWQgYW5kIGN1cnJlbnRseSBhY3RpdmUgb24gYSBDUFUsIHVwZGF0ZSB0aGUKCSAqIHZhbHVlIGluIHRoZSBjb3VudGVyIHN0cnVjdHVyZToKCSAqLwoJaWYgKGNvdW50ZXItPnN0YXRlID09IFBFUkZfQ09VTlRFUl9TVEFURV9BQ1RJVkUpIHsKCQlzbXBfY2FsbF9mdW5jdGlvbl9zaW5nbGUoY291bnRlci0+b25jcHUsCgkJCQkJIF9fcGVyZl9jb3VudGVyX3JlYWQsIGNvdW50ZXIsIDEpOwoJfSBlbHNlIGlmIChjb3VudGVyLT5zdGF0ZSA9PSBQRVJGX0NPVU5URVJfU1RBVEVfSU5BQ1RJVkUpIHsKCQl1cGRhdGVfY291bnRlcl90aW1lcyhjb3VudGVyKTsKCX0KCglyZXR1cm4gYXRvbWljNjRfcmVhZCgmY291bnRlci0+Y291bnQpOwp9CgovKgogKiBJbml0aWFsaXplIHRoZSBwZXJmX2NvdW50ZXIgY29udGV4dCBpbiBhIHRhc2tfc3RydWN0OgogKi8Kc3RhdGljIHZvaWQKX19wZXJmX2NvdW50ZXJfaW5pdF9jb250ZXh0KHN0cnVjdCBwZXJmX2NvdW50ZXJfY29udGV4dCAqY3R4LAoJCQkgICAgc3RydWN0IHRhc2tfc3RydWN0ICp0YXNrKQp7CgltZW1zZXQoY3R4LCAwLCBzaXplb2YoKmN0eCkpOwoJc3Bpbl9sb2NrX2luaXQoJmN0eC0+bG9jayk7CgltdXRleF9pbml0KCZjdHgtPm11dGV4KTsKCUlOSVRfTElTVF9IRUFEKCZjdHgtPmNvdW50ZXJfbGlzdCk7CglJTklUX0xJU1RfSEVBRCgmY3R4LT5ldmVudF9saXN0KTsKCWF0b21pY19zZXQoJmN0eC0+cmVmY291bnQsIDEpOwoJY3R4LT50YXNrID0gdGFzazsKfQoKc3RhdGljIHN0cnVjdCBwZXJmX2NvdW50ZXJfY29udGV4dCAqZmluZF9nZXRfY29udGV4dChwaWRfdCBwaWQsIGludCBjcHUpCnsKCXN0cnVjdCBwZXJmX2NvdW50ZXJfY29udGV4dCAqY3R4OwoJc3RydWN0IHBlcmZfY3B1X2NvbnRleHQgKmNwdWN0eDsKCXN0cnVjdCB0YXNrX3N0cnVjdCAqdGFzazsKCXVuc2lnbmVkIGxvbmcgZmxhZ3M7CglpbnQgZXJyOwoKCS8qCgkgKiBJZiBjcHUgaXMgbm90IGEgd2lsZGNhcmQgdGhlbiB0aGlzIGlzIGEgcGVyY3B1IGNvdW50ZXI6CgkgKi8KCWlmIChjcHUgIT0gLTEpIHsKCQkvKiBNdXN0IGJlIHJvb3QgdG8gb3BlcmF0ZSBvbiBhIENQVSBjb3VudGVyOiAqLwoJCWlmIChwZXJmX3BhcmFub2lkX2NwdSgpICYmICFjYXBhYmxlKENBUF9TWVNfQURNSU4pKQoJCQlyZXR1cm4gRVJSX1BUUigtRUFDQ0VTKTsKCgkJaWYgKGNwdSA8IDAgfHwgY3B1ID4gbnVtX3Bvc3NpYmxlX2NwdXMoKSkKCQkJcmV0dXJuIEVSUl9QVFIoLUVJTlZBTCk7CgoJCS8qCgkJICogV2UgY291bGQgYmUgY2xldmVyIGFuZCBhbGxvdyB0byBhdHRhY2ggYSBjb3VudGVyIHRvIGFuCgkJICogb2ZmbGluZSBDUFUgYW5kIGFjdGl2YXRlIGl0IHdoZW4gdGhlIENQVSBjb21lcyB1cCwgYnV0CgkJICogdGhhdCdzIGZvciBsYXRlci4KCQkgKi8KCQlpZiAoIWNwdV9pc3NldChjcHUsIGNwdV9vbmxpbmVfbWFwKSkKCQkJcmV0dXJuIEVSUl9QVFIoLUVOT0RFVik7CgoJCWNwdWN0eCA9ICZwZXJfY3B1KHBlcmZfY3B1X2NvbnRleHQsIGNwdSk7CgkJY3R4ID0gJmNwdWN0eC0+Y3R4OwoJCWdldF9jdHgoY3R4KTsKCgkJcmV0dXJuIGN0eDsKCX0KCglyY3VfcmVhZF9sb2NrKCk7CglpZiAoIXBpZCkKCQl0YXNrID0gY3VycmVudDsKCWVsc2UKCQl0YXNrID0gZmluZF90YXNrX2J5X3ZwaWQocGlkKTsKCWlmICh0YXNrKQoJCWdldF90YXNrX3N0cnVjdCh0YXNrKTsKCXJjdV9yZWFkX3VubG9jaygpOwoKCWlmICghdGFzaykKCQlyZXR1cm4gRVJSX1BUUigtRVNSQ0gpOwoKCS8qCgkgKiBDYW4ndCBhdHRhY2ggY291bnRlcnMgdG8gYSBkeWluZyB0YXNrLgoJICovCgllcnIgPSAtRVNSQ0g7CglpZiAodGFzay0+ZmxhZ3MgJiBQRl9FWElUSU5HKQoJCWdvdG8gZXJyb3V0OwoKCS8qIFJldXNlIHB0cmFjZSBwZXJtaXNzaW9uIGNoZWNrcyBmb3Igbm93LiAqLwoJZXJyID0gLUVBQ0NFUzsKCWlmICghcHRyYWNlX21heV9hY2Nlc3ModGFzaywgUFRSQUNFX01PREVfUkVBRCkpCgkJZ290byBlcnJvdXQ7CgogcmV0cnk6CgljdHggPSBwZXJmX2xvY2tfdGFza19jb250ZXh0KHRhc2ssICZmbGFncyk7CglpZiAoY3R4KSB7CgkJdW5jbG9uZV9jdHgoY3R4KTsKCQlzcGluX3VubG9ja19pcnFyZXN0b3JlKCZjdHgtPmxvY2ssIGZsYWdzKTsKCX0KCglpZiAoIWN0eCkgewoJCWN0eCA9IGttYWxsb2Moc2l6ZW9mKHN0cnVjdCBwZXJmX2NvdW50ZXJfY29udGV4dCksIEdGUF9LRVJORUwpOwoJCWVyciA9IC1FTk9NRU07CgkJaWYgKCFjdHgpCgkJCWdvdG8gZXJyb3V0OwoJCV9fcGVyZl9jb3VudGVyX2luaXRfY29udGV4dChjdHgsIHRhc2spOwoJCWdldF9jdHgoY3R4KTsKCQlpZiAoY21weGNoZygmdGFzay0+cGVyZl9jb3VudGVyX2N0eHAsIE5VTEwsIGN0eCkpIHsKCQkJLyoKCQkJICogV2UgcmFjZWQgd2l0aCBzb21lIG90aGVyIHRhc2s7IHVzZQoJCQkgKiB0aGUgY29udGV4dCB0aGV5IHNldC4KCQkJICovCgkJCWtmcmVlKGN0eCk7CgkJCWdvdG8gcmV0cnk7CgkJfQoJCWdldF90YXNrX3N0cnVjdCh0YXNrKTsKCX0KCglwdXRfdGFza19zdHJ1Y3QodGFzayk7CglyZXR1cm4gY3R4OwoKIGVycm91dDoKCXB1dF90YXNrX3N0cnVjdCh0YXNrKTsKCXJldHVybiBFUlJfUFRSKGVycik7Cn0KCnN0YXRpYyB2b2lkIGZyZWVfY291bnRlcl9yY3Uoc3RydWN0IHJjdV9oZWFkICpoZWFkKQp7CglzdHJ1Y3QgcGVyZl9jb3VudGVyICpjb3VudGVyOwoKCWNvdW50ZXIgPSBjb250YWluZXJfb2YoaGVhZCwgc3RydWN0IHBlcmZfY291bnRlciwgcmN1X2hlYWQpOwoJaWYgKGNvdW50ZXItPm5zKQoJCXB1dF9waWRfbnMoY291bnRlci0+bnMpOwoJa2ZyZWUoY291bnRlcik7Cn0KCnN0YXRpYyB2b2lkIHBlcmZfcGVuZGluZ19zeW5jKHN0cnVjdCBwZXJmX2NvdW50ZXIgKmNvdW50ZXIpOwoKc3RhdGljIHZvaWQgZnJlZV9jb3VudGVyKHN0cnVjdCBwZXJmX2NvdW50ZXIgKmNvdW50ZXIpCnsKCXBlcmZfcGVuZGluZ19zeW5jKGNvdW50ZXIpOwoKCWlmICghY291bnRlci0+cGFyZW50KSB7CgkJYXRvbWljX2RlYygmbnJfY291bnRlcnMpOwoJCWlmIChjb3VudGVyLT5hdHRyLm1tYXApCgkJCWF0b21pY19kZWMoJm5yX21tYXBfY291bnRlcnMpOwoJCWlmIChjb3VudGVyLT5hdHRyLmNvbW0pCgkJCWF0b21pY19kZWMoJm5yX2NvbW1fY291bnRlcnMpOwoJfQoKCWlmIChjb3VudGVyLT5kZXN0cm95KQoJCWNvdW50ZXItPmRlc3Ryb3koY291bnRlcik7CgoJcHV0X2N0eChjb3VudGVyLT5jdHgpOwoJY2FsbF9yY3UoJmNvdW50ZXItPnJjdV9oZWFkLCBmcmVlX2NvdW50ZXJfcmN1KTsKfQoKLyoKICogQ2FsbGVkIHdoZW4gdGhlIGxhc3QgcmVmZXJlbmNlIHRvIHRoZSBmaWxlIGlzIGdvbmUuCiAqLwpzdGF0aWMgaW50IHBlcmZfcmVsZWFzZShzdHJ1Y3QgaW5vZGUgKmlub2RlLCBzdHJ1Y3QgZmlsZSAqZmlsZSkKewoJc3RydWN0IHBlcmZfY291bnRlciAqY291bnRlciA9IGZpbGUtPnByaXZhdGVfZGF0YTsKCXN0cnVjdCBwZXJmX2NvdW50ZXJfY29udGV4dCAqY3R4ID0gY291bnRlci0+Y3R4OwoKCWZpbGUtPnByaXZhdGVfZGF0YSA9IE5VTEw7CgoJV0FSTl9PTl9PTkNFKGN0eC0+cGFyZW50X2N0eCk7CgltdXRleF9sb2NrKCZjdHgtPm11dGV4KTsKCXBlcmZfY291bnRlcl9yZW1vdmVfZnJvbV9jb250ZXh0KGNvdW50ZXIpOwoJbXV0ZXhfdW5sb2NrKCZjdHgtPm11dGV4KTsKCgltdXRleF9sb2NrKCZjb3VudGVyLT5vd25lci0+cGVyZl9jb3VudGVyX211dGV4KTsKCWxpc3RfZGVsX2luaXQoJmNvdW50ZXItPm93bmVyX2VudHJ5KTsKCW11dGV4X3VubG9jaygmY291bnRlci0+b3duZXItPnBlcmZfY291bnRlcl9tdXRleCk7CglwdXRfdGFza19zdHJ1Y3QoY291bnRlci0+b3duZXIpOwoKCWZyZWVfY291bnRlcihjb3VudGVyKTsKCglyZXR1cm4gMDsKfQoKLyoKICogUmVhZCB0aGUgcGVyZm9ybWFuY2UgY291bnRlciAtIHNpbXBsZSBub24gYmxvY2tpbmcgdmVyc2lvbiBmb3Igbm93CiAqLwpzdGF0aWMgc3NpemVfdApwZXJmX3JlYWRfaHcoc3RydWN0IHBlcmZfY291bnRlciAqY291bnRlciwgY2hhciBfX3VzZXIgKmJ1Ziwgc2l6ZV90IGNvdW50KQp7Cgl1NjQgdmFsdWVzWzRdOwoJaW50IG47CgoJLyoKCSAqIFJldHVybiBlbmQtb2YtZmlsZSBmb3IgYSByZWFkIG9uIGEgY291bnRlciB0aGF0IGlzIGluCgkgKiBlcnJvciBzdGF0ZSAoaS5lLiBiZWNhdXNlIGl0IHdhcyBwaW5uZWQgYnV0IGl0IGNvdWxkbid0IGJlCgkgKiBzY2hlZHVsZWQgb24gdG8gdGhlIENQVSBhdCBzb21lIHBvaW50KS4KCSAqLwoJaWYgKGNvdW50ZXItPnN0YXRlID09IFBFUkZfQ09VTlRFUl9TVEFURV9FUlJPUikKCQlyZXR1cm4gMDsKCglXQVJOX09OX09OQ0UoY291bnRlci0+Y3R4LT5wYXJlbnRfY3R4KTsKCW11dGV4X2xvY2soJmNvdW50ZXItPmNoaWxkX211dGV4KTsKCXZhbHVlc1swXSA9IHBlcmZfY291bnRlcl9yZWFkKGNvdW50ZXIpOwoJbiA9IDE7CglpZiAoY291bnRlci0+YXR0ci5yZWFkX2Zvcm1hdCAmIFBFUkZfRk9STUFUX1RPVEFMX1RJTUVfRU5BQkxFRCkKCQl2YWx1ZXNbbisrXSA9IGNvdW50ZXItPnRvdGFsX3RpbWVfZW5hYmxlZCArCgkJCWF0b21pYzY0X3JlYWQoJmNvdW50ZXItPmNoaWxkX3RvdGFsX3RpbWVfZW5hYmxlZCk7CglpZiAoY291bnRlci0+YXR0ci5yZWFkX2Zvcm1hdCAmIFBFUkZfRk9STUFUX1RPVEFMX1RJTUVfUlVOTklORykKCQl2YWx1ZXNbbisrXSA9IGNvdW50ZXItPnRvdGFsX3RpbWVfcnVubmluZyArCgkJCWF0b21pYzY0X3JlYWQoJmNvdW50ZXItPmNoaWxkX3RvdGFsX3RpbWVfcnVubmluZyk7CglpZiAoY291bnRlci0+YXR0ci5yZWFkX2Zvcm1hdCAmIFBFUkZfRk9STUFUX0lEKQoJCXZhbHVlc1tuKytdID0gcHJpbWFyeV9jb3VudGVyX2lkKGNvdW50ZXIpOwoJbXV0ZXhfdW5sb2NrKCZjb3VudGVyLT5jaGlsZF9tdXRleCk7CgoJaWYgKGNvdW50IDwgbiAqIHNpemVvZih1NjQpKQoJCXJldHVybiAtRUlOVkFMOwoJY291bnQgPSBuICogc2l6ZW9mKHU2NCk7CgoJaWYgKGNvcHlfdG9fdXNlcihidWYsIHZhbHVlcywgY291bnQpKQoJCXJldHVybiAtRUZBVUxUOwoKCXJldHVybiBjb3VudDsKfQoKc3RhdGljIHNzaXplX3QKcGVyZl9yZWFkKHN0cnVjdCBmaWxlICpmaWxlLCBjaGFyIF9fdXNlciAqYnVmLCBzaXplX3QgY291bnQsIGxvZmZfdCAqcHBvcykKewoJc3RydWN0IHBlcmZfY291bnRlciAqY291bnRlciA9IGZpbGUtPnByaXZhdGVfZGF0YTsKCglyZXR1cm4gcGVyZl9yZWFkX2h3KGNvdW50ZXIsIGJ1ZiwgY291bnQpOwp9CgpzdGF0aWMgdW5zaWduZWQgaW50IHBlcmZfcG9sbChzdHJ1Y3QgZmlsZSAqZmlsZSwgcG9sbF90YWJsZSAqd2FpdCkKewoJc3RydWN0IHBlcmZfY291bnRlciAqY291bnRlciA9IGZpbGUtPnByaXZhdGVfZGF0YTsKCXN0cnVjdCBwZXJmX21tYXBfZGF0YSAqZGF0YTsKCXVuc2lnbmVkIGludCBldmVudHMgPSBQT0xMX0hVUDsKCglyY3VfcmVhZF9sb2NrKCk7CglkYXRhID0gcmN1X2RlcmVmZXJlbmNlKGNvdW50ZXItPmRhdGEpOwoJaWYgKGRhdGEpCgkJZXZlbnRzID0gYXRvbWljX3hjaGcoJmRhdGEtPnBvbGwsIDApOwoJcmN1X3JlYWRfdW5sb2NrKCk7CgoJcG9sbF93YWl0KGZpbGUsICZjb3VudGVyLT53YWl0cSwgd2FpdCk7CgoJcmV0dXJuIGV2ZW50czsKfQoKc3RhdGljIHZvaWQgcGVyZl9jb3VudGVyX3Jlc2V0KHN0cnVjdCBwZXJmX2NvdW50ZXIgKmNvdW50ZXIpCnsKCSh2b2lkKXBlcmZfY291bnRlcl9yZWFkKGNvdW50ZXIpOwoJYXRvbWljNjRfc2V0KCZjb3VudGVyLT5jb3VudCwgMCk7CglwZXJmX2NvdW50ZXJfdXBkYXRlX3VzZXJwYWdlKGNvdW50ZXIpOwp9CgovKgogKiBIb2xkaW5nIHRoZSB0b3AtbGV2ZWwgY291bnRlcidzIGNoaWxkX211dGV4IG1lYW5zIHRoYXQgYW55CiAqIGRlc2NlbmRhbnQgcHJvY2VzcyB0aGF0IGhhcyBpbmhlcml0ZWQgdGhpcyBjb3VudGVyIHdpbGwgYmxvY2sKICogaW4gc3luY19jaGlsZF9jb3VudGVyIGlmIGl0IGdvZXMgdG8gZXhpdCwgdGh1cyBzYXRpc2Z5aW5nIHRoZQogKiB0YXNrIGV4aXN0ZW5jZSByZXF1aXJlbWVudHMgb2YgcGVyZl9jb3VudGVyX2VuYWJsZS9kaXNhYmxlLgogKi8Kc3RhdGljIHZvaWQgcGVyZl9jb3VudGVyX2Zvcl9lYWNoX2NoaWxkKHN0cnVjdCBwZXJmX2NvdW50ZXIgKmNvdW50ZXIsCgkJCQkJdm9pZCAoKmZ1bmMpKHN0cnVjdCBwZXJmX2NvdW50ZXIgKikpCnsKCXN0cnVjdCBwZXJmX2NvdW50ZXIgKmNoaWxkOwoKCVdBUk5fT05fT05DRShjb3VudGVyLT5jdHgtPnBhcmVudF9jdHgpOwoJbXV0ZXhfbG9jaygmY291bnRlci0+Y2hpbGRfbXV0ZXgpOwoJZnVuYyhjb3VudGVyKTsKCWxpc3RfZm9yX2VhY2hfZW50cnkoY2hpbGQsICZjb3VudGVyLT5jaGlsZF9saXN0LCBjaGlsZF9saXN0KQoJCWZ1bmMoY2hpbGQpOwoJbXV0ZXhfdW5sb2NrKCZjb3VudGVyLT5jaGlsZF9tdXRleCk7Cn0KCnN0YXRpYyB2b2lkIHBlcmZfY291bnRlcl9mb3JfZWFjaChzdHJ1Y3QgcGVyZl9jb3VudGVyICpjb3VudGVyLAoJCQkJICB2b2lkICgqZnVuYykoc3RydWN0IHBlcmZfY291bnRlciAqKSkKewoJc3RydWN0IHBlcmZfY291bnRlcl9jb250ZXh0ICpjdHggPSBjb3VudGVyLT5jdHg7CglzdHJ1Y3QgcGVyZl9jb3VudGVyICpzaWJsaW5nOwoKCVdBUk5fT05fT05DRShjdHgtPnBhcmVudF9jdHgpOwoJbXV0ZXhfbG9jaygmY3R4LT5tdXRleCk7Cgljb3VudGVyID0gY291bnRlci0+Z3JvdXBfbGVhZGVyOwoKCXBlcmZfY291bnRlcl9mb3JfZWFjaF9jaGlsZChjb3VudGVyLCBmdW5jKTsKCWZ1bmMoY291bnRlcik7CglsaXN0X2Zvcl9lYWNoX2VudHJ5KHNpYmxpbmcsICZjb3VudGVyLT5zaWJsaW5nX2xpc3QsIGxpc3RfZW50cnkpCgkJcGVyZl9jb3VudGVyX2Zvcl9lYWNoX2NoaWxkKGNvdW50ZXIsIGZ1bmMpOwoJbXV0ZXhfdW5sb2NrKCZjdHgtPm11dGV4KTsKfQoKc3RhdGljIGludCBwZXJmX2NvdW50ZXJfcGVyaW9kKHN0cnVjdCBwZXJmX2NvdW50ZXIgKmNvdW50ZXIsIHU2NCBfX3VzZXIgKmFyZykKewoJc3RydWN0IHBlcmZfY291bnRlcl9jb250ZXh0ICpjdHggPSBjb3VudGVyLT5jdHg7Cgl1bnNpZ25lZCBsb25nIHNpemU7CglpbnQgcmV0ID0gMDsKCXU2NCB2YWx1ZTsKCglpZiAoIWNvdW50ZXItPmF0dHIuc2FtcGxlX3BlcmlvZCkKCQlyZXR1cm4gLUVJTlZBTDsKCglzaXplID0gY29weV9mcm9tX3VzZXIoJnZhbHVlLCBhcmcsIHNpemVvZih2YWx1ZSkpOwoJaWYgKHNpemUgIT0gc2l6ZW9mKHZhbHVlKSkKCQlyZXR1cm4gLUVGQVVMVDsKCglpZiAoIXZhbHVlKQoJCXJldHVybiAtRUlOVkFMOwoKCXNwaW5fbG9ja19pcnEoJmN0eC0+bG9jayk7CglpZiAoY291bnRlci0+YXR0ci5mcmVxKSB7CgkJaWYgKHZhbHVlID4gc3lzY3RsX3BlcmZfY291bnRlcl9zYW1wbGVfcmF0ZSkgewoJCQlyZXQgPSAtRUlOVkFMOwoJCQlnb3RvIHVubG9jazsKCQl9CgoJCWNvdW50ZXItPmF0dHIuc2FtcGxlX2ZyZXEgPSB2YWx1ZTsKCX0gZWxzZSB7CgkJY291bnRlci0+YXR0ci5zYW1wbGVfcGVyaW9kID0gdmFsdWU7CgkJY291bnRlci0+aHcuc2FtcGxlX3BlcmlvZCA9IHZhbHVlOwoJfQp1bmxvY2s6CglzcGluX3VubG9ja19pcnEoJmN0eC0+bG9jayk7CgoJcmV0dXJuIHJldDsKfQoKc3RhdGljIGxvbmcgcGVyZl9pb2N0bChzdHJ1Y3QgZmlsZSAqZmlsZSwgdW5zaWduZWQgaW50IGNtZCwgdW5zaWduZWQgbG9uZyBhcmcpCnsKCXN0cnVjdCBwZXJmX2NvdW50ZXIgKmNvdW50ZXIgPSBmaWxlLT5wcml2YXRlX2RhdGE7Cgl2b2lkICgqZnVuYykoc3RydWN0IHBlcmZfY291bnRlciAqKTsKCXUzMiBmbGFncyA9IGFyZzsKCglzd2l0Y2ggKGNtZCkgewoJY2FzZSBQRVJGX0NPVU5URVJfSU9DX0VOQUJMRToKCQlmdW5jID0gcGVyZl9jb3VudGVyX2VuYWJsZTsKCQlicmVhazsKCWNhc2UgUEVSRl9DT1VOVEVSX0lPQ19ESVNBQkxFOgoJCWZ1bmMgPSBwZXJmX2NvdW50ZXJfZGlzYWJsZTsKCQlicmVhazsKCWNhc2UgUEVSRl9DT1VOVEVSX0lPQ19SRVNFVDoKCQlmdW5jID0gcGVyZl9jb3VudGVyX3Jlc2V0OwoJCWJyZWFrOwoKCWNhc2UgUEVSRl9DT1VOVEVSX0lPQ19SRUZSRVNIOgoJCXJldHVybiBwZXJmX2NvdW50ZXJfcmVmcmVzaChjb3VudGVyLCBhcmcpOwoKCWNhc2UgUEVSRl9DT1VOVEVSX0lPQ19QRVJJT0Q6CgkJcmV0dXJuIHBlcmZfY291bnRlcl9wZXJpb2QoY291bnRlciwgKHU2NCBfX3VzZXIgKilhcmcpOwoKCWRlZmF1bHQ6CgkJcmV0dXJuIC1FTk9UVFk7Cgl9CgoJaWYgKGZsYWdzICYgUEVSRl9JT0NfRkxBR19HUk9VUCkKCQlwZXJmX2NvdW50ZXJfZm9yX2VhY2goY291bnRlciwgZnVuYyk7CgllbHNlCgkJcGVyZl9jb3VudGVyX2Zvcl9lYWNoX2NoaWxkKGNvdW50ZXIsIGZ1bmMpOwoKCXJldHVybiAwOwp9CgppbnQgcGVyZl9jb3VudGVyX3Rhc2tfZW5hYmxlKHZvaWQpCnsKCXN0cnVjdCBwZXJmX2NvdW50ZXIgKmNvdW50ZXI7CgoJbXV0ZXhfbG9jaygmY3VycmVudC0+cGVyZl9jb3VudGVyX211dGV4KTsKCWxpc3RfZm9yX2VhY2hfZW50cnkoY291bnRlciwgJmN1cnJlbnQtPnBlcmZfY291bnRlcl9saXN0LCBvd25lcl9lbnRyeSkKCQlwZXJmX2NvdW50ZXJfZm9yX2VhY2hfY2hpbGQoY291bnRlciwgcGVyZl9jb3VudGVyX2VuYWJsZSk7CgltdXRleF91bmxvY2soJmN1cnJlbnQtPnBlcmZfY291bnRlcl9tdXRleCk7CgoJcmV0dXJuIDA7Cn0KCmludCBwZXJmX2NvdW50ZXJfdGFza19kaXNhYmxlKHZvaWQpCnsKCXN0cnVjdCBwZXJmX2NvdW50ZXIgKmNvdW50ZXI7CgoJbXV0ZXhfbG9jaygmY3VycmVudC0+cGVyZl9jb3VudGVyX211dGV4KTsKCWxpc3RfZm9yX2VhY2hfZW50cnkoY291bnRlciwgJmN1cnJlbnQtPnBlcmZfY291bnRlcl9saXN0LCBvd25lcl9lbnRyeSkKCQlwZXJmX2NvdW50ZXJfZm9yX2VhY2hfY2hpbGQoY291bnRlciwgcGVyZl9jb3VudGVyX2Rpc2FibGUpOwoJbXV0ZXhfdW5sb2NrKCZjdXJyZW50LT5wZXJmX2NvdW50ZXJfbXV0ZXgpOwoKCXJldHVybiAwOwp9CgpzdGF0aWMgaW50IHBlcmZfY291bnRlcl9pbmRleChzdHJ1Y3QgcGVyZl9jb3VudGVyICpjb3VudGVyKQp7CglpZiAoY291bnRlci0+c3RhdGUgIT0gUEVSRl9DT1VOVEVSX1NUQVRFX0FDVElWRSkKCQlyZXR1cm4gMDsKCglyZXR1cm4gY291bnRlci0+aHcuaWR4ICsgMSAtIFBFUkZfQ09VTlRFUl9JTkRFWF9PRkZTRVQ7Cn0KCi8qCiAqIENhbGxlcnMgbmVlZCB0byBlbnN1cmUgdGhlcmUgY2FuIGJlIG5vIG5lc3Rpbmcgb2YgdGhpcyBmdW5jdGlvbiwgb3RoZXJ3aXNlCiAqIHRoZSBzZXFsb2NrIGxvZ2ljIGdvZXMgYmFkLiBXZSBjYW4gbm90IHNlcmlhbGl6ZSB0aGlzIGJlY2F1c2UgdGhlIGFyY2gKICogY29kZSBjYWxscyB0aGlzIGZyb20gTk1JIGNvbnRleHQuCiAqLwp2b2lkIHBlcmZfY291bnRlcl91cGRhdGVfdXNlcnBhZ2Uoc3RydWN0IHBlcmZfY291bnRlciAqY291bnRlcikKewoJc3RydWN0IHBlcmZfY291bnRlcl9tbWFwX3BhZ2UgKnVzZXJwZzsKCXN0cnVjdCBwZXJmX21tYXBfZGF0YSAqZGF0YTsKCglyY3VfcmVhZF9sb2NrKCk7CglkYXRhID0gcmN1X2RlcmVmZXJlbmNlKGNvdW50ZXItPmRhdGEpOwoJaWYgKCFkYXRhKQoJCWdvdG8gdW5sb2NrOwoKCXVzZXJwZyA9IGRhdGEtPnVzZXJfcGFnZTsKCgkvKgoJICogRGlzYWJsZSBwcmVlbXB0aW9uIHNvIGFzIHRvIG5vdCBsZXQgdGhlIGNvcnJlc3BvbmRpbmcgdXNlci1zcGFjZQoJICogc3BpbiB0b28gbG9uZyBpZiB3ZSBnZXQgcHJlZW1wdGVkLgoJICovCglwcmVlbXB0X2Rpc2FibGUoKTsKCSsrdXNlcnBnLT5sb2NrOwoJYmFycmllcigpOwoJdXNlcnBnLT5pbmRleCA9IHBlcmZfY291bnRlcl9pbmRleChjb3VudGVyKTsKCXVzZXJwZy0+b2Zmc2V0ID0gYXRvbWljNjRfcmVhZCgmY291bnRlci0+Y291bnQpOwoJaWYgKGNvdW50ZXItPnN0YXRlID09IFBFUkZfQ09VTlRFUl9TVEFURV9BQ1RJVkUpCgkJdXNlcnBnLT5vZmZzZXQgLT0gYXRvbWljNjRfcmVhZCgmY291bnRlci0+aHcucHJldl9jb3VudCk7CgoJdXNlcnBnLT50aW1lX2VuYWJsZWQgPSBjb3VudGVyLT50b3RhbF90aW1lX2VuYWJsZWQgKwoJCQlhdG9taWM2NF9yZWFkKCZjb3VudGVyLT5jaGlsZF90b3RhbF90aW1lX2VuYWJsZWQpOwoKCXVzZXJwZy0+dGltZV9ydW5uaW5nID0gY291bnRlci0+dG90YWxfdGltZV9ydW5uaW5nICsKCQkJYXRvbWljNjRfcmVhZCgmY291bnRlci0+Y2hpbGRfdG90YWxfdGltZV9ydW5uaW5nKTsKCgliYXJyaWVyKCk7CgkrK3VzZXJwZy0+bG9jazsKCXByZWVtcHRfZW5hYmxlKCk7CnVubG9jazoKCXJjdV9yZWFkX3VubG9jaygpOwp9CgpzdGF0aWMgaW50IHBlcmZfbW1hcF9mYXVsdChzdHJ1Y3Qgdm1fYXJlYV9zdHJ1Y3QgKnZtYSwgc3RydWN0IHZtX2ZhdWx0ICp2bWYpCnsKCXN0cnVjdCBwZXJmX2NvdW50ZXIgKmNvdW50ZXIgPSB2bWEtPnZtX2ZpbGUtPnByaXZhdGVfZGF0YTsKCXN0cnVjdCBwZXJmX21tYXBfZGF0YSAqZGF0YTsKCWludCByZXQgPSBWTV9GQVVMVF9TSUdCVVM7CgoJaWYgKHZtZi0+ZmxhZ3MgJiBGQVVMVF9GTEFHX01LV1JJVEUpIHsKCQlpZiAodm1mLT5wZ29mZiA9PSAwKQoJCQlyZXQgPSAwOwoJCXJldHVybiByZXQ7Cgl9CgoJcmN1X3JlYWRfbG9jaygpOwoJZGF0YSA9IHJjdV9kZXJlZmVyZW5jZShjb3VudGVyLT5kYXRhKTsKCWlmICghZGF0YSkKCQlnb3RvIHVubG9jazsKCglpZiAodm1mLT5wZ29mZiA9PSAwKSB7CgkJdm1mLT5wYWdlID0gdmlydF90b19wYWdlKGRhdGEtPnVzZXJfcGFnZSk7Cgl9IGVsc2UgewoJCWludCBuciA9IHZtZi0+cGdvZmYgLSAxOwoKCQlpZiAoKHVuc2lnbmVkKW5yID4gZGF0YS0+bnJfcGFnZXMpCgkJCWdvdG8gdW5sb2NrOwoKCQlpZiAodm1mLT5mbGFncyAmIEZBVUxUX0ZMQUdfV1JJVEUpCgkJCWdvdG8gdW5sb2NrOwoKCQl2bWYtPnBhZ2UgPSB2aXJ0X3RvX3BhZ2UoZGF0YS0+ZGF0YV9wYWdlc1tucl0pOwoJfQoKCWdldF9wYWdlKHZtZi0+cGFnZSk7Cgl2bWYtPnBhZ2UtPm1hcHBpbmcgPSB2bWEtPnZtX2ZpbGUtPmZfbWFwcGluZzsKCXZtZi0+cGFnZS0+aW5kZXggICA9IHZtZi0+cGdvZmY7CgoJcmV0ID0gMDsKdW5sb2NrOgoJcmN1X3JlYWRfdW5sb2NrKCk7CgoJcmV0dXJuIHJldDsKfQoKc3RhdGljIGludCBwZXJmX21tYXBfZGF0YV9hbGxvYyhzdHJ1Y3QgcGVyZl9jb3VudGVyICpjb3VudGVyLCBpbnQgbnJfcGFnZXMpCnsKCXN0cnVjdCBwZXJmX21tYXBfZGF0YSAqZGF0YTsKCXVuc2lnbmVkIGxvbmcgc2l6ZTsKCWludCBpOwoKCVdBUk5fT04oYXRvbWljX3JlYWQoJmNvdW50ZXItPm1tYXBfY291bnQpKTsKCglzaXplID0gc2l6ZW9mKHN0cnVjdCBwZXJmX21tYXBfZGF0YSk7CglzaXplICs9IG5yX3BhZ2VzICogc2l6ZW9mKHZvaWQgKik7CgoJZGF0YSA9IGt6YWxsb2Moc2l6ZSwgR0ZQX0tFUk5FTCk7CglpZiAoIWRhdGEpCgkJZ290byBmYWlsOwoKCWRhdGEtPnVzZXJfcGFnZSA9ICh2b2lkICopZ2V0X3plcm9lZF9wYWdlKEdGUF9LRVJORUwpOwoJaWYgKCFkYXRhLT51c2VyX3BhZ2UpCgkJZ290byBmYWlsX3VzZXJfcGFnZTsKCglmb3IgKGkgPSAwOyBpIDwgbnJfcGFnZXM7IGkrKykgewoJCWRhdGEtPmRhdGFfcGFnZXNbaV0gPSAodm9pZCAqKWdldF96ZXJvZWRfcGFnZShHRlBfS0VSTkVMKTsKCQlpZiAoIWRhdGEtPmRhdGFfcGFnZXNbaV0pCgkJCWdvdG8gZmFpbF9kYXRhX3BhZ2VzOwoJfQoKCWRhdGEtPm5yX3BhZ2VzID0gbnJfcGFnZXM7CglhdG9taWNfc2V0KCZkYXRhLT5sb2NrLCAtMSk7CgoJcmN1X2Fzc2lnbl9wb2ludGVyKGNvdW50ZXItPmRhdGEsIGRhdGEpOwoKCXJldHVybiAwOwoKZmFpbF9kYXRhX3BhZ2VzOgoJZm9yIChpLS07IGkgPj0gMDsgaS0tKQoJCWZyZWVfcGFnZSgodW5zaWduZWQgbG9uZylkYXRhLT5kYXRhX3BhZ2VzW2ldKTsKCglmcmVlX3BhZ2UoKHVuc2lnbmVkIGxvbmcpZGF0YS0+dXNlcl9wYWdlKTsKCmZhaWxfdXNlcl9wYWdlOgoJa2ZyZWUoZGF0YSk7CgpmYWlsOgoJcmV0dXJuIC1FTk9NRU07Cn0KCnN0YXRpYyB2b2lkIHBlcmZfbW1hcF9mcmVlX3BhZ2UodW5zaWduZWQgbG9uZyBhZGRyKQp7CglzdHJ1Y3QgcGFnZSAqcGFnZSA9IHZpcnRfdG9fcGFnZSgodm9pZCAqKWFkZHIpOwoKCXBhZ2UtPm1hcHBpbmcgPSBOVUxMOwoJX19mcmVlX3BhZ2UocGFnZSk7Cn0KCnN0YXRpYyB2b2lkIF9fcGVyZl9tbWFwX2RhdGFfZnJlZShzdHJ1Y3QgcmN1X2hlYWQgKnJjdV9oZWFkKQp7CglzdHJ1Y3QgcGVyZl9tbWFwX2RhdGEgKmRhdGE7CglpbnQgaTsKCglkYXRhID0gY29udGFpbmVyX29mKHJjdV9oZWFkLCBzdHJ1Y3QgcGVyZl9tbWFwX2RhdGEsIHJjdV9oZWFkKTsKCglwZXJmX21tYXBfZnJlZV9wYWdlKCh1bnNpZ25lZCBsb25nKWRhdGEtPnVzZXJfcGFnZSk7Cglmb3IgKGkgPSAwOyBpIDwgZGF0YS0+bnJfcGFnZXM7IGkrKykKCQlwZXJmX21tYXBfZnJlZV9wYWdlKCh1bnNpZ25lZCBsb25nKWRhdGEtPmRhdGFfcGFnZXNbaV0pOwoKCWtmcmVlKGRhdGEpOwp9CgpzdGF0aWMgdm9pZCBwZXJmX21tYXBfZGF0YV9mcmVlKHN0cnVjdCBwZXJmX2NvdW50ZXIgKmNvdW50ZXIpCnsKCXN0cnVjdCBwZXJmX21tYXBfZGF0YSAqZGF0YSA9IGNvdW50ZXItPmRhdGE7CgoJV0FSTl9PTihhdG9taWNfcmVhZCgmY291bnRlci0+bW1hcF9jb3VudCkpOwoKCXJjdV9hc3NpZ25fcG9pbnRlcihjb3VudGVyLT5kYXRhLCBOVUxMKTsKCWNhbGxfcmN1KCZkYXRhLT5yY3VfaGVhZCwgX19wZXJmX21tYXBfZGF0YV9mcmVlKTsKfQoKc3RhdGljIHZvaWQgcGVyZl9tbWFwX29wZW4oc3RydWN0IHZtX2FyZWFfc3RydWN0ICp2bWEpCnsKCXN0cnVjdCBwZXJmX2NvdW50ZXIgKmNvdW50ZXIgPSB2bWEtPnZtX2ZpbGUtPnByaXZhdGVfZGF0YTsKCglhdG9taWNfaW5jKCZjb3VudGVyLT5tbWFwX2NvdW50KTsKfQoKc3RhdGljIHZvaWQgcGVyZl9tbWFwX2Nsb3NlKHN0cnVjdCB2bV9hcmVhX3N0cnVjdCAqdm1hKQp7CglzdHJ1Y3QgcGVyZl9jb3VudGVyICpjb3VudGVyID0gdm1hLT52bV9maWxlLT5wcml2YXRlX2RhdGE7CgoJV0FSTl9PTl9PTkNFKGNvdW50ZXItPmN0eC0+cGFyZW50X2N0eCk7CglpZiAoYXRvbWljX2RlY19hbmRfbXV0ZXhfbG9jaygmY291bnRlci0+bW1hcF9jb3VudCwgJmNvdW50ZXItPm1tYXBfbXV0ZXgpKSB7CgkJc3RydWN0IHVzZXJfc3RydWN0ICp1c2VyID0gY3VycmVudF91c2VyKCk7CgoJCWF0b21pY19sb25nX3N1Yihjb3VudGVyLT5kYXRhLT5ucl9wYWdlcyArIDEsICZ1c2VyLT5sb2NrZWRfdm0pOwoJCXZtYS0+dm1fbW0tPmxvY2tlZF92bSAtPSBjb3VudGVyLT5kYXRhLT5ucl9sb2NrZWQ7CgkJcGVyZl9tbWFwX2RhdGFfZnJlZShjb3VudGVyKTsKCQltdXRleF91bmxvY2soJmNvdW50ZXItPm1tYXBfbXV0ZXgpOwoJfQp9CgpzdGF0aWMgc3RydWN0IHZtX29wZXJhdGlvbnNfc3RydWN0IHBlcmZfbW1hcF92bW9wcyA9IHsKCS5vcGVuCQk9IHBlcmZfbW1hcF9vcGVuLAoJLmNsb3NlCQk9IHBlcmZfbW1hcF9jbG9zZSwKCS5mYXVsdAkJPSBwZXJmX21tYXBfZmF1bHQsCgkucGFnZV9ta3dyaXRlCT0gcGVyZl9tbWFwX2ZhdWx0LAp9OwoKc3RhdGljIGludCBwZXJmX21tYXAoc3RydWN0IGZpbGUgKmZpbGUsIHN0cnVjdCB2bV9hcmVhX3N0cnVjdCAqdm1hKQp7CglzdHJ1Y3QgcGVyZl9jb3VudGVyICpjb3VudGVyID0gZmlsZS0+cHJpdmF0ZV9kYXRhOwoJdW5zaWduZWQgbG9uZyB1c2VyX2xvY2tlZCwgdXNlcl9sb2NrX2xpbWl0OwoJc3RydWN0IHVzZXJfc3RydWN0ICp1c2VyID0gY3VycmVudF91c2VyKCk7Cgl1bnNpZ25lZCBsb25nIGxvY2tlZCwgbG9ja19saW1pdDsKCXVuc2lnbmVkIGxvbmcgdm1hX3NpemU7Cgl1bnNpZ25lZCBsb25nIG5yX3BhZ2VzOwoJbG9uZyB1c2VyX2V4dHJhLCBleHRyYTsKCWludCByZXQgPSAwOwoKCWlmICghKHZtYS0+dm1fZmxhZ3MgJiBWTV9TSEFSRUQpKQoJCXJldHVybiAtRUlOVkFMOwoKCXZtYV9zaXplID0gdm1hLT52bV9lbmQgLSB2bWEtPnZtX3N0YXJ0OwoJbnJfcGFnZXMgPSAodm1hX3NpemUgLyBQQUdFX1NJWkUpIC0gMTsKCgkvKgoJICogSWYgd2UgaGF2ZSBkYXRhIHBhZ2VzIGVuc3VyZSB0aGV5J3JlIGEgcG93ZXItb2YtdHdvIG51bWJlciwgc28gd2UKCSAqIGNhbiBkbyBiaXRtYXNrcyBpbnN0ZWFkIG9mIG1vZHVsby4KCSAqLwoJaWYgKG5yX3BhZ2VzICE9IDAgJiYgIWlzX3Bvd2VyX29mXzIobnJfcGFnZXMpKQoJCXJldHVybiAtRUlOVkFMOwoKCWlmICh2bWFfc2l6ZSAhPSBQQUdFX1NJWkUgKiAoMSArIG5yX3BhZ2VzKSkKCQlyZXR1cm4gLUVJTlZBTDsKCglpZiAodm1hLT52bV9wZ29mZiAhPSAwKQoJCXJldHVybiAtRUlOVkFMOwoKCVdBUk5fT05fT05DRShjb3VudGVyLT5jdHgtPnBhcmVudF9jdHgpOwoJbXV0ZXhfbG9jaygmY291bnRlci0+bW1hcF9tdXRleCk7CglpZiAoYXRvbWljX2luY19ub3RfemVybygmY291bnRlci0+bW1hcF9jb3VudCkpIHsKCQlpZiAobnJfcGFnZXMgIT0gY291bnRlci0+ZGF0YS0+bnJfcGFnZXMpCgkJCXJldCA9IC1FSU5WQUw7CgkJZ290byB1bmxvY2s7Cgl9CgoJdXNlcl9leHRyYSA9IG5yX3BhZ2VzICsgMTsKCXVzZXJfbG9ja19saW1pdCA9IHN5c2N0bF9wZXJmX2NvdW50ZXJfbWxvY2sgPj4gKFBBR0VfU0hJRlQgLSAxMCk7CgoJLyoKCSAqIEluY3JlYXNlIHRoZSBsaW1pdCBsaW5lYXJseSB3aXRoIG1vcmUgQ1BVczoKCSAqLwoJdXNlcl9sb2NrX2xpbWl0ICo9IG51bV9vbmxpbmVfY3B1cygpOwoKCXVzZXJfbG9ja2VkID0gYXRvbWljX2xvbmdfcmVhZCgmdXNlci0+bG9ja2VkX3ZtKSArIHVzZXJfZXh0cmE7CgoJZXh0cmEgPSAwOwoJaWYgKHVzZXJfbG9ja2VkID4gdXNlcl9sb2NrX2xpbWl0KQoJCWV4dHJhID0gdXNlcl9sb2NrZWQgLSB1c2VyX2xvY2tfbGltaXQ7CgoJbG9ja19saW1pdCA9IGN1cnJlbnQtPnNpZ25hbC0+cmxpbVtSTElNSVRfTUVNTE9DS10ucmxpbV9jdXI7Cglsb2NrX2xpbWl0ID4+PSBQQUdFX1NISUZUOwoJbG9ja2VkID0gdm1hLT52bV9tbS0+bG9ja2VkX3ZtICsgZXh0cmE7CgoJaWYgKChsb2NrZWQgPiBsb2NrX2xpbWl0KSAmJiAhY2FwYWJsZShDQVBfSVBDX0xPQ0spKSB7CgkJcmV0ID0gLUVQRVJNOwoJCWdvdG8gdW5sb2NrOwoJfQoKCVdBUk5fT04oY291bnRlci0+ZGF0YSk7CglyZXQgPSBwZXJmX21tYXBfZGF0YV9hbGxvYyhjb3VudGVyLCBucl9wYWdlcyk7CglpZiAocmV0KQoJCWdvdG8gdW5sb2NrOwoKCWF0b21pY19zZXQoJmNvdW50ZXItPm1tYXBfY291bnQsIDEpOwoJYXRvbWljX2xvbmdfYWRkKHVzZXJfZXh0cmEsICZ1c2VyLT5sb2NrZWRfdm0pOwoJdm1hLT52bV9tbS0+bG9ja2VkX3ZtICs9IGV4dHJhOwoJY291bnRlci0+ZGF0YS0+bnJfbG9ja2VkID0gZXh0cmE7CglpZiAodm1hLT52bV9mbGFncyAmIFZNX1dSSVRFKQoJCWNvdW50ZXItPmRhdGEtPndyaXRhYmxlID0gMTsKCnVubG9jazoKCW11dGV4X3VubG9jaygmY291bnRlci0+bW1hcF9tdXRleCk7CgoJdm1hLT52bV9mbGFncyB8PSBWTV9SRVNFUlZFRDsKCXZtYS0+dm1fb3BzID0gJnBlcmZfbW1hcF92bW9wczsKCglyZXR1cm4gcmV0Owp9CgpzdGF0aWMgaW50IHBlcmZfZmFzeW5jKGludCBmZCwgc3RydWN0IGZpbGUgKmZpbHAsIGludCBvbikKewoJc3RydWN0IGlub2RlICppbm9kZSA9IGZpbHAtPmZfcGF0aC5kZW50cnktPmRfaW5vZGU7CglzdHJ1Y3QgcGVyZl9jb3VudGVyICpjb3VudGVyID0gZmlscC0+cHJpdmF0ZV9kYXRhOwoJaW50IHJldHZhbDsKCgltdXRleF9sb2NrKCZpbm9kZS0+aV9tdXRleCk7CglyZXR2YWwgPSBmYXN5bmNfaGVscGVyKGZkLCBmaWxwLCBvbiwgJmNvdW50ZXItPmZhc3luYyk7CgltdXRleF91bmxvY2soJmlub2RlLT5pX211dGV4KTsKCglpZiAocmV0dmFsIDwgMCkKCQlyZXR1cm4gcmV0dmFsOwoKCXJldHVybiAwOwp9CgpzdGF0aWMgY29uc3Qgc3RydWN0IGZpbGVfb3BlcmF0aW9ucyBwZXJmX2ZvcHMgPSB7CgkucmVsZWFzZQkJPSBwZXJmX3JlbGVhc2UsCgkucmVhZAkJCT0gcGVyZl9yZWFkLAoJLnBvbGwJCQk9IHBlcmZfcG9sbCwKCS51bmxvY2tlZF9pb2N0bAkJPSBwZXJmX2lvY3RsLAoJLmNvbXBhdF9pb2N0bAkJPSBwZXJmX2lvY3RsLAoJLm1tYXAJCQk9IHBlcmZfbW1hcCwKCS5mYXN5bmMJCQk9IHBlcmZfZmFzeW5jLAp9OwoKLyoKICogUGVyZiBjb3VudGVyIHdha2V1cAogKgogKiBJZiB0aGVyZSdzIGRhdGEsIGVuc3VyZSB3ZSBzZXQgdGhlIHBvbGwoKSBzdGF0ZSBhbmQgcHVibGlzaCBldmVyeXRoaW5nCiAqIHRvIHVzZXItc3BhY2UgYmVmb3JlIHdha2luZyBldmVyeWJvZHkgdXAuCiAqLwoKdm9pZCBwZXJmX2NvdW50ZXJfd2FrZXVwKHN0cnVjdCBwZXJmX2NvdW50ZXIgKmNvdW50ZXIpCnsKCXdha2VfdXBfYWxsKCZjb3VudGVyLT53YWl0cSk7CgoJaWYgKGNvdW50ZXItPnBlbmRpbmdfa2lsbCkgewoJCWtpbGxfZmFzeW5jKCZjb3VudGVyLT5mYXN5bmMsIFNJR0lPLCBjb3VudGVyLT5wZW5kaW5nX2tpbGwpOwoJCWNvdW50ZXItPnBlbmRpbmdfa2lsbCA9IDA7Cgl9Cn0KCi8qCiAqIFBlbmRpbmcgd2FrZXVwcwogKgogKiBIYW5kbGUgdGhlIGNhc2Ugd2hlcmUgd2UgbmVlZCB0byB3YWtldXAgdXAgZnJvbSBOTUkgKG9yIHJxLT5sb2NrKSBjb250ZXh0LgogKgogKiBUaGUgTk1JIGJpdCBtZWFucyB3ZSBjYW5ub3QgcG9zc2libHkgdGFrZSBsb2Nrcy4gVGhlcmVmb3JlLCBtYWludGFpbiBhCiAqIHNpbmdsZSBsaW5rZWQgbGlzdCBhbmQgdXNlIGNtcHhjaGcoKSB0byBhZGQgZW50cmllcyBsb2NrbGVzcy4KICovCgpzdGF0aWMgdm9pZCBwZXJmX3BlbmRpbmdfY291bnRlcihzdHJ1Y3QgcGVyZl9wZW5kaW5nX2VudHJ5ICplbnRyeSkKewoJc3RydWN0IHBlcmZfY291bnRlciAqY291bnRlciA9IGNvbnRhaW5lcl9vZihlbnRyeSwKCQkJc3RydWN0IHBlcmZfY291bnRlciwgcGVuZGluZyk7CgoJaWYgKGNvdW50ZXItPnBlbmRpbmdfZGlzYWJsZSkgewoJCWNvdW50ZXItPnBlbmRpbmdfZGlzYWJsZSA9IDA7CgkJcGVyZl9jb3VudGVyX2Rpc2FibGUoY291bnRlcik7Cgl9CgoJaWYgKGNvdW50ZXItPnBlbmRpbmdfd2FrZXVwKSB7CgkJY291bnRlci0+cGVuZGluZ193YWtldXAgPSAwOwoJCXBlcmZfY291bnRlcl93YWtldXAoY291bnRlcik7Cgl9Cn0KCiNkZWZpbmUgUEVORElOR19UQUlMICgoc3RydWN0IHBlcmZfcGVuZGluZ19lbnRyeSAqKS0xVUwpCgpzdGF0aWMgREVGSU5FX1BFUl9DUFUoc3RydWN0IHBlcmZfcGVuZGluZ19lbnRyeSAqLCBwZXJmX3BlbmRpbmdfaGVhZCkgPSB7CglQRU5ESU5HX1RBSUwsCn07CgpzdGF0aWMgdm9pZCBwZXJmX3BlbmRpbmdfcXVldWUoc3RydWN0IHBlcmZfcGVuZGluZ19lbnRyeSAqZW50cnksCgkJCSAgICAgICB2b2lkICgqZnVuYykoc3RydWN0IHBlcmZfcGVuZGluZ19lbnRyeSAqKSkKewoJc3RydWN0IHBlcmZfcGVuZGluZ19lbnRyeSAqKmhlYWQ7CgoJaWYgKGNtcHhjaGcoJmVudHJ5LT5uZXh0LCBOVUxMLCBQRU5ESU5HX1RBSUwpICE9IE5VTEwpCgkJcmV0dXJuOwoKCWVudHJ5LT5mdW5jID0gZnVuYzsKCgloZWFkID0gJmdldF9jcHVfdmFyKHBlcmZfcGVuZGluZ19oZWFkKTsKCglkbyB7CgkJZW50cnktPm5leHQgPSAqaGVhZDsKCX0gd2hpbGUgKGNtcHhjaGcoaGVhZCwgZW50cnktPm5leHQsIGVudHJ5KSAhPSBlbnRyeS0+bmV4dCk7CgoJc2V0X3BlcmZfY291bnRlcl9wZW5kaW5nKCk7CgoJcHV0X2NwdV92YXIocGVyZl9wZW5kaW5nX2hlYWQpOwp9CgpzdGF0aWMgaW50IF9fcGVyZl9wZW5kaW5nX3J1bih2b2lkKQp7CglzdHJ1Y3QgcGVyZl9wZW5kaW5nX2VudHJ5ICpsaXN0OwoJaW50IG5yID0gMDsKCglsaXN0ID0geGNoZygmX19nZXRfY3B1X3ZhcihwZXJmX3BlbmRpbmdfaGVhZCksIFBFTkRJTkdfVEFJTCk7Cgl3aGlsZSAobGlzdCAhPSBQRU5ESU5HX1RBSUwpIHsKCQl2b2lkICgqZnVuYykoc3RydWN0IHBlcmZfcGVuZGluZ19lbnRyeSAqKTsKCQlzdHJ1Y3QgcGVyZl9wZW5kaW5nX2VudHJ5ICplbnRyeSA9IGxpc3Q7CgoJCWxpc3QgPSBsaXN0LT5uZXh0OwoKCQlmdW5jID0gZW50cnktPmZ1bmM7CgkJZW50cnktPm5leHQgPSBOVUxMOwoJCS8qCgkJICogRW5zdXJlIHdlIG9ic2VydmUgdGhlIHVucXVldWUgYmVmb3JlIHdlIGlzc3VlIHRoZSB3YWtldXAsCgkJICogc28gdGhhdCB3ZSB3b24ndCBiZSB3YWl0aW5nIGZvcmV2ZXIuCgkJICogLS0gc2VlIHBlcmZfbm90X3BlbmRpbmcoKS4KCQkgKi8KCQlzbXBfd21iKCk7CgoJCWZ1bmMoZW50cnkpOwoJCW5yKys7Cgl9CgoJcmV0dXJuIG5yOwp9CgpzdGF0aWMgaW5saW5lIGludCBwZXJmX25vdF9wZW5kaW5nKHN0cnVjdCBwZXJmX2NvdW50ZXIgKmNvdW50ZXIpCnsKCS8qCgkgKiBJZiB3ZSBmbHVzaCBvbiB3aGF0ZXZlciBjcHUgd2UgcnVuLCB0aGVyZSBpcyBhIGNoYW5jZSB3ZSBkb24ndAoJICogbmVlZCB0byB3YWl0LgoJICovCglnZXRfY3B1KCk7CglfX3BlcmZfcGVuZGluZ19ydW4oKTsKCXB1dF9jcHUoKTsKCgkvKgoJICogRW5zdXJlIHdlIHNlZSB0aGUgcHJvcGVyIHF1ZXVlIHN0YXRlIGJlZm9yZSBnb2luZyB0byBzbGVlcAoJICogc28gdGhhdCB3ZSBkbyBub3QgbWlzcyB0aGUgd2FrZXVwLiAtLSBzZWUgcGVyZl9wZW5kaW5nX2hhbmRsZSgpCgkgKi8KCXNtcF9ybWIoKTsKCXJldHVybiBjb3VudGVyLT5wZW5kaW5nLm5leHQgPT0gTlVMTDsKfQoKc3RhdGljIHZvaWQgcGVyZl9wZW5kaW5nX3N5bmMoc3RydWN0IHBlcmZfY291bnRlciAqY291bnRlcikKewoJd2FpdF9ldmVudChjb3VudGVyLT53YWl0cSwgcGVyZl9ub3RfcGVuZGluZyhjb3VudGVyKSk7Cn0KCnZvaWQgcGVyZl9jb3VudGVyX2RvX3BlbmRpbmcodm9pZCkKewoJX19wZXJmX3BlbmRpbmdfcnVuKCk7Cn0KCi8qCiAqIENhbGxjaGFpbiBzdXBwb3J0IC0tIGFyY2ggc3BlY2lmaWMKICovCgpfX3dlYWsgc3RydWN0IHBlcmZfY2FsbGNoYWluX2VudHJ5ICpwZXJmX2NhbGxjaGFpbihzdHJ1Y3QgcHRfcmVncyAqcmVncykKewoJcmV0dXJuIE5VTEw7Cn0KCi8qCiAqIE91dHB1dAogKi8KCnN0cnVjdCBwZXJmX291dHB1dF9oYW5kbGUgewoJc3RydWN0IHBlcmZfY291bnRlcgkqY291bnRlcjsKCXN0cnVjdCBwZXJmX21tYXBfZGF0YQkqZGF0YTsKCXVuc2lnbmVkIGxvbmcJCWhlYWQ7Cgl1bnNpZ25lZCBsb25nCQlvZmZzZXQ7CglpbnQJCQlubWk7CglpbnQJCQlzYW1wbGU7CglpbnQJCQlsb2NrZWQ7Cgl1bnNpZ25lZCBsb25nCQlmbGFnczsKfTsKCnN0YXRpYyBib29sIHBlcmZfb3V0cHV0X3NwYWNlKHN0cnVjdCBwZXJmX21tYXBfZGF0YSAqZGF0YSwKCQkJICAgICAgdW5zaWduZWQgaW50IG9mZnNldCwgdW5zaWduZWQgaW50IGhlYWQpCnsKCXVuc2lnbmVkIGxvbmcgdGFpbDsKCXVuc2lnbmVkIGxvbmcgbWFzazsKCglpZiAoIWRhdGEtPndyaXRhYmxlKQoJCXJldHVybiB0cnVlOwoKCW1hc2sgPSAoZGF0YS0+bnJfcGFnZXMgPDwgUEFHRV9TSElGVCkgLSAxOwoJLyoKCSAqIFVzZXJzcGFjZSBjb3VsZCBjaG9vc2UgdG8gaXNzdWUgYSBtYigpIGJlZm9yZSB1cGRhdGluZyB0aGUgdGFpbAoJICogcG9pbnRlci4gU28gdGhhdCBhbGwgcmVhZHMgd2lsbCBiZSBjb21wbGV0ZWQgYmVmb3JlIHRoZSB3cml0ZSBpcwoJICogaXNzdWVkLgoJICovCgl0YWlsID0gQUNDRVNTX09OQ0UoZGF0YS0+dXNlcl9wYWdlLT5kYXRhX3RhaWwpOwoJc21wX3JtYigpOwoKCW9mZnNldCA9IChvZmZzZXQgLSB0YWlsKSAmIG1hc2s7CgloZWFkICAgPSAoaGVhZCAgIC0gdGFpbCkgJiBtYXNrOwoKCWlmICgoaW50KShoZWFkIC0gb2Zmc2V0KSA8IDApCgkJcmV0dXJuIGZhbHNlOwoKCXJldHVybiB0cnVlOwp9CgpzdGF0aWMgdm9pZCBwZXJmX291dHB1dF93YWtldXAoc3RydWN0IHBlcmZfb3V0cHV0X2hhbmRsZSAqaGFuZGxlKQp7CglhdG9taWNfc2V0KCZoYW5kbGUtPmRhdGEtPnBvbGwsIFBPTExfSU4pOwoKCWlmIChoYW5kbGUtPm5taSkgewoJCWhhbmRsZS0+Y291bnRlci0+cGVuZGluZ193YWtldXAgPSAxOwoJCXBlcmZfcGVuZGluZ19xdWV1ZSgmaGFuZGxlLT5jb3VudGVyLT5wZW5kaW5nLAoJCQkJICAgcGVyZl9wZW5kaW5nX2NvdW50ZXIpOwoJfSBlbHNlCgkJcGVyZl9jb3VudGVyX3dha2V1cChoYW5kbGUtPmNvdW50ZXIpOwp9CgovKgogKiBDdXJpb3VzIGxvY2tpbmcgY29uc3RydWN0LgogKgogKiBXZSBuZWVkIHRvIGVuc3VyZSBhIGxhdGVyIGV2ZW50IGRvZXNuJ3QgcHVibGlzaCBhIGhlYWQgd2hlbiBhIGZvcm1lcgogKiBldmVudCBpc24ndCBkb25lIHdyaXRpbmcuIEhvd2V2ZXIgc2luY2Ugd2UgbmVlZCB0byBkZWFsIHdpdGggTk1JcyB3ZQogKiBjYW5ub3QgZnVsbHkgc2VyaWFsaXplIHRoaW5ncy4KICoKICogV2hhdCB3ZSBkbyBpcyBzZXJpYWxpemUgYmV0d2VlbiBDUFVzIHNvIHdlIG9ubHkgaGF2ZSB0byBkZWFsIHdpdGggTk1JCiAqIG5lc3Rpbmcgb24gYSBzaW5nbGUgQ1BVLgogKgogKiBXZSBvbmx5IHB1Ymxpc2ggdGhlIGhlYWQgKGFuZCBnZW5lcmF0ZSBhIHdha2V1cCkgd2hlbiB0aGUgb3V0ZXItbW9zdAogKiBldmVudCBjb21wbGV0ZXMuCiAqLwpzdGF0aWMgdm9pZCBwZXJmX291dHB1dF9sb2NrKHN0cnVjdCBwZXJmX291dHB1dF9oYW5kbGUgKmhhbmRsZSkKewoJc3RydWN0IHBlcmZfbW1hcF9kYXRhICpkYXRhID0gaGFuZGxlLT5kYXRhOwoJaW50IGNwdTsKCgloYW5kbGUtPmxvY2tlZCA9IDA7CgoJbG9jYWxfaXJxX3NhdmUoaGFuZGxlLT5mbGFncyk7CgljcHUgPSBzbXBfcHJvY2Vzc29yX2lkKCk7CgoJaWYgKGluX25taSgpICYmIGF0b21pY19yZWFkKCZkYXRhLT5sb2NrKSA9PSBjcHUpCgkJcmV0dXJuOwoKCXdoaWxlIChhdG9taWNfY21weGNoZygmZGF0YS0+bG9jaywgLTEsIGNwdSkgIT0gLTEpCgkJY3B1X3JlbGF4KCk7CgoJaGFuZGxlLT5sb2NrZWQgPSAxOwp9CgpzdGF0aWMgdm9pZCBwZXJmX291dHB1dF91bmxvY2soc3RydWN0IHBlcmZfb3V0cHV0X2hhbmRsZSAqaGFuZGxlKQp7CglzdHJ1Y3QgcGVyZl9tbWFwX2RhdGEgKmRhdGEgPSBoYW5kbGUtPmRhdGE7Cgl1bnNpZ25lZCBsb25nIGhlYWQ7CglpbnQgY3B1OwoKCWRhdGEtPmRvbmVfaGVhZCA9IGRhdGEtPmhlYWQ7CgoJaWYgKCFoYW5kbGUtPmxvY2tlZCkKCQlnb3RvIG91dDsKCmFnYWluOgoJLyoKCSAqIFRoZSB4Y2hnIGltcGxpZXMgYSBmdWxsIGJhcnJpZXIgdGhhdCBlbnN1cmVzIGFsbCB3cml0ZXMgYXJlIGRvbmUKCSAqIGJlZm9yZSB3ZSBwdWJsaXNoIHRoZSBuZXcgaGVhZCwgbWF0Y2hlZCBieSBhIHJtYigpIGluIHVzZXJzcGFjZSB3aGVuCgkgKiByZWFkaW5nIHRoaXMgcG9zaXRpb24uCgkgKi8KCXdoaWxlICgoaGVhZCA9IGF0b21pY19sb25nX3hjaGcoJmRhdGEtPmRvbmVfaGVhZCwgMCkpKQoJCWRhdGEtPnVzZXJfcGFnZS0+ZGF0YV9oZWFkID0gaGVhZDsKCgkvKgoJICogTk1JIGNhbiBoYXBwZW4gaGVyZSwgd2hpY2ggbWVhbnMgd2UgY2FuIG1pc3MgYSBkb25lX2hlYWQgdXBkYXRlLgoJICovCgoJY3B1ID0gYXRvbWljX3hjaGcoJmRhdGEtPmxvY2ssIC0xKTsKCVdBUk5fT05fT05DRShjcHUgIT0gc21wX3Byb2Nlc3Nvcl9pZCgpKTsKCgkvKgoJICogVGhlcmVmb3JlIHdlIGhhdmUgdG8gdmFsaWRhdGUgd2UgZGlkIG5vdCBpbmRlZWQgZG8gc28uCgkgKi8KCWlmICh1bmxpa2VseShhdG9taWNfbG9uZ19yZWFkKCZkYXRhLT5kb25lX2hlYWQpKSkgewoJCS8qCgkJICogU2luY2Ugd2UgaGFkIGl0IGxvY2tlZCwgd2UgY2FuIGxvY2sgaXQgYWdhaW4uCgkJICovCgkJd2hpbGUgKGF0b21pY19jbXB4Y2hnKCZkYXRhLT5sb2NrLCAtMSwgY3B1KSAhPSAtMSkKCQkJY3B1X3JlbGF4KCk7CgoJCWdvdG8gYWdhaW47Cgl9CgoJaWYgKGF0b21pY194Y2hnKCZkYXRhLT53YWtldXAsIDApKQoJCXBlcmZfb3V0cHV0X3dha2V1cChoYW5kbGUpOwpvdXQ6Cglsb2NhbF9pcnFfcmVzdG9yZShoYW5kbGUtPmZsYWdzKTsKfQoKc3RhdGljIHZvaWQgcGVyZl9vdXRwdXRfY29weShzdHJ1Y3QgcGVyZl9vdXRwdXRfaGFuZGxlICpoYW5kbGUsCgkJCSAgICAgY29uc3Qgdm9pZCAqYnVmLCB1bnNpZ25lZCBpbnQgbGVuKQp7Cgl1bnNpZ25lZCBpbnQgcGFnZXNfbWFzazsKCXVuc2lnbmVkIGludCBvZmZzZXQ7Cgl1bnNpZ25lZCBpbnQgc2l6ZTsKCXZvaWQgKipwYWdlczsKCglvZmZzZXQJCT0gaGFuZGxlLT5vZmZzZXQ7CglwYWdlc19tYXNrCT0gaGFuZGxlLT5kYXRhLT5ucl9wYWdlcyAtIDE7CglwYWdlcwkJPSBoYW5kbGUtPmRhdGEtPmRhdGFfcGFnZXM7CgoJZG8gewoJCXVuc2lnbmVkIGludCBwYWdlX29mZnNldDsKCQlpbnQgbnI7CgoJCW5yCSAgICA9IChvZmZzZXQgPj4gUEFHRV9TSElGVCkgJiBwYWdlc19tYXNrOwoJCXBhZ2Vfb2Zmc2V0ID0gb2Zmc2V0ICYgKFBBR0VfU0laRSAtIDEpOwoJCXNpemUJICAgID0gbWluX3QodW5zaWduZWQgaW50LCBQQUdFX1NJWkUgLSBwYWdlX29mZnNldCwgbGVuKTsKCgkJbWVtY3B5KHBhZ2VzW25yXSArIHBhZ2Vfb2Zmc2V0LCBidWYsIHNpemUpOwoKCQlsZW4JICAgIC09IHNpemU7CgkJYnVmCSAgICArPSBzaXplOwoJCW9mZnNldAkgICAgKz0gc2l6ZTsKCX0gd2hpbGUgKGxlbik7CgoJaGFuZGxlLT5vZmZzZXQgPSBvZmZzZXQ7CgoJLyoKCSAqIENoZWNrIHdlIGRpZG4ndCBjb3B5IHBhc3Qgb3VyIHJlc2VydmF0aW9uIHdpbmRvdywgdGFraW5nIHRoZQoJICogcG9zc2libGUgdW5zaWduZWQgaW50IHdyYXAgaW50byBhY2NvdW50LgoJICovCglXQVJOX09OX09OQ0UoKChsb25nKShoYW5kbGUtPmhlYWQgLSBoYW5kbGUtPm9mZnNldCkpIDwgMCk7Cn0KCiNkZWZpbmUgcGVyZl9vdXRwdXRfcHV0KGhhbmRsZSwgeCkgXAoJcGVyZl9vdXRwdXRfY29weSgoaGFuZGxlKSwgJih4KSwgc2l6ZW9mKHgpKQoKc3RhdGljIGludCBwZXJmX291dHB1dF9iZWdpbihzdHJ1Y3QgcGVyZl9vdXRwdXRfaGFuZGxlICpoYW5kbGUsCgkJCSAgICAgc3RydWN0IHBlcmZfY291bnRlciAqY291bnRlciwgdW5zaWduZWQgaW50IHNpemUsCgkJCSAgICAgaW50IG5taSwgaW50IHNhbXBsZSkKewoJc3RydWN0IHBlcmZfbW1hcF9kYXRhICpkYXRhOwoJdW5zaWduZWQgaW50IG9mZnNldCwgaGVhZDsKCWludCBoYXZlX2xvc3Q7CglzdHJ1Y3QgewoJCXN0cnVjdCBwZXJmX2V2ZW50X2hlYWRlciBoZWFkZXI7CgkJdTY0CQkJIGlkOwoJCXU2NAkJCSBsb3N0OwoJfSBsb3N0X2V2ZW50OwoKCS8qCgkgKiBGb3IgaW5oZXJpdGVkIGNvdW50ZXJzIHdlIHNlbmQgYWxsIHRoZSBvdXRwdXQgdG93YXJkcyB0aGUgcGFyZW50LgoJICovCglpZiAoY291bnRlci0+cGFyZW50KQoJCWNvdW50ZXIgPSBjb3VudGVyLT5wYXJlbnQ7CgoJcmN1X3JlYWRfbG9jaygpOwoJZGF0YSA9IHJjdV9kZXJlZmVyZW5jZShjb3VudGVyLT5kYXRhKTsKCWlmICghZGF0YSkKCQlnb3RvIG91dDsKCgloYW5kbGUtPmRhdGEJPSBkYXRhOwoJaGFuZGxlLT5jb3VudGVyCT0gY291bnRlcjsKCWhhbmRsZS0+bm1pCT0gbm1pOwoJaGFuZGxlLT5zYW1wbGUJPSBzYW1wbGU7CgoJaWYgKCFkYXRhLT5ucl9wYWdlcykKCQlnb3RvIGZhaWw7CgoJaGF2ZV9sb3N0ID0gYXRvbWljX3JlYWQoJmRhdGEtPmxvc3QpOwoJaWYgKGhhdmVfbG9zdCkKCQlzaXplICs9IHNpemVvZihsb3N0X2V2ZW50KTsKCglwZXJmX291dHB1dF9sb2NrKGhhbmRsZSk7CgoJZG8gewoJCW9mZnNldCA9IGhlYWQgPSBhdG9taWNfbG9uZ19yZWFkKCZkYXRhLT5oZWFkKTsKCQloZWFkICs9IHNpemU7CgkJaWYgKHVubGlrZWx5KCFwZXJmX291dHB1dF9zcGFjZShkYXRhLCBvZmZzZXQsIGhlYWQpKSkKCQkJZ290byBmYWlsOwoJfSB3aGlsZSAoYXRvbWljX2xvbmdfY21weGNoZygmZGF0YS0+aGVhZCwgb2Zmc2V0LCBoZWFkKSAhPSBvZmZzZXQpOwoKCWhhbmRsZS0+b2Zmc2V0CT0gb2Zmc2V0OwoJaGFuZGxlLT5oZWFkCT0gaGVhZDsKCglpZiAoKG9mZnNldCA+PiBQQUdFX1NISUZUKSAhPSAoaGVhZCA+PiBQQUdFX1NISUZUKSkKCQlhdG9taWNfc2V0KCZkYXRhLT53YWtldXAsIDEpOwoKCWlmIChoYXZlX2xvc3QpIHsKCQlsb3N0X2V2ZW50LmhlYWRlci50eXBlID0gUEVSRl9FVkVOVF9MT1NUOwoJCWxvc3RfZXZlbnQuaGVhZGVyLm1pc2MgPSAwOwoJCWxvc3RfZXZlbnQuaGVhZGVyLnNpemUgPSBzaXplb2YobG9zdF9ldmVudCk7CgkJbG9zdF9ldmVudC5pZCAgICAgICAgICA9IGNvdW50ZXItPmlkOwoJCWxvc3RfZXZlbnQubG9zdCAgICAgICAgPSBhdG9taWNfeGNoZygmZGF0YS0+bG9zdCwgMCk7CgoJCXBlcmZfb3V0cHV0X3B1dChoYW5kbGUsIGxvc3RfZXZlbnQpOwoJfQoKCXJldHVybiAwOwoKZmFpbDoKCWF0b21pY19pbmMoJmRhdGEtPmxvc3QpOwoJcGVyZl9vdXRwdXRfdW5sb2NrKGhhbmRsZSk7Cm91dDoKCXJjdV9yZWFkX3VubG9jaygpOwoKCXJldHVybiAtRU5PU1BDOwp9CgpzdGF0aWMgdm9pZCBwZXJmX291dHB1dF9lbmQoc3RydWN0IHBlcmZfb3V0cHV0X2hhbmRsZSAqaGFuZGxlKQp7CglzdHJ1Y3QgcGVyZl9jb3VudGVyICpjb3VudGVyID0gaGFuZGxlLT5jb3VudGVyOwoJc3RydWN0IHBlcmZfbW1hcF9kYXRhICpkYXRhID0gaGFuZGxlLT5kYXRhOwoKCWludCB3YWtldXBfZXZlbnRzID0gY291bnRlci0+YXR0ci53YWtldXBfZXZlbnRzOwoKCWlmIChoYW5kbGUtPnNhbXBsZSAmJiB3YWtldXBfZXZlbnRzKSB7CgkJaW50IGV2ZW50cyA9IGF0b21pY19pbmNfcmV0dXJuKCZkYXRhLT5ldmVudHMpOwoJCWlmIChldmVudHMgPj0gd2FrZXVwX2V2ZW50cykgewoJCQlhdG9taWNfc3ViKHdha2V1cF9ldmVudHMsICZkYXRhLT5ldmVudHMpOwoJCQlhdG9taWNfc2V0KCZkYXRhLT53YWtldXAsIDEpOwoJCX0KCX0KCglwZXJmX291dHB1dF91bmxvY2soaGFuZGxlKTsKCXJjdV9yZWFkX3VubG9jaygpOwp9CgpzdGF0aWMgdTMyIHBlcmZfY291bnRlcl9waWQoc3RydWN0IHBlcmZfY291bnRlciAqY291bnRlciwgc3RydWN0IHRhc2tfc3RydWN0ICpwKQp7CgkvKgoJICogb25seSB0b3AgbGV2ZWwgY291bnRlcnMgaGF2ZSB0aGUgcGlkIG5hbWVzcGFjZSB0aGV5IHdlcmUgY3JlYXRlZCBpbgoJICovCglpZiAoY291bnRlci0+cGFyZW50KQoJCWNvdW50ZXIgPSBjb3VudGVyLT5wYXJlbnQ7CgoJcmV0dXJuIHRhc2tfdGdpZF9ucl9ucyhwLCBjb3VudGVyLT5ucyk7Cn0KCnN0YXRpYyB1MzIgcGVyZl9jb3VudGVyX3RpZChzdHJ1Y3QgcGVyZl9jb3VudGVyICpjb3VudGVyLCBzdHJ1Y3QgdGFza19zdHJ1Y3QgKnApCnsKCS8qCgkgKiBvbmx5IHRvcCBsZXZlbCBjb3VudGVycyBoYXZlIHRoZSBwaWQgbmFtZXNwYWNlIHRoZXkgd2VyZSBjcmVhdGVkIGluCgkgKi8KCWlmIChjb3VudGVyLT5wYXJlbnQpCgkJY291bnRlciA9IGNvdW50ZXItPnBhcmVudDsKCglyZXR1cm4gdGFza19waWRfbnJfbnMocCwgY291bnRlci0+bnMpOwp9CgpzdGF0aWMgdm9pZCBwZXJmX2NvdW50ZXJfb3V0cHV0KHN0cnVjdCBwZXJmX2NvdW50ZXIgKmNvdW50ZXIsIGludCBubWksCgkJCQlzdHJ1Y3QgcGVyZl9zYW1wbGVfZGF0YSAqZGF0YSkKewoJaW50IHJldDsKCXU2NCBzYW1wbGVfdHlwZSA9IGNvdW50ZXItPmF0dHIuc2FtcGxlX3R5cGU7CglzdHJ1Y3QgcGVyZl9vdXRwdXRfaGFuZGxlIGhhbmRsZTsKCXN0cnVjdCBwZXJmX2V2ZW50X2hlYWRlciBoZWFkZXI7Cgl1NjQgaXA7CglzdHJ1Y3QgewoJCXUzMiBwaWQsIHRpZDsKCX0gdGlkX2VudHJ5OwoJc3RydWN0IHsKCQl1NjQgaWQ7CgkJdTY0IGNvdW50ZXI7Cgl9IGdyb3VwX2VudHJ5OwoJc3RydWN0IHBlcmZfY2FsbGNoYWluX2VudHJ5ICpjYWxsY2hhaW4gPSBOVUxMOwoJaW50IGNhbGxjaGFpbl9zaXplID0gMDsKCXU2NCB0aW1lOwoJc3RydWN0IHsKCQl1MzIgY3B1LCByZXNlcnZlZDsKCX0gY3B1X2VudHJ5OwoKCWhlYWRlci50eXBlID0gUEVSRl9FVkVOVF9TQU1QTEU7CgloZWFkZXIuc2l6ZSA9IHNpemVvZihoZWFkZXIpOwoKCWhlYWRlci5taXNjID0gMDsKCWhlYWRlci5taXNjIHw9IHBlcmZfbWlzY19mbGFncyhkYXRhLT5yZWdzKTsKCglpZiAoc2FtcGxlX3R5cGUgJiBQRVJGX1NBTVBMRV9JUCkgewoJCWlwID0gcGVyZl9pbnN0cnVjdGlvbl9wb2ludGVyKGRhdGEtPnJlZ3MpOwoJCWhlYWRlci5zaXplICs9IHNpemVvZihpcCk7Cgl9CgoJaWYgKHNhbXBsZV90eXBlICYgUEVSRl9TQU1QTEVfVElEKSB7CgkJLyogbmFtZXNwYWNlIGlzc3VlcyAqLwoJCXRpZF9lbnRyeS5waWQgPSBwZXJmX2NvdW50ZXJfcGlkKGNvdW50ZXIsIGN1cnJlbnQpOwoJCXRpZF9lbnRyeS50aWQgPSBwZXJmX2NvdW50ZXJfdGlkKGNvdW50ZXIsIGN1cnJlbnQpOwoKCQloZWFkZXIuc2l6ZSArPSBzaXplb2YodGlkX2VudHJ5KTsKCX0KCglpZiAoc2FtcGxlX3R5cGUgJiBQRVJGX1NBTVBMRV9USU1FKSB7CgkJLyoKCQkgKiBNYXliZSBkbyBiZXR0ZXIgb24geDg2IGFuZCBwcm92aWRlIGNwdV9jbG9ja19ubWkoKQoJCSAqLwoJCXRpbWUgPSBzY2hlZF9jbG9jaygpOwoKCQloZWFkZXIuc2l6ZSArPSBzaXplb2YodTY0KTsKCX0KCglpZiAoc2FtcGxlX3R5cGUgJiBQRVJGX1NBTVBMRV9BRERSKQoJCWhlYWRlci5zaXplICs9IHNpemVvZih1NjQpOwoKCWlmIChzYW1wbGVfdHlwZSAmIFBFUkZfU0FNUExFX0lEKQoJCWhlYWRlci5zaXplICs9IHNpemVvZih1NjQpOwoKCWlmIChzYW1wbGVfdHlwZSAmIFBFUkZfU0FNUExFX1NUUkVBTV9JRCkKCQloZWFkZXIuc2l6ZSArPSBzaXplb2YodTY0KTsKCglpZiAoc2FtcGxlX3R5cGUgJiBQRVJGX1NBTVBMRV9DUFUpIHsKCQloZWFkZXIuc2l6ZSArPSBzaXplb2YoY3B1X2VudHJ5KTsKCgkJY3B1X2VudHJ5LmNwdSA9IHJhd19zbXBfcHJvY2Vzc29yX2lkKCk7CgkJY3B1X2VudHJ5LnJlc2VydmVkID0gMDsKCX0KCglpZiAoc2FtcGxlX3R5cGUgJiBQRVJGX1NBTVBMRV9QRVJJT0QpCgkJaGVhZGVyLnNpemUgKz0gc2l6ZW9mKHU2NCk7CgoJaWYgKHNhbXBsZV90eXBlICYgUEVSRl9TQU1QTEVfR1JPVVApIHsKCQloZWFkZXIuc2l6ZSArPSBzaXplb2YodTY0KSArCgkJCWNvdW50ZXItPm5yX3NpYmxpbmdzICogc2l6ZW9mKGdyb3VwX2VudHJ5KTsKCX0KCglpZiAoc2FtcGxlX3R5cGUgJiBQRVJGX1NBTVBMRV9DQUxMQ0hBSU4pIHsKCQljYWxsY2hhaW4gPSBwZXJmX2NhbGxjaGFpbihkYXRhLT5yZWdzKTsKCgkJaWYgKGNhbGxjaGFpbikgewoJCQljYWxsY2hhaW5fc2l6ZSA9ICgxICsgY2FsbGNoYWluLT5ucikgKiBzaXplb2YodTY0KTsKCQkJaGVhZGVyLnNpemUgKz0gY2FsbGNoYWluX3NpemU7CgkJfSBlbHNlCgkJCWhlYWRlci5zaXplICs9IHNpemVvZih1NjQpOwoJfQoKCXJldCA9IHBlcmZfb3V0cHV0X2JlZ2luKCZoYW5kbGUsIGNvdW50ZXIsIGhlYWRlci5zaXplLCBubWksIDEpOwoJaWYgKHJldCkKCQlyZXR1cm47CgoJcGVyZl9vdXRwdXRfcHV0KCZoYW5kbGUsIGhlYWRlcik7CgoJaWYgKHNhbXBsZV90eXBlICYgUEVSRl9TQU1QTEVfSVApCgkJcGVyZl9vdXRwdXRfcHV0KCZoYW5kbGUsIGlwKTsKCglpZiAoc2FtcGxlX3R5cGUgJiBQRVJGX1NBTVBMRV9USUQpCgkJcGVyZl9vdXRwdXRfcHV0KCZoYW5kbGUsIHRpZF9lbnRyeSk7CgoJaWYgKHNhbXBsZV90eXBlICYgUEVSRl9TQU1QTEVfVElNRSkKCQlwZXJmX291dHB1dF9wdXQoJmhhbmRsZSwgdGltZSk7CgoJaWYgKHNhbXBsZV90eXBlICYgUEVSRl9TQU1QTEVfQUREUikKCQlwZXJmX291dHB1dF9wdXQoJmhhbmRsZSwgZGF0YS0+YWRkcik7CgoJaWYgKHNhbXBsZV90eXBlICYgUEVSRl9TQU1QTEVfSUQpIHsKCQl1NjQgaWQgPSBwcmltYXJ5X2NvdW50ZXJfaWQoY291bnRlcik7CgoJCXBlcmZfb3V0cHV0X3B1dCgmaGFuZGxlLCBpZCk7Cgl9CgoJaWYgKHNhbXBsZV90eXBlICYgUEVSRl9TQU1QTEVfU1RSRUFNX0lEKQoJCXBlcmZfb3V0cHV0X3B1dCgmaGFuZGxlLCBjb3VudGVyLT5pZCk7CgoJaWYgKHNhbXBsZV90eXBlICYgUEVSRl9TQU1QTEVfQ1BVKQoJCXBlcmZfb3V0cHV0X3B1dCgmaGFuZGxlLCBjcHVfZW50cnkpOwoKCWlmIChzYW1wbGVfdHlwZSAmIFBFUkZfU0FNUExFX1BFUklPRCkKCQlwZXJmX291dHB1dF9wdXQoJmhhbmRsZSwgZGF0YS0+cGVyaW9kKTsKCgkvKgoJICogWFhYIFBFUkZfU0FNUExFX0dST1VQIHZzIGluaGVyaXRlZCBjb3VudGVycyBzZWVtcyBkaWZmaWN1bHQuCgkgKi8KCWlmIChzYW1wbGVfdHlwZSAmIFBFUkZfU0FNUExFX0dST1VQKSB7CgkJc3RydWN0IHBlcmZfY291bnRlciAqbGVhZGVyLCAqc3ViOwoJCXU2NCBuciA9IGNvdW50ZXItPm5yX3NpYmxpbmdzOwoKCQlwZXJmX291dHB1dF9wdXQoJmhhbmRsZSwgbnIpOwoKCQlsZWFkZXIgPSBjb3VudGVyLT5ncm91cF9sZWFkZXI7CgkJbGlzdF9mb3JfZWFjaF9lbnRyeShzdWIsICZsZWFkZXItPnNpYmxpbmdfbGlzdCwgbGlzdF9lbnRyeSkgewoJCQlpZiAoc3ViICE9IGNvdW50ZXIpCgkJCQlzdWItPnBtdS0+cmVhZChzdWIpOwoKCQkJZ3JvdXBfZW50cnkuaWQgPSBwcmltYXJ5X2NvdW50ZXJfaWQoc3ViKTsKCQkJZ3JvdXBfZW50cnkuY291bnRlciA9IGF0b21pYzY0X3JlYWQoJnN1Yi0+Y291bnQpOwoKCQkJcGVyZl9vdXRwdXRfcHV0KCZoYW5kbGUsIGdyb3VwX2VudHJ5KTsKCQl9Cgl9CgoJaWYgKHNhbXBsZV90eXBlICYgUEVSRl9TQU1QTEVfQ0FMTENIQUlOKSB7CgkJaWYgKGNhbGxjaGFpbikKCQkJcGVyZl9vdXRwdXRfY29weSgmaGFuZGxlLCBjYWxsY2hhaW4sIGNhbGxjaGFpbl9zaXplKTsKCQllbHNlIHsKCQkJdTY0IG5yID0gMDsKCQkJcGVyZl9vdXRwdXRfcHV0KCZoYW5kbGUsIG5yKTsKCQl9Cgl9CgoJcGVyZl9vdXRwdXRfZW5kKCZoYW5kbGUpOwp9CgovKgogKiByZWFkIGV2ZW50CiAqLwoKc3RydWN0IHBlcmZfcmVhZF9ldmVudCB7CglzdHJ1Y3QgcGVyZl9ldmVudF9oZWFkZXIJaGVhZGVyOwoKCXUzMgkJCQlwaWQ7Cgl1MzIJCQkJdGlkOwoJdTY0CQkJCXZhbHVlOwoJdTY0CQkJCWZvcm1hdFszXTsKfTsKCnN0YXRpYyB2b2lkCnBlcmZfY291bnRlcl9yZWFkX2V2ZW50KHN0cnVjdCBwZXJmX2NvdW50ZXIgKmNvdW50ZXIsCgkJCXN0cnVjdCB0YXNrX3N0cnVjdCAqdGFzaykKewoJc3RydWN0IHBlcmZfb3V0cHV0X2hhbmRsZSBoYW5kbGU7CglzdHJ1Y3QgcGVyZl9yZWFkX2V2ZW50IGV2ZW50ID0gewoJCS5oZWFkZXIgPSB7CgkJCS50eXBlID0gUEVSRl9FVkVOVF9SRUFELAoJCQkubWlzYyA9IDAsCgkJCS5zaXplID0gc2l6ZW9mKGV2ZW50KSAtIHNpemVvZihldmVudC5mb3JtYXQpLAoJCX0sCgkJLnBpZCA9IHBlcmZfY291bnRlcl9waWQoY291bnRlciwgdGFzayksCgkJLnRpZCA9IHBlcmZfY291bnRlcl90aWQoY291bnRlciwgdGFzayksCgkJLnZhbHVlID0gYXRvbWljNjRfcmVhZCgmY291bnRlci0+Y291bnQpLAoJfTsKCWludCByZXQsIGkgPSAwOwoKCWlmIChjb3VudGVyLT5hdHRyLnJlYWRfZm9ybWF0ICYgUEVSRl9GT1JNQVRfVE9UQUxfVElNRV9FTkFCTEVEKSB7CgkJZXZlbnQuaGVhZGVyLnNpemUgKz0gc2l6ZW9mKHU2NCk7CgkJZXZlbnQuZm9ybWF0W2krK10gPSBjb3VudGVyLT50b3RhbF90aW1lX2VuYWJsZWQ7Cgl9CgoJaWYgKGNvdW50ZXItPmF0dHIucmVhZF9mb3JtYXQgJiBQRVJGX0ZPUk1BVF9UT1RBTF9USU1FX1JVTk5JTkcpIHsKCQlldmVudC5oZWFkZXIuc2l6ZSArPSBzaXplb2YodTY0KTsKCQlldmVudC5mb3JtYXRbaSsrXSA9IGNvdW50ZXItPnRvdGFsX3RpbWVfcnVubmluZzsKCX0KCglpZiAoY291bnRlci0+YXR0ci5yZWFkX2Zvcm1hdCAmIFBFUkZfRk9STUFUX0lEKSB7CgkJZXZlbnQuaGVhZGVyLnNpemUgKz0gc2l6ZW9mKHU2NCk7CgkJZXZlbnQuZm9ybWF0W2krK10gPSBwcmltYXJ5X2NvdW50ZXJfaWQoY291bnRlcik7Cgl9CgoJcmV0ID0gcGVyZl9vdXRwdXRfYmVnaW4oJmhhbmRsZSwgY291bnRlciwgZXZlbnQuaGVhZGVyLnNpemUsIDAsIDApOwoJaWYgKHJldCkKCQlyZXR1cm47CgoJcGVyZl9vdXRwdXRfY29weSgmaGFuZGxlLCAmZXZlbnQsIGV2ZW50LmhlYWRlci5zaXplKTsKCXBlcmZfb3V0cHV0X2VuZCgmaGFuZGxlKTsKfQoKLyoKICogZm9yayB0cmFja2luZwogKi8KCnN0cnVjdCBwZXJmX2ZvcmtfZXZlbnQgewoJc3RydWN0IHRhc2tfc3RydWN0CSp0YXNrOwoKCXN0cnVjdCB7CgkJc3RydWN0IHBlcmZfZXZlbnRfaGVhZGVyCWhlYWRlcjsKCgkJdTMyCQkJCXBpZDsKCQl1MzIJCQkJcHBpZDsKCX0gZXZlbnQ7Cn07CgpzdGF0aWMgdm9pZCBwZXJmX2NvdW50ZXJfZm9ya19vdXRwdXQoc3RydWN0IHBlcmZfY291bnRlciAqY291bnRlciwKCQkJCSAgICAgc3RydWN0IHBlcmZfZm9ya19ldmVudCAqZm9ya19ldmVudCkKewoJc3RydWN0IHBlcmZfb3V0cHV0X2hhbmRsZSBoYW5kbGU7CglpbnQgc2l6ZSA9IGZvcmtfZXZlbnQtPmV2ZW50LmhlYWRlci5zaXplOwoJc3RydWN0IHRhc2tfc3RydWN0ICp0YXNrID0gZm9ya19ldmVudC0+dGFzazsKCWludCByZXQgPSBwZXJmX291dHB1dF9iZWdpbigmaGFuZGxlLCBjb3VudGVyLCBzaXplLCAwLCAwKTsKCglpZiAocmV0KQoJCXJldHVybjsKCglmb3JrX2V2ZW50LT5ldmVudC5waWQgPSBwZXJmX2NvdW50ZXJfcGlkKGNvdW50ZXIsIHRhc2spOwoJZm9ya19ldmVudC0+ZXZlbnQucHBpZCA9IHBlcmZfY291bnRlcl9waWQoY291bnRlciwgdGFzay0+cmVhbF9wYXJlbnQpOwoKCXBlcmZfb3V0cHV0X3B1dCgmaGFuZGxlLCBmb3JrX2V2ZW50LT5ldmVudCk7CglwZXJmX291dHB1dF9lbmQoJmhhbmRsZSk7Cn0KCnN0YXRpYyBpbnQgcGVyZl9jb3VudGVyX2ZvcmtfbWF0Y2goc3RydWN0IHBlcmZfY291bnRlciAqY291bnRlcikKewoJaWYgKGNvdW50ZXItPmF0dHIuY29tbSB8fCBjb3VudGVyLT5hdHRyLm1tYXApCgkJcmV0dXJuIDE7CgoJcmV0dXJuIDA7Cn0KCnN0YXRpYyB2b2lkIHBlcmZfY291bnRlcl9mb3JrX2N0eChzdHJ1Y3QgcGVyZl9jb3VudGVyX2NvbnRleHQgKmN0eCwKCQkJCSAgc3RydWN0IHBlcmZfZm9ya19ldmVudCAqZm9ya19ldmVudCkKewoJc3RydWN0IHBlcmZfY291bnRlciAqY291bnRlcjsKCglpZiAoc3lzdGVtX3N0YXRlICE9IFNZU1RFTV9SVU5OSU5HIHx8IGxpc3RfZW1wdHkoJmN0eC0+ZXZlbnRfbGlzdCkpCgkJcmV0dXJuOwoKCXJjdV9yZWFkX2xvY2soKTsKCWxpc3RfZm9yX2VhY2hfZW50cnlfcmN1KGNvdW50ZXIsICZjdHgtPmV2ZW50X2xpc3QsIGV2ZW50X2VudHJ5KSB7CgkJaWYgKHBlcmZfY291bnRlcl9mb3JrX21hdGNoKGNvdW50ZXIpKQoJCQlwZXJmX2NvdW50ZXJfZm9ya19vdXRwdXQoY291bnRlciwgZm9ya19ldmVudCk7Cgl9CglyY3VfcmVhZF91bmxvY2soKTsKfQoKc3RhdGljIHZvaWQgcGVyZl9jb3VudGVyX2ZvcmtfZXZlbnQoc3RydWN0IHBlcmZfZm9ya19ldmVudCAqZm9ya19ldmVudCkKewoJc3RydWN0IHBlcmZfY3B1X2NvbnRleHQgKmNwdWN0eDsKCXN0cnVjdCBwZXJmX2NvdW50ZXJfY29udGV4dCAqY3R4OwoKCWNwdWN0eCA9ICZnZXRfY3B1X3ZhcihwZXJmX2NwdV9jb250ZXh0KTsKCXBlcmZfY291bnRlcl9mb3JrX2N0eCgmY3B1Y3R4LT5jdHgsIGZvcmtfZXZlbnQpOwoJcHV0X2NwdV92YXIocGVyZl9jcHVfY29udGV4dCk7CgoJcmN1X3JlYWRfbG9jaygpOwoJLyoKCSAqIGRvZXNuJ3QgcmVhbGx5IG1hdHRlciB3aGljaCBvZiB0aGUgY2hpbGQgY29udGV4dHMgdGhlCgkgKiBldmVudHMgZW5kcyB1cCBpbi4KCSAqLwoJY3R4ID0gcmN1X2RlcmVmZXJlbmNlKGN1cnJlbnQtPnBlcmZfY291bnRlcl9jdHhwKTsKCWlmIChjdHgpCgkJcGVyZl9jb3VudGVyX2ZvcmtfY3R4KGN0eCwgZm9ya19ldmVudCk7CglyY3VfcmVhZF91bmxvY2soKTsKfQoKdm9pZCBwZXJmX2NvdW50ZXJfZm9yayhzdHJ1Y3QgdGFza19zdHJ1Y3QgKnRhc2spCnsKCXN0cnVjdCBwZXJmX2ZvcmtfZXZlbnQgZm9ya19ldmVudDsKCglpZiAoIWF0b21pY19yZWFkKCZucl9jb21tX2NvdW50ZXJzKSAmJgoJICAgICFhdG9taWNfcmVhZCgmbnJfbW1hcF9jb3VudGVycykpCgkJcmV0dXJuOwoKCWZvcmtfZXZlbnQgPSAoc3RydWN0IHBlcmZfZm9ya19ldmVudCl7CgkJLnRhc2sJPSB0YXNrLAoJCS5ldmVudCAgPSB7CgkJCS5oZWFkZXIgPSB7CgkJCQkudHlwZSA9IFBFUkZfRVZFTlRfRk9SSywKCQkJCS5taXNjID0gMCwKCQkJCS5zaXplID0gc2l6ZW9mKGZvcmtfZXZlbnQuZXZlbnQpLAoJCQl9LAoJCQkvKiAucGlkICAqLwoJCQkvKiAucHBpZCAqLwoJCX0sCgl9OwoKCXBlcmZfY291bnRlcl9mb3JrX2V2ZW50KCZmb3JrX2V2ZW50KTsKfQoKLyoKICogY29tbSB0cmFja2luZwogKi8KCnN0cnVjdCBwZXJmX2NvbW1fZXZlbnQgewoJc3RydWN0IHRhc2tfc3RydWN0CSp0YXNrOwoJY2hhcgkJCSpjb21tOwoJaW50CQkJY29tbV9zaXplOwoKCXN0cnVjdCB7CgkJc3RydWN0IHBlcmZfZXZlbnRfaGVhZGVyCWhlYWRlcjsKCgkJdTMyCQkJCXBpZDsKCQl1MzIJCQkJdGlkOwoJfSBldmVudDsKfTsKCnN0YXRpYyB2b2lkIHBlcmZfY291bnRlcl9jb21tX291dHB1dChzdHJ1Y3QgcGVyZl9jb3VudGVyICpjb3VudGVyLAoJCQkJICAgICBzdHJ1Y3QgcGVyZl9jb21tX2V2ZW50ICpjb21tX2V2ZW50KQp7CglzdHJ1Y3QgcGVyZl9vdXRwdXRfaGFuZGxlIGhhbmRsZTsKCWludCBzaXplID0gY29tbV9ldmVudC0+ZXZlbnQuaGVhZGVyLnNpemU7CglpbnQgcmV0ID0gcGVyZl9vdXRwdXRfYmVnaW4oJmhhbmRsZSwgY291bnRlciwgc2l6ZSwgMCwgMCk7CgoJaWYgKHJldCkKCQlyZXR1cm47CgoJY29tbV9ldmVudC0+ZXZlbnQucGlkID0gcGVyZl9jb3VudGVyX3BpZChjb3VudGVyLCBjb21tX2V2ZW50LT50YXNrKTsKCWNvbW1fZXZlbnQtPmV2ZW50LnRpZCA9IHBlcmZfY291bnRlcl90aWQoY291bnRlciwgY29tbV9ldmVudC0+dGFzayk7CgoJcGVyZl9vdXRwdXRfcHV0KCZoYW5kbGUsIGNvbW1fZXZlbnQtPmV2ZW50KTsKCXBlcmZfb3V0cHV0X2NvcHkoJmhhbmRsZSwgY29tbV9ldmVudC0+Y29tbSwKCQkJCSAgIGNvbW1fZXZlbnQtPmNvbW1fc2l6ZSk7CglwZXJmX291dHB1dF9lbmQoJmhhbmRsZSk7Cn0KCnN0YXRpYyBpbnQgcGVyZl9jb3VudGVyX2NvbW1fbWF0Y2goc3RydWN0IHBlcmZfY291bnRlciAqY291bnRlcikKewoJaWYgKGNvdW50ZXItPmF0dHIuY29tbSkKCQlyZXR1cm4gMTsKCglyZXR1cm4gMDsKfQoKc3RhdGljIHZvaWQgcGVyZl9jb3VudGVyX2NvbW1fY3R4KHN0cnVjdCBwZXJmX2NvdW50ZXJfY29udGV4dCAqY3R4LAoJCQkJICBzdHJ1Y3QgcGVyZl9jb21tX2V2ZW50ICpjb21tX2V2ZW50KQp7CglzdHJ1Y3QgcGVyZl9jb3VudGVyICpjb3VudGVyOwoKCWlmIChzeXN0ZW1fc3RhdGUgIT0gU1lTVEVNX1JVTk5JTkcgfHwgbGlzdF9lbXB0eSgmY3R4LT5ldmVudF9saXN0KSkKCQlyZXR1cm47CgoJcmN1X3JlYWRfbG9jaygpOwoJbGlzdF9mb3JfZWFjaF9lbnRyeV9yY3UoY291bnRlciwgJmN0eC0+ZXZlbnRfbGlzdCwgZXZlbnRfZW50cnkpIHsKCQlpZiAocGVyZl9jb3VudGVyX2NvbW1fbWF0Y2goY291bnRlcikpCgkJCXBlcmZfY291bnRlcl9jb21tX291dHB1dChjb3VudGVyLCBjb21tX2V2ZW50KTsKCX0KCXJjdV9yZWFkX3VubG9jaygpOwp9CgpzdGF0aWMgdm9pZCBwZXJmX2NvdW50ZXJfY29tbV9ldmVudChzdHJ1Y3QgcGVyZl9jb21tX2V2ZW50ICpjb21tX2V2ZW50KQp7CglzdHJ1Y3QgcGVyZl9jcHVfY29udGV4dCAqY3B1Y3R4OwoJc3RydWN0IHBlcmZfY291bnRlcl9jb250ZXh0ICpjdHg7Cgl1bnNpZ25lZCBpbnQgc2l6ZTsKCWNoYXIgY29tbVtUQVNLX0NPTU1fTEVOXTsKCgltZW1zZXQoY29tbSwgMCwgc2l6ZW9mKGNvbW0pKTsKCXN0cm5jcHkoY29tbSwgY29tbV9ldmVudC0+dGFzay0+Y29tbSwgc2l6ZW9mKGNvbW0pKTsKCXNpemUgPSBBTElHTihzdHJsZW4oY29tbSkrMSwgc2l6ZW9mKHU2NCkpOwoKCWNvbW1fZXZlbnQtPmNvbW0gPSBjb21tOwoJY29tbV9ldmVudC0+Y29tbV9zaXplID0gc2l6ZTsKCgljb21tX2V2ZW50LT5ldmVudC5oZWFkZXIuc2l6ZSA9IHNpemVvZihjb21tX2V2ZW50LT5ldmVudCkgKyBzaXplOwoKCWNwdWN0eCA9ICZnZXRfY3B1X3ZhcihwZXJmX2NwdV9jb250ZXh0KTsKCXBlcmZfY291bnRlcl9jb21tX2N0eCgmY3B1Y3R4LT5jdHgsIGNvbW1fZXZlbnQpOwoJcHV0X2NwdV92YXIocGVyZl9jcHVfY29udGV4dCk7CgoJcmN1X3JlYWRfbG9jaygpOwoJLyoKCSAqIGRvZXNuJ3QgcmVhbGx5IG1hdHRlciB3aGljaCBvZiB0aGUgY2hpbGQgY29udGV4dHMgdGhlCgkgKiBldmVudHMgZW5kcyB1cCBpbi4KCSAqLwoJY3R4ID0gcmN1X2RlcmVmZXJlbmNlKGN1cnJlbnQtPnBlcmZfY291bnRlcl9jdHhwKTsKCWlmIChjdHgpCgkJcGVyZl9jb3VudGVyX2NvbW1fY3R4KGN0eCwgY29tbV9ldmVudCk7CglyY3VfcmVhZF91bmxvY2soKTsKfQoKdm9pZCBwZXJmX2NvdW50ZXJfY29tbShzdHJ1Y3QgdGFza19zdHJ1Y3QgKnRhc2spCnsKCXN0cnVjdCBwZXJmX2NvbW1fZXZlbnQgY29tbV9ldmVudDsKCglpZiAodGFzay0+cGVyZl9jb3VudGVyX2N0eHApCgkJcGVyZl9jb3VudGVyX2VuYWJsZV9vbl9leGVjKHRhc2spOwoKCWlmICghYXRvbWljX3JlYWQoJm5yX2NvbW1fY291bnRlcnMpKQoJCXJldHVybjsKCgljb21tX2V2ZW50ID0gKHN0cnVjdCBwZXJmX2NvbW1fZXZlbnQpewoJCS50YXNrCT0gdGFzaywKCQkvKiAuY29tbSAgICAgICovCgkJLyogLmNvbW1fc2l6ZSAqLwoJCS5ldmVudCAgPSB7CgkJCS5oZWFkZXIgPSB7CgkJCQkudHlwZSA9IFBFUkZfRVZFTlRfQ09NTSwKCQkJCS5taXNjID0gMCwKCQkJCS8qIC5zaXplICovCgkJCX0sCgkJCS8qIC5waWQgKi8KCQkJLyogLnRpZCAqLwoJCX0sCgl9OwoKCXBlcmZfY291bnRlcl9jb21tX2V2ZW50KCZjb21tX2V2ZW50KTsKfQoKLyoKICogbW1hcCB0cmFja2luZwogKi8KCnN0cnVjdCBwZXJmX21tYXBfZXZlbnQgewoJc3RydWN0IHZtX2FyZWFfc3RydWN0CSp2bWE7CgoJY29uc3QgY2hhcgkJKmZpbGVfbmFtZTsKCWludAkJCWZpbGVfc2l6ZTsKCglzdHJ1Y3QgewoJCXN0cnVjdCBwZXJmX2V2ZW50X2hlYWRlcgloZWFkZXI7CgoJCXUzMgkJCQlwaWQ7CgkJdTMyCQkJCXRpZDsKCQl1NjQJCQkJc3RhcnQ7CgkJdTY0CQkJCWxlbjsKCQl1NjQJCQkJcGdvZmY7Cgl9IGV2ZW50Owp9OwoKc3RhdGljIHZvaWQgcGVyZl9jb3VudGVyX21tYXBfb3V0cHV0KHN0cnVjdCBwZXJmX2NvdW50ZXIgKmNvdW50ZXIsCgkJCQkgICAgIHN0cnVjdCBwZXJmX21tYXBfZXZlbnQgKm1tYXBfZXZlbnQpCnsKCXN0cnVjdCBwZXJmX291dHB1dF9oYW5kbGUgaGFuZGxlOwoJaW50IHNpemUgPSBtbWFwX2V2ZW50LT5ldmVudC5oZWFkZXIuc2l6ZTsKCWludCByZXQgPSBwZXJmX291dHB1dF9iZWdpbigmaGFuZGxlLCBjb3VudGVyLCBzaXplLCAwLCAwKTsKCglpZiAocmV0KQoJCXJldHVybjsKCgltbWFwX2V2ZW50LT5ldmVudC5waWQgPSBwZXJmX2NvdW50ZXJfcGlkKGNvdW50ZXIsIGN1cnJlbnQpOwoJbW1hcF9ldmVudC0+ZXZlbnQudGlkID0gcGVyZl9jb3VudGVyX3RpZChjb3VudGVyLCBjdXJyZW50KTsKCglwZXJmX291dHB1dF9wdXQoJmhhbmRsZSwgbW1hcF9ldmVudC0+ZXZlbnQpOwoJcGVyZl9vdXRwdXRfY29weSgmaGFuZGxlLCBtbWFwX2V2ZW50LT5maWxlX25hbWUsCgkJCQkgICBtbWFwX2V2ZW50LT5maWxlX3NpemUpOwoJcGVyZl9vdXRwdXRfZW5kKCZoYW5kbGUpOwp9CgpzdGF0aWMgaW50IHBlcmZfY291bnRlcl9tbWFwX21hdGNoKHN0cnVjdCBwZXJmX2NvdW50ZXIgKmNvdW50ZXIsCgkJCQkgICBzdHJ1Y3QgcGVyZl9tbWFwX2V2ZW50ICptbWFwX2V2ZW50KQp7CglpZiAoY291bnRlci0+YXR0ci5tbWFwKQoJCXJldHVybiAxOwoKCXJldHVybiAwOwp9CgpzdGF0aWMgdm9pZCBwZXJmX2NvdW50ZXJfbW1hcF9jdHgoc3RydWN0IHBlcmZfY291bnRlcl9jb250ZXh0ICpjdHgsCgkJCQkgIHN0cnVjdCBwZXJmX21tYXBfZXZlbnQgKm1tYXBfZXZlbnQpCnsKCXN0cnVjdCBwZXJmX2NvdW50ZXIgKmNvdW50ZXI7CgoJaWYgKHN5c3RlbV9zdGF0ZSAhPSBTWVNURU1fUlVOTklORyB8fCBsaXN0X2VtcHR5KCZjdHgtPmV2ZW50X2xpc3QpKQoJCXJldHVybjsKCglyY3VfcmVhZF9sb2NrKCk7CglsaXN0X2Zvcl9lYWNoX2VudHJ5X3JjdShjb3VudGVyLCAmY3R4LT5ldmVudF9saXN0LCBldmVudF9lbnRyeSkgewoJCWlmIChwZXJmX2NvdW50ZXJfbW1hcF9tYXRjaChjb3VudGVyLCBtbWFwX2V2ZW50KSkKCQkJcGVyZl9jb3VudGVyX21tYXBfb3V0cHV0KGNvdW50ZXIsIG1tYXBfZXZlbnQpOwoJfQoJcmN1X3JlYWRfdW5sb2NrKCk7Cn0KCnN0YXRpYyB2b2lkIHBlcmZfY291bnRlcl9tbWFwX2V2ZW50KHN0cnVjdCBwZXJmX21tYXBfZXZlbnQgKm1tYXBfZXZlbnQpCnsKCXN0cnVjdCBwZXJmX2NwdV9jb250ZXh0ICpjcHVjdHg7CglzdHJ1Y3QgcGVyZl9jb3VudGVyX2NvbnRleHQgKmN0eDsKCXN0cnVjdCB2bV9hcmVhX3N0cnVjdCAqdm1hID0gbW1hcF9ldmVudC0+dm1hOwoJc3RydWN0IGZpbGUgKmZpbGUgPSB2bWEtPnZtX2ZpbGU7Cgl1bnNpZ25lZCBpbnQgc2l6ZTsKCWNoYXIgdG1wWzE2XTsKCWNoYXIgKmJ1ZiA9IE5VTEw7Cgljb25zdCBjaGFyICpuYW1lOwoKCW1lbXNldCh0bXAsIDAsIHNpemVvZih0bXApKTsKCglpZiAoZmlsZSkgewoJCS8qCgkJICogZF9wYXRoIHdvcmtzIGZyb20gdGhlIGVuZCBvZiB0aGUgYnVmZmVyIGJhY2t3YXJkcywgc28gd2UKCQkgKiBuZWVkIHRvIGFkZCBlbm91Z2ggemVybyBieXRlcyBhZnRlciB0aGUgc3RyaW5nIHRvIGhhbmRsZQoJCSAqIHRoZSA2NGJpdCBhbGlnbm1lbnQgd2UgZG8gbGF0ZXIuCgkJICovCgkJYnVmID0ga3phbGxvYyhQQVRIX01BWCArIHNpemVvZih1NjQpLCBHRlBfS0VSTkVMKTsKCQlpZiAoIWJ1ZikgewoJCQluYW1lID0gc3RybmNweSh0bXAsICIvL2Vub21lbSIsIHNpemVvZih0bXApKTsKCQkJZ290byBnb3RfbmFtZTsKCQl9CgkJbmFtZSA9IGRfcGF0aCgmZmlsZS0+Zl9wYXRoLCBidWYsIFBBVEhfTUFYKTsKCQlpZiAoSVNfRVJSKG5hbWUpKSB7CgkJCW5hbWUgPSBzdHJuY3B5KHRtcCwgIi8vdG9vbG9uZyIsIHNpemVvZih0bXApKTsKCQkJZ290byBnb3RfbmFtZTsKCQl9Cgl9IGVsc2UgewoJCWlmIChhcmNoX3ZtYV9uYW1lKG1tYXBfZXZlbnQtPnZtYSkpIHsKCQkJbmFtZSA9IHN0cm5jcHkodG1wLCBhcmNoX3ZtYV9uYW1lKG1tYXBfZXZlbnQtPnZtYSksCgkJCQkgICAgICAgc2l6ZW9mKHRtcCkpOwoJCQlnb3RvIGdvdF9uYW1lOwoJCX0KCgkJaWYgKCF2bWEtPnZtX21tKSB7CgkJCW5hbWUgPSBzdHJuY3B5KHRtcCwgIlt2ZHNvXSIsIHNpemVvZih0bXApKTsKCQkJZ290byBnb3RfbmFtZTsKCQl9CgoJCW5hbWUgPSBzdHJuY3B5KHRtcCwgIi8vYW5vbiIsIHNpemVvZih0bXApKTsKCQlnb3RvIGdvdF9uYW1lOwoJfQoKZ290X25hbWU6CglzaXplID0gQUxJR04oc3RybGVuKG5hbWUpKzEsIHNpemVvZih1NjQpKTsKCgltbWFwX2V2ZW50LT5maWxlX25hbWUgPSBuYW1lOwoJbW1hcF9ldmVudC0+ZmlsZV9zaXplID0gc2l6ZTsKCgltbWFwX2V2ZW50LT5ldmVudC5oZWFkZXIuc2l6ZSA9IHNpemVvZihtbWFwX2V2ZW50LT5ldmVudCkgKyBzaXplOwoKCWNwdWN0eCA9ICZnZXRfY3B1X3ZhcihwZXJmX2NwdV9jb250ZXh0KTsKCXBlcmZfY291bnRlcl9tbWFwX2N0eCgmY3B1Y3R4LT5jdHgsIG1tYXBfZXZlbnQpOwoJcHV0X2NwdV92YXIocGVyZl9jcHVfY29udGV4dCk7CgoJcmN1X3JlYWRfbG9jaygpOwoJLyoKCSAqIGRvZXNuJ3QgcmVhbGx5IG1hdHRlciB3aGljaCBvZiB0aGUgY2hpbGQgY29udGV4dHMgdGhlCgkgKiBldmVudHMgZW5kcyB1cCBpbi4KCSAqLwoJY3R4ID0gcmN1X2RlcmVmZXJlbmNlKGN1cnJlbnQtPnBlcmZfY291bnRlcl9jdHhwKTsKCWlmIChjdHgpCgkJcGVyZl9jb3VudGVyX21tYXBfY3R4KGN0eCwgbW1hcF9ldmVudCk7CglyY3VfcmVhZF91bmxvY2soKTsKCglrZnJlZShidWYpOwp9Cgp2b2lkIF9fcGVyZl9jb3VudGVyX21tYXAoc3RydWN0IHZtX2FyZWFfc3RydWN0ICp2bWEpCnsKCXN0cnVjdCBwZXJmX21tYXBfZXZlbnQgbW1hcF9ldmVudDsKCglpZiAoIWF0b21pY19yZWFkKCZucl9tbWFwX2NvdW50ZXJzKSkKCQlyZXR1cm47CgoJbW1hcF9ldmVudCA9IChzdHJ1Y3QgcGVyZl9tbWFwX2V2ZW50KXsKCQkudm1hCT0gdm1hLAoJCS8qIC5maWxlX25hbWUgKi8KCQkvKiAuZmlsZV9zaXplICovCgkJLmV2ZW50ICA9IHsKCQkJLmhlYWRlciA9IHsKCQkJCS50eXBlID0gUEVSRl9FVkVOVF9NTUFQLAoJCQkJLm1pc2MgPSAwLAoJCQkJLyogLnNpemUgKi8KCQkJfSwKCQkJLyogLnBpZCAqLwoJCQkvKiAudGlkICovCgkJCS5zdGFydCAgPSB2bWEtPnZtX3N0YXJ0LAoJCQkubGVuICAgID0gdm1hLT52bV9lbmQgLSB2bWEtPnZtX3N0YXJ0LAoJCQkucGdvZmYgID0gdm1hLT52bV9wZ29mZiwKCQl9LAoJfTsKCglwZXJmX2NvdW50ZXJfbW1hcF9ldmVudCgmbW1hcF9ldmVudCk7Cn0KCi8qCiAqIElSUSB0aHJvdHRsZSBsb2dnaW5nCiAqLwoKc3RhdGljIHZvaWQgcGVyZl9sb2dfdGhyb3R0bGUoc3RydWN0IHBlcmZfY291bnRlciAqY291bnRlciwgaW50IGVuYWJsZSkKewoJc3RydWN0IHBlcmZfb3V0cHV0X2hhbmRsZSBoYW5kbGU7CglpbnQgcmV0OwoKCXN0cnVjdCB7CgkJc3RydWN0IHBlcmZfZXZlbnRfaGVhZGVyCWhlYWRlcjsKCQl1NjQJCQkJdGltZTsKCQl1NjQJCQkJaWQ7CgkJdTY0CQkJCXN0cmVhbV9pZDsKCX0gdGhyb3R0bGVfZXZlbnQgPSB7CgkJLmhlYWRlciA9IHsKCQkJLnR5cGUgPSBQRVJGX0VWRU5UX1RIUk9UVExFLAoJCQkubWlzYyA9IDAsCgkJCS5zaXplID0gc2l6ZW9mKHRocm90dGxlX2V2ZW50KSwKCQl9LAoJCS50aW1lCQk9IHNjaGVkX2Nsb2NrKCksCgkJLmlkCQk9IHByaW1hcnlfY291bnRlcl9pZChjb3VudGVyKSwKCQkuc3RyZWFtX2lkCT0gY291bnRlci0+aWQsCgl9OwoKCWlmIChlbmFibGUpCgkJdGhyb3R0bGVfZXZlbnQuaGVhZGVyLnR5cGUgPSBQRVJGX0VWRU5UX1VOVEhST1RUTEU7CgoJcmV0ID0gcGVyZl9vdXRwdXRfYmVnaW4oJmhhbmRsZSwgY291bnRlciwgc2l6ZW9mKHRocm90dGxlX2V2ZW50KSwgMSwgMCk7CglpZiAocmV0KQoJCXJldHVybjsKCglwZXJmX291dHB1dF9wdXQoJmhhbmRsZSwgdGhyb3R0bGVfZXZlbnQpOwoJcGVyZl9vdXRwdXRfZW5kKCZoYW5kbGUpOwp9CgovKgogKiBHZW5lcmljIGNvdW50ZXIgb3ZlcmZsb3cgaGFuZGxpbmcsIHNhbXBsaW5nLgogKi8KCmludCBwZXJmX2NvdW50ZXJfb3ZlcmZsb3coc3RydWN0IHBlcmZfY291bnRlciAqY291bnRlciwgaW50IG5taSwKCQkJICBzdHJ1Y3QgcGVyZl9zYW1wbGVfZGF0YSAqZGF0YSkKewoJaW50IGV2ZW50cyA9IGF0b21pY19yZWFkKCZjb3VudGVyLT5ldmVudF9saW1pdCk7CglpbnQgdGhyb3R0bGUgPSBjb3VudGVyLT5wbXUtPnVudGhyb3R0bGUgIT0gTlVMTDsKCXN0cnVjdCBod19wZXJmX2NvdW50ZXIgKmh3YyA9ICZjb3VudGVyLT5odzsKCWludCByZXQgPSAwOwoKCWlmICghdGhyb3R0bGUpIHsKCQlod2MtPmludGVycnVwdHMrKzsKCX0gZWxzZSB7CgkJaWYgKGh3Yy0+aW50ZXJydXB0cyAhPSBNQVhfSU5URVJSVVBUUykgewoJCQlod2MtPmludGVycnVwdHMrKzsKCQkJaWYgKEhaICogaHdjLT5pbnRlcnJ1cHRzID4KCQkJCQkodTY0KXN5c2N0bF9wZXJmX2NvdW50ZXJfc2FtcGxlX3JhdGUpIHsKCQkJCWh3Yy0+aW50ZXJydXB0cyA9IE1BWF9JTlRFUlJVUFRTOwoJCQkJcGVyZl9sb2dfdGhyb3R0bGUoY291bnRlciwgMCk7CgkJCQlyZXQgPSAxOwoJCQl9CgkJfSBlbHNlIHsKCQkJLyoKCQkJICogS2VlcCByZS1kaXNhYmxpbmcgY291bnRlcnMgZXZlbiB0aG91Z2ggb24gdGhlIHByZXZpb3VzCgkJCSAqIHBhc3Mgd2UgZGlzYWJsZWQgaXQgLSBqdXN0IGluIGNhc2Ugd2UgcmFjZWQgd2l0aCBhCgkJCSAqIHNjaGVkLWluIGFuZCB0aGUgY291bnRlciBnb3QgZW5hYmxlZCBhZ2FpbjoKCQkJICovCgkJCXJldCA9IDE7CgkJfQoJfQoKCWlmIChjb3VudGVyLT5hdHRyLmZyZXEpIHsKCQl1NjQgbm93ID0gc2NoZWRfY2xvY2soKTsKCQlzNjQgZGVsdGEgPSBub3cgLSBod2MtPmZyZXFfc3RhbXA7CgoJCWh3Yy0+ZnJlcV9zdGFtcCA9IG5vdzsKCgkJaWYgKGRlbHRhID4gMCAmJiBkZWx0YSA8IFRJQ0tfTlNFQykKCQkJcGVyZl9hZGp1c3RfcGVyaW9kKGNvdW50ZXIsIE5TRUNfUEVSX1NFQyAvIChpbnQpZGVsdGEpOwoJfQoKCS8qCgkgKiBYWFggZXZlbnRfbGltaXQgbWlnaHQgbm90IHF1aXRlIHdvcmsgYXMgZXhwZWN0ZWQgb24gaW5oZXJpdGVkCgkgKiBjb3VudGVycwoJICovCgoJY291bnRlci0+cGVuZGluZ19raWxsID0gUE9MTF9JTjsKCWlmIChldmVudHMgJiYgYXRvbWljX2RlY19hbmRfdGVzdCgmY291bnRlci0+ZXZlbnRfbGltaXQpKSB7CgkJcmV0ID0gMTsKCQljb3VudGVyLT5wZW5kaW5nX2tpbGwgPSBQT0xMX0hVUDsKCQlpZiAobm1pKSB7CgkJCWNvdW50ZXItPnBlbmRpbmdfZGlzYWJsZSA9IDE7CgkJCXBlcmZfcGVuZGluZ19xdWV1ZSgmY291bnRlci0+cGVuZGluZywKCQkJCQkgICBwZXJmX3BlbmRpbmdfY291bnRlcik7CgkJfSBlbHNlCgkJCXBlcmZfY291bnRlcl9kaXNhYmxlKGNvdW50ZXIpOwoJfQoKCXBlcmZfY291bnRlcl9vdXRwdXQoY291bnRlciwgbm1pLCBkYXRhKTsKCXJldHVybiByZXQ7Cn0KCi8qCiAqIEdlbmVyaWMgc29mdHdhcmUgY291bnRlciBpbmZyYXN0cnVjdHVyZQogKi8KCnN0YXRpYyB2b2lkIHBlcmZfc3djb3VudGVyX3VwZGF0ZShzdHJ1Y3QgcGVyZl9jb3VudGVyICpjb3VudGVyKQp7CglzdHJ1Y3QgaHdfcGVyZl9jb3VudGVyICpod2MgPSAmY291bnRlci0+aHc7Cgl1NjQgcHJldiwgbm93OwoJczY0IGRlbHRhOwoKYWdhaW46CglwcmV2ID0gYXRvbWljNjRfcmVhZCgmaHdjLT5wcmV2X2NvdW50KTsKCW5vdyA9IGF0b21pYzY0X3JlYWQoJmh3Yy0+Y291bnQpOwoJaWYgKGF0b21pYzY0X2NtcHhjaGcoJmh3Yy0+cHJldl9jb3VudCwgcHJldiwgbm93KSAhPSBwcmV2KQoJCWdvdG8gYWdhaW47CgoJZGVsdGEgPSBub3cgLSBwcmV2OwoKCWF0b21pYzY0X2FkZChkZWx0YSwgJmNvdW50ZXItPmNvdW50KTsKCWF0b21pYzY0X3N1YihkZWx0YSwgJmh3Yy0+cGVyaW9kX2xlZnQpOwp9CgpzdGF0aWMgdm9pZCBwZXJmX3N3Y291bnRlcl9zZXRfcGVyaW9kKHN0cnVjdCBwZXJmX2NvdW50ZXIgKmNvdW50ZXIpCnsKCXN0cnVjdCBod19wZXJmX2NvdW50ZXIgKmh3YyA9ICZjb3VudGVyLT5odzsKCXM2NCBsZWZ0ID0gYXRvbWljNjRfcmVhZCgmaHdjLT5wZXJpb2RfbGVmdCk7CglzNjQgcGVyaW9kID0gaHdjLT5zYW1wbGVfcGVyaW9kOwoKCWlmICh1bmxpa2VseShsZWZ0IDw9IC1wZXJpb2QpKSB7CgkJbGVmdCA9IHBlcmlvZDsKCQlhdG9taWM2NF9zZXQoJmh3Yy0+cGVyaW9kX2xlZnQsIGxlZnQpOwoJCWh3Yy0+bGFzdF9wZXJpb2QgPSBwZXJpb2Q7Cgl9CgoJaWYgKHVubGlrZWx5KGxlZnQgPD0gMCkpIHsKCQlsZWZ0ICs9IHBlcmlvZDsKCQlhdG9taWM2NF9hZGQocGVyaW9kLCAmaHdjLT5wZXJpb2RfbGVmdCk7CgkJaHdjLT5sYXN0X3BlcmlvZCA9IHBlcmlvZDsKCX0KCglhdG9taWM2NF9zZXQoJmh3Yy0+cHJldl9jb3VudCwgLWxlZnQpOwoJYXRvbWljNjRfc2V0KCZod2MtPmNvdW50LCAtbGVmdCk7Cn0KCnN0YXRpYyBlbnVtIGhydGltZXJfcmVzdGFydCBwZXJmX3N3Y291bnRlcl9ocnRpbWVyKHN0cnVjdCBocnRpbWVyICpocnRpbWVyKQp7CgllbnVtIGhydGltZXJfcmVzdGFydCByZXQgPSBIUlRJTUVSX1JFU1RBUlQ7CglzdHJ1Y3QgcGVyZl9zYW1wbGVfZGF0YSBkYXRhOwoJc3RydWN0IHBlcmZfY291bnRlciAqY291bnRlcjsKCXU2NCBwZXJpb2Q7CgoJY291bnRlcgk9IGNvbnRhaW5lcl9vZihocnRpbWVyLCBzdHJ1Y3QgcGVyZl9jb3VudGVyLCBody5ocnRpbWVyKTsKCWNvdW50ZXItPnBtdS0+cmVhZChjb3VudGVyKTsKCglkYXRhLmFkZHIgPSAwOwoJZGF0YS5yZWdzID0gZ2V0X2lycV9yZWdzKCk7CgkvKgoJICogSW4gY2FzZSB3ZSBleGNsdWRlIGtlcm5lbCBJUHMgb3IgYXJlIHNvbWVob3cgbm90IGluIGludGVycnVwdAoJICogY29udGV4dCwgcHJvdmlkZSB0aGUgbmV4dCBiZXN0IHRoaW5nLCB0aGUgdXNlciBJUC4KCSAqLwoJaWYgKChjb3VudGVyLT5hdHRyLmV4Y2x1ZGVfa2VybmVsIHx8ICFkYXRhLnJlZ3MpICYmCgkJCSFjb3VudGVyLT5hdHRyLmV4Y2x1ZGVfdXNlcikKCQlkYXRhLnJlZ3MgPSB0YXNrX3B0X3JlZ3MoY3VycmVudCk7CgoJaWYgKGRhdGEucmVncykgewoJCWlmIChwZXJmX2NvdW50ZXJfb3ZlcmZsb3coY291bnRlciwgMCwgJmRhdGEpKQoJCQlyZXQgPSBIUlRJTUVSX05PUkVTVEFSVDsKCX0KCglwZXJpb2QgPSBtYXhfdCh1NjQsIDEwMDAwLCBjb3VudGVyLT5ody5zYW1wbGVfcGVyaW9kKTsKCWhydGltZXJfZm9yd2FyZF9ub3coaHJ0aW1lciwgbnNfdG9fa3RpbWUocGVyaW9kKSk7CgoJcmV0dXJuIHJldDsKfQoKc3RhdGljIHZvaWQgcGVyZl9zd2NvdW50ZXJfb3ZlcmZsb3coc3RydWN0IHBlcmZfY291bnRlciAqY291bnRlciwKCQkJCSAgICBpbnQgbm1pLCBzdHJ1Y3QgcGVyZl9zYW1wbGVfZGF0YSAqZGF0YSkKewoJZGF0YS0+cGVyaW9kID0gY291bnRlci0+aHcubGFzdF9wZXJpb2Q7CgoJcGVyZl9zd2NvdW50ZXJfdXBkYXRlKGNvdW50ZXIpOwoJcGVyZl9zd2NvdW50ZXJfc2V0X3BlcmlvZChjb3VudGVyKTsKCWlmIChwZXJmX2NvdW50ZXJfb3ZlcmZsb3coY291bnRlciwgbm1pLCBkYXRhKSkKCQkvKiBzb2Z0LWRpc2FibGUgdGhlIGNvdW50ZXIgKi8KCQk7Cn0KCnN0YXRpYyBpbnQgcGVyZl9zd2NvdW50ZXJfaXNfY291bnRpbmcoc3RydWN0IHBlcmZfY291bnRlciAqY291bnRlcikKewoJc3RydWN0IHBlcmZfY291bnRlcl9jb250ZXh0ICpjdHg7Cgl1bnNpZ25lZCBsb25nIGZsYWdzOwoJaW50IGNvdW50OwoKCWlmIChjb3VudGVyLT5zdGF0ZSA9PSBQRVJGX0NPVU5URVJfU1RBVEVfQUNUSVZFKQoJCXJldHVybiAxOwoKCWlmIChjb3VudGVyLT5zdGF0ZSAhPSBQRVJGX0NPVU5URVJfU1RBVEVfSU5BQ1RJVkUpCgkJcmV0dXJuIDA7CgoJLyoKCSAqIElmIHRoZSBjb3VudGVyIGlzIGluYWN0aXZlLCBpdCBjb3VsZCBiZSBqdXN0IGJlY2F1c2UKCSAqIGl0cyB0YXNrIGlzIHNjaGVkdWxlZCBvdXQsIG9yIGJlY2F1c2UgaXQncyBpbiBhIGdyb3VwCgkgKiB3aGljaCBjb3VsZCBub3QgZ28gb24gdGhlIFBNVS4gIFdlIHdhbnQgdG8gY291bnQgaW4KCSAqIHRoZSBmaXJzdCBjYXNlIGJ1dCBub3QgdGhlIHNlY29uZC4gIElmIHRoZSBjb250ZXh0IGlzCgkgKiBjdXJyZW50bHkgYWN0aXZlIHRoZW4gYW4gaW5hY3RpdmUgc29mdHdhcmUgY291bnRlciBtdXN0CgkgKiBiZSB0aGUgc2Vjb25kIGNhc2UuICBJZiBpdCdzIG5vdCBjdXJyZW50bHkgYWN0aXZlIHRoZW4KCSAqIHdlIG5lZWQgdG8ga25vdyB3aGV0aGVyIHRoZSBjb3VudGVyIHdhcyBhY3RpdmUgd2hlbiB0aGUKCSAqIGNvbnRleHQgd2FzIGxhc3QgYWN0aXZlLCB3aGljaCB3ZSBjYW4gZGV0ZXJtaW5lIGJ5CgkgKiBjb21wYXJpbmcgY291bnRlci0+dHN0YW1wX3N0b3BwZWQgd2l0aCBjdHgtPnRpbWUuCgkgKgoJICogV2UgYXJlIHdpdGhpbiBhbiBSQ1UgcmVhZC1zaWRlIGNyaXRpY2FsIHNlY3Rpb24sCgkgKiB3aGljaCBwcm90ZWN0cyB0aGUgZXhpc3RlbmNlIG9mICpjdHguCgkgKi8KCWN0eCA9IGNvdW50ZXItPmN0eDsKCXNwaW5fbG9ja19pcnFzYXZlKCZjdHgtPmxvY2ssIGZsYWdzKTsKCWNvdW50ID0gMTsKCS8qIFJlLWNoZWNrIHN0YXRlIG5vdyB3ZSBoYXZlIHRoZSBsb2NrICovCglpZiAoY291bnRlci0+c3RhdGUgPCBQRVJGX0NPVU5URVJfU1RBVEVfSU5BQ1RJVkUgfHwKCSAgICBjb3VudGVyLT5jdHgtPmlzX2FjdGl2ZSB8fAoJICAgIGNvdW50ZXItPnRzdGFtcF9zdG9wcGVkIDwgY3R4LT50aW1lKQoJCWNvdW50ID0gMDsKCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJmN0eC0+bG9jaywgZmxhZ3MpOwoJcmV0dXJuIGNvdW50Owp9CgpzdGF0aWMgaW50IHBlcmZfc3djb3VudGVyX21hdGNoKHN0cnVjdCBwZXJmX2NvdW50ZXIgKmNvdW50ZXIsCgkJCQllbnVtIHBlcmZfdHlwZV9pZCB0eXBlLAoJCQkJdTMyIGV2ZW50LCBzdHJ1Y3QgcHRfcmVncyAqcmVncykKewoJaWYgKCFwZXJmX3N3Y291bnRlcl9pc19jb3VudGluZyhjb3VudGVyKSkKCQlyZXR1cm4gMDsKCglpZiAoY291bnRlci0+YXR0ci50eXBlICE9IHR5cGUpCgkJcmV0dXJuIDA7CglpZiAoY291bnRlci0+YXR0ci5jb25maWcgIT0gZXZlbnQpCgkJcmV0dXJuIDA7CgoJaWYgKHJlZ3MpIHsKCQlpZiAoY291bnRlci0+YXR0ci5leGNsdWRlX3VzZXIgJiYgdXNlcl9tb2RlKHJlZ3MpKQoJCQlyZXR1cm4gMDsKCgkJaWYgKGNvdW50ZXItPmF0dHIuZXhjbHVkZV9rZXJuZWwgJiYgIXVzZXJfbW9kZShyZWdzKSkKCQkJcmV0dXJuIDA7Cgl9CgoJcmV0dXJuIDE7Cn0KCnN0YXRpYyB2b2lkIHBlcmZfc3djb3VudGVyX2FkZChzdHJ1Y3QgcGVyZl9jb3VudGVyICpjb3VudGVyLCB1NjQgbnIsCgkJCSAgICAgICBpbnQgbm1pLCBzdHJ1Y3QgcGVyZl9zYW1wbGVfZGF0YSAqZGF0YSkKewoJaW50IG5lZyA9IGF0b21pYzY0X2FkZF9uZWdhdGl2ZShuciwgJmNvdW50ZXItPmh3LmNvdW50KTsKCglpZiAoY291bnRlci0+aHcuc2FtcGxlX3BlcmlvZCAmJiAhbmVnICYmIGRhdGEtPnJlZ3MpCgkJcGVyZl9zd2NvdW50ZXJfb3ZlcmZsb3coY291bnRlciwgbm1pLCBkYXRhKTsKfQoKc3RhdGljIHZvaWQgcGVyZl9zd2NvdW50ZXJfY3R4X2V2ZW50KHN0cnVjdCBwZXJmX2NvdW50ZXJfY29udGV4dCAqY3R4LAoJCQkJICAgICBlbnVtIHBlcmZfdHlwZV9pZCB0eXBlLAoJCQkJICAgICB1MzIgZXZlbnQsIHU2NCBuciwgaW50IG5taSwKCQkJCSAgICAgc3RydWN0IHBlcmZfc2FtcGxlX2RhdGEgKmRhdGEpCnsKCXN0cnVjdCBwZXJmX2NvdW50ZXIgKmNvdW50ZXI7CgoJaWYgKHN5c3RlbV9zdGF0ZSAhPSBTWVNURU1fUlVOTklORyB8fCBsaXN0X2VtcHR5KCZjdHgtPmV2ZW50X2xpc3QpKQoJCXJldHVybjsKCglyY3VfcmVhZF9sb2NrKCk7CglsaXN0X2Zvcl9lYWNoX2VudHJ5X3JjdShjb3VudGVyLCAmY3R4LT5ldmVudF9saXN0LCBldmVudF9lbnRyeSkgewoJCWlmIChwZXJmX3N3Y291bnRlcl9tYXRjaChjb3VudGVyLCB0eXBlLCBldmVudCwgZGF0YS0+cmVncykpCgkJCXBlcmZfc3djb3VudGVyX2FkZChjb3VudGVyLCBuciwgbm1pLCBkYXRhKTsKCX0KCXJjdV9yZWFkX3VubG9jaygpOwp9CgpzdGF0aWMgaW50ICpwZXJmX3N3Y291bnRlcl9yZWN1cnNpb25fY29udGV4dChzdHJ1Y3QgcGVyZl9jcHVfY29udGV4dCAqY3B1Y3R4KQp7CglpZiAoaW5fbm1pKCkpCgkJcmV0dXJuICZjcHVjdHgtPnJlY3Vyc2lvblszXTsKCglpZiAoaW5faXJxKCkpCgkJcmV0dXJuICZjcHVjdHgtPnJlY3Vyc2lvblsyXTsKCglpZiAoaW5fc29mdGlycSgpKQoJCXJldHVybiAmY3B1Y3R4LT5yZWN1cnNpb25bMV07CgoJcmV0dXJuICZjcHVjdHgtPnJlY3Vyc2lvblswXTsKfQoKc3RhdGljIHZvaWQgZG9fcGVyZl9zd2NvdW50ZXJfZXZlbnQoZW51bSBwZXJmX3R5cGVfaWQgdHlwZSwgdTMyIGV2ZW50LAoJCQkJICAgIHU2NCBuciwgaW50IG5taSwKCQkJCSAgICBzdHJ1Y3QgcGVyZl9zYW1wbGVfZGF0YSAqZGF0YSkKewoJc3RydWN0IHBlcmZfY3B1X2NvbnRleHQgKmNwdWN0eCA9ICZnZXRfY3B1X3ZhcihwZXJmX2NwdV9jb250ZXh0KTsKCWludCAqcmVjdXJzaW9uID0gcGVyZl9zd2NvdW50ZXJfcmVjdXJzaW9uX2NvbnRleHQoY3B1Y3R4KTsKCXN0cnVjdCBwZXJmX2NvdW50ZXJfY29udGV4dCAqY3R4OwoKCWlmICgqcmVjdXJzaW9uKQoJCWdvdG8gb3V0OwoKCSgqcmVjdXJzaW9uKSsrOwoJYmFycmllcigpOwoKCXBlcmZfc3djb3VudGVyX2N0eF9ldmVudCgmY3B1Y3R4LT5jdHgsIHR5cGUsIGV2ZW50LAoJCQkJIG5yLCBubWksIGRhdGEpOwoJcmN1X3JlYWRfbG9jaygpOwoJLyoKCSAqIGRvZXNuJ3QgcmVhbGx5IG1hdHRlciB3aGljaCBvZiB0aGUgY2hpbGQgY29udGV4dHMgdGhlCgkgKiBldmVudHMgZW5kcyB1cCBpbi4KCSAqLwoJY3R4ID0gcmN1X2RlcmVmZXJlbmNlKGN1cnJlbnQtPnBlcmZfY291bnRlcl9jdHhwKTsKCWlmIChjdHgpCgkJcGVyZl9zd2NvdW50ZXJfY3R4X2V2ZW50KGN0eCwgdHlwZSwgZXZlbnQsIG5yLCBubWksIGRhdGEpOwoJcmN1X3JlYWRfdW5sb2NrKCk7CgoJYmFycmllcigpOwoJKCpyZWN1cnNpb24pLS07CgpvdXQ6CglwdXRfY3B1X3ZhcihwZXJmX2NwdV9jb250ZXh0KTsKfQoKdm9pZCBfX3BlcmZfc3djb3VudGVyX2V2ZW50KHUzMiBldmVudCwgdTY0IG5yLCBpbnQgbm1pLAoJCQkgICAgc3RydWN0IHB0X3JlZ3MgKnJlZ3MsIHU2NCBhZGRyKQp7CglzdHJ1Y3QgcGVyZl9zYW1wbGVfZGF0YSBkYXRhID0gewoJCS5yZWdzID0gcmVncywKCQkuYWRkciA9IGFkZHIsCgl9OwoKCWRvX3BlcmZfc3djb3VudGVyX2V2ZW50KFBFUkZfVFlQRV9TT0ZUV0FSRSwgZXZlbnQsIG5yLCBubWksICZkYXRhKTsKfQoKc3RhdGljIHZvaWQgcGVyZl9zd2NvdW50ZXJfcmVhZChzdHJ1Y3QgcGVyZl9jb3VudGVyICpjb3VudGVyKQp7CglwZXJmX3N3Y291bnRlcl91cGRhdGUoY291bnRlcik7Cn0KCnN0YXRpYyBpbnQgcGVyZl9zd2NvdW50ZXJfZW5hYmxlKHN0cnVjdCBwZXJmX2NvdW50ZXIgKmNvdW50ZXIpCnsKCXBlcmZfc3djb3VudGVyX3NldF9wZXJpb2QoY291bnRlcik7CglyZXR1cm4gMDsKfQoKc3RhdGljIHZvaWQgcGVyZl9zd2NvdW50ZXJfZGlzYWJsZShzdHJ1Y3QgcGVyZl9jb3VudGVyICpjb3VudGVyKQp7CglwZXJmX3N3Y291bnRlcl91cGRhdGUoY291bnRlcik7Cn0KCnN0YXRpYyBjb25zdCBzdHJ1Y3QgcG11IHBlcmZfb3BzX2dlbmVyaWMgPSB7CgkuZW5hYmxlCQk9IHBlcmZfc3djb3VudGVyX2VuYWJsZSwKCS5kaXNhYmxlCT0gcGVyZl9zd2NvdW50ZXJfZGlzYWJsZSwKCS5yZWFkCQk9IHBlcmZfc3djb3VudGVyX3JlYWQsCn07CgovKgogKiBTb2Z0d2FyZSBjb3VudGVyOiBjcHUgd2FsbCB0aW1lIGNsb2NrCiAqLwoKc3RhdGljIHZvaWQgY3B1X2Nsb2NrX3BlcmZfY291bnRlcl91cGRhdGUoc3RydWN0IHBlcmZfY291bnRlciAqY291bnRlcikKewoJaW50IGNwdSA9IHJhd19zbXBfcHJvY2Vzc29yX2lkKCk7CglzNjQgcHJldjsKCXU2NCBub3c7CgoJbm93ID0gY3B1X2Nsb2NrKGNwdSk7CglwcmV2ID0gYXRvbWljNjRfcmVhZCgmY291bnRlci0+aHcucHJldl9jb3VudCk7CglhdG9taWM2NF9zZXQoJmNvdW50ZXItPmh3LnByZXZfY291bnQsIG5vdyk7CglhdG9taWM2NF9hZGQobm93IC0gcHJldiwgJmNvdW50ZXItPmNvdW50KTsKfQoKc3RhdGljIGludCBjcHVfY2xvY2tfcGVyZl9jb3VudGVyX2VuYWJsZShzdHJ1Y3QgcGVyZl9jb3VudGVyICpjb3VudGVyKQp7CglzdHJ1Y3QgaHdfcGVyZl9jb3VudGVyICpod2MgPSAmY291bnRlci0+aHc7CglpbnQgY3B1ID0gcmF3X3NtcF9wcm9jZXNzb3JfaWQoKTsKCglhdG9taWM2NF9zZXQoJmh3Yy0+cHJldl9jb3VudCwgY3B1X2Nsb2NrKGNwdSkpOwoJaHJ0aW1lcl9pbml0KCZod2MtPmhydGltZXIsIENMT0NLX01PTk9UT05JQywgSFJUSU1FUl9NT0RFX1JFTCk7Cglod2MtPmhydGltZXIuZnVuY3Rpb24gPSBwZXJmX3N3Y291bnRlcl9ocnRpbWVyOwoJaWYgKGh3Yy0+c2FtcGxlX3BlcmlvZCkgewoJCXU2NCBwZXJpb2QgPSBtYXhfdCh1NjQsIDEwMDAwLCBod2MtPnNhbXBsZV9wZXJpb2QpOwoJCV9faHJ0aW1lcl9zdGFydF9yYW5nZV9ucygmaHdjLT5ocnRpbWVyLAoJCQkJbnNfdG9fa3RpbWUocGVyaW9kKSwgMCwKCQkJCUhSVElNRVJfTU9ERV9SRUwsIDApOwoJfQoKCXJldHVybiAwOwp9CgpzdGF0aWMgdm9pZCBjcHVfY2xvY2tfcGVyZl9jb3VudGVyX2Rpc2FibGUoc3RydWN0IHBlcmZfY291bnRlciAqY291bnRlcikKewoJaWYgKGNvdW50ZXItPmh3LnNhbXBsZV9wZXJpb2QpCgkJaHJ0aW1lcl9jYW5jZWwoJmNvdW50ZXItPmh3LmhydGltZXIpOwoJY3B1X2Nsb2NrX3BlcmZfY291bnRlcl91cGRhdGUoY291bnRlcik7Cn0KCnN0YXRpYyB2b2lkIGNwdV9jbG9ja19wZXJmX2NvdW50ZXJfcmVhZChzdHJ1Y3QgcGVyZl9jb3VudGVyICpjb3VudGVyKQp7CgljcHVfY2xvY2tfcGVyZl9jb3VudGVyX3VwZGF0ZShjb3VudGVyKTsKfQoKc3RhdGljIGNvbnN0IHN0cnVjdCBwbXUgcGVyZl9vcHNfY3B1X2Nsb2NrID0gewoJLmVuYWJsZQkJPSBjcHVfY2xvY2tfcGVyZl9jb3VudGVyX2VuYWJsZSwKCS5kaXNhYmxlCT0gY3B1X2Nsb2NrX3BlcmZfY291bnRlcl9kaXNhYmxlLAoJLnJlYWQJCT0gY3B1X2Nsb2NrX3BlcmZfY291bnRlcl9yZWFkLAp9OwoKLyoKICogU29mdHdhcmUgY291bnRlcjogdGFzayB0aW1lIGNsb2NrCiAqLwoKc3RhdGljIHZvaWQgdGFza19jbG9ja19wZXJmX2NvdW50ZXJfdXBkYXRlKHN0cnVjdCBwZXJmX2NvdW50ZXIgKmNvdW50ZXIsIHU2NCBub3cpCnsKCXU2NCBwcmV2OwoJczY0IGRlbHRhOwoKCXByZXYgPSBhdG9taWM2NF94Y2hnKCZjb3VudGVyLT5ody5wcmV2X2NvdW50LCBub3cpOwoJZGVsdGEgPSBub3cgLSBwcmV2OwoJYXRvbWljNjRfYWRkKGRlbHRhLCAmY291bnRlci0+Y291bnQpOwp9CgpzdGF0aWMgaW50IHRhc2tfY2xvY2tfcGVyZl9jb3VudGVyX2VuYWJsZShzdHJ1Y3QgcGVyZl9jb3VudGVyICpjb3VudGVyKQp7CglzdHJ1Y3QgaHdfcGVyZl9jb3VudGVyICpod2MgPSAmY291bnRlci0+aHc7Cgl1NjQgbm93OwoKCW5vdyA9IGNvdW50ZXItPmN0eC0+dGltZTsKCglhdG9taWM2NF9zZXQoJmh3Yy0+cHJldl9jb3VudCwgbm93KTsKCWhydGltZXJfaW5pdCgmaHdjLT5ocnRpbWVyLCBDTE9DS19NT05PVE9OSUMsIEhSVElNRVJfTU9ERV9SRUwpOwoJaHdjLT5ocnRpbWVyLmZ1bmN0aW9uID0gcGVyZl9zd2NvdW50ZXJfaHJ0aW1lcjsKCWlmIChod2MtPnNhbXBsZV9wZXJpb2QpIHsKCQl1NjQgcGVyaW9kID0gbWF4X3QodTY0LCAxMDAwMCwgaHdjLT5zYW1wbGVfcGVyaW9kKTsKCQlfX2hydGltZXJfc3RhcnRfcmFuZ2VfbnMoJmh3Yy0+aHJ0aW1lciwKCQkJCW5zX3RvX2t0aW1lKHBlcmlvZCksIDAsCgkJCQlIUlRJTUVSX01PREVfUkVMLCAwKTsKCX0KCglyZXR1cm4gMDsKfQoKc3RhdGljIHZvaWQgdGFza19jbG9ja19wZXJmX2NvdW50ZXJfZGlzYWJsZShzdHJ1Y3QgcGVyZl9jb3VudGVyICpjb3VudGVyKQp7CglpZiAoY291bnRlci0+aHcuc2FtcGxlX3BlcmlvZCkKCQlocnRpbWVyX2NhbmNlbCgmY291bnRlci0+aHcuaHJ0aW1lcik7Cgl0YXNrX2Nsb2NrX3BlcmZfY291bnRlcl91cGRhdGUoY291bnRlciwgY291bnRlci0+Y3R4LT50aW1lKTsKCn0KCnN0YXRpYyB2b2lkIHRhc2tfY2xvY2tfcGVyZl9jb3VudGVyX3JlYWQoc3RydWN0IHBlcmZfY291bnRlciAqY291bnRlcikKewoJdTY0IHRpbWU7CgoJaWYgKCFpbl9ubWkoKSkgewoJCXVwZGF0ZV9jb250ZXh0X3RpbWUoY291bnRlci0+Y3R4KTsKCQl0aW1lID0gY291bnRlci0+Y3R4LT50aW1lOwoJfSBlbHNlIHsKCQl1NjQgbm93ID0gcGVyZl9jbG9jaygpOwoJCXU2NCBkZWx0YSA9IG5vdyAtIGNvdW50ZXItPmN0eC0+dGltZXN0YW1wOwoJCXRpbWUgPSBjb3VudGVyLT5jdHgtPnRpbWUgKyBkZWx0YTsKCX0KCgl0YXNrX2Nsb2NrX3BlcmZfY291bnRlcl91cGRhdGUoY291bnRlciwgdGltZSk7Cn0KCnN0YXRpYyBjb25zdCBzdHJ1Y3QgcG11IHBlcmZfb3BzX3Rhc2tfY2xvY2sgPSB7CgkuZW5hYmxlCQk9IHRhc2tfY2xvY2tfcGVyZl9jb3VudGVyX2VuYWJsZSwKCS5kaXNhYmxlCT0gdGFza19jbG9ja19wZXJmX2NvdW50ZXJfZGlzYWJsZSwKCS5yZWFkCQk9IHRhc2tfY2xvY2tfcGVyZl9jb3VudGVyX3JlYWQsCn07CgojaWZkZWYgQ09ORklHX0VWRU5UX1BST0ZJTEUKdm9pZCBwZXJmX3RwY291bnRlcl9ldmVudChpbnQgZXZlbnRfaWQpCnsKCXN0cnVjdCBwZXJmX3NhbXBsZV9kYXRhIGRhdGEgPSB7CgkJLnJlZ3MgPSBnZXRfaXJxX3JlZ3MoKSwKCQkuYWRkciA9IDAsCgl9OwoKCWlmICghZGF0YS5yZWdzKQoJCWRhdGEucmVncyA9IHRhc2tfcHRfcmVncyhjdXJyZW50KTsKCglkb19wZXJmX3N3Y291bnRlcl9ldmVudChQRVJGX1RZUEVfVFJBQ0VQT0lOVCwgZXZlbnRfaWQsIDEsIDEsICZkYXRhKTsKfQpFWFBPUlRfU1lNQk9MX0dQTChwZXJmX3RwY291bnRlcl9ldmVudCk7CgpleHRlcm4gaW50IGZ0cmFjZV9wcm9maWxlX2VuYWJsZShpbnQpOwpleHRlcm4gdm9pZCBmdHJhY2VfcHJvZmlsZV9kaXNhYmxlKGludCk7CgpzdGF0aWMgdm9pZCB0cF9wZXJmX2NvdW50ZXJfZGVzdHJveShzdHJ1Y3QgcGVyZl9jb3VudGVyICpjb3VudGVyKQp7CglmdHJhY2VfcHJvZmlsZV9kaXNhYmxlKGNvdW50ZXItPmF0dHIuY29uZmlnKTsKfQoKc3RhdGljIGNvbnN0IHN0cnVjdCBwbXUgKnRwX3BlcmZfY291bnRlcl9pbml0KHN0cnVjdCBwZXJmX2NvdW50ZXIgKmNvdW50ZXIpCnsKCWlmIChmdHJhY2VfcHJvZmlsZV9lbmFibGUoY291bnRlci0+YXR0ci5jb25maWcpKQoJCXJldHVybiBOVUxMOwoKCWNvdW50ZXItPmRlc3Ryb3kgPSB0cF9wZXJmX2NvdW50ZXJfZGVzdHJveTsKCglyZXR1cm4gJnBlcmZfb3BzX2dlbmVyaWM7Cn0KI2Vsc2UKc3RhdGljIGNvbnN0IHN0cnVjdCBwbXUgKnRwX3BlcmZfY291bnRlcl9pbml0KHN0cnVjdCBwZXJmX2NvdW50ZXIgKmNvdW50ZXIpCnsKCXJldHVybiBOVUxMOwp9CiNlbmRpZgoKYXRvbWljX3QgcGVyZl9zd2NvdW50ZXJfZW5hYmxlZFtQRVJGX0NPVU5UX1NXX01BWF07CgpzdGF0aWMgdm9pZCBzd19wZXJmX2NvdW50ZXJfZGVzdHJveShzdHJ1Y3QgcGVyZl9jb3VudGVyICpjb3VudGVyKQp7Cgl1NjQgZXZlbnQgPSBjb3VudGVyLT5hdHRyLmNvbmZpZzsKCglXQVJOX09OKGNvdW50ZXItPnBhcmVudCk7CgoJYXRvbWljX2RlYygmcGVyZl9zd2NvdW50ZXJfZW5hYmxlZFtldmVudF0pOwp9CgpzdGF0aWMgY29uc3Qgc3RydWN0IHBtdSAqc3dfcGVyZl9jb3VudGVyX2luaXQoc3RydWN0IHBlcmZfY291bnRlciAqY291bnRlcikKewoJY29uc3Qgc3RydWN0IHBtdSAqcG11ID0gTlVMTDsKCXU2NCBldmVudCA9IGNvdW50ZXItPmF0dHIuY29uZmlnOwoKCS8qCgkgKiBTb2Z0d2FyZSBjb3VudGVycyAoY3VycmVudGx5KSBjYW4ndCBpbiBnZW5lcmFsIGRpc3Rpbmd1aXNoCgkgKiBiZXR3ZWVuIHVzZXIsIGtlcm5lbCBhbmQgaHlwZXJ2aXNvciBldmVudHMuCgkgKiBIb3dldmVyLCBjb250ZXh0IHN3aXRjaGVzIGFuZCBjcHUgbWlncmF0aW9ucyBhcmUgY29uc2lkZXJlZAoJICogdG8gYmUga2VybmVsIGV2ZW50cywgYW5kIHBhZ2UgZmF1bHRzIGFyZSBuZXZlciBoeXBlcnZpc29yCgkgKiBldmVudHMuCgkgKi8KCXN3aXRjaCAoZXZlbnQpIHsKCWNhc2UgUEVSRl9DT1VOVF9TV19DUFVfQ0xPQ0s6CgkJcG11ID0gJnBlcmZfb3BzX2NwdV9jbG9jazsKCgkJYnJlYWs7CgljYXNlIFBFUkZfQ09VTlRfU1dfVEFTS19DTE9DSzoKCQkvKgoJCSAqIElmIHRoZSB1c2VyIGluc3RhbnRpYXRlcyB0aGlzIGFzIGEgcGVyLWNwdSBjb3VudGVyLAoJCSAqIHVzZSB0aGUgY3B1X2Nsb2NrIGNvdW50ZXIgaW5zdGVhZC4KCQkgKi8KCQlpZiAoY291bnRlci0+Y3R4LT50YXNrKQoJCQlwbXUgPSAmcGVyZl9vcHNfdGFza19jbG9jazsKCQllbHNlCgkJCXBtdSA9ICZwZXJmX29wc19jcHVfY2xvY2s7CgoJCWJyZWFrOwoJY2FzZSBQRVJGX0NPVU5UX1NXX1BBR0VfRkFVTFRTOgoJY2FzZSBQRVJGX0NPVU5UX1NXX1BBR0VfRkFVTFRTX01JTjoKCWNhc2UgUEVSRl9DT1VOVF9TV19QQUdFX0ZBVUxUU19NQUo6CgljYXNlIFBFUkZfQ09VTlRfU1dfQ09OVEVYVF9TV0lUQ0hFUzoKCWNhc2UgUEVSRl9DT1VOVF9TV19DUFVfTUlHUkFUSU9OUzoKCQlpZiAoIWNvdW50ZXItPnBhcmVudCkgewoJCQlhdG9taWNfaW5jKCZwZXJmX3N3Y291bnRlcl9lbmFibGVkW2V2ZW50XSk7CgkJCWNvdW50ZXItPmRlc3Ryb3kgPSBzd19wZXJmX2NvdW50ZXJfZGVzdHJveTsKCQl9CgkJcG11ID0gJnBlcmZfb3BzX2dlbmVyaWM7CgkJYnJlYWs7Cgl9CgoJcmV0dXJuIHBtdTsKfQoKLyoKICogQWxsb2NhdGUgYW5kIGluaXRpYWxpemUgYSBjb3VudGVyIHN0cnVjdHVyZQogKi8Kc3RhdGljIHN0cnVjdCBwZXJmX2NvdW50ZXIgKgpwZXJmX2NvdW50ZXJfYWxsb2Moc3RydWN0IHBlcmZfY291bnRlcl9hdHRyICphdHRyLAoJCSAgIGludCBjcHUsCgkJICAgc3RydWN0IHBlcmZfY291bnRlcl9jb250ZXh0ICpjdHgsCgkJICAgc3RydWN0IHBlcmZfY291bnRlciAqZ3JvdXBfbGVhZGVyLAoJCSAgIHN0cnVjdCBwZXJmX2NvdW50ZXIgKnBhcmVudF9jb3VudGVyLAoJCSAgIGdmcF90IGdmcGZsYWdzKQp7Cgljb25zdCBzdHJ1Y3QgcG11ICpwbXU7CglzdHJ1Y3QgcGVyZl9jb3VudGVyICpjb3VudGVyOwoJc3RydWN0IGh3X3BlcmZfY291bnRlciAqaHdjOwoJbG9uZyBlcnI7CgoJY291bnRlciA9IGt6YWxsb2Moc2l6ZW9mKCpjb3VudGVyKSwgZ2ZwZmxhZ3MpOwoJaWYgKCFjb3VudGVyKQoJCXJldHVybiBFUlJfUFRSKC1FTk9NRU0pOwoKCS8qCgkgKiBTaW5nbGUgY291bnRlcnMgYXJlIHRoZWlyIG93biBncm91cCBsZWFkZXJzLCB3aXRoIGFuCgkgKiBlbXB0eSBzaWJsaW5nIGxpc3Q6CgkgKi8KCWlmICghZ3JvdXBfbGVhZGVyKQoJCWdyb3VwX2xlYWRlciA9IGNvdW50ZXI7CgoJbXV0ZXhfaW5pdCgmY291bnRlci0+Y2hpbGRfbXV0ZXgpOwoJSU5JVF9MSVNUX0hFQUQoJmNvdW50ZXItPmNoaWxkX2xpc3QpOwoKCUlOSVRfTElTVF9IRUFEKCZjb3VudGVyLT5saXN0X2VudHJ5KTsKCUlOSVRfTElTVF9IRUFEKCZjb3VudGVyLT5ldmVudF9lbnRyeSk7CglJTklUX0xJU1RfSEVBRCgmY291bnRlci0+c2libGluZ19saXN0KTsKCWluaXRfd2FpdHF1ZXVlX2hlYWQoJmNvdW50ZXItPndhaXRxKTsKCgltdXRleF9pbml0KCZjb3VudGVyLT5tbWFwX211dGV4KTsKCgljb3VudGVyLT5jcHUJCT0gY3B1OwoJY291bnRlci0+YXR0cgkJPSAqYXR0cjsKCWNvdW50ZXItPmdyb3VwX2xlYWRlcgk9IGdyb3VwX2xlYWRlcjsKCWNvdW50ZXItPnBtdQkJPSBOVUxMOwoJY291bnRlci0+Y3R4CQk9IGN0eDsKCWNvdW50ZXItPm9uY3B1CQk9IC0xOwoKCWNvdW50ZXItPnBhcmVudAkJPSBwYXJlbnRfY291bnRlcjsKCgljb3VudGVyLT5ucwkJPSBnZXRfcGlkX25zKGN1cnJlbnQtPm5zcHJveHktPnBpZF9ucyk7Cgljb3VudGVyLT5pZAkJPSBhdG9taWM2NF9pbmNfcmV0dXJuKCZwZXJmX2NvdW50ZXJfaWQpOwoKCWNvdW50ZXItPnN0YXRlCQk9IFBFUkZfQ09VTlRFUl9TVEFURV9JTkFDVElWRTsKCglpZiAoYXR0ci0+ZGlzYWJsZWQpCgkJY291bnRlci0+c3RhdGUgPSBQRVJGX0NPVU5URVJfU1RBVEVfT0ZGOwoKCXBtdSA9IE5VTEw7CgoJaHdjID0gJmNvdW50ZXItPmh3OwoJaHdjLT5zYW1wbGVfcGVyaW9kID0gYXR0ci0+c2FtcGxlX3BlcmlvZDsKCWlmIChhdHRyLT5mcmVxICYmIGF0dHItPnNhbXBsZV9mcmVxKQoJCWh3Yy0+c2FtcGxlX3BlcmlvZCA9IDE7CgoJYXRvbWljNjRfc2V0KCZod2MtPnBlcmlvZF9sZWZ0LCBod2MtPnNhbXBsZV9wZXJpb2QpOwoKCS8qCgkgKiB3ZSBjdXJyZW50bHkgZG8gbm90IHN1cHBvcnQgUEVSRl9TQU1QTEVfR1JPVVAgb24gaW5oZXJpdGVkIGNvdW50ZXJzCgkgKi8KCWlmIChhdHRyLT5pbmhlcml0ICYmIChhdHRyLT5zYW1wbGVfdHlwZSAmIFBFUkZfU0FNUExFX0dST1VQKSkKCQlnb3RvIGRvbmU7CgoJc3dpdGNoIChhdHRyLT50eXBlKSB7CgljYXNlIFBFUkZfVFlQRV9SQVc6CgljYXNlIFBFUkZfVFlQRV9IQVJEV0FSRToKCWNhc2UgUEVSRl9UWVBFX0hXX0NBQ0hFOgoJCXBtdSA9IGh3X3BlcmZfY291bnRlcl9pbml0KGNvdW50ZXIpOwoJCWJyZWFrOwoKCWNhc2UgUEVSRl9UWVBFX1NPRlRXQVJFOgoJCXBtdSA9IHN3X3BlcmZfY291bnRlcl9pbml0KGNvdW50ZXIpOwoJCWJyZWFrOwoKCWNhc2UgUEVSRl9UWVBFX1RSQUNFUE9JTlQ6CgkJcG11ID0gdHBfcGVyZl9jb3VudGVyX2luaXQoY291bnRlcik7CgkJYnJlYWs7CgoJZGVmYXVsdDoKCQlicmVhazsKCX0KZG9uZToKCWVyciA9IDA7CglpZiAoIXBtdSkKCQllcnIgPSAtRUlOVkFMOwoJZWxzZSBpZiAoSVNfRVJSKHBtdSkpCgkJZXJyID0gUFRSX0VSUihwbXUpOwoKCWlmIChlcnIpIHsKCQlpZiAoY291bnRlci0+bnMpCgkJCXB1dF9waWRfbnMoY291bnRlci0+bnMpOwoJCWtmcmVlKGNvdW50ZXIpOwoJCXJldHVybiBFUlJfUFRSKGVycik7Cgl9CgoJY291bnRlci0+cG11ID0gcG11OwoKCWlmICghY291bnRlci0+cGFyZW50KSB7CgkJYXRvbWljX2luYygmbnJfY291bnRlcnMpOwoJCWlmIChjb3VudGVyLT5hdHRyLm1tYXApCgkJCWF0b21pY19pbmMoJm5yX21tYXBfY291bnRlcnMpOwoJCWlmIChjb3VudGVyLT5hdHRyLmNvbW0pCgkJCWF0b21pY19pbmMoJm5yX2NvbW1fY291bnRlcnMpOwoJfQoKCXJldHVybiBjb3VudGVyOwp9CgpzdGF0aWMgaW50IHBlcmZfY29weV9hdHRyKHN0cnVjdCBwZXJmX2NvdW50ZXJfYXR0ciBfX3VzZXIgKnVhdHRyLAoJCQkgIHN0cnVjdCBwZXJmX2NvdW50ZXJfYXR0ciAqYXR0cikKewoJaW50IHJldDsKCXUzMiBzaXplOwoKCWlmICghYWNjZXNzX29rKFZFUklGWV9XUklURSwgdWF0dHIsIFBFUkZfQVRUUl9TSVpFX1ZFUjApKQoJCXJldHVybiAtRUZBVUxUOwoKCS8qCgkgKiB6ZXJvIHRoZSBmdWxsIHN0cnVjdHVyZSwgc28gdGhhdCBhIHNob3J0IGNvcHkgd2lsbCBiZSBuaWNlLgoJICovCgltZW1zZXQoYXR0ciwgMCwgc2l6ZW9mKCphdHRyKSk7CgoJcmV0ID0gZ2V0X3VzZXIoc2l6ZSwgJnVhdHRyLT5zaXplKTsKCWlmIChyZXQpCgkJcmV0dXJuIHJldDsKCglpZiAoc2l6ZSA+IFBBR0VfU0laRSkJLyogc2lsbHkgbGFyZ2UgKi8KCQlnb3RvIGVycl9zaXplOwoKCWlmICghc2l6ZSkJCS8qIGFiaSBjb21wYXQgKi8KCQlzaXplID0gUEVSRl9BVFRSX1NJWkVfVkVSMDsKCglpZiAoc2l6ZSA8IFBFUkZfQVRUUl9TSVpFX1ZFUjApCgkJZ290byBlcnJfc2l6ZTsKCgkvKgoJICogSWYgd2UncmUgaGFuZGVkIGEgYmlnZ2VyIHN0cnVjdCB0aGFuIHdlIGtub3cgb2YsCgkgKiBlbnN1cmUgYWxsIHRoZSB1bmtub3duIGJpdHMgYXJlIDAuCgkgKi8KCWlmIChzaXplID4gc2l6ZW9mKCphdHRyKSkgewoJCXVuc2lnbmVkIGxvbmcgdmFsOwoJCXVuc2lnbmVkIGxvbmcgX191c2VyICphZGRyOwoJCXVuc2lnbmVkIGxvbmcgX191c2VyICplbmQ7CgoJCWFkZHIgPSBQVFJfQUxJR04oKHZvaWQgX191c2VyICopdWF0dHIgKyBzaXplb2YoKmF0dHIpLAoJCQkJc2l6ZW9mKHVuc2lnbmVkIGxvbmcpKTsKCQllbmQgID0gUFRSX0FMSUdOKCh2b2lkIF9fdXNlciAqKXVhdHRyICsgc2l6ZSwKCQkJCXNpemVvZih1bnNpZ25lZCBsb25nKSk7CgoJCWZvciAoOyBhZGRyIDwgZW5kOyBhZGRyICs9IHNpemVvZih1bnNpZ25lZCBsb25nKSkgewoJCQlyZXQgPSBnZXRfdXNlcih2YWwsIGFkZHIpOwoJCQlpZiAocmV0KQoJCQkJcmV0dXJuIHJldDsKCQkJaWYgKHZhbCkKCQkJCWdvdG8gZXJyX3NpemU7CgkJfQoJfQoKCXJldCA9IGNvcHlfZnJvbV91c2VyKGF0dHIsIHVhdHRyLCBzaXplKTsKCWlmIChyZXQpCgkJcmV0dXJuIC1FRkFVTFQ7CgoJLyoKCSAqIElmIHRoZSB0eXBlIGV4aXN0cywgdGhlIGNvcnJlc3BvbmRpbmcgY3JlYXRpb24gd2lsbCB2ZXJpZnkKCSAqIHRoZSBhdHRyLT5jb25maWcuCgkgKi8KCWlmIChhdHRyLT50eXBlID49IFBFUkZfVFlQRV9NQVgpCgkJcmV0dXJuIC1FSU5WQUw7CgoJaWYgKGF0dHItPl9fcmVzZXJ2ZWRfMSB8fCBhdHRyLT5fX3Jlc2VydmVkXzIgfHwgYXR0ci0+X19yZXNlcnZlZF8zKQoJCXJldHVybiAtRUlOVkFMOwoKCWlmIChhdHRyLT5zYW1wbGVfdHlwZSAmIH4oUEVSRl9TQU1QTEVfTUFYLTEpKQoJCXJldHVybiAtRUlOVkFMOwoKCWlmIChhdHRyLT5yZWFkX2Zvcm1hdCAmIH4oUEVSRl9GT1JNQVRfTUFYLTEpKQoJCXJldHVybiAtRUlOVkFMOwoKb3V0OgoJcmV0dXJuIHJldDsKCmVycl9zaXplOgoJcHV0X3VzZXIoc2l6ZW9mKCphdHRyKSwgJnVhdHRyLT5zaXplKTsKCXJldCA9IC1FMkJJRzsKCWdvdG8gb3V0Owp9CgovKioKICogc3lzX3BlcmZfY291bnRlcl9vcGVuIC0gb3BlbiBhIHBlcmZvcm1hbmNlIGNvdW50ZXIsIGFzc29jaWF0ZSBpdCB0byBhIHRhc2svY3B1CiAqCiAqIEBhdHRyX3VwdHI6CWV2ZW50IHR5cGUgYXR0cmlidXRlcyBmb3IgbW9uaXRvcmluZy9zYW1wbGluZwogKiBAcGlkOgkJdGFyZ2V0IHBpZAogKiBAY3B1OgkJdGFyZ2V0IGNwdQogKiBAZ3JvdXBfZmQ6CQlncm91cCBsZWFkZXIgY291bnRlciBmZAogKi8KU1lTQ0FMTF9ERUZJTkU1KHBlcmZfY291bnRlcl9vcGVuLAoJCXN0cnVjdCBwZXJmX2NvdW50ZXJfYXR0ciBfX3VzZXIgKiwgYXR0cl91cHRyLAoJCXBpZF90LCBwaWQsIGludCwgY3B1LCBpbnQsIGdyb3VwX2ZkLCB1bnNpZ25lZCBsb25nLCBmbGFncykKewoJc3RydWN0IHBlcmZfY291bnRlciAqY291bnRlciwgKmdyb3VwX2xlYWRlcjsKCXN0cnVjdCBwZXJmX2NvdW50ZXJfYXR0ciBhdHRyOwoJc3RydWN0IHBlcmZfY291bnRlcl9jb250ZXh0ICpjdHg7CglzdHJ1Y3QgZmlsZSAqY291bnRlcl9maWxlID0gTlVMTDsKCXN0cnVjdCBmaWxlICpncm91cF9maWxlID0gTlVMTDsKCWludCBmcHV0X25lZWRlZCA9IDA7CglpbnQgZnB1dF9uZWVkZWQyID0gMDsKCWludCByZXQ7CgoJLyogZm9yIGZ1dHVyZSBleHBhbmRhYmlsaXR5Li4uICovCglpZiAoZmxhZ3MpCgkJcmV0dXJuIC1FSU5WQUw7CgoJcmV0ID0gcGVyZl9jb3B5X2F0dHIoYXR0cl91cHRyLCAmYXR0cik7CglpZiAocmV0KQoJCXJldHVybiByZXQ7CgoJaWYgKCFhdHRyLmV4Y2x1ZGVfa2VybmVsKSB7CgkJaWYgKHBlcmZfcGFyYW5vaWRfa2VybmVsKCkgJiYgIWNhcGFibGUoQ0FQX1NZU19BRE1JTikpCgkJCXJldHVybiAtRUFDQ0VTOwoJfQoKCWlmIChhdHRyLmZyZXEpIHsKCQlpZiAoYXR0ci5zYW1wbGVfZnJlcSA+IHN5c2N0bF9wZXJmX2NvdW50ZXJfc2FtcGxlX3JhdGUpCgkJCXJldHVybiAtRUlOVkFMOwoJfQoKCS8qCgkgKiBHZXQgdGhlIHRhcmdldCBjb250ZXh0ICh0YXNrIG9yIHBlcmNwdSk6CgkgKi8KCWN0eCA9IGZpbmRfZ2V0X2NvbnRleHQocGlkLCBjcHUpOwoJaWYgKElTX0VSUihjdHgpKQoJCXJldHVybiBQVFJfRVJSKGN0eCk7CgoJLyoKCSAqIExvb2sgdXAgdGhlIGdyb3VwIGxlYWRlciAod2Ugd2lsbCBhdHRhY2ggdGhpcyBjb3VudGVyIHRvIGl0KToKCSAqLwoJZ3JvdXBfbGVhZGVyID0gTlVMTDsKCWlmIChncm91cF9mZCAhPSAtMSkgewoJCXJldCA9IC1FSU5WQUw7CgkJZ3JvdXBfZmlsZSA9IGZnZXRfbGlnaHQoZ3JvdXBfZmQsICZmcHV0X25lZWRlZCk7CgkJaWYgKCFncm91cF9maWxlKQoJCQlnb3RvIGVycl9wdXRfY29udGV4dDsKCQlpZiAoZ3JvdXBfZmlsZS0+Zl9vcCAhPSAmcGVyZl9mb3BzKQoJCQlnb3RvIGVycl9wdXRfY29udGV4dDsKCgkJZ3JvdXBfbGVhZGVyID0gZ3JvdXBfZmlsZS0+cHJpdmF0ZV9kYXRhOwoJCS8qCgkJICogRG8gbm90IGFsbG93IGEgcmVjdXJzaXZlIGhpZXJhcmNoeSAodGhpcyBuZXcgc2libGluZwoJCSAqIGJlY29taW5nIHBhcnQgb2YgYW5vdGhlciBncm91cC1zaWJsaW5nKToKCQkgKi8KCQlpZiAoZ3JvdXBfbGVhZGVyLT5ncm91cF9sZWFkZXIgIT0gZ3JvdXBfbGVhZGVyKQoJCQlnb3RvIGVycl9wdXRfY29udGV4dDsKCQkvKgoJCSAqIERvIG5vdCBhbGxvdyB0byBhdHRhY2ggdG8gYSBncm91cCBpbiBhIGRpZmZlcmVudAoJCSAqIHRhc2sgb3IgQ1BVIGNvbnRleHQ6CgkJICovCgkJaWYgKGdyb3VwX2xlYWRlci0+Y3R4ICE9IGN0eCkKCQkJZ290byBlcnJfcHV0X2NvbnRleHQ7CgkJLyoKCQkgKiBPbmx5IGEgZ3JvdXAgbGVhZGVyIGNhbiBiZSBleGNsdXNpdmUgb3IgcGlubmVkCgkJICovCgkJaWYgKGF0dHIuZXhjbHVzaXZlIHx8IGF0dHIucGlubmVkKQoJCQlnb3RvIGVycl9wdXRfY29udGV4dDsKCX0KCgljb3VudGVyID0gcGVyZl9jb3VudGVyX2FsbG9jKCZhdHRyLCBjcHUsIGN0eCwgZ3JvdXBfbGVhZGVyLAoJCQkJICAgICBOVUxMLCBHRlBfS0VSTkVMKTsKCXJldCA9IFBUUl9FUlIoY291bnRlcik7CglpZiAoSVNfRVJSKGNvdW50ZXIpKQoJCWdvdG8gZXJyX3B1dF9jb250ZXh0OwoKCXJldCA9IGFub25faW5vZGVfZ2V0ZmQoIltwZXJmX2NvdW50ZXJdIiwgJnBlcmZfZm9wcywgY291bnRlciwgMCk7CglpZiAocmV0IDwgMCkKCQlnb3RvIGVycl9mcmVlX3B1dF9jb250ZXh0OwoKCWNvdW50ZXJfZmlsZSA9IGZnZXRfbGlnaHQocmV0LCAmZnB1dF9uZWVkZWQyKTsKCWlmICghY291bnRlcl9maWxlKQoJCWdvdG8gZXJyX2ZyZWVfcHV0X2NvbnRleHQ7CgoJY291bnRlci0+ZmlscCA9IGNvdW50ZXJfZmlsZTsKCVdBUk5fT05fT05DRShjdHgtPnBhcmVudF9jdHgpOwoJbXV0ZXhfbG9jaygmY3R4LT5tdXRleCk7CglwZXJmX2luc3RhbGxfaW5fY29udGV4dChjdHgsIGNvdW50ZXIsIGNwdSk7CgkrK2N0eC0+Z2VuZXJhdGlvbjsKCW11dGV4X3VubG9jaygmY3R4LT5tdXRleCk7CgoJY291bnRlci0+b3duZXIgPSBjdXJyZW50OwoJZ2V0X3Rhc2tfc3RydWN0KGN1cnJlbnQpOwoJbXV0ZXhfbG9jaygmY3VycmVudC0+cGVyZl9jb3VudGVyX211dGV4KTsKCWxpc3RfYWRkX3RhaWwoJmNvdW50ZXItPm93bmVyX2VudHJ5LCAmY3VycmVudC0+cGVyZl9jb3VudGVyX2xpc3QpOwoJbXV0ZXhfdW5sb2NrKCZjdXJyZW50LT5wZXJmX2NvdW50ZXJfbXV0ZXgpOwoKCWZwdXRfbGlnaHQoY291bnRlcl9maWxlLCBmcHV0X25lZWRlZDIpOwoKb3V0X2ZwdXQ6CglmcHV0X2xpZ2h0KGdyb3VwX2ZpbGUsIGZwdXRfbmVlZGVkKTsKCglyZXR1cm4gcmV0OwoKZXJyX2ZyZWVfcHV0X2NvbnRleHQ6CglrZnJlZShjb3VudGVyKTsKCmVycl9wdXRfY29udGV4dDoKCXB1dF9jdHgoY3R4KTsKCglnb3RvIG91dF9mcHV0Owp9CgovKgogKiBpbmhlcml0IGEgY291bnRlciBmcm9tIHBhcmVudCB0YXNrIHRvIGNoaWxkIHRhc2s6CiAqLwpzdGF0aWMgc3RydWN0IHBlcmZfY291bnRlciAqCmluaGVyaXRfY291bnRlcihzdHJ1Y3QgcGVyZl9jb3VudGVyICpwYXJlbnRfY291bnRlciwKCSAgICAgIHN0cnVjdCB0YXNrX3N0cnVjdCAqcGFyZW50LAoJICAgICAgc3RydWN0IHBlcmZfY291bnRlcl9jb250ZXh0ICpwYXJlbnRfY3R4LAoJICAgICAgc3RydWN0IHRhc2tfc3RydWN0ICpjaGlsZCwKCSAgICAgIHN0cnVjdCBwZXJmX2NvdW50ZXIgKmdyb3VwX2xlYWRlciwKCSAgICAgIHN0cnVjdCBwZXJmX2NvdW50ZXJfY29udGV4dCAqY2hpbGRfY3R4KQp7CglzdHJ1Y3QgcGVyZl9jb3VudGVyICpjaGlsZF9jb3VudGVyOwoKCS8qCgkgKiBJbnN0ZWFkIG9mIGNyZWF0aW5nIHJlY3Vyc2l2ZSBoaWVyYXJjaGllcyBvZiBjb3VudGVycywKCSAqIHdlIGxpbmsgaW5oZXJpdGVkIGNvdW50ZXJzIGJhY2sgdG8gdGhlIG9yaWdpbmFsIHBhcmVudCwKCSAqIHdoaWNoIGhhcyBhIGZpbHAgZm9yIHN1cmUsIHdoaWNoIHdlIHVzZSBhcyB0aGUgcmVmZXJlbmNlCgkgKiBjb3VudDoKCSAqLwoJaWYgKHBhcmVudF9jb3VudGVyLT5wYXJlbnQpCgkJcGFyZW50X2NvdW50ZXIgPSBwYXJlbnRfY291bnRlci0+cGFyZW50OwoKCWNoaWxkX2NvdW50ZXIgPSBwZXJmX2NvdW50ZXJfYWxsb2MoJnBhcmVudF9jb3VudGVyLT5hdHRyLAoJCQkJCSAgIHBhcmVudF9jb3VudGVyLT5jcHUsIGNoaWxkX2N0eCwKCQkJCQkgICBncm91cF9sZWFkZXIsIHBhcmVudF9jb3VudGVyLAoJCQkJCSAgIEdGUF9LRVJORUwpOwoJaWYgKElTX0VSUihjaGlsZF9jb3VudGVyKSkKCQlyZXR1cm4gY2hpbGRfY291bnRlcjsKCWdldF9jdHgoY2hpbGRfY3R4KTsKCgkvKgoJICogTWFrZSB0aGUgY2hpbGQgc3RhdGUgZm9sbG93IHRoZSBzdGF0ZSBvZiB0aGUgcGFyZW50IGNvdW50ZXIsCgkgKiBub3QgaXRzIGF0dHIuZGlzYWJsZWQgYml0LiAgV2UgaG9sZCB0aGUgcGFyZW50J3MgbXV0ZXgsCgkgKiBzbyB3ZSB3b24ndCByYWNlIHdpdGggcGVyZl9jb3VudGVyX3tlbiwgZGlzfWFibGVfZmFtaWx5LgoJICovCglpZiAocGFyZW50X2NvdW50ZXItPnN0YXRlID49IFBFUkZfQ09VTlRFUl9TVEFURV9JTkFDVElWRSkKCQljaGlsZF9jb3VudGVyLT5zdGF0ZSA9IFBFUkZfQ09VTlRFUl9TVEFURV9JTkFDVElWRTsKCWVsc2UKCQljaGlsZF9jb3VudGVyLT5zdGF0ZSA9IFBFUkZfQ09VTlRFUl9TVEFURV9PRkY7CgoJaWYgKHBhcmVudF9jb3VudGVyLT5hdHRyLmZyZXEpCgkJY2hpbGRfY291bnRlci0+aHcuc2FtcGxlX3BlcmlvZCA9IHBhcmVudF9jb3VudGVyLT5ody5zYW1wbGVfcGVyaW9kOwoKCS8qCgkgKiBMaW5rIGl0IHVwIGluIHRoZSBjaGlsZCdzIGNvbnRleHQ6CgkgKi8KCWFkZF9jb3VudGVyX3RvX2N0eChjaGlsZF9jb3VudGVyLCBjaGlsZF9jdHgpOwoKCS8qCgkgKiBHZXQgYSByZWZlcmVuY2UgdG8gdGhlIHBhcmVudCBmaWxwIC0gd2Ugd2lsbCBmcHV0IGl0CgkgKiB3aGVuIHRoZSBjaGlsZCBjb3VudGVyIGV4aXRzLiBUaGlzIGlzIHNhZmUgdG8gZG8gYmVjYXVzZQoJICogd2UgYXJlIGluIHRoZSBwYXJlbnQgYW5kIHdlIGtub3cgdGhhdCB0aGUgZmlscCBzdGlsbAoJICogZXhpc3RzIGFuZCBoYXMgYSBub256ZXJvIGNvdW50OgoJICovCglhdG9taWNfbG9uZ19pbmMoJnBhcmVudF9jb3VudGVyLT5maWxwLT5mX2NvdW50KTsKCgkvKgoJICogTGluayB0aGlzIGludG8gdGhlIHBhcmVudCBjb3VudGVyJ3MgY2hpbGQgbGlzdAoJICovCglXQVJOX09OX09OQ0UocGFyZW50X2NvdW50ZXItPmN0eC0+cGFyZW50X2N0eCk7CgltdXRleF9sb2NrKCZwYXJlbnRfY291bnRlci0+Y2hpbGRfbXV0ZXgpOwoJbGlzdF9hZGRfdGFpbCgmY2hpbGRfY291bnRlci0+Y2hpbGRfbGlzdCwgJnBhcmVudF9jb3VudGVyLT5jaGlsZF9saXN0KTsKCW11dGV4X3VubG9jaygmcGFyZW50X2NvdW50ZXItPmNoaWxkX211dGV4KTsKCglyZXR1cm4gY2hpbGRfY291bnRlcjsKfQoKc3RhdGljIGludCBpbmhlcml0X2dyb3VwKHN0cnVjdCBwZXJmX2NvdW50ZXIgKnBhcmVudF9jb3VudGVyLAoJICAgICAgc3RydWN0IHRhc2tfc3RydWN0ICpwYXJlbnQsCgkgICAgICBzdHJ1Y3QgcGVyZl9jb3VudGVyX2NvbnRleHQgKnBhcmVudF9jdHgsCgkgICAgICBzdHJ1Y3QgdGFza19zdHJ1Y3QgKmNoaWxkLAoJICAgICAgc3RydWN0IHBlcmZfY291bnRlcl9jb250ZXh0ICpjaGlsZF9jdHgpCnsKCXN0cnVjdCBwZXJmX2NvdW50ZXIgKmxlYWRlcjsKCXN0cnVjdCBwZXJmX2NvdW50ZXIgKnN1YjsKCXN0cnVjdCBwZXJmX2NvdW50ZXIgKmNoaWxkX2N0cjsKCglsZWFkZXIgPSBpbmhlcml0X2NvdW50ZXIocGFyZW50X2NvdW50ZXIsIHBhcmVudCwgcGFyZW50X2N0eCwKCQkJCSBjaGlsZCwgTlVMTCwgY2hpbGRfY3R4KTsKCWlmIChJU19FUlIobGVhZGVyKSkKCQlyZXR1cm4gUFRSX0VSUihsZWFkZXIpOwoJbGlzdF9mb3JfZWFjaF9lbnRyeShzdWIsICZwYXJlbnRfY291bnRlci0+c2libGluZ19saXN0LCBsaXN0X2VudHJ5KSB7CgkJY2hpbGRfY3RyID0gaW5oZXJpdF9jb3VudGVyKHN1YiwgcGFyZW50LCBwYXJlbnRfY3R4LAoJCQkJCSAgICBjaGlsZCwgbGVhZGVyLCBjaGlsZF9jdHgpOwoJCWlmIChJU19FUlIoY2hpbGRfY3RyKSkKCQkJcmV0dXJuIFBUUl9FUlIoY2hpbGRfY3RyKTsKCX0KCXJldHVybiAwOwp9CgpzdGF0aWMgdm9pZCBzeW5jX2NoaWxkX2NvdW50ZXIoc3RydWN0IHBlcmZfY291bnRlciAqY2hpbGRfY291bnRlciwKCQkJICAgICAgIHN0cnVjdCB0YXNrX3N0cnVjdCAqY2hpbGQpCnsKCXN0cnVjdCBwZXJmX2NvdW50ZXIgKnBhcmVudF9jb3VudGVyID0gY2hpbGRfY291bnRlci0+cGFyZW50OwoJdTY0IGNoaWxkX3ZhbDsKCglpZiAoY2hpbGRfY291bnRlci0+YXR0ci5pbmhlcml0X3N0YXQpCgkJcGVyZl9jb3VudGVyX3JlYWRfZXZlbnQoY2hpbGRfY291bnRlciwgY2hpbGQpOwoKCWNoaWxkX3ZhbCA9IGF0b21pYzY0X3JlYWQoJmNoaWxkX2NvdW50ZXItPmNvdW50KTsKCgkvKgoJICogQWRkIGJhY2sgdGhlIGNoaWxkJ3MgY291bnQgdG8gdGhlIHBhcmVudCdzIGNvdW50OgoJICovCglhdG9taWM2NF9hZGQoY2hpbGRfdmFsLCAmcGFyZW50X2NvdW50ZXItPmNvdW50KTsKCWF0b21pYzY0X2FkZChjaGlsZF9jb3VudGVyLT50b3RhbF90aW1lX2VuYWJsZWQsCgkJICAgICAmcGFyZW50X2NvdW50ZXItPmNoaWxkX3RvdGFsX3RpbWVfZW5hYmxlZCk7CglhdG9taWM2NF9hZGQoY2hpbGRfY291bnRlci0+dG90YWxfdGltZV9ydW5uaW5nLAoJCSAgICAgJnBhcmVudF9jb3VudGVyLT5jaGlsZF90b3RhbF90aW1lX3J1bm5pbmcpOwoKCS8qCgkgKiBSZW1vdmUgdGhpcyBjb3VudGVyIGZyb20gdGhlIHBhcmVudCdzIGxpc3QKCSAqLwoJV0FSTl9PTl9PTkNFKHBhcmVudF9jb3VudGVyLT5jdHgtPnBhcmVudF9jdHgpOwoJbXV0ZXhfbG9jaygmcGFyZW50X2NvdW50ZXItPmNoaWxkX211dGV4KTsKCWxpc3RfZGVsX2luaXQoJmNoaWxkX2NvdW50ZXItPmNoaWxkX2xpc3QpOwoJbXV0ZXhfdW5sb2NrKCZwYXJlbnRfY291bnRlci0+Y2hpbGRfbXV0ZXgpOwoKCS8qCgkgKiBSZWxlYXNlIHRoZSBwYXJlbnQgY291bnRlciwgaWYgdGhpcyB3YXMgdGhlIGxhc3QKCSAqIHJlZmVyZW5jZSB0byBpdC4KCSAqLwoJZnB1dChwYXJlbnRfY291bnRlci0+ZmlscCk7Cn0KCnN0YXRpYyB2b2lkCl9fcGVyZl9jb3VudGVyX2V4aXRfdGFzayhzdHJ1Y3QgcGVyZl9jb3VudGVyICpjaGlsZF9jb3VudGVyLAoJCQkgc3RydWN0IHBlcmZfY291bnRlcl9jb250ZXh0ICpjaGlsZF9jdHgsCgkJCSBzdHJ1Y3QgdGFza19zdHJ1Y3QgKmNoaWxkKQp7CglzdHJ1Y3QgcGVyZl9jb3VudGVyICpwYXJlbnRfY291bnRlcjsKCgl1cGRhdGVfY291bnRlcl90aW1lcyhjaGlsZF9jb3VudGVyKTsKCXBlcmZfY291bnRlcl9yZW1vdmVfZnJvbV9jb250ZXh0KGNoaWxkX2NvdW50ZXIpOwoKCXBhcmVudF9jb3VudGVyID0gY2hpbGRfY291bnRlci0+cGFyZW50OwoJLyoKCSAqIEl0IGNhbiBoYXBwZW4gdGhhdCBwYXJlbnQgZXhpdHMgZmlyc3QsIGFuZCBoYXMgY291bnRlcnMKCSAqIHRoYXQgYXJlIHN0aWxsIGFyb3VuZCBkdWUgdG8gdGhlIGNoaWxkIHJlZmVyZW5jZS4gVGhlc2UKCSAqIGNvdW50ZXJzIG5lZWQgdG8gYmUgemFwcGVkIC0gYnV0IG90aGVyd2lzZSBsaW5nZXIuCgkgKi8KCWlmIChwYXJlbnRfY291bnRlcikgewoJCXN5bmNfY2hpbGRfY291bnRlcihjaGlsZF9jb3VudGVyLCBjaGlsZCk7CgkJZnJlZV9jb3VudGVyKGNoaWxkX2NvdW50ZXIpOwoJfQp9CgovKgogKiBXaGVuIGEgY2hpbGQgdGFzayBleGl0cywgZmVlZCBiYWNrIGNvdW50ZXIgdmFsdWVzIHRvIHBhcmVudCBjb3VudGVycy4KICovCnZvaWQgcGVyZl9jb3VudGVyX2V4aXRfdGFzayhzdHJ1Y3QgdGFza19zdHJ1Y3QgKmNoaWxkKQp7CglzdHJ1Y3QgcGVyZl9jb3VudGVyICpjaGlsZF9jb3VudGVyLCAqdG1wOwoJc3RydWN0IHBlcmZfY291bnRlcl9jb250ZXh0ICpjaGlsZF9jdHg7Cgl1bnNpZ25lZCBsb25nIGZsYWdzOwoKCWlmIChsaWtlbHkoIWNoaWxkLT5wZXJmX2NvdW50ZXJfY3R4cCkpCgkJcmV0dXJuOwoKCWxvY2FsX2lycV9zYXZlKGZsYWdzKTsKCS8qCgkgKiBXZSBjYW4ndCByZXNjaGVkdWxlIGhlcmUgYmVjYXVzZSBpbnRlcnJ1cHRzIGFyZSBkaXNhYmxlZCwKCSAqIGFuZCBlaXRoZXIgY2hpbGQgaXMgY3VycmVudCBvciBpdCBpcyBhIHRhc2sgdGhhdCBjYW4ndCBiZQoJICogc2NoZWR1bGVkLCBzbyB3ZSBhcmUgbm93IHNhZmUgZnJvbSByZXNjaGVkdWxpbmcgY2hhbmdpbmcKCSAqIG91ciBjb250ZXh0LgoJICovCgljaGlsZF9jdHggPSBjaGlsZC0+cGVyZl9jb3VudGVyX2N0eHA7CglfX3BlcmZfY291bnRlcl90YXNrX3NjaGVkX291dChjaGlsZF9jdHgpOwoKCS8qCgkgKiBUYWtlIHRoZSBjb250ZXh0IGxvY2sgaGVyZSBzbyB0aGF0IGlmIGZpbmRfZ2V0X2NvbnRleHQgaXMKCSAqIHJlYWRpbmcgY2hpbGQtPnBlcmZfY291bnRlcl9jdHhwLCB3ZSB3YWl0IHVudGlsIGl0IGhhcwoJICogaW5jcmVtZW50ZWQgdGhlIGNvbnRleHQncyByZWZjb3VudCBiZWZvcmUgd2UgZG8gcHV0X2N0eCBiZWxvdy4KCSAqLwoJc3Bpbl9sb2NrKCZjaGlsZF9jdHgtPmxvY2spOwoJY2hpbGQtPnBlcmZfY291bnRlcl9jdHhwID0gTlVMTDsKCS8qCgkgKiBJZiB0aGlzIGNvbnRleHQgaXMgYSBjbG9uZTsgdW5jbG9uZSBpdCBzbyBpdCBjYW4ndCBnZXQKCSAqIHN3YXBwZWQgdG8gYW5vdGhlciBwcm9jZXNzIHdoaWxlIHdlJ3JlIHJlbW92aW5nIGFsbAoJICogdGhlIGNvdW50ZXJzIGZyb20gaXQuCgkgKi8KCXVuY2xvbmVfY3R4KGNoaWxkX2N0eCk7CglzcGluX3VubG9jaygmY2hpbGRfY3R4LT5sb2NrKTsKCWxvY2FsX2lycV9yZXN0b3JlKGZsYWdzKTsKCgkvKgoJICogV2UgY2FuIHJlY3Vyc2Ugb24gdGhlIHNhbWUgbG9jayB0eXBlIHRocm91Z2g6CgkgKgoJICogICBfX3BlcmZfY291bnRlcl9leGl0X3Rhc2soKQoJICogICAgIHN5bmNfY2hpbGRfY291bnRlcigpCgkgKiAgICAgICBmcHV0KHBhcmVudF9jb3VudGVyLT5maWxwKQoJICogICAgICAgICBwZXJmX3JlbGVhc2UoKQoJICogICAgICAgICAgIG11dGV4X2xvY2soJmN0eC0+bXV0ZXgpCgkgKgoJICogQnV0IHNpbmNlIGl0cyB0aGUgcGFyZW50IGNvbnRleHQgaXQgd29uJ3QgYmUgdGhlIHNhbWUgaW5zdGFuY2UuCgkgKi8KCW11dGV4X2xvY2tfbmVzdGVkKCZjaGlsZF9jdHgtPm11dGV4LCBTSU5HTEVfREVQVEhfTkVTVElORyk7CgphZ2FpbjoKCWxpc3RfZm9yX2VhY2hfZW50cnlfc2FmZShjaGlsZF9jb3VudGVyLCB0bXAsICZjaGlsZF9jdHgtPmNvdW50ZXJfbGlzdCwKCQkJCSBsaXN0X2VudHJ5KQoJCV9fcGVyZl9jb3VudGVyX2V4aXRfdGFzayhjaGlsZF9jb3VudGVyLCBjaGlsZF9jdHgsIGNoaWxkKTsKCgkvKgoJICogSWYgdGhlIGxhc3QgY291bnRlciB3YXMgYSBncm91cCBjb3VudGVyLCBpdCB3aWxsIGhhdmUgYXBwZW5kZWQgYWxsCgkgKiBpdHMgc2libGluZ3MgdG8gdGhlIGxpc3QsIGJ1dCB3ZSBvYnRhaW5lZCAndG1wJyBiZWZvcmUgdGhhdCB3aGljaAoJICogd2lsbCBzdGlsbCBwb2ludCB0byB0aGUgbGlzdCBoZWFkIHRlcm1pbmF0aW5nIHRoZSBpdGVyYXRpb24uCgkgKi8KCWlmICghbGlzdF9lbXB0eSgmY2hpbGRfY3R4LT5jb3VudGVyX2xpc3QpKQoJCWdvdG8gYWdhaW47CgoJbXV0ZXhfdW5sb2NrKCZjaGlsZF9jdHgtPm11dGV4KTsKCglwdXRfY3R4KGNoaWxkX2N0eCk7Cn0KCi8qCiAqIGZyZWUgYW4gdW5leHBvc2VkLCB1bnVzZWQgY29udGV4dCBhcyBjcmVhdGVkIGJ5IGluaGVyaXRhbmNlIGJ5CiAqIGluaXRfdGFzayBiZWxvdywgdXNlZCBieSBmb3JrKCkgaW4gY2FzZSBvZiBmYWlsLgogKi8Kdm9pZCBwZXJmX2NvdW50ZXJfZnJlZV90YXNrKHN0cnVjdCB0YXNrX3N0cnVjdCAqdGFzaykKewoJc3RydWN0IHBlcmZfY291bnRlcl9jb250ZXh0ICpjdHggPSB0YXNrLT5wZXJmX2NvdW50ZXJfY3R4cDsKCXN0cnVjdCBwZXJmX2NvdW50ZXIgKmNvdW50ZXIsICp0bXA7CgoJaWYgKCFjdHgpCgkJcmV0dXJuOwoKCW11dGV4X2xvY2soJmN0eC0+bXV0ZXgpOwphZ2FpbjoKCWxpc3RfZm9yX2VhY2hfZW50cnlfc2FmZShjb3VudGVyLCB0bXAsICZjdHgtPmNvdW50ZXJfbGlzdCwgbGlzdF9lbnRyeSkgewoJCXN0cnVjdCBwZXJmX2NvdW50ZXIgKnBhcmVudCA9IGNvdW50ZXItPnBhcmVudDsKCgkJaWYgKFdBUk5fT05fT05DRSghcGFyZW50KSkKCQkJY29udGludWU7CgoJCW11dGV4X2xvY2soJnBhcmVudC0+Y2hpbGRfbXV0ZXgpOwoJCWxpc3RfZGVsX2luaXQoJmNvdW50ZXItPmNoaWxkX2xpc3QpOwoJCW11dGV4X3VubG9jaygmcGFyZW50LT5jaGlsZF9tdXRleCk7CgoJCWZwdXQocGFyZW50LT5maWxwKTsKCgkJbGlzdF9kZWxfY291bnRlcihjb3VudGVyLCBjdHgpOwoJCWZyZWVfY291bnRlcihjb3VudGVyKTsKCX0KCglpZiAoIWxpc3RfZW1wdHkoJmN0eC0+Y291bnRlcl9saXN0KSkKCQlnb3RvIGFnYWluOwoKCW11dGV4X3VubG9jaygmY3R4LT5tdXRleCk7CgoJcHV0X2N0eChjdHgpOwp9CgovKgogKiBJbml0aWFsaXplIHRoZSBwZXJmX2NvdW50ZXIgY29udGV4dCBpbiB0YXNrX3N0cnVjdAogKi8KaW50IHBlcmZfY291bnRlcl9pbml0X3Rhc2soc3RydWN0IHRhc2tfc3RydWN0ICpjaGlsZCkKewoJc3RydWN0IHBlcmZfY291bnRlcl9jb250ZXh0ICpjaGlsZF9jdHgsICpwYXJlbnRfY3R4OwoJc3RydWN0IHBlcmZfY291bnRlcl9jb250ZXh0ICpjbG9uZWRfY3R4OwoJc3RydWN0IHBlcmZfY291bnRlciAqY291bnRlcjsKCXN0cnVjdCB0YXNrX3N0cnVjdCAqcGFyZW50ID0gY3VycmVudDsKCWludCBpbmhlcml0ZWRfYWxsID0gMTsKCWludCByZXQgPSAwOwoKCWNoaWxkLT5wZXJmX2NvdW50ZXJfY3R4cCA9IE5VTEw7CgoJbXV0ZXhfaW5pdCgmY2hpbGQtPnBlcmZfY291bnRlcl9tdXRleCk7CglJTklUX0xJU1RfSEVBRCgmY2hpbGQtPnBlcmZfY291bnRlcl9saXN0KTsKCglpZiAobGlrZWx5KCFwYXJlbnQtPnBlcmZfY291bnRlcl9jdHhwKSkKCQlyZXR1cm4gMDsKCgkvKgoJICogVGhpcyBpcyBleGVjdXRlZCBmcm9tIHRoZSBwYXJlbnQgdGFzayBjb250ZXh0LCBzbyBpbmhlcml0CgkgKiBjb3VudGVycyB0aGF0IGhhdmUgYmVlbiBtYXJrZWQgZm9yIGNsb25pbmcuCgkgKiBGaXJzdCBhbGxvY2F0ZSBhbmQgaW5pdGlhbGl6ZSBhIGNvbnRleHQgZm9yIHRoZSBjaGlsZC4KCSAqLwoKCWNoaWxkX2N0eCA9IGttYWxsb2Moc2l6ZW9mKHN0cnVjdCBwZXJmX2NvdW50ZXJfY29udGV4dCksIEdGUF9LRVJORUwpOwoJaWYgKCFjaGlsZF9jdHgpCgkJcmV0dXJuIC1FTk9NRU07CgoJX19wZXJmX2NvdW50ZXJfaW5pdF9jb250ZXh0KGNoaWxkX2N0eCwgY2hpbGQpOwoJY2hpbGQtPnBlcmZfY291bnRlcl9jdHhwID0gY2hpbGRfY3R4OwoJZ2V0X3Rhc2tfc3RydWN0KGNoaWxkKTsKCgkvKgoJICogSWYgdGhlIHBhcmVudCdzIGNvbnRleHQgaXMgYSBjbG9uZSwgcGluIGl0IHNvIGl0IHdvbid0IGdldAoJICogc3dhcHBlZCB1bmRlciB1cy4KCSAqLwoJcGFyZW50X2N0eCA9IHBlcmZfcGluX3Rhc2tfY29udGV4dChwYXJlbnQpOwoKCS8qCgkgKiBObyBuZWVkIHRvIGNoZWNrIGlmIHBhcmVudF9jdHggIT0gTlVMTCBoZXJlOyBzaW5jZSB3ZSBzYXcKCSAqIGl0IG5vbi1OVUxMIGVhcmxpZXIsIHRoZSBvbmx5IHJlYXNvbiBmb3IgaXQgdG8gYmVjb21lIE5VTEwKCSAqIGlzIGlmIHdlIGV4aXQsIGFuZCBzaW5jZSB3ZSdyZSBjdXJyZW50bHkgaW4gdGhlIG1pZGRsZSBvZgoJICogYSBmb3JrIHdlIGNhbid0IGJlIGV4aXRpbmcgYXQgdGhlIHNhbWUgdGltZS4KCSAqLwoKCS8qCgkgKiBMb2NrIHRoZSBwYXJlbnQgbGlzdC4gTm8gbmVlZCB0byBsb2NrIHRoZSBjaGlsZCAtIG5vdCBQSUQKCSAqIGhhc2hlZCB5ZXQgYW5kIG5vdCBydW5uaW5nLCBzbyBub2JvZHkgY2FuIGFjY2VzcyBpdC4KCSAqLwoJbXV0ZXhfbG9jaygmcGFyZW50X2N0eC0+bXV0ZXgpOwoKCS8qCgkgKiBXZSBkb250IGhhdmUgdG8gZGlzYWJsZSBOTUlzIC0gd2UgYXJlIG9ubHkgbG9va2luZyBhdAoJICogdGhlIGxpc3QsIG5vdCBtYW5pcHVsYXRpbmcgaXQ6CgkgKi8KCWxpc3RfZm9yX2VhY2hfZW50cnlfcmN1KGNvdW50ZXIsICZwYXJlbnRfY3R4LT5ldmVudF9saXN0LCBldmVudF9lbnRyeSkgewoJCWlmIChjb3VudGVyICE9IGNvdW50ZXItPmdyb3VwX2xlYWRlcikKCQkJY29udGludWU7CgoJCWlmICghY291bnRlci0+YXR0ci5pbmhlcml0KSB7CgkJCWluaGVyaXRlZF9hbGwgPSAwOwoJCQljb250aW51ZTsKCQl9CgoJCXJldCA9IGluaGVyaXRfZ3JvdXAoY291bnRlciwgcGFyZW50LCBwYXJlbnRfY3R4LAoJCQkJCSAgICAgY2hpbGQsIGNoaWxkX2N0eCk7CgkJaWYgKHJldCkgewoJCQlpbmhlcml0ZWRfYWxsID0gMDsKCQkJYnJlYWs7CgkJfQoJfQoKCWlmIChpbmhlcml0ZWRfYWxsKSB7CgkJLyoKCQkgKiBNYXJrIHRoZSBjaGlsZCBjb250ZXh0IGFzIGEgY2xvbmUgb2YgdGhlIHBhcmVudAoJCSAqIGNvbnRleHQsIG9yIG9mIHdoYXRldmVyIHRoZSBwYXJlbnQgaXMgYSBjbG9uZSBvZi4KCQkgKiBOb3RlIHRoYXQgaWYgdGhlIHBhcmVudCBpcyBhIGNsb25lLCBpdCBjb3VsZCBnZXQKCQkgKiB1bmNsb25lZCBhdCBhbnkgcG9pbnQsIGJ1dCB0aGF0IGRvZXNuJ3QgbWF0dGVyCgkJICogYmVjYXVzZSB0aGUgbGlzdCBvZiBjb3VudGVycyBhbmQgdGhlIGdlbmVyYXRpb24KCQkgKiBjb3VudCBjYW4ndCBoYXZlIGNoYW5nZWQgc2luY2Ugd2UgdG9vayB0aGUgbXV0ZXguCgkJICovCgkJY2xvbmVkX2N0eCA9IHJjdV9kZXJlZmVyZW5jZShwYXJlbnRfY3R4LT5wYXJlbnRfY3R4KTsKCQlpZiAoY2xvbmVkX2N0eCkgewoJCQljaGlsZF9jdHgtPnBhcmVudF9jdHggPSBjbG9uZWRfY3R4OwoJCQljaGlsZF9jdHgtPnBhcmVudF9nZW4gPSBwYXJlbnRfY3R4LT5wYXJlbnRfZ2VuOwoJCX0gZWxzZSB7CgkJCWNoaWxkX2N0eC0+cGFyZW50X2N0eCA9IHBhcmVudF9jdHg7CgkJCWNoaWxkX2N0eC0+cGFyZW50X2dlbiA9IHBhcmVudF9jdHgtPmdlbmVyYXRpb247CgkJfQoJCWdldF9jdHgoY2hpbGRfY3R4LT5wYXJlbnRfY3R4KTsKCX0KCgltdXRleF91bmxvY2soJnBhcmVudF9jdHgtPm11dGV4KTsKCglwZXJmX3VucGluX2NvbnRleHQocGFyZW50X2N0eCk7CgoJcmV0dXJuIHJldDsKfQoKc3RhdGljIHZvaWQgX19jcHVpbml0IHBlcmZfY291bnRlcl9pbml0X2NwdShpbnQgY3B1KQp7CglzdHJ1Y3QgcGVyZl9jcHVfY29udGV4dCAqY3B1Y3R4OwoKCWNwdWN0eCA9ICZwZXJfY3B1KHBlcmZfY3B1X2NvbnRleHQsIGNwdSk7CglfX3BlcmZfY291bnRlcl9pbml0X2NvbnRleHQoJmNwdWN0eC0+Y3R4LCBOVUxMKTsKCglzcGluX2xvY2soJnBlcmZfcmVzb3VyY2VfbG9jayk7CgljcHVjdHgtPm1heF9wZXJ0YXNrID0gcGVyZl9tYXhfY291bnRlcnMgLSBwZXJmX3Jlc2VydmVkX3BlcmNwdTsKCXNwaW5fdW5sb2NrKCZwZXJmX3Jlc291cmNlX2xvY2spOwoKCWh3X3BlcmZfY291bnRlcl9zZXR1cChjcHUpOwp9CgojaWZkZWYgQ09ORklHX0hPVFBMVUdfQ1BVCnN0YXRpYyB2b2lkIF9fcGVyZl9jb3VudGVyX2V4aXRfY3B1KHZvaWQgKmluZm8pCnsKCXN0cnVjdCBwZXJmX2NwdV9jb250ZXh0ICpjcHVjdHggPSAmX19nZXRfY3B1X3ZhcihwZXJmX2NwdV9jb250ZXh0KTsKCXN0cnVjdCBwZXJmX2NvdW50ZXJfY29udGV4dCAqY3R4ID0gJmNwdWN0eC0+Y3R4OwoJc3RydWN0IHBlcmZfY291bnRlciAqY291bnRlciwgKnRtcDsKCglsaXN0X2Zvcl9lYWNoX2VudHJ5X3NhZmUoY291bnRlciwgdG1wLCAmY3R4LT5jb3VudGVyX2xpc3QsIGxpc3RfZW50cnkpCgkJX19wZXJmX2NvdW50ZXJfcmVtb3ZlX2Zyb21fY29udGV4dChjb3VudGVyKTsKfQpzdGF0aWMgdm9pZCBwZXJmX2NvdW50ZXJfZXhpdF9jcHUoaW50IGNwdSkKewoJc3RydWN0IHBlcmZfY3B1X2NvbnRleHQgKmNwdWN0eCA9ICZwZXJfY3B1KHBlcmZfY3B1X2NvbnRleHQsIGNwdSk7CglzdHJ1Y3QgcGVyZl9jb3VudGVyX2NvbnRleHQgKmN0eCA9ICZjcHVjdHgtPmN0eDsKCgltdXRleF9sb2NrKCZjdHgtPm11dGV4KTsKCXNtcF9jYWxsX2Z1bmN0aW9uX3NpbmdsZShjcHUsIF9fcGVyZl9jb3VudGVyX2V4aXRfY3B1LCBOVUxMLCAxKTsKCW11dGV4X3VubG9jaygmY3R4LT5tdXRleCk7Cn0KI2Vsc2UKc3RhdGljIGlubGluZSB2b2lkIHBlcmZfY291bnRlcl9leGl0X2NwdShpbnQgY3B1KSB7IH0KI2VuZGlmCgpzdGF0aWMgaW50IF9fY3B1aW5pdApwZXJmX2NwdV9ub3RpZnkoc3RydWN0IG5vdGlmaWVyX2Jsb2NrICpzZWxmLCB1bnNpZ25lZCBsb25nIGFjdGlvbiwgdm9pZCAqaGNwdSkKewoJdW5zaWduZWQgaW50IGNwdSA9IChsb25nKWhjcHU7CgoJc3dpdGNoIChhY3Rpb24pIHsKCgljYXNlIENQVV9VUF9QUkVQQVJFOgoJY2FzZSBDUFVfVVBfUFJFUEFSRV9GUk9aRU46CgkJcGVyZl9jb3VudGVyX2luaXRfY3B1KGNwdSk7CgkJYnJlYWs7CgoJY2FzZSBDUFVfRE9XTl9QUkVQQVJFOgoJY2FzZSBDUFVfRE9XTl9QUkVQQVJFX0ZST1pFTjoKCQlwZXJmX2NvdW50ZXJfZXhpdF9jcHUoY3B1KTsKCQlicmVhazsKCglkZWZhdWx0OgoJCWJyZWFrOwoJfQoKCXJldHVybiBOT1RJRllfT0s7Cn0KCi8qCiAqIFRoaXMgaGFzIHRvIGhhdmUgYSBoaWdoZXIgcHJpb3JpdHkgdGhhbiBtaWdyYXRpb25fbm90aWZpZXIgaW4gc2NoZWQuYy4KICovCnN0YXRpYyBzdHJ1Y3Qgbm90aWZpZXJfYmxvY2sgX19jcHVpbml0ZGF0YSBwZXJmX2NwdV9uYiA9IHsKCS5ub3RpZmllcl9jYWxsCQk9IHBlcmZfY3B1X25vdGlmeSwKCS5wcmlvcml0eQkJPSAyMCwKfTsKCnZvaWQgX19pbml0IHBlcmZfY291bnRlcl9pbml0KHZvaWQpCnsKCXBlcmZfY3B1X25vdGlmeSgmcGVyZl9jcHVfbmIsICh1bnNpZ25lZCBsb25nKUNQVV9VUF9QUkVQQVJFLAoJCQkodm9pZCAqKShsb25nKXNtcF9wcm9jZXNzb3JfaWQoKSk7CglyZWdpc3Rlcl9jcHVfbm90aWZpZXIoJnBlcmZfY3B1X25iKTsKfQoKc3RhdGljIHNzaXplX3QgcGVyZl9zaG93X3Jlc2VydmVfcGVyY3B1KHN0cnVjdCBzeXNkZXZfY2xhc3MgKmNsYXNzLCBjaGFyICpidWYpCnsKCXJldHVybiBzcHJpbnRmKGJ1ZiwgIiVkXG4iLCBwZXJmX3Jlc2VydmVkX3BlcmNwdSk7Cn0KCnN0YXRpYyBzc2l6ZV90CnBlcmZfc2V0X3Jlc2VydmVfcGVyY3B1KHN0cnVjdCBzeXNkZXZfY2xhc3MgKmNsYXNzLAoJCQljb25zdCBjaGFyICpidWYsCgkJCXNpemVfdCBjb3VudCkKewoJc3RydWN0IHBlcmZfY3B1X2NvbnRleHQgKmNwdWN0eDsKCXVuc2lnbmVkIGxvbmcgdmFsOwoJaW50IGVyciwgY3B1LCBtcHQ7CgoJZXJyID0gc3RyaWN0X3N0cnRvdWwoYnVmLCAxMCwgJnZhbCk7CglpZiAoZXJyKQoJCXJldHVybiBlcnI7CglpZiAodmFsID4gcGVyZl9tYXhfY291bnRlcnMpCgkJcmV0dXJuIC1FSU5WQUw7CgoJc3Bpbl9sb2NrKCZwZXJmX3Jlc291cmNlX2xvY2spOwoJcGVyZl9yZXNlcnZlZF9wZXJjcHUgPSB2YWw7Cglmb3JfZWFjaF9vbmxpbmVfY3B1KGNwdSkgewoJCWNwdWN0eCA9ICZwZXJfY3B1KHBlcmZfY3B1X2NvbnRleHQsIGNwdSk7CgkJc3Bpbl9sb2NrX2lycSgmY3B1Y3R4LT5jdHgubG9jayk7CgkJbXB0ID0gbWluKHBlcmZfbWF4X2NvdW50ZXJzIC0gY3B1Y3R4LT5jdHgubnJfY291bnRlcnMsCgkJCSAgcGVyZl9tYXhfY291bnRlcnMgLSBwZXJmX3Jlc2VydmVkX3BlcmNwdSk7CgkJY3B1Y3R4LT5tYXhfcGVydGFzayA9IG1wdDsKCQlzcGluX3VubG9ja19pcnEoJmNwdWN0eC0+Y3R4LmxvY2spOwoJfQoJc3Bpbl91bmxvY2soJnBlcmZfcmVzb3VyY2VfbG9jayk7CgoJcmV0dXJuIGNvdW50Owp9CgpzdGF0aWMgc3NpemVfdCBwZXJmX3Nob3dfb3ZlcmNvbW1pdChzdHJ1Y3Qgc3lzZGV2X2NsYXNzICpjbGFzcywgY2hhciAqYnVmKQp7CglyZXR1cm4gc3ByaW50ZihidWYsICIlZFxuIiwgcGVyZl9vdmVyY29tbWl0KTsKfQoKc3RhdGljIHNzaXplX3QKcGVyZl9zZXRfb3ZlcmNvbW1pdChzdHJ1Y3Qgc3lzZGV2X2NsYXNzICpjbGFzcywgY29uc3QgY2hhciAqYnVmLCBzaXplX3QgY291bnQpCnsKCXVuc2lnbmVkIGxvbmcgdmFsOwoJaW50IGVycjsKCgllcnIgPSBzdHJpY3Rfc3RydG91bChidWYsIDEwLCAmdmFsKTsKCWlmIChlcnIpCgkJcmV0dXJuIGVycjsKCWlmICh2YWwgPiAxKQoJCXJldHVybiAtRUlOVkFMOwoKCXNwaW5fbG9jaygmcGVyZl9yZXNvdXJjZV9sb2NrKTsKCXBlcmZfb3ZlcmNvbW1pdCA9IHZhbDsKCXNwaW5fdW5sb2NrKCZwZXJmX3Jlc291cmNlX2xvY2spOwoKCXJldHVybiBjb3VudDsKfQoKc3RhdGljIFNZU0RFVl9DTEFTU19BVFRSKAoJCQkJcmVzZXJ2ZV9wZXJjcHUsCgkJCQkwNjQ0LAoJCQkJcGVyZl9zaG93X3Jlc2VydmVfcGVyY3B1LAoJCQkJcGVyZl9zZXRfcmVzZXJ2ZV9wZXJjcHUKCQkJKTsKCnN0YXRpYyBTWVNERVZfQ0xBU1NfQVRUUigKCQkJCW92ZXJjb21taXQsCgkJCQkwNjQ0LAoJCQkJcGVyZl9zaG93X292ZXJjb21taXQsCgkJCQlwZXJmX3NldF9vdmVyY29tbWl0CgkJCSk7CgpzdGF0aWMgc3RydWN0IGF0dHJpYnV0ZSAqcGVyZmNsYXNzX2F0dHJzW10gPSB7CgkmYXR0cl9yZXNlcnZlX3BlcmNwdS5hdHRyLAoJJmF0dHJfb3ZlcmNvbW1pdC5hdHRyLAoJTlVMTAp9OwoKc3RhdGljIHN0cnVjdCBhdHRyaWJ1dGVfZ3JvdXAgcGVyZmNsYXNzX2F0dHJfZ3JvdXAgPSB7CgkuYXR0cnMJCQk9IHBlcmZjbGFzc19hdHRycywKCS5uYW1lCQkJPSAicGVyZl9jb3VudGVycyIsCn07CgpzdGF0aWMgaW50IF9faW5pdCBwZXJmX2NvdW50ZXJfc3lzZnNfaW5pdCh2b2lkKQp7CglyZXR1cm4gc3lzZnNfY3JlYXRlX2dyb3VwKCZjcHVfc3lzZGV2X2NsYXNzLmtzZXQua29iaiwKCQkJCSAgJnBlcmZjbGFzc19hdHRyX2dyb3VwKTsKfQpkZXZpY2VfaW5pdGNhbGwocGVyZl9jb3VudGVyX3N5c2ZzX2luaXQpOwo=