LyoKICogUGVyZm9ybWFuY2UgZXZlbnRzIGNvcmUgY29kZToKICoKICogIENvcHlyaWdodCAoQykgMjAwOCBUaG9tYXMgR2xlaXhuZXIgPHRnbHhAbGludXRyb25peC5kZT4KICogIENvcHlyaWdodCAoQykgMjAwOC0yMDA5IFJlZCBIYXQsIEluYy4sIEluZ28gTW9sbmFyCiAqICBDb3B5cmlnaHQgKEMpIDIwMDgtMjAwOSBSZWQgSGF0LCBJbmMuLCBQZXRlciBaaWpsc3RyYSA8cHppamxzdHJAcmVkaGF0LmNvbT4KICogIENvcHlyaWdodCAgqSAgMjAwOSBQYXVsIE1hY2tlcnJhcywgSUJNIENvcnAuIDxwYXVsdXNAYXUxLmlibS5jb20+CiAqCiAqIEZvciBsaWNlbnNpbmcgZGV0YWlscyBzZWUga2VybmVsLWJhc2UvQ09QWUlORwogKi8KCiNpbmNsdWRlIDxsaW51eC9mcy5oPgojaW5jbHVkZSA8bGludXgvbW0uaD4KI2luY2x1ZGUgPGxpbnV4L2NwdS5oPgojaW5jbHVkZSA8bGludXgvc21wLmg+CiNpbmNsdWRlIDxsaW51eC9pZHIuaD4KI2luY2x1ZGUgPGxpbnV4L2ZpbGUuaD4KI2luY2x1ZGUgPGxpbnV4L3BvbGwuaD4KI2luY2x1ZGUgPGxpbnV4L3NsYWIuaD4KI2luY2x1ZGUgPGxpbnV4L2hhc2guaD4KI2luY2x1ZGUgPGxpbnV4L3N5c2ZzLmg+CiNpbmNsdWRlIDxsaW51eC9kY2FjaGUuaD4KI2luY2x1ZGUgPGxpbnV4L3BlcmNwdS5oPgojaW5jbHVkZSA8bGludXgvcHRyYWNlLmg+CiNpbmNsdWRlIDxsaW51eC9yZWJvb3QuaD4KI2luY2x1ZGUgPGxpbnV4L3Ztc3RhdC5oPgojaW5jbHVkZSA8bGludXgvZGV2aWNlLmg+CiNpbmNsdWRlIDxsaW51eC92bWFsbG9jLmg+CiNpbmNsdWRlIDxsaW51eC9oYXJkaXJxLmg+CiNpbmNsdWRlIDxsaW51eC9yY3VsaXN0Lmg+CiNpbmNsdWRlIDxsaW51eC91YWNjZXNzLmg+CiNpbmNsdWRlIDxsaW51eC9zeXNjYWxscy5oPgojaW5jbHVkZSA8bGludXgvYW5vbl9pbm9kZXMuaD4KI2luY2x1ZGUgPGxpbnV4L2tlcm5lbF9zdGF0Lmg+CiNpbmNsdWRlIDxsaW51eC9wZXJmX2V2ZW50Lmg+CiNpbmNsdWRlIDxsaW51eC9mdHJhY2VfZXZlbnQuaD4KI2luY2x1ZGUgPGxpbnV4L2h3X2JyZWFrcG9pbnQuaD4KCiNpbmNsdWRlIDxhc20vaXJxX3JlZ3MuaD4KCmF0b21pY190IHBlcmZfdGFza19ldmVudHMgX19yZWFkX21vc3RseTsKc3RhdGljIGF0b21pY190IG5yX21tYXBfZXZlbnRzIF9fcmVhZF9tb3N0bHk7CnN0YXRpYyBhdG9taWNfdCBucl9jb21tX2V2ZW50cyBfX3JlYWRfbW9zdGx5OwpzdGF0aWMgYXRvbWljX3QgbnJfdGFza19ldmVudHMgX19yZWFkX21vc3RseTsKCnN0YXRpYyBMSVNUX0hFQUQocG11cyk7CnN0YXRpYyBERUZJTkVfTVVURVgocG11c19sb2NrKTsKc3RhdGljIHN0cnVjdCBzcmN1X3N0cnVjdCBwbXVzX3NyY3U7CgovKgogKiBwZXJmIGV2ZW50IHBhcmFub2lhIGxldmVsOgogKiAgLTEgLSBub3QgcGFyYW5vaWQgYXQgYWxsCiAqICAgMCAtIGRpc2FsbG93IHJhdyB0cmFjZXBvaW50IGFjY2VzcyBmb3IgdW5wcml2CiAqICAgMSAtIGRpc2FsbG93IGNwdSBldmVudHMgZm9yIHVucHJpdgogKiAgIDIgLSBkaXNhbGxvdyBrZXJuZWwgcHJvZmlsaW5nIGZvciB1bnByaXYKICovCmludCBzeXNjdGxfcGVyZl9ldmVudF9wYXJhbm9pZCBfX3JlYWRfbW9zdGx5ID0gMTsKCmludCBzeXNjdGxfcGVyZl9ldmVudF9tbG9jayBfX3JlYWRfbW9zdGx5ID0gNTEyOyAvKiAnZnJlZScga2IgcGVyIHVzZXIgKi8KCi8qCiAqIG1heCBwZXJmIGV2ZW50IHNhbXBsZSByYXRlCiAqLwppbnQgc3lzY3RsX3BlcmZfZXZlbnRfc2FtcGxlX3JhdGUgX19yZWFkX21vc3RseSA9IDEwMDAwMDsKCnN0YXRpYyBhdG9taWM2NF90IHBlcmZfZXZlbnRfaWQ7Cgp2b2lkIF9fd2VhayBwZXJmX2V2ZW50X3ByaW50X2RlYnVnKHZvaWQpCXsgfQoKZXh0ZXJuIF9fd2VhayBjb25zdCBjaGFyICpwZXJmX3BtdV9uYW1lKHZvaWQpCnsKCXJldHVybiAicG11IjsKfQoKdm9pZCBwZXJmX3BtdV9kaXNhYmxlKHN0cnVjdCBwbXUgKnBtdSkKewoJaW50ICpjb3VudCA9IHRoaXNfY3B1X3B0cihwbXUtPnBtdV9kaXNhYmxlX2NvdW50KTsKCWlmICghKCpjb3VudCkrKykKCQlwbXUtPnBtdV9kaXNhYmxlKHBtdSk7Cn0KCnZvaWQgcGVyZl9wbXVfZW5hYmxlKHN0cnVjdCBwbXUgKnBtdSkKewoJaW50ICpjb3VudCA9IHRoaXNfY3B1X3B0cihwbXUtPnBtdV9kaXNhYmxlX2NvdW50KTsKCWlmICghLS0oKmNvdW50KSkKCQlwbXUtPnBtdV9lbmFibGUocG11KTsKfQoKc3RhdGljIERFRklORV9QRVJfQ1BVKHN0cnVjdCBsaXN0X2hlYWQsIHJvdGF0aW9uX2xpc3QpOwoKLyoKICogcGVyZl9wbXVfcm90YXRlX3N0YXJ0KCkgYW5kIHBlcmZfcm90YXRlX2NvbnRleHQoKSBhcmUgZnVsbHkgc2VyaWFsaXplZAogKiBiZWNhdXNlIHRoZXkncmUgc3RyaWN0bHkgY3B1IGFmZmluZSBhbmQgcm90YXRlX3N0YXJ0IGlzIGNhbGxlZCB3aXRoIElSUXMKICogZGlzYWJsZWQsIHdoaWxlIHJvdGF0ZV9jb250ZXh0IGlzIGNhbGxlZCBmcm9tIElSUSBjb250ZXh0LgogKi8Kc3RhdGljIHZvaWQgcGVyZl9wbXVfcm90YXRlX3N0YXJ0KHN0cnVjdCBwbXUgKnBtdSkKewoJc3RydWN0IHBlcmZfY3B1X2NvbnRleHQgKmNwdWN0eCA9IHRoaXNfY3B1X3B0cihwbXUtPnBtdV9jcHVfY29udGV4dCk7CglzdHJ1Y3QgbGlzdF9oZWFkICpoZWFkID0gJl9fZ2V0X2NwdV92YXIocm90YXRpb25fbGlzdCk7CgoJV0FSTl9PTighaXJxc19kaXNhYmxlZCgpKTsKCglpZiAobGlzdF9lbXB0eSgmY3B1Y3R4LT5yb3RhdGlvbl9saXN0KSkKCQlsaXN0X2FkZCgmY3B1Y3R4LT5yb3RhdGlvbl9saXN0LCBoZWFkKTsKfQoKc3RhdGljIHZvaWQgZ2V0X2N0eChzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0ICpjdHgpCnsKCVdBUk5fT04oIWF0b21pY19pbmNfbm90X3plcm8oJmN0eC0+cmVmY291bnQpKTsKfQoKc3RhdGljIHZvaWQgZnJlZV9jdHgoc3RydWN0IHJjdV9oZWFkICpoZWFkKQp7CglzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0ICpjdHg7CgoJY3R4ID0gY29udGFpbmVyX29mKGhlYWQsIHN0cnVjdCBwZXJmX2V2ZW50X2NvbnRleHQsIHJjdV9oZWFkKTsKCWtmcmVlKGN0eCk7Cn0KCnN0YXRpYyB2b2lkIHB1dF9jdHgoc3RydWN0IHBlcmZfZXZlbnRfY29udGV4dCAqY3R4KQp7CglpZiAoYXRvbWljX2RlY19hbmRfdGVzdCgmY3R4LT5yZWZjb3VudCkpIHsKCQlpZiAoY3R4LT5wYXJlbnRfY3R4KQoJCQlwdXRfY3R4KGN0eC0+cGFyZW50X2N0eCk7CgkJaWYgKGN0eC0+dGFzaykKCQkJcHV0X3Rhc2tfc3RydWN0KGN0eC0+dGFzayk7CgkJY2FsbF9yY3UoJmN0eC0+cmN1X2hlYWQsIGZyZWVfY3R4KTsKCX0KfQoKc3RhdGljIHZvaWQgdW5jbG9uZV9jdHgoc3RydWN0IHBlcmZfZXZlbnRfY29udGV4dCAqY3R4KQp7CglpZiAoY3R4LT5wYXJlbnRfY3R4KSB7CgkJcHV0X2N0eChjdHgtPnBhcmVudF9jdHgpOwoJCWN0eC0+cGFyZW50X2N0eCA9IE5VTEw7Cgl9Cn0KCnN0YXRpYyB1MzIgcGVyZl9ldmVudF9waWQoc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50LCBzdHJ1Y3QgdGFza19zdHJ1Y3QgKnApCnsKCS8qCgkgKiBvbmx5IHRvcCBsZXZlbCBldmVudHMgaGF2ZSB0aGUgcGlkIG5hbWVzcGFjZSB0aGV5IHdlcmUgY3JlYXRlZCBpbgoJICovCglpZiAoZXZlbnQtPnBhcmVudCkKCQlldmVudCA9IGV2ZW50LT5wYXJlbnQ7CgoJcmV0dXJuIHRhc2tfdGdpZF9ucl9ucyhwLCBldmVudC0+bnMpOwp9CgpzdGF0aWMgdTMyIHBlcmZfZXZlbnRfdGlkKHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCwgc3RydWN0IHRhc2tfc3RydWN0ICpwKQp7CgkvKgoJICogb25seSB0b3AgbGV2ZWwgZXZlbnRzIGhhdmUgdGhlIHBpZCBuYW1lc3BhY2UgdGhleSB3ZXJlIGNyZWF0ZWQgaW4KCSAqLwoJaWYgKGV2ZW50LT5wYXJlbnQpCgkJZXZlbnQgPSBldmVudC0+cGFyZW50OwoKCXJldHVybiB0YXNrX3BpZF9ucl9ucyhwLCBldmVudC0+bnMpOwp9CgovKgogKiBJZiB3ZSBpbmhlcml0IGV2ZW50cyB3ZSB3YW50IHRvIHJldHVybiB0aGUgcGFyZW50IGV2ZW50IGlkCiAqIHRvIHVzZXJzcGFjZS4KICovCnN0YXRpYyB1NjQgcHJpbWFyeV9ldmVudF9pZChzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQpCnsKCXU2NCBpZCA9IGV2ZW50LT5pZDsKCglpZiAoZXZlbnQtPnBhcmVudCkKCQlpZCA9IGV2ZW50LT5wYXJlbnQtPmlkOwoKCXJldHVybiBpZDsKfQoKLyoKICogR2V0IHRoZSBwZXJmX2V2ZW50X2NvbnRleHQgZm9yIGEgdGFzayBhbmQgbG9jayBpdC4KICogVGhpcyBoYXMgdG8gY29wZSB3aXRoIHdpdGggdGhlIGZhY3QgdGhhdCB1bnRpbCBpdCBpcyBsb2NrZWQsCiAqIHRoZSBjb250ZXh0IGNvdWxkIGdldCBtb3ZlZCB0byBhbm90aGVyIHRhc2suCiAqLwpzdGF0aWMgc3RydWN0IHBlcmZfZXZlbnRfY29udGV4dCAqCnBlcmZfbG9ja190YXNrX2NvbnRleHQoc3RydWN0IHRhc2tfc3RydWN0ICp0YXNrLCBpbnQgY3R4biwgdW5zaWduZWQgbG9uZyAqZmxhZ3MpCnsKCXN0cnVjdCBwZXJmX2V2ZW50X2NvbnRleHQgKmN0eDsKCglyY3VfcmVhZF9sb2NrKCk7CnJldHJ5OgoJY3R4ID0gcmN1X2RlcmVmZXJlbmNlKHRhc2stPnBlcmZfZXZlbnRfY3R4cFtjdHhuXSk7CglpZiAoY3R4KSB7CgkJLyoKCQkgKiBJZiB0aGlzIGNvbnRleHQgaXMgYSBjbG9uZSBvZiBhbm90aGVyLCBpdCBtaWdodAoJCSAqIGdldCBzd2FwcGVkIGZvciBhbm90aGVyIHVuZGVybmVhdGggdXMgYnkKCQkgKiBwZXJmX2V2ZW50X3Rhc2tfc2NoZWRfb3V0LCB0aG91Z2ggdGhlCgkJICogcmN1X3JlYWRfbG9jaygpIHByb3RlY3RzIHVzIGZyb20gYW55IGNvbnRleHQKCQkgKiBnZXR0aW5nIGZyZWVkLiAgTG9jayB0aGUgY29udGV4dCBhbmQgY2hlY2sgaWYgaXQKCQkgKiBnb3Qgc3dhcHBlZCBiZWZvcmUgd2UgY291bGQgZ2V0IHRoZSBsb2NrLCBhbmQgcmV0cnkKCQkgKiBpZiBzby4gIElmIHdlIGxvY2tlZCB0aGUgcmlnaHQgY29udGV4dCwgdGhlbiBpdAoJCSAqIGNhbid0IGdldCBzd2FwcGVkIG9uIHVzIGFueSBtb3JlLgoJCSAqLwoJCXJhd19zcGluX2xvY2tfaXJxc2F2ZSgmY3R4LT5sb2NrLCAqZmxhZ3MpOwoJCWlmIChjdHggIT0gcmN1X2RlcmVmZXJlbmNlKHRhc2stPnBlcmZfZXZlbnRfY3R4cFtjdHhuXSkpIHsKCQkJcmF3X3NwaW5fdW5sb2NrX2lycXJlc3RvcmUoJmN0eC0+bG9jaywgKmZsYWdzKTsKCQkJZ290byByZXRyeTsKCQl9CgoJCWlmICghYXRvbWljX2luY19ub3RfemVybygmY3R4LT5yZWZjb3VudCkpIHsKCQkJcmF3X3NwaW5fdW5sb2NrX2lycXJlc3RvcmUoJmN0eC0+bG9jaywgKmZsYWdzKTsKCQkJY3R4ID0gTlVMTDsKCQl9Cgl9CglyY3VfcmVhZF91bmxvY2soKTsKCXJldHVybiBjdHg7Cn0KCi8qCiAqIEdldCB0aGUgY29udGV4dCBmb3IgYSB0YXNrIGFuZCBpbmNyZW1lbnQgaXRzIHBpbl9jb3VudCBzbyBpdAogKiBjYW4ndCBnZXQgc3dhcHBlZCB0byBhbm90aGVyIHRhc2suICBUaGlzIGFsc28gaW5jcmVtZW50cyBpdHMKICogcmVmZXJlbmNlIGNvdW50IHNvIHRoYXQgdGhlIGNvbnRleHQgY2FuJ3QgZ2V0IGZyZWVkLgogKi8Kc3RhdGljIHN0cnVjdCBwZXJmX2V2ZW50X2NvbnRleHQgKgpwZXJmX3Bpbl90YXNrX2NvbnRleHQoc3RydWN0IHRhc2tfc3RydWN0ICp0YXNrLCBpbnQgY3R4bikKewoJc3RydWN0IHBlcmZfZXZlbnRfY29udGV4dCAqY3R4OwoJdW5zaWduZWQgbG9uZyBmbGFnczsKCgljdHggPSBwZXJmX2xvY2tfdGFza19jb250ZXh0KHRhc2ssIGN0eG4sICZmbGFncyk7CglpZiAoY3R4KSB7CgkJKytjdHgtPnBpbl9jb3VudDsKCQlyYXdfc3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmY3R4LT5sb2NrLCBmbGFncyk7Cgl9CglyZXR1cm4gY3R4Owp9CgpzdGF0aWMgdm9pZCBwZXJmX3VucGluX2NvbnRleHQoc3RydWN0IHBlcmZfZXZlbnRfY29udGV4dCAqY3R4KQp7Cgl1bnNpZ25lZCBsb25nIGZsYWdzOwoKCXJhd19zcGluX2xvY2tfaXJxc2F2ZSgmY3R4LT5sb2NrLCBmbGFncyk7CgktLWN0eC0+cGluX2NvdW50OwoJcmF3X3NwaW5fdW5sb2NrX2lycXJlc3RvcmUoJmN0eC0+bG9jaywgZmxhZ3MpOwoJcHV0X2N0eChjdHgpOwp9CgpzdGF0aWMgaW5saW5lIHU2NCBwZXJmX2Nsb2NrKHZvaWQpCnsKCXJldHVybiBsb2NhbF9jbG9jaygpOwp9CgovKgogKiBVcGRhdGUgdGhlIHJlY29yZCBvZiB0aGUgY3VycmVudCB0aW1lIGluIGEgY29udGV4dC4KICovCnN0YXRpYyB2b2lkIHVwZGF0ZV9jb250ZXh0X3RpbWUoc3RydWN0IHBlcmZfZXZlbnRfY29udGV4dCAqY3R4KQp7Cgl1NjQgbm93ID0gcGVyZl9jbG9jaygpOwoKCWN0eC0+dGltZSArPSBub3cgLSBjdHgtPnRpbWVzdGFtcDsKCWN0eC0+dGltZXN0YW1wID0gbm93Owp9CgovKgogKiBVcGRhdGUgdGhlIHRvdGFsX3RpbWVfZW5hYmxlZCBhbmQgdG90YWxfdGltZV9ydW5uaW5nIGZpZWxkcyBmb3IgYSBldmVudC4KICovCnN0YXRpYyB2b2lkIHVwZGF0ZV9ldmVudF90aW1lcyhzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQpCnsKCXN0cnVjdCBwZXJmX2V2ZW50X2NvbnRleHQgKmN0eCA9IGV2ZW50LT5jdHg7Cgl1NjQgcnVuX2VuZDsKCglpZiAoZXZlbnQtPnN0YXRlIDwgUEVSRl9FVkVOVF9TVEFURV9JTkFDVElWRSB8fAoJICAgIGV2ZW50LT5ncm91cF9sZWFkZXItPnN0YXRlIDwgUEVSRl9FVkVOVF9TVEFURV9JTkFDVElWRSkKCQlyZXR1cm47CgoJaWYgKGN0eC0+aXNfYWN0aXZlKQoJCXJ1bl9lbmQgPSBjdHgtPnRpbWU7CgllbHNlCgkJcnVuX2VuZCA9IGV2ZW50LT50c3RhbXBfc3RvcHBlZDsKCglldmVudC0+dG90YWxfdGltZV9lbmFibGVkID0gcnVuX2VuZCAtIGV2ZW50LT50c3RhbXBfZW5hYmxlZDsKCglpZiAoZXZlbnQtPnN0YXRlID09IFBFUkZfRVZFTlRfU1RBVEVfSU5BQ1RJVkUpCgkJcnVuX2VuZCA9IGV2ZW50LT50c3RhbXBfc3RvcHBlZDsKCWVsc2UKCQlydW5fZW5kID0gY3R4LT50aW1lOwoKCWV2ZW50LT50b3RhbF90aW1lX3J1bm5pbmcgPSBydW5fZW5kIC0gZXZlbnQtPnRzdGFtcF9ydW5uaW5nOwp9CgovKgogKiBVcGRhdGUgdG90YWxfdGltZV9lbmFibGVkIGFuZCB0b3RhbF90aW1lX3J1bm5pbmcgZm9yIGFsbCBldmVudHMgaW4gYSBncm91cC4KICovCnN0YXRpYyB2b2lkIHVwZGF0ZV9ncm91cF90aW1lcyhzdHJ1Y3QgcGVyZl9ldmVudCAqbGVhZGVyKQp7CglzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQ7CgoJdXBkYXRlX2V2ZW50X3RpbWVzKGxlYWRlcik7CglsaXN0X2Zvcl9lYWNoX2VudHJ5KGV2ZW50LCAmbGVhZGVyLT5zaWJsaW5nX2xpc3QsIGdyb3VwX2VudHJ5KQoJCXVwZGF0ZV9ldmVudF90aW1lcyhldmVudCk7Cn0KCnN0YXRpYyBzdHJ1Y3QgbGlzdF9oZWFkICoKY3R4X2dyb3VwX2xpc3Qoc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50LCBzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0ICpjdHgpCnsKCWlmIChldmVudC0+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+Y3B1ID09IHNtcF9wcm9jZXNzb3JfaWQoKTsKfQoKc3RhdGljIHZvaWQKZXZlbnRfc2NoZWRfb3V0KHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCwKCQkgIHN0cnVjdCBwZXJmX2NwdV9jb250ZXh0ICpjcHVjdHgsCgkJICBzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0ICpjdHgpCnsKCXU2NCBkZWx0YTsKCS8qCgkgKiBBbiBldmVudCB3aGljaCBjb3VsZCBub3QgYmUgYWN0aXZhdGVkIGJlY2F1c2Ugb2YKCSAqIGZpbHRlciBtaXNtYXRjaCBzdGlsbCBuZWVkcyB0byBoYXZlIGl0cyB0aW1pbmdzCgkgKiBtYWludGFpbmVkLCBvdGhlcndpc2UgYm9ndXMgaW5mb3JtYXRpb24gaXMgcmV0dXJuCgkgKiB2aWEgcmVhZCgpIGZvciB0aW1lX2VuYWJsZWQsIHRpbWVfcnVubmluZzoKCSAqLwoJaWYgKGV2ZW50LT5zdGF0ZSA9PSBQRVJGX0VWRU5UX1NUQVRFX0lOQUNUSVZFCgkgICAgJiYgIWV2ZW50X2ZpbHRlcl9tYXRjaChldmVudCkpIHsKCQlkZWx0YSA9IGN0eC0+dGltZSAtIGV2ZW50LT50c3RhbXBfc3RvcHBlZDsKCQlldmVudC0+dHN0YW1wX3J1bm5pbmcgKz0gZGVsdGE7CgkJZXZlbnQtPnRzdGFtcF9zdG9wcGVkID0gY3R4LT50aW1lOwoJfQoKCWlmIChldmVudC0+c3RhdGUgIT0gUEVSRl9FVkVOVF9TVEFURV9BQ1RJVkUpCgkJcmV0dXJuOwoKCWV2ZW50LT5zdGF0ZSA9IFBFUkZfRVZFTlRfU1RBVEVfSU5BQ1RJVkU7CglpZiAoZXZlbnQtPnBlbmRpbmdfZGlzYWJsZSkgewoJCWV2ZW50LT5wZW5kaW5nX2Rpc2FibGUgPSAwOwoJCWV2ZW50LT5zdGF0ZSA9IFBFUkZfRVZFTlRfU1RBVEVfT0ZGOwoJfQoJZXZlbnQtPnRzdGFtcF9zdG9wcGVkID0gY3R4LT50aW1lOwoJZXZlbnQtPnBtdS0+ZGVsKGV2ZW50LCAwKTsKCWV2ZW50LT5vbmNwdSA9IC0xOwoKCWlmICghaXNfc29mdHdhcmVfZXZlbnQoZXZlbnQpKQoJCWNwdWN0eC0+YWN0aXZlX29uY3B1LS07CgljdHgtPm5yX2FjdGl2ZS0tOwoJaWYgKGV2ZW50LT5hdHRyLmV4Y2x1c2l2ZSB8fCAhY3B1Y3R4LT5hY3RpdmVfb25jcHUpCgkJY3B1Y3R4LT5leGNsdXNpdmUgPSAwOwp9CgpzdGF0aWMgdm9pZApncm91cF9zY2hlZF9vdXQoc3RydWN0IHBlcmZfZXZlbnQgKmdyb3VwX2V2ZW50LAoJCXN0cnVjdCBwZXJmX2NwdV9jb250ZXh0ICpjcHVjdHgsCgkJc3RydWN0IHBlcmZfZXZlbnRfY29udGV4dCAqY3R4KQp7CglzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQ7CglpbnQgc3RhdGUgPSBncm91cF9ldmVudC0+c3RhdGU7CgoJZXZlbnRfc2NoZWRfb3V0KGdyb3VwX2V2ZW50LCBjcHVjdHgsIGN0eCk7CgoJLyoKCSAqIFNjaGVkdWxlIG91dCBzaWJsaW5ncyAoaWYgYW55KToKCSAqLwoJbGlzdF9mb3JfZWFjaF9lbnRyeShldmVudCwgJmdyb3VwX2V2ZW50LT5zaWJsaW5nX2xpc3QsIGdyb3VwX2VudHJ5KQoJCWV2ZW50X3NjaGVkX291dChldmVudCwgY3B1Y3R4LCBjdHgpOwoKCWlmIChzdGF0ZSA9PSBQRVJGX0VWRU5UX1NUQVRFX0FDVElWRSAmJiBncm91cF9ldmVudC0+YXR0ci5leGNsdXNpdmUpCgkJY3B1Y3R4LT5leGNsdXNpdmUgPSAwOwp9CgpzdGF0aWMgaW5saW5lIHN0cnVjdCBwZXJmX2NwdV9jb250ZXh0ICoKX19nZXRfY3B1X2NvbnRleHQoc3RydWN0IHBlcmZfZXZlbnRfY29udGV4dCAqY3R4KQp7CglyZXR1cm4gdGhpc19jcHVfcHRyKGN0eC0+cG11LT5wbXVfY3B1X2NvbnRleHQpOwp9CgovKgogKiBDcm9zcyBDUFUgY2FsbCB0byByZW1vdmUgYSBwZXJmb3JtYW5jZSBldmVudAogKgogKiBXZSBkaXNhYmxlIHRoZSBldmVudCBvbiB0aGUgaGFyZHdhcmUgbGV2ZWwgZmlyc3QuIEFmdGVyIHRoYXQgd2UKICogcmVtb3ZlIGl0IGZyb20gdGhlIGNvbnRleHQgbGlzdC4KICovCnN0YXRpYyB2b2lkIF9fcGVyZl9ldmVudF9yZW1vdmVfZnJvbV9jb250ZXh0KHZvaWQgKmluZm8pCnsKCXN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCA9IGluZm87CglzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0ICpjdHggPSBldmVudC0+Y3R4OwoJc3RydWN0IHBlcmZfY3B1X2NvbnRleHQgKmNwdWN0eCA9IF9fZ2V0X2NwdV9jb250ZXh0KGN0eCk7CgoJLyoKCSAqIElmIHRoaXMgaXMgYSB0YXNrIGNvbnRleHQsIHdlIG5lZWQgdG8gY2hlY2sgd2hldGhlciBpdCBpcwoJICogdGhlIGN1cnJlbnQgdGFzayBjb250ZXh0IG9mIHRoaXMgY3B1LiBJZiBub3QgaXQgaGFzIGJlZW4KCSAqIHNjaGVkdWxlZCBvdXQgYmVmb3JlIHRoZSBzbXAgY2FsbCBhcnJpdmVkLgoJICovCglpZiAoY3R4LT50YXNrICYmIGNwdWN0eC0+dGFza19jdHggIT0gY3R4KQoJCXJldHVybjsKCglyYXdfc3Bpbl9sb2NrKCZjdHgtPmxvY2spOwoKCWV2ZW50X3NjaGVkX291dChldmVudCwgY3B1Y3R4LCBjdHgpOwoKCWxpc3RfZGVsX2V2ZW50KGV2ZW50LCBjdHgpOwoKCXJhd19zcGluX3VubG9jaygmY3R4LT5sb2NrKTsKfQoKCi8qCiAqIFJlbW92ZSB0aGUgZXZlbnQgZnJvbSBhIHRhc2sncyAob3IgYSBDUFUncykgbGlzdCBvZiBldmVudHMuCiAqCiAqIE11c3QgYmUgY2FsbGVkIHdpdGggY3R4LT5tdXRleCBoZWxkLgogKgogKiBDUFUgZXZlbnRzIGFyZSByZW1vdmVkIHdpdGggYSBzbXAgY2FsbC4gRm9yIHRhc2sgZXZlbnRzIHdlIG9ubHkKICogY2FsbCB3aGVuIHRoZSB0YXNrIGlzIG9uIGEgQ1BVLgogKgogKiBJZiBldmVudC0+Y3R4IGlzIGEgY2xvbmVkIGNvbnRleHQsIGNhbGxlcnMgbXVzdCBtYWtlIHN1cmUgdGhhdAogKiBldmVyeSB0YXNrIHN0cnVjdCB0aGF0IGV2ZW50LT5jdHgtPnRhc2sgY291bGQgcG9zc2libHkgcG9pbnQgdG8KICogcmVtYWlucyB2YWxpZC4gIFRoaXMgaXMgT0sgd2hlbiBjYWxsZWQgZnJvbSBwZXJmX3JlbGVhc2Ugc2luY2UKICogdGhhdCBvbmx5IGNhbGxzIHVzIG9uIHRoZSB0b3AtbGV2ZWwgY29udGV4dCwgd2hpY2ggY2FuJ3QgYmUgYSBjbG9uZS4KICogV2hlbiBjYWxsZWQgZnJvbSBwZXJmX2V2ZW50X2V4aXRfdGFzaywgaXQncyBPSyBiZWNhdXNlIHRoZQogKiBjb250ZXh0IGhhcyBiZWVuIGRldGFjaGVkIGZyb20gaXRzIHRhc2suCiAqLwpzdGF0aWMgdm9pZCBwZXJmX2V2ZW50X3JlbW92ZV9mcm9tX2NvbnRleHQoc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50KQp7CglzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0ICpjdHggPSBldmVudC0+Y3R4OwoJc3RydWN0IHRhc2tfc3RydWN0ICp0YXNrID0gY3R4LT50YXNrOwoKCWlmICghdGFzaykgewoJCS8qCgkJICogUGVyIGNwdSBldmVudHMgYXJlIHJlbW92ZWQgdmlhIGFuIHNtcCBjYWxsIGFuZAoJCSAqIHRoZSByZW1vdmFsIGlzIGFsd2F5cyBzdWNjZXNzZnVsLgoJCSAqLwoJCXNtcF9jYWxsX2Z1bmN0aW9uX3NpbmdsZShldmVudC0+Y3B1LAoJCQkJCSBfX3BlcmZfZXZlbnRfcmVtb3ZlX2Zyb21fY29udGV4dCwKCQkJCQkgZXZlbnQsIDEpOwoJCXJldHVybjsKCX0KCnJldHJ5OgoJdGFza19vbmNwdV9mdW5jdGlvbl9jYWxsKHRhc2ssIF9fcGVyZl9ldmVudF9yZW1vdmVfZnJvbV9jb250ZXh0LAoJCQkJIGV2ZW50KTsKCglyYXdfc3Bpbl9sb2NrX2lycSgmY3R4LT5sb2NrKTsKCS8qCgkgKiBJZiB0aGUgY29udGV4dCBpcyBhY3RpdmUgd2UgbmVlZCB0byByZXRyeSB0aGUgc21wIGNhbGwuCgkgKi8KCWlmIChjdHgtPm5yX2FjdGl2ZSAmJiAhbGlzdF9lbXB0eSgmZXZlbnQtPmdyb3VwX2VudHJ5KSkgewoJCXJhd19zcGluX3VubG9ja19pcnEoJmN0eC0+bG9jayk7CgkJZ290byByZXRyeTsKCX0KCgkvKgoJICogVGhlIGxvY2sgcHJldmVudHMgdGhhdCB0aGlzIGNvbnRleHQgaXMgc2NoZWR1bGVkIGluIHNvIHdlCgkgKiBjYW4gcmVtb3ZlIHRoZSBldmVudCBzYWZlbHksIGlmIHRoZSBjYWxsIGFib3ZlIGRpZCBub3QKCSAqIHN1Y2NlZWQuCgkgKi8KCWlmICghbGlzdF9lbXB0eSgmZXZlbnQtPmdyb3VwX2VudHJ5KSkKCQlsaXN0X2RlbF9ldmVudChldmVudCwgY3R4KTsKCXJhd19zcGluX3VubG9ja19pcnEoJmN0eC0+bG9jayk7Cn0KCi8qCiAqIENyb3NzIENQVSBjYWxsIHRvIGRpc2FibGUgYSBwZXJmb3JtYW5jZSBldmVudAogKi8Kc3RhdGljIHZvaWQgX19wZXJmX2V2ZW50X2Rpc2FibGUodm9pZCAqaW5mbykKewoJc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50ID0gaW5mbzsKCXN0cnVjdCBwZXJmX2V2ZW50X2NvbnRleHQgKmN0eCA9IGV2ZW50LT5jdHg7CglzdHJ1Y3QgcGVyZl9jcHVfY29udGV4dCAqY3B1Y3R4ID0gX19nZXRfY3B1X2NvbnRleHQoY3R4KTsKCgkvKgoJICogSWYgdGhpcyBpcyBhIHBlci10YXNrIGV2ZW50LCBuZWVkIHRvIGNoZWNrIHdoZXRoZXIgdGhpcwoJICogZXZlbnQncyB0YXNrIGlzIHRoZSBjdXJyZW50IHRhc2sgb24gdGhpcyBjcHUuCgkgKi8KCWlmIChjdHgtPnRhc2sgJiYgY3B1Y3R4LT50YXNrX2N0eCAhPSBjdHgpCgkJcmV0dXJuOwoKCXJhd19zcGluX2xvY2soJmN0eC0+bG9jayk7CgoJLyoKCSAqIElmIHRoZSBldmVudCBpcyBvbiwgdHVybiBpdCBvZmYuCgkgKiBJZiBpdCBpcyBpbiBlcnJvciBzdGF0ZSwgbGVhdmUgaXQgaW4gZXJyb3Igc3RhdGUuCgkgKi8KCWlmIChldmVudC0+c3RhdGUgPj0gUEVSRl9FVkVOVF9TVEFURV9JTkFDVElWRSkgewoJCXVwZGF0ZV9jb250ZXh0X3RpbWUoY3R4KTsKCQl1cGRhdGVfZ3JvdXBfdGltZXMoZXZlbnQpOwoJCWlmIChldmVudCA9PSBldmVudC0+Z3JvdXBfbGVhZGVyKQoJCQlncm91cF9zY2hlZF9vdXQoZXZlbnQsIGNwdWN0eCwgY3R4KTsKCQllbHNlCgkJCWV2ZW50X3NjaGVkX291dChldmVudCwgY3B1Y3R4LCBjdHgpOwoJCWV2ZW50LT5zdGF0ZSA9IFBFUkZfRVZFTlRfU1RBVEVfT0ZGOwoJfQoKCXJhd19zcGluX3VubG9jaygmY3R4LT5sb2NrKTsKfQoKLyoKICogRGlzYWJsZSBhIGV2ZW50LgogKgogKiBJZiBldmVudC0+Y3R4IGlzIGEgY2xvbmVkIGNvbnRleHQsIGNhbGxlcnMgbXVzdCBtYWtlIHN1cmUgdGhhdAogKiBldmVyeSB0YXNrIHN0cnVjdCB0aGF0IGV2ZW50LT5jdHgtPnRhc2sgY291bGQgcG9zc2libHkgcG9pbnQgdG8KICogcmVtYWlucyB2YWxpZC4gIFRoaXMgY29uZGl0aW9uIGlzIHNhdGlzaWZlZCB3aGVuIGNhbGxlZCB0aHJvdWdoCiAqIHBlcmZfZXZlbnRfZm9yX2VhY2hfY2hpbGQgb3IgcGVyZl9ldmVudF9mb3JfZWFjaCBiZWNhdXNlIHRoZXkKICogaG9sZCB0aGUgdG9wLWxldmVsIGV2ZW50J3MgY2hpbGRfbXV0ZXgsIHNvIGFueSBkZXNjZW5kYW50IHRoYXQKICogZ29lcyB0byBleGl0IHdpbGwgYmxvY2sgaW4gc3luY19jaGlsZF9ldmVudC4KICogV2hlbiBjYWxsZWQgZnJvbSBwZXJmX3BlbmRpbmdfZXZlbnQgaXQncyBPSyBiZWNhdXNlIGV2ZW50LT5jdHgKICogaXMgdGhlIGN1cnJlbnQgY29udGV4dCBvbiB0aGlzIENQVSBhbmQgcHJlZW1wdGlvbiBpcyBkaXNhYmxlZCwKICogaGVuY2Ugd2UgY2FuJ3QgZ2V0IGludG8gcGVyZl9ldmVudF90YXNrX3NjaGVkX291dCBmb3IgdGhpcyBjb250ZXh0LgogKi8Kdm9pZCBwZXJmX2V2ZW50X2Rpc2FibGUoc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50KQp7CglzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0ICpjdHggPSBldmVudC0+Y3R4OwoJc3RydWN0IHRhc2tfc3RydWN0ICp0YXNrID0gY3R4LT50YXNrOwoKCWlmICghdGFzaykgewoJCS8qCgkJICogRGlzYWJsZSB0aGUgZXZlbnQgb24gdGhlIGNwdSB0aGF0IGl0J3Mgb24KCQkgKi8KCQlzbXBfY2FsbF9mdW5jdGlvbl9zaW5nbGUoZXZlbnQtPmNwdSwgX19wZXJmX2V2ZW50X2Rpc2FibGUsCgkJCQkJIGV2ZW50LCAxKTsKCQlyZXR1cm47Cgl9CgpyZXRyeToKCXRhc2tfb25jcHVfZnVuY3Rpb25fY2FsbCh0YXNrLCBfX3BlcmZfZXZlbnRfZGlzYWJsZSwgZXZlbnQpOwoKCXJhd19zcGluX2xvY2tfaXJxKCZjdHgtPmxvY2spOwoJLyoKCSAqIElmIHRoZSBldmVudCBpcyBzdGlsbCBhY3RpdmUsIHdlIG5lZWQgdG8gcmV0cnkgdGhlIGNyb3NzLWNhbGwuCgkgKi8KCWlmIChldmVudC0+c3RhdGUgPT0gUEVSRl9FVkVOVF9TVEFURV9BQ1RJVkUpIHsKCQlyYXdfc3Bpbl91bmxvY2tfaXJxKCZjdHgtPmxvY2spOwoJCWdvdG8gcmV0cnk7Cgl9CgoJLyoKCSAqIFNpbmNlIHdlIGhhdmUgdGhlIGxvY2sgdGhpcyBjb250ZXh0IGNhbid0IGJlIHNjaGVkdWxlZAoJICogaW4sIHNvIHdlIGNhbiBjaGFuZ2UgdGhlIHN0YXRlIHNhZmVseS4KCSAqLwoJaWYgKGV2ZW50LT5zdGF0ZSA9PSBQRVJGX0VWRU5UX1NUQVRFX0lOQUNUSVZFKSB7CgkJdXBkYXRlX2dyb3VwX3RpbWVzKGV2ZW50KTsKCQlldmVudC0+c3RhdGUgPSBQRVJGX0VWRU5UX1NUQVRFX09GRjsKCX0KCglyYXdfc3Bpbl91bmxvY2tfaXJxKCZjdHgtPmxvY2spOwp9CgpzdGF0aWMgaW50CmV2ZW50X3NjaGVkX2luKHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCwKCQkgc3RydWN0IHBlcmZfY3B1X2NvbnRleHQgKmNwdWN0eCwKCQkgc3RydWN0IHBlcmZfZXZlbnRfY29udGV4dCAqY3R4KQp7CglpZiAoZXZlbnQtPnN0YXRlIDw9IFBFUkZfRVZFTlRfU1RBVEVfT0ZGKQoJCXJldHVybiAwOwoKCWV2ZW50LT5zdGF0ZSA9IFBFUkZfRVZFTlRfU1RBVEVfQUNUSVZFOwoJZXZlbnQtPm9uY3B1ID0gc21wX3Byb2Nlc3Nvcl9pZCgpOwoJLyoKCSAqIFRoZSBuZXcgc3RhdGUgbXVzdCBiZSB2aXNpYmxlIGJlZm9yZSB3ZSB0dXJuIGl0IG9uIGluIHRoZSBoYXJkd2FyZToKCSAqLwoJc21wX3dtYigpOwoKCWlmIChldmVudC0+cG11LT5hZGQoZXZlbnQsIFBFUkZfRUZfU1RBUlQpKSB7CgkJZXZlbnQtPnN0YXRlID0gUEVSRl9FVkVOVF9TVEFURV9JTkFDVElWRTsKCQlldmVudC0+b25jcHUgPSAtMTsKCQlyZXR1cm4gLUVBR0FJTjsKCX0KCglldmVudC0+dHN0YW1wX3J1bm5pbmcgKz0gY3R4LT50aW1lIC0gZXZlbnQtPnRzdGFtcF9zdG9wcGVkOwoKCWV2ZW50LT5zaGFkb3dfY3R4X3RpbWUgPSBjdHgtPnRpbWUgLSBjdHgtPnRpbWVzdGFtcDsKCglpZiAoIWlzX3NvZnR3YXJlX2V2ZW50KGV2ZW50KSkKCQljcHVjdHgtPmFjdGl2ZV9vbmNwdSsrOwoJY3R4LT5ucl9hY3RpdmUrKzsKCglpZiAoZXZlbnQtPmF0dHIuZXhjbHVzaXZlKQoJCWNwdWN0eC0+ZXhjbHVzaXZlID0gMTsKCglyZXR1cm4gMDsKfQoKc3RhdGljIGludApncm91cF9zY2hlZF9pbihzdHJ1Y3QgcGVyZl9ldmVudCAqZ3JvdXBfZXZlbnQsCgkgICAgICAgc3RydWN0IHBlcmZfY3B1X2NvbnRleHQgKmNwdWN0eCwKCSAgICAgICBzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0ICpjdHgpCnsKCXN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCwgKnBhcnRpYWxfZ3JvdXAgPSBOVUxMOwoJc3RydWN0IHBtdSAqcG11ID0gZ3JvdXBfZXZlbnQtPnBtdTsKCXU2NCBub3cgPSBjdHgtPnRpbWU7Cglib29sIHNpbXVsYXRlID0gZmFsc2U7CgoJaWYgKGdyb3VwX2V2ZW50LT5zdGF0ZSA9PSBQRVJGX0VWRU5UX1NUQVRFX09GRikKCQlyZXR1cm4gMDsKCglwbXUtPnN0YXJ0X3R4bihwbXUpOwoKCWlmIChldmVudF9zY2hlZF9pbihncm91cF9ldmVudCwgY3B1Y3R4LCBjdHgpKSB7CgkJcG11LT5jYW5jZWxfdHhuKHBtdSk7CgkJcmV0dXJuIC1FQUdBSU47Cgl9CgoJLyoKCSAqIFNjaGVkdWxlIGluIHNpYmxpbmdzIGFzIG9uZSBncm91cCAoaWYgYW55KToKCSAqLwoJbGlzdF9mb3JfZWFjaF9lbnRyeShldmVudCwgJmdyb3VwX2V2ZW50LT5zaWJsaW5nX2xpc3QsIGdyb3VwX2VudHJ5KSB7CgkJaWYgKGV2ZW50X3NjaGVkX2luKGV2ZW50LCBjcHVjdHgsIGN0eCkpIHsKCQkJcGFydGlhbF9ncm91cCA9IGV2ZW50OwoJCQlnb3RvIGdyb3VwX2Vycm9yOwoJCX0KCX0KCglpZiAoIXBtdS0+Y29tbWl0X3R4bihwbXUpKQoJCXJldHVybiAwOwoKZ3JvdXBfZXJyb3I6CgkvKgoJICogR3JvdXBzIGNhbiBiZSBzY2hlZHVsZWQgaW4gYXMgb25lIHVuaXQgb25seSwgc28gdW5kbyBhbnkKCSAqIHBhcnRpYWwgZ3JvdXAgYmVmb3JlIHJldHVybmluZzoKCSAqIFRoZSBldmVudHMgdXAgdG8gdGhlIGZhaWxlZCBldmVudCBhcmUgc2NoZWR1bGVkIG91dCBub3JtYWxseSwKCSAqIHRzdGFtcF9zdG9wcGVkIHdpbGwgYmUgdXBkYXRlZC4KCSAqCgkgKiBUaGUgZmFpbGVkIGV2ZW50cyBhbmQgdGhlIHJlbWFpbmluZyBzaWJsaW5ncyBuZWVkIHRvIGhhdmUKCSAqIHRoZWlyIHRpbWluZ3MgdXBkYXRlZCBhcyBpZiB0aGV5IGhhZCBnb25lIHRocnUgZXZlbnRfc2NoZWRfaW4oKQoJICogYW5kIGV2ZW50X3NjaGVkX291dCgpLiBUaGlzIGlzIHJlcXVpcmVkIHRvIGdldCBjb25zaXN0ZW50IHRpbWluZ3MKCSAqIGFjcm9zcyB0aGUgZ3JvdXAuIFRoaXMgYWxzbyB0YWtlcyBjYXJlIG9mIHRoZSBjYXNlIHdoZXJlIHRoZSBncm91cAoJICogY291bGQgbmV2ZXIgYmUgc2NoZWR1bGVkIGJ5IGVuc3VyaW5nIHRzdGFtcF9zdG9wcGVkIGlzIHNldCB0byBtYXJrCgkgKiB0aGUgdGltZSB0aGUgZXZlbnQgd2FzIGFjdHVhbGx5IHN0b3BwZWQsIHN1Y2ggdGhhdCB0aW1lIGRlbHRhCgkgKiBjYWxjdWxhdGlvbiBpbiB1cGRhdGVfZXZlbnRfdGltZXMoKSBpcyBjb3JyZWN0LgoJICovCglsaXN0X2Zvcl9lYWNoX2VudHJ5KGV2ZW50LCAmZ3JvdXBfZXZlbnQtPnNpYmxpbmdfbGlzdCwgZ3JvdXBfZW50cnkpIHsKCQlpZiAoZXZlbnQgPT0gcGFydGlhbF9ncm91cCkKCQkJc2ltdWxhdGUgPSB0cnVlOwoKCQlpZiAoc2ltdWxhdGUpIHsKCQkJZXZlbnQtPnRzdGFtcF9ydW5uaW5nICs9IG5vdyAtIGV2ZW50LT50c3RhbXBfc3RvcHBlZDsKCQkJZXZlbnQtPnRzdGFtcF9zdG9wcGVkID0gbm93OwoJCX0gZWxzZSB7CgkJCWV2ZW50X3NjaGVkX291dChldmVudCwgY3B1Y3R4LCBjdHgpOwoJCX0KCX0KCWV2ZW50X3NjaGVkX291dChncm91cF9ldmVudCwgY3B1Y3R4LCBjdHgpOwoKCXBtdS0+Y2FuY2VsX3R4bihwbXUpOwoKCXJldHVybiAtRUFHQUlOOwp9CgovKgogKiBXb3JrIG91dCB3aGV0aGVyIHdlIGNhbiBwdXQgdGhpcyBldmVudCBncm91cCBvbiB0aGUgQ1BVIG5vdy4KICovCnN0YXRpYyBpbnQgZ3JvdXBfY2FuX2dvX29uKHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCwKCQkJICAgc3RydWN0IHBlcmZfY3B1X2NvbnRleHQgKmNwdWN0eCwKCQkJICAgaW50IGNhbl9hZGRfaHcpCnsKCS8qCgkgKiBHcm91cHMgY29uc2lzdGluZyBlbnRpcmVseSBvZiBzb2Z0d2FyZSBldmVudHMgY2FuIGFsd2F5cyBnbyBvbi4KCSAqLwoJaWYgKGV2ZW50LT5ncm91cF9mbGFncyAmIFBFUkZfR1JPVVBfU09GVFdBUkUpCgkJcmV0dXJuIDE7CgkvKgoJICogSWYgYW4gZXhjbHVzaXZlIGdyb3VwIGlzIGFscmVhZHkgb24sIG5vIG90aGVyIGhhcmR3YXJlCgkgKiBldmVudHMgY2FuIGdvIG9uLgoJICovCglpZiAoY3B1Y3R4LT5leGNsdXNpdmUpCgkJcmV0dXJuIDA7CgkvKgoJICogSWYgdGhpcyBncm91cCBpcyBleGNsdXNpdmUgYW5kIHRoZXJlIGFyZSBhbHJlYWR5CgkgKiBldmVudHMgb24gdGhlIENQVSwgaXQgY2FuJ3QgZ28gb24uCgkgKi8KCWlmIChldmVudC0+YXR0ci5leGNsdXNpdmUgJiYgY3B1Y3R4LT5hY3RpdmVfb25jcHUpCgkJcmV0dXJuIDA7CgkvKgoJICogT3RoZXJ3aXNlLCB0cnkgdG8gYWRkIGl0IGlmIGFsbCBwcmV2aW91cyBncm91cHMgd2VyZSBhYmxlCgkgKiB0byBnbyBvbi4KCSAqLwoJcmV0dXJuIGNhbl9hZGRfaHc7Cn0KCnN0YXRpYyB2b2lkIGFkZF9ldmVudF90b19jdHgoc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50LAoJCQkgICAgICAgc3RydWN0IHBlcmZfZXZlbnRfY29udGV4dCAqY3R4KQp7CglsaXN0X2FkZF9ldmVudChldmVudCwgY3R4KTsKCXBlcmZfZ3JvdXBfYXR0YWNoKGV2ZW50KTsKCWV2ZW50LT50c3RhbXBfZW5hYmxlZCA9IGN0eC0+dGltZTsKCWV2ZW50LT50c3RhbXBfcnVubmluZyA9IGN0eC0+dGltZTsKCWV2ZW50LT50c3RhbXBfc3RvcHBlZCA9IGN0eC0+dGltZTsKfQoKLyoKICogQ3Jvc3MgQ1BVIGNhbGwgdG8gaW5zdGFsbCBhbmQgZW5hYmxlIGEgcGVyZm9ybWFuY2UgZXZlbnQKICoKICogTXVzdCBiZSBjYWxsZWQgd2l0aCBjdHgtPm11dGV4IGhlbGQKICovCnN0YXRpYyB2b2lkIF9fcGVyZl9pbnN0YWxsX2luX2NvbnRleHQodm9pZCAqaW5mbykKewoJc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50ID0gaW5mbzsKCXN0cnVjdCBwZXJmX2V2ZW50X2NvbnRleHQgKmN0eCA9IGV2ZW50LT5jdHg7CglzdHJ1Y3QgcGVyZl9ldmVudCAqbGVhZGVyID0gZXZlbnQtPmdyb3VwX2xlYWRlcjsKCXN0cnVjdCBwZXJmX2NwdV9jb250ZXh0ICpjcHVjdHggPSBfX2dldF9jcHVfY29udGV4dChjdHgpOwoJaW50IGVycjsKCgkvKgoJICogSWYgdGhpcyBpcyBhIHRhc2sgY29udGV4dCwgd2UgbmVlZCB0byBjaGVjayB3aGV0aGVyIGl0IGlzCgkgKiB0aGUgY3VycmVudCB0YXNrIGNvbnRleHQgb2YgdGhpcyBjcHUuIElmIG5vdCBpdCBoYXMgYmVlbgoJICogc2NoZWR1bGVkIG91dCBiZWZvcmUgdGhlIHNtcCBjYWxsIGFycml2ZWQuCgkgKiBPciBwb3NzaWJseSB0aGlzIGlzIHRoZSByaWdodCBjb250ZXh0IGJ1dCBpdCBpc24ndAoJICogb24gdGhpcyBjcHUgYmVjYXVzZSBpdCBoYWQgbm8gZXZlbnRzLgoJICovCglpZiAoY3R4LT50YXNrICYmIGNwdWN0eC0+dGFza19jdHggIT0gY3R4KSB7CgkJaWYgKGNwdWN0eC0+dGFza19jdHggfHwgY3R4LT50YXNrICE9IGN1cnJlbnQpCgkJCXJldHVybjsKCQljcHVjdHgtPnRhc2tfY3R4ID0gY3R4OwoJfQoKCXJhd19zcGluX2xvY2soJmN0eC0+bG9jayk7CgljdHgtPmlzX2FjdGl2ZSA9IDE7Cgl1cGRhdGVfY29udGV4dF90aW1lKGN0eCk7CgoJYWRkX2V2ZW50X3RvX2N0eChldmVudCwgY3R4KTsKCglpZiAoZXZlbnQtPmNwdSAhPSAtMSAmJiBldmVudC0+Y3B1ICE9IHNtcF9wcm9jZXNzb3JfaWQoKSkKCQlnb3RvIHVubG9jazsKCgkvKgoJICogRG9uJ3QgcHV0IHRoZSBldmVudCBvbiBpZiBpdCBpcyBkaXNhYmxlZCBvciBpZgoJICogaXQgaXMgaW4gYSBncm91cCBhbmQgdGhlIGdyb3VwIGlzbid0IG9uLgoJICovCglpZiAoZXZlbnQtPnN0YXRlICE9IFBFUkZfRVZFTlRfU1RBVEVfSU5BQ1RJVkUgfHwKCSAgICAobGVhZGVyICE9IGV2ZW50ICYmIGxlYWRlci0+c3RhdGUgIT0gUEVSRl9FVkVOVF9TVEFURV9BQ1RJVkUpKQoJCWdvdG8gdW5sb2NrOwoKCS8qCgkgKiBBbiBleGNsdXNpdmUgZXZlbnQgY2FuJ3QgZ28gb24gaWYgdGhlcmUgYXJlIGFscmVhZHkgYWN0aXZlCgkgKiBoYXJkd2FyZSBldmVudHMsIGFuZCBubyBoYXJkd2FyZSBldmVudCBjYW4gZ28gb24gaWYgdGhlcmUKCSAqIGlzIGFscmVhZHkgYW4gZXhjbHVzaXZlIGV2ZW50IG9uLgoJICovCglpZiAoIWdyb3VwX2Nhbl9nb19vbihldmVudCwgY3B1Y3R4LCAxKSkKCQllcnIgPSAtRUVYSVNUOwoJZWxzZQoJCWVyciA9IGV2ZW50X3NjaGVkX2luKGV2ZW50LCBjcHVjdHgsIGN0eCk7CgoJaWYgKGVycikgewoJCS8qCgkJICogVGhpcyBldmVudCBjb3VsZG4ndCBnbyBvbi4gIElmIGl0IGlzIGluIGEgZ3JvdXAKCQkgKiB0aGVuIHdlIGhhdmUgdG8gcHVsbCB0aGUgd2hvbGUgZ3JvdXAgb2ZmLgoJCSAqIElmIHRoZSBldmVudCBncm91cCBpcyBwaW5uZWQgdGhlbiBwdXQgaXQgaW4gZXJyb3Igc3RhdGUuCgkJICovCgkJaWYgKGxlYWRlciAhPSBldmVudCkKCQkJZ3JvdXBfc2NoZWRfb3V0KGxlYWRlciwgY3B1Y3R4LCBjdHgpOwoJCWlmIChsZWFkZXItPmF0dHIucGlubmVkKSB7CgkJCXVwZGF0ZV9ncm91cF90aW1lcyhsZWFkZXIpOwoJCQlsZWFkZXItPnN0YXRlID0gUEVSRl9FVkVOVF9TVEFURV9FUlJPUjsKCQl9Cgl9Cgp1bmxvY2s6CglyYXdfc3Bpbl91bmxvY2soJmN0eC0+bG9jayk7Cn0KCi8qCiAqIEF0dGFjaCBhIHBlcmZvcm1hbmNlIGV2ZW50IHRvIGEgY29udGV4dAogKgogKiBGaXJzdCB3ZSBhZGQgdGhlIGV2ZW50IHRvIHRoZSBsaXN0IHdpdGggdGhlIGhhcmR3YXJlIGVuYWJsZSBiaXQKICogaW4gZXZlbnQtPmh3X2NvbmZpZyBjbGVhcmVkLgogKgogKiBJZiB0aGUgZXZlbnQgaXMgYXR0YWNoZWQgdG8gYSB0YXNrIHdoaWNoIGlzIG9uIGEgQ1BVIHdlIHVzZSBhIHNtcAogKiBjYWxsIHRvIGVuYWJsZSBpdCBpbiB0aGUgdGFzayBjb250ZXh0LiBUaGUgdGFzayBtaWdodCBoYXZlIGJlZW4KICogc2NoZWR1bGVkIGF3YXksIGJ1dCB3ZSBjaGVjayB0aGlzIGluIHRoZSBzbXAgY2FsbCBhZ2Fpbi4KICoKICogTXVzdCBiZSBjYWxsZWQgd2l0aCBjdHgtPm11dGV4IGhlbGQuCiAqLwpzdGF0aWMgdm9pZApwZXJmX2luc3RhbGxfaW5fY29udGV4dChzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0ICpjdHgsCgkJCXN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCwKCQkJaW50IGNwdSkKewoJc3RydWN0IHRhc2tfc3RydWN0ICp0YXNrID0gY3R4LT50YXNrOwoKCWV2ZW50LT5jdHggPSBjdHg7CgoJaWYgKCF0YXNrKSB7CgkJLyoKCQkgKiBQZXIgY3B1IGV2ZW50cyBhcmUgaW5zdGFsbGVkIHZpYSBhbiBzbXAgY2FsbCBhbmQKCQkgKiB0aGUgaW5zdGFsbCBpcyBhbHdheXMgc3VjY2Vzc2Z1bC4KCQkgKi8KCQlzbXBfY2FsbF9mdW5jdGlvbl9zaW5nbGUoY3B1LCBfX3BlcmZfaW5zdGFsbF9pbl9jb250ZXh0LAoJCQkJCSBldmVudCwgMSk7CgkJcmV0dXJuOwoJfQoKcmV0cnk6Cgl0YXNrX29uY3B1X2Z1bmN0aW9uX2NhbGwodGFzaywgX19wZXJmX2luc3RhbGxfaW5fY29udGV4dCwKCQkJCSBldmVudCk7CgoJcmF3X3NwaW5fbG9ja19pcnEoJmN0eC0+bG9jayk7CgkvKgoJICogd2UgbmVlZCB0byByZXRyeSB0aGUgc21wIGNhbGwuCgkgKi8KCWlmIChjdHgtPmlzX2FjdGl2ZSAmJiBsaXN0X2VtcHR5KCZldmVudC0+Z3JvdXBfZW50cnkpKSB7CgkJcmF3X3NwaW5fdW5sb2NrX2lycSgmY3R4LT5sb2NrKTsKCQlnb3RvIHJldHJ5OwoJfQoKCS8qCgkgKiBUaGUgbG9jayBwcmV2ZW50cyB0aGF0IHRoaXMgY29udGV4dCBpcyBzY2hlZHVsZWQgaW4gc28gd2UKCSAqIGNhbiBhZGQgdGhlIGV2ZW50IHNhZmVseSwgaWYgaXQgdGhlIGNhbGwgYWJvdmUgZGlkIG5vdAoJICogc3VjY2VlZC4KCSAqLwoJaWYgKGxpc3RfZW1wdHkoJmV2ZW50LT5ncm91cF9lbnRyeSkpCgkJYWRkX2V2ZW50X3RvX2N0eChldmVudCwgY3R4KTsKCXJhd19zcGluX3VubG9ja19pcnEoJmN0eC0+bG9jayk7Cn0KCi8qCiAqIFB1dCBhIGV2ZW50IGludG8gaW5hY3RpdmUgc3RhdGUgYW5kIHVwZGF0ZSB0aW1lIGZpZWxkcy4KICogRW5hYmxpbmcgdGhlIGxlYWRlciBvZiBhIGdyb3VwIGVmZmVjdGl2ZWx5IGVuYWJsZXMgYWxsCiAqIHRoZSBncm91cCBtZW1iZXJzIHRoYXQgYXJlbid0IGV4cGxpY2l0bHkgZGlzYWJsZWQsIHNvIHdlCiAqIGhhdmUgdG8gdXBkYXRlIHRoZWlyIC0+dHN0YW1wX2VuYWJsZWQgYWxzby4KICogTm90ZTogdGhpcyB3b3JrcyBmb3IgZ3JvdXAgbWVtYmVycyBhcyB3ZWxsIGFzIGdyb3VwIGxlYWRlcnMKICogc2luY2UgdGhlIG5vbi1sZWFkZXIgbWVtYmVycycgc2libGluZ19saXN0cyB3aWxsIGJlIGVtcHR5LgogKi8Kc3RhdGljIHZvaWQgX19wZXJmX2V2ZW50X21hcmtfZW5hYmxlZChzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQsCgkJCQkJc3RydWN0IHBlcmZfZXZlbnRfY29udGV4dCAqY3R4KQp7CglzdHJ1Y3QgcGVyZl9ldmVudCAqc3ViOwoKCWV2ZW50LT5zdGF0ZSA9IFBFUkZfRVZFTlRfU1RBVEVfSU5BQ1RJVkU7CglldmVudC0+dHN0YW1wX2VuYWJsZWQgPSBjdHgtPnRpbWUgLSBldmVudC0+dG90YWxfdGltZV9lbmFibGVkOwoJbGlzdF9mb3JfZWFjaF9lbnRyeShzdWIsICZldmVudC0+c2libGluZ19saXN0LCBncm91cF9lbnRyeSkgewoJCWlmIChzdWItPnN0YXRlID49IFBFUkZfRVZFTlRfU1RBVEVfSU5BQ1RJVkUpIHsKCQkJc3ViLT50c3RhbXBfZW5hYmxlZCA9CgkJCQljdHgtPnRpbWUgLSBzdWItPnRvdGFsX3RpbWVfZW5hYmxlZDsKCQl9Cgl9Cn0KCi8qCiAqIENyb3NzIENQVSBjYWxsIHRvIGVuYWJsZSBhIHBlcmZvcm1hbmNlIGV2ZW50CiAqLwpzdGF0aWMgdm9pZCBfX3BlcmZfZXZlbnRfZW5hYmxlKHZvaWQgKmluZm8pCnsKCXN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCA9IGluZm87CglzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0ICpjdHggPSBldmVudC0+Y3R4OwoJc3RydWN0IHBlcmZfZXZlbnQgKmxlYWRlciA9IGV2ZW50LT5ncm91cF9sZWFkZXI7CglzdHJ1Y3QgcGVyZl9jcHVfY29udGV4dCAqY3B1Y3R4ID0gX19nZXRfY3B1X2NvbnRleHQoY3R4KTsKCWludCBlcnI7CgoJLyoKCSAqIElmIHRoaXMgaXMgYSBwZXItdGFzayBldmVudCwgbmVlZCB0byBjaGVjayB3aGV0aGVyIHRoaXMKCSAqIGV2ZW50J3MgdGFzayBpcyB0aGUgY3VycmVudCB0YXNrIG9uIHRoaXMgY3B1LgoJICovCglpZiAoY3R4LT50YXNrICYmIGNwdWN0eC0+dGFza19jdHggIT0gY3R4KSB7CgkJaWYgKGNwdWN0eC0+dGFza19jdHggfHwgY3R4LT50YXNrICE9IGN1cnJlbnQpCgkJCXJldHVybjsKCQljcHVjdHgtPnRhc2tfY3R4ID0gY3R4OwoJfQoKCXJhd19zcGluX2xvY2soJmN0eC0+bG9jayk7CgljdHgtPmlzX2FjdGl2ZSA9IDE7Cgl1cGRhdGVfY29udGV4dF90aW1lKGN0eCk7CgoJaWYgKGV2ZW50LT5zdGF0ZSA+PSBQRVJGX0VWRU5UX1NUQVRFX0lOQUNUSVZFKQoJCWdvdG8gdW5sb2NrOwoJX19wZXJmX2V2ZW50X21hcmtfZW5hYmxlZChldmVudCwgY3R4KTsKCglpZiAoZXZlbnQtPmNwdSAhPSAtMSAmJiBldmVudC0+Y3B1ICE9IHNtcF9wcm9jZXNzb3JfaWQoKSkKCQlnb3RvIHVubG9jazsKCgkvKgoJICogSWYgdGhlIGV2ZW50IGlzIGluIGEgZ3JvdXAgYW5kIGlzbid0IHRoZSBncm91cCBsZWFkZXIsCgkgKiB0aGVuIGRvbid0IHB1dCBpdCBvbiB1bmxlc3MgdGhlIGdyb3VwIGlzIG9uLgoJICovCglpZiAobGVhZGVyICE9IGV2ZW50ICYmIGxlYWRlci0+c3RhdGUgIT0gUEVSRl9FVkVOVF9TVEFURV9BQ1RJVkUpCgkJZ290byB1bmxvY2s7CgoJaWYgKCFncm91cF9jYW5fZ29fb24oZXZlbnQsIGNwdWN0eCwgMSkpIHsKCQllcnIgPSAtRUVYSVNUOwoJfSBlbHNlIHsKCQlpZiAoZXZlbnQgPT0gbGVhZGVyKQoJCQllcnIgPSBncm91cF9zY2hlZF9pbihldmVudCwgY3B1Y3R4LCBjdHgpOwoJCWVsc2UKCQkJZXJyID0gZXZlbnRfc2NoZWRfaW4oZXZlbnQsIGNwdWN0eCwgY3R4KTsKCX0KCglpZiAoZXJyKSB7CgkJLyoKCQkgKiBJZiB0aGlzIGV2ZW50IGNhbid0IGdvIG9uIGFuZCBpdCdzIHBhcnQgb2YgYQoJCSAqIGdyb3VwLCB0aGVuIHRoZSB3aG9sZSBncm91cCBoYXMgdG8gY29tZSBvZmYuCgkJICovCgkJaWYgKGxlYWRlciAhPSBldmVudCkKCQkJZ3JvdXBfc2NoZWRfb3V0KGxlYWRlciwgY3B1Y3R4LCBjdHgpOwoJCWlmIChsZWFkZXItPmF0dHIucGlubmVkKSB7CgkJCXVwZGF0ZV9ncm91cF90aW1lcyhsZWFkZXIpOwoJCQlsZWFkZXItPnN0YXRlID0gUEVSRl9FVkVOVF9TVEFURV9FUlJPUjsKCQl9Cgl9Cgp1bmxvY2s6CglyYXdfc3Bpbl91bmxvY2soJmN0eC0+bG9jayk7Cn0KCi8qCiAqIEVuYWJsZSBhIGV2ZW50LgogKgogKiBJZiBldmVudC0+Y3R4IGlzIGEgY2xvbmVkIGNvbnRleHQsIGNhbGxlcnMgbXVzdCBtYWtlIHN1cmUgdGhhdAogKiBldmVyeSB0YXNrIHN0cnVjdCB0aGF0IGV2ZW50LT5jdHgtPnRhc2sgY291bGQgcG9zc2libHkgcG9pbnQgdG8KICogcmVtYWlucyB2YWxpZC4gIFRoaXMgY29uZGl0aW9uIGlzIHNhdGlzZmllZCB3aGVuIGNhbGxlZCB0aHJvdWdoCiAqIHBlcmZfZXZlbnRfZm9yX2VhY2hfY2hpbGQgb3IgcGVyZl9ldmVudF9mb3JfZWFjaCBhcyBkZXNjcmliZWQKICogZm9yIHBlcmZfZXZlbnRfZGlzYWJsZS4KICovCnZvaWQgcGVyZl9ldmVudF9lbmFibGUoc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50KQp7CglzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0ICpjdHggPSBldmVudC0+Y3R4OwoJc3RydWN0IHRhc2tfc3RydWN0ICp0YXNrID0gY3R4LT50YXNrOwoKCWlmICghdGFzaykgewoJCS8qCgkJICogRW5hYmxlIHRoZSBldmVudCBvbiB0aGUgY3B1IHRoYXQgaXQncyBvbgoJCSAqLwoJCXNtcF9jYWxsX2Z1bmN0aW9uX3NpbmdsZShldmVudC0+Y3B1LCBfX3BlcmZfZXZlbnRfZW5hYmxlLAoJCQkJCSBldmVudCwgMSk7CgkJcmV0dXJuOwoJfQoKCXJhd19zcGluX2xvY2tfaXJxKCZjdHgtPmxvY2spOwoJaWYgKGV2ZW50LT5zdGF0ZSA+PSBQRVJGX0VWRU5UX1NUQVRFX0lOQUNUSVZFKQoJCWdvdG8gb3V0OwoKCS8qCgkgKiBJZiB0aGUgZXZlbnQgaXMgaW4gZXJyb3Igc3RhdGUsIGNsZWFyIHRoYXQgZmlyc3QuCgkgKiBUaGF0IHdheSwgaWYgd2Ugc2VlIHRoZSBldmVudCBpbiBlcnJvciBzdGF0ZSBiZWxvdywgd2UKCSAqIGtub3cgdGhhdCBpdCBoYXMgZ29uZSBiYWNrIGludG8gZXJyb3Igc3RhdGUsIGFzIGRpc3RpbmN0CgkgKiBmcm9tIHRoZSB0YXNrIGhhdmluZyBiZWVuIHNjaGVkdWxlZCBhd2F5IGJlZm9yZSB0aGUKCSAqIGNyb3NzLWNhbGwgYXJyaXZlZC4KCSAqLwoJaWYgKGV2ZW50LT5zdGF0ZSA9PSBQRVJGX0VWRU5UX1NUQVRFX0VSUk9SKQoJCWV2ZW50LT5zdGF0ZSA9IFBFUkZfRVZFTlRfU1RBVEVfT0ZGOwoKcmV0cnk6CglyYXdfc3Bpbl91bmxvY2tfaXJxKCZjdHgtPmxvY2spOwoJdGFza19vbmNwdV9mdW5jdGlvbl9jYWxsKHRhc2ssIF9fcGVyZl9ldmVudF9lbmFibGUsIGV2ZW50KTsKCglyYXdfc3Bpbl9sb2NrX2lycSgmY3R4LT5sb2NrKTsKCgkvKgoJICogSWYgdGhlIGNvbnRleHQgaXMgYWN0aXZlIGFuZCB0aGUgZXZlbnQgaXMgc3RpbGwgb2ZmLAoJICogd2UgbmVlZCB0byByZXRyeSB0aGUgY3Jvc3MtY2FsbC4KCSAqLwoJaWYgKGN0eC0+aXNfYWN0aXZlICYmIGV2ZW50LT5zdGF0ZSA9PSBQRVJGX0VWRU5UX1NUQVRFX09GRikKCQlnb3RvIHJldHJ5OwoKCS8qCgkgKiBTaW5jZSB3ZSBoYXZlIHRoZSBsb2NrIHRoaXMgY29udGV4dCBjYW4ndCBiZSBzY2hlZHVsZWQKCSAqIGluLCBzbyB3ZSBjYW4gY2hhbmdlIHRoZSBzdGF0ZSBzYWZlbHkuCgkgKi8KCWlmIChldmVudC0+c3RhdGUgPT0gUEVSRl9FVkVOVF9TVEFURV9PRkYpCgkJX19wZXJmX2V2ZW50X21hcmtfZW5hYmxlZChldmVudCwgY3R4KTsKCm91dDoKCXJhd19zcGluX3VubG9ja19pcnEoJmN0eC0+bG9jayk7Cn0KCnN0YXRpYyBpbnQgcGVyZl9ldmVudF9yZWZyZXNoKHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCwgaW50IHJlZnJlc2gpCnsKCS8qCgkgKiBub3Qgc3VwcG9ydGVkIG9uIGluaGVyaXRlZCBldmVudHMKCSAqLwoJaWYgKGV2ZW50LT5hdHRyLmluaGVyaXQgfHwgIWlzX3NhbXBsaW5nX2V2ZW50KGV2ZW50KSkKCQlyZXR1cm4gLUVJTlZBTDsKCglhdG9taWNfYWRkKHJlZnJlc2gsICZldmVudC0+ZXZlbnRfbGltaXQpOwoJcGVyZl9ldmVudF9lbmFibGUoZXZlbnQpOwoKCXJldHVybiAwOwp9CgplbnVtIGV2ZW50X3R5cGVfdCB7CglFVkVOVF9GTEVYSUJMRSA9IDB4MSwKCUVWRU5UX1BJTk5FRCA9IDB4MiwKCUVWRU5UX0FMTCA9IEVWRU5UX0ZMRVhJQkxFIHwgRVZFTlRfUElOTkVELAp9OwoKc3RhdGljIHZvaWQgY3R4X3NjaGVkX291dChzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0ICpjdHgsCgkJCSAgc3RydWN0IHBlcmZfY3B1X2NvbnRleHQgKmNwdWN0eCwKCQkJICBlbnVtIGV2ZW50X3R5cGVfdCBldmVudF90eXBlKQp7CglzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQ7CgoJcmF3X3NwaW5fbG9jaygmY3R4LT5sb2NrKTsKCXBlcmZfcG11X2Rpc2FibGUoY3R4LT5wbXUpOwoJY3R4LT5pc19hY3RpdmUgPSAwOwoJaWYgKGxpa2VseSghY3R4LT5ucl9ldmVudHMpKQoJCWdvdG8gb3V0OwoJdXBkYXRlX2NvbnRleHRfdGltZShjdHgpOwoKCWlmICghY3R4LT5ucl9hY3RpdmUpCgkJZ290byBvdXQ7CgoJaWYgKGV2ZW50X3R5cGUgJiBFVkVOVF9QSU5ORUQpIHsKCQlsaXN0X2Zvcl9lYWNoX2VudHJ5KGV2ZW50LCAmY3R4LT5waW5uZWRfZ3JvdXBzLCBncm91cF9lbnRyeSkKCQkJZ3JvdXBfc2NoZWRfb3V0KGV2ZW50LCBjcHVjdHgsIGN0eCk7Cgl9CgoJaWYgKGV2ZW50X3R5cGUgJiBFVkVOVF9GTEVYSUJMRSkgewoJCWxpc3RfZm9yX2VhY2hfZW50cnkoZXZlbnQsICZjdHgtPmZsZXhpYmxlX2dyb3VwcywgZ3JvdXBfZW50cnkpCgkJCWdyb3VwX3NjaGVkX291dChldmVudCwgY3B1Y3R4LCBjdHgpOwoJfQpvdXQ6CglwZXJmX3BtdV9lbmFibGUoY3R4LT5wbXUpOwoJcmF3X3NwaW5fdW5sb2NrKCZjdHgtPmxvY2spOwp9CgovKgogKiBUZXN0IHdoZXRoZXIgdHdvIGNvbnRleHRzIGFyZSBlcXVpdmFsZW50LCBpLmUuIHdoZXRoZXIgdGhleQogKiBoYXZlIGJvdGggYmVlbiBjbG9uZWQgZnJvbSB0aGUgc2FtZSB2ZXJzaW9uIG9mIHRoZSBzYW1lIGNvbnRleHQKICogYW5kIHRoZXkgYm90aCBoYXZlIHRoZSBzYW1lIG51bWJlciBvZiBlbmFibGVkIGV2ZW50cy4KICogSWYgdGhlIG51bWJlciBvZiBlbmFibGVkIGV2ZW50cyBpcyB0aGUgc2FtZSwgdGhlbiB0aGUgc2V0CiAqIG9mIGVuYWJsZWQgZXZlbnRzIHNob3VsZCBiZSB0aGUgc2FtZSwgYmVjYXVzZSB0aGVzZSBhcmUgYm90aAogKiBpbmhlcml0ZWQgY29udGV4dHMsIHRoZXJlZm9yZSB3ZSBjYW4ndCBhY2Nlc3MgaW5kaXZpZHVhbCBldmVudHMKICogaW4gdGhlbSBkaXJlY3RseSB3aXRoIGFuIGZkOyB3ZSBjYW4gb25seSBlbmFibGUvZGlzYWJsZSBhbGwKICogZXZlbnRzIHZpYSBwcmN0bCwgb3IgZW5hYmxlL2Rpc2FibGUgYWxsIGV2ZW50cyBpbiBhIGZhbWlseQogKiB2aWEgaW9jdGwsIHdoaWNoIHdpbGwgaGF2ZSB0aGUgc2FtZSBlZmZlY3Qgb24gYm90aCBjb250ZXh0cy4KICovCnN0YXRpYyBpbnQgY29udGV4dF9lcXVpdihzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0ICpjdHgxLAoJCQkgc3RydWN0IHBlcmZfZXZlbnRfY29udGV4dCAqY3R4MikKewoJcmV0dXJuIGN0eDEtPnBhcmVudF9jdHggJiYgY3R4MS0+cGFyZW50X2N0eCA9PSBjdHgyLT5wYXJlbnRfY3R4CgkJJiYgY3R4MS0+cGFyZW50X2dlbiA9PSBjdHgyLT5wYXJlbnRfZ2VuCgkJJiYgIWN0eDEtPnBpbl9jb3VudCAmJiAhY3R4Mi0+cGluX2NvdW50Owp9CgpzdGF0aWMgdm9pZCBfX3BlcmZfZXZlbnRfc3luY19zdGF0KHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCwKCQkJCSAgICAgc3RydWN0IHBlcmZfZXZlbnQgKm5leHRfZXZlbnQpCnsKCXU2NCB2YWx1ZTsKCglpZiAoIWV2ZW50LT5hdHRyLmluaGVyaXRfc3RhdCkKCQlyZXR1cm47CgoJLyoKCSAqIFVwZGF0ZSB0aGUgZXZlbnQgdmFsdWUsIHdlIGNhbm5vdCB1c2UgcGVyZl9ldmVudF9yZWFkKCkKCSAqIGJlY2F1c2Ugd2UncmUgaW4gdGhlIG1pZGRsZSBvZiBhIGNvbnRleHQgc3dpdGNoIGFuZCBoYXZlIElSUXMKCSAqIGRpc2FibGVkLCB3aGljaCB1cHNldHMgc21wX2NhbGxfZnVuY3Rpb25fc2luZ2xlKCksIGhvd2V2ZXIKCSAqIHdlIGtub3cgdGhlIGV2ZW50IG11c3QgYmUgb24gdGhlIGN1cnJlbnQgQ1BVLCB0aGVyZWZvcmUgd2UKCSAqIGRvbid0IG5lZWQgdG8gdXNlIGl0LgoJICovCglzd2l0Y2ggKGV2ZW50LT5zdGF0ZSkgewoJY2FzZSBQRVJGX0VWRU5UX1NUQVRFX0FDVElWRToKCQlldmVudC0+cG11LT5yZWFkKGV2ZW50KTsKCQkvKiBmYWxsLXRocm91Z2ggKi8KCgljYXNlIFBFUkZfRVZFTlRfU1RBVEVfSU5BQ1RJVkU6CgkJdXBkYXRlX2V2ZW50X3RpbWVzKGV2ZW50KTsKCQlicmVhazsKCglkZWZhdWx0OgoJCWJyZWFrOwoJfQoKCS8qCgkgKiBJbiBvcmRlciB0byBrZWVwIHBlci10YXNrIHN0YXRzIHJlbGlhYmxlIHdlIG5lZWQgdG8gZmxpcCB0aGUgZXZlbnQKCSAqIHZhbHVlcyB3aGVuIHdlIGZsaXAgdGhlIGNvbnRleHRzLgoJICovCgl2YWx1ZSA9IGxvY2FsNjRfcmVhZCgmbmV4dF9ldmVudC0+Y291bnQpOwoJdmFsdWUgPSBsb2NhbDY0X3hjaGcoJmV2ZW50LT5jb3VudCwgdmFsdWUpOwoJbG9jYWw2NF9zZXQoJm5leHRfZXZlbnQtPmNvdW50LCB2YWx1ZSk7CgoJc3dhcChldmVudC0+dG90YWxfdGltZV9lbmFibGVkLCBuZXh0X2V2ZW50LT50b3RhbF90aW1lX2VuYWJsZWQpOwoJc3dhcChldmVudC0+dG90YWxfdGltZV9ydW5uaW5nLCBuZXh0X2V2ZW50LT50b3RhbF90aW1lX3J1bm5pbmcpOwoKCS8qCgkgKiBTaW5jZSB3ZSBzd2l6emxlZCB0aGUgdmFsdWVzLCB1cGRhdGUgdGhlIHVzZXIgdmlzaWJsZSBkYXRhIHRvby4KCSAqLwoJcGVyZl9ldmVudF91cGRhdGVfdXNlcnBhZ2UoZXZlbnQpOwoJcGVyZl9ldmVudF91cGRhdGVfdXNlcnBhZ2UobmV4dF9ldmVudCk7Cn0KCiNkZWZpbmUgbGlzdF9uZXh0X2VudHJ5KHBvcywgbWVtYmVyKSBcCglsaXN0X2VudHJ5KHBvcy0+bWVtYmVyLm5leHQsIHR5cGVvZigqcG9zKSwgbWVtYmVyKQoKc3RhdGljIHZvaWQgcGVyZl9ldmVudF9zeW5jX3N0YXQoc3RydWN0IHBlcmZfZXZlbnRfY29udGV4dCAqY3R4LAoJCQkJICAgc3RydWN0IHBlcmZfZXZlbnRfY29udGV4dCAqbmV4dF9jdHgpCnsKCXN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCwgKm5leHRfZXZlbnQ7CgoJaWYgKCFjdHgtPm5yX3N0YXQpCgkJcmV0dXJuOwoKCXVwZGF0ZV9jb250ZXh0X3RpbWUoY3R4KTsKCglldmVudCA9IGxpc3RfZmlyc3RfZW50cnkoJmN0eC0+ZXZlbnRfbGlzdCwKCQkJCSAgIHN0cnVjdCBwZXJmX2V2ZW50LCBldmVudF9lbnRyeSk7CgoJbmV4dF9ldmVudCA9IGxpc3RfZmlyc3RfZW50cnkoJm5leHRfY3R4LT5ldmVudF9saXN0LAoJCQkJCXN0cnVjdCBwZXJmX2V2ZW50LCBldmVudF9lbnRyeSk7CgoJd2hpbGUgKCZldmVudC0+ZXZlbnRfZW50cnkgIT0gJmN0eC0+ZXZlbnRfbGlzdCAmJgoJICAgICAgICZuZXh0X2V2ZW50LT5ldmVudF9lbnRyeSAhPSAmbmV4dF9jdHgtPmV2ZW50X2xpc3QpIHsKCgkJX19wZXJmX2V2ZW50X3N5bmNfc3RhdChldmVudCwgbmV4dF9ldmVudCk7CgoJCWV2ZW50ID0gbGlzdF9uZXh0X2VudHJ5KGV2ZW50LCBldmVudF9lbnRyeSk7CgkJbmV4dF9ldmVudCA9IGxpc3RfbmV4dF9lbnRyeShuZXh0X2V2ZW50LCBldmVudF9lbnRyeSk7Cgl9Cn0KCnZvaWQgcGVyZl9ldmVudF9jb250ZXh0X3NjaGVkX291dChzdHJ1Y3QgdGFza19zdHJ1Y3QgKnRhc2ssIGludCBjdHhuLAoJCQkJICBzdHJ1Y3QgdGFza19zdHJ1Y3QgKm5leHQpCnsKCXN0cnVjdCBwZXJmX2V2ZW50X2NvbnRleHQgKmN0eCA9IHRhc2stPnBlcmZfZXZlbnRfY3R4cFtjdHhuXTsKCXN0cnVjdCBwZXJmX2V2ZW50X2NvbnRleHQgKm5leHRfY3R4OwoJc3RydWN0IHBlcmZfZXZlbnRfY29udGV4dCAqcGFyZW50OwoJc3RydWN0IHBlcmZfY3B1X2NvbnRleHQgKmNwdWN0eDsKCWludCBkb19zd2l0Y2ggPSAxOwoKCWlmIChsaWtlbHkoIWN0eCkpCgkJcmV0dXJuOwoKCWNwdWN0eCA9IF9fZ2V0X2NwdV9jb250ZXh0KGN0eCk7CglpZiAoIWNwdWN0eC0+dGFza19jdHgpCgkJcmV0dXJuOwoKCXJjdV9yZWFkX2xvY2soKTsKCXBhcmVudCA9IHJjdV9kZXJlZmVyZW5jZShjdHgtPnBhcmVudF9jdHgpOwoJbmV4dF9jdHggPSBuZXh0LT5wZXJmX2V2ZW50X2N0eHBbY3R4bl07CglpZiAocGFyZW50ICYmIG5leHRfY3R4ICYmCgkgICAgcmN1X2RlcmVmZXJlbmNlKG5leHRfY3R4LT5wYXJlbnRfY3R4KSA9PSBwYXJlbnQpIHsKCQkvKgoJCSAqIExvb2tzIGxpa2UgdGhlIHR3byBjb250ZXh0cyBhcmUgY2xvbmVzLCBzbyB3ZSBtaWdodCBiZQoJCSAqIGFibGUgdG8gb3B0aW1pemUgdGhlIGNvbnRleHQgc3dpdGNoLiAgV2UgbG9jayBib3RoCgkJICogY29udGV4dHMgYW5kIGNoZWNrIHRoYXQgdGhleSBhcmUgY2xvbmVzIHVuZGVyIHRoZQoJCSAqIGxvY2sgKGluY2x1ZGluZyByZS1jaGVja2luZyB0aGF0IG5laXRoZXIgaGFzIGJlZW4KCQkgKiB1bmNsb25lZCBpbiB0aGUgbWVhbnRpbWUpLiAgSXQgZG9lc24ndCBtYXR0ZXIgd2hpY2gKCQkgKiBvcmRlciB3ZSB0YWtlIHRoZSBsb2NrcyBiZWNhdXNlIG5vIG90aGVyIGNwdSBjb3VsZAoJCSAqIGJlIHRyeWluZyB0byBsb2NrIGJvdGggb2YgdGhlc2UgdGFza3MuCgkJICovCgkJcmF3X3NwaW5fbG9jaygmY3R4LT5sb2NrKTsKCQlyYXdfc3Bpbl9sb2NrX25lc3RlZCgmbmV4dF9jdHgtPmxvY2ssIFNJTkdMRV9ERVBUSF9ORVNUSU5HKTsKCQlpZiAoY29udGV4dF9lcXVpdihjdHgsIG5leHRfY3R4KSkgewoJCQkvKgoJCQkgKiBYWFggZG8gd2UgbmVlZCBhIG1lbW9yeSBiYXJyaWVyIG9mIHNvcnRzCgkJCSAqIHdydCB0byByY3VfZGVyZWZlcmVuY2UoKSBvZiBwZXJmX2V2ZW50X2N0eHAKCQkJICovCgkJCXRhc2stPnBlcmZfZXZlbnRfY3R4cFtjdHhuXSA9IG5leHRfY3R4OwoJCQluZXh0LT5wZXJmX2V2ZW50X2N0eHBbY3R4bl0gPSBjdHg7CgkJCWN0eC0+dGFzayA9IG5leHQ7CgkJCW5leHRfY3R4LT50YXNrID0gdGFzazsKCQkJZG9fc3dpdGNoID0gMDsKCgkJCXBlcmZfZXZlbnRfc3luY19zdGF0KGN0eCwgbmV4dF9jdHgpOwoJCX0KCQlyYXdfc3Bpbl91bmxvY2soJm5leHRfY3R4LT5sb2NrKTsKCQlyYXdfc3Bpbl91bmxvY2soJmN0eC0+bG9jayk7Cgl9CglyY3VfcmVhZF91bmxvY2soKTsKCglpZiAoZG9fc3dpdGNoKSB7CgkJY3R4X3NjaGVkX291dChjdHgsIGNwdWN0eCwgRVZFTlRfQUxMKTsKCQljcHVjdHgtPnRhc2tfY3R4ID0gTlVMTDsKCX0KfQoKI2RlZmluZSBmb3JfZWFjaF90YXNrX2NvbnRleHRfbnIoY3R4bikJCQkJCVwKCWZvciAoKGN0eG4pID0gMDsgKGN0eG4pIDwgcGVyZl9ucl90YXNrX2NvbnRleHRzOyAoY3R4bikrKykKCi8qCiAqIENhbGxlZCBmcm9tIHNjaGVkdWxlciB0byByZW1vdmUgdGhlIGV2ZW50cyBvZiB0aGUgY3VycmVudCB0YXNrLAogKiB3aXRoIGludGVycnVwdHMgZGlzYWJsZWQuCiAqCiAqIFdlIHN0b3AgZWFjaCBldmVudCBhbmQgdXBkYXRlIHRoZSBldmVudCB2YWx1ZSBpbiBldmVudC0+Y291bnQuCiAqCiAqIFRoaXMgZG9lcyBub3QgcHJvdGVjdCB1cyBhZ2FpbnN0IE5NSSwgYnV0IGRpc2FibGUoKQogKiBzZXRzIHRoZSBkaXNhYmxlZCBiaXQgaW4gdGhlIGNvbnRyb2wgZmllbGQgb2YgZXZlbnQgX2JlZm9yZV8KICogYWNjZXNzaW5nIHRoZSBldmVudCBjb250cm9sIHJlZ2lzdGVyLiBJZiBhIE5NSSBoaXRzLCB0aGVuIGl0IHdpbGwKICogbm90IHJlc3RhcnQgdGhlIGV2ZW50LgogKi8Kdm9pZCBfX3BlcmZfZXZlbnRfdGFza19zY2hlZF9vdXQoc3RydWN0IHRhc2tfc3RydWN0ICp0YXNrLAoJCQkJIHN0cnVjdCB0YXNrX3N0cnVjdCAqbmV4dCkKewoJaW50IGN0eG47CgoJZm9yX2VhY2hfdGFza19jb250ZXh0X25yKGN0eG4pCgkJcGVyZl9ldmVudF9jb250ZXh0X3NjaGVkX291dCh0YXNrLCBjdHhuLCBuZXh0KTsKfQoKc3RhdGljIHZvaWQgdGFza19jdHhfc2NoZWRfb3V0KHN0cnVjdCBwZXJmX2V2ZW50X2NvbnRleHQgKmN0eCwKCQkJICAgICAgIGVudW0gZXZlbnRfdHlwZV90IGV2ZW50X3R5cGUpCnsKCXN0cnVjdCBwZXJmX2NwdV9jb250ZXh0ICpjcHVjdHggPSBfX2dldF9jcHVfY29udGV4dChjdHgpOwoKCWlmICghY3B1Y3R4LT50YXNrX2N0eCkKCQlyZXR1cm47CgoJaWYgKFdBUk5fT05fT05DRShjdHggIT0gY3B1Y3R4LT50YXNrX2N0eCkpCgkJcmV0dXJuOwoKCWN0eF9zY2hlZF9vdXQoY3R4LCBjcHVjdHgsIGV2ZW50X3R5cGUpOwoJY3B1Y3R4LT50YXNrX2N0eCA9IE5VTEw7Cn0KCi8qCiAqIENhbGxlZCB3aXRoIElSUXMgZGlzYWJsZWQKICovCnN0YXRpYyB2b2lkIGNwdV9jdHhfc2NoZWRfb3V0KHN0cnVjdCBwZXJmX2NwdV9jb250ZXh0ICpjcHVjdHgsCgkJCSAgICAgIGVudW0gZXZlbnRfdHlwZV90IGV2ZW50X3R5cGUpCnsKCWN0eF9zY2hlZF9vdXQoJmNwdWN0eC0+Y3R4LCBjcHVjdHgsIGV2ZW50X3R5cGUpOwp9CgpzdGF0aWMgdm9pZApjdHhfcGlubmVkX3NjaGVkX2luKHN0cnVjdCBwZXJmX2V2ZW50X2NvbnRleHQgKmN0eCwKCQkgICAgc3RydWN0IHBlcmZfY3B1X2NvbnRleHQgKmNwdWN0eCkKewoJc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50OwoKCWxpc3RfZm9yX2VhY2hfZW50cnkoZXZlbnQsICZjdHgtPnBpbm5lZF9ncm91cHMsIGdyb3VwX2VudHJ5KSB7CgkJaWYgKGV2ZW50LT5zdGF0ZSA8PSBQRVJGX0VWRU5UX1NUQVRFX09GRikKCQkJY29udGludWU7CgkJaWYgKGV2ZW50LT5jcHUgIT0gLTEgJiYgZXZlbnQtPmNwdSAhPSBzbXBfcHJvY2Vzc29yX2lkKCkpCgkJCWNvbnRpbnVlOwoKCQlpZiAoZ3JvdXBfY2FuX2dvX29uKGV2ZW50LCBjcHVjdHgsIDEpKQoJCQlncm91cF9zY2hlZF9pbihldmVudCwgY3B1Y3R4LCBjdHgpOwoKCQkvKgoJCSAqIElmIHRoaXMgcGlubmVkIGdyb3VwIGhhc24ndCBiZWVuIHNjaGVkdWxlZCwKCQkgKiBwdXQgaXQgaW4gZXJyb3Igc3RhdGUuCgkJICovCgkJaWYgKGV2ZW50LT5zdGF0ZSA9PSBQRVJGX0VWRU5UX1NUQVRFX0lOQUNUSVZFKSB7CgkJCXVwZGF0ZV9ncm91cF90aW1lcyhldmVudCk7CgkJCWV2ZW50LT5zdGF0ZSA9IFBFUkZfRVZFTlRfU1RBVEVfRVJST1I7CgkJfQoJfQp9CgpzdGF0aWMgdm9pZApjdHhfZmxleGlibGVfc2NoZWRfaW4oc3RydWN0IHBlcmZfZXZlbnRfY29udGV4dCAqY3R4LAoJCSAgICAgIHN0cnVjdCBwZXJmX2NwdV9jb250ZXh0ICpjcHVjdHgpCnsKCXN0cnVjdCBwZXJmX2V2ZW50ICpldmVudDsKCWludCBjYW5fYWRkX2h3ID0gMTsKCglsaXN0X2Zvcl9lYWNoX2VudHJ5KGV2ZW50LCAmY3R4LT5mbGV4aWJsZV9ncm91cHMsIGdyb3VwX2VudHJ5KSB7CgkJLyogSWdub3JlIGV2ZW50cyBpbiBPRkYgb3IgRVJST1Igc3RhdGUgKi8KCQlpZiAoZXZlbnQtPnN0YXRlIDw9IFBFUkZfRVZFTlRfU1RBVEVfT0ZGKQoJCQljb250aW51ZTsKCQkvKgoJCSAqIExpc3RlbiB0byB0aGUgJ2NwdScgc2NoZWR1bGluZyBmaWx0ZXIgY29uc3RyYWludAoJCSAqIG9mIGV2ZW50czoKCQkgKi8KCQlpZiAoZXZlbnQtPmNwdSAhPSAtMSAmJiBldmVudC0+Y3B1ICE9IHNtcF9wcm9jZXNzb3JfaWQoKSkKCQkJY29udGludWU7CgoJCWlmIChncm91cF9jYW5fZ29fb24oZXZlbnQsIGNwdWN0eCwgY2FuX2FkZF9odykpIHsKCQkJaWYgKGdyb3VwX3NjaGVkX2luKGV2ZW50LCBjcHVjdHgsIGN0eCkpCgkJCQljYW5fYWRkX2h3ID0gMDsKCQl9Cgl9Cn0KCnN0YXRpYyB2b2lkCmN0eF9zY2hlZF9pbihzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0ICpjdHgsCgkgICAgIHN0cnVjdCBwZXJmX2NwdV9jb250ZXh0ICpjcHVjdHgsCgkgICAgIGVudW0gZXZlbnRfdHlwZV90IGV2ZW50X3R5cGUpCnsKCXJhd19zcGluX2xvY2soJmN0eC0+bG9jayk7CgljdHgtPmlzX2FjdGl2ZSA9IDE7CglpZiAobGlrZWx5KCFjdHgtPm5yX2V2ZW50cykpCgkJZ290byBvdXQ7CgoJY3R4LT50aW1lc3RhbXAgPSBwZXJmX2Nsb2NrKCk7CgoJLyoKCSAqIEZpcnN0IGdvIHRocm91Z2ggdGhlIGxpc3QgYW5kIHB1dCBvbiBhbnkgcGlubmVkIGdyb3VwcwoJICogaW4gb3JkZXIgdG8gZ2l2ZSB0aGVtIHRoZSBiZXN0IGNoYW5jZSBvZiBnb2luZyBvbi4KCSAqLwoJaWYgKGV2ZW50X3R5cGUgJiBFVkVOVF9QSU5ORUQpCgkJY3R4X3Bpbm5lZF9zY2hlZF9pbihjdHgsIGNwdWN0eCk7CgoJLyogVGhlbiB3YWxrIHRocm91Z2ggdGhlIGxvd2VyIHByaW8gZmxleGlibGUgZ3JvdXBzICovCglpZiAoZXZlbnRfdHlwZSAmIEVWRU5UX0ZMRVhJQkxFKQoJCWN0eF9mbGV4aWJsZV9zY2hlZF9pbihjdHgsIGNwdWN0eCk7CgpvdXQ6CglyYXdfc3Bpbl91bmxvY2soJmN0eC0+bG9jayk7Cn0KCnN0YXRpYyB2b2lkIGNwdV9jdHhfc2NoZWRfaW4oc3RydWN0IHBlcmZfY3B1X2NvbnRleHQgKmNwdWN0eCwKCQkJICAgICBlbnVtIGV2ZW50X3R5cGVfdCBldmVudF90eXBlKQp7CglzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0ICpjdHggPSAmY3B1Y3R4LT5jdHg7CgoJY3R4X3NjaGVkX2luKGN0eCwgY3B1Y3R4LCBldmVudF90eXBlKTsKfQoKc3RhdGljIHZvaWQgdGFza19jdHhfc2NoZWRfaW4oc3RydWN0IHBlcmZfZXZlbnRfY29udGV4dCAqY3R4LAoJCQkgICAgICBlbnVtIGV2ZW50X3R5cGVfdCBldmVudF90eXBlKQp7CglzdHJ1Y3QgcGVyZl9jcHVfY29udGV4dCAqY3B1Y3R4OwoKICAgICAgIAljcHVjdHggPSBfX2dldF9jcHVfY29udGV4dChjdHgpOwoJaWYgKGNwdWN0eC0+dGFza19jdHggPT0gY3R4KQoJCXJldHVybjsKCgljdHhfc2NoZWRfaW4oY3R4LCBjcHVjdHgsIGV2ZW50X3R5cGUpOwoJY3B1Y3R4LT50YXNrX2N0eCA9IGN0eDsKfQoKdm9pZCBwZXJmX2V2ZW50X2NvbnRleHRfc2NoZWRfaW4oc3RydWN0IHBlcmZfZXZlbnRfY29udGV4dCAqY3R4KQp7CglzdHJ1Y3QgcGVyZl9jcHVfY29udGV4dCAqY3B1Y3R4OwoKCWNwdWN0eCA9IF9fZ2V0X2NwdV9jb250ZXh0KGN0eCk7CglpZiAoY3B1Y3R4LT50YXNrX2N0eCA9PSBjdHgpCgkJcmV0dXJuOwoKCXBlcmZfcG11X2Rpc2FibGUoY3R4LT5wbXUpOwoJLyoKCSAqIFdlIHdhbnQgdG8ga2VlcCB0aGUgZm9sbG93aW5nIHByaW9yaXR5IG9yZGVyOgoJICogY3B1IHBpbm5lZCAodGhhdCBkb24ndCBuZWVkIHRvIG1vdmUpLCB0YXNrIHBpbm5lZCwKCSAqIGNwdSBmbGV4aWJsZSwgdGFzayBmbGV4aWJsZS4KCSAqLwoJY3B1X2N0eF9zY2hlZF9vdXQoY3B1Y3R4LCBFVkVOVF9GTEVYSUJMRSk7CgoJY3R4X3NjaGVkX2luKGN0eCwgY3B1Y3R4LCBFVkVOVF9QSU5ORUQpOwoJY3B1X2N0eF9zY2hlZF9pbihjcHVjdHgsIEVWRU5UX0ZMRVhJQkxFKTsKCWN0eF9zY2hlZF9pbihjdHgsIGNwdWN0eCwgRVZFTlRfRkxFWElCTEUpOwoKCWNwdWN0eC0+dGFza19jdHggPSBjdHg7CgoJLyoKCSAqIFNpbmNlIHRoZXNlIHJvdGF0aW9ucyBhcmUgcGVyLWNwdSwgd2UgbmVlZCB0byBlbnN1cmUgdGhlCgkgKiBjcHUtY29udGV4dCB3ZSBnb3Qgc2NoZWR1bGVkIG9uIGlzIGFjdHVhbGx5IHJvdGF0aW5nLgoJICovCglwZXJmX3BtdV9yb3RhdGVfc3RhcnQoY3R4LT5wbXUpOwoJcGVyZl9wbXVfZW5hYmxlKGN0eC0+cG11KTsKfQoKLyoKICogQ2FsbGVkIGZyb20gc2NoZWR1bGVyIHRvIGFkZCB0aGUgZXZlbnRzIG9mIHRoZSBjdXJyZW50IHRhc2sKICogd2l0aCBpbnRlcnJ1cHRzIGRpc2FibGVkLgogKgogKiBXZSByZXN0b3JlIHRoZSBldmVudCB2YWx1ZSBhbmQgdGhlbiBlbmFibGUgaXQuCiAqCiAqIFRoaXMgZG9lcyBub3QgcHJvdGVjdCB1cyBhZ2FpbnN0IE5NSSwgYnV0IGVuYWJsZSgpCiAqIHNldHMgdGhlIGVuYWJsZWQgYml0IGluIHRoZSBjb250cm9sIGZpZWxkIG9mIGV2ZW50IF9iZWZvcmVfCiAqIGFjY2Vzc2luZyB0aGUgZXZlbnQgY29udHJvbCByZWdpc3Rlci4gSWYgYSBOTUkgaGl0cywgdGhlbiBpdCB3aWxsCiAqIGtlZXAgdGhlIGV2ZW50IHJ1bm5pbmcuCiAqLwp2b2lkIF9fcGVyZl9ldmVudF90YXNrX3NjaGVkX2luKHN0cnVjdCB0YXNrX3N0cnVjdCAqdGFzaykKewoJc3RydWN0IHBlcmZfZXZlbnRfY29udGV4dCAqY3R4OwoJaW50IGN0eG47CgoJZm9yX2VhY2hfdGFza19jb250ZXh0X25yKGN0eG4pIHsKCQljdHggPSB0YXNrLT5wZXJmX2V2ZW50X2N0eHBbY3R4bl07CgkJaWYgKGxpa2VseSghY3R4KSkKCQkJY29udGludWU7CgoJCXBlcmZfZXZlbnRfY29udGV4dF9zY2hlZF9pbihjdHgpOwoJfQp9CgojZGVmaW5lIE1BWF9JTlRFUlJVUFRTICh+MFVMTCkKCnN0YXRpYyB2b2lkIHBlcmZfbG9nX3Rocm90dGxlKHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCwgaW50IGVuYWJsZSk7CgpzdGF0aWMgdTY0IHBlcmZfY2FsY3VsYXRlX3BlcmlvZChzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQsIHU2NCBuc2VjLCB1NjQgY291bnQpCnsKCXU2NCBmcmVxdWVuY3kgPSBldmVudC0+YXR0ci5zYW1wbGVfZnJlcTsKCXU2NCBzZWMgPSBOU0VDX1BFUl9TRUM7Cgl1NjQgZGl2aXNvciwgZGl2aWRlbmQ7CgoJaW50IGNvdW50X2ZscywgbnNlY19mbHMsIGZyZXF1ZW5jeV9mbHMsIHNlY19mbHM7CgoJY291bnRfZmxzID0gZmxzNjQoY291bnQpOwoJbnNlY19mbHMgPSBmbHM2NChuc2VjKTsKCWZyZXF1ZW5jeV9mbHMgPSBmbHM2NChmcmVxdWVuY3kpOwoJc2VjX2ZscyA9IDMwOwoKCS8qCgkgKiBXZSBnb3QgQGNvdW50IGluIEBuc2VjLCB3aXRoIGEgdGFyZ2V0IG9mIHNhbXBsZV9mcmVxIEhaCgkgKiB0aGUgdGFyZ2V0IHBlcmlvZCBiZWNvbWVzOgoJICoKCSAqICAgICAgICAgICAgIEBjb3VudCAqIDEwXjkKCSAqIHBlcmlvZCA9IC0tLS0tLS0tLS0tLS0tLS0tLS0KCSAqICAgICAgICAgIEBuc2VjICogc2FtcGxlX2ZyZXEKCSAqCgkgKi8KCgkvKgoJICogUmVkdWNlIGFjY3VyYWN5IGJ5IG9uZSBiaXQgc3VjaCB0aGF0IEBhIGFuZCBAYiBjb252ZXJnZQoJICogdG8gYSBzaW1pbGFyIG1hZ25pdHVkZS4KCSAqLwojZGVmaW5lIFJFRFVDRV9GTFMoYSwgYikgCQlcCmRvIHsJCQkJCVwKCWlmIChhIyNfZmxzID4gYiMjX2ZscykgewlcCgkJYSA+Pj0gMTsJCVwKCQlhIyNfZmxzLS07CQlcCgl9IGVsc2UgewkJCVwKCQliID4+PSAxOwkJXAoJCWIjI19mbHMtLTsJCVwKCX0JCQkJXAp9IHdoaWxlICgwKQoKCS8qCgkgKiBSZWR1Y2UgYWNjdXJhY3kgdW50aWwgZWl0aGVyIHRlcm0gZml0cyBpbiBhIHU2NCwgdGhlbiBwcm9jZWVkIHdpdGgKCSAqIHRoZSBvdGhlciwgc28gdGhhdCBmaW5hbGx5IHdlIGNhbiBkbyBhIHU2NC91NjQgZGl2aXNpb24uCgkgKi8KCXdoaWxlIChjb3VudF9mbHMgKyBzZWNfZmxzID4gNjQgJiYgbnNlY19mbHMgKyBmcmVxdWVuY3lfZmxzID4gNjQpIHsKCQlSRURVQ0VfRkxTKG5zZWMsIGZyZXF1ZW5jeSk7CgkJUkVEVUNFX0ZMUyhzZWMsIGNvdW50KTsKCX0KCglpZiAoY291bnRfZmxzICsgc2VjX2ZscyA+IDY0KSB7CgkJZGl2aXNvciA9IG5zZWMgKiBmcmVxdWVuY3k7CgoJCXdoaWxlIChjb3VudF9mbHMgKyBzZWNfZmxzID4gNjQpIHsKCQkJUkVEVUNFX0ZMUyhjb3VudCwgc2VjKTsKCQkJZGl2aXNvciA+Pj0gMTsKCQl9CgoJCWRpdmlkZW5kID0gY291bnQgKiBzZWM7Cgl9IGVsc2UgewoJCWRpdmlkZW5kID0gY291bnQgKiBzZWM7CgoJCXdoaWxlIChuc2VjX2ZscyArIGZyZXF1ZW5jeV9mbHMgPiA2NCkgewoJCQlSRURVQ0VfRkxTKG5zZWMsIGZyZXF1ZW5jeSk7CgkJCWRpdmlkZW5kID4+PSAxOwoJCX0KCgkJZGl2aXNvciA9IG5zZWMgKiBmcmVxdWVuY3k7Cgl9CgoJaWYgKCFkaXZpc29yKQoJCXJldHVybiBkaXZpZGVuZDsKCglyZXR1cm4gZGl2NjRfdTY0KGRpdmlkZW5kLCBkaXZpc29yKTsKfQoKc3RhdGljIHZvaWQgcGVyZl9hZGp1c3RfcGVyaW9kKHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCwgdTY0IG5zZWMsIHU2NCBjb3VudCkKewoJc3RydWN0IGh3X3BlcmZfZXZlbnQgKmh3YyA9ICZldmVudC0+aHc7CglzNjQgcGVyaW9kLCBzYW1wbGVfcGVyaW9kOwoJczY0IGRlbHRhOwoKCXBlcmlvZCA9IHBlcmZfY2FsY3VsYXRlX3BlcmlvZChldmVudCwgbnNlYywgY291bnQpOwoKCWRlbHRhID0gKHM2NCkocGVyaW9kIC0gaHdjLT5zYW1wbGVfcGVyaW9kKTsKCWRlbHRhID0gKGRlbHRhICsgNykgLyA4OyAvKiBsb3cgcGFzcyBmaWx0ZXIgKi8KCglzYW1wbGVfcGVyaW9kID0gaHdjLT5zYW1wbGVfcGVyaW9kICsgZGVsdGE7CgoJaWYgKCFzYW1wbGVfcGVyaW9kKQoJCXNhbXBsZV9wZXJpb2QgPSAxOwoKCWh3Yy0+c2FtcGxlX3BlcmlvZCA9IHNhbXBsZV9wZXJpb2Q7CgoJaWYgKGxvY2FsNjRfcmVhZCgmaHdjLT5wZXJpb2RfbGVmdCkgPiA4KnNhbXBsZV9wZXJpb2QpIHsKCQlldmVudC0+cG11LT5zdG9wKGV2ZW50LCBQRVJGX0VGX1VQREFURSk7CgkJbG9jYWw2NF9zZXQoJmh3Yy0+cGVyaW9kX2xlZnQsIDApOwoJCWV2ZW50LT5wbXUtPnN0YXJ0KGV2ZW50LCBQRVJGX0VGX1JFTE9BRCk7Cgl9Cn0KCnN0YXRpYyB2b2lkIHBlcmZfY3R4X2FkanVzdF9mcmVxKHN0cnVjdCBwZXJmX2V2ZW50X2NvbnRleHQgKmN0eCwgdTY0IHBlcmlvZCkKewoJc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50OwoJc3RydWN0IGh3X3BlcmZfZXZlbnQgKmh3YzsKCXU2NCBpbnRlcnJ1cHRzLCBub3c7CglzNjQgZGVsdGE7CgoJcmF3X3NwaW5fbG9jaygmY3R4LT5sb2NrKTsKCWxpc3RfZm9yX2VhY2hfZW50cnlfcmN1KGV2ZW50LCAmY3R4LT5ldmVudF9saXN0LCBldmVudF9lbnRyeSkgewoJCWlmIChldmVudC0+c3RhdGUgIT0gUEVSRl9FVkVOVF9TVEFURV9BQ1RJVkUpCgkJCWNvbnRpbnVlOwoKCQlpZiAoZXZlbnQtPmNwdSAhPSAtMSAmJiBldmVudC0+Y3B1ICE9IHNtcF9wcm9jZXNzb3JfaWQoKSkKCQkJY29udGludWU7CgoJCWh3YyA9ICZldmVudC0+aHc7CgoJCWludGVycnVwdHMgPSBod2MtPmludGVycnVwdHM7CgkJaHdjLT5pbnRlcnJ1cHRzID0gMDsKCgkJLyoKCQkgKiB1bnRocm90dGxlIGV2ZW50cyBvbiB0aGUgdGljawoJCSAqLwoJCWlmIChpbnRlcnJ1cHRzID09IE1BWF9JTlRFUlJVUFRTKSB7CgkJCXBlcmZfbG9nX3Rocm90dGxlKGV2ZW50LCAxKTsKCQkJZXZlbnQtPnBtdS0+c3RhcnQoZXZlbnQsIDApOwoJCX0KCgkJaWYgKCFldmVudC0+YXR0ci5mcmVxIHx8ICFldmVudC0+YXR0ci5zYW1wbGVfZnJlcSkKCQkJY29udGludWU7CgoJCWV2ZW50LT5wbXUtPnJlYWQoZXZlbnQpOwoJCW5vdyA9IGxvY2FsNjRfcmVhZCgmZXZlbnQtPmNvdW50KTsKCQlkZWx0YSA9IG5vdyAtIGh3Yy0+ZnJlcV9jb3VudF9zdGFtcDsKCQlod2MtPmZyZXFfY291bnRfc3RhbXAgPSBub3c7CgoJCWlmIChkZWx0YSA+IDApCgkJCXBlcmZfYWRqdXN0X3BlcmlvZChldmVudCwgcGVyaW9kLCBkZWx0YSk7Cgl9CglyYXdfc3Bpbl91bmxvY2soJmN0eC0+bG9jayk7Cn0KCi8qCiAqIFJvdW5kLXJvYmluIGEgY29udGV4dCdzIGV2ZW50czoKICovCnN0YXRpYyB2b2lkIHJvdGF0ZV9jdHgoc3RydWN0IHBlcmZfZXZlbnRfY29udGV4dCAqY3R4KQp7CglyYXdfc3Bpbl9sb2NrKCZjdHgtPmxvY2spOwoKCS8qCgkgKiBSb3RhdGUgdGhlIGZpcnN0IGVudHJ5IGxhc3Qgb2Ygbm9uLXBpbm5lZCBncm91cHMuIFJvdGF0aW9uIG1pZ2h0IGJlCgkgKiBkaXNhYmxlZCBieSB0aGUgaW5oZXJpdGFuY2UgY29kZS4KCSAqLwoJaWYgKCFjdHgtPnJvdGF0ZV9kaXNhYmxlKQoJCWxpc3Rfcm90YXRlX2xlZnQoJmN0eC0+ZmxleGlibGVfZ3JvdXBzKTsKCglyYXdfc3Bpbl91bmxvY2soJmN0eC0+bG9jayk7Cn0KCi8qCiAqIHBlcmZfcG11X3JvdGF0ZV9zdGFydCgpIGFuZCBwZXJmX3JvdGF0ZV9jb250ZXh0KCkgYXJlIGZ1bGx5IHNlcmlhbGl6ZWQKICogYmVjYXVzZSB0aGV5J3JlIHN0cmljdGx5IGNwdSBhZmZpbmUgYW5kIHJvdGF0ZV9zdGFydCBpcyBjYWxsZWQgd2l0aCBJUlFzCiAqIGRpc2FibGVkLCB3aGlsZSByb3RhdGVfY29udGV4dCBpcyBjYWxsZWQgZnJvbSBJUlEgY29udGV4dC4KICovCnN0YXRpYyB2b2lkIHBlcmZfcm90YXRlX2NvbnRleHQoc3RydWN0IHBlcmZfY3B1X2NvbnRleHQgKmNwdWN0eCkKewoJdTY0IGludGVydmFsID0gKHU2NCljcHVjdHgtPmppZmZpZXNfaW50ZXJ2YWwgKiBUSUNLX05TRUM7CglzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0ICpjdHggPSBOVUxMOwoJaW50IHJvdGF0ZSA9IDAsIHJlbW92ZSA9IDE7CgoJaWYgKGNwdWN0eC0+Y3R4Lm5yX2V2ZW50cykgewoJCXJlbW92ZSA9IDA7CgkJaWYgKGNwdWN0eC0+Y3R4Lm5yX2V2ZW50cyAhPSBjcHVjdHgtPmN0eC5ucl9hY3RpdmUpCgkJCXJvdGF0ZSA9IDE7Cgl9CgoJY3R4ID0gY3B1Y3R4LT50YXNrX2N0eDsKCWlmIChjdHggJiYgY3R4LT5ucl9ldmVudHMpIHsKCQlyZW1vdmUgPSAwOwoJCWlmIChjdHgtPm5yX2V2ZW50cyAhPSBjdHgtPm5yX2FjdGl2ZSkKCQkJcm90YXRlID0gMTsKCX0KCglwZXJmX3BtdV9kaXNhYmxlKGNwdWN0eC0+Y3R4LnBtdSk7CglwZXJmX2N0eF9hZGp1c3RfZnJlcSgmY3B1Y3R4LT5jdHgsIGludGVydmFsKTsKCWlmIChjdHgpCgkJcGVyZl9jdHhfYWRqdXN0X2ZyZXEoY3R4LCBpbnRlcnZhbCk7CgoJaWYgKCFyb3RhdGUpCgkJZ290byBkb25lOwoKCWNwdV9jdHhfc2NoZWRfb3V0KGNwdWN0eCwgRVZFTlRfRkxFWElCTEUpOwoJaWYgKGN0eCkKCQl0YXNrX2N0eF9zY2hlZF9vdXQoY3R4LCBFVkVOVF9GTEVYSUJMRSk7CgoJcm90YXRlX2N0eCgmY3B1Y3R4LT5jdHgpOwoJaWYgKGN0eCkKCQlyb3RhdGVfY3R4KGN0eCk7CgoJY3B1X2N0eF9zY2hlZF9pbihjcHVjdHgsIEVWRU5UX0ZMRVhJQkxFKTsKCWlmIChjdHgpCgkJdGFza19jdHhfc2NoZWRfaW4oY3R4LCBFVkVOVF9GTEVYSUJMRSk7Cgpkb25lOgoJaWYgKHJlbW92ZSkKCQlsaXN0X2RlbF9pbml0KCZjcHVjdHgtPnJvdGF0aW9uX2xpc3QpOwoKCXBlcmZfcG11X2VuYWJsZShjcHVjdHgtPmN0eC5wbXUpOwp9Cgp2b2lkIHBlcmZfZXZlbnRfdGFza190aWNrKHZvaWQpCnsKCXN0cnVjdCBsaXN0X2hlYWQgKmhlYWQgPSAmX19nZXRfY3B1X3Zhcihyb3RhdGlvbl9saXN0KTsKCXN0cnVjdCBwZXJmX2NwdV9jb250ZXh0ICpjcHVjdHgsICp0bXA7CgoJV0FSTl9PTighaXJxc19kaXNhYmxlZCgpKTsKCglsaXN0X2Zvcl9lYWNoX2VudHJ5X3NhZmUoY3B1Y3R4LCB0bXAsIGhlYWQsIHJvdGF0aW9uX2xpc3QpIHsKCQlpZiAoY3B1Y3R4LT5qaWZmaWVzX2ludGVydmFsID09IDEgfHwKCQkJCSEoamlmZmllcyAlIGNwdWN0eC0+amlmZmllc19pbnRlcnZhbCkpCgkJCXBlcmZfcm90YXRlX2NvbnRleHQoY3B1Y3R4KTsKCX0KfQoKc3RhdGljIGludCBldmVudF9lbmFibGVfb25fZXhlYyhzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQsCgkJCQlzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0ICpjdHgpCnsKCWlmICghZXZlbnQtPmF0dHIuZW5hYmxlX29uX2V4ZWMpCgkJcmV0dXJuIDA7CgoJZXZlbnQtPmF0dHIuZW5hYmxlX29uX2V4ZWMgPSAwOwoJaWYgKGV2ZW50LT5zdGF0ZSA+PSBQRVJGX0VWRU5UX1NUQVRFX0lOQUNUSVZFKQoJCXJldHVybiAwOwoKCV9fcGVyZl9ldmVudF9tYXJrX2VuYWJsZWQoZXZlbnQsIGN0eCk7CgoJcmV0dXJuIDE7Cn0KCi8qCiAqIEVuYWJsZSBhbGwgb2YgYSB0YXNrJ3MgZXZlbnRzIHRoYXQgaGF2ZSBiZWVuIG1hcmtlZCBlbmFibGUtb24tZXhlYy4KICogVGhpcyBleHBlY3RzIHRhc2sgPT0gY3VycmVudC4KICovCnN0YXRpYyB2b2lkIHBlcmZfZXZlbnRfZW5hYmxlX29uX2V4ZWMoc3RydWN0IHBlcmZfZXZlbnRfY29udGV4dCAqY3R4KQp7CglzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQ7Cgl1bnNpZ25lZCBsb25nIGZsYWdzOwoJaW50IGVuYWJsZWQgPSAwOwoJaW50IHJldDsKCglsb2NhbF9pcnFfc2F2ZShmbGFncyk7CglpZiAoIWN0eCB8fCAhY3R4LT5ucl9ldmVudHMpCgkJZ290byBvdXQ7CgoJdGFza19jdHhfc2NoZWRfb3V0KGN0eCwgRVZFTlRfQUxMKTsKCglyYXdfc3Bpbl9sb2NrKCZjdHgtPmxvY2spOwoKCWxpc3RfZm9yX2VhY2hfZW50cnkoZXZlbnQsICZjdHgtPnBpbm5lZF9ncm91cHMsIGdyb3VwX2VudHJ5KSB7CgkJcmV0ID0gZXZlbnRfZW5hYmxlX29uX2V4ZWMoZXZlbnQsIGN0eCk7CgkJaWYgKHJldCkKCQkJZW5hYmxlZCA9IDE7Cgl9CgoJbGlzdF9mb3JfZWFjaF9lbnRyeShldmVudCwgJmN0eC0+ZmxleGlibGVfZ3JvdXBzLCBncm91cF9lbnRyeSkgewoJCXJldCA9IGV2ZW50X2VuYWJsZV9vbl9leGVjKGV2ZW50LCBjdHgpOwoJCWlmIChyZXQpCgkJCWVuYWJsZWQgPSAxOwoJfQoKCS8qCgkgKiBVbmNsb25lIHRoaXMgY29udGV4dCBpZiB3ZSBlbmFibGVkIGFueSBldmVudC4KCSAqLwoJaWYgKGVuYWJsZWQpCgkJdW5jbG9uZV9jdHgoY3R4KTsKCglyYXdfc3Bpbl91bmxvY2soJmN0eC0+bG9jayk7CgoJcGVyZl9ldmVudF9jb250ZXh0X3NjaGVkX2luKGN0eCk7Cm91dDoKCWxvY2FsX2lycV9yZXN0b3JlKGZsYWdzKTsKfQoKLyoKICogQ3Jvc3MgQ1BVIGNhbGwgdG8gcmVhZCB0aGUgaGFyZHdhcmUgZXZlbnQKICovCnN0YXRpYyB2b2lkIF9fcGVyZl9ldmVudF9yZWFkKHZvaWQgKmluZm8pCnsKCXN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCA9IGluZm87CglzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0ICpjdHggPSBldmVudC0+Y3R4OwoJc3RydWN0IHBlcmZfY3B1X2NvbnRleHQgKmNwdWN0eCA9IF9fZ2V0X2NwdV9jb250ZXh0KGN0eCk7CgoJLyoKCSAqIElmIHRoaXMgaXMgYSB0YXNrIGNvbnRleHQsIHdlIG5lZWQgdG8gY2hlY2sgd2hldGhlciBpdCBpcwoJICogdGhlIGN1cnJlbnQgdGFzayBjb250ZXh0IG9mIHRoaXMgY3B1LiAgSWYgbm90IGl0IGhhcyBiZWVuCgkgKiBzY2hlZHVsZWQgb3V0IGJlZm9yZSB0aGUgc21wIGNhbGwgYXJyaXZlZC4gIEluIHRoYXQgY2FzZQoJICogZXZlbnQtPmNvdW50IHdvdWxkIGhhdmUgYmVlbiB1cGRhdGVkIHRvIGEgcmVjZW50IHNhbXBsZQoJICogd2hlbiB0aGUgZXZlbnQgd2FzIHNjaGVkdWxlZCBvdXQuCgkgKi8KCWlmIChjdHgtPnRhc2sgJiYgY3B1Y3R4LT50YXNrX2N0eCAhPSBjdHgpCgkJcmV0dXJuOwoKCXJhd19zcGluX2xvY2soJmN0eC0+bG9jayk7Cgl1cGRhdGVfY29udGV4dF90aW1lKGN0eCk7Cgl1cGRhdGVfZXZlbnRfdGltZXMoZXZlbnQpOwoJcmF3X3NwaW5fdW5sb2NrKCZjdHgtPmxvY2spOwoKCWV2ZW50LT5wbXUtPnJlYWQoZXZlbnQpOwp9CgpzdGF0aWMgaW5saW5lIHU2NCBwZXJmX2V2ZW50X2NvdW50KHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCkKewoJcmV0dXJuIGxvY2FsNjRfcmVhZCgmZXZlbnQtPmNvdW50KSArIGF0b21pYzY0X3JlYWQoJmV2ZW50LT5jaGlsZF9jb3VudCk7Cn0KCnN0YXRpYyB1NjQgcGVyZl9ldmVudF9yZWFkKHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCkKewoJLyoKCSAqIElmIGV2ZW50IGlzIGVuYWJsZWQgYW5kIGN1cnJlbnRseSBhY3RpdmUgb24gYSBDUFUsIHVwZGF0ZSB0aGUKCSAqIHZhbHVlIGluIHRoZSBldmVudCBzdHJ1Y3R1cmU6CgkgKi8KCWlmIChldmVudC0+c3RhdGUgPT0gUEVSRl9FVkVOVF9TVEFURV9BQ1RJVkUpIHsKCQlzbXBfY2FsbF9mdW5jdGlvbl9zaW5nbGUoZXZlbnQtPm9uY3B1LAoJCQkJCSBfX3BlcmZfZXZlbnRfcmVhZCwgZXZlbnQsIDEpOwoJfSBlbHNlIGlmIChldmVudC0+c3RhdGUgPT0gUEVSRl9FVkVOVF9TVEFURV9JTkFDVElWRSkgewoJCXN0cnVjdCBwZXJmX2V2ZW50X2NvbnRleHQgKmN0eCA9IGV2ZW50LT5jdHg7CgkJdW5zaWduZWQgbG9uZyBmbGFnczsKCgkJcmF3X3NwaW5fbG9ja19pcnFzYXZlKCZjdHgtPmxvY2ssIGZsYWdzKTsKCQkvKgoJCSAqIG1heSByZWFkIHdoaWxlIGNvbnRleHQgaXMgbm90IGFjdGl2ZQoJCSAqIChlLmcuLCB0aHJlYWQgaXMgYmxvY2tlZCksIGluIHRoYXQgY2FzZQoJCSAqIHdlIGNhbm5vdCB1cGRhdGUgY29udGV4dCB0aW1lCgkJICovCgkJaWYgKGN0eC0+aXNfYWN0aXZlKQoJCQl1cGRhdGVfY29udGV4dF90aW1lKGN0eCk7CgkJdXBkYXRlX2V2ZW50X3RpbWVzKGV2ZW50KTsKCQlyYXdfc3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmY3R4LT5sb2NrLCBmbGFncyk7Cgl9CgoJcmV0dXJuIHBlcmZfZXZlbnRfY291bnQoZXZlbnQpOwp9CgovKgogKiBDYWxsY2hhaW4gc3VwcG9ydAogKi8KCnN0cnVjdCBjYWxsY2hhaW5fY3B1c19lbnRyaWVzIHsKCXN0cnVjdCByY3VfaGVhZAkJCXJjdV9oZWFkOwoJc3RydWN0IHBlcmZfY2FsbGNoYWluX2VudHJ5CSpjcHVfZW50cmllc1swXTsKfTsKCnN0YXRpYyBERUZJTkVfUEVSX0NQVShpbnQsIGNhbGxjaGFpbl9yZWN1cnNpb25bUEVSRl9OUl9DT05URVhUU10pOwpzdGF0aWMgYXRvbWljX3QgbnJfY2FsbGNoYWluX2V2ZW50czsKc3RhdGljIERFRklORV9NVVRFWChjYWxsY2hhaW5fbXV0ZXgpOwpzdHJ1Y3QgY2FsbGNoYWluX2NwdXNfZW50cmllcyAqY2FsbGNoYWluX2NwdXNfZW50cmllczsKCgpfX3dlYWsgdm9pZCBwZXJmX2NhbGxjaGFpbl9rZXJuZWwoc3RydWN0IHBlcmZfY2FsbGNoYWluX2VudHJ5ICplbnRyeSwKCQkJCSAgc3RydWN0IHB0X3JlZ3MgKnJlZ3MpCnsKfQoKX193ZWFrIHZvaWQgcGVyZl9jYWxsY2hhaW5fdXNlcihzdHJ1Y3QgcGVyZl9jYWxsY2hhaW5fZW50cnkgKmVudHJ5LAoJCQkJc3RydWN0IHB0X3JlZ3MgKnJlZ3MpCnsKfQoKc3RhdGljIHZvaWQgcmVsZWFzZV9jYWxsY2hhaW5fYnVmZmVyc19yY3Uoc3RydWN0IHJjdV9oZWFkICpoZWFkKQp7CglzdHJ1Y3QgY2FsbGNoYWluX2NwdXNfZW50cmllcyAqZW50cmllczsKCWludCBjcHU7CgoJZW50cmllcyA9IGNvbnRhaW5lcl9vZihoZWFkLCBzdHJ1Y3QgY2FsbGNoYWluX2NwdXNfZW50cmllcywgcmN1X2hlYWQpOwoKCWZvcl9lYWNoX3Bvc3NpYmxlX2NwdShjcHUpCgkJa2ZyZWUoZW50cmllcy0+Y3B1X2VudHJpZXNbY3B1XSk7CgoJa2ZyZWUoZW50cmllcyk7Cn0KCnN0YXRpYyB2b2lkIHJlbGVhc2VfY2FsbGNoYWluX2J1ZmZlcnModm9pZCkKewoJc3RydWN0IGNhbGxjaGFpbl9jcHVzX2VudHJpZXMgKmVudHJpZXM7CgoJZW50cmllcyA9IGNhbGxjaGFpbl9jcHVzX2VudHJpZXM7CglyY3VfYXNzaWduX3BvaW50ZXIoY2FsbGNoYWluX2NwdXNfZW50cmllcywgTlVMTCk7CgljYWxsX3JjdSgmZW50cmllcy0+cmN1X2hlYWQsIHJlbGVhc2VfY2FsbGNoYWluX2J1ZmZlcnNfcmN1KTsKfQoKc3RhdGljIGludCBhbGxvY19jYWxsY2hhaW5fYnVmZmVycyh2b2lkKQp7CglpbnQgY3B1OwoJaW50IHNpemU7CglzdHJ1Y3QgY2FsbGNoYWluX2NwdXNfZW50cmllcyAqZW50cmllczsKCgkvKgoJICogV2UgY2FuJ3QgdXNlIHRoZSBwZXJjcHUgYWxsb2NhdGlvbiBBUEkgZm9yIGRhdGEgdGhhdCBjYW4gYmUKCSAqIGFjY2Vzc2VkIGZyb20gTk1JLiBVc2UgYSB0ZW1wb3JhcnkgbWFudWFsIHBlciBjcHUgYWxsb2NhdGlvbgoJICogdW50aWwgdGhhdCBnZXRzIHNvcnRlZCBvdXQuCgkgKi8KCXNpemUgPSBzaXplb2YoKmVudHJpZXMpICsgc2l6ZW9mKHN0cnVjdCBwZXJmX2NhbGxjaGFpbl9lbnRyeSAqKSAqCgkJbnVtX3Bvc3NpYmxlX2NwdXMoKTsKCgllbnRyaWVzID0ga3phbGxvYyhzaXplLCBHRlBfS0VSTkVMKTsKCWlmICghZW50cmllcykKCQlyZXR1cm4gLUVOT01FTTsKCglzaXplID0gc2l6ZW9mKHN0cnVjdCBwZXJmX2NhbGxjaGFpbl9lbnRyeSkgKiBQRVJGX05SX0NPTlRFWFRTOwoKCWZvcl9lYWNoX3Bvc3NpYmxlX2NwdShjcHUpIHsKCQllbnRyaWVzLT5jcHVfZW50cmllc1tjcHVdID0ga21hbGxvY19ub2RlKHNpemUsIEdGUF9LRVJORUwsCgkJCQkJCQkgY3B1X3RvX25vZGUoY3B1KSk7CgkJaWYgKCFlbnRyaWVzLT5jcHVfZW50cmllc1tjcHVdKQoJCQlnb3RvIGZhaWw7Cgl9CgoJcmN1X2Fzc2lnbl9wb2ludGVyKGNhbGxjaGFpbl9jcHVzX2VudHJpZXMsIGVudHJpZXMpOwoKCXJldHVybiAwOwoKZmFpbDoKCWZvcl9lYWNoX3Bvc3NpYmxlX2NwdShjcHUpCgkJa2ZyZWUoZW50cmllcy0+Y3B1X2VudHJpZXNbY3B1XSk7CglrZnJlZShlbnRyaWVzKTsKCglyZXR1cm4gLUVOT01FTTsKfQoKc3RhdGljIGludCBnZXRfY2FsbGNoYWluX2J1ZmZlcnModm9pZCkKewoJaW50IGVyciA9IDA7CglpbnQgY291bnQ7CgoJbXV0ZXhfbG9jaygmY2FsbGNoYWluX211dGV4KTsKCgljb3VudCA9IGF0b21pY19pbmNfcmV0dXJuKCZucl9jYWxsY2hhaW5fZXZlbnRzKTsKCWlmIChXQVJOX09OX09OQ0UoY291bnQgPCAxKSkgewoJCWVyciA9IC1FSU5WQUw7CgkJZ290byBleGl0OwoJfQoKCWlmIChjb3VudCA+IDEpIHsKCQkvKiBJZiB0aGUgYWxsb2NhdGlvbiBmYWlsZWQsIGdpdmUgdXAgKi8KCQlpZiAoIWNhbGxjaGFpbl9jcHVzX2VudHJpZXMpCgkJCWVyciA9IC1FTk9NRU07CgkJZ290byBleGl0OwoJfQoKCWVyciA9IGFsbG9jX2NhbGxjaGFpbl9idWZmZXJzKCk7CglpZiAoZXJyKQoJCXJlbGVhc2VfY2FsbGNoYWluX2J1ZmZlcnMoKTsKZXhpdDoKCW11dGV4X3VubG9jaygmY2FsbGNoYWluX211dGV4KTsKCglyZXR1cm4gZXJyOwp9CgpzdGF0aWMgdm9pZCBwdXRfY2FsbGNoYWluX2J1ZmZlcnModm9pZCkKewoJaWYgKGF0b21pY19kZWNfYW5kX211dGV4X2xvY2soJm5yX2NhbGxjaGFpbl9ldmVudHMsICZjYWxsY2hhaW5fbXV0ZXgpKSB7CgkJcmVsZWFzZV9jYWxsY2hhaW5fYnVmZmVycygpOwoJCW11dGV4X3VubG9jaygmY2FsbGNoYWluX211dGV4KTsKCX0KfQoKc3RhdGljIGludCBnZXRfcmVjdXJzaW9uX2NvbnRleHQoaW50ICpyZWN1cnNpb24pCnsKCWludCByY3R4OwoKCWlmIChpbl9ubWkoKSkKCQlyY3R4ID0gMzsKCWVsc2UgaWYgKGluX2lycSgpKQoJCXJjdHggPSAyOwoJZWxzZSBpZiAoaW5fc29mdGlycSgpKQoJCXJjdHggPSAxOwoJZWxzZQoJCXJjdHggPSAwOwoKCWlmIChyZWN1cnNpb25bcmN0eF0pCgkJcmV0dXJuIC0xOwoKCXJlY3Vyc2lvbltyY3R4XSsrOwoJYmFycmllcigpOwoKCXJldHVybiByY3R4Owp9CgpzdGF0aWMgaW5saW5lIHZvaWQgcHV0X3JlY3Vyc2lvbl9jb250ZXh0KGludCAqcmVjdXJzaW9uLCBpbnQgcmN0eCkKewoJYmFycmllcigpOwoJcmVjdXJzaW9uW3JjdHhdLS07Cn0KCnN0YXRpYyBzdHJ1Y3QgcGVyZl9jYWxsY2hhaW5fZW50cnkgKmdldF9jYWxsY2hhaW5fZW50cnkoaW50ICpyY3R4KQp7CglpbnQgY3B1OwoJc3RydWN0IGNhbGxjaGFpbl9jcHVzX2VudHJpZXMgKmVudHJpZXM7CgoJKnJjdHggPSBnZXRfcmVjdXJzaW9uX2NvbnRleHQoX19nZXRfY3B1X3ZhcihjYWxsY2hhaW5fcmVjdXJzaW9uKSk7CglpZiAoKnJjdHggPT0gLTEpCgkJcmV0dXJuIE5VTEw7CgoJZW50cmllcyA9IHJjdV9kZXJlZmVyZW5jZShjYWxsY2hhaW5fY3B1c19lbnRyaWVzKTsKCWlmICghZW50cmllcykKCQlyZXR1cm4gTlVMTDsKCgljcHUgPSBzbXBfcHJvY2Vzc29yX2lkKCk7CgoJcmV0dXJuICZlbnRyaWVzLT5jcHVfZW50cmllc1tjcHVdWypyY3R4XTsKfQoKc3RhdGljIHZvaWQKcHV0X2NhbGxjaGFpbl9lbnRyeShpbnQgcmN0eCkKewoJcHV0X3JlY3Vyc2lvbl9jb250ZXh0KF9fZ2V0X2NwdV92YXIoY2FsbGNoYWluX3JlY3Vyc2lvbiksIHJjdHgpOwp9CgpzdGF0aWMgc3RydWN0IHBlcmZfY2FsbGNoYWluX2VudHJ5ICpwZXJmX2NhbGxjaGFpbihzdHJ1Y3QgcHRfcmVncyAqcmVncykKewoJaW50IHJjdHg7CglzdHJ1Y3QgcGVyZl9jYWxsY2hhaW5fZW50cnkgKmVudHJ5OwoKCgllbnRyeSA9IGdldF9jYWxsY2hhaW5fZW50cnkoJnJjdHgpOwoJaWYgKHJjdHggPT0gLTEpCgkJcmV0dXJuIE5VTEw7CgoJaWYgKCFlbnRyeSkKCQlnb3RvIGV4aXRfcHV0OwoKCWVudHJ5LT5uciA9IDA7CgoJaWYgKCF1c2VyX21vZGUocmVncykpIHsKCQlwZXJmX2NhbGxjaGFpbl9zdG9yZShlbnRyeSwgUEVSRl9DT05URVhUX0tFUk5FTCk7CgkJcGVyZl9jYWxsY2hhaW5fa2VybmVsKGVudHJ5LCByZWdzKTsKCQlpZiAoY3VycmVudC0+bW0pCgkJCXJlZ3MgPSB0YXNrX3B0X3JlZ3MoY3VycmVudCk7CgkJZWxzZQoJCQlyZWdzID0gTlVMTDsKCX0KCglpZiAocmVncykgewoJCXBlcmZfY2FsbGNoYWluX3N0b3JlKGVudHJ5LCBQRVJGX0NPTlRFWFRfVVNFUik7CgkJcGVyZl9jYWxsY2hhaW5fdXNlcihlbnRyeSwgcmVncyk7Cgl9CgpleGl0X3B1dDoKCXB1dF9jYWxsY2hhaW5fZW50cnkocmN0eCk7CgoJcmV0dXJuIGVudHJ5Owp9CgovKgogKiBJbml0aWFsaXplIHRoZSBwZXJmX2V2ZW50IGNvbnRleHQgaW4gYSB0YXNrX3N0cnVjdDoKICovCnN0YXRpYyB2b2lkIF9fcGVyZl9ldmVudF9pbml0X2NvbnRleHQoc3RydWN0IHBlcmZfZXZlbnRfY29udGV4dCAqY3R4KQp7CglyYXdfc3Bpbl9sb2NrX2luaXQoJmN0eC0+bG9jayk7CgltdXRleF9pbml0KCZjdHgtPm11dGV4KTsKCUlOSVRfTElTVF9IRUFEKCZjdHgtPnBpbm5lZF9ncm91cHMpOwoJSU5JVF9MSVNUX0hFQUQoJmN0eC0+ZmxleGlibGVfZ3JvdXBzKTsKCUlOSVRfTElTVF9IRUFEKCZjdHgtPmV2ZW50X2xpc3QpOwoJYXRvbWljX3NldCgmY3R4LT5yZWZjb3VudCwgMSk7Cn0KCnN0YXRpYyBzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0ICoKYWxsb2NfcGVyZl9jb250ZXh0KHN0cnVjdCBwbXUgKnBtdSwgc3RydWN0IHRhc2tfc3RydWN0ICp0YXNrKQp7CglzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0ICpjdHg7CgoJY3R4ID0ga3phbGxvYyhzaXplb2Yoc3RydWN0IHBlcmZfZXZlbnRfY29udGV4dCksIEdGUF9LRVJORUwpOwoJaWYgKCFjdHgpCgkJcmV0dXJuIE5VTEw7CgoJX19wZXJmX2V2ZW50X2luaXRfY29udGV4dChjdHgpOwoJaWYgKHRhc2spIHsKCQljdHgtPnRhc2sgPSB0YXNrOwoJCWdldF90YXNrX3N0cnVjdCh0YXNrKTsKCX0KCWN0eC0+cG11ID0gcG11OwoKCXJldHVybiBjdHg7Cn0KCnN0YXRpYyBzdHJ1Y3QgdGFza19zdHJ1Y3QgKgpmaW5kX2xpdmVseV90YXNrX2J5X3ZwaWQocGlkX3QgdnBpZCkKewoJc3RydWN0IHRhc2tfc3RydWN0ICp0YXNrOwoJaW50IGVycjsKCglyY3VfcmVhZF9sb2NrKCk7CglpZiAoIXZwaWQpCgkJdGFzayA9IGN1cnJlbnQ7CgllbHNlCgkJdGFzayA9IGZpbmRfdGFza19ieV92cGlkKHZwaWQpOwoJaWYgKHRhc2spCgkJZ2V0X3Rhc2tfc3RydWN0KHRhc2spOwoJcmN1X3JlYWRfdW5sb2NrKCk7CgoJaWYgKCF0YXNrKQoJCXJldHVybiBFUlJfUFRSKC1FU1JDSCk7CgoJLyoKCSAqIENhbid0IGF0dGFjaCBldmVudHMgdG8gYSBkeWluZyB0YXNrLgoJICovCgllcnIgPSAtRVNSQ0g7CglpZiAodGFzay0+ZmxhZ3MgJiBQRl9FWElUSU5HKQoJCWdvdG8gZXJyb3V0OwoKCS8qIFJldXNlIHB0cmFjZSBwZXJtaXNzaW9uIGNoZWNrcyBmb3Igbm93LiAqLwoJZXJyID0gLUVBQ0NFUzsKCWlmICghcHRyYWNlX21heV9hY2Nlc3ModGFzaywgUFRSQUNFX01PREVfUkVBRCkpCgkJZ290byBlcnJvdXQ7CgoJcmV0dXJuIHRhc2s7CmVycm91dDoKCXB1dF90YXNrX3N0cnVjdCh0YXNrKTsKCXJldHVybiBFUlJfUFRSKGVycik7Cgp9CgpzdGF0aWMgc3RydWN0IHBlcmZfZXZlbnRfY29udGV4dCAqCmZpbmRfZ2V0X2NvbnRleHQoc3RydWN0IHBtdSAqcG11LCBzdHJ1Y3QgdGFza19zdHJ1Y3QgKnRhc2ssIGludCBjcHUpCnsKCXN0cnVjdCBwZXJmX2V2ZW50X2NvbnRleHQgKmN0eDsKCXN0cnVjdCBwZXJmX2NwdV9jb250ZXh0ICpjcHVjdHg7Cgl1bnNpZ25lZCBsb25nIGZsYWdzOwoJaW50IGN0eG4sIGVycjsKCglpZiAoIXRhc2sgJiYgY3B1ICE9IC0xKSB7CgkJLyogTXVzdCBiZSByb290IHRvIG9wZXJhdGUgb24gYSBDUFUgZXZlbnQ6ICovCgkJaWYgKHBlcmZfcGFyYW5vaWRfY3B1KCkgJiYgIWNhcGFibGUoQ0FQX1NZU19BRE1JTikpCgkJCXJldHVybiBFUlJfUFRSKC1FQUNDRVMpOwoKCQlpZiAoY3B1IDwgMCB8fCBjcHUgPj0gbnJfY3B1bWFza19iaXRzKQoJCQlyZXR1cm4gRVJSX1BUUigtRUlOVkFMKTsKCgkJLyoKCQkgKiBXZSBjb3VsZCBiZSBjbGV2ZXIgYW5kIGFsbG93IHRvIGF0dGFjaCBhIGV2ZW50IHRvIGFuCgkJICogb2ZmbGluZSBDUFUgYW5kIGFjdGl2YXRlIGl0IHdoZW4gdGhlIENQVSBjb21lcyB1cCwgYnV0CgkJICogdGhhdCdzIGZvciBsYXRlci4KCQkgKi8KCQlpZiAoIWNwdV9vbmxpbmUoY3B1KSkKCQkJcmV0dXJuIEVSUl9QVFIoLUVOT0RFVik7CgoJCWNwdWN0eCA9IHBlcl9jcHVfcHRyKHBtdS0+cG11X2NwdV9jb250ZXh0LCBjcHUpOwoJCWN0eCA9ICZjcHVjdHgtPmN0eDsKCQlnZXRfY3R4KGN0eCk7CgoJCXJldHVybiBjdHg7Cgl9CgoJZXJyID0gLUVJTlZBTDsKCWN0eG4gPSBwbXUtPnRhc2tfY3R4X25yOwoJaWYgKGN0eG4gPCAwKQoJCWdvdG8gZXJyb3V0OwoKcmV0cnk6CgljdHggPSBwZXJmX2xvY2tfdGFza19jb250ZXh0KHRhc2ssIGN0eG4sICZmbGFncyk7CglpZiAoY3R4KSB7CgkJdW5jbG9uZV9jdHgoY3R4KTsKCQlyYXdfc3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmY3R4LT5sb2NrLCBmbGFncyk7Cgl9CgoJaWYgKCFjdHgpIHsKCQljdHggPSBhbGxvY19wZXJmX2NvbnRleHQocG11LCB0YXNrKTsKCQllcnIgPSAtRU5PTUVNOwoJCWlmICghY3R4KQoJCQlnb3RvIGVycm91dDsKCgkJZ2V0X2N0eChjdHgpOwoKCQlpZiAoY21weGNoZygmdGFzay0+cGVyZl9ldmVudF9jdHhwW2N0eG5dLCBOVUxMLCBjdHgpKSB7CgkJCS8qCgkJCSAqIFdlIHJhY2VkIHdpdGggc29tZSBvdGhlciB0YXNrOyB1c2UKCQkJICogdGhlIGNvbnRleHQgdGhleSBzZXQuCgkJCSAqLwoJCQlwdXRfdGFza19zdHJ1Y3QodGFzayk7CgkJCWtmcmVlKGN0eCk7CgkJCWdvdG8gcmV0cnk7CgkJfQoJfQoKCXJldHVybiBjdHg7CgplcnJvdXQ6CglyZXR1cm4gRVJSX1BUUihlcnIpOwp9CgpzdGF0aWMgdm9pZCBwZXJmX2V2ZW50X2ZyZWVfZmlsdGVyKHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCk7CgpzdGF0aWMgdm9pZCBmcmVlX2V2ZW50X3JjdShzdHJ1Y3QgcmN1X2hlYWQgKmhlYWQpCnsKCXN0cnVjdCBwZXJmX2V2ZW50ICpldmVudDsKCglldmVudCA9IGNvbnRhaW5lcl9vZihoZWFkLCBzdHJ1Y3QgcGVyZl9ldmVudCwgcmN1X2hlYWQpOwoJaWYgKGV2ZW50LT5ucykKCQlwdXRfcGlkX25zKGV2ZW50LT5ucyk7CglwZXJmX2V2ZW50X2ZyZWVfZmlsdGVyKGV2ZW50KTsKCWtmcmVlKGV2ZW50KTsKfQoKc3RhdGljIHZvaWQgcGVyZl9idWZmZXJfcHV0KHN0cnVjdCBwZXJmX2J1ZmZlciAqYnVmZmVyKTsKCnN0YXRpYyB2b2lkIGZyZWVfZXZlbnQoc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50KQp7CglpcnFfd29ya19zeW5jKCZldmVudC0+cGVuZGluZyk7CgoJaWYgKCFldmVudC0+cGFyZW50KSB7CgkJaWYgKGV2ZW50LT5hdHRhY2hfc3RhdGUgJiBQRVJGX0FUVEFDSF9UQVNLKQoJCQlqdW1wX2xhYmVsX2RlYygmcGVyZl90YXNrX2V2ZW50cyk7CgkJaWYgKGV2ZW50LT5hdHRyLm1tYXAgfHwgZXZlbnQtPmF0dHIubW1hcF9kYXRhKQoJCQlhdG9taWNfZGVjKCZucl9tbWFwX2V2ZW50cyk7CgkJaWYgKGV2ZW50LT5hdHRyLmNvbW0pCgkJCWF0b21pY19kZWMoJm5yX2NvbW1fZXZlbnRzKTsKCQlpZiAoZXZlbnQtPmF0dHIudGFzaykKCQkJYXRvbWljX2RlYygmbnJfdGFza19ldmVudHMpOwoJCWlmIChldmVudC0+YXR0ci5zYW1wbGVfdHlwZSAmIFBFUkZfU0FNUExFX0NBTExDSEFJTikKCQkJcHV0X2NhbGxjaGFpbl9idWZmZXJzKCk7Cgl9CgoJaWYgKGV2ZW50LT5idWZmZXIpIHsKCQlwZXJmX2J1ZmZlcl9wdXQoZXZlbnQtPmJ1ZmZlcik7CgkJZXZlbnQtPmJ1ZmZlciA9IE5VTEw7Cgl9CgoJaWYgKGV2ZW50LT5kZXN0cm95KQoJCWV2ZW50LT5kZXN0cm95KGV2ZW50KTsKCglpZiAoZXZlbnQtPmN0eCkKCQlwdXRfY3R4KGV2ZW50LT5jdHgpOwoKCWNhbGxfcmN1KCZldmVudC0+cmN1X2hlYWQsIGZyZWVfZXZlbnRfcmN1KTsKfQoKaW50IHBlcmZfZXZlbnRfcmVsZWFzZV9rZXJuZWwoc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50KQp7CglzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0ICpjdHggPSBldmVudC0+Y3R4OwoKCS8qCgkgKiBSZW1vdmUgZnJvbSB0aGUgUE1VLCBjYW4ndCBnZXQgcmUtZW5hYmxlZCBzaW5jZSB3ZSBnb3QKCSAqIGhlcmUgYmVjYXVzZSB0aGUgbGFzdCByZWYgd2VudC4KCSAqLwoJcGVyZl9ldmVudF9kaXNhYmxlKGV2ZW50KTsKCglXQVJOX09OX09OQ0UoY3R4LT5wYXJlbnRfY3R4KTsKCS8qCgkgKiBUaGVyZSBhcmUgdHdvIHdheXMgdGhpcyBhbm5vdGF0aW9uIGlzIHVzZWZ1bDoKCSAqCgkgKiAgMSkgdGhlcmUgaXMgYSBsb2NrIHJlY3Vyc2lvbiBmcm9tIHBlcmZfZXZlbnRfZXhpdF90YXNrCgkgKiAgICAgc2VlIHRoZSBjb21tZW50IHRoZXJlLgoJICoKCSAqICAyKSB0aGVyZSBpcyBhIGxvY2staW52ZXJzaW9uIHdpdGggbW1hcF9zZW0gdGhyb3VnaAoJICogICAgIHBlcmZfZXZlbnRfcmVhZF9ncm91cCgpLCB3aGljaCB0YWtlcyBmYXVsdHMgd2hpbGUKCSAqICAgICBob2xkaW5nIGN0eC0+bXV0ZXgsIGhvd2V2ZXIgdGhpcyBpcyBjYWxsZWQgYWZ0ZXIKCSAqICAgICB0aGUgbGFzdCBmaWxlZGVzYyBkaWVkLCBzbyB0aGVyZSBpcyBubyBwb3NzaWJpbGl0eQoJICogICAgIHRvIHRyaWdnZXIgdGhlIEFCLUJBIGNhc2UuCgkgKi8KCW11dGV4X2xvY2tfbmVzdGVkKCZjdHgtPm11dGV4LCBTSU5HTEVfREVQVEhfTkVTVElORyk7CglyYXdfc3Bpbl9sb2NrX2lycSgmY3R4LT5sb2NrKTsKCXBlcmZfZ3JvdXBfZGV0YWNoKGV2ZW50KTsKCWxpc3RfZGVsX2V2ZW50KGV2ZW50LCBjdHgpOwoJcmF3X3NwaW5fdW5sb2NrX2lycSgmY3R4LT5sb2NrKTsKCW11dGV4X3VubG9jaygmY3R4LT5tdXRleCk7CgoJZnJlZV9ldmVudChldmVudCk7CgoJcmV0dXJuIDA7Cn0KRVhQT1JUX1NZTUJPTF9HUEwocGVyZl9ldmVudF9yZWxlYXNlX2tlcm5lbCk7CgovKgogKiBDYWxsZWQgd2hlbiB0aGUgbGFzdCByZWZlcmVuY2UgdG8gdGhlIGZpbGUgaXMgZ29uZS4KICovCnN0YXRpYyBpbnQgcGVyZl9yZWxlYXNlKHN0cnVjdCBpbm9kZSAqaW5vZGUsIHN0cnVjdCBmaWxlICpmaWxlKQp7CglzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQgPSBmaWxlLT5wcml2YXRlX2RhdGE7CglzdHJ1Y3QgdGFza19zdHJ1Y3QgKm93bmVyOwoKCWZpbGUtPnByaXZhdGVfZGF0YSA9IE5VTEw7CgoJcmN1X3JlYWRfbG9jaygpOwoJb3duZXIgPSBBQ0NFU1NfT05DRShldmVudC0+b3duZXIpOwoJLyoKCSAqIE1hdGNoZXMgdGhlIHNtcF93bWIoKSBpbiBwZXJmX2V2ZW50X2V4aXRfdGFzaygpLiBJZiB3ZSBvYnNlcnZlCgkgKiAhb3duZXIgaXQgbWVhbnMgdGhlIGxpc3QgZGVsZXRpb24gaXMgY29tcGxldGUgYW5kIHdlIGNhbiBpbmRlZWQKCSAqIGZyZWUgdGhpcyBldmVudCwgb3RoZXJ3aXNlIHdlIG5lZWQgdG8gc2VyaWFsaXplIG9uCgkgKiBvd25lci0+cGVyZl9ldmVudF9tdXRleC4KCSAqLwoJc21wX3JlYWRfYmFycmllcl9kZXBlbmRzKCk7CglpZiAob3duZXIpIHsKCQkvKgoJCSAqIFNpbmNlIGRlbGF5ZWRfcHV0X3Rhc2tfc3RydWN0KCkgYWxzbyBkcm9wcyB0aGUgbGFzdAoJCSAqIHRhc2sgcmVmZXJlbmNlIHdlIGNhbiBzYWZlbHkgdGFrZSBhIG5ldyByZWZlcmVuY2UKCQkgKiB3aGlsZSBob2xkaW5nIHRoZSByY3VfcmVhZF9sb2NrKCkuCgkJICovCgkJZ2V0X3Rhc2tfc3RydWN0KG93bmVyKTsKCX0KCXJjdV9yZWFkX3VubG9jaygpOwoKCWlmIChvd25lcikgewoJCW11dGV4X2xvY2soJm93bmVyLT5wZXJmX2V2ZW50X211dGV4KTsKCQkvKgoJCSAqIFdlIGhhdmUgdG8gcmUtY2hlY2sgdGhlIGV2ZW50LT5vd25lciBmaWVsZCwgaWYgaXQgaXMgY2xlYXJlZAoJCSAqIHdlIHJhY2VkIHdpdGggcGVyZl9ldmVudF9leGl0X3Rhc2soKSwgYWNxdWlyaW5nIHRoZSBtdXRleAoJCSAqIGVuc3VyZWQgdGhleSdyZSBkb25lLCBhbmQgd2UgY2FuIHByb2NlZWQgd2l0aCBmcmVlaW5nIHRoZQoJCSAqIGV2ZW50LgoJCSAqLwoJCWlmIChldmVudC0+b3duZXIpCgkJCWxpc3RfZGVsX2luaXQoJmV2ZW50LT5vd25lcl9lbnRyeSk7CgkJbXV0ZXhfdW5sb2NrKCZvd25lci0+cGVyZl9ldmVudF9tdXRleCk7CgkJcHV0X3Rhc2tfc3RydWN0KG93bmVyKTsKCX0KCglyZXR1cm4gcGVyZl9ldmVudF9yZWxlYXNlX2tlcm5lbChldmVudCk7Cn0KCnU2NCBwZXJmX2V2ZW50X3JlYWRfdmFsdWUoc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50LCB1NjQgKmVuYWJsZWQsIHU2NCAqcnVubmluZykKewoJc3RydWN0IHBlcmZfZXZlbnQgKmNoaWxkOwoJdTY0IHRvdGFsID0gMDsKCgkqZW5hYmxlZCA9IDA7CgkqcnVubmluZyA9IDA7CgoJbXV0ZXhfbG9jaygmZXZlbnQtPmNoaWxkX211dGV4KTsKCXRvdGFsICs9IHBlcmZfZXZlbnRfcmVhZChldmVudCk7CgkqZW5hYmxlZCArPSBldmVudC0+dG90YWxfdGltZV9lbmFibGVkICsKCQkJYXRvbWljNjRfcmVhZCgmZXZlbnQtPmNoaWxkX3RvdGFsX3RpbWVfZW5hYmxlZCk7CgkqcnVubmluZyArPSBldmVudC0+dG90YWxfdGltZV9ydW5uaW5nICsKCQkJYXRvbWljNjRfcmVhZCgmZXZlbnQtPmNoaWxkX3RvdGFsX3RpbWVfcnVubmluZyk7CgoJbGlzdF9mb3JfZWFjaF9lbnRyeShjaGlsZCwgJmV2ZW50LT5jaGlsZF9saXN0LCBjaGlsZF9saXN0KSB7CgkJdG90YWwgKz0gcGVyZl9ldmVudF9yZWFkKGNoaWxkKTsKCQkqZW5hYmxlZCArPSBjaGlsZC0+dG90YWxfdGltZV9lbmFibGVkOwoJCSpydW5uaW5nICs9IGNoaWxkLT50b3RhbF90aW1lX3J1bm5pbmc7Cgl9CgltdXRleF91bmxvY2soJmV2ZW50LT5jaGlsZF9tdXRleCk7CgoJcmV0dXJuIHRvdGFsOwp9CkVYUE9SVF9TWU1CT0xfR1BMKHBlcmZfZXZlbnRfcmVhZF92YWx1ZSk7CgpzdGF0aWMgaW50IHBlcmZfZXZlbnRfcmVhZF9ncm91cChzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQsCgkJCQkgICB1NjQgcmVhZF9mb3JtYXQsIGNoYXIgX191c2VyICpidWYpCnsKCXN0cnVjdCBwZXJmX2V2ZW50ICpsZWFkZXIgPSBldmVudC0+Z3JvdXBfbGVhZGVyLCAqc3ViOwoJaW50IG4gPSAwLCBzaXplID0gMCwgcmV0ID0gLUVGQVVMVDsKCXN0cnVjdCBwZXJmX2V2ZW50X2NvbnRleHQgKmN0eCA9IGxlYWRlci0+Y3R4OwoJdTY0IHZhbHVlc1s1XTsKCXU2NCBjb3VudCwgZW5hYmxlZCwgcnVubmluZzsKCgltdXRleF9sb2NrKCZjdHgtPm11dGV4KTsKCWNvdW50ID0gcGVyZl9ldmVudF9yZWFkX3ZhbHVlKGxlYWRlciwgJmVuYWJsZWQsICZydW5uaW5nKTsKCgl2YWx1ZXNbbisrXSA9IDEgKyBsZWFkZXItPm5yX3NpYmxpbmdzOwoJaWYgKHJlYWRfZm9ybWF0ICYgUEVSRl9GT1JNQVRfVE9UQUxfVElNRV9FTkFCTEVEKQoJCXZhbHVlc1tuKytdID0gZW5hYmxlZDsKCWlmIChyZWFkX2Zvcm1hdCAmIFBFUkZfRk9STUFUX1RPVEFMX1RJTUVfUlVOTklORykKCQl2YWx1ZXNbbisrXSA9IHJ1bm5pbmc7Cgl2YWx1ZXNbbisrXSA9IGNvdW50OwoJaWYgKHJlYWRfZm9ybWF0ICYgUEVSRl9GT1JNQVRfSUQpCgkJdmFsdWVzW24rK10gPSBwcmltYXJ5X2V2ZW50X2lkKGxlYWRlcik7CgoJc2l6ZSA9IG4gKiBzaXplb2YodTY0KTsKCglpZiAoY29weV90b191c2VyKGJ1ZiwgdmFsdWVzLCBzaXplKSkKCQlnb3RvIHVubG9jazsKCglyZXQgPSBzaXplOwoKCWxpc3RfZm9yX2VhY2hfZW50cnkoc3ViLCAmbGVhZGVyLT5zaWJsaW5nX2xpc3QsIGdyb3VwX2VudHJ5KSB7CgkJbiA9IDA7CgoJCXZhbHVlc1tuKytdID0gcGVyZl9ldmVudF9yZWFkX3ZhbHVlKHN1YiwgJmVuYWJsZWQsICZydW5uaW5nKTsKCQlpZiAocmVhZF9mb3JtYXQgJiBQRVJGX0ZPUk1BVF9JRCkKCQkJdmFsdWVzW24rK10gPSBwcmltYXJ5X2V2ZW50X2lkKHN1Yik7CgoJCXNpemUgPSBuICogc2l6ZW9mKHU2NCk7CgoJCWlmIChjb3B5X3RvX3VzZXIoYnVmICsgcmV0LCB2YWx1ZXMsIHNpemUpKSB7CgkJCXJldCA9IC1FRkFVTFQ7CgkJCWdvdG8gdW5sb2NrOwoJCX0KCgkJcmV0ICs9IHNpemU7Cgl9CnVubG9jazoKCW11dGV4X3VubG9jaygmY3R4LT5tdXRleCk7CgoJcmV0dXJuIHJldDsKfQoKc3RhdGljIGludCBwZXJmX2V2ZW50X3JlYWRfb25lKHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCwKCQkJCSB1NjQgcmVhZF9mb3JtYXQsIGNoYXIgX191c2VyICpidWYpCnsKCXU2NCBlbmFibGVkLCBydW5uaW5nOwoJdTY0IHZhbHVlc1s0XTsKCWludCBuID0gMDsKCgl2YWx1ZXNbbisrXSA9IHBlcmZfZXZlbnRfcmVhZF92YWx1ZShldmVudCwgJmVuYWJsZWQsICZydW5uaW5nKTsKCWlmIChyZWFkX2Zvcm1hdCAmIFBFUkZfRk9STUFUX1RPVEFMX1RJTUVfRU5BQkxFRCkKCQl2YWx1ZXNbbisrXSA9IGVuYWJsZWQ7CglpZiAocmVhZF9mb3JtYXQgJiBQRVJGX0ZPUk1BVF9UT1RBTF9USU1FX1JVTk5JTkcpCgkJdmFsdWVzW24rK10gPSBydW5uaW5nOwoJaWYgKHJlYWRfZm9ybWF0ICYgUEVSRl9GT1JNQVRfSUQpCgkJdmFsdWVzW24rK10gPSBwcmltYXJ5X2V2ZW50X2lkKGV2ZW50KTsKCglpZiAoY29weV90b191c2VyKGJ1ZiwgdmFsdWVzLCBuICogc2l6ZW9mKHU2NCkpKQoJCXJldHVybiAtRUZBVUxUOwoKCXJldHVybiBuICogc2l6ZW9mKHU2NCk7Cn0KCi8qCiAqIFJlYWQgdGhlIHBlcmZvcm1hbmNlIGV2ZW50IC0gc2ltcGxlIG5vbiBibG9ja2luZyB2ZXJzaW9uIGZvciBub3cKICovCnN0YXRpYyBzc2l6ZV90CnBlcmZfcmVhZF9odyhzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQsIGNoYXIgX191c2VyICpidWYsIHNpemVfdCBjb3VudCkKewoJdTY0IHJlYWRfZm9ybWF0ID0gZXZlbnQtPmF0dHIucmVhZF9mb3JtYXQ7CglpbnQgcmV0OwoKCS8qCgkgKiBSZXR1cm4gZW5kLW9mLWZpbGUgZm9yIGEgcmVhZCBvbiBhIGV2ZW50IHRoYXQgaXMgaW4KCSAqIGVycm9yIHN0YXRlIChpLmUuIGJlY2F1c2UgaXQgd2FzIHBpbm5lZCBidXQgaXQgY291bGRuJ3QgYmUKCSAqIHNjaGVkdWxlZCBvbiB0byB0aGUgQ1BVIGF0IHNvbWUgcG9pbnQpLgoJICovCglpZiAoZXZlbnQtPnN0YXRlID09IFBFUkZfRVZFTlRfU1RBVEVfRVJST1IpCgkJcmV0dXJuIDA7CgoJaWYgKGNvdW50IDwgZXZlbnQtPnJlYWRfc2l6ZSkKCQlyZXR1cm4gLUVOT1NQQzsKCglXQVJOX09OX09OQ0UoZXZlbnQtPmN0eC0+cGFyZW50X2N0eCk7CglpZiAocmVhZF9mb3JtYXQgJiBQRVJGX0ZPUk1BVF9HUk9VUCkKCQlyZXQgPSBwZXJmX2V2ZW50X3JlYWRfZ3JvdXAoZXZlbnQsIHJlYWRfZm9ybWF0LCBidWYpOwoJZWxzZQoJCXJldCA9IHBlcmZfZXZlbnRfcmVhZF9vbmUoZXZlbnQsIHJlYWRfZm9ybWF0LCBidWYpOwoKCXJldHVybiByZXQ7Cn0KCnN0YXRpYyBzc2l6ZV90CnBlcmZfcmVhZChzdHJ1Y3QgZmlsZSAqZmlsZSwgY2hhciBfX3VzZXIgKmJ1Ziwgc2l6ZV90IGNvdW50LCBsb2ZmX3QgKnBwb3MpCnsKCXN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCA9IGZpbGUtPnByaXZhdGVfZGF0YTsKCglyZXR1cm4gcGVyZl9yZWFkX2h3KGV2ZW50LCBidWYsIGNvdW50KTsKfQoKc3RhdGljIHVuc2lnbmVkIGludCBwZXJmX3BvbGwoc3RydWN0IGZpbGUgKmZpbGUsIHBvbGxfdGFibGUgKndhaXQpCnsKCXN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCA9IGZpbGUtPnByaXZhdGVfZGF0YTsKCXN0cnVjdCBwZXJmX2J1ZmZlciAqYnVmZmVyOwoJdW5zaWduZWQgaW50IGV2ZW50cyA9IFBPTExfSFVQOwoKCXJjdV9yZWFkX2xvY2soKTsKCWJ1ZmZlciA9IHJjdV9kZXJlZmVyZW5jZShldmVudC0+YnVmZmVyKTsKCWlmIChidWZmZXIpCgkJZXZlbnRzID0gYXRvbWljX3hjaGcoJmJ1ZmZlci0+cG9sbCwgMCk7CglyY3VfcmVhZF91bmxvY2soKTsKCglwb2xsX3dhaXQoZmlsZSwgJmV2ZW50LT53YWl0cSwgd2FpdCk7CgoJcmV0dXJuIGV2ZW50czsKfQoKc3RhdGljIHZvaWQgcGVyZl9ldmVudF9yZXNldChzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQpCnsKCSh2b2lkKXBlcmZfZXZlbnRfcmVhZChldmVudCk7Cglsb2NhbDY0X3NldCgmZXZlbnQtPmNvdW50LCAwKTsKCXBlcmZfZXZlbnRfdXBkYXRlX3VzZXJwYWdlKGV2ZW50KTsKfQoKLyoKICogSG9sZGluZyB0aGUgdG9wLWxldmVsIGV2ZW50J3MgY2hpbGRfbXV0ZXggbWVhbnMgdGhhdCBhbnkKICogZGVzY2VuZGFudCBwcm9jZXNzIHRoYXQgaGFzIGluaGVyaXRlZCB0aGlzIGV2ZW50IHdpbGwgYmxvY2sKICogaW4gc3luY19jaGlsZF9ldmVudCBpZiBpdCBnb2VzIHRvIGV4aXQsIHRodXMgc2F0aXNmeWluZyB0aGUKICogdGFzayBleGlzdGVuY2UgcmVxdWlyZW1lbnRzIG9mIHBlcmZfZXZlbnRfZW5hYmxlL2Rpc2FibGUuCiAqLwpzdGF0aWMgdm9pZCBwZXJmX2V2ZW50X2Zvcl9lYWNoX2NoaWxkKHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCwKCQkJCQl2b2lkICgqZnVuYykoc3RydWN0IHBlcmZfZXZlbnQgKikpCnsKCXN0cnVjdCBwZXJmX2V2ZW50ICpjaGlsZDsKCglXQVJOX09OX09OQ0UoZXZlbnQtPmN0eC0+cGFyZW50X2N0eCk7CgltdXRleF9sb2NrKCZldmVudC0+Y2hpbGRfbXV0ZXgpOwoJZnVuYyhldmVudCk7CglsaXN0X2Zvcl9lYWNoX2VudHJ5KGNoaWxkLCAmZXZlbnQtPmNoaWxkX2xpc3QsIGNoaWxkX2xpc3QpCgkJZnVuYyhjaGlsZCk7CgltdXRleF91bmxvY2soJmV2ZW50LT5jaGlsZF9tdXRleCk7Cn0KCnN0YXRpYyB2b2lkIHBlcmZfZXZlbnRfZm9yX2VhY2goc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50LAoJCQkJICB2b2lkICgqZnVuYykoc3RydWN0IHBlcmZfZXZlbnQgKikpCnsKCXN0cnVjdCBwZXJmX2V2ZW50X2NvbnRleHQgKmN0eCA9IGV2ZW50LT5jdHg7CglzdHJ1Y3QgcGVyZl9ldmVudCAqc2libGluZzsKCglXQVJOX09OX09OQ0UoY3R4LT5wYXJlbnRfY3R4KTsKCW11dGV4X2xvY2soJmN0eC0+bXV0ZXgpOwoJZXZlbnQgPSBldmVudC0+Z3JvdXBfbGVhZGVyOwoKCXBlcmZfZXZlbnRfZm9yX2VhY2hfY2hpbGQoZXZlbnQsIGZ1bmMpOwoJZnVuYyhldmVudCk7CglsaXN0X2Zvcl9lYWNoX2VudHJ5KHNpYmxpbmcsICZldmVudC0+c2libGluZ19saXN0LCBncm91cF9lbnRyeSkKCQlwZXJmX2V2ZW50X2Zvcl9lYWNoX2NoaWxkKGV2ZW50LCBmdW5jKTsKCW11dGV4X3VubG9jaygmY3R4LT5tdXRleCk7Cn0KCnN0YXRpYyBpbnQgcGVyZl9ldmVudF9wZXJpb2Qoc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50LCB1NjQgX191c2VyICphcmcpCnsKCXN0cnVjdCBwZXJmX2V2ZW50X2NvbnRleHQgKmN0eCA9IGV2ZW50LT5jdHg7CglpbnQgcmV0ID0gMDsKCXU2NCB2YWx1ZTsKCglpZiAoIWlzX3NhbXBsaW5nX2V2ZW50KGV2ZW50KSkKCQlyZXR1cm4gLUVJTlZBTDsKCglpZiAoY29weV9mcm9tX3VzZXIoJnZhbHVlLCBhcmcsIHNpemVvZih2YWx1ZSkpKQoJCXJldHVybiAtRUZBVUxUOwoKCWlmICghdmFsdWUpCgkJcmV0dXJuIC1FSU5WQUw7CgoJcmF3X3NwaW5fbG9ja19pcnEoJmN0eC0+bG9jayk7CglpZiAoZXZlbnQtPmF0dHIuZnJlcSkgewoJCWlmICh2YWx1ZSA+IHN5c2N0bF9wZXJmX2V2ZW50X3NhbXBsZV9yYXRlKSB7CgkJCXJldCA9IC1FSU5WQUw7CgkJCWdvdG8gdW5sb2NrOwoJCX0KCgkJZXZlbnQtPmF0dHIuc2FtcGxlX2ZyZXEgPSB2YWx1ZTsKCX0gZWxzZSB7CgkJZXZlbnQtPmF0dHIuc2FtcGxlX3BlcmlvZCA9IHZhbHVlOwoJCWV2ZW50LT5ody5zYW1wbGVfcGVyaW9kID0gdmFsdWU7Cgl9CnVubG9jazoKCXJhd19zcGluX3VubG9ja19pcnEoJmN0eC0+bG9jayk7CgoJcmV0dXJuIHJldDsKfQoKc3RhdGljIGNvbnN0IHN0cnVjdCBmaWxlX29wZXJhdGlvbnMgcGVyZl9mb3BzOwoKc3RhdGljIHN0cnVjdCBwZXJmX2V2ZW50ICpwZXJmX2ZnZXRfbGlnaHQoaW50IGZkLCBpbnQgKmZwdXRfbmVlZGVkKQp7CglzdHJ1Y3QgZmlsZSAqZmlsZTsKCglmaWxlID0gZmdldF9saWdodChmZCwgZnB1dF9uZWVkZWQpOwoJaWYgKCFmaWxlKQoJCXJldHVybiBFUlJfUFRSKC1FQkFERik7CgoJaWYgKGZpbGUtPmZfb3AgIT0gJnBlcmZfZm9wcykgewoJCWZwdXRfbGlnaHQoZmlsZSwgKmZwdXRfbmVlZGVkKTsKCQkqZnB1dF9uZWVkZWQgPSAwOwoJCXJldHVybiBFUlJfUFRSKC1FQkFERik7Cgl9CgoJcmV0dXJuIGZpbGUtPnByaXZhdGVfZGF0YTsKfQoKc3RhdGljIGludCBwZXJmX2V2ZW50X3NldF9vdXRwdXQoc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50LAoJCQkJIHN0cnVjdCBwZXJmX2V2ZW50ICpvdXRwdXRfZXZlbnQpOwpzdGF0aWMgaW50IHBlcmZfZXZlbnRfc2V0X2ZpbHRlcihzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQsIHZvaWQgX191c2VyICphcmcpOwoKc3RhdGljIGxvbmcgcGVyZl9pb2N0bChzdHJ1Y3QgZmlsZSAqZmlsZSwgdW5zaWduZWQgaW50IGNtZCwgdW5zaWduZWQgbG9uZyBhcmcpCnsKCXN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCA9IGZpbGUtPnByaXZhdGVfZGF0YTsKCXZvaWQgKCpmdW5jKShzdHJ1Y3QgcGVyZl9ldmVudCAqKTsKCXUzMiBmbGFncyA9IGFyZzsKCglzd2l0Y2ggKGNtZCkgewoJY2FzZSBQRVJGX0VWRU5UX0lPQ19FTkFCTEU6CgkJZnVuYyA9IHBlcmZfZXZlbnRfZW5hYmxlOwoJCWJyZWFrOwoJY2FzZSBQRVJGX0VWRU5UX0lPQ19ESVNBQkxFOgoJCWZ1bmMgPSBwZXJmX2V2ZW50X2Rpc2FibGU7CgkJYnJlYWs7CgljYXNlIFBFUkZfRVZFTlRfSU9DX1JFU0VUOgoJCWZ1bmMgPSBwZXJmX2V2ZW50X3Jlc2V0OwoJCWJyZWFrOwoKCWNhc2UgUEVSRl9FVkVOVF9JT0NfUkVGUkVTSDoKCQlyZXR1cm4gcGVyZl9ldmVudF9yZWZyZXNoKGV2ZW50LCBhcmcpOwoKCWNhc2UgUEVSRl9FVkVOVF9JT0NfUEVSSU9EOgoJCXJldHVybiBwZXJmX2V2ZW50X3BlcmlvZChldmVudCwgKHU2NCBfX3VzZXIgKilhcmcpOwoKCWNhc2UgUEVSRl9FVkVOVF9JT0NfU0VUX09VVFBVVDoKCXsKCQlzdHJ1Y3QgcGVyZl9ldmVudCAqb3V0cHV0X2V2ZW50ID0gTlVMTDsKCQlpbnQgZnB1dF9uZWVkZWQgPSAwOwoJCWludCByZXQ7CgoJCWlmIChhcmcgIT0gLTEpIHsKCQkJb3V0cHV0X2V2ZW50ID0gcGVyZl9mZ2V0X2xpZ2h0KGFyZywgJmZwdXRfbmVlZGVkKTsKCQkJaWYgKElTX0VSUihvdXRwdXRfZXZlbnQpKQoJCQkJcmV0dXJuIFBUUl9FUlIob3V0cHV0X2V2ZW50KTsKCQl9CgoJCXJldCA9IHBlcmZfZXZlbnRfc2V0X291dHB1dChldmVudCwgb3V0cHV0X2V2ZW50KTsKCQlpZiAob3V0cHV0X2V2ZW50KQoJCQlmcHV0X2xpZ2h0KG91dHB1dF9ldmVudC0+ZmlscCwgZnB1dF9uZWVkZWQpOwoKCQlyZXR1cm4gcmV0OwoJfQoKCWNhc2UgUEVSRl9FVkVOVF9JT0NfU0VUX0ZJTFRFUjoKCQlyZXR1cm4gcGVyZl9ldmVudF9zZXRfZmlsdGVyKGV2ZW50LCAodm9pZCBfX3VzZXIgKilhcmcpOwoKCWRlZmF1bHQ6CgkJcmV0dXJuIC1FTk9UVFk7Cgl9CgoJaWYgKGZsYWdzICYgUEVSRl9JT0NfRkxBR19HUk9VUCkKCQlwZXJmX2V2ZW50X2Zvcl9lYWNoKGV2ZW50LCBmdW5jKTsKCWVsc2UKCQlwZXJmX2V2ZW50X2Zvcl9lYWNoX2NoaWxkKGV2ZW50LCBmdW5jKTsKCglyZXR1cm4gMDsKfQoKaW50IHBlcmZfZXZlbnRfdGFza19lbmFibGUodm9pZCkKewoJc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50OwoKCW11dGV4X2xvY2soJmN1cnJlbnQtPnBlcmZfZXZlbnRfbXV0ZXgpOwoJbGlzdF9mb3JfZWFjaF9lbnRyeShldmVudCwgJmN1cnJlbnQtPnBlcmZfZXZlbnRfbGlzdCwgb3duZXJfZW50cnkpCgkJcGVyZl9ldmVudF9mb3JfZWFjaF9jaGlsZChldmVudCwgcGVyZl9ldmVudF9lbmFibGUpOwoJbXV0ZXhfdW5sb2NrKCZjdXJyZW50LT5wZXJmX2V2ZW50X211dGV4KTsKCglyZXR1cm4gMDsKfQoKaW50IHBlcmZfZXZlbnRfdGFza19kaXNhYmxlKHZvaWQpCnsKCXN0cnVjdCBwZXJmX2V2ZW50ICpldmVudDsKCgltdXRleF9sb2NrKCZjdXJyZW50LT5wZXJmX2V2ZW50X211dGV4KTsKCWxpc3RfZm9yX2VhY2hfZW50cnkoZXZlbnQsICZjdXJyZW50LT5wZXJmX2V2ZW50X2xpc3QsIG93bmVyX2VudHJ5KQoJCXBlcmZfZXZlbnRfZm9yX2VhY2hfY2hpbGQoZXZlbnQsIHBlcmZfZXZlbnRfZGlzYWJsZSk7CgltdXRleF91bmxvY2soJmN1cnJlbnQtPnBlcmZfZXZlbnRfbXV0ZXgpOwoKCXJldHVybiAwOwp9CgojaWZuZGVmIFBFUkZfRVZFTlRfSU5ERVhfT0ZGU0VUCiMgZGVmaW5lIFBFUkZfRVZFTlRfSU5ERVhfT0ZGU0VUIDAKI2VuZGlmCgpzdGF0aWMgaW50IHBlcmZfZXZlbnRfaW5kZXgoc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50KQp7CglpZiAoZXZlbnQtPmh3LnN0YXRlICYgUEVSRl9IRVNfU1RPUFBFRCkKCQlyZXR1cm4gMDsKCglpZiAoZXZlbnQtPnN0YXRlICE9IFBFUkZfRVZFTlRfU1RBVEVfQUNUSVZFKQoJCXJldHVybiAwOwoKCXJldHVybiBldmVudC0+aHcuaWR4ICsgMSAtIFBFUkZfRVZFTlRfSU5ERVhfT0ZGU0VUOwp9CgovKgogKiBDYWxsZXJzIG5lZWQgdG8gZW5zdXJlIHRoZXJlIGNhbiBiZSBubyBuZXN0aW5nIG9mIHRoaXMgZnVuY3Rpb24sIG90aGVyd2lzZQogKiB0aGUgc2VxbG9jayBsb2dpYyBnb2VzIGJhZC4gV2UgY2FuIG5vdCBzZXJpYWxpemUgdGhpcyBiZWNhdXNlIHRoZSBhcmNoCiAqIGNvZGUgY2FsbHMgdGhpcyBmcm9tIE5NSSBjb250ZXh0LgogKi8Kdm9pZCBwZXJmX2V2ZW50X3VwZGF0ZV91c2VycGFnZShzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQpCnsKCXN0cnVjdCBwZXJmX2V2ZW50X21tYXBfcGFnZSAqdXNlcnBnOwoJc3RydWN0IHBlcmZfYnVmZmVyICpidWZmZXI7CgoJcmN1X3JlYWRfbG9jaygpOwoJYnVmZmVyID0gcmN1X2RlcmVmZXJlbmNlKGV2ZW50LT5idWZmZXIpOwoJaWYgKCFidWZmZXIpCgkJZ290byB1bmxvY2s7CgoJdXNlcnBnID0gYnVmZmVyLT51c2VyX3BhZ2U7CgoJLyoKCSAqIERpc2FibGUgcHJlZW1wdGlvbiBzbyBhcyB0byBub3QgbGV0IHRoZSBjb3JyZXNwb25kaW5nIHVzZXItc3BhY2UKCSAqIHNwaW4gdG9vIGxvbmcgaWYgd2UgZ2V0IHByZWVtcHRlZC4KCSAqLwoJcHJlZW1wdF9kaXNhYmxlKCk7CgkrK3VzZXJwZy0+bG9jazsKCWJhcnJpZXIoKTsKCXVzZXJwZy0+aW5kZXggPSBwZXJmX2V2ZW50X2luZGV4KGV2ZW50KTsKCXVzZXJwZy0+b2Zmc2V0ID0gcGVyZl9ldmVudF9jb3VudChldmVudCk7CglpZiAoZXZlbnQtPnN0YXRlID09IFBFUkZfRVZFTlRfU1RBVEVfQUNUSVZFKQoJCXVzZXJwZy0+b2Zmc2V0IC09IGxvY2FsNjRfcmVhZCgmZXZlbnQtPmh3LnByZXZfY291bnQpOwoKCXVzZXJwZy0+dGltZV9lbmFibGVkID0gZXZlbnQtPnRvdGFsX3RpbWVfZW5hYmxlZCArCgkJCWF0b21pYzY0X3JlYWQoJmV2ZW50LT5jaGlsZF90b3RhbF90aW1lX2VuYWJsZWQpOwoKCXVzZXJwZy0+dGltZV9ydW5uaW5nID0gZXZlbnQtPnRvdGFsX3RpbWVfcnVubmluZyArCgkJCWF0b21pYzY0X3JlYWQoJmV2ZW50LT5jaGlsZF90b3RhbF90aW1lX3J1bm5pbmcpOwoKCWJhcnJpZXIoKTsKCSsrdXNlcnBnLT5sb2NrOwoJcHJlZW1wdF9lbmFibGUoKTsKdW5sb2NrOgoJcmN1X3JlYWRfdW5sb2NrKCk7Cn0KCnN0YXRpYyB1bnNpZ25lZCBsb25nIHBlcmZfZGF0YV9zaXplKHN0cnVjdCBwZXJmX2J1ZmZlciAqYnVmZmVyKTsKCnN0YXRpYyB2b2lkCnBlcmZfYnVmZmVyX2luaXQoc3RydWN0IHBlcmZfYnVmZmVyICpidWZmZXIsIGxvbmcgd2F0ZXJtYXJrLCBpbnQgZmxhZ3MpCnsKCWxvbmcgbWF4X3NpemUgPSBwZXJmX2RhdGFfc2l6ZShidWZmZXIpOwoKCWlmICh3YXRlcm1hcmspCgkJYnVmZmVyLT53YXRlcm1hcmsgPSBtaW4obWF4X3NpemUsIHdhdGVybWFyayk7CgoJaWYgKCFidWZmZXItPndhdGVybWFyaykKCQlidWZmZXItPndhdGVybWFyayA9IG1heF9zaXplIC8gMjsKCglpZiAoZmxhZ3MgJiBQRVJGX0JVRkZFUl9XUklUQUJMRSkKCQlidWZmZXItPndyaXRhYmxlID0gMTsKCglhdG9taWNfc2V0KCZidWZmZXItPnJlZmNvdW50LCAxKTsKfQoKI2lmbmRlZiBDT05GSUdfUEVSRl9VU0VfVk1BTExPQwoKLyoKICogQmFjayBwZXJmX21tYXAoKSB3aXRoIHJlZ3VsYXIgR0ZQX0tFUk5FTC0wIHBhZ2VzLgogKi8KCnN0YXRpYyBzdHJ1Y3QgcGFnZSAqCnBlcmZfbW1hcF90b19wYWdlKHN0cnVjdCBwZXJmX2J1ZmZlciAqYnVmZmVyLCB1bnNpZ25lZCBsb25nIHBnb2ZmKQp7CglpZiAocGdvZmYgPiBidWZmZXItPm5yX3BhZ2VzKQoJCXJldHVybiBOVUxMOwoKCWlmIChwZ29mZiA9PSAwKQoJCXJldHVybiB2aXJ0X3RvX3BhZ2UoYnVmZmVyLT51c2VyX3BhZ2UpOwoKCXJldHVybiB2aXJ0X3RvX3BhZ2UoYnVmZmVyLT5kYXRhX3BhZ2VzW3Bnb2ZmIC0gMV0pOwp9CgpzdGF0aWMgdm9pZCAqcGVyZl9tbWFwX2FsbG9jX3BhZ2UoaW50IGNwdSkKewoJc3RydWN0IHBhZ2UgKnBhZ2U7CglpbnQgbm9kZTsKCglub2RlID0gKGNwdSA9PSAtMSkgPyBjcHUgOiBjcHVfdG9fbm9kZShjcHUpOwoJcGFnZSA9IGFsbG9jX3BhZ2VzX25vZGUobm9kZSwgR0ZQX0tFUk5FTCB8IF9fR0ZQX1pFUk8sIDApOwoJaWYgKCFwYWdlKQoJCXJldHVybiBOVUxMOwoKCXJldHVybiBwYWdlX2FkZHJlc3MocGFnZSk7Cn0KCnN0YXRpYyBzdHJ1Y3QgcGVyZl9idWZmZXIgKgpwZXJmX2J1ZmZlcl9hbGxvYyhpbnQgbnJfcGFnZXMsIGxvbmcgd2F0ZXJtYXJrLCBpbnQgY3B1LCBpbnQgZmxhZ3MpCnsKCXN0cnVjdCBwZXJmX2J1ZmZlciAqYnVmZmVyOwoJdW5zaWduZWQgbG9uZyBzaXplOwoJaW50IGk7CgoJc2l6ZSA9IHNpemVvZihzdHJ1Y3QgcGVyZl9idWZmZXIpOwoJc2l6ZSArPSBucl9wYWdlcyAqIHNpemVvZih2b2lkICopOwoKCWJ1ZmZlciA9IGt6YWxsb2Moc2l6ZSwgR0ZQX0tFUk5FTCk7CglpZiAoIWJ1ZmZlcikKCQlnb3RvIGZhaWw7CgoJYnVmZmVyLT51c2VyX3BhZ2UgPSBwZXJmX21tYXBfYWxsb2NfcGFnZShjcHUpOwoJaWYgKCFidWZmZXItPnVzZXJfcGFnZSkKCQlnb3RvIGZhaWxfdXNlcl9wYWdlOwoKCWZvciAoaSA9IDA7IGkgPCBucl9wYWdlczsgaSsrKSB7CgkJYnVmZmVyLT5kYXRhX3BhZ2VzW2ldID0gcGVyZl9tbWFwX2FsbG9jX3BhZ2UoY3B1KTsKCQlpZiAoIWJ1ZmZlci0+ZGF0YV9wYWdlc1tpXSkKCQkJZ290byBmYWlsX2RhdGFfcGFnZXM7Cgl9CgoJYnVmZmVyLT5ucl9wYWdlcyA9IG5yX3BhZ2VzOwoKCXBlcmZfYnVmZmVyX2luaXQoYnVmZmVyLCB3YXRlcm1hcmssIGZsYWdzKTsKCglyZXR1cm4gYnVmZmVyOwoKZmFpbF9kYXRhX3BhZ2VzOgoJZm9yIChpLS07IGkgPj0gMDsgaS0tKQoJCWZyZWVfcGFnZSgodW5zaWduZWQgbG9uZylidWZmZXItPmRhdGFfcGFnZXNbaV0pOwoKCWZyZWVfcGFnZSgodW5zaWduZWQgbG9uZylidWZmZXItPnVzZXJfcGFnZSk7CgpmYWlsX3VzZXJfcGFnZToKCWtmcmVlKGJ1ZmZlcik7CgpmYWlsOgoJcmV0dXJuIE5VTEw7Cn0KCnN0YXRpYyB2b2lkIHBlcmZfbW1hcF9mcmVlX3BhZ2UodW5zaWduZWQgbG9uZyBhZGRyKQp7CglzdHJ1Y3QgcGFnZSAqcGFnZSA9IHZpcnRfdG9fcGFnZSgodm9pZCAqKWFkZHIpOwoKCXBhZ2UtPm1hcHBpbmcgPSBOVUxMOwoJX19mcmVlX3BhZ2UocGFnZSk7Cn0KCnN0YXRpYyB2b2lkIHBlcmZfYnVmZmVyX2ZyZWUoc3RydWN0IHBlcmZfYnVmZmVyICpidWZmZXIpCnsKCWludCBpOwoKCXBlcmZfbW1hcF9mcmVlX3BhZ2UoKHVuc2lnbmVkIGxvbmcpYnVmZmVyLT51c2VyX3BhZ2UpOwoJZm9yIChpID0gMDsgaSA8IGJ1ZmZlci0+bnJfcGFnZXM7IGkrKykKCQlwZXJmX21tYXBfZnJlZV9wYWdlKCh1bnNpZ25lZCBsb25nKWJ1ZmZlci0+ZGF0YV9wYWdlc1tpXSk7CglrZnJlZShidWZmZXIpOwp9CgpzdGF0aWMgaW5saW5lIGludCBwYWdlX29yZGVyKHN0cnVjdCBwZXJmX2J1ZmZlciAqYnVmZmVyKQp7CglyZXR1cm4gMDsKfQoKI2Vsc2UKCi8qCiAqIEJhY2sgcGVyZl9tbWFwKCkgd2l0aCB2bWFsbG9jIG1lbW9yeS4KICoKICogUmVxdWlyZWQgZm9yIGFyY2hpdGVjdHVyZXMgdGhhdCBoYXZlIGQtY2FjaGUgYWxpYXNpbmcgaXNzdWVzLgogKi8KCnN0YXRpYyBpbmxpbmUgaW50IHBhZ2Vfb3JkZXIoc3RydWN0IHBlcmZfYnVmZmVyICpidWZmZXIpCnsKCXJldHVybiBidWZmZXItPnBhZ2Vfb3JkZXI7Cn0KCnN0YXRpYyBzdHJ1Y3QgcGFnZSAqCnBlcmZfbW1hcF90b19wYWdlKHN0cnVjdCBwZXJmX2J1ZmZlciAqYnVmZmVyLCB1bnNpZ25lZCBsb25nIHBnb2ZmKQp7CglpZiAocGdvZmYgPiAoMVVMIDw8IHBhZ2Vfb3JkZXIoYnVmZmVyKSkpCgkJcmV0dXJuIE5VTEw7CgoJcmV0dXJuIHZtYWxsb2NfdG9fcGFnZSgodm9pZCAqKWJ1ZmZlci0+dXNlcl9wYWdlICsgcGdvZmYgKiBQQUdFX1NJWkUpOwp9CgpzdGF0aWMgdm9pZCBwZXJmX21tYXBfdW5tYXJrX3BhZ2Uodm9pZCAqYWRkcikKewoJc3RydWN0IHBhZ2UgKnBhZ2UgPSB2bWFsbG9jX3RvX3BhZ2UoYWRkcik7CgoJcGFnZS0+bWFwcGluZyA9IE5VTEw7Cn0KCnN0YXRpYyB2b2lkIHBlcmZfYnVmZmVyX2ZyZWVfd29yayhzdHJ1Y3Qgd29ya19zdHJ1Y3QgKndvcmspCnsKCXN0cnVjdCBwZXJmX2J1ZmZlciAqYnVmZmVyOwoJdm9pZCAqYmFzZTsKCWludCBpLCBucjsKCglidWZmZXIgPSBjb250YWluZXJfb2Yod29yaywgc3RydWN0IHBlcmZfYnVmZmVyLCB3b3JrKTsKCW5yID0gMSA8PCBwYWdlX29yZGVyKGJ1ZmZlcik7CgoJYmFzZSA9IGJ1ZmZlci0+dXNlcl9wYWdlOwoJZm9yIChpID0gMDsgaSA8IG5yICsgMTsgaSsrKQoJCXBlcmZfbW1hcF91bm1hcmtfcGFnZShiYXNlICsgKGkgKiBQQUdFX1NJWkUpKTsKCgl2ZnJlZShiYXNlKTsKCWtmcmVlKGJ1ZmZlcik7Cn0KCnN0YXRpYyB2b2lkIHBlcmZfYnVmZmVyX2ZyZWUoc3RydWN0IHBlcmZfYnVmZmVyICpidWZmZXIpCnsKCXNjaGVkdWxlX3dvcmsoJmJ1ZmZlci0+d29yayk7Cn0KCnN0YXRpYyBzdHJ1Y3QgcGVyZl9idWZmZXIgKgpwZXJmX2J1ZmZlcl9hbGxvYyhpbnQgbnJfcGFnZXMsIGxvbmcgd2F0ZXJtYXJrLCBpbnQgY3B1LCBpbnQgZmxhZ3MpCnsKCXN0cnVjdCBwZXJmX2J1ZmZlciAqYnVmZmVyOwoJdW5zaWduZWQgbG9uZyBzaXplOwoJdm9pZCAqYWxsX2J1ZjsKCglzaXplID0gc2l6ZW9mKHN0cnVjdCBwZXJmX2J1ZmZlcik7CglzaXplICs9IHNpemVvZih2b2lkICopOwoKCWJ1ZmZlciA9IGt6YWxsb2Moc2l6ZSwgR0ZQX0tFUk5FTCk7CglpZiAoIWJ1ZmZlcikKCQlnb3RvIGZhaWw7CgoJSU5JVF9XT1JLKCZidWZmZXItPndvcmssIHBlcmZfYnVmZmVyX2ZyZWVfd29yayk7CgoJYWxsX2J1ZiA9IHZtYWxsb2NfdXNlcigobnJfcGFnZXMgKyAxKSAqIFBBR0VfU0laRSk7CglpZiAoIWFsbF9idWYpCgkJZ290byBmYWlsX2FsbF9idWY7CgoJYnVmZmVyLT51c2VyX3BhZ2UgPSBhbGxfYnVmOwoJYnVmZmVyLT5kYXRhX3BhZ2VzWzBdID0gYWxsX2J1ZiArIFBBR0VfU0laRTsKCWJ1ZmZlci0+cGFnZV9vcmRlciA9IGlsb2cyKG5yX3BhZ2VzKTsKCWJ1ZmZlci0+bnJfcGFnZXMgPSAxOwoKCXBlcmZfYnVmZmVyX2luaXQoYnVmZmVyLCB3YXRlcm1hcmssIGZsYWdzKTsKCglyZXR1cm4gYnVmZmVyOwoKZmFpbF9hbGxfYnVmOgoJa2ZyZWUoYnVmZmVyKTsKCmZhaWw6CglyZXR1cm4gTlVMTDsKfQoKI2VuZGlmCgpzdGF0aWMgdW5zaWduZWQgbG9uZyBwZXJmX2RhdGFfc2l6ZShzdHJ1Y3QgcGVyZl9idWZmZXIgKmJ1ZmZlcikKewoJcmV0dXJuIGJ1ZmZlci0+bnJfcGFnZXMgPDwgKFBBR0VfU0hJRlQgKyBwYWdlX29yZGVyKGJ1ZmZlcikpOwp9CgpzdGF0aWMgaW50IHBlcmZfbW1hcF9mYXVsdChzdHJ1Y3Qgdm1fYXJlYV9zdHJ1Y3QgKnZtYSwgc3RydWN0IHZtX2ZhdWx0ICp2bWYpCnsKCXN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCA9IHZtYS0+dm1fZmlsZS0+cHJpdmF0ZV9kYXRhOwoJc3RydWN0IHBlcmZfYnVmZmVyICpidWZmZXI7CglpbnQgcmV0ID0gVk1fRkFVTFRfU0lHQlVTOwoKCWlmICh2bWYtPmZsYWdzICYgRkFVTFRfRkxBR19NS1dSSVRFKSB7CgkJaWYgKHZtZi0+cGdvZmYgPT0gMCkKCQkJcmV0ID0gMDsKCQlyZXR1cm4gcmV0OwoJfQoKCXJjdV9yZWFkX2xvY2soKTsKCWJ1ZmZlciA9IHJjdV9kZXJlZmVyZW5jZShldmVudC0+YnVmZmVyKTsKCWlmICghYnVmZmVyKQoJCWdvdG8gdW5sb2NrOwoKCWlmICh2bWYtPnBnb2ZmICYmICh2bWYtPmZsYWdzICYgRkFVTFRfRkxBR19XUklURSkpCgkJZ290byB1bmxvY2s7CgoJdm1mLT5wYWdlID0gcGVyZl9tbWFwX3RvX3BhZ2UoYnVmZmVyLCB2bWYtPnBnb2ZmKTsKCWlmICghdm1mLT5wYWdlKQoJCWdvdG8gdW5sb2NrOwoKCWdldF9wYWdlKHZtZi0+cGFnZSk7Cgl2bWYtPnBhZ2UtPm1hcHBpbmcgPSB2bWEtPnZtX2ZpbGUtPmZfbWFwcGluZzsKCXZtZi0+cGFnZS0+aW5kZXggICA9IHZtZi0+cGdvZmY7CgoJcmV0ID0gMDsKdW5sb2NrOgoJcmN1X3JlYWRfdW5sb2NrKCk7CgoJcmV0dXJuIHJldDsKfQoKc3RhdGljIHZvaWQgcGVyZl9idWZmZXJfZnJlZV9yY3Uoc3RydWN0IHJjdV9oZWFkICpyY3VfaGVhZCkKewoJc3RydWN0IHBlcmZfYnVmZmVyICpidWZmZXI7CgoJYnVmZmVyID0gY29udGFpbmVyX29mKHJjdV9oZWFkLCBzdHJ1Y3QgcGVyZl9idWZmZXIsIHJjdV9oZWFkKTsKCXBlcmZfYnVmZmVyX2ZyZWUoYnVmZmVyKTsKfQoKc3RhdGljIHN0cnVjdCBwZXJmX2J1ZmZlciAqcGVyZl9idWZmZXJfZ2V0KHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCkKewoJc3RydWN0IHBlcmZfYnVmZmVyICpidWZmZXI7CgoJcmN1X3JlYWRfbG9jaygpOwoJYnVmZmVyID0gcmN1X2RlcmVmZXJlbmNlKGV2ZW50LT5idWZmZXIpOwoJaWYgKGJ1ZmZlcikgewoJCWlmICghYXRvbWljX2luY19ub3RfemVybygmYnVmZmVyLT5yZWZjb3VudCkpCgkJCWJ1ZmZlciA9IE5VTEw7Cgl9CglyY3VfcmVhZF91bmxvY2soKTsKCglyZXR1cm4gYnVmZmVyOwp9CgpzdGF0aWMgdm9pZCBwZXJmX2J1ZmZlcl9wdXQoc3RydWN0IHBlcmZfYnVmZmVyICpidWZmZXIpCnsKCWlmICghYXRvbWljX2RlY19hbmRfdGVzdCgmYnVmZmVyLT5yZWZjb3VudCkpCgkJcmV0dXJuOwoKCWNhbGxfcmN1KCZidWZmZXItPnJjdV9oZWFkLCBwZXJmX2J1ZmZlcl9mcmVlX3JjdSk7Cn0KCnN0YXRpYyB2b2lkIHBlcmZfbW1hcF9vcGVuKHN0cnVjdCB2bV9hcmVhX3N0cnVjdCAqdm1hKQp7CglzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQgPSB2bWEtPnZtX2ZpbGUtPnByaXZhdGVfZGF0YTsKCglhdG9taWNfaW5jKCZldmVudC0+bW1hcF9jb3VudCk7Cn0KCnN0YXRpYyB2b2lkIHBlcmZfbW1hcF9jbG9zZShzdHJ1Y3Qgdm1fYXJlYV9zdHJ1Y3QgKnZtYSkKewoJc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50ID0gdm1hLT52bV9maWxlLT5wcml2YXRlX2RhdGE7CgoJaWYgKGF0b21pY19kZWNfYW5kX211dGV4X2xvY2soJmV2ZW50LT5tbWFwX2NvdW50LCAmZXZlbnQtPm1tYXBfbXV0ZXgpKSB7CgkJdW5zaWduZWQgbG9uZyBzaXplID0gcGVyZl9kYXRhX3NpemUoZXZlbnQtPmJ1ZmZlcik7CgkJc3RydWN0IHVzZXJfc3RydWN0ICp1c2VyID0gZXZlbnQtPm1tYXBfdXNlcjsKCQlzdHJ1Y3QgcGVyZl9idWZmZXIgKmJ1ZmZlciA9IGV2ZW50LT5idWZmZXI7CgoJCWF0b21pY19sb25nX3N1Yigoc2l6ZSA+PiBQQUdFX1NISUZUKSArIDEsICZ1c2VyLT5sb2NrZWRfdm0pOwoJCXZtYS0+dm1fbW0tPmxvY2tlZF92bSAtPSBldmVudC0+bW1hcF9sb2NrZWQ7CgkJcmN1X2Fzc2lnbl9wb2ludGVyKGV2ZW50LT5idWZmZXIsIE5VTEwpOwoJCW11dGV4X3VubG9jaygmZXZlbnQtPm1tYXBfbXV0ZXgpOwoKCQlwZXJmX2J1ZmZlcl9wdXQoYnVmZmVyKTsKCQlmcmVlX3VpZCh1c2VyKTsKCX0KfQoKc3RhdGljIGNvbnN0IHN0cnVjdCB2bV9vcGVyYXRpb25zX3N0cnVjdCBwZXJmX21tYXBfdm1vcHMgPSB7Cgkub3BlbgkJPSBwZXJmX21tYXBfb3BlbiwKCS5jbG9zZQkJPSBwZXJmX21tYXBfY2xvc2UsCgkuZmF1bHQJCT0gcGVyZl9tbWFwX2ZhdWx0LAoJLnBhZ2VfbWt3cml0ZQk9IHBlcmZfbW1hcF9mYXVsdCwKfTsKCnN0YXRpYyBpbnQgcGVyZl9tbWFwKHN0cnVjdCBmaWxlICpmaWxlLCBzdHJ1Y3Qgdm1fYXJlYV9zdHJ1Y3QgKnZtYSkKewoJc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50ID0gZmlsZS0+cHJpdmF0ZV9kYXRhOwoJdW5zaWduZWQgbG9uZyB1c2VyX2xvY2tlZCwgdXNlcl9sb2NrX2xpbWl0OwoJc3RydWN0IHVzZXJfc3RydWN0ICp1c2VyID0gY3VycmVudF91c2VyKCk7Cgl1bnNpZ25lZCBsb25nIGxvY2tlZCwgbG9ja19saW1pdDsKCXN0cnVjdCBwZXJmX2J1ZmZlciAqYnVmZmVyOwoJdW5zaWduZWQgbG9uZyB2bWFfc2l6ZTsKCXVuc2lnbmVkIGxvbmcgbnJfcGFnZXM7Cglsb25nIHVzZXJfZXh0cmEsIGV4dHJhOwoJaW50IHJldCA9IDAsIGZsYWdzID0gMDsKCgkvKgoJICogRG9uJ3QgYWxsb3cgbW1hcCgpIG9mIGluaGVyaXRlZCBwZXItdGFzayBjb3VudGVycy4gVGhpcyB3b3VsZAoJICogY3JlYXRlIGEgcGVyZm9ybWFuY2UgaXNzdWUgZHVlIHRvIGFsbCBjaGlsZHJlbiB3cml0aW5nIHRvIHRoZQoJICogc2FtZSBidWZmZXIuCgkgKi8KCWlmIChldmVudC0+Y3B1ID09IC0xICYmIGV2ZW50LT5hdHRyLmluaGVyaXQpCgkJcmV0dXJuIC1FSU5WQUw7CgoJaWYgKCEodm1hLT52bV9mbGFncyAmIFZNX1NIQVJFRCkpCgkJcmV0dXJuIC1FSU5WQUw7CgoJdm1hX3NpemUgPSB2bWEtPnZtX2VuZCAtIHZtYS0+dm1fc3RhcnQ7Cglucl9wYWdlcyA9ICh2bWFfc2l6ZSAvIFBBR0VfU0laRSkgLSAxOwoKCS8qCgkgKiBJZiB3ZSBoYXZlIGJ1ZmZlciBwYWdlcyBlbnN1cmUgdGhleSdyZSBhIHBvd2VyLW9mLXR3byBudW1iZXIsIHNvIHdlCgkgKiBjYW4gZG8gYml0bWFza3MgaW5zdGVhZCBvZiBtb2R1bG8uCgkgKi8KCWlmIChucl9wYWdlcyAhPSAwICYmICFpc19wb3dlcl9vZl8yKG5yX3BhZ2VzKSkKCQlyZXR1cm4gLUVJTlZBTDsKCglpZiAodm1hX3NpemUgIT0gUEFHRV9TSVpFICogKDEgKyBucl9wYWdlcykpCgkJcmV0dXJuIC1FSU5WQUw7CgoJaWYgKHZtYS0+dm1fcGdvZmYgIT0gMCkKCQlyZXR1cm4gLUVJTlZBTDsKCglXQVJOX09OX09OQ0UoZXZlbnQtPmN0eC0+cGFyZW50X2N0eCk7CgltdXRleF9sb2NrKCZldmVudC0+bW1hcF9tdXRleCk7CglpZiAoZXZlbnQtPmJ1ZmZlcikgewoJCWlmIChldmVudC0+YnVmZmVyLT5ucl9wYWdlcyA9PSBucl9wYWdlcykKCQkJYXRvbWljX2luYygmZXZlbnQtPmJ1ZmZlci0+cmVmY291bnQpOwoJCWVsc2UKCQkJcmV0ID0gLUVJTlZBTDsKCQlnb3RvIHVubG9jazsKCX0KCgl1c2VyX2V4dHJhID0gbnJfcGFnZXMgKyAxOwoJdXNlcl9sb2NrX2xpbWl0ID0gc3lzY3RsX3BlcmZfZXZlbnRfbWxvY2sgPj4gKFBBR0VfU0hJRlQgLSAxMCk7CgoJLyoKCSAqIEluY3JlYXNlIHRoZSBsaW1pdCBsaW5lYXJseSB3aXRoIG1vcmUgQ1BVczoKCSAqLwoJdXNlcl9sb2NrX2xpbWl0ICo9IG51bV9vbmxpbmVfY3B1cygpOwoKCXVzZXJfbG9ja2VkID0gYXRvbWljX2xvbmdfcmVhZCgmdXNlci0+bG9ja2VkX3ZtKSArIHVzZXJfZXh0cmE7CgoJZXh0cmEgPSAwOwoJaWYgKHVzZXJfbG9ja2VkID4gdXNlcl9sb2NrX2xpbWl0KQoJCWV4dHJhID0gdXNlcl9sb2NrZWQgLSB1c2VyX2xvY2tfbGltaXQ7CgoJbG9ja19saW1pdCA9IHJsaW1pdChSTElNSVRfTUVNTE9DSyk7Cglsb2NrX2xpbWl0ID4+PSBQQUdFX1NISUZUOwoJbG9ja2VkID0gdm1hLT52bV9tbS0+bG9ja2VkX3ZtICsgZXh0cmE7CgoJaWYgKChsb2NrZWQgPiBsb2NrX2xpbWl0KSAmJiBwZXJmX3BhcmFub2lkX3RyYWNlcG9pbnRfcmF3KCkgJiYKCQkhY2FwYWJsZShDQVBfSVBDX0xPQ0spKSB7CgkJcmV0ID0gLUVQRVJNOwoJCWdvdG8gdW5sb2NrOwoJfQoKCVdBUk5fT04oZXZlbnQtPmJ1ZmZlcik7CgoJaWYgKHZtYS0+dm1fZmxhZ3MgJiBWTV9XUklURSkKCQlmbGFncyB8PSBQRVJGX0JVRkZFUl9XUklUQUJMRTsKCglidWZmZXIgPSBwZXJmX2J1ZmZlcl9hbGxvYyhucl9wYWdlcywgZXZlbnQtPmF0dHIud2FrZXVwX3dhdGVybWFyaywKCQkJCSAgIGV2ZW50LT5jcHUsIGZsYWdzKTsKCWlmICghYnVmZmVyKSB7CgkJcmV0ID0gLUVOT01FTTsKCQlnb3RvIHVubG9jazsKCX0KCXJjdV9hc3NpZ25fcG9pbnRlcihldmVudC0+YnVmZmVyLCBidWZmZXIpOwoKCWF0b21pY19sb25nX2FkZCh1c2VyX2V4dHJhLCAmdXNlci0+bG9ja2VkX3ZtKTsKCWV2ZW50LT5tbWFwX2xvY2tlZCA9IGV4dHJhOwoJZXZlbnQtPm1tYXBfdXNlciA9IGdldF9jdXJyZW50X3VzZXIoKTsKCXZtYS0+dm1fbW0tPmxvY2tlZF92bSArPSBldmVudC0+bW1hcF9sb2NrZWQ7Cgp1bmxvY2s6CglpZiAoIXJldCkKCQlhdG9taWNfaW5jKCZldmVudC0+bW1hcF9jb3VudCk7CgltdXRleF91bmxvY2soJmV2ZW50LT5tbWFwX211dGV4KTsKCgl2bWEtPnZtX2ZsYWdzIHw9IFZNX1JFU0VSVkVEOwoJdm1hLT52bV9vcHMgPSAmcGVyZl9tbWFwX3Ztb3BzOwoKCXJldHVybiByZXQ7Cn0KCnN0YXRpYyBpbnQgcGVyZl9mYXN5bmMoaW50IGZkLCBzdHJ1Y3QgZmlsZSAqZmlscCwgaW50IG9uKQp7CglzdHJ1Y3QgaW5vZGUgKmlub2RlID0gZmlscC0+Zl9wYXRoLmRlbnRyeS0+ZF9pbm9kZTsKCXN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCA9IGZpbHAtPnByaXZhdGVfZGF0YTsKCWludCByZXR2YWw7CgoJbXV0ZXhfbG9jaygmaW5vZGUtPmlfbXV0ZXgpOwoJcmV0dmFsID0gZmFzeW5jX2hlbHBlcihmZCwgZmlscCwgb24sICZldmVudC0+ZmFzeW5jKTsKCW11dGV4X3VubG9jaygmaW5vZGUtPmlfbXV0ZXgpOwoKCWlmIChyZXR2YWwgPCAwKQoJCXJldHVybiByZXR2YWw7CgoJcmV0dXJuIDA7Cn0KCnN0YXRpYyBjb25zdCBzdHJ1Y3QgZmlsZV9vcGVyYXRpb25zIHBlcmZfZm9wcyA9IHsKCS5sbHNlZWsJCQk9IG5vX2xsc2VlaywKCS5yZWxlYXNlCQk9IHBlcmZfcmVsZWFzZSwKCS5yZWFkCQkJPSBwZXJmX3JlYWQsCgkucG9sbAkJCT0gcGVyZl9wb2xsLAoJLnVubG9ja2VkX2lvY3RsCQk9IHBlcmZfaW9jdGwsCgkuY29tcGF0X2lvY3RsCQk9IHBlcmZfaW9jdGwsCgkubW1hcAkJCT0gcGVyZl9tbWFwLAoJLmZhc3luYwkJCT0gcGVyZl9mYXN5bmMsCn07CgovKgogKiBQZXJmIGV2ZW50IHdha2V1cAogKgogKiBJZiB0aGVyZSdzIGRhdGEsIGVuc3VyZSB3ZSBzZXQgdGhlIHBvbGwoKSBzdGF0ZSBhbmQgcHVibGlzaCBldmVyeXRoaW5nCiAqIHRvIHVzZXItc3BhY2UgYmVmb3JlIHdha2luZyBldmVyeWJvZHkgdXAuCiAqLwoKdm9pZCBwZXJmX2V2ZW50X3dha2V1cChzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQpCnsKCXdha2VfdXBfYWxsKCZldmVudC0+d2FpdHEpOwoKCWlmIChldmVudC0+cGVuZGluZ19raWxsKSB7CgkJa2lsbF9mYXN5bmMoJmV2ZW50LT5mYXN5bmMsIFNJR0lPLCBldmVudC0+cGVuZGluZ19raWxsKTsKCQlldmVudC0+cGVuZGluZ19raWxsID0gMDsKCX0KfQoKc3RhdGljIHZvaWQgcGVyZl9wZW5kaW5nX2V2ZW50KHN0cnVjdCBpcnFfd29yayAqZW50cnkpCnsKCXN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCA9IGNvbnRhaW5lcl9vZihlbnRyeSwKCQkJc3RydWN0IHBlcmZfZXZlbnQsIHBlbmRpbmcpOwoKCWlmIChldmVudC0+cGVuZGluZ19kaXNhYmxlKSB7CgkJZXZlbnQtPnBlbmRpbmdfZGlzYWJsZSA9IDA7CgkJX19wZXJmX2V2ZW50X2Rpc2FibGUoZXZlbnQpOwoJfQoKCWlmIChldmVudC0+cGVuZGluZ193YWtldXApIHsKCQlldmVudC0+cGVuZGluZ193YWtldXAgPSAwOwoJCXBlcmZfZXZlbnRfd2FrZXVwKGV2ZW50KTsKCX0KfQoKLyoKICogV2UgYXNzdW1lIHRoZXJlIGlzIG9ubHkgS1ZNIHN1cHBvcnRpbmcgdGhlIGNhbGxiYWNrcy4KICogTGF0ZXIgb24sIHdlIG1pZ2h0IGNoYW5nZSBpdCB0byBhIGxpc3QgaWYgdGhlcmUgaXMKICogYW5vdGhlciB2aXJ0dWFsaXphdGlvbiBpbXBsZW1lbnRhdGlvbiBzdXBwb3J0aW5nIHRoZSBjYWxsYmFja3MuCiAqLwpzdHJ1Y3QgcGVyZl9ndWVzdF9pbmZvX2NhbGxiYWNrcyAqcGVyZl9ndWVzdF9jYnM7CgppbnQgcGVyZl9yZWdpc3Rlcl9ndWVzdF9pbmZvX2NhbGxiYWNrcyhzdHJ1Y3QgcGVyZl9ndWVzdF9pbmZvX2NhbGxiYWNrcyAqY2JzKQp7CglwZXJmX2d1ZXN0X2NicyA9IGNiczsKCXJldHVybiAwOwp9CkVYUE9SVF9TWU1CT0xfR1BMKHBlcmZfcmVnaXN0ZXJfZ3Vlc3RfaW5mb19jYWxsYmFja3MpOwoKaW50IHBlcmZfdW5yZWdpc3Rlcl9ndWVzdF9pbmZvX2NhbGxiYWNrcyhzdHJ1Y3QgcGVyZl9ndWVzdF9pbmZvX2NhbGxiYWNrcyAqY2JzKQp7CglwZXJmX2d1ZXN0X2NicyA9IE5VTEw7CglyZXR1cm4gMDsKfQpFWFBPUlRfU1lNQk9MX0dQTChwZXJmX3VucmVnaXN0ZXJfZ3Vlc3RfaW5mb19jYWxsYmFja3MpOwoKLyoKICogT3V0cHV0CiAqLwpzdGF0aWMgYm9vbCBwZXJmX291dHB1dF9zcGFjZShzdHJ1Y3QgcGVyZl9idWZmZXIgKmJ1ZmZlciwgdW5zaWduZWQgbG9uZyB0YWlsLAoJCQkgICAgICB1bnNpZ25lZCBsb25nIG9mZnNldCwgdW5zaWduZWQgbG9uZyBoZWFkKQp7Cgl1bnNpZ25lZCBsb25nIG1hc2s7CgoJaWYgKCFidWZmZXItPndyaXRhYmxlKQoJCXJldHVybiB0cnVlOwoKCW1hc2sgPSBwZXJmX2RhdGFfc2l6ZShidWZmZXIpIC0gMTsKCglvZmZzZXQgPSAob2Zmc2V0IC0gdGFpbCkgJiBtYXNrOwoJaGVhZCAgID0gKGhlYWQgICAtIHRhaWwpICYgbWFzazsKCglpZiAoKGludCkoaGVhZCAtIG9mZnNldCkgPCAwKQoJCXJldHVybiBmYWxzZTsKCglyZXR1cm4gdHJ1ZTsKfQoKc3RhdGljIHZvaWQgcGVyZl9vdXRwdXRfd2FrZXVwKHN0cnVjdCBwZXJmX291dHB1dF9oYW5kbGUgKmhhbmRsZSkKewoJYXRvbWljX3NldCgmaGFuZGxlLT5idWZmZXItPnBvbGwsIFBPTExfSU4pOwoKCWlmIChoYW5kbGUtPm5taSkgewoJCWhhbmRsZS0+ZXZlbnQtPnBlbmRpbmdfd2FrZXVwID0gMTsKCQlpcnFfd29ya19xdWV1ZSgmaGFuZGxlLT5ldmVudC0+cGVuZGluZyk7Cgl9IGVsc2UKCQlwZXJmX2V2ZW50X3dha2V1cChoYW5kbGUtPmV2ZW50KTsKfQoKLyoKICogV2UgbmVlZCB0byBlbnN1cmUgYSBsYXRlciBldmVudF9pZCBkb2Vzbid0IHB1Ymxpc2ggYSBoZWFkIHdoZW4gYSBmb3JtZXIKICogZXZlbnQgaXNuJ3QgZG9uZSB3cml0aW5nLiBIb3dldmVyIHNpbmNlIHdlIG5lZWQgdG8gZGVhbCB3aXRoIE5NSXMgd2UKICogY2Fubm90IGZ1bGx5IHNlcmlhbGl6ZSB0aGluZ3MuCiAqCiAqIFdlIG9ubHkgcHVibGlzaCB0aGUgaGVhZCAoYW5kIGdlbmVyYXRlIGEgd2FrZXVwKSB3aGVuIHRoZSBvdXRlci1tb3N0CiAqIGV2ZW50IGNvbXBsZXRlcy4KICovCnN0YXRpYyB2b2lkIHBlcmZfb3V0cHV0X2dldF9oYW5kbGUoc3RydWN0IHBlcmZfb3V0cHV0X2hhbmRsZSAqaGFuZGxlKQp7CglzdHJ1Y3QgcGVyZl9idWZmZXIgKmJ1ZmZlciA9IGhhbmRsZS0+YnVmZmVyOwoKCXByZWVtcHRfZGlzYWJsZSgpOwoJbG9jYWxfaW5jKCZidWZmZXItPm5lc3QpOwoJaGFuZGxlLT53YWtldXAgPSBsb2NhbF9yZWFkKCZidWZmZXItPndha2V1cCk7Cn0KCnN0YXRpYyB2b2lkIHBlcmZfb3V0cHV0X3B1dF9oYW5kbGUoc3RydWN0IHBlcmZfb3V0cHV0X2hhbmRsZSAqaGFuZGxlKQp7CglzdHJ1Y3QgcGVyZl9idWZmZXIgKmJ1ZmZlciA9IGhhbmRsZS0+YnVmZmVyOwoJdW5zaWduZWQgbG9uZyBoZWFkOwoKYWdhaW46CgloZWFkID0gbG9jYWxfcmVhZCgmYnVmZmVyLT5oZWFkKTsKCgkvKgoJICogSVJRL05NSSBjYW4gaGFwcGVuIGhlcmUsIHdoaWNoIG1lYW5zIHdlIGNhbiBtaXNzIGEgaGVhZCB1cGRhdGUuCgkgKi8KCglpZiAoIWxvY2FsX2RlY19hbmRfdGVzdCgmYnVmZmVyLT5uZXN0KSkKCQlnb3RvIG91dDsKCgkvKgoJICogUHVibGlzaCB0aGUga25vd24gZ29vZCBoZWFkLiBSZWx5IG9uIHRoZSBmdWxsIGJhcnJpZXIgaW1wbGllZAoJICogYnkgYXRvbWljX2RlY19hbmRfdGVzdCgpIG9yZGVyIHRoZSBidWZmZXItPmhlYWQgcmVhZCBhbmQgdGhpcwoJICogd3JpdGUuCgkgKi8KCWJ1ZmZlci0+dXNlcl9wYWdlLT5kYXRhX2hlYWQgPSBoZWFkOwoKCS8qCgkgKiBOb3cgY2hlY2sgaWYgd2UgbWlzc2VkIGFuIHVwZGF0ZSwgcmVseSBvbiB0aGUgKGNvbXBpbGVyKQoJICogYmFycmllciBpbiBhdG9taWNfZGVjX2FuZF90ZXN0KCkgdG8gcmUtcmVhZCBidWZmZXItPmhlYWQuCgkgKi8KCWlmICh1bmxpa2VseShoZWFkICE9IGxvY2FsX3JlYWQoJmJ1ZmZlci0+aGVhZCkpKSB7CgkJbG9jYWxfaW5jKCZidWZmZXItPm5lc3QpOwoJCWdvdG8gYWdhaW47Cgl9CgoJaWYgKGhhbmRsZS0+d2FrZXVwICE9IGxvY2FsX3JlYWQoJmJ1ZmZlci0+d2FrZXVwKSkKCQlwZXJmX291dHB1dF93YWtldXAoaGFuZGxlKTsKCm91dDoKCXByZWVtcHRfZW5hYmxlKCk7Cn0KCl9fYWx3YXlzX2lubGluZSB2b2lkIHBlcmZfb3V0cHV0X2NvcHkoc3RydWN0IHBlcmZfb3V0cHV0X2hhbmRsZSAqaGFuZGxlLAoJCSAgICAgIGNvbnN0IHZvaWQgKmJ1ZiwgdW5zaWduZWQgaW50IGxlbikKewoJZG8gewoJCXVuc2lnbmVkIGxvbmcgc2l6ZSA9IG1pbl90KHVuc2lnbmVkIGxvbmcsIGhhbmRsZS0+c2l6ZSwgbGVuKTsKCgkJbWVtY3B5KGhhbmRsZS0+YWRkciwgYnVmLCBzaXplKTsKCgkJbGVuIC09IHNpemU7CgkJaGFuZGxlLT5hZGRyICs9IHNpemU7CgkJYnVmICs9IHNpemU7CgkJaGFuZGxlLT5zaXplIC09IHNpemU7CgkJaWYgKCFoYW5kbGUtPnNpemUpIHsKCQkJc3RydWN0IHBlcmZfYnVmZmVyICpidWZmZXIgPSBoYW5kbGUtPmJ1ZmZlcjsKCgkJCWhhbmRsZS0+cGFnZSsrOwoJCQloYW5kbGUtPnBhZ2UgJj0gYnVmZmVyLT5ucl9wYWdlcyAtIDE7CgkJCWhhbmRsZS0+YWRkciA9IGJ1ZmZlci0+ZGF0YV9wYWdlc1toYW5kbGUtPnBhZ2VdOwoJCQloYW5kbGUtPnNpemUgPSBQQUdFX1NJWkUgPDwgcGFnZV9vcmRlcihidWZmZXIpOwoJCX0KCX0gd2hpbGUgKGxlbik7Cn0KCnN0YXRpYyB2b2lkIF9fcGVyZl9ldmVudF9oZWFkZXJfX2luaXRfaWQoc3RydWN0IHBlcmZfZXZlbnRfaGVhZGVyICpoZWFkZXIsCgkJCQkJIHN0cnVjdCBwZXJmX3NhbXBsZV9kYXRhICpkYXRhLAoJCQkJCSBzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQpCnsKCXU2NCBzYW1wbGVfdHlwZSA9IGV2ZW50LT5hdHRyLnNhbXBsZV90eXBlOwoKCWRhdGEtPnR5cGUgPSBzYW1wbGVfdHlwZTsKCWhlYWRlci0+c2l6ZSArPSBldmVudC0+aWRfaGVhZGVyX3NpemU7CgoJaWYgKHNhbXBsZV90eXBlICYgUEVSRl9TQU1QTEVfVElEKSB7CgkJLyogbmFtZXNwYWNlIGlzc3VlcyAqLwoJCWRhdGEtPnRpZF9lbnRyeS5waWQgPSBwZXJmX2V2ZW50X3BpZChldmVudCwgY3VycmVudCk7CgkJZGF0YS0+dGlkX2VudHJ5LnRpZCA9IHBlcmZfZXZlbnRfdGlkKGV2ZW50LCBjdXJyZW50KTsKCX0KCglpZiAoc2FtcGxlX3R5cGUgJiBQRVJGX1NBTVBMRV9USU1FKQoJCWRhdGEtPnRpbWUgPSBwZXJmX2Nsb2NrKCk7CgoJaWYgKHNhbXBsZV90eXBlICYgUEVSRl9TQU1QTEVfSUQpCgkJZGF0YS0+aWQgPSBwcmltYXJ5X2V2ZW50X2lkKGV2ZW50KTsKCglpZiAoc2FtcGxlX3R5cGUgJiBQRVJGX1NBTVBMRV9TVFJFQU1fSUQpCgkJZGF0YS0+c3RyZWFtX2lkID0gZXZlbnQtPmlkOwoKCWlmIChzYW1wbGVfdHlwZSAmIFBFUkZfU0FNUExFX0NQVSkgewoJCWRhdGEtPmNwdV9lbnRyeS5jcHUJID0gcmF3X3NtcF9wcm9jZXNzb3JfaWQoKTsKCQlkYXRhLT5jcHVfZW50cnkucmVzZXJ2ZWQgPSAwOwoJfQp9CgpzdGF0aWMgdm9pZCBwZXJmX2V2ZW50X2hlYWRlcl9faW5pdF9pZChzdHJ1Y3QgcGVyZl9ldmVudF9oZWFkZXIgKmhlYWRlciwKCQkJCSAgICAgICBzdHJ1Y3QgcGVyZl9zYW1wbGVfZGF0YSAqZGF0YSwKCQkJCSAgICAgICBzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQpCnsKCWlmIChldmVudC0+YXR0ci5zYW1wbGVfaWRfYWxsKQoJCV9fcGVyZl9ldmVudF9oZWFkZXJfX2luaXRfaWQoaGVhZGVyLCBkYXRhLCBldmVudCk7Cn0KCnN0YXRpYyB2b2lkIF9fcGVyZl9ldmVudF9fb3V0cHV0X2lkX3NhbXBsZShzdHJ1Y3QgcGVyZl9vdXRwdXRfaGFuZGxlICpoYW5kbGUsCgkJCQkJICAgc3RydWN0IHBlcmZfc2FtcGxlX2RhdGEgKmRhdGEpCnsKCXU2NCBzYW1wbGVfdHlwZSA9IGRhdGEtPnR5cGU7CgoJaWYgKHNhbXBsZV90eXBlICYgUEVSRl9TQU1QTEVfVElEKQoJCXBlcmZfb3V0cHV0X3B1dChoYW5kbGUsIGRhdGEtPnRpZF9lbnRyeSk7CgoJaWYgKHNhbXBsZV90eXBlICYgUEVSRl9TQU1QTEVfVElNRSkKCQlwZXJmX291dHB1dF9wdXQoaGFuZGxlLCBkYXRhLT50aW1lKTsKCglpZiAoc2FtcGxlX3R5cGUgJiBQRVJGX1NBTVBMRV9JRCkKCQlwZXJmX291dHB1dF9wdXQoaGFuZGxlLCBkYXRhLT5pZCk7CgoJaWYgKHNhbXBsZV90eXBlICYgUEVSRl9TQU1QTEVfU1RSRUFNX0lEKQoJCXBlcmZfb3V0cHV0X3B1dChoYW5kbGUsIGRhdGEtPnN0cmVhbV9pZCk7CgoJaWYgKHNhbXBsZV90eXBlICYgUEVSRl9TQU1QTEVfQ1BVKQoJCXBlcmZfb3V0cHV0X3B1dChoYW5kbGUsIGRhdGEtPmNwdV9lbnRyeSk7Cn0KCnN0YXRpYyB2b2lkIHBlcmZfZXZlbnRfX291dHB1dF9pZF9zYW1wbGUoc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50LAoJCQkJCSBzdHJ1Y3QgcGVyZl9vdXRwdXRfaGFuZGxlICpoYW5kbGUsCgkJCQkJIHN0cnVjdCBwZXJmX3NhbXBsZV9kYXRhICpzYW1wbGUpCnsKCWlmIChldmVudC0+YXR0ci5zYW1wbGVfaWRfYWxsKQoJCV9fcGVyZl9ldmVudF9fb3V0cHV0X2lkX3NhbXBsZShoYW5kbGUsIHNhbXBsZSk7Cn0KCmludCBwZXJmX291dHB1dF9iZWdpbihzdHJ1Y3QgcGVyZl9vdXRwdXRfaGFuZGxlICpoYW5kbGUsCgkJICAgICAgc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50LCB1bnNpZ25lZCBpbnQgc2l6ZSwKCQkgICAgICBpbnQgbm1pLCBpbnQgc2FtcGxlKQp7CglzdHJ1Y3QgcGVyZl9idWZmZXIgKmJ1ZmZlcjsKCXVuc2lnbmVkIGxvbmcgdGFpbCwgb2Zmc2V0LCBoZWFkOwoJaW50IGhhdmVfbG9zdDsKCXN0cnVjdCBwZXJmX3NhbXBsZV9kYXRhIHNhbXBsZV9kYXRhOwoJc3RydWN0IHsKCQlzdHJ1Y3QgcGVyZl9ldmVudF9oZWFkZXIgaGVhZGVyOwoJCXU2NAkJCSBpZDsKCQl1NjQJCQkgbG9zdDsKCX0gbG9zdF9ldmVudDsKCglyY3VfcmVhZF9sb2NrKCk7CgkvKgoJICogRm9yIGluaGVyaXRlZCBldmVudHMgd2Ugc2VuZCBhbGwgdGhlIG91dHB1dCB0b3dhcmRzIHRoZSBwYXJlbnQuCgkgKi8KCWlmIChldmVudC0+cGFyZW50KQoJCWV2ZW50ID0gZXZlbnQtPnBhcmVudDsKCglidWZmZXIgPSByY3VfZGVyZWZlcmVuY2UoZXZlbnQtPmJ1ZmZlcik7CglpZiAoIWJ1ZmZlcikKCQlnb3RvIG91dDsKCgloYW5kbGUtPmJ1ZmZlcgk9IGJ1ZmZlcjsKCWhhbmRsZS0+ZXZlbnQJPSBldmVudDsKCWhhbmRsZS0+bm1pCT0gbm1pOwoJaGFuZGxlLT5zYW1wbGUJPSBzYW1wbGU7CgoJaWYgKCFidWZmZXItPm5yX3BhZ2VzKQoJCWdvdG8gb3V0OwoKCWhhdmVfbG9zdCA9IGxvY2FsX3JlYWQoJmJ1ZmZlci0+bG9zdCk7CglpZiAoaGF2ZV9sb3N0KSB7CgkJbG9zdF9ldmVudC5oZWFkZXIuc2l6ZSA9IHNpemVvZihsb3N0X2V2ZW50KTsKCQlwZXJmX2V2ZW50X2hlYWRlcl9faW5pdF9pZCgmbG9zdF9ldmVudC5oZWFkZXIsICZzYW1wbGVfZGF0YSwKCQkJCQkgICBldmVudCk7CgkJc2l6ZSArPSBsb3N0X2V2ZW50LmhlYWRlci5zaXplOwoJfQoKCXBlcmZfb3V0cHV0X2dldF9oYW5kbGUoaGFuZGxlKTsKCglkbyB7CgkJLyoKCQkgKiBVc2Vyc3BhY2UgY291bGQgY2hvb3NlIHRvIGlzc3VlIGEgbWIoKSBiZWZvcmUgdXBkYXRpbmcgdGhlCgkJICogdGFpbCBwb2ludGVyLiBTbyB0aGF0IGFsbCByZWFkcyB3aWxsIGJlIGNvbXBsZXRlZCBiZWZvcmUgdGhlCgkJICogd3JpdGUgaXMgaXNzdWVkLgoJCSAqLwoJCXRhaWwgPSBBQ0NFU1NfT05DRShidWZmZXItPnVzZXJfcGFnZS0+ZGF0YV90YWlsKTsKCQlzbXBfcm1iKCk7CgkJb2Zmc2V0ID0gaGVhZCA9IGxvY2FsX3JlYWQoJmJ1ZmZlci0+aGVhZCk7CgkJaGVhZCArPSBzaXplOwoJCWlmICh1bmxpa2VseSghcGVyZl9vdXRwdXRfc3BhY2UoYnVmZmVyLCB0YWlsLCBvZmZzZXQsIGhlYWQpKSkKCQkJZ290byBmYWlsOwoJfSB3aGlsZSAobG9jYWxfY21weGNoZygmYnVmZmVyLT5oZWFkLCBvZmZzZXQsIGhlYWQpICE9IG9mZnNldCk7CgoJaWYgKGhlYWQgLSBsb2NhbF9yZWFkKCZidWZmZXItPndha2V1cCkgPiBidWZmZXItPndhdGVybWFyaykKCQlsb2NhbF9hZGQoYnVmZmVyLT53YXRlcm1hcmssICZidWZmZXItPndha2V1cCk7CgoJaGFuZGxlLT5wYWdlID0gb2Zmc2V0ID4+IChQQUdFX1NISUZUICsgcGFnZV9vcmRlcihidWZmZXIpKTsKCWhhbmRsZS0+cGFnZSAmPSBidWZmZXItPm5yX3BhZ2VzIC0gMTsKCWhhbmRsZS0+c2l6ZSA9IG9mZnNldCAmICgoUEFHRV9TSVpFIDw8IHBhZ2Vfb3JkZXIoYnVmZmVyKSkgLSAxKTsKCWhhbmRsZS0+YWRkciA9IGJ1ZmZlci0+ZGF0YV9wYWdlc1toYW5kbGUtPnBhZ2VdOwoJaGFuZGxlLT5hZGRyICs9IGhhbmRsZS0+c2l6ZTsKCWhhbmRsZS0+c2l6ZSA9IChQQUdFX1NJWkUgPDwgcGFnZV9vcmRlcihidWZmZXIpKSAtIGhhbmRsZS0+c2l6ZTsKCglpZiAoaGF2ZV9sb3N0KSB7CgkJbG9zdF9ldmVudC5oZWFkZXIudHlwZSA9IFBFUkZfUkVDT1JEX0xPU1Q7CgkJbG9zdF9ldmVudC5oZWFkZXIubWlzYyA9IDA7CgkJbG9zdF9ldmVudC5pZCAgICAgICAgICA9IGV2ZW50LT5pZDsKCQlsb3N0X2V2ZW50Lmxvc3QgICAgICAgID0gbG9jYWxfeGNoZygmYnVmZmVyLT5sb3N0LCAwKTsKCgkJcGVyZl9vdXRwdXRfcHV0KGhhbmRsZSwgbG9zdF9ldmVudCk7CgkJcGVyZl9ldmVudF9fb3V0cHV0X2lkX3NhbXBsZShldmVudCwgaGFuZGxlLCAmc2FtcGxlX2RhdGEpOwoJfQoKCXJldHVybiAwOwoKZmFpbDoKCWxvY2FsX2luYygmYnVmZmVyLT5sb3N0KTsKCXBlcmZfb3V0cHV0X3B1dF9oYW5kbGUoaGFuZGxlKTsKb3V0OgoJcmN1X3JlYWRfdW5sb2NrKCk7CgoJcmV0dXJuIC1FTk9TUEM7Cn0KCnZvaWQgcGVyZl9vdXRwdXRfZW5kKHN0cnVjdCBwZXJmX291dHB1dF9oYW5kbGUgKmhhbmRsZSkKewoJc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50ID0gaGFuZGxlLT5ldmVudDsKCXN0cnVjdCBwZXJmX2J1ZmZlciAqYnVmZmVyID0gaGFuZGxlLT5idWZmZXI7CgoJaW50IHdha2V1cF9ldmVudHMgPSBldmVudC0+YXR0ci53YWtldXBfZXZlbnRzOwoKCWlmIChoYW5kbGUtPnNhbXBsZSAmJiB3YWtldXBfZXZlbnRzKSB7CgkJaW50IGV2ZW50cyA9IGxvY2FsX2luY19yZXR1cm4oJmJ1ZmZlci0+ZXZlbnRzKTsKCQlpZiAoZXZlbnRzID49IHdha2V1cF9ldmVudHMpIHsKCQkJbG9jYWxfc3ViKHdha2V1cF9ldmVudHMsICZidWZmZXItPmV2ZW50cyk7CgkJCWxvY2FsX2luYygmYnVmZmVyLT53YWtldXApOwoJCX0KCX0KCglwZXJmX291dHB1dF9wdXRfaGFuZGxlKGhhbmRsZSk7CglyY3VfcmVhZF91bmxvY2soKTsKfQoKc3RhdGljIHZvaWQgcGVyZl9vdXRwdXRfcmVhZF9vbmUoc3RydWN0IHBlcmZfb3V0cHV0X2hhbmRsZSAqaGFuZGxlLAoJCQkJIHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCwKCQkJCSB1NjQgZW5hYmxlZCwgdTY0IHJ1bm5pbmcpCnsKCXU2NCByZWFkX2Zvcm1hdCA9IGV2ZW50LT5hdHRyLnJlYWRfZm9ybWF0OwoJdTY0IHZhbHVlc1s0XTsKCWludCBuID0gMDsKCgl2YWx1ZXNbbisrXSA9IHBlcmZfZXZlbnRfY291bnQoZXZlbnQpOwoJaWYgKHJlYWRfZm9ybWF0ICYgUEVSRl9GT1JNQVRfVE9UQUxfVElNRV9FTkFCTEVEKSB7CgkJdmFsdWVzW24rK10gPSBlbmFibGVkICsKCQkJYXRvbWljNjRfcmVhZCgmZXZlbnQtPmNoaWxkX3RvdGFsX3RpbWVfZW5hYmxlZCk7Cgl9CglpZiAocmVhZF9mb3JtYXQgJiBQRVJGX0ZPUk1BVF9UT1RBTF9USU1FX1JVTk5JTkcpIHsKCQl2YWx1ZXNbbisrXSA9IHJ1bm5pbmcgKwoJCQlhdG9taWM2NF9yZWFkKCZldmVudC0+Y2hpbGRfdG90YWxfdGltZV9ydW5uaW5nKTsKCX0KCWlmIChyZWFkX2Zvcm1hdCAmIFBFUkZfRk9STUFUX0lEKQoJCXZhbHVlc1tuKytdID0gcHJpbWFyeV9ldmVudF9pZChldmVudCk7CgoJcGVyZl9vdXRwdXRfY29weShoYW5kbGUsIHZhbHVlcywgbiAqIHNpemVvZih1NjQpKTsKfQoKLyoKICogWFhYIFBFUkZfRk9STUFUX0dST1VQIHZzIGluaGVyaXRlZCBldmVudHMgc2VlbXMgZGlmZmljdWx0LgogKi8Kc3RhdGljIHZvaWQgcGVyZl9vdXRwdXRfcmVhZF9ncm91cChzdHJ1Y3QgcGVyZl9vdXRwdXRfaGFuZGxlICpoYW5kbGUsCgkJCSAgICBzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQsCgkJCSAgICB1NjQgZW5hYmxlZCwgdTY0IHJ1bm5pbmcpCnsKCXN0cnVjdCBwZXJmX2V2ZW50ICpsZWFkZXIgPSBldmVudC0+Z3JvdXBfbGVhZGVyLCAqc3ViOwoJdTY0IHJlYWRfZm9ybWF0ID0gZXZlbnQtPmF0dHIucmVhZF9mb3JtYXQ7Cgl1NjQgdmFsdWVzWzVdOwoJaW50IG4gPSAwOwoKCXZhbHVlc1tuKytdID0gMSArIGxlYWRlci0+bnJfc2libGluZ3M7CgoJaWYgKHJlYWRfZm9ybWF0ICYgUEVSRl9GT1JNQVRfVE9UQUxfVElNRV9FTkFCTEVEKQoJCXZhbHVlc1tuKytdID0gZW5hYmxlZDsKCglpZiAocmVhZF9mb3JtYXQgJiBQRVJGX0ZPUk1BVF9UT1RBTF9USU1FX1JVTk5JTkcpCgkJdmFsdWVzW24rK10gPSBydW5uaW5nOwoKCWlmIChsZWFkZXIgIT0gZXZlbnQpCgkJbGVhZGVyLT5wbXUtPnJlYWQobGVhZGVyKTsKCgl2YWx1ZXNbbisrXSA9IHBlcmZfZXZlbnRfY291bnQobGVhZGVyKTsKCWlmIChyZWFkX2Zvcm1hdCAmIFBFUkZfRk9STUFUX0lEKQoJCXZhbHVlc1tuKytdID0gcHJpbWFyeV9ldmVudF9pZChsZWFkZXIpOwoKCXBlcmZfb3V0cHV0X2NvcHkoaGFuZGxlLCB2YWx1ZXMsIG4gKiBzaXplb2YodTY0KSk7CgoJbGlzdF9mb3JfZWFjaF9lbnRyeShzdWIsICZsZWFkZXItPnNpYmxpbmdfbGlzdCwgZ3JvdXBfZW50cnkpIHsKCQluID0gMDsKCgkJaWYgKHN1YiAhPSBldmVudCkKCQkJc3ViLT5wbXUtPnJlYWQoc3ViKTsKCgkJdmFsdWVzW24rK10gPSBwZXJmX2V2ZW50X2NvdW50KHN1Yik7CgkJaWYgKHJlYWRfZm9ybWF0ICYgUEVSRl9GT1JNQVRfSUQpCgkJCXZhbHVlc1tuKytdID0gcHJpbWFyeV9ldmVudF9pZChzdWIpOwoKCQlwZXJmX291dHB1dF9jb3B5KGhhbmRsZSwgdmFsdWVzLCBuICogc2l6ZW9mKHU2NCkpOwoJfQp9CgojZGVmaW5lIFBFUkZfRk9STUFUX1RPVEFMX1RJTUVTIChQRVJGX0ZPUk1BVF9UT1RBTF9USU1FX0VOQUJMRUR8XAoJCQkJIFBFUkZfRk9STUFUX1RPVEFMX1RJTUVfUlVOTklORykKCnN0YXRpYyB2b2lkIHBlcmZfb3V0cHV0X3JlYWQoc3RydWN0IHBlcmZfb3V0cHV0X2hhbmRsZSAqaGFuZGxlLAoJCQkgICAgIHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCkKewoJdTY0IGVuYWJsZWQgPSAwLCBydW5uaW5nID0gMCwgbm93LCBjdHhfdGltZTsKCXU2NCByZWFkX2Zvcm1hdCA9IGV2ZW50LT5hdHRyLnJlYWRfZm9ybWF0OwoKCS8qCgkgKiBjb21wdXRlIHRvdGFsX3RpbWVfZW5hYmxlZCwgdG90YWxfdGltZV9ydW5uaW5nCgkgKiBiYXNlZCBvbiBzbmFwc2hvdCB2YWx1ZXMgdGFrZW4gd2hlbiB0aGUgZXZlbnQKCSAqIHdhcyBsYXN0IHNjaGVkdWxlZCBpbi4KCSAqCgkgKiB3ZSBjYW5ub3Qgc2ltcGx5IGNhbGxlZCB1cGRhdGVfY29udGV4dF90aW1lKCkKCSAqIGJlY2F1c2Ugb2YgbG9ja2luZyBpc3N1ZSBhcyB3ZSBhcmUgY2FsbGVkIGluCgkgKiBOTUkgY29udGV4dAoJICovCglpZiAocmVhZF9mb3JtYXQgJiBQRVJGX0ZPUk1BVF9UT1RBTF9USU1FUykgewoJCW5vdyA9IHBlcmZfY2xvY2soKTsKCQljdHhfdGltZSA9IGV2ZW50LT5zaGFkb3dfY3R4X3RpbWUgKyBub3c7CgkJZW5hYmxlZCA9IGN0eF90aW1lIC0gZXZlbnQtPnRzdGFtcF9lbmFibGVkOwoJCXJ1bm5pbmcgPSBjdHhfdGltZSAtIGV2ZW50LT50c3RhbXBfcnVubmluZzsKCX0KCglpZiAoZXZlbnQtPmF0dHIucmVhZF9mb3JtYXQgJiBQRVJGX0ZPUk1BVF9HUk9VUCkKCQlwZXJmX291dHB1dF9yZWFkX2dyb3VwKGhhbmRsZSwgZXZlbnQsIGVuYWJsZWQsIHJ1bm5pbmcpOwoJZWxzZQoJCXBlcmZfb3V0cHV0X3JlYWRfb25lKGhhbmRsZSwgZXZlbnQsIGVuYWJsZWQsIHJ1bm5pbmcpOwp9Cgp2b2lkIHBlcmZfb3V0cHV0X3NhbXBsZShzdHJ1Y3QgcGVyZl9vdXRwdXRfaGFuZGxlICpoYW5kbGUsCgkJCXN0cnVjdCBwZXJmX2V2ZW50X2hlYWRlciAqaGVhZGVyLAoJCQlzdHJ1Y3QgcGVyZl9zYW1wbGVfZGF0YSAqZGF0YSwKCQkJc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50KQp7Cgl1NjQgc2FtcGxlX3R5cGUgPSBkYXRhLT50eXBlOwoKCXBlcmZfb3V0cHV0X3B1dChoYW5kbGUsICpoZWFkZXIpOwoKCWlmIChzYW1wbGVfdHlwZSAmIFBFUkZfU0FNUExFX0lQKQoJCXBlcmZfb3V0cHV0X3B1dChoYW5kbGUsIGRhdGEtPmlwKTsKCglpZiAoc2FtcGxlX3R5cGUgJiBQRVJGX1NBTVBMRV9USUQpCgkJcGVyZl9vdXRwdXRfcHV0KGhhbmRsZSwgZGF0YS0+dGlkX2VudHJ5KTsKCglpZiAoc2FtcGxlX3R5cGUgJiBQRVJGX1NBTVBMRV9USU1FKQoJCXBlcmZfb3V0cHV0X3B1dChoYW5kbGUsIGRhdGEtPnRpbWUpOwoKCWlmIChzYW1wbGVfdHlwZSAmIFBFUkZfU0FNUExFX0FERFIpCgkJcGVyZl9vdXRwdXRfcHV0KGhhbmRsZSwgZGF0YS0+YWRkcik7CgoJaWYgKHNhbXBsZV90eXBlICYgUEVSRl9TQU1QTEVfSUQpCgkJcGVyZl9vdXRwdXRfcHV0KGhhbmRsZSwgZGF0YS0+aWQpOwoKCWlmIChzYW1wbGVfdHlwZSAmIFBFUkZfU0FNUExFX1NUUkVBTV9JRCkKCQlwZXJmX291dHB1dF9wdXQoaGFuZGxlLCBkYXRhLT5zdHJlYW1faWQpOwoKCWlmIChzYW1wbGVfdHlwZSAmIFBFUkZfU0FNUExFX0NQVSkKCQlwZXJmX291dHB1dF9wdXQoaGFuZGxlLCBkYXRhLT5jcHVfZW50cnkpOwoKCWlmIChzYW1wbGVfdHlwZSAmIFBFUkZfU0FNUExFX1BFUklPRCkKCQlwZXJmX291dHB1dF9wdXQoaGFuZGxlLCBkYXRhLT5wZXJpb2QpOwoKCWlmIChzYW1wbGVfdHlwZSAmIFBFUkZfU0FNUExFX1JFQUQpCgkJcGVyZl9vdXRwdXRfcmVhZChoYW5kbGUsIGV2ZW50KTsKCglpZiAoc2FtcGxlX3R5cGUgJiBQRVJGX1NBTVBMRV9DQUxMQ0hBSU4pIHsKCQlpZiAoZGF0YS0+Y2FsbGNoYWluKSB7CgkJCWludCBzaXplID0gMTsKCgkJCWlmIChkYXRhLT5jYWxsY2hhaW4pCgkJCQlzaXplICs9IGRhdGEtPmNhbGxjaGFpbi0+bnI7CgoJCQlzaXplICo9IHNpemVvZih1NjQpOwoKCQkJcGVyZl9vdXRwdXRfY29weShoYW5kbGUsIGRhdGEtPmNhbGxjaGFpbiwgc2l6ZSk7CgkJfSBlbHNlIHsKCQkJdTY0IG5yID0gMDsKCQkJcGVyZl9vdXRwdXRfcHV0KGhhbmRsZSwgbnIpOwoJCX0KCX0KCglpZiAoc2FtcGxlX3R5cGUgJiBQRVJGX1NBTVBMRV9SQVcpIHsKCQlpZiAoZGF0YS0+cmF3KSB7CgkJCXBlcmZfb3V0cHV0X3B1dChoYW5kbGUsIGRhdGEtPnJhdy0+c2l6ZSk7CgkJCXBlcmZfb3V0cHV0X2NvcHkoaGFuZGxlLCBkYXRhLT5yYXctPmRhdGEsCgkJCQkJIGRhdGEtPnJhdy0+c2l6ZSk7CgkJfSBlbHNlIHsKCQkJc3RydWN0IHsKCQkJCXUzMglzaXplOwoJCQkJdTMyCWRhdGE7CgkJCX0gcmF3ID0gewoJCQkJLnNpemUgPSBzaXplb2YodTMyKSwKCQkJCS5kYXRhID0gMCwKCQkJfTsKCQkJcGVyZl9vdXRwdXRfcHV0KGhhbmRsZSwgcmF3KTsKCQl9Cgl9Cn0KCnZvaWQgcGVyZl9wcmVwYXJlX3NhbXBsZShzdHJ1Y3QgcGVyZl9ldmVudF9oZWFkZXIgKmhlYWRlciwKCQkJIHN0cnVjdCBwZXJmX3NhbXBsZV9kYXRhICpkYXRhLAoJCQkgc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50LAoJCQkgc3RydWN0IHB0X3JlZ3MgKnJlZ3MpCnsKCXU2NCBzYW1wbGVfdHlwZSA9IGV2ZW50LT5hdHRyLnNhbXBsZV90eXBlOwoKCWhlYWRlci0+dHlwZSA9IFBFUkZfUkVDT1JEX1NBTVBMRTsKCWhlYWRlci0+c2l6ZSA9IHNpemVvZigqaGVhZGVyKSArIGV2ZW50LT5oZWFkZXJfc2l6ZTsKCgloZWFkZXItPm1pc2MgPSAwOwoJaGVhZGVyLT5taXNjIHw9IHBlcmZfbWlzY19mbGFncyhyZWdzKTsKCglfX3BlcmZfZXZlbnRfaGVhZGVyX19pbml0X2lkKGhlYWRlciwgZGF0YSwgZXZlbnQpOwoKCWlmIChzYW1wbGVfdHlwZSAmIFBFUkZfU0FNUExFX0lQKQoJCWRhdGEtPmlwID0gcGVyZl9pbnN0cnVjdGlvbl9wb2ludGVyKHJlZ3MpOwoKCWlmIChzYW1wbGVfdHlwZSAmIFBFUkZfU0FNUExFX0NBTExDSEFJTikgewoJCWludCBzaXplID0gMTsKCgkJZGF0YS0+Y2FsbGNoYWluID0gcGVyZl9jYWxsY2hhaW4ocmVncyk7CgoJCWlmIChkYXRhLT5jYWxsY2hhaW4pCgkJCXNpemUgKz0gZGF0YS0+Y2FsbGNoYWluLT5ucjsKCgkJaGVhZGVyLT5zaXplICs9IHNpemUgKiBzaXplb2YodTY0KTsKCX0KCglpZiAoc2FtcGxlX3R5cGUgJiBQRVJGX1NBTVBMRV9SQVcpIHsKCQlpbnQgc2l6ZSA9IHNpemVvZih1MzIpOwoKCQlpZiAoZGF0YS0+cmF3KQoJCQlzaXplICs9IGRhdGEtPnJhdy0+c2l6ZTsKCQllbHNlCgkJCXNpemUgKz0gc2l6ZW9mKHUzMik7CgoJCVdBUk5fT05fT05DRShzaXplICYgKHNpemVvZih1NjQpLTEpKTsKCQloZWFkZXItPnNpemUgKz0gc2l6ZTsKCX0KfQoKc3RhdGljIHZvaWQgcGVyZl9ldmVudF9vdXRwdXQoc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50LCBpbnQgbm1pLAoJCQkJc3RydWN0IHBlcmZfc2FtcGxlX2RhdGEgKmRhdGEsCgkJCQlzdHJ1Y3QgcHRfcmVncyAqcmVncykKewoJc3RydWN0IHBlcmZfb3V0cHV0X2hhbmRsZSBoYW5kbGU7CglzdHJ1Y3QgcGVyZl9ldmVudF9oZWFkZXIgaGVhZGVyOwoKCS8qIHByb3RlY3QgdGhlIGNhbGxjaGFpbiBidWZmZXJzICovCglyY3VfcmVhZF9sb2NrKCk7CgoJcGVyZl9wcmVwYXJlX3NhbXBsZSgmaGVhZGVyLCBkYXRhLCBldmVudCwgcmVncyk7CgoJaWYgKHBlcmZfb3V0cHV0X2JlZ2luKCZoYW5kbGUsIGV2ZW50LCBoZWFkZXIuc2l6ZSwgbm1pLCAxKSkKCQlnb3RvIGV4aXQ7CgoJcGVyZl9vdXRwdXRfc2FtcGxlKCZoYW5kbGUsICZoZWFkZXIsIGRhdGEsIGV2ZW50KTsKCglwZXJmX291dHB1dF9lbmQoJmhhbmRsZSk7CgpleGl0OgoJcmN1X3JlYWRfdW5sb2NrKCk7Cn0KCi8qCiAqIHJlYWQgZXZlbnRfaWQKICovCgpzdHJ1Y3QgcGVyZl9yZWFkX2V2ZW50IHsKCXN0cnVjdCBwZXJmX2V2ZW50X2hlYWRlcgloZWFkZXI7CgoJdTMyCQkJCXBpZDsKCXUzMgkJCQl0aWQ7Cn07CgpzdGF0aWMgdm9pZApwZXJmX2V2ZW50X3JlYWRfZXZlbnQoc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50LAoJCQlzdHJ1Y3QgdGFza19zdHJ1Y3QgKnRhc2spCnsKCXN0cnVjdCBwZXJmX291dHB1dF9oYW5kbGUgaGFuZGxlOwoJc3RydWN0IHBlcmZfc2FtcGxlX2RhdGEgc2FtcGxlOwoJc3RydWN0IHBlcmZfcmVhZF9ldmVudCByZWFkX2V2ZW50ID0gewoJCS5oZWFkZXIgPSB7CgkJCS50eXBlID0gUEVSRl9SRUNPUkRfUkVBRCwKCQkJLm1pc2MgPSAwLAoJCQkuc2l6ZSA9IHNpemVvZihyZWFkX2V2ZW50KSArIGV2ZW50LT5yZWFkX3NpemUsCgkJfSwKCQkucGlkID0gcGVyZl9ldmVudF9waWQoZXZlbnQsIHRhc2spLAoJCS50aWQgPSBwZXJmX2V2ZW50X3RpZChldmVudCwgdGFzayksCgl9OwoJaW50IHJldDsKCglwZXJmX2V2ZW50X2hlYWRlcl9faW5pdF9pZCgmcmVhZF9ldmVudC5oZWFkZXIsICZzYW1wbGUsIGV2ZW50KTsKCXJldCA9IHBlcmZfb3V0cHV0X2JlZ2luKCZoYW5kbGUsIGV2ZW50LCByZWFkX2V2ZW50LmhlYWRlci5zaXplLCAwLCAwKTsKCWlmIChyZXQpCgkJcmV0dXJuOwoKCXBlcmZfb3V0cHV0X3B1dCgmaGFuZGxlLCByZWFkX2V2ZW50KTsKCXBlcmZfb3V0cHV0X3JlYWQoJmhhbmRsZSwgZXZlbnQpOwoJcGVyZl9ldmVudF9fb3V0cHV0X2lkX3NhbXBsZShldmVudCwgJmhhbmRsZSwgJnNhbXBsZSk7CgoJcGVyZl9vdXRwdXRfZW5kKCZoYW5kbGUpOwp9CgovKgogKiB0YXNrIHRyYWNraW5nIC0tIGZvcmsvZXhpdAogKgogKiBlbmFibGVkIGJ5OiBhdHRyLmNvbW0gfCBhdHRyLm1tYXAgfCBhdHRyLm1tYXBfZGF0YSB8IGF0dHIudGFzawogKi8KCnN0cnVjdCBwZXJmX3Rhc2tfZXZlbnQgewoJc3RydWN0IHRhc2tfc3RydWN0CQkqdGFzazsKCXN0cnVjdCBwZXJmX2V2ZW50X2NvbnRleHQJKnRhc2tfY3R4OwoKCXN0cnVjdCB7CgkJc3RydWN0IHBlcmZfZXZlbnRfaGVhZGVyCWhlYWRlcjsKCgkJdTMyCQkJCXBpZDsKCQl1MzIJCQkJcHBpZDsKCQl1MzIJCQkJdGlkOwoJCXUzMgkJCQlwdGlkOwoJCXU2NAkJCQl0aW1lOwoJfSBldmVudF9pZDsKfTsKCnN0YXRpYyB2b2lkIHBlcmZfZXZlbnRfdGFza19vdXRwdXQoc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50LAoJCQkJICAgICBzdHJ1Y3QgcGVyZl90YXNrX2V2ZW50ICp0YXNrX2V2ZW50KQp7CglzdHJ1Y3QgcGVyZl9vdXRwdXRfaGFuZGxlIGhhbmRsZTsKCXN0cnVjdCBwZXJmX3NhbXBsZV9kYXRhCXNhbXBsZTsKCXN0cnVjdCB0YXNrX3N0cnVjdCAqdGFzayA9IHRhc2tfZXZlbnQtPnRhc2s7CglpbnQgcmV0LCBzaXplID0gdGFza19ldmVudC0+ZXZlbnRfaWQuaGVhZGVyLnNpemU7CgoJcGVyZl9ldmVudF9oZWFkZXJfX2luaXRfaWQoJnRhc2tfZXZlbnQtPmV2ZW50X2lkLmhlYWRlciwgJnNhbXBsZSwgZXZlbnQpOwoKCXJldCA9IHBlcmZfb3V0cHV0X2JlZ2luKCZoYW5kbGUsIGV2ZW50LAoJCQkJdGFza19ldmVudC0+ZXZlbnRfaWQuaGVhZGVyLnNpemUsIDAsIDApOwoJaWYgKHJldCkKCQlnb3RvIG91dDsKCgl0YXNrX2V2ZW50LT5ldmVudF9pZC5waWQgPSBwZXJmX2V2ZW50X3BpZChldmVudCwgdGFzayk7Cgl0YXNrX2V2ZW50LT5ldmVudF9pZC5wcGlkID0gcGVyZl9ldmVudF9waWQoZXZlbnQsIGN1cnJlbnQpOwoKCXRhc2tfZXZlbnQtPmV2ZW50X2lkLnRpZCA9IHBlcmZfZXZlbnRfdGlkKGV2ZW50LCB0YXNrKTsKCXRhc2tfZXZlbnQtPmV2ZW50X2lkLnB0aWQgPSBwZXJmX2V2ZW50X3RpZChldmVudCwgY3VycmVudCk7CgoJcGVyZl9vdXRwdXRfcHV0KCZoYW5kbGUsIHRhc2tfZXZlbnQtPmV2ZW50X2lkKTsKCglwZXJmX2V2ZW50X19vdXRwdXRfaWRfc2FtcGxlKGV2ZW50LCAmaGFuZGxlLCAmc2FtcGxlKTsKCglwZXJmX291dHB1dF9lbmQoJmhhbmRsZSk7Cm91dDoKCXRhc2tfZXZlbnQtPmV2ZW50X2lkLmhlYWRlci5zaXplID0gc2l6ZTsKfQoKc3RhdGljIGludCBwZXJmX2V2ZW50X3Rhc2tfbWF0Y2goc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50KQp7CglpZiAoZXZlbnQtPnN0YXRlIDwgUEVSRl9FVkVOVF9TVEFURV9JTkFDVElWRSkKCQlyZXR1cm4gMDsKCglpZiAoZXZlbnQtPmNwdSAhPSAtMSAmJiBldmVudC0+Y3B1ICE9IHNtcF9wcm9jZXNzb3JfaWQoKSkKCQlyZXR1cm4gMDsKCglpZiAoZXZlbnQtPmF0dHIuY29tbSB8fCBldmVudC0+YXR0ci5tbWFwIHx8CgkgICAgZXZlbnQtPmF0dHIubW1hcF9kYXRhIHx8IGV2ZW50LT5hdHRyLnRhc2spCgkJcmV0dXJuIDE7CgoJcmV0dXJuIDA7Cn0KCnN0YXRpYyB2b2lkIHBlcmZfZXZlbnRfdGFza19jdHgoc3RydWN0IHBlcmZfZXZlbnRfY29udGV4dCAqY3R4LAoJCQkJICBzdHJ1Y3QgcGVyZl90YXNrX2V2ZW50ICp0YXNrX2V2ZW50KQp7CglzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQ7CgoJbGlzdF9mb3JfZWFjaF9lbnRyeV9yY3UoZXZlbnQsICZjdHgtPmV2ZW50X2xpc3QsIGV2ZW50X2VudHJ5KSB7CgkJaWYgKHBlcmZfZXZlbnRfdGFza19tYXRjaChldmVudCkpCgkJCXBlcmZfZXZlbnRfdGFza19vdXRwdXQoZXZlbnQsIHRhc2tfZXZlbnQpOwoJfQp9CgpzdGF0aWMgdm9pZCBwZXJmX2V2ZW50X3Rhc2tfZXZlbnQoc3RydWN0IHBlcmZfdGFza19ldmVudCAqdGFza19ldmVudCkKewoJc3RydWN0IHBlcmZfY3B1X2NvbnRleHQgKmNwdWN0eDsKCXN0cnVjdCBwZXJmX2V2ZW50X2NvbnRleHQgKmN0eDsKCXN0cnVjdCBwbXUgKnBtdTsKCWludCBjdHhuOwoKCXJjdV9yZWFkX2xvY2soKTsKCWxpc3RfZm9yX2VhY2hfZW50cnlfcmN1KHBtdSwgJnBtdXMsIGVudHJ5KSB7CgkJY3B1Y3R4ID0gZ2V0X2NwdV9wdHIocG11LT5wbXVfY3B1X2NvbnRleHQpOwoJCWlmIChjcHVjdHgtPmFjdGl2ZV9wbXUgIT0gcG11KQoJCQlnb3RvIG5leHQ7CgkJcGVyZl9ldmVudF90YXNrX2N0eCgmY3B1Y3R4LT5jdHgsIHRhc2tfZXZlbnQpOwoKCQljdHggPSB0YXNrX2V2ZW50LT50YXNrX2N0eDsKCQlpZiAoIWN0eCkgewoJCQljdHhuID0gcG11LT50YXNrX2N0eF9ucjsKCQkJaWYgKGN0eG4gPCAwKQoJCQkJZ290byBuZXh0OwoJCQljdHggPSByY3VfZGVyZWZlcmVuY2UoY3VycmVudC0+cGVyZl9ldmVudF9jdHhwW2N0eG5dKTsKCQl9CgkJaWYgKGN0eCkKCQkJcGVyZl9ldmVudF90YXNrX2N0eChjdHgsIHRhc2tfZXZlbnQpOwpuZXh0OgoJCXB1dF9jcHVfcHRyKHBtdS0+cG11X2NwdV9jb250ZXh0KTsKCX0KCXJjdV9yZWFkX3VubG9jaygpOwp9CgpzdGF0aWMgdm9pZCBwZXJmX2V2ZW50X3Rhc2soc3RydWN0IHRhc2tfc3RydWN0ICp0YXNrLAoJCQkgICAgICBzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0ICp0YXNrX2N0eCwKCQkJICAgICAgaW50IG5ldykKewoJc3RydWN0IHBlcmZfdGFza19ldmVudCB0YXNrX2V2ZW50OwoKCWlmICghYXRvbWljX3JlYWQoJm5yX2NvbW1fZXZlbnRzKSAmJgoJICAgICFhdG9taWNfcmVhZCgmbnJfbW1hcF9ldmVudHMpICYmCgkgICAgIWF0b21pY19yZWFkKCZucl90YXNrX2V2ZW50cykpCgkJcmV0dXJuOwoKCXRhc2tfZXZlbnQgPSAoc3RydWN0IHBlcmZfdGFza19ldmVudCl7CgkJLnRhc2sJICA9IHRhc2ssCgkJLnRhc2tfY3R4ID0gdGFza19jdHgsCgkJLmV2ZW50X2lkICAgID0gewoJCQkuaGVhZGVyID0gewoJCQkJLnR5cGUgPSBuZXcgPyBQRVJGX1JFQ09SRF9GT1JLIDogUEVSRl9SRUNPUkRfRVhJVCwKCQkJCS5taXNjID0gMCwKCQkJCS5zaXplID0gc2l6ZW9mKHRhc2tfZXZlbnQuZXZlbnRfaWQpLAoJCQl9LAoJCQkvKiAucGlkICAqLwoJCQkvKiAucHBpZCAqLwoJCQkvKiAudGlkICAqLwoJCQkvKiAucHRpZCAqLwoJCQkudGltZSA9IHBlcmZfY2xvY2soKSwKCQl9LAoJfTsKCglwZXJmX2V2ZW50X3Rhc2tfZXZlbnQoJnRhc2tfZXZlbnQpOwp9Cgp2b2lkIHBlcmZfZXZlbnRfZm9yayhzdHJ1Y3QgdGFza19zdHJ1Y3QgKnRhc2spCnsKCXBlcmZfZXZlbnRfdGFzayh0YXNrLCBOVUxMLCAxKTsKfQoKLyoKICogY29tbSB0cmFja2luZwogKi8KCnN0cnVjdCBwZXJmX2NvbW1fZXZlbnQgewoJc3RydWN0IHRhc2tfc3RydWN0CSp0YXNrOwoJY2hhcgkJCSpjb21tOwoJaW50CQkJY29tbV9zaXplOwoKCXN0cnVjdCB7CgkJc3RydWN0IHBlcmZfZXZlbnRfaGVhZGVyCWhlYWRlcjsKCgkJdTMyCQkJCXBpZDsKCQl1MzIJCQkJdGlkOwoJfSBldmVudF9pZDsKfTsKCnN0YXRpYyB2b2lkIHBlcmZfZXZlbnRfY29tbV9vdXRwdXQoc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50LAoJCQkJICAgICBzdHJ1Y3QgcGVyZl9jb21tX2V2ZW50ICpjb21tX2V2ZW50KQp7CglzdHJ1Y3QgcGVyZl9vdXRwdXRfaGFuZGxlIGhhbmRsZTsKCXN0cnVjdCBwZXJmX3NhbXBsZV9kYXRhIHNhbXBsZTsKCWludCBzaXplID0gY29tbV9ldmVudC0+ZXZlbnRfaWQuaGVhZGVyLnNpemU7CglpbnQgcmV0OwoKCXBlcmZfZXZlbnRfaGVhZGVyX19pbml0X2lkKCZjb21tX2V2ZW50LT5ldmVudF9pZC5oZWFkZXIsICZzYW1wbGUsIGV2ZW50KTsKCXJldCA9IHBlcmZfb3V0cHV0X2JlZ2luKCZoYW5kbGUsIGV2ZW50LAoJCQkJY29tbV9ldmVudC0+ZXZlbnRfaWQuaGVhZGVyLnNpemUsIDAsIDApOwoKCWlmIChyZXQpCgkJZ290byBvdXQ7CgoJY29tbV9ldmVudC0+ZXZlbnRfaWQucGlkID0gcGVyZl9ldmVudF9waWQoZXZlbnQsIGNvbW1fZXZlbnQtPnRhc2spOwoJY29tbV9ldmVudC0+ZXZlbnRfaWQudGlkID0gcGVyZl9ldmVudF90aWQoZXZlbnQsIGNvbW1fZXZlbnQtPnRhc2spOwoKCXBlcmZfb3V0cHV0X3B1dCgmaGFuZGxlLCBjb21tX2V2ZW50LT5ldmVudF9pZCk7CglwZXJmX291dHB1dF9jb3B5KCZoYW5kbGUsIGNvbW1fZXZlbnQtPmNvbW0sCgkJCQkgICBjb21tX2V2ZW50LT5jb21tX3NpemUpOwoKCXBlcmZfZXZlbnRfX291dHB1dF9pZF9zYW1wbGUoZXZlbnQsICZoYW5kbGUsICZzYW1wbGUpOwoKCXBlcmZfb3V0cHV0X2VuZCgmaGFuZGxlKTsKb3V0OgoJY29tbV9ldmVudC0+ZXZlbnRfaWQuaGVhZGVyLnNpemUgPSBzaXplOwp9CgpzdGF0aWMgaW50IHBlcmZfZXZlbnRfY29tbV9tYXRjaChzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQpCnsKCWlmIChldmVudC0+c3RhdGUgPCBQRVJGX0VWRU5UX1NUQVRFX0lOQUNUSVZFKQoJCXJldHVybiAwOwoKCWlmIChldmVudC0+Y3B1ICE9IC0xICYmIGV2ZW50LT5jcHUgIT0gc21wX3Byb2Nlc3Nvcl9pZCgpKQoJCXJldHVybiAwOwoKCWlmIChldmVudC0+YXR0ci5jb21tKQoJCXJldHVybiAxOwoKCXJldHVybiAwOwp9CgpzdGF0aWMgdm9pZCBwZXJmX2V2ZW50X2NvbW1fY3R4KHN0cnVjdCBwZXJmX2V2ZW50X2NvbnRleHQgKmN0eCwKCQkJCSAgc3RydWN0IHBlcmZfY29tbV9ldmVudCAqY29tbV9ldmVudCkKewoJc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50OwoKCWxpc3RfZm9yX2VhY2hfZW50cnlfcmN1KGV2ZW50LCAmY3R4LT5ldmVudF9saXN0LCBldmVudF9lbnRyeSkgewoJCWlmIChwZXJmX2V2ZW50X2NvbW1fbWF0Y2goZXZlbnQpKQoJCQlwZXJmX2V2ZW50X2NvbW1fb3V0cHV0KGV2ZW50LCBjb21tX2V2ZW50KTsKCX0KfQoKc3RhdGljIHZvaWQgcGVyZl9ldmVudF9jb21tX2V2ZW50KHN0cnVjdCBwZXJmX2NvbW1fZXZlbnQgKmNvbW1fZXZlbnQpCnsKCXN0cnVjdCBwZXJmX2NwdV9jb250ZXh0ICpjcHVjdHg7CglzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0ICpjdHg7CgljaGFyIGNvbW1bVEFTS19DT01NX0xFTl07Cgl1bnNpZ25lZCBpbnQgc2l6ZTsKCXN0cnVjdCBwbXUgKnBtdTsKCWludCBjdHhuOwoKCW1lbXNldChjb21tLCAwLCBzaXplb2YoY29tbSkpOwoJc3RybGNweShjb21tLCBjb21tX2V2ZW50LT50YXNrLT5jb21tLCBzaXplb2YoY29tbSkpOwoJc2l6ZSA9IEFMSUdOKHN0cmxlbihjb21tKSsxLCBzaXplb2YodTY0KSk7CgoJY29tbV9ldmVudC0+Y29tbSA9IGNvbW07Cgljb21tX2V2ZW50LT5jb21tX3NpemUgPSBzaXplOwoKCWNvbW1fZXZlbnQtPmV2ZW50X2lkLmhlYWRlci5zaXplID0gc2l6ZW9mKGNvbW1fZXZlbnQtPmV2ZW50X2lkKSArIHNpemU7CglyY3VfcmVhZF9sb2NrKCk7CglsaXN0X2Zvcl9lYWNoX2VudHJ5X3JjdShwbXUsICZwbXVzLCBlbnRyeSkgewoJCWNwdWN0eCA9IGdldF9jcHVfcHRyKHBtdS0+cG11X2NwdV9jb250ZXh0KTsKCQlpZiAoY3B1Y3R4LT5hY3RpdmVfcG11ICE9IHBtdSkKCQkJZ290byBuZXh0OwoJCXBlcmZfZXZlbnRfY29tbV9jdHgoJmNwdWN0eC0+Y3R4LCBjb21tX2V2ZW50KTsKCgkJY3R4biA9IHBtdS0+dGFza19jdHhfbnI7CgkJaWYgKGN0eG4gPCAwKQoJCQlnb3RvIG5leHQ7CgoJCWN0eCA9IHJjdV9kZXJlZmVyZW5jZShjdXJyZW50LT5wZXJmX2V2ZW50X2N0eHBbY3R4bl0pOwoJCWlmIChjdHgpCgkJCXBlcmZfZXZlbnRfY29tbV9jdHgoY3R4LCBjb21tX2V2ZW50KTsKbmV4dDoKCQlwdXRfY3B1X3B0cihwbXUtPnBtdV9jcHVfY29udGV4dCk7Cgl9CglyY3VfcmVhZF91bmxvY2soKTsKfQoKdm9pZCBwZXJmX2V2ZW50X2NvbW0oc3RydWN0IHRhc2tfc3RydWN0ICp0YXNrKQp7CglzdHJ1Y3QgcGVyZl9jb21tX2V2ZW50IGNvbW1fZXZlbnQ7CglzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0ICpjdHg7CglpbnQgY3R4bjsKCglmb3JfZWFjaF90YXNrX2NvbnRleHRfbnIoY3R4bikgewoJCWN0eCA9IHRhc2stPnBlcmZfZXZlbnRfY3R4cFtjdHhuXTsKCQlpZiAoIWN0eCkKCQkJY29udGludWU7CgoJCXBlcmZfZXZlbnRfZW5hYmxlX29uX2V4ZWMoY3R4KTsKCX0KCglpZiAoIWF0b21pY19yZWFkKCZucl9jb21tX2V2ZW50cykpCgkJcmV0dXJuOwoKCWNvbW1fZXZlbnQgPSAoc3RydWN0IHBlcmZfY29tbV9ldmVudCl7CgkJLnRhc2sJPSB0YXNrLAoJCS8qIC5jb21tICAgICAgKi8KCQkvKiAuY29tbV9zaXplICovCgkJLmV2ZW50X2lkICA9IHsKCQkJLmhlYWRlciA9IHsKCQkJCS50eXBlID0gUEVSRl9SRUNPUkRfQ09NTSwKCQkJCS5taXNjID0gMCwKCQkJCS8qIC5zaXplICovCgkJCX0sCgkJCS8qIC5waWQgKi8KCQkJLyogLnRpZCAqLwoJCX0sCgl9OwoKCXBlcmZfZXZlbnRfY29tbV9ldmVudCgmY29tbV9ldmVudCk7Cn0KCi8qCiAqIG1tYXAgdHJhY2tpbmcKICovCgpzdHJ1Y3QgcGVyZl9tbWFwX2V2ZW50IHsKCXN0cnVjdCB2bV9hcmVhX3N0cnVjdAkqdm1hOwoKCWNvbnN0IGNoYXIJCSpmaWxlX25hbWU7CglpbnQJCQlmaWxlX3NpemU7CgoJc3RydWN0IHsKCQlzdHJ1Y3QgcGVyZl9ldmVudF9oZWFkZXIJaGVhZGVyOwoKCQl1MzIJCQkJcGlkOwoJCXUzMgkJCQl0aWQ7CgkJdTY0CQkJCXN0YXJ0OwoJCXU2NAkJCQlsZW47CgkJdTY0CQkJCXBnb2ZmOwoJfSBldmVudF9pZDsKfTsKCnN0YXRpYyB2b2lkIHBlcmZfZXZlbnRfbW1hcF9vdXRwdXQoc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50LAoJCQkJICAgICBzdHJ1Y3QgcGVyZl9tbWFwX2V2ZW50ICptbWFwX2V2ZW50KQp7CglzdHJ1Y3QgcGVyZl9vdXRwdXRfaGFuZGxlIGhhbmRsZTsKCXN0cnVjdCBwZXJmX3NhbXBsZV9kYXRhIHNhbXBsZTsKCWludCBzaXplID0gbW1hcF9ldmVudC0+ZXZlbnRfaWQuaGVhZGVyLnNpemU7CglpbnQgcmV0OwoKCXBlcmZfZXZlbnRfaGVhZGVyX19pbml0X2lkKCZtbWFwX2V2ZW50LT5ldmVudF9pZC5oZWFkZXIsICZzYW1wbGUsIGV2ZW50KTsKCXJldCA9IHBlcmZfb3V0cHV0X2JlZ2luKCZoYW5kbGUsIGV2ZW50LAoJCQkJbW1hcF9ldmVudC0+ZXZlbnRfaWQuaGVhZGVyLnNpemUsIDAsIDApOwoJaWYgKHJldCkKCQlnb3RvIG91dDsKCgltbWFwX2V2ZW50LT5ldmVudF9pZC5waWQgPSBwZXJmX2V2ZW50X3BpZChldmVudCwgY3VycmVudCk7CgltbWFwX2V2ZW50LT5ldmVudF9pZC50aWQgPSBwZXJmX2V2ZW50X3RpZChldmVudCwgY3VycmVudCk7CgoJcGVyZl9vdXRwdXRfcHV0KCZoYW5kbGUsIG1tYXBfZXZlbnQtPmV2ZW50X2lkKTsKCXBlcmZfb3V0cHV0X2NvcHkoJmhhbmRsZSwgbW1hcF9ldmVudC0+ZmlsZV9uYW1lLAoJCQkJICAgbW1hcF9ldmVudC0+ZmlsZV9zaXplKTsKCglwZXJmX2V2ZW50X19vdXRwdXRfaWRfc2FtcGxlKGV2ZW50LCAmaGFuZGxlLCAmc2FtcGxlKTsKCglwZXJmX291dHB1dF9lbmQoJmhhbmRsZSk7Cm91dDoKCW1tYXBfZXZlbnQtPmV2ZW50X2lkLmhlYWRlci5zaXplID0gc2l6ZTsKfQoKc3RhdGljIGludCBwZXJmX2V2ZW50X21tYXBfbWF0Y2goc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50LAoJCQkJICAgc3RydWN0IHBlcmZfbW1hcF9ldmVudCAqbW1hcF9ldmVudCwKCQkJCSAgIGludCBleGVjdXRhYmxlKQp7CglpZiAoZXZlbnQtPnN0YXRlIDwgUEVSRl9FVkVOVF9TVEFURV9JTkFDVElWRSkKCQlyZXR1cm4gMDsKCglpZiAoZXZlbnQtPmNwdSAhPSAtMSAmJiBldmVudC0+Y3B1ICE9IHNtcF9wcm9jZXNzb3JfaWQoKSkKCQlyZXR1cm4gMDsKCglpZiAoKCFleGVjdXRhYmxlICYmIGV2ZW50LT5hdHRyLm1tYXBfZGF0YSkgfHwKCSAgICAoZXhlY3V0YWJsZSAmJiBldmVudC0+YXR0ci5tbWFwKSkKCQlyZXR1cm4gMTsKCglyZXR1cm4gMDsKfQoKc3RhdGljIHZvaWQgcGVyZl9ldmVudF9tbWFwX2N0eChzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0ICpjdHgsCgkJCQkgIHN0cnVjdCBwZXJmX21tYXBfZXZlbnQgKm1tYXBfZXZlbnQsCgkJCQkgIGludCBleGVjdXRhYmxlKQp7CglzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQ7CgoJbGlzdF9mb3JfZWFjaF9lbnRyeV9yY3UoZXZlbnQsICZjdHgtPmV2ZW50X2xpc3QsIGV2ZW50X2VudHJ5KSB7CgkJaWYgKHBlcmZfZXZlbnRfbW1hcF9tYXRjaChldmVudCwgbW1hcF9ldmVudCwgZXhlY3V0YWJsZSkpCgkJCXBlcmZfZXZlbnRfbW1hcF9vdXRwdXQoZXZlbnQsIG1tYXBfZXZlbnQpOwoJfQp9CgpzdGF0aWMgdm9pZCBwZXJmX2V2ZW50X21tYXBfZXZlbnQoc3RydWN0IHBlcmZfbW1hcF9ldmVudCAqbW1hcF9ldmVudCkKewoJc3RydWN0IHBlcmZfY3B1X2NvbnRleHQgKmNwdWN0eDsKCXN0cnVjdCBwZXJmX2V2ZW50X2NvbnRleHQgKmN0eDsKCXN0cnVjdCB2bV9hcmVhX3N0cnVjdCAqdm1hID0gbW1hcF9ldmVudC0+dm1hOwoJc3RydWN0IGZpbGUgKmZpbGUgPSB2bWEtPnZtX2ZpbGU7Cgl1bnNpZ25lZCBpbnQgc2l6ZTsKCWNoYXIgdG1wWzE2XTsKCWNoYXIgKmJ1ZiA9IE5VTEw7Cgljb25zdCBjaGFyICpuYW1lOwoJc3RydWN0IHBtdSAqcG11OwoJaW50IGN0eG47CgoJbWVtc2V0KHRtcCwgMCwgc2l6ZW9mKHRtcCkpOwoKCWlmIChmaWxlKSB7CgkJLyoKCQkgKiBkX3BhdGggd29ya3MgZnJvbSB0aGUgZW5kIG9mIHRoZSBidWZmZXIgYmFja3dhcmRzLCBzbyB3ZQoJCSAqIG5lZWQgdG8gYWRkIGVub3VnaCB6ZXJvIGJ5dGVzIGFmdGVyIHRoZSBzdHJpbmcgdG8gaGFuZGxlCgkJICogdGhlIDY0Yml0IGFsaWdubWVudCB3ZSBkbyBsYXRlci4KCQkgKi8KCQlidWYgPSBremFsbG9jKFBBVEhfTUFYICsgc2l6ZW9mKHU2NCksIEdGUF9LRVJORUwpOwoJCWlmICghYnVmKSB7CgkJCW5hbWUgPSBzdHJuY3B5KHRtcCwgIi8vZW5vbWVtIiwgc2l6ZW9mKHRtcCkpOwoJCQlnb3RvIGdvdF9uYW1lOwoJCX0KCQluYW1lID0gZF9wYXRoKCZmaWxlLT5mX3BhdGgsIGJ1ZiwgUEFUSF9NQVgpOwoJCWlmIChJU19FUlIobmFtZSkpIHsKCQkJbmFtZSA9IHN0cm5jcHkodG1wLCAiLy90b29sb25nIiwgc2l6ZW9mKHRtcCkpOwoJCQlnb3RvIGdvdF9uYW1lOwoJCX0KCX0gZWxzZSB7CgkJaWYgKGFyY2hfdm1hX25hbWUobW1hcF9ldmVudC0+dm1hKSkgewoJCQluYW1lID0gc3RybmNweSh0bXAsIGFyY2hfdm1hX25hbWUobW1hcF9ldmVudC0+dm1hKSwKCQkJCSAgICAgICBzaXplb2YodG1wKSk7CgkJCWdvdG8gZ290X25hbWU7CgkJfQoKCQlpZiAoIXZtYS0+dm1fbW0pIHsKCQkJbmFtZSA9IHN0cm5jcHkodG1wLCAiW3Zkc29dIiwgc2l6ZW9mKHRtcCkpOwoJCQlnb3RvIGdvdF9uYW1lOwoJCX0gZWxzZSBpZiAodm1hLT52bV9zdGFydCA8PSB2bWEtPnZtX21tLT5zdGFydF9icmsgJiYKCQkJCXZtYS0+dm1fZW5kID49IHZtYS0+dm1fbW0tPmJyaykgewoJCQluYW1lID0gc3RybmNweSh0bXAsICJbaGVhcF0iLCBzaXplb2YodG1wKSk7CgkJCWdvdG8gZ290X25hbWU7CgkJfSBlbHNlIGlmICh2bWEtPnZtX3N0YXJ0IDw9IHZtYS0+dm1fbW0tPnN0YXJ0X3N0YWNrICYmCgkJCQl2bWEtPnZtX2VuZCA+PSB2bWEtPnZtX21tLT5zdGFydF9zdGFjaykgewoJCQluYW1lID0gc3RybmNweSh0bXAsICJbc3RhY2tdIiwgc2l6ZW9mKHRtcCkpOwoJCQlnb3RvIGdvdF9uYW1lOwoJCX0KCgkJbmFtZSA9IHN0cm5jcHkodG1wLCAiLy9hbm9uIiwgc2l6ZW9mKHRtcCkpOwoJCWdvdG8gZ290X25hbWU7Cgl9Cgpnb3RfbmFtZToKCXNpemUgPSBBTElHTihzdHJsZW4obmFtZSkrMSwgc2l6ZW9mKHU2NCkpOwoKCW1tYXBfZXZlbnQtPmZpbGVfbmFtZSA9IG5hbWU7CgltbWFwX2V2ZW50LT5maWxlX3NpemUgPSBzaXplOwoKCW1tYXBfZXZlbnQtPmV2ZW50X2lkLmhlYWRlci5zaXplID0gc2l6ZW9mKG1tYXBfZXZlbnQtPmV2ZW50X2lkKSArIHNpemU7CgoJcmN1X3JlYWRfbG9jaygpOwoJbGlzdF9mb3JfZWFjaF9lbnRyeV9yY3UocG11LCAmcG11cywgZW50cnkpIHsKCQljcHVjdHggPSBnZXRfY3B1X3B0cihwbXUtPnBtdV9jcHVfY29udGV4dCk7CgkJaWYgKGNwdWN0eC0+YWN0aXZlX3BtdSAhPSBwbXUpCgkJCWdvdG8gbmV4dDsKCQlwZXJmX2V2ZW50X21tYXBfY3R4KCZjcHVjdHgtPmN0eCwgbW1hcF9ldmVudCwKCQkJCQl2bWEtPnZtX2ZsYWdzICYgVk1fRVhFQyk7CgoJCWN0eG4gPSBwbXUtPnRhc2tfY3R4X25yOwoJCWlmIChjdHhuIDwgMCkKCQkJZ290byBuZXh0OwoKCQljdHggPSByY3VfZGVyZWZlcmVuY2UoY3VycmVudC0+cGVyZl9ldmVudF9jdHhwW2N0eG5dKTsKCQlpZiAoY3R4KSB7CgkJCXBlcmZfZXZlbnRfbW1hcF9jdHgoY3R4LCBtbWFwX2V2ZW50LAoJCQkJCXZtYS0+dm1fZmxhZ3MgJiBWTV9FWEVDKTsKCQl9Cm5leHQ6CgkJcHV0X2NwdV9wdHIocG11LT5wbXVfY3B1X2NvbnRleHQpOwoJfQoJcmN1X3JlYWRfdW5sb2NrKCk7CgoJa2ZyZWUoYnVmKTsKfQoKdm9pZCBwZXJmX2V2ZW50X21tYXAoc3RydWN0IHZtX2FyZWFfc3RydWN0ICp2bWEpCnsKCXN0cnVjdCBwZXJmX21tYXBfZXZlbnQgbW1hcF9ldmVudDsKCglpZiAoIWF0b21pY19yZWFkKCZucl9tbWFwX2V2ZW50cykpCgkJcmV0dXJuOwoKCW1tYXBfZXZlbnQgPSAoc3RydWN0IHBlcmZfbW1hcF9ldmVudCl7CgkJLnZtYQk9IHZtYSwKCQkvKiAuZmlsZV9uYW1lICovCgkJLyogLmZpbGVfc2l6ZSAqLwoJCS5ldmVudF9pZCAgPSB7CgkJCS5oZWFkZXIgPSB7CgkJCQkudHlwZSA9IFBFUkZfUkVDT1JEX01NQVAsCgkJCQkubWlzYyA9IFBFUkZfUkVDT1JEX01JU0NfVVNFUiwKCQkJCS8qIC5zaXplICovCgkJCX0sCgkJCS8qIC5waWQgKi8KCQkJLyogLnRpZCAqLwoJCQkuc3RhcnQgID0gdm1hLT52bV9zdGFydCwKCQkJLmxlbiAgICA9IHZtYS0+dm1fZW5kIC0gdm1hLT52bV9zdGFydCwKCQkJLnBnb2ZmICA9ICh1NjQpdm1hLT52bV9wZ29mZiA8PCBQQUdFX1NISUZULAoJCX0sCgl9OwoKCXBlcmZfZXZlbnRfbW1hcF9ldmVudCgmbW1hcF9ldmVudCk7Cn0KCi8qCiAqIElSUSB0aHJvdHRsZSBsb2dnaW5nCiAqLwoKc3RhdGljIHZvaWQgcGVyZl9sb2dfdGhyb3R0bGUoc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50LCBpbnQgZW5hYmxlKQp7CglzdHJ1Y3QgcGVyZl9vdXRwdXRfaGFuZGxlIGhhbmRsZTsKCXN0cnVjdCBwZXJmX3NhbXBsZV9kYXRhIHNhbXBsZTsKCWludCByZXQ7CgoJc3RydWN0IHsKCQlzdHJ1Y3QgcGVyZl9ldmVudF9oZWFkZXIJaGVhZGVyOwoJCXU2NAkJCQl0aW1lOwoJCXU2NAkJCQlpZDsKCQl1NjQJCQkJc3RyZWFtX2lkOwoJfSB0aHJvdHRsZV9ldmVudCA9IHsKCQkuaGVhZGVyID0gewoJCQkudHlwZSA9IFBFUkZfUkVDT1JEX1RIUk9UVExFLAoJCQkubWlzYyA9IDAsCgkJCS5zaXplID0gc2l6ZW9mKHRocm90dGxlX2V2ZW50KSwKCQl9LAoJCS50aW1lCQk9IHBlcmZfY2xvY2soKSwKCQkuaWQJCT0gcHJpbWFyeV9ldmVudF9pZChldmVudCksCgkJLnN0cmVhbV9pZAk9IGV2ZW50LT5pZCwKCX07CgoJaWYgKGVuYWJsZSkKCQl0aHJvdHRsZV9ldmVudC5oZWFkZXIudHlwZSA9IFBFUkZfUkVDT1JEX1VOVEhST1RUTEU7CgoJcGVyZl9ldmVudF9oZWFkZXJfX2luaXRfaWQoJnRocm90dGxlX2V2ZW50LmhlYWRlciwgJnNhbXBsZSwgZXZlbnQpOwoKCXJldCA9IHBlcmZfb3V0cHV0X2JlZ2luKCZoYW5kbGUsIGV2ZW50LAoJCQkJdGhyb3R0bGVfZXZlbnQuaGVhZGVyLnNpemUsIDEsIDApOwoJaWYgKHJldCkKCQlyZXR1cm47CgoJcGVyZl9vdXRwdXRfcHV0KCZoYW5kbGUsIHRocm90dGxlX2V2ZW50KTsKCXBlcmZfZXZlbnRfX291dHB1dF9pZF9zYW1wbGUoZXZlbnQsICZoYW5kbGUsICZzYW1wbGUpOwoJcGVyZl9vdXRwdXRfZW5kKCZoYW5kbGUpOwp9CgovKgogKiBHZW5lcmljIGV2ZW50IG92ZXJmbG93IGhhbmRsaW5nLCBzYW1wbGluZy4KICovCgpzdGF0aWMgaW50IF9fcGVyZl9ldmVudF9vdmVyZmxvdyhzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQsIGludCBubWksCgkJCQkgICBpbnQgdGhyb3R0bGUsIHN0cnVjdCBwZXJmX3NhbXBsZV9kYXRhICpkYXRhLAoJCQkJICAgc3RydWN0IHB0X3JlZ3MgKnJlZ3MpCnsKCWludCBldmVudHMgPSBhdG9taWNfcmVhZCgmZXZlbnQtPmV2ZW50X2xpbWl0KTsKCXN0cnVjdCBod19wZXJmX2V2ZW50ICpod2MgPSAmZXZlbnQtPmh3OwoJaW50IHJldCA9IDA7CgoJLyoKCSAqIE5vbi1zYW1wbGluZyBjb3VudGVycyBtaWdodCBzdGlsbCB1c2UgdGhlIFBNSSB0byBmb2xkIHNob3J0CgkgKiBoYXJkd2FyZSBjb3VudGVycywgaWdub3JlIHRob3NlLgoJICovCglpZiAodW5saWtlbHkoIWlzX3NhbXBsaW5nX2V2ZW50KGV2ZW50KSkpCgkJcmV0dXJuIDA7CgoJaWYgKCF0aHJvdHRsZSkgewoJCWh3Yy0+aW50ZXJydXB0cysrOwoJfSBlbHNlIHsKCQlpZiAoaHdjLT5pbnRlcnJ1cHRzICE9IE1BWF9JTlRFUlJVUFRTKSB7CgkJCWh3Yy0+aW50ZXJydXB0cysrOwoJCQlpZiAoSFogKiBod2MtPmludGVycnVwdHMgPgoJCQkJCSh1NjQpc3lzY3RsX3BlcmZfZXZlbnRfc2FtcGxlX3JhdGUpIHsKCQkJCWh3Yy0+aW50ZXJydXB0cyA9IE1BWF9JTlRFUlJVUFRTOwoJCQkJcGVyZl9sb2dfdGhyb3R0bGUoZXZlbnQsIDApOwoJCQkJcmV0ID0gMTsKCQkJfQoJCX0gZWxzZSB7CgkJCS8qCgkJCSAqIEtlZXAgcmUtZGlzYWJsaW5nIGV2ZW50cyBldmVuIHRob3VnaCBvbiB0aGUgcHJldmlvdXMKCQkJICogcGFzcyB3ZSBkaXNhYmxlZCBpdCAtIGp1c3QgaW4gY2FzZSB3ZSByYWNlZCB3aXRoIGEKCQkJICogc2NoZWQtaW4gYW5kIHRoZSBldmVudCBnb3QgZW5hYmxlZCBhZ2FpbjoKCQkJICovCgkJCXJldCA9IDE7CgkJfQoJfQoKCWlmIChldmVudC0+YXR0ci5mcmVxKSB7CgkJdTY0IG5vdyA9IHBlcmZfY2xvY2soKTsKCQlzNjQgZGVsdGEgPSBub3cgLSBod2MtPmZyZXFfdGltZV9zdGFtcDsKCgkJaHdjLT5mcmVxX3RpbWVfc3RhbXAgPSBub3c7CgoJCWlmIChkZWx0YSA+IDAgJiYgZGVsdGEgPCAyKlRJQ0tfTlNFQykKCQkJcGVyZl9hZGp1c3RfcGVyaW9kKGV2ZW50LCBkZWx0YSwgaHdjLT5sYXN0X3BlcmlvZCk7Cgl9CgoJLyoKCSAqIFhYWCBldmVudF9saW1pdCBtaWdodCBub3QgcXVpdGUgd29yayBhcyBleHBlY3RlZCBvbiBpbmhlcml0ZWQKCSAqIGV2ZW50cwoJICovCgoJZXZlbnQtPnBlbmRpbmdfa2lsbCA9IFBPTExfSU47CglpZiAoZXZlbnRzICYmIGF0b21pY19kZWNfYW5kX3Rlc3QoJmV2ZW50LT5ldmVudF9saW1pdCkpIHsKCQlyZXQgPSAxOwoJCWV2ZW50LT5wZW5kaW5nX2tpbGwgPSBQT0xMX0hVUDsKCQlpZiAobm1pKSB7CgkJCWV2ZW50LT5wZW5kaW5nX2Rpc2FibGUgPSAxOwoJCQlpcnFfd29ya19xdWV1ZSgmZXZlbnQtPnBlbmRpbmcpOwoJCX0gZWxzZQoJCQlwZXJmX2V2ZW50X2Rpc2FibGUoZXZlbnQpOwoJfQoKCWlmIChldmVudC0+b3ZlcmZsb3dfaGFuZGxlcikKCQlldmVudC0+b3ZlcmZsb3dfaGFuZGxlcihldmVudCwgbm1pLCBkYXRhLCByZWdzKTsKCWVsc2UKCQlwZXJmX2V2ZW50X291dHB1dChldmVudCwgbm1pLCBkYXRhLCByZWdzKTsKCglyZXR1cm4gcmV0Owp9CgppbnQgcGVyZl9ldmVudF9vdmVyZmxvdyhzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQsIGludCBubWksCgkJCSAgc3RydWN0IHBlcmZfc2FtcGxlX2RhdGEgKmRhdGEsCgkJCSAgc3RydWN0IHB0X3JlZ3MgKnJlZ3MpCnsKCXJldHVybiBfX3BlcmZfZXZlbnRfb3ZlcmZsb3coZXZlbnQsIG5taSwgMSwgZGF0YSwgcmVncyk7Cn0KCi8qCiAqIEdlbmVyaWMgc29mdHdhcmUgZXZlbnQgaW5mcmFzdHJ1Y3R1cmUKICovCgpzdHJ1Y3Qgc3dldmVudF9odGFibGUgewoJc3RydWN0IHN3ZXZlbnRfaGxpc3QJCSpzd2V2ZW50X2hsaXN0OwoJc3RydWN0IG11dGV4CQkJaGxpc3RfbXV0ZXg7CglpbnQJCQkJaGxpc3RfcmVmY291bnQ7CgoJLyogUmVjdXJzaW9uIGF2b2lkYW5jZSBpbiBlYWNoIGNvbnRleHRzICovCglpbnQJCQkJcmVjdXJzaW9uW1BFUkZfTlJfQ09OVEVYVFNdOwp9OwoKc3RhdGljIERFRklORV9QRVJfQ1BVKHN0cnVjdCBzd2V2ZW50X2h0YWJsZSwgc3dldmVudF9odGFibGUpOwoKLyoKICogV2UgZGlyZWN0bHkgaW5jcmVtZW50IGV2ZW50LT5jb3VudCBhbmQga2VlcCBhIHNlY29uZCB2YWx1ZSBpbgogKiBldmVudC0+aHcucGVyaW9kX2xlZnQgdG8gY291bnQgaW50ZXJ2YWxzLiBUaGlzIHBlcmlvZCBldmVudAogKiBpcyBrZXB0IGluIHRoZSByYW5nZSBbLXNhbXBsZV9wZXJpb2QsIDBdIHNvIHRoYXQgd2UgY2FuIHVzZSB0aGUKICogc2lnbiBhcyB0cmlnZ2VyLgogKi8KCnN0YXRpYyB1NjQgcGVyZl9zd2V2ZW50X3NldF9wZXJpb2Qoc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50KQp7CglzdHJ1Y3QgaHdfcGVyZl9ldmVudCAqaHdjID0gJmV2ZW50LT5odzsKCXU2NCBwZXJpb2QgPSBod2MtPmxhc3RfcGVyaW9kOwoJdTY0IG5yLCBvZmZzZXQ7CglzNjQgb2xkLCB2YWw7CgoJaHdjLT5sYXN0X3BlcmlvZCA9IGh3Yy0+c2FtcGxlX3BlcmlvZDsKCmFnYWluOgoJb2xkID0gdmFsID0gbG9jYWw2NF9yZWFkKCZod2MtPnBlcmlvZF9sZWZ0KTsKCWlmICh2YWwgPCAwKQoJCXJldHVybiAwOwoKCW5yID0gZGl2NjRfdTY0KHBlcmlvZCArIHZhbCwgcGVyaW9kKTsKCW9mZnNldCA9IG5yICogcGVyaW9kOwoJdmFsIC09IG9mZnNldDsKCWlmIChsb2NhbDY0X2NtcHhjaGcoJmh3Yy0+cGVyaW9kX2xlZnQsIG9sZCwgdmFsKSAhPSBvbGQpCgkJZ290byBhZ2FpbjsKCglyZXR1cm4gbnI7Cn0KCnN0YXRpYyB2b2lkIHBlcmZfc3dldmVudF9vdmVyZmxvdyhzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQsIHU2NCBvdmVyZmxvdywKCQkJCSAgICBpbnQgbm1pLCBzdHJ1Y3QgcGVyZl9zYW1wbGVfZGF0YSAqZGF0YSwKCQkJCSAgICBzdHJ1Y3QgcHRfcmVncyAqcmVncykKewoJc3RydWN0IGh3X3BlcmZfZXZlbnQgKmh3YyA9ICZldmVudC0+aHc7CglpbnQgdGhyb3R0bGUgPSAwOwoKCWRhdGEtPnBlcmlvZCA9IGV2ZW50LT5ody5sYXN0X3BlcmlvZDsKCWlmICghb3ZlcmZsb3cpCgkJb3ZlcmZsb3cgPSBwZXJmX3N3ZXZlbnRfc2V0X3BlcmlvZChldmVudCk7CgoJaWYgKGh3Yy0+aW50ZXJydXB0cyA9PSBNQVhfSU5URVJSVVBUUykKCQlyZXR1cm47CgoJZm9yICg7IG92ZXJmbG93OyBvdmVyZmxvdy0tKSB7CgkJaWYgKF9fcGVyZl9ldmVudF9vdmVyZmxvdyhldmVudCwgbm1pLCB0aHJvdHRsZSwKCQkJCQkgICAgZGF0YSwgcmVncykpIHsKCQkJLyoKCQkJICogV2UgaW5oaWJpdCB0aGUgb3ZlcmZsb3cgZnJvbSBoYXBwZW5pbmcgd2hlbgoJCQkgKiBod2MtPmludGVycnVwdHMgPT0gTUFYX0lOVEVSUlVQVFMuCgkJCSAqLwoJCQlicmVhazsKCQl9CgkJdGhyb3R0bGUgPSAxOwoJfQp9CgpzdGF0aWMgdm9pZCBwZXJmX3N3ZXZlbnRfZXZlbnQoc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50LCB1NjQgbnIsCgkJCSAgICAgICBpbnQgbm1pLCBzdHJ1Y3QgcGVyZl9zYW1wbGVfZGF0YSAqZGF0YSwKCQkJICAgICAgIHN0cnVjdCBwdF9yZWdzICpyZWdzKQp7CglzdHJ1Y3QgaHdfcGVyZl9ldmVudCAqaHdjID0gJmV2ZW50LT5odzsKCglsb2NhbDY0X2FkZChuciwgJmV2ZW50LT5jb3VudCk7CgoJaWYgKCFyZWdzKQoJCXJldHVybjsKCglpZiAoIWlzX3NhbXBsaW5nX2V2ZW50KGV2ZW50KSkKCQlyZXR1cm47CgoJaWYgKG5yID09IDEgJiYgaHdjLT5zYW1wbGVfcGVyaW9kID09IDEgJiYgIWV2ZW50LT5hdHRyLmZyZXEpCgkJcmV0dXJuIHBlcmZfc3dldmVudF9vdmVyZmxvdyhldmVudCwgMSwgbm1pLCBkYXRhLCByZWdzKTsKCglpZiAobG9jYWw2NF9hZGRfbmVnYXRpdmUobnIsICZod2MtPnBlcmlvZF9sZWZ0KSkKCQlyZXR1cm47CgoJcGVyZl9zd2V2ZW50X292ZXJmbG93KGV2ZW50LCAwLCBubWksIGRhdGEsIHJlZ3MpOwp9CgpzdGF0aWMgaW50IHBlcmZfZXhjbHVkZV9ldmVudChzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQsCgkJCSAgICAgIHN0cnVjdCBwdF9yZWdzICpyZWdzKQp7CglpZiAoZXZlbnQtPmh3LnN0YXRlICYgUEVSRl9IRVNfU1RPUFBFRCkKCQlyZXR1cm4gMDsKCglpZiAocmVncykgewoJCWlmIChldmVudC0+YXR0ci5leGNsdWRlX3VzZXIgJiYgdXNlcl9tb2RlKHJlZ3MpKQoJCQlyZXR1cm4gMTsKCgkJaWYgKGV2ZW50LT5hdHRyLmV4Y2x1ZGVfa2VybmVsICYmICF1c2VyX21vZGUocmVncykpCgkJCXJldHVybiAxOwoJfQoKCXJldHVybiAwOwp9CgpzdGF0aWMgaW50IHBlcmZfc3dldmVudF9tYXRjaChzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQsCgkJCQllbnVtIHBlcmZfdHlwZV9pZCB0eXBlLAoJCQkJdTMyIGV2ZW50X2lkLAoJCQkJc3RydWN0IHBlcmZfc2FtcGxlX2RhdGEgKmRhdGEsCgkJCQlzdHJ1Y3QgcHRfcmVncyAqcmVncykKewoJaWYgKGV2ZW50LT5hdHRyLnR5cGUgIT0gdHlwZSkKCQlyZXR1cm4gMDsKCglpZiAoZXZlbnQtPmF0dHIuY29uZmlnICE9IGV2ZW50X2lkKQoJCXJldHVybiAwOwoKCWlmIChwZXJmX2V4Y2x1ZGVfZXZlbnQoZXZlbnQsIHJlZ3MpKQoJCXJldHVybiAwOwoKCXJldHVybiAxOwp9CgpzdGF0aWMgaW5saW5lIHU2NCBzd2V2ZW50X2hhc2godTY0IHR5cGUsIHUzMiBldmVudF9pZCkKewoJdTY0IHZhbCA9IGV2ZW50X2lkIHwgKHR5cGUgPDwgMzIpOwoKCXJldHVybiBoYXNoXzY0KHZhbCwgU1dFVkVOVF9ITElTVF9CSVRTKTsKfQoKc3RhdGljIGlubGluZSBzdHJ1Y3QgaGxpc3RfaGVhZCAqCl9fZmluZF9zd2V2ZW50X2hlYWQoc3RydWN0IHN3ZXZlbnRfaGxpc3QgKmhsaXN0LCB1NjQgdHlwZSwgdTMyIGV2ZW50X2lkKQp7Cgl1NjQgaGFzaCA9IHN3ZXZlbnRfaGFzaCh0eXBlLCBldmVudF9pZCk7CgoJcmV0dXJuICZobGlzdC0+aGVhZHNbaGFzaF07Cn0KCi8qIEZvciB0aGUgcmVhZCBzaWRlOiBldmVudHMgd2hlbiB0aGV5IHRyaWdnZXIgKi8Kc3RhdGljIGlubGluZSBzdHJ1Y3QgaGxpc3RfaGVhZCAqCmZpbmRfc3dldmVudF9oZWFkX3JjdShzdHJ1Y3Qgc3dldmVudF9odGFibGUgKnN3aGFzaCwgdTY0IHR5cGUsIHUzMiBldmVudF9pZCkKewoJc3RydWN0IHN3ZXZlbnRfaGxpc3QgKmhsaXN0OwoKCWhsaXN0ID0gcmN1X2RlcmVmZXJlbmNlKHN3aGFzaC0+c3dldmVudF9obGlzdCk7CglpZiAoIWhsaXN0KQoJCXJldHVybiBOVUxMOwoKCXJldHVybiBfX2ZpbmRfc3dldmVudF9oZWFkKGhsaXN0LCB0eXBlLCBldmVudF9pZCk7Cn0KCi8qIEZvciB0aGUgZXZlbnQgaGVhZCBpbnNlcnRpb24gYW5kIHJlbW92YWwgaW4gdGhlIGhsaXN0ICovCnN0YXRpYyBpbmxpbmUgc3RydWN0IGhsaXN0X2hlYWQgKgpmaW5kX3N3ZXZlbnRfaGVhZChzdHJ1Y3Qgc3dldmVudF9odGFibGUgKnN3aGFzaCwgc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50KQp7CglzdHJ1Y3Qgc3dldmVudF9obGlzdCAqaGxpc3Q7Cgl1MzIgZXZlbnRfaWQgPSBldmVudC0+YXR0ci5jb25maWc7Cgl1NjQgdHlwZSA9IGV2ZW50LT5hdHRyLnR5cGU7CgoJLyoKCSAqIEV2ZW50IHNjaGVkdWxpbmcgaXMgYWx3YXlzIHNlcmlhbGl6ZWQgYWdhaW5zdCBobGlzdCBhbGxvY2F0aW9uCgkgKiBhbmQgcmVsZWFzZS4gV2hpY2ggbWFrZXMgdGhlIHByb3RlY3RlZCB2ZXJzaW9uIHN1aXRhYmxlIGhlcmUuCgkgKiBUaGUgY29udGV4dCBsb2NrIGd1YXJhbnRlZXMgdGhhdC4KCSAqLwoJaGxpc3QgPSByY3VfZGVyZWZlcmVuY2VfcHJvdGVjdGVkKHN3aGFzaC0+c3dldmVudF9obGlzdCwKCQkJCQkgIGxvY2tkZXBfaXNfaGVsZCgmZXZlbnQtPmN0eC0+bG9jaykpOwoJaWYgKCFobGlzdCkKCQlyZXR1cm4gTlVMTDsKCglyZXR1cm4gX19maW5kX3N3ZXZlbnRfaGVhZChobGlzdCwgdHlwZSwgZXZlbnRfaWQpOwp9CgpzdGF0aWMgdm9pZCBkb19wZXJmX3N3X2V2ZW50KGVudW0gcGVyZl90eXBlX2lkIHR5cGUsIHUzMiBldmVudF9pZCwKCQkJCSAgICB1NjQgbnIsIGludCBubWksCgkJCQkgICAgc3RydWN0IHBlcmZfc2FtcGxlX2RhdGEgKmRhdGEsCgkJCQkgICAgc3RydWN0IHB0X3JlZ3MgKnJlZ3MpCnsKCXN0cnVjdCBzd2V2ZW50X2h0YWJsZSAqc3doYXNoID0gJl9fZ2V0X2NwdV92YXIoc3dldmVudF9odGFibGUpOwoJc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50OwoJc3RydWN0IGhsaXN0X25vZGUgKm5vZGU7CglzdHJ1Y3QgaGxpc3RfaGVhZCAqaGVhZDsKCglyY3VfcmVhZF9sb2NrKCk7CgloZWFkID0gZmluZF9zd2V2ZW50X2hlYWRfcmN1KHN3aGFzaCwgdHlwZSwgZXZlbnRfaWQpOwoJaWYgKCFoZWFkKQoJCWdvdG8gZW5kOwoKCWhsaXN0X2Zvcl9lYWNoX2VudHJ5X3JjdShldmVudCwgbm9kZSwgaGVhZCwgaGxpc3RfZW50cnkpIHsKCQlpZiAocGVyZl9zd2V2ZW50X21hdGNoKGV2ZW50LCB0eXBlLCBldmVudF9pZCwgZGF0YSwgcmVncykpCgkJCXBlcmZfc3dldmVudF9ldmVudChldmVudCwgbnIsIG5taSwgZGF0YSwgcmVncyk7Cgl9CmVuZDoKCXJjdV9yZWFkX3VubG9jaygpOwp9CgppbnQgcGVyZl9zd2V2ZW50X2dldF9yZWN1cnNpb25fY29udGV4dCh2b2lkKQp7CglzdHJ1Y3Qgc3dldmVudF9odGFibGUgKnN3aGFzaCA9ICZfX2dldF9jcHVfdmFyKHN3ZXZlbnRfaHRhYmxlKTsKCglyZXR1cm4gZ2V0X3JlY3Vyc2lvbl9jb250ZXh0KHN3aGFzaC0+cmVjdXJzaW9uKTsKfQpFWFBPUlRfU1lNQk9MX0dQTChwZXJmX3N3ZXZlbnRfZ2V0X3JlY3Vyc2lvbl9jb250ZXh0KTsKCnZvaWQgaW5saW5lIHBlcmZfc3dldmVudF9wdXRfcmVjdXJzaW9uX2NvbnRleHQoaW50IHJjdHgpCnsKCXN0cnVjdCBzd2V2ZW50X2h0YWJsZSAqc3doYXNoID0gJl9fZ2V0X2NwdV92YXIoc3dldmVudF9odGFibGUpOwoKCXB1dF9yZWN1cnNpb25fY29udGV4dChzd2hhc2gtPnJlY3Vyc2lvbiwgcmN0eCk7Cn0KCnZvaWQgX19wZXJmX3N3X2V2ZW50KHUzMiBldmVudF9pZCwgdTY0IG5yLCBpbnQgbm1pLAoJCQkgICAgc3RydWN0IHB0X3JlZ3MgKnJlZ3MsIHU2NCBhZGRyKQp7CglzdHJ1Y3QgcGVyZl9zYW1wbGVfZGF0YSBkYXRhOwoJaW50IHJjdHg7CgoJcHJlZW1wdF9kaXNhYmxlX25vdHJhY2UoKTsKCXJjdHggPSBwZXJmX3N3ZXZlbnRfZ2V0X3JlY3Vyc2lvbl9jb250ZXh0KCk7CglpZiAocmN0eCA8IDApCgkJcmV0dXJuOwoKCXBlcmZfc2FtcGxlX2RhdGFfaW5pdCgmZGF0YSwgYWRkcik7CgoJZG9fcGVyZl9zd19ldmVudChQRVJGX1RZUEVfU09GVFdBUkUsIGV2ZW50X2lkLCBuciwgbm1pLCAmZGF0YSwgcmVncyk7CgoJcGVyZl9zd2V2ZW50X3B1dF9yZWN1cnNpb25fY29udGV4dChyY3R4KTsKCXByZWVtcHRfZW5hYmxlX25vdHJhY2UoKTsKfQoKc3RhdGljIHZvaWQgcGVyZl9zd2V2ZW50X3JlYWQoc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50KQp7Cn0KCnN0YXRpYyBpbnQgcGVyZl9zd2V2ZW50X2FkZChzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQsIGludCBmbGFncykKewoJc3RydWN0IHN3ZXZlbnRfaHRhYmxlICpzd2hhc2ggPSAmX19nZXRfY3B1X3Zhcihzd2V2ZW50X2h0YWJsZSk7CglzdHJ1Y3QgaHdfcGVyZl9ldmVudCAqaHdjID0gJmV2ZW50LT5odzsKCXN0cnVjdCBobGlzdF9oZWFkICpoZWFkOwoKCWlmIChpc19zYW1wbGluZ19ldmVudChldmVudCkpIHsKCQlod2MtPmxhc3RfcGVyaW9kID0gaHdjLT5zYW1wbGVfcGVyaW9kOwoJCXBlcmZfc3dldmVudF9zZXRfcGVyaW9kKGV2ZW50KTsKCX0KCglod2MtPnN0YXRlID0gIShmbGFncyAmIFBFUkZfRUZfU1RBUlQpOwoKCWhlYWQgPSBmaW5kX3N3ZXZlbnRfaGVhZChzd2hhc2gsIGV2ZW50KTsKCWlmIChXQVJOX09OX09OQ0UoIWhlYWQpKQoJCXJldHVybiAtRUlOVkFMOwoKCWhsaXN0X2FkZF9oZWFkX3JjdSgmZXZlbnQtPmhsaXN0X2VudHJ5LCBoZWFkKTsKCglyZXR1cm4gMDsKfQoKc3RhdGljIHZvaWQgcGVyZl9zd2V2ZW50X2RlbChzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQsIGludCBmbGFncykKewoJaGxpc3RfZGVsX3JjdSgmZXZlbnQtPmhsaXN0X2VudHJ5KTsKfQoKc3RhdGljIHZvaWQgcGVyZl9zd2V2ZW50X3N0YXJ0KHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCwgaW50IGZsYWdzKQp7CglldmVudC0+aHcuc3RhdGUgPSAwOwp9CgpzdGF0aWMgdm9pZCBwZXJmX3N3ZXZlbnRfc3RvcChzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQsIGludCBmbGFncykKewoJZXZlbnQtPmh3LnN0YXRlID0gUEVSRl9IRVNfU1RPUFBFRDsKfQoKLyogRGVyZWYgdGhlIGhsaXN0IGZyb20gdGhlIHVwZGF0ZSBzaWRlICovCnN0YXRpYyBpbmxpbmUgc3RydWN0IHN3ZXZlbnRfaGxpc3QgKgpzd2V2ZW50X2hsaXN0X2RlcmVmKHN0cnVjdCBzd2V2ZW50X2h0YWJsZSAqc3doYXNoKQp7CglyZXR1cm4gcmN1X2RlcmVmZXJlbmNlX3Byb3RlY3RlZChzd2hhc2gtPnN3ZXZlbnRfaGxpc3QsCgkJCQkJIGxvY2tkZXBfaXNfaGVsZCgmc3doYXNoLT5obGlzdF9tdXRleCkpOwp9CgpzdGF0aWMgdm9pZCBzd2V2ZW50X2hsaXN0X3JlbGVhc2VfcmN1KHN0cnVjdCByY3VfaGVhZCAqcmN1X2hlYWQpCnsKCXN0cnVjdCBzd2V2ZW50X2hsaXN0ICpobGlzdDsKCglobGlzdCA9IGNvbnRhaW5lcl9vZihyY3VfaGVhZCwgc3RydWN0IHN3ZXZlbnRfaGxpc3QsIHJjdV9oZWFkKTsKCWtmcmVlKGhsaXN0KTsKfQoKc3RhdGljIHZvaWQgc3dldmVudF9obGlzdF9yZWxlYXNlKHN0cnVjdCBzd2V2ZW50X2h0YWJsZSAqc3doYXNoKQp7CglzdHJ1Y3Qgc3dldmVudF9obGlzdCAqaGxpc3QgPSBzd2V2ZW50X2hsaXN0X2RlcmVmKHN3aGFzaCk7CgoJaWYgKCFobGlzdCkKCQlyZXR1cm47CgoJcmN1X2Fzc2lnbl9wb2ludGVyKHN3aGFzaC0+c3dldmVudF9obGlzdCwgTlVMTCk7CgljYWxsX3JjdSgmaGxpc3QtPnJjdV9oZWFkLCBzd2V2ZW50X2hsaXN0X3JlbGVhc2VfcmN1KTsKfQoKc3RhdGljIHZvaWQgc3dldmVudF9obGlzdF9wdXRfY3B1KHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCwgaW50IGNwdSkKewoJc3RydWN0IHN3ZXZlbnRfaHRhYmxlICpzd2hhc2ggPSAmcGVyX2NwdShzd2V2ZW50X2h0YWJsZSwgY3B1KTsKCgltdXRleF9sb2NrKCZzd2hhc2gtPmhsaXN0X211dGV4KTsKCglpZiAoIS0tc3doYXNoLT5obGlzdF9yZWZjb3VudCkKCQlzd2V2ZW50X2hsaXN0X3JlbGVhc2Uoc3doYXNoKTsKCgltdXRleF91bmxvY2soJnN3aGFzaC0+aGxpc3RfbXV0ZXgpOwp9CgpzdGF0aWMgdm9pZCBzd2V2ZW50X2hsaXN0X3B1dChzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQpCnsKCWludCBjcHU7CgoJaWYgKGV2ZW50LT5jcHUgIT0gLTEpIHsKCQlzd2V2ZW50X2hsaXN0X3B1dF9jcHUoZXZlbnQsIGV2ZW50LT5jcHUpOwoJCXJldHVybjsKCX0KCglmb3JfZWFjaF9wb3NzaWJsZV9jcHUoY3B1KQoJCXN3ZXZlbnRfaGxpc3RfcHV0X2NwdShldmVudCwgY3B1KTsKfQoKc3RhdGljIGludCBzd2V2ZW50X2hsaXN0X2dldF9jcHUoc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50LCBpbnQgY3B1KQp7CglzdHJ1Y3Qgc3dldmVudF9odGFibGUgKnN3aGFzaCA9ICZwZXJfY3B1KHN3ZXZlbnRfaHRhYmxlLCBjcHUpOwoJaW50IGVyciA9IDA7CgoJbXV0ZXhfbG9jaygmc3doYXNoLT5obGlzdF9tdXRleCk7CgoJaWYgKCFzd2V2ZW50X2hsaXN0X2RlcmVmKHN3aGFzaCkgJiYgY3B1X29ubGluZShjcHUpKSB7CgkJc3RydWN0IHN3ZXZlbnRfaGxpc3QgKmhsaXN0OwoKCQlobGlzdCA9IGt6YWxsb2Moc2l6ZW9mKCpobGlzdCksIEdGUF9LRVJORUwpOwoJCWlmICghaGxpc3QpIHsKCQkJZXJyID0gLUVOT01FTTsKCQkJZ290byBleGl0OwoJCX0KCQlyY3VfYXNzaWduX3BvaW50ZXIoc3doYXNoLT5zd2V2ZW50X2hsaXN0LCBobGlzdCk7Cgl9Cglzd2hhc2gtPmhsaXN0X3JlZmNvdW50Kys7CmV4aXQ6CgltdXRleF91bmxvY2soJnN3aGFzaC0+aGxpc3RfbXV0ZXgpOwoKCXJldHVybiBlcnI7Cn0KCnN0YXRpYyBpbnQgc3dldmVudF9obGlzdF9nZXQoc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50KQp7CglpbnQgZXJyOwoJaW50IGNwdSwgZmFpbGVkX2NwdTsKCglpZiAoZXZlbnQtPmNwdSAhPSAtMSkKCQlyZXR1cm4gc3dldmVudF9obGlzdF9nZXRfY3B1KGV2ZW50LCBldmVudC0+Y3B1KTsKCglnZXRfb25saW5lX2NwdXMoKTsKCWZvcl9lYWNoX3Bvc3NpYmxlX2NwdShjcHUpIHsKCQllcnIgPSBzd2V2ZW50X2hsaXN0X2dldF9jcHUoZXZlbnQsIGNwdSk7CgkJaWYgKGVycikgewoJCQlmYWlsZWRfY3B1ID0gY3B1OwoJCQlnb3RvIGZhaWw7CgkJfQoJfQoJcHV0X29ubGluZV9jcHVzKCk7CgoJcmV0dXJuIDA7CmZhaWw6Cglmb3JfZWFjaF9wb3NzaWJsZV9jcHUoY3B1KSB7CgkJaWYgKGNwdSA9PSBmYWlsZWRfY3B1KQoJCQlicmVhazsKCQlzd2V2ZW50X2hsaXN0X3B1dF9jcHUoZXZlbnQsIGNwdSk7Cgl9CgoJcHV0X29ubGluZV9jcHVzKCk7CglyZXR1cm4gZXJyOwp9CgphdG9taWNfdCBwZXJmX3N3ZXZlbnRfZW5hYmxlZFtQRVJGX0NPVU5UX1NXX01BWF07CgpzdGF0aWMgdm9pZCBzd19wZXJmX2V2ZW50X2Rlc3Ryb3koc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50KQp7Cgl1NjQgZXZlbnRfaWQgPSBldmVudC0+YXR0ci5jb25maWc7CgoJV0FSTl9PTihldmVudC0+cGFyZW50KTsKCglqdW1wX2xhYmVsX2RlYygmcGVyZl9zd2V2ZW50X2VuYWJsZWRbZXZlbnRfaWRdKTsKCXN3ZXZlbnRfaGxpc3RfcHV0KGV2ZW50KTsKfQoKc3RhdGljIGludCBwZXJmX3N3ZXZlbnRfaW5pdChzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQpCnsKCWludCBldmVudF9pZCA9IGV2ZW50LT5hdHRyLmNvbmZpZzsKCglpZiAoZXZlbnQtPmF0dHIudHlwZSAhPSBQRVJGX1RZUEVfU09GVFdBUkUpCgkJcmV0dXJuIC1FTk9FTlQ7CgoJc3dpdGNoIChldmVudF9pZCkgewoJY2FzZSBQRVJGX0NPVU5UX1NXX0NQVV9DTE9DSzoKCWNhc2UgUEVSRl9DT1VOVF9TV19UQVNLX0NMT0NLOgoJCXJldHVybiAtRU5PRU5UOwoKCWRlZmF1bHQ6CgkJYnJlYWs7Cgl9CgoJaWYgKGV2ZW50X2lkID49IFBFUkZfQ09VTlRfU1dfTUFYKQoJCXJldHVybiAtRU5PRU5UOwoKCWlmICghZXZlbnQtPnBhcmVudCkgewoJCWludCBlcnI7CgoJCWVyciA9IHN3ZXZlbnRfaGxpc3RfZ2V0KGV2ZW50KTsKCQlpZiAoZXJyKQoJCQlyZXR1cm4gZXJyOwoKCQlqdW1wX2xhYmVsX2luYygmcGVyZl9zd2V2ZW50X2VuYWJsZWRbZXZlbnRfaWRdKTsKCQlldmVudC0+ZGVzdHJveSA9IHN3X3BlcmZfZXZlbnRfZGVzdHJveTsKCX0KCglyZXR1cm4gMDsKfQoKc3RhdGljIHN0cnVjdCBwbXUgcGVyZl9zd2V2ZW50ID0gewoJLnRhc2tfY3R4X25yCT0gcGVyZl9zd19jb250ZXh0LAoKCS5ldmVudF9pbml0CT0gcGVyZl9zd2V2ZW50X2luaXQsCgkuYWRkCQk9IHBlcmZfc3dldmVudF9hZGQsCgkuZGVsCQk9IHBlcmZfc3dldmVudF9kZWwsCgkuc3RhcnQJCT0gcGVyZl9zd2V2ZW50X3N0YXJ0LAoJLnN0b3AJCT0gcGVyZl9zd2V2ZW50X3N0b3AsCgkucmVhZAkJPSBwZXJmX3N3ZXZlbnRfcmVhZCwKfTsKCiNpZmRlZiBDT05GSUdfRVZFTlRfVFJBQ0lORwoKc3RhdGljIGludCBwZXJmX3RwX2ZpbHRlcl9tYXRjaChzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQsCgkJCQlzdHJ1Y3QgcGVyZl9zYW1wbGVfZGF0YSAqZGF0YSkKewoJdm9pZCAqcmVjb3JkID0gZGF0YS0+cmF3LT5kYXRhOwoKCWlmIChsaWtlbHkoIWV2ZW50LT5maWx0ZXIpIHx8IGZpbHRlcl9tYXRjaF9wcmVkcyhldmVudC0+ZmlsdGVyLCByZWNvcmQpKQoJCXJldHVybiAxOwoJcmV0dXJuIDA7Cn0KCnN0YXRpYyBpbnQgcGVyZl90cF9ldmVudF9tYXRjaChzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQsCgkJCQlzdHJ1Y3QgcGVyZl9zYW1wbGVfZGF0YSAqZGF0YSwKCQkJCXN0cnVjdCBwdF9yZWdzICpyZWdzKQp7CgkvKgoJICogQWxsIHRyYWNlcG9pbnRzIGFyZSBmcm9tIGtlcm5lbC1zcGFjZS4KCSAqLwoJaWYgKGV2ZW50LT5hdHRyLmV4Y2x1ZGVfa2VybmVsKQoJCXJldHVybiAwOwoKCWlmICghcGVyZl90cF9maWx0ZXJfbWF0Y2goZXZlbnQsIGRhdGEpKQoJCXJldHVybiAwOwoKCXJldHVybiAxOwp9Cgp2b2lkIHBlcmZfdHBfZXZlbnQodTY0IGFkZHIsIHU2NCBjb3VudCwgdm9pZCAqcmVjb3JkLCBpbnQgZW50cnlfc2l6ZSwKCQkgICBzdHJ1Y3QgcHRfcmVncyAqcmVncywgc3RydWN0IGhsaXN0X2hlYWQgKmhlYWQsIGludCByY3R4KQp7CglzdHJ1Y3QgcGVyZl9zYW1wbGVfZGF0YSBkYXRhOwoJc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50OwoJc3RydWN0IGhsaXN0X25vZGUgKm5vZGU7CgoJc3RydWN0IHBlcmZfcmF3X3JlY29yZCByYXcgPSB7CgkJLnNpemUgPSBlbnRyeV9zaXplLAoJCS5kYXRhID0gcmVjb3JkLAoJfTsKCglwZXJmX3NhbXBsZV9kYXRhX2luaXQoJmRhdGEsIGFkZHIpOwoJZGF0YS5yYXcgPSAmcmF3OwoKCWhsaXN0X2Zvcl9lYWNoX2VudHJ5X3JjdShldmVudCwgbm9kZSwgaGVhZCwgaGxpc3RfZW50cnkpIHsKCQlpZiAocGVyZl90cF9ldmVudF9tYXRjaChldmVudCwgJmRhdGEsIHJlZ3MpKQoJCQlwZXJmX3N3ZXZlbnRfZXZlbnQoZXZlbnQsIGNvdW50LCAxLCAmZGF0YSwgcmVncyk7Cgl9CgoJcGVyZl9zd2V2ZW50X3B1dF9yZWN1cnNpb25fY29udGV4dChyY3R4KTsKfQpFWFBPUlRfU1lNQk9MX0dQTChwZXJmX3RwX2V2ZW50KTsKCnN0YXRpYyB2b2lkIHRwX3BlcmZfZXZlbnRfZGVzdHJveShzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQpCnsKCXBlcmZfdHJhY2VfZGVzdHJveShldmVudCk7Cn0KCnN0YXRpYyBpbnQgcGVyZl90cF9ldmVudF9pbml0KHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCkKewoJaW50IGVycjsKCglpZiAoZXZlbnQtPmF0dHIudHlwZSAhPSBQRVJGX1RZUEVfVFJBQ0VQT0lOVCkKCQlyZXR1cm4gLUVOT0VOVDsKCgllcnIgPSBwZXJmX3RyYWNlX2luaXQoZXZlbnQpOwoJaWYgKGVycikKCQlyZXR1cm4gZXJyOwoKCWV2ZW50LT5kZXN0cm95ID0gdHBfcGVyZl9ldmVudF9kZXN0cm95OwoKCXJldHVybiAwOwp9CgpzdGF0aWMgc3RydWN0IHBtdSBwZXJmX3RyYWNlcG9pbnQgPSB7CgkudGFza19jdHhfbnIJPSBwZXJmX3N3X2NvbnRleHQsCgoJLmV2ZW50X2luaXQJPSBwZXJmX3RwX2V2ZW50X2luaXQsCgkuYWRkCQk9IHBlcmZfdHJhY2VfYWRkLAoJLmRlbAkJPSBwZXJmX3RyYWNlX2RlbCwKCS5zdGFydAkJPSBwZXJmX3N3ZXZlbnRfc3RhcnQsCgkuc3RvcAkJPSBwZXJmX3N3ZXZlbnRfc3RvcCwKCS5yZWFkCQk9IHBlcmZfc3dldmVudF9yZWFkLAp9OwoKc3RhdGljIGlubGluZSB2b2lkIHBlcmZfdHBfcmVnaXN0ZXIodm9pZCkKewoJcGVyZl9wbXVfcmVnaXN0ZXIoJnBlcmZfdHJhY2Vwb2ludCwgInRyYWNlcG9pbnQiLCBQRVJGX1RZUEVfVFJBQ0VQT0lOVCk7Cn0KCnN0YXRpYyBpbnQgcGVyZl9ldmVudF9zZXRfZmlsdGVyKHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCwgdm9pZCBfX3VzZXIgKmFyZykKewoJY2hhciAqZmlsdGVyX3N0cjsKCWludCByZXQ7CgoJaWYgKGV2ZW50LT5hdHRyLnR5cGUgIT0gUEVSRl9UWVBFX1RSQUNFUE9JTlQpCgkJcmV0dXJuIC1FSU5WQUw7CgoJZmlsdGVyX3N0ciA9IHN0cm5kdXBfdXNlcihhcmcsIFBBR0VfU0laRSk7CglpZiAoSVNfRVJSKGZpbHRlcl9zdHIpKQoJCXJldHVybiBQVFJfRVJSKGZpbHRlcl9zdHIpOwoKCXJldCA9IGZ0cmFjZV9wcm9maWxlX3NldF9maWx0ZXIoZXZlbnQsIGV2ZW50LT5hdHRyLmNvbmZpZywgZmlsdGVyX3N0cik7CgoJa2ZyZWUoZmlsdGVyX3N0cik7CglyZXR1cm4gcmV0Owp9CgpzdGF0aWMgdm9pZCBwZXJmX2V2ZW50X2ZyZWVfZmlsdGVyKHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCkKewoJZnRyYWNlX3Byb2ZpbGVfZnJlZV9maWx0ZXIoZXZlbnQpOwp9CgojZWxzZQoKc3RhdGljIGlubGluZSB2b2lkIHBlcmZfdHBfcmVnaXN0ZXIodm9pZCkKewp9CgpzdGF0aWMgaW50IHBlcmZfZXZlbnRfc2V0X2ZpbHRlcihzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQsIHZvaWQgX191c2VyICphcmcpCnsKCXJldHVybiAtRU5PRU5UOwp9CgpzdGF0aWMgdm9pZCBwZXJmX2V2ZW50X2ZyZWVfZmlsdGVyKHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCkKewp9CgojZW5kaWYgLyogQ09ORklHX0VWRU5UX1RSQUNJTkcgKi8KCiNpZmRlZiBDT05GSUdfSEFWRV9IV19CUkVBS1BPSU5UCnZvaWQgcGVyZl9icF9ldmVudChzdHJ1Y3QgcGVyZl9ldmVudCAqYnAsIHZvaWQgKmRhdGEpCnsKCXN0cnVjdCBwZXJmX3NhbXBsZV9kYXRhIHNhbXBsZTsKCXN0cnVjdCBwdF9yZWdzICpyZWdzID0gZGF0YTsKCglwZXJmX3NhbXBsZV9kYXRhX2luaXQoJnNhbXBsZSwgYnAtPmF0dHIuYnBfYWRkcik7CgoJaWYgKCFicC0+aHcuc3RhdGUgJiYgIXBlcmZfZXhjbHVkZV9ldmVudChicCwgcmVncykpCgkJcGVyZl9zd2V2ZW50X2V2ZW50KGJwLCAxLCAxLCAmc2FtcGxlLCByZWdzKTsKfQojZW5kaWYKCi8qCiAqIGhydGltZXIgYmFzZWQgc3dldmVudCBjYWxsYmFjawogKi8KCnN0YXRpYyBlbnVtIGhydGltZXJfcmVzdGFydCBwZXJmX3N3ZXZlbnRfaHJ0aW1lcihzdHJ1Y3QgaHJ0aW1lciAqaHJ0aW1lcikKewoJZW51bSBocnRpbWVyX3Jlc3RhcnQgcmV0ID0gSFJUSU1FUl9SRVNUQVJUOwoJc3RydWN0IHBlcmZfc2FtcGxlX2RhdGEgZGF0YTsKCXN0cnVjdCBwdF9yZWdzICpyZWdzOwoJc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50OwoJdTY0IHBlcmlvZDsKCglldmVudCA9IGNvbnRhaW5lcl9vZihocnRpbWVyLCBzdHJ1Y3QgcGVyZl9ldmVudCwgaHcuaHJ0aW1lcik7CglldmVudC0+cG11LT5yZWFkKGV2ZW50KTsKCglwZXJmX3NhbXBsZV9kYXRhX2luaXQoJmRhdGEsIDApOwoJZGF0YS5wZXJpb2QgPSBldmVudC0+aHcubGFzdF9wZXJpb2Q7CglyZWdzID0gZ2V0X2lycV9yZWdzKCk7CgoJaWYgKHJlZ3MgJiYgIXBlcmZfZXhjbHVkZV9ldmVudChldmVudCwgcmVncykpIHsKCQlpZiAoIShldmVudC0+YXR0ci5leGNsdWRlX2lkbGUgJiYgY3VycmVudC0+cGlkID09IDApKQoJCQlpZiAocGVyZl9ldmVudF9vdmVyZmxvdyhldmVudCwgMCwgJmRhdGEsIHJlZ3MpKQoJCQkJcmV0ID0gSFJUSU1FUl9OT1JFU1RBUlQ7Cgl9CgoJcGVyaW9kID0gbWF4X3QodTY0LCAxMDAwMCwgZXZlbnQtPmh3LnNhbXBsZV9wZXJpb2QpOwoJaHJ0aW1lcl9mb3J3YXJkX25vdyhocnRpbWVyLCBuc190b19rdGltZShwZXJpb2QpKTsKCglyZXR1cm4gcmV0Owp9CgpzdGF0aWMgdm9pZCBwZXJmX3N3ZXZlbnRfc3RhcnRfaHJ0aW1lcihzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQpCnsKCXN0cnVjdCBod19wZXJmX2V2ZW50ICpod2MgPSAmZXZlbnQtPmh3OwoJczY0IHBlcmlvZDsKCglpZiAoIWlzX3NhbXBsaW5nX2V2ZW50KGV2ZW50KSkKCQlyZXR1cm47CgoJaHJ0aW1lcl9pbml0KCZod2MtPmhydGltZXIsIENMT0NLX01PTk9UT05JQywgSFJUSU1FUl9NT0RFX1JFTCk7Cglod2MtPmhydGltZXIuZnVuY3Rpb24gPSBwZXJmX3N3ZXZlbnRfaHJ0aW1lcjsKCglwZXJpb2QgPSBsb2NhbDY0X3JlYWQoJmh3Yy0+cGVyaW9kX2xlZnQpOwoJaWYgKHBlcmlvZCkgewoJCWlmIChwZXJpb2QgPCAwKQoJCQlwZXJpb2QgPSAxMDAwMDsKCgkJbG9jYWw2NF9zZXQoJmh3Yy0+cGVyaW9kX2xlZnQsIDApOwoJfSBlbHNlIHsKCQlwZXJpb2QgPSBtYXhfdCh1NjQsIDEwMDAwLCBod2MtPnNhbXBsZV9wZXJpb2QpOwoJfQoJX19ocnRpbWVyX3N0YXJ0X3JhbmdlX25zKCZod2MtPmhydGltZXIsCgkJCQluc190b19rdGltZShwZXJpb2QpLCAwLAoJCQkJSFJUSU1FUl9NT0RFX1JFTF9QSU5ORUQsIDApOwp9CgpzdGF0aWMgdm9pZCBwZXJmX3N3ZXZlbnRfY2FuY2VsX2hydGltZXIoc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50KQp7CglzdHJ1Y3QgaHdfcGVyZl9ldmVudCAqaHdjID0gJmV2ZW50LT5odzsKCglpZiAoaXNfc2FtcGxpbmdfZXZlbnQoZXZlbnQpKSB7CgkJa3RpbWVfdCByZW1haW5pbmcgPSBocnRpbWVyX2dldF9yZW1haW5pbmcoJmh3Yy0+aHJ0aW1lcik7CgkJbG9jYWw2NF9zZXQoJmh3Yy0+cGVyaW9kX2xlZnQsIGt0aW1lX3RvX25zKHJlbWFpbmluZykpOwoKCQlocnRpbWVyX2NhbmNlbCgmaHdjLT5ocnRpbWVyKTsKCX0KfQoKLyoKICogU29mdHdhcmUgZXZlbnQ6IGNwdSB3YWxsIHRpbWUgY2xvY2sKICovCgpzdGF0aWMgdm9pZCBjcHVfY2xvY2tfZXZlbnRfdXBkYXRlKHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCkKewoJczY0IHByZXY7Cgl1NjQgbm93OwoKCW5vdyA9IGxvY2FsX2Nsb2NrKCk7CglwcmV2ID0gbG9jYWw2NF94Y2hnKCZldmVudC0+aHcucHJldl9jb3VudCwgbm93KTsKCWxvY2FsNjRfYWRkKG5vdyAtIHByZXYsICZldmVudC0+Y291bnQpOwp9CgpzdGF0aWMgdm9pZCBjcHVfY2xvY2tfZXZlbnRfc3RhcnQoc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50LCBpbnQgZmxhZ3MpCnsKCWxvY2FsNjRfc2V0KCZldmVudC0+aHcucHJldl9jb3VudCwgbG9jYWxfY2xvY2soKSk7CglwZXJmX3N3ZXZlbnRfc3RhcnRfaHJ0aW1lcihldmVudCk7Cn0KCnN0YXRpYyB2b2lkIGNwdV9jbG9ja19ldmVudF9zdG9wKHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCwgaW50IGZsYWdzKQp7CglwZXJmX3N3ZXZlbnRfY2FuY2VsX2hydGltZXIoZXZlbnQpOwoJY3B1X2Nsb2NrX2V2ZW50X3VwZGF0ZShldmVudCk7Cn0KCnN0YXRpYyBpbnQgY3B1X2Nsb2NrX2V2ZW50X2FkZChzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQsIGludCBmbGFncykKewoJaWYgKGZsYWdzICYgUEVSRl9FRl9TVEFSVCkKCQljcHVfY2xvY2tfZXZlbnRfc3RhcnQoZXZlbnQsIGZsYWdzKTsKCglyZXR1cm4gMDsKfQoKc3RhdGljIHZvaWQgY3B1X2Nsb2NrX2V2ZW50X2RlbChzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQsIGludCBmbGFncykKewoJY3B1X2Nsb2NrX2V2ZW50X3N0b3AoZXZlbnQsIGZsYWdzKTsKfQoKc3RhdGljIHZvaWQgY3B1X2Nsb2NrX2V2ZW50X3JlYWQoc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50KQp7CgljcHVfY2xvY2tfZXZlbnRfdXBkYXRlKGV2ZW50KTsKfQoKc3RhdGljIGludCBjcHVfY2xvY2tfZXZlbnRfaW5pdChzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQpCnsKCWlmIChldmVudC0+YXR0ci50eXBlICE9IFBFUkZfVFlQRV9TT0ZUV0FSRSkKCQlyZXR1cm4gLUVOT0VOVDsKCglpZiAoZXZlbnQtPmF0dHIuY29uZmlnICE9IFBFUkZfQ09VTlRfU1dfQ1BVX0NMT0NLKQoJCXJldHVybiAtRU5PRU5UOwoKCXJldHVybiAwOwp9CgpzdGF0aWMgc3RydWN0IHBtdSBwZXJmX2NwdV9jbG9jayA9IHsKCS50YXNrX2N0eF9ucgk9IHBlcmZfc3dfY29udGV4dCwKCgkuZXZlbnRfaW5pdAk9IGNwdV9jbG9ja19ldmVudF9pbml0LAoJLmFkZAkJPSBjcHVfY2xvY2tfZXZlbnRfYWRkLAoJLmRlbAkJPSBjcHVfY2xvY2tfZXZlbnRfZGVsLAoJLnN0YXJ0CQk9IGNwdV9jbG9ja19ldmVudF9zdGFydCwKCS5zdG9wCQk9IGNwdV9jbG9ja19ldmVudF9zdG9wLAoJLnJlYWQJCT0gY3B1X2Nsb2NrX2V2ZW50X3JlYWQsCn07CgovKgogKiBTb2Z0d2FyZSBldmVudDogdGFzayB0aW1lIGNsb2NrCiAqLwoKc3RhdGljIHZvaWQgdGFza19jbG9ja19ldmVudF91cGRhdGUoc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50LCB1NjQgbm93KQp7Cgl1NjQgcHJldjsKCXM2NCBkZWx0YTsKCglwcmV2ID0gbG9jYWw2NF94Y2hnKCZldmVudC0+aHcucHJldl9jb3VudCwgbm93KTsKCWRlbHRhID0gbm93IC0gcHJldjsKCWxvY2FsNjRfYWRkKGRlbHRhLCAmZXZlbnQtPmNvdW50KTsKfQoKc3RhdGljIHZvaWQgdGFza19jbG9ja19ldmVudF9zdGFydChzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQsIGludCBmbGFncykKewoJbG9jYWw2NF9zZXQoJmV2ZW50LT5ody5wcmV2X2NvdW50LCBldmVudC0+Y3R4LT50aW1lKTsKCXBlcmZfc3dldmVudF9zdGFydF9ocnRpbWVyKGV2ZW50KTsKfQoKc3RhdGljIHZvaWQgdGFza19jbG9ja19ldmVudF9zdG9wKHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCwgaW50IGZsYWdzKQp7CglwZXJmX3N3ZXZlbnRfY2FuY2VsX2hydGltZXIoZXZlbnQpOwoJdGFza19jbG9ja19ldmVudF91cGRhdGUoZXZlbnQsIGV2ZW50LT5jdHgtPnRpbWUpOwp9CgpzdGF0aWMgaW50IHRhc2tfY2xvY2tfZXZlbnRfYWRkKHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCwgaW50IGZsYWdzKQp7CglpZiAoZmxhZ3MgJiBQRVJGX0VGX1NUQVJUKQoJCXRhc2tfY2xvY2tfZXZlbnRfc3RhcnQoZXZlbnQsIGZsYWdzKTsKCglyZXR1cm4gMDsKfQoKc3RhdGljIHZvaWQgdGFza19jbG9ja19ldmVudF9kZWwoc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50LCBpbnQgZmxhZ3MpCnsKCXRhc2tfY2xvY2tfZXZlbnRfc3RvcChldmVudCwgUEVSRl9FRl9VUERBVEUpOwp9CgpzdGF0aWMgdm9pZCB0YXNrX2Nsb2NrX2V2ZW50X3JlYWQoc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50KQp7Cgl1NjQgdGltZTsKCglpZiAoIWluX25taSgpKSB7CgkJdXBkYXRlX2NvbnRleHRfdGltZShldmVudC0+Y3R4KTsKCQl0aW1lID0gZXZlbnQtPmN0eC0+dGltZTsKCX0gZWxzZSB7CgkJdTY0IG5vdyA9IHBlcmZfY2xvY2soKTsKCQl1NjQgZGVsdGEgPSBub3cgLSBldmVudC0+Y3R4LT50aW1lc3RhbXA7CgkJdGltZSA9IGV2ZW50LT5jdHgtPnRpbWUgKyBkZWx0YTsKCX0KCgl0YXNrX2Nsb2NrX2V2ZW50X3VwZGF0ZShldmVudCwgdGltZSk7Cn0KCnN0YXRpYyBpbnQgdGFza19jbG9ja19ldmVudF9pbml0KHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCkKewoJaWYgKGV2ZW50LT5hdHRyLnR5cGUgIT0gUEVSRl9UWVBFX1NPRlRXQVJFKQoJCXJldHVybiAtRU5PRU5UOwoKCWlmIChldmVudC0+YXR0ci5jb25maWcgIT0gUEVSRl9DT1VOVF9TV19UQVNLX0NMT0NLKQoJCXJldHVybiAtRU5PRU5UOwoKCXJldHVybiAwOwp9CgpzdGF0aWMgc3RydWN0IHBtdSBwZXJmX3Rhc2tfY2xvY2sgPSB7CgkudGFza19jdHhfbnIJPSBwZXJmX3N3X2NvbnRleHQsCgoJLmV2ZW50X2luaXQJPSB0YXNrX2Nsb2NrX2V2ZW50X2luaXQsCgkuYWRkCQk9IHRhc2tfY2xvY2tfZXZlbnRfYWRkLAoJLmRlbAkJPSB0YXNrX2Nsb2NrX2V2ZW50X2RlbCwKCS5zdGFydAkJPSB0YXNrX2Nsb2NrX2V2ZW50X3N0YXJ0LAoJLnN0b3AJCT0gdGFza19jbG9ja19ldmVudF9zdG9wLAoJLnJlYWQJCT0gdGFza19jbG9ja19ldmVudF9yZWFkLAp9OwoKc3RhdGljIHZvaWQgcGVyZl9wbXVfbm9wX3ZvaWQoc3RydWN0IHBtdSAqcG11KQp7Cn0KCnN0YXRpYyBpbnQgcGVyZl9wbXVfbm9wX2ludChzdHJ1Y3QgcG11ICpwbXUpCnsKCXJldHVybiAwOwp9CgpzdGF0aWMgdm9pZCBwZXJmX3BtdV9zdGFydF90eG4oc3RydWN0IHBtdSAqcG11KQp7CglwZXJmX3BtdV9kaXNhYmxlKHBtdSk7Cn0KCnN0YXRpYyBpbnQgcGVyZl9wbXVfY29tbWl0X3R4bihzdHJ1Y3QgcG11ICpwbXUpCnsKCXBlcmZfcG11X2VuYWJsZShwbXUpOwoJcmV0dXJuIDA7Cn0KCnN0YXRpYyB2b2lkIHBlcmZfcG11X2NhbmNlbF90eG4oc3RydWN0IHBtdSAqcG11KQp7CglwZXJmX3BtdV9lbmFibGUocG11KTsKfQoKLyoKICogRW5zdXJlcyBhbGwgY29udGV4dHMgd2l0aCB0aGUgc2FtZSB0YXNrX2N0eF9uciBoYXZlIHRoZSBzYW1lCiAqIHBtdV9jcHVfY29udGV4dCB0b28uCiAqLwpzdGF0aWMgdm9pZCAqZmluZF9wbXVfY29udGV4dChpbnQgY3R4bikKewoJc3RydWN0IHBtdSAqcG11OwoKCWlmIChjdHhuIDwgMCkKCQlyZXR1cm4gTlVMTDsKCglsaXN0X2Zvcl9lYWNoX2VudHJ5KHBtdSwgJnBtdXMsIGVudHJ5KSB7CgkJaWYgKHBtdS0+dGFza19jdHhfbnIgPT0gY3R4bikKCQkJcmV0dXJuIHBtdS0+cG11X2NwdV9jb250ZXh0OwoJfQoKCXJldHVybiBOVUxMOwp9CgpzdGF0aWMgdm9pZCB1cGRhdGVfcG11X2NvbnRleHQoc3RydWN0IHBtdSAqcG11LCBzdHJ1Y3QgcG11ICpvbGRfcG11KQp7CglpbnQgY3B1OwoKCWZvcl9lYWNoX3Bvc3NpYmxlX2NwdShjcHUpIHsKCQlzdHJ1Y3QgcGVyZl9jcHVfY29udGV4dCAqY3B1Y3R4OwoKCQljcHVjdHggPSBwZXJfY3B1X3B0cihwbXUtPnBtdV9jcHVfY29udGV4dCwgY3B1KTsKCgkJaWYgKGNwdWN0eC0+YWN0aXZlX3BtdSA9PSBvbGRfcG11KQoJCQljcHVjdHgtPmFjdGl2ZV9wbXUgPSBwbXU7Cgl9Cn0KCnN0YXRpYyB2b2lkIGZyZWVfcG11X2NvbnRleHQoc3RydWN0IHBtdSAqcG11KQp7CglzdHJ1Y3QgcG11ICppOwoKCW11dGV4X2xvY2soJnBtdXNfbG9jayk7CgkvKgoJICogTGlrZSBhIHJlYWwgbGFtZSByZWZjb3VudC4KCSAqLwoJbGlzdF9mb3JfZWFjaF9lbnRyeShpLCAmcG11cywgZW50cnkpIHsKCQlpZiAoaS0+cG11X2NwdV9jb250ZXh0ID09IHBtdS0+cG11X2NwdV9jb250ZXh0KSB7CgkJCXVwZGF0ZV9wbXVfY29udGV4dChpLCBwbXUpOwoJCQlnb3RvIG91dDsKCQl9Cgl9CgoJZnJlZV9wZXJjcHUocG11LT5wbXVfY3B1X2NvbnRleHQpOwpvdXQ6CgltdXRleF91bmxvY2soJnBtdXNfbG9jayk7Cn0Kc3RhdGljIHN0cnVjdCBpZHIgcG11X2lkcjsKCnN0YXRpYyBzc2l6ZV90CnR5cGVfc2hvdyhzdHJ1Y3QgZGV2aWNlICpkZXYsIHN0cnVjdCBkZXZpY2VfYXR0cmlidXRlICphdHRyLCBjaGFyICpwYWdlKQp7CglzdHJ1Y3QgcG11ICpwbXUgPSBkZXZfZ2V0X2RydmRhdGEoZGV2KTsKCglyZXR1cm4gc25wcmludGYocGFnZSwgUEFHRV9TSVpFLTEsICIlZFxuIiwgcG11LT50eXBlKTsKfQoKc3RhdGljIHN0cnVjdCBkZXZpY2VfYXR0cmlidXRlIHBtdV9kZXZfYXR0cnNbXSA9IHsKICAgICAgIF9fQVRUUl9STyh0eXBlKSwKICAgICAgIF9fQVRUUl9OVUxMLAp9OwoKc3RhdGljIGludCBwbXVfYnVzX3J1bm5pbmc7CnN0YXRpYyBzdHJ1Y3QgYnVzX3R5cGUgcG11X2J1cyA9IHsKCS5uYW1lCQk9ICJldmVudF9zb3VyY2UiLAoJLmRldl9hdHRycwk9IHBtdV9kZXZfYXR0cnMsCn07CgpzdGF0aWMgdm9pZCBwbXVfZGV2X3JlbGVhc2Uoc3RydWN0IGRldmljZSAqZGV2KQp7CglrZnJlZShkZXYpOwp9CgpzdGF0aWMgaW50IHBtdV9kZXZfYWxsb2Moc3RydWN0IHBtdSAqcG11KQp7CglpbnQgcmV0ID0gLUVOT01FTTsKCglwbXUtPmRldiA9IGt6YWxsb2Moc2l6ZW9mKHN0cnVjdCBkZXZpY2UpLCBHRlBfS0VSTkVMKTsKCWlmICghcG11LT5kZXYpCgkJZ290byBvdXQ7CgoJZGV2aWNlX2luaXRpYWxpemUocG11LT5kZXYpOwoJcmV0ID0gZGV2X3NldF9uYW1lKHBtdS0+ZGV2LCAiJXMiLCBwbXUtPm5hbWUpOwoJaWYgKHJldCkKCQlnb3RvIGZyZWVfZGV2OwoKCWRldl9zZXRfZHJ2ZGF0YShwbXUtPmRldiwgcG11KTsKCXBtdS0+ZGV2LT5idXMgPSAmcG11X2J1czsKCXBtdS0+ZGV2LT5yZWxlYXNlID0gcG11X2Rldl9yZWxlYXNlOwoJcmV0ID0gZGV2aWNlX2FkZChwbXUtPmRldik7CglpZiAocmV0KQoJCWdvdG8gZnJlZV9kZXY7CgpvdXQ6CglyZXR1cm4gcmV0OwoKZnJlZV9kZXY6CglwdXRfZGV2aWNlKHBtdS0+ZGV2KTsKCWdvdG8gb3V0Owp9CgppbnQgcGVyZl9wbXVfcmVnaXN0ZXIoc3RydWN0IHBtdSAqcG11LCBjaGFyICpuYW1lLCBpbnQgdHlwZSkKewoJaW50IGNwdSwgcmV0OwoKCW11dGV4X2xvY2soJnBtdXNfbG9jayk7CglyZXQgPSAtRU5PTUVNOwoJcG11LT5wbXVfZGlzYWJsZV9jb3VudCA9IGFsbG9jX3BlcmNwdShpbnQpOwoJaWYgKCFwbXUtPnBtdV9kaXNhYmxlX2NvdW50KQoJCWdvdG8gdW5sb2NrOwoKCXBtdS0+dHlwZSA9IC0xOwoJaWYgKCFuYW1lKQoJCWdvdG8gc2tpcF90eXBlOwoJcG11LT5uYW1lID0gbmFtZTsKCglpZiAodHlwZSA8IDApIHsKCQlpbnQgZXJyID0gaWRyX3ByZV9nZXQoJnBtdV9pZHIsIEdGUF9LRVJORUwpOwoJCWlmICghZXJyKQoJCQlnb3RvIGZyZWVfcGRjOwoKCQllcnIgPSBpZHJfZ2V0X25ld19hYm92ZSgmcG11X2lkciwgcG11LCBQRVJGX1RZUEVfTUFYLCAmdHlwZSk7CgkJaWYgKGVycikgewoJCQlyZXQgPSBlcnI7CgkJCWdvdG8gZnJlZV9wZGM7CgkJfQoJfQoJcG11LT50eXBlID0gdHlwZTsKCglpZiAocG11X2J1c19ydW5uaW5nKSB7CgkJcmV0ID0gcG11X2Rldl9hbGxvYyhwbXUpOwoJCWlmIChyZXQpCgkJCWdvdG8gZnJlZV9pZHI7Cgl9Cgpza2lwX3R5cGU6CglwbXUtPnBtdV9jcHVfY29udGV4dCA9IGZpbmRfcG11X2NvbnRleHQocG11LT50YXNrX2N0eF9ucik7CglpZiAocG11LT5wbXVfY3B1X2NvbnRleHQpCgkJZ290byBnb3RfY3B1X2NvbnRleHQ7CgoJcG11LT5wbXVfY3B1X2NvbnRleHQgPSBhbGxvY19wZXJjcHUoc3RydWN0IHBlcmZfY3B1X2NvbnRleHQpOwoJaWYgKCFwbXUtPnBtdV9jcHVfY29udGV4dCkKCQlnb3RvIGZyZWVfZGV2OwoKCWZvcl9lYWNoX3Bvc3NpYmxlX2NwdShjcHUpIHsKCQlzdHJ1Y3QgcGVyZl9jcHVfY29udGV4dCAqY3B1Y3R4OwoKCQljcHVjdHggPSBwZXJfY3B1X3B0cihwbXUtPnBtdV9jcHVfY29udGV4dCwgY3B1KTsKCQlfX3BlcmZfZXZlbnRfaW5pdF9jb250ZXh0KCZjcHVjdHgtPmN0eCk7CgkJY3B1Y3R4LT5jdHgudHlwZSA9IGNwdV9jb250ZXh0OwoJCWNwdWN0eC0+Y3R4LnBtdSA9IHBtdTsKCQljcHVjdHgtPmppZmZpZXNfaW50ZXJ2YWwgPSAxOwoJCUlOSVRfTElTVF9IRUFEKCZjcHVjdHgtPnJvdGF0aW9uX2xpc3QpOwoJCWNwdWN0eC0+YWN0aXZlX3BtdSA9IHBtdTsKCX0KCmdvdF9jcHVfY29udGV4dDoKCWlmICghcG11LT5zdGFydF90eG4pIHsKCQlpZiAocG11LT5wbXVfZW5hYmxlKSB7CgkJCS8qCgkJCSAqIElmIHdlIGhhdmUgcG11X2VuYWJsZS9wbXVfZGlzYWJsZSBjYWxscywgaW5zdGFsbAoJCQkgKiB0cmFuc2FjdGlvbiBzdHVicyB0aGF0IHVzZSB0aGF0IHRvIHRyeSBhbmQgYmF0Y2gKCQkJICogaGFyZHdhcmUgYWNjZXNzZXMuCgkJCSAqLwoJCQlwbXUtPnN0YXJ0X3R4biAgPSBwZXJmX3BtdV9zdGFydF90eG47CgkJCXBtdS0+Y29tbWl0X3R4biA9IHBlcmZfcG11X2NvbW1pdF90eG47CgkJCXBtdS0+Y2FuY2VsX3R4biA9IHBlcmZfcG11X2NhbmNlbF90eG47CgkJfSBlbHNlIHsKCQkJcG11LT5zdGFydF90eG4gID0gcGVyZl9wbXVfbm9wX3ZvaWQ7CgkJCXBtdS0+Y29tbWl0X3R4biA9IHBlcmZfcG11X25vcF9pbnQ7CgkJCXBtdS0+Y2FuY2VsX3R4biA9IHBlcmZfcG11X25vcF92b2lkOwoJCX0KCX0KCglpZiAoIXBtdS0+cG11X2VuYWJsZSkgewoJCXBtdS0+cG11X2VuYWJsZSAgPSBwZXJmX3BtdV9ub3Bfdm9pZDsKCQlwbXUtPnBtdV9kaXNhYmxlID0gcGVyZl9wbXVfbm9wX3ZvaWQ7Cgl9CgoJbGlzdF9hZGRfcmN1KCZwbXUtPmVudHJ5LCAmcG11cyk7CglyZXQgPSAwOwp1bmxvY2s6CgltdXRleF91bmxvY2soJnBtdXNfbG9jayk7CgoJcmV0dXJuIHJldDsKCmZyZWVfZGV2OgoJZGV2aWNlX2RlbChwbXUtPmRldik7CglwdXRfZGV2aWNlKHBtdS0+ZGV2KTsKCmZyZWVfaWRyOgoJaWYgKHBtdS0+dHlwZSA+PSBQRVJGX1RZUEVfTUFYKQoJCWlkcl9yZW1vdmUoJnBtdV9pZHIsIHBtdS0+dHlwZSk7CgpmcmVlX3BkYzoKCWZyZWVfcGVyY3B1KHBtdS0+cG11X2Rpc2FibGVfY291bnQpOwoJZ290byB1bmxvY2s7Cn0KCnZvaWQgcGVyZl9wbXVfdW5yZWdpc3RlcihzdHJ1Y3QgcG11ICpwbXUpCnsKCW11dGV4X2xvY2soJnBtdXNfbG9jayk7CglsaXN0X2RlbF9yY3UoJnBtdS0+ZW50cnkpOwoJbXV0ZXhfdW5sb2NrKCZwbXVzX2xvY2spOwoKCS8qCgkgKiBXZSBkZXJlZmVyZW5jZSB0aGUgcG11IGxpc3QgdW5kZXIgYm90aCBTUkNVIGFuZCByZWd1bGFyIFJDVSwgc28KCSAqIHN5bmNocm9uaXplIGFnYWluc3QgYm90aCBvZiB0aG9zZS4KCSAqLwoJc3luY2hyb25pemVfc3JjdSgmcG11c19zcmN1KTsKCXN5bmNocm9uaXplX3JjdSgpOwoKCWZyZWVfcGVyY3B1KHBtdS0+cG11X2Rpc2FibGVfY291bnQpOwoJaWYgKHBtdS0+dHlwZSA+PSBQRVJGX1RZUEVfTUFYKQoJCWlkcl9yZW1vdmUoJnBtdV9pZHIsIHBtdS0+dHlwZSk7CglkZXZpY2VfZGVsKHBtdS0+ZGV2KTsKCXB1dF9kZXZpY2UocG11LT5kZXYpOwoJZnJlZV9wbXVfY29udGV4dChwbXUpOwp9CgpzdHJ1Y3QgcG11ICpwZXJmX2luaXRfZXZlbnQoc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50KQp7CglzdHJ1Y3QgcG11ICpwbXUgPSBOVUxMOwoJaW50IGlkeDsKCglpZHggPSBzcmN1X3JlYWRfbG9jaygmcG11c19zcmN1KTsKCglyY3VfcmVhZF9sb2NrKCk7CglwbXUgPSBpZHJfZmluZCgmcG11X2lkciwgZXZlbnQtPmF0dHIudHlwZSk7CglyY3VfcmVhZF91bmxvY2soKTsKCWlmIChwbXUpCgkJZ290byB1bmxvY2s7CgoJbGlzdF9mb3JfZWFjaF9lbnRyeV9yY3UocG11LCAmcG11cywgZW50cnkpIHsKCQlpbnQgcmV0ID0gcG11LT5ldmVudF9pbml0KGV2ZW50KTsKCQlpZiAoIXJldCkKCQkJZ290byB1bmxvY2s7CgoJCWlmIChyZXQgIT0gLUVOT0VOVCkgewoJCQlwbXUgPSBFUlJfUFRSKHJldCk7CgkJCWdvdG8gdW5sb2NrOwoJCX0KCX0KCXBtdSA9IEVSUl9QVFIoLUVOT0VOVCk7CnVubG9jazoKCXNyY3VfcmVhZF91bmxvY2soJnBtdXNfc3JjdSwgaWR4KTsKCglyZXR1cm4gcG11Owp9CgovKgogKiBBbGxvY2F0ZSBhbmQgaW5pdGlhbGl6ZSBhIGV2ZW50IHN0cnVjdHVyZQogKi8Kc3RhdGljIHN0cnVjdCBwZXJmX2V2ZW50ICoKcGVyZl9ldmVudF9hbGxvYyhzdHJ1Y3QgcGVyZl9ldmVudF9hdHRyICphdHRyLCBpbnQgY3B1LAoJCSBzdHJ1Y3QgdGFza19zdHJ1Y3QgKnRhc2ssCgkJIHN0cnVjdCBwZXJmX2V2ZW50ICpncm91cF9sZWFkZXIsCgkJIHN0cnVjdCBwZXJmX2V2ZW50ICpwYXJlbnRfZXZlbnQsCgkJIHBlcmZfb3ZlcmZsb3dfaGFuZGxlcl90IG92ZXJmbG93X2hhbmRsZXIpCnsKCXN0cnVjdCBwbXUgKnBtdTsKCXN0cnVjdCBwZXJmX2V2ZW50ICpldmVudDsKCXN0cnVjdCBod19wZXJmX2V2ZW50ICpod2M7Cglsb25nIGVycjsKCglldmVudCA9IGt6YWxsb2Moc2l6ZW9mKCpldmVudCksIEdGUF9LRVJORUwpOwoJaWYgKCFldmVudCkKCQlyZXR1cm4gRVJSX1BUUigtRU5PTUVNKTsKCgkvKgoJICogU2luZ2xlIGV2ZW50cyBhcmUgdGhlaXIgb3duIGdyb3VwIGxlYWRlcnMsIHdpdGggYW4KCSAqIGVtcHR5IHNpYmxpbmcgbGlzdDoKCSAqLwoJaWYgKCFncm91cF9sZWFkZXIpCgkJZ3JvdXBfbGVhZGVyID0gZXZlbnQ7CgoJbXV0ZXhfaW5pdCgmZXZlbnQtPmNoaWxkX211dGV4KTsKCUlOSVRfTElTVF9IRUFEKCZldmVudC0+Y2hpbGRfbGlzdCk7CgoJSU5JVF9MSVNUX0hFQUQoJmV2ZW50LT5ncm91cF9lbnRyeSk7CglJTklUX0xJU1RfSEVBRCgmZXZlbnQtPmV2ZW50X2VudHJ5KTsKCUlOSVRfTElTVF9IRUFEKCZldmVudC0+c2libGluZ19saXN0KTsKCWluaXRfd2FpdHF1ZXVlX2hlYWQoJmV2ZW50LT53YWl0cSk7Cglpbml0X2lycV93b3JrKCZldmVudC0+cGVuZGluZywgcGVyZl9wZW5kaW5nX2V2ZW50KTsKCgltdXRleF9pbml0KCZldmVudC0+bW1hcF9tdXRleCk7CgoJZXZlbnQtPmNwdQkJPSBjcHU7CglldmVudC0+YXR0cgkJPSAqYXR0cjsKCWV2ZW50LT5ncm91cF9sZWFkZXIJPSBncm91cF9sZWFkZXI7CglldmVudC0+cG11CQk9IE5VTEw7CglldmVudC0+b25jcHUJCT0gLTE7CgoJZXZlbnQtPnBhcmVudAkJPSBwYXJlbnRfZXZlbnQ7CgoJZXZlbnQtPm5zCQk9IGdldF9waWRfbnMoY3VycmVudC0+bnNwcm94eS0+cGlkX25zKTsKCWV2ZW50LT5pZAkJPSBhdG9taWM2NF9pbmNfcmV0dXJuKCZwZXJmX2V2ZW50X2lkKTsKCglldmVudC0+c3RhdGUJCT0gUEVSRl9FVkVOVF9TVEFURV9JTkFDVElWRTsKCglpZiAodGFzaykgewoJCWV2ZW50LT5hdHRhY2hfc3RhdGUgPSBQRVJGX0FUVEFDSF9UQVNLOwojaWZkZWYgQ09ORklHX0hBVkVfSFdfQlJFQUtQT0lOVAoJCS8qCgkJICogaHdfYnJlYWtwb2ludCBpcyBhIGJpdCBkaWZmaWN1bHQgaGVyZS4uCgkJICovCgkJaWYgKGF0dHItPnR5cGUgPT0gUEVSRl9UWVBFX0JSRUFLUE9JTlQpCgkJCWV2ZW50LT5ody5icF90YXJnZXQgPSB0YXNrOwojZW5kaWYKCX0KCglpZiAoIW92ZXJmbG93X2hhbmRsZXIgJiYgcGFyZW50X2V2ZW50KQoJCW92ZXJmbG93X2hhbmRsZXIgPSBwYXJlbnRfZXZlbnQtPm92ZXJmbG93X2hhbmRsZXI7CgkKCWV2ZW50LT5vdmVyZmxvd19oYW5kbGVyCT0gb3ZlcmZsb3dfaGFuZGxlcjsKCglpZiAoYXR0ci0+ZGlzYWJsZWQpCgkJZXZlbnQtPnN0YXRlID0gUEVSRl9FVkVOVF9TVEFURV9PRkY7CgoJcG11ID0gTlVMTDsKCglod2MgPSAmZXZlbnQtPmh3OwoJaHdjLT5zYW1wbGVfcGVyaW9kID0gYXR0ci0+c2FtcGxlX3BlcmlvZDsKCWlmIChhdHRyLT5mcmVxICYmIGF0dHItPnNhbXBsZV9mcmVxKQoJCWh3Yy0+c2FtcGxlX3BlcmlvZCA9IDE7Cglod2MtPmxhc3RfcGVyaW9kID0gaHdjLT5zYW1wbGVfcGVyaW9kOwoKCWxvY2FsNjRfc2V0KCZod2MtPnBlcmlvZF9sZWZ0LCBod2MtPnNhbXBsZV9wZXJpb2QpOwoKCS8qCgkgKiB3ZSBjdXJyZW50bHkgZG8gbm90IHN1cHBvcnQgUEVSRl9GT1JNQVRfR1JPVVAgb24gaW5oZXJpdGVkIGV2ZW50cwoJICovCglpZiAoYXR0ci0+aW5oZXJpdCAmJiAoYXR0ci0+cmVhZF9mb3JtYXQgJiBQRVJGX0ZPUk1BVF9HUk9VUCkpCgkJZ290byBkb25lOwoKCXBtdSA9IHBlcmZfaW5pdF9ldmVudChldmVudCk7Cgpkb25lOgoJZXJyID0gMDsKCWlmICghcG11KQoJCWVyciA9IC1FSU5WQUw7CgllbHNlIGlmIChJU19FUlIocG11KSkKCQllcnIgPSBQVFJfRVJSKHBtdSk7CgoJaWYgKGVycikgewoJCWlmIChldmVudC0+bnMpCgkJCXB1dF9waWRfbnMoZXZlbnQtPm5zKTsKCQlrZnJlZShldmVudCk7CgkJcmV0dXJuIEVSUl9QVFIoZXJyKTsKCX0KCglldmVudC0+cG11ID0gcG11OwoKCWlmICghZXZlbnQtPnBhcmVudCkgewoJCWlmIChldmVudC0+YXR0YWNoX3N0YXRlICYgUEVSRl9BVFRBQ0hfVEFTSykKCQkJanVtcF9sYWJlbF9pbmMoJnBlcmZfdGFza19ldmVudHMpOwoJCWlmIChldmVudC0+YXR0ci5tbWFwIHx8IGV2ZW50LT5hdHRyLm1tYXBfZGF0YSkKCQkJYXRvbWljX2luYygmbnJfbW1hcF9ldmVudHMpOwoJCWlmIChldmVudC0+YXR0ci5jb21tKQoJCQlhdG9taWNfaW5jKCZucl9jb21tX2V2ZW50cyk7CgkJaWYgKGV2ZW50LT5hdHRyLnRhc2spCgkJCWF0b21pY19pbmMoJm5yX3Rhc2tfZXZlbnRzKTsKCQlpZiAoZXZlbnQtPmF0dHIuc2FtcGxlX3R5cGUgJiBQRVJGX1NBTVBMRV9DQUxMQ0hBSU4pIHsKCQkJZXJyID0gZ2V0X2NhbGxjaGFpbl9idWZmZXJzKCk7CgkJCWlmIChlcnIpIHsKCQkJCWZyZWVfZXZlbnQoZXZlbnQpOwoJCQkJcmV0dXJuIEVSUl9QVFIoZXJyKTsKCQkJfQoJCX0KCX0KCglyZXR1cm4gZXZlbnQ7Cn0KCnN0YXRpYyBpbnQgcGVyZl9jb3B5X2F0dHIoc3RydWN0IHBlcmZfZXZlbnRfYXR0ciBfX3VzZXIgKnVhdHRyLAoJCQkgIHN0cnVjdCBwZXJmX2V2ZW50X2F0dHIgKmF0dHIpCnsKCXUzMiBzaXplOwoJaW50IHJldDsKCglpZiAoIWFjY2Vzc19vayhWRVJJRllfV1JJVEUsIHVhdHRyLCBQRVJGX0FUVFJfU0laRV9WRVIwKSkKCQlyZXR1cm4gLUVGQVVMVDsKCgkvKgoJICogemVybyB0aGUgZnVsbCBzdHJ1Y3R1cmUsIHNvIHRoYXQgYSBzaG9ydCBjb3B5IHdpbGwgYmUgbmljZS4KCSAqLwoJbWVtc2V0KGF0dHIsIDAsIHNpemVvZigqYXR0cikpOwoKCXJldCA9IGdldF91c2VyKHNpemUsICZ1YXR0ci0+c2l6ZSk7CglpZiAocmV0KQoJCXJldHVybiByZXQ7CgoJaWYgKHNpemUgPiBQQUdFX1NJWkUpCS8qIHNpbGx5IGxhcmdlICovCgkJZ290byBlcnJfc2l6ZTsKCglpZiAoIXNpemUpCQkvKiBhYmkgY29tcGF0ICovCgkJc2l6ZSA9IFBFUkZfQVRUUl9TSVpFX1ZFUjA7CgoJaWYgKHNpemUgPCBQRVJGX0FUVFJfU0laRV9WRVIwKQoJCWdvdG8gZXJyX3NpemU7CgoJLyoKCSAqIElmIHdlJ3JlIGhhbmRlZCBhIGJpZ2dlciBzdHJ1Y3QgdGhhbiB3ZSBrbm93IG9mLAoJICogZW5zdXJlIGFsbCB0aGUgdW5rbm93biBiaXRzIGFyZSAwIC0gaS5lLiBuZXcKCSAqIHVzZXItc3BhY2UgZG9lcyBub3QgcmVseSBvbiBhbnkga2VybmVsIGZlYXR1cmUKCSAqIGV4dGVuc2lvbnMgd2UgZG9udCBrbm93IGFib3V0IHlldC4KCSAqLwoJaWYgKHNpemUgPiBzaXplb2YoKmF0dHIpKSB7CgkJdW5zaWduZWQgY2hhciBfX3VzZXIgKmFkZHI7CgkJdW5zaWduZWQgY2hhciBfX3VzZXIgKmVuZDsKCQl1bnNpZ25lZCBjaGFyIHZhbDsKCgkJYWRkciA9ICh2b2lkIF9fdXNlciAqKXVhdHRyICsgc2l6ZW9mKCphdHRyKTsKCQllbmQgID0gKHZvaWQgX191c2VyICopdWF0dHIgKyBzaXplOwoKCQlmb3IgKDsgYWRkciA8IGVuZDsgYWRkcisrKSB7CgkJCXJldCA9IGdldF91c2VyKHZhbCwgYWRkcik7CgkJCWlmIChyZXQpCgkJCQlyZXR1cm4gcmV0OwoJCQlpZiAodmFsKQoJCQkJZ290byBlcnJfc2l6ZTsKCQl9CgkJc2l6ZSA9IHNpemVvZigqYXR0cik7Cgl9CgoJcmV0ID0gY29weV9mcm9tX3VzZXIoYXR0ciwgdWF0dHIsIHNpemUpOwoJaWYgKHJldCkKCQlyZXR1cm4gLUVGQVVMVDsKCgkvKgoJICogSWYgdGhlIHR5cGUgZXhpc3RzLCB0aGUgY29ycmVzcG9uZGluZyBjcmVhdGlvbiB3aWxsIHZlcmlmeQoJICogdGhlIGF0dHItPmNvbmZpZy4KCSAqLwoJaWYgKGF0dHItPnR5cGUgPj0gUEVSRl9UWVBFX01BWCkKCQlyZXR1cm4gLUVJTlZBTDsKCglpZiAoYXR0ci0+X19yZXNlcnZlZF8xKQoJCXJldHVybiAtRUlOVkFMOwoKCWlmIChhdHRyLT5zYW1wbGVfdHlwZSAmIH4oUEVSRl9TQU1QTEVfTUFYLTEpKQoJCXJldHVybiAtRUlOVkFMOwoKCWlmIChhdHRyLT5yZWFkX2Zvcm1hdCAmIH4oUEVSRl9GT1JNQVRfTUFYLTEpKQoJCXJldHVybiAtRUlOVkFMOwoKb3V0OgoJcmV0dXJuIHJldDsKCmVycl9zaXplOgoJcHV0X3VzZXIoc2l6ZW9mKCphdHRyKSwgJnVhdHRyLT5zaXplKTsKCXJldCA9IC1FMkJJRzsKCWdvdG8gb3V0Owp9CgpzdGF0aWMgaW50CnBlcmZfZXZlbnRfc2V0X291dHB1dChzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQsIHN0cnVjdCBwZXJmX2V2ZW50ICpvdXRwdXRfZXZlbnQpCnsKCXN0cnVjdCBwZXJmX2J1ZmZlciAqYnVmZmVyID0gTlVMTCwgKm9sZF9idWZmZXIgPSBOVUxMOwoJaW50IHJldCA9IC1FSU5WQUw7CgoJaWYgKCFvdXRwdXRfZXZlbnQpCgkJZ290byBzZXQ7CgoJLyogZG9uJ3QgYWxsb3cgY2lyY3VsYXIgcmVmZXJlbmNlcyAqLwoJaWYgKGV2ZW50ID09IG91dHB1dF9ldmVudCkKCQlnb3RvIG91dDsKCgkvKgoJICogRG9uJ3QgYWxsb3cgY3Jvc3MtY3B1IGJ1ZmZlcnMKCSAqLwoJaWYgKG91dHB1dF9ldmVudC0+Y3B1ICE9IGV2ZW50LT5jcHUpCgkJZ290byBvdXQ7CgoJLyoKCSAqIElmIGl0cyBub3QgYSBwZXItY3B1IGJ1ZmZlciwgaXQgbXVzdCBiZSB0aGUgc2FtZSB0YXNrLgoJICovCglpZiAob3V0cHV0X2V2ZW50LT5jcHUgPT0gLTEgJiYgb3V0cHV0X2V2ZW50LT5jdHggIT0gZXZlbnQtPmN0eCkKCQlnb3RvIG91dDsKCnNldDoKCW11dGV4X2xvY2soJmV2ZW50LT5tbWFwX211dGV4KTsKCS8qIENhbid0IHJlZGlyZWN0IG91dHB1dCBpZiB3ZSd2ZSBnb3QgYW4gYWN0aXZlIG1tYXAoKSAqLwoJaWYgKGF0b21pY19yZWFkKCZldmVudC0+bW1hcF9jb3VudCkpCgkJZ290byB1bmxvY2s7CgoJaWYgKG91dHB1dF9ldmVudCkgewoJCS8qIGdldCB0aGUgYnVmZmVyIHdlIHdhbnQgdG8gcmVkaXJlY3QgdG8gKi8KCQlidWZmZXIgPSBwZXJmX2J1ZmZlcl9nZXQob3V0cHV0X2V2ZW50KTsKCQlpZiAoIWJ1ZmZlcikKCQkJZ290byB1bmxvY2s7Cgl9CgoJb2xkX2J1ZmZlciA9IGV2ZW50LT5idWZmZXI7CglyY3VfYXNzaWduX3BvaW50ZXIoZXZlbnQtPmJ1ZmZlciwgYnVmZmVyKTsKCXJldCA9IDA7CnVubG9jazoKCW11dGV4X3VubG9jaygmZXZlbnQtPm1tYXBfbXV0ZXgpOwoKCWlmIChvbGRfYnVmZmVyKQoJCXBlcmZfYnVmZmVyX3B1dChvbGRfYnVmZmVyKTsKb3V0OgoJcmV0dXJuIHJldDsKfQoKLyoqCiAqIHN5c19wZXJmX2V2ZW50X29wZW4gLSBvcGVuIGEgcGVyZm9ybWFuY2UgZXZlbnQsIGFzc29jaWF0ZSBpdCB0byBhIHRhc2svY3B1CiAqCiAqIEBhdHRyX3VwdHI6CWV2ZW50X2lkIHR5cGUgYXR0cmlidXRlcyBmb3IgbW9uaXRvcmluZy9zYW1wbGluZwogKiBAcGlkOgkJdGFyZ2V0IHBpZAogKiBAY3B1OgkJdGFyZ2V0IGNwdQogKiBAZ3JvdXBfZmQ6CQlncm91cCBsZWFkZXIgZXZlbnQgZmQKICovClNZU0NBTExfREVGSU5FNShwZXJmX2V2ZW50X29wZW4sCgkJc3RydWN0IHBlcmZfZXZlbnRfYXR0ciBfX3VzZXIgKiwgYXR0cl91cHRyLAoJCXBpZF90LCBwaWQsIGludCwgY3B1LCBpbnQsIGdyb3VwX2ZkLCB1bnNpZ25lZCBsb25nLCBmbGFncykKewoJc3RydWN0IHBlcmZfZXZlbnQgKmdyb3VwX2xlYWRlciA9IE5VTEwsICpvdXRwdXRfZXZlbnQgPSBOVUxMOwoJc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50LCAqc2libGluZzsKCXN0cnVjdCBwZXJmX2V2ZW50X2F0dHIgYXR0cjsKCXN0cnVjdCBwZXJmX2V2ZW50X2NvbnRleHQgKmN0eDsKCXN0cnVjdCBmaWxlICpldmVudF9maWxlID0gTlVMTDsKCXN0cnVjdCBmaWxlICpncm91cF9maWxlID0gTlVMTDsKCXN0cnVjdCB0YXNrX3N0cnVjdCAqdGFzayA9IE5VTEw7CglzdHJ1Y3QgcG11ICpwbXU7CglpbnQgZXZlbnRfZmQ7CglpbnQgbW92ZV9ncm91cCA9IDA7CglpbnQgZnB1dF9uZWVkZWQgPSAwOwoJaW50IGVycjsKCgkvKiBmb3IgZnV0dXJlIGV4cGFuZGFiaWxpdHkuLi4gKi8KCWlmIChmbGFncyAmIH4oUEVSRl9GTEFHX0ZEX05PX0dST1VQIHwgUEVSRl9GTEFHX0ZEX09VVFBVVCkpCgkJcmV0dXJuIC1FSU5WQUw7CgoJZXJyID0gcGVyZl9jb3B5X2F0dHIoYXR0cl91cHRyLCAmYXR0cik7CglpZiAoZXJyKQoJCXJldHVybiBlcnI7CgoJaWYgKCFhdHRyLmV4Y2x1ZGVfa2VybmVsKSB7CgkJaWYgKHBlcmZfcGFyYW5vaWRfa2VybmVsKCkgJiYgIWNhcGFibGUoQ0FQX1NZU19BRE1JTikpCgkJCXJldHVybiAtRUFDQ0VTOwoJfQoKCWlmIChhdHRyLmZyZXEpIHsKCQlpZiAoYXR0ci5zYW1wbGVfZnJlcSA+IHN5c2N0bF9wZXJmX2V2ZW50X3NhbXBsZV9yYXRlKQoJCQlyZXR1cm4gLUVJTlZBTDsKCX0KCglldmVudF9mZCA9IGdldF91bnVzZWRfZmRfZmxhZ3MoT19SRFdSKTsKCWlmIChldmVudF9mZCA8IDApCgkJcmV0dXJuIGV2ZW50X2ZkOwoKCWlmIChncm91cF9mZCAhPSAtMSkgewoJCWdyb3VwX2xlYWRlciA9IHBlcmZfZmdldF9saWdodChncm91cF9mZCwgJmZwdXRfbmVlZGVkKTsKCQlpZiAoSVNfRVJSKGdyb3VwX2xlYWRlcikpIHsKCQkJZXJyID0gUFRSX0VSUihncm91cF9sZWFkZXIpOwoJCQlnb3RvIGVycl9mZDsKCQl9CgkJZ3JvdXBfZmlsZSA9IGdyb3VwX2xlYWRlci0+ZmlscDsKCQlpZiAoZmxhZ3MgJiBQRVJGX0ZMQUdfRkRfT1VUUFVUKQoJCQlvdXRwdXRfZXZlbnQgPSBncm91cF9sZWFkZXI7CgkJaWYgKGZsYWdzICYgUEVSRl9GTEFHX0ZEX05PX0dST1VQKQoJCQlncm91cF9sZWFkZXIgPSBOVUxMOwoJfQoKCWlmIChwaWQgIT0gLTEpIHsKCQl0YXNrID0gZmluZF9saXZlbHlfdGFza19ieV92cGlkKHBpZCk7CgkJaWYgKElTX0VSUih0YXNrKSkgewoJCQllcnIgPSBQVFJfRVJSKHRhc2spOwoJCQlnb3RvIGVycl9ncm91cF9mZDsKCQl9Cgl9CgoJZXZlbnQgPSBwZXJmX2V2ZW50X2FsbG9jKCZhdHRyLCBjcHUsIHRhc2ssIGdyb3VwX2xlYWRlciwgTlVMTCwgTlVMTCk7CglpZiAoSVNfRVJSKGV2ZW50KSkgewoJCWVyciA9IFBUUl9FUlIoZXZlbnQpOwoJCWdvdG8gZXJyX3Rhc2s7Cgl9CgoJLyoKCSAqIFNwZWNpYWwgY2FzZSBzb2Z0d2FyZSBldmVudHMgYW5kIGFsbG93IHRoZW0gdG8gYmUgcGFydCBvZgoJICogYW55IGhhcmR3YXJlIGdyb3VwLgoJICovCglwbXUgPSBldmVudC0+cG11OwoKCWlmIChncm91cF9sZWFkZXIgJiYKCSAgICAoaXNfc29mdHdhcmVfZXZlbnQoZXZlbnQpICE9IGlzX3NvZnR3YXJlX2V2ZW50KGdyb3VwX2xlYWRlcikpKSB7CgkJaWYgKGlzX3NvZnR3YXJlX2V2ZW50KGV2ZW50KSkgewoJCQkvKgoJCQkgKiBJZiBldmVudCBhbmQgZ3JvdXBfbGVhZGVyIGFyZSBub3QgYm90aCBhIHNvZnR3YXJlCgkJCSAqIGV2ZW50LCBhbmQgZXZlbnQgaXMsIHRoZW4gZ3JvdXAgbGVhZGVyIGlzIG5vdC4KCQkJICoKCQkJICogQWxsb3cgdGhlIGFkZGl0aW9uIG9mIHNvZnR3YXJlIGV2ZW50cyB0byAhc29mdHdhcmUKCQkJICogZ3JvdXBzLCB0aGlzIGlzIHNhZmUgYmVjYXVzZSBzb2Z0d2FyZSBldmVudHMgbmV2ZXIKCQkJICogZmFpbCB0byBzY2hlZHVsZS4KCQkJICovCgkJCXBtdSA9IGdyb3VwX2xlYWRlci0+cG11OwoJCX0gZWxzZSBpZiAoaXNfc29mdHdhcmVfZXZlbnQoZ3JvdXBfbGVhZGVyKSAmJgoJCQkgICAoZ3JvdXBfbGVhZGVyLT5ncm91cF9mbGFncyAmIFBFUkZfR1JPVVBfU09GVFdBUkUpKSB7CgkJCS8qCgkJCSAqIEluIGNhc2UgdGhlIGdyb3VwIGlzIGEgcHVyZSBzb2Z0d2FyZSBncm91cCwgYW5kIHdlCgkJCSAqIHRyeSB0byBhZGQgYSBoYXJkd2FyZSBldmVudCwgbW92ZSB0aGUgd2hvbGUgZ3JvdXAgdG8KCQkJICogdGhlIGhhcmR3YXJlIGNvbnRleHQuCgkJCSAqLwoJCQltb3ZlX2dyb3VwID0gMTsKCQl9Cgl9CgoJLyoKCSAqIEdldCB0aGUgdGFyZ2V0IGNvbnRleHQgKHRhc2sgb3IgcGVyY3B1KToKCSAqLwoJY3R4ID0gZmluZF9nZXRfY29udGV4dChwbXUsIHRhc2ssIGNwdSk7CglpZiAoSVNfRVJSKGN0eCkpIHsKCQllcnIgPSBQVFJfRVJSKGN0eCk7CgkJZ290byBlcnJfYWxsb2M7Cgl9CgoJLyoKCSAqIExvb2sgdXAgdGhlIGdyb3VwIGxlYWRlciAod2Ugd2lsbCBhdHRhY2ggdGhpcyBldmVudCB0byBpdCk6CgkgKi8KCWlmIChncm91cF9sZWFkZXIpIHsKCQllcnIgPSAtRUlOVkFMOwoKCQkvKgoJCSAqIERvIG5vdCBhbGxvdyBhIHJlY3Vyc2l2ZSBoaWVyYXJjaHkgKHRoaXMgbmV3IHNpYmxpbmcKCQkgKiBiZWNvbWluZyBwYXJ0IG9mIGFub3RoZXIgZ3JvdXAtc2libGluZyk6CgkJICovCgkJaWYgKGdyb3VwX2xlYWRlci0+Z3JvdXBfbGVhZGVyICE9IGdyb3VwX2xlYWRlcikKCQkJZ290byBlcnJfY29udGV4dDsKCQkvKgoJCSAqIERvIG5vdCBhbGxvdyB0byBhdHRhY2ggdG8gYSBncm91cCBpbiBhIGRpZmZlcmVudAoJCSAqIHRhc2sgb3IgQ1BVIGNvbnRleHQ6CgkJICovCgkJaWYgKG1vdmVfZ3JvdXApIHsKCQkJaWYgKGdyb3VwX2xlYWRlci0+Y3R4LT50eXBlICE9IGN0eC0+dHlwZSkKCQkJCWdvdG8gZXJyX2NvbnRleHQ7CgkJfSBlbHNlIHsKCQkJaWYgKGdyb3VwX2xlYWRlci0+Y3R4ICE9IGN0eCkKCQkJCWdvdG8gZXJyX2NvbnRleHQ7CgkJfQoKCQkvKgoJCSAqIE9ubHkgYSBncm91cCBsZWFkZXIgY2FuIGJlIGV4Y2x1c2l2ZSBvciBwaW5uZWQKCQkgKi8KCQlpZiAoYXR0ci5leGNsdXNpdmUgfHwgYXR0ci5waW5uZWQpCgkJCWdvdG8gZXJyX2NvbnRleHQ7Cgl9CgoJaWYgKG91dHB1dF9ldmVudCkgewoJCWVyciA9IHBlcmZfZXZlbnRfc2V0X291dHB1dChldmVudCwgb3V0cHV0X2V2ZW50KTsKCQlpZiAoZXJyKQoJCQlnb3RvIGVycl9jb250ZXh0OwoJfQoKCWV2ZW50X2ZpbGUgPSBhbm9uX2lub2RlX2dldGZpbGUoIltwZXJmX2V2ZW50XSIsICZwZXJmX2ZvcHMsIGV2ZW50LCBPX1JEV1IpOwoJaWYgKElTX0VSUihldmVudF9maWxlKSkgewoJCWVyciA9IFBUUl9FUlIoZXZlbnRfZmlsZSk7CgkJZ290byBlcnJfY29udGV4dDsKCX0KCglpZiAobW92ZV9ncm91cCkgewoJCXN0cnVjdCBwZXJmX2V2ZW50X2NvbnRleHQgKmdjdHggPSBncm91cF9sZWFkZXItPmN0eDsKCgkJbXV0ZXhfbG9jaygmZ2N0eC0+bXV0ZXgpOwoJCXBlcmZfZXZlbnRfcmVtb3ZlX2Zyb21fY29udGV4dChncm91cF9sZWFkZXIpOwoJCWxpc3RfZm9yX2VhY2hfZW50cnkoc2libGluZywgJmdyb3VwX2xlYWRlci0+c2libGluZ19saXN0LAoJCQkJICAgIGdyb3VwX2VudHJ5KSB7CgkJCXBlcmZfZXZlbnRfcmVtb3ZlX2Zyb21fY29udGV4dChzaWJsaW5nKTsKCQkJcHV0X2N0eChnY3R4KTsKCQl9CgkJbXV0ZXhfdW5sb2NrKCZnY3R4LT5tdXRleCk7CgkJcHV0X2N0eChnY3R4KTsKCX0KCglldmVudC0+ZmlscCA9IGV2ZW50X2ZpbGU7CglXQVJOX09OX09OQ0UoY3R4LT5wYXJlbnRfY3R4KTsKCW11dGV4X2xvY2soJmN0eC0+bXV0ZXgpOwoKCWlmIChtb3ZlX2dyb3VwKSB7CgkJcGVyZl9pbnN0YWxsX2luX2NvbnRleHQoY3R4LCBncm91cF9sZWFkZXIsIGNwdSk7CgkJZ2V0X2N0eChjdHgpOwoJCWxpc3RfZm9yX2VhY2hfZW50cnkoc2libGluZywgJmdyb3VwX2xlYWRlci0+c2libGluZ19saXN0LAoJCQkJICAgIGdyb3VwX2VudHJ5KSB7CgkJCXBlcmZfaW5zdGFsbF9pbl9jb250ZXh0KGN0eCwgc2libGluZywgY3B1KTsKCQkJZ2V0X2N0eChjdHgpOwoJCX0KCX0KCglwZXJmX2luc3RhbGxfaW5fY29udGV4dChjdHgsIGV2ZW50LCBjcHUpOwoJKytjdHgtPmdlbmVyYXRpb247CgltdXRleF91bmxvY2soJmN0eC0+bXV0ZXgpOwoKCWV2ZW50LT5vd25lciA9IGN1cnJlbnQ7CgoJbXV0ZXhfbG9jaygmY3VycmVudC0+cGVyZl9ldmVudF9tdXRleCk7CglsaXN0X2FkZF90YWlsKCZldmVudC0+b3duZXJfZW50cnksICZjdXJyZW50LT5wZXJmX2V2ZW50X2xpc3QpOwoJbXV0ZXhfdW5sb2NrKCZjdXJyZW50LT5wZXJmX2V2ZW50X211dGV4KTsKCgkvKgoJICogUHJlY2FsY3VsYXRlIHNhbXBsZV9kYXRhIHNpemVzCgkgKi8KCXBlcmZfZXZlbnRfX2hlYWRlcl9zaXplKGV2ZW50KTsKCXBlcmZfZXZlbnRfX2lkX2hlYWRlcl9zaXplKGV2ZW50KTsKCgkvKgoJICogRHJvcCB0aGUgcmVmZXJlbmNlIG9uIHRoZSBncm91cF9ldmVudCBhZnRlciBwbGFjaW5nIHRoZQoJICogbmV3IGV2ZW50IG9uIHRoZSBzaWJsaW5nX2xpc3QuIFRoaXMgZW5zdXJlcyBkZXN0cnVjdGlvbgoJICogb2YgdGhlIGdyb3VwIGxlYWRlciB3aWxsIGZpbmQgdGhlIHBvaW50ZXIgdG8gaXRzZWxmIGluCgkgKiBwZXJmX2dyb3VwX2RldGFjaCgpLgoJICovCglmcHV0X2xpZ2h0KGdyb3VwX2ZpbGUsIGZwdXRfbmVlZGVkKTsKCWZkX2luc3RhbGwoZXZlbnRfZmQsIGV2ZW50X2ZpbGUpOwoJcmV0dXJuIGV2ZW50X2ZkOwoKZXJyX2NvbnRleHQ6CglwdXRfY3R4KGN0eCk7CmVycl9hbGxvYzoKCWZyZWVfZXZlbnQoZXZlbnQpOwplcnJfdGFzazoKCWlmICh0YXNrKQoJCXB1dF90YXNrX3N0cnVjdCh0YXNrKTsKZXJyX2dyb3VwX2ZkOgoJZnB1dF9saWdodChncm91cF9maWxlLCBmcHV0X25lZWRlZCk7CmVycl9mZDoKCXB1dF91bnVzZWRfZmQoZXZlbnRfZmQpOwoJcmV0dXJuIGVycjsKfQoKLyoqCiAqIHBlcmZfZXZlbnRfY3JlYXRlX2tlcm5lbF9jb3VudGVyCiAqCiAqIEBhdHRyOiBhdHRyaWJ1dGVzIG9mIHRoZSBjb3VudGVyIHRvIGNyZWF0ZQogKiBAY3B1OiBjcHUgaW4gd2hpY2ggdGhlIGNvdW50ZXIgaXMgYm91bmQKICogQHRhc2s6IHRhc2sgdG8gcHJvZmlsZSAoTlVMTCBmb3IgcGVyY3B1KQogKi8Kc3RydWN0IHBlcmZfZXZlbnQgKgpwZXJmX2V2ZW50X2NyZWF0ZV9rZXJuZWxfY291bnRlcihzdHJ1Y3QgcGVyZl9ldmVudF9hdHRyICphdHRyLCBpbnQgY3B1LAoJCQkJIHN0cnVjdCB0YXNrX3N0cnVjdCAqdGFzaywKCQkJCSBwZXJmX292ZXJmbG93X2hhbmRsZXJfdCBvdmVyZmxvd19oYW5kbGVyKQp7CglzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0ICpjdHg7CglzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQ7CglpbnQgZXJyOwoKCS8qCgkgKiBHZXQgdGhlIHRhcmdldCBjb250ZXh0ICh0YXNrIG9yIHBlcmNwdSk6CgkgKi8KCglldmVudCA9IHBlcmZfZXZlbnRfYWxsb2MoYXR0ciwgY3B1LCB0YXNrLCBOVUxMLCBOVUxMLCBvdmVyZmxvd19oYW5kbGVyKTsKCWlmIChJU19FUlIoZXZlbnQpKSB7CgkJZXJyID0gUFRSX0VSUihldmVudCk7CgkJZ290byBlcnI7Cgl9CgoJY3R4ID0gZmluZF9nZXRfY29udGV4dChldmVudC0+cG11LCB0YXNrLCBjcHUpOwoJaWYgKElTX0VSUihjdHgpKSB7CgkJZXJyID0gUFRSX0VSUihjdHgpOwoJCWdvdG8gZXJyX2ZyZWU7Cgl9CgoJZXZlbnQtPmZpbHAgPSBOVUxMOwoJV0FSTl9PTl9PTkNFKGN0eC0+cGFyZW50X2N0eCk7CgltdXRleF9sb2NrKCZjdHgtPm11dGV4KTsKCXBlcmZfaW5zdGFsbF9pbl9jb250ZXh0KGN0eCwgZXZlbnQsIGNwdSk7CgkrK2N0eC0+Z2VuZXJhdGlvbjsKCW11dGV4X3VubG9jaygmY3R4LT5tdXRleCk7CgoJcmV0dXJuIGV2ZW50OwoKZXJyX2ZyZWU6CglmcmVlX2V2ZW50KGV2ZW50KTsKZXJyOgoJcmV0dXJuIEVSUl9QVFIoZXJyKTsKfQpFWFBPUlRfU1lNQk9MX0dQTChwZXJmX2V2ZW50X2NyZWF0ZV9rZXJuZWxfY291bnRlcik7CgpzdGF0aWMgdm9pZCBzeW5jX2NoaWxkX2V2ZW50KHN0cnVjdCBwZXJmX2V2ZW50ICpjaGlsZF9ldmVudCwKCQkJICAgICAgIHN0cnVjdCB0YXNrX3N0cnVjdCAqY2hpbGQpCnsKCXN0cnVjdCBwZXJmX2V2ZW50ICpwYXJlbnRfZXZlbnQgPSBjaGlsZF9ldmVudC0+cGFyZW50OwoJdTY0IGNoaWxkX3ZhbDsKCglpZiAoY2hpbGRfZXZlbnQtPmF0dHIuaW5oZXJpdF9zdGF0KQoJCXBlcmZfZXZlbnRfcmVhZF9ldmVudChjaGlsZF9ldmVudCwgY2hpbGQpOwoKCWNoaWxkX3ZhbCA9IHBlcmZfZXZlbnRfY291bnQoY2hpbGRfZXZlbnQpOwoKCS8qCgkgKiBBZGQgYmFjayB0aGUgY2hpbGQncyBjb3VudCB0byB0aGUgcGFyZW50J3MgY291bnQ6CgkgKi8KCWF0b21pYzY0X2FkZChjaGlsZF92YWwsICZwYXJlbnRfZXZlbnQtPmNoaWxkX2NvdW50KTsKCWF0b21pYzY0X2FkZChjaGlsZF9ldmVudC0+dG90YWxfdGltZV9lbmFibGVkLAoJCSAgICAgJnBhcmVudF9ldmVudC0+Y2hpbGRfdG90YWxfdGltZV9lbmFibGVkKTsKCWF0b21pYzY0X2FkZChjaGlsZF9ldmVudC0+dG90YWxfdGltZV9ydW5uaW5nLAoJCSAgICAgJnBhcmVudF9ldmVudC0+Y2hpbGRfdG90YWxfdGltZV9ydW5uaW5nKTsKCgkvKgoJICogUmVtb3ZlIHRoaXMgZXZlbnQgZnJvbSB0aGUgcGFyZW50J3MgbGlzdAoJICovCglXQVJOX09OX09OQ0UocGFyZW50X2V2ZW50LT5jdHgtPnBhcmVudF9jdHgpOwoJbXV0ZXhfbG9jaygmcGFyZW50X2V2ZW50LT5jaGlsZF9tdXRleCk7CglsaXN0X2RlbF9pbml0KCZjaGlsZF9ldmVudC0+Y2hpbGRfbGlzdCk7CgltdXRleF91bmxvY2soJnBhcmVudF9ldmVudC0+Y2hpbGRfbXV0ZXgpOwoKCS8qCgkgKiBSZWxlYXNlIHRoZSBwYXJlbnQgZXZlbnQsIGlmIHRoaXMgd2FzIHRoZSBsYXN0CgkgKiByZWZlcmVuY2UgdG8gaXQuCgkgKi8KCWZwdXQocGFyZW50X2V2ZW50LT5maWxwKTsKfQoKc3RhdGljIHZvaWQKX19wZXJmX2V2ZW50X2V4aXRfdGFzayhzdHJ1Y3QgcGVyZl9ldmVudCAqY2hpbGRfZXZlbnQsCgkJCSBzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0ICpjaGlsZF9jdHgsCgkJCSBzdHJ1Y3QgdGFza19zdHJ1Y3QgKmNoaWxkKQp7CglzdHJ1Y3QgcGVyZl9ldmVudCAqcGFyZW50X2V2ZW50OwoKCXBlcmZfZXZlbnRfcmVtb3ZlX2Zyb21fY29udGV4dChjaGlsZF9ldmVudCk7CgoJcGFyZW50X2V2ZW50ID0gY2hpbGRfZXZlbnQtPnBhcmVudDsKCS8qCgkgKiBJdCBjYW4gaGFwcGVuIHRoYXQgcGFyZW50IGV4aXRzIGZpcnN0LCBhbmQgaGFzIGV2ZW50cwoJICogdGhhdCBhcmUgc3RpbGwgYXJvdW5kIGR1ZSB0byB0aGUgY2hpbGQgcmVmZXJlbmNlLiBUaGVzZQoJICogZXZlbnRzIG5lZWQgdG8gYmUgemFwcGVkIC0gYnV0IG90aGVyd2lzZSBsaW5nZXIuCgkgKi8KCWlmIChwYXJlbnRfZXZlbnQpIHsKCQlzeW5jX2NoaWxkX2V2ZW50KGNoaWxkX2V2ZW50LCBjaGlsZCk7CgkJZnJlZV9ldmVudChjaGlsZF9ldmVudCk7Cgl9Cn0KCnN0YXRpYyB2b2lkIHBlcmZfZXZlbnRfZXhpdF90YXNrX2NvbnRleHQoc3RydWN0IHRhc2tfc3RydWN0ICpjaGlsZCwgaW50IGN0eG4pCnsKCXN0cnVjdCBwZXJmX2V2ZW50ICpjaGlsZF9ldmVudCwgKnRtcDsKCXN0cnVjdCBwZXJmX2V2ZW50X2NvbnRleHQgKmNoaWxkX2N0eDsKCXVuc2lnbmVkIGxvbmcgZmxhZ3M7CgoJaWYgKGxpa2VseSghY2hpbGQtPnBlcmZfZXZlbnRfY3R4cFtjdHhuXSkpIHsKCQlwZXJmX2V2ZW50X3Rhc2soY2hpbGQsIE5VTEwsIDApOwoJCXJldHVybjsKCX0KCglsb2NhbF9pcnFfc2F2ZShmbGFncyk7CgkvKgoJICogV2UgY2FuJ3QgcmVzY2hlZHVsZSBoZXJlIGJlY2F1c2UgaW50ZXJydXB0cyBhcmUgZGlzYWJsZWQsCgkgKiBhbmQgZWl0aGVyIGNoaWxkIGlzIGN1cnJlbnQgb3IgaXQgaXMgYSB0YXNrIHRoYXQgY2FuJ3QgYmUKCSAqIHNjaGVkdWxlZCwgc28gd2UgYXJlIG5vdyBzYWZlIGZyb20gcmVzY2hlZHVsaW5nIGNoYW5naW5nCgkgKiBvdXIgY29udGV4dC4KCSAqLwoJY2hpbGRfY3R4ID0gY2hpbGQtPnBlcmZfZXZlbnRfY3R4cFtjdHhuXTsKCXRhc2tfY3R4X3NjaGVkX291dChjaGlsZF9jdHgsIEVWRU5UX0FMTCk7CgoJLyoKCSAqIFRha2UgdGhlIGNvbnRleHQgbG9jayBoZXJlIHNvIHRoYXQgaWYgZmluZF9nZXRfY29udGV4dCBpcwoJICogcmVhZGluZyBjaGlsZC0+cGVyZl9ldmVudF9jdHhwLCB3ZSB3YWl0IHVudGlsIGl0IGhhcwoJICogaW5jcmVtZW50ZWQgdGhlIGNvbnRleHQncyByZWZjb3VudCBiZWZvcmUgd2UgZG8gcHV0X2N0eCBiZWxvdy4KCSAqLwoJcmF3X3NwaW5fbG9jaygmY2hpbGRfY3R4LT5sb2NrKTsKCWNoaWxkLT5wZXJmX2V2ZW50X2N0eHBbY3R4bl0gPSBOVUxMOwoJLyoKCSAqIElmIHRoaXMgY29udGV4dCBpcyBhIGNsb25lOyB1bmNsb25lIGl0IHNvIGl0IGNhbid0IGdldAoJICogc3dhcHBlZCB0byBhbm90aGVyIHByb2Nlc3Mgd2hpbGUgd2UncmUgcmVtb3ZpbmcgYWxsCgkgKiB0aGUgZXZlbnRzIGZyb20gaXQuCgkgKi8KCXVuY2xvbmVfY3R4KGNoaWxkX2N0eCk7Cgl1cGRhdGVfY29udGV4dF90aW1lKGNoaWxkX2N0eCk7CglyYXdfc3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmY2hpbGRfY3R4LT5sb2NrLCBmbGFncyk7CgoJLyoKCSAqIFJlcG9ydCB0aGUgdGFzayBkZWFkIGFmdGVyIHVuc2NoZWR1bGluZyB0aGUgZXZlbnRzIHNvIHRoYXQgd2UKCSAqIHdvbid0IGdldCBhbnkgc2FtcGxlcyBhZnRlciBQRVJGX1JFQ09SRF9FWElULiBXZSBjYW4gaG93ZXZlciBzdGlsbAoJICogZ2V0IGEgZmV3IFBFUkZfUkVDT1JEX1JFQUQgZXZlbnRzLgoJICovCglwZXJmX2V2ZW50X3Rhc2soY2hpbGQsIGNoaWxkX2N0eCwgMCk7CgoJLyoKCSAqIFdlIGNhbiByZWN1cnNlIG9uIHRoZSBzYW1lIGxvY2sgdHlwZSB0aHJvdWdoOgoJICoKCSAqICAgX19wZXJmX2V2ZW50X2V4aXRfdGFzaygpCgkgKiAgICAgc3luY19jaGlsZF9ldmVudCgpCgkgKiAgICAgICBmcHV0KHBhcmVudF9ldmVudC0+ZmlscCkKCSAqICAgICAgICAgcGVyZl9yZWxlYXNlKCkKCSAqICAgICAgICAgICBtdXRleF9sb2NrKCZjdHgtPm11dGV4KQoJICoKCSAqIEJ1dCBzaW5jZSBpdHMgdGhlIHBhcmVudCBjb250ZXh0IGl0IHdvbid0IGJlIHRoZSBzYW1lIGluc3RhbmNlLgoJICovCgltdXRleF9sb2NrKCZjaGlsZF9jdHgtPm11dGV4KTsKCmFnYWluOgoJbGlzdF9mb3JfZWFjaF9lbnRyeV9zYWZlKGNoaWxkX2V2ZW50LCB0bXAsICZjaGlsZF9jdHgtPnBpbm5lZF9ncm91cHMsCgkJCQkgZ3JvdXBfZW50cnkpCgkJX19wZXJmX2V2ZW50X2V4aXRfdGFzayhjaGlsZF9ldmVudCwgY2hpbGRfY3R4LCBjaGlsZCk7CgoJbGlzdF9mb3JfZWFjaF9lbnRyeV9zYWZlKGNoaWxkX2V2ZW50LCB0bXAsICZjaGlsZF9jdHgtPmZsZXhpYmxlX2dyb3VwcywKCQkJCSBncm91cF9lbnRyeSkKCQlfX3BlcmZfZXZlbnRfZXhpdF90YXNrKGNoaWxkX2V2ZW50LCBjaGlsZF9jdHgsIGNoaWxkKTsKCgkvKgoJICogSWYgdGhlIGxhc3QgZXZlbnQgd2FzIGEgZ3JvdXAgZXZlbnQsIGl0IHdpbGwgaGF2ZSBhcHBlbmRlZCBhbGwKCSAqIGl0cyBzaWJsaW5ncyB0byB0aGUgbGlzdCwgYnV0IHdlIG9idGFpbmVkICd0bXAnIGJlZm9yZSB0aGF0IHdoaWNoCgkgKiB3aWxsIHN0aWxsIHBvaW50IHRvIHRoZSBsaXN0IGhlYWQgdGVybWluYXRpbmcgdGhlIGl0ZXJhdGlvbi4KCSAqLwoJaWYgKCFsaXN0X2VtcHR5KCZjaGlsZF9jdHgtPnBpbm5lZF9ncm91cHMpIHx8CgkgICAgIWxpc3RfZW1wdHkoJmNoaWxkX2N0eC0+ZmxleGlibGVfZ3JvdXBzKSkKCQlnb3RvIGFnYWluOwoKCW11dGV4X3VubG9jaygmY2hpbGRfY3R4LT5tdXRleCk7CgoJcHV0X2N0eChjaGlsZF9jdHgpOwp9CgovKgogKiBXaGVuIGEgY2hpbGQgdGFzayBleGl0cywgZmVlZCBiYWNrIGV2ZW50IHZhbHVlcyB0byBwYXJlbnQgZXZlbnRzLgogKi8Kdm9pZCBwZXJmX2V2ZW50X2V4aXRfdGFzayhzdHJ1Y3QgdGFza19zdHJ1Y3QgKmNoaWxkKQp7CglzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQsICp0bXA7CglpbnQgY3R4bjsKCgltdXRleF9sb2NrKCZjaGlsZC0+cGVyZl9ldmVudF9tdXRleCk7CglsaXN0X2Zvcl9lYWNoX2VudHJ5X3NhZmUoZXZlbnQsIHRtcCwgJmNoaWxkLT5wZXJmX2V2ZW50X2xpc3QsCgkJCQkgb3duZXJfZW50cnkpIHsKCQlsaXN0X2RlbF9pbml0KCZldmVudC0+b3duZXJfZW50cnkpOwoKCQkvKgoJCSAqIEVuc3VyZSB0aGUgbGlzdCBkZWxldGlvbiBpcyB2aXNpYmxlIGJlZm9yZSB3ZSBjbGVhcgoJCSAqIHRoZSBvd25lciwgY2xvc2VzIGEgcmFjZSBhZ2FpbnN0IHBlcmZfcmVsZWFzZSgpIHdoZXJlCgkJICogd2UgbmVlZCB0byBzZXJpYWxpemUgb24gdGhlIG93bmVyLT5wZXJmX2V2ZW50X211dGV4LgoJCSAqLwoJCXNtcF93bWIoKTsKCQlldmVudC0+b3duZXIgPSBOVUxMOwoJfQoJbXV0ZXhfdW5sb2NrKCZjaGlsZC0+cGVyZl9ldmVudF9tdXRleCk7CgoJZm9yX2VhY2hfdGFza19jb250ZXh0X25yKGN0eG4pCgkJcGVyZl9ldmVudF9leGl0X3Rhc2tfY29udGV4dChjaGlsZCwgY3R4bik7Cn0KCnN0YXRpYyB2b2lkIHBlcmZfZnJlZV9ldmVudChzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQsCgkJCSAgICBzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0ICpjdHgpCnsKCXN0cnVjdCBwZXJmX2V2ZW50ICpwYXJlbnQgPSBldmVudC0+cGFyZW50OwoKCWlmIChXQVJOX09OX09OQ0UoIXBhcmVudCkpCgkJcmV0dXJuOwoKCW11dGV4X2xvY2soJnBhcmVudC0+Y2hpbGRfbXV0ZXgpOwoJbGlzdF9kZWxfaW5pdCgmZXZlbnQtPmNoaWxkX2xpc3QpOwoJbXV0ZXhfdW5sb2NrKCZwYXJlbnQtPmNoaWxkX211dGV4KTsKCglmcHV0KHBhcmVudC0+ZmlscCk7CgoJcGVyZl9ncm91cF9kZXRhY2goZXZlbnQpOwoJbGlzdF9kZWxfZXZlbnQoZXZlbnQsIGN0eCk7CglmcmVlX2V2ZW50KGV2ZW50KTsKfQoKLyoKICogZnJlZSBhbiB1bmV4cG9zZWQsIHVudXNlZCBjb250ZXh0IGFzIGNyZWF0ZWQgYnkgaW5oZXJpdGFuY2UgYnkKICogcGVyZl9ldmVudF9pbml0X3Rhc2sgYmVsb3csIHVzZWQgYnkgZm9yaygpIGluIGNhc2Ugb2YgZmFpbC4KICovCnZvaWQgcGVyZl9ldmVudF9mcmVlX3Rhc2soc3RydWN0IHRhc2tfc3RydWN0ICp0YXNrKQp7CglzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0ICpjdHg7CglzdHJ1Y3QgcGVyZl9ldmVudCAqZXZlbnQsICp0bXA7CglpbnQgY3R4bjsKCglmb3JfZWFjaF90YXNrX2NvbnRleHRfbnIoY3R4bikgewoJCWN0eCA9IHRhc2stPnBlcmZfZXZlbnRfY3R4cFtjdHhuXTsKCQlpZiAoIWN0eCkKCQkJY29udGludWU7CgoJCW11dGV4X2xvY2soJmN0eC0+bXV0ZXgpOwphZ2FpbjoKCQlsaXN0X2Zvcl9lYWNoX2VudHJ5X3NhZmUoZXZlbnQsIHRtcCwgJmN0eC0+cGlubmVkX2dyb3VwcywKCQkJCWdyb3VwX2VudHJ5KQoJCQlwZXJmX2ZyZWVfZXZlbnQoZXZlbnQsIGN0eCk7CgoJCWxpc3RfZm9yX2VhY2hfZW50cnlfc2FmZShldmVudCwgdG1wLCAmY3R4LT5mbGV4aWJsZV9ncm91cHMsCgkJCQlncm91cF9lbnRyeSkKCQkJcGVyZl9mcmVlX2V2ZW50KGV2ZW50LCBjdHgpOwoKCQlpZiAoIWxpc3RfZW1wdHkoJmN0eC0+cGlubmVkX2dyb3VwcykgfHwKCQkJCSFsaXN0X2VtcHR5KCZjdHgtPmZsZXhpYmxlX2dyb3VwcykpCgkJCWdvdG8gYWdhaW47CgoJCW11dGV4X3VubG9jaygmY3R4LT5tdXRleCk7CgoJCXB1dF9jdHgoY3R4KTsKCX0KfQoKdm9pZCBwZXJmX2V2ZW50X2RlbGF5ZWRfcHV0KHN0cnVjdCB0YXNrX3N0cnVjdCAqdGFzaykKewoJaW50IGN0eG47CgoJZm9yX2VhY2hfdGFza19jb250ZXh0X25yKGN0eG4pCgkJV0FSTl9PTl9PTkNFKHRhc2stPnBlcmZfZXZlbnRfY3R4cFtjdHhuXSk7Cn0KCi8qCiAqIGluaGVyaXQgYSBldmVudCBmcm9tIHBhcmVudCB0YXNrIHRvIGNoaWxkIHRhc2s6CiAqLwpzdGF0aWMgc3RydWN0IHBlcmZfZXZlbnQgKgppbmhlcml0X2V2ZW50KHN0cnVjdCBwZXJmX2V2ZW50ICpwYXJlbnRfZXZlbnQsCgkgICAgICBzdHJ1Y3QgdGFza19zdHJ1Y3QgKnBhcmVudCwKCSAgICAgIHN0cnVjdCBwZXJmX2V2ZW50X2NvbnRleHQgKnBhcmVudF9jdHgsCgkgICAgICBzdHJ1Y3QgdGFza19zdHJ1Y3QgKmNoaWxkLAoJICAgICAgc3RydWN0IHBlcmZfZXZlbnQgKmdyb3VwX2xlYWRlciwKCSAgICAgIHN0cnVjdCBwZXJmX2V2ZW50X2NvbnRleHQgKmNoaWxkX2N0eCkKewoJc3RydWN0IHBlcmZfZXZlbnQgKmNoaWxkX2V2ZW50OwoJdW5zaWduZWQgbG9uZyBmbGFnczsKCgkvKgoJICogSW5zdGVhZCBvZiBjcmVhdGluZyByZWN1cnNpdmUgaGllcmFyY2hpZXMgb2YgZXZlbnRzLAoJICogd2UgbGluayBpbmhlcml0ZWQgZXZlbnRzIGJhY2sgdG8gdGhlIG9yaWdpbmFsIHBhcmVudCwKCSAqIHdoaWNoIGhhcyBhIGZpbHAgZm9yIHN1cmUsIHdoaWNoIHdlIHVzZSBhcyB0aGUgcmVmZXJlbmNlCgkgKiBjb3VudDoKCSAqLwoJaWYgKHBhcmVudF9ldmVudC0+cGFyZW50KQoJCXBhcmVudF9ldmVudCA9IHBhcmVudF9ldmVudC0+cGFyZW50OwoKCWNoaWxkX2V2ZW50ID0gcGVyZl9ldmVudF9hbGxvYygmcGFyZW50X2V2ZW50LT5hdHRyLAoJCQkJCSAgIHBhcmVudF9ldmVudC0+Y3B1LAoJCQkJCSAgIGNoaWxkLAoJCQkJCSAgIGdyb3VwX2xlYWRlciwgcGFyZW50X2V2ZW50LAoJCQkJCSAgIE5VTEwpOwoJaWYgKElTX0VSUihjaGlsZF9ldmVudCkpCgkJcmV0dXJuIGNoaWxkX2V2ZW50OwoJZ2V0X2N0eChjaGlsZF9jdHgpOwoKCS8qCgkgKiBNYWtlIHRoZSBjaGlsZCBzdGF0ZSBmb2xsb3cgdGhlIHN0YXRlIG9mIHRoZSBwYXJlbnQgZXZlbnQsCgkgKiBub3QgaXRzIGF0dHIuZGlzYWJsZWQgYml0LiAgV2UgaG9sZCB0aGUgcGFyZW50J3MgbXV0ZXgsCgkgKiBzbyB3ZSB3b24ndCByYWNlIHdpdGggcGVyZl9ldmVudF97ZW4sIGRpc31hYmxlX2ZhbWlseS4KCSAqLwoJaWYgKHBhcmVudF9ldmVudC0+c3RhdGUgPj0gUEVSRl9FVkVOVF9TVEFURV9JTkFDVElWRSkKCQljaGlsZF9ldmVudC0+c3RhdGUgPSBQRVJGX0VWRU5UX1NUQVRFX0lOQUNUSVZFOwoJZWxzZQoJCWNoaWxkX2V2ZW50LT5zdGF0ZSA9IFBFUkZfRVZFTlRfU1RBVEVfT0ZGOwoKCWlmIChwYXJlbnRfZXZlbnQtPmF0dHIuZnJlcSkgewoJCXU2NCBzYW1wbGVfcGVyaW9kID0gcGFyZW50X2V2ZW50LT5ody5zYW1wbGVfcGVyaW9kOwoJCXN0cnVjdCBod19wZXJmX2V2ZW50ICpod2MgPSAmY2hpbGRfZXZlbnQtPmh3OwoKCQlod2MtPnNhbXBsZV9wZXJpb2QgPSBzYW1wbGVfcGVyaW9kOwoJCWh3Yy0+bGFzdF9wZXJpb2QgICA9IHNhbXBsZV9wZXJpb2Q7CgoJCWxvY2FsNjRfc2V0KCZod2MtPnBlcmlvZF9sZWZ0LCBzYW1wbGVfcGVyaW9kKTsKCX0KCgljaGlsZF9ldmVudC0+Y3R4ID0gY2hpbGRfY3R4OwoJY2hpbGRfZXZlbnQtPm92ZXJmbG93X2hhbmRsZXIgPSBwYXJlbnRfZXZlbnQtPm92ZXJmbG93X2hhbmRsZXI7CgoJLyoKCSAqIFByZWNhbGN1bGF0ZSBzYW1wbGVfZGF0YSBzaXplcwoJICovCglwZXJmX2V2ZW50X19oZWFkZXJfc2l6ZShjaGlsZF9ldmVudCk7CglwZXJmX2V2ZW50X19pZF9oZWFkZXJfc2l6ZShjaGlsZF9ldmVudCk7CgoJLyoKCSAqIExpbmsgaXQgdXAgaW4gdGhlIGNoaWxkJ3MgY29udGV4dDoKCSAqLwoJcmF3X3NwaW5fbG9ja19pcnFzYXZlKCZjaGlsZF9jdHgtPmxvY2ssIGZsYWdzKTsKCWFkZF9ldmVudF90b19jdHgoY2hpbGRfZXZlbnQsIGNoaWxkX2N0eCk7CglyYXdfc3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmY2hpbGRfY3R4LT5sb2NrLCBmbGFncyk7CgoJLyoKCSAqIEdldCBhIHJlZmVyZW5jZSB0byB0aGUgcGFyZW50IGZpbHAgLSB3ZSB3aWxsIGZwdXQgaXQKCSAqIHdoZW4gdGhlIGNoaWxkIGV2ZW50IGV4aXRzLiBUaGlzIGlzIHNhZmUgdG8gZG8gYmVjYXVzZQoJICogd2UgYXJlIGluIHRoZSBwYXJlbnQgYW5kIHdlIGtub3cgdGhhdCB0aGUgZmlscCBzdGlsbAoJICogZXhpc3RzIGFuZCBoYXMgYSBub256ZXJvIGNvdW50OgoJICovCglhdG9taWNfbG9uZ19pbmMoJnBhcmVudF9ldmVudC0+ZmlscC0+Zl9jb3VudCk7CgoJLyoKCSAqIExpbmsgdGhpcyBpbnRvIHRoZSBwYXJlbnQgZXZlbnQncyBjaGlsZCBsaXN0CgkgKi8KCVdBUk5fT05fT05DRShwYXJlbnRfZXZlbnQtPmN0eC0+cGFyZW50X2N0eCk7CgltdXRleF9sb2NrKCZwYXJlbnRfZXZlbnQtPmNoaWxkX211dGV4KTsKCWxpc3RfYWRkX3RhaWwoJmNoaWxkX2V2ZW50LT5jaGlsZF9saXN0LCAmcGFyZW50X2V2ZW50LT5jaGlsZF9saXN0KTsKCW11dGV4X3VubG9jaygmcGFyZW50X2V2ZW50LT5jaGlsZF9tdXRleCk7CgoJcmV0dXJuIGNoaWxkX2V2ZW50Owp9CgpzdGF0aWMgaW50IGluaGVyaXRfZ3JvdXAoc3RydWN0IHBlcmZfZXZlbnQgKnBhcmVudF9ldmVudCwKCSAgICAgIHN0cnVjdCB0YXNrX3N0cnVjdCAqcGFyZW50LAoJICAgICAgc3RydWN0IHBlcmZfZXZlbnRfY29udGV4dCAqcGFyZW50X2N0eCwKCSAgICAgIHN0cnVjdCB0YXNrX3N0cnVjdCAqY2hpbGQsCgkgICAgICBzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0ICpjaGlsZF9jdHgpCnsKCXN0cnVjdCBwZXJmX2V2ZW50ICpsZWFkZXI7CglzdHJ1Y3QgcGVyZl9ldmVudCAqc3ViOwoJc3RydWN0IHBlcmZfZXZlbnQgKmNoaWxkX2N0cjsKCglsZWFkZXIgPSBpbmhlcml0X2V2ZW50KHBhcmVudF9ldmVudCwgcGFyZW50LCBwYXJlbnRfY3R4LAoJCQkJIGNoaWxkLCBOVUxMLCBjaGlsZF9jdHgpOwoJaWYgKElTX0VSUihsZWFkZXIpKQoJCXJldHVybiBQVFJfRVJSKGxlYWRlcik7CglsaXN0X2Zvcl9lYWNoX2VudHJ5KHN1YiwgJnBhcmVudF9ldmVudC0+c2libGluZ19saXN0LCBncm91cF9lbnRyeSkgewoJCWNoaWxkX2N0ciA9IGluaGVyaXRfZXZlbnQoc3ViLCBwYXJlbnQsIHBhcmVudF9jdHgsCgkJCQkJICAgIGNoaWxkLCBsZWFkZXIsIGNoaWxkX2N0eCk7CgkJaWYgKElTX0VSUihjaGlsZF9jdHIpKQoJCQlyZXR1cm4gUFRSX0VSUihjaGlsZF9jdHIpOwoJfQoJcmV0dXJuIDA7Cn0KCnN0YXRpYyBpbnQKaW5oZXJpdF90YXNrX2dyb3VwKHN0cnVjdCBwZXJmX2V2ZW50ICpldmVudCwgc3RydWN0IHRhc2tfc3RydWN0ICpwYXJlbnQsCgkJICAgc3RydWN0IHBlcmZfZXZlbnRfY29udGV4dCAqcGFyZW50X2N0eCwKCQkgICBzdHJ1Y3QgdGFza19zdHJ1Y3QgKmNoaWxkLCBpbnQgY3R4biwKCQkgICBpbnQgKmluaGVyaXRlZF9hbGwpCnsKCWludCByZXQ7CglzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0ICpjaGlsZF9jdHg7CgoJaWYgKCFldmVudC0+YXR0ci5pbmhlcml0KSB7CgkJKmluaGVyaXRlZF9hbGwgPSAwOwoJCXJldHVybiAwOwoJfQoKICAgICAgIAljaGlsZF9jdHggPSBjaGlsZC0+cGVyZl9ldmVudF9jdHhwW2N0eG5dOwoJaWYgKCFjaGlsZF9jdHgpIHsKCQkvKgoJCSAqIFRoaXMgaXMgZXhlY3V0ZWQgZnJvbSB0aGUgcGFyZW50IHRhc2sgY29udGV4dCwgc28KCQkgKiBpbmhlcml0IGV2ZW50cyB0aGF0IGhhdmUgYmVlbiBtYXJrZWQgZm9yIGNsb25pbmcuCgkJICogRmlyc3QgYWxsb2NhdGUgYW5kIGluaXRpYWxpemUgYSBjb250ZXh0IGZvciB0aGUKCQkgKiBjaGlsZC4KCQkgKi8KCgkJY2hpbGRfY3R4ID0gYWxsb2NfcGVyZl9jb250ZXh0KGV2ZW50LT5wbXUsIGNoaWxkKTsKCQlpZiAoIWNoaWxkX2N0eCkKCQkJcmV0dXJuIC1FTk9NRU07CgoJCWNoaWxkLT5wZXJmX2V2ZW50X2N0eHBbY3R4bl0gPSBjaGlsZF9jdHg7Cgl9CgoJcmV0ID0gaW5oZXJpdF9ncm91cChldmVudCwgcGFyZW50LCBwYXJlbnRfY3R4LAoJCQkgICAgY2hpbGQsIGNoaWxkX2N0eCk7CgoJaWYgKHJldCkKCQkqaW5oZXJpdGVkX2FsbCA9IDA7CgoJcmV0dXJuIHJldDsKfQoKLyoKICogSW5pdGlhbGl6ZSB0aGUgcGVyZl9ldmVudCBjb250ZXh0IGluIHRhc2tfc3RydWN0CiAqLwppbnQgcGVyZl9ldmVudF9pbml0X2NvbnRleHQoc3RydWN0IHRhc2tfc3RydWN0ICpjaGlsZCwgaW50IGN0eG4pCnsKCXN0cnVjdCBwZXJmX2V2ZW50X2NvbnRleHQgKmNoaWxkX2N0eCwgKnBhcmVudF9jdHg7CglzdHJ1Y3QgcGVyZl9ldmVudF9jb250ZXh0ICpjbG9uZWRfY3R4OwoJc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50OwoJc3RydWN0IHRhc2tfc3RydWN0ICpwYXJlbnQgPSBjdXJyZW50OwoJaW50IGluaGVyaXRlZF9hbGwgPSAxOwoJdW5zaWduZWQgbG9uZyBmbGFnczsKCWludCByZXQgPSAwOwoKCWNoaWxkLT5wZXJmX2V2ZW50X2N0eHBbY3R4bl0gPSBOVUxMOwoKCW11dGV4X2luaXQoJmNoaWxkLT5wZXJmX2V2ZW50X211dGV4KTsKCUlOSVRfTElTVF9IRUFEKCZjaGlsZC0+cGVyZl9ldmVudF9saXN0KTsKCglpZiAobGlrZWx5KCFwYXJlbnQtPnBlcmZfZXZlbnRfY3R4cFtjdHhuXSkpCgkJcmV0dXJuIDA7CgoJLyoKCSAqIElmIHRoZSBwYXJlbnQncyBjb250ZXh0IGlzIGEgY2xvbmUsIHBpbiBpdCBzbyBpdCB3b24ndCBnZXQKCSAqIHN3YXBwZWQgdW5kZXIgdXMuCgkgKi8KCXBhcmVudF9jdHggPSBwZXJmX3Bpbl90YXNrX2NvbnRleHQocGFyZW50LCBjdHhuKTsKCgkvKgoJICogTm8gbmVlZCB0byBjaGVjayBpZiBwYXJlbnRfY3R4ICE9IE5VTEwgaGVyZTsgc2luY2Ugd2Ugc2F3CgkgKiBpdCBub24tTlVMTCBlYXJsaWVyLCB0aGUgb25seSByZWFzb24gZm9yIGl0IHRvIGJlY29tZSBOVUxMCgkgKiBpcyBpZiB3ZSBleGl0LCBhbmQgc2luY2Ugd2UncmUgY3VycmVudGx5IGluIHRoZSBtaWRkbGUgb2YKCSAqIGEgZm9yayB3ZSBjYW4ndCBiZSBleGl0aW5nIGF0IHRoZSBzYW1lIHRpbWUuCgkgKi8KCgkvKgoJICogTG9jayB0aGUgcGFyZW50IGxpc3QuIE5vIG5lZWQgdG8gbG9jayB0aGUgY2hpbGQgLSBub3QgUElECgkgKiBoYXNoZWQgeWV0IGFuZCBub3QgcnVubmluZywgc28gbm9ib2R5IGNhbiBhY2Nlc3MgaXQuCgkgKi8KCW11dGV4X2xvY2soJnBhcmVudF9jdHgtPm11dGV4KTsKCgkvKgoJICogV2UgZG9udCBoYXZlIHRvIGRpc2FibGUgTk1JcyAtIHdlIGFyZSBvbmx5IGxvb2tpbmcgYXQKCSAqIHRoZSBsaXN0LCBub3QgbWFuaXB1bGF0aW5nIGl0OgoJICovCglsaXN0X2Zvcl9lYWNoX2VudHJ5KGV2ZW50LCAmcGFyZW50X2N0eC0+cGlubmVkX2dyb3VwcywgZ3JvdXBfZW50cnkpIHsKCQlyZXQgPSBpbmhlcml0X3Rhc2tfZ3JvdXAoZXZlbnQsIHBhcmVudCwgcGFyZW50X2N0eCwKCQkJCQkgY2hpbGQsIGN0eG4sICZpbmhlcml0ZWRfYWxsKTsKCQlpZiAocmV0KQoJCQlicmVhazsKCX0KCgkvKgoJICogV2UgY2FuJ3QgaG9sZCBjdHgtPmxvY2sgd2hlbiBpdGVyYXRpbmcgdGhlIC0+ZmxleGlibGVfZ3JvdXAgbGlzdCBkdWUKCSAqIHRvIGFsbG9jYXRpb25zLCBidXQgd2UgbmVlZCB0byBwcmV2ZW50IHJvdGF0aW9uIGJlY2F1c2UKCSAqIHJvdGF0ZV9jdHgoKSB3aWxsIGNoYW5nZSB0aGUgbGlzdCBmcm9tIGludGVycnVwdCBjb250ZXh0LgoJICovCglyYXdfc3Bpbl9sb2NrX2lycXNhdmUoJnBhcmVudF9jdHgtPmxvY2ssIGZsYWdzKTsKCXBhcmVudF9jdHgtPnJvdGF0ZV9kaXNhYmxlID0gMTsKCXJhd19zcGluX3VubG9ja19pcnFyZXN0b3JlKCZwYXJlbnRfY3R4LT5sb2NrLCBmbGFncyk7CgoJbGlzdF9mb3JfZWFjaF9lbnRyeShldmVudCwgJnBhcmVudF9jdHgtPmZsZXhpYmxlX2dyb3VwcywgZ3JvdXBfZW50cnkpIHsKCQlyZXQgPSBpbmhlcml0X3Rhc2tfZ3JvdXAoZXZlbnQsIHBhcmVudCwgcGFyZW50X2N0eCwKCQkJCQkgY2hpbGQsIGN0eG4sICZpbmhlcml0ZWRfYWxsKTsKCQlpZiAocmV0KQoJCQlicmVhazsKCX0KCglyYXdfc3Bpbl9sb2NrX2lycXNhdmUoJnBhcmVudF9jdHgtPmxvY2ssIGZsYWdzKTsKCXBhcmVudF9jdHgtPnJvdGF0ZV9kaXNhYmxlID0gMDsKCXJhd19zcGluX3VubG9ja19pcnFyZXN0b3JlKCZwYXJlbnRfY3R4LT5sb2NrLCBmbGFncyk7CgoJY2hpbGRfY3R4ID0gY2hpbGQtPnBlcmZfZXZlbnRfY3R4cFtjdHhuXTsKCglpZiAoY2hpbGRfY3R4ICYmIGluaGVyaXRlZF9hbGwpIHsKCQkvKgoJCSAqIE1hcmsgdGhlIGNoaWxkIGNvbnRleHQgYXMgYSBjbG9uZSBvZiB0aGUgcGFyZW50CgkJICogY29udGV4dCwgb3Igb2Ygd2hhdGV2ZXIgdGhlIHBhcmVudCBpcyBhIGNsb25lIG9mLgoJCSAqIE5vdGUgdGhhdCBpZiB0aGUgcGFyZW50IGlzIGEgY2xvbmUsIGl0IGNvdWxkIGdldAoJCSAqIHVuY2xvbmVkIGF0IGFueSBwb2ludCwgYnV0IHRoYXQgZG9lc24ndCBtYXR0ZXIKCQkgKiBiZWNhdXNlIHRoZSBsaXN0IG9mIGV2ZW50cyBhbmQgdGhlIGdlbmVyYXRpb24KCQkgKiBjb3VudCBjYW4ndCBoYXZlIGNoYW5nZWQgc2luY2Ugd2UgdG9vayB0aGUgbXV0ZXguCgkJICovCgkJY2xvbmVkX2N0eCA9IHJjdV9kZXJlZmVyZW5jZShwYXJlbnRfY3R4LT5wYXJlbnRfY3R4KTsKCQlpZiAoY2xvbmVkX2N0eCkgewoJCQljaGlsZF9jdHgtPnBhcmVudF9jdHggPSBjbG9uZWRfY3R4OwoJCQljaGlsZF9jdHgtPnBhcmVudF9nZW4gPSBwYXJlbnRfY3R4LT5wYXJlbnRfZ2VuOwoJCX0gZWxzZSB7CgkJCWNoaWxkX2N0eC0+cGFyZW50X2N0eCA9IHBhcmVudF9jdHg7CgkJCWNoaWxkX2N0eC0+cGFyZW50X2dlbiA9IHBhcmVudF9jdHgtPmdlbmVyYXRpb247CgkJfQoJCWdldF9jdHgoY2hpbGRfY3R4LT5wYXJlbnRfY3R4KTsKCX0KCgltdXRleF91bmxvY2soJnBhcmVudF9jdHgtPm11dGV4KTsKCglwZXJmX3VucGluX2NvbnRleHQocGFyZW50X2N0eCk7CgoJcmV0dXJuIHJldDsKfQoKLyoKICogSW5pdGlhbGl6ZSB0aGUgcGVyZl9ldmVudCBjb250ZXh0IGluIHRhc2tfc3RydWN0CiAqLwppbnQgcGVyZl9ldmVudF9pbml0X3Rhc2soc3RydWN0IHRhc2tfc3RydWN0ICpjaGlsZCkKewoJaW50IGN0eG4sIHJldDsKCglmb3JfZWFjaF90YXNrX2NvbnRleHRfbnIoY3R4bikgewoJCXJldCA9IHBlcmZfZXZlbnRfaW5pdF9jb250ZXh0KGNoaWxkLCBjdHhuKTsKCQlpZiAocmV0KQoJCQlyZXR1cm4gcmV0OwoJfQoKCXJldHVybiAwOwp9CgpzdGF0aWMgdm9pZCBfX2luaXQgcGVyZl9ldmVudF9pbml0X2FsbF9jcHVzKHZvaWQpCnsKCXN0cnVjdCBzd2V2ZW50X2h0YWJsZSAqc3doYXNoOwoJaW50IGNwdTsKCglmb3JfZWFjaF9wb3NzaWJsZV9jcHUoY3B1KSB7CgkJc3doYXNoID0gJnBlcl9jcHUoc3dldmVudF9odGFibGUsIGNwdSk7CgkJbXV0ZXhfaW5pdCgmc3doYXNoLT5obGlzdF9tdXRleCk7CgkJSU5JVF9MSVNUX0hFQUQoJnBlcl9jcHUocm90YXRpb25fbGlzdCwgY3B1KSk7Cgl9Cn0KCnN0YXRpYyB2b2lkIF9fY3B1aW5pdCBwZXJmX2V2ZW50X2luaXRfY3B1KGludCBjcHUpCnsKCXN0cnVjdCBzd2V2ZW50X2h0YWJsZSAqc3doYXNoID0gJnBlcl9jcHUoc3dldmVudF9odGFibGUsIGNwdSk7CgoJbXV0ZXhfbG9jaygmc3doYXNoLT5obGlzdF9tdXRleCk7CglpZiAoc3doYXNoLT5obGlzdF9yZWZjb3VudCA+IDApIHsKCQlzdHJ1Y3Qgc3dldmVudF9obGlzdCAqaGxpc3Q7CgoJCWhsaXN0ID0ga3phbGxvY19ub2RlKHNpemVvZigqaGxpc3QpLCBHRlBfS0VSTkVMLCBjcHVfdG9fbm9kZShjcHUpKTsKCQlXQVJOX09OKCFobGlzdCk7CgkJcmN1X2Fzc2lnbl9wb2ludGVyKHN3aGFzaC0+c3dldmVudF9obGlzdCwgaGxpc3QpOwoJfQoJbXV0ZXhfdW5sb2NrKCZzd2hhc2gtPmhsaXN0X211dGV4KTsKfQoKI2lmIGRlZmluZWQgQ09ORklHX0hPVFBMVUdfQ1BVIHx8IGRlZmluZWQgQ09ORklHX0tFWEVDCnN0YXRpYyB2b2lkIHBlcmZfcG11X3JvdGF0ZV9zdG9wKHN0cnVjdCBwbXUgKnBtdSkKewoJc3RydWN0IHBlcmZfY3B1X2NvbnRleHQgKmNwdWN0eCA9IHRoaXNfY3B1X3B0cihwbXUtPnBtdV9jcHVfY29udGV4dCk7CgoJV0FSTl9PTighaXJxc19kaXNhYmxlZCgpKTsKCglsaXN0X2RlbF9pbml0KCZjcHVjdHgtPnJvdGF0aW9uX2xpc3QpOwp9CgpzdGF0aWMgdm9pZCBfX3BlcmZfZXZlbnRfZXhpdF9jb250ZXh0KHZvaWQgKl9faW5mbykKewoJc3RydWN0IHBlcmZfZXZlbnRfY29udGV4dCAqY3R4ID0gX19pbmZvOwoJc3RydWN0IHBlcmZfZXZlbnQgKmV2ZW50LCAqdG1wOwoKCXBlcmZfcG11X3JvdGF0ZV9zdG9wKGN0eC0+cG11KTsKCglsaXN0X2Zvcl9lYWNoX2VudHJ5X3NhZmUoZXZlbnQsIHRtcCwgJmN0eC0+cGlubmVkX2dyb3VwcywgZ3JvdXBfZW50cnkpCgkJX19wZXJmX2V2ZW50X3JlbW92ZV9mcm9tX2NvbnRleHQoZXZlbnQpOwoJbGlzdF9mb3JfZWFjaF9lbnRyeV9zYWZlKGV2ZW50LCB0bXAsICZjdHgtPmZsZXhpYmxlX2dyb3VwcywgZ3JvdXBfZW50cnkpCgkJX19wZXJmX2V2ZW50X3JlbW92ZV9mcm9tX2NvbnRleHQoZXZlbnQpOwp9CgpzdGF0aWMgdm9pZCBwZXJmX2V2ZW50X2V4aXRfY3B1X2NvbnRleHQoaW50IGNwdSkKewoJc3RydWN0IHBlcmZfZXZlbnRfY29udGV4dCAqY3R4OwoJc3RydWN0IHBtdSAqcG11OwoJaW50IGlkeDsKCglpZHggPSBzcmN1X3JlYWRfbG9jaygmcG11c19zcmN1KTsKCWxpc3RfZm9yX2VhY2hfZW50cnlfcmN1KHBtdSwgJnBtdXMsIGVudHJ5KSB7CgkJY3R4ID0gJnBlcl9jcHVfcHRyKHBtdS0+cG11X2NwdV9jb250ZXh0LCBjcHUpLT5jdHg7CgoJCW11dGV4X2xvY2soJmN0eC0+bXV0ZXgpOwoJCXNtcF9jYWxsX2Z1bmN0aW9uX3NpbmdsZShjcHUsIF9fcGVyZl9ldmVudF9leGl0X2NvbnRleHQsIGN0eCwgMSk7CgkJbXV0ZXhfdW5sb2NrKCZjdHgtPm11dGV4KTsKCX0KCXNyY3VfcmVhZF91bmxvY2soJnBtdXNfc3JjdSwgaWR4KTsKfQoKc3RhdGljIHZvaWQgcGVyZl9ldmVudF9leGl0X2NwdShpbnQgY3B1KQp7CglzdHJ1Y3Qgc3dldmVudF9odGFibGUgKnN3aGFzaCA9ICZwZXJfY3B1KHN3ZXZlbnRfaHRhYmxlLCBjcHUpOwoKCW11dGV4X2xvY2soJnN3aGFzaC0+aGxpc3RfbXV0ZXgpOwoJc3dldmVudF9obGlzdF9yZWxlYXNlKHN3aGFzaCk7CgltdXRleF91bmxvY2soJnN3aGFzaC0+aGxpc3RfbXV0ZXgpOwoKCXBlcmZfZXZlbnRfZXhpdF9jcHVfY29udGV4dChjcHUpOwp9CiNlbHNlCnN0YXRpYyBpbmxpbmUgdm9pZCBwZXJmX2V2ZW50X2V4aXRfY3B1KGludCBjcHUpIHsgfQojZW5kaWYKCnN0YXRpYyBpbnQKcGVyZl9yZWJvb3Qoc3RydWN0IG5vdGlmaWVyX2Jsb2NrICpub3RpZmllciwgdW5zaWduZWQgbG9uZyB2YWwsIHZvaWQgKnYpCnsKCWludCBjcHU7CgoJZm9yX2VhY2hfb25saW5lX2NwdShjcHUpCgkJcGVyZl9ldmVudF9leGl0X2NwdShjcHUpOwoKCXJldHVybiBOT1RJRllfT0s7Cn0KCi8qCiAqIFJ1biB0aGUgcGVyZiByZWJvb3Qgbm90aWZpZXIgYXQgdGhlIHZlcnkgbGFzdCBwb3NzaWJsZSBtb21lbnQgc28gdGhhdAogKiB0aGUgZ2VuZXJpYyB3YXRjaGRvZyBjb2RlIHJ1bnMgYXMgbG9uZyBhcyBwb3NzaWJsZS4KICovCnN0YXRpYyBzdHJ1Y3Qgbm90aWZpZXJfYmxvY2sgcGVyZl9yZWJvb3Rfbm90aWZpZXIgPSB7Cgkubm90aWZpZXJfY2FsbCA9IHBlcmZfcmVib290LAoJLnByaW9yaXR5ID0gSU5UX01JTiwKfTsKCnN0YXRpYyBpbnQgX19jcHVpbml0CnBlcmZfY3B1X25vdGlmeShzdHJ1Y3Qgbm90aWZpZXJfYmxvY2sgKnNlbGYsIHVuc2lnbmVkIGxvbmcgYWN0aW9uLCB2b2lkICpoY3B1KQp7Cgl1bnNpZ25lZCBpbnQgY3B1ID0gKGxvbmcpaGNwdTsKCglzd2l0Y2ggKGFjdGlvbiAmIH5DUFVfVEFTS1NfRlJPWkVOKSB7CgoJY2FzZSBDUFVfVVBfUFJFUEFSRToKCWNhc2UgQ1BVX0RPV05fRkFJTEVEOgoJCXBlcmZfZXZlbnRfaW5pdF9jcHUoY3B1KTsKCQlicmVhazsKCgljYXNlIENQVV9VUF9DQU5DRUxFRDoKCWNhc2UgQ1BVX0RPV05fUFJFUEFSRToKCQlwZXJmX2V2ZW50X2V4aXRfY3B1KGNwdSk7CgkJYnJlYWs7CgoJZGVmYXVsdDoKCQlicmVhazsKCX0KCglyZXR1cm4gTk9USUZZX09LOwp9Cgp2b2lkIF9faW5pdCBwZXJmX2V2ZW50X2luaXQodm9pZCkKewoJaW50IHJldDsKCglpZHJfaW5pdCgmcG11X2lkcik7CgoJcGVyZl9ldmVudF9pbml0X2FsbF9jcHVzKCk7Cglpbml0X3NyY3Vfc3RydWN0KCZwbXVzX3NyY3UpOwoJcGVyZl9wbXVfcmVnaXN0ZXIoJnBlcmZfc3dldmVudCwgInNvZnR3YXJlIiwgUEVSRl9UWVBFX1NPRlRXQVJFKTsKCXBlcmZfcG11X3JlZ2lzdGVyKCZwZXJmX2NwdV9jbG9jaywgTlVMTCwgLTEpOwoJcGVyZl9wbXVfcmVnaXN0ZXIoJnBlcmZfdGFza19jbG9jaywgTlVMTCwgLTEpOwoJcGVyZl90cF9yZWdpc3RlcigpOwoJcGVyZl9jcHVfbm90aWZpZXIocGVyZl9jcHVfbm90aWZ5KTsKCXJlZ2lzdGVyX3JlYm9vdF9ub3RpZmllcigmcGVyZl9yZWJvb3Rfbm90aWZpZXIpOwoKCXJldCA9IGluaXRfaHdfYnJlYWtwb2ludCgpOwoJV0FSTihyZXQsICJod19icmVha3BvaW50IGluaXRpYWxpemF0aW9uIGZhaWxlZCB3aXRoOiAlZCIsIHJldCk7Cn0KCnN0YXRpYyBpbnQgX19pbml0IHBlcmZfZXZlbnRfc3lzZnNfaW5pdCh2b2lkKQp7CglzdHJ1Y3QgcG11ICpwbXU7CglpbnQgcmV0OwoKCW11dGV4X2xvY2soJnBtdXNfbG9jayk7CgoJcmV0ID0gYnVzX3JlZ2lzdGVyKCZwbXVfYnVzKTsKCWlmIChyZXQpCgkJZ290byB1bmxvY2s7CgoJbGlzdF9mb3JfZWFjaF9lbnRyeShwbXUsICZwbXVzLCBlbnRyeSkgewoJCWlmICghcG11LT5uYW1lIHx8IHBtdS0+dHlwZSA8IDApCgkJCWNvbnRpbnVlOwoKCQlyZXQgPSBwbXVfZGV2X2FsbG9jKHBtdSk7CgkJV0FSTihyZXQsICJGYWlsZWQgdG8gcmVnaXN0ZXIgcG11OiAlcywgcmVhc29uICVkXG4iLCBwbXUtPm5hbWUsIHJldCk7Cgl9CglwbXVfYnVzX3J1bm5pbmcgPSAxOwoJcmV0ID0gMDsKCnVubG9jazoKCW11dGV4X3VubG9jaygmcG11c19sb2NrKTsKCglyZXR1cm4gcmV0Owp9CmRldmljZV9pbml0Y2FsbChwZXJmX2V2ZW50X3N5c2ZzX2luaXQpOwo=