LyoKICogSUJNIEFTTSBTZXJ2aWNlIFByb2Nlc3NvciBEZXZpY2UgRHJpdmVyCiAqCiAqIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5CiAqIGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5CiAqIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlciB2ZXJzaW9uIDIgb2YgdGhlIExpY2Vuc2UsIG9yCiAqIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlCiAqIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIGFsb25nIHdpdGggdGhpcyBwcm9ncmFtOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDU5IFRlbXBsZSBQbGFjZSAtIFN1aXRlIDMzMCwgQm9zdG9uLCBNQSAwMjExMS0xMzA3LCBVU0EuCiAqCiAqIENvcHlyaWdodCAoQykgSUJNIENvcnBvcmF0aW9uLCAyMDA0CiAqCiAqIEF1dGhvcjogTWF4IEFzYvZjayA8YW1heEB1cy5pYm0uY29tPiAKICoKICovCgovKgogKiBQYXJ0cyBvZiB0aGlzIGNvZGUgYXJlIGJhc2VkIG9uIGFuIGFydGljbGUgYnkgSm9uYXRoYW4gQ29yYmV0IAogKiB0aGF0IGFwcGVhcmVkIGluIExpbnV4IFdlZWtseSBOZXdzLgogKi8KCgovKgogKiBUaGUgSUJNQVNNIGZpbGUgdmlydHVhbCBmaWxlc3lzdGVtLiBJdCBjcmVhdGVzIHRoZSBmb2xsb3dpbmcgaGllcmFyY2h5CiAqIGR5bWFtaWNhbGx5IHdoZW4gbW91bnRlZCBmcm9tIHVzZXIgc3BhY2U6CiAqCiAqICAgIC9pYm1hc20KICogICAgfC0tIDAKICogICAgfCAgIHwtLSBjb21tYW5kCiAqICAgIHwgICB8LS0gZXZlbnQKICogICAgfCAgIHwtLSByZXZlcnNlX2hlYXJ0YmVhdAogKiAgICB8ICAgYC0tIHJlbW90ZV92aWRlbwogKiAgICB8ICAgICAgIHwtLSBkZXB0aAogKiAgICB8ICAgICAgIHwtLSBoZWlnaHQKICogICAgfCAgICAgICBgLS0gd2lkdGgKICogICAgLgogKiAgICAuCiAqICAgIC4KICogICAgYC0tIG4KICogICAgICAgIHwtLSBjb21tYW5kCiAqICAgICAgICB8LS0gZXZlbnQKICogICAgICAgIHwtLSByZXZlcnNlX2hlYXJ0YmVhdAogKiAgICAgICAgYC0tIHJlbW90ZV92aWRlbwogKiAgICAgICAgICAgIHwtLSBkZXB0aAogKiAgICAgICAgICAgIHwtLSBoZWlnaHQKICogICAgICAgICAgICBgLS0gd2lkdGgKICoKICogRm9yIGVhY2ggc2VydmljZSBwcm9jZXNzb3IgdGhlIGZvbGxvd2luZyBmaWxlcyBhcmUgY3JlYXRlZDoKICoKICogY29tbWFuZDogZXhlY3V0ZSBkb3QgY29tbWFuZHMKICogCXdyaXRlOiBleGVjdXRlIGEgZG90IGNvbW1hbmQgb24gdGhlIHNlcnZpY2UgcHJvY2Vzc29yCiAqIAlyZWFkOiByZXR1cm4gdGhlIHJlc3VsdCBvZiBhIHByZXZpb3VzbHkgZXhlY3V0ZWQgZG90IGNvbW1hbmQKICoKICogZXZlbnRzOiBsaXN0ZW4gZm9yIHNlcnZpY2UgcHJvY2Vzc29yIGV2ZW50cwogKiAJcmVhZDogc2xlZXAgKGludGVycnVwdGlibGUpIHVudGlsIGFuIGV2ZW50IG9jY3VycwogKiAgICAgIHdyaXRlOiB3YWtldXAgc2xlZXBpbmcgZXZlbnQgbGlzdGVuZXIKICoKICogcmV2ZXJzZV9oZWFydGJlYXQ6IHNlbmQgYSBoZWFydGJlYXQgdG8gdGhlIHNlcnZpY2UgcHJvY2Vzc29yCiAqIAlyZWFkOiBzbGVlcCAoaW50ZXJydXB0aWJsZSkgdW50aWwgdGhlIHJldmVyc2UgaGVhcnRiZWF0IGZhaWxzCiAqICAgICAgd3JpdGU6IHdha2V1cCBzbGVlcGluZyBoZWFydGJlYXQgbGlzdGVuZXIKICoKICogcmVtb3RlX3ZpZGVvL3dpZHRoCiAqIHJlbW90ZV92aWRlby9oZWlnaHQKICogcmVtb3RlX3ZpZGVvL3dpZHRoOiBjb250cm9sIHJlbW90ZSBkaXNwbGF5IHNldHRpbmdzCiAqIAl3cml0ZTogc2V0IHZhbHVlCiAqIAlyZWFkOiByZWFkIHZhbHVlCiAqLwoKI2luY2x1ZGUgPGxpbnV4L2ZzLmg+CiNpbmNsdWRlIDxsaW51eC9wYWdlbWFwLmg+CiNpbmNsdWRlIDxhc20vdWFjY2Vzcy5oPgojaW5jbHVkZSA8YXNtL2lvLmg+CiNpbmNsdWRlICJpYm1hc20uaCIKI2luY2x1ZGUgInJlbW90ZS5oIgojaW5jbHVkZSAiZG90X2NvbW1hbmQuaCIKCiNkZWZpbmUgSUJNQVNNRlNfTUFHSUMgMHg2NjcyNmY2NwoKc3RhdGljIExJU1RfSEVBRChzZXJ2aWNlX3Byb2Nlc3NvcnMpOwoKc3RhdGljIHN0cnVjdCBpbm9kZSAqaWJtYXNtZnNfbWFrZV9pbm9kZShzdHJ1Y3Qgc3VwZXJfYmxvY2sgKnNiLCBpbnQgbW9kZSk7CnN0YXRpYyB2b2lkIGlibWFzbWZzX2NyZWF0ZV9maWxlcyAoc3RydWN0IHN1cGVyX2Jsb2NrICpzYiwgc3RydWN0IGRlbnRyeSAqcm9vdCk7CnN0YXRpYyBpbnQgaWJtYXNtZnNfZmlsbF9zdXBlciAoc3RydWN0IHN1cGVyX2Jsb2NrICpzYiwgdm9pZCAqZGF0YSwgaW50IHNpbGVudCk7CgoKc3RhdGljIGludCBpYm1hc21mc19nZXRfc3VwZXIoc3RydWN0IGZpbGVfc3lzdGVtX3R5cGUgKmZzdCwKCQkJaW50IGZsYWdzLCBjb25zdCBjaGFyICpuYW1lLCB2b2lkICpkYXRhLAoJCQlzdHJ1Y3QgdmZzbW91bnQgKm1udCkKewoJcmV0dXJuIGdldF9zYl9zaW5nbGUoZnN0LCBmbGFncywgZGF0YSwgaWJtYXNtZnNfZmlsbF9zdXBlciwgbW50KTsKfQoKc3RhdGljIHN0cnVjdCBzdXBlcl9vcGVyYXRpb25zIGlibWFzbWZzX3Nfb3BzID0gewoJLnN0YXRmcwkJPSBzaW1wbGVfc3RhdGZzLAoJLmRyb3BfaW5vZGUJPSBnZW5lcmljX2RlbGV0ZV9pbm9kZSwKfTsKCnN0YXRpYyBjb25zdCBzdHJ1Y3QgZmlsZV9vcGVyYXRpb25zICppYm1hc21mc19kaXJfb3BzID0gJnNpbXBsZV9kaXJfb3BlcmF0aW9uczsKCnN0YXRpYyBzdHJ1Y3QgZmlsZV9zeXN0ZW1fdHlwZSBpYm1hc21mc190eXBlID0gewoJLm93bmVyICAgICAgICAgID0gVEhJU19NT0RVTEUsCgkubmFtZSAgICAgICAgICAgPSAiaWJtYXNtZnMiLAoJLmdldF9zYiAgICAgICAgID0gaWJtYXNtZnNfZ2V0X3N1cGVyLAoJLmtpbGxfc2IgICAgICAgID0ga2lsbF9saXR0ZXJfc3VwZXIsCn07CgpzdGF0aWMgaW50IGlibWFzbWZzX2ZpbGxfc3VwZXIgKHN0cnVjdCBzdXBlcl9ibG9jayAqc2IsIHZvaWQgKmRhdGEsIGludCBzaWxlbnQpCnsKCXN0cnVjdCBpbm9kZSAqcm9vdDsKCXN0cnVjdCBkZW50cnkgKnJvb3RfZGVudHJ5OwoKCXNiLT5zX2Jsb2Nrc2l6ZSA9IFBBR0VfQ0FDSEVfU0laRTsKCXNiLT5zX2Jsb2Nrc2l6ZV9iaXRzID0gUEFHRV9DQUNIRV9TSElGVDsKCXNiLT5zX21hZ2ljID0gSUJNQVNNRlNfTUFHSUM7CglzYi0+c19vcCA9ICZpYm1hc21mc19zX29wczsKCXNiLT5zX3RpbWVfZ3JhbiA9IDE7CgoJcm9vdCA9IGlibWFzbWZzX21ha2VfaW5vZGUgKHNiLCBTX0lGRElSIHwgMDUwMCk7CglpZiAoIXJvb3QpCgkJcmV0dXJuIC1FTk9NRU07CgoJcm9vdC0+aV9vcCA9ICZzaW1wbGVfZGlyX2lub2RlX29wZXJhdGlvbnM7Cglyb290LT5pX2ZvcCA9IGlibWFzbWZzX2Rpcl9vcHM7CgoJcm9vdF9kZW50cnkgPSBkX2FsbG9jX3Jvb3Qocm9vdCk7CglpZiAoIXJvb3RfZGVudHJ5KSB7CgkJaXB1dChyb290KTsKCQlyZXR1cm4gLUVOT01FTTsKCX0KCXNiLT5zX3Jvb3QgPSByb290X2RlbnRyeTsKCglpYm1hc21mc19jcmVhdGVfZmlsZXMoc2IsIHJvb3RfZGVudHJ5KTsKCXJldHVybiAwOwp9CgpzdGF0aWMgc3RydWN0IGlub2RlICppYm1hc21mc19tYWtlX2lub2RlKHN0cnVjdCBzdXBlcl9ibG9jayAqc2IsIGludCBtb2RlKQp7CglzdHJ1Y3QgaW5vZGUgKnJldCA9IG5ld19pbm9kZShzYik7CgoJaWYgKHJldCkgewoJCXJldC0+aV9tb2RlID0gbW9kZTsKCQlyZXQtPmlfdWlkID0gcmV0LT5pX2dpZCA9IDA7CgkJcmV0LT5pX2Jsa3NpemUgPSBQQUdFX0NBQ0hFX1NJWkU7CgkJcmV0LT5pX2Jsb2NrcyA9IDA7CgkJcmV0LT5pX2F0aW1lID0gcmV0LT5pX210aW1lID0gcmV0LT5pX2N0aW1lID0gQ1VSUkVOVF9USU1FOwoJfQoJcmV0dXJuIHJldDsKfQoKc3RhdGljIHN0cnVjdCBkZW50cnkgKmlibWFzbWZzX2NyZWF0ZV9maWxlIChzdHJ1Y3Qgc3VwZXJfYmxvY2sgKnNiLAoJCQlzdHJ1Y3QgZGVudHJ5ICpwYXJlbnQsCgkJICAgICAgIAljb25zdCBjaGFyICpuYW1lLAoJCQlzdHJ1Y3QgZmlsZV9vcGVyYXRpb25zICpmb3BzLAoJCQl2b2lkICpkYXRhLAoJCQlpbnQgbW9kZSkKewoJc3RydWN0IGRlbnRyeSAqZGVudHJ5OwoJc3RydWN0IGlub2RlICppbm9kZTsKCglkZW50cnkgPSBkX2FsbG9jX25hbWUocGFyZW50LCBuYW1lKTsKCWlmICghZGVudHJ5KQoJCXJldHVybiBOVUxMOwoKCWlub2RlID0gaWJtYXNtZnNfbWFrZV9pbm9kZShzYiwgU19JRlJFRyB8IG1vZGUpOwoJaWYgKCFpbm9kZSkgewoJCWRwdXQoZGVudHJ5KTsKCQlyZXR1cm4gTlVMTDsKCX0KCglpbm9kZS0+aV9mb3AgPSBmb3BzOwoJaW5vZGUtPnUuZ2VuZXJpY19pcCA9IGRhdGE7CgoJZF9hZGQoZGVudHJ5LCBpbm9kZSk7CglyZXR1cm4gZGVudHJ5Owp9CgpzdGF0aWMgc3RydWN0IGRlbnRyeSAqaWJtYXNtZnNfY3JlYXRlX2RpciAoc3RydWN0IHN1cGVyX2Jsb2NrICpzYiwKCQkJCXN0cnVjdCBkZW50cnkgKnBhcmVudCwKCQkJCWNvbnN0IGNoYXIgKm5hbWUpCnsKCXN0cnVjdCBkZW50cnkgKmRlbnRyeTsKCXN0cnVjdCBpbm9kZSAqaW5vZGU7CgoJZGVudHJ5ID0gZF9hbGxvY19uYW1lKHBhcmVudCwgbmFtZSk7CglpZiAoIWRlbnRyeSkKCQlyZXR1cm4gTlVMTDsKCglpbm9kZSA9IGlibWFzbWZzX21ha2VfaW5vZGUoc2IsIFNfSUZESVIgfCAwNTAwKTsKCWlmICghaW5vZGUpIHsKCQlkcHV0KGRlbnRyeSk7CgkJcmV0dXJuIE5VTEw7Cgl9CgoJaW5vZGUtPmlfb3AgPSAmc2ltcGxlX2Rpcl9pbm9kZV9vcGVyYXRpb25zOwoJaW5vZGUtPmlfZm9wID0gaWJtYXNtZnNfZGlyX29wczsKCglkX2FkZChkZW50cnksIGlub2RlKTsKCXJldHVybiBkZW50cnk7Cn0KCmludCBpYm1hc21mc19yZWdpc3Rlcih2b2lkKQp7CglyZXR1cm4gcmVnaXN0ZXJfZmlsZXN5c3RlbSgmaWJtYXNtZnNfdHlwZSk7Cn0KCnZvaWQgaWJtYXNtZnNfdW5yZWdpc3Rlcih2b2lkKQp7Cgl1bnJlZ2lzdGVyX2ZpbGVzeXN0ZW0oJmlibWFzbWZzX3R5cGUpOwp9Cgp2b2lkIGlibWFzbWZzX2FkZF9zcChzdHJ1Y3Qgc2VydmljZV9wcm9jZXNzb3IgKnNwKQp7CglsaXN0X2FkZCgmc3AtPm5vZGUsICZzZXJ2aWNlX3Byb2Nlc3NvcnMpOwp9CgovKiBzdHJ1Y3QgdG8gc2F2ZSBzdGF0ZSBiZXR3ZWVuIGNvbW1hbmQgZmlsZSBvcGVyYXRpb25zICovCnN0cnVjdCBpYm1hc21mc19jb21tYW5kX2RhdGEgewoJc3RydWN0IHNlcnZpY2VfcHJvY2Vzc29yCSpzcDsKCXN0cnVjdCBjb21tYW5kCQkJKmNvbW1hbmQ7Cn07CgovKiBzdHJ1Y3QgdG8gc2F2ZSBzdGF0ZSBiZXR3ZWVuIGV2ZW50IGZpbGUgb3BlcmF0aW9ucyAqLwpzdHJ1Y3QgaWJtYXNtZnNfZXZlbnRfZGF0YSB7CglzdHJ1Y3Qgc2VydmljZV9wcm9jZXNzb3IJKnNwOwoJc3RydWN0IGV2ZW50X3JlYWRlcgkJcmVhZGVyOwoJaW50CQkJCWFjdGl2ZTsKfTsKCi8qIHN0cnVjdCB0byBzYXZlIHN0YXRlIGJldHdlZW4gcmV2ZXJzZSBoZWFydGJlYXQgZmlsZSBvcGVyYXRpb25zICovCnN0cnVjdCBpYm1hc21mc19oZWFydGJlYXRfZGF0YSB7CglzdHJ1Y3Qgc2VydmljZV9wcm9jZXNzb3IJKnNwOwoJc3RydWN0IHJldmVyc2VfaGVhcnRiZWF0CWhlYXJ0YmVhdDsKCWludAkJCQlhY3RpdmU7Cn07CgpzdGF0aWMgaW50IGNvbW1hbmRfZmlsZV9vcGVuKHN0cnVjdCBpbm9kZSAqaW5vZGUsIHN0cnVjdCBmaWxlICpmaWxlKQp7CglzdHJ1Y3QgaWJtYXNtZnNfY29tbWFuZF9kYXRhICpjb21tYW5kX2RhdGE7CgoJaWYgKCFpbm9kZS0+dS5nZW5lcmljX2lwKQoJCXJldHVybiAtRU5PREVWOwoKCWNvbW1hbmRfZGF0YSA9IGttYWxsb2Moc2l6ZW9mKHN0cnVjdCBpYm1hc21mc19jb21tYW5kX2RhdGEpLCBHRlBfS0VSTkVMKTsKCWlmICghY29tbWFuZF9kYXRhKQoJCXJldHVybiAtRU5PTUVNOwoKCWNvbW1hbmRfZGF0YS0+Y29tbWFuZCA9IE5VTEw7Cgljb21tYW5kX2RhdGEtPnNwID0gaW5vZGUtPnUuZ2VuZXJpY19pcDsKCWZpbGUtPnByaXZhdGVfZGF0YSA9IGNvbW1hbmRfZGF0YTsKCXJldHVybiAwOwp9CgpzdGF0aWMgaW50IGNvbW1hbmRfZmlsZV9jbG9zZShzdHJ1Y3QgaW5vZGUgKmlub2RlLCBzdHJ1Y3QgZmlsZSAqZmlsZSkKewoJc3RydWN0IGlibWFzbWZzX2NvbW1hbmRfZGF0YSAqY29tbWFuZF9kYXRhID0gZmlsZS0+cHJpdmF0ZV9kYXRhOwoKCWlmIChjb21tYW5kX2RhdGEtPmNvbW1hbmQpCgkJY29tbWFuZF9wdXQoY29tbWFuZF9kYXRhLT5jb21tYW5kKTsJCgoJa2ZyZWUoY29tbWFuZF9kYXRhKTsKCXJldHVybiAwOwp9CgpzdGF0aWMgc3NpemVfdCBjb21tYW5kX2ZpbGVfcmVhZChzdHJ1Y3QgZmlsZSAqZmlsZSwgY2hhciBfX3VzZXIgKmJ1Ziwgc2l6ZV90IGNvdW50LCBsb2ZmX3QgKm9mZnNldCkKewoJc3RydWN0IGlibWFzbWZzX2NvbW1hbmRfZGF0YSAqY29tbWFuZF9kYXRhID0gZmlsZS0+cHJpdmF0ZV9kYXRhOwoJc3RydWN0IGNvbW1hbmQgKmNtZDsKCWludCBsZW47Cgl1bnNpZ25lZCBsb25nIGZsYWdzOwoKCWlmICgqb2Zmc2V0IDwgMCkKCQlyZXR1cm4gLUVJTlZBTDsKCWlmIChjb3VudCA9PSAwIHx8IGNvdW50ID4gSUJNQVNNX0NNRF9NQVhfQlVGRkVSX1NJWkUpCgkJcmV0dXJuIDA7CglpZiAoKm9mZnNldCAhPSAwKQoJCXJldHVybiAwOwoKCXNwaW5fbG9ja19pcnFzYXZlKCZjb21tYW5kX2RhdGEtPnNwLT5sb2NrLCBmbGFncyk7CgljbWQgPSBjb21tYW5kX2RhdGEtPmNvbW1hbmQ7CglpZiAoY21kID09IE5VTEwpIHsKCQlzcGluX3VubG9ja19pcnFyZXN0b3JlKCZjb21tYW5kX2RhdGEtPnNwLT5sb2NrLCBmbGFncyk7CgkJcmV0dXJuIDA7Cgl9Cgljb21tYW5kX2RhdGEtPmNvbW1hbmQgPSBOVUxMOwoJc3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmY29tbWFuZF9kYXRhLT5zcC0+bG9jaywgZmxhZ3MpOwoKCWlmIChjbWQtPnN0YXR1cyAhPSBJQk1BU01fQ01EX0NPTVBMRVRFKSB7CgkJY29tbWFuZF9wdXQoY21kKTsKCQlyZXR1cm4gLUVJTzsKCX0KCWxlbiA9IG1pbihjb3VudCwgY21kLT5idWZmZXJfc2l6ZSk7CglpZiAoY29weV90b191c2VyKGJ1ZiwgY21kLT5idWZmZXIsIGxlbikpIHsKCQljb21tYW5kX3B1dChjbWQpOwoJCXJldHVybiAtRUZBVUxUOwoJfQoJY29tbWFuZF9wdXQoY21kKTsKCglyZXR1cm4gbGVuOwp9CgpzdGF0aWMgc3NpemVfdCBjb21tYW5kX2ZpbGVfd3JpdGUoc3RydWN0IGZpbGUgKmZpbGUsIGNvbnN0IGNoYXIgX191c2VyICp1YnVmZiwgc2l6ZV90IGNvdW50LCBsb2ZmX3QgKm9mZnNldCkKewoJc3RydWN0IGlibWFzbWZzX2NvbW1hbmRfZGF0YSAqY29tbWFuZF9kYXRhID0gZmlsZS0+cHJpdmF0ZV9kYXRhOwoJc3RydWN0IGNvbW1hbmQgKmNtZDsKCXVuc2lnbmVkIGxvbmcgZmxhZ3M7CgoJaWYgKCpvZmZzZXQgPCAwKQoJCXJldHVybiAtRUlOVkFMOwoJaWYgKGNvdW50ID09IDAgfHwgY291bnQgPiBJQk1BU01fQ01EX01BWF9CVUZGRVJfU0laRSkKCQlyZXR1cm4gMDsKCWlmICgqb2Zmc2V0ICE9IDApCgkJcmV0dXJuIDA7CgoJLyogY29tbWFuZHMgYXJlIGV4ZWN1dGVkIHNlcXVlbnRpYWxseSwgb25seSBvbmUgY29tbWFuZCBhdCBhIHRpbWUgKi8KCWlmIChjb21tYW5kX2RhdGEtPmNvbW1hbmQpCgkJcmV0dXJuIC1FQUdBSU47CgoJY21kID0gaWJtYXNtX25ld19jb21tYW5kKGNvbW1hbmRfZGF0YS0+c3AsIGNvdW50KTsKCWlmICghY21kKQoJCXJldHVybiAtRU5PTUVNOwoKCWlmIChjb3B5X2Zyb21fdXNlcihjbWQtPmJ1ZmZlciwgdWJ1ZmYsIGNvdW50KSkgewoJCWNvbW1hbmRfcHV0KGNtZCk7CgkJcmV0dXJuIC1FRkFVTFQ7Cgl9CgoJc3Bpbl9sb2NrX2lycXNhdmUoJmNvbW1hbmRfZGF0YS0+c3AtPmxvY2ssIGZsYWdzKTsKCWlmIChjb21tYW5kX2RhdGEtPmNvbW1hbmQpIHsKCQlzcGluX3VubG9ja19pcnFyZXN0b3JlKCZjb21tYW5kX2RhdGEtPnNwLT5sb2NrLCBmbGFncyk7CgkJY29tbWFuZF9wdXQoY21kKTsKCQlyZXR1cm4gLUVBR0FJTjsKCX0KCWNvbW1hbmRfZGF0YS0+Y29tbWFuZCA9IGNtZDsKCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJmNvbW1hbmRfZGF0YS0+c3AtPmxvY2ssIGZsYWdzKTsKCglpYm1hc21fZXhlY19jb21tYW5kKGNvbW1hbmRfZGF0YS0+c3AsIGNtZCk7CglpYm1hc21fd2FpdF9mb3JfcmVzcG9uc2UoY21kLCBnZXRfZG90X2NvbW1hbmRfdGltZW91dChjbWQtPmJ1ZmZlcikpOwoKCXJldHVybiBjb3VudDsKfQoKc3RhdGljIGludCBldmVudF9maWxlX29wZW4oc3RydWN0IGlub2RlICppbm9kZSwgc3RydWN0IGZpbGUgKmZpbGUpCnsKCXN0cnVjdCBpYm1hc21mc19ldmVudF9kYXRhICpldmVudF9kYXRhOwoJc3RydWN0IHNlcnZpY2VfcHJvY2Vzc29yICpzcDsgCgoJaWYgKCFpbm9kZS0+dS5nZW5lcmljX2lwKQoJCXJldHVybiAtRU5PREVWOwoKCXNwID0gaW5vZGUtPnUuZ2VuZXJpY19pcDsKCglldmVudF9kYXRhID0ga21hbGxvYyhzaXplb2Yoc3RydWN0IGlibWFzbWZzX2V2ZW50X2RhdGEpLCBHRlBfS0VSTkVMKTsKCWlmICghZXZlbnRfZGF0YSkKCQlyZXR1cm4gLUVOT01FTTsKCglpYm1hc21fZXZlbnRfcmVhZGVyX3JlZ2lzdGVyKHNwLCAmZXZlbnRfZGF0YS0+cmVhZGVyKTsKCglldmVudF9kYXRhLT5zcCA9IHNwOwoJZXZlbnRfZGF0YS0+YWN0aXZlID0gMDsKCWZpbGUtPnByaXZhdGVfZGF0YSA9IGV2ZW50X2RhdGE7CglyZXR1cm4gMDsKfQoKc3RhdGljIGludCBldmVudF9maWxlX2Nsb3NlKHN0cnVjdCBpbm9kZSAqaW5vZGUsIHN0cnVjdCBmaWxlICpmaWxlKQp7CglzdHJ1Y3QgaWJtYXNtZnNfZXZlbnRfZGF0YSAqZXZlbnRfZGF0YSA9IGZpbGUtPnByaXZhdGVfZGF0YTsKCglpYm1hc21fZXZlbnRfcmVhZGVyX3VucmVnaXN0ZXIoZXZlbnRfZGF0YS0+c3AsICZldmVudF9kYXRhLT5yZWFkZXIpOwoJa2ZyZWUoZXZlbnRfZGF0YSk7CglyZXR1cm4gMDsKfQoKc3RhdGljIHNzaXplX3QgZXZlbnRfZmlsZV9yZWFkKHN0cnVjdCBmaWxlICpmaWxlLCBjaGFyIF9fdXNlciAqYnVmLCBzaXplX3QgY291bnQsIGxvZmZfdCAqb2Zmc2V0KQp7CglzdHJ1Y3QgaWJtYXNtZnNfZXZlbnRfZGF0YSAqZXZlbnRfZGF0YSA9IGZpbGUtPnByaXZhdGVfZGF0YTsKCXN0cnVjdCBldmVudF9yZWFkZXIgKnJlYWRlciA9ICZldmVudF9kYXRhLT5yZWFkZXI7CglzdHJ1Y3Qgc2VydmljZV9wcm9jZXNzb3IgKnNwID0gZXZlbnRfZGF0YS0+c3A7CglpbnQgcmV0OwoJdW5zaWduZWQgbG9uZyBmbGFnczsKCglpZiAoKm9mZnNldCA8IDApCgkJcmV0dXJuIC1FSU5WQUw7CglpZiAoY291bnQgPT0gMCB8fCBjb3VudCA+IElCTUFTTV9FVkVOVF9NQVhfU0laRSkKCQlyZXR1cm4gMDsKCWlmICgqb2Zmc2V0ICE9IDApCgkJcmV0dXJuIDA7CgoJc3Bpbl9sb2NrX2lycXNhdmUoJnNwLT5sb2NrLCBmbGFncyk7CglpZiAoZXZlbnRfZGF0YS0+YWN0aXZlKSB7CgkJc3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmc3AtPmxvY2ssIGZsYWdzKTsKCQlyZXR1cm4gLUVCVVNZOwoJfQoJZXZlbnRfZGF0YS0+YWN0aXZlID0gMTsKCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJnNwLT5sb2NrLCBmbGFncyk7CgoJcmV0ID0gaWJtYXNtX2dldF9uZXh0X2V2ZW50KHNwLCByZWFkZXIpOwoJaWYgKHJldCA8PSAwKQoJCWdvdG8gb3V0OwoKCWlmIChjb3VudCA8IHJlYWRlci0+ZGF0YV9zaXplKSB7CgkJcmV0ID0gLUVJTlZBTDsKCQlnb3RvIG91dDsKCX0KCiAgICAgICAgaWYgKGNvcHlfdG9fdXNlcihidWYsIHJlYWRlci0+ZGF0YSwgcmVhZGVyLT5kYXRhX3NpemUpKSB7CgkJcmV0ID0gLUVGQVVMVDsKCQlnb3RvIG91dDsKCX0KCXJldCA9IHJlYWRlci0+ZGF0YV9zaXplOwoKb3V0OgoJZXZlbnRfZGF0YS0+YWN0aXZlID0gMDsKCXJldHVybiByZXQ7Cn0KCnN0YXRpYyBzc2l6ZV90IGV2ZW50X2ZpbGVfd3JpdGUoc3RydWN0IGZpbGUgKmZpbGUsIGNvbnN0IGNoYXIgX191c2VyICpidWYsIHNpemVfdCBjb3VudCwgbG9mZl90ICpvZmZzZXQpCnsKCXN0cnVjdCBpYm1hc21mc19ldmVudF9kYXRhICpldmVudF9kYXRhID0gZmlsZS0+cHJpdmF0ZV9kYXRhOwoKCWlmICgqb2Zmc2V0IDwgMCkKCQlyZXR1cm4gLUVJTlZBTDsKCWlmIChjb3VudCAhPSAxKQoJCXJldHVybiAwOwoJaWYgKCpvZmZzZXQgIT0gMCkKCQlyZXR1cm4gMDsKCglpYm1hc21fY2FuY2VsX25leHRfZXZlbnQoJmV2ZW50X2RhdGEtPnJlYWRlcik7CglyZXR1cm4gMDsKfQoKc3RhdGljIGludCByX2hlYXJ0YmVhdF9maWxlX29wZW4oc3RydWN0IGlub2RlICppbm9kZSwgc3RydWN0IGZpbGUgKmZpbGUpCnsKCXN0cnVjdCBpYm1hc21mc19oZWFydGJlYXRfZGF0YSAqcmhiZWF0OwoKCWlmICghaW5vZGUtPnUuZ2VuZXJpY19pcCkKCQlyZXR1cm4gLUVOT0RFVjsKCglyaGJlYXQgPSBrbWFsbG9jKHNpemVvZihzdHJ1Y3QgaWJtYXNtZnNfaGVhcnRiZWF0X2RhdGEpLCBHRlBfS0VSTkVMKTsKCWlmICghcmhiZWF0KQoJCXJldHVybiAtRU5PTUVNOwoKCXJoYmVhdC0+c3AgPSAoc3RydWN0IHNlcnZpY2VfcHJvY2Vzc29yICopaW5vZGUtPnUuZ2VuZXJpY19pcDsKCXJoYmVhdC0+YWN0aXZlID0gMDsKCWlibWFzbV9pbml0X3JldmVyc2VfaGVhcnRiZWF0KHJoYmVhdC0+c3AsICZyaGJlYXQtPmhlYXJ0YmVhdCk7CglmaWxlLT5wcml2YXRlX2RhdGEgPSByaGJlYXQ7CglyZXR1cm4gMDsKfQoKc3RhdGljIGludCByX2hlYXJ0YmVhdF9maWxlX2Nsb3NlKHN0cnVjdCBpbm9kZSAqaW5vZGUsIHN0cnVjdCBmaWxlICpmaWxlKQp7CglzdHJ1Y3QgaWJtYXNtZnNfaGVhcnRiZWF0X2RhdGEgKnJoYmVhdCA9IGZpbGUtPnByaXZhdGVfZGF0YTsKCglrZnJlZShyaGJlYXQpOwoJcmV0dXJuIDA7Cn0KCnN0YXRpYyBzc2l6ZV90IHJfaGVhcnRiZWF0X2ZpbGVfcmVhZChzdHJ1Y3QgZmlsZSAqZmlsZSwgY2hhciBfX3VzZXIgKmJ1Ziwgc2l6ZV90IGNvdW50LCBsb2ZmX3QgKm9mZnNldCkKewoJc3RydWN0IGlibWFzbWZzX2hlYXJ0YmVhdF9kYXRhICpyaGJlYXQgPSBmaWxlLT5wcml2YXRlX2RhdGE7Cgl1bnNpZ25lZCBsb25nIGZsYWdzOwoJaW50IHJlc3VsdDsKCglpZiAoKm9mZnNldCA8IDApCgkJcmV0dXJuIC1FSU5WQUw7CglpZiAoY291bnQgPT0gMCB8fCBjb3VudCA+IDEwMjQpCgkJcmV0dXJuIDA7CglpZiAoKm9mZnNldCAhPSAwKQoJCXJldHVybiAwOwoKCS8qIGFsbG93IG9ubHkgb25lIHJldmVyc2UgaGVhcnRiZWF0IHBlciBwcm9jZXNzICovCglzcGluX2xvY2tfaXJxc2F2ZSgmcmhiZWF0LT5zcC0+bG9jaywgZmxhZ3MpOwoJaWYgKHJoYmVhdC0+YWN0aXZlKSB7CgkJc3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmcmhiZWF0LT5zcC0+bG9jaywgZmxhZ3MpOwoJCXJldHVybiAtRUJVU1k7Cgl9CglyaGJlYXQtPmFjdGl2ZSA9IDE7CglzcGluX3VubG9ja19pcnFyZXN0b3JlKCZyaGJlYXQtPnNwLT5sb2NrLCBmbGFncyk7CgoJcmVzdWx0ID0gaWJtYXNtX3N0YXJ0X3JldmVyc2VfaGVhcnRiZWF0KHJoYmVhdC0+c3AsICZyaGJlYXQtPmhlYXJ0YmVhdCk7CglyaGJlYXQtPmFjdGl2ZSA9IDA7CgoJcmV0dXJuIHJlc3VsdDsKfQoKc3RhdGljIHNzaXplX3Qgcl9oZWFydGJlYXRfZmlsZV93cml0ZShzdHJ1Y3QgZmlsZSAqZmlsZSwgY29uc3QgY2hhciBfX3VzZXIgKmJ1Ziwgc2l6ZV90IGNvdW50LCBsb2ZmX3QgKm9mZnNldCkKewoJc3RydWN0IGlibWFzbWZzX2hlYXJ0YmVhdF9kYXRhICpyaGJlYXQgPSBmaWxlLT5wcml2YXRlX2RhdGE7CgoJaWYgKCpvZmZzZXQgPCAwKQoJCXJldHVybiAtRUlOVkFMOwoJaWYgKGNvdW50ICE9IDEpCgkJcmV0dXJuIDA7CglpZiAoKm9mZnNldCAhPSAwKQoJCXJldHVybiAwOwoKCWlmIChyaGJlYXQtPmFjdGl2ZSkKCQlpYm1hc21fc3RvcF9yZXZlcnNlX2hlYXJ0YmVhdCgmcmhiZWF0LT5oZWFydGJlYXQpOwoKCXJldHVybiAxOwp9CgpzdGF0aWMgaW50IHJlbW90ZV9zZXR0aW5nc19maWxlX29wZW4oc3RydWN0IGlub2RlICppbm9kZSwgc3RydWN0IGZpbGUgKmZpbGUpCnsKCWZpbGUtPnByaXZhdGVfZGF0YSA9IGlub2RlLT51LmdlbmVyaWNfaXA7CglyZXR1cm4gMDsKfQoKc3RhdGljIGludCByZW1vdGVfc2V0dGluZ3NfZmlsZV9jbG9zZShzdHJ1Y3QgaW5vZGUgKmlub2RlLCBzdHJ1Y3QgZmlsZSAqZmlsZSkKewoJcmV0dXJuIDA7Cn0KCnN0YXRpYyBzc2l6ZV90IHJlbW90ZV9zZXR0aW5nc19maWxlX3JlYWQoc3RydWN0IGZpbGUgKmZpbGUsIGNoYXIgX191c2VyICpidWYsIHNpemVfdCBjb3VudCwgbG9mZl90ICpvZmZzZXQpCnsKCXZvaWQgX19pb21lbSAqYWRkcmVzcyA9ICh2b2lkIF9faW9tZW0gKilmaWxlLT5wcml2YXRlX2RhdGE7Cgl1bnNpZ25lZCBjaGFyICpwYWdlOwoJaW50IHJldHZhbDsKCWludCBsZW4gPSAwOwoJdW5zaWduZWQgaW50IHZhbHVlOwoKCWlmICgqb2Zmc2V0IDwgMCkKCQlyZXR1cm4gLUVJTlZBTDsKCWlmIChjb3VudCA9PSAwIHx8IGNvdW50ID4gMTAyNCkKCQlyZXR1cm4gMDsKCWlmICgqb2Zmc2V0ICE9IDApCgkJcmV0dXJuIDA7CgoJcGFnZSA9ICh1bnNpZ25lZCBjaGFyICopX19nZXRfZnJlZV9wYWdlKEdGUF9LRVJORUwpOwoJaWYgKCFwYWdlKQoJCXJldHVybiAtRU5PTUVNOwoKCXZhbHVlID0gcmVhZGwoYWRkcmVzcyk7CglsZW4gPSBzcHJpbnRmKHBhZ2UsICIlZFxuIiwgdmFsdWUpOwoKCWlmIChjb3B5X3RvX3VzZXIoYnVmLCBwYWdlLCBsZW4pKSB7CgkJcmV0dmFsID0gLUVGQVVMVDsKCQlnb3RvIGV4aXQ7Cgl9Cgkqb2Zmc2V0ICs9IGxlbjsKCXJldHZhbCA9IGxlbjsKCmV4aXQ6CglmcmVlX3BhZ2UoKHVuc2lnbmVkIGxvbmcpcGFnZSk7CglyZXR1cm4gcmV0dmFsOwp9CgpzdGF0aWMgc3NpemVfdCByZW1vdGVfc2V0dGluZ3NfZmlsZV93cml0ZShzdHJ1Y3QgZmlsZSAqZmlsZSwgY29uc3QgY2hhciBfX3VzZXIgKnVidWZmLCBzaXplX3QgY291bnQsIGxvZmZfdCAqb2Zmc2V0KQp7Cgl2b2lkIF9faW9tZW0gKmFkZHJlc3MgPSAodm9pZCBfX2lvbWVtICopZmlsZS0+cHJpdmF0ZV9kYXRhOwoJY2hhciAqYnVmZjsKCXVuc2lnbmVkIGludCB2YWx1ZTsKCglpZiAoKm9mZnNldCA8IDApCgkJcmV0dXJuIC1FSU5WQUw7CglpZiAoY291bnQgPT0gMCB8fCBjb3VudCA+IDEwMjQpCgkJcmV0dXJuIDA7CglpZiAoKm9mZnNldCAhPSAwKQoJCXJldHVybiAwOwoKCWJ1ZmYgPSBrbWFsbG9jIChjb3VudCArIDEsIEdGUF9LRVJORUwpOwoJaWYgKCFidWZmKQoJCXJldHVybiAtRU5PTUVNOwoKCW1lbXNldChidWZmLCAweDAsIGNvdW50ICsgMSk7CgoJaWYgKGNvcHlfZnJvbV91c2VyKGJ1ZmYsIHVidWZmLCBjb3VudCkpIHsKCQlrZnJlZShidWZmKTsKCQlyZXR1cm4gLUVGQVVMVDsKCX0KCQoJdmFsdWUgPSBzaW1wbGVfc3RydG91bChidWZmLCBOVUxMLCAxMCk7Cgl3cml0ZWwodmFsdWUsIGFkZHJlc3MpOwoJa2ZyZWUoYnVmZik7CgoJcmV0dXJuIGNvdW50Owp9CgpzdGF0aWMgc3RydWN0IGZpbGVfb3BlcmF0aW9ucyBjb21tYW5kX2ZvcHMgPSB7Cgkub3BlbiA9CQljb21tYW5kX2ZpbGVfb3BlbiwKCS5yZWxlYXNlID0JY29tbWFuZF9maWxlX2Nsb3NlLAoJLnJlYWQgPQkJY29tbWFuZF9maWxlX3JlYWQsCgkud3JpdGUgPQljb21tYW5kX2ZpbGVfd3JpdGUsCn07CgpzdGF0aWMgc3RydWN0IGZpbGVfb3BlcmF0aW9ucyBldmVudF9mb3BzID0gewoJLm9wZW4gPQkJZXZlbnRfZmlsZV9vcGVuLAoJLnJlbGVhc2UgPQlldmVudF9maWxlX2Nsb3NlLAoJLnJlYWQgPQkJZXZlbnRfZmlsZV9yZWFkLAoJLndyaXRlID0JZXZlbnRfZmlsZV93cml0ZSwKfTsKCnN0YXRpYyBzdHJ1Y3QgZmlsZV9vcGVyYXRpb25zIHJfaGVhcnRiZWF0X2ZvcHMgPSB7Cgkub3BlbiA9CQlyX2hlYXJ0YmVhdF9maWxlX29wZW4sCgkucmVsZWFzZSA9CXJfaGVhcnRiZWF0X2ZpbGVfY2xvc2UsCgkucmVhZCA9CQlyX2hlYXJ0YmVhdF9maWxlX3JlYWQsCgkud3JpdGUgPQlyX2hlYXJ0YmVhdF9maWxlX3dyaXRlLAp9OwoKc3RhdGljIHN0cnVjdCBmaWxlX29wZXJhdGlvbnMgcmVtb3RlX3NldHRpbmdzX2ZvcHMgPSB7Cgkub3BlbiA9CQlyZW1vdGVfc2V0dGluZ3NfZmlsZV9vcGVuLAoJLnJlbGVhc2UgPQlyZW1vdGVfc2V0dGluZ3NfZmlsZV9jbG9zZSwKCS5yZWFkID0JCXJlbW90ZV9zZXR0aW5nc19maWxlX3JlYWQsCgkud3JpdGUgPQlyZW1vdGVfc2V0dGluZ3NfZmlsZV93cml0ZSwKfTsKCgpzdGF0aWMgdm9pZCBpYm1hc21mc19jcmVhdGVfZmlsZXMgKHN0cnVjdCBzdXBlcl9ibG9jayAqc2IsIHN0cnVjdCBkZW50cnkgKnJvb3QpCnsKCXN0cnVjdCBsaXN0X2hlYWQgKmVudHJ5OwoJc3RydWN0IHNlcnZpY2VfcHJvY2Vzc29yICpzcDsKCglsaXN0X2Zvcl9lYWNoKGVudHJ5LCAmc2VydmljZV9wcm9jZXNzb3JzKSB7CgkJc3RydWN0IGRlbnRyeSAqZGlyOwoJCXN0cnVjdCBkZW50cnkgKnJlbW90ZV9kaXI7CgkJc3AgPSBsaXN0X2VudHJ5KGVudHJ5LCBzdHJ1Y3Qgc2VydmljZV9wcm9jZXNzb3IsIG5vZGUpOwoJCWRpciA9IGlibWFzbWZzX2NyZWF0ZV9kaXIoc2IsIHJvb3QsIHNwLT5kaXJuYW1lKTsKCQlpZiAoIWRpcikKCQkJY29udGludWU7CgoJCWlibWFzbWZzX2NyZWF0ZV9maWxlKHNiLCBkaXIsICJjb21tYW5kIiwgJmNvbW1hbmRfZm9wcywgc3AsIFNfSVJVU1J8U19JV1VTUik7CgkJaWJtYXNtZnNfY3JlYXRlX2ZpbGUoc2IsIGRpciwgImV2ZW50IiwgJmV2ZW50X2ZvcHMsIHNwLCBTX0lSVVNSfFNfSVdVU1IpOwoJCWlibWFzbWZzX2NyZWF0ZV9maWxlKHNiLCBkaXIsICJyZXZlcnNlX2hlYXJ0YmVhdCIsICZyX2hlYXJ0YmVhdF9mb3BzLCBzcCwgU19JUlVTUnxTX0lXVVNSKTsKCgkJcmVtb3RlX2RpciA9IGlibWFzbWZzX2NyZWF0ZV9kaXIoc2IsIGRpciwgInJlbW90ZV92aWRlbyIpOwoJCWlmICghcmVtb3RlX2RpcikKCQkJY29udGludWU7CgoJCWlibWFzbWZzX2NyZWF0ZV9maWxlKHNiLCByZW1vdGVfZGlyLCAid2lkdGgiLCAmcmVtb3RlX3NldHRpbmdzX2ZvcHMsICh2b2lkICopZGlzcGxheV93aWR0aChzcCksIFNfSVJVU1J8U19JV1VTUik7CgkJaWJtYXNtZnNfY3JlYXRlX2ZpbGUoc2IsIHJlbW90ZV9kaXIsICJoZWlnaHQiLCAmcmVtb3RlX3NldHRpbmdzX2ZvcHMsICh2b2lkICopZGlzcGxheV9oZWlnaHQoc3ApLCBTX0lSVVNSfFNfSVdVU1IpOwoJCWlibWFzbWZzX2NyZWF0ZV9maWxlKHNiLCByZW1vdGVfZGlyLCAiZGVwdGgiLCAmcmVtb3RlX3NldHRpbmdzX2ZvcHMsICh2b2lkICopZGlzcGxheV9kZXB0aChzcCksIFNfSVJVU1J8U19JV1VTUik7Cgl9Cn0K