LyoKICoJRnVuY3Rpb25zIHRvIGhhbmRsZSBJMk8gY29udHJvbGxlcnMgYW5kIEkyTyBtZXNzYWdlIGhhbmRsaW5nCiAqCiAqCUNvcHlyaWdodCAoQykgMTk5OS0yMDAyCVJlZCBIYXQgU29mdHdhcmUKICoKICoJV3JpdHRlbiBieSBBbGFuIENveCwgQnVpbGRpbmcgTnVtYmVyIFRocmVlIEx0ZAogKgogKglUaGlzIHByb2dyYW0gaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKgl1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUKICoJRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIgdmVyc2lvbiAyIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91cgogKglvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKglBIGxvdCBvZiB0aGUgSTJPIG1lc3NhZ2Ugc2lkZSBjb2RlIGZyb20gdGhpcyBpcyB0YWtlbiBmcm9tIHRoZQogKglSZWQgQ3JlZWsgUkNQQ0k0NSBhZGFwdGVyIGRyaXZlciBieSBSZWQgQ3JlZWsgQ29tbXVuaWNhdGlvbnMKICoKICoJRml4ZXMvYWRkaXRpb25zOgogKgkJUGhpbGlwcCBSdW1wZgogKgkJSnVoYSBTaWV25G5lbiA8SnVoYS5TaWV2YW5lbkBjcy5IZWxzaW5raS5GST4KICoJCUF1dm8gSORra2luZW4gPEF1dm8uSGFra2luZW5AY3MuSGVsc2lua2kuRkk+CiAqCQlEZWVwYWsgU2F4ZW5hIDxkZWVwYWtAcGxleGl0eS5uZXQ+CiAqCQlCb2ppIFQgS2FubmFudGhhbmFtIDxib2ppLnQua2FubmFudGhhbmFtQGludGVsLmNvbT4KICoJCUFsYW4gQ294IDxhbGFuQHJlZGhhdC5jb20+OgogKgkJCVBvcnRlZCB0byBMaW51eCAyLjUuCiAqCQlNYXJrdXMgTGlkZWwgPE1hcmt1cy5MaWRlbEBzaGFkb3djb25uZWN0LmNvbT46CiAqCQkJTWlub3IgZml4ZXMgZm9yIDIuNi4KICovCgojaW5jbHVkZSA8bGludXgvbW9kdWxlLmg+CiNpbmNsdWRlIDxsaW51eC9pMm8uaD4KI2luY2x1ZGUgPGxpbnV4L2RlbGF5Lmg+CgojZGVmaW5lIE9TTV9WRVJTSU9OCSIkUmV2JCIKI2RlZmluZSBPU01fREVTQ1JJUFRJT04JIkkyTyBzdWJzeXN0ZW0iCgovKiBnbG9iYWwgSTJPIGNvbnRyb2xsZXIgbGlzdCAqLwpMSVNUX0hFQUQoaTJvX2NvbnRyb2xsZXJzKTsKCi8qCiAqIGdsb2JhbCBJMk8gU3lzdGVtIFRhYmxlLiBDb250YWlucyBpbmZvcm1hdGlvbiBhYm91dCBhbGwgdGhlIElPUHMgaW4gdGhlCiAqIHN5c3RlbS4gVXNlZCB0byBpbmZvcm0gSU9QcyBhYm91dCBlYWNoIG90aGVycyBleGlzdGVuY2UuCiAqLwpzdGF0aWMgc3RydWN0IGkyb19kbWEgaTJvX3N5c3RhYjsKCnN0YXRpYyBpbnQgaTJvX2hydF9nZXQoc3RydWN0IGkyb19jb250cm9sbGVyICpjKTsKCi8qIE1vZHVsZSBpbnRlcm5hbCBmdW5jdGlvbnMgZnJvbSBvdGhlciBzb3VyY2VzICovCmV4dGVybiBzdHJ1Y3QgaTJvX2RyaXZlciBpMm9fZXhlY19kcml2ZXI7CmV4dGVybiBpbnQgaTJvX2V4ZWNfbGN0X2dldChzdHJ1Y3QgaTJvX2NvbnRyb2xsZXIgKik7CmV4dGVybiB2b2lkIGkyb19kZXZpY2VfcmVtb3ZlKHN0cnVjdCBpMm9fZGV2aWNlICopOwoKZXh0ZXJuIGludCBfX2luaXQgaTJvX2RyaXZlcl9pbml0KHZvaWQpOwpleHRlcm4gdm9pZCBfX2V4aXQgaTJvX2RyaXZlcl9leGl0KHZvaWQpOwpleHRlcm4gaW50IF9faW5pdCBpMm9fZXhlY19pbml0KHZvaWQpOwpleHRlcm4gdm9pZCBfX2V4aXQgaTJvX2V4ZWNfZXhpdCh2b2lkKTsKZXh0ZXJuIGludCBfX2luaXQgaTJvX3BjaV9pbml0KHZvaWQpOwpleHRlcm4gdm9pZCBfX2V4aXQgaTJvX3BjaV9leGl0KHZvaWQpOwpleHRlcm4gaW50IGkyb19kZXZpY2VfaW5pdCh2b2lkKTsKZXh0ZXJuIHZvaWQgaTJvX2RldmljZV9leGl0KHZvaWQpOwoKLyoqCiAqCWkyb19tc2dfbm9wIC0gUmV0dXJucyBhIG1lc3NhZ2Ugd2hpY2ggaXMgbm90IHVzZWQKICoJQGM6IEkyTyBjb250cm9sbGVyIGZyb20gd2hpY2ggdGhlIG1lc3NhZ2Ugd2FzIGNyZWF0ZWQKICoJQG06IG1lc3NhZ2Ugd2hpY2ggc2hvdWxkIGJlIHJldHVybmVkCiAqCiAqCUlmIHlvdSBmZXRjaCBhIG1lc3NhZ2UgdmlhIGkyb19tc2dfZ2V0LCBhbmQgY2FuJ3QgdXNlIGl0LCB5b3UgbXVzdAogKglyZXR1cm4gdGhlIG1lc3NhZ2Ugd2l0aCB0aGlzIGZ1bmN0aW9uLiBPdGhlcndpc2UgdGhlIG1lc3NhZ2UgZnJhbWUKICoJaXMgbG9zdC4KICovCnZvaWQgaTJvX21zZ19ub3Aoc3RydWN0IGkyb19jb250cm9sbGVyICpjLCB1MzIgbSkKewoJc3RydWN0IGkyb19tZXNzYWdlIF9faW9tZW0gKm1zZyA9IGMtPmluX3F1ZXVlLnZpcnQgKyBtOwoKCXdyaXRlbChUSFJFRV9XT1JEX01TR19TSVpFIHwgU0dMX09GRlNFVF8wLCAmbXNnLT51LmhlYWRbMF0pOwoJd3JpdGVsKEkyT19DTURfVVRJTF9OT1AgPDwgMjQgfCBIT1NUX1RJRCA8PCAxMiB8IEFEQVBURVJfVElELAoJICAgICAgICZtc2ctPnUuaGVhZFsxXSk7Cgl3cml0ZWwoMCwgJm1zZy0+dS5oZWFkWzJdKTsKCXdyaXRlbCgwLCAmbXNnLT51LmhlYWRbM10pOwoJaTJvX21zZ19wb3N0KGMsIG0pOwp9OwoKLyoqCiAqCWkyb19tc2dfZ2V0X3dhaXQgLSBvYnRhaW4gYW4gSTJPIG1lc3NhZ2UgZnJvbSB0aGUgSU9QCiAqCUBjOiBJMk8gY29udHJvbGxlcgogKglAbXNnOiBwb2ludGVyIHRvIGEgSTJPIG1lc3NhZ2UgcG9pbnRlcgogKglAd2FpdDogaG93IGxvbmcgdG8gd2FpdCB1bnRpbCB0aW1lb3V0CiAqCiAqCVRoaXMgZnVuY3Rpb24gd2FpdHMgdXAgdG8gd2FpdCBzZWNvbmRzIGZvciBhIG1lc3NhZ2Ugc2xvdCB0byBiZQogKglhdmFpbGFibGUuCiAqCiAqCU9uIGEgc3VjY2VzcyB0aGUgbWVzc2FnZSBpcyByZXR1cm5lZCBhbmQgdGhlIHBvaW50ZXIgdG8gdGhlIG1lc3NhZ2UgaXMKICoJc2V0IGluIG1zZy4gVGhlIHJldHVybmVkIG1lc3NhZ2UgaXMgdGhlIHBoeXNpY2FsIHBhZ2UgZnJhbWUgb2Zmc2V0CiAqCWFkZHJlc3MgZnJvbSB0aGUgcmVhZCBwb3J0IChzZWUgdGhlIGkybyBzcGVjKS4gSWYgbm8gbWVzc2FnZSBpcwogKglhdmFpbGFibGUgcmV0dXJucyBJMk9fUVVFVUVfRU1QVFkgYW5kIG1zZyBpcyBsZWF2ZWQgdW50b3VjaGVkLgogKi8KdTMyIGkyb19tc2dfZ2V0X3dhaXQoc3RydWN0IGkyb19jb250cm9sbGVyICpjLCBzdHJ1Y3QgaTJvX21lc3NhZ2UgX19pb21lbSAqKm1zZywKCQkgICAgIGludCB3YWl0KQp7Cgl1bnNpZ25lZCBsb25nIHRpbWVvdXQgPSBqaWZmaWVzICsgd2FpdCAqIEhaOwoJdTMyIG07CgoJd2hpbGUgKChtID0gaTJvX21zZ19nZXQoYywgbXNnKSkgPT0gSTJPX1FVRVVFX0VNUFRZKSB7CgkJaWYgKHRpbWVfYWZ0ZXIoamlmZmllcywgdGltZW91dCkpIHsKCQkJcHJfZGVidWcoIiVzOiBUaW1lb3V0IHdhaXRpbmcgZm9yIG1lc3NhZ2UgZnJhbWUuXG4iLAoJCQkJIGMtPm5hbWUpOwoJCQlyZXR1cm4gSTJPX1FVRVVFX0VNUFRZOwoJCX0KCQlzZXRfY3VycmVudF9zdGF0ZShUQVNLX1VOSU5URVJSVVBUSUJMRSk7CgkJc2NoZWR1bGVfdGltZW91dCgxKTsKCX0KCglyZXR1cm4gbTsKfTsKCiNpZiBCSVRTX1BFUl9MT05HID09IDY0Ci8qKgogKiAgICAgIGkyb19jbnR4dF9saXN0X2FkZCAtIEFwcGVuZCBhIHBvaW50ZXIgdG8gY29udGV4dCBsaXN0IGFuZCByZXR1cm4gYSBpZAogKglAYzogY29udHJvbGxlciB0byB3aGljaCB0aGUgY29udGV4dCBsaXN0IGJlbG9uZwogKglAcHRyOiBwb2ludGVyIHRvIGFkZCB0byB0aGUgY29udGV4dCBsaXN0CiAqCiAqCUJlY2F1c2UgdGhlIGNvbnRleHQgZmllbGQgaW4gSTJPIGlzIG9ubHkgMzItYml0IGxhcmdlLCBvbiA2NC1iaXQgdGhlCiAqCXBvaW50ZXIgaXMgdG8gbGFyZ2UgdG8gZml0IGluIHRoZSBjb250ZXh0IGZpZWxkLiBUaGUgaTJvX2NudHh0X2xpc3QKICoJZnVuY3Rpb25zIHRoZXJlZm9yZSBtYXAgcG9pbnRlcnMgdG8gY29udGV4dCBmaWVsZHMuCiAqCiAqCVJldHVybnMgY29udGV4dCBpZCA+IDAgb24gc3VjY2VzcyBvciAwIG9uIGZhaWx1cmUuCiAqLwp1MzIgaTJvX2NudHh0X2xpc3RfYWRkKHN0cnVjdCBpMm9fY29udHJvbGxlciAqIGMsIHZvaWQgKnB0cikKewoJc3RydWN0IGkyb19jb250ZXh0X2xpc3RfZWxlbWVudCAqZW50cnk7Cgl1bnNpZ25lZCBsb25nIGZsYWdzOwoKCWlmICghcHRyKQoJCXByaW50ayhLRVJOX0VSUiAiJXM6IGNvdWxkbid0IGFkZCBOVUxMIHBvaW50ZXIgdG8gY29udGV4dCBsaXN0ISIKCQkgICAgICAgIlxuIiwgYy0+bmFtZSk7CgoJZW50cnkgPSBrbWFsbG9jKHNpemVvZigqZW50cnkpLCBHRlBfQVRPTUlDKTsKCWlmICghZW50cnkpIHsKCQlwcmludGsoS0VSTl9FUlIgIiVzOiBDb3VsZCBub3QgYWxsb2NhdGUgbWVtb3J5IGZvciBjb250ZXh0ICIKCQkgICAgICAgImxpc3QgZWxlbWVudFxuIiwgYy0+bmFtZSk7CgkJcmV0dXJuIDA7Cgl9CgoJZW50cnktPnB0ciA9IHB0cjsKCWVudHJ5LT50aW1lc3RhbXAgPSBqaWZmaWVzOwoJSU5JVF9MSVNUX0hFQUQoJmVudHJ5LT5saXN0KTsKCglzcGluX2xvY2tfaXJxc2F2ZSgmYy0+Y29udGV4dF9saXN0X2xvY2ssIGZsYWdzKTsKCglpZiAodW5saWtlbHkoYXRvbWljX2luY19hbmRfdGVzdCgmYy0+Y29udGV4dF9saXN0X2NvdW50ZXIpKSkKCQlhdG9taWNfaW5jKCZjLT5jb250ZXh0X2xpc3RfY291bnRlcik7CgoJZW50cnktPmNvbnRleHQgPSBhdG9taWNfcmVhZCgmYy0+Y29udGV4dF9saXN0X2NvdW50ZXIpOwoKCWxpc3RfYWRkKCZlbnRyeS0+bGlzdCwgJmMtPmNvbnRleHRfbGlzdCk7CgoJc3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmYy0+Y29udGV4dF9saXN0X2xvY2ssIGZsYWdzKTsKCglwcl9kZWJ1ZygiJXM6IEFkZCBjb250ZXh0IHRvIGxpc3QgJXAgLT4gJWRcbiIsIGMtPm5hbWUsIHB0ciwgY29udGV4dCk7CgoJcmV0dXJuIGVudHJ5LT5jb250ZXh0Owp9OwoKLyoqCiAqICAgICAgaTJvX2NudHh0X2xpc3RfcmVtb3ZlIC0gUmVtb3ZlIGEgcG9pbnRlciBmcm9tIHRoZSBjb250ZXh0IGxpc3QKICoJQGM6IGNvbnRyb2xsZXIgdG8gd2hpY2ggdGhlIGNvbnRleHQgbGlzdCBiZWxvbmcKICoJQHB0cjogcG9pbnRlciB3aGljaCBzaG91bGQgYmUgcmVtb3ZlZCBmcm9tIHRoZSBjb250ZXh0IGxpc3QKICoKICoJUmVtb3ZlcyBhIHByZXZpb3VzbHkgYWRkZWQgcG9pbnRlciBmcm9tIHRoZSBjb250ZXh0IGxpc3QgYW5kIHJldHVybnMKICoJdGhlIG1hdGNoaW5nIGNvbnRleHQgaWQuCiAqCiAqCVJldHVybnMgY29udGV4dCBpZCBvbiBzdWNjZXMgb3IgMCBvbiBmYWlsdXJlLgogKi8KdTMyIGkyb19jbnR4dF9saXN0X3JlbW92ZShzdHJ1Y3QgaTJvX2NvbnRyb2xsZXIgKiBjLCB2b2lkICpwdHIpCnsKCXN0cnVjdCBpMm9fY29udGV4dF9saXN0X2VsZW1lbnQgKmVudHJ5OwoJdTMyIGNvbnRleHQgPSAwOwoJdW5zaWduZWQgbG9uZyBmbGFnczsKCglzcGluX2xvY2tfaXJxc2F2ZSgmYy0+Y29udGV4dF9saXN0X2xvY2ssIGZsYWdzKTsKCWxpc3RfZm9yX2VhY2hfZW50cnkoZW50cnksICZjLT5jb250ZXh0X2xpc3QsIGxpc3QpCgkgICAgaWYgKGVudHJ5LT5wdHIgPT0gcHRyKSB7CgkJbGlzdF9kZWwoJmVudHJ5LT5saXN0KTsKCQljb250ZXh0ID0gZW50cnktPmNvbnRleHQ7CgkJa2ZyZWUoZW50cnkpOwoJCWJyZWFrOwoJfQoJc3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmYy0+Y29udGV4dF9saXN0X2xvY2ssIGZsYWdzKTsKCglpZiAoIWNvbnRleHQpCgkJcHJpbnRrKEtFUk5fV0FSTklORyAiJXM6IENvdWxkIG5vdCByZW1vdmUgbm9uZXhpc3RlbnQgcHRyICIKCQkgICAgICAgIiVwXG4iLCBjLT5uYW1lLCBwdHIpOwoKCXByX2RlYnVnKCIlczogcmVtb3ZlIHB0ciBmcm9tIGNvbnRleHQgbGlzdCAlZCAtPiAlcFxuIiwgYy0+bmFtZSwKCQkgY29udGV4dCwgcHRyKTsKCglyZXR1cm4gY29udGV4dDsKfTsKCi8qKgogKiAgICAgIGkyb19jbnR4dF9saXN0X2dldCAtIEdldCBhIHBvaW50ZXIgZnJvbSB0aGUgY29udGV4dCBsaXN0IGFuZCByZW1vdmUgaXQKICoJQGM6IGNvbnRyb2xsZXIgdG8gd2hpY2ggdGhlIGNvbnRleHQgbGlzdCBiZWxvbmcKICoJQGNvbnRleHQ6IGNvbnRleHQgaWQgdG8gd2hpY2ggdGhlIHBvaW50ZXIgYmVsb25nCiAqCiAqCVJldHVybnMgcG9pbnRlciB0byB0aGUgbWF0Y2hpbmcgY29udGV4dCBpZCBvbiBzdWNjZXNzIG9yIE5VTEwgb24KICoJZmFpbHVyZS4KICovCnZvaWQgKmkyb19jbnR4dF9saXN0X2dldChzdHJ1Y3QgaTJvX2NvbnRyb2xsZXIgKmMsIHUzMiBjb250ZXh0KQp7CglzdHJ1Y3QgaTJvX2NvbnRleHRfbGlzdF9lbGVtZW50ICplbnRyeTsKCXVuc2lnbmVkIGxvbmcgZmxhZ3M7Cgl2b2lkICpwdHIgPSBOVUxMOwoKCXNwaW5fbG9ja19pcnFzYXZlKCZjLT5jb250ZXh0X2xpc3RfbG9jaywgZmxhZ3MpOwoJbGlzdF9mb3JfZWFjaF9lbnRyeShlbnRyeSwgJmMtPmNvbnRleHRfbGlzdCwgbGlzdCkKCSAgICBpZiAoZW50cnktPmNvbnRleHQgPT0gY29udGV4dCkgewoJCWxpc3RfZGVsKCZlbnRyeS0+bGlzdCk7CgkJcHRyID0gZW50cnktPnB0cjsKCQlrZnJlZShlbnRyeSk7CgkJYnJlYWs7Cgl9CglzcGluX3VubG9ja19pcnFyZXN0b3JlKCZjLT5jb250ZXh0X2xpc3RfbG9jaywgZmxhZ3MpOwoKCWlmICghcHRyKQoJCXByaW50ayhLRVJOX1dBUk5JTkcgIiVzOiBjb250ZXh0IGlkICVkIG5vdCBmb3VuZFxuIiwgYy0+bmFtZSwKCQkgICAgICAgY29udGV4dCk7CgoJcHJfZGVidWcoIiVzOiBnZXQgcHRyIGZyb20gY29udGV4dCBsaXN0ICVkIC0+ICVwXG4iLCBjLT5uYW1lLCBjb250ZXh0LAoJCSBwdHIpOwoKCXJldHVybiBwdHI7Cn07CgovKioKICogICAgICBpMm9fY250eHRfbGlzdF9nZXRfcHRyIC0gR2V0IGEgY29udGV4dCBpZCBmcm9tIHRoZSBjb250ZXh0IGxpc3QKICoJQGM6IGNvbnRyb2xsZXIgdG8gd2hpY2ggdGhlIGNvbnRleHQgbGlzdCBiZWxvbmcKICoJQHB0cjogcG9pbnRlciB0byB3aGljaCB0aGUgY29udGV4dCBpZCBzaG91bGQgYmUgZmV0Y2hlZAogKgogKglSZXR1cm5zIGNvbnRleHQgaWQgd2hpY2ggbWF0Y2hlcyB0byB0aGUgcG9pbnRlciBvbiBzdWNjZXMgb3IgMCBvbgogKglmYWlsdXJlLgogKi8KdTMyIGkyb19jbnR4dF9saXN0X2dldF9wdHIoc3RydWN0IGkyb19jb250cm9sbGVyICogYywgdm9pZCAqcHRyKQp7CglzdHJ1Y3QgaTJvX2NvbnRleHRfbGlzdF9lbGVtZW50ICplbnRyeTsKCXUzMiBjb250ZXh0ID0gMDsKCXVuc2lnbmVkIGxvbmcgZmxhZ3M7CgoJc3Bpbl9sb2NrX2lycXNhdmUoJmMtPmNvbnRleHRfbGlzdF9sb2NrLCBmbGFncyk7CglsaXN0X2Zvcl9lYWNoX2VudHJ5KGVudHJ5LCAmYy0+Y29udGV4dF9saXN0LCBsaXN0KQoJICAgIGlmIChlbnRyeS0+cHRyID09IHB0cikgewoJCWNvbnRleHQgPSBlbnRyeS0+Y29udGV4dDsKCQlicmVhazsKCX0KCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJmMtPmNvbnRleHRfbGlzdF9sb2NrLCBmbGFncyk7CgoJaWYgKCFjb250ZXh0KQoJCXByaW50ayhLRVJOX1dBUk5JTkcgIiVzOiBDb3VsZCBub3QgZmluZCBub25leGlzdGVudCBwdHIgIgoJCSAgICAgICAiJXBcbiIsIGMtPm5hbWUsIHB0cik7CgoJcHJfZGVidWcoIiVzOiBnZXQgY29udGV4dCBpZCBmcm9tIGNvbnRleHQgbGlzdCAlcCAtPiAlZFxuIiwgYy0+bmFtZSwKCQkgcHRyLCBjb250ZXh0KTsKCglyZXR1cm4gY29udGV4dDsKfTsKI2VuZGlmCgovKioKICoJaTJvX2lvcF9maW5kIC0gRmluZCBhbiBJMk8gY29udHJvbGxlciBieSBpZAogKglAdW5pdDogdW5pdCBudW1iZXIgb2YgdGhlIEkyTyBjb250cm9sbGVyIHRvIHNlYXJjaCBmb3IKICoKICoJTG9va3VwIHRoZSBJMk8gY29udHJvbGxlciBvbiB0aGUgY29udHJvbGxlciBsaXN0LgogKgogKglSZXR1cm5zIHBvaW50ZXIgdG8gdGhlIEkyTyBjb250cm9sbGVyIG9uIHN1Y2Nlc3Mgb3IgTlVMTCBpZiBub3QgZm91bmQuCiAqLwpzdHJ1Y3QgaTJvX2NvbnRyb2xsZXIgKmkyb19maW5kX2lvcChpbnQgdW5pdCkKewoJc3RydWN0IGkyb19jb250cm9sbGVyICpjOwoKCWxpc3RfZm9yX2VhY2hfZW50cnkoYywgJmkyb19jb250cm9sbGVycywgbGlzdCkgewoJCWlmIChjLT51bml0ID09IHVuaXQpCgkJCXJldHVybiBjOwoJfQoKCXJldHVybiBOVUxMOwp9OwoKLyoqCiAqCWkyb19pb3BfZmluZF9kZXZpY2UgLSBGaW5kIGEgSTJPIGRldmljZSBvbiBhbiBJMk8gY29udHJvbGxlcgogKglAYzogSTJPIGNvbnRyb2xsZXIgd2hlcmUgdGhlIEkyTyBkZXZpY2UgaGFuZ3Mgb24KICoJQHRpZDogVElEIG9mIHRoZSBJMk8gZGV2aWNlIHRvIHNlYXJjaCBmb3IKICoKICoJU2VhcmNoZXMgdGhlIGRldmljZXMgb2YgdGhlIEkyTyBjb250cm9sbGVyIGZvciBhIGRldmljZSB3aXRoIFRJRCB0aWQgYW5kCiAqCXJldHVybnMgaXQuCiAqCiAqCVJldHVybnMgYSBwb2ludGVyIHRvIHRoZSBJMk8gZGV2aWNlIGlmIGZvdW5kLCBvdGhlcndpc2UgTlVMTC4KICovCnN0cnVjdCBpMm9fZGV2aWNlICppMm9faW9wX2ZpbmRfZGV2aWNlKHN0cnVjdCBpMm9fY29udHJvbGxlciAqYywgdTE2IHRpZCkKewoJc3RydWN0IGkyb19kZXZpY2UgKmRldjsKCglsaXN0X2Zvcl9lYWNoX2VudHJ5KGRldiwgJmMtPmRldmljZXMsIGxpc3QpCgkgICAgaWYgKGRldi0+bGN0X2RhdGEudGlkID09IHRpZCkKCQlyZXR1cm4gZGV2OwoKCXJldHVybiBOVUxMOwp9OwoKLyoqCiAqCWkyb19xdWllc2NlX2NvbnRyb2xsZXIgLSBxdWllc2NlIGNvbnRyb2xsZXIKICoJQGM6IGNvbnRyb2xsZXIKICoKICoJUXVpZXNjZSBhbiBJT1AuIENhdXNlcyBJT1AgdG8gbWFrZSBleHRlcm5hbCBvcGVyYXRpb24gcXVpZXNjZW50CiAqCShpMm8gJ1JFQURZJyBzdGF0ZSkuIEludGVybmFsIG9wZXJhdGlvbiBvZiB0aGUgSU9QIGNvbnRpbnVlcyBub3JtYWxseS4KICoKICoJUmV0dXJucyAwIG9uIHN1Y2Nlc3Mgb3IgbmVnYXRpdmUgZXJyb3IgY29kZSBvbiBmYWlsdXJlLgogKi8Kc3RhdGljIGludCBpMm9faW9wX3F1aWVzY2Uoc3RydWN0IGkyb19jb250cm9sbGVyICpjKQp7CglzdHJ1Y3QgaTJvX21lc3NhZ2UgX19pb21lbSAqbXNnOwoJdTMyIG07CglpMm9fc3RhdHVzX2Jsb2NrICpzYiA9IGMtPnN0YXR1c19ibG9jay52aXJ0OwoJaW50IHJjOwoKCWkyb19zdGF0dXNfZ2V0KGMpOwoKCS8qIFN5c1F1aWVzY2UgZGlzY2FyZGVkIGlmIElPUCBub3QgaW4gUkVBRFkgb3IgT1BFUkFUSU9OQUwgc3RhdGUgKi8KCWlmICgoc2ItPmlvcF9zdGF0ZSAhPSBBREFQVEVSX1NUQVRFX1JFQURZKSAmJgoJICAgIChzYi0+aW9wX3N0YXRlICE9IEFEQVBURVJfU1RBVEVfT1BFUkFUSU9OQUwpKQoJCXJldHVybiAwOwoKCW0gPSBpMm9fbXNnX2dldF93YWl0KGMsICZtc2csIEkyT19USU1FT1VUX01FU1NBR0VfR0VUKTsKCWlmIChtID09IEkyT19RVUVVRV9FTVBUWSkKCQlyZXR1cm4gLUVUSU1FRE9VVDsKCgl3cml0ZWwoRk9VUl9XT1JEX01TR19TSVpFIHwgU0dMX09GRlNFVF8wLCAmbXNnLT51LmhlYWRbMF0pOwoJd3JpdGVsKEkyT19DTURfU1lTX1FVSUVTQ0UgPDwgMjQgfCBIT1NUX1RJRCA8PCAxMiB8IEFEQVBURVJfVElELAoJICAgICAgICZtc2ctPnUuaGVhZFsxXSk7CgoJLyogTG9uZyB0aW1lb3V0IG5lZWRlZCBmb3IgcXVpZXNjZSBpZiBsb3RzIG9mIGRldmljZXMgKi8KCWlmICgocmMgPSBpMm9fbXNnX3Bvc3Rfd2FpdChjLCBtLCAyNDApKSkKCQlwcmludGsoS0VSTl9JTkZPICIlczogVW5hYmxlIHRvIHF1aWVzY2UgKHN0YXR1cz0lI3gpLlxuIiwKCQkgICAgICAgYy0+bmFtZSwgLXJjKTsKCWVsc2UKCQlwcl9kZWJ1ZygiJXM6IFF1aWVzY2VkLlxuIiwgYy0+bmFtZSk7CgoJaTJvX3N0YXR1c19nZXQoYyk7CS8vIEVudGVyZWQgUkVBRFkgc3RhdGUKCglyZXR1cm4gcmM7Cn07CgovKioKICoJaTJvX2lvcF9lbmFibGUgLSBtb3ZlIGNvbnRyb2xsZXIgZnJvbSByZWFkeSB0byBPUEVSQVRJT05BTAogKglAYzogSTJPIGNvbnRyb2xsZXIKICoKICoJRW5hYmxlIElPUC4gVGhpcyBhbGxvd3MgdGhlIElPUCB0byByZXN1bWUgZXh0ZXJuYWwgb3BlcmF0aW9ucyBhbmQKICoJcmV2ZXJzZXMgdGhlIGVmZmVjdCBvZiBhIHF1aWVzY2UuIFJldHVybnMgemVybyBvciBhbiBlcnJvciBjb2RlIGlmCiAqCWFuIGVycm9yIG9jY3Vycy4KICovCnN0YXRpYyBpbnQgaTJvX2lvcF9lbmFibGUoc3RydWN0IGkyb19jb250cm9sbGVyICpjKQp7CglzdHJ1Y3QgaTJvX21lc3NhZ2UgX19pb21lbSAqbXNnOwoJdTMyIG07CglpMm9fc3RhdHVzX2Jsb2NrICpzYiA9IGMtPnN0YXR1c19ibG9jay52aXJ0OwoJaW50IHJjOwoKCWkyb19zdGF0dXNfZ2V0KGMpOwoKCS8qIEVuYWJsZSBvbmx5IGFsbG93ZWQgb24gUkVBRFkgc3RhdGUgKi8KCWlmIChzYi0+aW9wX3N0YXRlICE9IEFEQVBURVJfU1RBVEVfUkVBRFkpCgkJcmV0dXJuIC1FSU5WQUw7CgoJbSA9IGkyb19tc2dfZ2V0X3dhaXQoYywgJm1zZywgSTJPX1RJTUVPVVRfTUVTU0FHRV9HRVQpOwoJaWYgKG0gPT0gSTJPX1FVRVVFX0VNUFRZKQoJCXJldHVybiAtRVRJTUVET1VUOwoKCXdyaXRlbChGT1VSX1dPUkRfTVNHX1NJWkUgfCBTR0xfT0ZGU0VUXzAsICZtc2ctPnUuaGVhZFswXSk7Cgl3cml0ZWwoSTJPX0NNRF9TWVNfRU5BQkxFIDw8IDI0IHwgSE9TVF9USUQgPDwgMTIgfCBBREFQVEVSX1RJRCwKCSAgICAgICAmbXNnLT51LmhlYWRbMV0pOwoKCS8qIEhvdyBsb25nIG9mIGEgdGltZW91dCBkbyB3ZSBuZWVkPyAqLwoJaWYgKChyYyA9IGkyb19tc2dfcG9zdF93YWl0KGMsIG0sIDI0MCkpKQoJCXByaW50ayhLRVJOX0VSUiAiJXM6IENvdWxkIG5vdCBlbmFibGUgKHN0YXR1cz0lI3gpLlxuIiwKCQkgICAgICAgYy0+bmFtZSwgLXJjKTsKCWVsc2UKCQlwcl9kZWJ1ZygiJXM6IEVuYWJsZWQuXG4iLCBjLT5uYW1lKTsKCglpMm9fc3RhdHVzX2dldChjKTsJLy8gZW50ZXJlZCBPUEVSQVRJT05BTCBzdGF0ZQoKCXJldHVybiByYzsKfTsKCi8qKgogKglpMm9faW9wX3F1aWVzY2VfYWxsIC0gUXVpZXNjZSBhbGwgSTJPIGNvbnRyb2xsZXJzIG9uIHRoZSBzeXN0ZW0KICoKICoJUXVpZXNjZSBhbGwgSTJPIGNvbnRyb2xsZXJzIHdoaWNoIGFyZSBjb25uZWN0ZWQgdG8gdGhlIHN5c3RlbS4KICovCnN0YXRpYyBpbmxpbmUgdm9pZCBpMm9faW9wX3F1aWVzY2VfYWxsKHZvaWQpCnsKCXN0cnVjdCBpMm9fY29udHJvbGxlciAqYywgKnRtcDsKCglsaXN0X2Zvcl9lYWNoX2VudHJ5X3NhZmUoYywgdG1wLCAmaTJvX2NvbnRyb2xsZXJzLCBsaXN0KSB7CgkJaWYgKCFjLT5ub19xdWllc2NlKQoJCQlpMm9faW9wX3F1aWVzY2UoYyk7Cgl9Cn07CgovKioKICoJaTJvX2lvcF9lbmFibGVfYWxsIC0gRW5hYmxlcyBhbGwgY29udHJvbGxlcnMgb24gdGhlIHN5c3RlbQogKgogKglFbmFibGVzIGFsbCBJMk8gY29udHJvbGxlcnMgd2hpY2ggYXJlIGNvbm5lY3RlZCB0byB0aGUgc3lzdGVtLgogKi8Kc3RhdGljIGlubGluZSB2b2lkIGkyb19pb3BfZW5hYmxlX2FsbCh2b2lkKQp7CglzdHJ1Y3QgaTJvX2NvbnRyb2xsZXIgKmMsICp0bXA7CgoJbGlzdF9mb3JfZWFjaF9lbnRyeV9zYWZlKGMsIHRtcCwgJmkyb19jb250cm9sbGVycywgbGlzdCkKCSAgICBpMm9faW9wX2VuYWJsZShjKTsKfTsKCi8qKgogKglpMm9fY2xlYXJfY29udHJvbGxlciAtIEJyaW5nIEkyTyBjb250cm9sbGVyIGludG8gSE9MRCBzdGF0ZQogKglAYzogY29udHJvbGxlcgogKgogKglDbGVhciBhbiBJT1AgdG8gSE9MRCBzdGF0ZSwgaWUuIHRlcm1pbmF0ZSBleHRlcm5hbCBvcGVyYXRpb25zLCBjbGVhciBhbGwKICoJaW5wdXQgcXVldWVzIGFuZCBwcmVwYXJlIGZvciBhIHN5c3RlbSByZXN0YXJ0LiBJT1AncyBpbnRlcm5hbCBvcGVyYXRpb24KICoJY29udGludWVzIG5vcm1hbGx5IGFuZCB0aGUgb3V0Ym91bmQgcXVldWUgaXMgYWxpdmUuIFRoZSBJT1AgaXMgbm90CiAqCWV4cGVjdGVkIHRvIHJlYnVpbGQgaXRzIExDVC4KICoKICoJUmV0dXJucyAwIG9uIHN1Y2Nlc3Mgb3IgbmVnYXRpdmUgZXJyb3IgY29kZSBvbiBmYWlsdXJlLgogKi8Kc3RhdGljIGludCBpMm9faW9wX2NsZWFyKHN0cnVjdCBpMm9fY29udHJvbGxlciAqYykKewoJc3RydWN0IGkyb19tZXNzYWdlIF9faW9tZW0gKm1zZzsKCXUzMiBtOwoJaW50IHJjOwoKCW0gPSBpMm9fbXNnX2dldF93YWl0KGMsICZtc2csIEkyT19USU1FT1VUX01FU1NBR0VfR0VUKTsKCWlmIChtID09IEkyT19RVUVVRV9FTVBUWSkKCQlyZXR1cm4gLUVUSU1FRE9VVDsKCgkvKiBRdWllc2NlIGFsbCBJT1BzIGZpcnN0ICovCglpMm9faW9wX3F1aWVzY2VfYWxsKCk7CgoJd3JpdGVsKEZPVVJfV09SRF9NU0dfU0laRSB8IFNHTF9PRkZTRVRfMCwgJm1zZy0+dS5oZWFkWzBdKTsKCXdyaXRlbChJMk9fQ01EX0FEQVBURVJfQ0xFQVIgPDwgMjQgfCBIT1NUX1RJRCA8PCAxMiB8IEFEQVBURVJfVElELAoJICAgICAgICZtc2ctPnUuaGVhZFsxXSk7CgoJaWYgKChyYyA9IGkyb19tc2dfcG9zdF93YWl0KGMsIG0sIDMwKSkpCgkJcHJpbnRrKEtFUk5fSU5GTyAiJXM6IFVuYWJsZSB0byBjbGVhciAoc3RhdHVzPSUjeCkuXG4iLAoJCSAgICAgICBjLT5uYW1lLCAtcmMpOwoJZWxzZQoJCXByX2RlYnVnKCIlczogQ2xlYXJlZC5cbiIsIGMtPm5hbWUpOwoKCS8qIEVuYWJsZSBhbGwgSU9QcyAqLwoJaTJvX2lvcF9lbmFibGVfYWxsKCk7CgoJaTJvX3N0YXR1c19nZXQoYyk7CgoJcmV0dXJuIHJjOwp9CgovKioKICoJaTJvX2lvcF9yZXNldCAtIHJlc2V0IGFuIEkyTyBjb250cm9sbGVyCiAqCUBjOiBjb250cm9sbGVyIHRvIHJlc2V0CiAqCiAqCVJlc2V0IHRoZSBJT1AgaW50byBJTklUIHN0YXRlIGFuZCB3YWl0IHVudGlsIElPUCBnZXRzIGludG8gUkVTRVQgc3RhdGUuCiAqCVRlcm1pbmF0ZSBhbGwgZXh0ZXJuYWwgb3BlcmF0aW9ucywgY2xlYXIgSU9QJ3MgaW5ib3VuZCBhbmQgb3V0Ym91bmQKICoJcXVldWVzLCB0ZXJtaW5hdGUgYWxsIERETXMsIGFuZCByZWxvYWQgdGhlIElPUCdzIG9wZXJhdGluZyBlbnZpcm9ubWVudAogKglhbmQgYWxsIGxvY2FsIERETXMuIFRoZSBJT1AgcmVidWlsZHMgaXRzIExDVC4KICovCnN0YXRpYyBpbnQgaTJvX2lvcF9yZXNldChzdHJ1Y3QgaTJvX2NvbnRyb2xsZXIgKmMpCnsKCXU4ICpzdGF0dXMgPSBjLT5zdGF0dXMudmlydDsKCXN0cnVjdCBpMm9fbWVzc2FnZSBfX2lvbWVtICptc2c7Cgl1MzIgbTsKCXVuc2lnbmVkIGxvbmcgdGltZW91dDsKCWkyb19zdGF0dXNfYmxvY2sgKnNiID0gYy0+c3RhdHVzX2Jsb2NrLnZpcnQ7CglpbnQgcmMgPSAwOwoKCXByX2RlYnVnKCIlczogUmVzZXR0aW5nIGNvbnRyb2xsZXJcbiIsIGMtPm5hbWUpOwoKCW0gPSBpMm9fbXNnX2dldF93YWl0KGMsICZtc2csIEkyT19USU1FT1VUX01FU1NBR0VfR0VUKTsKCWlmIChtID09IEkyT19RVUVVRV9FTVBUWSkKCQlyZXR1cm4gLUVUSU1FRE9VVDsKCgltZW1zZXQoc3RhdHVzLCAwLCA4KTsKCgkvKiBRdWllc2NlIGFsbCBJT1BzIGZpcnN0ICovCglpMm9faW9wX3F1aWVzY2VfYWxsKCk7CgoJd3JpdGVsKEVJR0hUX1dPUkRfTVNHX1NJWkUgfCBTR0xfT0ZGU0VUXzAsICZtc2ctPnUuaGVhZFswXSk7Cgl3cml0ZWwoSTJPX0NNRF9BREFQVEVSX1JFU0VUIDw8IDI0IHwgSE9TVF9USUQgPDwgMTIgfCBBREFQVEVSX1RJRCwKCSAgICAgICAmbXNnLT51LmhlYWRbMV0pOwoJd3JpdGVsKGkyb19leGVjX2RyaXZlci5jb250ZXh0LCAmbXNnLT51LnMuaWNudHh0KTsKCXdyaXRlbCgwLCAmbXNnLT51LnMudGNudHh0KTsJLy9GSVhNRTogdXNlIHJlYXNvbmFibGUgdHJhbnNhY3Rpb24gY29udGV4dAoJd3JpdGVsKDAsICZtc2ctPmJvZHlbMF0pOwoJd3JpdGVsKDAsICZtc2ctPmJvZHlbMV0pOwoJd3JpdGVsKGkyb19wdHJfbG93KCh2b2lkICopYy0+c3RhdHVzLnBoeXMpLCAmbXNnLT5ib2R5WzJdKTsKCXdyaXRlbChpMm9fcHRyX2hpZ2goKHZvaWQgKiljLT5zdGF0dXMucGh5cyksICZtc2ctPmJvZHlbM10pOwoKCWkyb19tc2dfcG9zdChjLCBtKTsKCgkvKiBXYWl0IGZvciBhIHJlcGx5ICovCgl0aW1lb3V0ID0gamlmZmllcyArIEkyT19USU1FT1VUX1JFU0VUICogSFo7Cgl3aGlsZSAoISpzdGF0dXMpIHsKCQlpZiAodGltZV9hZnRlcihqaWZmaWVzLCB0aW1lb3V0KSkgewoJCQlwcmludGsoS0VSTl9FUlIgIiVzOiBJT1AgcmVzZXQgdGltZW91dC5cbiIsIGMtPm5hbWUpOwoJCQlyYyA9IC1FVElNRURPVVQ7CgkJCWdvdG8gZXhpdDsKCQl9CgoJCS8qIFByb21pc2UgYnVnICovCgkJaWYgKHN0YXR1c1sxXSB8fCBzdGF0dXNbNF0pIHsKCQkJKnN0YXR1cyA9IDA7CgkJCWJyZWFrOwoJCX0KCgkJc2V0X2N1cnJlbnRfc3RhdGUoVEFTS19VTklOVEVSUlVQVElCTEUpOwoJCXNjaGVkdWxlX3RpbWVvdXQoMSk7CgoJCXJtYigpOwoJfQoKCWlmICgqc3RhdHVzID09IEkyT19DTURfSU5fUFJPR1JFU1MpIHsKCQkvKgoJCSAqIE9uY2UgdGhlIHJlc2V0IGlzIHNlbnQsIHRoZSBJT1AgZ29lcyBpbnRvIHRoZSBJTklUIHN0YXRlCgkJICogd2hpY2ggaXMgaW5kZXRlcm1pbmF0ZS4gIFdlIG5lZWQgdG8gd2FpdCB1bnRpbCB0aGUgSU9QCgkJICogaGFzIHJlYm9vdGVkIGJlZm9yZSB3ZSBjYW4gbGV0IHRoZSBzeXN0ZW0gdGFsayB0bwoJCSAqIGl0LiBXZSByZWFkIHRoZSBpbmJvdW5kIEZyZWVfTGlzdCB1bnRpbCBhIG1lc3NhZ2UgaXMKCQkgKiBhdmFpbGFibGUuIElmIHdlIGNhbid0IHJlYWQgb25lIGluIHRoZSBnaXZlbiBhbW1vdW50IG9mCgkJICogdGltZSwgd2UgYXNzdW1lIHRoZSBJT1AgY291bGQgbm90IHJlYm9vdCBwcm9wZXJseS4KCQkgKi8KCQlwcl9kZWJ1ZygiJXM6IFJlc2V0IGluIHByb2dyZXNzLCB3YWl0aW5nIGZvciByZWJvb3QuLi5cbiIsCgkJCSBjLT5uYW1lKTsKCgkJbSA9IGkyb19tc2dfZ2V0X3dhaXQoYywgJm1zZywgSTJPX1RJTUVPVVRfUkVTRVQpOwoJCXdoaWxlIChtID09IEkyT19RVUVVRV9FTVBUWSkgewoJCQlpZiAodGltZV9hZnRlcihqaWZmaWVzLCB0aW1lb3V0KSkgewoJCQkJcHJpbnRrKEtFUk5fRVJSICIlczogSU9QIHJlc2V0IHRpbWVvdXQuXG4iLAoJCQkJICAgICAgIGMtPm5hbWUpOwoJCQkJcmMgPSAtRVRJTUVET1VUOwoJCQkJZ290byBleGl0OwoJCQl9CgkJCXNldF9jdXJyZW50X3N0YXRlKFRBU0tfVU5JTlRFUlJVUFRJQkxFKTsKCQkJc2NoZWR1bGVfdGltZW91dCgxKTsKCgkJCW0gPSBpMm9fbXNnX2dldF93YWl0KGMsICZtc2csIEkyT19USU1FT1VUX1JFU0VUKTsKCQl9CgkJaTJvX21zZ19ub3AoYywgbSk7Cgl9CgoJLyogZnJvbSBoZXJlIGFsbCBxdWllc2NlIGNvbW1hbmRzIGFyZSBzYWZlICovCgljLT5ub19xdWllc2NlID0gMDsKCgkvKiBJZiBJb3BSZXNldCB3YXMgcmVqZWN0ZWQgb3IgZGlkbid0IHBlcmZvcm0gcmVzZXQsIHRyeSBJb3BDbGVhciAqLwoJaTJvX3N0YXR1c19nZXQoYyk7CglpZiAoKnN0YXR1cyA9PSBJMk9fQ01EX1JFSkVDVEVEIHx8IHNiLT5pb3Bfc3RhdGUgIT0gQURBUFRFUl9TVEFURV9SRVNFVCkgewoJCXByaW50ayhLRVJOX1dBUk5JTkcgIiVzOiBSZXNldCByZWplY3RlZCwgdHJ5aW5nIHRvIGNsZWFyXG4iLAoJCSAgICAgICBjLT5uYW1lKTsKCQlpMm9faW9wX2NsZWFyKGMpOwoJfSBlbHNlCgkJcHJfZGVidWcoIiVzOiBSZXNldCBjb21wbGV0ZWQuXG4iLCBjLT5uYW1lKTsKCiAgICAgIGV4aXQ6CgkvKiBFbmFibGUgYWxsIElPUHMgKi8KCWkyb19pb3BfZW5hYmxlX2FsbCgpOwoKCXJldHVybiByYzsKfTsKCi8qKgogKglpMm9faW9wX2luaXRfb3V0Ym91bmRfcXVldWUgLSBzZXR1cCB0aGUgb3V0Ym91bmQgbWVzc2FnZSBxdWV1ZQogKglAYzogSTJPIGNvbnRyb2xsZXIKICoKICoJQ2xlYXIgYW5kIChyZSlpbml0aWFsaXplIElPUCdzIG91dGJvdW5kIHF1ZXVlIGFuZCBwb3N0IHRoZSBtZXNzYWdlCiAqCWZyYW1lcyB0byB0aGUgSU9QLgogKgogKglSZXR1cm5zIDAgb24gc3VjY2VzcyBvciBhIG5lZ2F0aXZlIGVycm5vIGNvZGUgb24gZmFpbHVyZS4KICovCnN0YXRpYyBpbnQgaTJvX2lvcF9pbml0X291dGJvdW5kX3F1ZXVlKHN0cnVjdCBpMm9fY29udHJvbGxlciAqYykKewoJdTggKnN0YXR1cyA9IGMtPnN0YXR1cy52aXJ0OwoJdTMyIG07CglzdHJ1Y3QgaTJvX21lc3NhZ2UgX19pb21lbSAqbXNnOwoJdWxvbmcgdGltZW91dDsKCWludCBpOwoKCXByX2RlYnVnKCIlczogSW5pdGlhbGl6aW5nIE91dGJvdW5kIFF1ZXVlLi4uXG4iLCBjLT5uYW1lKTsKCgltZW1zZXQoc3RhdHVzLCAwLCA0KTsKCgltID0gaTJvX21zZ19nZXRfd2FpdChjLCAmbXNnLCBJMk9fVElNRU9VVF9NRVNTQUdFX0dFVCk7CglpZiAobSA9PSBJMk9fUVVFVUVfRU1QVFkpCgkJcmV0dXJuIC1FVElNRURPVVQ7CgoJd3JpdGVsKEVJR0hUX1dPUkRfTVNHX1NJWkUgfCBUUkxfT0ZGU0VUXzYsICZtc2ctPnUuaGVhZFswXSk7Cgl3cml0ZWwoSTJPX0NNRF9PVVRCT1VORF9JTklUIDw8IDI0IHwgSE9TVF9USUQgPDwgMTIgfCBBREFQVEVSX1RJRCwKCSAgICAgICAmbXNnLT51LmhlYWRbMV0pOwoJd3JpdGVsKGkyb19leGVjX2RyaXZlci5jb250ZXh0LCAmbXNnLT51LnMuaWNudHh0KTsKCXdyaXRlbCgweDAxMDYsICZtc2ctPnUucy50Y250eHQpOwkvKiBGSVhNRTogd2h5IDB4MDEwNiwgbWF5YmUgaW4KCQkJCQkJICAgU3BlYz8gKi8KCXdyaXRlbChQQUdFX1NJWkUsICZtc2ctPmJvZHlbMF0pOwoJd3JpdGVsKE1TR19GUkFNRV9TSVpFIDw8IDE2IHwgMHg4MCwgJm1zZy0+Ym9keVsxXSk7CS8qIE91dGJvdW5kIG1zZyBmcmFtZQoJCQkJCQkJCSAgIHNpemUgaW4gd29yZHMgYW5kIEluaXRjb2RlICovCgl3cml0ZWwoMHhkMDAwMDAwNCwgJm1zZy0+Ym9keVsyXSk7Cgl3cml0ZWwoaTJvX3B0cl9sb3coKHZvaWQgKiljLT5zdGF0dXMucGh5cyksICZtc2ctPmJvZHlbM10pOwoJd3JpdGVsKGkyb19wdHJfaGlnaCgodm9pZCAqKWMtPnN0YXR1cy5waHlzKSwgJm1zZy0+Ym9keVs0XSk7CgoJaTJvX21zZ19wb3N0KGMsIG0pOwoKCXRpbWVvdXQgPSBqaWZmaWVzICsgSTJPX1RJTUVPVVRfSU5JVF9PVVRCT1VORF9RVUVVRSAqIEhaOwoJd2hpbGUgKCpzdGF0dXMgPD0gSTJPX0NNRF9JTl9QUk9HUkVTUykgewoJCWlmICh0aW1lX2FmdGVyKGppZmZpZXMsIHRpbWVvdXQpKSB7CgkJCXByaW50ayhLRVJOX1dBUk5JTkcgIiVzOiBUaW1lb3V0IEluaXRpYWxpemluZ1xuIiwKCQkJICAgICAgIGMtPm5hbWUpOwoJCQlyZXR1cm4gLUVUSU1FRE9VVDsKCQl9CgkJc2V0X2N1cnJlbnRfc3RhdGUoVEFTS19VTklOVEVSUlVQVElCTEUpOwoJCXNjaGVkdWxlX3RpbWVvdXQoMSk7CgoJCXJtYigpOwoJfQoKCW0gPSBjLT5vdXRfcXVldWUucGh5czsKCgkvKiBQb3N0IGZyYW1lcyAqLwoJZm9yIChpID0gMDsgaSA8IE5NQlJfTVNHX0ZSQU1FUzsgaSsrKSB7CgkJaTJvX2ZsdXNoX3JlcGx5KGMsIG0pOwoJCXVkZWxheSgxKTsJLyogUHJvbWlzZSAqLwoJCW0gKz0gTVNHX0ZSQU1FX1NJWkUgKiA0OwoJfQoKCXJldHVybiAwOwp9CgovKioKICoJaTJvX2lvcF9zZW5kX25vcCAtIHNlbmQgYSBjb3JlIE5PUCBtZXNzYWdlCiAqCUBjOiBjb250cm9sbGVyCiAqCiAqCVNlbmQgYSBuby1vcGVyYXRpb24gbWVzc2FnZSB3aXRoIGEgcmVwbHkgc2V0IHRvIGNhdXNlIG5vCiAqCWFjdGlvbiBlaXRoZXIuIE5lZWRlZCBmb3IgYnJpbmdpbmcgdXAgcHJvbWlzZSBjb250cm9sbGVycy4KICovCnN0YXRpYyBpbnQgaTJvX2lvcF9zZW5kX25vcChzdHJ1Y3QgaTJvX2NvbnRyb2xsZXIgKmMpCnsKCXN0cnVjdCBpMm9fbWVzc2FnZSBfX2lvbWVtICptc2c7Cgl1MzIgbSA9IGkyb19tc2dfZ2V0X3dhaXQoYywgJm1zZywgSFopOwoJaWYgKG0gPT0gSTJPX1FVRVVFX0VNUFRZKQoJCXJldHVybiAtRVRJTUVET1VUOwoJaTJvX21zZ19ub3AoYywgbSk7CglyZXR1cm4gMDsKfQoKLyoqCiAqCWkyb19pb3BfYWN0aXZhdGUgLSBCcmluZyBjb250cm9sbGVyIHVwIHRvIEhPTEQKICoJQGM6IGNvbnRyb2xsZXIKICoKICoJVGhpcyBmdW5jdGlvbiBicmluZ3MgYW4gSTJPIGNvbnRyb2xsZXIgaW50byBIT0xEIHN0YXRlLiBUaGUgYWRhcHRlcgogKglpcyByZXNldCBpZiBuZWNlc3NhcnkgYW5kIHRoZW4gdGhlIHF1ZXVlcyBhbmQgcmVzb3VyY2UgdGFibGUgYXJlIHJlYWQuCiAqCiAqCVJldHVybnMgMCBvbiBzdWNjZXNzIG9yIG5lZ2F0aXZlIGVycm9yIGNvZGUgb24gZmFpbHVyZS4KICovCnN0YXRpYyBpbnQgaTJvX2lvcF9hY3RpdmF0ZShzdHJ1Y3QgaTJvX2NvbnRyb2xsZXIgKmMpCnsKCXN0cnVjdCBwY2lfZGV2ICppOTYwID0gTlVMTDsKCWkyb19zdGF0dXNfYmxvY2sgKnNiID0gYy0+c3RhdHVzX2Jsb2NrLnZpcnQ7CglpbnQgcmM7CgoJaWYgKGMtPnByb21pc2UpIHsKCQkvKiBCZWF0IHVwIHRoZSBoYXJkd2FyZSBmaXJzdCBvZiBhbGwgKi8KCQlpOTYwID0KCQkgICAgcGNpX2ZpbmRfc2xvdChjLT5wZGV2LT5idXMtPm51bWJlciwKCQkJCSAgUENJX0RFVkZOKFBDSV9TTE9UKGMtPnBkZXYtPmRldmZuKSwgMCkpOwoJCWlmIChpOTYwKQoJCQlwY2lfd3JpdGVfY29uZmlnX3dvcmQoaTk2MCwgMHg0MiwgMCk7CgoJCS8qIEZvbGxvdyB0aGlzIHNlcXVlbmNlIHByZWNpc2VseSBvciB0aGUgY29udHJvbGxlcgoJCSAgIGNlYXNlcyB0byBwZXJmb3JtIHVzZWZ1bCBmdW5jdGlvbnMgdW50aWwgcmVib290ICovCgkJaWYgKChyYyA9IGkyb19pb3Bfc2VuZF9ub3AoYykpKQoJCQlyZXR1cm4gcmM7CgoJCWlmICgocmMgPSBpMm9faW9wX3Jlc2V0KGMpKSkKCQkJcmV0dXJuIHJjOwoJfQoKCS8qIEluIElOSVQgc3RhdGUsIFdhaXQgSW5ib3VuZCBRIHRvIGluaXRpYWxpemUgKGluIGkyb19zdGF0dXNfZ2V0KSAqLwoJLyogSW4gUkVBRFkgc3RhdGUsIEdldCBzdGF0dXMgKi8KCglyYyA9IGkyb19zdGF0dXNfZ2V0KGMpOwoJaWYgKHJjKSB7CgkJcHJpbnRrKEtFUk5fSU5GTyAiJXM6IFVuYWJsZSB0byBvYnRhaW4gc3RhdHVzLCAiCgkJICAgICAgICJhdHRlbXB0aW5nIGEgcmVzZXQuXG4iLCBjLT5uYW1lKTsKCQlpZiAoaTJvX2lvcF9yZXNldChjKSkKCQkJcmV0dXJuIHJjOwoJfQoKCWlmIChzYi0+aTJvX3ZlcnNpb24gPiBJMk9WRVIxNSkgewoJCXByaW50ayhLRVJOX0VSUiAiJXM6IE5vdCBydW5uaW5nIHZlcnNpb24gMS41IG9mIHRoZSBJMk8gIgoJCSAgICAgICAiU3BlY2lmaWNhdGlvbi5cbiIsIGMtPm5hbWUpOwoJCXJldHVybiAtRU5PREVWOwoJfQoKCXN3aXRjaCAoc2ItPmlvcF9zdGF0ZSkgewoJY2FzZSBBREFQVEVSX1NUQVRFX0ZBVUxURUQ6CgkJcHJpbnRrKEtFUk5fQ1JJVCAiJXM6IGhhcmR3YXJlIGZhdWx0XG4iLCBjLT5uYW1lKTsKCQlyZXR1cm4gLUVOT0RFVjsKCgljYXNlIEFEQVBURVJfU1RBVEVfUkVBRFk6CgljYXNlIEFEQVBURVJfU1RBVEVfT1BFUkFUSU9OQUw6CgljYXNlIEFEQVBURVJfU1RBVEVfSE9MRDoKCWNhc2UgQURBUFRFUl9TVEFURV9GQUlMRUQ6CgkJcHJfZGVidWcoIiVzOiBhbHJlYWR5IHJ1bm5pbmcsIHRyeWluZyB0byByZXNldC4uLlxuIiwgYy0+bmFtZSk7CgkJaWYgKGkyb19pb3BfcmVzZXQoYykpCgkJCXJldHVybiAtRU5PREVWOwoJfQoKCXJjID0gaTJvX2lvcF9pbml0X291dGJvdW5kX3F1ZXVlKGMpOwoJaWYgKHJjKQoJCXJldHVybiByYzsKCglpZiAoYy0+cHJvbWlzZSkgewoJCWlmICgocmMgPSBpMm9faW9wX3NlbmRfbm9wKGMpKSkKCQkJcmV0dXJuIHJjOwoKCQlpZiAoKHJjID0gaTJvX3N0YXR1c19nZXQoYykpKQoJCQlyZXR1cm4gcmM7CgoJCWlmIChpOTYwKQoJCQlwY2lfd3JpdGVfY29uZmlnX3dvcmQoaTk2MCwgMHg0MiwgMHgzRkYpOwoJfQoKCS8qIEluIEhPTEQgc3RhdGUgKi8KCglyYyA9IGkyb19ocnRfZ2V0KGMpOwoKCXJldHVybiByYzsKfTsKCi8qKgogKglpMm9faW9wX3N5c3RhYl9zZXQgLSBTZXQgdGhlIEkyTyBTeXN0ZW0gVGFibGUgb2YgdGhlIHNwZWNpZmllZCBJT1AKICoJQGM6IEkyTyBjb250cm9sbGVyIHRvIHdoaWNoIHRoZSBzeXN0ZW0gdGFibGUgc2hvdWxkIGJlIHNlbmQKICoKICoJQmVmb3JlIHRoZSBzeXN0YWIgY291bGQgYmUgc2V0IGkyb19zeXN0YWJfYnVpbGQoKSBtdXN0IGJlIGNhbGxlZC4KICoKICoJUmV0dXJucyAwIG9uIHN1Y2Nlc3Mgb3IgbmVnYXRpdmUgZXJyb3IgY29kZSBvbiBmYWlsdXJlLgogKi8Kc3RhdGljIGludCBpMm9faW9wX3N5c3RhYl9zZXQoc3RydWN0IGkyb19jb250cm9sbGVyICpjKQp7CglzdHJ1Y3QgaTJvX21lc3NhZ2UgX19pb21lbSAqbXNnOwoJdTMyIG07CglpMm9fc3RhdHVzX2Jsb2NrICpzYiA9IGMtPnN0YXR1c19ibG9jay52aXJ0OwoJc3RydWN0IGRldmljZSAqZGV2ID0gJmMtPnBkZXYtPmRldjsKCXN0cnVjdCByZXNvdXJjZSAqcm9vdDsKCWludCByYzsKCglpZiAoc2ItPmN1cnJlbnRfbWVtX3NpemUgPCBzYi0+ZGVzaXJlZF9tZW1fc2l6ZSkgewoJCXN0cnVjdCByZXNvdXJjZSAqcmVzID0gJmMtPm1lbV9yZXNvdXJjZTsKCQlyZXMtPm5hbWUgPSBjLT5wZGV2LT5idXMtPm5hbWU7CgkJcmVzLT5mbGFncyA9IElPUkVTT1VSQ0VfTUVNOwoJCXJlcy0+c3RhcnQgPSAwOwoJCXJlcy0+ZW5kID0gMDsKCQlwcmludGsoS0VSTl9JTkZPICIlczogcmVxdWlyZXMgcHJpdmF0ZSBtZW1vcnkgcmVzb3VyY2VzLlxuIiwKCQkgICAgICAgYy0+bmFtZSk7CgkJcm9vdCA9IHBjaV9maW5kX3BhcmVudF9yZXNvdXJjZShjLT5wZGV2LCByZXMpOwoJCWlmIChyb290ID09IE5VTEwpCgkJCXByaW50ayhLRVJOX1dBUk5JTkcgIiVzOiBDYW4ndCBmaW5kIHBhcmVudCByZXNvdXJjZSFcbiIsCgkJCSAgICAgICBjLT5uYW1lKTsKCQlpZiAocm9vdCAmJiBhbGxvY2F0ZV9yZXNvdXJjZShyb290LCByZXMsIHNiLT5kZXNpcmVkX21lbV9zaXplLCBzYi0+ZGVzaXJlZF9tZW1fc2l6ZSwgc2ItPmRlc2lyZWRfbWVtX3NpemUsIDEgPDwgMjAsCS8qIFVuc3BlY2lmaWVkLCBzbyB1c2UgMU1iIGFuZCBwbGF5IHNhZmUgKi8KCQkJCQkgICAgICBOVUxMLCBOVUxMKSA+PSAwKSB7CgkJCWMtPm1lbV9hbGxvYyA9IDE7CgkJCXNiLT5jdXJyZW50X21lbV9zaXplID0gMSArIHJlcy0+ZW5kIC0gcmVzLT5zdGFydDsKCQkJc2ItPmN1cnJlbnRfbWVtX2Jhc2UgPSByZXMtPnN0YXJ0OwoJCQlwcmludGsoS0VSTl9JTkZPICIlczogYWxsb2NhdGVkICVsZCBieXRlcyBvZiBQQ0kgbWVtb3J5IgoJCQkgICAgICAgIiBhdCAweCUwOGxYLlxuIiwgYy0+bmFtZSwKCQkJICAgICAgIDEgKyByZXMtPmVuZCAtIHJlcy0+c3RhcnQsIHJlcy0+c3RhcnQpOwoJCX0KCX0KCglpZiAoc2ItPmN1cnJlbnRfaW9fc2l6ZSA8IHNiLT5kZXNpcmVkX2lvX3NpemUpIHsKCQlzdHJ1Y3QgcmVzb3VyY2UgKnJlcyA9ICZjLT5pb19yZXNvdXJjZTsKCQlyZXMtPm5hbWUgPSBjLT5wZGV2LT5idXMtPm5hbWU7CgkJcmVzLT5mbGFncyA9IElPUkVTT1VSQ0VfSU87CgkJcmVzLT5zdGFydCA9IDA7CgkJcmVzLT5lbmQgPSAwOwoJCXByaW50ayhLRVJOX0lORk8gIiVzOiByZXF1aXJlcyBwcml2YXRlIG1lbW9yeSByZXNvdXJjZXMuXG4iLAoJCSAgICAgICBjLT5uYW1lKTsKCQlyb290ID0gcGNpX2ZpbmRfcGFyZW50X3Jlc291cmNlKGMtPnBkZXYsIHJlcyk7CgkJaWYgKHJvb3QgPT0gTlVMTCkKCQkJcHJpbnRrKEtFUk5fV0FSTklORyAiJXM6IENhbid0IGZpbmQgcGFyZW50IHJlc291cmNlIVxuIiwKCQkJICAgICAgIGMtPm5hbWUpOwoJCWlmIChyb290ICYmIGFsbG9jYXRlX3Jlc291cmNlKHJvb3QsIHJlcywgc2ItPmRlc2lyZWRfaW9fc2l6ZSwgc2ItPmRlc2lyZWRfaW9fc2l6ZSwgc2ItPmRlc2lyZWRfaW9fc2l6ZSwgMSA8PCAyMCwJLyogVW5zcGVjaWZpZWQsIHNvIHVzZSAxTWIgYW5kIHBsYXkgc2FmZSAqLwoJCQkJCSAgICAgIE5VTEwsIE5VTEwpID49IDApIHsKCQkJYy0+aW9fYWxsb2MgPSAxOwoJCQlzYi0+Y3VycmVudF9pb19zaXplID0gMSArIHJlcy0+ZW5kIC0gcmVzLT5zdGFydDsKCQkJc2ItPmN1cnJlbnRfbWVtX2Jhc2UgPSByZXMtPnN0YXJ0OwoJCQlwcmludGsoS0VSTl9JTkZPICIlczogYWxsb2NhdGVkICVsZCBieXRlcyBvZiBQQ0kgSS9PIGF0IgoJCQkgICAgICAgIiAweCUwOGxYLlxuIiwgYy0+bmFtZSwKCQkJICAgICAgIDEgKyByZXMtPmVuZCAtIHJlcy0+c3RhcnQsIHJlcy0+c3RhcnQpOwoJCX0KCX0KCgltID0gaTJvX21zZ19nZXRfd2FpdChjLCAmbXNnLCBJMk9fVElNRU9VVF9NRVNTQUdFX0dFVCk7CglpZiAobSA9PSBJMk9fUVVFVUVfRU1QVFkpCgkJcmV0dXJuIC1FVElNRURPVVQ7CgoJaTJvX3N5c3RhYi5waHlzID0gZG1hX21hcF9zaW5nbGUoZGV2LCBpMm9fc3lzdGFiLnZpcnQsIGkyb19zeXN0YWIubGVuLAoJCQkJCSBQQ0lfRE1BX1RPREVWSUNFKTsKCWlmICghaTJvX3N5c3RhYi5waHlzKSB7CgkJaTJvX21zZ19ub3AoYywgbSk7CgkJcmV0dXJuIC1FTk9NRU07Cgl9CgoJd3JpdGVsKEkyT19NRVNTQUdFX1NJWkUoMTIpIHwgU0dMX09GRlNFVF82LCAmbXNnLT51LmhlYWRbMF0pOwoJd3JpdGVsKEkyT19DTURfU1lTX1RBQl9TRVQgPDwgMjQgfCBIT1NUX1RJRCA8PCAxMiB8IEFEQVBURVJfVElELAoJICAgICAgICZtc2ctPnUuaGVhZFsxXSk7CgoJLyoKCSAqIFByb3ZpZGUgdGhyZWUgU0dMLWVsZW1lbnRzOgoJICogU3lzdGVtIHRhYmxlIChTeXNUYWIpLCBQcml2YXRlIG1lbW9yeSBzcGFjZSBkZWNsYXJhdGlvbiBhbmQKCSAqIFByaXZhdGUgaS9vIHNwYWNlIGRlY2xhcmF0aW9uCgkgKgoJICogRklYTUU6IGlzIHRoaXMgc3RpbGwgdHJ1ZT8KCSAqIE5hc3R5IG9uZSBoZXJlLiBXZSBjYW4ndCB1c2UgZG1hX2FsbG9jX2NvaGVyZW50IHRvIHNlbmQgdGhlCgkgKiBzYW1lIHRhYmxlIHRvIGV2ZXJ5b25lLiBXZSBoYXZlIHRvIGdvIHJlbWFwIGl0IGZvciB0aGVtIGFsbAoJICovCgoJd3JpdGVsKGMtPnVuaXQgKyAyLCAmbXNnLT5ib2R5WzBdKTsKCXdyaXRlbCgwLCAmbXNnLT5ib2R5WzFdKTsKCXdyaXRlbCgweDU0MDAwMDAwIHwgaTJvX3N5c3RhYi5sZW4sICZtc2ctPmJvZHlbMl0pOwoJd3JpdGVsKGkyb19zeXN0YWIucGh5cywgJm1zZy0+Ym9keVszXSk7Cgl3cml0ZWwoMHg1NDAwMDAwMCB8IHNiLT5jdXJyZW50X21lbV9zaXplLCAmbXNnLT5ib2R5WzRdKTsKCXdyaXRlbChzYi0+Y3VycmVudF9tZW1fYmFzZSwgJm1zZy0+Ym9keVs1XSk7Cgl3cml0ZWwoMHhkNDAwMDAwMCB8IHNiLT5jdXJyZW50X2lvX3NpemUsICZtc2ctPmJvZHlbNl0pOwoJd3JpdGVsKHNiLT5jdXJyZW50X2lvX2Jhc2UsICZtc2ctPmJvZHlbNl0pOwoKCXJjID0gaTJvX21zZ19wb3N0X3dhaXQoYywgbSwgMTIwKTsKCglkbWFfdW5tYXBfc2luZ2xlKGRldiwgaTJvX3N5c3RhYi5waHlzLCBpMm9fc3lzdGFiLmxlbiwKCQkJIFBDSV9ETUFfVE9ERVZJQ0UpOwoKCWlmIChyYyA8IDApCgkJcHJpbnRrKEtFUk5fRVJSICIlczogVW5hYmxlIHRvIHNldCBTeXNUYWIgKHN0YXR1cz0lI3gpLlxuIiwKCQkgICAgICAgYy0+bmFtZSwgLXJjKTsKCWVsc2UKCQlwcl9kZWJ1ZygiJXM6IFN5c1RhYiBzZXQuXG4iLCBjLT5uYW1lKTsKCglpMm9fc3RhdHVzX2dldChjKTsJLy8gRW50ZXJlZCBSRUFEWSBzdGF0ZQoKCXJldHVybiByYzsKfQoKLyoqCiAqCWkyb19pb3Bfb25saW5lIC0gQnJpbmcgYSBjb250cm9sbGVyIG9ubGluZSBpbnRvIE9QRVJBVElPTkFMIHN0YXRlLgogKglAYzogSTJPIGNvbnRyb2xsZXIKICoKICoJU2VuZCB0aGUgc3lzdGVtIHRhYmxlIGFuZCBlbmFibGUgdGhlIEkyTyBjb250cm9sbGVyLgogKgogKglSZXR1cm5zIDAgb24gc3VjY2VzcyBvciBuZWdhdGl2ZXIgZXJyb3IgY29kZSBvbiBmYWlsdXJlLgogKi8Kc3RhdGljIGludCBpMm9faW9wX29ubGluZShzdHJ1Y3QgaTJvX2NvbnRyb2xsZXIgKmMpCnsKCWludCByYzsKCglyYyA9IGkyb19pb3Bfc3lzdGFiX3NldChjKTsKCWlmIChyYykKCQlyZXR1cm4gcmM7CgoJLyogSW4gUkVBRFkgc3RhdGUgKi8KCXByX2RlYnVnKCIlczogQXR0ZW1wdGluZyB0byBlbmFibGUuLi5cbiIsIGMtPm5hbWUpOwoJcmMgPSBpMm9faW9wX2VuYWJsZShjKTsKCWlmIChyYykKCQlyZXR1cm4gcmM7CgoJcmV0dXJuIDA7Cn07CgovKioKICoJaTJvX2lvcF9yZW1vdmUgLSBSZW1vdmUgdGhlIEkyTyBjb250cm9sbGVyIGZyb20gdGhlIEkyTyBjb3JlCiAqCUBjOiBJMk8gY29udHJvbGxlcgogKgogKglSZW1vdmUgdGhlIEkyTyBjb250cm9sbGVyIGZyb20gdGhlIEkyTyBjb3JlLiBJZiBkZXZpY2VzIGFyZSBhdHRhY2hlZCB0bwogKgl0aGUgY29udHJvbGxlciByZW1vdmUgdGhlc2UgYWxzbyBhbmQgZmluYWxseSByZXNldCB0aGUgY29udHJvbGxlci4KICovCnZvaWQgaTJvX2lvcF9yZW1vdmUoc3RydWN0IGkyb19jb250cm9sbGVyICpjKQp7CglzdHJ1Y3QgaTJvX2RldmljZSAqZGV2LCAqdG1wOwoKCXByX2RlYnVnKCIlczogZGVsZXRpbmcgY29udHJvbGxlclxuIiwgYy0+bmFtZSk7CgoJaTJvX2RyaXZlcl9ub3RpZnlfY29udHJvbGxlcl9yZW1vdmVfYWxsKGMpOwoKCWxpc3RfZGVsKCZjLT5saXN0KTsKCglsaXN0X2Zvcl9lYWNoX2VudHJ5X3NhZmUoZGV2LCB0bXAsICZjLT5kZXZpY2VzLCBsaXN0KQoJICAgIGkyb19kZXZpY2VfcmVtb3ZlKGRldik7CgoJLyogQXNrIHRoZSBJT1AgdG8gc3dpdGNoIHRvIFJFU0VUIHN0YXRlICovCglpMm9faW9wX3Jlc2V0KGMpOwp9CgovKioKICoJaTJvX3N5c3RhYl9idWlsZCAtIEJ1aWxkIHN5c3RlbSB0YWJsZQogKgogKglUaGUgc3lzdGVtIHRhYmxlIGNvbnRhaW5zIGluZm9ybWF0aW9uIGFib3V0IGFsbCB0aGUgSU9QcyBpbiB0aGUgc3lzdGVtCiAqCShkdWgpIGFuZCBpcyB1c2VkIGJ5IHRoZSBFeGVjdXRpdmVzIG9uIHRoZSBJT1BzIHRvIGVzdGFibGlzaCBwZWVyMnBlZXIKICoJY29ubmVjdGlvbnMuIFdlJ3JlIG5vdCBzdXBwb3J0aW5nIHBlZXIycGVlciBhdCB0aGUgbW9tZW50LCBidXQgdGhpcwogKgl3aWxsIGJlIG5lZWRlZCBkb3duIHRoZSByb2FkIGZvciB0aGluZ3MgbGlrZSBsYW4ybGFuIGZvcndhcmRpbmcuCiAqCiAqCVJldHVybnMgMCBvbiBzdWNjZXNzIG9yIG5lZ2F0aXZlIGVycm9yIGNvZGUgb24gZmFpbHVyZS4KICovCnN0YXRpYyBpbnQgaTJvX3N5c3RhYl9idWlsZCh2b2lkKQp7CglzdHJ1Y3QgaTJvX2NvbnRyb2xsZXIgKmMsICp0bXA7CglpbnQgbnVtX2NvbnRyb2xsZXJzID0gMDsKCXUzMiBjaGFuZ2VfaW5kID0gMDsKCWludCBjb3VudCA9IDA7CglzdHJ1Y3QgaTJvX3N5c190YmwgKnN5c3RhYiA9IGkyb19zeXN0YWIudmlydDsKCglsaXN0X2Zvcl9lYWNoX2VudHJ5X3NhZmUoYywgdG1wLCAmaTJvX2NvbnRyb2xsZXJzLCBsaXN0KQoJICAgIG51bV9jb250cm9sbGVycysrOwoKCWlmIChzeXN0YWIpIHsKCQljaGFuZ2VfaW5kID0gc3lzdGFiLT5jaGFuZ2VfaW5kOwoJCWtmcmVlKGkyb19zeXN0YWIudmlydCk7Cgl9CgoJLyogSGVhZGVyICsgSU9QcyAqLwoJaTJvX3N5c3RhYi5sZW4gPSBzaXplb2Yoc3RydWN0IGkyb19zeXNfdGJsKSArIG51bV9jb250cm9sbGVycyAqCgkgICAgc2l6ZW9mKHN0cnVjdCBpMm9fc3lzX3RibF9lbnRyeSk7CgoJc3lzdGFiID0gaTJvX3N5c3RhYi52aXJ0ID0ga21hbGxvYyhpMm9fc3lzdGFiLmxlbiwgR0ZQX0tFUk5FTCk7CglpZiAoIXN5c3RhYikgewoJCXByaW50ayhLRVJOX0VSUiAiaTJvOiB1bmFibGUgdG8gYWxsb2NhdGUgbWVtb3J5IGZvciBTeXN0ZW0gIgoJCSAgICAgICAiVGFibGVcbiIpOwoJCXJldHVybiAtRU5PTUVNOwoJfQoJbWVtc2V0KHN5c3RhYiwgMCwgaTJvX3N5c3RhYi5sZW4pOwoKCXN5c3RhYi0+dmVyc2lvbiA9IEkyT1ZFUlNJT047CglzeXN0YWItPmNoYW5nZV9pbmQgPSBjaGFuZ2VfaW5kICsgMTsKCglsaXN0X2Zvcl9lYWNoX2VudHJ5X3NhZmUoYywgdG1wLCAmaTJvX2NvbnRyb2xsZXJzLCBsaXN0KSB7CgkJaTJvX3N0YXR1c19ibG9jayAqc2I7CgoJCWlmIChjb3VudCA+PSBudW1fY29udHJvbGxlcnMpIHsKCQkJcHJpbnRrKEtFUk5fRVJSICJpMm86IGNvbnRyb2xsZXIgYWRkZWQgd2hpbGUgYnVpbGRpbmcgIgoJCQkgICAgICAgInN5c3RlbSB0YWJsZVxuIik7CgkJCWJyZWFrOwoJCX0KCgkJc2IgPSBjLT5zdGF0dXNfYmxvY2sudmlydDsKCgkJLyoKCQkgKiBHZXQgdXBkYXRlZCBJT1Agc3RhdGUgc28gd2UgaGF2ZSB0aGUgbGF0ZXN0IGluZm9ybWF0aW9uCgkJICoKCQkgKiBXZSBzaG91bGQgZGVsZXRlIHRoZSBjb250cm9sbGVyIGF0IHRoaXMgcG9pbnQgaWYgaXQKCQkgKiBkb2Vzbid0IHJlc3BvbmQgc2luY2UgaWYgaXQncyBub3Qgb24gdGhlIHN5c3RlbSB0YWJsZQoJCSAqIGl0IGlzIHRlY2huaW5pY2FsbHkgbm90IHBhcnQgb2YgdGhlIEkyTyBzdWJzeXN0ZW0uLi4KCQkgKi8KCQlpZiAodW5saWtlbHkoaTJvX3N0YXR1c19nZXQoYykpKSB7CgkJCXByaW50ayhLRVJOX0VSUiAiJXM6IERlbGV0aW5nIGIvYyBjb3VsZCBub3QgZ2V0IHN0YXR1cyIKCQkJICAgICAgICIgd2hpbGUgYXR0ZW1wdGluZyB0byBidWlsZCBzeXN0ZW0gdGFibGVcbiIsCgkJCSAgICAgICBjLT5uYW1lKTsKCQkJaTJvX2lvcF9yZW1vdmUoYyk7CgkJCWNvbnRpbnVlOwkvLyB0cnkgdGhlIG5leHQgb25lCgkJfQoKCQlzeXN0YWItPmlvcHNbY291bnRdLm9yZ19pZCA9IHNiLT5vcmdfaWQ7CgkJc3lzdGFiLT5pb3BzW2NvdW50XS5pb3BfaWQgPSBjLT51bml0ICsgMjsKCQlzeXN0YWItPmlvcHNbY291bnRdLnNlZ19udW0gPSAwOwoJCXN5c3RhYi0+aW9wc1tjb3VudF0uaTJvX3ZlcnNpb24gPSBzYi0+aTJvX3ZlcnNpb247CgkJc3lzdGFiLT5pb3BzW2NvdW50XS5pb3Bfc3RhdGUgPSBzYi0+aW9wX3N0YXRlOwoJCXN5c3RhYi0+aW9wc1tjb3VudF0ubXNnX3R5cGUgPSBzYi0+bXNnX3R5cGU7CgkJc3lzdGFiLT5pb3BzW2NvdW50XS5mcmFtZV9zaXplID0gc2ItPmluYm91bmRfZnJhbWVfc2l6ZTsKCQlzeXN0YWItPmlvcHNbY291bnRdLmxhc3RfY2hhbmdlZCA9IGNoYW5nZV9pbmQ7CgkJc3lzdGFiLT5pb3BzW2NvdW50XS5pb3BfY2FwYWJpbGl0aWVzID0gc2ItPmlvcF9jYXBhYmlsaXRpZXM7CgkJc3lzdGFiLT5pb3BzW2NvdW50XS5pbmJvdW5kX2xvdyA9IGkyb19wdHJfbG93KGMtPnBvc3RfcG9ydCk7CgkJc3lzdGFiLT5pb3BzW2NvdW50XS5pbmJvdW5kX2hpZ2ggPSBpMm9fcHRyX2hpZ2goYy0+cG9zdF9wb3J0KTsKCgkJY291bnQrKzsKCX0KCglzeXN0YWItPm51bV9lbnRyaWVzID0gY291bnQ7CgoJcmV0dXJuIDA7Cn07CgovKioKICoJaTJvX3BhcnNlX2hydCAtIFBhcnNlIHRoZSBoYXJkd2FyZSByZXNvdXJjZSB0YWJsZS4KICoJQGM6IEkyTyBjb250cm9sbGVyCiAqCiAqCVdlIGRvbid0IGRvIGFueXRoaW5nIHdpdGggaXQgZXhjZXB0IGR1bXBpbmcgaXQgKGluIGRlYnVnIG1vZGUpLgogKgogKglSZXR1cm5zIDAuCiAqLwpzdGF0aWMgaW50IGkyb19wYXJzZV9ocnQoc3RydWN0IGkyb19jb250cm9sbGVyICpjKQp7CglpMm9fZHVtcF9ocnQoYyk7CglyZXR1cm4gMDsKfTsKCi8qKgogKglpMm9fc3RhdHVzX2dldCAtIEdldCB0aGUgc3RhdHVzIGJsb2NrIGZyb20gdGhlIEkyTyBjb250cm9sbGVyCiAqCUBjOiBJMk8gY29udHJvbGxlcgogKgogKglJc3N1ZSBhIHN0YXR1cyBxdWVyeSBvbiB0aGUgY29udHJvbGxlci4gVGhpcyB1cGRhdGVzIHRoZSBhdHRhY2hlZAogKglzdGF0dXMgYmxvY2suIFRoZSBzdGF0dXMgYmxvY2sgY291bGQgdGhlbiBiZSBhY2Nlc3NlZCB0aHJvdWdoCiAqCWMtPnN0YXR1c19ibG9jay4KICoKICoJUmV0dXJucyAwIG9uIHN1Y2VzcyBvciBuZWdhdGl2ZSBlcnJvciBjb2RlIG9uIGZhaWx1cmUuCiAqLwppbnQgaTJvX3N0YXR1c19nZXQoc3RydWN0IGkyb19jb250cm9sbGVyICpjKQp7CglzdHJ1Y3QgaTJvX21lc3NhZ2UgX19pb21lbSAqbXNnOwoJdTMyIG07Cgl1OCAqc3RhdHVzX2Jsb2NrOwoJdW5zaWduZWQgbG9uZyB0aW1lb3V0OwoKCXN0YXR1c19ibG9jayA9ICh1OCAqKSBjLT5zdGF0dXNfYmxvY2sudmlydDsKCW1lbXNldChzdGF0dXNfYmxvY2ssIDAsIHNpemVvZihpMm9fc3RhdHVzX2Jsb2NrKSk7CgoJbSA9IGkyb19tc2dfZ2V0X3dhaXQoYywgJm1zZywgSTJPX1RJTUVPVVRfTUVTU0FHRV9HRVQpOwoJaWYgKG0gPT0gSTJPX1FVRVVFX0VNUFRZKQoJCXJldHVybiAtRVRJTUVET1VUOwoKCXdyaXRlbChOSU5FX1dPUkRfTVNHX1NJWkUgfCBTR0xfT0ZGU0VUXzAsICZtc2ctPnUuaGVhZFswXSk7Cgl3cml0ZWwoSTJPX0NNRF9TVEFUVVNfR0VUIDw8IDI0IHwgSE9TVF9USUQgPDwgMTIgfCBBREFQVEVSX1RJRCwKCSAgICAgICAmbXNnLT51LmhlYWRbMV0pOwoJd3JpdGVsKGkyb19leGVjX2RyaXZlci5jb250ZXh0LCAmbXNnLT51LnMuaWNudHh0KTsKCXdyaXRlbCgwLCAmbXNnLT51LnMudGNudHh0KTsJLy8gRklYTUU6IHVzZSByZXNvbmFibGUgdHJhbnNhY3Rpb24gY29udGV4dAoJd3JpdGVsKDAsICZtc2ctPmJvZHlbMF0pOwoJd3JpdGVsKDAsICZtc2ctPmJvZHlbMV0pOwoJd3JpdGVsKGkyb19wdHJfbG93KCh2b2lkICopYy0+c3RhdHVzX2Jsb2NrLnBoeXMpLCAmbXNnLT5ib2R5WzJdKTsKCXdyaXRlbChpMm9fcHRyX2hpZ2goKHZvaWQgKiljLT5zdGF0dXNfYmxvY2sucGh5cyksICZtc2ctPmJvZHlbM10pOwoJd3JpdGVsKHNpemVvZihpMm9fc3RhdHVzX2Jsb2NrKSwgJm1zZy0+Ym9keVs0XSk7CS8qIGFsd2F5cyA4OCBieXRlcyAqLwoKCWkyb19tc2dfcG9zdChjLCBtKTsKCgkvKiBXYWl0IGZvciBhIHJlcGx5ICovCgl0aW1lb3V0ID0gamlmZmllcyArIEkyT19USU1FT1VUX1NUQVRVU19HRVQgKiBIWjsKCXdoaWxlIChzdGF0dXNfYmxvY2tbODddICE9IDB4RkYpIHsKCQlpZiAodGltZV9hZnRlcihqaWZmaWVzLCB0aW1lb3V0KSkgewoJCQlwcmludGsoS0VSTl9FUlIgIiVzOiBHZXQgc3RhdHVzIHRpbWVvdXQuXG4iLCBjLT5uYW1lKTsKCQkJcmV0dXJuIC1FVElNRURPVVQ7CgkJfQoKCQlzZXRfY3VycmVudF9zdGF0ZShUQVNLX1VOSU5URVJSVVBUSUJMRSk7CgkJc2NoZWR1bGVfdGltZW91dCgxKTsKCgkJcm1iKCk7Cgl9CgojaWZkZWYgREVCVUcKCWkyb19kZWJ1Z19zdGF0ZShjKTsKI2VuZGlmCgoJcmV0dXJuIDA7Cn0KCi8qCiAqCWkyb19ocnRfZ2V0IC0gR2V0IHRoZSBIYXJkd2FyZSBSZXNvdXJjZSBUYWJsZSBmcm9tIHRoZSBJMk8gY29udHJvbGxlcgogKglAYzogSTJPIGNvbnRyb2xsZXIgZnJvbSB3aGljaCB0aGUgSFJUIHNob3VsZCBiZSBmZXRjaGVkCiAqCiAqCVRoZSBIUlQgY29udGFpbnMgaW5mb3JtYXRpb24gYWJvdXQgcG9zc2libGUgaGlkZGVuIGRldmljZXMgYnV0IGlzCiAqCW1vc3RseSB1c2VsZXNzIHRvIHVzLgogKgogKglSZXR1cm5zIDAgb24gc3VjY2VzcyBvciBuZWdhdGl2ZXIgZXJyb3IgY29kZSBvbiBmYWlsdXJlLgogKi8Kc3RhdGljIGludCBpMm9faHJ0X2dldChzdHJ1Y3QgaTJvX2NvbnRyb2xsZXIgKmMpCnsKCWludCByYzsKCWludCBpOwoJaTJvX2hydCAqaHJ0ID0gYy0+aHJ0LnZpcnQ7Cgl1MzIgc2l6ZSA9IHNpemVvZihpMm9faHJ0KTsKCXN0cnVjdCBkZXZpY2UgKmRldiA9ICZjLT5wZGV2LT5kZXY7CgoJZm9yIChpID0gMDsgaSA8IEkyT19IUlRfR0VUX1RSSUVTOyBpKyspIHsKCQlzdHJ1Y3QgaTJvX21lc3NhZ2UgX19pb21lbSAqbXNnOwoJCXUzMiBtOwoKCQltID0gaTJvX21zZ19nZXRfd2FpdChjLCAmbXNnLCBJMk9fVElNRU9VVF9NRVNTQUdFX0dFVCk7CgkJaWYgKG0gPT0gSTJPX1FVRVVFX0VNUFRZKQoJCQlyZXR1cm4gLUVUSU1FRE9VVDsKCgkJd3JpdGVsKFNJWF9XT1JEX01TR19TSVpFIHwgU0dMX09GRlNFVF80LCAmbXNnLT51LmhlYWRbMF0pOwoJCXdyaXRlbChJMk9fQ01EX0hSVF9HRVQgPDwgMjQgfCBIT1NUX1RJRCA8PCAxMiB8IEFEQVBURVJfVElELAoJCSAgICAgICAmbXNnLT51LmhlYWRbMV0pOwoJCXdyaXRlbCgweGQwMDAwMDAwIHwgYy0+aHJ0LmxlbiwgJm1zZy0+Ym9keVswXSk7CgkJd3JpdGVsKGMtPmhydC5waHlzLCAmbXNnLT5ib2R5WzFdKTsKCgkJcmMgPSBpMm9fbXNnX3Bvc3Rfd2FpdF9tZW0oYywgbSwgMjAsICZjLT5ocnQpOwoKCQlpZiAocmMgPCAwKSB7CgkJCXByaW50ayhLRVJOX0VSUiAiJXM6IFVuYWJsZSB0byBnZXQgSFJUIChzdGF0dXM9JSN4KVxuIiwKCQkJICAgICAgIGMtPm5hbWUsIC1yYyk7CgkJCXJldHVybiByYzsKCQl9CgoJCXNpemUgPSBocnQtPm51bV9lbnRyaWVzICogaHJ0LT5lbnRyeV9sZW4gPDwgMjsKCQlpZiAoc2l6ZSA+IGMtPmhydC5sZW4pIHsKCQkJaWYgKGkyb19kbWFfcmVhbGxvYyhkZXYsICZjLT5ocnQsIHNpemUsIEdGUF9LRVJORUwpKQoJCQkJcmV0dXJuIC1FTk9NRU07CgkJCWVsc2UKCQkJCWhydCA9IGMtPmhydC52aXJ0OwoJCX0gZWxzZQoJCQlyZXR1cm4gaTJvX3BhcnNlX2hydChjKTsKCX0KCglwcmludGsoS0VSTl9FUlIgIiVzOiBVbmFibGUgdG8gZ2V0IEhSVCBhZnRlciAlZCB0cmllcywgZ2l2aW5nIHVwXG4iLAoJICAgICAgIGMtPm5hbWUsIEkyT19IUlRfR0VUX1RSSUVTKTsKCglyZXR1cm4gLUVCVVNZOwp9CgovKioKICoJaTJvX2lvcF9hbGxvYyAtIEFsbG9jYXRlIGFuZCBpbml0aWFsaXplIGEgaTJvX2NvbnRyb2xsZXIgc3RydWN0CiAqCiAqCUFsbG9jYXRlIHRoZSBuZWNlc3NhcnkgbWVtb3J5IGZvciBhIGkyb19jb250cm9sbGVyIHN0cnVjdCBhbmQKICoJaW5pdGlhbGl6ZSB0aGUgbGlzdHMuCiAqCiAqCVJldHVybnMgYSBwb2ludGVyIHRvIHRoZSBJMk8gY29udHJvbGxlciBvciBhIG5lZ2F0aXZlIGVycm9yIGNvZGUgb24KICoJZmFpbHVyZS4KICovCnN0cnVjdCBpMm9fY29udHJvbGxlciAqaTJvX2lvcF9hbGxvYyh2b2lkKQp7CglzdGF0aWMgaW50IHVuaXQgPSAwOwkvKiAwIGFuZCAxIGFyZSBOVUxMIElPUCBhbmQgTG9jYWwgSG9zdCAqLwoJc3RydWN0IGkyb19jb250cm9sbGVyICpjOwoKCWMgPSBrbWFsbG9jKHNpemVvZigqYyksIEdGUF9LRVJORUwpOwoJaWYgKCFjKSB7CgkJcHJpbnRrKEtFUk5fRVJSICJpMm86IEluc3VmZmljaWVudCBtZW1vcnkgdG8gYWxsb2NhdGUgYSBJMk8gIgoJCSAgICAgICAiY29udHJvbGxlci5cbiIpOwoJCXJldHVybiBFUlJfUFRSKC1FTk9NRU0pOwoJfQoJbWVtc2V0KGMsIDAsIHNpemVvZigqYykpOwoKCUlOSVRfTElTVF9IRUFEKCZjLT5kZXZpY2VzKTsKCXNwaW5fbG9ja19pbml0KCZjLT5sb2NrKTsKCWluaXRfTVVURVgoJmMtPmxjdF9sb2NrKTsKCWMtPnVuaXQgPSB1bml0Kys7CglzcHJpbnRmKGMtPm5hbWUsICJpb3AlZCIsIGMtPnVuaXQpOwoKI2lmIEJJVFNfUEVSX0xPTkcgPT0gNjQKCXNwaW5fbG9ja19pbml0KCZjLT5jb250ZXh0X2xpc3RfbG9jayk7CglhdG9taWNfc2V0KCZjLT5jb250ZXh0X2xpc3RfY291bnRlciwgMCk7CglJTklUX0xJU1RfSEVBRCgmYy0+Y29udGV4dF9saXN0KTsKI2VuZGlmCgoJcmV0dXJuIGM7Cn07CgovKioKICoJaTJvX2lvcF9mcmVlIC0gRnJlZSB0aGUgaTJvX2NvbnRyb2xsZXIgc3RydWN0CiAqCUBjOiBJMk8gY29udHJvbGxlciB0byBmcmVlCiAqLwp2b2lkIGkyb19pb3BfZnJlZShzdHJ1Y3QgaTJvX2NvbnRyb2xsZXIgKmMpCnsKCWtmcmVlKGMpOwp9OwoKLyoqCiAqCWkyb19pb3BfYWRkIC0gSW5pdGlhbGl6ZSB0aGUgSTJPIGNvbnRyb2xsZXIgYW5kIGFkZCBoaW0gdG8gdGhlIEkyTyBjb3JlCiAqCUBjOiBjb250cm9sbGVyCiAqCiAqCUluaXRpYWxpemUgdGhlIEkyTyBjb250cm9sbGVyIGFuZCBpZiBubyBlcnJvciBvY2N1cnMgYWRkIGhpbSB0byB0aGUgSTJPCiAqCWNvcmUuCiAqCiAqCVJldHVybnMgMCBvbiBzdWNjZXNzIG9yIG5lZ2F0aXZlIGVycm9yIGNvZGUgb24gZmFpbHVyZS4KICovCmludCBpMm9faW9wX2FkZChzdHJ1Y3QgaTJvX2NvbnRyb2xsZXIgKmMpCnsKCWludCByYzsKCglwcmludGsoS0VSTl9JTkZPICIlczogQWN0aXZhdGluZyBJMk8gY29udHJvbGxlci4uLlxuIiwgYy0+bmFtZSk7CglwcmludGsoS0VSTl9JTkZPICIlczogVGhpcyBtYXkgdGFrZSBhIGZldyBtaW51dGVzIGlmIHRoZXJlIGFyZSBtYW55ICIKCSAgICAgICAiZGV2aWNlc1xuIiwgYy0+bmFtZSk7CgoJaWYgKChyYyA9IGkyb19pb3BfYWN0aXZhdGUoYykpKSB7CgkJcHJpbnRrKEtFUk5fRVJSICIlczogY291bGQgbm90IGFjdGl2YXRlIGNvbnRyb2xsZXJcbiIsCgkJICAgICAgIGMtPm5hbWUpOwoJCWkyb19pb3BfcmVzZXQoYyk7CgkJcmV0dXJuIHJjOwoJfQoKCXByX2RlYnVnKCIlczogYnVpbGRpbmcgc3lzIHRhYmxlLi4uXG4iLCBjLT5uYW1lKTsKCglpZiAoKHJjID0gaTJvX3N5c3RhYl9idWlsZCgpKSkgewoJCWkyb19pb3BfcmVzZXQoYyk7CgkJcmV0dXJuIHJjOwoJfQoKCXByX2RlYnVnKCIlczogb25saW5lIGNvbnRyb2xsZXIuLi5cbiIsIGMtPm5hbWUpOwoKCWlmICgocmMgPSBpMm9faW9wX29ubGluZShjKSkpIHsKCQlpMm9faW9wX3Jlc2V0KGMpOwoJCXJldHVybiByYzsKCX0KCglwcl9kZWJ1ZygiJXM6IGdldHRpbmcgTENULi4uXG4iLCBjLT5uYW1lKTsKCglpZiAoKHJjID0gaTJvX2V4ZWNfbGN0X2dldChjKSkpIHsKCQlpMm9faW9wX3Jlc2V0KGMpOwoJCXJldHVybiByYzsKCX0KCglsaXN0X2FkZCgmYy0+bGlzdCwgJmkyb19jb250cm9sbGVycyk7CgoJaTJvX2RyaXZlcl9ub3RpZnlfY29udHJvbGxlcl9hZGRfYWxsKGMpOwoKCXByaW50ayhLRVJOX0lORk8gIiVzOiBDb250cm9sbGVyIGFkZGVkXG4iLCBjLT5uYW1lKTsKCglyZXR1cm4gMDsKfTsKCi8qKgogKglpMm9fZXZlbnRfcmVnaXN0ZXIgLSBUdXJuIG9uL29mZiBldmVudCBub3RpZmljYXRpb24gZm9yIGEgSTJPIGRldmljZQogKglAZGV2OiBJMk8gZGV2aWNlIHdoaWNoIHNob3VsZCByZWNlaXZlIHRoZSBldmVudCByZWdpc3RyYXRpb24gcmVxdWVzdAogKglAZHJ2OiBkcml2ZXIgd2hpY2ggd2FudCB0byBnZXQgbm90aWZpZWQKICoJQHRjbnR4dDogdHJhbnNhY3Rpb24gY29udGV4dCB0byB1c2Ugd2l0aCB0aGlzIG5vdGlmaWVyCiAqCUBldnRfbWFzazogbWFzayBvZiBldmVudHMKICoKICoJQ3JlYXRlIGFuZCBwb3N0cyBhbiBldmVudCByZWdpc3RyYXRpb24gbWVzc2FnZSB0byB0aGUgdGFzay4gTm8gcmVwbHkKICoJaXMgd2FpdGVkIGZvciwgb3IgZXhwZWN0ZWQuIElmIHlvdSBkbyBub3Qgd2FudCBmdXJ0aGVyIG5vdGlmaWNhdGlvbnMsCiAqCWNhbGwgdGhlIGkyb19ldmVudF9yZWdpc3RlciBhZ2FpbiB3aXRoIGEgZXZ0X21hc2sgb2YgMC4KICoKICoJUmV0dXJucyAwIG9uIHN1Y2Nlc3Mgb3IgLUVUSU1FRE9VVCBpZiBubyBtZXNzYWdlIGNvdWxkIGJlIGZldGNoZWQgZm9yCiAqCXNlbmRpbmcgdGhlIHJlcXVlc3QuCiAqLwppbnQgaTJvX2V2ZW50X3JlZ2lzdGVyKHN0cnVjdCBpMm9fZGV2aWNlICpkZXYsIHN0cnVjdCBpMm9fZHJpdmVyICpkcnYsCgkJICAgICAgIGludCB0Y250eHQsIHUzMiBldnRfbWFzaykKewoJc3RydWN0IGkyb19jb250cm9sbGVyICpjID0gZGV2LT5pb3A7CglzdHJ1Y3QgaTJvX21lc3NhZ2UgX19pb21lbSAqbXNnOwoJdTMyIG07CgoJbSA9IGkyb19tc2dfZ2V0X3dhaXQoYywgJm1zZywgSTJPX1RJTUVPVVRfTUVTU0FHRV9HRVQpOwoJaWYgKG0gPT0gSTJPX1FVRVVFX0VNUFRZKQoJCXJldHVybiAtRVRJTUVET1VUOwoKCXdyaXRlbChGSVZFX1dPUkRfTVNHX1NJWkUgfCBTR0xfT0ZGU0VUXzAsICZtc2ctPnUuaGVhZFswXSk7Cgl3cml0ZWwoSTJPX0NNRF9VVElMX0VWVF9SRUdJU1RFUiA8PCAyNCB8IEhPU1RfVElEIDw8IDEyIHwgZGV2LT5sY3RfZGF0YS4KCSAgICAgICB0aWQsICZtc2ctPnUuaGVhZFsxXSk7Cgl3cml0ZWwoZHJ2LT5jb250ZXh0LCAmbXNnLT51LnMuaWNudHh0KTsKCXdyaXRlbCh0Y250eHQsICZtc2ctPnUucy50Y250eHQpOwoJd3JpdGVsKGV2dF9tYXNrLCAmbXNnLT5ib2R5WzBdKTsKCglpMm9fbXNnX3Bvc3QoYywgbSk7CgoJcmV0dXJuIDA7Cn07CgovKioKICoJaTJvX2lvcF9pbml0IC0gSTJPIG1haW4gaW5pdGlhbGl6YXRpb24gZnVuY3Rpb24KICoKICoJSW5pdGlhbGl6ZSB0aGUgSTJPIGRyaXZlcnMgKE9TTSkgZnVuY3Rpb25zLCByZWdpc3RlciB0aGUgRXhlY3V0aXZlIE9TTSwKICoJaW5pdGlhbGl6ZSB0aGUgSTJPIFBDSSBwYXJ0IGFuZCBmaW5hbGx5IGluaXRpYWxpemUgSTJPIGRldmljZSBzdHVmZi4KICoKICoJUmV0dXJucyAwIG9uIHN1Y2Nlc3Mgb3IgbmVnYXRpdmUgZXJyb3IgY29kZSBvbiBmYWlsdXJlLgogKi8Kc3RhdGljIGludCBfX2luaXQgaTJvX2lvcF9pbml0KHZvaWQpCnsKCWludCByYyA9IDA7CgoJcHJpbnRrKEtFUk5fSU5GTyBPU01fREVTQ1JJUFRJT04gIiB2IiBPU01fVkVSU0lPTiAiXG4iKTsKCglyYyA9IGkyb19kZXZpY2VfaW5pdCgpOwoJaWYgKHJjKQoJCWdvdG8gZXhpdDsKCglyYyA9IGkyb19kcml2ZXJfaW5pdCgpOwoJaWYgKHJjKQoJCWdvdG8gZGV2aWNlX2V4aXQ7CgoJcmMgPSBpMm9fZXhlY19pbml0KCk7CglpZiAocmMpCgkJZ290byBkcml2ZXJfZXhpdDsKCglyYyA9IGkyb19wY2lfaW5pdCgpOwoJaWYgKHJjIDwgMCkKCQlnb3RvIGV4ZWNfZXhpdDsKCglyZXR1cm4gMDsKCiAgICAgIGV4ZWNfZXhpdDoKCWkyb19leGVjX2V4aXQoKTsKCiAgICAgIGRyaXZlcl9leGl0OgoJaTJvX2RyaXZlcl9leGl0KCk7CgogICAgICBkZXZpY2VfZXhpdDoKCWkyb19kZXZpY2VfZXhpdCgpOwoKICAgICAgZXhpdDoKCXJldHVybiByYzsKfQoKLyoqCiAqCWkyb19pb3BfZXhpdCAtIEkyTyBtYWluIGV4aXQgZnVuY3Rpb24KICoKICoJUmVtb3ZlcyBJMk8gY29udHJvbGxlcnMgZnJvbSBQQ0kgc3Vic3lzdGVtIGFuZCBzaHV0IGRvd24gT1NNcy4KICovCnN0YXRpYyB2b2lkIF9fZXhpdCBpMm9faW9wX2V4aXQodm9pZCkKewoJaTJvX3BjaV9leGl0KCk7CglpMm9fZXhlY19leGl0KCk7CglpMm9fZHJpdmVyX2V4aXQoKTsKCWkyb19kZXZpY2VfZXhpdCgpOwp9OwoKbW9kdWxlX2luaXQoaTJvX2lvcF9pbml0KTsKbW9kdWxlX2V4aXQoaTJvX2lvcF9leGl0KTsKCk1PRFVMRV9BVVRIT1IoIlJlZCBIYXQgU29mdHdhcmUiKTsKTU9EVUxFX0xJQ0VOU0UoIkdQTCIpOwpNT0RVTEVfREVTQ1JJUFRJT04oT1NNX0RFU0NSSVBUSU9OKTsKTU9EVUxFX1ZFUlNJT04oT1NNX1ZFUlNJT04pOwoKI2lmIEJJVFNfUEVSX0xPTkcgPT0gNjQKRVhQT1JUX1NZTUJPTChpMm9fY250eHRfbGlzdF9hZGQpOwpFWFBPUlRfU1lNQk9MKGkyb19jbnR4dF9saXN0X2dldCk7CkVYUE9SVF9TWU1CT0woaTJvX2NudHh0X2xpc3RfcmVtb3ZlKTsKRVhQT1JUX1NZTUJPTChpMm9fY250eHRfbGlzdF9nZXRfcHRyKTsKI2VuZGlmCkVYUE9SVF9TWU1CT0woaTJvX21zZ19nZXRfd2FpdCk7CkVYUE9SVF9TWU1CT0woaTJvX21zZ19ub3ApOwpFWFBPUlRfU1lNQk9MKGkyb19maW5kX2lvcCk7CkVYUE9SVF9TWU1CT0woaTJvX2lvcF9maW5kX2RldmljZSk7CkVYUE9SVF9TWU1CT0woaTJvX2V2ZW50X3JlZ2lzdGVyKTsKRVhQT1JUX1NZTUJPTChpMm9fc3RhdHVzX2dldCk7CkVYUE9SVF9TWU1CT0woaTJvX2NvbnRyb2xsZXJzKTsK