LyoKCVNETCAtIFNpbXBsZSBEaXJlY3RNZWRpYSBMYXllcgogICAgQ29weXJpZ2h0IChDKSAxOTk3LTIwMTIgU2FtIExhbnRpbmdhCgoJVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vcgoJbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExpYnJhcnkgR2VuZXJhbCBQdWJsaWMKCUxpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlcgoJdmVyc2lvbiAyIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgoKCVRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAoJYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKCU1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VCglMaWJyYXJ5IEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KCglZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGlicmFyeSBHZW5lcmFsIFB1YmxpYwoJTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZQoJRm91bmRhdGlvbiwgSW5jLiwgNTkgVGVtcGxlIFBsYWNlLCBTdWl0ZSAzMzAsIEJvc3RvbiwgTUEgIDAyMTExLTEzMDcgIFVTQQoKCVNhbSBMYW50aW5nYQoJc2xvdWtlbkBsaWJzZGwub3JnCiovCiNpbmNsdWRlICJTRExfY29uZmlnLmgiCgojaWZkZWYgU0RMX0pPWVNUSUNLX0lPS0lUCgovKiBTREwgam95c3RpY2sgZHJpdmVyIGZvciBEYXJ3aW4gLyBNYWMgT1MgWCwgYmFzZWQgb24gdGhlIElPS2l0IEhJRCBBUEkgKi8KLyogV3JpdHRlbiAyMDAxIGJ5IE1heCBIb3JuICovCgojaW5jbHVkZSA8dW5pc3RkLmg+CiNpbmNsdWRlIDxjdHlwZS5oPgojaW5jbHVkZSA8c3lzZXhpdHMuaD4KI2luY2x1ZGUgPG1hY2gvbWFjaC5oPgojaW5jbHVkZSA8bWFjaC9tYWNoX2Vycm9yLmg+CiNpbmNsdWRlIDxJT0tpdC9JT0tpdExpYi5oPgojaW5jbHVkZSA8SU9LaXQvSU9DRlBsdWdJbi5oPgojaWZkZWYgTUFDT1NfMTBfMF80CiNpbmNsdWRlIDxJT0tpdC9oaWRzeXN0ZW0vSU9ISURVc2FnZVRhYmxlcy5oPgojZWxzZQovKiBUaGUgaGVhZGVyIHdhcyBtb3ZlZCBoZXJlIGluIE1hYyBPUyBYIDEwLjEgKi8KI2luY2x1ZGUgPEtlcm5lbC9JT0tpdC9oaWRzeXN0ZW0vSU9ISURVc2FnZVRhYmxlcy5oPgojZW5kaWYKI2luY2x1ZGUgPElPS2l0L2hpZC9JT0hJRExpYi5oPgojaW5jbHVkZSA8SU9LaXQvaGlkL0lPSElES2V5cy5oPgojaW5jbHVkZSA8Q29yZUZvdW5kYXRpb24vQ29yZUZvdW5kYXRpb24uaD4KI2luY2x1ZGUgPENhcmJvbi9DYXJib24uaD4gLyogZm9yIE5ld1B0ckNsZWFyLCBEaXNwb3NlUHRyICovCgojaW5jbHVkZSAiU0RMX2pveXN0aWNrLmgiCiNpbmNsdWRlICIuLi9TRExfc3lzam95c3RpY2suaCIKI2luY2x1ZGUgIi4uL1NETF9qb3lzdGlja19jLmgiCgpzdHJ1Y3QgcmVjRWxlbWVudAp7CglJT0hJREVsZW1lbnRDb29raWUgY29va2llOwkJCQkvKiB1bmlxdWUgdmFsdWUgd2hpY2ggaWRlbnRpZmllcyBlbGVtZW50LCB3aWxsIE5PVCBjaGFuZ2UgKi8KCWxvbmcgbWluOwkJCQkJCQkJLyogcmVwb3J0ZWQgbWluIHZhbHVlIHBvc3NpYmxlICovCglsb25nIG1heDsJCQkJCQkJCS8qIHJlcG9ydGVkIG1heCB2YWx1ZSBwb3NzaWJsZSAqLwojaWYgMAoJLyogVE9ETzogbWF5YmUgc2hvdWxkIGhhbmRsZSB0aGUgZm9sbG93aW5nIHN0dWZmIHNvbWVob3c/ICovCgoJbG9uZyBzY2FsZWRNaW47CQkJCQkJCS8qIHJlcG9ydGVkIHNjYWxlZCBtaW4gdmFsdWUgcG9zc2libGUgKi8KCWxvbmcgc2NhbGVkTWF4OwkJCQkJCQkvKiByZXBvcnRlZCBzY2FsZWQgbWF4IHZhbHVlIHBvc3NpYmxlICovCglsb25nIHNpemU7CQkJCQkJCQkvKiBzaXplIGluIGJpdHMgb2YgZGF0YSByZXR1cm4gZnJvbSBlbGVtZW50ICovCglCb29sZWFuIHJlbGF0aXZlOwkJCQkJCS8qIGFyZSByZXBvcnRzIHJlbGF0aXZlIHRvIGxhc3QgcmVwb3J0IChkZWx0YXMpICovCglCb29sZWFuIHdyYXBwaW5nOwkJCQkJCS8qIGRvZXMgZWxlbWVudCB3cmFwIGFyb3VuZCAob25lIHZhbHVlIGhpZ2hlciB0aGFuIG1heCBpcyBtaW4pICovCglCb29sZWFuIG5vbkxpbmVhcjsJCQkJCQkvKiBhcmUgdGhlIHZhbHVlcyByZXBvcnRlZCBub24tbGluZWFyIHJlbGF0aXZlIHRvIGVsZW1lbnQgbW92ZW1lbnQgKi8KCUJvb2xlYW4gcHJlZmVycmVkU3RhdGU7CQkJCQkvKiBkb2VzIGVsZW1lbnQgaGF2ZSBhIHByZWZlcnJlZCBzdGF0ZSAoc3VjaCBhcyBhIGJ1dHRvbikgKi8KCUJvb2xlYW4gbnVsbFN0YXRlOwkJCQkJCS8qIGRvZXMgZWxlbWVudCBoYXZlIG51bGwgc3RhdGUgKi8KI2VuZGlmIC8qIDAgKi8KCgkvKiBydW50aW1lIHZhcmlhYmxlcyB1c2VkIGZvciBhdXRvLWNhbGlicmF0aW9uICovCglsb25nIG1pblJlcG9ydDsJCQkJCQkJLyogbWluIHJldHVybmVkIHZhbHVlICovCglsb25nIG1heFJlcG9ydDsJCQkJCQkJLyogbWF4IHJldHVybmVkIHZhbHVlICovCgkKCXN0cnVjdCByZWNFbGVtZW50ICogcE5leHQ7CQkJCS8qIG5leHQgZWxlbWVudCBpbiBsaXN0ICovCn07CnR5cGVkZWYgc3RydWN0IHJlY0VsZW1lbnQgcmVjRWxlbWVudDsKCnN0cnVjdCBqb3lzdGlja19od2RhdGEKewoJSU9ISUREZXZpY2VJbnRlcmZhY2UgKiogaW50ZXJmYWNlOwkJLyogaW50ZXJmYWNlIHRvIGRldmljZSwgTlVMTCA9IG5vIGludGVyZmFjZSAqLwoKCWNoYXIgcHJvZHVjdFsyNTZdOwkJCQkJCQkvKiBuYW1lIG9mIHByb2R1Y3QgKi8KCWxvbmcgdXNhZ2U7CQkJCQkJCQkvKiB1c2FnZSBwYWdlIGZyb20gSU9VU0JISUQgUGFyc2VyLmggd2hpY2ggZGVmaW5lcyBnZW5lcmFsIHVzYWdlICovCglsb25nIHVzYWdlUGFnZTsJCQkJCQkJLyogdXNhZ2Ugd2l0aGluIGFib3ZlIHBhZ2UgZnJvbSBJT1VTQkhJRCBQYXJzZXIuaCB3aGljaCBkZWZpbmVzIHNwZWNpZmljIHVzYWdlICovCgoJbG9uZyBheGVzOwkJCQkJCQkJLyogbnVtYmVyIG9mIGF4aXMgKGNhbGN1bGF0ZWQsIG5vdCByZXBvcnRlZCBieSBkZXZpY2UpICovCglsb25nIGJ1dHRvbnM7CQkJCQkJCS8qIG51bWJlciBvZiBidXR0b25zIChjYWxjdWxhdGVkLCBub3QgcmVwb3J0ZWQgYnkgZGV2aWNlKSAqLwoJbG9uZyBoYXRzOwkJCQkJCQkJLyogbnVtYmVyIG9mIGhhdCBzd2l0Y2hlcyAoY2FsY3VsYXRlZCwgbm90IHJlcG9ydGVkIGJ5IGRldmljZSkgKi8KCWxvbmcgZWxlbWVudHM7CQkJCQkJCS8qIG51bWJlciBvZiB0b3RhbCBlbGVtZW50cyAoc2hvdWxkYmUgdG90YWwgb2YgYWJvdmUpIChjYWxjdWxhdGVkLCBub3QgcmVwb3J0ZWQgYnkgZGV2aWNlKSAqLwoKCXJlY0VsZW1lbnQqIGZpcnN0QXhpczsKCXJlY0VsZW1lbnQqIGZpcnN0QnV0dG9uOwoJcmVjRWxlbWVudCogZmlyc3RIYXQ7CgoJaW50IHJlbW92ZWQ7CglpbnQgdW5jZW50ZXJlZDsKCglzdHJ1Y3Qgam95c3RpY2tfaHdkYXRhKiBwTmV4dDsJCQkvKiBuZXh0IGRldmljZSAqLwp9Owp0eXBlZGVmIHN0cnVjdCBqb3lzdGlja19od2RhdGEgcmVjRGV2aWNlOwoKCi8qIExpbmtlZCBsaXN0IG9mIGFsbCBhdmFpbGFibGUgZGV2aWNlcyAqLwpzdGF0aWMgcmVjRGV2aWNlICpncERldmljZUxpc3QgPSBOVUxMOwoKCnN0YXRpYyB2b2lkIEhJRFJlcG9ydEVycm9yTnVtIChjaGFyICogc3RyRXJyb3IsIGxvbmcgbnVtRXJyb3IpCnsKCVNETF9TZXRFcnJvcihzdHJFcnJvcik7Cn0KCnN0YXRpYyB2b2lkIEhJREdldENvbGxlY3Rpb25FbGVtZW50cyAoQ0ZNdXRhYmxlRGljdGlvbmFyeVJlZiBkZXZpY2VQcm9wZXJ0aWVzLCByZWNEZXZpY2UgKnBEZXZpY2UpOwoKLyogcmV0dXJucyBjdXJyZW50IHZhbHVlIGZvciBlbGVtZW50LCBwb2xsaW5nIGVsZW1lbnQKICogd2lsbCByZXR1cm4gMCBvbiBlcnJvciBjb25kaXRpb25zIHdoaWNoIHNob3VsZCBiZSBhY2NvdW50ZWQgZm9yIGJ5IGFwcGxpY2F0aW9uCiAqLwoKc3RhdGljIFNJbnQzMiBISURHZXRFbGVtZW50VmFsdWUgKHJlY0RldmljZSAqcERldmljZSwgcmVjRWxlbWVudCAqcEVsZW1lbnQpCnsKCUlPUmV0dXJuIHJlc3VsdCA9IGtJT1JldHVyblN1Y2Nlc3M7CglJT0hJREV2ZW50U3RydWN0IGhpZEV2ZW50OwoJaGlkRXZlbnQudmFsdWUgPSAwOwoJCglpZiAoTlVMTCAhPSBwRGV2aWNlICYmIE5VTEwgIT0gcEVsZW1lbnQgJiYgTlVMTCAhPSBwRGV2aWNlLT5pbnRlcmZhY2UpCgl7CgkJcmVzdWx0ID0gKCoocERldmljZS0+aW50ZXJmYWNlKSktPmdldEVsZW1lbnRWYWx1ZShwRGV2aWNlLT5pbnRlcmZhY2UsIHBFbGVtZW50LT5jb29raWUsICZoaWRFdmVudCk7CgkJaWYgKGtJT1JldHVyblN1Y2Nlc3MgPT0gcmVzdWx0KQoJCXsKCQkJLyogcmVjb3JkIG1pbiBhbmQgbWF4IGZvciBhdXRvIGNhbGlicmF0aW9uICovCgkJCWlmIChoaWRFdmVudC52YWx1ZSA8IHBFbGVtZW50LT5taW5SZXBvcnQpCgkJCQlwRWxlbWVudC0+bWluUmVwb3J0ID0gaGlkRXZlbnQudmFsdWU7CgkJCWlmIChoaWRFdmVudC52YWx1ZSA+IHBFbGVtZW50LT5tYXhSZXBvcnQpCgkJCQlwRWxlbWVudC0+bWF4UmVwb3J0ID0gaGlkRXZlbnQudmFsdWU7CgkJfQoJfQoKCS8qIGF1dG8gdXNlciBzY2FsZSAqLwoJcmV0dXJuIGhpZEV2ZW50LnZhbHVlOwp9CgpzdGF0aWMgU0ludDMyIEhJRFNjYWxlZENhbGlicmF0ZWRWYWx1ZSAocmVjRGV2aWNlICpwRGV2aWNlLCByZWNFbGVtZW50ICpwRWxlbWVudCwgbG9uZyBtaW4sIGxvbmcgbWF4KQp7CglmbG9hdCBkZXZpY2VTY2FsZSA9IG1heCAtIG1pbjsKCWZsb2F0IHJlYWRTY2FsZSA9IHBFbGVtZW50LT5tYXhSZXBvcnQgLSBwRWxlbWVudC0+bWluUmVwb3J0OwoJU0ludDMyIHZhbHVlID0gSElER2V0RWxlbWVudFZhbHVlKHBEZXZpY2UsIHBFbGVtZW50KTsKCWlmIChyZWFkU2NhbGUgPT0gMCkKCQlyZXR1cm4gdmFsdWU7IC8qIG5vIHNjYWxpbmcgYXQgYWxsICovCgllbHNlCgkJcmV0dXJuICgodmFsdWUgLSBwRWxlbWVudC0+bWluUmVwb3J0KSAqIGRldmljZVNjYWxlIC8gcmVhZFNjYWxlKSArIG1pbjsKfQoKCnN0YXRpYyB2b2lkIEhJRFJlbW92YWxDYWxsYmFjayh2b2lkICogdGFyZ2V0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSU9SZXR1cm4gcmVzdWx0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdm9pZCAqIHJlZmNvbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZvaWQgKiBzZW5kZXIpCnsKCXJlY0RldmljZSAqZGV2aWNlID0gKHJlY0RldmljZSAqKSByZWZjb247CglkZXZpY2UtPnJlbW92ZWQgPSAxOwoJZGV2aWNlLT51bmNlbnRlcmVkID0gMTsKfQoKCgovKiBDcmVhdGUgYW5kIG9wZW4gYW4gaW50ZXJmYWNlIHRvIGRldmljZSwgcmVxdWlyZWQgcHJpb3IgdG8gZXh0cmFjdGluZyB2YWx1ZXMgb3IgYnVpbGRpbmcgcXVldWVzLgogKiBOb3RlOiBhcHBsaWN0aW9uIG5vdyBvd25zIHRoZSBkZXZpY2UgYW5kIG11c3QgY2xvc2UgYW5kIHJlbGVhc2UgaXQgcHJpb3IgdG8gZXhpdGluZwogKi8KCnN0YXRpYyBJT1JldHVybiBISURDcmVhdGVPcGVuRGV2aWNlSW50ZXJmYWNlIChpb19vYmplY3RfdCBoaWREZXZpY2UsIHJlY0RldmljZSAqcERldmljZSkKewoJSU9SZXR1cm4gcmVzdWx0ID0ga0lPUmV0dXJuU3VjY2VzczsKCUhSRVNVTFQgcGx1Z0luUmVzdWx0ID0gU19PSzsKCVNJbnQzMiBzY29yZSA9IDA7CglJT0NGUGx1Z0luSW50ZXJmYWNlICoqIHBwUGx1Z0luSW50ZXJmYWNlID0gTlVMTDsKCQoJaWYgKE5VTEwgPT0gcERldmljZS0+aW50ZXJmYWNlKQoJewoJCXJlc3VsdCA9IElPQ3JlYXRlUGx1Z0luSW50ZXJmYWNlRm9yU2VydmljZSAoaGlkRGV2aWNlLCBrSU9ISUREZXZpY2VVc2VyQ2xpZW50VHlwZUlELAoJCQkJCQkJCQkJCQkJa0lPQ0ZQbHVnSW5JbnRlcmZhY2VJRCwgJnBwUGx1Z0luSW50ZXJmYWNlLCAmc2NvcmUpOwoJCWlmIChrSU9SZXR1cm5TdWNjZXNzID09IHJlc3VsdCkKCQl7CgkJCS8qIENhbGwgYSBtZXRob2Qgb2YgdGhlIGludGVybWVkaWF0ZSBwbHVnLWluIHRvIGNyZWF0ZSB0aGUgZGV2aWNlIGludGVyZmFjZSAqLwoJCQlwbHVnSW5SZXN1bHQgPSAoKnBwUGx1Z0luSW50ZXJmYWNlKS0+UXVlcnlJbnRlcmZhY2UgKHBwUGx1Z0luSW50ZXJmYWNlLAoJCQkJCQkJCUNGVVVJREdldFVVSURCeXRlcyAoa0lPSElERGV2aWNlSW50ZXJmYWNlSUQpLCAodm9pZCAqKSAmKHBEZXZpY2UtPmludGVyZmFjZSkpOwoJCQlpZiAoU19PSyAhPSBwbHVnSW5SZXN1bHQpCgkJCQlISURSZXBvcnRFcnJvck51bSAoIkNvdWxkbtV0IHF1ZXJ5IEhJRCBjbGFzcyBkZXZpY2UgaW50ZXJmYWNlIGZyb20gcGx1Z0luSW50ZXJmYWNlIiwgcGx1Z0luUmVzdWx0KTsKCQkJKCpwcFBsdWdJbkludGVyZmFjZSktPlJlbGVhc2UgKHBwUGx1Z0luSW50ZXJmYWNlKTsKCQl9CgkJZWxzZQoJCQlISURSZXBvcnRFcnJvck51bSAoIkZhaWxlZCB0byBjcmVhdGUgKipwbHVnSW5JbnRlcmZhY2UgdmlhIElPQ3JlYXRlUGx1Z0luSW50ZXJmYWNlRm9yU2VydmljZS4iLCByZXN1bHQpOwoJfQoJaWYgKE5VTEwgIT0gcERldmljZS0+aW50ZXJmYWNlKQoJewoJCXJlc3VsdCA9ICgqKHBEZXZpY2UtPmludGVyZmFjZSkpLT5vcGVuIChwRGV2aWNlLT5pbnRlcmZhY2UsIDApOwoJCWlmIChrSU9SZXR1cm5TdWNjZXNzICE9IHJlc3VsdCkKCQkJSElEUmVwb3J0RXJyb3JOdW0gKCJGYWlsZWQgdG8gb3BlbiBwRGV2aWNlLT5pbnRlcmZhY2UgdmlhIG9wZW4uIiwgcmVzdWx0KTsKCQllbHNlCgkJCSgqKHBEZXZpY2UtPmludGVyZmFjZSkpLT5zZXRSZW1vdmFsQ2FsbGJhY2sgKHBEZXZpY2UtPmludGVyZmFjZSwgSElEUmVtb3ZhbENhbGxiYWNrLCBwRGV2aWNlLCBwRGV2aWNlKTsKCgl9CglyZXR1cm4gcmVzdWx0Owp9CgovKiBDbG9zZXMgYW5kIHJlbGVhc2VzIGludGVyZmFjZSB0byBkZXZpY2UsIHNob3VsZCBiZSBkb25lIHByaW9yIHRvIGV4dGluZyBhcHBsaWNhdGlvbgogKiBOb3RlOiB3aWxsIGhhdmUgbm8gYWZmZWN0IGlmIGRldmljZSBvciBpbnRlcmZhY2UgZG8gbm90IGV4aXN0CiAqIGFwcGxpY2F0aW9uIHdpbGwgIm93biIgdGhlIGRldmljZSBpZiBpbnRlcmZhY2UgaXMgbm90IGNsb3NlZAogKiAoZGV2aWNlIG1heSBoYXZlIHRvIGJlIHBsdWcgYW5kIHJlLXBsdWdnZWQgaW4gZGlmZmVyZW50IGxvY2F0aW9uIHRvIGdldCBpdCB3b3JraW5nIGFnYWluIHdpdGhvdXQgYSByZXN0YXJ0KQogKi8KCnN0YXRpYyBJT1JldHVybiBISURDbG9zZVJlbGVhc2VJbnRlcmZhY2UgKHJlY0RldmljZSAqcERldmljZSkKewoJSU9SZXR1cm4gcmVzdWx0ID0ga0lPUmV0dXJuU3VjY2VzczsKCQoJaWYgKChOVUxMICE9IHBEZXZpY2UpICYmIChOVUxMICE9IHBEZXZpY2UtPmludGVyZmFjZSkpCgl7CgkJLyogY2xvc2UgdGhlIGludGVyZmFjZSAqLwoJCXJlc3VsdCA9ICgqKHBEZXZpY2UtPmludGVyZmFjZSkpLT5jbG9zZSAocERldmljZS0+aW50ZXJmYWNlKTsKCQlpZiAoa0lPUmV0dXJuTm90T3BlbiA9PSByZXN1bHQpCgkJewoJCQkvKiBkbyBub3RoaW5nIGFzIGRldmljZSB3YXMgbm90IG9wZW5lZCwgdGh1cyBjYW4ndCBiZSBjbG9zZWQgKi8KCQl9CgkJZWxzZSBpZiAoa0lPUmV0dXJuU3VjY2VzcyAhPSByZXN1bHQpCgkJCUhJRFJlcG9ydEVycm9yTnVtICgiRmFpbGVkIHRvIGNsb3NlIElPSElERGV2aWNlSW50ZXJmYWNlLiIsIHJlc3VsdCk7CgkJLyogcmVsZWFzZSB0aGUgaW50ZXJmYWNlICovCgkJcmVzdWx0ID0gKCoocERldmljZS0+aW50ZXJmYWNlKSktPlJlbGVhc2UgKHBEZXZpY2UtPmludGVyZmFjZSk7CgkJaWYgKGtJT1JldHVyblN1Y2Nlc3MgIT0gcmVzdWx0KQoJCQlISURSZXBvcnRFcnJvck51bSAoIkZhaWxlZCB0byByZWxlYXNlIElPSElERGV2aWNlSW50ZXJmYWNlLiIsIHJlc3VsdCk7CgkJcERldmljZS0+aW50ZXJmYWNlID0gTlVMTDsKCX0JCglyZXR1cm4gcmVzdWx0Owp9CgovKiBleHRyYWN0cyBhY3R1YWwgc3BlY2lmaWMgZWxlbWVudCBpbmZvcm1hdGlvbiBmcm9tIGVhY2ggZWxlbWVudCBDRiBkaWN0aW9uYXJ5IGVudHJ5ICovCgpzdGF0aWMgdm9pZCBISURHZXRFbGVtZW50SW5mbyAoQ0ZUeXBlUmVmIHJlZkVsZW1lbnQsIHJlY0VsZW1lbnQgKnBFbGVtZW50KQp7Cglsb25nIG51bWJlcjsKCUNGVHlwZVJlZiByZWZUeXBlOwoKCXJlZlR5cGUgPSBDRkRpY3Rpb25hcnlHZXRWYWx1ZSAocmVmRWxlbWVudCwgQ0ZTVFIoa0lPSElERWxlbWVudENvb2tpZUtleSkpOwoJaWYgKHJlZlR5cGUgJiYgQ0ZOdW1iZXJHZXRWYWx1ZSAocmVmVHlwZSwga0NGTnVtYmVyTG9uZ1R5cGUsICZudW1iZXIpKQoJCXBFbGVtZW50LT5jb29raWUgPSAoSU9ISURFbGVtZW50Q29va2llKSBudW1iZXI7CglyZWZUeXBlID0gQ0ZEaWN0aW9uYXJ5R2V0VmFsdWUgKHJlZkVsZW1lbnQsIENGU1RSKGtJT0hJREVsZW1lbnRNaW5LZXkpKTsKCWlmIChyZWZUeXBlICYmIENGTnVtYmVyR2V0VmFsdWUgKHJlZlR5cGUsIGtDRk51bWJlckxvbmdUeXBlLCAmbnVtYmVyKSkKCQlwRWxlbWVudC0+bWluUmVwb3J0ID0gcEVsZW1lbnQtPm1pbiA9IG51bWJlcjsKCXJlZlR5cGUgPSBDRkRpY3Rpb25hcnlHZXRWYWx1ZSAocmVmRWxlbWVudCwgQ0ZTVFIoa0lPSElERWxlbWVudE1heEtleSkpOwoJaWYgKHJlZlR5cGUgJiYgQ0ZOdW1iZXJHZXRWYWx1ZSAocmVmVHlwZSwga0NGTnVtYmVyTG9uZ1R5cGUsICZudW1iZXIpKQoJCXBFbGVtZW50LT5tYXhSZXBvcnQgPSBwRWxlbWVudC0+bWF4ID0gbnVtYmVyOwovKgoJVE9ETzogbWF5YmUgc2hvdWxkIGhhbmRsZSB0aGUgZm9sbG93aW5nIHN0dWZmIHNvbWVob3c/CgoJcmVmVHlwZSA9IENGRGljdGlvbmFyeUdldFZhbHVlIChyZWZFbGVtZW50LCBDRlNUUihrSU9ISURFbGVtZW50U2NhbGVkTWluS2V5KSk7CglpZiAocmVmVHlwZSAmJiBDRk51bWJlckdldFZhbHVlIChyZWZUeXBlLCBrQ0ZOdW1iZXJMb25nVHlwZSwgJm51bWJlcikpCgkJcEVsZW1lbnQtPnNjYWxlZE1pbiA9IG51bWJlcjsKCXJlZlR5cGUgPSBDRkRpY3Rpb25hcnlHZXRWYWx1ZSAocmVmRWxlbWVudCwgQ0ZTVFIoa0lPSElERWxlbWVudFNjYWxlZE1heEtleSkpOwoJaWYgKHJlZlR5cGUgJiYgQ0ZOdW1iZXJHZXRWYWx1ZSAocmVmVHlwZSwga0NGTnVtYmVyTG9uZ1R5cGUsICZudW1iZXIpKQoJCXBFbGVtZW50LT5zY2FsZWRNYXggPSBudW1iZXI7CglyZWZUeXBlID0gQ0ZEaWN0aW9uYXJ5R2V0VmFsdWUgKHJlZkVsZW1lbnQsIENGU1RSKGtJT0hJREVsZW1lbnRTaXplS2V5KSk7CglpZiAocmVmVHlwZSAmJiBDRk51bWJlckdldFZhbHVlIChyZWZUeXBlLCBrQ0ZOdW1iZXJMb25nVHlwZSwgJm51bWJlcikpCgkJcEVsZW1lbnQtPnNpemUgPSBudW1iZXI7CglyZWZUeXBlID0gQ0ZEaWN0aW9uYXJ5R2V0VmFsdWUgKHJlZkVsZW1lbnQsIENGU1RSKGtJT0hJREVsZW1lbnRJc1JlbGF0aXZlS2V5KSk7CglpZiAocmVmVHlwZSkKCQlwRWxlbWVudC0+cmVsYXRpdmUgPSBDRkJvb2xlYW5HZXRWYWx1ZSAocmVmVHlwZSk7CglyZWZUeXBlID0gQ0ZEaWN0aW9uYXJ5R2V0VmFsdWUgKHJlZkVsZW1lbnQsIENGU1RSKGtJT0hJREVsZW1lbnRJc1dyYXBwaW5nS2V5KSk7CglpZiAocmVmVHlwZSkKCQlwRWxlbWVudC0+d3JhcHBpbmcgPSBDRkJvb2xlYW5HZXRWYWx1ZSAocmVmVHlwZSk7CglyZWZUeXBlID0gQ0ZEaWN0aW9uYXJ5R2V0VmFsdWUgKHJlZkVsZW1lbnQsIENGU1RSKGtJT0hJREVsZW1lbnRJc05vbkxpbmVhcktleSkpOwoJaWYgKHJlZlR5cGUpCgkJcEVsZW1lbnQtPm5vbkxpbmVhciA9IENGQm9vbGVhbkdldFZhbHVlIChyZWZUeXBlKTsKCXJlZlR5cGUgPSBDRkRpY3Rpb25hcnlHZXRWYWx1ZSAocmVmRWxlbWVudCwgQ0ZTVFIoa0lPSElERWxlbWVudEhhc1ByZWZlcmVkU3RhdGVLZXkpKTsKCWlmIChyZWZUeXBlKQoJCXBFbGVtZW50LT5wcmVmZXJyZWRTdGF0ZSA9IENGQm9vbGVhbkdldFZhbHVlIChyZWZUeXBlKTsKCXJlZlR5cGUgPSBDRkRpY3Rpb25hcnlHZXRWYWx1ZSAocmVmRWxlbWVudCwgQ0ZTVFIoa0lPSElERWxlbWVudEhhc051bGxTdGF0ZUtleSkpOwoJaWYgKHJlZlR5cGUpCgkJcEVsZW1lbnQtPm51bGxTdGF0ZSA9IENGQm9vbGVhbkdldFZhbHVlIChyZWZUeXBlKTsKKi8KfQkJCQoKLyogZXhhbWluZXMgQ0YgZGljdGlvbmFyeSB2bGF1ZSBpbiBkZXZpY2UgZWxlbWVudCBoaWVyYXJjaHkgdG8gZGV0ZXJtaW5lIGlmIGl0IGlzIGVsZW1lbnQgb2YgaW50ZXJlc3Qgb3IgYSBjb2xsZWN0aW9uIG9mIG1vcmUgZWxlbWVudHMKICogaWYgZWxlbWVudCBvZiBpbnRlcmVzdCBhbGxvY2F0ZSBzdG9yYWdlLCBhZGQgdG8gbGlzdCBhbmQgcmV0cmlldmUgZWxlbWVudCBzcGVjaWZpYyBpbmZvCiAqIGlmIGNvbGxlY3Rpb24gdGhlbiBwYXNzIG9uIHRvIGRlY29uc3RydWN0aW9uIGNvbGxlY3Rpb24gaW50byBhZGRpdGlvbmFsIGluZGl2aWR1YWwgZWxlbWVudHMKICovCgpzdGF0aWMgdm9pZCBISURBZGRFbGVtZW50IChDRlR5cGVSZWYgcmVmRWxlbWVudCwgcmVjRGV2aWNlKiBwRGV2aWNlKQp7CglyZWNFbGVtZW50KiBlbGVtZW50ID0gTlVMTDsKCXJlY0VsZW1lbnQqKiBoZWFkRWxlbWVudCA9IE5VTEw7Cglsb25nIGVsZW1lbnRUeXBlLCB1c2FnZVBhZ2UsIHVzYWdlOwoJQ0ZUeXBlUmVmIHJlZkVsZW1lbnRUeXBlID0gQ0ZEaWN0aW9uYXJ5R2V0VmFsdWUgKHJlZkVsZW1lbnQsIENGU1RSKGtJT0hJREVsZW1lbnRUeXBlS2V5KSk7CglDRlR5cGVSZWYgcmVmVXNhZ2VQYWdlID0gQ0ZEaWN0aW9uYXJ5R2V0VmFsdWUgKHJlZkVsZW1lbnQsIENGU1RSKGtJT0hJREVsZW1lbnRVc2FnZVBhZ2VLZXkpKTsKCUNGVHlwZVJlZiByZWZVc2FnZSA9IENGRGljdGlvbmFyeUdldFZhbHVlIChyZWZFbGVtZW50LCBDRlNUUihrSU9ISURFbGVtZW50VXNhZ2VLZXkpKTsKCgoJaWYgKChyZWZFbGVtZW50VHlwZSkgJiYgKENGTnVtYmVyR2V0VmFsdWUgKHJlZkVsZW1lbnRUeXBlLCBrQ0ZOdW1iZXJMb25nVHlwZSwgJmVsZW1lbnRUeXBlKSkpCgl7CgkJLyogbG9vayBhdCB0eXBlcyBvZiBpbnRlcmVzdCAqLwoJCWlmICgoZWxlbWVudFR5cGUgPT0ga0lPSElERWxlbWVudFR5cGVJbnB1dF9NaXNjKSB8fCAoZWxlbWVudFR5cGUgPT0ga0lPSElERWxlbWVudFR5cGVJbnB1dF9CdXR0b24pIHx8CgkJCShlbGVtZW50VHlwZSA9PSBrSU9ISURFbGVtZW50VHlwZUlucHV0X0F4aXMpKQoJCXsKCQkJaWYgKHJlZlVzYWdlUGFnZSAmJiBDRk51bWJlckdldFZhbHVlIChyZWZVc2FnZVBhZ2UsIGtDRk51bWJlckxvbmdUeXBlLCAmdXNhZ2VQYWdlKSAmJgoJCQkJcmVmVXNhZ2UgJiYgQ0ZOdW1iZXJHZXRWYWx1ZSAocmVmVXNhZ2UsIGtDRk51bWJlckxvbmdUeXBlLCAmdXNhZ2UpKQoJCQl7CgkJCQlzd2l0Y2ggKHVzYWdlUGFnZSkgLyogb25seSBpbnRlcmVzdGVkIGluIGtISURQYWdlX0dlbmVyaWNEZXNrdG9wIGFuZCBrSElEUGFnZV9CdXR0b24gKi8KCQkJCXsKCQkJCQljYXNlIGtISURQYWdlX0dlbmVyaWNEZXNrdG9wOgoJCQkJCQl7CgkJCQkJCQlzd2l0Y2ggKHVzYWdlKSAvKiBsb29rIGF0IHVzYWdlIHRvIGRldGVybWluZSBmdW5jdGlvbiAqLwoJCQkJCQkJewoJCQkJCQkJCWNhc2Uga0hJRFVzYWdlX0dEX1g6CgkJCQkJCQkJY2FzZSBrSElEVXNhZ2VfR0RfWToKCQkJCQkJCQljYXNlIGtISURVc2FnZV9HRF9aOgoJCQkJCQkJCWNhc2Uga0hJRFVzYWdlX0dEX1J4OgoJCQkJCQkJCWNhc2Uga0hJRFVzYWdlX0dEX1J5OgoJCQkJCQkJCWNhc2Uga0hJRFVzYWdlX0dEX1J6OgoJCQkJCQkJCWNhc2Uga0hJRFVzYWdlX0dEX1NsaWRlcjoKCQkJCQkJCQljYXNlIGtISURVc2FnZV9HRF9EaWFsOgoJCQkJCQkJCWNhc2Uga0hJRFVzYWdlX0dEX1doZWVsOgoJCQkJCQkJCQllbGVtZW50ID0gKHJlY0VsZW1lbnQgKikgTmV3UHRyQ2xlYXIgKHNpemVvZiAocmVjRWxlbWVudCkpOwoJCQkJCQkJCQlpZiAoZWxlbWVudCkKCQkJCQkJCQkJewoJCQkJCQkJCQkJcERldmljZS0+YXhlcysrOwoJCQkJCQkJCQkJaGVhZEVsZW1lbnQgPSAmKHBEZXZpY2UtPmZpcnN0QXhpcyk7CgkJCQkJCQkJCX0KCQkJCQkJCQlicmVhazsKCQkJCQkJCQljYXNlIGtISURVc2FnZV9HRF9IYXRzd2l0Y2g6CgkJCQkJCQkJCWVsZW1lbnQgPSAocmVjRWxlbWVudCAqKSBOZXdQdHJDbGVhciAoc2l6ZW9mIChyZWNFbGVtZW50KSk7CgkJCQkJCQkJCWlmIChlbGVtZW50KQoJCQkJCQkJCQl7CgkJCQkJCQkJCQlwRGV2aWNlLT5oYXRzKys7CgkJCQkJCQkJCQloZWFkRWxlbWVudCA9ICYocERldmljZS0+Zmlyc3RIYXQpOwoJCQkJCQkJCQl9CgkJCQkJCQkJYnJlYWs7CgkJCQkJCQl9CQkJCQkJCQoJCQkJCQl9CgkJCQkJCWJyZWFrOwoJCQkJCWNhc2Uga0hJRFBhZ2VfQnV0dG9uOgoJCQkJCQllbGVtZW50ID0gKHJlY0VsZW1lbnQgKikgTmV3UHRyQ2xlYXIgKHNpemVvZiAocmVjRWxlbWVudCkpOwoJCQkJCQlpZiAoZWxlbWVudCkKCQkJCQkJewoJCQkJCQkJcERldmljZS0+YnV0dG9ucysrOwoJCQkJCQkJaGVhZEVsZW1lbnQgPSAmKHBEZXZpY2UtPmZpcnN0QnV0dG9uKTsKCQkJCQkJfQoJCQkJCQlicmVhazsKCQkJCQlkZWZhdWx0OgoJCQkJCQlicmVhazsKCQkJCX0KCQkJfQoJCX0KCQllbHNlIGlmIChrSU9ISURFbGVtZW50VHlwZUNvbGxlY3Rpb24gPT0gZWxlbWVudFR5cGUpCgkJCUhJREdldENvbGxlY3Rpb25FbGVtZW50cyAoKENGTXV0YWJsZURpY3Rpb25hcnlSZWYpIHJlZkVsZW1lbnQsIHBEZXZpY2UpOwoJfQoKCWlmIChlbGVtZW50ICYmIGhlYWRFbGVtZW50KSAvKiBhZGQgdG8gbGlzdCAqLwoJewoJCXBEZXZpY2UtPmVsZW1lbnRzKys7CgkJaWYgKE5VTEwgPT0gKmhlYWRFbGVtZW50KQoJCQkqaGVhZEVsZW1lbnQgPSBlbGVtZW50OwoJCWVsc2UKCQl7CgkJCXJlY0VsZW1lbnQgKmVsZW1lbnRQcmV2aW91cywgKmVsZW1lbnRDdXJyZW50OwoJCQllbGVtZW50Q3VycmVudCA9ICpoZWFkRWxlbWVudDsKCQkJd2hpbGUgKGVsZW1lbnRDdXJyZW50KQoJCQl7CgkJCQllbGVtZW50UHJldmlvdXMgPSBlbGVtZW50Q3VycmVudDsKCQkJCWVsZW1lbnRDdXJyZW50ID0gZWxlbWVudFByZXZpb3VzLT5wTmV4dDsKCQkJfQoJCQllbGVtZW50UHJldmlvdXMtPnBOZXh0ID0gZWxlbWVudDsKCQl9CgkJZWxlbWVudC0+cE5leHQgPSBOVUxMOwoJCUhJREdldEVsZW1lbnRJbmZvIChyZWZFbGVtZW50LCBlbGVtZW50KTsKCX0KfQoKLyogY29sbGVjdHMgaW5mb3JtYXRpb24gZnJvbSBlYWNoIGFycmF5IG1lbWJlciBpbiBkZXZpY2UgZWxlbWVudCBsaXN0IChlYWNoIGFycmF5IG1lbWViZXIgPSBlbGVtZW50KSAqLwoKc3RhdGljIHZvaWQgSElER2V0RWxlbWVudHNDRkFycmF5SGFuZGxlciAoY29uc3Qgdm9pZCAqIHZhbHVlLCB2b2lkICogcGFyYW1ldGVyKQp7CglpZiAoQ0ZHZXRUeXBlSUQgKHZhbHVlKSA9PSBDRkRpY3Rpb25hcnlHZXRUeXBlSUQgKCkpCgkJSElEQWRkRWxlbWVudCAoKENGVHlwZVJlZikgdmFsdWUsIChyZWNEZXZpY2UgKikgcGFyYW1ldGVyKTsKfQoKLyogaGFuZGxlcyByZXRyaWV2YWwgb2YgZWxlbWVudCBpbmZvcm1hdGlvbiBmcm9tIGFycmF5cyBvZiBlbGVtZW50cyBpbiBkZXZpY2UgSU8gcmVnaXN0cnkgaW5mb3JtYXRpb24gKi8KCnN0YXRpYyB2b2lkIEhJREdldEVsZW1lbnRzIChDRlR5cGVSZWYgcmVmRWxlbWVudEN1cnJlbnQsIHJlY0RldmljZSAqcERldmljZSkKewoJQ0ZUeXBlSUQgdHlwZSA9IENGR2V0VHlwZUlEIChyZWZFbGVtZW50Q3VycmVudCk7CglpZiAodHlwZSA9PSBDRkFycmF5R2V0VHlwZUlEKCkpIC8qIGlmIGVsZW1lbnQgaXMgYW4gYXJyYXkgKi8KCXsKCQlDRlJhbmdlIHJhbmdlID0gezAsIENGQXJyYXlHZXRDb3VudCAocmVmRWxlbWVudEN1cnJlbnQpfTsKCQkvKiBDb3VudEVsZW1lbnRzQ0ZBcnJheUhhbmRsZXIgY2FsbGVkIGZvciBlYWNoIGFycmF5IG1lbWJlciAqLwoJCUNGQXJyYXlBcHBseUZ1bmN0aW9uIChyZWZFbGVtZW50Q3VycmVudCwgcmFuZ2UsIEhJREdldEVsZW1lbnRzQ0ZBcnJheUhhbmRsZXIsIHBEZXZpY2UpOwoJfQp9CQkJCgovKiBoYW5kbGVzIGV4dHJhY3RpbmcgZWxlbWVudCBpbmZvcm1hdGlvbiBmcm9tIGVsZW1lbnQgY29sbGVjdGlvbiBDRiB0eXBlcwogKiB1c2VkIGZyb20gdG9wIGxldmVsIGVsZW1lbnQgZGVjb2RpbmcgYW5kIGhpZXJhcmNoeSBkZWNvbnN0cnVjdGlvbiB0byBmbGF0dGVuIGRldmljZSBlbGVtZW50IGxpc3QKICovCgpzdGF0aWMgdm9pZCBISURHZXRDb2xsZWN0aW9uRWxlbWVudHMgKENGTXV0YWJsZURpY3Rpb25hcnlSZWYgZGV2aWNlUHJvcGVydGllcywgcmVjRGV2aWNlICpwRGV2aWNlKQp7CglDRlR5cGVSZWYgcmVmRWxlbWVudFRvcCA9IENGRGljdGlvbmFyeUdldFZhbHVlIChkZXZpY2VQcm9wZXJ0aWVzLCBDRlNUUihrSU9ISURFbGVtZW50S2V5KSk7CglpZiAocmVmRWxlbWVudFRvcCkKCQlISURHZXRFbGVtZW50cyAocmVmRWxlbWVudFRvcCwgcERldmljZSk7Cn0KCi8qIHVzZSB0b3AgbGV2ZWwgZWxlbWVudCB1c2FnZSBwYWdlIGFuZCB1c2FnZSB0byBkaXNjZXJuIGRldmljZSB1c2FnZSBwYWdlIGFuZCB1c2FnZSBzZXR0aW5nIGFwcHJvcHJpYXRlIHZsYXVlcyBpbiBkZXZpY2UgcmVjb3JkICovCgpzdGF0aWMgdm9pZCBISURUb3BMZXZlbEVsZW1lbnRIYW5kbGVyIChjb25zdCB2b2lkICogdmFsdWUsIHZvaWQgKiBwYXJhbWV0ZXIpCnsKCUNGVHlwZVJlZiByZWZDRiA9IDA7CglpZiAoQ0ZHZXRUeXBlSUQgKHZhbHVlKSAhPSBDRkRpY3Rpb25hcnlHZXRUeXBlSUQgKCkpCgkJcmV0dXJuOwoJcmVmQ0YgPSBDRkRpY3Rpb25hcnlHZXRWYWx1ZSAodmFsdWUsIENGU1RSKGtJT0hJREVsZW1lbnRVc2FnZVBhZ2VLZXkpKTsKCWlmICghQ0ZOdW1iZXJHZXRWYWx1ZSAocmVmQ0YsIGtDRk51bWJlckxvbmdUeXBlLCAmKChyZWNEZXZpY2UgKikgcGFyYW1ldGVyKS0+dXNhZ2VQYWdlKSkKCQlTRExfU2V0RXJyb3IgKCJDRk51bWJlckdldFZhbHVlIGVycm9yIHJldHJpZXZpbmcgcERldmljZS0+dXNhZ2VQYWdlLiIpOwoJcmVmQ0YgPSBDRkRpY3Rpb25hcnlHZXRWYWx1ZSAodmFsdWUsIENGU1RSKGtJT0hJREVsZW1lbnRVc2FnZUtleSkpOwoJaWYgKCFDRk51bWJlckdldFZhbHVlIChyZWZDRiwga0NGTnVtYmVyTG9uZ1R5cGUsICYoKHJlY0RldmljZSAqKSBwYXJhbWV0ZXIpLT51c2FnZSkpCgkJU0RMX1NldEVycm9yICgiQ0ZOdW1iZXJHZXRWYWx1ZSBlcnJvciByZXRyaWV2aW5nIHBEZXZpY2UtPnVzYWdlLiIpOwp9CgovKiBleHRyYWN0cyBkZXZpY2UgaW5mbyBmcm9tIENGIGRpY3Rpb25hcnkgcmVjb3JkcyBpbiBJTyByZWdpc3RyeSAqLwoKc3RhdGljIHZvaWQgSElER2V0RGV2aWNlSW5mbyAoaW9fb2JqZWN0X3QgaGlkRGV2aWNlLCBDRk11dGFibGVEaWN0aW9uYXJ5UmVmIGhpZFByb3BlcnRpZXMsIHJlY0RldmljZSAqcERldmljZSkKewoJQ0ZNdXRhYmxlRGljdGlvbmFyeVJlZiB1c2JQcm9wZXJ0aWVzID0gMDsKCWlvX3JlZ2lzdHJ5X2VudHJ5X3QgcGFyZW50MSwgcGFyZW50MjsKCQoJLyogTWFjIE9TIFggY3VycmVudGx5IGlzIG5vdCBtaXJyb3JpbmcgYWxsIFVTQiBwcm9wZXJ0aWVzIHRvIEhJRCBwYWdlIHNvIG5lZWQgdG8gbG9vayBhdCBVU0IgZGV2aWNlIHBhZ2UgYWxzbwoJICogZ2V0IGRpY3Rpb25hcnkgZm9yIHVzYiBwcm9wZXJ0aWVzOiBzdGVwIHVwIHR3byBsZXZlbHMgYW5kIGdldCBDRiBkaWN0aW9uYXJ5IGZvciBVU0IgcHJvcGVydGllcwoJICovCglpZiAoKEtFUk5fU1VDQ0VTUyA9PSBJT1JlZ2lzdHJ5RW50cnlHZXRQYXJlbnRFbnRyeSAoaGlkRGV2aWNlLCBrSU9TZXJ2aWNlUGxhbmUsICZwYXJlbnQxKSkgJiYKCQkoS0VSTl9TVUNDRVNTID09IElPUmVnaXN0cnlFbnRyeUdldFBhcmVudEVudHJ5IChwYXJlbnQxLCBrSU9TZXJ2aWNlUGxhbmUsICZwYXJlbnQyKSkgJiYKCQkoS0VSTl9TVUNDRVNTID09IElPUmVnaXN0cnlFbnRyeUNyZWF0ZUNGUHJvcGVydGllcyAocGFyZW50MiwgJnVzYlByb3BlcnRpZXMsIGtDRkFsbG9jYXRvckRlZmF1bHQsIGtOaWxPcHRpb25zKSkpCgl7CgkJaWYgKHVzYlByb3BlcnRpZXMpCgkJewoJCQlDRlR5cGVSZWYgcmVmQ0YgPSAwOwoJCQkvKiBnZXQgZGV2aWNlIGluZm8KCQkJICogdHJ5IGhpZCBkaWN0aW9uYXJ5IGZpcnN0LCBpZiBmYWlsIHRoZW4gZ28gdG8gdXNiIGRpY3Rpb25hcnkKCQkJICovCgkJCQoJCQkKCQkJLyogZ2V0IHByb2R1Y3QgbmFtZSAqLwoJCQlyZWZDRiA9IENGRGljdGlvbmFyeUdldFZhbHVlIChoaWRQcm9wZXJ0aWVzLCBDRlNUUihrSU9ISURQcm9kdWN0S2V5KSk7CgkJCWlmICghcmVmQ0YpCgkJCQlyZWZDRiA9IENGRGljdGlvbmFyeUdldFZhbHVlICh1c2JQcm9wZXJ0aWVzLCBDRlNUUigiVVNCIFByb2R1Y3QgTmFtZSIpKTsKCQkJaWYgKHJlZkNGKQoJCQl7CgkJCQlpZiAoIUNGU3RyaW5nR2V0Q1N0cmluZyAocmVmQ0YsIHBEZXZpY2UtPnByb2R1Y3QsIDI1NiwgQ0ZTdHJpbmdHZXRTeXN0ZW1FbmNvZGluZyAoKSkpCgkJCQkJU0RMX1NldEVycm9yICgiQ0ZTdHJpbmdHZXRDU3RyaW5nIGVycm9yIHJldHJpZXZpbmcgcERldmljZS0+cHJvZHVjdC4iKTsKCQkJfQoJCQkKCQkJLyogZ2V0IHVzYWdlIHBhZ2UgYW5kIHVzYWdlICovCgkJCXJlZkNGID0gQ0ZEaWN0aW9uYXJ5R2V0VmFsdWUgKGhpZFByb3BlcnRpZXMsIENGU1RSKGtJT0hJRFByaW1hcnlVc2FnZVBhZ2VLZXkpKTsKCQkJaWYgKHJlZkNGKQoJCQl7CgkJCQlpZiAoIUNGTnVtYmVyR2V0VmFsdWUgKHJlZkNGLCBrQ0ZOdW1iZXJMb25nVHlwZSwgJnBEZXZpY2UtPnVzYWdlUGFnZSkpCgkJCQkJU0RMX1NldEVycm9yICgiQ0ZOdW1iZXJHZXRWYWx1ZSBlcnJvciByZXRyaWV2aW5nIHBEZXZpY2UtPnVzYWdlUGFnZS4iKTsKCQkJCXJlZkNGID0gQ0ZEaWN0aW9uYXJ5R2V0VmFsdWUgKGhpZFByb3BlcnRpZXMsIENGU1RSKGtJT0hJRFByaW1hcnlVc2FnZUtleSkpOwoJCQkJaWYgKHJlZkNGKQoJCQkJCWlmICghQ0ZOdW1iZXJHZXRWYWx1ZSAocmVmQ0YsIGtDRk51bWJlckxvbmdUeXBlLCAmcERldmljZS0+dXNhZ2UpKQoJCQkJCQlTRExfU2V0RXJyb3IgKCJDRk51bWJlckdldFZhbHVlIGVycm9yIHJldHJpZXZpbmcgcERldmljZS0+dXNhZ2UuIik7CgkJCX0KCgkJCWlmIChOVUxMID09IHJlZkNGKSAvKiBnZXQgdG9wIGxldmVsIGVsZW1lbnQgSElEIHVzYWdlIHBhZ2Ugb3IgdXNhZ2UgKi8KCQkJewoJCQkJLyogdXNlIHRvcCBsZXZlbCBlbGVtZW50IGluc3RlYWQgKi8KCQkJCUNGVHlwZVJlZiByZWZDRlRvcEVsZW1lbnQgPSAwOwoJCQkJcmVmQ0ZUb3BFbGVtZW50ID0gQ0ZEaWN0aW9uYXJ5R2V0VmFsdWUgKGhpZFByb3BlcnRpZXMsIENGU1RSKGtJT0hJREVsZW1lbnRLZXkpKTsKCQkJCXsKCQkJCQkvKiByZWZDRlRvcEVsZW1lbnQgcG9pbnRzIHRvIGFuIGFycmF5IG9mIGVsZW1lbnQgZGljdGlvbmFyaWVzICovCgkJCQkJQ0ZSYW5nZSByYW5nZSA9IHswLCBDRkFycmF5R2V0Q291bnQgKHJlZkNGVG9wRWxlbWVudCl9OwoJCQkJCUNGQXJyYXlBcHBseUZ1bmN0aW9uIChyZWZDRlRvcEVsZW1lbnQsIHJhbmdlLCBISURUb3BMZXZlbEVsZW1lbnRIYW5kbGVyLCBwRGV2aWNlKTsKCQkJCX0KCQkJfQoKCQkJQ0ZSZWxlYXNlICh1c2JQcm9wZXJ0aWVzKTsKCQl9CgkJZWxzZQoJCQlTRExfU2V0RXJyb3IgKCJJT1JlZ2lzdHJ5RW50cnlDcmVhdGVDRlByb3BlcnRpZXMgZmFpbGVkIHRvIGNyZWF0ZSB1c2JQcm9wZXJ0aWVzLiIpOwoKCQlpZiAoa0lPUmV0dXJuU3VjY2VzcyAhPSBJT09iamVjdFJlbGVhc2UgKHBhcmVudDIpKQoJCQlTRExfU2V0RXJyb3IgKCJJT09iamVjdFJlbGVhc2UgZXJyb3Igd2l0aCBwYXJlbnQyLiIpOwoJCWlmIChrSU9SZXR1cm5TdWNjZXNzICE9IElPT2JqZWN0UmVsZWFzZSAocGFyZW50MSkpCgkJCVNETF9TZXRFcnJvciAoIklPT2JqZWN0UmVsZWFzZSBlcnJvciB3aXRoIHBhcmVudDEuIik7Cgl9Cn0KCgpzdGF0aWMgcmVjRGV2aWNlICpISURCdWlsZERldmljZSAoaW9fb2JqZWN0X3QgaGlkRGV2aWNlKQp7CglyZWNEZXZpY2UgKnBEZXZpY2UgPSAocmVjRGV2aWNlICopIE5ld1B0ckNsZWFyIChzaXplb2YgKHJlY0RldmljZSkpOwoJaWYgKHBEZXZpY2UpCgl7CgkJLyogZ2V0IGRpY3Rpb25hcnkgZm9yIEhJRCBwcm9wZXJ0aWVzICovCgkJQ0ZNdXRhYmxlRGljdGlvbmFyeVJlZiBoaWRQcm9wZXJ0aWVzID0gMDsKCQlrZXJuX3JldHVybl90IHJlc3VsdCA9IElPUmVnaXN0cnlFbnRyeUNyZWF0ZUNGUHJvcGVydGllcyAoaGlkRGV2aWNlLCAmaGlkUHJvcGVydGllcywga0NGQWxsb2NhdG9yRGVmYXVsdCwga05pbE9wdGlvbnMpOwoJCWlmICgocmVzdWx0ID09IEtFUk5fU1VDQ0VTUykgJiYgaGlkUHJvcGVydGllcykKCQl7CgkJCS8qIGNyZWF0ZSBkZXZpY2UgaW50ZXJmYWNlICovCgkJCXJlc3VsdCA9IEhJRENyZWF0ZU9wZW5EZXZpY2VJbnRlcmZhY2UgKGhpZERldmljZSwgcERldmljZSk7CgkJCWlmIChrSU9SZXR1cm5TdWNjZXNzID09IHJlc3VsdCkKCQkJewoJCQkJSElER2V0RGV2aWNlSW5mbyAoaGlkRGV2aWNlLCBoaWRQcm9wZXJ0aWVzLCBwRGV2aWNlKTsgLyogaGlkRGV2aWNlIHVzZWQgdG8gZmluZCBwYXJlbnRzIGluIHJlZ2lzdHJ5IHRyZWUgKi8KCQkJCUhJREdldENvbGxlY3Rpb25FbGVtZW50cyAoaGlkUHJvcGVydGllcywgcERldmljZSk7CgkJCX0KCQkJZWxzZQoJCQl7CgkJCQlEaXNwb3NlUHRyKChQdHIpcERldmljZSk7CgkJCQlwRGV2aWNlID0gTlVMTDsKCQkJfQoJCQlDRlJlbGVhc2UgKGhpZFByb3BlcnRpZXMpOwoJCX0KCQllbHNlCgkJewoJCQlEaXNwb3NlUHRyKChQdHIpcERldmljZSk7CgkJCXBEZXZpY2UgPSBOVUxMOwoJCX0KCX0KCXJldHVybiBwRGV2aWNlOwp9CgovKiBkaXNwb3NlcyBvZiB0aGUgZWxlbWVudCBsaXN0IGFzc29jaWF0ZWQgd2l0aCBhIGRldmljZSBhbmQgdGhlIG1lbW9yeSBhc3NvY2lhdGVkIHdpdGggdGhlIGxpc3QKICovCgpzdGF0aWMgdm9pZCBISUREaXNwb3NlRWxlbWVudExpc3QgKHJlY0VsZW1lbnQgKiplbGVtZW50TGlzdCkKewoJcmVjRWxlbWVudCAqcEVsZW1lbnQgPSAqZWxlbWVudExpc3Q7Cgl3aGlsZSAocEVsZW1lbnQpCgl7CgkJcmVjRWxlbWVudCAqcEVsZW1lbnROZXh0ID0gcEVsZW1lbnQtPnBOZXh0OwoJCURpc3Bvc2VQdHIgKChQdHIpIHBFbGVtZW50KTsKCQlwRWxlbWVudCA9IHBFbGVtZW50TmV4dDsKCX0KCSplbGVtZW50TGlzdCA9IE5VTEw7Cn0KCi8qIGRpc3Bvc2VzIG9mIGEgc2luZ2xlIGRldmljZSwgY2xvc2luZyBhbmQgcmVsZWFzZWluZyBpbnRlcmZhY2UsIGZyZWVpbmcgbWVtb3J5IGZybyBkZXZpY2UgYW5kIGVsZW1lbnRzLCBzZXR0aW5nIGRldmljZSBwb2ludGVyIHRvIE5VTEwKICogYWxsIHlvdXIgZGV2aWNlIG5vIGxvbmdlciBiZWxvbmcgdG8gdXMuLi4gKGkuZS4sIHlvdSBkbyBub3QgJ293bicgdGhlIGRldmljZSBhbnltb3JlKQogKi8KCnN0YXRpYyByZWNEZXZpY2UgKkhJRERpc3Bvc2VEZXZpY2UgKHJlY0RldmljZSAqKnBwRGV2aWNlKQp7CglrZXJuX3JldHVybl90IHJlc3VsdCA9IEtFUk5fU1VDQ0VTUzsKCXJlY0RldmljZSAqcERldmljZU5leHQgPSBOVUxMOwoJaWYgKCpwcERldmljZSkKCXsKCQkvKiBzYXZlIG5leHQgZGV2aWNlIHByaW9yIHRvIGRpc3Bvc2luZyBvZiB0aGlzIGRldmljZSAqLwoJCXBEZXZpY2VOZXh0ID0gKCpwcERldmljZSktPnBOZXh0OwoJCQoJCS8qIGZyZWUgZWxlbWVudCBsaXN0cyAqLwoJCUhJRERpc3Bvc2VFbGVtZW50TGlzdCAoJigqcHBEZXZpY2UpLT5maXJzdEF4aXMpOwoJCUhJRERpc3Bvc2VFbGVtZW50TGlzdCAoJigqcHBEZXZpY2UpLT5maXJzdEJ1dHRvbik7CgkJSElERGlzcG9zZUVsZW1lbnRMaXN0ICgmKCpwcERldmljZSktPmZpcnN0SGF0KTsKCQkKCQlyZXN1bHQgPSBISURDbG9zZVJlbGVhc2VJbnRlcmZhY2UgKCpwcERldmljZSk7IC8qIGZ1bmN0aW9uIHNhbml0eSBjaGVja3MgaW50ZXJmYWNlIHZhbHVlIChub3cgYXBwbGljYXRpb24gZG9lcyBub3Qgb3duIGRldmljZSkgKi8KCQlpZiAoa0lPUmV0dXJuU3VjY2VzcyAhPSByZXN1bHQpCgkJCUhJRFJlcG9ydEVycm9yTnVtICgiSElEQ2xvc2VSZWxlYXNlSW50ZXJmYWNlIGZhaWxlZCB3aGVuIHRyeWluZyB0byBkaXBvc2UgZGV2aWNlLiIsIHJlc3VsdCk7CgkJRGlzcG9zZVB0ciAoKFB0cikqcHBEZXZpY2UpOwoJCSpwcERldmljZSA9IE5VTEw7Cgl9CglyZXR1cm4gcERldmljZU5leHQ7Cn0KCgovKiBGdW5jdGlvbiB0byBzY2FuIHRoZSBzeXN0ZW0gZm9yIGpveXN0aWNrcy4KICogSm95c3RpY2sgMCBzaG91bGQgYmUgdGhlIHN5c3RlbSBkZWZhdWx0IGpveXN0aWNrLgogKiBUaGlzIGZ1bmN0aW9uIHNob3VsZCByZXR1cm4gdGhlIG51bWJlciBvZiBhdmFpbGFibGUgam95c3RpY2tzLCBvciAtMQogKiBvbiBhbiB1bnJlY292ZXJhYmxlIGZhdGFsIGVycm9yLgogKi8KaW50IFNETF9TWVNfSm95c3RpY2tJbml0KHZvaWQpCnsKCUlPUmV0dXJuIHJlc3VsdCA9IGtJT1JldHVyblN1Y2Nlc3M7CgltYWNoX3BvcnRfdCBtYXN0ZXJQb3J0ID0gMDsKCWlvX2l0ZXJhdG9yX3QgaGlkT2JqZWN0SXRlcmF0b3IgPSAwOwoJQ0ZNdXRhYmxlRGljdGlvbmFyeVJlZiBoaWRNYXRjaERpY3Rpb25hcnkgPSBOVUxMOwoJcmVjRGV2aWNlICpkZXZpY2UsICpsYXN0RGV2aWNlOwoJaW9fb2JqZWN0X3QgaW9ISUREZXZpY2VPYmplY3QgPSAwOwoJCglTRExfbnVtam95c3RpY2tzID0gMDsKCQoJaWYgKGdwRGV2aWNlTGlzdCkKCXsKCQlTRExfU2V0RXJyb3IoIkpveXN0aWNrOiBEZXZpY2UgbGlzdCBhbHJlYWR5IGluaXRlZC4iKTsKCQlyZXR1cm4gLTE7Cgl9CgkKCXJlc3VsdCA9IElPTWFzdGVyUG9ydCAoYm9vdHN0cmFwX3BvcnQsICZtYXN0ZXJQb3J0KTsKCWlmIChrSU9SZXR1cm5TdWNjZXNzICE9IHJlc3VsdCkKCXsKCQlTRExfU2V0RXJyb3IoIkpveXN0aWNrOiBJT01hc3RlclBvcnQgZXJyb3Igd2l0aCBib290c3RyYXBfcG9ydC4iKTsKCQlyZXR1cm4gLTE7Cgl9CgoJLyogU2V0IHVwIGEgbWF0Y2hpbmcgZGljdGlvbmFyeSB0byBzZWFyY2ggSS9PIFJlZ2lzdHJ5IGJ5IGNsYXNzIG5hbWUgZm9yIGFsbCBISUQgY2xhc3MgZGV2aWNlcy4gKi8KCWhpZE1hdGNoRGljdGlvbmFyeSA9IElPU2VydmljZU1hdGNoaW5nIChrSU9ISUREZXZpY2VLZXkpOwoJaWYgKGhpZE1hdGNoRGljdGlvbmFyeSkKCXsKCQkvKiBBZGQga2V5IGZvciBkZXZpY2UgdHlwZSAoam95c3RpY2ssIGluIHRoaXMgY2FzZSkgdG8gcmVmaW5lIHRoZSBtYXRjaGluZyBkaWN0aW9uYXJ5LiAqLwoJCQoJCS8qIE5PVEU6IHdlIG5vdyBwZXJmb3JtIHRoaXMgZmlsdGVyaW5nIGxhdGVyCgkJVUludDMyIHVzYWdlUGFnZSA9IGtISURQYWdlX0dlbmVyaWNEZXNrdG9wOwoJCVVJbnQzMiB1c2FnZSA9IGtISURVc2FnZV9HRF9Kb3lzdGljazsKCQlDRk51bWJlclJlZiByZWZVc2FnZSA9IE5VTEwsIHJlZlVzYWdlUGFnZSA9IE5VTEw7CgoJCXJlZlVzYWdlID0gQ0ZOdW1iZXJDcmVhdGUgKGtDRkFsbG9jYXRvckRlZmF1bHQsIGtDRk51bWJlckludFR5cGUsICZ1c2FnZSk7CgkJQ0ZEaWN0aW9uYXJ5U2V0VmFsdWUgKGhpZE1hdGNoRGljdGlvbmFyeSwgQ0ZTVFIgKGtJT0hJRFByaW1hcnlVc2FnZUtleSksIHJlZlVzYWdlKTsKCQlyZWZVc2FnZVBhZ2UgPSBDRk51bWJlckNyZWF0ZSAoa0NGQWxsb2NhdG9yRGVmYXVsdCwga0NGTnVtYmVySW50VHlwZSwgJnVzYWdlUGFnZSk7CgkJQ0ZEaWN0aW9uYXJ5U2V0VmFsdWUgKGhpZE1hdGNoRGljdGlvbmFyeSwgQ0ZTVFIgKGtJT0hJRFByaW1hcnlVc2FnZVBhZ2VLZXkpLCByZWZVc2FnZVBhZ2UpOwoJCSovCgl9CgllbHNlCgl7CgkJU0RMX1NldEVycm9yKCJKb3lzdGljazogRmFpbGVkIHRvIGdldCBISUQgQ0ZNdXRhYmxlRGljdGlvbmFyeVJlZiB2aWEgSU9TZXJ2aWNlTWF0Y2hpbmcuIik7CgkJcmV0dXJuIC0xOwoJfQoJCgkvKi8gTm93IHNlYXJjaCBJL08gUmVnaXN0cnkgZm9yIG1hdGNoaW5nIGRldmljZXMuICovCglyZXN1bHQgPSBJT1NlcnZpY2VHZXRNYXRjaGluZ1NlcnZpY2VzIChtYXN0ZXJQb3J0LCBoaWRNYXRjaERpY3Rpb25hcnksICZoaWRPYmplY3RJdGVyYXRvcik7CgkvKiBDaGVjayBmb3IgZXJyb3JzICovCglpZiAoa0lPUmV0dXJuU3VjY2VzcyAhPSByZXN1bHQpCgl7CgkJU0RMX1NldEVycm9yKCJKb3lzdGljazogQ291bGRuJ3QgY3JlYXRlIGEgSElEIG9iamVjdCBpdGVyYXRvci4iKTsKCQlyZXR1cm4gLTE7Cgl9CglpZiAoIWhpZE9iamVjdEl0ZXJhdG9yKSAvKiB0aGVyZSBhcmUgbm8gam95c3RpY2tzICovCgl7CgkJZ3BEZXZpY2VMaXN0ID0gTlVMTDsKCQlTRExfbnVtam95c3RpY2tzID0gMDsKCQlyZXR1cm4gMDsKCX0KCS8qIElPU2VydmljZUdldE1hdGNoaW5nU2VydmljZXMgY29uc3VtZXMgYSByZWZlcmVuY2UgdG8gdGhlIGRpY3Rpb25hcnksIHNvIHdlIGRvbid0IG5lZWQgdG8gcmVsZWFzZSB0aGUgZGljdGlvbmFyeSByZWYuICovCgoJLyogYnVpbGQgZmxhdCBsaW5rZWQgbGlzdCBvZiBkZXZpY2VzIGZyb20gZGV2aWNlIGl0ZXJhdG9yICovCgoJZ3BEZXZpY2VMaXN0ID0gbGFzdERldmljZSA9IE5VTEw7CgkKCXdoaWxlICgoaW9ISUREZXZpY2VPYmplY3QgPSBJT0l0ZXJhdG9yTmV4dCAoaGlkT2JqZWN0SXRlcmF0b3IpKSkKCXsKCQkvKiBidWlsZCBhIGRldmljZSByZWNvcmQgKi8KCQlkZXZpY2UgPSBISURCdWlsZERldmljZSAoaW9ISUREZXZpY2VPYmplY3QpOwoJCWlmICghZGV2aWNlKQoJCQljb250aW51ZTsKCgkJLyogZHVtcCBkZXZpY2Ugb2JqZWN0LCBpdCBpcyBubyBsb25nZXIgbmVlZGVkICovCgkJcmVzdWx0ID0gSU9PYmplY3RSZWxlYXNlIChpb0hJRERldmljZU9iamVjdCk7Ci8qCQlpZiAoS0VSTl9TVUNDRVNTICE9IHJlc3VsdCkKCQkJSElEUmVwb3J0RXJyb3JOdW0gKCJJT09iamVjdFJlbGVhc2UgZXJyb3Igd2l0aCBpb0hJRERldmljZU9iamVjdC4iLCByZXN1bHQpOwoqLwoKCQkvKiBGaWx0ZXIgZGV2aWNlIGxpc3QgdG8gbm9uLWtleWJvYXJkL21vdXNlIHN0dWZmICovIAoJCWlmICggKGRldmljZS0+dXNhZ2VQYWdlICE9IGtISURQYWdlX0dlbmVyaWNEZXNrdG9wKSB8fAoJCSAgICAgKChkZXZpY2UtPnVzYWdlICE9IGtISURVc2FnZV9HRF9Kb3lzdGljayAmJgoJCSAgICAgIGRldmljZS0+dXNhZ2UgIT0ga0hJRFVzYWdlX0dEX0dhbWVQYWQgJiYKCQkgICAgICBkZXZpY2UtPnVzYWdlICE9IGtISURVc2FnZV9HRF9NdWx0aUF4aXNDb250cm9sbGVyKSkgKSB7CgoJCQkvKiByZWxlYXNlIG1lbW9yeSBmb3IgdGhlIGRldmljZSAqLwoJCQlISUREaXNwb3NlRGV2aWNlICgmZGV2aWNlKTsKCQkJRGlzcG9zZVB0cigoUHRyKWRldmljZSk7CgkJCWNvbnRpbnVlOwoJCX0KCQkKCQkvKiBBZGQgZGV2aWNlIHRvIHRoZSBlbmQgb2YgdGhlIGxpc3QgKi8KCQlpZiAobGFzdERldmljZSkKCQkJbGFzdERldmljZS0+cE5leHQgPSBkZXZpY2U7CgkJZWxzZQoJCQlncERldmljZUxpc3QgPSBkZXZpY2U7CgkJbGFzdERldmljZSA9IGRldmljZTsKCX0KCXJlc3VsdCA9IElPT2JqZWN0UmVsZWFzZSAoaGlkT2JqZWN0SXRlcmF0b3IpOyAvKiByZWxlYXNlIHRoZSBpdGVyYXRvciAqLwoKCS8qIENvdW50IHRoZSB0b3RhbCBudW1iZXIgb2YgZGV2aWNlcyB3ZSBmb3VuZCAqLwoJZGV2aWNlID0gZ3BEZXZpY2VMaXN0OwoJd2hpbGUgKGRldmljZSkKCXsKCQlTRExfbnVtam95c3RpY2tzKys7CgkJZGV2aWNlID0gZGV2aWNlLT5wTmV4dDsKCX0KCQoJcmV0dXJuIFNETF9udW1qb3lzdGlja3M7Cn0KCi8qIEZ1bmN0aW9uIHRvIGdldCB0aGUgZGV2aWNlLWRlcGVuZGVudCBuYW1lIG9mIGEgam95c3RpY2sgKi8KY29uc3QgY2hhciAqU0RMX1NZU19Kb3lzdGlja05hbWUoaW50IGluZGV4KQp7CglyZWNEZXZpY2UgKmRldmljZSA9IGdwRGV2aWNlTGlzdDsKCQoJZm9yICg7IGluZGV4ID4gMDsgaW5kZXgtLSkKCQlkZXZpY2UgPSBkZXZpY2UtPnBOZXh0OwoKCXJldHVybiBkZXZpY2UtPnByb2R1Y3Q7Cn0KCi8qIEZ1bmN0aW9uIHRvIG9wZW4gYSBqb3lzdGljayBmb3IgdXNlLgogKiBUaGUgam95c3RpY2sgdG8gb3BlbiBpcyBzcGVjaWZpZWQgYnkgdGhlIGluZGV4IGZpZWxkIG9mIHRoZSBqb3lzdGljay4KICogVGhpcyBzaG91bGQgZmlsbCB0aGUgbmJ1dHRvbnMgYW5kIG5heGVzIGZpZWxkcyBvZiB0aGUgam95c3RpY2sgc3RydWN0dXJlLgogKiBJdCByZXR1cm5zIDAsIG9yIC0xIGlmIHRoZXJlIGlzIGFuIGVycm9yLgogKi8KaW50IFNETF9TWVNfSm95c3RpY2tPcGVuKFNETF9Kb3lzdGljayAqam95c3RpY2spCnsKCXJlY0RldmljZSAqZGV2aWNlID0gZ3BEZXZpY2VMaXN0OwoJaW50IGluZGV4OwoJCglmb3IgKGluZGV4ID0gam95c3RpY2stPmluZGV4OyBpbmRleCA+IDA7IGluZGV4LS0pCgkJZGV2aWNlID0gZGV2aWNlLT5wTmV4dDsKCglqb3lzdGljay0+aHdkYXRhID0gZGV2aWNlOwoJam95c3RpY2stPm5hbWUgPSBkZXZpY2UtPnByb2R1Y3Q7CgoJam95c3RpY2stPm5heGVzID0gZGV2aWNlLT5heGVzOwoJam95c3RpY2stPm5oYXRzID0gZGV2aWNlLT5oYXRzOwoJam95c3RpY2stPm5iYWxscyA9IDA7Cglqb3lzdGljay0+bmJ1dHRvbnMgPSBkZXZpY2UtPmJ1dHRvbnM7CgoJcmV0dXJuIDA7Cn0KCi8qIEZ1bmN0aW9uIHRvIHVwZGF0ZSB0aGUgc3RhdGUgb2YgYSBqb3lzdGljayAtIGNhbGxlZCBhcyBhIGRldmljZSBwb2xsLgogKiBUaGlzIGZ1bmN0aW9uIHNob3VsZG4ndCB1cGRhdGUgdGhlIGpveXN0aWNrIHN0cnVjdHVyZSBkaXJlY3RseSwKICogYnV0IGluc3RlYWQgc2hvdWxkIGNhbGwgU0RMX1ByaXZhdGVKb3lzdGljayooKSB0byBkZWxpdmVyIGV2ZW50cwogKiBhbmQgdXBkYXRlIGpveXN0aWNrIGRldmljZSBzdGF0ZS4KICovCnZvaWQgU0RMX1NZU19Kb3lzdGlja1VwZGF0ZShTRExfSm95c3RpY2sgKmpveXN0aWNrKQp7CglyZWNEZXZpY2UgKmRldmljZSA9IGpveXN0aWNrLT5od2RhdGE7CglyZWNFbGVtZW50ICplbGVtZW50OwoJU0ludDMyIHZhbHVlLCByYW5nZTsKCWludCBpOwoKCWlmIChkZXZpY2UtPnJlbW92ZWQpICAvKiBkZXZpY2Ugd2FzIHVucGx1Z2dlZDsgaWdub3JlIGl0LiAqLwoJewoJCWlmIChkZXZpY2UtPnVuY2VudGVyZWQpCgkJewoJCQlkZXZpY2UtPnVuY2VudGVyZWQgPSAwOwoKCQkJLyogVGVsbCB0aGUgYXBwIHRoYXQgZXZlcnl0aGluZyBpcyBjZW50ZXJlZC91bnByZXNzZWQuLi4gKi8KCQkJZm9yIChpID0gMDsgaSA8IGRldmljZS0+YXhlczsgaSsrKQoJCQkJU0RMX1ByaXZhdGVKb3lzdGlja0F4aXMoam95c3RpY2ssIGksIDApOwoKCQkJZm9yIChpID0gMDsgaSA8IGRldmljZS0+YnV0dG9uczsgaSsrKQoJCQkJU0RMX1ByaXZhdGVKb3lzdGlja0J1dHRvbihqb3lzdGljaywgaSwgMCk7CgoJCQlmb3IgKGkgPSAwOyBpIDwgZGV2aWNlLT5oYXRzOyBpKyspCgkJCQlTRExfUHJpdmF0ZUpveXN0aWNrSGF0KGpveXN0aWNrLCBpLCBTRExfSEFUX0NFTlRFUkVEKTsKCQl9CgoJCXJldHVybjsKCX0KCgllbGVtZW50ID0gZGV2aWNlLT5maXJzdEF4aXM7CglpID0gMDsKCXdoaWxlIChlbGVtZW50KQoJewoJCXZhbHVlID0gSElEU2NhbGVkQ2FsaWJyYXRlZFZhbHVlKGRldmljZSwgZWxlbWVudCwgLTMyNzY4LCAzMjc2Nyk7CgkJaWYgKCB2YWx1ZSAhPSBqb3lzdGljay0+YXhlc1tpXSApCgkJCVNETF9Qcml2YXRlSm95c3RpY2tBeGlzKGpveXN0aWNrLCBpLCB2YWx1ZSk7CgkJZWxlbWVudCA9IGVsZW1lbnQtPnBOZXh0OwoJCSsraTsKCX0KCQoJZWxlbWVudCA9IGRldmljZS0+Zmlyc3RCdXR0b247CglpID0gMDsKCXdoaWxlIChlbGVtZW50KQoJewoJCXZhbHVlID0gSElER2V0RWxlbWVudFZhbHVlKGRldmljZSwgZWxlbWVudCk7CiAgICAgICAgaWYgKHZhbHVlID4gMSkgIC8qIGhhbmRsZSBwcmVzc3VyZS1zZW5zaXRpdmUgYnV0dG9ucyAqLwogICAgICAgICAgICB2YWx1ZSA9IDE7CgkJaWYgKCB2YWx1ZSAhPSBqb3lzdGljay0+YnV0dG9uc1tpXSApCgkJCVNETF9Qcml2YXRlSm95c3RpY2tCdXR0b24oam95c3RpY2ssIGksIHZhbHVlKTsKCQllbGVtZW50ID0gZWxlbWVudC0+cE5leHQ7CgkJKytpOwoJfQoJICAgIAoJZWxlbWVudCA9IGRldmljZS0+Zmlyc3RIYXQ7CglpID0gMDsKCXdoaWxlIChlbGVtZW50KQoJewoJCVVpbnQ4IHBvcyA9IDA7CgoJCXJhbmdlID0gKGVsZW1lbnQtPm1heCAtIGVsZW1lbnQtPm1pbiArIDEpOwoJCXZhbHVlID0gSElER2V0RWxlbWVudFZhbHVlKGRldmljZSwgZWxlbWVudCkgLSBlbGVtZW50LT5taW47CgkJaWYgKHJhbmdlID09IDQpIC8qIDQgcG9zaXRpb24gaGF0c3dpdGNoIC0gc2NhbGUgdXAgdmFsdWUgKi8KCQkJdmFsdWUgKj0gMjsKCQllbHNlIGlmIChyYW5nZSAhPSA4KSAvKiBOZWl0aGVyIGEgNCBub3IgOCBwb3NpdGlvbnMgLSBmYWxsIGJhY2sgdG8gZGVmYXVsdCBwb3NpdGlvbiAoY2VudGVyZWQpICovCgkJCXZhbHVlID0gLTE7CgkJc3dpdGNoKHZhbHVlKQoJCXsKCQkJY2FzZSAwOgoJCQkJcG9zID0gU0RMX0hBVF9VUDsKCQkJCWJyZWFrOwoJCQljYXNlIDE6CgkJCQlwb3MgPSBTRExfSEFUX1JJR0hUVVA7CgkJCQlicmVhazsKCQkJY2FzZSAyOgoJCQkJcG9zID0gU0RMX0hBVF9SSUdIVDsKCQkJCWJyZWFrOwoJCQljYXNlIDM6CgkJCQlwb3MgPSBTRExfSEFUX1JJR0hURE9XTjsKCQkJCWJyZWFrOwoJCQljYXNlIDQ6CgkJCQlwb3MgPSBTRExfSEFUX0RPV047CgkJCQlicmVhazsKCQkJY2FzZSA1OgoJCQkJcG9zID0gU0RMX0hBVF9MRUZURE9XTjsKCQkJCWJyZWFrOwoJCQljYXNlIDY6CgkJCQlwb3MgPSBTRExfSEFUX0xFRlQ7CgkJCQlicmVhazsKCQkJY2FzZSA3OgoJCQkJcG9zID0gU0RMX0hBVF9MRUZUVVA7CgkJCQlicmVhazsKCQkJZGVmYXVsdDoKCQkJCS8qIEV2ZXJ5IG90aGVyIHZhbHVlIGlzIG1hcHBlZCB0byBjZW50ZXIuIFdlIGRvIHRoYXQgYmVjYXVzZSBzb21lCgkJCQkgKiBqb3lzdGlja3MgdXNlIDggYW5kIHNvbWUgMTUgZm9yIHRoaXMgdmFsdWUsIGFuZCBhcHBhcmVudGx5CgkJCQkgKiB0aGVyZSBhcmUgZXZlbiBtb3JlIHZhcmlhbnRzIG91dCB0aGVyZSAtIHNvIHdlIHRyeSB0byBiZSBnZW5lcm91cy4KCQkJCSAqLwoJCQkJcG9zID0gU0RMX0hBVF9DRU5URVJFRDsKCQkJCWJyZWFrOwoJCX0KCQlpZiAoIHBvcyAhPSBqb3lzdGljay0+aGF0c1tpXSApCgkJCVNETF9Qcml2YXRlSm95c3RpY2tIYXQoam95c3RpY2ssIGksIHBvcyk7CgkJZWxlbWVudCA9IGVsZW1lbnQtPnBOZXh0OwoJCSsraTsKCX0KCQoJcmV0dXJuOwp9CgovKiBGdW5jdGlvbiB0byBjbG9zZSBhIGpveXN0aWNrIGFmdGVyIHVzZSAqLwp2b2lkIFNETF9TWVNfSm95c3RpY2tDbG9zZShTRExfSm95c3RpY2sgKmpveXN0aWNrKQp7CgkvKiBTaG91bGQgd2UgZG8gYW55dGhpbmcgaGVyZT8gKi8KCXJldHVybjsKfQoKLyogRnVuY3Rpb24gdG8gcGVyZm9ybSBhbnkgc3lzdGVtLXNwZWNpZmljIGpveXN0aWNrIHJlbGF0ZWQgY2xlYW51cCAqLwp2b2lkIFNETF9TWVNfSm95c3RpY2tRdWl0KHZvaWQpCnsKCXdoaWxlIChOVUxMICE9IGdwRGV2aWNlTGlzdCkKCQlncERldmljZUxpc3QgPSBISUREaXNwb3NlRGV2aWNlICgmZ3BEZXZpY2VMaXN0KTsKfQoKI2VuZGlmIC8qIFNETF9KT1lTVElDS19JT0tJVCAqLwo=