LyoKICoJRnVuY3Rpb25zIHRvIGhhbmRsZSBJMk8gY29udHJvbGxlcnMgYW5kIEkyTyBtZXNzYWdlIGhhbmRsaW5nCiAqCiAqCUNvcHlyaWdodCAoQykgMTk5OS0yMDAyCVJlZCBIYXQgU29mdHdhcmUKICoKICoJV3JpdHRlbiBieSBBbGFuIENveCwgQnVpbGRpbmcgTnVtYmVyIFRocmVlIEx0ZAogKgogKglUaGlzIHByb2dyYW0gaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKgl1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUKICoJRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIgdmVyc2lvbiAyIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91cgogKglvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKglBIGxvdCBvZiB0aGUgSTJPIG1lc3NhZ2Ugc2lkZSBjb2RlIGZyb20gdGhpcyBpcyB0YWtlbiBmcm9tIHRoZQogKglSZWQgQ3JlZWsgUkNQQ0k0NSBhZGFwdGVyIGRyaXZlciBieSBSZWQgQ3JlZWsgQ29tbXVuaWNhdGlvbnMKICoKICoJRml4ZXMvYWRkaXRpb25zOgogKgkJUGhpbGlwcCBSdW1wZgogKgkJSnVoYSBTaWV25G5lbiA8SnVoYS5TaWV2YW5lbkBjcy5IZWxzaW5raS5GST4KICoJCUF1dm8gSORra2luZW4gPEF1dm8uSGFra2luZW5AY3MuSGVsc2lua2kuRkk+CiAqCQlEZWVwYWsgU2F4ZW5hIDxkZWVwYWtAcGxleGl0eS5uZXQ+CiAqCQlCb2ppIFQgS2FubmFudGhhbmFtIDxib2ppLnQua2FubmFudGhhbmFtQGludGVsLmNvbT4KICoJCUFsYW4gQ294IDxhbGFuQHJlZGhhdC5jb20+OgogKgkJCVBvcnRlZCB0byBMaW51eCAyLjUuCiAqCQlNYXJrdXMgTGlkZWwgPE1hcmt1cy5MaWRlbEBzaGFkb3djb25uZWN0LmNvbT46CiAqCQkJTWlub3IgZml4ZXMgZm9yIDIuNi4KICovCgojaW5jbHVkZSA8bGludXgvbW9kdWxlLmg+CiNpbmNsdWRlIDxsaW51eC9pMm8uaD4KI2luY2x1ZGUgPGxpbnV4L2RlbGF5Lmg+CiNpbmNsdWRlICJjb3JlLmgiCgojZGVmaW5lIE9TTV9OQU1FCSJpMm8iCiNkZWZpbmUgT1NNX1ZFUlNJT04JIjEuMjg4IgojZGVmaW5lIE9TTV9ERVNDUklQVElPTgkiSTJPIHN1YnN5c3RlbSIKCi8qIGdsb2JhbCBJMk8gY29udHJvbGxlciBsaXN0ICovCkxJU1RfSEVBRChpMm9fY29udHJvbGxlcnMpOwoKLyoKICogZ2xvYmFsIEkyTyBTeXN0ZW0gVGFibGUuIENvbnRhaW5zIGluZm9ybWF0aW9uIGFib3V0IGFsbCB0aGUgSU9QcyBpbiB0aGUKICogc3lzdGVtLiBVc2VkIHRvIGluZm9ybSBJT1BzIGFib3V0IGVhY2ggb3RoZXJzIGV4aXN0ZW5jZS4KICovCnN0YXRpYyBzdHJ1Y3QgaTJvX2RtYSBpMm9fc3lzdGFiOwoKc3RhdGljIGludCBpMm9faHJ0X2dldChzdHJ1Y3QgaTJvX2NvbnRyb2xsZXIgKmMpOwoKLyoqCiAqCWkyb19tc2dfbm9wIC0gUmV0dXJucyBhIG1lc3NhZ2Ugd2hpY2ggaXMgbm90IHVzZWQKICoJQGM6IEkyTyBjb250cm9sbGVyIGZyb20gd2hpY2ggdGhlIG1lc3NhZ2Ugd2FzIGNyZWF0ZWQKICoJQG06IG1lc3NhZ2Ugd2hpY2ggc2hvdWxkIGJlIHJldHVybmVkCiAqCiAqCUlmIHlvdSBmZXRjaCBhIG1lc3NhZ2UgdmlhIGkyb19tc2dfZ2V0LCBhbmQgY2FuJ3QgdXNlIGl0LCB5b3UgbXVzdAogKglyZXR1cm4gdGhlIG1lc3NhZ2Ugd2l0aCB0aGlzIGZ1bmN0aW9uLiBPdGhlcndpc2UgdGhlIG1lc3NhZ2UgZnJhbWUKICoJaXMgbG9zdC4KICovCnZvaWQgaTJvX21zZ19ub3Aoc3RydWN0IGkyb19jb250cm9sbGVyICpjLCB1MzIgbSkKewoJc3RydWN0IGkyb19tZXNzYWdlIF9faW9tZW0gKm1zZyA9IGkyb19tc2dfaW5fdG9fdmlydChjLCBtKTsKCgl3cml0ZWwoVEhSRUVfV09SRF9NU0dfU0laRSB8IFNHTF9PRkZTRVRfMCwgJm1zZy0+dS5oZWFkWzBdKTsKCXdyaXRlbChJMk9fQ01EX1VUSUxfTk9QIDw8IDI0IHwgSE9TVF9USUQgPDwgMTIgfCBBREFQVEVSX1RJRCwKCSAgICAgICAmbXNnLT51LmhlYWRbMV0pOwoJd3JpdGVsKDAsICZtc2ctPnUuaGVhZFsyXSk7Cgl3cml0ZWwoMCwgJm1zZy0+dS5oZWFkWzNdKTsKCWkyb19tc2dfcG9zdChjLCBtKTsKfTsKCi8qKgogKglpMm9fbXNnX2dldF93YWl0IC0gb2J0YWluIGFuIEkyTyBtZXNzYWdlIGZyb20gdGhlIElPUAogKglAYzogSTJPIGNvbnRyb2xsZXIKICoJQG1zZzogcG9pbnRlciB0byBhIEkyTyBtZXNzYWdlIHBvaW50ZXIKICoJQHdhaXQ6IGhvdyBsb25nIHRvIHdhaXQgdW50aWwgdGltZW91dAogKgogKglUaGlzIGZ1bmN0aW9uIHdhaXRzIHVwIHRvIHdhaXQgc2Vjb25kcyBmb3IgYSBtZXNzYWdlIHNsb3QgdG8gYmUKICoJYXZhaWxhYmxlLgogKgogKglPbiBhIHN1Y2Nlc3MgdGhlIG1lc3NhZ2UgaXMgcmV0dXJuZWQgYW5kIHRoZSBwb2ludGVyIHRvIHRoZSBtZXNzYWdlIGlzCiAqCXNldCBpbiBtc2cuIFRoZSByZXR1cm5lZCBtZXNzYWdlIGlzIHRoZSBwaHlzaWNhbCBwYWdlIGZyYW1lIG9mZnNldAogKglhZGRyZXNzIGZyb20gdGhlIHJlYWQgcG9ydCAoc2VlIHRoZSBpMm8gc3BlYykuIElmIG5vIG1lc3NhZ2UgaXMKICoJYXZhaWxhYmxlIHJldHVybnMgSTJPX1FVRVVFX0VNUFRZIGFuZCBtc2cgaXMgbGVhdmVkIHVudG91Y2hlZC4KICovCnUzMiBpMm9fbXNnX2dldF93YWl0KHN0cnVjdCBpMm9fY29udHJvbGxlciAqYywKCQkgICAgIHN0cnVjdCBpMm9fbWVzc2FnZSBfX2lvbWVtICoqIG1zZywgaW50IHdhaXQpCnsKCXVuc2lnbmVkIGxvbmcgdGltZW91dCA9IGppZmZpZXMgKyB3YWl0ICogSFo7Cgl1MzIgbTsKCgl3aGlsZSAoKG0gPSBpMm9fbXNnX2dldChjLCBtc2cpKSA9PSBJMk9fUVVFVUVfRU1QVFkpIHsKCQlpZiAodGltZV9hZnRlcihqaWZmaWVzLCB0aW1lb3V0KSkgewoJCQlvc21fZGVidWcoIiVzOiBUaW1lb3V0IHdhaXRpbmcgZm9yIG1lc3NhZ2UgZnJhbWUuXG4iLAoJCQkJICBjLT5uYW1lKTsKCQkJcmV0dXJuIEkyT19RVUVVRV9FTVBUWTsKCQl9CgkJc2V0X2N1cnJlbnRfc3RhdGUoVEFTS19VTklOVEVSUlVQVElCTEUpOwoJCXNjaGVkdWxlX3RpbWVvdXQoMSk7Cgl9CgoJcmV0dXJuIG07Cn07CgojaWYgQklUU19QRVJfTE9ORyA9PSA2NAovKioKICogICAgICBpMm9fY250eHRfbGlzdF9hZGQgLSBBcHBlbmQgYSBwb2ludGVyIHRvIGNvbnRleHQgbGlzdCBhbmQgcmV0dXJuIGEgaWQKICoJQGM6IGNvbnRyb2xsZXIgdG8gd2hpY2ggdGhlIGNvbnRleHQgbGlzdCBiZWxvbmcKICoJQHB0cjogcG9pbnRlciB0byBhZGQgdG8gdGhlIGNvbnRleHQgbGlzdAogKgogKglCZWNhdXNlIHRoZSBjb250ZXh0IGZpZWxkIGluIEkyTyBpcyBvbmx5IDMyLWJpdCBsYXJnZSwgb24gNjQtYml0IHRoZQogKglwb2ludGVyIGlzIHRvIGxhcmdlIHRvIGZpdCBpbiB0aGUgY29udGV4dCBmaWVsZC4gVGhlIGkyb19jbnR4dF9saXN0CiAqCWZ1bmN0aW9ucyB0aGVyZWZvcmUgbWFwIHBvaW50ZXJzIHRvIGNvbnRleHQgZmllbGRzLgogKgogKglSZXR1cm5zIGNvbnRleHQgaWQgPiAwIG9uIHN1Y2Nlc3Mgb3IgMCBvbiBmYWlsdXJlLgogKi8KdTMyIGkyb19jbnR4dF9saXN0X2FkZChzdHJ1Y3QgaTJvX2NvbnRyb2xsZXIgKiBjLCB2b2lkICpwdHIpCnsKCXN0cnVjdCBpMm9fY29udGV4dF9saXN0X2VsZW1lbnQgKmVudHJ5OwoJdW5zaWduZWQgbG9uZyBmbGFnczsKCglpZiAoIXB0cikKCQlvc21fZXJyKCIlczogY291bGRuJ3QgYWRkIE5VTEwgcG9pbnRlciB0byBjb250ZXh0IGxpc3QhXG4iLAoJCQljLT5uYW1lKTsKCgllbnRyeSA9IGttYWxsb2Moc2l6ZW9mKCplbnRyeSksIEdGUF9BVE9NSUMpOwoJaWYgKCFlbnRyeSkgewoJCW9zbV9lcnIoIiVzOiBDb3VsZCBub3QgYWxsb2NhdGUgbWVtb3J5IGZvciBjb250ZXh0IGxpc3QgZWxlbWVudCIKCQkJIlxuIiwgYy0+bmFtZSk7CgkJcmV0dXJuIDA7Cgl9CgoJZW50cnktPnB0ciA9IHB0cjsKCWVudHJ5LT50aW1lc3RhbXAgPSBqaWZmaWVzOwoJSU5JVF9MSVNUX0hFQUQoJmVudHJ5LT5saXN0KTsKCglzcGluX2xvY2tfaXJxc2F2ZSgmYy0+Y29udGV4dF9saXN0X2xvY2ssIGZsYWdzKTsKCglpZiAodW5saWtlbHkoYXRvbWljX2luY19hbmRfdGVzdCgmYy0+Y29udGV4dF9saXN0X2NvdW50ZXIpKSkKCQlhdG9taWNfaW5jKCZjLT5jb250ZXh0X2xpc3RfY291bnRlcik7CgoJZW50cnktPmNvbnRleHQgPSBhdG9taWNfcmVhZCgmYy0+Y29udGV4dF9saXN0X2NvdW50ZXIpOwoKCWxpc3RfYWRkKCZlbnRyeS0+bGlzdCwgJmMtPmNvbnRleHRfbGlzdCk7CgoJc3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmYy0+Y29udGV4dF9saXN0X2xvY2ssIGZsYWdzKTsKCglvc21fZGVidWcoIiVzOiBBZGQgY29udGV4dCB0byBsaXN0ICVwIC0+ICVkXG4iLCBjLT5uYW1lLCBwdHIsIGNvbnRleHQpOwoKCXJldHVybiBlbnRyeS0+Y29udGV4dDsKfTsKCi8qKgogKiAgICAgIGkyb19jbnR4dF9saXN0X3JlbW92ZSAtIFJlbW92ZSBhIHBvaW50ZXIgZnJvbSB0aGUgY29udGV4dCBsaXN0CiAqCUBjOiBjb250cm9sbGVyIHRvIHdoaWNoIHRoZSBjb250ZXh0IGxpc3QgYmVsb25nCiAqCUBwdHI6IHBvaW50ZXIgd2hpY2ggc2hvdWxkIGJlIHJlbW92ZWQgZnJvbSB0aGUgY29udGV4dCBsaXN0CiAqCiAqCVJlbW92ZXMgYSBwcmV2aW91c2x5IGFkZGVkIHBvaW50ZXIgZnJvbSB0aGUgY29udGV4dCBsaXN0IGFuZCByZXR1cm5zCiAqCXRoZSBtYXRjaGluZyBjb250ZXh0IGlkLgogKgogKglSZXR1cm5zIGNvbnRleHQgaWQgb24gc3VjY2VzIG9yIDAgb24gZmFpbHVyZS4KICovCnUzMiBpMm9fY250eHRfbGlzdF9yZW1vdmUoc3RydWN0IGkyb19jb250cm9sbGVyICogYywgdm9pZCAqcHRyKQp7CglzdHJ1Y3QgaTJvX2NvbnRleHRfbGlzdF9lbGVtZW50ICplbnRyeTsKCXUzMiBjb250ZXh0ID0gMDsKCXVuc2lnbmVkIGxvbmcgZmxhZ3M7CgoJc3Bpbl9sb2NrX2lycXNhdmUoJmMtPmNvbnRleHRfbGlzdF9sb2NrLCBmbGFncyk7CglsaXN0X2Zvcl9lYWNoX2VudHJ5KGVudHJ5LCAmYy0+Y29udGV4dF9saXN0LCBsaXN0KQoJICAgIGlmIChlbnRyeS0+cHRyID09IHB0cikgewoJCWxpc3RfZGVsKCZlbnRyeS0+bGlzdCk7CgkJY29udGV4dCA9IGVudHJ5LT5jb250ZXh0OwoJCWtmcmVlKGVudHJ5KTsKCQlicmVhazsKCX0KCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJmMtPmNvbnRleHRfbGlzdF9sb2NrLCBmbGFncyk7CgoJaWYgKCFjb250ZXh0KQoJCW9zbV93YXJuKCIlczogQ291bGQgbm90IHJlbW92ZSBub25leGlzdGVudCBwdHIgJXBcbiIsIGMtPm5hbWUsCgkJCSBwdHIpOwoKCW9zbV9kZWJ1ZygiJXM6IHJlbW92ZSBwdHIgZnJvbSBjb250ZXh0IGxpc3QgJWQgLT4gJXBcbiIsIGMtPm5hbWUsCgkJICBjb250ZXh0LCBwdHIpOwoKCXJldHVybiBjb250ZXh0Owp9OwoKLyoqCiAqICAgICAgaTJvX2NudHh0X2xpc3RfZ2V0IC0gR2V0IGEgcG9pbnRlciBmcm9tIHRoZSBjb250ZXh0IGxpc3QgYW5kIHJlbW92ZSBpdAogKglAYzogY29udHJvbGxlciB0byB3aGljaCB0aGUgY29udGV4dCBsaXN0IGJlbG9uZwogKglAY29udGV4dDogY29udGV4dCBpZCB0byB3aGljaCB0aGUgcG9pbnRlciBiZWxvbmcKICoKICoJUmV0dXJucyBwb2ludGVyIHRvIHRoZSBtYXRjaGluZyBjb250ZXh0IGlkIG9uIHN1Y2Nlc3Mgb3IgTlVMTCBvbgogKglmYWlsdXJlLgogKi8Kdm9pZCAqaTJvX2NudHh0X2xpc3RfZ2V0KHN0cnVjdCBpMm9fY29udHJvbGxlciAqYywgdTMyIGNvbnRleHQpCnsKCXN0cnVjdCBpMm9fY29udGV4dF9saXN0X2VsZW1lbnQgKmVudHJ5OwoJdW5zaWduZWQgbG9uZyBmbGFnczsKCXZvaWQgKnB0ciA9IE5VTEw7CgoJc3Bpbl9sb2NrX2lycXNhdmUoJmMtPmNvbnRleHRfbGlzdF9sb2NrLCBmbGFncyk7CglsaXN0X2Zvcl9lYWNoX2VudHJ5KGVudHJ5LCAmYy0+Y29udGV4dF9saXN0LCBsaXN0KQoJICAgIGlmIChlbnRyeS0+Y29udGV4dCA9PSBjb250ZXh0KSB7CgkJbGlzdF9kZWwoJmVudHJ5LT5saXN0KTsKCQlwdHIgPSBlbnRyeS0+cHRyOwoJCWtmcmVlKGVudHJ5KTsKCQlicmVhazsKCX0KCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJmMtPmNvbnRleHRfbGlzdF9sb2NrLCBmbGFncyk7CgoJaWYgKCFwdHIpCgkJb3NtX3dhcm4oIiVzOiBjb250ZXh0IGlkICVkIG5vdCBmb3VuZFxuIiwgYy0+bmFtZSwgY29udGV4dCk7CgoJb3NtX2RlYnVnKCIlczogZ2V0IHB0ciBmcm9tIGNvbnRleHQgbGlzdCAlZCAtPiAlcFxuIiwgYy0+bmFtZSwgY29udGV4dCwKCQkgIHB0cik7CgoJcmV0dXJuIHB0cjsKfTsKCi8qKgogKiAgICAgIGkyb19jbnR4dF9saXN0X2dldF9wdHIgLSBHZXQgYSBjb250ZXh0IGlkIGZyb20gdGhlIGNvbnRleHQgbGlzdAogKglAYzogY29udHJvbGxlciB0byB3aGljaCB0aGUgY29udGV4dCBsaXN0IGJlbG9uZwogKglAcHRyOiBwb2ludGVyIHRvIHdoaWNoIHRoZSBjb250ZXh0IGlkIHNob3VsZCBiZSBmZXRjaGVkCiAqCiAqCVJldHVybnMgY29udGV4dCBpZCB3aGljaCBtYXRjaGVzIHRvIHRoZSBwb2ludGVyIG9uIHN1Y2NlcyBvciAwIG9uCiAqCWZhaWx1cmUuCiAqLwp1MzIgaTJvX2NudHh0X2xpc3RfZ2V0X3B0cihzdHJ1Y3QgaTJvX2NvbnRyb2xsZXIgKiBjLCB2b2lkICpwdHIpCnsKCXN0cnVjdCBpMm9fY29udGV4dF9saXN0X2VsZW1lbnQgKmVudHJ5OwoJdTMyIGNvbnRleHQgPSAwOwoJdW5zaWduZWQgbG9uZyBmbGFnczsKCglzcGluX2xvY2tfaXJxc2F2ZSgmYy0+Y29udGV4dF9saXN0X2xvY2ssIGZsYWdzKTsKCWxpc3RfZm9yX2VhY2hfZW50cnkoZW50cnksICZjLT5jb250ZXh0X2xpc3QsIGxpc3QpCgkgICAgaWYgKGVudHJ5LT5wdHIgPT0gcHRyKSB7CgkJY29udGV4dCA9IGVudHJ5LT5jb250ZXh0OwoJCWJyZWFrOwoJfQoJc3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmYy0+Y29udGV4dF9saXN0X2xvY2ssIGZsYWdzKTsKCglpZiAoIWNvbnRleHQpCgkJb3NtX3dhcm4oIiVzOiBDb3VsZCBub3QgZmluZCBub25leGlzdGVudCBwdHIgJXBcbiIsIGMtPm5hbWUsCgkJCSBwdHIpOwoKCW9zbV9kZWJ1ZygiJXM6IGdldCBjb250ZXh0IGlkIGZyb20gY29udGV4dCBsaXN0ICVwIC0+ICVkXG4iLCBjLT5uYW1lLAoJCSAgcHRyLCBjb250ZXh0KTsKCglyZXR1cm4gY29udGV4dDsKfTsKI2VuZGlmCgovKioKICoJaTJvX2lvcF9maW5kIC0gRmluZCBhbiBJMk8gY29udHJvbGxlciBieSBpZAogKglAdW5pdDogdW5pdCBudW1iZXIgb2YgdGhlIEkyTyBjb250cm9sbGVyIHRvIHNlYXJjaCBmb3IKICoKICoJTG9va3VwIHRoZSBJMk8gY29udHJvbGxlciBvbiB0aGUgY29udHJvbGxlciBsaXN0LgogKgogKglSZXR1cm5zIHBvaW50ZXIgdG8gdGhlIEkyTyBjb250cm9sbGVyIG9uIHN1Y2Nlc3Mgb3IgTlVMTCBpZiBub3QgZm91bmQuCiAqLwpzdHJ1Y3QgaTJvX2NvbnRyb2xsZXIgKmkyb19maW5kX2lvcChpbnQgdW5pdCkKewoJc3RydWN0IGkyb19jb250cm9sbGVyICpjOwoKCWxpc3RfZm9yX2VhY2hfZW50cnkoYywgJmkyb19jb250cm9sbGVycywgbGlzdCkgewoJCWlmIChjLT51bml0ID09IHVuaXQpCgkJCXJldHVybiBjOwoJfQoKCXJldHVybiBOVUxMOwp9OwoKLyoqCiAqCWkyb19pb3BfZmluZF9kZXZpY2UgLSBGaW5kIGEgSTJPIGRldmljZSBvbiBhbiBJMk8gY29udHJvbGxlcgogKglAYzogSTJPIGNvbnRyb2xsZXIgd2hlcmUgdGhlIEkyTyBkZXZpY2UgaGFuZ3Mgb24KICoJQHRpZDogVElEIG9mIHRoZSBJMk8gZGV2aWNlIHRvIHNlYXJjaCBmb3IKICoKICoJU2VhcmNoZXMgdGhlIGRldmljZXMgb2YgdGhlIEkyTyBjb250cm9sbGVyIGZvciBhIGRldmljZSB3aXRoIFRJRCB0aWQgYW5kCiAqCXJldHVybnMgaXQuCiAqCiAqCVJldHVybnMgYSBwb2ludGVyIHRvIHRoZSBJMk8gZGV2aWNlIGlmIGZvdW5kLCBvdGhlcndpc2UgTlVMTC4KICovCnN0cnVjdCBpMm9fZGV2aWNlICppMm9faW9wX2ZpbmRfZGV2aWNlKHN0cnVjdCBpMm9fY29udHJvbGxlciAqYywgdTE2IHRpZCkKewoJc3RydWN0IGkyb19kZXZpY2UgKmRldjsKCglsaXN0X2Zvcl9lYWNoX2VudHJ5KGRldiwgJmMtPmRldmljZXMsIGxpc3QpCgkgICAgaWYgKGRldi0+bGN0X2RhdGEudGlkID09IHRpZCkKCQlyZXR1cm4gZGV2OwoKCXJldHVybiBOVUxMOwp9OwoKLyoqCiAqCWkyb19xdWllc2NlX2NvbnRyb2xsZXIgLSBxdWllc2NlIGNvbnRyb2xsZXIKICoJQGM6IGNvbnRyb2xsZXIKICoKICoJUXVpZXNjZSBhbiBJT1AuIENhdXNlcyBJT1AgdG8gbWFrZSBleHRlcm5hbCBvcGVyYXRpb24gcXVpZXNjZW50CiAqCShpMm8gJ1JFQURZJyBzdGF0ZSkuIEludGVybmFsIG9wZXJhdGlvbiBvZiB0aGUgSU9QIGNvbnRpbnVlcyBub3JtYWxseS4KICoKICoJUmV0dXJucyAwIG9uIHN1Y2Nlc3Mgb3IgbmVnYXRpdmUgZXJyb3IgY29kZSBvbiBmYWlsdXJlLgogKi8Kc3RhdGljIGludCBpMm9faW9wX3F1aWVzY2Uoc3RydWN0IGkyb19jb250cm9sbGVyICpjKQp7CglzdHJ1Y3QgaTJvX21lc3NhZ2UgX19pb21lbSAqbXNnOwoJdTMyIG07CglpMm9fc3RhdHVzX2Jsb2NrICpzYiA9IGMtPnN0YXR1c19ibG9jay52aXJ0OwoJaW50IHJjOwoKCWkyb19zdGF0dXNfZ2V0KGMpOwoKCS8qIFN5c1F1aWVzY2UgZGlzY2FyZGVkIGlmIElPUCBub3QgaW4gUkVBRFkgb3IgT1BFUkFUSU9OQUwgc3RhdGUgKi8KCWlmICgoc2ItPmlvcF9zdGF0ZSAhPSBBREFQVEVSX1NUQVRFX1JFQURZKSAmJgoJICAgIChzYi0+aW9wX3N0YXRlICE9IEFEQVBURVJfU1RBVEVfT1BFUkFUSU9OQUwpKQoJCXJldHVybiAwOwoKCW0gPSBpMm9fbXNnX2dldF93YWl0KGMsICZtc2csIEkyT19USU1FT1VUX01FU1NBR0VfR0VUKTsKCWlmIChtID09IEkyT19RVUVVRV9FTVBUWSkKCQlyZXR1cm4gLUVUSU1FRE9VVDsKCgl3cml0ZWwoRk9VUl9XT1JEX01TR19TSVpFIHwgU0dMX09GRlNFVF8wLCAmbXNnLT51LmhlYWRbMF0pOwoJd3JpdGVsKEkyT19DTURfU1lTX1FVSUVTQ0UgPDwgMjQgfCBIT1NUX1RJRCA8PCAxMiB8IEFEQVBURVJfVElELAoJICAgICAgICZtc2ctPnUuaGVhZFsxXSk7CgoJLyogTG9uZyB0aW1lb3V0IG5lZWRlZCBmb3IgcXVpZXNjZSBpZiBsb3RzIG9mIGRldmljZXMgKi8KCWlmICgocmMgPSBpMm9fbXNnX3Bvc3Rfd2FpdChjLCBtLCAyNDApKSkKCQlvc21faW5mbygiJXM6IFVuYWJsZSB0byBxdWllc2NlIChzdGF0dXM9JSN4KS5cbiIsIGMtPm5hbWUsIC1yYyk7CgllbHNlCgkJb3NtX2RlYnVnKCIlczogUXVpZXNjZWQuXG4iLCBjLT5uYW1lKTsKCglpMm9fc3RhdHVzX2dldChjKTsJLy8gRW50ZXJlZCBSRUFEWSBzdGF0ZQoKCXJldHVybiByYzsKfTsKCi8qKgogKglpMm9faW9wX2VuYWJsZSAtIG1vdmUgY29udHJvbGxlciBmcm9tIHJlYWR5IHRvIE9QRVJBVElPTkFMCiAqCUBjOiBJMk8gY29udHJvbGxlcgogKgogKglFbmFibGUgSU9QLiBUaGlzIGFsbG93cyB0aGUgSU9QIHRvIHJlc3VtZSBleHRlcm5hbCBvcGVyYXRpb25zIGFuZAogKglyZXZlcnNlcyB0aGUgZWZmZWN0IG9mIGEgcXVpZXNjZS4gUmV0dXJucyB6ZXJvIG9yIGFuIGVycm9yIGNvZGUgaWYKICoJYW4gZXJyb3Igb2NjdXJzLgogKi8Kc3RhdGljIGludCBpMm9faW9wX2VuYWJsZShzdHJ1Y3QgaTJvX2NvbnRyb2xsZXIgKmMpCnsKCXN0cnVjdCBpMm9fbWVzc2FnZSBfX2lvbWVtICptc2c7Cgl1MzIgbTsKCWkyb19zdGF0dXNfYmxvY2sgKnNiID0gYy0+c3RhdHVzX2Jsb2NrLnZpcnQ7CglpbnQgcmM7CgoJaTJvX3N0YXR1c19nZXQoYyk7CgoJLyogRW5hYmxlIG9ubHkgYWxsb3dlZCBvbiBSRUFEWSBzdGF0ZSAqLwoJaWYgKHNiLT5pb3Bfc3RhdGUgIT0gQURBUFRFUl9TVEFURV9SRUFEWSkKCQlyZXR1cm4gLUVJTlZBTDsKCgltID0gaTJvX21zZ19nZXRfd2FpdChjLCAmbXNnLCBJMk9fVElNRU9VVF9NRVNTQUdFX0dFVCk7CglpZiAobSA9PSBJMk9fUVVFVUVfRU1QVFkpCgkJcmV0dXJuIC1FVElNRURPVVQ7CgoJd3JpdGVsKEZPVVJfV09SRF9NU0dfU0laRSB8IFNHTF9PRkZTRVRfMCwgJm1zZy0+dS5oZWFkWzBdKTsKCXdyaXRlbChJMk9fQ01EX1NZU19FTkFCTEUgPDwgMjQgfCBIT1NUX1RJRCA8PCAxMiB8IEFEQVBURVJfVElELAoJICAgICAgICZtc2ctPnUuaGVhZFsxXSk7CgoJLyogSG93IGxvbmcgb2YgYSB0aW1lb3V0IGRvIHdlIG5lZWQ/ICovCglpZiAoKHJjID0gaTJvX21zZ19wb3N0X3dhaXQoYywgbSwgMjQwKSkpCgkJb3NtX2VycigiJXM6IENvdWxkIG5vdCBlbmFibGUgKHN0YXR1cz0lI3gpLlxuIiwgYy0+bmFtZSwgLXJjKTsKCWVsc2UKCQlvc21fZGVidWcoIiVzOiBFbmFibGVkLlxuIiwgYy0+bmFtZSk7CgoJaTJvX3N0YXR1c19nZXQoYyk7CS8vIGVudGVyZWQgT1BFUkFUSU9OQUwgc3RhdGUKCglyZXR1cm4gcmM7Cn07CgovKioKICoJaTJvX2lvcF9xdWllc2NlX2FsbCAtIFF1aWVzY2UgYWxsIEkyTyBjb250cm9sbGVycyBvbiB0aGUgc3lzdGVtCiAqCiAqCVF1aWVzY2UgYWxsIEkyTyBjb250cm9sbGVycyB3aGljaCBhcmUgY29ubmVjdGVkIHRvIHRoZSBzeXN0ZW0uCiAqLwpzdGF0aWMgaW5saW5lIHZvaWQgaTJvX2lvcF9xdWllc2NlX2FsbCh2b2lkKQp7CglzdHJ1Y3QgaTJvX2NvbnRyb2xsZXIgKmMsICp0bXA7CgoJbGlzdF9mb3JfZWFjaF9lbnRyeV9zYWZlKGMsIHRtcCwgJmkyb19jb250cm9sbGVycywgbGlzdCkgewoJCWlmICghYy0+bm9fcXVpZXNjZSkKCQkJaTJvX2lvcF9xdWllc2NlKGMpOwoJfQp9OwoKLyoqCiAqCWkyb19pb3BfZW5hYmxlX2FsbCAtIEVuYWJsZXMgYWxsIGNvbnRyb2xsZXJzIG9uIHRoZSBzeXN0ZW0KICoKICoJRW5hYmxlcyBhbGwgSTJPIGNvbnRyb2xsZXJzIHdoaWNoIGFyZSBjb25uZWN0ZWQgdG8gdGhlIHN5c3RlbS4KICovCnN0YXRpYyBpbmxpbmUgdm9pZCBpMm9faW9wX2VuYWJsZV9hbGwodm9pZCkKewoJc3RydWN0IGkyb19jb250cm9sbGVyICpjLCAqdG1wOwoKCWxpc3RfZm9yX2VhY2hfZW50cnlfc2FmZShjLCB0bXAsICZpMm9fY29udHJvbGxlcnMsIGxpc3QpCgkgICAgaTJvX2lvcF9lbmFibGUoYyk7Cn07CgovKioKICoJaTJvX2NsZWFyX2NvbnRyb2xsZXIgLSBCcmluZyBJMk8gY29udHJvbGxlciBpbnRvIEhPTEQgc3RhdGUKICoJQGM6IGNvbnRyb2xsZXIKICoKICoJQ2xlYXIgYW4gSU9QIHRvIEhPTEQgc3RhdGUsIGllLiB0ZXJtaW5hdGUgZXh0ZXJuYWwgb3BlcmF0aW9ucywgY2xlYXIgYWxsCiAqCWlucHV0IHF1ZXVlcyBhbmQgcHJlcGFyZSBmb3IgYSBzeXN0ZW0gcmVzdGFydC4gSU9QJ3MgaW50ZXJuYWwgb3BlcmF0aW9uCiAqCWNvbnRpbnVlcyBub3JtYWxseSBhbmQgdGhlIG91dGJvdW5kIHF1ZXVlIGlzIGFsaXZlLiBUaGUgSU9QIGlzIG5vdAogKglleHBlY3RlZCB0byByZWJ1aWxkIGl0cyBMQ1QuCiAqCiAqCVJldHVybnMgMCBvbiBzdWNjZXNzIG9yIG5lZ2F0aXZlIGVycm9yIGNvZGUgb24gZmFpbHVyZS4KICovCnN0YXRpYyBpbnQgaTJvX2lvcF9jbGVhcihzdHJ1Y3QgaTJvX2NvbnRyb2xsZXIgKmMpCnsKCXN0cnVjdCBpMm9fbWVzc2FnZSBfX2lvbWVtICptc2c7Cgl1MzIgbTsKCWludCByYzsKCgltID0gaTJvX21zZ19nZXRfd2FpdChjLCAmbXNnLCBJMk9fVElNRU9VVF9NRVNTQUdFX0dFVCk7CglpZiAobSA9PSBJMk9fUVVFVUVfRU1QVFkpCgkJcmV0dXJuIC1FVElNRURPVVQ7CgoJLyogUXVpZXNjZSBhbGwgSU9QcyBmaXJzdCAqLwoJaTJvX2lvcF9xdWllc2NlX2FsbCgpOwoKCXdyaXRlbChGT1VSX1dPUkRfTVNHX1NJWkUgfCBTR0xfT0ZGU0VUXzAsICZtc2ctPnUuaGVhZFswXSk7Cgl3cml0ZWwoSTJPX0NNRF9BREFQVEVSX0NMRUFSIDw8IDI0IHwgSE9TVF9USUQgPDwgMTIgfCBBREFQVEVSX1RJRCwKCSAgICAgICAmbXNnLT51LmhlYWRbMV0pOwoKCWlmICgocmMgPSBpMm9fbXNnX3Bvc3Rfd2FpdChjLCBtLCAzMCkpKQoJCW9zbV9pbmZvKCIlczogVW5hYmxlIHRvIGNsZWFyIChzdGF0dXM9JSN4KS5cbiIsIGMtPm5hbWUsIC1yYyk7CgllbHNlCgkJb3NtX2RlYnVnKCIlczogQ2xlYXJlZC5cbiIsIGMtPm5hbWUpOwoKCS8qIEVuYWJsZSBhbGwgSU9QcyAqLwoJaTJvX2lvcF9lbmFibGVfYWxsKCk7CgoJcmV0dXJuIHJjOwp9CgovKioKICoJaTJvX2lvcF9pbml0X291dGJvdW5kX3F1ZXVlIC0gc2V0dXAgdGhlIG91dGJvdW5kIG1lc3NhZ2UgcXVldWUKICoJQGM6IEkyTyBjb250cm9sbGVyCiAqCiAqCUNsZWFyIGFuZCAocmUpaW5pdGlhbGl6ZSBJT1AncyBvdXRib3VuZCBxdWV1ZSBhbmQgcG9zdCB0aGUgbWVzc2FnZQogKglmcmFtZXMgdG8gdGhlIElPUC4KICoKICoJUmV0dXJucyAwIG9uIHN1Y2Nlc3Mgb3IgYSBuZWdhdGl2ZSBlcnJubyBjb2RlIG9uIGZhaWx1cmUuCiAqLwpzdGF0aWMgaW50IGkyb19pb3BfaW5pdF9vdXRib3VuZF9xdWV1ZShzdHJ1Y3QgaTJvX2NvbnRyb2xsZXIgKmMpCnsKCXZvbGF0aWxlIHU4ICpzdGF0dXMgPSBjLT5zdGF0dXMudmlydDsKCXUzMiBtOwoJc3RydWN0IGkyb19tZXNzYWdlIF9faW9tZW0gKm1zZzsKCXVsb25nIHRpbWVvdXQ7CglpbnQgaTsKCglvc21fZGVidWcoIiVzOiBJbml0aWFsaXppbmcgT3V0Ym91bmQgUXVldWUuLi5cbiIsIGMtPm5hbWUpOwoKCW1lbXNldChjLT5zdGF0dXMudmlydCwgMCwgNCk7CgoJbSA9IGkyb19tc2dfZ2V0X3dhaXQoYywgJm1zZywgSTJPX1RJTUVPVVRfTUVTU0FHRV9HRVQpOwoJaWYgKG0gPT0gSTJPX1FVRVVFX0VNUFRZKQoJCXJldHVybiAtRVRJTUVET1VUOwoKCXdyaXRlbChFSUdIVF9XT1JEX01TR19TSVpFIHwgU0dMX09GRlNFVF82LCAmbXNnLT51LmhlYWRbMF0pOwoJd3JpdGVsKEkyT19DTURfT1VUQk9VTkRfSU5JVCA8PCAyNCB8IEhPU1RfVElEIDw8IDEyIHwgQURBUFRFUl9USUQsCgkgICAgICAgJm1zZy0+dS5oZWFkWzFdKTsKCXdyaXRlbChpMm9fZXhlY19kcml2ZXIuY29udGV4dCwgJm1zZy0+dS5zLmljbnR4dCk7Cgl3cml0ZWwoMHgwMDAwMDAwMCwgJm1zZy0+dS5zLnRjbnR4dCk7Cgl3cml0ZWwoUEFHRV9TSVpFLCAmbXNnLT5ib2R5WzBdKTsKCS8qIE91dGJvdW5kIG1zZyBmcmFtZSBzaXplIGluIHdvcmRzIGFuZCBJbml0Y29kZSAqLwoJd3JpdGVsKEkyT19PVVRCT1VORF9NU0dfRlJBTUVfU0laRSA8PCAxNiB8IDB4ODAsICZtc2ctPmJvZHlbMV0pOwoJd3JpdGVsKDB4ZDAwMDAwMDQsICZtc2ctPmJvZHlbMl0pOwoJd3JpdGVsKGkyb19kbWFfbG93KGMtPnN0YXR1cy5waHlzKSwgJm1zZy0+Ym9keVszXSk7Cgl3cml0ZWwoaTJvX2RtYV9oaWdoKGMtPnN0YXR1cy5waHlzKSwgJm1zZy0+Ym9keVs0XSk7CgoJaTJvX21zZ19wb3N0KGMsIG0pOwoKCXRpbWVvdXQgPSBqaWZmaWVzICsgSTJPX1RJTUVPVVRfSU5JVF9PVVRCT1VORF9RVUVVRSAqIEhaOwoJd2hpbGUgKCpzdGF0dXMgPD0gSTJPX0NNRF9JTl9QUk9HUkVTUykgewoJCWlmICh0aW1lX2FmdGVyKGppZmZpZXMsIHRpbWVvdXQpKSB7CgkJCW9zbV93YXJuKCIlczogVGltZW91dCBJbml0aWFsaXppbmdcbiIsIGMtPm5hbWUpOwoJCQlyZXR1cm4gLUVUSU1FRE9VVDsKCQl9CgkJc2V0X2N1cnJlbnRfc3RhdGUoVEFTS19VTklOVEVSUlVQVElCTEUpOwoJCXNjaGVkdWxlX3RpbWVvdXQoMSk7Cgl9CgoJbSA9IGMtPm91dF9xdWV1ZS5waHlzOwoKCS8qIFBvc3QgZnJhbWVzICovCglmb3IgKGkgPSAwOyBpIDwgSTJPX01BWF9PVVRCT1VORF9NU0dfRlJBTUVTOyBpKyspIHsKCQlpMm9fZmx1c2hfcmVwbHkoYywgbSk7CgkJdWRlbGF5KDEpOwkvKiBQcm9taXNlICovCgkJbSArPSBJMk9fT1VUQk9VTkRfTVNHX0ZSQU1FX1NJWkUgKiBzaXplb2YodTMyKTsKCX0KCglyZXR1cm4gMDsKfQoKLyoqCiAqCWkyb19pb3BfcmVzZXQgLSByZXNldCBhbiBJMk8gY29udHJvbGxlcgogKglAYzogY29udHJvbGxlciB0byByZXNldAogKgogKglSZXNldCB0aGUgSU9QIGludG8gSU5JVCBzdGF0ZSBhbmQgd2FpdCB1bnRpbCBJT1AgZ2V0cyBpbnRvIFJFU0VUIHN0YXRlLgogKglUZXJtaW5hdGUgYWxsIGV4dGVybmFsIG9wZXJhdGlvbnMsIGNsZWFyIElPUCdzIGluYm91bmQgYW5kIG91dGJvdW5kCiAqCXF1ZXVlcywgdGVybWluYXRlIGFsbCBERE1zLCBhbmQgcmVsb2FkIHRoZSBJT1AncyBvcGVyYXRpbmcgZW52aXJvbm1lbnQKICoJYW5kIGFsbCBsb2NhbCBERE1zLiBUaGUgSU9QIHJlYnVpbGRzIGl0cyBMQ1QuCiAqLwpzdGF0aWMgaW50IGkyb19pb3BfcmVzZXQoc3RydWN0IGkyb19jb250cm9sbGVyICpjKQp7Cgl2b2xhdGlsZSB1OCAqc3RhdHVzID0gYy0+c3RhdHVzLnZpcnQ7CglzdHJ1Y3QgaTJvX21lc3NhZ2UgX19pb21lbSAqbXNnOwoJdTMyIG07Cgl1bnNpZ25lZCBsb25nIHRpbWVvdXQ7CglpMm9fc3RhdHVzX2Jsb2NrICpzYiA9IGMtPnN0YXR1c19ibG9jay52aXJ0OwoJaW50IHJjID0gMDsKCglvc21fZGVidWcoIiVzOiBSZXNldHRpbmcgY29udHJvbGxlclxuIiwgYy0+bmFtZSk7CgoJbSA9IGkyb19tc2dfZ2V0X3dhaXQoYywgJm1zZywgSTJPX1RJTUVPVVRfTUVTU0FHRV9HRVQpOwoJaWYgKG0gPT0gSTJPX1FVRVVFX0VNUFRZKQoJCXJldHVybiAtRVRJTUVET1VUOwoKCW1lbXNldChjLT5zdGF0dXNfYmxvY2sudmlydCwgMCwgOCk7CgoJLyogUXVpZXNjZSBhbGwgSU9QcyBmaXJzdCAqLwoJaTJvX2lvcF9xdWllc2NlX2FsbCgpOwoKCXdyaXRlbChFSUdIVF9XT1JEX01TR19TSVpFIHwgU0dMX09GRlNFVF8wLCAmbXNnLT51LmhlYWRbMF0pOwoJd3JpdGVsKEkyT19DTURfQURBUFRFUl9SRVNFVCA8PCAyNCB8IEhPU1RfVElEIDw8IDEyIHwgQURBUFRFUl9USUQsCgkgICAgICAgJm1zZy0+dS5oZWFkWzFdKTsKCXdyaXRlbChpMm9fZXhlY19kcml2ZXIuY29udGV4dCwgJm1zZy0+dS5zLmljbnR4dCk7Cgl3cml0ZWwoMCwgJm1zZy0+dS5zLnRjbnR4dCk7CS8vRklYTUU6IHVzZSByZWFzb25hYmxlIHRyYW5zYWN0aW9uIGNvbnRleHQKCXdyaXRlbCgwLCAmbXNnLT5ib2R5WzBdKTsKCXdyaXRlbCgwLCAmbXNnLT5ib2R5WzFdKTsKCXdyaXRlbChpMm9fZG1hX2xvdyhjLT5zdGF0dXMucGh5cyksICZtc2ctPmJvZHlbMl0pOwoJd3JpdGVsKGkyb19kbWFfaGlnaChjLT5zdGF0dXMucGh5cyksICZtc2ctPmJvZHlbM10pOwoKCWkyb19tc2dfcG9zdChjLCBtKTsKCgkvKiBXYWl0IGZvciBhIHJlcGx5ICovCgl0aW1lb3V0ID0gamlmZmllcyArIEkyT19USU1FT1VUX1JFU0VUICogSFo7Cgl3aGlsZSAoISpzdGF0dXMpIHsKCQlpZiAodGltZV9hZnRlcihqaWZmaWVzLCB0aW1lb3V0KSkKCQkJYnJlYWs7CgoJCXNldF9jdXJyZW50X3N0YXRlKFRBU0tfVU5JTlRFUlJVUFRJQkxFKTsKCQlzY2hlZHVsZV90aW1lb3V0KDEpOwoJfQoKCXN3aXRjaCAoKnN0YXR1cykgewoJY2FzZSBJMk9fQ01EX1JFSkVDVEVEOgoJCW9zbV93YXJuKCIlczogSU9QIHJlc2V0IHJlamVjdGVkXG4iLCBjLT5uYW1lKTsKCQlyYyA9IC1FUEVSTTsKCQlicmVhazsKCgljYXNlIEkyT19DTURfSU5fUFJPR1JFU1M6CgkJLyoKCQkgKiBPbmNlIHRoZSByZXNldCBpcyBzZW50LCB0aGUgSU9QIGdvZXMgaW50byB0aGUgSU5JVCBzdGF0ZQoJCSAqIHdoaWNoIGlzIGluZGV0ZXJtaW5hdGUuIFdlIG5lZWQgdG8gd2FpdCB1bnRpbCB0aGUgSU9QIGhhcwoJCSAqIHJlYm9vdGVkIGJlZm9yZSB3ZSBjYW4gbGV0IHRoZSBzeXN0ZW0gdGFsayB0byBpdC4gV2UgcmVhZAoJCSAqIHRoZSBpbmJvdW5kIEZyZWVfTGlzdCB1bnRpbCBhIG1lc3NhZ2UgaXMgYXZhaWxhYmxlLiBJZiB3ZQoJCSAqIGNhbid0IHJlYWQgb25lIGluIHRoZSBnaXZlbiBhbW1vdW50IG9mIHRpbWUsIHdlIGFzc3VtZSB0aGUKCQkgKiBJT1AgY291bGQgbm90IHJlYm9vdCBwcm9wZXJseS4KCQkgKi8KCQlvc21fZGVidWcoIiVzOiBSZXNldCBpbiBwcm9ncmVzcywgd2FpdGluZyBmb3IgcmVib290Li4uXG4iLAoJCQkgIGMtPm5hbWUpOwoKCQltID0gaTJvX21zZ19nZXRfd2FpdChjLCAmbXNnLCBJMk9fVElNRU9VVF9SRVNFVCk7CgkJd2hpbGUgKG0gPT0gSTJPX1FVRVVFX0VNUFRZKSB7CgkJCWlmICh0aW1lX2FmdGVyKGppZmZpZXMsIHRpbWVvdXQpKSB7CgkJCQlvc21fZXJyKCIlczogSU9QIHJlc2V0IHRpbWVvdXQuXG4iLCBjLT5uYW1lKTsKCQkJCXJjID0gLUVUSU1FRE9VVDsKCQkJCWdvdG8gZXhpdDsKCQkJfQoJCQlzZXRfY3VycmVudF9zdGF0ZShUQVNLX1VOSU5URVJSVVBUSUJMRSk7CgkJCXNjaGVkdWxlX3RpbWVvdXQoMSk7CgoJCQltID0gaTJvX21zZ19nZXRfd2FpdChjLCAmbXNnLCBJMk9fVElNRU9VVF9SRVNFVCk7CgkJfQoJCWkyb19tc2dfbm9wKGMsIG0pOwoKCQkvKiBmcm9tIGhlcmUgYWxsIHF1aWVzY2UgY29tbWFuZHMgYXJlIHNhZmUgKi8KCQljLT5ub19xdWllc2NlID0gMDsKCgkJLyogdmVyaWZ5IGlmIGNvbnRyb2xsZXIgaXMgaW4gc3RhdGUgUkVTRVQgKi8KCQlpMm9fc3RhdHVzX2dldChjKTsKCgkJaWYgKCFjLT5wcm9taXNlICYmIChzYi0+aW9wX3N0YXRlICE9IEFEQVBURVJfU1RBVEVfUkVTRVQpKQoJCQlvc21fd2FybigiJXM6IHJlc2V0IGNvbXBsZXRlZCwgYnV0IGFkYXB0ZXIgbm90IGluIFJFU0VUIgoJCQkJICIgc3RhdGUuXG4iLCBjLT5uYW1lKTsKCQllbHNlCgkJCW9zbV9kZWJ1ZygiJXM6IHJlc2V0IGNvbXBsZXRlZC5cbiIsIGMtPm5hbWUpOwoKCQlicmVhazsKCglkZWZhdWx0OgoJCW9zbV9lcnIoIiVzOiBJT1AgcmVzZXQgdGltZW91dC5cbiIsIGMtPm5hbWUpOwoJCXJjID0gLUVUSU1FRE9VVDsKCQlicmVhazsKCX0KCiAgICAgIGV4aXQ6CgkvKiBFbmFibGUgYWxsIElPUHMgKi8KCWkyb19pb3BfZW5hYmxlX2FsbCgpOwoKCXJldHVybiByYzsKfTsKCi8qKgogKglpMm9faW9wX2FjdGl2YXRlIC0gQnJpbmcgY29udHJvbGxlciB1cCB0byBIT0xECiAqCUBjOiBjb250cm9sbGVyCiAqCiAqCVRoaXMgZnVuY3Rpb24gYnJpbmdzIGFuIEkyTyBjb250cm9sbGVyIGludG8gSE9MRCBzdGF0ZS4gVGhlIGFkYXB0ZXIKICoJaXMgcmVzZXQgaWYgbmVjZXNzYXJ5IGFuZCB0aGVuIHRoZSBxdWV1ZXMgYW5kIHJlc291cmNlIHRhYmxlIGFyZSByZWFkLgogKgogKglSZXR1cm5zIDAgb24gc3VjY2VzcyBvciBuZWdhdGl2ZSBlcnJvciBjb2RlIG9uIGZhaWx1cmUuCiAqLwpzdGF0aWMgaW50IGkyb19pb3BfYWN0aXZhdGUoc3RydWN0IGkyb19jb250cm9sbGVyICpjKQp7CglpMm9fc3RhdHVzX2Jsb2NrICpzYiA9IGMtPnN0YXR1c19ibG9jay52aXJ0OwoJaW50IHJjOwoJaW50IHN0YXRlOwoKCS8qIEluIElOSVQgc3RhdGUsIFdhaXQgSW5ib3VuZCBRIHRvIGluaXRpYWxpemUgKGluIGkyb19zdGF0dXNfZ2V0KSAqLwoJLyogSW4gUkVBRFkgc3RhdGUsIEdldCBzdGF0dXMgKi8KCglyYyA9IGkyb19zdGF0dXNfZ2V0KGMpOwoJaWYgKHJjKSB7CgkJb3NtX2luZm8oIiVzOiBVbmFibGUgdG8gb2J0YWluIHN0YXR1cywgYXR0ZW1wdGluZyBhIHJlc2V0LlxuIiwKCQkJIGMtPm5hbWUpOwoJCXJjID0gaTJvX2lvcF9yZXNldChjKTsKCQlpZiAocmMpCgkJCXJldHVybiByYzsKCX0KCglpZiAoc2ItPmkyb192ZXJzaW9uID4gSTJPVkVSMTUpIHsKCQlvc21fZXJyKCIlczogTm90IHJ1bm5pbmcgdmVyc2lvbiAxLjUgb2YgdGhlIEkyTyBTcGVjaWZpY2F0aW9uLiIKCQkJIlxuIiwgYy0+bmFtZSk7CgkJcmV0dXJuIC1FTk9ERVY7Cgl9CgoJc3dpdGNoIChzYi0+aW9wX3N0YXRlKSB7CgljYXNlIEFEQVBURVJfU1RBVEVfRkFVTFRFRDoKCQlvc21fZXJyKCIlczogaGFyZHdhcmUgZmF1bHRcbiIsIGMtPm5hbWUpOwoJCXJldHVybiAtRUZBVUxUOwoKCWNhc2UgQURBUFRFUl9TVEFURV9SRUFEWToKCWNhc2UgQURBUFRFUl9TVEFURV9PUEVSQVRJT05BTDoKCWNhc2UgQURBUFRFUl9TVEFURV9IT0xEOgoJY2FzZSBBREFQVEVSX1NUQVRFX0ZBSUxFRDoKCQlvc21fZGVidWcoIiVzOiBhbHJlYWR5IHJ1bm5pbmcsIHRyeWluZyB0byByZXNldC4uLlxuIiwgYy0+bmFtZSk7CgkJcmMgPSBpMm9faW9wX3Jlc2V0KGMpOwoJCWlmIChyYykKCQkJcmV0dXJuIHJjOwoJfQoKCS8qIHByZXNlcnZlIHN0YXRlICovCglzdGF0ZSA9IHNiLT5pb3Bfc3RhdGU7CgoJcmMgPSBpMm9faW9wX2luaXRfb3V0Ym91bmRfcXVldWUoYyk7CglpZiAocmMpCgkJcmV0dXJuIHJjOwoKCS8qIGlmIGFkYXB0ZXIgd2FzIG5vdCBpbiBSRVNFVCBzdGF0ZSBjbGVhciBub3cgKi8KCWlmIChzdGF0ZSAhPSBBREFQVEVSX1NUQVRFX1JFU0VUKQoJCWkyb19pb3BfY2xlYXIoYyk7CgoJaTJvX3N0YXR1c19nZXQoYyk7CgoJaWYgKHNiLT5pb3Bfc3RhdGUgIT0gQURBUFRFUl9TVEFURV9IT0xEKSB7CgkJb3NtX2VycigiJXM6IGZhaWxlZCB0byBicmluZyBJT1AgaW50byBIT0xEIHN0YXRlXG4iLCBjLT5uYW1lKTsKCQlyZXR1cm4gLUVJTzsKCX0KCglyZXR1cm4gaTJvX2hydF9nZXQoYyk7Cn07CgovKioKICoJaTJvX2lvcF9zeXN0YWJfc2V0IC0gU2V0IHRoZSBJMk8gU3lzdGVtIFRhYmxlIG9mIHRoZSBzcGVjaWZpZWQgSU9QCiAqCUBjOiBJMk8gY29udHJvbGxlciB0byB3aGljaCB0aGUgc3lzdGVtIHRhYmxlIHNob3VsZCBiZSBzZW5kCiAqCiAqCUJlZm9yZSB0aGUgc3lzdGFiIGNvdWxkIGJlIHNldCBpMm9fc3lzdGFiX2J1aWxkKCkgbXVzdCBiZSBjYWxsZWQuCiAqCiAqCVJldHVybnMgMCBvbiBzdWNjZXNzIG9yIG5lZ2F0aXZlIGVycm9yIGNvZGUgb24gZmFpbHVyZS4KICovCnN0YXRpYyBpbnQgaTJvX2lvcF9zeXN0YWJfc2V0KHN0cnVjdCBpMm9fY29udHJvbGxlciAqYykKewoJc3RydWN0IGkyb19tZXNzYWdlIF9faW9tZW0gKm1zZzsKCXUzMiBtOwoJaTJvX3N0YXR1c19ibG9jayAqc2IgPSBjLT5zdGF0dXNfYmxvY2sudmlydDsKCXN0cnVjdCBkZXZpY2UgKmRldiA9ICZjLT5wZGV2LT5kZXY7CglzdHJ1Y3QgcmVzb3VyY2UgKnJvb3Q7CglpbnQgcmM7CgoJaWYgKHNiLT5jdXJyZW50X21lbV9zaXplIDwgc2ItPmRlc2lyZWRfbWVtX3NpemUpIHsKCQlzdHJ1Y3QgcmVzb3VyY2UgKnJlcyA9ICZjLT5tZW1fcmVzb3VyY2U7CgkJcmVzLT5uYW1lID0gYy0+cGRldi0+YnVzLT5uYW1lOwoJCXJlcy0+ZmxhZ3MgPSBJT1JFU09VUkNFX01FTTsKCQlyZXMtPnN0YXJ0ID0gMDsKCQlyZXMtPmVuZCA9IDA7CgkJb3NtX2luZm8oIiVzOiByZXF1aXJlcyBwcml2YXRlIG1lbW9yeSByZXNvdXJjZXMuXG4iLCBjLT5uYW1lKTsKCQlyb290ID0gcGNpX2ZpbmRfcGFyZW50X3Jlc291cmNlKGMtPnBkZXYsIHJlcyk7CgkJaWYgKHJvb3QgPT0gTlVMTCkKCQkJb3NtX3dhcm4oIiVzOiBDYW4ndCBmaW5kIHBhcmVudCByZXNvdXJjZSFcbiIsIGMtPm5hbWUpOwoJCWlmIChyb290ICYmIGFsbG9jYXRlX3Jlc291cmNlKHJvb3QsIHJlcywgc2ItPmRlc2lyZWRfbWVtX3NpemUsIHNiLT5kZXNpcmVkX21lbV9zaXplLCBzYi0+ZGVzaXJlZF9tZW1fc2l6ZSwgMSA8PCAyMCwJLyogVW5zcGVjaWZpZWQsIHNvIHVzZSAxTWIgYW5kIHBsYXkgc2FmZSAqLwoJCQkJCSAgICAgIE5VTEwsIE5VTEwpID49IDApIHsKCQkJYy0+bWVtX2FsbG9jID0gMTsKCQkJc2ItPmN1cnJlbnRfbWVtX3NpemUgPSAxICsgcmVzLT5lbmQgLSByZXMtPnN0YXJ0OwoJCQlzYi0+Y3VycmVudF9tZW1fYmFzZSA9IHJlcy0+c3RhcnQ7CgkJCW9zbV9pbmZvKCIlczogYWxsb2NhdGVkICVsZCBieXRlcyBvZiBQQ0kgbWVtb3J5IGF0ICIKCQkJCSAiMHglMDhsWC5cbiIsIGMtPm5hbWUsCgkJCQkgMSArIHJlcy0+ZW5kIC0gcmVzLT5zdGFydCwgcmVzLT5zdGFydCk7CgkJfQoJfQoKCWlmIChzYi0+Y3VycmVudF9pb19zaXplIDwgc2ItPmRlc2lyZWRfaW9fc2l6ZSkgewoJCXN0cnVjdCByZXNvdXJjZSAqcmVzID0gJmMtPmlvX3Jlc291cmNlOwoJCXJlcy0+bmFtZSA9IGMtPnBkZXYtPmJ1cy0+bmFtZTsKCQlyZXMtPmZsYWdzID0gSU9SRVNPVVJDRV9JTzsKCQlyZXMtPnN0YXJ0ID0gMDsKCQlyZXMtPmVuZCA9IDA7CgkJb3NtX2luZm8oIiVzOiByZXF1aXJlcyBwcml2YXRlIG1lbW9yeSByZXNvdXJjZXMuXG4iLCBjLT5uYW1lKTsKCQlyb290ID0gcGNpX2ZpbmRfcGFyZW50X3Jlc291cmNlKGMtPnBkZXYsIHJlcyk7CgkJaWYgKHJvb3QgPT0gTlVMTCkKCQkJb3NtX3dhcm4oIiVzOiBDYW4ndCBmaW5kIHBhcmVudCByZXNvdXJjZSFcbiIsIGMtPm5hbWUpOwoJCWlmIChyb290ICYmIGFsbG9jYXRlX3Jlc291cmNlKHJvb3QsIHJlcywgc2ItPmRlc2lyZWRfaW9fc2l6ZSwgc2ItPmRlc2lyZWRfaW9fc2l6ZSwgc2ItPmRlc2lyZWRfaW9fc2l6ZSwgMSA8PCAyMCwJLyogVW5zcGVjaWZpZWQsIHNvIHVzZSAxTWIgYW5kIHBsYXkgc2FmZSAqLwoJCQkJCSAgICAgIE5VTEwsIE5VTEwpID49IDApIHsKCQkJYy0+aW9fYWxsb2MgPSAxOwoJCQlzYi0+Y3VycmVudF9pb19zaXplID0gMSArIHJlcy0+ZW5kIC0gcmVzLT5zdGFydDsKCQkJc2ItPmN1cnJlbnRfbWVtX2Jhc2UgPSByZXMtPnN0YXJ0OwoJCQlvc21faW5mbygiJXM6IGFsbG9jYXRlZCAlbGQgYnl0ZXMgb2YgUENJIEkvTyBhdCAweCUwOGxYIgoJCQkJICIuXG4iLCBjLT5uYW1lLCAxICsgcmVzLT5lbmQgLSByZXMtPnN0YXJ0LAoJCQkJIHJlcy0+c3RhcnQpOwoJCX0KCX0KCgltID0gaTJvX21zZ19nZXRfd2FpdChjLCAmbXNnLCBJMk9fVElNRU9VVF9NRVNTQUdFX0dFVCk7CglpZiAobSA9PSBJMk9fUVVFVUVfRU1QVFkpCgkJcmV0dXJuIC1FVElNRURPVVQ7CgoJaTJvX3N5c3RhYi5waHlzID0gZG1hX21hcF9zaW5nbGUoZGV2LCBpMm9fc3lzdGFiLnZpcnQsIGkyb19zeXN0YWIubGVuLAoJCQkJCSBQQ0lfRE1BX1RPREVWSUNFKTsKCWlmICghaTJvX3N5c3RhYi5waHlzKSB7CgkJaTJvX21zZ19ub3AoYywgbSk7CgkJcmV0dXJuIC1FTk9NRU07Cgl9CgoJd3JpdGVsKEkyT19NRVNTQUdFX1NJWkUoMTIpIHwgU0dMX09GRlNFVF82LCAmbXNnLT51LmhlYWRbMF0pOwoJd3JpdGVsKEkyT19DTURfU1lTX1RBQl9TRVQgPDwgMjQgfCBIT1NUX1RJRCA8PCAxMiB8IEFEQVBURVJfVElELAoJICAgICAgICZtc2ctPnUuaGVhZFsxXSk7CgoJLyoKCSAqIFByb3ZpZGUgdGhyZWUgU0dMLWVsZW1lbnRzOgoJICogU3lzdGVtIHRhYmxlIChTeXNUYWIpLCBQcml2YXRlIG1lbW9yeSBzcGFjZSBkZWNsYXJhdGlvbiBhbmQKCSAqIFByaXZhdGUgaS9vIHNwYWNlIGRlY2xhcmF0aW9uCgkgKgoJICogRklYTUU6IGlzIHRoaXMgc3RpbGwgdHJ1ZT8KCSAqIE5hc3R5IG9uZSBoZXJlLiBXZSBjYW4ndCB1c2UgZG1hX2FsbG9jX2NvaGVyZW50IHRvIHNlbmQgdGhlCgkgKiBzYW1lIHRhYmxlIHRvIGV2ZXJ5b25lLiBXZSBoYXZlIHRvIGdvIHJlbWFwIGl0IGZvciB0aGVtIGFsbAoJICovCgoJd3JpdGVsKGMtPnVuaXQgKyAyLCAmbXNnLT5ib2R5WzBdKTsKCXdyaXRlbCgwLCAmbXNnLT5ib2R5WzFdKTsKCXdyaXRlbCgweDU0MDAwMDAwIHwgaTJvX3N5c3RhYi5sZW4sICZtc2ctPmJvZHlbMl0pOwoJd3JpdGVsKGkyb19zeXN0YWIucGh5cywgJm1zZy0+Ym9keVszXSk7Cgl3cml0ZWwoMHg1NDAwMDAwMCB8IHNiLT5jdXJyZW50X21lbV9zaXplLCAmbXNnLT5ib2R5WzRdKTsKCXdyaXRlbChzYi0+Y3VycmVudF9tZW1fYmFzZSwgJm1zZy0+Ym9keVs1XSk7Cgl3cml0ZWwoMHhkNDAwMDAwMCB8IHNiLT5jdXJyZW50X2lvX3NpemUsICZtc2ctPmJvZHlbNl0pOwoJd3JpdGVsKHNiLT5jdXJyZW50X2lvX2Jhc2UsICZtc2ctPmJvZHlbNl0pOwoKCXJjID0gaTJvX21zZ19wb3N0X3dhaXQoYywgbSwgMTIwKTsKCglkbWFfdW5tYXBfc2luZ2xlKGRldiwgaTJvX3N5c3RhYi5waHlzLCBpMm9fc3lzdGFiLmxlbiwKCQkJIFBDSV9ETUFfVE9ERVZJQ0UpOwoKCWlmIChyYyA8IDApCgkJb3NtX2VycigiJXM6IFVuYWJsZSB0byBzZXQgU3lzVGFiIChzdGF0dXM9JSN4KS5cbiIsIGMtPm5hbWUsCgkJCS1yYyk7CgllbHNlCgkJb3NtX2RlYnVnKCIlczogU3lzVGFiIHNldC5cbiIsIGMtPm5hbWUpOwoKCWkyb19zdGF0dXNfZ2V0KGMpOwkvLyBFbnRlcmVkIFJFQURZIHN0YXRlCgoJcmV0dXJuIHJjOwp9CgovKioKICoJaTJvX2lvcF9vbmxpbmUgLSBCcmluZyBhIGNvbnRyb2xsZXIgb25saW5lIGludG8gT1BFUkFUSU9OQUwgc3RhdGUuCiAqCUBjOiBJMk8gY29udHJvbGxlcgogKgogKglTZW5kIHRoZSBzeXN0ZW0gdGFibGUgYW5kIGVuYWJsZSB0aGUgSTJPIGNvbnRyb2xsZXIuCiAqCiAqCVJldHVybnMgMCBvbiBzdWNjZXNzIG9yIG5lZ2F0aXZlciBlcnJvciBjb2RlIG9uIGZhaWx1cmUuCiAqLwpzdGF0aWMgaW50IGkyb19pb3Bfb25saW5lKHN0cnVjdCBpMm9fY29udHJvbGxlciAqYykKewoJaW50IHJjOwoKCXJjID0gaTJvX2lvcF9zeXN0YWJfc2V0KGMpOwoJaWYgKHJjKQoJCXJldHVybiByYzsKCgkvKiBJbiBSRUFEWSBzdGF0ZSAqLwoJb3NtX2RlYnVnKCIlczogQXR0ZW1wdGluZyB0byBlbmFibGUuLi5cbiIsIGMtPm5hbWUpOwoJcmMgPSBpMm9faW9wX2VuYWJsZShjKTsKCWlmIChyYykKCQlyZXR1cm4gcmM7CgoJcmV0dXJuIDA7Cn07CgovKioKICoJaTJvX2lvcF9yZW1vdmUgLSBSZW1vdmUgdGhlIEkyTyBjb250cm9sbGVyIGZyb20gdGhlIEkyTyBjb3JlCiAqCUBjOiBJMk8gY29udHJvbGxlcgogKgogKglSZW1vdmUgdGhlIEkyTyBjb250cm9sbGVyIGZyb20gdGhlIEkyTyBjb3JlLiBJZiBkZXZpY2VzIGFyZSBhdHRhY2hlZCB0bwogKgl0aGUgY29udHJvbGxlciByZW1vdmUgdGhlc2UgYWxzbyBhbmQgZmluYWxseSByZXNldCB0aGUgY29udHJvbGxlci4KICovCnZvaWQgaTJvX2lvcF9yZW1vdmUoc3RydWN0IGkyb19jb250cm9sbGVyICpjKQp7CglzdHJ1Y3QgaTJvX2RldmljZSAqZGV2LCAqdG1wOwoKCW9zbV9kZWJ1ZygiJXM6IGRlbGV0aW5nIGNvbnRyb2xsZXJcbiIsIGMtPm5hbWUpOwoKCWkyb19kcml2ZXJfbm90aWZ5X2NvbnRyb2xsZXJfcmVtb3ZlX2FsbChjKTsKCglsaXN0X2RlbCgmYy0+bGlzdCk7CgoJbGlzdF9mb3JfZWFjaF9lbnRyeV9zYWZlKGRldiwgdG1wLCAmYy0+ZGV2aWNlcywgbGlzdCkKCSAgICBpMm9fZGV2aWNlX3JlbW92ZShkZXYpOwoKCWRldmljZV9kZWwoJmMtPmRldmljZSk7CgoJLyogQXNrIHRoZSBJT1AgdG8gc3dpdGNoIHRvIFJFU0VUIHN0YXRlICovCglpMm9faW9wX3Jlc2V0KGMpOwoKCXB1dF9kZXZpY2UoJmMtPmRldmljZSk7Cn0KCi8qKgogKglpMm9fc3lzdGFiX2J1aWxkIC0gQnVpbGQgc3lzdGVtIHRhYmxlCiAqCiAqCVRoZSBzeXN0ZW0gdGFibGUgY29udGFpbnMgaW5mb3JtYXRpb24gYWJvdXQgYWxsIHRoZSBJT1BzIGluIHRoZSBzeXN0ZW0KICoJKGR1aCkgYW5kIGlzIHVzZWQgYnkgdGhlIEV4ZWN1dGl2ZXMgb24gdGhlIElPUHMgdG8gZXN0YWJsaXNoIHBlZXIycGVlcgogKgljb25uZWN0aW9ucy4gV2UncmUgbm90IHN1cHBvcnRpbmcgcGVlcjJwZWVyIGF0IHRoZSBtb21lbnQsIGJ1dCB0aGlzCiAqCXdpbGwgYmUgbmVlZGVkIGRvd24gdGhlIHJvYWQgZm9yIHRoaW5ncyBsaWtlIGxhbjJsYW4gZm9yd2FyZGluZy4KICoKICoJUmV0dXJucyAwIG9uIHN1Y2Nlc3Mgb3IgbmVnYXRpdmUgZXJyb3IgY29kZSBvbiBmYWlsdXJlLgogKi8Kc3RhdGljIGludCBpMm9fc3lzdGFiX2J1aWxkKHZvaWQpCnsKCXN0cnVjdCBpMm9fY29udHJvbGxlciAqYywgKnRtcDsKCWludCBudW1fY29udHJvbGxlcnMgPSAwOwoJdTMyIGNoYW5nZV9pbmQgPSAwOwoJaW50IGNvdW50ID0gMDsKCXN0cnVjdCBpMm9fc3lzX3RibCAqc3lzdGFiID0gaTJvX3N5c3RhYi52aXJ0OwoKCWxpc3RfZm9yX2VhY2hfZW50cnlfc2FmZShjLCB0bXAsICZpMm9fY29udHJvbGxlcnMsIGxpc3QpCgkgICAgbnVtX2NvbnRyb2xsZXJzKys7CgoJaWYgKHN5c3RhYikgewoJCWNoYW5nZV9pbmQgPSBzeXN0YWItPmNoYW5nZV9pbmQ7CgkJa2ZyZWUoaTJvX3N5c3RhYi52aXJ0KTsKCX0KCgkvKiBIZWFkZXIgKyBJT1BzICovCglpMm9fc3lzdGFiLmxlbiA9IHNpemVvZihzdHJ1Y3QgaTJvX3N5c190YmwpICsgbnVtX2NvbnRyb2xsZXJzICoKCSAgICBzaXplb2Yoc3RydWN0IGkyb19zeXNfdGJsX2VudHJ5KTsKCglzeXN0YWIgPSBpMm9fc3lzdGFiLnZpcnQgPSBrbWFsbG9jKGkyb19zeXN0YWIubGVuLCBHRlBfS0VSTkVMKTsKCWlmICghc3lzdGFiKSB7CgkJb3NtX2VycigidW5hYmxlIHRvIGFsbG9jYXRlIG1lbW9yeSBmb3IgU3lzdGVtIFRhYmxlXG4iKTsKCQlyZXR1cm4gLUVOT01FTTsKCX0KCW1lbXNldChzeXN0YWIsIDAsIGkyb19zeXN0YWIubGVuKTsKCglzeXN0YWItPnZlcnNpb24gPSBJMk9WRVJTSU9OOwoJc3lzdGFiLT5jaGFuZ2VfaW5kID0gY2hhbmdlX2luZCArIDE7CgoJbGlzdF9mb3JfZWFjaF9lbnRyeV9zYWZlKGMsIHRtcCwgJmkyb19jb250cm9sbGVycywgbGlzdCkgewoJCWkyb19zdGF0dXNfYmxvY2sgKnNiOwoKCQlpZiAoY291bnQgPj0gbnVtX2NvbnRyb2xsZXJzKSB7CgkJCW9zbV9lcnIoImNvbnRyb2xsZXIgYWRkZWQgd2hpbGUgYnVpbGRpbmcgc3lzdGVtIHRhYmxlIgoJCQkJIlxuIik7CgkJCWJyZWFrOwoJCX0KCgkJc2IgPSBjLT5zdGF0dXNfYmxvY2sudmlydDsKCgkJLyoKCQkgKiBHZXQgdXBkYXRlZCBJT1Agc3RhdGUgc28gd2UgaGF2ZSB0aGUgbGF0ZXN0IGluZm9ybWF0aW9uCgkJICoKCQkgKiBXZSBzaG91bGQgZGVsZXRlIHRoZSBjb250cm9sbGVyIGF0IHRoaXMgcG9pbnQgaWYgaXQKCQkgKiBkb2Vzbid0IHJlc3BvbmQgc2luY2UgaWYgaXQncyBub3Qgb24gdGhlIHN5c3RlbSB0YWJsZQoJCSAqIGl0IGlzIHRlY2huaW5pY2FsbHkgbm90IHBhcnQgb2YgdGhlIEkyTyBzdWJzeXN0ZW0uLi4KCQkgKi8KCQlpZiAodW5saWtlbHkoaTJvX3N0YXR1c19nZXQoYykpKSB7CgkJCW9zbV9lcnIoIiVzOiBEZWxldGluZyBiL2MgY291bGQgbm90IGdldCBzdGF0dXMgd2hpbGUgIgoJCQkJImF0dGVtcHRpbmcgdG8gYnVpbGQgc3lzdGVtIHRhYmxlXG4iLCBjLT5uYW1lKTsKCQkJaTJvX2lvcF9yZW1vdmUoYyk7CgkJCWNvbnRpbnVlOwkvLyB0cnkgdGhlIG5leHQgb25lCgkJfQoKCQlzeXN0YWItPmlvcHNbY291bnRdLm9yZ19pZCA9IHNiLT5vcmdfaWQ7CgkJc3lzdGFiLT5pb3BzW2NvdW50XS5pb3BfaWQgPSBjLT51bml0ICsgMjsKCQlzeXN0YWItPmlvcHNbY291bnRdLnNlZ19udW0gPSAwOwoJCXN5c3RhYi0+aW9wc1tjb3VudF0uaTJvX3ZlcnNpb24gPSBzYi0+aTJvX3ZlcnNpb247CgkJc3lzdGFiLT5pb3BzW2NvdW50XS5pb3Bfc3RhdGUgPSBzYi0+aW9wX3N0YXRlOwoJCXN5c3RhYi0+aW9wc1tjb3VudF0ubXNnX3R5cGUgPSBzYi0+bXNnX3R5cGU7CgkJc3lzdGFiLT5pb3BzW2NvdW50XS5mcmFtZV9zaXplID0gc2ItPmluYm91bmRfZnJhbWVfc2l6ZTsKCQlzeXN0YWItPmlvcHNbY291bnRdLmxhc3RfY2hhbmdlZCA9IGNoYW5nZV9pbmQ7CgkJc3lzdGFiLT5pb3BzW2NvdW50XS5pb3BfY2FwYWJpbGl0aWVzID0gc2ItPmlvcF9jYXBhYmlsaXRpZXM7CgkJc3lzdGFiLT5pb3BzW2NvdW50XS5pbmJvdW5kX2xvdyA9CgkJICAgIGkyb19kbWFfbG93KGMtPmJhc2UucGh5cyArIEkyT19JTl9QT1JUKTsKCQlzeXN0YWItPmlvcHNbY291bnRdLmluYm91bmRfaGlnaCA9CgkJICAgIGkyb19kbWFfaGlnaChjLT5iYXNlLnBoeXMgKyBJMk9fSU5fUE9SVCk7CgoJCWNvdW50Kys7Cgl9CgoJc3lzdGFiLT5udW1fZW50cmllcyA9IGNvdW50OwoKCXJldHVybiAwOwp9OwoKLyoqCiAqCWkyb19wYXJzZV9ocnQgLSBQYXJzZSB0aGUgaGFyZHdhcmUgcmVzb3VyY2UgdGFibGUuCiAqCUBjOiBJMk8gY29udHJvbGxlcgogKgogKglXZSBkb24ndCBkbyBhbnl0aGluZyB3aXRoIGl0IGV4Y2VwdCBkdW1waW5nIGl0IChpbiBkZWJ1ZyBtb2RlKS4KICoKICoJUmV0dXJucyAwLgogKi8Kc3RhdGljIGludCBpMm9fcGFyc2VfaHJ0KHN0cnVjdCBpMm9fY29udHJvbGxlciAqYykKewoJaTJvX2R1bXBfaHJ0KGMpOwoJcmV0dXJuIDA7Cn07CgovKioKICoJaTJvX3N0YXR1c19nZXQgLSBHZXQgdGhlIHN0YXR1cyBibG9jayBmcm9tIHRoZSBJMk8gY29udHJvbGxlcgogKglAYzogSTJPIGNvbnRyb2xsZXIKICoKICoJSXNzdWUgYSBzdGF0dXMgcXVlcnkgb24gdGhlIGNvbnRyb2xsZXIuIFRoaXMgdXBkYXRlcyB0aGUgYXR0YWNoZWQKICoJc3RhdHVzIGJsb2NrLiBUaGUgc3RhdHVzIGJsb2NrIGNvdWxkIHRoZW4gYmUgYWNjZXNzZWQgdGhyb3VnaAogKgljLT5zdGF0dXNfYmxvY2suCiAqCiAqCVJldHVybnMgMCBvbiBzdWNlc3Mgb3IgbmVnYXRpdmUgZXJyb3IgY29kZSBvbiBmYWlsdXJlLgogKi8KaW50IGkyb19zdGF0dXNfZ2V0KHN0cnVjdCBpMm9fY29udHJvbGxlciAqYykKewoJc3RydWN0IGkyb19tZXNzYWdlIF9faW9tZW0gKm1zZzsKCXUzMiBtOwoJdm9sYXRpbGUgdTggKnN0YXR1c19ibG9jazsKCXVuc2lnbmVkIGxvbmcgdGltZW91dDsKCglzdGF0dXNfYmxvY2sgPSAodTggKikgYy0+c3RhdHVzX2Jsb2NrLnZpcnQ7CgltZW1zZXQoYy0+c3RhdHVzX2Jsb2NrLnZpcnQsIDAsIHNpemVvZihpMm9fc3RhdHVzX2Jsb2NrKSk7CgoJbSA9IGkyb19tc2dfZ2V0X3dhaXQoYywgJm1zZywgSTJPX1RJTUVPVVRfTUVTU0FHRV9HRVQpOwoJaWYgKG0gPT0gSTJPX1FVRVVFX0VNUFRZKQoJCXJldHVybiAtRVRJTUVET1VUOwoKCXdyaXRlbChOSU5FX1dPUkRfTVNHX1NJWkUgfCBTR0xfT0ZGU0VUXzAsICZtc2ctPnUuaGVhZFswXSk7Cgl3cml0ZWwoSTJPX0NNRF9TVEFUVVNfR0VUIDw8IDI0IHwgSE9TVF9USUQgPDwgMTIgfCBBREFQVEVSX1RJRCwKCSAgICAgICAmbXNnLT51LmhlYWRbMV0pOwoJd3JpdGVsKGkyb19leGVjX2RyaXZlci5jb250ZXh0LCAmbXNnLT51LnMuaWNudHh0KTsKCXdyaXRlbCgwLCAmbXNnLT51LnMudGNudHh0KTsJLy8gRklYTUU6IHVzZSByZXNvbmFibGUgdHJhbnNhY3Rpb24gY29udGV4dAoJd3JpdGVsKDAsICZtc2ctPmJvZHlbMF0pOwoJd3JpdGVsKDAsICZtc2ctPmJvZHlbMV0pOwoJd3JpdGVsKGkyb19kbWFfbG93KGMtPnN0YXR1c19ibG9jay5waHlzKSwgJm1zZy0+Ym9keVsyXSk7Cgl3cml0ZWwoaTJvX2RtYV9oaWdoKGMtPnN0YXR1c19ibG9jay5waHlzKSwgJm1zZy0+Ym9keVszXSk7Cgl3cml0ZWwoc2l6ZW9mKGkyb19zdGF0dXNfYmxvY2spLCAmbXNnLT5ib2R5WzRdKTsJLyogYWx3YXlzIDg4IGJ5dGVzICovCgoJaTJvX21zZ19wb3N0KGMsIG0pOwoKCS8qIFdhaXQgZm9yIGEgcmVwbHkgKi8KCXRpbWVvdXQgPSBqaWZmaWVzICsgSTJPX1RJTUVPVVRfU1RBVFVTX0dFVCAqIEhaOwoJd2hpbGUgKHN0YXR1c19ibG9ja1s4N10gIT0gMHhGRikgewoJCWlmICh0aW1lX2FmdGVyKGppZmZpZXMsIHRpbWVvdXQpKSB7CgkJCW9zbV9lcnIoIiVzOiBHZXQgc3RhdHVzIHRpbWVvdXQuXG4iLCBjLT5uYW1lKTsKCQkJcmV0dXJuIC1FVElNRURPVVQ7CgkJfQoKCQlzZXRfY3VycmVudF9zdGF0ZShUQVNLX1VOSU5URVJSVVBUSUJMRSk7CgkJc2NoZWR1bGVfdGltZW91dCgxKTsKCX0KCiNpZmRlZiBERUJVRwoJaTJvX2RlYnVnX3N0YXRlKGMpOwojZW5kaWYKCglyZXR1cm4gMDsKfQoKLyoKICoJaTJvX2hydF9nZXQgLSBHZXQgdGhlIEhhcmR3YXJlIFJlc291cmNlIFRhYmxlIGZyb20gdGhlIEkyTyBjb250cm9sbGVyCiAqCUBjOiBJMk8gY29udHJvbGxlciBmcm9tIHdoaWNoIHRoZSBIUlQgc2hvdWxkIGJlIGZldGNoZWQKICoKICoJVGhlIEhSVCBjb250YWlucyBpbmZvcm1hdGlvbiBhYm91dCBwb3NzaWJsZSBoaWRkZW4gZGV2aWNlcyBidXQgaXMKICoJbW9zdGx5IHVzZWxlc3MgdG8gdXMuCiAqCiAqCVJldHVybnMgMCBvbiBzdWNjZXNzIG9yIG5lZ2F0aXZlciBlcnJvciBjb2RlIG9uIGZhaWx1cmUuCiAqLwpzdGF0aWMgaW50IGkyb19ocnRfZ2V0KHN0cnVjdCBpMm9fY29udHJvbGxlciAqYykKewoJaW50IHJjOwoJaW50IGk7CglpMm9faHJ0ICpocnQgPSBjLT5ocnQudmlydDsKCXUzMiBzaXplID0gc2l6ZW9mKGkyb19ocnQpOwoJc3RydWN0IGRldmljZSAqZGV2ID0gJmMtPnBkZXYtPmRldjsKCglmb3IgKGkgPSAwOyBpIDwgSTJPX0hSVF9HRVRfVFJJRVM7IGkrKykgewoJCXN0cnVjdCBpMm9fbWVzc2FnZSBfX2lvbWVtICptc2c7CgkJdTMyIG07CgoJCW0gPSBpMm9fbXNnX2dldF93YWl0KGMsICZtc2csIEkyT19USU1FT1VUX01FU1NBR0VfR0VUKTsKCQlpZiAobSA9PSBJMk9fUVVFVUVfRU1QVFkpCgkJCXJldHVybiAtRVRJTUVET1VUOwoKCQl3cml0ZWwoU0lYX1dPUkRfTVNHX1NJWkUgfCBTR0xfT0ZGU0VUXzQsICZtc2ctPnUuaGVhZFswXSk7CgkJd3JpdGVsKEkyT19DTURfSFJUX0dFVCA8PCAyNCB8IEhPU1RfVElEIDw8IDEyIHwgQURBUFRFUl9USUQsCgkJICAgICAgICZtc2ctPnUuaGVhZFsxXSk7CgkJd3JpdGVsKDB4ZDAwMDAwMDAgfCBjLT5ocnQubGVuLCAmbXNnLT5ib2R5WzBdKTsKCQl3cml0ZWwoYy0+aHJ0LnBoeXMsICZtc2ctPmJvZHlbMV0pOwoKCQlyYyA9IGkyb19tc2dfcG9zdF93YWl0X21lbShjLCBtLCAyMCwgJmMtPmhydCk7CgoJCWlmIChyYyA8IDApIHsKCQkJb3NtX2VycigiJXM6IFVuYWJsZSB0byBnZXQgSFJUIChzdGF0dXM9JSN4KVxuIiwgYy0+bmFtZSwKCQkJCS1yYyk7CgkJCXJldHVybiByYzsKCQl9CgoJCXNpemUgPSBocnQtPm51bV9lbnRyaWVzICogaHJ0LT5lbnRyeV9sZW4gPDwgMjsKCQlpZiAoc2l6ZSA+IGMtPmhydC5sZW4pIHsKCQkJaWYgKGkyb19kbWFfcmVhbGxvYyhkZXYsICZjLT5ocnQsIHNpemUsIEdGUF9LRVJORUwpKQoJCQkJcmV0dXJuIC1FTk9NRU07CgkJCWVsc2UKCQkJCWhydCA9IGMtPmhydC52aXJ0OwoJCX0gZWxzZQoJCQlyZXR1cm4gaTJvX3BhcnNlX2hydChjKTsKCX0KCglvc21fZXJyKCIlczogVW5hYmxlIHRvIGdldCBIUlQgYWZ0ZXIgJWQgdHJpZXMsIGdpdmluZyB1cFxuIiwgYy0+bmFtZSwKCQlJMk9fSFJUX0dFVF9UUklFUyk7CgoJcmV0dXJuIC1FQlVTWTsKfQoKLyoqCiAqCWkyb19pb3BfZnJlZSAtIEZyZWUgdGhlIGkyb19jb250cm9sbGVyIHN0cnVjdAogKglAYzogSTJPIGNvbnRyb2xsZXIgdG8gZnJlZQogKi8Kdm9pZCBpMm9faW9wX2ZyZWUoc3RydWN0IGkyb19jb250cm9sbGVyICpjKQp7CglrZnJlZShjKTsKfTsKCi8qKgogKglpMm9faW9wX3JlbGVhc2UgLSByZWxlYXNlIHRoZSBtZW1vcnkgZm9yIGEgSTJPIGNvbnRyb2xsZXIKICoJQGRldjogSTJPIGNvbnRyb2xsZXIgd2hpY2ggc2hvdWxkIGJlIHJlbGVhc2VkCiAqCiAqCVJlbGVhc2UgdGhlIGFsbG9jYXRlZCBtZW1vcnkuIFRoaXMgZnVuY3Rpb24gaXMgY2FsbGVkIGlmIHJlZmNvdW50IG9mCiAqCWRldmljZSByZWFjaGVzIDAgYXV0b21hdGljYWxseS4KICovCnN0YXRpYyB2b2lkIGkyb19pb3BfcmVsZWFzZShzdHJ1Y3QgZGV2aWNlICpkZXYpCnsKCXN0cnVjdCBpMm9fY29udHJvbGxlciAqYyA9IHRvX2kyb19jb250cm9sbGVyKGRldik7CgoJaTJvX2lvcF9mcmVlKGMpOwp9OwoKLyogSTJPIGNvbnRyb2xsZXIgY2xhc3MgKi8Kc3RhdGljIHN0cnVjdCBjbGFzcyBpMm9fY29udHJvbGxlcl9jbGFzcyA9IHsKCS5uYW1lID0gImkyb19jb250cm9sbGVyIiwKfTsKCi8qKgogKglpMm9faW9wX2FsbG9jIC0gQWxsb2NhdGUgYW5kIGluaXRpYWxpemUgYSBpMm9fY29udHJvbGxlciBzdHJ1Y3QKICoKICoJQWxsb2NhdGUgdGhlIG5lY2Vzc2FyeSBtZW1vcnkgZm9yIGEgaTJvX2NvbnRyb2xsZXIgc3RydWN0IGFuZAogKglpbml0aWFsaXplIHRoZSBsaXN0cy4KICoKICoJUmV0dXJucyBhIHBvaW50ZXIgdG8gdGhlIEkyTyBjb250cm9sbGVyIG9yIGEgbmVnYXRpdmUgZXJyb3IgY29kZSBvbgogKglmYWlsdXJlLgogKi8Kc3RydWN0IGkyb19jb250cm9sbGVyICppMm9faW9wX2FsbG9jKHZvaWQpCnsKCXN0YXRpYyBpbnQgdW5pdCA9IDA7CS8qIDAgYW5kIDEgYXJlIE5VTEwgSU9QIGFuZCBMb2NhbCBIb3N0ICovCglzdHJ1Y3QgaTJvX2NvbnRyb2xsZXIgKmM7CgoJYyA9IGttYWxsb2Moc2l6ZW9mKCpjKSwgR0ZQX0tFUk5FTCk7CglpZiAoIWMpIHsKCQlvc21fZXJyKCJpMm86IEluc3VmZmljaWVudCBtZW1vcnkgdG8gYWxsb2NhdGUgYSBJMk8gY29udHJvbGxlci4iCgkJCSJcbiIpOwoJCXJldHVybiBFUlJfUFRSKC1FTk9NRU0pOwoJfQoJbWVtc2V0KGMsIDAsIHNpemVvZigqYykpOwoKCUlOSVRfTElTVF9IRUFEKCZjLT5kZXZpY2VzKTsKCXNwaW5fbG9ja19pbml0KCZjLT5sb2NrKTsKCWluaXRfTVVURVgoJmMtPmxjdF9sb2NrKTsKCWMtPnVuaXQgPSB1bml0Kys7CglzcHJpbnRmKGMtPm5hbWUsICJpb3AlZCIsIGMtPnVuaXQpOwoKCWRldmljZV9pbml0aWFsaXplKCZjLT5kZXZpY2UpOwoJY2xhc3NfZGV2aWNlX2luaXRpYWxpemUoJmMtPmNsYXNzZGV2KTsKCgljLT5kZXZpY2UucmVsZWFzZSA9ICZpMm9faW9wX3JlbGVhc2U7CgljLT5jbGFzc2Rldi5jbGFzcyA9ICZpMm9fY29udHJvbGxlcl9jbGFzczsKCWMtPmNsYXNzZGV2LmRldiA9ICZjLT5kZXZpY2U7CgoJc25wcmludGYoYy0+ZGV2aWNlLmJ1c19pZCwgQlVTX0lEX1NJWkUsICJpb3AlZCIsIGMtPnVuaXQpOwoJc25wcmludGYoYy0+Y2xhc3NkZXYuY2xhc3NfaWQsIEJVU19JRF9TSVpFLCAiaW9wJWQiLCBjLT51bml0KTsKCiNpZiBCSVRTX1BFUl9MT05HID09IDY0CglzcGluX2xvY2tfaW5pdCgmYy0+Y29udGV4dF9saXN0X2xvY2spOwoJYXRvbWljX3NldCgmYy0+Y29udGV4dF9saXN0X2NvdW50ZXIsIDApOwoJSU5JVF9MSVNUX0hFQUQoJmMtPmNvbnRleHRfbGlzdCk7CiNlbmRpZgoKCXJldHVybiBjOwp9OwoKLyoqCiAqCWkyb19pb3BfYWRkIC0gSW5pdGlhbGl6ZSB0aGUgSTJPIGNvbnRyb2xsZXIgYW5kIGFkZCBoaW0gdG8gdGhlIEkyTyBjb3JlCiAqCUBjOiBjb250cm9sbGVyCiAqCiAqCUluaXRpYWxpemUgdGhlIEkyTyBjb250cm9sbGVyIGFuZCBpZiBubyBlcnJvciBvY2N1cnMgYWRkIGhpbSB0byB0aGUgSTJPCiAqCWNvcmUuCiAqCiAqCVJldHVybnMgMCBvbiBzdWNjZXNzIG9yIG5lZ2F0aXZlIGVycm9yIGNvZGUgb24gZmFpbHVyZS4KICovCmludCBpMm9faW9wX2FkZChzdHJ1Y3QgaTJvX2NvbnRyb2xsZXIgKmMpCnsKCWludCByYzsKCglpZiAoKHJjID0gZGV2aWNlX2FkZCgmYy0+ZGV2aWNlKSkpIHsKCQlvc21fZXJyKCIlczogY291bGQgbm90IGFkZCBjb250cm9sbGVyXG4iLCBjLT5uYW1lKTsKCQlnb3RvIGlvcF9yZXNldDsKCX0KCglpZiAoKHJjID0gY2xhc3NfZGV2aWNlX2FkZCgmYy0+Y2xhc3NkZXYpKSkgewoJCW9zbV9lcnIoIiVzOiBjb3VsZCBub3QgYWRkIGNvbnRyb2xsZXIgY2xhc3NcbiIsIGMtPm5hbWUpOwoJCWdvdG8gZGV2aWNlX2RlbDsKCX0KCglvc21faW5mbygiJXM6IEFjdGl2YXRpbmcgSTJPIGNvbnRyb2xsZXIuLi5cbiIsIGMtPm5hbWUpOwoJb3NtX2luZm8oIiVzOiBUaGlzIG1heSB0YWtlIGEgZmV3IG1pbnV0ZXMgaWYgdGhlcmUgYXJlIG1hbnkgZGV2aWNlc1xuIiwKCQkgYy0+bmFtZSk7CgoJaWYgKChyYyA9IGkyb19pb3BfYWN0aXZhdGUoYykpKSB7CgkJb3NtX2VycigiJXM6IGNvdWxkIG5vdCBhY3RpdmF0ZSBjb250cm9sbGVyXG4iLCBjLT5uYW1lKTsKCQlnb3RvIGNsYXNzX2RlbDsKCX0KCglvc21fZGVidWcoIiVzOiBidWlsZGluZyBzeXMgdGFibGUuLi5cbiIsIGMtPm5hbWUpOwoKCWlmICgocmMgPSBpMm9fc3lzdGFiX2J1aWxkKCkpKQoJCWdvdG8gY2xhc3NfZGVsOwoKCW9zbV9kZWJ1ZygiJXM6IG9ubGluZSBjb250cm9sbGVyLi4uXG4iLCBjLT5uYW1lKTsKCglpZiAoKHJjID0gaTJvX2lvcF9vbmxpbmUoYykpKQoJCWdvdG8gY2xhc3NfZGVsOwoKCW9zbV9kZWJ1ZygiJXM6IGdldHRpbmcgTENULi4uXG4iLCBjLT5uYW1lKTsKCglpZiAoKHJjID0gaTJvX2V4ZWNfbGN0X2dldChjKSkpCgkJZ290byBjbGFzc19kZWw7CgoJbGlzdF9hZGQoJmMtPmxpc3QsICZpMm9fY29udHJvbGxlcnMpOwoKCWkyb19kcml2ZXJfbm90aWZ5X2NvbnRyb2xsZXJfYWRkX2FsbChjKTsKCglvc21faW5mbygiJXM6IENvbnRyb2xsZXIgYWRkZWRcbiIsIGMtPm5hbWUpOwoKCXJldHVybiAwOwoKICAgICAgY2xhc3NfZGVsOgoJY2xhc3NfZGV2aWNlX2RlbCgmYy0+Y2xhc3NkZXYpOwoKICAgICAgZGV2aWNlX2RlbDoKCWRldmljZV9kZWwoJmMtPmRldmljZSk7CgogICAgICBpb3BfcmVzZXQ6CglpMm9faW9wX3Jlc2V0KGMpOwoKCXJldHVybiByYzsKfTsKCi8qKgogKglpMm9fZXZlbnRfcmVnaXN0ZXIgLSBUdXJuIG9uL29mZiBldmVudCBub3RpZmljYXRpb24gZm9yIGEgSTJPIGRldmljZQogKglAZGV2OiBJMk8gZGV2aWNlIHdoaWNoIHNob3VsZCByZWNlaXZlIHRoZSBldmVudCByZWdpc3RyYXRpb24gcmVxdWVzdAogKglAZHJ2OiBkcml2ZXIgd2hpY2ggd2FudCB0byBnZXQgbm90aWZpZWQKICoJQHRjbnR4dDogdHJhbnNhY3Rpb24gY29udGV4dCB0byB1c2Ugd2l0aCB0aGlzIG5vdGlmaWVyCiAqCUBldnRfbWFzazogbWFzayBvZiBldmVudHMKICoKICoJQ3JlYXRlIGFuZCBwb3N0cyBhbiBldmVudCByZWdpc3RyYXRpb24gbWVzc2FnZSB0byB0aGUgdGFzay4gTm8gcmVwbHkKICoJaXMgd2FpdGVkIGZvciwgb3IgZXhwZWN0ZWQuIElmIHlvdSBkbyBub3Qgd2FudCBmdXJ0aGVyIG5vdGlmaWNhdGlvbnMsCiAqCWNhbGwgdGhlIGkyb19ldmVudF9yZWdpc3RlciBhZ2FpbiB3aXRoIGEgZXZ0X21hc2sgb2YgMC4KICoKICoJUmV0dXJucyAwIG9uIHN1Y2Nlc3Mgb3IgLUVUSU1FRE9VVCBpZiBubyBtZXNzYWdlIGNvdWxkIGJlIGZldGNoZWQgZm9yCiAqCXNlbmRpbmcgdGhlIHJlcXVlc3QuCiAqLwppbnQgaTJvX2V2ZW50X3JlZ2lzdGVyKHN0cnVjdCBpMm9fZGV2aWNlICpkZXYsIHN0cnVjdCBpMm9fZHJpdmVyICpkcnYsCgkJICAgICAgIGludCB0Y250eHQsIHUzMiBldnRfbWFzaykKewoJc3RydWN0IGkyb19jb250cm9sbGVyICpjID0gZGV2LT5pb3A7CglzdHJ1Y3QgaTJvX21lc3NhZ2UgX19pb21lbSAqbXNnOwoJdTMyIG07CgoJbSA9IGkyb19tc2dfZ2V0X3dhaXQoYywgJm1zZywgSTJPX1RJTUVPVVRfTUVTU0FHRV9HRVQpOwoJaWYgKG0gPT0gSTJPX1FVRVVFX0VNUFRZKQoJCXJldHVybiAtRVRJTUVET1VUOwoKCXdyaXRlbChGSVZFX1dPUkRfTVNHX1NJWkUgfCBTR0xfT0ZGU0VUXzAsICZtc2ctPnUuaGVhZFswXSk7Cgl3cml0ZWwoSTJPX0NNRF9VVElMX0VWVF9SRUdJU1RFUiA8PCAyNCB8IEhPU1RfVElEIDw8IDEyIHwgZGV2LT5sY3RfZGF0YS4KCSAgICAgICB0aWQsICZtc2ctPnUuaGVhZFsxXSk7Cgl3cml0ZWwoZHJ2LT5jb250ZXh0LCAmbXNnLT51LnMuaWNudHh0KTsKCXdyaXRlbCh0Y250eHQsICZtc2ctPnUucy50Y250eHQpOwoJd3JpdGVsKGV2dF9tYXNrLCAmbXNnLT5ib2R5WzBdKTsKCglpMm9fbXNnX3Bvc3QoYywgbSk7CgoJcmV0dXJuIDA7Cn07CgovKioKICoJaTJvX2lvcF9pbml0IC0gSTJPIG1haW4gaW5pdGlhbGl6YXRpb24gZnVuY3Rpb24KICoKICoJSW5pdGlhbGl6ZSB0aGUgSTJPIGRyaXZlcnMgKE9TTSkgZnVuY3Rpb25zLCByZWdpc3RlciB0aGUgRXhlY3V0aXZlIE9TTSwKICoJaW5pdGlhbGl6ZSB0aGUgSTJPIFBDSSBwYXJ0IGFuZCBmaW5hbGx5IGluaXRpYWxpemUgSTJPIGRldmljZSBzdHVmZi4KICoKICoJUmV0dXJucyAwIG9uIHN1Y2Nlc3Mgb3IgbmVnYXRpdmUgZXJyb3IgY29kZSBvbiBmYWlsdXJlLgogKi8Kc3RhdGljIGludCBfX2luaXQgaTJvX2lvcF9pbml0KHZvaWQpCnsKCWludCByYyA9IDA7CgoJcHJpbnRrKEtFUk5fSU5GTyBPU01fREVTQ1JJUFRJT04gIiB2IiBPU01fVkVSU0lPTiAiXG4iKTsKCglyYyA9IGkyb19kZXZpY2VfaW5pdCgpOwoJaWYgKHJjKQoJCWdvdG8gZXhpdDsKCglpZiAoKHJjID0gY2xhc3NfcmVnaXN0ZXIoJmkyb19jb250cm9sbGVyX2NsYXNzKSkpIHsKCQlvc21fZXJyKCJjYW4ndCByZWdpc3RlciBjbGFzcyBpMm9fY29udHJvbGxlclxuIik7CgkJZ290byBkZXZpY2VfZXhpdDsKCX0KCglpZiAoKHJjID0gaTJvX2RyaXZlcl9pbml0KCkpKQoJCWdvdG8gY2xhc3NfZXhpdDsKCglpZiAoKHJjID0gaTJvX2V4ZWNfaW5pdCgpKSkKCQlnb3RvIGRyaXZlcl9leGl0OwoKCWlmICgocmMgPSBpMm9fcGNpX2luaXQoKSkpCgkJZ290byBleGVjX2V4aXQ7CgoJcmV0dXJuIDA7CgogICAgICBleGVjX2V4aXQ6CglpMm9fZXhlY19leGl0KCk7CgogICAgICBkcml2ZXJfZXhpdDoKCWkyb19kcml2ZXJfZXhpdCgpOwoKICAgICAgY2xhc3NfZXhpdDoKCWNsYXNzX3VucmVnaXN0ZXIoJmkyb19jb250cm9sbGVyX2NsYXNzKTsKCiAgICAgIGRldmljZV9leGl0OgoJaTJvX2RldmljZV9leGl0KCk7CgogICAgICBleGl0OgoJcmV0dXJuIHJjOwp9CgovKioKICoJaTJvX2lvcF9leGl0IC0gSTJPIG1haW4gZXhpdCBmdW5jdGlvbgogKgogKglSZW1vdmVzIEkyTyBjb250cm9sbGVycyBmcm9tIFBDSSBzdWJzeXN0ZW0gYW5kIHNodXQgZG93biBPU01zLgogKi8Kc3RhdGljIHZvaWQgX19leGl0IGkyb19pb3BfZXhpdCh2b2lkKQp7CglpMm9fcGNpX2V4aXQoKTsKCWkyb19leGVjX2V4aXQoKTsKCWkyb19kcml2ZXJfZXhpdCgpOwoJY2xhc3NfdW5yZWdpc3RlcigmaTJvX2NvbnRyb2xsZXJfY2xhc3MpOwoJaTJvX2RldmljZV9leGl0KCk7Cn07Cgptb2R1bGVfaW5pdChpMm9faW9wX2luaXQpOwptb2R1bGVfZXhpdChpMm9faW9wX2V4aXQpOwoKTU9EVUxFX0FVVEhPUigiUmVkIEhhdCBTb2Z0d2FyZSIpOwpNT0RVTEVfTElDRU5TRSgiR1BMIik7Ck1PRFVMRV9ERVNDUklQVElPTihPU01fREVTQ1JJUFRJT04pOwpNT0RVTEVfVkVSU0lPTihPU01fVkVSU0lPTik7CgojaWYgQklUU19QRVJfTE9ORyA9PSA2NApFWFBPUlRfU1lNQk9MKGkyb19jbnR4dF9saXN0X2FkZCk7CkVYUE9SVF9TWU1CT0woaTJvX2NudHh0X2xpc3RfZ2V0KTsKRVhQT1JUX1NZTUJPTChpMm9fY250eHRfbGlzdF9yZW1vdmUpOwpFWFBPUlRfU1lNQk9MKGkyb19jbnR4dF9saXN0X2dldF9wdHIpOwojZW5kaWYKRVhQT1JUX1NZTUJPTChpMm9fbXNnX2dldF93YWl0KTsKRVhQT1JUX1NZTUJPTChpMm9fbXNnX25vcCk7CkVYUE9SVF9TWU1CT0woaTJvX2ZpbmRfaW9wKTsKRVhQT1JUX1NZTUJPTChpMm9faW9wX2ZpbmRfZGV2aWNlKTsKRVhQT1JUX1NZTUJPTChpMm9fZXZlbnRfcmVnaXN0ZXIpOwpFWFBPUlRfU1lNQk9MKGkyb19zdGF0dXNfZ2V0KTsKRVhQT1JUX1NZTUJPTChpMm9fY29udHJvbGxlcnMpOwo=