LyoKICogUGVyZm9ybWFuY2UgZXZlbnRzIGNvcmUgY29kZToKICoKICogIENvcHlyaWdodCAoQykgMjAwOCBUaG9tYXMgR2xlaXhuZXIgPHRnbHhAbGludXRyb25peC5kZT4KICogIENvcHlyaWdodCAoQykgMjAwOC0yMDA5IFJlZCBIYXQsIEluYy4sIEluZ28gTW9sbmFyCiAqICBDb3B5cmlnaHQgKEMpIDIwMDgtMjAwOSBSZWQgSGF0LCBJbmMuLCBQZXRlciBaaWpsc3RyYSA8cHppamxzdHJAcmVkaGF0LmNvbT4KICogIENvcHlyaWdodCAgqSAgMjAwOSBQYXVsIE1hY2tlcnJhcywgSUJNIENvcnAuIDxwYXVsdXNAYXUxLmlibS5jb20+CiAqCiAqIEZvciBsaWNlbnNpbmcgZGV0YWlscyBzZWUga2VybmVsLWJhc2UvQ09QWUlORwogKi8KCiNpbmNsdWRlIDxsaW51eC9mcy5oPgojaW5jbHVkZSA8bGludXgvbW0uaD4KI2luY2x1ZGUgPGxpbnV4L2NwdS5oPgojaW5jbHVkZSA8bGludXgvc21wLmg+CiNpbmNsdWRlIDxsaW51eC9pZHIuaD4KI2luY2x1ZGUgPGxpbnV4L2ZpbGUuaD4KI2luY2x1ZGUgPGxpbnV4L3BvbGwuaD4KI2luY2x1ZGUgPGxpbnV4L3NsYWIuaD4KI2luY2x1ZGUgPGxpbnV4L2hhc2guaD4KI2luY2x1ZGUgPGxpbnV4L3N5c2ZzLmg+CiNpbmNsdWRlIDxsaW51eC9kY2FjaGUuaD4KI2luY2x1ZGUgPGxpbnV4L3BlcmNwdS5oPgojaW5jbHVkZSA8bGludXgvcHRyYWNlLmg+CiNpbmNsdWRlIDxsaW51eC9yZWJvb3QuaD4KI2luY2x1ZGUgPGxpbnV4L3Ztc3RhdC5oPgojaW5jbHVkZSA8bGludXgvZGV2aWNlLmg+CiNpbmNsdWRlIDxsaW51eC92bWFsbG9jLmg+CiNpbmNsdWRlIDxsaW51eC9oYXJkaXJxLmg+CiNpbmNsdWRlIDxsaW51eC9yY3VsaXN0Lmg+CiNpbmNsdWRlIDxsaW51eC91YWNjZXNzLmg+CiNpbmNsdWRlIDxsaW51eC9zeXNjYWxscy5oPgojaW5jbHVkZSA8bGludXgvYW5vbl9pbm9kZXMuaD4KI2luY2x1ZGUgPGxpbnV4L2tlcm5lbF9zdGF0Lmg+CiNpbmNsdWRlIDxsaW51eC9wZXJmX2V2ZW50Lmg+CiNpbmNsdWRlIDxsaW51eC9mdHJhY2VfZXZlbnQuaD4KI2luY2x1ZGUgPGxpbnV4L2h3X2JyZWFrcG9pbnQuaD4KCiNpbmNsdWRlIDxhc20vaXJxX3JlZ3MuaD4KCmVudW0gZXZlbnRfdHlwZV90IHsKCUVWRU5UX0ZMRVhJQkxFID0gMHgxLAoJRVZFTlRfUElOTkVEID0gMHgyLAoJRVZFTlRfQUxMID0gRVZFTlRfRkxFWElCTEUgfCBFVkVOVF9QSU5ORUQsCn07CgphdG9taWNfdCBwZXJmX3Rhc2tfZXZlbnRzIF9fcmVhZF9tb3N0bHk7CnN0YXRpYyBhdG9taWNfdCBucl9tbWFwX2V2ZW50cyBfX3JlYWRfbW9zdGx5OwpzdGF0aWMgYXRvbWljX3QgbnJfY29tbV9ldmVudHMgX19yZWFkX21vc3RseTsKc3RhdGljIGF0b21pY190IG5yX3Rhc2tfZXZlbnRzIF9fcmVhZF9tb3N0bHk7CgpzdGF0aWMgTElTVF9IRUFEKHBtdXMpOwpzdGF0aWMgREVGSU5FX01VVEVYKHBtdXNfbG9jayk7CnN0YXRpYyBzdHJ1Y3Qgc3JjdV9zdHJ1Y3QgcG11c19zcmN1OwoKLyoKICogcGVyZiBldmVudCBwYXJhbm9pYSBsZXZlbDoKICogIC0xIC0gbm90IHBhcmFub2lkIGF0IGFsbAogKiAgIDAgLSBkaXNhbGxvdyByYXcgdHJhY2Vwb2ludCBhY2Nlc3MgZm9yIHVucHJpdgogKiAgIDEgLSBkaXNhbGxvdyBjcHUgZXZlbnRzIGZvciB1bnByaXYKICogICAyIC0gZGlzYWxsb3cga2VybmVsIHByb2ZpbGluZyBmb3IgdW5wcml2CiAqLwppbnQgc3lzY3RsX3BlcmZfZXZlbnRfcGFyYW5vaWQgX19yZWFkX21vc3RseSA9IDE7CgppbnQgc3lzY3RsX3BlcmZfZXZlbnRfbWxvY2sgX19yZWFkX21vc3RseSA9IDUxMjsgLyogJ2ZyZWUnIGtiIHBlciB1c2VyICovCgovKgogKiBtYXggcGVyZiBldmVudCBzYW1wbGUgcmF0ZQogKi8KaW50IHN5c2N0bF9wZXJmX2V2ZW50X3NhbXBsZV9yYXRlIF9fcmVhZF9tb3N0bHkgPSAxMDAwMDA7CgpzdGF0aWMgYXRvbWljNjRfdCBwZXJmX2V2ZW50X2lkOwoKc3RhdGljIHZvaWQgY3B1X2N0eF9zY2hlZF9vdXQoc3RydWN0IHBlcmZfY3B1X2NvbnRleHQgKmNwdWN0eCwKCQkJICAgICAgZW51bSBldmVudF90eXBlX3QgZXZlbnRfdHlwZSk7CgpzdGF0aWMgdm9pZCBjcHVfY3R4X3NjaGVkX2luKHN0cnVjdCBwZXJmX2NwdV9jb250ZXh0ICpjcHVjdHgsCgkJCSAgICAgZW51bSBldmVudF90eXBlX3QgZXZlbnRfdHlwZSk7Cgp2b2lkIF9fd2VhayBwZXJmX2V2ZW50X3ByaW50X2RlYnVnKHZvaWQpCXsgfQoKZXh0ZXJuIF9fd2VhayBjb25zdCBjaGFyICpwZXJmX3BtdV9uYW1lKHZvaWQpCnsKCXJldHVybiAicG11IjsKfQoKc3RhdGljIGlubGluZSB1NjQgcGVyZl9jbG9jayh2b2lkKQp7CglyZXR1cm4gbG9jYWxfY2xvY2soKTsKfQoKdm9pZCBwZXJmX3BtdV9kaXNhYmxlKHN0cnVjdCBwbXUgKnBtdSkKewoJaW50ICpjb3VudCA9IHRoaXNfY3B1X3B0cihwbXUtPnBtdV9kaXNhYmxlX2NvdW50KTsKCWlmICghKCpjb3VudCkrKykKCQlwbXUtPnBtdV9kaXNhYmxlKHBtdSk7Cn0KCnZvaWQgcGVyZl9wbXVfZW5hYmxlKHN0cnVjdCBwbXUgKnBtdSkKewoJaW50ICpjb3VudCA9IHRoaXNfY3B1X3B0cihwbXUtPnBtdV9kaXNhYmxlX2NvdW50KTsKCWlmICghLS0oKmNvdW50KSkKCQlwbXUtPnBtdV9lbmFibGUocG11KTsKfQoKc3RhdGljIERFRklORV9QRVJfQ1BVKHN0cnVjdCBsaXN0X2hlYWQsIHJvdGF0aW9uX2xpc3QpOwoKLyoKICogcGVyZl9wbXVfcm90YXRlX3N0YXJ0KCkgYW5kIHBlcmZfcm90YXRlX2NvbnRleHQoKSBhcmUgZnVsbHkgc2VyaWFsaXplZAogKiBiZWNhdXNlIHRoZXkncmUgc3RyaWN0bHkgY3B1IGFmZmluZSBhbmQgcm90YXRlX3N0YXJ0IGlzIGNhbGxlZCB3aXRoIElSUXMKICogZGlzYWJsZWQsIHdoaWxlIHJvdGF0ZV9jb250ZXh0IGlzIGNhbGxlZCBmcm9tIElSUSBjb250ZXh0LgogKi8Kc3RhdGljIHZvaWQgcGVyZl9wbXVfcm90YXRlX3N0YXJ0KHN0cnVjdCBwbXUgKnBtdSkKewoJc3RydWN0IHBlcmZfY3B1X2NvbnRleHQgKmNwdWN0eCA9IHRoaXNfY3B1X3B0cihwbXUtPnBtdV9jcHVfY29udGV4dCk7CglzdHJ1Y3QgbGlzdF9oZWFkICpoZWFkID0gJl9fZ2V0X2NwdV92YXIocm90YXRpb25fbGlzdCk7CgoJV0FSTl9PTighaXJxc19kaXNhYmxlZCgpKTsKCglpZiAobGlzdF9lbXB0eSgmY3B1Y3R4LT5yb3RhdGlvbl9saXN0KSkKCQlsaXN0X2FkZCgmY3B1Y3R4LT5yb3RhdGlvbl9saXN0LCBoZWFkKTsKfQoKc3RhdGljIHZvaWQgZ2V0X2N0eChzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0ICpjdHgpCnsKCVdBUk5fT04oIWF0b21pY19pbmNfbm90X3plcm8oJmN0eC0+cmVmY291bnQpKTsKfQoKc3RhdGljIHZvaWQgZnJlZV9jdHgoc3RydWN0IHJjdV9oZWFkICpoZWFkKQp7CglzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0ICpjdHg7CgoJY3R4ID0gY29udGFpbmVyX29mKGhlYWQsIHN0cnVjdCBwZXJmX2V2ZW50X2NvbnRleHQsIHJjdV9oZWFkKTsKCWtmcmVlKGN0eCk7Cn0KCnN0YXRpYyB2b2lkIHB1dF9jdHgoc3RydWN0IHBlcmZfZXZlbnRfY29udGV4dCAqY3R4KQp7CglpZiAoYXRvbWljX2RlY19hbmRfdGVzdCgmY3R4LT5yZWZjb3VudCkpIHsKCQlpZiAoY3R4LT5wYXJlbnRfY3R4KQoJCQlwdXRfY3R4KGN0eC0+cGFyZW50X2N0eCk7CgkJaWYgKGN0eC0+dGFzaykKCQkJcHV0X3Rhc2tfc3RydWN0KGN0eC0+dGFzayk7CgkJY2FsbF9yY3UoJmN0eC0+cmN1X2hlYWQsIGZyZWVfY3R4KTsKCX0KfQoKc3RhdGljIHZvaWQgdW5jbG9uZV9jdHgoc3RydWN0IHBlcmZfZXZlbnRfY29udGV4dCAqY3R4KQp7CglpZiAoY3R4LT5wYXJlbnRfY3R4KSB7CgkJcHV0X2N0eChjdHgtPnBhcmVudF9jdHgpOwoJCWN0eC0+cGFyZW50X2N0eCA9IE5VTEw7Cgl9Cn0KCnN0YXRpYyB1MzIgcGVyZl9ldmVudF9waWQoc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50LCBzdHJ1Y3QgdGFza19zdHJ1Y3QgKnApCnsKCS8qCgkgKiBvbmx5IHRvcCBsZXZlbCBldmVudHMgaGF2ZSB0aGUgcGlkIG5hbWVzcGFjZSB0aGV5IHdlcmUgY3JlYXRlZCBpbgoJICovCglpZiAoZXZlbnQtPnBhcmVudCkKCQlldmVudCA9IGV2ZW50LT5wYXJlbnQ7CgoJcmV0dXJuIHRhc2tfdGdpZF9ucl9ucyhwLCBldmVudC0+bnMpOwp9CgpzdGF0aWMgdTMyIHBlcmZfZXZlbnRfdGlkKHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCwgc3RydWN0IHRhc2tfc3RydWN0ICpwKQp7CgkvKgoJICogb25seSB0b3AgbGV2ZWwgZXZlbnRzIGhhdmUgdGhlIHBpZCBuYW1lc3BhY2UgdGhleSB3ZXJlIGNyZWF0ZWQgaW4KCSAqLwoJaWYgKGV2ZW50LT5wYXJlbnQpCgkJZXZlbnQgPSBldmVudC0+cGFyZW50OwoKCXJldHVybiB0YXNrX3BpZF9ucl9ucyhwLCBldmVudC0+bnMpOwp9CgovKgogKiBJZiB3ZSBpbmhlcml0IGV2ZW50cyB3ZSB3YW50IHRvIHJldHVybiB0aGUgcGFyZW50IGV2ZW50IGlkCiAqIHRvIHVzZXJzcGFjZS4KICovCnN0YXRpYyB1NjQgcHJpbWFyeV9ldmVudF9pZChzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQpCnsKCXU2NCBpZCA9IGV2ZW50LT5pZDsKCglpZiAoZXZlbnQtPnBhcmVudCkKCQlpZCA9IGV2ZW50LT5wYXJlbnQtPmlkOwoKCXJldHVybiBpZDsKfQoKLyoKICogR2V0IHRoZSBwZXJmX2V2ZW50X2NvbnRleHQgZm9yIGEgdGFzayBhbmQgbG9jayBpdC4KICogVGhpcyBoYXMgdG8gY29wZSB3aXRoIHdpdGggdGhlIGZhY3QgdGhhdCB1bnRpbCBpdCBpcyBsb2NrZWQsCiAqIHRoZSBjb250ZXh0IGNvdWxkIGdldCBtb3ZlZCB0byBhbm90aGVyIHRhc2suCiAqLwpzdGF0aWMgc3RydWN0IHBlcmZfZXZlbnRfY29udGV4dCAqCnBlcmZfbG9ja190YXNrX2NvbnRleHQoc3RydWN0IHRhc2tfc3RydWN0ICp0YXNrLCBpbnQgY3R4biwgdW5zaWduZWQgbG9uZyAqZmxhZ3MpCnsKCXN0cnVjdCBwZXJmX2V2ZW50X2NvbnRleHQgKmN0eDsKCglyY3VfcmVhZF9sb2NrKCk7CnJldHJ5OgoJY3R4ID0gcmN1X2RlcmVmZXJlbmNlKHRhc2stPnBlcmZfZXZlbnRfY3R4cFtjdHhuXSk7CglpZiAoY3R4KSB7CgkJLyoKCQkgKiBJZiB0aGlzIGNvbnRleHQgaXMgYSBjbG9uZSBvZiBhbm90aGVyLCBpdCBtaWdodAoJCSAqIGdldCBzd2FwcGVkIGZvciBhbm90aGVyIHVuZGVybmVhdGggdXMgYnkKCQkgKiBwZXJmX2V2ZW50X3Rhc2tfc2NoZWRfb3V0LCB0aG91Z2ggdGhlCgkJICogcmN1X3JlYWRfbG9jaygpIHByb3RlY3RzIHVzIGZyb20gYW55IGNvbnRleHQKCQkgKiBnZXR0aW5nIGZyZWVkLiAgTG9jayB0aGUgY29udGV4dCBhbmQgY2hlY2sgaWYgaXQKCQkgKiBnb3Qgc3dhcHBlZCBiZWZvcmUgd2UgY291bGQgZ2V0IHRoZSBsb2NrLCBhbmQgcmV0cnkKCQkgKiBpZiBzby4gIElmIHdlIGxvY2tlZCB0aGUgcmlnaHQgY29udGV4dCwgdGhlbiBpdAoJCSAqIGNhbid0IGdldCBzd2FwcGVkIG9uIHVzIGFueSBtb3JlLgoJCSAqLwoJCXJhd19zcGluX2xvY2tfaXJxc2F2ZSgmY3R4LT5sb2NrLCAqZmxhZ3MpOwoJCWlmIChjdHggIT0gcmN1X2RlcmVmZXJlbmNlKHRhc2stPnBlcmZfZXZlbnRfY3R4cFtjdHhuXSkpIHsKCQkJcmF3X3NwaW5fdW5sb2NrX2lycXJlc3RvcmUoJmN0eC0+bG9jaywgKmZsYWdzKTsKCQkJZ290byByZXRyeTsKCQl9CgoJCWlmICghYXRvbWljX2luY19ub3RfemVybygmY3R4LT5yZWZjb3VudCkpIHsKCQkJcmF3X3NwaW5fdW5sb2NrX2lycXJlc3RvcmUoJmN0eC0+bG9jaywgKmZsYWdzKTsKCQkJY3R4ID0gTlVMTDsKCQl9Cgl9CglyY3VfcmVhZF91bmxvY2soKTsKCXJldHVybiBjdHg7Cn0KCi8qCiAqIEdldCB0aGUgY29udGV4dCBmb3IgYSB0YXNrIGFuZCBpbmNyZW1lbnQgaXRzIHBpbl9jb3VudCBzbyBpdAogKiBjYW4ndCBnZXQgc3dhcHBlZCB0byBhbm90aGVyIHRhc2suICBUaGlzIGFsc28gaW5jcmVtZW50cyBpdHMKICogcmVmZXJlbmNlIGNvdW50IHNvIHRoYXQgdGhlIGNvbnRleHQgY2FuJ3QgZ2V0IGZyZWVkLgogKi8Kc3RhdGljIHN0cnVjdCBwZXJmX2V2ZW50X2NvbnRleHQgKgpwZXJmX3Bpbl90YXNrX2NvbnRleHQoc3RydWN0IHRhc2tfc3RydWN0ICp0YXNrLCBpbnQgY3R4bikKewoJc3RydWN0IHBlcmZfZXZlbnRfY29udGV4dCAqY3R4OwoJdW5zaWduZWQgbG9uZyBmbGFnczsKCgljdHggPSBwZXJmX2xvY2tfdGFza19jb250ZXh0KHRhc2ssIGN0eG4sICZmbGFncyk7CglpZiAoY3R4KSB7CgkJKytjdHgtPnBpbl9jb3VudDsKCQlyYXdfc3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmY3R4LT5sb2NrLCBmbGFncyk7Cgl9CglyZXR1cm4gY3R4Owp9CgpzdGF0aWMgdm9pZCBwZXJmX3VucGluX2NvbnRleHQoc3RydWN0IHBlcmZfZXZlbnRfY29udGV4dCAqY3R4KQp7Cgl1bnNpZ25lZCBsb25nIGZsYWdzOwoKCXJhd19zcGluX2xvY2tfaXJxc2F2ZSgmY3R4LT5sb2NrLCBmbGFncyk7CgktLWN0eC0+cGluX2NvdW50OwoJcmF3X3NwaW5fdW5sb2NrX2lycXJlc3RvcmUoJmN0eC0+bG9jaywgZmxhZ3MpOwoJcHV0X2N0eChjdHgpOwp9CgovKgogKiBVcGRhdGUgdGhlIHJlY29yZCBvZiB0aGUgY3VycmVudCB0aW1lIGluIGEgY29udGV4dC4KICovCnN0YXRpYyB2b2lkIHVwZGF0ZV9jb250ZXh0X3RpbWUoc3RydWN0IHBlcmZfZXZlbnRfY29udGV4dCAqY3R4KQp7Cgl1NjQgbm93ID0gcGVyZl9jbG9jaygpOwoKCWN0eC0+dGltZSArPSBub3cgLSBjdHgtPnRpbWVzdGFtcDsKCWN0eC0+dGltZXN0YW1wID0gbm93Owp9CgpzdGF0aWMgdTY0IHBlcmZfZXZlbnRfdGltZShzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQpCnsKCXN0cnVjdCBwZXJmX2V2ZW50X2NvbnRleHQgKmN0eCA9IGV2ZW50LT5jdHg7CglyZXR1cm4gY3R4ID8gY3R4LT50aW1lIDogMDsKfQoKLyoKICogVXBkYXRlIHRoZSB0b3RhbF90aW1lX2VuYWJsZWQgYW5kIHRvdGFsX3RpbWVfcnVubmluZyBmaWVsZHMgZm9yIGEgZXZlbnQuCiAqLwpzdGF0aWMgdm9pZCB1cGRhdGVfZXZlbnRfdGltZXMoc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50KQp7CglzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0ICpjdHggPSBldmVudC0+Y3R4OwoJdTY0IHJ1bl9lbmQ7CgoJaWYgKGV2ZW50LT5zdGF0ZSA8IFBFUkZfRVZFTlRfU1RBVEVfSU5BQ1RJVkUgfHwKCSAgICBldmVudC0+Z3JvdXBfbGVhZGVyLT5zdGF0ZSA8IFBFUkZfRVZFTlRfU1RBVEVfSU5BQ1RJVkUpCgkJcmV0dXJuOwoKCWlmIChjdHgtPmlzX2FjdGl2ZSkKCQlydW5fZW5kID0gcGVyZl9ldmVudF90aW1lKGV2ZW50KTsKCWVsc2UKCQlydW5fZW5kID0gZXZlbnQtPnRzdGFtcF9zdG9wcGVkOwoKCWV2ZW50LT50b3RhbF90aW1lX2VuYWJsZWQgPSBydW5fZW5kIC0gZXZlbnQtPnRzdGFtcF9lbmFibGVkOwoKCWlmIChldmVudC0+c3RhdGUgPT0gUEVSRl9FVkVOVF9TVEFURV9JTkFDVElWRSkKCQlydW5fZW5kID0gZXZlbnQtPnRzdGFtcF9zdG9wcGVkOwoJZWxzZQoJCXJ1bl9lbmQgPSBwZXJmX2V2ZW50X3RpbWUoZXZlbnQpOwoKCWV2ZW50LT50b3RhbF90aW1lX3J1bm5pbmcgPSBydW5fZW5kIC0gZXZlbnQtPnRzdGFtcF9ydW5uaW5nOwp9CgovKgogKiBVcGRhdGUgdG90YWxfdGltZV9lbmFibGVkIGFuZCB0b3RhbF90aW1lX3J1bm5pbmcgZm9yIGFsbCBldmVudHMgaW4gYSBncm91cC4KICovCnN0YXRpYyB2b2lkIHVwZGF0ZV9ncm91cF90aW1lcyhzdHJ1Y3QgcGVyZl9ldmVudCAqbGVhZGVyKQp7CglzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQ7CgoJdXBkYXRlX2V2ZW50X3RpbWVzKGxlYWRlcik7CglsaXN0X2Zvcl9lYWNoX2VudHJ5KGV2ZW50LCAmbGVhZGVyLT5zaWJsaW5nX2xpc3QsIGdyb3VwX2VudHJ5KQoJCXVwZGF0ZV9ldmVudF90aW1lcyhldmVudCk7Cn0KCnN0YXRpYyBzdHJ1Y3QgbGlzdF9oZWFkICoKY3R4X2dyb3VwX2xpc3Qoc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50LCBzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0ICpjdHgpCnsKCWlmIChldmVudC0+YXR0ci5waW5uZWQpCgkJcmV0dXJuICZjdHgtPnBpbm5lZF9ncm91cHM7CgllbHNlCgkJcmV0dXJuICZjdHgtPmZsZXhpYmxlX2dyb3VwczsKfQoKLyoKICogQWRkIGEgZXZlbnQgZnJvbSB0aGUgbGlzdHMgZm9yIGl0cyBjb250ZXh0LgogKiBNdXN0IGJlIGNhbGxlZCB3aXRoIGN0eC0+bXV0ZXggYW5kIGN0eC0+bG9jayBoZWxkLgogKi8Kc3RhdGljIHZvaWQKbGlzdF9hZGRfZXZlbnQoc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50LCBzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0ICpjdHgpCnsKCVdBUk5fT05fT05DRShldmVudC0+YXR0YWNoX3N0YXRlICYgUEVSRl9BVFRBQ0hfQ09OVEVYVCk7CglldmVudC0+YXR0YWNoX3N0YXRlIHw9IFBFUkZfQVRUQUNIX0NPTlRFWFQ7CgoJLyoKCSAqIElmIHdlJ3JlIGEgc3RhbmQgYWxvbmUgZXZlbnQgb3IgZ3JvdXAgbGVhZGVyLCB3ZSBnbyB0byB0aGUgY29udGV4dAoJICogbGlzdCwgZ3JvdXAgZXZlbnRzIGFyZSBrZXB0IGF0dGFjaGVkIHRvIHRoZSBncm91cCBzbyB0aGF0CgkgKiBwZXJmX2dyb3VwX2RldGFjaCBjYW4sIGF0IGFsbCB0aW1lcywgbG9jYXRlIGFsbCBzaWJsaW5ncy4KCSAqLwoJaWYgKGV2ZW50LT5ncm91cF9sZWFkZXIgPT0gZXZlbnQpIHsKCQlzdHJ1Y3QgbGlzdF9oZWFkICpsaXN0OwoKCQlpZiAoaXNfc29mdHdhcmVfZXZlbnQoZXZlbnQpKQoJCQlldmVudC0+Z3JvdXBfZmxhZ3MgfD0gUEVSRl9HUk9VUF9TT0ZUV0FSRTsKCgkJbGlzdCA9IGN0eF9ncm91cF9saXN0KGV2ZW50LCBjdHgpOwoJCWxpc3RfYWRkX3RhaWwoJmV2ZW50LT5ncm91cF9lbnRyeSwgbGlzdCk7Cgl9CgoJbGlzdF9hZGRfcmN1KCZldmVudC0+ZXZlbnRfZW50cnksICZjdHgtPmV2ZW50X2xpc3QpOwoJaWYgKCFjdHgtPm5yX2V2ZW50cykKCQlwZXJmX3BtdV9yb3RhdGVfc3RhcnQoY3R4LT5wbXUpOwoJY3R4LT5ucl9ldmVudHMrKzsKCWlmIChldmVudC0+YXR0ci5pbmhlcml0X3N0YXQpCgkJY3R4LT5ucl9zdGF0Kys7Cn0KCi8qCiAqIENhbGxlZCBhdCBwZXJmX2V2ZW50IGNyZWF0aW9uIGFuZCB3aGVuIGV2ZW50cyBhcmUgYXR0YWNoZWQvZGV0YWNoZWQgZnJvbSBhCiAqIGdyb3VwLgogKi8Kc3RhdGljIHZvaWQgcGVyZl9ldmVudF9fcmVhZF9zaXplKHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCkKewoJaW50IGVudHJ5ID0gc2l6ZW9mKHU2NCk7IC8qIHZhbHVlICovCglpbnQgc2l6ZSA9IDA7CglpbnQgbnIgPSAxOwoKCWlmIChldmVudC0+YXR0ci5yZWFkX2Zvcm1hdCAmIFBFUkZfRk9STUFUX1RPVEFMX1RJTUVfRU5BQkxFRCkKCQlzaXplICs9IHNpemVvZih1NjQpOwoKCWlmIChldmVudC0+YXR0ci5yZWFkX2Zvcm1hdCAmIFBFUkZfRk9STUFUX1RPVEFMX1RJTUVfUlVOTklORykKCQlzaXplICs9IHNpemVvZih1NjQpOwoKCWlmIChldmVudC0+YXR0ci5yZWFkX2Zvcm1hdCAmIFBFUkZfRk9STUFUX0lEKQoJCWVudHJ5ICs9IHNpemVvZih1NjQpOwoKCWlmIChldmVudC0+YXR0ci5yZWFkX2Zvcm1hdCAmIFBFUkZfRk9STUFUX0dST1VQKSB7CgkJbnIgKz0gZXZlbnQtPmdyb3VwX2xlYWRlci0+bnJfc2libGluZ3M7CgkJc2l6ZSArPSBzaXplb2YodTY0KTsKCX0KCglzaXplICs9IGVudHJ5ICogbnI7CglldmVudC0+cmVhZF9zaXplID0gc2l6ZTsKfQoKc3RhdGljIHZvaWQgcGVyZl9ldmVudF9faGVhZGVyX3NpemUoc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50KQp7CglzdHJ1Y3QgcGVyZl9zYW1wbGVfZGF0YSAqZGF0YTsKCXU2NCBzYW1wbGVfdHlwZSA9IGV2ZW50LT5hdHRyLnNhbXBsZV90eXBlOwoJdTE2IHNpemUgPSAwOwoKCXBlcmZfZXZlbnRfX3JlYWRfc2l6ZShldmVudCk7CgoJaWYgKHNhbXBsZV90eXBlICYgUEVSRl9TQU1QTEVfSVApCgkJc2l6ZSArPSBzaXplb2YoZGF0YS0+aXApOwoKCWlmIChzYW1wbGVfdHlwZSAmIFBFUkZfU0FNUExFX0FERFIpCgkJc2l6ZSArPSBzaXplb2YoZGF0YS0+YWRkcik7CgoJaWYgKHNhbXBsZV90eXBlICYgUEVSRl9TQU1QTEVfUEVSSU9EKQoJCXNpemUgKz0gc2l6ZW9mKGRhdGEtPnBlcmlvZCk7CgoJaWYgKHNhbXBsZV90eXBlICYgUEVSRl9TQU1QTEVfUkVBRCkKCQlzaXplICs9IGV2ZW50LT5yZWFkX3NpemU7CgoJZXZlbnQtPmhlYWRlcl9zaXplID0gc2l6ZTsKfQoKc3RhdGljIHZvaWQgcGVyZl9ldmVudF9faWRfaGVhZGVyX3NpemUoc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50KQp7CglzdHJ1Y3QgcGVyZl9zYW1wbGVfZGF0YSAqZGF0YTsKCXU2NCBzYW1wbGVfdHlwZSA9IGV2ZW50LT5hdHRyLnNhbXBsZV90eXBlOwoJdTE2IHNpemUgPSAwOwoKCWlmIChzYW1wbGVfdHlwZSAmIFBFUkZfU0FNUExFX1RJRCkKCQlzaXplICs9IHNpemVvZihkYXRhLT50aWRfZW50cnkpOwoKCWlmIChzYW1wbGVfdHlwZSAmIFBFUkZfU0FNUExFX1RJTUUpCgkJc2l6ZSArPSBzaXplb2YoZGF0YS0+dGltZSk7CgoJaWYgKHNhbXBsZV90eXBlICYgUEVSRl9TQU1QTEVfSUQpCgkJc2l6ZSArPSBzaXplb2YoZGF0YS0+aWQpOwoKCWlmIChzYW1wbGVfdHlwZSAmIFBFUkZfU0FNUExFX1NUUkVBTV9JRCkKCQlzaXplICs9IHNpemVvZihkYXRhLT5zdHJlYW1faWQpOwoKCWlmIChzYW1wbGVfdHlwZSAmIFBFUkZfU0FNUExFX0NQVSkKCQlzaXplICs9IHNpemVvZihkYXRhLT5jcHVfZW50cnkpOwoKCWV2ZW50LT5pZF9oZWFkZXJfc2l6ZSA9IHNpemU7Cn0KCnN0YXRpYyB2b2lkIHBlcmZfZ3JvdXBfYXR0YWNoKHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCkKewoJc3RydWN0IHBlcmZfZXZlbnQgKmdyb3VwX2xlYWRlciA9IGV2ZW50LT5ncm91cF9sZWFkZXIsICpwb3M7CgoJLyoKCSAqIFdlIGNhbiBoYXZlIGRvdWJsZSBhdHRhY2ggZHVlIHRvIGdyb3VwIG1vdmVtZW50IGluIHBlcmZfZXZlbnRfb3Blbi4KCSAqLwoJaWYgKGV2ZW50LT5hdHRhY2hfc3RhdGUgJiBQRVJGX0FUVEFDSF9HUk9VUCkKCQlyZXR1cm47CgoJZXZlbnQtPmF0dGFjaF9zdGF0ZSB8PSBQRVJGX0FUVEFDSF9HUk9VUDsKCglpZiAoZ3JvdXBfbGVhZGVyID09IGV2ZW50KQoJCXJldHVybjsKCglpZiAoZ3JvdXBfbGVhZGVyLT5ncm91cF9mbGFncyAmIFBFUkZfR1JPVVBfU09GVFdBUkUgJiYKCQkJIWlzX3NvZnR3YXJlX2V2ZW50KGV2ZW50KSkKCQlncm91cF9sZWFkZXItPmdyb3VwX2ZsYWdzICY9IH5QRVJGX0dST1VQX1NPRlRXQVJFOwoKCWxpc3RfYWRkX3RhaWwoJmV2ZW50LT5ncm91cF9lbnRyeSwgJmdyb3VwX2xlYWRlci0+c2libGluZ19saXN0KTsKCWdyb3VwX2xlYWRlci0+bnJfc2libGluZ3MrKzsKCglwZXJmX2V2ZW50X19oZWFkZXJfc2l6ZShncm91cF9sZWFkZXIpOwoKCWxpc3RfZm9yX2VhY2hfZW50cnkocG9zLCAmZ3JvdXBfbGVhZGVyLT5zaWJsaW5nX2xpc3QsIGdyb3VwX2VudHJ5KQoJCXBlcmZfZXZlbnRfX2hlYWRlcl9zaXplKHBvcyk7Cn0KCi8qCiAqIFJlbW92ZSBhIGV2ZW50IGZyb20gdGhlIGxpc3RzIGZvciBpdHMgY29udGV4dC4KICogTXVzdCBiZSBjYWxsZWQgd2l0aCBjdHgtPm11dGV4IGFuZCBjdHgtPmxvY2sgaGVsZC4KICovCnN0YXRpYyB2b2lkCmxpc3RfZGVsX2V2ZW50KHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCwgc3RydWN0IHBlcmZfZXZlbnRfY29udGV4dCAqY3R4KQp7CgkvKgoJICogV2UgY2FuIGhhdmUgZG91YmxlIGRldGFjaCBkdWUgdG8gZXhpdC9ob3QtdW5wbHVnICsgY2xvc2UuCgkgKi8KCWlmICghKGV2ZW50LT5hdHRhY2hfc3RhdGUgJiBQRVJGX0FUVEFDSF9DT05URVhUKSkKCQlyZXR1cm47CgoJZXZlbnQtPmF0dGFjaF9zdGF0ZSAmPSB+UEVSRl9BVFRBQ0hfQ09OVEVYVDsKCgljdHgtPm5yX2V2ZW50cy0tOwoJaWYgKGV2ZW50LT5hdHRyLmluaGVyaXRfc3RhdCkKCQljdHgtPm5yX3N0YXQtLTsKCglsaXN0X2RlbF9yY3UoJmV2ZW50LT5ldmVudF9lbnRyeSk7CgoJaWYgKGV2ZW50LT5ncm91cF9sZWFkZXIgPT0gZXZlbnQpCgkJbGlzdF9kZWxfaW5pdCgmZXZlbnQtPmdyb3VwX2VudHJ5KTsKCgl1cGRhdGVfZ3JvdXBfdGltZXMoZXZlbnQpOwoKCS8qCgkgKiBJZiBldmVudCB3YXMgaW4gZXJyb3Igc3RhdGUsIHRoZW4ga2VlcCBpdAoJICogdGhhdCB3YXksIG90aGVyd2lzZSBib2d1cyBjb3VudHMgd2lsbCBiZQoJICogcmV0dXJuZWQgb24gcmVhZCgpLiBUaGUgb25seSB3YXkgdG8gZ2V0IG91dAoJICogb2YgZXJyb3Igc3RhdGUgaXMgYnkgZXhwbGljaXQgcmUtZW5hYmxpbmcKCSAqIG9mIHRoZSBldmVudAoJICovCglpZiAoZXZlbnQtPnN0YXRlID4gUEVSRl9FVkVOVF9TVEFURV9PRkYpCgkJZXZlbnQtPnN0YXRlID0gUEVSRl9FVkVOVF9TVEFURV9PRkY7Cn0KCnN0YXRpYyB2b2lkIHBlcmZfZ3JvdXBfZGV0YWNoKHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCkKewoJc3RydWN0IHBlcmZfZXZlbnQgKnNpYmxpbmcsICp0bXA7CglzdHJ1Y3QgbGlzdF9oZWFkICpsaXN0ID0gTlVMTDsKCgkvKgoJICogV2UgY2FuIGhhdmUgZG91YmxlIGRldGFjaCBkdWUgdG8gZXhpdC9ob3QtdW5wbHVnICsgY2xvc2UuCgkgKi8KCWlmICghKGV2ZW50LT5hdHRhY2hfc3RhdGUgJiBQRVJGX0FUVEFDSF9HUk9VUCkpCgkJcmV0dXJuOwoKCWV2ZW50LT5hdHRhY2hfc3RhdGUgJj0gflBFUkZfQVRUQUNIX0dST1VQOwoKCS8qCgkgKiBJZiB0aGlzIGlzIGEgc2libGluZywgcmVtb3ZlIGl0IGZyb20gaXRzIGdyb3VwLgoJICovCglpZiAoZXZlbnQtPmdyb3VwX2xlYWRlciAhPSBldmVudCkgewoJCWxpc3RfZGVsX2luaXQoJmV2ZW50LT5ncm91cF9lbnRyeSk7CgkJZXZlbnQtPmdyb3VwX2xlYWRlci0+bnJfc2libGluZ3MtLTsKCQlnb3RvIG91dDsKCX0KCglpZiAoIWxpc3RfZW1wdHkoJmV2ZW50LT5ncm91cF9lbnRyeSkpCgkJbGlzdCA9ICZldmVudC0+Z3JvdXBfZW50cnk7CgoJLyoKCSAqIElmIHRoaXMgd2FzIGEgZ3JvdXAgZXZlbnQgd2l0aCBzaWJsaW5nIGV2ZW50cyB0aGVuCgkgKiB1cGdyYWRlIHRoZSBzaWJsaW5ncyB0byBzaW5nbGV0b24gZXZlbnRzIGJ5IGFkZGluZyB0aGVtCgkgKiB0byB3aGF0ZXZlciBsaXN0IHdlIGFyZSBvbi4KCSAqLwoJbGlzdF9mb3JfZWFjaF9lbnRyeV9zYWZlKHNpYmxpbmcsIHRtcCwgJmV2ZW50LT5zaWJsaW5nX2xpc3QsIGdyb3VwX2VudHJ5KSB7CgkJaWYgKGxpc3QpCgkJCWxpc3RfbW92ZV90YWlsKCZzaWJsaW5nLT5ncm91cF9lbnRyeSwgbGlzdCk7CgkJc2libGluZy0+Z3JvdXBfbGVhZGVyID0gc2libGluZzsKCgkJLyogSW5oZXJpdCBncm91cCBmbGFncyBmcm9tIHRoZSBwcmV2aW91cyBsZWFkZXIgKi8KCQlzaWJsaW5nLT5ncm91cF9mbGFncyA9IGV2ZW50LT5ncm91cF9mbGFnczsKCX0KCm91dDoKCXBlcmZfZXZlbnRfX2hlYWRlcl9zaXplKGV2ZW50LT5ncm91cF9sZWFkZXIpOwoKCWxpc3RfZm9yX2VhY2hfZW50cnkodG1wLCAmZXZlbnQtPmdyb3VwX2xlYWRlci0+c2libGluZ19saXN0LCBncm91cF9lbnRyeSkKCQlwZXJmX2V2ZW50X19oZWFkZXJfc2l6ZSh0bXApOwp9CgpzdGF0aWMgaW5saW5lIGludApldmVudF9maWx0ZXJfbWF0Y2goc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50KQp7CglyZXR1cm4gZXZlbnQtPmNwdSA9PSAtMSB8fCBldmVudC0+Y3B1ID09IHNtcF9wcm9jZXNzb3JfaWQoKTsKfQoKc3RhdGljIHZvaWQKZXZlbnRfc2NoZWRfb3V0KHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCwKCQkgIHN0cnVjdCBwZXJmX2NwdV9jb250ZXh0ICpjcHVjdHgsCgkJICBzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0ICpjdHgpCnsKCXU2NCB0c3RhbXAgPSBwZXJmX2V2ZW50X3RpbWUoZXZlbnQpOwoJdTY0IGRlbHRhOwoJLyoKCSAqIEFuIGV2ZW50IHdoaWNoIGNvdWxkIG5vdCBiZSBhY3RpdmF0ZWQgYmVjYXVzZSBvZgoJICogZmlsdGVyIG1pc21hdGNoIHN0aWxsIG5lZWRzIHRvIGhhdmUgaXRzIHRpbWluZ3MKCSAqIG1haW50YWluZWQsIG90aGVyd2lzZSBib2d1cyBpbmZvcm1hdGlvbiBpcyByZXR1cm4KCSAqIHZpYSByZWFkKCkgZm9yIHRpbWVfZW5hYmxlZCwgdGltZV9ydW5uaW5nOgoJICovCglpZiAoZXZlbnQtPnN0YXRlID09IFBFUkZfRVZFTlRfU1RBVEVfSU5BQ1RJVkUKCSAgICAmJiAhZXZlbnRfZmlsdGVyX21hdGNoKGV2ZW50KSkgewoJCWRlbHRhID0gY3R4LT50aW1lIC0gZXZlbnQtPnRzdGFtcF9zdG9wcGVkOwoJCWV2ZW50LT50c3RhbXBfcnVubmluZyArPSBkZWx0YTsKCQlldmVudC0+dHN0YW1wX3N0b3BwZWQgPSB0c3RhbXA7Cgl9CgoJaWYgKGV2ZW50LT5zdGF0ZSAhPSBQRVJGX0VWRU5UX1NUQVRFX0FDVElWRSkKCQlyZXR1cm47CgoJZXZlbnQtPnN0YXRlID0gUEVSRl9FVkVOVF9TVEFURV9JTkFDVElWRTsKCWlmIChldmVudC0+cGVuZGluZ19kaXNhYmxlKSB7CgkJZXZlbnQtPnBlbmRpbmdfZGlzYWJsZSA9IDA7CgkJZXZlbnQtPnN0YXRlID0gUEVSRl9FVkVOVF9TVEFURV9PRkY7Cgl9CglldmVudC0+dHN0YW1wX3N0b3BwZWQgPSB0c3RhbXA7CglldmVudC0+cG11LT5kZWwoZXZlbnQsIDApOwoJZXZlbnQtPm9uY3B1ID0gLTE7CgoJaWYgKCFpc19zb2Z0d2FyZV9ldmVudChldmVudCkpCgkJY3B1Y3R4LT5hY3RpdmVfb25jcHUtLTsKCWN0eC0+bnJfYWN0aXZlLS07CglpZiAoZXZlbnQtPmF0dHIuZXhjbHVzaXZlIHx8ICFjcHVjdHgtPmFjdGl2ZV9vbmNwdSkKCQljcHVjdHgtPmV4Y2x1c2l2ZSA9IDA7Cn0KCnN0YXRpYyB2b2lkCmdyb3VwX3NjaGVkX291dChzdHJ1Y3QgcGVyZl9ldmVudCAqZ3JvdXBfZXZlbnQsCgkJc3RydWN0IHBlcmZfY3B1X2NvbnRleHQgKmNwdWN0eCwKCQlzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0ICpjdHgpCnsKCXN0cnVjdCBwZXJmX2V2ZW50ICpldmVudDsKCWludCBzdGF0ZSA9IGdyb3VwX2V2ZW50LT5zdGF0ZTsKCglldmVudF9zY2hlZF9vdXQoZ3JvdXBfZXZlbnQsIGNwdWN0eCwgY3R4KTsKCgkvKgoJICogU2NoZWR1bGUgb3V0IHNpYmxpbmdzIChpZiBhbnkpOgoJICovCglsaXN0X2Zvcl9lYWNoX2VudHJ5KGV2ZW50LCAmZ3JvdXBfZXZlbnQtPnNpYmxpbmdfbGlzdCwgZ3JvdXBfZW50cnkpCgkJZXZlbnRfc2NoZWRfb3V0KGV2ZW50LCBjcHVjdHgsIGN0eCk7CgoJaWYgKHN0YXRlID09IFBFUkZfRVZFTlRfU1RBVEVfQUNUSVZFICYmIGdyb3VwX2V2ZW50LT5hdHRyLmV4Y2x1c2l2ZSkKCQljcHVjdHgtPmV4Y2x1c2l2ZSA9IDA7Cn0KCnN0YXRpYyBpbmxpbmUgc3RydWN0IHBlcmZfY3B1X2NvbnRleHQgKgpfX2dldF9jcHVfY29udGV4dChzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0ICpjdHgpCnsKCXJldHVybiB0aGlzX2NwdV9wdHIoY3R4LT5wbXUtPnBtdV9jcHVfY29udGV4dCk7Cn0KCi8qCiAqIENyb3NzIENQVSBjYWxsIHRvIHJlbW92ZSBhIHBlcmZvcm1hbmNlIGV2ZW50CiAqCiAqIFdlIGRpc2FibGUgdGhlIGV2ZW50IG9uIHRoZSBoYXJkd2FyZSBsZXZlbCBmaXJzdC4gQWZ0ZXIgdGhhdCB3ZQogKiByZW1vdmUgaXQgZnJvbSB0aGUgY29udGV4dCBsaXN0LgogKi8Kc3RhdGljIHZvaWQgX19wZXJmX2V2ZW50X3JlbW92ZV9mcm9tX2NvbnRleHQodm9pZCAqaW5mbykKewoJc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50ID0gaW5mbzsKCXN0cnVjdCBwZXJmX2V2ZW50X2NvbnRleHQgKmN0eCA9IGV2ZW50LT5jdHg7CglzdHJ1Y3QgcGVyZl9jcHVfY29udGV4dCAqY3B1Y3R4ID0gX19nZXRfY3B1X2NvbnRleHQoY3R4KTsKCgkvKgoJICogSWYgdGhpcyBpcyBhIHRhc2sgY29udGV4dCwgd2UgbmVlZCB0byBjaGVjayB3aGV0aGVyIGl0IGlzCgkgKiB0aGUgY3VycmVudCB0YXNrIGNvbnRleHQgb2YgdGhpcyBjcHUuIElmIG5vdCBpdCBoYXMgYmVlbgoJICogc2NoZWR1bGVkIG91dCBiZWZvcmUgdGhlIHNtcCBjYWxsIGFycml2ZWQuCgkgKi8KCWlmIChjdHgtPnRhc2sgJiYgY3B1Y3R4LT50YXNrX2N0eCAhPSBjdHgpCgkJcmV0dXJuOwoKCXJhd19zcGluX2xvY2soJmN0eC0+bG9jayk7CgoJZXZlbnRfc2NoZWRfb3V0KGV2ZW50LCBjcHVjdHgsIGN0eCk7CgoJbGlzdF9kZWxfZXZlbnQoZXZlbnQsIGN0eCk7CgoJcmF3X3NwaW5fdW5sb2NrKCZjdHgtPmxvY2spOwp9CgoKLyoKICogUmVtb3ZlIHRoZSBldmVudCBmcm9tIGEgdGFzaydzIChvciBhIENQVSdzKSBsaXN0IG9mIGV2ZW50cy4KICoKICogTXVzdCBiZSBjYWxsZWQgd2l0aCBjdHgtPm11dGV4IGhlbGQuCiAqCiAqIENQVSBldmVudHMgYXJlIHJlbW92ZWQgd2l0aCBhIHNtcCBjYWxsLiBGb3IgdGFzayBldmVudHMgd2Ugb25seQogKiBjYWxsIHdoZW4gdGhlIHRhc2sgaXMgb24gYSBDUFUuCiAqCiAqIElmIGV2ZW50LT5jdHggaXMgYSBjbG9uZWQgY29udGV4dCwgY2FsbGVycyBtdXN0IG1ha2Ugc3VyZSB0aGF0CiAqIGV2ZXJ5IHRhc2sgc3RydWN0IHRoYXQgZXZlbnQtPmN0eC0+dGFzayBjb3VsZCBwb3NzaWJseSBwb2ludCB0bwogKiByZW1haW5zIHZhbGlkLiAgVGhpcyBpcyBPSyB3aGVuIGNhbGxlZCBmcm9tIHBlcmZfcmVsZWFzZSBzaW5jZQogKiB0aGF0IG9ubHkgY2FsbHMgdXMgb24gdGhlIHRvcC1sZXZlbCBjb250ZXh0LCB3aGljaCBjYW4ndCBiZSBhIGNsb25lLgogKiBXaGVuIGNhbGxlZCBmcm9tIHBlcmZfZXZlbnRfZXhpdF90YXNrLCBpdCdzIE9LIGJlY2F1c2UgdGhlCiAqIGNvbnRleHQgaGFzIGJlZW4gZGV0YWNoZWQgZnJvbSBpdHMgdGFzay4KICovCnN0YXRpYyB2b2lkIHBlcmZfZXZlbnRfcmVtb3ZlX2Zyb21fY29udGV4dChzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQpCnsKCXN0cnVjdCBwZXJmX2V2ZW50X2NvbnRleHQgKmN0eCA9IGV2ZW50LT5jdHg7CglzdHJ1Y3QgdGFza19zdHJ1Y3QgKnRhc2sgPSBjdHgtPnRhc2s7CgoJaWYgKCF0YXNrKSB7CgkJLyoKCQkgKiBQZXIgY3B1IGV2ZW50cyBhcmUgcmVtb3ZlZCB2aWEgYW4gc21wIGNhbGwgYW5kCgkJICogdGhlIHJlbW92YWwgaXMgYWx3YXlzIHN1Y2Nlc3NmdWwuCgkJICovCgkJc21wX2NhbGxfZnVuY3Rpb25fc2luZ2xlKGV2ZW50LT5jcHUsCgkJCQkJIF9fcGVyZl9ldmVudF9yZW1vdmVfZnJvbV9jb250ZXh0LAoJCQkJCSBldmVudCwgMSk7CgkJcmV0dXJuOwoJfQoKcmV0cnk6Cgl0YXNrX29uY3B1X2Z1bmN0aW9uX2NhbGwodGFzaywgX19wZXJmX2V2ZW50X3JlbW92ZV9mcm9tX2NvbnRleHQsCgkJCQkgZXZlbnQpOwoKCXJhd19zcGluX2xvY2tfaXJxKCZjdHgtPmxvY2spOwoJLyoKCSAqIElmIHRoZSBjb250ZXh0IGlzIGFjdGl2ZSB3ZSBuZWVkIHRvIHJldHJ5IHRoZSBzbXAgY2FsbC4KCSAqLwoJaWYgKGN0eC0+bnJfYWN0aXZlICYmICFsaXN0X2VtcHR5KCZldmVudC0+Z3JvdXBfZW50cnkpKSB7CgkJcmF3X3NwaW5fdW5sb2NrX2lycSgmY3R4LT5sb2NrKTsKCQlnb3RvIHJldHJ5OwoJfQoKCS8qCgkgKiBUaGUgbG9jayBwcmV2ZW50cyB0aGF0IHRoaXMgY29udGV4dCBpcyBzY2hlZHVsZWQgaW4gc28gd2UKCSAqIGNhbiByZW1vdmUgdGhlIGV2ZW50IHNhZmVseSwgaWYgdGhlIGNhbGwgYWJvdmUgZGlkIG5vdAoJICogc3VjY2VlZC4KCSAqLwoJaWYgKCFsaXN0X2VtcHR5KCZldmVudC0+Z3JvdXBfZW50cnkpKQoJCWxpc3RfZGVsX2V2ZW50KGV2ZW50LCBjdHgpOwoJcmF3X3NwaW5fdW5sb2NrX2lycSgmY3R4LT5sb2NrKTsKfQoKLyoKICogQ3Jvc3MgQ1BVIGNhbGwgdG8gZGlzYWJsZSBhIHBlcmZvcm1hbmNlIGV2ZW50CiAqLwpzdGF0aWMgdm9pZCBfX3BlcmZfZXZlbnRfZGlzYWJsZSh2b2lkICppbmZvKQp7CglzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQgPSBpbmZvOwoJc3RydWN0IHBlcmZfZXZlbnRfY29udGV4dCAqY3R4ID0gZXZlbnQtPmN0eDsKCXN0cnVjdCBwZXJmX2NwdV9jb250ZXh0ICpjcHVjdHggPSBfX2dldF9jcHVfY29udGV4dChjdHgpOwoKCS8qCgkgKiBJZiB0aGlzIGlzIGEgcGVyLXRhc2sgZXZlbnQsIG5lZWQgdG8gY2hlY2sgd2hldGhlciB0aGlzCgkgKiBldmVudCdzIHRhc2sgaXMgdGhlIGN1cnJlbnQgdGFzayBvbiB0aGlzIGNwdS4KCSAqLwoJaWYgKGN0eC0+dGFzayAmJiBjcHVjdHgtPnRhc2tfY3R4ICE9IGN0eCkKCQlyZXR1cm47CgoJcmF3X3NwaW5fbG9jaygmY3R4LT5sb2NrKTsKCgkvKgoJICogSWYgdGhlIGV2ZW50IGlzIG9uLCB0dXJuIGl0IG9mZi4KCSAqIElmIGl0IGlzIGluIGVycm9yIHN0YXRlLCBsZWF2ZSBpdCBpbiBlcnJvciBzdGF0ZS4KCSAqLwoJaWYgKGV2ZW50LT5zdGF0ZSA+PSBQRVJGX0VWRU5UX1NUQVRFX0lOQUNUSVZFKSB7CgkJdXBkYXRlX2NvbnRleHRfdGltZShjdHgpOwoJCXVwZGF0ZV9ncm91cF90aW1lcyhldmVudCk7CgkJaWYgKGV2ZW50ID09IGV2ZW50LT5ncm91cF9sZWFkZXIpCgkJCWdyb3VwX3NjaGVkX291dChldmVudCwgY3B1Y3R4LCBjdHgpOwoJCWVsc2UKCQkJZXZlbnRfc2NoZWRfb3V0KGV2ZW50LCBjcHVjdHgsIGN0eCk7CgkJZXZlbnQtPnN0YXRlID0gUEVSRl9FVkVOVF9TVEFURV9PRkY7Cgl9CgoJcmF3X3NwaW5fdW5sb2NrKCZjdHgtPmxvY2spOwp9CgovKgogKiBEaXNhYmxlIGEgZXZlbnQuCiAqCiAqIElmIGV2ZW50LT5jdHggaXMgYSBjbG9uZWQgY29udGV4dCwgY2FsbGVycyBtdXN0IG1ha2Ugc3VyZSB0aGF0CiAqIGV2ZXJ5IHRhc2sgc3RydWN0IHRoYXQgZXZlbnQtPmN0eC0+dGFzayBjb3VsZCBwb3NzaWJseSBwb2ludCB0bwogKiByZW1haW5zIHZhbGlkLiAgVGhpcyBjb25kaXRpb24gaXMgc2F0aXNpZmVkIHdoZW4gY2FsbGVkIHRocm91Z2gKICogcGVyZl9ldmVudF9mb3JfZWFjaF9jaGlsZCBvciBwZXJmX2V2ZW50X2Zvcl9lYWNoIGJlY2F1c2UgdGhleQogKiBob2xkIHRoZSB0b3AtbGV2ZWwgZXZlbnQncyBjaGlsZF9tdXRleCwgc28gYW55IGRlc2NlbmRhbnQgdGhhdAogKiBnb2VzIHRvIGV4aXQgd2lsbCBibG9jayBpbiBzeW5jX2NoaWxkX2V2ZW50LgogKiBXaGVuIGNhbGxlZCBmcm9tIHBlcmZfcGVuZGluZ19ldmVudCBpdCdzIE9LIGJlY2F1c2UgZXZlbnQtPmN0eAogKiBpcyB0aGUgY3VycmVudCBjb250ZXh0IG9uIHRoaXMgQ1BVIGFuZCBwcmVlbXB0aW9uIGlzIGRpc2FibGVkLAogKiBoZW5jZSB3ZSBjYW4ndCBnZXQgaW50byBwZXJmX2V2ZW50X3Rhc2tfc2NoZWRfb3V0IGZvciB0aGlzIGNvbnRleHQuCiAqLwp2b2lkIHBlcmZfZXZlbnRfZGlzYWJsZShzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQpCnsKCXN0cnVjdCBwZXJmX2V2ZW50X2NvbnRleHQgKmN0eCA9IGV2ZW50LT5jdHg7CglzdHJ1Y3QgdGFza19zdHJ1Y3QgKnRhc2sgPSBjdHgtPnRhc2s7CgoJaWYgKCF0YXNrKSB7CgkJLyoKCQkgKiBEaXNhYmxlIHRoZSBldmVudCBvbiB0aGUgY3B1IHRoYXQgaXQncyBvbgoJCSAqLwoJCXNtcF9jYWxsX2Z1bmN0aW9uX3NpbmdsZShldmVudC0+Y3B1LCBfX3BlcmZfZXZlbnRfZGlzYWJsZSwKCQkJCQkgZXZlbnQsIDEpOwoJCXJldHVybjsKCX0KCnJldHJ5OgoJdGFza19vbmNwdV9mdW5jdGlvbl9jYWxsKHRhc2ssIF9fcGVyZl9ldmVudF9kaXNhYmxlLCBldmVudCk7CgoJcmF3X3NwaW5fbG9ja19pcnEoJmN0eC0+bG9jayk7CgkvKgoJICogSWYgdGhlIGV2ZW50IGlzIHN0aWxsIGFjdGl2ZSwgd2UgbmVlZCB0byByZXRyeSB0aGUgY3Jvc3MtY2FsbC4KCSAqLwoJaWYgKGV2ZW50LT5zdGF0ZSA9PSBQRVJGX0VWRU5UX1NUQVRFX0FDVElWRSkgewoJCXJhd19zcGluX3VubG9ja19pcnEoJmN0eC0+bG9jayk7CgkJZ290byByZXRyeTsKCX0KCgkvKgoJICogU2luY2Ugd2UgaGF2ZSB0aGUgbG9jayB0aGlzIGNvbnRleHQgY2FuJ3QgYmUgc2NoZWR1bGVkCgkgKiBpbiwgc28gd2UgY2FuIGNoYW5nZSB0aGUgc3RhdGUgc2FmZWx5LgoJICovCglpZiAoZXZlbnQtPnN0YXRlID09IFBFUkZfRVZFTlRfU1RBVEVfSU5BQ1RJVkUpIHsKCQl1cGRhdGVfZ3JvdXBfdGltZXMoZXZlbnQpOwoJCWV2ZW50LT5zdGF0ZSA9IFBFUkZfRVZFTlRfU1RBVEVfT0ZGOwoJfQoKCXJhd19zcGluX3VubG9ja19pcnEoJmN0eC0+bG9jayk7Cn0KCnN0YXRpYyBpbnQKZXZlbnRfc2NoZWRfaW4oc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50LAoJCSBzdHJ1Y3QgcGVyZl9jcHVfY29udGV4dCAqY3B1Y3R4LAoJCSBzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0ICpjdHgpCnsKCXU2NCB0c3RhbXAgPSBwZXJmX2V2ZW50X3RpbWUoZXZlbnQpOwoKCWlmIChldmVudC0+c3RhdGUgPD0gUEVSRl9FVkVOVF9TVEFURV9PRkYpCgkJcmV0dXJuIDA7CgoJZXZlbnQtPnN0YXRlID0gUEVSRl9FVkVOVF9TVEFURV9BQ1RJVkU7CglldmVudC0+b25jcHUgPSBzbXBfcHJvY2Vzc29yX2lkKCk7CgkvKgoJICogVGhlIG5ldyBzdGF0ZSBtdXN0IGJlIHZpc2libGUgYmVmb3JlIHdlIHR1cm4gaXQgb24gaW4gdGhlIGhhcmR3YXJlOgoJICovCglzbXBfd21iKCk7CgoJaWYgKGV2ZW50LT5wbXUtPmFkZChldmVudCwgUEVSRl9FRl9TVEFSVCkpIHsKCQlldmVudC0+c3RhdGUgPSBQRVJGX0VWRU5UX1NUQVRFX0lOQUNUSVZFOwoJCWV2ZW50LT5vbmNwdSA9IC0xOwoJCXJldHVybiAtRUFHQUlOOwoJfQoKCWV2ZW50LT50c3RhbXBfcnVubmluZyArPSB0c3RhbXAgLSBldmVudC0+dHN0YW1wX3N0b3BwZWQ7CgoJZXZlbnQtPnNoYWRvd19jdHhfdGltZSA9IHRzdGFtcCAtIGN0eC0+dGltZXN0YW1wOwoKCWlmICghaXNfc29mdHdhcmVfZXZlbnQoZXZlbnQpKQoJCWNwdWN0eC0+YWN0aXZlX29uY3B1Kys7CgljdHgtPm5yX2FjdGl2ZSsrOwoKCWlmIChldmVudC0+YXR0ci5leGNsdXNpdmUpCgkJY3B1Y3R4LT5leGNsdXNpdmUgPSAxOwoKCXJldHVybiAwOwp9CgpzdGF0aWMgaW50Cmdyb3VwX3NjaGVkX2luKHN0cnVjdCBwZXJmX2V2ZW50ICpncm91cF9ldmVudCwKCSAgICAgICBzdHJ1Y3QgcGVyZl9jcHVfY29udGV4dCAqY3B1Y3R4LAoJICAgICAgIHN0cnVjdCBwZXJmX2V2ZW50X2NvbnRleHQgKmN0eCkKewoJc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50LCAqcGFydGlhbF9ncm91cCA9IE5VTEw7CglzdHJ1Y3QgcG11ICpwbXUgPSBncm91cF9ldmVudC0+cG11OwoJdTY0IG5vdyA9IGN0eC0+dGltZTsKCWJvb2wgc2ltdWxhdGUgPSBmYWxzZTsKCglpZiAoZ3JvdXBfZXZlbnQtPnN0YXRlID09IFBFUkZfRVZFTlRfU1RBVEVfT0ZGKQoJCXJldHVybiAwOwoKCXBtdS0+c3RhcnRfdHhuKHBtdSk7CgoJaWYgKGV2ZW50X3NjaGVkX2luKGdyb3VwX2V2ZW50LCBjcHVjdHgsIGN0eCkpIHsKCQlwbXUtPmNhbmNlbF90eG4ocG11KTsKCQlyZXR1cm4gLUVBR0FJTjsKCX0KCgkvKgoJICogU2NoZWR1bGUgaW4gc2libGluZ3MgYXMgb25lIGdyb3VwIChpZiBhbnkpOgoJICovCglsaXN0X2Zvcl9lYWNoX2VudHJ5KGV2ZW50LCAmZ3JvdXBfZXZlbnQtPnNpYmxpbmdfbGlzdCwgZ3JvdXBfZW50cnkpIHsKCQlpZiAoZXZlbnRfc2NoZWRfaW4oZXZlbnQsIGNwdWN0eCwgY3R4KSkgewoJCQlwYXJ0aWFsX2dyb3VwID0gZXZlbnQ7CgkJCWdvdG8gZ3JvdXBfZXJyb3I7CgkJfQoJfQoKCWlmICghcG11LT5jb21taXRfdHhuKHBtdSkpCgkJcmV0dXJuIDA7Cgpncm91cF9lcnJvcjoKCS8qCgkgKiBHcm91cHMgY2FuIGJlIHNjaGVkdWxlZCBpbiBhcyBvbmUgdW5pdCBvbmx5LCBzbyB1bmRvIGFueQoJICogcGFydGlhbCBncm91cCBiZWZvcmUgcmV0dXJuaW5nOgoJICogVGhlIGV2ZW50cyB1cCB0byB0aGUgZmFpbGVkIGV2ZW50IGFyZSBzY2hlZHVsZWQgb3V0IG5vcm1hbGx5LAoJICogdHN0YW1wX3N0b3BwZWQgd2lsbCBiZSB1cGRhdGVkLgoJICoKCSAqIFRoZSBmYWlsZWQgZXZlbnRzIGFuZCB0aGUgcmVtYWluaW5nIHNpYmxpbmdzIG5lZWQgdG8gaGF2ZQoJICogdGhlaXIgdGltaW5ncyB1cGRhdGVkIGFzIGlmIHRoZXkgaGFkIGdvbmUgdGhydSBldmVudF9zY2hlZF9pbigpCgkgKiBhbmQgZXZlbnRfc2NoZWRfb3V0KCkuIFRoaXMgaXMgcmVxdWlyZWQgdG8gZ2V0IGNvbnNpc3RlbnQgdGltaW5ncwoJICogYWNyb3NzIHRoZSBncm91cC4gVGhpcyBhbHNvIHRha2VzIGNhcmUgb2YgdGhlIGNhc2Ugd2hlcmUgdGhlIGdyb3VwCgkgKiBjb3VsZCBuZXZlciBiZSBzY2hlZHVsZWQgYnkgZW5zdXJpbmcgdHN0YW1wX3N0b3BwZWQgaXMgc2V0IHRvIG1hcmsKCSAqIHRoZSB0aW1lIHRoZSBldmVudCB3YXMgYWN0dWFsbHkgc3RvcHBlZCwgc3VjaCB0aGF0IHRpbWUgZGVsdGEKCSAqIGNhbGN1bGF0aW9uIGluIHVwZGF0ZV9ldmVudF90aW1lcygpIGlzIGNvcnJlY3QuCgkgKi8KCWxpc3RfZm9yX2VhY2hfZW50cnkoZXZlbnQsICZncm91cF9ldmVudC0+c2libGluZ19saXN0LCBncm91cF9lbnRyeSkgewoJCWlmIChldmVudCA9PSBwYXJ0aWFsX2dyb3VwKQoJCQlzaW11bGF0ZSA9IHRydWU7CgoJCWlmIChzaW11bGF0ZSkgewoJCQlldmVudC0+dHN0YW1wX3J1bm5pbmcgKz0gbm93IC0gZXZlbnQtPnRzdGFtcF9zdG9wcGVkOwoJCQlldmVudC0+dHN0YW1wX3N0b3BwZWQgPSBub3c7CgkJfSBlbHNlIHsKCQkJZXZlbnRfc2NoZWRfb3V0KGV2ZW50LCBjcHVjdHgsIGN0eCk7CgkJfQoJfQoJZXZlbnRfc2NoZWRfb3V0KGdyb3VwX2V2ZW50LCBjcHVjdHgsIGN0eCk7CgoJcG11LT5jYW5jZWxfdHhuKHBtdSk7CgoJcmV0dXJuIC1FQUdBSU47Cn0KCi8qCiAqIFdvcmsgb3V0IHdoZXRoZXIgd2UgY2FuIHB1dCB0aGlzIGV2ZW50IGdyb3VwIG9uIHRoZSBDUFUgbm93LgogKi8Kc3RhdGljIGludCBncm91cF9jYW5fZ29fb24oc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50LAoJCQkgICBzdHJ1Y3QgcGVyZl9jcHVfY29udGV4dCAqY3B1Y3R4LAoJCQkgICBpbnQgY2FuX2FkZF9odykKewoJLyoKCSAqIEdyb3VwcyBjb25zaXN0aW5nIGVudGlyZWx5IG9mIHNvZnR3YXJlIGV2ZW50cyBjYW4gYWx3YXlzIGdvIG9uLgoJICovCglpZiAoZXZlbnQtPmdyb3VwX2ZsYWdzICYgUEVSRl9HUk9VUF9TT0ZUV0FSRSkKCQlyZXR1cm4gMTsKCS8qCgkgKiBJZiBhbiBleGNsdXNpdmUgZ3JvdXAgaXMgYWxyZWFkeSBvbiwgbm8gb3RoZXIgaGFyZHdhcmUKCSAqIGV2ZW50cyBjYW4gZ28gb24uCgkgKi8KCWlmIChjcHVjdHgtPmV4Y2x1c2l2ZSkKCQlyZXR1cm4gMDsKCS8qCgkgKiBJZiB0aGlzIGdyb3VwIGlzIGV4Y2x1c2l2ZSBhbmQgdGhlcmUgYXJlIGFscmVhZHkKCSAqIGV2ZW50cyBvbiB0aGUgQ1BVLCBpdCBjYW4ndCBnbyBvbi4KCSAqLwoJaWYgKGV2ZW50LT5hdHRyLmV4Y2x1c2l2ZSAmJiBjcHVjdHgtPmFjdGl2ZV9vbmNwdSkKCQlyZXR1cm4gMDsKCS8qCgkgKiBPdGhlcndpc2UsIHRyeSB0byBhZGQgaXQgaWYgYWxsIHByZXZpb3VzIGdyb3VwcyB3ZXJlIGFibGUKCSAqIHRvIGdvIG9uLgoJICovCglyZXR1cm4gY2FuX2FkZF9odzsKfQoKc3RhdGljIHZvaWQgYWRkX2V2ZW50X3RvX2N0eChzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQsCgkJCSAgICAgICBzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0ICpjdHgpCnsKCXU2NCB0c3RhbXAgPSBwZXJmX2V2ZW50X3RpbWUoZXZlbnQpOwoKCWxpc3RfYWRkX2V2ZW50KGV2ZW50LCBjdHgpOwoJcGVyZl9ncm91cF9hdHRhY2goZXZlbnQpOwoJZXZlbnQtPnRzdGFtcF9lbmFibGVkID0gdHN0YW1wOwoJZXZlbnQtPnRzdGFtcF9ydW5uaW5nID0gdHN0YW1wOwoJZXZlbnQtPnRzdGFtcF9zdG9wcGVkID0gdHN0YW1wOwp9CgovKgogKiBDcm9zcyBDUFUgY2FsbCB0byBpbnN0YWxsIGFuZCBlbmFibGUgYSBwZXJmb3JtYW5jZSBldmVudAogKgogKiBNdXN0IGJlIGNhbGxlZCB3aXRoIGN0eC0+bXV0ZXggaGVsZAogKi8Kc3RhdGljIHZvaWQgX19wZXJmX2luc3RhbGxfaW5fY29udGV4dCh2b2lkICppbmZvKQp7CglzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQgPSBpbmZvOwoJc3RydWN0IHBlcmZfZXZlbnRfY29udGV4dCAqY3R4ID0gZXZlbnQtPmN0eDsKCXN0cnVjdCBwZXJmX2V2ZW50ICpsZWFkZXIgPSBldmVudC0+Z3JvdXBfbGVhZGVyOwoJc3RydWN0IHBlcmZfY3B1X2NvbnRleHQgKmNwdWN0eCA9IF9fZ2V0X2NwdV9jb250ZXh0KGN0eCk7CglpbnQgZXJyOwoKCS8qCgkgKiBJZiB0aGlzIGlzIGEgdGFzayBjb250ZXh0LCB3ZSBuZWVkIHRvIGNoZWNrIHdoZXRoZXIgaXQgaXMKCSAqIHRoZSBjdXJyZW50IHRhc2sgY29udGV4dCBvZiB0aGlzIGNwdS4gSWYgbm90IGl0IGhhcyBiZWVuCgkgKiBzY2hlZHVsZWQgb3V0IGJlZm9yZSB0aGUgc21wIGNhbGwgYXJyaXZlZC4KCSAqIE9yIHBvc3NpYmx5IHRoaXMgaXMgdGhlIHJpZ2h0IGNvbnRleHQgYnV0IGl0IGlzbid0CgkgKiBvbiB0aGlzIGNwdSBiZWNhdXNlIGl0IGhhZCBubyBldmVudHMuCgkgKi8KCWlmIChjdHgtPnRhc2sgJiYgY3B1Y3R4LT50YXNrX2N0eCAhPSBjdHgpIHsKCQlpZiAoY3B1Y3R4LT50YXNrX2N0eCB8fCBjdHgtPnRhc2sgIT0gY3VycmVudCkKCQkJcmV0dXJuOwoJCWNwdWN0eC0+dGFza19jdHggPSBjdHg7Cgl9CgoJcmF3X3NwaW5fbG9jaygmY3R4LT5sb2NrKTsKCWN0eC0+aXNfYWN0aXZlID0gMTsKCXVwZGF0ZV9jb250ZXh0X3RpbWUoY3R4KTsKCglhZGRfZXZlbnRfdG9fY3R4KGV2ZW50LCBjdHgpOwoKCWlmICghZXZlbnRfZmlsdGVyX21hdGNoKGV2ZW50KSkKCQlnb3RvIHVubG9jazsKCgkvKgoJICogRG9uJ3QgcHV0IHRoZSBldmVudCBvbiBpZiBpdCBpcyBkaXNhYmxlZCBvciBpZgoJICogaXQgaXMgaW4gYSBncm91cCBhbmQgdGhlIGdyb3VwIGlzbid0IG9uLgoJICovCglpZiAoZXZlbnQtPnN0YXRlICE9IFBFUkZfRVZFTlRfU1RBVEVfSU5BQ1RJVkUgfHwKCSAgICAobGVhZGVyICE9IGV2ZW50ICYmIGxlYWRlci0+c3RhdGUgIT0gUEVSRl9FVkVOVF9TVEFURV9BQ1RJVkUpKQoJCWdvdG8gdW5sb2NrOwoKCS8qCgkgKiBBbiBleGNsdXNpdmUgZXZlbnQgY2FuJ3QgZ28gb24gaWYgdGhlcmUgYXJlIGFscmVhZHkgYWN0aXZlCgkgKiBoYXJkd2FyZSBldmVudHMsIGFuZCBubyBoYXJkd2FyZSBldmVudCBjYW4gZ28gb24gaWYgdGhlcmUKCSAqIGlzIGFscmVhZHkgYW4gZXhjbHVzaXZlIGV2ZW50IG9uLgoJICovCglpZiAoIWdyb3VwX2Nhbl9nb19vbihldmVudCwgY3B1Y3R4LCAxKSkKCQllcnIgPSAtRUVYSVNUOwoJZWxzZQoJCWVyciA9IGV2ZW50X3NjaGVkX2luKGV2ZW50LCBjcHVjdHgsIGN0eCk7CgoJaWYgKGVycikgewoJCS8qCgkJICogVGhpcyBldmVudCBjb3VsZG4ndCBnbyBvbi4gIElmIGl0IGlzIGluIGEgZ3JvdXAKCQkgKiB0aGVuIHdlIGhhdmUgdG8gcHVsbCB0aGUgd2hvbGUgZ3JvdXAgb2ZmLgoJCSAqIElmIHRoZSBldmVudCBncm91cCBpcyBwaW5uZWQgdGhlbiBwdXQgaXQgaW4gZXJyb3Igc3RhdGUuCgkJICovCgkJaWYgKGxlYWRlciAhPSBldmVudCkKCQkJZ3JvdXBfc2NoZWRfb3V0KGxlYWRlciwgY3B1Y3R4LCBjdHgpOwoJCWlmIChsZWFkZXItPmF0dHIucGlubmVkKSB7CgkJCXVwZGF0ZV9ncm91cF90aW1lcyhsZWFkZXIpOwoJCQlsZWFkZXItPnN0YXRlID0gUEVSRl9FVkVOVF9TVEFURV9FUlJPUjsKCQl9Cgl9Cgp1bmxvY2s6CglyYXdfc3Bpbl91bmxvY2soJmN0eC0+bG9jayk7Cn0KCi8qCiAqIEF0dGFjaCBhIHBlcmZvcm1hbmNlIGV2ZW50IHRvIGEgY29udGV4dAogKgogKiBGaXJzdCB3ZSBhZGQgdGhlIGV2ZW50IHRvIHRoZSBsaXN0IHdpdGggdGhlIGhhcmR3YXJlIGVuYWJsZSBiaXQKICogaW4gZXZlbnQtPmh3X2NvbmZpZyBjbGVhcmVkLgogKgogKiBJZiB0aGUgZXZlbnQgaXMgYXR0YWNoZWQgdG8gYSB0YXNrIHdoaWNoIGlzIG9uIGEgQ1BVIHdlIHVzZSBhIHNtcAogKiBjYWxsIHRvIGVuYWJsZSBpdCBpbiB0aGUgdGFzayBjb250ZXh0LiBUaGUgdGFzayBtaWdodCBoYXZlIGJlZW4KICogc2NoZWR1bGVkIGF3YXksIGJ1dCB3ZSBjaGVjayB0aGlzIGluIHRoZSBzbXAgY2FsbCBhZ2Fpbi4KICoKICogTXVzdCBiZSBjYWxsZWQgd2l0aCBjdHgtPm11dGV4IGhlbGQuCiAqLwpzdGF0aWMgdm9pZApwZXJmX2luc3RhbGxfaW5fY29udGV4dChzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0ICpjdHgsCgkJCXN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCwKCQkJaW50IGNwdSkKewoJc3RydWN0IHRhc2tfc3RydWN0ICp0YXNrID0gY3R4LT50YXNrOwoKCWV2ZW50LT5jdHggPSBjdHg7CgoJaWYgKCF0YXNrKSB7CgkJLyoKCQkgKiBQZXIgY3B1IGV2ZW50cyBhcmUgaW5zdGFsbGVkIHZpYSBhbiBzbXAgY2FsbCBhbmQKCQkgKiB0aGUgaW5zdGFsbCBpcyBhbHdheXMgc3VjY2Vzc2Z1bC4KCQkgKi8KCQlzbXBfY2FsbF9mdW5jdGlvbl9zaW5nbGUoY3B1LCBfX3BlcmZfaW5zdGFsbF9pbl9jb250ZXh0LAoJCQkJCSBldmVudCwgMSk7CgkJcmV0dXJuOwoJfQoKcmV0cnk6Cgl0YXNrX29uY3B1X2Z1bmN0aW9uX2NhbGwodGFzaywgX19wZXJmX2luc3RhbGxfaW5fY29udGV4dCwKCQkJCSBldmVudCk7CgoJcmF3X3NwaW5fbG9ja19pcnEoJmN0eC0+bG9jayk7CgkvKgoJICogd2UgbmVlZCB0byByZXRyeSB0aGUgc21wIGNhbGwuCgkgKi8KCWlmIChjdHgtPmlzX2FjdGl2ZSAmJiBsaXN0X2VtcHR5KCZldmVudC0+Z3JvdXBfZW50cnkpKSB7CgkJcmF3X3NwaW5fdW5sb2NrX2lycSgmY3R4LT5sb2NrKTsKCQlnb3RvIHJldHJ5OwoJfQoKCS8qCgkgKiBUaGUgbG9jayBwcmV2ZW50cyB0aGF0IHRoaXMgY29udGV4dCBpcyBzY2hlZHVsZWQgaW4gc28gd2UKCSAqIGNhbiBhZGQgdGhlIGV2ZW50IHNhZmVseSwgaWYgaXQgdGhlIGNhbGwgYWJvdmUgZGlkIG5vdAoJICogc3VjY2VlZC4KCSAqLwoJaWYgKGxpc3RfZW1wdHkoJmV2ZW50LT5ncm91cF9lbnRyeSkpCgkJYWRkX2V2ZW50X3RvX2N0eChldmVudCwgY3R4KTsKCXJhd19zcGluX3VubG9ja19pcnEoJmN0eC0+bG9jayk7Cn0KCi8qCiAqIFB1dCBhIGV2ZW50IGludG8gaW5hY3RpdmUgc3RhdGUgYW5kIHVwZGF0ZSB0aW1lIGZpZWxkcy4KICogRW5hYmxpbmcgdGhlIGxlYWRlciBvZiBhIGdyb3VwIGVmZmVjdGl2ZWx5IGVuYWJsZXMgYWxsCiAqIHRoZSBncm91cCBtZW1iZXJzIHRoYXQgYXJlbid0IGV4cGxpY2l0bHkgZGlzYWJsZWQsIHNvIHdlCiAqIGhhdmUgdG8gdXBkYXRlIHRoZWlyIC0+dHN0YW1wX2VuYWJsZWQgYWxzby4KICogTm90ZTogdGhpcyB3b3JrcyBmb3IgZ3JvdXAgbWVtYmVycyBhcyB3ZWxsIGFzIGdyb3VwIGxlYWRlcnMKICogc2luY2UgdGhlIG5vbi1sZWFkZXIgbWVtYmVycycgc2libGluZ19saXN0cyB3aWxsIGJlIGVtcHR5LgogKi8Kc3RhdGljIHZvaWQgX19wZXJmX2V2ZW50X21hcmtfZW5hYmxlZChzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQsCgkJCQkJc3RydWN0IHBlcmZfZXZlbnRfY29udGV4dCAqY3R4KQp7CglzdHJ1Y3QgcGVyZl9ldmVudCAqc3ViOwoJdTY0IHRzdGFtcCA9IHBlcmZfZXZlbnRfdGltZShldmVudCk7CgoJZXZlbnQtPnN0YXRlID0gUEVSRl9FVkVOVF9TVEFURV9JTkFDVElWRTsKCWV2ZW50LT50c3RhbXBfZW5hYmxlZCA9IHRzdGFtcCAtIGV2ZW50LT50b3RhbF90aW1lX2VuYWJsZWQ7CglsaXN0X2Zvcl9lYWNoX2VudHJ5KHN1YiwgJmV2ZW50LT5zaWJsaW5nX2xpc3QsIGdyb3VwX2VudHJ5KSB7CgkJaWYgKHN1Yi0+c3RhdGUgPj0gUEVSRl9FVkVOVF9TVEFURV9JTkFDVElWRSkKCQkJc3ViLT50c3RhbXBfZW5hYmxlZCA9IHRzdGFtcCAtIHN1Yi0+dG90YWxfdGltZV9lbmFibGVkOwoJfQp9CgovKgogKiBDcm9zcyBDUFUgY2FsbCB0byBlbmFibGUgYSBwZXJmb3JtYW5jZSBldmVudAogKi8Kc3RhdGljIHZvaWQgX19wZXJmX2V2ZW50X2VuYWJsZSh2b2lkICppbmZvKQp7CglzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQgPSBpbmZvOwoJc3RydWN0IHBlcmZfZXZlbnRfY29udGV4dCAqY3R4ID0gZXZlbnQtPmN0eDsKCXN0cnVjdCBwZXJmX2V2ZW50ICpsZWFkZXIgPSBldmVudC0+Z3JvdXBfbGVhZGVyOwoJc3RydWN0IHBlcmZfY3B1X2NvbnRleHQgKmNwdWN0eCA9IF9fZ2V0X2NwdV9jb250ZXh0KGN0eCk7CglpbnQgZXJyOwoKCS8qCgkgKiBJZiB0aGlzIGlzIGEgcGVyLXRhc2sgZXZlbnQsIG5lZWQgdG8gY2hlY2sgd2hldGhlciB0aGlzCgkgKiBldmVudCdzIHRhc2sgaXMgdGhlIGN1cnJlbnQgdGFzayBvbiB0aGlzIGNwdS4KCSAqLwoJaWYgKGN0eC0+dGFzayAmJiBjcHVjdHgtPnRhc2tfY3R4ICE9IGN0eCkgewoJCWlmIChjcHVjdHgtPnRhc2tfY3R4IHx8IGN0eC0+dGFzayAhPSBjdXJyZW50KQoJCQlyZXR1cm47CgkJY3B1Y3R4LT50YXNrX2N0eCA9IGN0eDsKCX0KCglyYXdfc3Bpbl9sb2NrKCZjdHgtPmxvY2spOwoJY3R4LT5pc19hY3RpdmUgPSAxOwoJdXBkYXRlX2NvbnRleHRfdGltZShjdHgpOwoKCWlmIChldmVudC0+c3RhdGUgPj0gUEVSRl9FVkVOVF9TVEFURV9JTkFDVElWRSkKCQlnb3RvIHVubG9jazsKCV9fcGVyZl9ldmVudF9tYXJrX2VuYWJsZWQoZXZlbnQsIGN0eCk7CgoJaWYgKCFldmVudF9maWx0ZXJfbWF0Y2goZXZlbnQpKQoJCWdvdG8gdW5sb2NrOwoKCS8qCgkgKiBJZiB0aGUgZXZlbnQgaXMgaW4gYSBncm91cCBhbmQgaXNuJ3QgdGhlIGdyb3VwIGxlYWRlciwKCSAqIHRoZW4gZG9uJ3QgcHV0IGl0IG9uIHVubGVzcyB0aGUgZ3JvdXAgaXMgb24uCgkgKi8KCWlmIChsZWFkZXIgIT0gZXZlbnQgJiYgbGVhZGVyLT5zdGF0ZSAhPSBQRVJGX0VWRU5UX1NUQVRFX0FDVElWRSkKCQlnb3RvIHVubG9jazsKCglpZiAoIWdyb3VwX2Nhbl9nb19vbihldmVudCwgY3B1Y3R4LCAxKSkgewoJCWVyciA9IC1FRVhJU1Q7Cgl9IGVsc2UgewoJCWlmIChldmVudCA9PSBsZWFkZXIpCgkJCWVyciA9IGdyb3VwX3NjaGVkX2luKGV2ZW50LCBjcHVjdHgsIGN0eCk7CgkJZWxzZQoJCQllcnIgPSBldmVudF9zY2hlZF9pbihldmVudCwgY3B1Y3R4LCBjdHgpOwoJfQoKCWlmIChlcnIpIHsKCQkvKgoJCSAqIElmIHRoaXMgZXZlbnQgY2FuJ3QgZ28gb24gYW5kIGl0J3MgcGFydCBvZiBhCgkJICogZ3JvdXAsIHRoZW4gdGhlIHdob2xlIGdyb3VwIGhhcyB0byBjb21lIG9mZi4KCQkgKi8KCQlpZiAobGVhZGVyICE9IGV2ZW50KQoJCQlncm91cF9zY2hlZF9vdXQobGVhZGVyLCBjcHVjdHgsIGN0eCk7CgkJaWYgKGxlYWRlci0+YXR0ci5waW5uZWQpIHsKCQkJdXBkYXRlX2dyb3VwX3RpbWVzKGxlYWRlcik7CgkJCWxlYWRlci0+c3RhdGUgPSBQRVJGX0VWRU5UX1NUQVRFX0VSUk9SOwoJCX0KCX0KCnVubG9jazoKCXJhd19zcGluX3VubG9jaygmY3R4LT5sb2NrKTsKfQoKLyoKICogRW5hYmxlIGEgZXZlbnQuCiAqCiAqIElmIGV2ZW50LT5jdHggaXMgYSBjbG9uZWQgY29udGV4dCwgY2FsbGVycyBtdXN0IG1ha2Ugc3VyZSB0aGF0CiAqIGV2ZXJ5IHRhc2sgc3RydWN0IHRoYXQgZXZlbnQtPmN0eC0+dGFzayBjb3VsZCBwb3NzaWJseSBwb2ludCB0bwogKiByZW1haW5zIHZhbGlkLiAgVGhpcyBjb25kaXRpb24gaXMgc2F0aXNmaWVkIHdoZW4gY2FsbGVkIHRocm91Z2gKICogcGVyZl9ldmVudF9mb3JfZWFjaF9jaGlsZCBvciBwZXJmX2V2ZW50X2Zvcl9lYWNoIGFzIGRlc2NyaWJlZAogKiBmb3IgcGVyZl9ldmVudF9kaXNhYmxlLgogKi8Kdm9pZCBwZXJmX2V2ZW50X2VuYWJsZShzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQpCnsKCXN0cnVjdCBwZXJmX2V2ZW50X2NvbnRleHQgKmN0eCA9IGV2ZW50LT5jdHg7CglzdHJ1Y3QgdGFza19zdHJ1Y3QgKnRhc2sgPSBjdHgtPnRhc2s7CgoJaWYgKCF0YXNrKSB7CgkJLyoKCQkgKiBFbmFibGUgdGhlIGV2ZW50IG9uIHRoZSBjcHUgdGhhdCBpdCdzIG9uCgkJICovCgkJc21wX2NhbGxfZnVuY3Rpb25fc2luZ2xlKGV2ZW50LT5jcHUsIF9fcGVyZl9ldmVudF9lbmFibGUsCgkJCQkJIGV2ZW50LCAxKTsKCQlyZXR1cm47Cgl9CgoJcmF3X3NwaW5fbG9ja19pcnEoJmN0eC0+bG9jayk7CglpZiAoZXZlbnQtPnN0YXRlID49IFBFUkZfRVZFTlRfU1RBVEVfSU5BQ1RJVkUpCgkJZ290byBvdXQ7CgoJLyoKCSAqIElmIHRoZSBldmVudCBpcyBpbiBlcnJvciBzdGF0ZSwgY2xlYXIgdGhhdCBmaXJzdC4KCSAqIFRoYXQgd2F5LCBpZiB3ZSBzZWUgdGhlIGV2ZW50IGluIGVycm9yIHN0YXRlIGJlbG93LCB3ZQoJICoga25vdyB0aGF0IGl0IGhhcyBnb25lIGJhY2sgaW50byBlcnJvciBzdGF0ZSwgYXMgZGlzdGluY3QKCSAqIGZyb20gdGhlIHRhc2sgaGF2aW5nIGJlZW4gc2NoZWR1bGVkIGF3YXkgYmVmb3JlIHRoZQoJICogY3Jvc3MtY2FsbCBhcnJpdmVkLgoJICovCglpZiAoZXZlbnQtPnN0YXRlID09IFBFUkZfRVZFTlRfU1RBVEVfRVJST1IpCgkJZXZlbnQtPnN0YXRlID0gUEVSRl9FVkVOVF9TVEFURV9PRkY7CgpyZXRyeToKCXJhd19zcGluX3VubG9ja19pcnEoJmN0eC0+bG9jayk7Cgl0YXNrX29uY3B1X2Z1bmN0aW9uX2NhbGwodGFzaywgX19wZXJmX2V2ZW50X2VuYWJsZSwgZXZlbnQpOwoKCXJhd19zcGluX2xvY2tfaXJxKCZjdHgtPmxvY2spOwoKCS8qCgkgKiBJZiB0aGUgY29udGV4dCBpcyBhY3RpdmUgYW5kIHRoZSBldmVudCBpcyBzdGlsbCBvZmYsCgkgKiB3ZSBuZWVkIHRvIHJldHJ5IHRoZSBjcm9zcy1jYWxsLgoJICovCglpZiAoY3R4LT5pc19hY3RpdmUgJiYgZXZlbnQtPnN0YXRlID09IFBFUkZfRVZFTlRfU1RBVEVfT0ZGKQoJCWdvdG8gcmV0cnk7CgoJLyoKCSAqIFNpbmNlIHdlIGhhdmUgdGhlIGxvY2sgdGhpcyBjb250ZXh0IGNhbid0IGJlIHNjaGVkdWxlZAoJICogaW4sIHNvIHdlIGNhbiBjaGFuZ2UgdGhlIHN0YXRlIHNhZmVseS4KCSAqLwoJaWYgKGV2ZW50LT5zdGF0ZSA9PSBQRVJGX0VWRU5UX1NUQVRFX09GRikKCQlfX3BlcmZfZXZlbnRfbWFya19lbmFibGVkKGV2ZW50LCBjdHgpOwoKb3V0OgoJcmF3X3NwaW5fdW5sb2NrX2lycSgmY3R4LT5sb2NrKTsKfQoKc3RhdGljIGludCBwZXJmX2V2ZW50X3JlZnJlc2goc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50LCBpbnQgcmVmcmVzaCkKewoJLyoKCSAqIG5vdCBzdXBwb3J0ZWQgb24gaW5oZXJpdGVkIGV2ZW50cwoJICovCglpZiAoZXZlbnQtPmF0dHIuaW5oZXJpdCB8fCAhaXNfc2FtcGxpbmdfZXZlbnQoZXZlbnQpKQoJCXJldHVybiAtRUlOVkFMOwoKCWF0b21pY19hZGQocmVmcmVzaCwgJmV2ZW50LT5ldmVudF9saW1pdCk7CglwZXJmX2V2ZW50X2VuYWJsZShldmVudCk7CgoJcmV0dXJuIDA7Cn0KCnN0YXRpYyB2b2lkIGN0eF9zY2hlZF9vdXQoc3RydWN0IHBlcmZfZXZlbnRfY29udGV4dCAqY3R4LAoJCQkgIHN0cnVjdCBwZXJmX2NwdV9jb250ZXh0ICpjcHVjdHgsCgkJCSAgZW51bSBldmVudF90eXBlX3QgZXZlbnRfdHlwZSkKewoJc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50OwoKCXJhd19zcGluX2xvY2soJmN0eC0+bG9jayk7CglwZXJmX3BtdV9kaXNhYmxlKGN0eC0+cG11KTsKCWN0eC0+aXNfYWN0aXZlID0gMDsKCWlmIChsaWtlbHkoIWN0eC0+bnJfZXZlbnRzKSkKCQlnb3RvIG91dDsKCXVwZGF0ZV9jb250ZXh0X3RpbWUoY3R4KTsKCglpZiAoIWN0eC0+bnJfYWN0aXZlKQoJCWdvdG8gb3V0OwoKCWlmIChldmVudF90eXBlICYgRVZFTlRfUElOTkVEKSB7CgkJbGlzdF9mb3JfZWFjaF9lbnRyeShldmVudCwgJmN0eC0+cGlubmVkX2dyb3VwcywgZ3JvdXBfZW50cnkpCgkJCWdyb3VwX3NjaGVkX291dChldmVudCwgY3B1Y3R4LCBjdHgpOwoJfQoKCWlmIChldmVudF90eXBlICYgRVZFTlRfRkxFWElCTEUpIHsKCQlsaXN0X2Zvcl9lYWNoX2VudHJ5KGV2ZW50LCAmY3R4LT5mbGV4aWJsZV9ncm91cHMsIGdyb3VwX2VudHJ5KQoJCQlncm91cF9zY2hlZF9vdXQoZXZlbnQsIGNwdWN0eCwgY3R4KTsKCX0Kb3V0OgoJcGVyZl9wbXVfZW5hYmxlKGN0eC0+cG11KTsKCXJhd19zcGluX3VubG9jaygmY3R4LT5sb2NrKTsKfQoKLyoKICogVGVzdCB3aGV0aGVyIHR3byBjb250ZXh0cyBhcmUgZXF1aXZhbGVudCwgaS5lLiB3aGV0aGVyIHRoZXkKICogaGF2ZSBib3RoIGJlZW4gY2xvbmVkIGZyb20gdGhlIHNhbWUgdmVyc2lvbiBvZiB0aGUgc2FtZSBjb250ZXh0CiAqIGFuZCB0aGV5IGJvdGggaGF2ZSB0aGUgc2FtZSBudW1iZXIgb2YgZW5hYmxlZCBldmVudHMuCiAqIElmIHRoZSBudW1iZXIgb2YgZW5hYmxlZCBldmVudHMgaXMgdGhlIHNhbWUsIHRoZW4gdGhlIHNldAogKiBvZiBlbmFibGVkIGV2ZW50cyBzaG91bGQgYmUgdGhlIHNhbWUsIGJlY2F1c2UgdGhlc2UgYXJlIGJvdGgKICogaW5oZXJpdGVkIGNvbnRleHRzLCB0aGVyZWZvcmUgd2UgY2FuJ3QgYWNjZXNzIGluZGl2aWR1YWwgZXZlbnRzCiAqIGluIHRoZW0gZGlyZWN0bHkgd2l0aCBhbiBmZDsgd2UgY2FuIG9ubHkgZW5hYmxlL2Rpc2FibGUgYWxsCiAqIGV2ZW50cyB2aWEgcHJjdGwsIG9yIGVuYWJsZS9kaXNhYmxlIGFsbCBldmVudHMgaW4gYSBmYW1pbHkKICogdmlhIGlvY3RsLCB3aGljaCB3aWxsIGhhdmUgdGhlIHNhbWUgZWZmZWN0IG9uIGJvdGggY29udGV4dHMuCiAqLwpzdGF0aWMgaW50IGNvbnRleHRfZXF1aXYoc3RydWN0IHBlcmZfZXZlbnRfY29udGV4dCAqY3R4MSwKCQkJIHN0cnVjdCBwZXJmX2V2ZW50X2NvbnRleHQgKmN0eDIpCnsKCXJldHVybiBjdHgxLT5wYXJlbnRfY3R4ICYmIGN0eDEtPnBhcmVudF9jdHggPT0gY3R4Mi0+cGFyZW50X2N0eAoJCSYmIGN0eDEtPnBhcmVudF9nZW4gPT0gY3R4Mi0+cGFyZW50X2dlbgoJCSYmICFjdHgxLT5waW5fY291bnQgJiYgIWN0eDItPnBpbl9jb3VudDsKfQoKc3RhdGljIHZvaWQgX19wZXJmX2V2ZW50X3N5bmNfc3RhdChzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQsCgkJCQkgICAgIHN0cnVjdCBwZXJmX2V2ZW50ICpuZXh0X2V2ZW50KQp7Cgl1NjQgdmFsdWU7CgoJaWYgKCFldmVudC0+YXR0ci5pbmhlcml0X3N0YXQpCgkJcmV0dXJuOwoKCS8qCgkgKiBVcGRhdGUgdGhlIGV2ZW50IHZhbHVlLCB3ZSBjYW5ub3QgdXNlIHBlcmZfZXZlbnRfcmVhZCgpCgkgKiBiZWNhdXNlIHdlJ3JlIGluIHRoZSBtaWRkbGUgb2YgYSBjb250ZXh0IHN3aXRjaCBhbmQgaGF2ZSBJUlFzCgkgKiBkaXNhYmxlZCwgd2hpY2ggdXBzZXRzIHNtcF9jYWxsX2Z1bmN0aW9uX3NpbmdsZSgpLCBob3dldmVyCgkgKiB3ZSBrbm93IHRoZSBldmVudCBtdXN0IGJlIG9uIHRoZSBjdXJyZW50IENQVSwgdGhlcmVmb3JlIHdlCgkgKiBkb24ndCBuZWVkIHRvIHVzZSBpdC4KCSAqLwoJc3dpdGNoIChldmVudC0+c3RhdGUpIHsKCWNhc2UgUEVSRl9FVkVOVF9TVEFURV9BQ1RJVkU6CgkJZXZlbnQtPnBtdS0+cmVhZChldmVudCk7CgkJLyogZmFsbC10aHJvdWdoICovCgoJY2FzZSBQRVJGX0VWRU5UX1NUQVRFX0lOQUNUSVZFOgoJCXVwZGF0ZV9ldmVudF90aW1lcyhldmVudCk7CgkJYnJlYWs7CgoJZGVmYXVsdDoKCQlicmVhazsKCX0KCgkvKgoJICogSW4gb3JkZXIgdG8ga2VlcCBwZXItdGFzayBzdGF0cyByZWxpYWJsZSB3ZSBuZWVkIHRvIGZsaXAgdGhlIGV2ZW50CgkgKiB2YWx1ZXMgd2hlbiB3ZSBmbGlwIHRoZSBjb250ZXh0cy4KCSAqLwoJdmFsdWUgPSBsb2NhbDY0X3JlYWQoJm5leHRfZXZlbnQtPmNvdW50KTsKCXZhbHVlID0gbG9jYWw2NF94Y2hnKCZldmVudC0+Y291bnQsIHZhbHVlKTsKCWxvY2FsNjRfc2V0KCZuZXh0X2V2ZW50LT5jb3VudCwgdmFsdWUpOwoKCXN3YXAoZXZlbnQtPnRvdGFsX3RpbWVfZW5hYmxlZCwgbmV4dF9ldmVudC0+dG90YWxfdGltZV9lbmFibGVkKTsKCXN3YXAoZXZlbnQtPnRvdGFsX3RpbWVfcnVubmluZywgbmV4dF9ldmVudC0+dG90YWxfdGltZV9ydW5uaW5nKTsKCgkvKgoJICogU2luY2Ugd2Ugc3dpenpsZWQgdGhlIHZhbHVlcywgdXBkYXRlIHRoZSB1c2VyIHZpc2libGUgZGF0YSB0b28uCgkgKi8KCXBlcmZfZXZlbnRfdXBkYXRlX3VzZXJwYWdlKGV2ZW50KTsKCXBlcmZfZXZlbnRfdXBkYXRlX3VzZXJwYWdlKG5leHRfZXZlbnQpOwp9CgojZGVmaW5lIGxpc3RfbmV4dF9lbnRyeShwb3MsIG1lbWJlcikgXAoJbGlzdF9lbnRyeShwb3MtPm1lbWJlci5uZXh0LCB0eXBlb2YoKnBvcyksIG1lbWJlcikKCnN0YXRpYyB2b2lkIHBlcmZfZXZlbnRfc3luY19zdGF0KHN0cnVjdCBwZXJmX2V2ZW50X2NvbnRleHQgKmN0eCwKCQkJCSAgIHN0cnVjdCBwZXJmX2V2ZW50X2NvbnRleHQgKm5leHRfY3R4KQp7CglzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQsICpuZXh0X2V2ZW50OwoKCWlmICghY3R4LT5ucl9zdGF0KQoJCXJldHVybjsKCgl1cGRhdGVfY29udGV4dF90aW1lKGN0eCk7CgoJZXZlbnQgPSBsaXN0X2ZpcnN0X2VudHJ5KCZjdHgtPmV2ZW50X2xpc3QsCgkJCQkgICBzdHJ1Y3QgcGVyZl9ldmVudCwgZXZlbnRfZW50cnkpOwoKCW5leHRfZXZlbnQgPSBsaXN0X2ZpcnN0X2VudHJ5KCZuZXh0X2N0eC0+ZXZlbnRfbGlzdCwKCQkJCQlzdHJ1Y3QgcGVyZl9ldmVudCwgZXZlbnRfZW50cnkpOwoKCXdoaWxlICgmZXZlbnQtPmV2ZW50X2VudHJ5ICE9ICZjdHgtPmV2ZW50X2xpc3QgJiYKCSAgICAgICAmbmV4dF9ldmVudC0+ZXZlbnRfZW50cnkgIT0gJm5leHRfY3R4LT5ldmVudF9saXN0KSB7CgoJCV9fcGVyZl9ldmVudF9zeW5jX3N0YXQoZXZlbnQsIG5leHRfZXZlbnQpOwoKCQlldmVudCA9IGxpc3RfbmV4dF9lbnRyeShldmVudCwgZXZlbnRfZW50cnkpOwoJCW5leHRfZXZlbnQgPSBsaXN0X25leHRfZW50cnkobmV4dF9ldmVudCwgZXZlbnRfZW50cnkpOwoJfQp9Cgp2b2lkIHBlcmZfZXZlbnRfY29udGV4dF9zY2hlZF9vdXQoc3RydWN0IHRhc2tfc3RydWN0ICp0YXNrLCBpbnQgY3R4biwKCQkJCSAgc3RydWN0IHRhc2tfc3RydWN0ICpuZXh0KQp7CglzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0ICpjdHggPSB0YXNrLT5wZXJmX2V2ZW50X2N0eHBbY3R4bl07CglzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0ICpuZXh0X2N0eDsKCXN0cnVjdCBwZXJmX2V2ZW50X2NvbnRleHQgKnBhcmVudDsKCXN0cnVjdCBwZXJmX2NwdV9jb250ZXh0ICpjcHVjdHg7CglpbnQgZG9fc3dpdGNoID0gMTsKCglpZiAobGlrZWx5KCFjdHgpKQoJCXJldHVybjsKCgljcHVjdHggPSBfX2dldF9jcHVfY29udGV4dChjdHgpOwoJaWYgKCFjcHVjdHgtPnRhc2tfY3R4KQoJCXJldHVybjsKCglyY3VfcmVhZF9sb2NrKCk7CglwYXJlbnQgPSByY3VfZGVyZWZlcmVuY2UoY3R4LT5wYXJlbnRfY3R4KTsKCW5leHRfY3R4ID0gbmV4dC0+cGVyZl9ldmVudF9jdHhwW2N0eG5dOwoJaWYgKHBhcmVudCAmJiBuZXh0X2N0eCAmJgoJICAgIHJjdV9kZXJlZmVyZW5jZShuZXh0X2N0eC0+cGFyZW50X2N0eCkgPT0gcGFyZW50KSB7CgkJLyoKCQkgKiBMb29rcyBsaWtlIHRoZSB0d28gY29udGV4dHMgYXJlIGNsb25lcywgc28gd2UgbWlnaHQgYmUKCQkgKiBhYmxlIHRvIG9wdGltaXplIHRoZSBjb250ZXh0IHN3aXRjaC4gIFdlIGxvY2sgYm90aAoJCSAqIGNvbnRleHRzIGFuZCBjaGVjayB0aGF0IHRoZXkgYXJlIGNsb25lcyB1bmRlciB0aGUKCQkgKiBsb2NrIChpbmNsdWRpbmcgcmUtY2hlY2tpbmcgdGhhdCBuZWl0aGVyIGhhcyBiZWVuCgkJICogdW5jbG9uZWQgaW4gdGhlIG1lYW50aW1lKS4gIEl0IGRvZXNuJ3QgbWF0dGVyIHdoaWNoCgkJICogb3JkZXIgd2UgdGFrZSB0aGUgbG9ja3MgYmVjYXVzZSBubyBvdGhlciBjcHUgY291bGQKCQkgKiBiZSB0cnlpbmcgdG8gbG9jayBib3RoIG9mIHRoZXNlIHRhc2tzLgoJCSAqLwoJCXJhd19zcGluX2xvY2soJmN0eC0+bG9jayk7CgkJcmF3X3NwaW5fbG9ja19uZXN0ZWQoJm5leHRfY3R4LT5sb2NrLCBTSU5HTEVfREVQVEhfTkVTVElORyk7CgkJaWYgKGNvbnRleHRfZXF1aXYoY3R4LCBuZXh0X2N0eCkpIHsKCQkJLyoKCQkJICogWFhYIGRvIHdlIG5lZWQgYSBtZW1vcnkgYmFycmllciBvZiBzb3J0cwoJCQkgKiB3cnQgdG8gcmN1X2RlcmVmZXJlbmNlKCkgb2YgcGVyZl9ldmVudF9jdHhwCgkJCSAqLwoJCQl0YXNrLT5wZXJmX2V2ZW50X2N0eHBbY3R4bl0gPSBuZXh0X2N0eDsKCQkJbmV4dC0+cGVyZl9ldmVudF9jdHhwW2N0eG5dID0gY3R4OwoJCQljdHgtPnRhc2sgPSBuZXh0OwoJCQluZXh0X2N0eC0+dGFzayA9IHRhc2s7CgkJCWRvX3N3aXRjaCA9IDA7CgoJCQlwZXJmX2V2ZW50X3N5bmNfc3RhdChjdHgsIG5leHRfY3R4KTsKCQl9CgkJcmF3X3NwaW5fdW5sb2NrKCZuZXh0X2N0eC0+bG9jayk7CgkJcmF3X3NwaW5fdW5sb2NrKCZjdHgtPmxvY2spOwoJfQoJcmN1X3JlYWRfdW5sb2NrKCk7CgoJaWYgKGRvX3N3aXRjaCkgewoJCWN0eF9zY2hlZF9vdXQoY3R4LCBjcHVjdHgsIEVWRU5UX0FMTCk7CgkJY3B1Y3R4LT50YXNrX2N0eCA9IE5VTEw7Cgl9Cn0KCiNkZWZpbmUgZm9yX2VhY2hfdGFza19jb250ZXh0X25yKGN0eG4pCQkJCQlcCglmb3IgKChjdHhuKSA9IDA7IChjdHhuKSA8IHBlcmZfbnJfdGFza19jb250ZXh0czsgKGN0eG4pKyspCgovKgogKiBDYWxsZWQgZnJvbSBzY2hlZHVsZXIgdG8gcmVtb3ZlIHRoZSBldmVudHMgb2YgdGhlIGN1cnJlbnQgdGFzaywKICogd2l0aCBpbnRlcnJ1cHRzIGRpc2FibGVkLgogKgogKiBXZSBzdG9wIGVhY2ggZXZlbnQgYW5kIHVwZGF0ZSB0aGUgZXZlbnQgdmFsdWUgaW4gZXZlbnQtPmNvdW50LgogKgogKiBUaGlzIGRvZXMgbm90IHByb3RlY3QgdXMgYWdhaW5zdCBOTUksIGJ1dCBkaXNhYmxlKCkKICogc2V0cyB0aGUgZGlzYWJsZWQgYml0IGluIHRoZSBjb250cm9sIGZpZWxkIG9mIGV2ZW50IF9iZWZvcmVfCiAqIGFjY2Vzc2luZyB0aGUgZXZlbnQgY29udHJvbCByZWdpc3Rlci4gSWYgYSBOTUkgaGl0cywgdGhlbiBpdCB3aWxsCiAqIG5vdCByZXN0YXJ0IHRoZSBldmVudC4KICovCnZvaWQgX19wZXJmX2V2ZW50X3Rhc2tfc2NoZWRfb3V0KHN0cnVjdCB0YXNrX3N0cnVjdCAqdGFzaywKCQkJCSBzdHJ1Y3QgdGFza19zdHJ1Y3QgKm5leHQpCnsKCWludCBjdHhuOwoKCWZvcl9lYWNoX3Rhc2tfY29udGV4dF9ucihjdHhuKQoJCXBlcmZfZXZlbnRfY29udGV4dF9zY2hlZF9vdXQodGFzaywgY3R4biwgbmV4dCk7Cn0KCnN0YXRpYyB2b2lkIHRhc2tfY3R4X3NjaGVkX291dChzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0ICpjdHgsCgkJCSAgICAgICBlbnVtIGV2ZW50X3R5cGVfdCBldmVudF90eXBlKQp7CglzdHJ1Y3QgcGVyZl9jcHVfY29udGV4dCAqY3B1Y3R4ID0gX19nZXRfY3B1X2NvbnRleHQoY3R4KTsKCglpZiAoIWNwdWN0eC0+dGFza19jdHgpCgkJcmV0dXJuOwoKCWlmIChXQVJOX09OX09OQ0UoY3R4ICE9IGNwdWN0eC0+dGFza19jdHgpKQoJCXJldHVybjsKCgljdHhfc2NoZWRfb3V0KGN0eCwgY3B1Y3R4LCBldmVudF90eXBlKTsKCWNwdWN0eC0+dGFza19jdHggPSBOVUxMOwp9CgovKgogKiBDYWxsZWQgd2l0aCBJUlFzIGRpc2FibGVkCiAqLwpzdGF0aWMgdm9pZCBjcHVfY3R4X3NjaGVkX291dChzdHJ1Y3QgcGVyZl9jcHVfY29udGV4dCAqY3B1Y3R4LAoJCQkgICAgICBlbnVtIGV2ZW50X3R5cGVfdCBldmVudF90eXBlKQp7CgljdHhfc2NoZWRfb3V0KCZjcHVjdHgtPmN0eCwgY3B1Y3R4LCBldmVudF90eXBlKTsKfQoKc3RhdGljIHZvaWQKY3R4X3Bpbm5lZF9zY2hlZF9pbihzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0ICpjdHgsCgkJICAgIHN0cnVjdCBwZXJmX2NwdV9jb250ZXh0ICpjcHVjdHgpCnsKCXN0cnVjdCBwZXJmX2V2ZW50ICpldmVudDsKCglsaXN0X2Zvcl9lYWNoX2VudHJ5KGV2ZW50LCAmY3R4LT5waW5uZWRfZ3JvdXBzLCBncm91cF9lbnRyeSkgewoJCWlmIChldmVudC0+c3RhdGUgPD0gUEVSRl9FVkVOVF9TVEFURV9PRkYpCgkJCWNvbnRpbnVlOwoJCWlmICghZXZlbnRfZmlsdGVyX21hdGNoKGV2ZW50KSkKCQkJY29udGludWU7CgoJCWlmIChncm91cF9jYW5fZ29fb24oZXZlbnQsIGNwdWN0eCwgMSkpCgkJCWdyb3VwX3NjaGVkX2luKGV2ZW50LCBjcHVjdHgsIGN0eCk7CgoJCS8qCgkJICogSWYgdGhpcyBwaW5uZWQgZ3JvdXAgaGFzbid0IGJlZW4gc2NoZWR1bGVkLAoJCSAqIHB1dCBpdCBpbiBlcnJvciBzdGF0ZS4KCQkgKi8KCQlpZiAoZXZlbnQtPnN0YXRlID09IFBFUkZfRVZFTlRfU1RBVEVfSU5BQ1RJVkUpIHsKCQkJdXBkYXRlX2dyb3VwX3RpbWVzKGV2ZW50KTsKCQkJZXZlbnQtPnN0YXRlID0gUEVSRl9FVkVOVF9TVEFURV9FUlJPUjsKCQl9Cgl9Cn0KCnN0YXRpYyB2b2lkCmN0eF9mbGV4aWJsZV9zY2hlZF9pbihzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0ICpjdHgsCgkJICAgICAgc3RydWN0IHBlcmZfY3B1X2NvbnRleHQgKmNwdWN0eCkKewoJc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50OwoJaW50IGNhbl9hZGRfaHcgPSAxOwoKCWxpc3RfZm9yX2VhY2hfZW50cnkoZXZlbnQsICZjdHgtPmZsZXhpYmxlX2dyb3VwcywgZ3JvdXBfZW50cnkpIHsKCQkvKiBJZ25vcmUgZXZlbnRzIGluIE9GRiBvciBFUlJPUiBzdGF0ZSAqLwoJCWlmIChldmVudC0+c3RhdGUgPD0gUEVSRl9FVkVOVF9TVEFURV9PRkYpCgkJCWNvbnRpbnVlOwoJCS8qCgkJICogTGlzdGVuIHRvIHRoZSAnY3B1JyBzY2hlZHVsaW5nIGZpbHRlciBjb25zdHJhaW50CgkJICogb2YgZXZlbnRzOgoJCSAqLwoJCWlmICghZXZlbnRfZmlsdGVyX21hdGNoKGV2ZW50KSkKCQkJY29udGludWU7CgoJCWlmIChncm91cF9jYW5fZ29fb24oZXZlbnQsIGNwdWN0eCwgY2FuX2FkZF9odykpIHsKCQkJaWYgKGdyb3VwX3NjaGVkX2luKGV2ZW50LCBjcHVjdHgsIGN0eCkpCgkJCQljYW5fYWRkX2h3ID0gMDsKCQl9Cgl9Cn0KCnN0YXRpYyB2b2lkCmN0eF9zY2hlZF9pbihzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0ICpjdHgsCgkgICAgIHN0cnVjdCBwZXJmX2NwdV9jb250ZXh0ICpjcHVjdHgsCgkgICAgIGVudW0gZXZlbnRfdHlwZV90IGV2ZW50X3R5cGUpCnsKCXJhd19zcGluX2xvY2soJmN0eC0+bG9jayk7CgljdHgtPmlzX2FjdGl2ZSA9IDE7CglpZiAobGlrZWx5KCFjdHgtPm5yX2V2ZW50cykpCgkJZ290byBvdXQ7CgoJY3R4LT50aW1lc3RhbXAgPSBwZXJmX2Nsb2NrKCk7CgoJLyoKCSAqIEZpcnN0IGdvIHRocm91Z2ggdGhlIGxpc3QgYW5kIHB1dCBvbiBhbnkgcGlubmVkIGdyb3VwcwoJICogaW4gb3JkZXIgdG8gZ2l2ZSB0aGVtIHRoZSBiZXN0IGNoYW5jZSBvZiBnb2luZyBvbi4KCSAqLwoJaWYgKGV2ZW50X3R5cGUgJiBFVkVOVF9QSU5ORUQpCgkJY3R4X3Bpbm5lZF9zY2hlZF9pbihjdHgsIGNwdWN0eCk7CgoJLyogVGhlbiB3YWxrIHRocm91Z2ggdGhlIGxvd2VyIHByaW8gZmxleGlibGUgZ3JvdXBzICovCglpZiAoZXZlbnRfdHlwZSAmIEVWRU5UX0ZMRVhJQkxFKQoJCWN0eF9mbGV4aWJsZV9zY2hlZF9pbihjdHgsIGNwdWN0eCk7CgpvdXQ6CglyYXdfc3Bpbl91bmxvY2soJmN0eC0+bG9jayk7Cn0KCnN0YXRpYyB2b2lkIGNwdV9jdHhfc2NoZWRfaW4oc3RydWN0IHBlcmZfY3B1X2NvbnRleHQgKmNwdWN0eCwKCQkJICAgICBlbnVtIGV2ZW50X3R5cGVfdCBldmVudF90eXBlKQp7CglzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0ICpjdHggPSAmY3B1Y3R4LT5jdHg7CgoJY3R4X3NjaGVkX2luKGN0eCwgY3B1Y3R4LCBldmVudF90eXBlKTsKfQoKc3RhdGljIHZvaWQgdGFza19jdHhfc2NoZWRfaW4oc3RydWN0IHBlcmZfZXZlbnRfY29udGV4dCAqY3R4LAoJCQkgICAgICBlbnVtIGV2ZW50X3R5cGVfdCBldmVudF90eXBlKQp7CglzdHJ1Y3QgcGVyZl9jcHVfY29udGV4dCAqY3B1Y3R4OwoKICAgICAgIAljcHVjdHggPSBfX2dldF9jcHVfY29udGV4dChjdHgpOwoJaWYgKGNwdWN0eC0+dGFza19jdHggPT0gY3R4KQoJCXJldHVybjsKCgljdHhfc2NoZWRfaW4oY3R4LCBjcHVjdHgsIGV2ZW50X3R5cGUpOwoJY3B1Y3R4LT50YXNrX2N0eCA9IGN0eDsKfQoKdm9pZCBwZXJmX2V2ZW50X2NvbnRleHRfc2NoZWRfaW4oc3RydWN0IHBlcmZfZXZlbnRfY29udGV4dCAqY3R4KQp7CglzdHJ1Y3QgcGVyZl9jcHVfY29udGV4dCAqY3B1Y3R4OwoKCWNwdWN0eCA9IF9fZ2V0X2NwdV9jb250ZXh0KGN0eCk7CglpZiAoY3B1Y3R4LT50YXNrX2N0eCA9PSBjdHgpCgkJcmV0dXJuOwoKCXBlcmZfcG11X2Rpc2FibGUoY3R4LT5wbXUpOwoJLyoKCSAqIFdlIHdhbnQgdG8ga2VlcCB0aGUgZm9sbG93aW5nIHByaW9yaXR5IG9yZGVyOgoJICogY3B1IHBpbm5lZCAodGhhdCBkb24ndCBuZWVkIHRvIG1vdmUpLCB0YXNrIHBpbm5lZCwKCSAqIGNwdSBmbGV4aWJsZSwgdGFzayBmbGV4aWJsZS4KCSAqLwoJY3B1X2N0eF9zY2hlZF9vdXQoY3B1Y3R4LCBFVkVOVF9GTEVYSUJMRSk7CgoJY3R4X3NjaGVkX2luKGN0eCwgY3B1Y3R4LCBFVkVOVF9QSU5ORUQpOwoJY3B1X2N0eF9zY2hlZF9pbihjcHVjdHgsIEVWRU5UX0ZMRVhJQkxFKTsKCWN0eF9zY2hlZF9pbihjdHgsIGNwdWN0eCwgRVZFTlRfRkxFWElCTEUpOwoKCWNwdWN0eC0+dGFza19jdHggPSBjdHg7CgoJLyoKCSAqIFNpbmNlIHRoZXNlIHJvdGF0aW9ucyBhcmUgcGVyLWNwdSwgd2UgbmVlZCB0byBlbnN1cmUgdGhlCgkgKiBjcHUtY29udGV4dCB3ZSBnb3Qgc2NoZWR1bGVkIG9uIGlzIGFjdHVhbGx5IHJvdGF0aW5nLgoJICovCglwZXJmX3BtdV9yb3RhdGVfc3RhcnQoY3R4LT5wbXUpOwoJcGVyZl9wbXVfZW5hYmxlKGN0eC0+cG11KTsKfQoKLyoKICogQ2FsbGVkIGZyb20gc2NoZWR1bGVyIHRvIGFkZCB0aGUgZXZlbnRzIG9mIHRoZSBjdXJyZW50IHRhc2sKICogd2l0aCBpbnRlcnJ1cHRzIGRpc2FibGVkLgogKgogKiBXZSByZXN0b3JlIHRoZSBldmVudCB2YWx1ZSBhbmQgdGhlbiBlbmFibGUgaXQuCiAqCiAqIFRoaXMgZG9lcyBub3QgcHJvdGVjdCB1cyBhZ2FpbnN0IE5NSSwgYnV0IGVuYWJsZSgpCiAqIHNldHMgdGhlIGVuYWJsZWQgYml0IGluIHRoZSBjb250cm9sIGZpZWxkIG9mIGV2ZW50IF9iZWZvcmVfCiAqIGFjY2Vzc2luZyB0aGUgZXZlbnQgY29udHJvbCByZWdpc3Rlci4gSWYgYSBOTUkgaGl0cywgdGhlbiBpdCB3aWxsCiAqIGtlZXAgdGhlIGV2ZW50IHJ1bm5pbmcuCiAqLwp2b2lkIF9fcGVyZl9ldmVudF90YXNrX3NjaGVkX2luKHN0cnVjdCB0YXNrX3N0cnVjdCAqdGFzaykKewoJc3RydWN0IHBlcmZfZXZlbnRfY29udGV4dCAqY3R4OwoJaW50IGN0eG47CgoJZm9yX2VhY2hfdGFza19jb250ZXh0X25yKGN0eG4pIHsKCQljdHggPSB0YXNrLT5wZXJmX2V2ZW50X2N0eHBbY3R4bl07CgkJaWYgKGxpa2VseSghY3R4KSkKCQkJY29udGludWU7CgoJCXBlcmZfZXZlbnRfY29udGV4dF9zY2hlZF9pbihjdHgpOwoJfQp9CgojZGVmaW5lIE1BWF9JTlRFUlJVUFRTICh+MFVMTCkKCnN0YXRpYyB2b2lkIHBlcmZfbG9nX3Rocm90dGxlKHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCwgaW50IGVuYWJsZSk7CgpzdGF0aWMgdTY0IHBlcmZfY2FsY3VsYXRlX3BlcmlvZChzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQsIHU2NCBuc2VjLCB1NjQgY291bnQpCnsKCXU2NCBmcmVxdWVuY3kgPSBldmVudC0+YXR0ci5zYW1wbGVfZnJlcTsKCXU2NCBzZWMgPSBOU0VDX1BFUl9TRUM7Cgl1NjQgZGl2aXNvciwgZGl2aWRlbmQ7CgoJaW50IGNvdW50X2ZscywgbnNlY19mbHMsIGZyZXF1ZW5jeV9mbHMsIHNlY19mbHM7CgoJY291bnRfZmxzID0gZmxzNjQoY291bnQpOwoJbnNlY19mbHMgPSBmbHM2NChuc2VjKTsKCWZyZXF1ZW5jeV9mbHMgPSBmbHM2NChmcmVxdWVuY3kpOwoJc2VjX2ZscyA9IDMwOwoKCS8qCgkgKiBXZSBnb3QgQGNvdW50IGluIEBuc2VjLCB3aXRoIGEgdGFyZ2V0IG9mIHNhbXBsZV9mcmVxIEhaCgkgKiB0aGUgdGFyZ2V0IHBlcmlvZCBiZWNvbWVzOgoJICoKCSAqICAgICAgICAgICAgIEBjb3VudCAqIDEwXjkKCSAqIHBlcmlvZCA9IC0tLS0tLS0tLS0tLS0tLS0tLS0KCSAqICAgICAgICAgIEBuc2VjICogc2FtcGxlX2ZyZXEKCSAqCgkgKi8KCgkvKgoJICogUmVkdWNlIGFjY3VyYWN5IGJ5IG9uZSBiaXQgc3VjaCB0aGF0IEBhIGFuZCBAYiBjb252ZXJnZQoJICogdG8gYSBzaW1pbGFyIG1hZ25pdHVkZS4KCSAqLwojZGVmaW5lIFJFRFVDRV9GTFMoYSwgYikgCQlcCmRvIHsJCQkJCVwKCWlmIChhIyNfZmxzID4gYiMjX2ZscykgewlcCgkJYSA+Pj0gMTsJCVwKCQlhIyNfZmxzLS07CQlcCgl9IGVsc2UgewkJCVwKCQliID4+PSAxOwkJXAoJCWIjI19mbHMtLTsJCVwKCX0JCQkJXAp9IHdoaWxlICgwKQoKCS8qCgkgKiBSZWR1Y2UgYWNjdXJhY3kgdW50aWwgZWl0aGVyIHRlcm0gZml0cyBpbiBhIHU2NCwgdGhlbiBwcm9jZWVkIHdpdGgKCSAqIHRoZSBvdGhlciwgc28gdGhhdCBmaW5hbGx5IHdlIGNhbiBkbyBhIHU2NC91NjQgZGl2aXNpb24uCgkgKi8KCXdoaWxlIChjb3VudF9mbHMgKyBzZWNfZmxzID4gNjQgJiYgbnNlY19mbHMgKyBmcmVxdWVuY3lfZmxzID4gNjQpIHsKCQlSRURVQ0VfRkxTKG5zZWMsIGZyZXF1ZW5jeSk7CgkJUkVEVUNFX0ZMUyhzZWMsIGNvdW50KTsKCX0KCglpZiAoY291bnRfZmxzICsgc2VjX2ZscyA+IDY0KSB7CgkJZGl2aXNvciA9IG5zZWMgKiBmcmVxdWVuY3k7CgoJCXdoaWxlIChjb3VudF9mbHMgKyBzZWNfZmxzID4gNjQpIHsKCQkJUkVEVUNFX0ZMUyhjb3VudCwgc2VjKTsKCQkJZGl2aXNvciA+Pj0gMTsKCQl9CgoJCWRpdmlkZW5kID0gY291bnQgKiBzZWM7Cgl9IGVsc2UgewoJCWRpdmlkZW5kID0gY291bnQgKiBzZWM7CgoJCXdoaWxlIChuc2VjX2ZscyArIGZyZXF1ZW5jeV9mbHMgPiA2NCkgewoJCQlSRURVQ0VfRkxTKG5zZWMsIGZyZXF1ZW5jeSk7CgkJCWRpdmlkZW5kID4+PSAxOwoJCX0KCgkJZGl2aXNvciA9IG5zZWMgKiBmcmVxdWVuY3k7Cgl9CgoJaWYgKCFkaXZpc29yKQoJCXJldHVybiBkaXZpZGVuZDsKCglyZXR1cm4gZGl2NjRfdTY0KGRpdmlkZW5kLCBkaXZpc29yKTsKfQoKc3RhdGljIHZvaWQgcGVyZl9hZGp1c3RfcGVyaW9kKHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCwgdTY0IG5zZWMsIHU2NCBjb3VudCkKewoJc3RydWN0IGh3X3BlcmZfZXZlbnQgKmh3YyA9ICZldmVudC0+aHc7CglzNjQgcGVyaW9kLCBzYW1wbGVfcGVyaW9kOwoJczY0IGRlbHRhOwoKCXBlcmlvZCA9IHBlcmZfY2FsY3VsYXRlX3BlcmlvZChldmVudCwgbnNlYywgY291bnQpOwoKCWRlbHRhID0gKHM2NCkocGVyaW9kIC0gaHdjLT5zYW1wbGVfcGVyaW9kKTsKCWRlbHRhID0gKGRlbHRhICsgNykgLyA4OyAvKiBsb3cgcGFzcyBmaWx0ZXIgKi8KCglzYW1wbGVfcGVyaW9kID0gaHdjLT5zYW1wbGVfcGVyaW9kICsgZGVsdGE7CgoJaWYgKCFzYW1wbGVfcGVyaW9kKQoJCXNhbXBsZV9wZXJpb2QgPSAxOwoKCWh3Yy0+c2FtcGxlX3BlcmlvZCA9IHNhbXBsZV9wZXJpb2Q7CgoJaWYgKGxvY2FsNjRfcmVhZCgmaHdjLT5wZXJpb2RfbGVmdCkgPiA4KnNhbXBsZV9wZXJpb2QpIHsKCQlldmVudC0+cG11LT5zdG9wKGV2ZW50LCBQRVJGX0VGX1VQREFURSk7CgkJbG9jYWw2NF9zZXQoJmh3Yy0+cGVyaW9kX2xlZnQsIDApOwoJCWV2ZW50LT5wbXUtPnN0YXJ0KGV2ZW50LCBQRVJGX0VGX1JFTE9BRCk7Cgl9Cn0KCnN0YXRpYyB2b2lkIHBlcmZfY3R4X2FkanVzdF9mcmVxKHN0cnVjdCBwZXJmX2V2ZW50X2NvbnRleHQgKmN0eCwgdTY0IHBlcmlvZCkKewoJc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50OwoJc3RydWN0IGh3X3BlcmZfZXZlbnQgKmh3YzsKCXU2NCBpbnRlcnJ1cHRzLCBub3c7CglzNjQgZGVsdGE7CgoJcmF3X3NwaW5fbG9jaygmY3R4LT5sb2NrKTsKCWxpc3RfZm9yX2VhY2hfZW50cnlfcmN1KGV2ZW50LCAmY3R4LT5ldmVudF9saXN0LCBldmVudF9lbnRyeSkgewoJCWlmIChldmVudC0+c3RhdGUgIT0gUEVSRl9FVkVOVF9TVEFURV9BQ1RJVkUpCgkJCWNvbnRpbnVlOwoKCQlpZiAoIWV2ZW50X2ZpbHRlcl9tYXRjaChldmVudCkpCgkJCWNvbnRpbnVlOwoKCQlod2MgPSAmZXZlbnQtPmh3OwoKCQlpbnRlcnJ1cHRzID0gaHdjLT5pbnRlcnJ1cHRzOwoJCWh3Yy0+aW50ZXJydXB0cyA9IDA7CgoJCS8qCgkJICogdW50aHJvdHRsZSBldmVudHMgb24gdGhlIHRpY2sKCQkgKi8KCQlpZiAoaW50ZXJydXB0cyA9PSBNQVhfSU5URVJSVVBUUykgewoJCQlwZXJmX2xvZ190aHJvdHRsZShldmVudCwgMSk7CgkJCWV2ZW50LT5wbXUtPnN0YXJ0KGV2ZW50LCAwKTsKCQl9CgoJCWlmICghZXZlbnQtPmF0dHIuZnJlcSB8fCAhZXZlbnQtPmF0dHIuc2FtcGxlX2ZyZXEpCgkJCWNvbnRpbnVlOwoKCQlldmVudC0+cG11LT5yZWFkKGV2ZW50KTsKCQlub3cgPSBsb2NhbDY0X3JlYWQoJmV2ZW50LT5jb3VudCk7CgkJZGVsdGEgPSBub3cgLSBod2MtPmZyZXFfY291bnRfc3RhbXA7CgkJaHdjLT5mcmVxX2NvdW50X3N0YW1wID0gbm93OwoKCQlpZiAoZGVsdGEgPiAwKQoJCQlwZXJmX2FkanVzdF9wZXJpb2QoZXZlbnQsIHBlcmlvZCwgZGVsdGEpOwoJfQoJcmF3X3NwaW5fdW5sb2NrKCZjdHgtPmxvY2spOwp9CgovKgogKiBSb3VuZC1yb2JpbiBhIGNvbnRleHQncyBldmVudHM6CiAqLwpzdGF0aWMgdm9pZCByb3RhdGVfY3R4KHN0cnVjdCBwZXJmX2V2ZW50X2NvbnRleHQgKmN0eCkKewoJcmF3X3NwaW5fbG9jaygmY3R4LT5sb2NrKTsKCgkvKgoJICogUm90YXRlIHRoZSBmaXJzdCBlbnRyeSBsYXN0IG9mIG5vbi1waW5uZWQgZ3JvdXBzLiBSb3RhdGlvbiBtaWdodCBiZQoJICogZGlzYWJsZWQgYnkgdGhlIGluaGVyaXRhbmNlIGNvZGUuCgkgKi8KCWlmICghY3R4LT5yb3RhdGVfZGlzYWJsZSkKCQlsaXN0X3JvdGF0ZV9sZWZ0KCZjdHgtPmZsZXhpYmxlX2dyb3Vwcyk7CgoJcmF3X3NwaW5fdW5sb2NrKCZjdHgtPmxvY2spOwp9CgovKgogKiBwZXJmX3BtdV9yb3RhdGVfc3RhcnQoKSBhbmQgcGVyZl9yb3RhdGVfY29udGV4dCgpIGFyZSBmdWxseSBzZXJpYWxpemVkCiAqIGJlY2F1c2UgdGhleSdyZSBzdHJpY3RseSBjcHUgYWZmaW5lIGFuZCByb3RhdGVfc3RhcnQgaXMgY2FsbGVkIHdpdGggSVJRcwogKiBkaXNhYmxlZCwgd2hpbGUgcm90YXRlX2NvbnRleHQgaXMgY2FsbGVkIGZyb20gSVJRIGNvbnRleHQuCiAqLwpzdGF0aWMgdm9pZCBwZXJmX3JvdGF0ZV9jb250ZXh0KHN0cnVjdCBwZXJmX2NwdV9jb250ZXh0ICpjcHVjdHgpCnsKCXU2NCBpbnRlcnZhbCA9ICh1NjQpY3B1Y3R4LT5qaWZmaWVzX2ludGVydmFsICogVElDS19OU0VDOwoJc3RydWN0IHBlcmZfZXZlbnRfY29udGV4dCAqY3R4ID0gTlVMTDsKCWludCByb3RhdGUgPSAwLCByZW1vdmUgPSAxOwoKCWlmIChjcHVjdHgtPmN0eC5ucl9ldmVudHMpIHsKCQlyZW1vdmUgPSAwOwoJCWlmIChjcHVjdHgtPmN0eC5ucl9ldmVudHMgIT0gY3B1Y3R4LT5jdHgubnJfYWN0aXZlKQoJCQlyb3RhdGUgPSAxOwoJfQoKCWN0eCA9IGNwdWN0eC0+dGFza19jdHg7CglpZiAoY3R4ICYmIGN0eC0+bnJfZXZlbnRzKSB7CgkJcmVtb3ZlID0gMDsKCQlpZiAoY3R4LT5ucl9ldmVudHMgIT0gY3R4LT5ucl9hY3RpdmUpCgkJCXJvdGF0ZSA9IDE7Cgl9CgoJcGVyZl9wbXVfZGlzYWJsZShjcHVjdHgtPmN0eC5wbXUpOwoJcGVyZl9jdHhfYWRqdXN0X2ZyZXEoJmNwdWN0eC0+Y3R4LCBpbnRlcnZhbCk7CglpZiAoY3R4KQoJCXBlcmZfY3R4X2FkanVzdF9mcmVxKGN0eCwgaW50ZXJ2YWwpOwoKCWlmICghcm90YXRlKQoJCWdvdG8gZG9uZTsKCgljcHVfY3R4X3NjaGVkX291dChjcHVjdHgsIEVWRU5UX0ZMRVhJQkxFKTsKCWlmIChjdHgpCgkJdGFza19jdHhfc2NoZWRfb3V0KGN0eCwgRVZFTlRfRkxFWElCTEUpOwoKCXJvdGF0ZV9jdHgoJmNwdWN0eC0+Y3R4KTsKCWlmIChjdHgpCgkJcm90YXRlX2N0eChjdHgpOwoKCWNwdV9jdHhfc2NoZWRfaW4oY3B1Y3R4LCBFVkVOVF9GTEVYSUJMRSk7CglpZiAoY3R4KQoJCXRhc2tfY3R4X3NjaGVkX2luKGN0eCwgRVZFTlRfRkxFWElCTEUpOwoKZG9uZToKCWlmIChyZW1vdmUpCgkJbGlzdF9kZWxfaW5pdCgmY3B1Y3R4LT5yb3RhdGlvbl9saXN0KTsKCglwZXJmX3BtdV9lbmFibGUoY3B1Y3R4LT5jdHgucG11KTsKfQoKdm9pZCBwZXJmX2V2ZW50X3Rhc2tfdGljayh2b2lkKQp7CglzdHJ1Y3QgbGlzdF9oZWFkICpoZWFkID0gJl9fZ2V0X2NwdV92YXIocm90YXRpb25fbGlzdCk7CglzdHJ1Y3QgcGVyZl9jcHVfY29udGV4dCAqY3B1Y3R4LCAqdG1wOwoKCVdBUk5fT04oIWlycXNfZGlzYWJsZWQoKSk7CgoJbGlzdF9mb3JfZWFjaF9lbnRyeV9zYWZlKGNwdWN0eCwgdG1wLCBoZWFkLCByb3RhdGlvbl9saXN0KSB7CgkJaWYgKGNwdWN0eC0+amlmZmllc19pbnRlcnZhbCA9PSAxIHx8CgkJCQkhKGppZmZpZXMgJSBjcHVjdHgtPmppZmZpZXNfaW50ZXJ2YWwpKQoJCQlwZXJmX3JvdGF0ZV9jb250ZXh0KGNwdWN0eCk7Cgl9Cn0KCnN0YXRpYyBpbnQgZXZlbnRfZW5hYmxlX29uX2V4ZWMoc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50LAoJCQkJc3RydWN0IHBlcmZfZXZlbnRfY29udGV4dCAqY3R4KQp7CglpZiAoIWV2ZW50LT5hdHRyLmVuYWJsZV9vbl9leGVjKQoJCXJldHVybiAwOwoKCWV2ZW50LT5hdHRyLmVuYWJsZV9vbl9leGVjID0gMDsKCWlmIChldmVudC0+c3RhdGUgPj0gUEVSRl9FVkVOVF9TVEFURV9JTkFDVElWRSkKCQlyZXR1cm4gMDsKCglfX3BlcmZfZXZlbnRfbWFya19lbmFibGVkKGV2ZW50LCBjdHgpOwoKCXJldHVybiAxOwp9CgovKgogKiBFbmFibGUgYWxsIG9mIGEgdGFzaydzIGV2ZW50cyB0aGF0IGhhdmUgYmVlbiBtYXJrZWQgZW5hYmxlLW9uLWV4ZWMuCiAqIFRoaXMgZXhwZWN0cyB0YXNrID09IGN1cnJlbnQuCiAqLwpzdGF0aWMgdm9pZCBwZXJmX2V2ZW50X2VuYWJsZV9vbl9leGVjKHN0cnVjdCBwZXJmX2V2ZW50X2NvbnRleHQgKmN0eCkKewoJc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50OwoJdW5zaWduZWQgbG9uZyBmbGFnczsKCWludCBlbmFibGVkID0gMDsKCWludCByZXQ7CgoJbG9jYWxfaXJxX3NhdmUoZmxhZ3MpOwoJaWYgKCFjdHggfHwgIWN0eC0+bnJfZXZlbnRzKQoJCWdvdG8gb3V0OwoKCXRhc2tfY3R4X3NjaGVkX291dChjdHgsIEVWRU5UX0FMTCk7CgoJcmF3X3NwaW5fbG9jaygmY3R4LT5sb2NrKTsKCglsaXN0X2Zvcl9lYWNoX2VudHJ5KGV2ZW50LCAmY3R4LT5waW5uZWRfZ3JvdXBzLCBncm91cF9lbnRyeSkgewoJCXJldCA9IGV2ZW50X2VuYWJsZV9vbl9leGVjKGV2ZW50LCBjdHgpOwoJCWlmIChyZXQpCgkJCWVuYWJsZWQgPSAxOwoJfQoKCWxpc3RfZm9yX2VhY2hfZW50cnkoZXZlbnQsICZjdHgtPmZsZXhpYmxlX2dyb3VwcywgZ3JvdXBfZW50cnkpIHsKCQlyZXQgPSBldmVudF9lbmFibGVfb25fZXhlYyhldmVudCwgY3R4KTsKCQlpZiAocmV0KQoJCQllbmFibGVkID0gMTsKCX0KCgkvKgoJICogVW5jbG9uZSB0aGlzIGNvbnRleHQgaWYgd2UgZW5hYmxlZCBhbnkgZXZlbnQuCgkgKi8KCWlmIChlbmFibGVkKQoJCXVuY2xvbmVfY3R4KGN0eCk7CgoJcmF3X3NwaW5fdW5sb2NrKCZjdHgtPmxvY2spOwoKCXBlcmZfZXZlbnRfY29udGV4dF9zY2hlZF9pbihjdHgpOwpvdXQ6Cglsb2NhbF9pcnFfcmVzdG9yZShmbGFncyk7Cn0KCi8qCiAqIENyb3NzIENQVSBjYWxsIHRvIHJlYWQgdGhlIGhhcmR3YXJlIGV2ZW50CiAqLwpzdGF0aWMgdm9pZCBfX3BlcmZfZXZlbnRfcmVhZCh2b2lkICppbmZvKQp7CglzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQgPSBpbmZvOwoJc3RydWN0IHBlcmZfZXZlbnRfY29udGV4dCAqY3R4ID0gZXZlbnQtPmN0eDsKCXN0cnVjdCBwZXJmX2NwdV9jb250ZXh0ICpjcHVjdHggPSBfX2dldF9jcHVfY29udGV4dChjdHgpOwoKCS8qCgkgKiBJZiB0aGlzIGlzIGEgdGFzayBjb250ZXh0LCB3ZSBuZWVkIHRvIGNoZWNrIHdoZXRoZXIgaXQgaXMKCSAqIHRoZSBjdXJyZW50IHRhc2sgY29udGV4dCBvZiB0aGlzIGNwdS4gIElmIG5vdCBpdCBoYXMgYmVlbgoJICogc2NoZWR1bGVkIG91dCBiZWZvcmUgdGhlIHNtcCBjYWxsIGFycml2ZWQuICBJbiB0aGF0IGNhc2UKCSAqIGV2ZW50LT5jb3VudCB3b3VsZCBoYXZlIGJlZW4gdXBkYXRlZCB0byBhIHJlY2VudCBzYW1wbGUKCSAqIHdoZW4gdGhlIGV2ZW50IHdhcyBzY2hlZHVsZWQgb3V0LgoJICovCglpZiAoY3R4LT50YXNrICYmIGNwdWN0eC0+dGFza19jdHggIT0gY3R4KQoJCXJldHVybjsKCglyYXdfc3Bpbl9sb2NrKCZjdHgtPmxvY2spOwoJdXBkYXRlX2NvbnRleHRfdGltZShjdHgpOwoJdXBkYXRlX2V2ZW50X3RpbWVzKGV2ZW50KTsKCXJhd19zcGluX3VubG9jaygmY3R4LT5sb2NrKTsKCglldmVudC0+cG11LT5yZWFkKGV2ZW50KTsKfQoKc3RhdGljIGlubGluZSB1NjQgcGVyZl9ldmVudF9jb3VudChzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQpCnsKCXJldHVybiBsb2NhbDY0X3JlYWQoJmV2ZW50LT5jb3VudCkgKyBhdG9taWM2NF9yZWFkKCZldmVudC0+Y2hpbGRfY291bnQpOwp9CgpzdGF0aWMgdTY0IHBlcmZfZXZlbnRfcmVhZChzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQpCnsKCS8qCgkgKiBJZiBldmVudCBpcyBlbmFibGVkIGFuZCBjdXJyZW50bHkgYWN0aXZlIG9uIGEgQ1BVLCB1cGRhdGUgdGhlCgkgKiB2YWx1ZSBpbiB0aGUgZXZlbnQgc3RydWN0dXJlOgoJICovCglpZiAoZXZlbnQtPnN0YXRlID09IFBFUkZfRVZFTlRfU1RBVEVfQUNUSVZFKSB7CgkJc21wX2NhbGxfZnVuY3Rpb25fc2luZ2xlKGV2ZW50LT5vbmNwdSwKCQkJCQkgX19wZXJmX2V2ZW50X3JlYWQsIGV2ZW50LCAxKTsKCX0gZWxzZSBpZiAoZXZlbnQtPnN0YXRlID09IFBFUkZfRVZFTlRfU1RBVEVfSU5BQ1RJVkUpIHsKCQlzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0ICpjdHggPSBldmVudC0+Y3R4OwoJCXVuc2lnbmVkIGxvbmcgZmxhZ3M7CgoJCXJhd19zcGluX2xvY2tfaXJxc2F2ZSgmY3R4LT5sb2NrLCBmbGFncyk7CgkJLyoKCQkgKiBtYXkgcmVhZCB3aGlsZSBjb250ZXh0IGlzIG5vdCBhY3RpdmUKCQkgKiAoZS5nLiwgdGhyZWFkIGlzIGJsb2NrZWQpLCBpbiB0aGF0IGNhc2UKCQkgKiB3ZSBjYW5ub3QgdXBkYXRlIGNvbnRleHQgdGltZQoJCSAqLwoJCWlmIChjdHgtPmlzX2FjdGl2ZSkKCQkJdXBkYXRlX2NvbnRleHRfdGltZShjdHgpOwoJCXVwZGF0ZV9ldmVudF90aW1lcyhldmVudCk7CgkJcmF3X3NwaW5fdW5sb2NrX2lycXJlc3RvcmUoJmN0eC0+bG9jaywgZmxhZ3MpOwoJfQoKCXJldHVybiBwZXJmX2V2ZW50X2NvdW50KGV2ZW50KTsKfQoKLyoKICogQ2FsbGNoYWluIHN1cHBvcnQKICovCgpzdHJ1Y3QgY2FsbGNoYWluX2NwdXNfZW50cmllcyB7CglzdHJ1Y3QgcmN1X2hlYWQJCQlyY3VfaGVhZDsKCXN0cnVjdCBwZXJmX2NhbGxjaGFpbl9lbnRyeQkqY3B1X2VudHJpZXNbMF07Cn07CgpzdGF0aWMgREVGSU5FX1BFUl9DUFUoaW50LCBjYWxsY2hhaW5fcmVjdXJzaW9uW1BFUkZfTlJfQ09OVEVYVFNdKTsKc3RhdGljIGF0b21pY190IG5yX2NhbGxjaGFpbl9ldmVudHM7CnN0YXRpYyBERUZJTkVfTVVURVgoY2FsbGNoYWluX211dGV4KTsKc3RydWN0IGNhbGxjaGFpbl9jcHVzX2VudHJpZXMgKmNhbGxjaGFpbl9jcHVzX2VudHJpZXM7CgoKX193ZWFrIHZvaWQgcGVyZl9jYWxsY2hhaW5fa2VybmVsKHN0cnVjdCBwZXJmX2NhbGxjaGFpbl9lbnRyeSAqZW50cnksCgkJCQkgIHN0cnVjdCBwdF9yZWdzICpyZWdzKQp7Cn0KCl9fd2VhayB2b2lkIHBlcmZfY2FsbGNoYWluX3VzZXIoc3RydWN0IHBlcmZfY2FsbGNoYWluX2VudHJ5ICplbnRyeSwKCQkJCXN0cnVjdCBwdF9yZWdzICpyZWdzKQp7Cn0KCnN0YXRpYyB2b2lkIHJlbGVhc2VfY2FsbGNoYWluX2J1ZmZlcnNfcmN1KHN0cnVjdCByY3VfaGVhZCAqaGVhZCkKewoJc3RydWN0IGNhbGxjaGFpbl9jcHVzX2VudHJpZXMgKmVudHJpZXM7CglpbnQgY3B1OwoKCWVudHJpZXMgPSBjb250YWluZXJfb2YoaGVhZCwgc3RydWN0IGNhbGxjaGFpbl9jcHVzX2VudHJpZXMsIHJjdV9oZWFkKTsKCglmb3JfZWFjaF9wb3NzaWJsZV9jcHUoY3B1KQoJCWtmcmVlKGVudHJpZXMtPmNwdV9lbnRyaWVzW2NwdV0pOwoKCWtmcmVlKGVudHJpZXMpOwp9CgpzdGF0aWMgdm9pZCByZWxlYXNlX2NhbGxjaGFpbl9idWZmZXJzKHZvaWQpCnsKCXN0cnVjdCBjYWxsY2hhaW5fY3B1c19lbnRyaWVzICplbnRyaWVzOwoKCWVudHJpZXMgPSBjYWxsY2hhaW5fY3B1c19lbnRyaWVzOwoJcmN1X2Fzc2lnbl9wb2ludGVyKGNhbGxjaGFpbl9jcHVzX2VudHJpZXMsIE5VTEwpOwoJY2FsbF9yY3UoJmVudHJpZXMtPnJjdV9oZWFkLCByZWxlYXNlX2NhbGxjaGFpbl9idWZmZXJzX3JjdSk7Cn0KCnN0YXRpYyBpbnQgYWxsb2NfY2FsbGNoYWluX2J1ZmZlcnModm9pZCkKewoJaW50IGNwdTsKCWludCBzaXplOwoJc3RydWN0IGNhbGxjaGFpbl9jcHVzX2VudHJpZXMgKmVudHJpZXM7CgoJLyoKCSAqIFdlIGNhbid0IHVzZSB0aGUgcGVyY3B1IGFsbG9jYXRpb24gQVBJIGZvciBkYXRhIHRoYXQgY2FuIGJlCgkgKiBhY2Nlc3NlZCBmcm9tIE5NSS4gVXNlIGEgdGVtcG9yYXJ5IG1hbnVhbCBwZXIgY3B1IGFsbG9jYXRpb24KCSAqIHVudGlsIHRoYXQgZ2V0cyBzb3J0ZWQgb3V0LgoJICovCglzaXplID0gc2l6ZW9mKCplbnRyaWVzKSArIHNpemVvZihzdHJ1Y3QgcGVyZl9jYWxsY2hhaW5fZW50cnkgKikgKgoJCW51bV9wb3NzaWJsZV9jcHVzKCk7CgoJZW50cmllcyA9IGt6YWxsb2Moc2l6ZSwgR0ZQX0tFUk5FTCk7CglpZiAoIWVudHJpZXMpCgkJcmV0dXJuIC1FTk9NRU07CgoJc2l6ZSA9IHNpemVvZihzdHJ1Y3QgcGVyZl9jYWxsY2hhaW5fZW50cnkpICogUEVSRl9OUl9DT05URVhUUzsKCglmb3JfZWFjaF9wb3NzaWJsZV9jcHUoY3B1KSB7CgkJZW50cmllcy0+Y3B1X2VudHJpZXNbY3B1XSA9IGttYWxsb2Nfbm9kZShzaXplLCBHRlBfS0VSTkVMLAoJCQkJCQkJIGNwdV90b19ub2RlKGNwdSkpOwoJCWlmICghZW50cmllcy0+Y3B1X2VudHJpZXNbY3B1XSkKCQkJZ290byBmYWlsOwoJfQoKCXJjdV9hc3NpZ25fcG9pbnRlcihjYWxsY2hhaW5fY3B1c19lbnRyaWVzLCBlbnRyaWVzKTsKCglyZXR1cm4gMDsKCmZhaWw6Cglmb3JfZWFjaF9wb3NzaWJsZV9jcHUoY3B1KQoJCWtmcmVlKGVudHJpZXMtPmNwdV9lbnRyaWVzW2NwdV0pOwoJa2ZyZWUoZW50cmllcyk7CgoJcmV0dXJuIC1FTk9NRU07Cn0KCnN0YXRpYyBpbnQgZ2V0X2NhbGxjaGFpbl9idWZmZXJzKHZvaWQpCnsKCWludCBlcnIgPSAwOwoJaW50IGNvdW50OwoKCW11dGV4X2xvY2soJmNhbGxjaGFpbl9tdXRleCk7CgoJY291bnQgPSBhdG9taWNfaW5jX3JldHVybigmbnJfY2FsbGNoYWluX2V2ZW50cyk7CglpZiAoV0FSTl9PTl9PTkNFKGNvdW50IDwgMSkpIHsKCQllcnIgPSAtRUlOVkFMOwoJCWdvdG8gZXhpdDsKCX0KCglpZiAoY291bnQgPiAxKSB7CgkJLyogSWYgdGhlIGFsbG9jYXRpb24gZmFpbGVkLCBnaXZlIHVwICovCgkJaWYgKCFjYWxsY2hhaW5fY3B1c19lbnRyaWVzKQoJCQllcnIgPSAtRU5PTUVNOwoJCWdvdG8gZXhpdDsKCX0KCgllcnIgPSBhbGxvY19jYWxsY2hhaW5fYnVmZmVycygpOwoJaWYgKGVycikKCQlyZWxlYXNlX2NhbGxjaGFpbl9idWZmZXJzKCk7CmV4aXQ6CgltdXRleF91bmxvY2soJmNhbGxjaGFpbl9tdXRleCk7CgoJcmV0dXJuIGVycjsKfQoKc3RhdGljIHZvaWQgcHV0X2NhbGxjaGFpbl9idWZmZXJzKHZvaWQpCnsKCWlmIChhdG9taWNfZGVjX2FuZF9tdXRleF9sb2NrKCZucl9jYWxsY2hhaW5fZXZlbnRzLCAmY2FsbGNoYWluX211dGV4KSkgewoJCXJlbGVhc2VfY2FsbGNoYWluX2J1ZmZlcnMoKTsKCQltdXRleF91bmxvY2soJmNhbGxjaGFpbl9tdXRleCk7Cgl9Cn0KCnN0YXRpYyBpbnQgZ2V0X3JlY3Vyc2lvbl9jb250ZXh0KGludCAqcmVjdXJzaW9uKQp7CglpbnQgcmN0eDsKCglpZiAoaW5fbm1pKCkpCgkJcmN0eCA9IDM7CgllbHNlIGlmIChpbl9pcnEoKSkKCQlyY3R4ID0gMjsKCWVsc2UgaWYgKGluX3NvZnRpcnEoKSkKCQlyY3R4ID0gMTsKCWVsc2UKCQlyY3R4ID0gMDsKCglpZiAocmVjdXJzaW9uW3JjdHhdKQoJCXJldHVybiAtMTsKCglyZWN1cnNpb25bcmN0eF0rKzsKCWJhcnJpZXIoKTsKCglyZXR1cm4gcmN0eDsKfQoKc3RhdGljIGlubGluZSB2b2lkIHB1dF9yZWN1cnNpb25fY29udGV4dChpbnQgKnJlY3Vyc2lvbiwgaW50IHJjdHgpCnsKCWJhcnJpZXIoKTsKCXJlY3Vyc2lvbltyY3R4XS0tOwp9CgpzdGF0aWMgc3RydWN0IHBlcmZfY2FsbGNoYWluX2VudHJ5ICpnZXRfY2FsbGNoYWluX2VudHJ5KGludCAqcmN0eCkKewoJaW50IGNwdTsKCXN0cnVjdCBjYWxsY2hhaW5fY3B1c19lbnRyaWVzICplbnRyaWVzOwoKCSpyY3R4ID0gZ2V0X3JlY3Vyc2lvbl9jb250ZXh0KF9fZ2V0X2NwdV92YXIoY2FsbGNoYWluX3JlY3Vyc2lvbikpOwoJaWYgKCpyY3R4ID09IC0xKQoJCXJldHVybiBOVUxMOwoKCWVudHJpZXMgPSByY3VfZGVyZWZlcmVuY2UoY2FsbGNoYWluX2NwdXNfZW50cmllcyk7CglpZiAoIWVudHJpZXMpCgkJcmV0dXJuIE5VTEw7CgoJY3B1ID0gc21wX3Byb2Nlc3Nvcl9pZCgpOwoKCXJldHVybiAmZW50cmllcy0+Y3B1X2VudHJpZXNbY3B1XVsqcmN0eF07Cn0KCnN0YXRpYyB2b2lkCnB1dF9jYWxsY2hhaW5fZW50cnkoaW50IHJjdHgpCnsKCXB1dF9yZWN1cnNpb25fY29udGV4dChfX2dldF9jcHVfdmFyKGNhbGxjaGFpbl9yZWN1cnNpb24pLCByY3R4KTsKfQoKc3RhdGljIHN0cnVjdCBwZXJmX2NhbGxjaGFpbl9lbnRyeSAqcGVyZl9jYWxsY2hhaW4oc3RydWN0IHB0X3JlZ3MgKnJlZ3MpCnsKCWludCByY3R4OwoJc3RydWN0IHBlcmZfY2FsbGNoYWluX2VudHJ5ICplbnRyeTsKCgoJZW50cnkgPSBnZXRfY2FsbGNoYWluX2VudHJ5KCZyY3R4KTsKCWlmIChyY3R4ID09IC0xKQoJCXJldHVybiBOVUxMOwoKCWlmICghZW50cnkpCgkJZ290byBleGl0X3B1dDsKCgllbnRyeS0+bnIgPSAwOwoKCWlmICghdXNlcl9tb2RlKHJlZ3MpKSB7CgkJcGVyZl9jYWxsY2hhaW5fc3RvcmUoZW50cnksIFBFUkZfQ09OVEVYVF9LRVJORUwpOwoJCXBlcmZfY2FsbGNoYWluX2tlcm5lbChlbnRyeSwgcmVncyk7CgkJaWYgKGN1cnJlbnQtPm1tKQoJCQlyZWdzID0gdGFza19wdF9yZWdzKGN1cnJlbnQpOwoJCWVsc2UKCQkJcmVncyA9IE5VTEw7Cgl9CgoJaWYgKHJlZ3MpIHsKCQlwZXJmX2NhbGxjaGFpbl9zdG9yZShlbnRyeSwgUEVSRl9DT05URVhUX1VTRVIpOwoJCXBlcmZfY2FsbGNoYWluX3VzZXIoZW50cnksIHJlZ3MpOwoJfQoKZXhpdF9wdXQ6CglwdXRfY2FsbGNoYWluX2VudHJ5KHJjdHgpOwoKCXJldHVybiBlbnRyeTsKfQoKLyoKICogSW5pdGlhbGl6ZSB0aGUgcGVyZl9ldmVudCBjb250ZXh0IGluIGEgdGFza19zdHJ1Y3Q6CiAqLwpzdGF0aWMgdm9pZCBfX3BlcmZfZXZlbnRfaW5pdF9jb250ZXh0KHN0cnVjdCBwZXJmX2V2ZW50X2NvbnRleHQgKmN0eCkKewoJcmF3X3NwaW5fbG9ja19pbml0KCZjdHgtPmxvY2spOwoJbXV0ZXhfaW5pdCgmY3R4LT5tdXRleCk7CglJTklUX0xJU1RfSEVBRCgmY3R4LT5waW5uZWRfZ3JvdXBzKTsKCUlOSVRfTElTVF9IRUFEKCZjdHgtPmZsZXhpYmxlX2dyb3Vwcyk7CglJTklUX0xJU1RfSEVBRCgmY3R4LT5ldmVudF9saXN0KTsKCWF0b21pY19zZXQoJmN0eC0+cmVmY291bnQsIDEpOwp9CgpzdGF0aWMgc3RydWN0IHBlcmZfZXZlbnRfY29udGV4dCAqCmFsbG9jX3BlcmZfY29udGV4dChzdHJ1Y3QgcG11ICpwbXUsIHN0cnVjdCB0YXNrX3N0cnVjdCAqdGFzaykKewoJc3RydWN0IHBlcmZfZXZlbnRfY29udGV4dCAqY3R4OwoKCWN0eCA9IGt6YWxsb2Moc2l6ZW9mKHN0cnVjdCBwZXJmX2V2ZW50X2NvbnRleHQpLCBHRlBfS0VSTkVMKTsKCWlmICghY3R4KQoJCXJldHVybiBOVUxMOwoKCV9fcGVyZl9ldmVudF9pbml0X2NvbnRleHQoY3R4KTsKCWlmICh0YXNrKSB7CgkJY3R4LT50YXNrID0gdGFzazsKCQlnZXRfdGFza19zdHJ1Y3QodGFzayk7Cgl9CgljdHgtPnBtdSA9IHBtdTsKCglyZXR1cm4gY3R4Owp9CgpzdGF0aWMgc3RydWN0IHRhc2tfc3RydWN0ICoKZmluZF9saXZlbHlfdGFza19ieV92cGlkKHBpZF90IHZwaWQpCnsKCXN0cnVjdCB0YXNrX3N0cnVjdCAqdGFzazsKCWludCBlcnI7CgoJcmN1X3JlYWRfbG9jaygpOwoJaWYgKCF2cGlkKQoJCXRhc2sgPSBjdXJyZW50OwoJZWxzZQoJCXRhc2sgPSBmaW5kX3Rhc2tfYnlfdnBpZCh2cGlkKTsKCWlmICh0YXNrKQoJCWdldF90YXNrX3N0cnVjdCh0YXNrKTsKCXJjdV9yZWFkX3VubG9jaygpOwoKCWlmICghdGFzaykKCQlyZXR1cm4gRVJSX1BUUigtRVNSQ0gpOwoKCS8qCgkgKiBDYW4ndCBhdHRhY2ggZXZlbnRzIHRvIGEgZHlpbmcgdGFzay4KCSAqLwoJZXJyID0gLUVTUkNIOwoJaWYgKHRhc2stPmZsYWdzICYgUEZfRVhJVElORykKCQlnb3RvIGVycm91dDsKCgkvKiBSZXVzZSBwdHJhY2UgcGVybWlzc2lvbiBjaGVja3MgZm9yIG5vdy4gKi8KCWVyciA9IC1FQUNDRVM7CglpZiAoIXB0cmFjZV9tYXlfYWNjZXNzKHRhc2ssIFBUUkFDRV9NT0RFX1JFQUQpKQoJCWdvdG8gZXJyb3V0OwoKCXJldHVybiB0YXNrOwplcnJvdXQ6CglwdXRfdGFza19zdHJ1Y3QodGFzayk7CglyZXR1cm4gRVJSX1BUUihlcnIpOwoKfQoKc3RhdGljIHN0cnVjdCBwZXJmX2V2ZW50X2NvbnRleHQgKgpmaW5kX2dldF9jb250ZXh0KHN0cnVjdCBwbXUgKnBtdSwgc3RydWN0IHRhc2tfc3RydWN0ICp0YXNrLCBpbnQgY3B1KQp7CglzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0ICpjdHg7CglzdHJ1Y3QgcGVyZl9jcHVfY29udGV4dCAqY3B1Y3R4OwoJdW5zaWduZWQgbG9uZyBmbGFnczsKCWludCBjdHhuLCBlcnI7CgoJaWYgKCF0YXNrICYmIGNwdSAhPSAtMSkgewoJCS8qIE11c3QgYmUgcm9vdCB0byBvcGVyYXRlIG9uIGEgQ1BVIGV2ZW50OiAqLwoJCWlmIChwZXJmX3BhcmFub2lkX2NwdSgpICYmICFjYXBhYmxlKENBUF9TWVNfQURNSU4pKQoJCQlyZXR1cm4gRVJSX1BUUigtRUFDQ0VTKTsKCgkJaWYgKGNwdSA8IDAgfHwgY3B1ID49IG5yX2NwdW1hc2tfYml0cykKCQkJcmV0dXJuIEVSUl9QVFIoLUVJTlZBTCk7CgoJCS8qCgkJICogV2UgY291bGQgYmUgY2xldmVyIGFuZCBhbGxvdyB0byBhdHRhY2ggYSBldmVudCB0byBhbgoJCSAqIG9mZmxpbmUgQ1BVIGFuZCBhY3RpdmF0ZSBpdCB3aGVuIHRoZSBDUFUgY29tZXMgdXAsIGJ1dAoJCSAqIHRoYXQncyBmb3IgbGF0ZXIuCgkJICovCgkJaWYgKCFjcHVfb25saW5lKGNwdSkpCgkJCXJldHVybiBFUlJfUFRSKC1FTk9ERVYpOwoKCQljcHVjdHggPSBwZXJfY3B1X3B0cihwbXUtPnBtdV9jcHVfY29udGV4dCwgY3B1KTsKCQljdHggPSAmY3B1Y3R4LT5jdHg7CgkJZ2V0X2N0eChjdHgpOwoKCQlyZXR1cm4gY3R4OwoJfQoKCWVyciA9IC1FSU5WQUw7CgljdHhuID0gcG11LT50YXNrX2N0eF9ucjsKCWlmIChjdHhuIDwgMCkKCQlnb3RvIGVycm91dDsKCnJldHJ5OgoJY3R4ID0gcGVyZl9sb2NrX3Rhc2tfY29udGV4dCh0YXNrLCBjdHhuLCAmZmxhZ3MpOwoJaWYgKGN0eCkgewoJCXVuY2xvbmVfY3R4KGN0eCk7CgkJcmF3X3NwaW5fdW5sb2NrX2lycXJlc3RvcmUoJmN0eC0+bG9jaywgZmxhZ3MpOwoJfQoKCWlmICghY3R4KSB7CgkJY3R4ID0gYWxsb2NfcGVyZl9jb250ZXh0KHBtdSwgdGFzayk7CgkJZXJyID0gLUVOT01FTTsKCQlpZiAoIWN0eCkKCQkJZ290byBlcnJvdXQ7CgoJCWdldF9jdHgoY3R4KTsKCgkJaWYgKGNtcHhjaGcoJnRhc2stPnBlcmZfZXZlbnRfY3R4cFtjdHhuXSwgTlVMTCwgY3R4KSkgewoJCQkvKgoJCQkgKiBXZSByYWNlZCB3aXRoIHNvbWUgb3RoZXIgdGFzazsgdXNlCgkJCSAqIHRoZSBjb250ZXh0IHRoZXkgc2V0LgoJCQkgKi8KCQkJcHV0X3Rhc2tfc3RydWN0KHRhc2spOwoJCQlrZnJlZShjdHgpOwoJCQlnb3RvIHJldHJ5OwoJCX0KCX0KCglyZXR1cm4gY3R4OwoKZXJyb3V0OgoJcmV0dXJuIEVSUl9QVFIoZXJyKTsKfQoKc3RhdGljIHZvaWQgcGVyZl9ldmVudF9mcmVlX2ZpbHRlcihzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQpOwoKc3RhdGljIHZvaWQgZnJlZV9ldmVudF9yY3Uoc3RydWN0IHJjdV9oZWFkICpoZWFkKQp7CglzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQ7CgoJZXZlbnQgPSBjb250YWluZXJfb2YoaGVhZCwgc3RydWN0IHBlcmZfZXZlbnQsIHJjdV9oZWFkKTsKCWlmIChldmVudC0+bnMpCgkJcHV0X3BpZF9ucyhldmVudC0+bnMpOwoJcGVyZl9ldmVudF9mcmVlX2ZpbHRlcihldmVudCk7CglrZnJlZShldmVudCk7Cn0KCnN0YXRpYyB2b2lkIHBlcmZfYnVmZmVyX3B1dChzdHJ1Y3QgcGVyZl9idWZmZXIgKmJ1ZmZlcik7CgpzdGF0aWMgdm9pZCBmcmVlX2V2ZW50KHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCkKewoJaXJxX3dvcmtfc3luYygmZXZlbnQtPnBlbmRpbmcpOwoKCWlmICghZXZlbnQtPnBhcmVudCkgewoJCWlmIChldmVudC0+YXR0YWNoX3N0YXRlICYgUEVSRl9BVFRBQ0hfVEFTSykKCQkJanVtcF9sYWJlbF9kZWMoJnBlcmZfdGFza19ldmVudHMpOwoJCWlmIChldmVudC0+YXR0ci5tbWFwIHx8IGV2ZW50LT5hdHRyLm1tYXBfZGF0YSkKCQkJYXRvbWljX2RlYygmbnJfbW1hcF9ldmVudHMpOwoJCWlmIChldmVudC0+YXR0ci5jb21tKQoJCQlhdG9taWNfZGVjKCZucl9jb21tX2V2ZW50cyk7CgkJaWYgKGV2ZW50LT5hdHRyLnRhc2spCgkJCWF0b21pY19kZWMoJm5yX3Rhc2tfZXZlbnRzKTsKCQlpZiAoZXZlbnQtPmF0dHIuc2FtcGxlX3R5cGUgJiBQRVJGX1NBTVBMRV9DQUxMQ0hBSU4pCgkJCXB1dF9jYWxsY2hhaW5fYnVmZmVycygpOwoJfQoKCWlmIChldmVudC0+YnVmZmVyKSB7CgkJcGVyZl9idWZmZXJfcHV0KGV2ZW50LT5idWZmZXIpOwoJCWV2ZW50LT5idWZmZXIgPSBOVUxMOwoJfQoKCWlmIChldmVudC0+ZGVzdHJveSkKCQlldmVudC0+ZGVzdHJveShldmVudCk7CgoJaWYgKGV2ZW50LT5jdHgpCgkJcHV0X2N0eChldmVudC0+Y3R4KTsKCgljYWxsX3JjdSgmZXZlbnQtPnJjdV9oZWFkLCBmcmVlX2V2ZW50X3JjdSk7Cn0KCmludCBwZXJmX2V2ZW50X3JlbGVhc2Vfa2VybmVsKHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCkKewoJc3RydWN0IHBlcmZfZXZlbnRfY29udGV4dCAqY3R4ID0gZXZlbnQtPmN0eDsKCgkvKgoJICogUmVtb3ZlIGZyb20gdGhlIFBNVSwgY2FuJ3QgZ2V0IHJlLWVuYWJsZWQgc2luY2Ugd2UgZ290CgkgKiBoZXJlIGJlY2F1c2UgdGhlIGxhc3QgcmVmIHdlbnQuCgkgKi8KCXBlcmZfZXZlbnRfZGlzYWJsZShldmVudCk7CgoJV0FSTl9PTl9PTkNFKGN0eC0+cGFyZW50X2N0eCk7CgkvKgoJICogVGhlcmUgYXJlIHR3byB3YXlzIHRoaXMgYW5ub3RhdGlvbiBpcyB1c2VmdWw6CgkgKgoJICogIDEpIHRoZXJlIGlzIGEgbG9jayByZWN1cnNpb24gZnJvbSBwZXJmX2V2ZW50X2V4aXRfdGFzawoJICogICAgIHNlZSB0aGUgY29tbWVudCB0aGVyZS4KCSAqCgkgKiAgMikgdGhlcmUgaXMgYSBsb2NrLWludmVyc2lvbiB3aXRoIG1tYXBfc2VtIHRocm91Z2gKCSAqICAgICBwZXJmX2V2ZW50X3JlYWRfZ3JvdXAoKSwgd2hpY2ggdGFrZXMgZmF1bHRzIHdoaWxlCgkgKiAgICAgaG9sZGluZyBjdHgtPm11dGV4LCBob3dldmVyIHRoaXMgaXMgY2FsbGVkIGFmdGVyCgkgKiAgICAgdGhlIGxhc3QgZmlsZWRlc2MgZGllZCwgc28gdGhlcmUgaXMgbm8gcG9zc2liaWxpdHkKCSAqICAgICB0byB0cmlnZ2VyIHRoZSBBQi1CQSBjYXNlLgoJICovCgltdXRleF9sb2NrX25lc3RlZCgmY3R4LT5tdXRleCwgU0lOR0xFX0RFUFRIX05FU1RJTkcpOwoJcmF3X3NwaW5fbG9ja19pcnEoJmN0eC0+bG9jayk7CglwZXJmX2dyb3VwX2RldGFjaChldmVudCk7CglsaXN0X2RlbF9ldmVudChldmVudCwgY3R4KTsKCXJhd19zcGluX3VubG9ja19pcnEoJmN0eC0+bG9jayk7CgltdXRleF91bmxvY2soJmN0eC0+bXV0ZXgpOwoKCWZyZWVfZXZlbnQoZXZlbnQpOwoKCXJldHVybiAwOwp9CkVYUE9SVF9TWU1CT0xfR1BMKHBlcmZfZXZlbnRfcmVsZWFzZV9rZXJuZWwpOwoKLyoKICogQ2FsbGVkIHdoZW4gdGhlIGxhc3QgcmVmZXJlbmNlIHRvIHRoZSBmaWxlIGlzIGdvbmUuCiAqLwpzdGF0aWMgaW50IHBlcmZfcmVsZWFzZShzdHJ1Y3QgaW5vZGUgKmlub2RlLCBzdHJ1Y3QgZmlsZSAqZmlsZSkKewoJc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50ID0gZmlsZS0+cHJpdmF0ZV9kYXRhOwoJc3RydWN0IHRhc2tfc3RydWN0ICpvd25lcjsKCglmaWxlLT5wcml2YXRlX2RhdGEgPSBOVUxMOwoKCXJjdV9yZWFkX2xvY2soKTsKCW93bmVyID0gQUNDRVNTX09OQ0UoZXZlbnQtPm93bmVyKTsKCS8qCgkgKiBNYXRjaGVzIHRoZSBzbXBfd21iKCkgaW4gcGVyZl9ldmVudF9leGl0X3Rhc2soKS4gSWYgd2Ugb2JzZXJ2ZQoJICogIW93bmVyIGl0IG1lYW5zIHRoZSBsaXN0IGRlbGV0aW9uIGlzIGNvbXBsZXRlIGFuZCB3ZSBjYW4gaW5kZWVkCgkgKiBmcmVlIHRoaXMgZXZlbnQsIG90aGVyd2lzZSB3ZSBuZWVkIHRvIHNlcmlhbGl6ZSBvbgoJICogb3duZXItPnBlcmZfZXZlbnRfbXV0ZXguCgkgKi8KCXNtcF9yZWFkX2JhcnJpZXJfZGVwZW5kcygpOwoJaWYgKG93bmVyKSB7CgkJLyoKCQkgKiBTaW5jZSBkZWxheWVkX3B1dF90YXNrX3N0cnVjdCgpIGFsc28gZHJvcHMgdGhlIGxhc3QKCQkgKiB0YXNrIHJlZmVyZW5jZSB3ZSBjYW4gc2FmZWx5IHRha2UgYSBuZXcgcmVmZXJlbmNlCgkJICogd2hpbGUgaG9sZGluZyB0aGUgcmN1X3JlYWRfbG9jaygpLgoJCSAqLwoJCWdldF90YXNrX3N0cnVjdChvd25lcik7Cgl9CglyY3VfcmVhZF91bmxvY2soKTsKCglpZiAob3duZXIpIHsKCQltdXRleF9sb2NrKCZvd25lci0+cGVyZl9ldmVudF9tdXRleCk7CgkJLyoKCQkgKiBXZSBoYXZlIHRvIHJlLWNoZWNrIHRoZSBldmVudC0+b3duZXIgZmllbGQsIGlmIGl0IGlzIGNsZWFyZWQKCQkgKiB3ZSByYWNlZCB3aXRoIHBlcmZfZXZlbnRfZXhpdF90YXNrKCksIGFjcXVpcmluZyB0aGUgbXV0ZXgKCQkgKiBlbnN1cmVkIHRoZXkncmUgZG9uZSwgYW5kIHdlIGNhbiBwcm9jZWVkIHdpdGggZnJlZWluZyB0aGUKCQkgKiBldmVudC4KCQkgKi8KCQlpZiAoZXZlbnQtPm93bmVyKQoJCQlsaXN0X2RlbF9pbml0KCZldmVudC0+b3duZXJfZW50cnkpOwoJCW11dGV4X3VubG9jaygmb3duZXItPnBlcmZfZXZlbnRfbXV0ZXgpOwoJCXB1dF90YXNrX3N0cnVjdChvd25lcik7Cgl9CgoJcmV0dXJuIHBlcmZfZXZlbnRfcmVsZWFzZV9rZXJuZWwoZXZlbnQpOwp9Cgp1NjQgcGVyZl9ldmVudF9yZWFkX3ZhbHVlKHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCwgdTY0ICplbmFibGVkLCB1NjQgKnJ1bm5pbmcpCnsKCXN0cnVjdCBwZXJmX2V2ZW50ICpjaGlsZDsKCXU2NCB0b3RhbCA9IDA7CgoJKmVuYWJsZWQgPSAwOwoJKnJ1bm5pbmcgPSAwOwoKCW11dGV4X2xvY2soJmV2ZW50LT5jaGlsZF9tdXRleCk7Cgl0b3RhbCArPSBwZXJmX2V2ZW50X3JlYWQoZXZlbnQpOwoJKmVuYWJsZWQgKz0gZXZlbnQtPnRvdGFsX3RpbWVfZW5hYmxlZCArCgkJCWF0b21pYzY0X3JlYWQoJmV2ZW50LT5jaGlsZF90b3RhbF90aW1lX2VuYWJsZWQpOwoJKnJ1bm5pbmcgKz0gZXZlbnQtPnRvdGFsX3RpbWVfcnVubmluZyArCgkJCWF0b21pYzY0X3JlYWQoJmV2ZW50LT5jaGlsZF90b3RhbF90aW1lX3J1bm5pbmcpOwoKCWxpc3RfZm9yX2VhY2hfZW50cnkoY2hpbGQsICZldmVudC0+Y2hpbGRfbGlzdCwgY2hpbGRfbGlzdCkgewoJCXRvdGFsICs9IHBlcmZfZXZlbnRfcmVhZChjaGlsZCk7CgkJKmVuYWJsZWQgKz0gY2hpbGQtPnRvdGFsX3RpbWVfZW5hYmxlZDsKCQkqcnVubmluZyArPSBjaGlsZC0+dG90YWxfdGltZV9ydW5uaW5nOwoJfQoJbXV0ZXhfdW5sb2NrKCZldmVudC0+Y2hpbGRfbXV0ZXgpOwoKCXJldHVybiB0b3RhbDsKfQpFWFBPUlRfU1lNQk9MX0dQTChwZXJmX2V2ZW50X3JlYWRfdmFsdWUpOwoKc3RhdGljIGludCBwZXJmX2V2ZW50X3JlYWRfZ3JvdXAoc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50LAoJCQkJICAgdTY0IHJlYWRfZm9ybWF0LCBjaGFyIF9fdXNlciAqYnVmKQp7CglzdHJ1Y3QgcGVyZl9ldmVudCAqbGVhZGVyID0gZXZlbnQtPmdyb3VwX2xlYWRlciwgKnN1YjsKCWludCBuID0gMCwgc2l6ZSA9IDAsIHJldCA9IC1FRkFVTFQ7CglzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0ICpjdHggPSBsZWFkZXItPmN0eDsKCXU2NCB2YWx1ZXNbNV07Cgl1NjQgY291bnQsIGVuYWJsZWQsIHJ1bm5pbmc7CgoJbXV0ZXhfbG9jaygmY3R4LT5tdXRleCk7Cgljb3VudCA9IHBlcmZfZXZlbnRfcmVhZF92YWx1ZShsZWFkZXIsICZlbmFibGVkLCAmcnVubmluZyk7CgoJdmFsdWVzW24rK10gPSAxICsgbGVhZGVyLT5ucl9zaWJsaW5nczsKCWlmIChyZWFkX2Zvcm1hdCAmIFBFUkZfRk9STUFUX1RPVEFMX1RJTUVfRU5BQkxFRCkKCQl2YWx1ZXNbbisrXSA9IGVuYWJsZWQ7CglpZiAocmVhZF9mb3JtYXQgJiBQRVJGX0ZPUk1BVF9UT1RBTF9USU1FX1JVTk5JTkcpCgkJdmFsdWVzW24rK10gPSBydW5uaW5nOwoJdmFsdWVzW24rK10gPSBjb3VudDsKCWlmIChyZWFkX2Zvcm1hdCAmIFBFUkZfRk9STUFUX0lEKQoJCXZhbHVlc1tuKytdID0gcHJpbWFyeV9ldmVudF9pZChsZWFkZXIpOwoKCXNpemUgPSBuICogc2l6ZW9mKHU2NCk7CgoJaWYgKGNvcHlfdG9fdXNlcihidWYsIHZhbHVlcywgc2l6ZSkpCgkJZ290byB1bmxvY2s7CgoJcmV0ID0gc2l6ZTsKCglsaXN0X2Zvcl9lYWNoX2VudHJ5KHN1YiwgJmxlYWRlci0+c2libGluZ19saXN0LCBncm91cF9lbnRyeSkgewoJCW4gPSAwOwoKCQl2YWx1ZXNbbisrXSA9IHBlcmZfZXZlbnRfcmVhZF92YWx1ZShzdWIsICZlbmFibGVkLCAmcnVubmluZyk7CgkJaWYgKHJlYWRfZm9ybWF0ICYgUEVSRl9GT1JNQVRfSUQpCgkJCXZhbHVlc1tuKytdID0gcHJpbWFyeV9ldmVudF9pZChzdWIpOwoKCQlzaXplID0gbiAqIHNpemVvZih1NjQpOwoKCQlpZiAoY29weV90b191c2VyKGJ1ZiArIHJldCwgdmFsdWVzLCBzaXplKSkgewoJCQlyZXQgPSAtRUZBVUxUOwoJCQlnb3RvIHVubG9jazsKCQl9CgoJCXJldCArPSBzaXplOwoJfQp1bmxvY2s6CgltdXRleF91bmxvY2soJmN0eC0+bXV0ZXgpOwoKCXJldHVybiByZXQ7Cn0KCnN0YXRpYyBpbnQgcGVyZl9ldmVudF9yZWFkX29uZShzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQsCgkJCQkgdTY0IHJlYWRfZm9ybWF0LCBjaGFyIF9fdXNlciAqYnVmKQp7Cgl1NjQgZW5hYmxlZCwgcnVubmluZzsKCXU2NCB2YWx1ZXNbNF07CglpbnQgbiA9IDA7CgoJdmFsdWVzW24rK10gPSBwZXJmX2V2ZW50X3JlYWRfdmFsdWUoZXZlbnQsICZlbmFibGVkLCAmcnVubmluZyk7CglpZiAocmVhZF9mb3JtYXQgJiBQRVJGX0ZPUk1BVF9UT1RBTF9USU1FX0VOQUJMRUQpCgkJdmFsdWVzW24rK10gPSBlbmFibGVkOwoJaWYgKHJlYWRfZm9ybWF0ICYgUEVSRl9GT1JNQVRfVE9UQUxfVElNRV9SVU5OSU5HKQoJCXZhbHVlc1tuKytdID0gcnVubmluZzsKCWlmIChyZWFkX2Zvcm1hdCAmIFBFUkZfRk9STUFUX0lEKQoJCXZhbHVlc1tuKytdID0gcHJpbWFyeV9ldmVudF9pZChldmVudCk7CgoJaWYgKGNvcHlfdG9fdXNlcihidWYsIHZhbHVlcywgbiAqIHNpemVvZih1NjQpKSkKCQlyZXR1cm4gLUVGQVVMVDsKCglyZXR1cm4gbiAqIHNpemVvZih1NjQpOwp9CgovKgogKiBSZWFkIHRoZSBwZXJmb3JtYW5jZSBldmVudCAtIHNpbXBsZSBub24gYmxvY2tpbmcgdmVyc2lvbiBmb3Igbm93CiAqLwpzdGF0aWMgc3NpemVfdApwZXJmX3JlYWRfaHcoc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50LCBjaGFyIF9fdXNlciAqYnVmLCBzaXplX3QgY291bnQpCnsKCXU2NCByZWFkX2Zvcm1hdCA9IGV2ZW50LT5hdHRyLnJlYWRfZm9ybWF0OwoJaW50IHJldDsKCgkvKgoJICogUmV0dXJuIGVuZC1vZi1maWxlIGZvciBhIHJlYWQgb24gYSBldmVudCB0aGF0IGlzIGluCgkgKiBlcnJvciBzdGF0ZSAoaS5lLiBiZWNhdXNlIGl0IHdhcyBwaW5uZWQgYnV0IGl0IGNvdWxkbid0IGJlCgkgKiBzY2hlZHVsZWQgb24gdG8gdGhlIENQVSBhdCBzb21lIHBvaW50KS4KCSAqLwoJaWYgKGV2ZW50LT5zdGF0ZSA9PSBQRVJGX0VWRU5UX1NUQVRFX0VSUk9SKQoJCXJldHVybiAwOwoKCWlmIChjb3VudCA8IGV2ZW50LT5yZWFkX3NpemUpCgkJcmV0dXJuIC1FTk9TUEM7CgoJV0FSTl9PTl9PTkNFKGV2ZW50LT5jdHgtPnBhcmVudF9jdHgpOwoJaWYgKHJlYWRfZm9ybWF0ICYgUEVSRl9GT1JNQVRfR1JPVVApCgkJcmV0ID0gcGVyZl9ldmVudF9yZWFkX2dyb3VwKGV2ZW50LCByZWFkX2Zvcm1hdCwgYnVmKTsKCWVsc2UKCQlyZXQgPSBwZXJmX2V2ZW50X3JlYWRfb25lKGV2ZW50LCByZWFkX2Zvcm1hdCwgYnVmKTsKCglyZXR1cm4gcmV0Owp9CgpzdGF0aWMgc3NpemVfdApwZXJmX3JlYWQoc3RydWN0IGZpbGUgKmZpbGUsIGNoYXIgX191c2VyICpidWYsIHNpemVfdCBjb3VudCwgbG9mZl90ICpwcG9zKQp7CglzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQgPSBmaWxlLT5wcml2YXRlX2RhdGE7CgoJcmV0dXJuIHBlcmZfcmVhZF9odyhldmVudCwgYnVmLCBjb3VudCk7Cn0KCnN0YXRpYyB1bnNpZ25lZCBpbnQgcGVyZl9wb2xsKHN0cnVjdCBmaWxlICpmaWxlLCBwb2xsX3RhYmxlICp3YWl0KQp7CglzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQgPSBmaWxlLT5wcml2YXRlX2RhdGE7CglzdHJ1Y3QgcGVyZl9idWZmZXIgKmJ1ZmZlcjsKCXVuc2lnbmVkIGludCBldmVudHMgPSBQT0xMX0hVUDsKCglyY3VfcmVhZF9sb2NrKCk7CglidWZmZXIgPSByY3VfZGVyZWZlcmVuY2UoZXZlbnQtPmJ1ZmZlcik7CglpZiAoYnVmZmVyKQoJCWV2ZW50cyA9IGF0b21pY194Y2hnKCZidWZmZXItPnBvbGwsIDApOwoJcmN1X3JlYWRfdW5sb2NrKCk7CgoJcG9sbF93YWl0KGZpbGUsICZldmVudC0+d2FpdHEsIHdhaXQpOwoKCXJldHVybiBldmVudHM7Cn0KCnN0YXRpYyB2b2lkIHBlcmZfZXZlbnRfcmVzZXQoc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50KQp7Cgkodm9pZClwZXJmX2V2ZW50X3JlYWQoZXZlbnQpOwoJbG9jYWw2NF9zZXQoJmV2ZW50LT5jb3VudCwgMCk7CglwZXJmX2V2ZW50X3VwZGF0ZV91c2VycGFnZShldmVudCk7Cn0KCi8qCiAqIEhvbGRpbmcgdGhlIHRvcC1sZXZlbCBldmVudCdzIGNoaWxkX211dGV4IG1lYW5zIHRoYXQgYW55CiAqIGRlc2NlbmRhbnQgcHJvY2VzcyB0aGF0IGhhcyBpbmhlcml0ZWQgdGhpcyBldmVudCB3aWxsIGJsb2NrCiAqIGluIHN5bmNfY2hpbGRfZXZlbnQgaWYgaXQgZ29lcyB0byBleGl0LCB0aHVzIHNhdGlzZnlpbmcgdGhlCiAqIHRhc2sgZXhpc3RlbmNlIHJlcXVpcmVtZW50cyBvZiBwZXJmX2V2ZW50X2VuYWJsZS9kaXNhYmxlLgogKi8Kc3RhdGljIHZvaWQgcGVyZl9ldmVudF9mb3JfZWFjaF9jaGlsZChzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQsCgkJCQkJdm9pZCAoKmZ1bmMpKHN0cnVjdCBwZXJmX2V2ZW50ICopKQp7CglzdHJ1Y3QgcGVyZl9ldmVudCAqY2hpbGQ7CgoJV0FSTl9PTl9PTkNFKGV2ZW50LT5jdHgtPnBhcmVudF9jdHgpOwoJbXV0ZXhfbG9jaygmZXZlbnQtPmNoaWxkX211dGV4KTsKCWZ1bmMoZXZlbnQpOwoJbGlzdF9mb3JfZWFjaF9lbnRyeShjaGlsZCwgJmV2ZW50LT5jaGlsZF9saXN0LCBjaGlsZF9saXN0KQoJCWZ1bmMoY2hpbGQpOwoJbXV0ZXhfdW5sb2NrKCZldmVudC0+Y2hpbGRfbXV0ZXgpOwp9CgpzdGF0aWMgdm9pZCBwZXJmX2V2ZW50X2Zvcl9lYWNoKHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCwKCQkJCSAgdm9pZCAoKmZ1bmMpKHN0cnVjdCBwZXJmX2V2ZW50ICopKQp7CglzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0ICpjdHggPSBldmVudC0+Y3R4OwoJc3RydWN0IHBlcmZfZXZlbnQgKnNpYmxpbmc7CgoJV0FSTl9PTl9PTkNFKGN0eC0+cGFyZW50X2N0eCk7CgltdXRleF9sb2NrKCZjdHgtPm11dGV4KTsKCWV2ZW50ID0gZXZlbnQtPmdyb3VwX2xlYWRlcjsKCglwZXJmX2V2ZW50X2Zvcl9lYWNoX2NoaWxkKGV2ZW50LCBmdW5jKTsKCWZ1bmMoZXZlbnQpOwoJbGlzdF9mb3JfZWFjaF9lbnRyeShzaWJsaW5nLCAmZXZlbnQtPnNpYmxpbmdfbGlzdCwgZ3JvdXBfZW50cnkpCgkJcGVyZl9ldmVudF9mb3JfZWFjaF9jaGlsZChldmVudCwgZnVuYyk7CgltdXRleF91bmxvY2soJmN0eC0+bXV0ZXgpOwp9CgpzdGF0aWMgaW50IHBlcmZfZXZlbnRfcGVyaW9kKHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCwgdTY0IF9fdXNlciAqYXJnKQp7CglzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0ICpjdHggPSBldmVudC0+Y3R4OwoJaW50IHJldCA9IDA7Cgl1NjQgdmFsdWU7CgoJaWYgKCFpc19zYW1wbGluZ19ldmVudChldmVudCkpCgkJcmV0dXJuIC1FSU5WQUw7CgoJaWYgKGNvcHlfZnJvbV91c2VyKCZ2YWx1ZSwgYXJnLCBzaXplb2YodmFsdWUpKSkKCQlyZXR1cm4gLUVGQVVMVDsKCglpZiAoIXZhbHVlKQoJCXJldHVybiAtRUlOVkFMOwoKCXJhd19zcGluX2xvY2tfaXJxKCZjdHgtPmxvY2spOwoJaWYgKGV2ZW50LT5hdHRyLmZyZXEpIHsKCQlpZiAodmFsdWUgPiBzeXNjdGxfcGVyZl9ldmVudF9zYW1wbGVfcmF0ZSkgewoJCQlyZXQgPSAtRUlOVkFMOwoJCQlnb3RvIHVubG9jazsKCQl9CgoJCWV2ZW50LT5hdHRyLnNhbXBsZV9mcmVxID0gdmFsdWU7Cgl9IGVsc2UgewoJCWV2ZW50LT5hdHRyLnNhbXBsZV9wZXJpb2QgPSB2YWx1ZTsKCQlldmVudC0+aHcuc2FtcGxlX3BlcmlvZCA9IHZhbHVlOwoJfQp1bmxvY2s6CglyYXdfc3Bpbl91bmxvY2tfaXJxKCZjdHgtPmxvY2spOwoKCXJldHVybiByZXQ7Cn0KCnN0YXRpYyBjb25zdCBzdHJ1Y3QgZmlsZV9vcGVyYXRpb25zIHBlcmZfZm9wczsKCnN0YXRpYyBzdHJ1Y3QgcGVyZl9ldmVudCAqcGVyZl9mZ2V0X2xpZ2h0KGludCBmZCwgaW50ICpmcHV0X25lZWRlZCkKewoJc3RydWN0IGZpbGUgKmZpbGU7CgoJZmlsZSA9IGZnZXRfbGlnaHQoZmQsIGZwdXRfbmVlZGVkKTsKCWlmICghZmlsZSkKCQlyZXR1cm4gRVJSX1BUUigtRUJBREYpOwoKCWlmIChmaWxlLT5mX29wICE9ICZwZXJmX2ZvcHMpIHsKCQlmcHV0X2xpZ2h0KGZpbGUsICpmcHV0X25lZWRlZCk7CgkJKmZwdXRfbmVlZGVkID0gMDsKCQlyZXR1cm4gRVJSX1BUUigtRUJBREYpOwoJfQoKCXJldHVybiBmaWxlLT5wcml2YXRlX2RhdGE7Cn0KCnN0YXRpYyBpbnQgcGVyZl9ldmVudF9zZXRfb3V0cHV0KHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCwKCQkJCSBzdHJ1Y3QgcGVyZl9ldmVudCAqb3V0cHV0X2V2ZW50KTsKc3RhdGljIGludCBwZXJmX2V2ZW50X3NldF9maWx0ZXIoc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50LCB2b2lkIF9fdXNlciAqYXJnKTsKCnN0YXRpYyBsb25nIHBlcmZfaW9jdGwoc3RydWN0IGZpbGUgKmZpbGUsIHVuc2lnbmVkIGludCBjbWQsIHVuc2lnbmVkIGxvbmcgYXJnKQp7CglzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQgPSBmaWxlLT5wcml2YXRlX2RhdGE7Cgl2b2lkICgqZnVuYykoc3RydWN0IHBlcmZfZXZlbnQgKik7Cgl1MzIgZmxhZ3MgPSBhcmc7CgoJc3dpdGNoIChjbWQpIHsKCWNhc2UgUEVSRl9FVkVOVF9JT0NfRU5BQkxFOgoJCWZ1bmMgPSBwZXJmX2V2ZW50X2VuYWJsZTsKCQlicmVhazsKCWNhc2UgUEVSRl9FVkVOVF9JT0NfRElTQUJMRToKCQlmdW5jID0gcGVyZl9ldmVudF9kaXNhYmxlOwoJCWJyZWFrOwoJY2FzZSBQRVJGX0VWRU5UX0lPQ19SRVNFVDoKCQlmdW5jID0gcGVyZl9ldmVudF9yZXNldDsKCQlicmVhazsKCgljYXNlIFBFUkZfRVZFTlRfSU9DX1JFRlJFU0g6CgkJcmV0dXJuIHBlcmZfZXZlbnRfcmVmcmVzaChldmVudCwgYXJnKTsKCgljYXNlIFBFUkZfRVZFTlRfSU9DX1BFUklPRDoKCQlyZXR1cm4gcGVyZl9ldmVudF9wZXJpb2QoZXZlbnQsICh1NjQgX191c2VyICopYXJnKTsKCgljYXNlIFBFUkZfRVZFTlRfSU9DX1NFVF9PVVRQVVQ6Cgl7CgkJc3RydWN0IHBlcmZfZXZlbnQgKm91dHB1dF9ldmVudCA9IE5VTEw7CgkJaW50IGZwdXRfbmVlZGVkID0gMDsKCQlpbnQgcmV0OwoKCQlpZiAoYXJnICE9IC0xKSB7CgkJCW91dHB1dF9ldmVudCA9IHBlcmZfZmdldF9saWdodChhcmcsICZmcHV0X25lZWRlZCk7CgkJCWlmIChJU19FUlIob3V0cHV0X2V2ZW50KSkKCQkJCXJldHVybiBQVFJfRVJSKG91dHB1dF9ldmVudCk7CgkJfQoKCQlyZXQgPSBwZXJmX2V2ZW50X3NldF9vdXRwdXQoZXZlbnQsIG91dHB1dF9ldmVudCk7CgkJaWYgKG91dHB1dF9ldmVudCkKCQkJZnB1dF9saWdodChvdXRwdXRfZXZlbnQtPmZpbHAsIGZwdXRfbmVlZGVkKTsKCgkJcmV0dXJuIHJldDsKCX0KCgljYXNlIFBFUkZfRVZFTlRfSU9DX1NFVF9GSUxURVI6CgkJcmV0dXJuIHBlcmZfZXZlbnRfc2V0X2ZpbHRlcihldmVudCwgKHZvaWQgX191c2VyICopYXJnKTsKCglkZWZhdWx0OgoJCXJldHVybiAtRU5PVFRZOwoJfQoKCWlmIChmbGFncyAmIFBFUkZfSU9DX0ZMQUdfR1JPVVApCgkJcGVyZl9ldmVudF9mb3JfZWFjaChldmVudCwgZnVuYyk7CgllbHNlCgkJcGVyZl9ldmVudF9mb3JfZWFjaF9jaGlsZChldmVudCwgZnVuYyk7CgoJcmV0dXJuIDA7Cn0KCmludCBwZXJmX2V2ZW50X3Rhc2tfZW5hYmxlKHZvaWQpCnsKCXN0cnVjdCBwZXJmX2V2ZW50ICpldmVudDsKCgltdXRleF9sb2NrKCZjdXJyZW50LT5wZXJmX2V2ZW50X211dGV4KTsKCWxpc3RfZm9yX2VhY2hfZW50cnkoZXZlbnQsICZjdXJyZW50LT5wZXJmX2V2ZW50X2xpc3QsIG93bmVyX2VudHJ5KQoJCXBlcmZfZXZlbnRfZm9yX2VhY2hfY2hpbGQoZXZlbnQsIHBlcmZfZXZlbnRfZW5hYmxlKTsKCW11dGV4X3VubG9jaygmY3VycmVudC0+cGVyZl9ldmVudF9tdXRleCk7CgoJcmV0dXJuIDA7Cn0KCmludCBwZXJmX2V2ZW50X3Rhc2tfZGlzYWJsZSh2b2lkKQp7CglzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQ7CgoJbXV0ZXhfbG9jaygmY3VycmVudC0+cGVyZl9ldmVudF9tdXRleCk7CglsaXN0X2Zvcl9lYWNoX2VudHJ5KGV2ZW50LCAmY3VycmVudC0+cGVyZl9ldmVudF9saXN0LCBvd25lcl9lbnRyeSkKCQlwZXJmX2V2ZW50X2Zvcl9lYWNoX2NoaWxkKGV2ZW50LCBwZXJmX2V2ZW50X2Rpc2FibGUpOwoJbXV0ZXhfdW5sb2NrKCZjdXJyZW50LT5wZXJmX2V2ZW50X211dGV4KTsKCglyZXR1cm4gMDsKfQoKI2lmbmRlZiBQRVJGX0VWRU5UX0lOREVYX09GRlNFVAojIGRlZmluZSBQRVJGX0VWRU5UX0lOREVYX09GRlNFVCAwCiNlbmRpZgoKc3RhdGljIGludCBwZXJmX2V2ZW50X2luZGV4KHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCkKewoJaWYgKGV2ZW50LT5ody5zdGF0ZSAmIFBFUkZfSEVTX1NUT1BQRUQpCgkJcmV0dXJuIDA7CgoJaWYgKGV2ZW50LT5zdGF0ZSAhPSBQRVJGX0VWRU5UX1NUQVRFX0FDVElWRSkKCQlyZXR1cm4gMDsKCglyZXR1cm4gZXZlbnQtPmh3LmlkeCArIDEgLSBQRVJGX0VWRU5UX0lOREVYX09GRlNFVDsKfQoKLyoKICogQ2FsbGVycyBuZWVkIHRvIGVuc3VyZSB0aGVyZSBjYW4gYmUgbm8gbmVzdGluZyBvZiB0aGlzIGZ1bmN0aW9uLCBvdGhlcndpc2UKICogdGhlIHNlcWxvY2sgbG9naWMgZ29lcyBiYWQuIFdlIGNhbiBub3Qgc2VyaWFsaXplIHRoaXMgYmVjYXVzZSB0aGUgYXJjaAogKiBjb2RlIGNhbGxzIHRoaXMgZnJvbSBOTUkgY29udGV4dC4KICovCnZvaWQgcGVyZl9ldmVudF91cGRhdGVfdXNlcnBhZ2Uoc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50KQp7CglzdHJ1Y3QgcGVyZl9ldmVudF9tbWFwX3BhZ2UgKnVzZXJwZzsKCXN0cnVjdCBwZXJmX2J1ZmZlciAqYnVmZmVyOwoKCXJjdV9yZWFkX2xvY2soKTsKCWJ1ZmZlciA9IHJjdV9kZXJlZmVyZW5jZShldmVudC0+YnVmZmVyKTsKCWlmICghYnVmZmVyKQoJCWdvdG8gdW5sb2NrOwoKCXVzZXJwZyA9IGJ1ZmZlci0+dXNlcl9wYWdlOwoKCS8qCgkgKiBEaXNhYmxlIHByZWVtcHRpb24gc28gYXMgdG8gbm90IGxldCB0aGUgY29ycmVzcG9uZGluZyB1c2VyLXNwYWNlCgkgKiBzcGluIHRvbyBsb25nIGlmIHdlIGdldCBwcmVlbXB0ZWQuCgkgKi8KCXByZWVtcHRfZGlzYWJsZSgpOwoJKyt1c2VycGctPmxvY2s7CgliYXJyaWVyKCk7Cgl1c2VycGctPmluZGV4ID0gcGVyZl9ldmVudF9pbmRleChldmVudCk7Cgl1c2VycGctPm9mZnNldCA9IHBlcmZfZXZlbnRfY291bnQoZXZlbnQpOwoJaWYgKGV2ZW50LT5zdGF0ZSA9PSBQRVJGX0VWRU5UX1NUQVRFX0FDVElWRSkKCQl1c2VycGctPm9mZnNldCAtPSBsb2NhbDY0X3JlYWQoJmV2ZW50LT5ody5wcmV2X2NvdW50KTsKCgl1c2VycGctPnRpbWVfZW5hYmxlZCA9IGV2ZW50LT50b3RhbF90aW1lX2VuYWJsZWQgKwoJCQlhdG9taWM2NF9yZWFkKCZldmVudC0+Y2hpbGRfdG90YWxfdGltZV9lbmFibGVkKTsKCgl1c2VycGctPnRpbWVfcnVubmluZyA9IGV2ZW50LT50b3RhbF90aW1lX3J1bm5pbmcgKwoJCQlhdG9taWM2NF9yZWFkKCZldmVudC0+Y2hpbGRfdG90YWxfdGltZV9ydW5uaW5nKTsKCgliYXJyaWVyKCk7CgkrK3VzZXJwZy0+bG9jazsKCXByZWVtcHRfZW5hYmxlKCk7CnVubG9jazoKCXJjdV9yZWFkX3VubG9jaygpOwp9CgpzdGF0aWMgdW5zaWduZWQgbG9uZyBwZXJmX2RhdGFfc2l6ZShzdHJ1Y3QgcGVyZl9idWZmZXIgKmJ1ZmZlcik7CgpzdGF0aWMgdm9pZApwZXJmX2J1ZmZlcl9pbml0KHN0cnVjdCBwZXJmX2J1ZmZlciAqYnVmZmVyLCBsb25nIHdhdGVybWFyaywgaW50IGZsYWdzKQp7Cglsb25nIG1heF9zaXplID0gcGVyZl9kYXRhX3NpemUoYnVmZmVyKTsKCglpZiAod2F0ZXJtYXJrKQoJCWJ1ZmZlci0+d2F0ZXJtYXJrID0gbWluKG1heF9zaXplLCB3YXRlcm1hcmspOwoKCWlmICghYnVmZmVyLT53YXRlcm1hcmspCgkJYnVmZmVyLT53YXRlcm1hcmsgPSBtYXhfc2l6ZSAvIDI7CgoJaWYgKGZsYWdzICYgUEVSRl9CVUZGRVJfV1JJVEFCTEUpCgkJYnVmZmVyLT53cml0YWJsZSA9IDE7CgoJYXRvbWljX3NldCgmYnVmZmVyLT5yZWZjb3VudCwgMSk7Cn0KCiNpZm5kZWYgQ09ORklHX1BFUkZfVVNFX1ZNQUxMT0MKCi8qCiAqIEJhY2sgcGVyZl9tbWFwKCkgd2l0aCByZWd1bGFyIEdGUF9LRVJORUwtMCBwYWdlcy4KICovCgpzdGF0aWMgc3RydWN0IHBhZ2UgKgpwZXJmX21tYXBfdG9fcGFnZShzdHJ1Y3QgcGVyZl9idWZmZXIgKmJ1ZmZlciwgdW5zaWduZWQgbG9uZyBwZ29mZikKewoJaWYgKHBnb2ZmID4gYnVmZmVyLT5ucl9wYWdlcykKCQlyZXR1cm4gTlVMTDsKCglpZiAocGdvZmYgPT0gMCkKCQlyZXR1cm4gdmlydF90b19wYWdlKGJ1ZmZlci0+dXNlcl9wYWdlKTsKCglyZXR1cm4gdmlydF90b19wYWdlKGJ1ZmZlci0+ZGF0YV9wYWdlc1twZ29mZiAtIDFdKTsKfQoKc3RhdGljIHZvaWQgKnBlcmZfbW1hcF9hbGxvY19wYWdlKGludCBjcHUpCnsKCXN0cnVjdCBwYWdlICpwYWdlOwoJaW50IG5vZGU7CgoJbm9kZSA9IChjcHUgPT0gLTEpID8gY3B1IDogY3B1X3RvX25vZGUoY3B1KTsKCXBhZ2UgPSBhbGxvY19wYWdlc19ub2RlKG5vZGUsIEdGUF9LRVJORUwgfCBfX0dGUF9aRVJPLCAwKTsKCWlmICghcGFnZSkKCQlyZXR1cm4gTlVMTDsKCglyZXR1cm4gcGFnZV9hZGRyZXNzKHBhZ2UpOwp9CgpzdGF0aWMgc3RydWN0IHBlcmZfYnVmZmVyICoKcGVyZl9idWZmZXJfYWxsb2MoaW50IG5yX3BhZ2VzLCBsb25nIHdhdGVybWFyaywgaW50IGNwdSwgaW50IGZsYWdzKQp7CglzdHJ1Y3QgcGVyZl9idWZmZXIgKmJ1ZmZlcjsKCXVuc2lnbmVkIGxvbmcgc2l6ZTsKCWludCBpOwoKCXNpemUgPSBzaXplb2Yoc3RydWN0IHBlcmZfYnVmZmVyKTsKCXNpemUgKz0gbnJfcGFnZXMgKiBzaXplb2Yodm9pZCAqKTsKCglidWZmZXIgPSBremFsbG9jKHNpemUsIEdGUF9LRVJORUwpOwoJaWYgKCFidWZmZXIpCgkJZ290byBmYWlsOwoKCWJ1ZmZlci0+dXNlcl9wYWdlID0gcGVyZl9tbWFwX2FsbG9jX3BhZ2UoY3B1KTsKCWlmICghYnVmZmVyLT51c2VyX3BhZ2UpCgkJZ290byBmYWlsX3VzZXJfcGFnZTsKCglmb3IgKGkgPSAwOyBpIDwgbnJfcGFnZXM7IGkrKykgewoJCWJ1ZmZlci0+ZGF0YV9wYWdlc1tpXSA9IHBlcmZfbW1hcF9hbGxvY19wYWdlKGNwdSk7CgkJaWYgKCFidWZmZXItPmRhdGFfcGFnZXNbaV0pCgkJCWdvdG8gZmFpbF9kYXRhX3BhZ2VzOwoJfQoKCWJ1ZmZlci0+bnJfcGFnZXMgPSBucl9wYWdlczsKCglwZXJmX2J1ZmZlcl9pbml0KGJ1ZmZlciwgd2F0ZXJtYXJrLCBmbGFncyk7CgoJcmV0dXJuIGJ1ZmZlcjsKCmZhaWxfZGF0YV9wYWdlczoKCWZvciAoaS0tOyBpID49IDA7IGktLSkKCQlmcmVlX3BhZ2UoKHVuc2lnbmVkIGxvbmcpYnVmZmVyLT5kYXRhX3BhZ2VzW2ldKTsKCglmcmVlX3BhZ2UoKHVuc2lnbmVkIGxvbmcpYnVmZmVyLT51c2VyX3BhZ2UpOwoKZmFpbF91c2VyX3BhZ2U6CglrZnJlZShidWZmZXIpOwoKZmFpbDoKCXJldHVybiBOVUxMOwp9CgpzdGF0aWMgdm9pZCBwZXJmX21tYXBfZnJlZV9wYWdlKHVuc2lnbmVkIGxvbmcgYWRkcikKewoJc3RydWN0IHBhZ2UgKnBhZ2UgPSB2aXJ0X3RvX3BhZ2UoKHZvaWQgKilhZGRyKTsKCglwYWdlLT5tYXBwaW5nID0gTlVMTDsKCV9fZnJlZV9wYWdlKHBhZ2UpOwp9CgpzdGF0aWMgdm9pZCBwZXJmX2J1ZmZlcl9mcmVlKHN0cnVjdCBwZXJmX2J1ZmZlciAqYnVmZmVyKQp7CglpbnQgaTsKCglwZXJmX21tYXBfZnJlZV9wYWdlKCh1bnNpZ25lZCBsb25nKWJ1ZmZlci0+dXNlcl9wYWdlKTsKCWZvciAoaSA9IDA7IGkgPCBidWZmZXItPm5yX3BhZ2VzOyBpKyspCgkJcGVyZl9tbWFwX2ZyZWVfcGFnZSgodW5zaWduZWQgbG9uZylidWZmZXItPmRhdGFfcGFnZXNbaV0pOwoJa2ZyZWUoYnVmZmVyKTsKfQoKc3RhdGljIGlubGluZSBpbnQgcGFnZV9vcmRlcihzdHJ1Y3QgcGVyZl9idWZmZXIgKmJ1ZmZlcikKewoJcmV0dXJuIDA7Cn0KCiNlbHNlCgovKgogKiBCYWNrIHBlcmZfbW1hcCgpIHdpdGggdm1hbGxvYyBtZW1vcnkuCiAqCiAqIFJlcXVpcmVkIGZvciBhcmNoaXRlY3R1cmVzIHRoYXQgaGF2ZSBkLWNhY2hlIGFsaWFzaW5nIGlzc3Vlcy4KICovCgpzdGF0aWMgaW5saW5lIGludCBwYWdlX29yZGVyKHN0cnVjdCBwZXJmX2J1ZmZlciAqYnVmZmVyKQp7CglyZXR1cm4gYnVmZmVyLT5wYWdlX29yZGVyOwp9CgpzdGF0aWMgc3RydWN0IHBhZ2UgKgpwZXJmX21tYXBfdG9fcGFnZShzdHJ1Y3QgcGVyZl9idWZmZXIgKmJ1ZmZlciwgdW5zaWduZWQgbG9uZyBwZ29mZikKewoJaWYgKHBnb2ZmID4gKDFVTCA8PCBwYWdlX29yZGVyKGJ1ZmZlcikpKQoJCXJldHVybiBOVUxMOwoKCXJldHVybiB2bWFsbG9jX3RvX3BhZ2UoKHZvaWQgKilidWZmZXItPnVzZXJfcGFnZSArIHBnb2ZmICogUEFHRV9TSVpFKTsKfQoKc3RhdGljIHZvaWQgcGVyZl9tbWFwX3VubWFya19wYWdlKHZvaWQgKmFkZHIpCnsKCXN0cnVjdCBwYWdlICpwYWdlID0gdm1hbGxvY190b19wYWdlKGFkZHIpOwoKCXBhZ2UtPm1hcHBpbmcgPSBOVUxMOwp9CgpzdGF0aWMgdm9pZCBwZXJmX2J1ZmZlcl9mcmVlX3dvcmsoc3RydWN0IHdvcmtfc3RydWN0ICp3b3JrKQp7CglzdHJ1Y3QgcGVyZl9idWZmZXIgKmJ1ZmZlcjsKCXZvaWQgKmJhc2U7CglpbnQgaSwgbnI7CgoJYnVmZmVyID0gY29udGFpbmVyX29mKHdvcmssIHN0cnVjdCBwZXJmX2J1ZmZlciwgd29yayk7CgluciA9IDEgPDwgcGFnZV9vcmRlcihidWZmZXIpOwoKCWJhc2UgPSBidWZmZXItPnVzZXJfcGFnZTsKCWZvciAoaSA9IDA7IGkgPCBuciArIDE7IGkrKykKCQlwZXJmX21tYXBfdW5tYXJrX3BhZ2UoYmFzZSArIChpICogUEFHRV9TSVpFKSk7CgoJdmZyZWUoYmFzZSk7CglrZnJlZShidWZmZXIpOwp9CgpzdGF0aWMgdm9pZCBwZXJmX2J1ZmZlcl9mcmVlKHN0cnVjdCBwZXJmX2J1ZmZlciAqYnVmZmVyKQp7CglzY2hlZHVsZV93b3JrKCZidWZmZXItPndvcmspOwp9CgpzdGF0aWMgc3RydWN0IHBlcmZfYnVmZmVyICoKcGVyZl9idWZmZXJfYWxsb2MoaW50IG5yX3BhZ2VzLCBsb25nIHdhdGVybWFyaywgaW50IGNwdSwgaW50IGZsYWdzKQp7CglzdHJ1Y3QgcGVyZl9idWZmZXIgKmJ1ZmZlcjsKCXVuc2lnbmVkIGxvbmcgc2l6ZTsKCXZvaWQgKmFsbF9idWY7CgoJc2l6ZSA9IHNpemVvZihzdHJ1Y3QgcGVyZl9idWZmZXIpOwoJc2l6ZSArPSBzaXplb2Yodm9pZCAqKTsKCglidWZmZXIgPSBremFsbG9jKHNpemUsIEdGUF9LRVJORUwpOwoJaWYgKCFidWZmZXIpCgkJZ290byBmYWlsOwoKCUlOSVRfV09SSygmYnVmZmVyLT53b3JrLCBwZXJmX2J1ZmZlcl9mcmVlX3dvcmspOwoKCWFsbF9idWYgPSB2bWFsbG9jX3VzZXIoKG5yX3BhZ2VzICsgMSkgKiBQQUdFX1NJWkUpOwoJaWYgKCFhbGxfYnVmKQoJCWdvdG8gZmFpbF9hbGxfYnVmOwoKCWJ1ZmZlci0+dXNlcl9wYWdlID0gYWxsX2J1ZjsKCWJ1ZmZlci0+ZGF0YV9wYWdlc1swXSA9IGFsbF9idWYgKyBQQUdFX1NJWkU7CglidWZmZXItPnBhZ2Vfb3JkZXIgPSBpbG9nMihucl9wYWdlcyk7CglidWZmZXItPm5yX3BhZ2VzID0gMTsKCglwZXJmX2J1ZmZlcl9pbml0KGJ1ZmZlciwgd2F0ZXJtYXJrLCBmbGFncyk7CgoJcmV0dXJuIGJ1ZmZlcjsKCmZhaWxfYWxsX2J1ZjoKCWtmcmVlKGJ1ZmZlcik7CgpmYWlsOgoJcmV0dXJuIE5VTEw7Cn0KCiNlbmRpZgoKc3RhdGljIHVuc2lnbmVkIGxvbmcgcGVyZl9kYXRhX3NpemUoc3RydWN0IHBlcmZfYnVmZmVyICpidWZmZXIpCnsKCXJldHVybiBidWZmZXItPm5yX3BhZ2VzIDw8IChQQUdFX1NISUZUICsgcGFnZV9vcmRlcihidWZmZXIpKTsKfQoKc3RhdGljIGludCBwZXJmX21tYXBfZmF1bHQoc3RydWN0IHZtX2FyZWFfc3RydWN0ICp2bWEsIHN0cnVjdCB2bV9mYXVsdCAqdm1mKQp7CglzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQgPSB2bWEtPnZtX2ZpbGUtPnByaXZhdGVfZGF0YTsKCXN0cnVjdCBwZXJmX2J1ZmZlciAqYnVmZmVyOwoJaW50IHJldCA9IFZNX0ZBVUxUX1NJR0JVUzsKCglpZiAodm1mLT5mbGFncyAmIEZBVUxUX0ZMQUdfTUtXUklURSkgewoJCWlmICh2bWYtPnBnb2ZmID09IDApCgkJCXJldCA9IDA7CgkJcmV0dXJuIHJldDsKCX0KCglyY3VfcmVhZF9sb2NrKCk7CglidWZmZXIgPSByY3VfZGVyZWZlcmVuY2UoZXZlbnQtPmJ1ZmZlcik7CglpZiAoIWJ1ZmZlcikKCQlnb3RvIHVubG9jazsKCglpZiAodm1mLT5wZ29mZiAmJiAodm1mLT5mbGFncyAmIEZBVUxUX0ZMQUdfV1JJVEUpKQoJCWdvdG8gdW5sb2NrOwoKCXZtZi0+cGFnZSA9IHBlcmZfbW1hcF90b19wYWdlKGJ1ZmZlciwgdm1mLT5wZ29mZik7CglpZiAoIXZtZi0+cGFnZSkKCQlnb3RvIHVubG9jazsKCglnZXRfcGFnZSh2bWYtPnBhZ2UpOwoJdm1mLT5wYWdlLT5tYXBwaW5nID0gdm1hLT52bV9maWxlLT5mX21hcHBpbmc7Cgl2bWYtPnBhZ2UtPmluZGV4ICAgPSB2bWYtPnBnb2ZmOwoKCXJldCA9IDA7CnVubG9jazoKCXJjdV9yZWFkX3VubG9jaygpOwoKCXJldHVybiByZXQ7Cn0KCnN0YXRpYyB2b2lkIHBlcmZfYnVmZmVyX2ZyZWVfcmN1KHN0cnVjdCByY3VfaGVhZCAqcmN1X2hlYWQpCnsKCXN0cnVjdCBwZXJmX2J1ZmZlciAqYnVmZmVyOwoKCWJ1ZmZlciA9IGNvbnRhaW5lcl9vZihyY3VfaGVhZCwgc3RydWN0IHBlcmZfYnVmZmVyLCByY3VfaGVhZCk7CglwZXJmX2J1ZmZlcl9mcmVlKGJ1ZmZlcik7Cn0KCnN0YXRpYyBzdHJ1Y3QgcGVyZl9idWZmZXIgKnBlcmZfYnVmZmVyX2dldChzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQpCnsKCXN0cnVjdCBwZXJmX2J1ZmZlciAqYnVmZmVyOwoKCXJjdV9yZWFkX2xvY2soKTsKCWJ1ZmZlciA9IHJjdV9kZXJlZmVyZW5jZShldmVudC0+YnVmZmVyKTsKCWlmIChidWZmZXIpIHsKCQlpZiAoIWF0b21pY19pbmNfbm90X3plcm8oJmJ1ZmZlci0+cmVmY291bnQpKQoJCQlidWZmZXIgPSBOVUxMOwoJfQoJcmN1X3JlYWRfdW5sb2NrKCk7CgoJcmV0dXJuIGJ1ZmZlcjsKfQoKc3RhdGljIHZvaWQgcGVyZl9idWZmZXJfcHV0KHN0cnVjdCBwZXJmX2J1ZmZlciAqYnVmZmVyKQp7CglpZiAoIWF0b21pY19kZWNfYW5kX3Rlc3QoJmJ1ZmZlci0+cmVmY291bnQpKQoJCXJldHVybjsKCgljYWxsX3JjdSgmYnVmZmVyLT5yY3VfaGVhZCwgcGVyZl9idWZmZXJfZnJlZV9yY3UpOwp9CgpzdGF0aWMgdm9pZCBwZXJmX21tYXBfb3BlbihzdHJ1Y3Qgdm1fYXJlYV9zdHJ1Y3QgKnZtYSkKewoJc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50ID0gdm1hLT52bV9maWxlLT5wcml2YXRlX2RhdGE7CgoJYXRvbWljX2luYygmZXZlbnQtPm1tYXBfY291bnQpOwp9CgpzdGF0aWMgdm9pZCBwZXJmX21tYXBfY2xvc2Uoc3RydWN0IHZtX2FyZWFfc3RydWN0ICp2bWEpCnsKCXN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCA9IHZtYS0+dm1fZmlsZS0+cHJpdmF0ZV9kYXRhOwoKCWlmIChhdG9taWNfZGVjX2FuZF9tdXRleF9sb2NrKCZldmVudC0+bW1hcF9jb3VudCwgJmV2ZW50LT5tbWFwX211dGV4KSkgewoJCXVuc2lnbmVkIGxvbmcgc2l6ZSA9IHBlcmZfZGF0YV9zaXplKGV2ZW50LT5idWZmZXIpOwoJCXN0cnVjdCB1c2VyX3N0cnVjdCAqdXNlciA9IGV2ZW50LT5tbWFwX3VzZXI7CgkJc3RydWN0IHBlcmZfYnVmZmVyICpidWZmZXIgPSBldmVudC0+YnVmZmVyOwoKCQlhdG9taWNfbG9uZ19zdWIoKHNpemUgPj4gUEFHRV9TSElGVCkgKyAxLCAmdXNlci0+bG9ja2VkX3ZtKTsKCQl2bWEtPnZtX21tLT5sb2NrZWRfdm0gLT0gZXZlbnQtPm1tYXBfbG9ja2VkOwoJCXJjdV9hc3NpZ25fcG9pbnRlcihldmVudC0+YnVmZmVyLCBOVUxMKTsKCQltdXRleF91bmxvY2soJmV2ZW50LT5tbWFwX211dGV4KTsKCgkJcGVyZl9idWZmZXJfcHV0KGJ1ZmZlcik7CgkJZnJlZV91aWQodXNlcik7Cgl9Cn0KCnN0YXRpYyBjb25zdCBzdHJ1Y3Qgdm1fb3BlcmF0aW9uc19zdHJ1Y3QgcGVyZl9tbWFwX3Ztb3BzID0gewoJLm9wZW4JCT0gcGVyZl9tbWFwX29wZW4sCgkuY2xvc2UJCT0gcGVyZl9tbWFwX2Nsb3NlLAoJLmZhdWx0CQk9IHBlcmZfbW1hcF9mYXVsdCwKCS5wYWdlX21rd3JpdGUJPSBwZXJmX21tYXBfZmF1bHQsCn07CgpzdGF0aWMgaW50IHBlcmZfbW1hcChzdHJ1Y3QgZmlsZSAqZmlsZSwgc3RydWN0IHZtX2FyZWFfc3RydWN0ICp2bWEpCnsKCXN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCA9IGZpbGUtPnByaXZhdGVfZGF0YTsKCXVuc2lnbmVkIGxvbmcgdXNlcl9sb2NrZWQsIHVzZXJfbG9ja19saW1pdDsKCXN0cnVjdCB1c2VyX3N0cnVjdCAqdXNlciA9IGN1cnJlbnRfdXNlcigpOwoJdW5zaWduZWQgbG9uZyBsb2NrZWQsIGxvY2tfbGltaXQ7CglzdHJ1Y3QgcGVyZl9idWZmZXIgKmJ1ZmZlcjsKCXVuc2lnbmVkIGxvbmcgdm1hX3NpemU7Cgl1bnNpZ25lZCBsb25nIG5yX3BhZ2VzOwoJbG9uZyB1c2VyX2V4dHJhLCBleHRyYTsKCWludCByZXQgPSAwLCBmbGFncyA9IDA7CgoJLyoKCSAqIERvbid0IGFsbG93IG1tYXAoKSBvZiBpbmhlcml0ZWQgcGVyLXRhc2sgY291bnRlcnMuIFRoaXMgd291bGQKCSAqIGNyZWF0ZSBhIHBlcmZvcm1hbmNlIGlzc3VlIGR1ZSB0byBhbGwgY2hpbGRyZW4gd3JpdGluZyB0byB0aGUKCSAqIHNhbWUgYnVmZmVyLgoJICovCglpZiAoZXZlbnQtPmNwdSA9PSAtMSAmJiBldmVudC0+YXR0ci5pbmhlcml0KQoJCXJldHVybiAtRUlOVkFMOwoKCWlmICghKHZtYS0+dm1fZmxhZ3MgJiBWTV9TSEFSRUQpKQoJCXJldHVybiAtRUlOVkFMOwoKCXZtYV9zaXplID0gdm1hLT52bV9lbmQgLSB2bWEtPnZtX3N0YXJ0OwoJbnJfcGFnZXMgPSAodm1hX3NpemUgLyBQQUdFX1NJWkUpIC0gMTsKCgkvKgoJICogSWYgd2UgaGF2ZSBidWZmZXIgcGFnZXMgZW5zdXJlIHRoZXkncmUgYSBwb3dlci1vZi10d28gbnVtYmVyLCBzbyB3ZQoJICogY2FuIGRvIGJpdG1hc2tzIGluc3RlYWQgb2YgbW9kdWxvLgoJICovCglpZiAobnJfcGFnZXMgIT0gMCAmJiAhaXNfcG93ZXJfb2ZfMihucl9wYWdlcykpCgkJcmV0dXJuIC1FSU5WQUw7CgoJaWYgKHZtYV9zaXplICE9IFBBR0VfU0laRSAqICgxICsgbnJfcGFnZXMpKQoJCXJldHVybiAtRUlOVkFMOwoKCWlmICh2bWEtPnZtX3Bnb2ZmICE9IDApCgkJcmV0dXJuIC1FSU5WQUw7CgoJV0FSTl9PTl9PTkNFKGV2ZW50LT5jdHgtPnBhcmVudF9jdHgpOwoJbXV0ZXhfbG9jaygmZXZlbnQtPm1tYXBfbXV0ZXgpOwoJaWYgKGV2ZW50LT5idWZmZXIpIHsKCQlpZiAoZXZlbnQtPmJ1ZmZlci0+bnJfcGFnZXMgPT0gbnJfcGFnZXMpCgkJCWF0b21pY19pbmMoJmV2ZW50LT5idWZmZXItPnJlZmNvdW50KTsKCQllbHNlCgkJCXJldCA9IC1FSU5WQUw7CgkJZ290byB1bmxvY2s7Cgl9CgoJdXNlcl9leHRyYSA9IG5yX3BhZ2VzICsgMTsKCXVzZXJfbG9ja19saW1pdCA9IHN5c2N0bF9wZXJmX2V2ZW50X21sb2NrID4+IChQQUdFX1NISUZUIC0gMTApOwoKCS8qCgkgKiBJbmNyZWFzZSB0aGUgbGltaXQgbGluZWFybHkgd2l0aCBtb3JlIENQVXM6CgkgKi8KCXVzZXJfbG9ja19saW1pdCAqPSBudW1fb25saW5lX2NwdXMoKTsKCgl1c2VyX2xvY2tlZCA9IGF0b21pY19sb25nX3JlYWQoJnVzZXItPmxvY2tlZF92bSkgKyB1c2VyX2V4dHJhOwoKCWV4dHJhID0gMDsKCWlmICh1c2VyX2xvY2tlZCA+IHVzZXJfbG9ja19saW1pdCkKCQlleHRyYSA9IHVzZXJfbG9ja2VkIC0gdXNlcl9sb2NrX2xpbWl0OwoKCWxvY2tfbGltaXQgPSBybGltaXQoUkxJTUlUX01FTUxPQ0spOwoJbG9ja19saW1pdCA+Pj0gUEFHRV9TSElGVDsKCWxvY2tlZCA9IHZtYS0+dm1fbW0tPmxvY2tlZF92bSArIGV4dHJhOwoKCWlmICgobG9ja2VkID4gbG9ja19saW1pdCkgJiYgcGVyZl9wYXJhbm9pZF90cmFjZXBvaW50X3JhdygpICYmCgkJIWNhcGFibGUoQ0FQX0lQQ19MT0NLKSkgewoJCXJldCA9IC1FUEVSTTsKCQlnb3RvIHVubG9jazsKCX0KCglXQVJOX09OKGV2ZW50LT5idWZmZXIpOwoKCWlmICh2bWEtPnZtX2ZsYWdzICYgVk1fV1JJVEUpCgkJZmxhZ3MgfD0gUEVSRl9CVUZGRVJfV1JJVEFCTEU7CgoJYnVmZmVyID0gcGVyZl9idWZmZXJfYWxsb2MobnJfcGFnZXMsIGV2ZW50LT5hdHRyLndha2V1cF93YXRlcm1hcmssCgkJCQkgICBldmVudC0+Y3B1LCBmbGFncyk7CglpZiAoIWJ1ZmZlcikgewoJCXJldCA9IC1FTk9NRU07CgkJZ290byB1bmxvY2s7Cgl9CglyY3VfYXNzaWduX3BvaW50ZXIoZXZlbnQtPmJ1ZmZlciwgYnVmZmVyKTsKCglhdG9taWNfbG9uZ19hZGQodXNlcl9leHRyYSwgJnVzZXItPmxvY2tlZF92bSk7CglldmVudC0+bW1hcF9sb2NrZWQgPSBleHRyYTsKCWV2ZW50LT5tbWFwX3VzZXIgPSBnZXRfY3VycmVudF91c2VyKCk7Cgl2bWEtPnZtX21tLT5sb2NrZWRfdm0gKz0gZXZlbnQtPm1tYXBfbG9ja2VkOwoKdW5sb2NrOgoJaWYgKCFyZXQpCgkJYXRvbWljX2luYygmZXZlbnQtPm1tYXBfY291bnQpOwoJbXV0ZXhfdW5sb2NrKCZldmVudC0+bW1hcF9tdXRleCk7CgoJdm1hLT52bV9mbGFncyB8PSBWTV9SRVNFUlZFRDsKCXZtYS0+dm1fb3BzID0gJnBlcmZfbW1hcF92bW9wczsKCglyZXR1cm4gcmV0Owp9CgpzdGF0aWMgaW50IHBlcmZfZmFzeW5jKGludCBmZCwgc3RydWN0IGZpbGUgKmZpbHAsIGludCBvbikKewoJc3RydWN0IGlub2RlICppbm9kZSA9IGZpbHAtPmZfcGF0aC5kZW50cnktPmRfaW5vZGU7CglzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQgPSBmaWxwLT5wcml2YXRlX2RhdGE7CglpbnQgcmV0dmFsOwoKCW11dGV4X2xvY2soJmlub2RlLT5pX211dGV4KTsKCXJldHZhbCA9IGZhc3luY19oZWxwZXIoZmQsIGZpbHAsIG9uLCAmZXZlbnQtPmZhc3luYyk7CgltdXRleF91bmxvY2soJmlub2RlLT5pX211dGV4KTsKCglpZiAocmV0dmFsIDwgMCkKCQlyZXR1cm4gcmV0dmFsOwoKCXJldHVybiAwOwp9CgpzdGF0aWMgY29uc3Qgc3RydWN0IGZpbGVfb3BlcmF0aW9ucyBwZXJmX2ZvcHMgPSB7CgkubGxzZWVrCQkJPSBub19sbHNlZWssCgkucmVsZWFzZQkJPSBwZXJmX3JlbGVhc2UsCgkucmVhZAkJCT0gcGVyZl9yZWFkLAoJLnBvbGwJCQk9IHBlcmZfcG9sbCwKCS51bmxvY2tlZF9pb2N0bAkJPSBwZXJmX2lvY3RsLAoJLmNvbXBhdF9pb2N0bAkJPSBwZXJmX2lvY3RsLAoJLm1tYXAJCQk9IHBlcmZfbW1hcCwKCS5mYXN5bmMJCQk9IHBlcmZfZmFzeW5jLAp9OwoKLyoKICogUGVyZiBldmVudCB3YWtldXAKICoKICogSWYgdGhlcmUncyBkYXRhLCBlbnN1cmUgd2Ugc2V0IHRoZSBwb2xsKCkgc3RhdGUgYW5kIHB1Ymxpc2ggZXZlcnl0aGluZwogKiB0byB1c2VyLXNwYWNlIGJlZm9yZSB3YWtpbmcgZXZlcnlib2R5IHVwLgogKi8KCnZvaWQgcGVyZl9ldmVudF93YWtldXAoc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50KQp7Cgl3YWtlX3VwX2FsbCgmZXZlbnQtPndhaXRxKTsKCglpZiAoZXZlbnQtPnBlbmRpbmdfa2lsbCkgewoJCWtpbGxfZmFzeW5jKCZldmVudC0+ZmFzeW5jLCBTSUdJTywgZXZlbnQtPnBlbmRpbmdfa2lsbCk7CgkJZXZlbnQtPnBlbmRpbmdfa2lsbCA9IDA7Cgl9Cn0KCnN0YXRpYyB2b2lkIHBlcmZfcGVuZGluZ19ldmVudChzdHJ1Y3QgaXJxX3dvcmsgKmVudHJ5KQp7CglzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQgPSBjb250YWluZXJfb2YoZW50cnksCgkJCXN0cnVjdCBwZXJmX2V2ZW50LCBwZW5kaW5nKTsKCglpZiAoZXZlbnQtPnBlbmRpbmdfZGlzYWJsZSkgewoJCWV2ZW50LT5wZW5kaW5nX2Rpc2FibGUgPSAwOwoJCV9fcGVyZl9ldmVudF9kaXNhYmxlKGV2ZW50KTsKCX0KCglpZiAoZXZlbnQtPnBlbmRpbmdfd2FrZXVwKSB7CgkJZXZlbnQtPnBlbmRpbmdfd2FrZXVwID0gMDsKCQlwZXJmX2V2ZW50X3dha2V1cChldmVudCk7Cgl9Cn0KCi8qCiAqIFdlIGFzc3VtZSB0aGVyZSBpcyBvbmx5IEtWTSBzdXBwb3J0aW5nIHRoZSBjYWxsYmFja3MuCiAqIExhdGVyIG9uLCB3ZSBtaWdodCBjaGFuZ2UgaXQgdG8gYSBsaXN0IGlmIHRoZXJlIGlzCiAqIGFub3RoZXIgdmlydHVhbGl6YXRpb24gaW1wbGVtZW50YXRpb24gc3VwcG9ydGluZyB0aGUgY2FsbGJhY2tzLgogKi8Kc3RydWN0IHBlcmZfZ3Vlc3RfaW5mb19jYWxsYmFja3MgKnBlcmZfZ3Vlc3RfY2JzOwoKaW50IHBlcmZfcmVnaXN0ZXJfZ3Vlc3RfaW5mb19jYWxsYmFja3Moc3RydWN0IHBlcmZfZ3Vlc3RfaW5mb19jYWxsYmFja3MgKmNicykKewoJcGVyZl9ndWVzdF9jYnMgPSBjYnM7CglyZXR1cm4gMDsKfQpFWFBPUlRfU1lNQk9MX0dQTChwZXJmX3JlZ2lzdGVyX2d1ZXN0X2luZm9fY2FsbGJhY2tzKTsKCmludCBwZXJmX3VucmVnaXN0ZXJfZ3Vlc3RfaW5mb19jYWxsYmFja3Moc3RydWN0IHBlcmZfZ3Vlc3RfaW5mb19jYWxsYmFja3MgKmNicykKewoJcGVyZl9ndWVzdF9jYnMgPSBOVUxMOwoJcmV0dXJuIDA7Cn0KRVhQT1JUX1NZTUJPTF9HUEwocGVyZl91bnJlZ2lzdGVyX2d1ZXN0X2luZm9fY2FsbGJhY2tzKTsKCi8qCiAqIE91dHB1dAogKi8Kc3RhdGljIGJvb2wgcGVyZl9vdXRwdXRfc3BhY2Uoc3RydWN0IHBlcmZfYnVmZmVyICpidWZmZXIsIHVuc2lnbmVkIGxvbmcgdGFpbCwKCQkJICAgICAgdW5zaWduZWQgbG9uZyBvZmZzZXQsIHVuc2lnbmVkIGxvbmcgaGVhZCkKewoJdW5zaWduZWQgbG9uZyBtYXNrOwoKCWlmICghYnVmZmVyLT53cml0YWJsZSkKCQlyZXR1cm4gdHJ1ZTsKCgltYXNrID0gcGVyZl9kYXRhX3NpemUoYnVmZmVyKSAtIDE7CgoJb2Zmc2V0ID0gKG9mZnNldCAtIHRhaWwpICYgbWFzazsKCWhlYWQgICA9IChoZWFkICAgLSB0YWlsKSAmIG1hc2s7CgoJaWYgKChpbnQpKGhlYWQgLSBvZmZzZXQpIDwgMCkKCQlyZXR1cm4gZmFsc2U7CgoJcmV0dXJuIHRydWU7Cn0KCnN0YXRpYyB2b2lkIHBlcmZfb3V0cHV0X3dha2V1cChzdHJ1Y3QgcGVyZl9vdXRwdXRfaGFuZGxlICpoYW5kbGUpCnsKCWF0b21pY19zZXQoJmhhbmRsZS0+YnVmZmVyLT5wb2xsLCBQT0xMX0lOKTsKCglpZiAoaGFuZGxlLT5ubWkpIHsKCQloYW5kbGUtPmV2ZW50LT5wZW5kaW5nX3dha2V1cCA9IDE7CgkJaXJxX3dvcmtfcXVldWUoJmhhbmRsZS0+ZXZlbnQtPnBlbmRpbmcpOwoJfSBlbHNlCgkJcGVyZl9ldmVudF93YWtldXAoaGFuZGxlLT5ldmVudCk7Cn0KCi8qCiAqIFdlIG5lZWQgdG8gZW5zdXJlIGEgbGF0ZXIgZXZlbnRfaWQgZG9lc24ndCBwdWJsaXNoIGEgaGVhZCB3aGVuIGEgZm9ybWVyCiAqIGV2ZW50IGlzbid0IGRvbmUgd3JpdGluZy4gSG93ZXZlciBzaW5jZSB3ZSBuZWVkIHRvIGRlYWwgd2l0aCBOTUlzIHdlCiAqIGNhbm5vdCBmdWxseSBzZXJpYWxpemUgdGhpbmdzLgogKgogKiBXZSBvbmx5IHB1Ymxpc2ggdGhlIGhlYWQgKGFuZCBnZW5lcmF0ZSBhIHdha2V1cCkgd2hlbiB0aGUgb3V0ZXItbW9zdAogKiBldmVudCBjb21wbGV0ZXMuCiAqLwpzdGF0aWMgdm9pZCBwZXJmX291dHB1dF9nZXRfaGFuZGxlKHN0cnVjdCBwZXJmX291dHB1dF9oYW5kbGUgKmhhbmRsZSkKewoJc3RydWN0IHBlcmZfYnVmZmVyICpidWZmZXIgPSBoYW5kbGUtPmJ1ZmZlcjsKCglwcmVlbXB0X2Rpc2FibGUoKTsKCWxvY2FsX2luYygmYnVmZmVyLT5uZXN0KTsKCWhhbmRsZS0+d2FrZXVwID0gbG9jYWxfcmVhZCgmYnVmZmVyLT53YWtldXApOwp9CgpzdGF0aWMgdm9pZCBwZXJmX291dHB1dF9wdXRfaGFuZGxlKHN0cnVjdCBwZXJmX291dHB1dF9oYW5kbGUgKmhhbmRsZSkKewoJc3RydWN0IHBlcmZfYnVmZmVyICpidWZmZXIgPSBoYW5kbGUtPmJ1ZmZlcjsKCXVuc2lnbmVkIGxvbmcgaGVhZDsKCmFnYWluOgoJaGVhZCA9IGxvY2FsX3JlYWQoJmJ1ZmZlci0+aGVhZCk7CgoJLyoKCSAqIElSUS9OTUkgY2FuIGhhcHBlbiBoZXJlLCB3aGljaCBtZWFucyB3ZSBjYW4gbWlzcyBhIGhlYWQgdXBkYXRlLgoJICovCgoJaWYgKCFsb2NhbF9kZWNfYW5kX3Rlc3QoJmJ1ZmZlci0+bmVzdCkpCgkJZ290byBvdXQ7CgoJLyoKCSAqIFB1Ymxpc2ggdGhlIGtub3duIGdvb2QgaGVhZC4gUmVseSBvbiB0aGUgZnVsbCBiYXJyaWVyIGltcGxpZWQKCSAqIGJ5IGF0b21pY19kZWNfYW5kX3Rlc3QoKSBvcmRlciB0aGUgYnVmZmVyLT5oZWFkIHJlYWQgYW5kIHRoaXMKCSAqIHdyaXRlLgoJICovCglidWZmZXItPnVzZXJfcGFnZS0+ZGF0YV9oZWFkID0gaGVhZDsKCgkvKgoJICogTm93IGNoZWNrIGlmIHdlIG1pc3NlZCBhbiB1cGRhdGUsIHJlbHkgb24gdGhlIChjb21waWxlcikKCSAqIGJhcnJpZXIgaW4gYXRvbWljX2RlY19hbmRfdGVzdCgpIHRvIHJlLXJlYWQgYnVmZmVyLT5oZWFkLgoJICovCglpZiAodW5saWtlbHkoaGVhZCAhPSBsb2NhbF9yZWFkKCZidWZmZXItPmhlYWQpKSkgewoJCWxvY2FsX2luYygmYnVmZmVyLT5uZXN0KTsKCQlnb3RvIGFnYWluOwoJfQoKCWlmIChoYW5kbGUtPndha2V1cCAhPSBsb2NhbF9yZWFkKCZidWZmZXItPndha2V1cCkpCgkJcGVyZl9vdXRwdXRfd2FrZXVwKGhhbmRsZSk7CgpvdXQ6CglwcmVlbXB0X2VuYWJsZSgpOwp9CgpfX2Fsd2F5c19pbmxpbmUgdm9pZCBwZXJmX291dHB1dF9jb3B5KHN0cnVjdCBwZXJmX291dHB1dF9oYW5kbGUgKmhhbmRsZSwKCQkgICAgICBjb25zdCB2b2lkICpidWYsIHVuc2lnbmVkIGludCBsZW4pCnsKCWRvIHsKCQl1bnNpZ25lZCBsb25nIHNpemUgPSBtaW5fdCh1bnNpZ25lZCBsb25nLCBoYW5kbGUtPnNpemUsIGxlbik7CgoJCW1lbWNweShoYW5kbGUtPmFkZHIsIGJ1Ziwgc2l6ZSk7CgoJCWxlbiAtPSBzaXplOwoJCWhhbmRsZS0+YWRkciArPSBzaXplOwoJCWJ1ZiArPSBzaXplOwoJCWhhbmRsZS0+c2l6ZSAtPSBzaXplOwoJCWlmICghaGFuZGxlLT5zaXplKSB7CgkJCXN0cnVjdCBwZXJmX2J1ZmZlciAqYnVmZmVyID0gaGFuZGxlLT5idWZmZXI7CgoJCQloYW5kbGUtPnBhZ2UrKzsKCQkJaGFuZGxlLT5wYWdlICY9IGJ1ZmZlci0+bnJfcGFnZXMgLSAxOwoJCQloYW5kbGUtPmFkZHIgPSBidWZmZXItPmRhdGFfcGFnZXNbaGFuZGxlLT5wYWdlXTsKCQkJaGFuZGxlLT5zaXplID0gUEFHRV9TSVpFIDw8IHBhZ2Vfb3JkZXIoYnVmZmVyKTsKCQl9Cgl9IHdoaWxlIChsZW4pOwp9CgpzdGF0aWMgdm9pZCBfX3BlcmZfZXZlbnRfaGVhZGVyX19pbml0X2lkKHN0cnVjdCBwZXJmX2V2ZW50X2hlYWRlciAqaGVhZGVyLAoJCQkJCSBzdHJ1Y3QgcGVyZl9zYW1wbGVfZGF0YSAqZGF0YSwKCQkJCQkgc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50KQp7Cgl1NjQgc2FtcGxlX3R5cGUgPSBldmVudC0+YXR0ci5zYW1wbGVfdHlwZTsKCglkYXRhLT50eXBlID0gc2FtcGxlX3R5cGU7CgloZWFkZXItPnNpemUgKz0gZXZlbnQtPmlkX2hlYWRlcl9zaXplOwoKCWlmIChzYW1wbGVfdHlwZSAmIFBFUkZfU0FNUExFX1RJRCkgewoJCS8qIG5hbWVzcGFjZSBpc3N1ZXMgKi8KCQlkYXRhLT50aWRfZW50cnkucGlkID0gcGVyZl9ldmVudF9waWQoZXZlbnQsIGN1cnJlbnQpOwoJCWRhdGEtPnRpZF9lbnRyeS50aWQgPSBwZXJmX2V2ZW50X3RpZChldmVudCwgY3VycmVudCk7Cgl9CgoJaWYgKHNhbXBsZV90eXBlICYgUEVSRl9TQU1QTEVfVElNRSkKCQlkYXRhLT50aW1lID0gcGVyZl9jbG9jaygpOwoKCWlmIChzYW1wbGVfdHlwZSAmIFBFUkZfU0FNUExFX0lEKQoJCWRhdGEtPmlkID0gcHJpbWFyeV9ldmVudF9pZChldmVudCk7CgoJaWYgKHNhbXBsZV90eXBlICYgUEVSRl9TQU1QTEVfU1RSRUFNX0lEKQoJCWRhdGEtPnN0cmVhbV9pZCA9IGV2ZW50LT5pZDsKCglpZiAoc2FtcGxlX3R5cGUgJiBQRVJGX1NBTVBMRV9DUFUpIHsKCQlkYXRhLT5jcHVfZW50cnkuY3B1CSA9IHJhd19zbXBfcHJvY2Vzc29yX2lkKCk7CgkJZGF0YS0+Y3B1X2VudHJ5LnJlc2VydmVkID0gMDsKCX0KfQoKc3RhdGljIHZvaWQgcGVyZl9ldmVudF9oZWFkZXJfX2luaXRfaWQoc3RydWN0IHBlcmZfZXZlbnRfaGVhZGVyICpoZWFkZXIsCgkJCQkgICAgICAgc3RydWN0IHBlcmZfc2FtcGxlX2RhdGEgKmRhdGEsCgkJCQkgICAgICAgc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50KQp7CglpZiAoZXZlbnQtPmF0dHIuc2FtcGxlX2lkX2FsbCkKCQlfX3BlcmZfZXZlbnRfaGVhZGVyX19pbml0X2lkKGhlYWRlciwgZGF0YSwgZXZlbnQpOwp9CgpzdGF0aWMgdm9pZCBfX3BlcmZfZXZlbnRfX291dHB1dF9pZF9zYW1wbGUoc3RydWN0IHBlcmZfb3V0cHV0X2hhbmRsZSAqaGFuZGxlLAoJCQkJCSAgIHN0cnVjdCBwZXJmX3NhbXBsZV9kYXRhICpkYXRhKQp7Cgl1NjQgc2FtcGxlX3R5cGUgPSBkYXRhLT50eXBlOwoKCWlmIChzYW1wbGVfdHlwZSAmIFBFUkZfU0FNUExFX1RJRCkKCQlwZXJmX291dHB1dF9wdXQoaGFuZGxlLCBkYXRhLT50aWRfZW50cnkpOwoKCWlmIChzYW1wbGVfdHlwZSAmIFBFUkZfU0FNUExFX1RJTUUpCgkJcGVyZl9vdXRwdXRfcHV0KGhhbmRsZSwgZGF0YS0+dGltZSk7CgoJaWYgKHNhbXBsZV90eXBlICYgUEVSRl9TQU1QTEVfSUQpCgkJcGVyZl9vdXRwdXRfcHV0KGhhbmRsZSwgZGF0YS0+aWQpOwoKCWlmIChzYW1wbGVfdHlwZSAmIFBFUkZfU0FNUExFX1NUUkVBTV9JRCkKCQlwZXJmX291dHB1dF9wdXQoaGFuZGxlLCBkYXRhLT5zdHJlYW1faWQpOwoKCWlmIChzYW1wbGVfdHlwZSAmIFBFUkZfU0FNUExFX0NQVSkKCQlwZXJmX291dHB1dF9wdXQoaGFuZGxlLCBkYXRhLT5jcHVfZW50cnkpOwp9CgpzdGF0aWMgdm9pZCBwZXJmX2V2ZW50X19vdXRwdXRfaWRfc2FtcGxlKHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCwKCQkJCQkgc3RydWN0IHBlcmZfb3V0cHV0X2hhbmRsZSAqaGFuZGxlLAoJCQkJCSBzdHJ1Y3QgcGVyZl9zYW1wbGVfZGF0YSAqc2FtcGxlKQp7CglpZiAoZXZlbnQtPmF0dHIuc2FtcGxlX2lkX2FsbCkKCQlfX3BlcmZfZXZlbnRfX291dHB1dF9pZF9zYW1wbGUoaGFuZGxlLCBzYW1wbGUpOwp9CgppbnQgcGVyZl9vdXRwdXRfYmVnaW4oc3RydWN0IHBlcmZfb3V0cHV0X2hhbmRsZSAqaGFuZGxlLAoJCSAgICAgIHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCwgdW5zaWduZWQgaW50IHNpemUsCgkJICAgICAgaW50IG5taSwgaW50IHNhbXBsZSkKewoJc3RydWN0IHBlcmZfYnVmZmVyICpidWZmZXI7Cgl1bnNpZ25lZCBsb25nIHRhaWwsIG9mZnNldCwgaGVhZDsKCWludCBoYXZlX2xvc3Q7CglzdHJ1Y3QgcGVyZl9zYW1wbGVfZGF0YSBzYW1wbGVfZGF0YTsKCXN0cnVjdCB7CgkJc3RydWN0IHBlcmZfZXZlbnRfaGVhZGVyIGhlYWRlcjsKCQl1NjQJCQkgaWQ7CgkJdTY0CQkJIGxvc3Q7Cgl9IGxvc3RfZXZlbnQ7CgoJcmN1X3JlYWRfbG9jaygpOwoJLyoKCSAqIEZvciBpbmhlcml0ZWQgZXZlbnRzIHdlIHNlbmQgYWxsIHRoZSBvdXRwdXQgdG93YXJkcyB0aGUgcGFyZW50LgoJICovCglpZiAoZXZlbnQtPnBhcmVudCkKCQlldmVudCA9IGV2ZW50LT5wYXJlbnQ7CgoJYnVmZmVyID0gcmN1X2RlcmVmZXJlbmNlKGV2ZW50LT5idWZmZXIpOwoJaWYgKCFidWZmZXIpCgkJZ290byBvdXQ7CgoJaGFuZGxlLT5idWZmZXIJPSBidWZmZXI7CgloYW5kbGUtPmV2ZW50CT0gZXZlbnQ7CgloYW5kbGUtPm5taQk9IG5taTsKCWhhbmRsZS0+c2FtcGxlCT0gc2FtcGxlOwoKCWlmICghYnVmZmVyLT5ucl9wYWdlcykKCQlnb3RvIG91dDsKCgloYXZlX2xvc3QgPSBsb2NhbF9yZWFkKCZidWZmZXItPmxvc3QpOwoJaWYgKGhhdmVfbG9zdCkgewoJCWxvc3RfZXZlbnQuaGVhZGVyLnNpemUgPSBzaXplb2YobG9zdF9ldmVudCk7CgkJcGVyZl9ldmVudF9oZWFkZXJfX2luaXRfaWQoJmxvc3RfZXZlbnQuaGVhZGVyLCAmc2FtcGxlX2RhdGEsCgkJCQkJICAgZXZlbnQpOwoJCXNpemUgKz0gbG9zdF9ldmVudC5oZWFkZXIuc2l6ZTsKCX0KCglwZXJmX291dHB1dF9nZXRfaGFuZGxlKGhhbmRsZSk7CgoJZG8gewoJCS8qCgkJICogVXNlcnNwYWNlIGNvdWxkIGNob29zZSB0byBpc3N1ZSBhIG1iKCkgYmVmb3JlIHVwZGF0aW5nIHRoZQoJCSAqIHRhaWwgcG9pbnRlci4gU28gdGhhdCBhbGwgcmVhZHMgd2lsbCBiZSBjb21wbGV0ZWQgYmVmb3JlIHRoZQoJCSAqIHdyaXRlIGlzIGlzc3VlZC4KCQkgKi8KCQl0YWlsID0gQUNDRVNTX09OQ0UoYnVmZmVyLT51c2VyX3BhZ2UtPmRhdGFfdGFpbCk7CgkJc21wX3JtYigpOwoJCW9mZnNldCA9IGhlYWQgPSBsb2NhbF9yZWFkKCZidWZmZXItPmhlYWQpOwoJCWhlYWQgKz0gc2l6ZTsKCQlpZiAodW5saWtlbHkoIXBlcmZfb3V0cHV0X3NwYWNlKGJ1ZmZlciwgdGFpbCwgb2Zmc2V0LCBoZWFkKSkpCgkJCWdvdG8gZmFpbDsKCX0gd2hpbGUgKGxvY2FsX2NtcHhjaGcoJmJ1ZmZlci0+aGVhZCwgb2Zmc2V0LCBoZWFkKSAhPSBvZmZzZXQpOwoKCWlmIChoZWFkIC0gbG9jYWxfcmVhZCgmYnVmZmVyLT53YWtldXApID4gYnVmZmVyLT53YXRlcm1hcmspCgkJbG9jYWxfYWRkKGJ1ZmZlci0+d2F0ZXJtYXJrLCAmYnVmZmVyLT53YWtldXApOwoKCWhhbmRsZS0+cGFnZSA9IG9mZnNldCA+PiAoUEFHRV9TSElGVCArIHBhZ2Vfb3JkZXIoYnVmZmVyKSk7CgloYW5kbGUtPnBhZ2UgJj0gYnVmZmVyLT5ucl9wYWdlcyAtIDE7CgloYW5kbGUtPnNpemUgPSBvZmZzZXQgJiAoKFBBR0VfU0laRSA8PCBwYWdlX29yZGVyKGJ1ZmZlcikpIC0gMSk7CgloYW5kbGUtPmFkZHIgPSBidWZmZXItPmRhdGFfcGFnZXNbaGFuZGxlLT5wYWdlXTsKCWhhbmRsZS0+YWRkciArPSBoYW5kbGUtPnNpemU7CgloYW5kbGUtPnNpemUgPSAoUEFHRV9TSVpFIDw8IHBhZ2Vfb3JkZXIoYnVmZmVyKSkgLSBoYW5kbGUtPnNpemU7CgoJaWYgKGhhdmVfbG9zdCkgewoJCWxvc3RfZXZlbnQuaGVhZGVyLnR5cGUgPSBQRVJGX1JFQ09SRF9MT1NUOwoJCWxvc3RfZXZlbnQuaGVhZGVyLm1pc2MgPSAwOwoJCWxvc3RfZXZlbnQuaWQgICAgICAgICAgPSBldmVudC0+aWQ7CgkJbG9zdF9ldmVudC5sb3N0ICAgICAgICA9IGxvY2FsX3hjaGcoJmJ1ZmZlci0+bG9zdCwgMCk7CgoJCXBlcmZfb3V0cHV0X3B1dChoYW5kbGUsIGxvc3RfZXZlbnQpOwoJCXBlcmZfZXZlbnRfX291dHB1dF9pZF9zYW1wbGUoZXZlbnQsIGhhbmRsZSwgJnNhbXBsZV9kYXRhKTsKCX0KCglyZXR1cm4gMDsKCmZhaWw6Cglsb2NhbF9pbmMoJmJ1ZmZlci0+bG9zdCk7CglwZXJmX291dHB1dF9wdXRfaGFuZGxlKGhhbmRsZSk7Cm91dDoKCXJjdV9yZWFkX3VubG9jaygpOwoKCXJldHVybiAtRU5PU1BDOwp9Cgp2b2lkIHBlcmZfb3V0cHV0X2VuZChzdHJ1Y3QgcGVyZl9vdXRwdXRfaGFuZGxlICpoYW5kbGUpCnsKCXN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCA9IGhhbmRsZS0+ZXZlbnQ7CglzdHJ1Y3QgcGVyZl9idWZmZXIgKmJ1ZmZlciA9IGhhbmRsZS0+YnVmZmVyOwoKCWludCB3YWtldXBfZXZlbnRzID0gZXZlbnQtPmF0dHIud2FrZXVwX2V2ZW50czsKCglpZiAoaGFuZGxlLT5zYW1wbGUgJiYgd2FrZXVwX2V2ZW50cykgewoJCWludCBldmVudHMgPSBsb2NhbF9pbmNfcmV0dXJuKCZidWZmZXItPmV2ZW50cyk7CgkJaWYgKGV2ZW50cyA+PSB3YWtldXBfZXZlbnRzKSB7CgkJCWxvY2FsX3N1Yih3YWtldXBfZXZlbnRzLCAmYnVmZmVyLT5ldmVudHMpOwoJCQlsb2NhbF9pbmMoJmJ1ZmZlci0+d2FrZXVwKTsKCQl9Cgl9CgoJcGVyZl9vdXRwdXRfcHV0X2hhbmRsZShoYW5kbGUpOwoJcmN1X3JlYWRfdW5sb2NrKCk7Cn0KCnN0YXRpYyB2b2lkIHBlcmZfb3V0cHV0X3JlYWRfb25lKHN0cnVjdCBwZXJmX291dHB1dF9oYW5kbGUgKmhhbmRsZSwKCQkJCSBzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQsCgkJCQkgdTY0IGVuYWJsZWQsIHU2NCBydW5uaW5nKQp7Cgl1NjQgcmVhZF9mb3JtYXQgPSBldmVudC0+YXR0ci5yZWFkX2Zvcm1hdDsKCXU2NCB2YWx1ZXNbNF07CglpbnQgbiA9IDA7CgoJdmFsdWVzW24rK10gPSBwZXJmX2V2ZW50X2NvdW50KGV2ZW50KTsKCWlmIChyZWFkX2Zvcm1hdCAmIFBFUkZfRk9STUFUX1RPVEFMX1RJTUVfRU5BQkxFRCkgewoJCXZhbHVlc1tuKytdID0gZW5hYmxlZCArCgkJCWF0b21pYzY0X3JlYWQoJmV2ZW50LT5jaGlsZF90b3RhbF90aW1lX2VuYWJsZWQpOwoJfQoJaWYgKHJlYWRfZm9ybWF0ICYgUEVSRl9GT1JNQVRfVE9UQUxfVElNRV9SVU5OSU5HKSB7CgkJdmFsdWVzW24rK10gPSBydW5uaW5nICsKCQkJYXRvbWljNjRfcmVhZCgmZXZlbnQtPmNoaWxkX3RvdGFsX3RpbWVfcnVubmluZyk7Cgl9CglpZiAocmVhZF9mb3JtYXQgJiBQRVJGX0ZPUk1BVF9JRCkKCQl2YWx1ZXNbbisrXSA9IHByaW1hcnlfZXZlbnRfaWQoZXZlbnQpOwoKCXBlcmZfb3V0cHV0X2NvcHkoaGFuZGxlLCB2YWx1ZXMsIG4gKiBzaXplb2YodTY0KSk7Cn0KCi8qCiAqIFhYWCBQRVJGX0ZPUk1BVF9HUk9VUCB2cyBpbmhlcml0ZWQgZXZlbnRzIHNlZW1zIGRpZmZpY3VsdC4KICovCnN0YXRpYyB2b2lkIHBlcmZfb3V0cHV0X3JlYWRfZ3JvdXAoc3RydWN0IHBlcmZfb3V0cHV0X2hhbmRsZSAqaGFuZGxlLAoJCQkgICAgc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50LAoJCQkgICAgdTY0IGVuYWJsZWQsIHU2NCBydW5uaW5nKQp7CglzdHJ1Y3QgcGVyZl9ldmVudCAqbGVhZGVyID0gZXZlbnQtPmdyb3VwX2xlYWRlciwgKnN1YjsKCXU2NCByZWFkX2Zvcm1hdCA9IGV2ZW50LT5hdHRyLnJlYWRfZm9ybWF0OwoJdTY0IHZhbHVlc1s1XTsKCWludCBuID0gMDsKCgl2YWx1ZXNbbisrXSA9IDEgKyBsZWFkZXItPm5yX3NpYmxpbmdzOwoKCWlmIChyZWFkX2Zvcm1hdCAmIFBFUkZfRk9STUFUX1RPVEFMX1RJTUVfRU5BQkxFRCkKCQl2YWx1ZXNbbisrXSA9IGVuYWJsZWQ7CgoJaWYgKHJlYWRfZm9ybWF0ICYgUEVSRl9GT1JNQVRfVE9UQUxfVElNRV9SVU5OSU5HKQoJCXZhbHVlc1tuKytdID0gcnVubmluZzsKCglpZiAobGVhZGVyICE9IGV2ZW50KQoJCWxlYWRlci0+cG11LT5yZWFkKGxlYWRlcik7CgoJdmFsdWVzW24rK10gPSBwZXJmX2V2ZW50X2NvdW50KGxlYWRlcik7CglpZiAocmVhZF9mb3JtYXQgJiBQRVJGX0ZPUk1BVF9JRCkKCQl2YWx1ZXNbbisrXSA9IHByaW1hcnlfZXZlbnRfaWQobGVhZGVyKTsKCglwZXJmX291dHB1dF9jb3B5KGhhbmRsZSwgdmFsdWVzLCBuICogc2l6ZW9mKHU2NCkpOwoKCWxpc3RfZm9yX2VhY2hfZW50cnkoc3ViLCAmbGVhZGVyLT5zaWJsaW5nX2xpc3QsIGdyb3VwX2VudHJ5KSB7CgkJbiA9IDA7CgoJCWlmIChzdWIgIT0gZXZlbnQpCgkJCXN1Yi0+cG11LT5yZWFkKHN1Yik7CgoJCXZhbHVlc1tuKytdID0gcGVyZl9ldmVudF9jb3VudChzdWIpOwoJCWlmIChyZWFkX2Zvcm1hdCAmIFBFUkZfRk9STUFUX0lEKQoJCQl2YWx1ZXNbbisrXSA9IHByaW1hcnlfZXZlbnRfaWQoc3ViKTsKCgkJcGVyZl9vdXRwdXRfY29weShoYW5kbGUsIHZhbHVlcywgbiAqIHNpemVvZih1NjQpKTsKCX0KfQoKI2RlZmluZSBQRVJGX0ZPUk1BVF9UT1RBTF9USU1FUyAoUEVSRl9GT1JNQVRfVE9UQUxfVElNRV9FTkFCTEVEfFwKCQkJCSBQRVJGX0ZPUk1BVF9UT1RBTF9USU1FX1JVTk5JTkcpCgpzdGF0aWMgdm9pZCBwZXJmX291dHB1dF9yZWFkKHN0cnVjdCBwZXJmX291dHB1dF9oYW5kbGUgKmhhbmRsZSwKCQkJICAgICBzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQpCnsKCXU2NCBlbmFibGVkID0gMCwgcnVubmluZyA9IDAsIG5vdywgY3R4X3RpbWU7Cgl1NjQgcmVhZF9mb3JtYXQgPSBldmVudC0+YXR0ci5yZWFkX2Zvcm1hdDsKCgkvKgoJICogY29tcHV0ZSB0b3RhbF90aW1lX2VuYWJsZWQsIHRvdGFsX3RpbWVfcnVubmluZwoJICogYmFzZWQgb24gc25hcHNob3QgdmFsdWVzIHRha2VuIHdoZW4gdGhlIGV2ZW50CgkgKiB3YXMgbGFzdCBzY2hlZHVsZWQgaW4uCgkgKgoJICogd2UgY2Fubm90IHNpbXBseSBjYWxsZWQgdXBkYXRlX2NvbnRleHRfdGltZSgpCgkgKiBiZWNhdXNlIG9mIGxvY2tpbmcgaXNzdWUgYXMgd2UgYXJlIGNhbGxlZCBpbgoJICogTk1JIGNvbnRleHQKCSAqLwoJaWYgKHJlYWRfZm9ybWF0ICYgUEVSRl9GT1JNQVRfVE9UQUxfVElNRVMpIHsKCQlub3cgPSBwZXJmX2Nsb2NrKCk7CgkJY3R4X3RpbWUgPSBldmVudC0+c2hhZG93X2N0eF90aW1lICsgbm93OwoJCWVuYWJsZWQgPSBjdHhfdGltZSAtIGV2ZW50LT50c3RhbXBfZW5hYmxlZDsKCQlydW5uaW5nID0gY3R4X3RpbWUgLSBldmVudC0+dHN0YW1wX3J1bm5pbmc7Cgl9CgoJaWYgKGV2ZW50LT5hdHRyLnJlYWRfZm9ybWF0ICYgUEVSRl9GT1JNQVRfR1JPVVApCgkJcGVyZl9vdXRwdXRfcmVhZF9ncm91cChoYW5kbGUsIGV2ZW50LCBlbmFibGVkLCBydW5uaW5nKTsKCWVsc2UKCQlwZXJmX291dHB1dF9yZWFkX29uZShoYW5kbGUsIGV2ZW50LCBlbmFibGVkLCBydW5uaW5nKTsKfQoKdm9pZCBwZXJmX291dHB1dF9zYW1wbGUoc3RydWN0IHBlcmZfb3V0cHV0X2hhbmRsZSAqaGFuZGxlLAoJCQlzdHJ1Y3QgcGVyZl9ldmVudF9oZWFkZXIgKmhlYWRlciwKCQkJc3RydWN0IHBlcmZfc2FtcGxlX2RhdGEgKmRhdGEsCgkJCXN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCkKewoJdTY0IHNhbXBsZV90eXBlID0gZGF0YS0+dHlwZTsKCglwZXJmX291dHB1dF9wdXQoaGFuZGxlLCAqaGVhZGVyKTsKCglpZiAoc2FtcGxlX3R5cGUgJiBQRVJGX1NBTVBMRV9JUCkKCQlwZXJmX291dHB1dF9wdXQoaGFuZGxlLCBkYXRhLT5pcCk7CgoJaWYgKHNhbXBsZV90eXBlICYgUEVSRl9TQU1QTEVfVElEKQoJCXBlcmZfb3V0cHV0X3B1dChoYW5kbGUsIGRhdGEtPnRpZF9lbnRyeSk7CgoJaWYgKHNhbXBsZV90eXBlICYgUEVSRl9TQU1QTEVfVElNRSkKCQlwZXJmX291dHB1dF9wdXQoaGFuZGxlLCBkYXRhLT50aW1lKTsKCglpZiAoc2FtcGxlX3R5cGUgJiBQRVJGX1NBTVBMRV9BRERSKQoJCXBlcmZfb3V0cHV0X3B1dChoYW5kbGUsIGRhdGEtPmFkZHIpOwoKCWlmIChzYW1wbGVfdHlwZSAmIFBFUkZfU0FNUExFX0lEKQoJCXBlcmZfb3V0cHV0X3B1dChoYW5kbGUsIGRhdGEtPmlkKTsKCglpZiAoc2FtcGxlX3R5cGUgJiBQRVJGX1NBTVBMRV9TVFJFQU1fSUQpCgkJcGVyZl9vdXRwdXRfcHV0KGhhbmRsZSwgZGF0YS0+c3RyZWFtX2lkKTsKCglpZiAoc2FtcGxlX3R5cGUgJiBQRVJGX1NBTVBMRV9DUFUpCgkJcGVyZl9vdXRwdXRfcHV0KGhhbmRsZSwgZGF0YS0+Y3B1X2VudHJ5KTsKCglpZiAoc2FtcGxlX3R5cGUgJiBQRVJGX1NBTVBMRV9QRVJJT0QpCgkJcGVyZl9vdXRwdXRfcHV0KGhhbmRsZSwgZGF0YS0+cGVyaW9kKTsKCglpZiAoc2FtcGxlX3R5cGUgJiBQRVJGX1NBTVBMRV9SRUFEKQoJCXBlcmZfb3V0cHV0X3JlYWQoaGFuZGxlLCBldmVudCk7CgoJaWYgKHNhbXBsZV90eXBlICYgUEVSRl9TQU1QTEVfQ0FMTENIQUlOKSB7CgkJaWYgKGRhdGEtPmNhbGxjaGFpbikgewoJCQlpbnQgc2l6ZSA9IDE7CgoJCQlpZiAoZGF0YS0+Y2FsbGNoYWluKQoJCQkJc2l6ZSArPSBkYXRhLT5jYWxsY2hhaW4tPm5yOwoKCQkJc2l6ZSAqPSBzaXplb2YodTY0KTsKCgkJCXBlcmZfb3V0cHV0X2NvcHkoaGFuZGxlLCBkYXRhLT5jYWxsY2hhaW4sIHNpemUpOwoJCX0gZWxzZSB7CgkJCXU2NCBuciA9IDA7CgkJCXBlcmZfb3V0cHV0X3B1dChoYW5kbGUsIG5yKTsKCQl9Cgl9CgoJaWYgKHNhbXBsZV90eXBlICYgUEVSRl9TQU1QTEVfUkFXKSB7CgkJaWYgKGRhdGEtPnJhdykgewoJCQlwZXJmX291dHB1dF9wdXQoaGFuZGxlLCBkYXRhLT5yYXctPnNpemUpOwoJCQlwZXJmX291dHB1dF9jb3B5KGhhbmRsZSwgZGF0YS0+cmF3LT5kYXRhLAoJCQkJCSBkYXRhLT5yYXctPnNpemUpOwoJCX0gZWxzZSB7CgkJCXN0cnVjdCB7CgkJCQl1MzIJc2l6ZTsKCQkJCXUzMglkYXRhOwoJCQl9IHJhdyA9IHsKCQkJCS5zaXplID0gc2l6ZW9mKHUzMiksCgkJCQkuZGF0YSA9IDAsCgkJCX07CgkJCXBlcmZfb3V0cHV0X3B1dChoYW5kbGUsIHJhdyk7CgkJfQoJfQp9Cgp2b2lkIHBlcmZfcHJlcGFyZV9zYW1wbGUoc3RydWN0IHBlcmZfZXZlbnRfaGVhZGVyICpoZWFkZXIsCgkJCSBzdHJ1Y3QgcGVyZl9zYW1wbGVfZGF0YSAqZGF0YSwKCQkJIHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCwKCQkJIHN0cnVjdCBwdF9yZWdzICpyZWdzKQp7Cgl1NjQgc2FtcGxlX3R5cGUgPSBldmVudC0+YXR0ci5zYW1wbGVfdHlwZTsKCgloZWFkZXItPnR5cGUgPSBQRVJGX1JFQ09SRF9TQU1QTEU7CgloZWFkZXItPnNpemUgPSBzaXplb2YoKmhlYWRlcikgKyBldmVudC0+aGVhZGVyX3NpemU7CgoJaGVhZGVyLT5taXNjID0gMDsKCWhlYWRlci0+bWlzYyB8PSBwZXJmX21pc2NfZmxhZ3MocmVncyk7CgoJX19wZXJmX2V2ZW50X2hlYWRlcl9faW5pdF9pZChoZWFkZXIsIGRhdGEsIGV2ZW50KTsKCglpZiAoc2FtcGxlX3R5cGUgJiBQRVJGX1NBTVBMRV9JUCkKCQlkYXRhLT5pcCA9IHBlcmZfaW5zdHJ1Y3Rpb25fcG9pbnRlcihyZWdzKTsKCglpZiAoc2FtcGxlX3R5cGUgJiBQRVJGX1NBTVBMRV9DQUxMQ0hBSU4pIHsKCQlpbnQgc2l6ZSA9IDE7CgoJCWRhdGEtPmNhbGxjaGFpbiA9IHBlcmZfY2FsbGNoYWluKHJlZ3MpOwoKCQlpZiAoZGF0YS0+Y2FsbGNoYWluKQoJCQlzaXplICs9IGRhdGEtPmNhbGxjaGFpbi0+bnI7CgoJCWhlYWRlci0+c2l6ZSArPSBzaXplICogc2l6ZW9mKHU2NCk7Cgl9CgoJaWYgKHNhbXBsZV90eXBlICYgUEVSRl9TQU1QTEVfUkFXKSB7CgkJaW50IHNpemUgPSBzaXplb2YodTMyKTsKCgkJaWYgKGRhdGEtPnJhdykKCQkJc2l6ZSArPSBkYXRhLT5yYXctPnNpemU7CgkJZWxzZQoJCQlzaXplICs9IHNpemVvZih1MzIpOwoKCQlXQVJOX09OX09OQ0Uoc2l6ZSAmIChzaXplb2YodTY0KS0xKSk7CgkJaGVhZGVyLT5zaXplICs9IHNpemU7Cgl9Cn0KCnN0YXRpYyB2b2lkIHBlcmZfZXZlbnRfb3V0cHV0KHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCwgaW50IG5taSwKCQkJCXN0cnVjdCBwZXJmX3NhbXBsZV9kYXRhICpkYXRhLAoJCQkJc3RydWN0IHB0X3JlZ3MgKnJlZ3MpCnsKCXN0cnVjdCBwZXJmX291dHB1dF9oYW5kbGUgaGFuZGxlOwoJc3RydWN0IHBlcmZfZXZlbnRfaGVhZGVyIGhlYWRlcjsKCgkvKiBwcm90ZWN0IHRoZSBjYWxsY2hhaW4gYnVmZmVycyAqLwoJcmN1X3JlYWRfbG9jaygpOwoKCXBlcmZfcHJlcGFyZV9zYW1wbGUoJmhlYWRlciwgZGF0YSwgZXZlbnQsIHJlZ3MpOwoKCWlmIChwZXJmX291dHB1dF9iZWdpbigmaGFuZGxlLCBldmVudCwgaGVhZGVyLnNpemUsIG5taSwgMSkpCgkJZ290byBleGl0OwoKCXBlcmZfb3V0cHV0X3NhbXBsZSgmaGFuZGxlLCAmaGVhZGVyLCBkYXRhLCBldmVudCk7CgoJcGVyZl9vdXRwdXRfZW5kKCZoYW5kbGUpOwoKZXhpdDoKCXJjdV9yZWFkX3VubG9jaygpOwp9CgovKgogKiByZWFkIGV2ZW50X2lkCiAqLwoKc3RydWN0IHBlcmZfcmVhZF9ldmVudCB7CglzdHJ1Y3QgcGVyZl9ldmVudF9oZWFkZXIJaGVhZGVyOwoKCXUzMgkJCQlwaWQ7Cgl1MzIJCQkJdGlkOwp9OwoKc3RhdGljIHZvaWQKcGVyZl9ldmVudF9yZWFkX2V2ZW50KHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCwKCQkJc3RydWN0IHRhc2tfc3RydWN0ICp0YXNrKQp7CglzdHJ1Y3QgcGVyZl9vdXRwdXRfaGFuZGxlIGhhbmRsZTsKCXN0cnVjdCBwZXJmX3NhbXBsZV9kYXRhIHNhbXBsZTsKCXN0cnVjdCBwZXJmX3JlYWRfZXZlbnQgcmVhZF9ldmVudCA9IHsKCQkuaGVhZGVyID0gewoJCQkudHlwZSA9IFBFUkZfUkVDT1JEX1JFQUQsCgkJCS5taXNjID0gMCwKCQkJLnNpemUgPSBzaXplb2YocmVhZF9ldmVudCkgKyBldmVudC0+cmVhZF9zaXplLAoJCX0sCgkJLnBpZCA9IHBlcmZfZXZlbnRfcGlkKGV2ZW50LCB0YXNrKSwKCQkudGlkID0gcGVyZl9ldmVudF90aWQoZXZlbnQsIHRhc2spLAoJfTsKCWludCByZXQ7CgoJcGVyZl9ldmVudF9oZWFkZXJfX2luaXRfaWQoJnJlYWRfZXZlbnQuaGVhZGVyLCAmc2FtcGxlLCBldmVudCk7CglyZXQgPSBwZXJmX291dHB1dF9iZWdpbigmaGFuZGxlLCBldmVudCwgcmVhZF9ldmVudC5oZWFkZXIuc2l6ZSwgMCwgMCk7CglpZiAocmV0KQoJCXJldHVybjsKCglwZXJmX291dHB1dF9wdXQoJmhhbmRsZSwgcmVhZF9ldmVudCk7CglwZXJmX291dHB1dF9yZWFkKCZoYW5kbGUsIGV2ZW50KTsKCXBlcmZfZXZlbnRfX291dHB1dF9pZF9zYW1wbGUoZXZlbnQsICZoYW5kbGUsICZzYW1wbGUpOwoKCXBlcmZfb3V0cHV0X2VuZCgmaGFuZGxlKTsKfQoKLyoKICogdGFzayB0cmFja2luZyAtLSBmb3JrL2V4aXQKICoKICogZW5hYmxlZCBieTogYXR0ci5jb21tIHwgYXR0ci5tbWFwIHwgYXR0ci5tbWFwX2RhdGEgfCBhdHRyLnRhc2sKICovCgpzdHJ1Y3QgcGVyZl90YXNrX2V2ZW50IHsKCXN0cnVjdCB0YXNrX3N0cnVjdAkJKnRhc2s7CglzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0CSp0YXNrX2N0eDsKCglzdHJ1Y3QgewoJCXN0cnVjdCBwZXJmX2V2ZW50X2hlYWRlcgloZWFkZXI7CgoJCXUzMgkJCQlwaWQ7CgkJdTMyCQkJCXBwaWQ7CgkJdTMyCQkJCXRpZDsKCQl1MzIJCQkJcHRpZDsKCQl1NjQJCQkJdGltZTsKCX0gZXZlbnRfaWQ7Cn07CgpzdGF0aWMgdm9pZCBwZXJmX2V2ZW50X3Rhc2tfb3V0cHV0KHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCwKCQkJCSAgICAgc3RydWN0IHBlcmZfdGFza19ldmVudCAqdGFza19ldmVudCkKewoJc3RydWN0IHBlcmZfb3V0cHV0X2hhbmRsZSBoYW5kbGU7CglzdHJ1Y3QgcGVyZl9zYW1wbGVfZGF0YQlzYW1wbGU7CglzdHJ1Y3QgdGFza19zdHJ1Y3QgKnRhc2sgPSB0YXNrX2V2ZW50LT50YXNrOwoJaW50IHJldCwgc2l6ZSA9IHRhc2tfZXZlbnQtPmV2ZW50X2lkLmhlYWRlci5zaXplOwoKCXBlcmZfZXZlbnRfaGVhZGVyX19pbml0X2lkKCZ0YXNrX2V2ZW50LT5ldmVudF9pZC5oZWFkZXIsICZzYW1wbGUsIGV2ZW50KTsKCglyZXQgPSBwZXJmX291dHB1dF9iZWdpbigmaGFuZGxlLCBldmVudCwKCQkJCXRhc2tfZXZlbnQtPmV2ZW50X2lkLmhlYWRlci5zaXplLCAwLCAwKTsKCWlmIChyZXQpCgkJZ290byBvdXQ7CgoJdGFza19ldmVudC0+ZXZlbnRfaWQucGlkID0gcGVyZl9ldmVudF9waWQoZXZlbnQsIHRhc2spOwoJdGFza19ldmVudC0+ZXZlbnRfaWQucHBpZCA9IHBlcmZfZXZlbnRfcGlkKGV2ZW50LCBjdXJyZW50KTsKCgl0YXNrX2V2ZW50LT5ldmVudF9pZC50aWQgPSBwZXJmX2V2ZW50X3RpZChldmVudCwgdGFzayk7Cgl0YXNrX2V2ZW50LT5ldmVudF9pZC5wdGlkID0gcGVyZl9ldmVudF90aWQoZXZlbnQsIGN1cnJlbnQpOwoKCXBlcmZfb3V0cHV0X3B1dCgmaGFuZGxlLCB0YXNrX2V2ZW50LT5ldmVudF9pZCk7CgoJcGVyZl9ldmVudF9fb3V0cHV0X2lkX3NhbXBsZShldmVudCwgJmhhbmRsZSwgJnNhbXBsZSk7CgoJcGVyZl9vdXRwdXRfZW5kKCZoYW5kbGUpOwpvdXQ6Cgl0YXNrX2V2ZW50LT5ldmVudF9pZC5oZWFkZXIuc2l6ZSA9IHNpemU7Cn0KCnN0YXRpYyBpbnQgcGVyZl9ldmVudF90YXNrX21hdGNoKHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCkKewoJaWYgKGV2ZW50LT5zdGF0ZSA8IFBFUkZfRVZFTlRfU1RBVEVfSU5BQ1RJVkUpCgkJcmV0dXJuIDA7CgoJaWYgKCFldmVudF9maWx0ZXJfbWF0Y2goZXZlbnQpKQoJCXJldHVybiAwOwoKCWlmIChldmVudC0+YXR0ci5jb21tIHx8IGV2ZW50LT5hdHRyLm1tYXAgfHwKCSAgICBldmVudC0+YXR0ci5tbWFwX2RhdGEgfHwgZXZlbnQtPmF0dHIudGFzaykKCQlyZXR1cm4gMTsKCglyZXR1cm4gMDsKfQoKc3RhdGljIHZvaWQgcGVyZl9ldmVudF90YXNrX2N0eChzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0ICpjdHgsCgkJCQkgIHN0cnVjdCBwZXJmX3Rhc2tfZXZlbnQgKnRhc2tfZXZlbnQpCnsKCXN0cnVjdCBwZXJmX2V2ZW50ICpldmVudDsKCglsaXN0X2Zvcl9lYWNoX2VudHJ5X3JjdShldmVudCwgJmN0eC0+ZXZlbnRfbGlzdCwgZXZlbnRfZW50cnkpIHsKCQlpZiAocGVyZl9ldmVudF90YXNrX21hdGNoKGV2ZW50KSkKCQkJcGVyZl9ldmVudF90YXNrX291dHB1dChldmVudCwgdGFza19ldmVudCk7Cgl9Cn0KCnN0YXRpYyB2b2lkIHBlcmZfZXZlbnRfdGFza19ldmVudChzdHJ1Y3QgcGVyZl90YXNrX2V2ZW50ICp0YXNrX2V2ZW50KQp7CglzdHJ1Y3QgcGVyZl9jcHVfY29udGV4dCAqY3B1Y3R4OwoJc3RydWN0IHBlcmZfZXZlbnRfY29udGV4dCAqY3R4OwoJc3RydWN0IHBtdSAqcG11OwoJaW50IGN0eG47CgoJcmN1X3JlYWRfbG9jaygpOwoJbGlzdF9mb3JfZWFjaF9lbnRyeV9yY3UocG11LCAmcG11cywgZW50cnkpIHsKCQljcHVjdHggPSBnZXRfY3B1X3B0cihwbXUtPnBtdV9jcHVfY29udGV4dCk7CgkJaWYgKGNwdWN0eC0+YWN0aXZlX3BtdSAhPSBwbXUpCgkJCWdvdG8gbmV4dDsKCQlwZXJmX2V2ZW50X3Rhc2tfY3R4KCZjcHVjdHgtPmN0eCwgdGFza19ldmVudCk7CgoJCWN0eCA9IHRhc2tfZXZlbnQtPnRhc2tfY3R4OwoJCWlmICghY3R4KSB7CgkJCWN0eG4gPSBwbXUtPnRhc2tfY3R4X25yOwoJCQlpZiAoY3R4biA8IDApCgkJCQlnb3RvIG5leHQ7CgkJCWN0eCA9IHJjdV9kZXJlZmVyZW5jZShjdXJyZW50LT5wZXJmX2V2ZW50X2N0eHBbY3R4bl0pOwoJCX0KCQlpZiAoY3R4KQoJCQlwZXJmX2V2ZW50X3Rhc2tfY3R4KGN0eCwgdGFza19ldmVudCk7Cm5leHQ6CgkJcHV0X2NwdV9wdHIocG11LT5wbXVfY3B1X2NvbnRleHQpOwoJfQoJcmN1X3JlYWRfdW5sb2NrKCk7Cn0KCnN0YXRpYyB2b2lkIHBlcmZfZXZlbnRfdGFzayhzdHJ1Y3QgdGFza19zdHJ1Y3QgKnRhc2ssCgkJCSAgICAgIHN0cnVjdCBwZXJmX2V2ZW50X2NvbnRleHQgKnRhc2tfY3R4LAoJCQkgICAgICBpbnQgbmV3KQp7CglzdHJ1Y3QgcGVyZl90YXNrX2V2ZW50IHRhc2tfZXZlbnQ7CgoJaWYgKCFhdG9taWNfcmVhZCgmbnJfY29tbV9ldmVudHMpICYmCgkgICAgIWF0b21pY19yZWFkKCZucl9tbWFwX2V2ZW50cykgJiYKCSAgICAhYXRvbWljX3JlYWQoJm5yX3Rhc2tfZXZlbnRzKSkKCQlyZXR1cm47CgoJdGFza19ldmVudCA9IChzdHJ1Y3QgcGVyZl90YXNrX2V2ZW50KXsKCQkudGFzawkgID0gdGFzaywKCQkudGFza19jdHggPSB0YXNrX2N0eCwKCQkuZXZlbnRfaWQgICAgPSB7CgkJCS5oZWFkZXIgPSB7CgkJCQkudHlwZSA9IG5ldyA/IFBFUkZfUkVDT1JEX0ZPUksgOiBQRVJGX1JFQ09SRF9FWElULAoJCQkJLm1pc2MgPSAwLAoJCQkJLnNpemUgPSBzaXplb2YodGFza19ldmVudC5ldmVudF9pZCksCgkJCX0sCgkJCS8qIC5waWQgICovCgkJCS8qIC5wcGlkICovCgkJCS8qIC50aWQgICovCgkJCS8qIC5wdGlkICovCgkJCS50aW1lID0gcGVyZl9jbG9jaygpLAoJCX0sCgl9OwoKCXBlcmZfZXZlbnRfdGFza19ldmVudCgmdGFza19ldmVudCk7Cn0KCnZvaWQgcGVyZl9ldmVudF9mb3JrKHN0cnVjdCB0YXNrX3N0cnVjdCAqdGFzaykKewoJcGVyZl9ldmVudF90YXNrKHRhc2ssIE5VTEwsIDEpOwp9CgovKgogKiBjb21tIHRyYWNraW5nCiAqLwoKc3RydWN0IHBlcmZfY29tbV9ldmVudCB7CglzdHJ1Y3QgdGFza19zdHJ1Y3QJKnRhc2s7CgljaGFyCQkJKmNvbW07CglpbnQJCQljb21tX3NpemU7CgoJc3RydWN0IHsKCQlzdHJ1Y3QgcGVyZl9ldmVudF9oZWFkZXIJaGVhZGVyOwoKCQl1MzIJCQkJcGlkOwoJCXUzMgkJCQl0aWQ7Cgl9IGV2ZW50X2lkOwp9OwoKc3RhdGljIHZvaWQgcGVyZl9ldmVudF9jb21tX291dHB1dChzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQsCgkJCQkgICAgIHN0cnVjdCBwZXJmX2NvbW1fZXZlbnQgKmNvbW1fZXZlbnQpCnsKCXN0cnVjdCBwZXJmX291dHB1dF9oYW5kbGUgaGFuZGxlOwoJc3RydWN0IHBlcmZfc2FtcGxlX2RhdGEgc2FtcGxlOwoJaW50IHNpemUgPSBjb21tX2V2ZW50LT5ldmVudF9pZC5oZWFkZXIuc2l6ZTsKCWludCByZXQ7CgoJcGVyZl9ldmVudF9oZWFkZXJfX2luaXRfaWQoJmNvbW1fZXZlbnQtPmV2ZW50X2lkLmhlYWRlciwgJnNhbXBsZSwgZXZlbnQpOwoJcmV0ID0gcGVyZl9vdXRwdXRfYmVnaW4oJmhhbmRsZSwgZXZlbnQsCgkJCQljb21tX2V2ZW50LT5ldmVudF9pZC5oZWFkZXIuc2l6ZSwgMCwgMCk7CgoJaWYgKHJldCkKCQlnb3RvIG91dDsKCgljb21tX2V2ZW50LT5ldmVudF9pZC5waWQgPSBwZXJmX2V2ZW50X3BpZChldmVudCwgY29tbV9ldmVudC0+dGFzayk7Cgljb21tX2V2ZW50LT5ldmVudF9pZC50aWQgPSBwZXJmX2V2ZW50X3RpZChldmVudCwgY29tbV9ldmVudC0+dGFzayk7CgoJcGVyZl9vdXRwdXRfcHV0KCZoYW5kbGUsIGNvbW1fZXZlbnQtPmV2ZW50X2lkKTsKCXBlcmZfb3V0cHV0X2NvcHkoJmhhbmRsZSwgY29tbV9ldmVudC0+Y29tbSwKCQkJCSAgIGNvbW1fZXZlbnQtPmNvbW1fc2l6ZSk7CgoJcGVyZl9ldmVudF9fb3V0cHV0X2lkX3NhbXBsZShldmVudCwgJmhhbmRsZSwgJnNhbXBsZSk7CgoJcGVyZl9vdXRwdXRfZW5kKCZoYW5kbGUpOwpvdXQ6Cgljb21tX2V2ZW50LT5ldmVudF9pZC5oZWFkZXIuc2l6ZSA9IHNpemU7Cn0KCnN0YXRpYyBpbnQgcGVyZl9ldmVudF9jb21tX21hdGNoKHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCkKewoJaWYgKGV2ZW50LT5zdGF0ZSA8IFBFUkZfRVZFTlRfU1RBVEVfSU5BQ1RJVkUpCgkJcmV0dXJuIDA7CgoJaWYgKCFldmVudF9maWx0ZXJfbWF0Y2goZXZlbnQpKQoJCXJldHVybiAwOwoKCWlmIChldmVudC0+YXR0ci5jb21tKQoJCXJldHVybiAxOwoKCXJldHVybiAwOwp9CgpzdGF0aWMgdm9pZCBwZXJmX2V2ZW50X2NvbW1fY3R4KHN0cnVjdCBwZXJmX2V2ZW50X2NvbnRleHQgKmN0eCwKCQkJCSAgc3RydWN0IHBlcmZfY29tbV9ldmVudCAqY29tbV9ldmVudCkKewoJc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50OwoKCWxpc3RfZm9yX2VhY2hfZW50cnlfcmN1KGV2ZW50LCAmY3R4LT5ldmVudF9saXN0LCBldmVudF9lbnRyeSkgewoJCWlmIChwZXJmX2V2ZW50X2NvbW1fbWF0Y2goZXZlbnQpKQoJCQlwZXJmX2V2ZW50X2NvbW1fb3V0cHV0KGV2ZW50LCBjb21tX2V2ZW50KTsKCX0KfQoKc3RhdGljIHZvaWQgcGVyZl9ldmVudF9jb21tX2V2ZW50KHN0cnVjdCBwZXJmX2NvbW1fZXZlbnQgKmNvbW1fZXZlbnQpCnsKCXN0cnVjdCBwZXJmX2NwdV9jb250ZXh0ICpjcHVjdHg7CglzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0ICpjdHg7CgljaGFyIGNvbW1bVEFTS19DT01NX0xFTl07Cgl1bnNpZ25lZCBpbnQgc2l6ZTsKCXN0cnVjdCBwbXUgKnBtdTsKCWludCBjdHhuOwoKCW1lbXNldChjb21tLCAwLCBzaXplb2YoY29tbSkpOwoJc3RybGNweShjb21tLCBjb21tX2V2ZW50LT50YXNrLT5jb21tLCBzaXplb2YoY29tbSkpOwoJc2l6ZSA9IEFMSUdOKHN0cmxlbihjb21tKSsxLCBzaXplb2YodTY0KSk7CgoJY29tbV9ldmVudC0+Y29tbSA9IGNvbW07Cgljb21tX2V2ZW50LT5jb21tX3NpemUgPSBzaXplOwoKCWNvbW1fZXZlbnQtPmV2ZW50X2lkLmhlYWRlci5zaXplID0gc2l6ZW9mKGNvbW1fZXZlbnQtPmV2ZW50X2lkKSArIHNpemU7CglyY3VfcmVhZF9sb2NrKCk7CglsaXN0X2Zvcl9lYWNoX2VudHJ5X3JjdShwbXUsICZwbXVzLCBlbnRyeSkgewoJCWNwdWN0eCA9IGdldF9jcHVfcHRyKHBtdS0+cG11X2NwdV9jb250ZXh0KTsKCQlpZiAoY3B1Y3R4LT5hY3RpdmVfcG11ICE9IHBtdSkKCQkJZ290byBuZXh0OwoJCXBlcmZfZXZlbnRfY29tbV9jdHgoJmNwdWN0eC0+Y3R4LCBjb21tX2V2ZW50KTsKCgkJY3R4biA9IHBtdS0+dGFza19jdHhfbnI7CgkJaWYgKGN0eG4gPCAwKQoJCQlnb3RvIG5leHQ7CgoJCWN0eCA9IHJjdV9kZXJlZmVyZW5jZShjdXJyZW50LT5wZXJmX2V2ZW50X2N0eHBbY3R4bl0pOwoJCWlmIChjdHgpCgkJCXBlcmZfZXZlbnRfY29tbV9jdHgoY3R4LCBjb21tX2V2ZW50KTsKbmV4dDoKCQlwdXRfY3B1X3B0cihwbXUtPnBtdV9jcHVfY29udGV4dCk7Cgl9CglyY3VfcmVhZF91bmxvY2soKTsKfQoKdm9pZCBwZXJmX2V2ZW50X2NvbW0oc3RydWN0IHRhc2tfc3RydWN0ICp0YXNrKQp7CglzdHJ1Y3QgcGVyZl9jb21tX2V2ZW50IGNvbW1fZXZlbnQ7CglzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0ICpjdHg7CglpbnQgY3R4bjsKCglmb3JfZWFjaF90YXNrX2NvbnRleHRfbnIoY3R4bikgewoJCWN0eCA9IHRhc2stPnBlcmZfZXZlbnRfY3R4cFtjdHhuXTsKCQlpZiAoIWN0eCkKCQkJY29udGludWU7CgoJCXBlcmZfZXZlbnRfZW5hYmxlX29uX2V4ZWMoY3R4KTsKCX0KCglpZiAoIWF0b21pY19yZWFkKCZucl9jb21tX2V2ZW50cykpCgkJcmV0dXJuOwoKCWNvbW1fZXZlbnQgPSAoc3RydWN0IHBlcmZfY29tbV9ldmVudCl7CgkJLnRhc2sJPSB0YXNrLAoJCS8qIC5jb21tICAgICAgKi8KCQkvKiAuY29tbV9zaXplICovCgkJLmV2ZW50X2lkICA9IHsKCQkJLmhlYWRlciA9IHsKCQkJCS50eXBlID0gUEVSRl9SRUNPUkRfQ09NTSwKCQkJCS5taXNjID0gMCwKCQkJCS8qIC5zaXplICovCgkJCX0sCgkJCS8qIC5waWQgKi8KCQkJLyogLnRpZCAqLwoJCX0sCgl9OwoKCXBlcmZfZXZlbnRfY29tbV9ldmVudCgmY29tbV9ldmVudCk7Cn0KCi8qCiAqIG1tYXAgdHJhY2tpbmcKICovCgpzdHJ1Y3QgcGVyZl9tbWFwX2V2ZW50IHsKCXN0cnVjdCB2bV9hcmVhX3N0cnVjdAkqdm1hOwoKCWNvbnN0IGNoYXIJCSpmaWxlX25hbWU7CglpbnQJCQlmaWxlX3NpemU7CgoJc3RydWN0IHsKCQlzdHJ1Y3QgcGVyZl9ldmVudF9oZWFkZXIJaGVhZGVyOwoKCQl1MzIJCQkJcGlkOwoJCXUzMgkJCQl0aWQ7CgkJdTY0CQkJCXN0YXJ0OwoJCXU2NAkJCQlsZW47CgkJdTY0CQkJCXBnb2ZmOwoJfSBldmVudF9pZDsKfTsKCnN0YXRpYyB2b2lkIHBlcmZfZXZlbnRfbW1hcF9vdXRwdXQoc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50LAoJCQkJICAgICBzdHJ1Y3QgcGVyZl9tbWFwX2V2ZW50ICptbWFwX2V2ZW50KQp7CglzdHJ1Y3QgcGVyZl9vdXRwdXRfaGFuZGxlIGhhbmRsZTsKCXN0cnVjdCBwZXJmX3NhbXBsZV9kYXRhIHNhbXBsZTsKCWludCBzaXplID0gbW1hcF9ldmVudC0+ZXZlbnRfaWQuaGVhZGVyLnNpemU7CglpbnQgcmV0OwoKCXBlcmZfZXZlbnRfaGVhZGVyX19pbml0X2lkKCZtbWFwX2V2ZW50LT5ldmVudF9pZC5oZWFkZXIsICZzYW1wbGUsIGV2ZW50KTsKCXJldCA9IHBlcmZfb3V0cHV0X2JlZ2luKCZoYW5kbGUsIGV2ZW50LAoJCQkJbW1hcF9ldmVudC0+ZXZlbnRfaWQuaGVhZGVyLnNpemUsIDAsIDApOwoJaWYgKHJldCkKCQlnb3RvIG91dDsKCgltbWFwX2V2ZW50LT5ldmVudF9pZC5waWQgPSBwZXJmX2V2ZW50X3BpZChldmVudCwgY3VycmVudCk7CgltbWFwX2V2ZW50LT5ldmVudF9pZC50aWQgPSBwZXJmX2V2ZW50X3RpZChldmVudCwgY3VycmVudCk7CgoJcGVyZl9vdXRwdXRfcHV0KCZoYW5kbGUsIG1tYXBfZXZlbnQtPmV2ZW50X2lkKTsKCXBlcmZfb3V0cHV0X2NvcHkoJmhhbmRsZSwgbW1hcF9ldmVudC0+ZmlsZV9uYW1lLAoJCQkJICAgbW1hcF9ldmVudC0+ZmlsZV9zaXplKTsKCglwZXJmX2V2ZW50X19vdXRwdXRfaWRfc2FtcGxlKGV2ZW50LCAmaGFuZGxlLCAmc2FtcGxlKTsKCglwZXJmX291dHB1dF9lbmQoJmhhbmRsZSk7Cm91dDoKCW1tYXBfZXZlbnQtPmV2ZW50X2lkLmhlYWRlci5zaXplID0gc2l6ZTsKfQoKc3RhdGljIGludCBwZXJmX2V2ZW50X21tYXBfbWF0Y2goc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50LAoJCQkJICAgc3RydWN0IHBlcmZfbW1hcF9ldmVudCAqbW1hcF9ldmVudCwKCQkJCSAgIGludCBleGVjdXRhYmxlKQp7CglpZiAoZXZlbnQtPnN0YXRlIDwgUEVSRl9FVkVOVF9TVEFURV9JTkFDVElWRSkKCQlyZXR1cm4gMDsKCglpZiAoIWV2ZW50X2ZpbHRlcl9tYXRjaChldmVudCkpCgkJcmV0dXJuIDA7CgoJaWYgKCghZXhlY3V0YWJsZSAmJiBldmVudC0+YXR0ci5tbWFwX2RhdGEpIHx8CgkgICAgKGV4ZWN1dGFibGUgJiYgZXZlbnQtPmF0dHIubW1hcCkpCgkJcmV0dXJuIDE7CgoJcmV0dXJuIDA7Cn0KCnN0YXRpYyB2b2lkIHBlcmZfZXZlbnRfbW1hcF9jdHgoc3RydWN0IHBlcmZfZXZlbnRfY29udGV4dCAqY3R4LAoJCQkJICBzdHJ1Y3QgcGVyZl9tbWFwX2V2ZW50ICptbWFwX2V2ZW50LAoJCQkJICBpbnQgZXhlY3V0YWJsZSkKewoJc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50OwoKCWxpc3RfZm9yX2VhY2hfZW50cnlfcmN1KGV2ZW50LCAmY3R4LT5ldmVudF9saXN0LCBldmVudF9lbnRyeSkgewoJCWlmIChwZXJmX2V2ZW50X21tYXBfbWF0Y2goZXZlbnQsIG1tYXBfZXZlbnQsIGV4ZWN1dGFibGUpKQoJCQlwZXJmX2V2ZW50X21tYXBfb3V0cHV0KGV2ZW50LCBtbWFwX2V2ZW50KTsKCX0KfQoKc3RhdGljIHZvaWQgcGVyZl9ldmVudF9tbWFwX2V2ZW50KHN0cnVjdCBwZXJmX21tYXBfZXZlbnQgKm1tYXBfZXZlbnQpCnsKCXN0cnVjdCBwZXJmX2NwdV9jb250ZXh0ICpjcHVjdHg7CglzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0ICpjdHg7CglzdHJ1Y3Qgdm1fYXJlYV9zdHJ1Y3QgKnZtYSA9IG1tYXBfZXZlbnQtPnZtYTsKCXN0cnVjdCBmaWxlICpmaWxlID0gdm1hLT52bV9maWxlOwoJdW5zaWduZWQgaW50IHNpemU7CgljaGFyIHRtcFsxNl07CgljaGFyICpidWYgPSBOVUxMOwoJY29uc3QgY2hhciAqbmFtZTsKCXN0cnVjdCBwbXUgKnBtdTsKCWludCBjdHhuOwoKCW1lbXNldCh0bXAsIDAsIHNpemVvZih0bXApKTsKCglpZiAoZmlsZSkgewoJCS8qCgkJICogZF9wYXRoIHdvcmtzIGZyb20gdGhlIGVuZCBvZiB0aGUgYnVmZmVyIGJhY2t3YXJkcywgc28gd2UKCQkgKiBuZWVkIHRvIGFkZCBlbm91Z2ggemVybyBieXRlcyBhZnRlciB0aGUgc3RyaW5nIHRvIGhhbmRsZQoJCSAqIHRoZSA2NGJpdCBhbGlnbm1lbnQgd2UgZG8gbGF0ZXIuCgkJICovCgkJYnVmID0ga3phbGxvYyhQQVRIX01BWCArIHNpemVvZih1NjQpLCBHRlBfS0VSTkVMKTsKCQlpZiAoIWJ1ZikgewoJCQluYW1lID0gc3RybmNweSh0bXAsICIvL2Vub21lbSIsIHNpemVvZih0bXApKTsKCQkJZ290byBnb3RfbmFtZTsKCQl9CgkJbmFtZSA9IGRfcGF0aCgmZmlsZS0+Zl9wYXRoLCBidWYsIFBBVEhfTUFYKTsKCQlpZiAoSVNfRVJSKG5hbWUpKSB7CgkJCW5hbWUgPSBzdHJuY3B5KHRtcCwgIi8vdG9vbG9uZyIsIHNpemVvZih0bXApKTsKCQkJZ290byBnb3RfbmFtZTsKCQl9Cgl9IGVsc2UgewoJCWlmIChhcmNoX3ZtYV9uYW1lKG1tYXBfZXZlbnQtPnZtYSkpIHsKCQkJbmFtZSA9IHN0cm5jcHkodG1wLCBhcmNoX3ZtYV9uYW1lKG1tYXBfZXZlbnQtPnZtYSksCgkJCQkgICAgICAgc2l6ZW9mKHRtcCkpOwoJCQlnb3RvIGdvdF9uYW1lOwoJCX0KCgkJaWYgKCF2bWEtPnZtX21tKSB7CgkJCW5hbWUgPSBzdHJuY3B5KHRtcCwgIlt2ZHNvXSIsIHNpemVvZih0bXApKTsKCQkJZ290byBnb3RfbmFtZTsKCQl9IGVsc2UgaWYgKHZtYS0+dm1fc3RhcnQgPD0gdm1hLT52bV9tbS0+c3RhcnRfYnJrICYmCgkJCQl2bWEtPnZtX2VuZCA+PSB2bWEtPnZtX21tLT5icmspIHsKCQkJbmFtZSA9IHN0cm5jcHkodG1wLCAiW2hlYXBdIiwgc2l6ZW9mKHRtcCkpOwoJCQlnb3RvIGdvdF9uYW1lOwoJCX0gZWxzZSBpZiAodm1hLT52bV9zdGFydCA8PSB2bWEtPnZtX21tLT5zdGFydF9zdGFjayAmJgoJCQkJdm1hLT52bV9lbmQgPj0gdm1hLT52bV9tbS0+c3RhcnRfc3RhY2spIHsKCQkJbmFtZSA9IHN0cm5jcHkodG1wLCAiW3N0YWNrXSIsIHNpemVvZih0bXApKTsKCQkJZ290byBnb3RfbmFtZTsKCQl9CgoJCW5hbWUgPSBzdHJuY3B5KHRtcCwgIi8vYW5vbiIsIHNpemVvZih0bXApKTsKCQlnb3RvIGdvdF9uYW1lOwoJfQoKZ290X25hbWU6CglzaXplID0gQUxJR04oc3RybGVuKG5hbWUpKzEsIHNpemVvZih1NjQpKTsKCgltbWFwX2V2ZW50LT5maWxlX25hbWUgPSBuYW1lOwoJbW1hcF9ldmVudC0+ZmlsZV9zaXplID0gc2l6ZTsKCgltbWFwX2V2ZW50LT5ldmVudF9pZC5oZWFkZXIuc2l6ZSA9IHNpemVvZihtbWFwX2V2ZW50LT5ldmVudF9pZCkgKyBzaXplOwoKCXJjdV9yZWFkX2xvY2soKTsKCWxpc3RfZm9yX2VhY2hfZW50cnlfcmN1KHBtdSwgJnBtdXMsIGVudHJ5KSB7CgkJY3B1Y3R4ID0gZ2V0X2NwdV9wdHIocG11LT5wbXVfY3B1X2NvbnRleHQpOwoJCWlmIChjcHVjdHgtPmFjdGl2ZV9wbXUgIT0gcG11KQoJCQlnb3RvIG5leHQ7CgkJcGVyZl9ldmVudF9tbWFwX2N0eCgmY3B1Y3R4LT5jdHgsIG1tYXBfZXZlbnQsCgkJCQkJdm1hLT52bV9mbGFncyAmIFZNX0VYRUMpOwoKCQljdHhuID0gcG11LT50YXNrX2N0eF9ucjsKCQlpZiAoY3R4biA8IDApCgkJCWdvdG8gbmV4dDsKCgkJY3R4ID0gcmN1X2RlcmVmZXJlbmNlKGN1cnJlbnQtPnBlcmZfZXZlbnRfY3R4cFtjdHhuXSk7CgkJaWYgKGN0eCkgewoJCQlwZXJmX2V2ZW50X21tYXBfY3R4KGN0eCwgbW1hcF9ldmVudCwKCQkJCQl2bWEtPnZtX2ZsYWdzICYgVk1fRVhFQyk7CgkJfQpuZXh0OgoJCXB1dF9jcHVfcHRyKHBtdS0+cG11X2NwdV9jb250ZXh0KTsKCX0KCXJjdV9yZWFkX3VubG9jaygpOwoKCWtmcmVlKGJ1Zik7Cn0KCnZvaWQgcGVyZl9ldmVudF9tbWFwKHN0cnVjdCB2bV9hcmVhX3N0cnVjdCAqdm1hKQp7CglzdHJ1Y3QgcGVyZl9tbWFwX2V2ZW50IG1tYXBfZXZlbnQ7CgoJaWYgKCFhdG9taWNfcmVhZCgmbnJfbW1hcF9ldmVudHMpKQoJCXJldHVybjsKCgltbWFwX2V2ZW50ID0gKHN0cnVjdCBwZXJmX21tYXBfZXZlbnQpewoJCS52bWEJPSB2bWEsCgkJLyogLmZpbGVfbmFtZSAqLwoJCS8qIC5maWxlX3NpemUgKi8KCQkuZXZlbnRfaWQgID0gewoJCQkuaGVhZGVyID0gewoJCQkJLnR5cGUgPSBQRVJGX1JFQ09SRF9NTUFQLAoJCQkJLm1pc2MgPSBQRVJGX1JFQ09SRF9NSVNDX1VTRVIsCgkJCQkvKiAuc2l6ZSAqLwoJCQl9LAoJCQkvKiAucGlkICovCgkJCS8qIC50aWQgKi8KCQkJLnN0YXJ0ICA9IHZtYS0+dm1fc3RhcnQsCgkJCS5sZW4gICAgPSB2bWEtPnZtX2VuZCAtIHZtYS0+dm1fc3RhcnQsCgkJCS5wZ29mZiAgPSAodTY0KXZtYS0+dm1fcGdvZmYgPDwgUEFHRV9TSElGVCwKCQl9LAoJfTsKCglwZXJmX2V2ZW50X21tYXBfZXZlbnQoJm1tYXBfZXZlbnQpOwp9CgovKgogKiBJUlEgdGhyb3R0bGUgbG9nZ2luZwogKi8KCnN0YXRpYyB2b2lkIHBlcmZfbG9nX3Rocm90dGxlKHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCwgaW50IGVuYWJsZSkKewoJc3RydWN0IHBlcmZfb3V0cHV0X2hhbmRsZSBoYW5kbGU7CglzdHJ1Y3QgcGVyZl9zYW1wbGVfZGF0YSBzYW1wbGU7CglpbnQgcmV0OwoKCXN0cnVjdCB7CgkJc3RydWN0IHBlcmZfZXZlbnRfaGVhZGVyCWhlYWRlcjsKCQl1NjQJCQkJdGltZTsKCQl1NjQJCQkJaWQ7CgkJdTY0CQkJCXN0cmVhbV9pZDsKCX0gdGhyb3R0bGVfZXZlbnQgPSB7CgkJLmhlYWRlciA9IHsKCQkJLnR5cGUgPSBQRVJGX1JFQ09SRF9USFJPVFRMRSwKCQkJLm1pc2MgPSAwLAoJCQkuc2l6ZSA9IHNpemVvZih0aHJvdHRsZV9ldmVudCksCgkJfSwKCQkudGltZQkJPSBwZXJmX2Nsb2NrKCksCgkJLmlkCQk9IHByaW1hcnlfZXZlbnRfaWQoZXZlbnQpLAoJCS5zdHJlYW1faWQJPSBldmVudC0+aWQsCgl9OwoKCWlmIChlbmFibGUpCgkJdGhyb3R0bGVfZXZlbnQuaGVhZGVyLnR5cGUgPSBQRVJGX1JFQ09SRF9VTlRIUk9UVExFOwoKCXBlcmZfZXZlbnRfaGVhZGVyX19pbml0X2lkKCZ0aHJvdHRsZV9ldmVudC5oZWFkZXIsICZzYW1wbGUsIGV2ZW50KTsKCglyZXQgPSBwZXJmX291dHB1dF9iZWdpbigmaGFuZGxlLCBldmVudCwKCQkJCXRocm90dGxlX2V2ZW50LmhlYWRlci5zaXplLCAxLCAwKTsKCWlmIChyZXQpCgkJcmV0dXJuOwoKCXBlcmZfb3V0cHV0X3B1dCgmaGFuZGxlLCB0aHJvdHRsZV9ldmVudCk7CglwZXJmX2V2ZW50X19vdXRwdXRfaWRfc2FtcGxlKGV2ZW50LCAmaGFuZGxlLCAmc2FtcGxlKTsKCXBlcmZfb3V0cHV0X2VuZCgmaGFuZGxlKTsKfQoKLyoKICogR2VuZXJpYyBldmVudCBvdmVyZmxvdyBoYW5kbGluZywgc2FtcGxpbmcuCiAqLwoKc3RhdGljIGludCBfX3BlcmZfZXZlbnRfb3ZlcmZsb3coc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50LCBpbnQgbm1pLAoJCQkJICAgaW50IHRocm90dGxlLCBzdHJ1Y3QgcGVyZl9zYW1wbGVfZGF0YSAqZGF0YSwKCQkJCSAgIHN0cnVjdCBwdF9yZWdzICpyZWdzKQp7CglpbnQgZXZlbnRzID0gYXRvbWljX3JlYWQoJmV2ZW50LT5ldmVudF9saW1pdCk7CglzdHJ1Y3QgaHdfcGVyZl9ldmVudCAqaHdjID0gJmV2ZW50LT5odzsKCWludCByZXQgPSAwOwoKCS8qCgkgKiBOb24tc2FtcGxpbmcgY291bnRlcnMgbWlnaHQgc3RpbGwgdXNlIHRoZSBQTUkgdG8gZm9sZCBzaG9ydAoJICogaGFyZHdhcmUgY291bnRlcnMsIGlnbm9yZSB0aG9zZS4KCSAqLwoJaWYgKHVubGlrZWx5KCFpc19zYW1wbGluZ19ldmVudChldmVudCkpKQoJCXJldHVybiAwOwoKCWlmICghdGhyb3R0bGUpIHsKCQlod2MtPmludGVycnVwdHMrKzsKCX0gZWxzZSB7CgkJaWYgKGh3Yy0+aW50ZXJydXB0cyAhPSBNQVhfSU5URVJSVVBUUykgewoJCQlod2MtPmludGVycnVwdHMrKzsKCQkJaWYgKEhaICogaHdjLT5pbnRlcnJ1cHRzID4KCQkJCQkodTY0KXN5c2N0bF9wZXJmX2V2ZW50X3NhbXBsZV9yYXRlKSB7CgkJCQlod2MtPmludGVycnVwdHMgPSBNQVhfSU5URVJSVVBUUzsKCQkJCXBlcmZfbG9nX3Rocm90dGxlKGV2ZW50LCAwKTsKCQkJCXJldCA9IDE7CgkJCX0KCQl9IGVsc2UgewoJCQkvKgoJCQkgKiBLZWVwIHJlLWRpc2FibGluZyBldmVudHMgZXZlbiB0aG91Z2ggb24gdGhlIHByZXZpb3VzCgkJCSAqIHBhc3Mgd2UgZGlzYWJsZWQgaXQgLSBqdXN0IGluIGNhc2Ugd2UgcmFjZWQgd2l0aCBhCgkJCSAqIHNjaGVkLWluIGFuZCB0aGUgZXZlbnQgZ290IGVuYWJsZWQgYWdhaW46CgkJCSAqLwoJCQlyZXQgPSAxOwoJCX0KCX0KCglpZiAoZXZlbnQtPmF0dHIuZnJlcSkgewoJCXU2NCBub3cgPSBwZXJmX2Nsb2NrKCk7CgkJczY0IGRlbHRhID0gbm93IC0gaHdjLT5mcmVxX3RpbWVfc3RhbXA7CgoJCWh3Yy0+ZnJlcV90aW1lX3N0YW1wID0gbm93OwoKCQlpZiAoZGVsdGEgPiAwICYmIGRlbHRhIDwgMipUSUNLX05TRUMpCgkJCXBlcmZfYWRqdXN0X3BlcmlvZChldmVudCwgZGVsdGEsIGh3Yy0+bGFzdF9wZXJpb2QpOwoJfQoKCS8qCgkgKiBYWFggZXZlbnRfbGltaXQgbWlnaHQgbm90IHF1aXRlIHdvcmsgYXMgZXhwZWN0ZWQgb24gaW5oZXJpdGVkCgkgKiBldmVudHMKCSAqLwoKCWV2ZW50LT5wZW5kaW5nX2tpbGwgPSBQT0xMX0lOOwoJaWYgKGV2ZW50cyAmJiBhdG9taWNfZGVjX2FuZF90ZXN0KCZldmVudC0+ZXZlbnRfbGltaXQpKSB7CgkJcmV0ID0gMTsKCQlldmVudC0+cGVuZGluZ19raWxsID0gUE9MTF9IVVA7CgkJaWYgKG5taSkgewoJCQlldmVudC0+cGVuZGluZ19kaXNhYmxlID0gMTsKCQkJaXJxX3dvcmtfcXVldWUoJmV2ZW50LT5wZW5kaW5nKTsKCQl9IGVsc2UKCQkJcGVyZl9ldmVudF9kaXNhYmxlKGV2ZW50KTsKCX0KCglpZiAoZXZlbnQtPm92ZXJmbG93X2hhbmRsZXIpCgkJZXZlbnQtPm92ZXJmbG93X2hhbmRsZXIoZXZlbnQsIG5taSwgZGF0YSwgcmVncyk7CgllbHNlCgkJcGVyZl9ldmVudF9vdXRwdXQoZXZlbnQsIG5taSwgZGF0YSwgcmVncyk7CgoJcmV0dXJuIHJldDsKfQoKaW50IHBlcmZfZXZlbnRfb3ZlcmZsb3coc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50LCBpbnQgbm1pLAoJCQkgIHN0cnVjdCBwZXJmX3NhbXBsZV9kYXRhICpkYXRhLAoJCQkgIHN0cnVjdCBwdF9yZWdzICpyZWdzKQp7CglyZXR1cm4gX19wZXJmX2V2ZW50X292ZXJmbG93KGV2ZW50LCBubWksIDEsIGRhdGEsIHJlZ3MpOwp9CgovKgogKiBHZW5lcmljIHNvZnR3YXJlIGV2ZW50IGluZnJhc3RydWN0dXJlCiAqLwoKc3RydWN0IHN3ZXZlbnRfaHRhYmxlIHsKCXN0cnVjdCBzd2V2ZW50X2hsaXN0CQkqc3dldmVudF9obGlzdDsKCXN0cnVjdCBtdXRleAkJCWhsaXN0X211dGV4OwoJaW50CQkJCWhsaXN0X3JlZmNvdW50OwoKCS8qIFJlY3Vyc2lvbiBhdm9pZGFuY2UgaW4gZWFjaCBjb250ZXh0cyAqLwoJaW50CQkJCXJlY3Vyc2lvbltQRVJGX05SX0NPTlRFWFRTXTsKfTsKCnN0YXRpYyBERUZJTkVfUEVSX0NQVShzdHJ1Y3Qgc3dldmVudF9odGFibGUsIHN3ZXZlbnRfaHRhYmxlKTsKCi8qCiAqIFdlIGRpcmVjdGx5IGluY3JlbWVudCBldmVudC0+Y291bnQgYW5kIGtlZXAgYSBzZWNvbmQgdmFsdWUgaW4KICogZXZlbnQtPmh3LnBlcmlvZF9sZWZ0IHRvIGNvdW50IGludGVydmFscy4gVGhpcyBwZXJpb2QgZXZlbnQKICogaXMga2VwdCBpbiB0aGUgcmFuZ2UgWy1zYW1wbGVfcGVyaW9kLCAwXSBzbyB0aGF0IHdlIGNhbiB1c2UgdGhlCiAqIHNpZ24gYXMgdHJpZ2dlci4KICovCgpzdGF0aWMgdTY0IHBlcmZfc3dldmVudF9zZXRfcGVyaW9kKHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCkKewoJc3RydWN0IGh3X3BlcmZfZXZlbnQgKmh3YyA9ICZldmVudC0+aHc7Cgl1NjQgcGVyaW9kID0gaHdjLT5sYXN0X3BlcmlvZDsKCXU2NCBuciwgb2Zmc2V0OwoJczY0IG9sZCwgdmFsOwoKCWh3Yy0+bGFzdF9wZXJpb2QgPSBod2MtPnNhbXBsZV9wZXJpb2Q7CgphZ2FpbjoKCW9sZCA9IHZhbCA9IGxvY2FsNjRfcmVhZCgmaHdjLT5wZXJpb2RfbGVmdCk7CglpZiAodmFsIDwgMCkKCQlyZXR1cm4gMDsKCgluciA9IGRpdjY0X3U2NChwZXJpb2QgKyB2YWwsIHBlcmlvZCk7CglvZmZzZXQgPSBuciAqIHBlcmlvZDsKCXZhbCAtPSBvZmZzZXQ7CglpZiAobG9jYWw2NF9jbXB4Y2hnKCZod2MtPnBlcmlvZF9sZWZ0LCBvbGQsIHZhbCkgIT0gb2xkKQoJCWdvdG8gYWdhaW47CgoJcmV0dXJuIG5yOwp9CgpzdGF0aWMgdm9pZCBwZXJmX3N3ZXZlbnRfb3ZlcmZsb3coc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50LCB1NjQgb3ZlcmZsb3csCgkJCQkgICAgaW50IG5taSwgc3RydWN0IHBlcmZfc2FtcGxlX2RhdGEgKmRhdGEsCgkJCQkgICAgc3RydWN0IHB0X3JlZ3MgKnJlZ3MpCnsKCXN0cnVjdCBod19wZXJmX2V2ZW50ICpod2MgPSAmZXZlbnQtPmh3OwoJaW50IHRocm90dGxlID0gMDsKCglkYXRhLT5wZXJpb2QgPSBldmVudC0+aHcubGFzdF9wZXJpb2Q7CglpZiAoIW92ZXJmbG93KQoJCW92ZXJmbG93ID0gcGVyZl9zd2V2ZW50X3NldF9wZXJpb2QoZXZlbnQpOwoKCWlmIChod2MtPmludGVycnVwdHMgPT0gTUFYX0lOVEVSUlVQVFMpCgkJcmV0dXJuOwoKCWZvciAoOyBvdmVyZmxvdzsgb3ZlcmZsb3ctLSkgewoJCWlmIChfX3BlcmZfZXZlbnRfb3ZlcmZsb3coZXZlbnQsIG5taSwgdGhyb3R0bGUsCgkJCQkJICAgIGRhdGEsIHJlZ3MpKSB7CgkJCS8qCgkJCSAqIFdlIGluaGliaXQgdGhlIG92ZXJmbG93IGZyb20gaGFwcGVuaW5nIHdoZW4KCQkJICogaHdjLT5pbnRlcnJ1cHRzID09IE1BWF9JTlRFUlJVUFRTLgoJCQkgKi8KCQkJYnJlYWs7CgkJfQoJCXRocm90dGxlID0gMTsKCX0KfQoKc3RhdGljIHZvaWQgcGVyZl9zd2V2ZW50X2V2ZW50KHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCwgdTY0IG5yLAoJCQkgICAgICAgaW50IG5taSwgc3RydWN0IHBlcmZfc2FtcGxlX2RhdGEgKmRhdGEsCgkJCSAgICAgICBzdHJ1Y3QgcHRfcmVncyAqcmVncykKewoJc3RydWN0IGh3X3BlcmZfZXZlbnQgKmh3YyA9ICZldmVudC0+aHc7CgoJbG9jYWw2NF9hZGQobnIsICZldmVudC0+Y291bnQpOwoKCWlmICghcmVncykKCQlyZXR1cm47CgoJaWYgKCFpc19zYW1wbGluZ19ldmVudChldmVudCkpCgkJcmV0dXJuOwoKCWlmIChuciA9PSAxICYmIGh3Yy0+c2FtcGxlX3BlcmlvZCA9PSAxICYmICFldmVudC0+YXR0ci5mcmVxKQoJCXJldHVybiBwZXJmX3N3ZXZlbnRfb3ZlcmZsb3coZXZlbnQsIDEsIG5taSwgZGF0YSwgcmVncyk7CgoJaWYgKGxvY2FsNjRfYWRkX25lZ2F0aXZlKG5yLCAmaHdjLT5wZXJpb2RfbGVmdCkpCgkJcmV0dXJuOwoKCXBlcmZfc3dldmVudF9vdmVyZmxvdyhldmVudCwgMCwgbm1pLCBkYXRhLCByZWdzKTsKfQoKc3RhdGljIGludCBwZXJmX2V4Y2x1ZGVfZXZlbnQoc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50LAoJCQkgICAgICBzdHJ1Y3QgcHRfcmVncyAqcmVncykKewoJaWYgKGV2ZW50LT5ody5zdGF0ZSAmIFBFUkZfSEVTX1NUT1BQRUQpCgkJcmV0dXJuIDA7CgoJaWYgKHJlZ3MpIHsKCQlpZiAoZXZlbnQtPmF0dHIuZXhjbHVkZV91c2VyICYmIHVzZXJfbW9kZShyZWdzKSkKCQkJcmV0dXJuIDE7CgoJCWlmIChldmVudC0+YXR0ci5leGNsdWRlX2tlcm5lbCAmJiAhdXNlcl9tb2RlKHJlZ3MpKQoJCQlyZXR1cm4gMTsKCX0KCglyZXR1cm4gMDsKfQoKc3RhdGljIGludCBwZXJmX3N3ZXZlbnRfbWF0Y2goc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50LAoJCQkJZW51bSBwZXJmX3R5cGVfaWQgdHlwZSwKCQkJCXUzMiBldmVudF9pZCwKCQkJCXN0cnVjdCBwZXJmX3NhbXBsZV9kYXRhICpkYXRhLAoJCQkJc3RydWN0IHB0X3JlZ3MgKnJlZ3MpCnsKCWlmIChldmVudC0+YXR0ci50eXBlICE9IHR5cGUpCgkJcmV0dXJuIDA7CgoJaWYgKGV2ZW50LT5hdHRyLmNvbmZpZyAhPSBldmVudF9pZCkKCQlyZXR1cm4gMDsKCglpZiAocGVyZl9leGNsdWRlX2V2ZW50KGV2ZW50LCByZWdzKSkKCQlyZXR1cm4gMDsKCglyZXR1cm4gMTsKfQoKc3RhdGljIGlubGluZSB1NjQgc3dldmVudF9oYXNoKHU2NCB0eXBlLCB1MzIgZXZlbnRfaWQpCnsKCXU2NCB2YWwgPSBldmVudF9pZCB8ICh0eXBlIDw8IDMyKTsKCglyZXR1cm4gaGFzaF82NCh2YWwsIFNXRVZFTlRfSExJU1RfQklUUyk7Cn0KCnN0YXRpYyBpbmxpbmUgc3RydWN0IGhsaXN0X2hlYWQgKgpfX2ZpbmRfc3dldmVudF9oZWFkKHN0cnVjdCBzd2V2ZW50X2hsaXN0ICpobGlzdCwgdTY0IHR5cGUsIHUzMiBldmVudF9pZCkKewoJdTY0IGhhc2ggPSBzd2V2ZW50X2hhc2godHlwZSwgZXZlbnRfaWQpOwoKCXJldHVybiAmaGxpc3QtPmhlYWRzW2hhc2hdOwp9CgovKiBGb3IgdGhlIHJlYWQgc2lkZTogZXZlbnRzIHdoZW4gdGhleSB0cmlnZ2VyICovCnN0YXRpYyBpbmxpbmUgc3RydWN0IGhsaXN0X2hlYWQgKgpmaW5kX3N3ZXZlbnRfaGVhZF9yY3Uoc3RydWN0IHN3ZXZlbnRfaHRhYmxlICpzd2hhc2gsIHU2NCB0eXBlLCB1MzIgZXZlbnRfaWQpCnsKCXN0cnVjdCBzd2V2ZW50X2hsaXN0ICpobGlzdDsKCglobGlzdCA9IHJjdV9kZXJlZmVyZW5jZShzd2hhc2gtPnN3ZXZlbnRfaGxpc3QpOwoJaWYgKCFobGlzdCkKCQlyZXR1cm4gTlVMTDsKCglyZXR1cm4gX19maW5kX3N3ZXZlbnRfaGVhZChobGlzdCwgdHlwZSwgZXZlbnRfaWQpOwp9CgovKiBGb3IgdGhlIGV2ZW50IGhlYWQgaW5zZXJ0aW9uIGFuZCByZW1vdmFsIGluIHRoZSBobGlzdCAqLwpzdGF0aWMgaW5saW5lIHN0cnVjdCBobGlzdF9oZWFkICoKZmluZF9zd2V2ZW50X2hlYWQoc3RydWN0IHN3ZXZlbnRfaHRhYmxlICpzd2hhc2gsIHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCkKewoJc3RydWN0IHN3ZXZlbnRfaGxpc3QgKmhsaXN0OwoJdTMyIGV2ZW50X2lkID0gZXZlbnQtPmF0dHIuY29uZmlnOwoJdTY0IHR5cGUgPSBldmVudC0+YXR0ci50eXBlOwoKCS8qCgkgKiBFdmVudCBzY2hlZHVsaW5nIGlzIGFsd2F5cyBzZXJpYWxpemVkIGFnYWluc3QgaGxpc3QgYWxsb2NhdGlvbgoJICogYW5kIHJlbGVhc2UuIFdoaWNoIG1ha2VzIHRoZSBwcm90ZWN0ZWQgdmVyc2lvbiBzdWl0YWJsZSBoZXJlLgoJICogVGhlIGNvbnRleHQgbG9jayBndWFyYW50ZWVzIHRoYXQuCgkgKi8KCWhsaXN0ID0gcmN1X2RlcmVmZXJlbmNlX3Byb3RlY3RlZChzd2hhc2gtPnN3ZXZlbnRfaGxpc3QsCgkJCQkJICBsb2NrZGVwX2lzX2hlbGQoJmV2ZW50LT5jdHgtPmxvY2spKTsKCWlmICghaGxpc3QpCgkJcmV0dXJuIE5VTEw7CgoJcmV0dXJuIF9fZmluZF9zd2V2ZW50X2hlYWQoaGxpc3QsIHR5cGUsIGV2ZW50X2lkKTsKfQoKc3RhdGljIHZvaWQgZG9fcGVyZl9zd19ldmVudChlbnVtIHBlcmZfdHlwZV9pZCB0eXBlLCB1MzIgZXZlbnRfaWQsCgkJCQkgICAgdTY0IG5yLCBpbnQgbm1pLAoJCQkJICAgIHN0cnVjdCBwZXJmX3NhbXBsZV9kYXRhICpkYXRhLAoJCQkJICAgIHN0cnVjdCBwdF9yZWdzICpyZWdzKQp7CglzdHJ1Y3Qgc3dldmVudF9odGFibGUgKnN3aGFzaCA9ICZfX2dldF9jcHVfdmFyKHN3ZXZlbnRfaHRhYmxlKTsKCXN0cnVjdCBwZXJmX2V2ZW50ICpldmVudDsKCXN0cnVjdCBobGlzdF9ub2RlICpub2RlOwoJc3RydWN0IGhsaXN0X2hlYWQgKmhlYWQ7CgoJcmN1X3JlYWRfbG9jaygpOwoJaGVhZCA9IGZpbmRfc3dldmVudF9oZWFkX3JjdShzd2hhc2gsIHR5cGUsIGV2ZW50X2lkKTsKCWlmICghaGVhZCkKCQlnb3RvIGVuZDsKCglobGlzdF9mb3JfZWFjaF9lbnRyeV9yY3UoZXZlbnQsIG5vZGUsIGhlYWQsIGhsaXN0X2VudHJ5KSB7CgkJaWYgKHBlcmZfc3dldmVudF9tYXRjaChldmVudCwgdHlwZSwgZXZlbnRfaWQsIGRhdGEsIHJlZ3MpKQoJCQlwZXJmX3N3ZXZlbnRfZXZlbnQoZXZlbnQsIG5yLCBubWksIGRhdGEsIHJlZ3MpOwoJfQplbmQ6CglyY3VfcmVhZF91bmxvY2soKTsKfQoKaW50IHBlcmZfc3dldmVudF9nZXRfcmVjdXJzaW9uX2NvbnRleHQodm9pZCkKewoJc3RydWN0IHN3ZXZlbnRfaHRhYmxlICpzd2hhc2ggPSAmX19nZXRfY3B1X3Zhcihzd2V2ZW50X2h0YWJsZSk7CgoJcmV0dXJuIGdldF9yZWN1cnNpb25fY29udGV4dChzd2hhc2gtPnJlY3Vyc2lvbik7Cn0KRVhQT1JUX1NZTUJPTF9HUEwocGVyZl9zd2V2ZW50X2dldF9yZWN1cnNpb25fY29udGV4dCk7Cgp2b2lkIGlubGluZSBwZXJmX3N3ZXZlbnRfcHV0X3JlY3Vyc2lvbl9jb250ZXh0KGludCByY3R4KQp7CglzdHJ1Y3Qgc3dldmVudF9odGFibGUgKnN3aGFzaCA9ICZfX2dldF9jcHVfdmFyKHN3ZXZlbnRfaHRhYmxlKTsKCglwdXRfcmVjdXJzaW9uX2NvbnRleHQoc3doYXNoLT5yZWN1cnNpb24sIHJjdHgpOwp9Cgp2b2lkIF9fcGVyZl9zd19ldmVudCh1MzIgZXZlbnRfaWQsIHU2NCBuciwgaW50IG5taSwKCQkJICAgIHN0cnVjdCBwdF9yZWdzICpyZWdzLCB1NjQgYWRkcikKewoJc3RydWN0IHBlcmZfc2FtcGxlX2RhdGEgZGF0YTsKCWludCByY3R4OwoKCXByZWVtcHRfZGlzYWJsZV9ub3RyYWNlKCk7CglyY3R4ID0gcGVyZl9zd2V2ZW50X2dldF9yZWN1cnNpb25fY29udGV4dCgpOwoJaWYgKHJjdHggPCAwKQoJCXJldHVybjsKCglwZXJmX3NhbXBsZV9kYXRhX2luaXQoJmRhdGEsIGFkZHIpOwoKCWRvX3BlcmZfc3dfZXZlbnQoUEVSRl9UWVBFX1NPRlRXQVJFLCBldmVudF9pZCwgbnIsIG5taSwgJmRhdGEsIHJlZ3MpOwoKCXBlcmZfc3dldmVudF9wdXRfcmVjdXJzaW9uX2NvbnRleHQocmN0eCk7CglwcmVlbXB0X2VuYWJsZV9ub3RyYWNlKCk7Cn0KCnN0YXRpYyB2b2lkIHBlcmZfc3dldmVudF9yZWFkKHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCkKewp9CgpzdGF0aWMgaW50IHBlcmZfc3dldmVudF9hZGQoc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50LCBpbnQgZmxhZ3MpCnsKCXN0cnVjdCBzd2V2ZW50X2h0YWJsZSAqc3doYXNoID0gJl9fZ2V0X2NwdV92YXIoc3dldmVudF9odGFibGUpOwoJc3RydWN0IGh3X3BlcmZfZXZlbnQgKmh3YyA9ICZldmVudC0+aHc7CglzdHJ1Y3QgaGxpc3RfaGVhZCAqaGVhZDsKCglpZiAoaXNfc2FtcGxpbmdfZXZlbnQoZXZlbnQpKSB7CgkJaHdjLT5sYXN0X3BlcmlvZCA9IGh3Yy0+c2FtcGxlX3BlcmlvZDsKCQlwZXJmX3N3ZXZlbnRfc2V0X3BlcmlvZChldmVudCk7Cgl9CgoJaHdjLT5zdGF0ZSA9ICEoZmxhZ3MgJiBQRVJGX0VGX1NUQVJUKTsKCgloZWFkID0gZmluZF9zd2V2ZW50X2hlYWQoc3doYXNoLCBldmVudCk7CglpZiAoV0FSTl9PTl9PTkNFKCFoZWFkKSkKCQlyZXR1cm4gLUVJTlZBTDsKCglobGlzdF9hZGRfaGVhZF9yY3UoJmV2ZW50LT5obGlzdF9lbnRyeSwgaGVhZCk7CgoJcmV0dXJuIDA7Cn0KCnN0YXRpYyB2b2lkIHBlcmZfc3dldmVudF9kZWwoc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50LCBpbnQgZmxhZ3MpCnsKCWhsaXN0X2RlbF9yY3UoJmV2ZW50LT5obGlzdF9lbnRyeSk7Cn0KCnN0YXRpYyB2b2lkIHBlcmZfc3dldmVudF9zdGFydChzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQsIGludCBmbGFncykKewoJZXZlbnQtPmh3LnN0YXRlID0gMDsKfQoKc3RhdGljIHZvaWQgcGVyZl9zd2V2ZW50X3N0b3Aoc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50LCBpbnQgZmxhZ3MpCnsKCWV2ZW50LT5ody5zdGF0ZSA9IFBFUkZfSEVTX1NUT1BQRUQ7Cn0KCi8qIERlcmVmIHRoZSBobGlzdCBmcm9tIHRoZSB1cGRhdGUgc2lkZSAqLwpzdGF0aWMgaW5saW5lIHN0cnVjdCBzd2V2ZW50X2hsaXN0ICoKc3dldmVudF9obGlzdF9kZXJlZihzdHJ1Y3Qgc3dldmVudF9odGFibGUgKnN3aGFzaCkKewoJcmV0dXJuIHJjdV9kZXJlZmVyZW5jZV9wcm90ZWN0ZWQoc3doYXNoLT5zd2V2ZW50X2hsaXN0LAoJCQkJCSBsb2NrZGVwX2lzX2hlbGQoJnN3aGFzaC0+aGxpc3RfbXV0ZXgpKTsKfQoKc3RhdGljIHZvaWQgc3dldmVudF9obGlzdF9yZWxlYXNlX3JjdShzdHJ1Y3QgcmN1X2hlYWQgKnJjdV9oZWFkKQp7CglzdHJ1Y3Qgc3dldmVudF9obGlzdCAqaGxpc3Q7CgoJaGxpc3QgPSBjb250YWluZXJfb2YocmN1X2hlYWQsIHN0cnVjdCBzd2V2ZW50X2hsaXN0LCByY3VfaGVhZCk7CglrZnJlZShobGlzdCk7Cn0KCnN0YXRpYyB2b2lkIHN3ZXZlbnRfaGxpc3RfcmVsZWFzZShzdHJ1Y3Qgc3dldmVudF9odGFibGUgKnN3aGFzaCkKewoJc3RydWN0IHN3ZXZlbnRfaGxpc3QgKmhsaXN0ID0gc3dldmVudF9obGlzdF9kZXJlZihzd2hhc2gpOwoKCWlmICghaGxpc3QpCgkJcmV0dXJuOwoKCXJjdV9hc3NpZ25fcG9pbnRlcihzd2hhc2gtPnN3ZXZlbnRfaGxpc3QsIE5VTEwpOwoJY2FsbF9yY3UoJmhsaXN0LT5yY3VfaGVhZCwgc3dldmVudF9obGlzdF9yZWxlYXNlX3JjdSk7Cn0KCnN0YXRpYyB2b2lkIHN3ZXZlbnRfaGxpc3RfcHV0X2NwdShzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQsIGludCBjcHUpCnsKCXN0cnVjdCBzd2V2ZW50X2h0YWJsZSAqc3doYXNoID0gJnBlcl9jcHUoc3dldmVudF9odGFibGUsIGNwdSk7CgoJbXV0ZXhfbG9jaygmc3doYXNoLT5obGlzdF9tdXRleCk7CgoJaWYgKCEtLXN3aGFzaC0+aGxpc3RfcmVmY291bnQpCgkJc3dldmVudF9obGlzdF9yZWxlYXNlKHN3aGFzaCk7CgoJbXV0ZXhfdW5sb2NrKCZzd2hhc2gtPmhsaXN0X211dGV4KTsKfQoKc3RhdGljIHZvaWQgc3dldmVudF9obGlzdF9wdXQoc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50KQp7CglpbnQgY3B1OwoKCWlmIChldmVudC0+Y3B1ICE9IC0xKSB7CgkJc3dldmVudF9obGlzdF9wdXRfY3B1KGV2ZW50LCBldmVudC0+Y3B1KTsKCQlyZXR1cm47Cgl9CgoJZm9yX2VhY2hfcG9zc2libGVfY3B1KGNwdSkKCQlzd2V2ZW50X2hsaXN0X3B1dF9jcHUoZXZlbnQsIGNwdSk7Cn0KCnN0YXRpYyBpbnQgc3dldmVudF9obGlzdF9nZXRfY3B1KHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCwgaW50IGNwdSkKewoJc3RydWN0IHN3ZXZlbnRfaHRhYmxlICpzd2hhc2ggPSAmcGVyX2NwdShzd2V2ZW50X2h0YWJsZSwgY3B1KTsKCWludCBlcnIgPSAwOwoKCW11dGV4X2xvY2soJnN3aGFzaC0+aGxpc3RfbXV0ZXgpOwoKCWlmICghc3dldmVudF9obGlzdF9kZXJlZihzd2hhc2gpICYmIGNwdV9vbmxpbmUoY3B1KSkgewoJCXN0cnVjdCBzd2V2ZW50X2hsaXN0ICpobGlzdDsKCgkJaGxpc3QgPSBremFsbG9jKHNpemVvZigqaGxpc3QpLCBHRlBfS0VSTkVMKTsKCQlpZiAoIWhsaXN0KSB7CgkJCWVyciA9IC1FTk9NRU07CgkJCWdvdG8gZXhpdDsKCQl9CgkJcmN1X2Fzc2lnbl9wb2ludGVyKHN3aGFzaC0+c3dldmVudF9obGlzdCwgaGxpc3QpOwoJfQoJc3doYXNoLT5obGlzdF9yZWZjb3VudCsrOwpleGl0OgoJbXV0ZXhfdW5sb2NrKCZzd2hhc2gtPmhsaXN0X211dGV4KTsKCglyZXR1cm4gZXJyOwp9CgpzdGF0aWMgaW50IHN3ZXZlbnRfaGxpc3RfZ2V0KHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCkKewoJaW50IGVycjsKCWludCBjcHUsIGZhaWxlZF9jcHU7CgoJaWYgKGV2ZW50LT5jcHUgIT0gLTEpCgkJcmV0dXJuIHN3ZXZlbnRfaGxpc3RfZ2V0X2NwdShldmVudCwgZXZlbnQtPmNwdSk7CgoJZ2V0X29ubGluZV9jcHVzKCk7Cglmb3JfZWFjaF9wb3NzaWJsZV9jcHUoY3B1KSB7CgkJZXJyID0gc3dldmVudF9obGlzdF9nZXRfY3B1KGV2ZW50LCBjcHUpOwoJCWlmIChlcnIpIHsKCQkJZmFpbGVkX2NwdSA9IGNwdTsKCQkJZ290byBmYWlsOwoJCX0KCX0KCXB1dF9vbmxpbmVfY3B1cygpOwoKCXJldHVybiAwOwpmYWlsOgoJZm9yX2VhY2hfcG9zc2libGVfY3B1KGNwdSkgewoJCWlmIChjcHUgPT0gZmFpbGVkX2NwdSkKCQkJYnJlYWs7CgkJc3dldmVudF9obGlzdF9wdXRfY3B1KGV2ZW50LCBjcHUpOwoJfQoKCXB1dF9vbmxpbmVfY3B1cygpOwoJcmV0dXJuIGVycjsKfQoKYXRvbWljX3QgcGVyZl9zd2V2ZW50X2VuYWJsZWRbUEVSRl9DT1VOVF9TV19NQVhdOwoKc3RhdGljIHZvaWQgc3dfcGVyZl9ldmVudF9kZXN0cm95KHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCkKewoJdTY0IGV2ZW50X2lkID0gZXZlbnQtPmF0dHIuY29uZmlnOwoKCVdBUk5fT04oZXZlbnQtPnBhcmVudCk7CgoJanVtcF9sYWJlbF9kZWMoJnBlcmZfc3dldmVudF9lbmFibGVkW2V2ZW50X2lkXSk7Cglzd2V2ZW50X2hsaXN0X3B1dChldmVudCk7Cn0KCnN0YXRpYyBpbnQgcGVyZl9zd2V2ZW50X2luaXQoc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50KQp7CglpbnQgZXZlbnRfaWQgPSBldmVudC0+YXR0ci5jb25maWc7CgoJaWYgKGV2ZW50LT5hdHRyLnR5cGUgIT0gUEVSRl9UWVBFX1NPRlRXQVJFKQoJCXJldHVybiAtRU5PRU5UOwoKCXN3aXRjaCAoZXZlbnRfaWQpIHsKCWNhc2UgUEVSRl9DT1VOVF9TV19DUFVfQ0xPQ0s6CgljYXNlIFBFUkZfQ09VTlRfU1dfVEFTS19DTE9DSzoKCQlyZXR1cm4gLUVOT0VOVDsKCglkZWZhdWx0OgoJCWJyZWFrOwoJfQoKCWlmIChldmVudF9pZCA+PSBQRVJGX0NPVU5UX1NXX01BWCkKCQlyZXR1cm4gLUVOT0VOVDsKCglpZiAoIWV2ZW50LT5wYXJlbnQpIHsKCQlpbnQgZXJyOwoKCQllcnIgPSBzd2V2ZW50X2hsaXN0X2dldChldmVudCk7CgkJaWYgKGVycikKCQkJcmV0dXJuIGVycjsKCgkJanVtcF9sYWJlbF9pbmMoJnBlcmZfc3dldmVudF9lbmFibGVkW2V2ZW50X2lkXSk7CgkJZXZlbnQtPmRlc3Ryb3kgPSBzd19wZXJmX2V2ZW50X2Rlc3Ryb3k7Cgl9CgoJcmV0dXJuIDA7Cn0KCnN0YXRpYyBzdHJ1Y3QgcG11IHBlcmZfc3dldmVudCA9IHsKCS50YXNrX2N0eF9ucgk9IHBlcmZfc3dfY29udGV4dCwKCgkuZXZlbnRfaW5pdAk9IHBlcmZfc3dldmVudF9pbml0LAoJLmFkZAkJPSBwZXJmX3N3ZXZlbnRfYWRkLAoJLmRlbAkJPSBwZXJmX3N3ZXZlbnRfZGVsLAoJLnN0YXJ0CQk9IHBlcmZfc3dldmVudF9zdGFydCwKCS5zdG9wCQk9IHBlcmZfc3dldmVudF9zdG9wLAoJLnJlYWQJCT0gcGVyZl9zd2V2ZW50X3JlYWQsCn07CgojaWZkZWYgQ09ORklHX0VWRU5UX1RSQUNJTkcKCnN0YXRpYyBpbnQgcGVyZl90cF9maWx0ZXJfbWF0Y2goc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50LAoJCQkJc3RydWN0IHBlcmZfc2FtcGxlX2RhdGEgKmRhdGEpCnsKCXZvaWQgKnJlY29yZCA9IGRhdGEtPnJhdy0+ZGF0YTsKCglpZiAobGlrZWx5KCFldmVudC0+ZmlsdGVyKSB8fCBmaWx0ZXJfbWF0Y2hfcHJlZHMoZXZlbnQtPmZpbHRlciwgcmVjb3JkKSkKCQlyZXR1cm4gMTsKCXJldHVybiAwOwp9CgpzdGF0aWMgaW50IHBlcmZfdHBfZXZlbnRfbWF0Y2goc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50LAoJCQkJc3RydWN0IHBlcmZfc2FtcGxlX2RhdGEgKmRhdGEsCgkJCQlzdHJ1Y3QgcHRfcmVncyAqcmVncykKewoJLyoKCSAqIEFsbCB0cmFjZXBvaW50cyBhcmUgZnJvbSBrZXJuZWwtc3BhY2UuCgkgKi8KCWlmIChldmVudC0+YXR0ci5leGNsdWRlX2tlcm5lbCkKCQlyZXR1cm4gMDsKCglpZiAoIXBlcmZfdHBfZmlsdGVyX21hdGNoKGV2ZW50LCBkYXRhKSkKCQlyZXR1cm4gMDsKCglyZXR1cm4gMTsKfQoKdm9pZCBwZXJmX3RwX2V2ZW50KHU2NCBhZGRyLCB1NjQgY291bnQsIHZvaWQgKnJlY29yZCwgaW50IGVudHJ5X3NpemUsCgkJICAgc3RydWN0IHB0X3JlZ3MgKnJlZ3MsIHN0cnVjdCBobGlzdF9oZWFkICpoZWFkLCBpbnQgcmN0eCkKewoJc3RydWN0IHBlcmZfc2FtcGxlX2RhdGEgZGF0YTsKCXN0cnVjdCBwZXJmX2V2ZW50ICpldmVudDsKCXN0cnVjdCBobGlzdF9ub2RlICpub2RlOwoKCXN0cnVjdCBwZXJmX3Jhd19yZWNvcmQgcmF3ID0gewoJCS5zaXplID0gZW50cnlfc2l6ZSwKCQkuZGF0YSA9IHJlY29yZCwKCX07CgoJcGVyZl9zYW1wbGVfZGF0YV9pbml0KCZkYXRhLCBhZGRyKTsKCWRhdGEucmF3ID0gJnJhdzsKCglobGlzdF9mb3JfZWFjaF9lbnRyeV9yY3UoZXZlbnQsIG5vZGUsIGhlYWQsIGhsaXN0X2VudHJ5KSB7CgkJaWYgKHBlcmZfdHBfZXZlbnRfbWF0Y2goZXZlbnQsICZkYXRhLCByZWdzKSkKCQkJcGVyZl9zd2V2ZW50X2V2ZW50KGV2ZW50LCBjb3VudCwgMSwgJmRhdGEsIHJlZ3MpOwoJfQoKCXBlcmZfc3dldmVudF9wdXRfcmVjdXJzaW9uX2NvbnRleHQocmN0eCk7Cn0KRVhQT1JUX1NZTUJPTF9HUEwocGVyZl90cF9ldmVudCk7CgpzdGF0aWMgdm9pZCB0cF9wZXJmX2V2ZW50X2Rlc3Ryb3koc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50KQp7CglwZXJmX3RyYWNlX2Rlc3Ryb3koZXZlbnQpOwp9CgpzdGF0aWMgaW50IHBlcmZfdHBfZXZlbnRfaW5pdChzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQpCnsKCWludCBlcnI7CgoJaWYgKGV2ZW50LT5hdHRyLnR5cGUgIT0gUEVSRl9UWVBFX1RSQUNFUE9JTlQpCgkJcmV0dXJuIC1FTk9FTlQ7CgoJZXJyID0gcGVyZl90cmFjZV9pbml0KGV2ZW50KTsKCWlmIChlcnIpCgkJcmV0dXJuIGVycjsKCglldmVudC0+ZGVzdHJveSA9IHRwX3BlcmZfZXZlbnRfZGVzdHJveTsKCglyZXR1cm4gMDsKfQoKc3RhdGljIHN0cnVjdCBwbXUgcGVyZl90cmFjZXBvaW50ID0gewoJLnRhc2tfY3R4X25yCT0gcGVyZl9zd19jb250ZXh0LAoKCS5ldmVudF9pbml0CT0gcGVyZl90cF9ldmVudF9pbml0LAoJLmFkZAkJPSBwZXJmX3RyYWNlX2FkZCwKCS5kZWwJCT0gcGVyZl90cmFjZV9kZWwsCgkuc3RhcnQJCT0gcGVyZl9zd2V2ZW50X3N0YXJ0LAoJLnN0b3AJCT0gcGVyZl9zd2V2ZW50X3N0b3AsCgkucmVhZAkJPSBwZXJmX3N3ZXZlbnRfcmVhZCwKfTsKCnN0YXRpYyBpbmxpbmUgdm9pZCBwZXJmX3RwX3JlZ2lzdGVyKHZvaWQpCnsKCXBlcmZfcG11X3JlZ2lzdGVyKCZwZXJmX3RyYWNlcG9pbnQsICJ0cmFjZXBvaW50IiwgUEVSRl9UWVBFX1RSQUNFUE9JTlQpOwp9CgpzdGF0aWMgaW50IHBlcmZfZXZlbnRfc2V0X2ZpbHRlcihzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQsIHZvaWQgX191c2VyICphcmcpCnsKCWNoYXIgKmZpbHRlcl9zdHI7CglpbnQgcmV0OwoKCWlmIChldmVudC0+YXR0ci50eXBlICE9IFBFUkZfVFlQRV9UUkFDRVBPSU5UKQoJCXJldHVybiAtRUlOVkFMOwoKCWZpbHRlcl9zdHIgPSBzdHJuZHVwX3VzZXIoYXJnLCBQQUdFX1NJWkUpOwoJaWYgKElTX0VSUihmaWx0ZXJfc3RyKSkKCQlyZXR1cm4gUFRSX0VSUihmaWx0ZXJfc3RyKTsKCglyZXQgPSBmdHJhY2VfcHJvZmlsZV9zZXRfZmlsdGVyKGV2ZW50LCBldmVudC0+YXR0ci5jb25maWcsIGZpbHRlcl9zdHIpOwoKCWtmcmVlKGZpbHRlcl9zdHIpOwoJcmV0dXJuIHJldDsKfQoKc3RhdGljIHZvaWQgcGVyZl9ldmVudF9mcmVlX2ZpbHRlcihzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQpCnsKCWZ0cmFjZV9wcm9maWxlX2ZyZWVfZmlsdGVyKGV2ZW50KTsKfQoKI2Vsc2UKCnN0YXRpYyBpbmxpbmUgdm9pZCBwZXJmX3RwX3JlZ2lzdGVyKHZvaWQpCnsKfQoKc3RhdGljIGludCBwZXJmX2V2ZW50X3NldF9maWx0ZXIoc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50LCB2b2lkIF9fdXNlciAqYXJnKQp7CglyZXR1cm4gLUVOT0VOVDsKfQoKc3RhdGljIHZvaWQgcGVyZl9ldmVudF9mcmVlX2ZpbHRlcihzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQpCnsKfQoKI2VuZGlmIC8qIENPTkZJR19FVkVOVF9UUkFDSU5HICovCgojaWZkZWYgQ09ORklHX0hBVkVfSFdfQlJFQUtQT0lOVAp2b2lkIHBlcmZfYnBfZXZlbnQoc3RydWN0IHBlcmZfZXZlbnQgKmJwLCB2b2lkICpkYXRhKQp7CglzdHJ1Y3QgcGVyZl9zYW1wbGVfZGF0YSBzYW1wbGU7CglzdHJ1Y3QgcHRfcmVncyAqcmVncyA9IGRhdGE7CgoJcGVyZl9zYW1wbGVfZGF0YV9pbml0KCZzYW1wbGUsIGJwLT5hdHRyLmJwX2FkZHIpOwoKCWlmICghYnAtPmh3LnN0YXRlICYmICFwZXJmX2V4Y2x1ZGVfZXZlbnQoYnAsIHJlZ3MpKQoJCXBlcmZfc3dldmVudF9ldmVudChicCwgMSwgMSwgJnNhbXBsZSwgcmVncyk7Cn0KI2VuZGlmCgovKgogKiBocnRpbWVyIGJhc2VkIHN3ZXZlbnQgY2FsbGJhY2sKICovCgpzdGF0aWMgZW51bSBocnRpbWVyX3Jlc3RhcnQgcGVyZl9zd2V2ZW50X2hydGltZXIoc3RydWN0IGhydGltZXIgKmhydGltZXIpCnsKCWVudW0gaHJ0aW1lcl9yZXN0YXJ0IHJldCA9IEhSVElNRVJfUkVTVEFSVDsKCXN0cnVjdCBwZXJmX3NhbXBsZV9kYXRhIGRhdGE7CglzdHJ1Y3QgcHRfcmVncyAqcmVnczsKCXN0cnVjdCBwZXJmX2V2ZW50ICpldmVudDsKCXU2NCBwZXJpb2Q7CgoJZXZlbnQgPSBjb250YWluZXJfb2YoaHJ0aW1lciwgc3RydWN0IHBlcmZfZXZlbnQsIGh3LmhydGltZXIpOwoJZXZlbnQtPnBtdS0+cmVhZChldmVudCk7CgoJcGVyZl9zYW1wbGVfZGF0YV9pbml0KCZkYXRhLCAwKTsKCWRhdGEucGVyaW9kID0gZXZlbnQtPmh3Lmxhc3RfcGVyaW9kOwoJcmVncyA9IGdldF9pcnFfcmVncygpOwoKCWlmIChyZWdzICYmICFwZXJmX2V4Y2x1ZGVfZXZlbnQoZXZlbnQsIHJlZ3MpKSB7CgkJaWYgKCEoZXZlbnQtPmF0dHIuZXhjbHVkZV9pZGxlICYmIGN1cnJlbnQtPnBpZCA9PSAwKSkKCQkJaWYgKHBlcmZfZXZlbnRfb3ZlcmZsb3coZXZlbnQsIDAsICZkYXRhLCByZWdzKSkKCQkJCXJldCA9IEhSVElNRVJfTk9SRVNUQVJUOwoJfQoKCXBlcmlvZCA9IG1heF90KHU2NCwgMTAwMDAsIGV2ZW50LT5ody5zYW1wbGVfcGVyaW9kKTsKCWhydGltZXJfZm9yd2FyZF9ub3coaHJ0aW1lciwgbnNfdG9fa3RpbWUocGVyaW9kKSk7CgoJcmV0dXJuIHJldDsKfQoKc3RhdGljIHZvaWQgcGVyZl9zd2V2ZW50X3N0YXJ0X2hydGltZXIoc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50KQp7CglzdHJ1Y3QgaHdfcGVyZl9ldmVudCAqaHdjID0gJmV2ZW50LT5odzsKCXM2NCBwZXJpb2Q7CgoJaWYgKCFpc19zYW1wbGluZ19ldmVudChldmVudCkpCgkJcmV0dXJuOwoKCWhydGltZXJfaW5pdCgmaHdjLT5ocnRpbWVyLCBDTE9DS19NT05PVE9OSUMsIEhSVElNRVJfTU9ERV9SRUwpOwoJaHdjLT5ocnRpbWVyLmZ1bmN0aW9uID0gcGVyZl9zd2V2ZW50X2hydGltZXI7CgoJcGVyaW9kID0gbG9jYWw2NF9yZWFkKCZod2MtPnBlcmlvZF9sZWZ0KTsKCWlmIChwZXJpb2QpIHsKCQlpZiAocGVyaW9kIDwgMCkKCQkJcGVyaW9kID0gMTAwMDA7CgoJCWxvY2FsNjRfc2V0KCZod2MtPnBlcmlvZF9sZWZ0LCAwKTsKCX0gZWxzZSB7CgkJcGVyaW9kID0gbWF4X3QodTY0LCAxMDAwMCwgaHdjLT5zYW1wbGVfcGVyaW9kKTsKCX0KCV9faHJ0aW1lcl9zdGFydF9yYW5nZV9ucygmaHdjLT5ocnRpbWVyLAoJCQkJbnNfdG9fa3RpbWUocGVyaW9kKSwgMCwKCQkJCUhSVElNRVJfTU9ERV9SRUxfUElOTkVELCAwKTsKfQoKc3RhdGljIHZvaWQgcGVyZl9zd2V2ZW50X2NhbmNlbF9ocnRpbWVyKHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCkKewoJc3RydWN0IGh3X3BlcmZfZXZlbnQgKmh3YyA9ICZldmVudC0+aHc7CgoJaWYgKGlzX3NhbXBsaW5nX2V2ZW50KGV2ZW50KSkgewoJCWt0aW1lX3QgcmVtYWluaW5nID0gaHJ0aW1lcl9nZXRfcmVtYWluaW5nKCZod2MtPmhydGltZXIpOwoJCWxvY2FsNjRfc2V0KCZod2MtPnBlcmlvZF9sZWZ0LCBrdGltZV90b19ucyhyZW1haW5pbmcpKTsKCgkJaHJ0aW1lcl9jYW5jZWwoJmh3Yy0+aHJ0aW1lcik7Cgl9Cn0KCi8qCiAqIFNvZnR3YXJlIGV2ZW50OiBjcHUgd2FsbCB0aW1lIGNsb2NrCiAqLwoKc3RhdGljIHZvaWQgY3B1X2Nsb2NrX2V2ZW50X3VwZGF0ZShzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQpCnsKCXM2NCBwcmV2OwoJdTY0IG5vdzsKCglub3cgPSBsb2NhbF9jbG9jaygpOwoJcHJldiA9IGxvY2FsNjRfeGNoZygmZXZlbnQtPmh3LnByZXZfY291bnQsIG5vdyk7Cglsb2NhbDY0X2FkZChub3cgLSBwcmV2LCAmZXZlbnQtPmNvdW50KTsKfQoKc3RhdGljIHZvaWQgY3B1X2Nsb2NrX2V2ZW50X3N0YXJ0KHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCwgaW50IGZsYWdzKQp7Cglsb2NhbDY0X3NldCgmZXZlbnQtPmh3LnByZXZfY291bnQsIGxvY2FsX2Nsb2NrKCkpOwoJcGVyZl9zd2V2ZW50X3N0YXJ0X2hydGltZXIoZXZlbnQpOwp9CgpzdGF0aWMgdm9pZCBjcHVfY2xvY2tfZXZlbnRfc3RvcChzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQsIGludCBmbGFncykKewoJcGVyZl9zd2V2ZW50X2NhbmNlbF9ocnRpbWVyKGV2ZW50KTsKCWNwdV9jbG9ja19ldmVudF91cGRhdGUoZXZlbnQpOwp9CgpzdGF0aWMgaW50IGNwdV9jbG9ja19ldmVudF9hZGQoc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50LCBpbnQgZmxhZ3MpCnsKCWlmIChmbGFncyAmIFBFUkZfRUZfU1RBUlQpCgkJY3B1X2Nsb2NrX2V2ZW50X3N0YXJ0KGV2ZW50LCBmbGFncyk7CgoJcmV0dXJuIDA7Cn0KCnN0YXRpYyB2b2lkIGNwdV9jbG9ja19ldmVudF9kZWwoc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50LCBpbnQgZmxhZ3MpCnsKCWNwdV9jbG9ja19ldmVudF9zdG9wKGV2ZW50LCBmbGFncyk7Cn0KCnN0YXRpYyB2b2lkIGNwdV9jbG9ja19ldmVudF9yZWFkKHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCkKewoJY3B1X2Nsb2NrX2V2ZW50X3VwZGF0ZShldmVudCk7Cn0KCnN0YXRpYyBpbnQgY3B1X2Nsb2NrX2V2ZW50X2luaXQoc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50KQp7CglpZiAoZXZlbnQtPmF0dHIudHlwZSAhPSBQRVJGX1RZUEVfU09GVFdBUkUpCgkJcmV0dXJuIC1FTk9FTlQ7CgoJaWYgKGV2ZW50LT5hdHRyLmNvbmZpZyAhPSBQRVJGX0NPVU5UX1NXX0NQVV9DTE9DSykKCQlyZXR1cm4gLUVOT0VOVDsKCglyZXR1cm4gMDsKfQoKc3RhdGljIHN0cnVjdCBwbXUgcGVyZl9jcHVfY2xvY2sgPSB7CgkudGFza19jdHhfbnIJPSBwZXJmX3N3X2NvbnRleHQsCgoJLmV2ZW50X2luaXQJPSBjcHVfY2xvY2tfZXZlbnRfaW5pdCwKCS5hZGQJCT0gY3B1X2Nsb2NrX2V2ZW50X2FkZCwKCS5kZWwJCT0gY3B1X2Nsb2NrX2V2ZW50X2RlbCwKCS5zdGFydAkJPSBjcHVfY2xvY2tfZXZlbnRfc3RhcnQsCgkuc3RvcAkJPSBjcHVfY2xvY2tfZXZlbnRfc3RvcCwKCS5yZWFkCQk9IGNwdV9jbG9ja19ldmVudF9yZWFkLAp9OwoKLyoKICogU29mdHdhcmUgZXZlbnQ6IHRhc2sgdGltZSBjbG9jawogKi8KCnN0YXRpYyB2b2lkIHRhc2tfY2xvY2tfZXZlbnRfdXBkYXRlKHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCwgdTY0IG5vdykKewoJdTY0IHByZXY7CglzNjQgZGVsdGE7CgoJcHJldiA9IGxvY2FsNjRfeGNoZygmZXZlbnQtPmh3LnByZXZfY291bnQsIG5vdyk7CglkZWx0YSA9IG5vdyAtIHByZXY7Cglsb2NhbDY0X2FkZChkZWx0YSwgJmV2ZW50LT5jb3VudCk7Cn0KCnN0YXRpYyB2b2lkIHRhc2tfY2xvY2tfZXZlbnRfc3RhcnQoc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50LCBpbnQgZmxhZ3MpCnsKCWxvY2FsNjRfc2V0KCZldmVudC0+aHcucHJldl9jb3VudCwgZXZlbnQtPmN0eC0+dGltZSk7CglwZXJmX3N3ZXZlbnRfc3RhcnRfaHJ0aW1lcihldmVudCk7Cn0KCnN0YXRpYyB2b2lkIHRhc2tfY2xvY2tfZXZlbnRfc3RvcChzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQsIGludCBmbGFncykKewoJcGVyZl9zd2V2ZW50X2NhbmNlbF9ocnRpbWVyKGV2ZW50KTsKCXRhc2tfY2xvY2tfZXZlbnRfdXBkYXRlKGV2ZW50LCBldmVudC0+Y3R4LT50aW1lKTsKfQoKc3RhdGljIGludCB0YXNrX2Nsb2NrX2V2ZW50X2FkZChzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQsIGludCBmbGFncykKewoJaWYgKGZsYWdzICYgUEVSRl9FRl9TVEFSVCkKCQl0YXNrX2Nsb2NrX2V2ZW50X3N0YXJ0KGV2ZW50LCBmbGFncyk7CgoJcmV0dXJuIDA7Cn0KCnN0YXRpYyB2b2lkIHRhc2tfY2xvY2tfZXZlbnRfZGVsKHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCwgaW50IGZsYWdzKQp7Cgl0YXNrX2Nsb2NrX2V2ZW50X3N0b3AoZXZlbnQsIFBFUkZfRUZfVVBEQVRFKTsKfQoKc3RhdGljIHZvaWQgdGFza19jbG9ja19ldmVudF9yZWFkKHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCkKewoJdTY0IHRpbWU7CgoJaWYgKCFpbl9ubWkoKSkgewoJCXVwZGF0ZV9jb250ZXh0X3RpbWUoZXZlbnQtPmN0eCk7CgkJdGltZSA9IGV2ZW50LT5jdHgtPnRpbWU7Cgl9IGVsc2UgewoJCXU2NCBub3cgPSBwZXJmX2Nsb2NrKCk7CgkJdTY0IGRlbHRhID0gbm93IC0gZXZlbnQtPmN0eC0+dGltZXN0YW1wOwoJCXRpbWUgPSBldmVudC0+Y3R4LT50aW1lICsgZGVsdGE7Cgl9CgoJdGFza19jbG9ja19ldmVudF91cGRhdGUoZXZlbnQsIHRpbWUpOwp9CgpzdGF0aWMgaW50IHRhc2tfY2xvY2tfZXZlbnRfaW5pdChzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQpCnsKCWlmIChldmVudC0+YXR0ci50eXBlICE9IFBFUkZfVFlQRV9TT0ZUV0FSRSkKCQlyZXR1cm4gLUVOT0VOVDsKCglpZiAoZXZlbnQtPmF0dHIuY29uZmlnICE9IFBFUkZfQ09VTlRfU1dfVEFTS19DTE9DSykKCQlyZXR1cm4gLUVOT0VOVDsKCglyZXR1cm4gMDsKfQoKc3RhdGljIHN0cnVjdCBwbXUgcGVyZl90YXNrX2Nsb2NrID0gewoJLnRhc2tfY3R4X25yCT0gcGVyZl9zd19jb250ZXh0LAoKCS5ldmVudF9pbml0CT0gdGFza19jbG9ja19ldmVudF9pbml0LAoJLmFkZAkJPSB0YXNrX2Nsb2NrX2V2ZW50X2FkZCwKCS5kZWwJCT0gdGFza19jbG9ja19ldmVudF9kZWwsCgkuc3RhcnQJCT0gdGFza19jbG9ja19ldmVudF9zdGFydCwKCS5zdG9wCQk9IHRhc2tfY2xvY2tfZXZlbnRfc3RvcCwKCS5yZWFkCQk9IHRhc2tfY2xvY2tfZXZlbnRfcmVhZCwKfTsKCnN0YXRpYyB2b2lkIHBlcmZfcG11X25vcF92b2lkKHN0cnVjdCBwbXUgKnBtdSkKewp9CgpzdGF0aWMgaW50IHBlcmZfcG11X25vcF9pbnQoc3RydWN0IHBtdSAqcG11KQp7CglyZXR1cm4gMDsKfQoKc3RhdGljIHZvaWQgcGVyZl9wbXVfc3RhcnRfdHhuKHN0cnVjdCBwbXUgKnBtdSkKewoJcGVyZl9wbXVfZGlzYWJsZShwbXUpOwp9CgpzdGF0aWMgaW50IHBlcmZfcG11X2NvbW1pdF90eG4oc3RydWN0IHBtdSAqcG11KQp7CglwZXJmX3BtdV9lbmFibGUocG11KTsKCXJldHVybiAwOwp9CgpzdGF0aWMgdm9pZCBwZXJmX3BtdV9jYW5jZWxfdHhuKHN0cnVjdCBwbXUgKnBtdSkKewoJcGVyZl9wbXVfZW5hYmxlKHBtdSk7Cn0KCi8qCiAqIEVuc3VyZXMgYWxsIGNvbnRleHRzIHdpdGggdGhlIHNhbWUgdGFza19jdHhfbnIgaGF2ZSB0aGUgc2FtZQogKiBwbXVfY3B1X2NvbnRleHQgdG9vLgogKi8Kc3RhdGljIHZvaWQgKmZpbmRfcG11X2NvbnRleHQoaW50IGN0eG4pCnsKCXN0cnVjdCBwbXUgKnBtdTsKCglpZiAoY3R4biA8IDApCgkJcmV0dXJuIE5VTEw7CgoJbGlzdF9mb3JfZWFjaF9lbnRyeShwbXUsICZwbXVzLCBlbnRyeSkgewoJCWlmIChwbXUtPnRhc2tfY3R4X25yID09IGN0eG4pCgkJCXJldHVybiBwbXUtPnBtdV9jcHVfY29udGV4dDsKCX0KCglyZXR1cm4gTlVMTDsKfQoKc3RhdGljIHZvaWQgdXBkYXRlX3BtdV9jb250ZXh0KHN0cnVjdCBwbXUgKnBtdSwgc3RydWN0IHBtdSAqb2xkX3BtdSkKewoJaW50IGNwdTsKCglmb3JfZWFjaF9wb3NzaWJsZV9jcHUoY3B1KSB7CgkJc3RydWN0IHBlcmZfY3B1X2NvbnRleHQgKmNwdWN0eDsKCgkJY3B1Y3R4ID0gcGVyX2NwdV9wdHIocG11LT5wbXVfY3B1X2NvbnRleHQsIGNwdSk7CgoJCWlmIChjcHVjdHgtPmFjdGl2ZV9wbXUgPT0gb2xkX3BtdSkKCQkJY3B1Y3R4LT5hY3RpdmVfcG11ID0gcG11OwoJfQp9CgpzdGF0aWMgdm9pZCBmcmVlX3BtdV9jb250ZXh0KHN0cnVjdCBwbXUgKnBtdSkKewoJc3RydWN0IHBtdSAqaTsKCgltdXRleF9sb2NrKCZwbXVzX2xvY2spOwoJLyoKCSAqIExpa2UgYSByZWFsIGxhbWUgcmVmY291bnQuCgkgKi8KCWxpc3RfZm9yX2VhY2hfZW50cnkoaSwgJnBtdXMsIGVudHJ5KSB7CgkJaWYgKGktPnBtdV9jcHVfY29udGV4dCA9PSBwbXUtPnBtdV9jcHVfY29udGV4dCkgewoJCQl1cGRhdGVfcG11X2NvbnRleHQoaSwgcG11KTsKCQkJZ290byBvdXQ7CgkJfQoJfQoKCWZyZWVfcGVyY3B1KHBtdS0+cG11X2NwdV9jb250ZXh0KTsKb3V0OgoJbXV0ZXhfdW5sb2NrKCZwbXVzX2xvY2spOwp9CnN0YXRpYyBzdHJ1Y3QgaWRyIHBtdV9pZHI7CgpzdGF0aWMgc3NpemVfdAp0eXBlX3Nob3coc3RydWN0IGRldmljZSAqZGV2LCBzdHJ1Y3QgZGV2aWNlX2F0dHJpYnV0ZSAqYXR0ciwgY2hhciAqcGFnZSkKewoJc3RydWN0IHBtdSAqcG11ID0gZGV2X2dldF9kcnZkYXRhKGRldik7CgoJcmV0dXJuIHNucHJpbnRmKHBhZ2UsIFBBR0VfU0laRS0xLCAiJWRcbiIsIHBtdS0+dHlwZSk7Cn0KCnN0YXRpYyBzdHJ1Y3QgZGV2aWNlX2F0dHJpYnV0ZSBwbXVfZGV2X2F0dHJzW10gPSB7CiAgICAgICBfX0FUVFJfUk8odHlwZSksCiAgICAgICBfX0FUVFJfTlVMTCwKfTsKCnN0YXRpYyBpbnQgcG11X2J1c19ydW5uaW5nOwpzdGF0aWMgc3RydWN0IGJ1c190eXBlIHBtdV9idXMgPSB7CgkubmFtZQkJPSAiZXZlbnRfc291cmNlIiwKCS5kZXZfYXR0cnMJPSBwbXVfZGV2X2F0dHJzLAp9OwoKc3RhdGljIHZvaWQgcG11X2Rldl9yZWxlYXNlKHN0cnVjdCBkZXZpY2UgKmRldikKewoJa2ZyZWUoZGV2KTsKfQoKc3RhdGljIGludCBwbXVfZGV2X2FsbG9jKHN0cnVjdCBwbXUgKnBtdSkKewoJaW50IHJldCA9IC1FTk9NRU07CgoJcG11LT5kZXYgPSBremFsbG9jKHNpemVvZihzdHJ1Y3QgZGV2aWNlKSwgR0ZQX0tFUk5FTCk7CglpZiAoIXBtdS0+ZGV2KQoJCWdvdG8gb3V0OwoKCWRldmljZV9pbml0aWFsaXplKHBtdS0+ZGV2KTsKCXJldCA9IGRldl9zZXRfbmFtZShwbXUtPmRldiwgIiVzIiwgcG11LT5uYW1lKTsKCWlmIChyZXQpCgkJZ290byBmcmVlX2RldjsKCglkZXZfc2V0X2RydmRhdGEocG11LT5kZXYsIHBtdSk7CglwbXUtPmRldi0+YnVzID0gJnBtdV9idXM7CglwbXUtPmRldi0+cmVsZWFzZSA9IHBtdV9kZXZfcmVsZWFzZTsKCXJldCA9IGRldmljZV9hZGQocG11LT5kZXYpOwoJaWYgKHJldCkKCQlnb3RvIGZyZWVfZGV2OwoKb3V0OgoJcmV0dXJuIHJldDsKCmZyZWVfZGV2OgoJcHV0X2RldmljZShwbXUtPmRldik7Cglnb3RvIG91dDsKfQoKaW50IHBlcmZfcG11X3JlZ2lzdGVyKHN0cnVjdCBwbXUgKnBtdSwgY2hhciAqbmFtZSwgaW50IHR5cGUpCnsKCWludCBjcHUsIHJldDsKCgltdXRleF9sb2NrKCZwbXVzX2xvY2spOwoJcmV0ID0gLUVOT01FTTsKCXBtdS0+cG11X2Rpc2FibGVfY291bnQgPSBhbGxvY19wZXJjcHUoaW50KTsKCWlmICghcG11LT5wbXVfZGlzYWJsZV9jb3VudCkKCQlnb3RvIHVubG9jazsKCglwbXUtPnR5cGUgPSAtMTsKCWlmICghbmFtZSkKCQlnb3RvIHNraXBfdHlwZTsKCXBtdS0+bmFtZSA9IG5hbWU7CgoJaWYgKHR5cGUgPCAwKSB7CgkJaW50IGVyciA9IGlkcl9wcmVfZ2V0KCZwbXVfaWRyLCBHRlBfS0VSTkVMKTsKCQlpZiAoIWVycikKCQkJZ290byBmcmVlX3BkYzsKCgkJZXJyID0gaWRyX2dldF9uZXdfYWJvdmUoJnBtdV9pZHIsIHBtdSwgUEVSRl9UWVBFX01BWCwgJnR5cGUpOwoJCWlmIChlcnIpIHsKCQkJcmV0ID0gZXJyOwoJCQlnb3RvIGZyZWVfcGRjOwoJCX0KCX0KCXBtdS0+dHlwZSA9IHR5cGU7CgoJaWYgKHBtdV9idXNfcnVubmluZykgewoJCXJldCA9IHBtdV9kZXZfYWxsb2MocG11KTsKCQlpZiAocmV0KQoJCQlnb3RvIGZyZWVfaWRyOwoJfQoKc2tpcF90eXBlOgoJcG11LT5wbXVfY3B1X2NvbnRleHQgPSBmaW5kX3BtdV9jb250ZXh0KHBtdS0+dGFza19jdHhfbnIpOwoJaWYgKHBtdS0+cG11X2NwdV9jb250ZXh0KQoJCWdvdG8gZ290X2NwdV9jb250ZXh0OwoKCXBtdS0+cG11X2NwdV9jb250ZXh0ID0gYWxsb2NfcGVyY3B1KHN0cnVjdCBwZXJmX2NwdV9jb250ZXh0KTsKCWlmICghcG11LT5wbXVfY3B1X2NvbnRleHQpCgkJZ290byBmcmVlX2RldjsKCglmb3JfZWFjaF9wb3NzaWJsZV9jcHUoY3B1KSB7CgkJc3RydWN0IHBlcmZfY3B1X2NvbnRleHQgKmNwdWN0eDsKCgkJY3B1Y3R4ID0gcGVyX2NwdV9wdHIocG11LT5wbXVfY3B1X2NvbnRleHQsIGNwdSk7CgkJX19wZXJmX2V2ZW50X2luaXRfY29udGV4dCgmY3B1Y3R4LT5jdHgpOwoJCWNwdWN0eC0+Y3R4LnR5cGUgPSBjcHVfY29udGV4dDsKCQljcHVjdHgtPmN0eC5wbXUgPSBwbXU7CgkJY3B1Y3R4LT5qaWZmaWVzX2ludGVydmFsID0gMTsKCQlJTklUX0xJU1RfSEVBRCgmY3B1Y3R4LT5yb3RhdGlvbl9saXN0KTsKCQljcHVjdHgtPmFjdGl2ZV9wbXUgPSBwbXU7Cgl9Cgpnb3RfY3B1X2NvbnRleHQ6CglpZiAoIXBtdS0+c3RhcnRfdHhuKSB7CgkJaWYgKHBtdS0+cG11X2VuYWJsZSkgewoJCQkvKgoJCQkgKiBJZiB3ZSBoYXZlIHBtdV9lbmFibGUvcG11X2Rpc2FibGUgY2FsbHMsIGluc3RhbGwKCQkJICogdHJhbnNhY3Rpb24gc3R1YnMgdGhhdCB1c2UgdGhhdCB0byB0cnkgYW5kIGJhdGNoCgkJCSAqIGhhcmR3YXJlIGFjY2Vzc2VzLgoJCQkgKi8KCQkJcG11LT5zdGFydF90eG4gID0gcGVyZl9wbXVfc3RhcnRfdHhuOwoJCQlwbXUtPmNvbW1pdF90eG4gPSBwZXJmX3BtdV9jb21taXRfdHhuOwoJCQlwbXUtPmNhbmNlbF90eG4gPSBwZXJmX3BtdV9jYW5jZWxfdHhuOwoJCX0gZWxzZSB7CgkJCXBtdS0+c3RhcnRfdHhuICA9IHBlcmZfcG11X25vcF92b2lkOwoJCQlwbXUtPmNvbW1pdF90eG4gPSBwZXJmX3BtdV9ub3BfaW50OwoJCQlwbXUtPmNhbmNlbF90eG4gPSBwZXJmX3BtdV9ub3Bfdm9pZDsKCQl9Cgl9CgoJaWYgKCFwbXUtPnBtdV9lbmFibGUpIHsKCQlwbXUtPnBtdV9lbmFibGUgID0gcGVyZl9wbXVfbm9wX3ZvaWQ7CgkJcG11LT5wbXVfZGlzYWJsZSA9IHBlcmZfcG11X25vcF92b2lkOwoJfQoKCWxpc3RfYWRkX3JjdSgmcG11LT5lbnRyeSwgJnBtdXMpOwoJcmV0ID0gMDsKdW5sb2NrOgoJbXV0ZXhfdW5sb2NrKCZwbXVzX2xvY2spOwoKCXJldHVybiByZXQ7CgpmcmVlX2RldjoKCWRldmljZV9kZWwocG11LT5kZXYpOwoJcHV0X2RldmljZShwbXUtPmRldik7CgpmcmVlX2lkcjoKCWlmIChwbXUtPnR5cGUgPj0gUEVSRl9UWVBFX01BWCkKCQlpZHJfcmVtb3ZlKCZwbXVfaWRyLCBwbXUtPnR5cGUpOwoKZnJlZV9wZGM6CglmcmVlX3BlcmNwdShwbXUtPnBtdV9kaXNhYmxlX2NvdW50KTsKCWdvdG8gdW5sb2NrOwp9Cgp2b2lkIHBlcmZfcG11X3VucmVnaXN0ZXIoc3RydWN0IHBtdSAqcG11KQp7CgltdXRleF9sb2NrKCZwbXVzX2xvY2spOwoJbGlzdF9kZWxfcmN1KCZwbXUtPmVudHJ5KTsKCW11dGV4X3VubG9jaygmcG11c19sb2NrKTsKCgkvKgoJICogV2UgZGVyZWZlcmVuY2UgdGhlIHBtdSBsaXN0IHVuZGVyIGJvdGggU1JDVSBhbmQgcmVndWxhciBSQ1UsIHNvCgkgKiBzeW5jaHJvbml6ZSBhZ2FpbnN0IGJvdGggb2YgdGhvc2UuCgkgKi8KCXN5bmNocm9uaXplX3NyY3UoJnBtdXNfc3JjdSk7CglzeW5jaHJvbml6ZV9yY3UoKTsKCglmcmVlX3BlcmNwdShwbXUtPnBtdV9kaXNhYmxlX2NvdW50KTsKCWlmIChwbXUtPnR5cGUgPj0gUEVSRl9UWVBFX01BWCkKCQlpZHJfcmVtb3ZlKCZwbXVfaWRyLCBwbXUtPnR5cGUpOwoJZGV2aWNlX2RlbChwbXUtPmRldik7CglwdXRfZGV2aWNlKHBtdS0+ZGV2KTsKCWZyZWVfcG11X2NvbnRleHQocG11KTsKfQoKc3RydWN0IHBtdSAqcGVyZl9pbml0X2V2ZW50KHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCkKewoJc3RydWN0IHBtdSAqcG11ID0gTlVMTDsKCWludCBpZHg7CgoJaWR4ID0gc3JjdV9yZWFkX2xvY2soJnBtdXNfc3JjdSk7CgoJcmN1X3JlYWRfbG9jaygpOwoJcG11ID0gaWRyX2ZpbmQoJnBtdV9pZHIsIGV2ZW50LT5hdHRyLnR5cGUpOwoJcmN1X3JlYWRfdW5sb2NrKCk7CglpZiAocG11KQoJCWdvdG8gdW5sb2NrOwoKCWxpc3RfZm9yX2VhY2hfZW50cnlfcmN1KHBtdSwgJnBtdXMsIGVudHJ5KSB7CgkJaW50IHJldCA9IHBtdS0+ZXZlbnRfaW5pdChldmVudCk7CgkJaWYgKCFyZXQpCgkJCWdvdG8gdW5sb2NrOwoKCQlpZiAocmV0ICE9IC1FTk9FTlQpIHsKCQkJcG11ID0gRVJSX1BUUihyZXQpOwoJCQlnb3RvIHVubG9jazsKCQl9Cgl9CglwbXUgPSBFUlJfUFRSKC1FTk9FTlQpOwp1bmxvY2s6CglzcmN1X3JlYWRfdW5sb2NrKCZwbXVzX3NyY3UsIGlkeCk7CgoJcmV0dXJuIHBtdTsKfQoKLyoKICogQWxsb2NhdGUgYW5kIGluaXRpYWxpemUgYSBldmVudCBzdHJ1Y3R1cmUKICovCnN0YXRpYyBzdHJ1Y3QgcGVyZl9ldmVudCAqCnBlcmZfZXZlbnRfYWxsb2Moc3RydWN0IHBlcmZfZXZlbnRfYXR0ciAqYXR0ciwgaW50IGNwdSwKCQkgc3RydWN0IHRhc2tfc3RydWN0ICp0YXNrLAoJCSBzdHJ1Y3QgcGVyZl9ldmVudCAqZ3JvdXBfbGVhZGVyLAoJCSBzdHJ1Y3QgcGVyZl9ldmVudCAqcGFyZW50X2V2ZW50LAoJCSBwZXJmX292ZXJmbG93X2hhbmRsZXJfdCBvdmVyZmxvd19oYW5kbGVyKQp7CglzdHJ1Y3QgcG11ICpwbXU7CglzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQ7CglzdHJ1Y3QgaHdfcGVyZl9ldmVudCAqaHdjOwoJbG9uZyBlcnI7CgoJZXZlbnQgPSBremFsbG9jKHNpemVvZigqZXZlbnQpLCBHRlBfS0VSTkVMKTsKCWlmICghZXZlbnQpCgkJcmV0dXJuIEVSUl9QVFIoLUVOT01FTSk7CgoJLyoKCSAqIFNpbmdsZSBldmVudHMgYXJlIHRoZWlyIG93biBncm91cCBsZWFkZXJzLCB3aXRoIGFuCgkgKiBlbXB0eSBzaWJsaW5nIGxpc3Q6CgkgKi8KCWlmICghZ3JvdXBfbGVhZGVyKQoJCWdyb3VwX2xlYWRlciA9IGV2ZW50OwoKCW11dGV4X2luaXQoJmV2ZW50LT5jaGlsZF9tdXRleCk7CglJTklUX0xJU1RfSEVBRCgmZXZlbnQtPmNoaWxkX2xpc3QpOwoKCUlOSVRfTElTVF9IRUFEKCZldmVudC0+Z3JvdXBfZW50cnkpOwoJSU5JVF9MSVNUX0hFQUQoJmV2ZW50LT5ldmVudF9lbnRyeSk7CglJTklUX0xJU1RfSEVBRCgmZXZlbnQtPnNpYmxpbmdfbGlzdCk7Cglpbml0X3dhaXRxdWV1ZV9oZWFkKCZldmVudC0+d2FpdHEpOwoJaW5pdF9pcnFfd29yaygmZXZlbnQtPnBlbmRpbmcsIHBlcmZfcGVuZGluZ19ldmVudCk7CgoJbXV0ZXhfaW5pdCgmZXZlbnQtPm1tYXBfbXV0ZXgpOwoKCWV2ZW50LT5jcHUJCT0gY3B1OwoJZXZlbnQtPmF0dHIJCT0gKmF0dHI7CglldmVudC0+Z3JvdXBfbGVhZGVyCT0gZ3JvdXBfbGVhZGVyOwoJZXZlbnQtPnBtdQkJPSBOVUxMOwoJZXZlbnQtPm9uY3B1CQk9IC0xOwoKCWV2ZW50LT5wYXJlbnQJCT0gcGFyZW50X2V2ZW50OwoKCWV2ZW50LT5ucwkJPSBnZXRfcGlkX25zKGN1cnJlbnQtPm5zcHJveHktPnBpZF9ucyk7CglldmVudC0+aWQJCT0gYXRvbWljNjRfaW5jX3JldHVybigmcGVyZl9ldmVudF9pZCk7CgoJZXZlbnQtPnN0YXRlCQk9IFBFUkZfRVZFTlRfU1RBVEVfSU5BQ1RJVkU7CgoJaWYgKHRhc2spIHsKCQlldmVudC0+YXR0YWNoX3N0YXRlID0gUEVSRl9BVFRBQ0hfVEFTSzsKI2lmZGVmIENPTkZJR19IQVZFX0hXX0JSRUFLUE9JTlQKCQkvKgoJCSAqIGh3X2JyZWFrcG9pbnQgaXMgYSBiaXQgZGlmZmljdWx0IGhlcmUuLgoJCSAqLwoJCWlmIChhdHRyLT50eXBlID09IFBFUkZfVFlQRV9CUkVBS1BPSU5UKQoJCQlldmVudC0+aHcuYnBfdGFyZ2V0ID0gdGFzazsKI2VuZGlmCgl9CgoJaWYgKCFvdmVyZmxvd19oYW5kbGVyICYmIHBhcmVudF9ldmVudCkKCQlvdmVyZmxvd19oYW5kbGVyID0gcGFyZW50X2V2ZW50LT5vdmVyZmxvd19oYW5kbGVyOwoJCglldmVudC0+b3ZlcmZsb3dfaGFuZGxlcgk9IG92ZXJmbG93X2hhbmRsZXI7CgoJaWYgKGF0dHItPmRpc2FibGVkKQoJCWV2ZW50LT5zdGF0ZSA9IFBFUkZfRVZFTlRfU1RBVEVfT0ZGOwoKCXBtdSA9IE5VTEw7CgoJaHdjID0gJmV2ZW50LT5odzsKCWh3Yy0+c2FtcGxlX3BlcmlvZCA9IGF0dHItPnNhbXBsZV9wZXJpb2Q7CglpZiAoYXR0ci0+ZnJlcSAmJiBhdHRyLT5zYW1wbGVfZnJlcSkKCQlod2MtPnNhbXBsZV9wZXJpb2QgPSAxOwoJaHdjLT5sYXN0X3BlcmlvZCA9IGh3Yy0+c2FtcGxlX3BlcmlvZDsKCglsb2NhbDY0X3NldCgmaHdjLT5wZXJpb2RfbGVmdCwgaHdjLT5zYW1wbGVfcGVyaW9kKTsKCgkvKgoJICogd2UgY3VycmVudGx5IGRvIG5vdCBzdXBwb3J0IFBFUkZfRk9STUFUX0dST1VQIG9uIGluaGVyaXRlZCBldmVudHMKCSAqLwoJaWYgKGF0dHItPmluaGVyaXQgJiYgKGF0dHItPnJlYWRfZm9ybWF0ICYgUEVSRl9GT1JNQVRfR1JPVVApKQoJCWdvdG8gZG9uZTsKCglwbXUgPSBwZXJmX2luaXRfZXZlbnQoZXZlbnQpOwoKZG9uZToKCWVyciA9IDA7CglpZiAoIXBtdSkKCQllcnIgPSAtRUlOVkFMOwoJZWxzZSBpZiAoSVNfRVJSKHBtdSkpCgkJZXJyID0gUFRSX0VSUihwbXUpOwoKCWlmIChlcnIpIHsKCQlpZiAoZXZlbnQtPm5zKQoJCQlwdXRfcGlkX25zKGV2ZW50LT5ucyk7CgkJa2ZyZWUoZXZlbnQpOwoJCXJldHVybiBFUlJfUFRSKGVycik7Cgl9CgoJZXZlbnQtPnBtdSA9IHBtdTsKCglpZiAoIWV2ZW50LT5wYXJlbnQpIHsKCQlpZiAoZXZlbnQtPmF0dGFjaF9zdGF0ZSAmIFBFUkZfQVRUQUNIX1RBU0spCgkJCWp1bXBfbGFiZWxfaW5jKCZwZXJmX3Rhc2tfZXZlbnRzKTsKCQlpZiAoZXZlbnQtPmF0dHIubW1hcCB8fCBldmVudC0+YXR0ci5tbWFwX2RhdGEpCgkJCWF0b21pY19pbmMoJm5yX21tYXBfZXZlbnRzKTsKCQlpZiAoZXZlbnQtPmF0dHIuY29tbSkKCQkJYXRvbWljX2luYygmbnJfY29tbV9ldmVudHMpOwoJCWlmIChldmVudC0+YXR0ci50YXNrKQoJCQlhdG9taWNfaW5jKCZucl90YXNrX2V2ZW50cyk7CgkJaWYgKGV2ZW50LT5hdHRyLnNhbXBsZV90eXBlICYgUEVSRl9TQU1QTEVfQ0FMTENIQUlOKSB7CgkJCWVyciA9IGdldF9jYWxsY2hhaW5fYnVmZmVycygpOwoJCQlpZiAoZXJyKSB7CgkJCQlmcmVlX2V2ZW50KGV2ZW50KTsKCQkJCXJldHVybiBFUlJfUFRSKGVycik7CgkJCX0KCQl9Cgl9CgoJcmV0dXJuIGV2ZW50Owp9CgpzdGF0aWMgaW50IHBlcmZfY29weV9hdHRyKHN0cnVjdCBwZXJmX2V2ZW50X2F0dHIgX191c2VyICp1YXR0ciwKCQkJICBzdHJ1Y3QgcGVyZl9ldmVudF9hdHRyICphdHRyKQp7Cgl1MzIgc2l6ZTsKCWludCByZXQ7CgoJaWYgKCFhY2Nlc3Nfb2soVkVSSUZZX1dSSVRFLCB1YXR0ciwgUEVSRl9BVFRSX1NJWkVfVkVSMCkpCgkJcmV0dXJuIC1FRkFVTFQ7CgoJLyoKCSAqIHplcm8gdGhlIGZ1bGwgc3RydWN0dXJlLCBzbyB0aGF0IGEgc2hvcnQgY29weSB3aWxsIGJlIG5pY2UuCgkgKi8KCW1lbXNldChhdHRyLCAwLCBzaXplb2YoKmF0dHIpKTsKCglyZXQgPSBnZXRfdXNlcihzaXplLCAmdWF0dHItPnNpemUpOwoJaWYgKHJldCkKCQlyZXR1cm4gcmV0OwoKCWlmIChzaXplID4gUEFHRV9TSVpFKQkvKiBzaWxseSBsYXJnZSAqLwoJCWdvdG8gZXJyX3NpemU7CgoJaWYgKCFzaXplKQkJLyogYWJpIGNvbXBhdCAqLwoJCXNpemUgPSBQRVJGX0FUVFJfU0laRV9WRVIwOwoKCWlmIChzaXplIDwgUEVSRl9BVFRSX1NJWkVfVkVSMCkKCQlnb3RvIGVycl9zaXplOwoKCS8qCgkgKiBJZiB3ZSdyZSBoYW5kZWQgYSBiaWdnZXIgc3RydWN0IHRoYW4gd2Uga25vdyBvZiwKCSAqIGVuc3VyZSBhbGwgdGhlIHVua25vd24gYml0cyBhcmUgMCAtIGkuZS4gbmV3CgkgKiB1c2VyLXNwYWNlIGRvZXMgbm90IHJlbHkgb24gYW55IGtlcm5lbCBmZWF0dXJlCgkgKiBleHRlbnNpb25zIHdlIGRvbnQga25vdyBhYm91dCB5ZXQuCgkgKi8KCWlmIChzaXplID4gc2l6ZW9mKCphdHRyKSkgewoJCXVuc2lnbmVkIGNoYXIgX191c2VyICphZGRyOwoJCXVuc2lnbmVkIGNoYXIgX191c2VyICplbmQ7CgkJdW5zaWduZWQgY2hhciB2YWw7CgoJCWFkZHIgPSAodm9pZCBfX3VzZXIgKil1YXR0ciArIHNpemVvZigqYXR0cik7CgkJZW5kICA9ICh2b2lkIF9fdXNlciAqKXVhdHRyICsgc2l6ZTsKCgkJZm9yICg7IGFkZHIgPCBlbmQ7IGFkZHIrKykgewoJCQlyZXQgPSBnZXRfdXNlcih2YWwsIGFkZHIpOwoJCQlpZiAocmV0KQoJCQkJcmV0dXJuIHJldDsKCQkJaWYgKHZhbCkKCQkJCWdvdG8gZXJyX3NpemU7CgkJfQoJCXNpemUgPSBzaXplb2YoKmF0dHIpOwoJfQoKCXJldCA9IGNvcHlfZnJvbV91c2VyKGF0dHIsIHVhdHRyLCBzaXplKTsKCWlmIChyZXQpCgkJcmV0dXJuIC1FRkFVTFQ7CgoJLyoKCSAqIElmIHRoZSB0eXBlIGV4aXN0cywgdGhlIGNvcnJlc3BvbmRpbmcgY3JlYXRpb24gd2lsbCB2ZXJpZnkKCSAqIHRoZSBhdHRyLT5jb25maWcuCgkgKi8KCWlmIChhdHRyLT50eXBlID49IFBFUkZfVFlQRV9NQVgpCgkJcmV0dXJuIC1FSU5WQUw7CgoJaWYgKGF0dHItPl9fcmVzZXJ2ZWRfMSkKCQlyZXR1cm4gLUVJTlZBTDsKCglpZiAoYXR0ci0+c2FtcGxlX3R5cGUgJiB+KFBFUkZfU0FNUExFX01BWC0xKSkKCQlyZXR1cm4gLUVJTlZBTDsKCglpZiAoYXR0ci0+cmVhZF9mb3JtYXQgJiB+KFBFUkZfRk9STUFUX01BWC0xKSkKCQlyZXR1cm4gLUVJTlZBTDsKCm91dDoKCXJldHVybiByZXQ7CgplcnJfc2l6ZToKCXB1dF91c2VyKHNpemVvZigqYXR0ciksICZ1YXR0ci0+c2l6ZSk7CglyZXQgPSAtRTJCSUc7Cglnb3RvIG91dDsKfQoKc3RhdGljIGludApwZXJmX2V2ZW50X3NldF9vdXRwdXQoc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50LCBzdHJ1Y3QgcGVyZl9ldmVudCAqb3V0cHV0X2V2ZW50KQp7CglzdHJ1Y3QgcGVyZl9idWZmZXIgKmJ1ZmZlciA9IE5VTEwsICpvbGRfYnVmZmVyID0gTlVMTDsKCWludCByZXQgPSAtRUlOVkFMOwoKCWlmICghb3V0cHV0X2V2ZW50KQoJCWdvdG8gc2V0OwoKCS8qIGRvbid0IGFsbG93IGNpcmN1bGFyIHJlZmVyZW5jZXMgKi8KCWlmIChldmVudCA9PSBvdXRwdXRfZXZlbnQpCgkJZ290byBvdXQ7CgoJLyoKCSAqIERvbid0IGFsbG93IGNyb3NzLWNwdSBidWZmZXJzCgkgKi8KCWlmIChvdXRwdXRfZXZlbnQtPmNwdSAhPSBldmVudC0+Y3B1KQoJCWdvdG8gb3V0OwoKCS8qCgkgKiBJZiBpdHMgbm90IGEgcGVyLWNwdSBidWZmZXIsIGl0IG11c3QgYmUgdGhlIHNhbWUgdGFzay4KCSAqLwoJaWYgKG91dHB1dF9ldmVudC0+Y3B1ID09IC0xICYmIG91dHB1dF9ldmVudC0+Y3R4ICE9IGV2ZW50LT5jdHgpCgkJZ290byBvdXQ7CgpzZXQ6CgltdXRleF9sb2NrKCZldmVudC0+bW1hcF9tdXRleCk7CgkvKiBDYW4ndCByZWRpcmVjdCBvdXRwdXQgaWYgd2UndmUgZ290IGFuIGFjdGl2ZSBtbWFwKCkgKi8KCWlmIChhdG9taWNfcmVhZCgmZXZlbnQtPm1tYXBfY291bnQpKQoJCWdvdG8gdW5sb2NrOwoKCWlmIChvdXRwdXRfZXZlbnQpIHsKCQkvKiBnZXQgdGhlIGJ1ZmZlciB3ZSB3YW50IHRvIHJlZGlyZWN0IHRvICovCgkJYnVmZmVyID0gcGVyZl9idWZmZXJfZ2V0KG91dHB1dF9ldmVudCk7CgkJaWYgKCFidWZmZXIpCgkJCWdvdG8gdW5sb2NrOwoJfQoKCW9sZF9idWZmZXIgPSBldmVudC0+YnVmZmVyOwoJcmN1X2Fzc2lnbl9wb2ludGVyKGV2ZW50LT5idWZmZXIsIGJ1ZmZlcik7CglyZXQgPSAwOwp1bmxvY2s6CgltdXRleF91bmxvY2soJmV2ZW50LT5tbWFwX211dGV4KTsKCglpZiAob2xkX2J1ZmZlcikKCQlwZXJmX2J1ZmZlcl9wdXQob2xkX2J1ZmZlcik7Cm91dDoKCXJldHVybiByZXQ7Cn0KCi8qKgogKiBzeXNfcGVyZl9ldmVudF9vcGVuIC0gb3BlbiBhIHBlcmZvcm1hbmNlIGV2ZW50LCBhc3NvY2lhdGUgaXQgdG8gYSB0YXNrL2NwdQogKgogKiBAYXR0cl91cHRyOglldmVudF9pZCB0eXBlIGF0dHJpYnV0ZXMgZm9yIG1vbml0b3Jpbmcvc2FtcGxpbmcKICogQHBpZDoJCXRhcmdldCBwaWQKICogQGNwdToJCXRhcmdldCBjcHUKICogQGdyb3VwX2ZkOgkJZ3JvdXAgbGVhZGVyIGV2ZW50IGZkCiAqLwpTWVNDQUxMX0RFRklORTUocGVyZl9ldmVudF9vcGVuLAoJCXN0cnVjdCBwZXJmX2V2ZW50X2F0dHIgX191c2VyICosIGF0dHJfdXB0ciwKCQlwaWRfdCwgcGlkLCBpbnQsIGNwdSwgaW50LCBncm91cF9mZCwgdW5zaWduZWQgbG9uZywgZmxhZ3MpCnsKCXN0cnVjdCBwZXJmX2V2ZW50ICpncm91cF9sZWFkZXIgPSBOVUxMLCAqb3V0cHV0X2V2ZW50ID0gTlVMTDsKCXN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCwgKnNpYmxpbmc7CglzdHJ1Y3QgcGVyZl9ldmVudF9hdHRyIGF0dHI7CglzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0ICpjdHg7CglzdHJ1Y3QgZmlsZSAqZXZlbnRfZmlsZSA9IE5VTEw7CglzdHJ1Y3QgZmlsZSAqZ3JvdXBfZmlsZSA9IE5VTEw7CglzdHJ1Y3QgdGFza19zdHJ1Y3QgKnRhc2sgPSBOVUxMOwoJc3RydWN0IHBtdSAqcG11OwoJaW50IGV2ZW50X2ZkOwoJaW50IG1vdmVfZ3JvdXAgPSAwOwoJaW50IGZwdXRfbmVlZGVkID0gMDsKCWludCBlcnI7CgoJLyogZm9yIGZ1dHVyZSBleHBhbmRhYmlsaXR5Li4uICovCglpZiAoZmxhZ3MgJiB+KFBFUkZfRkxBR19GRF9OT19HUk9VUCB8IFBFUkZfRkxBR19GRF9PVVRQVVQpKQoJCXJldHVybiAtRUlOVkFMOwoKCWVyciA9IHBlcmZfY29weV9hdHRyKGF0dHJfdXB0ciwgJmF0dHIpOwoJaWYgKGVycikKCQlyZXR1cm4gZXJyOwoKCWlmICghYXR0ci5leGNsdWRlX2tlcm5lbCkgewoJCWlmIChwZXJmX3BhcmFub2lkX2tlcm5lbCgpICYmICFjYXBhYmxlKENBUF9TWVNfQURNSU4pKQoJCQlyZXR1cm4gLUVBQ0NFUzsKCX0KCglpZiAoYXR0ci5mcmVxKSB7CgkJaWYgKGF0dHIuc2FtcGxlX2ZyZXEgPiBzeXNjdGxfcGVyZl9ldmVudF9zYW1wbGVfcmF0ZSkKCQkJcmV0dXJuIC1FSU5WQUw7Cgl9CgoJZXZlbnRfZmQgPSBnZXRfdW51c2VkX2ZkX2ZsYWdzKE9fUkRXUik7CglpZiAoZXZlbnRfZmQgPCAwKQoJCXJldHVybiBldmVudF9mZDsKCglpZiAoZ3JvdXBfZmQgIT0gLTEpIHsKCQlncm91cF9sZWFkZXIgPSBwZXJmX2ZnZXRfbGlnaHQoZ3JvdXBfZmQsICZmcHV0X25lZWRlZCk7CgkJaWYgKElTX0VSUihncm91cF9sZWFkZXIpKSB7CgkJCWVyciA9IFBUUl9FUlIoZ3JvdXBfbGVhZGVyKTsKCQkJZ290byBlcnJfZmQ7CgkJfQoJCWdyb3VwX2ZpbGUgPSBncm91cF9sZWFkZXItPmZpbHA7CgkJaWYgKGZsYWdzICYgUEVSRl9GTEFHX0ZEX09VVFBVVCkKCQkJb3V0cHV0X2V2ZW50ID0gZ3JvdXBfbGVhZGVyOwoJCWlmIChmbGFncyAmIFBFUkZfRkxBR19GRF9OT19HUk9VUCkKCQkJZ3JvdXBfbGVhZGVyID0gTlVMTDsKCX0KCglpZiAocGlkICE9IC0xKSB7CgkJdGFzayA9IGZpbmRfbGl2ZWx5X3Rhc2tfYnlfdnBpZChwaWQpOwoJCWlmIChJU19FUlIodGFzaykpIHsKCQkJZXJyID0gUFRSX0VSUih0YXNrKTsKCQkJZ290byBlcnJfZ3JvdXBfZmQ7CgkJfQoJfQoKCWV2ZW50ID0gcGVyZl9ldmVudF9hbGxvYygmYXR0ciwgY3B1LCB0YXNrLCBncm91cF9sZWFkZXIsIE5VTEwsIE5VTEwpOwoJaWYgKElTX0VSUihldmVudCkpIHsKCQllcnIgPSBQVFJfRVJSKGV2ZW50KTsKCQlnb3RvIGVycl90YXNrOwoJfQoKCS8qCgkgKiBTcGVjaWFsIGNhc2Ugc29mdHdhcmUgZXZlbnRzIGFuZCBhbGxvdyB0aGVtIHRvIGJlIHBhcnQgb2YKCSAqIGFueSBoYXJkd2FyZSBncm91cC4KCSAqLwoJcG11ID0gZXZlbnQtPnBtdTsKCglpZiAoZ3JvdXBfbGVhZGVyICYmCgkgICAgKGlzX3NvZnR3YXJlX2V2ZW50KGV2ZW50KSAhPSBpc19zb2Z0d2FyZV9ldmVudChncm91cF9sZWFkZXIpKSkgewoJCWlmIChpc19zb2Z0d2FyZV9ldmVudChldmVudCkpIHsKCQkJLyoKCQkJICogSWYgZXZlbnQgYW5kIGdyb3VwX2xlYWRlciBhcmUgbm90IGJvdGggYSBzb2Z0d2FyZQoJCQkgKiBldmVudCwgYW5kIGV2ZW50IGlzLCB0aGVuIGdyb3VwIGxlYWRlciBpcyBub3QuCgkJCSAqCgkJCSAqIEFsbG93IHRoZSBhZGRpdGlvbiBvZiBzb2Z0d2FyZSBldmVudHMgdG8gIXNvZnR3YXJlCgkJCSAqIGdyb3VwcywgdGhpcyBpcyBzYWZlIGJlY2F1c2Ugc29mdHdhcmUgZXZlbnRzIG5ldmVyCgkJCSAqIGZhaWwgdG8gc2NoZWR1bGUuCgkJCSAqLwoJCQlwbXUgPSBncm91cF9sZWFkZXItPnBtdTsKCQl9IGVsc2UgaWYgKGlzX3NvZnR3YXJlX2V2ZW50KGdyb3VwX2xlYWRlcikgJiYKCQkJICAgKGdyb3VwX2xlYWRlci0+Z3JvdXBfZmxhZ3MgJiBQRVJGX0dST1VQX1NPRlRXQVJFKSkgewoJCQkvKgoJCQkgKiBJbiBjYXNlIHRoZSBncm91cCBpcyBhIHB1cmUgc29mdHdhcmUgZ3JvdXAsIGFuZCB3ZQoJCQkgKiB0cnkgdG8gYWRkIGEgaGFyZHdhcmUgZXZlbnQsIG1vdmUgdGhlIHdob2xlIGdyb3VwIHRvCgkJCSAqIHRoZSBoYXJkd2FyZSBjb250ZXh0LgoJCQkgKi8KCQkJbW92ZV9ncm91cCA9IDE7CgkJfQoJfQoKCS8qCgkgKiBHZXQgdGhlIHRhcmdldCBjb250ZXh0ICh0YXNrIG9yIHBlcmNwdSk6CgkgKi8KCWN0eCA9IGZpbmRfZ2V0X2NvbnRleHQocG11LCB0YXNrLCBjcHUpOwoJaWYgKElTX0VSUihjdHgpKSB7CgkJZXJyID0gUFRSX0VSUihjdHgpOwoJCWdvdG8gZXJyX2FsbG9jOwoJfQoKCS8qCgkgKiBMb29rIHVwIHRoZSBncm91cCBsZWFkZXIgKHdlIHdpbGwgYXR0YWNoIHRoaXMgZXZlbnQgdG8gaXQpOgoJICovCglpZiAoZ3JvdXBfbGVhZGVyKSB7CgkJZXJyID0gLUVJTlZBTDsKCgkJLyoKCQkgKiBEbyBub3QgYWxsb3cgYSByZWN1cnNpdmUgaGllcmFyY2h5ICh0aGlzIG5ldyBzaWJsaW5nCgkJICogYmVjb21pbmcgcGFydCBvZiBhbm90aGVyIGdyb3VwLXNpYmxpbmcpOgoJCSAqLwoJCWlmIChncm91cF9sZWFkZXItPmdyb3VwX2xlYWRlciAhPSBncm91cF9sZWFkZXIpCgkJCWdvdG8gZXJyX2NvbnRleHQ7CgkJLyoKCQkgKiBEbyBub3QgYWxsb3cgdG8gYXR0YWNoIHRvIGEgZ3JvdXAgaW4gYSBkaWZmZXJlbnQKCQkgKiB0YXNrIG9yIENQVSBjb250ZXh0OgoJCSAqLwoJCWlmIChtb3ZlX2dyb3VwKSB7CgkJCWlmIChncm91cF9sZWFkZXItPmN0eC0+dHlwZSAhPSBjdHgtPnR5cGUpCgkJCQlnb3RvIGVycl9jb250ZXh0OwoJCX0gZWxzZSB7CgkJCWlmIChncm91cF9sZWFkZXItPmN0eCAhPSBjdHgpCgkJCQlnb3RvIGVycl9jb250ZXh0OwoJCX0KCgkJLyoKCQkgKiBPbmx5IGEgZ3JvdXAgbGVhZGVyIGNhbiBiZSBleGNsdXNpdmUgb3IgcGlubmVkCgkJICovCgkJaWYgKGF0dHIuZXhjbHVzaXZlIHx8IGF0dHIucGlubmVkKQoJCQlnb3RvIGVycl9jb250ZXh0OwoJfQoKCWlmIChvdXRwdXRfZXZlbnQpIHsKCQllcnIgPSBwZXJmX2V2ZW50X3NldF9vdXRwdXQoZXZlbnQsIG91dHB1dF9ldmVudCk7CgkJaWYgKGVycikKCQkJZ290byBlcnJfY29udGV4dDsKCX0KCglldmVudF9maWxlID0gYW5vbl9pbm9kZV9nZXRmaWxlKCJbcGVyZl9ldmVudF0iLCAmcGVyZl9mb3BzLCBldmVudCwgT19SRFdSKTsKCWlmIChJU19FUlIoZXZlbnRfZmlsZSkpIHsKCQllcnIgPSBQVFJfRVJSKGV2ZW50X2ZpbGUpOwoJCWdvdG8gZXJyX2NvbnRleHQ7Cgl9CgoJaWYgKG1vdmVfZ3JvdXApIHsKCQlzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0ICpnY3R4ID0gZ3JvdXBfbGVhZGVyLT5jdHg7CgoJCW11dGV4X2xvY2soJmdjdHgtPm11dGV4KTsKCQlwZXJmX2V2ZW50X3JlbW92ZV9mcm9tX2NvbnRleHQoZ3JvdXBfbGVhZGVyKTsKCQlsaXN0X2Zvcl9lYWNoX2VudHJ5KHNpYmxpbmcsICZncm91cF9sZWFkZXItPnNpYmxpbmdfbGlzdCwKCQkJCSAgICBncm91cF9lbnRyeSkgewoJCQlwZXJmX2V2ZW50X3JlbW92ZV9mcm9tX2NvbnRleHQoc2libGluZyk7CgkJCXB1dF9jdHgoZ2N0eCk7CgkJfQoJCW11dGV4X3VubG9jaygmZ2N0eC0+bXV0ZXgpOwoJCXB1dF9jdHgoZ2N0eCk7Cgl9CgoJZXZlbnQtPmZpbHAgPSBldmVudF9maWxlOwoJV0FSTl9PTl9PTkNFKGN0eC0+cGFyZW50X2N0eCk7CgltdXRleF9sb2NrKCZjdHgtPm11dGV4KTsKCglpZiAobW92ZV9ncm91cCkgewoJCXBlcmZfaW5zdGFsbF9pbl9jb250ZXh0KGN0eCwgZ3JvdXBfbGVhZGVyLCBjcHUpOwoJCWdldF9jdHgoY3R4KTsKCQlsaXN0X2Zvcl9lYWNoX2VudHJ5KHNpYmxpbmcsICZncm91cF9sZWFkZXItPnNpYmxpbmdfbGlzdCwKCQkJCSAgICBncm91cF9lbnRyeSkgewoJCQlwZXJmX2luc3RhbGxfaW5fY29udGV4dChjdHgsIHNpYmxpbmcsIGNwdSk7CgkJCWdldF9jdHgoY3R4KTsKCQl9Cgl9CgoJcGVyZl9pbnN0YWxsX2luX2NvbnRleHQoY3R4LCBldmVudCwgY3B1KTsKCSsrY3R4LT5nZW5lcmF0aW9uOwoJbXV0ZXhfdW5sb2NrKCZjdHgtPm11dGV4KTsKCglldmVudC0+b3duZXIgPSBjdXJyZW50OwoKCW11dGV4X2xvY2soJmN1cnJlbnQtPnBlcmZfZXZlbnRfbXV0ZXgpOwoJbGlzdF9hZGRfdGFpbCgmZXZlbnQtPm93bmVyX2VudHJ5LCAmY3VycmVudC0+cGVyZl9ldmVudF9saXN0KTsKCW11dGV4X3VubG9jaygmY3VycmVudC0+cGVyZl9ldmVudF9tdXRleCk7CgoJLyoKCSAqIFByZWNhbGN1bGF0ZSBzYW1wbGVfZGF0YSBzaXplcwoJICovCglwZXJmX2V2ZW50X19oZWFkZXJfc2l6ZShldmVudCk7CglwZXJmX2V2ZW50X19pZF9oZWFkZXJfc2l6ZShldmVudCk7CgoJLyoKCSAqIERyb3AgdGhlIHJlZmVyZW5jZSBvbiB0aGUgZ3JvdXBfZXZlbnQgYWZ0ZXIgcGxhY2luZyB0aGUKCSAqIG5ldyBldmVudCBvbiB0aGUgc2libGluZ19saXN0LiBUaGlzIGVuc3VyZXMgZGVzdHJ1Y3Rpb24KCSAqIG9mIHRoZSBncm91cCBsZWFkZXIgd2lsbCBmaW5kIHRoZSBwb2ludGVyIHRvIGl0c2VsZiBpbgoJICogcGVyZl9ncm91cF9kZXRhY2goKS4KCSAqLwoJZnB1dF9saWdodChncm91cF9maWxlLCBmcHV0X25lZWRlZCk7CglmZF9pbnN0YWxsKGV2ZW50X2ZkLCBldmVudF9maWxlKTsKCXJldHVybiBldmVudF9mZDsKCmVycl9jb250ZXh0OgoJcHV0X2N0eChjdHgpOwplcnJfYWxsb2M6CglmcmVlX2V2ZW50KGV2ZW50KTsKZXJyX3Rhc2s6CglpZiAodGFzaykKCQlwdXRfdGFza19zdHJ1Y3QodGFzayk7CmVycl9ncm91cF9mZDoKCWZwdXRfbGlnaHQoZ3JvdXBfZmlsZSwgZnB1dF9uZWVkZWQpOwplcnJfZmQ6CglwdXRfdW51c2VkX2ZkKGV2ZW50X2ZkKTsKCXJldHVybiBlcnI7Cn0KCi8qKgogKiBwZXJmX2V2ZW50X2NyZWF0ZV9rZXJuZWxfY291bnRlcgogKgogKiBAYXR0cjogYXR0cmlidXRlcyBvZiB0aGUgY291bnRlciB0byBjcmVhdGUKICogQGNwdTogY3B1IGluIHdoaWNoIHRoZSBjb3VudGVyIGlzIGJvdW5kCiAqIEB0YXNrOiB0YXNrIHRvIHByb2ZpbGUgKE5VTEwgZm9yIHBlcmNwdSkKICovCnN0cnVjdCBwZXJmX2V2ZW50ICoKcGVyZl9ldmVudF9jcmVhdGVfa2VybmVsX2NvdW50ZXIoc3RydWN0IHBlcmZfZXZlbnRfYXR0ciAqYXR0ciwgaW50IGNwdSwKCQkJCSBzdHJ1Y3QgdGFza19zdHJ1Y3QgKnRhc2ssCgkJCQkgcGVyZl9vdmVyZmxvd19oYW5kbGVyX3Qgb3ZlcmZsb3dfaGFuZGxlcikKewoJc3RydWN0IHBlcmZfZXZlbnRfY29udGV4dCAqY3R4OwoJc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50OwoJaW50IGVycjsKCgkvKgoJICogR2V0IHRoZSB0YXJnZXQgY29udGV4dCAodGFzayBvciBwZXJjcHUpOgoJICovCgoJZXZlbnQgPSBwZXJmX2V2ZW50X2FsbG9jKGF0dHIsIGNwdSwgdGFzaywgTlVMTCwgTlVMTCwgb3ZlcmZsb3dfaGFuZGxlcik7CglpZiAoSVNfRVJSKGV2ZW50KSkgewoJCWVyciA9IFBUUl9FUlIoZXZlbnQpOwoJCWdvdG8gZXJyOwoJfQoKCWN0eCA9IGZpbmRfZ2V0X2NvbnRleHQoZXZlbnQtPnBtdSwgdGFzaywgY3B1KTsKCWlmIChJU19FUlIoY3R4KSkgewoJCWVyciA9IFBUUl9FUlIoY3R4KTsKCQlnb3RvIGVycl9mcmVlOwoJfQoKCWV2ZW50LT5maWxwID0gTlVMTDsKCVdBUk5fT05fT05DRShjdHgtPnBhcmVudF9jdHgpOwoJbXV0ZXhfbG9jaygmY3R4LT5tdXRleCk7CglwZXJmX2luc3RhbGxfaW5fY29udGV4dChjdHgsIGV2ZW50LCBjcHUpOwoJKytjdHgtPmdlbmVyYXRpb247CgltdXRleF91bmxvY2soJmN0eC0+bXV0ZXgpOwoKCXJldHVybiBldmVudDsKCmVycl9mcmVlOgoJZnJlZV9ldmVudChldmVudCk7CmVycjoKCXJldHVybiBFUlJfUFRSKGVycik7Cn0KRVhQT1JUX1NZTUJPTF9HUEwocGVyZl9ldmVudF9jcmVhdGVfa2VybmVsX2NvdW50ZXIpOwoKc3RhdGljIHZvaWQgc3luY19jaGlsZF9ldmVudChzdHJ1Y3QgcGVyZl9ldmVudCAqY2hpbGRfZXZlbnQsCgkJCSAgICAgICBzdHJ1Y3QgdGFza19zdHJ1Y3QgKmNoaWxkKQp7CglzdHJ1Y3QgcGVyZl9ldmVudCAqcGFyZW50X2V2ZW50ID0gY2hpbGRfZXZlbnQtPnBhcmVudDsKCXU2NCBjaGlsZF92YWw7CgoJaWYgKGNoaWxkX2V2ZW50LT5hdHRyLmluaGVyaXRfc3RhdCkKCQlwZXJmX2V2ZW50X3JlYWRfZXZlbnQoY2hpbGRfZXZlbnQsIGNoaWxkKTsKCgljaGlsZF92YWwgPSBwZXJmX2V2ZW50X2NvdW50KGNoaWxkX2V2ZW50KTsKCgkvKgoJICogQWRkIGJhY2sgdGhlIGNoaWxkJ3MgY291bnQgdG8gdGhlIHBhcmVudCdzIGNvdW50OgoJICovCglhdG9taWM2NF9hZGQoY2hpbGRfdmFsLCAmcGFyZW50X2V2ZW50LT5jaGlsZF9jb3VudCk7CglhdG9taWM2NF9hZGQoY2hpbGRfZXZlbnQtPnRvdGFsX3RpbWVfZW5hYmxlZCwKCQkgICAgICZwYXJlbnRfZXZlbnQtPmNoaWxkX3RvdGFsX3RpbWVfZW5hYmxlZCk7CglhdG9taWM2NF9hZGQoY2hpbGRfZXZlbnQtPnRvdGFsX3RpbWVfcnVubmluZywKCQkgICAgICZwYXJlbnRfZXZlbnQtPmNoaWxkX3RvdGFsX3RpbWVfcnVubmluZyk7CgoJLyoKCSAqIFJlbW92ZSB0aGlzIGV2ZW50IGZyb20gdGhlIHBhcmVudCdzIGxpc3QKCSAqLwoJV0FSTl9PTl9PTkNFKHBhcmVudF9ldmVudC0+Y3R4LT5wYXJlbnRfY3R4KTsKCW11dGV4X2xvY2soJnBhcmVudF9ldmVudC0+Y2hpbGRfbXV0ZXgpOwoJbGlzdF9kZWxfaW5pdCgmY2hpbGRfZXZlbnQtPmNoaWxkX2xpc3QpOwoJbXV0ZXhfdW5sb2NrKCZwYXJlbnRfZXZlbnQtPmNoaWxkX211dGV4KTsKCgkvKgoJICogUmVsZWFzZSB0aGUgcGFyZW50IGV2ZW50LCBpZiB0aGlzIHdhcyB0aGUgbGFzdAoJICogcmVmZXJlbmNlIHRvIGl0LgoJICovCglmcHV0KHBhcmVudF9ldmVudC0+ZmlscCk7Cn0KCnN0YXRpYyB2b2lkCl9fcGVyZl9ldmVudF9leGl0X3Rhc2soc3RydWN0IHBlcmZfZXZlbnQgKmNoaWxkX2V2ZW50LAoJCQkgc3RydWN0IHBlcmZfZXZlbnRfY29udGV4dCAqY2hpbGRfY3R4LAoJCQkgc3RydWN0IHRhc2tfc3RydWN0ICpjaGlsZCkKewoJc3RydWN0IHBlcmZfZXZlbnQgKnBhcmVudF9ldmVudDsKCglwZXJmX2V2ZW50X3JlbW92ZV9mcm9tX2NvbnRleHQoY2hpbGRfZXZlbnQpOwoKCXBhcmVudF9ldmVudCA9IGNoaWxkX2V2ZW50LT5wYXJlbnQ7CgkvKgoJICogSXQgY2FuIGhhcHBlbiB0aGF0IHBhcmVudCBleGl0cyBmaXJzdCwgYW5kIGhhcyBldmVudHMKCSAqIHRoYXQgYXJlIHN0aWxsIGFyb3VuZCBkdWUgdG8gdGhlIGNoaWxkIHJlZmVyZW5jZS4gVGhlc2UKCSAqIGV2ZW50cyBuZWVkIHRvIGJlIHphcHBlZCAtIGJ1dCBvdGhlcndpc2UgbGluZ2VyLgoJICovCglpZiAocGFyZW50X2V2ZW50KSB7CgkJc3luY19jaGlsZF9ldmVudChjaGlsZF9ldmVudCwgY2hpbGQpOwoJCWZyZWVfZXZlbnQoY2hpbGRfZXZlbnQpOwoJfQp9CgpzdGF0aWMgdm9pZCBwZXJmX2V2ZW50X2V4aXRfdGFza19jb250ZXh0KHN0cnVjdCB0YXNrX3N0cnVjdCAqY2hpbGQsIGludCBjdHhuKQp7CglzdHJ1Y3QgcGVyZl9ldmVudCAqY2hpbGRfZXZlbnQsICp0bXA7CglzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0ICpjaGlsZF9jdHg7Cgl1bnNpZ25lZCBsb25nIGZsYWdzOwoKCWlmIChsaWtlbHkoIWNoaWxkLT5wZXJmX2V2ZW50X2N0eHBbY3R4bl0pKSB7CgkJcGVyZl9ldmVudF90YXNrKGNoaWxkLCBOVUxMLCAwKTsKCQlyZXR1cm47Cgl9CgoJbG9jYWxfaXJxX3NhdmUoZmxhZ3MpOwoJLyoKCSAqIFdlIGNhbid0IHJlc2NoZWR1bGUgaGVyZSBiZWNhdXNlIGludGVycnVwdHMgYXJlIGRpc2FibGVkLAoJICogYW5kIGVpdGhlciBjaGlsZCBpcyBjdXJyZW50IG9yIGl0IGlzIGEgdGFzayB0aGF0IGNhbid0IGJlCgkgKiBzY2hlZHVsZWQsIHNvIHdlIGFyZSBub3cgc2FmZSBmcm9tIHJlc2NoZWR1bGluZyBjaGFuZ2luZwoJICogb3VyIGNvbnRleHQuCgkgKi8KCWNoaWxkX2N0eCA9IGNoaWxkLT5wZXJmX2V2ZW50X2N0eHBbY3R4bl07Cgl0YXNrX2N0eF9zY2hlZF9vdXQoY2hpbGRfY3R4LCBFVkVOVF9BTEwpOwoKCS8qCgkgKiBUYWtlIHRoZSBjb250ZXh0IGxvY2sgaGVyZSBzbyB0aGF0IGlmIGZpbmRfZ2V0X2NvbnRleHQgaXMKCSAqIHJlYWRpbmcgY2hpbGQtPnBlcmZfZXZlbnRfY3R4cCwgd2Ugd2FpdCB1bnRpbCBpdCBoYXMKCSAqIGluY3JlbWVudGVkIHRoZSBjb250ZXh0J3MgcmVmY291bnQgYmVmb3JlIHdlIGRvIHB1dF9jdHggYmVsb3cuCgkgKi8KCXJhd19zcGluX2xvY2soJmNoaWxkX2N0eC0+bG9jayk7CgljaGlsZC0+cGVyZl9ldmVudF9jdHhwW2N0eG5dID0gTlVMTDsKCS8qCgkgKiBJZiB0aGlzIGNvbnRleHQgaXMgYSBjbG9uZTsgdW5jbG9uZSBpdCBzbyBpdCBjYW4ndCBnZXQKCSAqIHN3YXBwZWQgdG8gYW5vdGhlciBwcm9jZXNzIHdoaWxlIHdlJ3JlIHJlbW92aW5nIGFsbAoJICogdGhlIGV2ZW50cyBmcm9tIGl0LgoJICovCgl1bmNsb25lX2N0eChjaGlsZF9jdHgpOwoJdXBkYXRlX2NvbnRleHRfdGltZShjaGlsZF9jdHgpOwoJcmF3X3NwaW5fdW5sb2NrX2lycXJlc3RvcmUoJmNoaWxkX2N0eC0+bG9jaywgZmxhZ3MpOwoKCS8qCgkgKiBSZXBvcnQgdGhlIHRhc2sgZGVhZCBhZnRlciB1bnNjaGVkdWxpbmcgdGhlIGV2ZW50cyBzbyB0aGF0IHdlCgkgKiB3b24ndCBnZXQgYW55IHNhbXBsZXMgYWZ0ZXIgUEVSRl9SRUNPUkRfRVhJVC4gV2UgY2FuIGhvd2V2ZXIgc3RpbGwKCSAqIGdldCBhIGZldyBQRVJGX1JFQ09SRF9SRUFEIGV2ZW50cy4KCSAqLwoJcGVyZl9ldmVudF90YXNrKGNoaWxkLCBjaGlsZF9jdHgsIDApOwoKCS8qCgkgKiBXZSBjYW4gcmVjdXJzZSBvbiB0aGUgc2FtZSBsb2NrIHR5cGUgdGhyb3VnaDoKCSAqCgkgKiAgIF9fcGVyZl9ldmVudF9leGl0X3Rhc2soKQoJICogICAgIHN5bmNfY2hpbGRfZXZlbnQoKQoJICogICAgICAgZnB1dChwYXJlbnRfZXZlbnQtPmZpbHApCgkgKiAgICAgICAgIHBlcmZfcmVsZWFzZSgpCgkgKiAgICAgICAgICAgbXV0ZXhfbG9jaygmY3R4LT5tdXRleCkKCSAqCgkgKiBCdXQgc2luY2UgaXRzIHRoZSBwYXJlbnQgY29udGV4dCBpdCB3b24ndCBiZSB0aGUgc2FtZSBpbnN0YW5jZS4KCSAqLwoJbXV0ZXhfbG9jaygmY2hpbGRfY3R4LT5tdXRleCk7CgphZ2FpbjoKCWxpc3RfZm9yX2VhY2hfZW50cnlfc2FmZShjaGlsZF9ldmVudCwgdG1wLCAmY2hpbGRfY3R4LT5waW5uZWRfZ3JvdXBzLAoJCQkJIGdyb3VwX2VudHJ5KQoJCV9fcGVyZl9ldmVudF9leGl0X3Rhc2soY2hpbGRfZXZlbnQsIGNoaWxkX2N0eCwgY2hpbGQpOwoKCWxpc3RfZm9yX2VhY2hfZW50cnlfc2FmZShjaGlsZF9ldmVudCwgdG1wLCAmY2hpbGRfY3R4LT5mbGV4aWJsZV9ncm91cHMsCgkJCQkgZ3JvdXBfZW50cnkpCgkJX19wZXJmX2V2ZW50X2V4aXRfdGFzayhjaGlsZF9ldmVudCwgY2hpbGRfY3R4LCBjaGlsZCk7CgoJLyoKCSAqIElmIHRoZSBsYXN0IGV2ZW50IHdhcyBhIGdyb3VwIGV2ZW50LCBpdCB3aWxsIGhhdmUgYXBwZW5kZWQgYWxsCgkgKiBpdHMgc2libGluZ3MgdG8gdGhlIGxpc3QsIGJ1dCB3ZSBvYnRhaW5lZCAndG1wJyBiZWZvcmUgdGhhdCB3aGljaAoJICogd2lsbCBzdGlsbCBwb2ludCB0byB0aGUgbGlzdCBoZWFkIHRlcm1pbmF0aW5nIHRoZSBpdGVyYXRpb24uCgkgKi8KCWlmICghbGlzdF9lbXB0eSgmY2hpbGRfY3R4LT5waW5uZWRfZ3JvdXBzKSB8fAoJICAgICFsaXN0X2VtcHR5KCZjaGlsZF9jdHgtPmZsZXhpYmxlX2dyb3VwcykpCgkJZ290byBhZ2FpbjsKCgltdXRleF91bmxvY2soJmNoaWxkX2N0eC0+bXV0ZXgpOwoKCXB1dF9jdHgoY2hpbGRfY3R4KTsKfQoKLyoKICogV2hlbiBhIGNoaWxkIHRhc2sgZXhpdHMsIGZlZWQgYmFjayBldmVudCB2YWx1ZXMgdG8gcGFyZW50IGV2ZW50cy4KICovCnZvaWQgcGVyZl9ldmVudF9leGl0X3Rhc2soc3RydWN0IHRhc2tfc3RydWN0ICpjaGlsZCkKewoJc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50LCAqdG1wOwoJaW50IGN0eG47CgoJbXV0ZXhfbG9jaygmY2hpbGQtPnBlcmZfZXZlbnRfbXV0ZXgpOwoJbGlzdF9mb3JfZWFjaF9lbnRyeV9zYWZlKGV2ZW50LCB0bXAsICZjaGlsZC0+cGVyZl9ldmVudF9saXN0LAoJCQkJIG93bmVyX2VudHJ5KSB7CgkJbGlzdF9kZWxfaW5pdCgmZXZlbnQtPm93bmVyX2VudHJ5KTsKCgkJLyoKCQkgKiBFbnN1cmUgdGhlIGxpc3QgZGVsZXRpb24gaXMgdmlzaWJsZSBiZWZvcmUgd2UgY2xlYXIKCQkgKiB0aGUgb3duZXIsIGNsb3NlcyBhIHJhY2UgYWdhaW5zdCBwZXJmX3JlbGVhc2UoKSB3aGVyZQoJCSAqIHdlIG5lZWQgdG8gc2VyaWFsaXplIG9uIHRoZSBvd25lci0+cGVyZl9ldmVudF9tdXRleC4KCQkgKi8KCQlzbXBfd21iKCk7CgkJZXZlbnQtPm93bmVyID0gTlVMTDsKCX0KCW11dGV4X3VubG9jaygmY2hpbGQtPnBlcmZfZXZlbnRfbXV0ZXgpOwoKCWZvcl9lYWNoX3Rhc2tfY29udGV4dF9ucihjdHhuKQoJCXBlcmZfZXZlbnRfZXhpdF90YXNrX2NvbnRleHQoY2hpbGQsIGN0eG4pOwp9CgpzdGF0aWMgdm9pZCBwZXJmX2ZyZWVfZXZlbnQoc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50LAoJCQkgICAgc3RydWN0IHBlcmZfZXZlbnRfY29udGV4dCAqY3R4KQp7CglzdHJ1Y3QgcGVyZl9ldmVudCAqcGFyZW50ID0gZXZlbnQtPnBhcmVudDsKCglpZiAoV0FSTl9PTl9PTkNFKCFwYXJlbnQpKQoJCXJldHVybjsKCgltdXRleF9sb2NrKCZwYXJlbnQtPmNoaWxkX211dGV4KTsKCWxpc3RfZGVsX2luaXQoJmV2ZW50LT5jaGlsZF9saXN0KTsKCW11dGV4X3VubG9jaygmcGFyZW50LT5jaGlsZF9tdXRleCk7CgoJZnB1dChwYXJlbnQtPmZpbHApOwoKCXBlcmZfZ3JvdXBfZGV0YWNoKGV2ZW50KTsKCWxpc3RfZGVsX2V2ZW50KGV2ZW50LCBjdHgpOwoJZnJlZV9ldmVudChldmVudCk7Cn0KCi8qCiAqIGZyZWUgYW4gdW5leHBvc2VkLCB1bnVzZWQgY29udGV4dCBhcyBjcmVhdGVkIGJ5IGluaGVyaXRhbmNlIGJ5CiAqIHBlcmZfZXZlbnRfaW5pdF90YXNrIGJlbG93LCB1c2VkIGJ5IGZvcmsoKSBpbiBjYXNlIG9mIGZhaWwuCiAqLwp2b2lkIHBlcmZfZXZlbnRfZnJlZV90YXNrKHN0cnVjdCB0YXNrX3N0cnVjdCAqdGFzaykKewoJc3RydWN0IHBlcmZfZXZlbnRfY29udGV4dCAqY3R4OwoJc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50LCAqdG1wOwoJaW50IGN0eG47CgoJZm9yX2VhY2hfdGFza19jb250ZXh0X25yKGN0eG4pIHsKCQljdHggPSB0YXNrLT5wZXJmX2V2ZW50X2N0eHBbY3R4bl07CgkJaWYgKCFjdHgpCgkJCWNvbnRpbnVlOwoKCQltdXRleF9sb2NrKCZjdHgtPm11dGV4KTsKYWdhaW46CgkJbGlzdF9mb3JfZWFjaF9lbnRyeV9zYWZlKGV2ZW50LCB0bXAsICZjdHgtPnBpbm5lZF9ncm91cHMsCgkJCQlncm91cF9lbnRyeSkKCQkJcGVyZl9mcmVlX2V2ZW50KGV2ZW50LCBjdHgpOwoKCQlsaXN0X2Zvcl9lYWNoX2VudHJ5X3NhZmUoZXZlbnQsIHRtcCwgJmN0eC0+ZmxleGlibGVfZ3JvdXBzLAoJCQkJZ3JvdXBfZW50cnkpCgkJCXBlcmZfZnJlZV9ldmVudChldmVudCwgY3R4KTsKCgkJaWYgKCFsaXN0X2VtcHR5KCZjdHgtPnBpbm5lZF9ncm91cHMpIHx8CgkJCQkhbGlzdF9lbXB0eSgmY3R4LT5mbGV4aWJsZV9ncm91cHMpKQoJCQlnb3RvIGFnYWluOwoKCQltdXRleF91bmxvY2soJmN0eC0+bXV0ZXgpOwoKCQlwdXRfY3R4KGN0eCk7Cgl9Cn0KCnZvaWQgcGVyZl9ldmVudF9kZWxheWVkX3B1dChzdHJ1Y3QgdGFza19zdHJ1Y3QgKnRhc2spCnsKCWludCBjdHhuOwoKCWZvcl9lYWNoX3Rhc2tfY29udGV4dF9ucihjdHhuKQoJCVdBUk5fT05fT05DRSh0YXNrLT5wZXJmX2V2ZW50X2N0eHBbY3R4bl0pOwp9CgovKgogKiBpbmhlcml0IGEgZXZlbnQgZnJvbSBwYXJlbnQgdGFzayB0byBjaGlsZCB0YXNrOgogKi8Kc3RhdGljIHN0cnVjdCBwZXJmX2V2ZW50ICoKaW5oZXJpdF9ldmVudChzdHJ1Y3QgcGVyZl9ldmVudCAqcGFyZW50X2V2ZW50LAoJICAgICAgc3RydWN0IHRhc2tfc3RydWN0ICpwYXJlbnQsCgkgICAgICBzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0ICpwYXJlbnRfY3R4LAoJICAgICAgc3RydWN0IHRhc2tfc3RydWN0ICpjaGlsZCwKCSAgICAgIHN0cnVjdCBwZXJmX2V2ZW50ICpncm91cF9sZWFkZXIsCgkgICAgICBzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0ICpjaGlsZF9jdHgpCnsKCXN0cnVjdCBwZXJmX2V2ZW50ICpjaGlsZF9ldmVudDsKCXVuc2lnbmVkIGxvbmcgZmxhZ3M7CgoJLyoKCSAqIEluc3RlYWQgb2YgY3JlYXRpbmcgcmVjdXJzaXZlIGhpZXJhcmNoaWVzIG9mIGV2ZW50cywKCSAqIHdlIGxpbmsgaW5oZXJpdGVkIGV2ZW50cyBiYWNrIHRvIHRoZSBvcmlnaW5hbCBwYXJlbnQsCgkgKiB3aGljaCBoYXMgYSBmaWxwIGZvciBzdXJlLCB3aGljaCB3ZSB1c2UgYXMgdGhlIHJlZmVyZW5jZQoJICogY291bnQ6CgkgKi8KCWlmIChwYXJlbnRfZXZlbnQtPnBhcmVudCkKCQlwYXJlbnRfZXZlbnQgPSBwYXJlbnRfZXZlbnQtPnBhcmVudDsKCgljaGlsZF9ldmVudCA9IHBlcmZfZXZlbnRfYWxsb2MoJnBhcmVudF9ldmVudC0+YXR0ciwKCQkJCQkgICBwYXJlbnRfZXZlbnQtPmNwdSwKCQkJCQkgICBjaGlsZCwKCQkJCQkgICBncm91cF9sZWFkZXIsIHBhcmVudF9ldmVudCwKCQkJCQkgICBOVUxMKTsKCWlmIChJU19FUlIoY2hpbGRfZXZlbnQpKQoJCXJldHVybiBjaGlsZF9ldmVudDsKCWdldF9jdHgoY2hpbGRfY3R4KTsKCgkvKgoJICogTWFrZSB0aGUgY2hpbGQgc3RhdGUgZm9sbG93IHRoZSBzdGF0ZSBvZiB0aGUgcGFyZW50IGV2ZW50LAoJICogbm90IGl0cyBhdHRyLmRpc2FibGVkIGJpdC4gIFdlIGhvbGQgdGhlIHBhcmVudCdzIG11dGV4LAoJICogc28gd2Ugd29uJ3QgcmFjZSB3aXRoIHBlcmZfZXZlbnRfe2VuLCBkaXN9YWJsZV9mYW1pbHkuCgkgKi8KCWlmIChwYXJlbnRfZXZlbnQtPnN0YXRlID49IFBFUkZfRVZFTlRfU1RBVEVfSU5BQ1RJVkUpCgkJY2hpbGRfZXZlbnQtPnN0YXRlID0gUEVSRl9FVkVOVF9TVEFURV9JTkFDVElWRTsKCWVsc2UKCQljaGlsZF9ldmVudC0+c3RhdGUgPSBQRVJGX0VWRU5UX1NUQVRFX09GRjsKCglpZiAocGFyZW50X2V2ZW50LT5hdHRyLmZyZXEpIHsKCQl1NjQgc2FtcGxlX3BlcmlvZCA9IHBhcmVudF9ldmVudC0+aHcuc2FtcGxlX3BlcmlvZDsKCQlzdHJ1Y3QgaHdfcGVyZl9ldmVudCAqaHdjID0gJmNoaWxkX2V2ZW50LT5odzsKCgkJaHdjLT5zYW1wbGVfcGVyaW9kID0gc2FtcGxlX3BlcmlvZDsKCQlod2MtPmxhc3RfcGVyaW9kICAgPSBzYW1wbGVfcGVyaW9kOwoKCQlsb2NhbDY0X3NldCgmaHdjLT5wZXJpb2RfbGVmdCwgc2FtcGxlX3BlcmlvZCk7Cgl9CgoJY2hpbGRfZXZlbnQtPmN0eCA9IGNoaWxkX2N0eDsKCWNoaWxkX2V2ZW50LT5vdmVyZmxvd19oYW5kbGVyID0gcGFyZW50X2V2ZW50LT5vdmVyZmxvd19oYW5kbGVyOwoKCS8qCgkgKiBQcmVjYWxjdWxhdGUgc2FtcGxlX2RhdGEgc2l6ZXMKCSAqLwoJcGVyZl9ldmVudF9faGVhZGVyX3NpemUoY2hpbGRfZXZlbnQpOwoJcGVyZl9ldmVudF9faWRfaGVhZGVyX3NpemUoY2hpbGRfZXZlbnQpOwoKCS8qCgkgKiBMaW5rIGl0IHVwIGluIHRoZSBjaGlsZCdzIGNvbnRleHQ6CgkgKi8KCXJhd19zcGluX2xvY2tfaXJxc2F2ZSgmY2hpbGRfY3R4LT5sb2NrLCBmbGFncyk7CglhZGRfZXZlbnRfdG9fY3R4KGNoaWxkX2V2ZW50LCBjaGlsZF9jdHgpOwoJcmF3X3NwaW5fdW5sb2NrX2lycXJlc3RvcmUoJmNoaWxkX2N0eC0+bG9jaywgZmxhZ3MpOwoKCS8qCgkgKiBHZXQgYSByZWZlcmVuY2UgdG8gdGhlIHBhcmVudCBmaWxwIC0gd2Ugd2lsbCBmcHV0IGl0CgkgKiB3aGVuIHRoZSBjaGlsZCBldmVudCBleGl0cy4gVGhpcyBpcyBzYWZlIHRvIGRvIGJlY2F1c2UKCSAqIHdlIGFyZSBpbiB0aGUgcGFyZW50IGFuZCB3ZSBrbm93IHRoYXQgdGhlIGZpbHAgc3RpbGwKCSAqIGV4aXN0cyBhbmQgaGFzIGEgbm9uemVybyBjb3VudDoKCSAqLwoJYXRvbWljX2xvbmdfaW5jKCZwYXJlbnRfZXZlbnQtPmZpbHAtPmZfY291bnQpOwoKCS8qCgkgKiBMaW5rIHRoaXMgaW50byB0aGUgcGFyZW50IGV2ZW50J3MgY2hpbGQgbGlzdAoJICovCglXQVJOX09OX09OQ0UocGFyZW50X2V2ZW50LT5jdHgtPnBhcmVudF9jdHgpOwoJbXV0ZXhfbG9jaygmcGFyZW50X2V2ZW50LT5jaGlsZF9tdXRleCk7CglsaXN0X2FkZF90YWlsKCZjaGlsZF9ldmVudC0+Y2hpbGRfbGlzdCwgJnBhcmVudF9ldmVudC0+Y2hpbGRfbGlzdCk7CgltdXRleF91bmxvY2soJnBhcmVudF9ldmVudC0+Y2hpbGRfbXV0ZXgpOwoKCXJldHVybiBjaGlsZF9ldmVudDsKfQoKc3RhdGljIGludCBpbmhlcml0X2dyb3VwKHN0cnVjdCBwZXJmX2V2ZW50ICpwYXJlbnRfZXZlbnQsCgkgICAgICBzdHJ1Y3QgdGFza19zdHJ1Y3QgKnBhcmVudCwKCSAgICAgIHN0cnVjdCBwZXJmX2V2ZW50X2NvbnRleHQgKnBhcmVudF9jdHgsCgkgICAgICBzdHJ1Y3QgdGFza19zdHJ1Y3QgKmNoaWxkLAoJICAgICAgc3RydWN0IHBlcmZfZXZlbnRfY29udGV4dCAqY2hpbGRfY3R4KQp7CglzdHJ1Y3QgcGVyZl9ldmVudCAqbGVhZGVyOwoJc3RydWN0IHBlcmZfZXZlbnQgKnN1YjsKCXN0cnVjdCBwZXJmX2V2ZW50ICpjaGlsZF9jdHI7CgoJbGVhZGVyID0gaW5oZXJpdF9ldmVudChwYXJlbnRfZXZlbnQsIHBhcmVudCwgcGFyZW50X2N0eCwKCQkJCSBjaGlsZCwgTlVMTCwgY2hpbGRfY3R4KTsKCWlmIChJU19FUlIobGVhZGVyKSkKCQlyZXR1cm4gUFRSX0VSUihsZWFkZXIpOwoJbGlzdF9mb3JfZWFjaF9lbnRyeShzdWIsICZwYXJlbnRfZXZlbnQtPnNpYmxpbmdfbGlzdCwgZ3JvdXBfZW50cnkpIHsKCQljaGlsZF9jdHIgPSBpbmhlcml0X2V2ZW50KHN1YiwgcGFyZW50LCBwYXJlbnRfY3R4LAoJCQkJCSAgICBjaGlsZCwgbGVhZGVyLCBjaGlsZF9jdHgpOwoJCWlmIChJU19FUlIoY2hpbGRfY3RyKSkKCQkJcmV0dXJuIFBUUl9FUlIoY2hpbGRfY3RyKTsKCX0KCXJldHVybiAwOwp9CgpzdGF0aWMgaW50CmluaGVyaXRfdGFza19ncm91cChzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQsIHN0cnVjdCB0YXNrX3N0cnVjdCAqcGFyZW50LAoJCSAgIHN0cnVjdCBwZXJmX2V2ZW50X2NvbnRleHQgKnBhcmVudF9jdHgsCgkJICAgc3RydWN0IHRhc2tfc3RydWN0ICpjaGlsZCwgaW50IGN0eG4sCgkJICAgaW50ICppbmhlcml0ZWRfYWxsKQp7CglpbnQgcmV0OwoJc3RydWN0IHBlcmZfZXZlbnRfY29udGV4dCAqY2hpbGRfY3R4OwoKCWlmICghZXZlbnQtPmF0dHIuaW5oZXJpdCkgewoJCSppbmhlcml0ZWRfYWxsID0gMDsKCQlyZXR1cm4gMDsKCX0KCiAgICAgICAJY2hpbGRfY3R4ID0gY2hpbGQtPnBlcmZfZXZlbnRfY3R4cFtjdHhuXTsKCWlmICghY2hpbGRfY3R4KSB7CgkJLyoKCQkgKiBUaGlzIGlzIGV4ZWN1dGVkIGZyb20gdGhlIHBhcmVudCB0YXNrIGNvbnRleHQsIHNvCgkJICogaW5oZXJpdCBldmVudHMgdGhhdCBoYXZlIGJlZW4gbWFya2VkIGZvciBjbG9uaW5nLgoJCSAqIEZpcnN0IGFsbG9jYXRlIGFuZCBpbml0aWFsaXplIGEgY29udGV4dCBmb3IgdGhlCgkJICogY2hpbGQuCgkJICovCgoJCWNoaWxkX2N0eCA9IGFsbG9jX3BlcmZfY29udGV4dChldmVudC0+cG11LCBjaGlsZCk7CgkJaWYgKCFjaGlsZF9jdHgpCgkJCXJldHVybiAtRU5PTUVNOwoKCQljaGlsZC0+cGVyZl9ldmVudF9jdHhwW2N0eG5dID0gY2hpbGRfY3R4OwoJfQoKCXJldCA9IGluaGVyaXRfZ3JvdXAoZXZlbnQsIHBhcmVudCwgcGFyZW50X2N0eCwKCQkJICAgIGNoaWxkLCBjaGlsZF9jdHgpOwoKCWlmIChyZXQpCgkJKmluaGVyaXRlZF9hbGwgPSAwOwoKCXJldHVybiByZXQ7Cn0KCi8qCiAqIEluaXRpYWxpemUgdGhlIHBlcmZfZXZlbnQgY29udGV4dCBpbiB0YXNrX3N0cnVjdAogKi8KaW50IHBlcmZfZXZlbnRfaW5pdF9jb250ZXh0KHN0cnVjdCB0YXNrX3N0cnVjdCAqY2hpbGQsIGludCBjdHhuKQp7CglzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0ICpjaGlsZF9jdHgsICpwYXJlbnRfY3R4OwoJc3RydWN0IHBlcmZfZXZlbnRfY29udGV4dCAqY2xvbmVkX2N0eDsKCXN0cnVjdCBwZXJmX2V2ZW50ICpldmVudDsKCXN0cnVjdCB0YXNrX3N0cnVjdCAqcGFyZW50ID0gY3VycmVudDsKCWludCBpbmhlcml0ZWRfYWxsID0gMTsKCXVuc2lnbmVkIGxvbmcgZmxhZ3M7CglpbnQgcmV0ID0gMDsKCgljaGlsZC0+cGVyZl9ldmVudF9jdHhwW2N0eG5dID0gTlVMTDsKCgltdXRleF9pbml0KCZjaGlsZC0+cGVyZl9ldmVudF9tdXRleCk7CglJTklUX0xJU1RfSEVBRCgmY2hpbGQtPnBlcmZfZXZlbnRfbGlzdCk7CgoJaWYgKGxpa2VseSghcGFyZW50LT5wZXJmX2V2ZW50X2N0eHBbY3R4bl0pKQoJCXJldHVybiAwOwoKCS8qCgkgKiBJZiB0aGUgcGFyZW50J3MgY29udGV4dCBpcyBhIGNsb25lLCBwaW4gaXQgc28gaXQgd29uJ3QgZ2V0CgkgKiBzd2FwcGVkIHVuZGVyIHVzLgoJICovCglwYXJlbnRfY3R4ID0gcGVyZl9waW5fdGFza19jb250ZXh0KHBhcmVudCwgY3R4bik7CgoJLyoKCSAqIE5vIG5lZWQgdG8gY2hlY2sgaWYgcGFyZW50X2N0eCAhPSBOVUxMIGhlcmU7IHNpbmNlIHdlIHNhdwoJICogaXQgbm9uLU5VTEwgZWFybGllciwgdGhlIG9ubHkgcmVhc29uIGZvciBpdCB0byBiZWNvbWUgTlVMTAoJICogaXMgaWYgd2UgZXhpdCwgYW5kIHNpbmNlIHdlJ3JlIGN1cnJlbnRseSBpbiB0aGUgbWlkZGxlIG9mCgkgKiBhIGZvcmsgd2UgY2FuJ3QgYmUgZXhpdGluZyBhdCB0aGUgc2FtZSB0aW1lLgoJICovCgoJLyoKCSAqIExvY2sgdGhlIHBhcmVudCBsaXN0LiBObyBuZWVkIHRvIGxvY2sgdGhlIGNoaWxkIC0gbm90IFBJRAoJICogaGFzaGVkIHlldCBhbmQgbm90IHJ1bm5pbmcsIHNvIG5vYm9keSBjYW4gYWNjZXNzIGl0LgoJICovCgltdXRleF9sb2NrKCZwYXJlbnRfY3R4LT5tdXRleCk7CgoJLyoKCSAqIFdlIGRvbnQgaGF2ZSB0byBkaXNhYmxlIE5NSXMgLSB3ZSBhcmUgb25seSBsb29raW5nIGF0CgkgKiB0aGUgbGlzdCwgbm90IG1hbmlwdWxhdGluZyBpdDoKCSAqLwoJbGlzdF9mb3JfZWFjaF9lbnRyeShldmVudCwgJnBhcmVudF9jdHgtPnBpbm5lZF9ncm91cHMsIGdyb3VwX2VudHJ5KSB7CgkJcmV0ID0gaW5oZXJpdF90YXNrX2dyb3VwKGV2ZW50LCBwYXJlbnQsIHBhcmVudF9jdHgsCgkJCQkJIGNoaWxkLCBjdHhuLCAmaW5oZXJpdGVkX2FsbCk7CgkJaWYgKHJldCkKCQkJYnJlYWs7Cgl9CgoJLyoKCSAqIFdlIGNhbid0IGhvbGQgY3R4LT5sb2NrIHdoZW4gaXRlcmF0aW5nIHRoZSAtPmZsZXhpYmxlX2dyb3VwIGxpc3QgZHVlCgkgKiB0byBhbGxvY2F0aW9ucywgYnV0IHdlIG5lZWQgdG8gcHJldmVudCByb3RhdGlvbiBiZWNhdXNlCgkgKiByb3RhdGVfY3R4KCkgd2lsbCBjaGFuZ2UgdGhlIGxpc3QgZnJvbSBpbnRlcnJ1cHQgY29udGV4dC4KCSAqLwoJcmF3X3NwaW5fbG9ja19pcnFzYXZlKCZwYXJlbnRfY3R4LT5sb2NrLCBmbGFncyk7CglwYXJlbnRfY3R4LT5yb3RhdGVfZGlzYWJsZSA9IDE7CglyYXdfc3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmcGFyZW50X2N0eC0+bG9jaywgZmxhZ3MpOwoKCWxpc3RfZm9yX2VhY2hfZW50cnkoZXZlbnQsICZwYXJlbnRfY3R4LT5mbGV4aWJsZV9ncm91cHMsIGdyb3VwX2VudHJ5KSB7CgkJcmV0ID0gaW5oZXJpdF90YXNrX2dyb3VwKGV2ZW50LCBwYXJlbnQsIHBhcmVudF9jdHgsCgkJCQkJIGNoaWxkLCBjdHhuLCAmaW5oZXJpdGVkX2FsbCk7CgkJaWYgKHJldCkKCQkJYnJlYWs7Cgl9CgoJcmF3X3NwaW5fbG9ja19pcnFzYXZlKCZwYXJlbnRfY3R4LT5sb2NrLCBmbGFncyk7CglwYXJlbnRfY3R4LT5yb3RhdGVfZGlzYWJsZSA9IDA7CgoJY2hpbGRfY3R4ID0gY2hpbGQtPnBlcmZfZXZlbnRfY3R4cFtjdHhuXTsKCglpZiAoY2hpbGRfY3R4ICYmIGluaGVyaXRlZF9hbGwpIHsKCQkvKgoJCSAqIE1hcmsgdGhlIGNoaWxkIGNvbnRleHQgYXMgYSBjbG9uZSBvZiB0aGUgcGFyZW50CgkJICogY29udGV4dCwgb3Igb2Ygd2hhdGV2ZXIgdGhlIHBhcmVudCBpcyBhIGNsb25lIG9mLgoJCSAqCgkJICogTm90ZSB0aGF0IGlmIHRoZSBwYXJlbnQgaXMgYSBjbG9uZSwgdGhlIGhvbGRpbmcgb2YKCQkgKiBwYXJlbnRfY3R4LT5sb2NrIGF2b2lkcyBpdCBmcm9tIGJlaW5nIHVuY2xvbmVkLgoJCSAqLwoJCWNsb25lZF9jdHggPSBwYXJlbnRfY3R4LT5wYXJlbnRfY3R4OwoJCWlmIChjbG9uZWRfY3R4KSB7CgkJCWNoaWxkX2N0eC0+cGFyZW50X2N0eCA9IGNsb25lZF9jdHg7CgkJCWNoaWxkX2N0eC0+cGFyZW50X2dlbiA9IHBhcmVudF9jdHgtPnBhcmVudF9nZW47CgkJfSBlbHNlIHsKCQkJY2hpbGRfY3R4LT5wYXJlbnRfY3R4ID0gcGFyZW50X2N0eDsKCQkJY2hpbGRfY3R4LT5wYXJlbnRfZ2VuID0gcGFyZW50X2N0eC0+Z2VuZXJhdGlvbjsKCQl9CgkJZ2V0X2N0eChjaGlsZF9jdHgtPnBhcmVudF9jdHgpOwoJfQoKCXJhd19zcGluX3VubG9ja19pcnFyZXN0b3JlKCZwYXJlbnRfY3R4LT5sb2NrLCBmbGFncyk7CgltdXRleF91bmxvY2soJnBhcmVudF9jdHgtPm11dGV4KTsKCglwZXJmX3VucGluX2NvbnRleHQocGFyZW50X2N0eCk7CgoJcmV0dXJuIHJldDsKfQoKLyoKICogSW5pdGlhbGl6ZSB0aGUgcGVyZl9ldmVudCBjb250ZXh0IGluIHRhc2tfc3RydWN0CiAqLwppbnQgcGVyZl9ldmVudF9pbml0X3Rhc2soc3RydWN0IHRhc2tfc3RydWN0ICpjaGlsZCkKewoJaW50IGN0eG4sIHJldDsKCglmb3JfZWFjaF90YXNrX2NvbnRleHRfbnIoY3R4bikgewoJCXJldCA9IHBlcmZfZXZlbnRfaW5pdF9jb250ZXh0KGNoaWxkLCBjdHhuKTsKCQlpZiAocmV0KQoJCQlyZXR1cm4gcmV0OwoJfQoKCXJldHVybiAwOwp9CgpzdGF0aWMgdm9pZCBfX2luaXQgcGVyZl9ldmVudF9pbml0X2FsbF9jcHVzKHZvaWQpCnsKCXN0cnVjdCBzd2V2ZW50X2h0YWJsZSAqc3doYXNoOwoJaW50IGNwdTsKCglmb3JfZWFjaF9wb3NzaWJsZV9jcHUoY3B1KSB7CgkJc3doYXNoID0gJnBlcl9jcHUoc3dldmVudF9odGFibGUsIGNwdSk7CgkJbXV0ZXhfaW5pdCgmc3doYXNoLT5obGlzdF9tdXRleCk7CgkJSU5JVF9MSVNUX0hFQUQoJnBlcl9jcHUocm90YXRpb25fbGlzdCwgY3B1KSk7Cgl9Cn0KCnN0YXRpYyB2b2lkIF9fY3B1aW5pdCBwZXJmX2V2ZW50X2luaXRfY3B1KGludCBjcHUpCnsKCXN0cnVjdCBzd2V2ZW50X2h0YWJsZSAqc3doYXNoID0gJnBlcl9jcHUoc3dldmVudF9odGFibGUsIGNwdSk7CgoJbXV0ZXhfbG9jaygmc3doYXNoLT5obGlzdF9tdXRleCk7CglpZiAoc3doYXNoLT5obGlzdF9yZWZjb3VudCA+IDApIHsKCQlzdHJ1Y3Qgc3dldmVudF9obGlzdCAqaGxpc3Q7CgoJCWhsaXN0ID0ga3phbGxvY19ub2RlKHNpemVvZigqaGxpc3QpLCBHRlBfS0VSTkVMLCBjcHVfdG9fbm9kZShjcHUpKTsKCQlXQVJOX09OKCFobGlzdCk7CgkJcmN1X2Fzc2lnbl9wb2ludGVyKHN3aGFzaC0+c3dldmVudF9obGlzdCwgaGxpc3QpOwoJfQoJbXV0ZXhfdW5sb2NrKCZzd2hhc2gtPmhsaXN0X211dGV4KTsKfQoKI2lmIGRlZmluZWQgQ09ORklHX0hPVFBMVUdfQ1BVIHx8IGRlZmluZWQgQ09ORklHX0tFWEVDCnN0YXRpYyB2b2lkIHBlcmZfcG11X3JvdGF0ZV9zdG9wKHN0cnVjdCBwbXUgKnBtdSkKewoJc3RydWN0IHBlcmZfY3B1X2NvbnRleHQgKmNwdWN0eCA9IHRoaXNfY3B1X3B0cihwbXUtPnBtdV9jcHVfY29udGV4dCk7CgoJV0FSTl9PTighaXJxc19kaXNhYmxlZCgpKTsKCglsaXN0X2RlbF9pbml0KCZjcHVjdHgtPnJvdGF0aW9uX2xpc3QpOwp9CgpzdGF0aWMgdm9pZCBfX3BlcmZfZXZlbnRfZXhpdF9jb250ZXh0KHZvaWQgKl9faW5mbykKewoJc3RydWN0IHBlcmZfZXZlbnRfY29udGV4dCAqY3R4ID0gX19pbmZvOwoJc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50LCAqdG1wOwoKCXBlcmZfcG11X3JvdGF0ZV9zdG9wKGN0eC0+cG11KTsKCglsaXN0X2Zvcl9lYWNoX2VudHJ5X3NhZmUoZXZlbnQsIHRtcCwgJmN0eC0+cGlubmVkX2dyb3VwcywgZ3JvdXBfZW50cnkpCgkJX19wZXJmX2V2ZW50X3JlbW92ZV9mcm9tX2NvbnRleHQoZXZlbnQpOwoJbGlzdF9mb3JfZWFjaF9lbnRyeV9zYWZlKGV2ZW50LCB0bXAsICZjdHgtPmZsZXhpYmxlX2dyb3VwcywgZ3JvdXBfZW50cnkpCgkJX19wZXJmX2V2ZW50X3JlbW92ZV9mcm9tX2NvbnRleHQoZXZlbnQpOwp9CgpzdGF0aWMgdm9pZCBwZXJmX2V2ZW50X2V4aXRfY3B1X2NvbnRleHQoaW50IGNwdSkKewoJc3RydWN0IHBlcmZfZXZlbnRfY29udGV4dCAqY3R4OwoJc3RydWN0IHBtdSAqcG11OwoJaW50IGlkeDsKCglpZHggPSBzcmN1X3JlYWRfbG9jaygmcG11c19zcmN1KTsKCWxpc3RfZm9yX2VhY2hfZW50cnlfcmN1KHBtdSwgJnBtdXMsIGVudHJ5KSB7CgkJY3R4ID0gJnBlcl9jcHVfcHRyKHBtdS0+cG11X2NwdV9jb250ZXh0LCBjcHUpLT5jdHg7CgoJCW11dGV4X2xvY2soJmN0eC0+bXV0ZXgpOwoJCXNtcF9jYWxsX2Z1bmN0aW9uX3NpbmdsZShjcHUsIF9fcGVyZl9ldmVudF9leGl0X2NvbnRleHQsIGN0eCwgMSk7CgkJbXV0ZXhfdW5sb2NrKCZjdHgtPm11dGV4KTsKCX0KCXNyY3VfcmVhZF91bmxvY2soJnBtdXNfc3JjdSwgaWR4KTsKfQoKc3RhdGljIHZvaWQgcGVyZl9ldmVudF9leGl0X2NwdShpbnQgY3B1KQp7CglzdHJ1Y3Qgc3dldmVudF9odGFibGUgKnN3aGFzaCA9ICZwZXJfY3B1KHN3ZXZlbnRfaHRhYmxlLCBjcHUpOwoKCW11dGV4X2xvY2soJnN3aGFzaC0+aGxpc3RfbXV0ZXgpOwoJc3dldmVudF9obGlzdF9yZWxlYXNlKHN3aGFzaCk7CgltdXRleF91bmxvY2soJnN3aGFzaC0+aGxpc3RfbXV0ZXgpOwoKCXBlcmZfZXZlbnRfZXhpdF9jcHVfY29udGV4dChjcHUpOwp9CiNlbHNlCnN0YXRpYyBpbmxpbmUgdm9pZCBwZXJmX2V2ZW50X2V4aXRfY3B1KGludCBjcHUpIHsgfQojZW5kaWYKCnN0YXRpYyBpbnQKcGVyZl9yZWJvb3Qoc3RydWN0IG5vdGlmaWVyX2Jsb2NrICpub3RpZmllciwgdW5zaWduZWQgbG9uZyB2YWwsIHZvaWQgKnYpCnsKCWludCBjcHU7CgoJZm9yX2VhY2hfb25saW5lX2NwdShjcHUpCgkJcGVyZl9ldmVudF9leGl0X2NwdShjcHUpOwoKCXJldHVybiBOT1RJRllfT0s7Cn0KCi8qCiAqIFJ1biB0aGUgcGVyZiByZWJvb3Qgbm90aWZpZXIgYXQgdGhlIHZlcnkgbGFzdCBwb3NzaWJsZSBtb21lbnQgc28gdGhhdAogKiB0aGUgZ2VuZXJpYyB3YXRjaGRvZyBjb2RlIHJ1bnMgYXMgbG9uZyBhcyBwb3NzaWJsZS4KICovCnN0YXRpYyBzdHJ1Y3Qgbm90aWZpZXJfYmxvY2sgcGVyZl9yZWJvb3Rfbm90aWZpZXIgPSB7Cgkubm90aWZpZXJfY2FsbCA9IHBlcmZfcmVib290LAoJLnByaW9yaXR5ID0gSU5UX01JTiwKfTsKCnN0YXRpYyBpbnQgX19jcHVpbml0CnBlcmZfY3B1X25vdGlmeShzdHJ1Y3Qgbm90aWZpZXJfYmxvY2sgKnNlbGYsIHVuc2lnbmVkIGxvbmcgYWN0aW9uLCB2b2lkICpoY3B1KQp7Cgl1bnNpZ25lZCBpbnQgY3B1ID0gKGxvbmcpaGNwdTsKCglzd2l0Y2ggKGFjdGlvbiAmIH5DUFVfVEFTS1NfRlJPWkVOKSB7CgoJY2FzZSBDUFVfVVBfUFJFUEFSRToKCWNhc2UgQ1BVX0RPV05fRkFJTEVEOgoJCXBlcmZfZXZlbnRfaW5pdF9jcHUoY3B1KTsKCQlicmVhazsKCgljYXNlIENQVV9VUF9DQU5DRUxFRDoKCWNhc2UgQ1BVX0RPV05fUFJFUEFSRToKCQlwZXJmX2V2ZW50X2V4aXRfY3B1KGNwdSk7CgkJYnJlYWs7CgoJZGVmYXVsdDoKCQlicmVhazsKCX0KCglyZXR1cm4gTk9USUZZX09LOwp9Cgp2b2lkIF9faW5pdCBwZXJmX2V2ZW50X2luaXQodm9pZCkKewoJaW50IHJldDsKCglpZHJfaW5pdCgmcG11X2lkcik7CgoJcGVyZl9ldmVudF9pbml0X2FsbF9jcHVzKCk7Cglpbml0X3NyY3Vfc3RydWN0KCZwbXVzX3NyY3UpOwoJcGVyZl9wbXVfcmVnaXN0ZXIoJnBlcmZfc3dldmVudCwgInNvZnR3YXJlIiwgUEVSRl9UWVBFX1NPRlRXQVJFKTsKCXBlcmZfcG11X3JlZ2lzdGVyKCZwZXJmX2NwdV9jbG9jaywgTlVMTCwgLTEpOwoJcGVyZl9wbXVfcmVnaXN0ZXIoJnBlcmZfdGFza19jbG9jaywgTlVMTCwgLTEpOwoJcGVyZl90cF9yZWdpc3RlcigpOwoJcGVyZl9jcHVfbm90aWZpZXIocGVyZl9jcHVfbm90aWZ5KTsKCXJlZ2lzdGVyX3JlYm9vdF9ub3RpZmllcigmcGVyZl9yZWJvb3Rfbm90aWZpZXIpOwoKCXJldCA9IGluaXRfaHdfYnJlYWtwb2ludCgpOwoJV0FSTihyZXQsICJod19icmVha3BvaW50IGluaXRpYWxpemF0aW9uIGZhaWxlZCB3aXRoOiAlZCIsIHJldCk7Cn0KCnN0YXRpYyBpbnQgX19pbml0IHBlcmZfZXZlbnRfc3lzZnNfaW5pdCh2b2lkKQp7CglzdHJ1Y3QgcG11ICpwbXU7CglpbnQgcmV0OwoKCW11dGV4X2xvY2soJnBtdXNfbG9jayk7CgoJcmV0ID0gYnVzX3JlZ2lzdGVyKCZwbXVfYnVzKTsKCWlmIChyZXQpCgkJZ290byB1bmxvY2s7CgoJbGlzdF9mb3JfZWFjaF9lbnRyeShwbXUsICZwbXVzLCBlbnRyeSkgewoJCWlmICghcG11LT5uYW1lIHx8IHBtdS0+dHlwZSA8IDApCgkJCWNvbnRpbnVlOwoKCQlyZXQgPSBwbXVfZGV2X2FsbG9jKHBtdSk7CgkJV0FSTihyZXQsICJGYWlsZWQgdG8gcmVnaXN0ZXIgcG11OiAlcywgcmVhc29uICVkXG4iLCBwbXUtPm5hbWUsIHJldCk7Cgl9CglwbXVfYnVzX3J1bm5pbmcgPSAxOwoJcmV0ID0gMDsKCnVubG9jazoKCW11dGV4X3VubG9jaygmcG11c19sb2NrKTsKCglyZXR1cm4gcmV0Owp9CmRldmljZV9pbml0Y2FsbChwZXJmX2V2ZW50X3N5c2ZzX2luaXQpOwo=