LyoKICogIGxpbnV4L2ZzL3N1cGVyLmMKICoKICogIENvcHlyaWdodCAoQykgMTk5MSwgMTk5MiAgTGludXMgVG9ydmFsZHMKICoKICogIHN1cGVyLmMgY29udGFpbnMgY29kZSB0byBoYW5kbGU6IC0gbW91bnQgc3RydWN0dXJlcwogKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLSBzdXBlci1ibG9jayB0YWJsZXMKICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC0gZmlsZXN5c3RlbSBkcml2ZXJzIGxpc3QKICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC0gbW91bnQgc3lzdGVtIGNhbGwKICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC0gdW1vdW50IHN5c3RlbSBjYWxsCiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAtIHVzdGF0IHN5c3RlbSBjYWxsCiAqCiAqIEdLIDIvNS85NSAgLSAgQ2hhbmdlZCB0byBzdXBwb3J0IG1vdW50aW5nIHRoZSByb290IGZzIHZpYSBORlMKICoKICogIEFkZGVkIGtlcm5lbGQgc3VwcG9ydDogSmFjcXVlcyBHZWxpbmFzIGFuZCBCam9ybiBFa3dhbGwKICogIEFkZGVkIGNoYW5nZV9yb290OiBXZXJuZXIgQWxtZXNiZXJnZXIgJiBIYW5zIExlcm1lbiwgRmViICc5NgogKiAgQWRkZWQgb3B0aW9ucyB0byAvcHJvYy9tb3VudHM6CiAqICAgIFRvcmJq9nJuIExpbmRoICh0b3Jiam9ybi5saW5kaEBnb3B0YS5zZSksIEFwcmlsIDE0LCAxOTk2LgogKiAgQWRkZWQgZGV2ZnMgc3VwcG9ydDogUmljaGFyZCBHb29jaCA8cmdvb2NoQGF0bmYuY3Npcm8uYXU+LCAxMy1KQU4tMTk5OAogKiAgSGVhdmlseSByZXdyaXR0ZW4gZm9yICdvbmUgZnMgLSBvbmUgdHJlZScgZGNhY2hlIGFyY2hpdGVjdHVyZS4gQVYsIE1hciAyMDAwCiAqLwoKI2luY2x1ZGUgPGxpbnV4L21vZHVsZS5oPgojaW5jbHVkZSA8bGludXgvc2xhYi5oPgojaW5jbHVkZSA8bGludXgvaW5pdC5oPgojaW5jbHVkZSA8bGludXgvc21wX2xvY2suaD4KI2luY2x1ZGUgPGxpbnV4L2FjY3QuaD4KI2luY2x1ZGUgPGxpbnV4L2Jsa2Rldi5oPgojaW5jbHVkZSA8bGludXgvcXVvdGFvcHMuaD4KI2luY2x1ZGUgPGxpbnV4L25hbWVpLmg+CiNpbmNsdWRlIDxsaW51eC9idWZmZXJfaGVhZC5oPgkJLyogZm9yIGZzeW5jX3N1cGVyKCkgKi8KI2luY2x1ZGUgPGxpbnV4L21vdW50Lmg+CiNpbmNsdWRlIDxsaW51eC9zZWN1cml0eS5oPgojaW5jbHVkZSA8bGludXgvc3lzY2FsbHMuaD4KI2luY2x1ZGUgPGxpbnV4L3Zmcy5oPgojaW5jbHVkZSA8bGludXgvd3JpdGViYWNrLmg+CQkvKiBmb3IgdGhlIGVtZXJnZW5jeSByZW1vdW50IHN0dWZmICovCiNpbmNsdWRlIDxsaW51eC9pZHIuaD4KI2luY2x1ZGUgPGxpbnV4L2tvYmplY3QuaD4KI2luY2x1ZGUgPGxpbnV4L211dGV4Lmg+CiNpbmNsdWRlIDxhc20vdWFjY2Vzcy5oPgoKCnZvaWQgZ2V0X2ZpbGVzeXN0ZW0oc3RydWN0IGZpbGVfc3lzdGVtX3R5cGUgKmZzKTsKdm9pZCBwdXRfZmlsZXN5c3RlbShzdHJ1Y3QgZmlsZV9zeXN0ZW1fdHlwZSAqZnMpOwpzdHJ1Y3QgZmlsZV9zeXN0ZW1fdHlwZSAqZ2V0X2ZzX3R5cGUoY29uc3QgY2hhciAqbmFtZSk7CgpMSVNUX0hFQUQoc3VwZXJfYmxvY2tzKTsKREVGSU5FX1NQSU5MT0NLKHNiX2xvY2spOwoKLyoqCiAqCWFsbG9jX3N1cGVyCS0JY3JlYXRlIG5ldyBzdXBlcmJsb2NrCiAqCiAqCUFsbG9jYXRlcyBhbmQgaW5pdGlhbGl6ZXMgYSBuZXcgJnN0cnVjdCBzdXBlcl9ibG9jay4gIGFsbG9jX3N1cGVyKCkKICoJcmV0dXJucyBhIHBvaW50ZXIgbmV3IHN1cGVyYmxvY2sgb3IgJU5VTEwgaWYgYWxsb2NhdGlvbiBoYWQgZmFpbGVkLgogKi8Kc3RhdGljIHN0cnVjdCBzdXBlcl9ibG9jayAqYWxsb2Nfc3VwZXIoc3RydWN0IGZpbGVfc3lzdGVtX3R5cGUgKnR5cGUpCnsKCXN0cnVjdCBzdXBlcl9ibG9jayAqcyA9IGt6YWxsb2Moc2l6ZW9mKHN0cnVjdCBzdXBlcl9ibG9jayksICBHRlBfVVNFUik7CglzdGF0aWMgc3RydWN0IHN1cGVyX29wZXJhdGlvbnMgZGVmYXVsdF9vcDsKCglpZiAocykgewoJCWlmIChzZWN1cml0eV9zYl9hbGxvYyhzKSkgewoJCQlrZnJlZShzKTsKCQkJcyA9IE5VTEw7CgkJCWdvdG8gb3V0OwoJCX0KCQlJTklUX0xJU1RfSEVBRCgmcy0+c19kaXJ0eSk7CgkJSU5JVF9MSVNUX0hFQUQoJnMtPnNfaW8pOwoJCUlOSVRfTElTVF9IRUFEKCZzLT5zX2ZpbGVzKTsKCQlJTklUX0xJU1RfSEVBRCgmcy0+c19pbnN0YW5jZXMpOwoJCUlOSVRfSExJU1RfSEVBRCgmcy0+c19hbm9uKTsKCQlJTklUX0xJU1RfSEVBRCgmcy0+c19pbm9kZXMpOwoJCWluaXRfcndzZW0oJnMtPnNfdW1vdW50KTsKCQltdXRleF9pbml0KCZzLT5zX2xvY2spOwoJCWxvY2tkZXBfc2V0X2NsYXNzKCZzLT5zX3Vtb3VudCwgJnR5cGUtPnNfdW1vdW50X2tleSk7CgkJLyoKCQkgKiBUaGUgbG9ja2luZyBydWxlcyBmb3Igc19sb2NrIGFyZSB1cCB0byB0aGUKCQkgKiBmaWxlc3lzdGVtLiBGb3IgZXhhbXBsZSBleHQzZnMgaGFzIGRpZmZlcmVudAoJCSAqIGxvY2sgb3JkZXJpbmcgdGhhbiB1c2JmczoKCQkgKi8KCQlsb2NrZGVwX3NldF9jbGFzcygmcy0+c19sb2NrLCAmdHlwZS0+c19sb2NrX2tleSk7CgkJZG93bl93cml0ZSgmcy0+c191bW91bnQpOwoJCXMtPnNfY291bnQgPSBTX0JJQVM7CgkJYXRvbWljX3NldCgmcy0+c19hY3RpdmUsIDEpOwoJCW11dGV4X2luaXQoJnMtPnNfdmZzX3JlbmFtZV9tdXRleCk7CgkJbXV0ZXhfaW5pdCgmcy0+c19kcXVvdC5kcWlvX211dGV4KTsKCQltdXRleF9pbml0KCZzLT5zX2RxdW90LmRxb25vZmZfbXV0ZXgpOwoJCWluaXRfcndzZW0oJnMtPnNfZHF1b3QuZHFwdHJfc2VtKTsKCQlpbml0X3dhaXRxdWV1ZV9oZWFkKCZzLT5zX3dhaXRfdW5mcm96ZW4pOwoJCXMtPnNfbWF4Ynl0ZXMgPSBNQVhfTk9OX0xGUzsKCQlzLT5kcV9vcCA9IHNiX2RxdW90X29wczsKCQlzLT5zX3Fjb3AgPSBzYl9xdW90YWN0bF9vcHM7CgkJcy0+c19vcCA9ICZkZWZhdWx0X29wOwoJCXMtPnNfdGltZV9ncmFuID0gMTAwMDAwMDAwMDsKCX0Kb3V0OgoJcmV0dXJuIHM7Cn0KCi8qKgogKglkZXN0cm95X3N1cGVyCS0JZnJlZXMgYSBzdXBlcmJsb2NrCiAqCUBzOiBzdXBlcmJsb2NrIHRvIGZyZWUKICoKICoJRnJlZXMgYSBzdXBlcmJsb2NrLgogKi8Kc3RhdGljIGlubGluZSB2b2lkIGRlc3Ryb3lfc3VwZXIoc3RydWN0IHN1cGVyX2Jsb2NrICpzKQp7CglzZWN1cml0eV9zYl9mcmVlKHMpOwoJa2ZyZWUocyk7Cn0KCi8qIFN1cGVyYmxvY2sgcmVmY291bnRpbmcgICovCgovKgogKiBEcm9wIGEgc3VwZXJibG9jaydzIHJlZmNvdW50LiAgUmV0dXJucyBub24temVybyBpZiB0aGUgc3VwZXJibG9jayB3YXMKICogZGVzdHJveWVkLiAgVGhlIGNhbGxlciBtdXN0IGhvbGQgc2JfbG9jay4KICovCmludCBfX3B1dF9zdXBlcihzdHJ1Y3Qgc3VwZXJfYmxvY2sgKnNiKQp7CglpbnQgcmV0ID0gMDsKCglpZiAoIS0tc2ItPnNfY291bnQpIHsKCQlkZXN0cm95X3N1cGVyKHNiKTsKCQlyZXQgPSAxOwoJfQoJcmV0dXJuIHJldDsKfQoKLyoKICogRHJvcCBhIHN1cGVyYmxvY2sncyByZWZjb3VudC4KICogUmV0dXJucyBub24temVybyBpZiB0aGUgc3VwZXJibG9jayBpcyBhYm91dCB0byBiZSBkZXN0cm95ZWQgYW5kCiAqIGF0IGxlYXN0IGlzIGFscmVhZHkgcmVtb3ZlZCBmcm9tIHN1cGVyX2Jsb2NrcyBsaXN0LCBzbyBpZiB3ZSBhcmUKICogbWFraW5nIGEgbG9vcCB0aHJvdWdoIHN1cGVyIGJsb2NrcyB0aGVuIHdlIG5lZWQgdG8gcmVzdGFydC4KICogVGhlIGNhbGxlciBtdXN0IGhvbGQgc2JfbG9jay4KICovCmludCBfX3B1dF9zdXBlcl9hbmRfbmVlZF9yZXN0YXJ0KHN0cnVjdCBzdXBlcl9ibG9jayAqc2IpCnsKCS8qIGNoZWNrIGZvciByYWNlIHdpdGggZ2VuZXJpY19zaHV0ZG93bl9zdXBlcigpICovCglpZiAobGlzdF9lbXB0eSgmc2ItPnNfbGlzdCkpIHsKCQkvKiBzdXBlciBibG9jayBpcyByZW1vdmVkLCBuZWVkIHRvIHJlc3RhcnQuLi4gKi8KCQlfX3B1dF9zdXBlcihzYik7CgkJcmV0dXJuIDE7Cgl9CgkvKiBjYW4ndCBiZSB0aGUgbGFzdCwgc2luY2Ugc19saXN0IGlzIHN0aWxsIGluIHVzZSAqLwoJc2ItPnNfY291bnQtLTsKCUJVR19PTihzYi0+c19jb3VudCA9PSAwKTsKCXJldHVybiAwOwp9CgovKioKICoJcHV0X3N1cGVyCS0JZHJvcCBhIHRlbXBvcmFyeSByZWZlcmVuY2UgdG8gc3VwZXJibG9jawogKglAc2I6IHN1cGVyYmxvY2sgaW4gcXVlc3Rpb24KICoKICoJRHJvcHMgYSB0ZW1wb3JhcnkgcmVmZXJlbmNlLCBmcmVlcyBzdXBlcmJsb2NrIGlmIHRoZXJlJ3Mgbm8KICoJcmVmZXJlbmNlcyBsZWZ0LgogKi8Kc3RhdGljIHZvaWQgcHV0X3N1cGVyKHN0cnVjdCBzdXBlcl9ibG9jayAqc2IpCnsKCXNwaW5fbG9jaygmc2JfbG9jayk7CglfX3B1dF9zdXBlcihzYik7CglzcGluX3VubG9jaygmc2JfbG9jayk7Cn0KCgovKioKICoJZGVhY3RpdmF0ZV9zdXBlcgktCWRyb3AgYW4gYWN0aXZlIHJlZmVyZW5jZSB0byBzdXBlcmJsb2NrCiAqCUBzOiBzdXBlcmJsb2NrIHRvIGRlYWN0aXZhdGUKICoKICoJRHJvcHMgYW4gYWN0aXZlIHJlZmVyZW5jZSB0byBzdXBlcmJsb2NrLCBhY3F1aXJpbmcgYSB0ZW1wcm9yeSBvbmUgaWYKICoJdGhlcmUgaXMgbm8gYWN0aXZlIHJlZmVyZW5jZXMgbGVmdC4gIEluIHRoYXQgY2FzZSB3ZSBsb2NrIHN1cGVyYmxvY2ssCiAqCXRlbGwgZnMgZHJpdmVyIHRvIHNodXQgaXQgZG93biBhbmQgZHJvcCB0aGUgdGVtcG9yYXJ5IHJlZmVyZW5jZSB3ZQogKgloYWQganVzdCBhY3F1aXJlZC4KICovCnZvaWQgZGVhY3RpdmF0ZV9zdXBlcihzdHJ1Y3Qgc3VwZXJfYmxvY2sgKnMpCnsKCXN0cnVjdCBmaWxlX3N5c3RlbV90eXBlICpmcyA9IHMtPnNfdHlwZTsKCWlmIChhdG9taWNfZGVjX2FuZF9sb2NrKCZzLT5zX2FjdGl2ZSwgJnNiX2xvY2spKSB7CgkJcy0+c19jb3VudCAtPSBTX0JJQVMtMTsKCQlzcGluX3VubG9jaygmc2JfbG9jayk7CgkJRFFVT1RfT0ZGKHMpOwoJCWRvd25fd3JpdGUoJnMtPnNfdW1vdW50KTsKCQlmcy0+a2lsbF9zYihzKTsKCQlwdXRfZmlsZXN5c3RlbShmcyk7CgkJcHV0X3N1cGVyKHMpOwoJfQp9CgpFWFBPUlRfU1lNQk9MKGRlYWN0aXZhdGVfc3VwZXIpOwoKLyoqCiAqCWdyYWJfc3VwZXIgLSBhY3F1aXJlIGFuIGFjdGl2ZSByZWZlcmVuY2UKICoJQHM6IHJlZmVyZW5jZSB3ZSBhcmUgdHJ5aW5nIHRvIG1ha2UgYWN0aXZlCiAqCiAqCVRyaWVzIHRvIGFjcXVpcmUgYW4gYWN0aXZlIHJlZmVyZW5jZS4gIGdyYWJfc3VwZXIoKSBpcyB1c2VkIHdoZW4gd2UKICogCWhhZCBqdXN0IGZvdW5kIGEgc3VwZXJibG9jayBpbiBzdXBlcl9ibG9ja3Mgb3IgZnNfdHlwZS0+ZnNfc3VwZXJzCiAqCWFuZCB3YW50IHRvIHR1cm4gaXQgaW50byBhIGZ1bGwtYmxvd24gYWN0aXZlIHJlZmVyZW5jZS4gIGdyYWJfc3VwZXIoKQogKglpcyBjYWxsZWQgd2l0aCBzYl9sb2NrIGhlbGQgYW5kIGRyb3BzIGl0LiAgUmV0dXJucyAxIGluIGNhc2Ugb2YKICoJc3VjY2VzcywgMCBpZiB3ZSBoYWQgZmFpbGVkIChzdXBlcmJsb2NrIGNvbnRlbnRzIHdhcyBhbHJlYWR5IGRlYWQgb3IKICoJZHlpbmcgd2hlbiBncmFiX3N1cGVyKCkgaGFkIGJlZW4gY2FsbGVkKS4KICovCnN0YXRpYyBpbnQgZ3JhYl9zdXBlcihzdHJ1Y3Qgc3VwZXJfYmxvY2sgKnMpCnsKCXMtPnNfY291bnQrKzsKCXNwaW5fdW5sb2NrKCZzYl9sb2NrKTsKCWRvd25fd3JpdGUoJnMtPnNfdW1vdW50KTsKCWlmIChzLT5zX3Jvb3QpIHsKCQlzcGluX2xvY2soJnNiX2xvY2spOwoJCWlmIChzLT5zX2NvdW50ID4gU19CSUFTKSB7CgkJCWF0b21pY19pbmMoJnMtPnNfYWN0aXZlKTsKCQkJcy0+c19jb3VudC0tOwoJCQlzcGluX3VubG9jaygmc2JfbG9jayk7CgkJCXJldHVybiAxOwoJCX0KCQlzcGluX3VubG9jaygmc2JfbG9jayk7Cgl9Cgl1cF93cml0ZSgmcy0+c191bW91bnQpOwoJcHV0X3N1cGVyKHMpOwoJeWllbGQoKTsKCXJldHVybiAwOwp9CgovKioKICoJZ2VuZXJpY19zaHV0ZG93bl9zdXBlcgktCWNvbW1vbiBoZWxwZXIgZm9yIC0+a2lsbF9zYigpCiAqCUBzYjogc3VwZXJibG9jayB0byBraWxsCiAqCiAqCWdlbmVyaWNfc2h1dGRvd25fc3VwZXIoKSBkb2VzIGFsbCBmcy1pbmRlcGVuZGVudCB3b3JrIG9uIHN1cGVyYmxvY2sKICoJc2h1dGRvd24uICBUeXBpY2FsIC0+a2lsbF9zYigpIHNob3VsZCBwaWNrIGFsbCBmcy1zcGVjaWZpYyBvYmplY3RzCiAqCXRoYXQgbmVlZCBkZXN0cnVjdGlvbiBvdXQgb2Ygc3VwZXJibG9jaywgY2FsbCBnZW5lcmljX3NodXRkb3duX3N1cGVyKCkKICoJYW5kIHJlbGVhc2UgYWZvcmVtZW50aW9uZWQgb2JqZWN0cy4gIE5vdGU6IGRlbnRyaWVzIGFuZCBpbm9kZXMgX2FyZV8KICoJdGFrZW4gY2FyZSBvZiBhbmQgZG8gbm90IG5lZWQgc3BlY2lmaWMgaGFuZGxpbmcuCiAqLwp2b2lkIGdlbmVyaWNfc2h1dGRvd25fc3VwZXIoc3RydWN0IHN1cGVyX2Jsb2NrICpzYikKewoJc3RydWN0IGRlbnRyeSAqcm9vdCA9IHNiLT5zX3Jvb3Q7CglzdHJ1Y3Qgc3VwZXJfb3BlcmF0aW9ucyAqc29wID0gc2ItPnNfb3A7CgoJaWYgKHJvb3QpIHsKCQlzYi0+c19yb290ID0gTlVMTDsKCQlzaHJpbmtfZGNhY2hlX3BhcmVudChyb290KTsKCQlzaHJpbmtfZGNhY2hlX3NiKHNiKTsKCQlkcHV0KHJvb3QpOwoJCWZzeW5jX3N1cGVyKHNiKTsKCQlsb2NrX3N1cGVyKHNiKTsKCQlzYi0+c19mbGFncyAmPSB+TVNfQUNUSVZFOwoJCS8qIGJhZCBuYW1lIC0gaXQgc2hvdWxkIGJlIGV2aWN0X2lub2RlcygpICovCgkJaW52YWxpZGF0ZV9pbm9kZXMoc2IpOwoJCWxvY2tfa2VybmVsKCk7CgoJCWlmIChzb3AtPndyaXRlX3N1cGVyICYmIHNiLT5zX2RpcnQpCgkJCXNvcC0+d3JpdGVfc3VwZXIoc2IpOwoJCWlmIChzb3AtPnB1dF9zdXBlcikKCQkJc29wLT5wdXRfc3VwZXIoc2IpOwoKCQkvKiBGb3JnZXQgYW55IHJlbWFpbmluZyBpbm9kZXMgKi8KCQlpZiAoaW52YWxpZGF0ZV9pbm9kZXMoc2IpKSB7CgkJCXByaW50aygiVkZTOiBCdXN5IGlub2RlcyBhZnRlciB1bm1vdW50IG9mICVzLiAiCgkJCSAgICJTZWxmLWRlc3RydWN0IGluIDUgc2Vjb25kcy4gIEhhdmUgYSBuaWNlIGRheS4uLlxuIiwKCQkJICAgc2ItPnNfaWQpOwoJCX0KCgkJdW5sb2NrX2tlcm5lbCgpOwoJCXVubG9ja19zdXBlcihzYik7Cgl9CglzcGluX2xvY2soJnNiX2xvY2spOwoJLyogc2hvdWxkIGJlIGluaXRpYWxpemVkIGZvciBfX3B1dF9zdXBlcl9hbmRfbmVlZF9yZXN0YXJ0KCkgKi8KCWxpc3RfZGVsX2luaXQoJnNiLT5zX2xpc3QpOwoJbGlzdF9kZWwoJnNiLT5zX2luc3RhbmNlcyk7CglzcGluX3VubG9jaygmc2JfbG9jayk7Cgl1cF93cml0ZSgmc2ItPnNfdW1vdW50KTsKfQoKRVhQT1JUX1NZTUJPTChnZW5lcmljX3NodXRkb3duX3N1cGVyKTsKCi8qKgogKglzZ2V0CS0JZmluZCBvciBjcmVhdGUgYSBzdXBlcmJsb2NrCiAqCUB0eXBlOglmaWxlc3lzdGVtIHR5cGUgc3VwZXJibG9jayBzaG91bGQgYmVsb25nIHRvCiAqCUB0ZXN0Ogljb21wYXJpc29uIGNhbGxiYWNrCiAqCUBzZXQ6CXNldHVwIGNhbGxiYWNrCiAqCUBkYXRhOglhcmd1bWVudCB0byBlYWNoIG9mIHRoZW0KICovCnN0cnVjdCBzdXBlcl9ibG9jayAqc2dldChzdHJ1Y3QgZmlsZV9zeXN0ZW1fdHlwZSAqdHlwZSwKCQkJaW50ICgqdGVzdCkoc3RydWN0IHN1cGVyX2Jsb2NrICosdm9pZCAqKSwKCQkJaW50ICgqc2V0KShzdHJ1Y3Qgc3VwZXJfYmxvY2sgKix2b2lkICopLAoJCQl2b2lkICpkYXRhKQp7CglzdHJ1Y3Qgc3VwZXJfYmxvY2sgKnMgPSBOVUxMOwoJc3RydWN0IGxpc3RfaGVhZCAqcDsKCWludCBlcnI7CgpyZXRyeToKCXNwaW5fbG9jaygmc2JfbG9jayk7CglpZiAodGVzdCkgbGlzdF9mb3JfZWFjaChwLCAmdHlwZS0+ZnNfc3VwZXJzKSB7CgkJc3RydWN0IHN1cGVyX2Jsb2NrICpvbGQ7CgkJb2xkID0gbGlzdF9lbnRyeShwLCBzdHJ1Y3Qgc3VwZXJfYmxvY2ssIHNfaW5zdGFuY2VzKTsKCQlpZiAoIXRlc3Qob2xkLCBkYXRhKSkKCQkJY29udGludWU7CgkJaWYgKCFncmFiX3N1cGVyKG9sZCkpCgkJCWdvdG8gcmV0cnk7CgkJaWYgKHMpCgkJCWRlc3Ryb3lfc3VwZXIocyk7CgkJcmV0dXJuIG9sZDsKCX0KCWlmICghcykgewoJCXNwaW5fdW5sb2NrKCZzYl9sb2NrKTsKCQlzID0gYWxsb2Nfc3VwZXIodHlwZSk7CgkJaWYgKCFzKQoJCQlyZXR1cm4gRVJSX1BUUigtRU5PTUVNKTsKCQlnb3RvIHJldHJ5OwoJfQoJCQoJZXJyID0gc2V0KHMsIGRhdGEpOwoJaWYgKGVycikgewoJCXNwaW5fdW5sb2NrKCZzYl9sb2NrKTsKCQlkZXN0cm95X3N1cGVyKHMpOwoJCXJldHVybiBFUlJfUFRSKGVycik7Cgl9CglzLT5zX3R5cGUgPSB0eXBlOwoJc3RybGNweShzLT5zX2lkLCB0eXBlLT5uYW1lLCBzaXplb2Yocy0+c19pZCkpOwoJbGlzdF9hZGRfdGFpbCgmcy0+c19saXN0LCAmc3VwZXJfYmxvY2tzKTsKCWxpc3RfYWRkKCZzLT5zX2luc3RhbmNlcywgJnR5cGUtPmZzX3N1cGVycyk7CglzcGluX3VubG9jaygmc2JfbG9jayk7CglnZXRfZmlsZXN5c3RlbSh0eXBlKTsKCXJldHVybiBzOwp9CgpFWFBPUlRfU1lNQk9MKHNnZXQpOwoKdm9pZCBkcm9wX3N1cGVyKHN0cnVjdCBzdXBlcl9ibG9jayAqc2IpCnsKCXVwX3JlYWQoJnNiLT5zX3Vtb3VudCk7CglwdXRfc3VwZXIoc2IpOwp9CgpFWFBPUlRfU1lNQk9MKGRyb3Bfc3VwZXIpOwoKc3RhdGljIGlubGluZSB2b2lkIHdyaXRlX3N1cGVyKHN0cnVjdCBzdXBlcl9ibG9jayAqc2IpCnsKCWxvY2tfc3VwZXIoc2IpOwoJaWYgKHNiLT5zX3Jvb3QgJiYgc2ItPnNfZGlydCkKCQlpZiAoc2ItPnNfb3AtPndyaXRlX3N1cGVyKQoJCQlzYi0+c19vcC0+d3JpdGVfc3VwZXIoc2IpOwoJdW5sb2NrX3N1cGVyKHNiKTsKfQoKLyoKICogTm90ZTogY2hlY2sgdGhlIGRpcnR5IGZsYWcgYmVmb3JlIHdhaXRpbmcsIHNvIHdlIGRvbid0CiAqIGhvbGQgdXAgdGhlIHN5bmMgd2hpbGUgbW91bnRpbmcgYSBkZXZpY2UuIChUaGUgbmV3bHkKICogbW91bnRlZCBkZXZpY2Ugd29uJ3QgbmVlZCBzeW5jaW5nLikKICovCnZvaWQgc3luY19zdXBlcnModm9pZCkKewoJc3RydWN0IHN1cGVyX2Jsb2NrICpzYjsKCglzcGluX2xvY2soJnNiX2xvY2spOwpyZXN0YXJ0OgoJbGlzdF9mb3JfZWFjaF9lbnRyeShzYiwgJnN1cGVyX2Jsb2Nrcywgc19saXN0KSB7CgkJaWYgKHNiLT5zX2RpcnQpIHsKCQkJc2ItPnNfY291bnQrKzsKCQkJc3Bpbl91bmxvY2soJnNiX2xvY2spOwoJCQlkb3duX3JlYWQoJnNiLT5zX3Vtb3VudCk7CgkJCXdyaXRlX3N1cGVyKHNiKTsKCQkJdXBfcmVhZCgmc2ItPnNfdW1vdW50KTsKCQkJc3Bpbl9sb2NrKCZzYl9sb2NrKTsKCQkJaWYgKF9fcHV0X3N1cGVyX2FuZF9uZWVkX3Jlc3RhcnQoc2IpKQoJCQkJZ290byByZXN0YXJ0OwoJCX0KCX0KCXNwaW5fdW5sb2NrKCZzYl9sb2NrKTsKfQoKLyoKICogQ2FsbCB0aGUgLT5zeW5jX2ZzIHN1cGVyX29wIGFnYWluc3QgYWxsIGZpbGVzeXRlbXMgd2hpY2ggYXJlIHIvdyBhbmQKICogd2hpY2ggaW1wbGVtZW50IGl0LgogKgogKiBUaGlzIG9wZXJhdGlvbiBpcyBjYXJlZnVsIHRvIGF2b2lkIHRoZSBsaXZlbG9jayB3aGljaCBjb3VsZCBlYXNpbHkgaGFwcGVuCiAqIGlmIHR3byBvciBtb3JlIGZpbGVzeXN0ZW1zIGFyZSBiZWluZyBjb250aW51b3VzbHkgZGlydGllZC4gIHNfbmVlZF9zeW5jX2ZzCiAqIGlzIHVzZWQgb25seSBoZXJlLiAgV2Ugc2V0IGl0IGFnYWluc3QgYWxsIGZpbGVzeXN0ZW1zIGFuZCB0aGVuIGNsZWFyIGl0IGFzCiAqIHdlIHN5bmMgdGhlbS4gIFNvIHJlZGlydGllZCBmaWxlc3lzdGVtcyBhcmUgc2tpcHBlZC4KICoKICogQnV0IGlmIHByb2Nlc3MgQSBpcyBjdXJyZW50bHkgcnVubmluZyBzeW5jX2ZpbGVzeXRlbXMgYW5kIHRoZW4gcHJvY2VzcyBCCiAqIGNhbGxzIHN5bmNfZmlsZXN5c3RlbXMgYXMgd2VsbCwgcHJvY2VzcyBCIHdpbGwgc2V0IGFsbCB0aGUgc19uZWVkX3N5bmNfZnMKICogZmxhZ3MgYWdhaW4sIHdoaWNoIHdpbGwgY2F1c2UgcHJvY2VzcyBBIHRvIHJlc3luYyBldmVyeXRoaW5nLiAgRml4IHRoYXQgd2l0aAogKiBhIGxvY2FsIG11dGV4LgogKgogKiAoRmFiaWFuKSBBdm9pZCBzeW5jX2ZzIHdpdGggY2xlYW4gZnMgJiB3YWl0IG1vZGUgMAogKi8Kdm9pZCBzeW5jX2ZpbGVzeXN0ZW1zKGludCB3YWl0KQp7CglzdHJ1Y3Qgc3VwZXJfYmxvY2sgKnNiOwoJc3RhdGljIERFRklORV9NVVRFWChtdXRleCk7CgoJbXV0ZXhfbG9jaygmbXV0ZXgpOwkJLyogQ291bGQgYmUgZG93bl9pbnRlcnJ1cHRpYmxlICovCglzcGluX2xvY2soJnNiX2xvY2spOwoJbGlzdF9mb3JfZWFjaF9lbnRyeShzYiwgJnN1cGVyX2Jsb2Nrcywgc19saXN0KSB7CgkJaWYgKCFzYi0+c19vcC0+c3luY19mcykKCQkJY29udGludWU7CgkJaWYgKHNiLT5zX2ZsYWdzICYgTVNfUkRPTkxZKQoJCQljb250aW51ZTsKCQlzYi0+c19uZWVkX3N5bmNfZnMgPSAxOwoJfQoKcmVzdGFydDoKCWxpc3RfZm9yX2VhY2hfZW50cnkoc2IsICZzdXBlcl9ibG9ja3MsIHNfbGlzdCkgewoJCWlmICghc2ItPnNfbmVlZF9zeW5jX2ZzKQoJCQljb250aW51ZTsKCQlzYi0+c19uZWVkX3N5bmNfZnMgPSAwOwoJCWlmIChzYi0+c19mbGFncyAmIE1TX1JET05MWSkKCQkJY29udGludWU7CS8qIGhtLiAgV2FzIHJlbW91bnRlZCByL28gbWVhbndoaWxlICovCgkJc2ItPnNfY291bnQrKzsKCQlzcGluX3VubG9jaygmc2JfbG9jayk7CgkJZG93bl9yZWFkKCZzYi0+c191bW91bnQpOwoJCWlmIChzYi0+c19yb290ICYmICh3YWl0IHx8IHNiLT5zX2RpcnQpKQoJCQlzYi0+c19vcC0+c3luY19mcyhzYiwgd2FpdCk7CgkJdXBfcmVhZCgmc2ItPnNfdW1vdW50KTsKCQkvKiByZXN0YXJ0IG9ubHkgd2hlbiBzYiBpcyBubyBsb25nZXIgb24gdGhlIGxpc3QgKi8KCQlzcGluX2xvY2soJnNiX2xvY2spOwoJCWlmIChfX3B1dF9zdXBlcl9hbmRfbmVlZF9yZXN0YXJ0KHNiKSkKCQkJZ290byByZXN0YXJ0OwoJfQoJc3Bpbl91bmxvY2soJnNiX2xvY2spOwoJbXV0ZXhfdW5sb2NrKCZtdXRleCk7Cn0KCi8qKgogKglnZXRfc3VwZXIgLSBnZXQgdGhlIHN1cGVyYmxvY2sgb2YgYSBkZXZpY2UKICoJQGJkZXY6IGRldmljZSB0byBnZXQgdGhlIHN1cGVyYmxvY2sgZm9yCiAqCQogKglTY2FucyB0aGUgc3VwZXJibG9jayBsaXN0IGFuZCBmaW5kcyB0aGUgc3VwZXJibG9jayBvZiB0aGUgZmlsZSBzeXN0ZW0KICoJbW91bnRlZCBvbiB0aGUgZGV2aWNlIGdpdmVuLiAlTlVMTCBpcyByZXR1cm5lZCBpZiBubyBtYXRjaCBpcyBmb3VuZC4KICovCgpzdHJ1Y3Qgc3VwZXJfYmxvY2sgKiBnZXRfc3VwZXIoc3RydWN0IGJsb2NrX2RldmljZSAqYmRldikKewoJc3RydWN0IHN1cGVyX2Jsb2NrICpzYjsKCglpZiAoIWJkZXYpCgkJcmV0dXJuIE5VTEw7CgoJc3Bpbl9sb2NrKCZzYl9sb2NrKTsKcmVzY2FuOgoJbGlzdF9mb3JfZWFjaF9lbnRyeShzYiwgJnN1cGVyX2Jsb2Nrcywgc19saXN0KSB7CgkJaWYgKHNiLT5zX2JkZXYgPT0gYmRldikgewoJCQlzYi0+c19jb3VudCsrOwoJCQlzcGluX3VubG9jaygmc2JfbG9jayk7CgkJCWRvd25fcmVhZCgmc2ItPnNfdW1vdW50KTsKCQkJaWYgKHNiLT5zX3Jvb3QpCgkJCQlyZXR1cm4gc2I7CgkJCXVwX3JlYWQoJnNiLT5zX3Vtb3VudCk7CgkJCS8qIHJlc3RhcnQgb25seSB3aGVuIHNiIGlzIG5vIGxvbmdlciBvbiB0aGUgbGlzdCAqLwoJCQlzcGluX2xvY2soJnNiX2xvY2spOwoJCQlpZiAoX19wdXRfc3VwZXJfYW5kX25lZWRfcmVzdGFydChzYikpCgkJCQlnb3RvIHJlc2NhbjsKCQl9Cgl9CglzcGluX3VubG9jaygmc2JfbG9jayk7CglyZXR1cm4gTlVMTDsKfQoKRVhQT1JUX1NZTUJPTChnZXRfc3VwZXIpOwogCnN0cnVjdCBzdXBlcl9ibG9jayAqIHVzZXJfZ2V0X3N1cGVyKGRldl90IGRldikKewoJc3RydWN0IHN1cGVyX2Jsb2NrICpzYjsKCglzcGluX2xvY2soJnNiX2xvY2spOwpyZXNjYW46CglsaXN0X2Zvcl9lYWNoX2VudHJ5KHNiLCAmc3VwZXJfYmxvY2tzLCBzX2xpc3QpIHsKCQlpZiAoc2ItPnNfZGV2ID09ICBkZXYpIHsKCQkJc2ItPnNfY291bnQrKzsKCQkJc3Bpbl91bmxvY2soJnNiX2xvY2spOwoJCQlkb3duX3JlYWQoJnNiLT5zX3Vtb3VudCk7CgkJCWlmIChzYi0+c19yb290KQoJCQkJcmV0dXJuIHNiOwoJCQl1cF9yZWFkKCZzYi0+c191bW91bnQpOwoJCQkvKiByZXN0YXJ0IG9ubHkgd2hlbiBzYiBpcyBubyBsb25nZXIgb24gdGhlIGxpc3QgKi8KCQkJc3Bpbl9sb2NrKCZzYl9sb2NrKTsKCQkJaWYgKF9fcHV0X3N1cGVyX2FuZF9uZWVkX3Jlc3RhcnQoc2IpKQoJCQkJZ290byByZXNjYW47CgkJfQoJfQoJc3Bpbl91bmxvY2soJnNiX2xvY2spOwoJcmV0dXJuIE5VTEw7Cn0KCmFzbWxpbmthZ2UgbG9uZyBzeXNfdXN0YXQodW5zaWduZWQgZGV2LCBzdHJ1Y3QgdXN0YXQgX191c2VyICogdWJ1ZikKewogICAgICAgIHN0cnVjdCBzdXBlcl9ibG9jayAqczsKICAgICAgICBzdHJ1Y3QgdXN0YXQgdG1wOwogICAgICAgIHN0cnVjdCBrc3RhdGZzIHNidWY7CglpbnQgZXJyID0gLUVJTlZBTDsKCiAgICAgICAgcyA9IHVzZXJfZ2V0X3N1cGVyKG5ld19kZWNvZGVfZGV2KGRldikpOwogICAgICAgIGlmIChzID09IE5VTEwpCiAgICAgICAgICAgICAgICBnb3RvIG91dDsKCWVyciA9IHZmc19zdGF0ZnMocy0+c19yb290LCAmc2J1Zik7Cglkcm9wX3N1cGVyKHMpOwoJaWYgKGVycikKCQlnb3RvIG91dDsKCiAgICAgICAgbWVtc2V0KCZ0bXAsMCxzaXplb2Yoc3RydWN0IHVzdGF0KSk7CiAgICAgICAgdG1wLmZfdGZyZWUgPSBzYnVmLmZfYmZyZWU7CiAgICAgICAgdG1wLmZfdGlub2RlID0gc2J1Zi5mX2ZmcmVlOwoKICAgICAgICBlcnIgPSBjb3B5X3RvX3VzZXIodWJ1ZiwmdG1wLHNpemVvZihzdHJ1Y3QgdXN0YXQpKSA/IC1FRkFVTFQgOiAwOwpvdXQ6CglyZXR1cm4gZXJyOwp9CgovKioKICoJbWFya19maWxlc19ybwogKglAc2I6IHN1cGVyYmxvY2sgaW4gcXVlc3Rpb24KICoKICoJQWxsIGZpbGVzIGFyZSBtYXJrZWQgcmVhZC9vbmx5LiAgV2UgZG9uJ3QgY2FyZSBhYm91dCBwZW5kaW5nCiAqCWRlbGV0ZSBmaWxlcyBzbyB0aGlzIHNob3VsZCBiZSB1c2VkIGluICdmb3JjZScgbW9kZSBvbmx5CiAqLwoKc3RhdGljIHZvaWQgbWFya19maWxlc19ybyhzdHJ1Y3Qgc3VwZXJfYmxvY2sgKnNiKQp7CglzdHJ1Y3QgZmlsZSAqZjsKCglmaWxlX2xpc3RfbG9jaygpOwoJbGlzdF9mb3JfZWFjaF9lbnRyeShmLCAmc2ItPnNfZmlsZXMsIGZfdS5mdV9saXN0KSB7CgkJaWYgKFNfSVNSRUcoZi0+Zl9kZW50cnktPmRfaW5vZGUtPmlfbW9kZSkgJiYgZmlsZV9jb3VudChmKSkKCQkJZi0+Zl9tb2RlICY9IH5GTU9ERV9XUklURTsKCX0KCWZpbGVfbGlzdF91bmxvY2soKTsKfQoKLyoqCiAqCWRvX3JlbW91bnRfc2IgLSBhc2tzIGZpbGVzeXN0ZW0gdG8gY2hhbmdlIG1vdW50IG9wdGlvbnMuCiAqCUBzYjoJc3VwZXJibG9jayBpbiBxdWVzdGlvbgogKglAZmxhZ3M6CW51bWVyaWMgcGFydCBvZiBvcHRpb25zCiAqCUBkYXRhOgl0aGUgcmVzdCBvZiBvcHRpb25zCiAqICAgICAgQGZvcmNlOiB3aGV0aGVyIG9yIG5vdCB0byBmb3JjZSB0aGUgY2hhbmdlCiAqCiAqCUFsdGVycyB0aGUgbW91bnQgb3B0aW9ucyBvZiBhIG1vdW50ZWQgZmlsZSBzeXN0ZW0uCiAqLwppbnQgZG9fcmVtb3VudF9zYihzdHJ1Y3Qgc3VwZXJfYmxvY2sgKnNiLCBpbnQgZmxhZ3MsIHZvaWQgKmRhdGEsIGludCBmb3JjZSkKewoJaW50IHJldHZhbDsKCQoJaWYgKCEoZmxhZ3MgJiBNU19SRE9OTFkpICYmIGJkZXZfcmVhZF9vbmx5KHNiLT5zX2JkZXYpKQoJCXJldHVybiAtRUFDQ0VTOwoJaWYgKGZsYWdzICYgTVNfUkRPTkxZKQoJCWFjY3RfYXV0b19jbG9zZShzYik7CglzaHJpbmtfZGNhY2hlX3NiKHNiKTsKCWZzeW5jX3N1cGVyKHNiKTsKCgkvKiBJZiB3ZSBhcmUgcmVtb3VudGluZyBSRE9OTFkgYW5kIGN1cnJlbnQgc2IgaXMgcmVhZC93cml0ZSwKCSAgIG1ha2Ugc3VyZSB0aGVyZSBhcmUgbm8gcncgZmlsZXMgb3BlbmVkICovCglpZiAoKGZsYWdzICYgTVNfUkRPTkxZKSAmJiAhKHNiLT5zX2ZsYWdzICYgTVNfUkRPTkxZKSkgewoJCWlmIChmb3JjZSkKCQkJbWFya19maWxlc19ybyhzYik7CgkJZWxzZSBpZiAoIWZzX21heV9yZW1vdW50X3JvKHNiKSkKCQkJcmV0dXJuIC1FQlVTWTsKCX0KCglpZiAoc2ItPnNfb3AtPnJlbW91bnRfZnMpIHsKCQlsb2NrX3N1cGVyKHNiKTsKCQlyZXR2YWwgPSBzYi0+c19vcC0+cmVtb3VudF9mcyhzYiwgJmZsYWdzLCBkYXRhKTsKCQl1bmxvY2tfc3VwZXIoc2IpOwoJCWlmIChyZXR2YWwpCgkJCXJldHVybiByZXR2YWw7Cgl9CglzYi0+c19mbGFncyA9IChzYi0+c19mbGFncyAmIH5NU19STVRfTUFTSykgfCAoZmxhZ3MgJiBNU19STVRfTUFTSyk7CglyZXR1cm4gMDsKfQoKc3RhdGljIHZvaWQgZG9fZW1lcmdlbmN5X3JlbW91bnQodW5zaWduZWQgbG9uZyBmb28pCnsKCXN0cnVjdCBzdXBlcl9ibG9jayAqc2I7CgoJc3Bpbl9sb2NrKCZzYl9sb2NrKTsKCWxpc3RfZm9yX2VhY2hfZW50cnkoc2IsICZzdXBlcl9ibG9ja3MsIHNfbGlzdCkgewoJCXNiLT5zX2NvdW50Kys7CgkJc3Bpbl91bmxvY2soJnNiX2xvY2spOwoJCWRvd25fcmVhZCgmc2ItPnNfdW1vdW50KTsKCQlpZiAoc2ItPnNfcm9vdCAmJiBzYi0+c19iZGV2ICYmICEoc2ItPnNfZmxhZ3MgJiBNU19SRE9OTFkpKSB7CgkJCS8qCgkJCSAqIC0+cmVtb3VudF9mcyBuZWVkcyBsb2NrX2tlcm5lbCgpLgoJCQkgKgoJCQkgKiBXaGF0IGxvY2sgcHJvdGVjdHMgc2ItPnNfZmxhZ3M/PwoJCQkgKi8KCQkJbG9ja19rZXJuZWwoKTsKCQkJZG9fcmVtb3VudF9zYihzYiwgTVNfUkRPTkxZLCBOVUxMLCAxKTsKCQkJdW5sb2NrX2tlcm5lbCgpOwoJCX0KCQlkcm9wX3N1cGVyKHNiKTsKCQlzcGluX2xvY2soJnNiX2xvY2spOwoJfQoJc3Bpbl91bmxvY2soJnNiX2xvY2spOwoJcHJpbnRrKCJFbWVyZ2VuY3kgUmVtb3VudCBjb21wbGV0ZVxuIik7Cn0KCnZvaWQgZW1lcmdlbmN5X3JlbW91bnQodm9pZCkKewoJcGRmbHVzaF9vcGVyYXRpb24oZG9fZW1lcmdlbmN5X3JlbW91bnQsIDApOwp9CgovKgogKiBVbm5hbWVkIGJsb2NrIGRldmljZXMgYXJlIGR1bW15IGRldmljZXMgdXNlZCBieSB2aXJ0dWFsCiAqIGZpbGVzeXN0ZW1zIHdoaWNoIGRvbid0IHVzZSByZWFsIGJsb2NrLWRldmljZXMuICAtLSBqcnMKICovCgpzdGF0aWMgc3RydWN0IGlkciB1bm5hbWVkX2Rldl9pZHI7CnN0YXRpYyBERUZJTkVfU1BJTkxPQ0sodW5uYW1lZF9kZXZfbG9jayk7LyogcHJvdGVjdHMgdGhlIGFib3ZlICovCgppbnQgc2V0X2Fub25fc3VwZXIoc3RydWN0IHN1cGVyX2Jsb2NrICpzLCB2b2lkICpkYXRhKQp7CglpbnQgZGV2OwoJaW50IGVycm9yOwoKIHJldHJ5OgoJaWYgKGlkcl9wcmVfZ2V0KCZ1bm5hbWVkX2Rldl9pZHIsIEdGUF9BVE9NSUMpID09IDApCgkJcmV0dXJuIC1FTk9NRU07CglzcGluX2xvY2soJnVubmFtZWRfZGV2X2xvY2spOwoJZXJyb3IgPSBpZHJfZ2V0X25ldygmdW5uYW1lZF9kZXZfaWRyLCBOVUxMLCAmZGV2KTsKCXNwaW5fdW5sb2NrKCZ1bm5hbWVkX2Rldl9sb2NrKTsKCWlmIChlcnJvciA9PSAtRUFHQUlOKQoJCS8qIFdlIHJhY2VkIGFuZCBsb3N0IHdpdGggYW5vdGhlciBDUFUuICovCgkJZ290byByZXRyeTsKCWVsc2UgaWYgKGVycm9yKQoJCXJldHVybiAtRUFHQUlOOwoKCWlmICgoZGV2ICYgTUFYX0lEX01BU0spID09ICgxIDw8IE1JTk9SQklUUykpIHsKCQlzcGluX2xvY2soJnVubmFtZWRfZGV2X2xvY2spOwoJCWlkcl9yZW1vdmUoJnVubmFtZWRfZGV2X2lkciwgZGV2KTsKCQlzcGluX3VubG9jaygmdW5uYW1lZF9kZXZfbG9jayk7CgkJcmV0dXJuIC1FTUZJTEU7Cgl9CglzLT5zX2RldiA9IE1LREVWKDAsIGRldiAmIE1JTk9STUFTSyk7CglyZXR1cm4gMDsKfQoKRVhQT1JUX1NZTUJPTChzZXRfYW5vbl9zdXBlcik7Cgp2b2lkIGtpbGxfYW5vbl9zdXBlcihzdHJ1Y3Qgc3VwZXJfYmxvY2sgKnNiKQp7CglpbnQgc2xvdCA9IE1JTk9SKHNiLT5zX2Rldik7CgoJZ2VuZXJpY19zaHV0ZG93bl9zdXBlcihzYik7CglzcGluX2xvY2soJnVubmFtZWRfZGV2X2xvY2spOwoJaWRyX3JlbW92ZSgmdW5uYW1lZF9kZXZfaWRyLCBzbG90KTsKCXNwaW5fdW5sb2NrKCZ1bm5hbWVkX2Rldl9sb2NrKTsKfQoKRVhQT1JUX1NZTUJPTChraWxsX2Fub25fc3VwZXIpOwoKdm9pZCBfX2luaXQgdW5uYW1lZF9kZXZfaW5pdCh2b2lkKQp7CglpZHJfaW5pdCgmdW5uYW1lZF9kZXZfaWRyKTsKfQoKdm9pZCBraWxsX2xpdHRlcl9zdXBlcihzdHJ1Y3Qgc3VwZXJfYmxvY2sgKnNiKQp7CglpZiAoc2ItPnNfcm9vdCkKCQlkX2dlbm9jaWRlKHNiLT5zX3Jvb3QpOwoJa2lsbF9hbm9uX3N1cGVyKHNiKTsKfQoKRVhQT1JUX1NZTUJPTChraWxsX2xpdHRlcl9zdXBlcik7CgpzdGF0aWMgaW50IHNldF9iZGV2X3N1cGVyKHN0cnVjdCBzdXBlcl9ibG9jayAqcywgdm9pZCAqZGF0YSkKewoJcy0+c19iZGV2ID0gZGF0YTsKCXMtPnNfZGV2ID0gcy0+c19iZGV2LT5iZF9kZXY7CglyZXR1cm4gMDsKfQoKc3RhdGljIGludCB0ZXN0X2JkZXZfc3VwZXIoc3RydWN0IHN1cGVyX2Jsb2NrICpzLCB2b2lkICpkYXRhKQp7CglyZXR1cm4gKHZvaWQgKilzLT5zX2JkZXYgPT0gZGF0YTsKfQoKc3RhdGljIHZvaWQgYmRldl91ZXZlbnQoc3RydWN0IGJsb2NrX2RldmljZSAqYmRldiwgZW51bSBrb2JqZWN0X2FjdGlvbiBhY3Rpb24pCnsKCWlmIChiZGV2LT5iZF9kaXNrKSB7CgkJaWYgKGJkZXYtPmJkX3BhcnQpCgkJCWtvYmplY3RfdWV2ZW50KCZiZGV2LT5iZF9wYXJ0LT5rb2JqLCBhY3Rpb24pOwoJCWVsc2UKCQkJa29iamVjdF91ZXZlbnQoJmJkZXYtPmJkX2Rpc2stPmtvYmosIGFjdGlvbik7Cgl9Cn0KCmludCBnZXRfc2JfYmRldihzdHJ1Y3QgZmlsZV9zeXN0ZW1fdHlwZSAqZnNfdHlwZSwKCWludCBmbGFncywgY29uc3QgY2hhciAqZGV2X25hbWUsIHZvaWQgKmRhdGEsCglpbnQgKCpmaWxsX3N1cGVyKShzdHJ1Y3Qgc3VwZXJfYmxvY2sgKiwgdm9pZCAqLCBpbnQpLAoJc3RydWN0IHZmc21vdW50ICptbnQpCnsKCXN0cnVjdCBibG9ja19kZXZpY2UgKmJkZXY7CglzdHJ1Y3Qgc3VwZXJfYmxvY2sgKnM7CglpbnQgZXJyb3IgPSAwOwoKCWJkZXYgPSBvcGVuX2JkZXZfZXhjbChkZXZfbmFtZSwgZmxhZ3MsIGZzX3R5cGUpOwoJaWYgKElTX0VSUihiZGV2KSkKCQlyZXR1cm4gUFRSX0VSUihiZGV2KTsKCgkvKgoJICogb25jZSB0aGUgc3VwZXIgaXMgaW5zZXJ0ZWQgaW50byB0aGUgbGlzdCBieSBzZ2V0LCBzX3Vtb3VudAoJICogd2lsbCBwcm90ZWN0IHRoZSBsb2NrZnMgY29kZSBmcm9tIHRyeWluZyB0byBzdGFydCBhIHNuYXBzaG90CgkgKiB3aGlsZSB3ZSBhcmUgbW91bnRpbmcKCSAqLwoJbXV0ZXhfbG9jaygmYmRldi0+YmRfbW91bnRfbXV0ZXgpOwoJcyA9IHNnZXQoZnNfdHlwZSwgdGVzdF9iZGV2X3N1cGVyLCBzZXRfYmRldl9zdXBlciwgYmRldik7CgltdXRleF91bmxvY2soJmJkZXYtPmJkX21vdW50X211dGV4KTsKCWlmIChJU19FUlIocykpCgkJZ290byBlcnJvcl9zOwoKCWlmIChzLT5zX3Jvb3QpIHsKCQlpZiAoKGZsYWdzIF4gcy0+c19mbGFncykgJiBNU19SRE9OTFkpIHsKCQkJdXBfd3JpdGUoJnMtPnNfdW1vdW50KTsKCQkJZGVhY3RpdmF0ZV9zdXBlcihzKTsKCQkJZXJyb3IgPSAtRUJVU1k7CgkJCWdvdG8gZXJyb3JfYmRldjsKCQl9CgoJCWNsb3NlX2JkZXZfZXhjbChiZGV2KTsKCX0gZWxzZSB7CgkJY2hhciBiW0JERVZOQU1FX1NJWkVdOwoKCQlzLT5zX2ZsYWdzID0gZmxhZ3M7CgkJc3RybGNweShzLT5zX2lkLCBiZGV2bmFtZShiZGV2LCBiKSwgc2l6ZW9mKHMtPnNfaWQpKTsKCQlzYl9zZXRfYmxvY2tzaXplKHMsIGJsb2NrX3NpemUoYmRldikpOwoJCWVycm9yID0gZmlsbF9zdXBlcihzLCBkYXRhLCBmbGFncyAmIE1TX1NJTEVOVCA/IDEgOiAwKTsKCQlpZiAoZXJyb3IpIHsKCQkJdXBfd3JpdGUoJnMtPnNfdW1vdW50KTsKCQkJZGVhY3RpdmF0ZV9zdXBlcihzKTsKCQkJZ290byBlcnJvcjsKCQl9CgoJCXMtPnNfZmxhZ3MgfD0gTVNfQUNUSVZFOwoJCWJkZXZfdWV2ZW50KGJkZXYsIEtPQkpfTU9VTlQpOwoJfQoKCXJldHVybiBzaW1wbGVfc2V0X21udChtbnQsIHMpOwoKZXJyb3JfczoKCWVycm9yID0gUFRSX0VSUihzKTsKZXJyb3JfYmRldjoKCWNsb3NlX2JkZXZfZXhjbChiZGV2KTsKZXJyb3I6CglyZXR1cm4gZXJyb3I7Cn0KCkVYUE9SVF9TWU1CT0woZ2V0X3NiX2JkZXYpOwoKdm9pZCBraWxsX2Jsb2NrX3N1cGVyKHN0cnVjdCBzdXBlcl9ibG9jayAqc2IpCnsKCXN0cnVjdCBibG9ja19kZXZpY2UgKmJkZXYgPSBzYi0+c19iZGV2OwoKCWJkZXZfdWV2ZW50KGJkZXYsIEtPQkpfVU1PVU5UKTsKCWdlbmVyaWNfc2h1dGRvd25fc3VwZXIoc2IpOwoJc3luY19ibG9ja2RldihiZGV2KTsKCWNsb3NlX2JkZXZfZXhjbChiZGV2KTsKfQoKRVhQT1JUX1NZTUJPTChraWxsX2Jsb2NrX3N1cGVyKTsKCmludCBnZXRfc2Jfbm9kZXYoc3RydWN0IGZpbGVfc3lzdGVtX3R5cGUgKmZzX3R5cGUsCglpbnQgZmxhZ3MsIHZvaWQgKmRhdGEsCglpbnQgKCpmaWxsX3N1cGVyKShzdHJ1Y3Qgc3VwZXJfYmxvY2sgKiwgdm9pZCAqLCBpbnQpLAoJc3RydWN0IHZmc21vdW50ICptbnQpCnsKCWludCBlcnJvcjsKCXN0cnVjdCBzdXBlcl9ibG9jayAqcyA9IHNnZXQoZnNfdHlwZSwgTlVMTCwgc2V0X2Fub25fc3VwZXIsIE5VTEwpOwoKCWlmIChJU19FUlIocykpCgkJcmV0dXJuIFBUUl9FUlIocyk7CgoJcy0+c19mbGFncyA9IGZsYWdzOwoKCWVycm9yID0gZmlsbF9zdXBlcihzLCBkYXRhLCBmbGFncyAmIE1TX1NJTEVOVCA/IDEgOiAwKTsKCWlmIChlcnJvcikgewoJCXVwX3dyaXRlKCZzLT5zX3Vtb3VudCk7CgkJZGVhY3RpdmF0ZV9zdXBlcihzKTsKCQlyZXR1cm4gZXJyb3I7Cgl9CglzLT5zX2ZsYWdzIHw9IE1TX0FDVElWRTsKCXJldHVybiBzaW1wbGVfc2V0X21udChtbnQsIHMpOwp9CgpFWFBPUlRfU1lNQk9MKGdldF9zYl9ub2Rldik7CgpzdGF0aWMgaW50IGNvbXBhcmVfc2luZ2xlKHN0cnVjdCBzdXBlcl9ibG9jayAqcywgdm9pZCAqcCkKewoJcmV0dXJuIDE7Cn0KCmludCBnZXRfc2Jfc2luZ2xlKHN0cnVjdCBmaWxlX3N5c3RlbV90eXBlICpmc190eXBlLAoJaW50IGZsYWdzLCB2b2lkICpkYXRhLAoJaW50ICgqZmlsbF9zdXBlcikoc3RydWN0IHN1cGVyX2Jsb2NrICosIHZvaWQgKiwgaW50KSwKCXN0cnVjdCB2ZnNtb3VudCAqbW50KQp7CglzdHJ1Y3Qgc3VwZXJfYmxvY2sgKnM7CglpbnQgZXJyb3I7CgoJcyA9IHNnZXQoZnNfdHlwZSwgY29tcGFyZV9zaW5nbGUsIHNldF9hbm9uX3N1cGVyLCBOVUxMKTsKCWlmIChJU19FUlIocykpCgkJcmV0dXJuIFBUUl9FUlIocyk7CglpZiAoIXMtPnNfcm9vdCkgewoJCXMtPnNfZmxhZ3MgPSBmbGFnczsKCQllcnJvciA9IGZpbGxfc3VwZXIocywgZGF0YSwgZmxhZ3MgJiBNU19TSUxFTlQgPyAxIDogMCk7CgkJaWYgKGVycm9yKSB7CgkJCXVwX3dyaXRlKCZzLT5zX3Vtb3VudCk7CgkJCWRlYWN0aXZhdGVfc3VwZXIocyk7CgkJCXJldHVybiBlcnJvcjsKCQl9CgkJcy0+c19mbGFncyB8PSBNU19BQ1RJVkU7Cgl9Cglkb19yZW1vdW50X3NiKHMsIGZsYWdzLCBkYXRhLCAwKTsKCXJldHVybiBzaW1wbGVfc2V0X21udChtbnQsIHMpOwp9CgpFWFBPUlRfU1lNQk9MKGdldF9zYl9zaW5nbGUpOwoKc3RydWN0IHZmc21vdW50ICoKdmZzX2tlcm5fbW91bnQoc3RydWN0IGZpbGVfc3lzdGVtX3R5cGUgKnR5cGUsIGludCBmbGFncywgY29uc3QgY2hhciAqbmFtZSwgdm9pZCAqZGF0YSkKewoJc3RydWN0IHZmc21vdW50ICptbnQ7CgljaGFyICpzZWNkYXRhID0gTlVMTDsKCWludCBlcnJvcjsKCglpZiAoIXR5cGUpCgkJcmV0dXJuIEVSUl9QVFIoLUVOT0RFVik7CgoJZXJyb3IgPSAtRU5PTUVNOwoJbW50ID0gYWxsb2NfdmZzbW50KG5hbWUpOwoJaWYgKCFtbnQpCgkJZ290byBvdXQ7CgoJaWYgKGRhdGEpIHsKCQlzZWNkYXRhID0gYWxsb2Nfc2VjZGF0YSgpOwoJCWlmICghc2VjZGF0YSkKCQkJZ290byBvdXRfbW50OwoKCQllcnJvciA9IHNlY3VyaXR5X3NiX2NvcHlfZGF0YSh0eXBlLCBkYXRhLCBzZWNkYXRhKTsKCQlpZiAoZXJyb3IpCgkJCWdvdG8gb3V0X2ZyZWVfc2VjZGF0YTsKCX0KCgllcnJvciA9IHR5cGUtPmdldF9zYih0eXBlLCBmbGFncywgbmFtZSwgZGF0YSwgbW50KTsKCWlmIChlcnJvciA8IDApCgkJZ290byBvdXRfZnJlZV9zZWNkYXRhOwoKIAllcnJvciA9IHNlY3VyaXR5X3NiX2tlcm5fbW91bnQobW50LT5tbnRfc2IsIHNlY2RhdGEpOwogCWlmIChlcnJvcikKIAkJZ290byBvdXRfc2I7CgoJbW50LT5tbnRfbW91bnRwb2ludCA9IG1udC0+bW50X3Jvb3Q7CgltbnQtPm1udF9wYXJlbnQgPSBtbnQ7Cgl1cF93cml0ZSgmbW50LT5tbnRfc2ItPnNfdW1vdW50KTsKCWZyZWVfc2VjZGF0YShzZWNkYXRhKTsKCXJldHVybiBtbnQ7Cm91dF9zYjoKCWRwdXQobW50LT5tbnRfcm9vdCk7Cgl1cF93cml0ZSgmbW50LT5tbnRfc2ItPnNfdW1vdW50KTsKCWRlYWN0aXZhdGVfc3VwZXIobW50LT5tbnRfc2IpOwpvdXRfZnJlZV9zZWNkYXRhOgoJZnJlZV9zZWNkYXRhKHNlY2RhdGEpOwpvdXRfbW50OgoJZnJlZV92ZnNtbnQobW50KTsKb3V0OgoJcmV0dXJuIEVSUl9QVFIoZXJyb3IpOwp9CgpFWFBPUlRfU1lNQk9MX0dQTCh2ZnNfa2Vybl9tb3VudCk7CgpzdHJ1Y3QgdmZzbW91bnQgKgpkb19rZXJuX21vdW50KGNvbnN0IGNoYXIgKmZzdHlwZSwgaW50IGZsYWdzLCBjb25zdCBjaGFyICpuYW1lLCB2b2lkICpkYXRhKQp7CglzdHJ1Y3QgZmlsZV9zeXN0ZW1fdHlwZSAqdHlwZSA9IGdldF9mc190eXBlKGZzdHlwZSk7CglzdHJ1Y3QgdmZzbW91bnQgKm1udDsKCWlmICghdHlwZSkKCQlyZXR1cm4gRVJSX1BUUigtRU5PREVWKTsKCW1udCA9IHZmc19rZXJuX21vdW50KHR5cGUsIGZsYWdzLCBuYW1lLCBkYXRhKTsKCXB1dF9maWxlc3lzdGVtKHR5cGUpOwoJcmV0dXJuIG1udDsKfQoKc3RydWN0IHZmc21vdW50ICprZXJuX21vdW50KHN0cnVjdCBmaWxlX3N5c3RlbV90eXBlICp0eXBlKQp7CglyZXR1cm4gdmZzX2tlcm5fbW91bnQodHlwZSwgMCwgdHlwZS0+bmFtZSwgTlVMTCk7Cn0KCkVYUE9SVF9TWU1CT0woa2Vybl9tb3VudCk7Cg==