LyoKICogIGxpbnV4L2ZzL3N1cGVyLmMKICoKICogIENvcHlyaWdodCAoQykgMTk5MSwgMTk5MiAgTGludXMgVG9ydmFsZHMKICoKICogIHN1cGVyLmMgY29udGFpbnMgY29kZSB0byBoYW5kbGU6IC0gbW91bnQgc3RydWN0dXJlcwogKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLSBzdXBlci1ibG9jayB0YWJsZXMKICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC0gZmlsZXN5c3RlbSBkcml2ZXJzIGxpc3QKICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC0gbW91bnQgc3lzdGVtIGNhbGwKICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC0gdW1vdW50IHN5c3RlbSBjYWxsCiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAtIHVzdGF0IHN5c3RlbSBjYWxsCiAqCiAqIEdLIDIvNS85NSAgLSAgQ2hhbmdlZCB0byBzdXBwb3J0IG1vdW50aW5nIHRoZSByb290IGZzIHZpYSBORlMKICoKICogIEFkZGVkIGtlcm5lbGQgc3VwcG9ydDogSmFjcXVlcyBHZWxpbmFzIGFuZCBCam9ybiBFa3dhbGwKICogIEFkZGVkIGNoYW5nZV9yb290OiBXZXJuZXIgQWxtZXNiZXJnZXIgJiBIYW5zIExlcm1lbiwgRmViICc5NgogKiAgQWRkZWQgb3B0aW9ucyB0byAvcHJvYy9tb3VudHM6CiAqICAgIFRvcmJq9nJuIExpbmRoICh0b3Jiam9ybi5saW5kaEBnb3B0YS5zZSksIEFwcmlsIDE0LCAxOTk2LgogKiAgQWRkZWQgZGV2ZnMgc3VwcG9ydDogUmljaGFyZCBHb29jaCA8cmdvb2NoQGF0bmYuY3Npcm8uYXU+LCAxMy1KQU4tMTk5OAogKiAgSGVhdmlseSByZXdyaXR0ZW4gZm9yICdvbmUgZnMgLSBvbmUgdHJlZScgZGNhY2hlIGFyY2hpdGVjdHVyZS4gQVYsIE1hciAyMDAwCiAqLwoKI2luY2x1ZGUgPGxpbnV4L2NvbmZpZy5oPgojaW5jbHVkZSA8bGludXgvbW9kdWxlLmg+CiNpbmNsdWRlIDxsaW51eC9zbGFiLmg+CiNpbmNsdWRlIDxsaW51eC9pbml0Lmg+CiNpbmNsdWRlIDxsaW51eC9zbXBfbG9jay5oPgojaW5jbHVkZSA8bGludXgvYWNjdC5oPgojaW5jbHVkZSA8bGludXgvYmxrZGV2Lmg+CiNpbmNsdWRlIDxsaW51eC9xdW90YW9wcy5oPgojaW5jbHVkZSA8bGludXgvbmFtZWkuaD4KI2luY2x1ZGUgPGxpbnV4L2J1ZmZlcl9oZWFkLmg+CQkvKiBmb3IgZnN5bmNfc3VwZXIoKSAqLwojaW5jbHVkZSA8bGludXgvbW91bnQuaD4KI2luY2x1ZGUgPGxpbnV4L3NlY3VyaXR5Lmg+CiNpbmNsdWRlIDxsaW51eC9zeXNjYWxscy5oPgojaW5jbHVkZSA8bGludXgvdmZzLmg+CiNpbmNsdWRlIDxsaW51eC93cml0ZWJhY2suaD4JCS8qIGZvciB0aGUgZW1lcmdlbmN5IHJlbW91bnQgc3R1ZmYgKi8KI2luY2x1ZGUgPGxpbnV4L2lkci5oPgojaW5jbHVkZSA8bGludXgva29iamVjdC5oPgojaW5jbHVkZSA8bGludXgvbXV0ZXguaD4KI2luY2x1ZGUgPGFzbS91YWNjZXNzLmg+CgoKdm9pZCBnZXRfZmlsZXN5c3RlbShzdHJ1Y3QgZmlsZV9zeXN0ZW1fdHlwZSAqZnMpOwp2b2lkIHB1dF9maWxlc3lzdGVtKHN0cnVjdCBmaWxlX3N5c3RlbV90eXBlICpmcyk7CnN0cnVjdCBmaWxlX3N5c3RlbV90eXBlICpnZXRfZnNfdHlwZShjb25zdCBjaGFyICpuYW1lKTsKCkxJU1RfSEVBRChzdXBlcl9ibG9ja3MpOwpERUZJTkVfU1BJTkxPQ0soc2JfbG9jayk7CgovKioKICoJYWxsb2Nfc3VwZXIJLQljcmVhdGUgbmV3IHN1cGVyYmxvY2sKICoKICoJQWxsb2NhdGVzIGFuZCBpbml0aWFsaXplcyBhIG5ldyAmc3RydWN0IHN1cGVyX2Jsb2NrLiAgYWxsb2Nfc3VwZXIoKQogKglyZXR1cm5zIGEgcG9pbnRlciBuZXcgc3VwZXJibG9jayBvciAlTlVMTCBpZiBhbGxvY2F0aW9uIGhhZCBmYWlsZWQuCiAqLwpzdGF0aWMgc3RydWN0IHN1cGVyX2Jsb2NrICphbGxvY19zdXBlcih2b2lkKQp7CglzdHJ1Y3Qgc3VwZXJfYmxvY2sgKnMgPSBremFsbG9jKHNpemVvZihzdHJ1Y3Qgc3VwZXJfYmxvY2spLCAgR0ZQX1VTRVIpOwoJc3RhdGljIHN0cnVjdCBzdXBlcl9vcGVyYXRpb25zIGRlZmF1bHRfb3A7CgoJaWYgKHMpIHsKCQlpZiAoc2VjdXJpdHlfc2JfYWxsb2MocykpIHsKCQkJa2ZyZWUocyk7CgkJCXMgPSBOVUxMOwoJCQlnb3RvIG91dDsKCQl9CgkJSU5JVF9MSVNUX0hFQUQoJnMtPnNfZGlydHkpOwoJCUlOSVRfTElTVF9IRUFEKCZzLT5zX2lvKTsKCQlJTklUX0xJU1RfSEVBRCgmcy0+c19maWxlcyk7CgkJSU5JVF9MSVNUX0hFQUQoJnMtPnNfaW5zdGFuY2VzKTsKCQlJTklUX0hMSVNUX0hFQUQoJnMtPnNfYW5vbik7CgkJSU5JVF9MSVNUX0hFQUQoJnMtPnNfaW5vZGVzKTsKCQlpbml0X3J3c2VtKCZzLT5zX3Vtb3VudCk7CgkJbXV0ZXhfaW5pdCgmcy0+c19sb2NrKTsKCQlkb3duX3dyaXRlKCZzLT5zX3Vtb3VudCk7CgkJcy0+c19jb3VudCA9IFNfQklBUzsKCQlhdG9taWNfc2V0KCZzLT5zX2FjdGl2ZSwgMSk7CgkJbXV0ZXhfaW5pdCgmcy0+c192ZnNfcmVuYW1lX211dGV4KTsKCQltdXRleF9pbml0KCZzLT5zX2RxdW90LmRxaW9fbXV0ZXgpOwoJCW11dGV4X2luaXQoJnMtPnNfZHF1b3QuZHFvbm9mZl9tdXRleCk7CgkJaW5pdF9yd3NlbSgmcy0+c19kcXVvdC5kcXB0cl9zZW0pOwoJCWluaXRfd2FpdHF1ZXVlX2hlYWQoJnMtPnNfd2FpdF91bmZyb3plbik7CgkJcy0+c19tYXhieXRlcyA9IE1BWF9OT05fTEZTOwoJCXMtPmRxX29wID0gc2JfZHF1b3Rfb3BzOwoJCXMtPnNfcWNvcCA9IHNiX3F1b3RhY3RsX29wczsKCQlzLT5zX29wID0gJmRlZmF1bHRfb3A7CgkJcy0+c190aW1lX2dyYW4gPSAxMDAwMDAwMDAwOwoJfQpvdXQ6CglyZXR1cm4gczsKfQoKLyoqCiAqCWRlc3Ryb3lfc3VwZXIJLQlmcmVlcyBhIHN1cGVyYmxvY2sKICoJQHM6IHN1cGVyYmxvY2sgdG8gZnJlZQogKgogKglGcmVlcyBhIHN1cGVyYmxvY2suCiAqLwpzdGF0aWMgaW5saW5lIHZvaWQgZGVzdHJveV9zdXBlcihzdHJ1Y3Qgc3VwZXJfYmxvY2sgKnMpCnsKCXNlY3VyaXR5X3NiX2ZyZWUocyk7CglrZnJlZShzKTsKfQoKLyogU3VwZXJibG9jayByZWZjb3VudGluZyAgKi8KCi8qCiAqIERyb3AgYSBzdXBlcmJsb2NrJ3MgcmVmY291bnQuICBSZXR1cm5zIG5vbi16ZXJvIGlmIHRoZSBzdXBlcmJsb2NrIHdhcwogKiBkZXN0cm95ZWQuICBUaGUgY2FsbGVyIG11c3QgaG9sZCBzYl9sb2NrLgogKi8KaW50IF9fcHV0X3N1cGVyKHN0cnVjdCBzdXBlcl9ibG9jayAqc2IpCnsKCWludCByZXQgPSAwOwoKCWlmICghLS1zYi0+c19jb3VudCkgewoJCWRlc3Ryb3lfc3VwZXIoc2IpOwoJCXJldCA9IDE7Cgl9CglyZXR1cm4gcmV0Owp9CgovKgogKiBEcm9wIGEgc3VwZXJibG9jaydzIHJlZmNvdW50LgogKiBSZXR1cm5zIG5vbi16ZXJvIGlmIHRoZSBzdXBlcmJsb2NrIGlzIGFib3V0IHRvIGJlIGRlc3Ryb3llZCBhbmQKICogYXQgbGVhc3QgaXMgYWxyZWFkeSByZW1vdmVkIGZyb20gc3VwZXJfYmxvY2tzIGxpc3QsIHNvIGlmIHdlIGFyZQogKiBtYWtpbmcgYSBsb29wIHRocm91Z2ggc3VwZXIgYmxvY2tzIHRoZW4gd2UgbmVlZCB0byByZXN0YXJ0LgogKiBUaGUgY2FsbGVyIG11c3QgaG9sZCBzYl9sb2NrLgogKi8KaW50IF9fcHV0X3N1cGVyX2FuZF9uZWVkX3Jlc3RhcnQoc3RydWN0IHN1cGVyX2Jsb2NrICpzYikKewoJLyogY2hlY2sgZm9yIHJhY2Ugd2l0aCBnZW5lcmljX3NodXRkb3duX3N1cGVyKCkgKi8KCWlmIChsaXN0X2VtcHR5KCZzYi0+c19saXN0KSkgewoJCS8qIHN1cGVyIGJsb2NrIGlzIHJlbW92ZWQsIG5lZWQgdG8gcmVzdGFydC4uLiAqLwoJCV9fcHV0X3N1cGVyKHNiKTsKCQlyZXR1cm4gMTsKCX0KCS8qIGNhbid0IGJlIHRoZSBsYXN0LCBzaW5jZSBzX2xpc3QgaXMgc3RpbGwgaW4gdXNlICovCglzYi0+c19jb3VudC0tOwoJQlVHX09OKHNiLT5zX2NvdW50ID09IDApOwoJcmV0dXJuIDA7Cn0KCi8qKgogKglwdXRfc3VwZXIJLQlkcm9wIGEgdGVtcG9yYXJ5IHJlZmVyZW5jZSB0byBzdXBlcmJsb2NrCiAqCUBzYjogc3VwZXJibG9jayBpbiBxdWVzdGlvbgogKgogKglEcm9wcyBhIHRlbXBvcmFyeSByZWZlcmVuY2UsIGZyZWVzIHN1cGVyYmxvY2sgaWYgdGhlcmUncyBubwogKglyZWZlcmVuY2VzIGxlZnQuCiAqLwpzdGF0aWMgdm9pZCBwdXRfc3VwZXIoc3RydWN0IHN1cGVyX2Jsb2NrICpzYikKewoJc3Bpbl9sb2NrKCZzYl9sb2NrKTsKCV9fcHV0X3N1cGVyKHNiKTsKCXNwaW5fdW5sb2NrKCZzYl9sb2NrKTsKfQoKCi8qKgogKglkZWFjdGl2YXRlX3N1cGVyCS0JZHJvcCBhbiBhY3RpdmUgcmVmZXJlbmNlIHRvIHN1cGVyYmxvY2sKICoJQHM6IHN1cGVyYmxvY2sgdG8gZGVhY3RpdmF0ZQogKgogKglEcm9wcyBhbiBhY3RpdmUgcmVmZXJlbmNlIHRvIHN1cGVyYmxvY2ssIGFjcXVpcmluZyBhIHRlbXByb3J5IG9uZSBpZgogKgl0aGVyZSBpcyBubyBhY3RpdmUgcmVmZXJlbmNlcyBsZWZ0LiAgSW4gdGhhdCBjYXNlIHdlIGxvY2sgc3VwZXJibG9jaywKICoJdGVsbCBmcyBkcml2ZXIgdG8gc2h1dCBpdCBkb3duIGFuZCBkcm9wIHRoZSB0ZW1wb3JhcnkgcmVmZXJlbmNlIHdlCiAqCWhhZCBqdXN0IGFjcXVpcmVkLgogKi8Kdm9pZCBkZWFjdGl2YXRlX3N1cGVyKHN0cnVjdCBzdXBlcl9ibG9jayAqcykKewoJc3RydWN0IGZpbGVfc3lzdGVtX3R5cGUgKmZzID0gcy0+c190eXBlOwoJaWYgKGF0b21pY19kZWNfYW5kX2xvY2soJnMtPnNfYWN0aXZlLCAmc2JfbG9jaykpIHsKCQlzLT5zX2NvdW50IC09IFNfQklBUy0xOwoJCXNwaW5fdW5sb2NrKCZzYl9sb2NrKTsKCQlEUVVPVF9PRkYocyk7CgkJZG93bl93cml0ZSgmcy0+c191bW91bnQpOwoJCWZzLT5raWxsX3NiKHMpOwoJCXB1dF9maWxlc3lzdGVtKGZzKTsKCQlwdXRfc3VwZXIocyk7Cgl9Cn0KCkVYUE9SVF9TWU1CT0woZGVhY3RpdmF0ZV9zdXBlcik7CgovKioKICoJZ3JhYl9zdXBlciAtIGFjcXVpcmUgYW4gYWN0aXZlIHJlZmVyZW5jZQogKglAczogcmVmZXJlbmNlIHdlIGFyZSB0cnlpbmcgdG8gbWFrZSBhY3RpdmUKICoKICoJVHJpZXMgdG8gYWNxdWlyZSBhbiBhY3RpdmUgcmVmZXJlbmNlLiAgZ3JhYl9zdXBlcigpIGlzIHVzZWQgd2hlbiB3ZQogKiAJaGFkIGp1c3QgZm91bmQgYSBzdXBlcmJsb2NrIGluIHN1cGVyX2Jsb2NrcyBvciBmc190eXBlLT5mc19zdXBlcnMKICoJYW5kIHdhbnQgdG8gdHVybiBpdCBpbnRvIGEgZnVsbC1ibG93biBhY3RpdmUgcmVmZXJlbmNlLiAgZ3JhYl9zdXBlcigpCiAqCWlzIGNhbGxlZCB3aXRoIHNiX2xvY2sgaGVsZCBhbmQgZHJvcHMgaXQuICBSZXR1cm5zIDEgaW4gY2FzZSBvZgogKglzdWNjZXNzLCAwIGlmIHdlIGhhZCBmYWlsZWQgKHN1cGVyYmxvY2sgY29udGVudHMgd2FzIGFscmVhZHkgZGVhZCBvcgogKglkeWluZyB3aGVuIGdyYWJfc3VwZXIoKSBoYWQgYmVlbiBjYWxsZWQpLgogKi8Kc3RhdGljIGludCBncmFiX3N1cGVyKHN0cnVjdCBzdXBlcl9ibG9jayAqcykKewoJcy0+c19jb3VudCsrOwoJc3Bpbl91bmxvY2soJnNiX2xvY2spOwoJZG93bl93cml0ZSgmcy0+c191bW91bnQpOwoJaWYgKHMtPnNfcm9vdCkgewoJCXNwaW5fbG9jaygmc2JfbG9jayk7CgkJaWYgKHMtPnNfY291bnQgPiBTX0JJQVMpIHsKCQkJYXRvbWljX2luYygmcy0+c19hY3RpdmUpOwoJCQlzLT5zX2NvdW50LS07CgkJCXNwaW5fdW5sb2NrKCZzYl9sb2NrKTsKCQkJcmV0dXJuIDE7CgkJfQoJCXNwaW5fdW5sb2NrKCZzYl9sb2NrKTsKCX0KCXVwX3dyaXRlKCZzLT5zX3Vtb3VudCk7CglwdXRfc3VwZXIocyk7Cgl5aWVsZCgpOwoJcmV0dXJuIDA7Cn0KCi8qKgogKglnZW5lcmljX3NodXRkb3duX3N1cGVyCS0JY29tbW9uIGhlbHBlciBmb3IgLT5raWxsX3NiKCkKICoJQHNiOiBzdXBlcmJsb2NrIHRvIGtpbGwKICoKICoJZ2VuZXJpY19zaHV0ZG93bl9zdXBlcigpIGRvZXMgYWxsIGZzLWluZGVwZW5kZW50IHdvcmsgb24gc3VwZXJibG9jawogKglzaHV0ZG93bi4gIFR5cGljYWwgLT5raWxsX3NiKCkgc2hvdWxkIHBpY2sgYWxsIGZzLXNwZWNpZmljIG9iamVjdHMKICoJdGhhdCBuZWVkIGRlc3RydWN0aW9uIG91dCBvZiBzdXBlcmJsb2NrLCBjYWxsIGdlbmVyaWNfc2h1dGRvd25fc3VwZXIoKQogKglhbmQgcmVsZWFzZSBhZm9yZW1lbnRpb25lZCBvYmplY3RzLiAgTm90ZTogZGVudHJpZXMgYW5kIGlub2RlcyBfYXJlXwogKgl0YWtlbiBjYXJlIG9mIGFuZCBkbyBub3QgbmVlZCBzcGVjaWZpYyBoYW5kbGluZy4KICovCnZvaWQgZ2VuZXJpY19zaHV0ZG93bl9zdXBlcihzdHJ1Y3Qgc3VwZXJfYmxvY2sgKnNiKQp7CglzdHJ1Y3QgZGVudHJ5ICpyb290ID0gc2ItPnNfcm9vdDsKCXN0cnVjdCBzdXBlcl9vcGVyYXRpb25zICpzb3AgPSBzYi0+c19vcDsKCglpZiAocm9vdCkgewoJCXNiLT5zX3Jvb3QgPSBOVUxMOwoJCXNocmlua19kY2FjaGVfcGFyZW50KHJvb3QpOwoJCXNocmlua19kY2FjaGVfc2Ioc2IpOwoJCWRwdXQocm9vdCk7CgkJZnN5bmNfc3VwZXIoc2IpOwoJCWxvY2tfc3VwZXIoc2IpOwoJCXNiLT5zX2ZsYWdzICY9IH5NU19BQ1RJVkU7CgkJLyogYmFkIG5hbWUgLSBpdCBzaG91bGQgYmUgZXZpY3RfaW5vZGVzKCkgKi8KCQlpbnZhbGlkYXRlX2lub2RlcyhzYik7CgkJbG9ja19rZXJuZWwoKTsKCgkJaWYgKHNvcC0+d3JpdGVfc3VwZXIgJiYgc2ItPnNfZGlydCkKCQkJc29wLT53cml0ZV9zdXBlcihzYik7CgkJaWYgKHNvcC0+cHV0X3N1cGVyKQoJCQlzb3AtPnB1dF9zdXBlcihzYik7CgoJCS8qIEZvcmdldCBhbnkgcmVtYWluaW5nIGlub2RlcyAqLwoJCWlmIChpbnZhbGlkYXRlX2lub2RlcyhzYikpIHsKCQkJcHJpbnRrKCJWRlM6IEJ1c3kgaW5vZGVzIGFmdGVyIHVubW91bnQgb2YgJXMuICIKCQkJICAgIlNlbGYtZGVzdHJ1Y3QgaW4gNSBzZWNvbmRzLiAgSGF2ZSBhIG5pY2UgZGF5Li4uXG4iLAoJCQkgICBzYi0+c19pZCk7CgkJfQoKCQl1bmxvY2tfa2VybmVsKCk7CgkJdW5sb2NrX3N1cGVyKHNiKTsKCX0KCXNwaW5fbG9jaygmc2JfbG9jayk7CgkvKiBzaG91bGQgYmUgaW5pdGlhbGl6ZWQgZm9yIF9fcHV0X3N1cGVyX2FuZF9uZWVkX3Jlc3RhcnQoKSAqLwoJbGlzdF9kZWxfaW5pdCgmc2ItPnNfbGlzdCk7CglsaXN0X2RlbCgmc2ItPnNfaW5zdGFuY2VzKTsKCXNwaW5fdW5sb2NrKCZzYl9sb2NrKTsKCXVwX3dyaXRlKCZzYi0+c191bW91bnQpOwp9CgpFWFBPUlRfU1lNQk9MKGdlbmVyaWNfc2h1dGRvd25fc3VwZXIpOwoKLyoqCiAqCXNnZXQJLQlmaW5kIG9yIGNyZWF0ZSBhIHN1cGVyYmxvY2sKICoJQHR5cGU6CWZpbGVzeXN0ZW0gdHlwZSBzdXBlcmJsb2NrIHNob3VsZCBiZWxvbmcgdG8KICoJQHRlc3Q6CWNvbXBhcmlzb24gY2FsbGJhY2sKICoJQHNldDoJc2V0dXAgY2FsbGJhY2sKICoJQGRhdGE6CWFyZ3VtZW50IHRvIGVhY2ggb2YgdGhlbQogKi8Kc3RydWN0IHN1cGVyX2Jsb2NrICpzZ2V0KHN0cnVjdCBmaWxlX3N5c3RlbV90eXBlICp0eXBlLAoJCQlpbnQgKCp0ZXN0KShzdHJ1Y3Qgc3VwZXJfYmxvY2sgKix2b2lkICopLAoJCQlpbnQgKCpzZXQpKHN0cnVjdCBzdXBlcl9ibG9jayAqLHZvaWQgKiksCgkJCXZvaWQgKmRhdGEpCnsKCXN0cnVjdCBzdXBlcl9ibG9jayAqcyA9IE5VTEw7CglzdHJ1Y3QgbGlzdF9oZWFkICpwOwoJaW50IGVycjsKCnJldHJ5OgoJc3Bpbl9sb2NrKCZzYl9sb2NrKTsKCWlmICh0ZXN0KSBsaXN0X2Zvcl9lYWNoKHAsICZ0eXBlLT5mc19zdXBlcnMpIHsKCQlzdHJ1Y3Qgc3VwZXJfYmxvY2sgKm9sZDsKCQlvbGQgPSBsaXN0X2VudHJ5KHAsIHN0cnVjdCBzdXBlcl9ibG9jaywgc19pbnN0YW5jZXMpOwoJCWlmICghdGVzdChvbGQsIGRhdGEpKQoJCQljb250aW51ZTsKCQlpZiAoIWdyYWJfc3VwZXIob2xkKSkKCQkJZ290byByZXRyeTsKCQlpZiAocykKCQkJZGVzdHJveV9zdXBlcihzKTsKCQlyZXR1cm4gb2xkOwoJfQoJaWYgKCFzKSB7CgkJc3Bpbl91bmxvY2soJnNiX2xvY2spOwoJCXMgPSBhbGxvY19zdXBlcigpOwoJCWlmICghcykKCQkJcmV0dXJuIEVSUl9QVFIoLUVOT01FTSk7CgkJZ290byByZXRyeTsKCX0KCQkKCWVyciA9IHNldChzLCBkYXRhKTsKCWlmIChlcnIpIHsKCQlzcGluX3VubG9jaygmc2JfbG9jayk7CgkJZGVzdHJveV9zdXBlcihzKTsKCQlyZXR1cm4gRVJSX1BUUihlcnIpOwoJfQoJcy0+c190eXBlID0gdHlwZTsKCXN0cmxjcHkocy0+c19pZCwgdHlwZS0+bmFtZSwgc2l6ZW9mKHMtPnNfaWQpKTsKCWxpc3RfYWRkX3RhaWwoJnMtPnNfbGlzdCwgJnN1cGVyX2Jsb2Nrcyk7CglsaXN0X2FkZCgmcy0+c19pbnN0YW5jZXMsICZ0eXBlLT5mc19zdXBlcnMpOwoJc3Bpbl91bmxvY2soJnNiX2xvY2spOwoJZ2V0X2ZpbGVzeXN0ZW0odHlwZSk7CglyZXR1cm4gczsKfQoKRVhQT1JUX1NZTUJPTChzZ2V0KTsKCnZvaWQgZHJvcF9zdXBlcihzdHJ1Y3Qgc3VwZXJfYmxvY2sgKnNiKQp7Cgl1cF9yZWFkKCZzYi0+c191bW91bnQpOwoJcHV0X3N1cGVyKHNiKTsKfQoKRVhQT1JUX1NZTUJPTChkcm9wX3N1cGVyKTsKCnN0YXRpYyBpbmxpbmUgdm9pZCB3cml0ZV9zdXBlcihzdHJ1Y3Qgc3VwZXJfYmxvY2sgKnNiKQp7Cglsb2NrX3N1cGVyKHNiKTsKCWlmIChzYi0+c19yb290ICYmIHNiLT5zX2RpcnQpCgkJaWYgKHNiLT5zX29wLT53cml0ZV9zdXBlcikKCQkJc2ItPnNfb3AtPndyaXRlX3N1cGVyKHNiKTsKCXVubG9ja19zdXBlcihzYik7Cn0KCi8qCiAqIE5vdGU6IGNoZWNrIHRoZSBkaXJ0eSBmbGFnIGJlZm9yZSB3YWl0aW5nLCBzbyB3ZSBkb24ndAogKiBob2xkIHVwIHRoZSBzeW5jIHdoaWxlIG1vdW50aW5nIGEgZGV2aWNlLiAoVGhlIG5ld2x5CiAqIG1vdW50ZWQgZGV2aWNlIHdvbid0IG5lZWQgc3luY2luZy4pCiAqLwp2b2lkIHN5bmNfc3VwZXJzKHZvaWQpCnsKCXN0cnVjdCBzdXBlcl9ibG9jayAqc2I7CgoJc3Bpbl9sb2NrKCZzYl9sb2NrKTsKcmVzdGFydDoKCWxpc3RfZm9yX2VhY2hfZW50cnkoc2IsICZzdXBlcl9ibG9ja3MsIHNfbGlzdCkgewoJCWlmIChzYi0+c19kaXJ0KSB7CgkJCXNiLT5zX2NvdW50Kys7CgkJCXNwaW5fdW5sb2NrKCZzYl9sb2NrKTsKCQkJZG93bl9yZWFkKCZzYi0+c191bW91bnQpOwoJCQl3cml0ZV9zdXBlcihzYik7CgkJCXVwX3JlYWQoJnNiLT5zX3Vtb3VudCk7CgkJCXNwaW5fbG9jaygmc2JfbG9jayk7CgkJCWlmIChfX3B1dF9zdXBlcl9hbmRfbmVlZF9yZXN0YXJ0KHNiKSkKCQkJCWdvdG8gcmVzdGFydDsKCQl9Cgl9CglzcGluX3VubG9jaygmc2JfbG9jayk7Cn0KCi8qCiAqIENhbGwgdGhlIC0+c3luY19mcyBzdXBlcl9vcCBhZ2FpbnN0IGFsbCBmaWxlc3l0ZW1zIHdoaWNoIGFyZSByL3cgYW5kCiAqIHdoaWNoIGltcGxlbWVudCBpdC4KICoKICogVGhpcyBvcGVyYXRpb24gaXMgY2FyZWZ1bCB0byBhdm9pZCB0aGUgbGl2ZWxvY2sgd2hpY2ggY291bGQgZWFzaWx5IGhhcHBlbgogKiBpZiB0d28gb3IgbW9yZSBmaWxlc3lzdGVtcyBhcmUgYmVpbmcgY29udGludW91c2x5IGRpcnRpZWQuICBzX25lZWRfc3luY19mcwogKiBpcyB1c2VkIG9ubHkgaGVyZS4gIFdlIHNldCBpdCBhZ2FpbnN0IGFsbCBmaWxlc3lzdGVtcyBhbmQgdGhlbiBjbGVhciBpdCBhcwogKiB3ZSBzeW5jIHRoZW0uICBTbyByZWRpcnRpZWQgZmlsZXN5c3RlbXMgYXJlIHNraXBwZWQuCiAqCiAqIEJ1dCBpZiBwcm9jZXNzIEEgaXMgY3VycmVudGx5IHJ1bm5pbmcgc3luY19maWxlc3l0ZW1zIGFuZCB0aGVuIHByb2Nlc3MgQgogKiBjYWxscyBzeW5jX2ZpbGVzeXN0ZW1zIGFzIHdlbGwsIHByb2Nlc3MgQiB3aWxsIHNldCBhbGwgdGhlIHNfbmVlZF9zeW5jX2ZzCiAqIGZsYWdzIGFnYWluLCB3aGljaCB3aWxsIGNhdXNlIHByb2Nlc3MgQSB0byByZXN5bmMgZXZlcnl0aGluZy4gIEZpeCB0aGF0IHdpdGgKICogYSBsb2NhbCBtdXRleC4KICoKICogKEZhYmlhbikgQXZvaWQgc3luY19mcyB3aXRoIGNsZWFuIGZzICYgd2FpdCBtb2RlIDAKICovCnZvaWQgc3luY19maWxlc3lzdGVtcyhpbnQgd2FpdCkKewoJc3RydWN0IHN1cGVyX2Jsb2NrICpzYjsKCXN0YXRpYyBERUZJTkVfTVVURVgobXV0ZXgpOwoKCW11dGV4X2xvY2soJm11dGV4KTsJCS8qIENvdWxkIGJlIGRvd25faW50ZXJydXB0aWJsZSAqLwoJc3Bpbl9sb2NrKCZzYl9sb2NrKTsKCWxpc3RfZm9yX2VhY2hfZW50cnkoc2IsICZzdXBlcl9ibG9ja3MsIHNfbGlzdCkgewoJCWlmICghc2ItPnNfb3AtPnN5bmNfZnMpCgkJCWNvbnRpbnVlOwoJCWlmIChzYi0+c19mbGFncyAmIE1TX1JET05MWSkKCQkJY29udGludWU7CgkJc2ItPnNfbmVlZF9zeW5jX2ZzID0gMTsKCX0KCnJlc3RhcnQ6CglsaXN0X2Zvcl9lYWNoX2VudHJ5KHNiLCAmc3VwZXJfYmxvY2tzLCBzX2xpc3QpIHsKCQlpZiAoIXNiLT5zX25lZWRfc3luY19mcykKCQkJY29udGludWU7CgkJc2ItPnNfbmVlZF9zeW5jX2ZzID0gMDsKCQlpZiAoc2ItPnNfZmxhZ3MgJiBNU19SRE9OTFkpCgkJCWNvbnRpbnVlOwkvKiBobS4gIFdhcyByZW1vdW50ZWQgci9vIG1lYW53aGlsZSAqLwoJCXNiLT5zX2NvdW50Kys7CgkJc3Bpbl91bmxvY2soJnNiX2xvY2spOwoJCWRvd25fcmVhZCgmc2ItPnNfdW1vdW50KTsKCQlpZiAoc2ItPnNfcm9vdCAmJiAod2FpdCB8fCBzYi0+c19kaXJ0KSkKCQkJc2ItPnNfb3AtPnN5bmNfZnMoc2IsIHdhaXQpOwoJCXVwX3JlYWQoJnNiLT5zX3Vtb3VudCk7CgkJLyogcmVzdGFydCBvbmx5IHdoZW4gc2IgaXMgbm8gbG9uZ2VyIG9uIHRoZSBsaXN0ICovCgkJc3Bpbl9sb2NrKCZzYl9sb2NrKTsKCQlpZiAoX19wdXRfc3VwZXJfYW5kX25lZWRfcmVzdGFydChzYikpCgkJCWdvdG8gcmVzdGFydDsKCX0KCXNwaW5fdW5sb2NrKCZzYl9sb2NrKTsKCW11dGV4X3VubG9jaygmbXV0ZXgpOwp9CgovKioKICoJZ2V0X3N1cGVyIC0gZ2V0IHRoZSBzdXBlcmJsb2NrIG9mIGEgZGV2aWNlCiAqCUBiZGV2OiBkZXZpY2UgdG8gZ2V0IHRoZSBzdXBlcmJsb2NrIGZvcgogKgkKICoJU2NhbnMgdGhlIHN1cGVyYmxvY2sgbGlzdCBhbmQgZmluZHMgdGhlIHN1cGVyYmxvY2sgb2YgdGhlIGZpbGUgc3lzdGVtCiAqCW1vdW50ZWQgb24gdGhlIGRldmljZSBnaXZlbi4gJU5VTEwgaXMgcmV0dXJuZWQgaWYgbm8gbWF0Y2ggaXMgZm91bmQuCiAqLwoKc3RydWN0IHN1cGVyX2Jsb2NrICogZ2V0X3N1cGVyKHN0cnVjdCBibG9ja19kZXZpY2UgKmJkZXYpCnsKCXN0cnVjdCBzdXBlcl9ibG9jayAqc2I7CgoJaWYgKCFiZGV2KQoJCXJldHVybiBOVUxMOwoKCXNwaW5fbG9jaygmc2JfbG9jayk7CnJlc2NhbjoKCWxpc3RfZm9yX2VhY2hfZW50cnkoc2IsICZzdXBlcl9ibG9ja3MsIHNfbGlzdCkgewoJCWlmIChzYi0+c19iZGV2ID09IGJkZXYpIHsKCQkJc2ItPnNfY291bnQrKzsKCQkJc3Bpbl91bmxvY2soJnNiX2xvY2spOwoJCQlkb3duX3JlYWQoJnNiLT5zX3Vtb3VudCk7CgkJCWlmIChzYi0+c19yb290KQoJCQkJcmV0dXJuIHNiOwoJCQl1cF9yZWFkKCZzYi0+c191bW91bnQpOwoJCQkvKiByZXN0YXJ0IG9ubHkgd2hlbiBzYiBpcyBubyBsb25nZXIgb24gdGhlIGxpc3QgKi8KCQkJc3Bpbl9sb2NrKCZzYl9sb2NrKTsKCQkJaWYgKF9fcHV0X3N1cGVyX2FuZF9uZWVkX3Jlc3RhcnQoc2IpKQoJCQkJZ290byByZXNjYW47CgkJfQoJfQoJc3Bpbl91bmxvY2soJnNiX2xvY2spOwoJcmV0dXJuIE5VTEw7Cn0KCkVYUE9SVF9TWU1CT0woZ2V0X3N1cGVyKTsKIApzdHJ1Y3Qgc3VwZXJfYmxvY2sgKiB1c2VyX2dldF9zdXBlcihkZXZfdCBkZXYpCnsKCXN0cnVjdCBzdXBlcl9ibG9jayAqc2I7CgoJc3Bpbl9sb2NrKCZzYl9sb2NrKTsKcmVzY2FuOgoJbGlzdF9mb3JfZWFjaF9lbnRyeShzYiwgJnN1cGVyX2Jsb2Nrcywgc19saXN0KSB7CgkJaWYgKHNiLT5zX2RldiA9PSAgZGV2KSB7CgkJCXNiLT5zX2NvdW50Kys7CgkJCXNwaW5fdW5sb2NrKCZzYl9sb2NrKTsKCQkJZG93bl9yZWFkKCZzYi0+c191bW91bnQpOwoJCQlpZiAoc2ItPnNfcm9vdCkKCQkJCXJldHVybiBzYjsKCQkJdXBfcmVhZCgmc2ItPnNfdW1vdW50KTsKCQkJLyogcmVzdGFydCBvbmx5IHdoZW4gc2IgaXMgbm8gbG9uZ2VyIG9uIHRoZSBsaXN0ICovCgkJCXNwaW5fbG9jaygmc2JfbG9jayk7CgkJCWlmIChfX3B1dF9zdXBlcl9hbmRfbmVlZF9yZXN0YXJ0KHNiKSkKCQkJCWdvdG8gcmVzY2FuOwoJCX0KCX0KCXNwaW5fdW5sb2NrKCZzYl9sb2NrKTsKCXJldHVybiBOVUxMOwp9Cgphc21saW5rYWdlIGxvbmcgc3lzX3VzdGF0KHVuc2lnbmVkIGRldiwgc3RydWN0IHVzdGF0IF9fdXNlciAqIHVidWYpCnsKICAgICAgICBzdHJ1Y3Qgc3VwZXJfYmxvY2sgKnM7CiAgICAgICAgc3RydWN0IHVzdGF0IHRtcDsKICAgICAgICBzdHJ1Y3Qga3N0YXRmcyBzYnVmOwoJaW50IGVyciA9IC1FSU5WQUw7CgogICAgICAgIHMgPSB1c2VyX2dldF9zdXBlcihuZXdfZGVjb2RlX2RldihkZXYpKTsKICAgICAgICBpZiAocyA9PSBOVUxMKQogICAgICAgICAgICAgICAgZ290byBvdXQ7CgllcnIgPSB2ZnNfc3RhdGZzKHMtPnNfcm9vdCwgJnNidWYpOwoJZHJvcF9zdXBlcihzKTsKCWlmIChlcnIpCgkJZ290byBvdXQ7CgogICAgICAgIG1lbXNldCgmdG1wLDAsc2l6ZW9mKHN0cnVjdCB1c3RhdCkpOwogICAgICAgIHRtcC5mX3RmcmVlID0gc2J1Zi5mX2JmcmVlOwogICAgICAgIHRtcC5mX3Rpbm9kZSA9IHNidWYuZl9mZnJlZTsKCiAgICAgICAgZXJyID0gY29weV90b191c2VyKHVidWYsJnRtcCxzaXplb2Yoc3RydWN0IHVzdGF0KSkgPyAtRUZBVUxUIDogMDsKb3V0OgoJcmV0dXJuIGVycjsKfQoKLyoqCiAqCW1hcmtfZmlsZXNfcm8KICoJQHNiOiBzdXBlcmJsb2NrIGluIHF1ZXN0aW9uCiAqCiAqCUFsbCBmaWxlcyBhcmUgbWFya2VkIHJlYWQvb25seS4gIFdlIGRvbid0IGNhcmUgYWJvdXQgcGVuZGluZwogKglkZWxldGUgZmlsZXMgc28gdGhpcyBzaG91bGQgYmUgdXNlZCBpbiAnZm9yY2UnIG1vZGUgb25seQogKi8KCnN0YXRpYyB2b2lkIG1hcmtfZmlsZXNfcm8oc3RydWN0IHN1cGVyX2Jsb2NrICpzYikKewoJc3RydWN0IGZpbGUgKmY7CgoJZmlsZV9saXN0X2xvY2soKTsKCWxpc3RfZm9yX2VhY2hfZW50cnkoZiwgJnNiLT5zX2ZpbGVzLCBmX3UuZnVfbGlzdCkgewoJCWlmIChTX0lTUkVHKGYtPmZfZGVudHJ5LT5kX2lub2RlLT5pX21vZGUpICYmIGZpbGVfY291bnQoZikpCgkJCWYtPmZfbW9kZSAmPSB+Rk1PREVfV1JJVEU7Cgl9CglmaWxlX2xpc3RfdW5sb2NrKCk7Cn0KCi8qKgogKglkb19yZW1vdW50X3NiIC0gYXNrcyBmaWxlc3lzdGVtIHRvIGNoYW5nZSBtb3VudCBvcHRpb25zLgogKglAc2I6CXN1cGVyYmxvY2sgaW4gcXVlc3Rpb24KICoJQGZsYWdzOgludW1lcmljIHBhcnQgb2Ygb3B0aW9ucwogKglAZGF0YToJdGhlIHJlc3Qgb2Ygb3B0aW9ucwogKiAgICAgIEBmb3JjZTogd2hldGhlciBvciBub3QgdG8gZm9yY2UgdGhlIGNoYW5nZQogKgogKglBbHRlcnMgdGhlIG1vdW50IG9wdGlvbnMgb2YgYSBtb3VudGVkIGZpbGUgc3lzdGVtLgogKi8KaW50IGRvX3JlbW91bnRfc2Ioc3RydWN0IHN1cGVyX2Jsb2NrICpzYiwgaW50IGZsYWdzLCB2b2lkICpkYXRhLCBpbnQgZm9yY2UpCnsKCWludCByZXR2YWw7CgkKCWlmICghKGZsYWdzICYgTVNfUkRPTkxZKSAmJiBiZGV2X3JlYWRfb25seShzYi0+c19iZGV2KSkKCQlyZXR1cm4gLUVBQ0NFUzsKCWlmIChmbGFncyAmIE1TX1JET05MWSkKCQlhY2N0X2F1dG9fY2xvc2Uoc2IpOwoJc2hyaW5rX2RjYWNoZV9zYihzYik7Cglmc3luY19zdXBlcihzYik7CgoJLyogSWYgd2UgYXJlIHJlbW91bnRpbmcgUkRPTkxZIGFuZCBjdXJyZW50IHNiIGlzIHJlYWQvd3JpdGUsCgkgICBtYWtlIHN1cmUgdGhlcmUgYXJlIG5vIHJ3IGZpbGVzIG9wZW5lZCAqLwoJaWYgKChmbGFncyAmIE1TX1JET05MWSkgJiYgIShzYi0+c19mbGFncyAmIE1TX1JET05MWSkpIHsKCQlpZiAoZm9yY2UpCgkJCW1hcmtfZmlsZXNfcm8oc2IpOwoJCWVsc2UgaWYgKCFmc19tYXlfcmVtb3VudF9ybyhzYikpCgkJCXJldHVybiAtRUJVU1k7Cgl9CgoJaWYgKHNiLT5zX29wLT5yZW1vdW50X2ZzKSB7CgkJbG9ja19zdXBlcihzYik7CgkJcmV0dmFsID0gc2ItPnNfb3AtPnJlbW91bnRfZnMoc2IsICZmbGFncywgZGF0YSk7CgkJdW5sb2NrX3N1cGVyKHNiKTsKCQlpZiAocmV0dmFsKQoJCQlyZXR1cm4gcmV0dmFsOwoJfQoJc2ItPnNfZmxhZ3MgPSAoc2ItPnNfZmxhZ3MgJiB+TVNfUk1UX01BU0spIHwgKGZsYWdzICYgTVNfUk1UX01BU0spOwoJcmV0dXJuIDA7Cn0KCnN0YXRpYyB2b2lkIGRvX2VtZXJnZW5jeV9yZW1vdW50KHVuc2lnbmVkIGxvbmcgZm9vKQp7CglzdHJ1Y3Qgc3VwZXJfYmxvY2sgKnNiOwoKCXNwaW5fbG9jaygmc2JfbG9jayk7CglsaXN0X2Zvcl9lYWNoX2VudHJ5KHNiLCAmc3VwZXJfYmxvY2tzLCBzX2xpc3QpIHsKCQlzYi0+c19jb3VudCsrOwoJCXNwaW5fdW5sb2NrKCZzYl9sb2NrKTsKCQlkb3duX3JlYWQoJnNiLT5zX3Vtb3VudCk7CgkJaWYgKHNiLT5zX3Jvb3QgJiYgc2ItPnNfYmRldiAmJiAhKHNiLT5zX2ZsYWdzICYgTVNfUkRPTkxZKSkgewoJCQkvKgoJCQkgKiAtPnJlbW91bnRfZnMgbmVlZHMgbG9ja19rZXJuZWwoKS4KCQkJICoKCQkJICogV2hhdCBsb2NrIHByb3RlY3RzIHNiLT5zX2ZsYWdzPz8KCQkJICovCgkJCWxvY2tfa2VybmVsKCk7CgkJCWRvX3JlbW91bnRfc2Ioc2IsIE1TX1JET05MWSwgTlVMTCwgMSk7CgkJCXVubG9ja19rZXJuZWwoKTsKCQl9CgkJZHJvcF9zdXBlcihzYik7CgkJc3Bpbl9sb2NrKCZzYl9sb2NrKTsKCX0KCXNwaW5fdW5sb2NrKCZzYl9sb2NrKTsKCXByaW50aygiRW1lcmdlbmN5IFJlbW91bnQgY29tcGxldGVcbiIpOwp9Cgp2b2lkIGVtZXJnZW5jeV9yZW1vdW50KHZvaWQpCnsKCXBkZmx1c2hfb3BlcmF0aW9uKGRvX2VtZXJnZW5jeV9yZW1vdW50LCAwKTsKfQoKLyoKICogVW5uYW1lZCBibG9jayBkZXZpY2VzIGFyZSBkdW1teSBkZXZpY2VzIHVzZWQgYnkgdmlydHVhbAogKiBmaWxlc3lzdGVtcyB3aGljaCBkb24ndCB1c2UgcmVhbCBibG9jay1kZXZpY2VzLiAgLS0ganJzCiAqLwoKc3RhdGljIHN0cnVjdCBpZHIgdW5uYW1lZF9kZXZfaWRyOwpzdGF0aWMgREVGSU5FX1NQSU5MT0NLKHVubmFtZWRfZGV2X2xvY2spOy8qIHByb3RlY3RzIHRoZSBhYm92ZSAqLwoKaW50IHNldF9hbm9uX3N1cGVyKHN0cnVjdCBzdXBlcl9ibG9jayAqcywgdm9pZCAqZGF0YSkKewoJaW50IGRldjsKCWludCBlcnJvcjsKCiByZXRyeToKCWlmIChpZHJfcHJlX2dldCgmdW5uYW1lZF9kZXZfaWRyLCBHRlBfQVRPTUlDKSA9PSAwKQoJCXJldHVybiAtRU5PTUVNOwoJc3Bpbl9sb2NrKCZ1bm5hbWVkX2Rldl9sb2NrKTsKCWVycm9yID0gaWRyX2dldF9uZXcoJnVubmFtZWRfZGV2X2lkciwgTlVMTCwgJmRldik7CglzcGluX3VubG9jaygmdW5uYW1lZF9kZXZfbG9jayk7CglpZiAoZXJyb3IgPT0gLUVBR0FJTikKCQkvKiBXZSByYWNlZCBhbmQgbG9zdCB3aXRoIGFub3RoZXIgQ1BVLiAqLwoJCWdvdG8gcmV0cnk7CgllbHNlIGlmIChlcnJvcikKCQlyZXR1cm4gLUVBR0FJTjsKCglpZiAoKGRldiAmIE1BWF9JRF9NQVNLKSA9PSAoMSA8PCBNSU5PUkJJVFMpKSB7CgkJc3Bpbl9sb2NrKCZ1bm5hbWVkX2Rldl9sb2NrKTsKCQlpZHJfcmVtb3ZlKCZ1bm5hbWVkX2Rldl9pZHIsIGRldik7CgkJc3Bpbl91bmxvY2soJnVubmFtZWRfZGV2X2xvY2spOwoJCXJldHVybiAtRU1GSUxFOwoJfQoJcy0+c19kZXYgPSBNS0RFVigwLCBkZXYgJiBNSU5PUk1BU0spOwoJcmV0dXJuIDA7Cn0KCkVYUE9SVF9TWU1CT0woc2V0X2Fub25fc3VwZXIpOwoKdm9pZCBraWxsX2Fub25fc3VwZXIoc3RydWN0IHN1cGVyX2Jsb2NrICpzYikKewoJaW50IHNsb3QgPSBNSU5PUihzYi0+c19kZXYpOwoKCWdlbmVyaWNfc2h1dGRvd25fc3VwZXIoc2IpOwoJc3Bpbl9sb2NrKCZ1bm5hbWVkX2Rldl9sb2NrKTsKCWlkcl9yZW1vdmUoJnVubmFtZWRfZGV2X2lkciwgc2xvdCk7CglzcGluX3VubG9jaygmdW5uYW1lZF9kZXZfbG9jayk7Cn0KCkVYUE9SVF9TWU1CT0woa2lsbF9hbm9uX3N1cGVyKTsKCnZvaWQgX19pbml0IHVubmFtZWRfZGV2X2luaXQodm9pZCkKewoJaWRyX2luaXQoJnVubmFtZWRfZGV2X2lkcik7Cn0KCnZvaWQga2lsbF9saXR0ZXJfc3VwZXIoc3RydWN0IHN1cGVyX2Jsb2NrICpzYikKewoJaWYgKHNiLT5zX3Jvb3QpCgkJZF9nZW5vY2lkZShzYi0+c19yb290KTsKCWtpbGxfYW5vbl9zdXBlcihzYik7Cn0KCkVYUE9SVF9TWU1CT0woa2lsbF9saXR0ZXJfc3VwZXIpOwoKc3RhdGljIGludCBzZXRfYmRldl9zdXBlcihzdHJ1Y3Qgc3VwZXJfYmxvY2sgKnMsIHZvaWQgKmRhdGEpCnsKCXMtPnNfYmRldiA9IGRhdGE7CglzLT5zX2RldiA9IHMtPnNfYmRldi0+YmRfZGV2OwoJcmV0dXJuIDA7Cn0KCnN0YXRpYyBpbnQgdGVzdF9iZGV2X3N1cGVyKHN0cnVjdCBzdXBlcl9ibG9jayAqcywgdm9pZCAqZGF0YSkKewoJcmV0dXJuICh2b2lkICopcy0+c19iZGV2ID09IGRhdGE7Cn0KCnN0YXRpYyB2b2lkIGJkZXZfdWV2ZW50KHN0cnVjdCBibG9ja19kZXZpY2UgKmJkZXYsIGVudW0ga29iamVjdF9hY3Rpb24gYWN0aW9uKQp7CglpZiAoYmRldi0+YmRfZGlzaykgewoJCWlmIChiZGV2LT5iZF9wYXJ0KQoJCQlrb2JqZWN0X3VldmVudCgmYmRldi0+YmRfcGFydC0+a29iaiwgYWN0aW9uKTsKCQllbHNlCgkJCWtvYmplY3RfdWV2ZW50KCZiZGV2LT5iZF9kaXNrLT5rb2JqLCBhY3Rpb24pOwoJfQp9CgppbnQgZ2V0X3NiX2JkZXYoc3RydWN0IGZpbGVfc3lzdGVtX3R5cGUgKmZzX3R5cGUsCglpbnQgZmxhZ3MsIGNvbnN0IGNoYXIgKmRldl9uYW1lLCB2b2lkICpkYXRhLAoJaW50ICgqZmlsbF9zdXBlcikoc3RydWN0IHN1cGVyX2Jsb2NrICosIHZvaWQgKiwgaW50KSwKCXN0cnVjdCB2ZnNtb3VudCAqbW50KQp7CglzdHJ1Y3QgYmxvY2tfZGV2aWNlICpiZGV2OwoJc3RydWN0IHN1cGVyX2Jsb2NrICpzOwoJaW50IGVycm9yID0gMDsKCgliZGV2ID0gb3Blbl9iZGV2X2V4Y2woZGV2X25hbWUsIGZsYWdzLCBmc190eXBlKTsKCWlmIChJU19FUlIoYmRldikpCgkJcmV0dXJuIFBUUl9FUlIoYmRldik7CgoJLyoKCSAqIG9uY2UgdGhlIHN1cGVyIGlzIGluc2VydGVkIGludG8gdGhlIGxpc3QgYnkgc2dldCwgc191bW91bnQKCSAqIHdpbGwgcHJvdGVjdCB0aGUgbG9ja2ZzIGNvZGUgZnJvbSB0cnlpbmcgdG8gc3RhcnQgYSBzbmFwc2hvdAoJICogd2hpbGUgd2UgYXJlIG1vdW50aW5nCgkgKi8KCW11dGV4X2xvY2soJmJkZXYtPmJkX21vdW50X211dGV4KTsKCXMgPSBzZ2V0KGZzX3R5cGUsIHRlc3RfYmRldl9zdXBlciwgc2V0X2JkZXZfc3VwZXIsIGJkZXYpOwoJbXV0ZXhfdW5sb2NrKCZiZGV2LT5iZF9tb3VudF9tdXRleCk7CglpZiAoSVNfRVJSKHMpKQoJCWdvdG8gZXJyb3JfczsKCglpZiAocy0+c19yb290KSB7CgkJaWYgKChmbGFncyBeIHMtPnNfZmxhZ3MpICYgTVNfUkRPTkxZKSB7CgkJCXVwX3dyaXRlKCZzLT5zX3Vtb3VudCk7CgkJCWRlYWN0aXZhdGVfc3VwZXIocyk7CgkJCWVycm9yID0gLUVCVVNZOwoJCQlnb3RvIGVycm9yX2JkZXY7CgkJfQoKCQljbG9zZV9iZGV2X2V4Y2woYmRldik7Cgl9IGVsc2UgewoJCWNoYXIgYltCREVWTkFNRV9TSVpFXTsKCgkJcy0+c19mbGFncyA9IGZsYWdzOwoJCXN0cmxjcHkocy0+c19pZCwgYmRldm5hbWUoYmRldiwgYiksIHNpemVvZihzLT5zX2lkKSk7CgkJc2Jfc2V0X2Jsb2Nrc2l6ZShzLCBibG9ja19zaXplKGJkZXYpKTsKCQllcnJvciA9IGZpbGxfc3VwZXIocywgZGF0YSwgZmxhZ3MgJiBNU19TSUxFTlQgPyAxIDogMCk7CgkJaWYgKGVycm9yKSB7CgkJCXVwX3dyaXRlKCZzLT5zX3Vtb3VudCk7CgkJCWRlYWN0aXZhdGVfc3VwZXIocyk7CgkJCWdvdG8gZXJyb3I7CgkJfQoKCQlzLT5zX2ZsYWdzIHw9IE1TX0FDVElWRTsKCQliZGV2X3VldmVudChiZGV2LCBLT0JKX01PVU5UKTsKCX0KCglyZXR1cm4gc2ltcGxlX3NldF9tbnQobW50LCBzKTsKCmVycm9yX3M6CgllcnJvciA9IFBUUl9FUlIocyk7CmVycm9yX2JkZXY6CgljbG9zZV9iZGV2X2V4Y2woYmRldik7CmVycm9yOgoJcmV0dXJuIGVycm9yOwp9CgpFWFBPUlRfU1lNQk9MKGdldF9zYl9iZGV2KTsKCnZvaWQga2lsbF9ibG9ja19zdXBlcihzdHJ1Y3Qgc3VwZXJfYmxvY2sgKnNiKQp7CglzdHJ1Y3QgYmxvY2tfZGV2aWNlICpiZGV2ID0gc2ItPnNfYmRldjsKCgliZGV2X3VldmVudChiZGV2LCBLT0JKX1VNT1VOVCk7CglnZW5lcmljX3NodXRkb3duX3N1cGVyKHNiKTsKCXN5bmNfYmxvY2tkZXYoYmRldik7CgljbG9zZV9iZGV2X2V4Y2woYmRldik7Cn0KCkVYUE9SVF9TWU1CT0woa2lsbF9ibG9ja19zdXBlcik7CgppbnQgZ2V0X3NiX25vZGV2KHN0cnVjdCBmaWxlX3N5c3RlbV90eXBlICpmc190eXBlLAoJaW50IGZsYWdzLCB2b2lkICpkYXRhLAoJaW50ICgqZmlsbF9zdXBlcikoc3RydWN0IHN1cGVyX2Jsb2NrICosIHZvaWQgKiwgaW50KSwKCXN0cnVjdCB2ZnNtb3VudCAqbW50KQp7CglpbnQgZXJyb3I7CglzdHJ1Y3Qgc3VwZXJfYmxvY2sgKnMgPSBzZ2V0KGZzX3R5cGUsIE5VTEwsIHNldF9hbm9uX3N1cGVyLCBOVUxMKTsKCglpZiAoSVNfRVJSKHMpKQoJCXJldHVybiBQVFJfRVJSKHMpOwoKCXMtPnNfZmxhZ3MgPSBmbGFnczsKCgllcnJvciA9IGZpbGxfc3VwZXIocywgZGF0YSwgZmxhZ3MgJiBNU19TSUxFTlQgPyAxIDogMCk7CglpZiAoZXJyb3IpIHsKCQl1cF93cml0ZSgmcy0+c191bW91bnQpOwoJCWRlYWN0aXZhdGVfc3VwZXIocyk7CgkJcmV0dXJuIGVycm9yOwoJfQoJcy0+c19mbGFncyB8PSBNU19BQ1RJVkU7CglyZXR1cm4gc2ltcGxlX3NldF9tbnQobW50LCBzKTsKfQoKRVhQT1JUX1NZTUJPTChnZXRfc2Jfbm9kZXYpOwoKc3RhdGljIGludCBjb21wYXJlX3NpbmdsZShzdHJ1Y3Qgc3VwZXJfYmxvY2sgKnMsIHZvaWQgKnApCnsKCXJldHVybiAxOwp9CgppbnQgZ2V0X3NiX3NpbmdsZShzdHJ1Y3QgZmlsZV9zeXN0ZW1fdHlwZSAqZnNfdHlwZSwKCWludCBmbGFncywgdm9pZCAqZGF0YSwKCWludCAoKmZpbGxfc3VwZXIpKHN0cnVjdCBzdXBlcl9ibG9jayAqLCB2b2lkICosIGludCksCglzdHJ1Y3QgdmZzbW91bnQgKm1udCkKewoJc3RydWN0IHN1cGVyX2Jsb2NrICpzOwoJaW50IGVycm9yOwoKCXMgPSBzZ2V0KGZzX3R5cGUsIGNvbXBhcmVfc2luZ2xlLCBzZXRfYW5vbl9zdXBlciwgTlVMTCk7CglpZiAoSVNfRVJSKHMpKQoJCXJldHVybiBQVFJfRVJSKHMpOwoJaWYgKCFzLT5zX3Jvb3QpIHsKCQlzLT5zX2ZsYWdzID0gZmxhZ3M7CgkJZXJyb3IgPSBmaWxsX3N1cGVyKHMsIGRhdGEsIGZsYWdzICYgTVNfU0lMRU5UID8gMSA6IDApOwoJCWlmIChlcnJvcikgewoJCQl1cF93cml0ZSgmcy0+c191bW91bnQpOwoJCQlkZWFjdGl2YXRlX3N1cGVyKHMpOwoJCQlyZXR1cm4gZXJyb3I7CgkJfQoJCXMtPnNfZmxhZ3MgfD0gTVNfQUNUSVZFOwoJfQoJZG9fcmVtb3VudF9zYihzLCBmbGFncywgZGF0YSwgMCk7CglyZXR1cm4gc2ltcGxlX3NldF9tbnQobW50LCBzKTsKfQoKRVhQT1JUX1NZTUJPTChnZXRfc2Jfc2luZ2xlKTsKCnN0cnVjdCB2ZnNtb3VudCAqCnZmc19rZXJuX21vdW50KHN0cnVjdCBmaWxlX3N5c3RlbV90eXBlICp0eXBlLCBpbnQgZmxhZ3MsIGNvbnN0IGNoYXIgKm5hbWUsIHZvaWQgKmRhdGEpCnsKCXN0cnVjdCB2ZnNtb3VudCAqbW50OwoJY2hhciAqc2VjZGF0YSA9IE5VTEw7CglpbnQgZXJyb3I7CgoJaWYgKCF0eXBlKQoJCXJldHVybiBFUlJfUFRSKC1FTk9ERVYpOwoKCWVycm9yID0gLUVOT01FTTsKCW1udCA9IGFsbG9jX3Zmc21udChuYW1lKTsKCWlmICghbW50KQoJCWdvdG8gb3V0OwoKCWlmIChkYXRhKSB7CgkJc2VjZGF0YSA9IGFsbG9jX3NlY2RhdGEoKTsKCQlpZiAoIXNlY2RhdGEpCgkJCWdvdG8gb3V0X21udDsKCgkJZXJyb3IgPSBzZWN1cml0eV9zYl9jb3B5X2RhdGEodHlwZSwgZGF0YSwgc2VjZGF0YSk7CgkJaWYgKGVycm9yKQoJCQlnb3RvIG91dF9mcmVlX3NlY2RhdGE7Cgl9CgoJZXJyb3IgPSB0eXBlLT5nZXRfc2IodHlwZSwgZmxhZ3MsIG5hbWUsIGRhdGEsIG1udCk7CglpZiAoZXJyb3IgPCAwKQoJCWdvdG8gb3V0X2ZyZWVfc2VjZGF0YTsKCiAJZXJyb3IgPSBzZWN1cml0eV9zYl9rZXJuX21vdW50KG1udC0+bW50X3NiLCBzZWNkYXRhKTsKIAlpZiAoZXJyb3IpCiAJCWdvdG8gb3V0X3NiOwoKCW1udC0+bW50X21vdW50cG9pbnQgPSBtbnQtPm1udF9yb290OwoJbW50LT5tbnRfcGFyZW50ID0gbW50OwoJdXBfd3JpdGUoJm1udC0+bW50X3NiLT5zX3Vtb3VudCk7CglmcmVlX3NlY2RhdGEoc2VjZGF0YSk7CglyZXR1cm4gbW50OwpvdXRfc2I6CglkcHV0KG1udC0+bW50X3Jvb3QpOwoJdXBfd3JpdGUoJm1udC0+bW50X3NiLT5zX3Vtb3VudCk7CglkZWFjdGl2YXRlX3N1cGVyKG1udC0+bW50X3NiKTsKb3V0X2ZyZWVfc2VjZGF0YToKCWZyZWVfc2VjZGF0YShzZWNkYXRhKTsKb3V0X21udDoKCWZyZWVfdmZzbW50KG1udCk7Cm91dDoKCXJldHVybiBFUlJfUFRSKGVycm9yKTsKfQoKRVhQT1JUX1NZTUJPTF9HUEwodmZzX2tlcm5fbW91bnQpOwoKc3RydWN0IHZmc21vdW50ICoKZG9fa2Vybl9tb3VudChjb25zdCBjaGFyICpmc3R5cGUsIGludCBmbGFncywgY29uc3QgY2hhciAqbmFtZSwgdm9pZCAqZGF0YSkKewoJc3RydWN0IGZpbGVfc3lzdGVtX3R5cGUgKnR5cGUgPSBnZXRfZnNfdHlwZShmc3R5cGUpOwoJc3RydWN0IHZmc21vdW50ICptbnQ7CglpZiAoIXR5cGUpCgkJcmV0dXJuIEVSUl9QVFIoLUVOT0RFVik7CgltbnQgPSB2ZnNfa2Vybl9tb3VudCh0eXBlLCBmbGFncywgbmFtZSwgZGF0YSk7CglwdXRfZmlsZXN5c3RlbSh0eXBlKTsKCXJldHVybiBtbnQ7Cn0KCkVYUE9SVF9TWU1CT0xfR1BMKGRvX2tlcm5fbW91bnQpOwoKc3RydWN0IHZmc21vdW50ICprZXJuX21vdW50KHN0cnVjdCBmaWxlX3N5c3RlbV90eXBlICp0eXBlKQp7CglyZXR1cm4gdmZzX2tlcm5fbW91bnQodHlwZSwgMCwgdHlwZS0+bmFtZSwgTlVMTCk7Cn0KCkVYUE9SVF9TWU1CT0woa2Vybl9tb3VudCk7Cg==