LyoKICogZHJpdmVycy9pMmMvaTJjLWlibV9paWMuYwogKgogKiBTdXBwb3J0IGZvciB0aGUgSUlDIHBlcmlwaGVyYWwgb24gSUJNIFBQQyA0eHgKICoKICogQ29weXJpZ2h0IChjKSAyMDAzLCAyMDA0IFp1bHR5cyBUZWNobm9sb2dpZXMuCiAqIEV1Z2VuZSBTdXJvdmVnaW4gPGV1Z2VuZS5zdXJvdmVnaW5AenVsdHlzLmNvbT4gb3IgPGVic0BlYnNob21lLm5ldD4KICoKICogQmFzZWQgb24gb3JpZ2luYWwgd29yayBieSAKICogCUlhbiBEYVNpbHZhICA8aWRhc2lsdmFAbXZpc3RhLmNvbT4KICogICAgICBBcm1pbiBLdXN0ZXIgPGFrdXN0ZXJAbXZpc3RhLmNvbT4KICogCU1hdHQgUG9ydGVyICA8bXBvcnRlckBtdmlzdGEuY29tPgogKgogKiAgICAgIENvcHlyaWdodCAyMDAwLTIwMDMgTW9udGFWaXN0YSBTb2Z0d2FyZSBJbmMuCiAqCiAqIE9yaWdpbmFsIGRyaXZlciB2ZXJzaW9uIHdhcyBoaWdobHkgbGV2ZXJhZ2VkIGZyb20gaTJjLWVsZWt0b3IuYwogKgogKiAgIAlDb3B5cmlnaHQgMTk5NS05NyBTaW1vbiBHLiBWb2dsCiAqICAgICAgICAgICAgICAgIDE5OTgtOTkgSGFucyBCZXJnbHVuZAogKgogKiAgIAlXaXRoIHNvbWUgY2hhbmdlcyBmcm9tIEt59nN0aSBN5Gxra2kgPGttYWxra2lAY2MuaHV0LmZpPiAKICoJYW5kIGV2ZW4gRnJvZG8gTG9vaWphYXJkIDxmcm9kb2xAZGRzLm5sPgogKgogKiBUaGlzIHByb2dyYW0gaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgIHRoZSB0ZXJtcyBvZiAgdGhlIEdOVSBHZW5lcmFsICBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlCiAqIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgIGVpdGhlciB2ZXJzaW9uIDIgb2YgdGhlICBMaWNlbnNlLCBvciAoYXQgeW91cgogKiBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKi8KCiNpbmNsdWRlIDxsaW51eC9jb25maWcuaD4KI2luY2x1ZGUgPGxpbnV4L21vZHVsZS5oPgojaW5jbHVkZSA8bGludXgva2VybmVsLmg+CiNpbmNsdWRlIDxsaW51eC9pb3BvcnQuaD4KI2luY2x1ZGUgPGxpbnV4L2RlbGF5Lmg+CiNpbmNsdWRlIDxsaW51eC9zbGFiLmg+CiNpbmNsdWRlIDxsaW51eC9pbml0Lmg+CiNpbmNsdWRlIDxsaW51eC9pbnRlcnJ1cHQuaD4KI2luY2x1ZGUgPGFzbS9pcnEuaD4KI2luY2x1ZGUgPGFzbS9pby5oPgojaW5jbHVkZSA8bGludXgvaTJjLmg+CiNpbmNsdWRlIDxsaW51eC9pMmMtaWQuaD4KI2luY2x1ZGUgPGFzbS9vY3AuaD4KI2luY2x1ZGUgPGFzbS9pYm00eHguaD4KCiNpbmNsdWRlICJpMmMtaWJtX2lpYy5oIgoKI2RlZmluZSBEUklWRVJfVkVSU0lPTiAiMi4xIgoKTU9EVUxFX0RFU0NSSVBUSU9OKCJJQk0gSUlDIGRyaXZlciB2IiBEUklWRVJfVkVSU0lPTik7Ck1PRFVMRV9MSUNFTlNFKCJHUEwiKTsKCnN0YXRpYyBpbnQgaWljX2ZvcmNlX3BvbGw7Cm1vZHVsZV9wYXJhbShpaWNfZm9yY2VfcG9sbCwgYm9vbCwgMCk7Ck1PRFVMRV9QQVJNX0RFU0MoaWljX2ZvcmNlX3BvbGwsICJGb3JjZSBwb2xsaW5nIG1vZGUiKTsKCnN0YXRpYyBpbnQgaWljX2ZvcmNlX2Zhc3Q7Cm1vZHVsZV9wYXJhbShpaWNfZm9yY2VfZmFzdCwgYm9vbCwgMCk7Ck1PRFVMRV9QQVJNX0RFU0MoaWljX2Zhc3RfcG9sbCwgIkZvcmNlIGZhc3QgbW9kZSAoNDAwIGtIeikiKTsKCiNkZWZpbmUgREJHX0xFVkVMIDAKCiNpZmRlZiBEQkcKI3VuZGVmIERCRwojZW5kaWYKCiNpZmRlZiBEQkcyCiN1bmRlZiBEQkcyCiNlbmRpZgoKI2lmIERCR19MRVZFTCA+IDAKIyAgZGVmaW5lIERCRyhmLHguLi4pCXByaW50ayhLRVJOX0RFQlVHICJpYm0taWljIiBmLCAjI3gpCiNlbHNlCiMgIGRlZmluZSBEQkcoZix4Li4uKQkoKHZvaWQpMCkKI2VuZGlmCiNpZiBEQkdfTEVWRUwgPiAxCiMgIGRlZmluZSBEQkcyKGYseC4uLikgCURCRyhmLCAjI3gpCiNlbHNlCiMgIGRlZmluZSBEQkcyKGYseC4uLikgCSgodm9pZCkwKQojZW5kaWYKI2lmIERCR19MRVZFTCA+IDIKc3RhdGljIHZvaWQgZHVtcF9paWNfcmVncyhjb25zdCBjaGFyKiBoZWFkZXIsIHN0cnVjdCBpYm1faWljX3ByaXZhdGUqIGRldikKewoJdm9sYXRpbGUgc3RydWN0IGlpY19yZWdzIF9faW9tZW0gKmlpYyA9IGRldi0+dmFkZHI7CglwcmludGsoS0VSTl9ERUJVRyAiaWJtLWlpYyVkOiAlc1xuIiwgZGV2LT5pZHgsIGhlYWRlcik7CglwcmludGsoS0VSTl9ERUJVRyAiICBjbnRsICAgICA9IDB4JTAyeCwgbWRjbnRsID0gMHglMDJ4XG4iCgkgICAgICAgS0VSTl9ERUJVRyAiICBzdHMgICAgICA9IDB4JTAyeCwgZXh0c3RzID0gMHglMDJ4XG4iCgkgICAgICAgS0VSTl9ERUJVRyAiICBjbGtkaXYgICA9IDB4JTAyeCwgeGZyY250ID0gMHglMDJ4XG4iCgkgICAgICAgS0VSTl9ERUJVRyAiICB4dGNudGxzcyA9IDB4JTAyeCwgZGlyZWN0Y250bCA9IDB4JTAyeFxuIiwKCQlpbl84KCZpaWMtPmNudGwpLCBpbl84KCZpaWMtPm1kY250bCksIGluXzgoJmlpYy0+c3RzKSwgCgkJaW5fOCgmaWljLT5leHRzdHMpLCBpbl84KCZpaWMtPmNsa2RpdiksIGluXzgoJmlpYy0+eGZyY250KSwgCgkJaW5fOCgmaWljLT54dGNudGxzcyksIGluXzgoJmlpYy0+ZGlyZWN0Y250bCkpOwp9CiMgIGRlZmluZSBEVU1QX1JFR1MoaCxkZXYpCWR1bXBfaWljX3JlZ3MoKGgpLChkZXYpKQojZWxzZQojICBkZWZpbmUgRFVNUF9SRUdTKGgsZGV2KQkoKHZvaWQpMCkKI2VuZGlmCgovKiBCdXMgdGltaW5ncyAoaW4gbnMpIGZvciBiaXQtYmFuZ2luZyAqLwpzdGF0aWMgc3RydWN0IGkyY190aW1pbmdzIHsKCXVuc2lnbmVkIGludCBoZF9zdGE7Cgl1bnNpZ25lZCBpbnQgc3Vfc3RvOwoJdW5zaWduZWQgaW50IGxvdzsKCXVuc2lnbmVkIGludCBoaWdoOwoJdW5zaWduZWQgaW50IGJ1ZjsKfSB0aW1pbmdzIFtdID0gewovKiBTdGFuZGFyZCBtb2RlICgxMDAgS0h6KSAqLwp7CgkuaGRfc3RhCT0gNDAwMCwKCS5zdV9zdG8JPSA0MDAwLAoJLmxvdwk9IDQ3MDAsCgkuaGlnaAk9IDQwMDAsCgkuYnVmCT0gNDcwMCwKfSwKLyogRmFzdCBtb2RlICg0MDAgS0h6KSAqLwp7CgkuaGRfc3RhID0gNjAwLAoJLnN1X3N0bwk9IDYwMCwKCS5sb3cgCT0gMTMwMCwKCS5oaWdoIAk9IDYwMCwKCS5idWYJPSAxMzAwLAp9fTsKCi8qIEVuYWJsZS9kaXNhYmxlIGludGVycnVwdCBnZW5lcmF0aW9uICovCnN0YXRpYyBpbmxpbmUgdm9pZCBpaWNfaW50ZXJydXB0X21vZGUoc3RydWN0IGlibV9paWNfcHJpdmF0ZSogZGV2LCBpbnQgZW5hYmxlKQp7CglvdXRfOCgmZGV2LT52YWRkci0+aW50bXNrLCBlbmFibGUgPyBJTlRSTVNLX0VJTVRDIDogMCk7Cn0KIAovKgogKiBJbml0aWFsaXplIElJQyBpbnRlcmZhY2UuCiAqLwpzdGF0aWMgdm9pZCBpaWNfZGV2X2luaXQoc3RydWN0IGlibV9paWNfcHJpdmF0ZSogZGV2KQp7Cgl2b2xhdGlsZSBzdHJ1Y3QgaWljX3JlZ3MgX19pb21lbSAqaWljID0gZGV2LT52YWRkcjsKCglEQkcoIiVkOiBpbml0XG4iLCBkZXYtPmlkeCk7CgkKCS8qIENsZWFyIG1hc3RlciBhZGRyZXNzICovCglvdXRfOCgmaWljLT5sbWFkciwgMCk7CglvdXRfOCgmaWljLT5obWFkciwgMCk7CgoJLyogQ2xlYXIgc2xhdmUgYWRkcmVzcyAqLwoJb3V0XzgoJmlpYy0+bHNhZHIsIDApOwoJb3V0XzgoJmlpYy0+aHNhZHIsIDApOwoKCS8qIENsZWFyIHN0YXR1cyAmIGV4dGVuZGVkIHN0YXR1cyAqLwoJb3V0XzgoJmlpYy0+c3RzLCBTVFNfU0NNUCB8IFNUU19JUlFBKTsKCW91dF84KCZpaWMtPmV4dHN0cywgRVhUU1RTX0lSUVAgfCBFWFRTVFNfSVJRRCB8IEVYVFNUU19MQQoJCQkgICAgfCBFWFRTVFNfSUNUIHwgRVhUU1RTX1hGUkEpOwoKCS8qIFNldCBjbG9jayBkaXZpZGVyICovCglvdXRfOCgmaWljLT5jbGtkaXYsIGRldi0+Y2xja2Rpdik7CgoJLyogQ2xlYXIgdHJhbnNmZXIgY291bnQgKi8KCW91dF84KCZpaWMtPnhmcmNudCwgMCk7CgoJLyogQ2xlYXIgZXh0ZW5kZWQgY29udHJvbCBhbmQgc3RhdHVzICovCglvdXRfOCgmaWljLT54dGNudGxzcywgWFRDTlRMU1NfU1JDIHwgWFRDTlRMU1NfU1JTIHwgWFRDTlRMU1NfU1dDCgkJCSAgICB8IFhUQ05UTFNTX1NXUyk7CgoJLyogQ2xlYXIgY29udHJvbCByZWdpc3RlciAqLwoJb3V0XzgoJmlpYy0+Y250bCwgMCk7CgkKCS8qIEVuYWJsZSBpbnRlcnJ1cHRzIGlmIHBvc3NpYmxlICovCglpaWNfaW50ZXJydXB0X21vZGUoZGV2LCBkZXYtPmlycSA+PSAwKTsKCgkvKiBTZXQgbW9kZSBjb250cm9sICovCglvdXRfOCgmaWljLT5tZGNudGwsIE1EQ05UTF9GTURCIHwgTURDTlRMX0VJTlQgfCBNRENOVExfRVVCUwoJCQkgICAgfCAoZGV2LT5mYXN0X21vZGUgPyBNRENOVExfRlNNIDogMCkpOwoKCURVTVBfUkVHUygiaWljX2luaXQiLCBkZXYpOwp9CgovKiAKICogUmVzZXQgSUlDIGludGVyZmFjZQogKi8Kc3RhdGljIHZvaWQgaWljX2Rldl9yZXNldChzdHJ1Y3QgaWJtX2lpY19wcml2YXRlKiBkZXYpCnsKCXZvbGF0aWxlIHN0cnVjdCBpaWNfcmVncyBfX2lvbWVtICppaWMgPSBkZXYtPnZhZGRyOwoJaW50IGk7Cgl1OCBkYzsKCQoJREJHKCIlZDogc29mdCByZXNldFxuIiwgZGV2LT5pZHgpOwoJRFVNUF9SRUdTKCJyZXNldCIsIGRldik7CgkKICAgIAkvKiBQbGFjZSBjaGlwIGluIHRoZSByZXNldCBzdGF0ZSAqLwoJb3V0XzgoJmlpYy0+eHRjbnRsc3MsIFhUQ05UTFNTX1NSU1QpOwoJCgkvKiBDaGVjayBpZiBidXMgaXMgZnJlZSAqLwoJZGMgPSBpbl84KCZpaWMtPmRpcmVjdGNudGwpOwkKCWlmICghRElSQ1ROTF9GUkVFKGRjKSl7CgkJREJHKCIlZDogdHJ5aW5nIHRvIHJlZ2FpbiBidXMgY29udHJvbFxuIiwgZGV2LT5pZHgpOwoJCgkJLyogVHJ5IHRvIHNldCBidXMgZnJlZSBzdGF0ZSAqLwoJCW91dF84KCZpaWMtPmRpcmVjdGNudGwsIERJUkNOVExfU0RBQyB8IERJUkNOVExfU0NDKTsJCgkKCQkvKiBXYWl0IHVudGlsIHdlIHJlZ2FpbiBidXMgY29udHJvbCAqLwoJCWZvciAoaSA9IDA7IGkgPCAxMDA7ICsraSl7CgkJCWRjID0gaW5fOCgmaWljLT5kaXJlY3RjbnRsKTsKCQkJaWYgKERJUkNUTkxfRlJFRShkYykpCgkJCQlicmVhazsKCQkJCgkJCS8qIFRvZ2dsZSBTQ0wgbGluZSAqLwoJCQlkYyBePSBESVJDTlRMX1NDQzsKCQkJb3V0XzgoJmlpYy0+ZGlyZWN0Y250bCwgZGMpOwoJCQl1ZGVsYXkoMTApOwoJCQlkYyBePSBESVJDTlRMX1NDQzsKCQkJb3V0XzgoJmlpYy0+ZGlyZWN0Y250bCwgZGMpOwoJCQkKCQkJLyogYmUgbmljZSAqLwoJCQljb25kX3Jlc2NoZWQoKTsKCQl9Cgl9CgkKCS8qIFJlbW92ZSByZXNldCAqLwoJb3V0XzgoJmlpYy0+eHRjbnRsc3MsIDApOwoJCgkvKiBSZWluaXRpYWxpemUgaW50ZXJmYWNlICovCglpaWNfZGV2X2luaXQoZGV2KTsKfQoKLyoKICogRG8gMC1sZW5ndGggdHJhbnNhY3Rpb24gdXNpbmcgYml0LWJhbmdpbmcgdGhyb3VnaCBJSUNfRElSRUNUQ05UTCByZWdpc3Rlci4KICovCgovKiBXYWl0IGZvciBTQ0wgYW5kL29yIFNEQSB0byBiZSBoaWdoICovCnN0YXRpYyBpbnQgaWljX2RjX3dhaXQodm9sYXRpbGUgc3RydWN0IGlpY19yZWdzIF9faW9tZW0gKmlpYywgdTggbWFzaykKewoJdW5zaWduZWQgbG9uZyB4ID0gamlmZmllcyArIEhaIC8gMjggKyAyOwoJd2hpbGUgKChpbl84KCZpaWMtPmRpcmVjdGNudGwpICYgbWFzaykgIT0gbWFzayl7CgkJaWYgKHVubGlrZWx5KHRpbWVfYWZ0ZXIoamlmZmllcywgeCkpKQoJCQlyZXR1cm4gLTE7CgkJY29uZF9yZXNjaGVkKCk7Cgl9CglyZXR1cm4gMDsKfQoKc3RhdGljIGludCBpaWNfc21idXNfcXVpY2soc3RydWN0IGlibV9paWNfcHJpdmF0ZSogZGV2LCBjb25zdCBzdHJ1Y3QgaTJjX21zZyogcCkKewoJdm9sYXRpbGUgc3RydWN0IGlpY19yZWdzIF9faW9tZW0gKmlpYyA9IGRldi0+dmFkZHI7Cgljb25zdCBzdHJ1Y3QgaTJjX3RpbWluZ3MqIHQgPSAmdGltaW5nc1tkZXYtPmZhc3RfbW9kZSA/IDEgOiAwXTsKCXU4IG1hc2ssIHYsIHNkYTsKCWludCBpLCByZXM7CgoJLyogT25seSA3LWJpdCBhZGRyZXNzZXMgYXJlIHN1cHBvcnRlZCAqLwoJaWYgKHVubGlrZWx5KHAtPmZsYWdzICYgSTJDX01fVEVOKSl7CgkJREJHKCIlZDogc21idXNfcXVpY2sgLSAxMCBiaXQgYWRkcmVzc2VzIGFyZSBub3Qgc3VwcG9ydGVkXG4iLAoJCQlkZXYtPmlkeCk7CgkJcmV0dXJuIC1FSU5WQUw7Cgl9CgoJREJHKCIlZDogc21idXNfcXVpY2soMHglMDJ4KVxuIiwgZGV2LT5pZHgsIHAtPmFkZHIpOwoKCS8qIFJlc2V0IElJQyBpbnRlcmZhY2UgKi8KCW91dF84KCZpaWMtPnh0Y250bHNzLCBYVENOVExTU19TUlNUKTsKCgkvKiBXYWl0IGZvciBidXMgdG8gYmVjb21lIGZyZWUgKi8KCW91dF84KCZpaWMtPmRpcmVjdGNudGwsIERJUkNOVExfU0RBQyB8IERJUkNOVExfU0NDKTsKCWlmICh1bmxpa2VseShpaWNfZGNfd2FpdChpaWMsIERJUkNOVExfTVNEQSB8IERJUkNOVExfTVNDKSkpCgkJZ290byBlcnI7CgluZGVsYXkodC0+YnVmKTsKCgkvKiBTVEFSVCAqLwoJb3V0XzgoJmlpYy0+ZGlyZWN0Y250bCwgRElSQ05UTF9TQ0MpOwoJc2RhID0gMDsKCW5kZWxheSh0LT5oZF9zdGEpOwoKCS8qIFNlbmQgYWRkcmVzcyAqLwoJdiA9ICh1OCkoKHAtPmFkZHIgPDwgMSkgfCAoKHAtPmZsYWdzICYgSTJDX01fUkQpID8gMSA6IDApKTsKCWZvciAoaSA9IDAsIG1hc2sgPSAweDgwOyBpIDwgODsgKytpLCBtYXNrID4+PSAxKXsKCQlvdXRfOCgmaWljLT5kaXJlY3RjbnRsLCBzZGEpOwoJCW5kZWxheSh0LT5sb3cgLyAyKTsKCQlzZGEgPSAodiAmIG1hc2spID8gRElSQ05UTF9TREFDIDogMDsKCQlvdXRfOCgmaWljLT5kaXJlY3RjbnRsLCBzZGEpOwoJCW5kZWxheSh0LT5sb3cgLyAyKTsKCgkJb3V0XzgoJmlpYy0+ZGlyZWN0Y250bCwgRElSQ05UTF9TQ0MgfCBzZGEpOwoJCWlmICh1bmxpa2VseShpaWNfZGNfd2FpdChpaWMsIERJUkNOVExfTVNDKSkpCgkJCWdvdG8gZXJyOwoJCW5kZWxheSh0LT5oaWdoKTsKCX0KCgkvKiBBQ0sgKi8KCW91dF84KCZpaWMtPmRpcmVjdGNudGwsIHNkYSk7CgluZGVsYXkodC0+bG93IC8gMik7CglvdXRfOCgmaWljLT5kaXJlY3RjbnRsLCBESVJDTlRMX1NEQUMpOwoJbmRlbGF5KHQtPmxvdyAvIDIpOwoJb3V0XzgoJmlpYy0+ZGlyZWN0Y250bCwgRElSQ05UTF9TREFDIHwgRElSQ05UTF9TQ0MpOwoJaWYgKHVubGlrZWx5KGlpY19kY193YWl0KGlpYywgRElSQ05UTF9NU0MpKSkKCQlnb3RvIGVycjsKCXJlcyA9IChpbl84KCZpaWMtPmRpcmVjdGNudGwpICYgRElSQ05UTF9NU0RBKSA/IC1FUkVNT1RFSU8gOiAxOwoJbmRlbGF5KHQtPmhpZ2gpOwoKCS8qIFNUT1AgKi8KCW91dF84KCZpaWMtPmRpcmVjdGNudGwsIDApOwoJbmRlbGF5KHQtPmxvdyk7CglvdXRfOCgmaWljLT5kaXJlY3RjbnRsLCBESVJDTlRMX1NDQyk7CglpZiAodW5saWtlbHkoaWljX2RjX3dhaXQoaWljLCBESVJDTlRMX01TQykpKQoJCWdvdG8gZXJyOwoJbmRlbGF5KHQtPnN1X3N0byk7CglvdXRfOCgmaWljLT5kaXJlY3RjbnRsLCBESVJDTlRMX1NEQUMgfCBESVJDTlRMX1NDQyk7CgoJbmRlbGF5KHQtPmJ1Zik7CgoJREJHKCIlZDogc21idXNfcXVpY2sgLT4gJXNcbiIsIGRldi0+aWR4LCByZXMgPyAiTkFDSyIgOiAiQUNLIik7Cm91dDoKCS8qIFJlbW92ZSByZXNldCAqLwoJb3V0XzgoJmlpYy0+eHRjbnRsc3MsIDApOwoKCS8qIFJlaW5pdGlhbGl6ZSBpbnRlcmZhY2UgKi8KCWlpY19kZXZfaW5pdChkZXYpOwoKCXJldHVybiByZXM7CmVycjoKCURCRygiJWQ6IHNtYnVzX3F1aWNrIC0gYnVzIGlzIHN0dWNrXG4iLCBkZXYtPmlkeCk7CglyZXMgPSAtRVJFTU9URUlPOwoJZ290byBvdXQ7Cn0KCi8qCiAqIElJQyBpbnRlcnJ1cHQgaGFuZGxlcgogKi8Kc3RhdGljIGlycXJldHVybl90IGlpY19oYW5kbGVyKGludCBpcnEsIHZvaWQgKmRldl9pZCwgc3RydWN0IHB0X3JlZ3MgKnJlZ3MpCnsKCXN0cnVjdCBpYm1faWljX3ByaXZhdGUqIGRldiA9IChzdHJ1Y3QgaWJtX2lpY19wcml2YXRlKilkZXZfaWQ7Cgl2b2xhdGlsZSBzdHJ1Y3QgaWljX3JlZ3MgX19pb21lbSAqaWljID0gZGV2LT52YWRkcjsKCQoJREJHMigiJWQ6IGlycSBoYW5kbGVyLCBTVFMgPSAweCUwMngsIEVYVFNUUyA9IDB4JTAyeFxuIiwgCgkgICAgIGRldi0+aWR4LCBpbl84KCZpaWMtPnN0cyksIGluXzgoJmlpYy0+ZXh0c3RzKSk7CgkKCS8qIEFja25vd2xlZGdlIElSUSBhbmQgd2FrZXVwIGlpY193YWl0X2Zvcl90YyAqLwoJb3V0XzgoJmlpYy0+c3RzLCBTVFNfSVJRQSB8IFNUU19TQ01QKTsKCXdha2VfdXBfaW50ZXJydXB0aWJsZSgmZGV2LT53cSk7CgkKCXJldHVybiBJUlFfSEFORExFRDsKfQoKLyoKICogR2V0IG1hc3RlciB0cmFuc2ZlciByZXN1bHQgYW5kIGNsZWFyIGVycm9ycyBpZiBhbnkuCiAqIFJldHVybnMgdGhlIG51bWJlciBvZiBhY3R1YWxseSB0cmFuc2ZlcnJlZCBieXRlcyBvciBlcnJvciAoPDApCiAqLwpzdGF0aWMgaW50IGlpY194ZmVyX3Jlc3VsdChzdHJ1Y3QgaWJtX2lpY19wcml2YXRlKiBkZXYpCnsKCXZvbGF0aWxlIHN0cnVjdCBpaWNfcmVncyBfX2lvbWVtICppaWMgPSBkZXYtPnZhZGRyOwkKCQoJaWYgKHVubGlrZWx5KGluXzgoJmlpYy0+c3RzKSAmIFNUU19FUlIpKXsKCQlEQkcoIiVkOiB4ZmVyIGVycm9yLCBFWFRTVFMgPSAweCUwMnhcbiIsIGRldi0+aWR4LCAKCQkJaW5fOCgmaWljLT5leHRzdHMpKTsKCQkJCQoJCS8qIENsZWFyIGVycm9ycyBhbmQgcG9zc2libGUgcGVuZGluZyBJUlFzICovCgkJb3V0XzgoJmlpYy0+ZXh0c3RzLCBFWFRTVFNfSVJRUCB8IEVYVFNUU19JUlFEIHwgCgkJCUVYVFNUU19MQSB8IEVYVFNUU19JQ1QgfCBFWFRTVFNfWEZSQSk7CgkJCQoJCS8qIEZsdXNoIG1hc3RlciBkYXRhIGJ1ZmZlciAqLwoJCW91dF84KCZpaWMtPm1kY250bCwgaW5fOCgmaWljLT5tZGNudGwpIHwgTURDTlRMX0ZNREIpOwoJCQoJCS8qIElzIGJ1cyBmcmVlPwoJCSAqIElmIGVycm9yIGhhcHBlbmVkIGR1cmluZyBjb21iaW5lZCB4ZmVyCgkJICogSUlDIGludGVyZmFjZSBpcyB1c3VhbGx5IHN0dWNrIGluIHNvbWUgc3RyYW5nZQoJCSAqIHN0YXRlLCB0aGUgb25seSB3YXkgb3V0IC0gc29mdCByZXNldC4KCQkgKi8KCQlpZiAoKGluXzgoJmlpYy0+ZXh0c3RzKSAmIEVYVFNUU19CQ1NfTUFTSykgIT0gRVhUU1RTX0JDU19GUkVFKXsKCQkJREJHKCIlZDogYnVzIGlzIHN0dWNrLCByZXNldHRpbmdcbiIsIGRldi0+aWR4KTsKCQkJaWljX2Rldl9yZXNldChkZXYpOwoJCX0KCQlyZXR1cm4gLUVSRU1PVEVJTzsKCX0KCWVsc2UKCQlyZXR1cm4gaW5fOCgmaWljLT54ZnJjbnQpICYgWEZSQ05UX01UQ19NQVNLOwp9CgovKgogKiBUcnkgdG8gYWJvcnQgYWN0aXZlIHRyYW5zZmVyLgogKi8Kc3RhdGljIHZvaWQgaWljX2Fib3J0X3hmZXIoc3RydWN0IGlibV9paWNfcHJpdmF0ZSogZGV2KQp7Cgl2b2xhdGlsZSBzdHJ1Y3QgaWljX3JlZ3MgX19pb21lbSAqaWljID0gZGV2LT52YWRkcjsKCXVuc2lnbmVkIGxvbmcgeDsKCQoJREJHKCIlZDogaWljX2Fib3J0X3hmZXJcbiIsIGRldi0+aWR4KTsKCQoJb3V0XzgoJmlpYy0+Y250bCwgQ05UTF9ITVQpOwoJCgkvKgoJICogV2FpdCBmb3IgdGhlIGFib3J0IGNvbW1hbmQgdG8gY29tcGxldGUuCgkgKiBJdCdzIG5vdCB3b3J0aCB0byBiZSBvcHRpbWl6ZWQsIGp1c3QgcG9sbCAodGltZW91dCA+PSAxIHRpY2spCgkgKi8KCXggPSBqaWZmaWVzICsgMjsKCXdoaWxlICgoaW5fOCgmaWljLT5leHRzdHMpICYgRVhUU1RTX0JDU19NQVNLKSAhPSBFWFRTVFNfQkNTX0ZSRUUpewoJCWlmICh0aW1lX2FmdGVyKGppZmZpZXMsIHgpKXsKCQkJREJHKCIlZDogYWJvcnQgdGltZW91dCwgcmVzZXR0aW5nLi4uXG4iLCBkZXYtPmlkeCk7CgkJCWlpY19kZXZfcmVzZXQoZGV2KTsKCQkJcmV0dXJuOwoJCX0KCQlzY2hlZHVsZSgpOwoJfQoKCS8qIEp1c3QgdG8gY2xlYXIgZXJyb3JzICovCglpaWNfeGZlcl9yZXN1bHQoZGV2KTsKfQoKLyoKICogV2FpdCBmb3IgbWFzdGVyIHRyYW5zZmVyIHRvIGNvbXBsZXRlLgogKiBJdCBwdXRzIGN1cnJlbnQgcHJvY2VzcyB0byBzbGVlcCB1bnRpbCB3ZSBnZXQgaW50ZXJydXB0IG9yIHRpbWVvdXQgZXhwaXJlcy4KICogUmV0dXJucyB0aGUgbnVtYmVyIG9mIHRyYW5zZmVycmVkIGJ5dGVzIG9yIGVycm9yICg8MCkKICovCnN0YXRpYyBpbnQgaWljX3dhaXRfZm9yX3RjKHN0cnVjdCBpYm1faWljX3ByaXZhdGUqIGRldil7CgkKCXZvbGF0aWxlIHN0cnVjdCBpaWNfcmVncyBfX2lvbWVtICppaWMgPSBkZXYtPnZhZGRyOwoJaW50IHJldCA9IDA7CgkKCWlmIChkZXYtPmlycSA+PSAwKXsKCQkvKiBJbnRlcnJ1cHQgbW9kZSAqLwoJCXJldCA9IHdhaXRfZXZlbnRfaW50ZXJydXB0aWJsZV90aW1lb3V0KGRldi0+d3EsIAoJCQkhKGluXzgoJmlpYy0+c3RzKSAmIFNUU19QVCksIGRldi0+YWRhcC50aW1lb3V0ICogSFopOwoKCQlpZiAodW5saWtlbHkocmV0IDwgMCkpCgkJCURCRygiJWQ6IHdhaXQgaW50ZXJydXB0ZWRcbiIsIGRldi0+aWR4KTsKCQllbHNlIGlmICh1bmxpa2VseShpbl84KCZpaWMtPnN0cykgJiBTVFNfUFQpKXsKCQkJREJHKCIlZDogd2FpdCB0aW1lb3V0XG4iLCBkZXYtPmlkeCk7CgkJCXJldCA9IC1FVElNRURPVVQ7CgkJfQoJfQoJZWxzZSB7CgkJLyogUG9sbGluZyBtb2RlICovCgkJdW5zaWduZWQgbG9uZyB4ID0gamlmZmllcyArIGRldi0+YWRhcC50aW1lb3V0ICogSFo7CgkJCgkJd2hpbGUgKGluXzgoJmlpYy0+c3RzKSAmIFNUU19QVCl7CgkJCWlmICh1bmxpa2VseSh0aW1lX2FmdGVyKGppZmZpZXMsIHgpKSl7CgkJCQlEQkcoIiVkOiBwb2xsIHRpbWVvdXRcbiIsIGRldi0+aWR4KTsKCQkJCXJldCA9IC1FVElNRURPVVQ7CgkJCQlicmVhazsKCQkJfQoJCQoJCQlpZiAodW5saWtlbHkoc2lnbmFsX3BlbmRpbmcoY3VycmVudCkpKXsKCQkJCURCRygiJWQ6IHBvbGwgaW50ZXJydXB0ZWRcbiIsIGRldi0+aWR4KTsKCQkJCXJldCA9IC1FUkVTVEFSVFNZUzsKCQkJCWJyZWFrOwoJCQl9CgkJCXNjaGVkdWxlKCk7CgkJfQkKCX0KCQoJaWYgKHVubGlrZWx5KHJldCA8IDApKQoJCWlpY19hYm9ydF94ZmVyKGRldik7CgllbHNlCgkJcmV0ID0gaWljX3hmZXJfcmVzdWx0KGRldik7CgkKCURCRzIoIiVkOiBpaWNfd2FpdF9mb3JfdGMgLT4gJWRcbiIsIGRldi0+aWR4LCByZXQpOwoJCglyZXR1cm4gcmV0Owp9CgovKgogKiBMb3cgbGV2ZWwgbWFzdGVyIHRyYW5zZmVyIHJvdXRpbmUKICovCnN0YXRpYyBpbnQgaWljX3hmZXJfYnl0ZXMoc3RydWN0IGlibV9paWNfcHJpdmF0ZSogZGV2LCBzdHJ1Y3QgaTJjX21zZyogcG0sIAoJCQkgIGludCBjb21iaW5lZF94ZmVyKQp7Cgl2b2xhdGlsZSBzdHJ1Y3QgaWljX3JlZ3MgX19pb21lbSAqaWljID0gZGV2LT52YWRkcjsKCWNoYXIqIGJ1ZiA9IHBtLT5idWY7CglpbnQgaSwgaiwgbG9vcHMsIHJldCA9IDA7CglpbnQgbGVuID0gcG0tPmxlbjsKCgl1OCBjbnRsID0gKGluXzgoJmlpYy0+Y250bCkgJiBDTlRMX0FNRCkgfCBDTlRMX1BUOwoJaWYgKHBtLT5mbGFncyAmIEkyQ19NX1JEKQoJCWNudGwgfD0gQ05UTF9SVzsKCQoJbG9vcHMgPSAobGVuICsgMykgLyA0OwoJZm9yIChpID0gMDsgaSA8IGxvb3BzOyArK2ksIGxlbiAtPSA0KXsKCQlpbnQgY291bnQgPSBsZW4gPiA0ID8gNCA6IGxlbjsKCQl1OCBjbWQgPSBjbnRsIHwgKChjb3VudCAtIDEpIDw8IENOVExfVENUX1NISUZUKTsKCQkKCQlpZiAoIShjbnRsICYgQ05UTF9SVykpCgkJCWZvciAoaiA9IDA7IGogPCBjb3VudDsgKytqKQoJCQkJb3V0XzgoKHZvaWQgX19pb21lbSAqKSZpaWMtPm1kYnVmLCAqYnVmKyspOwoJCQoJCWlmIChpIDwgbG9vcHMgLSAxKQoJCQljbWQgfD0gQ05UTF9DSFQ7CgkJZWxzZSBpZiAoY29tYmluZWRfeGZlcikKCQkJY21kIHw9IENOVExfUlBTVDsKCQkKCQlEQkcyKCIlZDogeGZlcl9ieXRlcywgJWQsIENOVEwgPSAweCUwMnhcbiIsIGRldi0+aWR4LCBjb3VudCwgY21kKTsKCQkKCQkvKiBTdGFydCB0cmFuc2ZlciAqLwoJCW91dF84KCZpaWMtPmNudGwsIGNtZCk7CgkJCgkJLyogV2FpdCBmb3IgY29tcGxldGlvbiAqLwoJCXJldCA9IGlpY193YWl0X2Zvcl90YyhkZXYpOwoKCQlpZiAodW5saWtlbHkocmV0IDwgMCkpCgkJCWJyZWFrOwoJCWVsc2UgaWYgKHVubGlrZWx5KHJldCAhPSBjb3VudCkpewoJCQlEQkcoIiVkOiB4ZmVyX2J5dGVzLCByZXF1ZXN0ZWQgJWQsIHRyYW5zZmVyZWQgJWRcbiIsIAoJCQkJZGV2LT5pZHgsIGNvdW50LCByZXQpOwoJCQkKCQkJLyogSWYgaXQncyBub3QgYSBsYXN0IHBhcnQgb2YgeGZlciwgYWJvcnQgaXQgKi8KCQkJaWYgKGNvbWJpbmVkX3hmZXIgfHwgKGkgPCBsb29wcyAtIDEpKQogICAgCQkJCWlpY19hYm9ydF94ZmVyKGRldik7CgkJCQkKCQkJcmV0ID0gLUVSRU1PVEVJTzsKCQkJYnJlYWs7CQkJCQoJCX0KCQkKCQlpZiAoY250bCAmIENOVExfUlcpCgkJCWZvciAoaiA9IDA7IGogPCBjb3VudDsgKytqKQoJCQkJKmJ1ZisrID0gaW5fOCgodm9pZCBfX2lvbWVtICopJmlpYy0+bWRidWYpOwoJfQoJCglyZXR1cm4gcmV0ID4gMCA/IDAgOiByZXQ7Cn0KCi8qCiAqIFNldCB0YXJnZXQgc2xhdmUgYWRkcmVzcyBmb3IgbWFzdGVyIHRyYW5zZmVyCiAqLwpzdGF0aWMgaW5saW5lIHZvaWQgaWljX2FkZHJlc3Moc3RydWN0IGlibV9paWNfcHJpdmF0ZSogZGV2LCBzdHJ1Y3QgaTJjX21zZyogbXNnKQp7Cgl2b2xhdGlsZSBzdHJ1Y3QgaWljX3JlZ3MgX19pb21lbSAqaWljID0gZGV2LT52YWRkcjsKCXUxNiBhZGRyID0gbXNnLT5hZGRyOwoJCglEQkcyKCIlZDogaWljX2FkZHJlc3MsIDB4JTAzeCAoJWQtYml0KVxuIiwgZGV2LT5pZHgsIAoJCWFkZHIsIG1zZy0+ZmxhZ3MgJiBJMkNfTV9URU4gPyAxMCA6IDcpOwoJCglpZiAobXNnLT5mbGFncyAmIEkyQ19NX1RFTil7CgkgICAgb3V0XzgoJmlpYy0+Y250bCwgQ05UTF9BTUQpOwoJICAgIG91dF84KCZpaWMtPmxtYWRyLCBhZGRyKTsKCSAgICBvdXRfOCgmaWljLT5obWFkciwgMHhmMCB8ICgoYWRkciA+PiA3KSAmIDB4MDYpKTsKCX0KCWVsc2UgewoJICAgIG91dF84KCZpaWMtPmNudGwsIDApOwoJICAgIG91dF84KCZpaWMtPmxtYWRyLCBhZGRyIDw8IDEpOwoJfQp9CgpzdGF0aWMgaW5saW5lIGludCBpaWNfaW52YWxpZF9hZGRyZXNzKGNvbnN0IHN0cnVjdCBpMmNfbXNnKiBwKQp7CglyZXR1cm4gKHAtPmFkZHIgPiAweDNmZikgfHwgKCEocC0+ZmxhZ3MgJiBJMkNfTV9URU4pICYmIChwLT5hZGRyID4gMHg3ZikpOwp9CgpzdGF0aWMgaW5saW5lIGludCBpaWNfYWRkcmVzc19uZXEoY29uc3Qgc3RydWN0IGkyY19tc2cqIHAxLCAKCQkJCSAgY29uc3Qgc3RydWN0IGkyY19tc2cqIHAyKQp7CglyZXR1cm4gKHAxLT5hZGRyICE9IHAyLT5hZGRyKSAKCQl8fCAoKHAxLT5mbGFncyAmIEkyQ19NX1RFTikgIT0gKHAyLT5mbGFncyAmIEkyQ19NX1RFTikpOwp9IAoKLyoKICogR2VuZXJpYyBtYXN0ZXIgdHJhbnNmZXIgZW50cnlwb2ludC4gCiAqIFJldHVybnMgdGhlIG51bWJlciBvZiBwcm9jZXNzZWQgbWVzc2FnZXMgb3IgZXJyb3IgKDwwKQogKi8Kc3RhdGljIGludCBpaWNfeGZlcihzdHJ1Y3QgaTJjX2FkYXB0ZXIgKmFkYXAsIHN0cnVjdCBpMmNfbXNnICptc2dzLCBpbnQgbnVtKQp7CiAgICAJc3RydWN0IGlibV9paWNfcHJpdmF0ZSogZGV2ID0gKHN0cnVjdCBpYm1faWljX3ByaXZhdGUqKShpMmNfZ2V0X2FkYXBkYXRhKGFkYXApKTsKCXZvbGF0aWxlIHN0cnVjdCBpaWNfcmVncyBfX2lvbWVtICppaWMgPSBkZXYtPnZhZGRyOwoJaW50IGksIHJldCA9IDA7CgkKCURCRzIoIiVkOiBpaWNfeGZlciwgJWQgbXNnKHMpXG4iLCBkZXYtPmlkeCwgbnVtKTsKCQoJaWYgKCFudW0pCgkJcmV0dXJuIDA7CgkKCS8qIENoZWNrIHRoZSBzYW5pdHkgb2YgdGhlIHBhc3NlZCBtZXNzYWdlcy4KCSAqIFVoaCwgZ2VuZXJpYyBpMmMgbGF5ZXIgaXMgbW9yZSBzdWl0YWJsZSBwbGFjZSBmb3Igc3VjaCBjb2RlLi4uCgkgKi8KCWlmICh1bmxpa2VseShpaWNfaW52YWxpZF9hZGRyZXNzKCZtc2dzWzBdKSkpewoJCURCRygiJWQ6IGludmFsaWQgYWRkcmVzcyAweCUwM3ggKCVkLWJpdClcbiIsIGRldi0+aWR4LCAKCQkJbXNnc1swXS5hZGRyLCBtc2dzWzBdLmZsYWdzICYgSTJDX01fVEVOID8gMTAgOiA3KTsKCQlyZXR1cm4gLUVJTlZBTDsKCX0JCQoJZm9yIChpID0gMDsgaSA8IG51bTsgKytpKXsKCQlpZiAodW5saWtlbHkobXNnc1tpXS5sZW4gPD0gMCkpewoJCQlpZiAobnVtID09IDEgJiYgIW1zZ3NbMF0ubGVuKXsKCQkJCS8qIFNwZWNpYWwgY2FzZSBmb3IgSTJDX1NNQlVTX1FVSUNLIGVtdWxhdGlvbi4KCQkJCSAqIElCTSBJSUMgZG9lc24ndCBzdXBwb3J0IDAtbGVuZ3RoIHRyYW5zYWN0aW9ucwoJCQkJICogc28gd2UgaGF2ZSB0byBlbXVsYXRlIHRoZW0gdXNpbmcgYml0LWJhbmdpbmcuCgkJCQkgKi8KCQkJCXJldHVybiBpaWNfc21idXNfcXVpY2soZGV2LCAmbXNnc1swXSk7CgkJCX0KCQkJREJHKCIlZDogaW52YWxpZCBsZW4gJWQgaW4gbXNnWyVkXVxuIiwgZGV2LT5pZHgsIAoJCQkJbXNnc1tpXS5sZW4sIGkpOwoJCQlyZXR1cm4gLUVJTlZBTDsKCQl9CgkJaWYgKHVubGlrZWx5KGlpY19hZGRyZXNzX25lcSgmbXNnc1swXSwgJm1zZ3NbaV0pKSl7CgkJCURCRygiJWQ6IGludmFsaWQgYWRkciBpbiBtc2dbJWRdXG4iLCBkZXYtPmlkeCwgaSk7CgkJCXJldHVybiAtRUlOVkFMOwoJCX0KCX0KCQoJLyogQ2hlY2sgYnVzIHN0YXRlICovCglpZiAodW5saWtlbHkoKGluXzgoJmlpYy0+ZXh0c3RzKSAmIEVYVFNUU19CQ1NfTUFTSykgIT0gRVhUU1RTX0JDU19GUkVFKSl7CgkJREJHKCIlZDogaWljX3hmZXIsIGJ1cyBpcyBub3QgZnJlZVxuIiwgZGV2LT5pZHgpOwoJCQoJCS8qIFVzdWFsbHkgaXQgbWVhbnMgc29tZXRoaW5nIHNlcmlvdXMgaGFzIGhhcHBlbmQuCgkJICogV2UgKmNhbm5vdCogaGF2ZSB1bmZpbmlzaGVkIHByZXZpb3VzIHRyYW5zZmVyCgkJICogc28gaXQgZG9lc24ndCBtYWtlIGFueSBzZW5zZSB0byB0cnkgdG8gc3RvcCBpdC4KCQkgKiBQcm9iYWJseSB3ZSB3ZXJlIG5vdCBhYmxlIHRvIHJlY292ZXIgZnJvbSB0aGUgCgkJICogcHJldmlvdXMgZXJyb3IuCgkJICogVGhlIG9ubHkgKnJlYXNvbmFibGUqIHRoaW5nIEkgY2FuIHRoaW5rIG9mIGhlcmUKCQkgKiBpcyBzb2Z0IHJlc2V0LiAgLS1lYnMKCQkgKi8KCQlpaWNfZGV2X3Jlc2V0KGRldik7CgkJCgkJaWYgKChpbl84KCZpaWMtPmV4dHN0cykgJiBFWFRTVFNfQkNTX01BU0spICE9IEVYVFNUU19CQ1NfRlJFRSl7CgkJCURCRygiJWQ6IGlpY194ZmVyLCBidXMgaXMgc3RpbGwgbm90IGZyZWVcbiIsIGRldi0+aWR4KTsKCQkJcmV0dXJuIC1FUkVNT1RFSU87CgkJfQoJfSAKCWVsc2UgewoJCS8qIEZsdXNoIG1hc3RlciBkYXRhIGJ1ZmZlciAoanVzdCBpbiBjYXNlKSAqLwoJCW91dF84KCZpaWMtPm1kY250bCwgaW5fOCgmaWljLT5tZGNudGwpIHwgTURDTlRMX0ZNREIpOwoJfQoJCgkvKiBMb2FkIHNsYXZlIGFkZHJlc3MgKi8KCWlpY19hZGRyZXNzKGRldiwgJm1zZ3NbMF0pOwoJCgkvKiBEbyByZWFsIHRyYW5zZmVyICovCiAgICAJZm9yIChpID0gMDsgaSA8IG51bSAmJiAhcmV0OyArK2kpCgkJcmV0ID0gaWljX3hmZXJfYnl0ZXMoZGV2LCAmbXNnc1tpXSwgaSA8IG51bSAtIDEpOwoKCXJldHVybiByZXQgPCAwID8gcmV0IDogbnVtOwp9CgpzdGF0aWMgdTMyIGlpY19mdW5jKHN0cnVjdCBpMmNfYWRhcHRlciAqYWRhcCkKewoJcmV0dXJuIEkyQ19GVU5DX0kyQyB8IEkyQ19GVU5DX1NNQlVTX0VNVUwgfCBJMkNfRlVOQ18xMEJJVF9BRERSOwp9CgpzdGF0aWMgc3RydWN0IGkyY19hbGdvcml0aG0gaWljX2FsZ28gPSB7CgkubWFzdGVyX3hmZXIgCT0gaWljX3hmZXIsCgkuZnVuY3Rpb25hbGl0eQk9IGlpY19mdW5jCn07CgovKgogKiBDYWxjdWxhdGVzIElJQ3hfQ0xDS0RJViB2YWx1ZSBmb3IgYSBzcGVjaWZpYyBPUEIgY2xvY2sgZnJlcXVlbmN5CiAqLwpzdGF0aWMgaW5saW5lIHU4IGlpY19jbGNrZGl2KHVuc2lnbmVkIGludCBvcGIpCnsKCS8qIENvbXBhdGliaWxpdHkga2x1ZGdlLCBzaG91bGQgZ28gYXdheSBhZnRlciBhbGwgY2FyZHMKCSAqIGFyZSBmaXhlZCB0byBmaWxsIGNvcnJlY3QgdmFsdWUgZm9yIG9wYmZyZXEuCgkgKiBQcmV2aW91cyBkcml2ZXIgdmVyc2lvbiB1c2VkIGhhcmRjb2RlZCBkaXZpZGVyIHZhbHVlIDQsCgkgKiBpdCBjb3JyZXNwb25kcyB0byBPUEIgZnJlcXVlbmN5IGZyb20gdGhlIHJhbmdlICg0MCwgNTBdIE1IegoJICovCglpZiAoIW9wYil7CgkJcHJpbnRrKEtFUk5fV0FSTklORyAiaWJtLWlpYzogdXNpbmcgY29tcGF0aWJpbGl0eSB2YWx1ZSBmb3IgT1BCIGZyZXEsIgoJCQkiIGZpeCB5b3VyIGJvYXJkIHNwZWNpZmljIHNldHVwXG4iKTsKCQlvcGIgPSA1MDAwMDAwMDsKCX0KCgkvKiBDb252ZXJ0IHRvIE1IeiAqLwoJb3BiIC89IDEwMDAwMDA7CgkKCWlmIChvcGIgPCAyMCB8fCBvcGIgPiAxNTApewoJCXByaW50ayhLRVJOX0NSSVQgImlibS1paWM6IGludmFsaWQgT1BCIGNsb2NrIGZyZXF1ZW5jeSAldSBNSHpcbiIsCgkJCW9wYik7CgkJb3BiID0gb3BiIDwgMjAgPyAyMCA6IDE1MDsKCX0KCXJldHVybiAodTgpKChvcGIgKyA5KSAvIDEwIC0gMSk7Cn0KCi8qCiAqIFJlZ2lzdGVyIHNpbmdsZSBJSUMgaW50ZXJmYWNlCiAqLwpzdGF0aWMgaW50IF9fZGV2aW5pdCBpaWNfcHJvYmUoc3RydWN0IG9jcF9kZXZpY2UgKm9jcCl7CgoJc3RydWN0IGlibV9paWNfcHJpdmF0ZSogZGV2OwoJc3RydWN0IGkyY19hZGFwdGVyKiBhZGFwOwoJc3RydWN0IG9jcF9mdW5jX2lpY19kYXRhKiBpaWNfZGF0YSA9IG9jcC0+ZGVmLT5hZGRpdGlvbnM7CglpbnQgcmV0OwoJCglpZiAoIWlpY19kYXRhKQoJCXByaW50ayhLRVJOX1dBUk5JTkciaWJtLWlpYyVkOiBtaXNzaW5nIGFkZGl0aW9uYWwgZGF0YSFcbiIsCgkJCW9jcC0+ZGVmLT5pbmRleCk7CgoJaWYgKCEoZGV2ID0ga21hbGxvYyhzaXplb2YoKmRldiksIEdGUF9LRVJORUwpKSl7CgkJcHJpbnRrKEtFUk5fQ1JJVCAiaWJtLWlpYyVkOiBmYWlsZWQgdG8gYWxsb2NhdGUgZGV2aWNlIGRhdGFcbiIsCgkJCW9jcC0+ZGVmLT5pbmRleCk7CgkJcmV0dXJuIC1FTk9NRU07Cgl9CgoJbWVtc2V0KGRldiwgMCwgc2l6ZW9mKCpkZXYpKTsKCWRldi0+aWR4ID0gb2NwLT5kZWYtPmluZGV4OwoJb2NwX3NldF9kcnZkYXRhKG9jcCwgZGV2KTsKCQoJaWYgKCEoZGV2LT52YWRkciA9IGlvcmVtYXAob2NwLT5kZWYtPnBhZGRyLCBzaXplb2Yoc3RydWN0IGlpY19yZWdzKSkpKXsKCQlwcmludGsoS0VSTl9DUklUICJpYm0taWljJWQ6IGZhaWxlZCB0byBpb3JlbWFwIGRldmljZSByZWdpc3RlcnNcbiIsCgkJCWRldi0+aWR4KTsKCQlyZXQgPSAtRU5YSU87CgkJZ290byBmYWlsMjsKCX0KCQoJaW5pdF93YWl0cXVldWVfaGVhZCgmZGV2LT53cSk7CgoJZGV2LT5pcnEgPSBpaWNfZm9yY2VfcG9sbCA/IC0xIDogb2NwLT5kZWYtPmlycTsKCWlmIChkZXYtPmlycSA+PSAwKXsKCQkvKiBEaXNhYmxlIGludGVycnVwdHMgdW50aWwgd2UgZmluaXNoIGluaXRpYWxpemF0aW9uLAoJCSAgIGFzc3VtZXMgbGV2ZWwtc2Vuc2l0aXZlIElSUSBzZXR1cC4uLgoJCSAqLwoJCWlpY19pbnRlcnJ1cHRfbW9kZShkZXYsIDApOwoJCWlmIChyZXF1ZXN0X2lycShkZXYtPmlycSwgaWljX2hhbmRsZXIsIDAsICJJQk0gSUlDIiwgZGV2KSl7CgkJCXByaW50ayhLRVJOX0VSUiAiaWJtLWlpYyVkOiByZXF1ZXN0X2lycSAlZCBmYWlsZWRcbiIsIAoJCQkJZGV2LT5pZHgsIGRldi0+aXJxKTsKCQkJLyogRmFsbGJhY2sgdG8gdGhlIHBvbGxpbmcgbW9kZSAqLwkKCQkJZGV2LT5pcnEgPSAtMTsKCQl9Cgl9CgkKCWlmIChkZXYtPmlycSA8IDApCgkJcHJpbnRrKEtFUk5fV0FSTklORyAiaWJtLWlpYyVkOiB1c2luZyBwb2xsaW5nIG1vZGVcbiIsIAoJCQlkZXYtPmlkeCk7CgkJCgkvKiBCb2FyZCBzcGVjaWZpYyBzZXR0aW5ncyAqLwoJZGV2LT5mYXN0X21vZGUgPSBpaWNfZm9yY2VfZmFzdCA/IDEgOiAoaWljX2RhdGEgPyBpaWNfZGF0YS0+ZmFzdF9tb2RlIDogMCk7CgkKCS8qIGNsY2tkaXYgaXMgdGhlIHNhbWUgZm9yICphbGwqIElJQyBpbnRlcmZhY2VzLCAKCSAqIGJ1dCBJJ2QgcmF0aGVyIG1ha2UgYSBjb3B5IHRoYW4gaW50cm9kdWNlIGFub3RoZXIgZ2xvYmFsLiAtLWVicwoJICovCglkZXYtPmNsY2tkaXYgPSBpaWNfY2xja2RpdihvY3Bfc3lzX2luZm8ub3BiX2J1c19mcmVxKTsKCURCRygiJWQ6IGNsY2tkaXYgPSAlZFxuIiwgZGV2LT5pZHgsIGRldi0+Y2xja2Rpdik7CgkKCS8qIEluaXRpYWxpemUgSUlDIGludGVyZmFjZSAqLwoJaWljX2Rldl9pbml0KGRldik7CgkKCS8qIFJlZ2lzdGVyIGl0IHdpdGggaTJjIGxheWVyICovCglhZGFwID0gJmRldi0+YWRhcDsKCXN0cmNweShhZGFwLT5uYW1lLCAiSUJNIElJQyIpOwoJaTJjX3NldF9hZGFwZGF0YShhZGFwLCBkZXYpOwoJYWRhcC0+aWQgPSBJMkNfSFdfT0NQOwoJYWRhcC0+YWxnbyA9ICZpaWNfYWxnbzsKCWFkYXAtPmNsaWVudF9yZWdpc3RlciA9IE5VTEw7CglhZGFwLT5jbGllbnRfdW5yZWdpc3RlciA9IE5VTEw7CglhZGFwLT50aW1lb3V0ID0gMTsKCWFkYXAtPnJldHJpZXMgPSAxOwoKCWlmICgocmV0ID0gaTJjX2FkZF9hZGFwdGVyKGFkYXApKSAhPSAwKXsKCQlwcmludGsoS0VSTl9DUklUICJpYm0taWljJWQ6IGZhaWxlZCB0byByZWdpc3RlciBpMmMgYWRhcHRlclxuIiwKCQkJZGV2LT5pZHgpOwoJCWdvdG8gZmFpbDsKCX0KCQoJcHJpbnRrKEtFUk5fSU5GTyAiaWJtLWlpYyVkOiB1c2luZyAlcyBtb2RlXG4iLCBkZXYtPmlkeCwKCQlkZXYtPmZhc3RfbW9kZSA/ICJmYXN0ICg0MDAga0h6KSIgOiAic3RhbmRhcmQgKDEwMCBrSHopIik7CgoJcmV0dXJuIDA7CgpmYWlsOgkKCWlmIChkZXYtPmlycSA+PSAwKXsKCQlpaWNfaW50ZXJydXB0X21vZGUoZGV2LCAwKTsKCQlmcmVlX2lycShkZXYtPmlycSwgZGV2KTsKCX0JCgoJaW91bm1hcChkZXYtPnZhZGRyKTsKZmFpbDI6CQoJb2NwX3NldF9kcnZkYXRhKG9jcCwgTlVMTCk7CglrZnJlZShkZXYpOwkKCXJldHVybiByZXQ7Cn0KCi8qCiAqIENsZWFudXAgaW5pdGlhbGl6ZWQgSUlDIGludGVyZmFjZQogKi8Kc3RhdGljIHZvaWQgX19kZXZleGl0IGlpY19yZW1vdmUoc3RydWN0IG9jcF9kZXZpY2UgKm9jcCkKewoJc3RydWN0IGlibV9paWNfcHJpdmF0ZSogZGV2ID0gKHN0cnVjdCBpYm1faWljX3ByaXZhdGUqKW9jcF9nZXRfZHJ2ZGF0YShvY3ApOwoJQlVHX09OKGRldiA9PSBOVUxMKTsKCWlmIChpMmNfZGVsX2FkYXB0ZXIoJmRldi0+YWRhcCkpewoJCXByaW50ayhLRVJOX0NSSVQgImlibS1paWMlZDogZmFpbGVkIHRvIGRlbGV0ZSBpMmMgYWRhcHRlciA6KFxuIiwKCQkJZGV2LT5pZHgpOwoJCS8qIFRoYXQncyAqdmVyeSogYmFkLCBqdXN0IHNodXRkb3duIElSUSAuLi4gKi8KCQlpZiAoZGV2LT5pcnEgPj0gMCl7CgkJICAgIGlpY19pbnRlcnJ1cHRfbW9kZShkZXYsIDApOwkKCQkgICAgZnJlZV9pcnEoZGV2LT5pcnEsIGRldik7CgkJICAgIGRldi0+aXJxID0gLTE7CgkJfQoJfSBlbHNlIHsKCQlpZiAoZGV2LT5pcnEgPj0gMCl7CgkJICAgIGlpY19pbnRlcnJ1cHRfbW9kZShkZXYsIDApOwkKCQkgICAgZnJlZV9pcnEoZGV2LT5pcnEsIGRldik7CgkJfQoJCWlvdW5tYXAoZGV2LT52YWRkcik7CgkJa2ZyZWUoZGV2KTsKCX0KfQoKc3RhdGljIHN0cnVjdCBvY3BfZGV2aWNlX2lkIGlibV9paWNfaWRzW10gX19kZXZpbml0ZGF0YSA9IAp7Cgl7IC52ZW5kb3IgPSBPQ1BfVkVORE9SX0lCTSwgLmZ1bmN0aW9uID0gT0NQX0ZVTkNfSUlDIH0sCgl7IC52ZW5kb3IgPSBPQ1BfVkVORE9SX0lOVkFMSUQgfQp9OwoKTU9EVUxFX0RFVklDRV9UQUJMRShvY3AsIGlibV9paWNfaWRzKTsKCnN0YXRpYyBzdHJ1Y3Qgb2NwX2RyaXZlciBpYm1faWljX2RyaXZlciA9CnsKCS5uYW1lIAkJPSAiaWljIiwKCS5pZF90YWJsZQk9IGlibV9paWNfaWRzLAoJLnByb2JlCQk9IGlpY19wcm9iZSwKCS5yZW1vdmUJCT0gX19kZXZleGl0X3AoaWljX3JlbW92ZSksCiNpZiBkZWZpbmVkKENPTkZJR19QTSkKCS5zdXNwZW5kCT0gTlVMTCwKCS5yZXN1bWUJCT0gTlVMTCwKI2VuZGlmCn07CgpzdGF0aWMgaW50IF9faW5pdCBpaWNfaW5pdCh2b2lkKQp7CglwcmludGsoS0VSTl9JTkZPICJJQk0gSUlDIGRyaXZlciB2IiBEUklWRVJfVkVSU0lPTiAiXG4iKTsKCXJldHVybiBvY3BfcmVnaXN0ZXJfZHJpdmVyKCZpYm1faWljX2RyaXZlcik7Cn0KCnN0YXRpYyB2b2lkIF9fZXhpdCBpaWNfZXhpdCh2b2lkKQp7CglvY3BfdW5yZWdpc3Rlcl9kcml2ZXIoJmlibV9paWNfZHJpdmVyKTsKfQoKbW9kdWxlX2luaXQoaWljX2luaXQpOwptb2R1bGVfZXhpdChpaWNfZXhpdCk7Cg==