LyoKICogIGxpbnV4L2ZzL3N1cGVyLmMKICoKICogIENvcHlyaWdodCAoQykgMTk5MSwgMTk5MiAgTGludXMgVG9ydmFsZHMKICoKICogIHN1cGVyLmMgY29udGFpbnMgY29kZSB0byBoYW5kbGU6IC0gbW91bnQgc3RydWN0dXJlcwogKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLSBzdXBlci1ibG9jayB0YWJsZXMKICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC0gZmlsZXN5c3RlbSBkcml2ZXJzIGxpc3QKICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC0gbW91bnQgc3lzdGVtIGNhbGwKICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC0gdW1vdW50IHN5c3RlbSBjYWxsCiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAtIHVzdGF0IHN5c3RlbSBjYWxsCiAqCiAqIEdLIDIvNS85NSAgLSAgQ2hhbmdlZCB0byBzdXBwb3J0IG1vdW50aW5nIHRoZSByb290IGZzIHZpYSBORlMKICoKICogIEFkZGVkIGtlcm5lbGQgc3VwcG9ydDogSmFjcXVlcyBHZWxpbmFzIGFuZCBCam9ybiBFa3dhbGwKICogIEFkZGVkIGNoYW5nZV9yb290OiBXZXJuZXIgQWxtZXNiZXJnZXIgJiBIYW5zIExlcm1lbiwgRmViICc5NgogKiAgQWRkZWQgb3B0aW9ucyB0byAvcHJvYy9tb3VudHM6CiAqICAgIFRvcmJq9nJuIExpbmRoICh0b3Jiam9ybi5saW5kaEBnb3B0YS5zZSksIEFwcmlsIDE0LCAxOTk2LgogKiAgQWRkZWQgZGV2ZnMgc3VwcG9ydDogUmljaGFyZCBHb29jaCA8cmdvb2NoQGF0bmYuY3Npcm8uYXU+LCAxMy1KQU4tMTk5OAogKiAgSGVhdmlseSByZXdyaXR0ZW4gZm9yICdvbmUgZnMgLSBvbmUgdHJlZScgZGNhY2hlIGFyY2hpdGVjdHVyZS4gQVYsIE1hciAyMDAwCiAqLwoKI2luY2x1ZGUgPGxpbnV4L21vZHVsZS5oPgojaW5jbHVkZSA8bGludXgvc2xhYi5oPgojaW5jbHVkZSA8bGludXgvaW5pdC5oPgojaW5jbHVkZSA8bGludXgvc21wX2xvY2suaD4KI2luY2x1ZGUgPGxpbnV4L2FjY3QuaD4KI2luY2x1ZGUgPGxpbnV4L2Jsa2Rldi5oPgojaW5jbHVkZSA8bGludXgvcXVvdGFvcHMuaD4KI2luY2x1ZGUgPGxpbnV4L25hbWVpLmg+CiNpbmNsdWRlIDxsaW51eC9idWZmZXJfaGVhZC5oPgkJLyogZm9yIGZzeW5jX3N1cGVyKCkgKi8KI2luY2x1ZGUgPGxpbnV4L21vdW50Lmg+CiNpbmNsdWRlIDxsaW51eC9zZWN1cml0eS5oPgojaW5jbHVkZSA8bGludXgvc3lzY2FsbHMuaD4KI2luY2x1ZGUgPGxpbnV4L3Zmcy5oPgojaW5jbHVkZSA8bGludXgvd3JpdGViYWNrLmg+CQkvKiBmb3IgdGhlIGVtZXJnZW5jeSByZW1vdW50IHN0dWZmICovCiNpbmNsdWRlIDxsaW51eC9pZHIuaD4KI2luY2x1ZGUgPGxpbnV4L2tvYmplY3QuaD4KI2luY2x1ZGUgPGxpbnV4L211dGV4Lmg+CiNpbmNsdWRlIDxhc20vdWFjY2Vzcy5oPgoKCnZvaWQgZ2V0X2ZpbGVzeXN0ZW0oc3RydWN0IGZpbGVfc3lzdGVtX3R5cGUgKmZzKTsKdm9pZCBwdXRfZmlsZXN5c3RlbShzdHJ1Y3QgZmlsZV9zeXN0ZW1fdHlwZSAqZnMpOwpzdHJ1Y3QgZmlsZV9zeXN0ZW1fdHlwZSAqZ2V0X2ZzX3R5cGUoY29uc3QgY2hhciAqbmFtZSk7CgpMSVNUX0hFQUQoc3VwZXJfYmxvY2tzKTsKREVGSU5FX1NQSU5MT0NLKHNiX2xvY2spOwoKLyoqCiAqCWFsbG9jX3N1cGVyCS0JY3JlYXRlIG5ldyBzdXBlcmJsb2NrCiAqCiAqCUFsbG9jYXRlcyBhbmQgaW5pdGlhbGl6ZXMgYSBuZXcgJnN0cnVjdCBzdXBlcl9ibG9jay4gIGFsbG9jX3N1cGVyKCkKICoJcmV0dXJucyBhIHBvaW50ZXIgbmV3IHN1cGVyYmxvY2sgb3IgJU5VTEwgaWYgYWxsb2NhdGlvbiBoYWQgZmFpbGVkLgogKi8Kc3RhdGljIHN0cnVjdCBzdXBlcl9ibG9jayAqYWxsb2Nfc3VwZXIodm9pZCkKewoJc3RydWN0IHN1cGVyX2Jsb2NrICpzID0ga3phbGxvYyhzaXplb2Yoc3RydWN0IHN1cGVyX2Jsb2NrKSwgIEdGUF9VU0VSKTsKCXN0YXRpYyBzdHJ1Y3Qgc3VwZXJfb3BlcmF0aW9ucyBkZWZhdWx0X29wOwoKCWlmIChzKSB7CgkJaWYgKHNlY3VyaXR5X3NiX2FsbG9jKHMpKSB7CgkJCWtmcmVlKHMpOwoJCQlzID0gTlVMTDsKCQkJZ290byBvdXQ7CgkJfQoJCUlOSVRfTElTVF9IRUFEKCZzLT5zX2RpcnR5KTsKCQlJTklUX0xJU1RfSEVBRCgmcy0+c19pbyk7CgkJSU5JVF9MSVNUX0hFQUQoJnMtPnNfZmlsZXMpOwoJCUlOSVRfTElTVF9IRUFEKCZzLT5zX2luc3RhbmNlcyk7CgkJSU5JVF9ITElTVF9IRUFEKCZzLT5zX2Fub24pOwoJCUlOSVRfTElTVF9IRUFEKCZzLT5zX2lub2Rlcyk7CgkJaW5pdF9yd3NlbSgmcy0+c191bW91bnQpOwoJCW11dGV4X2luaXQoJnMtPnNfbG9jayk7CgkJZG93bl93cml0ZSgmcy0+c191bW91bnQpOwoJCXMtPnNfY291bnQgPSBTX0JJQVM7CgkJYXRvbWljX3NldCgmcy0+c19hY3RpdmUsIDEpOwoJCW11dGV4X2luaXQoJnMtPnNfdmZzX3JlbmFtZV9tdXRleCk7CgkJbXV0ZXhfaW5pdCgmcy0+c19kcXVvdC5kcWlvX211dGV4KTsKCQltdXRleF9pbml0KCZzLT5zX2RxdW90LmRxb25vZmZfbXV0ZXgpOwoJCWluaXRfcndzZW0oJnMtPnNfZHF1b3QuZHFwdHJfc2VtKTsKCQlpbml0X3dhaXRxdWV1ZV9oZWFkKCZzLT5zX3dhaXRfdW5mcm96ZW4pOwoJCXMtPnNfbWF4Ynl0ZXMgPSBNQVhfTk9OX0xGUzsKCQlzLT5kcV9vcCA9IHNiX2RxdW90X29wczsKCQlzLT5zX3Fjb3AgPSBzYl9xdW90YWN0bF9vcHM7CgkJcy0+c19vcCA9ICZkZWZhdWx0X29wOwoJCXMtPnNfdGltZV9ncmFuID0gMTAwMDAwMDAwMDsKCX0Kb3V0OgoJcmV0dXJuIHM7Cn0KCi8qKgogKglkZXN0cm95X3N1cGVyCS0JZnJlZXMgYSBzdXBlcmJsb2NrCiAqCUBzOiBzdXBlcmJsb2NrIHRvIGZyZWUKICoKICoJRnJlZXMgYSBzdXBlcmJsb2NrLgogKi8Kc3RhdGljIGlubGluZSB2b2lkIGRlc3Ryb3lfc3VwZXIoc3RydWN0IHN1cGVyX2Jsb2NrICpzKQp7CglzZWN1cml0eV9zYl9mcmVlKHMpOwoJa2ZyZWUocyk7Cn0KCi8qIFN1cGVyYmxvY2sgcmVmY291bnRpbmcgICovCgovKgogKiBEcm9wIGEgc3VwZXJibG9jaydzIHJlZmNvdW50LiAgUmV0dXJucyBub24temVybyBpZiB0aGUgc3VwZXJibG9jayB3YXMKICogZGVzdHJveWVkLiAgVGhlIGNhbGxlciBtdXN0IGhvbGQgc2JfbG9jay4KICovCmludCBfX3B1dF9zdXBlcihzdHJ1Y3Qgc3VwZXJfYmxvY2sgKnNiKQp7CglpbnQgcmV0ID0gMDsKCglpZiAoIS0tc2ItPnNfY291bnQpIHsKCQlkZXN0cm95X3N1cGVyKHNiKTsKCQlyZXQgPSAxOwoJfQoJcmV0dXJuIHJldDsKfQoKLyoKICogRHJvcCBhIHN1cGVyYmxvY2sncyByZWZjb3VudC4KICogUmV0dXJucyBub24temVybyBpZiB0aGUgc3VwZXJibG9jayBpcyBhYm91dCB0byBiZSBkZXN0cm95ZWQgYW5kCiAqIGF0IGxlYXN0IGlzIGFscmVhZHkgcmVtb3ZlZCBmcm9tIHN1cGVyX2Jsb2NrcyBsaXN0LCBzbyBpZiB3ZSBhcmUKICogbWFraW5nIGEgbG9vcCB0aHJvdWdoIHN1cGVyIGJsb2NrcyB0aGVuIHdlIG5lZWQgdG8gcmVzdGFydC4KICogVGhlIGNhbGxlciBtdXN0IGhvbGQgc2JfbG9jay4KICovCmludCBfX3B1dF9zdXBlcl9hbmRfbmVlZF9yZXN0YXJ0KHN0cnVjdCBzdXBlcl9ibG9jayAqc2IpCnsKCS8qIGNoZWNrIGZvciByYWNlIHdpdGggZ2VuZXJpY19zaHV0ZG93bl9zdXBlcigpICovCglpZiAobGlzdF9lbXB0eSgmc2ItPnNfbGlzdCkpIHsKCQkvKiBzdXBlciBibG9jayBpcyByZW1vdmVkLCBuZWVkIHRvIHJlc3RhcnQuLi4gKi8KCQlfX3B1dF9zdXBlcihzYik7CgkJcmV0dXJuIDE7Cgl9CgkvKiBjYW4ndCBiZSB0aGUgbGFzdCwgc2luY2Ugc19saXN0IGlzIHN0aWxsIGluIHVzZSAqLwoJc2ItPnNfY291bnQtLTsKCUJVR19PTihzYi0+c19jb3VudCA9PSAwKTsKCXJldHVybiAwOwp9CgovKioKICoJcHV0X3N1cGVyCS0JZHJvcCBhIHRlbXBvcmFyeSByZWZlcmVuY2UgdG8gc3VwZXJibG9jawogKglAc2I6IHN1cGVyYmxvY2sgaW4gcXVlc3Rpb24KICoKICoJRHJvcHMgYSB0ZW1wb3JhcnkgcmVmZXJlbmNlLCBmcmVlcyBzdXBlcmJsb2NrIGlmIHRoZXJlJ3Mgbm8KICoJcmVmZXJlbmNlcyBsZWZ0LgogKi8Kc3RhdGljIHZvaWQgcHV0X3N1cGVyKHN0cnVjdCBzdXBlcl9ibG9jayAqc2IpCnsKCXNwaW5fbG9jaygmc2JfbG9jayk7CglfX3B1dF9zdXBlcihzYik7CglzcGluX3VubG9jaygmc2JfbG9jayk7Cn0KCgovKioKICoJZGVhY3RpdmF0ZV9zdXBlcgktCWRyb3AgYW4gYWN0aXZlIHJlZmVyZW5jZSB0byBzdXBlcmJsb2NrCiAqCUBzOiBzdXBlcmJsb2NrIHRvIGRlYWN0aXZhdGUKICoKICoJRHJvcHMgYW4gYWN0aXZlIHJlZmVyZW5jZSB0byBzdXBlcmJsb2NrLCBhY3F1aXJpbmcgYSB0ZW1wcm9yeSBvbmUgaWYKICoJdGhlcmUgaXMgbm8gYWN0aXZlIHJlZmVyZW5jZXMgbGVmdC4gIEluIHRoYXQgY2FzZSB3ZSBsb2NrIHN1cGVyYmxvY2ssCiAqCXRlbGwgZnMgZHJpdmVyIHRvIHNodXQgaXQgZG93biBhbmQgZHJvcCB0aGUgdGVtcG9yYXJ5IHJlZmVyZW5jZSB3ZQogKgloYWQganVzdCBhY3F1aXJlZC4KICovCnZvaWQgZGVhY3RpdmF0ZV9zdXBlcihzdHJ1Y3Qgc3VwZXJfYmxvY2sgKnMpCnsKCXN0cnVjdCBmaWxlX3N5c3RlbV90eXBlICpmcyA9IHMtPnNfdHlwZTsKCWlmIChhdG9taWNfZGVjX2FuZF9sb2NrKCZzLT5zX2FjdGl2ZSwgJnNiX2xvY2spKSB7CgkJcy0+c19jb3VudCAtPSBTX0JJQVMtMTsKCQlzcGluX3VubG9jaygmc2JfbG9jayk7CgkJRFFVT1RfT0ZGKHMpOwoJCWRvd25fd3JpdGUoJnMtPnNfdW1vdW50KTsKCQlmcy0+a2lsbF9zYihzKTsKCQlwdXRfZmlsZXN5c3RlbShmcyk7CgkJcHV0X3N1cGVyKHMpOwoJfQp9CgpFWFBPUlRfU1lNQk9MKGRlYWN0aXZhdGVfc3VwZXIpOwoKLyoqCiAqCWdyYWJfc3VwZXIgLSBhY3F1aXJlIGFuIGFjdGl2ZSByZWZlcmVuY2UKICoJQHM6IHJlZmVyZW5jZSB3ZSBhcmUgdHJ5aW5nIHRvIG1ha2UgYWN0aXZlCiAqCiAqCVRyaWVzIHRvIGFjcXVpcmUgYW4gYWN0aXZlIHJlZmVyZW5jZS4gIGdyYWJfc3VwZXIoKSBpcyB1c2VkIHdoZW4gd2UKICogCWhhZCBqdXN0IGZvdW5kIGEgc3VwZXJibG9jayBpbiBzdXBlcl9ibG9ja3Mgb3IgZnNfdHlwZS0+ZnNfc3VwZXJzCiAqCWFuZCB3YW50IHRvIHR1cm4gaXQgaW50byBhIGZ1bGwtYmxvd24gYWN0aXZlIHJlZmVyZW5jZS4gIGdyYWJfc3VwZXIoKQogKglpcyBjYWxsZWQgd2l0aCBzYl9sb2NrIGhlbGQgYW5kIGRyb3BzIGl0LiAgUmV0dXJucyAxIGluIGNhc2Ugb2YKICoJc3VjY2VzcywgMCBpZiB3ZSBoYWQgZmFpbGVkIChzdXBlcmJsb2NrIGNvbnRlbnRzIHdhcyBhbHJlYWR5IGRlYWQgb3IKICoJZHlpbmcgd2hlbiBncmFiX3N1cGVyKCkgaGFkIGJlZW4gY2FsbGVkKS4KICovCnN0YXRpYyBpbnQgZ3JhYl9zdXBlcihzdHJ1Y3Qgc3VwZXJfYmxvY2sgKnMpCnsKCXMtPnNfY291bnQrKzsKCXNwaW5fdW5sb2NrKCZzYl9sb2NrKTsKCWRvd25fd3JpdGUoJnMtPnNfdW1vdW50KTsKCWlmIChzLT5zX3Jvb3QpIHsKCQlzcGluX2xvY2soJnNiX2xvY2spOwoJCWlmIChzLT5zX2NvdW50ID4gU19CSUFTKSB7CgkJCWF0b21pY19pbmMoJnMtPnNfYWN0aXZlKTsKCQkJcy0+c19jb3VudC0tOwoJCQlzcGluX3VubG9jaygmc2JfbG9jayk7CgkJCXJldHVybiAxOwoJCX0KCQlzcGluX3VubG9jaygmc2JfbG9jayk7Cgl9Cgl1cF93cml0ZSgmcy0+c191bW91bnQpOwoJcHV0X3N1cGVyKHMpOwoJeWllbGQoKTsKCXJldHVybiAwOwp9CgovKioKICoJZ2VuZXJpY19zaHV0ZG93bl9zdXBlcgktCWNvbW1vbiBoZWxwZXIgZm9yIC0+a2lsbF9zYigpCiAqCUBzYjogc3VwZXJibG9jayB0byBraWxsCiAqCiAqCWdlbmVyaWNfc2h1dGRvd25fc3VwZXIoKSBkb2VzIGFsbCBmcy1pbmRlcGVuZGVudCB3b3JrIG9uIHN1cGVyYmxvY2sKICoJc2h1dGRvd24uICBUeXBpY2FsIC0+a2lsbF9zYigpIHNob3VsZCBwaWNrIGFsbCBmcy1zcGVjaWZpYyBvYmplY3RzCiAqCXRoYXQgbmVlZCBkZXN0cnVjdGlvbiBvdXQgb2Ygc3VwZXJibG9jaywgY2FsbCBnZW5lcmljX3NodXRkb3duX3N1cGVyKCkKICoJYW5kIHJlbGVhc2UgYWZvcmVtZW50aW9uZWQgb2JqZWN0cy4gIE5vdGU6IGRlbnRyaWVzIGFuZCBpbm9kZXMgX2FyZV8KICoJdGFrZW4gY2FyZSBvZiBhbmQgZG8gbm90IG5lZWQgc3BlY2lmaWMgaGFuZGxpbmcuCiAqLwp2b2lkIGdlbmVyaWNfc2h1dGRvd25fc3VwZXIoc3RydWN0IHN1cGVyX2Jsb2NrICpzYikKewoJc3RydWN0IGRlbnRyeSAqcm9vdCA9IHNiLT5zX3Jvb3Q7CglzdHJ1Y3Qgc3VwZXJfb3BlcmF0aW9ucyAqc29wID0gc2ItPnNfb3A7CgoJaWYgKHJvb3QpIHsKCQlzYi0+c19yb290ID0gTlVMTDsKCQlzaHJpbmtfZGNhY2hlX3BhcmVudChyb290KTsKCQlzaHJpbmtfZGNhY2hlX3NiKHNiKTsKCQlkcHV0KHJvb3QpOwoJCWZzeW5jX3N1cGVyKHNiKTsKCQlsb2NrX3N1cGVyKHNiKTsKCQlzYi0+c19mbGFncyAmPSB+TVNfQUNUSVZFOwoJCS8qIGJhZCBuYW1lIC0gaXQgc2hvdWxkIGJlIGV2aWN0X2lub2RlcygpICovCgkJaW52YWxpZGF0ZV9pbm9kZXMoc2IpOwoJCWxvY2tfa2VybmVsKCk7CgoJCWlmIChzb3AtPndyaXRlX3N1cGVyICYmIHNiLT5zX2RpcnQpCgkJCXNvcC0+d3JpdGVfc3VwZXIoc2IpOwoJCWlmIChzb3AtPnB1dF9zdXBlcikKCQkJc29wLT5wdXRfc3VwZXIoc2IpOwoKCQkvKiBGb3JnZXQgYW55IHJlbWFpbmluZyBpbm9kZXMgKi8KCQlpZiAoaW52YWxpZGF0ZV9pbm9kZXMoc2IpKSB7CgkJCXByaW50aygiVkZTOiBCdXN5IGlub2RlcyBhZnRlciB1bm1vdW50IG9mICVzLiAiCgkJCSAgICJTZWxmLWRlc3RydWN0IGluIDUgc2Vjb25kcy4gIEhhdmUgYSBuaWNlIGRheS4uLlxuIiwKCQkJICAgc2ItPnNfaWQpOwoJCX0KCgkJdW5sb2NrX2tlcm5lbCgpOwoJCXVubG9ja19zdXBlcihzYik7Cgl9CglzcGluX2xvY2soJnNiX2xvY2spOwoJLyogc2hvdWxkIGJlIGluaXRpYWxpemVkIGZvciBfX3B1dF9zdXBlcl9hbmRfbmVlZF9yZXN0YXJ0KCkgKi8KCWxpc3RfZGVsX2luaXQoJnNiLT5zX2xpc3QpOwoJbGlzdF9kZWwoJnNiLT5zX2luc3RhbmNlcyk7CglzcGluX3VubG9jaygmc2JfbG9jayk7Cgl1cF93cml0ZSgmc2ItPnNfdW1vdW50KTsKfQoKRVhQT1JUX1NZTUJPTChnZW5lcmljX3NodXRkb3duX3N1cGVyKTsKCi8qKgogKglzZ2V0CS0JZmluZCBvciBjcmVhdGUgYSBzdXBlcmJsb2NrCiAqCUB0eXBlOglmaWxlc3lzdGVtIHR5cGUgc3VwZXJibG9jayBzaG91bGQgYmVsb25nIHRvCiAqCUB0ZXN0Ogljb21wYXJpc29uIGNhbGxiYWNrCiAqCUBzZXQ6CXNldHVwIGNhbGxiYWNrCiAqCUBkYXRhOglhcmd1bWVudCB0byBlYWNoIG9mIHRoZW0KICovCnN0cnVjdCBzdXBlcl9ibG9jayAqc2dldChzdHJ1Y3QgZmlsZV9zeXN0ZW1fdHlwZSAqdHlwZSwKCQkJaW50ICgqdGVzdCkoc3RydWN0IHN1cGVyX2Jsb2NrICosdm9pZCAqKSwKCQkJaW50ICgqc2V0KShzdHJ1Y3Qgc3VwZXJfYmxvY2sgKix2b2lkICopLAoJCQl2b2lkICpkYXRhKQp7CglzdHJ1Y3Qgc3VwZXJfYmxvY2sgKnMgPSBOVUxMOwoJc3RydWN0IGxpc3RfaGVhZCAqcDsKCWludCBlcnI7CgpyZXRyeToKCXNwaW5fbG9jaygmc2JfbG9jayk7CglpZiAodGVzdCkgbGlzdF9mb3JfZWFjaChwLCAmdHlwZS0+ZnNfc3VwZXJzKSB7CgkJc3RydWN0IHN1cGVyX2Jsb2NrICpvbGQ7CgkJb2xkID0gbGlzdF9lbnRyeShwLCBzdHJ1Y3Qgc3VwZXJfYmxvY2ssIHNfaW5zdGFuY2VzKTsKCQlpZiAoIXRlc3Qob2xkLCBkYXRhKSkKCQkJY29udGludWU7CgkJaWYgKCFncmFiX3N1cGVyKG9sZCkpCgkJCWdvdG8gcmV0cnk7CgkJaWYgKHMpCgkJCWRlc3Ryb3lfc3VwZXIocyk7CgkJcmV0dXJuIG9sZDsKCX0KCWlmICghcykgewoJCXNwaW5fdW5sb2NrKCZzYl9sb2NrKTsKCQlzID0gYWxsb2Nfc3VwZXIoKTsKCQlpZiAoIXMpCgkJCXJldHVybiBFUlJfUFRSKC1FTk9NRU0pOwoJCWdvdG8gcmV0cnk7Cgl9CgkJCgllcnIgPSBzZXQocywgZGF0YSk7CglpZiAoZXJyKSB7CgkJc3Bpbl91bmxvY2soJnNiX2xvY2spOwoJCWRlc3Ryb3lfc3VwZXIocyk7CgkJcmV0dXJuIEVSUl9QVFIoZXJyKTsKCX0KCXMtPnNfdHlwZSA9IHR5cGU7CglzdHJsY3B5KHMtPnNfaWQsIHR5cGUtPm5hbWUsIHNpemVvZihzLT5zX2lkKSk7CglsaXN0X2FkZF90YWlsKCZzLT5zX2xpc3QsICZzdXBlcl9ibG9ja3MpOwoJbGlzdF9hZGQoJnMtPnNfaW5zdGFuY2VzLCAmdHlwZS0+ZnNfc3VwZXJzKTsKCXNwaW5fdW5sb2NrKCZzYl9sb2NrKTsKCWdldF9maWxlc3lzdGVtKHR5cGUpOwoJcmV0dXJuIHM7Cn0KCkVYUE9SVF9TWU1CT0woc2dldCk7Cgp2b2lkIGRyb3Bfc3VwZXIoc3RydWN0IHN1cGVyX2Jsb2NrICpzYikKewoJdXBfcmVhZCgmc2ItPnNfdW1vdW50KTsKCXB1dF9zdXBlcihzYik7Cn0KCkVYUE9SVF9TWU1CT0woZHJvcF9zdXBlcik7CgpzdGF0aWMgaW5saW5lIHZvaWQgd3JpdGVfc3VwZXIoc3RydWN0IHN1cGVyX2Jsb2NrICpzYikKewoJbG9ja19zdXBlcihzYik7CglpZiAoc2ItPnNfcm9vdCAmJiBzYi0+c19kaXJ0KQoJCWlmIChzYi0+c19vcC0+d3JpdGVfc3VwZXIpCgkJCXNiLT5zX29wLT53cml0ZV9zdXBlcihzYik7Cgl1bmxvY2tfc3VwZXIoc2IpOwp9CgovKgogKiBOb3RlOiBjaGVjayB0aGUgZGlydHkgZmxhZyBiZWZvcmUgd2FpdGluZywgc28gd2UgZG9uJ3QKICogaG9sZCB1cCB0aGUgc3luYyB3aGlsZSBtb3VudGluZyBhIGRldmljZS4gKFRoZSBuZXdseQogKiBtb3VudGVkIGRldmljZSB3b24ndCBuZWVkIHN5bmNpbmcuKQogKi8Kdm9pZCBzeW5jX3N1cGVycyh2b2lkKQp7CglzdHJ1Y3Qgc3VwZXJfYmxvY2sgKnNiOwoKCXNwaW5fbG9jaygmc2JfbG9jayk7CnJlc3RhcnQ6CglsaXN0X2Zvcl9lYWNoX2VudHJ5KHNiLCAmc3VwZXJfYmxvY2tzLCBzX2xpc3QpIHsKCQlpZiAoc2ItPnNfZGlydCkgewoJCQlzYi0+c19jb3VudCsrOwoJCQlzcGluX3VubG9jaygmc2JfbG9jayk7CgkJCWRvd25fcmVhZCgmc2ItPnNfdW1vdW50KTsKCQkJd3JpdGVfc3VwZXIoc2IpOwoJCQl1cF9yZWFkKCZzYi0+c191bW91bnQpOwoJCQlzcGluX2xvY2soJnNiX2xvY2spOwoJCQlpZiAoX19wdXRfc3VwZXJfYW5kX25lZWRfcmVzdGFydChzYikpCgkJCQlnb3RvIHJlc3RhcnQ7CgkJfQoJfQoJc3Bpbl91bmxvY2soJnNiX2xvY2spOwp9CgovKgogKiBDYWxsIHRoZSAtPnN5bmNfZnMgc3VwZXJfb3AgYWdhaW5zdCBhbGwgZmlsZXN5dGVtcyB3aGljaCBhcmUgci93IGFuZAogKiB3aGljaCBpbXBsZW1lbnQgaXQuCiAqCiAqIFRoaXMgb3BlcmF0aW9uIGlzIGNhcmVmdWwgdG8gYXZvaWQgdGhlIGxpdmVsb2NrIHdoaWNoIGNvdWxkIGVhc2lseSBoYXBwZW4KICogaWYgdHdvIG9yIG1vcmUgZmlsZXN5c3RlbXMgYXJlIGJlaW5nIGNvbnRpbnVvdXNseSBkaXJ0aWVkLiAgc19uZWVkX3N5bmNfZnMKICogaXMgdXNlZCBvbmx5IGhlcmUuICBXZSBzZXQgaXQgYWdhaW5zdCBhbGwgZmlsZXN5c3RlbXMgYW5kIHRoZW4gY2xlYXIgaXQgYXMKICogd2Ugc3luYyB0aGVtLiAgU28gcmVkaXJ0aWVkIGZpbGVzeXN0ZW1zIGFyZSBza2lwcGVkLgogKgogKiBCdXQgaWYgcHJvY2VzcyBBIGlzIGN1cnJlbnRseSBydW5uaW5nIHN5bmNfZmlsZXN5dGVtcyBhbmQgdGhlbiBwcm9jZXNzIEIKICogY2FsbHMgc3luY19maWxlc3lzdGVtcyBhcyB3ZWxsLCBwcm9jZXNzIEIgd2lsbCBzZXQgYWxsIHRoZSBzX25lZWRfc3luY19mcwogKiBmbGFncyBhZ2Fpbiwgd2hpY2ggd2lsbCBjYXVzZSBwcm9jZXNzIEEgdG8gcmVzeW5jIGV2ZXJ5dGhpbmcuICBGaXggdGhhdCB3aXRoCiAqIGEgbG9jYWwgbXV0ZXguCiAqCiAqIChGYWJpYW4pIEF2b2lkIHN5bmNfZnMgd2l0aCBjbGVhbiBmcyAmIHdhaXQgbW9kZSAwCiAqLwp2b2lkIHN5bmNfZmlsZXN5c3RlbXMoaW50IHdhaXQpCnsKCXN0cnVjdCBzdXBlcl9ibG9jayAqc2I7CglzdGF0aWMgREVGSU5FX01VVEVYKG11dGV4KTsKCgltdXRleF9sb2NrKCZtdXRleCk7CQkvKiBDb3VsZCBiZSBkb3duX2ludGVycnVwdGlibGUgKi8KCXNwaW5fbG9jaygmc2JfbG9jayk7CglsaXN0X2Zvcl9lYWNoX2VudHJ5KHNiLCAmc3VwZXJfYmxvY2tzLCBzX2xpc3QpIHsKCQlpZiAoIXNiLT5zX29wLT5zeW5jX2ZzKQoJCQljb250aW51ZTsKCQlpZiAoc2ItPnNfZmxhZ3MgJiBNU19SRE9OTFkpCgkJCWNvbnRpbnVlOwoJCXNiLT5zX25lZWRfc3luY19mcyA9IDE7Cgl9CgpyZXN0YXJ0OgoJbGlzdF9mb3JfZWFjaF9lbnRyeShzYiwgJnN1cGVyX2Jsb2Nrcywgc19saXN0KSB7CgkJaWYgKCFzYi0+c19uZWVkX3N5bmNfZnMpCgkJCWNvbnRpbnVlOwoJCXNiLT5zX25lZWRfc3luY19mcyA9IDA7CgkJaWYgKHNiLT5zX2ZsYWdzICYgTVNfUkRPTkxZKQoJCQljb250aW51ZTsJLyogaG0uICBXYXMgcmVtb3VudGVkIHIvbyBtZWFud2hpbGUgKi8KCQlzYi0+c19jb3VudCsrOwoJCXNwaW5fdW5sb2NrKCZzYl9sb2NrKTsKCQlkb3duX3JlYWQoJnNiLT5zX3Vtb3VudCk7CgkJaWYgKHNiLT5zX3Jvb3QgJiYgKHdhaXQgfHwgc2ItPnNfZGlydCkpCgkJCXNiLT5zX29wLT5zeW5jX2ZzKHNiLCB3YWl0KTsKCQl1cF9yZWFkKCZzYi0+c191bW91bnQpOwoJCS8qIHJlc3RhcnQgb25seSB3aGVuIHNiIGlzIG5vIGxvbmdlciBvbiB0aGUgbGlzdCAqLwoJCXNwaW5fbG9jaygmc2JfbG9jayk7CgkJaWYgKF9fcHV0X3N1cGVyX2FuZF9uZWVkX3Jlc3RhcnQoc2IpKQoJCQlnb3RvIHJlc3RhcnQ7Cgl9CglzcGluX3VubG9jaygmc2JfbG9jayk7CgltdXRleF91bmxvY2soJm11dGV4KTsKfQoKLyoqCiAqCWdldF9zdXBlciAtIGdldCB0aGUgc3VwZXJibG9jayBvZiBhIGRldmljZQogKglAYmRldjogZGV2aWNlIHRvIGdldCB0aGUgc3VwZXJibG9jayBmb3IKICoJCiAqCVNjYW5zIHRoZSBzdXBlcmJsb2NrIGxpc3QgYW5kIGZpbmRzIHRoZSBzdXBlcmJsb2NrIG9mIHRoZSBmaWxlIHN5c3RlbQogKgltb3VudGVkIG9uIHRoZSBkZXZpY2UgZ2l2ZW4uICVOVUxMIGlzIHJldHVybmVkIGlmIG5vIG1hdGNoIGlzIGZvdW5kLgogKi8KCnN0cnVjdCBzdXBlcl9ibG9jayAqIGdldF9zdXBlcihzdHJ1Y3QgYmxvY2tfZGV2aWNlICpiZGV2KQp7CglzdHJ1Y3Qgc3VwZXJfYmxvY2sgKnNiOwoKCWlmICghYmRldikKCQlyZXR1cm4gTlVMTDsKCglzcGluX2xvY2soJnNiX2xvY2spOwpyZXNjYW46CglsaXN0X2Zvcl9lYWNoX2VudHJ5KHNiLCAmc3VwZXJfYmxvY2tzLCBzX2xpc3QpIHsKCQlpZiAoc2ItPnNfYmRldiA9PSBiZGV2KSB7CgkJCXNiLT5zX2NvdW50Kys7CgkJCXNwaW5fdW5sb2NrKCZzYl9sb2NrKTsKCQkJZG93bl9yZWFkKCZzYi0+c191bW91bnQpOwoJCQlpZiAoc2ItPnNfcm9vdCkKCQkJCXJldHVybiBzYjsKCQkJdXBfcmVhZCgmc2ItPnNfdW1vdW50KTsKCQkJLyogcmVzdGFydCBvbmx5IHdoZW4gc2IgaXMgbm8gbG9uZ2VyIG9uIHRoZSBsaXN0ICovCgkJCXNwaW5fbG9jaygmc2JfbG9jayk7CgkJCWlmIChfX3B1dF9zdXBlcl9hbmRfbmVlZF9yZXN0YXJ0KHNiKSkKCQkJCWdvdG8gcmVzY2FuOwoJCX0KCX0KCXNwaW5fdW5sb2NrKCZzYl9sb2NrKTsKCXJldHVybiBOVUxMOwp9CgpFWFBPUlRfU1lNQk9MKGdldF9zdXBlcik7CiAKc3RydWN0IHN1cGVyX2Jsb2NrICogdXNlcl9nZXRfc3VwZXIoZGV2X3QgZGV2KQp7CglzdHJ1Y3Qgc3VwZXJfYmxvY2sgKnNiOwoKCXNwaW5fbG9jaygmc2JfbG9jayk7CnJlc2NhbjoKCWxpc3RfZm9yX2VhY2hfZW50cnkoc2IsICZzdXBlcl9ibG9ja3MsIHNfbGlzdCkgewoJCWlmIChzYi0+c19kZXYgPT0gIGRldikgewoJCQlzYi0+c19jb3VudCsrOwoJCQlzcGluX3VubG9jaygmc2JfbG9jayk7CgkJCWRvd25fcmVhZCgmc2ItPnNfdW1vdW50KTsKCQkJaWYgKHNiLT5zX3Jvb3QpCgkJCQlyZXR1cm4gc2I7CgkJCXVwX3JlYWQoJnNiLT5zX3Vtb3VudCk7CgkJCS8qIHJlc3RhcnQgb25seSB3aGVuIHNiIGlzIG5vIGxvbmdlciBvbiB0aGUgbGlzdCAqLwoJCQlzcGluX2xvY2soJnNiX2xvY2spOwoJCQlpZiAoX19wdXRfc3VwZXJfYW5kX25lZWRfcmVzdGFydChzYikpCgkJCQlnb3RvIHJlc2NhbjsKCQl9Cgl9CglzcGluX3VubG9jaygmc2JfbG9jayk7CglyZXR1cm4gTlVMTDsKfQoKYXNtbGlua2FnZSBsb25nIHN5c191c3RhdCh1bnNpZ25lZCBkZXYsIHN0cnVjdCB1c3RhdCBfX3VzZXIgKiB1YnVmKQp7CiAgICAgICAgc3RydWN0IHN1cGVyX2Jsb2NrICpzOwogICAgICAgIHN0cnVjdCB1c3RhdCB0bXA7CiAgICAgICAgc3RydWN0IGtzdGF0ZnMgc2J1ZjsKCWludCBlcnIgPSAtRUlOVkFMOwoKICAgICAgICBzID0gdXNlcl9nZXRfc3VwZXIobmV3X2RlY29kZV9kZXYoZGV2KSk7CiAgICAgICAgaWYgKHMgPT0gTlVMTCkKICAgICAgICAgICAgICAgIGdvdG8gb3V0OwoJZXJyID0gdmZzX3N0YXRmcyhzLT5zX3Jvb3QsICZzYnVmKTsKCWRyb3Bfc3VwZXIocyk7CglpZiAoZXJyKQoJCWdvdG8gb3V0OwoKICAgICAgICBtZW1zZXQoJnRtcCwwLHNpemVvZihzdHJ1Y3QgdXN0YXQpKTsKICAgICAgICB0bXAuZl90ZnJlZSA9IHNidWYuZl9iZnJlZTsKICAgICAgICB0bXAuZl90aW5vZGUgPSBzYnVmLmZfZmZyZWU7CgogICAgICAgIGVyciA9IGNvcHlfdG9fdXNlcih1YnVmLCZ0bXAsc2l6ZW9mKHN0cnVjdCB1c3RhdCkpID8gLUVGQVVMVCA6IDA7Cm91dDoKCXJldHVybiBlcnI7Cn0KCi8qKgogKgltYXJrX2ZpbGVzX3JvCiAqCUBzYjogc3VwZXJibG9jayBpbiBxdWVzdGlvbgogKgogKglBbGwgZmlsZXMgYXJlIG1hcmtlZCByZWFkL29ubHkuICBXZSBkb24ndCBjYXJlIGFib3V0IHBlbmRpbmcKICoJZGVsZXRlIGZpbGVzIHNvIHRoaXMgc2hvdWxkIGJlIHVzZWQgaW4gJ2ZvcmNlJyBtb2RlIG9ubHkKICovCgpzdGF0aWMgdm9pZCBtYXJrX2ZpbGVzX3JvKHN0cnVjdCBzdXBlcl9ibG9jayAqc2IpCnsKCXN0cnVjdCBmaWxlICpmOwoKCWZpbGVfbGlzdF9sb2NrKCk7CglsaXN0X2Zvcl9lYWNoX2VudHJ5KGYsICZzYi0+c19maWxlcywgZl91LmZ1X2xpc3QpIHsKCQlpZiAoU19JU1JFRyhmLT5mX2RlbnRyeS0+ZF9pbm9kZS0+aV9tb2RlKSAmJiBmaWxlX2NvdW50KGYpKQoJCQlmLT5mX21vZGUgJj0gfkZNT0RFX1dSSVRFOwoJfQoJZmlsZV9saXN0X3VubG9jaygpOwp9CgovKioKICoJZG9fcmVtb3VudF9zYiAtIGFza3MgZmlsZXN5c3RlbSB0byBjaGFuZ2UgbW91bnQgb3B0aW9ucy4KICoJQHNiOglzdXBlcmJsb2NrIGluIHF1ZXN0aW9uCiAqCUBmbGFnczoJbnVtZXJpYyBwYXJ0IG9mIG9wdGlvbnMKICoJQGRhdGE6CXRoZSByZXN0IG9mIG9wdGlvbnMKICogICAgICBAZm9yY2U6IHdoZXRoZXIgb3Igbm90IHRvIGZvcmNlIHRoZSBjaGFuZ2UKICoKICoJQWx0ZXJzIHRoZSBtb3VudCBvcHRpb25zIG9mIGEgbW91bnRlZCBmaWxlIHN5c3RlbS4KICovCmludCBkb19yZW1vdW50X3NiKHN0cnVjdCBzdXBlcl9ibG9jayAqc2IsIGludCBmbGFncywgdm9pZCAqZGF0YSwgaW50IGZvcmNlKQp7CglpbnQgcmV0dmFsOwoJCglpZiAoIShmbGFncyAmIE1TX1JET05MWSkgJiYgYmRldl9yZWFkX29ubHkoc2ItPnNfYmRldikpCgkJcmV0dXJuIC1FQUNDRVM7CglpZiAoZmxhZ3MgJiBNU19SRE9OTFkpCgkJYWNjdF9hdXRvX2Nsb3NlKHNiKTsKCXNocmlua19kY2FjaGVfc2Ioc2IpOwoJZnN5bmNfc3VwZXIoc2IpOwoKCS8qIElmIHdlIGFyZSByZW1vdW50aW5nIFJET05MWSBhbmQgY3VycmVudCBzYiBpcyByZWFkL3dyaXRlLAoJICAgbWFrZSBzdXJlIHRoZXJlIGFyZSBubyBydyBmaWxlcyBvcGVuZWQgKi8KCWlmICgoZmxhZ3MgJiBNU19SRE9OTFkpICYmICEoc2ItPnNfZmxhZ3MgJiBNU19SRE9OTFkpKSB7CgkJaWYgKGZvcmNlKQoJCQltYXJrX2ZpbGVzX3JvKHNiKTsKCQllbHNlIGlmICghZnNfbWF5X3JlbW91bnRfcm8oc2IpKQoJCQlyZXR1cm4gLUVCVVNZOwoJfQoKCWlmIChzYi0+c19vcC0+cmVtb3VudF9mcykgewoJCWxvY2tfc3VwZXIoc2IpOwoJCXJldHZhbCA9IHNiLT5zX29wLT5yZW1vdW50X2ZzKHNiLCAmZmxhZ3MsIGRhdGEpOwoJCXVubG9ja19zdXBlcihzYik7CgkJaWYgKHJldHZhbCkKCQkJcmV0dXJuIHJldHZhbDsKCX0KCXNiLT5zX2ZsYWdzID0gKHNiLT5zX2ZsYWdzICYgfk1TX1JNVF9NQVNLKSB8IChmbGFncyAmIE1TX1JNVF9NQVNLKTsKCXJldHVybiAwOwp9CgpzdGF0aWMgdm9pZCBkb19lbWVyZ2VuY3lfcmVtb3VudCh1bnNpZ25lZCBsb25nIGZvbykKewoJc3RydWN0IHN1cGVyX2Jsb2NrICpzYjsKCglzcGluX2xvY2soJnNiX2xvY2spOwoJbGlzdF9mb3JfZWFjaF9lbnRyeShzYiwgJnN1cGVyX2Jsb2Nrcywgc19saXN0KSB7CgkJc2ItPnNfY291bnQrKzsKCQlzcGluX3VubG9jaygmc2JfbG9jayk7CgkJZG93bl9yZWFkKCZzYi0+c191bW91bnQpOwoJCWlmIChzYi0+c19yb290ICYmIHNiLT5zX2JkZXYgJiYgIShzYi0+c19mbGFncyAmIE1TX1JET05MWSkpIHsKCQkJLyoKCQkJICogLT5yZW1vdW50X2ZzIG5lZWRzIGxvY2tfa2VybmVsKCkuCgkJCSAqCgkJCSAqIFdoYXQgbG9jayBwcm90ZWN0cyBzYi0+c19mbGFncz8/CgkJCSAqLwoJCQlsb2NrX2tlcm5lbCgpOwoJCQlkb19yZW1vdW50X3NiKHNiLCBNU19SRE9OTFksIE5VTEwsIDEpOwoJCQl1bmxvY2tfa2VybmVsKCk7CgkJfQoJCWRyb3Bfc3VwZXIoc2IpOwoJCXNwaW5fbG9jaygmc2JfbG9jayk7Cgl9CglzcGluX3VubG9jaygmc2JfbG9jayk7CglwcmludGsoIkVtZXJnZW5jeSBSZW1vdW50IGNvbXBsZXRlXG4iKTsKfQoKdm9pZCBlbWVyZ2VuY3lfcmVtb3VudCh2b2lkKQp7CglwZGZsdXNoX29wZXJhdGlvbihkb19lbWVyZ2VuY3lfcmVtb3VudCwgMCk7Cn0KCi8qCiAqIFVubmFtZWQgYmxvY2sgZGV2aWNlcyBhcmUgZHVtbXkgZGV2aWNlcyB1c2VkIGJ5IHZpcnR1YWwKICogZmlsZXN5c3RlbXMgd2hpY2ggZG9uJ3QgdXNlIHJlYWwgYmxvY2stZGV2aWNlcy4gIC0tIGpycwogKi8KCnN0YXRpYyBzdHJ1Y3QgaWRyIHVubmFtZWRfZGV2X2lkcjsKc3RhdGljIERFRklORV9TUElOTE9DSyh1bm5hbWVkX2Rldl9sb2NrKTsvKiBwcm90ZWN0cyB0aGUgYWJvdmUgKi8KCmludCBzZXRfYW5vbl9zdXBlcihzdHJ1Y3Qgc3VwZXJfYmxvY2sgKnMsIHZvaWQgKmRhdGEpCnsKCWludCBkZXY7CglpbnQgZXJyb3I7CgogcmV0cnk6CglpZiAoaWRyX3ByZV9nZXQoJnVubmFtZWRfZGV2X2lkciwgR0ZQX0FUT01JQykgPT0gMCkKCQlyZXR1cm4gLUVOT01FTTsKCXNwaW5fbG9jaygmdW5uYW1lZF9kZXZfbG9jayk7CgllcnJvciA9IGlkcl9nZXRfbmV3KCZ1bm5hbWVkX2Rldl9pZHIsIE5VTEwsICZkZXYpOwoJc3Bpbl91bmxvY2soJnVubmFtZWRfZGV2X2xvY2spOwoJaWYgKGVycm9yID09IC1FQUdBSU4pCgkJLyogV2UgcmFjZWQgYW5kIGxvc3Qgd2l0aCBhbm90aGVyIENQVS4gKi8KCQlnb3RvIHJldHJ5OwoJZWxzZSBpZiAoZXJyb3IpCgkJcmV0dXJuIC1FQUdBSU47CgoJaWYgKChkZXYgJiBNQVhfSURfTUFTSykgPT0gKDEgPDwgTUlOT1JCSVRTKSkgewoJCXNwaW5fbG9jaygmdW5uYW1lZF9kZXZfbG9jayk7CgkJaWRyX3JlbW92ZSgmdW5uYW1lZF9kZXZfaWRyLCBkZXYpOwoJCXNwaW5fdW5sb2NrKCZ1bm5hbWVkX2Rldl9sb2NrKTsKCQlyZXR1cm4gLUVNRklMRTsKCX0KCXMtPnNfZGV2ID0gTUtERVYoMCwgZGV2ICYgTUlOT1JNQVNLKTsKCXJldHVybiAwOwp9CgpFWFBPUlRfU1lNQk9MKHNldF9hbm9uX3N1cGVyKTsKCnZvaWQga2lsbF9hbm9uX3N1cGVyKHN0cnVjdCBzdXBlcl9ibG9jayAqc2IpCnsKCWludCBzbG90ID0gTUlOT1Ioc2ItPnNfZGV2KTsKCglnZW5lcmljX3NodXRkb3duX3N1cGVyKHNiKTsKCXNwaW5fbG9jaygmdW5uYW1lZF9kZXZfbG9jayk7CglpZHJfcmVtb3ZlKCZ1bm5hbWVkX2Rldl9pZHIsIHNsb3QpOwoJc3Bpbl91bmxvY2soJnVubmFtZWRfZGV2X2xvY2spOwp9CgpFWFBPUlRfU1lNQk9MKGtpbGxfYW5vbl9zdXBlcik7Cgp2b2lkIF9faW5pdCB1bm5hbWVkX2Rldl9pbml0KHZvaWQpCnsKCWlkcl9pbml0KCZ1bm5hbWVkX2Rldl9pZHIpOwp9Cgp2b2lkIGtpbGxfbGl0dGVyX3N1cGVyKHN0cnVjdCBzdXBlcl9ibG9jayAqc2IpCnsKCWlmIChzYi0+c19yb290KQoJCWRfZ2Vub2NpZGUoc2ItPnNfcm9vdCk7CglraWxsX2Fub25fc3VwZXIoc2IpOwp9CgpFWFBPUlRfU1lNQk9MKGtpbGxfbGl0dGVyX3N1cGVyKTsKCnN0YXRpYyBpbnQgc2V0X2JkZXZfc3VwZXIoc3RydWN0IHN1cGVyX2Jsb2NrICpzLCB2b2lkICpkYXRhKQp7CglzLT5zX2JkZXYgPSBkYXRhOwoJcy0+c19kZXYgPSBzLT5zX2JkZXYtPmJkX2RldjsKCXJldHVybiAwOwp9CgpzdGF0aWMgaW50IHRlc3RfYmRldl9zdXBlcihzdHJ1Y3Qgc3VwZXJfYmxvY2sgKnMsIHZvaWQgKmRhdGEpCnsKCXJldHVybiAodm9pZCAqKXMtPnNfYmRldiA9PSBkYXRhOwp9CgpzdGF0aWMgdm9pZCBiZGV2X3VldmVudChzdHJ1Y3QgYmxvY2tfZGV2aWNlICpiZGV2LCBlbnVtIGtvYmplY3RfYWN0aW9uIGFjdGlvbikKewoJaWYgKGJkZXYtPmJkX2Rpc2spIHsKCQlpZiAoYmRldi0+YmRfcGFydCkKCQkJa29iamVjdF91ZXZlbnQoJmJkZXYtPmJkX3BhcnQtPmtvYmosIGFjdGlvbik7CgkJZWxzZQoJCQlrb2JqZWN0X3VldmVudCgmYmRldi0+YmRfZGlzay0+a29iaiwgYWN0aW9uKTsKCX0KfQoKaW50IGdldF9zYl9iZGV2KHN0cnVjdCBmaWxlX3N5c3RlbV90eXBlICpmc190eXBlLAoJaW50IGZsYWdzLCBjb25zdCBjaGFyICpkZXZfbmFtZSwgdm9pZCAqZGF0YSwKCWludCAoKmZpbGxfc3VwZXIpKHN0cnVjdCBzdXBlcl9ibG9jayAqLCB2b2lkICosIGludCksCglzdHJ1Y3QgdmZzbW91bnQgKm1udCkKewoJc3RydWN0IGJsb2NrX2RldmljZSAqYmRldjsKCXN0cnVjdCBzdXBlcl9ibG9jayAqczsKCWludCBlcnJvciA9IDA7CgoJYmRldiA9IG9wZW5fYmRldl9leGNsKGRldl9uYW1lLCBmbGFncywgZnNfdHlwZSk7CglpZiAoSVNfRVJSKGJkZXYpKQoJCXJldHVybiBQVFJfRVJSKGJkZXYpOwoKCS8qCgkgKiBvbmNlIHRoZSBzdXBlciBpcyBpbnNlcnRlZCBpbnRvIHRoZSBsaXN0IGJ5IHNnZXQsIHNfdW1vdW50CgkgKiB3aWxsIHByb3RlY3QgdGhlIGxvY2tmcyBjb2RlIGZyb20gdHJ5aW5nIHRvIHN0YXJ0IGEgc25hcHNob3QKCSAqIHdoaWxlIHdlIGFyZSBtb3VudGluZwoJICovCgltdXRleF9sb2NrKCZiZGV2LT5iZF9tb3VudF9tdXRleCk7CglzID0gc2dldChmc190eXBlLCB0ZXN0X2JkZXZfc3VwZXIsIHNldF9iZGV2X3N1cGVyLCBiZGV2KTsKCW11dGV4X3VubG9jaygmYmRldi0+YmRfbW91bnRfbXV0ZXgpOwoJaWYgKElTX0VSUihzKSkKCQlnb3RvIGVycm9yX3M7CgoJaWYgKHMtPnNfcm9vdCkgewoJCWlmICgoZmxhZ3MgXiBzLT5zX2ZsYWdzKSAmIE1TX1JET05MWSkgewoJCQl1cF93cml0ZSgmcy0+c191bW91bnQpOwoJCQlkZWFjdGl2YXRlX3N1cGVyKHMpOwoJCQllcnJvciA9IC1FQlVTWTsKCQkJZ290byBlcnJvcl9iZGV2OwoJCX0KCgkJY2xvc2VfYmRldl9leGNsKGJkZXYpOwoJfSBlbHNlIHsKCQljaGFyIGJbQkRFVk5BTUVfU0laRV07CgoJCXMtPnNfZmxhZ3MgPSBmbGFnczsKCQlzdHJsY3B5KHMtPnNfaWQsIGJkZXZuYW1lKGJkZXYsIGIpLCBzaXplb2Yocy0+c19pZCkpOwoJCXNiX3NldF9ibG9ja3NpemUocywgYmxvY2tfc2l6ZShiZGV2KSk7CgkJZXJyb3IgPSBmaWxsX3N1cGVyKHMsIGRhdGEsIGZsYWdzICYgTVNfU0lMRU5UID8gMSA6IDApOwoJCWlmIChlcnJvcikgewoJCQl1cF93cml0ZSgmcy0+c191bW91bnQpOwoJCQlkZWFjdGl2YXRlX3N1cGVyKHMpOwoJCQlnb3RvIGVycm9yOwoJCX0KCgkJcy0+c19mbGFncyB8PSBNU19BQ1RJVkU7CgkJYmRldl91ZXZlbnQoYmRldiwgS09CSl9NT1VOVCk7Cgl9CgoJcmV0dXJuIHNpbXBsZV9zZXRfbW50KG1udCwgcyk7CgplcnJvcl9zOgoJZXJyb3IgPSBQVFJfRVJSKHMpOwplcnJvcl9iZGV2OgoJY2xvc2VfYmRldl9leGNsKGJkZXYpOwplcnJvcjoKCXJldHVybiBlcnJvcjsKfQoKRVhQT1JUX1NZTUJPTChnZXRfc2JfYmRldik7Cgp2b2lkIGtpbGxfYmxvY2tfc3VwZXIoc3RydWN0IHN1cGVyX2Jsb2NrICpzYikKewoJc3RydWN0IGJsb2NrX2RldmljZSAqYmRldiA9IHNiLT5zX2JkZXY7CgoJYmRldl91ZXZlbnQoYmRldiwgS09CSl9VTU9VTlQpOwoJZ2VuZXJpY19zaHV0ZG93bl9zdXBlcihzYik7CglzeW5jX2Jsb2NrZGV2KGJkZXYpOwoJY2xvc2VfYmRldl9leGNsKGJkZXYpOwp9CgpFWFBPUlRfU1lNQk9MKGtpbGxfYmxvY2tfc3VwZXIpOwoKaW50IGdldF9zYl9ub2RldihzdHJ1Y3QgZmlsZV9zeXN0ZW1fdHlwZSAqZnNfdHlwZSwKCWludCBmbGFncywgdm9pZCAqZGF0YSwKCWludCAoKmZpbGxfc3VwZXIpKHN0cnVjdCBzdXBlcl9ibG9jayAqLCB2b2lkICosIGludCksCglzdHJ1Y3QgdmZzbW91bnQgKm1udCkKewoJaW50IGVycm9yOwoJc3RydWN0IHN1cGVyX2Jsb2NrICpzID0gc2dldChmc190eXBlLCBOVUxMLCBzZXRfYW5vbl9zdXBlciwgTlVMTCk7CgoJaWYgKElTX0VSUihzKSkKCQlyZXR1cm4gUFRSX0VSUihzKTsKCglzLT5zX2ZsYWdzID0gZmxhZ3M7CgoJZXJyb3IgPSBmaWxsX3N1cGVyKHMsIGRhdGEsIGZsYWdzICYgTVNfU0lMRU5UID8gMSA6IDApOwoJaWYgKGVycm9yKSB7CgkJdXBfd3JpdGUoJnMtPnNfdW1vdW50KTsKCQlkZWFjdGl2YXRlX3N1cGVyKHMpOwoJCXJldHVybiBlcnJvcjsKCX0KCXMtPnNfZmxhZ3MgfD0gTVNfQUNUSVZFOwoJcmV0dXJuIHNpbXBsZV9zZXRfbW50KG1udCwgcyk7Cn0KCkVYUE9SVF9TWU1CT0woZ2V0X3NiX25vZGV2KTsKCnN0YXRpYyBpbnQgY29tcGFyZV9zaW5nbGUoc3RydWN0IHN1cGVyX2Jsb2NrICpzLCB2b2lkICpwKQp7CglyZXR1cm4gMTsKfQoKaW50IGdldF9zYl9zaW5nbGUoc3RydWN0IGZpbGVfc3lzdGVtX3R5cGUgKmZzX3R5cGUsCglpbnQgZmxhZ3MsIHZvaWQgKmRhdGEsCglpbnQgKCpmaWxsX3N1cGVyKShzdHJ1Y3Qgc3VwZXJfYmxvY2sgKiwgdm9pZCAqLCBpbnQpLAoJc3RydWN0IHZmc21vdW50ICptbnQpCnsKCXN0cnVjdCBzdXBlcl9ibG9jayAqczsKCWludCBlcnJvcjsKCglzID0gc2dldChmc190eXBlLCBjb21wYXJlX3NpbmdsZSwgc2V0X2Fub25fc3VwZXIsIE5VTEwpOwoJaWYgKElTX0VSUihzKSkKCQlyZXR1cm4gUFRSX0VSUihzKTsKCWlmICghcy0+c19yb290KSB7CgkJcy0+c19mbGFncyA9IGZsYWdzOwoJCWVycm9yID0gZmlsbF9zdXBlcihzLCBkYXRhLCBmbGFncyAmIE1TX1NJTEVOVCA/IDEgOiAwKTsKCQlpZiAoZXJyb3IpIHsKCQkJdXBfd3JpdGUoJnMtPnNfdW1vdW50KTsKCQkJZGVhY3RpdmF0ZV9zdXBlcihzKTsKCQkJcmV0dXJuIGVycm9yOwoJCX0KCQlzLT5zX2ZsYWdzIHw9IE1TX0FDVElWRTsKCX0KCWRvX3JlbW91bnRfc2IocywgZmxhZ3MsIGRhdGEsIDApOwoJcmV0dXJuIHNpbXBsZV9zZXRfbW50KG1udCwgcyk7Cn0KCkVYUE9SVF9TWU1CT0woZ2V0X3NiX3NpbmdsZSk7CgpzdHJ1Y3QgdmZzbW91bnQgKgp2ZnNfa2Vybl9tb3VudChzdHJ1Y3QgZmlsZV9zeXN0ZW1fdHlwZSAqdHlwZSwgaW50IGZsYWdzLCBjb25zdCBjaGFyICpuYW1lLCB2b2lkICpkYXRhKQp7CglzdHJ1Y3QgdmZzbW91bnQgKm1udDsKCWNoYXIgKnNlY2RhdGEgPSBOVUxMOwoJaW50IGVycm9yOwoKCWlmICghdHlwZSkKCQlyZXR1cm4gRVJSX1BUUigtRU5PREVWKTsKCgllcnJvciA9IC1FTk9NRU07CgltbnQgPSBhbGxvY192ZnNtbnQobmFtZSk7CglpZiAoIW1udCkKCQlnb3RvIG91dDsKCglpZiAoZGF0YSkgewoJCXNlY2RhdGEgPSBhbGxvY19zZWNkYXRhKCk7CgkJaWYgKCFzZWNkYXRhKQoJCQlnb3RvIG91dF9tbnQ7CgoJCWVycm9yID0gc2VjdXJpdHlfc2JfY29weV9kYXRhKHR5cGUsIGRhdGEsIHNlY2RhdGEpOwoJCWlmIChlcnJvcikKCQkJZ290byBvdXRfZnJlZV9zZWNkYXRhOwoJfQoKCWVycm9yID0gdHlwZS0+Z2V0X3NiKHR5cGUsIGZsYWdzLCBuYW1lLCBkYXRhLCBtbnQpOwoJaWYgKGVycm9yIDwgMCkKCQlnb3RvIG91dF9mcmVlX3NlY2RhdGE7CgogCWVycm9yID0gc2VjdXJpdHlfc2Jfa2Vybl9tb3VudChtbnQtPm1udF9zYiwgc2VjZGF0YSk7CiAJaWYgKGVycm9yKQogCQlnb3RvIG91dF9zYjsKCgltbnQtPm1udF9tb3VudHBvaW50ID0gbW50LT5tbnRfcm9vdDsKCW1udC0+bW50X3BhcmVudCA9IG1udDsKCXVwX3dyaXRlKCZtbnQtPm1udF9zYi0+c191bW91bnQpOwoJZnJlZV9zZWNkYXRhKHNlY2RhdGEpOwoJcmV0dXJuIG1udDsKb3V0X3NiOgoJZHB1dChtbnQtPm1udF9yb290KTsKCXVwX3dyaXRlKCZtbnQtPm1udF9zYi0+c191bW91bnQpOwoJZGVhY3RpdmF0ZV9zdXBlcihtbnQtPm1udF9zYik7Cm91dF9mcmVlX3NlY2RhdGE6CglmcmVlX3NlY2RhdGEoc2VjZGF0YSk7Cm91dF9tbnQ6CglmcmVlX3Zmc21udChtbnQpOwpvdXQ6CglyZXR1cm4gRVJSX1BUUihlcnJvcik7Cn0KCkVYUE9SVF9TWU1CT0xfR1BMKHZmc19rZXJuX21vdW50KTsKCnN0cnVjdCB2ZnNtb3VudCAqCmRvX2tlcm5fbW91bnQoY29uc3QgY2hhciAqZnN0eXBlLCBpbnQgZmxhZ3MsIGNvbnN0IGNoYXIgKm5hbWUsIHZvaWQgKmRhdGEpCnsKCXN0cnVjdCBmaWxlX3N5c3RlbV90eXBlICp0eXBlID0gZ2V0X2ZzX3R5cGUoZnN0eXBlKTsKCXN0cnVjdCB2ZnNtb3VudCAqbW50OwoJaWYgKCF0eXBlKQoJCXJldHVybiBFUlJfUFRSKC1FTk9ERVYpOwoJbW50ID0gdmZzX2tlcm5fbW91bnQodHlwZSwgZmxhZ3MsIG5hbWUsIGRhdGEpOwoJcHV0X2ZpbGVzeXN0ZW0odHlwZSk7CglyZXR1cm4gbW50Owp9CgpzdHJ1Y3QgdmZzbW91bnQgKmtlcm5fbW91bnQoc3RydWN0IGZpbGVfc3lzdGVtX3R5cGUgKnR5cGUpCnsKCXJldHVybiB2ZnNfa2Vybl9tb3VudCh0eXBlLCAwLCB0eXBlLT5uYW1lLCBOVUxMKTsKfQoKRVhQT1JUX1NZTUJPTChrZXJuX21vdW50KTsK