LyoKICAgIFNETCAtIFNpbXBsZSBEaXJlY3RNZWRpYSBMYXllcgogICAgQ29weXJpZ2h0IChDKSAxOTk3LTIwMTIgU2FtIExhbnRpbmdhCgogICAgVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vcgogICAgbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogICAgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyCiAgICB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KCiAgICBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICAgIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCiAgICBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQogICAgTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KCiAgICBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAgICBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAgICBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgIDAyMTEwLTEzMDEgIFVTQQoKICAgIFNhbSBMYW50aW5nYQogICAgc2xvdWtlbkBsaWJzZGwub3JnCgogICAgVGhpcyBkcml2ZXIgd2FzIHdyaXR0ZW4gYnk6CiAgICBFcmlrIEluZ2UgQm9sc/gKICAgIGtuYW5AbW8uaGltb2xkZS5ubwoqLwojaW5jbHVkZSAiU0RMX2NvbmZpZy5oIgoKLyogQWxsb3cgYWNjZXNzIHRvIGEgcmF3IG1peGluZyBidWZmZXIgKi8KCiNpbmNsdWRlIDxzaWduYWwuaD4KI2luY2x1ZGUgPHVuaXN0ZC5oPgoKI2luY2x1ZGUgIlNETF90aW1lci5oIgojaW5jbHVkZSAiU0RMX2F1ZGlvLmgiCiNpbmNsdWRlICIuLi9TRExfYXVkaW9tZW0uaCIKI2luY2x1ZGUgIi4uL1NETF9hdWRpb19jLmgiCiNpbmNsdWRlICIuLi9TRExfYXVkaW9kZXZfYy5oIgojaW5jbHVkZSAiU0RMX25hc2F1ZGlvLmgiCgojaWZkZWYgU0RMX0FVRElPX0RSSVZFUl9OQVNfRFlOQU1JQwojaW5jbHVkZSAiU0RMX2xvYWRzby5oIgojZW5kaWYKCi8qIFRoZSB0YWcgbmFtZSB1c2VkIGJ5IGFydHNjIGF1ZGlvICovCiNkZWZpbmUgTkFTX0RSSVZFUl9OQU1FICAgICAgICAgIm5hcyIKCnN0YXRpYyBzdHJ1Y3QgU0RMX1ByaXZhdGVBdWRpb0RhdGEgKnRoaXMyID0gTlVMTDsKCnN0YXRpYyB2b2lkICgqTkFTX0F1Q2xvc2VTZXJ2ZXIpIChBdVNlcnZlciAqKTsKc3RhdGljIHZvaWQgKCpOQVNfQXVOZXh0RXZlbnQpIChBdVNlcnZlciAqLCBBdUJvb2wsIEF1RXZlbnQgKik7CnN0YXRpYyBBdUJvb2woKk5BU19BdURpc3BhdGNoRXZlbnQpIChBdVNlcnZlciAqLCBBdUV2ZW50ICopOwpzdGF0aWMgQXVGbG93SUQoKk5BU19BdUNyZWF0ZUZsb3cpIChBdVNlcnZlciAqLCBBdVN0YXR1cyAqKTsKc3RhdGljIHZvaWQgKCpOQVNfQXVTdGFydEZsb3cpIChBdVNlcnZlciAqLCBBdUZsb3dJRCwgQXVTdGF0dXMgKik7CnN0YXRpYyB2b2lkICgqTkFTX0F1U2V0RWxlbWVudHMpCiAgKEF1U2VydmVyICosIEF1Rmxvd0lELCBBdUJvb2wsIGludCwgQXVFbGVtZW50ICosIEF1U3RhdHVzICopOwpzdGF0aWMgdm9pZCAoKk5BU19BdVdyaXRlRWxlbWVudCkKICAoQXVTZXJ2ZXIgKiwgQXVGbG93SUQsIGludCwgQXVVaW50MzIsIEF1UG9pbnRlciwgQXVCb29sLCBBdVN0YXR1cyAqKTsKc3RhdGljIEF1U2VydmVyICooKk5BU19BdU9wZW5TZXJ2ZXIpCiAgKF9BdUNvbnN0IGNoYXIgKiwgaW50LCBfQXVDb25zdCBjaGFyICosIGludCwgX0F1Q29uc3QgY2hhciAqLCBjaGFyICoqKTsKc3RhdGljIEF1RXZlbnRIYW5kbGVyUmVjICooKk5BU19BdVJlZ2lzdGVyRXZlbnRIYW5kbGVyKQogIChBdVNlcnZlciAqLCBBdU1hc2ssIGludCwgQXVJRCwgQXVFdmVudEhhbmRsZXJDYWxsYmFjaywgQXVQb2ludGVyKTsKCgojaWZkZWYgU0RMX0FVRElPX0RSSVZFUl9OQVNfRFlOQU1JQwoKc3RhdGljIGNvbnN0IGNoYXIgKm5hc19saWJyYXJ5ID0gU0RMX0FVRElPX0RSSVZFUl9OQVNfRFlOQU1JQzsKc3RhdGljIHZvaWQgKm5hc19oYW5kbGUgPSBOVUxMOwoKc3RhdGljIGludApsb2FkX25hc19zeW0oY29uc3QgY2hhciAqZm4sIHZvaWQgKiphZGRyKQp7CiAgICAqYWRkciA9IFNETF9Mb2FkRnVuY3Rpb24obmFzX2hhbmRsZSwgZm4pOwogICAgaWYgKCphZGRyID09IE5VTEwpIHsKICAgICAgICByZXR1cm4gMDsKICAgIH0KICAgIHJldHVybiAxOwp9CgovKiBjYXN0IGZ1bmNzIHRvIGNoYXIqIGZpcnN0LCB0byBwbGVhc2UgR0NDJ3Mgc3RyaWN0IGFsaWFzaW5nIHJ1bGVzLiAqLwojZGVmaW5lIFNETF9OQVNfU1lNKHgpIFwKICAgIGlmICghbG9hZF9uYXNfc3ltKCN4LCAodm9pZCAqKikgKGNoYXIgKikgJk5BU18jI3gpKSByZXR1cm4gLTEKI2Vsc2UKI2RlZmluZSBTRExfTkFTX1NZTSh4KSBOQVNfIyN4ID0geAojZW5kaWYKCnN0YXRpYyBpbnQKbG9hZF9uYXNfc3ltcyh2b2lkKQp7CiAgICBTRExfTkFTX1NZTShBdUNsb3NlU2VydmVyKTsKICAgIFNETF9OQVNfU1lNKEF1TmV4dEV2ZW50KTsKICAgIFNETF9OQVNfU1lNKEF1RGlzcGF0Y2hFdmVudCk7CiAgICBTRExfTkFTX1NZTShBdUNyZWF0ZUZsb3cpOwogICAgU0RMX05BU19TWU0oQXVTdGFydEZsb3cpOwogICAgU0RMX05BU19TWU0oQXVTZXRFbGVtZW50cyk7CiAgICBTRExfTkFTX1NZTShBdVdyaXRlRWxlbWVudCk7CiAgICBTRExfTkFTX1NZTShBdU9wZW5TZXJ2ZXIpOwogICAgU0RMX05BU19TWU0oQXVSZWdpc3RlckV2ZW50SGFuZGxlcik7CiAgICByZXR1cm4gMDsKfQoKI3VuZGVmIFNETF9OQVNfU1lNCgojaWZkZWYgU0RMX0FVRElPX0RSSVZFUl9OQVNfRFlOQU1JQwoKc3RhdGljIHZvaWQKVW5sb2FkTkFTTGlicmFyeSh2b2lkKQp7CiAgICBpZiAobmFzX2hhbmRsZSAhPSBOVUxMKSB7CiAgICAgICAgU0RMX1VubG9hZE9iamVjdChuYXNfaGFuZGxlKTsKICAgICAgICBuYXNfaGFuZGxlID0gTlVMTDsKICAgIH0KfQoKc3RhdGljIGludApMb2FkTkFTTGlicmFyeSh2b2lkKQp7CiAgICBpbnQgcmV0dmFsID0gMDsKICAgIGlmIChuYXNfaGFuZGxlID09IE5VTEwpIHsKICAgICAgICBuYXNfaGFuZGxlID0gU0RMX0xvYWRPYmplY3QobmFzX2xpYnJhcnkpOwogICAgICAgIGlmIChuYXNfaGFuZGxlID09IE5VTEwpIHsKICAgICAgICAgICAgLyogQ29weSBlcnJvciBzdHJpbmcgc28gd2UgY2FuIHVzZSBpdCBpbiBhIG5ldyBTRExfU2V0RXJyb3IoKS4gKi8KICAgICAgICAgICAgY2hhciAqb3JpZ2VyciA9IFNETF9HZXRFcnJvcigpOwogICAgICAgICAgICBzaXplX3QgbGVuID0gU0RMX3N0cmxlbihvcmlnZXJyKSArIDE7CiAgICAgICAgICAgIGNoYXIgKmVyciA9IChjaGFyICopIGFsbG9jYShsZW4pOwogICAgICAgICAgICBTRExfc3RybGNweShlcnIsIG9yaWdlcnIsIGxlbik7CiAgICAgICAgICAgIHJldHZhbCA9IC0xOwogICAgICAgICAgICBTRExfU2V0RXJyb3IoIk5BUzogU0RMX0xvYWRPYmplY3QoJyVzJykgZmFpbGVkOiAlc1xuIiwKICAgICAgICAgICAgICAgICAgICAgICAgIG5hc19saWJyYXJ5LCBlcnIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHJldHZhbCA9IGxvYWRfbmFzX3N5bXMoKTsKICAgICAgICAgICAgaWYgKHJldHZhbCA8IDApIHsKICAgICAgICAgICAgICAgIFVubG9hZE5BU0xpYnJhcnkoKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KICAgIHJldHVybiByZXR2YWw7Cn0KCiNlbHNlCgpzdGF0aWMgdm9pZApVbmxvYWROQVNMaWJyYXJ5KHZvaWQpCnsKfQoKc3RhdGljIGludApMb2FkTkFTTGlicmFyeSh2b2lkKQp7CiAgICBsb2FkX25hc19zeW1zKCk7CiAgICByZXR1cm4gMDsKfQoKI2VuZGlmIC8qIFNETF9BVURJT19EUklWRVJfTkFTX0RZTkFNSUMgKi8KCgovKiBBdWRpbyBkcml2ZXIgZnVuY3Rpb25zICovCnN0YXRpYyBpbnQgTkFTX09wZW5BdWRpbyhfVEhJUywgU0RMX0F1ZGlvU3BlYyAqc3BlYyk7CnN0YXRpYyB2b2lkIE5BU19XYWl0QXVkaW8oX1RISVMpOwpzdGF0aWMgdm9pZCBOQVNfUGxheUF1ZGlvKF9USElTKTsKc3RhdGljIFVpbnQ4ICpOQVNfR2V0QXVkaW9CdWYoX1RISVMpOwpzdGF0aWMgdm9pZCBOQVNfQ2xvc2VBdWRpbyhfVEhJUyk7CgovKiBBdWRpbyBkcml2ZXIgYm9vdHN0cmFwIGZ1bmN0aW9ucyAqLwoKc3RhdGljIGludCBBdWRpb19BdmFpbGFibGUodm9pZCkKewoJaWYgKExvYWROQVNMaWJyYXJ5KCkgPT0gMCkgewoJCUF1U2VydmVyICphdWQgPSBOQVNfQXVPcGVuU2VydmVyKCIiLCAwLCBOVUxMLCAwLCBOVUxMLCBOVUxMKTsKCQlpZiAoIWF1ZCkgewoJCQlVbmxvYWROQVNMaWJyYXJ5KCk7CgkJCXJldHVybiAwOwoJCX0KCQlOQVNfQXVDbG9zZVNlcnZlcihhdWQpOwoJCVVubG9hZE5BU0xpYnJhcnkoKTsKCQlyZXR1cm4gMTsKCX0KCXJldHVybiAwOwp9CgpzdGF0aWMgdm9pZCBBdWRpb19EZWxldGVEZXZpY2UoU0RMX0F1ZGlvRGV2aWNlICpkZXZpY2UpCnsKCVVubG9hZE5BU0xpYnJhcnkoKTsKCVNETF9mcmVlKGRldmljZS0+aGlkZGVuKTsKCVNETF9mcmVlKGRldmljZSk7Cn0KCnN0YXRpYyBTRExfQXVkaW9EZXZpY2UgKkF1ZGlvX0NyZWF0ZURldmljZShpbnQgZGV2aW5kZXgpCnsKCVNETF9BdWRpb0RldmljZSAqdGhpczsKCglpZiAoTG9hZE5BU0xpYnJhcnkoKSA8IDApIHsKCQlyZXR1cm4gTlVMTDsKCX0KCgkvKiBJbml0aWFsaXplIGFsbCB2YXJpYWJsZXMgdGhhdCB3ZSBjbGVhbiBvbiBzaHV0ZG93biAqLwoJdGhpcyA9IChTRExfQXVkaW9EZXZpY2UgKilTRExfbWFsbG9jKHNpemVvZihTRExfQXVkaW9EZXZpY2UpKTsKCWlmICggdGhpcyApIHsKCQlTRExfbWVtc2V0KHRoaXMsIDAsIChzaXplb2YgKnRoaXMpKTsKCQl0aGlzLT5oaWRkZW4gPSAoc3RydWN0IFNETF9Qcml2YXRlQXVkaW9EYXRhICopCgkJCQlTRExfbWFsbG9jKChzaXplb2YgKnRoaXMtPmhpZGRlbikpOwoJfQoJaWYgKCAodGhpcyA9PSBOVUxMKSB8fCAodGhpcy0+aGlkZGVuID09IE5VTEwpICkgewoJCVNETF9PdXRPZk1lbW9yeSgpOwoJCWlmICggdGhpcyApIHsKCQkJU0RMX2ZyZWUodGhpcyk7CgkJfQoJCXJldHVybiBOVUxMOwoJfQoJU0RMX21lbXNldCh0aGlzLT5oaWRkZW4sIDAsIChzaXplb2YgKnRoaXMtPmhpZGRlbikpOwoKCS8qIFNldCB0aGUgZnVuY3Rpb24gcG9pbnRlcnMgKi8KCXRoaXMtPk9wZW5BdWRpbyA9IE5BU19PcGVuQXVkaW87Cgl0aGlzLT5XYWl0QXVkaW8gPSBOQVNfV2FpdEF1ZGlvOwoJdGhpcy0+UGxheUF1ZGlvID0gTkFTX1BsYXlBdWRpbzsKCXRoaXMtPkdldEF1ZGlvQnVmID0gTkFTX0dldEF1ZGlvQnVmOwoJdGhpcy0+Q2xvc2VBdWRpbyA9IE5BU19DbG9zZUF1ZGlvOwoKCXRoaXMtPmZyZWUgPSBBdWRpb19EZWxldGVEZXZpY2U7CgoJcmV0dXJuIHRoaXM7Cn0KCkF1ZGlvQm9vdFN0cmFwIE5BU19ib290c3RyYXAgPSB7CglOQVNfRFJJVkVSX05BTUUsICJOZXR3b3JrIEF1ZGlvIFN5c3RlbSIsCglBdWRpb19BdmFpbGFibGUsIEF1ZGlvX0NyZWF0ZURldmljZQp9OwoKLyogVGhpcyBmdW5jdGlvbiB3YWl0cyB1bnRpbCBpdCBpcyBwb3NzaWJsZSB0byB3cml0ZSBhIGZ1bGwgc291bmQgYnVmZmVyICovCnN0YXRpYyB2b2lkIE5BU19XYWl0QXVkaW8oX1RISVMpCnsKCXdoaWxlICggdGhpcy0+aGlkZGVuLT5idWZfZnJlZSA8IHRoaXMtPmhpZGRlbi0+bWl4bGVuICkgewoJCUF1RXZlbnQgZXY7CgkJTkFTX0F1TmV4dEV2ZW50KHRoaXMtPmhpZGRlbi0+YXVkLCBBdVRydWUsICZldik7CgkJTkFTX0F1RGlzcGF0Y2hFdmVudCh0aGlzLT5oaWRkZW4tPmF1ZCwgJmV2KTsKCX0KfQoKc3RhdGljIHZvaWQgTkFTX1BsYXlBdWRpbyhfVEhJUykKewoJd2hpbGUgKHRoaXMtPmhpZGRlbi0+bWl4bGVuID4gdGhpcy0+aGlkZGVuLT5idWZfZnJlZSkgeyAvKiBXZSB0aGluayB0aGUgYnVmZmVyIGlzIGZ1bGw/IFlpa2VzISBBc2sgdGhlIHNlcnZlciBmb3IgZXZlbnRzLAoJCQkJICAgIGluIHRoZSBob3BlIHRoYXQgc29tZSBvZiB0aGVtIGlzIExvd1dhdGVyIGV2ZW50cyB0ZWxsaW5nIHVzIG1vcmUKCQkJCSAgICBvZiB0aGUgYnVmZmVyIGlzIGZyZWUgbm93IHRoYW4gd2hhdCB3ZSB0aGluay4gKi8KCQlBdUV2ZW50IGV2OwoJCU5BU19BdU5leHRFdmVudCh0aGlzLT5oaWRkZW4tPmF1ZCwgQXVUcnVlLCAmZXYpOwoJCU5BU19BdURpc3BhdGNoRXZlbnQodGhpcy0+aGlkZGVuLT5hdWQsICZldik7Cgl9Cgl0aGlzLT5oaWRkZW4tPmJ1Zl9mcmVlIC09IHRoaXMtPmhpZGRlbi0+bWl4bGVuOwoKCS8qIFdyaXRlIHRoZSBhdWRpbyBkYXRhICovCglOQVNfQXVXcml0ZUVsZW1lbnQodGhpcy0+aGlkZGVuLT5hdWQsIHRoaXMtPmhpZGRlbi0+ZmxvdywgMCwgdGhpcy0+aGlkZGVuLT5taXhsZW4sIHRoaXMtPmhpZGRlbi0+bWl4YnVmLCBBdUZhbHNlLCBOVUxMKTsKCgl0aGlzLT5oaWRkZW4tPndyaXR0ZW4gKz0gdGhpcy0+aGlkZGVuLT5taXhsZW47CgkKI2lmZGVmIERFQlVHX0FVRElPCglmcHJpbnRmKHN0ZGVyciwgIldyb3RlICVkIGJ5dGVzIG9mIGF1ZGlvIGRhdGFcbiIsIHRoaXMtPmhpZGRlbi0+bWl4bGVuKTsKI2VuZGlmCn0KCnN0YXRpYyBVaW50OCAqTkFTX0dldEF1ZGlvQnVmKF9USElTKQp7CglyZXR1cm4odGhpcy0+aGlkZGVuLT5taXhidWYpOwp9CgpzdGF0aWMgdm9pZCBOQVNfQ2xvc2VBdWRpbyhfVEhJUykKewoJaWYgKCB0aGlzLT5oaWRkZW4tPm1peGJ1ZiAhPSBOVUxMICkgewoJCVNETF9GcmVlQXVkaW9NZW0odGhpcy0+aGlkZGVuLT5taXhidWYpOwoJCXRoaXMtPmhpZGRlbi0+bWl4YnVmID0gTlVMTDsKCX0KCWlmICggdGhpcy0+aGlkZGVuLT5hdWQgKSB7CgkJTkFTX0F1Q2xvc2VTZXJ2ZXIodGhpcy0+aGlkZGVuLT5hdWQpOwoJCXRoaXMtPmhpZGRlbi0+YXVkID0gMDsKCX0KfQoKc3RhdGljIHVuc2lnbmVkIGNoYXIgc2RsZm9ybWF0X3RvX2F1Zm9ybWF0KHVuc2lnbmVkIGludCBmbXQpCnsKICBzd2l0Y2ggKGZtdCkKICAgIHsKICAgIGNhc2UgQVVESU9fVTg6CiAgICAgIHJldHVybiBBdUZvcm1hdExpbmVhclVuc2lnbmVkODsKICAgIGNhc2UgQVVESU9fUzg6CiAgICAgIHJldHVybiBBdUZvcm1hdExpbmVhclNpZ25lZDg7CiAgICBjYXNlIEFVRElPX1UxNkxTQjoKICAgICAgcmV0dXJuIEF1Rm9ybWF0TGluZWFyVW5zaWduZWQxNkxTQjsKICAgIGNhc2UgQVVESU9fVTE2TVNCOgogICAgICByZXR1cm4gQXVGb3JtYXRMaW5lYXJVbnNpZ25lZDE2TVNCOwogICAgY2FzZSBBVURJT19TMTZMU0I6CiAgICAgIHJldHVybiBBdUZvcm1hdExpbmVhclNpZ25lZDE2TFNCOwogICAgY2FzZSBBVURJT19TMTZNU0I6CiAgICAgIHJldHVybiBBdUZvcm1hdExpbmVhclNpZ25lZDE2TVNCOwogICAgfQogIHJldHVybiBBdU5vbmU7Cn0KCnN0YXRpYyBBdUJvb2wKZXZlbnRfaGFuZGxlcihBdVNlcnZlciogYXVkLCBBdUV2ZW50KiBldiwgQXVFdmVudEhhbmRsZXJSZWMqIGhuZCkKewoJc3dpdGNoIChldi0+dHlwZSkgewoJY2FzZSBBdUV2ZW50VHlwZUVsZW1lbnROb3RpZnk6IHsKCQlBdUVsZW1lbnROb3RpZnlFdmVudCogZXZlbnQgPSAoQXVFbGVtZW50Tm90aWZ5RXZlbnQgKilldjsKCgkJc3dpdGNoIChldmVudC0+a2luZCkgewoJCWNhc2UgQXVFbGVtZW50Tm90aWZ5S2luZExvd1dhdGVyOgoJCQlpZiAodGhpczItPmJ1Zl9mcmVlID49IDApIHsKCQkJCXRoaXMyLT5yZWFsbHkgKz0gZXZlbnQtPm51bV9ieXRlczsKCQkJCWdldHRpbWVvZmRheSgmdGhpczItPmxhc3RfdHYsIDApOwoJCQkJdGhpczItPmJ1Zl9mcmVlICs9IGV2ZW50LT5udW1fYnl0ZXM7CgkJCX0gZWxzZSB7CgkJCQl0aGlzMi0+YnVmX2ZyZWUgPSBldmVudC0+bnVtX2J5dGVzOwoJCQl9CgkJCWJyZWFrOwoJCWNhc2UgQXVFbGVtZW50Tm90aWZ5S2luZFN0YXRlOgoJCQlzd2l0Y2ggKGV2ZW50LT5jdXJfc3RhdGUpIHsKCQkJY2FzZSBBdVN0YXRlUGF1c2U6CgkJCQlpZiAoZXZlbnQtPnJlYXNvbiAhPSBBdVJlYXNvblVzZXIpIHsKCQkJCQlpZiAodGhpczItPmJ1Zl9mcmVlID49IDApIHsKCQkJCQkJdGhpczItPnJlYWxseSArPSBldmVudC0+bnVtX2J5dGVzOwoJCQkJCQlnZXR0aW1lb2ZkYXkoJnRoaXMyLT5sYXN0X3R2LCAwKTsKCQkJCQkJdGhpczItPmJ1Zl9mcmVlICs9IGV2ZW50LT5udW1fYnl0ZXM7CgkJCQkJfSBlbHNlIHsKCQkJCQkJdGhpczItPmJ1Zl9mcmVlID0gZXZlbnQtPm51bV9ieXRlczsKCQkJCQl9CgkJCQl9CgkJCQlicmVhazsKCQkJfQoJCX0KCX0KCX0KCXJldHVybiBBdVRydWU7Cn0KCnN0YXRpYyBBdURldmljZUlECmZpbmRfZGV2aWNlKF9USElTLCBpbnQgbmNoKQp7CiAgICAvKiBUaGVzZSAiQXUiIHRoaW5ncyBhcmUgYWxsIG1hY3Jvcywgbm90IGZ1bmN0aW9ucy4uLiAqLwoJaW50IGk7Cglmb3IgKGkgPSAwOyBpIDwgQXVTZXJ2ZXJOdW1EZXZpY2VzKHRoaXMtPmhpZGRlbi0+YXVkKTsgaSsrKSB7CgkJaWYgKChBdURldmljZUtpbmQoQXVTZXJ2ZXJEZXZpY2UodGhpcy0+aGlkZGVuLT5hdWQsIGkpKSA9PQoJCQkJQXVDb21wb25lbnRLaW5kUGh5c2ljYWxPdXRwdXQpICYmCgkJCUF1RGV2aWNlTnVtVHJhY2tzKEF1U2VydmVyRGV2aWNlKHRoaXMtPmhpZGRlbi0+YXVkLCBpKSkgPT0gbmNoKSB7CgkJCXJldHVybiBBdURldmljZUlkZW50aWZpZXIoQXVTZXJ2ZXJEZXZpY2UodGhpcy0+aGlkZGVuLT5hdWQsIGkpKTsKCQl9Cgl9CglyZXR1cm4gQXVOb25lOwp9CgpzdGF0aWMgaW50IE5BU19PcGVuQXVkaW8oX1RISVMsIFNETF9BdWRpb1NwZWMgKnNwZWMpCnsKCUF1RWxlbWVudCBlbG1zWzNdOwoJaW50IGJ1ZmZlcl9zaXplOwoJVWludDE2IHRlc3RfZm9ybWF0LCBmb3JtYXQ7CgoJdGhpcy0+aGlkZGVuLT5taXhidWYgPSBOVUxMOwoKCS8qIFRyeSBmb3IgYSBjbG9zZXN0IG1hdGNoIG9uIGF1ZGlvIGZvcm1hdCAqLwoJZm9ybWF0ID0gMDsKCWZvciAoIHRlc3RfZm9ybWF0ID0gU0RMX0ZpcnN0QXVkaW9Gb3JtYXQoc3BlYy0+Zm9ybWF0KTsKCQkJCQkJISBmb3JtYXQgJiYgdGVzdF9mb3JtYXQ7ICkgewoJCWZvcm1hdCA9IHNkbGZvcm1hdF90b19hdWZvcm1hdCh0ZXN0X2Zvcm1hdCk7CgoJCWlmIChmb3JtYXQgPT0gQXVOb25lKSB7CgkJCXRlc3RfZm9ybWF0ID0gU0RMX05leHRBdWRpb0Zvcm1hdCgpOwoJCX0KCX0KCWlmICggZm9ybWF0ID09IDAgKSB7CgkJU0RMX1NldEVycm9yKCJDb3VsZG4ndCBmaW5kIGFueSBoYXJkd2FyZSBhdWRpbyBmb3JtYXRzIik7CgkJcmV0dXJuKC0xKTsKCX0KCXNwZWMtPmZvcm1hdCA9IHRlc3RfZm9ybWF0OwoKCXRoaXMtPmhpZGRlbi0+YXVkID0gTkFTX0F1T3BlblNlcnZlcigiIiwgMCwgTlVMTCwgMCwgTlVMTCwgTlVMTCk7CglpZiAodGhpcy0+aGlkZGVuLT5hdWQgPT0gMCkKCXsKCQlTRExfU2V0RXJyb3IoIkNvdWxkbid0IG9wZW4gY29ubmVjdGlvbiB0byBOQVMgc2VydmVyIik7CgkJcmV0dXJuICgtMSk7Cgl9CgkKCXRoaXMtPmhpZGRlbi0+ZGV2ID0gZmluZF9kZXZpY2UodGhpcywgc3BlYy0+Y2hhbm5lbHMpOwoJaWYgKCh0aGlzLT5oaWRkZW4tPmRldiA9PSBBdU5vbmUpIHx8ICghKHRoaXMtPmhpZGRlbi0+ZmxvdyA9IE5BU19BdUNyZWF0ZUZsb3codGhpcy0+aGlkZGVuLT5hdWQsIE5VTEwpKSkpIHsKCQlOQVNfQXVDbG9zZVNlcnZlcih0aGlzLT5oaWRkZW4tPmF1ZCk7CgkJdGhpcy0+aGlkZGVuLT5hdWQgPSAwOwoJCVNETF9TZXRFcnJvcigiQ291bGRuJ3QgZmluZCBhIGZpdHRpbmcgcGxheWJhY2sgZGV2aWNlIG9uIE5BUyBzZXJ2ZXIiKTsKCQlyZXR1cm4gKC0xKTsKCX0KCQoJYnVmZmVyX3NpemUgPSBzcGVjLT5mcmVxOwoJaWYgKGJ1ZmZlcl9zaXplIDwgNDA5NikKCQlidWZmZXJfc2l6ZSA9IDQwOTY7IAoKCWlmIChidWZmZXJfc2l6ZSA+IDMyNzY4KQoJCWJ1ZmZlcl9zaXplID0gMzI3Njg7IC8qIFNvIHRoYXQgdGhlIGJ1ZmZlciB3b24ndCBnZXQgdW5tYW5hZ2VhYmx5IGJpZy4gKi8KCgkvKiBDYWxjdWxhdGUgdGhlIGZpbmFsIHBhcmFtZXRlcnMgZm9yIHRoaXMgYXVkaW8gc3BlY2lmaWNhdGlvbiAqLwoJU0RMX0NhbGN1bGF0ZUF1ZGlvU3BlYyhzcGVjKTsKCgl0aGlzMiA9IHRoaXMtPmhpZGRlbjsKCiAgICAvKiBUaGVzZSAiQXUiIHRoaW5ncyB3aXRob3V0IGEgTkFTXyBwcmVmaXggYXJlIG1hY3Jvcywgbm90IGZ1bmN0aW9ucy4uLiAqLwoJQXVNYWtlRWxlbWVudEltcG9ydENsaWVudChlbG1zLCBzcGVjLT5mcmVxLCBmb3JtYXQsIHNwZWMtPmNoYW5uZWxzLCBBdVRydWUsCgkJCQlidWZmZXJfc2l6ZSwgYnVmZmVyX3NpemUgLyA0LCAwLCBOVUxMKTsKCUF1TWFrZUVsZW1lbnRFeHBvcnREZXZpY2UoZWxtcysxLCAwLCB0aGlzLT5oaWRkZW4tPmRldiwgc3BlYy0+ZnJlcSwKCQkJCUF1VW5saW1pdGVkU2FtcGxlcywgMCwgTlVMTCk7CglOQVNfQXVTZXRFbGVtZW50cyh0aGlzLT5oaWRkZW4tPmF1ZCwgdGhpcy0+aGlkZGVuLT5mbG93LCBBdVRydWUsIDIsIGVsbXMsIE5VTEwpOwoJTkFTX0F1UmVnaXN0ZXJFdmVudEhhbmRsZXIodGhpcy0+aGlkZGVuLT5hdWQsIEF1RXZlbnRIYW5kbGVySURNYXNrLCAwLCB0aGlzLT5oaWRkZW4tPmZsb3csCgkJCQlldmVudF9oYW5kbGVyLCAoQXVQb2ludGVyKSBOVUxMKTsKCglOQVNfQXVTdGFydEZsb3codGhpcy0+aGlkZGVuLT5hdWQsIHRoaXMtPmhpZGRlbi0+ZmxvdywgTlVMTCk7CgoJLyogQWxsb2NhdGUgbWl4aW5nIGJ1ZmZlciAqLwoJdGhpcy0+aGlkZGVuLT5taXhsZW4gPSBzcGVjLT5zaXplOwoJdGhpcy0+aGlkZGVuLT5taXhidWYgPSAoVWludDggKilTRExfQWxsb2NBdWRpb01lbSh0aGlzLT5oaWRkZW4tPm1peGxlbik7CglpZiAoIHRoaXMtPmhpZGRlbi0+bWl4YnVmID09IE5VTEwgKSB7CgkJcmV0dXJuKC0xKTsKCX0KCVNETF9tZW1zZXQodGhpcy0+aGlkZGVuLT5taXhidWYsIHNwZWMtPnNpbGVuY2UsIHNwZWMtPnNpemUpOwoKCS8qIEdldCB0aGUgcGFyZW50IHByb2Nlc3MgaWQgKHdlJ3JlIHRoZSBwYXJlbnQgb2YgdGhlIGF1ZGlvIHRocmVhZCkgKi8KCXRoaXMtPmhpZGRlbi0+cGFyZW50ID0gZ2V0cGlkKCk7CgoJLyogV2UncmUgcmVhZHkgdG8gcm9jayBhbmQgcm9sbC4gOi0pICovCglyZXR1cm4oMCk7Cn0K