LyoKICogQWdlcmUgU3lzdGVtcyBJbmMuCiAqIDEwLzEwMC8xMDAwIEJhc2UtVCBFdGhlcm5ldCBEcml2ZXIgZm9yIHRoZSBFVDEzMDEgYW5kIEVUMTMxeCBzZXJpZXMgTUFDcwogKgogKiBDb3B5cmlnaHQgqSAyMDA1IEFnZXJlIFN5c3RlbXMgSW5jLgogKiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiAgIGh0dHA6Ly93d3cuYWdlcmUuY29tCiAqCiAqLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAqCiAqIGV0MTMxMF90eC5jIC0gUm91dGluZXMgdXNlZCB0byBwZXJmb3JtIGRhdGEgdHJhbnNtaXNzaW9uLgogKgogKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogKgogKiBTT0ZUV0FSRSBMSUNFTlNFCiAqCiAqIFRoaXMgc29mdHdhcmUgaXMgcHJvdmlkZWQgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIHRlcm1zIGFuZCBjb25kaXRpb25zLAogKiB3aGljaCB5b3Ugc2hvdWxkIHJlYWQgY2FyZWZ1bGx5IGJlZm9yZSB1c2luZyB0aGUgc29mdHdhcmUuICBVc2luZyB0aGlzCiAqIHNvZnR3YXJlIGluZGljYXRlcyB5b3VyIGFjY2VwdGFuY2Ugb2YgdGhlc2UgdGVybXMgYW5kIGNvbmRpdGlvbnMuICBJZiB5b3UgZG8KICogbm90IGFncmVlIHdpdGggdGhlc2UgdGVybXMgYW5kIGNvbmRpdGlvbnMsIGRvIG5vdCB1c2UgdGhlIHNvZnR3YXJlLgogKgogKiBDb3B5cmlnaHQgqSAyMDA1IEFnZXJlIFN5c3RlbXMgSW5jLgogKiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKgogKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBvciBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAogKiBtb2RpZmljYXRpb25zLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6CiAqCiAqIC4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzCiAqICAgIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBEaXNjbGFpbWVyIGFzIGNvbW1lbnRzIGluIHRoZSBjb2RlIGFzCiAqICAgIHdlbGwgYXMgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQogKiAgICBkaXN0cmlidXRpb24uCiAqCiAqIC4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLAogKiAgICB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBEaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uCiAqICAgIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUgZGlzdHJpYnV0aW9uLgogKgogKiAuIE5laXRoZXIgdGhlIG5hbWUgb2YgQWdlcmUgU3lzdGVtcyBJbmMuIG5vciB0aGUgbmFtZXMgb2YgdGhlIGNvbnRyaWJ1dG9ycwogKiAgICBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUKICogICAgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCiAqCiAqIERpc2NsYWltZXIKICoKICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCCTQVMgSVOUIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsCiAqIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBJTkZSSU5HRU1FTlQgQU5EIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YKICogTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gIEFOWQogKiBVU0UsIE1PRElGSUNBVElPTiBPUiBESVNUUklCVVRJT04gT0YgVEhJUyBTT0ZUV0FSRSBJUyBTT0xFTFkgQVQgVEhFIFVTRVJTIE9XTgogKiBSSVNLLiBJTiBOTyBFVkVOVCBTSEFMTCBBR0VSRSBTWVNURU1TIElOQy4gT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZCiAqIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTCiAqIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsKICogTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECiAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgQ09OVFJBQ1QsIFNUUklDVAogKiBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAogKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSAogKiBEQU1BR0UuCiAqCiAqLwoKI2luY2x1ZGUgImV0MTMxeF92ZXJzaW9uLmgiCiNpbmNsdWRlICJldDEzMXhfZGVidWcuaCIKI2luY2x1ZGUgImV0MTMxeF9kZWZzLmgiCgojaW5jbHVkZSA8bGludXgvcGNpLmg+CiNpbmNsdWRlIDxsaW51eC9pbml0Lmg+CiNpbmNsdWRlIDxsaW51eC9tb2R1bGUuaD4KI2luY2x1ZGUgPGxpbnV4L3R5cGVzLmg+CiNpbmNsdWRlIDxsaW51eC9rZXJuZWwuaD4KCiNpbmNsdWRlIDxsaW51eC9zY2hlZC5oPgojaW5jbHVkZSA8bGludXgvcHRyYWNlLmg+CiNpbmNsdWRlIDxsaW51eC9zbGFiLmg+CiNpbmNsdWRlIDxsaW51eC9jdHlwZS5oPgojaW5jbHVkZSA8bGludXgvc3RyaW5nLmg+CiNpbmNsdWRlIDxsaW51eC90aW1lci5oPgojaW5jbHVkZSA8bGludXgvaW50ZXJydXB0Lmg+CiNpbmNsdWRlIDxsaW51eC9pbi5oPgojaW5jbHVkZSA8bGludXgvZGVsYXkuaD4KI2luY2x1ZGUgPGFzbS9pby5oPgojaW5jbHVkZSA8YXNtL3N5c3RlbS5oPgojaW5jbHVkZSA8YXNtL2JpdG9wcy5oPgoKI2luY2x1ZGUgPGxpbnV4L25ldGRldmljZS5oPgojaW5jbHVkZSA8bGludXgvZXRoZXJkZXZpY2UuaD4KI2luY2x1ZGUgPGxpbnV4L3NrYnVmZi5oPgojaW5jbHVkZSA8bGludXgvaWZfYXJwLmg+CiNpbmNsdWRlIDxsaW51eC9pb3BvcnQuaD4KCiNpbmNsdWRlICJldDEzMTBfcGh5LmgiCiNpbmNsdWRlICJldDEzMTBfcG0uaCIKI2luY2x1ZGUgImV0MTMxMF9qYWdjb3JlLmgiCgojaW5jbHVkZSAiZXQxMzF4X2FkYXB0ZXIuaCIKI2luY2x1ZGUgImV0MTMxeF9pbml0cGNpLmgiCiNpbmNsdWRlICJldDEzMXhfaXNyLmgiCgojaW5jbHVkZSAiZXQxMzEwX3R4LmgiCgovKiBEYXRhIGZvciBkZWJ1Z2dpbmcgZmFjaWxpdGllcyAqLwojaWZkZWYgQ09ORklHX0VUMTMxWF9ERUJVRwpleHRlcm4gZGJnX2luZm9fdCAqZXQxMzF4X2RiZ2luZm87CiNlbmRpZiAvKiBDT05GSUdfRVQxMzFYX0RFQlVHICovCgpzdGF0aWMgdm9pZCBldDEzMXhfdXBkYXRlX3RjYl9saXN0KHN0cnVjdCBldDEzMXhfYWRhcHRlciAqcEFkYXB0ZXIpOwpzdGF0aWMgdm9pZCBldDEzMXhfY2hlY2tfc2VuZF93YWl0X2xpc3Qoc3RydWN0IGV0MTMxeF9hZGFwdGVyICpwQWRhcHRlcik7CnN0YXRpYyBpbmxpbmUgdm9pZCBldDEzMXhfZnJlZV9zZW5kX3BhY2tldChzdHJ1Y3QgZXQxMzF4X2FkYXB0ZXIgKnBBZGFwdGVyLAoJCQkJCSAgIFBNUF9UQ0IgcE1wVGNiKTsKc3RhdGljIGludCBldDEzMXhfc2VuZF9wYWNrZXQoc3RydWN0IHNrX2J1ZmYgKnNrYiwKCQkJICAgICAgc3RydWN0IGV0MTMxeF9hZGFwdGVyICpwQWRhcHRlcik7CnN0YXRpYyBpbnQgbmljX3NlbmRfcGFja2V0KHN0cnVjdCBldDEzMXhfYWRhcHRlciAqcEFkYXB0ZXIsIFBNUF9UQ0IgcE1wVGNiKTsKCi8qKgogKiBldDEzMXhfdHhfZG1hX21lbW9yeV9hbGxvYwogKiBAYWRhcHRlcjogcG9pbnRlciB0byBvdXIgcHJpdmF0ZSBhZGFwdGVyIHN0cnVjdHVyZQogKgogKiBSZXR1cm5zIDAgb24gc3VjY2VzcyBhbmQgZXJybm8gb24gZmFpbHVyZSAoYXMgZGVmaW5lZCBpbiBlcnJuby5oKS4KICoKICogQWxsb2NhdGVzIG1lbW9yeSB0aGF0IHdpbGwgYmUgdmlzaWJsZSBib3RoIHRvIHRoZSBkZXZpY2UgYW5kIHRvIHRoZSBDUFUuCiAqIFRoZSBPUyB3aWxsIHBhc3MgdXMgcGFja2V0cywgcG9pbnRlcnMgdG8gd2hpY2ggd2Ugd2lsbCBpbnNlcnQgaW4gdGhlIFR4CiAqIERlc2NyaXB0b3IgcXVldWUuIFRoZSBkZXZpY2Ugd2lsbCByZWFkIHRoaXMgcXVldWUgdG8gZmluZCB0aGUgcGFja2V0cyBpbgogKiBtZW1vcnkuIFRoZSBkZXZpY2Ugd2lsbCB1cGRhdGUgdGhlICJzdGF0dXMiIGluIG1lbW9yeSBlYWNoIHRpbWUgaXQgeG1pdHMgYQogKiBwYWNrZXQuCiAqLwppbnQgZXQxMzF4X3R4X2RtYV9tZW1vcnlfYWxsb2Moc3RydWN0IGV0MTMxeF9hZGFwdGVyICphZGFwdGVyKQp7CglpbnQgZGVzY19zaXplID0gMDsKCVRYX1JJTkdfdCAqdHhfcmluZyA9ICZhZGFwdGVyLT5UeFJpbmc7CgoJREJHX0VOVEVSKGV0MTMxeF9kYmdpbmZvKTsKCgkvKiBBbGxvY2F0ZSBtZW1vcnkgZm9yIHRoZSBUQ0IncyAoVHJhbnNtaXQgQ29udHJvbCBCbG9jaykgKi8KCWFkYXB0ZXItPlR4UmluZy5NcFRjYk1lbSA9IChNUF9UQ0IgKikga2NhbGxvYyhOVU1fVENCLCBzaXplb2YoTVBfVENCKSwKCQkJCQkJICAgICAgR0ZQX0FUT01JQyB8IEdGUF9ETUEpOwoJaWYgKCFhZGFwdGVyLT5UeFJpbmcuTXBUY2JNZW0pIHsKCQlEQkdfRVJST1IoZXQxMzF4X2RiZ2luZm8sICJDYW5ub3QgYWxsb2MgbWVtb3J5IGZvciBUQ0JzXG4iKTsKCQlEQkdfTEVBVkUoZXQxMzF4X2RiZ2luZm8pOwoJCXJldHVybiAtRU5PTUVNOwoJfQoKCS8qIEFsbG9jYXRlIGVub3VnaCBtZW1vcnkgZm9yIHRoZSBUeCBkZXNjcmlwdG9yIHJpbmcsIGFuZCBhbGxvY2F0ZQoJICogc29tZSBleHRyYSBzbyB0aGF0IHRoZSByaW5nIGNhbiBiZSBhbGlnbmVkIG9uIGEgNGsgYm91bmRhcnkuCgkgKi8KCWRlc2Nfc2l6ZSA9IChzaXplb2YoVFhfREVTQ19FTlRSWV90KSAqIE5VTV9ERVNDX1BFUl9SSU5HX1RYKSArIDQwOTYgLSAxOwoJdHhfcmluZy0+cFR4RGVzY1JpbmdWYSA9CgkgICAgKFBUWF9ERVNDX0VOVFJZX3QpIHBjaV9hbGxvY19jb25zaXN0ZW50KGFkYXB0ZXItPnBkZXYsIGRlc2Nfc2l6ZSwKCQkJCQkJICAgICZ0eF9yaW5nLT5wVHhEZXNjUmluZ1BhKTsKCWlmICghYWRhcHRlci0+VHhSaW5nLnBUeERlc2NSaW5nVmEpIHsKCQlEQkdfRVJST1IoZXQxMzF4X2RiZ2luZm8sICJDYW5ub3QgYWxsb2MgbWVtb3J5IGZvciBUeCBSaW5nXG4iKTsKCQlEQkdfTEVBVkUoZXQxMzF4X2RiZ2luZm8pOwoJCXJldHVybiAtRU5PTUVNOwoJfQoKCS8qIFNhdmUgcGh5c2ljYWwgYWRkcmVzcwoJICoKCSAqIE5PVEU6IHBjaV9hbGxvY19jb25zaXN0ZW50KCksIHVzZWQgYWJvdmUgdG8gYWxsb2MgRE1BIHJlZ2lvbnMsCgkgKiBBTFdBWVMgcmV0dXJucyBTQUMgKDMyLWJpdCkgYWRkcmVzc2VzLiBJZiBEQUMgKDY0LWJpdCkgYWRkcmVzc2VzCgkgKiBhcmUgZXZlciByZXR1cm5lZCwgbWFrZSBzdXJlIHRoZSBoaWdoIHBhcnQgaXMgcmV0cmlldmVkIGhlcmUgYmVmb3JlCgkgKiBzdG9yaW5nIHRoZSBhZGp1c3RlZCBhZGRyZXNzLgoJICovCgl0eF9yaW5nLT5wVHhEZXNjUmluZ0FkanVzdGVkUGEgPSB0eF9yaW5nLT5wVHhEZXNjUmluZ1BhOwoKCS8qIEFsaWduIFR4IERlc2NyaXB0b3IgUmluZyBvbiBhIDRrICgweDEwMDApIGJ5dGUgYm91bmRhcnkgKi8KCWV0MTMxeF9hbGlnbl9hbGxvY2F0ZWRfbWVtb3J5KGFkYXB0ZXIsCgkJCQkgICAgICAmdHhfcmluZy0+cFR4RGVzY1JpbmdBZGp1c3RlZFBhLAoJCQkJICAgICAgJnR4X3JpbmctPlR4RGVzY09mZnNldCwgMHgwRkZGKTsKCgl0eF9yaW5nLT5wVHhEZXNjUmluZ1ZhICs9IHR4X3JpbmctPlR4RGVzY09mZnNldDsKCgkvKiBBbGxvY2F0ZSBtZW1vcnkgZm9yIHRoZSBUeCBzdGF0dXMgYmxvY2sgKi8KCXR4X3JpbmctPnBUeFN0YXR1c1ZhID0gcGNpX2FsbG9jX2NvbnNpc3RlbnQoYWRhcHRlci0+cGRldiwKCQkJCQkJICAgIHNpemVvZihUWF9TVEFUVVNfQkxPQ0tfdCksCgkJCQkJCSAgICAmdHhfcmluZy0+cFR4U3RhdHVzUGEpOwoJaWYgKCFhZGFwdGVyLT5UeFJpbmcucFR4U3RhdHVzUGEpIHsKCQlEQkdfRVJST1IoZXQxMzF4X2RiZ2luZm8sCgkJCSAgIkNhbm5vdCBhbGxvYyBtZW1vcnkgZm9yIFR4IHN0YXR1cyBibG9ja1xuIik7CgkJREJHX0xFQVZFKGV0MTMxeF9kYmdpbmZvKTsKCQlyZXR1cm4gLUVOT01FTTsKCX0KCgkvKiBBbGxvY2F0ZSBtZW1vcnkgZm9yIGEgZHVtbXkgYnVmZmVyICovCgl0eF9yaW5nLT5wVHhEdW1teUJsa1ZhID0gcGNpX2FsbG9jX2NvbnNpc3RlbnQoYWRhcHRlci0+cGRldiwKCQkJCQkJICAgICAgTklDX01JTl9QQUNLRVRfU0laRSwKCQkJCQkJICAgICAgJnR4X3JpbmctPnBUeER1bW15QmxrUGEpOwoJaWYgKCFhZGFwdGVyLT5UeFJpbmcucFR4RHVtbXlCbGtQYSkgewoJCURCR19FUlJPUihldDEzMXhfZGJnaW5mbywKCQkJICAiQ2Fubm90IGFsbG9jIG1lbW9yeSBmb3IgVHggZHVtbXkgYnVmZmVyXG4iKTsKCQlEQkdfTEVBVkUoZXQxMzF4X2RiZ2luZm8pOwoJCXJldHVybiAtRU5PTUVNOwoJfQoKCURCR19MRUFWRShldDEzMXhfZGJnaW5mbyk7CglyZXR1cm4gMDsKfQoKLyoqCiAqIGV0MTMxeF90eF9kbWFfbWVtb3J5X2ZyZWUgLSBGcmVlIGFsbCBtZW1vcnkgYWxsb2NhdGVkIHdpdGhpbiB0aGlzIG1vZHVsZQogKiBAYWRhcHRlcjogcG9pbnRlciB0byBvdXIgcHJpdmF0ZSBhZGFwdGVyIHN0cnVjdHVyZQogKgogKiBSZXR1cm5zIDAgb24gc3VjY2VzcyBhbmQgZXJybm8gb24gZmFpbHVyZSAoYXMgZGVmaW5lZCBpbiBlcnJuby5oKS4KICovCnZvaWQgZXQxMzF4X3R4X2RtYV9tZW1vcnlfZnJlZShzdHJ1Y3QgZXQxMzF4X2FkYXB0ZXIgKmFkYXB0ZXIpCnsKCWludCBkZXNjX3NpemUgPSAwOwoKCURCR19FTlRFUihldDEzMXhfZGJnaW5mbyk7CgoJaWYgKGFkYXB0ZXItPlR4UmluZy5wVHhEZXNjUmluZ1ZhKSB7CgkJLyogRnJlZSBtZW1vcnkgcmVsYXRpbmcgdG8gVHggcmluZ3MgaGVyZSAqLwoJCWFkYXB0ZXItPlR4UmluZy5wVHhEZXNjUmluZ1ZhIC09IGFkYXB0ZXItPlR4UmluZy5UeERlc2NPZmZzZXQ7CgoJCWRlc2Nfc2l6ZSA9CgkJICAgIChzaXplb2YoVFhfREVTQ19FTlRSWV90KSAqIE5VTV9ERVNDX1BFUl9SSU5HX1RYKSArIDQwOTYgLSAxOwoKCQlwY2lfZnJlZV9jb25zaXN0ZW50KGFkYXB0ZXItPnBkZXYsCgkJCQkgICAgZGVzY19zaXplLAoJCQkJICAgIGFkYXB0ZXItPlR4UmluZy5wVHhEZXNjUmluZ1ZhLAoJCQkJICAgIGFkYXB0ZXItPlR4UmluZy5wVHhEZXNjUmluZ1BhKTsKCgkJYWRhcHRlci0+VHhSaW5nLnBUeERlc2NSaW5nVmEgPSBOVUxMOwoJfQoKCS8qIEZyZWUgbWVtb3J5IGZvciB0aGUgVHggc3RhdHVzIGJsb2NrICovCglpZiAoYWRhcHRlci0+VHhSaW5nLnBUeFN0YXR1c1ZhKSB7CgkJcGNpX2ZyZWVfY29uc2lzdGVudChhZGFwdGVyLT5wZGV2LAoJCQkJICAgIHNpemVvZihUWF9TVEFUVVNfQkxPQ0tfdCksCgkJCQkgICAgYWRhcHRlci0+VHhSaW5nLnBUeFN0YXR1c1ZhLAoJCQkJICAgIGFkYXB0ZXItPlR4UmluZy5wVHhTdGF0dXNQYSk7CgoJCWFkYXB0ZXItPlR4UmluZy5wVHhTdGF0dXNWYSA9IE5VTEw7Cgl9CgoJLyogRnJlZSBtZW1vcnkgZm9yIHRoZSBkdW1teSBidWZmZXIgKi8KCWlmIChhZGFwdGVyLT5UeFJpbmcucFR4RHVtbXlCbGtWYSkgewoJCXBjaV9mcmVlX2NvbnNpc3RlbnQoYWRhcHRlci0+cGRldiwKCQkJCSAgICBOSUNfTUlOX1BBQ0tFVF9TSVpFLAoJCQkJICAgIGFkYXB0ZXItPlR4UmluZy5wVHhEdW1teUJsa1ZhLAoJCQkJICAgIGFkYXB0ZXItPlR4UmluZy5wVHhEdW1teUJsa1BhKTsKCgkJYWRhcHRlci0+VHhSaW5nLnBUeER1bW15QmxrVmEgPSBOVUxMOwoJfQoKCS8qIEZyZWUgdGhlIG1lbW9yeSBmb3IgTVBfVENCIHN0cnVjdHVyZXMgKi8KCWlmIChhZGFwdGVyLT5UeFJpbmcuTXBUY2JNZW0pIHsKCQlrZnJlZShhZGFwdGVyLT5UeFJpbmcuTXBUY2JNZW0pOwoJCWFkYXB0ZXItPlR4UmluZy5NcFRjYk1lbSA9IE5VTEw7Cgl9CgoJREJHX0xFQVZFKGV0MTMxeF9kYmdpbmZvKTsKfQoKLyoqCiAqIENvbmZpZ1R4RG1hUmVncyAtIFNldCB1cCB0aGUgdHggZG1hIHNlY3Rpb24gb2YgdGhlIEpBR0NvcmUuCiAqIEBhZGFwdGVyOiBwb2ludGVyIHRvIG91ciBwcml2YXRlIGFkYXB0ZXIgc3RydWN0dXJlCiAqLwp2b2lkIENvbmZpZ1R4RG1hUmVncyhzdHJ1Y3QgZXQxMzF4X2FkYXB0ZXIgKnBBZGFwdGVyKQp7CglzdHJ1Y3QgX1RYRE1BX3QgX19pb21lbSAqcFR4RG1hID0gJnBBZGFwdGVyLT5DU1JBZGRyZXNzLT50eGRtYTsKCglEQkdfRU5URVIoZXQxMzF4X2RiZ2luZm8pOwoKCS8qIExvYWQgdGhlIGhhcmR3YXJlIHdpdGggdGhlIHN0YXJ0IG9mIHRoZSB0cmFuc21pdCBkZXNjcmlwdG9yIHJpbmcuICovCgl3cml0ZWwoKHVpbnQzMl90KSAocEFkYXB0ZXItPlR4UmluZy5wVHhEZXNjUmluZ0FkanVzdGVkUGEgPj4gMzIpLAoJICAgICAgICZwVHhEbWEtPnByX2Jhc2VfaGkpOwoJd3JpdGVsKCh1aW50MzJfdCkgcEFkYXB0ZXItPlR4UmluZy5wVHhEZXNjUmluZ0FkanVzdGVkUGEsCgkgICAgICAgJnBUeERtYS0+cHJfYmFzZV9sbyk7CgoJLyogSW5pdGlhbGlzZSB0aGUgdHJhbnNtaXQgRE1BIGVuZ2luZSAqLwoJd3JpdGVsKE5VTV9ERVNDX1BFUl9SSU5HX1RYIC0gMSwgJnBUeERtYS0+cHJfbnVtX2Rlcy52YWx1ZSk7CgoJLyogTG9hZCB0aGUgY29tcGxldGlvbiB3cml0ZWJhY2sgcGh5c2ljYWwgYWRkcmVzcwoJICoKCSAqIE5PVEU6IHBjaV9hbGxvY19jb25zaXN0ZW50KCksIHVzZWQgYWJvdmUgdG8gYWxsb2MgRE1BIHJlZ2lvbnMsCgkgKiBBTFdBWVMgcmV0dXJucyBTQUMgKDMyLWJpdCkgYWRkcmVzc2VzLiBJZiBEQUMgKDY0LWJpdCkgYWRkcmVzc2VzCgkgKiBhcmUgZXZlciByZXR1cm5lZCwgbWFrZSBzdXJlIHRoZSBoaWdoIHBhcnQgaXMgcmV0cmlldmVkIGhlcmUgYmVmb3JlCgkgKiBzdG9yaW5nIHRoZSBhZGp1c3RlZCBhZGRyZXNzLgoJICovCgl3cml0ZWwoMCwgJnBUeERtYS0+ZG1hX3diX2Jhc2VfaGkpOwoJd3JpdGVsKHBBZGFwdGVyLT5UeFJpbmcucFR4U3RhdHVzUGEsICZwVHhEbWEtPmRtYV93Yl9iYXNlX2xvKTsKCgltZW1zZXQocEFkYXB0ZXItPlR4UmluZy5wVHhTdGF0dXNWYSwgMCwgc2l6ZW9mKFRYX1NUQVRVU19CTE9DS190KSk7CgoJd3JpdGVsKDAsICZwVHhEbWEtPnNlcnZpY2VfcmVxdWVzdC52YWx1ZSk7CglwQWRhcHRlci0+VHhSaW5nLnR4RG1hUmVhZHlUb1NlbmQudmFsdWUgPSAwOwoKCURCR19MRUFWRShldDEzMXhfZGJnaW5mbyk7Cn0KCi8qKgogKiBldDEzMXhfdHhfZG1hX2Rpc2FibGUgLSBTdG9wIG9mIFR4X0RNQSBvbiB0aGUgRVQxMzEwCiAqIEBwQWRhcHRlcjogcG9pbnRlciB0byBvdXIgYWRhcHRlciBzdHJ1Y3R1cmUKICovCnZvaWQgZXQxMzF4X3R4X2RtYV9kaXNhYmxlKHN0cnVjdCBldDEzMXhfYWRhcHRlciAqcEFkYXB0ZXIpCnsKCURCR19FTlRFUihldDEzMXhfZGJnaW5mbyk7CgoJLyogU2V0dXAgdGhlIHRyYW1zbWl0IGRtYSBjb25maWd1cmF0aW9uIHJlZ2lzdGVyICovCgl3cml0ZWwoMHgxMDEsICZwQWRhcHRlci0+Q1NSQWRkcmVzcy0+dHhkbWEuY3NyLnZhbHVlKTsKCglEQkdfTEVBVkUoZXQxMzF4X2RiZ2luZm8pOwp9CgovKioKICogZXQxMzF4X3R4X2RtYV9lbmFibGUgLSByZS1zdGFydCBvZiBUeF9ETUEgb24gdGhlIEVUMTMxMC4KICogQHBBZGFwdGVyOiBwb2ludGVyIHRvIG91ciBhZGFwdGVyIHN0cnVjdHVyZQogKgogKiBNYWlubHkgdXNlZCBhZnRlciBhIHJldHVybiB0byB0aGUgRDAgKGZ1bGwtcG93ZXIpIHN0YXRlIGZyb20gYSBsb3dlciBzdGF0ZS4KICovCnZvaWQgZXQxMzF4X3R4X2RtYV9lbmFibGUoc3RydWN0IGV0MTMxeF9hZGFwdGVyICpwQWRhcHRlcikKewoJREJHX0VOVEVSKGV0MTMxeF9kYmdpbmZvKTsKCglpZiAocEFkYXB0ZXItPlJlZ2lzdHJ5UGh5TG9vcGJrKSB7CgkvKiBUeERNQSBpcyBkaXNhYmxlZCBmb3IgbG9vcGJhY2sgb3BlcmF0aW9uLiAqLwoJCXdyaXRlbCgweDEwMSwgJnBBZGFwdGVyLT5DU1JBZGRyZXNzLT50eGRtYS5jc3IudmFsdWUpOwoJfSBlbHNlIHsKCQlUWERNQV9DU1JfdCBjc3IgPSB7IDAgfTsKCgkJLyogU2V0dXAgdGhlIHRyYW5zbWl0IGRtYSBjb25maWd1cmF0aW9uIHJlZ2lzdGVyIGZvciBub3JtYWwKCQkgKiBvcGVyYXRpb24KCQkgKi8KCQljc3IuYml0cy5zbmdsX2Vwa3RfbW9kZSA9IDE7CgkJY3NyLmJpdHMuaGFsdCA9IDA7CgkJY3NyLmJpdHMuY2FjaGVfdGhyc2hsZCA9IHBBZGFwdGVyLT5SZWdpc3RyeURNQUNhY2hlOwoJCXdyaXRlbChjc3IudmFsdWUsICZwQWRhcHRlci0+Q1NSQWRkcmVzcy0+dHhkbWEuY3NyLnZhbHVlKTsKCX0KCglEQkdfTEVBVkUoZXQxMzF4X2RiZ2luZm8pOwp9CgovKioKICogZXQxMzF4X2luaXRfc2VuZCAtIEluaXRpYWxpemUgc2VuZCBkYXRhIHN0cnVjdHVyZXMKICogQGFkYXB0ZXI6IHBvaW50ZXIgdG8gb3VyIHByaXZhdGUgYWRhcHRlciBzdHJ1Y3R1cmUKICovCnZvaWQgZXQxMzF4X2luaXRfc2VuZChzdHJ1Y3QgZXQxMzF4X2FkYXB0ZXIgKmFkYXB0ZXIpCnsKCVBNUF9UQ0IgcE1wVGNiOwoJdWludDMyX3QgVGNiQ291bnQ7CglUWF9SSU5HX3QgKnR4X3Jpbmc7CgoJREJHX0VOVEVSKGV0MTMxeF9kYmdpbmZvKTsKCgkvKiBTZXR1cCBzb21lIGNvbnZlbmllbmNlIHBvaW50ZXJzICovCgl0eF9yaW5nID0gJmFkYXB0ZXItPlR4UmluZzsKCXBNcFRjYiA9IGFkYXB0ZXItPlR4UmluZy5NcFRjYk1lbTsKCgl0eF9yaW5nLT5UQ0JSZWFkeVF1ZXVlSGVhZCA9IHBNcFRjYjsKCgkvKiBHbyB0aHJvdWdoIGFuZCBzZXQgdXAgZWFjaCBUQ0IgKi8KCWZvciAoVGNiQ291bnQgPSAwOyBUY2JDb3VudCA8IE5VTV9UQ0I7IFRjYkNvdW50KyspIHsKCQltZW1zZXQocE1wVGNiLCAwLCBzaXplb2YoTVBfVENCKSk7CgoJCS8qIFNldCB0aGUgbGluayBwb2ludGVyIGluIEhXIFRDQiB0byB0aGUgbmV4dCBUQ0IgaW4gdGhlCgkJICogY2hhaW4uICBJZiB0aGlzIGlzIHRoZSBsYXN0IFRDQiBpbiB0aGUgY2hhaW4sIGFsc28gc2V0IHRoZQoJCSAqIHRhaWwgcG9pbnRlci4KCQkgKi8KCQlpZiAoVGNiQ291bnQgPCBOVU1fVENCIC0gMSkgewoJCQlwTXBUY2ItPk5leHQgPSBwTXBUY2IgKyAxOwoJCX0gZWxzZSB7CgkJCXR4X3JpbmctPlRDQlJlYWR5UXVldWVUYWlsID0gcE1wVGNiOwoJCQlwTXBUY2ItPk5leHQgPSAoUE1QX1RDQikgTlVMTDsKCQl9CgoJCXBNcFRjYisrOwoJfQoKCS8qIEN1cnIgc2VuZCBxdWV1ZSBzaG91bGQgbm93IGJlIGVtcHR5ICovCgl0eF9yaW5nLT5DdXJyU2VuZEhlYWQgPSAoUE1QX1RDQikgTlVMTDsKCXR4X3JpbmctPkN1cnJTZW5kVGFpbCA9IChQTVBfVENCKSBOVUxMOwoKCUlOSVRfTElTVF9IRUFEKCZhZGFwdGVyLT5UeFJpbmcuU2VuZFdhaXRRdWV1ZSk7CgoJREJHX0xFQVZFKGV0MTMxeF9kYmdpbmZvKTsKfQoKLyoqCiAqIGV0MTMxeF9zZW5kX3BhY2tldHMgLSBUaGlzIGZ1bmN0aW9uIGlzIGNhbGxlZCBieSB0aGUgT1MgdG8gc2VuZCBwYWNrZXRzCiAqIEBza2I6IHRoZSBwYWNrZXQocykgdG8gc2VuZAogKiBAbmV0ZGV2OmRldmljZSBvbiB3aGljaCB0byBUWCB0aGUgYWJvdmUgcGFja2V0KHMpCiAqCiAqIFJldHVybiAwIGluIGFsbW9zdCBhbGwgY2FzZXM7IG5vbi16ZXJvIHZhbHVlIGluIGV4dHJlbWUgaGFyZCBmYWlsdXJlIG9ubHkKICovCmludCBldDEzMXhfc2VuZF9wYWNrZXRzKHN0cnVjdCBza19idWZmICpza2IsIHN0cnVjdCBuZXRfZGV2aWNlICpuZXRkZXYpCnsKCWludCBzdGF0dXMgPSAwOwoJc3RydWN0IGV0MTMxeF9hZGFwdGVyICpwQWRhcHRlciA9IE5VTEw7CgoJREJHX1RYX0VOVEVSKGV0MTMxeF9kYmdpbmZvKTsKCglwQWRhcHRlciA9IG5ldGRldl9wcml2KG5ldGRldik7CgoJLyogU2VuZCB0aGVzZSBwYWNrZXRzCgkgKgoJICogTk9URTogVGhlIExpbnV4IFR4IGVudHJ5IHBvaW50IGlzIG9ubHkgZ2l2ZW4gb25lIHBhY2tldCBhdCBhIHRpbWUKCSAqIHRvIFR4LCBzbyB0aGUgUGFja2V0Q291bnQgYW5kIGl0J3MgYXJyYXkgdXNlZCBtYWtlcyBubyBzZW5zZSBoZXJlCgkgKi8KCgkvKiBRdWV1ZSBpcyBub3QgZW1wdHkgb3IgVENCIGlzIG5vdCBhdmFpbGFibGUgKi8KCWlmICghbGlzdF9lbXB0eSgmcEFkYXB0ZXItPlR4UmluZy5TZW5kV2FpdFF1ZXVlKSB8fAoJICAgIE1QX1RDQl9SRVNPVVJDRVNfTk9UX0FWQUlMQUJMRShwQWRhcHRlcikpIHsKCQkvKiBOT1RFOiBJZiB0aGVyZSdzIGFuIGVycm9yIG9uIHNlbmQsIG5vIG5lZWQgdG8gcXVldWUgdGhlCgkJICogcGFja2V0IHVuZGVyIExpbnV4OyBpZiB3ZSBqdXN0IHNlbmQgYW4gZXJyb3IgdXAgdG8gdGhlCgkJICogbmV0aWYgbGF5ZXIsIGl0IHdpbGwgcmVzZW5kIHRoZSBza2IgdG8gdXMuCgkJICovCgkJREJHX1ZFUkJPU0UoZXQxMzF4X2RiZ2luZm8sICJUQ0IgUmVzb3VyY2VzIE5vdCBBdmFpbGFibGVcbiIpOwoJCXN0YXR1cyA9IC1FTk9NRU07Cgl9IGVsc2UgewoJCS8qIFdlIG5lZWQgdG8gc2VlIGlmIHRoZSBsaW5rIGlzIHVwOyBpZiBpdCdzIG5vdCwgbWFrZSB0aGUKCQkgKiBuZXRpZiBsYXllciB0aGluayB3ZSdyZSBnb29kIGFuZCBkcm9wIHRoZSBwYWNrZXQKCQkgKi8KCQkvL2lmKCBNUF9TSE9VTERfRkFJTF9TRU5EKCBwQWRhcHRlciApIHx8IHBBZGFwdGVyLT5Ecml2ZXJOb1BoeUFjY2VzcyApCgkJaWYgKE1QX1NIT1VMRF9GQUlMX1NFTkQocEFkYXB0ZXIpIHx8IHBBZGFwdGVyLT5Ecml2ZXJOb1BoeUFjY2VzcwoJCSAgICB8fCAhbmV0aWZfY2Fycmllcl9vayhuZXRkZXYpKSB7CgkJCURCR19WRVJCT1NFKGV0MTMxeF9kYmdpbmZvLAoJCQkJICAgICJDYW4ndCBUeCwgTGluayBpcyBET1dOOyBkcm9wIHRoZSBwYWNrZXRcbiIpOwoKCQkJZGV2X2tmcmVlX3NrYl9hbnkoc2tiKTsKCQkJc2tiID0gTlVMTDsKCgkJCXBBZGFwdGVyLT5uZXRfc3RhdHMudHhfZHJvcHBlZCsrOwoJCX0gZWxzZSB7CgkJCXN0YXR1cyA9IGV0MTMxeF9zZW5kX3BhY2tldChza2IsIHBBZGFwdGVyKTsKCgkJCWlmIChzdGF0dXMgPT0gLUVOT01FTSkgewoKCQkJCS8qIE5PVEU6IElmIHRoZXJlJ3MgYW4gZXJyb3Igb24gc2VuZCwgbm8gbmVlZAoJCQkJICogdG8gcXVldWUgdGhlIHBhY2tldCB1bmRlciBMaW51eDsgaWYgd2UganVzdAoJCQkJICogc2VuZCBhbiBlcnJvciB1cCB0byB0aGUgbmV0aWYgbGF5ZXIsIGl0CgkJCQkgKiB3aWxsIHJlc2VuZCB0aGUgc2tiIHRvIHVzLgoJCQkJICovCgkJCQlEQkdfV0FSTklORyhldDEzMXhfZGJnaW5mbywKCQkJCQkgICAgIlJlc291cmNlcyBwcm9ibGVtLCBRdWV1ZSB0eCBwYWNrZXRcbiIpOwoJCQl9IGVsc2UgaWYgKHN0YXR1cyAhPSAwKSB7CgkJCQkvKiBPbiBhbnkgb3RoZXIgZXJyb3IsIG1ha2UgbmV0aWYgdGhpbmsgd2UncmUKCQkJCSAqIE9LIGFuZCBkcm9wIHRoZSBwYWNrZXQKCQkJCSAqLwoJCQkJREJHX1dBUk5JTkcoZXQxMzF4X2RiZ2luZm8sCgkJCQkJICAgICJHZW5lcmFsIGVycm9yLCBkcm9wIHBhY2tldFxuIik7CgoJCQkJZGV2X2tmcmVlX3NrYl9hbnkoc2tiKTsKCQkJCXNrYiA9IE5VTEw7CgoJCQkJcEFkYXB0ZXItPm5ldF9zdGF0cy50eF9kcm9wcGVkKys7CgkJCX0KCQl9Cgl9CgoJREJHX1RYX0xFQVZFKGV0MTMxeF9kYmdpbmZvKTsKCXJldHVybiBzdGF0dXM7Cn0KCi8qKgogKiBldDEzMXhfc2VuZF9wYWNrZXQgLSBEbyB0aGUgd29yayB0byBzZW5kIGEgcGFja2V0CiAqIEBza2I6IHRoZSBwYWNrZXQocykgdG8gc2VuZAogKiBAcEFkYXB0ZXI6IGEgcG9pbnRlciB0byB0aGUgZGV2aWNlJ3MgcHJpdmF0ZSBhZGFwdGVyIHN0cnVjdHVyZQogKgogKiBSZXR1cm4gMCBpbiBhbG1vc3QgYWxsIGNhc2VzOyBub24temVybyB2YWx1ZSBpbiBleHRyZW1lIGhhcmQgZmFpbHVyZSBvbmx5LgogKgogKiBBc3N1bXB0aW9uOiBTZW5kIHNwaW5sb2NrIGhhcyBiZWVuIGFjcXVpcmVkCiAqLwpzdGF0aWMgaW50IGV0MTMxeF9zZW5kX3BhY2tldChzdHJ1Y3Qgc2tfYnVmZiAqc2tiLAoJCQkgICAgICBzdHJ1Y3QgZXQxMzF4X2FkYXB0ZXIgKnBBZGFwdGVyKQp7CglpbnQgc3RhdHVzID0gMDsKCVBNUF9UQ0IgcE1wVGNiID0gTlVMTDsKCXVpbnQxNl90ICpwU2hCdWZWYTsKCXVuc2lnbmVkIGxvbmcgbG9ja2ZsYWdzOwoKCURCR19UWF9FTlRFUihldDEzMXhfZGJnaW5mbyk7CgoJLyogSXMgb3VyIGJ1ZmZlciBzY2F0dGVyZWQsIG9yIGNvbnRpbnVvdXM/ICovCglpZiAoc2tiX3NoaW5mbyhza2IpLT5ucl9mcmFncyA9PSAwKSB7CgkJREJHX1RYKGV0MTMxeF9kYmdpbmZvLCAiU2NhdHRlcmVkIGJ1ZmZlcjogTk9cbiIpOwoJfSBlbHNlIHsKCQlEQkdfVFgoZXQxMzF4X2RiZ2luZm8sICJTY2F0dGVyZWQgYnVmZmVyOiBZRVMsIE51bSBGcmFnczogJWRcbiIsCgkJICAgICAgIHNrYl9zaGluZm8oc2tiKS0+bnJfZnJhZ3MpOwoJfQoKCS8qIEFsbCBwYWNrZXRzIG11c3QgaGF2ZSBhdCBsZWFzdCBhIE1BQyBhZGRyZXNzIGFuZCBhIHByb3RvY29sIHR5cGUgKi8KCWlmIChza2ItPmxlbiA8IEVUSF9ITEVOKSB7CgkJREJHX0VSUk9SKGV0MTMxeF9kYmdpbmZvLAoJCQkgICJQYWNrZXQgc2l6ZSA8IEVUSF9ITEVOICgxNCBieXRlcylcbiIpOwoJCURCR19MRUFWRShldDEzMXhfZGJnaW5mbyk7CgkJcmV0dXJuIC1FSU87Cgl9CgoJLyogR2V0IGEgVENCIGZvciB0aGlzIHBhY2tldCAqLwoJc3Bpbl9sb2NrX2lycXNhdmUoJnBBZGFwdGVyLT5UQ0JSZWFkeVFMb2NrLCBsb2NrZmxhZ3MpOwoKCXBNcFRjYiA9IHBBZGFwdGVyLT5UeFJpbmcuVENCUmVhZHlRdWV1ZUhlYWQ7CgoJaWYgKHBNcFRjYiA9PSBOVUxMKSB7CgkJc3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmcEFkYXB0ZXItPlRDQlJlYWR5UUxvY2ssIGxvY2tmbGFncyk7CgoJCURCR19XQVJOSU5HKGV0MTMxeF9kYmdpbmZvLCAiQ2FuJ3Qgb2J0YWluIGEgVENCXG4iKTsKCQlEQkdfVFhfTEVBVkUoZXQxMzF4X2RiZ2luZm8pOwoJCXJldHVybiAtRU5PTUVNOwoJfQoKCXBBZGFwdGVyLT5UeFJpbmcuVENCUmVhZHlRdWV1ZUhlYWQgPSBwTXBUY2ItPk5leHQ7CgoJaWYgKHBBZGFwdGVyLT5UeFJpbmcuVENCUmVhZHlRdWV1ZUhlYWQgPT0gTlVMTCkgewoJCXBBZGFwdGVyLT5UeFJpbmcuVENCUmVhZHlRdWV1ZVRhaWwgPSBOVUxMOwoJfQoKCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJnBBZGFwdGVyLT5UQ0JSZWFkeVFMb2NrLCBsb2NrZmxhZ3MpOwoKCXBNcFRjYi0+UGFja2V0TGVuZ3RoID0gc2tiLT5sZW47CglwTXBUY2ItPlBhY2tldCA9IHNrYjsKCglpZiAoKHNrYi0+ZGF0YSAhPSBOVUxMKSAmJiAoKHNrYi0+bGVuIC0gc2tiLT5kYXRhX2xlbikgPj0gNikpIHsKCQlwU2hCdWZWYSA9ICh1aW50MTZfdCAqKSBza2ItPmRhdGE7CgoJCWlmICgocFNoQnVmVmFbMF0gPT0gMHhmZmZmKSAmJgoJCSAgICAocFNoQnVmVmFbMV0gPT0gMHhmZmZmKSAmJiAocFNoQnVmVmFbMl0gPT0gMHhmZmZmKSkgewoJCQlNUF9TRVRfRkxBRyhwTXBUY2IsIGZNUF9ERVNUX0JST0FEKTsKCQl9IGVsc2UgaWYgKChwU2hCdWZWYVswXSAmIDB4MykgPT0gMHgwMDAxKSB7CgkJCU1QX1NFVF9GTEFHKHBNcFRjYiwgZk1QX0RFU1RfTVVMVEkpOwoJCX0KCX0KCglwTXBUY2ItPk5leHQgPSBOVUxMOwoKCS8qIENhbGwgdGhlIE5JQyBzcGVjaWZpYyBzZW5kIGhhbmRsZXIuICovCglpZiAoc3RhdHVzID09IDApIHsKCQlzdGF0dXMgPSBuaWNfc2VuZF9wYWNrZXQocEFkYXB0ZXIsIHBNcFRjYik7Cgl9CgoJaWYgKHN0YXR1cyAhPSAwKSB7CgkJc3Bpbl9sb2NrX2lycXNhdmUoJnBBZGFwdGVyLT5UQ0JSZWFkeVFMb2NrLCBsb2NrZmxhZ3MpOwoKCQlpZiAocEFkYXB0ZXItPlR4UmluZy5UQ0JSZWFkeVF1ZXVlVGFpbCkgewoJCQlwQWRhcHRlci0+VHhSaW5nLlRDQlJlYWR5UXVldWVUYWlsLT5OZXh0ID0gcE1wVGNiOwoJCX0gZWxzZSB7CgkJCS8qIEFwcGFyZW50bHkgcmVhZHkgUSBpcyBlbXB0eS4gKi8KCQkJcEFkYXB0ZXItPlR4UmluZy5UQ0JSZWFkeVF1ZXVlSGVhZCA9IHBNcFRjYjsKCQl9CgoJCXBBZGFwdGVyLT5UeFJpbmcuVENCUmVhZHlRdWV1ZVRhaWwgPSBwTXBUY2I7CgoJCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJnBBZGFwdGVyLT5UQ0JSZWFkeVFMb2NrLCBsb2NrZmxhZ3MpOwoKCQlEQkdfVFhfTEVBVkUoZXQxMzF4X2RiZ2luZm8pOwoJCXJldHVybiBzdGF0dXM7Cgl9CgoJREJHX0FTU0VSVChwQWRhcHRlci0+VHhSaW5nLm5CdXN5U2VuZCA8PSBOVU1fVENCKTsKCglEQkdfVFhfTEVBVkUoZXQxMzF4X2RiZ2luZm8pOwoJcmV0dXJuIDA7Cn0KCi8qKgogKiBuaWNfc2VuZF9wYWNrZXQgLSBOSUMgc3BlY2lmaWMgc2VuZCBoYW5kbGVyIGZvciB2ZXJzaW9uIEIgc2lsaWNvbi4KICogQHBBZGFwdGVyOiBwb2ludGVyIHRvIG91ciBhZGFwdGVyCiAqIEBwTXBUY2I6IHBvaW50ZXIgdG8gTVBfVENCCiAqCiAqIFJldHVybnMgMCBvciBlcnJuby4KICovCnN0YXRpYyBpbnQgbmljX3NlbmRfcGFja2V0KHN0cnVjdCBldDEzMXhfYWRhcHRlciAqcEFkYXB0ZXIsIFBNUF9UQ0IgcE1wVGNiKQp7Cgl1aW50MzJfdCBsb29wSW5kZXg7CglUWF9ERVNDX0VOVFJZX3QgQ3VyRGVzY1syNF07Cgl1aW50MzJfdCBGcmFnbWVudE51bWJlciA9IDA7Cgl1aW50MzJfdCBpVGhpc0NvcHksIGlSZW1haW5kZXI7CglzdHJ1Y3Qgc2tfYnVmZiAqcFBhY2tldCA9IHBNcFRjYi0+UGFja2V0OwoJdWludDMyX3QgRnJhZ0xpc3RDb3VudCA9IHNrYl9zaGluZm8ocFBhY2tldCktPm5yX2ZyYWdzICsgMTsKCXN0cnVjdCBza2JfZnJhZ19zdHJ1Y3QgKnBGcmFnTGlzdCA9ICZza2Jfc2hpbmZvKHBQYWNrZXQpLT5mcmFnc1swXTsKCXVuc2lnbmVkIGxvbmcgbG9ja2ZsYWdzMSwgbG9ja2ZsYWdzMjsKCglEQkdfVFhfRU5URVIoZXQxMzF4X2RiZ2luZm8pOwoKCS8qIFBhcnQgb2YgdGhlIG9wdGltaXphdGlvbnMgb2YgdGhpcyBzZW5kIHJvdXRpbmUgcmVzdHJpY3QgdXMgdG8KCSAqIHNlbmRpbmcgMjQgZnJhZ21lbnRzIGF0IGEgcGFzcy4gIEluIHByYWN0aWNlIHdlIHNob3VsZCBuZXZlciBzZWUKCSAqIG1vcmUgdGhhbiA1IGZyYWdtZW50cy4KCSAqCgkgKiBOT1RFOiBUaGUgb2xkZXIgdmVyc2lvbiBvZiB0aGlzIGZ1bmN0aW9uIChiZWxvdykgY2FuIGhhbmRsZSBhbnkKCSAqIG51bWJlciBvZiBmcmFnbWVudHMuIElmIG5lZWRlZCwgd2UgY2FuIGNhbGwgdGhpcyBmdW5jdGlvbiwKCSAqIGFsdGhvdWdoIGl0IGlzIGxlc3MgZWZmaWNpZW50LgoJICovCglpZiAoRnJhZ0xpc3RDb3VudCA+IDIzKSB7CgkJREJHX1RYX0xFQVZFKGV0MTMxeF9kYmdpbmZvKTsKCQlyZXR1cm4gLUVJTzsKCX0KCgltZW1zZXQoQ3VyRGVzYywgMCwgc2l6ZW9mKFRYX0RFU0NfRU5UUllfdCkgKiAoRnJhZ0xpc3RDb3VudCArIDEpKTsKCglmb3IgKGxvb3BJbmRleCA9IDA7IGxvb3BJbmRleCA8IEZyYWdMaXN0Q291bnQ7IGxvb3BJbmRleCsrKSB7CgkJLyogSWYgdGhlcmUgaXMgc29tZXRoaW5nIGluIHRoaXMgZWxlbWVudCwgbGV0cyBnZXQgYQoJCSAqIGRlc2NyaXB0b3IgZnJvbSB0aGUgcmluZyBhbmQgZ2V0IHRoZSBuZWNlc3NhcnkgZGF0YQoJCSAqLwoJCWlmIChsb29wSW5kZXggPT0gMCkgewoJCQkvKiBJZiB0aGUgZnJhZ21lbnRzIGFyZSBzbWFsbGVyIHRoYW4gYSBzdGFuZGFyZCBNVFUsCgkJCSAqIHRoZW4gbWFwIHRoZW0gdG8gYSBzaW5nbGUgZGVzY3JpcHRvciBpbiB0aGUgVHgKCQkJICogRGVzYyByaW5nLiBIb3dldmVyLCBpZiB0aGV5J3JlIGxhcmdlciwgYXMgaXMKCQkJICogcG9zc2libGUgd2l0aCBzdXBwb3J0IGZvciBqdW1ibyBwYWNrZXRzLCB0aGVuCgkJCSAqIHNwbGl0IHRoZW0gZWFjaCBhY3Jvc3MgMiBkZXNjcmlwdG9ycy4KCQkJICoKCQkJICogVGhpcyB3aWxsIHdvcmsgdW50aWwgd2UgZGV0ZXJtaW5lIHdoeSB0aGUgaGFyZHdhcmUKCQkJICogZG9lc24ndCBzZWVtIHRvIGxpa2UgbGFyZ2UgZnJhZ21lbnRzLgoJCQkgKi8KCQkJaWYgKChwUGFja2V0LT5sZW4gLSBwUGFja2V0LT5kYXRhX2xlbikgPD0gMTUxNCkgewoJCQkJREJHX1RYKGV0MTMxeF9kYmdpbmZvLAoJCQkJICAgICAgICJHb3QgcGFja2V0IG9mIGxlbmd0aCAlZCwgIgoJCQkJICAgICAgICJmaWxsaW5nIGRlc2MgZW50cnkgJWQsICIKCQkJCSAgICAgICAiVENCOiAweCVwXG4iLAoJCQkJICAgICAgIChwUGFja2V0LT5sZW4gLSBwUGFja2V0LT5kYXRhX2xlbiksCgkJCQkgICAgICAgcEFkYXB0ZXItPlR4UmluZy50eERtYVJlYWR5VG9TZW5kLmJpdHMuCgkJCQkgICAgICAgdmFsLCBwTXBUY2IpOwoKCQkJCUN1ckRlc2NbRnJhZ21lbnROdW1iZXJdLkRhdGFCdWZmZXJQdHJIaWdoID0gMDsKCgkJCQlDdXJEZXNjW0ZyYWdtZW50TnVtYmVyXS53b3JkMi5iaXRzLgoJCQkJICAgIGxlbmd0aF9pbl9ieXRlcyA9CgkJCQkgICAgcFBhY2tldC0+bGVuIC0gcFBhY2tldC0+ZGF0YV9sZW47CgoJCQkJLyogTk9URTogSGVyZSwgdGhlIGRtYV9hZGRyX3QgcmV0dXJuZWQgZnJvbQoJCQkJICogcGNpX21hcF9zaW5nbGUoKSBpcyBpbXBsaWNpdGx5IGNhc3QgYXMgYQoJCQkJICogdWludDMyX3QuIEFsdGhvdWdoIGRtYV9hZGRyX3QgY2FuIGJlCgkJCQkgKiA2NC1iaXQsIHRoZSBhZGRyZXNzIHJldHVybmVkIGJ5CgkJCQkgKiBwY2lfbWFwX3NpbmdsZSgpIGlzIGFsd2F5cyAzMi1iaXQKCQkJCSAqIGFkZHJlc3NhYmxlIChhcyBkZWZpbmVkIGJ5IHRoZSBwY2kvZG1hCgkJCQkgKiBzdWJzeXN0ZW0pCgkJCQkgKi8KCQkJCUN1ckRlc2NbRnJhZ21lbnROdW1iZXIrK10uRGF0YUJ1ZmZlclB0ckxvdyA9CgkJCQkgICAgcGNpX21hcF9zaW5nbGUocEFkYXB0ZXItPnBkZXYsCgkJCQkJCSAgIHBQYWNrZXQtPmRhdGEsCgkJCQkJCSAgIHBQYWNrZXQtPmxlbiAtCgkJCQkJCSAgIHBQYWNrZXQtPmRhdGFfbGVuLAoJCQkJCQkgICBQQ0lfRE1BX1RPREVWSUNFKTsKCQkJfSBlbHNlIHsKCQkJCURCR19UWChldDEzMXhfZGJnaW5mbywKCQkJCSAgICAgICAiR290IHBhY2tldCBvZiBsZW5ndGggJWQsICIKCQkJCSAgICAgICAiZmlsbGluZyBkZXNjIGVudHJ5ICVkLCAiCgkJCQkgICAgICAgIlRDQjogMHglcFxuIiwKCQkJCSAgICAgICAocFBhY2tldC0+bGVuIC0gcFBhY2tldC0+ZGF0YV9sZW4pLAoJCQkJICAgICAgIHBBZGFwdGVyLT5UeFJpbmcudHhEbWFSZWFkeVRvU2VuZC5iaXRzLgoJCQkJICAgICAgIHZhbCwgcE1wVGNiKTsKCgkJCQlDdXJEZXNjW0ZyYWdtZW50TnVtYmVyXS5EYXRhQnVmZmVyUHRySGlnaCA9IDA7CgoJCQkJQ3VyRGVzY1tGcmFnbWVudE51bWJlcl0ud29yZDIuYml0cy4KCQkJCSAgICBsZW5ndGhfaW5fYnl0ZXMgPQoJCQkJICAgICgocFBhY2tldC0+bGVuIC0gcFBhY2tldC0+ZGF0YV9sZW4pIC8gMik7CgoJCQkJLyogTk9URTogSGVyZSwgdGhlIGRtYV9hZGRyX3QgcmV0dXJuZWQgZnJvbQoJCQkJICogcGNpX21hcF9zaW5nbGUoKSBpcyBpbXBsaWNpdGx5IGNhc3QgYXMgYQoJCQkJICogdWludDMyX3QuIEFsdGhvdWdoIGRtYV9hZGRyX3QgY2FuIGJlCgkJCQkgKiA2NC1iaXQsIHRoZSBhZGRyZXNzIHJldHVybmVkIGJ5CgkJCQkgKiBwY2lfbWFwX3NpbmdsZSgpIGlzIGFsd2F5cyAzMi1iaXQKCQkJCSAqIGFkZHJlc3NhYmxlIChhcyBkZWZpbmVkIGJ5IHRoZSBwY2kvZG1hCgkJCQkgKiBzdWJzeXN0ZW0pCgkJCQkgKi8KCQkJCUN1ckRlc2NbRnJhZ21lbnROdW1iZXIrK10uRGF0YUJ1ZmZlclB0ckxvdyA9CgkJCQkgICAgcGNpX21hcF9zaW5nbGUocEFkYXB0ZXItPnBkZXYsCgkJCQkJCSAgIHBQYWNrZXQtPmRhdGEsCgkJCQkJCSAgICgocFBhY2tldC0+bGVuIC0KCQkJCQkJICAgICBwUGFja2V0LT5kYXRhX2xlbikgLyAyKSwKCQkJCQkJICAgUENJX0RNQV9UT0RFVklDRSk7CgkJCQlDdXJEZXNjW0ZyYWdtZW50TnVtYmVyXS5EYXRhQnVmZmVyUHRySGlnaCA9IDA7CgoJCQkJQ3VyRGVzY1tGcmFnbWVudE51bWJlcl0ud29yZDIuYml0cy4KCQkJCSAgICBsZW5ndGhfaW5fYnl0ZXMgPQoJCQkJICAgICgocFBhY2tldC0+bGVuIC0gcFBhY2tldC0+ZGF0YV9sZW4pIC8gMik7CgoJCQkJLyogTk9URTogSGVyZSwgdGhlIGRtYV9hZGRyX3QgcmV0dXJuZWQgZnJvbQoJCQkJICogcGNpX21hcF9zaW5nbGUoKSBpcyBpbXBsaWNpdGx5IGNhc3QgYXMgYQoJCQkJICogdWludDMyX3QuIEFsdGhvdWdoIGRtYV9hZGRyX3QgY2FuIGJlCgkJCQkgKiA2NC1iaXQsIHRoZSBhZGRyZXNzIHJldHVybmVkIGJ5CgkJCQkgKiBwY2lfbWFwX3NpbmdsZSgpIGlzIGFsd2F5cyAzMi1iaXQKCQkJCSAqIGFkZHJlc3NhYmxlIChhcyBkZWZpbmVkIGJ5IHRoZSBwY2kvZG1hCgkJCQkgKiBzdWJzeXN0ZW0pCgkJCQkgKi8KCQkJCUN1ckRlc2NbRnJhZ21lbnROdW1iZXIrK10uRGF0YUJ1ZmZlclB0ckxvdyA9CgkJCQkgICAgcGNpX21hcF9zaW5nbGUocEFkYXB0ZXItPnBkZXYsCgkJCQkJCSAgIHBQYWNrZXQtPmRhdGEgKwoJCQkJCQkgICAoKHBQYWNrZXQtPmxlbiAtCgkJCQkJCSAgICAgcFBhY2tldC0+ZGF0YV9sZW4pIC8gMiksCgkJCQkJCSAgICgocFBhY2tldC0+bGVuIC0KCQkJCQkJICAgICBwUGFja2V0LT5kYXRhX2xlbikgLyAyKSwKCQkJCQkJICAgUENJX0RNQV9UT0RFVklDRSk7CgkJCX0KCQl9IGVsc2UgewoJCQlEQkdfVFgoZXQxMzF4X2RiZ2luZm8sCgkJCSAgICAgICAiR290IHBhY2tldCBvZiBsZW5ndGggJWQsIgoJCQkgICAgICAgImZpbGxpbmcgZGVzYyBlbnRyeSAlZFxuIgoJCQkgICAgICAgIlRDQjogMHglcFxuIiwKCQkJICAgICAgIHBGcmFnTGlzdFtsb29wSW5kZXhdLnNpemUsCgkJCSAgICAgICBwQWRhcHRlci0+VHhSaW5nLnR4RG1hUmVhZHlUb1NlbmQuYml0cy52YWwsCgkJCSAgICAgICBwTXBUY2IpOwoKCQkJQ3VyRGVzY1tGcmFnbWVudE51bWJlcl0uRGF0YUJ1ZmZlclB0ckhpZ2ggPSAwOwoKCQkJQ3VyRGVzY1tGcmFnbWVudE51bWJlcl0ud29yZDIuYml0cy5sZW5ndGhfaW5fYnl0ZXMgPQoJCQkgICAgcEZyYWdMaXN0W2xvb3BJbmRleCAtIDFdLnNpemU7CgoJCQkvKiBOT1RFOiBIZXJlLCB0aGUgZG1hX2FkZHJfdCByZXR1cm5lZCBmcm9tCgkJCSAqIHBjaV9tYXBfcGFnZSgpIGlzIGltcGxpY2l0bHkgY2FzdCBhcyBhIHVpbnQzMl90LgoJCQkgKiBBbHRob3VnaCBkbWFfYWRkcl90IGNhbiBiZSA2NC1iaXQsIHRoZSBhZGRyZXNzCgkJCSAqIHJldHVybmVkIGJ5IHBjaV9tYXBfcGFnZSgpIGlzIGFsd2F5cyAzMi1iaXQKCQkJICogYWRkcmVzc2FibGUgKGFzIGRlZmluZWQgYnkgdGhlIHBjaS9kbWEgc3Vic3lzdGVtKQoJCQkgKi8KCQkJQ3VyRGVzY1tGcmFnbWVudE51bWJlcisrXS5EYXRhQnVmZmVyUHRyTG93ID0KCQkJICAgIHBjaV9tYXBfcGFnZShwQWRhcHRlci0+cGRldiwKCQkJCQkgcEZyYWdMaXN0W2xvb3BJbmRleCAtIDFdLnBhZ2UsCgkJCQkJIHBGcmFnTGlzdFtsb29wSW5kZXggLSAxXS5wYWdlX29mZnNldCwKCQkJCQkgcEZyYWdMaXN0W2xvb3BJbmRleCAtIDFdLnNpemUsCgkJCQkJIFBDSV9ETUFfVE9ERVZJQ0UpOwoJCX0KCX0KCglpZiAoRnJhZ21lbnROdW1iZXIgPT0gMCkgewoJCURCR19XQVJOSU5HKGV0MTMxeF9kYmdpbmZvLCAiTm8uIGZyYWdzIGlzIDBcbiIpOwoJCXJldHVybiAtRUlPOwoJfQoKCWlmIChwQWRhcHRlci0+dWlMaW5rU3BlZWQgPT0gVFJVRVBIWV9TUEVFRF8xMDAwTUJQUykgewoJCWlmICgrK3BBZGFwdGVyLT5UeFJpbmcuVHhQYWNrZXRzU2luY2VMYXN0aW50ZXJydXB0ID09CgkJICAgIHBBZGFwdGVyLT5SZWdpc3RyeVR4TnVtQnVmZmVycykgewoJCQlDdXJEZXNjW0ZyYWdtZW50TnVtYmVyIC0gMV0ud29yZDMudmFsdWUgPSAweDU7CgkJCXBBZGFwdGVyLT5UeFJpbmcuVHhQYWNrZXRzU2luY2VMYXN0aW50ZXJydXB0ID0gMDsKCQl9IGVsc2UgewoJCQlDdXJEZXNjW0ZyYWdtZW50TnVtYmVyIC0gMV0ud29yZDMudmFsdWUgPSAweDE7CgkJfQoJfSBlbHNlIHsKCQlDdXJEZXNjW0ZyYWdtZW50TnVtYmVyIC0gMV0ud29yZDMudmFsdWUgPSAweDU7Cgl9CgoJQ3VyRGVzY1swXS53b3JkMy5iaXRzLmYgPSAxOwoKCXBNcFRjYi0+V3JJbmRleFN0YXJ0ID0gcEFkYXB0ZXItPlR4UmluZy50eERtYVJlYWR5VG9TZW5kOwoJcE1wVGNiLT5QYWNrZXRTdGFsZUNvdW50ID0gMDsKCglzcGluX2xvY2tfaXJxc2F2ZSgmcEFkYXB0ZXItPlNlbmRIV0xvY2ssIGxvY2tmbGFnczEpOwoKCWlUaGlzQ29weSA9CgkgICAgTlVNX0RFU0NfUEVSX1JJTkdfVFggLSBwQWRhcHRlci0+VHhSaW5nLnR4RG1hUmVhZHlUb1NlbmQuYml0cy52YWw7CgoJaWYgKGlUaGlzQ29weSA+PSBGcmFnbWVudE51bWJlcikgewoJCWlSZW1haW5kZXIgPSAwOwoJCWlUaGlzQ29weSA9IEZyYWdtZW50TnVtYmVyOwoJfSBlbHNlIHsKCQlpUmVtYWluZGVyID0gRnJhZ21lbnROdW1iZXIgLSBpVGhpc0NvcHk7Cgl9CgoJbWVtY3B5KHBBZGFwdGVyLT5UeFJpbmcucFR4RGVzY1JpbmdWYSArCgkgICAgICAgcEFkYXB0ZXItPlR4UmluZy50eERtYVJlYWR5VG9TZW5kLmJpdHMudmFsLCBDdXJEZXNjLAoJICAgICAgIHNpemVvZihUWF9ERVNDX0VOVFJZX3QpICogaVRoaXNDb3B5KTsKCglwQWRhcHRlci0+VHhSaW5nLnR4RG1hUmVhZHlUb1NlbmQuYml0cy52YWwgKz0gaVRoaXNDb3B5OwoKCWlmICgocEFkYXB0ZXItPlR4UmluZy50eERtYVJlYWR5VG9TZW5kLmJpdHMudmFsID09IDApIHx8CgkgICAgKHBBZGFwdGVyLT5UeFJpbmcudHhEbWFSZWFkeVRvU2VuZC5iaXRzLnZhbCA9PQoJICAgICBOVU1fREVTQ19QRVJfUklOR19UWCkpIHsKCQlpZiAocEFkYXB0ZXItPlR4UmluZy50eERtYVJlYWR5VG9TZW5kLmJpdHMud3JhcCkgewoJCQlwQWRhcHRlci0+VHhSaW5nLnR4RG1hUmVhZHlUb1NlbmQudmFsdWUgPSAwOwoJCX0gZWxzZSB7CgkJCXBBZGFwdGVyLT5UeFJpbmcudHhEbWFSZWFkeVRvU2VuZC52YWx1ZSA9IDB4NDAwOwoJCX0KCX0KCglpZiAoaVJlbWFpbmRlcikgewoJCW1lbWNweShwQWRhcHRlci0+VHhSaW5nLnBUeERlc2NSaW5nVmEsCgkJICAgICAgIEN1ckRlc2MgKyBpVGhpc0NvcHksCgkJICAgICAgIHNpemVvZihUWF9ERVNDX0VOVFJZX3QpICogaVJlbWFpbmRlcik7CgoJCXBBZGFwdGVyLT5UeFJpbmcudHhEbWFSZWFkeVRvU2VuZC5iaXRzLnZhbCArPSBpUmVtYWluZGVyOwoJfQoKCWlmIChwQWRhcHRlci0+VHhSaW5nLnR4RG1hUmVhZHlUb1NlbmQuYml0cy52YWwgPT0gMCkgewoJCWlmIChwQWRhcHRlci0+VHhSaW5nLnR4RG1hUmVhZHlUb1NlbmQudmFsdWUpIHsKCQkJcE1wVGNiLT5XckluZGV4LnZhbHVlID0gTlVNX0RFU0NfUEVSX1JJTkdfVFggLSAxOwoJCX0gZWxzZSB7CgkJCXBNcFRjYi0+V3JJbmRleC52YWx1ZSA9CgkJCSAgICAweDQwMCB8IChOVU1fREVTQ19QRVJfUklOR19UWCAtIDEpOwoJCX0KCX0gZWxzZSB7CgkJcE1wVGNiLT5XckluZGV4LnZhbHVlID0KCQkgICAgcEFkYXB0ZXItPlR4UmluZy50eERtYVJlYWR5VG9TZW5kLnZhbHVlIC0gMTsKCX0KCglzcGluX2xvY2tfaXJxc2F2ZSgmcEFkYXB0ZXItPlRDQlNlbmRRTG9jaywgbG9ja2ZsYWdzMik7CgoJaWYgKHBBZGFwdGVyLT5UeFJpbmcuQ3VyclNlbmRUYWlsKSB7CgkJcEFkYXB0ZXItPlR4UmluZy5DdXJyU2VuZFRhaWwtPk5leHQgPSBwTXBUY2I7Cgl9IGVsc2UgewoJCXBBZGFwdGVyLT5UeFJpbmcuQ3VyclNlbmRIZWFkID0gcE1wVGNiOwoJfQoKCXBBZGFwdGVyLT5UeFJpbmcuQ3VyclNlbmRUYWlsID0gcE1wVGNiOwoKCURCR19BU1NFUlQocE1wVGNiLT5OZXh0ID09IE5VTEwpOwoKCXBBZGFwdGVyLT5UeFJpbmcubkJ1c3lTZW5kKys7CgoJc3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmcEFkYXB0ZXItPlRDQlNlbmRRTG9jaywgbG9ja2ZsYWdzMik7CgoJLyogV3JpdGUgdGhlIG5ldyB3cml0ZSBwb2ludGVyIGJhY2sgdG8gdGhlIGRldmljZS4gKi8KCXdyaXRlbChwQWRhcHRlci0+VHhSaW5nLnR4RG1hUmVhZHlUb1NlbmQudmFsdWUsCgkgICAgICAgJnBBZGFwdGVyLT5DU1JBZGRyZXNzLT50eGRtYS5zZXJ2aWNlX3JlcXVlc3QudmFsdWUpOwoKCS8qIEZvciBHaWcgb25seSwgd2UgdXNlIFR4IEludGVycnVwdCBjb2FsZXNjaW5nLiAgRW5hYmxlIHRoZSBzb2Z0d2FyZQoJICogdGltZXIgdG8gd2FrZSB1cyB1cCBpZiB0aGlzIHBhY2tldCBpc24ndCBmb2xsb3dlZCBieSBOIG1vcmUuCgkgKi8KCWlmIChwQWRhcHRlci0+dWlMaW5rU3BlZWQgPT0gVFJVRVBIWV9TUEVFRF8xMDAwTUJQUykgewoJCXdyaXRlbChwQWRhcHRlci0+UmVnaXN0cnlUeFRpbWVJbnRlcnZhbCAqIE5BTk9fSU5fQV9NSUNSTywKCQkgICAgICAgJnBBZGFwdGVyLT5DU1JBZGRyZXNzLT5nbG9iYWwud2F0Y2hkb2dfdGltZXIpOwoJfQoKCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJnBBZGFwdGVyLT5TZW5kSFdMb2NrLCBsb2NrZmxhZ3MxKTsKCglEQkdfVFhfTEVBVkUoZXQxMzF4X2RiZ2luZm8pOwoJcmV0dXJuIDA7Cn0KCi8qCiAqIE5PVEU6IEZvciBub3csIGtlZXAgdGhpcyBvbGRlciB2ZXJzaW9uIG9mIE5JQ1NlbmRQYWNrZXQgYXJvdW5kIGZvcgogKiByZWZlcmVuY2UsIGV2ZW4gdGhvdWdoIGl0J3Mgbm90IHVzZWQKICovCiNpZiAwCgovKioKICogTklDU2VuZFBhY2tldCAtIE5JQyBzcGVjaWZpYyBzZW5kIGhhbmRsZXIuCiAqIEBwQWRhcHRlcjogcG9pbnRlciB0byBvdXIgYWRhcHRlcgogKiBAcE1wVGNiOiBwb2ludGVyIHRvIE1QX1RDQgogKgogKiBSZXR1cm5zIDAgb24gc3VjY2VzLCBlcnJubyBvbiBmYWlsdXJlLgogKgogKiBUaGlzIHZlcnNpb24gb2YgdGhlIHNlbmQgcm91dGluZSBpcyBkZXNpZ25lZCBmb3IgdmVyc2lvbiBBIHNpbGljb24uCiAqIEFzc3VtcHRpb24gLSBTZW5kIHNwaW5sb2NrIGhhcyBiZWVuIGFjcXVpcmVkLgogKi8Kc3RhdGljIGludCBuaWNfc2VuZF9wYWNrZXQoc3RydWN0IGV0MTMxeF9hZGFwdGVyICpwQWRhcHRlciwgUE1QX1RDQiBwTXBUY2IpCnsKCXVpbnQzMl90IGxvb3BJbmRleCwgZnJhZ0luZGV4LCBsb29wRW5kOwoJdWludDMyX3QgaVNwbGl0Rmlyc3RFbGVtZW50ID0gMDsKCXVpbnQzMl90IFNlZ21lbnRTaXplID0gMDsKCVRYX0RFU0NfRU5UUllfdCBDdXJEZXNjOwoJVFhfREVTQ19FTlRSWV90ICpDdXJEZXNjUG9zdENvcHkgPSBOVUxMOwoJdWludDMyX3QgU2xvdHNBdmFpbGFibGU7CglETUExMFdfdCBTZXJ2aWNlQ29tcGxldGU7Cgl1bnNpZ25lZCBpbnQgbG9ja2ZsYWdzMSwgbG9ja2ZsYWdzMjsKCXN0cnVjdCBza19idWZmICpwUGFja2V0ID0gcE1wVGNiLT5QYWNrZXQ7Cgl1aW50MzJfdCBGcmFnTGlzdENvdW50ID0gc2tiX3NoaW5mbyhwUGFja2V0KS0+bnJfZnJhZ3MgKyAxOwoJc3RydWN0IHNrYl9mcmFnX3N0cnVjdCAqcEZyYWdMaXN0ID0gJnNrYl9zaGluZm8ocFBhY2tldCktPmZyYWdzWzBdOwoKCURCR19UWF9FTlRFUihldDEzMXhfZGJnaW5mbyk7CgoJU2VydmljZUNvbXBsZXRlLnZhbHVlID0KCQlyZWFkbCgmcEFkYXB0ZXItPkNTUkFkZHJlc3MtPnR4ZG1hLk5ld1NlcnZpY2VDb21wbGV0ZS52YWx1ZSk7CgoJLyoKCSAqIEF0dGVtcHQgdG8gZml4IFRXTyBoYXJkd2FyZSBidWdzOgoJICogMSkgIE5FVkVSIHdyaXRlIGFuIG9kZCBudW1iZXIgb2YgZGVzY3JpcHRvcnMuCgkgKiAyKSAgSWYgcGFja2V0IGxlbmd0aCBpcyBsZXNzIHRoYW4gTklDX01JTl9QQUNLRVRfU0laRSwgdGhlbiBwYWQgdGhlCgkgKiAgICAgcGFja2V0IHRvIE5JQ19NSU5fUEFDS0VUX1NJWkUgYnl0ZXMgYnkgYWRkaW5nIGEgbmV3IGxhc3QKCSAqICAgICBkZXNjcmlwdG9yIElOIEhBTEYgRFVQTEVYIE1PREUgT05MWQoJICogTk9URSB0aGF0ICgyKSBpbnRlcmFjdHMgd2l0aCAoMSkuICBJZiB0aGUgcGFja2V0IGlzIGxlc3MgdGhhbgoJICogTklDX01JTl9QQUNLRVRfU0laRSBieXRlcyB0aGVuIHdlIHdpbGwgYXBwZW5kIGEgZGVzY3JpcHRvci4KCSAqIFRoZXJlZm9yZSBpZiBpdCBpcyBldmVuIG5vdywgaXQgd2lsbCBldmVudHVhbGx5IGVuZCB1cCBvZGQsIGFuZAoJICogc28gd2lsbCBuZWVkIGFkanVzdGluZy4KCSAqCgkgKiBWTEFOIHRhZ3MgZ2V0IGludm9sdmVkIHNpbmNlIFZMQU4gdGFncyBhZGQgYW5vdGhlciBvbmUgb3IgdHdvCgkgKiBzZWdtZW50cy4KCSAqLwoJREJHX1RYKGV0MTMxeF9kYmdpbmZvLAoJICAgICAgICJwTXBUY2ItPlBhY2tldExlbmd0aDogJWRcbiIsIHBNcFRjYi0+UGFja2V0TGVuZ3RoKTsKCglpZiAoKHBBZGFwdGVyLT51aUR1cGxleE1vZGUgPT0gMCkKCSAgICAmJiAocE1wVGNiLT5QYWNrZXRMZW5ndGggPCBOSUNfTUlOX1BBQ0tFVF9TSVpFKSkgewoJCURCR19UWChldDEzMXhfZGJnaW5mbywKCQkgICAgICAgIkhBTEYgRFVQTEVYIG1vZGUgQU5EIGxlbiA8IE1JTl9QS1RfU0laRVxuIik7CgkJaWYgKChGcmFnTGlzdENvdW50ICYgMHgxKSA9PSAwKSB7CgkJCURCR19UWChldDEzMXhfZGJnaW5mbywKCQkJICAgICAgICJFdmVuIG51bWJlciBvZiBkZXNjcywgc3BsaXQgMXN0IGVsZW1cbiIpOwoJCQlpU3BsaXRGaXJzdEVsZW1lbnQgPSAxOwoJCQkvL1NlZ21lbnRTaXplID0gcEZyYWdMaXN0WzBdLnNpemUgLyAyOwoJCQlTZWdtZW50U2l6ZSA9IChwUGFja2V0LT5sZW4gLSBwUGFja2V0LT5kYXRhX2xlbikgLyAyOwoJCX0KCX0gZWxzZSBpZiAoRnJhZ0xpc3RDb3VudCAmIDB4MSkgewoJCURCR19UWChldDEzMXhfZGJnaW5mbywgIk9kZCBudW1iZXIgb2YgZGVzY3MsIHNwbGl0IDFzdCBlbGVtXG4iKTsKCgkJaVNwbGl0Rmlyc3RFbGVtZW50ID0gMTsKCQkvL1NlZ21lbnRTaXplID0gcEZyYWdMaXN0WzBdLnNpemUgLyAyOwoJCVNlZ21lbnRTaXplID0gKHBQYWNrZXQtPmxlbiAtIHBQYWNrZXQtPmRhdGFfbGVuKSAvIDI7Cgl9CgoJc3Bpbl9sb2NrX2lycXNhdmUoJnBBZGFwdGVyLT5TZW5kSFdMb2NrLCBsb2NrZmxhZ3MxKTsKCglpZiAocEFkYXB0ZXItPlR4UmluZy50eERtYVJlYWR5VG9TZW5kLmJpdHMuc2Vydl9yZXFfd3JhcCA9PQoJICAgIFNlcnZpY2VDb21wbGV0ZS5iaXRzLnNlcnZfY3BsX3dyYXApIHsKCQkvKiBUaGUgcmluZyBoYXNuJ3Qgd3JhcHBlZC4gIFNsb3RzIGF2YWlsYWJsZSBzaG91bGQgYmUKCQkgKiAoUklOR19TSVpFKSAtICB0aGUgZGlmZmVyZW5jZSBiZXR3ZWVuIHRoZSB0d28gcG9pbnRlcnMuCgkJICovCgkJU2xvdHNBdmFpbGFibGUgPSBOVU1fREVTQ19QRVJfUklOR19UWCAtCgkJICAgIChwQWRhcHRlci0+VHhSaW5nLnR4RG1hUmVhZHlUb1NlbmQuYml0cy5zZXJ2X3JlcSAtCgkJICAgICBTZXJ2aWNlQ29tcGxldGUuYml0cy5zZXJ2X2NwbCk7Cgl9IGVsc2UgewoJCS8qIFRoZSByaW5nIGhhcyB3cmFwcGVkLiAgU2xvdHMgYXZhaWxhYmxlIHNob3VsZCBiZSB0aGUKCQkgKiBkaWZmZXJlbmNlIGJldHdlZW4gdGhlIHR3byBwb2ludGVycy4KCQkgKi8KCQlTbG90c0F2YWlsYWJsZSA9IFNlcnZpY2VDb21wbGV0ZS5iaXRzLnNlcnZfY3BsIC0KCQkgICAgcEFkYXB0ZXItPlR4UmluZy50eERtYVJlYWR5VG9TZW5kLmJpdHMuc2Vydl9yZXE7Cgl9CgoJaWYgKChGcmFnTGlzdENvdW50ICsgaVNwbGl0Rmlyc3RFbGVtZW50KSA+IFNsb3RzQXZhaWxhYmxlKSB7CgkJREJHX1dBUk5JTkcoZXQxMzF4X2RiZ2luZm8sCgkJCSAgICAiTm90IEVub3VnaCBTcGFjZSBpbiBUeCBEZXNjIFJpbmdcbiIpOwoJCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJnBBZGFwdGVyLT5TZW5kSFdMb2NrLCBsb2NrZmxhZ3MxKTsKCQlyZXR1cm4gLUVOT01FTTsKCX0KCglsb29wRW5kID0gKEZyYWdMaXN0Q291bnQpICsgaVNwbGl0Rmlyc3RFbGVtZW50OwoJZnJhZ0luZGV4ID0gMDsKCglEQkdfVFgoZXQxMzF4X2RiZ2luZm8sCgkgICAgICAgIlRDQiAgICAgICAgICAgOiAweCVwXG4iCgkgICAgICAgIlBhY2tldCAoU0tCKSAgOiAweCVwXHQgUGFja2V0LT5sZW46ICVkXHQgUGFja2V0LT5kYXRhX2xlbjogJWRcbiIKCSAgICAgICAiRnJhZ0xpc3RDb3VudCA6ICVkXHQgaVNwbGl0Rmlyc3RFbGVtZW50OiAlZFx0IGxvb3BFbmQ6JWRcbiIsCgkgICAgICAgcE1wVGNiLAoJICAgICAgIHBQYWNrZXQsIHBQYWNrZXQtPmxlbiwgcFBhY2tldC0+ZGF0YV9sZW4sCgkgICAgICAgRnJhZ0xpc3RDb3VudCwgaVNwbGl0Rmlyc3RFbGVtZW50LCBsb29wRW5kKTsKCglmb3IgKGxvb3BJbmRleCA9IDA7IGxvb3BJbmRleCA8IGxvb3BFbmQ7IGxvb3BJbmRleCsrKSB7CgkJaWYgKGxvb3BJbmRleCA+IGlTcGxpdEZpcnN0RWxlbWVudCkgewoJCQlmcmFnSW5kZXgrKzsKCQl9CgoJCURCR19UWChldDEzMXhfZGJnaW5mbywKCQkgICAgICAgIkluIGxvb3AsIGxvb3BJbmRleDogJWRcdCBmcmFnSW5kZXg6ICVkXG4iLCBsb29wSW5kZXgsCgkJICAgICAgIGZyYWdJbmRleCk7CgoJCS8qIElmIHRoZXJlIGlzIHNvbWV0aGluZyBpbiB0aGlzIGVsZW1lbnQsIGxldCdzIGdldCBhCgkJICogZGVzY3JpcHRvciBmcm9tIHRoZSByaW5nIGFuZCBnZXQgdGhlIG5lY2Vzc2FyeSBkYXRhCgkJICovCgkJREJHX1RYKGV0MTMxeF9kYmdpbmZvLAoJCSAgICAgICAiUGFja2V0IExlbmd0aCAlZCwiCgkJICAgICAgICJmaWxsaW5nIGRlc2MgZW50cnkgJWRcbiIsCgkJICAgICAgIHBQYWNrZXQtPmxlbiwKCQkgICAgICAgcEFkYXB0ZXItPlR4UmluZy50eERtYVJlYWR5VG9TZW5kLmJpdHMuc2Vydl9yZXEpOwoKCQkvLyBOT1RFIC0gU2hvdWxkIHdlIGRvIGEgcGFyYW5vaWEgY2hlY2sgaGVyZSB0byBtYWtlIHN1cmUgdGhlIGZyYWdtZW50CgkJLy8gYWN0dWFsbHkgaGFzIGEgbGVuZ3RoPyBJdCdzIEhJR0hMWSB1bmxpa2VseSB0aGUgZnJhZ21lbnQgd291bGQKCQkvLyBjb250YWluIG5vIGRhdGEuLi4KCQlpZiAoMSkgewoJCQkvLyBOT1RFIC0gQ3VycmVudGx5IGFsd2F5cyBnZXR0aW5nIDMyLWJpdCBhZGRycywgYW5kIGRtYV9hZGRyX3QgaXMKCQkJLy8gICAgICAgIG9ubHkgMzItYml0LCBzbyBsZWF2ZSAiaGlnaCIgcHRyIHZhbHVlIG91dCBmb3Igbm93CgkJCUN1ckRlc2MuRGF0YUJ1ZmZlclB0ckhpZ2ggPSAwOwoKCQkJQ3VyRGVzYy53b3JkMi52YWx1ZSA9IDA7CgkJCUN1ckRlc2Mud29yZDMudmFsdWUgPSAwOwoKCQkJaWYgKGZyYWdJbmRleCA9PSAwKSB7CgkJCQlpZiAoaVNwbGl0Rmlyc3RFbGVtZW50KSB7CgkJCQkJREJHX1RYKGV0MTMxeF9kYmdpbmZvLAoJCQkJCSAgICAgICAiU3BsaXQgZmlyc3QgZWxlbWVudDogWUVTXG4iKTsKCgkJCQkJaWYgKGxvb3BJbmRleCA9PSAwKSB7CgkJCQkJCURCR19UWChldDEzMXhfZGJnaW5mbywKCQkJCQkJICAgICAgICJHb3QgZnJhZ21lbnQgb2YgbGVuZ3RoICVkLCBmcmFnSW5kZXg6ICVkXG4iLAoJCQkJCQkgICAgICAgcFBhY2tldC0+bGVuIC0KCQkJCQkJICAgICAgIHBQYWNrZXQtPmRhdGFfbGVuLAoJCQkJCQkgICAgICAgZnJhZ0luZGV4KTsKCQkJCQkJREJHX1RYKGV0MTMxeF9kYmdpbmZvLAoJCQkJCQkgICAgICAgIlNlZ21lbnRTaXplOiAlZFxuIiwKCQkJCQkJICAgICAgIFNlZ21lbnRTaXplKTsKCgkJCQkJCUN1ckRlc2Mud29yZDIuYml0cy4KCQkJCQkJICAgIGxlbmd0aF9pbl9ieXRlcyA9CgkJCQkJCSAgICBTZWdtZW50U2l6ZTsKCQkJCQkJQ3VyRGVzYy5EYXRhQnVmZmVyUHRyTG93ID0KCQkJCQkJICAgIHBjaV9tYXBfc2luZ2xlKHBBZGFwdGVyLT4KCQkJCQkJCQkgICBwZGV2LAoJCQkJCQkJCSAgIHBQYWNrZXQtPgoJCQkJCQkJCSAgIGRhdGEsCgkJCQkJCQkJICAgU2VnbWVudFNpemUsCgkJCQkJCQkJICAgUENJX0RNQV9UT0RFVklDRSk7CgkJCQkJCURCR19UWChldDEzMXhfZGJnaW5mbywKCQkJCQkJICAgICAgICJwY2lfbWFwX3NpbmdsZSgpIHJldHVybnM6IDB4JTA4eFxuIiwKCQkJCQkJICAgICAgIEN1ckRlc2MuCgkJCQkJCSAgICAgICBEYXRhQnVmZmVyUHRyTG93KTsKCQkJCQl9IGVsc2UgewoJCQkJCQlEQkdfVFgoZXQxMzF4X2RiZ2luZm8sCgkJCQkJCSAgICAgICAiR290IGZyYWdtZW50IG9mIGxlbmd0aCAlZCwgZnJhZ0luZGV4OiAlZFxuIiwKCQkJCQkJICAgICAgIHBQYWNrZXQtPmxlbiAtCgkJCQkJCSAgICAgICBwUGFja2V0LT5kYXRhX2xlbiwKCQkJCQkJICAgICAgIGZyYWdJbmRleCk7CgkJCQkJCURCR19UWChldDEzMXhfZGJnaW5mbywKCQkJCQkJICAgICAgICJMZWZ0b3ZlciBTaXplOiAlZFxuIiwKCQkJCQkJICAgICAgIChwUGFja2V0LT5sZW4gLQoJCQkJCQkJcFBhY2tldC0+ZGF0YV9sZW4gLQoJCQkJCQkJU2VnbWVudFNpemUpKTsKCgkJCQkJCUN1ckRlc2Mud29yZDIuYml0cy4KCQkJCQkJICAgIGxlbmd0aF9pbl9ieXRlcyA9CgkJCQkJCSAgICAoKHBQYWNrZXQtPmxlbiAtCgkJCQkJCSAgICAgIHBQYWNrZXQtPmRhdGFfbGVuKSAtCgkJCQkJCSAgICAgU2VnbWVudFNpemUpOwoJCQkJCQlDdXJEZXNjLkRhdGFCdWZmZXJQdHJMb3cgPQoJCQkJCQkgICAgcGNpX21hcF9zaW5nbGUocEFkYXB0ZXItPgoJCQkJCQkJCSAgIHBkZXYsCgkJCQkJCQkJICAgKHBQYWNrZXQtPgoJCQkJCQkJCSAgICBkYXRhICsKCQkJCQkJCQkgICAgU2VnbWVudFNpemUpLAoJCQkJCQkJCSAgIChwUGFja2V0LT4KCQkJCQkJCQkgICAgbGVuIC0KCQkJCQkJCQkgICAgcFBhY2tldC0+CgkJCQkJCQkJICAgIGRhdGFfbGVuIC0KCQkJCQkJCQkgICAgU2VnbWVudFNpemUpLAoJCQkJCQkJCSAgIFBDSV9ETUFfVE9ERVZJQ0UpOwoJCQkJCQlEQkdfVFgoZXQxMzF4X2RiZ2luZm8sCgkJCQkJCSAgICAgICAicGNpX21hcF9zaW5nbGUoKSByZXR1cm5zOiAweCUwOHhcbiIsCgkJCQkJCSAgICAgICBDdXJEZXNjLgoJCQkJCQkgICAgICAgRGF0YUJ1ZmZlclB0ckxvdyk7CgkJCQkJfQoJCQkJfSBlbHNlIHsKCQkJCQlEQkdfVFgoZXQxMzF4X2RiZ2luZm8sCgkJCQkJICAgICAgICJTcGxpdCBmaXJzdCBlbGVtZW50OiBOT1xuIik7CgoJCQkJCUN1ckRlc2Mud29yZDIuYml0cy5sZW5ndGhfaW5fYnl0ZXMgPQoJCQkJCSAgICBwUGFja2V0LT5sZW4gLSBwUGFja2V0LT5kYXRhX2xlbjsKCgkJCQkJQ3VyRGVzYy5EYXRhQnVmZmVyUHRyTG93ID0KCQkJCQkgICAgcGNpX21hcF9zaW5nbGUocEFkYXB0ZXItPnBkZXYsCgkJCQkJCQkgICBwUGFja2V0LT5kYXRhLAoJCQkJCQkJICAgKHBQYWNrZXQtPmxlbiAtCgkJCQkJCQkgICAgcFBhY2tldC0+ZGF0YV9sZW4pLAoJCQkJCQkJICAgUENJX0RNQV9UT0RFVklDRSk7CgkJCQkJREJHX1RYKGV0MTMxeF9kYmdpbmZvLAoJCQkJCSAgICAgICAicGNpX21hcF9zaW5nbGUoKSByZXR1cm5zOiAweCUwOHhcbiIsCgkJCQkJICAgICAgIEN1ckRlc2MuRGF0YUJ1ZmZlclB0ckxvdyk7CgkJCQl9CgkJCX0gZWxzZSB7CgoJCQkJQ3VyRGVzYy53b3JkMi5iaXRzLmxlbmd0aF9pbl9ieXRlcyA9CgkJCQkgICAgcEZyYWdMaXN0W2ZyYWdJbmRleCAtIDFdLnNpemU7CgkJCQlDdXJEZXNjLkRhdGFCdWZmZXJQdHJMb3cgPQoJCQkJICAgIHBjaV9tYXBfcGFnZShwQWRhcHRlci0+cGRldiwKCQkJCQkJIHBGcmFnTGlzdFtmcmFnSW5kZXggLSAxXS5wYWdlLAoJCQkJCQkgcEZyYWdMaXN0W2ZyYWdJbmRleCAtCgkJCQkJCQkgICAxXS5wYWdlX29mZnNldCwKCQkJCQkJIHBGcmFnTGlzdFtmcmFnSW5kZXggLSAxXS5zaXplLAoJCQkJCQkgUENJX0RNQV9UT0RFVklDRSk7CgkJCQlEQkdfVFgoZXQxMzF4X2RiZ2luZm8sCgkJCQkgICAgICAgInBjaV9tYXBfcGFnZSgpIHJldHVybnM6IDB4JTA4eFxuIiwKCQkJCSAgICAgICBDdXJEZXNjLkRhdGFCdWZmZXJQdHJMb3cpOwoJCQl9CgoJCQlpZiAobG9vcEluZGV4ID09IDApIHsKCQkJCS8qIFRoaXMgaXMgdGhlIGZpcnN0IGRlc2NyaXB0b3Igb2YgdGhlIHBhY2tldAoJCQkJICoKCQkJCSAqIFNldCB0aGUgImYiIGJpdCB0byBpbmRpY2F0ZSB0aGlzIGlzIHRoZQoJCQkJICogZmlyc3QgZGVzY3JpcHRvciBpbiB0aGUgcGFja2V0LgoJCQkJICovCgkJCQlEQkdfVFgoZXQxMzF4X2RiZ2luZm8sCgkJCQkgICAgICAgIlRoaXMgaXMgb3VyIEZJUlNUIGRlc2NyaXB0b3JcbiIpOwoJCQkJQ3VyRGVzYy53b3JkMy5iaXRzLmYgPSAxOwoKCQkJCXBNcFRjYi0+V3JJbmRleFN0YXJ0ID0KCQkJCSAgICBwQWRhcHRlci0+VHhSaW5nLnR4RG1hUmVhZHlUb1NlbmQ7CgkJCX0KCgkJCWlmICgobG9vcEluZGV4ID09IChsb29wRW5kIC0gMSkpICYmCgkJCSAgICAocEFkYXB0ZXItPnVpRHVwbGV4TW9kZSB8fAoJCQkgICAgIChwTXBUY2ItPlBhY2tldExlbmd0aCA+PSBOSUNfTUlOX1BBQ0tFVF9TSVpFKSkpIHsKCQkJCS8qIFRoaXMgaXMgdGhlIExhc3QgZGVzY3JpcHRvciBvZiB0aGUgcGFja2V0ICovCgkJCQlEQkdfVFgoZXQxMzF4X2RiZ2luZm8sCgkJCQkgICAgICAgIlRISVMgaXMgb3VyIExBU1QgZGVzY3JpcHRvclxuIik7CgoJCQkJaWYgKHBBZGFwdGVyLT51aUxpbmtTcGVlZCA9PQoJCQkJICAgIFRSVUVQSFlfU1BFRURfMTAwME1CUFMpIHsKCQkJCQlpZiAoKytwQWRhcHRlci0+VHhSaW5nLgoJCQkJCSAgICBUeFBhY2tldHNTaW5jZUxhc3RpbnRlcnJ1cHQgPj0KCQkJCQkgICAgcEFkYXB0ZXItPlJlZ2lzdHJ5VHhOdW1CdWZmZXJzKSB7CgkJCQkJCUN1ckRlc2Mud29yZDMudmFsdWUgPSAweDU7CgkJCQkJCXBBZGFwdGVyLT5UeFJpbmcuCgkJCQkJCSAgICBUeFBhY2tldHNTaW5jZUxhc3RpbnRlcnJ1cHQKCQkJCQkJICAgID0gMDsKCQkJCQl9IGVsc2UgewoJCQkJCQlDdXJEZXNjLndvcmQzLnZhbHVlID0gMHgxOwoJCQkJCX0KCQkJCX0gZWxzZSB7CgkJCQkJQ3VyRGVzYy53b3JkMy52YWx1ZSA9IDB4NTsKCQkJCX0KCgkJCQkvKiBGb2xsb3dpbmcgaW5kZXggd2lsbCBiZSB1c2VkIGR1cmluZyBmcmVlaW5nCgkJCQkgKiBvZiBwYWNrZXQKCQkJCSAqLwoJCQkJcE1wVGNiLT5XckluZGV4ID0KCQkJCSAgICBwQWRhcHRlci0+VHhSaW5nLnR4RG1hUmVhZHlUb1NlbmQ7CgkJCQlwTXBUY2ItPlBhY2tldFN0YWxlQ291bnQgPSAwOwoJCQl9CgoJCQkvKiBDb3B5IHRoZSBkZXNjcmlwdG9yIChmaWxsZWQgYWJvdmUpIGludG8gdGhlCgkJCSAqIGRlc2NyaXB0b3IgcmluZyBhdCB0aGUgbmV4dCBmcmVlIGVudHJ5LiAgQWR2YW5jZQoJCQkgKiB0aGUgIm5leHQgZnJlZSBlbnRyeSIgdmFyaWFibGUKCQkJICovCgkJCW1lbWNweShwQWRhcHRlci0+VHhSaW5nLnBUeERlc2NSaW5nVmEgKwoJCQkgICAgICAgcEFkYXB0ZXItPlR4UmluZy50eERtYVJlYWR5VG9TZW5kLmJpdHMuc2Vydl9yZXEsCgkJCSAgICAgICAmQ3VyRGVzYywgc2l6ZW9mKFRYX0RFU0NfRU5UUllfdCkpOwoKCQkJQ3VyRGVzY1Bvc3RDb3B5ID0KCQkJICAgIHBBZGFwdGVyLT5UeFJpbmcucFR4RGVzY1JpbmdWYSArCgkJCSAgICBwQWRhcHRlci0+VHhSaW5nLnR4RG1hUmVhZHlUb1NlbmQuYml0cy5zZXJ2X3JlcTsKCgkJCURCR19UWChldDEzMXhfZGJnaW5mbywKCQkJICAgICAgICJDVVJSRU5UIERFU0NSSVBUT1JcbiIKCQkJICAgICAgICJcdEFkZHJlc3MgICAgICAgICAgIDogMHglcFxuIgoJCQkgICAgICAgIlx0RGF0YUJ1ZmZlclB0ckhpZ2ggOiAweCUwOHhcbiIKCQkJICAgICAgICJcdERhdGFCdWZmZXJQdHJMb3cgIDogMHglMDh4XG4iCgkJCSAgICAgICAiXHR3b3JkMiAgICAgICAgICAgICA6IDB4JTA4eFxuIgoJCQkgICAgICAgIlx0d29yZDMgICAgICAgICAgICAgOiAweCUwOHhcbiIsCgkJCSAgICAgICBDdXJEZXNjUG9zdENvcHksCgkJCSAgICAgICBDdXJEZXNjUG9zdENvcHktPkRhdGFCdWZmZXJQdHJIaWdoLAoJCQkgICAgICAgQ3VyRGVzY1Bvc3RDb3B5LT5EYXRhQnVmZmVyUHRyTG93LAoJCQkgICAgICAgQ3VyRGVzY1Bvc3RDb3B5LT53b3JkMi52YWx1ZSwKCQkJICAgICAgIEN1ckRlc2NQb3N0Q29weS0+d29yZDMudmFsdWUpOwoKCQkJaWYgKCsrcEFkYXB0ZXItPlR4UmluZy50eERtYVJlYWR5VG9TZW5kLmJpdHMuc2Vydl9yZXEgPj0KCQkJICAgIE5VTV9ERVNDX1BFUl9SSU5HX1RYKSB7CgkJCQlpZiAocEFkYXB0ZXItPlR4UmluZy50eERtYVJlYWR5VG9TZW5kLmJpdHMuCgkJCQkgICAgc2Vydl9yZXFfd3JhcCkgewoJCQkJCXBBZGFwdGVyLT5UeFJpbmcudHhEbWFSZWFkeVRvU2VuZC4KCQkJCQkgICAgdmFsdWUgPSAwOwoJCQkJfSBlbHNlIHsKCQkJCQlwQWRhcHRlci0+VHhSaW5nLnR4RG1hUmVhZHlUb1NlbmQuCgkJCQkJICAgIHZhbHVlID0gMHg0MDA7CgkJCQl9CgkJCX0KCQl9Cgl9CgoJaWYgKHBBZGFwdGVyLT51aUR1cGxleE1vZGUgPT0gMCAmJgoJICAgIHBNcFRjYi0+UGFja2V0TGVuZ3RoIDwgTklDX01JTl9QQUNLRVRfU0laRSkgewoJCS8vIE5PVEUgLSBTYW1lIDMyLzY0LWJpdCBpc3N1ZSBhcyBhYm92ZS4uLgoJCUN1ckRlc2MuRGF0YUJ1ZmZlclB0ckhpZ2ggPSAweDA7CgkJQ3VyRGVzYy5EYXRhQnVmZmVyUHRyTG93ID0gcEFkYXB0ZXItPlR4UmluZy5wVHhEdW1teUJsa1BhOwoJCUN1ckRlc2Mud29yZDIudmFsdWUgPSAwOwoKCQlpZiAocEFkYXB0ZXItPnVpTGlua1NwZWVkID09IFRSVUVQSFlfU1BFRURfMTAwME1CUFMpIHsKCQkJaWYgKCsrcEFkYXB0ZXItPlR4UmluZy5UeFBhY2tldHNTaW5jZUxhc3RpbnRlcnJ1cHQgPj0KCQkJICAgIHBBZGFwdGVyLT5SZWdpc3RyeVR4TnVtQnVmZmVycykgewoJCQkJQ3VyRGVzYy53b3JkMy52YWx1ZSA9IDB4NTsKCQkJCXBBZGFwdGVyLT5UeFJpbmcuVHhQYWNrZXRzU2luY2VMYXN0aW50ZXJydXB0ID0KCQkJCSAgICAwOwoJCQl9IGVsc2UgewoJCQkJQ3VyRGVzYy53b3JkMy52YWx1ZSA9IDB4MTsKCQkJfQoJCX0gZWxzZSB7CgkJCUN1ckRlc2Mud29yZDMudmFsdWUgPSAweDU7CgkJfQoKCQlDdXJEZXNjLndvcmQyLmJpdHMubGVuZ3RoX2luX2J5dGVzID0KCQkgICAgTklDX01JTl9QQUNLRVRfU0laRSAtIHBNcFRjYi0+UGFja2V0TGVuZ3RoOwoKCQlwTXBUY2ItPldySW5kZXggPSBwQWRhcHRlci0+VHhSaW5nLnR4RG1hUmVhZHlUb1NlbmQ7CgoJCW1lbWNweShwQWRhcHRlci0+VHhSaW5nLnBUeERlc2NSaW5nVmEgKwoJCSAgICAgICBwQWRhcHRlci0+VHhSaW5nLnR4RG1hUmVhZHlUb1NlbmQuYml0cy5zZXJ2X3JlcSwKCQkgICAgICAgJkN1ckRlc2MsIHNpemVvZihUWF9ERVNDX0VOVFJZX3QpKTsKCgkJQ3VyRGVzY1Bvc3RDb3B5ID0KCQkgICAgcEFkYXB0ZXItPlR4UmluZy5wVHhEZXNjUmluZ1ZhICsKCQkgICAgcEFkYXB0ZXItPlR4UmluZy50eERtYVJlYWR5VG9TZW5kLmJpdHMuc2Vydl9yZXE7CgoJCURCR19UWChldDEzMXhfZGJnaW5mbywKCQkgICAgICAgIkNVUlJFTlQgREVTQ1JJUFRPUlxuIgoJCSAgICAgICAiXHRBZGRyZXNzICAgICAgICAgICA6IDB4JXBcbiIKCQkgICAgICAgIlx0RGF0YUJ1ZmZlclB0ckhpZ2ggOiAweCUwOHhcbiIKCQkgICAgICAgIlx0RGF0YUJ1ZmZlclB0ckxvdyAgOiAweCUwOHhcbiIKCQkgICAgICAgIlx0d29yZDIgICAgICAgICAgICAgOiAweCUwOHhcbiIKCQkgICAgICAgIlx0d29yZDMgICAgICAgICAgICAgOiAweCUwOHhcbiIsCgkJICAgICAgIEN1ckRlc2NQb3N0Q29weSwKCQkgICAgICAgQ3VyRGVzY1Bvc3RDb3B5LT5EYXRhQnVmZmVyUHRySGlnaCwKCQkgICAgICAgQ3VyRGVzY1Bvc3RDb3B5LT5EYXRhQnVmZmVyUHRyTG93LAoJCSAgICAgICBDdXJEZXNjUG9zdENvcHktPndvcmQyLnZhbHVlLAoJCSAgICAgICBDdXJEZXNjUG9zdENvcHktPndvcmQzLnZhbHVlKTsKCgkJaWYgKCsrcEFkYXB0ZXItPlR4UmluZy50eERtYVJlYWR5VG9TZW5kLmJpdHMuc2Vydl9yZXEgPj0KCQkgICAgTlVNX0RFU0NfUEVSX1JJTkdfVFgpIHsKCQkJaWYgKHBBZGFwdGVyLT5UeFJpbmcudHhEbWFSZWFkeVRvU2VuZC5iaXRzLgoJCQkgICAgc2Vydl9yZXFfd3JhcCkgewoJCQkJcEFkYXB0ZXItPlR4UmluZy50eERtYVJlYWR5VG9TZW5kLnZhbHVlID0gMDsKCQkJfSBlbHNlIHsKCQkJCXBBZGFwdGVyLT5UeFJpbmcudHhEbWFSZWFkeVRvU2VuZC52YWx1ZSA9IDB4NDAwOwoJCQl9CgkJfQoKCQlEQkdfVFgoZXQxMzF4X2RiZ2luZm8sICJQYWRkaW5nIGRlc2NyaXB0b3IgJWQgYnkgJWQgYnl0ZXNcbiIsCgkJICAgICAgIC8vcEFkYXB0ZXItPlR4UmluZy50eERtYVJlYWR5VG9TZW5kLnZhbHVlLAoJCSAgICAgICBwQWRhcHRlci0+VHhSaW5nLnR4RG1hUmVhZHlUb1NlbmQuYml0cy5zZXJ2X3JlcSwKCQkgICAgICAgTklDX01JTl9QQUNLRVRfU0laRSAtIHBNcFRjYi0+UGFja2V0TGVuZ3RoKTsKCX0KCglzcGluX2xvY2tfaXJxc2F2ZSgmcEFkYXB0ZXItPlRDQlNlbmRRTG9jaywgbG9ja2ZsYWdzMik7CgoJaWYgKHBBZGFwdGVyLT5UeFJpbmcuQ3VyclNlbmRUYWlsKSB7CgkJcEFkYXB0ZXItPlR4UmluZy5DdXJyU2VuZFRhaWwtPk5leHQgPSBwTXBUY2I7Cgl9IGVsc2UgewoJCXBBZGFwdGVyLT5UeFJpbmcuQ3VyclNlbmRIZWFkID0gcE1wVGNiOwoJfQoKCXBBZGFwdGVyLT5UeFJpbmcuQ3VyclNlbmRUYWlsID0gcE1wVGNiOwoKCURCR19BU1NFUlQocE1wVGNiLT5OZXh0ID09IE5VTEwpOwoKCXBBZGFwdGVyLT5UeFJpbmcubkJ1c3lTZW5kKys7CgoJc3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmcEFkYXB0ZXItPlRDQlNlbmRRTG9jaywgbG9ja2ZsYWdzMik7CgoJLyogV3JpdGUgdGhlIG5ldyB3cml0ZSBwb2ludGVyIGJhY2sgdG8gdGhlIGRldmljZS4gKi8KCXdyaXRlbChwQWRhcHRlci0+VHhSaW5nLnR4RG1hUmVhZHlUb1NlbmQudmFsdWUsCgkgICAgICAgJnBBZGFwdGVyLT5DU1JBZGRyZXNzLT50eGRtYS5zZXJ2aWNlX3JlcXVlc3QudmFsdWUpOwoKI2lmZGVmIENPTkZJR19FVDEzMVhfREVCVUcKCUR1bXBEZXZpY2VCbG9jayhEQkdfVFhfT04sIHBBZGFwdGVyLCAxKTsKI2VuZGlmCgoJLyogRm9yIEdpZyBvbmx5LCB3ZSB1c2UgVHggSW50ZXJydXB0IGNvYWxlc2NpbmcuICBFbmFibGUgdGhlIHNvZnR3YXJlCgkgKiB0aW1lciB0byB3YWtlIHVzIHVwIGlmIHRoaXMgcGFja2V0IGlzbid0IGZvbGxvd2VkIGJ5IE4gbW9yZS4KCSAqLwoJaWYgKHBBZGFwdGVyLT51aUxpbmtTcGVlZCA9PSBUUlVFUEhZX1NQRUVEXzEwMDBNQlBTKSB7CgkJd3JpdGVsKHBBZGFwdGVyLT5SZWdpc3RyeVR4VGltZUludGVydmFsICogTkFOT19JTl9BX01JQ1JPLAoJCSAgICAgICAmcEFkYXB0ZXItPkNTUkFkZHJlc3MtPmdsb2JhbC53YXRjaGRvZ190aW1lcik7Cgl9CgoJc3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmcEFkYXB0ZXItPlNlbmRIV0xvY2ssIGxvY2tmbGFnczEpOwoKCURCR19UWF9MRUFWRShldDEzMXhfZGJnaW5mbyk7CglyZXR1cm4gMDsKfQoKI2VuZGlmCgovKioKICogZXQxMzF4X2ZyZWVfc2VuZF9wYWNrZXQgLSBSZWN5Y2xlIGEgTVBfVENCLCBjb21wbGV0ZSB0aGUgcGFja2V0IGlmIG5lY2Vzc2FyeQogKiBAcEFkYXB0ZXI6IHBvaW50ZXIgdG8gb3VyIGFkYXB0ZXIKICogQHBNcFRjYjogcG9pbnRlciB0byBNUF9UQ0IKICoKICogQXNzdW1wdGlvbiAtIFNlbmQgc3BpbmxvY2sgaGFzIGJlZW4gYWNxdWlyZWQKICovCl9faW5saW5lIHZvaWQgZXQxMzF4X2ZyZWVfc2VuZF9wYWNrZXQoc3RydWN0IGV0MTMxeF9hZGFwdGVyICpwQWRhcHRlciwgUE1QX1RDQiBwTXBUY2IpCnsKCXVuc2lnbmVkIGxvbmcgbG9ja2ZsYWdzOwoJVFhfREVTQ19FTlRSWV90ICpkZXNjID0gTlVMTDsKCXN0cnVjdCBuZXRfZGV2aWNlX3N0YXRzICpzdGF0cyA9ICZwQWRhcHRlci0+bmV0X3N0YXRzOwoKCWlmIChNUF9URVNUX0ZMQUcocE1wVGNiLCBmTVBfREVTVF9CUk9BRCkpIHsKCQlhdG9taWNfaW5jKCZwQWRhcHRlci0+U3RhdHMuYnJkY3N0eG10KTsKCX0gZWxzZSBpZiAoTVBfVEVTVF9GTEFHKHBNcFRjYiwgZk1QX0RFU1RfTVVMVEkpKSB7CgkJYXRvbWljX2luYygmcEFkYXB0ZXItPlN0YXRzLm11bHRpeG10KTsKCX0gZWxzZSB7CgkJYXRvbWljX2luYygmcEFkYXB0ZXItPlN0YXRzLnVuaXhtdCk7Cgl9CgoJaWYgKHBNcFRjYi0+UGFja2V0KSB7CgkJc3RhdHMtPnR4X2J5dGVzICs9IHBNcFRjYi0+UGFja2V0LT5sZW47CgoJCS8qIEl0ZXJhdGUgdGhyb3VnaCB0aGUgVFggZGVzY3JpcHRvcnMgb24gdGhlIHJpbmcKCQkgKiBjb3JyZXNwb25kaW5nIHRvIHRoaXMgcGFja2V0IGFuZCB1bWFwIHRoZSBmcmFnbWVudHMKCQkgKiB0aGV5IHBvaW50IHRvCgkJICovCgkJREJHX1RYKGV0MTMxeF9kYmdpbmZvLAoJCSAgICAgICAiVW5tYXAgZGVzY3JpcHRvcnMgSGVyZVxuIgoJCSAgICAgICAiVENCICAgICAgICAgICAgICAgICAgOiAweCVwXG4iCgkJICAgICAgICJUQ0IgTmV4dCAgICAgICAgICAgICA6IDB4JXBcbiIKCQkgICAgICAgIlRDQiBQYWNrZXRMZW5ndGggICAgIDogJWRcbiIKCQkgICAgICAgIlRDQiBXckluZGV4LnZhbHVlICAgIDogMHglMDh4XG4iCgkJICAgICAgICJUQ0IgV3JJbmRleC5iaXRzLnZhbCA6ICVkXG4iCgkJICAgICAgICJUQ0IgV3JJbmRleC52YWx1ZSAgICA6IDB4JTA4eFxuIgoJCSAgICAgICAiVENCIFdySW5kZXguYml0cy52YWwgOiAlZFxuIiwKCQkgICAgICAgcE1wVGNiLAoJCSAgICAgICBwTXBUY2ItPk5leHQsCgkJICAgICAgIHBNcFRjYi0+UGFja2V0TGVuZ3RoLAoJCSAgICAgICBwTXBUY2ItPldySW5kZXhTdGFydC52YWx1ZSwKCQkgICAgICAgcE1wVGNiLT5XckluZGV4U3RhcnQuYml0cy52YWwsCgkJICAgICAgIHBNcFRjYi0+V3JJbmRleC52YWx1ZSwKCQkgICAgICAgcE1wVGNiLT5XckluZGV4LmJpdHMudmFsKTsKCgkJZG8gewoJCQlkZXNjID0KCQkJICAgIChUWF9ERVNDX0VOVFJZX3QgKikgKHBBZGFwdGVyLT5UeFJpbmcuCgkJCQkJCSBwVHhEZXNjUmluZ1ZhICsKCQkJCQkJIHBNcFRjYi0+V3JJbmRleFN0YXJ0LmJpdHMudmFsKTsKCgkJCURCR19UWChldDEzMXhfZGJnaW5mbywKCQkJICAgICAgICJDVVJSRU5UIERFU0NSSVBUT1JcbiIKCQkJICAgICAgICJcdEFkZHJlc3MgICAgICAgICAgIDogMHglcFxuIgoJCQkgICAgICAgIlx0RGF0YUJ1ZmZlclB0ckhpZ2ggOiAweCUwOHhcbiIKCQkJICAgICAgICJcdERhdGFCdWZmZXJQdHJMb3cgIDogMHglMDh4XG4iCgkJCSAgICAgICAiXHR3b3JkMiAgICAgICAgICAgICA6IDB4JTA4eFxuIgoJCQkgICAgICAgIlx0d29yZDMgICAgICAgICAgICAgOiAweCUwOHhcbiIsCgkJCSAgICAgICBkZXNjLAoJCQkgICAgICAgZGVzYy0+RGF0YUJ1ZmZlclB0ckhpZ2gsCgkJCSAgICAgICBkZXNjLT5EYXRhQnVmZmVyUHRyTG93LAoJCQkgICAgICAgZGVzYy0+d29yZDIudmFsdWUsCgkJCSAgICAgICBkZXNjLT53b3JkMy52YWx1ZSk7CgoJCQlwY2lfdW5tYXBfc2luZ2xlKHBBZGFwdGVyLT5wZGV2LAoJCQkJCSBkZXNjLT5EYXRhQnVmZmVyUHRyTG93LAoJCQkJCSBkZXNjLT53b3JkMi52YWx1ZSwgUENJX0RNQV9UT0RFVklDRSk7CgoJCQlpZiAoKytwTXBUY2ItPldySW5kZXhTdGFydC5iaXRzLnZhbCA+PQoJCQkgICAgTlVNX0RFU0NfUEVSX1JJTkdfVFgpIHsKCQkJCWlmIChwTXBUY2ItPldySW5kZXhTdGFydC5iaXRzLndyYXApIHsKCQkJCQlwTXBUY2ItPldySW5kZXhTdGFydC52YWx1ZSA9IDA7CgkJCQl9IGVsc2UgewoJCQkJCXBNcFRjYi0+V3JJbmRleFN0YXJ0LnZhbHVlID0gMHg0MDA7CgkJCQl9CgkJCX0KCQl9CgkJd2hpbGUgKGRlc2MgIT0gKHBBZGFwdGVyLT5UeFJpbmcucFR4RGVzY1JpbmdWYSArCgkJCQlwTXBUY2ItPldySW5kZXguYml0cy52YWwpKTsKCgkJREJHX1RYKGV0MTMxeF9kYmdpbmZvLAoJCSAgICAgICAiRnJlZSBQYWNrZXQgKFNLQikgICA6IDB4JXBcbiIsIHBNcFRjYi0+UGFja2V0KTsKCgkJZGV2X2tmcmVlX3NrYl9hbnkocE1wVGNiLT5QYWNrZXQpOwoJfQoKCW1lbXNldChwTXBUY2IsIDAsIHNpemVvZihNUF9UQ0IpKTsKCgkvKiBBZGQgdGhlIFRDQiB0byB0aGUgUmVhZHkgUSAqLwoJc3Bpbl9sb2NrX2lycXNhdmUoJnBBZGFwdGVyLT5UQ0JSZWFkeVFMb2NrLCBsb2NrZmxhZ3MpOwoKCXBBZGFwdGVyLT5TdGF0cy5vcGFja2V0cysrOwoKCWlmIChwQWRhcHRlci0+VHhSaW5nLlRDQlJlYWR5UXVldWVUYWlsKSB7CgkJcEFkYXB0ZXItPlR4UmluZy5UQ0JSZWFkeVF1ZXVlVGFpbC0+TmV4dCA9IHBNcFRjYjsKCX0gZWxzZSB7CgkJLyogQXBwYXJlbnRseSByZWFkeSBRIGlzIGVtcHR5LiAqLwoJCXBBZGFwdGVyLT5UeFJpbmcuVENCUmVhZHlRdWV1ZUhlYWQgPSBwTXBUY2I7Cgl9CgoJcEFkYXB0ZXItPlR4UmluZy5UQ0JSZWFkeVF1ZXVlVGFpbCA9IHBNcFRjYjsKCglzcGluX3VubG9ja19pcnFyZXN0b3JlKCZwQWRhcHRlci0+VENCUmVhZHlRTG9jaywgbG9ja2ZsYWdzKTsKCglEQkdfQVNTRVJUKHBBZGFwdGVyLT5UeFJpbmcubkJ1c3lTZW5kID49IDApOwp9CgovKioKICogZXQxMzF4X2ZyZWVfYnVzeV9zZW5kX3BhY2tldHMgLSBGcmVlIGFuZCBjb21wbGV0ZSB0aGUgc3RvcHBlZCBhY3RpdmUgc2VuZHMKICogQHBBZGFwdGVyOiBwb2ludGVyIHRvIG91ciBhZGFwdGVyCiAqCiAqIEFzc3VtcHRpb24gLSBTZW5kIHNwaW5sb2NrIGhhcyBiZWVuIGFjcXVpcmVkCiAqLwp2b2lkIGV0MTMxeF9mcmVlX2J1c3lfc2VuZF9wYWNrZXRzKHN0cnVjdCBldDEzMXhfYWRhcHRlciAqcEFkYXB0ZXIpCnsKCVBNUF9UQ0IgcE1wVGNiOwoJc3RydWN0IGxpc3RfaGVhZCAqcEVudHJ5OwoJdW5zaWduZWQgbG9uZyBsb2NrZmxhZ3M7Cgl1aW50MzJfdCBGcmVlQ291bnRlciA9IDA7CgoJREJHX0VOVEVSKGV0MTMxeF9kYmdpbmZvKTsKCgl3aGlsZSAoIWxpc3RfZW1wdHkoJnBBZGFwdGVyLT5UeFJpbmcuU2VuZFdhaXRRdWV1ZSkpIHsKCQlzcGluX2xvY2tfaXJxc2F2ZSgmcEFkYXB0ZXItPlNlbmRXYWl0TG9jaywgbG9ja2ZsYWdzKTsKCgkJcEFkYXB0ZXItPlR4UmluZy5uV2FpdFNlbmQtLTsKCQlzcGluX3VubG9ja19pcnFyZXN0b3JlKCZwQWRhcHRlci0+U2VuZFdhaXRMb2NrLCBsb2NrZmxhZ3MpOwoKCQlwRW50cnkgPSBwQWRhcHRlci0+VHhSaW5nLlNlbmRXYWl0UXVldWUubmV4dDsKCX0KCglwQWRhcHRlci0+VHhSaW5nLm5XYWl0U2VuZCA9IDA7CgoJLyogQW55IHBhY2tldHMgYmVpbmcgc2VudD8gQ2hlY2sgdGhlIGZpcnN0IFRDQiBvbiB0aGUgc2VuZCBsaXN0ICovCglzcGluX2xvY2tfaXJxc2F2ZSgmcEFkYXB0ZXItPlRDQlNlbmRRTG9jaywgbG9ja2ZsYWdzKTsKCglwTXBUY2IgPSBwQWRhcHRlci0+VHhSaW5nLkN1cnJTZW5kSGVhZDsKCgl3aGlsZSAoKHBNcFRjYiAhPSBOVUxMKSAmJiAoRnJlZUNvdW50ZXIgPCBOVU1fVENCKSkgewoJCVBNUF9UQ0IgcE5leHQgPSBwTXBUY2ItPk5leHQ7CgoJCXBBZGFwdGVyLT5UeFJpbmcuQ3VyclNlbmRIZWFkID0gcE5leHQ7CgoJCWlmIChwTmV4dCA9PSBOVUxMKSB7CgkJCXBBZGFwdGVyLT5UeFJpbmcuQ3VyclNlbmRUYWlsID0gTlVMTDsKCQl9CgoJCXBBZGFwdGVyLT5UeFJpbmcubkJ1c3lTZW5kLS07CgoJCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJnBBZGFwdGVyLT5UQ0JTZW5kUUxvY2ssIGxvY2tmbGFncyk7CgoJCURCR19WRVJCT1NFKGV0MTMxeF9kYmdpbmZvLCAicE1wVGNiID0gMHglcFxuIiwgcE1wVGNiKTsKCgkJRnJlZUNvdW50ZXIrKzsKCQlNUF9GUkVFX1NFTkRfUEFDS0VUX0ZVTihwQWRhcHRlciwgcE1wVGNiKTsKCgkJc3Bpbl9sb2NrX2lycXNhdmUoJnBBZGFwdGVyLT5UQ0JTZW5kUUxvY2ssIGxvY2tmbGFncyk7CgoJCXBNcFRjYiA9IHBBZGFwdGVyLT5UeFJpbmcuQ3VyclNlbmRIZWFkOwoJfQoKCWlmIChGcmVlQ291bnRlciA9PSBOVU1fVENCKSB7CgkJREJHX0VSUk9SKGV0MTMxeF9kYmdpbmZvLAoJCQkgICJNcEZyZWVCdXN5U2VuZFBhY2tldHMgZXhpdHRlZCBsb29wIGZvciBhIGJhZCByZWFzb25cbiIpOwoJCUJVRygpOwoJfQoKCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJnBBZGFwdGVyLT5UQ0JTZW5kUUxvY2ssIGxvY2tmbGFncyk7CgoJcEFkYXB0ZXItPlR4UmluZy5uQnVzeVNlbmQgPSAwOwoKCURCR19MRUFWRShldDEzMXhfZGJnaW5mbyk7Cn0KCi8qKgogKiBldDEzMXhfaGFuZGxlX3NlbmRfaW50ZXJydXB0IC0gSW50ZXJydXB0IGhhbmRsZXIgZm9yIHNlbmRpbmcgcHJvY2Vzc2luZwogKiBAcEFkYXB0ZXI6IHBvaW50ZXIgdG8gb3VyIGFkYXB0ZXIKICoKICogUmUtY2xhaW0gdGhlIHNlbmQgcmVzb3VyY2VzLCBjb21wbGV0ZSBzZW5kcyBhbmQgZ2V0IG1vcmUgdG8gc2VuZCBmcm9tCiAqIHRoZSBzZW5kIHdhaXQgcXVldWUuCiAqCiAqIEFzc3VtcHRpb24gLSBTZW5kIHNwaW5sb2NrIGhhcyBiZWVuIGFjcXVpcmVkCiAqLwp2b2lkIGV0MTMxeF9oYW5kbGVfc2VuZF9pbnRlcnJ1cHQoc3RydWN0IGV0MTMxeF9hZGFwdGVyICpwQWRhcHRlcikKewoJREJHX1RYX0VOVEVSKGV0MTMxeF9kYmdpbmZvKTsKCgkvKiBNYXJrIGFzIGNvbXBsZXRlZCBhbnkgcGFja2V0cyB3aGljaCBoYXZlIGJlZW4gc2VudCBieSB0aGUgZGV2aWNlLiAqLwoJZXQxMzF4X3VwZGF0ZV90Y2JfbGlzdChwQWRhcHRlcik7CgoJLyogSWYgd2UgcXVldWVkIGFueSB0cmFuc21pdHMgYmVjYXVzZSB3ZSBkaWRuJ3QgaGF2ZSBhbnkgVENCcyBlYXJsaWVyLAoJICogZGVxdWV1ZSBhbmQgc2VuZCB0aG9zZSBwYWNrZXRzIG5vdywgYXMgbG9uZyBhcyB3ZSBoYXZlIGZyZWUgVENCcy4KCSAqLwoJZXQxMzF4X2NoZWNrX3NlbmRfd2FpdF9saXN0KHBBZGFwdGVyKTsKCglEQkdfVFhfTEVBVkUoZXQxMzF4X2RiZ2luZm8pOwp9CgovKioKICogZXQxMzF4X3VwZGF0ZV90Y2JfbGlzdCAtIEhlbHBlciByb3V0aW5lIGZvciBTZW5kIEludGVycnVwdCBoYW5kbGVyCiAqIEBwQWRhcHRlcjogcG9pbnRlciB0byBvdXIgYWRhcHRlcgogKgogKiBSZS1jbGFpbXMgdGhlIHNlbmQgcmVzb3VyY2VzIGFuZCBjb21wbGV0ZXMgc2VuZHMuICBDYW4gYWxzbyBiZSBjYWxsZWQgYXMKICogcGFydCBvZiB0aGUgTklDIHNlbmQgcm91dGluZSB3aGVuIHRoZSAiU2VydmljZUNvbXBsZXRlIiBpbmRpY2F0aW9uIGhhcwogKiB3cmFwcGVkLgogKi8Kc3RhdGljIHZvaWQgZXQxMzF4X3VwZGF0ZV90Y2JfbGlzdChzdHJ1Y3QgZXQxMzF4X2FkYXB0ZXIgKnBBZGFwdGVyKQp7Cgl1bnNpZ25lZCBsb25nIGxvY2tmbGFnczsKCURNQTEwV190IFNlcnZpY2VDb21wbGV0ZTsKCVBNUF9UQ0IgcE1wVGNiOwoKCVNlcnZpY2VDb21wbGV0ZS52YWx1ZSA9CgkgICAgcmVhZGwoJnBBZGFwdGVyLT5DU1JBZGRyZXNzLT50eGRtYS5OZXdTZXJ2aWNlQ29tcGxldGUudmFsdWUpOwoKCS8qIEhhcyB0aGUgcmluZyB3cmFwcGVkPyAgUHJvY2VzcyBhbnkgZGVzY3JpcHRvcnMgdGhhdCBkbyBub3QgaGF2ZQoJICogdGhlIHNhbWUgIndyYXAiIGluZGljYXRvciBhcyB0aGUgY3VycmVudCBjb21wbGV0aW9uIGluZGljYXRvcgoJICovCglzcGluX2xvY2tfaXJxc2F2ZSgmcEFkYXB0ZXItPlRDQlNlbmRRTG9jaywgbG9ja2ZsYWdzKTsKCglwTXBUY2IgPSBwQWRhcHRlci0+VHhSaW5nLkN1cnJTZW5kSGVhZDsKCXdoaWxlIChwTXBUY2IgJiYKCSAgICAgICBTZXJ2aWNlQ29tcGxldGUuYml0cy53cmFwICE9IHBNcFRjYi0+V3JJbmRleC5iaXRzLndyYXAgICYmCgkgICAgICAgU2VydmljZUNvbXBsZXRlLmJpdHMudmFsIDwgcE1wVGNiLT5XckluZGV4LmJpdHMudmFsKSB7CgkJcEFkYXB0ZXItPlR4UmluZy5uQnVzeVNlbmQtLTsKCQlwQWRhcHRlci0+VHhSaW5nLkN1cnJTZW5kSGVhZCA9IHBNcFRjYi0+TmV4dDsKCQlpZiAocE1wVGNiLT5OZXh0ID09IE5VTEwpIHsKCQkJcEFkYXB0ZXItPlR4UmluZy5DdXJyU2VuZFRhaWwgPSBOVUxMOwoJCX0KCgkJc3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmcEFkYXB0ZXItPlRDQlNlbmRRTG9jaywgbG9ja2ZsYWdzKTsKCQlNUF9GUkVFX1NFTkRfUEFDS0VUX0ZVTihwQWRhcHRlciwgcE1wVGNiKTsKCQlzcGluX2xvY2tfaXJxc2F2ZSgmcEFkYXB0ZXItPlRDQlNlbmRRTG9jaywgbG9ja2ZsYWdzKTsKCgkJLyogR290byB0aGUgbmV4dCBwYWNrZXQgKi8KCQlwTXBUY2IgPSBwQWRhcHRlci0+VHhSaW5nLkN1cnJTZW5kSGVhZDsKCX0KCXdoaWxlIChwTXBUY2IgJiYKCSAgICAgICBTZXJ2aWNlQ29tcGxldGUuYml0cy53cmFwID09IHBNcFRjYi0+V3JJbmRleC5iaXRzLndyYXAgJiYKCSAgICAgICBTZXJ2aWNlQ29tcGxldGUuYml0cy52YWwgPiBwTXBUY2ItPldySW5kZXguYml0cy52YWwpIHsKCQlwQWRhcHRlci0+VHhSaW5nLm5CdXN5U2VuZC0tOwoJCXBBZGFwdGVyLT5UeFJpbmcuQ3VyclNlbmRIZWFkID0gcE1wVGNiLT5OZXh0OwoJCWlmIChwTXBUY2ItPk5leHQgPT0gTlVMTCkgewoJCQlwQWRhcHRlci0+VHhSaW5nLkN1cnJTZW5kVGFpbCA9IE5VTEw7CgkJfQoKCQlzcGluX3VubG9ja19pcnFyZXN0b3JlKCZwQWRhcHRlci0+VENCU2VuZFFMb2NrLCBsb2NrZmxhZ3MpOwoJCU1QX0ZSRUVfU0VORF9QQUNLRVRfRlVOKHBBZGFwdGVyLCBwTXBUY2IpOwoJCXNwaW5fbG9ja19pcnFzYXZlKCZwQWRhcHRlci0+VENCU2VuZFFMb2NrLCBsb2NrZmxhZ3MpOwoKCQkvKiBHb3RvIHRoZSBuZXh0IHBhY2tldCAqLwoJCXBNcFRjYiA9IHBBZGFwdGVyLT5UeFJpbmcuQ3VyclNlbmRIZWFkOwoJfQoKCS8qIFdha2UgdXAgdGhlIHF1ZXVlIHdoZW4gd2UgaGl0IGEgbG93LXdhdGVyIG1hcmsgKi8KCWlmIChwQWRhcHRlci0+VHhSaW5nLm5CdXN5U2VuZCA8PSAoTlVNX1RDQiAvIDMpKSB7CgkJbmV0aWZfd2FrZV9xdWV1ZShwQWRhcHRlci0+bmV0ZGV2KTsKCX0KCglzcGluX3VubG9ja19pcnFyZXN0b3JlKCZwQWRhcHRlci0+VENCU2VuZFFMb2NrLCBsb2NrZmxhZ3MpOwp9CgovKioKICogZXQxMzF4X2NoZWNrX3NlbmRfd2FpdF9saXN0IC0gSGVscGVyIHJvdXRpbmUgZm9yIHRoZSBpbnRlcnJ1cHQgaGFuZGxlcgogKiBAcEFkYXB0ZXI6IHBvaW50ZXIgdG8gb3VyIGFkYXB0ZXIKICoKICogVGFrZXMgcGFja2V0cyBmcm9tIHRoZSBzZW5kIHdhaXQgcXVldWUgYW5kIHBvc3RzIHRoZW0gdG8gdGhlIGRldmljZSAoaWYKICogcm9vbSBhdmFpbGFibGUpLgogKi8Kc3RhdGljIHZvaWQgZXQxMzF4X2NoZWNrX3NlbmRfd2FpdF9saXN0KHN0cnVjdCBldDEzMXhfYWRhcHRlciAqcEFkYXB0ZXIpCnsKCXVuc2lnbmVkIGxvbmcgbG9ja2ZsYWdzOwoKCXNwaW5fbG9ja19pcnFzYXZlKCZwQWRhcHRlci0+U2VuZFdhaXRMb2NrLCBsb2NrZmxhZ3MpOwoKCXdoaWxlICghbGlzdF9lbXB0eSgmcEFkYXB0ZXItPlR4UmluZy5TZW5kV2FpdFF1ZXVlKSAmJgoJICAgICAgIE1QX1RDQl9SRVNPVVJDRVNfQVZBSUxBQkxFKHBBZGFwdGVyKSkgewoJCXN0cnVjdCBsaXN0X2hlYWQgKnBFbnRyeTsKCgkJREJHX1ZFUkJPU0UoZXQxMzF4X2RiZ2luZm8sICJUeCBwYWNrZXRzIG9uIHRoZSB3YWl0IHF1ZXVlXG4iKTsKCgkJcEVudHJ5ID0gcEFkYXB0ZXItPlR4UmluZy5TZW5kV2FpdFF1ZXVlLm5leHQ7CgoJCXBBZGFwdGVyLT5UeFJpbmcubldhaXRTZW5kLS07CgoJCURCR19XQVJOSU5HKGV0MTMxeF9kYmdpbmZvLAoJCQkgICAgIk1wSGFuZGxlU2VuZEludGVycnVwdCAtIHNlbnQgYSBxdWV1ZWQgcGt0LiBXYWl0aW5nICVkXG4iLAoJCQkgICAgcEFkYXB0ZXItPlR4UmluZy5uV2FpdFNlbmQpOwoJfQoKCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJnBBZGFwdGVyLT5TZW5kV2FpdExvY2ssIGxvY2tmbGFncyk7Cn0K