LyogIAkJCURpcmVjdFNvdW5kCiAqCiAqIENvcHlyaWdodCAxOTk4IE1hcmN1cyBNZWlzc25lcgogKiBDb3B5cmlnaHQgMTk5OCBSb2IgUmlnZ3MKICogQ29weXJpZ2h0IDIwMDAtMjAwMiBUcmFuc0dhbWluZyBUZWNobm9sb2dpZXMsIEluYy4KICoKICogVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vcgogKiBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlcgogKiB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KICoKICogVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsCiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VCiAqIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZQogKiBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSwgVVNBCiAqLwoKI2luY2x1ZGUgPGFzc2VydC5oPgojaW5jbHVkZSA8c3RkYXJnLmg+CiNpbmNsdWRlIDxtYXRoLmg+CS8qIEluc29tbmlhIC0gcG93KCkgZnVuY3Rpb24gKi8KCiNkZWZpbmUgTk9OQU1FTEVTU1NUUlVDVAojZGVmaW5lIE5PTkFNRUxFU1NVTklPTgojaW5jbHVkZSAid2luZGVmLmgiCiNpbmNsdWRlICJ3aW5iYXNlLmgiCiNpbmNsdWRlICJ3aW51c2VyLmgiCiNpbmNsdWRlICJtbXN5c3RlbS5oIgojaW5jbHVkZSAid2lucmVnLmgiCiNpbmNsdWRlICJ3aW50ZXJubC5oIgojaW5jbHVkZSAid2luZS9kZWJ1Zy5oIgojaW5jbHVkZSAiZHNvdW5kLmgiCiNpbmNsdWRlICJkc2RyaXZlci5oIgojaW5jbHVkZSAiZHNvdW5kX3ByaXZhdGUuaCIKCldJTkVfREVGQVVMVF9ERUJVR19DSEFOTkVMKGRzb3VuZCk7Cgp2b2lkIERTT1VORF9SZWNhbGNWb2xQYW4oUERTVk9MVU1FUEFOIHZvbHBhbikKewoJZG91YmxlIHRlbXA7CglUUkFDRSgiKCVwKVxuIix2b2xwYW4pOwoKCVRSQUNFKCJWb2w9JWxkIFBhbj0lbGRcbiIsIHZvbHBhbi0+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+aEV2ZW50Tm90aWZ5LCBpKTsKCQkJCVNldEV2ZW50KGV2ZW50LT5oRXZlbnROb3RpZnkpOwoJCQl9CgkJfQoJfQp9CgovKiBXQVYgZm9ybWF0IGluZm8gY2FuIGJlIGZvdW5kIGF0OgogKgogKiAgICBodHRwOi8vd3d3LmN3aS5ubC9mdHAvYXVkaW8vQXVkaW9Gb3JtYXRzLnBhcnQyCiAqICAgIGZ0cDovL2Z0cC5jd2kubmwvcHViL2F1ZGlvL1JJRkYtZm9ybWF0CiAqCiAqIEltcG9ydCBwb2ludHMgdG8gcmVtZW1iZXI6CiAqICAgIDgtYml0IFdBViBpcyB1bnNpZ25lZAogKiAgICAxNi1iaXQgV0FWIGlzIHNpZ25lZAogKi8KIC8qIFVzZSB0aGUgc2FtZSBmb3JtdWxhcyBhcyBwY21jb252ZXJ0ZXIuYyAqLwpzdGF0aWMgaW5saW5lIElOVDE2IGN2dFU4dG9TMTYoQllURSBiKQp7CiAgICByZXR1cm4gKHNob3J0KSgoYisoYiA8PCA4KSktMzI3NjgpOwp9CgpzdGF0aWMgaW5saW5lIEJZVEUgY3Z0UzE2dG9VOChJTlQxNiBzKQp7CiAgICByZXR1cm4gKHMgPj4gOCkgXiAodW5zaWduZWQgY2hhcikweDgwOwp9CgpzdGF0aWMgaW5saW5lIHZvaWQgY3BfZmllbGRzKGNvbnN0IElEaXJlY3RTb3VuZEJ1ZmZlckltcGwgKmRzYiwgQllURSAqaWJ1ZiwgQllURSAqb2J1ZiApCnsKCURpcmVjdFNvdW5kRGV2aWNlICogZGV2aWNlID0gZHNiLT5kZXZpY2U7CiAgICAgICAgSU5UIGZsLGZyOwoKICAgICAgICBpZiAoZHNiLT5wd2Z4LT53Qml0c1BlclNhbXBsZSA9PSA4KSAgewogICAgICAgICAgICAgICAgaWYgKGRldmljZS0+cHdmeC0+d0JpdHNQZXJTYW1wbGUgPT0gOCAmJgogICAgICAgICAgICAgICAgICAgIGRldmljZS0+cHdmeC0+bkNoYW5uZWxzID09IGRzYi0+cHdmeC0+bkNoYW5uZWxzKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8qIGF2b2lkIG5lZWRsZXNzIDgtPjE2LT44IGNvbnZlcnNpb24gKi8KICAgICAgICAgICAgICAgICAgICAgICAgKm9idWY9KmlidWY7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChkc2ItPnB3ZngtPm5DaGFubmVscz09MikKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKG9idWYrMSk9KihpYnVmKzEpOwogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBmbCA9IGN2dFU4dG9TMTYoKmlidWYpOwogICAgICAgICAgICAgICAgZnIgPSAoZHNiLT5wd2Z4LT5uQ2hhbm5lbHM9PTIgPyBjdnRVOHRvUzE2KCooaWJ1ZiArIDEpKSA6IGZsKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgZmwgPSAqKChJTlQxNiAqKWlidWYpOwogICAgICAgICAgICAgICAgZnIgPSAoZHNiLT5wd2Z4LT5uQ2hhbm5lbHM9PTIgPyAqKCgoSU5UMTYgKilpYnVmKSArIDEpICA6IGZsKTsKICAgICAgICB9CgogICAgICAgIGlmIChkZXZpY2UtPnB3ZngtPm5DaGFubmVscyA9PSAyKSB7CiAgICAgICAgICAgICAgICBpZiAoZGV2aWNlLT5wd2Z4LT53Qml0c1BlclNhbXBsZSA9PSA4KSB7CiAgICAgICAgICAgICAgICAgICAgICAgICpvYnVmID0gY3Z0UzE2dG9VOChmbCk7CiAgICAgICAgICAgICAgICAgICAgICAgICoob2J1ZiArIDEpID0gY3Z0UzE2dG9VOChmcik7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmIChkZXZpY2UtPnB3ZngtPndCaXRzUGVyU2FtcGxlID09IDE2KSB7CiAgICAgICAgICAgICAgICAgICAgICAgICooKElOVDE2ICopb2J1ZikgPSBmbDsKICAgICAgICAgICAgICAgICAgICAgICAgKigoKElOVDE2ICopb2J1ZikgKyAxKSA9IGZyOwogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGlmIChkZXZpY2UtPnB3ZngtPm5DaGFubmVscyA9PSAxKSB7CiAgICAgICAgICAgICAgICBmbCA9IChmbCArIGZyKSA+PiAxOwogICAgICAgICAgICAgICAgaWYgKGRldmljZS0+cHdmeC0+d0JpdHNQZXJTYW1wbGUgPT0gOCkgewogICAgICAgICAgICAgICAgICAgICAgICAqb2J1ZiA9IGN2dFMxNnRvVTgoZmwpOwogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoZGV2aWNlLT5wd2Z4LT53Qml0c1BlclNhbXBsZSA9PSAxNikgewogICAgICAgICAgICAgICAgICAgICAgICAqKChJTlQxNiAqKW9idWYpID0gZmw7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgIH0KICAgICAgICB9Cn0KCi8qIE5vdyB3aXRoIFBlcmZlY3RQaXRjaCAodG0pIHRlY2hub2xvZ3kgKi8Kc3RhdGljIElOVCBEU09VTkRfTWl4ZXJOb3JtKElEaXJlY3RTb3VuZEJ1ZmZlckltcGwgKmRzYiwgQllURSAqYnVmLCBJTlQgbGVuKQp7CglJTlQJaSwgc2l6ZSwgaXBvcywgaWxlbjsKCUJZVEUJKmlicCwgKm9icDsKCUlOVAlpQWR2YW5jZSA9IGRzYi0+cHdmeC0+bkJsb2NrQWxpZ247CglJTlQJb0FkdmFuY2UgPSBkc2ItPmRldmljZS0+cHdmeC0+bkJsb2NrQWxpZ247CgoJaWJwID0gZHNiLT5idWZmZXItPm1lbW9yeSArIGRzYi0+YnVmX21peHBvczsKCW9icCA9IGJ1ZjsKCglUUkFDRSgiKCVwLCAlcCwgJXApLCBidWZfbWl4cG9zPSVsZFxuIiwgZHNiLCBpYnAsIG9icCwgZHNiLT5idWZfbWl4cG9zKTsKCS8qIENoZWNrIGZvciB0aGUgYmVzdCBjYXNlICovCglpZiAoKGRzYi0+ZnJlcSA9PSBkc2ItPmRldmljZS0+cHdmeC0+blNhbXBsZXNQZXJTZWMpICYmCgkgICAgKGRzYi0+cHdmeC0+d0JpdHNQZXJTYW1wbGUgPT0gZHNiLT5kZXZpY2UtPnB3ZngtPndCaXRzUGVyU2FtcGxlKSAmJgoJICAgIChkc2ItPnB3ZngtPm5DaGFubmVscyA9PSBkc2ItPmRldmljZS0+cHdmeC0+bkNoYW5uZWxzKSkgewoJICAgICAgICBJTlQgYnl0ZXNsZWZ0ID0gZHNiLT5idWZsZW4gLSBkc2ItPmJ1Zl9taXhwb3M7CgkJVFJBQ0UoIiglcCkgQmVzdCBjYXNlXG4iLCBkc2IpOwoJICAgIAlpZiAobGVuIDw9IGJ5dGVzbGVmdCApCgkJCUNvcHlNZW1vcnkob2JwLCBpYnAsIGxlbik7CgkJZWxzZSB7IC8qIHdyYXAgKi8KCQkJQ29weU1lbW9yeShvYnAsIGlicCwgYnl0ZXNsZWZ0KTsKCQkJQ29weU1lbW9yeShvYnAgKyBieXRlc2xlZnQsIGRzYi0+YnVmZmVyLT5tZW1vcnksIGxlbiAtIGJ5dGVzbGVmdCk7CgkJfQoJCXJldHVybiBsZW47Cgl9CgoJLyogQ2hlY2sgZm9yIHNhbWUgc2FtcGxlIHJhdGUgKi8KCWlmIChkc2ItPmZyZXEgPT0gZHNiLT5kZXZpY2UtPnB3ZngtPm5TYW1wbGVzUGVyU2VjKSB7CgkJVFJBQ0UoIiglcCkgU2FtZSBzYW1wbGUgcmF0ZSAlbGQgPSBwcmltYXJ5ICVsZFxuIiwgZHNiLAoJCQlkc2ItPmZyZXEsIGRzYi0+ZGV2aWNlLT5wd2Z4LT5uU2FtcGxlc1BlclNlYyk7CgkJaWxlbiA9IDA7CgkJZm9yIChpID0gMDsgaSA8IGxlbjsgaSArPSBvQWR2YW5jZSkgewoJCQljcF9maWVsZHMoZHNiLCBpYnAsIG9icCApOwoJCQlpYnAgKz0gaUFkdmFuY2U7CgkJCWlsZW4gKz0gaUFkdmFuY2U7CgkJCW9icCArPSBvQWR2YW5jZTsKCQkJaWYgKGlicCA+PSAoQllURSAqKShkc2ItPmJ1ZmZlci0+bWVtb3J5ICsgZHNiLT5idWZsZW4pKQoJCQkJaWJwID0gZHNiLT5idWZmZXItPm1lbW9yeTsJLyogd3JhcCAqLwoJCX0KCQlyZXR1cm4gKGlsZW4pOwoJfQoKCS8qIE1peCBpbiBkaWZmZXJlbnQgc2FtcGxlIHJhdGVzICovCgkvKiAqLwoJLyogTmV3IFBlcmZlY3RQaXRjaCh0bSkgVGVjaG5vbG9neSAoYykgMTk5OCBSb2IgUmlnZ3MgKi8KCS8qIFBhdGVudCBQZW5kaW5nIDotXSAqLwoKCS8qIFBhdGVudCBlbmhhbmNlbWVudHMgKGMpIDIwMDAgT3ZlIEvldmVuLAoJICogVHJhbnNHYW1pbmcgVGVjaG5vbG9naWVzIEluYy4gKi8KCgkvKiBGSVhNRSgiKCVwKSBBZGp1c3RpbmcgZnJlcXVlbmN5OiAlbGQgLT4gJWxkIChuZWVkIG9wdGltaXphdGlvbilcbiIsCgkgICBkc2IsIGRzYi0+ZnJlcSwgZHNiLT5kZXZpY2UtPnB3ZngtPm5TYW1wbGVzUGVyU2VjKTsgKi8KCglzaXplID0gbGVuIC8gb0FkdmFuY2U7CglpbGVuID0gMDsKCWlwb3MgPSBkc2ItPmJ1Zl9taXhwb3M7Cglmb3IgKGkgPSAwOyBpIDwgc2l6ZTsgaSsrKSB7CiAgICAgICAgICAgICAgICBjcF9maWVsZHMoZHNiLCAoZHNiLT5idWZmZXItPm1lbW9yeSArIGlwb3MpLCBvYnApOwoJCW9icCArPSBvQWR2YW5jZTsKCQlkc2ItPmZyZXFBY2MgKz0gZHNiLT5mcmVxQWRqdXN0OwoJCWlmIChkc2ItPmZyZXFBY2MgPj0gKDE8PERTT1VORF9GUkVRU0hJRlQpKSB7CgkJCVVMT05HIGFkdiA9IChkc2ItPmZyZXFBY2M+PkRTT1VORF9GUkVRU0hJRlQpICogaUFkdmFuY2U7CgkJCWRzYi0+ZnJlcUFjYyAmPSAoMTw8RFNPVU5EX0ZSRVFTSElGVCktMTsKCQkJaXBvcyArPSBhZHY7IGlsZW4gKz0gYWR2OwoJCQlpcG9zICU9IGRzYi0+YnVmbGVuOwoJCX0KCX0KCXJldHVybiBpbGVuOwp9CgpzdGF0aWMgdm9pZCBEU09VTkRfTWl4ZXJWb2woSURpcmVjdFNvdW5kQnVmZmVySW1wbCAqZHNiLCBCWVRFICpidWYsIElOVCBsZW4pCnsKCUlOVAlpOwoJQllURQkqYnBjID0gYnVmOwoJSU5UMTYJKmJwcyA9IChJTlQxNiAqKSBidWY7CgoJVFJBQ0UoIiglcCwlcCwlZClcbiIsZHNiLGJ1ZixsZW4pOwoJVFJBQ0UoImxlZnQgPSAlbHgsIHJpZ2h0ID0gJWx4XG4iLCBkc2ItPmN2b2xwYW4uZHdUb3RhbExlZnRBbXBGYWN0b3IsIAoJCWRzYi0+Y3ZvbHBhbi5kd1RvdGFsUmlnaHRBbXBGYWN0b3IpOwoKCWlmICgoIShkc2ItPmRzYmQuZHdGbGFncyAmIERTQkNBUFNfQ1RSTFBBTikgfHwgKGRzYi0+Y3ZvbHBhbi5sUGFuID09IDApKSAmJgoJICAgICghKGRzYi0+ZHNiZC5kd0ZsYWdzICYgRFNCQ0FQU19DVFJMVk9MVU1FKSB8fCAoZHNiLT5jdm9scGFuLmxWb2x1bWUgPT0gMCkpICYmCgkgICAgIShkc2ItPmRzYmQuZHdGbGFncyAmIERTQkNBUFNfQ1RSTDNEKSkKCQlyZXR1cm47CQkvKiBOb3RoaW5nIHRvIGRvICovCgoJLyogSWYgd2UgZW5kIHVwIHdpdGggc29tZSBib3pvIGNvZGVyIHVzaW5nIHBhbm5pbmcgb3IgM0Qgc291bmQgKi8KCS8qIHdpdGggYSBtb25vIHByaW1hcnkgYnVmZmVyLCBpdCBjb3VsZCBzb3VuZCB2ZXJ5IHdlaXJkIHVzaW5nICovCgkvKiB0aGlzIG1ldGhvZC4gT2ggd2VsbCwgdG91Z2ggcGF0b290aWVzLiAqLwoKCXN3aXRjaCAoZHNiLT5kZXZpY2UtPnB3ZngtPndCaXRzUGVyU2FtcGxlKSB7CgljYXNlIDg6CgkJLyogOC1iaXQgV0FWIGlzIHVuc2lnbmVkLCBidXQgd2UgbmVlZCB0byBvcGVyYXRlICovCgkJLyogb24gc2lnbmVkIGRhdGEgZm9yIHRoaXMgdG8gd29yayBwcm9wZXJseSAqLwoJCXN3aXRjaCAoZHNiLT5kZXZpY2UtPnB3ZngtPm5DaGFubmVscykgewoJCWNhc2UgMToKCQkJZm9yIChpID0gMDsgaSA8IGxlbjsgaSsrKSB7CgkJCQlJTlQgdmFsID0gKmJwYyAtIDEyODsKCQkJCXZhbCA9ICh2YWwgKiBkc2ItPmN2b2xwYW4uZHdUb3RhbExlZnRBbXBGYWN0b3IpID4+IDE2OwoJCQkJKmJwYyA9IHZhbCArIDEyODsKCQkJCWJwYysrOwoJCQl9CgkJCWJyZWFrOwoJCWNhc2UgMjoKCQkJZm9yIChpID0gMDsgaSA8IGxlbjsgaSs9MikgewoJCQkJSU5UIHZhbCA9ICpicGMgLSAxMjg7CgkJCQl2YWwgPSAodmFsICogZHNiLT5jdm9scGFuLmR3VG90YWxMZWZ0QW1wRmFjdG9yKSA+PiAxNjsKCQkJCSpicGMrKyA9IHZhbCArIDEyODsKCQkJCXZhbCA9ICpicGMgLSAxMjg7CgkJCQl2YWwgPSAodmFsICogZHNiLT5jdm9scGFuLmR3VG90YWxSaWdodEFtcEZhY3RvcikgPj4gMTY7CgkJCQkqYnBjID0gdmFsICsgMTI4OwoJCQkJYnBjKys7CgkJCX0KCQkJYnJlYWs7CgkJZGVmYXVsdDoKCQkJRklYTUUoImRvZXNuJ3Qgc3VwcG9ydCAlZCBjaGFubmVsc1xuIiwgZHNiLT5kZXZpY2UtPnB3ZngtPm5DaGFubmVscyk7CgkJCWJyZWFrOwoJCX0KCQlicmVhazsKCWNhc2UgMTY6CgkJLyogMTYtYml0IFdBViBpcyBzaWduZWQgLS0gbXVjaCBiZXR0ZXIgKi8KCQlzd2l0Y2ggKGRzYi0+ZGV2aWNlLT5wd2Z4LT5uQ2hhbm5lbHMpIHsKCQljYXNlIDE6CgkJCWZvciAoaSA9IDA7IGkgPCBsZW47IGkgKz0gMikgewoJCQkJKmJwcyA9ICgqYnBzICogZHNiLT5jdm9scGFuLmR3VG90YWxMZWZ0QW1wRmFjdG9yKSA+PiAxNjsKCQkJCWJwcysrOwoJCQl9CgkJCWJyZWFrOwoJCWNhc2UgMjoKCQkJZm9yIChpID0gMDsgaSA8IGxlbjsgaSArPSA0KSB7CgkJCQkqYnBzID0gKCpicHMgKiBkc2ItPmN2b2xwYW4uZHdUb3RhbExlZnRBbXBGYWN0b3IpID4+IDE2OwoJCQkJYnBzKys7CgkJCQkqYnBzID0gKCpicHMgKiBkc2ItPmN2b2xwYW4uZHdUb3RhbFJpZ2h0QW1wRmFjdG9yKSA+PiAxNjsKCQkJCWJwcysrOwoJCQl9CgkJCWJyZWFrOwoJCWRlZmF1bHQ6CgkJCUZJWE1FKCJkb2Vzbid0IHN1cHBvcnQgJWQgY2hhbm5lbHNcbiIsIGRzYi0+ZGV2aWNlLT5wd2Z4LT5uQ2hhbm5lbHMpOwoJCQlicmVhazsKCQl9CgkJYnJlYWs7CglkZWZhdWx0OgoJCUZJWE1FKCJkb2Vzbid0IHN1cHBvcnQgJWQgYml0IHNhbXBsZXNcbiIsIGRzYi0+ZGV2aWNlLT5wd2Z4LT53Qml0c1BlclNhbXBsZSk7CgkJYnJlYWs7Cgl9Cn0KCnN0YXRpYyBMUEJZVEUgRFNPVU5EX3RtcGJ1ZmZlcihEaXJlY3RTb3VuZERldmljZSAqZGV2aWNlLCBEV09SRCBsZW4pCnsKICAgIFRSQUNFKCIoJXAsJWxkKVxuIiwgZGV2aWNlLCBsZW4pOwoKICAgIGlmIChsZW4gPiBkZXZpY2UtPnRtcF9idWZmZXJfbGVuKSB7CiAgICAgICAgaWYgKGRldmljZS0+dG1wX2J1ZmZlcikKICAgICAgICAgICAgZGV2aWNlLT50bXBfYnVmZmVyID0gSGVhcFJlQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgZGV2aWNlLT50bXBfYnVmZmVyLCBsZW4pOwogICAgICAgIGVsc2UKICAgICAgICAgICAgZGV2aWNlLT50bXBfYnVmZmVyID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIGxlbik7CgogICAgICAgIGRldmljZS0+dG1wX2J1ZmZlcl9sZW4gPSBsZW47CiAgICB9CgogICAgcmV0dXJuIGRldmljZS0+dG1wX2J1ZmZlcjsKfQoKc3RhdGljIERXT1JEIERTT1VORF9NaXhJbkJ1ZmZlcihJRGlyZWN0U291bmRCdWZmZXJJbXBsICpkc2IsIERXT1JEIHdyaXRlcG9zLCBEV09SRCBmcmFnbGVuKQp7CglJTlQJaSwgbGVuLCBpbGVuLCBmaWVsZCwgdG9kbzsKCUJZVEUJKmJ1ZiwgKmlidWY7CgoJVFJBQ0UoIiglcCwlbGQsJWxkKVxuIixkc2Isd3JpdGVwb3MsZnJhZ2xlbik7CgoJbGVuID0gZnJhZ2xlbjsKCWlmICghKGRzYi0+cGxheWZsYWdzICYgRFNCUExBWV9MT09QSU5HKSkgewoJCWludCBzZWNvbmRhcnlfcmVtYWluZGVyID0gZHNiLT5idWZsZW4gLSBkc2ItPmJ1Zl9taXhwb3M7CgkJaW50IGFkanVzdGVkX3JlbWFpbmRlciA9IE11bERpdihkc2ItPmRldmljZS0+cHdmeC0+bkF2Z0J5dGVzUGVyU2VjLCBzZWNvbmRhcnlfcmVtYWluZGVyLCBkc2ItPm5BdmdCeXRlc1BlclNlYyk7CgkJYXNzZXJ0KGFkanVzdGVkX3JlbWFpbmRlciA+PSAwKTsKCQlUUkFDRSgic2Vjb25kYXJ5X3JlbWFpbmRlciA9ICVkLCBhZGp1c3RlZF9yZW1haW5kZXIgPSAlZCwgbGVuID0gJWRcbiIsIHNlY29uZGFyeV9yZW1haW5kZXIsIGFkanVzdGVkX3JlbWFpbmRlciwgbGVuKTsKCQlpZiAoYWRqdXN0ZWRfcmVtYWluZGVyIDwgbGVuKSB7CgkJCVRSQUNFKCJjbGlwcGluZyBsZW4gdG8gcmVtYWluZGVyIG9mIHNlY29uZGFyeSBidWZmZXJcbiIpOwoJCQlsZW4gPSBhZGp1c3RlZF9yZW1haW5kZXI7CgkJfQoJCWlmIChsZW4gPT0gMCkKCQkJcmV0dXJuIDA7Cgl9CgoJaWYgKGxlbiAlIGRzYi0+ZGV2aWNlLT5wd2Z4LT5uQmxvY2tBbGlnbikgewoJCUlOVCBuQmxvY2tBbGlnbiA9IGRzYi0+ZGV2aWNlLT5wd2Z4LT5uQmxvY2tBbGlnbjsKCQlFUlIoImxlbmd0aCBub3QgYSBtdWx0aXBsZSBvZiBibG9jayBzaXplLCBsZW4gPSAlZCwgYmxvY2sgc2l6ZSA9ICVkXG4iLCBsZW4sIG5CbG9ja0FsaWduKTsKCQlsZW4gPSAobGVuIC8gbkJsb2NrQWxpZ24pICogbkJsb2NrQWxpZ247CS8qIGRhdGEgYWxpZ25tZW50ICovCgl9CgoJaWYgKChidWYgPSBpYnVmID0gRFNPVU5EX3RtcGJ1ZmZlcihkc2ItPmRldmljZSwgbGVuKSkgPT0gTlVMTCkKCQlyZXR1cm4gMDsKCglUUkFDRSgiTWl4SW5CdWZmZXIgKCVwKSBsZW4gPSAlZCwgZGVzdCA9ICVsZFxuIiwgZHNiLCBsZW4sIHdyaXRlcG9zKTsKCglpbGVuID0gRFNPVU5EX01peGVyTm9ybShkc2IsIGlidWYsIGxlbik7CglpZiAoKGRzYi0+ZHNiZC5kd0ZsYWdzICYgRFNCQ0FQU19DVFJMUEFOKSB8fAoJICAgIChkc2ItPmRzYmQuZHdGbGFncyAmIERTQkNBUFNfQ1RSTFZPTFVNRSkgfHwKCSAgICAoZHNiLT5kc2JkLmR3RmxhZ3MgJiBEU0JDQVBTX0NUUkwzRCkpCgkJRFNPVU5EX01peGVyVm9sKGRzYiwgaWJ1ZiwgbGVuKTsKCglpZiAoZHNiLT5kZXZpY2UtPnB3ZngtPndCaXRzUGVyU2FtcGxlID09IDgpIHsKCQlCWVRFCSpvYnVmID0gZHNiLT5kZXZpY2UtPmJ1ZmZlciArIHdyaXRlcG9zOwoKCQlpZiAoKHdyaXRlcG9zICsgbGVuKSA8PSBkc2ItPmRldmljZS0+YnVmbGVuKQoJCQl0b2RvID0gbGVuOwoJCWVsc2UKCQkJdG9kbyA9IGRzYi0+ZGV2aWNlLT5idWZsZW4gLSB3cml0ZXBvczsKCgkJZm9yIChpID0gMDsgaSA8IHRvZG87IGkrKykgewoJCQkvKiA4LWJpdCBXQVYgaXMgdW5zaWduZWQgKi8KCQkJZmllbGQgPSAoKmlidWYrKyAtIDEyOCk7CgkJCWZpZWxkICs9ICgqb2J1ZiAtIDEyOCk7CgkJCWlmIChmaWVsZCA+IDEyNykgZmllbGQgPSAxMjc7CgkJCWVsc2UgaWYgKGZpZWxkIDwgLTEyOCkgZmllbGQgPSAtMTI4OwoJCQkqb2J1ZisrID0gZmllbGQgKyAxMjg7CgkJfQogCgkJaWYgKHRvZG8gPCBsZW4pIHsKCQkJdG9kbyA9IGxlbiAtIHRvZG87CgkJCW9idWYgPSBkc2ItPmRldmljZS0+YnVmZmVyOwoKCQkJZm9yIChpID0gMDsgaSA8IHRvZG87IGkrKykgewoJCQkJLyogOC1iaXQgV0FWIGlzIHVuc2lnbmVkICovCgkJCQlmaWVsZCA9ICgqaWJ1ZisrIC0gMTI4KTsKCQkJCWZpZWxkICs9ICgqb2J1ZiAtIDEyOCk7CgkJCQlpZiAoZmllbGQgPiAxMjcpIGZpZWxkID0gMTI3OwoJCQkJZWxzZSBpZiAoZmllbGQgPCAtMTI4KSBmaWVsZCA9IC0xMjg7CgkJCQkqb2J1ZisrID0gZmllbGQgKyAxMjg7CgkJCX0KCQl9CiAgICAgICAgfSBlbHNlIHsKCQlJTlQxNgkqaWJ1ZnMsICpvYnVmczsKCgkJaWJ1ZnMgPSAoSU5UMTYgKikgaWJ1ZjsKCQlvYnVmcyA9IChJTlQxNiAqKShkc2ItPmRldmljZS0+YnVmZmVyICsgd3JpdGVwb3MpOwoKCQlpZiAoKHdyaXRlcG9zICsgbGVuKSA8PSBkc2ItPmRldmljZS0+YnVmbGVuKQoJCQl0b2RvID0gbGVuIC8gMjsKCQllbHNlCgkJCXRvZG8gPSAoZHNiLT5kZXZpY2UtPmJ1ZmxlbiAtIHdyaXRlcG9zKSAvIDI7CgoJCWZvciAoaSA9IDA7IGkgPCB0b2RvOyBpKyspIHsKCQkJLyogMTYtYml0IFdBViBpcyBzaWduZWQgKi8KCQkJZmllbGQgPSAqaWJ1ZnMrKzsKCQkJZmllbGQgKz0gKm9idWZzOwoJCQlpZiAoZmllbGQgPiAzMjc2NykgZmllbGQgPSAzMjc2NzsKCQkJZWxzZSBpZiAoZmllbGQgPCAtMzI3NjgpIGZpZWxkID0gLTMyNzY4OwoJCQkqb2J1ZnMrKyA9IGZpZWxkOwoJCX0KCgkJaWYgKHRvZG8gPCAobGVuIC8gMikpIHsKCQkJdG9kbyA9IChsZW4gLyAyKSAtIHRvZG87CgkJCW9idWZzID0gKElOVDE2ICopZHNiLT5kZXZpY2UtPmJ1ZmZlcjsKCgkJCWZvciAoaSA9IDA7IGkgPCB0b2RvOyBpKyspIHsKCQkJCS8qIDE2LWJpdCBXQVYgaXMgc2lnbmVkICovCgkJCQlmaWVsZCA9ICppYnVmcysrOwoJCQkJZmllbGQgKz0gKm9idWZzOwoJCQkJaWYgKGZpZWxkID4gMzI3NjcpIGZpZWxkID0gMzI3Njc7CgkJCQllbHNlIGlmIChmaWVsZCA8IC0zMjc2OCkgZmllbGQgPSAtMzI3Njg7CgkJCQkqb2J1ZnMrKyA9IGZpZWxkOwoJCQl9CgkJfQogICAgICAgIH0KCglpZiAoZHNiLT5sZWFkaW4gJiYgKGRzYi0+c3RhcnRwb3MgPiBkc2ItPmJ1Zl9taXhwb3MpICYmIChkc2ItPnN0YXJ0cG9zIDw9IGRzYi0+YnVmX21peHBvcyArIGlsZW4pKSB7CgkJLyogSEFDSy4uLiBsZWFkaW4gc2hvdWxkIGJlIHJlc2V0IHdoZW4gdGhlIFBMQVkgcG9zaXRpb24gcmVhY2hlcyB0aGUgc3RhcnRwb3MsCgkJICogbm90IHRoZSBNSVggcG9zaXRpb24uLi4gYnV0IGlmIHRoZSBzb3VuZCBidWZmZXIgaXMgYmlnZ2VyIHRoYW4gb3VyIHByZWJ1ZmZlcmluZwoJCSAqICh3aGljaCBtdXN0IGJlIHRoZSBjYXNlIGZvciB0aGUgc3RyZWFtaW5nIGJ1ZmZlcnMgdGhhdCBuZWVkIHRoaXMgaGFjayBhbnl3YXkpCgkJICogcGx1cyBEU19IRUxfTUFSR0lOIG9yIGVxdWl2YWxlbnQsIHRoZW4gdGhpcyBvdWdodCB0byB3b3JrIGFueXdheS4gKi8KCQlkc2ItPmxlYWRpbiA9IEZBTFNFOwoJfQoKCWRzYi0+YnVmX21peHBvcyArPSBpbGVuOwoKCWlmIChkc2ItPmJ1Zl9taXhwb3MgPj0gZHNiLT5idWZsZW4pIHsKCQlpZiAoZHNiLT5wbGF5ZmxhZ3MgJiBEU0JQTEFZX0xPT1BJTkcpIHsKCQkJLyogd3JhcCAqLwoJCQlkc2ItPmJ1Zl9taXhwb3MgJT0gZHNiLT5idWZsZW47CgkJCWlmIChkc2ItPmxlYWRpbiAmJiAoZHNiLT5zdGFydHBvcyA8PSBkc2ItPmJ1Zl9taXhwb3MpKQoJCQkJZHNiLT5sZWFkaW4gPSBGQUxTRTsgLyogSEFDSzogc2VlIGFib3ZlICovCgkJfSBlbHNlIGlmIChkc2ItPmJ1Zl9taXhwb3MgPiBkc2ItPmJ1ZmxlbikgewoJCQlFUlIoIk1peHBvcyAoJWx1KSBwYXN0IGJ1ZmxlbiAoJWx1KSwgY2FwcGluZy4uLlxuIiwgZHNiLT5idWZfbWl4cG9zLCBkc2ItPmJ1Zmxlbik7CgkJCWRzYi0+YnVmX21peHBvcyA9IGRzYi0+YnVmbGVuOwoJCX0KCX0KCglyZXR1cm4gbGVuOwp9CgpzdGF0aWMgdm9pZCBEU09VTkRfUGhhc2VDYW5jZWwoSURpcmVjdFNvdW5kQnVmZmVySW1wbCAqZHNiLCBEV09SRCB3cml0ZXBvcywgRFdPUkQgbGVuKQp7CglJTlQgICAgIGlsZW4sIGZpZWxkOwoJVUlOVCAgICBpLCB0b2RvOwoJQllURQkqYnVmLCAqaWJ1ZjsKCglUUkFDRSgiKCVwLCVsZCwlbGQpXG4iLGRzYix3cml0ZXBvcyxsZW4pOwoKCWlmIChsZW4gJSBkc2ItPmRldmljZS0+cHdmeC0+bkJsb2NrQWxpZ24pIHsKCQlJTlQgbkJsb2NrQWxpZ24gPSBkc2ItPmRldmljZS0+cHdmeC0+bkJsb2NrQWxpZ247CgkJRVJSKCJsZW5ndGggbm90IGEgbXVsdGlwbGUgb2YgYmxvY2sgc2l6ZSwgbGVuID0gJWxkLCBibG9jayBzaXplID0gJWRcbiIsIGxlbiwgbkJsb2NrQWxpZ24pOwoJCWxlbiA9IChsZW4gLyBuQmxvY2tBbGlnbikgKiBuQmxvY2tBbGlnbjsJLyogZGF0YSBhbGlnbm1lbnQgKi8KCX0KCglpZiAoKGJ1ZiA9IGlidWYgPSBEU09VTkRfdG1wYnVmZmVyKGRzYi0+ZGV2aWNlLCBsZW4pKSA9PSBOVUxMKQoJCXJldHVybjsKCglUUkFDRSgiUGhhc2VDYW5jZWwgKCVwKSBsZW4gPSAlbGQsIGRlc3QgPSAlbGRcbiIsIGRzYiwgbGVuLCB3cml0ZXBvcyk7CgoJaWxlbiA9IERTT1VORF9NaXhlck5vcm0oZHNiLCBpYnVmLCBsZW4pOwoJaWYgKChkc2ItPmRzYmQuZHdGbGFncyAmIERTQkNBUFNfQ1RSTFBBTikgfHwKCSAgICAoZHNiLT5kc2JkLmR3RmxhZ3MgJiBEU0JDQVBTX0NUUkxWT0xVTUUpIHx8CgkgICAgKGRzYi0+ZHNiZC5kd0ZsYWdzICYgRFNCQ0FQU19DVFJMM0QpKQoJCURTT1VORF9NaXhlclZvbChkc2IsIGlidWYsIGxlbik7CgoJLyogc3VidHJhY3QgaW5zdGVhZCBvZiBhZGQsIHRvIHBoYXNlIG91dCBwcmVtaXhlZCBkYXRhICovCglpZiAoZHNiLT5kZXZpY2UtPnB3ZngtPndCaXRzUGVyU2FtcGxlID09IDgpIHsKCQlCWVRFCSpvYnVmID0gZHNiLT5kZXZpY2UtPmJ1ZmZlciArIHdyaXRlcG9zOwoKCQlpZiAoKHdyaXRlcG9zICsgbGVuKSA8PSBkc2ItPmRldmljZS0+YnVmbGVuKQoJCQl0b2RvID0gbGVuOwoJCWVsc2UKCQkJdG9kbyA9IGRzYi0+ZGV2aWNlLT5idWZsZW4gLSB3cml0ZXBvczsKCgkJZm9yIChpID0gMDsgaSA8IHRvZG87IGkrKykgewoJCQkvKiA4LWJpdCBXQVYgaXMgdW5zaWduZWQgKi8KCQkJZmllbGQgPSAoKm9idWYgLSAxMjgpOwoJCQlmaWVsZCAtPSAoKmlidWYrKyAtIDEyOCk7CgkJCWlmIChmaWVsZCA+IDEyNykgZmllbGQgPSAxMjc7CgkJCWVsc2UgaWYgKGZpZWxkIDwgLTEyOCkgZmllbGQgPSAtMTI4OwoJCQkqb2J1ZisrID0gZmllbGQgKyAxMjg7CgkJfQogCgkJaWYgKHRvZG8gPCBsZW4pIHsKCQkJdG9kbyA9IGxlbiAtIHRvZG87CgkJCW9idWYgPSBkc2ItPmRldmljZS0+YnVmZmVyOwoKCQkJZm9yIChpID0gMDsgaSA8IHRvZG87IGkrKykgewoJCQkJLyogOC1iaXQgV0FWIGlzIHVuc2lnbmVkICovCgkJCQlmaWVsZCA9ICgqb2J1ZiAtIDEyOCk7CgkJCQlmaWVsZCAtPSAoKmlidWYrKyAtIDEyOCk7CgkJCQlpZiAoZmllbGQgPiAxMjcpIGZpZWxkID0gMTI3OwoJCQkJZWxzZSBpZiAoZmllbGQgPCAtMTI4KSBmaWVsZCA9IC0xMjg7CgkJCQkqb2J1ZisrID0gZmllbGQgKyAxMjg7CgkJCX0KCQl9CiAgICAgICAgfSBlbHNlIHsKCQlJTlQxNgkqaWJ1ZnMsICpvYnVmczsKCgkJaWJ1ZnMgPSAoSU5UMTYgKikgaWJ1ZjsKCQlvYnVmcyA9IChJTlQxNiAqKShkc2ItPmRldmljZS0+YnVmZmVyICsgd3JpdGVwb3MpOwoKCQlpZiAoKHdyaXRlcG9zICsgbGVuKSA8PSBkc2ItPmRldmljZS0+YnVmbGVuKQoJCQl0b2RvID0gbGVuIC8gMjsKCQllbHNlCgkJCXRvZG8gPSAoZHNiLT5kZXZpY2UtPmJ1ZmxlbiAtIHdyaXRlcG9zKSAvIDI7CgoJCWZvciAoaSA9IDA7IGkgPCB0b2RvOyBpKyspIHsKCQkJLyogMTYtYml0IFdBViBpcyBzaWduZWQgKi8KCQkJZmllbGQgPSAqb2J1ZnM7CgkJCWZpZWxkIC09ICppYnVmcysrOwoJCQlpZiAoZmllbGQgPiAzMjc2NykgZmllbGQgPSAzMjc2NzsKCQkJZWxzZSBpZiAoZmllbGQgPCAtMzI3NjgpIGZpZWxkID0gLTMyNzY4OwoJCQkqb2J1ZnMrKyA9IGZpZWxkOwoJCX0KCgkJaWYgKHRvZG8gPCAobGVuIC8gMikpIHsKCQkJdG9kbyA9IChsZW4gLyAyKSAtIHRvZG87CgkJCW9idWZzID0gKElOVDE2ICopZHNiLT5kZXZpY2UtPmJ1ZmZlcjsKCgkJCWZvciAoaSA9IDA7IGkgPCB0b2RvOyBpKyspIHsKCQkJCS8qIDE2LWJpdCBXQVYgaXMgc2lnbmVkICovCgkJCQlmaWVsZCA9ICpvYnVmczsKCQkJCWZpZWxkIC09ICppYnVmcysrOwoJCQkJaWYgKGZpZWxkID4gMzI3NjcpIGZpZWxkID0gMzI3Njc7CgkJCQllbHNlIGlmIChmaWVsZCA8IC0zMjc2OCkgZmllbGQgPSAtMzI3Njg7CgkJCQkqb2J1ZnMrKyA9IGZpZWxkOwoJCQl9CgkJfQogICAgICAgIH0KfQoKc3RhdGljIHZvaWQgRFNPVU5EX01peENhbmNlbChJRGlyZWN0U291bmRCdWZmZXJJbXBsICpkc2IsIERXT1JEIHdyaXRlcG9zLCBCT09MIGNhbmNlbCkKewoJRFdPUkQgICBzaXplLCBmbGVuLCBsZW4sIG5wb3MsIG5sZW47CglJTlQJaUFkdmFuY2UgPSBkc2ItPnB3ZngtPm5CbG9ja0FsaWduOwoJSU5UCW9BZHZhbmNlID0gZHNiLT5kZXZpY2UtPnB3ZngtPm5CbG9ja0FsaWduOwoJLyogZGV0ZXJtaW5lIGFtb3VudCBvZiBwcmVtaXhlZCBkYXRhIHRvIGNhbmNlbCAqLwoJRFdPUkQgcHJpbWFyeV9kb25lID0KCQkoKGRzYi0+cHJpbWFyeV9taXhwb3MgPCB3cml0ZXBvcykgPyBkc2ItPmRldmljZS0+YnVmbGVuIDogMCkgKwoJCWRzYi0+cHJpbWFyeV9taXhwb3MgLSB3cml0ZXBvczsKCglUUkFDRSgiKCVwLCAlbGQpLCBidWZfbWl4cG9zPSVsZFxuIiwgZHNiLCB3cml0ZXBvcywgZHNiLT5idWZfbWl4cG9zKTsKCgkvKiBiYWNrdHJhY2sgdGhlIG1peCBwb3NpdGlvbiAqLwoJc2l6ZSA9IHByaW1hcnlfZG9uZSAvIG9BZHZhbmNlOwoJZmxlbiA9IHNpemUgKiBkc2ItPmZyZXFBZGp1c3Q7CglsZW4gPSAoZmxlbiA+PiBEU09VTkRfRlJFUVNISUZUKSAqIGlBZHZhbmNlOwoJZmxlbiAmPSAoMTw8RFNPVU5EX0ZSRVFTSElGVCktMTsKCXdoaWxlIChkc2ItPmZyZXFBY2MgPCBmbGVuKSB7CgkJbGVuICs9IGlBZHZhbmNlOwoJCWRzYi0+ZnJlcUFjYyArPSAxPDxEU09VTkRfRlJFUVNISUZUOwoJfQoJbGVuICU9IGRzYi0+YnVmbGVuOwoJbnBvcyA9ICgoZHNiLT5idWZfbWl4cG9zIDwgbGVuKSA/IGRzYi0+YnVmbGVuIDogMCkgKwoJCWRzYi0+YnVmX21peHBvcyAtIGxlbjsKCWlmIChkc2ItPmxlYWRpbiAmJiAoZHNiLT5zdGFydHBvcyA+IG5wb3MpICYmIChkc2ItPnN0YXJ0cG9zIDw9IG5wb3MgKyBsZW4pKSB7CgkJLyogc3RvcCBiYWNrdHJhY2tpbmcgYXQgc3RhcnRwb3MgKi8KCQlucG9zID0gZHNiLT5zdGFydHBvczsKCQlsZW4gPSAoKGRzYi0+YnVmX21peHBvcyA8IG5wb3MpID8gZHNiLT5idWZsZW4gOiAwKSArCgkJCWRzYi0+YnVmX21peHBvcyAtIG5wb3M7CgkJZmxlbiA9IGRzYi0+ZnJlcUFjYzsKCQlubGVuID0gbGVuIC8gZHNiLT5wd2Z4LT5uQmxvY2tBbGlnbjsKCQlubGVuID0gKChubGVuIDw8IERTT1VORF9GUkVRU0hJRlQpICsgZmxlbikgLyBkc2ItPmZyZXFBZGp1c3Q7CgkJbmxlbiAqPSBkc2ItPmRldmljZS0+cHdmeC0+bkJsb2NrQWxpZ247CgkJd3JpdGVwb3MgPQoJCQkoKGRzYi0+cHJpbWFyeV9taXhwb3MgPCBubGVuKSA/IGRzYi0+ZGV2aWNlLT5idWZsZW4gOiAwKSArCgkJCWRzYi0+cHJpbWFyeV9taXhwb3MgLSBubGVuOwoJfQoKCWRzYi0+ZnJlcUFjYyAtPSBmbGVuOwoJZHNiLT5idWZfbWl4cG9zID0gbnBvczsKCWRzYi0+cHJpbWFyeV9taXhwb3MgPSB3cml0ZXBvczsKCglUUkFDRSgibmV3IGJ1Zl9taXhwb3M9JWxkLCBwcmltYXJ5X21peHBvcz0lbGQgKGxlbj0lbGQpXG4iLAoJICAgICAgZHNiLT5idWZfbWl4cG9zLCBkc2ItPnByaW1hcnlfbWl4cG9zLCBsZW4pOwoKCWlmIChjYW5jZWwpIERTT1VORF9QaGFzZUNhbmNlbChkc2IsIHdyaXRlcG9zLCBsZW4pOwp9Cgp2b2lkIERTT1VORF9NaXhDYW5jZWxBdChJRGlyZWN0U291bmRCdWZmZXJJbXBsICpkc2IsIERXT1JEIGJ1Zl93cml0ZXBvcykKewojaWYgMAoJRFdPUkQgICBpLCBzaXplLCBmbGVuLCBsZW4sIG5wb3MsIG5sZW47CglJTlQJaUFkdmFuY2UgPSBkc2ItPnB3ZngtPm5CbG9ja0FsaWduOwoJSU5UCW9BZHZhbmNlID0gZHNiLT5kZXZpY2UtPnB3ZngtPm5CbG9ja0FsaWduOwoJLyogZGV0ZXJtaW5lIGFtb3VudCBvZiBwcmVtaXhlZCBkYXRhIHRvIGNhbmNlbCAqLwoJRFdPUkQgYnVmX2RvbmUgPQoJCSgoZHNiLT5idWZfbWl4cG9zIDwgYnVmX3dyaXRlcG9zKSA/IGRzYi0+YnVmbGVuIDogMCkgKwoJCWRzYi0+YnVmX21peHBvcyAtIGJ1Zl93cml0ZXBvczsKI2VuZGlmCgoJV0FSTigiKCVwLCAlbGQpLCBidWZfbWl4cG9zPSVsZFxuIiwgZHNiLCBidWZfd3JpdGVwb3MsIGRzYi0+YnVmX21peHBvcyk7CgkvKiBzaW5jZSB0aGlzIGlzIG5vdCBpbXBsZW1lbnRlZCB5ZXQsIGp1c3QgY2FuY2VsICpBTEwqIHByZWJ1ZmZlcmluZyBmb3Igbm93CgkgKiAod2hpY2ggaXMgZmFzdGVyIGFueXdheSB3aGVuIHRoZXJlJ3Mgb25seSBhIHNpbmdsZSBzZWNvbmRhcnkgYnVmZmVyKSAqLwoJZHNiLT5kZXZpY2UtPm5lZWRfcmVtaXggPSBUUlVFOwp9Cgp2b2lkIERTT1VORF9Gb3JjZVJlbWl4KElEaXJlY3RTb3VuZEJ1ZmZlckltcGwgKmRzYikKewoJVFJBQ0UoIiglcClcbiIsZHNiKTsKCUVudGVyQ3JpdGljYWxTZWN0aW9uKCZkc2ItPmxvY2spOwoJaWYgKGRzYi0+c3RhdGUgPT0gU1RBVEVfUExBWUlORykKCQlkc2ItPmRldmljZS0+bmVlZF9yZW1peCA9IFRSVUU7CglMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZHNiLT5sb2NrKTsKfQoKc3RhdGljIERXT1JEIERTT1VORF9NaXhPbmUoSURpcmVjdFNvdW5kQnVmZmVySW1wbCAqZHNiLCBEV09SRCBwbGF5cG9zLCBEV09SRCB3cml0ZXBvcywgRFdPUkQgbWl4bGVuKQp7CglEV09SRCBsZW4sIHNsZW47CgkvKiBkZXRlcm1pbmUgdGhpcyBidWZmZXIncyB3cml0ZSBwb3NpdGlvbiAqLwoJRFdPUkQgYnVmX3dyaXRlcG9zID0gRFNPVU5EX0NhbGNQbGF5UG9zaXRpb24oZHNiLCB3cml0ZXBvcywgd3JpdGVwb3MpOwoJLyogZGV0ZXJtaW5lIGhvdyBtdWNoIGFscmVhZHktbWl4ZWQgZGF0YSBleGlzdHMgKi8KCURXT1JEIGJ1Zl9kb25lID0KCQkoKGRzYi0+YnVmX21peHBvcyA8IGJ1Zl93cml0ZXBvcykgPyBkc2ItPmJ1ZmxlbiA6IDApICsKCQlkc2ItPmJ1Zl9taXhwb3MgLSBidWZfd3JpdGVwb3M7CglEV09SRCBwcmltYXJ5X2RvbmUgPQoJCSgoZHNiLT5wcmltYXJ5X21peHBvcyA8IHdyaXRlcG9zKSA/IGRzYi0+ZGV2aWNlLT5idWZsZW4gOiAwKSArCgkJZHNiLT5wcmltYXJ5X21peHBvcyAtIHdyaXRlcG9zOwoJRFdPUkQgYWR2X2RvbmUgPQoJCSgoZHNiLT5kZXZpY2UtPm1peHBvcyA8IHdyaXRlcG9zKSA/IGRzYi0+ZGV2aWNlLT5idWZsZW4gOiAwKSArCgkJZHNiLT5kZXZpY2UtPm1peHBvcyAtIHdyaXRlcG9zOwoJRFdPUkQgcGxheWVkID0KCQkoKGJ1Zl93cml0ZXBvcyA8IGRzYi0+cGxheXBvcykgPyBkc2ItPmJ1ZmxlbiA6IDApICsKCQlidWZfd3JpdGVwb3MgLSBkc2ItPnBsYXlwb3M7CglEV09SRCBidWZfbGVmdCA9IGRzYi0+YnVmbGVuIC0gYnVmX3dyaXRlcG9zOwoJaW50IHN0aWxsX2JlaGluZDsKCglUUkFDRSgiKCVwLCVsZCwlbGQsJWxkKVxuIixkc2IscGxheXBvcyx3cml0ZXBvcyxtaXhsZW4pOwoJVFJBQ0UoImJ1Zl93cml0ZXBvcz0lbGQsIHByaW1hcnlfd3JpdGVwb3M9JWxkXG4iLCBidWZfd3JpdGVwb3MsIHdyaXRlcG9zKTsKCVRSQUNFKCJidWZfZG9uZT0lbGQsIHByaW1hcnlfZG9uZT0lbGRcbiIsIGJ1Zl9kb25lLCBwcmltYXJ5X2RvbmUpOwoJVFJBQ0UoImJ1Zl9taXhwb3M9JWxkLCBwcmltYXJ5X21peHBvcz0lbGQsIG1peGxlbj0lbGRcbiIsIGRzYi0+YnVmX21peHBvcywgZHNiLT5wcmltYXJ5X21peHBvcywKCSAgICAgIG1peGxlbik7CglUUkFDRSgibG9vcGluZz0lbGQsIHN0YXJ0cG9zPSVsZCwgbGVhZGluPSVsZFxuIiwgZHNiLT5wbGF5ZmxhZ3MsIGRzYi0+c3RhcnRwb3MsIGRzYi0+bGVhZGluKTsKCgkvKiBjaGVjayBmb3Igbm90aWZpY2F0aW9uIHBvc2l0aW9ucyAqLwoJaWYgKGRzYi0+ZHNiZC5kd0ZsYWdzICYgRFNCQ0FQU19DVFJMUE9TSVRJT05OT1RJRlkgJiYKCSAgICBkc2ItPnN0YXRlICE9IFNUQVRFX1NUQVJUSU5HKSB7CgkJRFNPVU5EX0NoZWNrRXZlbnQoZHNiLCBwbGF5ZWQpOwoJfQoKCS8qIHNhdmUgd3JpdGUgcG9zaXRpb24gZm9yIG5vbi1HRVRDVVJSRU5UUE9TSVRJT04yLi4uICovCglkc2ItPnBsYXlwb3MgPSBidWZfd3JpdGVwb3M7CgoJLyogY2hlY2sgd2hldGhlciBDYWxjUGxheVBvc2l0aW9uIGRldGVjdGVkIGEgbWl4aW5nIHVuZGVycnVuICovCglpZiAoKGJ1Zl9kb25lID09IDApICYmIChkc2ItPnByaW1hcnlfbWl4cG9zICE9IHdyaXRlcG9zKSkgewoJCS8qIGl0IGRpZCwgYnV0IGRpZCB3ZSBoYXZlIG1vcmUgdG8gcGxheT8gKi8KCQlpZiAoKGRzYi0+cGxheWZsYWdzICYgRFNCUExBWV9MT09QSU5HKSB8fAoJCSAgICAoZHNiLT5idWZfbWl4cG9zIDwgZHNiLT5idWZsZW4pKSB7CgkJCS8qIHllcywgaGF2ZSB0byByZWNvdmVyICovCgkJCUVSUigidW5kZXJydW4gb24gc291bmQgYnVmZmVyICVwXG4iLCBkc2IpOwoJCQlUUkFDRSgicmVjb3ZlcmluZyBmcm9tIHVuZGVycnVuOiBwcmltYXJ5X21peHBvcz0lbGRcbiIsIHdyaXRlcG9zKTsKCQl9CgkJZHNiLT5wcmltYXJ5X21peHBvcyA9IHdyaXRlcG9zOwoJCXByaW1hcnlfZG9uZSA9IDA7Cgl9CgkvKiBkZXRlcm1pbmUgaG93IGZhciBhaGVhZCB3ZSBzaG91bGQgbWl4ICovCglpZiAoKChkc2ItPnBsYXlmbGFncyAmIERTQlBMQVlfTE9PUElORykgfHwKCSAgICAgKGRzYi0+bGVhZGluICYmIChkc2ItPnByb2JhYmx5X3ZhbGlkX3RvICE9IDApKSkgJiYKCSAgICAhKGRzYi0+ZHNiZC5kd0ZsYWdzICYgRFNCQ0FQU19TVEFUSUMpKSB7CgkJLyogaWYgdGhpcyBpcyBhIHN0cmVhbWluZyBidWZmZXIsIGl0IHR5cGljYWxseSBtZWFucyB0aGF0CgkJICogd2Ugc2hvdWxkIGRlZmVyIG1peGluZyBwYXN0IHByb2JhYmx5X3ZhbGlkX3RvIGFzIGxvbmcKCQkgKiBhcyB3ZSBjYW4sIHRvIGF2b2lkIHVubmVjZXNzYXJ5IHJlbWl4aW5nICovCgkJLyogdGhlIGhlYXZ5LWxvb2tpbmcgY2FsY3VsYXRpb25zIHNob3VsZG4ndCBiZSB0aGF0IGJhZCwKCQkgKiBhcyBhbnkgZ2FtZSBpc24ndCBsaWtlbHkgdG8gYmUgaGF2ZSBtb3JlIHRoYW4gMSBvciAyCgkJICogc3RyZWFtaW5nIGJ1ZmZlcnMgaW4gdXNlIGF0IGFueSB0aW1lIGFueXdheS4uLiAqLwoJCURXT1JEIHByb2JhYmx5X3ZhbGlkX2xlZnQgPQoJCQkoZHNiLT5wcm9iYWJseV92YWxpZF90byA9PSAoRFdPUkQpLTEpID8gZHNiLT5idWZsZW4gOgoJCQkoKGRzYi0+cHJvYmFibHlfdmFsaWRfdG8gPCBidWZfd3JpdGVwb3MpID8gZHNiLT5idWZsZW4gOiAwKSArCgkJCWRzYi0+cHJvYmFibHlfdmFsaWRfdG8gLSBidWZfd3JpdGVwb3M7CgkJLyogY2hlY2sgZm9yIGxlYWRpbiBjb25kaXRpb24gKi8KCQlpZiAoKHByb2JhYmx5X3ZhbGlkX2xlZnQgPT0gMCkgJiYKCQkgICAgKGRzYi0+cHJvYmFibHlfdmFsaWRfdG8gPT0gZHNiLT5zdGFydHBvcykgJiYKCQkgICAgZHNiLT5sZWFkaW4pCgkJCXByb2JhYmx5X3ZhbGlkX2xlZnQgPSBkc2ItPmJ1ZmxlbjsKCQlUUkFDRSgic3RyZWFtaW5nIGJ1ZmZlciBwcm9iYWJseV92YWxpZF90bz0lbGQsIHByb2JhYmx5X3ZhbGlkX2xlZnQ9JWxkXG4iLAoJCSAgICAgIGRzYi0+cHJvYmFibHlfdmFsaWRfdG8sIHByb2JhYmx5X3ZhbGlkX2xlZnQpOwoJCS8qIGNoZWNrIHdoZXRoZXIgdGhlIGFwcCdzIHRpbWUgaXMgYWxyZWFkeSB1cCAqLwoJCWlmIChwcm9iYWJseV92YWxpZF9sZWZ0IDwgZHNiLT53cml0ZWxlYWQpIHsKCQkJV0FSTigicHJvYmFibHlfdmFsaWRfdG8gbm93IHdpdGhpbiB3cml0ZWxlYWQsIHBvc3NpYmxlIHN0cmVhbWluZyB1bmRlcnJ1blxuIik7CgkJCS8qIG9uY2Ugd2UgcGFzcyB0aGUgcG9pbnQgb2Ygbm8gcmV0dXJuLAoJCQkgKiBubyByZWFzb24gdG8gaG9sZCBiYWNrIGFueW1vcmUgKi8KCQkJZHNiLT5wcm9iYWJseV92YWxpZF90byA9IChEV09SRCktMTsKCQkJLyogd2UganVzdCBoYXZlIHRvIGdvIGFoZWFkIGFuZCBtaXggd2hhdCB3ZSBoYXZlLAoJCQkgKiB0aGVyZSdzIG5vIHRlbGxpbmcgd2hhdCB0aGUgYXBwIGlzIHRoaW5raW5nIGFueXdheSAqLwoJCX0gZWxzZSB7CgkJCS8qIGFkanVzdCBmb3Igb3VyIGZyZXF1ZW5jeSBhbmQgb3VyIHNhbXBsZSBzaXplICovCgkJCXByb2JhYmx5X3ZhbGlkX2xlZnQgPSBNdWxEaXYocHJvYmFibHlfdmFsaWRfbGVmdCwKCQkJCQkJICAgICAxIDw8IERTT1VORF9GUkVRU0hJRlQsCgkJCQkJCSAgICAgZHNiLT5wd2Z4LT5uQmxvY2tBbGlnbiAqIGRzYi0+ZnJlcUFkanVzdCkgKgoJCQkJICAgICAgICAgICAgICBkc2ItPmRldmljZS0+cHdmeC0+bkJsb2NrQWxpZ247CgkJCS8qIGNoZWNrIHdoZXRoZXIgdG8gY2xpcCBtaXhfbGVuICovCgkJCWlmIChwcm9iYWJseV92YWxpZF9sZWZ0IDwgbWl4bGVuKSB7CgkJCQlUUkFDRSgiY2xpcHBpbmcgdG8gcHJvYmFibHlfdmFsaWRfbGVmdD0lbGRcbiIsIHByb2JhYmx5X3ZhbGlkX2xlZnQpOwoJCQkJbWl4bGVuID0gcHJvYmFibHlfdmFsaWRfbGVmdDsKCQkJfQoJCX0KCX0KCS8qIGN1dCBtaXhsZW4gd2l0aCB3aGF0J3MgYWxyZWFkeSBiZWVuIG1peGVkICovCglpZiAobWl4bGVuIDwgcHJpbWFyeV9kb25lKSB7CgkJLyogaHVoPyBhbmQgc3RpbGwgQ2FsY1BsYXlQb3NpdGlvbiBkaWRuJ3QKCQkgKiBkZXRlY3QgYW4gdW5kZXJydW4/ICovCgkJRklYTUUoInByb2JsZW0gd2l0aCB1bmRlcnJ1biBkZXRlY3Rpb24gKG1peGxlbj0lbGQgPCBwcmltYXJ5X2RvbmU9JWxkKVxuIiwgbWl4bGVuLCBwcmltYXJ5X2RvbmUpOwoJCXJldHVybiAwOwoJfQoJbGVuID0gbWl4bGVuIC0gcHJpbWFyeV9kb25lOwoJVFJBQ0UoInJlbWFpbmluZyBtaXhsZW49JWxkXG4iLCBsZW4pOwoKCWlmIChsZW4gPCBkc2ItPmRldmljZS0+ZnJhZ2xlbikgewoJCS8qIHNtYWxsZXIgdGhhbiBhIGZyYWdtZW50LCB3YWl0IHVudGlsIGl0IGdldHMgbGFyZ2VyCgkJICogYmVmb3JlIHdlIHRha2UgdGhlIG1peGluZyBvdmVyaGVhZCAqLwoJCVRSQUNFKCJtaXhsZW4gbm90IHdvcnRoIGl0LCBkZWZlcnJpbmcgbWl4aW5nXG4iKTsKCQlzdGlsbF9iZWhpbmQgPSAxOwoJCWdvdG8gcG9zdF9taXg7Cgl9CgoJLyogb2ssIHdlIGtub3cgaG93IG11Y2ggdG8gbWl4LCBsZXQncyBnbyAqLwoJc3RpbGxfYmVoaW5kID0gKGFkdl9kb25lID4gcHJpbWFyeV9kb25lKTsKCXdoaWxlIChsZW4pIHsKCQlzbGVuID0gZHNiLT5kZXZpY2UtPmJ1ZmxlbiAtIGRzYi0+cHJpbWFyeV9taXhwb3M7CgkJaWYgKHNsZW4gPiBsZW4pIHNsZW4gPSBsZW47CgkJc2xlbiA9IERTT1VORF9NaXhJbkJ1ZmZlcihkc2IsIGRzYi0+cHJpbWFyeV9taXhwb3MsIHNsZW4pOwoKCQlpZiAoKGRzYi0+cHJpbWFyeV9taXhwb3MgPCBkc2ItPmRldmljZS0+bWl4cG9zKSAmJgoJCSAgICAoZHNiLT5wcmltYXJ5X21peHBvcyArIHNsZW4gPj0gZHNiLT5kZXZpY2UtPm1peHBvcykpCgkJCXN0aWxsX2JlaGluZCA9IEZBTFNFOwoKCQlkc2ItPnByaW1hcnlfbWl4cG9zICs9IHNsZW47IGxlbiAtPSBzbGVuOwoJCWRzYi0+cHJpbWFyeV9taXhwb3MgJT0gZHNiLT5kZXZpY2UtPmJ1ZmxlbjsKCgkJaWYgKChkc2ItPnN0YXRlID09IFNUQVRFX1NUT1BQRUQpIHx8ICFzbGVuKSBicmVhazsKCX0KCVRSQUNFKCJuZXcgcHJpbWFyeV9taXhwb3M9JWxkLCBwcmltYXJ5X2FkdmJhc2U9JWxkXG4iLCBkc2ItPnByaW1hcnlfbWl4cG9zLCBkc2ItPmRldmljZS0+bWl4cG9zKTsKCVRSQUNFKCJtaXhlZCBkYXRhIGxlbj0lbGQsIHN0aWxsX2JlaGluZD0lZFxuIiwgbWl4bGVuLWxlbiwgc3RpbGxfYmVoaW5kKTsKCnBvc3RfbWl4OgoJLyogY2hlY2sgaWYgYnVmZmVyIHNob3VsZCBiZSBjb25zaWRlcmVkIGNvbXBsZXRlICovCglpZiAoYnVmX2xlZnQgPCBkc2ItPndyaXRlbGVhZCAmJgoJICAgICEoZHNiLT5wbGF5ZmxhZ3MgJiBEU0JQTEFZX0xPT1BJTkcpKSB7CgkJZHNiLT5zdGF0ZSA9IFNUQVRFX1NUT1BQRUQ7CgkJZHNiLT5wbGF5cG9zID0gMDsKCQlkc2ItPmxhc3RfcGxheXBvcyA9IDA7CgkJZHNiLT5idWZfbWl4cG9zID0gMDsKCQlkc2ItPmxlYWRpbiA9IEZBTFNFOwoJCWRzYi0+bmVlZF9yZW1peCA9IEZBTFNFOwoJCURTT1VORF9DaGVja0V2ZW50KGRzYiwgYnVmX2xlZnQpOwoJfQoKCS8qIHJldHVybiBob3cgZmFyIHdlIHRoaW5rIHRoZSBwcmltYXJ5IGJ1ZmZlciBjYW4KCSAqIGFkdmFuY2UgaXRzIHVuZGVycnVuIGRldGVjdG9yLi4uKi8KCWlmIChzdGlsbF9iZWhpbmQpIHJldHVybiAwOwoJaWYgKChtaXhsZW4gLSBsZW4pIDwgcHJpbWFyeV9kb25lKSByZXR1cm4gMDsKCXNsZW4gPSAoKGRzYi0+cHJpbWFyeV9taXhwb3MgPCBkc2ItPmRldmljZS0+bWl4cG9zKSA/CgkJZHNiLT5kZXZpY2UtPmJ1ZmxlbiA6IDApICsgZHNiLT5wcmltYXJ5X21peHBvcyAtCgkJZHNiLT5kZXZpY2UtPm1peHBvczsKCWlmIChzbGVuID4gbWl4bGVuKSB7CgkJLyogdGhlIHByaW1hcnlfZG9uZSBhbmQgc3RpbGxfYmVoaW5kIGNoZWNrcyBhYm92ZSBzaG91bGQgaGF2ZSB3b3JrZWQgKi8KCQlGSVhNRSgicHJvYmxlbSB3aXRoIGFkdmFuY2VtZW50IGNhbGN1bGF0aW9uIChhZHZsZW49JWxkID4gbWl4bGVuPSVsZClcbiIsIHNsZW4sIG1peGxlbik7CgkJc2xlbiA9IDA7Cgl9CglyZXR1cm4gc2xlbjsKfQoKc3RhdGljIERXT1JEIERTT1VORF9NaXhUb1ByaW1hcnkoRGlyZWN0U291bmREZXZpY2UgKmRldmljZSwgRFdPUkQgcGxheXBvcywgRFdPUkQgd3JpdGVwb3MsIERXT1JEIG1peGxlbiwgQk9PTCByZWNvdmVyKQp7CglJTlQJCQlpLCBsZW4sIG1heGxlbiA9IDA7CglJRGlyZWN0U291bmRCdWZmZXJJbXBsCSpkc2I7CgoJVFJBQ0UoIiglbGQsJWxkLCVsZCwlZClcbiIsIHBsYXlwb3MsIHdyaXRlcG9zLCBtaXhsZW4sIHJlY292ZXIpOwoJZm9yIChpID0gMDsgaSA8IGRldmljZS0+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==