LyogcmFkZW9uX3N0YXRlLmMgLS0gU3RhdGUgc3VwcG9ydCBmb3IgUmFkZW9uIC0qLSBsaW51eC1jIC0qLSAqLwovKgogKiBDb3B5cmlnaHQgMjAwMCBWQSBMaW51eCBTeXN0ZW1zLCBJbmMuLCBGcmVtb250LCBDYWxpZm9ybmlhLgogKiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKgogKiBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYQogKiBjb3B5IG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlICJTb2Z0d2FyZSIpLAogKiB0byBkZWFsIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uCiAqIHRoZSByaWdodHMgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLCBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLAogKiBhbmQvb3Igc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0IHBlcnNvbnMgdG8gd2hvbSB0aGUKICogU29mdHdhcmUgaXMgZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczoKICoKICogVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2UgKGluY2x1ZGluZyB0aGUgbmV4dAogKiBwYXJhZ3JhcGgpIHNoYWxsIGJlIGluY2x1ZGVkIGluIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlCiAqIFNvZnR3YXJlLgogKgogKiBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgIkFTIElTIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTUyBPUgogKiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSwKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gIElOIE5PIEVWRU5UIFNIQUxMCiAqIFBSRUNJU0lPTiBJTlNJR0hUIEFORC9PUiBJVFMgU1VQUExJRVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLCBEQU1BR0VTIE9SCiAqIE9USEVSIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1IgT1RIRVJXSVNFLAogKiBBUklTSU5HIEZST00sIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRSBVU0UgT1IgT1RIRVIKICogREVBTElOR1MgSU4gVEhFIFNPRlRXQVJFLgogKgogKiBBdXRob3JzOgogKiAgICBHYXJldGggSHVnaGVzIDxnYXJldGhAdmFsaW51eC5jb20+CiAqICAgIEtldmluIEUuIE1hcnRpbiA8bWFydGluQHZhbGludXguY29tPgogKi8KCiNpbmNsdWRlICJkcm1QLmgiCiNpbmNsdWRlICJkcm0uaCIKI2luY2x1ZGUgImRybV9zYXJlYS5oIgojaW5jbHVkZSAicmFkZW9uX2RybS5oIgojaW5jbHVkZSAicmFkZW9uX2Rydi5oIgoKLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKiBIZWxwZXIgZnVuY3Rpb25zIGZvciBjbGllbnQgc3RhdGUgY2hlY2tpbmcgYW5kIGZpeHVwCiAqLwoKc3RhdGljIF9faW5saW5lX18gaW50IHJhZGVvbl9jaGVja19hbmRfZml4dXBfb2Zmc2V0KGRybV9yYWRlb25fcHJpdmF0ZV90ICoKCQkJCQkJICAgIGRldl9wcml2LAoJCQkJCQkgICAgc3RydWN0IGRybV9maWxlICogZmlscF9wcml2LAoJCQkJCQkgICAgdTMyICpvZmZzZXQpCnsKCXU2NCBvZmYgPSAqb2Zmc2V0OwoJdTMyIGZiX2VuZCA9IGRldl9wcml2LT5mYl9sb2NhdGlvbiArIGRldl9wcml2LT5mYl9zaXplIC0gMTsKCXN0cnVjdCBkcm1fcmFkZW9uX2RyaXZlcl9maWxlX2ZpZWxkcyAqcmFkZW9uX3ByaXY7CgoJLyogSHJtIC4uLiB0aGUgc3Rvcnkgb2YgdGhlIG9mZnNldCAuLi4gU28gdGhpcyBmdW5jdGlvbiBjb252ZXJ0cwoJICogdGhlIHZhcmlvdXMgaWRlYXMgb2Ygd2hhdCB1c2VybGFuZCBjbGllbnRzIG1pZ2h0IGhhdmUgZm9yIGFuCgkgKiBvZmZzZXQgaW4gdGhlIGNhcmQgYWRkcmVzcyBzcGFjZSBpbnRvIGFuIG9mZnNldCBpbnRvIHRoZSBjYXJkCgkgKiBhZGRyZXNzIHNwYWNlIDopIFNvIHdpdGggYSBzYW5lIGNsaWVudCwgaXQgc2hvdWxkIGp1c3Qga2VlcAoJICogdGhlIHZhbHVlIGludGFjdCBhbmQganVzdCBkbyBzb21lIGJvdW5kYXJ5IGNoZWNraW5nLiBIb3dldmVyLAoJICogbm90IGFsbCBjbGllbnRzIGFyZSBzYW5lLiBTb21lIG9sZGVyIGNsaWVudHMgcGFzcyB1cyAwIGJhc2VkCgkgKiBvZmZzZXRzIHJlbGF0aXZlIHRvIHRoZSBzdGFydCBvZiB0aGUgZnJhbWVidWZmZXIgYW5kIHNvbWUgbWF5CgkgKiBhc3N1bWUgdGhlIEFHUCBhcGVydHVyZSBpdCBhcHBlbmRlZCB0byB0aGUgZnJhbWVidWZmZXIsIHNvIHdlCgkgKiB0cnkgdG8gZGV0ZWN0IHRob3NlIGNhc2VzIGFuZCBmaXggdGhlbSB1cC4KCSAqCgkgKiBOb3RlOiBJdCBtaWdodCBiZSBhIGdvb2QgaWRlYSBoZXJlIHRvIG1ha2Ugc3VyZSB0aGUgb2Zmc2V0IGxhbmRzCgkgKiBpbiBzb21lICJhbGxvd2VkIiBhcmVhIHRvIHByb3RlY3QgdGhpbmdzIGxpa2UgdGhlIFBDSUUgR0FSVC4uLgoJICovCgoJLyogRmlyc3QsIHRoZSBiZXN0IGNhc2UsIHRoZSBvZmZzZXQgYWxyZWFkeSBsYW5kcyBpbiBlaXRoZXIgdGhlCgkgKiBmcmFtZWJ1ZmZlciBvciB0aGUgR0FSVCBtYXBwZWQgc3BhY2UKCSAqLwoJaWYgKHJhZGVvbl9jaGVja19vZmZzZXQoZGV2X3ByaXYsIG9mZikpCgkJcmV0dXJuIDA7CgoJLyogT2ssIHRoYXQgZGlkbid0IGhhcHBlbi4uLiBub3cgY2hlY2sgaWYgd2UgaGF2ZSBhIHplcm8gYmFzZWQKCSAqIG9mZnNldCB0aGF0IGZpdHMgaW4gdGhlIGZyYW1lYnVmZmVyICsgZ2FydCBzcGFjZSwgYXBwbHkgdGhlCgkgKiBtYWdpYyBvZmZzZXQgd2UgZ2V0IGZyb20gU0VUUEFSQU0gb3IgY2FsY3VsYXRlZCBmcm9tIGZiX2xvY2F0aW9uCgkgKi8KCWlmIChvZmYgPCAoZGV2X3ByaXYtPmZiX3NpemUgKyBkZXZfcHJpdi0+Z2FydF9zaXplKSkgewoJCXJhZGVvbl9wcml2ID0gZmlscF9wcml2LT5kcml2ZXJfcHJpdjsKCQlvZmYgKz0gcmFkZW9uX3ByaXYtPnJhZGVvbl9mYl9kZWx0YTsKCX0KCgkvKiBGaW5hbGx5LCBhc3N1bWUgd2UgYWltZWQgYXQgYSBHQVJUIG9mZnNldCBpZiBiZXlvbmQgdGhlIGZiICovCglpZiAob2ZmID4gZmJfZW5kKQoJCW9mZiA9IG9mZiAtIGZiX2VuZCAtIDEgKyBkZXZfcHJpdi0+Z2FydF92bV9zdGFydDsKCgkvKiBOb3cgcmVjaGVjayBhbmQgZmFpbCBpZiBvdXQgb2YgYm91bmRzICovCglpZiAocmFkZW9uX2NoZWNrX29mZnNldChkZXZfcHJpdiwgb2ZmKSkgewoJCURSTV9ERUJVRygib2Zmc2V0IGZpeGVkIHVwIHRvIDB4JXhcbiIsICh1bnNpZ25lZCBpbnQpb2ZmKTsKCQkqb2Zmc2V0ID0gb2ZmOwoJCXJldHVybiAwOwoJfQoJcmV0dXJuIERSTV9FUlIoRUlOVkFMKTsKfQoKc3RhdGljIF9faW5saW5lX18gaW50IHJhZGVvbl9jaGVja19hbmRfZml4dXBfcGFja2V0cyhkcm1fcmFkZW9uX3ByaXZhdGVfdCAqCgkJCQkJCSAgICAgZGV2X3ByaXYsCgkJCQkJCSAgICAgc3RydWN0IGRybV9maWxlICogZmlscF9wcml2LAoJCQkJCQkgICAgIGludCBpZCwgdTMyICpkYXRhKQp7Cglzd2l0Y2ggKGlkKSB7CgoJY2FzZSBSQURFT05fRU1JVF9QUF9NSVNDOgoJCWlmIChyYWRlb25fY2hlY2tfYW5kX2ZpeHVwX29mZnNldChkZXZfcHJpdiwgZmlscF9wcml2LAoJCSAgICAmZGF0YVsoUkFERU9OX1JCM0RfREVQVEhPRkZTRVQgLSBSQURFT05fUFBfTUlTQykgLyA0XSkpIHsKCQkJRFJNX0VSUk9SKCJJbnZhbGlkIGRlcHRoIGJ1ZmZlciBvZmZzZXRcbiIpOwoJCQlyZXR1cm4gRFJNX0VSUihFSU5WQUwpOwoJCX0KCQlicmVhazsKCgljYXNlIFJBREVPTl9FTUlUX1BQX0NOVEw6CgkJaWYgKHJhZGVvbl9jaGVja19hbmRfZml4dXBfb2Zmc2V0KGRldl9wcml2LCBmaWxwX3ByaXYsCgkJICAgICZkYXRhWyhSQURFT05fUkIzRF9DT0xPUk9GRlNFVCAtIFJBREVPTl9QUF9DTlRMKSAvIDRdKSkgewoJCQlEUk1fRVJST1IoIkludmFsaWQgY29sb3VyIGJ1ZmZlciBvZmZzZXRcbiIpOwoJCQlyZXR1cm4gRFJNX0VSUihFSU5WQUwpOwoJCX0KCQlicmVhazsKCgljYXNlIFIyMDBfRU1JVF9QUF9UWE9GRlNFVF8wOgoJY2FzZSBSMjAwX0VNSVRfUFBfVFhPRkZTRVRfMToKCWNhc2UgUjIwMF9FTUlUX1BQX1RYT0ZGU0VUXzI6CgljYXNlIFIyMDBfRU1JVF9QUF9UWE9GRlNFVF8zOgoJY2FzZSBSMjAwX0VNSVRfUFBfVFhPRkZTRVRfNDoKCWNhc2UgUjIwMF9FTUlUX1BQX1RYT0ZGU0VUXzU6CgkJaWYgKHJhZGVvbl9jaGVja19hbmRfZml4dXBfb2Zmc2V0KGRldl9wcml2LCBmaWxwX3ByaXYsCgkJCQkJCSAgJmRhdGFbMF0pKSB7CgkJCURSTV9FUlJPUigiSW52YWxpZCBSMjAwIHRleHR1cmUgb2Zmc2V0XG4iKTsKCQkJcmV0dXJuIERSTV9FUlIoRUlOVkFMKTsKCQl9CgkJYnJlYWs7CgoJY2FzZSBSQURFT05fRU1JVF9QUF9UWEZJTFRFUl8wOgoJY2FzZSBSQURFT05fRU1JVF9QUF9UWEZJTFRFUl8xOgoJY2FzZSBSQURFT05fRU1JVF9QUF9UWEZJTFRFUl8yOgoJCWlmIChyYWRlb25fY2hlY2tfYW5kX2ZpeHVwX29mZnNldChkZXZfcHJpdiwgZmlscF9wcml2LAoJCSAgICAmZGF0YVsoUkFERU9OX1BQX1RYT0ZGU0VUXzAgLSBSQURFT05fUFBfVFhGSUxURVJfMCkgLyA0XSkpIHsKCQkJRFJNX0VSUk9SKCJJbnZhbGlkIFIxMDAgdGV4dHVyZSBvZmZzZXRcbiIpOwoJCQlyZXR1cm4gRFJNX0VSUihFSU5WQUwpOwoJCX0KCQlicmVhazsKCgljYXNlIFIyMDBfRU1JVF9QUF9DVUJJQ19PRkZTRVRTXzA6CgljYXNlIFIyMDBfRU1JVF9QUF9DVUJJQ19PRkZTRVRTXzE6CgljYXNlIFIyMDBfRU1JVF9QUF9DVUJJQ19PRkZTRVRTXzI6CgljYXNlIFIyMDBfRU1JVF9QUF9DVUJJQ19PRkZTRVRTXzM6CgljYXNlIFIyMDBfRU1JVF9QUF9DVUJJQ19PRkZTRVRTXzQ6CgljYXNlIFIyMDBfRU1JVF9QUF9DVUJJQ19PRkZTRVRTXzU6ewoJCQlpbnQgaTsKCQkJZm9yIChpID0gMDsgaSA8IDU7IGkrKykgewoJCQkJaWYgKHJhZGVvbl9jaGVja19hbmRfZml4dXBfb2Zmc2V0KGRldl9wcml2LAoJCQkJCQkJCSAgZmlscF9wcml2LAoJCQkJCQkJCSAgJmRhdGFbaV0pKSB7CgkJCQkJRFJNX0VSUk9SCgkJCQkJICAgICgiSW52YWxpZCBSMjAwIGN1YmljIHRleHR1cmUgb2Zmc2V0XG4iKTsKCQkJCQlyZXR1cm4gRFJNX0VSUihFSU5WQUwpOwoJCQkJfQoJCQl9CgkJCWJyZWFrOwoJCX0KCgljYXNlIFJBREVPTl9FTUlUX1BQX0NVQklDX09GRlNFVFNfVDA6CgljYXNlIFJBREVPTl9FTUlUX1BQX0NVQklDX09GRlNFVFNfVDE6CgljYXNlIFJBREVPTl9FTUlUX1BQX0NVQklDX09GRlNFVFNfVDI6ewoJCQlpbnQgaTsKCQkJZm9yIChpID0gMDsgaSA8IDU7IGkrKykgewoJCQkJaWYgKHJhZGVvbl9jaGVja19hbmRfZml4dXBfb2Zmc2V0KGRldl9wcml2LAoJCQkJCQkJCSAgZmlscF9wcml2LAoJCQkJCQkJCSAgJmRhdGFbaV0pKSB7CgkJCQkJRFJNX0VSUk9SCgkJCQkJICAgICgiSW52YWxpZCBSMTAwIGN1YmljIHRleHR1cmUgb2Zmc2V0XG4iKTsKCQkJCQlyZXR1cm4gRFJNX0VSUihFSU5WQUwpOwoJCQkJfQoJCQl9CgkJfQoJCWJyZWFrOwoKCWNhc2UgUjIwMF9FTUlUX1ZBUF9DVEw6ewoJCQlSSU5HX0xPQ0FMUzsKCQkJQkVHSU5fUklORygyKTsKCQkJT1VUX1JJTkdfUkVHKFJBREVPTl9TRV9UQ0xfU1RBVEVfRkxVU0gsIDApOwoJCQlBRFZBTkNFX1JJTkcoKTsKCQl9CgkJYnJlYWs7CgoJY2FzZSBSQURFT05fRU1JVF9SQjNEX0NPTE9SUElUQ0g6CgljYXNlIFJBREVPTl9FTUlUX1JFX0xJTkVfUEFUVEVSTjoKCWNhc2UgUkFERU9OX0VNSVRfU0VfTElORV9XSURUSDoKCWNhc2UgUkFERU9OX0VNSVRfUFBfTFVNX01BVFJJWDoKCWNhc2UgUkFERU9OX0VNSVRfUFBfUk9UX01BVFJJWF8wOgoJY2FzZSBSQURFT05fRU1JVF9SQjNEX1NURU5DSUxSRUZNQVNLOgoJY2FzZSBSQURFT05fRU1JVF9TRV9WUE9SVF9YU0NBTEU6CgljYXNlIFJBREVPTl9FTUlUX1NFX0NOVEw6CgljYXNlIFJBREVPTl9FTUlUX1NFX0NOVExfU1RBVFVTOgoJY2FzZSBSQURFT05fRU1JVF9SRV9NSVNDOgoJY2FzZSBSQURFT05fRU1JVF9QUF9CT1JERVJfQ09MT1JfMDoKCWNhc2UgUkFERU9OX0VNSVRfUFBfQk9SREVSX0NPTE9SXzE6CgljYXNlIFJBREVPTl9FTUlUX1BQX0JPUkRFUl9DT0xPUl8yOgoJY2FzZSBSQURFT05fRU1JVF9TRV9aQklBU19GQUNUT1I6CgljYXNlIFJBREVPTl9FTUlUX1NFX1RDTF9PVVRQVVRfVlRYX0ZNVDoKCWNhc2UgUkFERU9OX0VNSVRfU0VfVENMX01BVEVSSUFMX0VNTUlTU0lWRV9SRUQ6CgljYXNlIFIyMDBfRU1JVF9QUF9UWENCTEVORF8wOgoJY2FzZSBSMjAwX0VNSVRfUFBfVFhDQkxFTkRfMToKCWNhc2UgUjIwMF9FTUlUX1BQX1RYQ0JMRU5EXzI6CgljYXNlIFIyMDBfRU1JVF9QUF9UWENCTEVORF8zOgoJY2FzZSBSMjAwX0VNSVRfUFBfVFhDQkxFTkRfNDoKCWNhc2UgUjIwMF9FTUlUX1BQX1RYQ0JMRU5EXzU6CgljYXNlIFIyMDBfRU1JVF9QUF9UWENCTEVORF82OgoJY2FzZSBSMjAwX0VNSVRfUFBfVFhDQkxFTkRfNzoKCWNhc2UgUjIwMF9FTUlUX1RDTF9MSUdIVF9NT0RFTF9DVExfMDoKCWNhc2UgUjIwMF9FTUlUX1RGQUNUT1JfMDoKCWNhc2UgUjIwMF9FTUlUX1ZUWF9GTVRfMDoKCWNhc2UgUjIwMF9FTUlUX01BVFJJWF9TRUxFQ1RfMDoKCWNhc2UgUjIwMF9FTUlUX1RFWF9QUk9DX0NUTF8yOgoJY2FzZSBSMjAwX0VNSVRfVENMX1VDUF9WRVJUX0JMRU5EX0NUTDoKCWNhc2UgUjIwMF9FTUlUX1BQX1RYRklMVEVSXzA6CgljYXNlIFIyMDBfRU1JVF9QUF9UWEZJTFRFUl8xOgoJY2FzZSBSMjAwX0VNSVRfUFBfVFhGSUxURVJfMjoKCWNhc2UgUjIwMF9FTUlUX1BQX1RYRklMVEVSXzM6CgljYXNlIFIyMDBfRU1JVF9QUF9UWEZJTFRFUl80OgoJY2FzZSBSMjAwX0VNSVRfUFBfVFhGSUxURVJfNToKCWNhc2UgUjIwMF9FTUlUX1ZURV9DTlRMOgoJY2FzZSBSMjAwX0VNSVRfT1VUUFVUX1ZUWF9DT01QX1NFTDoKCWNhc2UgUjIwMF9FTUlUX1BQX1RBTV9ERUJVRzM6CgljYXNlIFIyMDBfRU1JVF9QUF9DTlRMX1g6CgljYXNlIFIyMDBfRU1JVF9SQjNEX0RFUFRIWFlfT0ZGU0VUOgoJY2FzZSBSMjAwX0VNSVRfUkVfQVVYX1NDSVNTT1JfQ05UTDoKCWNhc2UgUjIwMF9FTUlUX1JFX1NDSVNTT1JfVExfMDoKCWNhc2UgUjIwMF9FTUlUX1JFX1NDSVNTT1JfVExfMToKCWNhc2UgUjIwMF9FTUlUX1JFX1NDSVNTT1JfVExfMjoKCWNhc2UgUjIwMF9FTUlUX1NFX1ZBUF9DTlRMX1NUQVRVUzoKCWNhc2UgUjIwMF9FTUlUX1NFX1ZUWF9TVEFURV9DTlRMOgoJY2FzZSBSMjAwX0VNSVRfUkVfUE9JTlRTSVpFOgoJY2FzZSBSMjAwX0VNSVRfVENMX0lOUFVUX1ZUWF9WRUNUT1JfQUREUl8wOgoJY2FzZSBSMjAwX0VNSVRfUFBfQ1VCSUNfRkFDRVNfMDoKCWNhc2UgUjIwMF9FTUlUX1BQX0NVQklDX0ZBQ0VTXzE6CgljYXNlIFIyMDBfRU1JVF9QUF9DVUJJQ19GQUNFU18yOgoJY2FzZSBSMjAwX0VNSVRfUFBfQ1VCSUNfRkFDRVNfMzoKCWNhc2UgUjIwMF9FTUlUX1BQX0NVQklDX0ZBQ0VTXzQ6CgljYXNlIFIyMDBfRU1JVF9QUF9DVUJJQ19GQUNFU181OgoJY2FzZSBSQURFT05fRU1JVF9QUF9URVhfU0laRV8wOgoJY2FzZSBSQURFT05fRU1JVF9QUF9URVhfU0laRV8xOgoJY2FzZSBSQURFT05fRU1JVF9QUF9URVhfU0laRV8yOgoJY2FzZSBSMjAwX0VNSVRfUkIzRF9CTEVORENPTE9SOgoJY2FzZSBSMjAwX0VNSVRfVENMX1BPSU5UX1NQUklURV9DTlRMOgoJY2FzZSBSQURFT05fRU1JVF9QUF9DVUJJQ19GQUNFU18wOgoJY2FzZSBSQURFT05fRU1JVF9QUF9DVUJJQ19GQUNFU18xOgoJY2FzZSBSQURFT05fRU1JVF9QUF9DVUJJQ19GQUNFU18yOgoJY2FzZSBSMjAwX0VNSVRfUFBfVFJJX1BFUkZfQ05UTDoKCWNhc2UgUjIwMF9FTUlUX1BQX0FGU18wOgoJY2FzZSBSMjAwX0VNSVRfUFBfQUZTXzE6CgljYXNlIFIyMDBfRU1JVF9BVEZfVEZBQ1RPUjoKCWNhc2UgUjIwMF9FTUlUX1BQX1RYQ1RMQUxMXzA6CgljYXNlIFIyMDBfRU1JVF9QUF9UWENUTEFMTF8xOgoJY2FzZSBSMjAwX0VNSVRfUFBfVFhDVExBTExfMjoKCWNhc2UgUjIwMF9FTUlUX1BQX1RYQ1RMQUxMXzM6CgljYXNlIFIyMDBfRU1JVF9QUF9UWENUTEFMTF80OgoJY2FzZSBSMjAwX0VNSVRfUFBfVFhDVExBTExfNToKCWNhc2UgUjIwMF9FTUlUX1ZBUF9QVlNfQ05UTDoKCQkvKiBUaGVzZSBwYWNrZXRzIGRvbid0IGNvbnRhaW4gbWVtb3J5IG9mZnNldHMgKi8KCQlicmVhazsKCglkZWZhdWx0OgoJCURSTV9FUlJPUigiVW5rbm93biBzdGF0ZSBwYWNrZXQgSUQgJWRcbiIsIGlkKTsKCQlyZXR1cm4gRFJNX0VSUihFSU5WQUwpOwoJfQoKCXJldHVybiAwOwp9CgpzdGF0aWMgX19pbmxpbmVfXyBpbnQgcmFkZW9uX2NoZWNrX2FuZF9maXh1cF9wYWNrZXQzKGRybV9yYWRlb25fcHJpdmF0ZV90ICoKCQkJCQkJICAgICBkZXZfcHJpdiwKCQkJCQkJICAgICBzdHJ1Y3QgZHJtX2ZpbGUgKmZpbHBfcHJpdiwKCQkJCQkJICAgICBkcm1fcmFkZW9uX2tjbWRfYnVmZmVyX3QgKgoJCQkJCQkgICAgIGNtZGJ1ZiwKCQkJCQkJICAgICB1bnNpZ25lZCBpbnQgKmNtZHN6KQp7Cgl1MzIgKmNtZCA9ICh1MzIgKikgY21kYnVmLT5idWY7Cgl1MzIgb2Zmc2V0LCBuYXJyYXlzOwoJaW50IGNvdW50LCBpLCBrOwoKCSpjbWRzeiA9IDIgKyAoKGNtZFswXSAmIFJBREVPTl9DUF9QQUNLRVRfQ09VTlRfTUFTSykgPj4gMTYpOwoKCWlmICgoY21kWzBdICYgMHhjMDAwMDAwMCkgIT0gUkFERU9OX0NQX1BBQ0tFVDMpIHsKCQlEUk1fRVJST1IoIk5vdCBhIHR5cGUgMyBwYWNrZXRcbiIpOwoJCXJldHVybiBEUk1fRVJSKEVJTlZBTCk7Cgl9CgoJaWYgKDQgKiAqY21kc3ogPiBjbWRidWYtPmJ1ZnN6KSB7CgkJRFJNX0VSUk9SKCJQYWNrZXQgc2l6ZSBsYXJnZXIgdGhhbiBzaXplIG9mIGRhdGEgcHJvdmlkZWRcbiIpOwoJCXJldHVybiBEUk1fRVJSKEVJTlZBTCk7Cgl9CgoJc3dpdGNoKGNtZFswXSAmIDB4ZmYwMCkgewoJLyogWFhYIEFyZSB0aGVyZSBvbGQgZHJpdmVycyBuZWVkaW5nIG90aGVyIHBhY2tldHM/ICovCgoJY2FzZSBSQURFT05fM0RfRFJBV19JTU1EOgoJY2FzZSBSQURFT05fM0RfRFJBV19WQlVGOgoJY2FzZSBSQURFT05fM0RfRFJBV19JTkRYOgoJY2FzZSBSQURFT05fV0FJVF9GT1JfSURMRToKCWNhc2UgUkFERU9OX0NQX05PUDoKCWNhc2UgUkFERU9OXzNEX0NMRUFSX1pNQVNLOgovKgljYXNlIFJBREVPTl9DUF9ORVhUX0NIQVI6CgljYXNlIFJBREVPTl9DUF9QTFlfTkVYVFNDQU46CgljYXNlIFJBREVPTl9DUF9TRVRfU0NJU1NPUlM6ICovIC8qIHByb2JhYmx5IHNhZmUgYnV0IHdpbGwgbmV2ZXIgbmVlZCB0aGVtPyAqLwoJCS8qIHRoZXNlIHBhY2tldHMgYXJlIHNhZmUgKi8KCQlicmVhazsKCgljYXNlIFJBREVPTl9DUF8zRF9EUkFXX0lNTURfMjoKCWNhc2UgUkFERU9OX0NQXzNEX0RSQVdfVkJVRl8yOgoJY2FzZSBSQURFT05fQ1BfM0RfRFJBV19JTkRYXzI6CgljYXNlIFJBREVPTl8zRF9DTEVBUl9ISVo6CgkJLyogc2FmZSBidXQgcjIwMCBvbmx5ICovCgkJaWYgKGRldl9wcml2LT5taWNyb2NvZGVfdmVyc2lvbiAhPSBVQ09ERV9SMjAwKSB7CgkJCURSTV9FUlJPUigiSW52YWxpZCAzZCBwYWNrZXQgZm9yIHIxMDAtY2xhc3MgY2hpcFxuIik7CgkJCXJldHVybiBEUk1fRVJSKEVJTlZBTCk7CgkJfQoJCWJyZWFrOwoKCWNhc2UgUkFERU9OXzNEX0xPQURfVkJQTlRSOgoJCWNvdW50ID0gKGNtZFswXSA+PiAxNikgJiAweDNmZmY7CgoJCWlmIChjb3VudCA+IDE4KSB7IC8qIDEyIGFycmF5cyBtYXggKi8KCQkJRFJNX0VSUk9SKCJUb28gbGFyZ2UgcGF5bG9hZCBpbiAzRF9MT0FEX1ZCUE5UUiAoY291bnQ9JWQpXG4iLAoJCQkJICBjb3VudCk7CgkJCXJldHVybiBEUk1fRVJSKEVJTlZBTCk7CgkJfQoKCQkvKiBjYXJlZnVsbHkgY2hlY2sgcGFja2V0IGNvbnRlbnRzICovCgkJbmFycmF5cyA9IGNtZFsxXSAmIH4weGMwMDA7CgkJayA9IDA7CgkJaSA9IDI7CgkJd2hpbGUgKChrIDwgbmFycmF5cykgJiYgKGkgPCAoY291bnQgKyAyKSkpIHsKCQkJaSsrOwkJLyogc2tpcCBhdHRyaWJ1dGUgZmllbGQgKi8KCQkJaWYgKHJhZGVvbl9jaGVja19hbmRfZml4dXBfb2Zmc2V0KGRldl9wcml2LCBmaWxwX3ByaXYsICZjbWRbaV0pKSB7CgkJCQlEUk1fRVJST1IKCQkJCSAgICAoIkludmFsaWQgb2Zmc2V0IChrPSVkIGk9JWQpIGluIDNEX0xPQURfVkJQTlRSIHBhY2tldC5cbiIsCgkJCQkgICAgIGssIGkpOwoJCQkJcmV0dXJuIERSTV9FUlIoRUlOVkFMKTsKCQkJfQoJCQlrKys7CgkJCWkrKzsKCQkJaWYgKGsgPT0gbmFycmF5cykKCQkJCWJyZWFrOwoJCQkvKiBoYXZlIG9uZSBtb3JlIHRvIHByb2Nlc3MsIHRoZXkgY29tZSBpbiBwYWlycyAqLwoJCQlpZiAocmFkZW9uX2NoZWNrX2FuZF9maXh1cF9vZmZzZXQoZGV2X3ByaXYsIGZpbHBfcHJpdiwgJmNtZFtpXSkpIHsKCQkJCURSTV9FUlJPUgoJCQkJICAgICgiSW52YWxpZCBvZmZzZXQgKGs9JWQgaT0lZCkgaW4gM0RfTE9BRF9WQlBOVFIgcGFja2V0LlxuIiwKCQkJCSAgICAgaywgaSk7CgkJCQlyZXR1cm4gRFJNX0VSUihFSU5WQUwpOwoJCQl9CgkJCWsrKzsKCQkJaSsrOwoJCX0KCQkvKiBkbyB0aGUgY291bnRzIG1hdGNoIHdoYXQgd2UgZXhwZWN0ID8gKi8KCQlpZiAoKGsgIT0gbmFycmF5cykgfHwgKGkgIT0gKGNvdW50ICsgMikpKSB7CgkJCURSTV9FUlJPUgoJCQkgICAgKCJNYWxmb3JtZWQgM0RfTE9BRF9WQlBOVFIgcGFja2V0IChrPSVkIGk9JWQgbmFycmF5cz0lZCBjb3VudCsxPSVkKS5cbiIsCgkJCSAgICAgIGssIGksIG5hcnJheXMsIGNvdW50ICsgMSk7CgkJCXJldHVybiBEUk1fRVJSKEVJTlZBTCk7CgkJfQoJCWJyZWFrOwoKCWNhc2UgUkFERU9OXzNEX1JORFJfR0VOX0lORFhfUFJJTToKCQlpZiAoZGV2X3ByaXYtPm1pY3JvY29kZV92ZXJzaW9uICE9IFVDT0RFX1IxMDApIHsKCQkJRFJNX0VSUk9SKCJJbnZhbGlkIDNkIHBhY2tldCBmb3IgcjIwMC1jbGFzcyBjaGlwXG4iKTsKCQkJcmV0dXJuIERSTV9FUlIoRUlOVkFMKTsKCQl9CgkJaWYgKHJhZGVvbl9jaGVja19hbmRfZml4dXBfb2Zmc2V0KGRldl9wcml2LCBmaWxwX3ByaXYsICZjbWRbMV0pKSB7CgkJCQlEUk1fRVJST1IoIkludmFsaWQgcm5kcl9nZW5faW5keCBvZmZzZXRcbiIpOwoJCQkJcmV0dXJuIERSTV9FUlIoRUlOVkFMKTsKCQl9CgkJYnJlYWs7CgoJY2FzZSBSQURFT05fQ1BfSU5EWF9CVUZGRVI6CgkJaWYgKGRldl9wcml2LT5taWNyb2NvZGVfdmVyc2lvbiAhPSBVQ09ERV9SMjAwKSB7CgkJCURSTV9FUlJPUigiSW52YWxpZCAzZCBwYWNrZXQgZm9yIHIxMDAtY2xhc3MgY2hpcFxuIik7CgkJCXJldHVybiBEUk1fRVJSKEVJTlZBTCk7CgkJfQoJCWlmICgoY21kWzFdICYgMHg4MDAwZmZmZikgIT0gMHg4MDAwMDgxMCkgewoJCQlEUk1fRVJST1IoIkludmFsaWQgaW5keF9idWZmZXIgcmVnIGFkZHJlc3MgJTA4WFxuIiwgY21kWzFdKTsKCQkJcmV0dXJuIERSTV9FUlIoRUlOVkFMKTsKCQl9CgkJaWYgKHJhZGVvbl9jaGVja19hbmRfZml4dXBfb2Zmc2V0KGRldl9wcml2LCBmaWxwX3ByaXYsICZjbWRbMl0pKSB7CgkJCURSTV9FUlJPUigiSW52YWxpZCBpbmR4X2J1ZmZlciBvZmZzZXQgaXMgJTA4WFxuIiwgY21kWzJdKTsKCQkJcmV0dXJuIERSTV9FUlIoRUlOVkFMKTsKCQl9CgkJYnJlYWs7CgoJY2FzZSBSQURFT05fQ05UTF9IT1NUREFUQV9CTFQ6CgljYXNlIFJBREVPTl9DTlRMX1BBSU5UX01VTFRJOgoJY2FzZSBSQURFT05fQ05UTF9CSVRCTFRfTVVMVEk6CgkJLyogTVNCIG9mIG9wY29kZTogbmV4dCBEV09SRCBHVUlfQ05UTCAqLwoJCWlmIChjbWRbMV0gJiAoUkFERU9OX0dNQ19TUkNfUElUQ0hfT0ZGU0VUX0NOVEwKCQkJICAgICAgfCBSQURFT05fR01DX0RTVF9QSVRDSF9PRkZTRVRfQ05UTCkpIHsKCQkJb2Zmc2V0ID0gY21kWzJdIDw8IDEwOwoJCQlpZiAocmFkZW9uX2NoZWNrX2FuZF9maXh1cF9vZmZzZXQKCQkJICAgIChkZXZfcHJpdiwgZmlscF9wcml2LCAmb2Zmc2V0KSkgewoJCQkJRFJNX0VSUk9SKCJJbnZhbGlkIGZpcnN0IHBhY2tldCBvZmZzZXRcbiIpOwoJCQkJcmV0dXJuIERSTV9FUlIoRUlOVkFMKTsKCQkJfQoJCQljbWRbMl0gPSAoY21kWzJdICYgMHhmZmMwMDAwMCkgfCBvZmZzZXQgPj4gMTA7CgkJfQoKCQlpZiAoKGNtZFsxXSAmIFJBREVPTl9HTUNfU1JDX1BJVENIX09GRlNFVF9DTlRMKSAmJgoJCSAgICAoY21kWzFdICYgUkFERU9OX0dNQ19EU1RfUElUQ0hfT0ZGU0VUX0NOVEwpKSB7CgkJCW9mZnNldCA9IGNtZFszXSA8PCAxMDsKCQkJaWYgKHJhZGVvbl9jaGVja19hbmRfZml4dXBfb2Zmc2V0CgkJCSAgICAoZGV2X3ByaXYsIGZpbHBfcHJpdiwgJm9mZnNldCkpIHsKCQkJCURSTV9FUlJPUigiSW52YWxpZCBzZWNvbmQgcGFja2V0IG9mZnNldFxuIik7CgkJCQlyZXR1cm4gRFJNX0VSUihFSU5WQUwpOwoJCQl9CgkJCWNtZFszXSA9IChjbWRbM10gJiAweGZmYzAwMDAwKSB8IG9mZnNldCA+PiAxMDsKCQl9CgkJYnJlYWs7CgoJZGVmYXVsdDoKCQlEUk1fRVJST1IoIkludmFsaWQgcGFja2V0IHR5cGUgJXhcbiIsIGNtZFswXSAmIDB4ZmYwMCk7CgkJcmV0dXJuIERSTV9FUlIoRUlOVkFMKTsKCX0KCglyZXR1cm4gMDsKfQoKLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKiBDUCBoYXJkd2FyZSBzdGF0ZSBwcm9ncmFtbWluZyBmdW5jdGlvbnMKICovCgpzdGF0aWMgX19pbmxpbmVfXyB2b2lkIHJhZGVvbl9lbWl0X2NsaXBfcmVjdChkcm1fcmFkZW9uX3ByaXZhdGVfdCAqIGRldl9wcml2LAoJCQkJCSAgICAgc3RydWN0IGRybV9jbGlwX3JlY3QgKiBib3gpCnsKCVJJTkdfTE9DQUxTOwoKCURSTV9ERUJVRygiICAgYm94OiAgeDE9JWQgeTE9JWQgIHgyPSVkIHkyPSVkXG4iLAoJCSAgYm94LT54MSwgYm94LT55MSwgYm94LT54MiwgYm94LT55Mik7CgoJQkVHSU5fUklORyg0KTsKCU9VVF9SSU5HKENQX1BBQ0tFVDAoUkFERU9OX1JFX1RPUF9MRUZULCAwKSk7CglPVVRfUklORygoYm94LT55MSA8PCAxNikgfCBib3gtPngxKTsKCU9VVF9SSU5HKENQX1BBQ0tFVDAoUkFERU9OX1JFX1dJRFRIX0hFSUdIVCwgMCkpOwoJT1VUX1JJTkcoKChib3gtPnkyIC0gMSkgPDwgMTYpIHwgKGJveC0+eDIgLSAxKSk7CglBRFZBTkNFX1JJTkcoKTsKfQoKLyogRW1pdCAxLjEgc3RhdGUKICovCnN0YXRpYyBpbnQgcmFkZW9uX2VtaXRfc3RhdGUoZHJtX3JhZGVvbl9wcml2YXRlX3QgKiBkZXZfcHJpdiwKCQkJICAgICBzdHJ1Y3QgZHJtX2ZpbGUgKiBmaWxwX3ByaXYsCgkJCSAgICAgZHJtX3JhZGVvbl9jb250ZXh0X3JlZ3NfdCAqIGN0eCwKCQkJICAgICBkcm1fcmFkZW9uX3RleHR1cmVfcmVnc190ICogdGV4LAoJCQkgICAgIHVuc2lnbmVkIGludCBkaXJ0eSkKewoJUklOR19MT0NBTFM7CglEUk1fREVCVUcoImRpcnR5PTB4JTA4eFxuIiwgZGlydHkpOwoKCWlmIChkaXJ0eSAmIFJBREVPTl9VUExPQURfQ09OVEVYVCkgewoJCWlmIChyYWRlb25fY2hlY2tfYW5kX2ZpeHVwX29mZnNldChkZXZfcHJpdiwgZmlscF9wcml2LAoJCQkJCQkgICZjdHgtPnJiM2RfZGVwdGhvZmZzZXQpKSB7CgkJCURSTV9FUlJPUigiSW52YWxpZCBkZXB0aCBidWZmZXIgb2Zmc2V0XG4iKTsKCQkJcmV0dXJuIERSTV9FUlIoRUlOVkFMKTsKCQl9CgoJCWlmIChyYWRlb25fY2hlY2tfYW5kX2ZpeHVwX29mZnNldChkZXZfcHJpdiwgZmlscF9wcml2LAoJCQkJCQkgICZjdHgtPnJiM2RfY29sb3JvZmZzZXQpKSB7CgkJCURSTV9FUlJPUigiSW52YWxpZCBkZXB0aCBidWZmZXIgb2Zmc2V0XG4iKTsKCQkJcmV0dXJuIERSTV9FUlIoRUlOVkFMKTsKCQl9CgoJCUJFR0lOX1JJTkcoMTQpOwoJCU9VVF9SSU5HKENQX1BBQ0tFVDAoUkFERU9OX1BQX01JU0MsIDYpKTsKCQlPVVRfUklORyhjdHgtPnBwX21pc2MpOwoJCU9VVF9SSU5HKGN0eC0+cHBfZm9nX2NvbG9yKTsKCQlPVVRfUklORyhjdHgtPnJlX3NvbGlkX2NvbG9yKTsKCQlPVVRfUklORyhjdHgtPnJiM2RfYmxlbmRjbnRsKTsKCQlPVVRfUklORyhjdHgtPnJiM2RfZGVwdGhvZmZzZXQpOwoJCU9VVF9SSU5HKGN0eC0+cmIzZF9kZXB0aHBpdGNoKTsKCQlPVVRfUklORyhjdHgtPnJiM2RfenN0ZW5jaWxjbnRsKTsKCQlPVVRfUklORyhDUF9QQUNLRVQwKFJBREVPTl9QUF9DTlRMLCAyKSk7CgkJT1VUX1JJTkcoY3R4LT5wcF9jbnRsKTsKCQlPVVRfUklORyhjdHgtPnJiM2RfY250bCk7CgkJT1VUX1JJTkcoY3R4LT5yYjNkX2NvbG9yb2Zmc2V0KTsKCQlPVVRfUklORyhDUF9QQUNLRVQwKFJBREVPTl9SQjNEX0NPTE9SUElUQ0gsIDApKTsKCQlPVVRfUklORyhjdHgtPnJiM2RfY29sb3JwaXRjaCk7CgkJQURWQU5DRV9SSU5HKCk7Cgl9CgoJaWYgKGRpcnR5ICYgUkFERU9OX1VQTE9BRF9WRVJURk1UKSB7CgkJQkVHSU5fUklORygyKTsKCQlPVVRfUklORyhDUF9QQUNLRVQwKFJBREVPTl9TRV9DT09SRF9GTVQsIDApKTsKCQlPVVRfUklORyhjdHgtPnNlX2Nvb3JkX2ZtdCk7CgkJQURWQU5DRV9SSU5HKCk7Cgl9CgoJaWYgKGRpcnR5ICYgUkFERU9OX1VQTE9BRF9MSU5FKSB7CgkJQkVHSU5fUklORyg1KTsKCQlPVVRfUklORyhDUF9QQUNLRVQwKFJBREVPTl9SRV9MSU5FX1BBVFRFUk4sIDEpKTsKCQlPVVRfUklORyhjdHgtPnJlX2xpbmVfcGF0dGVybik7CgkJT1VUX1JJTkcoY3R4LT5yZV9saW5lX3N0YXRlKTsKCQlPVVRfUklORyhDUF9QQUNLRVQwKFJBREVPTl9TRV9MSU5FX1dJRFRILCAwKSk7CgkJT1VUX1JJTkcoY3R4LT5zZV9saW5lX3dpZHRoKTsKCQlBRFZBTkNFX1JJTkcoKTsKCX0KCglpZiAoZGlydHkgJiBSQURFT05fVVBMT0FEX0JVTVBNQVApIHsKCQlCRUdJTl9SSU5HKDUpOwoJCU9VVF9SSU5HKENQX1BBQ0tFVDAoUkFERU9OX1BQX0xVTV9NQVRSSVgsIDApKTsKCQlPVVRfUklORyhjdHgtPnBwX2x1bV9tYXRyaXgpOwoJCU9VVF9SSU5HKENQX1BBQ0tFVDAoUkFERU9OX1BQX1JPVF9NQVRSSVhfMCwgMSkpOwoJCU9VVF9SSU5HKGN0eC0+cHBfcm90X21hdHJpeF8wKTsKCQlPVVRfUklORyhjdHgtPnBwX3JvdF9tYXRyaXhfMSk7CgkJQURWQU5DRV9SSU5HKCk7Cgl9CgoJaWYgKGRpcnR5ICYgUkFERU9OX1VQTE9BRF9NQVNLUykgewoJCUJFR0lOX1JJTkcoNCk7CgkJT1VUX1JJTkcoQ1BfUEFDS0VUMChSQURFT05fUkIzRF9TVEVOQ0lMUkVGTUFTSywgMikpOwoJCU9VVF9SSU5HKGN0eC0+cmIzZF9zdGVuY2lscmVmbWFzayk7CgkJT1VUX1JJTkcoY3R4LT5yYjNkX3JvcGNudGwpOwoJCU9VVF9SSU5HKGN0eC0+cmIzZF9wbGFuZW1hc2spOwoJCUFEVkFOQ0VfUklORygpOwoJfQoKCWlmIChkaXJ0eSAmIFJBREVPTl9VUExPQURfVklFV1BPUlQpIHsKCQlCRUdJTl9SSU5HKDcpOwoJCU9VVF9SSU5HKENQX1BBQ0tFVDAoUkFERU9OX1NFX1ZQT1JUX1hTQ0FMRSwgNSkpOwoJCU9VVF9SSU5HKGN0eC0+c2VfdnBvcnRfeHNjYWxlKTsKCQlPVVRfUklORyhjdHgtPnNlX3Zwb3J0X3hvZmZzZXQpOwoJCU9VVF9SSU5HKGN0eC0+c2VfdnBvcnRfeXNjYWxlKTsKCQlPVVRfUklORyhjdHgtPnNlX3Zwb3J0X3lvZmZzZXQpOwoJCU9VVF9SSU5HKGN0eC0+c2VfdnBvcnRfenNjYWxlKTsKCQlPVVRfUklORyhjdHgtPnNlX3Zwb3J0X3pvZmZzZXQpOwoJCUFEVkFOQ0VfUklORygpOwoJfQoKCWlmIChkaXJ0eSAmIFJBREVPTl9VUExPQURfU0VUVVApIHsKCQlCRUdJTl9SSU5HKDQpOwoJCU9VVF9SSU5HKENQX1BBQ0tFVDAoUkFERU9OX1NFX0NOVEwsIDApKTsKCQlPVVRfUklORyhjdHgtPnNlX2NudGwpOwoJCU9VVF9SSU5HKENQX1BBQ0tFVDAoUkFERU9OX1NFX0NOVExfU1RBVFVTLCAwKSk7CgkJT1VUX1JJTkcoY3R4LT5zZV9jbnRsX3N0YXR1cyk7CgkJQURWQU5DRV9SSU5HKCk7Cgl9CgoJaWYgKGRpcnR5ICYgUkFERU9OX1VQTE9BRF9NSVNDKSB7CgkJQkVHSU5fUklORygyKTsKCQlPVVRfUklORyhDUF9QQUNLRVQwKFJBREVPTl9SRV9NSVNDLCAwKSk7CgkJT1VUX1JJTkcoY3R4LT5yZV9taXNjKTsKCQlBRFZBTkNFX1JJTkcoKTsKCX0KCglpZiAoZGlydHkgJiBSQURFT05fVVBMT0FEX1RFWDApIHsKCQlpZiAocmFkZW9uX2NoZWNrX2FuZF9maXh1cF9vZmZzZXQoZGV2X3ByaXYsIGZpbHBfcHJpdiwKCQkJCQkJICAmdGV4WzBdLnBwX3R4b2Zmc2V0KSkgewoJCQlEUk1fRVJST1IoIkludmFsaWQgdGV4dHVyZSBvZmZzZXQgZm9yIHVuaXQgMFxuIik7CgkJCXJldHVybiBEUk1fRVJSKEVJTlZBTCk7CgkJfQoKCQlCRUdJTl9SSU5HKDkpOwoJCU9VVF9SSU5HKENQX1BBQ0tFVDAoUkFERU9OX1BQX1RYRklMVEVSXzAsIDUpKTsKCQlPVVRfUklORyh0ZXhbMF0ucHBfdHhmaWx0ZXIpOwoJCU9VVF9SSU5HKHRleFswXS5wcF90eGZvcm1hdCk7CgkJT1VUX1JJTkcodGV4WzBdLnBwX3R4b2Zmc2V0KTsKCQlPVVRfUklORyh0ZXhbMF0ucHBfdHhjYmxlbmQpOwoJCU9VVF9SSU5HKHRleFswXS5wcF90eGFibGVuZCk7CgkJT1VUX1JJTkcodGV4WzBdLnBwX3RmYWN0b3IpOwoJCU9VVF9SSU5HKENQX1BBQ0tFVDAoUkFERU9OX1BQX0JPUkRFUl9DT0xPUl8wLCAwKSk7CgkJT1VUX1JJTkcodGV4WzBdLnBwX2JvcmRlcl9jb2xvcik7CgkJQURWQU5DRV9SSU5HKCk7Cgl9CgoJaWYgKGRpcnR5ICYgUkFERU9OX1VQTE9BRF9URVgxKSB7CgkJaWYgKHJhZGVvbl9jaGVja19hbmRfZml4dXBfb2Zmc2V0KGRldl9wcml2LCBmaWxwX3ByaXYsCgkJCQkJCSAgJnRleFsxXS5wcF90eG9mZnNldCkpIHsKCQkJRFJNX0VSUk9SKCJJbnZhbGlkIHRleHR1cmUgb2Zmc2V0IGZvciB1bml0IDFcbiIpOwoJCQlyZXR1cm4gRFJNX0VSUihFSU5WQUwpOwoJCX0KCgkJQkVHSU5fUklORyg5KTsKCQlPVVRfUklORyhDUF9QQUNLRVQwKFJBREVPTl9QUF9UWEZJTFRFUl8xLCA1KSk7CgkJT1VUX1JJTkcodGV4WzFdLnBwX3R4ZmlsdGVyKTsKCQlPVVRfUklORyh0ZXhbMV0ucHBfdHhmb3JtYXQpOwoJCU9VVF9SSU5HKHRleFsxXS5wcF90eG9mZnNldCk7CgkJT1VUX1JJTkcodGV4WzFdLnBwX3R4Y2JsZW5kKTsKCQlPVVRfUklORyh0ZXhbMV0ucHBfdHhhYmxlbmQpOwoJCU9VVF9SSU5HKHRleFsxXS5wcF90ZmFjdG9yKTsKCQlPVVRfUklORyhDUF9QQUNLRVQwKFJBREVPTl9QUF9CT1JERVJfQ09MT1JfMSwgMCkpOwoJCU9VVF9SSU5HKHRleFsxXS5wcF9ib3JkZXJfY29sb3IpOwoJCUFEVkFOQ0VfUklORygpOwoJfQoKCWlmIChkaXJ0eSAmIFJBREVPTl9VUExPQURfVEVYMikgewoJCWlmIChyYWRlb25fY2hlY2tfYW5kX2ZpeHVwX29mZnNldChkZXZfcHJpdiwgZmlscF9wcml2LAoJCQkJCQkgICZ0ZXhbMl0ucHBfdHhvZmZzZXQpKSB7CgkJCURSTV9FUlJPUigiSW52YWxpZCB0ZXh0dXJlIG9mZnNldCBmb3IgdW5pdCAyXG4iKTsKCQkJcmV0dXJuIERSTV9FUlIoRUlOVkFMKTsKCQl9CgoJCUJFR0lOX1JJTkcoOSk7CgkJT1VUX1JJTkcoQ1BfUEFDS0VUMChSQURFT05fUFBfVFhGSUxURVJfMiwgNSkpOwoJCU9VVF9SSU5HKHRleFsyXS5wcF90eGZpbHRlcik7CgkJT1VUX1JJTkcodGV4WzJdLnBwX3R4Zm9ybWF0KTsKCQlPVVRfUklORyh0ZXhbMl0ucHBfdHhvZmZzZXQpOwoJCU9VVF9SSU5HKHRleFsyXS5wcF90eGNibGVuZCk7CgkJT1VUX1JJTkcodGV4WzJdLnBwX3R4YWJsZW5kKTsKCQlPVVRfUklORyh0ZXhbMl0ucHBfdGZhY3Rvcik7CgkJT1VUX1JJTkcoQ1BfUEFDS0VUMChSQURFT05fUFBfQk9SREVSX0NPTE9SXzIsIDApKTsKCQlPVVRfUklORyh0ZXhbMl0ucHBfYm9yZGVyX2NvbG9yKTsKCQlBRFZBTkNFX1JJTkcoKTsKCX0KCglyZXR1cm4gMDsKfQoKLyogRW1pdCAxLjIgc3RhdGUKICovCnN0YXRpYyBpbnQgcmFkZW9uX2VtaXRfc3RhdGUyKGRybV9yYWRlb25fcHJpdmF0ZV90ICogZGV2X3ByaXYsCgkJCSAgICAgIHN0cnVjdCBkcm1fZmlsZSAqIGZpbHBfcHJpdiwKCQkJICAgICAgZHJtX3JhZGVvbl9zdGF0ZV90ICogc3RhdGUpCnsKCVJJTkdfTE9DQUxTOwoKCWlmIChzdGF0ZS0+ZGlydHkgJiBSQURFT05fVVBMT0FEX1pCSUFTKSB7CgkJQkVHSU5fUklORygzKTsKCQlPVVRfUklORyhDUF9QQUNLRVQwKFJBREVPTl9TRV9aQklBU19GQUNUT1IsIDEpKTsKCQlPVVRfUklORyhzdGF0ZS0+Y29udGV4dDIuc2VfemJpYXNfZmFjdG9yKTsKCQlPVVRfUklORyhzdGF0ZS0+Y29udGV4dDIuc2VfemJpYXNfY29uc3RhbnQpOwoJCUFEVkFOQ0VfUklORygpOwoJfQoKCXJldHVybiByYWRlb25fZW1pdF9zdGF0ZShkZXZfcHJpdiwgZmlscF9wcml2LCAmc3RhdGUtPmNvbnRleHQsCgkJCQkgc3RhdGUtPnRleCwgc3RhdGUtPmRpcnR5KTsKfQoKLyogTmV3ICgxLjMpIHN0YXRlIG1lY2hhbmlzbS4gIDMgY29tbWFuZHMgKHBhY2tldCwgc2NhbGFyLCB2ZWN0b3IpIGluCiAqIDEuMyBjbWRidWZmZXJzIGFsbG93IGFsbCBwcmV2aW91cyBzdGF0ZSB0byBiZSB1cGRhdGVkIGFzIHdlbGwgYXMKICogdGhlIHRjbCBzY2FsYXIgYW5kIHZlY3RvciBhcmVhcy4KICovCnN0YXRpYyBzdHJ1Y3QgewoJaW50IHN0YXJ0OwoJaW50IGxlbjsKCWNvbnN0IGNoYXIgKm5hbWU7Cn0gcGFja2V0W1JBREVPTl9NQVhfU1RBVEVfUEFDS0VUU10gPSB7Cgl7UkFERU9OX1BQX01JU0MsIDcsICJSQURFT05fUFBfTUlTQyJ9LAoJe1JBREVPTl9QUF9DTlRMLCAzLCAiUkFERU9OX1BQX0NOVEwifSwKCXtSQURFT05fUkIzRF9DT0xPUlBJVENILCAxLCAiUkFERU9OX1JCM0RfQ09MT1JQSVRDSCJ9LAoJe1JBREVPTl9SRV9MSU5FX1BBVFRFUk4sIDIsICJSQURFT05fUkVfTElORV9QQVRURVJOIn0sCgl7UkFERU9OX1NFX0xJTkVfV0lEVEgsIDEsICJSQURFT05fU0VfTElORV9XSURUSCJ9LAoJe1JBREVPTl9QUF9MVU1fTUFUUklYLCAxLCAiUkFERU9OX1BQX0xVTV9NQVRSSVgifSwKCXtSQURFT05fUFBfUk9UX01BVFJJWF8wLCAyLCAiUkFERU9OX1BQX1JPVF9NQVRSSVhfMCJ9LAoJe1JBREVPTl9SQjNEX1NURU5DSUxSRUZNQVNLLCAzLCAiUkFERU9OX1JCM0RfU1RFTkNJTFJFRk1BU0sifSwKCXtSQURFT05fU0VfVlBPUlRfWFNDQUxFLCA2LCAiUkFERU9OX1NFX1ZQT1JUX1hTQ0FMRSJ9LAoJe1JBREVPTl9TRV9DTlRMLCAyLCAiUkFERU9OX1NFX0NOVEwifSwKCXtSQURFT05fU0VfQ05UTF9TVEFUVVMsIDEsICJSQURFT05fU0VfQ05UTF9TVEFUVVMifSwKCXtSQURFT05fUkVfTUlTQywgMSwgIlJBREVPTl9SRV9NSVNDIn0sCgl7UkFERU9OX1BQX1RYRklMVEVSXzAsIDYsICJSQURFT05fUFBfVFhGSUxURVJfMCJ9LAoJe1JBREVPTl9QUF9CT1JERVJfQ09MT1JfMCwgMSwgIlJBREVPTl9QUF9CT1JERVJfQ09MT1JfMCJ9LAoJe1JBREVPTl9QUF9UWEZJTFRFUl8xLCA2LCAiUkFERU9OX1BQX1RYRklMVEVSXzEifSwKCXtSQURFT05fUFBfQk9SREVSX0NPTE9SXzEsIDEsICJSQURFT05fUFBfQk9SREVSX0NPTE9SXzEifSwKCXtSQURFT05fUFBfVFhGSUxURVJfMiwgNiwgIlJBREVPTl9QUF9UWEZJTFRFUl8yIn0sCgl7UkFERU9OX1BQX0JPUkRFUl9DT0xPUl8yLCAxLCAiUkFERU9OX1BQX0JPUkRFUl9DT0xPUl8yIn0sCgl7UkFERU9OX1NFX1pCSUFTX0ZBQ1RPUiwgMiwgIlJBREVPTl9TRV9aQklBU19GQUNUT1IifSwKCXtSQURFT05fU0VfVENMX09VVFBVVF9WVFhfRk1ULCAxMSwgIlJBREVPTl9TRV9UQ0xfT1VUUFVUX1ZUWF9GTVQifSwKCXtSQURFT05fU0VfVENMX01BVEVSSUFMX0VNTUlTU0lWRV9SRUQsIDE3LAoJCSAgICAiUkFERU9OX1NFX1RDTF9NQVRFUklBTF9FTU1JU1NJVkVfUkVEIn0sCgl7UjIwMF9QUF9UWENCTEVORF8wLCA0LCAiUjIwMF9QUF9UWENCTEVORF8wIn0sCgl7UjIwMF9QUF9UWENCTEVORF8xLCA0LCAiUjIwMF9QUF9UWENCTEVORF8xIn0sCgl7UjIwMF9QUF9UWENCTEVORF8yLCA0LCAiUjIwMF9QUF9UWENCTEVORF8yIn0sCgl7UjIwMF9QUF9UWENCTEVORF8zLCA0LCAiUjIwMF9QUF9UWENCTEVORF8zIn0sCgl7UjIwMF9QUF9UWENCTEVORF80LCA0LCAiUjIwMF9QUF9UWENCTEVORF80In0sCgl7UjIwMF9QUF9UWENCTEVORF81LCA0LCAiUjIwMF9QUF9UWENCTEVORF81In0sCgl7UjIwMF9QUF9UWENCTEVORF82LCA0LCAiUjIwMF9QUF9UWENCTEVORF82In0sCgl7UjIwMF9QUF9UWENCTEVORF83LCA0LCAiUjIwMF9QUF9UWENCTEVORF83In0sCgl7UjIwMF9TRV9UQ0xfTElHSFRfTU9ERUxfQ1RMXzAsIDYsICJSMjAwX1NFX1RDTF9MSUdIVF9NT0RFTF9DVExfMCJ9LAoJe1IyMDBfUFBfVEZBQ1RPUl8wLCA2LCAiUjIwMF9QUF9URkFDVE9SXzAifSwKCXtSMjAwX1NFX1ZUWF9GTVRfMCwgNCwgIlIyMDBfU0VfVlRYX0ZNVF8wIn0sCgl7UjIwMF9TRV9WQVBfQ05UTCwgMSwgIlIyMDBfU0VfVkFQX0NOVEwifSwKCXtSMjAwX1NFX1RDTF9NQVRSSVhfU0VMXzAsIDUsICJSMjAwX1NFX1RDTF9NQVRSSVhfU0VMXzAifSwKCXtSMjAwX1NFX1RDTF9URVhfUFJPQ19DVExfMiwgNSwgIlIyMDBfU0VfVENMX1RFWF9QUk9DX0NUTF8yIn0sCgl7UjIwMF9TRV9UQ0xfVUNQX1ZFUlRfQkxFTkRfQ1RMLCAxLCAiUjIwMF9TRV9UQ0xfVUNQX1ZFUlRfQkxFTkRfQ1RMIn0sCgl7UjIwMF9QUF9UWEZJTFRFUl8wLCA2LCAiUjIwMF9QUF9UWEZJTFRFUl8wIn0sCgl7UjIwMF9QUF9UWEZJTFRFUl8xLCA2LCAiUjIwMF9QUF9UWEZJTFRFUl8xIn0sCgl7UjIwMF9QUF9UWEZJTFRFUl8yLCA2LCAiUjIwMF9QUF9UWEZJTFRFUl8yIn0sCgl7UjIwMF9QUF9UWEZJTFRFUl8zLCA2LCAiUjIwMF9QUF9UWEZJTFRFUl8zIn0sCgl7UjIwMF9QUF9UWEZJTFRFUl80LCA2LCAiUjIwMF9QUF9UWEZJTFRFUl80In0sCgl7UjIwMF9QUF9UWEZJTFRFUl81LCA2LCAiUjIwMF9QUF9UWEZJTFRFUl81In0sCgl7UjIwMF9QUF9UWE9GRlNFVF8wLCAxLCAiUjIwMF9QUF9UWE9GRlNFVF8wIn0sCgl7UjIwMF9QUF9UWE9GRlNFVF8xLCAxLCAiUjIwMF9QUF9UWE9GRlNFVF8xIn0sCgl7UjIwMF9QUF9UWE9GRlNFVF8yLCAxLCAiUjIwMF9QUF9UWE9GRlNFVF8yIn0sCgl7UjIwMF9QUF9UWE9GRlNFVF8zLCAxLCAiUjIwMF9QUF9UWE9GRlNFVF8zIn0sCgl7UjIwMF9QUF9UWE9GRlNFVF80LCAxLCAiUjIwMF9QUF9UWE9GRlNFVF80In0sCgl7UjIwMF9QUF9UWE9GRlNFVF81LCAxLCAiUjIwMF9QUF9UWE9GRlNFVF81In0sCgl7UjIwMF9TRV9WVEVfQ05UTCwgMSwgIlIyMDBfU0VfVlRFX0NOVEwifSwKCXtSMjAwX1NFX1RDTF9PVVRQVVRfVlRYX0NPTVBfU0VMLCAxLAoJICJSMjAwX1NFX1RDTF9PVVRQVVRfVlRYX0NPTVBfU0VMIn0sCgl7UjIwMF9QUF9UQU1fREVCVUczLCAxLCAiUjIwMF9QUF9UQU1fREVCVUczIn0sCgl7UjIwMF9QUF9DTlRMX1gsIDEsICJSMjAwX1BQX0NOVExfWCJ9LAoJe1IyMDBfUkIzRF9ERVBUSFhZX09GRlNFVCwgMSwgIlIyMDBfUkIzRF9ERVBUSFhZX09GRlNFVCJ9LAoJe1IyMDBfUkVfQVVYX1NDSVNTT1JfQ05UTCwgMSwgIlIyMDBfUkVfQVVYX1NDSVNTT1JfQ05UTCJ9LAoJe1IyMDBfUkVfU0NJU1NPUl9UTF8wLCAyLCAiUjIwMF9SRV9TQ0lTU09SX1RMXzAifSwKCXtSMjAwX1JFX1NDSVNTT1JfVExfMSwgMiwgIlIyMDBfUkVfU0NJU1NPUl9UTF8xIn0sCgl7UjIwMF9SRV9TQ0lTU09SX1RMXzIsIDIsICJSMjAwX1JFX1NDSVNTT1JfVExfMiJ9LAoJe1IyMDBfU0VfVkFQX0NOVExfU1RBVFVTLCAxLCAiUjIwMF9TRV9WQVBfQ05UTF9TVEFUVVMifSwKCXtSMjAwX1NFX1ZUWF9TVEFURV9DTlRMLCAxLCAiUjIwMF9TRV9WVFhfU1RBVEVfQ05UTCJ9LAoJe1IyMDBfUkVfUE9JTlRTSVpFLCAxLCAiUjIwMF9SRV9QT0lOVFNJWkUifSwKCXtSMjAwX1NFX1RDTF9JTlBVVF9WVFhfVkVDVE9SX0FERFJfMCwgNCwKCQkgICAgIlIyMDBfU0VfVENMX0lOUFVUX1ZUWF9WRUNUT1JfQUREUl8wIn0sCgl7UjIwMF9QUF9DVUJJQ19GQUNFU18wLCAxLCAiUjIwMF9QUF9DVUJJQ19GQUNFU18wIn0sCS8qIDYxICovCgl7UjIwMF9QUF9DVUJJQ19PRkZTRVRfRjFfMCwgNSwgIlIyMDBfUFBfQ1VCSUNfT0ZGU0VUX0YxXzAifSwgLyogNjIgKi8KCXtSMjAwX1BQX0NVQklDX0ZBQ0VTXzEsIDEsICJSMjAwX1BQX0NVQklDX0ZBQ0VTXzEifSwKCXtSMjAwX1BQX0NVQklDX09GRlNFVF9GMV8xLCA1LCAiUjIwMF9QUF9DVUJJQ19PRkZTRVRfRjFfMSJ9LAoJe1IyMDBfUFBfQ1VCSUNfRkFDRVNfMiwgMSwgIlIyMDBfUFBfQ1VCSUNfRkFDRVNfMiJ9LAoJe1IyMDBfUFBfQ1VCSUNfT0ZGU0VUX0YxXzIsIDUsICJSMjAwX1BQX0NVQklDX09GRlNFVF9GMV8yIn0sCgl7UjIwMF9QUF9DVUJJQ19GQUNFU18zLCAxLCAiUjIwMF9QUF9DVUJJQ19GQUNFU18zIn0sCgl7UjIwMF9QUF9DVUJJQ19PRkZTRVRfRjFfMywgNSwgIlIyMDBfUFBfQ1VCSUNfT0ZGU0VUX0YxXzMifSwKCXtSMjAwX1BQX0NVQklDX0ZBQ0VTXzQsIDEsICJSMjAwX1BQX0NVQklDX0ZBQ0VTXzQifSwKCXtSMjAwX1BQX0NVQklDX09GRlNFVF9GMV80LCA1LCAiUjIwMF9QUF9DVUJJQ19PRkZTRVRfRjFfNCJ9LAoJe1IyMDBfUFBfQ1VCSUNfRkFDRVNfNSwgMSwgIlIyMDBfUFBfQ1VCSUNfRkFDRVNfNSJ9LAoJe1IyMDBfUFBfQ1VCSUNfT0ZGU0VUX0YxXzUsIDUsICJSMjAwX1BQX0NVQklDX09GRlNFVF9GMV81In0sCgl7UkFERU9OX1BQX1RFWF9TSVpFXzAsIDIsICJSQURFT05fUFBfVEVYX1NJWkVfMCJ9LAoJe1JBREVPTl9QUF9URVhfU0laRV8xLCAyLCAiUkFERU9OX1BQX1RFWF9TSVpFXzEifSwKCXtSQURFT05fUFBfVEVYX1NJWkVfMiwgMiwgIlJBREVPTl9QUF9URVhfU0laRV8yIn0sCgl7UjIwMF9SQjNEX0JMRU5EQ09MT1IsIDMsICJSMjAwX1JCM0RfQkxFTkRDT0xPUiJ9LAoJe1IyMDBfU0VfVENMX1BPSU5UX1NQUklURV9DTlRMLCAxLCAiUjIwMF9TRV9UQ0xfUE9JTlRfU1BSSVRFX0NOVEwifSwKCXtSQURFT05fUFBfQ1VCSUNfRkFDRVNfMCwgMSwgIlJBREVPTl9QUF9DVUJJQ19GQUNFU18wIn0sCgl7UkFERU9OX1BQX0NVQklDX09GRlNFVF9UMF8wLCA1LCAiUkFERU9OX1BQX0NVQklDX09GRlNFVF9UMF8wIn0sCgl7UkFERU9OX1BQX0NVQklDX0ZBQ0VTXzEsIDEsICJSQURFT05fUFBfQ1VCSUNfRkFDRVNfMSJ9LAoJe1JBREVPTl9QUF9DVUJJQ19PRkZTRVRfVDFfMCwgNSwgIlJBREVPTl9QUF9DVUJJQ19PRkZTRVRfVDFfMCJ9LAoJe1JBREVPTl9QUF9DVUJJQ19GQUNFU18yLCAxLCAiUkFERU9OX1BQX0NVQklDX0ZBQ0VTXzIifSwKCXtSQURFT05fUFBfQ1VCSUNfT0ZGU0VUX1QyXzAsIDUsICJSQURFT05fUFBfQ1VCSUNfT0ZGU0VUX1QyXzAifSwKCXtSMjAwX1BQX1RSSV9QRVJGLCAyLCAiUjIwMF9QUF9UUklfUEVSRiJ9LAoJe1IyMDBfUFBfQUZTXzAsIDMyLCAiUjIwMF9QUF9BRlNfMCJ9LCAgICAgLyogODUgKi8KCXtSMjAwX1BQX0FGU18xLCAzMiwgIlIyMDBfUFBfQUZTXzEifSwKCXtSMjAwX1BQX1RGQUNUT1JfMCwgOCwgIlIyMDBfQVRGX1RGQUNUT1IifSwKCXtSMjAwX1BQX1RYRklMVEVSXzAsIDgsICJSMjAwX1BQX1RYQ1RMQUxMXzAifSwKCXtSMjAwX1BQX1RYRklMVEVSXzEsIDgsICJSMjAwX1BQX1RYQ1RMQUxMXzEifSwKCXtSMjAwX1BQX1RYRklMVEVSXzIsIDgsICJSMjAwX1BQX1RYQ1RMQUxMXzIifSwKCXtSMjAwX1BQX1RYRklMVEVSXzMsIDgsICJSMjAwX1BQX1RYQ1RMQUxMXzMifSwKCXtSMjAwX1BQX1RYRklMVEVSXzQsIDgsICJSMjAwX1BQX1RYQ1RMQUxMXzQifSwKCXtSMjAwX1BQX1RYRklMVEVSXzUsIDgsICJSMjAwX1BQX1RYQ1RMQUxMXzUifSwKCXtSMjAwX1ZBUF9QVlNfQ05UTF8xLCAyLCAiUjIwMF9WQVBfUFZTX0NOVEwifSwKfTsKCi8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICogUGVyZm9ybWFuY2UgbW9uaXRvcmluZyBmdW5jdGlvbnMKICovCgpzdGF0aWMgdm9pZCByYWRlb25fY2xlYXJfYm94KGRybV9yYWRlb25fcHJpdmF0ZV90ICogZGV2X3ByaXYsCgkJCSAgICAgaW50IHgsIGludCB5LCBpbnQgdywgaW50IGgsIGludCByLCBpbnQgZywgaW50IGIpCnsKCXUzMiBjb2xvcjsKCVJJTkdfTE9DQUxTOwoKCXggKz0gZGV2X3ByaXYtPnNhcmVhX3ByaXYtPmJveGVzWzBdLngxOwoJeSArPSBkZXZfcHJpdi0+c2FyZWFfcHJpdi0+Ym94ZXNbMF0ueTE7CgoJc3dpdGNoIChkZXZfcHJpdi0+Y29sb3JfZm10KSB7CgljYXNlIFJBREVPTl9DT0xPUl9GT1JNQVRfUkdCNTY1OgoJCWNvbG9yID0gKCgociAmIDB4ZjgpIDw8IDgpIHwKCQkJICgoZyAmIDB4ZmMpIDw8IDMpIHwgKChiICYgMHhmOCkgPj4gMykpOwoJCWJyZWFrOwoJY2FzZSBSQURFT05fQ09MT1JfRk9STUFUX0FSR0I4ODg4OgoJZGVmYXVsdDoKCQljb2xvciA9ICgoKDB4ZmYpIDw8IDI0KSB8IChyIDw8IDE2KSB8IChnIDw8IDgpIHwgYik7CgkJYnJlYWs7Cgl9CgoJQkVHSU5fUklORyg0KTsKCVJBREVPTl9XQUlUX1VOVElMXzNEX0lETEUoKTsKCU9VVF9SSU5HKENQX1BBQ0tFVDAoUkFERU9OX0RQX1dSSVRFX01BU0ssIDApKTsKCU9VVF9SSU5HKDB4ZmZmZmZmZmYpOwoJQURWQU5DRV9SSU5HKCk7CgoJQkVHSU5fUklORyg2KTsKCglPVVRfUklORyhDUF9QQUNLRVQzKFJBREVPTl9DTlRMX1BBSU5UX01VTFRJLCA0KSk7CglPVVRfUklORyhSQURFT05fR01DX0RTVF9QSVRDSF9PRkZTRVRfQ05UTCB8CgkJIFJBREVPTl9HTUNfQlJVU0hfU09MSURfQ09MT1IgfAoJCSAoZGV2X3ByaXYtPmNvbG9yX2ZtdCA8PCA4KSB8CgkJIFJBREVPTl9HTUNfU1JDX0RBVEFUWVBFX0NPTE9SIHwKCQkgUkFERU9OX1JPUDNfUCB8IFJBREVPTl9HTUNfQ0xSX0NNUF9DTlRMX0RJUyk7CgoJaWYgKGRldl9wcml2LT5zYXJlYV9wcml2LT5wZkN1cnJlbnRQYWdlID09IDEpIHsKCQlPVVRfUklORyhkZXZfcHJpdi0+ZnJvbnRfcGl0Y2hfb2Zmc2V0KTsKCX0gZWxzZSB7CgkJT1VUX1JJTkcoZGV2X3ByaXYtPmJhY2tfcGl0Y2hfb2Zmc2V0KTsKCX0KCglPVVRfUklORyhjb2xvcik7CgoJT1VUX1JJTkcoKHggPDwgMTYpIHwgeSk7CglPVVRfUklORygodyA8PCAxNikgfCBoKTsKCglBRFZBTkNFX1JJTkcoKTsKfQoKc3RhdGljIHZvaWQgcmFkZW9uX2NwX3BlcmZvcm1hbmNlX2JveGVzKGRybV9yYWRlb25fcHJpdmF0ZV90ICogZGV2X3ByaXYpCnsKCS8qIENvbGxhcHNlIHZhcmlvdXMgdGhpbmdzIGludG8gYSB3YWl0IGZsYWcgLS0gdHJ5aW5nIHRvCgkgKiBndWVzcyBpZiB1c2Vyc3Bhc2Ugc2xlcHQgLS0gYmV0dGVyIGp1c3QgdG8gaGF2ZSB0aGVtIHRlbGwgdXMuCgkgKi8KCWlmIChkZXZfcHJpdi0+c3RhdHMubGFzdF9mcmFtZV9yZWFkcyA+IDEgfHwKCSAgICBkZXZfcHJpdi0+c3RhdHMubGFzdF9jbGVhcl9yZWFkcyA+IGRldl9wcml2LT5zdGF0cy5jbGVhcnMpIHsKCQlkZXZfcHJpdi0+c3RhdHMuYm94ZXMgfD0gUkFERU9OX0JPWF9XQUlUX0lETEU7Cgl9CgoJaWYgKGRldl9wcml2LT5zdGF0cy5mcmVlbGlzdF9sb29wcykgewoJCWRldl9wcml2LT5zdGF0cy5ib3hlcyB8PSBSQURFT05fQk9YX1dBSVRfSURMRTsKCX0KCgkvKiBQdXJwbGUgYm94IGZvciBwYWdlIGZsaXBwaW5nCgkgKi8KCWlmIChkZXZfcHJpdi0+c3RhdHMuYm94ZXMgJiBSQURFT05fQk9YX0ZMSVApCgkJcmFkZW9uX2NsZWFyX2JveChkZXZfcHJpdiwgNCwgNCwgOCwgOCwgMjU1LCAwLCAyNTUpOwoKCS8qIFJlZCBib3ggaWYgd2UgaGF2ZSB0byB3YWl0IGZvciBpZGxlIGF0IGFueSBwb2ludAoJICovCglpZiAoZGV2X3ByaXYtPnN0YXRzLmJveGVzICYgUkFERU9OX0JPWF9XQUlUX0lETEUpCgkJcmFkZW9uX2NsZWFyX2JveChkZXZfcHJpdiwgMTYsIDQsIDgsIDgsIDI1NSwgMCwgMCk7CgoJLyogQmx1ZSBib3g6IGxvc3QgY29udGV4dD8KCSAqLwoKCS8qIFllbGxvdyBib3ggZm9yIHRleHR1cmUgc3dhcHMKCSAqLwoJaWYgKGRldl9wcml2LT5zdGF0cy5ib3hlcyAmIFJBREVPTl9CT1hfVEVYVFVSRV9MT0FEKQoJCXJhZGVvbl9jbGVhcl9ib3goZGV2X3ByaXYsIDQwLCA0LCA4LCA4LCAyNTUsIDI1NSwgMCk7CgoJLyogR3JlZW4gYm94IGlmIGhhcmR3YXJlIG5ldmVyIGlkbGVzIChhcyBmYXIgYXMgd2UgY2FuIHRlbGwpCgkgKi8KCWlmICghKGRldl9wcml2LT5zdGF0cy5ib3hlcyAmIFJBREVPTl9CT1hfRE1BX0lETEUpKQoJCXJhZGVvbl9jbGVhcl9ib3goZGV2X3ByaXYsIDY0LCA0LCA4LCA4LCAwLCAyNTUsIDApOwoKCS8qIERyYXcgYmFycyBpbmRpY2F0aW5nIG51bWJlciBvZiBidWZmZXJzIGFsbG9jYXRlZAoJICogKG5vdCBhIGdyZWF0IG1lYXN1cmUsIGVhc2lseSBjb25mdXNlZCkKCSAqLwoJaWYgKGRldl9wcml2LT5zdGF0cy5yZXF1ZXN0ZWRfYnVmcykgewoJCWlmIChkZXZfcHJpdi0+c3RhdHMucmVxdWVzdGVkX2J1ZnMgPiAxMDApCgkJCWRldl9wcml2LT5zdGF0cy5yZXF1ZXN0ZWRfYnVmcyA9IDEwMDsKCgkJcmFkZW9uX2NsZWFyX2JveChkZXZfcHJpdiwgNCwgMTYsCgkJCQkgZGV2X3ByaXYtPnN0YXRzLnJlcXVlc3RlZF9idWZzLCA0LAoJCQkJIDE5NiwgMTI4LCAxMjgpOwoJfQoKCW1lbXNldCgmZGV2X3ByaXYtPnN0YXRzLCAwLCBzaXplb2YoZGV2X3ByaXYtPnN0YXRzKSk7Cgp9CgovKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqIENQIGNvbW1hbmQgZGlzcGF0Y2ggZnVuY3Rpb25zCiAqLwoKc3RhdGljIHZvaWQgcmFkZW9uX2NwX2Rpc3BhdGNoX2NsZWFyKHN0cnVjdCBkcm1fZGV2aWNlICogZGV2LAoJCQkJICAgICBkcm1fcmFkZW9uX2NsZWFyX3QgKiBjbGVhciwKCQkJCSAgICAgZHJtX3JhZGVvbl9jbGVhcl9yZWN0X3QgKiBkZXB0aF9ib3hlcykKewoJZHJtX3JhZGVvbl9wcml2YXRlX3QgKmRldl9wcml2ID0gZGV2LT5kZXZfcHJpdmF0ZTsKCWRybV9yYWRlb25fc2FyZWFfdCAqc2FyZWFfcHJpdiA9IGRldl9wcml2LT5zYXJlYV9wcml2OwoJZHJtX3JhZGVvbl9kZXB0aF9jbGVhcl90ICpkZXB0aF9jbGVhciA9ICZkZXZfcHJpdi0+ZGVwdGhfY2xlYXI7CglpbnQgbmJveCA9IHNhcmVhX3ByaXYtPm5ib3g7CglzdHJ1Y3QgZHJtX2NsaXBfcmVjdCAqcGJveCA9IHNhcmVhX3ByaXYtPmJveGVzOwoJdW5zaWduZWQgaW50IGZsYWdzID0gY2xlYXItPmZsYWdzOwoJdTMyIHJiM2RfY250bCA9IDAsIHJiM2Rfc3RlbmNpbHJlZm1hc2sgPSAwOwoJaW50IGk7CglSSU5HX0xPQ0FMUzsKCURSTV9ERUJVRygiZmxhZ3MgPSAweCV4XG4iLCBmbGFncyk7CgoJZGV2X3ByaXYtPnN0YXRzLmNsZWFycysrOwoKCWlmIChkZXZfcHJpdi0+c2FyZWFfcHJpdi0+cGZDdXJyZW50UGFnZSA9PSAxKSB7CgkJdW5zaWduZWQgaW50IHRtcCA9IGZsYWdzOwoKCQlmbGFncyAmPSB+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+Y3R4X293bmVyID0gMDsKCgkJZm9yIChpID0gMDsgaSA8IG5ib3g7IGkrKykgewoKCQkJLyogRnVubnkgdGhhdCB0aGlzIHNob3VsZCBiZSByZXF1aXJlZCAtLQoJCQkgKiAgc2V0cyB0b3AtbGVmdD8KCQkJICovCgkJCXJhZGVvbl9lbWl0X2NsaXBfcmVjdChkZXZfcHJpdiwgJnNhcmVhX3ByaXYtPmJveGVzW2ldKTsKCgkJCUJFR0lOX1JJTkcoMTUpOwoKCQkJT1VUX1JJTkcoQ1BfUEFDS0VUMyhSQURFT05fM0RfRFJBV19JTU1ELCAxMykpOwoJCQlPVVRfUklORyhSQURFT05fVlRYX1pfUFJFU0VOVCB8CgkJCQkgUkFERU9OX1ZUWF9QS0NPTE9SX1BSRVNFTlQpOwoJCQlPVVRfUklORygoUkFERU9OX1BSSU1fVFlQRV9SRUNUX0xJU1QgfAoJCQkJICBSQURFT05fUFJJTV9XQUxLX1JJTkcgfAoJCQkJICBSQURFT05fTUFPU19FTkFCTEUgfAoJCQkJICBSQURFT05fVlRYX0ZNVF9SQURFT05fTU9ERSB8CgkJCQkgICgzIDw8IFJBREVPTl9OVU1fVkVSVElDRVNfU0hJRlQpKSk7CgoJCQlPVVRfUklORyhkZXB0aF9ib3hlc1tpXS51aVtDTEVBUl9YMV0pOwoJCQlPVVRfUklORyhkZXB0aF9ib3hlc1tpXS51aVtDTEVBUl9ZMV0pOwoJCQlPVVRfUklORyhkZXB0aF9ib3hlc1tpXS51aVtDTEVBUl9ERVBUSF0pOwoJCQlPVVRfUklORygweDApOwoKCQkJT1VUX1JJTkcoZGVwdGhfYm94ZXNbaV0udWlbQ0xFQVJfWDFdKTsKCQkJT1VUX1JJTkcoZGVwdGhfYm94ZXNbaV0udWlbQ0xFQVJfWTJdKTsKCQkJT1VUX1JJTkcoZGVwdGhfYm94ZXNbaV0udWlbQ0xFQVJfREVQVEhdKTsKCQkJT1VUX1JJTkcoMHgwKTsKCgkJCU9VVF9SSU5HKGRlcHRoX2JveGVzW2ldLnVpW0NMRUFSX1gyXSk7CgkJCU9VVF9SSU5HKGRlcHRoX2JveGVzW2ldLnVpW0NMRUFSX1kyXSk7CgkJCU9VVF9SSU5HKGRlcHRoX2JveGVzW2ldLnVpW0NMRUFSX0RFUFRIXSk7CgkJCU9VVF9SSU5HKDB4MCk7CgoJCQlBRFZBTkNFX1JJTkcoKTsKCQl9Cgl9CgoJLyogSW5jcmVtZW50IHRoZSBjbGVhciBjb3VudGVyLiAgVGhlIGNsaWVudC1zaWRlIDNEIGRyaXZlciBtdXN0CgkgKiB3YWl0IG9uIHRoaXMgdmFsdWUgYmVmb3JlIHBlcmZvcm1pbmcgdGhlIGNsZWFyIGlvY3RsLiAgV2UKCSAqIG5lZWQgdGhpcyBiZWNhdXNlIHRoZSBjYXJkJ3Mgc28gZGFtbmVkIGZhc3QuLi4KCSAqLwoJZGV2X3ByaXYtPnNhcmVhX3ByaXYtPmxhc3RfY2xlYXIrKzsKCglCRUdJTl9SSU5HKDQpOwoKCVJBREVPTl9DTEVBUl9BR0UoZGV2X3ByaXYtPnNhcmVhX3ByaXYtPmxhc3RfY2xlYXIpOwoJUkFERU9OX1dBSVRfVU5USUxfSURMRSgpOwoKCUFEVkFOQ0VfUklORygpOwp9CgpzdGF0aWMgdm9pZCByYWRlb25fY3BfZGlzcGF0Y2hfc3dhcChzdHJ1Y3QgZHJtX2RldmljZSAqIGRldikKewoJZHJtX3JhZGVvbl9wcml2YXRlX3QgKmRldl9wcml2ID0gZGV2LT5kZXZfcHJpdmF0ZTsKCWRybV9yYWRlb25fc2FyZWFfdCAqc2FyZWFfcHJpdiA9IGRldl9wcml2LT5zYXJlYV9wcml2OwoJaW50IG5ib3ggPSBzYXJlYV9wcml2LT5uYm94OwoJc3RydWN0IGRybV9jbGlwX3JlY3QgKnBib3ggPSBzYXJlYV9wcml2LT5ib3hlczsKCWludCBpOwoJUklOR19MT0NBTFM7CglEUk1fREVCVUcoIlxuIik7CgoJLyogRG8gc29tZSB0cml2aWFsIHBlcmZvcm1hbmNlIG1vbml0b3JpbmcuLi4KCSAqLwoJaWYgKGRldl9wcml2LT5kb19ib3hlcykKCQlyYWRlb25fY3BfcGVyZm9ybWFuY2VfYm94ZXMoZGV2X3ByaXYpOwoKCS8qIFdhaXQgZm9yIHRoZSAzRCBzdHJlYW0gdG8gaWRsZSBiZWZvcmUgZGlzcGF0Y2hpbmcgdGhlIGJpdGJsdC4KCSAqIFRoaXMgd2lsbCBwcmV2ZW50IGRhdGEgY29ycnVwdGlvbiBiZXR3ZWVuIHRoZSB0d28gc3RyZWFtcy4KCSAqLwoJQkVHSU5fUklORygyKTsKCglSQURFT05fV0FJVF9VTlRJTF8zRF9JRExFKCk7CgoJQURWQU5DRV9SSU5HKCk7CgoJZm9yIChpID0gMDsgaSA8IG5ib3g7IGkrKykgewoJCWludCB4ID0gcGJveFtpXS54MTsKCQlpbnQgeSA9IHBib3hbaV0ueTE7CgkJaW50IHcgPSBwYm94W2ldLngyIC0geDsKCQlpbnQgaCA9IHBib3hbaV0ueTIgLSB5OwoKCQlEUk1fREVCVUcoImRpc3BhdGNoIHN3YXAgJWQsJWQtJWQsJWRcbiIsIHgsIHksIHcsIGgpOwoKCQlCRUdJTl9SSU5HKDkpOwoKCQlPVVRfUklORyhDUF9QQUNLRVQwKFJBREVPTl9EUF9HVUlfTUFTVEVSX0NOVEwsIDApKTsKCQlPVVRfUklORyhSQURFT05fR01DX1NSQ19QSVRDSF9PRkZTRVRfQ05UTCB8CgkJCSBSQURFT05fR01DX0RTVF9QSVRDSF9PRkZTRVRfQ05UTCB8CgkJCSBSQURFT05fR01DX0JSVVNIX05PTkUgfAoJCQkgKGRldl9wcml2LT5jb2xvcl9mbXQgPDwgOCkgfAoJCQkgUkFERU9OX0dNQ19TUkNfREFUQVRZUEVfQ09MT1IgfAoJCQkgUkFERU9OX1JPUDNfUyB8CgkJCSBSQURFT05fRFBfU1JDX1NPVVJDRV9NRU1PUlkgfAoJCQkgUkFERU9OX0dNQ19DTFJfQ01QX0NOVExfRElTIHwgUkFERU9OX0dNQ19XUl9NU0tfRElTKTsKCgkJLyogTWFrZSB0aGlzIHdvcmsgZXZlbiBpZiBmcm9udCAmIGJhY2sgYXJlIGZsaXBwZWQ6CgkJICovCgkJT1VUX1JJTkcoQ1BfUEFDS0VUMChSQURFT05fU1JDX1BJVENIX09GRlNFVCwgMSkpOwoJCWlmIChkZXZfcHJpdi0+c2FyZWFfcHJpdi0+cGZDdXJyZW50UGFnZSA9PSAwKSB7CgkJCU9VVF9SSU5HKGRldl9wcml2LT5iYWNrX3BpdGNoX29mZnNldCk7CgkJCU9VVF9SSU5HKGRldl9wcml2LT5mcm9udF9waXRjaF9vZmZzZXQpOwoJCX0gZWxzZSB7CgkJCU9VVF9SSU5HKGRldl9wcml2LT5mcm9udF9waXRjaF9vZmZzZXQpOwoJCQlPVVRfUklORyhkZXZfcHJpdi0+YmFja19waXRjaF9vZmZzZXQpOwoJCX0KCgkJT1VUX1JJTkcoQ1BfUEFDS0VUMChSQURFT05fU1JDX1hfWSwgMikpOwoJCU9VVF9SSU5HKCh4IDw8IDE2KSB8IHkpOwoJCU9VVF9SSU5HKCh4IDw8IDE2KSB8IHkpOwoJCU9VVF9SSU5HKCh3IDw8IDE2KSB8IGgpOwoKCQlBRFZBTkNFX1JJTkcoKTsKCX0KCgkvKiBJbmNyZW1lbnQgdGhlIGZyYW1lIGNvdW50ZXIuICBUaGUgY2xpZW50LXNpZGUgM0QgZHJpdmVyIG11c3QKCSAqIHRocm90dGxlIHRoZSBmcmFtZXJhdGUgYnkgd2FpdGluZyBmb3IgdGhpcyB2YWx1ZSBiZWZvcmUKCSAqIHBlcmZvcm1pbmcgdGhlIHN3YXBidWZmZXIgaW9jdGwuCgkgKi8KCWRldl9wcml2LT5zYXJlYV9wcml2LT5sYXN0X2ZyYW1lKys7CgoJQkVHSU5fUklORyg0KTsKCglSQURFT05fRlJBTUVfQUdFKGRldl9wcml2LT5zYXJlYV9wcml2LT5sYXN0X2ZyYW1lKTsKCVJBREVPTl9XQUlUX1VOVElMXzJEX0lETEUoKTsKCglBRFZBTkNFX1JJTkcoKTsKfQoKc3RhdGljIHZvaWQgcmFkZW9uX2NwX2Rpc3BhdGNoX2ZsaXAoc3RydWN0IGRybV9kZXZpY2UgKiBkZXYpCnsKCWRybV9yYWRlb25fcHJpdmF0ZV90ICpkZXZfcHJpdiA9IGRldi0+ZGV2X3ByaXZhdGU7CglzdHJ1Y3QgZHJtX3NhcmVhICpzYXJlYSA9IChzdHJ1Y3QgZHJtX3NhcmVhICopIGRldl9wcml2LT5zYXJlYS0+aGFuZGxlOwoJaW50IG9mZnNldCA9IChkZXZfcHJpdi0+c2FyZWFfcHJpdi0+cGZDdXJyZW50UGFnZSA9PSAxKQoJICAgID8gZGV2X3ByaXYtPmZyb250X29mZnNldCA6IGRldl9wcml2LT5iYWNrX29mZnNldDsKCVJJTkdfTE9DQUxTOwoJRFJNX0RFQlVHKCIlczogcGZDdXJyZW50UGFnZT0lZFxuIiwKCQkgIF9fRlVOQ1RJT05fXywKCQkgIGRldl9wcml2LT5zYXJlYV9wcml2LT5wZkN1cnJlbnRQYWdlKTsKCgkvKiBEbyBzb21lIHRyaXZpYWwgcGVyZm9ybWFuY2UgbW9uaXRvcmluZy4uLgoJICovCglpZiAoZGV2X3ByaXYtPmRvX2JveGVzKSB7CgkJZGV2X3ByaXYtPnN0YXRzLmJveGVzIHw9IFJBREVPTl9CT1hfRkxJUDsKCQlyYWRlb25fY3BfcGVyZm9ybWFuY2VfYm94ZXMoZGV2X3ByaXYpOwoJfQoKCS8qIFVwZGF0ZSB0aGUgZnJhbWUgb2Zmc2V0cyBmb3IgYm90aCBDUlRDcwoJICovCglCRUdJTl9SSU5HKDYpOwoKCVJBREVPTl9XQUlUX1VOVElMXzNEX0lETEUoKTsKCU9VVF9SSU5HX1JFRyhSQURFT05fQ1JUQ19PRkZTRVQsCgkJICAgICAoKHNhcmVhLT5mcmFtZS55ICogZGV2X3ByaXYtPmZyb250X3BpdGNoICsKCQkgICAgICAgc2FyZWEtPmZyYW1lLnggKiAoZGV2X3ByaXYtPmNvbG9yX2ZtdCAtIDIpKSAmIH43KQoJCSAgICAgKyBvZmZzZXQpOwoJT1VUX1JJTkdfUkVHKFJBREVPTl9DUlRDMl9PRkZTRVQsIGRldl9wcml2LT5zYXJlYV9wcml2LT5jcnRjMl9iYXNlCgkJICAgICArIG9mZnNldCk7CgoJQURWQU5DRV9SSU5HKCk7CgoJLyogSW5jcmVtZW50IHRoZSBmcmFtZSBjb3VudGVyLiAgVGhlIGNsaWVudC1zaWRlIDNEIGRyaXZlciBtdXN0CgkgKiB0aHJvdHRsZSB0aGUgZnJhbWVyYXRlIGJ5IHdhaXRpbmcgZm9yIHRoaXMgdmFsdWUgYmVmb3JlCgkgKiBwZXJmb3JtaW5nIHRoZSBzd2FwYnVmZmVyIGlvY3RsLgoJICovCglkZXZfcHJpdi0+c2FyZWFfcHJpdi0+bGFzdF9mcmFtZSsrOwoJZGV2X3ByaXYtPnNhcmVhX3ByaXYtPnBmQ3VycmVudFBhZ2UgPQoJCTEgLSBkZXZfcHJpdi0+c2FyZWFfcHJpdi0+cGZDdXJyZW50UGFnZTsKCglCRUdJTl9SSU5HKDIpOwoKCVJBREVPTl9GUkFNRV9BR0UoZGV2X3ByaXYtPnNhcmVhX3ByaXYtPmxhc3RfZnJhbWUpOwoKCUFEVkFOQ0VfUklORygpOwp9CgpzdGF0aWMgaW50IGJhZF9wcmltX3ZlcnRleF9ucihpbnQgcHJpbWl0aXZlLCBpbnQgbnIpCnsKCXN3aXRjaCAocHJpbWl0aXZlICYgUkFERU9OX1BSSU1fVFlQRV9NQVNLKSB7CgljYXNlIFJBREVPTl9QUklNX1RZUEVfTk9ORToKCWNhc2UgUkFERU9OX1BSSU1fVFlQRV9QT0lOVDoKCQlyZXR1cm4gbnIgPCAxOwoJY2FzZSBSQURFT05fUFJJTV9UWVBFX0xJTkU6CgkJcmV0dXJuIChuciAmIDEpIHx8IG5yID09IDA7CgljYXNlIFJBREVPTl9QUklNX1RZUEVfTElORV9TVFJJUDoKCQlyZXR1cm4gbnIgPCAyOwoJY2FzZSBSQURFT05fUFJJTV9UWVBFX1RSSV9MSVNUOgoJY2FzZSBSQURFT05fUFJJTV9UWVBFXzNWUlRfUE9JTlRfTElTVDoKCWNhc2UgUkFERU9OX1BSSU1fVFlQRV8zVlJUX0xJTkVfTElTVDoKCWNhc2UgUkFERU9OX1BSSU1fVFlQRV9SRUNUX0xJU1Q6CgkJcmV0dXJuIG5yICUgMyB8fCBuciA9PSAwOwoJY2FzZSBSQURFT05fUFJJTV9UWVBFX1RSSV9GQU46CgljYXNlIFJBREVPTl9QUklNX1RZUEVfVFJJX1NUUklQOgoJCXJldHVybiBuciA8IDM7CglkZWZhdWx0OgoJCXJldHVybiAxOwoJfQp9Cgp0eXBlZGVmIHN0cnVjdCB7Cgl1bnNpZ25lZCBpbnQgc3RhcnQ7Cgl1bnNpZ25lZCBpbnQgZmluaXNoOwoJdW5zaWduZWQgaW50IHByaW07Cgl1bnNpZ25lZCBpbnQgbnVtdmVydHM7Cgl1bnNpZ25lZCBpbnQgb2Zmc2V0OwoJdW5zaWduZWQgaW50IHZjX2Zvcm1hdDsKfSBkcm1fcmFkZW9uX3RjbF9wcmltX3Q7CgpzdGF0aWMgdm9pZCByYWRlb25fY3BfZGlzcGF0Y2hfdmVydGV4KHN0cnVjdCBkcm1fZGV2aWNlICogZGV2LAoJCQkJICAgICAgc3RydWN0IGRybV9idWYgKiBidWYsCgkJCQkgICAgICBkcm1fcmFkZW9uX3RjbF9wcmltX3QgKiBwcmltKQp7Cglkcm1fcmFkZW9uX3ByaXZhdGVfdCAqZGV2X3ByaXYgPSBkZXYtPmRldl9wcml2YXRlOwoJZHJtX3JhZGVvbl9zYXJlYV90ICpzYXJlYV9wcml2ID0gZGV2X3ByaXYtPnNhcmVhX3ByaXY7CglpbnQgb2Zmc2V0ID0gZGV2X3ByaXYtPmdhcnRfYnVmZmVyc19vZmZzZXQgKyBidWYtPm9mZnNldCArIHByaW0tPnN0YXJ0OwoJaW50IG51bXZlcnRzID0gKGludClwcmltLT5udW12ZXJ0czsKCWludCBuYm94ID0gc2FyZWFfcHJpdi0+bmJveDsKCWludCBpID0gMDsKCVJJTkdfTE9DQUxTOwoKCURSTV9ERUJVRygiaHdwcmltIDB4JXggdmZtdCAweCV4ICVkLi4lZCAlZCB2ZXJ0c1xuIiwKCQkgIHByaW0tPnByaW0sCgkJICBwcmltLT52Y19mb3JtYXQsIHByaW0tPnN0YXJ0LCBwcmltLT5maW5pc2gsIHByaW0tPm51bXZlcnRzKTsKCglpZiAoYmFkX3ByaW1fdmVydGV4X25yKHByaW0tPnByaW0sIHByaW0tPm51bXZlcnRzKSkgewoJCURSTV9FUlJPUigiYmFkIHByaW0gJXggbnVtdmVydHMgJWRcbiIsCgkJCSAgcHJpbS0+cHJpbSwgcHJpbS0+bnVtdmVydHMpOwoJCXJldHVybjsKCX0KCglkbyB7CgkJLyogRW1pdCB0aGUgbmV4dCBjbGlwcmVjdCAqLwoJCWlmIChpIDwgbmJveCkgewoJCQlyYWRlb25fZW1pdF9jbGlwX3JlY3QoZGV2X3ByaXYsICZzYXJlYV9wcml2LT5ib3hlc1tpXSk7CgkJfQoKCQkvKiBFbWl0IHRoZSB2ZXJ0ZXggYnVmZmVyIHJlbmRlcmluZyBjb21tYW5kcyAqLwoJCUJFR0lOX1JJTkcoNSk7CgoJCU9VVF9SSU5HKENQX1BBQ0tFVDMoUkFERU9OXzNEX1JORFJfR0VOX0lORFhfUFJJTSwgMykpOwoJCU9VVF9SSU5HKG9mZnNldCk7CgkJT1VUX1JJTkcobnVtdmVydHMpOwoJCU9VVF9SSU5HKHByaW0tPnZjX2Zvcm1hdCk7CgkJT1VUX1JJTkcocHJpbS0+cHJpbSB8IFJBREVPTl9QUklNX1dBTEtfTElTVCB8CgkJCSBSQURFT05fQ09MT1JfT1JERVJfUkdCQSB8CgkJCSBSQURFT05fVlRYX0ZNVF9SQURFT05fTU9ERSB8CgkJCSAobnVtdmVydHMgPDwgUkFERU9OX05VTV9WRVJUSUNFU19TSElGVCkpOwoKCQlBRFZBTkNFX1JJTkcoKTsKCgkJaSsrOwoJfSB3aGlsZSAoaSA8IG5ib3gpOwp9CgpzdGF0aWMgdm9pZCByYWRlb25fY3BfZGlzY2FyZF9idWZmZXIoc3RydWN0IGRybV9kZXZpY2UgKiBkZXYsIHN0cnVjdCBkcm1fYnVmICogYnVmKQp7Cglkcm1fcmFkZW9uX3ByaXZhdGVfdCAqZGV2X3ByaXYgPSBkZXYtPmRldl9wcml2YXRlOwoJZHJtX3JhZGVvbl9idWZfcHJpdl90ICpidWZfcHJpdiA9IGJ1Zi0+ZGV2X3ByaXZhdGU7CglSSU5HX0xPQ0FMUzsKCglidWZfcHJpdi0+YWdlID0gKytkZXZfcHJpdi0+c2FyZWFfcHJpdi0+bGFzdF9kaXNwYXRjaDsKCgkvKiBFbWl0IHRoZSB2ZXJ0ZXggYnVmZmVyIGFnZSAqLwoJQkVHSU5fUklORygyKTsKCVJBREVPTl9ESVNQQVRDSF9BR0UoYnVmX3ByaXYtPmFnZSk7CglBRFZBTkNFX1JJTkcoKTsKCglidWYtPnBlbmRpbmcgPSAxOwoJYnVmLT51c2VkID0gMDsKfQoKc3RhdGljIHZvaWQgcmFkZW9uX2NwX2Rpc3BhdGNoX2luZGlyZWN0KHN0cnVjdCBkcm1fZGV2aWNlICogZGV2LAoJCQkJCXN0cnVjdCBkcm1fYnVmICogYnVmLCBpbnQgc3RhcnQsIGludCBlbmQpCnsKCWRybV9yYWRlb25fcHJpdmF0ZV90ICpkZXZfcHJpdiA9IGRldi0+ZGV2X3ByaXZhdGU7CglSSU5HX0xPQ0FMUzsKCURSTV9ERUJVRygiaW5kaXJlY3Q6IGJ1Zj0lZCBzPTB4JXggZT0weCV4XG4iLCBidWYtPmlkeCwgc3RhcnQsIGVuZCk7CgoJaWYgKHN0YXJ0ICE9IGVuZCkgewoJCWludCBvZmZzZXQgPSAoZGV2X3ByaXYtPmdhcnRfYnVmZmVyc19vZmZzZXQKCQkJICAgICAgKyBidWYtPm9mZnNldCArIHN0YXJ0KTsKCQlpbnQgZHdvcmRzID0gKGVuZCAtIHN0YXJ0ICsgMykgLyBzaXplb2YodTMyKTsKCgkJLyogSW5kaXJlY3QgYnVmZmVyIGRhdGEgbXVzdCBiZSBhbiBldmVuIG51bWJlciBvZgoJCSAqIGR3b3Jkcywgc28gaWYgd2UndmUgYmVlbiBnaXZlbiBhbiBvZGQgbnVtYmVyIHdlIG11c3QKCQkgKiBwYWQgdGhlIGRhdGEgd2l0aCBhIFR5cGUtMiBDUCBwYWNrZXQuCgkJICovCgkJaWYgKGR3b3JkcyAmIDEpIHsKCQkJdTMyICpkYXRhID0gKHUzMiAqKQoJCQkgICAgKChjaGFyICopZGV2LT5hZ3BfYnVmZmVyX21hcC0+aGFuZGxlCgkJCSAgICAgKyBidWYtPm9mZnNldCArIHN0YXJ0KTsKCQkJZGF0YVtkd29yZHMrK10gPSBSQURFT05fQ1BfUEFDS0VUMjsKCQl9CgoJCS8qIEZpcmUgb2ZmIHRoZSBpbmRpcmVjdCBidWZmZXIgKi8KCQlCRUdJTl9SSU5HKDMpOwoKCQlPVVRfUklORyhDUF9QQUNLRVQwKFJBREVPTl9DUF9JQl9CQVNFLCAxKSk7CgkJT1VUX1JJTkcob2Zmc2V0KTsKCQlPVVRfUklORyhkd29yZHMpOwoKCQlBRFZBTkNFX1JJTkcoKTsKCX0KfQoKc3RhdGljIHZvaWQgcmFkZW9uX2NwX2Rpc3BhdGNoX2luZGljZXMoc3RydWN0IGRybV9kZXZpY2UgKiBkZXYsCgkJCQkgICAgICAgc3RydWN0IGRybV9idWYgKiBlbHRfYnVmLAoJCQkJICAgICAgIGRybV9yYWRlb25fdGNsX3ByaW1fdCAqIHByaW0pCnsKCWRybV9yYWRlb25fcHJpdmF0ZV90ICpkZXZfcHJpdiA9IGRldi0+ZGV2X3ByaXZhdGU7Cglkcm1fcmFkZW9uX3NhcmVhX3QgKnNhcmVhX3ByaXYgPSBkZXZfcHJpdi0+c2FyZWFfcHJpdjsKCWludCBvZmZzZXQgPSBkZXZfcHJpdi0+Z2FydF9idWZmZXJzX29mZnNldCArIHByaW0tPm9mZnNldDsKCXUzMiAqZGF0YTsKCWludCBkd29yZHM7CglpbnQgaSA9IDA7CglpbnQgc3RhcnQgPSBwcmltLT5zdGFydCArIFJBREVPTl9JTkRFWF9QUklNX09GRlNFVDsKCWludCBjb3VudCA9IChwcmltLT5maW5pc2ggLSBzdGFydCkgLyBzaXplb2YodTE2KTsKCWludCBuYm94ID0gc2FyZWFfcHJpdi0+bmJveDsKCglEUk1fREVCVUcoImh3cHJpbSAweCV4IHZmbXQgMHgleCAlZC4uJWQgb2Zmc2V0OiAleCBuciAlZFxuIiwKCQkgIHByaW0tPnByaW0sCgkJICBwcmltLT52Y19mb3JtYXQsCgkJICBwcmltLT5zdGFydCwgcHJpbS0+ZmluaXNoLCBwcmltLT5vZmZzZXQsIHByaW0tPm51bXZlcnRzKTsKCglpZiAoYmFkX3ByaW1fdmVydGV4X25yKHByaW0tPnByaW0sIGNvdW50KSkgewoJCURSTV9FUlJPUigiYmFkIHByaW0gJXggY291bnQgJWRcbiIsIHByaW0tPnByaW0sIGNvdW50KTsKCQlyZXR1cm47Cgl9CgoJaWYgKHN0YXJ0ID49IHByaW0tPmZpbmlzaCB8fCAocHJpbS0+c3RhcnQgJiAweDcpKSB7CgkJRFJNX0VSUk9SKCJidWZmZXIgcHJpbSAlZFxuIiwgcHJpbS0+cHJpbSk7CgkJcmV0dXJuOwoJfQoKCWR3b3JkcyA9IChwcmltLT5maW5pc2ggLSBwcmltLT5zdGFydCArIDMpIC8gc2l6ZW9mKHUzMik7CgoJZGF0YSA9ICh1MzIgKikgKChjaGFyICopZGV2LT5hZ3BfYnVmZmVyX21hcC0+aGFuZGxlICsKCQkJZWx0X2J1Zi0+b2Zmc2V0ICsgcHJpbS0+c3RhcnQpOwoKCWRhdGFbMF0gPSBDUF9QQUNLRVQzKFJBREVPTl8zRF9STkRSX0dFTl9JTkRYX1BSSU0sIGR3b3JkcyAtIDIpOwoJZGF0YVsxXSA9IG9mZnNldDsKCWRhdGFbMl0gPSBwcmltLT5udW12ZXJ0czsKCWRhdGFbM10gPSBwcmltLT52Y19mb3JtYXQ7CglkYXRhWzRdID0gKHByaW0tPnByaW0gfAoJCSAgIFJBREVPTl9QUklNX1dBTEtfSU5EIHwKCQkgICBSQURFT05fQ09MT1JfT1JERVJfUkdCQSB8CgkJICAgUkFERU9OX1ZUWF9GTVRfUkFERU9OX01PREUgfAoJCSAgIChjb3VudCA8PCBSQURFT05fTlVNX1ZFUlRJQ0VTX1NISUZUKSk7CgoJZG8gewoJCWlmIChpIDwgbmJveCkKCQkJcmFkZW9uX2VtaXRfY2xpcF9yZWN0KGRldl9wcml2LCAmc2FyZWFfcHJpdi0+Ym94ZXNbaV0pOwoKCQlyYWRlb25fY3BfZGlzcGF0Y2hfaW5kaXJlY3QoZGV2LCBlbHRfYnVmLAoJCQkJCSAgICBwcmltLT5zdGFydCwgcHJpbS0+ZmluaXNoKTsKCgkJaSsrOwoJfSB3aGlsZSAoaSA8IG5ib3gpOwoKfQoKI2RlZmluZSBSQURFT05fTUFYX1RFWFRVUkVfU0laRSBSQURFT05fQlVGRkVSX1NJWkUKCnN0YXRpYyBpbnQgcmFkZW9uX2NwX2Rpc3BhdGNoX3RleHR1cmUoRFJNRklMRSBmaWxwLAoJCQkJICAgICAgc3RydWN0IGRybV9kZXZpY2UgKiBkZXYsCgkJCQkgICAgICBkcm1fcmFkZW9uX3RleHR1cmVfdCAqIHRleCwKCQkJCSAgICAgIGRybV9yYWRlb25fdGV4X2ltYWdlX3QgKiBpbWFnZSkKewoJZHJtX3JhZGVvbl9wcml2YXRlX3QgKmRldl9wcml2ID0gZGV2LT5kZXZfcHJpdmF0ZTsKCXN0cnVjdCBkcm1fZmlsZSAqZmlscF9wcml2OwoJc3RydWN0IGRybV9idWYgKmJ1ZjsKCXUzMiBmb3JtYXQ7Cgl1MzIgKmJ1ZmZlcjsKCWNvbnN0IHU4IF9fdXNlciAqZGF0YTsKCWludCBzaXplLCBkd29yZHMsIHRleF93aWR0aCwgYmxpdF93aWR0aCwgc3BpdGNoOwoJdTMyIGhlaWdodDsKCWludCBpOwoJdTMyIHRleHBpdGNoLCBtaWNyb3RpbGU7Cgl1MzIgb2Zmc2V0OwoJUklOR19MT0NBTFM7CgoJRFJNX0dFVF9QUklWX1dJVEhfUkVUVVJOKGZpbHBfcHJpdiwgZmlscCk7CgoJaWYgKHJhZGVvbl9jaGVja19hbmRfZml4dXBfb2Zmc2V0KGRldl9wcml2LCBmaWxwX3ByaXYsICZ0ZXgtPm9mZnNldCkpIHsKCQlEUk1fRVJST1IoIkludmFsaWQgZGVzdGluYXRpb24gb2Zmc2V0XG4iKTsKCQlyZXR1cm4gRFJNX0VSUihFSU5WQUwpOwoJfQoKCWRldl9wcml2LT5zdGF0cy5ib3hlcyB8PSBSQURFT05fQk9YX1RFWFRVUkVfTE9BRDsKCgkvKiBGbHVzaCB0aGUgcGl4ZWwgY2FjaGUuICBUaGlzIGVuc3VyZXMgbm8gcGl4ZWwgZGF0YSBnZXRzIG1peGVkCgkgKiB1cCB3aXRoIHRoZSB0ZXh0dXJlIGRhdGEgZnJvbSB0aGUgaG9zdCBkYXRhIGJsaXQsIG90aGVyd2lzZQoJICogcGFydCBvZiB0aGUgdGV4dHVyZSBpbWFnZSBtYXkgYmUgY29ycnVwdGVkLgoJICovCglCRUdJTl9SSU5HKDQpOwoJUkFERU9OX0ZMVVNIX0NBQ0hFKCk7CglSQURFT05fV0FJVF9VTlRJTF9JRExFKCk7CglBRFZBTkNFX1JJTkcoKTsKCgkvKiBUaGUgY29tcGlsZXIgd29uJ3Qgb3B0aW1pemUgYXdheSBhIGRpdmlzaW9uIGJ5IGEgdmFyaWFibGUsCgkgKiBldmVuIGlmIHRoZSBvbmx5IGxlZ2FsIHZhbHVlcyBhcmUgcG93ZXJzIG9mIHR3by4gIFRodXMsIHdlJ2xsCgkgKiB1c2UgYSBzaGlmdCBpbnN0ZWFkLgoJICovCglzd2l0Y2ggKHRleC0+Zm9ybWF0KSB7CgljYXNlIFJBREVPTl9UWEZPUk1BVF9BUkdCODg4ODoKCWNhc2UgUkFERU9OX1RYRk9STUFUX1JHQkE4ODg4OgoJCWZvcm1hdCA9IFJBREVPTl9DT0xPUl9GT1JNQVRfQVJHQjg4ODg7CgkJdGV4X3dpZHRoID0gdGV4LT53aWR0aCAqIDQ7CgkJYmxpdF93aWR0aCA9IGltYWdlLT53aWR0aCAqIDQ7CgkJYnJlYWs7CgljYXNlIFJBREVPTl9UWEZPUk1BVF9BSTg4OgoJY2FzZSBSQURFT05fVFhGT1JNQVRfQVJHQjE1NTU6CgljYXNlIFJBREVPTl9UWEZPUk1BVF9SR0I1NjU6CgljYXNlIFJBREVPTl9UWEZPUk1BVF9BUkdCNDQ0NDoKCWNhc2UgUkFERU9OX1RYRk9STUFUX1ZZVVk0MjI6CgljYXNlIFJBREVPTl9UWEZPUk1BVF9ZVllVNDIyOgoJCWZvcm1hdCA9IFJBREVPTl9DT0xPUl9GT1JNQVRfUkdCNTY1OwoJCXRleF93aWR0aCA9IHRleC0+d2lkdGggKiAyOwoJCWJsaXRfd2lkdGggPSBpbWFnZS0+d2lkdGggKiAyOwoJCWJyZWFrOwoJY2FzZSBSQURFT05fVFhGT1JNQVRfSTg6CgljYXNlIFJBREVPTl9UWEZPUk1BVF9SR0IzMzI6CgkJZm9ybWF0ID0gUkFERU9OX0NPTE9SX0ZPUk1BVF9DSTg7CgkJdGV4X3dpZHRoID0gdGV4LT53aWR0aCAqIDE7CgkJYmxpdF93aWR0aCA9IGltYWdlLT53aWR0aCAqIDE7CgkJYnJlYWs7CglkZWZhdWx0OgoJCURSTV9FUlJPUigiaW52YWxpZCB0ZXh0dXJlIGZvcm1hdCAlZFxuIiwgdGV4LT5mb3JtYXQpOwoJCXJldHVybiBEUk1fRVJSKEVJTlZBTCk7Cgl9CglzcGl0Y2ggPSBibGl0X3dpZHRoID4+IDY7CglpZiAoc3BpdGNoID09IDAgJiYgaW1hZ2UtPmhlaWdodCA+IDEpCgkJcmV0dXJuIERSTV9FUlIoRUlOVkFMKTsKCgl0ZXhwaXRjaCA9IHRleC0+cGl0Y2g7CglpZiAoKHRleHBpdGNoIDw8IDIyKSAmIFJBREVPTl9EU1RfVElMRV9NSUNSTykgewoJCW1pY3JvdGlsZSA9IDE7CgkJaWYgKHRleF93aWR0aCA8IDY0KSB7CgkJCXRleHBpdGNoICY9IH4oUkFERU9OX0RTVF9USUxFX01JQ1JPID4+IDIyKTsKCQkJLyogd2UgZ290IHRpbGVkIGNvb3JkaW5hdGVzLCB1bnRpbGUgdGhlbSAqLwoJCQlpbWFnZS0+eCAqPSAyOwoJCX0KCX0gZWxzZQoJCW1pY3JvdGlsZSA9IDA7CgoJRFJNX0RFQlVHKCJ0ZXg9JWR4JWQgYmxpdD0lZFxuIiwgdGV4X3dpZHRoLCB0ZXgtPmhlaWdodCwgYmxpdF93aWR0aCk7CgoJZG8gewoJCURSTV9ERUJVRygidGV4OiBvZnM9MHgleCBwPSVkIGY9JWQgeD0laGQgeT0laGQgdz0laGQgaD0laGRcbiIsCgkJCSAgdGV4LT5vZmZzZXQgPj4gMTAsIHRleC0+cGl0Y2gsIHRleC0+Zm9ybWF0LAoJCQkgIGltYWdlLT54LCBpbWFnZS0+eSwgaW1hZ2UtPndpZHRoLCBpbWFnZS0+aGVpZ2h0KTsKCgkJLyogTWFrZSBhIGNvcHkgb2Ygc29tZSBwYXJhbWV0ZXJzIGluIGNhc2Ugd2UgaGF2ZSB0bwoJCSAqIHVwZGF0ZSB0aGVtIGZvciBhIG11bHRpLXBhc3MgdGV4dHVyZSBibGl0LgoJCSAqLwoJCWhlaWdodCA9IGltYWdlLT5oZWlnaHQ7CgkJZGF0YSA9IChjb25zdCB1OCBfX3VzZXIgKilpbWFnZS0+ZGF0YTsKCgkJc2l6ZSA9IGhlaWdodCAqIGJsaXRfd2lkdGg7CgoJCWlmIChzaXplID4gUkFERU9OX01BWF9URVhUVVJFX1NJWkUpIHsKCQkJaGVpZ2h0ID0gUkFERU9OX01BWF9URVhUVVJFX1NJWkUgLyBibGl0X3dpZHRoOwoJCQlzaXplID0gaGVpZ2h0ICogYmxpdF93aWR0aDsKCQl9IGVsc2UgaWYgKHNpemUgPCA0ICYmIHNpemUgPiAwKSB7CgkJCXNpemUgPSA0OwoJCX0gZWxzZSBpZiAoc2l6ZSA9PSAwKSB7CgkJCXJldHVybiAwOwoJCX0KCgkJYnVmID0gcmFkZW9uX2ZyZWVsaXN0X2dldChkZXYpOwoJCWlmICgwICYmICFidWYpIHsKCQkJcmFkZW9uX2RvX2NwX2lkbGUoZGV2X3ByaXYpOwoJCQlidWYgPSByYWRlb25fZnJlZWxpc3RfZ2V0KGRldik7CgkJfQoJCWlmICghYnVmKSB7CgkJCURSTV9ERUJVRygicmFkZW9uX2NwX2Rpc3BhdGNoX3RleHR1cmU6IEVBR0FJTlxuIik7CgkJCWlmIChEUk1fQ09QWV9UT19VU0VSKHRleC0+aW1hZ2UsIGltYWdlLCBzaXplb2YoKmltYWdlKSkpCgkJCQlyZXR1cm4gRFJNX0VSUihFRkFVTFQpOwoJCQlyZXR1cm4gRFJNX0VSUihFQUdBSU4pOwoJCX0KCgkJLyogRGlzcGF0Y2ggdGhlIGluZGlyZWN0IGJ1ZmZlci4KCQkgKi8KCQlidWZmZXIgPQoJCSAgICAodTMyICopICgoY2hhciAqKWRldi0+YWdwX2J1ZmZlcl9tYXAtPmhhbmRsZSArIGJ1Zi0+b2Zmc2V0KTsKCQlkd29yZHMgPSBzaXplIC8gNDsKCiNkZWZpbmUgUkFERU9OX0NPUFlfTVQoX2J1ZiwgX2RhdGEsIF93aWR0aCkgXAoJZG8geyBcCgkJaWYgKERSTV9DT1BZX0ZST01fVVNFUihfYnVmLCBfZGF0YSwgKF93aWR0aCkpKSB7XAoJCQlEUk1fRVJST1IoIkVGQVVMVCBvbiBwYWQsICVkIGJ5dGVzXG4iLCAoX3dpZHRoKSk7IFwKCQkJcmV0dXJuIERSTV9FUlIoRUZBVUxUKTsgXAoJCX0gXAoJfSB3aGlsZSgwKQoKCQlpZiAobWljcm90aWxlKSB7CgkJCS8qIHRleHR1cmUgbWljcm8gdGlsaW5nIGluIHVzZSwgbWluaW11bSB0ZXh0dXJlIHdpZHRoIGlzIHRodXMgMTYgYnl0ZXMuCgkJCSAgIGhvd2V2ZXIsIHdlIGNhbm5vdCB1c2UgYmxpdHRlciBkaXJlY3RseSBmb3IgdGV4dHVyZSB3aWR0aCA8IDY0IGJ5dGVzLAoJCQkgICBzaW5jZSBtaW5pbXVtIHRleCBwaXRjaCBpcyA2NCBieXRlcyBhbmQgd2UgbmVlZCB0aGlzIHRvIG1hdGNoCgkJCSAgIHRoZSB0ZXh0dXJlIHdpZHRoLCBvdGhlcndpc2UgdGhlIGJsaXR0ZXIgd2lsbCB0aWxlIGl0IHdyb25nLgoJCQkgICBUaHVzLCB0aWxpbmcgbWFudWFsbHkgaW4gdGhpcyBjYXNlLiBBZGRpdGlvbmFsbHksIG5lZWQgdG8gc3BlY2lhbAoJCQkgICBjYXNlIHRleCBoZWlnaHQgPSAxLCBzaW5jZSBvdXIgYWN0dWFsIGltYWdlIHdpbGwgaGF2ZSBoZWlnaHQgMgoJCQkgICBhbmQgd2UgbmVlZCB0byBlbnN1cmUgd2UgZG9uJ3QgcmVhZCBiZXlvbmQgdGhlIHRleHR1cmUgc2l6ZQoJCQkgICBmcm9tIHVzZXIgc3BhY2UuICovCgkJCWlmICh0ZXgtPmhlaWdodCA9PSAxKSB7CgkJCQlpZiAodGV4X3dpZHRoID49IDY0IHx8IHRleF93aWR0aCA8PSAxNikgewoJCQkJCVJBREVPTl9DT1BZX01UKGJ1ZmZlciwgZGF0YSwKCQkJCQkJKGludCkodGV4X3dpZHRoICogc2l6ZW9mKHUzMikpKTsKCQkJCX0gZWxzZSBpZiAodGV4X3dpZHRoID09IDMyKSB7CgkJCQkJUkFERU9OX0NPUFlfTVQoYnVmZmVyLCBkYXRhLCAxNik7CgkJCQkJUkFERU9OX0NPUFlfTVQoYnVmZmVyICsgOCwKCQkJCQkJICAgICAgIGRhdGEgKyAxNiwgMTYpOwoJCQkJfQoJCQl9IGVsc2UgaWYgKHRleF93aWR0aCA+PSA2NCB8fCB0ZXhfd2lkdGggPT0gMTYpIHsKCQkJCVJBREVPTl9DT1BZX01UKGJ1ZmZlciwgZGF0YSwKCQkJCQkgICAgICAgKGludCkoZHdvcmRzICogc2l6ZW9mKHUzMikpKTsKCQkJfSBlbHNlIGlmICh0ZXhfd2lkdGggPCAxNikgewoJCQkJZm9yIChpID0gMDsgaSA8IHRleC0+aGVpZ2h0OyBpKyspIHsKCQkJCQlSQURFT05fQ09QWV9NVChidWZmZXIsIGRhdGEsIHRleF93aWR0aCk7CgkJCQkJYnVmZmVyICs9IDQ7CgkJCQkJZGF0YSArPSB0ZXhfd2lkdGg7CgkJCQl9CgkJCX0gZWxzZSBpZiAodGV4X3dpZHRoID09IDMyKSB7CgkJCQkvKiBUT0RPOiBtYWtlIHN1cmUgdGhpcyB3b3JrcyB3aGVuIG5vdCBmaXR0aW5nIGluIG9uZSBidWZmZXIKCQkJCSAgIChpLmUuIDMyYnl0ZXMgeCAyMDQ4Li4uKSAqLwoJCQkJZm9yIChpID0gMDsgaSA8IHRleC0+aGVpZ2h0OyBpICs9IDIpIHsKCQkJCQlSQURFT05fQ09QWV9NVChidWZmZXIsIGRhdGEsIDE2KTsKCQkJCQlkYXRhICs9IDE2OwoJCQkJCVJBREVPTl9DT1BZX01UKGJ1ZmZlciArIDgsIGRhdGEsIDE2KTsKCQkJCQlkYXRhICs9IDE2OwoJCQkJCVJBREVPTl9DT1BZX01UKGJ1ZmZlciArIDQsIGRhdGEsIDE2KTsKCQkJCQlkYXRhICs9IDE2OwoJCQkJCVJBREVPTl9DT1BZX01UKGJ1ZmZlciArIDEyLCBkYXRhLCAxNik7CgkJCQkJZGF0YSArPSAxNjsKCQkJCQlidWZmZXIgKz0gMTY7CgkJCQl9CgkJCX0KCQl9IGVsc2UgewoJCQlpZiAodGV4X3dpZHRoID49IDMyKSB7CgkJCQkvKiBUZXh0dXJlIGltYWdlIHdpZHRoIGlzIGxhcmdlciB0aGFuIHRoZSBtaW5pbXVtLCBzbyB3ZQoJCQkJICogY2FuIHVwbG9hZCBpdCBkaXJlY3RseS4KCQkJCSAqLwoJCQkJUkFERU9OX0NPUFlfTVQoYnVmZmVyLCBkYXRhLAoJCQkJCSAgICAgICAoaW50KShkd29yZHMgKiBzaXplb2YodTMyKSkpOwoJCQl9IGVsc2UgewoJCQkJLyogVGV4dHVyZSBpbWFnZSB3aWR0aCBpcyBsZXNzIHRoYW4gdGhlIG1pbmltdW0sIHNvIHdlCgkJCQkgKiBuZWVkIHRvIHBhZCBvdXQgZWFjaCBpbWFnZSBzY2FubGluZSB0byB0aGUgbWluaW11bQoJCQkJICogd2lkdGguCgkJCQkgKi8KCQkJCWZvciAoaSA9IDA7IGkgPCB0ZXgtPmhlaWdodDsgaSsrKSB7CgkJCQkJUkFERU9OX0NPUFlfTVQoYnVmZmVyLCBkYXRhLCB0ZXhfd2lkdGgpOwoJCQkJCWJ1ZmZlciArPSA4OwoJCQkJCWRhdGEgKz0gdGV4X3dpZHRoOwoJCQkJfQoJCQl9CgkJfQoKI3VuZGVmIFJBREVPTl9DT1BZX01UCgkJYnVmLT5maWxwID0gZmlscDsKCQlidWYtPnVzZWQgPSBzaXplOwoJCW9mZnNldCA9IGRldl9wcml2LT5nYXJ0X2J1ZmZlcnNfb2Zmc2V0ICsgYnVmLT5vZmZzZXQ7CgkJQkVHSU5fUklORyg5KTsKCQlPVVRfUklORyhDUF9QQUNLRVQzKFJBREVPTl9DTlRMX0JJVEJMVF9NVUxUSSwgNSkpOwoJCU9VVF9SSU5HKFJBREVPTl9HTUNfU1JDX1BJVENIX09GRlNFVF9DTlRMIHwKCQkJIFJBREVPTl9HTUNfRFNUX1BJVENIX09GRlNFVF9DTlRMIHwKCQkJIFJBREVPTl9HTUNfQlJVU0hfTk9ORSB8CgkJCSAoZm9ybWF0IDw8IDgpIHwKCQkJIFJBREVPTl9HTUNfU1JDX0RBVEFUWVBFX0NPTE9SIHwKCQkJIFJBREVPTl9ST1AzX1MgfAoJCQkgUkFERU9OX0RQX1NSQ19TT1VSQ0VfTUVNT1JZIHwKCQkJIFJBREVPTl9HTUNfQ0xSX0NNUF9DTlRMX0RJUyB8IFJBREVPTl9HTUNfV1JfTVNLX0RJUyk7CgkJT1VUX1JJTkcoKHNwaXRjaCA8PCAyMikgfCAob2Zmc2V0ID4+IDEwKSk7CgkJT1VUX1JJTkcoKHRleHBpdGNoIDw8IDIyKSB8ICh0ZXgtPm9mZnNldCA+PiAxMCkpOwoJCU9VVF9SSU5HKDApOwoJCU9VVF9SSU5HKChpbWFnZS0+eCA8PCAxNikgfCBpbWFnZS0+eSk7CgkJT1VUX1JJTkcoKGltYWdlLT53aWR0aCA8PCAxNikgfCBoZWlnaHQpOwoJCVJBREVPTl9XQUlUX1VOVElMXzJEX0lETEUoKTsKCQlBRFZBTkNFX1JJTkcoKTsKCgkJcmFkZW9uX2NwX2Rpc2NhcmRfYnVmZmVyKGRldiwgYnVmKTsKCgkJLyogVXBkYXRlIHRoZSBpbnB1dCBwYXJhbWV0ZXJzIGZvciBuZXh0IHRpbWUgKi8KCQlpbWFnZS0+eSArPSBoZWlnaHQ7CgkJaW1hZ2UtPmhlaWdodCAtPSBoZWlnaHQ7CgkJaW1hZ2UtPmRhdGEgPSAoY29uc3QgdTggX191c2VyICopaW1hZ2UtPmRhdGEgKyBzaXplOwoJfSB3aGlsZSAoaW1hZ2UtPmhlaWdodCA+IDApOwoKCS8qIEZsdXNoIHRoZSBwaXhlbCBjYWNoZSBhZnRlciB0aGUgYmxpdCBjb21wbGV0ZXMuICBUaGlzIGVuc3VyZXMKCSAqIHRoZSB0ZXh0dXJlIGRhdGEgaXMgd3JpdHRlbiBvdXQgdG8gbWVtb3J5IGJlZm9yZSByZW5kZXJpbmcKCSAqIGNvbnRpbnVlcy4KCSAqLwoJQkVHSU5fUklORyg0KTsKCVJBREVPTl9GTFVTSF9DQUNIRSgpOwoJUkFERU9OX1dBSVRfVU5USUxfMkRfSURMRSgpOwoJQURWQU5DRV9SSU5HKCk7CglyZXR1cm4gMDsKfQoKc3RhdGljIHZvaWQgcmFkZW9uX2NwX2Rpc3BhdGNoX3N0aXBwbGUoc3RydWN0IGRybV9kZXZpY2UgKiBkZXYsIHUzMiAqIHN0aXBwbGUpCnsKCWRybV9yYWRlb25fcHJpdmF0ZV90ICpkZXZfcHJpdiA9IGRldi0+ZGV2X3ByaXZhdGU7CglpbnQgaTsKCVJJTkdfTE9DQUxTOwoJRFJNX0RFQlVHKCJcbiIpOwoKCUJFR0lOX1JJTkcoMzUpOwoKCU9VVF9SSU5HKENQX1BBQ0tFVDAoUkFERU9OX1JFX1NUSVBQTEVfQUREUiwgMCkpOwoJT1VUX1JJTkcoMHgwMDAwMDAwMCk7CgoJT1VUX1JJTkcoQ1BfUEFDS0VUMF9UQUJMRShSQURFT05fUkVfU1RJUFBMRV9EQVRBLCAzMSkpOwoJZm9yIChpID0gMDsgaSA8IDMyOyBpKyspIHsKCQlPVVRfUklORyhzdGlwcGxlW2ldKTsKCX0KCglBRFZBTkNFX1JJTkcoKTsKfQoKc3RhdGljIHZvaWQgcmFkZW9uX2FwcGx5X3N1cmZhY2VfcmVncyhpbnQgc3VyZl9pbmRleCwKCQkJCSAgICAgIGRybV9yYWRlb25fcHJpdmF0ZV90ICpkZXZfcHJpdikKewoJaWYgKCFkZXZfcHJpdi0+bW1pbykKCQlyZXR1cm47CgoJcmFkZW9uX2RvX2NwX2lkbGUoZGV2X3ByaXYpOwoKCVJBREVPTl9XUklURShSQURFT05fU1VSRkFDRTBfSU5GTyArIDE2ICogc3VyZl9pbmRleCwKCQkgICAgIGRldl9wcml2LT5zdXJmYWNlc1tzdXJmX2luZGV4XS5mbGFncyk7CglSQURFT05fV1JJVEUoUkFERU9OX1NVUkZBQ0UwX0xPV0VSX0JPVU5EICsgMTYgKiBzdXJmX2luZGV4LAoJCSAgICAgZGV2X3ByaXYtPnN1cmZhY2VzW3N1cmZfaW5kZXhdLmxvd2VyKTsKCVJBREVPTl9XUklURShSQURFT05fU1VSRkFDRTBfVVBQRVJfQk9VTkQgKyAxNiAqIHN1cmZfaW5kZXgsCgkJICAgICBkZXZfcHJpdi0+c3VyZmFjZXNbc3VyZl9pbmRleF0udXBwZXIpOwp9CgovKiBBbGxvY2F0ZXMgYSB2aXJ0dWFsIHN1cmZhY2UKICogZG9lc24ndCBhbHdheXMgYWxsb2NhdGUgYSByZWFsIHN1cmZhY2UsIHdpbGwgc3RyZXRjaCBhbiBleGlzdGluZwogKiBzdXJmYWNlIHdoZW4gcG9zc2libGUuCiAqCiAqIE5vdGUgdGhhdCByZWZjb3VudCBjYW4gYmUgYXQgbW9zdCAyLCBzaW5jZSBkdXJpbmcgYSBmcmVlIHJlZmNvdW50PTMKICogbWlnaHQgbWVhbiB3ZSBoYXZlIHRvIGFsbG9jYXRlIGEgbmV3IHN1cmZhY2Ugd2hpY2ggbWlnaHQgbm90IGFsd2F5cwogKiBiZSBhdmFpbGFibGUuCiAqIEZvciBleGFtcGxlIDogd2UgYWxsb2NhdGUgdGhyZWUgY29udGlnb3VzIHN1cmZhY2VzIEFCQy4gSWYgQiBpcwogKiBmcmVlZCwgd2Ugc3VkZGVubHkgbmVlZCB0d28gc3VyZmFjZXMgdG8gc3RvcmUgQSBhbmQgQywgd2hpY2ggbWlnaHQKICogbm90IGFsd2F5cyBiZSBhdmFpbGFibGUuCiAqLwpzdGF0aWMgaW50IGFsbG9jX3N1cmZhY2UoZHJtX3JhZGVvbl9zdXJmYWNlX2FsbG9jX3QgKm5ldywKCQkJIGRybV9yYWRlb25fcHJpdmF0ZV90ICpkZXZfcHJpdiwgRFJNRklMRSBmaWxwKQp7CglzdHJ1Y3QgcmFkZW9uX3ZpcnRfc3VyZmFjZSAqczsKCWludCBpOwoJaW50IHZpcnRfc3VyZmFjZV9pbmRleDsKCXVpbnQzMl90IG5ld191cHBlciwgbmV3X2xvd2VyOwoKCW5ld19sb3dlciA9IG5ldy0+YWRkcmVzczsKCW5ld191cHBlciA9IG5ld19sb3dlciArIG5ldy0+c2l6ZSAtIDE7CgoJLyogc2FuaXR5IGNoZWNrICovCglpZiAoKG5ld19sb3dlciA+PSBuZXdfdXBwZXIpIHx8IChuZXctPmZsYWdzID09IDApIHx8IChuZXctPnNpemUgPT0gMCkgfHwKCSAgICAoKG5ld191cHBlciAmIFJBREVPTl9TVVJGX0FERFJFU1NfRklYRURfTUFTSykgIT0KCSAgICAgUkFERU9OX1NVUkZfQUREUkVTU19GSVhFRF9NQVNLKQoJICAgIHx8ICgobmV3X2xvd2VyICYgUkFERU9OX1NVUkZfQUREUkVTU19GSVhFRF9NQVNLKSAhPSAwKSkKCQlyZXR1cm4gLTE7CgoJLyogbWFrZSBzdXJlIHRoZXJlIGlzIG5vIG92ZXJsYXAgd2l0aCBleGlzdGluZyBzdXJmYWNlcyAqLwoJZm9yIChpID0gMDsgaSA8IFJBREVPTl9NQVhfU1VSRkFDRVM7IGkrKykgewoJCWlmICgoZGV2X3ByaXYtPnN1cmZhY2VzW2ldLnJlZmNvdW50ICE9IDApICYmCgkJICAgICgoKG5ld19sb3dlciA+PSBkZXZfcHJpdi0+c3VyZmFjZXNbaV0ubG93ZXIpICYmCgkJICAgICAgKG5ld19sb3dlciA8IGRldl9wcml2LT5zdXJmYWNlc1tpXS51cHBlcikpIHx8CgkJICAgICAoKG5ld19sb3dlciA8IGRldl9wcml2LT5zdXJmYWNlc1tpXS5sb3dlcikgJiYKCQkgICAgICAobmV3X3VwcGVyID4gZGV2X3ByaXYtPnN1cmZhY2VzW2ldLmxvd2VyKSkpKSB7CgkJCXJldHVybiAtMTsKCQl9Cgl9CgoJLyogZmluZCBhIHZpcnR1YWwgc3VyZmFjZSAqLwoJZm9yIChpID0gMDsgaSA8IDIgKiBSQURFT05fTUFYX1NVUkZBQ0VTOyBpKyspCgkJaWYgKGRldl9wcml2LT52aXJ0X3N1cmZhY2VzW2ldLmZpbHAgPT0gMCkKCQkJYnJlYWs7CglpZiAoaSA9PSAyICogUkFERU9OX01BWF9TVVJGQUNFUykgewoJCXJldHVybiAtMTsKCX0KCXZpcnRfc3VyZmFjZV9pbmRleCA9IGk7CgoJLyogdHJ5IHRvIHJldXNlIGFuIGV4aXN0aW5nIHN1cmZhY2UgKi8KCWZvciAoaSA9IDA7IGkgPCBSQURFT05fTUFYX1NVUkZBQ0VTOyBpKyspIHsKCQkvKiBleHRlbmQgYmVmb3JlICovCgkJaWYgKChkZXZfcHJpdi0+c3VyZmFjZXNbaV0ucmVmY291bnQgPT0gMSkgJiYKCQkgICAgKG5ldy0+ZmxhZ3MgPT0gZGV2X3ByaXYtPnN1cmZhY2VzW2ldLmZsYWdzKSAmJgoJCSAgICAobmV3X3VwcGVyICsgMSA9PSBkZXZfcHJpdi0+c3VyZmFjZXNbaV0ubG93ZXIpKSB7CgkJCXMgPSAmKGRldl9wcml2LT52aXJ0X3N1cmZhY2VzW3ZpcnRfc3VyZmFjZV9pbmRleF0pOwoJCQlzLT5zdXJmYWNlX2luZGV4ID0gaTsKCQkJcy0+bG93ZXIgPSBuZXdfbG93ZXI7CgkJCXMtPnVwcGVyID0gbmV3X3VwcGVyOwoJCQlzLT5mbGFncyA9IG5ldy0+ZmxhZ3M7CgkJCXMtPmZpbHAgPSBmaWxwOwoJCQlkZXZfcHJpdi0+c3VyZmFjZXNbaV0ucmVmY291bnQrKzsKCQkJZGV2X3ByaXYtPnN1cmZhY2VzW2ldLmxvd2VyID0gcy0+bG93ZXI7CgkJCXJhZGVvbl9hcHBseV9zdXJmYWNlX3JlZ3Mocy0+c3VyZmFjZV9pbmRleCwgZGV2X3ByaXYpOwoJCQlyZXR1cm4gdmlydF9zdXJmYWNlX2luZGV4OwoJCX0KCgkJLyogZXh0ZW5kIGFmdGVyICovCgkJaWYgKChkZXZfcHJpdi0+c3VyZmFjZXNbaV0ucmVmY291bnQgPT0gMSkgJiYKCQkgICAgKG5ldy0+ZmxhZ3MgPT0gZGV2X3ByaXYtPnN1cmZhY2VzW2ldLmZsYWdzKSAmJgoJCSAgICAobmV3X2xvd2VyID09IGRldl9wcml2LT5zdXJmYWNlc1tpXS51cHBlciArIDEpKSB7CgkJCXMgPSAmKGRldl9wcml2LT52aXJ0X3N1cmZhY2VzW3ZpcnRfc3VyZmFjZV9pbmRleF0pOwoJCQlzLT5zdXJmYWNlX2luZGV4ID0gaTsKCQkJcy0+bG93ZXIgPSBuZXdfbG93ZXI7CgkJCXMtPnVwcGVyID0gbmV3X3VwcGVyOwoJCQlzLT5mbGFncyA9IG5ldy0+ZmxhZ3M7CgkJCXMtPmZpbHAgPSBmaWxwOwoJCQlkZXZfcHJpdi0+c3VyZmFjZXNbaV0ucmVmY291bnQrKzsKCQkJZGV2X3ByaXYtPnN1cmZhY2VzW2ldLnVwcGVyID0gcy0+dXBwZXI7CgkJCXJhZGVvbl9hcHBseV9zdXJmYWNlX3JlZ3Mocy0+c3VyZmFjZV9pbmRleCwgZGV2X3ByaXYpOwoJCQlyZXR1cm4gdmlydF9zdXJmYWNlX2luZGV4OwoJCX0KCX0KCgkvKiBva2F5LCB3ZSBuZWVkIGEgbmV3IG9uZSAqLwoJZm9yIChpID0gMDsgaSA8IFJBREVPTl9NQVhfU1VSRkFDRVM7IGkrKykgewoJCWlmIChkZXZfcHJpdi0+c3VyZmFjZXNbaV0ucmVmY291bnQgPT0gMCkgewoJCQlzID0gJihkZXZfcHJpdi0+dmlydF9zdXJmYWNlc1t2aXJ0X3N1cmZhY2VfaW5kZXhdKTsKCQkJcy0+c3VyZmFjZV9pbmRleCA9IGk7CgkJCXMtPmxvd2VyID0gbmV3X2xvd2VyOwoJCQlzLT51cHBlciA9IG5ld191cHBlcjsKCQkJcy0+ZmxhZ3MgPSBuZXctPmZsYWdzOwoJCQlzLT5maWxwID0gZmlscDsKCQkJZGV2X3ByaXYtPnN1cmZhY2VzW2ldLnJlZmNvdW50ID0gMTsKCQkJZGV2X3ByaXYtPnN1cmZhY2VzW2ldLmxvd2VyID0gcy0+bG93ZXI7CgkJCWRldl9wcml2LT5zdXJmYWNlc1tpXS51cHBlciA9IHMtPnVwcGVyOwoJCQlkZXZfcHJpdi0+c3VyZmFjZXNbaV0uZmxhZ3MgPSBzLT5mbGFnczsKCQkJcmFkZW9uX2FwcGx5X3N1cmZhY2VfcmVncyhzLT5zdXJmYWNlX2luZGV4LCBkZXZfcHJpdik7CgkJCXJldHVybiB2aXJ0X3N1cmZhY2VfaW5kZXg7CgkJfQoJfQoKCS8qIHdlIGRpZG4ndCBmaW5kIGFueXRoaW5nICovCglyZXR1cm4gLTE7Cn0KCnN0YXRpYyBpbnQgZnJlZV9zdXJmYWNlKERSTUZJTEUgZmlscCwgZHJtX3JhZGVvbl9wcml2YXRlX3QgKiBkZXZfcHJpdiwKCQkJaW50IGxvd2VyKQp7CglzdHJ1Y3QgcmFkZW9uX3ZpcnRfc3VyZmFjZSAqczsKCWludCBpOwoJLyogZmluZCB0aGUgdmlydHVhbCBzdXJmYWNlICovCglmb3IgKGkgPSAwOyBpIDwgMiAqIFJBREVPTl9NQVhfU1VSRkFDRVM7IGkrKykgewoJCXMgPSAmKGRldl9wcml2LT52aXJ0X3N1cmZhY2VzW2ldKTsKCQlpZiAocy0+ZmlscCkgewoJCQlpZiAoKGxvd2VyID09IHMtPmxvd2VyKSAmJiAoZmlscCA9PSBzLT5maWxwKSkgewoJCQkJaWYgKGRldl9wcml2LT5zdXJmYWNlc1tzLT5zdXJmYWNlX2luZGV4XS4KCQkJCSAgICBsb3dlciA9PSBzLT5sb3dlcikKCQkJCQlkZXZfcHJpdi0+c3VyZmFjZXNbcy0+c3VyZmFjZV9pbmRleF0uCgkJCQkJICAgIGxvd2VyID0gcy0+dXBwZXI7CgoJCQkJaWYgKGRldl9wcml2LT5zdXJmYWNlc1tzLT5zdXJmYWNlX2luZGV4XS4KCQkJCSAgICB1cHBlciA9PSBzLT51cHBlcikKCQkJCQlkZXZfcHJpdi0+c3VyZmFjZXNbcy0+c3VyZmFjZV9pbmRleF0uCgkJCQkJICAgIHVwcGVyID0gcy0+bG93ZXI7CgoJCQkJZGV2X3ByaXYtPnN1cmZhY2VzW3MtPnN1cmZhY2VfaW5kZXhdLnJlZmNvdW50LS07CgkJCQlpZiAoZGV2X3ByaXYtPnN1cmZhY2VzW3MtPnN1cmZhY2VfaW5kZXhdLgoJCQkJICAgIHJlZmNvdW50ID09IDApCgkJCQkJZGV2X3ByaXYtPnN1cmZhY2VzW3MtPnN1cmZhY2VfaW5kZXhdLgoJCQkJCSAgICBmbGFncyA9IDA7CgkJCQlzLT5maWxwID0gTlVMTDsKCQkJCXJhZGVvbl9hcHBseV9zdXJmYWNlX3JlZ3Mocy0+c3VyZmFjZV9pbmRleCwKCQkJCQkJCSAgZGV2X3ByaXYpOwoJCQkJcmV0dXJuIDA7CgkJCX0KCQl9Cgl9CglyZXR1cm4gMTsKfQoKc3RhdGljIHZvaWQgcmFkZW9uX3N1cmZhY2VzX3JlbGVhc2UoRFJNRklMRSBmaWxwLAoJCQkJICAgIGRybV9yYWRlb25fcHJpdmF0ZV90ICogZGV2X3ByaXYpCnsKCWludCBpOwoJZm9yIChpID0gMDsgaSA8IDIgKiBSQURFT05fTUFYX1NVUkZBQ0VTOyBpKyspIHsKCQlpZiAoZGV2X3ByaXYtPnZpcnRfc3VyZmFjZXNbaV0uZmlscCA9PSBmaWxwKQoJCQlmcmVlX3N1cmZhY2UoZmlscCwgZGV2X3ByaXYsCgkJCQkgICAgIGRldl9wcml2LT52aXJ0X3N1cmZhY2VzW2ldLmxvd2VyKTsKCX0KfQoKLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKiBJT0NUTCBmdW5jdGlvbnMKICovCnN0YXRpYyBpbnQgcmFkZW9uX3N1cmZhY2VfYWxsb2MoRFJNX0lPQ1RMX0FSR1MpCnsKCURSTV9ERVZJQ0U7Cglkcm1fcmFkZW9uX3ByaXZhdGVfdCAqZGV2X3ByaXYgPSBkZXYtPmRldl9wcml2YXRlOwoJZHJtX3JhZGVvbl9zdXJmYWNlX2FsbG9jX3QgYWxsb2M7CgoJRFJNX0NPUFlfRlJPTV9VU0VSX0lPQ1RMKGFsbG9jLAoJCQkJIChkcm1fcmFkZW9uX3N1cmZhY2VfYWxsb2NfdCBfX3VzZXIgKikgZGF0YSwKCQkJCSBzaXplb2YoYWxsb2MpKTsKCglpZiAoYWxsb2Nfc3VyZmFjZSgmYWxsb2MsIGRldl9wcml2LCBmaWxwKSA9PSAtMSkKCQlyZXR1cm4gRFJNX0VSUihFSU5WQUwpOwoJZWxzZQoJCXJldHVybiAwOwp9CgpzdGF0aWMgaW50IHJhZGVvbl9zdXJmYWNlX2ZyZWUoRFJNX0lPQ1RMX0FSR1MpCnsKCURSTV9ERVZJQ0U7Cglkcm1fcmFkZW9uX3ByaXZhdGVfdCAqZGV2X3ByaXYgPSBkZXYtPmRldl9wcml2YXRlOwoJZHJtX3JhZGVvbl9zdXJmYWNlX2ZyZWVfdCBtZW1mcmVlOwoKCURSTV9DT1BZX0ZST01fVVNFUl9JT0NUTChtZW1mcmVlLCAoZHJtX3JhZGVvbl9zdXJmYWNlX2ZyZWVfdCBfX3VzZXIgKikgZGF0YSwKCQkJCSBzaXplb2YobWVtZnJlZSkpOwoKCWlmIChmcmVlX3N1cmZhY2UoZmlscCwgZGV2X3ByaXYsIG1lbWZyZWUuYWRkcmVzcykpCgkJcmV0dXJuIERSTV9FUlIoRUlOVkFMKTsKCWVsc2UKCQlyZXR1cm4gMDsKfQoKc3RhdGljIGludCByYWRlb25fY3BfY2xlYXIoRFJNX0lPQ1RMX0FSR1MpCnsKCURSTV9ERVZJQ0U7Cglkcm1fcmFkZW9uX3ByaXZhdGVfdCAqZGV2X3ByaXYgPSBkZXYtPmRldl9wcml2YXRlOwoJZHJtX3JhZGVvbl9zYXJlYV90ICpzYXJlYV9wcml2ID0gZGV2X3ByaXYtPnNhcmVhX3ByaXY7Cglkcm1fcmFkZW9uX2NsZWFyX3QgY2xlYXI7Cglkcm1fcmFkZW9uX2NsZWFyX3JlY3RfdCBkZXB0aF9ib3hlc1tSQURFT05fTlJfU0FSRUFfQ0xJUFJFQ1RTXTsKCURSTV9ERUJVRygiXG4iKTsKCglMT0NLX1RFU1RfV0lUSF9SRVRVUk4oZGV2LCBmaWxwKTsKCglEUk1fQ09QWV9GUk9NX1VTRVJfSU9DVEwoY2xlYXIsIChkcm1fcmFkZW9uX2NsZWFyX3QgX191c2VyICopIGRhdGEsCgkJCQkgc2l6ZW9mKGNsZWFyKSk7CgoJUklOR19TUEFDRV9URVNUX1dJVEhfUkVUVVJOKGRldl9wcml2KTsKCglpZiAoc2FyZWFfcHJpdi0+bmJveCA+IFJBREVPTl9OUl9TQVJFQV9DTElQUkVDVFMpCgkJc2FyZWFfcHJpdi0+bmJveCA9IFJBREVPTl9OUl9TQVJFQV9DTElQUkVDVFM7CgoJaWYgKERSTV9DT1BZX0ZST01fVVNFUigmZGVwdGhfYm94ZXMsIGNsZWFyLmRlcHRoX2JveGVzLAoJCQkgICAgICAgc2FyZWFfcHJpdi0+bmJveCAqIHNpemVvZihkZXB0aF9ib3hlc1swXSkpKQoJCXJldHVybiBEUk1fRVJSKEVGQVVMVCk7CgoJcmFkZW9uX2NwX2Rpc3BhdGNoX2NsZWFyKGRldiwgJmNsZWFyLCBkZXB0aF9ib3hlcyk7CgoJQ09NTUlUX1JJTkcoKTsKCXJldHVybiAwOwp9CgovKiBOb3Qgc3VyZSB3aHkgdGhpcyBpc24ndCBzZXQgYWxsIHRoZSB0aW1lOgogKi8Kc3RhdGljIGludCByYWRlb25fZG9faW5pdF9wYWdlZmxpcChzdHJ1Y3QgZHJtX2RldmljZSAqIGRldikKewoJZHJtX3JhZGVvbl9wcml2YXRlX3QgKmRldl9wcml2ID0gZGV2LT5kZXZfcHJpdmF0ZTsKCVJJTkdfTE9DQUxTOwoKCURSTV9ERUJVRygiXG4iKTsKCglCRUdJTl9SSU5HKDYpOwoJUkFERU9OX1dBSVRfVU5USUxfM0RfSURMRSgpOwoJT1VUX1JJTkcoQ1BfUEFDS0VUMChSQURFT05fQ1JUQ19PRkZTRVRfQ05UTCwgMCkpOwoJT1VUX1JJTkcoUkFERU9OX1JFQUQoUkFERU9OX0NSVENfT0ZGU0VUX0NOVEwpIHwKCQkgUkFERU9OX0NSVENfT0ZGU0VUX0ZMSVBfQ05UTCk7CglPVVRfUklORyhDUF9QQUNLRVQwKFJBREVPTl9DUlRDMl9PRkZTRVRfQ05UTCwgMCkpOwoJT1VUX1JJTkcoUkFERU9OX1JFQUQoUkFERU9OX0NSVEMyX09GRlNFVF9DTlRMKSB8CgkJIFJBREVPTl9DUlRDX09GRlNFVF9GTElQX0NOVEwpOwoJQURWQU5DRV9SSU5HKCk7CgoJZGV2X3ByaXYtPnBhZ2VfZmxpcHBpbmcgPSAxOwoKCWlmIChkZXZfcHJpdi0+c2FyZWFfcHJpdi0+cGZDdXJyZW50UGFnZSAhPSAxKQoJCWRldl9wcml2LT5zYXJlYV9wcml2LT5wZkN1cnJlbnRQYWdlID0gMDsKCglyZXR1cm4gMDsKfQoKLyogU3dhcHBpbmcgYW5kIGZsaXBwaW5nIGFyZSBkaWZmZXJlbnQgb3BlcmF0aW9ucywgbmVlZCBkaWZmZXJlbnQgaW9jdGxzLgogKiBUaGV5IGNhbiAmIHNob3VsZCBiZSBpbnRlcm1peGVkIHRvIHN1cHBvcnQgbXVsdGlwbGUgM2Qgd2luZG93cy4KICovCnN0YXRpYyBpbnQgcmFkZW9uX2NwX2ZsaXAoRFJNX0lPQ1RMX0FSR1MpCnsKCURSTV9ERVZJQ0U7Cglkcm1fcmFkZW9uX3ByaXZhdGVfdCAqZGV2X3ByaXYgPSBkZXYtPmRldl9wcml2YXRlOwoJRFJNX0RFQlVHKCJcbiIpOwoKCUxPQ0tfVEVTVF9XSVRIX1JFVFVSTihkZXYsIGZpbHApOwoKCVJJTkdfU1BBQ0VfVEVTVF9XSVRIX1JFVFVSTihkZXZfcHJpdik7CgoJaWYgKCFkZXZfcHJpdi0+cGFnZV9mbGlwcGluZykKCQlyYWRlb25fZG9faW5pdF9wYWdlZmxpcChkZXYpOwoKCXJhZGVvbl9jcF9kaXNwYXRjaF9mbGlwKGRldik7CgoJQ09NTUlUX1JJTkcoKTsKCXJldHVybiAwOwp9CgpzdGF0aWMgaW50IHJhZGVvbl9jcF9zd2FwKERSTV9JT0NUTF9BUkdTKQp7CglEUk1fREVWSUNFOwoJZHJtX3JhZGVvbl9wcml2YXRlX3QgKmRldl9wcml2ID0gZGV2LT5kZXZfcHJpdmF0ZTsKCWRybV9yYWRlb25fc2FyZWFfdCAqc2FyZWFfcHJpdiA9IGRldl9wcml2LT5zYXJlYV9wcml2OwoJRFJNX0RFQlVHKCJcbiIpOwoKCUxPQ0tfVEVTVF9XSVRIX1JFVFVSTihkZXYsIGZpbHApOwoKCVJJTkdfU1BBQ0VfVEVTVF9XSVRIX1JFVFVSTihkZXZfcHJpdik7CgoJaWYgKHNhcmVhX3ByaXYtPm5ib3ggPiBSQURFT05fTlJfU0FSRUFfQ0xJUFJFQ1RTKQoJCXNhcmVhX3ByaXYtPm5ib3ggPSBSQURFT05fTlJfU0FSRUFfQ0xJUFJFQ1RTOwoKCXJhZGVvbl9jcF9kaXNwYXRjaF9zd2FwKGRldik7CglkZXZfcHJpdi0+c2FyZWFfcHJpdi0+Y3R4X293bmVyID0gMDsKCglDT01NSVRfUklORygpOwoJcmV0dXJuIDA7Cn0KCnN0YXRpYyBpbnQgcmFkZW9uX2NwX3ZlcnRleChEUk1fSU9DVExfQVJHUykKewoJRFJNX0RFVklDRTsKCWRybV9yYWRlb25fcHJpdmF0ZV90ICpkZXZfcHJpdiA9IGRldi0+ZGV2X3ByaXZhdGU7CglzdHJ1Y3QgZHJtX2ZpbGUgKmZpbHBfcHJpdjsKCWRybV9yYWRlb25fc2FyZWFfdCAqc2FyZWFfcHJpdiA9IGRldl9wcml2LT5zYXJlYV9wcml2OwoJc3RydWN0IGRybV9kZXZpY2VfZG1hICpkbWEgPSBkZXYtPmRtYTsKCXN0cnVjdCBkcm1fYnVmICpidWY7Cglkcm1fcmFkZW9uX3ZlcnRleF90IHZlcnRleDsKCWRybV9yYWRlb25fdGNsX3ByaW1fdCBwcmltOwoKCUxPQ0tfVEVTVF9XSVRIX1JFVFVSTihkZXYsIGZpbHApOwoKCURSTV9HRVRfUFJJVl9XSVRIX1JFVFVSTihmaWxwX3ByaXYsIGZpbHApOwoKCURSTV9DT1BZX0ZST01fVVNFUl9JT0NUTCh2ZXJ0ZXgsIChkcm1fcmFkZW9uX3ZlcnRleF90IF9fdXNlciAqKSBkYXRhLAoJCQkJIHNpemVvZih2ZXJ0ZXgpKTsKCglEUk1fREVCVUcoInBpZD0lZCBpbmRleD0lZCBjb3VudD0lZCBkaXNjYXJkPSVkXG4iLAoJCSAgRFJNX0NVUlJFTlRQSUQsIHZlcnRleC5pZHgsIHZlcnRleC5jb3VudCwgdmVydGV4LmRpc2NhcmQpOwoKCWlmICh2ZXJ0ZXguaWR4IDwgMCB8fCB2ZXJ0ZXguaWR4ID49IGRtYS0+YnVmX2NvdW50KSB7CgkJRFJNX0VSUk9SKCJidWZmZXIgaW5kZXggJWQgKG9mICVkIG1heClcbiIsCgkJCSAgdmVydGV4LmlkeCwgZG1hLT5idWZfY291bnQgLSAxKTsKCQlyZXR1cm4gRFJNX0VSUihFSU5WQUwpOwoJfQoJaWYgKHZlcnRleC5wcmltIDwgMCB8fCB2ZXJ0ZXgucHJpbSA+IFJBREVPTl9QUklNX1RZUEVfM1ZSVF9MSU5FX0xJU1QpIHsKCQlEUk1fRVJST1IoImJ1ZmZlciBwcmltICVkXG4iLCB2ZXJ0ZXgucHJpbSk7CgkJcmV0dXJuIERSTV9FUlIoRUlOVkFMKTsKCX0KCglSSU5HX1NQQUNFX1RFU1RfV0lUSF9SRVRVUk4oZGV2X3ByaXYpOwoJVkJfQUdFX1RFU1RfV0lUSF9SRVRVUk4oZGV2X3ByaXYpOwoKCWJ1ZiA9IGRtYS0+YnVmbGlzdFt2ZXJ0ZXguaWR4XTsKCglpZiAoYnVmLT5maWxwICE9IGZpbHApIHsKCQlEUk1fRVJST1IoInByb2Nlc3MgJWQgdXNpbmcgYnVmZmVyIG93bmVkIGJ5ICVwXG4iLAoJCQkgIERSTV9DVVJSRU5UUElELCBidWYtPmZpbHApOwoJCXJldHVybiBEUk1fRVJSKEVJTlZBTCk7Cgl9CglpZiAoYnVmLT5wZW5kaW5nKSB7CgkJRFJNX0VSUk9SKCJzZW5kaW5nIHBlbmRpbmcgYnVmZmVyICVkXG4iLCB2ZXJ0ZXguaWR4KTsKCQlyZXR1cm4gRFJNX0VSUihFSU5WQUwpOwoJfQoKCS8qIEJ1aWxkIHVwIGEgcHJpbV90IHJlY29yZDoKCSAqLwoJaWYgKHZlcnRleC5jb3VudCkgewoJCWJ1Zi0+dXNlZCA9IHZlcnRleC5jb3VudDsJLyogbm90IHVzZWQ/ICovCgoJCWlmIChzYXJlYV9wcml2LT5kaXJ0eSAmIH5SQURFT05fVVBMT0FEX0NMSVBSRUNUUykgewoJCQlpZiAocmFkZW9uX2VtaXRfc3RhdGUoZGV2X3ByaXYsIGZpbHBfcHJpdiwKCQkJCQkgICAgICAmc2FyZWFfcHJpdi0+Y29udGV4dF9zdGF0ZSwKCQkJCQkgICAgICBzYXJlYV9wcml2LT50ZXhfc3RhdGUsCgkJCQkJICAgICAgc2FyZWFfcHJpdi0+ZGlydHkpKSB7CgkJCQlEUk1fRVJST1IoInJhZGVvbl9lbWl0X3N0YXRlIGZhaWxlZFxuIik7CgkJCQlyZXR1cm4gRFJNX0VSUihFSU5WQUwpOwoJCQl9CgoJCQlzYXJlYV9wcml2LT5kaXJ0eSAmPSB+KFJBREVPTl9VUExPQURfVEVYMElNQUdFUyB8CgkJCQkJICAgICAgIFJBREVPTl9VUExPQURfVEVYMUlNQUdFUyB8CgkJCQkJICAgICAgIFJBREVPTl9VUExPQURfVEVYMklNQUdFUyB8CgkJCQkJICAgICAgIFJBREVPTl9SRVFVSVJFX1FVSUVTQ0VOQ0UpOwoJCX0KCgkJcHJpbS5zdGFydCA9IDA7CgkJcHJpbS5maW5pc2ggPSB2ZXJ0ZXguY291bnQ7CS8qIHVudXNlZCAqLwoJCXByaW0ucHJpbSA9IHZlcnRleC5wcmltOwoJCXByaW0ubnVtdmVydHMgPSB2ZXJ0ZXguY291bnQ7CgkJcHJpbS52Y19mb3JtYXQgPSBkZXZfcHJpdi0+c2FyZWFfcHJpdi0+dmNfZm9ybWF0OwoKCQlyYWRlb25fY3BfZGlzcGF0Y2hfdmVydGV4KGRldiwgYnVmLCAmcHJpbSk7Cgl9CgoJaWYgKHZlcnRleC5kaXNjYXJkKSB7CgkJcmFkZW9uX2NwX2Rpc2NhcmRfYnVmZmVyKGRldiwgYnVmKTsKCX0KCglDT01NSVRfUklORygpOwoJcmV0dXJuIDA7Cn0KCnN0YXRpYyBpbnQgcmFkZW9uX2NwX2luZGljZXMoRFJNX0lPQ1RMX0FSR1MpCnsKCURSTV9ERVZJQ0U7Cglkcm1fcmFkZW9uX3ByaXZhdGVfdCAqZGV2X3ByaXYgPSBkZXYtPmRldl9wcml2YXRlOwoJc3RydWN0IGRybV9maWxlICpmaWxwX3ByaXY7Cglkcm1fcmFkZW9uX3NhcmVhX3QgKnNhcmVhX3ByaXYgPSBkZXZfcHJpdi0+c2FyZWFfcHJpdjsKCXN0cnVjdCBkcm1fZGV2aWNlX2RtYSAqZG1hID0gZGV2LT5kbWE7CglzdHJ1Y3QgZHJtX2J1ZiAqYnVmOwoJZHJtX3JhZGVvbl9pbmRpY2VzX3QgZWx0czsKCWRybV9yYWRlb25fdGNsX3ByaW1fdCBwcmltOwoJaW50IGNvdW50OwoKCUxPQ0tfVEVTVF9XSVRIX1JFVFVSTihkZXYsIGZpbHApOwoKCURSTV9HRVRfUFJJVl9XSVRIX1JFVFVSTihmaWxwX3ByaXYsIGZpbHApOwoKCURSTV9DT1BZX0ZST01fVVNFUl9JT0NUTChlbHRzLCAoZHJtX3JhZGVvbl9pbmRpY2VzX3QgX191c2VyICopIGRhdGEsCgkJCQkgc2l6ZW9mKGVsdHMpKTsKCglEUk1fREVCVUcoInBpZD0lZCBpbmRleD0lZCBzdGFydD0lZCBlbmQ9JWQgZGlzY2FyZD0lZFxuIiwKCQkgIERSTV9DVVJSRU5UUElELCBlbHRzLmlkeCwgZWx0cy5zdGFydCwgZWx0cy5lbmQsIGVsdHMuZGlzY2FyZCk7CgoJaWYgKGVsdHMuaWR4IDwgMCB8fCBlbHRzLmlkeCA+PSBkbWEtPmJ1Zl9jb3VudCkgewoJCURSTV9FUlJPUigiYnVmZmVyIGluZGV4ICVkIChvZiAlZCBtYXgpXG4iLAoJCQkgIGVsdHMuaWR4LCBkbWEtPmJ1Zl9jb3VudCAtIDEpOwoJCXJldHVybiBEUk1fRVJSKEVJTlZBTCk7Cgl9CglpZiAoZWx0cy5wcmltIDwgMCB8fCBlbHRzLnByaW0gPiBSQURFT05fUFJJTV9UWVBFXzNWUlRfTElORV9MSVNUKSB7CgkJRFJNX0VSUk9SKCJidWZmZXIgcHJpbSAlZFxuIiwgZWx0cy5wcmltKTsKCQlyZXR1cm4gRFJNX0VSUihFSU5WQUwpOwoJfQoKCVJJTkdfU1BBQ0VfVEVTVF9XSVRIX1JFVFVSTihkZXZfcHJpdik7CglWQl9BR0VfVEVTVF9XSVRIX1JFVFVSTihkZXZfcHJpdik7CgoJYnVmID0gZG1hLT5idWZsaXN0W2VsdHMuaWR4XTsKCglpZiAoYnVmLT5maWxwICE9IGZpbHApIHsKCQlEUk1fRVJST1IoInByb2Nlc3MgJWQgdXNpbmcgYnVmZmVyIG93bmVkIGJ5ICVwXG4iLAoJCQkgIERSTV9DVVJSRU5UUElELCBidWYtPmZpbHApOwoJCXJldHVybiBEUk1fRVJSKEVJTlZBTCk7Cgl9CglpZiAoYnVmLT5wZW5kaW5nKSB7CgkJRFJNX0VSUk9SKCJzZW5kaW5nIHBlbmRpbmcgYnVmZmVyICVkXG4iLCBlbHRzLmlkeCk7CgkJcmV0dXJuIERSTV9FUlIoRUlOVkFMKTsKCX0KCgljb3VudCA9IChlbHRzLmVuZCAtIGVsdHMuc3RhcnQpIC8gc2l6ZW9mKHUxNik7CgllbHRzLnN0YXJ0IC09IFJBREVPTl9JTkRFWF9QUklNX09GRlNFVDsKCglpZiAoZWx0cy5zdGFydCAmIDB4NykgewoJCURSTV9FUlJPUigibWlzYWxpZ25lZCBidWZmZXIgMHgleFxuIiwgZWx0cy5zdGFydCk7CgkJcmV0dXJuIERSTV9FUlIoRUlOVkFMKTsKCX0KCWlmIChlbHRzLnN0YXJ0IDwgYnVmLT51c2VkKSB7CgkJRFJNX0VSUk9SKCJubyBoZWFkZXIgMHgleCAtIDB4JXhcbiIsIGVsdHMuc3RhcnQsIGJ1Zi0+dXNlZCk7CgkJcmV0dXJuIERSTV9FUlIoRUlOVkFMKTsKCX0KCglidWYtPnVzZWQgPSBlbHRzLmVuZDsKCglpZiAoc2FyZWFfcHJpdi0+ZGlydHkgJiB+UkFERU9OX1VQTE9BRF9DTElQUkVDVFMpIHsKCQlpZiAocmFkZW9uX2VtaXRfc3RhdGUoZGV2X3ByaXYsIGZpbHBfcHJpdiwKCQkJCSAgICAgICZzYXJlYV9wcml2LT5jb250ZXh0X3N0YXRlLAoJCQkJICAgICAgc2FyZWFfcHJpdi0+dGV4X3N0YXRlLAoJCQkJICAgICAgc2FyZWFfcHJpdi0+ZGlydHkpKSB7CgkJCURSTV9FUlJPUigicmFkZW9uX2VtaXRfc3RhdGUgZmFpbGVkXG4iKTsKCQkJcmV0dXJuIERSTV9FUlIoRUlOVkFMKTsKCQl9CgoJCXNhcmVhX3ByaXYtPmRpcnR5ICY9IH4oUkFERU9OX1VQTE9BRF9URVgwSU1BR0VTIHwKCQkJCSAgICAgICBSQURFT05fVVBMT0FEX1RFWDFJTUFHRVMgfAoJCQkJICAgICAgIFJBREVPTl9VUExPQURfVEVYMklNQUdFUyB8CgkJCQkgICAgICAgUkFERU9OX1JFUVVJUkVfUVVJRVNDRU5DRSk7Cgl9CgoJLyogQnVpbGQgdXAgYSBwcmltX3QgcmVjb3JkOgoJICovCglwcmltLnN0YXJ0ID0gZWx0cy5zdGFydDsKCXByaW0uZmluaXNoID0gZWx0cy5lbmQ7CglwcmltLnByaW0gPSBlbHRzLnByaW07CglwcmltLm9mZnNldCA9IDA7CS8qIG9mZnNldCBmcm9tIHN0YXJ0IG9mIGRtYSBidWZmZXJzICovCglwcmltLm51bXZlcnRzID0gUkFERU9OX01BWF9WQl9WRVJUUzsJLyogZHVoICovCglwcmltLnZjX2Zvcm1hdCA9IGRldl9wcml2LT5zYXJlYV9wcml2LT52Y19mb3JtYXQ7CgoJcmFkZW9uX2NwX2Rpc3BhdGNoX2luZGljZXMoZGV2LCBidWYsICZwcmltKTsKCWlmIChlbHRzLmRpc2NhcmQpIHsKCQlyYWRlb25fY3BfZGlzY2FyZF9idWZmZXIoZGV2LCBidWYpOwoJfQoKCUNPTU1JVF9SSU5HKCk7CglyZXR1cm4gMDsKfQoKc3RhdGljIGludCByYWRlb25fY3BfdGV4dHVyZShEUk1fSU9DVExfQVJHUykKewoJRFJNX0RFVklDRTsKCWRybV9yYWRlb25fcHJpdmF0ZV90ICpkZXZfcHJpdiA9IGRldi0+ZGV2X3ByaXZhdGU7Cglkcm1fcmFkZW9uX3RleHR1cmVfdCB0ZXg7Cglkcm1fcmFkZW9uX3RleF9pbWFnZV90IGltYWdlOwoJaW50IHJldDsKCglMT0NLX1RFU1RfV0lUSF9SRVRVUk4oZGV2LCBmaWxwKTsKCglEUk1fQ09QWV9GUk9NX1VTRVJfSU9DVEwodGV4LCAoZHJtX3JhZGVvbl90ZXh0dXJlX3QgX191c2VyICopIGRhdGEsCgkJCQkgc2l6ZW9mKHRleCkpOwoKCWlmICh0ZXguaW1hZ2UgPT0gTlVMTCkgewoJCURSTV9FUlJPUigibnVsbCB0ZXh0dXJlIGltYWdlIVxuIik7CgkJcmV0dXJuIERSTV9FUlIoRUlOVkFMKTsKCX0KCglpZiAoRFJNX0NPUFlfRlJPTV9VU0VSKCZpbWFnZSwKCQkJICAgICAgIChkcm1fcmFkZW9uX3RleF9pbWFnZV90IF9fdXNlciAqKSB0ZXguaW1hZ2UsCgkJCSAgICAgICBzaXplb2YoaW1hZ2UpKSkKCQlyZXR1cm4gRFJNX0VSUihFRkFVTFQpOwoKCVJJTkdfU1BBQ0VfVEVTVF9XSVRIX1JFVFVSTihkZXZfcHJpdik7CglWQl9BR0VfVEVTVF9XSVRIX1JFVFVSTihkZXZfcHJpdik7CgoJcmV0ID0gcmFkZW9uX2NwX2Rpc3BhdGNoX3RleHR1cmUoZmlscCwgZGV2LCAmdGV4LCAmaW1hZ2UpOwoKCUNPTU1JVF9SSU5HKCk7CglyZXR1cm4gcmV0Owp9CgpzdGF0aWMgaW50IHJhZGVvbl9jcF9zdGlwcGxlKERSTV9JT0NUTF9BUkdTKQp7CglEUk1fREVWSUNFOwoJZHJtX3JhZGVvbl9wcml2YXRlX3QgKmRldl9wcml2ID0gZGV2LT5kZXZfcHJpdmF0ZTsKCWRybV9yYWRlb25fc3RpcHBsZV90IHN0aXBwbGU7Cgl1MzIgbWFza1szMl07CgoJTE9DS19URVNUX1dJVEhfUkVUVVJOKGRldiwgZmlscCk7CgoJRFJNX0NPUFlfRlJPTV9VU0VSX0lPQ1RMKHN0aXBwbGUsIChkcm1fcmFkZW9uX3N0aXBwbGVfdCBfX3VzZXIgKikgZGF0YSwKCQkJCSBzaXplb2Yoc3RpcHBsZSkpOwoKCWlmIChEUk1fQ09QWV9GUk9NX1VTRVIoJm1hc2ssIHN0aXBwbGUubWFzaywgMzIgKiBzaXplb2YodTMyKSkpCgkJcmV0dXJuIERSTV9FUlIoRUZBVUxUKTsKCglSSU5HX1NQQUNFX1RFU1RfV0lUSF9SRVRVUk4oZGV2X3ByaXYpOwoKCXJhZGVvbl9jcF9kaXNwYXRjaF9zdGlwcGxlKGRldiwgbWFzayk7CgoJQ09NTUlUX1JJTkcoKTsKCXJldHVybiAwOwp9CgpzdGF0aWMgaW50IHJhZGVvbl9jcF9pbmRpcmVjdChEUk1fSU9DVExfQVJHUykKewoJRFJNX0RFVklDRTsKCWRybV9yYWRlb25fcHJpdmF0ZV90ICpkZXZfcHJpdiA9IGRldi0+ZGV2X3ByaXZhdGU7CglzdHJ1Y3QgZHJtX2RldmljZV9kbWEgKmRtYSA9IGRldi0+ZG1hOwoJc3RydWN0IGRybV9idWYgKmJ1ZjsKCWRybV9yYWRlb25faW5kaXJlY3RfdCBpbmRpcmVjdDsKCVJJTkdfTE9DQUxTOwoKCUxPQ0tfVEVTVF9XSVRIX1JFVFVSTihkZXYsIGZpbHApOwoKCURSTV9DT1BZX0ZST01fVVNFUl9JT0NUTChpbmRpcmVjdCwKCQkJCSAoZHJtX3JhZGVvbl9pbmRpcmVjdF90IF9fdXNlciAqKSBkYXRhLAoJCQkJIHNpemVvZihpbmRpcmVjdCkpOwoKCURSTV9ERUJVRygiaW5kaXJlY3Q6IGlkeD0lZCBzPSVkIGU9JWQgZD0lZFxuIiwKCQkgIGluZGlyZWN0LmlkeCwgaW5kaXJlY3Quc3RhcnQsIGluZGlyZWN0LmVuZCwgaW5kaXJlY3QuZGlzY2FyZCk7CgoJaWYgKGluZGlyZWN0LmlkeCA8IDAgfHwgaW5kaXJlY3QuaWR4ID49IGRtYS0+YnVmX2NvdW50KSB7CgkJRFJNX0VSUk9SKCJidWZmZXIgaW5kZXggJWQgKG9mICVkIG1heClcbiIsCgkJCSAgaW5kaXJlY3QuaWR4LCBkbWEtPmJ1Zl9jb3VudCAtIDEpOwoJCXJldHVybiBEUk1fRVJSKEVJTlZBTCk7Cgl9CgoJYnVmID0gZG1hLT5idWZsaXN0W2luZGlyZWN0LmlkeF07CgoJaWYgKGJ1Zi0+ZmlscCAhPSBmaWxwKSB7CgkJRFJNX0VSUk9SKCJwcm9jZXNzICVkIHVzaW5nIGJ1ZmZlciBvd25lZCBieSAlcFxuIiwKCQkJICBEUk1fQ1VSUkVOVFBJRCwgYnVmLT5maWxwKTsKCQlyZXR1cm4gRFJNX0VSUihFSU5WQUwpOwoJfQoJaWYgKGJ1Zi0+cGVuZGluZykgewoJCURSTV9FUlJPUigic2VuZGluZyBwZW5kaW5nIGJ1ZmZlciAlZFxuIiwgaW5kaXJlY3QuaWR4KTsKCQlyZXR1cm4gRFJNX0VSUihFSU5WQUwpOwoJfQoKCWlmIChpbmRpcmVjdC5zdGFydCA8IGJ1Zi0+dXNlZCkgewoJCURSTV9FUlJPUigicmV1c2luZyBpbmRpcmVjdDogc3RhcnQ9MHgleCBhY3R1YWw9MHgleFxuIiwKCQkJICBpbmRpcmVjdC5zdGFydCwgYnVmLT51c2VkKTsKCQlyZXR1cm4gRFJNX0VSUihFSU5WQUwpOwoJfQoKCVJJTkdfU1BBQ0VfVEVTVF9XSVRIX1JFVFVSTihkZXZfcHJpdik7CglWQl9BR0VfVEVTVF9XSVRIX1JFVFVSTihkZXZfcHJpdik7CgoJYnVmLT51c2VkID0gaW5kaXJlY3QuZW5kOwoKCS8qIFdhaXQgZm9yIHRoZSAzRCBzdHJlYW0gdG8gaWRsZSBiZWZvcmUgdGhlIGluZGlyZWN0IGJ1ZmZlcgoJICogY29udGFpbmluZyAyRCBhY2NlbGVyYXRpb24gY29tbWFuZHMgaXMgcHJvY2Vzc2VkLgoJICovCglCRUdJTl9SSU5HKDIpOwoKCVJBREVPTl9XQUlUX1VOVElMXzNEX0lETEUoKTsKCglBRFZBTkNFX1JJTkcoKTsKCgkvKiBEaXNwYXRjaCB0aGUgaW5kaXJlY3QgYnVmZmVyIGZ1bGwgb2YgY29tbWFuZHMgZnJvbSB0aGUKCSAqIFggc2VydmVyLiAgVGhpcyBpcyBpbnNlY3VyZSBhbmQgaXMgdGh1cyBvbmx5IGF2YWlsYWJsZSB0bwoJICogcHJpdmlsZWdlZCBjbGllbnRzLgoJICovCglyYWRlb25fY3BfZGlzcGF0Y2hfaW5kaXJlY3QoZGV2LCBidWYsIGluZGlyZWN0LnN0YXJ0LCBpbmRpcmVjdC5lbmQpOwoJaWYgKGluZGlyZWN0LmRpc2NhcmQpIHsKCQlyYWRlb25fY3BfZGlzY2FyZF9idWZmZXIoZGV2LCBidWYpOwoJfQoKCUNPTU1JVF9SSU5HKCk7CglyZXR1cm4gMDsKfQoKc3RhdGljIGludCByYWRlb25fY3BfdmVydGV4MihEUk1fSU9DVExfQVJHUykKewoJRFJNX0RFVklDRTsKCWRybV9yYWRlb25fcHJpdmF0ZV90ICpkZXZfcHJpdiA9IGRldi0+ZGV2X3ByaXZhdGU7CglzdHJ1Y3QgZHJtX2ZpbGUgKmZpbHBfcHJpdjsKCWRybV9yYWRlb25fc2FyZWFfdCAqc2FyZWFfcHJpdiA9IGRldl9wcml2LT5zYXJlYV9wcml2OwoJc3RydWN0IGRybV9kZXZpY2VfZG1hICpkbWEgPSBkZXYtPmRtYTsKCXN0cnVjdCBkcm1fYnVmICpidWY7Cglkcm1fcmFkZW9uX3ZlcnRleDJfdCB2ZXJ0ZXg7CglpbnQgaTsKCXVuc2lnbmVkIGNoYXIgbGFzdHN0YXRlOwoKCUxPQ0tfVEVTVF9XSVRIX1JFVFVSTihkZXYsIGZpbHApOwoKCURSTV9HRVRfUFJJVl9XSVRIX1JFVFVSTihmaWxwX3ByaXYsIGZpbHApOwoKCURSTV9DT1BZX0ZST01fVVNFUl9JT0NUTCh2ZXJ0ZXgsIChkcm1fcmFkZW9uX3ZlcnRleDJfdCBfX3VzZXIgKikgZGF0YSwKCQkJCSBzaXplb2YodmVydGV4KSk7CgoJRFJNX0RFQlVHKCJwaWQ9JWQgaW5kZXg9JWQgZGlzY2FyZD0lZFxuIiwKCQkgIERSTV9DVVJSRU5UUElELCB2ZXJ0ZXguaWR4LCB2ZXJ0ZXguZGlzY2FyZCk7CgoJaWYgKHZlcnRleC5pZHggPCAwIHx8IHZlcnRleC5pZHggPj0gZG1hLT5idWZfY291bnQpIHsKCQlEUk1fRVJST1IoImJ1ZmZlciBpbmRleCAlZCAob2YgJWQgbWF4KVxuIiwKCQkJICB2ZXJ0ZXguaWR4LCBkbWEtPmJ1Zl9jb3VudCAtIDEpOwoJCXJldHVybiBEUk1fRVJSKEVJTlZBTCk7Cgl9CgoJUklOR19TUEFDRV9URVNUX1dJVEhfUkVUVVJOKGRldl9wcml2KTsKCVZCX0FHRV9URVNUX1dJVEhfUkVUVVJOKGRldl9wcml2KTsKCglidWYgPSBkbWEtPmJ1Zmxpc3RbdmVydGV4LmlkeF07CgoJaWYgKGJ1Zi0+ZmlscCAhPSBmaWxwKSB7CgkJRFJNX0VSUk9SKCJwcm9jZXNzICVkIHVzaW5nIGJ1ZmZlciBvd25lZCBieSAlcFxuIiwKCQkJICBEUk1fQ1VSUkVOVFBJRCwgYnVmLT5maWxwKTsKCQlyZXR1cm4gRFJNX0VSUihFSU5WQUwpOwoJfQoKCWlmIChidWYtPnBlbmRpbmcpIHsKCQlEUk1fRVJST1IoInNlbmRpbmcgcGVuZGluZyBidWZmZXIgJWRcbiIsIHZlcnRleC5pZHgpOwoJCXJldHVybiBEUk1fRVJSKEVJTlZBTCk7Cgl9CgoJaWYgKHNhcmVhX3ByaXYtPm5ib3ggPiBSQURFT05fTlJfU0FSRUFfQ0xJUFJFQ1RTKQoJCXJldHVybiBEUk1fRVJSKEVJTlZBTCk7CgoJZm9yIChsYXN0c3RhdGUgPSAweGZmLCBpID0gMDsgaSA8IHZlcnRleC5ucl9wcmltczsgaSsrKSB7CgkJZHJtX3JhZGVvbl9wcmltX3QgcHJpbTsKCQlkcm1fcmFkZW9uX3RjbF9wcmltX3QgdGNscHJpbTsKCgkJaWYgKERSTV9DT1BZX0ZST01fVVNFUigmcHJpbSwgJnZlcnRleC5wcmltW2ldLCBzaXplb2YocHJpbSkpKQoJCQlyZXR1cm4gRFJNX0VSUihFRkFVTFQpOwoKCQlpZiAocHJpbS5zdGF0ZWlkeCAhPSBsYXN0c3RhdGUpIHsKCQkJZHJtX3JhZGVvbl9zdGF0ZV90IHN0YXRlOwoKCQkJaWYgKERSTV9DT1BZX0ZST01fVVNFUigmc3RhdGUsCgkJCQkJICAgICAgICZ2ZXJ0ZXguc3RhdGVbcHJpbS5zdGF0ZWlkeF0sCgkJCQkJICAgICAgIHNpemVvZihzdGF0ZSkpKQoJCQkJcmV0dXJuIERSTV9FUlIoRUZBVUxUKTsKCgkJCWlmIChyYWRlb25fZW1pdF9zdGF0ZTIoZGV2X3ByaXYsIGZpbHBfcHJpdiwgJnN0YXRlKSkgewoJCQkJRFJNX0VSUk9SKCJyYWRlb25fZW1pdF9zdGF0ZTIgZmFpbGVkXG4iKTsKCQkJCXJldHVybiBEUk1fRVJSKEVJTlZBTCk7CgkJCX0KCgkJCWxhc3RzdGF0ZSA9IHByaW0uc3RhdGVpZHg7CgkJfQoKCQl0Y2xwcmltLnN0YXJ0ID0gcHJpbS5zdGFydDsKCQl0Y2xwcmltLmZpbmlzaCA9IHByaW0uZmluaXNoOwoJCXRjbHByaW0ucHJpbSA9IHByaW0ucHJpbTsKCQl0Y2xwcmltLnZjX2Zvcm1hdCA9IHByaW0udmNfZm9ybWF0OwoKCQlpZiAocHJpbS5wcmltICYgUkFERU9OX1BSSU1fV0FMS19JTkQpIHsKCQkJdGNscHJpbS5vZmZzZXQgPSBwcmltLm51bXZlcnRzICogNjQ7CgkJCXRjbHByaW0ubnVtdmVydHMgPSBSQURFT05fTUFYX1ZCX1ZFUlRTOwkvKiBkdWggKi8KCgkJCXJhZGVvbl9jcF9kaXNwYXRjaF9pbmRpY2VzKGRldiwgYnVmLCAmdGNscHJpbSk7CgkJfSBlbHNlIHsKCQkJdGNscHJpbS5udW12ZXJ0cyA9IHByaW0ubnVtdmVydHM7CgkJCXRjbHByaW0ub2Zmc2V0ID0gMDsJLyogbm90IHVzZWQgKi8KCgkJCXJhZGVvbl9jcF9kaXNwYXRjaF92ZXJ0ZXgoZGV2LCBidWYsICZ0Y2xwcmltKTsKCQl9CgoJCWlmIChzYXJlYV9wcml2LT5uYm94ID09IDEpCgkJCXNhcmVhX3ByaXYtPm5ib3ggPSAwOwoJfQoKCWlmICh2ZXJ0ZXguZGlzY2FyZCkgewoJCXJhZGVvbl9jcF9kaXNjYXJkX2J1ZmZlcihkZXYsIGJ1Zik7Cgl9CgoJQ09NTUlUX1JJTkcoKTsKCXJldHVybiAwOwp9CgpzdGF0aWMgaW50IHJhZGVvbl9lbWl0X3BhY2tldHMoZHJtX3JhZGVvbl9wcml2YXRlX3QgKiBkZXZfcHJpdiwKCQkJICAgICAgIHN0cnVjdCBkcm1fZmlsZSAqIGZpbHBfcHJpdiwKCQkJICAgICAgIGRybV9yYWRlb25fY21kX2hlYWRlcl90IGhlYWRlciwKCQkJICAgICAgIGRybV9yYWRlb25fa2NtZF9idWZmZXJfdCAqY21kYnVmKQp7CglpbnQgaWQgPSAoaW50KWhlYWRlci5wYWNrZXQucGFja2V0X2lkOwoJaW50IHN6LCByZWc7CglpbnQgKmRhdGEgPSAoaW50ICopY21kYnVmLT5idWY7CglSSU5HX0xPQ0FMUzsKCglpZiAoaWQgPj0gUkFERU9OX01BWF9TVEFURV9QQUNLRVRTKQoJCXJldHVybiBEUk1fRVJSKEVJTlZBTCk7CgoJc3ogPSBwYWNrZXRbaWRdLmxlbjsKCXJlZyA9IHBhY2tldFtpZF0uc3RhcnQ7CgoJaWYgKHN6ICogc2l6ZW9mKGludCkgPiBjbWRidWYtPmJ1ZnN6KSB7CgkJRFJNX0VSUk9SKCJQYWNrZXQgc2l6ZSBwcm92aWRlZCBsYXJnZXIgdGhhbiBkYXRhIHByb3ZpZGVkXG4iKTsKCQlyZXR1cm4gRFJNX0VSUihFSU5WQUwpOwoJfQoKCWlmIChyYWRlb25fY2hlY2tfYW5kX2ZpeHVwX3BhY2tldHMoZGV2X3ByaXYsIGZpbHBfcHJpdiwgaWQsIGRhdGEpKSB7CgkJRFJNX0VSUk9SKCJQYWNrZXQgdmVyaWZpY2F0aW9uIGZhaWxlZFxuIik7CgkJcmV0dXJuIERSTV9FUlIoRUlOVkFMKTsKCX0KCglCRUdJTl9SSU5HKHN6ICsgMSk7CglPVVRfUklORyhDUF9QQUNLRVQwKHJlZywgKHN6IC0gMSkpKTsKCU9VVF9SSU5HX1RBQkxFKGRhdGEsIHN6KTsKCUFEVkFOQ0VfUklORygpOwoKCWNtZGJ1Zi0+YnVmICs9IHN6ICogc2l6ZW9mKGludCk7CgljbWRidWYtPmJ1ZnN6IC09IHN6ICogc2l6ZW9mKGludCk7CglyZXR1cm4gMDsKfQoKc3RhdGljIF9faW5saW5lX18gaW50IHJhZGVvbl9lbWl0X3NjYWxhcnMoZHJtX3JhZGVvbl9wcml2YXRlX3QgKmRldl9wcml2LAoJCQkJCSAgZHJtX3JhZGVvbl9jbWRfaGVhZGVyX3QgaGVhZGVyLAoJCQkJCSAgZHJtX3JhZGVvbl9rY21kX2J1ZmZlcl90ICpjbWRidWYpCnsKCWludCBzeiA9IGhlYWRlci5zY2FsYXJzLmNvdW50OwoJaW50IHN0YXJ0ID0gaGVhZGVyLnNjYWxhcnMub2Zmc2V0OwoJaW50IHN0cmlkZSA9IGhlYWRlci5zY2FsYXJzLnN0cmlkZTsKCVJJTkdfTE9DQUxTOwoKCUJFR0lOX1JJTkcoMyArIHN6KTsKCU9VVF9SSU5HKENQX1BBQ0tFVDAoUkFERU9OX1NFX1RDTF9TQ0FMQVJfSU5EWF9SRUcsIDApKTsKCU9VVF9SSU5HKHN0YXJ0IHwgKHN0cmlkZSA8PCBSQURFT05fU0NBTF9JTkRYX0RXT1JEX1NUUklERV9TSElGVCkpOwoJT1VUX1JJTkcoQ1BfUEFDS0VUMF9UQUJMRShSQURFT05fU0VfVENMX1NDQUxBUl9EQVRBX1JFRywgc3ogLSAxKSk7CglPVVRfUklOR19UQUJMRShjbWRidWYtPmJ1Ziwgc3opOwoJQURWQU5DRV9SSU5HKCk7CgljbWRidWYtPmJ1ZiArPSBzeiAqIHNpemVvZihpbnQpOwoJY21kYnVmLT5idWZzeiAtPSBzeiAqIHNpemVvZihpbnQpOwoJcmV0dXJuIDA7Cn0KCi8qIEdvZCB0aGlzIGlzIHVnbHkKICovCnN0YXRpYyBfX2lubGluZV9fIGludCByYWRlb25fZW1pdF9zY2FsYXJzMihkcm1fcmFkZW9uX3ByaXZhdGVfdCAqZGV2X3ByaXYsCgkJCQkJICAgZHJtX3JhZGVvbl9jbWRfaGVhZGVyX3QgaGVhZGVyLAoJCQkJCSAgIGRybV9yYWRlb25fa2NtZF9idWZmZXJfdCAqY21kYnVmKQp7CglpbnQgc3ogPSBoZWFkZXIuc2NhbGFycy5jb3VudDsKCWludCBzdGFydCA9ICgodW5zaWduZWQgaW50KWhlYWRlci5zY2FsYXJzLm9mZnNldCkgKyAweDEwMDsKCWludCBzdHJpZGUgPSBoZWFkZXIuc2NhbGFycy5zdHJpZGU7CglSSU5HX0xPQ0FMUzsKCglCRUdJTl9SSU5HKDMgKyBzeik7CglPVVRfUklORyhDUF9QQUNLRVQwKFJBREVPTl9TRV9UQ0xfU0NBTEFSX0lORFhfUkVHLCAwKSk7CglPVVRfUklORyhzdGFydCB8IChzdHJpZGUgPDwgUkFERU9OX1NDQUxfSU5EWF9EV09SRF9TVFJJREVfU0hJRlQpKTsKCU9VVF9SSU5HKENQX1BBQ0tFVDBfVEFCTEUoUkFERU9OX1NFX1RDTF9TQ0FMQVJfREFUQV9SRUcsIHN6IC0gMSkpOwoJT1VUX1JJTkdfVEFCTEUoY21kYnVmLT5idWYsIHN6KTsKCUFEVkFOQ0VfUklORygpOwoJY21kYnVmLT5idWYgKz0gc3ogKiBzaXplb2YoaW50KTsKCWNtZGJ1Zi0+YnVmc3ogLT0gc3ogKiBzaXplb2YoaW50KTsKCXJldHVybiAwOwp9CgpzdGF0aWMgX19pbmxpbmVfXyBpbnQgcmFkZW9uX2VtaXRfdmVjdG9ycyhkcm1fcmFkZW9uX3ByaXZhdGVfdCAqZGV2X3ByaXYsCgkJCQkJICBkcm1fcmFkZW9uX2NtZF9oZWFkZXJfdCBoZWFkZXIsCgkJCQkJICBkcm1fcmFkZW9uX2tjbWRfYnVmZmVyX3QgKmNtZGJ1ZikKewoJaW50IHN6ID0gaGVhZGVyLnZlY3RvcnMuY291bnQ7CglpbnQgc3RhcnQgPSBoZWFkZXIudmVjdG9ycy5vZmZzZXQ7CglpbnQgc3RyaWRlID0gaGVhZGVyLnZlY3RvcnMuc3RyaWRlOwoJUklOR19MT0NBTFM7CgoJQkVHSU5fUklORyg1ICsgc3opOwoJT1VUX1JJTkdfUkVHKFJBREVPTl9TRV9UQ0xfU1RBVEVfRkxVU0gsIDApOwoJT1VUX1JJTkcoQ1BfUEFDS0VUMChSQURFT05fU0VfVENMX1ZFQ1RPUl9JTkRYX1JFRywgMCkpOwoJT1VUX1JJTkcoc3RhcnQgfCAoc3RyaWRlIDw8IFJBREVPTl9WRUNfSU5EWF9PQ1RXT1JEX1NUUklERV9TSElGVCkpOwoJT1VUX1JJTkcoQ1BfUEFDS0VUMF9UQUJMRShSQURFT05fU0VfVENMX1ZFQ1RPUl9EQVRBX1JFRywgKHN6IC0gMSkpKTsKCU9VVF9SSU5HX1RBQkxFKGNtZGJ1Zi0+YnVmLCBzeik7CglBRFZBTkNFX1JJTkcoKTsKCgljbWRidWYtPmJ1ZiArPSBzeiAqIHNpemVvZihpbnQpOwoJY21kYnVmLT5idWZzeiAtPSBzeiAqIHNpemVvZihpbnQpOwoJcmV0dXJuIDA7Cn0KCnN0YXRpYyBfX2lubGluZV9fIGludCByYWRlb25fZW1pdF92ZWNsaW5lYXIoZHJtX3JhZGVvbl9wcml2YXRlX3QgKmRldl9wcml2LAoJCQkJCSAgZHJtX3JhZGVvbl9jbWRfaGVhZGVyX3QgaGVhZGVyLAoJCQkJCSAgZHJtX3JhZGVvbl9rY21kX2J1ZmZlcl90ICpjbWRidWYpCnsKCWludCBzeiA9IGhlYWRlci52ZWNsaW5lYXIuY291bnQgKiA0OwoJaW50IHN0YXJ0ID0gaGVhZGVyLnZlY2xpbmVhci5hZGRyX2xvIHwgKGhlYWRlci52ZWNsaW5lYXIuYWRkcl9oaSA8PCA4KTsKCVJJTkdfTE9DQUxTOwoKICAgICAgICBpZiAoIXN6KQogICAgICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgaWYgKHN6ICogNCA+IGNtZGJ1Zi0+YnVmc3opCiAgICAgICAgICAgICAgICByZXR1cm4gRFJNX0VSUihFSU5WQUwpOwoKCUJFR0lOX1JJTkcoNSArIHN6KTsKCU9VVF9SSU5HX1JFRyhSQURFT05fU0VfVENMX1NUQVRFX0ZMVVNILCAwKTsKCU9VVF9SSU5HKENQX1BBQ0tFVDAoUkFERU9OX1NFX1RDTF9WRUNUT1JfSU5EWF9SRUcsIDApKTsKCU9VVF9SSU5HKHN0YXJ0IHwgKDEgPDwgUkFERU9OX1ZFQ19JTkRYX09DVFdPUkRfU1RSSURFX1NISUZUKSk7CglPVVRfUklORyhDUF9QQUNLRVQwX1RBQkxFKFJBREVPTl9TRV9UQ0xfVkVDVE9SX0RBVEFfUkVHLCAoc3ogLSAxKSkpOwoJT1VUX1JJTkdfVEFCTEUoY21kYnVmLT5idWYsIHN6KTsKCUFEVkFOQ0VfUklORygpOwoKCWNtZGJ1Zi0+YnVmICs9IHN6ICogc2l6ZW9mKGludCk7CgljbWRidWYtPmJ1ZnN6IC09IHN6ICogc2l6ZW9mKGludCk7CglyZXR1cm4gMDsKfQoKc3RhdGljIGludCByYWRlb25fZW1pdF9wYWNrZXQzKHN0cnVjdCBkcm1fZGV2aWNlICogZGV2LAoJCQkgICAgICAgc3RydWN0IGRybV9maWxlICogZmlscF9wcml2LAoJCQkgICAgICAgZHJtX3JhZGVvbl9rY21kX2J1ZmZlcl90ICpjbWRidWYpCnsKCWRybV9yYWRlb25fcHJpdmF0ZV90ICpkZXZfcHJpdiA9IGRldi0+ZGV2X3ByaXZhdGU7Cgl1bnNpZ25lZCBpbnQgY21kc3o7CglpbnQgcmV0OwoJUklOR19MT0NBTFM7CgoJRFJNX0RFQlVHKCJcbiIpOwoKCWlmICgocmV0ID0gcmFkZW9uX2NoZWNrX2FuZF9maXh1cF9wYWNrZXQzKGRldl9wcml2LCBmaWxwX3ByaXYsCgkJCQkJCSAgY21kYnVmLCAmY21kc3opKSkgewoJCURSTV9FUlJPUigiUGFja2V0IHZlcmlmaWNhdGlvbiBmYWlsZWRcbiIpOwoJCXJldHVybiByZXQ7Cgl9CgoJQkVHSU5fUklORyhjbWRzeik7CglPVVRfUklOR19UQUJMRShjbWRidWYtPmJ1ZiwgY21kc3opOwoJQURWQU5DRV9SSU5HKCk7CgoJY21kYnVmLT5idWYgKz0gY21kc3ogKiA0OwoJY21kYnVmLT5idWZzeiAtPSBjbWRzeiAqIDQ7CglyZXR1cm4gMDsKfQoKc3RhdGljIGludCByYWRlb25fZW1pdF9wYWNrZXQzX2NsaXByZWN0KHN0cnVjdCBkcm1fZGV2aWNlICpkZXYsCgkJCQkJc3RydWN0IGRybV9maWxlICpmaWxwX3ByaXYsCgkJCQkJZHJtX3JhZGVvbl9rY21kX2J1ZmZlcl90ICpjbWRidWYsCgkJCQkJaW50IG9yaWdfbmJveCkKewoJZHJtX3JhZGVvbl9wcml2YXRlX3QgKmRldl9wcml2ID0gZGV2LT5kZXZfcHJpdmF0ZTsKCXN0cnVjdCBkcm1fY2xpcF9yZWN0IGJveDsKCXVuc2lnbmVkIGludCBjbWRzejsKCWludCByZXQ7CglzdHJ1Y3QgZHJtX2NsaXBfcmVjdCBfX3VzZXIgKmJveGVzID0gY21kYnVmLT5ib3hlczsKCWludCBpID0gMDsKCVJJTkdfTE9DQUxTOwoKCURSTV9ERUJVRygiXG4iKTsKCglpZiAoKHJldCA9IHJhZGVvbl9jaGVja19hbmRfZml4dXBfcGFja2V0MyhkZXZfcHJpdiwgZmlscF9wcml2LAoJCQkJCQkgIGNtZGJ1ZiwgJmNtZHN6KSkpIHsKCQlEUk1fRVJST1IoIlBhY2tldCB2ZXJpZmljYXRpb24gZmFpbGVkXG4iKTsKCQlyZXR1cm4gcmV0OwoJfQoKCWlmICghb3JpZ19uYm94KQoJCWdvdG8gb3V0OwoKCWRvIHsKCQlpZiAoaSA8IGNtZGJ1Zi0+bmJveCkgewoJCQlpZiAoRFJNX0NPUFlfRlJPTV9VU0VSKCZib3gsICZib3hlc1tpXSwgc2l6ZW9mKGJveCkpKQoJCQkJcmV0dXJuIERSTV9FUlIoRUZBVUxUKTsKCQkJLyogRklYTUUgVGhlIHNlY29uZCBhbmQgc3Vic2VxdWVudCB0aW1lcyByb3VuZAoJCQkgKiB0aGlzIGxvb3AsIHNlbmQgYSBXQUlUX1VOVElMXzNEX0lETEUgYmVmb3JlCgkJCSAqIGNhbGxpbmcgZW1pdF9jbGlwX3JlY3QoKS4gVGhpcyBmaXhlcyBhCgkJCSAqIGxvY2t1cCBvbiBmYXN0IG1hY2hpbmVzIHdoZW4gc2VuZGluZwoJCQkgKiBzZXZlcmFsIGNsaXByZWN0cyB3aXRoIGEgY21kYnVmLCBhcyB3aGVuCgkJCSAqIHdhdmluZyBhIDJEIHdpbmRvdyBvdmVyIGEgM0QKCQkJICogd2luZG93LiBTb21ldGhpbmcgaW4gdGhlIGNvbW1hbmRzIGZyb20gdXNlcgoJCQkgKiBzcGFjZSBzZWVtcyB0byBoYW5nIHRoZSBjYXJkIHdoZW4gdGhleSdyZQoJCQkgKiBzZW50IHNldmVyYWwgdGltZXMgaW4gYSByb3cuIFRoYXQgd291bGQgYmUKCQkJICogdGhlIGNvcnJlY3QgcGxhY2UgdG8gZml4IGl0IGJ1dCB0aGlzIHdvcmtzCgkJCSAqIGFyb3VuZCBpdCB1bnRpbCBJIGNhbiBmaWd1cmUgdGhhdCBvdXQgLSBUaW0KCQkJICogU21pdGggKi8KCQkJaWYgKGkpIHsKCQkJCUJFR0lOX1JJTkcoMik7CgkJCQlSQURFT05fV0FJVF9VTlRJTF8zRF9JRExFKCk7CgkJCQlBRFZBTkNFX1JJTkcoKTsKCQkJfQoJCQlyYWRlb25fZW1pdF9jbGlwX3JlY3QoZGV2X3ByaXYsICZib3gpOwoJCX0KCgkJQkVHSU5fUklORyhjbWRzeik7CgkJT1VUX1JJTkdfVEFCTEUoY21kYnVmLT5idWYsIGNtZHN6KTsKCQlBRFZBTkNFX1JJTkcoKTsKCgl9IHdoaWxlICgrK2kgPCBjbWRidWYtPm5ib3gpOwoJaWYgKGNtZGJ1Zi0+bmJveCA9PSAxKQoJCWNtZGJ1Zi0+bmJveCA9IDA7CgogICAgICBvdXQ6CgljbWRidWYtPmJ1ZiArPSBjbWRzeiAqIDQ7CgljbWRidWYtPmJ1ZnN6IC09IGNtZHN6ICogNDsKCXJldHVybiAwOwp9CgpzdGF0aWMgaW50IHJhZGVvbl9lbWl0X3dhaXQoc3RydWN0IGRybV9kZXZpY2UgKiBkZXYsIGludCBmbGFncykKewoJZHJtX3JhZGVvbl9wcml2YXRlX3QgKmRldl9wcml2ID0gZGV2LT5kZXZfcHJpdmF0ZTsKCVJJTkdfTE9DQUxTOwoKCURSTV9ERUJVRygiJXM6ICV4XG4iLCBfX0ZVTkNUSU9OX18sIGZsYWdzKTsKCXN3aXRjaCAoZmxhZ3MpIHsKCWNhc2UgUkFERU9OX1dBSVRfMkQ6CgkJQkVHSU5fUklORygyKTsKCQlSQURFT05fV0FJVF9VTlRJTF8yRF9JRExFKCk7CgkJQURWQU5DRV9SSU5HKCk7CgkJYnJlYWs7CgljYXNlIFJBREVPTl9XQUlUXzNEOgoJCUJFR0lOX1JJTkcoMik7CgkJUkFERU9OX1dBSVRfVU5USUxfM0RfSURMRSgpOwoJCUFEVkFOQ0VfUklORygpOwoJCWJyZWFrOwoJY2FzZSBSQURFT05fV0FJVF8yRCB8IFJBREVPTl9XQUlUXzNEOgoJCUJFR0lOX1JJTkcoMik7CgkJUkFERU9OX1dBSVRfVU5USUxfSURMRSgpOwoJCUFEVkFOQ0VfUklORygpOwoJCWJyZWFrOwoJZGVmYXVsdDoKCQlyZXR1cm4gRFJNX0VSUihFSU5WQUwpOwoJfQoKCXJldHVybiAwOwp9CgpzdGF0aWMgaW50IHJhZGVvbl9jcF9jbWRidWYoRFJNX0lPQ1RMX0FSR1MpCnsKCURSTV9ERVZJQ0U7Cglkcm1fcmFkZW9uX3ByaXZhdGVfdCAqZGV2X3ByaXYgPSBkZXYtPmRldl9wcml2YXRlOwoJc3RydWN0IGRybV9maWxlICpmaWxwX3ByaXY7CglzdHJ1Y3QgZHJtX2RldmljZV9kbWEgKmRtYSA9IGRldi0+ZG1hOwoJc3RydWN0IGRybV9idWYgKmJ1ZiA9IE5VTEw7CglpbnQgaWR4OwoJZHJtX3JhZGVvbl9rY21kX2J1ZmZlcl90IGNtZGJ1ZjsKCWRybV9yYWRlb25fY21kX2hlYWRlcl90IGhlYWRlcjsKCWludCBvcmlnX25ib3gsIG9yaWdfYnVmc3o7CgljaGFyICprYnVmID0gTlVMTDsKCglMT0NLX1RFU1RfV0lUSF9SRVRVUk4oZGV2LCBmaWxwKTsKCglEUk1fR0VUX1BSSVZfV0lUSF9SRVRVUk4oZmlscF9wcml2LCBmaWxwKTsKCglEUk1fQ09QWV9GUk9NX1VTRVJfSU9DVEwoY21kYnVmLAoJCQkJIChkcm1fcmFkZW9uX2NtZF9idWZmZXJfdCBfX3VzZXIgKikgZGF0YSwKCQkJCSBzaXplb2YoY21kYnVmKSk7CgoJUklOR19TUEFDRV9URVNUX1dJVEhfUkVUVVJOKGRldl9wcml2KTsKCVZCX0FHRV9URVNUX1dJVEhfUkVUVVJOKGRldl9wcml2KTsKCglpZiAoY21kYnVmLmJ1ZnN6ID4gNjQgKiAxMDI0IHx8IGNtZGJ1Zi5idWZzeiA8IDApIHsKCQlyZXR1cm4gRFJNX0VSUihFSU5WQUwpOwoJfQoKCS8qIEFsbG9jYXRlIGFuIGluLWtlcm5lbCBhcmVhIGFuZCBjb3B5IGluIHRoZSBjbWRidWYuICBEbyB0aGlzIHRvIGF2b2lkCgkgKiByYWNlcyBiZXR3ZWVuIGNoZWNraW5nIHZhbHVlcyBhbmQgdXNpbmcgdGhvc2UgdmFsdWVzIGluIG90aGVyIGNvZGUsCgkgKiBhbmQgc2ltcGx5IHRvIGF2b2lkIGEgbG90IG9mIGZ1bmN0aW9uIGNhbGxzIHRvIGNvcHkgaW4gZGF0YS4KCSAqLwoJb3JpZ19idWZzeiA9IGNtZGJ1Zi5idWZzejsKCWlmIChvcmlnX2J1ZnN6ICE9IDApIHsKCQlrYnVmID0gZHJtX2FsbG9jKGNtZGJ1Zi5idWZzeiwgRFJNX01FTV9EUklWRVIpOwoJCWlmIChrYnVmID09IE5VTEwpCgkJCXJldHVybiBEUk1fRVJSKEVOT01FTSk7CgkJaWYgKERSTV9DT1BZX0ZST01fVVNFUihrYnVmLCAodm9pZCBfX3VzZXIgKiljbWRidWYuYnVmLAoJCQkJICAgICAgIGNtZGJ1Zi5idWZzeikpIHsKCQkJZHJtX2ZyZWUoa2J1Ziwgb3JpZ19idWZzeiwgRFJNX01FTV9EUklWRVIpOwoJCQlyZXR1cm4gRFJNX0VSUihFRkFVTFQpOwoJCX0KCQljbWRidWYuYnVmID0ga2J1ZjsKCX0KCglvcmlnX25ib3ggPSBjbWRidWYubmJveDsKCglpZiAoZGV2X3ByaXYtPm1pY3JvY29kZV92ZXJzaW9uID09IFVDT0RFX1IzMDApIHsKCQlpbnQgdGVtcDsKCQl0ZW1wID0gcjMwMF9kb19jcF9jbWRidWYoZGV2LCBmaWxwLCBmaWxwX3ByaXYsICZjbWRidWYpOwoKCQlpZiAob3JpZ19idWZzeiAhPSAwKQoJCQlkcm1fZnJlZShrYnVmLCBvcmlnX2J1ZnN6LCBEUk1fTUVNX0RSSVZFUik7CgoJCXJldHVybiB0ZW1wOwoJfQoKCS8qIG1pY3JvY29kZV92ZXJzaW9uICE9IHIzMDAgKi8KCXdoaWxlIChjbWRidWYuYnVmc3ogPj0gc2l6ZW9mKGhlYWRlcikpIHsKCgkJaGVhZGVyLmkgPSAqKGludCAqKWNtZGJ1Zi5idWY7CgkJY21kYnVmLmJ1ZiArPSBzaXplb2YoaGVhZGVyKTsKCQljbWRidWYuYnVmc3ogLT0gc2l6ZW9mKGhlYWRlcik7CgoJCXN3aXRjaCAoaGVhZGVyLmhlYWRlci5jbWRfdHlwZSkgewoJCWNhc2UgUkFERU9OX0NNRF9QQUNLRVQ6CgkJCURSTV9ERUJVRygiUkFERU9OX0NNRF9QQUNLRVRcbiIpOwoJCQlpZiAocmFkZW9uX2VtaXRfcGFja2V0cwoJCQkgICAgKGRldl9wcml2LCBmaWxwX3ByaXYsIGhlYWRlciwgJmNtZGJ1ZikpIHsKCQkJCURSTV9FUlJPUigicmFkZW9uX2VtaXRfcGFja2V0cyBmYWlsZWRcbiIpOwoJCQkJZ290byBlcnI7CgkJCX0KCQkJYnJlYWs7CgoJCWNhc2UgUkFERU9OX0NNRF9TQ0FMQVJTOgoJCQlEUk1fREVCVUcoIlJBREVPTl9DTURfU0NBTEFSU1xuIik7CgkJCWlmIChyYWRlb25fZW1pdF9zY2FsYXJzKGRldl9wcml2LCBoZWFkZXIsICZjbWRidWYpKSB7CgkJCQlEUk1fRVJST1IoInJhZGVvbl9lbWl0X3NjYWxhcnMgZmFpbGVkXG4iKTsKCQkJCWdvdG8gZXJyOwoJCQl9CgkJCWJyZWFrOwoKCQljYXNlIFJBREVPTl9DTURfVkVDVE9SUzoKCQkJRFJNX0RFQlVHKCJSQURFT05fQ01EX1ZFQ1RPUlNcbiIpOwoJCQlpZiAocmFkZW9uX2VtaXRfdmVjdG9ycyhkZXZfcHJpdiwgaGVhZGVyLCAmY21kYnVmKSkgewoJCQkJRFJNX0VSUk9SKCJyYWRlb25fZW1pdF92ZWN0b3JzIGZhaWxlZFxuIik7CgkJCQlnb3RvIGVycjsKCQkJfQoJCQlicmVhazsKCgkJY2FzZSBSQURFT05fQ01EX0RNQV9ESVNDQVJEOgoJCQlEUk1fREVCVUcoIlJBREVPTl9DTURfRE1BX0RJU0NBUkRcbiIpOwoJCQlpZHggPSBoZWFkZXIuZG1hLmJ1Zl9pZHg7CgkJCWlmIChpZHggPCAwIHx8IGlkeCA+PSBkbWEtPmJ1Zl9jb3VudCkgewoJCQkJRFJNX0VSUk9SKCJidWZmZXIgaW5kZXggJWQgKG9mICVkIG1heClcbiIsCgkJCQkJICBpZHgsIGRtYS0+YnVmX2NvdW50IC0gMSk7CgkJCQlnb3RvIGVycjsKCQkJfQoKCQkJYnVmID0gZG1hLT5idWZsaXN0W2lkeF07CgkJCWlmIChidWYtPmZpbHAgIT0gZmlscCB8fCBidWYtPnBlbmRpbmcpIHsKCQkJCURSTV9FUlJPUigiYmFkIGJ1ZmZlciAlcCAlcCAlZFxuIiwKCQkJCQkgIGJ1Zi0+ZmlscCwgZmlscCwgYnVmLT5wZW5kaW5nKTsKCQkJCWdvdG8gZXJyOwoJCQl9CgoJCQlyYWRlb25fY3BfZGlzY2FyZF9idWZmZXIoZGV2LCBidWYpOwoJCQlicmVhazsKCgkJY2FzZSBSQURFT05fQ01EX1BBQ0tFVDM6CgkJCURSTV9ERUJVRygiUkFERU9OX0NNRF9QQUNLRVQzXG4iKTsKCQkJaWYgKHJhZGVvbl9lbWl0X3BhY2tldDMoZGV2LCBmaWxwX3ByaXYsICZjbWRidWYpKSB7CgkJCQlEUk1fRVJST1IoInJhZGVvbl9lbWl0X3BhY2tldDMgZmFpbGVkXG4iKTsKCQkJCWdvdG8gZXJyOwoJCQl9CgkJCWJyZWFrOwoKCQljYXNlIFJBREVPTl9DTURfUEFDS0VUM19DTElQOgoJCQlEUk1fREVCVUcoIlJBREVPTl9DTURfUEFDS0VUM19DTElQXG4iKTsKCQkJaWYgKHJhZGVvbl9lbWl0X3BhY2tldDNfY2xpcHJlY3QKCQkJICAgIChkZXYsIGZpbHBfcHJpdiwgJmNtZGJ1Ziwgb3JpZ19uYm94KSkgewoJCQkJRFJNX0VSUk9SKCJyYWRlb25fZW1pdF9wYWNrZXQzX2NsaXAgZmFpbGVkXG4iKTsKCQkJCWdvdG8gZXJyOwoJCQl9CgkJCWJyZWFrOwoKCQljYXNlIFJBREVPTl9DTURfU0NBTEFSUzI6CgkJCURSTV9ERUJVRygiUkFERU9OX0NNRF9TQ0FMQVJTMlxuIik7CgkJCWlmIChyYWRlb25fZW1pdF9zY2FsYXJzMihkZXZfcHJpdiwgaGVhZGVyLCAmY21kYnVmKSkgewoJCQkJRFJNX0VSUk9SKCJyYWRlb25fZW1pdF9zY2FsYXJzMiBmYWlsZWRcbiIpOwoJCQkJZ290byBlcnI7CgkJCX0KCQkJYnJlYWs7CgoJCWNhc2UgUkFERU9OX0NNRF9XQUlUOgoJCQlEUk1fREVCVUcoIlJBREVPTl9DTURfV0FJVFxuIik7CgkJCWlmIChyYWRlb25fZW1pdF93YWl0KGRldiwgaGVhZGVyLndhaXQuZmxhZ3MpKSB7CgkJCQlEUk1fRVJST1IoInJhZGVvbl9lbWl0X3dhaXQgZmFpbGVkXG4iKTsKCQkJCWdvdG8gZXJyOwoJCQl9CgkJCWJyZWFrOwoJCWNhc2UgUkFERU9OX0NNRF9WRUNMSU5FQVI6CgkJCURSTV9ERUJVRygiUkFERU9OX0NNRF9WRUNMSU5FQVJcbiIpOwoJCQlpZiAocmFkZW9uX2VtaXRfdmVjbGluZWFyKGRldl9wcml2LCBoZWFkZXIsICZjbWRidWYpKSB7CgkJCQlEUk1fRVJST1IoInJhZGVvbl9lbWl0X3ZlY2xpbmVhciBmYWlsZWRcbiIpOwoJCQkJZ290byBlcnI7CgkJCX0KCQkJYnJlYWs7CgoJCWRlZmF1bHQ6CgkJCURSTV9FUlJPUigiYmFkIGNtZF90eXBlICVkIGF0ICVwXG4iLAoJCQkJICBoZWFkZXIuaGVhZGVyLmNtZF90eXBlLAoJCQkJICBjbWRidWYuYnVmIC0gc2l6ZW9mKGhlYWRlcikpOwoJCQlnb3RvIGVycjsKCQl9Cgl9CgoJaWYgKG9yaWdfYnVmc3ogIT0gMCkKCQlkcm1fZnJlZShrYnVmLCBvcmlnX2J1ZnN6LCBEUk1fTUVNX0RSSVZFUik7CgoJRFJNX0RFQlVHKCJET05FXG4iKTsKCUNPTU1JVF9SSU5HKCk7CglyZXR1cm4gMDsKCiAgICAgIGVycjoKCWlmIChvcmlnX2J1ZnN6ICE9IDApCgkJZHJtX2ZyZWUoa2J1Ziwgb3JpZ19idWZzeiwgRFJNX01FTV9EUklWRVIpOwoJcmV0dXJuIERSTV9FUlIoRUlOVkFMKTsKfQoKc3RhdGljIGludCByYWRlb25fY3BfZ2V0cGFyYW0oRFJNX0lPQ1RMX0FSR1MpCnsKCURSTV9ERVZJQ0U7Cglkcm1fcmFkZW9uX3ByaXZhdGVfdCAqZGV2X3ByaXYgPSBkZXYtPmRldl9wcml2YXRlOwoJZHJtX3JhZGVvbl9nZXRwYXJhbV90IHBhcmFtOwoJaW50IHZhbHVlOwoKCURSTV9DT1BZX0ZST01fVVNFUl9JT0NUTChwYXJhbSwgKGRybV9yYWRlb25fZ2V0cGFyYW1fdCBfX3VzZXIgKikgZGF0YSwKCQkJCSBzaXplb2YocGFyYW0pKTsKCglEUk1fREVCVUcoInBpZD0lZFxuIiwgRFJNX0NVUlJFTlRQSUQpOwoKCXN3aXRjaCAocGFyYW0ucGFyYW0pIHsKCWNhc2UgUkFERU9OX1BBUkFNX0dBUlRfQlVGRkVSX09GRlNFVDoKCQl2YWx1ZSA9IGRldl9wcml2LT5nYXJ0X2J1ZmZlcnNfb2Zmc2V0OwoJCWJyZWFrOwoJY2FzZSBSQURFT05fUEFSQU1fTEFTVF9GUkFNRToKCQlkZXZfcHJpdi0+c3RhdHMubGFzdF9mcmFtZV9yZWFkcysrOwoJCXZhbHVlID0gR0VUX1NDUkFUQ0goMCk7CgkJYnJlYWs7CgljYXNlIFJBREVPTl9QQVJBTV9MQVNUX0RJU1BBVENIOgoJCXZhbHVlID0gR0VUX1NDUkFUQ0goMSk7CgkJYnJlYWs7CgljYXNlIFJBREVPTl9QQVJBTV9MQVNUX0NMRUFSOgoJCWRldl9wcml2LT5zdGF0cy5sYXN0X2NsZWFyX3JlYWRzKys7CgkJdmFsdWUgPSBHRVRfU0NSQVRDSCgyKTsKCQlicmVhazsKCWNhc2UgUkFERU9OX1BBUkFNX0lSUV9OUjoKCQl2YWx1ZSA9IGRldi0+aXJxOwoJCWJyZWFrOwoJY2FzZSBSQURFT05fUEFSQU1fR0FSVF9CQVNFOgoJCXZhbHVlID0gZGV2X3ByaXYtPmdhcnRfdm1fc3RhcnQ7CgkJYnJlYWs7CgljYXNlIFJBREVPTl9QQVJBTV9SRUdJU1RFUl9IQU5ETEU6CgkJdmFsdWUgPSBkZXZfcHJpdi0+bW1pby0+b2Zmc2V0OwoJCWJyZWFrOwoJY2FzZSBSQURFT05fUEFSQU1fU1RBVFVTX0hBTkRMRToKCQl2YWx1ZSA9IGRldl9wcml2LT5yaW5nX3JwdHJfb2Zmc2V0OwoJCWJyZWFrOwojaWYgQklUU19QRVJfTE9ORyA9PSAzMgoJCS8qCgkJICogVGhpcyBpb2N0bCgpIGRvZXNuJ3Qgd29yayBvbiA2NC1iaXQgcGxhdGZvcm1zIGJlY2F1c2UgaHdfbG9jayBpcyBhCgkJICogcG9pbnRlciB3aGljaCBjYW4ndCBmaXQgaW50byBhbiBpbnQtc2l6ZWQgdmFyaWFibGUuICBBY2NvcmRpbmcgdG8KCQkgKiBNaWNoZWwgRORuemVyLCB0aGUgaW9jdGwoKSBpcyBvbmx5IHVzZWQgb24gZW1iZWRkZWQgcGxhdGZvcm1zLCBzbwoJCSAqIG5vdCBzdXBwb3J0aW5nIGl0IHNob3VsZG4ndCBiZSBhIHByb2JsZW0uICBJZiB0aGUgc2FtZSBmdW5jdGlvbmFsaXR5CgkJICogaXMgbmVlZGVkIG9uIDY0LWJpdCBwbGF0Zm9ybXMsIGEgbmV3IGlvY3RsKCkgd291bGQgaGF2ZSB0byBiZSBhZGRlZCwKCQkgKiBzbyBiYWNrd2FyZHMtY29tcGF0aWJpbGl0eSBmb3IgdGhlIGVtYmVkZGVkIHBsYXRmb3JtcyBjYW4gYmUKCQkgKiBtYWludGFpbmVkLiAgLS1kYXZpZG0gNC1GZWItMjAwNC4KCQkgKi8KCWNhc2UgUkFERU9OX1BBUkFNX1NBUkVBX0hBTkRMRToKCQkvKiBUaGUgbG9jayBpcyB0aGUgZmlyc3QgZHdvcmQgaW4gdGhlIHNhcmVhLiAqLwoJCXZhbHVlID0gKGxvbmcpZGV2LT5sb2NrLmh3X2xvY2s7CgkJYnJlYWs7CiNlbmRpZgoJY2FzZSBSQURFT05fUEFSQU1fR0FSVF9URVhfSEFORExFOgoJCXZhbHVlID0gZGV2X3ByaXYtPmdhcnRfdGV4dHVyZXNfb2Zmc2V0OwoJCWJyZWFrOwoJY2FzZSBSQURFT05fUEFSQU1fU0NSQVRDSF9PRkZTRVQ6CgkJaWYgKCFkZXZfcHJpdi0+d3JpdGViYWNrX3dvcmtzKQoJCQlyZXR1cm4gRFJNX0VSUihFSU5WQUwpOwoJCXZhbHVlID0gUkFERU9OX1NDUkFUQ0hfUkVHX09GRlNFVDsKCQlicmVhazsKCWNhc2UgUkFERU9OX1BBUkFNX0NBUkRfVFlQRToKCQlpZiAoZGV2X3ByaXYtPmZsYWdzICYgUkFERU9OX0lTX1BDSUUpCgkJCXZhbHVlID0gUkFERU9OX0NBUkRfUENJRTsKCQllbHNlIGlmIChkZXZfcHJpdi0+ZmxhZ3MgJiBSQURFT05fSVNfQUdQKQoJCQl2YWx1ZSA9IFJBREVPTl9DQVJEX0FHUDsKCQllbHNlCgkJCXZhbHVlID0gUkFERU9OX0NBUkRfUENJOwoJCWJyZWFrOwoJY2FzZSBSQURFT05fUEFSQU1fVkJMQU5LX0NSVEM6CgkJdmFsdWUgPSByYWRlb25fdmJsYW5rX2NydGNfZ2V0KGRldik7CgkJYnJlYWs7CglkZWZhdWx0OgoJCURSTV9ERUJVRygiSW52YWxpZCBwYXJhbWV0ZXIgJWRcbiIsIHBhcmFtLnBhcmFtKTsKCQlyZXR1cm4gRFJNX0VSUihFSU5WQUwpOwoJfQoKCWlmIChEUk1fQ09QWV9UT19VU0VSKHBhcmFtLnZhbHVlLCAmdmFsdWUsIHNpemVvZihpbnQpKSkgewoJCURSTV9FUlJPUigiY29weV90b191c2VyXG4iKTsKCQlyZXR1cm4gRFJNX0VSUihFRkFVTFQpOwoJfQoKCXJldHVybiAwOwp9CgpzdGF0aWMgaW50IHJhZGVvbl9jcF9zZXRwYXJhbShEUk1fSU9DVExfQVJHUykKewoJRFJNX0RFVklDRTsKCWRybV9yYWRlb25fcHJpdmF0ZV90ICpkZXZfcHJpdiA9IGRldi0+ZGV2X3ByaXZhdGU7CglzdHJ1Y3QgZHJtX2ZpbGUgKmZpbHBfcHJpdjsKCWRybV9yYWRlb25fc2V0cGFyYW1fdCBzcDsKCXN0cnVjdCBkcm1fcmFkZW9uX2RyaXZlcl9maWxlX2ZpZWxkcyAqcmFkZW9uX3ByaXY7CgoJRFJNX0dFVF9QUklWX1dJVEhfUkVUVVJOKGZpbHBfcHJpdiwgZmlscCk7CgoJRFJNX0NPUFlfRlJPTV9VU0VSX0lPQ1RMKHNwLCAoZHJtX3JhZGVvbl9zZXRwYXJhbV90IF9fdXNlciAqKSBkYXRhLAoJCQkJIHNpemVvZihzcCkpOwoKCXN3aXRjaCAoc3AucGFyYW0pIHsKCWNhc2UgUkFERU9OX1NFVFBBUkFNX0ZCX0xPQ0FUSU9OOgoJCXJhZGVvbl9wcml2ID0gZmlscF9wcml2LT5kcml2ZXJfcHJpdjsKCQlyYWRlb25fcHJpdi0+cmFkZW9uX2ZiX2RlbHRhID0gZGV2X3ByaXYtPmZiX2xvY2F0aW9uIC0gc3AudmFsdWU7CgkJYnJlYWs7CgljYXNlIFJBREVPTl9TRVRQQVJBTV9TV0lUQ0hfVElMSU5HOgoJCWlmIChzcC52YWx1ZSA9PSAwKSB7CgkJCURSTV9ERUJVRygiY29sb3IgdGlsaW5nIGRpc2FibGVkXG4iKTsKCQkJZGV2X3ByaXYtPmZyb250X3BpdGNoX29mZnNldCAmPSB+UkFERU9OX0RTVF9USUxFX01BQ1JPOwoJCQlkZXZfcHJpdi0+YmFja19waXRjaF9vZmZzZXQgJj0gflJBREVPTl9EU1RfVElMRV9NQUNSTzsKCQkJZGV2X3ByaXYtPnNhcmVhX3ByaXYtPnRpbGluZ19lbmFibGVkID0gMDsKCQl9IGVsc2UgaWYgKHNwLnZhbHVlID09IDEpIHsKCQkJRFJNX0RFQlVHKCJjb2xvciB0aWxpbmcgZW5hYmxlZFxuIik7CgkJCWRldl9wcml2LT5mcm9udF9waXRjaF9vZmZzZXQgfD0gUkFERU9OX0RTVF9USUxFX01BQ1JPOwoJCQlkZXZfcHJpdi0+YmFja19waXRjaF9vZmZzZXQgfD0gUkFERU9OX0RTVF9USUxFX01BQ1JPOwoJCQlkZXZfcHJpdi0+c2FyZWFfcHJpdi0+dGlsaW5nX2VuYWJsZWQgPSAxOwoJCX0KCQlicmVhazsKCWNhc2UgUkFERU9OX1NFVFBBUkFNX1BDSUdBUlRfTE9DQVRJT046CgkJZGV2X3ByaXYtPnBjaWdhcnRfb2Zmc2V0ID0gc3AudmFsdWU7CgkJZGV2X3ByaXYtPnBjaWdhcnRfb2Zmc2V0X3NldCA9IDE7CgkJYnJlYWs7CgljYXNlIFJBREVPTl9TRVRQQVJBTV9ORVdfTUVNTUFQOgoJCWRldl9wcml2LT5uZXdfbWVtbWFwID0gc3AudmFsdWU7CgkJYnJlYWs7CgljYXNlIFJBREVPTl9TRVRQQVJBTV9QQ0lHQVJUX1RBQkxFX1NJWkU6CgkJZGV2X3ByaXYtPmdhcnRfaW5mby50YWJsZV9zaXplID0gc3AudmFsdWU7CgkJaWYgKGRldl9wcml2LT5nYXJ0X2luZm8udGFibGVfc2l6ZSA8IFJBREVPTl9QQ0lHQVJUX1RBQkxFX1NJWkUpCgkJCWRldl9wcml2LT5nYXJ0X2luZm8udGFibGVfc2l6ZSA9IFJBREVPTl9QQ0lHQVJUX1RBQkxFX1NJWkU7CgkJYnJlYWs7CgljYXNlIFJBREVPTl9TRVRQQVJBTV9WQkxBTktfQ1JUQzoKCQlyZXR1cm4gcmFkZW9uX3ZibGFua19jcnRjX3NldChkZXYsIHNwLnZhbHVlKTsKCQlicmVhazsKCWRlZmF1bHQ6CgkJRFJNX0RFQlVHKCJJbnZhbGlkIHBhcmFtZXRlciAlZFxuIiwgc3AucGFyYW0pOwoJCXJldHVybiBEUk1fRVJSKEVJTlZBTCk7Cgl9CgoJcmV0dXJuIDA7Cn0KCi8qIFdoZW4gYSBjbGllbnQgZGllczoKICogICAgLSBDaGVjayBmb3IgYW5kIGNsZWFuIHVwIGZsaXBwZWQgcGFnZSBzdGF0ZQogKiAgICAtIEZyZWUgYW55IGFsbG9jZWQgR0FSVCBtZW1vcnkuCiAqICAgIC0gRnJlZSBhbnkgYWxsb2NlZCByYWRlb24gc3VyZmFjZXMuCiAqCiAqIERSTSBpbmZyYXN0cnVjdHVyZSB0YWtlcyBjYXJlIG9mIHJlY2xhaW1pbmcgZG1hIGJ1ZmZlcnMuCiAqLwp2b2lkIHJhZGVvbl9kcml2ZXJfcHJlY2xvc2Uoc3RydWN0IGRybV9kZXZpY2UgKmRldiwgRFJNRklMRSBmaWxwKQp7CglpZiAoZGV2LT5kZXZfcHJpdmF0ZSkgewoJCWRybV9yYWRlb25fcHJpdmF0ZV90ICpkZXZfcHJpdiA9IGRldi0+ZGV2X3ByaXZhdGU7CgkJZGV2X3ByaXYtPnBhZ2VfZmxpcHBpbmcgPSAwOwoJCXJhZGVvbl9tZW1fcmVsZWFzZShmaWxwLCBkZXZfcHJpdi0+Z2FydF9oZWFwKTsKCQlyYWRlb25fbWVtX3JlbGVhc2UoZmlscCwgZGV2X3ByaXYtPmZiX2hlYXApOwoJCXJhZGVvbl9zdXJmYWNlc19yZWxlYXNlKGZpbHAsIGRldl9wcml2KTsKCX0KfQoKdm9pZCByYWRlb25fZHJpdmVyX2xhc3RjbG9zZShzdHJ1Y3QgZHJtX2RldmljZSAqZGV2KQp7CglpZiAoZGV2LT5kZXZfcHJpdmF0ZSkgewoJCWRybV9yYWRlb25fcHJpdmF0ZV90ICpkZXZfcHJpdiA9IGRldi0+ZGV2X3ByaXZhdGU7CgoJCWlmIChkZXZfcHJpdi0+c2FyZWFfcHJpdiAmJgoJCSAgICBkZXZfcHJpdi0+c2FyZWFfcHJpdi0+cGZDdXJyZW50UGFnZSAhPSAwKQoJCQlyYWRlb25fY3BfZGlzcGF0Y2hfZmxpcChkZXYpOwoJfQoKCXJhZGVvbl9kb19yZWxlYXNlKGRldik7Cn0KCmludCByYWRlb25fZHJpdmVyX29wZW4oc3RydWN0IGRybV9kZXZpY2UgKmRldiwgc3RydWN0IGRybV9maWxlICpmaWxwX3ByaXYpCnsKCWRybV9yYWRlb25fcHJpdmF0ZV90ICpkZXZfcHJpdiA9IGRldi0+ZGV2X3ByaXZhdGU7CglzdHJ1Y3QgZHJtX3JhZGVvbl9kcml2ZXJfZmlsZV9maWVsZHMgKnJhZGVvbl9wcml2OwoKCURSTV9ERUJVRygiXG4iKTsKCXJhZGVvbl9wcml2ID0KCSAgICAoc3RydWN0IGRybV9yYWRlb25fZHJpdmVyX2ZpbGVfZmllbGRzICopCgkgICAgZHJtX2FsbG9jKHNpemVvZigqcmFkZW9uX3ByaXYpLCBEUk1fTUVNX0ZJTEVTKTsKCglpZiAoIXJhZGVvbl9wcml2KQoJCXJldHVybiAtRU5PTUVNOwoKCWZpbHBfcHJpdi0+ZHJpdmVyX3ByaXYgPSByYWRlb25fcHJpdjsKCglpZiAoZGV2X3ByaXYpCgkJcmFkZW9uX3ByaXYtPnJhZGVvbl9mYl9kZWx0YSA9IGRldl9wcml2LT5mYl9sb2NhdGlvbjsKCWVsc2UKCQlyYWRlb25fcHJpdi0+cmFkZW9uX2ZiX2RlbHRhID0gMDsKCXJldHVybiAwOwp9Cgp2b2lkIHJhZGVvbl9kcml2ZXJfcG9zdGNsb3NlKHN0cnVjdCBkcm1fZGV2aWNlICpkZXYsIHN0cnVjdCBkcm1fZmlsZSAqZmlscF9wcml2KQp7CglzdHJ1Y3QgZHJtX3JhZGVvbl9kcml2ZXJfZmlsZV9maWVsZHMgKnJhZGVvbl9wcml2ID0KCSAgICBmaWxwX3ByaXYtPmRyaXZlcl9wcml2OwoKCWRybV9mcmVlKHJhZGVvbl9wcml2LCBzaXplb2YoKnJhZGVvbl9wcml2KSwgRFJNX01FTV9GSUxFUyk7Cn0KCmRybV9pb2N0bF9kZXNjX3QgcmFkZW9uX2lvY3Rsc1tdID0gewoJW0RSTV9JT0NUTF9OUihEUk1fUkFERU9OX0NQX0lOSVQpXSA9IHtyYWRlb25fY3BfaW5pdCwgRFJNX0FVVEh8RFJNX01BU1RFUnxEUk1fUk9PVF9PTkxZfSwKCVtEUk1fSU9DVExfTlIoRFJNX1JBREVPTl9DUF9TVEFSVCldID0ge3JhZGVvbl9jcF9zdGFydCwgRFJNX0FVVEh8RFJNX01BU1RFUnxEUk1fUk9PVF9PTkxZfSwKCVtEUk1fSU9DVExfTlIoRFJNX1JBREVPTl9DUF9TVE9QKV0gPSB7cmFkZW9uX2NwX3N0b3AsIERSTV9BVVRIfERSTV9NQVNURVJ8RFJNX1JPT1RfT05MWX0sCglbRFJNX0lPQ1RMX05SKERSTV9SQURFT05fQ1BfUkVTRVQpXSA9IHtyYWRlb25fY3BfcmVzZXQsIERSTV9BVVRIfERSTV9NQVNURVJ8RFJNX1JPT1RfT05MWX0sCglbRFJNX0lPQ1RMX05SKERSTV9SQURFT05fQ1BfSURMRSldID0ge3JhZGVvbl9jcF9pZGxlLCBEUk1fQVVUSH0sCglbRFJNX0lPQ1RMX05SKERSTV9SQURFT05fQ1BfUkVTVU1FKV0gPSB7cmFkZW9uX2NwX3Jlc3VtZSwgRFJNX0FVVEh9LAoJW0RSTV9JT0NUTF9OUihEUk1fUkFERU9OX1JFU0VUKV0gPSB7cmFkZW9uX2VuZ2luZV9yZXNldCwgRFJNX0FVVEh9LAoJW0RSTV9JT0NUTF9OUihEUk1fUkFERU9OX0ZVTExTQ1JFRU4pXSA9IHtyYWRlb25fZnVsbHNjcmVlbiwgRFJNX0FVVEh9LAoJW0RSTV9JT0NUTF9OUihEUk1fUkFERU9OX1NXQVApXSA9IHtyYWRlb25fY3Bfc3dhcCwgRFJNX0FVVEh9LAoJW0RSTV9JT0NUTF9OUihEUk1fUkFERU9OX0NMRUFSKV0gPSB7cmFkZW9uX2NwX2NsZWFyLCBEUk1fQVVUSH0sCglbRFJNX0lPQ1RMX05SKERSTV9SQURFT05fVkVSVEVYKV0gPSB7cmFkZW9uX2NwX3ZlcnRleCwgRFJNX0FVVEh9LAoJW0RSTV9JT0NUTF9OUihEUk1fUkFERU9OX0lORElDRVMpXSA9IHtyYWRlb25fY3BfaW5kaWNlcywgRFJNX0FVVEh9LAoJW0RSTV9JT0NUTF9OUihEUk1fUkFERU9OX1RFWFRVUkUpXSA9IHtyYWRlb25fY3BfdGV4dHVyZSwgRFJNX0FVVEh9LAoJW0RSTV9JT0NUTF9OUihEUk1fUkFERU9OX1NUSVBQTEUpXSA9IHtyYWRlb25fY3Bfc3RpcHBsZSwgRFJNX0FVVEh9LAoJW0RSTV9JT0NUTF9OUihEUk1fUkFERU9OX0lORElSRUNUKV0gPSB7cmFkZW9uX2NwX2luZGlyZWN0LCBEUk1fQVVUSHxEUk1fTUFTVEVSfERSTV9ST09UX09OTFl9LAoJW0RSTV9JT0NUTF9OUihEUk1fUkFERU9OX1ZFUlRFWDIpXSA9IHtyYWRlb25fY3BfdmVydGV4MiwgRFJNX0FVVEh9LAoJW0RSTV9JT0NUTF9OUihEUk1fUkFERU9OX0NNREJVRildID0ge3JhZGVvbl9jcF9jbWRidWYsIERSTV9BVVRIfSwKCVtEUk1fSU9DVExfTlIoRFJNX1JBREVPTl9HRVRQQVJBTSldID0ge3JhZGVvbl9jcF9nZXRwYXJhbSwgRFJNX0FVVEh9LAoJW0RSTV9JT0NUTF9OUihEUk1fUkFERU9OX0ZMSVApXSA9IHtyYWRlb25fY3BfZmxpcCwgRFJNX0FVVEh9LAoJW0RSTV9JT0NUTF9OUihEUk1fUkFERU9OX0FMTE9DKV0gPSB7cmFkZW9uX21lbV9hbGxvYywgRFJNX0FVVEh9LAoJW0RSTV9JT0NUTF9OUihEUk1fUkFERU9OX0ZSRUUpXSA9IHtyYWRlb25fbWVtX2ZyZWUsIERSTV9BVVRIfSwKCVtEUk1fSU9DVExfTlIoRFJNX1JBREVPTl9JTklUX0hFQVApXSA9IHtyYWRlb25fbWVtX2luaXRfaGVhcCwgRFJNX0FVVEh8RFJNX01BU1RFUnxEUk1fUk9PVF9PTkxZfSwKCVtEUk1fSU9DVExfTlIoRFJNX1JBREVPTl9JUlFfRU1JVCldID0ge3JhZGVvbl9pcnFfZW1pdCwgRFJNX0FVVEh9LAoJW0RSTV9JT0NUTF9OUihEUk1fUkFERU9OX0lSUV9XQUlUKV0gPSB7cmFkZW9uX2lycV93YWl0LCBEUk1fQVVUSH0sCglbRFJNX0lPQ1RMX05SKERSTV9SQURFT05fU0VUUEFSQU0pXSA9IHtyYWRlb25fY3Bfc2V0cGFyYW0sIERSTV9BVVRIfSwKCVtEUk1fSU9DVExfTlIoRFJNX1JBREVPTl9TVVJGX0FMTE9DKV0gPSB7cmFkZW9uX3N1cmZhY2VfYWxsb2MsIERSTV9BVVRIfSwKCVtEUk1fSU9DVExfTlIoRFJNX1JBREVPTl9TVVJGX0ZSRUUpXSA9IHtyYWRlb25fc3VyZmFjZV9mcmVlLCBEUk1fQVVUSH0KfTsKCmludCByYWRlb25fbWF4X2lvY3RsID0gRFJNX0FSUkFZX1NJWkUocmFkZW9uX2lvY3Rscyk7Cg==