LyogIAkJCURpcmVjdFNvdW5kCiAqCiAqIENvcHlyaWdodCAxOTk4IE1hcmN1cyBNZWlzc25lcgogKiBDb3B5cmlnaHQgMTk5OCBSb2IgUmlnZ3MKICogQ29weXJpZ2h0IDIwMDAtMjAwMiBUcmFuc0dhbWluZyBUZWNobm9sb2dpZXMsIEluYy4KICoKICogVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vcgogKiBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlcgogKiB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KICoKICogVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsCiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VCiAqIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZQogKiBGb3VuZGF0aW9uLCBJbmMuLCA1OSBUZW1wbGUgUGxhY2UsIFN1aXRlIDMzMCwgQm9zdG9uLCBNQSAgMDIxMTEtMTMwNyAgVVNBCiAqLwoKI2luY2x1ZGUgPGFzc2VydC5oPgojaW5jbHVkZSA8c3RkYXJnLmg+CiNpbmNsdWRlIDxtYXRoLmg+CS8qIEluc29tbmlhIC0gcG93KCkgZnVuY3Rpb24gKi8KCiNkZWZpbmUgTk9OQU1FTEVTU1NUUlVDVAojZGVmaW5lIE5PTkFNRUxFU1NVTklPTgojaW5jbHVkZSAid2luZGVmLmgiCiNpbmNsdWRlICJ3aW5iYXNlLmgiCiNpbmNsdWRlICJtbXN5c3RlbS5oIgojaW5jbHVkZSAid2lucmVnLmgiCiNpbmNsdWRlICJ3aW50ZXJubC5oIgojaW5jbHVkZSAid2luZS9kZWJ1Zy5oIgojaW5jbHVkZSAiZHNvdW5kLmgiCiNpbmNsdWRlICJkc2RyaXZlci5oIgojaW5jbHVkZSAiZHNvdW5kX3ByaXZhdGUuaCIKCldJTkVfREVGQVVMVF9ERUJVR19DSEFOTkVMKGRzb3VuZCk7Cgp2b2lkIERTT1VORF9SZWNhbGNWb2xQYW4oUERTVk9MVU1FUEFOIHZvbHBhbikKewoJZG91YmxlIHRlbXA7CglUUkFDRSgiKCVwKVxuIix2b2xwYW4pOwoKCVRSQUNFKCJWb2w9JWxkIFBhbj0lbGRcbiIsIHZvbHBhbi0+bFZvbHVtZSwgdm9scGFuLT5sUGFuKTsKCS8qIHRoZSBBbXBGYWN0b3JzIGFyZSBleHByZXNzZWQgaW4gMTYuMTYgZml4ZWQgcG9pbnQgKi8KCXZvbHBhbi0+ZHdWb2xBbXBGYWN0b3IgPSAoVUxPTkcpIChwb3coMi4wLCB2b2xwYW4tPmxWb2x1bWUgLyA2MDAuMCkgKiAweGZmZmYpOwoJLyogRklYTUU6IGR3UGFue0xlZnR8UmlnaHR9QW1wRmFjdG9yICovCgoJLyogRklYTUU6IHVzZSBjYWxjdWxhdGVkIHZvbCBhbmQgcGFuIGFtcGZhY3RvcnMgKi8KCXRlbXAgPSAoZG91YmxlKSAodm9scGFuLT5sVm9sdW1lIC0gKHZvbHBhbi0+bFBhbiA+IDAgPyB2b2xwYW4tPmxQYW4gOiAwKSk7Cgl2b2xwYW4tPmR3VG90YWxMZWZ0QW1wRmFjdG9yID0gKFVMT05HKSAocG93KDIuMCwgdGVtcCAvIDYwMC4wKSAqIDB4ZmZmZik7Cgl0ZW1wID0gKGRvdWJsZSkgKHZvbHBhbi0+bFZvbHVtZSArICh2b2xwYW4tPmxQYW4gPCAwID8gdm9scGFuLT5sUGFuIDogMCkpOwoJdm9scGFuLT5kd1RvdGFsUmlnaHRBbXBGYWN0b3IgPSAoVUxPTkcpIChwb3coMi4wLCB0ZW1wIC8gNjAwLjApICogMHhmZmZmKTsKCglUUkFDRSgibGVmdCA9ICVseCwgcmlnaHQgPSAlbHhcbiIsIHZvbHBhbi0+ZHdUb3RhbExlZnRBbXBGYWN0b3IsIHZvbHBhbi0+ZHdUb3RhbFJpZ2h0QW1wRmFjdG9yKTsKfQoKdm9pZCBEU09VTkRfQW1wRmFjdG9yVG9Wb2xQYW4oUERTVk9MVU1FUEFOIHZvbHBhbikKewogICAgZG91YmxlIGxlZnQscmlnaHQ7CiAgICBUUkFDRSgiKCVwKVxuIix2b2xwYW4pOwoKICAgIFRSQUNFKCJsZWZ0PSVseCwgcmlnaHQ9JWx4XG4iLHZvbHBhbi0+ZHdUb3RhbExlZnRBbXBGYWN0b3Isdm9scGFuLT5kd1RvdGFsUmlnaHRBbXBGYWN0b3IpOwogICAgaWYgKHZvbHBhbi0+ZHdUb3RhbExlZnRBbXBGYWN0b3I9PTApCiAgICAgICAgbGVmdD0tMTAwMDA7CiAgICBlbHNlCiAgICAgICAgbGVmdD02MDAgKiBsb2coKChkb3VibGUpdm9scGFuLT5kd1RvdGFsTGVmdEFtcEZhY3RvcikgLyAweGZmZmYpIC8gbG9nKDIpOwogICAgaWYgKHZvbHBhbi0+ZHdUb3RhbFJpZ2h0QW1wRmFjdG9yPT0wKQogICAgICAgIHJpZ2h0PS0xMDAwMDsKICAgIGVsc2UKICAgICAgICByaWdodD02MDAgKiBsb2coKChkb3VibGUpdm9scGFuLT5kd1RvdGFsUmlnaHRBbXBGYWN0b3IpIC8gMHhmZmZmKSAvIGxvZygyKTsKICAgIGlmIChsZWZ0PHJpZ2h0KQogICAgewogICAgICAgIHZvbHBhbi0+bFZvbHVtZT1yaWdodDsKICAgICAgICB2b2xwYW4tPmR3Vm9sQW1wRmFjdG9yPXZvbHBhbi0+ZHdUb3RhbFJpZ2h0QW1wRmFjdG9yOwogICAgfQogICAgZWxzZQogICAgewogICAgICAgIHZvbHBhbi0+bFZvbHVtZT1sZWZ0OwogICAgICAgIHZvbHBhbi0+ZHdWb2xBbXBGYWN0b3I9dm9scGFuLT5kd1RvdGFsTGVmdEFtcEZhY3RvcjsKICAgIH0KICAgIGlmICh2b2xwYW4tPmxWb2x1bWUgPCAtMTAwMDApCiAgICAgICAgdm9scGFuLT5sVm9sdW1lPS0xMDAwMDsKICAgIHZvbHBhbi0+bFBhbj1yaWdodC1sZWZ0OwogICAgaWYgKHZvbHBhbi0+bFBhbiA8IC0xMDAwMCkKICAgICAgICB2b2xwYW4tPmxQYW49LTEwMDAwOwoKICAgIFRSQUNFKCJWb2w9JWxkIFBhbj0lbGRcbiIsIHZvbHBhbi0+bFZvbHVtZSwgdm9scGFuLT5sUGFuKTsKfQoKdm9pZCBEU09VTkRfUmVjYWxjRm9ybWF0KElEaXJlY3RTb3VuZEJ1ZmZlckltcGwgKmRzYikKewoJVFJBQ0UoIiglcClcbiIsZHNiKTsKCgkvKiBjYWxjdWxhdGUgdGhlIDEwbXMgd3JpdGUgbGVhZCAqLwoJZHNiLT53cml0ZWxlYWQgPSAoZHNiLT5mcmVxIC8gMTAwKSAqIGRzYi0+cHdmeC0+bkJsb2NrQWxpZ247Cn0KCnZvaWQgRFNPVU5EX0NoZWNrRXZlbnQoSURpcmVjdFNvdW5kQnVmZmVySW1wbCAqZHNiLCBpbnQgbGVuKQp7CglpbnQJCQlpOwoJRFdPUkQJCQlvZmZzZXQ7CglMUERTQlBPU0lUSU9OTk9USUZZCWV2ZW50OwoJVFJBQ0UoIiglcCwlZClcbiIsZHNiLGxlbik7CgoJaWYgKGRzYi0+bnJvZm5vdGlmaWVzID09IDApCgkJcmV0dXJuOwoKCVRSQUNFKCIoJXApIGJ1ZmxlbiA9ICVsZCwgcGxheXBvcyA9ICVsZCwgbGVuID0gJWRcbiIsCgkJZHNiLCBkc2ItPmJ1ZmxlbiwgZHNiLT5wbGF5cG9zLCBsZW4pOwoJZm9yIChpID0gMDsgaSA8IGRzYi0+bnJvZm5vdGlmaWVzIDsgaSsrKSB7CgkJZXZlbnQgPSBkc2ItPm5vdGlmaWVzICsgaTsKCQlvZmZzZXQgPSBldmVudC0+ZHdPZmZzZXQ7CgkJVFJBQ0UoImNoZWNraW5nICVkLCBwb3NpdGlvbiAlbGQsIGV2ZW50ID0gJXBcbiIsCgkJCWksIG9mZnNldCwgZXZlbnQtPmhFdmVudE5vdGlmeSk7CgkJLyogRFNCUE5fT0ZGU0VUU1RPUCBoYXMgdG8gYmUgdGhlIGxhc3QgZWxlbWVudC4gU28gdGhpcyBpcyAqLwoJCS8qIE9LLiBbSW5zaWRlIERpcmVjdFgsIHAyNzRdICovCgkJLyogICovCgkJLyogVGhpcyBhbHNvIG1lYW5zIHdlIGNhbid0IHNvcnQgdGhlIGVudHJpZXMgYnkgb2Zmc2V0LCAqLwoJCS8qIGJlY2F1c2UgRFNCUE5fT0ZGU0VUU1RPUCA9PSAtMSAqLwoJCWlmIChvZmZzZXQgPT0gRFNCUE5fT0ZGU0VUU1RPUCkgewoJCQlpZiAoZHNiLT5zdGF0ZSA9PSBTVEFURV9TVE9QUEVEKSB7CgkJCQlTZXRFdmVudChldmVudC0+aEV2ZW50Tm90aWZ5KTsKCQkJCVRSQUNFKCJzaWduYWxsZWQgZXZlbnQgJXAgKCVkKVxuIiwgZXZlbnQtPmhFdmVudE5vdGlmeSwgaSk7CgkJCQlyZXR1cm47CgkJCX0gZWxzZQoJCQkJcmV0dXJuOwoJCX0KCQlpZiAoKGRzYi0+cGxheXBvcyArIGxlbikgPj0gZHNiLT5idWZsZW4pIHsKCQkJaWYgKChvZmZzZXQgPCAoKGRzYi0+cGxheXBvcyArIGxlbikgJSBkc2ItPmJ1ZmxlbikpIHx8CgkJCSAgICAob2Zmc2V0ID49IGRzYi0+cGxheXBvcykpIHsKCQkJCVRSQUNFKCJzaWduYWxsZWQgZXZlbnQgJXAgKCVkKVxuIiwgZXZlbnQtPmhFdmVudE5vdGlmeSwgaSk7CgkJCQlTZXRFdmVudChldmVudC0+aEV2ZW50Tm90aWZ5KTsKCQkJfQoJCX0gZWxzZSB7CgkJCWlmICgob2Zmc2V0ID49IGRzYi0+cGxheXBvcykgJiYgKG9mZnNldCA8IChkc2ItPnBsYXlwb3MgKyBsZW4pKSkgewoJCQkJVFJBQ0UoInNpZ25hbGxlZCBldmVudCAlcCAoJWQpXG4iLCBldmVudC0+aEV2ZW50Tm90aWZ5LCBpKTsKCQkJCVNldEV2ZW50KGV2ZW50LT5oRXZlbnROb3RpZnkpOwoJCQl9CgkJfQoJfQp9CgovKiBXQVYgZm9ybWF0IGluZm8gY2FuIGJlIGZvdW5kIGF0OgogKgogKiAgICBodHRwOi8vd3d3LmN3aS5ubC9mdHAvYXVkaW8vQXVkaW9Gb3JtYXRzLnBhcnQyCiAqICAgIGZ0cDovL2Z0cC5jd2kubmwvcHViL2F1ZGlvL1JJRkYtZm9ybWF0CiAqCiAqIEltcG9ydCBwb2ludHMgdG8gcmVtZW1iZXI6CiAqICAgIDgtYml0IFdBViBpcyB1bnNpZ25lZAogKiAgICAxNi1iaXQgV0FWIGlzIHNpZ25lZAogKi8KIC8qIFVzZSB0aGUgc2FtZSBmb3JtdWxhcyBhcyBwY21jb252ZXJ0ZXIuYyAqLwpzdGF0aWMgaW5saW5lIElOVDE2IGN2dFU4dG9TMTYoQllURSBiKQp7CiAgICByZXR1cm4gKHNob3J0KSgoYisoYiA8PCA4KSktMzI3NjgpOwp9CgpzdGF0aWMgaW5saW5lIEJZVEUgY3Z0UzE2dG9VOChJTlQxNiBzKQp7CiAgICByZXR1cm4gKHMgPj4gOCkgXiAodW5zaWduZWQgY2hhcikweDgwOwp9CgpzdGF0aWMgaW5saW5lIHZvaWQgY3BfZmllbGRzKGNvbnN0IElEaXJlY3RTb3VuZEJ1ZmZlckltcGwgKmRzYiwgQllURSAqaWJ1ZiwgQllURSAqb2J1ZiApCnsKCURpcmVjdFNvdW5kRGV2aWNlICogZGV2aWNlID0gZHNiLT5kc291bmQtPmRldmljZTsKICAgICAgICBJTlQgZmwsZnI7CgogICAgICAgIGlmIChkc2ItPnB3ZngtPndCaXRzUGVyU2FtcGxlID09IDgpICB7CiAgICAgICAgICAgICAgICBpZiAoZGV2aWNlLT5wd2Z4LT53Qml0c1BlclNhbXBsZSA9PSA4ICYmCiAgICAgICAgICAgICAgICAgICAgZGV2aWNlLT5wd2Z4LT5uQ2hhbm5lbHMgPT0gZHNiLT5wd2Z4LT5uQ2hhbm5lbHMpIHsKICAgICAgICAgICAgICAgICAgICAgICAgLyogYXZvaWQgbmVlZGxlc3MgOC0+MTYtPjggY29udmVyc2lvbiAqLwogICAgICAgICAgICAgICAgICAgICAgICAqb2J1Zj0qaWJ1ZjsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGRzYi0+cHdmeC0+bkNoYW5uZWxzPT0yKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICoob2J1ZisxKT0qKGlidWYrMSk7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGZsID0gY3Z0VTh0b1MxNigqaWJ1Zik7CiAgICAgICAgICAgICAgICBmciA9IChkc2ItPnB3ZngtPm5DaGFubmVscz09MiA/IGN2dFU4dG9TMTYoKihpYnVmICsgMSkpIDogZmwpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBmbCA9ICooKElOVDE2ICopaWJ1Zik7CiAgICAgICAgICAgICAgICBmciA9IChkc2ItPnB3ZngtPm5DaGFubmVscz09MiA/ICooKChJTlQxNiAqKWlidWYpICsgMSkgIDogZmwpOwogICAgICAgIH0KCiAgICAgICAgaWYgKGRldmljZS0+cHdmeC0+bkNoYW5uZWxzID09IDIpIHsKICAgICAgICAgICAgICAgIGlmIChkZXZpY2UtPnB3ZngtPndCaXRzUGVyU2FtcGxlID09IDgpIHsKICAgICAgICAgICAgICAgICAgICAgICAgKm9idWYgPSBjdnRTMTZ0b1U4KGZsKTsKICAgICAgICAgICAgICAgICAgICAgICAgKihvYnVmICsgMSkgPSBjdnRTMTZ0b1U4KGZyKTsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKGRldmljZS0+cHdmeC0+d0JpdHNQZXJTYW1wbGUgPT0gMTYpIHsKICAgICAgICAgICAgICAgICAgICAgICAgKigoSU5UMTYgKilvYnVmKSA9IGZsOwogICAgICAgICAgICAgICAgICAgICAgICAqKCgoSU5UMTYgKilvYnVmKSArIDEpID0gZnI7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaWYgKGRldmljZS0+cHdmeC0+bkNoYW5uZWxzID09IDEpIHsKICAgICAgICAgICAgICAgIGZsID0gKGZsICsgZnIpID4+IDE7CiAgICAgICAgICAgICAgICBpZiAoZGV2aWNlLT5wd2Z4LT53Qml0c1BlclNhbXBsZSA9PSA4KSB7CiAgICAgICAgICAgICAgICAgICAgICAgICpvYnVmID0gY3Z0UzE2dG9VOChmbCk7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmIChkZXZpY2UtPnB3ZngtPndCaXRzUGVyU2FtcGxlID09IDE2KSB7CiAgICAgICAgICAgICAgICAgICAgICAgICooKElOVDE2ICopb2J1ZikgPSBmbDsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgfQogICAgICAgIH0KfQoKLyogTm93IHdpdGggUGVyZmVjdFBpdGNoICh0bSkgdGVjaG5vbG9neSAqLwpzdGF0aWMgSU5UIERTT1VORF9NaXhlck5vcm0oSURpcmVjdFNvdW5kQnVmZmVySW1wbCAqZHNiLCBCWVRFICpidWYsIElOVCBsZW4pCnsKCUlOVAlpLCBzaXplLCBpcG9zLCBpbGVuOwoJQllURQkqaWJwLCAqb2JwOwoJSU5UCWlBZHZhbmNlID0gZHNiLT5wd2Z4LT5uQmxvY2tBbGlnbjsKCUlOVAlvQWR2YW5jZSA9IGRzYi0+ZHNvdW5kLT5kZXZpY2UtPnB3ZngtPm5CbG9ja0FsaWduOwoKCWlicCA9IGRzYi0+YnVmZmVyLT5tZW1vcnkgKyBkc2ItPmJ1Zl9taXhwb3M7CglvYnAgPSBidWY7CgoJVFJBQ0UoIiglcCwgJXAsICVwKSwgYnVmX21peHBvcz0lbGRcbiIsIGRzYiwgaWJwLCBvYnAsIGRzYi0+YnVmX21peHBvcyk7CgkvKiBDaGVjayBmb3IgdGhlIGJlc3QgY2FzZSAqLwoJaWYgKChkc2ItPmZyZXEgPT0gZHNiLT5kc291bmQtPmRldmljZS0+cHdmeC0+blNhbXBsZXNQZXJTZWMpICYmCgkgICAgKGRzYi0+cHdmeC0+d0JpdHNQZXJTYW1wbGUgPT0gZHNiLT5kc291bmQtPmRldmljZS0+cHdmeC0+d0JpdHNQZXJTYW1wbGUpICYmCgkgICAgKGRzYi0+cHdmeC0+bkNoYW5uZWxzID09IGRzYi0+ZHNvdW5kLT5kZXZpY2UtPnB3ZngtPm5DaGFubmVscykpIHsKCSAgICAgICAgSU5UIGJ5dGVzbGVmdCA9IGRzYi0+YnVmbGVuIC0gZHNiLT5idWZfbWl4cG9zOwoJCVRSQUNFKCIoJXApIEJlc3QgY2FzZVxuIiwgZHNiKTsKCSAgICAJaWYgKGxlbiA8PSBieXRlc2xlZnQgKQoJCQlDb3B5TWVtb3J5KG9icCwgaWJwLCBsZW4pOwoJCWVsc2UgeyAvKiB3cmFwICovCgkJCUNvcHlNZW1vcnkob2JwLCBpYnAsIGJ5dGVzbGVmdCk7CgkJCUNvcHlNZW1vcnkob2JwICsgYnl0ZXNsZWZ0LCBkc2ItPmJ1ZmZlci0+bWVtb3J5LCBsZW4gLSBieXRlc2xlZnQpOwoJCX0KCQlyZXR1cm4gbGVuOwoJfQoKCS8qIENoZWNrIGZvciBzYW1lIHNhbXBsZSByYXRlICovCglpZiAoZHNiLT5mcmVxID09IGRzYi0+ZHNvdW5kLT5kZXZpY2UtPnB3ZngtPm5TYW1wbGVzUGVyU2VjKSB7CgkJVFJBQ0UoIiglcCkgU2FtZSBzYW1wbGUgcmF0ZSAlbGQgPSBwcmltYXJ5ICVsZFxuIiwgZHNiLAoJCQlkc2ItPmZyZXEsIGRzYi0+ZHNvdW5kLT5kZXZpY2UtPnB3ZngtPm5TYW1wbGVzUGVyU2VjKTsKCQlpbGVuID0gMDsKCQlmb3IgKGkgPSAwOyBpIDwgbGVuOyBpICs9IG9BZHZhbmNlKSB7CgkJCWNwX2ZpZWxkcyhkc2IsIGlicCwgb2JwICk7CgkJCWlicCArPSBpQWR2YW5jZTsKCQkJaWxlbiArPSBpQWR2YW5jZTsKCQkJb2JwICs9IG9BZHZhbmNlOwoJCQlpZiAoaWJwID49IChCWVRFICopKGRzYi0+YnVmZmVyLT5tZW1vcnkgKyBkc2ItPmJ1ZmxlbikpCgkJCQlpYnAgPSBkc2ItPmJ1ZmZlci0+bWVtb3J5OwkvKiB3cmFwICovCgkJfQoJCXJldHVybiAoaWxlbik7Cgl9CgoJLyogTWl4IGluIGRpZmZlcmVudCBzYW1wbGUgcmF0ZXMgKi8KCS8qICovCgkvKiBOZXcgUGVyZmVjdFBpdGNoKHRtKSBUZWNobm9sb2d5IChjKSAxOTk4IFJvYiBSaWdncyAqLwoJLyogUGF0ZW50IFBlbmRpbmcgOi1dICovCgoJLyogUGF0ZW50IGVuaGFuY2VtZW50cyAoYykgMjAwMCBPdmUgS+V2ZW4sCgkgKiBUcmFuc0dhbWluZyBUZWNobm9sb2dpZXMgSW5jLiAqLwoKCS8qIEZJWE1FKCIoJXApIEFkanVzdGluZyBmcmVxdWVuY3k6ICVsZCAtPiAlbGQgKG5lZWQgb3B0aW1pemF0aW9uKVxuIiwKCSAgIGRzYiwgZHNiLT5mcmVxLCBkc2ItPmRzb3VuZC0+ZGV2aWNlLT5wd2Z4LT5uU2FtcGxlc1BlclNlYyk7ICovCgoJc2l6ZSA9IGxlbiAvIG9BZHZhbmNlOwoJaWxlbiA9IDA7CglpcG9zID0gZHNiLT5idWZfbWl4cG9zOwoJZm9yIChpID0gMDsgaSA8IHNpemU7IGkrKykgewogICAgICAgICAgICAgICAgY3BfZmllbGRzKGRzYiwgKGRzYi0+YnVmZmVyLT5tZW1vcnkgKyBpcG9zKSwgb2JwKTsKCQlvYnAgKz0gb0FkdmFuY2U7CgkJZHNiLT5mcmVxQWNjICs9IGRzYi0+ZnJlcUFkanVzdDsKCQlpZiAoZHNiLT5mcmVxQWNjID49ICgxPDxEU09VTkRfRlJFUVNISUZUKSkgewoJCQlVTE9ORyBhZHYgPSAoZHNiLT5mcmVxQWNjPj5EU09VTkRfRlJFUVNISUZUKSAqIGlBZHZhbmNlOwoJCQlkc2ItPmZyZXFBY2MgJj0gKDE8PERTT1VORF9GUkVRU0hJRlQpLTE7CgkJCWlwb3MgKz0gYWR2OyBpbGVuICs9IGFkdjsKCQkJaXBvcyAlPSBkc2ItPmJ1ZmxlbjsKCQl9Cgl9CglyZXR1cm4gaWxlbjsKfQoKc3RhdGljIHZvaWQgRFNPVU5EX01peGVyVm9sKElEaXJlY3RTb3VuZEJ1ZmZlckltcGwgKmRzYiwgQllURSAqYnVmLCBJTlQgbGVuKQp7CglJTlQJaTsKCUJZVEUJKmJwYyA9IGJ1ZjsKCUlOVDE2CSpicHMgPSAoSU5UMTYgKikgYnVmOwoKCVRSQUNFKCIoJXAsJXAsJWQpXG4iLGRzYixidWYsbGVuKTsKCVRSQUNFKCJsZWZ0ID0gJWx4LCByaWdodCA9ICVseFxuIiwgZHNiLT5jdm9scGFuLmR3VG90YWxMZWZ0QW1wRmFjdG9yLCAKCQlkc2ItPmN2b2xwYW4uZHdUb3RhbFJpZ2h0QW1wRmFjdG9yKTsKCglpZiAoKCEoZHNiLT5kc2JkLmR3RmxhZ3MgJiBEU0JDQVBTX0NUUkxQQU4pIHx8IChkc2ItPmN2b2xwYW4ubFBhbiA9PSAwKSkgJiYKCSAgICAoIShkc2ItPmRzYmQuZHdGbGFncyAmIERTQkNBUFNfQ1RSTFZPTFVNRSkgfHwgKGRzYi0+Y3ZvbHBhbi5sVm9sdW1lID09IDApKSAmJgoJICAgICEoZHNiLT5kc2JkLmR3RmxhZ3MgJiBEU0JDQVBTX0NUUkwzRCkpCgkJcmV0dXJuOwkJLyogTm90aGluZyB0byBkbyAqLwoKCS8qIElmIHdlIGVuZCB1cCB3aXRoIHNvbWUgYm96byBjb2RlciB1c2luZyBwYW5uaW5nIG9yIDNEIHNvdW5kICovCgkvKiB3aXRoIGEgbW9ubyBwcmltYXJ5IGJ1ZmZlciwgaXQgY291bGQgc291bmQgdmVyeSB3ZWlyZCB1c2luZyAqLwoJLyogdGhpcyBtZXRob2QuIE9oIHdlbGwsIHRvdWdoIHBhdG9vdGllcy4gKi8KCglzd2l0Y2ggKGRzYi0+ZHNvdW5kLT5kZXZpY2UtPnB3ZngtPndCaXRzUGVyU2FtcGxlKSB7CgljYXNlIDg6CgkJLyogOC1iaXQgV0FWIGlzIHVuc2lnbmVkLCBidXQgd2UgbmVlZCB0byBvcGVyYXRlICovCgkJLyogb24gc2lnbmVkIGRhdGEgZm9yIHRoaXMgdG8gd29yayBwcm9wZXJseSAqLwoJCXN3aXRjaCAoZHNiLT5kc291bmQtPmRldmljZS0+cHdmeC0+bkNoYW5uZWxzKSB7CgkJY2FzZSAxOgoJCQlmb3IgKGkgPSAwOyBpIDwgbGVuOyBpKyspIHsKCQkJCUlOVCB2YWwgPSAqYnBjIC0gMTI4OwoJCQkJdmFsID0gKHZhbCAqIGRzYi0+Y3ZvbHBhbi5kd1RvdGFsTGVmdEFtcEZhY3RvcikgPj4gMTY7CgkJCQkqYnBjID0gdmFsICsgMTI4OwoJCQkJYnBjKys7CgkJCX0KCQkJYnJlYWs7CgkJY2FzZSAyOgoJCQlmb3IgKGkgPSAwOyBpIDwgbGVuOyBpKz0yKSB7CgkJCQlJTlQgdmFsID0gKmJwYyAtIDEyODsKCQkJCXZhbCA9ICh2YWwgKiBkc2ItPmN2b2xwYW4uZHdUb3RhbExlZnRBbXBGYWN0b3IpID4+IDE2OwoJCQkJKmJwYysrID0gdmFsICsgMTI4OwoJCQkJdmFsID0gKmJwYyAtIDEyODsKCQkJCXZhbCA9ICh2YWwgKiBkc2ItPmN2b2xwYW4uZHdUb3RhbFJpZ2h0QW1wRmFjdG9yKSA+PiAxNjsKCQkJCSpicGMgPSB2YWwgKyAxMjg7CgkJCQlicGMrKzsKCQkJfQoJCQlicmVhazsKCQlkZWZhdWx0OgoJCQlGSVhNRSgiZG9lc24ndCBzdXBwb3J0ICVkIGNoYW5uZWxzXG4iLCBkc2ItPmRzb3VuZC0+ZGV2aWNlLT5wd2Z4LT5uQ2hhbm5lbHMpOwoJCQlicmVhazsKCQl9CgkJYnJlYWs7CgljYXNlIDE2OgoJCS8qIDE2LWJpdCBXQVYgaXMgc2lnbmVkIC0tIG11Y2ggYmV0dGVyICovCgkJc3dpdGNoIChkc2ItPmRzb3VuZC0+ZGV2aWNlLT5wd2Z4LT5uQ2hhbm5lbHMpIHsKCQljYXNlIDE6CgkJCWZvciAoaSA9IDA7IGkgPCBsZW47IGkgKz0gMikgewoJCQkJKmJwcyA9ICgqYnBzICogZHNiLT5jdm9scGFuLmR3VG90YWxMZWZ0QW1wRmFjdG9yKSA+PiAxNjsKCQkJCWJwcysrOwoJCQl9CgkJCWJyZWFrOwoJCWNhc2UgMjoKCQkJZm9yIChpID0gMDsgaSA8IGxlbjsgaSArPSA0KSB7CgkJCQkqYnBzID0gKCpicHMgKiBkc2ItPmN2b2xwYW4uZHdUb3RhbExlZnRBbXBGYWN0b3IpID4+IDE2OwoJCQkJYnBzKys7CgkJCQkqYnBzID0gKCpicHMgKiBkc2ItPmN2b2xwYW4uZHdUb3RhbFJpZ2h0QW1wRmFjdG9yKSA+PiAxNjsKCQkJCWJwcysrOwoJCQl9CgkJCWJyZWFrOwoJCWRlZmF1bHQ6CgkJCUZJWE1FKCJkb2Vzbid0IHN1cHBvcnQgJWQgY2hhbm5lbHNcbiIsIGRzYi0+ZHNvdW5kLT5kZXZpY2UtPnB3ZngtPm5DaGFubmVscyk7CgkJCWJyZWFrOwoJCX0KCQlicmVhazsKCWRlZmF1bHQ6CgkJRklYTUUoImRvZXNuJ3Qgc3VwcG9ydCAlZCBiaXQgc2FtcGxlc1xuIiwgZHNiLT5kc291bmQtPmRldmljZS0+cHdmeC0+d0JpdHNQZXJTYW1wbGUpOwoJCWJyZWFrOwoJfQp9CgpzdGF0aWMgTFBCWVRFIERTT1VORF90bXBidWZmZXIoRGlyZWN0U291bmREZXZpY2UgKmRldmljZSwgRFdPUkQgbGVuKQp7CiAgICBUUkFDRSgiKCVwLCVsZClcbiIsIGRldmljZSwgbGVuKTsKCiAgICBpZiAobGVuID4gZGV2aWNlLT50bXBfYnVmZmVyX2xlbikgewogICAgICAgIGlmIChkZXZpY2UtPnRtcF9idWZmZXIpCiAgICAgICAgICAgIGRldmljZS0+dG1wX2J1ZmZlciA9IEhlYXBSZUFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIGRldmljZS0+dG1wX2J1ZmZlciwgbGVuKTsKICAgICAgICBlbHNlCiAgICAgICAgICAgIGRldmljZS0+dG1wX2J1ZmZlciA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBsZW4pOwoKICAgICAgICBkZXZpY2UtPnRtcF9idWZmZXJfbGVuID0gbGVuOwogICAgfQoKICAgIHJldHVybiBkZXZpY2UtPnRtcF9idWZmZXI7Cn0KCnN0YXRpYyBEV09SRCBEU09VTkRfTWl4SW5CdWZmZXIoSURpcmVjdFNvdW5kQnVmZmVySW1wbCAqZHNiLCBEV09SRCB3cml0ZXBvcywgRFdPUkQgZnJhZ2xlbikKewoJSU5UCWksIGxlbiwgaWxlbiwgZmllbGQsIHRvZG87CglCWVRFCSpidWYsICppYnVmOwoKCVRSQUNFKCIoJXAsJWxkLCVsZClcbiIsZHNiLHdyaXRlcG9zLGZyYWdsZW4pOwoKCWxlbiA9IGZyYWdsZW47CglpZiAoIShkc2ItPnBsYXlmbGFncyAmIERTQlBMQVlfTE9PUElORykpIHsKCQlpbnQgc2Vjb25kYXJ5X3JlbWFpbmRlciA9IGRzYi0+YnVmbGVuIC0gZHNiLT5idWZfbWl4cG9zOwoJCWludCBhZGp1c3RlZF9yZW1haW5kZXIgPSBNdWxEaXYoZHNiLT5kc291bmQtPmRldmljZS0+cHdmeC0+bkF2Z0J5dGVzUGVyU2VjLCBzZWNvbmRhcnlfcmVtYWluZGVyLCBkc2ItPm5BdmdCeXRlc1BlclNlYyk7CgkJYXNzZXJ0KGFkanVzdGVkX3JlbWFpbmRlciA+PSAwKTsKCQlUUkFDRSgic2Vjb25kYXJ5X3JlbWFpbmRlciA9ICVkLCBhZGp1c3RlZF9yZW1haW5kZXIgPSAlZCwgbGVuID0gJWRcbiIsIHNlY29uZGFyeV9yZW1haW5kZXIsIGFkanVzdGVkX3JlbWFpbmRlciwgbGVuKTsKCQlpZiAoYWRqdXN0ZWRfcmVtYWluZGVyIDwgbGVuKSB7CgkJCVRSQUNFKCJjbGlwcGluZyBsZW4gdG8gcmVtYWluZGVyIG9mIHNlY29uZGFyeSBidWZmZXJcbiIpOwoJCQlsZW4gPSBhZGp1c3RlZF9yZW1haW5kZXI7CgkJfQoJCWlmIChsZW4gPT0gMCkKCQkJcmV0dXJuIDA7Cgl9CgoJaWYgKGxlbiAlIGRzYi0+ZHNvdW5kLT5kZXZpY2UtPnB3ZngtPm5CbG9ja0FsaWduKSB7CgkJSU5UIG5CbG9ja0FsaWduID0gZHNiLT5kc291bmQtPmRldmljZS0+cHdmeC0+bkJsb2NrQWxpZ247CgkJRVJSKCJsZW5ndGggbm90IGEgbXVsdGlwbGUgb2YgYmxvY2sgc2l6ZSwgbGVuID0gJWQsIGJsb2NrIHNpemUgPSAlZFxuIiwgbGVuLCBuQmxvY2tBbGlnbik7CgkJbGVuID0gKGxlbiAvIG5CbG9ja0FsaWduKSAqIG5CbG9ja0FsaWduOwkvKiBkYXRhIGFsaWdubWVudCAqLwoJfQoKCWlmICgoYnVmID0gaWJ1ZiA9IERTT1VORF90bXBidWZmZXIoZHNiLT5kc291bmQtPmRldmljZSwgbGVuKSkgPT0gTlVMTCkKCQlyZXR1cm4gMDsKCglUUkFDRSgiTWl4SW5CdWZmZXIgKCVwKSBsZW4gPSAlZCwgZGVzdCA9ICVsZFxuIiwgZHNiLCBsZW4sIHdyaXRlcG9zKTsKCglpbGVuID0gRFNPVU5EX01peGVyTm9ybShkc2IsIGlidWYsIGxlbik7CglpZiAoKGRzYi0+ZHNiZC5kd0ZsYWdzICYgRFNCQ0FQU19DVFJMUEFOKSB8fAoJICAgIChkc2ItPmRzYmQuZHdGbGFncyAmIERTQkNBUFNfQ1RSTFZPTFVNRSkgfHwKCSAgICAoZHNiLT5kc2JkLmR3RmxhZ3MgJiBEU0JDQVBTX0NUUkwzRCkpCgkJRFNPVU5EX01peGVyVm9sKGRzYiwgaWJ1ZiwgbGVuKTsKCglpZiAoZHNiLT5kc291bmQtPmRldmljZS0+cHdmeC0+d0JpdHNQZXJTYW1wbGUgPT0gOCkgewoJCUJZVEUJKm9idWYgPSBkc2ItPmRzb3VuZC0+ZGV2aWNlLT5idWZmZXIgKyB3cml0ZXBvczsKCgkJaWYgKCh3cml0ZXBvcyArIGxlbikgPD0gZHNiLT5kc291bmQtPmRldmljZS0+YnVmbGVuKQoJCQl0b2RvID0gbGVuOwoJCWVsc2UKCQkJdG9kbyA9IGRzYi0+ZHNvdW5kLT5kZXZpY2UtPmJ1ZmxlbiAtIHdyaXRlcG9zOwoKCQlmb3IgKGkgPSAwOyBpIDwgdG9kbzsgaSsrKSB7CgkJCS8qIDgtYml0IFdBViBpcyB1bnNpZ25lZCAqLwoJCQlmaWVsZCA9ICgqaWJ1ZisrIC0gMTI4KTsKCQkJZmllbGQgKz0gKCpvYnVmIC0gMTI4KTsKCQkJaWYgKGZpZWxkID4gMTI3KSBmaWVsZCA9IDEyNzsKCQkJZWxzZSBpZiAoZmllbGQgPCAtMTI4KSBmaWVsZCA9IC0xMjg7CgkJCSpvYnVmKysgPSBmaWVsZCArIDEyODsKCQl9CiAKCQlpZiAodG9kbyA8IGxlbikgewoJCQl0b2RvID0gbGVuIC0gdG9kbzsKCQkJb2J1ZiA9IGRzYi0+ZHNvdW5kLT5kZXZpY2UtPmJ1ZmZlcjsKCgkJCWZvciAoaSA9IDA7IGkgPCB0b2RvOyBpKyspIHsKCQkJCS8qIDgtYml0IFdBViBpcyB1bnNpZ25lZCAqLwoJCQkJZmllbGQgPSAoKmlidWYrKyAtIDEyOCk7CgkJCQlmaWVsZCArPSAoKm9idWYgLSAxMjgpOwoJCQkJaWYgKGZpZWxkID4gMTI3KSBmaWVsZCA9IDEyNzsKCQkJCWVsc2UgaWYgKGZpZWxkIDwgLTEyOCkgZmllbGQgPSAtMTI4OwoJCQkJKm9idWYrKyA9IGZpZWxkICsgMTI4OwoJCQl9CgkJfQogICAgICAgIH0gZWxzZSB7CgkJSU5UMTYJKmlidWZzLCAqb2J1ZnM7CgoJCWlidWZzID0gKElOVDE2ICopIGlidWY7CgkJb2J1ZnMgPSAoSU5UMTYgKikoZHNiLT5kc291bmQtPmRldmljZS0+YnVmZmVyICsgd3JpdGVwb3MpOwoKCQlpZiAoKHdyaXRlcG9zICsgbGVuKSA8PSBkc2ItPmRzb3VuZC0+ZGV2aWNlLT5idWZsZW4pCgkJCXRvZG8gPSBsZW4gLyAyOwoJCWVsc2UKCQkJdG9kbyA9IChkc2ItPmRzb3VuZC0+ZGV2aWNlLT5idWZsZW4gLSB3cml0ZXBvcykgLyAyOwoKCQlmb3IgKGkgPSAwOyBpIDwgdG9kbzsgaSsrKSB7CgkJCS8qIDE2LWJpdCBXQVYgaXMgc2lnbmVkICovCgkJCWZpZWxkID0gKmlidWZzKys7CgkJCWZpZWxkICs9ICpvYnVmczsKCQkJaWYgKGZpZWxkID4gMzI3NjcpIGZpZWxkID0gMzI3Njc7CgkJCWVsc2UgaWYgKGZpZWxkIDwgLTMyNzY4KSBmaWVsZCA9IC0zMjc2ODsKCQkJKm9idWZzKysgPSBmaWVsZDsKCQl9CgoJCWlmICh0b2RvIDwgKGxlbiAvIDIpKSB7CgkJCXRvZG8gPSAobGVuIC8gMikgLSB0b2RvOwoJCQlvYnVmcyA9IChJTlQxNiAqKWRzYi0+ZHNvdW5kLT5kZXZpY2UtPmJ1ZmZlcjsKCgkJCWZvciAoaSA9IDA7IGkgPCB0b2RvOyBpKyspIHsKCQkJCS8qIDE2LWJpdCBXQVYgaXMgc2lnbmVkICovCgkJCQlmaWVsZCA9ICppYnVmcysrOwoJCQkJZmllbGQgKz0gKm9idWZzOwoJCQkJaWYgKGZpZWxkID4gMzI3NjcpIGZpZWxkID0gMzI3Njc7CgkJCQllbHNlIGlmIChmaWVsZCA8IC0zMjc2OCkgZmllbGQgPSAtMzI3Njg7CgkJCQkqb2J1ZnMrKyA9IGZpZWxkOwoJCQl9CgkJfQogICAgICAgIH0KCglpZiAoZHNiLT5sZWFkaW4gJiYgKGRzYi0+c3RhcnRwb3MgPiBkc2ItPmJ1Zl9taXhwb3MpICYmIChkc2ItPnN0YXJ0cG9zIDw9IGRzYi0+YnVmX21peHBvcyArIGlsZW4pKSB7CgkJLyogSEFDSy4uLiBsZWFkaW4gc2hvdWxkIGJlIHJlc2V0IHdoZW4gdGhlIFBMQVkgcG9zaXRpb24gcmVhY2hlcyB0aGUgc3RhcnRwb3MsCgkJICogbm90IHRoZSBNSVggcG9zaXRpb24uLi4gYnV0IGlmIHRoZSBzb3VuZCBidWZmZXIgaXMgYmlnZ2VyIHRoYW4gb3VyIHByZWJ1ZmZlcmluZwoJCSAqICh3aGljaCBtdXN0IGJlIHRoZSBjYXNlIGZvciB0aGUgc3RyZWFtaW5nIGJ1ZmZlcnMgdGhhdCBuZWVkIHRoaXMgaGFjayBhbnl3YXkpCgkJICogcGx1cyBEU19IRUxfTUFSR0lOIG9yIGVxdWl2YWxlbnQsIHRoZW4gdGhpcyBvdWdodCB0byB3b3JrIGFueXdheS4gKi8KCQlkc2ItPmxlYWRpbiA9IEZBTFNFOwoJfQoKCWRzYi0+YnVmX21peHBvcyArPSBpbGVuOwoKCWlmIChkc2ItPmJ1Zl9taXhwb3MgPj0gZHNiLT5idWZsZW4pIHsKCQlpZiAoZHNiLT5wbGF5ZmxhZ3MgJiBEU0JQTEFZX0xPT1BJTkcpIHsKCQkJLyogd3JhcCAqLwoJCQlkc2ItPmJ1Zl9taXhwb3MgJT0gZHNiLT5idWZsZW47CgkJCWlmIChkc2ItPmxlYWRpbiAmJiAoZHNiLT5zdGFydHBvcyA8PSBkc2ItPmJ1Zl9taXhwb3MpKQoJCQkJZHNiLT5sZWFkaW4gPSBGQUxTRTsgLyogSEFDSzogc2VlIGFib3ZlICovCgkJfSBlbHNlIGlmIChkc2ItPmJ1Zl9taXhwb3MgPiBkc2ItPmJ1ZmxlbikgewoJCQlFUlIoIk1peHBvcyAoJWx1KSBwYXN0IGJ1ZmxlbiAoJWx1KSwgY2FwcGluZy4uLlxuIiwgZHNiLT5idWZfbWl4cG9zLCBkc2ItPmJ1Zmxlbik7CgkJCWRzYi0+YnVmX21peHBvcyA9IGRzYi0+YnVmbGVuOwoJCX0KCX0KCglyZXR1cm4gbGVuOwp9CgpzdGF0aWMgdm9pZCBEU09VTkRfUGhhc2VDYW5jZWwoSURpcmVjdFNvdW5kQnVmZmVySW1wbCAqZHNiLCBEV09SRCB3cml0ZXBvcywgRFdPUkQgbGVuKQp7CglJTlQgICAgIGlsZW4sIGZpZWxkOwoJVUlOVCAgICBpLCB0b2RvOwoJQllURQkqYnVmLCAqaWJ1ZjsKCglUUkFDRSgiKCVwLCVsZCwlbGQpXG4iLGRzYix3cml0ZXBvcyxsZW4pOwoKCWlmIChsZW4gJSBkc2ItPmRzb3VuZC0+ZGV2aWNlLT5wd2Z4LT5uQmxvY2tBbGlnbikgewoJCUlOVCBuQmxvY2tBbGlnbiA9IGRzYi0+ZHNvdW5kLT5kZXZpY2UtPnB3ZngtPm5CbG9ja0FsaWduOwoJCUVSUigibGVuZ3RoIG5vdCBhIG11bHRpcGxlIG9mIGJsb2NrIHNpemUsIGxlbiA9ICVsZCwgYmxvY2sgc2l6ZSA9ICVkXG4iLCBsZW4sIG5CbG9ja0FsaWduKTsKCQlsZW4gPSAobGVuIC8gbkJsb2NrQWxpZ24pICogbkJsb2NrQWxpZ247CS8qIGRhdGEgYWxpZ25tZW50ICovCgl9CgoJaWYgKChidWYgPSBpYnVmID0gRFNPVU5EX3RtcGJ1ZmZlcihkc2ItPmRzb3VuZC0+ZGV2aWNlLCBsZW4pKSA9PSBOVUxMKQoJCXJldHVybjsKCglUUkFDRSgiUGhhc2VDYW5jZWwgKCVwKSBsZW4gPSAlbGQsIGRlc3QgPSAlbGRcbiIsIGRzYiwgbGVuLCB3cml0ZXBvcyk7CgoJaWxlbiA9IERTT1VORF9NaXhlck5vcm0oZHNiLCBpYnVmLCBsZW4pOwoJaWYgKChkc2ItPmRzYmQuZHdGbGFncyAmIERTQkNBUFNfQ1RSTFBBTikgfHwKCSAgICAoZHNiLT5kc2JkLmR3RmxhZ3MgJiBEU0JDQVBTX0NUUkxWT0xVTUUpIHx8CgkgICAgKGRzYi0+ZHNiZC5kd0ZsYWdzICYgRFNCQ0FQU19DVFJMM0QpKQoJCURTT1VORF9NaXhlclZvbChkc2IsIGlidWYsIGxlbik7CgoJLyogc3VidHJhY3QgaW5zdGVhZCBvZiBhZGQsIHRvIHBoYXNlIG91dCBwcmVtaXhlZCBkYXRhICovCglpZiAoZHNiLT5kc291bmQtPmRldmljZS0+cHdmeC0+d0JpdHNQZXJTYW1wbGUgPT0gOCkgewoJCUJZVEUJKm9idWYgPSBkc2ItPmRzb3VuZC0+ZGV2aWNlLT5idWZmZXIgKyB3cml0ZXBvczsKCgkJaWYgKCh3cml0ZXBvcyArIGxlbikgPD0gZHNiLT5kc291bmQtPmRldmljZS0+YnVmbGVuKQoJCQl0b2RvID0gbGVuOwoJCWVsc2UKCQkJdG9kbyA9IGRzYi0+ZHNvdW5kLT5kZXZpY2UtPmJ1ZmxlbiAtIHdyaXRlcG9zOwoKCQlmb3IgKGkgPSAwOyBpIDwgdG9kbzsgaSsrKSB7CgkJCS8qIDgtYml0IFdBViBpcyB1bnNpZ25lZCAqLwoJCQlmaWVsZCA9ICgqaWJ1ZisrIC0gMTI4KTsKCQkJZmllbGQgLT0gKCpvYnVmIC0gMTI4KTsKCQkJaWYgKGZpZWxkID4gMTI3KSBmaWVsZCA9IDEyNzsKCQkJZWxzZSBpZiAoZmllbGQgPCAtMTI4KSBmaWVsZCA9IC0xMjg7CgkJCSpvYnVmKysgPSBmaWVsZCArIDEyODsKCQl9CiAKCQlpZiAodG9kbyA8IGxlbikgewoJCQl0b2RvID0gbGVuIC0gdG9kbzsKCQkJb2J1ZiA9IGRzYi0+ZHNvdW5kLT5kZXZpY2UtPmJ1ZmZlcjsKCgkJCWZvciAoaSA9IDA7IGkgPCB0b2RvOyBpKyspIHsKCQkJCS8qIDgtYml0IFdBViBpcyB1bnNpZ25lZCAqLwoJCQkJZmllbGQgPSAoKmlidWYrKyAtIDEyOCk7CgkJCQlmaWVsZCAtPSAoKm9idWYgLSAxMjgpOwoJCQkJaWYgKGZpZWxkID4gMTI3KSBmaWVsZCA9IDEyNzsKCQkJCWVsc2UgaWYgKGZpZWxkIDwgLTEyOCkgZmllbGQgPSAtMTI4OwoJCQkJKm9idWYrKyA9IGZpZWxkICsgMTI4OwoJCQl9CgkJfQogICAgICAgIH0gZWxzZSB7CgkJSU5UMTYJKmlidWZzLCAqb2J1ZnM7CgoJCWlidWZzID0gKElOVDE2ICopIGlidWY7CgkJb2J1ZnMgPSAoSU5UMTYgKikoZHNiLT5kc291bmQtPmRldmljZS0+YnVmZmVyICsgd3JpdGVwb3MpOwoKCQlpZiAoKHdyaXRlcG9zICsgbGVuKSA8PSBkc2ItPmRzb3VuZC0+ZGV2aWNlLT5idWZsZW4pCgkJCXRvZG8gPSBsZW4gLyAyOwoJCWVsc2UKCQkJdG9kbyA9IChkc2ItPmRzb3VuZC0+ZGV2aWNlLT5idWZsZW4gLSB3cml0ZXBvcykgLyAyOwoKCQlmb3IgKGkgPSAwOyBpIDwgdG9kbzsgaSsrKSB7CgkJCS8qIDE2LWJpdCBXQVYgaXMgc2lnbmVkICovCgkJCWZpZWxkID0gKmlidWZzKys7CgkJCWZpZWxkIC09ICpvYnVmczsKCQkJaWYgKGZpZWxkID4gMzI3NjcpIGZpZWxkID0gMzI3Njc7CgkJCWVsc2UgaWYgKGZpZWxkIDwgLTMyNzY4KSBmaWVsZCA9IC0zMjc2ODsKCQkJKm9idWZzKysgPSBmaWVsZDsKCQl9CgoJCWlmICh0b2RvIDwgKGxlbiAvIDIpKSB7CgkJCXRvZG8gPSAobGVuIC8gMikgLSB0b2RvOwoJCQlvYnVmcyA9IChJTlQxNiAqKWRzYi0+ZHNvdW5kLT5kZXZpY2UtPmJ1ZmZlcjsKCgkJCWZvciAoaSA9IDA7IGkgPCB0b2RvOyBpKyspIHsKCQkJCS8qIDE2LWJpdCBXQVYgaXMgc2lnbmVkICovCgkJCQlmaWVsZCA9ICppYnVmcysrOwoJCQkJZmllbGQgLT0gKm9idWZzOwoJCQkJaWYgKGZpZWxkID4gMzI3NjcpIGZpZWxkID0gMzI3Njc7CgkJCQllbHNlIGlmIChmaWVsZCA8IC0zMjc2OCkgZmllbGQgPSAtMzI3Njg7CgkJCQkqb2J1ZnMrKyA9IGZpZWxkOwoJCQl9CgkJfQogICAgICAgIH0KfQoKc3RhdGljIHZvaWQgRFNPVU5EX01peENhbmNlbChJRGlyZWN0U291bmRCdWZmZXJJbXBsICpkc2IsIERXT1JEIHdyaXRlcG9zLCBCT09MIGNhbmNlbCkKewoJRFdPUkQgICBzaXplLCBmbGVuLCBsZW4sIG5wb3MsIG5sZW47CglJTlQJaUFkdmFuY2UgPSBkc2ItPnB3ZngtPm5CbG9ja0FsaWduOwoJSU5UCW9BZHZhbmNlID0gZHNiLT5kc291bmQtPmRldmljZS0+cHdmeC0+bkJsb2NrQWxpZ247CgkvKiBkZXRlcm1pbmUgYW1vdW50IG9mIHByZW1peGVkIGRhdGEgdG8gY2FuY2VsICovCglEV09SRCBwcmltYXJ5X2RvbmUgPQoJCSgoZHNiLT5wcmltYXJ5X21peHBvcyA8IHdyaXRlcG9zKSA/IGRzYi0+ZHNvdW5kLT5kZXZpY2UtPmJ1ZmxlbiA6IDApICsKCQlkc2ItPnByaW1hcnlfbWl4cG9zIC0gd3JpdGVwb3M7CgoJVFJBQ0UoIiglcCwgJWxkKSwgYnVmX21peHBvcz0lbGRcbiIsIGRzYiwgd3JpdGVwb3MsIGRzYi0+YnVmX21peHBvcyk7CgoJLyogYmFja3RyYWNrIHRoZSBtaXggcG9zaXRpb24gKi8KCXNpemUgPSBwcmltYXJ5X2RvbmUgLyBvQWR2YW5jZTsKCWZsZW4gPSBzaXplICogZHNiLT5mcmVxQWRqdXN0OwoJbGVuID0gKGZsZW4gPj4gRFNPVU5EX0ZSRVFTSElGVCkgKiBpQWR2YW5jZTsKCWZsZW4gJj0gKDE8PERTT1VORF9GUkVRU0hJRlQpLTE7Cgl3aGlsZSAoZHNiLT5mcmVxQWNjIDwgZmxlbikgewoJCWxlbiArPSBpQWR2YW5jZTsKCQlkc2ItPmZyZXFBY2MgKz0gMTw8RFNPVU5EX0ZSRVFTSElGVDsKCX0KCWxlbiAlPSBkc2ItPmJ1ZmxlbjsKCW5wb3MgPSAoKGRzYi0+YnVmX21peHBvcyA8IGxlbikgPyBkc2ItPmJ1ZmxlbiA6IDApICsKCQlkc2ItPmJ1Zl9taXhwb3MgLSBsZW47CglpZiAoZHNiLT5sZWFkaW4gJiYgKGRzYi0+c3RhcnRwb3MgPiBucG9zKSAmJiAoZHNiLT5zdGFydHBvcyA8PSBucG9zICsgbGVuKSkgewoJCS8qIHN0b3AgYmFja3RyYWNraW5nIGF0IHN0YXJ0cG9zICovCgkJbnBvcyA9IGRzYi0+c3RhcnRwb3M7CgkJbGVuID0gKChkc2ItPmJ1Zl9taXhwb3MgPCBucG9zKSA/IGRzYi0+YnVmbGVuIDogMCkgKwoJCQlkc2ItPmJ1Zl9taXhwb3MgLSBucG9zOwoJCWZsZW4gPSBkc2ItPmZyZXFBY2M7CgkJbmxlbiA9IGxlbiAvIGRzYi0+cHdmeC0+bkJsb2NrQWxpZ247CgkJbmxlbiA9ICgobmxlbiA8PCBEU09VTkRfRlJFUVNISUZUKSArIGZsZW4pIC8gZHNiLT5mcmVxQWRqdXN0OwoJCW5sZW4gKj0gZHNiLT5kc291bmQtPmRldmljZS0+cHdmeC0+bkJsb2NrQWxpZ247CgkJd3JpdGVwb3MgPQoJCQkoKGRzYi0+cHJpbWFyeV9taXhwb3MgPCBubGVuKSA/IGRzYi0+ZHNvdW5kLT5kZXZpY2UtPmJ1ZmxlbiA6IDApICsKCQkJZHNiLT5wcmltYXJ5X21peHBvcyAtIG5sZW47Cgl9CgoJZHNiLT5mcmVxQWNjIC09IGZsZW47Cglkc2ItPmJ1Zl9taXhwb3MgPSBucG9zOwoJZHNiLT5wcmltYXJ5X21peHBvcyA9IHdyaXRlcG9zOwoKCVRSQUNFKCJuZXcgYnVmX21peHBvcz0lbGQsIHByaW1hcnlfbWl4cG9zPSVsZCAobGVuPSVsZClcbiIsCgkgICAgICBkc2ItPmJ1Zl9taXhwb3MsIGRzYi0+cHJpbWFyeV9taXhwb3MsIGxlbik7CgoJaWYgKGNhbmNlbCkgRFNPVU5EX1BoYXNlQ2FuY2VsKGRzYiwgd3JpdGVwb3MsIGxlbik7Cn0KCnZvaWQgRFNPVU5EX01peENhbmNlbEF0KElEaXJlY3RTb3VuZEJ1ZmZlckltcGwgKmRzYiwgRFdPUkQgYnVmX3dyaXRlcG9zKQp7CiNpZiAwCglEV09SRCAgIGksIHNpemUsIGZsZW4sIGxlbiwgbnBvcywgbmxlbjsKCUlOVAlpQWR2YW5jZSA9IGRzYi0+cHdmeC0+bkJsb2NrQWxpZ247CglJTlQJb0FkdmFuY2UgPSBkc2ItPmRzb3VuZC0+ZGV2aWNlLT5wd2Z4LT5uQmxvY2tBbGlnbjsKCS8qIGRldGVybWluZSBhbW91bnQgb2YgcHJlbWl4ZWQgZGF0YSB0byBjYW5jZWwgKi8KCURXT1JEIGJ1Zl9kb25lID0KCQkoKGRzYi0+YnVmX21peHBvcyA8IGJ1Zl93cml0ZXBvcykgPyBkc2ItPmJ1ZmxlbiA6IDApICsKCQlkc2ItPmJ1Zl9taXhwb3MgLSBidWZfd3JpdGVwb3M7CiNlbmRpZgoKCVdBUk4oIiglcCwgJWxkKSwgYnVmX21peHBvcz0lbGRcbiIsIGRzYiwgYnVmX3dyaXRlcG9zLCBkc2ItPmJ1Zl9taXhwb3MpOwoJLyogc2luY2UgdGhpcyBpcyBub3QgaW1wbGVtZW50ZWQgeWV0LCBqdXN0IGNhbmNlbCAqQUxMKiBwcmVidWZmZXJpbmcgZm9yIG5vdwoJICogKHdoaWNoIGlzIGZhc3RlciBhbnl3YXkgd2hlbiB0aGVyZSdzIG9ubHkgYSBzaW5nbGUgc2Vjb25kYXJ5IGJ1ZmZlcikgKi8KCWRzYi0+ZHNvdW5kLT5kZXZpY2UtPm5lZWRfcmVtaXggPSBUUlVFOwp9Cgp2b2lkIERTT1VORF9Gb3JjZVJlbWl4KElEaXJlY3RTb3VuZEJ1ZmZlckltcGwgKmRzYikKewoJVFJBQ0UoIiglcClcbiIsZHNiKTsKCUVudGVyQ3JpdGljYWxTZWN0aW9uKCZkc2ItPmxvY2spOwoJaWYgKGRzYi0+c3RhdGUgPT0gU1RBVEVfUExBWUlORykKCQlkc2ItPmRzb3VuZC0+ZGV2aWNlLT5uZWVkX3JlbWl4ID0gVFJVRTsKCUxlYXZlQ3JpdGljYWxTZWN0aW9uKCZkc2ItPmxvY2spOwp9CgpzdGF0aWMgRFdPUkQgRFNPVU5EX01peE9uZShJRGlyZWN0U291bmRCdWZmZXJJbXBsICpkc2IsIERXT1JEIHBsYXlwb3MsIERXT1JEIHdyaXRlcG9zLCBEV09SRCBtaXhsZW4pCnsKCURXT1JEIGxlbiwgc2xlbjsKCS8qIGRldGVybWluZSB0aGlzIGJ1ZmZlcidzIHdyaXRlIHBvc2l0aW9uICovCglEV09SRCBidWZfd3JpdGVwb3MgPSBEU09VTkRfQ2FsY1BsYXlQb3NpdGlvbihkc2IsIHdyaXRlcG9zLCB3cml0ZXBvcyk7CgkvKiBkZXRlcm1pbmUgaG93IG11Y2ggYWxyZWFkeS1taXhlZCBkYXRhIGV4aXN0cyAqLwoJRFdPUkQgYnVmX2RvbmUgPQoJCSgoZHNiLT5idWZfbWl4cG9zIDwgYnVmX3dyaXRlcG9zKSA/IGRzYi0+YnVmbGVuIDogMCkgKwoJCWRzYi0+YnVmX21peHBvcyAtIGJ1Zl93cml0ZXBvczsKCURXT1JEIHByaW1hcnlfZG9uZSA9CgkJKChkc2ItPnByaW1hcnlfbWl4cG9zIDwgd3JpdGVwb3MpID8gZHNiLT5kc291bmQtPmRldmljZS0+YnVmbGVuIDogMCkgKwoJCWRzYi0+cHJpbWFyeV9taXhwb3MgLSB3cml0ZXBvczsKCURXT1JEIGFkdl9kb25lID0KCQkoKGRzYi0+ZHNvdW5kLT5kZXZpY2UtPm1peHBvcyA8IHdyaXRlcG9zKSA/IGRzYi0+ZHNvdW5kLT5kZXZpY2UtPmJ1ZmxlbiA6IDApICsKCQlkc2ItPmRzb3VuZC0+ZGV2aWNlLT5taXhwb3MgLSB3cml0ZXBvczsKCURXT1JEIHBsYXllZCA9CgkJKChidWZfd3JpdGVwb3MgPCBkc2ItPnBsYXlwb3MpID8gZHNiLT5idWZsZW4gOiAwKSArCgkJYnVmX3dyaXRlcG9zIC0gZHNiLT5wbGF5cG9zOwoJRFdPUkQgYnVmX2xlZnQgPSBkc2ItPmJ1ZmxlbiAtIGJ1Zl93cml0ZXBvczsKCWludCBzdGlsbF9iZWhpbmQ7CgoJVFJBQ0UoIiglcCwlbGQsJWxkLCVsZClcbiIsZHNiLHBsYXlwb3Msd3JpdGVwb3MsbWl4bGVuKTsKCVRSQUNFKCJidWZfd3JpdGVwb3M9JWxkLCBwcmltYXJ5X3dyaXRlcG9zPSVsZFxuIiwgYnVmX3dyaXRlcG9zLCB3cml0ZXBvcyk7CglUUkFDRSgiYnVmX2RvbmU9JWxkLCBwcmltYXJ5X2RvbmU9JWxkXG4iLCBidWZfZG9uZSwgcHJpbWFyeV9kb25lKTsKCVRSQUNFKCJidWZfbWl4cG9zPSVsZCwgcHJpbWFyeV9taXhwb3M9JWxkLCBtaXhsZW49JWxkXG4iLCBkc2ItPmJ1Zl9taXhwb3MsIGRzYi0+cHJpbWFyeV9taXhwb3MsCgkgICAgICBtaXhsZW4pOwoJVFJBQ0UoImxvb3Bpbmc9JWxkLCBzdGFydHBvcz0lbGQsIGxlYWRpbj0lbGRcbiIsIGRzYi0+cGxheWZsYWdzLCBkc2ItPnN0YXJ0cG9zLCBkc2ItPmxlYWRpbik7CgoJLyogY2hlY2sgZm9yIG5vdGlmaWNhdGlvbiBwb3NpdGlvbnMgKi8KCWlmIChkc2ItPmRzYmQuZHdGbGFncyAmIERTQkNBUFNfQ1RSTFBPU0lUSU9OTk9USUZZICYmCgkgICAgZHNiLT5zdGF0ZSAhPSBTVEFURV9TVEFSVElORykgewoJCURTT1VORF9DaGVja0V2ZW50KGRzYiwgcGxheWVkKTsKCX0KCgkvKiBzYXZlIHdyaXRlIHBvc2l0aW9uIGZvciBub24tR0VUQ1VSUkVOVFBPU0lUSU9OMi4uLiAqLwoJZHNiLT5wbGF5cG9zID0gYnVmX3dyaXRlcG9zOwoKCS8qIGNoZWNrIHdoZXRoZXIgQ2FsY1BsYXlQb3NpdGlvbiBkZXRlY3RlZCBhIG1peGluZyB1bmRlcnJ1biAqLwoJaWYgKChidWZfZG9uZSA9PSAwKSAmJiAoZHNiLT5wcmltYXJ5X21peHBvcyAhPSB3cml0ZXBvcykpIHsKCQkvKiBpdCBkaWQsIGJ1dCBkaWQgd2UgaGF2ZSBtb3JlIHRvIHBsYXk/ICovCgkJaWYgKChkc2ItPnBsYXlmbGFncyAmIERTQlBMQVlfTE9PUElORykgfHwKCQkgICAgKGRzYi0+YnVmX21peHBvcyA8IGRzYi0+YnVmbGVuKSkgewoJCQkvKiB5ZXMsIGhhdmUgdG8gcmVjb3ZlciAqLwoJCQlFUlIoInVuZGVycnVuIG9uIHNvdW5kIGJ1ZmZlciAlcFxuIiwgZHNiKTsKCQkJVFJBQ0UoInJlY292ZXJpbmcgZnJvbSB1bmRlcnJ1bjogcHJpbWFyeV9taXhwb3M9JWxkXG4iLCB3cml0ZXBvcyk7CgkJfQoJCWRzYi0+cHJpbWFyeV9taXhwb3MgPSB3cml0ZXBvczsKCQlwcmltYXJ5X2RvbmUgPSAwOwoJfQoJLyogZGV0ZXJtaW5lIGhvdyBmYXIgYWhlYWQgd2Ugc2hvdWxkIG1peCAqLwoJaWYgKCgoZHNiLT5wbGF5ZmxhZ3MgJiBEU0JQTEFZX0xPT1BJTkcpIHx8CgkgICAgIChkc2ItPmxlYWRpbiAmJiAoZHNiLT5wcm9iYWJseV92YWxpZF90byAhPSAwKSkpICYmCgkgICAgIShkc2ItPmRzYmQuZHdGbGFncyAmIERTQkNBUFNfU1RBVElDKSkgewoJCS8qIGlmIHRoaXMgaXMgYSBzdHJlYW1pbmcgYnVmZmVyLCBpdCB0eXBpY2FsbHkgbWVhbnMgdGhhdAoJCSAqIHdlIHNob3VsZCBkZWZlciBtaXhpbmcgcGFzdCBwcm9iYWJseV92YWxpZF90byBhcyBsb25nCgkJICogYXMgd2UgY2FuLCB0byBhdm9pZCB1bm5lY2Vzc2FyeSByZW1peGluZyAqLwoJCS8qIHRoZSBoZWF2eS1sb29raW5nIGNhbGN1bGF0aW9ucyBzaG91bGRuJ3QgYmUgdGhhdCBiYWQsCgkJICogYXMgYW55IGdhbWUgaXNuJ3QgbGlrZWx5IHRvIGJlIGhhdmUgbW9yZSB0aGFuIDEgb3IgMgoJCSAqIHN0cmVhbWluZyBidWZmZXJzIGluIHVzZSBhdCBhbnkgdGltZSBhbnl3YXkuLi4gKi8KCQlEV09SRCBwcm9iYWJseV92YWxpZF9sZWZ0ID0KCQkJKGRzYi0+cHJvYmFibHlfdmFsaWRfdG8gPT0gKERXT1JEKS0xKSA/IGRzYi0+YnVmbGVuIDoKCQkJKChkc2ItPnByb2JhYmx5X3ZhbGlkX3RvIDwgYnVmX3dyaXRlcG9zKSA/IGRzYi0+YnVmbGVuIDogMCkgKwoJCQlkc2ItPnByb2JhYmx5X3ZhbGlkX3RvIC0gYnVmX3dyaXRlcG9zOwoJCS8qIGNoZWNrIGZvciBsZWFkaW4gY29uZGl0aW9uICovCgkJaWYgKChwcm9iYWJseV92YWxpZF9sZWZ0ID09IDApICYmCgkJICAgIChkc2ItPnByb2JhYmx5X3ZhbGlkX3RvID09IGRzYi0+c3RhcnRwb3MpICYmCgkJICAgIGRzYi0+bGVhZGluKQoJCQlwcm9iYWJseV92YWxpZF9sZWZ0ID0gZHNiLT5idWZsZW47CgkJVFJBQ0UoInN0cmVhbWluZyBidWZmZXIgcHJvYmFibHlfdmFsaWRfdG89JWxkLCBwcm9iYWJseV92YWxpZF9sZWZ0PSVsZFxuIiwKCQkgICAgICBkc2ItPnByb2JhYmx5X3ZhbGlkX3RvLCBwcm9iYWJseV92YWxpZF9sZWZ0KTsKCQkvKiBjaGVjayB3aGV0aGVyIHRoZSBhcHAncyB0aW1lIGlzIGFscmVhZHkgdXAgKi8KCQlpZiAocHJvYmFibHlfdmFsaWRfbGVmdCA8IGRzYi0+d3JpdGVsZWFkKSB7CgkJCVdBUk4oInByb2JhYmx5X3ZhbGlkX3RvIG5vdyB3aXRoaW4gd3JpdGVsZWFkLCBwb3NzaWJsZSBzdHJlYW1pbmcgdW5kZXJydW5cbiIpOwoJCQkvKiBvbmNlIHdlIHBhc3MgdGhlIHBvaW50IG9mIG5vIHJldHVybiwKCQkJICogbm8gcmVhc29uIHRvIGhvbGQgYmFjayBhbnltb3JlICovCgkJCWRzYi0+cHJvYmFibHlfdmFsaWRfdG8gPSAoRFdPUkQpLTE7CgkJCS8qIHdlIGp1c3QgaGF2ZSB0byBnbyBhaGVhZCBhbmQgbWl4IHdoYXQgd2UgaGF2ZSwKCQkJICogdGhlcmUncyBubyB0ZWxsaW5nIHdoYXQgdGhlIGFwcCBpcyB0aGlua2luZyBhbnl3YXkgKi8KCQl9IGVsc2UgewoJCQkvKiBhZGp1c3QgZm9yIG91ciBmcmVxdWVuY3kgYW5kIG91ciBzYW1wbGUgc2l6ZSAqLwoJCQlwcm9iYWJseV92YWxpZF9sZWZ0ID0gTXVsRGl2KHByb2JhYmx5X3ZhbGlkX2xlZnQsCgkJCQkJCSAgICAgMSA8PCBEU09VTkRfRlJFUVNISUZULAoJCQkJCQkgICAgIGRzYi0+cHdmeC0+bkJsb2NrQWxpZ24gKiBkc2ItPmZyZXFBZGp1c3QpICoKCQkJCSAgICAgICAgICAgICAgZHNiLT5kc291bmQtPmRldmljZS0+cHdmeC0+bkJsb2NrQWxpZ247CgkJCS8qIGNoZWNrIHdoZXRoZXIgdG8gY2xpcCBtaXhfbGVuICovCgkJCWlmIChwcm9iYWJseV92YWxpZF9sZWZ0IDwgbWl4bGVuKSB7CgkJCQlUUkFDRSgiY2xpcHBpbmcgdG8gcHJvYmFibHlfdmFsaWRfbGVmdD0lbGRcbiIsIHByb2JhYmx5X3ZhbGlkX2xlZnQpOwoJCQkJbWl4bGVuID0gcHJvYmFibHlfdmFsaWRfbGVmdDsKCQkJfQoJCX0KCX0KCS8qIGN1dCBtaXhsZW4gd2l0aCB3aGF0J3MgYWxyZWFkeSBiZWVuIG1peGVkICovCglpZiAobWl4bGVuIDwgcHJpbWFyeV9kb25lKSB7CgkJLyogaHVoPyBhbmQgc3RpbGwgQ2FsY1BsYXlQb3NpdGlvbiBkaWRuJ3QKCQkgKiBkZXRlY3QgYW4gdW5kZXJydW4/ICovCgkJRklYTUUoInByb2JsZW0gd2l0aCB1bmRlcnJ1biBkZXRlY3Rpb24gKG1peGxlbj0lbGQgPCBwcmltYXJ5X2RvbmU9JWxkKVxuIiwgbWl4bGVuLCBwcmltYXJ5X2RvbmUpOwoJCXJldHVybiAwOwoJfQoJbGVuID0gbWl4bGVuIC0gcHJpbWFyeV9kb25lOwoJVFJBQ0UoInJlbWFpbmluZyBtaXhsZW49JWxkXG4iLCBsZW4pOwoKCWlmIChsZW4gPCBkc2ItPmRzb3VuZC0+ZGV2aWNlLT5mcmFnbGVuKSB7CgkJLyogc21hbGxlciB0aGFuIGEgZnJhZ21lbnQsIHdhaXQgdW50aWwgaXQgZ2V0cyBsYXJnZXIKCQkgKiBiZWZvcmUgd2UgdGFrZSB0aGUgbWl4aW5nIG92ZXJoZWFkICovCgkJVFJBQ0UoIm1peGxlbiBub3Qgd29ydGggaXQsIGRlZmVycmluZyBtaXhpbmdcbiIpOwoJCXN0aWxsX2JlaGluZCA9IDE7CgkJZ290byBwb3N0X21peDsKCX0KCgkvKiBvaywgd2Uga25vdyBob3cgbXVjaCB0byBtaXgsIGxldCdzIGdvICovCglzdGlsbF9iZWhpbmQgPSAoYWR2X2RvbmUgPiBwcmltYXJ5X2RvbmUpOwoJd2hpbGUgKGxlbikgewoJCXNsZW4gPSBkc2ItPmRzb3VuZC0+ZGV2aWNlLT5idWZsZW4gLSBkc2ItPnByaW1hcnlfbWl4cG9zOwoJCWlmIChzbGVuID4gbGVuKSBzbGVuID0gbGVuOwoJCXNsZW4gPSBEU09VTkRfTWl4SW5CdWZmZXIoZHNiLCBkc2ItPnByaW1hcnlfbWl4cG9zLCBzbGVuKTsKCgkJaWYgKChkc2ItPnByaW1hcnlfbWl4cG9zIDwgZHNiLT5kc291bmQtPmRldmljZS0+bWl4cG9zKSAmJgoJCSAgICAoZHNiLT5wcmltYXJ5X21peHBvcyArIHNsZW4gPj0gZHNiLT5kc291bmQtPmRldmljZS0+bWl4cG9zKSkKCQkJc3RpbGxfYmVoaW5kID0gRkFMU0U7CgoJCWRzYi0+cHJpbWFyeV9taXhwb3MgKz0gc2xlbjsgbGVuIC09IHNsZW47CgkJZHNiLT5wcmltYXJ5X21peHBvcyAlPSBkc2ItPmRzb3VuZC0+ZGV2aWNlLT5idWZsZW47CgoJCWlmICgoZHNiLT5zdGF0ZSA9PSBTVEFURV9TVE9QUEVEKSB8fCAhc2xlbikgYnJlYWs7Cgl9CglUUkFDRSgibmV3IHByaW1hcnlfbWl4cG9zPSVsZCwgcHJpbWFyeV9hZHZiYXNlPSVsZFxuIiwgZHNiLT5wcmltYXJ5X21peHBvcywgZHNiLT5kc291bmQtPmRldmljZS0+bWl4cG9zKTsKCVRSQUNFKCJtaXhlZCBkYXRhIGxlbj0lbGQsIHN0aWxsX2JlaGluZD0lZFxuIiwgbWl4bGVuLWxlbiwgc3RpbGxfYmVoaW5kKTsKCnBvc3RfbWl4OgoJLyogY2hlY2sgaWYgYnVmZmVyIHNob3VsZCBiZSBjb25zaWRlcmVkIGNvbXBsZXRlICovCglpZiAoYnVmX2xlZnQgPCBkc2ItPndyaXRlbGVhZCAmJgoJICAgICEoZHNiLT5wbGF5ZmxhZ3MgJiBEU0JQTEFZX0xPT1BJTkcpKSB7CgkJZHNiLT5zdGF0ZSA9IFNUQVRFX1NUT1BQRUQ7CgkJZHNiLT5wbGF5cG9zID0gMDsKCQlkc2ItPmxhc3RfcGxheXBvcyA9IDA7CgkJZHNiLT5idWZfbWl4cG9zID0gMDsKCQlkc2ItPmxlYWRpbiA9IEZBTFNFOwoJCWRzYi0+bmVlZF9yZW1peCA9IEZBTFNFOwoJCURTT1VORF9DaGVja0V2ZW50KGRzYiwgYnVmX2xlZnQpOwoJfQoKCS8qIHJldHVybiBob3cgZmFyIHdlIHRoaW5rIHRoZSBwcmltYXJ5IGJ1ZmZlciBjYW4KCSAqIGFkdmFuY2UgaXRzIHVuZGVycnVuIGRldGVjdG9yLi4uKi8KCWlmIChzdGlsbF9iZWhpbmQpIHJldHVybiAwOwoJaWYgKChtaXhsZW4gLSBsZW4pIDwgcHJpbWFyeV9kb25lKSByZXR1cm4gMDsKCXNsZW4gPSAoKGRzYi0+cHJpbWFyeV9taXhwb3MgPCBkc2ItPmRzb3VuZC0+ZGV2aWNlLT5taXhwb3MpID8KCQlkc2ItPmRzb3VuZC0+ZGV2aWNlLT5idWZsZW4gOiAwKSArIGRzYi0+cHJpbWFyeV9taXhwb3MgLQoJCWRzYi0+ZHNvdW5kLT5kZXZpY2UtPm1peHBvczsKCWlmIChzbGVuID4gbWl4bGVuKSB7CgkJLyogdGhlIHByaW1hcnlfZG9uZSBhbmQgc3RpbGxfYmVoaW5kIGNoZWNrcyBhYm92ZSBzaG91bGQgaGF2ZSB3b3JrZWQgKi8KCQlGSVhNRSgicHJvYmxlbSB3aXRoIGFkdmFuY2VtZW50IGNhbGN1bGF0aW9uIChhZHZsZW49JWxkID4gbWl4bGVuPSVsZClcbiIsIHNsZW4sIG1peGxlbik7CgkJc2xlbiA9IDA7Cgl9CglyZXR1cm4gc2xlbjsKfQoKc3RhdGljIERXT1JEIERTT1VORF9NaXhUb1ByaW1hcnkoRGlyZWN0U291bmREZXZpY2UgKmRldmljZSwgRFdPUkQgcGxheXBvcywgRFdPUkQgd3JpdGVwb3MsIERXT1JEIG1peGxlbiwgQk9PTCByZWNvdmVyKQp7CglJTlQJCQlpLCBsZW4sIG1heGxlbiA9IDA7CglJRGlyZWN0U291bmRCdWZmZXJJbXBsCSpkc2I7CgoJVFJBQ0UoIiglbGQsJWxkLCVsZCwlZClcbiIsIHBsYXlwb3MsIHdyaXRlcG9zLCBtaXhsZW4sIHJlY292ZXIpOwoJZm9yIChpID0gMDsgaSA8IGRldmljZS0+bnJvZmJ1ZmZlcnM7IGkrKykgewoJCWRzYiA9IGRldmljZS0+YnVmZmVyc1tpXTsKCgkJaWYgKGRzYi0+YnVmbGVuICYmIGRzYi0+c3RhdGUgJiYgIWRzYi0+aHdidWYpIHsKCQkJVFJBQ0UoIkNoZWNraW5nICVwLCBtaXhsZW49JWxkXG4iLCBkc2IsIG1peGxlbik7CgkJCUVudGVyQ3JpdGljYWxTZWN0aW9uKCYoZHNiLT5sb2NrKSk7CgkJCWlmIChkc2ItPnN0YXRlID09IFNUQVRFX1NUT1BQSU5HKSB7CgkJCQlEU09VTkRfTWl4Q2FuY2VsKGRzYiwgd3JpdGVwb3MsIFRSVUUpOwoJCQkJZHNiLT5zdGF0ZSA9IFNUQVRFX1NUT1BQRUQ7CgkJCQlEU09VTkRfQ2hlY2tFdmVudChkc2IsIDApOwoJCQl9IGVsc2UgewoJCQkJaWYgKChkc2ItPnN0YXRlID09IFNUQVRFX1NUQVJUSU5HKSB8fCByZWNvdmVyKSB7CgkJCQkJZHNiLT5wcmltYXJ5X21peHBvcyA9IHdyaXRlcG9zOwoJCQkJCWRzYi0+Y3ZvbHBhbiA9IGRzYi0+dm9scGFuOwoJCQkJCWRzYi0+bmVlZF9yZW1peCA9IEZBTFNFOwoJCQkJfQoJCQkJZWxzZSBpZiAoZHNiLT5uZWVkX3JlbWl4KSB7CgkJCQkJRFNPVU5EX01peENhbmNlbChkc2IsIHdyaXRlcG9zLCBUUlVFKTsKCQkJCQlkc2ItPmN2b2xwYW4gPSBkc2ItPnZvbHBhbjsKCQkJCQlkc2ItPm5lZWRfcmVtaXggPSBGQUxTRTsKCQkJCX0KCQkJCWxlbiA9IERTT1VORF9NaXhPbmUoZHNiLCBwbGF5cG9zLCB3cml0ZXBvcywgbWl4bGVuKTsKCQkJCWlmIChkc2ItPnN0YXRlID09IFNUQVRFX1NUQVJUSU5HKQoJCQkJCWRzYi0+c3RhdGUgPSBTVEFURV9QTEFZSU5HOwoJCQkJbWF4bGVuID0gKGxlbiA+IG1heGxlbikgPyBsZW4gOiBtYXhsZW47CgkJCX0KCQkJTGVhdmVDcml0aWNhbFNlY3Rpb24oJihkc2ItPmxvY2spKTsKCQl9Cgl9CgoJcmV0dXJuIG1heGxlbjsKfQoKc3RhdGljIHZvaWQgRFNPVU5EX01peFJlc2V0KERpcmVjdFNvdW5kRGV2aWNlICpkZXZpY2UsIERXT1JEIHdyaXRlcG9zKQp7CglJTlQJCQlpOwoJSURpcmVjdFNvdW5kQnVmZmVySW1wbAkqZHNiOwoJaW50IG5maWxsZXI7CgoJVFJBQ0UoIiglcCwlbGQpXG4iLCBkZXZpY2UsIHdyaXRlcG9zKTsKCgkvKiB0aGUgc291bmQgb2Ygc2lsZW5jZSAqLwoJbmZpbGxlciA9IGRldmljZS0+cHdmeC0+d0JpdHNQZXJTYW1wbGUgPT0gOCA/IDEyOCA6IDA7CgoJLyogcmVzZXQgYWxsIGJ1ZmZlciBtaXggcG9zaXRpb25zICovCglmb3IgKGkgPSAwOyBpIDwgZGV2aWNlLT5ucm9mYnVmZmVyczsgaSsrKSB7CgkJZHNiID0gZGV2aWNlLT5idWZmZXJzW2ldOwoKCQlpZiAoZHNiLT5idWZsZW4gJiYgZHNiLT5zdGF0ZSAmJiAhZHNiLT5od2J1ZikgewoJCQlUUkFDRSgiUmVzZXR0aW5nICVwXG4iLCBkc2IpOwoJCQlFbnRlckNyaXRpY2FsU2VjdGlvbigmKGRzYi0+bG9jaykpOwoJCQlpZiAoZHNiLT5zdGF0ZSA9PSBTVEFURV9TVE9QUElORykgewoJCQkJZHNiLT5zdGF0ZSA9IFNUQVRFX1NUT1BQRUQ7CgkJCX0KCQkJZWxzZSBpZiAoZHNiLT5zdGF0ZSA9PSBTVEFURV9TVEFSVElORykgewoJCQkJLyogbm90aGluZyAqLwoJCQl9IGVsc2UgewoJCQkJRFNPVU5EX01peENhbmNlbChkc2IsIHdyaXRlcG9zLCBGQUxTRSk7CgkJCQlkc2ItPmN2b2xwYW4gPSBkc2ItPnZvbHBhbjsKCQkJCWRzYi0+bmVlZF9yZW1peCA9IEZBTFNFOwoJCQl9CgkJCUxlYXZlQ3JpdGljYWxTZWN0aW9uKCYoZHNiLT5sb2NrKSk7CgkJfQoJfQoKCS8qIHdpcGUgb3V0IHByZW1peGVkIGRhdGEgKi8KCWlmIChkZXZpY2UtPm1peHBvcyA8IHdyaXRlcG9zKSB7CgkJRmlsbE1lbW9yeShkZXZpY2UtPmJ1ZmZlciArIHdyaXRlcG9zLCBkZXZpY2UtPmJ1ZmxlbiAtIHdyaXRlcG9zLCBuZmlsbGVyKTsKCQlGaWxsTWVtb3J5KGRldmljZS0+YnVmZmVyLCBkZXZpY2UtPm1peHBvcywgbmZpbGxlcik7Cgl9IGVsc2UgewoJCUZpbGxNZW1vcnkoZGV2aWNlLT5idWZmZXIgKyB3cml0ZXBvcywgZGV2aWNlLT5taXhwb3MgLSB3cml0ZXBvcywgbmZpbGxlcik7Cgl9CgoJLyogcmVzZXQgcHJpbWFyeSBtaXggcG9zaXRpb24gKi8KCWRldmljZS0+bWl4cG9zID0gd3JpdGVwb3M7Cn0KCnN0YXRpYyB2b2lkIERTT1VORF9DaGVja1Jlc2V0KERpcmVjdFNvdW5kRGV2aWNlICpkZXZpY2UsIERXT1JEIHdyaXRlcG9zKQp7CglUUkFDRSgiKCVwLCVsZClcbiIsZGV2aWNlLHdyaXRlcG9zKTsKCWlmIChkZXZpY2UtPm5lZWRfcmVtaXgpIHsKCQlEU09VTkRfTWl4UmVzZXQoZGV2aWNlLCB3cml0ZXBvcyk7CgkJZGV2aWNlLT5uZWVkX3JlbWl4ID0gRkFMU0U7CgkJLyogbWF4aW1pemUgSGFsZi1MaWZlIHBlcmZvcm1hbmNlICovCgkJZGV2aWNlLT5wcmVidWYgPSBkc19zbmRfcXVldWVfbWluOwoJCWRldmljZS0+cHJlY291bnQgPSAwOwoJfSBlbHNlIHsKCQlkZXZpY2UtPnByZWNvdW50Kys7CgkJaWYgKGRldmljZS0+cHJlY291bnQgPj0gNCkgewoJCQlpZiAoZGV2aWNlLT5wcmVidWYgPCBkc19zbmRfcXVldWVfbWF4KQoJCQkJZGV2aWNlLT5wcmVidWYrKzsKCQkJZGV2aWNlLT5wcmVjb3VudCA9IDA7CgkJfQoJfQoJVFJBQ0UoInByZW1peCBhZGp1c3Q6ICVkXG4iLCBkZXZpY2UtPnByZWJ1Zik7Cn0KCnZvaWQgRFNPVU5EX1dhdmVRdWV1ZShEaXJlY3RTb3VuZERldmljZSAqZGV2aWNlLCBEV09SRCBtaXhxKQp7CglUUkFDRSgiKCVwLCVsZClcbiIsIGRldmljZSwgbWl4cSk7CglpZiAobWl4cSArIGRldmljZS0+cHdxdWV1ZSA+IGRzX2hlbF9xdWV1ZSkgbWl4cSA9IGRzX2hlbF9xdWV1ZSAtIGRldmljZS0+cHdxdWV1ZTsKCVRSQUNFKCJxdWV1ZWluZyAlbGQgYnVmZmVycywgc3RhcnRpbmcgYXQgJWRcbiIsIG1peHEsIGRldmljZS0+cHd3cml0ZSk7Cglmb3IgKDsgbWl4cTsgbWl4cS0tKSB7CgkJd2F2ZU91dFdyaXRlKGRldmljZS0+aHdvLCBkZXZpY2UtPnB3YXZlW2RldmljZS0+cHd3cml0ZV0sIHNpemVvZihXQVZFSERSKSk7CgkJZGV2aWNlLT5wd3dyaXRlKys7CgkJaWYgKGRldmljZS0+cHd3cml0ZSA+PSBEU19IRUxfRlJBR1MpIGRldmljZS0+cHd3cml0ZSA9IDA7CgkJZGV2aWNlLT5wd3F1ZXVlKys7Cgl9Cn0KCi8qICNkZWZpbmUgU1lOQ19DQUxMQkFDSyAqLwoKdm9pZCBEU09VTkRfUGVyZm9ybU1peChEaXJlY3RTb3VuZERldmljZSAqZGV2aWNlKQp7CglpbnQgbmZpbGxlcjsKCUJPT0wgZm9yY2VkOwoJSFJFU1VMVCBocmVzOwoKCVRSQUNFKCIoJXApXG4iLCBkZXZpY2UpOwoKCS8qIHRoZSBzb3VuZCBvZiBzaWxlbmNlICovCgluZmlsbGVyID0gZGV2aWNlLT5wd2Z4LT53Qml0c1BlclNhbXBsZSA9PSA4ID8gMTI4IDogMDsKCgkvKiB3aGV0aGVyIHRoZSBwcmltYXJ5IGlzIGZvcmNlZCB0byBwbGF5IGV2ZW4gd2l0aG91dCBzZWNvbmRhcnkgYnVmZmVycyAqLwoJZm9yY2VkID0gKChkZXZpY2UtPnN0YXRlID09IFNUQVRFX1BMQVlJTkcpIHx8IChkZXZpY2UtPnN0YXRlID09IFNUQVRFX1NUQVJUSU5HKSk7CgoJaWYgKGRldmljZS0+cHJpb2xldmVsICE9IERTU0NMX1dSSVRFUFJJTUFSWSkgewoJCUJPT0wgcGF1c2VkID0gKChkZXZpY2UtPnN0YXRlID09IFNUQVRFX1NUT1BQRUQpIHx8IChkZXZpY2UtPnN0YXRlID09IFNUQVRFX1NUQVJUSU5HKSk7CgkJLyogRklYTUU6IGRvY3VtZW50IHZhcmlhYmxlcyAqLwogCQlEV09SRCBwbGF5cG9zLCB3cml0ZXBvcywgaW5xLCBtYXhxLCBmcmFnOwogCQlpZiAoZGV2aWNlLT5od2J1ZikgewoJCQlocmVzID0gSURzRHJpdmVyQnVmZmVyX0dldFBvc2l0aW9uKGRldmljZS0+aHdidWYsICZwbGF5cG9zLCAmd3JpdGVwb3MpOwoJCQlpZiAoaHJlcykgewoJCQkgICAgV0FSTigiSURzRHJpdmVyQnVmZmVyX0dldFBvc2l0aW9uIGZhaWxlZFxuIik7CgkJCSAgICByZXR1cm47CgkJCX0KCQkJLyogV2VsbCwgd2UgKmNvdWxkKiBkbyBKdXN0LUluLVRpbWUgbWl4aW5nIHVzaW5nIHRoZSB3cml0ZXBvcywKCQkJICogYnV0IHRoYXQncyBhIGxpdHRsZSBiaXQgYW1iaXRpb3VzIGFuZCB1bm5lY2Vzc2FyeS4uLiAqLwoJCQkvKiByYXRoZXIgYWRkIG91ciBzYWZldHkgbWFyZ2luIHRvIHRoZSB3cml0ZXBvcywgaWYgd2UncmUgcGxheWluZyAqLwoJCQlpZiAoIXBhdXNlZCkgewoJCQkJd3JpdGVwb3MgKz0gZGV2aWNlLT53cml0ZWxlYWQ7CgkJCQl3cml0ZXBvcyAlPSBkZXZpY2UtPmJ1ZmxlbjsKCQkJfSBlbHNlIHdyaXRlcG9zID0gcGxheXBvczsKCQl9IGVsc2UgewogCQkJcGxheXBvcyA9IGRldmljZS0+cHdwbGF5ICogZGV2aWNlLT5mcmFnbGVuOwogCQkJd3JpdGVwb3MgPSBwbGF5cG9zOwogCQkJaWYgKCFwYXVzZWQpIHsKCSAJCQl3cml0ZXBvcyArPSBkc19oZWxfbWFyZ2luICogZGV2aWNlLT5mcmFnbGVuOwogCQkJCXdyaXRlcG9zICU9IGRldmljZS0+YnVmbGVuOwoJIAkJfQoJCX0KCQlUUkFDRSgicHJpbWFyeSBwbGF5cG9zPSVsZCwgd3JpdGVwb3M9JWxkLCBjbHJwb3M9JWxkLCBtaXhwb3M9JWxkLCBidWZsZW49JWxkXG4iLAoJCSAgICAgIHBsYXlwb3Msd3JpdGVwb3MsZGV2aWNlLT5wbGF5cG9zLGRldmljZS0+bWl4cG9zLGRldmljZS0+YnVmbGVuKTsKCQlhc3NlcnQoZGV2aWNlLT5wbGF5cG9zIDwgZGV2aWNlLT5idWZsZW4pOwoJCS8qIHdpcGUgb3V0IGp1c3QtcGxheWVkIHNvdW5kIGRhdGEgKi8KCQlpZiAocGxheXBvcyA8IGRldmljZS0+cGxheXBvcykgewoJCQlGaWxsTWVtb3J5KGRldmljZS0+YnVmZmVyICsgZGV2aWNlLT5wbGF5cG9zLCBkZXZpY2UtPmJ1ZmxlbiAtIGRldmljZS0+cGxheXBvcywgbmZpbGxlcik7CgkJCUZpbGxNZW1vcnkoZGV2aWNlLT5idWZmZXIsIHBsYXlwb3MsIG5maWxsZXIpOwoJCX0gZWxzZSB7CgkJCUZpbGxNZW1vcnkoZGV2aWNlLT5idWZmZXIgKyBkZXZpY2UtPnBsYXlwb3MsIHBsYXlwb3MgLSBkZXZpY2UtPnBsYXlwb3MsIG5maWxsZXIpOwoJCX0KCQlkZXZpY2UtPnBsYXlwb3MgPSBwbGF5cG9zOwoKCQlFbnRlckNyaXRpY2FsU2VjdGlvbigmKGRldmljZS0+bWl4bG9jaykpOwoKCQkvKiByZXNldCBtaXhpbmcgaWYgbmVjZXNzYXJ5ICovCgkJRFNPVU5EX0NoZWNrUmVzZXQoZGV2aWNlLCB3cml0ZXBvcyk7CgoJCS8qIGNoZWNrIGhvdyBtdWNoIHByZWJ1ZmZlcmluZyBpcyBsZWZ0ICovCgkJaW5xID0gZGV2aWNlLT5taXhwb3M7CgkJaWYgKGlucSA8IHdyaXRlcG9zKQoJCQlpbnEgKz0gZGV2aWNlLT5idWZsZW47CgkJaW5xIC09IHdyaXRlcG9zOwoKCQkvKiBmaW5kIHRoZSBtYXhpbXVtIHdlIGNhbiBwcmVidWZmZXIgKi8KCQlpZiAoIXBhdXNlZCkgewoJCQltYXhxID0gcGxheXBvczsKCQkJaWYgKG1heHEgPCB3cml0ZXBvcykKCQkJCW1heHEgKz0gZGV2aWNlLT5idWZsZW47CgkJCW1heHEgLT0gd3JpdGVwb3M7CgkJfSBlbHNlIG1heHEgPSBkZXZpY2UtPmJ1ZmxlbjsKCgkJLyogY2xpcCBtYXhxIHRvIGRldmljZS0+cHJlYnVmICovCgkJZnJhZyA9IGRldmljZS0+cHJlYnVmICogZGV2aWNlLT5mcmFnbGVuOwoJCWlmIChtYXhxID4gZnJhZykgbWF4cSA9IGZyYWc7CgoJCS8qIGNoZWNrIGZvciBjb25zaXN0ZW5jeSAqLwoJCWlmIChpbnEgPiBtYXhxKSB7CgkJCS8qIHRoZSBwbGF5YmFjayBwb3NpdGlvbiBtdXN0IGhhdmUgcGFzc2VkIG91ciBsYXN0CgkJCSAqIG1peGVkIHBvc2l0aW9uLCBpLmUuIGl0J3MgYW4gdW5kZXJydW4sIG9yIHdlIGhhdmUKCQkJICogbm90aGluZyBtb3JlIHRvIHBsYXkgKi8KCQkJVFJBQ0UoInJlYWNoZWQgZW5kIG9mIG1peGVkIGRhdGEgKGlucT0lbGQsIG1heHE9JWxkKVxuIiwgaW5xLCBtYXhxKTsKCQkJaW5xID0gMDsKCQkJLyogc3RvcCB0aGUgcGxheWJhY2sgbm93LCB0byBhbGxvdyBidWZmZXJzIHRvIHJlZmlsbCAqLwoJCQlpZiAoZGV2aWNlLT5zdGF0ZSA9PSBTVEFURV9QTEFZSU5HKSB7CgkJCQlkZXZpY2UtPnN0YXRlID0gU1RBVEVfU1RBUlRJTkc7CgkJCX0KCQkJZWxzZSBpZiAoZGV2aWNlLT5zdGF0ZSA9PSBTVEFURV9TVE9QUElORykgewoJCQkJZGV2aWNlLT5zdGF0ZSA9IFNUQVRFX1NUT1BQRUQ7CgkJCX0KCQkJZWxzZSB7CgkJCQkvKiBob3cgY2FuIHdlIGhhdmUgYW4gdW5kZXJydW4gaWYgd2UgYXJlbid0IHBsYXlpbmc/ICovCgkJCQlXQVJOKCJ1bmV4cGVjdGVkIHByaW1hcnkgc3RhdGUgKCVsZClcbiIsIGRldmljZS0+c3RhdGUpOwoJCQl9CiNpZmRlZiBTWU5DX0NBTExCQUNLCgkJCS8qIERTT1VORF9jYWxsYmFjayBtYXkgbmVlZCB0aGlzIGxvY2sgKi8KCQkJTGVhdmVDcml0aWNhbFNlY3Rpb24oJihkZXZpY2UtPm1peGxvY2spKTsKI2VuZGlmCgkJCWlmIChEU09VTkRfUHJpbWFyeVN0b3AoZGV2aWNlKSAhPSBEU19PSykKCQkJCVdBUk4oIkRTT1VORF9QcmltYXJ5U3RvcCBmYWlsZWRcbiIpOwojaWZkZWYgU1lOQ19DQUxMQkFDSwoJCQlFbnRlckNyaXRpY2FsU2VjdGlvbigmKGRldmljZS0+bWl4bG9jaykpOwojZW5kaWYKCQkJaWYgKGRldmljZS0+aHdidWYpIHsKCQkJCS8qIHRoZSBTdG9wIGlzIHN1cHBvc2VkIHRvIHJlc2V0IHBsYXkgcG9zaXRpb24gdG8gYmVnaW5uaW5nIG9mIGJ1ZmZlciAqLwoJCQkJLyogdW5mb3J0dW5hdGVseSwgT1NTIGlzIG5vdCBhYmxlIHRvIGRvIHNvLCBzbyBnZXQgY3VycmVudCBwb2ludGVyICovCgkJCQlocmVzID0gSURzRHJpdmVyQnVmZmVyX0dldFBvc2l0aW9uKGRldmljZS0+aHdidWYsICZwbGF5cG9zLCBOVUxMKTsKCQkJCWlmIChocmVzKSB7CgkJCQkJTGVhdmVDcml0aWNhbFNlY3Rpb24oJihkZXZpY2UtPm1peGxvY2spKTsKCQkJCQlXQVJOKCJJRHNEcml2ZXJCdWZmZXJfR2V0UG9zaXRpb24gZmFpbGVkXG4iKTsKCQkJCQlyZXR1cm47CgkJCQl9CgkJCX0gZWxzZSB7CgkgCQkJcGxheXBvcyA9IGRldmljZS0+cHdwbGF5ICogZGV2aWNlLT5mcmFnbGVuOwoJCQl9CgkJCXdyaXRlcG9zID0gcGxheXBvczsKCQkJZGV2aWNlLT5wbGF5cG9zID0gcGxheXBvczsKCQkJZGV2aWNlLT5taXhwb3MgPSB3cml0ZXBvczsKCQkJaW5xID0gMDsKCQkJbWF4cSA9IGRldmljZS0+YnVmbGVuOwoJCQlpZiAobWF4cSA+IGZyYWcpIG1heHEgPSBmcmFnOwoJCQlGaWxsTWVtb3J5KGRldmljZS0+YnVmZmVyLCBkZXZpY2UtPmJ1ZmxlbiwgbmZpbGxlcik7CgkJCXBhdXNlZCA9IFRSVUU7CgkJfQoKCQkvKiBkbyB0aGUgbWl4aW5nICovCgkJZnJhZyA9IERTT1VORF9NaXhUb1ByaW1hcnkoZGV2aWNlLCBwbGF5cG9zLCB3cml0ZXBvcywgbWF4cSwgcGF1c2VkKTsKCQlpZiAoZm9yY2VkKSBmcmFnID0gbWF4cSAtIGlucTsKCQlkZXZpY2UtPm1peHBvcyArPSBmcmFnOwoJCWRldmljZS0+bWl4cG9zICU9IGRldmljZS0+YnVmbGVuOwoKCQlpZiAoZnJhZykgewoJCQkvKiBidWZmZXJzIGhhdmUgYmVlbiBmaWxsZWQsIHJlc3RhcnQgcGxheWJhY2sgKi8KCQkJaWYgKGRldmljZS0+c3RhdGUgPT0gU1RBVEVfU1RBUlRJTkcpIHsKCQkJCWRldmljZS0+c3RhdGUgPSBTVEFURV9QTEFZSU5HOwoJCQl9CgkJCWVsc2UgaWYgKGRldmljZS0+c3RhdGUgPT0gU1RBVEVfU1RPUFBFRCkgewoJCQkJLyogdGhlIGRzb3VuZCBpcyBzdXBwb3NlZCB0byBwbGF5IGlmIHRoZXJlJ3Mgc29tZXRoaW5nIHRvIHBsYXkKCQkJCSAqIGV2ZW4gaWYgaXQgaXMgcmVwb3J0ZWQgYXMgc3RvcHBlZCwgc28gZG9uJ3QgbGV0IHRoaXMgY29uZnVzZSB5b3UgKi8KCQkJCWRldmljZS0+c3RhdGUgPSBTVEFURV9TVE9QUElORzsKCQkJfQoJCQlMZWF2ZUNyaXRpY2FsU2VjdGlvbigmKGRldmljZS0+bWl4bG9jaykpOwoJCQlpZiAocGF1c2VkKSB7CgkJCQlpZiAoRFNPVU5EX1ByaW1hcnlQbGF5KGRldmljZSkgIT0gRFNfT0spCgkJCQkJV0FSTigiRFNPVU5EX1ByaW1hcnlQbGF5IGZhaWxlZFxuIik7CgkJCQllbHNlCgkJCQkJVFJBQ0UoInN0YXJ0aW5nIHBsYXliYWNrXG4iKTsKCQkJfQoJCX0KCQllbHNlCgkJCUxlYXZlQ3JpdGljYWxTZWN0aW9uKCYoZGV2aWNlLT5taXhsb2NrKSk7Cgl9IGVsc2UgewoJCS8qIGluIHRoZSBEU1NDTF9XUklURVBSSU1BUlkgbW9kZSwgdGhlIGFwcCBpcyB0b3RhbGx5IGluIGNoYXJnZS4uLiAqLwoJCWlmIChkZXZpY2UtPnN0YXRlID09IFNUQVRFX1NUQVJUSU5HKSB7CgkJCWlmIChEU09VTkRfUHJpbWFyeVBsYXkoZGV2aWNlKSAhPSBEU19PSykKCQkJCVdBUk4oIkRTT1VORF9QcmltYXJ5UGxheSBmYWlsZWRcbiIpOwoJCQllbHNlCgkJCQlkZXZpY2UtPnN0YXRlID0gU1RBVEVfUExBWUlORzsKCQl9CgkJZWxzZSBpZiAoZGV2aWNlLT5zdGF0ZSA9PSBTVEFURV9TVE9QUElORykgewoJCQlpZiAoRFNPVU5EX1ByaW1hcnlTdG9wKGRldmljZSkgIT0gRFNfT0spCgkJCQlXQVJOKCJEU09VTkRfUHJpbWFyeVN0b3AgZmFpbGVkXG4iKTsKCQkJZWxzZQoJCQkJZGV2aWNlLT5zdGF0ZSA9IFNUQVRFX1NUT1BQRUQ7CgkJfQoJfQp9Cgp2b2lkIENBTExCQUNLIERTT1VORF90aW1lcihVSU5UIHRpbWVySUQsIFVJTlQgbXNnLCBEV09SRCBkd1VzZXIsIERXT1JEIGR3MSwgRFdPUkQgZHcyKQp7CiAgICAgICAgRGlyZWN0U291bmREZXZpY2UgKiBkZXZpY2UgPSAoRGlyZWN0U291bmREZXZpY2UqKWR3VXNlcjsKCURXT1JEIHN0YXJ0X3RpbWUgPSAgR2V0VGlja0NvdW50KCk7CiAgICAgICAgRFdPUkQgZW5kX3RpbWU7CglUUkFDRSgiKCVkLCVkLDB4JWx4LDB4JWx4LDB4JWx4KVxuIix0aW1lcklELG1zZyxkd1VzZXIsZHcxLGR3Mik7CiAgICAgICAgVFJBQ0UoImVudGVyaW5nIGF0ICVsZFxuIiwgc3RhcnRfdGltZSk7CgoJaWYgKERTT1VORF9yZW5kZXJlcltkZXZpY2UtPmRydmRlc2MuZG5EZXZOb2RlXSAhPSBkZXZpY2UpIHsKCQlFUlIoImRzb3VuZCBkaWVkIHdpdGhvdXQga2lsbGluZyB1cz9cbiIpOwoJCXRpbWVLaWxsRXZlbnQodGltZXJJRCk7CgkJdGltZUVuZFBlcmlvZChEU19USU1FX1JFUyk7CgkJcmV0dXJuOwoJfQoKCVJ0bEFjcXVpcmVSZXNvdXJjZVNoYXJlZCgmKGRldmljZS0+YnVmZmVyX2xpc3RfbG9jayksIFRSVUUpOwoKCWlmIChkZXZpY2UtPnJlZikKCQlEU09VTkRfUGVyZm9ybU1peChkZXZpY2UpOwoKCVJ0bFJlbGVhc2VSZXNvdXJjZSgmKGRldmljZS0+YnVmZmVyX2xpc3RfbG9jaykpOwoKCWVuZF90aW1lID0gR2V0VGlja0NvdW50KCk7CglUUkFDRSgiY29tcGxldGVkIHByb2Nlc3NpbmcgYXQgJWxkLCBkdXJhdGlvbiA9ICVsZFxuIiwgZW5kX3RpbWUsIGVuZF90aW1lIC0gc3RhcnRfdGltZSk7Cn0KCnZvaWQgQ0FMTEJBQ0sgRFNPVU5EX2NhbGxiYWNrKEhXQVZFT1VUIGh3bywgVUlOVCBtc2csIERXT1JEIGR3VXNlciwgRFdPUkQgZHcxLCBEV09SRCBkdzIpCnsKICAgICAgICBEaXJlY3RTb3VuZERldmljZSAqIGRldmljZSA9IChEaXJlY3RTb3VuZERldmljZSopZHdVc2VyOwoJVFJBQ0UoIiglcCwleCwlbHgsJWx4LCVseClcbiIsaHdvLG1zZyxkd1VzZXIsZHcxLGR3Mik7CglUUkFDRSgiZW50ZXJpbmcgYXQgJWxkLCBtc2c9JTA4eCglcylcbiIsIEdldFRpY2tDb3VudCgpLCBtc2csIAoJCW1zZz09TU1fV09NX0RPTkUgPyAiTU1fV09NX0RPTkUiIDogbXNnPT1NTV9XT01fQ0xPU0UgPyAiTU1fV09NX0NMT1NFIiA6IAoJCW1zZz09TU1fV09NX09QRU4gPyAiTU1fV09NX09QRU4iIDogIlVOS05PV04iKTsKCWlmIChtc2cgPT0gTU1fV09NX0RPTkUpIHsKCQlEV09SRCBpbnEsIG1peHEsIGZyYWdsZW4sIGJ1ZmxlbiwgcHdwbGF5LCBwbGF5cG9zLCBtaXhwb3M7CgkJaWYgKGRldmljZS0+cHdxdWV1ZSA9PSAoRFdPUkQpLTEpIHsKCQkJVFJBQ0UoImNvbXBsZXRlZCBkdWUgdG8gcmVzZXRcbiIpOwoJCQlyZXR1cm47CgkJfQovKiBpdCBjb3VsZCBiZSBhIGJhZCBpZGVhIHRvIGVudGVyIGNyaXRpY2FsIHNlY3Rpb24gaGVyZS4uLiBpZiB0aGVyZSdzIGxvY2sgY29udGVudGlvbiwKICogdGhlIHJlc3VsdGluZyBzY2hlZHVsaW5nIGRlbGF5cyBtaWdodCBvYnN0cnVjdCB0aGUgd2lubW0gcGxheWVyIHRocmVhZCAqLwojaWZkZWYgU1lOQ19DQUxMQkFDSwoJCUVudGVyQ3JpdGljYWxTZWN0aW9uKCYoZGV2aWNlLT5taXhsb2NrKSk7CiNlbmRpZgoJCS8qIHJldHJpZXZlIGN1cnJlbnQgdmFsdWVzICovCgkJZnJhZ2xlbiA9IGRldmljZS0+ZnJhZ2xlbjsKCQlidWZsZW4gPSBkZXZpY2UtPmJ1ZmxlbjsKCQlwd3BsYXkgPSBkZXZpY2UtPnB3cGxheTsKCQlwbGF5cG9zID0gcHdwbGF5ICogZnJhZ2xlbjsKCQltaXhwb3MgPSBkZXZpY2UtPm1peHBvczsKCQkvKiBjaGVjayByZW1haW5pbmcgbWl4ZWQgZGF0YSAqLwoJCWlucSA9ICgobWl4cG9zIDwgcGxheXBvcykgPyBidWZsZW4gOiAwKSArIG1peHBvcyAtIHBsYXlwb3M7CgkJbWl4cSA9IGlucSAvIGZyYWdsZW47CgkJaWYgKChpbnEgLSAobWl4cSAqIGZyYWdsZW4pKSA+IDApIG1peHErKzsKCQkvKiBjb21wbGV0ZSB0aGUgcGxheWluZyBidWZmZXIgKi8KCQlUUkFDRSgiZG9uZSBwbGF5aW5nIHByaW1hcnkgcG9zPSVsZFxuIiwgcGxheXBvcyk7CgkJcHdwbGF5Kys7CgkJaWYgKHB3cGxheSA+PSBEU19IRUxfRlJBR1MpIHB3cGxheSA9IDA7CgkJLyogd3JpdGUgbmV3IHZhbHVlcyAqLwoJCWRldmljZS0+cHdwbGF5ID0gcHdwbGF5OwoJCWRldmljZS0+cHdxdWV1ZS0tOwoJCS8qIHF1ZXVlIG5ldyBidWZmZXIgaWYgd2UgaGF2ZSBkYXRhIGZvciBpdCAqLwoJCWlmIChpbnE+MSkgRFNPVU5EX1dhdmVRdWV1ZShkZXZpY2UsIGlucS0xKTsKI2lmZGVmIFNZTkNfQ0FMTEJBQ0sKCQlMZWF2ZUNyaXRpY2FsU2VjdGlvbigmKGRldmljZS0+bWl4bG9jaykpOwojZW5kaWYKCX0KCVRSQUNFKCJjb21wbGV0ZWRcbiIpOwp9Cg==