LyoKICogSUJNIEFTTSBTZXJ2aWNlIFByb2Nlc3NvciBEZXZpY2UgRHJpdmVyCiAqCiAqIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5CiAqIGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5CiAqIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlciB2ZXJzaW9uIDIgb2YgdGhlIExpY2Vuc2UsIG9yCiAqIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlCiAqIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIGFsb25nIHdpdGggdGhpcyBwcm9ncmFtOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDU5IFRlbXBsZSBQbGFjZSAtIFN1aXRlIDMzMCwgQm9zdG9uLCBNQSAwMjExMS0xMzA3LCBVU0EuCiAqCiAqIENvcHlyaWdodCAoQykgSUJNIENvcnBvcmF0aW9uLCAyMDA0CiAqCiAqIEF1dGhvcjogTWF4IEFzYvZjayA8YW1heEB1cy5pYm0uY29tPgogKgogKi8KCi8qCiAqIFBhcnRzIG9mIHRoaXMgY29kZSBhcmUgYmFzZWQgb24gYW4gYXJ0aWNsZSBieSBKb25hdGhhbiBDb3JiZXQKICogdGhhdCBhcHBlYXJlZCBpbiBMaW51eCBXZWVrbHkgTmV3cy4KICovCgoKLyoKICogVGhlIElCTUFTTSBmaWxlIHZpcnR1YWwgZmlsZXN5c3RlbS4gSXQgY3JlYXRlcyB0aGUgZm9sbG93aW5nIGhpZXJhcmNoeQogKiBkeW1hbWljYWxseSB3aGVuIG1vdW50ZWQgZnJvbSB1c2VyIHNwYWNlOgogKgogKiAgICAvaWJtYXNtCiAqICAgIHwtLSAwCiAqICAgIHwgICB8LS0gY29tbWFuZAogKiAgICB8ICAgfC0tIGV2ZW50CiAqICAgIHwgICB8LS0gcmV2ZXJzZV9oZWFydGJlYXQKICogICAgfCAgIGAtLSByZW1vdGVfdmlkZW8KICogICAgfCAgICAgICB8LS0gZGVwdGgKICogICAgfCAgICAgICB8LS0gaGVpZ2h0CiAqICAgIHwgICAgICAgYC0tIHdpZHRoCiAqICAgIC4KICogICAgLgogKiAgICAuCiAqICAgIGAtLSBuCiAqICAgICAgICB8LS0gY29tbWFuZAogKiAgICAgICAgfC0tIGV2ZW50CiAqICAgICAgICB8LS0gcmV2ZXJzZV9oZWFydGJlYXQKICogICAgICAgIGAtLSByZW1vdGVfdmlkZW8KICogICAgICAgICAgICB8LS0gZGVwdGgKICogICAgICAgICAgICB8LS0gaGVpZ2h0CiAqICAgICAgICAgICAgYC0tIHdpZHRoCiAqCiAqIEZvciBlYWNoIHNlcnZpY2UgcHJvY2Vzc29yIHRoZSBmb2xsb3dpbmcgZmlsZXMgYXJlIGNyZWF0ZWQ6CiAqCiAqIGNvbW1hbmQ6IGV4ZWN1dGUgZG90IGNvbW1hbmRzCiAqCXdyaXRlOiBleGVjdXRlIGEgZG90IGNvbW1hbmQgb24gdGhlIHNlcnZpY2UgcHJvY2Vzc29yCiAqCXJlYWQ6IHJldHVybiB0aGUgcmVzdWx0IG9mIGEgcHJldmlvdXNseSBleGVjdXRlZCBkb3QgY29tbWFuZAogKgogKiBldmVudHM6IGxpc3RlbiBmb3Igc2VydmljZSBwcm9jZXNzb3IgZXZlbnRzCiAqCXJlYWQ6IHNsZWVwIChpbnRlcnJ1cHRpYmxlKSB1bnRpbCBhbiBldmVudCBvY2N1cnMKICogICAgICB3cml0ZTogd2FrZXVwIHNsZWVwaW5nIGV2ZW50IGxpc3RlbmVyCiAqCiAqIHJldmVyc2VfaGVhcnRiZWF0OiBzZW5kIGEgaGVhcnRiZWF0IHRvIHRoZSBzZXJ2aWNlIHByb2Nlc3NvcgogKglyZWFkOiBzbGVlcCAoaW50ZXJydXB0aWJsZSkgdW50aWwgdGhlIHJldmVyc2UgaGVhcnRiZWF0IGZhaWxzCiAqICAgICAgd3JpdGU6IHdha2V1cCBzbGVlcGluZyBoZWFydGJlYXQgbGlzdGVuZXIKICoKICogcmVtb3RlX3ZpZGVvL3dpZHRoCiAqIHJlbW90ZV92aWRlby9oZWlnaHQKICogcmVtb3RlX3ZpZGVvL3dpZHRoOiBjb250cm9sIHJlbW90ZSBkaXNwbGF5IHNldHRpbmdzCiAqCXdyaXRlOiBzZXQgdmFsdWUKICoJcmVhZDogcmVhZCB2YWx1ZQogKi8KCiNpbmNsdWRlIDxsaW51eC9mcy5oPgojaW5jbHVkZSA8bGludXgvcGFnZW1hcC5oPgojaW5jbHVkZSA8YXNtL3VhY2Nlc3MuaD4KI2luY2x1ZGUgPGFzbS9pby5oPgojaW5jbHVkZSAiaWJtYXNtLmgiCiNpbmNsdWRlICJyZW1vdGUuaCIKI2luY2x1ZGUgImRvdF9jb21tYW5kLmgiCgojZGVmaW5lIElCTUFTTUZTX01BR0lDIDB4NjY3MjZmNjcKCnN0YXRpYyBMSVNUX0hFQUQoc2VydmljZV9wcm9jZXNzb3JzKTsKCnN0YXRpYyBzdHJ1Y3QgaW5vZGUgKmlibWFzbWZzX21ha2VfaW5vZGUoc3RydWN0IHN1cGVyX2Jsb2NrICpzYiwgaW50IG1vZGUpOwpzdGF0aWMgdm9pZCBpYm1hc21mc19jcmVhdGVfZmlsZXMgKHN0cnVjdCBzdXBlcl9ibG9jayAqc2IsIHN0cnVjdCBkZW50cnkgKnJvb3QpOwpzdGF0aWMgaW50IGlibWFzbWZzX2ZpbGxfc3VwZXIgKHN0cnVjdCBzdXBlcl9ibG9jayAqc2IsIHZvaWQgKmRhdGEsIGludCBzaWxlbnQpOwoKCnN0YXRpYyBpbnQgaWJtYXNtZnNfZ2V0X3N1cGVyKHN0cnVjdCBmaWxlX3N5c3RlbV90eXBlICpmc3QsCgkJCWludCBmbGFncywgY29uc3QgY2hhciAqbmFtZSwgdm9pZCAqZGF0YSwKCQkJc3RydWN0IHZmc21vdW50ICptbnQpCnsKCXJldHVybiBnZXRfc2Jfc2luZ2xlKGZzdCwgZmxhZ3MsIGRhdGEsIGlibWFzbWZzX2ZpbGxfc3VwZXIsIG1udCk7Cn0KCnN0YXRpYyBzdHJ1Y3Qgc3VwZXJfb3BlcmF0aW9ucyBpYm1hc21mc19zX29wcyA9IHsKCS5zdGF0ZnMJCT0gc2ltcGxlX3N0YXRmcywKCS5kcm9wX2lub2RlCT0gZ2VuZXJpY19kZWxldGVfaW5vZGUsCn07CgpzdGF0aWMgY29uc3Qgc3RydWN0IGZpbGVfb3BlcmF0aW9ucyAqaWJtYXNtZnNfZGlyX29wcyA9ICZzaW1wbGVfZGlyX29wZXJhdGlvbnM7CgpzdGF0aWMgc3RydWN0IGZpbGVfc3lzdGVtX3R5cGUgaWJtYXNtZnNfdHlwZSA9IHsKCS5vd25lciAgICAgICAgICA9IFRISVNfTU9EVUxFLAoJLm5hbWUgICAgICAgICAgID0gImlibWFzbWZzIiwKCS5nZXRfc2IgICAgICAgICA9IGlibWFzbWZzX2dldF9zdXBlciwKCS5raWxsX3NiICAgICAgICA9IGtpbGxfbGl0dGVyX3N1cGVyLAp9OwoKc3RhdGljIGludCBpYm1hc21mc19maWxsX3N1cGVyIChzdHJ1Y3Qgc3VwZXJfYmxvY2sgKnNiLCB2b2lkICpkYXRhLCBpbnQgc2lsZW50KQp7CglzdHJ1Y3QgaW5vZGUgKnJvb3Q7CglzdHJ1Y3QgZGVudHJ5ICpyb290X2RlbnRyeTsKCglzYi0+c19ibG9ja3NpemUgPSBQQUdFX0NBQ0hFX1NJWkU7CglzYi0+c19ibG9ja3NpemVfYml0cyA9IFBBR0VfQ0FDSEVfU0hJRlQ7CglzYi0+c19tYWdpYyA9IElCTUFTTUZTX01BR0lDOwoJc2ItPnNfb3AgPSAmaWJtYXNtZnNfc19vcHM7CglzYi0+c190aW1lX2dyYW4gPSAxOwoKCXJvb3QgPSBpYm1hc21mc19tYWtlX2lub2RlIChzYiwgU19JRkRJUiB8IDA1MDApOwoJaWYgKCFyb290KQoJCXJldHVybiAtRU5PTUVNOwoKCXJvb3QtPmlfb3AgPSAmc2ltcGxlX2Rpcl9pbm9kZV9vcGVyYXRpb25zOwoJcm9vdC0+aV9mb3AgPSBpYm1hc21mc19kaXJfb3BzOwoKCXJvb3RfZGVudHJ5ID0gZF9hbGxvY19yb290KHJvb3QpOwoJaWYgKCFyb290X2RlbnRyeSkgewoJCWlwdXQocm9vdCk7CgkJcmV0dXJuIC1FTk9NRU07Cgl9CglzYi0+c19yb290ID0gcm9vdF9kZW50cnk7CgoJaWJtYXNtZnNfY3JlYXRlX2ZpbGVzKHNiLCByb290X2RlbnRyeSk7CglyZXR1cm4gMDsKfQoKc3RhdGljIHN0cnVjdCBpbm9kZSAqaWJtYXNtZnNfbWFrZV9pbm9kZShzdHJ1Y3Qgc3VwZXJfYmxvY2sgKnNiLCBpbnQgbW9kZSkKewoJc3RydWN0IGlub2RlICpyZXQgPSBuZXdfaW5vZGUoc2IpOwoKCWlmIChyZXQpIHsKCQlyZXQtPmlfbW9kZSA9IG1vZGU7CgkJcmV0LT5pX3VpZCA9IHJldC0+aV9naWQgPSAwOwoJCXJldC0+aV9ibG9ja3MgPSAwOwoJCXJldC0+aV9hdGltZSA9IHJldC0+aV9tdGltZSA9IHJldC0+aV9jdGltZSA9IENVUlJFTlRfVElNRTsKCX0KCXJldHVybiByZXQ7Cn0KCnN0YXRpYyBzdHJ1Y3QgZGVudHJ5ICppYm1hc21mc19jcmVhdGVfZmlsZSAoc3RydWN0IHN1cGVyX2Jsb2NrICpzYiwKCQkJc3RydWN0IGRlbnRyeSAqcGFyZW50LAoJCQljb25zdCBjaGFyICpuYW1lLAoJCQljb25zdCBzdHJ1Y3QgZmlsZV9vcGVyYXRpb25zICpmb3BzLAoJCQl2b2lkICpkYXRhLAoJCQlpbnQgbW9kZSkKewoJc3RydWN0IGRlbnRyeSAqZGVudHJ5OwoJc3RydWN0IGlub2RlICppbm9kZTsKCglkZW50cnkgPSBkX2FsbG9jX25hbWUocGFyZW50LCBuYW1lKTsKCWlmICghZGVudHJ5KQoJCXJldHVybiBOVUxMOwoKCWlub2RlID0gaWJtYXNtZnNfbWFrZV9pbm9kZShzYiwgU19JRlJFRyB8IG1vZGUpOwoJaWYgKCFpbm9kZSkgewoJCWRwdXQoZGVudHJ5KTsKCQlyZXR1cm4gTlVMTDsKCX0KCglpbm9kZS0+aV9mb3AgPSBmb3BzOwoJaW5vZGUtPmlfcHJpdmF0ZSA9IGRhdGE7CgoJZF9hZGQoZGVudHJ5LCBpbm9kZSk7CglyZXR1cm4gZGVudHJ5Owp9CgpzdGF0aWMgc3RydWN0IGRlbnRyeSAqaWJtYXNtZnNfY3JlYXRlX2RpciAoc3RydWN0IHN1cGVyX2Jsb2NrICpzYiwKCQkJCXN0cnVjdCBkZW50cnkgKnBhcmVudCwKCQkJCWNvbnN0IGNoYXIgKm5hbWUpCnsKCXN0cnVjdCBkZW50cnkgKmRlbnRyeTsKCXN0cnVjdCBpbm9kZSAqaW5vZGU7CgoJZGVudHJ5ID0gZF9hbGxvY19uYW1lKHBhcmVudCwgbmFtZSk7CglpZiAoIWRlbnRyeSkKCQlyZXR1cm4gTlVMTDsKCglpbm9kZSA9IGlibWFzbWZzX21ha2VfaW5vZGUoc2IsIFNfSUZESVIgfCAwNTAwKTsKCWlmICghaW5vZGUpIHsKCQlkcHV0KGRlbnRyeSk7CgkJcmV0dXJuIE5VTEw7Cgl9CgoJaW5vZGUtPmlfb3AgPSAmc2ltcGxlX2Rpcl9pbm9kZV9vcGVyYXRpb25zOwoJaW5vZGUtPmlfZm9wID0gaWJtYXNtZnNfZGlyX29wczsKCglkX2FkZChkZW50cnksIGlub2RlKTsKCXJldHVybiBkZW50cnk7Cn0KCmludCBpYm1hc21mc19yZWdpc3Rlcih2b2lkKQp7CglyZXR1cm4gcmVnaXN0ZXJfZmlsZXN5c3RlbSgmaWJtYXNtZnNfdHlwZSk7Cn0KCnZvaWQgaWJtYXNtZnNfdW5yZWdpc3Rlcih2b2lkKQp7Cgl1bnJlZ2lzdGVyX2ZpbGVzeXN0ZW0oJmlibWFzbWZzX3R5cGUpOwp9Cgp2b2lkIGlibWFzbWZzX2FkZF9zcChzdHJ1Y3Qgc2VydmljZV9wcm9jZXNzb3IgKnNwKQp7CglsaXN0X2FkZCgmc3AtPm5vZGUsICZzZXJ2aWNlX3Byb2Nlc3NvcnMpOwp9CgovKiBzdHJ1Y3QgdG8gc2F2ZSBzdGF0ZSBiZXR3ZWVuIGNvbW1hbmQgZmlsZSBvcGVyYXRpb25zICovCnN0cnVjdCBpYm1hc21mc19jb21tYW5kX2RhdGEgewoJc3RydWN0IHNlcnZpY2VfcHJvY2Vzc29yCSpzcDsKCXN0cnVjdCBjb21tYW5kCQkJKmNvbW1hbmQ7Cn07CgovKiBzdHJ1Y3QgdG8gc2F2ZSBzdGF0ZSBiZXR3ZWVuIGV2ZW50IGZpbGUgb3BlcmF0aW9ucyAqLwpzdHJ1Y3QgaWJtYXNtZnNfZXZlbnRfZGF0YSB7CglzdHJ1Y3Qgc2VydmljZV9wcm9jZXNzb3IJKnNwOwoJc3RydWN0IGV2ZW50X3JlYWRlcgkJcmVhZGVyOwoJaW50CQkJCWFjdGl2ZTsKfTsKCi8qIHN0cnVjdCB0byBzYXZlIHN0YXRlIGJldHdlZW4gcmV2ZXJzZSBoZWFydGJlYXQgZmlsZSBvcGVyYXRpb25zICovCnN0cnVjdCBpYm1hc21mc19oZWFydGJlYXRfZGF0YSB7CglzdHJ1Y3Qgc2VydmljZV9wcm9jZXNzb3IJKnNwOwoJc3RydWN0IHJldmVyc2VfaGVhcnRiZWF0CWhlYXJ0YmVhdDsKCWludAkJCQlhY3RpdmU7Cn07CgpzdGF0aWMgaW50IGNvbW1hbmRfZmlsZV9vcGVuKHN0cnVjdCBpbm9kZSAqaW5vZGUsIHN0cnVjdCBmaWxlICpmaWxlKQp7CglzdHJ1Y3QgaWJtYXNtZnNfY29tbWFuZF9kYXRhICpjb21tYW5kX2RhdGE7CgoJaWYgKCFpbm9kZS0+aV9wcml2YXRlKQoJCXJldHVybiAtRU5PREVWOwoKCWNvbW1hbmRfZGF0YSA9IGttYWxsb2Moc2l6ZW9mKHN0cnVjdCBpYm1hc21mc19jb21tYW5kX2RhdGEpLCBHRlBfS0VSTkVMKTsKCWlmICghY29tbWFuZF9kYXRhKQoJCXJldHVybiAtRU5PTUVNOwoKCWNvbW1hbmRfZGF0YS0+Y29tbWFuZCA9IE5VTEw7Cgljb21tYW5kX2RhdGEtPnNwID0gaW5vZGUtPmlfcHJpdmF0ZTsKCWZpbGUtPnByaXZhdGVfZGF0YSA9IGNvbW1hbmRfZGF0YTsKCXJldHVybiAwOwp9CgpzdGF0aWMgaW50IGNvbW1hbmRfZmlsZV9jbG9zZShzdHJ1Y3QgaW5vZGUgKmlub2RlLCBzdHJ1Y3QgZmlsZSAqZmlsZSkKewoJc3RydWN0IGlibWFzbWZzX2NvbW1hbmRfZGF0YSAqY29tbWFuZF9kYXRhID0gZmlsZS0+cHJpdmF0ZV9kYXRhOwoKCWlmIChjb21tYW5kX2RhdGEtPmNvbW1hbmQpCgkJY29tbWFuZF9wdXQoY29tbWFuZF9kYXRhLT5jb21tYW5kKTsKCglrZnJlZShjb21tYW5kX2RhdGEpOwoJcmV0dXJuIDA7Cn0KCnN0YXRpYyBzc2l6ZV90IGNvbW1hbmRfZmlsZV9yZWFkKHN0cnVjdCBmaWxlICpmaWxlLCBjaGFyIF9fdXNlciAqYnVmLCBzaXplX3QgY291bnQsIGxvZmZfdCAqb2Zmc2V0KQp7CglzdHJ1Y3QgaWJtYXNtZnNfY29tbWFuZF9kYXRhICpjb21tYW5kX2RhdGEgPSBmaWxlLT5wcml2YXRlX2RhdGE7CglzdHJ1Y3QgY29tbWFuZCAqY21kOwoJaW50IGxlbjsKCXVuc2lnbmVkIGxvbmcgZmxhZ3M7CgoJaWYgKCpvZmZzZXQgPCAwKQoJCXJldHVybiAtRUlOVkFMOwoJaWYgKGNvdW50ID09IDAgfHwgY291bnQgPiBJQk1BU01fQ01EX01BWF9CVUZGRVJfU0laRSkKCQlyZXR1cm4gMDsKCWlmICgqb2Zmc2V0ICE9IDApCgkJcmV0dXJuIDA7CgoJc3Bpbl9sb2NrX2lycXNhdmUoJmNvbW1hbmRfZGF0YS0+c3AtPmxvY2ssIGZsYWdzKTsKCWNtZCA9IGNvbW1hbmRfZGF0YS0+Y29tbWFuZDsKCWlmIChjbWQgPT0gTlVMTCkgewoJCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJmNvbW1hbmRfZGF0YS0+c3AtPmxvY2ssIGZsYWdzKTsKCQlyZXR1cm4gMDsKCX0KCWNvbW1hbmRfZGF0YS0+Y29tbWFuZCA9IE5VTEw7CglzcGluX3VubG9ja19pcnFyZXN0b3JlKCZjb21tYW5kX2RhdGEtPnNwLT5sb2NrLCBmbGFncyk7CgoJaWYgKGNtZC0+c3RhdHVzICE9IElCTUFTTV9DTURfQ09NUExFVEUpIHsKCQljb21tYW5kX3B1dChjbWQpOwoJCXJldHVybiAtRUlPOwoJfQoJbGVuID0gbWluKGNvdW50LCBjbWQtPmJ1ZmZlcl9zaXplKTsKCWlmIChjb3B5X3RvX3VzZXIoYnVmLCBjbWQtPmJ1ZmZlciwgbGVuKSkgewoJCWNvbW1hbmRfcHV0KGNtZCk7CgkJcmV0dXJuIC1FRkFVTFQ7Cgl9Cgljb21tYW5kX3B1dChjbWQpOwoKCXJldHVybiBsZW47Cn0KCnN0YXRpYyBzc2l6ZV90IGNvbW1hbmRfZmlsZV93cml0ZShzdHJ1Y3QgZmlsZSAqZmlsZSwgY29uc3QgY2hhciBfX3VzZXIgKnVidWZmLCBzaXplX3QgY291bnQsIGxvZmZfdCAqb2Zmc2V0KQp7CglzdHJ1Y3QgaWJtYXNtZnNfY29tbWFuZF9kYXRhICpjb21tYW5kX2RhdGEgPSBmaWxlLT5wcml2YXRlX2RhdGE7CglzdHJ1Y3QgY29tbWFuZCAqY21kOwoJdW5zaWduZWQgbG9uZyBmbGFnczsKCglpZiAoKm9mZnNldCA8IDApCgkJcmV0dXJuIC1FSU5WQUw7CglpZiAoY291bnQgPT0gMCB8fCBjb3VudCA+IElCTUFTTV9DTURfTUFYX0JVRkZFUl9TSVpFKQoJCXJldHVybiAwOwoJaWYgKCpvZmZzZXQgIT0gMCkKCQlyZXR1cm4gMDsKCgkvKiBjb21tYW5kcyBhcmUgZXhlY3V0ZWQgc2VxdWVudGlhbGx5LCBvbmx5IG9uZSBjb21tYW5kIGF0IGEgdGltZSAqLwoJaWYgKGNvbW1hbmRfZGF0YS0+Y29tbWFuZCkKCQlyZXR1cm4gLUVBR0FJTjsKCgljbWQgPSBpYm1hc21fbmV3X2NvbW1hbmQoY29tbWFuZF9kYXRhLT5zcCwgY291bnQpOwoJaWYgKCFjbWQpCgkJcmV0dXJuIC1FTk9NRU07CgoJaWYgKGNvcHlfZnJvbV91c2VyKGNtZC0+YnVmZmVyLCB1YnVmZiwgY291bnQpKSB7CgkJY29tbWFuZF9wdXQoY21kKTsKCQlyZXR1cm4gLUVGQVVMVDsKCX0KCglzcGluX2xvY2tfaXJxc2F2ZSgmY29tbWFuZF9kYXRhLT5zcC0+bG9jaywgZmxhZ3MpOwoJaWYgKGNvbW1hbmRfZGF0YS0+Y29tbWFuZCkgewoJCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJmNvbW1hbmRfZGF0YS0+c3AtPmxvY2ssIGZsYWdzKTsKCQljb21tYW5kX3B1dChjbWQpOwoJCXJldHVybiAtRUFHQUlOOwoJfQoJY29tbWFuZF9kYXRhLT5jb21tYW5kID0gY21kOwoJc3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmY29tbWFuZF9kYXRhLT5zcC0+bG9jaywgZmxhZ3MpOwoKCWlibWFzbV9leGVjX2NvbW1hbmQoY29tbWFuZF9kYXRhLT5zcCwgY21kKTsKCWlibWFzbV93YWl0X2Zvcl9yZXNwb25zZShjbWQsIGdldF9kb3RfY29tbWFuZF90aW1lb3V0KGNtZC0+YnVmZmVyKSk7CgoJcmV0dXJuIGNvdW50Owp9CgpzdGF0aWMgaW50IGV2ZW50X2ZpbGVfb3BlbihzdHJ1Y3QgaW5vZGUgKmlub2RlLCBzdHJ1Y3QgZmlsZSAqZmlsZSkKewoJc3RydWN0IGlibWFzbWZzX2V2ZW50X2RhdGEgKmV2ZW50X2RhdGE7CglzdHJ1Y3Qgc2VydmljZV9wcm9jZXNzb3IgKnNwOwoKCWlmICghaW5vZGUtPmlfcHJpdmF0ZSkKCQlyZXR1cm4gLUVOT0RFVjsKCglzcCA9IGlub2RlLT5pX3ByaXZhdGU7CgoJZXZlbnRfZGF0YSA9IGttYWxsb2Moc2l6ZW9mKHN0cnVjdCBpYm1hc21mc19ldmVudF9kYXRhKSwgR0ZQX0tFUk5FTCk7CglpZiAoIWV2ZW50X2RhdGEpCgkJcmV0dXJuIC1FTk9NRU07CgoJaWJtYXNtX2V2ZW50X3JlYWRlcl9yZWdpc3RlcihzcCwgJmV2ZW50X2RhdGEtPnJlYWRlcik7CgoJZXZlbnRfZGF0YS0+c3AgPSBzcDsKCWV2ZW50X2RhdGEtPmFjdGl2ZSA9IDA7CglmaWxlLT5wcml2YXRlX2RhdGEgPSBldmVudF9kYXRhOwoJcmV0dXJuIDA7Cn0KCnN0YXRpYyBpbnQgZXZlbnRfZmlsZV9jbG9zZShzdHJ1Y3QgaW5vZGUgKmlub2RlLCBzdHJ1Y3QgZmlsZSAqZmlsZSkKewoJc3RydWN0IGlibWFzbWZzX2V2ZW50X2RhdGEgKmV2ZW50X2RhdGEgPSBmaWxlLT5wcml2YXRlX2RhdGE7CgoJaWJtYXNtX2V2ZW50X3JlYWRlcl91bnJlZ2lzdGVyKGV2ZW50X2RhdGEtPnNwLCAmZXZlbnRfZGF0YS0+cmVhZGVyKTsKCWtmcmVlKGV2ZW50X2RhdGEpOwoJcmV0dXJuIDA7Cn0KCnN0YXRpYyBzc2l6ZV90IGV2ZW50X2ZpbGVfcmVhZChzdHJ1Y3QgZmlsZSAqZmlsZSwgY2hhciBfX3VzZXIgKmJ1Ziwgc2l6ZV90IGNvdW50LCBsb2ZmX3QgKm9mZnNldCkKewoJc3RydWN0IGlibWFzbWZzX2V2ZW50X2RhdGEgKmV2ZW50X2RhdGEgPSBmaWxlLT5wcml2YXRlX2RhdGE7CglzdHJ1Y3QgZXZlbnRfcmVhZGVyICpyZWFkZXIgPSAmZXZlbnRfZGF0YS0+cmVhZGVyOwoJc3RydWN0IHNlcnZpY2VfcHJvY2Vzc29yICpzcCA9IGV2ZW50X2RhdGEtPnNwOwoJaW50IHJldDsKCXVuc2lnbmVkIGxvbmcgZmxhZ3M7CgoJaWYgKCpvZmZzZXQgPCAwKQoJCXJldHVybiAtRUlOVkFMOwoJaWYgKGNvdW50ID09IDAgfHwgY291bnQgPiBJQk1BU01fRVZFTlRfTUFYX1NJWkUpCgkJcmV0dXJuIDA7CglpZiAoKm9mZnNldCAhPSAwKQoJCXJldHVybiAwOwoKCXNwaW5fbG9ja19pcnFzYXZlKCZzcC0+bG9jaywgZmxhZ3MpOwoJaWYgKGV2ZW50X2RhdGEtPmFjdGl2ZSkgewoJCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJnNwLT5sb2NrLCBmbGFncyk7CgkJcmV0dXJuIC1FQlVTWTsKCX0KCWV2ZW50X2RhdGEtPmFjdGl2ZSA9IDE7CglzcGluX3VubG9ja19pcnFyZXN0b3JlKCZzcC0+bG9jaywgZmxhZ3MpOwoKCXJldCA9IGlibWFzbV9nZXRfbmV4dF9ldmVudChzcCwgcmVhZGVyKTsKCWlmIChyZXQgPD0gMCkKCQlnb3RvIG91dDsKCglpZiAoY291bnQgPCByZWFkZXItPmRhdGFfc2l6ZSkgewoJCXJldCA9IC1FSU5WQUw7CgkJZ290byBvdXQ7Cgl9CgogICAgICAgIGlmIChjb3B5X3RvX3VzZXIoYnVmLCByZWFkZXItPmRhdGEsIHJlYWRlci0+ZGF0YV9zaXplKSkgewoJCXJldCA9IC1FRkFVTFQ7CgkJZ290byBvdXQ7Cgl9CglyZXQgPSByZWFkZXItPmRhdGFfc2l6ZTsKCm91dDoKCWV2ZW50X2RhdGEtPmFjdGl2ZSA9IDA7CglyZXR1cm4gcmV0Owp9CgpzdGF0aWMgc3NpemVfdCBldmVudF9maWxlX3dyaXRlKHN0cnVjdCBmaWxlICpmaWxlLCBjb25zdCBjaGFyIF9fdXNlciAqYnVmLCBzaXplX3QgY291bnQsIGxvZmZfdCAqb2Zmc2V0KQp7CglzdHJ1Y3QgaWJtYXNtZnNfZXZlbnRfZGF0YSAqZXZlbnRfZGF0YSA9IGZpbGUtPnByaXZhdGVfZGF0YTsKCglpZiAoKm9mZnNldCA8IDApCgkJcmV0dXJuIC1FSU5WQUw7CglpZiAoY291bnQgIT0gMSkKCQlyZXR1cm4gMDsKCWlmICgqb2Zmc2V0ICE9IDApCgkJcmV0dXJuIDA7CgoJaWJtYXNtX2NhbmNlbF9uZXh0X2V2ZW50KCZldmVudF9kYXRhLT5yZWFkZXIpOwoJcmV0dXJuIDA7Cn0KCnN0YXRpYyBpbnQgcl9oZWFydGJlYXRfZmlsZV9vcGVuKHN0cnVjdCBpbm9kZSAqaW5vZGUsIHN0cnVjdCBmaWxlICpmaWxlKQp7CglzdHJ1Y3QgaWJtYXNtZnNfaGVhcnRiZWF0X2RhdGEgKnJoYmVhdDsKCglpZiAoIWlub2RlLT5pX3ByaXZhdGUpCgkJcmV0dXJuIC1FTk9ERVY7CgoJcmhiZWF0ID0ga21hbGxvYyhzaXplb2Yoc3RydWN0IGlibWFzbWZzX2hlYXJ0YmVhdF9kYXRhKSwgR0ZQX0tFUk5FTCk7CglpZiAoIXJoYmVhdCkKCQlyZXR1cm4gLUVOT01FTTsKCglyaGJlYXQtPnNwID0gaW5vZGUtPmlfcHJpdmF0ZTsKCXJoYmVhdC0+YWN0aXZlID0gMDsKCWlibWFzbV9pbml0X3JldmVyc2VfaGVhcnRiZWF0KHJoYmVhdC0+c3AsICZyaGJlYXQtPmhlYXJ0YmVhdCk7CglmaWxlLT5wcml2YXRlX2RhdGEgPSByaGJlYXQ7CglyZXR1cm4gMDsKfQoKc3RhdGljIGludCByX2hlYXJ0YmVhdF9maWxlX2Nsb3NlKHN0cnVjdCBpbm9kZSAqaW5vZGUsIHN0cnVjdCBmaWxlICpmaWxlKQp7CglzdHJ1Y3QgaWJtYXNtZnNfaGVhcnRiZWF0X2RhdGEgKnJoYmVhdCA9IGZpbGUtPnByaXZhdGVfZGF0YTsKCglrZnJlZShyaGJlYXQpOwoJcmV0dXJuIDA7Cn0KCnN0YXRpYyBzc2l6ZV90IHJfaGVhcnRiZWF0X2ZpbGVfcmVhZChzdHJ1Y3QgZmlsZSAqZmlsZSwgY2hhciBfX3VzZXIgKmJ1Ziwgc2l6ZV90IGNvdW50LCBsb2ZmX3QgKm9mZnNldCkKewoJc3RydWN0IGlibWFzbWZzX2hlYXJ0YmVhdF9kYXRhICpyaGJlYXQgPSBmaWxlLT5wcml2YXRlX2RhdGE7Cgl1bnNpZ25lZCBsb25nIGZsYWdzOwoJaW50IHJlc3VsdDsKCglpZiAoKm9mZnNldCA8IDApCgkJcmV0dXJuIC1FSU5WQUw7CglpZiAoY291bnQgPT0gMCB8fCBjb3VudCA+IDEwMjQpCgkJcmV0dXJuIDA7CglpZiAoKm9mZnNldCAhPSAwKQoJCXJldHVybiAwOwoKCS8qIGFsbG93IG9ubHkgb25lIHJldmVyc2UgaGVhcnRiZWF0IHBlciBwcm9jZXNzICovCglzcGluX2xvY2tfaXJxc2F2ZSgmcmhiZWF0LT5zcC0+bG9jaywgZmxhZ3MpOwoJaWYgKHJoYmVhdC0+YWN0aXZlKSB7CgkJc3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmcmhiZWF0LT5zcC0+bG9jaywgZmxhZ3MpOwoJCXJldHVybiAtRUJVU1k7Cgl9CglyaGJlYXQtPmFjdGl2ZSA9IDE7CglzcGluX3VubG9ja19pcnFyZXN0b3JlKCZyaGJlYXQtPnNwLT5sb2NrLCBmbGFncyk7CgoJcmVzdWx0ID0gaWJtYXNtX3N0YXJ0X3JldmVyc2VfaGVhcnRiZWF0KHJoYmVhdC0+c3AsICZyaGJlYXQtPmhlYXJ0YmVhdCk7CglyaGJlYXQtPmFjdGl2ZSA9IDA7CgoJcmV0dXJuIHJlc3VsdDsKfQoKc3RhdGljIHNzaXplX3Qgcl9oZWFydGJlYXRfZmlsZV93cml0ZShzdHJ1Y3QgZmlsZSAqZmlsZSwgY29uc3QgY2hhciBfX3VzZXIgKmJ1Ziwgc2l6ZV90IGNvdW50LCBsb2ZmX3QgKm9mZnNldCkKewoJc3RydWN0IGlibWFzbWZzX2hlYXJ0YmVhdF9kYXRhICpyaGJlYXQgPSBmaWxlLT5wcml2YXRlX2RhdGE7CgoJaWYgKCpvZmZzZXQgPCAwKQoJCXJldHVybiAtRUlOVkFMOwoJaWYgKGNvdW50ICE9IDEpCgkJcmV0dXJuIDA7CglpZiAoKm9mZnNldCAhPSAwKQoJCXJldHVybiAwOwoKCWlmIChyaGJlYXQtPmFjdGl2ZSkKCQlpYm1hc21fc3RvcF9yZXZlcnNlX2hlYXJ0YmVhdCgmcmhiZWF0LT5oZWFydGJlYXQpOwoKCXJldHVybiAxOwp9CgpzdGF0aWMgaW50IHJlbW90ZV9zZXR0aW5nc19maWxlX29wZW4oc3RydWN0IGlub2RlICppbm9kZSwgc3RydWN0IGZpbGUgKmZpbGUpCnsKCWZpbGUtPnByaXZhdGVfZGF0YSA9IGlub2RlLT5pX3ByaXZhdGU7CglyZXR1cm4gMDsKfQoKc3RhdGljIGludCByZW1vdGVfc2V0dGluZ3NfZmlsZV9jbG9zZShzdHJ1Y3QgaW5vZGUgKmlub2RlLCBzdHJ1Y3QgZmlsZSAqZmlsZSkKewoJcmV0dXJuIDA7Cn0KCnN0YXRpYyBzc2l6ZV90IHJlbW90ZV9zZXR0aW5nc19maWxlX3JlYWQoc3RydWN0IGZpbGUgKmZpbGUsIGNoYXIgX191c2VyICpidWYsIHNpemVfdCBjb3VudCwgbG9mZl90ICpvZmZzZXQpCnsKCXZvaWQgX19pb21lbSAqYWRkcmVzcyA9ICh2b2lkIF9faW9tZW0gKilmaWxlLT5wcml2YXRlX2RhdGE7Cgl1bnNpZ25lZCBjaGFyICpwYWdlOwoJaW50IHJldHZhbDsKCWludCBsZW4gPSAwOwoJdW5zaWduZWQgaW50IHZhbHVlOwoKCWlmICgqb2Zmc2V0IDwgMCkKCQlyZXR1cm4gLUVJTlZBTDsKCWlmIChjb3VudCA9PSAwIHx8IGNvdW50ID4gMTAyNCkKCQlyZXR1cm4gMDsKCWlmICgqb2Zmc2V0ICE9IDApCgkJcmV0dXJuIDA7CgoJcGFnZSA9ICh1bnNpZ25lZCBjaGFyICopX19nZXRfZnJlZV9wYWdlKEdGUF9LRVJORUwpOwoJaWYgKCFwYWdlKQoJCXJldHVybiAtRU5PTUVNOwoKCXZhbHVlID0gcmVhZGwoYWRkcmVzcyk7CglsZW4gPSBzcHJpbnRmKHBhZ2UsICIlZFxuIiwgdmFsdWUpOwoKCWlmIChjb3B5X3RvX3VzZXIoYnVmLCBwYWdlLCBsZW4pKSB7CgkJcmV0dmFsID0gLUVGQVVMVDsKCQlnb3RvIGV4aXQ7Cgl9Cgkqb2Zmc2V0ICs9IGxlbjsKCXJldHZhbCA9IGxlbjsKCmV4aXQ6CglmcmVlX3BhZ2UoKHVuc2lnbmVkIGxvbmcpcGFnZSk7CglyZXR1cm4gcmV0dmFsOwp9CgpzdGF0aWMgc3NpemVfdCByZW1vdGVfc2V0dGluZ3NfZmlsZV93cml0ZShzdHJ1Y3QgZmlsZSAqZmlsZSwgY29uc3QgY2hhciBfX3VzZXIgKnVidWZmLCBzaXplX3QgY291bnQsIGxvZmZfdCAqb2Zmc2V0KQp7Cgl2b2lkIF9faW9tZW0gKmFkZHJlc3MgPSAodm9pZCBfX2lvbWVtICopZmlsZS0+cHJpdmF0ZV9kYXRhOwoJY2hhciAqYnVmZjsKCXVuc2lnbmVkIGludCB2YWx1ZTsKCglpZiAoKm9mZnNldCA8IDApCgkJcmV0dXJuIC1FSU5WQUw7CglpZiAoY291bnQgPT0gMCB8fCBjb3VudCA+IDEwMjQpCgkJcmV0dXJuIDA7CglpZiAoKm9mZnNldCAhPSAwKQoJCXJldHVybiAwOwoKCWJ1ZmYgPSBremFsbG9jIChjb3VudCArIDEsIEdGUF9LRVJORUwpOwoJaWYgKCFidWZmKQoJCXJldHVybiAtRU5PTUVNOwoKCglpZiAoY29weV9mcm9tX3VzZXIoYnVmZiwgdWJ1ZmYsIGNvdW50KSkgewoJCWtmcmVlKGJ1ZmYpOwoJCXJldHVybiAtRUZBVUxUOwoJfQoKCXZhbHVlID0gc2ltcGxlX3N0cnRvdWwoYnVmZiwgTlVMTCwgMTApOwoJd3JpdGVsKHZhbHVlLCBhZGRyZXNzKTsKCWtmcmVlKGJ1ZmYpOwoKCXJldHVybiBjb3VudDsKfQoKc3RhdGljIGNvbnN0IHN0cnVjdCBmaWxlX29wZXJhdGlvbnMgY29tbWFuZF9mb3BzID0gewoJLm9wZW4gPQkJY29tbWFuZF9maWxlX29wZW4sCgkucmVsZWFzZSA9CWNvbW1hbmRfZmlsZV9jbG9zZSwKCS5yZWFkID0JCWNvbW1hbmRfZmlsZV9yZWFkLAoJLndyaXRlID0JY29tbWFuZF9maWxlX3dyaXRlLAp9OwoKc3RhdGljIGNvbnN0IHN0cnVjdCBmaWxlX29wZXJhdGlvbnMgZXZlbnRfZm9wcyA9IHsKCS5vcGVuID0JCWV2ZW50X2ZpbGVfb3BlbiwKCS5yZWxlYXNlID0JZXZlbnRfZmlsZV9jbG9zZSwKCS5yZWFkID0JCWV2ZW50X2ZpbGVfcmVhZCwKCS53cml0ZSA9CWV2ZW50X2ZpbGVfd3JpdGUsCn07CgpzdGF0aWMgY29uc3Qgc3RydWN0IGZpbGVfb3BlcmF0aW9ucyByX2hlYXJ0YmVhdF9mb3BzID0gewoJLm9wZW4gPQkJcl9oZWFydGJlYXRfZmlsZV9vcGVuLAoJLnJlbGVhc2UgPQlyX2hlYXJ0YmVhdF9maWxlX2Nsb3NlLAoJLnJlYWQgPQkJcl9oZWFydGJlYXRfZmlsZV9yZWFkLAoJLndyaXRlID0Jcl9oZWFydGJlYXRfZmlsZV93cml0ZSwKfTsKCnN0YXRpYyBjb25zdCBzdHJ1Y3QgZmlsZV9vcGVyYXRpb25zIHJlbW90ZV9zZXR0aW5nc19mb3BzID0gewoJLm9wZW4gPQkJcmVtb3RlX3NldHRpbmdzX2ZpbGVfb3BlbiwKCS5yZWxlYXNlID0JcmVtb3RlX3NldHRpbmdzX2ZpbGVfY2xvc2UsCgkucmVhZCA9CQlyZW1vdGVfc2V0dGluZ3NfZmlsZV9yZWFkLAoJLndyaXRlID0JcmVtb3RlX3NldHRpbmdzX2ZpbGVfd3JpdGUsCn07CgoKc3RhdGljIHZvaWQgaWJtYXNtZnNfY3JlYXRlX2ZpbGVzIChzdHJ1Y3Qgc3VwZXJfYmxvY2sgKnNiLCBzdHJ1Y3QgZGVudHJ5ICpyb290KQp7CglzdHJ1Y3QgbGlzdF9oZWFkICplbnRyeTsKCXN0cnVjdCBzZXJ2aWNlX3Byb2Nlc3NvciAqc3A7CgoJbGlzdF9mb3JfZWFjaChlbnRyeSwgJnNlcnZpY2VfcHJvY2Vzc29ycykgewoJCXN0cnVjdCBkZW50cnkgKmRpcjsKCQlzdHJ1Y3QgZGVudHJ5ICpyZW1vdGVfZGlyOwoJCXNwID0gbGlzdF9lbnRyeShlbnRyeSwgc3RydWN0IHNlcnZpY2VfcHJvY2Vzc29yLCBub2RlKTsKCQlkaXIgPSBpYm1hc21mc19jcmVhdGVfZGlyKHNiLCByb290LCBzcC0+ZGlybmFtZSk7CgkJaWYgKCFkaXIpCgkJCWNvbnRpbnVlOwoKCQlpYm1hc21mc19jcmVhdGVfZmlsZShzYiwgZGlyLCAiY29tbWFuZCIsICZjb21tYW5kX2ZvcHMsIHNwLCBTX0lSVVNSfFNfSVdVU1IpOwoJCWlibWFzbWZzX2NyZWF0ZV9maWxlKHNiLCBkaXIsICJldmVudCIsICZldmVudF9mb3BzLCBzcCwgU19JUlVTUnxTX0lXVVNSKTsKCQlpYm1hc21mc19jcmVhdGVfZmlsZShzYiwgZGlyLCAicmV2ZXJzZV9oZWFydGJlYXQiLCAmcl9oZWFydGJlYXRfZm9wcywgc3AsIFNfSVJVU1J8U19JV1VTUik7CgoJCXJlbW90ZV9kaXIgPSBpYm1hc21mc19jcmVhdGVfZGlyKHNiLCBkaXIsICJyZW1vdGVfdmlkZW8iKTsKCQlpZiAoIXJlbW90ZV9kaXIpCgkJCWNvbnRpbnVlOwoKCQlpYm1hc21mc19jcmVhdGVfZmlsZShzYiwgcmVtb3RlX2RpciwgIndpZHRoIiwgJnJlbW90ZV9zZXR0aW5nc19mb3BzLCAodm9pZCAqKWRpc3BsYXlfd2lkdGgoc3ApLCBTX0lSVVNSfFNfSVdVU1IpOwoJCWlibWFzbWZzX2NyZWF0ZV9maWxlKHNiLCByZW1vdGVfZGlyLCAiaGVpZ2h0IiwgJnJlbW90ZV9zZXR0aW5nc19mb3BzLCAodm9pZCAqKWRpc3BsYXlfaGVpZ2h0KHNwKSwgU19JUlVTUnxTX0lXVVNSKTsKCQlpYm1hc21mc19jcmVhdGVfZmlsZShzYiwgcmVtb3RlX2RpciwgImRlcHRoIiwgJnJlbW90ZV9zZXR0aW5nc19mb3BzLCAodm9pZCAqKWRpc3BsYXlfZGVwdGgoc3ApLCBTX0lSVVNSfFNfSVdVU1IpOwoJfQp9Cg==