LyoKICoJRnVuY3Rpb25zIHRvIGhhbmRsZSBJMk8gY29udHJvbGxlcnMgYW5kIEkyTyBtZXNzYWdlIGhhbmRsaW5nCiAqCiAqCUNvcHlyaWdodCAoQykgMTk5OS0yMDAyCVJlZCBIYXQgU29mdHdhcmUKICoKICoJV3JpdHRlbiBieSBBbGFuIENveCwgQnVpbGRpbmcgTnVtYmVyIFRocmVlIEx0ZAogKgogKglUaGlzIHByb2dyYW0gaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKgl1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUKICoJRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIgdmVyc2lvbiAyIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91cgogKglvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKglBIGxvdCBvZiB0aGUgSTJPIG1lc3NhZ2Ugc2lkZSBjb2RlIGZyb20gdGhpcyBpcyB0YWtlbiBmcm9tIHRoZQogKglSZWQgQ3JlZWsgUkNQQ0k0NSBhZGFwdGVyIGRyaXZlciBieSBSZWQgQ3JlZWsgQ29tbXVuaWNhdGlvbnMKICoKICoJRml4ZXMvYWRkaXRpb25zOgogKgkJUGhpbGlwcCBSdW1wZgogKgkJSnVoYSBTaWV25G5lbiA8SnVoYS5TaWV2YW5lbkBjcy5IZWxzaW5raS5GST4KICoJCUF1dm8gSORra2luZW4gPEF1dm8uSGFra2luZW5AY3MuSGVsc2lua2kuRkk+CiAqCQlEZWVwYWsgU2F4ZW5hIDxkZWVwYWtAcGxleGl0eS5uZXQ+CiAqCQlCb2ppIFQgS2FubmFudGhhbmFtIDxib2ppLnQua2FubmFudGhhbmFtQGludGVsLmNvbT4KICoJCUFsYW4gQ294IDxhbGFuQHJlZGhhdC5jb20+OgogKgkJCVBvcnRlZCB0byBMaW51eCAyLjUuCiAqCQlNYXJrdXMgTGlkZWwgPE1hcmt1cy5MaWRlbEBzaGFkb3djb25uZWN0LmNvbT46CiAqCQkJTWlub3IgZml4ZXMgZm9yIDIuNi4KICovCgojaW5jbHVkZSA8bGludXgvbW9kdWxlLmg+CiNpbmNsdWRlIDxsaW51eC9pMm8uaD4KI2luY2x1ZGUgPGxpbnV4L2RlbGF5Lmg+CiNpbmNsdWRlIDxsaW51eC9zY2hlZC5oPgojaW5jbHVkZSAiY29yZS5oIgoKI2RlZmluZSBPU01fTkFNRQkiaTJvIgojZGVmaW5lIE9TTV9WRVJTSU9OCSIxLjI4OCIKI2RlZmluZSBPU01fREVTQ1JJUFRJT04JIkkyTyBzdWJzeXN0ZW0iCgovKiBnbG9iYWwgSTJPIGNvbnRyb2xsZXIgbGlzdCAqLwpMSVNUX0hFQUQoaTJvX2NvbnRyb2xsZXJzKTsKCi8qCiAqIGdsb2JhbCBJMk8gU3lzdGVtIFRhYmxlLiBDb250YWlucyBpbmZvcm1hdGlvbiBhYm91dCBhbGwgdGhlIElPUHMgaW4gdGhlCiAqIHN5c3RlbS4gVXNlZCB0byBpbmZvcm0gSU9QcyBhYm91dCBlYWNoIG90aGVycyBleGlzdGVuY2UuCiAqLwpzdGF0aWMgc3RydWN0IGkyb19kbWEgaTJvX3N5c3RhYjsKCnN0YXRpYyBpbnQgaTJvX2hydF9nZXQoc3RydWN0IGkyb19jb250cm9sbGVyICpjKTsKCi8qKgogKglpMm9fbXNnX25vcCAtIFJldHVybnMgYSBtZXNzYWdlIHdoaWNoIGlzIG5vdCB1c2VkCiAqCUBjOiBJMk8gY29udHJvbGxlciBmcm9tIHdoaWNoIHRoZSBtZXNzYWdlIHdhcyBjcmVhdGVkCiAqCUBtOiBtZXNzYWdlIHdoaWNoIHNob3VsZCBiZSByZXR1cm5lZAogKgogKglJZiB5b3UgZmV0Y2ggYSBtZXNzYWdlIHZpYSBpMm9fbXNnX2dldCwgYW5kIGNhbid0IHVzZSBpdCwgeW91IG11c3QKICoJcmV0dXJuIHRoZSBtZXNzYWdlIHdpdGggdGhpcyBmdW5jdGlvbi4gT3RoZXJ3aXNlIHRoZSBtZXNzYWdlIGZyYW1lCiAqCWlzIGxvc3QuCiAqLwp2b2lkIGkyb19tc2dfbm9wKHN0cnVjdCBpMm9fY29udHJvbGxlciAqYywgdTMyIG0pCnsKCXN0cnVjdCBpMm9fbWVzc2FnZSBfX2lvbWVtICptc2cgPSBpMm9fbXNnX2luX3RvX3ZpcnQoYywgbSk7CgoJd3JpdGVsKFRIUkVFX1dPUkRfTVNHX1NJWkUgfCBTR0xfT0ZGU0VUXzAsICZtc2ctPnUuaGVhZFswXSk7Cgl3cml0ZWwoSTJPX0NNRF9VVElMX05PUCA8PCAyNCB8IEhPU1RfVElEIDw8IDEyIHwgQURBUFRFUl9USUQsCgkgICAgICAgJm1zZy0+dS5oZWFkWzFdKTsKCXdyaXRlbCgwLCAmbXNnLT51LmhlYWRbMl0pOwoJd3JpdGVsKDAsICZtc2ctPnUuaGVhZFszXSk7CglpMm9fbXNnX3Bvc3QoYywgbSk7Cn07CgovKioKICoJaTJvX21zZ19nZXRfd2FpdCAtIG9idGFpbiBhbiBJMk8gbWVzc2FnZSBmcm9tIHRoZSBJT1AKICoJQGM6IEkyTyBjb250cm9sbGVyCiAqCUBtc2c6IHBvaW50ZXIgdG8gYSBJMk8gbWVzc2FnZSBwb2ludGVyCiAqCUB3YWl0OiBob3cgbG9uZyB0byB3YWl0IHVudGlsIHRpbWVvdXQKICoKICoJVGhpcyBmdW5jdGlvbiB3YWl0cyB1cCB0byB3YWl0IHNlY29uZHMgZm9yIGEgbWVzc2FnZSBzbG90IHRvIGJlCiAqCWF2YWlsYWJsZS4KICoKICoJT24gYSBzdWNjZXNzIHRoZSBtZXNzYWdlIGlzIHJldHVybmVkIGFuZCB0aGUgcG9pbnRlciB0byB0aGUgbWVzc2FnZSBpcwogKglzZXQgaW4gbXNnLiBUaGUgcmV0dXJuZWQgbWVzc2FnZSBpcyB0aGUgcGh5c2ljYWwgcGFnZSBmcmFtZSBvZmZzZXQKICoJYWRkcmVzcyBmcm9tIHRoZSByZWFkIHBvcnQgKHNlZSB0aGUgaTJvIHNwZWMpLiBJZiBubyBtZXNzYWdlIGlzCiAqCWF2YWlsYWJsZSByZXR1cm5zIEkyT19RVUVVRV9FTVBUWSBhbmQgbXNnIGlzIGxlYXZlZCB1bnRvdWNoZWQuCiAqLwp1MzIgaTJvX21zZ19nZXRfd2FpdChzdHJ1Y3QgaTJvX2NvbnRyb2xsZXIgKmMsCgkJICAgICBzdHJ1Y3QgaTJvX21lc3NhZ2UgX19pb21lbSAqKiBtc2csIGludCB3YWl0KQp7Cgl1bnNpZ25lZCBsb25nIHRpbWVvdXQgPSBqaWZmaWVzICsgd2FpdCAqIEhaOwoJdTMyIG07CgoJd2hpbGUgKChtID0gaTJvX21zZ19nZXQoYywgbXNnKSkgPT0gSTJPX1FVRVVFX0VNUFRZKSB7CgkJaWYgKHRpbWVfYWZ0ZXIoamlmZmllcywgdGltZW91dCkpIHsKCQkJb3NtX2RlYnVnKCIlczogVGltZW91dCB3YWl0aW5nIGZvciBtZXNzYWdlIGZyYW1lLlxuIiwKCQkJCSAgYy0+bmFtZSk7CgkJCXJldHVybiBJMk9fUVVFVUVfRU1QVFk7CgkJfQoJCXNjaGVkdWxlX3RpbWVvdXRfdW5pbnRlcnJ1cHRpYmxlKDEpOwoJfQoKCXJldHVybiBtOwp9OwoKI2lmIEJJVFNfUEVSX0xPTkcgPT0gNjQKLyoqCiAqICAgICAgaTJvX2NudHh0X2xpc3RfYWRkIC0gQXBwZW5kIGEgcG9pbnRlciB0byBjb250ZXh0IGxpc3QgYW5kIHJldHVybiBhIGlkCiAqCUBjOiBjb250cm9sbGVyIHRvIHdoaWNoIHRoZSBjb250ZXh0IGxpc3QgYmVsb25nCiAqCUBwdHI6IHBvaW50ZXIgdG8gYWRkIHRvIHRoZSBjb250ZXh0IGxpc3QKICoKICoJQmVjYXVzZSB0aGUgY29udGV4dCBmaWVsZCBpbiBJMk8gaXMgb25seSAzMi1iaXQgbGFyZ2UsIG9uIDY0LWJpdCB0aGUKICoJcG9pbnRlciBpcyB0byBsYXJnZSB0byBmaXQgaW4gdGhlIGNvbnRleHQgZmllbGQuIFRoZSBpMm9fY250eHRfbGlzdAogKglmdW5jdGlvbnMgdGhlcmVmb3JlIG1hcCBwb2ludGVycyB0byBjb250ZXh0IGZpZWxkcy4KICoKICoJUmV0dXJucyBjb250ZXh0IGlkID4gMCBvbiBzdWNjZXNzIG9yIDAgb24gZmFpbHVyZS4KICovCnUzMiBpMm9fY250eHRfbGlzdF9hZGQoc3RydWN0IGkyb19jb250cm9sbGVyICogYywgdm9pZCAqcHRyKQp7CglzdHJ1Y3QgaTJvX2NvbnRleHRfbGlzdF9lbGVtZW50ICplbnRyeTsKCXVuc2lnbmVkIGxvbmcgZmxhZ3M7CgoJaWYgKCFwdHIpCgkJb3NtX2VycigiJXM6IGNvdWxkbid0IGFkZCBOVUxMIHBvaW50ZXIgdG8gY29udGV4dCBsaXN0IVxuIiwKCQkJYy0+bmFtZSk7CgoJZW50cnkgPSBrbWFsbG9jKHNpemVvZigqZW50cnkpLCBHRlBfQVRPTUlDKTsKCWlmICghZW50cnkpIHsKCQlvc21fZXJyKCIlczogQ291bGQgbm90IGFsbG9jYXRlIG1lbW9yeSBmb3IgY29udGV4dCBsaXN0IGVsZW1lbnQiCgkJCSJcbiIsIGMtPm5hbWUpOwoJCXJldHVybiAwOwoJfQoKCWVudHJ5LT5wdHIgPSBwdHI7CgllbnRyeS0+dGltZXN0YW1wID0gamlmZmllczsKCUlOSVRfTElTVF9IRUFEKCZlbnRyeS0+bGlzdCk7CgoJc3Bpbl9sb2NrX2lycXNhdmUoJmMtPmNvbnRleHRfbGlzdF9sb2NrLCBmbGFncyk7CgoJaWYgKHVubGlrZWx5KGF0b21pY19pbmNfYW5kX3Rlc3QoJmMtPmNvbnRleHRfbGlzdF9jb3VudGVyKSkpCgkJYXRvbWljX2luYygmYy0+Y29udGV4dF9saXN0X2NvdW50ZXIpOwoKCWVudHJ5LT5jb250ZXh0ID0gYXRvbWljX3JlYWQoJmMtPmNvbnRleHRfbGlzdF9jb3VudGVyKTsKCglsaXN0X2FkZCgmZW50cnktPmxpc3QsICZjLT5jb250ZXh0X2xpc3QpOwoKCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJmMtPmNvbnRleHRfbGlzdF9sb2NrLCBmbGFncyk7CgoJb3NtX2RlYnVnKCIlczogQWRkIGNvbnRleHQgdG8gbGlzdCAlcCAtPiAlZFxuIiwgYy0+bmFtZSwgcHRyLCBjb250ZXh0KTsKCglyZXR1cm4gZW50cnktPmNvbnRleHQ7Cn07CgovKioKICogICAgICBpMm9fY250eHRfbGlzdF9yZW1vdmUgLSBSZW1vdmUgYSBwb2ludGVyIGZyb20gdGhlIGNvbnRleHQgbGlzdAogKglAYzogY29udHJvbGxlciB0byB3aGljaCB0aGUgY29udGV4dCBsaXN0IGJlbG9uZwogKglAcHRyOiBwb2ludGVyIHdoaWNoIHNob3VsZCBiZSByZW1vdmVkIGZyb20gdGhlIGNvbnRleHQgbGlzdAogKgogKglSZW1vdmVzIGEgcHJldmlvdXNseSBhZGRlZCBwb2ludGVyIGZyb20gdGhlIGNvbnRleHQgbGlzdCBhbmQgcmV0dXJucwogKgl0aGUgbWF0Y2hpbmcgY29udGV4dCBpZC4KICoKICoJUmV0dXJucyBjb250ZXh0IGlkIG9uIHN1Y2NlcyBvciAwIG9uIGZhaWx1cmUuCiAqLwp1MzIgaTJvX2NudHh0X2xpc3RfcmVtb3ZlKHN0cnVjdCBpMm9fY29udHJvbGxlciAqIGMsIHZvaWQgKnB0cikKewoJc3RydWN0IGkyb19jb250ZXh0X2xpc3RfZWxlbWVudCAqZW50cnk7Cgl1MzIgY29udGV4dCA9IDA7Cgl1bnNpZ25lZCBsb25nIGZsYWdzOwoKCXNwaW5fbG9ja19pcnFzYXZlKCZjLT5jb250ZXh0X2xpc3RfbG9jaywgZmxhZ3MpOwoJbGlzdF9mb3JfZWFjaF9lbnRyeShlbnRyeSwgJmMtPmNvbnRleHRfbGlzdCwgbGlzdCkKCSAgICBpZiAoZW50cnktPnB0ciA9PSBwdHIpIHsKCQlsaXN0X2RlbCgmZW50cnktPmxpc3QpOwoJCWNvbnRleHQgPSBlbnRyeS0+Y29udGV4dDsKCQlrZnJlZShlbnRyeSk7CgkJYnJlYWs7Cgl9CglzcGluX3VubG9ja19pcnFyZXN0b3JlKCZjLT5jb250ZXh0X2xpc3RfbG9jaywgZmxhZ3MpOwoKCWlmICghY29udGV4dCkKCQlvc21fd2FybigiJXM6IENvdWxkIG5vdCByZW1vdmUgbm9uZXhpc3RlbnQgcHRyICVwXG4iLCBjLT5uYW1lLAoJCQkgcHRyKTsKCglvc21fZGVidWcoIiVzOiByZW1vdmUgcHRyIGZyb20gY29udGV4dCBsaXN0ICVkIC0+ICVwXG4iLCBjLT5uYW1lLAoJCSAgY29udGV4dCwgcHRyKTsKCglyZXR1cm4gY29udGV4dDsKfTsKCi8qKgogKiAgICAgIGkyb19jbnR4dF9saXN0X2dldCAtIEdldCBhIHBvaW50ZXIgZnJvbSB0aGUgY29udGV4dCBsaXN0IGFuZCByZW1vdmUgaXQKICoJQGM6IGNvbnRyb2xsZXIgdG8gd2hpY2ggdGhlIGNvbnRleHQgbGlzdCBiZWxvbmcKICoJQGNvbnRleHQ6IGNvbnRleHQgaWQgdG8gd2hpY2ggdGhlIHBvaW50ZXIgYmVsb25nCiAqCiAqCVJldHVybnMgcG9pbnRlciB0byB0aGUgbWF0Y2hpbmcgY29udGV4dCBpZCBvbiBzdWNjZXNzIG9yIE5VTEwgb24KICoJZmFpbHVyZS4KICovCnZvaWQgKmkyb19jbnR4dF9saXN0X2dldChzdHJ1Y3QgaTJvX2NvbnRyb2xsZXIgKmMsIHUzMiBjb250ZXh0KQp7CglzdHJ1Y3QgaTJvX2NvbnRleHRfbGlzdF9lbGVtZW50ICplbnRyeTsKCXVuc2lnbmVkIGxvbmcgZmxhZ3M7Cgl2b2lkICpwdHIgPSBOVUxMOwoKCXNwaW5fbG9ja19pcnFzYXZlKCZjLT5jb250ZXh0X2xpc3RfbG9jaywgZmxhZ3MpOwoJbGlzdF9mb3JfZWFjaF9lbnRyeShlbnRyeSwgJmMtPmNvbnRleHRfbGlzdCwgbGlzdCkKCSAgICBpZiAoZW50cnktPmNvbnRleHQgPT0gY29udGV4dCkgewoJCWxpc3RfZGVsKCZlbnRyeS0+bGlzdCk7CgkJcHRyID0gZW50cnktPnB0cjsKCQlrZnJlZShlbnRyeSk7CgkJYnJlYWs7Cgl9CglzcGluX3VubG9ja19pcnFyZXN0b3JlKCZjLT5jb250ZXh0X2xpc3RfbG9jaywgZmxhZ3MpOwoKCWlmICghcHRyKQoJCW9zbV93YXJuKCIlczogY29udGV4dCBpZCAlZCBub3QgZm91bmRcbiIsIGMtPm5hbWUsIGNvbnRleHQpOwoKCW9zbV9kZWJ1ZygiJXM6IGdldCBwdHIgZnJvbSBjb250ZXh0IGxpc3QgJWQgLT4gJXBcbiIsIGMtPm5hbWUsIGNvbnRleHQsCgkJICBwdHIpOwoKCXJldHVybiBwdHI7Cn07CgovKioKICogICAgICBpMm9fY250eHRfbGlzdF9nZXRfcHRyIC0gR2V0IGEgY29udGV4dCBpZCBmcm9tIHRoZSBjb250ZXh0IGxpc3QKICoJQGM6IGNvbnRyb2xsZXIgdG8gd2hpY2ggdGhlIGNvbnRleHQgbGlzdCBiZWxvbmcKICoJQHB0cjogcG9pbnRlciB0byB3aGljaCB0aGUgY29udGV4dCBpZCBzaG91bGQgYmUgZmV0Y2hlZAogKgogKglSZXR1cm5zIGNvbnRleHQgaWQgd2hpY2ggbWF0Y2hlcyB0byB0aGUgcG9pbnRlciBvbiBzdWNjZXMgb3IgMCBvbgogKglmYWlsdXJlLgogKi8KdTMyIGkyb19jbnR4dF9saXN0X2dldF9wdHIoc3RydWN0IGkyb19jb250cm9sbGVyICogYywgdm9pZCAqcHRyKQp7CglzdHJ1Y3QgaTJvX2NvbnRleHRfbGlzdF9lbGVtZW50ICplbnRyeTsKCXUzMiBjb250ZXh0ID0gMDsKCXVuc2lnbmVkIGxvbmcgZmxhZ3M7CgoJc3Bpbl9sb2NrX2lycXNhdmUoJmMtPmNvbnRleHRfbGlzdF9sb2NrLCBmbGFncyk7CglsaXN0X2Zvcl9lYWNoX2VudHJ5KGVudHJ5LCAmYy0+Y29udGV4dF9saXN0LCBsaXN0KQoJICAgIGlmIChlbnRyeS0+cHRyID09IHB0cikgewoJCWNvbnRleHQgPSBlbnRyeS0+Y29udGV4dDsKCQlicmVhazsKCX0KCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJmMtPmNvbnRleHRfbGlzdF9sb2NrLCBmbGFncyk7CgoJaWYgKCFjb250ZXh0KQoJCW9zbV93YXJuKCIlczogQ291bGQgbm90IGZpbmQgbm9uZXhpc3RlbnQgcHRyICVwXG4iLCBjLT5uYW1lLAoJCQkgcHRyKTsKCglvc21fZGVidWcoIiVzOiBnZXQgY29udGV4dCBpZCBmcm9tIGNvbnRleHQgbGlzdCAlcCAtPiAlZFxuIiwgYy0+bmFtZSwKCQkgIHB0ciwgY29udGV4dCk7CgoJcmV0dXJuIGNvbnRleHQ7Cn07CiNlbmRpZgoKLyoqCiAqCWkyb19pb3BfZmluZCAtIEZpbmQgYW4gSTJPIGNvbnRyb2xsZXIgYnkgaWQKICoJQHVuaXQ6IHVuaXQgbnVtYmVyIG9mIHRoZSBJMk8gY29udHJvbGxlciB0byBzZWFyY2ggZm9yCiAqCiAqCUxvb2t1cCB0aGUgSTJPIGNvbnRyb2xsZXIgb24gdGhlIGNvbnRyb2xsZXIgbGlzdC4KICoKICoJUmV0dXJucyBwb2ludGVyIHRvIHRoZSBJMk8gY29udHJvbGxlciBvbiBzdWNjZXNzIG9yIE5VTEwgaWYgbm90IGZvdW5kLgogKi8Kc3RydWN0IGkyb19jb250cm9sbGVyICppMm9fZmluZF9pb3AoaW50IHVuaXQpCnsKCXN0cnVjdCBpMm9fY29udHJvbGxlciAqYzsKCglsaXN0X2Zvcl9lYWNoX2VudHJ5KGMsICZpMm9fY29udHJvbGxlcnMsIGxpc3QpIHsKCQlpZiAoYy0+dW5pdCA9PSB1bml0KQoJCQlyZXR1cm4gYzsKCX0KCglyZXR1cm4gTlVMTDsKfTsKCi8qKgogKglpMm9faW9wX2ZpbmRfZGV2aWNlIC0gRmluZCBhIEkyTyBkZXZpY2Ugb24gYW4gSTJPIGNvbnRyb2xsZXIKICoJQGM6IEkyTyBjb250cm9sbGVyIHdoZXJlIHRoZSBJMk8gZGV2aWNlIGhhbmdzIG9uCiAqCUB0aWQ6IFRJRCBvZiB0aGUgSTJPIGRldmljZSB0byBzZWFyY2ggZm9yCiAqCiAqCVNlYXJjaGVzIHRoZSBkZXZpY2VzIG9mIHRoZSBJMk8gY29udHJvbGxlciBmb3IgYSBkZXZpY2Ugd2l0aCBUSUQgdGlkIGFuZAogKglyZXR1cm5zIGl0LgogKgogKglSZXR1cm5zIGEgcG9pbnRlciB0byB0aGUgSTJPIGRldmljZSBpZiBmb3VuZCwgb3RoZXJ3aXNlIE5VTEwuCiAqLwpzdHJ1Y3QgaTJvX2RldmljZSAqaTJvX2lvcF9maW5kX2RldmljZShzdHJ1Y3QgaTJvX2NvbnRyb2xsZXIgKmMsIHUxNiB0aWQpCnsKCXN0cnVjdCBpMm9fZGV2aWNlICpkZXY7CgoJbGlzdF9mb3JfZWFjaF9lbnRyeShkZXYsICZjLT5kZXZpY2VzLCBsaXN0KQoJICAgIGlmIChkZXYtPmxjdF9kYXRhLnRpZCA9PSB0aWQpCgkJcmV0dXJuIGRldjsKCglyZXR1cm4gTlVMTDsKfTsKCi8qKgogKglpMm9fcXVpZXNjZV9jb250cm9sbGVyIC0gcXVpZXNjZSBjb250cm9sbGVyCiAqCUBjOiBjb250cm9sbGVyCiAqCiAqCVF1aWVzY2UgYW4gSU9QLiBDYXVzZXMgSU9QIHRvIG1ha2UgZXh0ZXJuYWwgb3BlcmF0aW9uIHF1aWVzY2VudAogKgkoaTJvICdSRUFEWScgc3RhdGUpLiBJbnRlcm5hbCBvcGVyYXRpb24gb2YgdGhlIElPUCBjb250aW51ZXMgbm9ybWFsbHkuCiAqCiAqCVJldHVybnMgMCBvbiBzdWNjZXNzIG9yIG5lZ2F0aXZlIGVycm9yIGNvZGUgb24gZmFpbHVyZS4KICovCnN0YXRpYyBpbnQgaTJvX2lvcF9xdWllc2NlKHN0cnVjdCBpMm9fY29udHJvbGxlciAqYykKewoJc3RydWN0IGkyb19tZXNzYWdlIF9faW9tZW0gKm1zZzsKCXUzMiBtOwoJaTJvX3N0YXR1c19ibG9jayAqc2IgPSBjLT5zdGF0dXNfYmxvY2sudmlydDsKCWludCByYzsKCglpMm9fc3RhdHVzX2dldChjKTsKCgkvKiBTeXNRdWllc2NlIGRpc2NhcmRlZCBpZiBJT1Agbm90IGluIFJFQURZIG9yIE9QRVJBVElPTkFMIHN0YXRlICovCglpZiAoKHNiLT5pb3Bfc3RhdGUgIT0gQURBUFRFUl9TVEFURV9SRUFEWSkgJiYKCSAgICAoc2ItPmlvcF9zdGF0ZSAhPSBBREFQVEVSX1NUQVRFX09QRVJBVElPTkFMKSkKCQlyZXR1cm4gMDsKCgltID0gaTJvX21zZ19nZXRfd2FpdChjLCAmbXNnLCBJMk9fVElNRU9VVF9NRVNTQUdFX0dFVCk7CglpZiAobSA9PSBJMk9fUVVFVUVfRU1QVFkpCgkJcmV0dXJuIC1FVElNRURPVVQ7CgoJd3JpdGVsKEZPVVJfV09SRF9NU0dfU0laRSB8IFNHTF9PRkZTRVRfMCwgJm1zZy0+dS5oZWFkWzBdKTsKCXdyaXRlbChJMk9fQ01EX1NZU19RVUlFU0NFIDw8IDI0IHwgSE9TVF9USUQgPDwgMTIgfCBBREFQVEVSX1RJRCwKCSAgICAgICAmbXNnLT51LmhlYWRbMV0pOwoKCS8qIExvbmcgdGltZW91dCBuZWVkZWQgZm9yIHF1aWVzY2UgaWYgbG90cyBvZiBkZXZpY2VzICovCglpZiAoKHJjID0gaTJvX21zZ19wb3N0X3dhaXQoYywgbSwgMjQwKSkpCgkJb3NtX2luZm8oIiVzOiBVbmFibGUgdG8gcXVpZXNjZSAoc3RhdHVzPSUjeCkuXG4iLCBjLT5uYW1lLCAtcmMpOwoJZWxzZQoJCW9zbV9kZWJ1ZygiJXM6IFF1aWVzY2VkLlxuIiwgYy0+bmFtZSk7CgoJaTJvX3N0YXR1c19nZXQoYyk7CS8vIEVudGVyZWQgUkVBRFkgc3RhdGUKCglyZXR1cm4gcmM7Cn07CgovKioKICoJaTJvX2lvcF9lbmFibGUgLSBtb3ZlIGNvbnRyb2xsZXIgZnJvbSByZWFkeSB0byBPUEVSQVRJT05BTAogKglAYzogSTJPIGNvbnRyb2xsZXIKICoKICoJRW5hYmxlIElPUC4gVGhpcyBhbGxvd3MgdGhlIElPUCB0byByZXN1bWUgZXh0ZXJuYWwgb3BlcmF0aW9ucyBhbmQKICoJcmV2ZXJzZXMgdGhlIGVmZmVjdCBvZiBhIHF1aWVzY2UuIFJldHVybnMgemVybyBvciBhbiBlcnJvciBjb2RlIGlmCiAqCWFuIGVycm9yIG9jY3Vycy4KICovCnN0YXRpYyBpbnQgaTJvX2lvcF9lbmFibGUoc3RydWN0IGkyb19jb250cm9sbGVyICpjKQp7CglzdHJ1Y3QgaTJvX21lc3NhZ2UgX19pb21lbSAqbXNnOwoJdTMyIG07CglpMm9fc3RhdHVzX2Jsb2NrICpzYiA9IGMtPnN0YXR1c19ibG9jay52aXJ0OwoJaW50IHJjOwoKCWkyb19zdGF0dXNfZ2V0KGMpOwoKCS8qIEVuYWJsZSBvbmx5IGFsbG93ZWQgb24gUkVBRFkgc3RhdGUgKi8KCWlmIChzYi0+aW9wX3N0YXRlICE9IEFEQVBURVJfU1RBVEVfUkVBRFkpCgkJcmV0dXJuIC1FSU5WQUw7CgoJbSA9IGkyb19tc2dfZ2V0X3dhaXQoYywgJm1zZywgSTJPX1RJTUVPVVRfTUVTU0FHRV9HRVQpOwoJaWYgKG0gPT0gSTJPX1FVRVVFX0VNUFRZKQoJCXJldHVybiAtRVRJTUVET1VUOwoKCXdyaXRlbChGT1VSX1dPUkRfTVNHX1NJWkUgfCBTR0xfT0ZGU0VUXzAsICZtc2ctPnUuaGVhZFswXSk7Cgl3cml0ZWwoSTJPX0NNRF9TWVNfRU5BQkxFIDw8IDI0IHwgSE9TVF9USUQgPDwgMTIgfCBBREFQVEVSX1RJRCwKCSAgICAgICAmbXNnLT51LmhlYWRbMV0pOwoKCS8qIEhvdyBsb25nIG9mIGEgdGltZW91dCBkbyB3ZSBuZWVkPyAqLwoJaWYgKChyYyA9IGkyb19tc2dfcG9zdF93YWl0KGMsIG0sIDI0MCkpKQoJCW9zbV9lcnIoIiVzOiBDb3VsZCBub3QgZW5hYmxlIChzdGF0dXM9JSN4KS5cbiIsIGMtPm5hbWUsIC1yYyk7CgllbHNlCgkJb3NtX2RlYnVnKCIlczogRW5hYmxlZC5cbiIsIGMtPm5hbWUpOwoKCWkyb19zdGF0dXNfZ2V0KGMpOwkvLyBlbnRlcmVkIE9QRVJBVElPTkFMIHN0YXRlCgoJcmV0dXJuIHJjOwp9OwoKLyoqCiAqCWkyb19pb3BfcXVpZXNjZV9hbGwgLSBRdWllc2NlIGFsbCBJMk8gY29udHJvbGxlcnMgb24gdGhlIHN5c3RlbQogKgogKglRdWllc2NlIGFsbCBJMk8gY29udHJvbGxlcnMgd2hpY2ggYXJlIGNvbm5lY3RlZCB0byB0aGUgc3lzdGVtLgogKi8Kc3RhdGljIGlubGluZSB2b2lkIGkyb19pb3BfcXVpZXNjZV9hbGwodm9pZCkKewoJc3RydWN0IGkyb19jb250cm9sbGVyICpjLCAqdG1wOwoKCWxpc3RfZm9yX2VhY2hfZW50cnlfc2FmZShjLCB0bXAsICZpMm9fY29udHJvbGxlcnMsIGxpc3QpIHsKCQlpZiAoIWMtPm5vX3F1aWVzY2UpCgkJCWkyb19pb3BfcXVpZXNjZShjKTsKCX0KfTsKCi8qKgogKglpMm9faW9wX2VuYWJsZV9hbGwgLSBFbmFibGVzIGFsbCBjb250cm9sbGVycyBvbiB0aGUgc3lzdGVtCiAqCiAqCUVuYWJsZXMgYWxsIEkyTyBjb250cm9sbGVycyB3aGljaCBhcmUgY29ubmVjdGVkIHRvIHRoZSBzeXN0ZW0uCiAqLwpzdGF0aWMgaW5saW5lIHZvaWQgaTJvX2lvcF9lbmFibGVfYWxsKHZvaWQpCnsKCXN0cnVjdCBpMm9fY29udHJvbGxlciAqYywgKnRtcDsKCglsaXN0X2Zvcl9lYWNoX2VudHJ5X3NhZmUoYywgdG1wLCAmaTJvX2NvbnRyb2xsZXJzLCBsaXN0KQoJICAgIGkyb19pb3BfZW5hYmxlKGMpOwp9OwoKLyoqCiAqCWkyb19jbGVhcl9jb250cm9sbGVyIC0gQnJpbmcgSTJPIGNvbnRyb2xsZXIgaW50byBIT0xEIHN0YXRlCiAqCUBjOiBjb250cm9sbGVyCiAqCiAqCUNsZWFyIGFuIElPUCB0byBIT0xEIHN0YXRlLCBpZS4gdGVybWluYXRlIGV4dGVybmFsIG9wZXJhdGlvbnMsIGNsZWFyIGFsbAogKglpbnB1dCBxdWV1ZXMgYW5kIHByZXBhcmUgZm9yIGEgc3lzdGVtIHJlc3RhcnQuIElPUCdzIGludGVybmFsIG9wZXJhdGlvbgogKgljb250aW51ZXMgbm9ybWFsbHkgYW5kIHRoZSBvdXRib3VuZCBxdWV1ZSBpcyBhbGl2ZS4gVGhlIElPUCBpcyBub3QKICoJZXhwZWN0ZWQgdG8gcmVidWlsZCBpdHMgTENULgogKgogKglSZXR1cm5zIDAgb24gc3VjY2VzcyBvciBuZWdhdGl2ZSBlcnJvciBjb2RlIG9uIGZhaWx1cmUuCiAqLwpzdGF0aWMgaW50IGkyb19pb3BfY2xlYXIoc3RydWN0IGkyb19jb250cm9sbGVyICpjKQp7CglzdHJ1Y3QgaTJvX21lc3NhZ2UgX19pb21lbSAqbXNnOwoJdTMyIG07CglpbnQgcmM7CgoJbSA9IGkyb19tc2dfZ2V0X3dhaXQoYywgJm1zZywgSTJPX1RJTUVPVVRfTUVTU0FHRV9HRVQpOwoJaWYgKG0gPT0gSTJPX1FVRVVFX0VNUFRZKQoJCXJldHVybiAtRVRJTUVET1VUOwoKCS8qIFF1aWVzY2UgYWxsIElPUHMgZmlyc3QgKi8KCWkyb19pb3BfcXVpZXNjZV9hbGwoKTsKCgl3cml0ZWwoRk9VUl9XT1JEX01TR19TSVpFIHwgU0dMX09GRlNFVF8wLCAmbXNnLT51LmhlYWRbMF0pOwoJd3JpdGVsKEkyT19DTURfQURBUFRFUl9DTEVBUiA8PCAyNCB8IEhPU1RfVElEIDw8IDEyIHwgQURBUFRFUl9USUQsCgkgICAgICAgJm1zZy0+dS5oZWFkWzFdKTsKCglpZiAoKHJjID0gaTJvX21zZ19wb3N0X3dhaXQoYywgbSwgMzApKSkKCQlvc21faW5mbygiJXM6IFVuYWJsZSB0byBjbGVhciAoc3RhdHVzPSUjeCkuXG4iLCBjLT5uYW1lLCAtcmMpOwoJZWxzZQoJCW9zbV9kZWJ1ZygiJXM6IENsZWFyZWQuXG4iLCBjLT5uYW1lKTsKCgkvKiBFbmFibGUgYWxsIElPUHMgKi8KCWkyb19pb3BfZW5hYmxlX2FsbCgpOwoKCXJldHVybiByYzsKfQoKLyoqCiAqCWkyb19pb3BfaW5pdF9vdXRib3VuZF9xdWV1ZSAtIHNldHVwIHRoZSBvdXRib3VuZCBtZXNzYWdlIHF1ZXVlCiAqCUBjOiBJMk8gY29udHJvbGxlcgogKgogKglDbGVhciBhbmQgKHJlKWluaXRpYWxpemUgSU9QJ3Mgb3V0Ym91bmQgcXVldWUgYW5kIHBvc3QgdGhlIG1lc3NhZ2UKICoJZnJhbWVzIHRvIHRoZSBJT1AuCiAqCiAqCVJldHVybnMgMCBvbiBzdWNjZXNzIG9yIGEgbmVnYXRpdmUgZXJybm8gY29kZSBvbiBmYWlsdXJlLgogKi8Kc3RhdGljIGludCBpMm9faW9wX2luaXRfb3V0Ym91bmRfcXVldWUoc3RydWN0IGkyb19jb250cm9sbGVyICpjKQp7Cgl2b2xhdGlsZSB1OCAqc3RhdHVzID0gYy0+c3RhdHVzLnZpcnQ7Cgl1MzIgbTsKCXN0cnVjdCBpMm9fbWVzc2FnZSBfX2lvbWVtICptc2c7Cgl1bG9uZyB0aW1lb3V0OwoJaW50IGk7CgoJb3NtX2RlYnVnKCIlczogSW5pdGlhbGl6aW5nIE91dGJvdW5kIFF1ZXVlLi4uXG4iLCBjLT5uYW1lKTsKCgltZW1zZXQoYy0+c3RhdHVzLnZpcnQsIDAsIDQpOwoKCW0gPSBpMm9fbXNnX2dldF93YWl0KGMsICZtc2csIEkyT19USU1FT1VUX01FU1NBR0VfR0VUKTsKCWlmIChtID09IEkyT19RVUVVRV9FTVBUWSkKCQlyZXR1cm4gLUVUSU1FRE9VVDsKCgl3cml0ZWwoRUlHSFRfV09SRF9NU0dfU0laRSB8IFNHTF9PRkZTRVRfNiwgJm1zZy0+dS5oZWFkWzBdKTsKCXdyaXRlbChJMk9fQ01EX09VVEJPVU5EX0lOSVQgPDwgMjQgfCBIT1NUX1RJRCA8PCAxMiB8IEFEQVBURVJfVElELAoJICAgICAgICZtc2ctPnUuaGVhZFsxXSk7Cgl3cml0ZWwoaTJvX2V4ZWNfZHJpdmVyLmNvbnRleHQsICZtc2ctPnUucy5pY250eHQpOwoJd3JpdGVsKDB4MDAwMDAwMDAsICZtc2ctPnUucy50Y250eHQpOwoJd3JpdGVsKFBBR0VfU0laRSwgJm1zZy0+Ym9keVswXSk7CgkvKiBPdXRib3VuZCBtc2cgZnJhbWUgc2l6ZSBpbiB3b3JkcyBhbmQgSW5pdGNvZGUgKi8KCXdyaXRlbChJMk9fT1VUQk9VTkRfTVNHX0ZSQU1FX1NJWkUgPDwgMTYgfCAweDgwLCAmbXNnLT5ib2R5WzFdKTsKCXdyaXRlbCgweGQwMDAwMDA0LCAmbXNnLT5ib2R5WzJdKTsKCXdyaXRlbChpMm9fZG1hX2xvdyhjLT5zdGF0dXMucGh5cyksICZtc2ctPmJvZHlbM10pOwoJd3JpdGVsKGkyb19kbWFfaGlnaChjLT5zdGF0dXMucGh5cyksICZtc2ctPmJvZHlbNF0pOwoKCWkyb19tc2dfcG9zdChjLCBtKTsKCgl0aW1lb3V0ID0gamlmZmllcyArIEkyT19USU1FT1VUX0lOSVRfT1VUQk9VTkRfUVVFVUUgKiBIWjsKCXdoaWxlICgqc3RhdHVzIDw9IEkyT19DTURfSU5fUFJPR1JFU1MpIHsKCQlpZiAodGltZV9hZnRlcihqaWZmaWVzLCB0aW1lb3V0KSkgewoJCQlvc21fd2FybigiJXM6IFRpbWVvdXQgSW5pdGlhbGl6aW5nXG4iLCBjLT5uYW1lKTsKCQkJcmV0dXJuIC1FVElNRURPVVQ7CgkJfQoJCXNjaGVkdWxlX3RpbWVvdXRfdW5pbnRlcnJ1cHRpYmxlKDEpOwoJfQoKCW0gPSBjLT5vdXRfcXVldWUucGh5czsKCgkvKiBQb3N0IGZyYW1lcyAqLwoJZm9yIChpID0gMDsgaSA8IEkyT19NQVhfT1VUQk9VTkRfTVNHX0ZSQU1FUzsgaSsrKSB7CgkJaTJvX2ZsdXNoX3JlcGx5KGMsIG0pOwoJCXVkZWxheSgxKTsJLyogUHJvbWlzZSAqLwoJCW0gKz0gSTJPX09VVEJPVU5EX01TR19GUkFNRV9TSVpFICogc2l6ZW9mKHUzMik7Cgl9CgoJcmV0dXJuIDA7Cn0KCi8qKgogKglpMm9faW9wX3Jlc2V0IC0gcmVzZXQgYW4gSTJPIGNvbnRyb2xsZXIKICoJQGM6IGNvbnRyb2xsZXIgdG8gcmVzZXQKICoKICoJUmVzZXQgdGhlIElPUCBpbnRvIElOSVQgc3RhdGUgYW5kIHdhaXQgdW50aWwgSU9QIGdldHMgaW50byBSRVNFVCBzdGF0ZS4KICoJVGVybWluYXRlIGFsbCBleHRlcm5hbCBvcGVyYXRpb25zLCBjbGVhciBJT1AncyBpbmJvdW5kIGFuZCBvdXRib3VuZAogKglxdWV1ZXMsIHRlcm1pbmF0ZSBhbGwgRERNcywgYW5kIHJlbG9hZCB0aGUgSU9QJ3Mgb3BlcmF0aW5nIGVudmlyb25tZW50CiAqCWFuZCBhbGwgbG9jYWwgRERNcy4gVGhlIElPUCByZWJ1aWxkcyBpdHMgTENULgogKi8Kc3RhdGljIGludCBpMm9faW9wX3Jlc2V0KHN0cnVjdCBpMm9fY29udHJvbGxlciAqYykKewoJdm9sYXRpbGUgdTggKnN0YXR1cyA9IGMtPnN0YXR1cy52aXJ0OwoJc3RydWN0IGkyb19tZXNzYWdlIF9faW9tZW0gKm1zZzsKCXUzMiBtOwoJdW5zaWduZWQgbG9uZyB0aW1lb3V0OwoJaTJvX3N0YXR1c19ibG9jayAqc2IgPSBjLT5zdGF0dXNfYmxvY2sudmlydDsKCWludCByYyA9IDA7CgoJb3NtX2RlYnVnKCIlczogUmVzZXR0aW5nIGNvbnRyb2xsZXJcbiIsIGMtPm5hbWUpOwoKCW0gPSBpMm9fbXNnX2dldF93YWl0KGMsICZtc2csIEkyT19USU1FT1VUX01FU1NBR0VfR0VUKTsKCWlmIChtID09IEkyT19RVUVVRV9FTVBUWSkKCQlyZXR1cm4gLUVUSU1FRE9VVDsKCgltZW1zZXQoYy0+c3RhdHVzX2Jsb2NrLnZpcnQsIDAsIDgpOwoKCS8qIFF1aWVzY2UgYWxsIElPUHMgZmlyc3QgKi8KCWkyb19pb3BfcXVpZXNjZV9hbGwoKTsKCgl3cml0ZWwoRUlHSFRfV09SRF9NU0dfU0laRSB8IFNHTF9PRkZTRVRfMCwgJm1zZy0+dS5oZWFkWzBdKTsKCXdyaXRlbChJMk9fQ01EX0FEQVBURVJfUkVTRVQgPDwgMjQgfCBIT1NUX1RJRCA8PCAxMiB8IEFEQVBURVJfVElELAoJICAgICAgICZtc2ctPnUuaGVhZFsxXSk7Cgl3cml0ZWwoaTJvX2V4ZWNfZHJpdmVyLmNvbnRleHQsICZtc2ctPnUucy5pY250eHQpOwoJd3JpdGVsKDAsICZtc2ctPnUucy50Y250eHQpOwkvL0ZJWE1FOiB1c2UgcmVhc29uYWJsZSB0cmFuc2FjdGlvbiBjb250ZXh0Cgl3cml0ZWwoMCwgJm1zZy0+Ym9keVswXSk7Cgl3cml0ZWwoMCwgJm1zZy0+Ym9keVsxXSk7Cgl3cml0ZWwoaTJvX2RtYV9sb3coYy0+c3RhdHVzLnBoeXMpLCAmbXNnLT5ib2R5WzJdKTsKCXdyaXRlbChpMm9fZG1hX2hpZ2goYy0+c3RhdHVzLnBoeXMpLCAmbXNnLT5ib2R5WzNdKTsKCglpMm9fbXNnX3Bvc3QoYywgbSk7CgoJLyogV2FpdCBmb3IgYSByZXBseSAqLwoJdGltZW91dCA9IGppZmZpZXMgKyBJMk9fVElNRU9VVF9SRVNFVCAqIEhaOwoJd2hpbGUgKCEqc3RhdHVzKSB7CgkJaWYgKHRpbWVfYWZ0ZXIoamlmZmllcywgdGltZW91dCkpCgkJCWJyZWFrOwoKCQlzY2hlZHVsZV90aW1lb3V0X3VuaW50ZXJydXB0aWJsZSgxKTsKCX0KCglzd2l0Y2ggKCpzdGF0dXMpIHsKCWNhc2UgSTJPX0NNRF9SRUpFQ1RFRDoKCQlvc21fd2FybigiJXM6IElPUCByZXNldCByZWplY3RlZFxuIiwgYy0+bmFtZSk7CgkJcmMgPSAtRVBFUk07CgkJYnJlYWs7CgoJY2FzZSBJMk9fQ01EX0lOX1BST0dSRVNTOgoJCS8qCgkJICogT25jZSB0aGUgcmVzZXQgaXMgc2VudCwgdGhlIElPUCBnb2VzIGludG8gdGhlIElOSVQgc3RhdGUKCQkgKiB3aGljaCBpcyBpbmRldGVybWluYXRlLiBXZSBuZWVkIHRvIHdhaXQgdW50aWwgdGhlIElPUCBoYXMKCQkgKiByZWJvb3RlZCBiZWZvcmUgd2UgY2FuIGxldCB0aGUgc3lzdGVtIHRhbGsgdG8gaXQuIFdlIHJlYWQKCQkgKiB0aGUgaW5ib3VuZCBGcmVlX0xpc3QgdW50aWwgYSBtZXNzYWdlIGlzIGF2YWlsYWJsZS4gSWYgd2UKCQkgKiBjYW4ndCByZWFkIG9uZSBpbiB0aGUgZ2l2ZW4gYW1tb3VudCBvZiB0aW1lLCB3ZSBhc3N1bWUgdGhlCgkJICogSU9QIGNvdWxkIG5vdCByZWJvb3QgcHJvcGVybHkuCgkJICovCgkJb3NtX2RlYnVnKCIlczogUmVzZXQgaW4gcHJvZ3Jlc3MsIHdhaXRpbmcgZm9yIHJlYm9vdC4uLlxuIiwKCQkJICBjLT5uYW1lKTsKCgkJbSA9IGkyb19tc2dfZ2V0X3dhaXQoYywgJm1zZywgSTJPX1RJTUVPVVRfUkVTRVQpOwoJCXdoaWxlIChtID09IEkyT19RVUVVRV9FTVBUWSkgewoJCQlpZiAodGltZV9hZnRlcihqaWZmaWVzLCB0aW1lb3V0KSkgewoJCQkJb3NtX2VycigiJXM6IElPUCByZXNldCB0aW1lb3V0LlxuIiwgYy0+bmFtZSk7CgkJCQlyYyA9IC1FVElNRURPVVQ7CgkJCQlnb3RvIGV4aXQ7CgkJCX0KCQkJc2NoZWR1bGVfdGltZW91dF91bmludGVycnVwdGlibGUoMSk7CgoJCQltID0gaTJvX21zZ19nZXRfd2FpdChjLCAmbXNnLCBJMk9fVElNRU9VVF9SRVNFVCk7CgkJfQoJCWkyb19tc2dfbm9wKGMsIG0pOwoKCQkvKiBmcm9tIGhlcmUgYWxsIHF1aWVzY2UgY29tbWFuZHMgYXJlIHNhZmUgKi8KCQljLT5ub19xdWllc2NlID0gMDsKCgkJLyogdmVyaWZ5IGlmIGNvbnRyb2xsZXIgaXMgaW4gc3RhdGUgUkVTRVQgKi8KCQlpMm9fc3RhdHVzX2dldChjKTsKCgkJaWYgKCFjLT5wcm9taXNlICYmIChzYi0+aW9wX3N0YXRlICE9IEFEQVBURVJfU1RBVEVfUkVTRVQpKQoJCQlvc21fd2FybigiJXM6IHJlc2V0IGNvbXBsZXRlZCwgYnV0IGFkYXB0ZXIgbm90IGluIFJFU0VUIgoJCQkJICIgc3RhdGUuXG4iLCBjLT5uYW1lKTsKCQllbHNlCgkJCW9zbV9kZWJ1ZygiJXM6IHJlc2V0IGNvbXBsZXRlZC5cbiIsIGMtPm5hbWUpOwoKCQlicmVhazsKCglkZWZhdWx0OgoJCW9zbV9lcnIoIiVzOiBJT1AgcmVzZXQgdGltZW91dC5cbiIsIGMtPm5hbWUpOwoJCXJjID0gLUVUSU1FRE9VVDsKCQlicmVhazsKCX0KCiAgICAgIGV4aXQ6CgkvKiBFbmFibGUgYWxsIElPUHMgKi8KCWkyb19pb3BfZW5hYmxlX2FsbCgpOwoKCXJldHVybiByYzsKfTsKCi8qKgogKglpMm9faW9wX2FjdGl2YXRlIC0gQnJpbmcgY29udHJvbGxlciB1cCB0byBIT0xECiAqCUBjOiBjb250cm9sbGVyCiAqCiAqCVRoaXMgZnVuY3Rpb24gYnJpbmdzIGFuIEkyTyBjb250cm9sbGVyIGludG8gSE9MRCBzdGF0ZS4gVGhlIGFkYXB0ZXIKICoJaXMgcmVzZXQgaWYgbmVjZXNzYXJ5IGFuZCB0aGVuIHRoZSBxdWV1ZXMgYW5kIHJlc291cmNlIHRhYmxlIGFyZSByZWFkLgogKgogKglSZXR1cm5zIDAgb24gc3VjY2VzcyBvciBuZWdhdGl2ZSBlcnJvciBjb2RlIG9uIGZhaWx1cmUuCiAqLwpzdGF0aWMgaW50IGkyb19pb3BfYWN0aXZhdGUoc3RydWN0IGkyb19jb250cm9sbGVyICpjKQp7CglpMm9fc3RhdHVzX2Jsb2NrICpzYiA9IGMtPnN0YXR1c19ibG9jay52aXJ0OwoJaW50IHJjOwoJaW50IHN0YXRlOwoKCS8qIEluIElOSVQgc3RhdGUsIFdhaXQgSW5ib3VuZCBRIHRvIGluaXRpYWxpemUgKGluIGkyb19zdGF0dXNfZ2V0KSAqLwoJLyogSW4gUkVBRFkgc3RhdGUsIEdldCBzdGF0dXMgKi8KCglyYyA9IGkyb19zdGF0dXNfZ2V0KGMpOwoJaWYgKHJjKSB7CgkJb3NtX2luZm8oIiVzOiBVbmFibGUgdG8gb2J0YWluIHN0YXR1cywgYXR0ZW1wdGluZyBhIHJlc2V0LlxuIiwKCQkJIGMtPm5hbWUpOwoJCXJjID0gaTJvX2lvcF9yZXNldChjKTsKCQlpZiAocmMpCgkJCXJldHVybiByYzsKCX0KCglpZiAoc2ItPmkyb192ZXJzaW9uID4gSTJPVkVSMTUpIHsKCQlvc21fZXJyKCIlczogTm90IHJ1bm5pbmcgdmVyc2lvbiAxLjUgb2YgdGhlIEkyTyBTcGVjaWZpY2F0aW9uLiIKCQkJIlxuIiwgYy0+bmFtZSk7CgkJcmV0dXJuIC1FTk9ERVY7Cgl9CgoJc3dpdGNoIChzYi0+aW9wX3N0YXRlKSB7CgljYXNlIEFEQVBURVJfU1RBVEVfRkFVTFRFRDoKCQlvc21fZXJyKCIlczogaGFyZHdhcmUgZmF1bHRcbiIsIGMtPm5hbWUpOwoJCXJldHVybiAtRUZBVUxUOwoKCWNhc2UgQURBUFRFUl9TVEFURV9SRUFEWToKCWNhc2UgQURBUFRFUl9TVEFURV9PUEVSQVRJT05BTDoKCWNhc2UgQURBUFRFUl9TVEFURV9IT0xEOgoJY2FzZSBBREFQVEVSX1NUQVRFX0ZBSUxFRDoKCQlvc21fZGVidWcoIiVzOiBhbHJlYWR5IHJ1bm5pbmcsIHRyeWluZyB0byByZXNldC4uLlxuIiwgYy0+bmFtZSk7CgkJcmMgPSBpMm9faW9wX3Jlc2V0KGMpOwoJCWlmIChyYykKCQkJcmV0dXJuIHJjOwoJfQoKCS8qIHByZXNlcnZlIHN0YXRlICovCglzdGF0ZSA9IHNiLT5pb3Bfc3RhdGU7CgoJcmMgPSBpMm9faW9wX2luaXRfb3V0Ym91bmRfcXVldWUoYyk7CglpZiAocmMpCgkJcmV0dXJuIHJjOwoKCS8qIGlmIGFkYXB0ZXIgd2FzIG5vdCBpbiBSRVNFVCBzdGF0ZSBjbGVhciBub3cgKi8KCWlmIChzdGF0ZSAhPSBBREFQVEVSX1NUQVRFX1JFU0VUKQoJCWkyb19pb3BfY2xlYXIoYyk7CgoJaTJvX3N0YXR1c19nZXQoYyk7CgoJaWYgKHNiLT5pb3Bfc3RhdGUgIT0gQURBUFRFUl9TVEFURV9IT0xEKSB7CgkJb3NtX2VycigiJXM6IGZhaWxlZCB0byBicmluZyBJT1AgaW50byBIT0xEIHN0YXRlXG4iLCBjLT5uYW1lKTsKCQlyZXR1cm4gLUVJTzsKCX0KCglyZXR1cm4gaTJvX2hydF9nZXQoYyk7Cn07CgovKioKICoJaTJvX2lvcF9zeXN0YWJfc2V0IC0gU2V0IHRoZSBJMk8gU3lzdGVtIFRhYmxlIG9mIHRoZSBzcGVjaWZpZWQgSU9QCiAqCUBjOiBJMk8gY29udHJvbGxlciB0byB3aGljaCB0aGUgc3lzdGVtIHRhYmxlIHNob3VsZCBiZSBzZW5kCiAqCiAqCUJlZm9yZSB0aGUgc3lzdGFiIGNvdWxkIGJlIHNldCBpMm9fc3lzdGFiX2J1aWxkKCkgbXVzdCBiZSBjYWxsZWQuCiAqCiAqCVJldHVybnMgMCBvbiBzdWNjZXNzIG9yIG5lZ2F0aXZlIGVycm9yIGNvZGUgb24gZmFpbHVyZS4KICovCnN0YXRpYyBpbnQgaTJvX2lvcF9zeXN0YWJfc2V0KHN0cnVjdCBpMm9fY29udHJvbGxlciAqYykKewoJc3RydWN0IGkyb19tZXNzYWdlIF9faW9tZW0gKm1zZzsKCXUzMiBtOwoJaTJvX3N0YXR1c19ibG9jayAqc2IgPSBjLT5zdGF0dXNfYmxvY2sudmlydDsKCXN0cnVjdCBkZXZpY2UgKmRldiA9ICZjLT5wZGV2LT5kZXY7CglzdHJ1Y3QgcmVzb3VyY2UgKnJvb3Q7CglpbnQgcmM7CgoJaWYgKHNiLT5jdXJyZW50X21lbV9zaXplIDwgc2ItPmRlc2lyZWRfbWVtX3NpemUpIHsKCQlzdHJ1Y3QgcmVzb3VyY2UgKnJlcyA9ICZjLT5tZW1fcmVzb3VyY2U7CgkJcmVzLT5uYW1lID0gYy0+cGRldi0+YnVzLT5uYW1lOwoJCXJlcy0+ZmxhZ3MgPSBJT1JFU09VUkNFX01FTTsKCQlyZXMtPnN0YXJ0ID0gMDsKCQlyZXMtPmVuZCA9IDA7CgkJb3NtX2luZm8oIiVzOiByZXF1aXJlcyBwcml2YXRlIG1lbW9yeSByZXNvdXJjZXMuXG4iLCBjLT5uYW1lKTsKCQlyb290ID0gcGNpX2ZpbmRfcGFyZW50X3Jlc291cmNlKGMtPnBkZXYsIHJlcyk7CgkJaWYgKHJvb3QgPT0gTlVMTCkKCQkJb3NtX3dhcm4oIiVzOiBDYW4ndCBmaW5kIHBhcmVudCByZXNvdXJjZSFcbiIsIGMtPm5hbWUpOwoJCWlmIChyb290ICYmIGFsbG9jYXRlX3Jlc291cmNlKHJvb3QsIHJlcywgc2ItPmRlc2lyZWRfbWVtX3NpemUsIHNiLT5kZXNpcmVkX21lbV9zaXplLCBzYi0+ZGVzaXJlZF9tZW1fc2l6ZSwgMSA8PCAyMCwJLyogVW5zcGVjaWZpZWQsIHNvIHVzZSAxTWIgYW5kIHBsYXkgc2FmZSAqLwoJCQkJCSAgICAgIE5VTEwsIE5VTEwpID49IDApIHsKCQkJYy0+bWVtX2FsbG9jID0gMTsKCQkJc2ItPmN1cnJlbnRfbWVtX3NpemUgPSAxICsgcmVzLT5lbmQgLSByZXMtPnN0YXJ0OwoJCQlzYi0+Y3VycmVudF9tZW1fYmFzZSA9IHJlcy0+c3RhcnQ7CgkJCW9zbV9pbmZvKCIlczogYWxsb2NhdGVkICVsZCBieXRlcyBvZiBQQ0kgbWVtb3J5IGF0ICIKCQkJCSAiMHglMDhsWC5cbiIsIGMtPm5hbWUsCgkJCQkgMSArIHJlcy0+ZW5kIC0gcmVzLT5zdGFydCwgcmVzLT5zdGFydCk7CgkJfQoJfQoKCWlmIChzYi0+Y3VycmVudF9pb19zaXplIDwgc2ItPmRlc2lyZWRfaW9fc2l6ZSkgewoJCXN0cnVjdCByZXNvdXJjZSAqcmVzID0gJmMtPmlvX3Jlc291cmNlOwoJCXJlcy0+bmFtZSA9IGMtPnBkZXYtPmJ1cy0+bmFtZTsKCQlyZXMtPmZsYWdzID0gSU9SRVNPVVJDRV9JTzsKCQlyZXMtPnN0YXJ0ID0gMDsKCQlyZXMtPmVuZCA9IDA7CgkJb3NtX2luZm8oIiVzOiByZXF1aXJlcyBwcml2YXRlIG1lbW9yeSByZXNvdXJjZXMuXG4iLCBjLT5uYW1lKTsKCQlyb290ID0gcGNpX2ZpbmRfcGFyZW50X3Jlc291cmNlKGMtPnBkZXYsIHJlcyk7CgkJaWYgKHJvb3QgPT0gTlVMTCkKCQkJb3NtX3dhcm4oIiVzOiBDYW4ndCBmaW5kIHBhcmVudCByZXNvdXJjZSFcbiIsIGMtPm5hbWUpOwoJCWlmIChyb290ICYmIGFsbG9jYXRlX3Jlc291cmNlKHJvb3QsIHJlcywgc2ItPmRlc2lyZWRfaW9fc2l6ZSwgc2ItPmRlc2lyZWRfaW9fc2l6ZSwgc2ItPmRlc2lyZWRfaW9fc2l6ZSwgMSA8PCAyMCwJLyogVW5zcGVjaWZpZWQsIHNvIHVzZSAxTWIgYW5kIHBsYXkgc2FmZSAqLwoJCQkJCSAgICAgIE5VTEwsIE5VTEwpID49IDApIHsKCQkJYy0+aW9fYWxsb2MgPSAxOwoJCQlzYi0+Y3VycmVudF9pb19zaXplID0gMSArIHJlcy0+ZW5kIC0gcmVzLT5zdGFydDsKCQkJc2ItPmN1cnJlbnRfbWVtX2Jhc2UgPSByZXMtPnN0YXJ0OwoJCQlvc21faW5mbygiJXM6IGFsbG9jYXRlZCAlbGQgYnl0ZXMgb2YgUENJIEkvTyBhdCAweCUwOGxYIgoJCQkJICIuXG4iLCBjLT5uYW1lLCAxICsgcmVzLT5lbmQgLSByZXMtPnN0YXJ0LAoJCQkJIHJlcy0+c3RhcnQpOwoJCX0KCX0KCgltID0gaTJvX21zZ19nZXRfd2FpdChjLCAmbXNnLCBJMk9fVElNRU9VVF9NRVNTQUdFX0dFVCk7CglpZiAobSA9PSBJMk9fUVVFVUVfRU1QVFkpCgkJcmV0dXJuIC1FVElNRURPVVQ7CgoJaTJvX3N5c3RhYi5waHlzID0gZG1hX21hcF9zaW5nbGUoZGV2LCBpMm9fc3lzdGFiLnZpcnQsIGkyb19zeXN0YWIubGVuLAoJCQkJCSBQQ0lfRE1BX1RPREVWSUNFKTsKCWlmICghaTJvX3N5c3RhYi5waHlzKSB7CgkJaTJvX21zZ19ub3AoYywgbSk7CgkJcmV0dXJuIC1FTk9NRU07Cgl9CgoJd3JpdGVsKEkyT19NRVNTQUdFX1NJWkUoMTIpIHwgU0dMX09GRlNFVF82LCAmbXNnLT51LmhlYWRbMF0pOwoJd3JpdGVsKEkyT19DTURfU1lTX1RBQl9TRVQgPDwgMjQgfCBIT1NUX1RJRCA8PCAxMiB8IEFEQVBURVJfVElELAoJICAgICAgICZtc2ctPnUuaGVhZFsxXSk7CgoJLyoKCSAqIFByb3ZpZGUgdGhyZWUgU0dMLWVsZW1lbnRzOgoJICogU3lzdGVtIHRhYmxlIChTeXNUYWIpLCBQcml2YXRlIG1lbW9yeSBzcGFjZSBkZWNsYXJhdGlvbiBhbmQKCSAqIFByaXZhdGUgaS9vIHNwYWNlIGRlY2xhcmF0aW9uCgkgKgoJICogRklYTUU6IGlzIHRoaXMgc3RpbGwgdHJ1ZT8KCSAqIE5hc3R5IG9uZSBoZXJlLiBXZSBjYW4ndCB1c2UgZG1hX2FsbG9jX2NvaGVyZW50IHRvIHNlbmQgdGhlCgkgKiBzYW1lIHRhYmxlIHRvIGV2ZXJ5b25lLiBXZSBoYXZlIHRvIGdvIHJlbWFwIGl0IGZvciB0aGVtIGFsbAoJICovCgoJd3JpdGVsKGMtPnVuaXQgKyAyLCAmbXNnLT5ib2R5WzBdKTsKCXdyaXRlbCgwLCAmbXNnLT5ib2R5WzFdKTsKCXdyaXRlbCgweDU0MDAwMDAwIHwgaTJvX3N5c3RhYi5sZW4sICZtc2ctPmJvZHlbMl0pOwoJd3JpdGVsKGkyb19zeXN0YWIucGh5cywgJm1zZy0+Ym9keVszXSk7Cgl3cml0ZWwoMHg1NDAwMDAwMCB8IHNiLT5jdXJyZW50X21lbV9zaXplLCAmbXNnLT5ib2R5WzRdKTsKCXdyaXRlbChzYi0+Y3VycmVudF9tZW1fYmFzZSwgJm1zZy0+Ym9keVs1XSk7Cgl3cml0ZWwoMHhkNDAwMDAwMCB8IHNiLT5jdXJyZW50X2lvX3NpemUsICZtc2ctPmJvZHlbNl0pOwoJd3JpdGVsKHNiLT5jdXJyZW50X2lvX2Jhc2UsICZtc2ctPmJvZHlbNl0pOwoKCXJjID0gaTJvX21zZ19wb3N0X3dhaXQoYywgbSwgMTIwKTsKCglkbWFfdW5tYXBfc2luZ2xlKGRldiwgaTJvX3N5c3RhYi5waHlzLCBpMm9fc3lzdGFiLmxlbiwKCQkJIFBDSV9ETUFfVE9ERVZJQ0UpOwoKCWlmIChyYyA8IDApCgkJb3NtX2VycigiJXM6IFVuYWJsZSB0byBzZXQgU3lzVGFiIChzdGF0dXM9JSN4KS5cbiIsIGMtPm5hbWUsCgkJCS1yYyk7CgllbHNlCgkJb3NtX2RlYnVnKCIlczogU3lzVGFiIHNldC5cbiIsIGMtPm5hbWUpOwoKCWkyb19zdGF0dXNfZ2V0KGMpOwkvLyBFbnRlcmVkIFJFQURZIHN0YXRlCgoJcmV0dXJuIHJjOwp9CgovKioKICoJaTJvX2lvcF9vbmxpbmUgLSBCcmluZyBhIGNvbnRyb2xsZXIgb25saW5lIGludG8gT1BFUkFUSU9OQUwgc3RhdGUuCiAqCUBjOiBJMk8gY29udHJvbGxlcgogKgogKglTZW5kIHRoZSBzeXN0ZW0gdGFibGUgYW5kIGVuYWJsZSB0aGUgSTJPIGNvbnRyb2xsZXIuCiAqCiAqCVJldHVybnMgMCBvbiBzdWNjZXNzIG9yIG5lZ2F0aXZlciBlcnJvciBjb2RlIG9uIGZhaWx1cmUuCiAqLwpzdGF0aWMgaW50IGkyb19pb3Bfb25saW5lKHN0cnVjdCBpMm9fY29udHJvbGxlciAqYykKewoJaW50IHJjOwoKCXJjID0gaTJvX2lvcF9zeXN0YWJfc2V0KGMpOwoJaWYgKHJjKQoJCXJldHVybiByYzsKCgkvKiBJbiBSRUFEWSBzdGF0ZSAqLwoJb3NtX2RlYnVnKCIlczogQXR0ZW1wdGluZyB0byBlbmFibGUuLi5cbiIsIGMtPm5hbWUpOwoJcmMgPSBpMm9faW9wX2VuYWJsZShjKTsKCWlmIChyYykKCQlyZXR1cm4gcmM7CgoJcmV0dXJuIDA7Cn07CgovKioKICoJaTJvX2lvcF9yZW1vdmUgLSBSZW1vdmUgdGhlIEkyTyBjb250cm9sbGVyIGZyb20gdGhlIEkyTyBjb3JlCiAqCUBjOiBJMk8gY29udHJvbGxlcgogKgogKglSZW1vdmUgdGhlIEkyTyBjb250cm9sbGVyIGZyb20gdGhlIEkyTyBjb3JlLiBJZiBkZXZpY2VzIGFyZSBhdHRhY2hlZCB0bwogKgl0aGUgY29udHJvbGxlciByZW1vdmUgdGhlc2UgYWxzbyBhbmQgZmluYWxseSByZXNldCB0aGUgY29udHJvbGxlci4KICovCnZvaWQgaTJvX2lvcF9yZW1vdmUoc3RydWN0IGkyb19jb250cm9sbGVyICpjKQp7CglzdHJ1Y3QgaTJvX2RldmljZSAqZGV2LCAqdG1wOwoKCW9zbV9kZWJ1ZygiJXM6IGRlbGV0aW5nIGNvbnRyb2xsZXJcbiIsIGMtPm5hbWUpOwoKCWkyb19kcml2ZXJfbm90aWZ5X2NvbnRyb2xsZXJfcmVtb3ZlX2FsbChjKTsKCglsaXN0X2RlbCgmYy0+bGlzdCk7CgoJbGlzdF9mb3JfZWFjaF9lbnRyeV9zYWZlKGRldiwgdG1wLCAmYy0+ZGV2aWNlcywgbGlzdCkKCSAgICBpMm9fZGV2aWNlX3JlbW92ZShkZXYpOwoKCWNsYXNzX2RldmljZV91bnJlZ2lzdGVyKGMtPmNsYXNzZGV2KTsKCWRldmljZV9kZWwoJmMtPmRldmljZSk7CgoJLyogQXNrIHRoZSBJT1AgdG8gc3dpdGNoIHRvIFJFU0VUIHN0YXRlICovCglpMm9faW9wX3Jlc2V0KGMpOwoKCXB1dF9kZXZpY2UoJmMtPmRldmljZSk7Cn0KCi8qKgogKglpMm9fc3lzdGFiX2J1aWxkIC0gQnVpbGQgc3lzdGVtIHRhYmxlCiAqCiAqCVRoZSBzeXN0ZW0gdGFibGUgY29udGFpbnMgaW5mb3JtYXRpb24gYWJvdXQgYWxsIHRoZSBJT1BzIGluIHRoZSBzeXN0ZW0KICoJKGR1aCkgYW5kIGlzIHVzZWQgYnkgdGhlIEV4ZWN1dGl2ZXMgb24gdGhlIElPUHMgdG8gZXN0YWJsaXNoIHBlZXIycGVlcgogKgljb25uZWN0aW9ucy4gV2UncmUgbm90IHN1cHBvcnRpbmcgcGVlcjJwZWVyIGF0IHRoZSBtb21lbnQsIGJ1dCB0aGlzCiAqCXdpbGwgYmUgbmVlZGVkIGRvd24gdGhlIHJvYWQgZm9yIHRoaW5ncyBsaWtlIGxhbjJsYW4gZm9yd2FyZGluZy4KICoKICoJUmV0dXJucyAwIG9uIHN1Y2Nlc3Mgb3IgbmVnYXRpdmUgZXJyb3IgY29kZSBvbiBmYWlsdXJlLgogKi8Kc3RhdGljIGludCBpMm9fc3lzdGFiX2J1aWxkKHZvaWQpCnsKCXN0cnVjdCBpMm9fY29udHJvbGxlciAqYywgKnRtcDsKCWludCBudW1fY29udHJvbGxlcnMgPSAwOwoJdTMyIGNoYW5nZV9pbmQgPSAwOwoJaW50IGNvdW50ID0gMDsKCXN0cnVjdCBpMm9fc3lzX3RibCAqc3lzdGFiID0gaTJvX3N5c3RhYi52aXJ0OwoKCWxpc3RfZm9yX2VhY2hfZW50cnlfc2FmZShjLCB0bXAsICZpMm9fY29udHJvbGxlcnMsIGxpc3QpCgkgICAgbnVtX2NvbnRyb2xsZXJzKys7CgoJaWYgKHN5c3RhYikgewoJCWNoYW5nZV9pbmQgPSBzeXN0YWItPmNoYW5nZV9pbmQ7CgkJa2ZyZWUoaTJvX3N5c3RhYi52aXJ0KTsKCX0KCgkvKiBIZWFkZXIgKyBJT1BzICovCglpMm9fc3lzdGFiLmxlbiA9IHNpemVvZihzdHJ1Y3QgaTJvX3N5c190YmwpICsgbnVtX2NvbnRyb2xsZXJzICoKCSAgICBzaXplb2Yoc3RydWN0IGkyb19zeXNfdGJsX2VudHJ5KTsKCglzeXN0YWIgPSBpMm9fc3lzdGFiLnZpcnQgPSBrbWFsbG9jKGkyb19zeXN0YWIubGVuLCBHRlBfS0VSTkVMKTsKCWlmICghc3lzdGFiKSB7CgkJb3NtX2VycigidW5hYmxlIHRvIGFsbG9jYXRlIG1lbW9yeSBmb3IgU3lzdGVtIFRhYmxlXG4iKTsKCQlyZXR1cm4gLUVOT01FTTsKCX0KCW1lbXNldChzeXN0YWIsIDAsIGkyb19zeXN0YWIubGVuKTsKCglzeXN0YWItPnZlcnNpb24gPSBJMk9WRVJTSU9OOwoJc3lzdGFiLT5jaGFuZ2VfaW5kID0gY2hhbmdlX2luZCArIDE7CgoJbGlzdF9mb3JfZWFjaF9lbnRyeV9zYWZlKGMsIHRtcCwgJmkyb19jb250cm9sbGVycywgbGlzdCkgewoJCWkyb19zdGF0dXNfYmxvY2sgKnNiOwoKCQlpZiAoY291bnQgPj0gbnVtX2NvbnRyb2xsZXJzKSB7CgkJCW9zbV9lcnIoImNvbnRyb2xsZXIgYWRkZWQgd2hpbGUgYnVpbGRpbmcgc3lzdGVtIHRhYmxlIgoJCQkJIlxuIik7CgkJCWJyZWFrOwoJCX0KCgkJc2IgPSBjLT5zdGF0dXNfYmxvY2sudmlydDsKCgkJLyoKCQkgKiBHZXQgdXBkYXRlZCBJT1Agc3RhdGUgc28gd2UgaGF2ZSB0aGUgbGF0ZXN0IGluZm9ybWF0aW9uCgkJICoKCQkgKiBXZSBzaG91bGQgZGVsZXRlIHRoZSBjb250cm9sbGVyIGF0IHRoaXMgcG9pbnQgaWYgaXQKCQkgKiBkb2Vzbid0IHJlc3BvbmQgc2luY2UgaWYgaXQncyBub3Qgb24gdGhlIHN5c3RlbSB0YWJsZQoJCSAqIGl0IGlzIHRlY2huaW5pY2FsbHkgbm90IHBhcnQgb2YgdGhlIEkyTyBzdWJzeXN0ZW0uLi4KCQkgKi8KCQlpZiAodW5saWtlbHkoaTJvX3N0YXR1c19nZXQoYykpKSB7CgkJCW9zbV9lcnIoIiVzOiBEZWxldGluZyBiL2MgY291bGQgbm90IGdldCBzdGF0dXMgd2hpbGUgIgoJCQkJImF0dGVtcHRpbmcgdG8gYnVpbGQgc3lzdGVtIHRhYmxlXG4iLCBjLT5uYW1lKTsKCQkJaTJvX2lvcF9yZW1vdmUoYyk7CgkJCWNvbnRpbnVlOwkvLyB0cnkgdGhlIG5leHQgb25lCgkJfQoKCQlzeXN0YWItPmlvcHNbY291bnRdLm9yZ19pZCA9IHNiLT5vcmdfaWQ7CgkJc3lzdGFiLT5pb3BzW2NvdW50XS5pb3BfaWQgPSBjLT51bml0ICsgMjsKCQlzeXN0YWItPmlvcHNbY291bnRdLnNlZ19udW0gPSAwOwoJCXN5c3RhYi0+aW9wc1tjb3VudF0uaTJvX3ZlcnNpb24gPSBzYi0+aTJvX3ZlcnNpb247CgkJc3lzdGFiLT5pb3BzW2NvdW50XS5pb3Bfc3RhdGUgPSBzYi0+aW9wX3N0YXRlOwoJCXN5c3RhYi0+aW9wc1tjb3VudF0ubXNnX3R5cGUgPSBzYi0+bXNnX3R5cGU7CgkJc3lzdGFiLT5pb3BzW2NvdW50XS5mcmFtZV9zaXplID0gc2ItPmluYm91bmRfZnJhbWVfc2l6ZTsKCQlzeXN0YWItPmlvcHNbY291bnRdLmxhc3RfY2hhbmdlZCA9IGNoYW5nZV9pbmQ7CgkJc3lzdGFiLT5pb3BzW2NvdW50XS5pb3BfY2FwYWJpbGl0aWVzID0gc2ItPmlvcF9jYXBhYmlsaXRpZXM7CgkJc3lzdGFiLT5pb3BzW2NvdW50XS5pbmJvdW5kX2xvdyA9CgkJICAgIGkyb19kbWFfbG93KGMtPmJhc2UucGh5cyArIEkyT19JTl9QT1JUKTsKCQlzeXN0YWItPmlvcHNbY291bnRdLmluYm91bmRfaGlnaCA9CgkJICAgIGkyb19kbWFfaGlnaChjLT5iYXNlLnBoeXMgKyBJMk9fSU5fUE9SVCk7CgoJCWNvdW50Kys7Cgl9CgoJc3lzdGFiLT5udW1fZW50cmllcyA9IGNvdW50OwoKCXJldHVybiAwOwp9OwoKLyoqCiAqCWkyb19wYXJzZV9ocnQgLSBQYXJzZSB0aGUgaGFyZHdhcmUgcmVzb3VyY2UgdGFibGUuCiAqCUBjOiBJMk8gY29udHJvbGxlcgogKgogKglXZSBkb24ndCBkbyBhbnl0aGluZyB3aXRoIGl0IGV4Y2VwdCBkdW1waW5nIGl0IChpbiBkZWJ1ZyBtb2RlKS4KICoKICoJUmV0dXJucyAwLgogKi8Kc3RhdGljIGludCBpMm9fcGFyc2VfaHJ0KHN0cnVjdCBpMm9fY29udHJvbGxlciAqYykKewoJaTJvX2R1bXBfaHJ0KGMpOwoJcmV0dXJuIDA7Cn07CgovKioKICoJaTJvX3N0YXR1c19nZXQgLSBHZXQgdGhlIHN0YXR1cyBibG9jayBmcm9tIHRoZSBJMk8gY29udHJvbGxlcgogKglAYzogSTJPIGNvbnRyb2xsZXIKICoKICoJSXNzdWUgYSBzdGF0dXMgcXVlcnkgb24gdGhlIGNvbnRyb2xsZXIuIFRoaXMgdXBkYXRlcyB0aGUgYXR0YWNoZWQKICoJc3RhdHVzIGJsb2NrLiBUaGUgc3RhdHVzIGJsb2NrIGNvdWxkIHRoZW4gYmUgYWNjZXNzZWQgdGhyb3VnaAogKgljLT5zdGF0dXNfYmxvY2suCiAqCiAqCVJldHVybnMgMCBvbiBzdWNlc3Mgb3IgbmVnYXRpdmUgZXJyb3IgY29kZSBvbiBmYWlsdXJlLgogKi8KaW50IGkyb19zdGF0dXNfZ2V0KHN0cnVjdCBpMm9fY29udHJvbGxlciAqYykKewoJc3RydWN0IGkyb19tZXNzYWdlIF9faW9tZW0gKm1zZzsKCXUzMiBtOwoJdm9sYXRpbGUgdTggKnN0YXR1c19ibG9jazsKCXVuc2lnbmVkIGxvbmcgdGltZW91dDsKCglzdGF0dXNfYmxvY2sgPSAodTggKikgYy0+c3RhdHVzX2Jsb2NrLnZpcnQ7CgltZW1zZXQoYy0+c3RhdHVzX2Jsb2NrLnZpcnQsIDAsIHNpemVvZihpMm9fc3RhdHVzX2Jsb2NrKSk7CgoJbSA9IGkyb19tc2dfZ2V0X3dhaXQoYywgJm1zZywgSTJPX1RJTUVPVVRfTUVTU0FHRV9HRVQpOwoJaWYgKG0gPT0gSTJPX1FVRVVFX0VNUFRZKQoJCXJldHVybiAtRVRJTUVET1VUOwoKCXdyaXRlbChOSU5FX1dPUkRfTVNHX1NJWkUgfCBTR0xfT0ZGU0VUXzAsICZtc2ctPnUuaGVhZFswXSk7Cgl3cml0ZWwoSTJPX0NNRF9TVEFUVVNfR0VUIDw8IDI0IHwgSE9TVF9USUQgPDwgMTIgfCBBREFQVEVSX1RJRCwKCSAgICAgICAmbXNnLT51LmhlYWRbMV0pOwoJd3JpdGVsKGkyb19leGVjX2RyaXZlci5jb250ZXh0LCAmbXNnLT51LnMuaWNudHh0KTsKCXdyaXRlbCgwLCAmbXNnLT51LnMudGNudHh0KTsJLy8gRklYTUU6IHVzZSByZXNvbmFibGUgdHJhbnNhY3Rpb24gY29udGV4dAoJd3JpdGVsKDAsICZtc2ctPmJvZHlbMF0pOwoJd3JpdGVsKDAsICZtc2ctPmJvZHlbMV0pOwoJd3JpdGVsKGkyb19kbWFfbG93KGMtPnN0YXR1c19ibG9jay5waHlzKSwgJm1zZy0+Ym9keVsyXSk7Cgl3cml0ZWwoaTJvX2RtYV9oaWdoKGMtPnN0YXR1c19ibG9jay5waHlzKSwgJm1zZy0+Ym9keVszXSk7Cgl3cml0ZWwoc2l6ZW9mKGkyb19zdGF0dXNfYmxvY2spLCAmbXNnLT5ib2R5WzRdKTsJLyogYWx3YXlzIDg4IGJ5dGVzICovCgoJaTJvX21zZ19wb3N0KGMsIG0pOwoKCS8qIFdhaXQgZm9yIGEgcmVwbHkgKi8KCXRpbWVvdXQgPSBqaWZmaWVzICsgSTJPX1RJTUVPVVRfU1RBVFVTX0dFVCAqIEhaOwoJd2hpbGUgKHN0YXR1c19ibG9ja1s4N10gIT0gMHhGRikgewoJCWlmICh0aW1lX2FmdGVyKGppZmZpZXMsIHRpbWVvdXQpKSB7CgkJCW9zbV9lcnIoIiVzOiBHZXQgc3RhdHVzIHRpbWVvdXQuXG4iLCBjLT5uYW1lKTsKCQkJcmV0dXJuIC1FVElNRURPVVQ7CgkJfQoKCQlzY2hlZHVsZV90aW1lb3V0X3VuaW50ZXJydXB0aWJsZSgxKTsKCX0KCiNpZmRlZiBERUJVRwoJaTJvX2RlYnVnX3N0YXRlKGMpOwojZW5kaWYKCglyZXR1cm4gMDsKfQoKLyoKICoJaTJvX2hydF9nZXQgLSBHZXQgdGhlIEhhcmR3YXJlIFJlc291cmNlIFRhYmxlIGZyb20gdGhlIEkyTyBjb250cm9sbGVyCiAqCUBjOiBJMk8gY29udHJvbGxlciBmcm9tIHdoaWNoIHRoZSBIUlQgc2hvdWxkIGJlIGZldGNoZWQKICoKICoJVGhlIEhSVCBjb250YWlucyBpbmZvcm1hdGlvbiBhYm91dCBwb3NzaWJsZSBoaWRkZW4gZGV2aWNlcyBidXQgaXMKICoJbW9zdGx5IHVzZWxlc3MgdG8gdXMuCiAqCiAqCVJldHVybnMgMCBvbiBzdWNjZXNzIG9yIG5lZ2F0aXZlciBlcnJvciBjb2RlIG9uIGZhaWx1cmUuCiAqLwpzdGF0aWMgaW50IGkyb19ocnRfZ2V0KHN0cnVjdCBpMm9fY29udHJvbGxlciAqYykKewoJaW50IHJjOwoJaW50IGk7CglpMm9faHJ0ICpocnQgPSBjLT5ocnQudmlydDsKCXUzMiBzaXplID0gc2l6ZW9mKGkyb19ocnQpOwoJc3RydWN0IGRldmljZSAqZGV2ID0gJmMtPnBkZXYtPmRldjsKCglmb3IgKGkgPSAwOyBpIDwgSTJPX0hSVF9HRVRfVFJJRVM7IGkrKykgewoJCXN0cnVjdCBpMm9fbWVzc2FnZSBfX2lvbWVtICptc2c7CgkJdTMyIG07CgoJCW0gPSBpMm9fbXNnX2dldF93YWl0KGMsICZtc2csIEkyT19USU1FT1VUX01FU1NBR0VfR0VUKTsKCQlpZiAobSA9PSBJMk9fUVVFVUVfRU1QVFkpCgkJCXJldHVybiAtRVRJTUVET1VUOwoKCQl3cml0ZWwoU0lYX1dPUkRfTVNHX1NJWkUgfCBTR0xfT0ZGU0VUXzQsICZtc2ctPnUuaGVhZFswXSk7CgkJd3JpdGVsKEkyT19DTURfSFJUX0dFVCA8PCAyNCB8IEhPU1RfVElEIDw8IDEyIHwgQURBUFRFUl9USUQsCgkJICAgICAgICZtc2ctPnUuaGVhZFsxXSk7CgkJd3JpdGVsKDB4ZDAwMDAwMDAgfCBjLT5ocnQubGVuLCAmbXNnLT5ib2R5WzBdKTsKCQl3cml0ZWwoYy0+aHJ0LnBoeXMsICZtc2ctPmJvZHlbMV0pOwoKCQlyYyA9IGkyb19tc2dfcG9zdF93YWl0X21lbShjLCBtLCAyMCwgJmMtPmhydCk7CgoJCWlmIChyYyA8IDApIHsKCQkJb3NtX2VycigiJXM6IFVuYWJsZSB0byBnZXQgSFJUIChzdGF0dXM9JSN4KVxuIiwgYy0+bmFtZSwKCQkJCS1yYyk7CgkJCXJldHVybiByYzsKCQl9CgoJCXNpemUgPSBocnQtPm51bV9lbnRyaWVzICogaHJ0LT5lbnRyeV9sZW4gPDwgMjsKCQlpZiAoc2l6ZSA+IGMtPmhydC5sZW4pIHsKCQkJaWYgKGkyb19kbWFfcmVhbGxvYyhkZXYsICZjLT5ocnQsIHNpemUsIEdGUF9LRVJORUwpKQoJCQkJcmV0dXJuIC1FTk9NRU07CgkJCWVsc2UKCQkJCWhydCA9IGMtPmhydC52aXJ0OwoJCX0gZWxzZQoJCQlyZXR1cm4gaTJvX3BhcnNlX2hydChjKTsKCX0KCglvc21fZXJyKCIlczogVW5hYmxlIHRvIGdldCBIUlQgYWZ0ZXIgJWQgdHJpZXMsIGdpdmluZyB1cFxuIiwgYy0+bmFtZSwKCQlJMk9fSFJUX0dFVF9UUklFUyk7CgoJcmV0dXJuIC1FQlVTWTsKfQoKLyoqCiAqCWkyb19pb3BfZnJlZSAtIEZyZWUgdGhlIGkyb19jb250cm9sbGVyIHN0cnVjdAogKglAYzogSTJPIGNvbnRyb2xsZXIgdG8gZnJlZQogKi8Kdm9pZCBpMm9faW9wX2ZyZWUoc3RydWN0IGkyb19jb250cm9sbGVyICpjKQp7CglrZnJlZShjKTsKfTsKCi8qKgogKglpMm9faW9wX3JlbGVhc2UgLSByZWxlYXNlIHRoZSBtZW1vcnkgZm9yIGEgSTJPIGNvbnRyb2xsZXIKICoJQGRldjogSTJPIGNvbnRyb2xsZXIgd2hpY2ggc2hvdWxkIGJlIHJlbGVhc2VkCiAqCiAqCVJlbGVhc2UgdGhlIGFsbG9jYXRlZCBtZW1vcnkuIFRoaXMgZnVuY3Rpb24gaXMgY2FsbGVkIGlmIHJlZmNvdW50IG9mCiAqCWRldmljZSByZWFjaGVzIDAgYXV0b21hdGljYWxseS4KICovCnN0YXRpYyB2b2lkIGkyb19pb3BfcmVsZWFzZShzdHJ1Y3QgZGV2aWNlICpkZXYpCnsKCXN0cnVjdCBpMm9fY29udHJvbGxlciAqYyA9IHRvX2kyb19jb250cm9sbGVyKGRldik7CgoJaTJvX2lvcF9mcmVlKGMpOwp9OwoKLyogSTJPIGNvbnRyb2xsZXIgY2xhc3MgKi8Kc3RhdGljIHN0cnVjdCBjbGFzcyAqaTJvX2NvbnRyb2xsZXJfY2xhc3M7CgovKioKICoJaTJvX2lvcF9hbGxvYyAtIEFsbG9jYXRlIGFuZCBpbml0aWFsaXplIGEgaTJvX2NvbnRyb2xsZXIgc3RydWN0CiAqCiAqCUFsbG9jYXRlIHRoZSBuZWNlc3NhcnkgbWVtb3J5IGZvciBhIGkyb19jb250cm9sbGVyIHN0cnVjdCBhbmQKICoJaW5pdGlhbGl6ZSB0aGUgbGlzdHMuCiAqCiAqCVJldHVybnMgYSBwb2ludGVyIHRvIHRoZSBJMk8gY29udHJvbGxlciBvciBhIG5lZ2F0aXZlIGVycm9yIGNvZGUgb24KICoJZmFpbHVyZS4KICovCnN0cnVjdCBpMm9fY29udHJvbGxlciAqaTJvX2lvcF9hbGxvYyh2b2lkKQp7CglzdGF0aWMgaW50IHVuaXQgPSAwOwkvKiAwIGFuZCAxIGFyZSBOVUxMIElPUCBhbmQgTG9jYWwgSG9zdCAqLwoJc3RydWN0IGkyb19jb250cm9sbGVyICpjOwoKCWMgPSBrbWFsbG9jKHNpemVvZigqYyksIEdGUF9LRVJORUwpOwoJaWYgKCFjKSB7CgkJb3NtX2VycigiaTJvOiBJbnN1ZmZpY2llbnQgbWVtb3J5IHRvIGFsbG9jYXRlIGEgSTJPIGNvbnRyb2xsZXIuIgoJCQkiXG4iKTsKCQlyZXR1cm4gRVJSX1BUUigtRU5PTUVNKTsKCX0KCW1lbXNldChjLCAwLCBzaXplb2YoKmMpKTsKCglJTklUX0xJU1RfSEVBRCgmYy0+ZGV2aWNlcyk7CglzcGluX2xvY2tfaW5pdCgmYy0+bG9jayk7Cglpbml0X01VVEVYKCZjLT5sY3RfbG9jayk7CgljLT51bml0ID0gdW5pdCsrOwoJc3ByaW50ZihjLT5uYW1lLCAiaW9wJWQiLCBjLT51bml0KTsKCglkZXZpY2VfaW5pdGlhbGl6ZSgmYy0+ZGV2aWNlKTsKCgljLT5kZXZpY2UucmVsZWFzZSA9ICZpMm9faW9wX3JlbGVhc2U7CgoJc25wcmludGYoYy0+ZGV2aWNlLmJ1c19pZCwgQlVTX0lEX1NJWkUsICJpb3AlZCIsIGMtPnVuaXQpOwoKI2lmIEJJVFNfUEVSX0xPTkcgPT0gNjQKCXNwaW5fbG9ja19pbml0KCZjLT5jb250ZXh0X2xpc3RfbG9jayk7CglhdG9taWNfc2V0KCZjLT5jb250ZXh0X2xpc3RfY291bnRlciwgMCk7CglJTklUX0xJU1RfSEVBRCgmYy0+Y29udGV4dF9saXN0KTsKI2VuZGlmCgoJcmV0dXJuIGM7Cn07CgovKioKICoJaTJvX2lvcF9hZGQgLSBJbml0aWFsaXplIHRoZSBJMk8gY29udHJvbGxlciBhbmQgYWRkIGhpbSB0byB0aGUgSTJPIGNvcmUKICoJQGM6IGNvbnRyb2xsZXIKICoKICoJSW5pdGlhbGl6ZSB0aGUgSTJPIGNvbnRyb2xsZXIgYW5kIGlmIG5vIGVycm9yIG9jY3VycyBhZGQgaGltIHRvIHRoZSBJMk8KICoJY29yZS4KICoKICoJUmV0dXJucyAwIG9uIHN1Y2Nlc3Mgb3IgbmVnYXRpdmUgZXJyb3IgY29kZSBvbiBmYWlsdXJlLgogKi8KaW50IGkyb19pb3BfYWRkKHN0cnVjdCBpMm9fY29udHJvbGxlciAqYykKewoJaW50IHJjOwoKCWlmICgocmMgPSBkZXZpY2VfYWRkKCZjLT5kZXZpY2UpKSkgewoJCW9zbV9lcnIoIiVzOiBjb3VsZCBub3QgYWRkIGNvbnRyb2xsZXJcbiIsIGMtPm5hbWUpOwoJCWdvdG8gaW9wX3Jlc2V0OwoJfQoKCWMtPmNsYXNzZGV2ID0gY2xhc3NfZGV2aWNlX2NyZWF0ZShpMm9fY29udHJvbGxlcl9jbGFzcywgTlVMTCwgTUtERVYoMCwwKSwKCQkJJmMtPmRldmljZSwgImlvcCVkIiwgYy0+dW5pdCk7CglpZiAoSVNfRVJSKGMtPmNsYXNzZGV2KSkgewoJCW9zbV9lcnIoIiVzOiBjb3VsZCBub3QgYWRkIGNvbnRyb2xsZXIgY2xhc3NcbiIsIGMtPm5hbWUpOwoJCWdvdG8gZGV2aWNlX2RlbDsKCX0KCglvc21faW5mbygiJXM6IEFjdGl2YXRpbmcgSTJPIGNvbnRyb2xsZXIuLi5cbiIsIGMtPm5hbWUpOwoJb3NtX2luZm8oIiVzOiBUaGlzIG1heSB0YWtlIGEgZmV3IG1pbnV0ZXMgaWYgdGhlcmUgYXJlIG1hbnkgZGV2aWNlc1xuIiwKCQkgYy0+bmFtZSk7CgoJaWYgKChyYyA9IGkyb19pb3BfYWN0aXZhdGUoYykpKSB7CgkJb3NtX2VycigiJXM6IGNvdWxkIG5vdCBhY3RpdmF0ZSBjb250cm9sbGVyXG4iLCBjLT5uYW1lKTsKCQlnb3RvIGNsYXNzX2RlbDsKCX0KCglvc21fZGVidWcoIiVzOiBidWlsZGluZyBzeXMgdGFibGUuLi5cbiIsIGMtPm5hbWUpOwoKCWlmICgocmMgPSBpMm9fc3lzdGFiX2J1aWxkKCkpKQoJCWdvdG8gY2xhc3NfZGVsOwoKCW9zbV9kZWJ1ZygiJXM6IG9ubGluZSBjb250cm9sbGVyLi4uXG4iLCBjLT5uYW1lKTsKCglpZiAoKHJjID0gaTJvX2lvcF9vbmxpbmUoYykpKQoJCWdvdG8gY2xhc3NfZGVsOwoKCW9zbV9kZWJ1ZygiJXM6IGdldHRpbmcgTENULi4uXG4iLCBjLT5uYW1lKTsKCglpZiAoKHJjID0gaTJvX2V4ZWNfbGN0X2dldChjKSkpCgkJZ290byBjbGFzc19kZWw7CgoJbGlzdF9hZGQoJmMtPmxpc3QsICZpMm9fY29udHJvbGxlcnMpOwoKCWkyb19kcml2ZXJfbm90aWZ5X2NvbnRyb2xsZXJfYWRkX2FsbChjKTsKCglvc21faW5mbygiJXM6IENvbnRyb2xsZXIgYWRkZWRcbiIsIGMtPm5hbWUpOwoKCXJldHVybiAwOwoKICAgICAgY2xhc3NfZGVsOgoJY2xhc3NfZGV2aWNlX3VucmVnaXN0ZXIoYy0+Y2xhc3NkZXYpOwoKICAgICAgZGV2aWNlX2RlbDoKCWRldmljZV9kZWwoJmMtPmRldmljZSk7CgogICAgICBpb3BfcmVzZXQ6CglpMm9faW9wX3Jlc2V0KGMpOwoKCXJldHVybiByYzsKfTsKCi8qKgogKglpMm9fZXZlbnRfcmVnaXN0ZXIgLSBUdXJuIG9uL29mZiBldmVudCBub3RpZmljYXRpb24gZm9yIGEgSTJPIGRldmljZQogKglAZGV2OiBJMk8gZGV2aWNlIHdoaWNoIHNob3VsZCByZWNlaXZlIHRoZSBldmVudCByZWdpc3RyYXRpb24gcmVxdWVzdAogKglAZHJ2OiBkcml2ZXIgd2hpY2ggd2FudCB0byBnZXQgbm90aWZpZWQKICoJQHRjbnR4dDogdHJhbnNhY3Rpb24gY29udGV4dCB0byB1c2Ugd2l0aCB0aGlzIG5vdGlmaWVyCiAqCUBldnRfbWFzazogbWFzayBvZiBldmVudHMKICoKICoJQ3JlYXRlIGFuZCBwb3N0cyBhbiBldmVudCByZWdpc3RyYXRpb24gbWVzc2FnZSB0byB0aGUgdGFzay4gTm8gcmVwbHkKICoJaXMgd2FpdGVkIGZvciwgb3IgZXhwZWN0ZWQuIElmIHlvdSBkbyBub3Qgd2FudCBmdXJ0aGVyIG5vdGlmaWNhdGlvbnMsCiAqCWNhbGwgdGhlIGkyb19ldmVudF9yZWdpc3RlciBhZ2FpbiB3aXRoIGEgZXZ0X21hc2sgb2YgMC4KICoKICoJUmV0dXJucyAwIG9uIHN1Y2Nlc3Mgb3IgLUVUSU1FRE9VVCBpZiBubyBtZXNzYWdlIGNvdWxkIGJlIGZldGNoZWQgZm9yCiAqCXNlbmRpbmcgdGhlIHJlcXVlc3QuCiAqLwppbnQgaTJvX2V2ZW50X3JlZ2lzdGVyKHN0cnVjdCBpMm9fZGV2aWNlICpkZXYsIHN0cnVjdCBpMm9fZHJpdmVyICpkcnYsCgkJICAgICAgIGludCB0Y250eHQsIHUzMiBldnRfbWFzaykKewoJc3RydWN0IGkyb19jb250cm9sbGVyICpjID0gZGV2LT5pb3A7CglzdHJ1Y3QgaTJvX21lc3NhZ2UgX19pb21lbSAqbXNnOwoJdTMyIG07CgoJbSA9IGkyb19tc2dfZ2V0X3dhaXQoYywgJm1zZywgSTJPX1RJTUVPVVRfTUVTU0FHRV9HRVQpOwoJaWYgKG0gPT0gSTJPX1FVRVVFX0VNUFRZKQoJCXJldHVybiAtRVRJTUVET1VUOwoKCXdyaXRlbChGSVZFX1dPUkRfTVNHX1NJWkUgfCBTR0xfT0ZGU0VUXzAsICZtc2ctPnUuaGVhZFswXSk7Cgl3cml0ZWwoSTJPX0NNRF9VVElMX0VWVF9SRUdJU1RFUiA8PCAyNCB8IEhPU1RfVElEIDw8IDEyIHwgZGV2LT5sY3RfZGF0YS4KCSAgICAgICB0aWQsICZtc2ctPnUuaGVhZFsxXSk7Cgl3cml0ZWwoZHJ2LT5jb250ZXh0LCAmbXNnLT51LnMuaWNudHh0KTsKCXdyaXRlbCh0Y250eHQsICZtc2ctPnUucy50Y250eHQpOwoJd3JpdGVsKGV2dF9tYXNrLCAmbXNnLT5ib2R5WzBdKTsKCglpMm9fbXNnX3Bvc3QoYywgbSk7CgoJcmV0dXJuIDA7Cn07CgovKioKICoJaTJvX2lvcF9pbml0IC0gSTJPIG1haW4gaW5pdGlhbGl6YXRpb24gZnVuY3Rpb24KICoKICoJSW5pdGlhbGl6ZSB0aGUgSTJPIGRyaXZlcnMgKE9TTSkgZnVuY3Rpb25zLCByZWdpc3RlciB0aGUgRXhlY3V0aXZlIE9TTSwKICoJaW5pdGlhbGl6ZSB0aGUgSTJPIFBDSSBwYXJ0IGFuZCBmaW5hbGx5IGluaXRpYWxpemUgSTJPIGRldmljZSBzdHVmZi4KICoKICoJUmV0dXJucyAwIG9uIHN1Y2Nlc3Mgb3IgbmVnYXRpdmUgZXJyb3IgY29kZSBvbiBmYWlsdXJlLgogKi8Kc3RhdGljIGludCBfX2luaXQgaTJvX2lvcF9pbml0KHZvaWQpCnsKCWludCByYyA9IDA7CgoJcHJpbnRrKEtFUk5fSU5GTyBPU01fREVTQ1JJUFRJT04gIiB2IiBPU01fVkVSU0lPTiAiXG4iKTsKCglpMm9fY29udHJvbGxlcl9jbGFzcyA9IGNsYXNzX2NyZWF0ZShUSElTX01PRFVMRSwgImkyb19jb250cm9sbGVyIik7CglpZiAoSVNfRVJSKGkyb19jb250cm9sbGVyX2NsYXNzKSkgewoJCW9zbV9lcnIoImNhbid0IHJlZ2lzdGVyIGNsYXNzIGkyb19jb250cm9sbGVyXG4iKTsKCQlnb3RvIGV4aXQ7Cgl9CgoJaWYgKChyYyA9IGkyb19kcml2ZXJfaW5pdCgpKSkKCQlnb3RvIGNsYXNzX2V4aXQ7CgoJaWYgKChyYyA9IGkyb19leGVjX2luaXQoKSkpCgkJZ290byBkcml2ZXJfZXhpdDsKCglpZiAoKHJjID0gaTJvX3BjaV9pbml0KCkpKQoJCWdvdG8gZXhlY19leGl0OwoKCXJldHVybiAwOwoKICAgICAgZXhlY19leGl0OgoJaTJvX2V4ZWNfZXhpdCgpOwoKICAgICAgZHJpdmVyX2V4aXQ6CglpMm9fZHJpdmVyX2V4aXQoKTsKCiAgICAgIGNsYXNzX2V4aXQ6CgljbGFzc19kZXN0cm95KGkyb19jb250cm9sbGVyX2NsYXNzKTsKCiAgICAgIGV4aXQ6CglyZXR1cm4gcmM7Cn0KCi8qKgogKglpMm9faW9wX2V4aXQgLSBJMk8gbWFpbiBleGl0IGZ1bmN0aW9uCiAqCiAqCVJlbW92ZXMgSTJPIGNvbnRyb2xsZXJzIGZyb20gUENJIHN1YnN5c3RlbSBhbmQgc2h1dCBkb3duIE9TTXMuCiAqLwpzdGF0aWMgdm9pZCBfX2V4aXQgaTJvX2lvcF9leGl0KHZvaWQpCnsKCWkyb19wY2lfZXhpdCgpOwoJaTJvX2V4ZWNfZXhpdCgpOwoJaTJvX2RyaXZlcl9leGl0KCk7CgljbGFzc19kZXN0cm95KGkyb19jb250cm9sbGVyX2NsYXNzKTsKfTsKCm1vZHVsZV9pbml0KGkyb19pb3BfaW5pdCk7Cm1vZHVsZV9leGl0KGkyb19pb3BfZXhpdCk7CgpNT0RVTEVfQVVUSE9SKCJSZWQgSGF0IFNvZnR3YXJlIik7Ck1PRFVMRV9MSUNFTlNFKCJHUEwiKTsKTU9EVUxFX0RFU0NSSVBUSU9OKE9TTV9ERVNDUklQVElPTik7Ck1PRFVMRV9WRVJTSU9OKE9TTV9WRVJTSU9OKTsKCiNpZiBCSVRTX1BFUl9MT05HID09IDY0CkVYUE9SVF9TWU1CT0woaTJvX2NudHh0X2xpc3RfYWRkKTsKRVhQT1JUX1NZTUJPTChpMm9fY250eHRfbGlzdF9nZXQpOwpFWFBPUlRfU1lNQk9MKGkyb19jbnR4dF9saXN0X3JlbW92ZSk7CkVYUE9SVF9TWU1CT0woaTJvX2NudHh0X2xpc3RfZ2V0X3B0cik7CiNlbmRpZgpFWFBPUlRfU1lNQk9MKGkyb19tc2dfZ2V0X3dhaXQpOwpFWFBPUlRfU1lNQk9MKGkyb19tc2dfbm9wKTsKRVhQT1JUX1NZTUJPTChpMm9fZmluZF9pb3ApOwpFWFBPUlRfU1lNQk9MKGkyb19pb3BfZmluZF9kZXZpY2UpOwpFWFBPUlRfU1lNQk9MKGkyb19ldmVudF9yZWdpc3Rlcik7CkVYUE9SVF9TWU1CT0woaTJvX3N0YXR1c19nZXQpOwpFWFBPUlRfU1lNQk9MKGkyb19jb250cm9sbGVycyk7Cg==