LyoKICogQ29weXJpZ2h0IKkgMjAwNiBJbnRlbCBDb3Jwb3JhdGlvbgogKgogKiBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYQogKiBjb3B5IG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlICJTb2Z0d2FyZSIpLAogKiB0byBkZWFsIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uCiAqIHRoZSByaWdodHMgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLCBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLAogKiBhbmQvb3Igc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0IHBlcnNvbnMgdG8gd2hvbSB0aGUKICogU29mdHdhcmUgaXMgZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczoKICoKICogVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2UgKGluY2x1ZGluZyB0aGUgbmV4dAogKiBwYXJhZ3JhcGgpIHNoYWxsIGJlIGluY2x1ZGVkIGluIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlCiAqIFNvZnR3YXJlLgogKgogKiBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgIkFTIElTIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTUyBPUgogKiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSwKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gIElOIE5PIEVWRU5UIFNIQUxMCiAqIFRIRSBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLCBEQU1BR0VTIE9SIE9USEVSCiAqIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1IgT1RIRVJXSVNFLCBBUklTSU5HIEZST00sCiAqIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRSBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU4gVEhFCiAqIFNPRlRXQVJFLgogKgogKiBBdXRob3JzOgogKiAgICBFcmljIEFuaG9sdCA8ZXJpY0BhbmhvbHQubmV0PgogKgogKi8KI2luY2x1ZGUgImRybVAuaCIKI2luY2x1ZGUgImRybS5oIgojaW5jbHVkZSAiaTkxNV9kcm0uaCIKI2luY2x1ZGUgImk5MTVfZHJ2LmgiCiNpbmNsdWRlICJpbnRlbF9iaW9zLmgiCgojZGVmaW5lCVNMQVZFX0FERFIxCTB4NzAKI2RlZmluZQlTTEFWRV9BRERSMgkweDcyCgpzdGF0aWMgdm9pZCAqCmZpbmRfc2VjdGlvbihzdHJ1Y3QgYmRiX2hlYWRlciAqYmRiLCBpbnQgc2VjdGlvbl9pZCkKewoJdTggKmJhc2UgPSAodTggKiliZGI7CglpbnQgaW5kZXggPSAwOwoJdTE2IHRvdGFsLCBjdXJyZW50X3NpemU7Cgl1OCBjdXJyZW50X2lkOwoKCS8qIHNraXAgdG8gZmlyc3Qgc2VjdGlvbiAqLwoJaW5kZXggKz0gYmRiLT5oZWFkZXJfc2l6ZTsKCXRvdGFsID0gYmRiLT5iZGJfc2l6ZTsKCgkvKiB3YWxrIHRoZSBzZWN0aW9ucyBsb29raW5nIGZvciBzZWN0aW9uX2lkICovCgl3aGlsZSAoaW5kZXggPCB0b3RhbCkgewoJCWN1cnJlbnRfaWQgPSAqKGJhc2UgKyBpbmRleCk7CgkJaW5kZXgrKzsKCQljdXJyZW50X3NpemUgPSAqKCh1MTYgKikoYmFzZSArIGluZGV4KSk7CgkJaW5kZXggKz0gMjsKCQlpZiAoY3VycmVudF9pZCA9PSBzZWN0aW9uX2lkKQoJCQlyZXR1cm4gYmFzZSArIGluZGV4OwoJCWluZGV4ICs9IGN1cnJlbnRfc2l6ZTsKCX0KCglyZXR1cm4gTlVMTDsKfQoKc3RhdGljIHUxNgpnZXRfYmxvY2tzaXplKHZvaWQgKnApCnsKCXUxNiAqYmxvY2tfcHRyLCBibG9ja19zaXplOwoKCWJsb2NrX3B0ciA9ICh1MTYgKikoKGNoYXIgKilwIC0gMik7CglibG9ja19zaXplID0gKmJsb2NrX3B0cjsKCXJldHVybiBibG9ja19zaXplOwp9CgpzdGF0aWMgdm9pZApmaWxsX2RldGFpbF90aW1pbmdfZGF0YShzdHJ1Y3QgZHJtX2Rpc3BsYXlfbW9kZSAqcGFuZWxfZml4ZWRfbW9kZSwKCQkJc3RydWN0IGx2ZHNfZHZvX3RpbWluZyAqZHZvX3RpbWluZykKewoJcGFuZWxfZml4ZWRfbW9kZS0+aGRpc3BsYXkgPSAoZHZvX3RpbWluZy0+aGFjdGl2ZV9oaSA8PCA4KSB8CgkJZHZvX3RpbWluZy0+aGFjdGl2ZV9sbzsKCXBhbmVsX2ZpeGVkX21vZGUtPmhzeW5jX3N0YXJ0ID0gcGFuZWxfZml4ZWRfbW9kZS0+aGRpc3BsYXkgKwoJCSgoZHZvX3RpbWluZy0+aHN5bmNfb2ZmX2hpIDw8IDgpIHwgZHZvX3RpbWluZy0+aHN5bmNfb2ZmX2xvKTsKCXBhbmVsX2ZpeGVkX21vZGUtPmhzeW5jX2VuZCA9IHBhbmVsX2ZpeGVkX21vZGUtPmhzeW5jX3N0YXJ0ICsKCQlkdm9fdGltaW5nLT5oc3luY19wdWxzZV93aWR0aDsKCXBhbmVsX2ZpeGVkX21vZGUtPmh0b3RhbCA9IHBhbmVsX2ZpeGVkX21vZGUtPmhkaXNwbGF5ICsKCQkoKGR2b190aW1pbmctPmhibGFua19oaSA8PCA4KSB8IGR2b190aW1pbmctPmhibGFua19sbyk7CgoJcGFuZWxfZml4ZWRfbW9kZS0+dmRpc3BsYXkgPSAoZHZvX3RpbWluZy0+dmFjdGl2ZV9oaSA8PCA4KSB8CgkJZHZvX3RpbWluZy0+dmFjdGl2ZV9sbzsKCXBhbmVsX2ZpeGVkX21vZGUtPnZzeW5jX3N0YXJ0ID0gcGFuZWxfZml4ZWRfbW9kZS0+dmRpc3BsYXkgKwoJCWR2b190aW1pbmctPnZzeW5jX29mZjsKCXBhbmVsX2ZpeGVkX21vZGUtPnZzeW5jX2VuZCA9IHBhbmVsX2ZpeGVkX21vZGUtPnZzeW5jX3N0YXJ0ICsKCQlkdm9fdGltaW5nLT52c3luY19wdWxzZV93aWR0aDsKCXBhbmVsX2ZpeGVkX21vZGUtPnZ0b3RhbCA9IHBhbmVsX2ZpeGVkX21vZGUtPnZkaXNwbGF5ICsKCQkoKGR2b190aW1pbmctPnZibGFua19oaSA8PCA4KSB8IGR2b190aW1pbmctPnZibGFua19sbyk7CglwYW5lbF9maXhlZF9tb2RlLT5jbG9jayA9IGR2b190aW1pbmctPmNsb2NrICogMTA7CglwYW5lbF9maXhlZF9tb2RlLT50eXBlID0gRFJNX01PREVfVFlQRV9QUkVGRVJSRUQ7CgoJLyogU29tZSBWQlRzIGhhdmUgYm9ndXMgaC92dG90YWwgdmFsdWVzICovCglpZiAocGFuZWxfZml4ZWRfbW9kZS0+aHN5bmNfZW5kID4gcGFuZWxfZml4ZWRfbW9kZS0+aHRvdGFsKQoJCXBhbmVsX2ZpeGVkX21vZGUtPmh0b3RhbCA9IHBhbmVsX2ZpeGVkX21vZGUtPmhzeW5jX2VuZCArIDE7CglpZiAocGFuZWxfZml4ZWRfbW9kZS0+dnN5bmNfZW5kID4gcGFuZWxfZml4ZWRfbW9kZS0+dnRvdGFsKQoJCXBhbmVsX2ZpeGVkX21vZGUtPnZ0b3RhbCA9IHBhbmVsX2ZpeGVkX21vZGUtPnZzeW5jX2VuZCArIDE7CgoJZHJtX21vZGVfc2V0X25hbWUocGFuZWxfZml4ZWRfbW9kZSk7Cn0KCi8qIFRyeSB0byBmaW5kIGludGVncmF0ZWQgcGFuZWwgZGF0YSAqLwpzdGF0aWMgdm9pZApwYXJzZV9sZnBfcGFuZWxfZGF0YShzdHJ1Y3QgZHJtX2k5MTVfcHJpdmF0ZSAqZGV2X3ByaXYsCgkJCSAgICBzdHJ1Y3QgYmRiX2hlYWRlciAqYmRiKQp7CglzdHJ1Y3QgYmRiX2x2ZHNfb3B0aW9ucyAqbHZkc19vcHRpb25zOwoJc3RydWN0IGJkYl9sdmRzX2xmcF9kYXRhICpsdmRzX2xmcF9kYXRhOwoJc3RydWN0IGJkYl9sdmRzX2xmcF9kYXRhX3B0cnMgKmx2ZHNfbGZwX2RhdGFfcHRyczsKCXN0cnVjdCBiZGJfbHZkc19sZnBfZGF0YV9lbnRyeSAqZW50cnk7CglzdHJ1Y3QgbHZkc19kdm9fdGltaW5nICpkdm9fdGltaW5nOwoJc3RydWN0IGRybV9kaXNwbGF5X21vZGUgKnBhbmVsX2ZpeGVkX21vZGU7CglpbnQgbGZwX2RhdGFfc2l6ZSwgZHZvX3RpbWluZ19vZmZzZXQ7CgoJLyogRGVmYXVsdHMgaWYgd2UgY2FuJ3QgZmluZCBWQlQgaW5mbyAqLwoJZGV2X3ByaXYtPmx2ZHNfZGl0aGVyID0gMDsKCWRldl9wcml2LT5sdmRzX3ZidCA9IDA7CgoJbHZkc19vcHRpb25zID0gZmluZF9zZWN0aW9uKGJkYiwgQkRCX0xWRFNfT1BUSU9OUyk7CglpZiAoIWx2ZHNfb3B0aW9ucykKCQlyZXR1cm47CgoJZGV2X3ByaXYtPmx2ZHNfZGl0aGVyID0gbHZkc19vcHRpb25zLT5waXhlbF9kaXRoZXI7CglpZiAobHZkc19vcHRpb25zLT5wYW5lbF90eXBlID09IDB4ZmYpCgkJcmV0dXJuOwoKCWx2ZHNfbGZwX2RhdGEgPSBmaW5kX3NlY3Rpb24oYmRiLCBCREJfTFZEU19MRlBfREFUQSk7CglpZiAoIWx2ZHNfbGZwX2RhdGEpCgkJcmV0dXJuOwoKCWx2ZHNfbGZwX2RhdGFfcHRycyA9IGZpbmRfc2VjdGlvbihiZGIsIEJEQl9MVkRTX0xGUF9EQVRBX1BUUlMpOwoJaWYgKCFsdmRzX2xmcF9kYXRhX3B0cnMpCgkJcmV0dXJuOwoKCWRldl9wcml2LT5sdmRzX3ZidCA9IDE7CgoJbGZwX2RhdGFfc2l6ZSA9IGx2ZHNfbGZwX2RhdGFfcHRycy0+cHRyWzFdLmR2b190aW1pbmdfb2Zmc2V0IC0KCQlsdmRzX2xmcF9kYXRhX3B0cnMtPnB0clswXS5kdm9fdGltaW5nX29mZnNldDsKCWVudHJ5ID0gKHN0cnVjdCBiZGJfbHZkc19sZnBfZGF0YV9lbnRyeSAqKQoJCSgodWludDhfdCAqKWx2ZHNfbGZwX2RhdGEtPmRhdGEgKyAobGZwX2RhdGFfc2l6ZSAqCgkJCQkJCSAgIGx2ZHNfb3B0aW9ucy0+cGFuZWxfdHlwZSkpOwoJZHZvX3RpbWluZ19vZmZzZXQgPSBsdmRzX2xmcF9kYXRhX3B0cnMtPnB0clswXS5kdm9fdGltaW5nX29mZnNldCAtCgkJbHZkc19sZnBfZGF0YV9wdHJzLT5wdHJbMF0uZnBfdGltaW5nX29mZnNldDsKCgkvKgoJICogdGhlIHNpemUgb2YgZnBfdGltaW5nIHZhcmllcyBvbiB0aGUgZGlmZmVyZW50IHBsYXRmb3JtLgoJICogU28gY2FsY3VsYXRlIHRoZSBEVk8gdGltaW5nIHJlbGF0aXZlIG9mZnNldCBpbiBMVkRTIGRhdGEKCSAqIGVudHJ5IHRvIGdldCB0aGUgRFZPIHRpbWluZyBlbnRyeQoJICovCglkdm9fdGltaW5nID0gKHN0cnVjdCBsdmRzX2R2b190aW1pbmcgKikKCQkJKCh1bnNpZ25lZCBjaGFyICopZW50cnkgKyBkdm9fdGltaW5nX29mZnNldCk7CgoJcGFuZWxfZml4ZWRfbW9kZSA9IGt6YWxsb2Moc2l6ZW9mKCpwYW5lbF9maXhlZF9tb2RlKSwgR0ZQX0tFUk5FTCk7CgoJZmlsbF9kZXRhaWxfdGltaW5nX2RhdGEocGFuZWxfZml4ZWRfbW9kZSwgZHZvX3RpbWluZyk7CgoJZGV2X3ByaXYtPmxmcF9sdmRzX3ZidF9tb2RlID0gcGFuZWxfZml4ZWRfbW9kZTsKCglEUk1fREVCVUcoIkZvdW5kIHBhbmVsIG1vZGUgaW4gQklPUyBWQlQgdGFibGVzOlxuIik7Cglkcm1fbW9kZV9kZWJ1Z19wcmludG1vZGVsaW5lKHBhbmVsX2ZpeGVkX21vZGUpOwoKCXJldHVybjsKfQoKLyogVHJ5IHRvIGZpbmQgc2R2byBwYW5lbCBkYXRhICovCnN0YXRpYyB2b2lkCnBhcnNlX3Nkdm9fcGFuZWxfZGF0YShzdHJ1Y3QgZHJtX2k5MTVfcHJpdmF0ZSAqZGV2X3ByaXYsCgkJICAgICAgc3RydWN0IGJkYl9oZWFkZXIgKmJkYikKewoJc3RydWN0IGJkYl9zZHZvX2x2ZHNfb3B0aW9ucyAqc2R2b19sdmRzX29wdGlvbnM7CglzdHJ1Y3QgbHZkc19kdm9fdGltaW5nICpkdm9fdGltaW5nOwoJc3RydWN0IGRybV9kaXNwbGF5X21vZGUgKnBhbmVsX2ZpeGVkX21vZGU7CgoJZGV2X3ByaXYtPnNkdm9fbHZkc192YnRfbW9kZSA9IE5VTEw7CgoJc2R2b19sdmRzX29wdGlvbnMgPSBmaW5kX3NlY3Rpb24oYmRiLCBCREJfU0RWT19MVkRTX09QVElPTlMpOwoJaWYgKCFzZHZvX2x2ZHNfb3B0aW9ucykKCQlyZXR1cm47CgoJZHZvX3RpbWluZyA9IGZpbmRfc2VjdGlvbihiZGIsIEJEQl9TRFZPX1BBTkVMX0RURFMpOwoJaWYgKCFkdm9fdGltaW5nKQoJCXJldHVybjsKCglwYW5lbF9maXhlZF9tb2RlID0ga3phbGxvYyhzaXplb2YoKnBhbmVsX2ZpeGVkX21vZGUpLCBHRlBfS0VSTkVMKTsKCglpZiAoIXBhbmVsX2ZpeGVkX21vZGUpCgkJcmV0dXJuOwoKCWZpbGxfZGV0YWlsX3RpbWluZ19kYXRhKHBhbmVsX2ZpeGVkX21vZGUsCgkJCWR2b190aW1pbmcgKyBzZHZvX2x2ZHNfb3B0aW9ucy0+cGFuZWxfdHlwZSk7CgoJZGV2X3ByaXYtPnNkdm9fbHZkc192YnRfbW9kZSA9IHBhbmVsX2ZpeGVkX21vZGU7CgoJcmV0dXJuOwp9CgpzdGF0aWMgdm9pZApwYXJzZV9nZW5lcmFsX2ZlYXR1cmVzKHN0cnVjdCBkcm1faTkxNV9wcml2YXRlICpkZXZfcHJpdiwKCQkgICAgICAgc3RydWN0IGJkYl9oZWFkZXIgKmJkYikKewoJc3RydWN0IGJkYl9nZW5lcmFsX2ZlYXR1cmVzICpnZW5lcmFsOwoKCS8qIFNldCBzZW5zaWJsZSBkZWZhdWx0cyBpbiBjYXNlIHdlIGNhbid0IGZpbmQgdGhlIGdlbmVyYWwgYmxvY2sgKi8KCWRldl9wcml2LT5pbnRfdHZfc3VwcG9ydCA9IDE7CglkZXZfcHJpdi0+aW50X2NydF9zdXBwb3J0ID0gMTsKCglnZW5lcmFsID0gZmluZF9zZWN0aW9uKGJkYiwgQkRCX0dFTkVSQUxfRkVBVFVSRVMpOwoJaWYgKGdlbmVyYWwpIHsKCQlkZXZfcHJpdi0+aW50X3R2X3N1cHBvcnQgPSBnZW5lcmFsLT5pbnRfdHZfc3VwcG9ydDsKCQlkZXZfcHJpdi0+aW50X2NydF9zdXBwb3J0ID0gZ2VuZXJhbC0+aW50X2NydF9zdXBwb3J0OwoJCWRldl9wcml2LT5sdmRzX3VzZV9zc2MgPSBnZW5lcmFsLT5lbmFibGVfc3NjOwoKCQlpZiAoZGV2X3ByaXYtPmx2ZHNfdXNlX3NzYykgewoJCQlpZiAoSVNfSTg1WChkZXZfcHJpdi0+ZGV2KSkKCQkJCWRldl9wcml2LT5sdmRzX3NzY19mcmVxID0KCQkJCQlnZW5lcmFsLT5zc2NfZnJlcSA/IDY2IDogNDg7CgkJCWVsc2UgaWYgKElTX0lHRE5HKGRldl9wcml2LT5kZXYpKQoJCQkJZGV2X3ByaXYtPmx2ZHNfc3NjX2ZyZXEgPQoJCQkJCWdlbmVyYWwtPnNzY19mcmVxID8gMTAwIDogMTIwOwoJCQllbHNlCgkJCQlkZXZfcHJpdi0+bHZkc19zc2NfZnJlcSA9CgkJCQkJZ2VuZXJhbC0+c3NjX2ZyZXEgPyAxMDAgOiA5NjsKCQl9Cgl9Cn0KCnN0YXRpYyB2b2lkCnBhcnNlX2dlbmVyYWxfZGVmaW5pdGlvbnMoc3RydWN0IGRybV9pOTE1X3ByaXZhdGUgKmRldl9wcml2LAoJCQkgIHN0cnVjdCBiZGJfaGVhZGVyICpiZGIpCnsKCXN0cnVjdCBiZGJfZ2VuZXJhbF9kZWZpbml0aW9ucyAqZ2VuZXJhbDsKCWNvbnN0IGludCBjcnRfYnVzX21hcF90YWJsZVtdID0gewoJCUdQSU9CLAoJCUdQSU9BLAoJCUdQSU9DLAoJCUdQSU9ELAoJCUdQSU9FLAoJCUdQSU9GLAoJfTsKCgkvKiBTZXQgc2Vuc2libGUgZGVmYXVsdHMgaW4gY2FzZSB3ZSBjYW4ndCBmaW5kIHRoZSBnZW5lcmFsIGJsb2NrCgkgICBvciBpdCBpcyB0aGUgd3JvbmcgY2hpcHNldCAqLwoJZGV2X3ByaXYtPmNydF9kZGNfYnVzID0gLTE7CgoJZ2VuZXJhbCA9IGZpbmRfc2VjdGlvbihiZGIsIEJEQl9HRU5FUkFMX0RFRklOSVRJT05TKTsKCWlmIChnZW5lcmFsKSB7CgkJdTE2IGJsb2NrX3NpemUgPSBnZXRfYmxvY2tzaXplKGdlbmVyYWwpOwoJCWlmIChibG9ja19zaXplID49IHNpemVvZigqZ2VuZXJhbCkpIHsKCQkJaW50IGJ1c19waW4gPSBnZW5lcmFsLT5jcnRfZGRjX2dtYnVzX3BpbjsKCQkJRFJNX0RFQlVHKCJjcnRfZGRjX2J1c19waW46ICVkXG4iLCBidXNfcGluKTsKCQkJaWYgKChidXNfcGluID49IDEpICYmIChidXNfcGluIDw9IDYpKSB7CgkJCQlkZXZfcHJpdi0+Y3J0X2RkY19idXMgPQoJCQkJCWNydF9idXNfbWFwX3RhYmxlW2J1c19waW4tMV07CgkJCX0KCQl9IGVsc2UgewoJCQlEUk1fREVCVUcoIkJEQl9HRCB0b28gc21hbGwgKCVkKS4gSW52YWxpZC5cbiIsCgkJCQkgIGJsb2NrX3NpemUpOwoJCX0KCX0KfQoKc3RhdGljIHZvaWQKcGFyc2Vfc2R2b19kZXZpY2VfbWFwcGluZyhzdHJ1Y3QgZHJtX2k5MTVfcHJpdmF0ZSAqZGV2X3ByaXYsCgkJICAgICAgIHN0cnVjdCBiZGJfaGVhZGVyICpiZGIpCnsKCXN0cnVjdCBzZHZvX2RldmljZV9tYXBwaW5nICpwX21hcHBpbmc7CglzdHJ1Y3QgYmRiX2dlbmVyYWxfZGVmaW5pdGlvbnMgKnBfZGVmczsKCXN0cnVjdCBjaGlsZF9kZXZpY2VfY29uZmlnICpwX2NoaWxkOwoJaW50IGksIGNoaWxkX2RldmljZV9udW0sIGNvdW50OwoJdTE2CWJsb2NrX3NpemU7CgoJcF9kZWZzID0gZmluZF9zZWN0aW9uKGJkYiwgQkRCX0dFTkVSQUxfREVGSU5JVElPTlMpOwoJaWYgKCFwX2RlZnMpIHsKCQlEUk1fREVCVUcoIk5vIGdlbmVyYWwgZGVmaW5pdGlvbiBibG9jayBpcyBmb3VuZFxuIik7CgkJcmV0dXJuOwoJfQoJLyoganVkZ2Ugd2hldGhlciB0aGUgc2l6ZSBvZiBjaGlsZCBkZXZpY2UgbWVldHMgdGhlIHJlcXVpcmVtZW50cy4KCSAqIElmIHRoZSBjaGlsZCBkZXZpY2Ugc2l6ZSBvYnRhaW5lZCBmcm9tIGdlbmVyYWwgZGVmaW5pdGlvbiBibG9jawoJICogaXMgZGlmZmVyZW50IHdpdGggc2l6ZW9mKHN0cnVjdCBjaGlsZF9kZXZpY2VfY29uZmlnKSwgc2tpcCB0aGUKCSAqIHBhcnNpbmcgb2Ygc2R2byBkZXZpY2UgaW5mbwoJICovCglpZiAocF9kZWZzLT5jaGlsZF9kZXZfc2l6ZSAhPSBzaXplb2YoKnBfY2hpbGQpKSB7CgkJLyogZGlmZmVyZW50IGNoaWxkIGRldiBzaXplIC4gSWdub3JlIGl0ICovCgkJRFJNX0RFQlVHKCJkaWZmZXJlbnQgY2hpbGQgc2l6ZSBpcyBmb3VuZC4gSW52YWxpZC5cbiIpOwoJCXJldHVybjsKCX0KCS8qIGdldCB0aGUgYmxvY2sgc2l6ZSBvZiBnZW5lcmFsIGRlZmluaXRpb25zICovCglibG9ja19zaXplID0gZ2V0X2Jsb2Nrc2l6ZShwX2RlZnMpOwoJLyogZ2V0IHRoZSBudW1iZXIgb2YgY2hpbGQgZGV2aWNlICovCgljaGlsZF9kZXZpY2VfbnVtID0gKGJsb2NrX3NpemUgLSBzaXplb2YoKnBfZGVmcykpIC8KCQkJCXNpemVvZigqcF9jaGlsZCk7Cgljb3VudCA9IDA7Cglmb3IgKGkgPSAwOyBpIDwgY2hpbGRfZGV2aWNlX251bTsgaSsrKSB7CgkJcF9jaGlsZCA9ICYocF9kZWZzLT5kZXZpY2VzW2ldKTsKCQlpZiAoIXBfY2hpbGQtPmRldmljZV90eXBlKSB7CgkJCS8qIHNraXAgdGhlIGRldmljZSBibG9jayBpZiBkZXZpY2UgdHlwZSBpcyBpbnZhbGlkICovCgkJCWNvbnRpbnVlOwoJCX0KCQlpZiAocF9jaGlsZC0+c2xhdmVfYWRkciAhPSBTTEFWRV9BRERSMSAmJgoJCQlwX2NoaWxkLT5zbGF2ZV9hZGRyICE9IFNMQVZFX0FERFIyKSB7CgkJCS8qCgkJCSAqIElmIHRoZSBzbGF2ZSBhZGRyZXNzIGlzIG5laXRoZXIgMHg3MCBub3IgMHg3MiwKCQkJICogaXQgaXMgbm90IGEgU0RWTyBkZXZpY2UuIFNraXAgaXQuCgkJCSAqLwoJCQljb250aW51ZTsKCQl9CgkJaWYgKHBfY2hpbGQtPmR2b19wb3J0ICE9IERFVklDRV9QT1JUX0RWT0IgJiYKCQkJcF9jaGlsZC0+ZHZvX3BvcnQgIT0gREVWSUNFX1BPUlRfRFZPQykgewoJCQkvKiBza2lwIHRoZSBpbmNvcnJlY3QgU0RWTyBwb3J0ICovCgkJCURSTV9ERUJVRygiSW5jb3JyZWN0IFNEVk8gcG9ydC4gU2tpcCBpdCBcbiIpOwoJCQljb250aW51ZTsKCQl9CgkJRFJNX0RFQlVHKCJ0aGUgU0RWTyBkZXZpY2Ugd2l0aCBzbGF2ZSBhZGRyICUyeCBpcyBmb3VuZCBvbiAiCgkJCQkiJXMgcG9ydFxuIiwKCQkJCXBfY2hpbGQtPnNsYXZlX2FkZHIsCgkJCQkocF9jaGlsZC0+ZHZvX3BvcnQgPT0gREVWSUNFX1BPUlRfRFZPQikgPwoJCQkJCSJTRFZPQiIgOiAiU0RWT0MiKTsKCQlwX21hcHBpbmcgPSAmKGRldl9wcml2LT5zZHZvX21hcHBpbmdzW3BfY2hpbGQtPmR2b19wb3J0IC0gMV0pOwoJCWlmICghcF9tYXBwaW5nLT5pbml0aWFsaXplZCkgewoJCQlwX21hcHBpbmctPmR2b19wb3J0ID0gcF9jaGlsZC0+ZHZvX3BvcnQ7CgkJCXBfbWFwcGluZy0+c2xhdmVfYWRkciA9IHBfY2hpbGQtPnNsYXZlX2FkZHI7CgkJCXBfbWFwcGluZy0+ZHZvX3dpcmluZyA9IHBfY2hpbGQtPmR2b193aXJpbmc7CgkJCXBfbWFwcGluZy0+aW5pdGlhbGl6ZWQgPSAxOwoJCX0gZWxzZSB7CgkJCURSTV9ERUJVRygiTWF5YmUgb25lIFNEVk8gcG9ydCBpcyBzaGFyZWQgYnkgIgoJCQkJCSAidHdvIFNEVk8gZGV2aWNlLlxuIik7CgkJfQoJCWlmIChwX2NoaWxkLT5zbGF2ZTJfYWRkcikgewoJCQkvKiBNYXliZSB0aGlzIGlzIGEgU0RWTyBkZXZpY2Ugd2l0aCBtdWx0aXBsZSBpbnB1dHMgKi8KCQkJLyogQW5kIHRoZSBtYXBwaW5nIGluZm8gaXMgbm90IGFkZGVkICovCgkJCURSTV9ERUJVRygidGhlcmUgZXhpc3RzIHRoZSBzbGF2ZTJfYWRkci4gTWF5YmUgdGhpcyAiCgkJCQkiaXMgYSBTRFZPIGRldmljZSB3aXRoIG11bHRpcGxlIGlucHV0cy5cbiIpOwoJCX0KCQljb3VudCsrOwoJfQoKCWlmICghY291bnQpIHsKCQkvKiBObyBTRFZPIGRldmljZSBpbmZvIGlzIGZvdW5kICovCgkJRFJNX0RFQlVHKCJObyBTRFZPIGRldmljZSBpbmZvIGlzIGZvdW5kIGluIFZCVFxuIik7Cgl9CglyZXR1cm47Cn0KCnN0YXRpYyB2b2lkCnBhcnNlX2RyaXZlcl9mZWF0dXJlcyhzdHJ1Y3QgZHJtX2k5MTVfcHJpdmF0ZSAqZGV2X3ByaXYsCgkJICAgICAgIHN0cnVjdCBiZGJfaGVhZGVyICpiZGIpCnsKCXN0cnVjdCBkcm1fZGV2aWNlICpkZXYgPSBkZXZfcHJpdi0+ZGV2OwoJc3RydWN0IGJkYl9kcml2ZXJfZmVhdHVyZXMgKmRyaXZlcjsKCglkcml2ZXIgPSBmaW5kX3NlY3Rpb24oYmRiLCBCREJfRFJJVkVSX0ZFQVRVUkVTKTsKCWlmICghZHJpdmVyKQoJCXJldHVybjsKCglpZiAoZHJpdmVyICYmIFNVUFBPUlRTX0VEUChkZXYpICYmCgkgICAgZHJpdmVyLT5sdmRzX2NvbmZpZyA9PSBCREJfRFJJVkVSX0ZFQVRVUkVfRURQKSB7CgkJZGV2X3ByaXYtPmVkcF9zdXBwb3J0ID0gMTsKCX0gZWxzZSB7CgkJZGV2X3ByaXYtPmVkcF9zdXBwb3J0ID0gMDsKCX0KCglpZiAoZHJpdmVyICYmIGRyaXZlci0+ZHVhbF9mcmVxdWVuY3kpCgkJZGV2X3ByaXYtPnJlbmRlcl9yZWNsb2NrX2F2YWlsID0gdHJ1ZTsKfQoKLyoqCiAqIGludGVsX2luaXRfYmlvcyAtIGluaXRpYWxpemUgVkJJT1Mgc2V0dGluZ3MgJiBmaW5kIFZCVAogKiBAZGV2OiBEUk0gZGV2aWNlCiAqCiAqIExvYWRzIHRoZSBWaWRlbyBCSU9TIGFuZCBjaGVja3MgdGhhdCB0aGUgVkJUIGV4aXN0cy4gIFNldHMgc2NyYXRjaCByZWdpc3RlcnMKICogdG8gYXBwcm9wcmlhdGUgdmFsdWVzLgogKgogKiBWQlQgZXhpc3RlbmNlIGlzIGEgc2FuaXR5IGNoZWNrIHRoYXQgaXMgcmVsaWVkIG9uIGJ5IG90aGVyIGk4MzBfYmlvcy5jIGNvZGUuCiAqIE5vdGUgdGhhdCBpdCB3b3VsZCBiZSBiZXR0ZXIgdG8gdXNlIGEgQklPUyBjYWxsIHRvIGdldCB0aGUgVkJULCBhcyBCSU9TZXMgbWF5CiAqIGZlZWQgYW4gdXBkYXRlZCBWQlQgYmFjayB0aHJvdWdoIHRoYXQsIGNvbXBhcmVkIHRvIHdoYXQgd2UnbGwgZmV0Y2ggdXNpbmcKICogdGhpcyBtZXRob2Qgb2YgZ3JvcGluZyBhcm91bmQgaW4gdGhlIEJJT1MgZGF0YS4KICoKICogUmV0dXJucyAwIG9uIHN1Y2Nlc3MsIG5vbnplcm8gb24gZmFpbHVyZS4KICovCmJvb2wKaW50ZWxfaW5pdF9iaW9zKHN0cnVjdCBkcm1fZGV2aWNlICpkZXYpCnsKCXN0cnVjdCBkcm1faTkxNV9wcml2YXRlICpkZXZfcHJpdiA9IGRldi0+ZGV2X3ByaXZhdGU7CglzdHJ1Y3QgcGNpX2RldiAqcGRldiA9IGRldi0+cGRldjsKCXN0cnVjdCB2YnRfaGVhZGVyICp2YnQgPSBOVUxMOwoJc3RydWN0IGJkYl9oZWFkZXIgKmJkYjsKCXU4IF9faW9tZW0gKmJpb3M7CglzaXplX3Qgc2l6ZTsKCWludCBpOwoKCWJpb3MgPSBwY2lfbWFwX3JvbShwZGV2LCAmc2l6ZSk7CglpZiAoIWJpb3MpCgkJcmV0dXJuIC0xOwoKCS8qIFNjb3VyIG1lbW9yeSBsb29raW5nIGZvciB0aGUgVkJUIHNpZ25hdHVyZSAqLwoJZm9yIChpID0gMDsgaSArIDQgPCBzaXplOyBpKyspIHsKCQlpZiAoIW1lbWNtcChiaW9zICsgaSwgIiRWQlQiLCA0KSkgewoJCQl2YnQgPSAoc3RydWN0IHZidF9oZWFkZXIgKikoYmlvcyArIGkpOwoJCQlicmVhazsKCQl9Cgl9CgoJaWYgKCF2YnQpIHsKCQlEUk1fRVJST1IoIlZCVCBzaWduYXR1cmUgbWlzc2luZ1xuIik7CgkJcGNpX3VubWFwX3JvbShwZGV2LCBiaW9zKTsKCQlyZXR1cm4gLTE7Cgl9CgoJYmRiID0gKHN0cnVjdCBiZGJfaGVhZGVyICopKGJpb3MgKyBpICsgdmJ0LT5iZGJfb2Zmc2V0KTsKCgkvKiBHcmFiIHVzZWZ1bCBnZW5lcmFsIGRlZmluaXRpb25zICovCglwYXJzZV9nZW5lcmFsX2ZlYXR1cmVzKGRldl9wcml2LCBiZGIpOwoJcGFyc2VfZ2VuZXJhbF9kZWZpbml0aW9ucyhkZXZfcHJpdiwgYmRiKTsKCXBhcnNlX2xmcF9wYW5lbF9kYXRhKGRldl9wcml2LCBiZGIpOwoJcGFyc2Vfc2R2b19wYW5lbF9kYXRhKGRldl9wcml2LCBiZGIpOwoJcGFyc2Vfc2R2b19kZXZpY2VfbWFwcGluZyhkZXZfcHJpdiwgYmRiKTsKCXBhcnNlX2RyaXZlcl9mZWF0dXJlcyhkZXZfcHJpdiwgYmRiKTsKCglwY2lfdW5tYXBfcm9tKHBkZXYsIGJpb3MpOwoKCXJldHVybiAwOwp9Cg==