LyoKICogUGVyZm9ybWFuY2UgY291bnRlciBjb3JlIGNvZGUKICoKICogIENvcHlyaWdodCAoQykgMjAwOCBUaG9tYXMgR2xlaXhuZXIgPHRnbHhAbGludXRyb25peC5kZT4KICogIENvcHlyaWdodCAoQykgMjAwOC0yMDA5IFJlZCBIYXQsIEluYy4sIEluZ28gTW9sbmFyCiAqICBDb3B5cmlnaHQgKEMpIDIwMDgtMjAwOSBSZWQgSGF0LCBJbmMuLCBQZXRlciBaaWpsc3RyYSA8cHppamxzdHJAcmVkaGF0LmNvbT4KICogIENvcHlyaWdodCAgqSAgMjAwOSBQYXVsIE1hY2tlcnJhcywgSUJNIENvcnAuIDxwYXVsdXNAYXUxLmlibS5jb20+CiAqCiAqICBGb3IgbGljZW5zaW5nIGRldGFpbHMgc2VlIGtlcm5lbC1iYXNlL0NPUFlJTkcKICovCgojaW5jbHVkZSA8bGludXgvZnMuaD4KI2luY2x1ZGUgPGxpbnV4L21tLmg+CiNpbmNsdWRlIDxsaW51eC9jcHUuaD4KI2luY2x1ZGUgPGxpbnV4L3NtcC5oPgojaW5jbHVkZSA8bGludXgvZmlsZS5oPgojaW5jbHVkZSA8bGludXgvcG9sbC5oPgojaW5jbHVkZSA8bGludXgvc3lzZnMuaD4KI2luY2x1ZGUgPGxpbnV4L2RjYWNoZS5oPgojaW5jbHVkZSA8bGludXgvcGVyY3B1Lmg+CiNpbmNsdWRlIDxsaW51eC9wdHJhY2UuaD4KI2luY2x1ZGUgPGxpbnV4L3Ztc3RhdC5oPgojaW5jbHVkZSA8bGludXgvaGFyZGlycS5oPgojaW5jbHVkZSA8bGludXgvcmN1bGlzdC5oPgojaW5jbHVkZSA8bGludXgvdWFjY2Vzcy5oPgojaW5jbHVkZSA8bGludXgvc3lzY2FsbHMuaD4KI2luY2x1ZGUgPGxpbnV4L2Fub25faW5vZGVzLmg+CiNpbmNsdWRlIDxsaW51eC9rZXJuZWxfc3RhdC5oPgojaW5jbHVkZSA8bGludXgvcGVyZl9jb3VudGVyLmg+CgojaW5jbHVkZSA8YXNtL2lycV9yZWdzLmg+CgovKgogKiBFYWNoIENQVSBoYXMgYSBsaXN0IG9mIHBlciBDUFUgY291bnRlcnM6CiAqLwpERUZJTkVfUEVSX0NQVShzdHJ1Y3QgcGVyZl9jcHVfY29udGV4dCwgcGVyZl9jcHVfY29udGV4dCk7CgppbnQgcGVyZl9tYXhfY291bnRlcnMgX19yZWFkX21vc3RseSA9IDE7CnN0YXRpYyBpbnQgcGVyZl9yZXNlcnZlZF9wZXJjcHUgX19yZWFkX21vc3RseTsKc3RhdGljIGludCBwZXJmX292ZXJjb21taXQgX19yZWFkX21vc3RseSA9IDE7CgpzdGF0aWMgYXRvbWljX3QgbnJfY291bnRlcnMgX19yZWFkX21vc3RseTsKc3RhdGljIGF0b21pY190IG5yX21tYXBfY291bnRlcnMgX19yZWFkX21vc3RseTsKc3RhdGljIGF0b21pY190IG5yX2NvbW1fY291bnRlcnMgX19yZWFkX21vc3RseTsKCi8qCiAqIHBlcmYgY291bnRlciBwYXJhbm9pYSBsZXZlbDoKICogIDAgLSBub3QgcGFyYW5vaWQKICogIDEgLSBkaXNhbGxvdyBjcHUgY291bnRlcnMgdG8gdW5wcml2CiAqICAyIC0gZGlzYWxsb3cga2VybmVsIHByb2ZpbGluZyB0byB1bnByaXYKICovCmludCBzeXNjdGxfcGVyZl9jb3VudGVyX3BhcmFub2lkIF9fcmVhZF9tb3N0bHk7CgpzdGF0aWMgaW5saW5lIGJvb2wgcGVyZl9wYXJhbm9pZF9jcHUodm9pZCkKewoJcmV0dXJuIHN5c2N0bF9wZXJmX2NvdW50ZXJfcGFyYW5vaWQgPiAwOwp9CgpzdGF0aWMgaW5saW5lIGJvb2wgcGVyZl9wYXJhbm9pZF9rZXJuZWwodm9pZCkKewoJcmV0dXJuIHN5c2N0bF9wZXJmX2NvdW50ZXJfcGFyYW5vaWQgPiAxOwp9CgppbnQgc3lzY3RsX3BlcmZfY291bnRlcl9tbG9jayBfX3JlYWRfbW9zdGx5ID0gNTEyOyAvKiAnZnJlZScga2IgcGVyIHVzZXIgKi8KCi8qCiAqIG1heCBwZXJmIGNvdW50ZXIgc2FtcGxlIHJhdGUKICovCmludCBzeXNjdGxfcGVyZl9jb3VudGVyX3NhbXBsZV9yYXRlIF9fcmVhZF9tb3N0bHkgPSAxMDAwMDA7CgpzdGF0aWMgYXRvbWljNjRfdCBwZXJmX2NvdW50ZXJfaWQ7CgovKgogKiBMb2NrIGZvciAoc3lzYWRtaW4tY29uZmlndXJhYmxlKSBjb3VudGVyIHJlc2VydmF0aW9uczoKICovCnN0YXRpYyBERUZJTkVfU1BJTkxPQ0socGVyZl9yZXNvdXJjZV9sb2NrKTsKCi8qCiAqIEFyY2hpdGVjdHVyZSBwcm92aWRlZCBBUElzIC0gd2VhayBhbGlhc2VzOgogKi8KZXh0ZXJuIF9fd2VhayBjb25zdCBzdHJ1Y3QgcG11ICpod19wZXJmX2NvdW50ZXJfaW5pdChzdHJ1Y3QgcGVyZl9jb3VudGVyICpjb3VudGVyKQp7CglyZXR1cm4gTlVMTDsKfQoKdm9pZCBfX3dlYWsgaHdfcGVyZl9kaXNhYmxlKHZvaWQpCQl7IGJhcnJpZXIoKTsgfQp2b2lkIF9fd2VhayBod19wZXJmX2VuYWJsZSh2b2lkKQkJeyBiYXJyaWVyKCk7IH0KCnZvaWQgX193ZWFrIGh3X3BlcmZfY291bnRlcl9zZXR1cChpbnQgY3B1KQl7IGJhcnJpZXIoKTsgfQoKaW50IF9fd2Vhawpod19wZXJmX2dyb3VwX3NjaGVkX2luKHN0cnVjdCBwZXJmX2NvdW50ZXIgKmdyb3VwX2xlYWRlciwKCSAgICAgICBzdHJ1Y3QgcGVyZl9jcHVfY29udGV4dCAqY3B1Y3R4LAoJICAgICAgIHN0cnVjdCBwZXJmX2NvdW50ZXJfY29udGV4dCAqY3R4LCBpbnQgY3B1KQp7CglyZXR1cm4gMDsKfQoKdm9pZCBfX3dlYWsgcGVyZl9jb3VudGVyX3ByaW50X2RlYnVnKHZvaWQpCXsgfQoKc3RhdGljIERFRklORV9QRVJfQ1BVKGludCwgZGlzYWJsZV9jb3VudCk7Cgp2b2lkIF9fcGVyZl9kaXNhYmxlKHZvaWQpCnsKCV9fZ2V0X2NwdV92YXIoZGlzYWJsZV9jb3VudCkrKzsKfQoKYm9vbCBfX3BlcmZfZW5hYmxlKHZvaWQpCnsKCXJldHVybiAhLS1fX2dldF9jcHVfdmFyKGRpc2FibGVfY291bnQpOwp9Cgp2b2lkIHBlcmZfZGlzYWJsZSh2b2lkKQp7CglfX3BlcmZfZGlzYWJsZSgpOwoJaHdfcGVyZl9kaXNhYmxlKCk7Cn0KCnZvaWQgcGVyZl9lbmFibGUodm9pZCkKewoJaWYgKF9fcGVyZl9lbmFibGUoKSkKCQlod19wZXJmX2VuYWJsZSgpOwp9CgpzdGF0aWMgdm9pZCBnZXRfY3R4KHN0cnVjdCBwZXJmX2NvdW50ZXJfY29udGV4dCAqY3R4KQp7CglXQVJOX09OKCFhdG9taWNfaW5jX25vdF96ZXJvKCZjdHgtPnJlZmNvdW50KSk7Cn0KCnN0YXRpYyB2b2lkIGZyZWVfY3R4KHN0cnVjdCByY3VfaGVhZCAqaGVhZCkKewoJc3RydWN0IHBlcmZfY291bnRlcl9jb250ZXh0ICpjdHg7CgoJY3R4ID0gY29udGFpbmVyX29mKGhlYWQsIHN0cnVjdCBwZXJmX2NvdW50ZXJfY29udGV4dCwgcmN1X2hlYWQpOwoJa2ZyZWUoY3R4KTsKfQoKc3RhdGljIHZvaWQgcHV0X2N0eChzdHJ1Y3QgcGVyZl9jb3VudGVyX2NvbnRleHQgKmN0eCkKewoJaWYgKGF0b21pY19kZWNfYW5kX3Rlc3QoJmN0eC0+cmVmY291bnQpKSB7CgkJaWYgKGN0eC0+cGFyZW50X2N0eCkKCQkJcHV0X2N0eChjdHgtPnBhcmVudF9jdHgpOwoJCWlmIChjdHgtPnRhc2spCgkJCXB1dF90YXNrX3N0cnVjdChjdHgtPnRhc2spOwoJCWNhbGxfcmN1KCZjdHgtPnJjdV9oZWFkLCBmcmVlX2N0eCk7Cgl9Cn0KCi8qCiAqIEdldCB0aGUgcGVyZl9jb3VudGVyX2NvbnRleHQgZm9yIGEgdGFzayBhbmQgbG9jayBpdC4KICogVGhpcyBoYXMgdG8gY29wZSB3aXRoIHdpdGggdGhlIGZhY3QgdGhhdCB1bnRpbCBpdCBpcyBsb2NrZWQsCiAqIHRoZSBjb250ZXh0IGNvdWxkIGdldCBtb3ZlZCB0byBhbm90aGVyIHRhc2suCiAqLwpzdGF0aWMgc3RydWN0IHBlcmZfY291bnRlcl9jb250ZXh0ICoKcGVyZl9sb2NrX3Rhc2tfY29udGV4dChzdHJ1Y3QgdGFza19zdHJ1Y3QgKnRhc2ssIHVuc2lnbmVkIGxvbmcgKmZsYWdzKQp7CglzdHJ1Y3QgcGVyZl9jb3VudGVyX2NvbnRleHQgKmN0eDsKCglyY3VfcmVhZF9sb2NrKCk7CiByZXRyeToKCWN0eCA9IHJjdV9kZXJlZmVyZW5jZSh0YXNrLT5wZXJmX2NvdW50ZXJfY3R4cCk7CglpZiAoY3R4KSB7CgkJLyoKCQkgKiBJZiB0aGlzIGNvbnRleHQgaXMgYSBjbG9uZSBvZiBhbm90aGVyLCBpdCBtaWdodAoJCSAqIGdldCBzd2FwcGVkIGZvciBhbm90aGVyIHVuZGVybmVhdGggdXMgYnkKCQkgKiBwZXJmX2NvdW50ZXJfdGFza19zY2hlZF9vdXQsIHRob3VnaCB0aGUKCQkgKiByY3VfcmVhZF9sb2NrKCkgcHJvdGVjdHMgdXMgZnJvbSBhbnkgY29udGV4dAoJCSAqIGdldHRpbmcgZnJlZWQuICBMb2NrIHRoZSBjb250ZXh0IGFuZCBjaGVjayBpZiBpdAoJCSAqIGdvdCBzd2FwcGVkIGJlZm9yZSB3ZSBjb3VsZCBnZXQgdGhlIGxvY2ssIGFuZCByZXRyeQoJCSAqIGlmIHNvLiAgSWYgd2UgbG9ja2VkIHRoZSByaWdodCBjb250ZXh0LCB0aGVuIGl0CgkJICogY2FuJ3QgZ2V0IHN3YXBwZWQgb24gdXMgYW55IG1vcmUuCgkJICovCgkJc3Bpbl9sb2NrX2lycXNhdmUoJmN0eC0+bG9jaywgKmZsYWdzKTsKCQlpZiAoY3R4ICE9IHJjdV9kZXJlZmVyZW5jZSh0YXNrLT5wZXJmX2NvdW50ZXJfY3R4cCkpIHsKCQkJc3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmY3R4LT5sb2NrLCAqZmxhZ3MpOwoJCQlnb3RvIHJldHJ5OwoJCX0KCgkJaWYgKCFhdG9taWNfaW5jX25vdF96ZXJvKCZjdHgtPnJlZmNvdW50KSkgewoJCQlzcGluX3VubG9ja19pcnFyZXN0b3JlKCZjdHgtPmxvY2ssICpmbGFncyk7CgkJCWN0eCA9IE5VTEw7CgkJfQoJfQoJcmN1X3JlYWRfdW5sb2NrKCk7CglyZXR1cm4gY3R4Owp9CgovKgogKiBHZXQgdGhlIGNvbnRleHQgZm9yIGEgdGFzayBhbmQgaW5jcmVtZW50IGl0cyBwaW5fY291bnQgc28gaXQKICogY2FuJ3QgZ2V0IHN3YXBwZWQgdG8gYW5vdGhlciB0YXNrLiAgVGhpcyBhbHNvIGluY3JlbWVudHMgaXRzCiAqIHJlZmVyZW5jZSBjb3VudCBzbyB0aGF0IHRoZSBjb250ZXh0IGNhbid0IGdldCBmcmVlZC4KICovCnN0YXRpYyBzdHJ1Y3QgcGVyZl9jb3VudGVyX2NvbnRleHQgKnBlcmZfcGluX3Rhc2tfY29udGV4dChzdHJ1Y3QgdGFza19zdHJ1Y3QgKnRhc2spCnsKCXN0cnVjdCBwZXJmX2NvdW50ZXJfY29udGV4dCAqY3R4OwoJdW5zaWduZWQgbG9uZyBmbGFnczsKCgljdHggPSBwZXJmX2xvY2tfdGFza19jb250ZXh0KHRhc2ssICZmbGFncyk7CglpZiAoY3R4KSB7CgkJKytjdHgtPnBpbl9jb3VudDsKCQlzcGluX3VubG9ja19pcnFyZXN0b3JlKCZjdHgtPmxvY2ssIGZsYWdzKTsKCX0KCXJldHVybiBjdHg7Cn0KCnN0YXRpYyB2b2lkIHBlcmZfdW5waW5fY29udGV4dChzdHJ1Y3QgcGVyZl9jb3VudGVyX2NvbnRleHQgKmN0eCkKewoJdW5zaWduZWQgbG9uZyBmbGFnczsKCglzcGluX2xvY2tfaXJxc2F2ZSgmY3R4LT5sb2NrLCBmbGFncyk7CgktLWN0eC0+cGluX2NvdW50OwoJc3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmY3R4LT5sb2NrLCBmbGFncyk7CglwdXRfY3R4KGN0eCk7Cn0KCi8qCiAqIEFkZCBhIGNvdW50ZXIgZnJvbSB0aGUgbGlzdHMgZm9yIGl0cyBjb250ZXh0LgogKiBNdXN0IGJlIGNhbGxlZCB3aXRoIGN0eC0+bXV0ZXggYW5kIGN0eC0+bG9jayBoZWxkLgogKi8Kc3RhdGljIHZvaWQKbGlzdF9hZGRfY291bnRlcihzdHJ1Y3QgcGVyZl9jb3VudGVyICpjb3VudGVyLCBzdHJ1Y3QgcGVyZl9jb3VudGVyX2NvbnRleHQgKmN0eCkKewoJc3RydWN0IHBlcmZfY291bnRlciAqZ3JvdXBfbGVhZGVyID0gY291bnRlci0+Z3JvdXBfbGVhZGVyOwoKCS8qCgkgKiBEZXBlbmRpbmcgb24gd2hldGhlciBpdCBpcyBhIHN0YW5kYWxvbmUgb3Igc2libGluZyBjb3VudGVyLAoJICogYWRkIGl0IHN0cmFpZ2h0IHRvIHRoZSBjb250ZXh0J3MgY291bnRlciBsaXN0LCBvciB0byB0aGUgZ3JvdXAKCSAqIGxlYWRlcidzIHNpYmxpbmcgbGlzdDoKCSAqLwoJaWYgKGdyb3VwX2xlYWRlciA9PSBjb3VudGVyKQoJCWxpc3RfYWRkX3RhaWwoJmNvdW50ZXItPmxpc3RfZW50cnksICZjdHgtPmNvdW50ZXJfbGlzdCk7CgllbHNlIHsKCQlsaXN0X2FkZF90YWlsKCZjb3VudGVyLT5saXN0X2VudHJ5LCAmZ3JvdXBfbGVhZGVyLT5zaWJsaW5nX2xpc3QpOwoJCWdyb3VwX2xlYWRlci0+bnJfc2libGluZ3MrKzsKCX0KCglsaXN0X2FkZF9yY3UoJmNvdW50ZXItPmV2ZW50X2VudHJ5LCAmY3R4LT5ldmVudF9saXN0KTsKCWN0eC0+bnJfY291bnRlcnMrKzsKCWlmIChjb3VudGVyLT5hdHRyLmluaGVyaXRfc3RhdCkKCQljdHgtPm5yX3N0YXQrKzsKfQoKLyoKICogUmVtb3ZlIGEgY291bnRlciBmcm9tIHRoZSBsaXN0cyBmb3IgaXRzIGNvbnRleHQuCiAqIE11c3QgYmUgY2FsbGVkIHdpdGggY3R4LT5tdXRleCBhbmQgY3R4LT5sb2NrIGhlbGQuCiAqLwpzdGF0aWMgdm9pZApsaXN0X2RlbF9jb3VudGVyKHN0cnVjdCBwZXJmX2NvdW50ZXIgKmNvdW50ZXIsIHN0cnVjdCBwZXJmX2NvdW50ZXJfY29udGV4dCAqY3R4KQp7CglzdHJ1Y3QgcGVyZl9jb3VudGVyICpzaWJsaW5nLCAqdG1wOwoKCWlmIChsaXN0X2VtcHR5KCZjb3VudGVyLT5saXN0X2VudHJ5KSkKCQlyZXR1cm47CgljdHgtPm5yX2NvdW50ZXJzLS07CglpZiAoY291bnRlci0+YXR0ci5pbmhlcml0X3N0YXQpCgkJY3R4LT5ucl9zdGF0LS07CgoJbGlzdF9kZWxfaW5pdCgmY291bnRlci0+bGlzdF9lbnRyeSk7CglsaXN0X2RlbF9yY3UoJmNvdW50ZXItPmV2ZW50X2VudHJ5KTsKCglpZiAoY291bnRlci0+Z3JvdXBfbGVhZGVyICE9IGNvdW50ZXIpCgkJY291bnRlci0+Z3JvdXBfbGVhZGVyLT5ucl9zaWJsaW5ncy0tOwoKCS8qCgkgKiBJZiB0aGlzIHdhcyBhIGdyb3VwIGNvdW50ZXIgd2l0aCBzaWJsaW5nIGNvdW50ZXJzIHRoZW4KCSAqIHVwZ3JhZGUgdGhlIHNpYmxpbmdzIHRvIHNpbmdsZXRvbiBjb3VudGVycyBieSBhZGRpbmcgdGhlbQoJICogdG8gdGhlIGNvbnRleHQgbGlzdCBkaXJlY3RseToKCSAqLwoJbGlzdF9mb3JfZWFjaF9lbnRyeV9zYWZlKHNpYmxpbmcsIHRtcCwKCQkJCSAmY291bnRlci0+c2libGluZ19saXN0LCBsaXN0X2VudHJ5KSB7CgoJCWxpc3RfbW92ZV90YWlsKCZzaWJsaW5nLT5saXN0X2VudHJ5LCAmY3R4LT5jb3VudGVyX2xpc3QpOwoJCXNpYmxpbmctPmdyb3VwX2xlYWRlciA9IHNpYmxpbmc7Cgl9Cn0KCnN0YXRpYyB2b2lkCmNvdW50ZXJfc2NoZWRfb3V0KHN0cnVjdCBwZXJmX2NvdW50ZXIgKmNvdW50ZXIsCgkJICBzdHJ1Y3QgcGVyZl9jcHVfY29udGV4dCAqY3B1Y3R4LAoJCSAgc3RydWN0IHBlcmZfY291bnRlcl9jb250ZXh0ICpjdHgpCnsKCWlmIChjb3VudGVyLT5zdGF0ZSAhPSBQRVJGX0NPVU5URVJfU1RBVEVfQUNUSVZFKQoJCXJldHVybjsKCgljb3VudGVyLT5zdGF0ZSA9IFBFUkZfQ09VTlRFUl9TVEFURV9JTkFDVElWRTsKCWNvdW50ZXItPnRzdGFtcF9zdG9wcGVkID0gY3R4LT50aW1lOwoJY291bnRlci0+cG11LT5kaXNhYmxlKGNvdW50ZXIpOwoJY291bnRlci0+b25jcHUgPSAtMTsKCglpZiAoIWlzX3NvZnR3YXJlX2NvdW50ZXIoY291bnRlcikpCgkJY3B1Y3R4LT5hY3RpdmVfb25jcHUtLTsKCWN0eC0+bnJfYWN0aXZlLS07CglpZiAoY291bnRlci0+YXR0ci5leGNsdXNpdmUgfHwgIWNwdWN0eC0+YWN0aXZlX29uY3B1KQoJCWNwdWN0eC0+ZXhjbHVzaXZlID0gMDsKfQoKc3RhdGljIHZvaWQKZ3JvdXBfc2NoZWRfb3V0KHN0cnVjdCBwZXJmX2NvdW50ZXIgKmdyb3VwX2NvdW50ZXIsCgkJc3RydWN0IHBlcmZfY3B1X2NvbnRleHQgKmNwdWN0eCwKCQlzdHJ1Y3QgcGVyZl9jb3VudGVyX2NvbnRleHQgKmN0eCkKewoJc3RydWN0IHBlcmZfY291bnRlciAqY291bnRlcjsKCglpZiAoZ3JvdXBfY291bnRlci0+c3RhdGUgIT0gUEVSRl9DT1VOVEVSX1NUQVRFX0FDVElWRSkKCQlyZXR1cm47CgoJY291bnRlcl9zY2hlZF9vdXQoZ3JvdXBfY291bnRlciwgY3B1Y3R4LCBjdHgpOwoKCS8qCgkgKiBTY2hlZHVsZSBvdXQgc2libGluZ3MgKGlmIGFueSk6CgkgKi8KCWxpc3RfZm9yX2VhY2hfZW50cnkoY291bnRlciwgJmdyb3VwX2NvdW50ZXItPnNpYmxpbmdfbGlzdCwgbGlzdF9lbnRyeSkKCQljb3VudGVyX3NjaGVkX291dChjb3VudGVyLCBjcHVjdHgsIGN0eCk7CgoJaWYgKGdyb3VwX2NvdW50ZXItPmF0dHIuZXhjbHVzaXZlKQoJCWNwdWN0eC0+ZXhjbHVzaXZlID0gMDsKfQoKLyoKICogQ3Jvc3MgQ1BVIGNhbGwgdG8gcmVtb3ZlIGEgcGVyZm9ybWFuY2UgY291bnRlcgogKgogKiBXZSBkaXNhYmxlIHRoZSBjb3VudGVyIG9uIHRoZSBoYXJkd2FyZSBsZXZlbCBmaXJzdC4gQWZ0ZXIgdGhhdCB3ZQogKiByZW1vdmUgaXQgZnJvbSB0aGUgY29udGV4dCBsaXN0LgogKi8Kc3RhdGljIHZvaWQgX19wZXJmX2NvdW50ZXJfcmVtb3ZlX2Zyb21fY29udGV4dCh2b2lkICppbmZvKQp7CglzdHJ1Y3QgcGVyZl9jcHVfY29udGV4dCAqY3B1Y3R4ID0gJl9fZ2V0X2NwdV92YXIocGVyZl9jcHVfY29udGV4dCk7CglzdHJ1Y3QgcGVyZl9jb3VudGVyICpjb3VudGVyID0gaW5mbzsKCXN0cnVjdCBwZXJmX2NvdW50ZXJfY29udGV4dCAqY3R4ID0gY291bnRlci0+Y3R4OwoKCS8qCgkgKiBJZiB0aGlzIGlzIGEgdGFzayBjb250ZXh0LCB3ZSBuZWVkIHRvIGNoZWNrIHdoZXRoZXIgaXQgaXMKCSAqIHRoZSBjdXJyZW50IHRhc2sgY29udGV4dCBvZiB0aGlzIGNwdS4gSWYgbm90IGl0IGhhcyBiZWVuCgkgKiBzY2hlZHVsZWQgb3V0IGJlZm9yZSB0aGUgc21wIGNhbGwgYXJyaXZlZC4KCSAqLwoJaWYgKGN0eC0+dGFzayAmJiBjcHVjdHgtPnRhc2tfY3R4ICE9IGN0eCkKCQlyZXR1cm47CgoJc3Bpbl9sb2NrKCZjdHgtPmxvY2spOwoJLyoKCSAqIFByb3RlY3QgdGhlIGxpc3Qgb3BlcmF0aW9uIGFnYWluc3QgTk1JIGJ5IGRpc2FibGluZyB0aGUKCSAqIGNvdW50ZXJzIG9uIGEgZ2xvYmFsIGxldmVsLgoJICovCglwZXJmX2Rpc2FibGUoKTsKCgljb3VudGVyX3NjaGVkX291dChjb3VudGVyLCBjcHVjdHgsIGN0eCk7CgoJbGlzdF9kZWxfY291bnRlcihjb3VudGVyLCBjdHgpOwoKCWlmICghY3R4LT50YXNrKSB7CgkJLyoKCQkgKiBBbGxvdyBtb3JlIHBlciB0YXNrIGNvdW50ZXJzIHdpdGggcmVzcGVjdCB0byB0aGUKCQkgKiByZXNlcnZhdGlvbjoKCQkgKi8KCQljcHVjdHgtPm1heF9wZXJ0YXNrID0KCQkJbWluKHBlcmZfbWF4X2NvdW50ZXJzIC0gY3R4LT5ucl9jb3VudGVycywKCQkJICAgIHBlcmZfbWF4X2NvdW50ZXJzIC0gcGVyZl9yZXNlcnZlZF9wZXJjcHUpOwoJfQoKCXBlcmZfZW5hYmxlKCk7CglzcGluX3VubG9jaygmY3R4LT5sb2NrKTsKfQoKCi8qCiAqIFJlbW92ZSB0aGUgY291bnRlciBmcm9tIGEgdGFzaydzIChvciBhIENQVSdzKSBsaXN0IG9mIGNvdW50ZXJzLgogKgogKiBNdXN0IGJlIGNhbGxlZCB3aXRoIGN0eC0+bXV0ZXggaGVsZC4KICoKICogQ1BVIGNvdW50ZXJzIGFyZSByZW1vdmVkIHdpdGggYSBzbXAgY2FsbC4gRm9yIHRhc2sgY291bnRlcnMgd2Ugb25seQogKiBjYWxsIHdoZW4gdGhlIHRhc2sgaXMgb24gYSBDUFUuCiAqCiAqIElmIGNvdW50ZXItPmN0eCBpcyBhIGNsb25lZCBjb250ZXh0LCBjYWxsZXJzIG11c3QgbWFrZSBzdXJlIHRoYXQKICogZXZlcnkgdGFzayBzdHJ1Y3QgdGhhdCBjb3VudGVyLT5jdHgtPnRhc2sgY291bGQgcG9zc2libHkgcG9pbnQgdG8KICogcmVtYWlucyB2YWxpZC4gIFRoaXMgaXMgT0sgd2hlbiBjYWxsZWQgZnJvbSBwZXJmX3JlbGVhc2Ugc2luY2UKICogdGhhdCBvbmx5IGNhbGxzIHVzIG9uIHRoZSB0b3AtbGV2ZWwgY29udGV4dCwgd2hpY2ggY2FuJ3QgYmUgYSBjbG9uZS4KICogV2hlbiBjYWxsZWQgZnJvbSBwZXJmX2NvdW50ZXJfZXhpdF90YXNrLCBpdCdzIE9LIGJlY2F1c2UgdGhlCiAqIGNvbnRleHQgaGFzIGJlZW4gZGV0YWNoZWQgZnJvbSBpdHMgdGFzay4KICovCnN0YXRpYyB2b2lkIHBlcmZfY291bnRlcl9yZW1vdmVfZnJvbV9jb250ZXh0KHN0cnVjdCBwZXJmX2NvdW50ZXIgKmNvdW50ZXIpCnsKCXN0cnVjdCBwZXJmX2NvdW50ZXJfY29udGV4dCAqY3R4ID0gY291bnRlci0+Y3R4OwoJc3RydWN0IHRhc2tfc3RydWN0ICp0YXNrID0gY3R4LT50YXNrOwoKCWlmICghdGFzaykgewoJCS8qCgkJICogUGVyIGNwdSBjb3VudGVycyBhcmUgcmVtb3ZlZCB2aWEgYW4gc21wIGNhbGwgYW5kCgkJICogdGhlIHJlbW92YWwgaXMgYWx3YXlzIHN1Y2Vzc2Z1bC4KCQkgKi8KCQlzbXBfY2FsbF9mdW5jdGlvbl9zaW5nbGUoY291bnRlci0+Y3B1LAoJCQkJCSBfX3BlcmZfY291bnRlcl9yZW1vdmVfZnJvbV9jb250ZXh0LAoJCQkJCSBjb3VudGVyLCAxKTsKCQlyZXR1cm47Cgl9CgpyZXRyeToKCXRhc2tfb25jcHVfZnVuY3Rpb25fY2FsbCh0YXNrLCBfX3BlcmZfY291bnRlcl9yZW1vdmVfZnJvbV9jb250ZXh0LAoJCQkJIGNvdW50ZXIpOwoKCXNwaW5fbG9ja19pcnEoJmN0eC0+bG9jayk7CgkvKgoJICogSWYgdGhlIGNvbnRleHQgaXMgYWN0aXZlIHdlIG5lZWQgdG8gcmV0cnkgdGhlIHNtcCBjYWxsLgoJICovCglpZiAoY3R4LT5ucl9hY3RpdmUgJiYgIWxpc3RfZW1wdHkoJmNvdW50ZXItPmxpc3RfZW50cnkpKSB7CgkJc3Bpbl91bmxvY2tfaXJxKCZjdHgtPmxvY2spOwoJCWdvdG8gcmV0cnk7Cgl9CgoJLyoKCSAqIFRoZSBsb2NrIHByZXZlbnRzIHRoYXQgdGhpcyBjb250ZXh0IGlzIHNjaGVkdWxlZCBpbiBzbyB3ZQoJICogY2FuIHJlbW92ZSB0aGUgY291bnRlciBzYWZlbHksIGlmIHRoZSBjYWxsIGFib3ZlIGRpZCBub3QKCSAqIHN1Y2NlZWQuCgkgKi8KCWlmICghbGlzdF9lbXB0eSgmY291bnRlci0+bGlzdF9lbnRyeSkpIHsKCQlsaXN0X2RlbF9jb3VudGVyKGNvdW50ZXIsIGN0eCk7Cgl9CglzcGluX3VubG9ja19pcnEoJmN0eC0+bG9jayk7Cn0KCnN0YXRpYyBpbmxpbmUgdTY0IHBlcmZfY2xvY2sodm9pZCkKewoJcmV0dXJuIGNwdV9jbG9jayhzbXBfcHJvY2Vzc29yX2lkKCkpOwp9CgovKgogKiBVcGRhdGUgdGhlIHJlY29yZCBvZiB0aGUgY3VycmVudCB0aW1lIGluIGEgY29udGV4dC4KICovCnN0YXRpYyB2b2lkIHVwZGF0ZV9jb250ZXh0X3RpbWUoc3RydWN0IHBlcmZfY291bnRlcl9jb250ZXh0ICpjdHgpCnsKCXU2NCBub3cgPSBwZXJmX2Nsb2NrKCk7CgoJY3R4LT50aW1lICs9IG5vdyAtIGN0eC0+dGltZXN0YW1wOwoJY3R4LT50aW1lc3RhbXAgPSBub3c7Cn0KCi8qCiAqIFVwZGF0ZSB0aGUgdG90YWxfdGltZV9lbmFibGVkIGFuZCB0b3RhbF90aW1lX3J1bm5pbmcgZmllbGRzIGZvciBhIGNvdW50ZXIuCiAqLwpzdGF0aWMgdm9pZCB1cGRhdGVfY291bnRlcl90aW1lcyhzdHJ1Y3QgcGVyZl9jb3VudGVyICpjb3VudGVyKQp7CglzdHJ1Y3QgcGVyZl9jb3VudGVyX2NvbnRleHQgKmN0eCA9IGNvdW50ZXItPmN0eDsKCXU2NCBydW5fZW5kOwoKCWlmIChjb3VudGVyLT5zdGF0ZSA8IFBFUkZfQ09VTlRFUl9TVEFURV9JTkFDVElWRSkKCQlyZXR1cm47CgoJY291bnRlci0+dG90YWxfdGltZV9lbmFibGVkID0gY3R4LT50aW1lIC0gY291bnRlci0+dHN0YW1wX2VuYWJsZWQ7CgoJaWYgKGNvdW50ZXItPnN0YXRlID09IFBFUkZfQ09VTlRFUl9TVEFURV9JTkFDVElWRSkKCQlydW5fZW5kID0gY291bnRlci0+dHN0YW1wX3N0b3BwZWQ7CgllbHNlCgkJcnVuX2VuZCA9IGN0eC0+dGltZTsKCgljb3VudGVyLT50b3RhbF90aW1lX3J1bm5pbmcgPSBydW5fZW5kIC0gY291bnRlci0+dHN0YW1wX3J1bm5pbmc7Cn0KCi8qCiAqIFVwZGF0ZSB0b3RhbF90aW1lX2VuYWJsZWQgYW5kIHRvdGFsX3RpbWVfcnVubmluZyBmb3IgYWxsIGNvdW50ZXJzIGluIGEgZ3JvdXAuCiAqLwpzdGF0aWMgdm9pZCB1cGRhdGVfZ3JvdXBfdGltZXMoc3RydWN0IHBlcmZfY291bnRlciAqbGVhZGVyKQp7CglzdHJ1Y3QgcGVyZl9jb3VudGVyICpjb3VudGVyOwoKCXVwZGF0ZV9jb3VudGVyX3RpbWVzKGxlYWRlcik7CglsaXN0X2Zvcl9lYWNoX2VudHJ5KGNvdW50ZXIsICZsZWFkZXItPnNpYmxpbmdfbGlzdCwgbGlzdF9lbnRyeSkKCQl1cGRhdGVfY291bnRlcl90aW1lcyhjb3VudGVyKTsKfQoKLyoKICogQ3Jvc3MgQ1BVIGNhbGwgdG8gZGlzYWJsZSBhIHBlcmZvcm1hbmNlIGNvdW50ZXIKICovCnN0YXRpYyB2b2lkIF9fcGVyZl9jb3VudGVyX2Rpc2FibGUodm9pZCAqaW5mbykKewoJc3RydWN0IHBlcmZfY291bnRlciAqY291bnRlciA9IGluZm87CglzdHJ1Y3QgcGVyZl9jcHVfY29udGV4dCAqY3B1Y3R4ID0gJl9fZ2V0X2NwdV92YXIocGVyZl9jcHVfY29udGV4dCk7CglzdHJ1Y3QgcGVyZl9jb3VudGVyX2NvbnRleHQgKmN0eCA9IGNvdW50ZXItPmN0eDsKCgkvKgoJICogSWYgdGhpcyBpcyBhIHBlci10YXNrIGNvdW50ZXIsIG5lZWQgdG8gY2hlY2sgd2hldGhlciB0aGlzCgkgKiBjb3VudGVyJ3MgdGFzayBpcyB0aGUgY3VycmVudCB0YXNrIG9uIHRoaXMgY3B1LgoJICovCglpZiAoY3R4LT50YXNrICYmIGNwdWN0eC0+dGFza19jdHggIT0gY3R4KQoJCXJldHVybjsKCglzcGluX2xvY2soJmN0eC0+bG9jayk7CgoJLyoKCSAqIElmIHRoZSBjb3VudGVyIGlzIG9uLCB0dXJuIGl0IG9mZi4KCSAqIElmIGl0IGlzIGluIGVycm9yIHN0YXRlLCBsZWF2ZSBpdCBpbiBlcnJvciBzdGF0ZS4KCSAqLwoJaWYgKGNvdW50ZXItPnN0YXRlID49IFBFUkZfQ09VTlRFUl9TVEFURV9JTkFDVElWRSkgewoJCXVwZGF0ZV9jb250ZXh0X3RpbWUoY3R4KTsKCQl1cGRhdGVfY291bnRlcl90aW1lcyhjb3VudGVyKTsKCQlpZiAoY291bnRlciA9PSBjb3VudGVyLT5ncm91cF9sZWFkZXIpCgkJCWdyb3VwX3NjaGVkX291dChjb3VudGVyLCBjcHVjdHgsIGN0eCk7CgkJZWxzZQoJCQljb3VudGVyX3NjaGVkX291dChjb3VudGVyLCBjcHVjdHgsIGN0eCk7CgkJY291bnRlci0+c3RhdGUgPSBQRVJGX0NPVU5URVJfU1RBVEVfT0ZGOwoJfQoKCXNwaW5fdW5sb2NrKCZjdHgtPmxvY2spOwp9CgovKgogKiBEaXNhYmxlIGEgY291bnRlci4KICoKICogSWYgY291bnRlci0+Y3R4IGlzIGEgY2xvbmVkIGNvbnRleHQsIGNhbGxlcnMgbXVzdCBtYWtlIHN1cmUgdGhhdAogKiBldmVyeSB0YXNrIHN0cnVjdCB0aGF0IGNvdW50ZXItPmN0eC0+dGFzayBjb3VsZCBwb3NzaWJseSBwb2ludCB0bwogKiByZW1haW5zIHZhbGlkLiAgVGhpcyBjb25kaXRpb24gaXMgc2F0aXNpZmVkIHdoZW4gY2FsbGVkIHRocm91Z2gKICogcGVyZl9jb3VudGVyX2Zvcl9lYWNoX2NoaWxkIG9yIHBlcmZfY291bnRlcl9mb3JfZWFjaCBiZWNhdXNlIHRoZXkKICogaG9sZCB0aGUgdG9wLWxldmVsIGNvdW50ZXIncyBjaGlsZF9tdXRleCwgc28gYW55IGRlc2NlbmRhbnQgdGhhdAogKiBnb2VzIHRvIGV4aXQgd2lsbCBibG9jayBpbiBzeW5jX2NoaWxkX2NvdW50ZXIuCiAqIFdoZW4gY2FsbGVkIGZyb20gcGVyZl9wZW5kaW5nX2NvdW50ZXIgaXQncyBPSyBiZWNhdXNlIGNvdW50ZXItPmN0eAogKiBpcyB0aGUgY3VycmVudCBjb250ZXh0IG9uIHRoaXMgQ1BVIGFuZCBwcmVlbXB0aW9uIGlzIGRpc2FibGVkLAogKiBoZW5jZSB3ZSBjYW4ndCBnZXQgaW50byBwZXJmX2NvdW50ZXJfdGFza19zY2hlZF9vdXQgZm9yIHRoaXMgY29udGV4dC4KICovCnN0YXRpYyB2b2lkIHBlcmZfY291bnRlcl9kaXNhYmxlKHN0cnVjdCBwZXJmX2NvdW50ZXIgKmNvdW50ZXIpCnsKCXN0cnVjdCBwZXJmX2NvdW50ZXJfY29udGV4dCAqY3R4ID0gY291bnRlci0+Y3R4OwoJc3RydWN0IHRhc2tfc3RydWN0ICp0YXNrID0gY3R4LT50YXNrOwoKCWlmICghdGFzaykgewoJCS8qCgkJICogRGlzYWJsZSB0aGUgY291bnRlciBvbiB0aGUgY3B1IHRoYXQgaXQncyBvbgoJCSAqLwoJCXNtcF9jYWxsX2Z1bmN0aW9uX3NpbmdsZShjb3VudGVyLT5jcHUsIF9fcGVyZl9jb3VudGVyX2Rpc2FibGUsCgkJCQkJIGNvdW50ZXIsIDEpOwoJCXJldHVybjsKCX0KCiByZXRyeToKCXRhc2tfb25jcHVfZnVuY3Rpb25fY2FsbCh0YXNrLCBfX3BlcmZfY291bnRlcl9kaXNhYmxlLCBjb3VudGVyKTsKCglzcGluX2xvY2tfaXJxKCZjdHgtPmxvY2spOwoJLyoKCSAqIElmIHRoZSBjb3VudGVyIGlzIHN0aWxsIGFjdGl2ZSwgd2UgbmVlZCB0byByZXRyeSB0aGUgY3Jvc3MtY2FsbC4KCSAqLwoJaWYgKGNvdW50ZXItPnN0YXRlID09IFBFUkZfQ09VTlRFUl9TVEFURV9BQ1RJVkUpIHsKCQlzcGluX3VubG9ja19pcnEoJmN0eC0+bG9jayk7CgkJZ290byByZXRyeTsKCX0KCgkvKgoJICogU2luY2Ugd2UgaGF2ZSB0aGUgbG9jayB0aGlzIGNvbnRleHQgY2FuJ3QgYmUgc2NoZWR1bGVkCgkgKiBpbiwgc28gd2UgY2FuIGNoYW5nZSB0aGUgc3RhdGUgc2FmZWx5LgoJICovCglpZiAoY291bnRlci0+c3RhdGUgPT0gUEVSRl9DT1VOVEVSX1NUQVRFX0lOQUNUSVZFKSB7CgkJdXBkYXRlX2NvdW50ZXJfdGltZXMoY291bnRlcik7CgkJY291bnRlci0+c3RhdGUgPSBQRVJGX0NPVU5URVJfU1RBVEVfT0ZGOwoJfQoKCXNwaW5fdW5sb2NrX2lycSgmY3R4LT5sb2NrKTsKfQoKc3RhdGljIGludApjb3VudGVyX3NjaGVkX2luKHN0cnVjdCBwZXJmX2NvdW50ZXIgKmNvdW50ZXIsCgkJIHN0cnVjdCBwZXJmX2NwdV9jb250ZXh0ICpjcHVjdHgsCgkJIHN0cnVjdCBwZXJmX2NvdW50ZXJfY29udGV4dCAqY3R4LAoJCSBpbnQgY3B1KQp7CglpZiAoY291bnRlci0+c3RhdGUgPD0gUEVSRl9DT1VOVEVSX1NUQVRFX09GRikKCQlyZXR1cm4gMDsKCgljb3VudGVyLT5zdGF0ZSA9IFBFUkZfQ09VTlRFUl9TVEFURV9BQ1RJVkU7Cgljb3VudGVyLT5vbmNwdSA9IGNwdTsJLyogVE9ETzogcHV0ICdjcHUnIGludG8gY3B1Y3R4LT5jcHUgKi8KCS8qCgkgKiBUaGUgbmV3IHN0YXRlIG11c3QgYmUgdmlzaWJsZSBiZWZvcmUgd2UgdHVybiBpdCBvbiBpbiB0aGUgaGFyZHdhcmU6CgkgKi8KCXNtcF93bWIoKTsKCglpZiAoY291bnRlci0+cG11LT5lbmFibGUoY291bnRlcikpIHsKCQljb3VudGVyLT5zdGF0ZSA9IFBFUkZfQ09VTlRFUl9TVEFURV9JTkFDVElWRTsKCQljb3VudGVyLT5vbmNwdSA9IC0xOwoJCXJldHVybiAtRUFHQUlOOwoJfQoKCWNvdW50ZXItPnRzdGFtcF9ydW5uaW5nICs9IGN0eC0+dGltZSAtIGNvdW50ZXItPnRzdGFtcF9zdG9wcGVkOwoKCWlmICghaXNfc29mdHdhcmVfY291bnRlcihjb3VudGVyKSkKCQljcHVjdHgtPmFjdGl2ZV9vbmNwdSsrOwoJY3R4LT5ucl9hY3RpdmUrKzsKCglpZiAoY291bnRlci0+YXR0ci5leGNsdXNpdmUpCgkJY3B1Y3R4LT5leGNsdXNpdmUgPSAxOwoKCXJldHVybiAwOwp9CgpzdGF0aWMgaW50Cmdyb3VwX3NjaGVkX2luKHN0cnVjdCBwZXJmX2NvdW50ZXIgKmdyb3VwX2NvdW50ZXIsCgkgICAgICAgc3RydWN0IHBlcmZfY3B1X2NvbnRleHQgKmNwdWN0eCwKCSAgICAgICBzdHJ1Y3QgcGVyZl9jb3VudGVyX2NvbnRleHQgKmN0eCwKCSAgICAgICBpbnQgY3B1KQp7CglzdHJ1Y3QgcGVyZl9jb3VudGVyICpjb3VudGVyLCAqcGFydGlhbF9ncm91cDsKCWludCByZXQ7CgoJaWYgKGdyb3VwX2NvdW50ZXItPnN0YXRlID09IFBFUkZfQ09VTlRFUl9TVEFURV9PRkYpCgkJcmV0dXJuIDA7CgoJcmV0ID0gaHdfcGVyZl9ncm91cF9zY2hlZF9pbihncm91cF9jb3VudGVyLCBjcHVjdHgsIGN0eCwgY3B1KTsKCWlmIChyZXQpCgkJcmV0dXJuIHJldCA8IDAgPyByZXQgOiAwOwoKCWlmIChjb3VudGVyX3NjaGVkX2luKGdyb3VwX2NvdW50ZXIsIGNwdWN0eCwgY3R4LCBjcHUpKQoJCXJldHVybiAtRUFHQUlOOwoKCS8qCgkgKiBTY2hlZHVsZSBpbiBzaWJsaW5ncyBhcyBvbmUgZ3JvdXAgKGlmIGFueSk6CgkgKi8KCWxpc3RfZm9yX2VhY2hfZW50cnkoY291bnRlciwgJmdyb3VwX2NvdW50ZXItPnNpYmxpbmdfbGlzdCwgbGlzdF9lbnRyeSkgewoJCWlmIChjb3VudGVyX3NjaGVkX2luKGNvdW50ZXIsIGNwdWN0eCwgY3R4LCBjcHUpKSB7CgkJCXBhcnRpYWxfZ3JvdXAgPSBjb3VudGVyOwoJCQlnb3RvIGdyb3VwX2Vycm9yOwoJCX0KCX0KCglyZXR1cm4gMDsKCmdyb3VwX2Vycm9yOgoJLyoKCSAqIEdyb3VwcyBjYW4gYmUgc2NoZWR1bGVkIGluIGFzIG9uZSB1bml0IG9ubHksIHNvIHVuZG8gYW55CgkgKiBwYXJ0aWFsIGdyb3VwIGJlZm9yZSByZXR1cm5pbmc6CgkgKi8KCWxpc3RfZm9yX2VhY2hfZW50cnkoY291bnRlciwgJmdyb3VwX2NvdW50ZXItPnNpYmxpbmdfbGlzdCwgbGlzdF9lbnRyeSkgewoJCWlmIChjb3VudGVyID09IHBhcnRpYWxfZ3JvdXApCgkJCWJyZWFrOwoJCWNvdW50ZXJfc2NoZWRfb3V0KGNvdW50ZXIsIGNwdWN0eCwgY3R4KTsKCX0KCWNvdW50ZXJfc2NoZWRfb3V0KGdyb3VwX2NvdW50ZXIsIGNwdWN0eCwgY3R4KTsKCglyZXR1cm4gLUVBR0FJTjsKfQoKLyoKICogUmV0dXJuIDEgZm9yIGEgZ3JvdXAgY29uc2lzdGluZyBlbnRpcmVseSBvZiBzb2Z0d2FyZSBjb3VudGVycywKICogMCBpZiB0aGUgZ3JvdXAgY29udGFpbnMgYW55IGhhcmR3YXJlIGNvdW50ZXJzLgogKi8Kc3RhdGljIGludCBpc19zb2Z0d2FyZV9vbmx5X2dyb3VwKHN0cnVjdCBwZXJmX2NvdW50ZXIgKmxlYWRlcikKewoJc3RydWN0IHBlcmZfY291bnRlciAqY291bnRlcjsKCglpZiAoIWlzX3NvZnR3YXJlX2NvdW50ZXIobGVhZGVyKSkKCQlyZXR1cm4gMDsKCglsaXN0X2Zvcl9lYWNoX2VudHJ5KGNvdW50ZXIsICZsZWFkZXItPnNpYmxpbmdfbGlzdCwgbGlzdF9lbnRyeSkKCQlpZiAoIWlzX3NvZnR3YXJlX2NvdW50ZXIoY291bnRlcikpCgkJCXJldHVybiAwOwoKCXJldHVybiAxOwp9CgovKgogKiBXb3JrIG91dCB3aGV0aGVyIHdlIGNhbiBwdXQgdGhpcyBjb3VudGVyIGdyb3VwIG9uIHRoZSBDUFUgbm93LgogKi8Kc3RhdGljIGludCBncm91cF9jYW5fZ29fb24oc3RydWN0IHBlcmZfY291bnRlciAqY291bnRlciwKCQkJICAgc3RydWN0IHBlcmZfY3B1X2NvbnRleHQgKmNwdWN0eCwKCQkJICAgaW50IGNhbl9hZGRfaHcpCnsKCS8qCgkgKiBHcm91cHMgY29uc2lzdGluZyBlbnRpcmVseSBvZiBzb2Z0d2FyZSBjb3VudGVycyBjYW4gYWx3YXlzIGdvIG9uLgoJICovCglpZiAoaXNfc29mdHdhcmVfb25seV9ncm91cChjb3VudGVyKSkKCQlyZXR1cm4gMTsKCS8qCgkgKiBJZiBhbiBleGNsdXNpdmUgZ3JvdXAgaXMgYWxyZWFkeSBvbiwgbm8gb3RoZXIgaGFyZHdhcmUKCSAqIGNvdW50ZXJzIGNhbiBnbyBvbi4KCSAqLwoJaWYgKGNwdWN0eC0+ZXhjbHVzaXZlKQoJCXJldHVybiAwOwoJLyoKCSAqIElmIHRoaXMgZ3JvdXAgaXMgZXhjbHVzaXZlIGFuZCB0aGVyZSBhcmUgYWxyZWFkeQoJICogY291bnRlcnMgb24gdGhlIENQVSwgaXQgY2FuJ3QgZ28gb24uCgkgKi8KCWlmIChjb3VudGVyLT5hdHRyLmV4Y2x1c2l2ZSAmJiBjcHVjdHgtPmFjdGl2ZV9vbmNwdSkKCQlyZXR1cm4gMDsKCS8qCgkgKiBPdGhlcndpc2UsIHRyeSB0byBhZGQgaXQgaWYgYWxsIHByZXZpb3VzIGdyb3VwcyB3ZXJlIGFibGUKCSAqIHRvIGdvIG9uLgoJICovCglyZXR1cm4gY2FuX2FkZF9odzsKfQoKc3RhdGljIHZvaWQgYWRkX2NvdW50ZXJfdG9fY3R4KHN0cnVjdCBwZXJmX2NvdW50ZXIgKmNvdW50ZXIsCgkJCSAgICAgICBzdHJ1Y3QgcGVyZl9jb3VudGVyX2NvbnRleHQgKmN0eCkKewoJbGlzdF9hZGRfY291bnRlcihjb3VudGVyLCBjdHgpOwoJY291bnRlci0+dHN0YW1wX2VuYWJsZWQgPSBjdHgtPnRpbWU7Cgljb3VudGVyLT50c3RhbXBfcnVubmluZyA9IGN0eC0+dGltZTsKCWNvdW50ZXItPnRzdGFtcF9zdG9wcGVkID0gY3R4LT50aW1lOwp9CgovKgogKiBDcm9zcyBDUFUgY2FsbCB0byBpbnN0YWxsIGFuZCBlbmFibGUgYSBwZXJmb3JtYW5jZSBjb3VudGVyCiAqCiAqIE11c3QgYmUgY2FsbGVkIHdpdGggY3R4LT5tdXRleCBoZWxkCiAqLwpzdGF0aWMgdm9pZCBfX3BlcmZfaW5zdGFsbF9pbl9jb250ZXh0KHZvaWQgKmluZm8pCnsKCXN0cnVjdCBwZXJmX2NwdV9jb250ZXh0ICpjcHVjdHggPSAmX19nZXRfY3B1X3ZhcihwZXJmX2NwdV9jb250ZXh0KTsKCXN0cnVjdCBwZXJmX2NvdW50ZXIgKmNvdW50ZXIgPSBpbmZvOwoJc3RydWN0IHBlcmZfY291bnRlcl9jb250ZXh0ICpjdHggPSBjb3VudGVyLT5jdHg7CglzdHJ1Y3QgcGVyZl9jb3VudGVyICpsZWFkZXIgPSBjb3VudGVyLT5ncm91cF9sZWFkZXI7CglpbnQgY3B1ID0gc21wX3Byb2Nlc3Nvcl9pZCgpOwoJaW50IGVycjsKCgkvKgoJICogSWYgdGhpcyBpcyBhIHRhc2sgY29udGV4dCwgd2UgbmVlZCB0byBjaGVjayB3aGV0aGVyIGl0IGlzCgkgKiB0aGUgY3VycmVudCB0YXNrIGNvbnRleHQgb2YgdGhpcyBjcHUuIElmIG5vdCBpdCBoYXMgYmVlbgoJICogc2NoZWR1bGVkIG91dCBiZWZvcmUgdGhlIHNtcCBjYWxsIGFycml2ZWQuCgkgKiBPciBwb3NzaWJseSB0aGlzIGlzIHRoZSByaWdodCBjb250ZXh0IGJ1dCBpdCBpc24ndAoJICogb24gdGhpcyBjcHUgYmVjYXVzZSBpdCBoYWQgbm8gY291bnRlcnMuCgkgKi8KCWlmIChjdHgtPnRhc2sgJiYgY3B1Y3R4LT50YXNrX2N0eCAhPSBjdHgpIHsKCQlpZiAoY3B1Y3R4LT50YXNrX2N0eCB8fCBjdHgtPnRhc2sgIT0gY3VycmVudCkKCQkJcmV0dXJuOwoJCWNwdWN0eC0+dGFza19jdHggPSBjdHg7Cgl9CgoJc3Bpbl9sb2NrKCZjdHgtPmxvY2spOwoJY3R4LT5pc19hY3RpdmUgPSAxOwoJdXBkYXRlX2NvbnRleHRfdGltZShjdHgpOwoKCS8qCgkgKiBQcm90ZWN0IHRoZSBsaXN0IG9wZXJhdGlvbiBhZ2FpbnN0IE5NSSBieSBkaXNhYmxpbmcgdGhlCgkgKiBjb3VudGVycyBvbiBhIGdsb2JhbCBsZXZlbC4gTk9QIGZvciBub24gTk1JIGJhc2VkIGNvdW50ZXJzLgoJICovCglwZXJmX2Rpc2FibGUoKTsKCglhZGRfY291bnRlcl90b19jdHgoY291bnRlciwgY3R4KTsKCgkvKgoJICogRG9uJ3QgcHV0IHRoZSBjb3VudGVyIG9uIGlmIGl0IGlzIGRpc2FibGVkIG9yIGlmCgkgKiBpdCBpcyBpbiBhIGdyb3VwIGFuZCB0aGUgZ3JvdXAgaXNuJ3Qgb24uCgkgKi8KCWlmIChjb3VudGVyLT5zdGF0ZSAhPSBQRVJGX0NPVU5URVJfU1RBVEVfSU5BQ1RJVkUgfHwKCSAgICAobGVhZGVyICE9IGNvdW50ZXIgJiYgbGVhZGVyLT5zdGF0ZSAhPSBQRVJGX0NPVU5URVJfU1RBVEVfQUNUSVZFKSkKCQlnb3RvIHVubG9jazsKCgkvKgoJICogQW4gZXhjbHVzaXZlIGNvdW50ZXIgY2FuJ3QgZ28gb24gaWYgdGhlcmUgYXJlIGFscmVhZHkgYWN0aXZlCgkgKiBoYXJkd2FyZSBjb3VudGVycywgYW5kIG5vIGhhcmR3YXJlIGNvdW50ZXIgY2FuIGdvIG9uIGlmIHRoZXJlCgkgKiBpcyBhbHJlYWR5IGFuIGV4Y2x1c2l2ZSBjb3VudGVyIG9uLgoJICovCglpZiAoIWdyb3VwX2Nhbl9nb19vbihjb3VudGVyLCBjcHVjdHgsIDEpKQoJCWVyciA9IC1FRVhJU1Q7CgllbHNlCgkJZXJyID0gY291bnRlcl9zY2hlZF9pbihjb3VudGVyLCBjcHVjdHgsIGN0eCwgY3B1KTsKCglpZiAoZXJyKSB7CgkJLyoKCQkgKiBUaGlzIGNvdW50ZXIgY291bGRuJ3QgZ28gb24uICBJZiBpdCBpcyBpbiBhIGdyb3VwCgkJICogdGhlbiB3ZSBoYXZlIHRvIHB1bGwgdGhlIHdob2xlIGdyb3VwIG9mZi4KCQkgKiBJZiB0aGUgY291bnRlciBncm91cCBpcyBwaW5uZWQgdGhlbiBwdXQgaXQgaW4gZXJyb3Igc3RhdGUuCgkJICovCgkJaWYgKGxlYWRlciAhPSBjb3VudGVyKQoJCQlncm91cF9zY2hlZF9vdXQobGVhZGVyLCBjcHVjdHgsIGN0eCk7CgkJaWYgKGxlYWRlci0+YXR0ci5waW5uZWQpIHsKCQkJdXBkYXRlX2dyb3VwX3RpbWVzKGxlYWRlcik7CgkJCWxlYWRlci0+c3RhdGUgPSBQRVJGX0NPVU5URVJfU1RBVEVfRVJST1I7CgkJfQoJfQoKCWlmICghZXJyICYmICFjdHgtPnRhc2sgJiYgY3B1Y3R4LT5tYXhfcGVydGFzaykKCQljcHVjdHgtPm1heF9wZXJ0YXNrLS07CgogdW5sb2NrOgoJcGVyZl9lbmFibGUoKTsKCglzcGluX3VubG9jaygmY3R4LT5sb2NrKTsKfQoKLyoKICogQXR0YWNoIGEgcGVyZm9ybWFuY2UgY291bnRlciB0byBhIGNvbnRleHQKICoKICogRmlyc3Qgd2UgYWRkIHRoZSBjb3VudGVyIHRvIHRoZSBsaXN0IHdpdGggdGhlIGhhcmR3YXJlIGVuYWJsZSBiaXQKICogaW4gY291bnRlci0+aHdfY29uZmlnIGNsZWFyZWQuCiAqCiAqIElmIHRoZSBjb3VudGVyIGlzIGF0dGFjaGVkIHRvIGEgdGFzayB3aGljaCBpcyBvbiBhIENQVSB3ZSB1c2UgYSBzbXAKICogY2FsbCB0byBlbmFibGUgaXQgaW4gdGhlIHRhc2sgY29udGV4dC4gVGhlIHRhc2sgbWlnaHQgaGF2ZSBiZWVuCiAqIHNjaGVkdWxlZCBhd2F5LCBidXQgd2UgY2hlY2sgdGhpcyBpbiB0aGUgc21wIGNhbGwgYWdhaW4uCiAqCiAqIE11c3QgYmUgY2FsbGVkIHdpdGggY3R4LT5tdXRleCBoZWxkLgogKi8Kc3RhdGljIHZvaWQKcGVyZl9pbnN0YWxsX2luX2NvbnRleHQoc3RydWN0IHBlcmZfY291bnRlcl9jb250ZXh0ICpjdHgsCgkJCXN0cnVjdCBwZXJmX2NvdW50ZXIgKmNvdW50ZXIsCgkJCWludCBjcHUpCnsKCXN0cnVjdCB0YXNrX3N0cnVjdCAqdGFzayA9IGN0eC0+dGFzazsKCglpZiAoIXRhc2spIHsKCQkvKgoJCSAqIFBlciBjcHUgY291bnRlcnMgYXJlIGluc3RhbGxlZCB2aWEgYW4gc21wIGNhbGwgYW5kCgkJICogdGhlIGluc3RhbGwgaXMgYWx3YXlzIHN1Y2Vzc2Z1bC4KCQkgKi8KCQlzbXBfY2FsbF9mdW5jdGlvbl9zaW5nbGUoY3B1LCBfX3BlcmZfaW5zdGFsbF9pbl9jb250ZXh0LAoJCQkJCSBjb3VudGVyLCAxKTsKCQlyZXR1cm47Cgl9CgpyZXRyeToKCXRhc2tfb25jcHVfZnVuY3Rpb25fY2FsbCh0YXNrLCBfX3BlcmZfaW5zdGFsbF9pbl9jb250ZXh0LAoJCQkJIGNvdW50ZXIpOwoKCXNwaW5fbG9ja19pcnEoJmN0eC0+bG9jayk7CgkvKgoJICogd2UgbmVlZCB0byByZXRyeSB0aGUgc21wIGNhbGwuCgkgKi8KCWlmIChjdHgtPmlzX2FjdGl2ZSAmJiBsaXN0X2VtcHR5KCZjb3VudGVyLT5saXN0X2VudHJ5KSkgewoJCXNwaW5fdW5sb2NrX2lycSgmY3R4LT5sb2NrKTsKCQlnb3RvIHJldHJ5OwoJfQoKCS8qCgkgKiBUaGUgbG9jayBwcmV2ZW50cyB0aGF0IHRoaXMgY29udGV4dCBpcyBzY2hlZHVsZWQgaW4gc28gd2UKCSAqIGNhbiBhZGQgdGhlIGNvdW50ZXIgc2FmZWx5LCBpZiBpdCB0aGUgY2FsbCBhYm92ZSBkaWQgbm90CgkgKiBzdWNjZWVkLgoJICovCglpZiAobGlzdF9lbXB0eSgmY291bnRlci0+bGlzdF9lbnRyeSkpCgkJYWRkX2NvdW50ZXJfdG9fY3R4KGNvdW50ZXIsIGN0eCk7CglzcGluX3VubG9ja19pcnEoJmN0eC0+bG9jayk7Cn0KCi8qCiAqIENyb3NzIENQVSBjYWxsIHRvIGVuYWJsZSBhIHBlcmZvcm1hbmNlIGNvdW50ZXIKICovCnN0YXRpYyB2b2lkIF9fcGVyZl9jb3VudGVyX2VuYWJsZSh2b2lkICppbmZvKQp7CglzdHJ1Y3QgcGVyZl9jb3VudGVyICpjb3VudGVyID0gaW5mbzsKCXN0cnVjdCBwZXJmX2NwdV9jb250ZXh0ICpjcHVjdHggPSAmX19nZXRfY3B1X3ZhcihwZXJmX2NwdV9jb250ZXh0KTsKCXN0cnVjdCBwZXJmX2NvdW50ZXJfY29udGV4dCAqY3R4ID0gY291bnRlci0+Y3R4OwoJc3RydWN0IHBlcmZfY291bnRlciAqbGVhZGVyID0gY291bnRlci0+Z3JvdXBfbGVhZGVyOwoJaW50IGVycjsKCgkvKgoJICogSWYgdGhpcyBpcyBhIHBlci10YXNrIGNvdW50ZXIsIG5lZWQgdG8gY2hlY2sgd2hldGhlciB0aGlzCgkgKiBjb3VudGVyJ3MgdGFzayBpcyB0aGUgY3VycmVudCB0YXNrIG9uIHRoaXMgY3B1LgoJICovCglpZiAoY3R4LT50YXNrICYmIGNwdWN0eC0+dGFza19jdHggIT0gY3R4KSB7CgkJaWYgKGNwdWN0eC0+dGFza19jdHggfHwgY3R4LT50YXNrICE9IGN1cnJlbnQpCgkJCXJldHVybjsKCQljcHVjdHgtPnRhc2tfY3R4ID0gY3R4OwoJfQoKCXNwaW5fbG9jaygmY3R4LT5sb2NrKTsKCWN0eC0+aXNfYWN0aXZlID0gMTsKCXVwZGF0ZV9jb250ZXh0X3RpbWUoY3R4KTsKCglpZiAoY291bnRlci0+c3RhdGUgPj0gUEVSRl9DT1VOVEVSX1NUQVRFX0lOQUNUSVZFKQoJCWdvdG8gdW5sb2NrOwoJY291bnRlci0+c3RhdGUgPSBQRVJGX0NPVU5URVJfU1RBVEVfSU5BQ1RJVkU7Cgljb3VudGVyLT50c3RhbXBfZW5hYmxlZCA9IGN0eC0+dGltZSAtIGNvdW50ZXItPnRvdGFsX3RpbWVfZW5hYmxlZDsKCgkvKgoJICogSWYgdGhlIGNvdW50ZXIgaXMgaW4gYSBncm91cCBhbmQgaXNuJ3QgdGhlIGdyb3VwIGxlYWRlciwKCSAqIHRoZW4gZG9uJ3QgcHV0IGl0IG9uIHVubGVzcyB0aGUgZ3JvdXAgaXMgb24uCgkgKi8KCWlmIChsZWFkZXIgIT0gY291bnRlciAmJiBsZWFkZXItPnN0YXRlICE9IFBFUkZfQ09VTlRFUl9TVEFURV9BQ1RJVkUpCgkJZ290byB1bmxvY2s7CgoJaWYgKCFncm91cF9jYW5fZ29fb24oY291bnRlciwgY3B1Y3R4LCAxKSkgewoJCWVyciA9IC1FRVhJU1Q7Cgl9IGVsc2UgewoJCXBlcmZfZGlzYWJsZSgpOwoJCWlmIChjb3VudGVyID09IGxlYWRlcikKCQkJZXJyID0gZ3JvdXBfc2NoZWRfaW4oY291bnRlciwgY3B1Y3R4LCBjdHgsCgkJCQkJICAgICBzbXBfcHJvY2Vzc29yX2lkKCkpOwoJCWVsc2UKCQkJZXJyID0gY291bnRlcl9zY2hlZF9pbihjb3VudGVyLCBjcHVjdHgsIGN0eCwKCQkJCQkgICAgICAgc21wX3Byb2Nlc3Nvcl9pZCgpKTsKCQlwZXJmX2VuYWJsZSgpOwoJfQoKCWlmIChlcnIpIHsKCQkvKgoJCSAqIElmIHRoaXMgY291bnRlciBjYW4ndCBnbyBvbiBhbmQgaXQncyBwYXJ0IG9mIGEKCQkgKiBncm91cCwgdGhlbiB0aGUgd2hvbGUgZ3JvdXAgaGFzIHRvIGNvbWUgb2ZmLgoJCSAqLwoJCWlmIChsZWFkZXIgIT0gY291bnRlcikKCQkJZ3JvdXBfc2NoZWRfb3V0KGxlYWRlciwgY3B1Y3R4LCBjdHgpOwoJCWlmIChsZWFkZXItPmF0dHIucGlubmVkKSB7CgkJCXVwZGF0ZV9ncm91cF90aW1lcyhsZWFkZXIpOwoJCQlsZWFkZXItPnN0YXRlID0gUEVSRl9DT1VOVEVSX1NUQVRFX0VSUk9SOwoJCX0KCX0KCiB1bmxvY2s6CglzcGluX3VubG9jaygmY3R4LT5sb2NrKTsKfQoKLyoKICogRW5hYmxlIGEgY291bnRlci4KICoKICogSWYgY291bnRlci0+Y3R4IGlzIGEgY2xvbmVkIGNvbnRleHQsIGNhbGxlcnMgbXVzdCBtYWtlIHN1cmUgdGhhdAogKiBldmVyeSB0YXNrIHN0cnVjdCB0aGF0IGNvdW50ZXItPmN0eC0+dGFzayBjb3VsZCBwb3NzaWJseSBwb2ludCB0bwogKiByZW1haW5zIHZhbGlkLiAgVGhpcyBjb25kaXRpb24gaXMgc2F0aXNmaWVkIHdoZW4gY2FsbGVkIHRocm91Z2gKICogcGVyZl9jb3VudGVyX2Zvcl9lYWNoX2NoaWxkIG9yIHBlcmZfY291bnRlcl9mb3JfZWFjaCBhcyBkZXNjcmliZWQKICogZm9yIHBlcmZfY291bnRlcl9kaXNhYmxlLgogKi8Kc3RhdGljIHZvaWQgcGVyZl9jb3VudGVyX2VuYWJsZShzdHJ1Y3QgcGVyZl9jb3VudGVyICpjb3VudGVyKQp7CglzdHJ1Y3QgcGVyZl9jb3VudGVyX2NvbnRleHQgKmN0eCA9IGNvdW50ZXItPmN0eDsKCXN0cnVjdCB0YXNrX3N0cnVjdCAqdGFzayA9IGN0eC0+dGFzazsKCglpZiAoIXRhc2spIHsKCQkvKgoJCSAqIEVuYWJsZSB0aGUgY291bnRlciBvbiB0aGUgY3B1IHRoYXQgaXQncyBvbgoJCSAqLwoJCXNtcF9jYWxsX2Z1bmN0aW9uX3NpbmdsZShjb3VudGVyLT5jcHUsIF9fcGVyZl9jb3VudGVyX2VuYWJsZSwKCQkJCQkgY291bnRlciwgMSk7CgkJcmV0dXJuOwoJfQoKCXNwaW5fbG9ja19pcnEoJmN0eC0+bG9jayk7CglpZiAoY291bnRlci0+c3RhdGUgPj0gUEVSRl9DT1VOVEVSX1NUQVRFX0lOQUNUSVZFKQoJCWdvdG8gb3V0OwoKCS8qCgkgKiBJZiB0aGUgY291bnRlciBpcyBpbiBlcnJvciBzdGF0ZSwgY2xlYXIgdGhhdCBmaXJzdC4KCSAqIFRoYXQgd2F5LCBpZiB3ZSBzZWUgdGhlIGNvdW50ZXIgaW4gZXJyb3Igc3RhdGUgYmVsb3csIHdlCgkgKiBrbm93IHRoYXQgaXQgaGFzIGdvbmUgYmFjayBpbnRvIGVycm9yIHN0YXRlLCBhcyBkaXN0aW5jdAoJICogZnJvbSB0aGUgdGFzayBoYXZpbmcgYmVlbiBzY2hlZHVsZWQgYXdheSBiZWZvcmUgdGhlCgkgKiBjcm9zcy1jYWxsIGFycml2ZWQuCgkgKi8KCWlmIChjb3VudGVyLT5zdGF0ZSA9PSBQRVJGX0NPVU5URVJfU1RBVEVfRVJST1IpCgkJY291bnRlci0+c3RhdGUgPSBQRVJGX0NPVU5URVJfU1RBVEVfT0ZGOwoKIHJldHJ5OgoJc3Bpbl91bmxvY2tfaXJxKCZjdHgtPmxvY2spOwoJdGFza19vbmNwdV9mdW5jdGlvbl9jYWxsKHRhc2ssIF9fcGVyZl9jb3VudGVyX2VuYWJsZSwgY291bnRlcik7CgoJc3Bpbl9sb2NrX2lycSgmY3R4LT5sb2NrKTsKCgkvKgoJICogSWYgdGhlIGNvbnRleHQgaXMgYWN0aXZlIGFuZCB0aGUgY291bnRlciBpcyBzdGlsbCBvZmYsCgkgKiB3ZSBuZWVkIHRvIHJldHJ5IHRoZSBjcm9zcy1jYWxsLgoJICovCglpZiAoY3R4LT5pc19hY3RpdmUgJiYgY291bnRlci0+c3RhdGUgPT0gUEVSRl9DT1VOVEVSX1NUQVRFX09GRikKCQlnb3RvIHJldHJ5OwoKCS8qCgkgKiBTaW5jZSB3ZSBoYXZlIHRoZSBsb2NrIHRoaXMgY29udGV4dCBjYW4ndCBiZSBzY2hlZHVsZWQKCSAqIGluLCBzbyB3ZSBjYW4gY2hhbmdlIHRoZSBzdGF0ZSBzYWZlbHkuCgkgKi8KCWlmIChjb3VudGVyLT5zdGF0ZSA9PSBQRVJGX0NPVU5URVJfU1RBVEVfT0ZGKSB7CgkJY291bnRlci0+c3RhdGUgPSBQRVJGX0NPVU5URVJfU1RBVEVfSU5BQ1RJVkU7CgkJY291bnRlci0+dHN0YW1wX2VuYWJsZWQgPQoJCQljdHgtPnRpbWUgLSBjb3VudGVyLT50b3RhbF90aW1lX2VuYWJsZWQ7Cgl9CiBvdXQ6CglzcGluX3VubG9ja19pcnEoJmN0eC0+bG9jayk7Cn0KCnN0YXRpYyBpbnQgcGVyZl9jb3VudGVyX3JlZnJlc2goc3RydWN0IHBlcmZfY291bnRlciAqY291bnRlciwgaW50IHJlZnJlc2gpCnsKCS8qCgkgKiBub3Qgc3VwcG9ydGVkIG9uIGluaGVyaXRlZCBjb3VudGVycwoJICovCglpZiAoY291bnRlci0+YXR0ci5pbmhlcml0KQoJCXJldHVybiAtRUlOVkFMOwoKCWF0b21pY19hZGQocmVmcmVzaCwgJmNvdW50ZXItPmV2ZW50X2xpbWl0KTsKCXBlcmZfY291bnRlcl9lbmFibGUoY291bnRlcik7CgoJcmV0dXJuIDA7Cn0KCnZvaWQgX19wZXJmX2NvdW50ZXJfc2NoZWRfb3V0KHN0cnVjdCBwZXJmX2NvdW50ZXJfY29udGV4dCAqY3R4LAoJCQkgICAgICBzdHJ1Y3QgcGVyZl9jcHVfY29udGV4dCAqY3B1Y3R4KQp7CglzdHJ1Y3QgcGVyZl9jb3VudGVyICpjb3VudGVyOwoKCXNwaW5fbG9jaygmY3R4LT5sb2NrKTsKCWN0eC0+aXNfYWN0aXZlID0gMDsKCWlmIChsaWtlbHkoIWN0eC0+bnJfY291bnRlcnMpKQoJCWdvdG8gb3V0OwoJdXBkYXRlX2NvbnRleHRfdGltZShjdHgpOwoKCXBlcmZfZGlzYWJsZSgpOwoJaWYgKGN0eC0+bnJfYWN0aXZlKSB7CgkJbGlzdF9mb3JfZWFjaF9lbnRyeShjb3VudGVyLCAmY3R4LT5jb3VudGVyX2xpc3QsIGxpc3RfZW50cnkpIHsKCQkJaWYgKGNvdW50ZXIgIT0gY291bnRlci0+Z3JvdXBfbGVhZGVyKQoJCQkJY291bnRlcl9zY2hlZF9vdXQoY291bnRlciwgY3B1Y3R4LCBjdHgpOwoJCQllbHNlCgkJCQlncm91cF9zY2hlZF9vdXQoY291bnRlciwgY3B1Y3R4LCBjdHgpOwoJCX0KCX0KCXBlcmZfZW5hYmxlKCk7CiBvdXQ6CglzcGluX3VubG9jaygmY3R4LT5sb2NrKTsKfQoKLyoKICogVGVzdCB3aGV0aGVyIHR3byBjb250ZXh0cyBhcmUgZXF1aXZhbGVudCwgaS5lLiB3aGV0aGVyIHRoZXkKICogaGF2ZSBib3RoIGJlZW4gY2xvbmVkIGZyb20gdGhlIHNhbWUgdmVyc2lvbiBvZiB0aGUgc2FtZSBjb250ZXh0CiAqIGFuZCB0aGV5IGJvdGggaGF2ZSB0aGUgc2FtZSBudW1iZXIgb2YgZW5hYmxlZCBjb3VudGVycy4KICogSWYgdGhlIG51bWJlciBvZiBlbmFibGVkIGNvdW50ZXJzIGlzIHRoZSBzYW1lLCB0aGVuIHRoZSBzZXQKICogb2YgZW5hYmxlZCBjb3VudGVycyBzaG91bGQgYmUgdGhlIHNhbWUsIGJlY2F1c2UgdGhlc2UgYXJlIGJvdGgKICogaW5oZXJpdGVkIGNvbnRleHRzLCB0aGVyZWZvcmUgd2UgY2FuJ3QgYWNjZXNzIGluZGl2aWR1YWwgY291bnRlcnMKICogaW4gdGhlbSBkaXJlY3RseSB3aXRoIGFuIGZkOyB3ZSBjYW4gb25seSBlbmFibGUvZGlzYWJsZSBhbGwKICogY291bnRlcnMgdmlhIHByY3RsLCBvciBlbmFibGUvZGlzYWJsZSBhbGwgY291bnRlcnMgaW4gYSBmYW1pbHkKICogdmlhIGlvY3RsLCB3aGljaCB3aWxsIGhhdmUgdGhlIHNhbWUgZWZmZWN0IG9uIGJvdGggY29udGV4dHMuCiAqLwpzdGF0aWMgaW50IGNvbnRleHRfZXF1aXYoc3RydWN0IHBlcmZfY291bnRlcl9jb250ZXh0ICpjdHgxLAoJCQkgc3RydWN0IHBlcmZfY291bnRlcl9jb250ZXh0ICpjdHgyKQp7CglyZXR1cm4gY3R4MS0+cGFyZW50X2N0eCAmJiBjdHgxLT5wYXJlbnRfY3R4ID09IGN0eDItPnBhcmVudF9jdHgKCQkmJiBjdHgxLT5wYXJlbnRfZ2VuID09IGN0eDItPnBhcmVudF9nZW4KCQkmJiAhY3R4MS0+cGluX2NvdW50ICYmICFjdHgyLT5waW5fY291bnQ7Cn0KCnN0YXRpYyB2b2lkIF9fcGVyZl9jb3VudGVyX3JlYWQodm9pZCAqY291bnRlcik7CgpzdGF0aWMgdm9pZCBfX3BlcmZfY291bnRlcl9zeW5jX3N0YXQoc3RydWN0IHBlcmZfY291bnRlciAqY291bnRlciwKCQkJCSAgICAgc3RydWN0IHBlcmZfY291bnRlciAqbmV4dF9jb3VudGVyKQp7Cgl1NjQgdmFsdWU7CgoJaWYgKCFjb3VudGVyLT5hdHRyLmluaGVyaXRfc3RhdCkKCQlyZXR1cm47CgoJLyoKCSAqIFVwZGF0ZSB0aGUgY291bnRlciB2YWx1ZSwgd2UgY2Fubm90IHVzZSBwZXJmX2NvdW50ZXJfcmVhZCgpCgkgKiBiZWNhdXNlIHdlJ3JlIGluIHRoZSBtaWRkbGUgb2YgYSBjb250ZXh0IHN3aXRjaCBhbmQgaGF2ZSBJUlFzCgkgKiBkaXNhYmxlZCwgd2hpY2ggdXBzZXRzIHNtcF9jYWxsX2Z1bmN0aW9uX3NpbmdsZSgpLCBob3dldmVyCgkgKiB3ZSBrbm93IHRoZSBjb3VudGVyIG11c3QgYmUgb24gdGhlIGN1cnJlbnQgQ1BVLCB0aGVyZWZvcmUgd2UKCSAqIGRvbid0IG5lZWQgdG8gdXNlIGl0LgoJICovCglzd2l0Y2ggKGNvdW50ZXItPnN0YXRlKSB7CgljYXNlIFBFUkZfQ09VTlRFUl9TVEFURV9BQ1RJVkU6CgkJX19wZXJmX2NvdW50ZXJfcmVhZChjb3VudGVyKTsKCQlicmVhazsKCgljYXNlIFBFUkZfQ09VTlRFUl9TVEFURV9JTkFDVElWRToKCQl1cGRhdGVfY291bnRlcl90aW1lcyhjb3VudGVyKTsKCQlicmVhazsKCglkZWZhdWx0OgoJCWJyZWFrOwoJfQoKCS8qCgkgKiBJbiBvcmRlciB0byBrZWVwIHBlci10YXNrIHN0YXRzIHJlbGlhYmxlIHdlIG5lZWQgdG8gZmxpcCB0aGUgY291bnRlcgoJICogdmFsdWVzIHdoZW4gd2UgZmxpcCB0aGUgY29udGV4dHMuCgkgKi8KCXZhbHVlID0gYXRvbWljNjRfcmVhZCgmbmV4dF9jb3VudGVyLT5jb3VudCk7Cgl2YWx1ZSA9IGF0b21pYzY0X3hjaGcoJmNvdW50ZXItPmNvdW50LCB2YWx1ZSk7CglhdG9taWM2NF9zZXQoJm5leHRfY291bnRlci0+Y291bnQsIHZhbHVlKTsKCglzd2FwKGNvdW50ZXItPnRvdGFsX3RpbWVfZW5hYmxlZCwgbmV4dF9jb3VudGVyLT50b3RhbF90aW1lX2VuYWJsZWQpOwoJc3dhcChjb3VudGVyLT50b3RhbF90aW1lX3J1bm5pbmcsIG5leHRfY291bnRlci0+dG90YWxfdGltZV9ydW5uaW5nKTsKCgkvKgoJICogU2luY2Ugd2Ugc3dpenpsZWQgdGhlIHZhbHVlcywgdXBkYXRlIHRoZSB1c2VyIHZpc2libGUgZGF0YSB0b28uCgkgKi8KCXBlcmZfY291bnRlcl91cGRhdGVfdXNlcnBhZ2UoY291bnRlcik7CglwZXJmX2NvdW50ZXJfdXBkYXRlX3VzZXJwYWdlKG5leHRfY291bnRlcik7Cn0KCiNkZWZpbmUgbGlzdF9uZXh0X2VudHJ5KHBvcywgbWVtYmVyKSBcCglsaXN0X2VudHJ5KHBvcy0+bWVtYmVyLm5leHQsIHR5cGVvZigqcG9zKSwgbWVtYmVyKQoKc3RhdGljIHZvaWQgcGVyZl9jb3VudGVyX3N5bmNfc3RhdChzdHJ1Y3QgcGVyZl9jb3VudGVyX2NvbnRleHQgKmN0eCwKCQkJCSAgIHN0cnVjdCBwZXJmX2NvdW50ZXJfY29udGV4dCAqbmV4dF9jdHgpCnsKCXN0cnVjdCBwZXJmX2NvdW50ZXIgKmNvdW50ZXIsICpuZXh0X2NvdW50ZXI7CgoJaWYgKCFjdHgtPm5yX3N0YXQpCgkJcmV0dXJuOwoKCWNvdW50ZXIgPSBsaXN0X2ZpcnN0X2VudHJ5KCZjdHgtPmV2ZW50X2xpc3QsCgkJCQkgICBzdHJ1Y3QgcGVyZl9jb3VudGVyLCBldmVudF9lbnRyeSk7CgoJbmV4dF9jb3VudGVyID0gbGlzdF9maXJzdF9lbnRyeSgmbmV4dF9jdHgtPmV2ZW50X2xpc3QsCgkJCQkJc3RydWN0IHBlcmZfY291bnRlciwgZXZlbnRfZW50cnkpOwoKCXdoaWxlICgmY291bnRlci0+ZXZlbnRfZW50cnkgIT0gJmN0eC0+ZXZlbnRfbGlzdCAmJgoJICAgICAgICZuZXh0X2NvdW50ZXItPmV2ZW50X2VudHJ5ICE9ICZuZXh0X2N0eC0+ZXZlbnRfbGlzdCkgewoKCQlfX3BlcmZfY291bnRlcl9zeW5jX3N0YXQoY291bnRlciwgbmV4dF9jb3VudGVyKTsKCgkJY291bnRlciA9IGxpc3RfbmV4dF9lbnRyeShjb3VudGVyLCBldmVudF9lbnRyeSk7CgkJbmV4dF9jb3VudGVyID0gbGlzdF9uZXh0X2VudHJ5KGNvdW50ZXIsIGV2ZW50X2VudHJ5KTsKCX0KfQoKLyoKICogQ2FsbGVkIGZyb20gc2NoZWR1bGVyIHRvIHJlbW92ZSB0aGUgY291bnRlcnMgb2YgdGhlIGN1cnJlbnQgdGFzaywKICogd2l0aCBpbnRlcnJ1cHRzIGRpc2FibGVkLgogKgogKiBXZSBzdG9wIGVhY2ggY291bnRlciBhbmQgdXBkYXRlIHRoZSBjb3VudGVyIHZhbHVlIGluIGNvdW50ZXItPmNvdW50LgogKgogKiBUaGlzIGRvZXMgbm90IHByb3RlY3QgdXMgYWdhaW5zdCBOTUksIGJ1dCBkaXNhYmxlKCkKICogc2V0cyB0aGUgZGlzYWJsZWQgYml0IGluIHRoZSBjb250cm9sIGZpZWxkIG9mIGNvdW50ZXIgX2JlZm9yZV8KICogYWNjZXNzaW5nIHRoZSBjb3VudGVyIGNvbnRyb2wgcmVnaXN0ZXIuIElmIGEgTk1JIGhpdHMsIHRoZW4gaXQgd2lsbAogKiBub3QgcmVzdGFydCB0aGUgY291bnRlci4KICovCnZvaWQgcGVyZl9jb3VudGVyX3Rhc2tfc2NoZWRfb3V0KHN0cnVjdCB0YXNrX3N0cnVjdCAqdGFzaywKCQkJCSBzdHJ1Y3QgdGFza19zdHJ1Y3QgKm5leHQsIGludCBjcHUpCnsKCXN0cnVjdCBwZXJmX2NwdV9jb250ZXh0ICpjcHVjdHggPSAmcGVyX2NwdShwZXJmX2NwdV9jb250ZXh0LCBjcHUpOwoJc3RydWN0IHBlcmZfY291bnRlcl9jb250ZXh0ICpjdHggPSB0YXNrLT5wZXJmX2NvdW50ZXJfY3R4cDsKCXN0cnVjdCBwZXJmX2NvdW50ZXJfY29udGV4dCAqbmV4dF9jdHg7CglzdHJ1Y3QgcGVyZl9jb3VudGVyX2NvbnRleHQgKnBhcmVudDsKCXN0cnVjdCBwdF9yZWdzICpyZWdzOwoJaW50IGRvX3N3aXRjaCA9IDE7CgoJcmVncyA9IHRhc2tfcHRfcmVncyh0YXNrKTsKCXBlcmZfc3djb3VudGVyX2V2ZW50KFBFUkZfQ09VTlRfU1dfQ09OVEVYVF9TV0lUQ0hFUywgMSwgMSwgcmVncywgMCk7CgoJaWYgKGxpa2VseSghY3R4IHx8ICFjcHVjdHgtPnRhc2tfY3R4KSkKCQlyZXR1cm47CgoJdXBkYXRlX2NvbnRleHRfdGltZShjdHgpOwoKCXJjdV9yZWFkX2xvY2soKTsKCXBhcmVudCA9IHJjdV9kZXJlZmVyZW5jZShjdHgtPnBhcmVudF9jdHgpOwoJbmV4dF9jdHggPSBuZXh0LT5wZXJmX2NvdW50ZXJfY3R4cDsKCWlmIChwYXJlbnQgJiYgbmV4dF9jdHggJiYKCSAgICByY3VfZGVyZWZlcmVuY2UobmV4dF9jdHgtPnBhcmVudF9jdHgpID09IHBhcmVudCkgewoJCS8qCgkJICogTG9va3MgbGlrZSB0aGUgdHdvIGNvbnRleHRzIGFyZSBjbG9uZXMsIHNvIHdlIG1pZ2h0IGJlCgkJICogYWJsZSB0byBvcHRpbWl6ZSB0aGUgY29udGV4dCBzd2l0Y2guICBXZSBsb2NrIGJvdGgKCQkgKiBjb250ZXh0cyBhbmQgY2hlY2sgdGhhdCB0aGV5IGFyZSBjbG9uZXMgdW5kZXIgdGhlCgkJICogbG9jayAoaW5jbHVkaW5nIHJlLWNoZWNraW5nIHRoYXQgbmVpdGhlciBoYXMgYmVlbgoJCSAqIHVuY2xvbmVkIGluIHRoZSBtZWFudGltZSkuICBJdCBkb2Vzbid0IG1hdHRlciB3aGljaAoJCSAqIG9yZGVyIHdlIHRha2UgdGhlIGxvY2tzIGJlY2F1c2Ugbm8gb3RoZXIgY3B1IGNvdWxkCgkJICogYmUgdHJ5aW5nIHRvIGxvY2sgYm90aCBvZiB0aGVzZSB0YXNrcy4KCQkgKi8KCQlzcGluX2xvY2soJmN0eC0+bG9jayk7CgkJc3Bpbl9sb2NrX25lc3RlZCgmbmV4dF9jdHgtPmxvY2ssIFNJTkdMRV9ERVBUSF9ORVNUSU5HKTsKCQlpZiAoY29udGV4dF9lcXVpdihjdHgsIG5leHRfY3R4KSkgewoJCQkvKgoJCQkgKiBYWFggZG8gd2UgbmVlZCBhIG1lbW9yeSBiYXJyaWVyIG9mIHNvcnRzCgkJCSAqIHdydCB0byByY3VfZGVyZWZlcmVuY2UoKSBvZiBwZXJmX2NvdW50ZXJfY3R4cAoJCQkgKi8KCQkJdGFzay0+cGVyZl9jb3VudGVyX2N0eHAgPSBuZXh0X2N0eDsKCQkJbmV4dC0+cGVyZl9jb3VudGVyX2N0eHAgPSBjdHg7CgkJCWN0eC0+dGFzayA9IG5leHQ7CgkJCW5leHRfY3R4LT50YXNrID0gdGFzazsKCQkJZG9fc3dpdGNoID0gMDsKCgkJCXBlcmZfY291bnRlcl9zeW5jX3N0YXQoY3R4LCBuZXh0X2N0eCk7CgkJfQoJCXNwaW5fdW5sb2NrKCZuZXh0X2N0eC0+bG9jayk7CgkJc3Bpbl91bmxvY2soJmN0eC0+bG9jayk7Cgl9CglyY3VfcmVhZF91bmxvY2soKTsKCglpZiAoZG9fc3dpdGNoKSB7CgkJX19wZXJmX2NvdW50ZXJfc2NoZWRfb3V0KGN0eCwgY3B1Y3R4KTsKCQljcHVjdHgtPnRhc2tfY3R4ID0gTlVMTDsKCX0KfQoKLyoKICogQ2FsbGVkIHdpdGggSVJRcyBkaXNhYmxlZAogKi8Kc3RhdGljIHZvaWQgX19wZXJmX2NvdW50ZXJfdGFza19zY2hlZF9vdXQoc3RydWN0IHBlcmZfY291bnRlcl9jb250ZXh0ICpjdHgpCnsKCXN0cnVjdCBwZXJmX2NwdV9jb250ZXh0ICpjcHVjdHggPSAmX19nZXRfY3B1X3ZhcihwZXJmX2NwdV9jb250ZXh0KTsKCglpZiAoIWNwdWN0eC0+dGFza19jdHgpCgkJcmV0dXJuOwoKCWlmIChXQVJOX09OX09OQ0UoY3R4ICE9IGNwdWN0eC0+dGFza19jdHgpKQoJCXJldHVybjsKCglfX3BlcmZfY291bnRlcl9zY2hlZF9vdXQoY3R4LCBjcHVjdHgpOwoJY3B1Y3R4LT50YXNrX2N0eCA9IE5VTEw7Cn0KCi8qCiAqIENhbGxlZCB3aXRoIElSUXMgZGlzYWJsZWQKICovCnN0YXRpYyB2b2lkIHBlcmZfY291bnRlcl9jcHVfc2NoZWRfb3V0KHN0cnVjdCBwZXJmX2NwdV9jb250ZXh0ICpjcHVjdHgpCnsKCV9fcGVyZl9jb3VudGVyX3NjaGVkX291dCgmY3B1Y3R4LT5jdHgsIGNwdWN0eCk7Cn0KCnN0YXRpYyB2b2lkCl9fcGVyZl9jb3VudGVyX3NjaGVkX2luKHN0cnVjdCBwZXJmX2NvdW50ZXJfY29udGV4dCAqY3R4LAoJCQlzdHJ1Y3QgcGVyZl9jcHVfY29udGV4dCAqY3B1Y3R4LCBpbnQgY3B1KQp7CglzdHJ1Y3QgcGVyZl9jb3VudGVyICpjb3VudGVyOwoJaW50IGNhbl9hZGRfaHcgPSAxOwoKCXNwaW5fbG9jaygmY3R4LT5sb2NrKTsKCWN0eC0+aXNfYWN0aXZlID0gMTsKCWlmIChsaWtlbHkoIWN0eC0+bnJfY291bnRlcnMpKQoJCWdvdG8gb3V0OwoKCWN0eC0+dGltZXN0YW1wID0gcGVyZl9jbG9jaygpOwoKCXBlcmZfZGlzYWJsZSgpOwoKCS8qCgkgKiBGaXJzdCBnbyB0aHJvdWdoIHRoZSBsaXN0IGFuZCBwdXQgb24gYW55IHBpbm5lZCBncm91cHMKCSAqIGluIG9yZGVyIHRvIGdpdmUgdGhlbSB0aGUgYmVzdCBjaGFuY2Ugb2YgZ29pbmcgb24uCgkgKi8KCWxpc3RfZm9yX2VhY2hfZW50cnkoY291bnRlciwgJmN0eC0+Y291bnRlcl9saXN0LCBsaXN0X2VudHJ5KSB7CgkJaWYgKGNvdW50ZXItPnN0YXRlIDw9IFBFUkZfQ09VTlRFUl9TVEFURV9PRkYgfHwKCQkgICAgIWNvdW50ZXItPmF0dHIucGlubmVkKQoJCQljb250aW51ZTsKCQlpZiAoY291bnRlci0+Y3B1ICE9IC0xICYmIGNvdW50ZXItPmNwdSAhPSBjcHUpCgkJCWNvbnRpbnVlOwoKCQlpZiAoY291bnRlciAhPSBjb3VudGVyLT5ncm91cF9sZWFkZXIpCgkJCWNvdW50ZXJfc2NoZWRfaW4oY291bnRlciwgY3B1Y3R4LCBjdHgsIGNwdSk7CgkJZWxzZSB7CgkJCWlmIChncm91cF9jYW5fZ29fb24oY291bnRlciwgY3B1Y3R4LCAxKSkKCQkJCWdyb3VwX3NjaGVkX2luKGNvdW50ZXIsIGNwdWN0eCwgY3R4LCBjcHUpOwoJCX0KCgkJLyoKCQkgKiBJZiB0aGlzIHBpbm5lZCBncm91cCBoYXNuJ3QgYmVlbiBzY2hlZHVsZWQsCgkJICogcHV0IGl0IGluIGVycm9yIHN0YXRlLgoJCSAqLwoJCWlmIChjb3VudGVyLT5zdGF0ZSA9PSBQRVJGX0NPVU5URVJfU1RBVEVfSU5BQ1RJVkUpIHsKCQkJdXBkYXRlX2dyb3VwX3RpbWVzKGNvdW50ZXIpOwoJCQljb3VudGVyLT5zdGF0ZSA9IFBFUkZfQ09VTlRFUl9TVEFURV9FUlJPUjsKCQl9Cgl9CgoJbGlzdF9mb3JfZWFjaF9lbnRyeShjb3VudGVyLCAmY3R4LT5jb3VudGVyX2xpc3QsIGxpc3RfZW50cnkpIHsKCQkvKgoJCSAqIElnbm9yZSBjb3VudGVycyBpbiBPRkYgb3IgRVJST1Igc3RhdGUsIGFuZAoJCSAqIGlnbm9yZSBwaW5uZWQgY291bnRlcnMgc2luY2Ugd2UgZGlkIHRoZW0gYWxyZWFkeS4KCQkgKi8KCQlpZiAoY291bnRlci0+c3RhdGUgPD0gUEVSRl9DT1VOVEVSX1NUQVRFX09GRiB8fAoJCSAgICBjb3VudGVyLT5hdHRyLnBpbm5lZCkKCQkJY29udGludWU7CgoJCS8qCgkJICogTGlzdGVuIHRvIHRoZSAnY3B1JyBzY2hlZHVsaW5nIGZpbHRlciBjb25zdHJhaW50CgkJICogb2YgY291bnRlcnM6CgkJICovCgkJaWYgKGNvdW50ZXItPmNwdSAhPSAtMSAmJiBjb3VudGVyLT5jcHUgIT0gY3B1KQoJCQljb250aW51ZTsKCgkJaWYgKGNvdW50ZXIgIT0gY291bnRlci0+Z3JvdXBfbGVhZGVyKSB7CgkJCWlmIChjb3VudGVyX3NjaGVkX2luKGNvdW50ZXIsIGNwdWN0eCwgY3R4LCBjcHUpKQoJCQkJY2FuX2FkZF9odyA9IDA7CgkJfSBlbHNlIHsKCQkJaWYgKGdyb3VwX2Nhbl9nb19vbihjb3VudGVyLCBjcHVjdHgsIGNhbl9hZGRfaHcpKSB7CgkJCQlpZiAoZ3JvdXBfc2NoZWRfaW4oY291bnRlciwgY3B1Y3R4LCBjdHgsIGNwdSkpCgkJCQkJY2FuX2FkZF9odyA9IDA7CgkJCX0KCQl9Cgl9CglwZXJmX2VuYWJsZSgpOwogb3V0OgoJc3Bpbl91bmxvY2soJmN0eC0+bG9jayk7Cn0KCi8qCiAqIENhbGxlZCBmcm9tIHNjaGVkdWxlciB0byBhZGQgdGhlIGNvdW50ZXJzIG9mIHRoZSBjdXJyZW50IHRhc2sKICogd2l0aCBpbnRlcnJ1cHRzIGRpc2FibGVkLgogKgogKiBXZSByZXN0b3JlIHRoZSBjb3VudGVyIHZhbHVlIGFuZCB0aGVuIGVuYWJsZSBpdC4KICoKICogVGhpcyBkb2VzIG5vdCBwcm90ZWN0IHVzIGFnYWluc3QgTk1JLCBidXQgZW5hYmxlKCkKICogc2V0cyB0aGUgZW5hYmxlZCBiaXQgaW4gdGhlIGNvbnRyb2wgZmllbGQgb2YgY291bnRlciBfYmVmb3JlXwogKiBhY2Nlc3NpbmcgdGhlIGNvdW50ZXIgY29udHJvbCByZWdpc3Rlci4gSWYgYSBOTUkgaGl0cywgdGhlbiBpdCB3aWxsCiAqIGtlZXAgdGhlIGNvdW50ZXIgcnVubmluZy4KICovCnZvaWQgcGVyZl9jb3VudGVyX3Rhc2tfc2NoZWRfaW4oc3RydWN0IHRhc2tfc3RydWN0ICp0YXNrLCBpbnQgY3B1KQp7CglzdHJ1Y3QgcGVyZl9jcHVfY29udGV4dCAqY3B1Y3R4ID0gJnBlcl9jcHUocGVyZl9jcHVfY29udGV4dCwgY3B1KTsKCXN0cnVjdCBwZXJmX2NvdW50ZXJfY29udGV4dCAqY3R4ID0gdGFzay0+cGVyZl9jb3VudGVyX2N0eHA7CgoJaWYgKGxpa2VseSghY3R4KSkKCQlyZXR1cm47CglpZiAoY3B1Y3R4LT50YXNrX2N0eCA9PSBjdHgpCgkJcmV0dXJuOwoJX19wZXJmX2NvdW50ZXJfc2NoZWRfaW4oY3R4LCBjcHVjdHgsIGNwdSk7CgljcHVjdHgtPnRhc2tfY3R4ID0gY3R4Owp9CgpzdGF0aWMgdm9pZCBwZXJmX2NvdW50ZXJfY3B1X3NjaGVkX2luKHN0cnVjdCBwZXJmX2NwdV9jb250ZXh0ICpjcHVjdHgsIGludCBjcHUpCnsKCXN0cnVjdCBwZXJmX2NvdW50ZXJfY29udGV4dCAqY3R4ID0gJmNwdWN0eC0+Y3R4OwoKCV9fcGVyZl9jb3VudGVyX3NjaGVkX2luKGN0eCwgY3B1Y3R4LCBjcHUpOwp9CgojZGVmaW5lIE1BWF9JTlRFUlJVUFRTICh+MFVMTCkKCnN0YXRpYyB2b2lkIHBlcmZfbG9nX3Rocm90dGxlKHN0cnVjdCBwZXJmX2NvdW50ZXIgKmNvdW50ZXIsIGludCBlbmFibGUpOwpzdGF0aWMgdm9pZCBwZXJmX2xvZ19wZXJpb2Qoc3RydWN0IHBlcmZfY291bnRlciAqY291bnRlciwgdTY0IHBlcmlvZCk7CgpzdGF0aWMgdm9pZCBwZXJmX2FkanVzdF9wZXJpb2Qoc3RydWN0IHBlcmZfY291bnRlciAqY291bnRlciwgdTY0IGV2ZW50cykKewoJc3RydWN0IGh3X3BlcmZfY291bnRlciAqaHdjID0gJmNvdW50ZXItPmh3OwoJdTY0IHBlcmlvZCwgc2FtcGxlX3BlcmlvZDsKCXM2NCBkZWx0YTsKCglldmVudHMgKj0gaHdjLT5zYW1wbGVfcGVyaW9kOwoJcGVyaW9kID0gZGl2NjRfdTY0KGV2ZW50cywgY291bnRlci0+YXR0ci5zYW1wbGVfZnJlcSk7CgoJZGVsdGEgPSAoczY0KShwZXJpb2QgLSBod2MtPnNhbXBsZV9wZXJpb2QpOwoJZGVsdGEgPSAoZGVsdGEgKyA3KSAvIDg7IC8qIGxvdyBwYXNzIGZpbHRlciAqLwoKCXNhbXBsZV9wZXJpb2QgPSBod2MtPnNhbXBsZV9wZXJpb2QgKyBkZWx0YTsKCglpZiAoIXNhbXBsZV9wZXJpb2QpCgkJc2FtcGxlX3BlcmlvZCA9IDE7CgoJcGVyZl9sb2dfcGVyaW9kKGNvdW50ZXIsIHNhbXBsZV9wZXJpb2QpOwoKCWh3Yy0+c2FtcGxlX3BlcmlvZCA9IHNhbXBsZV9wZXJpb2Q7Cn0KCnN0YXRpYyB2b2lkIHBlcmZfY3R4X2FkanVzdF9mcmVxKHN0cnVjdCBwZXJmX2NvdW50ZXJfY29udGV4dCAqY3R4KQp7CglzdHJ1Y3QgcGVyZl9jb3VudGVyICpjb3VudGVyOwoJc3RydWN0IGh3X3BlcmZfY291bnRlciAqaHdjOwoJdTY0IGludGVycnVwdHMsIGZyZXE7CgoJc3Bpbl9sb2NrKCZjdHgtPmxvY2spOwoJbGlzdF9mb3JfZWFjaF9lbnRyeShjb3VudGVyLCAmY3R4LT5jb3VudGVyX2xpc3QsIGxpc3RfZW50cnkpIHsKCQlpZiAoY291bnRlci0+c3RhdGUgIT0gUEVSRl9DT1VOVEVSX1NUQVRFX0FDVElWRSkKCQkJY29udGludWU7CgoJCWh3YyA9ICZjb3VudGVyLT5odzsKCgkJaW50ZXJydXB0cyA9IGh3Yy0+aW50ZXJydXB0czsKCQlod2MtPmludGVycnVwdHMgPSAwOwoKCQkvKgoJCSAqIHVudGhyb3R0bGUgY291bnRlcnMgb24gdGhlIHRpY2sKCQkgKi8KCQlpZiAoaW50ZXJydXB0cyA9PSBNQVhfSU5URVJSVVBUUykgewoJCQlwZXJmX2xvZ190aHJvdHRsZShjb3VudGVyLCAxKTsKCQkJY291bnRlci0+cG11LT51bnRocm90dGxlKGNvdW50ZXIpOwoJCQlpbnRlcnJ1cHRzID0gMipzeXNjdGxfcGVyZl9jb3VudGVyX3NhbXBsZV9yYXRlL0haOwoJCX0KCgkJaWYgKCFjb3VudGVyLT5hdHRyLmZyZXEgfHwgIWNvdW50ZXItPmF0dHIuc2FtcGxlX2ZyZXEpCgkJCWNvbnRpbnVlOwoKCQkvKgoJCSAqIGlmIHRoZSBzcGVjaWZpZWQgZnJlcSA8IEhaIHRoZW4gd2UgbmVlZCB0byBza2lwIHRpY2tzCgkJICovCgkJaWYgKGNvdW50ZXItPmF0dHIuc2FtcGxlX2ZyZXEgPCBIWikgewoJCQlmcmVxID0gY291bnRlci0+YXR0ci5zYW1wbGVfZnJlcTsKCgkJCWh3Yy0+ZnJlcV9jb3VudCArPSBmcmVxOwoJCQlod2MtPmZyZXFfaW50ZXJydXB0cyArPSBpbnRlcnJ1cHRzOwoKCQkJaWYgKGh3Yy0+ZnJlcV9jb3VudCA8IEhaKQoJCQkJY29udGludWU7CgoJCQlpbnRlcnJ1cHRzID0gaHdjLT5mcmVxX2ludGVycnVwdHM7CgkJCWh3Yy0+ZnJlcV9pbnRlcnJ1cHRzID0gMDsKCQkJaHdjLT5mcmVxX2NvdW50IC09IEhaOwoJCX0gZWxzZQoJCQlmcmVxID0gSFo7CgoJCXBlcmZfYWRqdXN0X3BlcmlvZChjb3VudGVyLCBmcmVxICogaW50ZXJydXB0cyk7CgoJCS8qCgkJICogSW4gb3JkZXIgdG8gYXZvaWQgYmVpbmcgc3RhbGxlZCBieSBhbiAoYWNjaWRlbnRhbCkgaHVnZQoJCSAqIHNhbXBsZSBwZXJpb2QsIGZvcmNlIHJlc2V0IHRoZSBzYW1wbGUgcGVyaW9kIGlmIHdlIGRpZG4ndAoJCSAqIGdldCBhbnkgZXZlbnRzIGluIHRoaXMgZnJlcSBwZXJpb2QuCgkJICovCgkJaWYgKCFpbnRlcnJ1cHRzKSB7CgkJCXBlcmZfZGlzYWJsZSgpOwoJCQljb3VudGVyLT5wbXUtPmRpc2FibGUoY291bnRlcik7CgkJCWF0b21pYzY0X3NldCgmaHdjLT5wZXJpb2RfbGVmdCwgMCk7CgkJCWNvdW50ZXItPnBtdS0+ZW5hYmxlKGNvdW50ZXIpOwoJCQlwZXJmX2VuYWJsZSgpOwoJCX0KCX0KCXNwaW5fdW5sb2NrKCZjdHgtPmxvY2spOwp9CgovKgogKiBSb3VuZC1yb2JpbiBhIGNvbnRleHQncyBjb3VudGVyczoKICovCnN0YXRpYyB2b2lkIHJvdGF0ZV9jdHgoc3RydWN0IHBlcmZfY291bnRlcl9jb250ZXh0ICpjdHgpCnsKCXN0cnVjdCBwZXJmX2NvdW50ZXIgKmNvdW50ZXI7CgoJaWYgKCFjdHgtPm5yX2NvdW50ZXJzKQoJCXJldHVybjsKCglzcGluX2xvY2soJmN0eC0+bG9jayk7CgkvKgoJICogUm90YXRlIHRoZSBmaXJzdCBlbnRyeSBsYXN0ICh3b3JrcyBqdXN0IGZpbmUgZm9yIGdyb3VwIGNvdW50ZXJzIHRvbyk6CgkgKi8KCXBlcmZfZGlzYWJsZSgpOwoJbGlzdF9mb3JfZWFjaF9lbnRyeShjb3VudGVyLCAmY3R4LT5jb3VudGVyX2xpc3QsIGxpc3RfZW50cnkpIHsKCQlsaXN0X21vdmVfdGFpbCgmY291bnRlci0+bGlzdF9lbnRyeSwgJmN0eC0+Y291bnRlcl9saXN0KTsKCQlicmVhazsKCX0KCXBlcmZfZW5hYmxlKCk7CgoJc3Bpbl91bmxvY2soJmN0eC0+bG9jayk7Cn0KCnZvaWQgcGVyZl9jb3VudGVyX3Rhc2tfdGljayhzdHJ1Y3QgdGFza19zdHJ1Y3QgKmN1cnIsIGludCBjcHUpCnsKCXN0cnVjdCBwZXJmX2NwdV9jb250ZXh0ICpjcHVjdHg7CglzdHJ1Y3QgcGVyZl9jb3VudGVyX2NvbnRleHQgKmN0eDsKCglpZiAoIWF0b21pY19yZWFkKCZucl9jb3VudGVycykpCgkJcmV0dXJuOwoKCWNwdWN0eCA9ICZwZXJfY3B1KHBlcmZfY3B1X2NvbnRleHQsIGNwdSk7CgljdHggPSBjdXJyLT5wZXJmX2NvdW50ZXJfY3R4cDsKCglwZXJmX2N0eF9hZGp1c3RfZnJlcSgmY3B1Y3R4LT5jdHgpOwoJaWYgKGN0eCkKCQlwZXJmX2N0eF9hZGp1c3RfZnJlcShjdHgpOwoKCXBlcmZfY291bnRlcl9jcHVfc2NoZWRfb3V0KGNwdWN0eCk7CglpZiAoY3R4KQoJCV9fcGVyZl9jb3VudGVyX3Rhc2tfc2NoZWRfb3V0KGN0eCk7CgoJcm90YXRlX2N0eCgmY3B1Y3R4LT5jdHgpOwoJaWYgKGN0eCkKCQlyb3RhdGVfY3R4KGN0eCk7CgoJcGVyZl9jb3VudGVyX2NwdV9zY2hlZF9pbihjcHVjdHgsIGNwdSk7CglpZiAoY3R4KQoJCXBlcmZfY291bnRlcl90YXNrX3NjaGVkX2luKGN1cnIsIGNwdSk7Cn0KCi8qCiAqIEVuYWJsZSBhbGwgb2YgYSB0YXNrJ3MgY291bnRlcnMgdGhhdCBoYXZlIGJlZW4gbWFya2VkIGVuYWJsZS1vbi1leGVjLgogKiBUaGlzIGV4cGVjdHMgdGFzayA9PSBjdXJyZW50LgogKi8Kc3RhdGljIHZvaWQgcGVyZl9jb3VudGVyX2VuYWJsZV9vbl9leGVjKHN0cnVjdCB0YXNrX3N0cnVjdCAqdGFzaykKewoJc3RydWN0IHBlcmZfY291bnRlcl9jb250ZXh0ICpjdHg7CglzdHJ1Y3QgcGVyZl9jb3VudGVyICpjb3VudGVyOwoJdW5zaWduZWQgbG9uZyBmbGFnczsKCWludCBlbmFibGVkID0gMDsKCglsb2NhbF9pcnFfc2F2ZShmbGFncyk7CgljdHggPSB0YXNrLT5wZXJmX2NvdW50ZXJfY3R4cDsKCWlmICghY3R4IHx8ICFjdHgtPm5yX2NvdW50ZXJzKQoJCWdvdG8gb3V0OwoKCV9fcGVyZl9jb3VudGVyX3Rhc2tfc2NoZWRfb3V0KGN0eCk7CgoJc3Bpbl9sb2NrKCZjdHgtPmxvY2spOwoKCWxpc3RfZm9yX2VhY2hfZW50cnkoY291bnRlciwgJmN0eC0+Y291bnRlcl9saXN0LCBsaXN0X2VudHJ5KSB7CgkJaWYgKCFjb3VudGVyLT5hdHRyLmVuYWJsZV9vbl9leGVjKQoJCQljb250aW51ZTsKCQljb3VudGVyLT5hdHRyLmVuYWJsZV9vbl9leGVjID0gMDsKCQlpZiAoY291bnRlci0+c3RhdGUgPj0gUEVSRl9DT1VOVEVSX1NUQVRFX0lOQUNUSVZFKQoJCQljb250aW51ZTsKCQljb3VudGVyLT5zdGF0ZSA9IFBFUkZfQ09VTlRFUl9TVEFURV9JTkFDVElWRTsKCQljb3VudGVyLT50c3RhbXBfZW5hYmxlZCA9CgkJCWN0eC0+dGltZSAtIGNvdW50ZXItPnRvdGFsX3RpbWVfZW5hYmxlZDsKCQllbmFibGVkID0gMTsKCX0KCgkvKgoJICogVW5jbG9uZSB0aGlzIGNvbnRleHQgaWYgd2UgZW5hYmxlZCBhbnkgY291bnRlci4KCSAqLwoJaWYgKGVuYWJsZWQgJiYgY3R4LT5wYXJlbnRfY3R4KSB7CgkJcHV0X2N0eChjdHgtPnBhcmVudF9jdHgpOwoJCWN0eC0+cGFyZW50X2N0eCA9IE5VTEw7Cgl9CgoJc3Bpbl91bmxvY2soJmN0eC0+bG9jayk7CgoJcGVyZl9jb3VudGVyX3Rhc2tfc2NoZWRfaW4odGFzaywgc21wX3Byb2Nlc3Nvcl9pZCgpKTsKIG91dDoKCWxvY2FsX2lycV9yZXN0b3JlKGZsYWdzKTsKfQoKLyoKICogQ3Jvc3MgQ1BVIGNhbGwgdG8gcmVhZCB0aGUgaGFyZHdhcmUgY291bnRlcgogKi8Kc3RhdGljIHZvaWQgX19wZXJmX2NvdW50ZXJfcmVhZCh2b2lkICppbmZvKQp7CglzdHJ1Y3QgcGVyZl9jb3VudGVyICpjb3VudGVyID0gaW5mbzsKCXN0cnVjdCBwZXJmX2NvdW50ZXJfY29udGV4dCAqY3R4ID0gY291bnRlci0+Y3R4OwoJdW5zaWduZWQgbG9uZyBmbGFnczsKCglsb2NhbF9pcnFfc2F2ZShmbGFncyk7CglpZiAoY3R4LT5pc19hY3RpdmUpCgkJdXBkYXRlX2NvbnRleHRfdGltZShjdHgpOwoJY291bnRlci0+cG11LT5yZWFkKGNvdW50ZXIpOwoJdXBkYXRlX2NvdW50ZXJfdGltZXMoY291bnRlcik7Cglsb2NhbF9pcnFfcmVzdG9yZShmbGFncyk7Cn0KCnN0YXRpYyB1NjQgcGVyZl9jb3VudGVyX3JlYWQoc3RydWN0IHBlcmZfY291bnRlciAqY291bnRlcikKewoJLyoKCSAqIElmIGNvdW50ZXIgaXMgZW5hYmxlZCBhbmQgY3VycmVudGx5IGFjdGl2ZSBvbiBhIENQVSwgdXBkYXRlIHRoZQoJICogdmFsdWUgaW4gdGhlIGNvdW50ZXIgc3RydWN0dXJlOgoJICovCglpZiAoY291bnRlci0+c3RhdGUgPT0gUEVSRl9DT1VOVEVSX1NUQVRFX0FDVElWRSkgewoJCXNtcF9jYWxsX2Z1bmN0aW9uX3NpbmdsZShjb3VudGVyLT5vbmNwdSwKCQkJCQkgX19wZXJmX2NvdW50ZXJfcmVhZCwgY291bnRlciwgMSk7Cgl9IGVsc2UgaWYgKGNvdW50ZXItPnN0YXRlID09IFBFUkZfQ09VTlRFUl9TVEFURV9JTkFDVElWRSkgewoJCXVwZGF0ZV9jb3VudGVyX3RpbWVzKGNvdW50ZXIpOwoJfQoKCXJldHVybiBhdG9taWM2NF9yZWFkKCZjb3VudGVyLT5jb3VudCk7Cn0KCi8qCiAqIEluaXRpYWxpemUgdGhlIHBlcmZfY291bnRlciBjb250ZXh0IGluIGEgdGFza19zdHJ1Y3Q6CiAqLwpzdGF0aWMgdm9pZApfX3BlcmZfY291bnRlcl9pbml0X2NvbnRleHQoc3RydWN0IHBlcmZfY291bnRlcl9jb250ZXh0ICpjdHgsCgkJCSAgICBzdHJ1Y3QgdGFza19zdHJ1Y3QgKnRhc2spCnsKCW1lbXNldChjdHgsIDAsIHNpemVvZigqY3R4KSk7CglzcGluX2xvY2tfaW5pdCgmY3R4LT5sb2NrKTsKCW11dGV4X2luaXQoJmN0eC0+bXV0ZXgpOwoJSU5JVF9MSVNUX0hFQUQoJmN0eC0+Y291bnRlcl9saXN0KTsKCUlOSVRfTElTVF9IRUFEKCZjdHgtPmV2ZW50X2xpc3QpOwoJYXRvbWljX3NldCgmY3R4LT5yZWZjb3VudCwgMSk7CgljdHgtPnRhc2sgPSB0YXNrOwp9CgpzdGF0aWMgc3RydWN0IHBlcmZfY291bnRlcl9jb250ZXh0ICpmaW5kX2dldF9jb250ZXh0KHBpZF90IHBpZCwgaW50IGNwdSkKewoJc3RydWN0IHBlcmZfY291bnRlcl9jb250ZXh0ICpwYXJlbnRfY3R4OwoJc3RydWN0IHBlcmZfY291bnRlcl9jb250ZXh0ICpjdHg7CglzdHJ1Y3QgcGVyZl9jcHVfY29udGV4dCAqY3B1Y3R4OwoJc3RydWN0IHRhc2tfc3RydWN0ICp0YXNrOwoJdW5zaWduZWQgbG9uZyBmbGFnczsKCWludCBlcnI7CgoJLyoKCSAqIElmIGNwdSBpcyBub3QgYSB3aWxkY2FyZCB0aGVuIHRoaXMgaXMgYSBwZXJjcHUgY291bnRlcjoKCSAqLwoJaWYgKGNwdSAhPSAtMSkgewoJCS8qIE11c3QgYmUgcm9vdCB0byBvcGVyYXRlIG9uIGEgQ1BVIGNvdW50ZXI6ICovCgkJaWYgKHBlcmZfcGFyYW5vaWRfY3B1KCkgJiYgIWNhcGFibGUoQ0FQX1NZU19BRE1JTikpCgkJCXJldHVybiBFUlJfUFRSKC1FQUNDRVMpOwoKCQlpZiAoY3B1IDwgMCB8fCBjcHUgPiBudW1fcG9zc2libGVfY3B1cygpKQoJCQlyZXR1cm4gRVJSX1BUUigtRUlOVkFMKTsKCgkJLyoKCQkgKiBXZSBjb3VsZCBiZSBjbGV2ZXIgYW5kIGFsbG93IHRvIGF0dGFjaCBhIGNvdW50ZXIgdG8gYW4KCQkgKiBvZmZsaW5lIENQVSBhbmQgYWN0aXZhdGUgaXQgd2hlbiB0aGUgQ1BVIGNvbWVzIHVwLCBidXQKCQkgKiB0aGF0J3MgZm9yIGxhdGVyLgoJCSAqLwoJCWlmICghY3B1X2lzc2V0KGNwdSwgY3B1X29ubGluZV9tYXApKQoJCQlyZXR1cm4gRVJSX1BUUigtRU5PREVWKTsKCgkJY3B1Y3R4ID0gJnBlcl9jcHUocGVyZl9jcHVfY29udGV4dCwgY3B1KTsKCQljdHggPSAmY3B1Y3R4LT5jdHg7CgkJZ2V0X2N0eChjdHgpOwoKCQlyZXR1cm4gY3R4OwoJfQoKCXJjdV9yZWFkX2xvY2soKTsKCWlmICghcGlkKQoJCXRhc2sgPSBjdXJyZW50OwoJZWxzZQoJCXRhc2sgPSBmaW5kX3Rhc2tfYnlfdnBpZChwaWQpOwoJaWYgKHRhc2spCgkJZ2V0X3Rhc2tfc3RydWN0KHRhc2spOwoJcmN1X3JlYWRfdW5sb2NrKCk7CgoJaWYgKCF0YXNrKQoJCXJldHVybiBFUlJfUFRSKC1FU1JDSCk7CgoJLyoKCSAqIENhbid0IGF0dGFjaCBjb3VudGVycyB0byBhIGR5aW5nIHRhc2suCgkgKi8KCWVyciA9IC1FU1JDSDsKCWlmICh0YXNrLT5mbGFncyAmIFBGX0VYSVRJTkcpCgkJZ290byBlcnJvdXQ7CgoJLyogUmV1c2UgcHRyYWNlIHBlcm1pc3Npb24gY2hlY2tzIGZvciBub3cuICovCgllcnIgPSAtRUFDQ0VTOwoJaWYgKCFwdHJhY2VfbWF5X2FjY2Vzcyh0YXNrLCBQVFJBQ0VfTU9ERV9SRUFEKSkKCQlnb3RvIGVycm91dDsKCiByZXRyeToKCWN0eCA9IHBlcmZfbG9ja190YXNrX2NvbnRleHQodGFzaywgJmZsYWdzKTsKCWlmIChjdHgpIHsKCQlwYXJlbnRfY3R4ID0gY3R4LT5wYXJlbnRfY3R4OwoJCWlmIChwYXJlbnRfY3R4KSB7CgkJCXB1dF9jdHgocGFyZW50X2N0eCk7CgkJCWN0eC0+cGFyZW50X2N0eCA9IE5VTEw7CQkvKiBubyBsb25nZXIgYSBjbG9uZSAqLwoJCX0KCQlzcGluX3VubG9ja19pcnFyZXN0b3JlKCZjdHgtPmxvY2ssIGZsYWdzKTsKCX0KCglpZiAoIWN0eCkgewoJCWN0eCA9IGttYWxsb2Moc2l6ZW9mKHN0cnVjdCBwZXJmX2NvdW50ZXJfY29udGV4dCksIEdGUF9LRVJORUwpOwoJCWVyciA9IC1FTk9NRU07CgkJaWYgKCFjdHgpCgkJCWdvdG8gZXJyb3V0OwoJCV9fcGVyZl9jb3VudGVyX2luaXRfY29udGV4dChjdHgsIHRhc2spOwoJCWdldF9jdHgoY3R4KTsKCQlpZiAoY21weGNoZygmdGFzay0+cGVyZl9jb3VudGVyX2N0eHAsIE5VTEwsIGN0eCkpIHsKCQkJLyoKCQkJICogV2UgcmFjZWQgd2l0aCBzb21lIG90aGVyIHRhc2s7IHVzZQoJCQkgKiB0aGUgY29udGV4dCB0aGV5IHNldC4KCQkJICovCgkJCWtmcmVlKGN0eCk7CgkJCWdvdG8gcmV0cnk7CgkJfQoJCWdldF90YXNrX3N0cnVjdCh0YXNrKTsKCX0KCglwdXRfdGFza19zdHJ1Y3QodGFzayk7CglyZXR1cm4gY3R4OwoKIGVycm91dDoKCXB1dF90YXNrX3N0cnVjdCh0YXNrKTsKCXJldHVybiBFUlJfUFRSKGVycik7Cn0KCnN0YXRpYyB2b2lkIGZyZWVfY291bnRlcl9yY3Uoc3RydWN0IHJjdV9oZWFkICpoZWFkKQp7CglzdHJ1Y3QgcGVyZl9jb3VudGVyICpjb3VudGVyOwoKCWNvdW50ZXIgPSBjb250YWluZXJfb2YoaGVhZCwgc3RydWN0IHBlcmZfY291bnRlciwgcmN1X2hlYWQpOwoJaWYgKGNvdW50ZXItPm5zKQoJCXB1dF9waWRfbnMoY291bnRlci0+bnMpOwoJa2ZyZWUoY291bnRlcik7Cn0KCnN0YXRpYyB2b2lkIHBlcmZfcGVuZGluZ19zeW5jKHN0cnVjdCBwZXJmX2NvdW50ZXIgKmNvdW50ZXIpOwoKc3RhdGljIHZvaWQgZnJlZV9jb3VudGVyKHN0cnVjdCBwZXJmX2NvdW50ZXIgKmNvdW50ZXIpCnsKCXBlcmZfcGVuZGluZ19zeW5jKGNvdW50ZXIpOwoKCWlmICghY291bnRlci0+cGFyZW50KSB7CgkJYXRvbWljX2RlYygmbnJfY291bnRlcnMpOwoJCWlmIChjb3VudGVyLT5hdHRyLm1tYXApCgkJCWF0b21pY19kZWMoJm5yX21tYXBfY291bnRlcnMpOwoJCWlmIChjb3VudGVyLT5hdHRyLmNvbW0pCgkJCWF0b21pY19kZWMoJm5yX2NvbW1fY291bnRlcnMpOwoJfQoKCWlmIChjb3VudGVyLT5kZXN0cm95KQoJCWNvdW50ZXItPmRlc3Ryb3koY291bnRlcik7CgoJcHV0X2N0eChjb3VudGVyLT5jdHgpOwoJY2FsbF9yY3UoJmNvdW50ZXItPnJjdV9oZWFkLCBmcmVlX2NvdW50ZXJfcmN1KTsKfQoKLyoKICogQ2FsbGVkIHdoZW4gdGhlIGxhc3QgcmVmZXJlbmNlIHRvIHRoZSBmaWxlIGlzIGdvbmUuCiAqLwpzdGF0aWMgaW50IHBlcmZfcmVsZWFzZShzdHJ1Y3QgaW5vZGUgKmlub2RlLCBzdHJ1Y3QgZmlsZSAqZmlsZSkKewoJc3RydWN0IHBlcmZfY291bnRlciAqY291bnRlciA9IGZpbGUtPnByaXZhdGVfZGF0YTsKCXN0cnVjdCBwZXJmX2NvdW50ZXJfY29udGV4dCAqY3R4ID0gY291bnRlci0+Y3R4OwoKCWZpbGUtPnByaXZhdGVfZGF0YSA9IE5VTEw7CgoJV0FSTl9PTl9PTkNFKGN0eC0+cGFyZW50X2N0eCk7CgltdXRleF9sb2NrKCZjdHgtPm11dGV4KTsKCXBlcmZfY291bnRlcl9yZW1vdmVfZnJvbV9jb250ZXh0KGNvdW50ZXIpOwoJbXV0ZXhfdW5sb2NrKCZjdHgtPm11dGV4KTsKCgltdXRleF9sb2NrKCZjb3VudGVyLT5vd25lci0+cGVyZl9jb3VudGVyX211dGV4KTsKCWxpc3RfZGVsX2luaXQoJmNvdW50ZXItPm93bmVyX2VudHJ5KTsKCW11dGV4X3VubG9jaygmY291bnRlci0+b3duZXItPnBlcmZfY291bnRlcl9tdXRleCk7CglwdXRfdGFza19zdHJ1Y3QoY291bnRlci0+b3duZXIpOwoKCWZyZWVfY291bnRlcihjb3VudGVyKTsKCglyZXR1cm4gMDsKfQoKLyoKICogUmVhZCB0aGUgcGVyZm9ybWFuY2UgY291bnRlciAtIHNpbXBsZSBub24gYmxvY2tpbmcgdmVyc2lvbiBmb3Igbm93CiAqLwpzdGF0aWMgc3NpemVfdApwZXJmX3JlYWRfaHcoc3RydWN0IHBlcmZfY291bnRlciAqY291bnRlciwgY2hhciBfX3VzZXIgKmJ1Ziwgc2l6ZV90IGNvdW50KQp7Cgl1NjQgdmFsdWVzWzRdOwoJaW50IG47CgoJLyoKCSAqIFJldHVybiBlbmQtb2YtZmlsZSBmb3IgYSByZWFkIG9uIGEgY291bnRlciB0aGF0IGlzIGluCgkgKiBlcnJvciBzdGF0ZSAoaS5lLiBiZWNhdXNlIGl0IHdhcyBwaW5uZWQgYnV0IGl0IGNvdWxkbid0IGJlCgkgKiBzY2hlZHVsZWQgb24gdG8gdGhlIENQVSBhdCBzb21lIHBvaW50KS4KCSAqLwoJaWYgKGNvdW50ZXItPnN0YXRlID09IFBFUkZfQ09VTlRFUl9TVEFURV9FUlJPUikKCQlyZXR1cm4gMDsKCglXQVJOX09OX09OQ0UoY291bnRlci0+Y3R4LT5wYXJlbnRfY3R4KTsKCW11dGV4X2xvY2soJmNvdW50ZXItPmNoaWxkX211dGV4KTsKCXZhbHVlc1swXSA9IHBlcmZfY291bnRlcl9yZWFkKGNvdW50ZXIpOwoJbiA9IDE7CglpZiAoY291bnRlci0+YXR0ci5yZWFkX2Zvcm1hdCAmIFBFUkZfRk9STUFUX1RPVEFMX1RJTUVfRU5BQkxFRCkKCQl2YWx1ZXNbbisrXSA9IGNvdW50ZXItPnRvdGFsX3RpbWVfZW5hYmxlZCArCgkJCWF0b21pYzY0X3JlYWQoJmNvdW50ZXItPmNoaWxkX3RvdGFsX3RpbWVfZW5hYmxlZCk7CglpZiAoY291bnRlci0+YXR0ci5yZWFkX2Zvcm1hdCAmIFBFUkZfRk9STUFUX1RPVEFMX1RJTUVfUlVOTklORykKCQl2YWx1ZXNbbisrXSA9IGNvdW50ZXItPnRvdGFsX3RpbWVfcnVubmluZyArCgkJCWF0b21pYzY0X3JlYWQoJmNvdW50ZXItPmNoaWxkX3RvdGFsX3RpbWVfcnVubmluZyk7CglpZiAoY291bnRlci0+YXR0ci5yZWFkX2Zvcm1hdCAmIFBFUkZfRk9STUFUX0lEKQoJCXZhbHVlc1tuKytdID0gY291bnRlci0+aWQ7CgltdXRleF91bmxvY2soJmNvdW50ZXItPmNoaWxkX211dGV4KTsKCglpZiAoY291bnQgPCBuICogc2l6ZW9mKHU2NCkpCgkJcmV0dXJuIC1FSU5WQUw7Cgljb3VudCA9IG4gKiBzaXplb2YodTY0KTsKCglpZiAoY29weV90b191c2VyKGJ1ZiwgdmFsdWVzLCBjb3VudCkpCgkJcmV0dXJuIC1FRkFVTFQ7CgoJcmV0dXJuIGNvdW50Owp9CgpzdGF0aWMgc3NpemVfdApwZXJmX3JlYWQoc3RydWN0IGZpbGUgKmZpbGUsIGNoYXIgX191c2VyICpidWYsIHNpemVfdCBjb3VudCwgbG9mZl90ICpwcG9zKQp7CglzdHJ1Y3QgcGVyZl9jb3VudGVyICpjb3VudGVyID0gZmlsZS0+cHJpdmF0ZV9kYXRhOwoKCXJldHVybiBwZXJmX3JlYWRfaHcoY291bnRlciwgYnVmLCBjb3VudCk7Cn0KCnN0YXRpYyB1bnNpZ25lZCBpbnQgcGVyZl9wb2xsKHN0cnVjdCBmaWxlICpmaWxlLCBwb2xsX3RhYmxlICp3YWl0KQp7CglzdHJ1Y3QgcGVyZl9jb3VudGVyICpjb3VudGVyID0gZmlsZS0+cHJpdmF0ZV9kYXRhOwoJc3RydWN0IHBlcmZfbW1hcF9kYXRhICpkYXRhOwoJdW5zaWduZWQgaW50IGV2ZW50cyA9IFBPTExfSFVQOwoKCXJjdV9yZWFkX2xvY2soKTsKCWRhdGEgPSByY3VfZGVyZWZlcmVuY2UoY291bnRlci0+ZGF0YSk7CglpZiAoZGF0YSkKCQlldmVudHMgPSBhdG9taWNfeGNoZygmZGF0YS0+cG9sbCwgMCk7CglyY3VfcmVhZF91bmxvY2soKTsKCglwb2xsX3dhaXQoZmlsZSwgJmNvdW50ZXItPndhaXRxLCB3YWl0KTsKCglyZXR1cm4gZXZlbnRzOwp9CgpzdGF0aWMgdm9pZCBwZXJmX2NvdW50ZXJfcmVzZXQoc3RydWN0IHBlcmZfY291bnRlciAqY291bnRlcikKewoJKHZvaWQpcGVyZl9jb3VudGVyX3JlYWQoY291bnRlcik7CglhdG9taWM2NF9zZXQoJmNvdW50ZXItPmNvdW50LCAwKTsKCXBlcmZfY291bnRlcl91cGRhdGVfdXNlcnBhZ2UoY291bnRlcik7Cn0KCi8qCiAqIEhvbGRpbmcgdGhlIHRvcC1sZXZlbCBjb3VudGVyJ3MgY2hpbGRfbXV0ZXggbWVhbnMgdGhhdCBhbnkKICogZGVzY2VuZGFudCBwcm9jZXNzIHRoYXQgaGFzIGluaGVyaXRlZCB0aGlzIGNvdW50ZXIgd2lsbCBibG9jawogKiBpbiBzeW5jX2NoaWxkX2NvdW50ZXIgaWYgaXQgZ29lcyB0byBleGl0LCB0aHVzIHNhdGlzZnlpbmcgdGhlCiAqIHRhc2sgZXhpc3RlbmNlIHJlcXVpcmVtZW50cyBvZiBwZXJmX2NvdW50ZXJfZW5hYmxlL2Rpc2FibGUuCiAqLwpzdGF0aWMgdm9pZCBwZXJmX2NvdW50ZXJfZm9yX2VhY2hfY2hpbGQoc3RydWN0IHBlcmZfY291bnRlciAqY291bnRlciwKCQkJCQl2b2lkICgqZnVuYykoc3RydWN0IHBlcmZfY291bnRlciAqKSkKewoJc3RydWN0IHBlcmZfY291bnRlciAqY2hpbGQ7CgoJV0FSTl9PTl9PTkNFKGNvdW50ZXItPmN0eC0+cGFyZW50X2N0eCk7CgltdXRleF9sb2NrKCZjb3VudGVyLT5jaGlsZF9tdXRleCk7CglmdW5jKGNvdW50ZXIpOwoJbGlzdF9mb3JfZWFjaF9lbnRyeShjaGlsZCwgJmNvdW50ZXItPmNoaWxkX2xpc3QsIGNoaWxkX2xpc3QpCgkJZnVuYyhjaGlsZCk7CgltdXRleF91bmxvY2soJmNvdW50ZXItPmNoaWxkX211dGV4KTsKfQoKc3RhdGljIHZvaWQgcGVyZl9jb3VudGVyX2Zvcl9lYWNoKHN0cnVjdCBwZXJmX2NvdW50ZXIgKmNvdW50ZXIsCgkJCQkgIHZvaWQgKCpmdW5jKShzdHJ1Y3QgcGVyZl9jb3VudGVyICopKQp7CglzdHJ1Y3QgcGVyZl9jb3VudGVyX2NvbnRleHQgKmN0eCA9IGNvdW50ZXItPmN0eDsKCXN0cnVjdCBwZXJmX2NvdW50ZXIgKnNpYmxpbmc7CgoJV0FSTl9PTl9PTkNFKGN0eC0+cGFyZW50X2N0eCk7CgltdXRleF9sb2NrKCZjdHgtPm11dGV4KTsKCWNvdW50ZXIgPSBjb3VudGVyLT5ncm91cF9sZWFkZXI7CgoJcGVyZl9jb3VudGVyX2Zvcl9lYWNoX2NoaWxkKGNvdW50ZXIsIGZ1bmMpOwoJZnVuYyhjb3VudGVyKTsKCWxpc3RfZm9yX2VhY2hfZW50cnkoc2libGluZywgJmNvdW50ZXItPnNpYmxpbmdfbGlzdCwgbGlzdF9lbnRyeSkKCQlwZXJmX2NvdW50ZXJfZm9yX2VhY2hfY2hpbGQoY291bnRlciwgZnVuYyk7CgltdXRleF91bmxvY2soJmN0eC0+bXV0ZXgpOwp9CgpzdGF0aWMgaW50IHBlcmZfY291bnRlcl9wZXJpb2Qoc3RydWN0IHBlcmZfY291bnRlciAqY291bnRlciwgdTY0IF9fdXNlciAqYXJnKQp7CglzdHJ1Y3QgcGVyZl9jb3VudGVyX2NvbnRleHQgKmN0eCA9IGNvdW50ZXItPmN0eDsKCXVuc2lnbmVkIGxvbmcgc2l6ZTsKCWludCByZXQgPSAwOwoJdTY0IHZhbHVlOwoKCWlmICghY291bnRlci0+YXR0ci5zYW1wbGVfcGVyaW9kKQoJCXJldHVybiAtRUlOVkFMOwoKCXNpemUgPSBjb3B5X2Zyb21fdXNlcigmdmFsdWUsIGFyZywgc2l6ZW9mKHZhbHVlKSk7CglpZiAoc2l6ZSAhPSBzaXplb2YodmFsdWUpKQoJCXJldHVybiAtRUZBVUxUOwoKCWlmICghdmFsdWUpCgkJcmV0dXJuIC1FSU5WQUw7CgoJc3Bpbl9sb2NrX2lycSgmY3R4LT5sb2NrKTsKCWlmIChjb3VudGVyLT5hdHRyLmZyZXEpIHsKCQlpZiAodmFsdWUgPiBzeXNjdGxfcGVyZl9jb3VudGVyX3NhbXBsZV9yYXRlKSB7CgkJCXJldCA9IC1FSU5WQUw7CgkJCWdvdG8gdW5sb2NrOwoJCX0KCgkJY291bnRlci0+YXR0ci5zYW1wbGVfZnJlcSA9IHZhbHVlOwoJfSBlbHNlIHsKCQlwZXJmX2xvZ19wZXJpb2QoY291bnRlciwgdmFsdWUpOwoKCQljb3VudGVyLT5hdHRyLnNhbXBsZV9wZXJpb2QgPSB2YWx1ZTsKCQljb3VudGVyLT5ody5zYW1wbGVfcGVyaW9kID0gdmFsdWU7Cgl9CnVubG9jazoKCXNwaW5fdW5sb2NrX2lycSgmY3R4LT5sb2NrKTsKCglyZXR1cm4gcmV0Owp9CgpzdGF0aWMgbG9uZyBwZXJmX2lvY3RsKHN0cnVjdCBmaWxlICpmaWxlLCB1bnNpZ25lZCBpbnQgY21kLCB1bnNpZ25lZCBsb25nIGFyZykKewoJc3RydWN0IHBlcmZfY291bnRlciAqY291bnRlciA9IGZpbGUtPnByaXZhdGVfZGF0YTsKCXZvaWQgKCpmdW5jKShzdHJ1Y3QgcGVyZl9jb3VudGVyICopOwoJdTMyIGZsYWdzID0gYXJnOwoKCXN3aXRjaCAoY21kKSB7CgljYXNlIFBFUkZfQ09VTlRFUl9JT0NfRU5BQkxFOgoJCWZ1bmMgPSBwZXJmX2NvdW50ZXJfZW5hYmxlOwoJCWJyZWFrOwoJY2FzZSBQRVJGX0NPVU5URVJfSU9DX0RJU0FCTEU6CgkJZnVuYyA9IHBlcmZfY291bnRlcl9kaXNhYmxlOwoJCWJyZWFrOwoJY2FzZSBQRVJGX0NPVU5URVJfSU9DX1JFU0VUOgoJCWZ1bmMgPSBwZXJmX2NvdW50ZXJfcmVzZXQ7CgkJYnJlYWs7CgoJY2FzZSBQRVJGX0NPVU5URVJfSU9DX1JFRlJFU0g6CgkJcmV0dXJuIHBlcmZfY291bnRlcl9yZWZyZXNoKGNvdW50ZXIsIGFyZyk7CgoJY2FzZSBQRVJGX0NPVU5URVJfSU9DX1BFUklPRDoKCQlyZXR1cm4gcGVyZl9jb3VudGVyX3BlcmlvZChjb3VudGVyLCAodTY0IF9fdXNlciAqKWFyZyk7CgoJZGVmYXVsdDoKCQlyZXR1cm4gLUVOT1RUWTsKCX0KCglpZiAoZmxhZ3MgJiBQRVJGX0lPQ19GTEFHX0dST1VQKQoJCXBlcmZfY291bnRlcl9mb3JfZWFjaChjb3VudGVyLCBmdW5jKTsKCWVsc2UKCQlwZXJmX2NvdW50ZXJfZm9yX2VhY2hfY2hpbGQoY291bnRlciwgZnVuYyk7CgoJcmV0dXJuIDA7Cn0KCmludCBwZXJmX2NvdW50ZXJfdGFza19lbmFibGUodm9pZCkKewoJc3RydWN0IHBlcmZfY291bnRlciAqY291bnRlcjsKCgltdXRleF9sb2NrKCZjdXJyZW50LT5wZXJmX2NvdW50ZXJfbXV0ZXgpOwoJbGlzdF9mb3JfZWFjaF9lbnRyeShjb3VudGVyLCAmY3VycmVudC0+cGVyZl9jb3VudGVyX2xpc3QsIG93bmVyX2VudHJ5KQoJCXBlcmZfY291bnRlcl9mb3JfZWFjaF9jaGlsZChjb3VudGVyLCBwZXJmX2NvdW50ZXJfZW5hYmxlKTsKCW11dGV4X3VubG9jaygmY3VycmVudC0+cGVyZl9jb3VudGVyX211dGV4KTsKCglyZXR1cm4gMDsKfQoKaW50IHBlcmZfY291bnRlcl90YXNrX2Rpc2FibGUodm9pZCkKewoJc3RydWN0IHBlcmZfY291bnRlciAqY291bnRlcjsKCgltdXRleF9sb2NrKCZjdXJyZW50LT5wZXJmX2NvdW50ZXJfbXV0ZXgpOwoJbGlzdF9mb3JfZWFjaF9lbnRyeShjb3VudGVyLCAmY3VycmVudC0+cGVyZl9jb3VudGVyX2xpc3QsIG93bmVyX2VudHJ5KQoJCXBlcmZfY291bnRlcl9mb3JfZWFjaF9jaGlsZChjb3VudGVyLCBwZXJmX2NvdW50ZXJfZGlzYWJsZSk7CgltdXRleF91bmxvY2soJmN1cnJlbnQtPnBlcmZfY291bnRlcl9tdXRleCk7CgoJcmV0dXJuIDA7Cn0KCnN0YXRpYyBpbnQgcGVyZl9jb3VudGVyX2luZGV4KHN0cnVjdCBwZXJmX2NvdW50ZXIgKmNvdW50ZXIpCnsKCWlmIChjb3VudGVyLT5zdGF0ZSAhPSBQRVJGX0NPVU5URVJfU1RBVEVfQUNUSVZFKQoJCXJldHVybiAwOwoKCXJldHVybiBjb3VudGVyLT5ody5pZHggKyAxIC0gUEVSRl9DT1VOVEVSX0lOREVYX09GRlNFVDsKfQoKLyoKICogQ2FsbGVycyBuZWVkIHRvIGVuc3VyZSB0aGVyZSBjYW4gYmUgbm8gbmVzdGluZyBvZiB0aGlzIGZ1bmN0aW9uLCBvdGhlcndpc2UKICogdGhlIHNlcWxvY2sgbG9naWMgZ29lcyBiYWQuIFdlIGNhbiBub3Qgc2VyaWFsaXplIHRoaXMgYmVjYXVzZSB0aGUgYXJjaAogKiBjb2RlIGNhbGxzIHRoaXMgZnJvbSBOTUkgY29udGV4dC4KICovCnZvaWQgcGVyZl9jb3VudGVyX3VwZGF0ZV91c2VycGFnZShzdHJ1Y3QgcGVyZl9jb3VudGVyICpjb3VudGVyKQp7CglzdHJ1Y3QgcGVyZl9jb3VudGVyX21tYXBfcGFnZSAqdXNlcnBnOwoJc3RydWN0IHBlcmZfbW1hcF9kYXRhICpkYXRhOwoKCXJjdV9yZWFkX2xvY2soKTsKCWRhdGEgPSByY3VfZGVyZWZlcmVuY2UoY291bnRlci0+ZGF0YSk7CglpZiAoIWRhdGEpCgkJZ290byB1bmxvY2s7CgoJdXNlcnBnID0gZGF0YS0+dXNlcl9wYWdlOwoKCS8qCgkgKiBEaXNhYmxlIHByZWVtcHRpb24gc28gYXMgdG8gbm90IGxldCB0aGUgY29ycmVzcG9uZGluZyB1c2VyLXNwYWNlCgkgKiBzcGluIHRvbyBsb25nIGlmIHdlIGdldCBwcmVlbXB0ZWQuCgkgKi8KCXByZWVtcHRfZGlzYWJsZSgpOwoJKyt1c2VycGctPmxvY2s7CgliYXJyaWVyKCk7Cgl1c2VycGctPmluZGV4ID0gcGVyZl9jb3VudGVyX2luZGV4KGNvdW50ZXIpOwoJdXNlcnBnLT5vZmZzZXQgPSBhdG9taWM2NF9yZWFkKCZjb3VudGVyLT5jb3VudCk7CglpZiAoY291bnRlci0+c3RhdGUgPT0gUEVSRl9DT1VOVEVSX1NUQVRFX0FDVElWRSkKCQl1c2VycGctPm9mZnNldCAtPSBhdG9taWM2NF9yZWFkKCZjb3VudGVyLT5ody5wcmV2X2NvdW50KTsKCgl1c2VycGctPnRpbWVfZW5hYmxlZCA9IGNvdW50ZXItPnRvdGFsX3RpbWVfZW5hYmxlZCArCgkJCWF0b21pYzY0X3JlYWQoJmNvdW50ZXItPmNoaWxkX3RvdGFsX3RpbWVfZW5hYmxlZCk7CgoJdXNlcnBnLT50aW1lX3J1bm5pbmcgPSBjb3VudGVyLT50b3RhbF90aW1lX3J1bm5pbmcgKwoJCQlhdG9taWM2NF9yZWFkKCZjb3VudGVyLT5jaGlsZF90b3RhbF90aW1lX3J1bm5pbmcpOwoKCWJhcnJpZXIoKTsKCSsrdXNlcnBnLT5sb2NrOwoJcHJlZW1wdF9lbmFibGUoKTsKdW5sb2NrOgoJcmN1X3JlYWRfdW5sb2NrKCk7Cn0KCnN0YXRpYyBpbnQgcGVyZl9tbWFwX2ZhdWx0KHN0cnVjdCB2bV9hcmVhX3N0cnVjdCAqdm1hLCBzdHJ1Y3Qgdm1fZmF1bHQgKnZtZikKewoJc3RydWN0IHBlcmZfY291bnRlciAqY291bnRlciA9IHZtYS0+dm1fZmlsZS0+cHJpdmF0ZV9kYXRhOwoJc3RydWN0IHBlcmZfbW1hcF9kYXRhICpkYXRhOwoJaW50IHJldCA9IFZNX0ZBVUxUX1NJR0JVUzsKCglpZiAodm1mLT5mbGFncyAmIEZBVUxUX0ZMQUdfTUtXUklURSkgewoJCWlmICh2bWYtPnBnb2ZmID09IDApCgkJCXJldCA9IDA7CgkJcmV0dXJuIHJldDsKCX0KCglyY3VfcmVhZF9sb2NrKCk7CglkYXRhID0gcmN1X2RlcmVmZXJlbmNlKGNvdW50ZXItPmRhdGEpOwoJaWYgKCFkYXRhKQoJCWdvdG8gdW5sb2NrOwoKCWlmICh2bWYtPnBnb2ZmID09IDApIHsKCQl2bWYtPnBhZ2UgPSB2aXJ0X3RvX3BhZ2UoZGF0YS0+dXNlcl9wYWdlKTsKCX0gZWxzZSB7CgkJaW50IG5yID0gdm1mLT5wZ29mZiAtIDE7CgoJCWlmICgodW5zaWduZWQpbnIgPiBkYXRhLT5ucl9wYWdlcykKCQkJZ290byB1bmxvY2s7CgoJCWlmICh2bWYtPmZsYWdzICYgRkFVTFRfRkxBR19XUklURSkKCQkJZ290byB1bmxvY2s7CgoJCXZtZi0+cGFnZSA9IHZpcnRfdG9fcGFnZShkYXRhLT5kYXRhX3BhZ2VzW25yXSk7Cgl9CgoJZ2V0X3BhZ2Uodm1mLT5wYWdlKTsKCXZtZi0+cGFnZS0+bWFwcGluZyA9IHZtYS0+dm1fZmlsZS0+Zl9tYXBwaW5nOwoJdm1mLT5wYWdlLT5pbmRleCAgID0gdm1mLT5wZ29mZjsKCglyZXQgPSAwOwp1bmxvY2s6CglyY3VfcmVhZF91bmxvY2soKTsKCglyZXR1cm4gcmV0Owp9CgpzdGF0aWMgaW50IHBlcmZfbW1hcF9kYXRhX2FsbG9jKHN0cnVjdCBwZXJmX2NvdW50ZXIgKmNvdW50ZXIsIGludCBucl9wYWdlcykKewoJc3RydWN0IHBlcmZfbW1hcF9kYXRhICpkYXRhOwoJdW5zaWduZWQgbG9uZyBzaXplOwoJaW50IGk7CgoJV0FSTl9PTihhdG9taWNfcmVhZCgmY291bnRlci0+bW1hcF9jb3VudCkpOwoKCXNpemUgPSBzaXplb2Yoc3RydWN0IHBlcmZfbW1hcF9kYXRhKTsKCXNpemUgKz0gbnJfcGFnZXMgKiBzaXplb2Yodm9pZCAqKTsKCglkYXRhID0ga3phbGxvYyhzaXplLCBHRlBfS0VSTkVMKTsKCWlmICghZGF0YSkKCQlnb3RvIGZhaWw7CgoJZGF0YS0+dXNlcl9wYWdlID0gKHZvaWQgKilnZXRfemVyb2VkX3BhZ2UoR0ZQX0tFUk5FTCk7CglpZiAoIWRhdGEtPnVzZXJfcGFnZSkKCQlnb3RvIGZhaWxfdXNlcl9wYWdlOwoKCWZvciAoaSA9IDA7IGkgPCBucl9wYWdlczsgaSsrKSB7CgkJZGF0YS0+ZGF0YV9wYWdlc1tpXSA9ICh2b2lkICopZ2V0X3plcm9lZF9wYWdlKEdGUF9LRVJORUwpOwoJCWlmICghZGF0YS0+ZGF0YV9wYWdlc1tpXSkKCQkJZ290byBmYWlsX2RhdGFfcGFnZXM7Cgl9CgoJZGF0YS0+bnJfcGFnZXMgPSBucl9wYWdlczsKCWF0b21pY19zZXQoJmRhdGEtPmxvY2ssIC0xKTsKCglyY3VfYXNzaWduX3BvaW50ZXIoY291bnRlci0+ZGF0YSwgZGF0YSk7CgoJcmV0dXJuIDA7CgpmYWlsX2RhdGFfcGFnZXM6Cglmb3IgKGktLTsgaSA+PSAwOyBpLS0pCgkJZnJlZV9wYWdlKCh1bnNpZ25lZCBsb25nKWRhdGEtPmRhdGFfcGFnZXNbaV0pOwoKCWZyZWVfcGFnZSgodW5zaWduZWQgbG9uZylkYXRhLT51c2VyX3BhZ2UpOwoKZmFpbF91c2VyX3BhZ2U6CglrZnJlZShkYXRhKTsKCmZhaWw6CglyZXR1cm4gLUVOT01FTTsKfQoKc3RhdGljIHZvaWQgcGVyZl9tbWFwX2ZyZWVfcGFnZSh1bnNpZ25lZCBsb25nIGFkZHIpCnsKCXN0cnVjdCBwYWdlICpwYWdlID0gdmlydF90b19wYWdlKCh2b2lkICopYWRkcik7CgoJcGFnZS0+bWFwcGluZyA9IE5VTEw7CglfX2ZyZWVfcGFnZShwYWdlKTsKfQoKc3RhdGljIHZvaWQgX19wZXJmX21tYXBfZGF0YV9mcmVlKHN0cnVjdCByY3VfaGVhZCAqcmN1X2hlYWQpCnsKCXN0cnVjdCBwZXJmX21tYXBfZGF0YSAqZGF0YTsKCWludCBpOwoKCWRhdGEgPSBjb250YWluZXJfb2YocmN1X2hlYWQsIHN0cnVjdCBwZXJmX21tYXBfZGF0YSwgcmN1X2hlYWQpOwoKCXBlcmZfbW1hcF9mcmVlX3BhZ2UoKHVuc2lnbmVkIGxvbmcpZGF0YS0+dXNlcl9wYWdlKTsKCWZvciAoaSA9IDA7IGkgPCBkYXRhLT5ucl9wYWdlczsgaSsrKQoJCXBlcmZfbW1hcF9mcmVlX3BhZ2UoKHVuc2lnbmVkIGxvbmcpZGF0YS0+ZGF0YV9wYWdlc1tpXSk7CgoJa2ZyZWUoZGF0YSk7Cn0KCnN0YXRpYyB2b2lkIHBlcmZfbW1hcF9kYXRhX2ZyZWUoc3RydWN0IHBlcmZfY291bnRlciAqY291bnRlcikKewoJc3RydWN0IHBlcmZfbW1hcF9kYXRhICpkYXRhID0gY291bnRlci0+ZGF0YTsKCglXQVJOX09OKGF0b21pY19yZWFkKCZjb3VudGVyLT5tbWFwX2NvdW50KSk7CgoJcmN1X2Fzc2lnbl9wb2ludGVyKGNvdW50ZXItPmRhdGEsIE5VTEwpOwoJY2FsbF9yY3UoJmRhdGEtPnJjdV9oZWFkLCBfX3BlcmZfbW1hcF9kYXRhX2ZyZWUpOwp9CgpzdGF0aWMgdm9pZCBwZXJmX21tYXBfb3BlbihzdHJ1Y3Qgdm1fYXJlYV9zdHJ1Y3QgKnZtYSkKewoJc3RydWN0IHBlcmZfY291bnRlciAqY291bnRlciA9IHZtYS0+dm1fZmlsZS0+cHJpdmF0ZV9kYXRhOwoKCWF0b21pY19pbmMoJmNvdW50ZXItPm1tYXBfY291bnQpOwp9CgpzdGF0aWMgdm9pZCBwZXJmX21tYXBfY2xvc2Uoc3RydWN0IHZtX2FyZWFfc3RydWN0ICp2bWEpCnsKCXN0cnVjdCBwZXJmX2NvdW50ZXIgKmNvdW50ZXIgPSB2bWEtPnZtX2ZpbGUtPnByaXZhdGVfZGF0YTsKCglXQVJOX09OX09OQ0UoY291bnRlci0+Y3R4LT5wYXJlbnRfY3R4KTsKCWlmIChhdG9taWNfZGVjX2FuZF9tdXRleF9sb2NrKCZjb3VudGVyLT5tbWFwX2NvdW50LCAmY291bnRlci0+bW1hcF9tdXRleCkpIHsKCQlzdHJ1Y3QgdXNlcl9zdHJ1Y3QgKnVzZXIgPSBjdXJyZW50X3VzZXIoKTsKCgkJYXRvbWljX2xvbmdfc3ViKGNvdW50ZXItPmRhdGEtPm5yX3BhZ2VzICsgMSwgJnVzZXItPmxvY2tlZF92bSk7CgkJdm1hLT52bV9tbS0+bG9ja2VkX3ZtIC09IGNvdW50ZXItPmRhdGEtPm5yX2xvY2tlZDsKCQlwZXJmX21tYXBfZGF0YV9mcmVlKGNvdW50ZXIpOwoJCW11dGV4X3VubG9jaygmY291bnRlci0+bW1hcF9tdXRleCk7Cgl9Cn0KCnN0YXRpYyBzdHJ1Y3Qgdm1fb3BlcmF0aW9uc19zdHJ1Y3QgcGVyZl9tbWFwX3Ztb3BzID0gewoJLm9wZW4JCT0gcGVyZl9tbWFwX29wZW4sCgkuY2xvc2UJCT0gcGVyZl9tbWFwX2Nsb3NlLAoJLmZhdWx0CQk9IHBlcmZfbW1hcF9mYXVsdCwKCS5wYWdlX21rd3JpdGUJPSBwZXJmX21tYXBfZmF1bHQsCn07CgpzdGF0aWMgaW50IHBlcmZfbW1hcChzdHJ1Y3QgZmlsZSAqZmlsZSwgc3RydWN0IHZtX2FyZWFfc3RydWN0ICp2bWEpCnsKCXN0cnVjdCBwZXJmX2NvdW50ZXIgKmNvdW50ZXIgPSBmaWxlLT5wcml2YXRlX2RhdGE7Cgl1bnNpZ25lZCBsb25nIHVzZXJfbG9ja2VkLCB1c2VyX2xvY2tfbGltaXQ7CglzdHJ1Y3QgdXNlcl9zdHJ1Y3QgKnVzZXIgPSBjdXJyZW50X3VzZXIoKTsKCXVuc2lnbmVkIGxvbmcgbG9ja2VkLCBsb2NrX2xpbWl0OwoJdW5zaWduZWQgbG9uZyB2bWFfc2l6ZTsKCXVuc2lnbmVkIGxvbmcgbnJfcGFnZXM7Cglsb25nIHVzZXJfZXh0cmEsIGV4dHJhOwoJaW50IHJldCA9IDA7CgoJaWYgKCEodm1hLT52bV9mbGFncyAmIFZNX1NIQVJFRCkpCgkJcmV0dXJuIC1FSU5WQUw7CgoJdm1hX3NpemUgPSB2bWEtPnZtX2VuZCAtIHZtYS0+dm1fc3RhcnQ7Cglucl9wYWdlcyA9ICh2bWFfc2l6ZSAvIFBBR0VfU0laRSkgLSAxOwoKCS8qCgkgKiBJZiB3ZSBoYXZlIGRhdGEgcGFnZXMgZW5zdXJlIHRoZXkncmUgYSBwb3dlci1vZi10d28gbnVtYmVyLCBzbyB3ZQoJICogY2FuIGRvIGJpdG1hc2tzIGluc3RlYWQgb2YgbW9kdWxvLgoJICovCglpZiAobnJfcGFnZXMgIT0gMCAmJiAhaXNfcG93ZXJfb2ZfMihucl9wYWdlcykpCgkJcmV0dXJuIC1FSU5WQUw7CgoJaWYgKHZtYV9zaXplICE9IFBBR0VfU0laRSAqICgxICsgbnJfcGFnZXMpKQoJCXJldHVybiAtRUlOVkFMOwoKCWlmICh2bWEtPnZtX3Bnb2ZmICE9IDApCgkJcmV0dXJuIC1FSU5WQUw7CgoJV0FSTl9PTl9PTkNFKGNvdW50ZXItPmN0eC0+cGFyZW50X2N0eCk7CgltdXRleF9sb2NrKCZjb3VudGVyLT5tbWFwX211dGV4KTsKCWlmIChhdG9taWNfaW5jX25vdF96ZXJvKCZjb3VudGVyLT5tbWFwX2NvdW50KSkgewoJCWlmIChucl9wYWdlcyAhPSBjb3VudGVyLT5kYXRhLT5ucl9wYWdlcykKCQkJcmV0ID0gLUVJTlZBTDsKCQlnb3RvIHVubG9jazsKCX0KCgl1c2VyX2V4dHJhID0gbnJfcGFnZXMgKyAxOwoJdXNlcl9sb2NrX2xpbWl0ID0gc3lzY3RsX3BlcmZfY291bnRlcl9tbG9jayA+PiAoUEFHRV9TSElGVCAtIDEwKTsKCgkvKgoJICogSW5jcmVhc2UgdGhlIGxpbWl0IGxpbmVhcmx5IHdpdGggbW9yZSBDUFVzOgoJICovCgl1c2VyX2xvY2tfbGltaXQgKj0gbnVtX29ubGluZV9jcHVzKCk7CgoJdXNlcl9sb2NrZWQgPSBhdG9taWNfbG9uZ19yZWFkKCZ1c2VyLT5sb2NrZWRfdm0pICsgdXNlcl9leHRyYTsKCglleHRyYSA9IDA7CglpZiAodXNlcl9sb2NrZWQgPiB1c2VyX2xvY2tfbGltaXQpCgkJZXh0cmEgPSB1c2VyX2xvY2tlZCAtIHVzZXJfbG9ja19saW1pdDsKCglsb2NrX2xpbWl0ID0gY3VycmVudC0+c2lnbmFsLT5ybGltW1JMSU1JVF9NRU1MT0NLXS5ybGltX2N1cjsKCWxvY2tfbGltaXQgPj49IFBBR0VfU0hJRlQ7Cglsb2NrZWQgPSB2bWEtPnZtX21tLT5sb2NrZWRfdm0gKyBleHRyYTsKCglpZiAoKGxvY2tlZCA+IGxvY2tfbGltaXQpICYmICFjYXBhYmxlKENBUF9JUENfTE9DSykpIHsKCQlyZXQgPSAtRVBFUk07CgkJZ290byB1bmxvY2s7Cgl9CgoJV0FSTl9PTihjb3VudGVyLT5kYXRhKTsKCXJldCA9IHBlcmZfbW1hcF9kYXRhX2FsbG9jKGNvdW50ZXIsIG5yX3BhZ2VzKTsKCWlmIChyZXQpCgkJZ290byB1bmxvY2s7CgoJYXRvbWljX3NldCgmY291bnRlci0+bW1hcF9jb3VudCwgMSk7CglhdG9taWNfbG9uZ19hZGQodXNlcl9leHRyYSwgJnVzZXItPmxvY2tlZF92bSk7Cgl2bWEtPnZtX21tLT5sb2NrZWRfdm0gKz0gZXh0cmE7Cgljb3VudGVyLT5kYXRhLT5ucl9sb2NrZWQgPSBleHRyYTsKCWlmICh2bWEtPnZtX2ZsYWdzICYgVk1fV1JJVEUpCgkJY291bnRlci0+ZGF0YS0+d3JpdGFibGUgPSAxOwoKdW5sb2NrOgoJbXV0ZXhfdW5sb2NrKCZjb3VudGVyLT5tbWFwX211dGV4KTsKCgl2bWEtPnZtX2ZsYWdzIHw9IFZNX1JFU0VSVkVEOwoJdm1hLT52bV9vcHMgPSAmcGVyZl9tbWFwX3Ztb3BzOwoKCXJldHVybiByZXQ7Cn0KCnN0YXRpYyBpbnQgcGVyZl9mYXN5bmMoaW50IGZkLCBzdHJ1Y3QgZmlsZSAqZmlscCwgaW50IG9uKQp7CglzdHJ1Y3QgaW5vZGUgKmlub2RlID0gZmlscC0+Zl9wYXRoLmRlbnRyeS0+ZF9pbm9kZTsKCXN0cnVjdCBwZXJmX2NvdW50ZXIgKmNvdW50ZXIgPSBmaWxwLT5wcml2YXRlX2RhdGE7CglpbnQgcmV0dmFsOwoKCW11dGV4X2xvY2soJmlub2RlLT5pX211dGV4KTsKCXJldHZhbCA9IGZhc3luY19oZWxwZXIoZmQsIGZpbHAsIG9uLCAmY291bnRlci0+ZmFzeW5jKTsKCW11dGV4X3VubG9jaygmaW5vZGUtPmlfbXV0ZXgpOwoKCWlmIChyZXR2YWwgPCAwKQoJCXJldHVybiByZXR2YWw7CgoJcmV0dXJuIDA7Cn0KCnN0YXRpYyBjb25zdCBzdHJ1Y3QgZmlsZV9vcGVyYXRpb25zIHBlcmZfZm9wcyA9IHsKCS5yZWxlYXNlCQk9IHBlcmZfcmVsZWFzZSwKCS5yZWFkCQkJPSBwZXJmX3JlYWQsCgkucG9sbAkJCT0gcGVyZl9wb2xsLAoJLnVubG9ja2VkX2lvY3RsCQk9IHBlcmZfaW9jdGwsCgkuY29tcGF0X2lvY3RsCQk9IHBlcmZfaW9jdGwsCgkubW1hcAkJCT0gcGVyZl9tbWFwLAoJLmZhc3luYwkJCT0gcGVyZl9mYXN5bmMsCn07CgovKgogKiBQZXJmIGNvdW50ZXIgd2FrZXVwCiAqCiAqIElmIHRoZXJlJ3MgZGF0YSwgZW5zdXJlIHdlIHNldCB0aGUgcG9sbCgpIHN0YXRlIGFuZCBwdWJsaXNoIGV2ZXJ5dGhpbmcKICogdG8gdXNlci1zcGFjZSBiZWZvcmUgd2FraW5nIGV2ZXJ5Ym9keSB1cC4KICovCgp2b2lkIHBlcmZfY291bnRlcl93YWtldXAoc3RydWN0IHBlcmZfY291bnRlciAqY291bnRlcikKewoJd2FrZV91cF9hbGwoJmNvdW50ZXItPndhaXRxKTsKCglpZiAoY291bnRlci0+cGVuZGluZ19raWxsKSB7CgkJa2lsbF9mYXN5bmMoJmNvdW50ZXItPmZhc3luYywgU0lHSU8sIGNvdW50ZXItPnBlbmRpbmdfa2lsbCk7CgkJY291bnRlci0+cGVuZGluZ19raWxsID0gMDsKCX0KfQoKLyoKICogUGVuZGluZyB3YWtldXBzCiAqCiAqIEhhbmRsZSB0aGUgY2FzZSB3aGVyZSB3ZSBuZWVkIHRvIHdha2V1cCB1cCBmcm9tIE5NSSAob3IgcnEtPmxvY2spIGNvbnRleHQuCiAqCiAqIFRoZSBOTUkgYml0IG1lYW5zIHdlIGNhbm5vdCBwb3NzaWJseSB0YWtlIGxvY2tzLiBUaGVyZWZvcmUsIG1haW50YWluIGEKICogc2luZ2xlIGxpbmtlZCBsaXN0IGFuZCB1c2UgY21weGNoZygpIHRvIGFkZCBlbnRyaWVzIGxvY2tsZXNzLgogKi8KCnN0YXRpYyB2b2lkIHBlcmZfcGVuZGluZ19jb3VudGVyKHN0cnVjdCBwZXJmX3BlbmRpbmdfZW50cnkgKmVudHJ5KQp7CglzdHJ1Y3QgcGVyZl9jb3VudGVyICpjb3VudGVyID0gY29udGFpbmVyX29mKGVudHJ5LAoJCQlzdHJ1Y3QgcGVyZl9jb3VudGVyLCBwZW5kaW5nKTsKCglpZiAoY291bnRlci0+cGVuZGluZ19kaXNhYmxlKSB7CgkJY291bnRlci0+cGVuZGluZ19kaXNhYmxlID0gMDsKCQlwZXJmX2NvdW50ZXJfZGlzYWJsZShjb3VudGVyKTsKCX0KCglpZiAoY291bnRlci0+cGVuZGluZ193YWtldXApIHsKCQljb3VudGVyLT5wZW5kaW5nX3dha2V1cCA9IDA7CgkJcGVyZl9jb3VudGVyX3dha2V1cChjb3VudGVyKTsKCX0KfQoKI2RlZmluZSBQRU5ESU5HX1RBSUwgKChzdHJ1Y3QgcGVyZl9wZW5kaW5nX2VudHJ5ICopLTFVTCkKCnN0YXRpYyBERUZJTkVfUEVSX0NQVShzdHJ1Y3QgcGVyZl9wZW5kaW5nX2VudHJ5ICosIHBlcmZfcGVuZGluZ19oZWFkKSA9IHsKCVBFTkRJTkdfVEFJTCwKfTsKCnN0YXRpYyB2b2lkIHBlcmZfcGVuZGluZ19xdWV1ZShzdHJ1Y3QgcGVyZl9wZW5kaW5nX2VudHJ5ICplbnRyeSwKCQkJICAgICAgIHZvaWQgKCpmdW5jKShzdHJ1Y3QgcGVyZl9wZW5kaW5nX2VudHJ5ICopKQp7CglzdHJ1Y3QgcGVyZl9wZW5kaW5nX2VudHJ5ICoqaGVhZDsKCglpZiAoY21weGNoZygmZW50cnktPm5leHQsIE5VTEwsIFBFTkRJTkdfVEFJTCkgIT0gTlVMTCkKCQlyZXR1cm47CgoJZW50cnktPmZ1bmMgPSBmdW5jOwoKCWhlYWQgPSAmZ2V0X2NwdV92YXIocGVyZl9wZW5kaW5nX2hlYWQpOwoKCWRvIHsKCQllbnRyeS0+bmV4dCA9ICpoZWFkOwoJfSB3aGlsZSAoY21weGNoZyhoZWFkLCBlbnRyeS0+bmV4dCwgZW50cnkpICE9IGVudHJ5LT5uZXh0KTsKCglzZXRfcGVyZl9jb3VudGVyX3BlbmRpbmcoKTsKCglwdXRfY3B1X3ZhcihwZXJmX3BlbmRpbmdfaGVhZCk7Cn0KCnN0YXRpYyBpbnQgX19wZXJmX3BlbmRpbmdfcnVuKHZvaWQpCnsKCXN0cnVjdCBwZXJmX3BlbmRpbmdfZW50cnkgKmxpc3Q7CglpbnQgbnIgPSAwOwoKCWxpc3QgPSB4Y2hnKCZfX2dldF9jcHVfdmFyKHBlcmZfcGVuZGluZ19oZWFkKSwgUEVORElOR19UQUlMKTsKCXdoaWxlIChsaXN0ICE9IFBFTkRJTkdfVEFJTCkgewoJCXZvaWQgKCpmdW5jKShzdHJ1Y3QgcGVyZl9wZW5kaW5nX2VudHJ5ICopOwoJCXN0cnVjdCBwZXJmX3BlbmRpbmdfZW50cnkgKmVudHJ5ID0gbGlzdDsKCgkJbGlzdCA9IGxpc3QtPm5leHQ7CgoJCWZ1bmMgPSBlbnRyeS0+ZnVuYzsKCQllbnRyeS0+bmV4dCA9IE5VTEw7CgkJLyoKCQkgKiBFbnN1cmUgd2Ugb2JzZXJ2ZSB0aGUgdW5xdWV1ZSBiZWZvcmUgd2UgaXNzdWUgdGhlIHdha2V1cCwKCQkgKiBzbyB0aGF0IHdlIHdvbid0IGJlIHdhaXRpbmcgZm9yZXZlci4KCQkgKiAtLSBzZWUgcGVyZl9ub3RfcGVuZGluZygpLgoJCSAqLwoJCXNtcF93bWIoKTsKCgkJZnVuYyhlbnRyeSk7CgkJbnIrKzsKCX0KCglyZXR1cm4gbnI7Cn0KCnN0YXRpYyBpbmxpbmUgaW50IHBlcmZfbm90X3BlbmRpbmcoc3RydWN0IHBlcmZfY291bnRlciAqY291bnRlcikKewoJLyoKCSAqIElmIHdlIGZsdXNoIG9uIHdoYXRldmVyIGNwdSB3ZSBydW4sIHRoZXJlIGlzIGEgY2hhbmNlIHdlIGRvbid0CgkgKiBuZWVkIHRvIHdhaXQuCgkgKi8KCWdldF9jcHUoKTsKCV9fcGVyZl9wZW5kaW5nX3J1bigpOwoJcHV0X2NwdSgpOwoKCS8qCgkgKiBFbnN1cmUgd2Ugc2VlIHRoZSBwcm9wZXIgcXVldWUgc3RhdGUgYmVmb3JlIGdvaW5nIHRvIHNsZWVwCgkgKiBzbyB0aGF0IHdlIGRvIG5vdCBtaXNzIHRoZSB3YWtldXAuIC0tIHNlZSBwZXJmX3BlbmRpbmdfaGFuZGxlKCkKCSAqLwoJc21wX3JtYigpOwoJcmV0dXJuIGNvdW50ZXItPnBlbmRpbmcubmV4dCA9PSBOVUxMOwp9CgpzdGF0aWMgdm9pZCBwZXJmX3BlbmRpbmdfc3luYyhzdHJ1Y3QgcGVyZl9jb3VudGVyICpjb3VudGVyKQp7Cgl3YWl0X2V2ZW50KGNvdW50ZXItPndhaXRxLCBwZXJmX25vdF9wZW5kaW5nKGNvdW50ZXIpKTsKfQoKdm9pZCBwZXJmX2NvdW50ZXJfZG9fcGVuZGluZyh2b2lkKQp7CglfX3BlcmZfcGVuZGluZ19ydW4oKTsKfQoKLyoKICogQ2FsbGNoYWluIHN1cHBvcnQgLS0gYXJjaCBzcGVjaWZpYwogKi8KCl9fd2VhayBzdHJ1Y3QgcGVyZl9jYWxsY2hhaW5fZW50cnkgKnBlcmZfY2FsbGNoYWluKHN0cnVjdCBwdF9yZWdzICpyZWdzKQp7CglyZXR1cm4gTlVMTDsKfQoKLyoKICogT3V0cHV0CiAqLwoKc3RydWN0IHBlcmZfb3V0cHV0X2hhbmRsZSB7CglzdHJ1Y3QgcGVyZl9jb3VudGVyCSpjb3VudGVyOwoJc3RydWN0IHBlcmZfbW1hcF9kYXRhCSpkYXRhOwoJdW5zaWduZWQgbG9uZwkJaGVhZDsKCXVuc2lnbmVkIGxvbmcJCW9mZnNldDsKCWludAkJCW5taTsKCWludAkJCXNhbXBsZTsKCWludAkJCWxvY2tlZDsKCXVuc2lnbmVkIGxvbmcJCWZsYWdzOwp9OwoKc3RhdGljIGJvb2wgcGVyZl9vdXRwdXRfc3BhY2Uoc3RydWN0IHBlcmZfbW1hcF9kYXRhICpkYXRhLAoJCQkgICAgICB1bnNpZ25lZCBpbnQgb2Zmc2V0LCB1bnNpZ25lZCBpbnQgaGVhZCkKewoJdW5zaWduZWQgbG9uZyB0YWlsOwoJdW5zaWduZWQgbG9uZyBtYXNrOwoKCWlmICghZGF0YS0+d3JpdGFibGUpCgkJcmV0dXJuIHRydWU7CgoJbWFzayA9IChkYXRhLT5ucl9wYWdlcyA8PCBQQUdFX1NISUZUKSAtIDE7CgkvKgoJICogVXNlcnNwYWNlIGNvdWxkIGNob29zZSB0byBpc3N1ZSBhIG1iKCkgYmVmb3JlIHVwZGF0aW5nIHRoZSB0YWlsCgkgKiBwb2ludGVyLiBTbyB0aGF0IGFsbCByZWFkcyB3aWxsIGJlIGNvbXBsZXRlZCBiZWZvcmUgdGhlIHdyaXRlIGlzCgkgKiBpc3N1ZWQuCgkgKi8KCXRhaWwgPSBBQ0NFU1NfT05DRShkYXRhLT51c2VyX3BhZ2UtPmRhdGFfdGFpbCk7CglzbXBfcm1iKCk7CgoJb2Zmc2V0ID0gKG9mZnNldCAtIHRhaWwpICYgbWFzazsKCWhlYWQgICA9IChoZWFkICAgLSB0YWlsKSAmIG1hc2s7CgoJaWYgKChpbnQpKGhlYWQgLSBvZmZzZXQpIDwgMCkKCQlyZXR1cm4gZmFsc2U7CgoJcmV0dXJuIHRydWU7Cn0KCnN0YXRpYyB2b2lkIHBlcmZfb3V0cHV0X3dha2V1cChzdHJ1Y3QgcGVyZl9vdXRwdXRfaGFuZGxlICpoYW5kbGUpCnsKCWF0b21pY19zZXQoJmhhbmRsZS0+ZGF0YS0+cG9sbCwgUE9MTF9JTik7CgoJaWYgKGhhbmRsZS0+bm1pKSB7CgkJaGFuZGxlLT5jb3VudGVyLT5wZW5kaW5nX3dha2V1cCA9IDE7CgkJcGVyZl9wZW5kaW5nX3F1ZXVlKCZoYW5kbGUtPmNvdW50ZXItPnBlbmRpbmcsCgkJCQkgICBwZXJmX3BlbmRpbmdfY291bnRlcik7Cgl9IGVsc2UKCQlwZXJmX2NvdW50ZXJfd2FrZXVwKGhhbmRsZS0+Y291bnRlcik7Cn0KCi8qCiAqIEN1cmlvdXMgbG9ja2luZyBjb25zdHJ1Y3QuCiAqCiAqIFdlIG5lZWQgdG8gZW5zdXJlIGEgbGF0ZXIgZXZlbnQgZG9lc24ndCBwdWJsaXNoIGEgaGVhZCB3aGVuIGEgZm9ybWVyCiAqIGV2ZW50IGlzbid0IGRvbmUgd3JpdGluZy4gSG93ZXZlciBzaW5jZSB3ZSBuZWVkIHRvIGRlYWwgd2l0aCBOTUlzIHdlCiAqIGNhbm5vdCBmdWxseSBzZXJpYWxpemUgdGhpbmdzLgogKgogKiBXaGF0IHdlIGRvIGlzIHNlcmlhbGl6ZSBiZXR3ZWVuIENQVXMgc28gd2Ugb25seSBoYXZlIHRvIGRlYWwgd2l0aCBOTUkKICogbmVzdGluZyBvbiBhIHNpbmdsZSBDUFUuCiAqCiAqIFdlIG9ubHkgcHVibGlzaCB0aGUgaGVhZCAoYW5kIGdlbmVyYXRlIGEgd2FrZXVwKSB3aGVuIHRoZSBvdXRlci1tb3N0CiAqIGV2ZW50IGNvbXBsZXRlcy4KICovCnN0YXRpYyB2b2lkIHBlcmZfb3V0cHV0X2xvY2soc3RydWN0IHBlcmZfb3V0cHV0X2hhbmRsZSAqaGFuZGxlKQp7CglzdHJ1Y3QgcGVyZl9tbWFwX2RhdGEgKmRhdGEgPSBoYW5kbGUtPmRhdGE7CglpbnQgY3B1OwoKCWhhbmRsZS0+bG9ja2VkID0gMDsKCglsb2NhbF9pcnFfc2F2ZShoYW5kbGUtPmZsYWdzKTsKCWNwdSA9IHNtcF9wcm9jZXNzb3JfaWQoKTsKCglpZiAoaW5fbm1pKCkgJiYgYXRvbWljX3JlYWQoJmRhdGEtPmxvY2spID09IGNwdSkKCQlyZXR1cm47CgoJd2hpbGUgKGF0b21pY19jbXB4Y2hnKCZkYXRhLT5sb2NrLCAtMSwgY3B1KSAhPSAtMSkKCQljcHVfcmVsYXgoKTsKCgloYW5kbGUtPmxvY2tlZCA9IDE7Cn0KCnN0YXRpYyB2b2lkIHBlcmZfb3V0cHV0X3VubG9jayhzdHJ1Y3QgcGVyZl9vdXRwdXRfaGFuZGxlICpoYW5kbGUpCnsKCXN0cnVjdCBwZXJmX21tYXBfZGF0YSAqZGF0YSA9IGhhbmRsZS0+ZGF0YTsKCXVuc2lnbmVkIGxvbmcgaGVhZDsKCWludCBjcHU7CgoJZGF0YS0+ZG9uZV9oZWFkID0gZGF0YS0+aGVhZDsKCglpZiAoIWhhbmRsZS0+bG9ja2VkKQoJCWdvdG8gb3V0OwoKYWdhaW46CgkvKgoJICogVGhlIHhjaGcgaW1wbGllcyBhIGZ1bGwgYmFycmllciB0aGF0IGVuc3VyZXMgYWxsIHdyaXRlcyBhcmUgZG9uZQoJICogYmVmb3JlIHdlIHB1Ymxpc2ggdGhlIG5ldyBoZWFkLCBtYXRjaGVkIGJ5IGEgcm1iKCkgaW4gdXNlcnNwYWNlIHdoZW4KCSAqIHJlYWRpbmcgdGhpcyBwb3NpdGlvbi4KCSAqLwoJd2hpbGUgKChoZWFkID0gYXRvbWljX2xvbmdfeGNoZygmZGF0YS0+ZG9uZV9oZWFkLCAwKSkpCgkJZGF0YS0+dXNlcl9wYWdlLT5kYXRhX2hlYWQgPSBoZWFkOwoKCS8qCgkgKiBOTUkgY2FuIGhhcHBlbiBoZXJlLCB3aGljaCBtZWFucyB3ZSBjYW4gbWlzcyBhIGRvbmVfaGVhZCB1cGRhdGUuCgkgKi8KCgljcHUgPSBhdG9taWNfeGNoZygmZGF0YS0+bG9jaywgLTEpOwoJV0FSTl9PTl9PTkNFKGNwdSAhPSBzbXBfcHJvY2Vzc29yX2lkKCkpOwoKCS8qCgkgKiBUaGVyZWZvcmUgd2UgaGF2ZSB0byB2YWxpZGF0ZSB3ZSBkaWQgbm90IGluZGVlZCBkbyBzby4KCSAqLwoJaWYgKHVubGlrZWx5KGF0b21pY19sb25nX3JlYWQoJmRhdGEtPmRvbmVfaGVhZCkpKSB7CgkJLyoKCQkgKiBTaW5jZSB3ZSBoYWQgaXQgbG9ja2VkLCB3ZSBjYW4gbG9jayBpdCBhZ2Fpbi4KCQkgKi8KCQl3aGlsZSAoYXRvbWljX2NtcHhjaGcoJmRhdGEtPmxvY2ssIC0xLCBjcHUpICE9IC0xKQoJCQljcHVfcmVsYXgoKTsKCgkJZ290byBhZ2FpbjsKCX0KCglpZiAoYXRvbWljX3hjaGcoJmRhdGEtPndha2V1cCwgMCkpCgkJcGVyZl9vdXRwdXRfd2FrZXVwKGhhbmRsZSk7Cm91dDoKCWxvY2FsX2lycV9yZXN0b3JlKGhhbmRsZS0+ZmxhZ3MpOwp9CgpzdGF0aWMgdm9pZCBwZXJmX291dHB1dF9jb3B5KHN0cnVjdCBwZXJmX291dHB1dF9oYW5kbGUgKmhhbmRsZSwKCQkJICAgICBjb25zdCB2b2lkICpidWYsIHVuc2lnbmVkIGludCBsZW4pCnsKCXVuc2lnbmVkIGludCBwYWdlc19tYXNrOwoJdW5zaWduZWQgaW50IG9mZnNldDsKCXVuc2lnbmVkIGludCBzaXplOwoJdm9pZCAqKnBhZ2VzOwoKCW9mZnNldAkJPSBoYW5kbGUtPm9mZnNldDsKCXBhZ2VzX21hc2sJPSBoYW5kbGUtPmRhdGEtPm5yX3BhZ2VzIC0gMTsKCXBhZ2VzCQk9IGhhbmRsZS0+ZGF0YS0+ZGF0YV9wYWdlczsKCglkbyB7CgkJdW5zaWduZWQgaW50IHBhZ2Vfb2Zmc2V0OwoJCWludCBucjsKCgkJbnIJICAgID0gKG9mZnNldCA+PiBQQUdFX1NISUZUKSAmIHBhZ2VzX21hc2s7CgkJcGFnZV9vZmZzZXQgPSBvZmZzZXQgJiAoUEFHRV9TSVpFIC0gMSk7CgkJc2l6ZQkgICAgPSBtaW5fdCh1bnNpZ25lZCBpbnQsIFBBR0VfU0laRSAtIHBhZ2Vfb2Zmc2V0LCBsZW4pOwoKCQltZW1jcHkocGFnZXNbbnJdICsgcGFnZV9vZmZzZXQsIGJ1Ziwgc2l6ZSk7CgoJCWxlbgkgICAgLT0gc2l6ZTsKCQlidWYJICAgICs9IHNpemU7CgkJb2Zmc2V0CSAgICArPSBzaXplOwoJfSB3aGlsZSAobGVuKTsKCgloYW5kbGUtPm9mZnNldCA9IG9mZnNldDsKCgkvKgoJICogQ2hlY2sgd2UgZGlkbid0IGNvcHkgcGFzdCBvdXIgcmVzZXJ2YXRpb24gd2luZG93LCB0YWtpbmcgdGhlCgkgKiBwb3NzaWJsZSB1bnNpZ25lZCBpbnQgd3JhcCBpbnRvIGFjY291bnQuCgkgKi8KCVdBUk5fT05fT05DRSgoKGxvbmcpKGhhbmRsZS0+aGVhZCAtIGhhbmRsZS0+b2Zmc2V0KSkgPCAwKTsKfQoKI2RlZmluZSBwZXJmX291dHB1dF9wdXQoaGFuZGxlLCB4KSBcCglwZXJmX291dHB1dF9jb3B5KChoYW5kbGUpLCAmKHgpLCBzaXplb2YoeCkpCgpzdGF0aWMgaW50IHBlcmZfb3V0cHV0X2JlZ2luKHN0cnVjdCBwZXJmX291dHB1dF9oYW5kbGUgKmhhbmRsZSwKCQkJICAgICBzdHJ1Y3QgcGVyZl9jb3VudGVyICpjb3VudGVyLCB1bnNpZ25lZCBpbnQgc2l6ZSwKCQkJICAgICBpbnQgbm1pLCBpbnQgc2FtcGxlKQp7CglzdHJ1Y3QgcGVyZl9tbWFwX2RhdGEgKmRhdGE7Cgl1bnNpZ25lZCBpbnQgb2Zmc2V0LCBoZWFkOwoJaW50IGhhdmVfbG9zdDsKCXN0cnVjdCB7CgkJc3RydWN0IHBlcmZfZXZlbnRfaGVhZGVyIGhlYWRlcjsKCQl1NjQJCQkgaWQ7CgkJdTY0CQkJIGxvc3Q7Cgl9IGxvc3RfZXZlbnQ7CgoJLyoKCSAqIEZvciBpbmhlcml0ZWQgY291bnRlcnMgd2Ugc2VuZCBhbGwgdGhlIG91dHB1dCB0b3dhcmRzIHRoZSBwYXJlbnQuCgkgKi8KCWlmIChjb3VudGVyLT5wYXJlbnQpCgkJY291bnRlciA9IGNvdW50ZXItPnBhcmVudDsKCglyY3VfcmVhZF9sb2NrKCk7CglkYXRhID0gcmN1X2RlcmVmZXJlbmNlKGNvdW50ZXItPmRhdGEpOwoJaWYgKCFkYXRhKQoJCWdvdG8gb3V0OwoKCWhhbmRsZS0+ZGF0YQk9IGRhdGE7CgloYW5kbGUtPmNvdW50ZXIJPSBjb3VudGVyOwoJaGFuZGxlLT5ubWkJPSBubWk7CgloYW5kbGUtPnNhbXBsZQk9IHNhbXBsZTsKCglpZiAoIWRhdGEtPm5yX3BhZ2VzKQoJCWdvdG8gZmFpbDsKCgloYXZlX2xvc3QgPSBhdG9taWNfcmVhZCgmZGF0YS0+bG9zdCk7CglpZiAoaGF2ZV9sb3N0KQoJCXNpemUgKz0gc2l6ZW9mKGxvc3RfZXZlbnQpOwoKCXBlcmZfb3V0cHV0X2xvY2soaGFuZGxlKTsKCglkbyB7CgkJb2Zmc2V0ID0gaGVhZCA9IGF0b21pY19sb25nX3JlYWQoJmRhdGEtPmhlYWQpOwoJCWhlYWQgKz0gc2l6ZTsKCQlpZiAodW5saWtlbHkoIXBlcmZfb3V0cHV0X3NwYWNlKGRhdGEsIG9mZnNldCwgaGVhZCkpKQoJCQlnb3RvIGZhaWw7Cgl9IHdoaWxlIChhdG9taWNfbG9uZ19jbXB4Y2hnKCZkYXRhLT5oZWFkLCBvZmZzZXQsIGhlYWQpICE9IG9mZnNldCk7CgoJaGFuZGxlLT5vZmZzZXQJPSBvZmZzZXQ7CgloYW5kbGUtPmhlYWQJPSBoZWFkOwoKCWlmICgob2Zmc2V0ID4+IFBBR0VfU0hJRlQpICE9IChoZWFkID4+IFBBR0VfU0hJRlQpKQoJCWF0b21pY19zZXQoJmRhdGEtPndha2V1cCwgMSk7CgoJaWYgKGhhdmVfbG9zdCkgewoJCWxvc3RfZXZlbnQuaGVhZGVyLnR5cGUgPSBQRVJGX0VWRU5UX0xPU1Q7CgkJbG9zdF9ldmVudC5oZWFkZXIubWlzYyA9IDA7CgkJbG9zdF9ldmVudC5oZWFkZXIuc2l6ZSA9IHNpemVvZihsb3N0X2V2ZW50KTsKCQlsb3N0X2V2ZW50LmlkICAgICAgICAgID0gY291bnRlci0+aWQ7CgkJbG9zdF9ldmVudC5sb3N0ICAgICAgICA9IGF0b21pY194Y2hnKCZkYXRhLT5sb3N0LCAwKTsKCgkJcGVyZl9vdXRwdXRfcHV0KGhhbmRsZSwgbG9zdF9ldmVudCk7Cgl9CgoJcmV0dXJuIDA7CgpmYWlsOgoJYXRvbWljX2luYygmZGF0YS0+bG9zdCk7CglwZXJmX291dHB1dF91bmxvY2soaGFuZGxlKTsKb3V0OgoJcmN1X3JlYWRfdW5sb2NrKCk7CgoJcmV0dXJuIC1FTk9TUEM7Cn0KCnN0YXRpYyB2b2lkIHBlcmZfb3V0cHV0X2VuZChzdHJ1Y3QgcGVyZl9vdXRwdXRfaGFuZGxlICpoYW5kbGUpCnsKCXN0cnVjdCBwZXJmX2NvdW50ZXIgKmNvdW50ZXIgPSBoYW5kbGUtPmNvdW50ZXI7CglzdHJ1Y3QgcGVyZl9tbWFwX2RhdGEgKmRhdGEgPSBoYW5kbGUtPmRhdGE7CgoJaW50IHdha2V1cF9ldmVudHMgPSBjb3VudGVyLT5hdHRyLndha2V1cF9ldmVudHM7CgoJaWYgKGhhbmRsZS0+c2FtcGxlICYmIHdha2V1cF9ldmVudHMpIHsKCQlpbnQgZXZlbnRzID0gYXRvbWljX2luY19yZXR1cm4oJmRhdGEtPmV2ZW50cyk7CgkJaWYgKGV2ZW50cyA+PSB3YWtldXBfZXZlbnRzKSB7CgkJCWF0b21pY19zdWIod2FrZXVwX2V2ZW50cywgJmRhdGEtPmV2ZW50cyk7CgkJCWF0b21pY19zZXQoJmRhdGEtPndha2V1cCwgMSk7CgkJfQoJfQoKCXBlcmZfb3V0cHV0X3VubG9jayhoYW5kbGUpOwoJcmN1X3JlYWRfdW5sb2NrKCk7Cn0KCnN0YXRpYyB1MzIgcGVyZl9jb3VudGVyX3BpZChzdHJ1Y3QgcGVyZl9jb3VudGVyICpjb3VudGVyLCBzdHJ1Y3QgdGFza19zdHJ1Y3QgKnApCnsKCS8qCgkgKiBvbmx5IHRvcCBsZXZlbCBjb3VudGVycyBoYXZlIHRoZSBwaWQgbmFtZXNwYWNlIHRoZXkgd2VyZSBjcmVhdGVkIGluCgkgKi8KCWlmIChjb3VudGVyLT5wYXJlbnQpCgkJY291bnRlciA9IGNvdW50ZXItPnBhcmVudDsKCglyZXR1cm4gdGFza190Z2lkX25yX25zKHAsIGNvdW50ZXItPm5zKTsKfQoKc3RhdGljIHUzMiBwZXJmX2NvdW50ZXJfdGlkKHN0cnVjdCBwZXJmX2NvdW50ZXIgKmNvdW50ZXIsIHN0cnVjdCB0YXNrX3N0cnVjdCAqcCkKewoJLyoKCSAqIG9ubHkgdG9wIGxldmVsIGNvdW50ZXJzIGhhdmUgdGhlIHBpZCBuYW1lc3BhY2UgdGhleSB3ZXJlIGNyZWF0ZWQgaW4KCSAqLwoJaWYgKGNvdW50ZXItPnBhcmVudCkKCQljb3VudGVyID0gY291bnRlci0+cGFyZW50OwoKCXJldHVybiB0YXNrX3BpZF9ucl9ucyhwLCBjb3VudGVyLT5ucyk7Cn0KCnN0YXRpYyB2b2lkIHBlcmZfY291bnRlcl9vdXRwdXQoc3RydWN0IHBlcmZfY291bnRlciAqY291bnRlciwgaW50IG5taSwKCQkJCXN0cnVjdCBwZXJmX3NhbXBsZV9kYXRhICpkYXRhKQp7CglpbnQgcmV0OwoJdTY0IHNhbXBsZV90eXBlID0gY291bnRlci0+YXR0ci5zYW1wbGVfdHlwZTsKCXN0cnVjdCBwZXJmX291dHB1dF9oYW5kbGUgaGFuZGxlOwoJc3RydWN0IHBlcmZfZXZlbnRfaGVhZGVyIGhlYWRlcjsKCXU2NCBpcDsKCXN0cnVjdCB7CgkJdTMyIHBpZCwgdGlkOwoJfSB0aWRfZW50cnk7CglzdHJ1Y3QgewoJCXU2NCBpZDsKCQl1NjQgY291bnRlcjsKCX0gZ3JvdXBfZW50cnk7CglzdHJ1Y3QgcGVyZl9jYWxsY2hhaW5fZW50cnkgKmNhbGxjaGFpbiA9IE5VTEw7CglpbnQgY2FsbGNoYWluX3NpemUgPSAwOwoJdTY0IHRpbWU7CglzdHJ1Y3QgewoJCXUzMiBjcHUsIHJlc2VydmVkOwoJfSBjcHVfZW50cnk7CgoJaGVhZGVyLnR5cGUgPSBQRVJGX0VWRU5UX1NBTVBMRTsKCWhlYWRlci5zaXplID0gc2l6ZW9mKGhlYWRlcik7CgoJaGVhZGVyLm1pc2MgPSAwOwoJaGVhZGVyLm1pc2MgfD0gcGVyZl9taXNjX2ZsYWdzKGRhdGEtPnJlZ3MpOwoKCWlmIChzYW1wbGVfdHlwZSAmIFBFUkZfU0FNUExFX0lQKSB7CgkJaXAgPSBwZXJmX2luc3RydWN0aW9uX3BvaW50ZXIoZGF0YS0+cmVncyk7CgkJaGVhZGVyLnNpemUgKz0gc2l6ZW9mKGlwKTsKCX0KCglpZiAoc2FtcGxlX3R5cGUgJiBQRVJGX1NBTVBMRV9USUQpIHsKCQkvKiBuYW1lc3BhY2UgaXNzdWVzICovCgkJdGlkX2VudHJ5LnBpZCA9IHBlcmZfY291bnRlcl9waWQoY291bnRlciwgY3VycmVudCk7CgkJdGlkX2VudHJ5LnRpZCA9IHBlcmZfY291bnRlcl90aWQoY291bnRlciwgY3VycmVudCk7CgoJCWhlYWRlci5zaXplICs9IHNpemVvZih0aWRfZW50cnkpOwoJfQoKCWlmIChzYW1wbGVfdHlwZSAmIFBFUkZfU0FNUExFX1RJTUUpIHsKCQkvKgoJCSAqIE1heWJlIGRvIGJldHRlciBvbiB4ODYgYW5kIHByb3ZpZGUgY3B1X2Nsb2NrX25taSgpCgkJICovCgkJdGltZSA9IHNjaGVkX2Nsb2NrKCk7CgoJCWhlYWRlci5zaXplICs9IHNpemVvZih1NjQpOwoJfQoKCWlmIChzYW1wbGVfdHlwZSAmIFBFUkZfU0FNUExFX0FERFIpCgkJaGVhZGVyLnNpemUgKz0gc2l6ZW9mKHU2NCk7CgoJaWYgKHNhbXBsZV90eXBlICYgUEVSRl9TQU1QTEVfSUQpCgkJaGVhZGVyLnNpemUgKz0gc2l6ZW9mKHU2NCk7CgoJaWYgKHNhbXBsZV90eXBlICYgUEVSRl9TQU1QTEVfQ1BVKSB7CgkJaGVhZGVyLnNpemUgKz0gc2l6ZW9mKGNwdV9lbnRyeSk7CgoJCWNwdV9lbnRyeS5jcHUgPSByYXdfc21wX3Byb2Nlc3Nvcl9pZCgpOwoJfQoKCWlmIChzYW1wbGVfdHlwZSAmIFBFUkZfU0FNUExFX1BFUklPRCkKCQloZWFkZXIuc2l6ZSArPSBzaXplb2YodTY0KTsKCglpZiAoc2FtcGxlX3R5cGUgJiBQRVJGX1NBTVBMRV9HUk9VUCkgewoJCWhlYWRlci5zaXplICs9IHNpemVvZih1NjQpICsKCQkJY291bnRlci0+bnJfc2libGluZ3MgKiBzaXplb2YoZ3JvdXBfZW50cnkpOwoJfQoKCWlmIChzYW1wbGVfdHlwZSAmIFBFUkZfU0FNUExFX0NBTExDSEFJTikgewoJCWNhbGxjaGFpbiA9IHBlcmZfY2FsbGNoYWluKGRhdGEtPnJlZ3MpOwoKCQlpZiAoY2FsbGNoYWluKSB7CgkJCWNhbGxjaGFpbl9zaXplID0gKDEgKyBjYWxsY2hhaW4tPm5yKSAqIHNpemVvZih1NjQpOwoJCQloZWFkZXIuc2l6ZSArPSBjYWxsY2hhaW5fc2l6ZTsKCQl9IGVsc2UKCQkJaGVhZGVyLnNpemUgKz0gc2l6ZW9mKHU2NCk7Cgl9CgoJcmV0ID0gcGVyZl9vdXRwdXRfYmVnaW4oJmhhbmRsZSwgY291bnRlciwgaGVhZGVyLnNpemUsIG5taSwgMSk7CglpZiAocmV0KQoJCXJldHVybjsKCglwZXJmX291dHB1dF9wdXQoJmhhbmRsZSwgaGVhZGVyKTsKCglpZiAoc2FtcGxlX3R5cGUgJiBQRVJGX1NBTVBMRV9JUCkKCQlwZXJmX291dHB1dF9wdXQoJmhhbmRsZSwgaXApOwoKCWlmIChzYW1wbGVfdHlwZSAmIFBFUkZfU0FNUExFX1RJRCkKCQlwZXJmX291dHB1dF9wdXQoJmhhbmRsZSwgdGlkX2VudHJ5KTsKCglpZiAoc2FtcGxlX3R5cGUgJiBQRVJGX1NBTVBMRV9USU1FKQoJCXBlcmZfb3V0cHV0X3B1dCgmaGFuZGxlLCB0aW1lKTsKCglpZiAoc2FtcGxlX3R5cGUgJiBQRVJGX1NBTVBMRV9BRERSKQoJCXBlcmZfb3V0cHV0X3B1dCgmaGFuZGxlLCBkYXRhLT5hZGRyKTsKCglpZiAoc2FtcGxlX3R5cGUgJiBQRVJGX1NBTVBMRV9JRCkKCQlwZXJmX291dHB1dF9wdXQoJmhhbmRsZSwgY291bnRlci0+aWQpOwoKCWlmIChzYW1wbGVfdHlwZSAmIFBFUkZfU0FNUExFX0NQVSkKCQlwZXJmX291dHB1dF9wdXQoJmhhbmRsZSwgY3B1X2VudHJ5KTsKCglpZiAoc2FtcGxlX3R5cGUgJiBQRVJGX1NBTVBMRV9QRVJJT0QpCgkJcGVyZl9vdXRwdXRfcHV0KCZoYW5kbGUsIGRhdGEtPnBlcmlvZCk7CgoJLyoKCSAqIFhYWCBQRVJGX1NBTVBMRV9HUk9VUCB2cyBpbmhlcml0ZWQgY291bnRlcnMgc2VlbXMgZGlmZmljdWx0LgoJICovCglpZiAoc2FtcGxlX3R5cGUgJiBQRVJGX1NBTVBMRV9HUk9VUCkgewoJCXN0cnVjdCBwZXJmX2NvdW50ZXIgKmxlYWRlciwgKnN1YjsKCQl1NjQgbnIgPSBjb3VudGVyLT5ucl9zaWJsaW5nczsKCgkJcGVyZl9vdXRwdXRfcHV0KCZoYW5kbGUsIG5yKTsKCgkJbGVhZGVyID0gY291bnRlci0+Z3JvdXBfbGVhZGVyOwoJCWxpc3RfZm9yX2VhY2hfZW50cnkoc3ViLCAmbGVhZGVyLT5zaWJsaW5nX2xpc3QsIGxpc3RfZW50cnkpIHsKCQkJaWYgKHN1YiAhPSBjb3VudGVyKQoJCQkJc3ViLT5wbXUtPnJlYWQoc3ViKTsKCgkJCWdyb3VwX2VudHJ5LmlkID0gc3ViLT5pZDsKCQkJZ3JvdXBfZW50cnkuY291bnRlciA9IGF0b21pYzY0X3JlYWQoJnN1Yi0+Y291bnQpOwoKCQkJcGVyZl9vdXRwdXRfcHV0KCZoYW5kbGUsIGdyb3VwX2VudHJ5KTsKCQl9Cgl9CgoJaWYgKHNhbXBsZV90eXBlICYgUEVSRl9TQU1QTEVfQ0FMTENIQUlOKSB7CgkJaWYgKGNhbGxjaGFpbikKCQkJcGVyZl9vdXRwdXRfY29weSgmaGFuZGxlLCBjYWxsY2hhaW4sIGNhbGxjaGFpbl9zaXplKTsKCQllbHNlIHsKCQkJdTY0IG5yID0gMDsKCQkJcGVyZl9vdXRwdXRfcHV0KCZoYW5kbGUsIG5yKTsKCQl9Cgl9CgoJcGVyZl9vdXRwdXRfZW5kKCZoYW5kbGUpOwp9CgovKgogKiByZWFkIGV2ZW50CiAqLwoKc3RydWN0IHBlcmZfcmVhZF9ldmVudCB7CglzdHJ1Y3QgcGVyZl9ldmVudF9oZWFkZXIJaGVhZGVyOwoKCXUzMgkJCQlwaWQ7Cgl1MzIJCQkJdGlkOwoJdTY0CQkJCXZhbHVlOwoJdTY0CQkJCWZvcm1hdFszXTsKfTsKCnN0YXRpYyB2b2lkCnBlcmZfY291bnRlcl9yZWFkX2V2ZW50KHN0cnVjdCBwZXJmX2NvdW50ZXIgKmNvdW50ZXIsCgkJCXN0cnVjdCB0YXNrX3N0cnVjdCAqdGFzaykKewoJc3RydWN0IHBlcmZfb3V0cHV0X2hhbmRsZSBoYW5kbGU7CglzdHJ1Y3QgcGVyZl9yZWFkX2V2ZW50IGV2ZW50ID0gewoJCS5oZWFkZXIgPSB7CgkJCS50eXBlID0gUEVSRl9FVkVOVF9SRUFELAoJCQkubWlzYyA9IDAsCgkJCS5zaXplID0gc2l6ZW9mKGV2ZW50KSAtIHNpemVvZihldmVudC5mb3JtYXQpLAoJCX0sCgkJLnBpZCA9IHBlcmZfY291bnRlcl9waWQoY291bnRlciwgdGFzayksCgkJLnRpZCA9IHBlcmZfY291bnRlcl90aWQoY291bnRlciwgdGFzayksCgkJLnZhbHVlID0gYXRvbWljNjRfcmVhZCgmY291bnRlci0+Y291bnQpLAoJfTsKCWludCByZXQsIGkgPSAwOwoKCWlmIChjb3VudGVyLT5hdHRyLnJlYWRfZm9ybWF0ICYgUEVSRl9GT1JNQVRfVE9UQUxfVElNRV9FTkFCTEVEKSB7CgkJZXZlbnQuaGVhZGVyLnNpemUgKz0gc2l6ZW9mKHU2NCk7CgkJZXZlbnQuZm9ybWF0W2krK10gPSBjb3VudGVyLT50b3RhbF90aW1lX2VuYWJsZWQ7Cgl9CgoJaWYgKGNvdW50ZXItPmF0dHIucmVhZF9mb3JtYXQgJiBQRVJGX0ZPUk1BVF9UT1RBTF9USU1FX1JVTk5JTkcpIHsKCQlldmVudC5oZWFkZXIuc2l6ZSArPSBzaXplb2YodTY0KTsKCQlldmVudC5mb3JtYXRbaSsrXSA9IGNvdW50ZXItPnRvdGFsX3RpbWVfcnVubmluZzsKCX0KCglpZiAoY291bnRlci0+YXR0ci5yZWFkX2Zvcm1hdCAmIFBFUkZfRk9STUFUX0lEKSB7CgkJdTY0IGlkOwoKCQlldmVudC5oZWFkZXIuc2l6ZSArPSBzaXplb2YodTY0KTsKCQlpZiAoY291bnRlci0+cGFyZW50KQoJCQlpZCA9IGNvdW50ZXItPnBhcmVudC0+aWQ7CgkJZWxzZQoJCQlpZCA9IGNvdW50ZXItPmlkOwoKCQlldmVudC5mb3JtYXRbaSsrXSA9IGlkOwoJfQoKCXJldCA9IHBlcmZfb3V0cHV0X2JlZ2luKCZoYW5kbGUsIGNvdW50ZXIsIGV2ZW50LmhlYWRlci5zaXplLCAwLCAwKTsKCWlmIChyZXQpCgkJcmV0dXJuOwoKCXBlcmZfb3V0cHV0X2NvcHkoJmhhbmRsZSwgJmV2ZW50LCBldmVudC5oZWFkZXIuc2l6ZSk7CglwZXJmX291dHB1dF9lbmQoJmhhbmRsZSk7Cn0KCi8qCiAqIGZvcmsgdHJhY2tpbmcKICovCgpzdHJ1Y3QgcGVyZl9mb3JrX2V2ZW50IHsKCXN0cnVjdCB0YXNrX3N0cnVjdAkqdGFzazsKCglzdHJ1Y3QgewoJCXN0cnVjdCBwZXJmX2V2ZW50X2hlYWRlcgloZWFkZXI7CgoJCXUzMgkJCQlwaWQ7CgkJdTMyCQkJCXBwaWQ7Cgl9IGV2ZW50Owp9OwoKc3RhdGljIHZvaWQgcGVyZl9jb3VudGVyX2Zvcmtfb3V0cHV0KHN0cnVjdCBwZXJmX2NvdW50ZXIgKmNvdW50ZXIsCgkJCQkgICAgIHN0cnVjdCBwZXJmX2ZvcmtfZXZlbnQgKmZvcmtfZXZlbnQpCnsKCXN0cnVjdCBwZXJmX291dHB1dF9oYW5kbGUgaGFuZGxlOwoJaW50IHNpemUgPSBmb3JrX2V2ZW50LT5ldmVudC5oZWFkZXIuc2l6ZTsKCXN0cnVjdCB0YXNrX3N0cnVjdCAqdGFzayA9IGZvcmtfZXZlbnQtPnRhc2s7CglpbnQgcmV0ID0gcGVyZl9vdXRwdXRfYmVnaW4oJmhhbmRsZSwgY291bnRlciwgc2l6ZSwgMCwgMCk7CgoJaWYgKHJldCkKCQlyZXR1cm47CgoJZm9ya19ldmVudC0+ZXZlbnQucGlkID0gcGVyZl9jb3VudGVyX3BpZChjb3VudGVyLCB0YXNrKTsKCWZvcmtfZXZlbnQtPmV2ZW50LnBwaWQgPSBwZXJmX2NvdW50ZXJfcGlkKGNvdW50ZXIsIHRhc2stPnJlYWxfcGFyZW50KTsKCglwZXJmX291dHB1dF9wdXQoJmhhbmRsZSwgZm9ya19ldmVudC0+ZXZlbnQpOwoJcGVyZl9vdXRwdXRfZW5kKCZoYW5kbGUpOwp9CgpzdGF0aWMgaW50IHBlcmZfY291bnRlcl9mb3JrX21hdGNoKHN0cnVjdCBwZXJmX2NvdW50ZXIgKmNvdW50ZXIpCnsKCWlmIChjb3VudGVyLT5hdHRyLmNvbW0gfHwgY291bnRlci0+YXR0ci5tbWFwKQoJCXJldHVybiAxOwoKCXJldHVybiAwOwp9CgpzdGF0aWMgdm9pZCBwZXJmX2NvdW50ZXJfZm9ya19jdHgoc3RydWN0IHBlcmZfY291bnRlcl9jb250ZXh0ICpjdHgsCgkJCQkgIHN0cnVjdCBwZXJmX2ZvcmtfZXZlbnQgKmZvcmtfZXZlbnQpCnsKCXN0cnVjdCBwZXJmX2NvdW50ZXIgKmNvdW50ZXI7CgoJaWYgKHN5c3RlbV9zdGF0ZSAhPSBTWVNURU1fUlVOTklORyB8fCBsaXN0X2VtcHR5KCZjdHgtPmV2ZW50X2xpc3QpKQoJCXJldHVybjsKCglyY3VfcmVhZF9sb2NrKCk7CglsaXN0X2Zvcl9lYWNoX2VudHJ5X3JjdShjb3VudGVyLCAmY3R4LT5ldmVudF9saXN0LCBldmVudF9lbnRyeSkgewoJCWlmIChwZXJmX2NvdW50ZXJfZm9ya19tYXRjaChjb3VudGVyKSkKCQkJcGVyZl9jb3VudGVyX2Zvcmtfb3V0cHV0KGNvdW50ZXIsIGZvcmtfZXZlbnQpOwoJfQoJcmN1X3JlYWRfdW5sb2NrKCk7Cn0KCnN0YXRpYyB2b2lkIHBlcmZfY291bnRlcl9mb3JrX2V2ZW50KHN0cnVjdCBwZXJmX2ZvcmtfZXZlbnQgKmZvcmtfZXZlbnQpCnsKCXN0cnVjdCBwZXJmX2NwdV9jb250ZXh0ICpjcHVjdHg7CglzdHJ1Y3QgcGVyZl9jb3VudGVyX2NvbnRleHQgKmN0eDsKCgljcHVjdHggPSAmZ2V0X2NwdV92YXIocGVyZl9jcHVfY29udGV4dCk7CglwZXJmX2NvdW50ZXJfZm9ya19jdHgoJmNwdWN0eC0+Y3R4LCBmb3JrX2V2ZW50KTsKCXB1dF9jcHVfdmFyKHBlcmZfY3B1X2NvbnRleHQpOwoKCXJjdV9yZWFkX2xvY2soKTsKCS8qCgkgKiBkb2Vzbid0IHJlYWxseSBtYXR0ZXIgd2hpY2ggb2YgdGhlIGNoaWxkIGNvbnRleHRzIHRoZQoJICogZXZlbnRzIGVuZHMgdXAgaW4uCgkgKi8KCWN0eCA9IHJjdV9kZXJlZmVyZW5jZShjdXJyZW50LT5wZXJmX2NvdW50ZXJfY3R4cCk7CglpZiAoY3R4KQoJCXBlcmZfY291bnRlcl9mb3JrX2N0eChjdHgsIGZvcmtfZXZlbnQpOwoJcmN1X3JlYWRfdW5sb2NrKCk7Cn0KCnZvaWQgcGVyZl9jb3VudGVyX2Zvcmsoc3RydWN0IHRhc2tfc3RydWN0ICp0YXNrKQp7CglzdHJ1Y3QgcGVyZl9mb3JrX2V2ZW50IGZvcmtfZXZlbnQ7CgoJaWYgKCFhdG9taWNfcmVhZCgmbnJfY29tbV9jb3VudGVycykgJiYKCSAgICAhYXRvbWljX3JlYWQoJm5yX21tYXBfY291bnRlcnMpKQoJCXJldHVybjsKCglmb3JrX2V2ZW50ID0gKHN0cnVjdCBwZXJmX2ZvcmtfZXZlbnQpewoJCS50YXNrCT0gdGFzaywKCQkuZXZlbnQgID0gewoJCQkuaGVhZGVyID0gewoJCQkJLnR5cGUgPSBQRVJGX0VWRU5UX0ZPUkssCgkJCQkuc2l6ZSA9IHNpemVvZihmb3JrX2V2ZW50LmV2ZW50KSwKCQkJfSwKCQl9LAoJfTsKCglwZXJmX2NvdW50ZXJfZm9ya19ldmVudCgmZm9ya19ldmVudCk7Cn0KCi8qCiAqIGNvbW0gdHJhY2tpbmcKICovCgpzdHJ1Y3QgcGVyZl9jb21tX2V2ZW50IHsKCXN0cnVjdCB0YXNrX3N0cnVjdAkqdGFzazsKCWNoYXIJCQkqY29tbTsKCWludAkJCWNvbW1fc2l6ZTsKCglzdHJ1Y3QgewoJCXN0cnVjdCBwZXJmX2V2ZW50X2hlYWRlcgloZWFkZXI7CgoJCXUzMgkJCQlwaWQ7CgkJdTMyCQkJCXRpZDsKCX0gZXZlbnQ7Cn07CgpzdGF0aWMgdm9pZCBwZXJmX2NvdW50ZXJfY29tbV9vdXRwdXQoc3RydWN0IHBlcmZfY291bnRlciAqY291bnRlciwKCQkJCSAgICAgc3RydWN0IHBlcmZfY29tbV9ldmVudCAqY29tbV9ldmVudCkKewoJc3RydWN0IHBlcmZfb3V0cHV0X2hhbmRsZSBoYW5kbGU7CglpbnQgc2l6ZSA9IGNvbW1fZXZlbnQtPmV2ZW50LmhlYWRlci5zaXplOwoJaW50IHJldCA9IHBlcmZfb3V0cHV0X2JlZ2luKCZoYW5kbGUsIGNvdW50ZXIsIHNpemUsIDAsIDApOwoKCWlmIChyZXQpCgkJcmV0dXJuOwoKCWNvbW1fZXZlbnQtPmV2ZW50LnBpZCA9IHBlcmZfY291bnRlcl9waWQoY291bnRlciwgY29tbV9ldmVudC0+dGFzayk7Cgljb21tX2V2ZW50LT5ldmVudC50aWQgPSBwZXJmX2NvdW50ZXJfdGlkKGNvdW50ZXIsIGNvbW1fZXZlbnQtPnRhc2spOwoKCXBlcmZfb3V0cHV0X3B1dCgmaGFuZGxlLCBjb21tX2V2ZW50LT5ldmVudCk7CglwZXJmX291dHB1dF9jb3B5KCZoYW5kbGUsIGNvbW1fZXZlbnQtPmNvbW0sCgkJCQkgICBjb21tX2V2ZW50LT5jb21tX3NpemUpOwoJcGVyZl9vdXRwdXRfZW5kKCZoYW5kbGUpOwp9CgpzdGF0aWMgaW50IHBlcmZfY291bnRlcl9jb21tX21hdGNoKHN0cnVjdCBwZXJmX2NvdW50ZXIgKmNvdW50ZXIpCnsKCWlmIChjb3VudGVyLT5hdHRyLmNvbW0pCgkJcmV0dXJuIDE7CgoJcmV0dXJuIDA7Cn0KCnN0YXRpYyB2b2lkIHBlcmZfY291bnRlcl9jb21tX2N0eChzdHJ1Y3QgcGVyZl9jb3VudGVyX2NvbnRleHQgKmN0eCwKCQkJCSAgc3RydWN0IHBlcmZfY29tbV9ldmVudCAqY29tbV9ldmVudCkKewoJc3RydWN0IHBlcmZfY291bnRlciAqY291bnRlcjsKCglpZiAoc3lzdGVtX3N0YXRlICE9IFNZU1RFTV9SVU5OSU5HIHx8IGxpc3RfZW1wdHkoJmN0eC0+ZXZlbnRfbGlzdCkpCgkJcmV0dXJuOwoKCXJjdV9yZWFkX2xvY2soKTsKCWxpc3RfZm9yX2VhY2hfZW50cnlfcmN1KGNvdW50ZXIsICZjdHgtPmV2ZW50X2xpc3QsIGV2ZW50X2VudHJ5KSB7CgkJaWYgKHBlcmZfY291bnRlcl9jb21tX21hdGNoKGNvdW50ZXIpKQoJCQlwZXJmX2NvdW50ZXJfY29tbV9vdXRwdXQoY291bnRlciwgY29tbV9ldmVudCk7Cgl9CglyY3VfcmVhZF91bmxvY2soKTsKfQoKc3RhdGljIHZvaWQgcGVyZl9jb3VudGVyX2NvbW1fZXZlbnQoc3RydWN0IHBlcmZfY29tbV9ldmVudCAqY29tbV9ldmVudCkKewoJc3RydWN0IHBlcmZfY3B1X2NvbnRleHQgKmNwdWN0eDsKCXN0cnVjdCBwZXJmX2NvdW50ZXJfY29udGV4dCAqY3R4OwoJdW5zaWduZWQgaW50IHNpemU7CgljaGFyICpjb21tID0gY29tbV9ldmVudC0+dGFzay0+Y29tbTsKCglzaXplID0gQUxJR04oc3RybGVuKGNvbW0pKzEsIHNpemVvZih1NjQpKTsKCgljb21tX2V2ZW50LT5jb21tID0gY29tbTsKCWNvbW1fZXZlbnQtPmNvbW1fc2l6ZSA9IHNpemU7CgoJY29tbV9ldmVudC0+ZXZlbnQuaGVhZGVyLnNpemUgPSBzaXplb2YoY29tbV9ldmVudC0+ZXZlbnQpICsgc2l6ZTsKCgljcHVjdHggPSAmZ2V0X2NwdV92YXIocGVyZl9jcHVfY29udGV4dCk7CglwZXJmX2NvdW50ZXJfY29tbV9jdHgoJmNwdWN0eC0+Y3R4LCBjb21tX2V2ZW50KTsKCXB1dF9jcHVfdmFyKHBlcmZfY3B1X2NvbnRleHQpOwoKCXJjdV9yZWFkX2xvY2soKTsKCS8qCgkgKiBkb2Vzbid0IHJlYWxseSBtYXR0ZXIgd2hpY2ggb2YgdGhlIGNoaWxkIGNvbnRleHRzIHRoZQoJICogZXZlbnRzIGVuZHMgdXAgaW4uCgkgKi8KCWN0eCA9IHJjdV9kZXJlZmVyZW5jZShjdXJyZW50LT5wZXJmX2NvdW50ZXJfY3R4cCk7CglpZiAoY3R4KQoJCXBlcmZfY291bnRlcl9jb21tX2N0eChjdHgsIGNvbW1fZXZlbnQpOwoJcmN1X3JlYWRfdW5sb2NrKCk7Cn0KCnZvaWQgcGVyZl9jb3VudGVyX2NvbW0oc3RydWN0IHRhc2tfc3RydWN0ICp0YXNrKQp7CglzdHJ1Y3QgcGVyZl9jb21tX2V2ZW50IGNvbW1fZXZlbnQ7CgoJaWYgKHRhc2stPnBlcmZfY291bnRlcl9jdHhwKQoJCXBlcmZfY291bnRlcl9lbmFibGVfb25fZXhlYyh0YXNrKTsKCglpZiAoIWF0b21pY19yZWFkKCZucl9jb21tX2NvdW50ZXJzKSkKCQlyZXR1cm47CgoJY29tbV9ldmVudCA9IChzdHJ1Y3QgcGVyZl9jb21tX2V2ZW50KXsKCQkudGFzawk9IHRhc2ssCgkJLmV2ZW50ICA9IHsKCQkJLmhlYWRlciA9IHsgLnR5cGUgPSBQRVJGX0VWRU5UX0NPTU0sIH0sCgkJfSwKCX07CgoJcGVyZl9jb3VudGVyX2NvbW1fZXZlbnQoJmNvbW1fZXZlbnQpOwp9CgovKgogKiBtbWFwIHRyYWNraW5nCiAqLwoKc3RydWN0IHBlcmZfbW1hcF9ldmVudCB7CglzdHJ1Y3Qgdm1fYXJlYV9zdHJ1Y3QJKnZtYTsKCgljb25zdCBjaGFyCQkqZmlsZV9uYW1lOwoJaW50CQkJZmlsZV9zaXplOwoKCXN0cnVjdCB7CgkJc3RydWN0IHBlcmZfZXZlbnRfaGVhZGVyCWhlYWRlcjsKCgkJdTMyCQkJCXBpZDsKCQl1MzIJCQkJdGlkOwoJCXU2NAkJCQlzdGFydDsKCQl1NjQJCQkJbGVuOwoJCXU2NAkJCQlwZ29mZjsKCX0gZXZlbnQ7Cn07CgpzdGF0aWMgdm9pZCBwZXJmX2NvdW50ZXJfbW1hcF9vdXRwdXQoc3RydWN0IHBlcmZfY291bnRlciAqY291bnRlciwKCQkJCSAgICAgc3RydWN0IHBlcmZfbW1hcF9ldmVudCAqbW1hcF9ldmVudCkKewoJc3RydWN0IHBlcmZfb3V0cHV0X2hhbmRsZSBoYW5kbGU7CglpbnQgc2l6ZSA9IG1tYXBfZXZlbnQtPmV2ZW50LmhlYWRlci5zaXplOwoJaW50IHJldCA9IHBlcmZfb3V0cHV0X2JlZ2luKCZoYW5kbGUsIGNvdW50ZXIsIHNpemUsIDAsIDApOwoKCWlmIChyZXQpCgkJcmV0dXJuOwoKCW1tYXBfZXZlbnQtPmV2ZW50LnBpZCA9IHBlcmZfY291bnRlcl9waWQoY291bnRlciwgY3VycmVudCk7CgltbWFwX2V2ZW50LT5ldmVudC50aWQgPSBwZXJmX2NvdW50ZXJfdGlkKGNvdW50ZXIsIGN1cnJlbnQpOwoKCXBlcmZfb3V0cHV0X3B1dCgmaGFuZGxlLCBtbWFwX2V2ZW50LT5ldmVudCk7CglwZXJmX291dHB1dF9jb3B5KCZoYW5kbGUsIG1tYXBfZXZlbnQtPmZpbGVfbmFtZSwKCQkJCSAgIG1tYXBfZXZlbnQtPmZpbGVfc2l6ZSk7CglwZXJmX291dHB1dF9lbmQoJmhhbmRsZSk7Cn0KCnN0YXRpYyBpbnQgcGVyZl9jb3VudGVyX21tYXBfbWF0Y2goc3RydWN0IHBlcmZfY291bnRlciAqY291bnRlciwKCQkJCSAgIHN0cnVjdCBwZXJmX21tYXBfZXZlbnQgKm1tYXBfZXZlbnQpCnsKCWlmIChjb3VudGVyLT5hdHRyLm1tYXApCgkJcmV0dXJuIDE7CgoJcmV0dXJuIDA7Cn0KCnN0YXRpYyB2b2lkIHBlcmZfY291bnRlcl9tbWFwX2N0eChzdHJ1Y3QgcGVyZl9jb3VudGVyX2NvbnRleHQgKmN0eCwKCQkJCSAgc3RydWN0IHBlcmZfbW1hcF9ldmVudCAqbW1hcF9ldmVudCkKewoJc3RydWN0IHBlcmZfY291bnRlciAqY291bnRlcjsKCglpZiAoc3lzdGVtX3N0YXRlICE9IFNZU1RFTV9SVU5OSU5HIHx8IGxpc3RfZW1wdHkoJmN0eC0+ZXZlbnRfbGlzdCkpCgkJcmV0dXJuOwoKCXJjdV9yZWFkX2xvY2soKTsKCWxpc3RfZm9yX2VhY2hfZW50cnlfcmN1KGNvdW50ZXIsICZjdHgtPmV2ZW50X2xpc3QsIGV2ZW50X2VudHJ5KSB7CgkJaWYgKHBlcmZfY291bnRlcl9tbWFwX21hdGNoKGNvdW50ZXIsIG1tYXBfZXZlbnQpKQoJCQlwZXJmX2NvdW50ZXJfbW1hcF9vdXRwdXQoY291bnRlciwgbW1hcF9ldmVudCk7Cgl9CglyY3VfcmVhZF91bmxvY2soKTsKfQoKc3RhdGljIHZvaWQgcGVyZl9jb3VudGVyX21tYXBfZXZlbnQoc3RydWN0IHBlcmZfbW1hcF9ldmVudCAqbW1hcF9ldmVudCkKewoJc3RydWN0IHBlcmZfY3B1X2NvbnRleHQgKmNwdWN0eDsKCXN0cnVjdCBwZXJmX2NvdW50ZXJfY29udGV4dCAqY3R4OwoJc3RydWN0IHZtX2FyZWFfc3RydWN0ICp2bWEgPSBtbWFwX2V2ZW50LT52bWE7CglzdHJ1Y3QgZmlsZSAqZmlsZSA9IHZtYS0+dm1fZmlsZTsKCXVuc2lnbmVkIGludCBzaXplOwoJY2hhciB0bXBbMTZdOwoJY2hhciAqYnVmID0gTlVMTDsKCWNvbnN0IGNoYXIgKm5hbWU7CgoJaWYgKGZpbGUpIHsKCQlidWYgPSBremFsbG9jKFBBVEhfTUFYLCBHRlBfS0VSTkVMKTsKCQlpZiAoIWJ1ZikgewoJCQluYW1lID0gc3RybmNweSh0bXAsICIvL2Vub21lbSIsIHNpemVvZih0bXApKTsKCQkJZ290byBnb3RfbmFtZTsKCQl9CgkJbmFtZSA9IGRfcGF0aCgmZmlsZS0+Zl9wYXRoLCBidWYsIFBBVEhfTUFYKTsKCQlpZiAoSVNfRVJSKG5hbWUpKSB7CgkJCW5hbWUgPSBzdHJuY3B5KHRtcCwgIi8vdG9vbG9uZyIsIHNpemVvZih0bXApKTsKCQkJZ290byBnb3RfbmFtZTsKCQl9Cgl9IGVsc2UgewoJCW5hbWUgPSBhcmNoX3ZtYV9uYW1lKG1tYXBfZXZlbnQtPnZtYSk7CgkJaWYgKG5hbWUpCgkJCWdvdG8gZ290X25hbWU7CgoJCWlmICghdm1hLT52bV9tbSkgewoJCQluYW1lID0gc3RybmNweSh0bXAsICJbdmRzb10iLCBzaXplb2YodG1wKSk7CgkJCWdvdG8gZ290X25hbWU7CgkJfQoKCQluYW1lID0gc3RybmNweSh0bXAsICIvL2Fub24iLCBzaXplb2YodG1wKSk7CgkJZ290byBnb3RfbmFtZTsKCX0KCmdvdF9uYW1lOgoJc2l6ZSA9IEFMSUdOKHN0cmxlbihuYW1lKSsxLCBzaXplb2YodTY0KSk7CgoJbW1hcF9ldmVudC0+ZmlsZV9uYW1lID0gbmFtZTsKCW1tYXBfZXZlbnQtPmZpbGVfc2l6ZSA9IHNpemU7CgoJbW1hcF9ldmVudC0+ZXZlbnQuaGVhZGVyLnNpemUgPSBzaXplb2YobW1hcF9ldmVudC0+ZXZlbnQpICsgc2l6ZTsKCgljcHVjdHggPSAmZ2V0X2NwdV92YXIocGVyZl9jcHVfY29udGV4dCk7CglwZXJmX2NvdW50ZXJfbW1hcF9jdHgoJmNwdWN0eC0+Y3R4LCBtbWFwX2V2ZW50KTsKCXB1dF9jcHVfdmFyKHBlcmZfY3B1X2NvbnRleHQpOwoKCXJjdV9yZWFkX2xvY2soKTsKCS8qCgkgKiBkb2Vzbid0IHJlYWxseSBtYXR0ZXIgd2hpY2ggb2YgdGhlIGNoaWxkIGNvbnRleHRzIHRoZQoJICogZXZlbnRzIGVuZHMgdXAgaW4uCgkgKi8KCWN0eCA9IHJjdV9kZXJlZmVyZW5jZShjdXJyZW50LT5wZXJmX2NvdW50ZXJfY3R4cCk7CglpZiAoY3R4KQoJCXBlcmZfY291bnRlcl9tbWFwX2N0eChjdHgsIG1tYXBfZXZlbnQpOwoJcmN1X3JlYWRfdW5sb2NrKCk7CgoJa2ZyZWUoYnVmKTsKfQoKdm9pZCBfX3BlcmZfY291bnRlcl9tbWFwKHN0cnVjdCB2bV9hcmVhX3N0cnVjdCAqdm1hKQp7CglzdHJ1Y3QgcGVyZl9tbWFwX2V2ZW50IG1tYXBfZXZlbnQ7CgoJaWYgKCFhdG9taWNfcmVhZCgmbnJfbW1hcF9jb3VudGVycykpCgkJcmV0dXJuOwoKCW1tYXBfZXZlbnQgPSAoc3RydWN0IHBlcmZfbW1hcF9ldmVudCl7CgkJLnZtYQk9IHZtYSwKCQkuZXZlbnQgID0gewoJCQkuaGVhZGVyID0geyAudHlwZSA9IFBFUkZfRVZFTlRfTU1BUCwgfSwKCQkJLnN0YXJ0ICA9IHZtYS0+dm1fc3RhcnQsCgkJCS5sZW4gICAgPSB2bWEtPnZtX2VuZCAtIHZtYS0+dm1fc3RhcnQsCgkJCS5wZ29mZiAgPSB2bWEtPnZtX3Bnb2ZmLAoJCX0sCgl9OwoKCXBlcmZfY291bnRlcl9tbWFwX2V2ZW50KCZtbWFwX2V2ZW50KTsKfQoKLyoKICogTG9nIHNhbXBsZV9wZXJpb2QgY2hhbmdlcyBzbyB0aGF0IGFuYWx5emluZyB0b29scyBjYW4gcmUtbm9ybWFsaXplIHRoZQogKiBldmVudCBmbG93LgogKi8KCnN0cnVjdCBmcmVxX2V2ZW50IHsKCXN0cnVjdCBwZXJmX2V2ZW50X2hlYWRlcgloZWFkZXI7Cgl1NjQJCQkJdGltZTsKCXU2NAkJCQlpZDsKCXU2NAkJCQlwZXJpb2Q7Cn07CgpzdGF0aWMgdm9pZCBwZXJmX2xvZ19wZXJpb2Qoc3RydWN0IHBlcmZfY291bnRlciAqY291bnRlciwgdTY0IHBlcmlvZCkKewoJc3RydWN0IHBlcmZfb3V0cHV0X2hhbmRsZSBoYW5kbGU7CglzdHJ1Y3QgZnJlcV9ldmVudCBldmVudDsKCWludCByZXQ7CgoJaWYgKGNvdW50ZXItPmh3LnNhbXBsZV9wZXJpb2QgPT0gcGVyaW9kKQoJCXJldHVybjsKCglpZiAoY291bnRlci0+YXR0ci5zYW1wbGVfdHlwZSAmIFBFUkZfU0FNUExFX1BFUklPRCkKCQlyZXR1cm47CgoJZXZlbnQgPSAoc3RydWN0IGZyZXFfZXZlbnQpIHsKCQkuaGVhZGVyID0gewoJCQkudHlwZSA9IFBFUkZfRVZFTlRfUEVSSU9ELAoJCQkubWlzYyA9IDAsCgkJCS5zaXplID0gc2l6ZW9mKGV2ZW50KSwKCQl9LAoJCS50aW1lID0gc2NoZWRfY2xvY2soKSwKCQkuaWQgPSBjb3VudGVyLT5pZCwKCQkucGVyaW9kID0gcGVyaW9kLAoJfTsKCglyZXQgPSBwZXJmX291dHB1dF9iZWdpbigmaGFuZGxlLCBjb3VudGVyLCBzaXplb2YoZXZlbnQpLCAxLCAwKTsKCWlmIChyZXQpCgkJcmV0dXJuOwoKCXBlcmZfb3V0cHV0X3B1dCgmaGFuZGxlLCBldmVudCk7CglwZXJmX291dHB1dF9lbmQoJmhhbmRsZSk7Cn0KCi8qCiAqIElSUSB0aHJvdHRsZSBsb2dnaW5nCiAqLwoKc3RhdGljIHZvaWQgcGVyZl9sb2dfdGhyb3R0bGUoc3RydWN0IHBlcmZfY291bnRlciAqY291bnRlciwgaW50IGVuYWJsZSkKewoJc3RydWN0IHBlcmZfb3V0cHV0X2hhbmRsZSBoYW5kbGU7CglpbnQgcmV0OwoKCXN0cnVjdCB7CgkJc3RydWN0IHBlcmZfZXZlbnRfaGVhZGVyCWhlYWRlcjsKCQl1NjQJCQkJdGltZTsKCQl1NjQJCQkJaWQ7Cgl9IHRocm90dGxlX2V2ZW50ID0gewoJCS5oZWFkZXIgPSB7CgkJCS50eXBlID0gUEVSRl9FVkVOVF9USFJPVFRMRSArIDEsCgkJCS5taXNjID0gMCwKCQkJLnNpemUgPSBzaXplb2YodGhyb3R0bGVfZXZlbnQpLAoJCX0sCgkJLnRpbWUJPSBzY2hlZF9jbG9jaygpLAoJCS5pZAk9IGNvdW50ZXItPmlkLAoJfTsKCglyZXQgPSBwZXJmX291dHB1dF9iZWdpbigmaGFuZGxlLCBjb3VudGVyLCBzaXplb2YodGhyb3R0bGVfZXZlbnQpLCAxLCAwKTsKCWlmIChyZXQpCgkJcmV0dXJuOwoKCXBlcmZfb3V0cHV0X3B1dCgmaGFuZGxlLCB0aHJvdHRsZV9ldmVudCk7CglwZXJmX291dHB1dF9lbmQoJmhhbmRsZSk7Cn0KCi8qCiAqIEdlbmVyaWMgY291bnRlciBvdmVyZmxvdyBoYW5kbGluZywgc2FtcGxpbmcuCiAqLwoKaW50IHBlcmZfY291bnRlcl9vdmVyZmxvdyhzdHJ1Y3QgcGVyZl9jb3VudGVyICpjb3VudGVyLCBpbnQgbm1pLAoJCQkgIHN0cnVjdCBwZXJmX3NhbXBsZV9kYXRhICpkYXRhKQp7CglpbnQgZXZlbnRzID0gYXRvbWljX3JlYWQoJmNvdW50ZXItPmV2ZW50X2xpbWl0KTsKCWludCB0aHJvdHRsZSA9IGNvdW50ZXItPnBtdS0+dW50aHJvdHRsZSAhPSBOVUxMOwoJc3RydWN0IGh3X3BlcmZfY291bnRlciAqaHdjID0gJmNvdW50ZXItPmh3OwoJaW50IHJldCA9IDA7CgoJaWYgKCF0aHJvdHRsZSkgewoJCWh3Yy0+aW50ZXJydXB0cysrOwoJfSBlbHNlIHsKCQlpZiAoaHdjLT5pbnRlcnJ1cHRzICE9IE1BWF9JTlRFUlJVUFRTKSB7CgkJCWh3Yy0+aW50ZXJydXB0cysrOwoJCQlpZiAoSFogKiBod2MtPmludGVycnVwdHMgPgoJCQkJCSh1NjQpc3lzY3RsX3BlcmZfY291bnRlcl9zYW1wbGVfcmF0ZSkgewoJCQkJaHdjLT5pbnRlcnJ1cHRzID0gTUFYX0lOVEVSUlVQVFM7CgkJCQlwZXJmX2xvZ190aHJvdHRsZShjb3VudGVyLCAwKTsKCQkJCXJldCA9IDE7CgkJCX0KCQl9IGVsc2UgewoJCQkvKgoJCQkgKiBLZWVwIHJlLWRpc2FibGluZyBjb3VudGVycyBldmVuIHRob3VnaCBvbiB0aGUgcHJldmlvdXMKCQkJICogcGFzcyB3ZSBkaXNhYmxlZCBpdCAtIGp1c3QgaW4gY2FzZSB3ZSByYWNlZCB3aXRoIGEKCQkJICogc2NoZWQtaW4gYW5kIHRoZSBjb3VudGVyIGdvdCBlbmFibGVkIGFnYWluOgoJCQkgKi8KCQkJcmV0ID0gMTsKCQl9Cgl9CgoJaWYgKGNvdW50ZXItPmF0dHIuZnJlcSkgewoJCXU2NCBub3cgPSBzY2hlZF9jbG9jaygpOwoJCXM2NCBkZWx0YSA9IG5vdyAtIGh3Yy0+ZnJlcV9zdGFtcDsKCgkJaHdjLT5mcmVxX3N0YW1wID0gbm93OwoKCQlpZiAoZGVsdGEgPiAwICYmIGRlbHRhIDwgVElDS19OU0VDKQoJCQlwZXJmX2FkanVzdF9wZXJpb2QoY291bnRlciwgTlNFQ19QRVJfU0VDIC8gKGludClkZWx0YSk7Cgl9CgoJLyoKCSAqIFhYWCBldmVudF9saW1pdCBtaWdodCBub3QgcXVpdGUgd29yayBhcyBleHBlY3RlZCBvbiBpbmhlcml0ZWQKCSAqIGNvdW50ZXJzCgkgKi8KCgljb3VudGVyLT5wZW5kaW5nX2tpbGwgPSBQT0xMX0lOOwoJaWYgKGV2ZW50cyAmJiBhdG9taWNfZGVjX2FuZF90ZXN0KCZjb3VudGVyLT5ldmVudF9saW1pdCkpIHsKCQlyZXQgPSAxOwoJCWNvdW50ZXItPnBlbmRpbmdfa2lsbCA9IFBPTExfSFVQOwoJCWlmIChubWkpIHsKCQkJY291bnRlci0+cGVuZGluZ19kaXNhYmxlID0gMTsKCQkJcGVyZl9wZW5kaW5nX3F1ZXVlKCZjb3VudGVyLT5wZW5kaW5nLAoJCQkJCSAgIHBlcmZfcGVuZGluZ19jb3VudGVyKTsKCQl9IGVsc2UKCQkJcGVyZl9jb3VudGVyX2Rpc2FibGUoY291bnRlcik7Cgl9CgoJcGVyZl9jb3VudGVyX291dHB1dChjb3VudGVyLCBubWksIGRhdGEpOwoJcmV0dXJuIHJldDsKfQoKLyoKICogR2VuZXJpYyBzb2Z0d2FyZSBjb3VudGVyIGluZnJhc3RydWN0dXJlCiAqLwoKc3RhdGljIHZvaWQgcGVyZl9zd2NvdW50ZXJfdXBkYXRlKHN0cnVjdCBwZXJmX2NvdW50ZXIgKmNvdW50ZXIpCnsKCXN0cnVjdCBod19wZXJmX2NvdW50ZXIgKmh3YyA9ICZjb3VudGVyLT5odzsKCXU2NCBwcmV2LCBub3c7CglzNjQgZGVsdGE7CgphZ2FpbjoKCXByZXYgPSBhdG9taWM2NF9yZWFkKCZod2MtPnByZXZfY291bnQpOwoJbm93ID0gYXRvbWljNjRfcmVhZCgmaHdjLT5jb3VudCk7CglpZiAoYXRvbWljNjRfY21weGNoZygmaHdjLT5wcmV2X2NvdW50LCBwcmV2LCBub3cpICE9IHByZXYpCgkJZ290byBhZ2FpbjsKCglkZWx0YSA9IG5vdyAtIHByZXY7CgoJYXRvbWljNjRfYWRkKGRlbHRhLCAmY291bnRlci0+Y291bnQpOwoJYXRvbWljNjRfc3ViKGRlbHRhLCAmaHdjLT5wZXJpb2RfbGVmdCk7Cn0KCnN0YXRpYyB2b2lkIHBlcmZfc3djb3VudGVyX3NldF9wZXJpb2Qoc3RydWN0IHBlcmZfY291bnRlciAqY291bnRlcikKewoJc3RydWN0IGh3X3BlcmZfY291bnRlciAqaHdjID0gJmNvdW50ZXItPmh3OwoJczY0IGxlZnQgPSBhdG9taWM2NF9yZWFkKCZod2MtPnBlcmlvZF9sZWZ0KTsKCXM2NCBwZXJpb2QgPSBod2MtPnNhbXBsZV9wZXJpb2Q7CgoJaWYgKHVubGlrZWx5KGxlZnQgPD0gLXBlcmlvZCkpIHsKCQlsZWZ0ID0gcGVyaW9kOwoJCWF0b21pYzY0X3NldCgmaHdjLT5wZXJpb2RfbGVmdCwgbGVmdCk7CgkJaHdjLT5sYXN0X3BlcmlvZCA9IHBlcmlvZDsKCX0KCglpZiAodW5saWtlbHkobGVmdCA8PSAwKSkgewoJCWxlZnQgKz0gcGVyaW9kOwoJCWF0b21pYzY0X2FkZChwZXJpb2QsICZod2MtPnBlcmlvZF9sZWZ0KTsKCQlod2MtPmxhc3RfcGVyaW9kID0gcGVyaW9kOwoJfQoKCWF0b21pYzY0X3NldCgmaHdjLT5wcmV2X2NvdW50LCAtbGVmdCk7CglhdG9taWM2NF9zZXQoJmh3Yy0+Y291bnQsIC1sZWZ0KTsKfQoKc3RhdGljIGVudW0gaHJ0aW1lcl9yZXN0YXJ0IHBlcmZfc3djb3VudGVyX2hydGltZXIoc3RydWN0IGhydGltZXIgKmhydGltZXIpCnsKCWVudW0gaHJ0aW1lcl9yZXN0YXJ0IHJldCA9IEhSVElNRVJfUkVTVEFSVDsKCXN0cnVjdCBwZXJmX3NhbXBsZV9kYXRhIGRhdGE7CglzdHJ1Y3QgcGVyZl9jb3VudGVyICpjb3VudGVyOwoJdTY0IHBlcmlvZDsKCgljb3VudGVyCT0gY29udGFpbmVyX29mKGhydGltZXIsIHN0cnVjdCBwZXJmX2NvdW50ZXIsIGh3LmhydGltZXIpOwoJY291bnRlci0+cG11LT5yZWFkKGNvdW50ZXIpOwoKCWRhdGEuYWRkciA9IDA7CglkYXRhLnJlZ3MgPSBnZXRfaXJxX3JlZ3MoKTsKCS8qCgkgKiBJbiBjYXNlIHdlIGV4Y2x1ZGUga2VybmVsIElQcyBvciBhcmUgc29tZWhvdyBub3QgaW4gaW50ZXJydXB0CgkgKiBjb250ZXh0LCBwcm92aWRlIHRoZSBuZXh0IGJlc3QgdGhpbmcsIHRoZSB1c2VyIElQLgoJICovCglpZiAoKGNvdW50ZXItPmF0dHIuZXhjbHVkZV9rZXJuZWwgfHwgIWRhdGEucmVncykgJiYKCQkJIWNvdW50ZXItPmF0dHIuZXhjbHVkZV91c2VyKQoJCWRhdGEucmVncyA9IHRhc2tfcHRfcmVncyhjdXJyZW50KTsKCglpZiAoZGF0YS5yZWdzKSB7CgkJaWYgKHBlcmZfY291bnRlcl9vdmVyZmxvdyhjb3VudGVyLCAwLCAmZGF0YSkpCgkJCXJldCA9IEhSVElNRVJfTk9SRVNUQVJUOwoJfQoKCXBlcmlvZCA9IG1heF90KHU2NCwgMTAwMDAsIGNvdW50ZXItPmh3LnNhbXBsZV9wZXJpb2QpOwoJaHJ0aW1lcl9mb3J3YXJkX25vdyhocnRpbWVyLCBuc190b19rdGltZShwZXJpb2QpKTsKCglyZXR1cm4gcmV0Owp9CgpzdGF0aWMgdm9pZCBwZXJmX3N3Y291bnRlcl9vdmVyZmxvdyhzdHJ1Y3QgcGVyZl9jb3VudGVyICpjb3VudGVyLAoJCQkJICAgIGludCBubWksIHN0cnVjdCBwZXJmX3NhbXBsZV9kYXRhICpkYXRhKQp7CglkYXRhLT5wZXJpb2QgPSBjb3VudGVyLT5ody5sYXN0X3BlcmlvZDsKCglwZXJmX3N3Y291bnRlcl91cGRhdGUoY291bnRlcik7CglwZXJmX3N3Y291bnRlcl9zZXRfcGVyaW9kKGNvdW50ZXIpOwoJaWYgKHBlcmZfY291bnRlcl9vdmVyZmxvdyhjb3VudGVyLCBubWksIGRhdGEpKQoJCS8qIHNvZnQtZGlzYWJsZSB0aGUgY291bnRlciAqLwoJCTsKfQoKc3RhdGljIGludCBwZXJmX3N3Y291bnRlcl9pc19jb3VudGluZyhzdHJ1Y3QgcGVyZl9jb3VudGVyICpjb3VudGVyKQp7CglzdHJ1Y3QgcGVyZl9jb3VudGVyX2NvbnRleHQgKmN0eDsKCXVuc2lnbmVkIGxvbmcgZmxhZ3M7CglpbnQgY291bnQ7CgoJaWYgKGNvdW50ZXItPnN0YXRlID09IFBFUkZfQ09VTlRFUl9TVEFURV9BQ1RJVkUpCgkJcmV0dXJuIDE7CgoJaWYgKGNvdW50ZXItPnN0YXRlICE9IFBFUkZfQ09VTlRFUl9TVEFURV9JTkFDVElWRSkKCQlyZXR1cm4gMDsKCgkvKgoJICogSWYgdGhlIGNvdW50ZXIgaXMgaW5hY3RpdmUsIGl0IGNvdWxkIGJlIGp1c3QgYmVjYXVzZQoJICogaXRzIHRhc2sgaXMgc2NoZWR1bGVkIG91dCwgb3IgYmVjYXVzZSBpdCdzIGluIGEgZ3JvdXAKCSAqIHdoaWNoIGNvdWxkIG5vdCBnbyBvbiB0aGUgUE1VLiAgV2Ugd2FudCB0byBjb3VudCBpbgoJICogdGhlIGZpcnN0IGNhc2UgYnV0IG5vdCB0aGUgc2Vjb25kLiAgSWYgdGhlIGNvbnRleHQgaXMKCSAqIGN1cnJlbnRseSBhY3RpdmUgdGhlbiBhbiBpbmFjdGl2ZSBzb2Z0d2FyZSBjb3VudGVyIG11c3QKCSAqIGJlIHRoZSBzZWNvbmQgY2FzZS4gIElmIGl0J3Mgbm90IGN1cnJlbnRseSBhY3RpdmUgdGhlbgoJICogd2UgbmVlZCB0byBrbm93IHdoZXRoZXIgdGhlIGNvdW50ZXIgd2FzIGFjdGl2ZSB3aGVuIHRoZQoJICogY29udGV4dCB3YXMgbGFzdCBhY3RpdmUsIHdoaWNoIHdlIGNhbiBkZXRlcm1pbmUgYnkKCSAqIGNvbXBhcmluZyBjb3VudGVyLT50c3RhbXBfc3RvcHBlZCB3aXRoIGN0eC0+dGltZS4KCSAqCgkgKiBXZSBhcmUgd2l0aGluIGFuIFJDVSByZWFkLXNpZGUgY3JpdGljYWwgc2VjdGlvbiwKCSAqIHdoaWNoIHByb3RlY3RzIHRoZSBleGlzdGVuY2Ugb2YgKmN0eC4KCSAqLwoJY3R4ID0gY291bnRlci0+Y3R4OwoJc3Bpbl9sb2NrX2lycXNhdmUoJmN0eC0+bG9jaywgZmxhZ3MpOwoJY291bnQgPSAxOwoJLyogUmUtY2hlY2sgc3RhdGUgbm93IHdlIGhhdmUgdGhlIGxvY2sgKi8KCWlmIChjb3VudGVyLT5zdGF0ZSA8IFBFUkZfQ09VTlRFUl9TVEFURV9JTkFDVElWRSB8fAoJICAgIGNvdW50ZXItPmN0eC0+aXNfYWN0aXZlIHx8CgkgICAgY291bnRlci0+dHN0YW1wX3N0b3BwZWQgPCBjdHgtPnRpbWUpCgkJY291bnQgPSAwOwoJc3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmY3R4LT5sb2NrLCBmbGFncyk7CglyZXR1cm4gY291bnQ7Cn0KCnN0YXRpYyBpbnQgcGVyZl9zd2NvdW50ZXJfbWF0Y2goc3RydWN0IHBlcmZfY291bnRlciAqY291bnRlciwKCQkJCWVudW0gcGVyZl90eXBlX2lkIHR5cGUsCgkJCQl1MzIgZXZlbnQsIHN0cnVjdCBwdF9yZWdzICpyZWdzKQp7CglpZiAoIXBlcmZfc3djb3VudGVyX2lzX2NvdW50aW5nKGNvdW50ZXIpKQoJCXJldHVybiAwOwoKCWlmIChjb3VudGVyLT5hdHRyLnR5cGUgIT0gdHlwZSkKCQlyZXR1cm4gMDsKCWlmIChjb3VudGVyLT5hdHRyLmNvbmZpZyAhPSBldmVudCkKCQlyZXR1cm4gMDsKCglpZiAocmVncykgewoJCWlmIChjb3VudGVyLT5hdHRyLmV4Y2x1ZGVfdXNlciAmJiB1c2VyX21vZGUocmVncykpCgkJCXJldHVybiAwOwoKCQlpZiAoY291bnRlci0+YXR0ci5leGNsdWRlX2tlcm5lbCAmJiAhdXNlcl9tb2RlKHJlZ3MpKQoJCQlyZXR1cm4gMDsKCX0KCglyZXR1cm4gMTsKfQoKc3RhdGljIHZvaWQgcGVyZl9zd2NvdW50ZXJfYWRkKHN0cnVjdCBwZXJmX2NvdW50ZXIgKmNvdW50ZXIsIHU2NCBuciwKCQkJICAgICAgIGludCBubWksIHN0cnVjdCBwZXJmX3NhbXBsZV9kYXRhICpkYXRhKQp7CglpbnQgbmVnID0gYXRvbWljNjRfYWRkX25lZ2F0aXZlKG5yLCAmY291bnRlci0+aHcuY291bnQpOwoKCWlmIChjb3VudGVyLT5ody5zYW1wbGVfcGVyaW9kICYmICFuZWcgJiYgZGF0YS0+cmVncykKCQlwZXJmX3N3Y291bnRlcl9vdmVyZmxvdyhjb3VudGVyLCBubWksIGRhdGEpOwp9CgpzdGF0aWMgdm9pZCBwZXJmX3N3Y291bnRlcl9jdHhfZXZlbnQoc3RydWN0IHBlcmZfY291bnRlcl9jb250ZXh0ICpjdHgsCgkJCQkgICAgIGVudW0gcGVyZl90eXBlX2lkIHR5cGUsCgkJCQkgICAgIHUzMiBldmVudCwgdTY0IG5yLCBpbnQgbm1pLAoJCQkJICAgICBzdHJ1Y3QgcGVyZl9zYW1wbGVfZGF0YSAqZGF0YSkKewoJc3RydWN0IHBlcmZfY291bnRlciAqY291bnRlcjsKCglpZiAoc3lzdGVtX3N0YXRlICE9IFNZU1RFTV9SVU5OSU5HIHx8IGxpc3RfZW1wdHkoJmN0eC0+ZXZlbnRfbGlzdCkpCgkJcmV0dXJuOwoKCXJjdV9yZWFkX2xvY2soKTsKCWxpc3RfZm9yX2VhY2hfZW50cnlfcmN1KGNvdW50ZXIsICZjdHgtPmV2ZW50X2xpc3QsIGV2ZW50X2VudHJ5KSB7CgkJaWYgKHBlcmZfc3djb3VudGVyX21hdGNoKGNvdW50ZXIsIHR5cGUsIGV2ZW50LCBkYXRhLT5yZWdzKSkKCQkJcGVyZl9zd2NvdW50ZXJfYWRkKGNvdW50ZXIsIG5yLCBubWksIGRhdGEpOwoJfQoJcmN1X3JlYWRfdW5sb2NrKCk7Cn0KCnN0YXRpYyBpbnQgKnBlcmZfc3djb3VudGVyX3JlY3Vyc2lvbl9jb250ZXh0KHN0cnVjdCBwZXJmX2NwdV9jb250ZXh0ICpjcHVjdHgpCnsKCWlmIChpbl9ubWkoKSkKCQlyZXR1cm4gJmNwdWN0eC0+cmVjdXJzaW9uWzNdOwoKCWlmIChpbl9pcnEoKSkKCQlyZXR1cm4gJmNwdWN0eC0+cmVjdXJzaW9uWzJdOwoKCWlmIChpbl9zb2Z0aXJxKCkpCgkJcmV0dXJuICZjcHVjdHgtPnJlY3Vyc2lvblsxXTsKCglyZXR1cm4gJmNwdWN0eC0+cmVjdXJzaW9uWzBdOwp9CgpzdGF0aWMgdm9pZCBkb19wZXJmX3N3Y291bnRlcl9ldmVudChlbnVtIHBlcmZfdHlwZV9pZCB0eXBlLCB1MzIgZXZlbnQsCgkJCQkgICAgdTY0IG5yLCBpbnQgbm1pLAoJCQkJICAgIHN0cnVjdCBwZXJmX3NhbXBsZV9kYXRhICpkYXRhKQp7CglzdHJ1Y3QgcGVyZl9jcHVfY29udGV4dCAqY3B1Y3R4ID0gJmdldF9jcHVfdmFyKHBlcmZfY3B1X2NvbnRleHQpOwoJaW50ICpyZWN1cnNpb24gPSBwZXJmX3N3Y291bnRlcl9yZWN1cnNpb25fY29udGV4dChjcHVjdHgpOwoJc3RydWN0IHBlcmZfY291bnRlcl9jb250ZXh0ICpjdHg7CgoJaWYgKCpyZWN1cnNpb24pCgkJZ290byBvdXQ7CgoJKCpyZWN1cnNpb24pKys7CgliYXJyaWVyKCk7CgoJcGVyZl9zd2NvdW50ZXJfY3R4X2V2ZW50KCZjcHVjdHgtPmN0eCwgdHlwZSwgZXZlbnQsCgkJCQkgbnIsIG5taSwgZGF0YSk7CglyY3VfcmVhZF9sb2NrKCk7CgkvKgoJICogZG9lc24ndCByZWFsbHkgbWF0dGVyIHdoaWNoIG9mIHRoZSBjaGlsZCBjb250ZXh0cyB0aGUKCSAqIGV2ZW50cyBlbmRzIHVwIGluLgoJICovCgljdHggPSByY3VfZGVyZWZlcmVuY2UoY3VycmVudC0+cGVyZl9jb3VudGVyX2N0eHApOwoJaWYgKGN0eCkKCQlwZXJmX3N3Y291bnRlcl9jdHhfZXZlbnQoY3R4LCB0eXBlLCBldmVudCwgbnIsIG5taSwgZGF0YSk7CglyY3VfcmVhZF91bmxvY2soKTsKCgliYXJyaWVyKCk7CgkoKnJlY3Vyc2lvbiktLTsKCm91dDoKCXB1dF9jcHVfdmFyKHBlcmZfY3B1X2NvbnRleHQpOwp9Cgp2b2lkIF9fcGVyZl9zd2NvdW50ZXJfZXZlbnQodTMyIGV2ZW50LCB1NjQgbnIsIGludCBubWksCgkJCSAgICBzdHJ1Y3QgcHRfcmVncyAqcmVncywgdTY0IGFkZHIpCnsKCXN0cnVjdCBwZXJmX3NhbXBsZV9kYXRhIGRhdGEgPSB7CgkJLnJlZ3MgPSByZWdzLAoJCS5hZGRyID0gYWRkciwKCX07CgoJZG9fcGVyZl9zd2NvdW50ZXJfZXZlbnQoUEVSRl9UWVBFX1NPRlRXQVJFLCBldmVudCwgbnIsIG5taSwgJmRhdGEpOwp9CgpzdGF0aWMgdm9pZCBwZXJmX3N3Y291bnRlcl9yZWFkKHN0cnVjdCBwZXJmX2NvdW50ZXIgKmNvdW50ZXIpCnsKCXBlcmZfc3djb3VudGVyX3VwZGF0ZShjb3VudGVyKTsKfQoKc3RhdGljIGludCBwZXJmX3N3Y291bnRlcl9lbmFibGUoc3RydWN0IHBlcmZfY291bnRlciAqY291bnRlcikKewoJcGVyZl9zd2NvdW50ZXJfc2V0X3BlcmlvZChjb3VudGVyKTsKCXJldHVybiAwOwp9CgpzdGF0aWMgdm9pZCBwZXJmX3N3Y291bnRlcl9kaXNhYmxlKHN0cnVjdCBwZXJmX2NvdW50ZXIgKmNvdW50ZXIpCnsKCXBlcmZfc3djb3VudGVyX3VwZGF0ZShjb3VudGVyKTsKfQoKc3RhdGljIGNvbnN0IHN0cnVjdCBwbXUgcGVyZl9vcHNfZ2VuZXJpYyA9IHsKCS5lbmFibGUJCT0gcGVyZl9zd2NvdW50ZXJfZW5hYmxlLAoJLmRpc2FibGUJPSBwZXJmX3N3Y291bnRlcl9kaXNhYmxlLAoJLnJlYWQJCT0gcGVyZl9zd2NvdW50ZXJfcmVhZCwKfTsKCi8qCiAqIFNvZnR3YXJlIGNvdW50ZXI6IGNwdSB3YWxsIHRpbWUgY2xvY2sKICovCgpzdGF0aWMgdm9pZCBjcHVfY2xvY2tfcGVyZl9jb3VudGVyX3VwZGF0ZShzdHJ1Y3QgcGVyZl9jb3VudGVyICpjb3VudGVyKQp7CglpbnQgY3B1ID0gcmF3X3NtcF9wcm9jZXNzb3JfaWQoKTsKCXM2NCBwcmV2OwoJdTY0IG5vdzsKCglub3cgPSBjcHVfY2xvY2soY3B1KTsKCXByZXYgPSBhdG9taWM2NF9yZWFkKCZjb3VudGVyLT5ody5wcmV2X2NvdW50KTsKCWF0b21pYzY0X3NldCgmY291bnRlci0+aHcucHJldl9jb3VudCwgbm93KTsKCWF0b21pYzY0X2FkZChub3cgLSBwcmV2LCAmY291bnRlci0+Y291bnQpOwp9CgpzdGF0aWMgaW50IGNwdV9jbG9ja19wZXJmX2NvdW50ZXJfZW5hYmxlKHN0cnVjdCBwZXJmX2NvdW50ZXIgKmNvdW50ZXIpCnsKCXN0cnVjdCBod19wZXJmX2NvdW50ZXIgKmh3YyA9ICZjb3VudGVyLT5odzsKCWludCBjcHUgPSByYXdfc21wX3Byb2Nlc3Nvcl9pZCgpOwoKCWF0b21pYzY0X3NldCgmaHdjLT5wcmV2X2NvdW50LCBjcHVfY2xvY2soY3B1KSk7CglocnRpbWVyX2luaXQoJmh3Yy0+aHJ0aW1lciwgQ0xPQ0tfTU9OT1RPTklDLCBIUlRJTUVSX01PREVfUkVMKTsKCWh3Yy0+aHJ0aW1lci5mdW5jdGlvbiA9IHBlcmZfc3djb3VudGVyX2hydGltZXI7CglpZiAoaHdjLT5zYW1wbGVfcGVyaW9kKSB7CgkJdTY0IHBlcmlvZCA9IG1heF90KHU2NCwgMTAwMDAsIGh3Yy0+c2FtcGxlX3BlcmlvZCk7CgkJX19ocnRpbWVyX3N0YXJ0X3JhbmdlX25zKCZod2MtPmhydGltZXIsCgkJCQluc190b19rdGltZShwZXJpb2QpLCAwLAoJCQkJSFJUSU1FUl9NT0RFX1JFTCwgMCk7Cgl9CgoJcmV0dXJuIDA7Cn0KCnN0YXRpYyB2b2lkIGNwdV9jbG9ja19wZXJmX2NvdW50ZXJfZGlzYWJsZShzdHJ1Y3QgcGVyZl9jb3VudGVyICpjb3VudGVyKQp7CglpZiAoY291bnRlci0+aHcuc2FtcGxlX3BlcmlvZCkKCQlocnRpbWVyX2NhbmNlbCgmY291bnRlci0+aHcuaHJ0aW1lcik7CgljcHVfY2xvY2tfcGVyZl9jb3VudGVyX3VwZGF0ZShjb3VudGVyKTsKfQoKc3RhdGljIHZvaWQgY3B1X2Nsb2NrX3BlcmZfY291bnRlcl9yZWFkKHN0cnVjdCBwZXJmX2NvdW50ZXIgKmNvdW50ZXIpCnsKCWNwdV9jbG9ja19wZXJmX2NvdW50ZXJfdXBkYXRlKGNvdW50ZXIpOwp9CgpzdGF0aWMgY29uc3Qgc3RydWN0IHBtdSBwZXJmX29wc19jcHVfY2xvY2sgPSB7CgkuZW5hYmxlCQk9IGNwdV9jbG9ja19wZXJmX2NvdW50ZXJfZW5hYmxlLAoJLmRpc2FibGUJPSBjcHVfY2xvY2tfcGVyZl9jb3VudGVyX2Rpc2FibGUsCgkucmVhZAkJPSBjcHVfY2xvY2tfcGVyZl9jb3VudGVyX3JlYWQsCn07CgovKgogKiBTb2Z0d2FyZSBjb3VudGVyOiB0YXNrIHRpbWUgY2xvY2sKICovCgpzdGF0aWMgdm9pZCB0YXNrX2Nsb2NrX3BlcmZfY291bnRlcl91cGRhdGUoc3RydWN0IHBlcmZfY291bnRlciAqY291bnRlciwgdTY0IG5vdykKewoJdTY0IHByZXY7CglzNjQgZGVsdGE7CgoJcHJldiA9IGF0b21pYzY0X3hjaGcoJmNvdW50ZXItPmh3LnByZXZfY291bnQsIG5vdyk7CglkZWx0YSA9IG5vdyAtIHByZXY7CglhdG9taWM2NF9hZGQoZGVsdGEsICZjb3VudGVyLT5jb3VudCk7Cn0KCnN0YXRpYyBpbnQgdGFza19jbG9ja19wZXJmX2NvdW50ZXJfZW5hYmxlKHN0cnVjdCBwZXJmX2NvdW50ZXIgKmNvdW50ZXIpCnsKCXN0cnVjdCBod19wZXJmX2NvdW50ZXIgKmh3YyA9ICZjb3VudGVyLT5odzsKCXU2NCBub3c7CgoJbm93ID0gY291bnRlci0+Y3R4LT50aW1lOwoKCWF0b21pYzY0X3NldCgmaHdjLT5wcmV2X2NvdW50LCBub3cpOwoJaHJ0aW1lcl9pbml0KCZod2MtPmhydGltZXIsIENMT0NLX01PTk9UT05JQywgSFJUSU1FUl9NT0RFX1JFTCk7Cglod2MtPmhydGltZXIuZnVuY3Rpb24gPSBwZXJmX3N3Y291bnRlcl9ocnRpbWVyOwoJaWYgKGh3Yy0+c2FtcGxlX3BlcmlvZCkgewoJCXU2NCBwZXJpb2QgPSBtYXhfdCh1NjQsIDEwMDAwLCBod2MtPnNhbXBsZV9wZXJpb2QpOwoJCV9faHJ0aW1lcl9zdGFydF9yYW5nZV9ucygmaHdjLT5ocnRpbWVyLAoJCQkJbnNfdG9fa3RpbWUocGVyaW9kKSwgMCwKCQkJCUhSVElNRVJfTU9ERV9SRUwsIDApOwoJfQoKCXJldHVybiAwOwp9CgpzdGF0aWMgdm9pZCB0YXNrX2Nsb2NrX3BlcmZfY291bnRlcl9kaXNhYmxlKHN0cnVjdCBwZXJmX2NvdW50ZXIgKmNvdW50ZXIpCnsKCWlmIChjb3VudGVyLT5ody5zYW1wbGVfcGVyaW9kKQoJCWhydGltZXJfY2FuY2VsKCZjb3VudGVyLT5ody5ocnRpbWVyKTsKCXRhc2tfY2xvY2tfcGVyZl9jb3VudGVyX3VwZGF0ZShjb3VudGVyLCBjb3VudGVyLT5jdHgtPnRpbWUpOwoKfQoKc3RhdGljIHZvaWQgdGFza19jbG9ja19wZXJmX2NvdW50ZXJfcmVhZChzdHJ1Y3QgcGVyZl9jb3VudGVyICpjb3VudGVyKQp7Cgl1NjQgdGltZTsKCglpZiAoIWluX25taSgpKSB7CgkJdXBkYXRlX2NvbnRleHRfdGltZShjb3VudGVyLT5jdHgpOwoJCXRpbWUgPSBjb3VudGVyLT5jdHgtPnRpbWU7Cgl9IGVsc2UgewoJCXU2NCBub3cgPSBwZXJmX2Nsb2NrKCk7CgkJdTY0IGRlbHRhID0gbm93IC0gY291bnRlci0+Y3R4LT50aW1lc3RhbXA7CgkJdGltZSA9IGNvdW50ZXItPmN0eC0+dGltZSArIGRlbHRhOwoJfQoKCXRhc2tfY2xvY2tfcGVyZl9jb3VudGVyX3VwZGF0ZShjb3VudGVyLCB0aW1lKTsKfQoKc3RhdGljIGNvbnN0IHN0cnVjdCBwbXUgcGVyZl9vcHNfdGFza19jbG9jayA9IHsKCS5lbmFibGUJCT0gdGFza19jbG9ja19wZXJmX2NvdW50ZXJfZW5hYmxlLAoJLmRpc2FibGUJPSB0YXNrX2Nsb2NrX3BlcmZfY291bnRlcl9kaXNhYmxlLAoJLnJlYWQJCT0gdGFza19jbG9ja19wZXJmX2NvdW50ZXJfcmVhZCwKfTsKCiNpZmRlZiBDT05GSUdfRVZFTlRfUFJPRklMRQp2b2lkIHBlcmZfdHBjb3VudGVyX2V2ZW50KGludCBldmVudF9pZCkKewoJc3RydWN0IHBlcmZfc2FtcGxlX2RhdGEgZGF0YSA9IHsKCQkucmVncyA9IGdldF9pcnFfcmVncygpOwoJCS5hZGRyID0gMCwKCX07CgoJaWYgKCFkYXRhLnJlZ3MpCgkJZGF0YS5yZWdzID0gdGFza19wdF9yZWdzKGN1cnJlbnQpOwoKCWRvX3BlcmZfc3djb3VudGVyX2V2ZW50KFBFUkZfVFlQRV9UUkFDRVBPSU5ULCBldmVudF9pZCwgMSwgMSwgJmRhdGEpOwp9CkVYUE9SVF9TWU1CT0xfR1BMKHBlcmZfdHBjb3VudGVyX2V2ZW50KTsKCmV4dGVybiBpbnQgZnRyYWNlX3Byb2ZpbGVfZW5hYmxlKGludCk7CmV4dGVybiB2b2lkIGZ0cmFjZV9wcm9maWxlX2Rpc2FibGUoaW50KTsKCnN0YXRpYyB2b2lkIHRwX3BlcmZfY291bnRlcl9kZXN0cm95KHN0cnVjdCBwZXJmX2NvdW50ZXIgKmNvdW50ZXIpCnsKCWZ0cmFjZV9wcm9maWxlX2Rpc2FibGUocGVyZl9ldmVudF9pZCgmY291bnRlci0+YXR0cikpOwp9CgpzdGF0aWMgY29uc3Qgc3RydWN0IHBtdSAqdHBfcGVyZl9jb3VudGVyX2luaXQoc3RydWN0IHBlcmZfY291bnRlciAqY291bnRlcikKewoJaW50IGV2ZW50X2lkID0gcGVyZl9ldmVudF9pZCgmY291bnRlci0+YXR0cik7CglpbnQgcmV0OwoKCXJldCA9IGZ0cmFjZV9wcm9maWxlX2VuYWJsZShldmVudF9pZCk7CglpZiAocmV0KQoJCXJldHVybiBOVUxMOwoKCWNvdW50ZXItPmRlc3Ryb3kgPSB0cF9wZXJmX2NvdW50ZXJfZGVzdHJveTsKCglyZXR1cm4gJnBlcmZfb3BzX2dlbmVyaWM7Cn0KI2Vsc2UKc3RhdGljIGNvbnN0IHN0cnVjdCBwbXUgKnRwX3BlcmZfY291bnRlcl9pbml0KHN0cnVjdCBwZXJmX2NvdW50ZXIgKmNvdW50ZXIpCnsKCXJldHVybiBOVUxMOwp9CiNlbmRpZgoKYXRvbWljX3QgcGVyZl9zd2NvdW50ZXJfZW5hYmxlZFtQRVJGX0NPVU5UX1NXX01BWF07CgpzdGF0aWMgdm9pZCBzd19wZXJmX2NvdW50ZXJfZGVzdHJveShzdHJ1Y3QgcGVyZl9jb3VudGVyICpjb3VudGVyKQp7Cgl1NjQgZXZlbnQgPSBjb3VudGVyLT5hdHRyLmNvbmZpZzsKCglXQVJOX09OKGNvdW50ZXItPnBhcmVudCk7CgoJYXRvbWljX2RlYygmcGVyZl9zd2NvdW50ZXJfZW5hYmxlZFtldmVudF0pOwp9CgpzdGF0aWMgY29uc3Qgc3RydWN0IHBtdSAqc3dfcGVyZl9jb3VudGVyX2luaXQoc3RydWN0IHBlcmZfY291bnRlciAqY291bnRlcikKewoJY29uc3Qgc3RydWN0IHBtdSAqcG11ID0gTlVMTDsKCXU2NCBldmVudCA9IGNvdW50ZXItPmF0dHIuY29uZmlnOwoKCS8qCgkgKiBTb2Z0d2FyZSBjb3VudGVycyAoY3VycmVudGx5KSBjYW4ndCBpbiBnZW5lcmFsIGRpc3Rpbmd1aXNoCgkgKiBiZXR3ZWVuIHVzZXIsIGtlcm5lbCBhbmQgaHlwZXJ2aXNvciBldmVudHMuCgkgKiBIb3dldmVyLCBjb250ZXh0IHN3aXRjaGVzIGFuZCBjcHUgbWlncmF0aW9ucyBhcmUgY29uc2lkZXJlZAoJICogdG8gYmUga2VybmVsIGV2ZW50cywgYW5kIHBhZ2UgZmF1bHRzIGFyZSBuZXZlciBoeXBlcnZpc29yCgkgKiBldmVudHMuCgkgKi8KCXN3aXRjaCAoZXZlbnQpIHsKCWNhc2UgUEVSRl9DT1VOVF9TV19DUFVfQ0xPQ0s6CgkJcG11ID0gJnBlcmZfb3BzX2NwdV9jbG9jazsKCgkJYnJlYWs7CgljYXNlIFBFUkZfQ09VTlRfU1dfVEFTS19DTE9DSzoKCQkvKgoJCSAqIElmIHRoZSB1c2VyIGluc3RhbnRpYXRlcyB0aGlzIGFzIGEgcGVyLWNwdSBjb3VudGVyLAoJCSAqIHVzZSB0aGUgY3B1X2Nsb2NrIGNvdW50ZXIgaW5zdGVhZC4KCQkgKi8KCQlpZiAoY291bnRlci0+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+cGVyZl9jb3VudGVyX2N0eHA7CglfX3BlcmZfY291bnRlcl90YXNrX3NjaGVkX291dChjaGlsZF9jdHgpOwoKCS8qCgkgKiBUYWtlIHRoZSBjb250ZXh0IGxvY2sgaGVyZSBzbyB0aGF0IGlmIGZpbmRfZ2V0X2NvbnRleHQgaXMKCSAqIHJlYWRpbmcgY2hpbGQtPnBlcmZfY291bnRlcl9jdHhwLCB3ZSB3YWl0IHVudGlsIGl0IGhhcwoJICogaW5jcmVtZW50ZWQgdGhlIGNvbnRleHQncyByZWZjb3VudCBiZWZvcmUgd2UgZG8gcHV0X2N0eCBiZWxvdy4KCSAqLwoJc3Bpbl9sb2NrKCZjaGlsZF9jdHgtPmxvY2spOwoJY2hpbGQtPnBlcmZfY291bnRlcl9jdHhwID0gTlVMTDsKCWlmIChjaGlsZF9jdHgtPnBhcmVudF9jdHgpIHsKCQkvKgoJCSAqIFRoaXMgY29udGV4dCBpcyBhIGNsb25lOyB1bmNsb25lIGl0IHNvIGl0IGNhbid0IGdldAoJCSAqIHN3YXBwZWQgdG8gYW5vdGhlciBwcm9jZXNzIHdoaWxlIHdlJ3JlIHJlbW92aW5nIGFsbAoJCSAqIHRoZSBjb3VudGVycyBmcm9tIGl0LgoJCSAqLwoJCXB1dF9jdHgoY2hpbGRfY3R4LT5wYXJlbnRfY3R4KTsKCQljaGlsZF9jdHgtPnBhcmVudF9jdHggPSBOVUxMOwoJfQoJc3Bpbl91bmxvY2soJmNoaWxkX2N0eC0+bG9jayk7Cglsb2NhbF9pcnFfcmVzdG9yZShmbGFncyk7CgoJLyoKCSAqIFdlIGNhbiByZWN1cnNlIG9uIHRoZSBzYW1lIGxvY2sgdHlwZSB0aHJvdWdoOgoJICoKCSAqICAgX19wZXJmX2NvdW50ZXJfZXhpdF90YXNrKCkKCSAqICAgICBzeW5jX2NoaWxkX2NvdW50ZXIoKQoJICogICAgICAgZnB1dChwYXJlbnRfY291bnRlci0+ZmlscCkKCSAqICAgICAgICAgcGVyZl9yZWxlYXNlKCkKCSAqICAgICAgICAgICBtdXRleF9sb2NrKCZjdHgtPm11dGV4KQoJICoKCSAqIEJ1dCBzaW5jZSBpdHMgdGhlIHBhcmVudCBjb250ZXh0IGl0IHdvbid0IGJlIHRoZSBzYW1lIGluc3RhbmNlLgoJICovCgltdXRleF9sb2NrX25lc3RlZCgmY2hpbGRfY3R4LT5tdXRleCwgU0lOR0xFX0RFUFRIX05FU1RJTkcpOwoKYWdhaW46CglsaXN0X2Zvcl9lYWNoX2VudHJ5X3NhZmUoY2hpbGRfY291bnRlciwgdG1wLCAmY2hpbGRfY3R4LT5jb3VudGVyX2xpc3QsCgkJCQkgbGlzdF9lbnRyeSkKCQlfX3BlcmZfY291bnRlcl9leGl0X3Rhc2soY2hpbGRfY291bnRlciwgY2hpbGRfY3R4LCBjaGlsZCk7CgoJLyoKCSAqIElmIHRoZSBsYXN0IGNvdW50ZXIgd2FzIGEgZ3JvdXAgY291bnRlciwgaXQgd2lsbCBoYXZlIGFwcGVuZGVkIGFsbAoJICogaXRzIHNpYmxpbmdzIHRvIHRoZSBsaXN0LCBidXQgd2Ugb2J0YWluZWQgJ3RtcCcgYmVmb3JlIHRoYXQgd2hpY2gKCSAqIHdpbGwgc3RpbGwgcG9pbnQgdG8gdGhlIGxpc3QgaGVhZCB0ZXJtaW5hdGluZyB0aGUgaXRlcmF0aW9uLgoJICovCglpZiAoIWxpc3RfZW1wdHkoJmNoaWxkX2N0eC0+Y291bnRlcl9saXN0KSkKCQlnb3RvIGFnYWluOwoKCW11dGV4X3VubG9jaygmY2hpbGRfY3R4LT5tdXRleCk7CgoJcHV0X2N0eChjaGlsZF9jdHgpOwp9CgovKgogKiBmcmVlIGFuIHVuZXhwb3NlZCwgdW51c2VkIGNvbnRleHQgYXMgY3JlYXRlZCBieSBpbmhlcml0YW5jZSBieQogKiBpbml0X3Rhc2sgYmVsb3csIHVzZWQgYnkgZm9yaygpIGluIGNhc2Ugb2YgZmFpbC4KICovCnZvaWQgcGVyZl9jb3VudGVyX2ZyZWVfdGFzayhzdHJ1Y3QgdGFza19zdHJ1Y3QgKnRhc2spCnsKCXN0cnVjdCBwZXJmX2NvdW50ZXJfY29udGV4dCAqY3R4ID0gdGFzay0+cGVyZl9jb3VudGVyX2N0eHA7CglzdHJ1Y3QgcGVyZl9jb3VudGVyICpjb3VudGVyLCAqdG1wOwoKCWlmICghY3R4KQoJCXJldHVybjsKCgltdXRleF9sb2NrKCZjdHgtPm11dGV4KTsKYWdhaW46CglsaXN0X2Zvcl9lYWNoX2VudHJ5X3NhZmUoY291bnRlciwgdG1wLCAmY3R4LT5jb3VudGVyX2xpc3QsIGxpc3RfZW50cnkpIHsKCQlzdHJ1Y3QgcGVyZl9jb3VudGVyICpwYXJlbnQgPSBjb3VudGVyLT5wYXJlbnQ7CgoJCWlmIChXQVJOX09OX09OQ0UoIXBhcmVudCkpCgkJCWNvbnRpbnVlOwoKCQltdXRleF9sb2NrKCZwYXJlbnQtPmNoaWxkX211dGV4KTsKCQlsaXN0X2RlbF9pbml0KCZjb3VudGVyLT5jaGlsZF9saXN0KTsKCQltdXRleF91bmxvY2soJnBhcmVudC0+Y2hpbGRfbXV0ZXgpOwoKCQlmcHV0KHBhcmVudC0+ZmlscCk7CgoJCWxpc3RfZGVsX2NvdW50ZXIoY291bnRlciwgY3R4KTsKCQlmcmVlX2NvdW50ZXIoY291bnRlcik7Cgl9CgoJaWYgKCFsaXN0X2VtcHR5KCZjdHgtPmNvdW50ZXJfbGlzdCkpCgkJZ290byBhZ2FpbjsKCgltdXRleF91bmxvY2soJmN0eC0+bXV0ZXgpOwoKCXB1dF9jdHgoY3R4KTsKfQoKLyoKICogSW5pdGlhbGl6ZSB0aGUgcGVyZl9jb3VudGVyIGNvbnRleHQgaW4gdGFza19zdHJ1Y3QKICovCmludCBwZXJmX2NvdW50ZXJfaW5pdF90YXNrKHN0cnVjdCB0YXNrX3N0cnVjdCAqY2hpbGQpCnsKCXN0cnVjdCBwZXJmX2NvdW50ZXJfY29udGV4dCAqY2hpbGRfY3R4LCAqcGFyZW50X2N0eDsKCXN0cnVjdCBwZXJmX2NvdW50ZXJfY29udGV4dCAqY2xvbmVkX2N0eDsKCXN0cnVjdCBwZXJmX2NvdW50ZXIgKmNvdW50ZXI7CglzdHJ1Y3QgdGFza19zdHJ1Y3QgKnBhcmVudCA9IGN1cnJlbnQ7CglpbnQgaW5oZXJpdGVkX2FsbCA9IDE7CglpbnQgcmV0ID0gMDsKCgljaGlsZC0+cGVyZl9jb3VudGVyX2N0eHAgPSBOVUxMOwoKCW11dGV4X2luaXQoJmNoaWxkLT5wZXJmX2NvdW50ZXJfbXV0ZXgpOwoJSU5JVF9MSVNUX0hFQUQoJmNoaWxkLT5wZXJmX2NvdW50ZXJfbGlzdCk7CgoJaWYgKGxpa2VseSghcGFyZW50LT5wZXJmX2NvdW50ZXJfY3R4cCkpCgkJcmV0dXJuIDA7CgoJLyoKCSAqIFRoaXMgaXMgZXhlY3V0ZWQgZnJvbSB0aGUgcGFyZW50IHRhc2sgY29udGV4dCwgc28gaW5oZXJpdAoJICogY291bnRlcnMgdGhhdCBoYXZlIGJlZW4gbWFya2VkIGZvciBjbG9uaW5nLgoJICogRmlyc3QgYWxsb2NhdGUgYW5kIGluaXRpYWxpemUgYSBjb250ZXh0IGZvciB0aGUgY2hpbGQuCgkgKi8KCgljaGlsZF9jdHggPSBrbWFsbG9jKHNpemVvZihzdHJ1Y3QgcGVyZl9jb3VudGVyX2NvbnRleHQpLCBHRlBfS0VSTkVMKTsKCWlmICghY2hpbGRfY3R4KQoJCXJldHVybiAtRU5PTUVNOwoKCV9fcGVyZl9jb3VudGVyX2luaXRfY29udGV4dChjaGlsZF9jdHgsIGNoaWxkKTsKCWNoaWxkLT5wZXJmX2NvdW50ZXJfY3R4cCA9IGNoaWxkX2N0eDsKCWdldF90YXNrX3N0cnVjdChjaGlsZCk7CgoJLyoKCSAqIElmIHRoZSBwYXJlbnQncyBjb250ZXh0IGlzIGEgY2xvbmUsIHBpbiBpdCBzbyBpdCB3b24ndCBnZXQKCSAqIHN3YXBwZWQgdW5kZXIgdXMuCgkgKi8KCXBhcmVudF9jdHggPSBwZXJmX3Bpbl90YXNrX2NvbnRleHQocGFyZW50KTsKCgkvKgoJICogTm8gbmVlZCB0byBjaGVjayBpZiBwYXJlbnRfY3R4ICE9IE5VTEwgaGVyZTsgc2luY2Ugd2Ugc2F3CgkgKiBpdCBub24tTlVMTCBlYXJsaWVyLCB0aGUgb25seSByZWFzb24gZm9yIGl0IHRvIGJlY29tZSBOVUxMCgkgKiBpcyBpZiB3ZSBleGl0LCBhbmQgc2luY2Ugd2UncmUgY3VycmVudGx5IGluIHRoZSBtaWRkbGUgb2YKCSAqIGEgZm9yayB3ZSBjYW4ndCBiZSBleGl0aW5nIGF0IHRoZSBzYW1lIHRpbWUuCgkgKi8KCgkvKgoJICogTG9jayB0aGUgcGFyZW50IGxpc3QuIE5vIG5lZWQgdG8gbG9jayB0aGUgY2hpbGQgLSBub3QgUElECgkgKiBoYXNoZWQgeWV0IGFuZCBub3QgcnVubmluZywgc28gbm9ib2R5IGNhbiBhY2Nlc3MgaXQuCgkgKi8KCW11dGV4X2xvY2soJnBhcmVudF9jdHgtPm11dGV4KTsKCgkvKgoJICogV2UgZG9udCBoYXZlIHRvIGRpc2FibGUgTk1JcyAtIHdlIGFyZSBvbmx5IGxvb2tpbmcgYXQKCSAqIHRoZSBsaXN0LCBub3QgbWFuaXB1bGF0aW5nIGl0OgoJICovCglsaXN0X2Zvcl9lYWNoX2VudHJ5X3JjdShjb3VudGVyLCAmcGFyZW50X2N0eC0+ZXZlbnRfbGlzdCwgZXZlbnRfZW50cnkpIHsKCQlpZiAoY291bnRlciAhPSBjb3VudGVyLT5ncm91cF9sZWFkZXIpCgkJCWNvbnRpbnVlOwoKCQlpZiAoIWNvdW50ZXItPmF0dHIuaW5oZXJpdCkgewoJCQlpbmhlcml0ZWRfYWxsID0gMDsKCQkJY29udGludWU7CgkJfQoKCQlyZXQgPSBpbmhlcml0X2dyb3VwKGNvdW50ZXIsIHBhcmVudCwgcGFyZW50X2N0eCwKCQkJCQkgICAgIGNoaWxkLCBjaGlsZF9jdHgpOwoJCWlmIChyZXQpIHsKCQkJaW5oZXJpdGVkX2FsbCA9IDA7CgkJCWJyZWFrOwoJCX0KCX0KCglpZiAoaW5oZXJpdGVkX2FsbCkgewoJCS8qCgkJICogTWFyayB0aGUgY2hpbGQgY29udGV4dCBhcyBhIGNsb25lIG9mIHRoZSBwYXJlbnQKCQkgKiBjb250ZXh0LCBvciBvZiB3aGF0ZXZlciB0aGUgcGFyZW50IGlzIGEgY2xvbmUgb2YuCgkJICogTm90ZSB0aGF0IGlmIHRoZSBwYXJlbnQgaXMgYSBjbG9uZSwgaXQgY291bGQgZ2V0CgkJICogdW5jbG9uZWQgYXQgYW55IHBvaW50LCBidXQgdGhhdCBkb2Vzbid0IG1hdHRlcgoJCSAqIGJlY2F1c2UgdGhlIGxpc3Qgb2YgY291bnRlcnMgYW5kIHRoZSBnZW5lcmF0aW9uCgkJICogY291bnQgY2FuJ3QgaGF2ZSBjaGFuZ2VkIHNpbmNlIHdlIHRvb2sgdGhlIG11dGV4LgoJCSAqLwoJCWNsb25lZF9jdHggPSByY3VfZGVyZWZlcmVuY2UocGFyZW50X2N0eC0+cGFyZW50X2N0eCk7CgkJaWYgKGNsb25lZF9jdHgpIHsKCQkJY2hpbGRfY3R4LT5wYXJlbnRfY3R4ID0gY2xvbmVkX2N0eDsKCQkJY2hpbGRfY3R4LT5wYXJlbnRfZ2VuID0gcGFyZW50X2N0eC0+cGFyZW50X2dlbjsKCQl9IGVsc2UgewoJCQljaGlsZF9jdHgtPnBhcmVudF9jdHggPSBwYXJlbnRfY3R4OwoJCQljaGlsZF9jdHgtPnBhcmVudF9nZW4gPSBwYXJlbnRfY3R4LT5nZW5lcmF0aW9uOwoJCX0KCQlnZXRfY3R4KGNoaWxkX2N0eC0+cGFyZW50X2N0eCk7Cgl9CgoJbXV0ZXhfdW5sb2NrKCZwYXJlbnRfY3R4LT5tdXRleCk7CgoJcGVyZl91bnBpbl9jb250ZXh0KHBhcmVudF9jdHgpOwoKCXJldHVybiByZXQ7Cn0KCnN0YXRpYyB2b2lkIF9fY3B1aW5pdCBwZXJmX2NvdW50ZXJfaW5pdF9jcHUoaW50IGNwdSkKewoJc3RydWN0IHBlcmZfY3B1X2NvbnRleHQgKmNwdWN0eDsKCgljcHVjdHggPSAmcGVyX2NwdShwZXJmX2NwdV9jb250ZXh0LCBjcHUpOwoJX19wZXJmX2NvdW50ZXJfaW5pdF9jb250ZXh0KCZjcHVjdHgtPmN0eCwgTlVMTCk7CgoJc3Bpbl9sb2NrKCZwZXJmX3Jlc291cmNlX2xvY2spOwoJY3B1Y3R4LT5tYXhfcGVydGFzayA9IHBlcmZfbWF4X2NvdW50ZXJzIC0gcGVyZl9yZXNlcnZlZF9wZXJjcHU7CglzcGluX3VubG9jaygmcGVyZl9yZXNvdXJjZV9sb2NrKTsKCglod19wZXJmX2NvdW50ZXJfc2V0dXAoY3B1KTsKfQoKI2lmZGVmIENPTkZJR19IT1RQTFVHX0NQVQpzdGF0aWMgdm9pZCBfX3BlcmZfY291bnRlcl9leGl0X2NwdSh2b2lkICppbmZvKQp7CglzdHJ1Y3QgcGVyZl9jcHVfY29udGV4dCAqY3B1Y3R4ID0gJl9fZ2V0X2NwdV92YXIocGVyZl9jcHVfY29udGV4dCk7CglzdHJ1Y3QgcGVyZl9jb3VudGVyX2NvbnRleHQgKmN0eCA9ICZjcHVjdHgtPmN0eDsKCXN0cnVjdCBwZXJmX2NvdW50ZXIgKmNvdW50ZXIsICp0bXA7CgoJbGlzdF9mb3JfZWFjaF9lbnRyeV9zYWZlKGNvdW50ZXIsIHRtcCwgJmN0eC0+Y291bnRlcl9saXN0LCBsaXN0X2VudHJ5KQoJCV9fcGVyZl9jb3VudGVyX3JlbW92ZV9mcm9tX2NvbnRleHQoY291bnRlcik7Cn0Kc3RhdGljIHZvaWQgcGVyZl9jb3VudGVyX2V4aXRfY3B1KGludCBjcHUpCnsKCXN0cnVjdCBwZXJmX2NwdV9jb250ZXh0ICpjcHVjdHggPSAmcGVyX2NwdShwZXJmX2NwdV9jb250ZXh0LCBjcHUpOwoJc3RydWN0IHBlcmZfY291bnRlcl9jb250ZXh0ICpjdHggPSAmY3B1Y3R4LT5jdHg7CgoJbXV0ZXhfbG9jaygmY3R4LT5tdXRleCk7CglzbXBfY2FsbF9mdW5jdGlvbl9zaW5nbGUoY3B1LCBfX3BlcmZfY291bnRlcl9leGl0X2NwdSwgTlVMTCwgMSk7CgltdXRleF91bmxvY2soJmN0eC0+bXV0ZXgpOwp9CiNlbHNlCnN0YXRpYyBpbmxpbmUgdm9pZCBwZXJmX2NvdW50ZXJfZXhpdF9jcHUoaW50IGNwdSkgeyB9CiNlbmRpZgoKc3RhdGljIGludCBfX2NwdWluaXQKcGVyZl9jcHVfbm90aWZ5KHN0cnVjdCBub3RpZmllcl9ibG9jayAqc2VsZiwgdW5zaWduZWQgbG9uZyBhY3Rpb24sIHZvaWQgKmhjcHUpCnsKCXVuc2lnbmVkIGludCBjcHUgPSAobG9uZyloY3B1OwoKCXN3aXRjaCAoYWN0aW9uKSB7CgoJY2FzZSBDUFVfVVBfUFJFUEFSRToKCWNhc2UgQ1BVX1VQX1BSRVBBUkVfRlJPWkVOOgoJCXBlcmZfY291bnRlcl9pbml0X2NwdShjcHUpOwoJCWJyZWFrOwoKCWNhc2UgQ1BVX0RPV05fUFJFUEFSRToKCWNhc2UgQ1BVX0RPV05fUFJFUEFSRV9GUk9aRU46CgkJcGVyZl9jb3VudGVyX2V4aXRfY3B1KGNwdSk7CgkJYnJlYWs7CgoJZGVmYXVsdDoKCQlicmVhazsKCX0KCglyZXR1cm4gTk9USUZZX09LOwp9CgovKgogKiBUaGlzIGhhcyB0byBoYXZlIGEgaGlnaGVyIHByaW9yaXR5IHRoYW4gbWlncmF0aW9uX25vdGlmaWVyIGluIHNjaGVkLmMuCiAqLwpzdGF0aWMgc3RydWN0IG5vdGlmaWVyX2Jsb2NrIF9fY3B1aW5pdGRhdGEgcGVyZl9jcHVfbmIgPSB7Cgkubm90aWZpZXJfY2FsbAkJPSBwZXJmX2NwdV9ub3RpZnksCgkucHJpb3JpdHkJCT0gMjAsCn07Cgp2b2lkIF9faW5pdCBwZXJmX2NvdW50ZXJfaW5pdCh2b2lkKQp7CglwZXJmX2NwdV9ub3RpZnkoJnBlcmZfY3B1X25iLCAodW5zaWduZWQgbG9uZylDUFVfVVBfUFJFUEFSRSwKCQkJKHZvaWQgKikobG9uZylzbXBfcHJvY2Vzc29yX2lkKCkpOwoJcmVnaXN0ZXJfY3B1X25vdGlmaWVyKCZwZXJmX2NwdV9uYik7Cn0KCnN0YXRpYyBzc2l6ZV90IHBlcmZfc2hvd19yZXNlcnZlX3BlcmNwdShzdHJ1Y3Qgc3lzZGV2X2NsYXNzICpjbGFzcywgY2hhciAqYnVmKQp7CglyZXR1cm4gc3ByaW50ZihidWYsICIlZFxuIiwgcGVyZl9yZXNlcnZlZF9wZXJjcHUpOwp9CgpzdGF0aWMgc3NpemVfdApwZXJmX3NldF9yZXNlcnZlX3BlcmNwdShzdHJ1Y3Qgc3lzZGV2X2NsYXNzICpjbGFzcywKCQkJY29uc3QgY2hhciAqYnVmLAoJCQlzaXplX3QgY291bnQpCnsKCXN0cnVjdCBwZXJmX2NwdV9jb250ZXh0ICpjcHVjdHg7Cgl1bnNpZ25lZCBsb25nIHZhbDsKCWludCBlcnIsIGNwdSwgbXB0OwoKCWVyciA9IHN0cmljdF9zdHJ0b3VsKGJ1ZiwgMTAsICZ2YWwpOwoJaWYgKGVycikKCQlyZXR1cm4gZXJyOwoJaWYgKHZhbCA+IHBlcmZfbWF4X2NvdW50ZXJzKQoJCXJldHVybiAtRUlOVkFMOwoKCXNwaW5fbG9jaygmcGVyZl9yZXNvdXJjZV9sb2NrKTsKCXBlcmZfcmVzZXJ2ZWRfcGVyY3B1ID0gdmFsOwoJZm9yX2VhY2hfb25saW5lX2NwdShjcHUpIHsKCQljcHVjdHggPSAmcGVyX2NwdShwZXJmX2NwdV9jb250ZXh0LCBjcHUpOwoJCXNwaW5fbG9ja19pcnEoJmNwdWN0eC0+Y3R4LmxvY2spOwoJCW1wdCA9IG1pbihwZXJmX21heF9jb3VudGVycyAtIGNwdWN0eC0+Y3R4Lm5yX2NvdW50ZXJzLAoJCQkgIHBlcmZfbWF4X2NvdW50ZXJzIC0gcGVyZl9yZXNlcnZlZF9wZXJjcHUpOwoJCWNwdWN0eC0+bWF4X3BlcnRhc2sgPSBtcHQ7CgkJc3Bpbl91bmxvY2tfaXJxKCZjcHVjdHgtPmN0eC5sb2NrKTsKCX0KCXNwaW5fdW5sb2NrKCZwZXJmX3Jlc291cmNlX2xvY2spOwoKCXJldHVybiBjb3VudDsKfQoKc3RhdGljIHNzaXplX3QgcGVyZl9zaG93X292ZXJjb21taXQoc3RydWN0IHN5c2Rldl9jbGFzcyAqY2xhc3MsIGNoYXIgKmJ1ZikKewoJcmV0dXJuIHNwcmludGYoYnVmLCAiJWRcbiIsIHBlcmZfb3ZlcmNvbW1pdCk7Cn0KCnN0YXRpYyBzc2l6ZV90CnBlcmZfc2V0X292ZXJjb21taXQoc3RydWN0IHN5c2Rldl9jbGFzcyAqY2xhc3MsIGNvbnN0IGNoYXIgKmJ1Ziwgc2l6ZV90IGNvdW50KQp7Cgl1bnNpZ25lZCBsb25nIHZhbDsKCWludCBlcnI7CgoJZXJyID0gc3RyaWN0X3N0cnRvdWwoYnVmLCAxMCwgJnZhbCk7CglpZiAoZXJyKQoJCXJldHVybiBlcnI7CglpZiAodmFsID4gMSkKCQlyZXR1cm4gLUVJTlZBTDsKCglzcGluX2xvY2soJnBlcmZfcmVzb3VyY2VfbG9jayk7CglwZXJmX292ZXJjb21taXQgPSB2YWw7CglzcGluX3VubG9jaygmcGVyZl9yZXNvdXJjZV9sb2NrKTsKCglyZXR1cm4gY291bnQ7Cn0KCnN0YXRpYyBTWVNERVZfQ0xBU1NfQVRUUigKCQkJCXJlc2VydmVfcGVyY3B1LAoJCQkJMDY0NCwKCQkJCXBlcmZfc2hvd19yZXNlcnZlX3BlcmNwdSwKCQkJCXBlcmZfc2V0X3Jlc2VydmVfcGVyY3B1CgkJCSk7CgpzdGF0aWMgU1lTREVWX0NMQVNTX0FUVFIoCgkJCQlvdmVyY29tbWl0LAoJCQkJMDY0NCwKCQkJCXBlcmZfc2hvd19vdmVyY29tbWl0LAoJCQkJcGVyZl9zZXRfb3ZlcmNvbW1pdAoJCQkpOwoKc3RhdGljIHN0cnVjdCBhdHRyaWJ1dGUgKnBlcmZjbGFzc19hdHRyc1tdID0gewoJJmF0dHJfcmVzZXJ2ZV9wZXJjcHUuYXR0ciwKCSZhdHRyX292ZXJjb21taXQuYXR0ciwKCU5VTEwKfTsKCnN0YXRpYyBzdHJ1Y3QgYXR0cmlidXRlX2dyb3VwIHBlcmZjbGFzc19hdHRyX2dyb3VwID0gewoJLmF0dHJzCQkJPSBwZXJmY2xhc3NfYXR0cnMsCgkubmFtZQkJCT0gInBlcmZfY291bnRlcnMiLAp9OwoKc3RhdGljIGludCBfX2luaXQgcGVyZl9jb3VudGVyX3N5c2ZzX2luaXQodm9pZCkKewoJcmV0dXJuIHN5c2ZzX2NyZWF0ZV9ncm91cCgmY3B1X3N5c2Rldl9jbGFzcy5rc2V0LmtvYmosCgkJCQkgICZwZXJmY2xhc3NfYXR0cl9ncm91cCk7Cn0KZGV2aWNlX2luaXRjYWxsKHBlcmZfY291bnRlcl9zeXNmc19pbml0KTsK