LyoKICoJRnVuY3Rpb25zIHRvIGhhbmRsZSBJMk8gY29udHJvbGxlcnMgYW5kIEkyTyBtZXNzYWdlIGhhbmRsaW5nCiAqCiAqCUNvcHlyaWdodCAoQykgMTk5OS0yMDAyCVJlZCBIYXQgU29mdHdhcmUKICoKICoJV3JpdHRlbiBieSBBbGFuIENveCwgQnVpbGRpbmcgTnVtYmVyIFRocmVlIEx0ZAogKgogKglUaGlzIHByb2dyYW0gaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKgl1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUKICoJRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIgdmVyc2lvbiAyIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91cgogKglvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKglBIGxvdCBvZiB0aGUgSTJPIG1lc3NhZ2Ugc2lkZSBjb2RlIGZyb20gdGhpcyBpcyB0YWtlbiBmcm9tIHRoZQogKglSZWQgQ3JlZWsgUkNQQ0k0NSBhZGFwdGVyIGRyaXZlciBieSBSZWQgQ3JlZWsgQ29tbXVuaWNhdGlvbnMKICoKICoJRml4ZXMvYWRkaXRpb25zOgogKgkJUGhpbGlwcCBSdW1wZgogKgkJSnVoYSBTaWV25G5lbiA8SnVoYS5TaWV2YW5lbkBjcy5IZWxzaW5raS5GST4KICoJCUF1dm8gSORra2luZW4gPEF1dm8uSGFra2luZW5AY3MuSGVsc2lua2kuRkk+CiAqCQlEZWVwYWsgU2F4ZW5hIDxkZWVwYWtAcGxleGl0eS5uZXQ+CiAqCQlCb2ppIFQgS2FubmFudGhhbmFtIDxib2ppLnQua2FubmFudGhhbmFtQGludGVsLmNvbT4KICoJCUFsYW4gQ294IDxhbGFuQHJlZGhhdC5jb20+OgogKgkJCVBvcnRlZCB0byBMaW51eCAyLjUuCiAqCQlNYXJrdXMgTGlkZWwgPE1hcmt1cy5MaWRlbEBzaGFkb3djb25uZWN0LmNvbT46CiAqCQkJTWlub3IgZml4ZXMgZm9yIDIuNi4KICovCgojaW5jbHVkZSA8bGludXgvbW9kdWxlLmg+CiNpbmNsdWRlIDxsaW51eC9pMm8uaD4KI2luY2x1ZGUgPGxpbnV4L2RlbGF5Lmg+CiNpbmNsdWRlIDxsaW51eC9zY2hlZC5oPgojaW5jbHVkZSAiY29yZS5oIgoKI2RlZmluZSBPU01fTkFNRQkiaTJvIgojZGVmaW5lIE9TTV9WRVJTSU9OCSIxLjI4OCIKI2RlZmluZSBPU01fREVTQ1JJUFRJT04JIkkyTyBzdWJzeXN0ZW0iCgovKiBnbG9iYWwgSTJPIGNvbnRyb2xsZXIgbGlzdCAqLwpMSVNUX0hFQUQoaTJvX2NvbnRyb2xsZXJzKTsKCi8qCiAqIGdsb2JhbCBJMk8gU3lzdGVtIFRhYmxlLiBDb250YWlucyBpbmZvcm1hdGlvbiBhYm91dCBhbGwgdGhlIElPUHMgaW4gdGhlCiAqIHN5c3RlbS4gVXNlZCB0byBpbmZvcm0gSU9QcyBhYm91dCBlYWNoIG90aGVycyBleGlzdGVuY2UuCiAqLwpzdGF0aWMgc3RydWN0IGkyb19kbWEgaTJvX3N5c3RhYjsKCnN0YXRpYyBpbnQgaTJvX2hydF9nZXQoc3RydWN0IGkyb19jb250cm9sbGVyICpjKTsKCi8qKgogKglpMm9fbXNnX25vcCAtIFJldHVybnMgYSBtZXNzYWdlIHdoaWNoIGlzIG5vdCB1c2VkCiAqCUBjOiBJMk8gY29udHJvbGxlciBmcm9tIHdoaWNoIHRoZSBtZXNzYWdlIHdhcyBjcmVhdGVkCiAqCUBtOiBtZXNzYWdlIHdoaWNoIHNob3VsZCBiZSByZXR1cm5lZAogKgogKglJZiB5b3UgZmV0Y2ggYSBtZXNzYWdlIHZpYSBpMm9fbXNnX2dldCwgYW5kIGNhbid0IHVzZSBpdCwgeW91IG11c3QKICoJcmV0dXJuIHRoZSBtZXNzYWdlIHdpdGggdGhpcyBmdW5jdGlvbi4gT3RoZXJ3aXNlIHRoZSBtZXNzYWdlIGZyYW1lCiAqCWlzIGxvc3QuCiAqLwp2b2lkIGkyb19tc2dfbm9wKHN0cnVjdCBpMm9fY29udHJvbGxlciAqYywgdTMyIG0pCnsKCXN0cnVjdCBpMm9fbWVzc2FnZSBfX2lvbWVtICptc2cgPSBpMm9fbXNnX2luX3RvX3ZpcnQoYywgbSk7CgoJd3JpdGVsKFRIUkVFX1dPUkRfTVNHX1NJWkUgfCBTR0xfT0ZGU0VUXzAsICZtc2ctPnUuaGVhZFswXSk7Cgl3cml0ZWwoSTJPX0NNRF9VVElMX05PUCA8PCAyNCB8IEhPU1RfVElEIDw8IDEyIHwgQURBUFRFUl9USUQsCgkgICAgICAgJm1zZy0+dS5oZWFkWzFdKTsKCXdyaXRlbCgwLCAmbXNnLT51LmhlYWRbMl0pOwoJd3JpdGVsKDAsICZtc2ctPnUuaGVhZFszXSk7CglpMm9fbXNnX3Bvc3QoYywgbSk7Cn07CgovKioKICoJaTJvX21zZ19nZXRfd2FpdCAtIG9idGFpbiBhbiBJMk8gbWVzc2FnZSBmcm9tIHRoZSBJT1AKICoJQGM6IEkyTyBjb250cm9sbGVyCiAqCUBtc2c6IHBvaW50ZXIgdG8gYSBJMk8gbWVzc2FnZSBwb2ludGVyCiAqCUB3YWl0OiBob3cgbG9uZyB0byB3YWl0IHVudGlsIHRpbWVvdXQKICoKICoJVGhpcyBmdW5jdGlvbiB3YWl0cyB1cCB0byB3YWl0IHNlY29uZHMgZm9yIGEgbWVzc2FnZSBzbG90IHRvIGJlCiAqCWF2YWlsYWJsZS4KICoKICoJT24gYSBzdWNjZXNzIHRoZSBtZXNzYWdlIGlzIHJldHVybmVkIGFuZCB0aGUgcG9pbnRlciB0byB0aGUgbWVzc2FnZSBpcwogKglzZXQgaW4gbXNnLiBUaGUgcmV0dXJuZWQgbWVzc2FnZSBpcyB0aGUgcGh5c2ljYWwgcGFnZSBmcmFtZSBvZmZzZXQKICoJYWRkcmVzcyBmcm9tIHRoZSByZWFkIHBvcnQgKHNlZSB0aGUgaTJvIHNwZWMpLiBJZiBubyBtZXNzYWdlIGlzCiAqCWF2YWlsYWJsZSByZXR1cm5zIEkyT19RVUVVRV9FTVBUWSBhbmQgbXNnIGlzIGxlYXZlZCB1bnRvdWNoZWQuCiAqLwp1MzIgaTJvX21zZ19nZXRfd2FpdChzdHJ1Y3QgaTJvX2NvbnRyb2xsZXIgKmMsCgkJICAgICBzdHJ1Y3QgaTJvX21lc3NhZ2UgX19pb21lbSAqKiBtc2csIGludCB3YWl0KQp7Cgl1bnNpZ25lZCBsb25nIHRpbWVvdXQgPSBqaWZmaWVzICsgd2FpdCAqIEhaOwoJdTMyIG07CgoJd2hpbGUgKChtID0gaTJvX21zZ19nZXQoYywgbXNnKSkgPT0gSTJPX1FVRVVFX0VNUFRZKSB7CgkJaWYgKHRpbWVfYWZ0ZXIoamlmZmllcywgdGltZW91dCkpIHsKCQkJb3NtX2RlYnVnKCIlczogVGltZW91dCB3YWl0aW5nIGZvciBtZXNzYWdlIGZyYW1lLlxuIiwKCQkJCSAgYy0+bmFtZSk7CgkJCXJldHVybiBJMk9fUVVFVUVfRU1QVFk7CgkJfQoJCXNldF9jdXJyZW50X3N0YXRlKFRBU0tfVU5JTlRFUlJVUFRJQkxFKTsKCQlzY2hlZHVsZV90aW1lb3V0KDEpOwoJfQoKCXJldHVybiBtOwp9OwoKI2lmIEJJVFNfUEVSX0xPTkcgPT0gNjQKLyoqCiAqICAgICAgaTJvX2NudHh0X2xpc3RfYWRkIC0gQXBwZW5kIGEgcG9pbnRlciB0byBjb250ZXh0IGxpc3QgYW5kIHJldHVybiBhIGlkCiAqCUBjOiBjb250cm9sbGVyIHRvIHdoaWNoIHRoZSBjb250ZXh0IGxpc3QgYmVsb25nCiAqCUBwdHI6IHBvaW50ZXIgdG8gYWRkIHRvIHRoZSBjb250ZXh0IGxpc3QKICoKICoJQmVjYXVzZSB0aGUgY29udGV4dCBmaWVsZCBpbiBJMk8gaXMgb25seSAzMi1iaXQgbGFyZ2UsIG9uIDY0LWJpdCB0aGUKICoJcG9pbnRlciBpcyB0byBsYXJnZSB0byBmaXQgaW4gdGhlIGNvbnRleHQgZmllbGQuIFRoZSBpMm9fY250eHRfbGlzdAogKglmdW5jdGlvbnMgdGhlcmVmb3JlIG1hcCBwb2ludGVycyB0byBjb250ZXh0IGZpZWxkcy4KICoKICoJUmV0dXJucyBjb250ZXh0IGlkID4gMCBvbiBzdWNjZXNzIG9yIDAgb24gZmFpbHVyZS4KICovCnUzMiBpMm9fY250eHRfbGlzdF9hZGQoc3RydWN0IGkyb19jb250cm9sbGVyICogYywgdm9pZCAqcHRyKQp7CglzdHJ1Y3QgaTJvX2NvbnRleHRfbGlzdF9lbGVtZW50ICplbnRyeTsKCXVuc2lnbmVkIGxvbmcgZmxhZ3M7CgoJaWYgKCFwdHIpCgkJb3NtX2VycigiJXM6IGNvdWxkbid0IGFkZCBOVUxMIHBvaW50ZXIgdG8gY29udGV4dCBsaXN0IVxuIiwKCQkJYy0+bmFtZSk7CgoJZW50cnkgPSBrbWFsbG9jKHNpemVvZigqZW50cnkpLCBHRlBfQVRPTUlDKTsKCWlmICghZW50cnkpIHsKCQlvc21fZXJyKCIlczogQ291bGQgbm90IGFsbG9jYXRlIG1lbW9yeSBmb3IgY29udGV4dCBsaXN0IGVsZW1lbnQiCgkJCSJcbiIsIGMtPm5hbWUpOwoJCXJldHVybiAwOwoJfQoKCWVudHJ5LT5wdHIgPSBwdHI7CgllbnRyeS0+dGltZXN0YW1wID0gamlmZmllczsKCUlOSVRfTElTVF9IRUFEKCZlbnRyeS0+bGlzdCk7CgoJc3Bpbl9sb2NrX2lycXNhdmUoJmMtPmNvbnRleHRfbGlzdF9sb2NrLCBmbGFncyk7CgoJaWYgKHVubGlrZWx5KGF0b21pY19pbmNfYW5kX3Rlc3QoJmMtPmNvbnRleHRfbGlzdF9jb3VudGVyKSkpCgkJYXRvbWljX2luYygmYy0+Y29udGV4dF9saXN0X2NvdW50ZXIpOwoKCWVudHJ5LT5jb250ZXh0ID0gYXRvbWljX3JlYWQoJmMtPmNvbnRleHRfbGlzdF9jb3VudGVyKTsKCglsaXN0X2FkZCgmZW50cnktPmxpc3QsICZjLT5jb250ZXh0X2xpc3QpOwoKCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJmMtPmNvbnRleHRfbGlzdF9sb2NrLCBmbGFncyk7CgoJb3NtX2RlYnVnKCIlczogQWRkIGNvbnRleHQgdG8gbGlzdCAlcCAtPiAlZFxuIiwgYy0+bmFtZSwgcHRyLCBjb250ZXh0KTsKCglyZXR1cm4gZW50cnktPmNvbnRleHQ7Cn07CgovKioKICogICAgICBpMm9fY250eHRfbGlzdF9yZW1vdmUgLSBSZW1vdmUgYSBwb2ludGVyIGZyb20gdGhlIGNvbnRleHQgbGlzdAogKglAYzogY29udHJvbGxlciB0byB3aGljaCB0aGUgY29udGV4dCBsaXN0IGJlbG9uZwogKglAcHRyOiBwb2ludGVyIHdoaWNoIHNob3VsZCBiZSByZW1vdmVkIGZyb20gdGhlIGNvbnRleHQgbGlzdAogKgogKglSZW1vdmVzIGEgcHJldmlvdXNseSBhZGRlZCBwb2ludGVyIGZyb20gdGhlIGNvbnRleHQgbGlzdCBhbmQgcmV0dXJucwogKgl0aGUgbWF0Y2hpbmcgY29udGV4dCBpZC4KICoKICoJUmV0dXJucyBjb250ZXh0IGlkIG9uIHN1Y2NlcyBvciAwIG9uIGZhaWx1cmUuCiAqLwp1MzIgaTJvX2NudHh0X2xpc3RfcmVtb3ZlKHN0cnVjdCBpMm9fY29udHJvbGxlciAqIGMsIHZvaWQgKnB0cikKewoJc3RydWN0IGkyb19jb250ZXh0X2xpc3RfZWxlbWVudCAqZW50cnk7Cgl1MzIgY29udGV4dCA9IDA7Cgl1bnNpZ25lZCBsb25nIGZsYWdzOwoKCXNwaW5fbG9ja19pcnFzYXZlKCZjLT5jb250ZXh0X2xpc3RfbG9jaywgZmxhZ3MpOwoJbGlzdF9mb3JfZWFjaF9lbnRyeShlbnRyeSwgJmMtPmNvbnRleHRfbGlzdCwgbGlzdCkKCSAgICBpZiAoZW50cnktPnB0ciA9PSBwdHIpIHsKCQlsaXN0X2RlbCgmZW50cnktPmxpc3QpOwoJCWNvbnRleHQgPSBlbnRyeS0+Y29udGV4dDsKCQlrZnJlZShlbnRyeSk7CgkJYnJlYWs7Cgl9CglzcGluX3VubG9ja19pcnFyZXN0b3JlKCZjLT5jb250ZXh0X2xpc3RfbG9jaywgZmxhZ3MpOwoKCWlmICghY29udGV4dCkKCQlvc21fd2FybigiJXM6IENvdWxkIG5vdCByZW1vdmUgbm9uZXhpc3RlbnQgcHRyICVwXG4iLCBjLT5uYW1lLAoJCQkgcHRyKTsKCglvc21fZGVidWcoIiVzOiByZW1vdmUgcHRyIGZyb20gY29udGV4dCBsaXN0ICVkIC0+ICVwXG4iLCBjLT5uYW1lLAoJCSAgY29udGV4dCwgcHRyKTsKCglyZXR1cm4gY29udGV4dDsKfTsKCi8qKgogKiAgICAgIGkyb19jbnR4dF9saXN0X2dldCAtIEdldCBhIHBvaW50ZXIgZnJvbSB0aGUgY29udGV4dCBsaXN0IGFuZCByZW1vdmUgaXQKICoJQGM6IGNvbnRyb2xsZXIgdG8gd2hpY2ggdGhlIGNvbnRleHQgbGlzdCBiZWxvbmcKICoJQGNvbnRleHQ6IGNvbnRleHQgaWQgdG8gd2hpY2ggdGhlIHBvaW50ZXIgYmVsb25nCiAqCiAqCVJldHVybnMgcG9pbnRlciB0byB0aGUgbWF0Y2hpbmcgY29udGV4dCBpZCBvbiBzdWNjZXNzIG9yIE5VTEwgb24KICoJZmFpbHVyZS4KICovCnZvaWQgKmkyb19jbnR4dF9saXN0X2dldChzdHJ1Y3QgaTJvX2NvbnRyb2xsZXIgKmMsIHUzMiBjb250ZXh0KQp7CglzdHJ1Y3QgaTJvX2NvbnRleHRfbGlzdF9lbGVtZW50ICplbnRyeTsKCXVuc2lnbmVkIGxvbmcgZmxhZ3M7Cgl2b2lkICpwdHIgPSBOVUxMOwoKCXNwaW5fbG9ja19pcnFzYXZlKCZjLT5jb250ZXh0X2xpc3RfbG9jaywgZmxhZ3MpOwoJbGlzdF9mb3JfZWFjaF9lbnRyeShlbnRyeSwgJmMtPmNvbnRleHRfbGlzdCwgbGlzdCkKCSAgICBpZiAoZW50cnktPmNvbnRleHQgPT0gY29udGV4dCkgewoJCWxpc3RfZGVsKCZlbnRyeS0+bGlzdCk7CgkJcHRyID0gZW50cnktPnB0cjsKCQlrZnJlZShlbnRyeSk7CgkJYnJlYWs7Cgl9CglzcGluX3VubG9ja19pcnFyZXN0b3JlKCZjLT5jb250ZXh0X2xpc3RfbG9jaywgZmxhZ3MpOwoKCWlmICghcHRyKQoJCW9zbV93YXJuKCIlczogY29udGV4dCBpZCAlZCBub3QgZm91bmRcbiIsIGMtPm5hbWUsIGNvbnRleHQpOwoKCW9zbV9kZWJ1ZygiJXM6IGdldCBwdHIgZnJvbSBjb250ZXh0IGxpc3QgJWQgLT4gJXBcbiIsIGMtPm5hbWUsIGNvbnRleHQsCgkJICBwdHIpOwoKCXJldHVybiBwdHI7Cn07CgovKioKICogICAgICBpMm9fY250eHRfbGlzdF9nZXRfcHRyIC0gR2V0IGEgY29udGV4dCBpZCBmcm9tIHRoZSBjb250ZXh0IGxpc3QKICoJQGM6IGNvbnRyb2xsZXIgdG8gd2hpY2ggdGhlIGNvbnRleHQgbGlzdCBiZWxvbmcKICoJQHB0cjogcG9pbnRlciB0byB3aGljaCB0aGUgY29udGV4dCBpZCBzaG91bGQgYmUgZmV0Y2hlZAogKgogKglSZXR1cm5zIGNvbnRleHQgaWQgd2hpY2ggbWF0Y2hlcyB0byB0aGUgcG9pbnRlciBvbiBzdWNjZXMgb3IgMCBvbgogKglmYWlsdXJlLgogKi8KdTMyIGkyb19jbnR4dF9saXN0X2dldF9wdHIoc3RydWN0IGkyb19jb250cm9sbGVyICogYywgdm9pZCAqcHRyKQp7CglzdHJ1Y3QgaTJvX2NvbnRleHRfbGlzdF9lbGVtZW50ICplbnRyeTsKCXUzMiBjb250ZXh0ID0gMDsKCXVuc2lnbmVkIGxvbmcgZmxhZ3M7CgoJc3Bpbl9sb2NrX2lycXNhdmUoJmMtPmNvbnRleHRfbGlzdF9sb2NrLCBmbGFncyk7CglsaXN0X2Zvcl9lYWNoX2VudHJ5KGVudHJ5LCAmYy0+Y29udGV4dF9saXN0LCBsaXN0KQoJICAgIGlmIChlbnRyeS0+cHRyID09IHB0cikgewoJCWNvbnRleHQgPSBlbnRyeS0+Y29udGV4dDsKCQlicmVhazsKCX0KCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJmMtPmNvbnRleHRfbGlzdF9sb2NrLCBmbGFncyk7CgoJaWYgKCFjb250ZXh0KQoJCW9zbV93YXJuKCIlczogQ291bGQgbm90IGZpbmQgbm9uZXhpc3RlbnQgcHRyICVwXG4iLCBjLT5uYW1lLAoJCQkgcHRyKTsKCglvc21fZGVidWcoIiVzOiBnZXQgY29udGV4dCBpZCBmcm9tIGNvbnRleHQgbGlzdCAlcCAtPiAlZFxuIiwgYy0+bmFtZSwKCQkgIHB0ciwgY29udGV4dCk7CgoJcmV0dXJuIGNvbnRleHQ7Cn07CiNlbmRpZgoKLyoqCiAqCWkyb19pb3BfZmluZCAtIEZpbmQgYW4gSTJPIGNvbnRyb2xsZXIgYnkgaWQKICoJQHVuaXQ6IHVuaXQgbnVtYmVyIG9mIHRoZSBJMk8gY29udHJvbGxlciB0byBzZWFyY2ggZm9yCiAqCiAqCUxvb2t1cCB0aGUgSTJPIGNvbnRyb2xsZXIgb24gdGhlIGNvbnRyb2xsZXIgbGlzdC4KICoKICoJUmV0dXJucyBwb2ludGVyIHRvIHRoZSBJMk8gY29udHJvbGxlciBvbiBzdWNjZXNzIG9yIE5VTEwgaWYgbm90IGZvdW5kLgogKi8Kc3RydWN0IGkyb19jb250cm9sbGVyICppMm9fZmluZF9pb3AoaW50IHVuaXQpCnsKCXN0cnVjdCBpMm9fY29udHJvbGxlciAqYzsKCglsaXN0X2Zvcl9lYWNoX2VudHJ5KGMsICZpMm9fY29udHJvbGxlcnMsIGxpc3QpIHsKCQlpZiAoYy0+dW5pdCA9PSB1bml0KQoJCQlyZXR1cm4gYzsKCX0KCglyZXR1cm4gTlVMTDsKfTsKCi8qKgogKglpMm9faW9wX2ZpbmRfZGV2aWNlIC0gRmluZCBhIEkyTyBkZXZpY2Ugb24gYW4gSTJPIGNvbnRyb2xsZXIKICoJQGM6IEkyTyBjb250cm9sbGVyIHdoZXJlIHRoZSBJMk8gZGV2aWNlIGhhbmdzIG9uCiAqCUB0aWQ6IFRJRCBvZiB0aGUgSTJPIGRldmljZSB0byBzZWFyY2ggZm9yCiAqCiAqCVNlYXJjaGVzIHRoZSBkZXZpY2VzIG9mIHRoZSBJMk8gY29udHJvbGxlciBmb3IgYSBkZXZpY2Ugd2l0aCBUSUQgdGlkIGFuZAogKglyZXR1cm5zIGl0LgogKgogKglSZXR1cm5zIGEgcG9pbnRlciB0byB0aGUgSTJPIGRldmljZSBpZiBmb3VuZCwgb3RoZXJ3aXNlIE5VTEwuCiAqLwpzdHJ1Y3QgaTJvX2RldmljZSAqaTJvX2lvcF9maW5kX2RldmljZShzdHJ1Y3QgaTJvX2NvbnRyb2xsZXIgKmMsIHUxNiB0aWQpCnsKCXN0cnVjdCBpMm9fZGV2aWNlICpkZXY7CgoJbGlzdF9mb3JfZWFjaF9lbnRyeShkZXYsICZjLT5kZXZpY2VzLCBsaXN0KQoJICAgIGlmIChkZXYtPmxjdF9kYXRhLnRpZCA9PSB0aWQpCgkJcmV0dXJuIGRldjsKCglyZXR1cm4gTlVMTDsKfTsKCi8qKgogKglpMm9fcXVpZXNjZV9jb250cm9sbGVyIC0gcXVpZXNjZSBjb250cm9sbGVyCiAqCUBjOiBjb250cm9sbGVyCiAqCiAqCVF1aWVzY2UgYW4gSU9QLiBDYXVzZXMgSU9QIHRvIG1ha2UgZXh0ZXJuYWwgb3BlcmF0aW9uIHF1aWVzY2VudAogKgkoaTJvICdSRUFEWScgc3RhdGUpLiBJbnRlcm5hbCBvcGVyYXRpb24gb2YgdGhlIElPUCBjb250aW51ZXMgbm9ybWFsbHkuCiAqCiAqCVJldHVybnMgMCBvbiBzdWNjZXNzIG9yIG5lZ2F0aXZlIGVycm9yIGNvZGUgb24gZmFpbHVyZS4KICovCnN0YXRpYyBpbnQgaTJvX2lvcF9xdWllc2NlKHN0cnVjdCBpMm9fY29udHJvbGxlciAqYykKewoJc3RydWN0IGkyb19tZXNzYWdlIF9faW9tZW0gKm1zZzsKCXUzMiBtOwoJaTJvX3N0YXR1c19ibG9jayAqc2IgPSBjLT5zdGF0dXNfYmxvY2sudmlydDsKCWludCByYzsKCglpMm9fc3RhdHVzX2dldChjKTsKCgkvKiBTeXNRdWllc2NlIGRpc2NhcmRlZCBpZiBJT1Agbm90IGluIFJFQURZIG9yIE9QRVJBVElPTkFMIHN0YXRlICovCglpZiAoKHNiLT5pb3Bfc3RhdGUgIT0gQURBUFRFUl9TVEFURV9SRUFEWSkgJiYKCSAgICAoc2ItPmlvcF9zdGF0ZSAhPSBBREFQVEVSX1NUQVRFX09QRVJBVElPTkFMKSkKCQlyZXR1cm4gMDsKCgltID0gaTJvX21zZ19nZXRfd2FpdChjLCAmbXNnLCBJMk9fVElNRU9VVF9NRVNTQUdFX0dFVCk7CglpZiAobSA9PSBJMk9fUVVFVUVfRU1QVFkpCgkJcmV0dXJuIC1FVElNRURPVVQ7CgoJd3JpdGVsKEZPVVJfV09SRF9NU0dfU0laRSB8IFNHTF9PRkZTRVRfMCwgJm1zZy0+dS5oZWFkWzBdKTsKCXdyaXRlbChJMk9fQ01EX1NZU19RVUlFU0NFIDw8IDI0IHwgSE9TVF9USUQgPDwgMTIgfCBBREFQVEVSX1RJRCwKCSAgICAgICAmbXNnLT51LmhlYWRbMV0pOwoKCS8qIExvbmcgdGltZW91dCBuZWVkZWQgZm9yIHF1aWVzY2UgaWYgbG90cyBvZiBkZXZpY2VzICovCglpZiAoKHJjID0gaTJvX21zZ19wb3N0X3dhaXQoYywgbSwgMjQwKSkpCgkJb3NtX2luZm8oIiVzOiBVbmFibGUgdG8gcXVpZXNjZSAoc3RhdHVzPSUjeCkuXG4iLCBjLT5uYW1lLCAtcmMpOwoJZWxzZQoJCW9zbV9kZWJ1ZygiJXM6IFF1aWVzY2VkLlxuIiwgYy0+bmFtZSk7CgoJaTJvX3N0YXR1c19nZXQoYyk7CS8vIEVudGVyZWQgUkVBRFkgc3RhdGUKCglyZXR1cm4gcmM7Cn07CgovKioKICoJaTJvX2lvcF9lbmFibGUgLSBtb3ZlIGNvbnRyb2xsZXIgZnJvbSByZWFkeSB0byBPUEVSQVRJT05BTAogKglAYzogSTJPIGNvbnRyb2xsZXIKICoKICoJRW5hYmxlIElPUC4gVGhpcyBhbGxvd3MgdGhlIElPUCB0byByZXN1bWUgZXh0ZXJuYWwgb3BlcmF0aW9ucyBhbmQKICoJcmV2ZXJzZXMgdGhlIGVmZmVjdCBvZiBhIHF1aWVzY2UuIFJldHVybnMgemVybyBvciBhbiBlcnJvciBjb2RlIGlmCiAqCWFuIGVycm9yIG9jY3Vycy4KICovCnN0YXRpYyBpbnQgaTJvX2lvcF9lbmFibGUoc3RydWN0IGkyb19jb250cm9sbGVyICpjKQp7CglzdHJ1Y3QgaTJvX21lc3NhZ2UgX19pb21lbSAqbXNnOwoJdTMyIG07CglpMm9fc3RhdHVzX2Jsb2NrICpzYiA9IGMtPnN0YXR1c19ibG9jay52aXJ0OwoJaW50IHJjOwoKCWkyb19zdGF0dXNfZ2V0KGMpOwoKCS8qIEVuYWJsZSBvbmx5IGFsbG93ZWQgb24gUkVBRFkgc3RhdGUgKi8KCWlmIChzYi0+aW9wX3N0YXRlICE9IEFEQVBURVJfU1RBVEVfUkVBRFkpCgkJcmV0dXJuIC1FSU5WQUw7CgoJbSA9IGkyb19tc2dfZ2V0X3dhaXQoYywgJm1zZywgSTJPX1RJTUVPVVRfTUVTU0FHRV9HRVQpOwoJaWYgKG0gPT0gSTJPX1FVRVVFX0VNUFRZKQoJCXJldHVybiAtRVRJTUVET1VUOwoKCXdyaXRlbChGT1VSX1dPUkRfTVNHX1NJWkUgfCBTR0xfT0ZGU0VUXzAsICZtc2ctPnUuaGVhZFswXSk7Cgl3cml0ZWwoSTJPX0NNRF9TWVNfRU5BQkxFIDw8IDI0IHwgSE9TVF9USUQgPDwgMTIgfCBBREFQVEVSX1RJRCwKCSAgICAgICAmbXNnLT51LmhlYWRbMV0pOwoKCS8qIEhvdyBsb25nIG9mIGEgdGltZW91dCBkbyB3ZSBuZWVkPyAqLwoJaWYgKChyYyA9IGkyb19tc2dfcG9zdF93YWl0KGMsIG0sIDI0MCkpKQoJCW9zbV9lcnIoIiVzOiBDb3VsZCBub3QgZW5hYmxlIChzdGF0dXM9JSN4KS5cbiIsIGMtPm5hbWUsIC1yYyk7CgllbHNlCgkJb3NtX2RlYnVnKCIlczogRW5hYmxlZC5cbiIsIGMtPm5hbWUpOwoKCWkyb19zdGF0dXNfZ2V0KGMpOwkvLyBlbnRlcmVkIE9QRVJBVElPTkFMIHN0YXRlCgoJcmV0dXJuIHJjOwp9OwoKLyoqCiAqCWkyb19pb3BfcXVpZXNjZV9hbGwgLSBRdWllc2NlIGFsbCBJMk8gY29udHJvbGxlcnMgb24gdGhlIHN5c3RlbQogKgogKglRdWllc2NlIGFsbCBJMk8gY29udHJvbGxlcnMgd2hpY2ggYXJlIGNvbm5lY3RlZCB0byB0aGUgc3lzdGVtLgogKi8Kc3RhdGljIGlubGluZSB2b2lkIGkyb19pb3BfcXVpZXNjZV9hbGwodm9pZCkKewoJc3RydWN0IGkyb19jb250cm9sbGVyICpjLCAqdG1wOwoKCWxpc3RfZm9yX2VhY2hfZW50cnlfc2FmZShjLCB0bXAsICZpMm9fY29udHJvbGxlcnMsIGxpc3QpIHsKCQlpZiAoIWMtPm5vX3F1aWVzY2UpCgkJCWkyb19pb3BfcXVpZXNjZShjKTsKCX0KfTsKCi8qKgogKglpMm9faW9wX2VuYWJsZV9hbGwgLSBFbmFibGVzIGFsbCBjb250cm9sbGVycyBvbiB0aGUgc3lzdGVtCiAqCiAqCUVuYWJsZXMgYWxsIEkyTyBjb250cm9sbGVycyB3aGljaCBhcmUgY29ubmVjdGVkIHRvIHRoZSBzeXN0ZW0uCiAqLwpzdGF0aWMgaW5saW5lIHZvaWQgaTJvX2lvcF9lbmFibGVfYWxsKHZvaWQpCnsKCXN0cnVjdCBpMm9fY29udHJvbGxlciAqYywgKnRtcDsKCglsaXN0X2Zvcl9lYWNoX2VudHJ5X3NhZmUoYywgdG1wLCAmaTJvX2NvbnRyb2xsZXJzLCBsaXN0KQoJICAgIGkyb19pb3BfZW5hYmxlKGMpOwp9OwoKLyoqCiAqCWkyb19jbGVhcl9jb250cm9sbGVyIC0gQnJpbmcgSTJPIGNvbnRyb2xsZXIgaW50byBIT0xEIHN0YXRlCiAqCUBjOiBjb250cm9sbGVyCiAqCiAqCUNsZWFyIGFuIElPUCB0byBIT0xEIHN0YXRlLCBpZS4gdGVybWluYXRlIGV4dGVybmFsIG9wZXJhdGlvbnMsIGNsZWFyIGFsbAogKglpbnB1dCBxdWV1ZXMgYW5kIHByZXBhcmUgZm9yIGEgc3lzdGVtIHJlc3RhcnQuIElPUCdzIGludGVybmFsIG9wZXJhdGlvbgogKgljb250aW51ZXMgbm9ybWFsbHkgYW5kIHRoZSBvdXRib3VuZCBxdWV1ZSBpcyBhbGl2ZS4gVGhlIElPUCBpcyBub3QKICoJZXhwZWN0ZWQgdG8gcmVidWlsZCBpdHMgTENULgogKgogKglSZXR1cm5zIDAgb24gc3VjY2VzcyBvciBuZWdhdGl2ZSBlcnJvciBjb2RlIG9uIGZhaWx1cmUuCiAqLwpzdGF0aWMgaW50IGkyb19pb3BfY2xlYXIoc3RydWN0IGkyb19jb250cm9sbGVyICpjKQp7CglzdHJ1Y3QgaTJvX21lc3NhZ2UgX19pb21lbSAqbXNnOwoJdTMyIG07CglpbnQgcmM7CgoJbSA9IGkyb19tc2dfZ2V0X3dhaXQoYywgJm1zZywgSTJPX1RJTUVPVVRfTUVTU0FHRV9HRVQpOwoJaWYgKG0gPT0gSTJPX1FVRVVFX0VNUFRZKQoJCXJldHVybiAtRVRJTUVET1VUOwoKCS8qIFF1aWVzY2UgYWxsIElPUHMgZmlyc3QgKi8KCWkyb19pb3BfcXVpZXNjZV9hbGwoKTsKCgl3cml0ZWwoRk9VUl9XT1JEX01TR19TSVpFIHwgU0dMX09GRlNFVF8wLCAmbXNnLT51LmhlYWRbMF0pOwoJd3JpdGVsKEkyT19DTURfQURBUFRFUl9DTEVBUiA8PCAyNCB8IEhPU1RfVElEIDw8IDEyIHwgQURBUFRFUl9USUQsCgkgICAgICAgJm1zZy0+dS5oZWFkWzFdKTsKCglpZiAoKHJjID0gaTJvX21zZ19wb3N0X3dhaXQoYywgbSwgMzApKSkKCQlvc21faW5mbygiJXM6IFVuYWJsZSB0byBjbGVhciAoc3RhdHVzPSUjeCkuXG4iLCBjLT5uYW1lLCAtcmMpOwoJZWxzZQoJCW9zbV9kZWJ1ZygiJXM6IENsZWFyZWQuXG4iLCBjLT5uYW1lKTsKCgkvKiBFbmFibGUgYWxsIElPUHMgKi8KCWkyb19pb3BfZW5hYmxlX2FsbCgpOwoKCXJldHVybiByYzsKfQoKLyoqCiAqCWkyb19pb3BfaW5pdF9vdXRib3VuZF9xdWV1ZSAtIHNldHVwIHRoZSBvdXRib3VuZCBtZXNzYWdlIHF1ZXVlCiAqCUBjOiBJMk8gY29udHJvbGxlcgogKgogKglDbGVhciBhbmQgKHJlKWluaXRpYWxpemUgSU9QJ3Mgb3V0Ym91bmQgcXVldWUgYW5kIHBvc3QgdGhlIG1lc3NhZ2UKICoJZnJhbWVzIHRvIHRoZSBJT1AuCiAqCiAqCVJldHVybnMgMCBvbiBzdWNjZXNzIG9yIGEgbmVnYXRpdmUgZXJybm8gY29kZSBvbiBmYWlsdXJlLgogKi8Kc3RhdGljIGludCBpMm9faW9wX2luaXRfb3V0Ym91bmRfcXVldWUoc3RydWN0IGkyb19jb250cm9sbGVyICpjKQp7Cgl2b2xhdGlsZSB1OCAqc3RhdHVzID0gYy0+c3RhdHVzLnZpcnQ7Cgl1MzIgbTsKCXN0cnVjdCBpMm9fbWVzc2FnZSBfX2lvbWVtICptc2c7Cgl1bG9uZyB0aW1lb3V0OwoJaW50IGk7CgoJb3NtX2RlYnVnKCIlczogSW5pdGlhbGl6aW5nIE91dGJvdW5kIFF1ZXVlLi4uXG4iLCBjLT5uYW1lKTsKCgltZW1zZXQoYy0+c3RhdHVzLnZpcnQsIDAsIDQpOwoKCW0gPSBpMm9fbXNnX2dldF93YWl0KGMsICZtc2csIEkyT19USU1FT1VUX01FU1NBR0VfR0VUKTsKCWlmIChtID09IEkyT19RVUVVRV9FTVBUWSkKCQlyZXR1cm4gLUVUSU1FRE9VVDsKCgl3cml0ZWwoRUlHSFRfV09SRF9NU0dfU0laRSB8IFNHTF9PRkZTRVRfNiwgJm1zZy0+dS5oZWFkWzBdKTsKCXdyaXRlbChJMk9fQ01EX09VVEJPVU5EX0lOSVQgPDwgMjQgfCBIT1NUX1RJRCA8PCAxMiB8IEFEQVBURVJfVElELAoJICAgICAgICZtc2ctPnUuaGVhZFsxXSk7Cgl3cml0ZWwoaTJvX2V4ZWNfZHJpdmVyLmNvbnRleHQsICZtc2ctPnUucy5pY250eHQpOwoJd3JpdGVsKDB4MDAwMDAwMDAsICZtc2ctPnUucy50Y250eHQpOwoJd3JpdGVsKFBBR0VfU0laRSwgJm1zZy0+Ym9keVswXSk7CgkvKiBPdXRib3VuZCBtc2cgZnJhbWUgc2l6ZSBpbiB3b3JkcyBhbmQgSW5pdGNvZGUgKi8KCXdyaXRlbChJMk9fT1VUQk9VTkRfTVNHX0ZSQU1FX1NJWkUgPDwgMTYgfCAweDgwLCAmbXNnLT5ib2R5WzFdKTsKCXdyaXRlbCgweGQwMDAwMDA0LCAmbXNnLT5ib2R5WzJdKTsKCXdyaXRlbChpMm9fZG1hX2xvdyhjLT5zdGF0dXMucGh5cyksICZtc2ctPmJvZHlbM10pOwoJd3JpdGVsKGkyb19kbWFfaGlnaChjLT5zdGF0dXMucGh5cyksICZtc2ctPmJvZHlbNF0pOwoKCWkyb19tc2dfcG9zdChjLCBtKTsKCgl0aW1lb3V0ID0gamlmZmllcyArIEkyT19USU1FT1VUX0lOSVRfT1VUQk9VTkRfUVVFVUUgKiBIWjsKCXdoaWxlICgqc3RhdHVzIDw9IEkyT19DTURfSU5fUFJPR1JFU1MpIHsKCQlpZiAodGltZV9hZnRlcihqaWZmaWVzLCB0aW1lb3V0KSkgewoJCQlvc21fd2FybigiJXM6IFRpbWVvdXQgSW5pdGlhbGl6aW5nXG4iLCBjLT5uYW1lKTsKCQkJcmV0dXJuIC1FVElNRURPVVQ7CgkJfQoJCXNldF9jdXJyZW50X3N0YXRlKFRBU0tfVU5JTlRFUlJVUFRJQkxFKTsKCQlzY2hlZHVsZV90aW1lb3V0KDEpOwoJfQoKCW0gPSBjLT5vdXRfcXVldWUucGh5czsKCgkvKiBQb3N0IGZyYW1lcyAqLwoJZm9yIChpID0gMDsgaSA8IEkyT19NQVhfT1VUQk9VTkRfTVNHX0ZSQU1FUzsgaSsrKSB7CgkJaTJvX2ZsdXNoX3JlcGx5KGMsIG0pOwoJCXVkZWxheSgxKTsJLyogUHJvbWlzZSAqLwoJCW0gKz0gSTJPX09VVEJPVU5EX01TR19GUkFNRV9TSVpFICogc2l6ZW9mKHUzMik7Cgl9CgoJcmV0dXJuIDA7Cn0KCi8qKgogKglpMm9faW9wX3Jlc2V0IC0gcmVzZXQgYW4gSTJPIGNvbnRyb2xsZXIKICoJQGM6IGNvbnRyb2xsZXIgdG8gcmVzZXQKICoKICoJUmVzZXQgdGhlIElPUCBpbnRvIElOSVQgc3RhdGUgYW5kIHdhaXQgdW50aWwgSU9QIGdldHMgaW50byBSRVNFVCBzdGF0ZS4KICoJVGVybWluYXRlIGFsbCBleHRlcm5hbCBvcGVyYXRpb25zLCBjbGVhciBJT1AncyBpbmJvdW5kIGFuZCBvdXRib3VuZAogKglxdWV1ZXMsIHRlcm1pbmF0ZSBhbGwgRERNcywgYW5kIHJlbG9hZCB0aGUgSU9QJ3Mgb3BlcmF0aW5nIGVudmlyb25tZW50CiAqCWFuZCBhbGwgbG9jYWwgRERNcy4gVGhlIElPUCByZWJ1aWxkcyBpdHMgTENULgogKi8Kc3RhdGljIGludCBpMm9faW9wX3Jlc2V0KHN0cnVjdCBpMm9fY29udHJvbGxlciAqYykKewoJdm9sYXRpbGUgdTggKnN0YXR1cyA9IGMtPnN0YXR1cy52aXJ0OwoJc3RydWN0IGkyb19tZXNzYWdlIF9faW9tZW0gKm1zZzsKCXUzMiBtOwoJdW5zaWduZWQgbG9uZyB0aW1lb3V0OwoJaTJvX3N0YXR1c19ibG9jayAqc2IgPSBjLT5zdGF0dXNfYmxvY2sudmlydDsKCWludCByYyA9IDA7CgoJb3NtX2RlYnVnKCIlczogUmVzZXR0aW5nIGNvbnRyb2xsZXJcbiIsIGMtPm5hbWUpOwoKCW0gPSBpMm9fbXNnX2dldF93YWl0KGMsICZtc2csIEkyT19USU1FT1VUX01FU1NBR0VfR0VUKTsKCWlmIChtID09IEkyT19RVUVVRV9FTVBUWSkKCQlyZXR1cm4gLUVUSU1FRE9VVDsKCgltZW1zZXQoYy0+c3RhdHVzX2Jsb2NrLnZpcnQsIDAsIDgpOwoKCS8qIFF1aWVzY2UgYWxsIElPUHMgZmlyc3QgKi8KCWkyb19pb3BfcXVpZXNjZV9hbGwoKTsKCgl3cml0ZWwoRUlHSFRfV09SRF9NU0dfU0laRSB8IFNHTF9PRkZTRVRfMCwgJm1zZy0+dS5oZWFkWzBdKTsKCXdyaXRlbChJMk9fQ01EX0FEQVBURVJfUkVTRVQgPDwgMjQgfCBIT1NUX1RJRCA8PCAxMiB8IEFEQVBURVJfVElELAoJICAgICAgICZtc2ctPnUuaGVhZFsxXSk7Cgl3cml0ZWwoaTJvX2V4ZWNfZHJpdmVyLmNvbnRleHQsICZtc2ctPnUucy5pY250eHQpOwoJd3JpdGVsKDAsICZtc2ctPnUucy50Y250eHQpOwkvL0ZJWE1FOiB1c2UgcmVhc29uYWJsZSB0cmFuc2FjdGlvbiBjb250ZXh0Cgl3cml0ZWwoMCwgJm1zZy0+Ym9keVswXSk7Cgl3cml0ZWwoMCwgJm1zZy0+Ym9keVsxXSk7Cgl3cml0ZWwoaTJvX2RtYV9sb3coYy0+c3RhdHVzLnBoeXMpLCAmbXNnLT5ib2R5WzJdKTsKCXdyaXRlbChpMm9fZG1hX2hpZ2goYy0+c3RhdHVzLnBoeXMpLCAmbXNnLT5ib2R5WzNdKTsKCglpMm9fbXNnX3Bvc3QoYywgbSk7CgoJLyogV2FpdCBmb3IgYSByZXBseSAqLwoJdGltZW91dCA9IGppZmZpZXMgKyBJMk9fVElNRU9VVF9SRVNFVCAqIEhaOwoJd2hpbGUgKCEqc3RhdHVzKSB7CgkJaWYgKHRpbWVfYWZ0ZXIoamlmZmllcywgdGltZW91dCkpCgkJCWJyZWFrOwoKCQlzZXRfY3VycmVudF9zdGF0ZShUQVNLX1VOSU5URVJSVVBUSUJMRSk7CgkJc2NoZWR1bGVfdGltZW91dCgxKTsKCX0KCglzd2l0Y2ggKCpzdGF0dXMpIHsKCWNhc2UgSTJPX0NNRF9SRUpFQ1RFRDoKCQlvc21fd2FybigiJXM6IElPUCByZXNldCByZWplY3RlZFxuIiwgYy0+bmFtZSk7CgkJcmMgPSAtRVBFUk07CgkJYnJlYWs7CgoJY2FzZSBJMk9fQ01EX0lOX1BST0dSRVNTOgoJCS8qCgkJICogT25jZSB0aGUgcmVzZXQgaXMgc2VudCwgdGhlIElPUCBnb2VzIGludG8gdGhlIElOSVQgc3RhdGUKCQkgKiB3aGljaCBpcyBpbmRldGVybWluYXRlLiBXZSBuZWVkIHRvIHdhaXQgdW50aWwgdGhlIElPUCBoYXMKCQkgKiByZWJvb3RlZCBiZWZvcmUgd2UgY2FuIGxldCB0aGUgc3lzdGVtIHRhbGsgdG8gaXQuIFdlIHJlYWQKCQkgKiB0aGUgaW5ib3VuZCBGcmVlX0xpc3QgdW50aWwgYSBtZXNzYWdlIGlzIGF2YWlsYWJsZS4gSWYgd2UKCQkgKiBjYW4ndCByZWFkIG9uZSBpbiB0aGUgZ2l2ZW4gYW1tb3VudCBvZiB0aW1lLCB3ZSBhc3N1bWUgdGhlCgkJICogSU9QIGNvdWxkIG5vdCByZWJvb3QgcHJvcGVybHkuCgkJICovCgkJb3NtX2RlYnVnKCIlczogUmVzZXQgaW4gcHJvZ3Jlc3MsIHdhaXRpbmcgZm9yIHJlYm9vdC4uLlxuIiwKCQkJICBjLT5uYW1lKTsKCgkJbSA9IGkyb19tc2dfZ2V0X3dhaXQoYywgJm1zZywgSTJPX1RJTUVPVVRfUkVTRVQpOwoJCXdoaWxlIChtID09IEkyT19RVUVVRV9FTVBUWSkgewoJCQlpZiAodGltZV9hZnRlcihqaWZmaWVzLCB0aW1lb3V0KSkgewoJCQkJb3NtX2VycigiJXM6IElPUCByZXNldCB0aW1lb3V0LlxuIiwgYy0+bmFtZSk7CgkJCQlyYyA9IC1FVElNRURPVVQ7CgkJCQlnb3RvIGV4aXQ7CgkJCX0KCQkJc2V0X2N1cnJlbnRfc3RhdGUoVEFTS19VTklOVEVSUlVQVElCTEUpOwoJCQlzY2hlZHVsZV90aW1lb3V0KDEpOwoKCQkJbSA9IGkyb19tc2dfZ2V0X3dhaXQoYywgJm1zZywgSTJPX1RJTUVPVVRfUkVTRVQpOwoJCX0KCQlpMm9fbXNnX25vcChjLCBtKTsKCgkJLyogZnJvbSBoZXJlIGFsbCBxdWllc2NlIGNvbW1hbmRzIGFyZSBzYWZlICovCgkJYy0+bm9fcXVpZXNjZSA9IDA7CgoJCS8qIHZlcmlmeSBpZiBjb250cm9sbGVyIGlzIGluIHN0YXRlIFJFU0VUICovCgkJaTJvX3N0YXR1c19nZXQoYyk7CgoJCWlmICghYy0+cHJvbWlzZSAmJiAoc2ItPmlvcF9zdGF0ZSAhPSBBREFQVEVSX1NUQVRFX1JFU0VUKSkKCQkJb3NtX3dhcm4oIiVzOiByZXNldCBjb21wbGV0ZWQsIGJ1dCBhZGFwdGVyIG5vdCBpbiBSRVNFVCIKCQkJCSAiIHN0YXRlLlxuIiwgYy0+bmFtZSk7CgkJZWxzZQoJCQlvc21fZGVidWcoIiVzOiByZXNldCBjb21wbGV0ZWQuXG4iLCBjLT5uYW1lKTsKCgkJYnJlYWs7CgoJZGVmYXVsdDoKCQlvc21fZXJyKCIlczogSU9QIHJlc2V0IHRpbWVvdXQuXG4iLCBjLT5uYW1lKTsKCQlyYyA9IC1FVElNRURPVVQ7CgkJYnJlYWs7Cgl9CgogICAgICBleGl0OgoJLyogRW5hYmxlIGFsbCBJT1BzICovCglpMm9faW9wX2VuYWJsZV9hbGwoKTsKCglyZXR1cm4gcmM7Cn07CgovKioKICoJaTJvX2lvcF9hY3RpdmF0ZSAtIEJyaW5nIGNvbnRyb2xsZXIgdXAgdG8gSE9MRAogKglAYzogY29udHJvbGxlcgogKgogKglUaGlzIGZ1bmN0aW9uIGJyaW5ncyBhbiBJMk8gY29udHJvbGxlciBpbnRvIEhPTEQgc3RhdGUuIFRoZSBhZGFwdGVyCiAqCWlzIHJlc2V0IGlmIG5lY2Vzc2FyeSBhbmQgdGhlbiB0aGUgcXVldWVzIGFuZCByZXNvdXJjZSB0YWJsZSBhcmUgcmVhZC4KICoKICoJUmV0dXJucyAwIG9uIHN1Y2Nlc3Mgb3IgbmVnYXRpdmUgZXJyb3IgY29kZSBvbiBmYWlsdXJlLgogKi8Kc3RhdGljIGludCBpMm9faW9wX2FjdGl2YXRlKHN0cnVjdCBpMm9fY29udHJvbGxlciAqYykKewoJaTJvX3N0YXR1c19ibG9jayAqc2IgPSBjLT5zdGF0dXNfYmxvY2sudmlydDsKCWludCByYzsKCWludCBzdGF0ZTsKCgkvKiBJbiBJTklUIHN0YXRlLCBXYWl0IEluYm91bmQgUSB0byBpbml0aWFsaXplIChpbiBpMm9fc3RhdHVzX2dldCkgKi8KCS8qIEluIFJFQURZIHN0YXRlLCBHZXQgc3RhdHVzICovCgoJcmMgPSBpMm9fc3RhdHVzX2dldChjKTsKCWlmIChyYykgewoJCW9zbV9pbmZvKCIlczogVW5hYmxlIHRvIG9idGFpbiBzdGF0dXMsIGF0dGVtcHRpbmcgYSByZXNldC5cbiIsCgkJCSBjLT5uYW1lKTsKCQlyYyA9IGkyb19pb3BfcmVzZXQoYyk7CgkJaWYgKHJjKQoJCQlyZXR1cm4gcmM7Cgl9CgoJaWYgKHNiLT5pMm9fdmVyc2lvbiA+IEkyT1ZFUjE1KSB7CgkJb3NtX2VycigiJXM6IE5vdCBydW5uaW5nIHZlcnNpb24gMS41IG9mIHRoZSBJMk8gU3BlY2lmaWNhdGlvbi4iCgkJCSJcbiIsIGMtPm5hbWUpOwoJCXJldHVybiAtRU5PREVWOwoJfQoKCXN3aXRjaCAoc2ItPmlvcF9zdGF0ZSkgewoJY2FzZSBBREFQVEVSX1NUQVRFX0ZBVUxURUQ6CgkJb3NtX2VycigiJXM6IGhhcmR3YXJlIGZhdWx0XG4iLCBjLT5uYW1lKTsKCQlyZXR1cm4gLUVGQVVMVDsKCgljYXNlIEFEQVBURVJfU1RBVEVfUkVBRFk6CgljYXNlIEFEQVBURVJfU1RBVEVfT1BFUkFUSU9OQUw6CgljYXNlIEFEQVBURVJfU1RBVEVfSE9MRDoKCWNhc2UgQURBUFRFUl9TVEFURV9GQUlMRUQ6CgkJb3NtX2RlYnVnKCIlczogYWxyZWFkeSBydW5uaW5nLCB0cnlpbmcgdG8gcmVzZXQuLi5cbiIsIGMtPm5hbWUpOwoJCXJjID0gaTJvX2lvcF9yZXNldChjKTsKCQlpZiAocmMpCgkJCXJldHVybiByYzsKCX0KCgkvKiBwcmVzZXJ2ZSBzdGF0ZSAqLwoJc3RhdGUgPSBzYi0+aW9wX3N0YXRlOwoKCXJjID0gaTJvX2lvcF9pbml0X291dGJvdW5kX3F1ZXVlKGMpOwoJaWYgKHJjKQoJCXJldHVybiByYzsKCgkvKiBpZiBhZGFwdGVyIHdhcyBub3QgaW4gUkVTRVQgc3RhdGUgY2xlYXIgbm93ICovCglpZiAoc3RhdGUgIT0gQURBUFRFUl9TVEFURV9SRVNFVCkKCQlpMm9faW9wX2NsZWFyKGMpOwoKCWkyb19zdGF0dXNfZ2V0KGMpOwoKCWlmIChzYi0+aW9wX3N0YXRlICE9IEFEQVBURVJfU1RBVEVfSE9MRCkgewoJCW9zbV9lcnIoIiVzOiBmYWlsZWQgdG8gYnJpbmcgSU9QIGludG8gSE9MRCBzdGF0ZVxuIiwgYy0+bmFtZSk7CgkJcmV0dXJuIC1FSU87Cgl9CgoJcmV0dXJuIGkyb19ocnRfZ2V0KGMpOwp9OwoKLyoqCiAqCWkyb19pb3Bfc3lzdGFiX3NldCAtIFNldCB0aGUgSTJPIFN5c3RlbSBUYWJsZSBvZiB0aGUgc3BlY2lmaWVkIElPUAogKglAYzogSTJPIGNvbnRyb2xsZXIgdG8gd2hpY2ggdGhlIHN5c3RlbSB0YWJsZSBzaG91bGQgYmUgc2VuZAogKgogKglCZWZvcmUgdGhlIHN5c3RhYiBjb3VsZCBiZSBzZXQgaTJvX3N5c3RhYl9idWlsZCgpIG11c3QgYmUgY2FsbGVkLgogKgogKglSZXR1cm5zIDAgb24gc3VjY2VzcyBvciBuZWdhdGl2ZSBlcnJvciBjb2RlIG9uIGZhaWx1cmUuCiAqLwpzdGF0aWMgaW50IGkyb19pb3Bfc3lzdGFiX3NldChzdHJ1Y3QgaTJvX2NvbnRyb2xsZXIgKmMpCnsKCXN0cnVjdCBpMm9fbWVzc2FnZSBfX2lvbWVtICptc2c7Cgl1MzIgbTsKCWkyb19zdGF0dXNfYmxvY2sgKnNiID0gYy0+c3RhdHVzX2Jsb2NrLnZpcnQ7CglzdHJ1Y3QgZGV2aWNlICpkZXYgPSAmYy0+cGRldi0+ZGV2OwoJc3RydWN0IHJlc291cmNlICpyb290OwoJaW50IHJjOwoKCWlmIChzYi0+Y3VycmVudF9tZW1fc2l6ZSA8IHNiLT5kZXNpcmVkX21lbV9zaXplKSB7CgkJc3RydWN0IHJlc291cmNlICpyZXMgPSAmYy0+bWVtX3Jlc291cmNlOwoJCXJlcy0+bmFtZSA9IGMtPnBkZXYtPmJ1cy0+bmFtZTsKCQlyZXMtPmZsYWdzID0gSU9SRVNPVVJDRV9NRU07CgkJcmVzLT5zdGFydCA9IDA7CgkJcmVzLT5lbmQgPSAwOwoJCW9zbV9pbmZvKCIlczogcmVxdWlyZXMgcHJpdmF0ZSBtZW1vcnkgcmVzb3VyY2VzLlxuIiwgYy0+bmFtZSk7CgkJcm9vdCA9IHBjaV9maW5kX3BhcmVudF9yZXNvdXJjZShjLT5wZGV2LCByZXMpOwoJCWlmIChyb290ID09IE5VTEwpCgkJCW9zbV93YXJuKCIlczogQ2FuJ3QgZmluZCBwYXJlbnQgcmVzb3VyY2UhXG4iLCBjLT5uYW1lKTsKCQlpZiAocm9vdCAmJiBhbGxvY2F0ZV9yZXNvdXJjZShyb290LCByZXMsIHNiLT5kZXNpcmVkX21lbV9zaXplLCBzYi0+ZGVzaXJlZF9tZW1fc2l6ZSwgc2ItPmRlc2lyZWRfbWVtX3NpemUsIDEgPDwgMjAsCS8qIFVuc3BlY2lmaWVkLCBzbyB1c2UgMU1iIGFuZCBwbGF5IHNhZmUgKi8KCQkJCQkgICAgICBOVUxMLCBOVUxMKSA+PSAwKSB7CgkJCWMtPm1lbV9hbGxvYyA9IDE7CgkJCXNiLT5jdXJyZW50X21lbV9zaXplID0gMSArIHJlcy0+ZW5kIC0gcmVzLT5zdGFydDsKCQkJc2ItPmN1cnJlbnRfbWVtX2Jhc2UgPSByZXMtPnN0YXJ0OwoJCQlvc21faW5mbygiJXM6IGFsbG9jYXRlZCAlbGQgYnl0ZXMgb2YgUENJIG1lbW9yeSBhdCAiCgkJCQkgIjB4JTA4bFguXG4iLCBjLT5uYW1lLAoJCQkJIDEgKyByZXMtPmVuZCAtIHJlcy0+c3RhcnQsIHJlcy0+c3RhcnQpOwoJCX0KCX0KCglpZiAoc2ItPmN1cnJlbnRfaW9fc2l6ZSA8IHNiLT5kZXNpcmVkX2lvX3NpemUpIHsKCQlzdHJ1Y3QgcmVzb3VyY2UgKnJlcyA9ICZjLT5pb19yZXNvdXJjZTsKCQlyZXMtPm5hbWUgPSBjLT5wZGV2LT5idXMtPm5hbWU7CgkJcmVzLT5mbGFncyA9IElPUkVTT1VSQ0VfSU87CgkJcmVzLT5zdGFydCA9IDA7CgkJcmVzLT5lbmQgPSAwOwoJCW9zbV9pbmZvKCIlczogcmVxdWlyZXMgcHJpdmF0ZSBtZW1vcnkgcmVzb3VyY2VzLlxuIiwgYy0+bmFtZSk7CgkJcm9vdCA9IHBjaV9maW5kX3BhcmVudF9yZXNvdXJjZShjLT5wZGV2LCByZXMpOwoJCWlmIChyb290ID09IE5VTEwpCgkJCW9zbV93YXJuKCIlczogQ2FuJ3QgZmluZCBwYXJlbnQgcmVzb3VyY2UhXG4iLCBjLT5uYW1lKTsKCQlpZiAocm9vdCAmJiBhbGxvY2F0ZV9yZXNvdXJjZShyb290LCByZXMsIHNiLT5kZXNpcmVkX2lvX3NpemUsIHNiLT5kZXNpcmVkX2lvX3NpemUsIHNiLT5kZXNpcmVkX2lvX3NpemUsIDEgPDwgMjAsCS8qIFVuc3BlY2lmaWVkLCBzbyB1c2UgMU1iIGFuZCBwbGF5IHNhZmUgKi8KCQkJCQkgICAgICBOVUxMLCBOVUxMKSA+PSAwKSB7CgkJCWMtPmlvX2FsbG9jID0gMTsKCQkJc2ItPmN1cnJlbnRfaW9fc2l6ZSA9IDEgKyByZXMtPmVuZCAtIHJlcy0+c3RhcnQ7CgkJCXNiLT5jdXJyZW50X21lbV9iYXNlID0gcmVzLT5zdGFydDsKCQkJb3NtX2luZm8oIiVzOiBhbGxvY2F0ZWQgJWxkIGJ5dGVzIG9mIFBDSSBJL08gYXQgMHglMDhsWCIKCQkJCSAiLlxuIiwgYy0+bmFtZSwgMSArIHJlcy0+ZW5kIC0gcmVzLT5zdGFydCwKCQkJCSByZXMtPnN0YXJ0KTsKCQl9Cgl9CgoJbSA9IGkyb19tc2dfZ2V0X3dhaXQoYywgJm1zZywgSTJPX1RJTUVPVVRfTUVTU0FHRV9HRVQpOwoJaWYgKG0gPT0gSTJPX1FVRVVFX0VNUFRZKQoJCXJldHVybiAtRVRJTUVET1VUOwoKCWkyb19zeXN0YWIucGh5cyA9IGRtYV9tYXBfc2luZ2xlKGRldiwgaTJvX3N5c3RhYi52aXJ0LCBpMm9fc3lzdGFiLmxlbiwKCQkJCQkgUENJX0RNQV9UT0RFVklDRSk7CglpZiAoIWkyb19zeXN0YWIucGh5cykgewoJCWkyb19tc2dfbm9wKGMsIG0pOwoJCXJldHVybiAtRU5PTUVNOwoJfQoKCXdyaXRlbChJMk9fTUVTU0FHRV9TSVpFKDEyKSB8IFNHTF9PRkZTRVRfNiwgJm1zZy0+dS5oZWFkWzBdKTsKCXdyaXRlbChJMk9fQ01EX1NZU19UQUJfU0VUIDw8IDI0IHwgSE9TVF9USUQgPDwgMTIgfCBBREFQVEVSX1RJRCwKCSAgICAgICAmbXNnLT51LmhlYWRbMV0pOwoKCS8qCgkgKiBQcm92aWRlIHRocmVlIFNHTC1lbGVtZW50czoKCSAqIFN5c3RlbSB0YWJsZSAoU3lzVGFiKSwgUHJpdmF0ZSBtZW1vcnkgc3BhY2UgZGVjbGFyYXRpb24gYW5kCgkgKiBQcml2YXRlIGkvbyBzcGFjZSBkZWNsYXJhdGlvbgoJICoKCSAqIEZJWE1FOiBpcyB0aGlzIHN0aWxsIHRydWU/CgkgKiBOYXN0eSBvbmUgaGVyZS4gV2UgY2FuJ3QgdXNlIGRtYV9hbGxvY19jb2hlcmVudCB0byBzZW5kIHRoZQoJICogc2FtZSB0YWJsZSB0byBldmVyeW9uZS4gV2UgaGF2ZSB0byBnbyByZW1hcCBpdCBmb3IgdGhlbSBhbGwKCSAqLwoKCXdyaXRlbChjLT51bml0ICsgMiwgJm1zZy0+Ym9keVswXSk7Cgl3cml0ZWwoMCwgJm1zZy0+Ym9keVsxXSk7Cgl3cml0ZWwoMHg1NDAwMDAwMCB8IGkyb19zeXN0YWIubGVuLCAmbXNnLT5ib2R5WzJdKTsKCXdyaXRlbChpMm9fc3lzdGFiLnBoeXMsICZtc2ctPmJvZHlbM10pOwoJd3JpdGVsKDB4NTQwMDAwMDAgfCBzYi0+Y3VycmVudF9tZW1fc2l6ZSwgJm1zZy0+Ym9keVs0XSk7Cgl3cml0ZWwoc2ItPmN1cnJlbnRfbWVtX2Jhc2UsICZtc2ctPmJvZHlbNV0pOwoJd3JpdGVsKDB4ZDQwMDAwMDAgfCBzYi0+Y3VycmVudF9pb19zaXplLCAmbXNnLT5ib2R5WzZdKTsKCXdyaXRlbChzYi0+Y3VycmVudF9pb19iYXNlLCAmbXNnLT5ib2R5WzZdKTsKCglyYyA9IGkyb19tc2dfcG9zdF93YWl0KGMsIG0sIDEyMCk7CgoJZG1hX3VubWFwX3NpbmdsZShkZXYsIGkyb19zeXN0YWIucGh5cywgaTJvX3N5c3RhYi5sZW4sCgkJCSBQQ0lfRE1BX1RPREVWSUNFKTsKCglpZiAocmMgPCAwKQoJCW9zbV9lcnIoIiVzOiBVbmFibGUgdG8gc2V0IFN5c1RhYiAoc3RhdHVzPSUjeCkuXG4iLCBjLT5uYW1lLAoJCQktcmMpOwoJZWxzZQoJCW9zbV9kZWJ1ZygiJXM6IFN5c1RhYiBzZXQuXG4iLCBjLT5uYW1lKTsKCglpMm9fc3RhdHVzX2dldChjKTsJLy8gRW50ZXJlZCBSRUFEWSBzdGF0ZQoKCXJldHVybiByYzsKfQoKLyoqCiAqCWkyb19pb3Bfb25saW5lIC0gQnJpbmcgYSBjb250cm9sbGVyIG9ubGluZSBpbnRvIE9QRVJBVElPTkFMIHN0YXRlLgogKglAYzogSTJPIGNvbnRyb2xsZXIKICoKICoJU2VuZCB0aGUgc3lzdGVtIHRhYmxlIGFuZCBlbmFibGUgdGhlIEkyTyBjb250cm9sbGVyLgogKgogKglSZXR1cm5zIDAgb24gc3VjY2VzcyBvciBuZWdhdGl2ZXIgZXJyb3IgY29kZSBvbiBmYWlsdXJlLgogKi8Kc3RhdGljIGludCBpMm9faW9wX29ubGluZShzdHJ1Y3QgaTJvX2NvbnRyb2xsZXIgKmMpCnsKCWludCByYzsKCglyYyA9IGkyb19pb3Bfc3lzdGFiX3NldChjKTsKCWlmIChyYykKCQlyZXR1cm4gcmM7CgoJLyogSW4gUkVBRFkgc3RhdGUgKi8KCW9zbV9kZWJ1ZygiJXM6IEF0dGVtcHRpbmcgdG8gZW5hYmxlLi4uXG4iLCBjLT5uYW1lKTsKCXJjID0gaTJvX2lvcF9lbmFibGUoYyk7CglpZiAocmMpCgkJcmV0dXJuIHJjOwoKCXJldHVybiAwOwp9OwoKLyoqCiAqCWkyb19pb3BfcmVtb3ZlIC0gUmVtb3ZlIHRoZSBJMk8gY29udHJvbGxlciBmcm9tIHRoZSBJMk8gY29yZQogKglAYzogSTJPIGNvbnRyb2xsZXIKICoKICoJUmVtb3ZlIHRoZSBJMk8gY29udHJvbGxlciBmcm9tIHRoZSBJMk8gY29yZS4gSWYgZGV2aWNlcyBhcmUgYXR0YWNoZWQgdG8KICoJdGhlIGNvbnRyb2xsZXIgcmVtb3ZlIHRoZXNlIGFsc28gYW5kIGZpbmFsbHkgcmVzZXQgdGhlIGNvbnRyb2xsZXIuCiAqLwp2b2lkIGkyb19pb3BfcmVtb3ZlKHN0cnVjdCBpMm9fY29udHJvbGxlciAqYykKewoJc3RydWN0IGkyb19kZXZpY2UgKmRldiwgKnRtcDsKCglvc21fZGVidWcoIiVzOiBkZWxldGluZyBjb250cm9sbGVyXG4iLCBjLT5uYW1lKTsKCglpMm9fZHJpdmVyX25vdGlmeV9jb250cm9sbGVyX3JlbW92ZV9hbGwoYyk7CgoJbGlzdF9kZWwoJmMtPmxpc3QpOwoKCWxpc3RfZm9yX2VhY2hfZW50cnlfc2FmZShkZXYsIHRtcCwgJmMtPmRldmljZXMsIGxpc3QpCgkgICAgaTJvX2RldmljZV9yZW1vdmUoZGV2KTsKCgljbGFzc19kZXZpY2VfdW5yZWdpc3RlcihjLT5jbGFzc2Rldik7CglkZXZpY2VfZGVsKCZjLT5kZXZpY2UpOwoKCS8qIEFzayB0aGUgSU9QIHRvIHN3aXRjaCB0byBSRVNFVCBzdGF0ZSAqLwoJaTJvX2lvcF9yZXNldChjKTsKCglwdXRfZGV2aWNlKCZjLT5kZXZpY2UpOwp9CgovKioKICoJaTJvX3N5c3RhYl9idWlsZCAtIEJ1aWxkIHN5c3RlbSB0YWJsZQogKgogKglUaGUgc3lzdGVtIHRhYmxlIGNvbnRhaW5zIGluZm9ybWF0aW9uIGFib3V0IGFsbCB0aGUgSU9QcyBpbiB0aGUgc3lzdGVtCiAqCShkdWgpIGFuZCBpcyB1c2VkIGJ5IHRoZSBFeGVjdXRpdmVzIG9uIHRoZSBJT1BzIHRvIGVzdGFibGlzaCBwZWVyMnBlZXIKICoJY29ubmVjdGlvbnMuIFdlJ3JlIG5vdCBzdXBwb3J0aW5nIHBlZXIycGVlciBhdCB0aGUgbW9tZW50LCBidXQgdGhpcwogKgl3aWxsIGJlIG5lZWRlZCBkb3duIHRoZSByb2FkIGZvciB0aGluZ3MgbGlrZSBsYW4ybGFuIGZvcndhcmRpbmcuCiAqCiAqCVJldHVybnMgMCBvbiBzdWNjZXNzIG9yIG5lZ2F0aXZlIGVycm9yIGNvZGUgb24gZmFpbHVyZS4KICovCnN0YXRpYyBpbnQgaTJvX3N5c3RhYl9idWlsZCh2b2lkKQp7CglzdHJ1Y3QgaTJvX2NvbnRyb2xsZXIgKmMsICp0bXA7CglpbnQgbnVtX2NvbnRyb2xsZXJzID0gMDsKCXUzMiBjaGFuZ2VfaW5kID0gMDsKCWludCBjb3VudCA9IDA7CglzdHJ1Y3QgaTJvX3N5c190YmwgKnN5c3RhYiA9IGkyb19zeXN0YWIudmlydDsKCglsaXN0X2Zvcl9lYWNoX2VudHJ5X3NhZmUoYywgdG1wLCAmaTJvX2NvbnRyb2xsZXJzLCBsaXN0KQoJICAgIG51bV9jb250cm9sbGVycysrOwoKCWlmIChzeXN0YWIpIHsKCQljaGFuZ2VfaW5kID0gc3lzdGFiLT5jaGFuZ2VfaW5kOwoJCWtmcmVlKGkyb19zeXN0YWIudmlydCk7Cgl9CgoJLyogSGVhZGVyICsgSU9QcyAqLwoJaTJvX3N5c3RhYi5sZW4gPSBzaXplb2Yoc3RydWN0IGkyb19zeXNfdGJsKSArIG51bV9jb250cm9sbGVycyAqCgkgICAgc2l6ZW9mKHN0cnVjdCBpMm9fc3lzX3RibF9lbnRyeSk7CgoJc3lzdGFiID0gaTJvX3N5c3RhYi52aXJ0ID0ga21hbGxvYyhpMm9fc3lzdGFiLmxlbiwgR0ZQX0tFUk5FTCk7CglpZiAoIXN5c3RhYikgewoJCW9zbV9lcnIoInVuYWJsZSB0byBhbGxvY2F0ZSBtZW1vcnkgZm9yIFN5c3RlbSBUYWJsZVxuIik7CgkJcmV0dXJuIC1FTk9NRU07Cgl9CgltZW1zZXQoc3lzdGFiLCAwLCBpMm9fc3lzdGFiLmxlbik7CgoJc3lzdGFiLT52ZXJzaW9uID0gSTJPVkVSU0lPTjsKCXN5c3RhYi0+Y2hhbmdlX2luZCA9IGNoYW5nZV9pbmQgKyAxOwoKCWxpc3RfZm9yX2VhY2hfZW50cnlfc2FmZShjLCB0bXAsICZpMm9fY29udHJvbGxlcnMsIGxpc3QpIHsKCQlpMm9fc3RhdHVzX2Jsb2NrICpzYjsKCgkJaWYgKGNvdW50ID49IG51bV9jb250cm9sbGVycykgewoJCQlvc21fZXJyKCJjb250cm9sbGVyIGFkZGVkIHdoaWxlIGJ1aWxkaW5nIHN5c3RlbSB0YWJsZSIKCQkJCSJcbiIpOwoJCQlicmVhazsKCQl9CgoJCXNiID0gYy0+c3RhdHVzX2Jsb2NrLnZpcnQ7CgoJCS8qCgkJICogR2V0IHVwZGF0ZWQgSU9QIHN0YXRlIHNvIHdlIGhhdmUgdGhlIGxhdGVzdCBpbmZvcm1hdGlvbgoJCSAqCgkJICogV2Ugc2hvdWxkIGRlbGV0ZSB0aGUgY29udHJvbGxlciBhdCB0aGlzIHBvaW50IGlmIGl0CgkJICogZG9lc24ndCByZXNwb25kIHNpbmNlIGlmIGl0J3Mgbm90IG9uIHRoZSBzeXN0ZW0gdGFibGUKCQkgKiBpdCBpcyB0ZWNobmluaWNhbGx5IG5vdCBwYXJ0IG9mIHRoZSBJMk8gc3Vic3lzdGVtLi4uCgkJICovCgkJaWYgKHVubGlrZWx5KGkyb19zdGF0dXNfZ2V0KGMpKSkgewoJCQlvc21fZXJyKCIlczogRGVsZXRpbmcgYi9jIGNvdWxkIG5vdCBnZXQgc3RhdHVzIHdoaWxlICIKCQkJCSJhdHRlbXB0aW5nIHRvIGJ1aWxkIHN5c3RlbSB0YWJsZVxuIiwgYy0+bmFtZSk7CgkJCWkyb19pb3BfcmVtb3ZlKGMpOwoJCQljb250aW51ZTsJLy8gdHJ5IHRoZSBuZXh0IG9uZQoJCX0KCgkJc3lzdGFiLT5pb3BzW2NvdW50XS5vcmdfaWQgPSBzYi0+b3JnX2lkOwoJCXN5c3RhYi0+aW9wc1tjb3VudF0uaW9wX2lkID0gYy0+dW5pdCArIDI7CgkJc3lzdGFiLT5pb3BzW2NvdW50XS5zZWdfbnVtID0gMDsKCQlzeXN0YWItPmlvcHNbY291bnRdLmkyb192ZXJzaW9uID0gc2ItPmkyb192ZXJzaW9uOwoJCXN5c3RhYi0+aW9wc1tjb3VudF0uaW9wX3N0YXRlID0gc2ItPmlvcF9zdGF0ZTsKCQlzeXN0YWItPmlvcHNbY291bnRdLm1zZ190eXBlID0gc2ItPm1zZ190eXBlOwoJCXN5c3RhYi0+aW9wc1tjb3VudF0uZnJhbWVfc2l6ZSA9IHNiLT5pbmJvdW5kX2ZyYW1lX3NpemU7CgkJc3lzdGFiLT5pb3BzW2NvdW50XS5sYXN0X2NoYW5nZWQgPSBjaGFuZ2VfaW5kOwoJCXN5c3RhYi0+aW9wc1tjb3VudF0uaW9wX2NhcGFiaWxpdGllcyA9IHNiLT5pb3BfY2FwYWJpbGl0aWVzOwoJCXN5c3RhYi0+aW9wc1tjb3VudF0uaW5ib3VuZF9sb3cgPQoJCSAgICBpMm9fZG1hX2xvdyhjLT5iYXNlLnBoeXMgKyBJMk9fSU5fUE9SVCk7CgkJc3lzdGFiLT5pb3BzW2NvdW50XS5pbmJvdW5kX2hpZ2ggPQoJCSAgICBpMm9fZG1hX2hpZ2goYy0+YmFzZS5waHlzICsgSTJPX0lOX1BPUlQpOwoKCQljb3VudCsrOwoJfQoKCXN5c3RhYi0+bnVtX2VudHJpZXMgPSBjb3VudDsKCglyZXR1cm4gMDsKfTsKCi8qKgogKglpMm9fcGFyc2VfaHJ0IC0gUGFyc2UgdGhlIGhhcmR3YXJlIHJlc291cmNlIHRhYmxlLgogKglAYzogSTJPIGNvbnRyb2xsZXIKICoKICoJV2UgZG9uJ3QgZG8gYW55dGhpbmcgd2l0aCBpdCBleGNlcHQgZHVtcGluZyBpdCAoaW4gZGVidWcgbW9kZSkuCiAqCiAqCVJldHVybnMgMC4KICovCnN0YXRpYyBpbnQgaTJvX3BhcnNlX2hydChzdHJ1Y3QgaTJvX2NvbnRyb2xsZXIgKmMpCnsKCWkyb19kdW1wX2hydChjKTsKCXJldHVybiAwOwp9OwoKLyoqCiAqCWkyb19zdGF0dXNfZ2V0IC0gR2V0IHRoZSBzdGF0dXMgYmxvY2sgZnJvbSB0aGUgSTJPIGNvbnRyb2xsZXIKICoJQGM6IEkyTyBjb250cm9sbGVyCiAqCiAqCUlzc3VlIGEgc3RhdHVzIHF1ZXJ5IG9uIHRoZSBjb250cm9sbGVyLiBUaGlzIHVwZGF0ZXMgdGhlIGF0dGFjaGVkCiAqCXN0YXR1cyBibG9jay4gVGhlIHN0YXR1cyBibG9jayBjb3VsZCB0aGVuIGJlIGFjY2Vzc2VkIHRocm91Z2gKICoJYy0+c3RhdHVzX2Jsb2NrLgogKgogKglSZXR1cm5zIDAgb24gc3VjZXNzIG9yIG5lZ2F0aXZlIGVycm9yIGNvZGUgb24gZmFpbHVyZS4KICovCmludCBpMm9fc3RhdHVzX2dldChzdHJ1Y3QgaTJvX2NvbnRyb2xsZXIgKmMpCnsKCXN0cnVjdCBpMm9fbWVzc2FnZSBfX2lvbWVtICptc2c7Cgl1MzIgbTsKCXZvbGF0aWxlIHU4ICpzdGF0dXNfYmxvY2s7Cgl1bnNpZ25lZCBsb25nIHRpbWVvdXQ7CgoJc3RhdHVzX2Jsb2NrID0gKHU4ICopIGMtPnN0YXR1c19ibG9jay52aXJ0OwoJbWVtc2V0KGMtPnN0YXR1c19ibG9jay52aXJ0LCAwLCBzaXplb2YoaTJvX3N0YXR1c19ibG9jaykpOwoKCW0gPSBpMm9fbXNnX2dldF93YWl0KGMsICZtc2csIEkyT19USU1FT1VUX01FU1NBR0VfR0VUKTsKCWlmIChtID09IEkyT19RVUVVRV9FTVBUWSkKCQlyZXR1cm4gLUVUSU1FRE9VVDsKCgl3cml0ZWwoTklORV9XT1JEX01TR19TSVpFIHwgU0dMX09GRlNFVF8wLCAmbXNnLT51LmhlYWRbMF0pOwoJd3JpdGVsKEkyT19DTURfU1RBVFVTX0dFVCA8PCAyNCB8IEhPU1RfVElEIDw8IDEyIHwgQURBUFRFUl9USUQsCgkgICAgICAgJm1zZy0+dS5oZWFkWzFdKTsKCXdyaXRlbChpMm9fZXhlY19kcml2ZXIuY29udGV4dCwgJm1zZy0+dS5zLmljbnR4dCk7Cgl3cml0ZWwoMCwgJm1zZy0+dS5zLnRjbnR4dCk7CS8vIEZJWE1FOiB1c2UgcmVzb25hYmxlIHRyYW5zYWN0aW9uIGNvbnRleHQKCXdyaXRlbCgwLCAmbXNnLT5ib2R5WzBdKTsKCXdyaXRlbCgwLCAmbXNnLT5ib2R5WzFdKTsKCXdyaXRlbChpMm9fZG1hX2xvdyhjLT5zdGF0dXNfYmxvY2sucGh5cyksICZtc2ctPmJvZHlbMl0pOwoJd3JpdGVsKGkyb19kbWFfaGlnaChjLT5zdGF0dXNfYmxvY2sucGh5cyksICZtc2ctPmJvZHlbM10pOwoJd3JpdGVsKHNpemVvZihpMm9fc3RhdHVzX2Jsb2NrKSwgJm1zZy0+Ym9keVs0XSk7CS8qIGFsd2F5cyA4OCBieXRlcyAqLwoKCWkyb19tc2dfcG9zdChjLCBtKTsKCgkvKiBXYWl0IGZvciBhIHJlcGx5ICovCgl0aW1lb3V0ID0gamlmZmllcyArIEkyT19USU1FT1VUX1NUQVRVU19HRVQgKiBIWjsKCXdoaWxlIChzdGF0dXNfYmxvY2tbODddICE9IDB4RkYpIHsKCQlpZiAodGltZV9hZnRlcihqaWZmaWVzLCB0aW1lb3V0KSkgewoJCQlvc21fZXJyKCIlczogR2V0IHN0YXR1cyB0aW1lb3V0LlxuIiwgYy0+bmFtZSk7CgkJCXJldHVybiAtRVRJTUVET1VUOwoJCX0KCgkJc2V0X2N1cnJlbnRfc3RhdGUoVEFTS19VTklOVEVSUlVQVElCTEUpOwoJCXNjaGVkdWxlX3RpbWVvdXQoMSk7Cgl9CgojaWZkZWYgREVCVUcKCWkyb19kZWJ1Z19zdGF0ZShjKTsKI2VuZGlmCgoJcmV0dXJuIDA7Cn0KCi8qCiAqCWkyb19ocnRfZ2V0IC0gR2V0IHRoZSBIYXJkd2FyZSBSZXNvdXJjZSBUYWJsZSBmcm9tIHRoZSBJMk8gY29udHJvbGxlcgogKglAYzogSTJPIGNvbnRyb2xsZXIgZnJvbSB3aGljaCB0aGUgSFJUIHNob3VsZCBiZSBmZXRjaGVkCiAqCiAqCVRoZSBIUlQgY29udGFpbnMgaW5mb3JtYXRpb24gYWJvdXQgcG9zc2libGUgaGlkZGVuIGRldmljZXMgYnV0IGlzCiAqCW1vc3RseSB1c2VsZXNzIHRvIHVzLgogKgogKglSZXR1cm5zIDAgb24gc3VjY2VzcyBvciBuZWdhdGl2ZXIgZXJyb3IgY29kZSBvbiBmYWlsdXJlLgogKi8Kc3RhdGljIGludCBpMm9faHJ0X2dldChzdHJ1Y3QgaTJvX2NvbnRyb2xsZXIgKmMpCnsKCWludCByYzsKCWludCBpOwoJaTJvX2hydCAqaHJ0ID0gYy0+aHJ0LnZpcnQ7Cgl1MzIgc2l6ZSA9IHNpemVvZihpMm9faHJ0KTsKCXN0cnVjdCBkZXZpY2UgKmRldiA9ICZjLT5wZGV2LT5kZXY7CgoJZm9yIChpID0gMDsgaSA8IEkyT19IUlRfR0VUX1RSSUVTOyBpKyspIHsKCQlzdHJ1Y3QgaTJvX21lc3NhZ2UgX19pb21lbSAqbXNnOwoJCXUzMiBtOwoKCQltID0gaTJvX21zZ19nZXRfd2FpdChjLCAmbXNnLCBJMk9fVElNRU9VVF9NRVNTQUdFX0dFVCk7CgkJaWYgKG0gPT0gSTJPX1FVRVVFX0VNUFRZKQoJCQlyZXR1cm4gLUVUSU1FRE9VVDsKCgkJd3JpdGVsKFNJWF9XT1JEX01TR19TSVpFIHwgU0dMX09GRlNFVF80LCAmbXNnLT51LmhlYWRbMF0pOwoJCXdyaXRlbChJMk9fQ01EX0hSVF9HRVQgPDwgMjQgfCBIT1NUX1RJRCA8PCAxMiB8IEFEQVBURVJfVElELAoJCSAgICAgICAmbXNnLT51LmhlYWRbMV0pOwoJCXdyaXRlbCgweGQwMDAwMDAwIHwgYy0+aHJ0LmxlbiwgJm1zZy0+Ym9keVswXSk7CgkJd3JpdGVsKGMtPmhydC5waHlzLCAmbXNnLT5ib2R5WzFdKTsKCgkJcmMgPSBpMm9fbXNnX3Bvc3Rfd2FpdF9tZW0oYywgbSwgMjAsICZjLT5ocnQpOwoKCQlpZiAocmMgPCAwKSB7CgkJCW9zbV9lcnIoIiVzOiBVbmFibGUgdG8gZ2V0IEhSVCAoc3RhdHVzPSUjeClcbiIsIGMtPm5hbWUsCgkJCQktcmMpOwoJCQlyZXR1cm4gcmM7CgkJfQoKCQlzaXplID0gaHJ0LT5udW1fZW50cmllcyAqIGhydC0+ZW50cnlfbGVuIDw8IDI7CgkJaWYgKHNpemUgPiBjLT5ocnQubGVuKSB7CgkJCWlmIChpMm9fZG1hX3JlYWxsb2MoZGV2LCAmYy0+aHJ0LCBzaXplLCBHRlBfS0VSTkVMKSkKCQkJCXJldHVybiAtRU5PTUVNOwoJCQllbHNlCgkJCQlocnQgPSBjLT5ocnQudmlydDsKCQl9IGVsc2UKCQkJcmV0dXJuIGkyb19wYXJzZV9ocnQoYyk7Cgl9CgoJb3NtX2VycigiJXM6IFVuYWJsZSB0byBnZXQgSFJUIGFmdGVyICVkIHRyaWVzLCBnaXZpbmcgdXBcbiIsIGMtPm5hbWUsCgkJSTJPX0hSVF9HRVRfVFJJRVMpOwoKCXJldHVybiAtRUJVU1k7Cn0KCi8qKgogKglpMm9faW9wX2ZyZWUgLSBGcmVlIHRoZSBpMm9fY29udHJvbGxlciBzdHJ1Y3QKICoJQGM6IEkyTyBjb250cm9sbGVyIHRvIGZyZWUKICovCnZvaWQgaTJvX2lvcF9mcmVlKHN0cnVjdCBpMm9fY29udHJvbGxlciAqYykKewoJa2ZyZWUoYyk7Cn07CgovKioKICoJaTJvX2lvcF9yZWxlYXNlIC0gcmVsZWFzZSB0aGUgbWVtb3J5IGZvciBhIEkyTyBjb250cm9sbGVyCiAqCUBkZXY6IEkyTyBjb250cm9sbGVyIHdoaWNoIHNob3VsZCBiZSByZWxlYXNlZAogKgogKglSZWxlYXNlIHRoZSBhbGxvY2F0ZWQgbWVtb3J5LiBUaGlzIGZ1bmN0aW9uIGlzIGNhbGxlZCBpZiByZWZjb3VudCBvZgogKglkZXZpY2UgcmVhY2hlcyAwIGF1dG9tYXRpY2FsbHkuCiAqLwpzdGF0aWMgdm9pZCBpMm9faW9wX3JlbGVhc2Uoc3RydWN0IGRldmljZSAqZGV2KQp7CglzdHJ1Y3QgaTJvX2NvbnRyb2xsZXIgKmMgPSB0b19pMm9fY29udHJvbGxlcihkZXYpOwoKCWkyb19pb3BfZnJlZShjKTsKfTsKCi8qIEkyTyBjb250cm9sbGVyIGNsYXNzICovCnN0YXRpYyBzdHJ1Y3QgY2xhc3MgKmkyb19jb250cm9sbGVyX2NsYXNzOwoKLyoqCiAqCWkyb19pb3BfYWxsb2MgLSBBbGxvY2F0ZSBhbmQgaW5pdGlhbGl6ZSBhIGkyb19jb250cm9sbGVyIHN0cnVjdAogKgogKglBbGxvY2F0ZSB0aGUgbmVjZXNzYXJ5IG1lbW9yeSBmb3IgYSBpMm9fY29udHJvbGxlciBzdHJ1Y3QgYW5kCiAqCWluaXRpYWxpemUgdGhlIGxpc3RzLgogKgogKglSZXR1cm5zIGEgcG9pbnRlciB0byB0aGUgSTJPIGNvbnRyb2xsZXIgb3IgYSBuZWdhdGl2ZSBlcnJvciBjb2RlIG9uCiAqCWZhaWx1cmUuCiAqLwpzdHJ1Y3QgaTJvX2NvbnRyb2xsZXIgKmkyb19pb3BfYWxsb2Modm9pZCkKewoJc3RhdGljIGludCB1bml0ID0gMDsJLyogMCBhbmQgMSBhcmUgTlVMTCBJT1AgYW5kIExvY2FsIEhvc3QgKi8KCXN0cnVjdCBpMm9fY29udHJvbGxlciAqYzsKCgljID0ga21hbGxvYyhzaXplb2YoKmMpLCBHRlBfS0VSTkVMKTsKCWlmICghYykgewoJCW9zbV9lcnIoImkybzogSW5zdWZmaWNpZW50IG1lbW9yeSB0byBhbGxvY2F0ZSBhIEkyTyBjb250cm9sbGVyLiIKCQkJIlxuIik7CgkJcmV0dXJuIEVSUl9QVFIoLUVOT01FTSk7Cgl9CgltZW1zZXQoYywgMCwgc2l6ZW9mKCpjKSk7CgoJSU5JVF9MSVNUX0hFQUQoJmMtPmRldmljZXMpOwoJc3Bpbl9sb2NrX2luaXQoJmMtPmxvY2spOwoJaW5pdF9NVVRFWCgmYy0+bGN0X2xvY2spOwoJYy0+dW5pdCA9IHVuaXQrKzsKCXNwcmludGYoYy0+bmFtZSwgImlvcCVkIiwgYy0+dW5pdCk7CgoJZGV2aWNlX2luaXRpYWxpemUoJmMtPmRldmljZSk7CgoJYy0+ZGV2aWNlLnJlbGVhc2UgPSAmaTJvX2lvcF9yZWxlYXNlOwoKCXNucHJpbnRmKGMtPmRldmljZS5idXNfaWQsIEJVU19JRF9TSVpFLCAiaW9wJWQiLCBjLT51bml0KTsKCiNpZiBCSVRTX1BFUl9MT05HID09IDY0CglzcGluX2xvY2tfaW5pdCgmYy0+Y29udGV4dF9saXN0X2xvY2spOwoJYXRvbWljX3NldCgmYy0+Y29udGV4dF9saXN0X2NvdW50ZXIsIDApOwoJSU5JVF9MSVNUX0hFQUQoJmMtPmNvbnRleHRfbGlzdCk7CiNlbmRpZgoKCXJldHVybiBjOwp9OwoKLyoqCiAqCWkyb19pb3BfYWRkIC0gSW5pdGlhbGl6ZSB0aGUgSTJPIGNvbnRyb2xsZXIgYW5kIGFkZCBoaW0gdG8gdGhlIEkyTyBjb3JlCiAqCUBjOiBjb250cm9sbGVyCiAqCiAqCUluaXRpYWxpemUgdGhlIEkyTyBjb250cm9sbGVyIGFuZCBpZiBubyBlcnJvciBvY2N1cnMgYWRkIGhpbSB0byB0aGUgSTJPCiAqCWNvcmUuCiAqCiAqCVJldHVybnMgMCBvbiBzdWNjZXNzIG9yIG5lZ2F0aXZlIGVycm9yIGNvZGUgb24gZmFpbHVyZS4KICovCmludCBpMm9faW9wX2FkZChzdHJ1Y3QgaTJvX2NvbnRyb2xsZXIgKmMpCnsKCWludCByYzsKCglpZiAoKHJjID0gZGV2aWNlX2FkZCgmYy0+ZGV2aWNlKSkpIHsKCQlvc21fZXJyKCIlczogY291bGQgbm90IGFkZCBjb250cm9sbGVyXG4iLCBjLT5uYW1lKTsKCQlnb3RvIGlvcF9yZXNldDsKCX0KCgljLT5jbGFzc2RldiA9IGNsYXNzX2RldmljZV9jcmVhdGUoaTJvX2NvbnRyb2xsZXJfY2xhc3MsIE5VTEwsIE1LREVWKDAsMCksCgkJCSZjLT5kZXZpY2UsICJpb3AlZCIsIGMtPnVuaXQpOwoJaWYgKElTX0VSUihjLT5jbGFzc2RldikpIHsKCQlvc21fZXJyKCIlczogY291bGQgbm90IGFkZCBjb250cm9sbGVyIGNsYXNzXG4iLCBjLT5uYW1lKTsKCQlnb3RvIGRldmljZV9kZWw7Cgl9CgoJb3NtX2luZm8oIiVzOiBBY3RpdmF0aW5nIEkyTyBjb250cm9sbGVyLi4uXG4iLCBjLT5uYW1lKTsKCW9zbV9pbmZvKCIlczogVGhpcyBtYXkgdGFrZSBhIGZldyBtaW51dGVzIGlmIHRoZXJlIGFyZSBtYW55IGRldmljZXNcbiIsCgkJIGMtPm5hbWUpOwoKCWlmICgocmMgPSBpMm9faW9wX2FjdGl2YXRlKGMpKSkgewoJCW9zbV9lcnIoIiVzOiBjb3VsZCBub3QgYWN0aXZhdGUgY29udHJvbGxlclxuIiwgYy0+bmFtZSk7CgkJZ290byBjbGFzc19kZWw7Cgl9CgoJb3NtX2RlYnVnKCIlczogYnVpbGRpbmcgc3lzIHRhYmxlLi4uXG4iLCBjLT5uYW1lKTsKCglpZiAoKHJjID0gaTJvX3N5c3RhYl9idWlsZCgpKSkKCQlnb3RvIGNsYXNzX2RlbDsKCglvc21fZGVidWcoIiVzOiBvbmxpbmUgY29udHJvbGxlci4uLlxuIiwgYy0+bmFtZSk7CgoJaWYgKChyYyA9IGkyb19pb3Bfb25saW5lKGMpKSkKCQlnb3RvIGNsYXNzX2RlbDsKCglvc21fZGVidWcoIiVzOiBnZXR0aW5nIExDVC4uLlxuIiwgYy0+bmFtZSk7CgoJaWYgKChyYyA9IGkyb19leGVjX2xjdF9nZXQoYykpKQoJCWdvdG8gY2xhc3NfZGVsOwoKCWxpc3RfYWRkKCZjLT5saXN0LCAmaTJvX2NvbnRyb2xsZXJzKTsKCglpMm9fZHJpdmVyX25vdGlmeV9jb250cm9sbGVyX2FkZF9hbGwoYyk7CgoJb3NtX2luZm8oIiVzOiBDb250cm9sbGVyIGFkZGVkXG4iLCBjLT5uYW1lKTsKCglyZXR1cm4gMDsKCiAgICAgIGNsYXNzX2RlbDoKCWNsYXNzX2RldmljZV91bnJlZ2lzdGVyKGMtPmNsYXNzZGV2KTsKCiAgICAgIGRldmljZV9kZWw6CglkZXZpY2VfZGVsKCZjLT5kZXZpY2UpOwoKICAgICAgaW9wX3Jlc2V0OgoJaTJvX2lvcF9yZXNldChjKTsKCglyZXR1cm4gcmM7Cn07CgovKioKICoJaTJvX2V2ZW50X3JlZ2lzdGVyIC0gVHVybiBvbi9vZmYgZXZlbnQgbm90aWZpY2F0aW9uIGZvciBhIEkyTyBkZXZpY2UKICoJQGRldjogSTJPIGRldmljZSB3aGljaCBzaG91bGQgcmVjZWl2ZSB0aGUgZXZlbnQgcmVnaXN0cmF0aW9uIHJlcXVlc3QKICoJQGRydjogZHJpdmVyIHdoaWNoIHdhbnQgdG8gZ2V0IG5vdGlmaWVkCiAqCUB0Y250eHQ6IHRyYW5zYWN0aW9uIGNvbnRleHQgdG8gdXNlIHdpdGggdGhpcyBub3RpZmllcgogKglAZXZ0X21hc2s6IG1hc2sgb2YgZXZlbnRzCiAqCiAqCUNyZWF0ZSBhbmQgcG9zdHMgYW4gZXZlbnQgcmVnaXN0cmF0aW9uIG1lc3NhZ2UgdG8gdGhlIHRhc2suIE5vIHJlcGx5CiAqCWlzIHdhaXRlZCBmb3IsIG9yIGV4cGVjdGVkLiBJZiB5b3UgZG8gbm90IHdhbnQgZnVydGhlciBub3RpZmljYXRpb25zLAogKgljYWxsIHRoZSBpMm9fZXZlbnRfcmVnaXN0ZXIgYWdhaW4gd2l0aCBhIGV2dF9tYXNrIG9mIDAuCiAqCiAqCVJldHVybnMgMCBvbiBzdWNjZXNzIG9yIC1FVElNRURPVVQgaWYgbm8gbWVzc2FnZSBjb3VsZCBiZSBmZXRjaGVkIGZvcgogKglzZW5kaW5nIHRoZSByZXF1ZXN0LgogKi8KaW50IGkyb19ldmVudF9yZWdpc3RlcihzdHJ1Y3QgaTJvX2RldmljZSAqZGV2LCBzdHJ1Y3QgaTJvX2RyaXZlciAqZHJ2LAoJCSAgICAgICBpbnQgdGNudHh0LCB1MzIgZXZ0X21hc2spCnsKCXN0cnVjdCBpMm9fY29udHJvbGxlciAqYyA9IGRldi0+aW9wOwoJc3RydWN0IGkyb19tZXNzYWdlIF9faW9tZW0gKm1zZzsKCXUzMiBtOwoKCW0gPSBpMm9fbXNnX2dldF93YWl0KGMsICZtc2csIEkyT19USU1FT1VUX01FU1NBR0VfR0VUKTsKCWlmIChtID09IEkyT19RVUVVRV9FTVBUWSkKCQlyZXR1cm4gLUVUSU1FRE9VVDsKCgl3cml0ZWwoRklWRV9XT1JEX01TR19TSVpFIHwgU0dMX09GRlNFVF8wLCAmbXNnLT51LmhlYWRbMF0pOwoJd3JpdGVsKEkyT19DTURfVVRJTF9FVlRfUkVHSVNURVIgPDwgMjQgfCBIT1NUX1RJRCA8PCAxMiB8IGRldi0+bGN0X2RhdGEuCgkgICAgICAgdGlkLCAmbXNnLT51LmhlYWRbMV0pOwoJd3JpdGVsKGRydi0+Y29udGV4dCwgJm1zZy0+dS5zLmljbnR4dCk7Cgl3cml0ZWwodGNudHh0LCAmbXNnLT51LnMudGNudHh0KTsKCXdyaXRlbChldnRfbWFzaywgJm1zZy0+Ym9keVswXSk7CgoJaTJvX21zZ19wb3N0KGMsIG0pOwoKCXJldHVybiAwOwp9OwoKLyoqCiAqCWkyb19pb3BfaW5pdCAtIEkyTyBtYWluIGluaXRpYWxpemF0aW9uIGZ1bmN0aW9uCiAqCiAqCUluaXRpYWxpemUgdGhlIEkyTyBkcml2ZXJzIChPU00pIGZ1bmN0aW9ucywgcmVnaXN0ZXIgdGhlIEV4ZWN1dGl2ZSBPU00sCiAqCWluaXRpYWxpemUgdGhlIEkyTyBQQ0kgcGFydCBhbmQgZmluYWxseSBpbml0aWFsaXplIEkyTyBkZXZpY2Ugc3R1ZmYuCiAqCiAqCVJldHVybnMgMCBvbiBzdWNjZXNzIG9yIG5lZ2F0aXZlIGVycm9yIGNvZGUgb24gZmFpbHVyZS4KICovCnN0YXRpYyBpbnQgX19pbml0IGkyb19pb3BfaW5pdCh2b2lkKQp7CglpbnQgcmMgPSAwOwoKCXByaW50ayhLRVJOX0lORk8gT1NNX0RFU0NSSVBUSU9OICIgdiIgT1NNX1ZFUlNJT04gIlxuIik7CgoJaTJvX2NvbnRyb2xsZXJfY2xhc3MgPSBjbGFzc19jcmVhdGUoVEhJU19NT0RVTEUsICJpMm9fY29udHJvbGxlciIpOwoJaWYgKElTX0VSUihpMm9fY29udHJvbGxlcl9jbGFzcykpIHsKCQlvc21fZXJyKCJjYW4ndCByZWdpc3RlciBjbGFzcyBpMm9fY29udHJvbGxlclxuIik7CgkJZ290byBleGl0OwoJfQoKCWlmICgocmMgPSBpMm9fZHJpdmVyX2luaXQoKSkpCgkJZ290byBjbGFzc19leGl0OwoKCWlmICgocmMgPSBpMm9fZXhlY19pbml0KCkpKQoJCWdvdG8gZHJpdmVyX2V4aXQ7CgoJaWYgKChyYyA9IGkyb19wY2lfaW5pdCgpKSkKCQlnb3RvIGV4ZWNfZXhpdDsKCglyZXR1cm4gMDsKCiAgICAgIGV4ZWNfZXhpdDoKCWkyb19leGVjX2V4aXQoKTsKCiAgICAgIGRyaXZlcl9leGl0OgoJaTJvX2RyaXZlcl9leGl0KCk7CgogICAgICBjbGFzc19leGl0OgoJY2xhc3NfZGVzdHJveShpMm9fY29udHJvbGxlcl9jbGFzcyk7CgogICAgICBleGl0OgoJcmV0dXJuIHJjOwp9CgovKioKICoJaTJvX2lvcF9leGl0IC0gSTJPIG1haW4gZXhpdCBmdW5jdGlvbgogKgogKglSZW1vdmVzIEkyTyBjb250cm9sbGVycyBmcm9tIFBDSSBzdWJzeXN0ZW0gYW5kIHNodXQgZG93biBPU01zLgogKi8Kc3RhdGljIHZvaWQgX19leGl0IGkyb19pb3BfZXhpdCh2b2lkKQp7CglpMm9fcGNpX2V4aXQoKTsKCWkyb19leGVjX2V4aXQoKTsKCWkyb19kcml2ZXJfZXhpdCgpOwoJY2xhc3NfZGVzdHJveShpMm9fY29udHJvbGxlcl9jbGFzcyk7Cn07Cgptb2R1bGVfaW5pdChpMm9faW9wX2luaXQpOwptb2R1bGVfZXhpdChpMm9faW9wX2V4aXQpOwoKTU9EVUxFX0FVVEhPUigiUmVkIEhhdCBTb2Z0d2FyZSIpOwpNT0RVTEVfTElDRU5TRSgiR1BMIik7Ck1PRFVMRV9ERVNDUklQVElPTihPU01fREVTQ1JJUFRJT04pOwpNT0RVTEVfVkVSU0lPTihPU01fVkVSU0lPTik7CgojaWYgQklUU19QRVJfTE9ORyA9PSA2NApFWFBPUlRfU1lNQk9MKGkyb19jbnR4dF9saXN0X2FkZCk7CkVYUE9SVF9TWU1CT0woaTJvX2NudHh0X2xpc3RfZ2V0KTsKRVhQT1JUX1NZTUJPTChpMm9fY250eHRfbGlzdF9yZW1vdmUpOwpFWFBPUlRfU1lNQk9MKGkyb19jbnR4dF9saXN0X2dldF9wdHIpOwojZW5kaWYKRVhQT1JUX1NZTUJPTChpMm9fbXNnX2dldF93YWl0KTsKRVhQT1JUX1NZTUJPTChpMm9fbXNnX25vcCk7CkVYUE9SVF9TWU1CT0woaTJvX2ZpbmRfaW9wKTsKRVhQT1JUX1NZTUJPTChpMm9faW9wX2ZpbmRfZGV2aWNlKTsKRVhQT1JUX1NZTUJPTChpMm9fZXZlbnRfcmVnaXN0ZXIpOwpFWFBPUlRfU1lNQk9MKGkyb19zdGF0dXNfZ2V0KTsKRVhQT1JUX1NZTUJPTChpMm9fY29udHJvbGxlcnMpOwo=