LyogcmFkZW9uX3N0YXRlLmMgLS0gU3RhdGUgc3VwcG9ydCBmb3IgUmFkZW9uIC0qLSBsaW51eC1jIC0qLSAqLwovKgogKiBDb3B5cmlnaHQgMjAwMCBWQSBMaW51eCBTeXN0ZW1zLCBJbmMuLCBGcmVtb250LCBDYWxpZm9ybmlhLgogKiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKgogKiBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYQogKiBjb3B5IG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlICJTb2Z0d2FyZSIpLAogKiB0byBkZWFsIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uCiAqIHRoZSByaWdodHMgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLCBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLAogKiBhbmQvb3Igc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0IHBlcnNvbnMgdG8gd2hvbSB0aGUKICogU29mdHdhcmUgaXMgZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczoKICoKICogVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2UgKGluY2x1ZGluZyB0aGUgbmV4dAogKiBwYXJhZ3JhcGgpIHNoYWxsIGJlIGluY2x1ZGVkIGluIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlCiAqIFNvZnR3YXJlLgogKgogKiBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgIkFTIElTIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTUyBPUgogKiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSwKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gIElOIE5PIEVWRU5UIFNIQUxMCiAqIFBSRUNJU0lPTiBJTlNJR0hUIEFORC9PUiBJVFMgU1VQUExJRVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLCBEQU1BR0VTIE9SCiAqIE9USEVSIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1IgT1RIRVJXSVNFLAogKiBBUklTSU5HIEZST00sIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRSBVU0UgT1IgT1RIRVIKICogREVBTElOR1MgSU4gVEhFIFNPRlRXQVJFLgogKgogKiBBdXRob3JzOgogKiAgICBHYXJldGggSHVnaGVzIDxnYXJldGhAdmFsaW51eC5jb20+CiAqICAgIEtldmluIEUuIE1hcnRpbiA8bWFydGluQHZhbGludXguY29tPgogKi8KCiNpbmNsdWRlICJkcm1QLmgiCiNpbmNsdWRlICJkcm0uaCIKI2luY2x1ZGUgImRybV9zYXJlYS5oIgojaW5jbHVkZSAicmFkZW9uX2RybS5oIgojaW5jbHVkZSAicmFkZW9uX2Rydi5oIgoKLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKiBIZWxwZXIgZnVuY3Rpb25zIGZvciBjbGllbnQgc3RhdGUgY2hlY2tpbmcgYW5kIGZpeHVwCiAqLwoKc3RhdGljIF9faW5saW5lX18gaW50IHJhZGVvbl9jaGVja19hbmRfZml4dXBfb2Zmc2V0KGRybV9yYWRlb25fcHJpdmF0ZV90ICoKCQkJCQkJICAgIGRldl9wcml2LAoJCQkJCQkgICAgZHJtX2ZpbGVfdCAqIGZpbHBfcHJpdiwKCQkJCQkJICAgIHUzMiAqb2Zmc2V0KQp7Cgl1NjQgb2ZmID0gKm9mZnNldDsKCXUzMiBmYl9lbmQgPSBkZXZfcHJpdi0+ZmJfbG9jYXRpb24gKyBkZXZfcHJpdi0+ZmJfc2l6ZSAtIDE7CglzdHJ1Y3QgZHJtX3JhZGVvbl9kcml2ZXJfZmlsZV9maWVsZHMgKnJhZGVvbl9wcml2OwoKCS8qIEhybSAuLi4gdGhlIHN0b3J5IG9mIHRoZSBvZmZzZXQgLi4uIFNvIHRoaXMgZnVuY3Rpb24gY29udmVydHMKCSAqIHRoZSB2YXJpb3VzIGlkZWFzIG9mIHdoYXQgdXNlcmxhbmQgY2xpZW50cyBtaWdodCBoYXZlIGZvciBhbgoJICogb2Zmc2V0IGluIHRoZSBjYXJkIGFkZHJlc3Mgc3BhY2UgaW50byBhbiBvZmZzZXQgaW50byB0aGUgY2FyZAoJICogYWRkcmVzcyBzcGFjZSA6KSBTbyB3aXRoIGEgc2FuZSBjbGllbnQsIGl0IHNob3VsZCBqdXN0IGtlZXAKCSAqIHRoZSB2YWx1ZSBpbnRhY3QgYW5kIGp1c3QgZG8gc29tZSBib3VuZGFyeSBjaGVja2luZy4gSG93ZXZlciwKCSAqIG5vdCBhbGwgY2xpZW50cyBhcmUgc2FuZS4gU29tZSBvbGRlciBjbGllbnRzIHBhc3MgdXMgMCBiYXNlZAoJICogb2Zmc2V0cyByZWxhdGl2ZSB0byB0aGUgc3RhcnQgb2YgdGhlIGZyYW1lYnVmZmVyIGFuZCBzb21lIG1heQoJICogYXNzdW1lIHRoZSBBR1AgYXBlcnR1cmUgaXQgYXBwZW5kZWQgdG8gdGhlIGZyYW1lYnVmZmVyLCBzbyB3ZQoJICogdHJ5IHRvIGRldGVjdCB0aG9zZSBjYXNlcyBhbmQgZml4IHRoZW0gdXAuCgkgKgoJICogTm90ZTogSXQgbWlnaHQgYmUgYSBnb29kIGlkZWEgaGVyZSB0byBtYWtlIHN1cmUgdGhlIG9mZnNldCBsYW5kcwoJICogaW4gc29tZSAiYWxsb3dlZCIgYXJlYSB0byBwcm90ZWN0IHRoaW5ncyBsaWtlIHRoZSBQQ0lFIEdBUlQuLi4KCSAqLwoKCS8qIEZpcnN0LCB0aGUgYmVzdCBjYXNlLCB0aGUgb2Zmc2V0IGFscmVhZHkgbGFuZHMgaW4gZWl0aGVyIHRoZQoJICogZnJhbWVidWZmZXIgb3IgdGhlIEdBUlQgbWFwcGVkIHNwYWNlCgkgKi8KCWlmIChyYWRlb25fY2hlY2tfb2Zmc2V0KGRldl9wcml2LCBvZmYpKQoJCXJldHVybiAwOwoKCS8qIE9rLCB0aGF0IGRpZG4ndCBoYXBwZW4uLi4gbm93IGNoZWNrIGlmIHdlIGhhdmUgYSB6ZXJvIGJhc2VkCgkgKiBvZmZzZXQgdGhhdCBmaXRzIGluIHRoZSBmcmFtZWJ1ZmZlciArIGdhcnQgc3BhY2UsIGFwcGx5IHRoZQoJICogbWFnaWMgb2Zmc2V0IHdlIGdldCBmcm9tIFNFVFBBUkFNIG9yIGNhbGN1bGF0ZWQgZnJvbSBmYl9sb2NhdGlvbgoJICovCglpZiAob2ZmIDwgKGRldl9wcml2LT5mYl9zaXplICsgZGV2X3ByaXYtPmdhcnRfc2l6ZSkpIHsKCQlyYWRlb25fcHJpdiA9IGZpbHBfcHJpdi0+ZHJpdmVyX3ByaXY7CgkJb2ZmICs9IHJhZGVvbl9wcml2LT5yYWRlb25fZmJfZGVsdGE7Cgl9CgoJLyogRmluYWxseSwgYXNzdW1lIHdlIGFpbWVkIGF0IGEgR0FSVCBvZmZzZXQgaWYgYmV5b25kIHRoZSBmYiAqLwoJaWYgKG9mZiA+IGZiX2VuZCkKCQlvZmYgPSBvZmYgLSBmYl9lbmQgLSAxICsgZGV2X3ByaXYtPmdhcnRfdm1fc3RhcnQ7CgoJLyogTm93IHJlY2hlY2sgYW5kIGZhaWwgaWYgb3V0IG9mIGJvdW5kcyAqLwoJaWYgKHJhZGVvbl9jaGVja19vZmZzZXQoZGV2X3ByaXYsIG9mZikpIHsKCQlEUk1fREVCVUcoIm9mZnNldCBmaXhlZCB1cCB0byAweCV4XG4iLCAodW5zaWduZWQgaW50KW9mZik7CgkJKm9mZnNldCA9IG9mZjsKCQlyZXR1cm4gMDsKCX0KCXJldHVybiBEUk1fRVJSKEVJTlZBTCk7Cn0KCnN0YXRpYyBfX2lubGluZV9fIGludCByYWRlb25fY2hlY2tfYW5kX2ZpeHVwX3BhY2tldHMoZHJtX3JhZGVvbl9wcml2YXRlX3QgKgoJCQkJCQkgICAgIGRldl9wcml2LAoJCQkJCQkgICAgIGRybV9maWxlX3QgKiBmaWxwX3ByaXYsCgkJCQkJCSAgICAgaW50IGlkLCB1MzIgKmRhdGEpCnsKCXN3aXRjaCAoaWQpIHsKCgljYXNlIFJBREVPTl9FTUlUX1BQX01JU0M6CgkJaWYgKHJhZGVvbl9jaGVja19hbmRfZml4dXBfb2Zmc2V0KGRldl9wcml2LCBmaWxwX3ByaXYsCgkJICAgICZkYXRhWyhSQURFT05fUkIzRF9ERVBUSE9GRlNFVCAtIFJBREVPTl9QUF9NSVNDKSAvIDRdKSkgewoJCQlEUk1fRVJST1IoIkludmFsaWQgZGVwdGggYnVmZmVyIG9mZnNldFxuIik7CgkJCXJldHVybiBEUk1fRVJSKEVJTlZBTCk7CgkJfQoJCWJyZWFrOwoKCWNhc2UgUkFERU9OX0VNSVRfUFBfQ05UTDoKCQlpZiAocmFkZW9uX2NoZWNrX2FuZF9maXh1cF9vZmZzZXQoZGV2X3ByaXYsIGZpbHBfcHJpdiwKCQkgICAgJmRhdGFbKFJBREVPTl9SQjNEX0NPTE9ST0ZGU0VUIC0gUkFERU9OX1BQX0NOVEwpIC8gNF0pKSB7CgkJCURSTV9FUlJPUigiSW52YWxpZCBjb2xvdXIgYnVmZmVyIG9mZnNldFxuIik7CgkJCXJldHVybiBEUk1fRVJSKEVJTlZBTCk7CgkJfQoJCWJyZWFrOwoKCWNhc2UgUjIwMF9FTUlUX1BQX1RYT0ZGU0VUXzA6CgljYXNlIFIyMDBfRU1JVF9QUF9UWE9GRlNFVF8xOgoJY2FzZSBSMjAwX0VNSVRfUFBfVFhPRkZTRVRfMjoKCWNhc2UgUjIwMF9FTUlUX1BQX1RYT0ZGU0VUXzM6CgljYXNlIFIyMDBfRU1JVF9QUF9UWE9GRlNFVF80OgoJY2FzZSBSMjAwX0VNSVRfUFBfVFhPRkZTRVRfNToKCQlpZiAocmFkZW9uX2NoZWNrX2FuZF9maXh1cF9vZmZzZXQoZGV2X3ByaXYsIGZpbHBfcHJpdiwKCQkJCQkJICAmZGF0YVswXSkpIHsKCQkJRFJNX0VSUk9SKCJJbnZhbGlkIFIyMDAgdGV4dHVyZSBvZmZzZXRcbiIpOwoJCQlyZXR1cm4gRFJNX0VSUihFSU5WQUwpOwoJCX0KCQlicmVhazsKCgljYXNlIFJBREVPTl9FTUlUX1BQX1RYRklMVEVSXzA6CgljYXNlIFJBREVPTl9FTUlUX1BQX1RYRklMVEVSXzE6CgljYXNlIFJBREVPTl9FTUlUX1BQX1RYRklMVEVSXzI6CgkJaWYgKHJhZGVvbl9jaGVja19hbmRfZml4dXBfb2Zmc2V0KGRldl9wcml2LCBmaWxwX3ByaXYsCgkJICAgICZkYXRhWyhSQURFT05fUFBfVFhPRkZTRVRfMCAtIFJBREVPTl9QUF9UWEZJTFRFUl8wKSAvIDRdKSkgewoJCQlEUk1fRVJST1IoIkludmFsaWQgUjEwMCB0ZXh0dXJlIG9mZnNldFxuIik7CgkJCXJldHVybiBEUk1fRVJSKEVJTlZBTCk7CgkJfQoJCWJyZWFrOwoKCWNhc2UgUjIwMF9FTUlUX1BQX0NVQklDX09GRlNFVFNfMDoKCWNhc2UgUjIwMF9FTUlUX1BQX0NVQklDX09GRlNFVFNfMToKCWNhc2UgUjIwMF9FTUlUX1BQX0NVQklDX09GRlNFVFNfMjoKCWNhc2UgUjIwMF9FTUlUX1BQX0NVQklDX09GRlNFVFNfMzoKCWNhc2UgUjIwMF9FTUlUX1BQX0NVQklDX09GRlNFVFNfNDoKCWNhc2UgUjIwMF9FTUlUX1BQX0NVQklDX09GRlNFVFNfNTp7CgkJCWludCBpOwoJCQlmb3IgKGkgPSAwOyBpIDwgNTsgaSsrKSB7CgkJCQlpZiAocmFkZW9uX2NoZWNrX2FuZF9maXh1cF9vZmZzZXQoZGV2X3ByaXYsCgkJCQkJCQkJICBmaWxwX3ByaXYsCgkJCQkJCQkJICAmZGF0YVtpXSkpIHsKCQkJCQlEUk1fRVJST1IKCQkJCQkgICAgKCJJbnZhbGlkIFIyMDAgY3ViaWMgdGV4dHVyZSBvZmZzZXRcbiIpOwoJCQkJCXJldHVybiBEUk1fRVJSKEVJTlZBTCk7CgkJCQl9CgkJCX0KCQkJYnJlYWs7CgkJfQoKCWNhc2UgUkFERU9OX0VNSVRfUFBfQ1VCSUNfT0ZGU0VUU19UMDoKCWNhc2UgUkFERU9OX0VNSVRfUFBfQ1VCSUNfT0ZGU0VUU19UMToKCWNhc2UgUkFERU9OX0VNSVRfUFBfQ1VCSUNfT0ZGU0VUU19UMjp7CgkJCWludCBpOwoJCQlmb3IgKGkgPSAwOyBpIDwgNTsgaSsrKSB7CgkJCQlpZiAocmFkZW9uX2NoZWNrX2FuZF9maXh1cF9vZmZzZXQoZGV2X3ByaXYsCgkJCQkJCQkJICBmaWxwX3ByaXYsCgkJCQkJCQkJICAmZGF0YVtpXSkpIHsKCQkJCQlEUk1fRVJST1IKCQkJCQkgICAgKCJJbnZhbGlkIFIxMDAgY3ViaWMgdGV4dHVyZSBvZmZzZXRcbiIpOwoJCQkJCXJldHVybiBEUk1fRVJSKEVJTlZBTCk7CgkJCQl9CgkJCX0KCQl9CgkJYnJlYWs7CgoJY2FzZSBSMjAwX0VNSVRfVkFQX0NUTDp7CgkJCVJJTkdfTE9DQUxTOwoJCQlCRUdJTl9SSU5HKDIpOwoJCQlPVVRfUklOR19SRUcoUkFERU9OX1NFX1RDTF9TVEFURV9GTFVTSCwgMCk7CgkJCUFEVkFOQ0VfUklORygpOwoJCX0KCQlicmVhazsKCgljYXNlIFJBREVPTl9FTUlUX1JCM0RfQ09MT1JQSVRDSDoKCWNhc2UgUkFERU9OX0VNSVRfUkVfTElORV9QQVRURVJOOgoJY2FzZSBSQURFT05fRU1JVF9TRV9MSU5FX1dJRFRIOgoJY2FzZSBSQURFT05fRU1JVF9QUF9MVU1fTUFUUklYOgoJY2FzZSBSQURFT05fRU1JVF9QUF9ST1RfTUFUUklYXzA6CgljYXNlIFJBREVPTl9FTUlUX1JCM0RfU1RFTkNJTFJFRk1BU0s6CgljYXNlIFJBREVPTl9FTUlUX1NFX1ZQT1JUX1hTQ0FMRToKCWNhc2UgUkFERU9OX0VNSVRfU0VfQ05UTDoKCWNhc2UgUkFERU9OX0VNSVRfU0VfQ05UTF9TVEFUVVM6CgljYXNlIFJBREVPTl9FTUlUX1JFX01JU0M6CgljYXNlIFJBREVPTl9FTUlUX1BQX0JPUkRFUl9DT0xPUl8wOgoJY2FzZSBSQURFT05fRU1JVF9QUF9CT1JERVJfQ09MT1JfMToKCWNhc2UgUkFERU9OX0VNSVRfUFBfQk9SREVSX0NPTE9SXzI6CgljYXNlIFJBREVPTl9FTUlUX1NFX1pCSUFTX0ZBQ1RPUjoKCWNhc2UgUkFERU9OX0VNSVRfU0VfVENMX09VVFBVVF9WVFhfRk1UOgoJY2FzZSBSQURFT05fRU1JVF9TRV9UQ0xfTUFURVJJQUxfRU1NSVNTSVZFX1JFRDoKCWNhc2UgUjIwMF9FTUlUX1BQX1RYQ0JMRU5EXzA6CgljYXNlIFIyMDBfRU1JVF9QUF9UWENCTEVORF8xOgoJY2FzZSBSMjAwX0VNSVRfUFBfVFhDQkxFTkRfMjoKCWNhc2UgUjIwMF9FTUlUX1BQX1RYQ0JMRU5EXzM6CgljYXNlIFIyMDBfRU1JVF9QUF9UWENCTEVORF80OgoJY2FzZSBSMjAwX0VNSVRfUFBfVFhDQkxFTkRfNToKCWNhc2UgUjIwMF9FTUlUX1BQX1RYQ0JMRU5EXzY6CgljYXNlIFIyMDBfRU1JVF9QUF9UWENCTEVORF83OgoJY2FzZSBSMjAwX0VNSVRfVENMX0xJR0hUX01PREVMX0NUTF8wOgoJY2FzZSBSMjAwX0VNSVRfVEZBQ1RPUl8wOgoJY2FzZSBSMjAwX0VNSVRfVlRYX0ZNVF8wOgoJY2FzZSBSMjAwX0VNSVRfTUFUUklYX1NFTEVDVF8wOgoJY2FzZSBSMjAwX0VNSVRfVEVYX1BST0NfQ1RMXzI6CgljYXNlIFIyMDBfRU1JVF9UQ0xfVUNQX1ZFUlRfQkxFTkRfQ1RMOgoJY2FzZSBSMjAwX0VNSVRfUFBfVFhGSUxURVJfMDoKCWNhc2UgUjIwMF9FTUlUX1BQX1RYRklMVEVSXzE6CgljYXNlIFIyMDBfRU1JVF9QUF9UWEZJTFRFUl8yOgoJY2FzZSBSMjAwX0VNSVRfUFBfVFhGSUxURVJfMzoKCWNhc2UgUjIwMF9FTUlUX1BQX1RYRklMVEVSXzQ6CgljYXNlIFIyMDBfRU1JVF9QUF9UWEZJTFRFUl81OgoJY2FzZSBSMjAwX0VNSVRfVlRFX0NOVEw6CgljYXNlIFIyMDBfRU1JVF9PVVRQVVRfVlRYX0NPTVBfU0VMOgoJY2FzZSBSMjAwX0VNSVRfUFBfVEFNX0RFQlVHMzoKCWNhc2UgUjIwMF9FTUlUX1BQX0NOVExfWDoKCWNhc2UgUjIwMF9FTUlUX1JCM0RfREVQVEhYWV9PRkZTRVQ6CgljYXNlIFIyMDBfRU1JVF9SRV9BVVhfU0NJU1NPUl9DTlRMOgoJY2FzZSBSMjAwX0VNSVRfUkVfU0NJU1NPUl9UTF8wOgoJY2FzZSBSMjAwX0VNSVRfUkVfU0NJU1NPUl9UTF8xOgoJY2FzZSBSMjAwX0VNSVRfUkVfU0NJU1NPUl9UTF8yOgoJY2FzZSBSMjAwX0VNSVRfU0VfVkFQX0NOVExfU1RBVFVTOgoJY2FzZSBSMjAwX0VNSVRfU0VfVlRYX1NUQVRFX0NOVEw6CgljYXNlIFIyMDBfRU1JVF9SRV9QT0lOVFNJWkU6CgljYXNlIFIyMDBfRU1JVF9UQ0xfSU5QVVRfVlRYX1ZFQ1RPUl9BRERSXzA6CgljYXNlIFIyMDBfRU1JVF9QUF9DVUJJQ19GQUNFU18wOgoJY2FzZSBSMjAwX0VNSVRfUFBfQ1VCSUNfRkFDRVNfMToKCWNhc2UgUjIwMF9FTUlUX1BQX0NVQklDX0ZBQ0VTXzI6CgljYXNlIFIyMDBfRU1JVF9QUF9DVUJJQ19GQUNFU18zOgoJY2FzZSBSMjAwX0VNSVRfUFBfQ1VCSUNfRkFDRVNfNDoKCWNhc2UgUjIwMF9FTUlUX1BQX0NVQklDX0ZBQ0VTXzU6CgljYXNlIFJBREVPTl9FTUlUX1BQX1RFWF9TSVpFXzA6CgljYXNlIFJBREVPTl9FTUlUX1BQX1RFWF9TSVpFXzE6CgljYXNlIFJBREVPTl9FTUlUX1BQX1RFWF9TSVpFXzI6CgljYXNlIFIyMDBfRU1JVF9SQjNEX0JMRU5EQ09MT1I6CgljYXNlIFIyMDBfRU1JVF9UQ0xfUE9JTlRfU1BSSVRFX0NOVEw6CgljYXNlIFJBREVPTl9FTUlUX1BQX0NVQklDX0ZBQ0VTXzA6CgljYXNlIFJBREVPTl9FTUlUX1BQX0NVQklDX0ZBQ0VTXzE6CgljYXNlIFJBREVPTl9FTUlUX1BQX0NVQklDX0ZBQ0VTXzI6CgljYXNlIFIyMDBfRU1JVF9QUF9UUklfUEVSRl9DTlRMOgoJY2FzZSBSMjAwX0VNSVRfUFBfQUZTXzA6CgljYXNlIFIyMDBfRU1JVF9QUF9BRlNfMToKCWNhc2UgUjIwMF9FTUlUX0FURl9URkFDVE9SOgoJY2FzZSBSMjAwX0VNSVRfUFBfVFhDVExBTExfMDoKCWNhc2UgUjIwMF9FTUlUX1BQX1RYQ1RMQUxMXzE6CgljYXNlIFIyMDBfRU1JVF9QUF9UWENUTEFMTF8yOgoJY2FzZSBSMjAwX0VNSVRfUFBfVFhDVExBTExfMzoKCWNhc2UgUjIwMF9FTUlUX1BQX1RYQ1RMQUxMXzQ6CgljYXNlIFIyMDBfRU1JVF9QUF9UWENUTEFMTF81OgoJY2FzZSBSMjAwX0VNSVRfVkFQX1BWU19DTlRMOgoJCS8qIFRoZXNlIHBhY2tldHMgZG9uJ3QgY29udGFpbiBtZW1vcnkgb2Zmc2V0cyAqLwoJCWJyZWFrOwoKCWRlZmF1bHQ6CgkJRFJNX0VSUk9SKCJVbmtub3duIHN0YXRlIHBhY2tldCBJRCAlZFxuIiwgaWQpOwoJCXJldHVybiBEUk1fRVJSKEVJTlZBTCk7Cgl9CgoJcmV0dXJuIDA7Cn0KCnN0YXRpYyBfX2lubGluZV9fIGludCByYWRlb25fY2hlY2tfYW5kX2ZpeHVwX3BhY2tldDMoZHJtX3JhZGVvbl9wcml2YXRlX3QgKgoJCQkJCQkgICAgIGRldl9wcml2LAoJCQkJCQkgICAgIGRybV9maWxlX3QgKmZpbHBfcHJpdiwKCQkJCQkJICAgICBkcm1fcmFkZW9uX2tjbWRfYnVmZmVyX3QgKgoJCQkJCQkgICAgIGNtZGJ1ZiwKCQkJCQkJICAgICB1bnNpZ25lZCBpbnQgKmNtZHN6KQp7Cgl1MzIgKmNtZCA9ICh1MzIgKikgY21kYnVmLT5idWY7Cgl1MzIgb2Zmc2V0LCBuYXJyYXlzOwoJaW50IGNvdW50LCBpLCBrOwoKCSpjbWRzeiA9IDIgKyAoKGNtZFswXSAmIFJBREVPTl9DUF9QQUNLRVRfQ09VTlRfTUFTSykgPj4gMTYpOwoKCWlmICgoY21kWzBdICYgMHhjMDAwMDAwMCkgIT0gUkFERU9OX0NQX1BBQ0tFVDMpIHsKCQlEUk1fRVJST1IoIk5vdCBhIHR5cGUgMyBwYWNrZXRcbiIpOwoJCXJldHVybiBEUk1fRVJSKEVJTlZBTCk7Cgl9CgoJaWYgKDQgKiAqY21kc3ogPiBjbWRidWYtPmJ1ZnN6KSB7CgkJRFJNX0VSUk9SKCJQYWNrZXQgc2l6ZSBsYXJnZXIgdGhhbiBzaXplIG9mIGRhdGEgcHJvdmlkZWRcbiIpOwoJCXJldHVybiBEUk1fRVJSKEVJTlZBTCk7Cgl9CgoJc3dpdGNoKGNtZFswXSAmIDB4ZmYwMCkgewoJLyogWFhYIEFyZSB0aGVyZSBvbGQgZHJpdmVycyBuZWVkaW5nIG90aGVyIHBhY2tldHM/ICovCgoJY2FzZSBSQURFT05fM0RfRFJBV19JTU1EOgoJY2FzZSBSQURFT05fM0RfRFJBV19WQlVGOgoJY2FzZSBSQURFT05fM0RfRFJBV19JTkRYOgoJY2FzZSBSQURFT05fV0FJVF9GT1JfSURMRToKCWNhc2UgUkFERU9OX0NQX05PUDoKCWNhc2UgUkFERU9OXzNEX0NMRUFSX1pNQVNLOgovKgljYXNlIFJBREVPTl9DUF9ORVhUX0NIQVI6CgljYXNlIFJBREVPTl9DUF9QTFlfTkVYVFNDQU46CgljYXNlIFJBREVPTl9DUF9TRVRfU0NJU1NPUlM6ICovIC8qIHByb2JhYmx5IHNhZmUgYnV0IHdpbGwgbmV2ZXIgbmVlZCB0aGVtPyAqLwoJCS8qIHRoZXNlIHBhY2tldHMgYXJlIHNhZmUgKi8KCQlicmVhazsKCgljYXNlIFJBREVPTl9DUF8zRF9EUkFXX0lNTURfMjoKCWNhc2UgUkFERU9OX0NQXzNEX0RSQVdfVkJVRl8yOgoJY2FzZSBSQURFT05fQ1BfM0RfRFJBV19JTkRYXzI6CgljYXNlIFJBREVPTl8zRF9DTEVBUl9ISVo6CgkJLyogc2FmZSBidXQgcjIwMCBvbmx5ICovCgkJaWYgKGRldl9wcml2LT5taWNyb2NvZGVfdmVyc2lvbiAhPSBVQ09ERV9SMjAwKSB7CgkJCURSTV9FUlJPUigiSW52YWxpZCAzZCBwYWNrZXQgZm9yIHIxMDAtY2xhc3MgY2hpcFxuIik7CgkJCXJldHVybiBEUk1fRVJSKEVJTlZBTCk7CgkJfQoJCWJyZWFrOwoKCWNhc2UgUkFERU9OXzNEX0xPQURfVkJQTlRSOgoJCWNvdW50ID0gKGNtZFswXSA+PiAxNikgJiAweDNmZmY7CgoJCWlmIChjb3VudCA+IDE4KSB7IC8qIDEyIGFycmF5cyBtYXggKi8KCQkJRFJNX0VSUk9SKCJUb28gbGFyZ2UgcGF5bG9hZCBpbiAzRF9MT0FEX1ZCUE5UUiAoY291bnQ9JWQpXG4iLAoJCQkJICBjb3VudCk7CgkJCXJldHVybiBEUk1fRVJSKEVJTlZBTCk7CgkJfQoKCQkvKiBjYXJlZnVsbHkgY2hlY2sgcGFja2V0IGNvbnRlbnRzICovCgkJbmFycmF5cyA9IGNtZFsxXSAmIH4weGMwMDA7CgkJayA9IDA7CgkJaSA9IDI7CgkJd2hpbGUgKChrIDwgbmFycmF5cykgJiYgKGkgPCAoY291bnQgKyAyKSkpIHsKCQkJaSsrOwkJLyogc2tpcCBhdHRyaWJ1dGUgZmllbGQgKi8KCQkJaWYgKHJhZGVvbl9jaGVja19hbmRfZml4dXBfb2Zmc2V0KGRldl9wcml2LCBmaWxwX3ByaXYsICZjbWRbaV0pKSB7CgkJCQlEUk1fRVJST1IKCQkJCSAgICAoIkludmFsaWQgb2Zmc2V0IChrPSVkIGk9JWQpIGluIDNEX0xPQURfVkJQTlRSIHBhY2tldC5cbiIsCgkJCQkgICAgIGssIGkpOwoJCQkJcmV0dXJuIERSTV9FUlIoRUlOVkFMKTsKCQkJfQoJCQlrKys7CgkJCWkrKzsKCQkJaWYgKGsgPT0gbmFycmF5cykKCQkJCWJyZWFrOwoJCQkvKiBoYXZlIG9uZSBtb3JlIHRvIHByb2Nlc3MsIHRoZXkgY29tZSBpbiBwYWlycyAqLwoJCQlpZiAocmFkZW9uX2NoZWNrX2FuZF9maXh1cF9vZmZzZXQoZGV2X3ByaXYsIGZpbHBfcHJpdiwgJmNtZFtpXSkpIHsKCQkJCURSTV9FUlJPUgoJCQkJICAgICgiSW52YWxpZCBvZmZzZXQgKGs9JWQgaT0lZCkgaW4gM0RfTE9BRF9WQlBOVFIgcGFja2V0LlxuIiwKCQkJCSAgICAgaywgaSk7CgkJCQlyZXR1cm4gRFJNX0VSUihFSU5WQUwpOwoJCQl9CgkJCWsrKzsKCQkJaSsrOwoJCX0KCQkvKiBkbyB0aGUgY291bnRzIG1hdGNoIHdoYXQgd2UgZXhwZWN0ID8gKi8KCQlpZiAoKGsgIT0gbmFycmF5cykgfHwgKGkgIT0gKGNvdW50ICsgMikpKSB7CgkJCURSTV9FUlJPUgoJCQkgICAgKCJNYWxmb3JtZWQgM0RfTE9BRF9WQlBOVFIgcGFja2V0IChrPSVkIGk9JWQgbmFycmF5cz0lZCBjb3VudCsxPSVkKS5cbiIsCgkJCSAgICAgIGssIGksIG5hcnJheXMsIGNvdW50ICsgMSk7CgkJCXJldHVybiBEUk1fRVJSKEVJTlZBTCk7CgkJfQoJCWJyZWFrOwoKCWNhc2UgUkFERU9OXzNEX1JORFJfR0VOX0lORFhfUFJJTToKCQlpZiAoZGV2X3ByaXYtPm1pY3JvY29kZV92ZXJzaW9uICE9IFVDT0RFX1IxMDApIHsKCQkJRFJNX0VSUk9SKCJJbnZhbGlkIDNkIHBhY2tldCBmb3IgcjIwMC1jbGFzcyBjaGlwXG4iKTsKCQkJcmV0dXJuIERSTV9FUlIoRUlOVkFMKTsKCQl9CgkJaWYgKHJhZGVvbl9jaGVja19hbmRfZml4dXBfb2Zmc2V0KGRldl9wcml2LCBmaWxwX3ByaXYsICZjbWRbMV0pKSB7CgkJCQlEUk1fRVJST1IoIkludmFsaWQgcm5kcl9nZW5faW5keCBvZmZzZXRcbiIpOwoJCQkJcmV0dXJuIERSTV9FUlIoRUlOVkFMKTsKCQl9CgkJYnJlYWs7CgoJY2FzZSBSQURFT05fQ1BfSU5EWF9CVUZGRVI6CgkJaWYgKGRldl9wcml2LT5taWNyb2NvZGVfdmVyc2lvbiAhPSBVQ09ERV9SMjAwKSB7CgkJCURSTV9FUlJPUigiSW52YWxpZCAzZCBwYWNrZXQgZm9yIHIxMDAtY2xhc3MgY2hpcFxuIik7CgkJCXJldHVybiBEUk1fRVJSKEVJTlZBTCk7CgkJfQoJCWlmICgoY21kWzFdICYgMHg4MDAwZmZmZikgIT0gMHg4MDAwMDgxMCkgewoJCQlEUk1fRVJST1IoIkludmFsaWQgaW5keF9idWZmZXIgcmVnIGFkZHJlc3MgJTA4WFxuIiwgY21kWzFdKTsKCQkJcmV0dXJuIERSTV9FUlIoRUlOVkFMKTsKCQl9CgkJaWYgKHJhZGVvbl9jaGVja19hbmRfZml4dXBfb2Zmc2V0KGRldl9wcml2LCBmaWxwX3ByaXYsICZjbWRbMl0pKSB7CgkJCURSTV9FUlJPUigiSW52YWxpZCBpbmR4X2J1ZmZlciBvZmZzZXQgaXMgJTA4WFxuIiwgY21kWzJdKTsKCQkJcmV0dXJuIERSTV9FUlIoRUlOVkFMKTsKCQl9CgkJYnJlYWs7CgoJY2FzZSBSQURFT05fQ05UTF9IT1NUREFUQV9CTFQ6CgljYXNlIFJBREVPTl9DTlRMX1BBSU5UX01VTFRJOgoJY2FzZSBSQURFT05fQ05UTF9CSVRCTFRfTVVMVEk6CgkJLyogTVNCIG9mIG9wY29kZTogbmV4dCBEV09SRCBHVUlfQ05UTCAqLwoJCWlmIChjbWRbMV0gJiAoUkFERU9OX0dNQ19TUkNfUElUQ0hfT0ZGU0VUX0NOVEwKCQkJICAgICAgfCBSQURFT05fR01DX0RTVF9QSVRDSF9PRkZTRVRfQ05UTCkpIHsKCQkJb2Zmc2V0ID0gY21kWzJdIDw8IDEwOwoJCQlpZiAocmFkZW9uX2NoZWNrX2FuZF9maXh1cF9vZmZzZXQKCQkJICAgIChkZXZfcHJpdiwgZmlscF9wcml2LCAmb2Zmc2V0KSkgewoJCQkJRFJNX0VSUk9SKCJJbnZhbGlkIGZpcnN0IHBhY2tldCBvZmZzZXRcbiIpOwoJCQkJcmV0dXJuIERSTV9FUlIoRUlOVkFMKTsKCQkJfQoJCQljbWRbMl0gPSAoY21kWzJdICYgMHhmZmMwMDAwMCkgfCBvZmZzZXQgPj4gMTA7CgkJfQoKCQlpZiAoKGNtZFsxXSAmIFJBREVPTl9HTUNfU1JDX1BJVENIX09GRlNFVF9DTlRMKSAmJgoJCSAgICAoY21kWzFdICYgUkFERU9OX0dNQ19EU1RfUElUQ0hfT0ZGU0VUX0NOVEwpKSB7CgkJCW9mZnNldCA9IGNtZFszXSA8PCAxMDsKCQkJaWYgKHJhZGVvbl9jaGVja19hbmRfZml4dXBfb2Zmc2V0CgkJCSAgICAoZGV2X3ByaXYsIGZpbHBfcHJpdiwgJm9mZnNldCkpIHsKCQkJCURSTV9FUlJPUigiSW52YWxpZCBzZWNvbmQgcGFja2V0IG9mZnNldFxuIik7CgkJCQlyZXR1cm4gRFJNX0VSUihFSU5WQUwpOwoJCQl9CgkJCWNtZFszXSA9IChjbWRbM10gJiAweGZmYzAwMDAwKSB8IG9mZnNldCA+PiAxMDsKCQl9CgkJYnJlYWs7CgoJZGVmYXVsdDoKCQlEUk1fRVJST1IoIkludmFsaWQgcGFja2V0IHR5cGUgJXhcbiIsIGNtZFswXSAmIDB4ZmYwMCk7CgkJcmV0dXJuIERSTV9FUlIoRUlOVkFMKTsKCX0KCglyZXR1cm4gMDsKfQoKLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKiBDUCBoYXJkd2FyZSBzdGF0ZSBwcm9ncmFtbWluZyBmdW5jdGlvbnMKICovCgpzdGF0aWMgX19pbmxpbmVfXyB2b2lkIHJhZGVvbl9lbWl0X2NsaXBfcmVjdChkcm1fcmFkZW9uX3ByaXZhdGVfdCAqIGRldl9wcml2LAoJCQkJCSAgICAgZHJtX2NsaXBfcmVjdF90ICogYm94KQp7CglSSU5HX0xPQ0FMUzsKCglEUk1fREVCVUcoIiAgIGJveDogIHgxPSVkIHkxPSVkICB4Mj0lZCB5Mj0lZFxuIiwKCQkgIGJveC0+eDEsIGJveC0+eTEsIGJveC0+eDIsIGJveC0+eTIpOwoKCUJFR0lOX1JJTkcoNCk7CglPVVRfUklORyhDUF9QQUNLRVQwKFJBREVPTl9SRV9UT1BfTEVGVCwgMCkpOwoJT1VUX1JJTkcoKGJveC0+eTEgPDwgMTYpIHwgYm94LT54MSk7CglPVVRfUklORyhDUF9QQUNLRVQwKFJBREVPTl9SRV9XSURUSF9IRUlHSFQsIDApKTsKCU9VVF9SSU5HKCgoYm94LT55MiAtIDEpIDw8IDE2KSB8IChib3gtPngyIC0gMSkpOwoJQURWQU5DRV9SSU5HKCk7Cn0KCi8qIEVtaXQgMS4xIHN0YXRlCiAqLwpzdGF0aWMgaW50IHJhZGVvbl9lbWl0X3N0YXRlKGRybV9yYWRlb25fcHJpdmF0ZV90ICogZGV2X3ByaXYsCgkJCSAgICAgZHJtX2ZpbGVfdCAqIGZpbHBfcHJpdiwKCQkJICAgICBkcm1fcmFkZW9uX2NvbnRleHRfcmVnc190ICogY3R4LAoJCQkgICAgIGRybV9yYWRlb25fdGV4dHVyZV9yZWdzX3QgKiB0ZXgsCgkJCSAgICAgdW5zaWduZWQgaW50IGRpcnR5KQp7CglSSU5HX0xPQ0FMUzsKCURSTV9ERUJVRygiZGlydHk9MHglMDh4XG4iLCBkaXJ0eSk7CgoJaWYgKGRpcnR5ICYgUkFERU9OX1VQTE9BRF9DT05URVhUKSB7CgkJaWYgKHJhZGVvbl9jaGVja19hbmRfZml4dXBfb2Zmc2V0KGRldl9wcml2LCBmaWxwX3ByaXYsCgkJCQkJCSAgJmN0eC0+cmIzZF9kZXB0aG9mZnNldCkpIHsKCQkJRFJNX0VSUk9SKCJJbnZhbGlkIGRlcHRoIGJ1ZmZlciBvZmZzZXRcbiIpOwoJCQlyZXR1cm4gRFJNX0VSUihFSU5WQUwpOwoJCX0KCgkJaWYgKHJhZGVvbl9jaGVja19hbmRfZml4dXBfb2Zmc2V0KGRldl9wcml2LCBmaWxwX3ByaXYsCgkJCQkJCSAgJmN0eC0+cmIzZF9jb2xvcm9mZnNldCkpIHsKCQkJRFJNX0VSUk9SKCJJbnZhbGlkIGRlcHRoIGJ1ZmZlciBvZmZzZXRcbiIpOwoJCQlyZXR1cm4gRFJNX0VSUihFSU5WQUwpOwoJCX0KCgkJQkVHSU5fUklORygxNCk7CgkJT1VUX1JJTkcoQ1BfUEFDS0VUMChSQURFT05fUFBfTUlTQywgNikpOwoJCU9VVF9SSU5HKGN0eC0+cHBfbWlzYyk7CgkJT1VUX1JJTkcoY3R4LT5wcF9mb2dfY29sb3IpOwoJCU9VVF9SSU5HKGN0eC0+cmVfc29saWRfY29sb3IpOwoJCU9VVF9SSU5HKGN0eC0+cmIzZF9ibGVuZGNudGwpOwoJCU9VVF9SSU5HKGN0eC0+cmIzZF9kZXB0aG9mZnNldCk7CgkJT1VUX1JJTkcoY3R4LT5yYjNkX2RlcHRocGl0Y2gpOwoJCU9VVF9SSU5HKGN0eC0+cmIzZF96c3RlbmNpbGNudGwpOwoJCU9VVF9SSU5HKENQX1BBQ0tFVDAoUkFERU9OX1BQX0NOVEwsIDIpKTsKCQlPVVRfUklORyhjdHgtPnBwX2NudGwpOwoJCU9VVF9SSU5HKGN0eC0+cmIzZF9jbnRsKTsKCQlPVVRfUklORyhjdHgtPnJiM2RfY29sb3JvZmZzZXQpOwoJCU9VVF9SSU5HKENQX1BBQ0tFVDAoUkFERU9OX1JCM0RfQ09MT1JQSVRDSCwgMCkpOwoJCU9VVF9SSU5HKGN0eC0+cmIzZF9jb2xvcnBpdGNoKTsKCQlBRFZBTkNFX1JJTkcoKTsKCX0KCglpZiAoZGlydHkgJiBSQURFT05fVVBMT0FEX1ZFUlRGTVQpIHsKCQlCRUdJTl9SSU5HKDIpOwoJCU9VVF9SSU5HKENQX1BBQ0tFVDAoUkFERU9OX1NFX0NPT1JEX0ZNVCwgMCkpOwoJCU9VVF9SSU5HKGN0eC0+c2VfY29vcmRfZm10KTsKCQlBRFZBTkNFX1JJTkcoKTsKCX0KCglpZiAoZGlydHkgJiBSQURFT05fVVBMT0FEX0xJTkUpIHsKCQlCRUdJTl9SSU5HKDUpOwoJCU9VVF9SSU5HKENQX1BBQ0tFVDAoUkFERU9OX1JFX0xJTkVfUEFUVEVSTiwgMSkpOwoJCU9VVF9SSU5HKGN0eC0+cmVfbGluZV9wYXR0ZXJuKTsKCQlPVVRfUklORyhjdHgtPnJlX2xpbmVfc3RhdGUpOwoJCU9VVF9SSU5HKENQX1BBQ0tFVDAoUkFERU9OX1NFX0xJTkVfV0lEVEgsIDApKTsKCQlPVVRfUklORyhjdHgtPnNlX2xpbmVfd2lkdGgpOwoJCUFEVkFOQ0VfUklORygpOwoJfQoKCWlmIChkaXJ0eSAmIFJBREVPTl9VUExPQURfQlVNUE1BUCkgewoJCUJFR0lOX1JJTkcoNSk7CgkJT1VUX1JJTkcoQ1BfUEFDS0VUMChSQURFT05fUFBfTFVNX01BVFJJWCwgMCkpOwoJCU9VVF9SSU5HKGN0eC0+cHBfbHVtX21hdHJpeCk7CgkJT1VUX1JJTkcoQ1BfUEFDS0VUMChSQURFT05fUFBfUk9UX01BVFJJWF8wLCAxKSk7CgkJT1VUX1JJTkcoY3R4LT5wcF9yb3RfbWF0cml4XzApOwoJCU9VVF9SSU5HKGN0eC0+cHBfcm90X21hdHJpeF8xKTsKCQlBRFZBTkNFX1JJTkcoKTsKCX0KCglpZiAoZGlydHkgJiBSQURFT05fVVBMT0FEX01BU0tTKSB7CgkJQkVHSU5fUklORyg0KTsKCQlPVVRfUklORyhDUF9QQUNLRVQwKFJBREVPTl9SQjNEX1NURU5DSUxSRUZNQVNLLCAyKSk7CgkJT1VUX1JJTkcoY3R4LT5yYjNkX3N0ZW5jaWxyZWZtYXNrKTsKCQlPVVRfUklORyhjdHgtPnJiM2Rfcm9wY250bCk7CgkJT1VUX1JJTkcoY3R4LT5yYjNkX3BsYW5lbWFzayk7CgkJQURWQU5DRV9SSU5HKCk7Cgl9CgoJaWYgKGRpcnR5ICYgUkFERU9OX1VQTE9BRF9WSUVXUE9SVCkgewoJCUJFR0lOX1JJTkcoNyk7CgkJT1VUX1JJTkcoQ1BfUEFDS0VUMChSQURFT05fU0VfVlBPUlRfWFNDQUxFLCA1KSk7CgkJT1VUX1JJTkcoY3R4LT5zZV92cG9ydF94c2NhbGUpOwoJCU9VVF9SSU5HKGN0eC0+c2VfdnBvcnRfeG9mZnNldCk7CgkJT1VUX1JJTkcoY3R4LT5zZV92cG9ydF95c2NhbGUpOwoJCU9VVF9SSU5HKGN0eC0+c2VfdnBvcnRfeW9mZnNldCk7CgkJT1VUX1JJTkcoY3R4LT5zZV92cG9ydF96c2NhbGUpOwoJCU9VVF9SSU5HKGN0eC0+c2VfdnBvcnRfem9mZnNldCk7CgkJQURWQU5DRV9SSU5HKCk7Cgl9CgoJaWYgKGRpcnR5ICYgUkFERU9OX1VQTE9BRF9TRVRVUCkgewoJCUJFR0lOX1JJTkcoNCk7CgkJT1VUX1JJTkcoQ1BfUEFDS0VUMChSQURFT05fU0VfQ05UTCwgMCkpOwoJCU9VVF9SSU5HKGN0eC0+c2VfY250bCk7CgkJT1VUX1JJTkcoQ1BfUEFDS0VUMChSQURFT05fU0VfQ05UTF9TVEFUVVMsIDApKTsKCQlPVVRfUklORyhjdHgtPnNlX2NudGxfc3RhdHVzKTsKCQlBRFZBTkNFX1JJTkcoKTsKCX0KCglpZiAoZGlydHkgJiBSQURFT05fVVBMT0FEX01JU0MpIHsKCQlCRUdJTl9SSU5HKDIpOwoJCU9VVF9SSU5HKENQX1BBQ0tFVDAoUkFERU9OX1JFX01JU0MsIDApKTsKCQlPVVRfUklORyhjdHgtPnJlX21pc2MpOwoJCUFEVkFOQ0VfUklORygpOwoJfQoKCWlmIChkaXJ0eSAmIFJBREVPTl9VUExPQURfVEVYMCkgewoJCWlmIChyYWRlb25fY2hlY2tfYW5kX2ZpeHVwX29mZnNldChkZXZfcHJpdiwgZmlscF9wcml2LAoJCQkJCQkgICZ0ZXhbMF0ucHBfdHhvZmZzZXQpKSB7CgkJCURSTV9FUlJPUigiSW52YWxpZCB0ZXh0dXJlIG9mZnNldCBmb3IgdW5pdCAwXG4iKTsKCQkJcmV0dXJuIERSTV9FUlIoRUlOVkFMKTsKCQl9CgoJCUJFR0lOX1JJTkcoOSk7CgkJT1VUX1JJTkcoQ1BfUEFDS0VUMChSQURFT05fUFBfVFhGSUxURVJfMCwgNSkpOwoJCU9VVF9SSU5HKHRleFswXS5wcF90eGZpbHRlcik7CgkJT1VUX1JJTkcodGV4WzBdLnBwX3R4Zm9ybWF0KTsKCQlPVVRfUklORyh0ZXhbMF0ucHBfdHhvZmZzZXQpOwoJCU9VVF9SSU5HKHRleFswXS5wcF90eGNibGVuZCk7CgkJT1VUX1JJTkcodGV4WzBdLnBwX3R4YWJsZW5kKTsKCQlPVVRfUklORyh0ZXhbMF0ucHBfdGZhY3Rvcik7CgkJT1VUX1JJTkcoQ1BfUEFDS0VUMChSQURFT05fUFBfQk9SREVSX0NPTE9SXzAsIDApKTsKCQlPVVRfUklORyh0ZXhbMF0ucHBfYm9yZGVyX2NvbG9yKTsKCQlBRFZBTkNFX1JJTkcoKTsKCX0KCglpZiAoZGlydHkgJiBSQURFT05fVVBMT0FEX1RFWDEpIHsKCQlpZiAocmFkZW9uX2NoZWNrX2FuZF9maXh1cF9vZmZzZXQoZGV2X3ByaXYsIGZpbHBfcHJpdiwKCQkJCQkJICAmdGV4WzFdLnBwX3R4b2Zmc2V0KSkgewoJCQlEUk1fRVJST1IoIkludmFsaWQgdGV4dHVyZSBvZmZzZXQgZm9yIHVuaXQgMVxuIik7CgkJCXJldHVybiBEUk1fRVJSKEVJTlZBTCk7CgkJfQoKCQlCRUdJTl9SSU5HKDkpOwoJCU9VVF9SSU5HKENQX1BBQ0tFVDAoUkFERU9OX1BQX1RYRklMVEVSXzEsIDUpKTsKCQlPVVRfUklORyh0ZXhbMV0ucHBfdHhmaWx0ZXIpOwoJCU9VVF9SSU5HKHRleFsxXS5wcF90eGZvcm1hdCk7CgkJT1VUX1JJTkcodGV4WzFdLnBwX3R4b2Zmc2V0KTsKCQlPVVRfUklORyh0ZXhbMV0ucHBfdHhjYmxlbmQpOwoJCU9VVF9SSU5HKHRleFsxXS5wcF90eGFibGVuZCk7CgkJT1VUX1JJTkcodGV4WzFdLnBwX3RmYWN0b3IpOwoJCU9VVF9SSU5HKENQX1BBQ0tFVDAoUkFERU9OX1BQX0JPUkRFUl9DT0xPUl8xLCAwKSk7CgkJT1VUX1JJTkcodGV4WzFdLnBwX2JvcmRlcl9jb2xvcik7CgkJQURWQU5DRV9SSU5HKCk7Cgl9CgoJaWYgKGRpcnR5ICYgUkFERU9OX1VQTE9BRF9URVgyKSB7CgkJaWYgKHJhZGVvbl9jaGVja19hbmRfZml4dXBfb2Zmc2V0KGRldl9wcml2LCBmaWxwX3ByaXYsCgkJCQkJCSAgJnRleFsyXS5wcF90eG9mZnNldCkpIHsKCQkJRFJNX0VSUk9SKCJJbnZhbGlkIHRleHR1cmUgb2Zmc2V0IGZvciB1bml0IDJcbiIpOwoJCQlyZXR1cm4gRFJNX0VSUihFSU5WQUwpOwoJCX0KCgkJQkVHSU5fUklORyg5KTsKCQlPVVRfUklORyhDUF9QQUNLRVQwKFJBREVPTl9QUF9UWEZJTFRFUl8yLCA1KSk7CgkJT1VUX1JJTkcodGV4WzJdLnBwX3R4ZmlsdGVyKTsKCQlPVVRfUklORyh0ZXhbMl0ucHBfdHhmb3JtYXQpOwoJCU9VVF9SSU5HKHRleFsyXS5wcF90eG9mZnNldCk7CgkJT1VUX1JJTkcodGV4WzJdLnBwX3R4Y2JsZW5kKTsKCQlPVVRfUklORyh0ZXhbMl0ucHBfdHhhYmxlbmQpOwoJCU9VVF9SSU5HKHRleFsyXS5wcF90ZmFjdG9yKTsKCQlPVVRfUklORyhDUF9QQUNLRVQwKFJBREVPTl9QUF9CT1JERVJfQ09MT1JfMiwgMCkpOwoJCU9VVF9SSU5HKHRleFsyXS5wcF9ib3JkZXJfY29sb3IpOwoJCUFEVkFOQ0VfUklORygpOwoJfQoKCXJldHVybiAwOwp9CgovKiBFbWl0IDEuMiBzdGF0ZQogKi8Kc3RhdGljIGludCByYWRlb25fZW1pdF9zdGF0ZTIoZHJtX3JhZGVvbl9wcml2YXRlX3QgKiBkZXZfcHJpdiwKCQkJICAgICAgZHJtX2ZpbGVfdCAqIGZpbHBfcHJpdiwKCQkJICAgICAgZHJtX3JhZGVvbl9zdGF0ZV90ICogc3RhdGUpCnsKCVJJTkdfTE9DQUxTOwoKCWlmIChzdGF0ZS0+ZGlydHkgJiBSQURFT05fVVBMT0FEX1pCSUFTKSB7CgkJQkVHSU5fUklORygzKTsKCQlPVVRfUklORyhDUF9QQUNLRVQwKFJBREVPTl9TRV9aQklBU19GQUNUT1IsIDEpKTsKCQlPVVRfUklORyhzdGF0ZS0+Y29udGV4dDIuc2VfemJpYXNfZmFjdG9yKTsKCQlPVVRfUklORyhzdGF0ZS0+Y29udGV4dDIuc2VfemJpYXNfY29uc3RhbnQpOwoJCUFEVkFOQ0VfUklORygpOwoJfQoKCXJldHVybiByYWRlb25fZW1pdF9zdGF0ZShkZXZfcHJpdiwgZmlscF9wcml2LCAmc3RhdGUtPmNvbnRleHQsCgkJCQkgc3RhdGUtPnRleCwgc3RhdGUtPmRpcnR5KTsKfQoKLyogTmV3ICgxLjMpIHN0YXRlIG1lY2hhbmlzbS4gIDMgY29tbWFuZHMgKHBhY2tldCwgc2NhbGFyLCB2ZWN0b3IpIGluCiAqIDEuMyBjbWRidWZmZXJzIGFsbG93IGFsbCBwcmV2aW91cyBzdGF0ZSB0byBiZSB1cGRhdGVkIGFzIHdlbGwgYXMKICogdGhlIHRjbCBzY2FsYXIgYW5kIHZlY3RvciBhcmVhcy4KICovCnN0YXRpYyBzdHJ1Y3QgewoJaW50IHN0YXJ0OwoJaW50IGxlbjsKCWNvbnN0IGNoYXIgKm5hbWU7Cn0gcGFja2V0W1JBREVPTl9NQVhfU1RBVEVfUEFDS0VUU10gPSB7Cgl7UkFERU9OX1BQX01JU0MsIDcsICJSQURFT05fUFBfTUlTQyJ9LAoJe1JBREVPTl9QUF9DTlRMLCAzLCAiUkFERU9OX1BQX0NOVEwifSwKCXtSQURFT05fUkIzRF9DT0xPUlBJVENILCAxLCAiUkFERU9OX1JCM0RfQ09MT1JQSVRDSCJ9LAoJe1JBREVPTl9SRV9MSU5FX1BBVFRFUk4sIDIsICJSQURFT05fUkVfTElORV9QQVRURVJOIn0sCgl7UkFERU9OX1NFX0xJTkVfV0lEVEgsIDEsICJSQURFT05fU0VfTElORV9XSURUSCJ9LAoJe1JBREVPTl9QUF9MVU1fTUFUUklYLCAxLCAiUkFERU9OX1BQX0xVTV9NQVRSSVgifSwKCXtSQURFT05fUFBfUk9UX01BVFJJWF8wLCAyLCAiUkFERU9OX1BQX1JPVF9NQVRSSVhfMCJ9LAoJe1JBREVPTl9SQjNEX1NURU5DSUxSRUZNQVNLLCAzLCAiUkFERU9OX1JCM0RfU1RFTkNJTFJFRk1BU0sifSwKCXtSQURFT05fU0VfVlBPUlRfWFNDQUxFLCA2LCAiUkFERU9OX1NFX1ZQT1JUX1hTQ0FMRSJ9LAoJe1JBREVPTl9TRV9DTlRMLCAyLCAiUkFERU9OX1NFX0NOVEwifSwKCXtSQURFT05fU0VfQ05UTF9TVEFUVVMsIDEsICJSQURFT05fU0VfQ05UTF9TVEFUVVMifSwKCXtSQURFT05fUkVfTUlTQywgMSwgIlJBREVPTl9SRV9NSVNDIn0sCgl7UkFERU9OX1BQX1RYRklMVEVSXzAsIDYsICJSQURFT05fUFBfVFhGSUxURVJfMCJ9LAoJe1JBREVPTl9QUF9CT1JERVJfQ09MT1JfMCwgMSwgIlJBREVPTl9QUF9CT1JERVJfQ09MT1JfMCJ9LAoJe1JBREVPTl9QUF9UWEZJTFRFUl8xLCA2LCAiUkFERU9OX1BQX1RYRklMVEVSXzEifSwKCXtSQURFT05fUFBfQk9SREVSX0NPTE9SXzEsIDEsICJSQURFT05fUFBfQk9SREVSX0NPTE9SXzEifSwKCXtSQURFT05fUFBfVFhGSUxURVJfMiwgNiwgIlJBREVPTl9QUF9UWEZJTFRFUl8yIn0sCgl7UkFERU9OX1BQX0JPUkRFUl9DT0xPUl8yLCAxLCAiUkFERU9OX1BQX0JPUkRFUl9DT0xPUl8yIn0sCgl7UkFERU9OX1NFX1pCSUFTX0ZBQ1RPUiwgMiwgIlJBREVPTl9TRV9aQklBU19GQUNUT1IifSwKCXtSQURFT05fU0VfVENMX09VVFBVVF9WVFhfRk1ULCAxMSwgIlJBREVPTl9TRV9UQ0xfT1VUUFVUX1ZUWF9GTVQifSwKCXtSQURFT05fU0VfVENMX01BVEVSSUFMX0VNTUlTU0lWRV9SRUQsIDE3LAoJCSAgICAiUkFERU9OX1NFX1RDTF9NQVRFUklBTF9FTU1JU1NJVkVfUkVEIn0sCgl7UjIwMF9QUF9UWENCTEVORF8wLCA0LCAiUjIwMF9QUF9UWENCTEVORF8wIn0sCgl7UjIwMF9QUF9UWENCTEVORF8xLCA0LCAiUjIwMF9QUF9UWENCTEVORF8xIn0sCgl7UjIwMF9QUF9UWENCTEVORF8yLCA0LCAiUjIwMF9QUF9UWENCTEVORF8yIn0sCgl7UjIwMF9QUF9UWENCTEVORF8zLCA0LCAiUjIwMF9QUF9UWENCTEVORF8zIn0sCgl7UjIwMF9QUF9UWENCTEVORF80LCA0LCAiUjIwMF9QUF9UWENCTEVORF80In0sCgl7UjIwMF9QUF9UWENCTEVORF81LCA0LCAiUjIwMF9QUF9UWENCTEVORF81In0sCgl7UjIwMF9QUF9UWENCTEVORF82LCA0LCAiUjIwMF9QUF9UWENCTEVORF82In0sCgl7UjIwMF9QUF9UWENCTEVORF83LCA0LCAiUjIwMF9QUF9UWENCTEVORF83In0sCgl7UjIwMF9TRV9UQ0xfTElHSFRfTU9ERUxfQ1RMXzAsIDYsICJSMjAwX1NFX1RDTF9MSUdIVF9NT0RFTF9DVExfMCJ9LAoJe1IyMDBfUFBfVEZBQ1RPUl8wLCA2LCAiUjIwMF9QUF9URkFDVE9SXzAifSwKCXtSMjAwX1NFX1ZUWF9GTVRfMCwgNCwgIlIyMDBfU0VfVlRYX0ZNVF8wIn0sCgl7UjIwMF9TRV9WQVBfQ05UTCwgMSwgIlIyMDBfU0VfVkFQX0NOVEwifSwKCXtSMjAwX1NFX1RDTF9NQVRSSVhfU0VMXzAsIDUsICJSMjAwX1NFX1RDTF9NQVRSSVhfU0VMXzAifSwKCXtSMjAwX1NFX1RDTF9URVhfUFJPQ19DVExfMiwgNSwgIlIyMDBfU0VfVENMX1RFWF9QUk9DX0NUTF8yIn0sCgl7UjIwMF9TRV9UQ0xfVUNQX1ZFUlRfQkxFTkRfQ1RMLCAxLCAiUjIwMF9TRV9UQ0xfVUNQX1ZFUlRfQkxFTkRfQ1RMIn0sCgl7UjIwMF9QUF9UWEZJTFRFUl8wLCA2LCAiUjIwMF9QUF9UWEZJTFRFUl8wIn0sCgl7UjIwMF9QUF9UWEZJTFRFUl8xLCA2LCAiUjIwMF9QUF9UWEZJTFRFUl8xIn0sCgl7UjIwMF9QUF9UWEZJTFRFUl8yLCA2LCAiUjIwMF9QUF9UWEZJTFRFUl8yIn0sCgl7UjIwMF9QUF9UWEZJTFRFUl8zLCA2LCAiUjIwMF9QUF9UWEZJTFRFUl8zIn0sCgl7UjIwMF9QUF9UWEZJTFRFUl80LCA2LCAiUjIwMF9QUF9UWEZJTFRFUl80In0sCgl7UjIwMF9QUF9UWEZJTFRFUl81LCA2LCAiUjIwMF9QUF9UWEZJTFRFUl81In0sCgl7UjIwMF9QUF9UWE9GRlNFVF8wLCAxLCAiUjIwMF9QUF9UWE9GRlNFVF8wIn0sCgl7UjIwMF9QUF9UWE9GRlNFVF8xLCAxLCAiUjIwMF9QUF9UWE9GRlNFVF8xIn0sCgl7UjIwMF9QUF9UWE9GRlNFVF8yLCAxLCAiUjIwMF9QUF9UWE9GRlNFVF8yIn0sCgl7UjIwMF9QUF9UWE9GRlNFVF8zLCAxLCAiUjIwMF9QUF9UWE9GRlNFVF8zIn0sCgl7UjIwMF9QUF9UWE9GRlNFVF80LCAxLCAiUjIwMF9QUF9UWE9GRlNFVF80In0sCgl7UjIwMF9QUF9UWE9GRlNFVF81LCAxLCAiUjIwMF9QUF9UWE9GRlNFVF81In0sCgl7UjIwMF9TRV9WVEVfQ05UTCwgMSwgIlIyMDBfU0VfVlRFX0NOVEwifSwKCXtSMjAwX1NFX1RDTF9PVVRQVVRfVlRYX0NPTVBfU0VMLCAxLAoJICJSMjAwX1NFX1RDTF9PVVRQVVRfVlRYX0NPTVBfU0VMIn0sCgl7UjIwMF9QUF9UQU1fREVCVUczLCAxLCAiUjIwMF9QUF9UQU1fREVCVUczIn0sCgl7UjIwMF9QUF9DTlRMX1gsIDEsICJSMjAwX1BQX0NOVExfWCJ9LAoJe1IyMDBfUkIzRF9ERVBUSFhZX09GRlNFVCwgMSwgIlIyMDBfUkIzRF9ERVBUSFhZX09GRlNFVCJ9LAoJe1IyMDBfUkVfQVVYX1NDSVNTT1JfQ05UTCwgMSwgIlIyMDBfUkVfQVVYX1NDSVNTT1JfQ05UTCJ9LAoJe1IyMDBfUkVfU0NJU1NPUl9UTF8wLCAyLCAiUjIwMF9SRV9TQ0lTU09SX1RMXzAifSwKCXtSMjAwX1JFX1NDSVNTT1JfVExfMSwgMiwgIlIyMDBfUkVfU0NJU1NPUl9UTF8xIn0sCgl7UjIwMF9SRV9TQ0lTU09SX1RMXzIsIDIsICJSMjAwX1JFX1NDSVNTT1JfVExfMiJ9LAoJe1IyMDBfU0VfVkFQX0NOVExfU1RBVFVTLCAxLCAiUjIwMF9TRV9WQVBfQ05UTF9TVEFUVVMifSwKCXtSMjAwX1NFX1ZUWF9TVEFURV9DTlRMLCAxLCAiUjIwMF9TRV9WVFhfU1RBVEVfQ05UTCJ9LAoJe1IyMDBfUkVfUE9JTlRTSVpFLCAxLCAiUjIwMF9SRV9QT0lOVFNJWkUifSwKCXtSMjAwX1NFX1RDTF9JTlBVVF9WVFhfVkVDVE9SX0FERFJfMCwgNCwKCQkgICAgIlIyMDBfU0VfVENMX0lOUFVUX1ZUWF9WRUNUT1JfQUREUl8wIn0sCgl7UjIwMF9QUF9DVUJJQ19GQUNFU18wLCAxLCAiUjIwMF9QUF9DVUJJQ19GQUNFU18wIn0sCS8qIDYxICovCgl7UjIwMF9QUF9DVUJJQ19PRkZTRVRfRjFfMCwgNSwgIlIyMDBfUFBfQ1VCSUNfT0ZGU0VUX0YxXzAifSwgLyogNjIgKi8KCXtSMjAwX1BQX0NVQklDX0ZBQ0VTXzEsIDEsICJSMjAwX1BQX0NVQklDX0ZBQ0VTXzEifSwKCXtSMjAwX1BQX0NVQklDX09GRlNFVF9GMV8xLCA1LCAiUjIwMF9QUF9DVUJJQ19PRkZTRVRfRjFfMSJ9LAoJe1IyMDBfUFBfQ1VCSUNfRkFDRVNfMiwgMSwgIlIyMDBfUFBfQ1VCSUNfRkFDRVNfMiJ9LAoJe1IyMDBfUFBfQ1VCSUNfT0ZGU0VUX0YxXzIsIDUsICJSMjAwX1BQX0NVQklDX09GRlNFVF9GMV8yIn0sCgl7UjIwMF9QUF9DVUJJQ19GQUNFU18zLCAxLCAiUjIwMF9QUF9DVUJJQ19GQUNFU18zIn0sCgl7UjIwMF9QUF9DVUJJQ19PRkZTRVRfRjFfMywgNSwgIlIyMDBfUFBfQ1VCSUNfT0ZGU0VUX0YxXzMifSwKCXtSMjAwX1BQX0NVQklDX0ZBQ0VTXzQsIDEsICJSMjAwX1BQX0NVQklDX0ZBQ0VTXzQifSwKCXtSMjAwX1BQX0NVQklDX09GRlNFVF9GMV80LCA1LCAiUjIwMF9QUF9DVUJJQ19PRkZTRVRfRjFfNCJ9LAoJe1IyMDBfUFBfQ1VCSUNfRkFDRVNfNSwgMSwgIlIyMDBfUFBfQ1VCSUNfRkFDRVNfNSJ9LAoJe1IyMDBfUFBfQ1VCSUNfT0ZGU0VUX0YxXzUsIDUsICJSMjAwX1BQX0NVQklDX09GRlNFVF9GMV81In0sCgl7UkFERU9OX1BQX1RFWF9TSVpFXzAsIDIsICJSQURFT05fUFBfVEVYX1NJWkVfMCJ9LAoJe1JBREVPTl9QUF9URVhfU0laRV8xLCAyLCAiUkFERU9OX1BQX1RFWF9TSVpFXzEifSwKCXtSQURFT05fUFBfVEVYX1NJWkVfMiwgMiwgIlJBREVPTl9QUF9URVhfU0laRV8yIn0sCgl7UjIwMF9SQjNEX0JMRU5EQ09MT1IsIDMsICJSMjAwX1JCM0RfQkxFTkRDT0xPUiJ9LAoJe1IyMDBfU0VfVENMX1BPSU5UX1NQUklURV9DTlRMLCAxLCAiUjIwMF9TRV9UQ0xfUE9JTlRfU1BSSVRFX0NOVEwifSwKCXtSQURFT05fUFBfQ1VCSUNfRkFDRVNfMCwgMSwgIlJBREVPTl9QUF9DVUJJQ19GQUNFU18wIn0sCgl7UkFERU9OX1BQX0NVQklDX09GRlNFVF9UMF8wLCA1LCAiUkFERU9OX1BQX0NVQklDX09GRlNFVF9UMF8wIn0sCgl7UkFERU9OX1BQX0NVQklDX0ZBQ0VTXzEsIDEsICJSQURFT05fUFBfQ1VCSUNfRkFDRVNfMSJ9LAoJe1JBREVPTl9QUF9DVUJJQ19PRkZTRVRfVDFfMCwgNSwgIlJBREVPTl9QUF9DVUJJQ19PRkZTRVRfVDFfMCJ9LAoJe1JBREVPTl9QUF9DVUJJQ19GQUNFU18yLCAxLCAiUkFERU9OX1BQX0NVQklDX0ZBQ0VTXzIifSwKCXtSQURFT05fUFBfQ1VCSUNfT0ZGU0VUX1QyXzAsIDUsICJSQURFT05fUFBfQ1VCSUNfT0ZGU0VUX1QyXzAifSwKCXtSMjAwX1BQX1RSSV9QRVJGLCAyLCAiUjIwMF9QUF9UUklfUEVSRiJ9LAoJe1IyMDBfUFBfQUZTXzAsIDMyLCAiUjIwMF9QUF9BRlNfMCJ9LCAgICAgLyogODUgKi8KCXtSMjAwX1BQX0FGU18xLCAzMiwgIlIyMDBfUFBfQUZTXzEifSwKCXtSMjAwX1BQX1RGQUNUT1JfMCwgOCwgIlIyMDBfQVRGX1RGQUNUT1IifSwKCXtSMjAwX1BQX1RYRklMVEVSXzAsIDgsICJSMjAwX1BQX1RYQ1RMQUxMXzAifSwKCXtSMjAwX1BQX1RYRklMVEVSXzEsIDgsICJSMjAwX1BQX1RYQ1RMQUxMXzEifSwKCXtSMjAwX1BQX1RYRklMVEVSXzIsIDgsICJSMjAwX1BQX1RYQ1RMQUxMXzIifSwKCXtSMjAwX1BQX1RYRklMVEVSXzMsIDgsICJSMjAwX1BQX1RYQ1RMQUxMXzMifSwKCXtSMjAwX1BQX1RYRklMVEVSXzQsIDgsICJSMjAwX1BQX1RYQ1RMQUxMXzQifSwKCXtSMjAwX1BQX1RYRklMVEVSXzUsIDgsICJSMjAwX1BQX1RYQ1RMQUxMXzUifSwKCXtSMjAwX1ZBUF9QVlNfQ05UTF8xLCAyLCAiUjIwMF9WQVBfUFZTX0NOVEwifSwKfTsKCi8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICogUGVyZm9ybWFuY2UgbW9uaXRvcmluZyBmdW5jdGlvbnMKICovCgpzdGF0aWMgdm9pZCByYWRlb25fY2xlYXJfYm94KGRybV9yYWRlb25fcHJpdmF0ZV90ICogZGV2X3ByaXYsCgkJCSAgICAgaW50IHgsIGludCB5LCBpbnQgdywgaW50IGgsIGludCByLCBpbnQgZywgaW50IGIpCnsKCXUzMiBjb2xvcjsKCVJJTkdfTE9DQUxTOwoKCXggKz0gZGV2X3ByaXYtPnNhcmVhX3ByaXYtPmJveGVzWzBdLngxOwoJeSArPSBkZXZfcHJpdi0+c2FyZWFfcHJpdi0+Ym94ZXNbMF0ueTE7CgoJc3dpdGNoIChkZXZfcHJpdi0+Y29sb3JfZm10KSB7CgljYXNlIFJBREVPTl9DT0xPUl9GT1JNQVRfUkdCNTY1OgoJCWNvbG9yID0gKCgociAmIDB4ZjgpIDw8IDgpIHwKCQkJICgoZyAmIDB4ZmMpIDw8IDMpIHwgKChiICYgMHhmOCkgPj4gMykpOwoJCWJyZWFrOwoJY2FzZSBSQURFT05fQ09MT1JfRk9STUFUX0FSR0I4ODg4OgoJZGVmYXVsdDoKCQljb2xvciA9ICgoKDB4ZmYpIDw8IDI0KSB8IChyIDw8IDE2KSB8IChnIDw8IDgpIHwgYik7CgkJYnJlYWs7Cgl9CgoJQkVHSU5fUklORyg0KTsKCVJBREVPTl9XQUlUX1VOVElMXzNEX0lETEUoKTsKCU9VVF9SSU5HKENQX1BBQ0tFVDAoUkFERU9OX0RQX1dSSVRFX01BU0ssIDApKTsKCU9VVF9SSU5HKDB4ZmZmZmZmZmYpOwoJQURWQU5DRV9SSU5HKCk7CgoJQkVHSU5fUklORyg2KTsKCglPVVRfUklORyhDUF9QQUNLRVQzKFJBREVPTl9DTlRMX1BBSU5UX01VTFRJLCA0KSk7CglPVVRfUklORyhSQURFT05fR01DX0RTVF9QSVRDSF9PRkZTRVRfQ05UTCB8CgkJIFJBREVPTl9HTUNfQlJVU0hfU09MSURfQ09MT1IgfAoJCSAoZGV2X3ByaXYtPmNvbG9yX2ZtdCA8PCA4KSB8CgkJIFJBREVPTl9HTUNfU1JDX0RBVEFUWVBFX0NPTE9SIHwKCQkgUkFERU9OX1JPUDNfUCB8IFJBREVPTl9HTUNfQ0xSX0NNUF9DTlRMX0RJUyk7CgoJaWYgKGRldl9wcml2LT5wYWdlX2ZsaXBwaW5nICYmIGRldl9wcml2LT5jdXJyZW50X3BhZ2UgPT0gMSkgewoJCU9VVF9SSU5HKGRldl9wcml2LT5mcm9udF9waXRjaF9vZmZzZXQpOwoJfSBlbHNlIHsKCQlPVVRfUklORyhkZXZfcHJpdi0+YmFja19waXRjaF9vZmZzZXQpOwoJfQoKCU9VVF9SSU5HKGNvbG9yKTsKCglPVVRfUklORygoeCA8PCAxNikgfCB5KTsKCU9VVF9SSU5HKCh3IDw8IDE2KSB8IGgpOwoKCUFEVkFOQ0VfUklORygpOwp9CgpzdGF0aWMgdm9pZCByYWRlb25fY3BfcGVyZm9ybWFuY2VfYm94ZXMoZHJtX3JhZGVvbl9wcml2YXRlX3QgKiBkZXZfcHJpdikKewoJLyogQ29sbGFwc2UgdmFyaW91cyB0aGluZ3MgaW50byBhIHdhaXQgZmxhZyAtLSB0cnlpbmcgdG8KCSAqIGd1ZXNzIGlmIHVzZXJzcGFzZSBzbGVwdCAtLSBiZXR0ZXIganVzdCB0byBoYXZlIHRoZW0gdGVsbCB1cy4KCSAqLwoJaWYgKGRldl9wcml2LT5zdGF0cy5sYXN0X2ZyYW1lX3JlYWRzID4gMSB8fAoJICAgIGRldl9wcml2LT5zdGF0cy5sYXN0X2NsZWFyX3JlYWRzID4gZGV2X3ByaXYtPnN0YXRzLmNsZWFycykgewoJCWRldl9wcml2LT5zdGF0cy5ib3hlcyB8PSBSQURFT05fQk9YX1dBSVRfSURMRTsKCX0KCglpZiAoZGV2X3ByaXYtPnN0YXRzLmZyZWVsaXN0X2xvb3BzKSB7CgkJZGV2X3ByaXYtPnN0YXRzLmJveGVzIHw9IFJBREVPTl9CT1hfV0FJVF9JRExFOwoJfQoKCS8qIFB1cnBsZSBib3ggZm9yIHBhZ2UgZmxpcHBpbmcKCSAqLwoJaWYgKGRldl9wcml2LT5zdGF0cy5ib3hlcyAmIFJBREVPTl9CT1hfRkxJUCkKCQlyYWRlb25fY2xlYXJfYm94KGRldl9wcml2LCA0LCA0LCA4LCA4LCAyNTUsIDAsIDI1NSk7CgoJLyogUmVkIGJveCBpZiB3ZSBoYXZlIHRvIHdhaXQgZm9yIGlkbGUgYXQgYW55IHBvaW50CgkgKi8KCWlmIChkZXZfcHJpdi0+c3RhdHMuYm94ZXMgJiBSQURFT05fQk9YX1dBSVRfSURMRSkKCQlyYWRlb25fY2xlYXJfYm94KGRldl9wcml2LCAxNiwgNCwgOCwgOCwgMjU1LCAwLCAwKTsKCgkvKiBCbHVlIGJveDogbG9zdCBjb250ZXh0PwoJICovCgoJLyogWWVsbG93IGJveCBmb3IgdGV4dHVyZSBzd2FwcwoJICovCglpZiAoZGV2X3ByaXYtPnN0YXRzLmJveGVzICYgUkFERU9OX0JPWF9URVhUVVJFX0xPQUQpCgkJcmFkZW9uX2NsZWFyX2JveChkZXZfcHJpdiwgNDAsIDQsIDgsIDgsIDI1NSwgMjU1LCAwKTsKCgkvKiBHcmVlbiBib3ggaWYgaGFyZHdhcmUgbmV2ZXIgaWRsZXMgKGFzIGZhciBhcyB3ZSBjYW4gdGVsbCkKCSAqLwoJaWYgKCEoZGV2X3ByaXYtPnN0YXRzLmJveGVzICYgUkFERU9OX0JPWF9ETUFfSURMRSkpCgkJcmFkZW9uX2NsZWFyX2JveChkZXZfcHJpdiwgNjQsIDQsIDgsIDgsIDAsIDI1NSwgMCk7CgoJLyogRHJhdyBiYXJzIGluZGljYXRpbmcgbnVtYmVyIG9mIGJ1ZmZlcnMgYWxsb2NhdGVkCgkgKiAobm90IGEgZ3JlYXQgbWVhc3VyZSwgZWFzaWx5IGNvbmZ1c2VkKQoJICovCglpZiAoZGV2X3ByaXYtPnN0YXRzLnJlcXVlc3RlZF9idWZzKSB7CgkJaWYgKGRldl9wcml2LT5zdGF0cy5yZXF1ZXN0ZWRfYnVmcyA+IDEwMCkKCQkJZGV2X3ByaXYtPnN0YXRzLnJlcXVlc3RlZF9idWZzID0gMTAwOwoKCQlyYWRlb25fY2xlYXJfYm94KGRldl9wcml2LCA0LCAxNiwKCQkJCSBkZXZfcHJpdi0+c3RhdHMucmVxdWVzdGVkX2J1ZnMsIDQsCgkJCQkgMTk2LCAxMjgsIDEyOCk7Cgl9CgoJbWVtc2V0KCZkZXZfcHJpdi0+c3RhdHMsIDAsIHNpemVvZihkZXZfcHJpdi0+c3RhdHMpKTsKCn0KCi8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICogQ1AgY29tbWFuZCBkaXNwYXRjaCBmdW5jdGlvbnMKICovCgpzdGF0aWMgdm9pZCByYWRlb25fY3BfZGlzcGF0Y2hfY2xlYXIoZHJtX2RldmljZV90ICogZGV2LAoJCQkJICAgICBkcm1fcmFkZW9uX2NsZWFyX3QgKiBjbGVhciwKCQkJCSAgICAgZHJtX3JhZGVvbl9jbGVhcl9yZWN0X3QgKiBkZXB0aF9ib3hlcykKewoJZHJtX3JhZGVvbl9wcml2YXRlX3QgKmRldl9wcml2ID0gZGV2LT5kZXZfcHJpdmF0ZTsKCWRybV9yYWRlb25fc2FyZWFfdCAqc2FyZWFfcHJpdiA9IGRldl9wcml2LT5zYXJlYV9wcml2OwoJZHJtX3JhZGVvbl9kZXB0aF9jbGVhcl90ICpkZXB0aF9jbGVhciA9ICZkZXZfcHJpdi0+ZGVwdGhfY2xlYXI7CglpbnQgbmJveCA9IHNhcmVhX3ByaXYtPm5ib3g7Cglkcm1fY2xpcF9yZWN0X3QgKnBib3ggPSBzYXJlYV9wcml2LT5ib3hlczsKCXVuc2lnbmVkIGludCBmbGFncyA9IGNsZWFyLT5mbGFnczsKCXUzMiByYjNkX2NudGwgPSAwLCByYjNkX3N0ZW5jaWxyZWZtYXNrID0gMDsKCWludCBpOwoJUklOR19MT0NBTFM7CglEUk1fREVCVUcoImZsYWdzID0gMHgleFxuIiwgZmxhZ3MpOwoKCWRldl9wcml2LT5zdGF0cy5jbGVhcnMrKzsKCglpZiAoZGV2X3ByaXYtPnBhZ2VfZmxpcHBpbmcgJiYgZGV2X3ByaXYtPmN1cnJlbnRfcGFnZSA9PSAxKSB7CgkJdW5zaWduZWQgaW50IHRtcCA9IGZsYWdzOwoKCQlmbGFncyAmPSB+KFJBREVPTl9GUk9OVCB8IFJBREVPTl9CQUNLKTsKCQlpZiAodG1wICYgUkFERU9OX0ZST05UKQoJCQlmbGFncyB8PSBSQURFT05fQkFDSzsKCQlpZiAodG1wICYgUkFERU9OX0JBQ0spCgkJCWZsYWdzIHw9IFJBREVPTl9GUk9OVDsKCX0KCglpZiAoZmxhZ3MgJiAoUkFERU9OX0ZST05UIHwgUkFERU9OX0JBQ0spKSB7CgoJCUJFR0lOX1JJTkcoNCk7CgoJCS8qIEVuc3VyZSB0aGUgM0Qgc3RyZWFtIGlzIGlkbGUgYmVmb3JlIGRvaW5nIGEKCQkgKiAyRCBmaWxsIHRvIGNsZWFyIHRoZSBmcm9udCBvciBiYWNrIGJ1ZmZlci4KCQkgKi8KCQlSQURFT05fV0FJVF9VTlRJTF8zRF9JRExFKCk7CgoJCU9VVF9SSU5HKENQX1BBQ0tFVDAoUkFERU9OX0RQX1dSSVRFX01BU0ssIDApKTsKCQlPVVRfUklORyhjbGVhci0+Y29sb3JfbWFzayk7CgoJCUFEVkFOQ0VfUklORygpOwoKCQkvKiBNYWtlIHN1cmUgd2UgcmVzdG9yZSB0aGUgM0Qgc3RhdGUgbmV4dCB0aW1lLgoJCSAqLwoJCWRldl9wcml2LT5zYXJlYV9wcml2LT5jdHhfb3duZXIgPSAwOwoKCQlmb3IgKGkgPSAwOyBpIDwgbmJveDsgaSsrKSB7CgkJCWludCB4ID0gcGJveFtpXS54MTsKCQkJaW50IHkgPSBwYm94W2ldLnkxOwoJCQlpbnQgdyA9IHBib3hbaV0ueDIgLSB4OwoJCQlpbnQgaCA9IHBib3hbaV0ueTIgLSB5OwoKCQkJRFJNX0RFQlVHKCJkaXNwYXRjaCBjbGVhciAlZCwlZC0lZCwlZCBmbGFncyAweCV4XG4iLAoJCQkJICB4LCB5LCB3LCBoLCBmbGFncyk7CgoJCQlpZiAoZmxhZ3MgJiBSQURFT05fRlJPTlQpIHsKCQkJCUJFR0lOX1JJTkcoNik7CgoJCQkJT1VUX1JJTkcoQ1BfUEFDS0VUMwoJCQkJCSAoUkFERU9OX0NOVExfUEFJTlRfTVVMVEksIDQpKTsKCQkJCU9VVF9SSU5HKFJBREVPTl9HTUNfRFNUX1BJVENIX09GRlNFVF9DTlRMIHwKCQkJCQkgUkFERU9OX0dNQ19CUlVTSF9TT0xJRF9DT0xPUiB8CgkJCQkJIChkZXZfcHJpdi0+CgkJCQkJICBjb2xvcl9mbXQgPDwgOCkgfAoJCQkJCSBSQURFT05fR01DX1NSQ19EQVRBVFlQRV9DT0xPUiB8CgkJCQkJIFJBREVPTl9ST1AzX1AgfAoJCQkJCSBSQURFT05fR01DX0NMUl9DTVBfQ05UTF9ESVMpOwoKCQkJCU9VVF9SSU5HKGRldl9wcml2LT5mcm9udF9waXRjaF9vZmZzZXQpOwoJCQkJT1VUX1JJTkcoY2xlYXItPmNsZWFyX2NvbG9yKTsKCgkJCQlPVVRfUklORygoeCA8PCAxNikgfCB5KTsKCQkJCU9VVF9SSU5HKCh3IDw8IDE2KSB8IGgpOwoKCQkJCUFEVkFOQ0VfUklORygpOwoJCQl9CgoJCQlpZiAoZmxhZ3MgJiBSQURFT05fQkFDSykgewoJCQkJQkVHSU5fUklORyg2KTsKCgkJCQlPVVRfUklORyhDUF9QQUNLRVQzCgkJCQkJIChSQURFT05fQ05UTF9QQUlOVF9NVUxUSSwgNCkpOwoJCQkJT1VUX1JJTkcoUkFERU9OX0dNQ19EU1RfUElUQ0hfT0ZGU0VUX0NOVEwgfAoJCQkJCSBSQURFT05fR01DX0JSVVNIX1NPTElEX0NPTE9SIHwKCQkJCQkgKGRldl9wcml2LT4KCQkJCQkgIGNvbG9yX2ZtdCA8PCA4KSB8CgkJCQkJIFJBREVPTl9HTUNfU1JDX0RBVEFUWVBFX0NPTE9SIHwKCQkJCQkgUkFERU9OX1JPUDNfUCB8CgkJCQkJIFJBREVPTl9HTUNfQ0xSX0NNUF9DTlRMX0RJUyk7CgoJCQkJT1VUX1JJTkcoZGV2X3ByaXYtPmJhY2tfcGl0Y2hfb2Zmc2V0KTsKCQkJCU9VVF9SSU5HKGNsZWFyLT5jbGVhcl9jb2xvcik7CgoJCQkJT1VUX1JJTkcoKHggPDwgMTYpIHwgeSk7CgkJCQlPVVRfUklORygodyA8PCAxNikgfCBoKTsKCgkJCQlBRFZBTkNFX1JJTkcoKTsKCQkJfQoJCX0KCX0KCgkvKiBoeXBlciB6IGNsZWFyICovCgkvKiBubyBkb2NzIGF2YWlsYWJsZSwgYmFzZWQgb24gcmV2ZXJzZSBlbmdlbmVlcmluZyBieSBTdGVwaGFuZSBNYXJjaGVzaW4gKi8KCWlmICgoZmxhZ3MgJiAoUkFERU9OX0RFUFRIIHwgUkFERU9OX1NURU5DSUwpKQoJICAgICYmIChmbGFncyAmIFJBREVPTl9DTEVBUl9GQVNUWikpIHsKCgkJaW50IGk7CgkJaW50IGRlcHRocGl4cGVybGluZSA9CgkJICAgIGRldl9wcml2LT5kZXB0aF9mbXQgPT0KCQkgICAgUkFERU9OX0RFUFRIX0ZPUk1BVF8xNkJJVF9JTlRfWiA/IChkZXZfcHJpdi0+ZGVwdGhfcGl0Y2ggLwoJCQkJCQkgICAgICAgMikgOiAoZGV2X3ByaXYtPgoJCQkJCQkJICAgICBkZXB0aF9waXRjaCAvIDQpOwoKCQl1MzIgY2xlYXJtYXNrOwoKCQl1MzIgdGVtcFJCM0RfREVQVEhDTEVBUlZBTFVFID0gY2xlYXItPmNsZWFyX2RlcHRoIHwKCQkgICAgKChjbGVhci0+ZGVwdGhfbWFzayAmIDB4ZmYpIDw8IDI0KTsKCgkJLyogTWFrZSBzdXJlIHdlIHJlc3RvcmUgdGhlIDNEIHN0YXRlIG5leHQgdGltZS4KCQkgKiB3ZSBoYXZlbid0IHRvdWNoZWQgYW55ICJub3JtYWwiIHN0YXRlIC0gc3RpbGwgbmVlZCB0aGlzPwoJCSAqLwoJCWRldl9wcml2LT5zYXJlYV9wcml2LT5jdHhfb3duZXIgPSAwOwoKCQlpZiAoKGRldl9wcml2LT5mbGFncyAmIFJBREVPTl9IQVNfSElFUlopCgkJICAgICYmIChmbGFncyAmIFJBREVPTl9VU0VfSElFUlopKSB7CgkJCS8qIEZJWE1FIDogcmV2ZXJzZSBlbmdpbmVlciB0aGF0IGZvciBSeDAwIGNhcmRzICovCgkJCS8qIEZJWE1FIDogdGhlIG1hc2sgc3VwcG9zZWRseSBjb250YWlucyBsb3ctcmVzIHogdmFsdWVzLiBTbyBjYW4ndCBzZXQKCQkJICAganVzdCB0byB0aGUgbWF4ICgweGZmPyBvciBhY3R1YWxseSAweDNmZmY/KSwgbmVlZCB0byB0YWtlIHogY2xlYXIKCQkJICAgdmFsdWUgaW50byBhY2NvdW50PyAqLwoJCQkvKiBwYXR0ZXJuIHNlZW1zIHRvIHdvcmsgZm9yIHIxMDAsIHRob3VnaCBnZXQgc2xpZ2h0CgkJCSAgIHJlbmRlcmluZyBlcnJvcnMgd2l0aCBnbHhnZWFycy4gSWYgaGllcnogaXMgbm90IGVuYWJsZWQgZm9yIHIxMDAsCgkJCSAgIG9ubHkgNCBiaXRzIHdoaWNoIGluZGljYXRlIGNsZWFyICgxNSwxNiwzMSwzMiwgYWxsIHplcm8pIG1hdHRlciwgdGhlCgkJCSAgIG90aGVyIG9uZXMgYXJlIGlnbm9yZWQsIGFuZCB0aGUgc2FtZSBjbGVhciBtYXNrIGNhbiBiZSB1c2VkLiBUaGF0J3MKCQkJICAgdmVyeSBkaWZmZXJlbnQgYmVoYXZpb3VyIHRoYW4gUjIwMCB3aGljaCBuZWVkcyBkaWZmZXJlbnQgY2xlYXIgbWFzawoJCQkgICBhbmQgZGlmZmVyZW50IG51bWJlciBvZiB0aWxlcyB0byBjbGVhciBpZiBoaWVyeiBpcyBlbmFibGVkIG9yIG5vdCAhPyEKCQkJICovCgkJCWNsZWFybWFzayA9ICgweGZmIDw8IDIyKSB8ICgweGZmIDw8IDYpIHwgMHgwMDNmMDAzZjsKCQl9IGVsc2UgewoJCQkvKiBjbGVhciBtYXNrIDogY2hvb3NlcyB0aGUgY2xlYXJpbmcgcGF0dGVybi4KCQkJICAgcnYyNTA6IGNvdWxkIGJlIHVzZWQgdG8gY2xlYXIgb25seSBwYXJ0cyBvZiBtYWNyb3RpbGVzCgkJCSAgIChidXQgdGhhdCB3b3VsZCBnZXQgcmVhbGx5IGNvbXBsaWNhdGVkLi4uKT8KCQkJICAgYml0IDAgYW5kIDEgKGVpdGhlciBvciBib3RoIG9mIHRoZW0gPyE/ISkgYXJlIHVzZWQgdG8KCQkJICAgbm90IGNsZWFyIHRpbGUgKG9yIG1heWJlIG9uZSBvZiB0aGUgYml0cyBpbmRpY2F0ZXMgaWYgdGhlIHRpbGUgaXMKCQkJICAgY29tcHJlc3NlZCBvciBub3QpLCBiaXQgMiBhbmQgMyB0byBub3QgY2xlYXIgdGlsZSAxLC4uLiwuCgkJCSAgIFBhdHRlcm4gaXMgYXMgZm9sbG93czoKCQkJICAgfCAwLDEgfCA0LDUgfCA4LDkgfDEyLDEzfDE2LDE3fDIwLDIxfDI0LDI1fDI4LDI5fAoJCQkgICBiaXRzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCQkJICAgfCAyLDMgfCA2LDcgfDEwLDExfDE0LDE1fDE4LDE5fDIyLDIzfDI2LDI3fDMwLDMxfAoJCQkgICBydjEwMDogY2xlYXJtYXNrIGNvdmVycyAyeDggNHgxIHRpbGVzLCBidXQgb25lIGNsZWFyIHN0aWxsCgkJCSAgIGNvdmVycyAyNTYgcGl4ZWxzID8hPwoJCQkgKi8KCQkJY2xlYXJtYXNrID0gMHgwOwoJCX0KCgkJQkVHSU5fUklORyg4KTsKCQlSQURFT05fV0FJVF9VTlRJTF8yRF9JRExFKCk7CgkJT1VUX1JJTkdfUkVHKFJBREVPTl9SQjNEX0RFUFRIQ0xFQVJWQUxVRSwKCQkJICAgICB0ZW1wUkIzRF9ERVBUSENMRUFSVkFMVUUpOwoJCS8qIHdoYXQgb2Zmc2V0IGlzIHRoaXMgZXhhY3RseSA/ICovCgkJT1VUX1JJTkdfUkVHKFJBREVPTl9SQjNEX1pNQVNLT0ZGU0VULCAwKTsKCQkvKiBuZWVkIGN0bHN0YXQsIG90aGVyd2lzZSBnZXQgc29tZSBzdHJhbmdlIGJsYWNrIGZsaWNrZXJpbmcgKi8KCQlPVVRfUklOR19SRUcoUkFERU9OX1JCM0RfWkNBQ0hFX0NUTFNUQVQsCgkJCSAgICAgUkFERU9OX1JCM0RfWkNfRkxVU0hfQUxMKTsKCQlBRFZBTkNFX1JJTkcoKTsKCgkJZm9yIChpID0gMDsgaSA8IG5ib3g7IGkrKykgewoJCQlpbnQgdGlsZW9mZnNldCwgbnJ0aWxlc3gsIG5ydGlsZXN5LCBqOwoJCQkvKiBpdCBsb29rcyBsaWtlIHIyMDAgbmVlZHMgcnYtc3R5bGUgY2xlYXJzLCBhdCBsZWFzdCBpZiBoaWVyeiBpcyBub3QgZW5hYmxlZD8gKi8KCQkJaWYgKChkZXZfcHJpdi0+ZmxhZ3MgJiBSQURFT05fSEFTX0hJRVJaKQoJCQkgICAgJiYgIShkZXZfcHJpdi0+bWljcm9jb2RlX3ZlcnNpb24gPT0gVUNPREVfUjIwMCkpIHsKCQkJCS8qIEZJWE1FIDogZmlndXJlIHRoaXMgb3V0IGZvciByMjAwICh3aGVuIGhpZXJ6IGlzIGVuYWJsZWQpLiBPcgoJCQkJICAgbWF5YmUgcjIwMCBhY3R1YWxseSBkb2Vzbid0IG5lZWQgdG8gcHV0IHRoZSBsb3ctcmVzIHogdmFsdWUgaW50bwoJCQkJICAgdGhlIHRpbGUgY2FjaGUgbGlrZSByMTAwLCBidXQganVzdCBuZWVkcyB0byBjbGVhciB0aGUgaGktbGV2ZWwgei1idWZmZXI/CgkJCQkgICBXb3JrcyBmb3IgUjEwMCwgYm90aCB3aXRoIGhpZXJ6IGFuZCB3aXRob3V0LgoJCQkJICAgUjEwMCBzZWVtcyB0byBvcGVyYXRlIG9uIDJ4MSA4eDggdGlsZXMsIGJ1dC4uLgoJCQkJICAgb2RkOiBvZmZzZXQvbnJ0aWxlcyBuZWVkIHRvIGJlIDY0IHBpeCAoNCBibG9jaykgYWxpZ25lZD8gUG90ZW50aWFsbHkKCQkJCSAgIHByb2JsZW1hdGljIHdpdGggcmVzb2x1dGlvbnMgd2hpY2ggYXJlIG5vdCA2NCBwaXggYWxpZ25lZD8gKi8KCQkJCXRpbGVvZmZzZXQgPQoJCQkJICAgICgocGJveFtpXS55MSA+PiAzKSAqIGRlcHRocGl4cGVybGluZSArCgkJCQkgICAgIHBib3hbaV0ueDEpID4+IDY7CgkJCQlucnRpbGVzeCA9CgkJCQkgICAgKChwYm94W2ldLngyICYgfjYzKSAtCgkJCQkgICAgIChwYm94W2ldLngxICYgfjYzKSkgPj4gNDsKCQkJCW5ydGlsZXN5ID0KCQkJCSAgICAocGJveFtpXS55MiA+PiAzKSAtIChwYm94W2ldLnkxID4+IDMpOwoJCQkJZm9yIChqID0gMDsgaiA8PSBucnRpbGVzeTsgaisrKSB7CgkJCQkJQkVHSU5fUklORyg0KTsKCQkJCQlPVVRfUklORyhDUF9QQUNLRVQzCgkJCQkJCSAoUkFERU9OXzNEX0NMRUFSX1pNQVNLLCAyKSk7CgkJCQkJLyogZmlyc3QgdGlsZSAqLwoJCQkJCU9VVF9SSU5HKHRpbGVvZmZzZXQgKiA4KTsKCQkJCQkvKiB0aGUgbnVtYmVyIG9mIHRpbGVzIHRvIGNsZWFyICovCgkJCQkJT1VUX1JJTkcobnJ0aWxlc3ggKyA0KTsKCQkJCQkvKiBjbGVhciBtYXNrIDogY2hvb3NlcyB0aGUgY2xlYXJpbmcgcGF0dGVybi4gKi8KCQkJCQlPVVRfUklORyhjbGVhcm1hc2spOwoJCQkJCUFEVkFOQ0VfUklORygpOwoJCQkJCXRpbGVvZmZzZXQgKz0gZGVwdGhwaXhwZXJsaW5lID4+IDY7CgkJCQl9CgkJCX0gZWxzZSBpZiAoZGV2X3ByaXYtPm1pY3JvY29kZV92ZXJzaW9uID09IFVDT0RFX1IyMDApIHsKCQkJCS8qIHdvcmtzIGZvciBydjI1MC4gKi8KCQkJCS8qIGZpbmQgZmlyc3QgbWFjcm8gdGlsZSAoOHgyIDR4NCB6LXBpeGVscyBvbiBydjI1MCkgKi8KCQkJCXRpbGVvZmZzZXQgPQoJCQkJICAgICgocGJveFtpXS55MSA+PiAzKSAqIGRlcHRocGl4cGVybGluZSArCgkJCQkgICAgIHBib3hbaV0ueDEpID4+IDU7CgkJCQlucnRpbGVzeCA9CgkJCQkgICAgKHBib3hbaV0ueDIgPj4gNSkgLSAocGJveFtpXS54MSA+PiA1KTsKCQkJCW5ydGlsZXN5ID0KCQkJCSAgICAocGJveFtpXS55MiA+PiAzKSAtIChwYm94W2ldLnkxID4+IDMpOwoJCQkJZm9yIChqID0gMDsgaiA8PSBucnRpbGVzeTsgaisrKSB7CgkJCQkJQkVHSU5fUklORyg0KTsKCQkJCQlPVVRfUklORyhDUF9QQUNLRVQzCgkJCQkJCSAoUkFERU9OXzNEX0NMRUFSX1pNQVNLLCAyKSk7CgkJCQkJLyogZmlyc3QgdGlsZSAqLwoJCQkJCS8qIGp1ZGdpbmcgYnkgdGhlIGZpcnN0IHRpbGUgb2Zmc2V0IG5lZWRlZCwgY291bGQgcG9zc2libHkKCQkJCQkgICBkaXJlY3RseSBhZGRyZXNzL2NsZWFyIDR4NCB0aWxlcyBpbnN0ZWFkIG9mIDh4MiAqIDR4NAoJCQkJCSAgIG1hY3JvIHRpbGVzLCB0aG91Z2ggd291bGQgc3RpbGwgbmVlZCBjbGVhciBtYXNrIGZvcgoJCQkJCSAgIHJpZ2h0L2JvdHRvbSBpZiB0cnVlbHkgNHg0IGdyYW51bGFyaXR5IGlzIGRlc2lyZWQgPyAqLwoJCQkJCU9VVF9SSU5HKHRpbGVvZmZzZXQgKiAxNik7CgkJCQkJLyogdGhlIG51bWJlciBvZiB0aWxlcyB0byBjbGVhciAqLwoJCQkJCU9VVF9SSU5HKG5ydGlsZXN4ICsgMSk7CgkJCQkJLyogY2xlYXIgbWFzayA6IGNob29zZXMgdGhlIGNsZWFyaW5nIHBhdHRlcm4uICovCgkJCQkJT1VUX1JJTkcoY2xlYXJtYXNrKTsKCQkJCQlBRFZBTkNFX1JJTkcoKTsKCQkJCQl0aWxlb2Zmc2V0ICs9IGRlcHRocGl4cGVybGluZSA+PiA1OwoJCQkJfQoJCQl9IGVsc2UgewkvKiBydiAxMDAgKi8KCQkJCS8qIHJ2MTAwIG1pZ2h0IG5vdCBuZWVkIDY0IHBpeCBhbGlnbm1lbnQsIHdobyBrbm93cyAqLwoJCQkJLyogb2Zmc2V0cyBhcmUsIGhtbSwgd2VpcmQgKi8KCQkJCXRpbGVvZmZzZXQgPQoJCQkJICAgICgocGJveFtpXS55MSA+PiA0KSAqIGRlcHRocGl4cGVybGluZSArCgkJCQkgICAgIHBib3hbaV0ueDEpID4+IDY7CgkJCQlucnRpbGVzeCA9CgkJCQkgICAgKChwYm94W2ldLngyICYgfjYzKSAtCgkJCQkgICAgIChwYm94W2ldLngxICYgfjYzKSkgPj4gNDsKCQkJCW5ydGlsZXN5ID0KCQkJCSAgICAocGJveFtpXS55MiA+PiA0KSAtIChwYm94W2ldLnkxID4+IDQpOwoJCQkJZm9yIChqID0gMDsgaiA8PSBucnRpbGVzeTsgaisrKSB7CgkJCQkJQkVHSU5fUklORyg0KTsKCQkJCQlPVVRfUklORyhDUF9QQUNLRVQzCgkJCQkJCSAoUkFERU9OXzNEX0NMRUFSX1pNQVNLLCAyKSk7CgkJCQkJT1VUX1JJTkcodGlsZW9mZnNldCAqIDEyOCk7CgkJCQkJLyogdGhlIG51bWJlciBvZiB0aWxlcyB0byBjbGVhciAqLwoJCQkJCU9VVF9SSU5HKG5ydGlsZXN4ICsgNCk7CgkJCQkJLyogY2xlYXIgbWFzayA6IGNob29zZXMgdGhlIGNsZWFyaW5nIHBhdHRlcm4uICovCgkJCQkJT1VUX1JJTkcoY2xlYXJtYXNrKTsKCQkJCQlBRFZBTkNFX1JJTkcoKTsKCQkJCQl0aWxlb2Zmc2V0ICs9IGRlcHRocGl4cGVybGluZSA+PiA2OwoJCQkJfQoJCQl9CgkJfQoKCQkvKiBUT0RPIGRvbid0IGFsd2F5cyBjbGVhciBhbGwgaGktbGV2ZWwgeiB0aWxlcyAqLwoJCWlmICgoZGV2X3ByaXYtPmZsYWdzICYgUkFERU9OX0hBU19ISUVSWikKCQkgICAgJiYgKGRldl9wcml2LT5taWNyb2NvZGVfdmVyc2lvbiA9PSBVQ09ERV9SMjAwKQoJCSAgICAmJiAoZmxhZ3MgJiBSQURFT05fVVNFX0hJRVJaKSkKCQkJLyogcjEwMCBhbmQgY2FyZHMgd2l0aG91dCBoaWVyYXJjaGljYWwgei1idWZmZXIgaGF2ZSBubyBoaWdoLWxldmVsIHotYnVmZmVyICovCgkJCS8qIEZJWE1FIDogdGhlIG1hc2sgc3VwcG9zZWRseSBjb250YWlucyBsb3ctcmVzIHogdmFsdWVzLiBTbyBjYW4ndCBzZXQKCQkJICAganVzdCB0byB0aGUgbWF4ICgweGZmPyBvciBhY3R1YWxseSAweDNmZmY/KSwgbmVlZCB0byB0YWtlIHogY2xlYXIKCQkJICAgdmFsdWUgaW50byBhY2NvdW50PyAqLwoJCXsKCQkJQkVHSU5fUklORyg0KTsKCQkJT1VUX1JJTkcoQ1BfUEFDS0VUMyhSQURFT05fM0RfQ0xFQVJfSElaLCAyKSk7CgkJCU9VVF9SSU5HKDB4MCk7CS8qIEZpcnN0IHRpbGUgKi8KCQkJT1VUX1JJTkcoMHgzY2MwKTsKCQkJT1VUX1JJTkcoKDB4ZmYgPDwgMjIpIHwgKDB4ZmYgPDwgNikgfCAweDAwM2YwMDNmKTsKCQkJQURWQU5DRV9SSU5HKCk7CgkJfQoJfQoKCS8qIFdlIGhhdmUgdG8gY2xlYXIgdGhlIGRlcHRoIGFuZC9vciBzdGVuY2lsIGJ1ZmZlcnMgYnkKCSAqIHJlbmRlcmluZyBhIHF1YWQgaW50byBqdXN0IHRob3NlIGJ1ZmZlcnMuICBUaHVzLCB3ZSBoYXZlIHRvCgkgKiBtYWtlIHN1cmUgdGhlIDNEIGVuZ2luZSBpcyBjb25maWd1cmVkIGNvcnJlY3RseS4KCSAqLwoJZWxzZSBpZiAoKGRldl9wcml2LT5taWNyb2NvZGVfdmVyc2lvbiA9PSBVQ09ERV9SMjAwKSAmJgoJCShmbGFncyAmIChSQURFT05fREVQVEggfCBSQURFT05fU1RFTkNJTCkpKSB7CgoJCWludCB0ZW1wUFBfQ05UTDsKCQlpbnQgdGVtcFJFX0NOVEw7CgkJaW50IHRlbXBSQjNEX0NOVEw7CgkJaW50IHRlbXBSQjNEX1pTVEVOQ0lMQ05UTDsKCQlpbnQgdGVtcFJCM0RfU1RFTkNJTFJFRk1BU0s7CgkJaW50IHRlbXBSQjNEX1BMQU5FTUFTSzsKCQlpbnQgdGVtcFNFX0NOVEw7CgkJaW50IHRlbXBTRV9WVEVfQ05UTDsKCQlpbnQgdGVtcFNFX1ZUWF9GTVRfMDsKCQlpbnQgdGVtcFNFX1ZUWF9GTVRfMTsKCQlpbnQgdGVtcFNFX1ZBUF9DTlRMOwoJCWludCB0ZW1wUkVfQVVYX1NDSVNTT1JfQ05UTDsKCgkJdGVtcFBQX0NOVEwgPSAwOwoJCXRlbXBSRV9DTlRMID0gMDsKCgkJdGVtcFJCM0RfQ05UTCA9IGRlcHRoX2NsZWFyLT5yYjNkX2NudGw7CgoJCXRlbXBSQjNEX1pTVEVOQ0lMQ05UTCA9IGRlcHRoX2NsZWFyLT5yYjNkX3pzdGVuY2lsY250bDsKCQl0ZW1wUkIzRF9TVEVOQ0lMUkVGTUFTSyA9IDB4MDsKCgkJdGVtcFNFX0NOVEwgPSBkZXB0aF9jbGVhci0+c2VfY250bDsKCgkJLyogRGlzYWJsZSBUQ0wgKi8KCgkJdGVtcFNFX1ZBUF9DTlRMID0gKAkvKiBTRV9WQVBfQ05UTF9fRk9SQ0VfV19UT19PTkVfTUFTSyB8ICAqLwoJCQkJCSAgKDB4OSA8PAoJCQkJCSAgIFNFX1ZBUF9DTlRMX19WRl9NQVhfVlRYX05VTV9fU0hJRlQpKTsKCgkJdGVtcFJCM0RfUExBTkVNQVNLID0gMHgwOwoKCQl0ZW1wUkVfQVVYX1NDSVNTT1JfQ05UTCA9IDB4MDsKCgkJdGVtcFNFX1ZURV9DTlRMID0KCQkgICAgU0VfVlRFX0NOVExfX1ZUWF9YWV9GTVRfTUFTSyB8IFNFX1ZURV9DTlRMX19WVFhfWl9GTVRfTUFTSzsKCgkJLyogVmVydGV4IGZvcm1hdCAoWCwgWSwgWiwgVykgKi8KCQl0ZW1wU0VfVlRYX0ZNVF8wID0KCQkgICAgU0VfVlRYX0ZNVF8wX19WVFhfWjBfUFJFU0VOVF9NQVNLIHwKCQkgICAgU0VfVlRYX0ZNVF8wX19WVFhfVzBfUFJFU0VOVF9NQVNLOwoJCXRlbXBTRV9WVFhfRk1UXzEgPSAweDA7CgoJCS8qCgkJICogRGVwdGggYnVmZmVyIHNwZWNpZmljIGVuYWJsZXMKCQkgKi8KCQlpZiAoZmxhZ3MgJiBSQURFT05fREVQVEgpIHsKCQkJLyogRW5hYmxlIGRlcHRoIGJ1ZmZlciAqLwoJCQl0ZW1wUkIzRF9DTlRMIHw9IFJBREVPTl9aX0VOQUJMRTsKCQl9IGVsc2UgewoJCQkvKiBEaXNhYmxlIGRlcHRoIGJ1ZmZlciAqLwoJCQl0ZW1wUkIzRF9DTlRMICY9IH5SQURFT05fWl9FTkFCTEU7CgkJfQoKCQkvKgoJCSAqIFN0ZW5jaWwgYnVmZmVyIHNwZWNpZmljIGVuYWJsZXMKCQkgKi8KCQlpZiAoZmxhZ3MgJiBSQURFT05fU1RFTkNJTCkgewoJCQl0ZW1wUkIzRF9DTlRMIHw9IFJBREVPTl9TVEVOQ0lMX0VOQUJMRTsKCQkJdGVtcFJCM0RfU1RFTkNJTFJFRk1BU0sgPSBjbGVhci0+ZGVwdGhfbWFzazsKCQl9IGVsc2UgewoJCQl0ZW1wUkIzRF9DTlRMICY9IH5SQURFT05fU1RFTkNJTF9FTkFCTEU7CgkJCXRlbXBSQjNEX1NURU5DSUxSRUZNQVNLID0gMHgwMDAwMDAwMDsKCQl9CgoJCWlmIChmbGFncyAmIFJBREVPTl9VU0VfQ09NUF9aQlVGKSB7CgkJCXRlbXBSQjNEX1pTVEVOQ0lMQ05UTCB8PSBSQURFT05fWl9DT01QUkVTU0lPTl9FTkFCTEUgfAoJCQkgICAgUkFERU9OX1pfREVDT01QUkVTU0lPTl9FTkFCTEU7CgkJfQoJCWlmIChmbGFncyAmIFJBREVPTl9VU0VfSElFUlopIHsKCQkJdGVtcFJCM0RfWlNURU5DSUxDTlRMIHw9IFJBREVPTl9aX0hJRVJBUkNIWV9FTkFCTEU7CgkJfQoKCQlCRUdJTl9SSU5HKDI2KTsKCQlSQURFT05fV0FJVF9VTlRJTF8yRF9JRExFKCk7CgoJCU9VVF9SSU5HX1JFRyhSQURFT05fUFBfQ05UTCwgdGVtcFBQX0NOVEwpOwoJCU9VVF9SSU5HX1JFRyhSMjAwX1JFX0NOVEwsIHRlbXBSRV9DTlRMKTsKCQlPVVRfUklOR19SRUcoUkFERU9OX1JCM0RfQ05UTCwgdGVtcFJCM0RfQ05UTCk7CgkJT1VUX1JJTkdfUkVHKFJBREVPTl9SQjNEX1pTVEVOQ0lMQ05UTCwgdGVtcFJCM0RfWlNURU5DSUxDTlRMKTsKCQlPVVRfUklOR19SRUcoUkFERU9OX1JCM0RfU1RFTkNJTFJFRk1BU0ssCgkJCSAgICAgdGVtcFJCM0RfU1RFTkNJTFJFRk1BU0spOwoJCU9VVF9SSU5HX1JFRyhSQURFT05fUkIzRF9QTEFORU1BU0ssIHRlbXBSQjNEX1BMQU5FTUFTSyk7CgkJT1VUX1JJTkdfUkVHKFJBREVPTl9TRV9DTlRMLCB0ZW1wU0VfQ05UTCk7CgkJT1VUX1JJTkdfUkVHKFIyMDBfU0VfVlRFX0NOVEwsIHRlbXBTRV9WVEVfQ05UTCk7CgkJT1VUX1JJTkdfUkVHKFIyMDBfU0VfVlRYX0ZNVF8wLCB0ZW1wU0VfVlRYX0ZNVF8wKTsKCQlPVVRfUklOR19SRUcoUjIwMF9TRV9WVFhfRk1UXzEsIHRlbXBTRV9WVFhfRk1UXzEpOwoJCU9VVF9SSU5HX1JFRyhSMjAwX1NFX1ZBUF9DTlRMLCB0ZW1wU0VfVkFQX0NOVEwpOwoJCU9VVF9SSU5HX1JFRyhSMjAwX1JFX0FVWF9TQ0lTU09SX0NOVEwsIHRlbXBSRV9BVVhfU0NJU1NPUl9DTlRMKTsKCQlBRFZBTkNFX1JJTkcoKTsKCgkJLyogTWFrZSBzdXJlIHdlIHJlc3RvcmUgdGhlIDNEIHN0YXRlIG5leHQgdGltZS4KCQkgKi8KCQlkZXZfcHJpdi0+c2FyZWFfcHJpdi0+Y3R4X293bmVyID0gMDsKCgkJZm9yIChpID0gMDsgaSA8IG5ib3g7IGkrKykgewoKCQkJLyogRnVubnkgdGhhdCB0aGlzIHNob3VsZCBiZSByZXF1aXJlZCAtLQoJCQkgKiAgc2V0cyB0b3AtbGVmdD8KCQkJICovCgkJCXJhZGVvbl9lbWl0X2NsaXBfcmVjdChkZXZfcHJpdiwgJnNhcmVhX3ByaXYtPmJveGVzW2ldKTsKCgkJCUJFR0lOX1JJTkcoMTQpOwoJCQlPVVRfUklORyhDUF9QQUNLRVQzKFIyMDBfM0RfRFJBV19JTU1EXzIsIDEyKSk7CgkJCU9VVF9SSU5HKChSQURFT05fUFJJTV9UWVBFX1JFQ1RfTElTVCB8CgkJCQkgIFJBREVPTl9QUklNX1dBTEtfUklORyB8CgkJCQkgICgzIDw8IFJBREVPTl9OVU1fVkVSVElDRVNfU0hJRlQpKSk7CgkJCU9VVF9SSU5HKGRlcHRoX2JveGVzW2ldLnVpW0NMRUFSX1gxXSk7CgkJCU9VVF9SSU5HKGRlcHRoX2JveGVzW2ldLnVpW0NMRUFSX1kxXSk7CgkJCU9VVF9SSU5HKGRlcHRoX2JveGVzW2ldLnVpW0NMRUFSX0RFUFRIXSk7CgkJCU9VVF9SSU5HKDB4M2Y4MDAwMDApOwoJCQlPVVRfUklORyhkZXB0aF9ib3hlc1tpXS51aVtDTEVBUl9YMV0pOwoJCQlPVVRfUklORyhkZXB0aF9ib3hlc1tpXS51aVtDTEVBUl9ZMl0pOwoJCQlPVVRfUklORyhkZXB0aF9ib3hlc1tpXS51aVtDTEVBUl9ERVBUSF0pOwoJCQlPVVRfUklORygweDNmODAwMDAwKTsKCQkJT1VUX1JJTkcoZGVwdGhfYm94ZXNbaV0udWlbQ0xFQVJfWDJdKTsKCQkJT1VUX1JJTkcoZGVwdGhfYm94ZXNbaV0udWlbQ0xFQVJfWTJdKTsKCQkJT1VUX1JJTkcoZGVwdGhfYm94ZXNbaV0udWlbQ0xFQVJfREVQVEhdKTsKCQkJT1VUX1JJTkcoMHgzZjgwMDAwMCk7CgkJCUFEVkFOQ0VfUklORygpOwoJCX0KCX0gZWxzZSBpZiAoKGZsYWdzICYgKFJBREVPTl9ERVBUSCB8IFJBREVPTl9TVEVOQ0lMKSkpIHsKCgkJaW50IHRlbXBSQjNEX1pTVEVOQ0lMQ05UTCA9IGRlcHRoX2NsZWFyLT5yYjNkX3pzdGVuY2lsY250bDsKCgkJcmIzZF9jbnRsID0gZGVwdGhfY2xlYXItPnJiM2RfY250bDsKCgkJaWYgKGZsYWdzICYgUkFERU9OX0RFUFRIKSB7CgkJCXJiM2RfY250bCB8PSBSQURFT05fWl9FTkFCTEU7CgkJfSBlbHNlIHsKCQkJcmIzZF9jbnRsICY9IH5SQURFT05fWl9FTkFCTEU7CgkJfQoKCQlpZiAoZmxhZ3MgJiBSQURFT05fU1RFTkNJTCkgewoJCQlyYjNkX2NudGwgfD0gUkFERU9OX1NURU5DSUxfRU5BQkxFOwoJCQlyYjNkX3N0ZW5jaWxyZWZtYXNrID0gY2xlYXItPmRlcHRoX21hc2s7CS8qIG1pc25hbWVkIGZpZWxkICovCgkJfSBlbHNlIHsKCQkJcmIzZF9jbnRsICY9IH5SQURFT05fU1RFTkNJTF9FTkFCTEU7CgkJCXJiM2Rfc3RlbmNpbHJlZm1hc2sgPSAweDAwMDAwMDAwOwoJCX0KCgkJaWYgKGZsYWdzICYgUkFERU9OX1VTRV9DT01QX1pCVUYpIHsKCQkJdGVtcFJCM0RfWlNURU5DSUxDTlRMIHw9IFJBREVPTl9aX0NPTVBSRVNTSU9OX0VOQUJMRSB8CgkJCSAgICBSQURFT05fWl9ERUNPTVBSRVNTSU9OX0VOQUJMRTsKCQl9CgkJaWYgKGZsYWdzICYgUkFERU9OX1VTRV9ISUVSWikgewoJCQl0ZW1wUkIzRF9aU1RFTkNJTENOVEwgfD0gUkFERU9OX1pfSElFUkFSQ0hZX0VOQUJMRTsKCQl9CgoJCUJFR0lOX1JJTkcoMTMpOwoJCVJBREVPTl9XQUlUX1VOVElMXzJEX0lETEUoKTsKCgkJT1VUX1JJTkcoQ1BfUEFDS0VUMChSQURFT05fUFBfQ05UTCwgMSkpOwoJCU9VVF9SSU5HKDB4MDAwMDAwMDApOwoJCU9VVF9SSU5HKHJiM2RfY250bCk7CgoJCU9VVF9SSU5HX1JFRyhSQURFT05fUkIzRF9aU1RFTkNJTENOVEwsIHRlbXBSQjNEX1pTVEVOQ0lMQ05UTCk7CgkJT1VUX1JJTkdfUkVHKFJBREVPTl9SQjNEX1NURU5DSUxSRUZNQVNLLCByYjNkX3N0ZW5jaWxyZWZtYXNrKTsKCQlPVVRfUklOR19SRUcoUkFERU9OX1JCM0RfUExBTkVNQVNLLCAweDAwMDAwMDAwKTsKCQlPVVRfUklOR19SRUcoUkFERU9OX1NFX0NOVEwsIGRlcHRoX2NsZWFyLT5zZV9jbnRsKTsKCQlBRFZBTkNFX1JJTkcoKTsKCgkJLyogTWFrZSBzdXJlIHdlIHJlc3RvcmUgdGhlIDNEIHN0YXRlIG5leHQgdGltZS4KCQkgKi8KCQlkZXZfcHJpdi0+c2FyZWFfcHJpdi0+Y3R4X293bmVyID0gMDsKCgkJZm9yIChpID0gMDsgaSA8IG5ib3g7IGkrKykgewoKCQkJLyogRnVubnkgdGhhdCB0aGlzIHNob3VsZCBiZSByZXF1aXJlZCAtLQoJCQkgKiAgc2V0cyB0b3AtbGVmdD8KCQkJICovCgkJCXJhZGVvbl9lbWl0X2NsaXBfcmVjdChkZXZfcHJpdiwgJnNhcmVhX3ByaXYtPmJveGVzW2ldKTsKCgkJCUJFR0lOX1JJTkcoMTUpOwoKCQkJT1VUX1JJTkcoQ1BfUEFDS0VUMyhSQURFT05fM0RfRFJBV19JTU1ELCAxMykpOwoJCQlPVVRfUklORyhSQURFT05fVlRYX1pfUFJFU0VOVCB8CgkJCQkgUkFERU9OX1ZUWF9QS0NPTE9SX1BSRVNFTlQpOwoJCQlPVVRfUklORygoUkFERU9OX1BSSU1fVFlQRV9SRUNUX0xJU1QgfAoJCQkJICBSQURFT05fUFJJTV9XQUxLX1JJTkcgfAoJCQkJICBSQURFT05fTUFPU19FTkFCTEUgfAoJCQkJICBSQURFT05fVlRYX0ZNVF9SQURFT05fTU9ERSB8CgkJCQkgICgzIDw8IFJBREVPTl9OVU1fVkVSVElDRVNfU0hJRlQpKSk7CgoJCQlPVVRfUklORyhkZXB0aF9ib3hlc1tpXS51aVtDTEVBUl9YMV0pOwoJCQlPVVRfUklORyhkZXB0aF9ib3hlc1tpXS51aVtDTEVBUl9ZMV0pOwoJCQlPVVRfUklORyhkZXB0aF9ib3hlc1tpXS51aVtDTEVBUl9ERVBUSF0pOwoJCQlPVVRfUklORygweDApOwoKCQkJT1VUX1JJTkcoZGVwdGhfYm94ZXNbaV0udWlbQ0xFQVJfWDFdKTsKCQkJT1VUX1JJTkcoZGVwdGhfYm94ZXNbaV0udWlbQ0xFQVJfWTJdKTsKCQkJT1VUX1JJTkcoZGVwdGhfYm94ZXNbaV0udWlbQ0xFQVJfREVQVEhdKTsKCQkJT1VUX1JJTkcoMHgwKTsKCgkJCU9VVF9SSU5HKGRlcHRoX2JveGVzW2ldLnVpW0NMRUFSX1gyXSk7CgkJCU9VVF9SSU5HKGRlcHRoX2JveGVzW2ldLnVpW0NMRUFSX1kyXSk7CgkJCU9VVF9SSU5HKGRlcHRoX2JveGVzW2ldLnVpW0NMRUFSX0RFUFRIXSk7CgkJCU9VVF9SSU5HKDB4MCk7CgoJCQlBRFZBTkNFX1JJTkcoKTsKCQl9Cgl9CgoJLyogSW5jcmVtZW50IHRoZSBjbGVhciBjb3VudGVyLiAgVGhlIGNsaWVudC1zaWRlIDNEIGRyaXZlciBtdXN0CgkgKiB3YWl0IG9uIHRoaXMgdmFsdWUgYmVmb3JlIHBlcmZvcm1pbmcgdGhlIGNsZWFyIGlvY3RsLiAgV2UKCSAqIG5lZWQgdGhpcyBiZWNhdXNlIHRoZSBjYXJkJ3Mgc28gZGFtbmVkIGZhc3QuLi4KCSAqLwoJZGV2X3ByaXYtPnNhcmVhX3ByaXYtPmxhc3RfY2xlYXIrKzsKCglCRUdJTl9SSU5HKDQpOwoKCVJBREVPTl9DTEVBUl9BR0UoZGV2X3ByaXYtPnNhcmVhX3ByaXYtPmxhc3RfY2xlYXIpOwoJUkFERU9OX1dBSVRfVU5USUxfSURMRSgpOwoKCUFEVkFOQ0VfUklORygpOwp9CgpzdGF0aWMgdm9pZCByYWRlb25fY3BfZGlzcGF0Y2hfc3dhcChkcm1fZGV2aWNlX3QgKiBkZXYpCnsKCWRybV9yYWRlb25fcHJpdmF0ZV90ICpkZXZfcHJpdiA9IGRldi0+ZGV2X3ByaXZhdGU7Cglkcm1fcmFkZW9uX3NhcmVhX3QgKnNhcmVhX3ByaXYgPSBkZXZfcHJpdi0+c2FyZWFfcHJpdjsKCWludCBuYm94ID0gc2FyZWFfcHJpdi0+bmJveDsKCWRybV9jbGlwX3JlY3RfdCAqcGJveCA9IHNhcmVhX3ByaXYtPmJveGVzOwoJaW50IGk7CglSSU5HX0xPQ0FMUzsKCURSTV9ERUJVRygiXG4iKTsKCgkvKiBEbyBzb21lIHRyaXZpYWwgcGVyZm9ybWFuY2UgbW9uaXRvcmluZy4uLgoJICovCglpZiAoZGV2X3ByaXYtPmRvX2JveGVzKQoJCXJhZGVvbl9jcF9wZXJmb3JtYW5jZV9ib3hlcyhkZXZfcHJpdik7CgoJLyogV2FpdCBmb3IgdGhlIDNEIHN0cmVhbSB0byBpZGxlIGJlZm9yZSBkaXNwYXRjaGluZyB0aGUgYml0Ymx0LgoJICogVGhpcyB3aWxsIHByZXZlbnQgZGF0YSBjb3JydXB0aW9uIGJldHdlZW4gdGhlIHR3byBzdHJlYW1zLgoJICovCglCRUdJTl9SSU5HKDIpOwoKCVJBREVPTl9XQUlUX1VOVElMXzNEX0lETEUoKTsKCglBRFZBTkNFX1JJTkcoKTsKCglmb3IgKGkgPSAwOyBpIDwgbmJveDsgaSsrKSB7CgkJaW50IHggPSBwYm94W2ldLngxOwoJCWludCB5ID0gcGJveFtpXS55MTsKCQlpbnQgdyA9IHBib3hbaV0ueDIgLSB4OwoJCWludCBoID0gcGJveFtpXS55MiAtIHk7CgoJCURSTV9ERUJVRygiZGlzcGF0Y2ggc3dhcCAlZCwlZC0lZCwlZFxuIiwgeCwgeSwgdywgaCk7CgoJCUJFR0lOX1JJTkcoOSk7CgoJCU9VVF9SSU5HKENQX1BBQ0tFVDAoUkFERU9OX0RQX0dVSV9NQVNURVJfQ05UTCwgMCkpOwoJCU9VVF9SSU5HKFJBREVPTl9HTUNfU1JDX1BJVENIX09GRlNFVF9DTlRMIHwKCQkJIFJBREVPTl9HTUNfRFNUX1BJVENIX09GRlNFVF9DTlRMIHwKCQkJIFJBREVPTl9HTUNfQlJVU0hfTk9ORSB8CgkJCSAoZGV2X3ByaXYtPmNvbG9yX2ZtdCA8PCA4KSB8CgkJCSBSQURFT05fR01DX1NSQ19EQVRBVFlQRV9DT0xPUiB8CgkJCSBSQURFT05fUk9QM19TIHwKCQkJIFJBREVPTl9EUF9TUkNfU09VUkNFX01FTU9SWSB8CgkJCSBSQURFT05fR01DX0NMUl9DTVBfQ05UTF9ESVMgfCBSQURFT05fR01DX1dSX01TS19ESVMpOwoKCQkvKiBNYWtlIHRoaXMgd29yayBldmVuIGlmIGZyb250ICYgYmFjayBhcmUgZmxpcHBlZDoKCQkgKi8KCQlPVVRfUklORyhDUF9QQUNLRVQwKFJBREVPTl9TUkNfUElUQ0hfT0ZGU0VULCAxKSk7CgkJaWYgKGRldl9wcml2LT5jdXJyZW50X3BhZ2UgPT0gMCkgewoJCQlPVVRfUklORyhkZXZfcHJpdi0+YmFja19waXRjaF9vZmZzZXQpOwoJCQlPVVRfUklORyhkZXZfcHJpdi0+ZnJvbnRfcGl0Y2hfb2Zmc2V0KTsKCQl9IGVsc2UgewoJCQlPVVRfUklORyhkZXZfcHJpdi0+ZnJvbnRfcGl0Y2hfb2Zmc2V0KTsKCQkJT1VUX1JJTkcoZGV2X3ByaXYtPmJhY2tfcGl0Y2hfb2Zmc2V0KTsKCQl9CgoJCU9VVF9SSU5HKENQX1BBQ0tFVDAoUkFERU9OX1NSQ19YX1ksIDIpKTsKCQlPVVRfUklORygoeCA8PCAxNikgfCB5KTsKCQlPVVRfUklORygoeCA8PCAxNikgfCB5KTsKCQlPVVRfUklORygodyA8PCAxNikgfCBoKTsKCgkJQURWQU5DRV9SSU5HKCk7Cgl9CgoJLyogSW5jcmVtZW50IHRoZSBmcmFtZSBjb3VudGVyLiAgVGhlIGNsaWVudC1zaWRlIDNEIGRyaXZlciBtdXN0CgkgKiB0aHJvdHRsZSB0aGUgZnJhbWVyYXRlIGJ5IHdhaXRpbmcgZm9yIHRoaXMgdmFsdWUgYmVmb3JlCgkgKiBwZXJmb3JtaW5nIHRoZSBzd2FwYnVmZmVyIGlvY3RsLgoJICovCglkZXZfcHJpdi0+c2FyZWFfcHJpdi0+bGFzdF9mcmFtZSsrOwoKCUJFR0lOX1JJTkcoNCk7CgoJUkFERU9OX0ZSQU1FX0FHRShkZXZfcHJpdi0+c2FyZWFfcHJpdi0+bGFzdF9mcmFtZSk7CglSQURFT05fV0FJVF9VTlRJTF8yRF9JRExFKCk7CgoJQURWQU5DRV9SSU5HKCk7Cn0KCnN0YXRpYyB2b2lkIHJhZGVvbl9jcF9kaXNwYXRjaF9mbGlwKGRybV9kZXZpY2VfdCAqIGRldikKewoJZHJtX3JhZGVvbl9wcml2YXRlX3QgKmRldl9wcml2ID0gZGV2LT5kZXZfcHJpdmF0ZTsKCWRybV9zYXJlYV90ICpzYXJlYSA9IChkcm1fc2FyZWFfdCAqKSBkZXZfcHJpdi0+c2FyZWEtPmhhbmRsZTsKCWludCBvZmZzZXQgPSAoZGV2X3ByaXYtPmN1cnJlbnRfcGFnZSA9PSAxKQoJICAgID8gZGV2X3ByaXYtPmZyb250X29mZnNldCA6IGRldl9wcml2LT5iYWNrX29mZnNldDsKCVJJTkdfTE9DQUxTOwoJRFJNX0RFQlVHKCIlczogcGFnZT0lZCBwZkN1cnJlbnRQYWdlPSVkXG4iLAoJCSAgX19GVU5DVElPTl9fLAoJCSAgZGV2X3ByaXYtPmN1cnJlbnRfcGFnZSwgZGV2X3ByaXYtPnNhcmVhX3ByaXYtPnBmQ3VycmVudFBhZ2UpOwoKCS8qIERvIHNvbWUgdHJpdmlhbCBwZXJmb3JtYW5jZSBtb25pdG9yaW5nLi4uCgkgKi8KCWlmIChkZXZfcHJpdi0+ZG9fYm94ZXMpIHsKCQlkZXZfcHJpdi0+c3RhdHMuYm94ZXMgfD0gUkFERU9OX0JPWF9GTElQOwoJCXJhZGVvbl9jcF9wZXJmb3JtYW5jZV9ib3hlcyhkZXZfcHJpdik7Cgl9CgoJLyogVXBkYXRlIHRoZSBmcmFtZSBvZmZzZXRzIGZvciBib3RoIENSVENzCgkgKi8KCUJFR0lOX1JJTkcoNik7CgoJUkFERU9OX1dBSVRfVU5USUxfM0RfSURMRSgpOwoJT1VUX1JJTkdfUkVHKFJBREVPTl9DUlRDX09GRlNFVCwKCQkgICAgICgoc2FyZWEtPmZyYW1lLnkgKiBkZXZfcHJpdi0+ZnJvbnRfcGl0Y2ggKwoJCSAgICAgICBzYXJlYS0+ZnJhbWUueCAqIChkZXZfcHJpdi0+Y29sb3JfZm10IC0gMikpICYgfjcpCgkJICAgICArIG9mZnNldCk7CglPVVRfUklOR19SRUcoUkFERU9OX0NSVEMyX09GRlNFVCwgZGV2X3ByaXYtPnNhcmVhX3ByaXYtPmNydGMyX2Jhc2UKCQkgICAgICsgb2Zmc2V0KTsKCglBRFZBTkNFX1JJTkcoKTsKCgkvKiBJbmNyZW1lbnQgdGhlIGZyYW1lIGNvdW50ZXIuICBUaGUgY2xpZW50LXNpZGUgM0QgZHJpdmVyIG11c3QKCSAqIHRocm90dGxlIHRoZSBmcmFtZXJhdGUgYnkgd2FpdGluZyBmb3IgdGhpcyB2YWx1ZSBiZWZvcmUKCSAqIHBlcmZvcm1pbmcgdGhlIHN3YXBidWZmZXIgaW9jdGwuCgkgKi8KCWRldl9wcml2LT5zYXJlYV9wcml2LT5sYXN0X2ZyYW1lKys7CglkZXZfcHJpdi0+c2FyZWFfcHJpdi0+cGZDdXJyZW50UGFnZSA9IGRldl9wcml2LT5jdXJyZW50X3BhZ2UgPQoJICAgIDEgLSBkZXZfcHJpdi0+Y3VycmVudF9wYWdlOwoKCUJFR0lOX1JJTkcoMik7CgoJUkFERU9OX0ZSQU1FX0FHRShkZXZfcHJpdi0+c2FyZWFfcHJpdi0+bGFzdF9mcmFtZSk7CgoJQURWQU5DRV9SSU5HKCk7Cn0KCnN0YXRpYyBpbnQgYmFkX3ByaW1fdmVydGV4X25yKGludCBwcmltaXRpdmUsIGludCBucikKewoJc3dpdGNoIChwcmltaXRpdmUgJiBSQURFT05fUFJJTV9UWVBFX01BU0spIHsKCWNhc2UgUkFERU9OX1BSSU1fVFlQRV9OT05FOgoJY2FzZSBSQURFT05fUFJJTV9UWVBFX1BPSU5UOgoJCXJldHVybiBuciA8IDE7CgljYXNlIFJBREVPTl9QUklNX1RZUEVfTElORToKCQlyZXR1cm4gKG5yICYgMSkgfHwgbnIgPT0gMDsKCWNhc2UgUkFERU9OX1BSSU1fVFlQRV9MSU5FX1NUUklQOgoJCXJldHVybiBuciA8IDI7CgljYXNlIFJBREVPTl9QUklNX1RZUEVfVFJJX0xJU1Q6CgljYXNlIFJBREVPTl9QUklNX1RZUEVfM1ZSVF9QT0lOVF9MSVNUOgoJY2FzZSBSQURFT05fUFJJTV9UWVBFXzNWUlRfTElORV9MSVNUOgoJY2FzZSBSQURFT05fUFJJTV9UWVBFX1JFQ1RfTElTVDoKCQlyZXR1cm4gbnIgJSAzIHx8IG5yID09IDA7CgljYXNlIFJBREVPTl9QUklNX1RZUEVfVFJJX0ZBTjoKCWNhc2UgUkFERU9OX1BSSU1fVFlQRV9UUklfU1RSSVA6CgkJcmV0dXJuIG5yIDwgMzsKCWRlZmF1bHQ6CgkJcmV0dXJuIDE7Cgl9Cn0KCnR5cGVkZWYgc3RydWN0IHsKCXVuc2lnbmVkIGludCBzdGFydDsKCXVuc2lnbmVkIGludCBmaW5pc2g7Cgl1bnNpZ25lZCBpbnQgcHJpbTsKCXVuc2lnbmVkIGludCBudW12ZXJ0czsKCXVuc2lnbmVkIGludCBvZmZzZXQ7Cgl1bnNpZ25lZCBpbnQgdmNfZm9ybWF0Owp9IGRybV9yYWRlb25fdGNsX3ByaW1fdDsKCnN0YXRpYyB2b2lkIHJhZGVvbl9jcF9kaXNwYXRjaF92ZXJ0ZXgoZHJtX2RldmljZV90ICogZGV2LAoJCQkJICAgICAgZHJtX2J1Zl90ICogYnVmLAoJCQkJICAgICAgZHJtX3JhZGVvbl90Y2xfcHJpbV90ICogcHJpbSkKewoJZHJtX3JhZGVvbl9wcml2YXRlX3QgKmRldl9wcml2ID0gZGV2LT5kZXZfcHJpdmF0ZTsKCWRybV9yYWRlb25fc2FyZWFfdCAqc2FyZWFfcHJpdiA9IGRldl9wcml2LT5zYXJlYV9wcml2OwoJaW50IG9mZnNldCA9IGRldl9wcml2LT5nYXJ0X2J1ZmZlcnNfb2Zmc2V0ICsgYnVmLT5vZmZzZXQgKyBwcmltLT5zdGFydDsKCWludCBudW12ZXJ0cyA9IChpbnQpcHJpbS0+bnVtdmVydHM7CglpbnQgbmJveCA9IHNhcmVhX3ByaXYtPm5ib3g7CglpbnQgaSA9IDA7CglSSU5HX0xPQ0FMUzsKCglEUk1fREVCVUcoImh3cHJpbSAweCV4IHZmbXQgMHgleCAlZC4uJWQgJWQgdmVydHNcbiIsCgkJICBwcmltLT5wcmltLAoJCSAgcHJpbS0+dmNfZm9ybWF0LCBwcmltLT5zdGFydCwgcHJpbS0+ZmluaXNoLCBwcmltLT5udW12ZXJ0cyk7CgoJaWYgKGJhZF9wcmltX3ZlcnRleF9ucihwcmltLT5wcmltLCBwcmltLT5udW12ZXJ0cykpIHsKCQlEUk1fRVJST1IoImJhZCBwcmltICV4IG51bXZlcnRzICVkXG4iLAoJCQkgIHByaW0tPnByaW0sIHByaW0tPm51bXZlcnRzKTsKCQlyZXR1cm47Cgl9CgoJZG8gewoJCS8qIEVtaXQgdGhlIG5leHQgY2xpcHJlY3QgKi8KCQlpZiAoaSA8IG5ib3gpIHsKCQkJcmFkZW9uX2VtaXRfY2xpcF9yZWN0KGRldl9wcml2LCAmc2FyZWFfcHJpdi0+Ym94ZXNbaV0pOwoJCX0KCgkJLyogRW1pdCB0aGUgdmVydGV4IGJ1ZmZlciByZW5kZXJpbmcgY29tbWFuZHMgKi8KCQlCRUdJTl9SSU5HKDUpOwoKCQlPVVRfUklORyhDUF9QQUNLRVQzKFJBREVPTl8zRF9STkRSX0dFTl9JTkRYX1BSSU0sIDMpKTsKCQlPVVRfUklORyhvZmZzZXQpOwoJCU9VVF9SSU5HKG51bXZlcnRzKTsKCQlPVVRfUklORyhwcmltLT52Y19mb3JtYXQpOwoJCU9VVF9SSU5HKHByaW0tPnByaW0gfCBSQURFT05fUFJJTV9XQUxLX0xJU1QgfAoJCQkgUkFERU9OX0NPTE9SX09SREVSX1JHQkEgfAoJCQkgUkFERU9OX1ZUWF9GTVRfUkFERU9OX01PREUgfAoJCQkgKG51bXZlcnRzIDw8IFJBREVPTl9OVU1fVkVSVElDRVNfU0hJRlQpKTsKCgkJQURWQU5DRV9SSU5HKCk7CgoJCWkrKzsKCX0gd2hpbGUgKGkgPCBuYm94KTsKfQoKc3RhdGljIHZvaWQgcmFkZW9uX2NwX2Rpc2NhcmRfYnVmZmVyKGRybV9kZXZpY2VfdCAqIGRldiwgZHJtX2J1Zl90ICogYnVmKQp7Cglkcm1fcmFkZW9uX3ByaXZhdGVfdCAqZGV2X3ByaXYgPSBkZXYtPmRldl9wcml2YXRlOwoJZHJtX3JhZGVvbl9idWZfcHJpdl90ICpidWZfcHJpdiA9IGJ1Zi0+ZGV2X3ByaXZhdGU7CglSSU5HX0xPQ0FMUzsKCglidWZfcHJpdi0+YWdlID0gKytkZXZfcHJpdi0+c2FyZWFfcHJpdi0+bGFzdF9kaXNwYXRjaDsKCgkvKiBFbWl0IHRoZSB2ZXJ0ZXggYnVmZmVyIGFnZSAqLwoJQkVHSU5fUklORygyKTsKCVJBREVPTl9ESVNQQVRDSF9BR0UoYnVmX3ByaXYtPmFnZSk7CglBRFZBTkNFX1JJTkcoKTsKCglidWYtPnBlbmRpbmcgPSAxOwoJYnVmLT51c2VkID0gMDsKfQoKc3RhdGljIHZvaWQgcmFkZW9uX2NwX2Rpc3BhdGNoX2luZGlyZWN0KGRybV9kZXZpY2VfdCAqIGRldiwKCQkJCQlkcm1fYnVmX3QgKiBidWYsIGludCBzdGFydCwgaW50IGVuZCkKewoJZHJtX3JhZGVvbl9wcml2YXRlX3QgKmRldl9wcml2ID0gZGV2LT5kZXZfcHJpdmF0ZTsKCVJJTkdfTE9DQUxTOwoJRFJNX0RFQlVHKCJpbmRpcmVjdDogYnVmPSVkIHM9MHgleCBlPTB4JXhcbiIsIGJ1Zi0+aWR4LCBzdGFydCwgZW5kKTsKCglpZiAoc3RhcnQgIT0gZW5kKSB7CgkJaW50IG9mZnNldCA9IChkZXZfcHJpdi0+Z2FydF9idWZmZXJzX29mZnNldAoJCQkgICAgICArIGJ1Zi0+b2Zmc2V0ICsgc3RhcnQpOwoJCWludCBkd29yZHMgPSAoZW5kIC0gc3RhcnQgKyAzKSAvIHNpemVvZih1MzIpOwoKCQkvKiBJbmRpcmVjdCBidWZmZXIgZGF0YSBtdXN0IGJlIGFuIGV2ZW4gbnVtYmVyIG9mCgkJICogZHdvcmRzLCBzbyBpZiB3ZSd2ZSBiZWVuIGdpdmVuIGFuIG9kZCBudW1iZXIgd2UgbXVzdAoJCSAqIHBhZCB0aGUgZGF0YSB3aXRoIGEgVHlwZS0yIENQIHBhY2tldC4KCQkgKi8KCQlpZiAoZHdvcmRzICYgMSkgewoJCQl1MzIgKmRhdGEgPSAodTMyICopCgkJCSAgICAoKGNoYXIgKilkZXYtPmFncF9idWZmZXJfbWFwLT5oYW5kbGUKCQkJICAgICArIGJ1Zi0+b2Zmc2V0ICsgc3RhcnQpOwoJCQlkYXRhW2R3b3JkcysrXSA9IFJBREVPTl9DUF9QQUNLRVQyOwoJCX0KCgkJLyogRmlyZSBvZmYgdGhlIGluZGlyZWN0IGJ1ZmZlciAqLwoJCUJFR0lOX1JJTkcoMyk7CgoJCU9VVF9SSU5HKENQX1BBQ0tFVDAoUkFERU9OX0NQX0lCX0JBU0UsIDEpKTsKCQlPVVRfUklORyhvZmZzZXQpOwoJCU9VVF9SSU5HKGR3b3Jkcyk7CgoJCUFEVkFOQ0VfUklORygpOwoJfQp9CgpzdGF0aWMgdm9pZCByYWRlb25fY3BfZGlzcGF0Y2hfaW5kaWNlcyhkcm1fZGV2aWNlX3QgKiBkZXYsCgkJCQkgICAgICAgZHJtX2J1Zl90ICogZWx0X2J1ZiwKCQkJCSAgICAgICBkcm1fcmFkZW9uX3RjbF9wcmltX3QgKiBwcmltKQp7Cglkcm1fcmFkZW9uX3ByaXZhdGVfdCAqZGV2X3ByaXYgPSBkZXYtPmRldl9wcml2YXRlOwoJZHJtX3JhZGVvbl9zYXJlYV90ICpzYXJlYV9wcml2ID0gZGV2X3ByaXYtPnNhcmVhX3ByaXY7CglpbnQgb2Zmc2V0ID0gZGV2X3ByaXYtPmdhcnRfYnVmZmVyc19vZmZzZXQgKyBwcmltLT5vZmZzZXQ7Cgl1MzIgKmRhdGE7CglpbnQgZHdvcmRzOwoJaW50IGkgPSAwOwoJaW50IHN0YXJ0ID0gcHJpbS0+c3RhcnQgKyBSQURFT05fSU5ERVhfUFJJTV9PRkZTRVQ7CglpbnQgY291bnQgPSAocHJpbS0+ZmluaXNoIC0gc3RhcnQpIC8gc2l6ZW9mKHUxNik7CglpbnQgbmJveCA9IHNhcmVhX3ByaXYtPm5ib3g7CgoJRFJNX0RFQlVHKCJod3ByaW0gMHgleCB2Zm10IDB4JXggJWQuLiVkIG9mZnNldDogJXggbnIgJWRcbiIsCgkJICBwcmltLT5wcmltLAoJCSAgcHJpbS0+dmNfZm9ybWF0LAoJCSAgcHJpbS0+c3RhcnQsIHByaW0tPmZpbmlzaCwgcHJpbS0+b2Zmc2V0LCBwcmltLT5udW12ZXJ0cyk7CgoJaWYgKGJhZF9wcmltX3ZlcnRleF9ucihwcmltLT5wcmltLCBjb3VudCkpIHsKCQlEUk1fRVJST1IoImJhZCBwcmltICV4IGNvdW50ICVkXG4iLCBwcmltLT5wcmltLCBjb3VudCk7CgkJcmV0dXJuOwoJfQoKCWlmIChzdGFydCA+PSBwcmltLT5maW5pc2ggfHwgKHByaW0tPnN0YXJ0ICYgMHg3KSkgewoJCURSTV9FUlJPUigiYnVmZmVyIHByaW0gJWRcbiIsIHByaW0tPnByaW0pOwoJCXJldHVybjsKCX0KCglkd29yZHMgPSAocHJpbS0+ZmluaXNoIC0gcHJpbS0+c3RhcnQgKyAzKSAvIHNpemVvZih1MzIpOwoKCWRhdGEgPSAodTMyICopICgoY2hhciAqKWRldi0+YWdwX2J1ZmZlcl9tYXAtPmhhbmRsZSArCgkJCWVsdF9idWYtPm9mZnNldCArIHByaW0tPnN0YXJ0KTsKCglkYXRhWzBdID0gQ1BfUEFDS0VUMyhSQURFT05fM0RfUk5EUl9HRU5fSU5EWF9QUklNLCBkd29yZHMgLSAyKTsKCWRhdGFbMV0gPSBvZmZzZXQ7CglkYXRhWzJdID0gcHJpbS0+bnVtdmVydHM7CglkYXRhWzNdID0gcHJpbS0+dmNfZm9ybWF0OwoJZGF0YVs0XSA9IChwcmltLT5wcmltIHwKCQkgICBSQURFT05fUFJJTV9XQUxLX0lORCB8CgkJICAgUkFERU9OX0NPTE9SX09SREVSX1JHQkEgfAoJCSAgIFJBREVPTl9WVFhfRk1UX1JBREVPTl9NT0RFIHwKCQkgICAoY291bnQgPDwgUkFERU9OX05VTV9WRVJUSUNFU19TSElGVCkpOwoKCWRvIHsKCQlpZiAoaSA8IG5ib3gpCgkJCXJhZGVvbl9lbWl0X2NsaXBfcmVjdChkZXZfcHJpdiwgJnNhcmVhX3ByaXYtPmJveGVzW2ldKTsKCgkJcmFkZW9uX2NwX2Rpc3BhdGNoX2luZGlyZWN0KGRldiwgZWx0X2J1ZiwKCQkJCQkgICAgcHJpbS0+c3RhcnQsIHByaW0tPmZpbmlzaCk7CgoJCWkrKzsKCX0gd2hpbGUgKGkgPCBuYm94KTsKCn0KCiNkZWZpbmUgUkFERU9OX01BWF9URVhUVVJFX1NJWkUgUkFERU9OX0JVRkZFUl9TSVpFCgpzdGF0aWMgaW50IHJhZGVvbl9jcF9kaXNwYXRjaF90ZXh0dXJlKERSTUZJTEUgZmlscCwKCQkJCSAgICAgIGRybV9kZXZpY2VfdCAqIGRldiwKCQkJCSAgICAgIGRybV9yYWRlb25fdGV4dHVyZV90ICogdGV4LAoJCQkJICAgICAgZHJtX3JhZGVvbl90ZXhfaW1hZ2VfdCAqIGltYWdlKQp7Cglkcm1fcmFkZW9uX3ByaXZhdGVfdCAqZGV2X3ByaXYgPSBkZXYtPmRldl9wcml2YXRlOwoJZHJtX2ZpbGVfdCAqZmlscF9wcml2OwoJZHJtX2J1Zl90ICpidWY7Cgl1MzIgZm9ybWF0OwoJdTMyICpidWZmZXI7Cgljb25zdCB1OCBfX3VzZXIgKmRhdGE7CglpbnQgc2l6ZSwgZHdvcmRzLCB0ZXhfd2lkdGgsIGJsaXRfd2lkdGgsIHNwaXRjaDsKCXUzMiBoZWlnaHQ7CglpbnQgaTsKCXUzMiB0ZXhwaXRjaCwgbWljcm90aWxlOwoJdTMyIG9mZnNldDsKCVJJTkdfTE9DQUxTOwoKCURSTV9HRVRfUFJJVl9XSVRIX1JFVFVSTihmaWxwX3ByaXYsIGZpbHApOwoKCWlmIChyYWRlb25fY2hlY2tfYW5kX2ZpeHVwX29mZnNldChkZXZfcHJpdiwgZmlscF9wcml2LCAmdGV4LT5vZmZzZXQpKSB7CgkJRFJNX0VSUk9SKCJJbnZhbGlkIGRlc3RpbmF0aW9uIG9mZnNldFxuIik7CgkJcmV0dXJuIERSTV9FUlIoRUlOVkFMKTsKCX0KCglkZXZfcHJpdi0+c3RhdHMuYm94ZXMgfD0gUkFERU9OX0JPWF9URVhUVVJFX0xPQUQ7CgoJLyogRmx1c2ggdGhlIHBpeGVsIGNhY2hlLiAgVGhpcyBlbnN1cmVzIG5vIHBpeGVsIGRhdGEgZ2V0cyBtaXhlZAoJICogdXAgd2l0aCB0aGUgdGV4dHVyZSBkYXRhIGZyb20gdGhlIGhvc3QgZGF0YSBibGl0LCBvdGhlcndpc2UKCSAqIHBhcnQgb2YgdGhlIHRleHR1cmUgaW1hZ2UgbWF5IGJlIGNvcnJ1cHRlZC4KCSAqLwoJQkVHSU5fUklORyg0KTsKCVJBREVPTl9GTFVTSF9DQUNIRSgpOwoJUkFERU9OX1dBSVRfVU5USUxfSURMRSgpOwoJQURWQU5DRV9SSU5HKCk7CgoJLyogVGhlIGNvbXBpbGVyIHdvbid0IG9wdGltaXplIGF3YXkgYSBkaXZpc2lvbiBieSBhIHZhcmlhYmxlLAoJICogZXZlbiBpZiB0aGUgb25seSBsZWdhbCB2YWx1ZXMgYXJlIHBvd2VycyBvZiB0d28uICBUaHVzLCB3ZSdsbAoJICogdXNlIGEgc2hpZnQgaW5zdGVhZC4KCSAqLwoJc3dpdGNoICh0ZXgtPmZvcm1hdCkgewoJY2FzZSBSQURFT05fVFhGT1JNQVRfQVJHQjg4ODg6CgljYXNlIFJBREVPTl9UWEZPUk1BVF9SR0JBODg4ODoKCQlmb3JtYXQgPSBSQURFT05fQ09MT1JfRk9STUFUX0FSR0I4ODg4OwoJCXRleF93aWR0aCA9IHRleC0+d2lkdGggKiA0OwoJCWJsaXRfd2lkdGggPSBpbWFnZS0+d2lkdGggKiA0OwoJCWJyZWFrOwoJY2FzZSBSQURFT05fVFhGT1JNQVRfQUk4ODoKCWNhc2UgUkFERU9OX1RYRk9STUFUX0FSR0IxNTU1OgoJY2FzZSBSQURFT05fVFhGT1JNQVRfUkdCNTY1OgoJY2FzZSBSQURFT05fVFhGT1JNQVRfQVJHQjQ0NDQ6CgljYXNlIFJBREVPTl9UWEZPUk1BVF9WWVVZNDIyOgoJY2FzZSBSQURFT05fVFhGT1JNQVRfWVZZVTQyMjoKCQlmb3JtYXQgPSBSQURFT05fQ09MT1JfRk9STUFUX1JHQjU2NTsKCQl0ZXhfd2lkdGggPSB0ZXgtPndpZHRoICogMjsKCQlibGl0X3dpZHRoID0gaW1hZ2UtPndpZHRoICogMjsKCQlicmVhazsKCWNhc2UgUkFERU9OX1RYRk9STUFUX0k4OgoJY2FzZSBSQURFT05fVFhGT1JNQVRfUkdCMzMyOgoJCWZvcm1hdCA9IFJBREVPTl9DT0xPUl9GT1JNQVRfQ0k4OwoJCXRleF93aWR0aCA9IHRleC0+d2lkdGggKiAxOwoJCWJsaXRfd2lkdGggPSBpbWFnZS0+d2lkdGggKiAxOwoJCWJyZWFrOwoJZGVmYXVsdDoKCQlEUk1fRVJST1IoImludmFsaWQgdGV4dHVyZSBmb3JtYXQgJWRcbiIsIHRleC0+Zm9ybWF0KTsKCQlyZXR1cm4gRFJNX0VSUihFSU5WQUwpOwoJfQoJc3BpdGNoID0gYmxpdF93aWR0aCA+PiA2OwoJaWYgKHNwaXRjaCA9PSAwICYmIGltYWdlLT5oZWlnaHQgPiAxKQoJCXJldHVybiBEUk1fRVJSKEVJTlZBTCk7CgoJdGV4cGl0Y2ggPSB0ZXgtPnBpdGNoOwoJaWYgKCh0ZXhwaXRjaCA8PCAyMikgJiBSQURFT05fRFNUX1RJTEVfTUlDUk8pIHsKCQltaWNyb3RpbGUgPSAxOwoJCWlmICh0ZXhfd2lkdGggPCA2NCkgewoJCQl0ZXhwaXRjaCAmPSB+KFJBREVPTl9EU1RfVElMRV9NSUNSTyA+PiAyMik7CgkJCS8qIHdlIGdvdCB0aWxlZCBjb29yZGluYXRlcywgdW50aWxlIHRoZW0gKi8KCQkJaW1hZ2UtPnggKj0gMjsKCQl9Cgl9IGVsc2UKCQltaWNyb3RpbGUgPSAwOwoKCURSTV9ERUJVRygidGV4PSVkeCVkIGJsaXQ9JWRcbiIsIHRleF93aWR0aCwgdGV4LT5oZWlnaHQsIGJsaXRfd2lkdGgpOwoKCWRvIHsKCQlEUk1fREVCVUcoInRleDogb2ZzPTB4JXggcD0lZCBmPSVkIHg9JWhkIHk9JWhkIHc9JWhkIGg9JWhkXG4iLAoJCQkgIHRleC0+b2Zmc2V0ID4+IDEwLCB0ZXgtPnBpdGNoLCB0ZXgtPmZvcm1hdCwKCQkJICBpbWFnZS0+eCwgaW1hZ2UtPnksIGltYWdlLT53aWR0aCwgaW1hZ2UtPmhlaWdodCk7CgoJCS8qIE1ha2UgYSBjb3B5IG9mIHNvbWUgcGFyYW1ldGVycyBpbiBjYXNlIHdlIGhhdmUgdG8KCQkgKiB1cGRhdGUgdGhlbSBmb3IgYSBtdWx0aS1wYXNzIHRleHR1cmUgYmxpdC4KCQkgKi8KCQloZWlnaHQgPSBpbWFnZS0+aGVpZ2h0OwoJCWRhdGEgPSAoY29uc3QgdTggX191c2VyICopaW1hZ2UtPmRhdGE7CgoJCXNpemUgPSBoZWlnaHQgKiBibGl0X3dpZHRoOwoKCQlpZiAoc2l6ZSA+IFJBREVPTl9NQVhfVEVYVFVSRV9TSVpFKSB7CgkJCWhlaWdodCA9IFJBREVPTl9NQVhfVEVYVFVSRV9TSVpFIC8gYmxpdF93aWR0aDsKCQkJc2l6ZSA9IGhlaWdodCAqIGJsaXRfd2lkdGg7CgkJfSBlbHNlIGlmIChzaXplIDwgNCAmJiBzaXplID4gMCkgewoJCQlzaXplID0gNDsKCQl9IGVsc2UgaWYgKHNpemUgPT0gMCkgewoJCQlyZXR1cm4gMDsKCQl9CgoJCWJ1ZiA9IHJhZGVvbl9mcmVlbGlzdF9nZXQoZGV2KTsKCQlpZiAoMCAmJiAhYnVmKSB7CgkJCXJhZGVvbl9kb19jcF9pZGxlKGRldl9wcml2KTsKCQkJYnVmID0gcmFkZW9uX2ZyZWVsaXN0X2dldChkZXYpOwoJCX0KCQlpZiAoIWJ1ZikgewoJCQlEUk1fREVCVUcoInJhZGVvbl9jcF9kaXNwYXRjaF90ZXh0dXJlOiBFQUdBSU5cbiIpOwoJCQlpZiAoRFJNX0NPUFlfVE9fVVNFUih0ZXgtPmltYWdlLCBpbWFnZSwgc2l6ZW9mKCppbWFnZSkpKQoJCQkJcmV0dXJuIERSTV9FUlIoRUZBVUxUKTsKCQkJcmV0dXJuIERSTV9FUlIoRUFHQUlOKTsKCQl9CgoJCS8qIERpc3BhdGNoIHRoZSBpbmRpcmVjdCBidWZmZXIuCgkJICovCgkJYnVmZmVyID0KCQkgICAgKHUzMiAqKSAoKGNoYXIgKilkZXYtPmFncF9idWZmZXJfbWFwLT5oYW5kbGUgKyBidWYtPm9mZnNldCk7CgkJZHdvcmRzID0gc2l6ZSAvIDQ7CgojZGVmaW5lIFJBREVPTl9DT1BZX01UKF9idWYsIF9kYXRhLCBfd2lkdGgpIFwKCWRvIHsgXAoJCWlmIChEUk1fQ09QWV9GUk9NX1VTRVIoX2J1ZiwgX2RhdGEsIChfd2lkdGgpKSkge1wKCQkJRFJNX0VSUk9SKCJFRkFVTFQgb24gcGFkLCAlZCBieXRlc1xuIiwgKF93aWR0aCkpOyBcCgkJCXJldHVybiBEUk1fRVJSKEVGQVVMVCk7IFwKCQl9IFwKCX0gd2hpbGUoMCkKCgkJaWYgKG1pY3JvdGlsZSkgewoJCQkvKiB0ZXh0dXJlIG1pY3JvIHRpbGluZyBpbiB1c2UsIG1pbmltdW0gdGV4dHVyZSB3aWR0aCBpcyB0aHVzIDE2IGJ5dGVzLgoJCQkgICBob3dldmVyLCB3ZSBjYW5ub3QgdXNlIGJsaXR0ZXIgZGlyZWN0bHkgZm9yIHRleHR1cmUgd2lkdGggPCA2NCBieXRlcywKCQkJICAgc2luY2UgbWluaW11bSB0ZXggcGl0Y2ggaXMgNjQgYnl0ZXMgYW5kIHdlIG5lZWQgdGhpcyB0byBtYXRjaAoJCQkgICB0aGUgdGV4dHVyZSB3aWR0aCwgb3RoZXJ3aXNlIHRoZSBibGl0dGVyIHdpbGwgdGlsZSBpdCB3cm9uZy4KCQkJICAgVGh1cywgdGlsaW5nIG1hbnVhbGx5IGluIHRoaXMgY2FzZS4gQWRkaXRpb25hbGx5LCBuZWVkIHRvIHNwZWNpYWwKCQkJICAgY2FzZSB0ZXggaGVpZ2h0ID0gMSwgc2luY2Ugb3VyIGFjdHVhbCBpbWFnZSB3aWxsIGhhdmUgaGVpZ2h0IDIKCQkJICAgYW5kIHdlIG5lZWQgdG8gZW5zdXJlIHdlIGRvbid0IHJlYWQgYmV5b25kIHRoZSB0ZXh0dXJlIHNpemUKCQkJICAgZnJvbSB1c2VyIHNwYWNlLiAqLwoJCQlpZiAodGV4LT5oZWlnaHQgPT0gMSkgewoJCQkJaWYgKHRleF93aWR0aCA+PSA2NCB8fCB0ZXhfd2lkdGggPD0gMTYpIHsKCQkJCQlSQURFT05fQ09QWV9NVChidWZmZXIsIGRhdGEsCgkJCQkJCShpbnQpKHRleF93aWR0aCAqIHNpemVvZih1MzIpKSk7CgkJCQl9IGVsc2UgaWYgKHRleF93aWR0aCA9PSAzMikgewoJCQkJCVJBREVPTl9DT1BZX01UKGJ1ZmZlciwgZGF0YSwgMTYpOwoJCQkJCVJBREVPTl9DT1BZX01UKGJ1ZmZlciArIDgsCgkJCQkJCSAgICAgICBkYXRhICsgMTYsIDE2KTsKCQkJCX0KCQkJfSBlbHNlIGlmICh0ZXhfd2lkdGggPj0gNjQgfHwgdGV4X3dpZHRoID09IDE2KSB7CgkJCQlSQURFT05fQ09QWV9NVChidWZmZXIsIGRhdGEsCgkJCQkJICAgICAgIChpbnQpKGR3b3JkcyAqIHNpemVvZih1MzIpKSk7CgkJCX0gZWxzZSBpZiAodGV4X3dpZHRoIDwgMTYpIHsKCQkJCWZvciAoaSA9IDA7IGkgPCB0ZXgtPmhlaWdodDsgaSsrKSB7CgkJCQkJUkFERU9OX0NPUFlfTVQoYnVmZmVyLCBkYXRhLCB0ZXhfd2lkdGgpOwoJCQkJCWJ1ZmZlciArPSA0OwoJCQkJCWRhdGEgKz0gdGV4X3dpZHRoOwoJCQkJfQoJCQl9IGVsc2UgaWYgKHRleF93aWR0aCA9PSAzMikgewoJCQkJLyogVE9ETzogbWFrZSBzdXJlIHRoaXMgd29ya3Mgd2hlbiBub3QgZml0dGluZyBpbiBvbmUgYnVmZmVyCgkJCQkgICAoaS5lLiAzMmJ5dGVzIHggMjA0OC4uLikgKi8KCQkJCWZvciAoaSA9IDA7IGkgPCB0ZXgtPmhlaWdodDsgaSArPSAyKSB7CgkJCQkJUkFERU9OX0NPUFlfTVQoYnVmZmVyLCBkYXRhLCAxNik7CgkJCQkJZGF0YSArPSAxNjsKCQkJCQlSQURFT05fQ09QWV9NVChidWZmZXIgKyA4LCBkYXRhLCAxNik7CgkJCQkJZGF0YSArPSAxNjsKCQkJCQlSQURFT05fQ09QWV9NVChidWZmZXIgKyA0LCBkYXRhLCAxNik7CgkJCQkJZGF0YSArPSAxNjsKCQkJCQlSQURFT05fQ09QWV9NVChidWZmZXIgKyAxMiwgZGF0YSwgMTYpOwoJCQkJCWRhdGEgKz0gMTY7CgkJCQkJYnVmZmVyICs9IDE2OwoJCQkJfQoJCQl9CgkJfSBlbHNlIHsKCQkJaWYgKHRleF93aWR0aCA+PSAzMikgewoJCQkJLyogVGV4dHVyZSBpbWFnZSB3aWR0aCBpcyBsYXJnZXIgdGhhbiB0aGUgbWluaW11bSwgc28gd2UKCQkJCSAqIGNhbiB1cGxvYWQgaXQgZGlyZWN0bHkuCgkJCQkgKi8KCQkJCVJBREVPTl9DT1BZX01UKGJ1ZmZlciwgZGF0YSwKCQkJCQkgICAgICAgKGludCkoZHdvcmRzICogc2l6ZW9mKHUzMikpKTsKCQkJfSBlbHNlIHsKCQkJCS8qIFRleHR1cmUgaW1hZ2Ugd2lkdGggaXMgbGVzcyB0aGFuIHRoZSBtaW5pbXVtLCBzbyB3ZQoJCQkJICogbmVlZCB0byBwYWQgb3V0IGVhY2ggaW1hZ2Ugc2NhbmxpbmUgdG8gdGhlIG1pbmltdW0KCQkJCSAqIHdpZHRoLgoJCQkJICovCgkJCQlmb3IgKGkgPSAwOyBpIDwgdGV4LT5oZWlnaHQ7IGkrKykgewoJCQkJCVJBREVPTl9DT1BZX01UKGJ1ZmZlciwgZGF0YSwgdGV4X3dpZHRoKTsKCQkJCQlidWZmZXIgKz0gODsKCQkJCQlkYXRhICs9IHRleF93aWR0aDsKCQkJCX0KCQkJfQoJCX0KCiN1bmRlZiBSQURFT05fQ09QWV9NVAoJCWJ1Zi0+ZmlscCA9IGZpbHA7CgkJYnVmLT51c2VkID0gc2l6ZTsKCQlvZmZzZXQgPSBkZXZfcHJpdi0+Z2FydF9idWZmZXJzX29mZnNldCArIGJ1Zi0+b2Zmc2V0OwoJCUJFR0lOX1JJTkcoOSk7CgkJT1VUX1JJTkcoQ1BfUEFDS0VUMyhSQURFT05fQ05UTF9CSVRCTFRfTVVMVEksIDUpKTsKCQlPVVRfUklORyhSQURFT05fR01DX1NSQ19QSVRDSF9PRkZTRVRfQ05UTCB8CgkJCSBSQURFT05fR01DX0RTVF9QSVRDSF9PRkZTRVRfQ05UTCB8CgkJCSBSQURFT05fR01DX0JSVVNIX05PTkUgfAoJCQkgKGZvcm1hdCA8PCA4KSB8CgkJCSBSQURFT05fR01DX1NSQ19EQVRBVFlQRV9DT0xPUiB8CgkJCSBSQURFT05fUk9QM19TIHwKCQkJIFJBREVPTl9EUF9TUkNfU09VUkNFX01FTU9SWSB8CgkJCSBSQURFT05fR01DX0NMUl9DTVBfQ05UTF9ESVMgfCBSQURFT05fR01DX1dSX01TS19ESVMpOwoJCU9VVF9SSU5HKChzcGl0Y2ggPDwgMjIpIHwgKG9mZnNldCA+PiAxMCkpOwoJCU9VVF9SSU5HKCh0ZXhwaXRjaCA8PCAyMikgfCAodGV4LT5vZmZzZXQgPj4gMTApKTsKCQlPVVRfUklORygwKTsKCQlPVVRfUklORygoaW1hZ2UtPnggPDwgMTYpIHwgaW1hZ2UtPnkpOwoJCU9VVF9SSU5HKChpbWFnZS0+d2lkdGggPDwgMTYpIHwgaGVpZ2h0KTsKCQlSQURFT05fV0FJVF9VTlRJTF8yRF9JRExFKCk7CgkJQURWQU5DRV9SSU5HKCk7CgoJCXJhZGVvbl9jcF9kaXNjYXJkX2J1ZmZlcihkZXYsIGJ1Zik7CgoJCS8qIFVwZGF0ZSB0aGUgaW5wdXQgcGFyYW1ldGVycyBmb3IgbmV4dCB0aW1lICovCgkJaW1hZ2UtPnkgKz0gaGVpZ2h0OwoJCWltYWdlLT5oZWlnaHQgLT0gaGVpZ2h0OwoJCWltYWdlLT5kYXRhID0gKGNvbnN0IHU4IF9fdXNlciAqKWltYWdlLT5kYXRhICsgc2l6ZTsKCX0gd2hpbGUgKGltYWdlLT5oZWlnaHQgPiAwKTsKCgkvKiBGbHVzaCB0aGUgcGl4ZWwgY2FjaGUgYWZ0ZXIgdGhlIGJsaXQgY29tcGxldGVzLiAgVGhpcyBlbnN1cmVzCgkgKiB0aGUgdGV4dHVyZSBkYXRhIGlzIHdyaXR0ZW4gb3V0IHRvIG1lbW9yeSBiZWZvcmUgcmVuZGVyaW5nCgkgKiBjb250aW51ZXMuCgkgKi8KCUJFR0lOX1JJTkcoNCk7CglSQURFT05fRkxVU0hfQ0FDSEUoKTsKCVJBREVPTl9XQUlUX1VOVElMXzJEX0lETEUoKTsKCUFEVkFOQ0VfUklORygpOwoJcmV0dXJuIDA7Cn0KCnN0YXRpYyB2b2lkIHJhZGVvbl9jcF9kaXNwYXRjaF9zdGlwcGxlKGRybV9kZXZpY2VfdCAqIGRldiwgdTMyICogc3RpcHBsZSkKewoJZHJtX3JhZGVvbl9wcml2YXRlX3QgKmRldl9wcml2ID0gZGV2LT5kZXZfcHJpdmF0ZTsKCWludCBpOwoJUklOR19MT0NBTFM7CglEUk1fREVCVUcoIlxuIik7CgoJQkVHSU5fUklORygzNSk7CgoJT1VUX1JJTkcoQ1BfUEFDS0VUMChSQURFT05fUkVfU1RJUFBMRV9BRERSLCAwKSk7CglPVVRfUklORygweDAwMDAwMDAwKTsKCglPVVRfUklORyhDUF9QQUNLRVQwX1RBQkxFKFJBREVPTl9SRV9TVElQUExFX0RBVEEsIDMxKSk7Cglmb3IgKGkgPSAwOyBpIDwgMzI7IGkrKykgewoJCU9VVF9SSU5HKHN0aXBwbGVbaV0pOwoJfQoKCUFEVkFOQ0VfUklORygpOwp9CgpzdGF0aWMgdm9pZCByYWRlb25fYXBwbHlfc3VyZmFjZV9yZWdzKGludCBzdXJmX2luZGV4LAoJCQkJICAgICAgZHJtX3JhZGVvbl9wcml2YXRlX3QgKmRldl9wcml2KQp7CglpZiAoIWRldl9wcml2LT5tbWlvKQoJCXJldHVybjsKCglyYWRlb25fZG9fY3BfaWRsZShkZXZfcHJpdik7CgoJUkFERU9OX1dSSVRFKFJBREVPTl9TVVJGQUNFMF9JTkZPICsgMTYgKiBzdXJmX2luZGV4LAoJCSAgICAgZGV2X3ByaXYtPnN1cmZhY2VzW3N1cmZfaW5kZXhdLmZsYWdzKTsKCVJBREVPTl9XUklURShSQURFT05fU1VSRkFDRTBfTE9XRVJfQk9VTkQgKyAxNiAqIHN1cmZfaW5kZXgsCgkJICAgICBkZXZfcHJpdi0+c3VyZmFjZXNbc3VyZl9pbmRleF0ubG93ZXIpOwoJUkFERU9OX1dSSVRFKFJBREVPTl9TVVJGQUNFMF9VUFBFUl9CT1VORCArIDE2ICogc3VyZl9pbmRleCwKCQkgICAgIGRldl9wcml2LT5zdXJmYWNlc1tzdXJmX2luZGV4XS51cHBlcik7Cn0KCi8qIEFsbG9jYXRlcyBhIHZpcnR1YWwgc3VyZmFjZQogKiBkb2Vzbid0IGFsd2F5cyBhbGxvY2F0ZSBhIHJlYWwgc3VyZmFjZSwgd2lsbCBzdHJldGNoIGFuIGV4aXN0aW5nCiAqIHN1cmZhY2Ugd2hlbiBwb3NzaWJsZS4KICoKICogTm90ZSB0aGF0IHJlZmNvdW50IGNhbiBiZSBhdCBtb3N0IDIsIHNpbmNlIGR1cmluZyBhIGZyZWUgcmVmY291bnQ9MwogKiBtaWdodCBtZWFuIHdlIGhhdmUgdG8gYWxsb2NhdGUgYSBuZXcgc3VyZmFjZSB3aGljaCBtaWdodCBub3QgYWx3YXlzCiAqIGJlIGF2YWlsYWJsZS4KICogRm9yIGV4YW1wbGUgOiB3ZSBhbGxvY2F0ZSB0aHJlZSBjb250aWdvdXMgc3VyZmFjZXMgQUJDLiBJZiBCIGlzCiAqIGZyZWVkLCB3ZSBzdWRkZW5seSBuZWVkIHR3byBzdXJmYWNlcyB0byBzdG9yZSBBIGFuZCBDLCB3aGljaCBtaWdodAogKiBub3QgYWx3YXlzIGJlIGF2YWlsYWJsZS4KICovCnN0YXRpYyBpbnQgYWxsb2Nfc3VyZmFjZShkcm1fcmFkZW9uX3N1cmZhY2VfYWxsb2NfdCAqbmV3LAoJCQkgZHJtX3JhZGVvbl9wcml2YXRlX3QgKmRldl9wcml2LCBEUk1GSUxFIGZpbHApCnsKCXN0cnVjdCByYWRlb25fdmlydF9zdXJmYWNlICpzOwoJaW50IGk7CglpbnQgdmlydF9zdXJmYWNlX2luZGV4OwoJdWludDMyX3QgbmV3X3VwcGVyLCBuZXdfbG93ZXI7CgoJbmV3X2xvd2VyID0gbmV3LT5hZGRyZXNzOwoJbmV3X3VwcGVyID0gbmV3X2xvd2VyICsgbmV3LT5zaXplIC0gMTsKCgkvKiBzYW5pdHkgY2hlY2sgKi8KCWlmICgobmV3X2xvd2VyID49IG5ld191cHBlcikgfHwgKG5ldy0+ZmxhZ3MgPT0gMCkgfHwgKG5ldy0+c2l6ZSA9PSAwKSB8fAoJICAgICgobmV3X3VwcGVyICYgUkFERU9OX1NVUkZfQUREUkVTU19GSVhFRF9NQVNLKSAhPQoJICAgICBSQURFT05fU1VSRl9BRERSRVNTX0ZJWEVEX01BU0spCgkgICAgfHwgKChuZXdfbG93ZXIgJiBSQURFT05fU1VSRl9BRERSRVNTX0ZJWEVEX01BU0spICE9IDApKQoJCXJldHVybiAtMTsKCgkvKiBtYWtlIHN1cmUgdGhlcmUgaXMgbm8gb3ZlcmxhcCB3aXRoIGV4aXN0aW5nIHN1cmZhY2VzICovCglmb3IgKGkgPSAwOyBpIDwgUkFERU9OX01BWF9TVVJGQUNFUzsgaSsrKSB7CgkJaWYgKChkZXZfcHJpdi0+c3VyZmFjZXNbaV0ucmVmY291bnQgIT0gMCkgJiYKCQkgICAgKCgobmV3X2xvd2VyID49IGRldl9wcml2LT5zdXJmYWNlc1tpXS5sb3dlcikgJiYKCQkgICAgICAobmV3X2xvd2VyIDwgZGV2X3ByaXYtPnN1cmZhY2VzW2ldLnVwcGVyKSkgfHwKCQkgICAgICgobmV3X2xvd2VyIDwgZGV2X3ByaXYtPnN1cmZhY2VzW2ldLmxvd2VyKSAmJgoJCSAgICAgIChuZXdfdXBwZXIgPiBkZXZfcHJpdi0+c3VyZmFjZXNbaV0ubG93ZXIpKSkpIHsKCQkJcmV0dXJuIC0xOwoJCX0KCX0KCgkvKiBmaW5kIGEgdmlydHVhbCBzdXJmYWNlICovCglmb3IgKGkgPSAwOyBpIDwgMiAqIFJBREVPTl9NQVhfU1VSRkFDRVM7IGkrKykKCQlpZiAoZGV2X3ByaXYtPnZpcnRfc3VyZmFjZXNbaV0uZmlscCA9PSAwKQoJCQlicmVhazsKCWlmIChpID09IDIgKiBSQURFT05fTUFYX1NVUkZBQ0VTKSB7CgkJcmV0dXJuIC0xOwoJfQoJdmlydF9zdXJmYWNlX2luZGV4ID0gaTsKCgkvKiB0cnkgdG8gcmV1c2UgYW4gZXhpc3Rpbmcgc3VyZmFjZSAqLwoJZm9yIChpID0gMDsgaSA8IFJBREVPTl9NQVhfU1VSRkFDRVM7IGkrKykgewoJCS8qIGV4dGVuZCBiZWZvcmUgKi8KCQlpZiAoKGRldl9wcml2LT5zdXJmYWNlc1tpXS5yZWZjb3VudCA9PSAxKSAmJgoJCSAgICAobmV3LT5mbGFncyA9PSBkZXZfcHJpdi0+c3VyZmFjZXNbaV0uZmxhZ3MpICYmCgkJICAgIChuZXdfdXBwZXIgKyAxID09IGRldl9wcml2LT5zdXJmYWNlc1tpXS5sb3dlcikpIHsKCQkJcyA9ICYoZGV2X3ByaXYtPnZpcnRfc3VyZmFjZXNbdmlydF9zdXJmYWNlX2luZGV4XSk7CgkJCXMtPnN1cmZhY2VfaW5kZXggPSBpOwoJCQlzLT5sb3dlciA9IG5ld19sb3dlcjsKCQkJcy0+dXBwZXIgPSBuZXdfdXBwZXI7CgkJCXMtPmZsYWdzID0gbmV3LT5mbGFnczsKCQkJcy0+ZmlscCA9IGZpbHA7CgkJCWRldl9wcml2LT5zdXJmYWNlc1tpXS5yZWZjb3VudCsrOwoJCQlkZXZfcHJpdi0+c3VyZmFjZXNbaV0ubG93ZXIgPSBzLT5sb3dlcjsKCQkJcmFkZW9uX2FwcGx5X3N1cmZhY2VfcmVncyhzLT5zdXJmYWNlX2luZGV4LCBkZXZfcHJpdik7CgkJCXJldHVybiB2aXJ0X3N1cmZhY2VfaW5kZXg7CgkJfQoKCQkvKiBleHRlbmQgYWZ0ZXIgKi8KCQlpZiAoKGRldl9wcml2LT5zdXJmYWNlc1tpXS5yZWZjb3VudCA9PSAxKSAmJgoJCSAgICAobmV3LT5mbGFncyA9PSBkZXZfcHJpdi0+c3VyZmFjZXNbaV0uZmxhZ3MpICYmCgkJICAgIChuZXdfbG93ZXIgPT0gZGV2X3ByaXYtPnN1cmZhY2VzW2ldLnVwcGVyICsgMSkpIHsKCQkJcyA9ICYoZGV2X3ByaXYtPnZpcnRfc3VyZmFjZXNbdmlydF9zdXJmYWNlX2luZGV4XSk7CgkJCXMtPnN1cmZhY2VfaW5kZXggPSBpOwoJCQlzLT5sb3dlciA9IG5ld19sb3dlcjsKCQkJcy0+dXBwZXIgPSBuZXdfdXBwZXI7CgkJCXMtPmZsYWdzID0gbmV3LT5mbGFnczsKCQkJcy0+ZmlscCA9IGZpbHA7CgkJCWRldl9wcml2LT5zdXJmYWNlc1tpXS5yZWZjb3VudCsrOwoJCQlkZXZfcHJpdi0+c3VyZmFjZXNbaV0udXBwZXIgPSBzLT51cHBlcjsKCQkJcmFkZW9uX2FwcGx5X3N1cmZhY2VfcmVncyhzLT5zdXJmYWNlX2luZGV4LCBkZXZfcHJpdik7CgkJCXJldHVybiB2aXJ0X3N1cmZhY2VfaW5kZXg7CgkJfQoJfQoKCS8qIG9rYXksIHdlIG5lZWQgYSBuZXcgb25lICovCglmb3IgKGkgPSAwOyBpIDwgUkFERU9OX01BWF9TVVJGQUNFUzsgaSsrKSB7CgkJaWYgKGRldl9wcml2LT5zdXJmYWNlc1tpXS5yZWZjb3VudCA9PSAwKSB7CgkJCXMgPSAmKGRldl9wcml2LT52aXJ0X3N1cmZhY2VzW3ZpcnRfc3VyZmFjZV9pbmRleF0pOwoJCQlzLT5zdXJmYWNlX2luZGV4ID0gaTsKCQkJcy0+bG93ZXIgPSBuZXdfbG93ZXI7CgkJCXMtPnVwcGVyID0gbmV3X3VwcGVyOwoJCQlzLT5mbGFncyA9IG5ldy0+ZmxhZ3M7CgkJCXMtPmZpbHAgPSBmaWxwOwoJCQlkZXZfcHJpdi0+c3VyZmFjZXNbaV0ucmVmY291bnQgPSAxOwoJCQlkZXZfcHJpdi0+c3VyZmFjZXNbaV0ubG93ZXIgPSBzLT5sb3dlcjsKCQkJZGV2X3ByaXYtPnN1cmZhY2VzW2ldLnVwcGVyID0gcy0+dXBwZXI7CgkJCWRldl9wcml2LT5zdXJmYWNlc1tpXS5mbGFncyA9IHMtPmZsYWdzOwoJCQlyYWRlb25fYXBwbHlfc3VyZmFjZV9yZWdzKHMtPnN1cmZhY2VfaW5kZXgsIGRldl9wcml2KTsKCQkJcmV0dXJuIHZpcnRfc3VyZmFjZV9pbmRleDsKCQl9Cgl9CgoJLyogd2UgZGlkbid0IGZpbmQgYW55dGhpbmcgKi8KCXJldHVybiAtMTsKfQoKc3RhdGljIGludCBmcmVlX3N1cmZhY2UoRFJNRklMRSBmaWxwLCBkcm1fcmFkZW9uX3ByaXZhdGVfdCAqIGRldl9wcml2LAoJCQlpbnQgbG93ZXIpCnsKCXN0cnVjdCByYWRlb25fdmlydF9zdXJmYWNlICpzOwoJaW50IGk7CgkvKiBmaW5kIHRoZSB2aXJ0dWFsIHN1cmZhY2UgKi8KCWZvciAoaSA9IDA7IGkgPCAyICogUkFERU9OX01BWF9TVVJGQUNFUzsgaSsrKSB7CgkJcyA9ICYoZGV2X3ByaXYtPnZpcnRfc3VyZmFjZXNbaV0pOwoJCWlmIChzLT5maWxwKSB7CgkJCWlmICgobG93ZXIgPT0gcy0+bG93ZXIpICYmIChmaWxwID09IHMtPmZpbHApKSB7CgkJCQlpZiAoZGV2X3ByaXYtPnN1cmZhY2VzW3MtPnN1cmZhY2VfaW5kZXhdLgoJCQkJICAgIGxvd2VyID09IHMtPmxvd2VyKQoJCQkJCWRldl9wcml2LT5zdXJmYWNlc1tzLT5zdXJmYWNlX2luZGV4XS4KCQkJCQkgICAgbG93ZXIgPSBzLT51cHBlcjsKCgkJCQlpZiAoZGV2X3ByaXYtPnN1cmZhY2VzW3MtPnN1cmZhY2VfaW5kZXhdLgoJCQkJICAgIHVwcGVyID09IHMtPnVwcGVyKQoJCQkJCWRldl9wcml2LT5zdXJmYWNlc1tzLT5zdXJmYWNlX2luZGV4XS4KCQkJCQkgICAgdXBwZXIgPSBzLT5sb3dlcjsKCgkJCQlkZXZfcHJpdi0+c3VyZmFjZXNbcy0+c3VyZmFjZV9pbmRleF0ucmVmY291bnQtLTsKCQkJCWlmIChkZXZfcHJpdi0+c3VyZmFjZXNbcy0+c3VyZmFjZV9pbmRleF0uCgkJCQkgICAgcmVmY291bnQgPT0gMCkKCQkJCQlkZXZfcHJpdi0+c3VyZmFjZXNbcy0+c3VyZmFjZV9pbmRleF0uCgkJCQkJICAgIGZsYWdzID0gMDsKCQkJCXMtPmZpbHAgPSBOVUxMOwoJCQkJcmFkZW9uX2FwcGx5X3N1cmZhY2VfcmVncyhzLT5zdXJmYWNlX2luZGV4LAoJCQkJCQkJICBkZXZfcHJpdik7CgkJCQlyZXR1cm4gMDsKCQkJfQoJCX0KCX0KCXJldHVybiAxOwp9CgpzdGF0aWMgdm9pZCByYWRlb25fc3VyZmFjZXNfcmVsZWFzZShEUk1GSUxFIGZpbHAsCgkJCQkgICAgZHJtX3JhZGVvbl9wcml2YXRlX3QgKiBkZXZfcHJpdikKewoJaW50IGk7Cglmb3IgKGkgPSAwOyBpIDwgMiAqIFJBREVPTl9NQVhfU1VSRkFDRVM7IGkrKykgewoJCWlmIChkZXZfcHJpdi0+dmlydF9zdXJmYWNlc1tpXS5maWxwID09IGZpbHApCgkJCWZyZWVfc3VyZmFjZShmaWxwLCBkZXZfcHJpdiwKCQkJCSAgICAgZGV2X3ByaXYtPnZpcnRfc3VyZmFjZXNbaV0ubG93ZXIpOwoJfQp9CgovKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqIElPQ1RMIGZ1bmN0aW9ucwogKi8Kc3RhdGljIGludCByYWRlb25fc3VyZmFjZV9hbGxvYyhEUk1fSU9DVExfQVJHUykKewoJRFJNX0RFVklDRTsKCWRybV9yYWRlb25fcHJpdmF0ZV90ICpkZXZfcHJpdiA9IGRldi0+ZGV2X3ByaXZhdGU7Cglkcm1fcmFkZW9uX3N1cmZhY2VfYWxsb2NfdCBhbGxvYzsKCglEUk1fQ09QWV9GUk9NX1VTRVJfSU9DVEwoYWxsb2MsCgkJCQkgKGRybV9yYWRlb25fc3VyZmFjZV9hbGxvY190IF9fdXNlciAqKSBkYXRhLAoJCQkJIHNpemVvZihhbGxvYykpOwoKCWlmIChhbGxvY19zdXJmYWNlKCZhbGxvYywgZGV2X3ByaXYsIGZpbHApID09IC0xKQoJCXJldHVybiBEUk1fRVJSKEVJTlZBTCk7CgllbHNlCgkJcmV0dXJuIDA7Cn0KCnN0YXRpYyBpbnQgcmFkZW9uX3N1cmZhY2VfZnJlZShEUk1fSU9DVExfQVJHUykKewoJRFJNX0RFVklDRTsKCWRybV9yYWRlb25fcHJpdmF0ZV90ICpkZXZfcHJpdiA9IGRldi0+ZGV2X3ByaXZhdGU7Cglkcm1fcmFkZW9uX3N1cmZhY2VfZnJlZV90IG1lbWZyZWU7CgoJRFJNX0NPUFlfRlJPTV9VU0VSX0lPQ1RMKG1lbWZyZWUsIChkcm1fcmFkZW9uX3N1cmZhY2VfZnJlZV90IF9fdXNlciAqKSBkYXRhLAoJCQkJIHNpemVvZihtZW1mcmVlKSk7CgoJaWYgKGZyZWVfc3VyZmFjZShmaWxwLCBkZXZfcHJpdiwgbWVtZnJlZS5hZGRyZXNzKSkKCQlyZXR1cm4gRFJNX0VSUihFSU5WQUwpOwoJZWxzZQoJCXJldHVybiAwOwp9CgpzdGF0aWMgaW50IHJhZGVvbl9jcF9jbGVhcihEUk1fSU9DVExfQVJHUykKewoJRFJNX0RFVklDRTsKCWRybV9yYWRlb25fcHJpdmF0ZV90ICpkZXZfcHJpdiA9IGRldi0+ZGV2X3ByaXZhdGU7Cglkcm1fcmFkZW9uX3NhcmVhX3QgKnNhcmVhX3ByaXYgPSBkZXZfcHJpdi0+c2FyZWFfcHJpdjsKCWRybV9yYWRlb25fY2xlYXJfdCBjbGVhcjsKCWRybV9yYWRlb25fY2xlYXJfcmVjdF90IGRlcHRoX2JveGVzW1JBREVPTl9OUl9TQVJFQV9DTElQUkVDVFNdOwoJRFJNX0RFQlVHKCJcbiIpOwoKCUxPQ0tfVEVTVF9XSVRIX1JFVFVSTihkZXYsIGZpbHApOwoKCURSTV9DT1BZX0ZST01fVVNFUl9JT0NUTChjbGVhciwgKGRybV9yYWRlb25fY2xlYXJfdCBfX3VzZXIgKikgZGF0YSwKCQkJCSBzaXplb2YoY2xlYXIpKTsKCglSSU5HX1NQQUNFX1RFU1RfV0lUSF9SRVRVUk4oZGV2X3ByaXYpOwoKCWlmIChzYXJlYV9wcml2LT5uYm94ID4gUkFERU9OX05SX1NBUkVBX0NMSVBSRUNUUykKCQlzYXJlYV9wcml2LT5uYm94ID0gUkFERU9OX05SX1NBUkVBX0NMSVBSRUNUUzsKCglpZiAoRFJNX0NPUFlfRlJPTV9VU0VSKCZkZXB0aF9ib3hlcywgY2xlYXIuZGVwdGhfYm94ZXMsCgkJCSAgICAgICBzYXJlYV9wcml2LT5uYm94ICogc2l6ZW9mKGRlcHRoX2JveGVzWzBdKSkpCgkJcmV0dXJuIERSTV9FUlIoRUZBVUxUKTsKCglyYWRlb25fY3BfZGlzcGF0Y2hfY2xlYXIoZGV2LCAmY2xlYXIsIGRlcHRoX2JveGVzKTsKCglDT01NSVRfUklORygpOwoJcmV0dXJuIDA7Cn0KCi8qIE5vdCBzdXJlIHdoeSB0aGlzIGlzbid0IHNldCBhbGwgdGhlIHRpbWU6CiAqLwpzdGF0aWMgaW50IHJhZGVvbl9kb19pbml0X3BhZ2VmbGlwKGRybV9kZXZpY2VfdCAqIGRldikKewoJZHJtX3JhZGVvbl9wcml2YXRlX3QgKmRldl9wcml2ID0gZGV2LT5kZXZfcHJpdmF0ZTsKCVJJTkdfTE9DQUxTOwoKCURSTV9ERUJVRygiXG4iKTsKCglCRUdJTl9SSU5HKDYpOwoJUkFERU9OX1dBSVRfVU5USUxfM0RfSURMRSgpOwoJT1VUX1JJTkcoQ1BfUEFDS0VUMChSQURFT05fQ1JUQ19PRkZTRVRfQ05UTCwgMCkpOwoJT1VUX1JJTkcoUkFERU9OX1JFQUQoUkFERU9OX0NSVENfT0ZGU0VUX0NOVEwpIHwKCQkgUkFERU9OX0NSVENfT0ZGU0VUX0ZMSVBfQ05UTCk7CglPVVRfUklORyhDUF9QQUNLRVQwKFJBREVPTl9DUlRDMl9PRkZTRVRfQ05UTCwgMCkpOwoJT1VUX1JJTkcoUkFERU9OX1JFQUQoUkFERU9OX0NSVEMyX09GRlNFVF9DTlRMKSB8CgkJIFJBREVPTl9DUlRDX09GRlNFVF9GTElQX0NOVEwpOwoJQURWQU5DRV9SSU5HKCk7CgoJZGV2X3ByaXYtPnBhZ2VfZmxpcHBpbmcgPSAxOwoJZGV2X3ByaXYtPmN1cnJlbnRfcGFnZSA9IDA7CglkZXZfcHJpdi0+c2FyZWFfcHJpdi0+cGZDdXJyZW50UGFnZSA9IGRldl9wcml2LT5jdXJyZW50X3BhZ2U7CgoJcmV0dXJuIDA7Cn0KCi8qIENhbGxlZCB3aGVuZXZlciBhIGNsaWVudCBkaWVzLCBmcm9tIGRybV9yZWxlYXNlLgogKiBOT1RFOiAgTG9jayBpc24ndCBuZWNlc3NhcmlseSBoZWxkIHdoZW4gdGhpcyBpcyBjYWxsZWQhCiAqLwpzdGF0aWMgaW50IHJhZGVvbl9kb19jbGVhbnVwX3BhZ2VmbGlwKGRybV9kZXZpY2VfdCAqIGRldikKewoJZHJtX3JhZGVvbl9wcml2YXRlX3QgKmRldl9wcml2ID0gZGV2LT5kZXZfcHJpdmF0ZTsKCURSTV9ERUJVRygiXG4iKTsKCglpZiAoZGV2X3ByaXYtPmN1cnJlbnRfcGFnZSAhPSAwKQoJCXJhZGVvbl9jcF9kaXNwYXRjaF9mbGlwKGRldik7CgoJZGV2X3ByaXYtPnBhZ2VfZmxpcHBpbmcgPSAwOwoJcmV0dXJuIDA7Cn0KCi8qIFN3YXBwaW5nIGFuZCBmbGlwcGluZyBhcmUgZGlmZmVyZW50IG9wZXJhdGlvbnMsIG5lZWQgZGlmZmVyZW50IGlvY3Rscy4KICogVGhleSBjYW4gJiBzaG91bGQgYmUgaW50ZXJtaXhlZCB0byBzdXBwb3J0IG11bHRpcGxlIDNkIHdpbmRvd3MuCiAqLwpzdGF0aWMgaW50IHJhZGVvbl9jcF9mbGlwKERSTV9JT0NUTF9BUkdTKQp7CglEUk1fREVWSUNFOwoJZHJtX3JhZGVvbl9wcml2YXRlX3QgKmRldl9wcml2ID0gZGV2LT5kZXZfcHJpdmF0ZTsKCURSTV9ERUJVRygiXG4iKTsKCglMT0NLX1RFU1RfV0lUSF9SRVRVUk4oZGV2LCBmaWxwKTsKCglSSU5HX1NQQUNFX1RFU1RfV0lUSF9SRVRVUk4oZGV2X3ByaXYpOwoKCWlmICghZGV2X3ByaXYtPnBhZ2VfZmxpcHBpbmcpCgkJcmFkZW9uX2RvX2luaXRfcGFnZWZsaXAoZGV2KTsKCglyYWRlb25fY3BfZGlzcGF0Y2hfZmxpcChkZXYpOwoKCUNPTU1JVF9SSU5HKCk7CglyZXR1cm4gMDsKfQoKc3RhdGljIGludCByYWRlb25fY3Bfc3dhcChEUk1fSU9DVExfQVJHUykKewoJRFJNX0RFVklDRTsKCWRybV9yYWRlb25fcHJpdmF0ZV90ICpkZXZfcHJpdiA9IGRldi0+ZGV2X3ByaXZhdGU7Cglkcm1fcmFkZW9uX3NhcmVhX3QgKnNhcmVhX3ByaXYgPSBkZXZfcHJpdi0+c2FyZWFfcHJpdjsKCURSTV9ERUJVRygiXG4iKTsKCglMT0NLX1RFU1RfV0lUSF9SRVRVUk4oZGV2LCBmaWxwKTsKCglSSU5HX1NQQUNFX1RFU1RfV0lUSF9SRVRVUk4oZGV2X3ByaXYpOwoKCWlmIChzYXJlYV9wcml2LT5uYm94ID4gUkFERU9OX05SX1NBUkVBX0NMSVBSRUNUUykKCQlzYXJlYV9wcml2LT5uYm94ID0gUkFERU9OX05SX1NBUkVBX0NMSVBSRUNUUzsKCglyYWRlb25fY3BfZGlzcGF0Y2hfc3dhcChkZXYpOwoJZGV2X3ByaXYtPnNhcmVhX3ByaXYtPmN0eF9vd25lciA9IDA7CgoJQ09NTUlUX1JJTkcoKTsKCXJldHVybiAwOwp9CgpzdGF0aWMgaW50IHJhZGVvbl9jcF92ZXJ0ZXgoRFJNX0lPQ1RMX0FSR1MpCnsKCURSTV9ERVZJQ0U7Cglkcm1fcmFkZW9uX3ByaXZhdGVfdCAqZGV2X3ByaXYgPSBkZXYtPmRldl9wcml2YXRlOwoJZHJtX2ZpbGVfdCAqZmlscF9wcml2OwoJZHJtX3JhZGVvbl9zYXJlYV90ICpzYXJlYV9wcml2ID0gZGV2X3ByaXYtPnNhcmVhX3ByaXY7Cglkcm1fZGV2aWNlX2RtYV90ICpkbWEgPSBkZXYtPmRtYTsKCWRybV9idWZfdCAqYnVmOwoJZHJtX3JhZGVvbl92ZXJ0ZXhfdCB2ZXJ0ZXg7Cglkcm1fcmFkZW9uX3RjbF9wcmltX3QgcHJpbTsKCglMT0NLX1RFU1RfV0lUSF9SRVRVUk4oZGV2LCBmaWxwKTsKCglEUk1fR0VUX1BSSVZfV0lUSF9SRVRVUk4oZmlscF9wcml2LCBmaWxwKTsKCglEUk1fQ09QWV9GUk9NX1VTRVJfSU9DVEwodmVydGV4LCAoZHJtX3JhZGVvbl92ZXJ0ZXhfdCBfX3VzZXIgKikgZGF0YSwKCQkJCSBzaXplb2YodmVydGV4KSk7CgoJRFJNX0RFQlVHKCJwaWQ9JWQgaW5kZXg9JWQgY291bnQ9JWQgZGlzY2FyZD0lZFxuIiwKCQkgIERSTV9DVVJSRU5UUElELCB2ZXJ0ZXguaWR4LCB2ZXJ0ZXguY291bnQsIHZlcnRleC5kaXNjYXJkKTsKCglpZiAodmVydGV4LmlkeCA8IDAgfHwgdmVydGV4LmlkeCA+PSBkbWEtPmJ1Zl9jb3VudCkgewoJCURSTV9FUlJPUigiYnVmZmVyIGluZGV4ICVkIChvZiAlZCBtYXgpXG4iLAoJCQkgIHZlcnRleC5pZHgsIGRtYS0+YnVmX2NvdW50IC0gMSk7CgkJcmV0dXJuIERSTV9FUlIoRUlOVkFMKTsKCX0KCWlmICh2ZXJ0ZXgucHJpbSA8IDAgfHwgdmVydGV4LnByaW0gPiBSQURFT05fUFJJTV9UWVBFXzNWUlRfTElORV9MSVNUKSB7CgkJRFJNX0VSUk9SKCJidWZmZXIgcHJpbSAlZFxuIiwgdmVydGV4LnByaW0pOwoJCXJldHVybiBEUk1fRVJSKEVJTlZBTCk7Cgl9CgoJUklOR19TUEFDRV9URVNUX1dJVEhfUkVUVVJOKGRldl9wcml2KTsKCVZCX0FHRV9URVNUX1dJVEhfUkVUVVJOKGRldl9wcml2KTsKCglidWYgPSBkbWEtPmJ1Zmxpc3RbdmVydGV4LmlkeF07CgoJaWYgKGJ1Zi0+ZmlscCAhPSBmaWxwKSB7CgkJRFJNX0VSUk9SKCJwcm9jZXNzICVkIHVzaW5nIGJ1ZmZlciBvd25lZCBieSAlcFxuIiwKCQkJICBEUk1fQ1VSUkVOVFBJRCwgYnVmLT5maWxwKTsKCQlyZXR1cm4gRFJNX0VSUihFSU5WQUwpOwoJfQoJaWYgKGJ1Zi0+cGVuZGluZykgewoJCURSTV9FUlJPUigic2VuZGluZyBwZW5kaW5nIGJ1ZmZlciAlZFxuIiwgdmVydGV4LmlkeCk7CgkJcmV0dXJuIERSTV9FUlIoRUlOVkFMKTsKCX0KCgkvKiBCdWlsZCB1cCBhIHByaW1fdCByZWNvcmQ6CgkgKi8KCWlmICh2ZXJ0ZXguY291bnQpIHsKCQlidWYtPnVzZWQgPSB2ZXJ0ZXguY291bnQ7CS8qIG5vdCB1c2VkPyAqLwoKCQlpZiAoc2FyZWFfcHJpdi0+ZGlydHkgJiB+UkFERU9OX1VQTE9BRF9DTElQUkVDVFMpIHsKCQkJaWYgKHJhZGVvbl9lbWl0X3N0YXRlKGRldl9wcml2LCBmaWxwX3ByaXYsCgkJCQkJICAgICAgJnNhcmVhX3ByaXYtPmNvbnRleHRfc3RhdGUsCgkJCQkJICAgICAgc2FyZWFfcHJpdi0+dGV4X3N0YXRlLAoJCQkJCSAgICAgIHNhcmVhX3ByaXYtPmRpcnR5KSkgewoJCQkJRFJNX0VSUk9SKCJyYWRlb25fZW1pdF9zdGF0ZSBmYWlsZWRcbiIpOwoJCQkJcmV0dXJuIERSTV9FUlIoRUlOVkFMKTsKCQkJfQoKCQkJc2FyZWFfcHJpdi0+ZGlydHkgJj0gfihSQURFT05fVVBMT0FEX1RFWDBJTUFHRVMgfAoJCQkJCSAgICAgICBSQURFT05fVVBMT0FEX1RFWDFJTUFHRVMgfAoJCQkJCSAgICAgICBSQURFT05fVVBMT0FEX1RFWDJJTUFHRVMgfAoJCQkJCSAgICAgICBSQURFT05fUkVRVUlSRV9RVUlFU0NFTkNFKTsKCQl9CgoJCXByaW0uc3RhcnQgPSAwOwoJCXByaW0uZmluaXNoID0gdmVydGV4LmNvdW50OwkvKiB1bnVzZWQgKi8KCQlwcmltLnByaW0gPSB2ZXJ0ZXgucHJpbTsKCQlwcmltLm51bXZlcnRzID0gdmVydGV4LmNvdW50OwoJCXByaW0udmNfZm9ybWF0ID0gZGV2X3ByaXYtPnNhcmVhX3ByaXYtPnZjX2Zvcm1hdDsKCgkJcmFkZW9uX2NwX2Rpc3BhdGNoX3ZlcnRleChkZXYsIGJ1ZiwgJnByaW0pOwoJfQoKCWlmICh2ZXJ0ZXguZGlzY2FyZCkgewoJCXJhZGVvbl9jcF9kaXNjYXJkX2J1ZmZlcihkZXYsIGJ1Zik7Cgl9CgoJQ09NTUlUX1JJTkcoKTsKCXJldHVybiAwOwp9CgpzdGF0aWMgaW50IHJhZGVvbl9jcF9pbmRpY2VzKERSTV9JT0NUTF9BUkdTKQp7CglEUk1fREVWSUNFOwoJZHJtX3JhZGVvbl9wcml2YXRlX3QgKmRldl9wcml2ID0gZGV2LT5kZXZfcHJpdmF0ZTsKCWRybV9maWxlX3QgKmZpbHBfcHJpdjsKCWRybV9yYWRlb25fc2FyZWFfdCAqc2FyZWFfcHJpdiA9IGRldl9wcml2LT5zYXJlYV9wcml2OwoJZHJtX2RldmljZV9kbWFfdCAqZG1hID0gZGV2LT5kbWE7Cglkcm1fYnVmX3QgKmJ1ZjsKCWRybV9yYWRlb25faW5kaWNlc190IGVsdHM7Cglkcm1fcmFkZW9uX3RjbF9wcmltX3QgcHJpbTsKCWludCBjb3VudDsKCglMT0NLX1RFU1RfV0lUSF9SRVRVUk4oZGV2LCBmaWxwKTsKCglEUk1fR0VUX1BSSVZfV0lUSF9SRVRVUk4oZmlscF9wcml2LCBmaWxwKTsKCglEUk1fQ09QWV9GUk9NX1VTRVJfSU9DVEwoZWx0cywgKGRybV9yYWRlb25faW5kaWNlc190IF9fdXNlciAqKSBkYXRhLAoJCQkJIHNpemVvZihlbHRzKSk7CgoJRFJNX0RFQlVHKCJwaWQ9JWQgaW5kZXg9JWQgc3RhcnQ9JWQgZW5kPSVkIGRpc2NhcmQ9JWRcbiIsCgkJICBEUk1fQ1VSUkVOVFBJRCwgZWx0cy5pZHgsIGVsdHMuc3RhcnQsIGVsdHMuZW5kLCBlbHRzLmRpc2NhcmQpOwoKCWlmIChlbHRzLmlkeCA8IDAgfHwgZWx0cy5pZHggPj0gZG1hLT5idWZfY291bnQpIHsKCQlEUk1fRVJST1IoImJ1ZmZlciBpbmRleCAlZCAob2YgJWQgbWF4KVxuIiwKCQkJICBlbHRzLmlkeCwgZG1hLT5idWZfY291bnQgLSAxKTsKCQlyZXR1cm4gRFJNX0VSUihFSU5WQUwpOwoJfQoJaWYgKGVsdHMucHJpbSA8IDAgfHwgZWx0cy5wcmltID4gUkFERU9OX1BSSU1fVFlQRV8zVlJUX0xJTkVfTElTVCkgewoJCURSTV9FUlJPUigiYnVmZmVyIHByaW0gJWRcbiIsIGVsdHMucHJpbSk7CgkJcmV0dXJuIERSTV9FUlIoRUlOVkFMKTsKCX0KCglSSU5HX1NQQUNFX1RFU1RfV0lUSF9SRVRVUk4oZGV2X3ByaXYpOwoJVkJfQUdFX1RFU1RfV0lUSF9SRVRVUk4oZGV2X3ByaXYpOwoKCWJ1ZiA9IGRtYS0+YnVmbGlzdFtlbHRzLmlkeF07CgoJaWYgKGJ1Zi0+ZmlscCAhPSBmaWxwKSB7CgkJRFJNX0VSUk9SKCJwcm9jZXNzICVkIHVzaW5nIGJ1ZmZlciBvd25lZCBieSAlcFxuIiwKCQkJICBEUk1fQ1VSUkVOVFBJRCwgYnVmLT5maWxwKTsKCQlyZXR1cm4gRFJNX0VSUihFSU5WQUwpOwoJfQoJaWYgKGJ1Zi0+cGVuZGluZykgewoJCURSTV9FUlJPUigic2VuZGluZyBwZW5kaW5nIGJ1ZmZlciAlZFxuIiwgZWx0cy5pZHgpOwoJCXJldHVybiBEUk1fRVJSKEVJTlZBTCk7Cgl9CgoJY291bnQgPSAoZWx0cy5lbmQgLSBlbHRzLnN0YXJ0KSAvIHNpemVvZih1MTYpOwoJZWx0cy5zdGFydCAtPSBSQURFT05fSU5ERVhfUFJJTV9PRkZTRVQ7CgoJaWYgKGVsdHMuc3RhcnQgJiAweDcpIHsKCQlEUk1fRVJST1IoIm1pc2FsaWduZWQgYnVmZmVyIDB4JXhcbiIsIGVsdHMuc3RhcnQpOwoJCXJldHVybiBEUk1fRVJSKEVJTlZBTCk7Cgl9CglpZiAoZWx0cy5zdGFydCA8IGJ1Zi0+dXNlZCkgewoJCURSTV9FUlJPUigibm8gaGVhZGVyIDB4JXggLSAweCV4XG4iLCBlbHRzLnN0YXJ0LCBidWYtPnVzZWQpOwoJCXJldHVybiBEUk1fRVJSKEVJTlZBTCk7Cgl9CgoJYnVmLT51c2VkID0gZWx0cy5lbmQ7CgoJaWYgKHNhcmVhX3ByaXYtPmRpcnR5ICYgflJBREVPTl9VUExPQURfQ0xJUFJFQ1RTKSB7CgkJaWYgKHJhZGVvbl9lbWl0X3N0YXRlKGRldl9wcml2LCBmaWxwX3ByaXYsCgkJCQkgICAgICAmc2FyZWFfcHJpdi0+Y29udGV4dF9zdGF0ZSwKCQkJCSAgICAgIHNhcmVhX3ByaXYtPnRleF9zdGF0ZSwKCQkJCSAgICAgIHNhcmVhX3ByaXYtPmRpcnR5KSkgewoJCQlEUk1fRVJST1IoInJhZGVvbl9lbWl0X3N0YXRlIGZhaWxlZFxuIik7CgkJCXJldHVybiBEUk1fRVJSKEVJTlZBTCk7CgkJfQoKCQlzYXJlYV9wcml2LT5kaXJ0eSAmPSB+KFJBREVPTl9VUExPQURfVEVYMElNQUdFUyB8CgkJCQkgICAgICAgUkFERU9OX1VQTE9BRF9URVgxSU1BR0VTIHwKCQkJCSAgICAgICBSQURFT05fVVBMT0FEX1RFWDJJTUFHRVMgfAoJCQkJICAgICAgIFJBREVPTl9SRVFVSVJFX1FVSUVTQ0VOQ0UpOwoJfQoKCS8qIEJ1aWxkIHVwIGEgcHJpbV90IHJlY29yZDoKCSAqLwoJcHJpbS5zdGFydCA9IGVsdHMuc3RhcnQ7CglwcmltLmZpbmlzaCA9IGVsdHMuZW5kOwoJcHJpbS5wcmltID0gZWx0cy5wcmltOwoJcHJpbS5vZmZzZXQgPSAwOwkvKiBvZmZzZXQgZnJvbSBzdGFydCBvZiBkbWEgYnVmZmVycyAqLwoJcHJpbS5udW12ZXJ0cyA9IFJBREVPTl9NQVhfVkJfVkVSVFM7CS8qIGR1aCAqLwoJcHJpbS52Y19mb3JtYXQgPSBkZXZfcHJpdi0+c2FyZWFfcHJpdi0+dmNfZm9ybWF0OwoKCXJhZGVvbl9jcF9kaXNwYXRjaF9pbmRpY2VzKGRldiwgYnVmLCAmcHJpbSk7CglpZiAoZWx0cy5kaXNjYXJkKSB7CgkJcmFkZW9uX2NwX2Rpc2NhcmRfYnVmZmVyKGRldiwgYnVmKTsKCX0KCglDT01NSVRfUklORygpOwoJcmV0dXJuIDA7Cn0KCnN0YXRpYyBpbnQgcmFkZW9uX2NwX3RleHR1cmUoRFJNX0lPQ1RMX0FSR1MpCnsKCURSTV9ERVZJQ0U7Cglkcm1fcmFkZW9uX3ByaXZhdGVfdCAqZGV2X3ByaXYgPSBkZXYtPmRldl9wcml2YXRlOwoJZHJtX3JhZGVvbl90ZXh0dXJlX3QgdGV4OwoJZHJtX3JhZGVvbl90ZXhfaW1hZ2VfdCBpbWFnZTsKCWludCByZXQ7CgoJTE9DS19URVNUX1dJVEhfUkVUVVJOKGRldiwgZmlscCk7CgoJRFJNX0NPUFlfRlJPTV9VU0VSX0lPQ1RMKHRleCwgKGRybV9yYWRlb25fdGV4dHVyZV90IF9fdXNlciAqKSBkYXRhLAoJCQkJIHNpemVvZih0ZXgpKTsKCglpZiAodGV4LmltYWdlID09IE5VTEwpIHsKCQlEUk1fRVJST1IoIm51bGwgdGV4dHVyZSBpbWFnZSFcbiIpOwoJCXJldHVybiBEUk1fRVJSKEVJTlZBTCk7Cgl9CgoJaWYgKERSTV9DT1BZX0ZST01fVVNFUigmaW1hZ2UsCgkJCSAgICAgICAoZHJtX3JhZGVvbl90ZXhfaW1hZ2VfdCBfX3VzZXIgKikgdGV4LmltYWdlLAoJCQkgICAgICAgc2l6ZW9mKGltYWdlKSkpCgkJcmV0dXJuIERSTV9FUlIoRUZBVUxUKTsKCglSSU5HX1NQQUNFX1RFU1RfV0lUSF9SRVRVUk4oZGV2X3ByaXYpOwoJVkJfQUdFX1RFU1RfV0lUSF9SRVRVUk4oZGV2X3ByaXYpOwoKCXJldCA9IHJhZGVvbl9jcF9kaXNwYXRjaF90ZXh0dXJlKGZpbHAsIGRldiwgJnRleCwgJmltYWdlKTsKCglDT01NSVRfUklORygpOwoJcmV0dXJuIHJldDsKfQoKc3RhdGljIGludCByYWRlb25fY3Bfc3RpcHBsZShEUk1fSU9DVExfQVJHUykKewoJRFJNX0RFVklDRTsKCWRybV9yYWRlb25fcHJpdmF0ZV90ICpkZXZfcHJpdiA9IGRldi0+ZGV2X3ByaXZhdGU7Cglkcm1fcmFkZW9uX3N0aXBwbGVfdCBzdGlwcGxlOwoJdTMyIG1hc2tbMzJdOwoKCUxPQ0tfVEVTVF9XSVRIX1JFVFVSTihkZXYsIGZpbHApOwoKCURSTV9DT1BZX0ZST01fVVNFUl9JT0NUTChzdGlwcGxlLCAoZHJtX3JhZGVvbl9zdGlwcGxlX3QgX191c2VyICopIGRhdGEsCgkJCQkgc2l6ZW9mKHN0aXBwbGUpKTsKCglpZiAoRFJNX0NPUFlfRlJPTV9VU0VSKCZtYXNrLCBzdGlwcGxlLm1hc2ssIDMyICogc2l6ZW9mKHUzMikpKQoJCXJldHVybiBEUk1fRVJSKEVGQVVMVCk7CgoJUklOR19TUEFDRV9URVNUX1dJVEhfUkVUVVJOKGRldl9wcml2KTsKCglyYWRlb25fY3BfZGlzcGF0Y2hfc3RpcHBsZShkZXYsIG1hc2spOwoKCUNPTU1JVF9SSU5HKCk7CglyZXR1cm4gMDsKfQoKc3RhdGljIGludCByYWRlb25fY3BfaW5kaXJlY3QoRFJNX0lPQ1RMX0FSR1MpCnsKCURSTV9ERVZJQ0U7Cglkcm1fcmFkZW9uX3ByaXZhdGVfdCAqZGV2X3ByaXYgPSBkZXYtPmRldl9wcml2YXRlOwoJZHJtX2RldmljZV9kbWFfdCAqZG1hID0gZGV2LT5kbWE7Cglkcm1fYnVmX3QgKmJ1ZjsKCWRybV9yYWRlb25faW5kaXJlY3RfdCBpbmRpcmVjdDsKCVJJTkdfTE9DQUxTOwoKCUxPQ0tfVEVTVF9XSVRIX1JFVFVSTihkZXYsIGZpbHApOwoKCURSTV9DT1BZX0ZST01fVVNFUl9JT0NUTChpbmRpcmVjdCwKCQkJCSAoZHJtX3JhZGVvbl9pbmRpcmVjdF90IF9fdXNlciAqKSBkYXRhLAoJCQkJIHNpemVvZihpbmRpcmVjdCkpOwoKCURSTV9ERUJVRygiaW5kaXJlY3Q6IGlkeD0lZCBzPSVkIGU9JWQgZD0lZFxuIiwKCQkgIGluZGlyZWN0LmlkeCwgaW5kaXJlY3Quc3RhcnQsIGluZGlyZWN0LmVuZCwgaW5kaXJlY3QuZGlzY2FyZCk7CgoJaWYgKGluZGlyZWN0LmlkeCA8IDAgfHwgaW5kaXJlY3QuaWR4ID49IGRtYS0+YnVmX2NvdW50KSB7CgkJRFJNX0VSUk9SKCJidWZmZXIgaW5kZXggJWQgKG9mICVkIG1heClcbiIsCgkJCSAgaW5kaXJlY3QuaWR4LCBkbWEtPmJ1Zl9jb3VudCAtIDEpOwoJCXJldHVybiBEUk1fRVJSKEVJTlZBTCk7Cgl9CgoJYnVmID0gZG1hLT5idWZsaXN0W2luZGlyZWN0LmlkeF07CgoJaWYgKGJ1Zi0+ZmlscCAhPSBmaWxwKSB7CgkJRFJNX0VSUk9SKCJwcm9jZXNzICVkIHVzaW5nIGJ1ZmZlciBvd25lZCBieSAlcFxuIiwKCQkJICBEUk1fQ1VSUkVOVFBJRCwgYnVmLT5maWxwKTsKCQlyZXR1cm4gRFJNX0VSUihFSU5WQUwpOwoJfQoJaWYgKGJ1Zi0+cGVuZGluZykgewoJCURSTV9FUlJPUigic2VuZGluZyBwZW5kaW5nIGJ1ZmZlciAlZFxuIiwgaW5kaXJlY3QuaWR4KTsKCQlyZXR1cm4gRFJNX0VSUihFSU5WQUwpOwoJfQoKCWlmIChpbmRpcmVjdC5zdGFydCA8IGJ1Zi0+dXNlZCkgewoJCURSTV9FUlJPUigicmV1c2luZyBpbmRpcmVjdDogc3RhcnQ9MHgleCBhY3R1YWw9MHgleFxuIiwKCQkJICBpbmRpcmVjdC5zdGFydCwgYnVmLT51c2VkKTsKCQlyZXR1cm4gRFJNX0VSUihFSU5WQUwpOwoJfQoKCVJJTkdfU1BBQ0VfVEVTVF9XSVRIX1JFVFVSTihkZXZfcHJpdik7CglWQl9BR0VfVEVTVF9XSVRIX1JFVFVSTihkZXZfcHJpdik7CgoJYnVmLT51c2VkID0gaW5kaXJlY3QuZW5kOwoKCS8qIFdhaXQgZm9yIHRoZSAzRCBzdHJlYW0gdG8gaWRsZSBiZWZvcmUgdGhlIGluZGlyZWN0IGJ1ZmZlcgoJICogY29udGFpbmluZyAyRCBhY2NlbGVyYXRpb24gY29tbWFuZHMgaXMgcHJvY2Vzc2VkLgoJICovCglCRUdJTl9SSU5HKDIpOwoKCVJBREVPTl9XQUlUX1VOVElMXzNEX0lETEUoKTsKCglBRFZBTkNFX1JJTkcoKTsKCgkvKiBEaXNwYXRjaCB0aGUgaW5kaXJlY3QgYnVmZmVyIGZ1bGwgb2YgY29tbWFuZHMgZnJvbSB0aGUKCSAqIFggc2VydmVyLiAgVGhpcyBpcyBpbnNlY3VyZSBhbmQgaXMgdGh1cyBvbmx5IGF2YWlsYWJsZSB0bwoJICogcHJpdmlsZWdlZCBjbGllbnRzLgoJICovCglyYWRlb25fY3BfZGlzcGF0Y2hfaW5kaXJlY3QoZGV2LCBidWYsIGluZGlyZWN0LnN0YXJ0LCBpbmRpcmVjdC5lbmQpOwoJaWYgKGluZGlyZWN0LmRpc2NhcmQpIHsKCQlyYWRlb25fY3BfZGlzY2FyZF9idWZmZXIoZGV2LCBidWYpOwoJfQoKCUNPTU1JVF9SSU5HKCk7CglyZXR1cm4gMDsKfQoKc3RhdGljIGludCByYWRlb25fY3BfdmVydGV4MihEUk1fSU9DVExfQVJHUykKewoJRFJNX0RFVklDRTsKCWRybV9yYWRlb25fcHJpdmF0ZV90ICpkZXZfcHJpdiA9IGRldi0+ZGV2X3ByaXZhdGU7Cglkcm1fZmlsZV90ICpmaWxwX3ByaXY7Cglkcm1fcmFkZW9uX3NhcmVhX3QgKnNhcmVhX3ByaXYgPSBkZXZfcHJpdi0+c2FyZWFfcHJpdjsKCWRybV9kZXZpY2VfZG1hX3QgKmRtYSA9IGRldi0+ZG1hOwoJZHJtX2J1Zl90ICpidWY7Cglkcm1fcmFkZW9uX3ZlcnRleDJfdCB2ZXJ0ZXg7CglpbnQgaTsKCXVuc2lnbmVkIGNoYXIgbGFzdHN0YXRlOwoKCUxPQ0tfVEVTVF9XSVRIX1JFVFVSTihkZXYsIGZpbHApOwoKCURSTV9HRVRfUFJJVl9XSVRIX1JFVFVSTihmaWxwX3ByaXYsIGZpbHApOwoKCURSTV9DT1BZX0ZST01fVVNFUl9JT0NUTCh2ZXJ0ZXgsIChkcm1fcmFkZW9uX3ZlcnRleDJfdCBfX3VzZXIgKikgZGF0YSwKCQkJCSBzaXplb2YodmVydGV4KSk7CgoJRFJNX0RFQlVHKCJwaWQ9JWQgaW5kZXg9JWQgZGlzY2FyZD0lZFxuIiwKCQkgIERSTV9DVVJSRU5UUElELCB2ZXJ0ZXguaWR4LCB2ZXJ0ZXguZGlzY2FyZCk7CgoJaWYgKHZlcnRleC5pZHggPCAwIHx8IHZlcnRleC5pZHggPj0gZG1hLT5idWZfY291bnQpIHsKCQlEUk1fRVJST1IoImJ1ZmZlciBpbmRleCAlZCAob2YgJWQgbWF4KVxuIiwKCQkJICB2ZXJ0ZXguaWR4LCBkbWEtPmJ1Zl9jb3VudCAtIDEpOwoJCXJldHVybiBEUk1fRVJSKEVJTlZBTCk7Cgl9CgoJUklOR19TUEFDRV9URVNUX1dJVEhfUkVUVVJOKGRldl9wcml2KTsKCVZCX0FHRV9URVNUX1dJVEhfUkVUVVJOKGRldl9wcml2KTsKCglidWYgPSBkbWEtPmJ1Zmxpc3RbdmVydGV4LmlkeF07CgoJaWYgKGJ1Zi0+ZmlscCAhPSBmaWxwKSB7CgkJRFJNX0VSUk9SKCJwcm9jZXNzICVkIHVzaW5nIGJ1ZmZlciBvd25lZCBieSAlcFxuIiwKCQkJICBEUk1fQ1VSUkVOVFBJRCwgYnVmLT5maWxwKTsKCQlyZXR1cm4gRFJNX0VSUihFSU5WQUwpOwoJfQoKCWlmIChidWYtPnBlbmRpbmcpIHsKCQlEUk1fRVJST1IoInNlbmRpbmcgcGVuZGluZyBidWZmZXIgJWRcbiIsIHZlcnRleC5pZHgpOwoJCXJldHVybiBEUk1fRVJSKEVJTlZBTCk7Cgl9CgoJaWYgKHNhcmVhX3ByaXYtPm5ib3ggPiBSQURFT05fTlJfU0FSRUFfQ0xJUFJFQ1RTKQoJCXJldHVybiBEUk1fRVJSKEVJTlZBTCk7CgoJZm9yIChsYXN0c3RhdGUgPSAweGZmLCBpID0gMDsgaSA8IHZlcnRleC5ucl9wcmltczsgaSsrKSB7CgkJZHJtX3JhZGVvbl9wcmltX3QgcHJpbTsKCQlkcm1fcmFkZW9uX3RjbF9wcmltX3QgdGNscHJpbTsKCgkJaWYgKERSTV9DT1BZX0ZST01fVVNFUigmcHJpbSwgJnZlcnRleC5wcmltW2ldLCBzaXplb2YocHJpbSkpKQoJCQlyZXR1cm4gRFJNX0VSUihFRkFVTFQpOwoKCQlpZiAocHJpbS5zdGF0ZWlkeCAhPSBsYXN0c3RhdGUpIHsKCQkJZHJtX3JhZGVvbl9zdGF0ZV90IHN0YXRlOwoKCQkJaWYgKERSTV9DT1BZX0ZST01fVVNFUigmc3RhdGUsCgkJCQkJICAgICAgICZ2ZXJ0ZXguc3RhdGVbcHJpbS5zdGF0ZWlkeF0sCgkJCQkJICAgICAgIHNpemVvZihzdGF0ZSkpKQoJCQkJcmV0dXJuIERSTV9FUlIoRUZBVUxUKTsKCgkJCWlmIChyYWRlb25fZW1pdF9zdGF0ZTIoZGV2X3ByaXYsIGZpbHBfcHJpdiwgJnN0YXRlKSkgewoJCQkJRFJNX0VSUk9SKCJyYWRlb25fZW1pdF9zdGF0ZTIgZmFpbGVkXG4iKTsKCQkJCXJldHVybiBEUk1fRVJSKEVJTlZBTCk7CgkJCX0KCgkJCWxhc3RzdGF0ZSA9IHByaW0uc3RhdGVpZHg7CgkJfQoKCQl0Y2xwcmltLnN0YXJ0ID0gcHJpbS5zdGFydDsKCQl0Y2xwcmltLmZpbmlzaCA9IHByaW0uZmluaXNoOwoJCXRjbHByaW0ucHJpbSA9IHByaW0ucHJpbTsKCQl0Y2xwcmltLnZjX2Zvcm1hdCA9IHByaW0udmNfZm9ybWF0OwoKCQlpZiAocHJpbS5wcmltICYgUkFERU9OX1BSSU1fV0FMS19JTkQpIHsKCQkJdGNscHJpbS5vZmZzZXQgPSBwcmltLm51bXZlcnRzICogNjQ7CgkJCXRjbHByaW0ubnVtdmVydHMgPSBSQURFT05fTUFYX1ZCX1ZFUlRTOwkvKiBkdWggKi8KCgkJCXJhZGVvbl9jcF9kaXNwYXRjaF9pbmRpY2VzKGRldiwgYnVmLCAmdGNscHJpbSk7CgkJfSBlbHNlIHsKCQkJdGNscHJpbS5udW12ZXJ0cyA9IHByaW0ubnVtdmVydHM7CgkJCXRjbHByaW0ub2Zmc2V0ID0gMDsJLyogbm90IHVzZWQgKi8KCgkJCXJhZGVvbl9jcF9kaXNwYXRjaF92ZXJ0ZXgoZGV2LCBidWYsICZ0Y2xwcmltKTsKCQl9CgoJCWlmIChzYXJlYV9wcml2LT5uYm94ID09IDEpCgkJCXNhcmVhX3ByaXYtPm5ib3ggPSAwOwoJfQoKCWlmICh2ZXJ0ZXguZGlzY2FyZCkgewoJCXJhZGVvbl9jcF9kaXNjYXJkX2J1ZmZlcihkZXYsIGJ1Zik7Cgl9CgoJQ09NTUlUX1JJTkcoKTsKCXJldHVybiAwOwp9CgpzdGF0aWMgaW50IHJhZGVvbl9lbWl0X3BhY2tldHMoZHJtX3JhZGVvbl9wcml2YXRlX3QgKiBkZXZfcHJpdiwKCQkJICAgICAgIGRybV9maWxlX3QgKiBmaWxwX3ByaXYsCgkJCSAgICAgICBkcm1fcmFkZW9uX2NtZF9oZWFkZXJfdCBoZWFkZXIsCgkJCSAgICAgICBkcm1fcmFkZW9uX2tjbWRfYnVmZmVyX3QgKmNtZGJ1ZikKewoJaW50IGlkID0gKGludCloZWFkZXIucGFja2V0LnBhY2tldF9pZDsKCWludCBzeiwgcmVnOwoJaW50ICpkYXRhID0gKGludCAqKWNtZGJ1Zi0+YnVmOwoJUklOR19MT0NBTFM7CgoJaWYgKGlkID49IFJBREVPTl9NQVhfU1RBVEVfUEFDS0VUUykKCQlyZXR1cm4gRFJNX0VSUihFSU5WQUwpOwoKCXN6ID0gcGFja2V0W2lkXS5sZW47CglyZWcgPSBwYWNrZXRbaWRdLnN0YXJ0OwoKCWlmIChzeiAqIHNpemVvZihpbnQpID4gY21kYnVmLT5idWZzeikgewoJCURSTV9FUlJPUigiUGFja2V0IHNpemUgcHJvdmlkZWQgbGFyZ2VyIHRoYW4gZGF0YSBwcm92aWRlZFxuIik7CgkJcmV0dXJuIERSTV9FUlIoRUlOVkFMKTsKCX0KCglpZiAocmFkZW9uX2NoZWNrX2FuZF9maXh1cF9wYWNrZXRzKGRldl9wcml2LCBmaWxwX3ByaXYsIGlkLCBkYXRhKSkgewoJCURSTV9FUlJPUigiUGFja2V0IHZlcmlmaWNhdGlvbiBmYWlsZWRcbiIpOwoJCXJldHVybiBEUk1fRVJSKEVJTlZBTCk7Cgl9CgoJQkVHSU5fUklORyhzeiArIDEpOwoJT1VUX1JJTkcoQ1BfUEFDS0VUMChyZWcsIChzeiAtIDEpKSk7CglPVVRfUklOR19UQUJMRShkYXRhLCBzeik7CglBRFZBTkNFX1JJTkcoKTsKCgljbWRidWYtPmJ1ZiArPSBzeiAqIHNpemVvZihpbnQpOwoJY21kYnVmLT5idWZzeiAtPSBzeiAqIHNpemVvZihpbnQpOwoJcmV0dXJuIDA7Cn0KCnN0YXRpYyBfX2lubGluZV9fIGludCByYWRlb25fZW1pdF9zY2FsYXJzKGRybV9yYWRlb25fcHJpdmF0ZV90ICpkZXZfcHJpdiwKCQkJCQkgIGRybV9yYWRlb25fY21kX2hlYWRlcl90IGhlYWRlciwKCQkJCQkgIGRybV9yYWRlb25fa2NtZF9idWZmZXJfdCAqY21kYnVmKQp7CglpbnQgc3ogPSBoZWFkZXIuc2NhbGFycy5jb3VudDsKCWludCBzdGFydCA9IGhlYWRlci5zY2FsYXJzLm9mZnNldDsKCWludCBzdHJpZGUgPSBoZWFkZXIuc2NhbGFycy5zdHJpZGU7CglSSU5HX0xPQ0FMUzsKCglCRUdJTl9SSU5HKDMgKyBzeik7CglPVVRfUklORyhDUF9QQUNLRVQwKFJBREVPTl9TRV9UQ0xfU0NBTEFSX0lORFhfUkVHLCAwKSk7CglPVVRfUklORyhzdGFydCB8IChzdHJpZGUgPDwgUkFERU9OX1NDQUxfSU5EWF9EV09SRF9TVFJJREVfU0hJRlQpKTsKCU9VVF9SSU5HKENQX1BBQ0tFVDBfVEFCTEUoUkFERU9OX1NFX1RDTF9TQ0FMQVJfREFUQV9SRUcsIHN6IC0gMSkpOwoJT1VUX1JJTkdfVEFCTEUoY21kYnVmLT5idWYsIHN6KTsKCUFEVkFOQ0VfUklORygpOwoJY21kYnVmLT5idWYgKz0gc3ogKiBzaXplb2YoaW50KTsKCWNtZGJ1Zi0+YnVmc3ogLT0gc3ogKiBzaXplb2YoaW50KTsKCXJldHVybiAwOwp9CgovKiBHb2QgdGhpcyBpcyB1Z2x5CiAqLwpzdGF0aWMgX19pbmxpbmVfXyBpbnQgcmFkZW9uX2VtaXRfc2NhbGFyczIoZHJtX3JhZGVvbl9wcml2YXRlX3QgKmRldl9wcml2LAoJCQkJCSAgIGRybV9yYWRlb25fY21kX2hlYWRlcl90IGhlYWRlciwKCQkJCQkgICBkcm1fcmFkZW9uX2tjbWRfYnVmZmVyX3QgKmNtZGJ1ZikKewoJaW50IHN6ID0gaGVhZGVyLnNjYWxhcnMuY291bnQ7CglpbnQgc3RhcnQgPSAoKHVuc2lnbmVkIGludCloZWFkZXIuc2NhbGFycy5vZmZzZXQpICsgMHgxMDA7CglpbnQgc3RyaWRlID0gaGVhZGVyLnNjYWxhcnMuc3RyaWRlOwoJUklOR19MT0NBTFM7CgoJQkVHSU5fUklORygzICsgc3opOwoJT1VUX1JJTkcoQ1BfUEFDS0VUMChSQURFT05fU0VfVENMX1NDQUxBUl9JTkRYX1JFRywgMCkpOwoJT1VUX1JJTkcoc3RhcnQgfCAoc3RyaWRlIDw8IFJBREVPTl9TQ0FMX0lORFhfRFdPUkRfU1RSSURFX1NISUZUKSk7CglPVVRfUklORyhDUF9QQUNLRVQwX1RBQkxFKFJBREVPTl9TRV9UQ0xfU0NBTEFSX0RBVEFfUkVHLCBzeiAtIDEpKTsKCU9VVF9SSU5HX1RBQkxFKGNtZGJ1Zi0+YnVmLCBzeik7CglBRFZBTkNFX1JJTkcoKTsKCWNtZGJ1Zi0+YnVmICs9IHN6ICogc2l6ZW9mKGludCk7CgljbWRidWYtPmJ1ZnN6IC09IHN6ICogc2l6ZW9mKGludCk7CglyZXR1cm4gMDsKfQoKc3RhdGljIF9faW5saW5lX18gaW50IHJhZGVvbl9lbWl0X3ZlY3RvcnMoZHJtX3JhZGVvbl9wcml2YXRlX3QgKmRldl9wcml2LAoJCQkJCSAgZHJtX3JhZGVvbl9jbWRfaGVhZGVyX3QgaGVhZGVyLAoJCQkJCSAgZHJtX3JhZGVvbl9rY21kX2J1ZmZlcl90ICpjbWRidWYpCnsKCWludCBzeiA9IGhlYWRlci52ZWN0b3JzLmNvdW50OwoJaW50IHN0YXJ0ID0gaGVhZGVyLnZlY3RvcnMub2Zmc2V0OwoJaW50IHN0cmlkZSA9IGhlYWRlci52ZWN0b3JzLnN0cmlkZTsKCVJJTkdfTE9DQUxTOwoKCUJFR0lOX1JJTkcoNSArIHN6KTsKCU9VVF9SSU5HX1JFRyhSQURFT05fU0VfVENMX1NUQVRFX0ZMVVNILCAwKTsKCU9VVF9SSU5HKENQX1BBQ0tFVDAoUkFERU9OX1NFX1RDTF9WRUNUT1JfSU5EWF9SRUcsIDApKTsKCU9VVF9SSU5HKHN0YXJ0IHwgKHN0cmlkZSA8PCBSQURFT05fVkVDX0lORFhfT0NUV09SRF9TVFJJREVfU0hJRlQpKTsKCU9VVF9SSU5HKENQX1BBQ0tFVDBfVEFCTEUoUkFERU9OX1NFX1RDTF9WRUNUT1JfREFUQV9SRUcsIChzeiAtIDEpKSk7CglPVVRfUklOR19UQUJMRShjbWRidWYtPmJ1Ziwgc3opOwoJQURWQU5DRV9SSU5HKCk7CgoJY21kYnVmLT5idWYgKz0gc3ogKiBzaXplb2YoaW50KTsKCWNtZGJ1Zi0+YnVmc3ogLT0gc3ogKiBzaXplb2YoaW50KTsKCXJldHVybiAwOwp9CgpzdGF0aWMgX19pbmxpbmVfXyBpbnQgcmFkZW9uX2VtaXRfdmVjbGluZWFyKGRybV9yYWRlb25fcHJpdmF0ZV90ICpkZXZfcHJpdiwKCQkJCQkgIGRybV9yYWRlb25fY21kX2hlYWRlcl90IGhlYWRlciwKCQkJCQkgIGRybV9yYWRlb25fa2NtZF9idWZmZXJfdCAqY21kYnVmKQp7CglpbnQgc3ogPSBoZWFkZXIudmVjbGluZWFyLmNvdW50ICogNDsKCWludCBzdGFydCA9IGhlYWRlci52ZWNsaW5lYXIuYWRkcl9sbyB8IChoZWFkZXIudmVjbGluZWFyLmFkZHJfaGkgPDwgOCk7CglSSU5HX0xPQ0FMUzsKCiAgICAgICAgaWYgKCFzeikKICAgICAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgIGlmIChzeiAqIDQgPiBjbWRidWYtPmJ1ZnN6KQogICAgICAgICAgICAgICAgcmV0dXJuIERSTV9FUlIoRUlOVkFMKTsKCglCRUdJTl9SSU5HKDUgKyBzeik7CglPVVRfUklOR19SRUcoUkFERU9OX1NFX1RDTF9TVEFURV9GTFVTSCwgMCk7CglPVVRfUklORyhDUF9QQUNLRVQwKFJBREVPTl9TRV9UQ0xfVkVDVE9SX0lORFhfUkVHLCAwKSk7CglPVVRfUklORyhzdGFydCB8ICgxIDw8IFJBREVPTl9WRUNfSU5EWF9PQ1RXT1JEX1NUUklERV9TSElGVCkpOwoJT1VUX1JJTkcoQ1BfUEFDS0VUMF9UQUJMRShSQURFT05fU0VfVENMX1ZFQ1RPUl9EQVRBX1JFRywgKHN6IC0gMSkpKTsKCU9VVF9SSU5HX1RBQkxFKGNtZGJ1Zi0+YnVmLCBzeik7CglBRFZBTkNFX1JJTkcoKTsKCgljbWRidWYtPmJ1ZiArPSBzeiAqIHNpemVvZihpbnQpOwoJY21kYnVmLT5idWZzeiAtPSBzeiAqIHNpemVvZihpbnQpOwoJcmV0dXJuIDA7Cn0KCnN0YXRpYyBpbnQgcmFkZW9uX2VtaXRfcGFja2V0Myhkcm1fZGV2aWNlX3QgKiBkZXYsCgkJCSAgICAgICBkcm1fZmlsZV90ICogZmlscF9wcml2LAoJCQkgICAgICAgZHJtX3JhZGVvbl9rY21kX2J1ZmZlcl90ICpjbWRidWYpCnsKCWRybV9yYWRlb25fcHJpdmF0ZV90ICpkZXZfcHJpdiA9IGRldi0+ZGV2X3ByaXZhdGU7Cgl1bnNpZ25lZCBpbnQgY21kc3o7CglpbnQgcmV0OwoJUklOR19MT0NBTFM7CgoJRFJNX0RFQlVHKCJcbiIpOwoKCWlmICgocmV0ID0gcmFkZW9uX2NoZWNrX2FuZF9maXh1cF9wYWNrZXQzKGRldl9wcml2LCBmaWxwX3ByaXYsCgkJCQkJCSAgY21kYnVmLCAmY21kc3opKSkgewoJCURSTV9FUlJPUigiUGFja2V0IHZlcmlmaWNhdGlvbiBmYWlsZWRcbiIpOwoJCXJldHVybiByZXQ7Cgl9CgoJQkVHSU5fUklORyhjbWRzeik7CglPVVRfUklOR19UQUJMRShjbWRidWYtPmJ1ZiwgY21kc3opOwoJQURWQU5DRV9SSU5HKCk7CgoJY21kYnVmLT5idWYgKz0gY21kc3ogKiA0OwoJY21kYnVmLT5idWZzeiAtPSBjbWRzeiAqIDQ7CglyZXR1cm4gMDsKfQoKc3RhdGljIGludCByYWRlb25fZW1pdF9wYWNrZXQzX2NsaXByZWN0KGRybV9kZXZpY2VfdCAqZGV2LAoJCQkJCWRybV9maWxlX3QgKmZpbHBfcHJpdiwKCQkJCQlkcm1fcmFkZW9uX2tjbWRfYnVmZmVyX3QgKmNtZGJ1ZiwKCQkJCQlpbnQgb3JpZ19uYm94KQp7Cglkcm1fcmFkZW9uX3ByaXZhdGVfdCAqZGV2X3ByaXYgPSBkZXYtPmRldl9wcml2YXRlOwoJZHJtX2NsaXBfcmVjdF90IGJveDsKCXVuc2lnbmVkIGludCBjbWRzejsKCWludCByZXQ7Cglkcm1fY2xpcF9yZWN0X3QgX191c2VyICpib3hlcyA9IGNtZGJ1Zi0+Ym94ZXM7CglpbnQgaSA9IDA7CglSSU5HX0xPQ0FMUzsKCglEUk1fREVCVUcoIlxuIik7CgoJaWYgKChyZXQgPSByYWRlb25fY2hlY2tfYW5kX2ZpeHVwX3BhY2tldDMoZGV2X3ByaXYsIGZpbHBfcHJpdiwKCQkJCQkJICBjbWRidWYsICZjbWRzeikpKSB7CgkJRFJNX0VSUk9SKCJQYWNrZXQgdmVyaWZpY2F0aW9uIGZhaWxlZFxuIik7CgkJcmV0dXJuIHJldDsKCX0KCglpZiAoIW9yaWdfbmJveCkKCQlnb3RvIG91dDsKCglkbyB7CgkJaWYgKGkgPCBjbWRidWYtPm5ib3gpIHsKCQkJaWYgKERSTV9DT1BZX0ZST01fVVNFUigmYm94LCAmYm94ZXNbaV0sIHNpemVvZihib3gpKSkKCQkJCXJldHVybiBEUk1fRVJSKEVGQVVMVCk7CgkJCS8qIEZJWE1FIFRoZSBzZWNvbmQgYW5kIHN1YnNlcXVlbnQgdGltZXMgcm91bmQKCQkJICogdGhpcyBsb29wLCBzZW5kIGEgV0FJVF9VTlRJTF8zRF9JRExFIGJlZm9yZQoJCQkgKiBjYWxsaW5nIGVtaXRfY2xpcF9yZWN0KCkuIFRoaXMgZml4ZXMgYQoJCQkgKiBsb2NrdXAgb24gZmFzdCBtYWNoaW5lcyB3aGVuIHNlbmRpbmcKCQkJICogc2V2ZXJhbCBjbGlwcmVjdHMgd2l0aCBhIGNtZGJ1ZiwgYXMgd2hlbgoJCQkgKiB3YXZpbmcgYSAyRCB3aW5kb3cgb3ZlciBhIDNECgkJCSAqIHdpbmRvdy4gU29tZXRoaW5nIGluIHRoZSBjb21tYW5kcyBmcm9tIHVzZXIKCQkJICogc3BhY2Ugc2VlbXMgdG8gaGFuZyB0aGUgY2FyZCB3aGVuIHRoZXkncmUKCQkJICogc2VudCBzZXZlcmFsIHRpbWVzIGluIGEgcm93LiBUaGF0IHdvdWxkIGJlCgkJCSAqIHRoZSBjb3JyZWN0IHBsYWNlIHRvIGZpeCBpdCBidXQgdGhpcyB3b3JrcwoJCQkgKiBhcm91bmQgaXQgdW50aWwgSSBjYW4gZmlndXJlIHRoYXQgb3V0IC0gVGltCgkJCSAqIFNtaXRoICovCgkJCWlmIChpKSB7CgkJCQlCRUdJTl9SSU5HKDIpOwoJCQkJUkFERU9OX1dBSVRfVU5USUxfM0RfSURMRSgpOwoJCQkJQURWQU5DRV9SSU5HKCk7CgkJCX0KCQkJcmFkZW9uX2VtaXRfY2xpcF9yZWN0KGRldl9wcml2LCAmYm94KTsKCQl9CgoJCUJFR0lOX1JJTkcoY21kc3opOwoJCU9VVF9SSU5HX1RBQkxFKGNtZGJ1Zi0+YnVmLCBjbWRzeik7CgkJQURWQU5DRV9SSU5HKCk7CgoJfSB3aGlsZSAoKytpIDwgY21kYnVmLT5uYm94KTsKCWlmIChjbWRidWYtPm5ib3ggPT0gMSkKCQljbWRidWYtPm5ib3ggPSAwOwoKICAgICAgb3V0OgoJY21kYnVmLT5idWYgKz0gY21kc3ogKiA0OwoJY21kYnVmLT5idWZzeiAtPSBjbWRzeiAqIDQ7CglyZXR1cm4gMDsKfQoKc3RhdGljIGludCByYWRlb25fZW1pdF93YWl0KGRybV9kZXZpY2VfdCAqIGRldiwgaW50IGZsYWdzKQp7Cglkcm1fcmFkZW9uX3ByaXZhdGVfdCAqZGV2X3ByaXYgPSBkZXYtPmRldl9wcml2YXRlOwoJUklOR19MT0NBTFM7CgoJRFJNX0RFQlVHKCIlczogJXhcbiIsIF9fRlVOQ1RJT05fXywgZmxhZ3MpOwoJc3dpdGNoIChmbGFncykgewoJY2FzZSBSQURFT05fV0FJVF8yRDoKCQlCRUdJTl9SSU5HKDIpOwoJCVJBREVPTl9XQUlUX1VOVElMXzJEX0lETEUoKTsKCQlBRFZBTkNFX1JJTkcoKTsKCQlicmVhazsKCWNhc2UgUkFERU9OX1dBSVRfM0Q6CgkJQkVHSU5fUklORygyKTsKCQlSQURFT05fV0FJVF9VTlRJTF8zRF9JRExFKCk7CgkJQURWQU5DRV9SSU5HKCk7CgkJYnJlYWs7CgljYXNlIFJBREVPTl9XQUlUXzJEIHwgUkFERU9OX1dBSVRfM0Q6CgkJQkVHSU5fUklORygyKTsKCQlSQURFT05fV0FJVF9VTlRJTF9JRExFKCk7CgkJQURWQU5DRV9SSU5HKCk7CgkJYnJlYWs7CglkZWZhdWx0OgoJCXJldHVybiBEUk1fRVJSKEVJTlZBTCk7Cgl9CgoJcmV0dXJuIDA7Cn0KCnN0YXRpYyBpbnQgcmFkZW9uX2NwX2NtZGJ1ZihEUk1fSU9DVExfQVJHUykKewoJRFJNX0RFVklDRTsKCWRybV9yYWRlb25fcHJpdmF0ZV90ICpkZXZfcHJpdiA9IGRldi0+ZGV2X3ByaXZhdGU7Cglkcm1fZmlsZV90ICpmaWxwX3ByaXY7Cglkcm1fZGV2aWNlX2RtYV90ICpkbWEgPSBkZXYtPmRtYTsKCWRybV9idWZfdCAqYnVmID0gTlVMTDsKCWludCBpZHg7Cglkcm1fcmFkZW9uX2tjbWRfYnVmZmVyX3QgY21kYnVmOwoJZHJtX3JhZGVvbl9jbWRfaGVhZGVyX3QgaGVhZGVyOwoJaW50IG9yaWdfbmJveCwgb3JpZ19idWZzejsKCWNoYXIgKmtidWYgPSBOVUxMOwoKCUxPQ0tfVEVTVF9XSVRIX1JFVFVSTihkZXYsIGZpbHApOwoKCURSTV9HRVRfUFJJVl9XSVRIX1JFVFVSTihmaWxwX3ByaXYsIGZpbHApOwoKCURSTV9DT1BZX0ZST01fVVNFUl9JT0NUTChjbWRidWYsCgkJCQkgKGRybV9yYWRlb25fY21kX2J1ZmZlcl90IF9fdXNlciAqKSBkYXRhLAoJCQkJIHNpemVvZihjbWRidWYpKTsKCglSSU5HX1NQQUNFX1RFU1RfV0lUSF9SRVRVUk4oZGV2X3ByaXYpOwoJVkJfQUdFX1RFU1RfV0lUSF9SRVRVUk4oZGV2X3ByaXYpOwoKCWlmIChjbWRidWYuYnVmc3ogPiA2NCAqIDEwMjQgfHwgY21kYnVmLmJ1ZnN6IDwgMCkgewoJCXJldHVybiBEUk1fRVJSKEVJTlZBTCk7Cgl9CgoJLyogQWxsb2NhdGUgYW4gaW4ta2VybmVsIGFyZWEgYW5kIGNvcHkgaW4gdGhlIGNtZGJ1Zi4gIERvIHRoaXMgdG8gYXZvaWQKCSAqIHJhY2VzIGJldHdlZW4gY2hlY2tpbmcgdmFsdWVzIGFuZCB1c2luZyB0aG9zZSB2YWx1ZXMgaW4gb3RoZXIgY29kZSwKCSAqIGFuZCBzaW1wbHkgdG8gYXZvaWQgYSBsb3Qgb2YgZnVuY3Rpb24gY2FsbHMgdG8gY29weSBpbiBkYXRhLgoJICovCglvcmlnX2J1ZnN6ID0gY21kYnVmLmJ1ZnN6OwoJaWYgKG9yaWdfYnVmc3ogIT0gMCkgewoJCWtidWYgPSBkcm1fYWxsb2MoY21kYnVmLmJ1ZnN6LCBEUk1fTUVNX0RSSVZFUik7CgkJaWYgKGtidWYgPT0gTlVMTCkKCQkJcmV0dXJuIERSTV9FUlIoRU5PTUVNKTsKCQlpZiAoRFJNX0NPUFlfRlJPTV9VU0VSKGtidWYsICh2b2lkIF9fdXNlciAqKWNtZGJ1Zi5idWYsCgkJCQkgICAgICAgY21kYnVmLmJ1ZnN6KSkgewoJCQlkcm1fZnJlZShrYnVmLCBvcmlnX2J1ZnN6LCBEUk1fTUVNX0RSSVZFUik7CgkJCXJldHVybiBEUk1fRVJSKEVGQVVMVCk7CgkJfQoJCWNtZGJ1Zi5idWYgPSBrYnVmOwoJfQoKCW9yaWdfbmJveCA9IGNtZGJ1Zi5uYm94OwoKCWlmIChkZXZfcHJpdi0+bWljcm9jb2RlX3ZlcnNpb24gPT0gVUNPREVfUjMwMCkgewoJCWludCB0ZW1wOwoJCXRlbXAgPSByMzAwX2RvX2NwX2NtZGJ1ZihkZXYsIGZpbHAsIGZpbHBfcHJpdiwgJmNtZGJ1Zik7CgoJCWlmIChvcmlnX2J1ZnN6ICE9IDApCgkJCWRybV9mcmVlKGtidWYsIG9yaWdfYnVmc3osIERSTV9NRU1fRFJJVkVSKTsKCgkJcmV0dXJuIHRlbXA7Cgl9CgoJLyogbWljcm9jb2RlX3ZlcnNpb24gIT0gcjMwMCAqLwoJd2hpbGUgKGNtZGJ1Zi5idWZzeiA+PSBzaXplb2YoaGVhZGVyKSkgewoKCQloZWFkZXIuaSA9ICooaW50ICopY21kYnVmLmJ1ZjsKCQljbWRidWYuYnVmICs9IHNpemVvZihoZWFkZXIpOwoJCWNtZGJ1Zi5idWZzeiAtPSBzaXplb2YoaGVhZGVyKTsKCgkJc3dpdGNoIChoZWFkZXIuaGVhZGVyLmNtZF90eXBlKSB7CgkJY2FzZSBSQURFT05fQ01EX1BBQ0tFVDoKCQkJRFJNX0RFQlVHKCJSQURFT05fQ01EX1BBQ0tFVFxuIik7CgkJCWlmIChyYWRlb25fZW1pdF9wYWNrZXRzCgkJCSAgICAoZGV2X3ByaXYsIGZpbHBfcHJpdiwgaGVhZGVyLCAmY21kYnVmKSkgewoJCQkJRFJNX0VSUk9SKCJyYWRlb25fZW1pdF9wYWNrZXRzIGZhaWxlZFxuIik7CgkJCQlnb3RvIGVycjsKCQkJfQoJCQlicmVhazsKCgkJY2FzZSBSQURFT05fQ01EX1NDQUxBUlM6CgkJCURSTV9ERUJVRygiUkFERU9OX0NNRF9TQ0FMQVJTXG4iKTsKCQkJaWYgKHJhZGVvbl9lbWl0X3NjYWxhcnMoZGV2X3ByaXYsIGhlYWRlciwgJmNtZGJ1ZikpIHsKCQkJCURSTV9FUlJPUigicmFkZW9uX2VtaXRfc2NhbGFycyBmYWlsZWRcbiIpOwoJCQkJZ290byBlcnI7CgkJCX0KCQkJYnJlYWs7CgoJCWNhc2UgUkFERU9OX0NNRF9WRUNUT1JTOgoJCQlEUk1fREVCVUcoIlJBREVPTl9DTURfVkVDVE9SU1xuIik7CgkJCWlmIChyYWRlb25fZW1pdF92ZWN0b3JzKGRldl9wcml2LCBoZWFkZXIsICZjbWRidWYpKSB7CgkJCQlEUk1fRVJST1IoInJhZGVvbl9lbWl0X3ZlY3RvcnMgZmFpbGVkXG4iKTsKCQkJCWdvdG8gZXJyOwoJCQl9CgkJCWJyZWFrOwoKCQljYXNlIFJBREVPTl9DTURfRE1BX0RJU0NBUkQ6CgkJCURSTV9ERUJVRygiUkFERU9OX0NNRF9ETUFfRElTQ0FSRFxuIik7CgkJCWlkeCA9IGhlYWRlci5kbWEuYnVmX2lkeDsKCQkJaWYgKGlkeCA8IDAgfHwgaWR4ID49IGRtYS0+YnVmX2NvdW50KSB7CgkJCQlEUk1fRVJST1IoImJ1ZmZlciBpbmRleCAlZCAob2YgJWQgbWF4KVxuIiwKCQkJCQkgIGlkeCwgZG1hLT5idWZfY291bnQgLSAxKTsKCQkJCWdvdG8gZXJyOwoJCQl9CgoJCQlidWYgPSBkbWEtPmJ1Zmxpc3RbaWR4XTsKCQkJaWYgKGJ1Zi0+ZmlscCAhPSBmaWxwIHx8IGJ1Zi0+cGVuZGluZykgewoJCQkJRFJNX0VSUk9SKCJiYWQgYnVmZmVyICVwICVwICVkXG4iLAoJCQkJCSAgYnVmLT5maWxwLCBmaWxwLCBidWYtPnBlbmRpbmcpOwoJCQkJZ290byBlcnI7CgkJCX0KCgkJCXJhZGVvbl9jcF9kaXNjYXJkX2J1ZmZlcihkZXYsIGJ1Zik7CgkJCWJyZWFrOwoKCQljYXNlIFJBREVPTl9DTURfUEFDS0VUMzoKCQkJRFJNX0RFQlVHKCJSQURFT05fQ01EX1BBQ0tFVDNcbiIpOwoJCQlpZiAocmFkZW9uX2VtaXRfcGFja2V0MyhkZXYsIGZpbHBfcHJpdiwgJmNtZGJ1ZikpIHsKCQkJCURSTV9FUlJPUigicmFkZW9uX2VtaXRfcGFja2V0MyBmYWlsZWRcbiIpOwoJCQkJZ290byBlcnI7CgkJCX0KCQkJYnJlYWs7CgoJCWNhc2UgUkFERU9OX0NNRF9QQUNLRVQzX0NMSVA6CgkJCURSTV9ERUJVRygiUkFERU9OX0NNRF9QQUNLRVQzX0NMSVBcbiIpOwoJCQlpZiAocmFkZW9uX2VtaXRfcGFja2V0M19jbGlwcmVjdAoJCQkgICAgKGRldiwgZmlscF9wcml2LCAmY21kYnVmLCBvcmlnX25ib3gpKSB7CgkJCQlEUk1fRVJST1IoInJhZGVvbl9lbWl0X3BhY2tldDNfY2xpcCBmYWlsZWRcbiIpOwoJCQkJZ290byBlcnI7CgkJCX0KCQkJYnJlYWs7CgoJCWNhc2UgUkFERU9OX0NNRF9TQ0FMQVJTMjoKCQkJRFJNX0RFQlVHKCJSQURFT05fQ01EX1NDQUxBUlMyXG4iKTsKCQkJaWYgKHJhZGVvbl9lbWl0X3NjYWxhcnMyKGRldl9wcml2LCBoZWFkZXIsICZjbWRidWYpKSB7CgkJCQlEUk1fRVJST1IoInJhZGVvbl9lbWl0X3NjYWxhcnMyIGZhaWxlZFxuIik7CgkJCQlnb3RvIGVycjsKCQkJfQoJCQlicmVhazsKCgkJY2FzZSBSQURFT05fQ01EX1dBSVQ6CgkJCURSTV9ERUJVRygiUkFERU9OX0NNRF9XQUlUXG4iKTsKCQkJaWYgKHJhZGVvbl9lbWl0X3dhaXQoZGV2LCBoZWFkZXIud2FpdC5mbGFncykpIHsKCQkJCURSTV9FUlJPUigicmFkZW9uX2VtaXRfd2FpdCBmYWlsZWRcbiIpOwoJCQkJZ290byBlcnI7CgkJCX0KCQkJYnJlYWs7CgkJY2FzZSBSQURFT05fQ01EX1ZFQ0xJTkVBUjoKCQkJRFJNX0RFQlVHKCJSQURFT05fQ01EX1ZFQ0xJTkVBUlxuIik7CgkJCWlmIChyYWRlb25fZW1pdF92ZWNsaW5lYXIoZGV2X3ByaXYsIGhlYWRlciwgJmNtZGJ1ZikpIHsKCQkJCURSTV9FUlJPUigicmFkZW9uX2VtaXRfdmVjbGluZWFyIGZhaWxlZFxuIik7CgkJCQlnb3RvIGVycjsKCQkJfQoJCQlicmVhazsKCgkJZGVmYXVsdDoKCQkJRFJNX0VSUk9SKCJiYWQgY21kX3R5cGUgJWQgYXQgJXBcbiIsCgkJCQkgIGhlYWRlci5oZWFkZXIuY21kX3R5cGUsCgkJCQkgIGNtZGJ1Zi5idWYgLSBzaXplb2YoaGVhZGVyKSk7CgkJCWdvdG8gZXJyOwoJCX0KCX0KCglpZiAob3JpZ19idWZzeiAhPSAwKQoJCWRybV9mcmVlKGtidWYsIG9yaWdfYnVmc3osIERSTV9NRU1fRFJJVkVSKTsKCglEUk1fREVCVUcoIkRPTkVcbiIpOwoJQ09NTUlUX1JJTkcoKTsKCXJldHVybiAwOwoKICAgICAgZXJyOgoJaWYgKG9yaWdfYnVmc3ogIT0gMCkKCQlkcm1fZnJlZShrYnVmLCBvcmlnX2J1ZnN6LCBEUk1fTUVNX0RSSVZFUik7CglyZXR1cm4gRFJNX0VSUihFSU5WQUwpOwp9CgpzdGF0aWMgaW50IHJhZGVvbl9jcF9nZXRwYXJhbShEUk1fSU9DVExfQVJHUykKewoJRFJNX0RFVklDRTsKCWRybV9yYWRlb25fcHJpdmF0ZV90ICpkZXZfcHJpdiA9IGRldi0+ZGV2X3ByaXZhdGU7Cglkcm1fcmFkZW9uX2dldHBhcmFtX3QgcGFyYW07CglpbnQgdmFsdWU7CgoJRFJNX0NPUFlfRlJPTV9VU0VSX0lPQ1RMKHBhcmFtLCAoZHJtX3JhZGVvbl9nZXRwYXJhbV90IF9fdXNlciAqKSBkYXRhLAoJCQkJIHNpemVvZihwYXJhbSkpOwoKCURSTV9ERUJVRygicGlkPSVkXG4iLCBEUk1fQ1VSUkVOVFBJRCk7CgoJc3dpdGNoIChwYXJhbS5wYXJhbSkgewoJY2FzZSBSQURFT05fUEFSQU1fR0FSVF9CVUZGRVJfT0ZGU0VUOgoJCXZhbHVlID0gZGV2X3ByaXYtPmdhcnRfYnVmZmVyc19vZmZzZXQ7CgkJYnJlYWs7CgljYXNlIFJBREVPTl9QQVJBTV9MQVNUX0ZSQU1FOgoJCWRldl9wcml2LT5zdGF0cy5sYXN0X2ZyYW1lX3JlYWRzKys7CgkJdmFsdWUgPSBHRVRfU0NSQVRDSCgwKTsKCQlicmVhazsKCWNhc2UgUkFERU9OX1BBUkFNX0xBU1RfRElTUEFUQ0g6CgkJdmFsdWUgPSBHRVRfU0NSQVRDSCgxKTsKCQlicmVhazsKCWNhc2UgUkFERU9OX1BBUkFNX0xBU1RfQ0xFQVI6CgkJZGV2X3ByaXYtPnN0YXRzLmxhc3RfY2xlYXJfcmVhZHMrKzsKCQl2YWx1ZSA9IEdFVF9TQ1JBVENIKDIpOwoJCWJyZWFrOwoJY2FzZSBSQURFT05fUEFSQU1fSVJRX05SOgoJCXZhbHVlID0gZGV2LT5pcnE7CgkJYnJlYWs7CgljYXNlIFJBREVPTl9QQVJBTV9HQVJUX0JBU0U6CgkJdmFsdWUgPSBkZXZfcHJpdi0+Z2FydF92bV9zdGFydDsKCQlicmVhazsKCWNhc2UgUkFERU9OX1BBUkFNX1JFR0lTVEVSX0hBTkRMRToKCQl2YWx1ZSA9IGRldl9wcml2LT5tbWlvLT5vZmZzZXQ7CgkJYnJlYWs7CgljYXNlIFJBREVPTl9QQVJBTV9TVEFUVVNfSEFORExFOgoJCXZhbHVlID0gZGV2X3ByaXYtPnJpbmdfcnB0cl9vZmZzZXQ7CgkJYnJlYWs7CiNpZiBCSVRTX1BFUl9MT05HID09IDMyCgkJLyoKCQkgKiBUaGlzIGlvY3RsKCkgZG9lc24ndCB3b3JrIG9uIDY0LWJpdCBwbGF0Zm9ybXMgYmVjYXVzZSBod19sb2NrIGlzIGEKCQkgKiBwb2ludGVyIHdoaWNoIGNhbid0IGZpdCBpbnRvIGFuIGludC1zaXplZCB2YXJpYWJsZS4gIEFjY29yZGluZyB0bwoJCSAqIE1pY2hlbCBE5G56ZXIsIHRoZSBpb2N0bCgpIGlzIG9ubHkgdXNlZCBvbiBlbWJlZGRlZCBwbGF0Zm9ybXMsIHNvCgkJICogbm90IHN1cHBvcnRpbmcgaXQgc2hvdWxkbid0IGJlIGEgcHJvYmxlbS4gIElmIHRoZSBzYW1lIGZ1bmN0aW9uYWxpdHkKCQkgKiBpcyBuZWVkZWQgb24gNjQtYml0IHBsYXRmb3JtcywgYSBuZXcgaW9jdGwoKSB3b3VsZCBoYXZlIHRvIGJlIGFkZGVkLAoJCSAqIHNvIGJhY2t3YXJkcy1jb21wYXRpYmlsaXR5IGZvciB0aGUgZW1iZWRkZWQgcGxhdGZvcm1zIGNhbiBiZQoJCSAqIG1haW50YWluZWQuICAtLWRhdmlkbSA0LUZlYi0yMDA0LgoJCSAqLwoJY2FzZSBSQURFT05fUEFSQU1fU0FSRUFfSEFORExFOgoJCS8qIFRoZSBsb2NrIGlzIHRoZSBmaXJzdCBkd29yZCBpbiB0aGUgc2FyZWEuICovCgkJdmFsdWUgPSAobG9uZylkZXYtPmxvY2suaHdfbG9jazsKCQlicmVhazsKI2VuZGlmCgljYXNlIFJBREVPTl9QQVJBTV9HQVJUX1RFWF9IQU5ETEU6CgkJdmFsdWUgPSBkZXZfcHJpdi0+Z2FydF90ZXh0dXJlc19vZmZzZXQ7CgkJYnJlYWs7CgljYXNlIFJBREVPTl9QQVJBTV9TQ1JBVENIX09GRlNFVDoKCQlpZiAoIWRldl9wcml2LT53cml0ZWJhY2tfd29ya3MpCgkJCXJldHVybiBEUk1fRVJSKEVJTlZBTCk7CgkJdmFsdWUgPSBSQURFT05fU0NSQVRDSF9SRUdfT0ZGU0VUOwoJCWJyZWFrOwoJY2FzZSBSQURFT05fUEFSQU1fQ0FSRF9UWVBFOgoJCWlmIChkZXZfcHJpdi0+ZmxhZ3MgJiBSQURFT05fSVNfUENJRSkKCQkJdmFsdWUgPSBSQURFT05fQ0FSRF9QQ0lFOwoJCWVsc2UgaWYgKGRldl9wcml2LT5mbGFncyAmIFJBREVPTl9JU19BR1ApCgkJCXZhbHVlID0gUkFERU9OX0NBUkRfQUdQOwoJCWVsc2UKCQkJdmFsdWUgPSBSQURFT05fQ0FSRF9QQ0k7CgkJYnJlYWs7CglkZWZhdWx0OgoJCURSTV9ERUJVRygiSW52YWxpZCBwYXJhbWV0ZXIgJWRcbiIsIHBhcmFtLnBhcmFtKTsKCQlyZXR1cm4gRFJNX0VSUihFSU5WQUwpOwoJfQoKCWlmIChEUk1fQ09QWV9UT19VU0VSKHBhcmFtLnZhbHVlLCAmdmFsdWUsIHNpemVvZihpbnQpKSkgewoJCURSTV9FUlJPUigiY29weV90b191c2VyXG4iKTsKCQlyZXR1cm4gRFJNX0VSUihFRkFVTFQpOwoJfQoKCXJldHVybiAwOwp9CgpzdGF0aWMgaW50IHJhZGVvbl9jcF9zZXRwYXJhbShEUk1fSU9DVExfQVJHUykKewoJRFJNX0RFVklDRTsKCWRybV9yYWRlb25fcHJpdmF0ZV90ICpkZXZfcHJpdiA9IGRldi0+ZGV2X3ByaXZhdGU7Cglkcm1fZmlsZV90ICpmaWxwX3ByaXY7Cglkcm1fcmFkZW9uX3NldHBhcmFtX3Qgc3A7CglzdHJ1Y3QgZHJtX3JhZGVvbl9kcml2ZXJfZmlsZV9maWVsZHMgKnJhZGVvbl9wcml2OwoKCURSTV9HRVRfUFJJVl9XSVRIX1JFVFVSTihmaWxwX3ByaXYsIGZpbHApOwoKCURSTV9DT1BZX0ZST01fVVNFUl9JT0NUTChzcCwgKGRybV9yYWRlb25fc2V0cGFyYW1fdCBfX3VzZXIgKikgZGF0YSwKCQkJCSBzaXplb2Yoc3ApKTsKCglzd2l0Y2ggKHNwLnBhcmFtKSB7CgljYXNlIFJBREVPTl9TRVRQQVJBTV9GQl9MT0NBVElPTjoKCQlyYWRlb25fcHJpdiA9IGZpbHBfcHJpdi0+ZHJpdmVyX3ByaXY7CgkJcmFkZW9uX3ByaXYtPnJhZGVvbl9mYl9kZWx0YSA9IGRldl9wcml2LT5mYl9sb2NhdGlvbiAtIHNwLnZhbHVlOwoJCWJyZWFrOwoJY2FzZSBSQURFT05fU0VUUEFSQU1fU1dJVENIX1RJTElORzoKCQlpZiAoc3AudmFsdWUgPT0gMCkgewoJCQlEUk1fREVCVUcoImNvbG9yIHRpbGluZyBkaXNhYmxlZFxuIik7CgkJCWRldl9wcml2LT5mcm9udF9waXRjaF9vZmZzZXQgJj0gflJBREVPTl9EU1RfVElMRV9NQUNSTzsKCQkJZGV2X3ByaXYtPmJhY2tfcGl0Y2hfb2Zmc2V0ICY9IH5SQURFT05fRFNUX1RJTEVfTUFDUk87CgkJCWRldl9wcml2LT5zYXJlYV9wcml2LT50aWxpbmdfZW5hYmxlZCA9IDA7CgkJfSBlbHNlIGlmIChzcC52YWx1ZSA9PSAxKSB7CgkJCURSTV9ERUJVRygiY29sb3IgdGlsaW5nIGVuYWJsZWRcbiIpOwoJCQlkZXZfcHJpdi0+ZnJvbnRfcGl0Y2hfb2Zmc2V0IHw9IFJBREVPTl9EU1RfVElMRV9NQUNSTzsKCQkJZGV2X3ByaXYtPmJhY2tfcGl0Y2hfb2Zmc2V0IHw9IFJBREVPTl9EU1RfVElMRV9NQUNSTzsKCQkJZGV2X3ByaXYtPnNhcmVhX3ByaXYtPnRpbGluZ19lbmFibGVkID0gMTsKCQl9CgkJYnJlYWs7CgljYXNlIFJBREVPTl9TRVRQQVJBTV9QQ0lHQVJUX0xPQ0FUSU9OOgoJCWRldl9wcml2LT5wY2lnYXJ0X29mZnNldCA9IHNwLnZhbHVlOwoJCWJyZWFrOwoJY2FzZSBSQURFT05fU0VUUEFSQU1fTkVXX01FTU1BUDoKCQlkZXZfcHJpdi0+bmV3X21lbW1hcCA9IHNwLnZhbHVlOwoJCWJyZWFrOwoJZGVmYXVsdDoKCQlEUk1fREVCVUcoIkludmFsaWQgcGFyYW1ldGVyICVkXG4iLCBzcC5wYXJhbSk7CgkJcmV0dXJuIERSTV9FUlIoRUlOVkFMKTsKCX0KCglyZXR1cm4gMDsKfQoKLyogV2hlbiBhIGNsaWVudCBkaWVzOgogKiAgICAtIENoZWNrIGZvciBhbmQgY2xlYW4gdXAgZmxpcHBlZCBwYWdlIHN0YXRlCiAqICAgIC0gRnJlZSBhbnkgYWxsb2NlZCBHQVJUIG1lbW9yeS4KICogICAgLSBGcmVlIGFueSBhbGxvY2VkIHJhZGVvbiBzdXJmYWNlcy4KICoKICogRFJNIGluZnJhc3RydWN0dXJlIHRha2VzIGNhcmUgb2YgcmVjbGFpbWluZyBkbWEgYnVmZmVycy4KICovCnZvaWQgcmFkZW9uX2RyaXZlcl9wcmVjbG9zZShkcm1fZGV2aWNlX3QgKiBkZXYsIERSTUZJTEUgZmlscCkKewoJaWYgKGRldi0+ZGV2X3ByaXZhdGUpIHsKCQlkcm1fcmFkZW9uX3ByaXZhdGVfdCAqZGV2X3ByaXYgPSBkZXYtPmRldl9wcml2YXRlOwoJCWlmIChkZXZfcHJpdi0+cGFnZV9mbGlwcGluZykgewoJCQlyYWRlb25fZG9fY2xlYW51cF9wYWdlZmxpcChkZXYpOwoJCX0KCQlyYWRlb25fbWVtX3JlbGVhc2UoZmlscCwgZGV2X3ByaXYtPmdhcnRfaGVhcCk7CgkJcmFkZW9uX21lbV9yZWxlYXNlKGZpbHAsIGRldl9wcml2LT5mYl9oZWFwKTsKCQlyYWRlb25fc3VyZmFjZXNfcmVsZWFzZShmaWxwLCBkZXZfcHJpdik7Cgl9Cn0KCnZvaWQgcmFkZW9uX2RyaXZlcl9sYXN0Y2xvc2UoZHJtX2RldmljZV90ICogZGV2KQp7CglyYWRlb25fZG9fcmVsZWFzZShkZXYpOwp9CgppbnQgcmFkZW9uX2RyaXZlcl9vcGVuKGRybV9kZXZpY2VfdCAqIGRldiwgZHJtX2ZpbGVfdCAqIGZpbHBfcHJpdikKewoJZHJtX3JhZGVvbl9wcml2YXRlX3QgKmRldl9wcml2ID0gZGV2LT5kZXZfcHJpdmF0ZTsKCXN0cnVjdCBkcm1fcmFkZW9uX2RyaXZlcl9maWxlX2ZpZWxkcyAqcmFkZW9uX3ByaXY7CgoJRFJNX0RFQlVHKCJcbiIpOwoJcmFkZW9uX3ByaXYgPQoJICAgIChzdHJ1Y3QgZHJtX3JhZGVvbl9kcml2ZXJfZmlsZV9maWVsZHMgKikKCSAgICBkcm1fYWxsb2Moc2l6ZW9mKCpyYWRlb25fcHJpdiksIERSTV9NRU1fRklMRVMpOwoKCWlmICghcmFkZW9uX3ByaXYpCgkJcmV0dXJuIC1FTk9NRU07CgoJZmlscF9wcml2LT5kcml2ZXJfcHJpdiA9IHJhZGVvbl9wcml2OwoKCWlmIChkZXZfcHJpdikKCQlyYWRlb25fcHJpdi0+cmFkZW9uX2ZiX2RlbHRhID0gZGV2X3ByaXYtPmZiX2xvY2F0aW9uOwoJZWxzZQoJCXJhZGVvbl9wcml2LT5yYWRlb25fZmJfZGVsdGEgPSAwOwoJcmV0dXJuIDA7Cn0KCnZvaWQgcmFkZW9uX2RyaXZlcl9wb3N0Y2xvc2UoZHJtX2RldmljZV90ICogZGV2LCBkcm1fZmlsZV90ICogZmlscF9wcml2KQp7CglzdHJ1Y3QgZHJtX3JhZGVvbl9kcml2ZXJfZmlsZV9maWVsZHMgKnJhZGVvbl9wcml2ID0KCSAgICBmaWxwX3ByaXYtPmRyaXZlcl9wcml2OwoKCWRybV9mcmVlKHJhZGVvbl9wcml2LCBzaXplb2YoKnJhZGVvbl9wcml2KSwgRFJNX01FTV9GSUxFUyk7Cn0KCmRybV9pb2N0bF9kZXNjX3QgcmFkZW9uX2lvY3Rsc1tdID0gewoJW0RSTV9JT0NUTF9OUihEUk1fUkFERU9OX0NQX0lOSVQpXSA9IHtyYWRlb25fY3BfaW5pdCwgRFJNX0FVVEh8RFJNX01BU1RFUnxEUk1fUk9PVF9PTkxZfSwKCVtEUk1fSU9DVExfTlIoRFJNX1JBREVPTl9DUF9TVEFSVCldID0ge3JhZGVvbl9jcF9zdGFydCwgRFJNX0FVVEh8RFJNX01BU1RFUnxEUk1fUk9PVF9PTkxZfSwKCVtEUk1fSU9DVExfTlIoRFJNX1JBREVPTl9DUF9TVE9QKV0gPSB7cmFkZW9uX2NwX3N0b3AsIERSTV9BVVRIfERSTV9NQVNURVJ8RFJNX1JPT1RfT05MWX0sCglbRFJNX0lPQ1RMX05SKERSTV9SQURFT05fQ1BfUkVTRVQpXSA9IHtyYWRlb25fY3BfcmVzZXQsIERSTV9BVVRIfERSTV9NQVNURVJ8RFJNX1JPT1RfT05MWX0sCglbRFJNX0lPQ1RMX05SKERSTV9SQURFT05fQ1BfSURMRSldID0ge3JhZGVvbl9jcF9pZGxlLCBEUk1fQVVUSH0sCglbRFJNX0lPQ1RMX05SKERSTV9SQURFT05fQ1BfUkVTVU1FKV0gPSB7cmFkZW9uX2NwX3Jlc3VtZSwgRFJNX0FVVEh9LAoJW0RSTV9JT0NUTF9OUihEUk1fUkFERU9OX1JFU0VUKV0gPSB7cmFkZW9uX2VuZ2luZV9yZXNldCwgRFJNX0FVVEh9LAoJW0RSTV9JT0NUTF9OUihEUk1fUkFERU9OX0ZVTExTQ1JFRU4pXSA9IHtyYWRlb25fZnVsbHNjcmVlbiwgRFJNX0FVVEh9LAoJW0RSTV9JT0NUTF9OUihEUk1fUkFERU9OX1NXQVApXSA9IHtyYWRlb25fY3Bfc3dhcCwgRFJNX0FVVEh9LAoJW0RSTV9JT0NUTF9OUihEUk1fUkFERU9OX0NMRUFSKV0gPSB7cmFkZW9uX2NwX2NsZWFyLCBEUk1fQVVUSH0sCglbRFJNX0lPQ1RMX05SKERSTV9SQURFT05fVkVSVEVYKV0gPSB7cmFkZW9uX2NwX3ZlcnRleCwgRFJNX0FVVEh9LAoJW0RSTV9JT0NUTF9OUihEUk1fUkFERU9OX0lORElDRVMpXSA9IHtyYWRlb25fY3BfaW5kaWNlcywgRFJNX0FVVEh9LAoJW0RSTV9JT0NUTF9OUihEUk1fUkFERU9OX1RFWFRVUkUpXSA9IHtyYWRlb25fY3BfdGV4dHVyZSwgRFJNX0FVVEh9LAoJW0RSTV9JT0NUTF9OUihEUk1fUkFERU9OX1NUSVBQTEUpXSA9IHtyYWRlb25fY3Bfc3RpcHBsZSwgRFJNX0FVVEh9LAoJW0RSTV9JT0NUTF9OUihEUk1fUkFERU9OX0lORElSRUNUKV0gPSB7cmFkZW9uX2NwX2luZGlyZWN0LCBEUk1fQVVUSHxEUk1fTUFTVEVSfERSTV9ST09UX09OTFl9LAoJW0RSTV9JT0NUTF9OUihEUk1fUkFERU9OX1ZFUlRFWDIpXSA9IHtyYWRlb25fY3BfdmVydGV4MiwgRFJNX0FVVEh9LAoJW0RSTV9JT0NUTF9OUihEUk1fUkFERU9OX0NNREJVRildID0ge3JhZGVvbl9jcF9jbWRidWYsIERSTV9BVVRIfSwKCVtEUk1fSU9DVExfTlIoRFJNX1JBREVPTl9HRVRQQVJBTSldID0ge3JhZGVvbl9jcF9nZXRwYXJhbSwgRFJNX0FVVEh9LAoJW0RSTV9JT0NUTF9OUihEUk1fUkFERU9OX0ZMSVApXSA9IHtyYWRlb25fY3BfZmxpcCwgRFJNX0FVVEh9LAoJW0RSTV9JT0NUTF9OUihEUk1fUkFERU9OX0FMTE9DKV0gPSB7cmFkZW9uX21lbV9hbGxvYywgRFJNX0FVVEh9LAoJW0RSTV9JT0NUTF9OUihEUk1fUkFERU9OX0ZSRUUpXSA9IHtyYWRlb25fbWVtX2ZyZWUsIERSTV9BVVRIfSwKCVtEUk1fSU9DVExfTlIoRFJNX1JBREVPTl9JTklUX0hFQVApXSA9IHtyYWRlb25fbWVtX2luaXRfaGVhcCwgRFJNX0FVVEh8RFJNX01BU1RFUnxEUk1fUk9PVF9PTkxZfSwKCVtEUk1fSU9DVExfTlIoRFJNX1JBREVPTl9JUlFfRU1JVCldID0ge3JhZGVvbl9pcnFfZW1pdCwgRFJNX0FVVEh9LAoJW0RSTV9JT0NUTF9OUihEUk1fUkFERU9OX0lSUV9XQUlUKV0gPSB7cmFkZW9uX2lycV93YWl0LCBEUk1fQVVUSH0sCglbRFJNX0lPQ1RMX05SKERSTV9SQURFT05fU0VUUEFSQU0pXSA9IHtyYWRlb25fY3Bfc2V0cGFyYW0sIERSTV9BVVRIfSwKCVtEUk1fSU9DVExfTlIoRFJNX1JBREVPTl9TVVJGX0FMTE9DKV0gPSB7cmFkZW9uX3N1cmZhY2VfYWxsb2MsIERSTV9BVVRIfSwKCVtEUk1fSU9DVExfTlIoRFJNX1JBREVPTl9TVVJGX0ZSRUUpXSA9IHtyYWRlb25fc3VyZmFjZV9mcmVlLCBEUk1fQVVUSH0KfTsKCmludCByYWRlb25fbWF4X2lvY3RsID0gRFJNX0FSUkFZX1NJWkUocmFkZW9uX2lvY3Rscyk7Cg==