LyoKICogbGludXgvZHJpdmVycy9zMzkwL2Npby9jbWYuYwogKgogKiBMaW51eCBvbiB6U2VyaWVzIENoYW5uZWwgTWVhc3VyZW1lbnQgRmFjaWxpdHkgc3VwcG9ydAogKgogKiBDb3B5cmlnaHQgMjAwMCwyMDAzIElCTSBDb3Jwb3JhdGlvbgogKgogKiBBdXRob3I6IEFybmQgQmVyZ21hbm4gPGFybmRiQGRlLmlibS5jb20+CiAqCiAqIG9yaWdpbmFsIGlkZWEgZnJvbSBOYXRhcmFqYW4gS3Jpc2huYXN3YW1pIDxua3Jpc2huYUB1cy5pYm0uY29tPgogKgogKiBUaGlzIHByb2dyYW0gaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeQogKiBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieQogKiB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIgdmVyc2lvbiAyLCBvciAoYXQgeW91ciBvcHRpb24pCiAqIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZQogKiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiBhbG9uZyB3aXRoIHRoaXMgcHJvZ3JhbTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZQogKiBGb3VuZGF0aW9uLCBJbmMuLCA2NzUgTWFzcyBBdmUsIENhbWJyaWRnZSwgTUEgMDIxMzksIFVTQS4KICovCgojaW5jbHVkZSA8bGludXgvYm9vdG1lbS5oPgojaW5jbHVkZSA8bGludXgvZGV2aWNlLmg+CiNpbmNsdWRlIDxsaW51eC9pbml0Lmg+CiNpbmNsdWRlIDxsaW51eC9saXN0Lmg+CiNpbmNsdWRlIDxsaW51eC9tb2R1bGUuaD4KI2luY2x1ZGUgPGxpbnV4L21vZHVsZXBhcmFtLmg+CiNpbmNsdWRlIDxsaW51eC9zbGFiLmg+CiNpbmNsdWRlIDxsaW51eC90aW1leC5oPgkvKiBnZXRfY2xvY2soKSAqLwoKI2luY2x1ZGUgPGFzbS9jY3dkZXYuaD4KI2luY2x1ZGUgPGFzbS9jaW8uaD4KI2luY2x1ZGUgPGFzbS9jbWIuaD4KI2luY2x1ZGUgPGFzbS9kaXY2NC5oPgoKI2luY2x1ZGUgImNpby5oIgojaW5jbHVkZSAiY3NzLmgiCiNpbmNsdWRlICJkZXZpY2UuaCIKI2luY2x1ZGUgImlvYXNtLmgiCiNpbmNsdWRlICJjaHNjLmgiCgovKiBwYXJhbWV0ZXIgdG8gZW5hYmxlIGNtZiBkdXJpbmcgYm9vdCwgcG9zc2libGUgdXNlcyBhcmU6CiAqICAiczM5MGNtZiIgLS0gZW5hYmxlIGNtZiBhbmQgYWxsb2NhdGUgMiBNQiBvZiByYW0gc28gbWVhc3VyaW5nIGNhbiBiZQogKiAgICAgICAgICAgICAgIHVzZWQgb24gYW55IHN1YmNoYW5uZWwKICogICJzMzkwY21mPTxudW0+IiAtLSBlbmFibGUgY21mIGFuZCBhbGxvY2F0ZSBlbm91Z2ggbWVtb3J5IHRvIG1lYXN1cmUKICogICAgICAgICAgICAgICAgICAgICA8bnVtPiBzdWJjaGFubmVsLCB3aGVyZSA8bnVtPiBpcyBhbiBpbnRlZ2VyCiAqICAgICAgICAgICAgICAgICAgICAgYmV0d2VlbiAxIGFuZCA2NTUzNSwgZGVmYXVsdCBpcyAxMDI0CiAqLwojZGVmaW5lIEFSR1NUUklORyAiczM5MGNtZiIKCi8qIGluZGljZXMgZm9yIFJFQURDTUIgKi8KZW51bSBjbWJfaW5kZXggewogLyogYmFzaWMgYW5kIGV4ZW5kZWQgZm9ybWF0OiAqLwoJY21iX3NzY2hfcnNjaF9jb3VudCwKCWNtYl9zYW1wbGVfY291bnQsCgljbWJfZGV2aWNlX2Nvbm5lY3RfdGltZSwKCWNtYl9mdW5jdGlvbl9wZW5kaW5nX3RpbWUsCgljbWJfZGV2aWNlX2Rpc2Nvbm5lY3RfdGltZSwKCWNtYl9jb250cm9sX3VuaXRfcXVldWluZ190aW1lLAoJY21iX2RldmljZV9hY3RpdmVfb25seV90aW1lLAogLyogZXh0ZW5kZWQgZm9ybWF0IG9ubHk6ICovCgljbWJfZGV2aWNlX2J1c3lfdGltZSwKCWNtYl9pbml0aWFsX2NvbW1hbmRfcmVzcG9uc2VfdGltZSwKfTsKCi8qKgogKiBlbnVtIGNtYl9mb3JtYXQgLSB0eXBlcyBvZiBzdXBwb3J0ZWQgbWVhc3VyZW1lbnQgYmxvY2sgZm9ybWF0cwogKgogKiBAQ01GX0JBU0lDOiAgICAgIHRyYWRpdGlvbmFsIGNoYW5uZWwgbWVhc3VyZW1lbnQgYmxvY2tzIHN1cHBvcnRlZAogKiAJCSAgICBieSBhbGwgbWFjaGluZXMgdGhhdCB3ZSBydW4gb24KICogQENNRl9FWFRFTkRFRDogICBpbXByb3ZlZCBmb3JtYXQgdGhhdCB3YXMgaW50cm9kdWNlZCB3aXRoIHRoZSB6OTkwCiAqIAkJICAgIG1hY2hpbmUKICogQENNRl9BVVRPREVURUNUOiBkZWZhdWx0OiB1c2UgZXh0ZW5kZWQgZm9ybWF0IHdoZW4gcnVubmluZyBvbiBhIHo5OTAKICogICAgICAgICAgICAgICAgICBvciBsYXRlciBtYWNoaW5lLCBvdGhlcndpc2UgZmFsbCBiYWNrIHRvIGJhc2ljIGZvcm1hdAogKiovCmVudW0gY21iX2Zvcm1hdCB7CglDTUZfQkFTSUMsCglDTUZfRVhURU5ERUQsCglDTUZfQVVUT0RFVEVDVCA9IC0xLAp9OwovKioKICogZm9ybWF0IC0gYWN0dWFsIGZvcm1hdCBmb3IgYWxsIG1lYXN1cmVtZW50IGJsb2NrcwogKgogKiBUaGUgZm9ybWF0IG1vZHVsZSBwYXJhbWV0ZXIgY2FuIGJlIHNldCB0byBhIHZhbHVlIG9mIDAgKHplcm8pCiAqIG9yIDEsIGluZGljYXRpbmcgYmFzaWMgb3IgZXh0ZW5kZWQgZm9ybWF0IGFzIGRlc2NyaWJlZCBmb3IKICogZW51bSBjbWJfZm9ybWF0LgogKi8Kc3RhdGljIGludCBmb3JtYXQgPSBDTUZfQVVUT0RFVEVDVDsKbW9kdWxlX3BhcmFtKGZvcm1hdCwgYm9vbCwgMDQ0NCk7CgovKioKICogc3RydWN0IGNtYl9vcGVyYXRpb25zIC0gZnVuY3Rpb25zIHRvIHVzZSBkZXBlbmRpbmcgb24gY21iX2Zvcm1hdAogKgogKiBhbGwgdGhlc2UgZnVuY3Rpb25zIG9wZXJhdGUgb24gYSBzdHJ1Y3QgY21mX2RldmljZS4gVGhlcmUgaXMgb25seQogKiBvbmUgaW5zdGFuY2Ugb2Ygc3RydWN0IGNtYl9vcGVyYXRpb25zIGJlY2F1c2UgYWxsIGNtZl9kZXZpY2UKICogb2JqZWN0cyBhcmUgZ3VhcmFudGVlZCB0byBiZSBvZiB0aGUgc2FtZSB0eXBlLgogKgogKiBAYWxsb2M6CWFsbG9jYXRlIG1lbW9yeSBmb3IgYSBjaGFubmVsIG1lYXN1cmVtZW50IGJsb2NrLAogKgkJZWl0aGVyIHdpdGggdGhlIGhlbHAgb2YgYSBzcGVjaWFsIHBvb2wgb3Igd2l0aCBrbWFsbG9jCiAqIEBmcmVlOglmcmVlIG1lbW9yeSBhbGxvY2F0ZWQgd2l0aCBAYWxsb2MKICogQHNldDoJZW5hYmxlIG9yIGRpc2FibGUgbWVhc3VyZW1lbnQKICogQHJlYWRhbGw6CXJlYWQgYSBtZWFzdXJlbWVudCBibG9jayBpbiBhIGNvbW1vbiBmb3JtYXQKICogQHJlc2V0OgljbGVhciB0aGUgZGF0YSBpbiB0aGUgYXNzb2NpYXRlZCBtZWFzdXJlbWVudCBibG9jayBhbmQKICoJCXJlc2V0IGl0cyB0aW1lIHN0YW1wCiAqLwpzdHJ1Y3QgY21iX29wZXJhdGlvbnMgewoJaW50ICgqYWxsb2MpICAoc3RydWN0IGNjd19kZXZpY2UqKTsKCXZvaWQoKmZyZWUpICAgKHN0cnVjdCBjY3dfZGV2aWNlKik7CglpbnQgKCpzZXQpICAgIChzdHJ1Y3QgY2N3X2RldmljZSosIHUzMik7Cgl1NjQgKCpyZWFkKSAgIChzdHJ1Y3QgY2N3X2RldmljZSosIGludCk7CglpbnQgKCpyZWFkYWxsKShzdHJ1Y3QgY2N3X2RldmljZSosIHN0cnVjdCBjbWJkYXRhICopOwoJdm9pZCAoKnJlc2V0KSAoc3RydWN0IGNjd19kZXZpY2UqKTsKCglzdHJ1Y3QgYXR0cmlidXRlX2dyb3VwICphdHRyX2dyb3VwOwp9OwpzdGF0aWMgc3RydWN0IGNtYl9vcGVyYXRpb25zICpjbWJvcHM7CgovKiBvdXIgdXNlciBpbnRlcmZhY2UgaXMgZGVzaWduZWQgaW4gdGVybXMgb2YgbmFub3NlY29uZHMsCiAqIHdoaWxlIHRoZSBoYXJkd2FyZSBtZWFzdXJlcyB0b3RhbCB0aW1lcyBpbiBpdHMgb3duCiAqIHVuaXQuKi8Kc3RhdGljIGlubGluZSB1NjQgdGltZV90b19uc2VjKHUzMiB2YWx1ZSkKewoJcmV0dXJuICgodTY0KXZhbHVlKSAqIDEyODAwMHVsbDsKfQoKLyoKICogVXNlcnMgYXJlIHVzdWFsbHkgaW50ZXJlc3RlZCBpbiBhdmVyYWdlIHRpbWVzLAogKiBub3QgYWNjdW11bGF0ZWQgdGltZS4KICogVGhpcyBhbHNvIGhlbHBzIHVzIHdpdGggYXRvbWljaXR5IHByb2JsZW1zCiAqIHdoZW4gcmVhZGluZyBzaW5sZ2UgdmFsdWVzLgogKi8Kc3RhdGljIGlubGluZSB1NjQgdGltZV90b19hdmdfbnNlYyh1MzIgdmFsdWUsIHUzMiBjb3VudCkKewoJdTY0IHJldDsKCgkvKiBubyBzYW1wbGVzIHlldCwgYXZvaWQgZGl2aXNpb24gYnkgMCAqLwoJaWYgKGNvdW50ID09IDApCgkJcmV0dXJuIDA7CgoJLyogdmFsdWUgY29tZXMgaW4gdW5pdHMgb2YgMTI4ILVzZWMgKi8KCXJldCA9IHRpbWVfdG9fbnNlYyh2YWx1ZSk7Cglkb19kaXYocmV0LCBjb3VudCk7CgoJcmV0dXJuIHJldDsKfQoKLyogYWN0aXZhdGUgb3IgZGVhY3RpdmF0ZSB0aGUgY2hhbm5lbCBtb25pdG9yLiBXaGVuIGFyZWEgaXMgTlVMTCwKICogdGhlIG1vbml0b3IgaXMgZGVhY3RpdmF0ZWQuIFRoZSBjaGFubmVsIG1vbml0b3IgbmVlZHMgdG8KICogYmUgYWN0aXZlIGluIG9yZGVyIHRvIG1lYXN1cmUgc3ViY2hhbm5lbHMsIHdoaWNoIGFsc28gbmVlZAogKiB0byBiZSBlbmFibGVkLiAqLwpzdGF0aWMgaW5saW5lIHZvaWQKY21mX2FjdGl2YXRlKHZvaWQgKmFyZWEsIHVuc2lnbmVkIGludCBvbm9mZikKewoJcmVnaXN0ZXIgdm9pZCAqIF9fZ3ByMiBhc20oIjIiKTsKCXJlZ2lzdGVyIGxvbmcgX19ncHIxIGFzbSgiMSIpOwoKCV9fZ3ByMiA9IGFyZWE7CglfX2dwcjEgPSBvbm9mZiA/IDIgOiAwOwoJLyogYWN0aXZhdGUgY2hhbm5lbCBtZWFzdXJlbWVudCAqLwoJYXNtKCJzY2htIiA6IDogImQiIChfX2dwcjIpLCAiZCIgKF9fZ3ByMSkgKTsKfQoKc3RhdGljIGludApzZXRfc2NoaWIoc3RydWN0IGNjd19kZXZpY2UgKmNkZXYsIHUzMiBtbWUsIGludCBtYmZjLCB1bnNpZ25lZCBsb25nIGFkZHJlc3MpCnsKCWludCByZXQ7CglpbnQgcmV0cnk7CglzdHJ1Y3Qgc3ViY2hhbm5lbCAqc2NoOwoJc3RydWN0IHNjaGliICpzY2hpYjsKCglzY2ggPSB0b19zdWJjaGFubmVsKGNkZXYtPmRldi5wYXJlbnQpOwoJc2NoaWIgPSAmc2NoLT5zY2hpYjsKCS8qIG1zY2ggY2FuIHNpbGVudGx5IGZhaWwsIHNvIGRvIGl0IGFnYWluIGlmIG5lY2Vzc2FyeSAqLwoJZm9yIChyZXRyeSA9IDA7IHJldHJ5IDwgMzsgcmV0cnkrKykgewoJCS8qIHByZXBhcmUgc2NoaWIgKi8KCQlzdHNjaChzY2gtPnNjaGlkLCBzY2hpYik7CgkJc2NoaWItPnBtY3cubW1lICA9IG1tZTsKCQlzY2hpYi0+cG1jdy5tYmZjID0gbWJmYzsKCQkvKiBhZGRyZXNzIGNhbiBiZSBlaXRoZXIgYSBibG9jayBhZGRyZXNzIG9yIGEgYmxvY2sgaW5kZXggKi8KCQlpZiAobWJmYykKCQkJc2NoaWItPm1iYSA9IGFkZHJlc3M7CgkJZWxzZQoJCQlzY2hpYi0+cG1jdy5tYmkgPSBhZGRyZXNzOwoKCQkvKiB0cnkgdG8gc3VibWl0IGl0ICovCgkJc3dpdGNoKHJldCA9IG1zY2hfZXJyKHNjaC0+c2NoaWQsIHNjaGliKSkgewoJCQljYXNlIDA6CgkJCQlicmVhazsKCQkJY2FzZSAxOgoJCQljYXNlIDI6IC8qIGluIEkvTyBvciBzdGF0dXMgcGVuZGluZyAqLwoJCQkJcmV0ID0gLUVCVVNZOwoJCQkJYnJlYWs7CgkJCWNhc2UgMzogLyogc3ViY2hhbm5lbCBpcyBubyBsb25nZXIgdmFsaWQgKi8KCQkJCXJldCA9IC1FTk9ERVY7CgkJCQlicmVhazsKCQkJZGVmYXVsdDogLyogbXNjaCBjYXVnaHQgYW4gZXhjZXB0aW9uICovCgkJCQlyZXQgPSAtRUlOVkFMOwoJCQkJYnJlYWs7CgkJfQoJCXN0c2NoKHNjaC0+c2NoaWQsIHNjaGliKTsgLyogcmVzdG9yZSB0aGUgc2NoaWIgKi8KCgkJaWYgKHJldCkKCQkJYnJlYWs7CgoJCS8qIGNoZWNrIGlmIGl0IHdvcmtlZCAqLwoJCWlmIChzY2hpYi0+cG1jdy5tbWUgID09IG1tZSAmJgoJCSAgICBzY2hpYi0+cG1jdy5tYmZjID09IG1iZmMgJiYKCQkgICAgKG1iZmMgPyAoc2NoaWItPm1iYSA9PSBhZGRyZXNzKQoJCQkgIDogKHNjaGliLT5wbWN3Lm1iaSA9PSBhZGRyZXNzKSkpCgkJCXJldHVybiAwOwoKCQlyZXQgPSAtRUlOVkFMOwoJfQoKCXJldHVybiByZXQ7Cn0KCnN0cnVjdCBzZXRfc2NoaWJfc3RydWN0IHsKCXUzMiBtbWU7CglpbnQgbWJmYzsKCXVuc2lnbmVkIGxvbmcgYWRkcmVzczsKCXdhaXRfcXVldWVfaGVhZF90IHdhaXQ7CglpbnQgcmV0Owp9OwoKc3RhdGljIGludCBzZXRfc2NoaWJfd2FpdChzdHJ1Y3QgY2N3X2RldmljZSAqY2RldiwgdTMyIG1tZSwKCQkJCWludCBtYmZjLCB1bnNpZ25lZCBsb25nIGFkZHJlc3MpCnsKCXN0cnVjdCBzZXRfc2NoaWJfc3RydWN0IHMgPSB7CgkJLm1tZSA9IG1tZSwKCQkubWJmYyA9IG1iZmMsCgkJLmFkZHJlc3MgPSBhZGRyZXNzLAoJCS53YWl0ID0gX19XQUlUX1FVRVVFX0hFQURfSU5JVElBTElaRVIocy53YWl0KSwKCX07CgoJc3Bpbl9sb2NrX2lycShjZGV2LT5jY3dsb2NrKTsKCXMucmV0ID0gc2V0X3NjaGliKGNkZXYsIG1tZSwgbWJmYywgYWRkcmVzcyk7CglpZiAocy5yZXQgIT0gLUVCVVNZKSB7CgkJZ290byBvdXRfbm93YWl0OwoJfQoKCWlmIChjZGV2LT5wcml2YXRlLT5zdGF0ZSAhPSBERVZfU1RBVEVfT05MSU5FKSB7CgkJcy5yZXQgPSAtRUJVU1k7CgkJLyogaWYgdGhlIGRldmljZSBpcyBub3Qgb25saW5lLCBkb24ndCBldmVuIHRyeSBhZ2FpbiAqLwoJCWdvdG8gb3V0X25vd2FpdDsKCX0KCWNkZXYtPnByaXZhdGUtPnN0YXRlID0gREVWX1NUQVRFX0NNRkNIQU5HRTsKCWNkZXYtPnByaXZhdGUtPmNtYl93YWl0ID0gJnM7CglzLnJldCA9IDE7CgoJc3Bpbl91bmxvY2tfaXJxKGNkZXYtPmNjd2xvY2spOwoJaWYgKHdhaXRfZXZlbnRfaW50ZXJydXB0aWJsZShzLndhaXQsIHMucmV0ICE9IDEpKSB7CgkJc3Bpbl9sb2NrX2lycShjZGV2LT5jY3dsb2NrKTsKCQlpZiAocy5yZXQgPT0gMSkgewoJCQlzLnJldCA9IC1FUkVTVEFSVFNZUzsKCQkJY2Rldi0+cHJpdmF0ZS0+Y21iX3dhaXQgPSAwOwoJCQlpZiAoY2Rldi0+cHJpdmF0ZS0+c3RhdGUgPT0gREVWX1NUQVRFX0NNRkNIQU5HRSkKCQkJCWNkZXYtPnByaXZhdGUtPnN0YXRlID0gREVWX1NUQVRFX09OTElORTsKCQl9CgkJc3Bpbl91bmxvY2tfaXJxKGNkZXYtPmNjd2xvY2spOwoJfQoJcmV0dXJuIHMucmV0OwoKb3V0X25vd2FpdDoKCXNwaW5fdW5sb2NrX2lycShjZGV2LT5jY3dsb2NrKTsKCXJldHVybiBzLnJldDsKfQoKdm9pZCByZXRyeV9zZXRfc2NoaWIoc3RydWN0IGNjd19kZXZpY2UgKmNkZXYpCnsKCXN0cnVjdCBzZXRfc2NoaWJfc3RydWN0ICpzOwoKCXMgPSBjZGV2LT5wcml2YXRlLT5jbWJfd2FpdDsKCWNkZXYtPnByaXZhdGUtPmNtYl93YWl0ID0gMDsKCWlmICghcykgewoJCVdBUk5fT04oMSk7CgkJcmV0dXJuOwoJfQoJcy0+cmV0ID0gc2V0X3NjaGliKGNkZXYsIHMtPm1tZSwgcy0+bWJmYywgcy0+YWRkcmVzcyk7Cgl3YWtlX3VwKCZzLT53YWl0KTsKfQoKLyoqCiAqIHN0cnVjdCBjbWJfYXJlYSAtIGNvbnRhaW5lciBmb3IgZ2xvYmFsIGNtYiBkYXRhCiAqCiAqIEBtZW06CXBvaW50ZXIgdG8gQ01CcyAob25seSBpbiBiYXNpYyBtZWFzdXJlbWVudCBtb2RlKQogKiBAbGlzdDoJY29udGFpbnMgYSBsaW5rZWQgbGlzdCBvZiBhbGwgc3ViY2hhbm5lbHMKICogQGxvY2s6CXByb3RlY3QgY29uY3VycmVudCBhY2Nlc3MgdG8gQG1lbSBhbmQgQGxpc3QKICovCnN0cnVjdCBjbWJfYXJlYSB7CglzdHJ1Y3QgY21iICptZW07CglzdHJ1Y3QgbGlzdF9oZWFkIGxpc3Q7CglpbnQgbnVtX2NoYW5uZWxzOwoJc3BpbmxvY2tfdCBsb2NrOwp9OwoKc3RhdGljIHN0cnVjdCBjbWJfYXJlYSBjbWJfYXJlYSA9IHsKCS5sb2NrID0gU1BJTl9MT0NLX1VOTE9DS0VELAoJLmxpc3QgPSBMSVNUX0hFQURfSU5JVChjbWJfYXJlYS5saXN0KSwKCS5udW1fY2hhbm5lbHMgID0gMTAyNCwKfTsKCgwKLyogKioqKioqIG9sZCBzdHlsZSBDTUIgaGFuZGxpbmcgKioqKioqKiovCgovKiogaW50IG1heGNoYW5uZWxzCiAqCiAqIEJhc2ljIGNoYW5uZWwgbWVhc3VyZW1lbnQgYmxvY2tzIGFyZSBhbGxvY2F0ZWQgaW4gb25lIGNvbnRpZ3VvdXMKICogYmxvY2sgb2YgbWVtb3J5LCB3aGljaCBjYW4gbm90IGJlIG1vdmVkIGFzIGxvbmcgYXMgYW55IGNoYW5uZWwKICogaXMgYWN0aXZlLiBUaGVyZWZvcmUsIGEgbWF4aW11bSBudW1iZXIgb2Ygc3ViY2hhbm5lbHMgbmVlZHMgdG8KICogYmUgZGVmaW5lZCBzb21ld2hlcmUuIFRoaXMgaXMgYSBtb2R1bGUgcGFyYW1ldGVyLCBkZWZhdWx0aW5nIHRvCiAqIGEgcmVzb25hYmxlIHZhbHVlIG9mIDEwMjQsIG9yIDMyIGtiIG9mIG1lbW9yeS4KICogQ3VycmVudCBrZXJuZWxzIGRvbid0IGFsbG93IGttYWxsb2Mgd2l0aCBtb3JlIHRoYW4gMTI4a2IsIHNvIHRoZQogKiBtYXhpbXVtIGlzIDQwOTYKICovCgptb2R1bGVfcGFyYW1fbmFtZWQobWF4Y2hhbm5lbHMsIGNtYl9hcmVhLm51bV9jaGFubmVscywgdWludCwgMDQ0NCk7CgovKioKICogc3RydWN0IGNtYiAtIGJhc2ljIGNoYW5uZWwgbWVhc3VyZW1lbnQgYmxvY2sKICoKICogY21iIGFzIHVzZWQgYnkgdGhlIGhhcmR3YXJlIHRoZSBmaWVsZHMgYXJlIGRlc2NyaWJlZCBpbiB6L0FyY2hpdGVjdHVyZQogKiBQcmluY2lwbGVzIG9mIE9wZXJhdGlvbiwgY2hhcHRlciAxNy4KICogVGhlIGFyZWEgdG8gYmUgYSBjb250aWd1b3VzIGFycmF5IGFuZCBtYXkgbm90IGJlIHJlYWxsb2NhdGVkIG9yIGZyZWVkLgogKiBPbmx5IG9uZSBjbWIgYXJlYSBjYW4gYmUgcHJlc2VudCBpbiB0aGUgc3lzdGVtLgogKi8Kc3RydWN0IGNtYiB7Cgl1MTYgc3NjaF9yc2NoX2NvdW50OwoJdTE2IHNhbXBsZV9jb3VudDsKCXUzMiBkZXZpY2VfY29ubmVjdF90aW1lOwoJdTMyIGZ1bmN0aW9uX3BlbmRpbmdfdGltZTsKCXUzMiBkZXZpY2VfZGlzY29ubmVjdF90aW1lOwoJdTMyIGNvbnRyb2xfdW5pdF9xdWV1aW5nX3RpbWU7Cgl1MzIgZGV2aWNlX2FjdGl2ZV9vbmx5X3RpbWU7Cgl1MzIgcmVzZXJ2ZWRbMl07Cn07CgovKiBpbnNlcnQgYSBzaW5nbGUgZGV2aWNlIGludG8gdGhlIGNtYl9hcmVhIGxpc3QKICogY2FsbGVkIHdpdGggY21iX2FyZWEubG9jayBoZWxkIGZyb20gYWxsb2NfY21iCiAqLwpzdGF0aWMgaW5saW5lIGludAphbGxvY19jbWJfc2luZ2xlIChzdHJ1Y3QgY2N3X2RldmljZSAqY2RldikKewoJc3RydWN0IGNtYiAqY21iOwoJc3RydWN0IGNjd19kZXZpY2VfcHJpdmF0ZSAqbm9kZTsKCWludCByZXQ7CgoJc3Bpbl9sb2NrX2lycShjZGV2LT5jY3dsb2NrKTsKCWlmICghbGlzdF9lbXB0eSgmY2Rldi0+cHJpdmF0ZS0+Y21iX2xpc3QpKSB7CgkJcmV0ID0gLUVCVVNZOwoJCWdvdG8gb3V0OwoJfQoKCS8qIGZpbmQgZmlyc3QgdW51c2VkIGNtYiBpbiBjbWJfYXJlYS5tZW0uCgkgKiB0aGlzIGlzIGEgbGl0dGxlIHRyaWNreTogY21iX2FyZWEubGlzdAoJICogcmVtYWlucyBzb3J0ZWQgYnkgLT5jbWIgcG9pbnRlcnMgKi8KCWNtYiA9IGNtYl9hcmVhLm1lbTsKCWxpc3RfZm9yX2VhY2hfZW50cnkobm9kZSwgJmNtYl9hcmVhLmxpc3QsIGNtYl9saXN0KSB7CgkJaWYgKChzdHJ1Y3QgY21iKilub2RlLT5jbWIgPiBjbWIpCgkJCWJyZWFrOwoJCWNtYisrOwoJfQoJaWYgKGNtYiAtIGNtYl9hcmVhLm1lbSA+PSBjbWJfYXJlYS5udW1fY2hhbm5lbHMpIHsKCQlyZXQgPSAtRU5PTUVNOwoJCWdvdG8gb3V0OwoJfQoKCS8qIGluc2VydCBuZXcgY21iICovCglsaXN0X2FkZF90YWlsKCZjZGV2LT5wcml2YXRlLT5jbWJfbGlzdCwgJm5vZGUtPmNtYl9saXN0KTsKCWNkZXYtPnByaXZhdGUtPmNtYiA9IGNtYjsKCXJldCA9IDA7Cm91dDoKCXNwaW5fdW5sb2NrX2lycShjZGV2LT5jY3dsb2NrKTsKCXJldHVybiByZXQ7Cn0KCnN0YXRpYyBpbnQKYWxsb2NfY21iIChzdHJ1Y3QgY2N3X2RldmljZSAqY2RldikKewoJaW50IHJldDsKCXN0cnVjdCBjbWIgKm1lbTsKCXNzaXplX3Qgc2l6ZTsKCglzcGluX2xvY2soJmNtYl9hcmVhLmxvY2spOwoKCWlmICghY21iX2FyZWEubWVtKSB7CgkJLyogdGhlcmUgaXMgbm8gdXNlciB5ZXQsIHNvIHdlIG5lZWQgYSBuZXcgYXJlYSAqLwoJCXNpemUgPSBzaXplb2Yoc3RydWN0IGNtYikgKiBjbWJfYXJlYS5udW1fY2hhbm5lbHM7CgkJV0FSTl9PTighbGlzdF9lbXB0eSgmY21iX2FyZWEubGlzdCkpOwoKCQlzcGluX3VubG9jaygmY21iX2FyZWEubG9jayk7CgkJbWVtID0gKHZvaWQqKV9fZ2V0X2ZyZWVfcGFnZXMoR0ZQX0tFUk5FTCB8IEdGUF9ETUEsCgkJCQkgZ2V0X29yZGVyKHNpemUpKTsKCQlzcGluX2xvY2soJmNtYl9hcmVhLmxvY2spOwoKCQlpZiAoY21iX2FyZWEubWVtKSB7CgkJCS8qIG9rLCBhbm90aGVyIHRocmVhZCB3YXMgZmFzdGVyICovCgkJCWZyZWVfcGFnZXMoKHVuc2lnbmVkIGxvbmcpbWVtLCBnZXRfb3JkZXIoc2l6ZSkpOwoJCX0gZWxzZSBpZiAoIW1lbSkgewoJCQkvKiBubyBsdWNrICovCgkJCXJldCA9IC1FTk9NRU07CgkJCWdvdG8gb3V0OwoJCX0gZWxzZSB7CgkJCS8qIGV2ZXJ5dGhpbmcgb2sgKi8KCQkJbWVtc2V0KG1lbSwgMCwgc2l6ZSk7CgkJCWNtYl9hcmVhLm1lbSA9IG1lbTsKCQkJY21mX2FjdGl2YXRlKGNtYl9hcmVhLm1lbSwgMSk7CgkJfQoJfQoKCS8qIGRvIHRoZSBhY3R1YWwgYWxsb2NhdGlvbiAqLwoJcmV0ID0gYWxsb2NfY21iX3NpbmdsZShjZGV2KTsKb3V0OgoJc3Bpbl91bmxvY2soJmNtYl9hcmVhLmxvY2spOwoKCXJldHVybiByZXQ7Cn0KCnN0YXRpYyB2b2lkCmZyZWVfY21iKHN0cnVjdCBjY3dfZGV2aWNlICpjZGV2KQp7CglzdHJ1Y3QgY2N3X2RldmljZV9wcml2YXRlICpwcml2OwoKCXByaXYgPSBjZGV2LT5wcml2YXRlOwoKCXNwaW5fbG9jaygmY21iX2FyZWEubG9jayk7CglzcGluX2xvY2tfaXJxKGNkZXYtPmNjd2xvY2spOwoKCWlmIChsaXN0X2VtcHR5KCZwcml2LT5jbWJfbGlzdCkpIHsKCQkvKiBhbHJlYWR5IGZyZWVkICovCgkJZ290byBvdXQ7Cgl9CgoJcHJpdi0+Y21iID0gTlVMTDsKCWxpc3RfZGVsX2luaXQoJnByaXYtPmNtYl9saXN0KTsKCglpZiAobGlzdF9lbXB0eSgmY21iX2FyZWEubGlzdCkpIHsKCQlzc2l6ZV90IHNpemU7CgkJc2l6ZSA9IHNpemVvZihzdHJ1Y3QgY21iKSAqIGNtYl9hcmVhLm51bV9jaGFubmVsczsKCQljbWZfYWN0aXZhdGUoTlVMTCwgMCk7CgkJZnJlZV9wYWdlcygodW5zaWduZWQgbG9uZyljbWJfYXJlYS5tZW0sIGdldF9vcmRlcihzaXplKSk7CgkJY21iX2FyZWEubWVtID0gTlVMTDsKCX0Kb3V0OgoJc3Bpbl91bmxvY2tfaXJxKGNkZXYtPmNjd2xvY2spOwoJc3Bpbl91bmxvY2soJmNtYl9hcmVhLmxvY2spOwp9CgpzdGF0aWMgaW50CnNldF9jbWIoc3RydWN0IGNjd19kZXZpY2UgKmNkZXYsIHUzMiBtbWUpCnsKCXUxNiBvZmZzZXQ7CgoJaWYgKCFjZGV2LT5wcml2YXRlLT5jbWIpCgkJcmV0dXJuIC1FSU5WQUw7CgoJb2Zmc2V0ID0gbW1lID8gKHN0cnVjdCBjbWIgKiljZGV2LT5wcml2YXRlLT5jbWIgLSBjbWJfYXJlYS5tZW0gOiAwOwoKCXJldHVybiBzZXRfc2NoaWJfd2FpdChjZGV2LCBtbWUsIDAsIG9mZnNldCk7Cn0KCnN0YXRpYyB1NjQKcmVhZF9jbWIgKHN0cnVjdCBjY3dfZGV2aWNlICpjZGV2LCBpbnQgaW5kZXgpCnsKCS8qIHllcywgd2UgaGF2ZSB0byBwdXQgaXQgb24gdGhlIHN0YWNrCgkgKiBiZWNhdXNlIHRoZSBjbWIgbXVzdCBvbmx5IGJlIGFjY2Vzc2VkCgkgKiBhdG9taWNhbGx5LCBlLmcuIHdpdGggbXZjICovCglzdHJ1Y3QgY21iIGNtYjsKCXVuc2lnbmVkIGxvbmcgZmxhZ3M7Cgl1MzIgdmFsOwoKCXNwaW5fbG9ja19pcnFzYXZlKGNkZXYtPmNjd2xvY2ssIGZsYWdzKTsKCWlmICghY2Rldi0+cHJpdmF0ZS0+Y21iKSB7CgkJc3Bpbl91bmxvY2tfaXJxcmVzdG9yZShjZGV2LT5jY3dsb2NrLCBmbGFncyk7CgkJcmV0dXJuIDA7Cgl9CgoJY21iID0gKihzdHJ1Y3QgY21iKiljZGV2LT5wcml2YXRlLT5jbWI7CglzcGluX3VubG9ja19pcnFyZXN0b3JlKGNkZXYtPmNjd2xvY2ssIGZsYWdzKTsKCglzd2l0Y2ggKGluZGV4KSB7CgljYXNlIGNtYl9zc2NoX3JzY2hfY291bnQ6CgkJcmV0dXJuIGNtYi5zc2NoX3JzY2hfY291bnQ7CgljYXNlIGNtYl9zYW1wbGVfY291bnQ6CgkJcmV0dXJuIGNtYi5zYW1wbGVfY291bnQ7CgljYXNlIGNtYl9kZXZpY2VfY29ubmVjdF90aW1lOgoJCXZhbCA9IGNtYi5kZXZpY2VfY29ubmVjdF90aW1lOwoJCWJyZWFrOwoJY2FzZSBjbWJfZnVuY3Rpb25fcGVuZGluZ190aW1lOgoJCXZhbCA9IGNtYi5mdW5jdGlvbl9wZW5kaW5nX3RpbWU7CgkJYnJlYWs7CgljYXNlIGNtYl9kZXZpY2VfZGlzY29ubmVjdF90aW1lOgoJCXZhbCA9IGNtYi5kZXZpY2VfZGlzY29ubmVjdF90aW1lOwoJCWJyZWFrOwoJY2FzZSBjbWJfY29udHJvbF91bml0X3F1ZXVpbmdfdGltZToKCQl2YWwgPSBjbWIuY29udHJvbF91bml0X3F1ZXVpbmdfdGltZTsKCQlicmVhazsKCWNhc2UgY21iX2RldmljZV9hY3RpdmVfb25seV90aW1lOgoJCXZhbCA9IGNtYi5kZXZpY2VfYWN0aXZlX29ubHlfdGltZTsKCQlicmVhazsKCWRlZmF1bHQ6CgkJcmV0dXJuIDA7Cgl9CglyZXR1cm4gdGltZV90b19hdmdfbnNlYyh2YWwsIGNtYi5zYW1wbGVfY291bnQpOwp9CgpzdGF0aWMgaW50CnJlYWRhbGxfY21iIChzdHJ1Y3QgY2N3X2RldmljZSAqY2Rldiwgc3RydWN0IGNtYmRhdGEgKmRhdGEpCnsKCS8qIHllcywgd2UgaGF2ZSB0byBwdXQgaXQgb24gdGhlIHN0YWNrCgkgKiBiZWNhdXNlIHRoZSBjbWIgbXVzdCBvbmx5IGJlIGFjY2Vzc2VkCgkgKiBhdG9taWNhbGx5LCBlLmcuIHdpdGggbXZjICovCglzdHJ1Y3QgY21iIGNtYjsKCXVuc2lnbmVkIGxvbmcgZmxhZ3M7Cgl1NjQgdGltZTsKCglzcGluX2xvY2tfaXJxc2F2ZShjZGV2LT5jY3dsb2NrLCBmbGFncyk7CglpZiAoIWNkZXYtPnByaXZhdGUtPmNtYikgewoJCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoY2Rldi0+Y2N3bG9jaywgZmxhZ3MpOwoJCXJldHVybiAtRU5PREVWOwoJfQoKCWNtYiA9ICooc3RydWN0IGNtYiopY2Rldi0+cHJpdmF0ZS0+Y21iOwoJdGltZSA9IGdldF9jbG9jaygpIC0gY2Rldi0+cHJpdmF0ZS0+Y21iX3N0YXJ0X3RpbWU7CglzcGluX3VubG9ja19pcnFyZXN0b3JlKGNkZXYtPmNjd2xvY2ssIGZsYWdzKTsKCgltZW1zZXQoZGF0YSwgMCwgc2l6ZW9mKHN0cnVjdCBjbWJkYXRhKSk7CgoJLyogd2Ugb25seSBrbm93IHZhbHVlcyBiZWZvcmUgZGV2aWNlX2J1c3lfdGltZSAqLwoJZGF0YS0+c2l6ZSA9IG9mZnNldG9mKHN0cnVjdCBjbWJkYXRhLCBkZXZpY2VfYnVzeV90aW1lKTsKCgkvKiBjb252ZXJ0IHRvIG5hbm9zZWNvbmRzICovCglkYXRhLT5lbGFwc2VkX3RpbWUgPSAodGltZSAqIDEwMDApID4+IDEyOwoKCS8qIGNvcHkgZGF0YSB0byBuZXcgc3RydWN0dXJlICovCglkYXRhLT5zc2NoX3JzY2hfY291bnQgPSBjbWIuc3NjaF9yc2NoX2NvdW50OwoJZGF0YS0+c2FtcGxlX2NvdW50ID0gY21iLnNhbXBsZV9jb3VudDsKCgkvKiB0aW1lIGZpZWxkcyBhcmUgY29udmVydGVkIHRvIG5hbm9zZWNvbmRzIHdoaWxlIGNvcHlpbmcgKi8KCWRhdGEtPmRldmljZV9jb25uZWN0X3RpbWUgPSB0aW1lX3RvX25zZWMoY21iLmRldmljZV9jb25uZWN0X3RpbWUpOwoJZGF0YS0+ZnVuY3Rpb25fcGVuZGluZ190aW1lID0gdGltZV90b19uc2VjKGNtYi5mdW5jdGlvbl9wZW5kaW5nX3RpbWUpOwoJZGF0YS0+ZGV2aWNlX2Rpc2Nvbm5lY3RfdGltZSA9IHRpbWVfdG9fbnNlYyhjbWIuZGV2aWNlX2Rpc2Nvbm5lY3RfdGltZSk7CglkYXRhLT5jb250cm9sX3VuaXRfcXVldWluZ190aW1lCgkJPSB0aW1lX3RvX25zZWMoY21iLmNvbnRyb2xfdW5pdF9xdWV1aW5nX3RpbWUpOwoJZGF0YS0+ZGV2aWNlX2FjdGl2ZV9vbmx5X3RpbWUKCQk9IHRpbWVfdG9fbnNlYyhjbWIuZGV2aWNlX2FjdGl2ZV9vbmx5X3RpbWUpOwoKCXJldHVybiAwOwp9CgpzdGF0aWMgdm9pZApyZXNldF9jbWIoc3RydWN0IGNjd19kZXZpY2UgKmNkZXYpCnsKCXN0cnVjdCBjbWIgKmNtYjsKCXNwaW5fbG9ja19pcnEoY2Rldi0+Y2N3bG9jayk7CgljbWIgPSBjZGV2LT5wcml2YXRlLT5jbWI7CglpZiAoY21iKQoJCW1lbXNldCAoY21iLCAwLCBzaXplb2YgKCpjbWIpKTsKCWNkZXYtPnByaXZhdGUtPmNtYl9zdGFydF90aW1lID0gZ2V0X2Nsb2NrKCk7CglzcGluX3VubG9ja19pcnEoY2Rldi0+Y2N3bG9jayk7Cn0KCnN0YXRpYyBzdHJ1Y3QgYXR0cmlidXRlX2dyb3VwIGNtZl9hdHRyX2dyb3VwOwoKc3RhdGljIHN0cnVjdCBjbWJfb3BlcmF0aW9ucyBjbWJvcHNfYmFzaWMgPSB7CgkuYWxsb2MJPSBhbGxvY19jbWIsCgkuZnJlZQk9IGZyZWVfY21iLAoJLnNldAk9IHNldF9jbWIsCgkucmVhZAk9IHJlYWRfY21iLAoJLnJlYWRhbGwgICAgPSByZWFkYWxsX2NtYiwKCS5yZXNldAkgICAgPSByZXNldF9jbWIsCgkuYXR0cl9ncm91cCA9ICZjbWZfYXR0cl9ncm91cCwKfTsKDAovKiAqKioqKioqKiBleHRlbmRlZCBjbWIgaGFuZGxpbmcgKioqKioqKiovCgovKioKICogc3RydWN0IGNtYmUgLSBleHRlbmRlZCBjaGFubmVsIG1lYXN1cmVtZW50IGJsb2NrCiAqCiAqIGNtYiBhcyB1c2VkIGJ5IHRoZSBoYXJkd2FyZSwgbWF5IGJlIGluIGFueSA2NCBiaXQgcGh5c2ljYWwgbG9jYXRpb24sCiAqIHRoZSBmaWVsZHMgYXJlIGRlc2NyaWJlZCBpbiB6L0FyY2hpdGVjdHVyZSBQcmluY2lwbGVzIG9mIE9wZXJhdGlvbiwKICogdGhpcmQgZWRpdGlvbiwgY2hhcHRlciAxNy4KICovCnN0cnVjdCBjbWJlIHsKCXUzMiBzc2NoX3JzY2hfY291bnQ7Cgl1MzIgc2FtcGxlX2NvdW50OwoJdTMyIGRldmljZV9jb25uZWN0X3RpbWU7Cgl1MzIgZnVuY3Rpb25fcGVuZGluZ190aW1lOwoJdTMyIGRldmljZV9kaXNjb25uZWN0X3RpbWU7Cgl1MzIgY29udHJvbF91bml0X3F1ZXVpbmdfdGltZTsKCXUzMiBkZXZpY2VfYWN0aXZlX29ubHlfdGltZTsKCXUzMiBkZXZpY2VfYnVzeV90aW1lOwoJdTMyIGluaXRpYWxfY29tbWFuZF9yZXNwb25zZV90aW1lOwoJdTMyIHJlc2VydmVkWzddOwp9OwoKLyoga21hbGxvYyBvbmx5IGd1YXJhbnRlZXMgOCBieXRlIGFsaWdubWVudCwgYnV0IHdlIG5lZWQgY21iZQogKiBwb2ludGVycyB0byBiZSBuYXR1cmFsbHkgYWxpZ25lZC4gTWFrZSBzdXJlIHRvIGFsbG9jYXRlCiAqIGVub3VnaCBzcGFjZSBmb3IgdHdvIGNtYmVzICovCnN0YXRpYyBpbmxpbmUgc3RydWN0IGNtYmUqIGNtYmVfYWxpZ24oc3RydWN0IGNtYmUgKmMpCnsKCXVuc2lnbmVkIGxvbmcgYWRkcjsKCWFkZHIgPSAoKHVuc2lnbmVkIGxvbmcpYyArIHNpemVvZiAoc3RydWN0IGNtYmUpIC0gc2l6ZW9mKGxvbmcpKSAmCgkJCQkgfihzaXplb2YgKHN0cnVjdCBjbWJlKSAtIHNpemVvZihsb25nKSk7CglyZXR1cm4gKHN0cnVjdCBjbWJlKilhZGRyOwp9CgpzdGF0aWMgaW50CmFsbG9jX2NtYmUgKHN0cnVjdCBjY3dfZGV2aWNlICpjZGV2KQp7CglzdHJ1Y3QgY21iZSAqY21iZTsKCWNtYmUgPSBrbWFsbG9jIChzaXplb2YgKCpjbWJlKSAqIDIsIEdGUF9LRVJORUwpOwoJaWYgKCFjbWJlKQoJCXJldHVybiAtRU5PTUVNOwoKCXNwaW5fbG9ja19pcnEoY2Rldi0+Y2N3bG9jayk7CglpZiAoY2Rldi0+cHJpdmF0ZS0+Y21iKSB7CgkJa2ZyZWUoY21iZSk7CgkJc3Bpbl91bmxvY2tfaXJxKGNkZXYtPmNjd2xvY2spOwoJCXJldHVybiAtRUJVU1k7Cgl9CgoJY2Rldi0+cHJpdmF0ZS0+Y21iID0gY21iZTsKCXNwaW5fdW5sb2NrX2lycShjZGV2LT5jY3dsb2NrKTsKCgkvKiBhY3RpdmF0ZSBnbG9iYWwgbWVhc3VyZW1lbnQgaWYgdGhpcyBpcyB0aGUgZmlyc3QgY2hhbm5lbCAqLwoJc3Bpbl9sb2NrKCZjbWJfYXJlYS5sb2NrKTsKCWlmIChsaXN0X2VtcHR5KCZjbWJfYXJlYS5saXN0KSkKCQljbWZfYWN0aXZhdGUoTlVMTCwgMSk7CglsaXN0X2FkZF90YWlsKCZjZGV2LT5wcml2YXRlLT5jbWJfbGlzdCwgJmNtYl9hcmVhLmxpc3QpOwoJc3Bpbl91bmxvY2soJmNtYl9hcmVhLmxvY2spOwoKCXJldHVybiAwOwp9CgpzdGF0aWMgdm9pZApmcmVlX2NtYmUgKHN0cnVjdCBjY3dfZGV2aWNlICpjZGV2KQp7CglzcGluX2xvY2tfaXJxKGNkZXYtPmNjd2xvY2spOwoJa2ZyZWUoY2Rldi0+cHJpdmF0ZS0+Y21iKTsKCWNkZXYtPnByaXZhdGUtPmNtYiA9IE5VTEw7CglzcGluX3VubG9ja19pcnEoY2Rldi0+Y2N3bG9jayk7CgoJLyogZGVhY3RpdmF0ZSBnbG9iYWwgbWVhc3VyZW1lbnQgaWYgdGhpcyBpcyB0aGUgbGFzdCBjaGFubmVsICovCglzcGluX2xvY2soJmNtYl9hcmVhLmxvY2spOwoJbGlzdF9kZWxfaW5pdCgmY2Rldi0+cHJpdmF0ZS0+Y21iX2xpc3QpOwoJaWYgKGxpc3RfZW1wdHkoJmNtYl9hcmVhLmxpc3QpKQoJCWNtZl9hY3RpdmF0ZShOVUxMLCAwKTsKCXNwaW5fdW5sb2NrKCZjbWJfYXJlYS5sb2NrKTsKfQoKc3RhdGljIGludApzZXRfY21iZShzdHJ1Y3QgY2N3X2RldmljZSAqY2RldiwgdTMyIG1tZSkKewoJdW5zaWduZWQgbG9uZyBtYmE7CgoJaWYgKCFjZGV2LT5wcml2YXRlLT5jbWIpCgkJcmV0dXJuIC1FSU5WQUw7CgltYmEgPSBtbWUgPyAodW5zaWduZWQgbG9uZykgY21iZV9hbGlnbihjZGV2LT5wcml2YXRlLT5jbWIpIDogMDsKCglyZXR1cm4gc2V0X3NjaGliX3dhaXQoY2RldiwgbW1lLCAxLCBtYmEpOwp9CgoKdTY0CnJlYWRfY21iZSAoc3RydWN0IGNjd19kZXZpY2UgKmNkZXYsIGludCBpbmRleCkKewoJLyogeWVzLCB3ZSBoYXZlIHRvIHB1dCBpdCBvbiB0aGUgc3RhY2sKCSAqIGJlY2F1c2UgdGhlIGNtYiBtdXN0IG9ubHkgYmUgYWNjZXNzZWQKCSAqIGF0b21pY2FsbHksIGUuZy4gd2l0aCBtdmMgKi8KCXN0cnVjdCBjbWJlIGNtYjsKCXVuc2lnbmVkIGxvbmcgZmxhZ3M7Cgl1MzIgdmFsOwoKCXNwaW5fbG9ja19pcnFzYXZlKGNkZXYtPmNjd2xvY2ssIGZsYWdzKTsKCWlmICghY2Rldi0+cHJpdmF0ZS0+Y21iKSB7CgkJc3Bpbl91bmxvY2tfaXJxcmVzdG9yZShjZGV2LT5jY3dsb2NrLCBmbGFncyk7CgkJcmV0dXJuIDA7Cgl9CgoJY21iID0gKmNtYmVfYWxpZ24oY2Rldi0+cHJpdmF0ZS0+Y21iKTsKCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoY2Rldi0+Y2N3bG9jaywgZmxhZ3MpOwoKCXN3aXRjaCAoaW5kZXgpIHsKCWNhc2UgY21iX3NzY2hfcnNjaF9jb3VudDoKCQlyZXR1cm4gY21iLnNzY2hfcnNjaF9jb3VudDsKCWNhc2UgY21iX3NhbXBsZV9jb3VudDoKCQlyZXR1cm4gY21iLnNhbXBsZV9jb3VudDsKCWNhc2UgY21iX2RldmljZV9jb25uZWN0X3RpbWU6CgkJdmFsID0gY21iLmRldmljZV9jb25uZWN0X3RpbWU7CgkJYnJlYWs7CgljYXNlIGNtYl9mdW5jdGlvbl9wZW5kaW5nX3RpbWU6CgkJdmFsID0gY21iLmZ1bmN0aW9uX3BlbmRpbmdfdGltZTsKCQlicmVhazsKCWNhc2UgY21iX2RldmljZV9kaXNjb25uZWN0X3RpbWU6CgkJdmFsID0gY21iLmRldmljZV9kaXNjb25uZWN0X3RpbWU7CgkJYnJlYWs7CgljYXNlIGNtYl9jb250cm9sX3VuaXRfcXVldWluZ190aW1lOgoJCXZhbCA9IGNtYi5jb250cm9sX3VuaXRfcXVldWluZ190aW1lOwoJCWJyZWFrOwoJY2FzZSBjbWJfZGV2aWNlX2FjdGl2ZV9vbmx5X3RpbWU6CgkJdmFsID0gY21iLmRldmljZV9hY3RpdmVfb25seV90aW1lOwoJCWJyZWFrOwoJY2FzZSBjbWJfZGV2aWNlX2J1c3lfdGltZToKCQl2YWwgPSBjbWIuZGV2aWNlX2J1c3lfdGltZTsKCQlicmVhazsKCWNhc2UgY21iX2luaXRpYWxfY29tbWFuZF9yZXNwb25zZV90aW1lOgoJCXZhbCA9IGNtYi5pbml0aWFsX2NvbW1hbmRfcmVzcG9uc2VfdGltZTsKCQlicmVhazsKCWRlZmF1bHQ6CgkJcmV0dXJuIDA7Cgl9CglyZXR1cm4gdGltZV90b19hdmdfbnNlYyh2YWwsIGNtYi5zYW1wbGVfY291bnQpOwp9CgpzdGF0aWMgaW50CnJlYWRhbGxfY21iZSAoc3RydWN0IGNjd19kZXZpY2UgKmNkZXYsIHN0cnVjdCBjbWJkYXRhICpkYXRhKQp7CgkvKiB5ZXMsIHdlIGhhdmUgdG8gcHV0IGl0IG9uIHRoZSBzdGFjawoJICogYmVjYXVzZSB0aGUgY21iIG11c3Qgb25seSBiZSBhY2Nlc3NlZAoJICogYXRvbWljYWxseSwgZS5nLiB3aXRoIG12YyAqLwoJc3RydWN0IGNtYmUgY21iOwoJdW5zaWduZWQgbG9uZyBmbGFnczsKCXU2NCB0aW1lOwoKCXNwaW5fbG9ja19pcnFzYXZlKGNkZXYtPmNjd2xvY2ssIGZsYWdzKTsKCWlmICghY2Rldi0+cHJpdmF0ZS0+Y21iKSB7CgkJc3Bpbl91bmxvY2tfaXJxcmVzdG9yZShjZGV2LT5jY3dsb2NrLCBmbGFncyk7CgkJcmV0dXJuIC1FTk9ERVY7Cgl9CgoJY21iID0gKmNtYmVfYWxpZ24oY2Rldi0+cHJpdmF0ZS0+Y21iKTsKCXRpbWUgPSBnZXRfY2xvY2soKSAtIGNkZXYtPnByaXZhdGUtPmNtYl9zdGFydF90aW1lOwoJc3Bpbl91bmxvY2tfaXJxcmVzdG9yZShjZGV2LT5jY3dsb2NrLCBmbGFncyk7CgoJbWVtc2V0IChkYXRhLCAwLCBzaXplb2Yoc3RydWN0IGNtYmRhdGEpKTsKCgkvKiB3ZSBvbmx5IGtub3cgdmFsdWVzIGJlZm9yZSBkZXZpY2VfYnVzeV90aW1lICovCglkYXRhLT5zaXplID0gb2Zmc2V0b2Yoc3RydWN0IGNtYmRhdGEsIGRldmljZV9idXN5X3RpbWUpOwoKCS8qIGNvbnZlciB0byBuYW5vc2Vjb25kcyAqLwoJZGF0YS0+ZWxhcHNlZF90aW1lID0gKHRpbWUgKiAxMDAwKSA+PiAxMjsKCgkvKiBjb3B5IGRhdGEgdG8gbmV3IHN0cnVjdHVyZSAqLwoJZGF0YS0+c3NjaF9yc2NoX2NvdW50ID0gY21iLnNzY2hfcnNjaF9jb3VudDsKCWRhdGEtPnNhbXBsZV9jb3VudCA9IGNtYi5zYW1wbGVfY291bnQ7CgoJLyogdGltZSBmaWVsZHMgYXJlIGNvbnZlcnRlZCB0byBuYW5vc2Vjb25kcyB3aGlsZSBjb3B5aW5nICovCglkYXRhLT5kZXZpY2VfY29ubmVjdF90aW1lID0gdGltZV90b19uc2VjKGNtYi5kZXZpY2VfY29ubmVjdF90aW1lKTsKCWRhdGEtPmZ1bmN0aW9uX3BlbmRpbmdfdGltZSA9IHRpbWVfdG9fbnNlYyhjbWIuZnVuY3Rpb25fcGVuZGluZ190aW1lKTsKCWRhdGEtPmRldmljZV9kaXNjb25uZWN0X3RpbWUgPSB0aW1lX3RvX25zZWMoY21iLmRldmljZV9kaXNjb25uZWN0X3RpbWUpOwoJZGF0YS0+Y29udHJvbF91bml0X3F1ZXVpbmdfdGltZQoJCT0gdGltZV90b19uc2VjKGNtYi5jb250cm9sX3VuaXRfcXVldWluZ190aW1lKTsKCWRhdGEtPmRldmljZV9hY3RpdmVfb25seV90aW1lCgkJPSB0aW1lX3RvX25zZWMoY21iLmRldmljZV9hY3RpdmVfb25seV90aW1lKTsKCWRhdGEtPmRldmljZV9idXN5X3RpbWUgPSB0aW1lX3RvX25zZWMoY21iLmRldmljZV9idXN5X3RpbWUpOwoJZGF0YS0+aW5pdGlhbF9jb21tYW5kX3Jlc3BvbnNlX3RpbWUKCQk9IHRpbWVfdG9fbnNlYyhjbWIuaW5pdGlhbF9jb21tYW5kX3Jlc3BvbnNlX3RpbWUpOwoKCXJldHVybiAwOwp9CgpzdGF0aWMgdm9pZApyZXNldF9jbWJlKHN0cnVjdCBjY3dfZGV2aWNlICpjZGV2KQp7CglzdHJ1Y3QgY21iZSAqY21iOwoJc3Bpbl9sb2NrX2lycShjZGV2LT5jY3dsb2NrKTsKCWNtYiA9IGNtYmVfYWxpZ24oY2Rldi0+cHJpdmF0ZS0+Y21iKTsKCWlmIChjbWIpCgkJbWVtc2V0IChjbWIsIDAsIHNpemVvZiAoKmNtYikpOwoJY2Rldi0+cHJpdmF0ZS0+Y21iX3N0YXJ0X3RpbWUgPSBnZXRfY2xvY2soKTsKCXNwaW5fdW5sb2NrX2lycShjZGV2LT5jY3dsb2NrKTsKfQoKc3RhdGljIHN0cnVjdCBhdHRyaWJ1dGVfZ3JvdXAgY21mX2F0dHJfZ3JvdXBfZXh0OwoKc3RhdGljIHN0cnVjdCBjbWJfb3BlcmF0aW9ucyBjbWJvcHNfZXh0ZW5kZWQgPSB7CgkuYWxsb2MJICAgID0gYWxsb2NfY21iZSwKCS5mcmVlCSAgICA9IGZyZWVfY21iZSwKCS5zZXQJICAgID0gc2V0X2NtYmUsCgkucmVhZAkgICAgPSByZWFkX2NtYmUsCgkucmVhZGFsbCAgICA9IHJlYWRhbGxfY21iZSwKCS5yZXNldAkgICAgPSByZXNldF9jbWJlLAoJLmF0dHJfZ3JvdXAgPSAmY21mX2F0dHJfZ3JvdXBfZXh0LAp9OwoMCgpzdGF0aWMgc3NpemVfdApjbWJfc2hvd19hdHRyKHN0cnVjdCBkZXZpY2UgKmRldiwgY2hhciAqYnVmLCBlbnVtIGNtYl9pbmRleCBpZHgpCnsKCXJldHVybiBzcHJpbnRmKGJ1ZiwgIiVsbGRcbiIsCgkJKHVuc2lnbmVkIGxvbmcgbG9uZykgY21mX3JlYWQodG9fY2N3ZGV2KGRldiksIGlkeCkpOwp9CgpzdGF0aWMgc3NpemVfdApjbWJfc2hvd19hdmdfc2FtcGxlX2ludGVydmFsKHN0cnVjdCBkZXZpY2UgKmRldiwgc3RydWN0IGRldmljZV9hdHRyaWJ1dGUgKmF0dHIsIGNoYXIgKmJ1ZikKewoJc3RydWN0IGNjd19kZXZpY2UgKmNkZXY7Cglsb25nIGludGVydmFsOwoJdW5zaWduZWQgbG9uZyBjb3VudDsKCgljZGV2ID0gdG9fY2N3ZGV2KGRldik7CglpbnRlcnZhbCAgPSBnZXRfY2xvY2soKSAtIGNkZXYtPnByaXZhdGUtPmNtYl9zdGFydF90aW1lOwoJY291bnQgPSBjbWZfcmVhZChjZGV2LCBjbWJfc2FtcGxlX2NvdW50KTsKCWlmIChjb3VudCkKCQlpbnRlcnZhbCAvPSBjb3VudDsKCWVsc2UKCQlpbnRlcnZhbCA9IC0xOwoJcmV0dXJuIHNwcmludGYoYnVmLCAiJWxkXG4iLCBpbnRlcnZhbCk7Cn0KCnN0YXRpYyBzc2l6ZV90CmNtYl9zaG93X2F2Z191dGlsaXphdGlvbihzdHJ1Y3QgZGV2aWNlICpkZXYsIHN0cnVjdCBkZXZpY2VfYXR0cmlidXRlICphdHRyLCBjaGFyICpidWYpCnsKCXN0cnVjdCBjbWJkYXRhIGRhdGE7Cgl1NjQgdXRpbGl6YXRpb247Cgl1bnNpZ25lZCBsb25nIHQsIHU7CglpbnQgcmV0OwoKCXJldCA9IGNtZl9yZWFkYWxsKHRvX2Njd2RldihkZXYpLCAmZGF0YSk7CglpZiAocmV0KQoJCXJldHVybiByZXQ7CgoJdXRpbGl6YXRpb24gPSBkYXRhLmRldmljZV9jb25uZWN0X3RpbWUgKwoJCSAgICAgIGRhdGEuZnVuY3Rpb25fcGVuZGluZ190aW1lICsKCQkgICAgICBkYXRhLmRldmljZV9kaXNjb25uZWN0X3RpbWU7CgoJLyogc2hpZnQgdG8gYXZvaWQgbG9uZyBsb25nIGRpdmlzaW9uICovCgl3aGlsZSAoLTF1bCA8IChkYXRhLmVsYXBzZWRfdGltZSB8IHV0aWxpemF0aW9uKSkgewoJCXV0aWxpemF0aW9uID4+PSA4OwoJCWRhdGEuZWxhcHNlZF90aW1lID4+PSA4OwoJfQoKCS8qIGNhbGN1bGF0ZSB2YWx1ZSBpbiAwLjEgcGVyY2VudCB1bml0cyAqLwoJdCA9ICh1bnNpZ25lZCBsb25nKSBkYXRhLmVsYXBzZWRfdGltZSAvIDEwMDA7Cgl1ID0gKHVuc2lnbmVkIGxvbmcpIHV0aWxpemF0aW9uIC8gdDsKCglyZXR1cm4gc3ByaW50ZihidWYsICIlMDJsZC4lMDFsZCUlXG4iLCB1LyAxMCwgdSAtICh1LyAxMCkgKiAxMCk7Cn0KCiNkZWZpbmUgY21mX2F0dHIobmFtZSkgXApzdGF0aWMgc3NpemVfdCBzaG93XyAjIyBuYW1lIChzdHJ1Y3QgZGV2aWNlICogZGV2LCBzdHJ1Y3QgZGV2aWNlX2F0dHJpYnV0ZSAqYXR0ciwgY2hhciAqIGJ1ZikgXAp7IHJldHVybiBjbWJfc2hvd19hdHRyKChkZXYpLCBidWYsIGNtYl8gIyMgbmFtZSk7IH0gXApzdGF0aWMgREVWSUNFX0FUVFIobmFtZSwgMDQ0NCwgc2hvd18gIyMgbmFtZSwgTlVMTCk7CgojZGVmaW5lIGNtZl9hdHRyX2F2ZyhuYW1lKSBcCnN0YXRpYyBzc2l6ZV90IHNob3dfYXZnXyAjIyBuYW1lIChzdHJ1Y3QgZGV2aWNlICogZGV2LCBzdHJ1Y3QgZGV2aWNlX2F0dHJpYnV0ZSAqYXR0ciwgY2hhciAqIGJ1ZikgXAp7IHJldHVybiBjbWJfc2hvd19hdHRyKChkZXYpLCBidWYsIGNtYl8gIyMgbmFtZSk7IH0gXApzdGF0aWMgREVWSUNFX0FUVFIoYXZnXyAjIyBuYW1lLCAwNDQ0LCBzaG93X2F2Z18gIyMgbmFtZSwgTlVMTCk7CgpjbWZfYXR0cihzc2NoX3JzY2hfY291bnQpOwpjbWZfYXR0cihzYW1wbGVfY291bnQpOwpjbWZfYXR0cl9hdmcoZGV2aWNlX2Nvbm5lY3RfdGltZSk7CmNtZl9hdHRyX2F2ZyhmdW5jdGlvbl9wZW5kaW5nX3RpbWUpOwpjbWZfYXR0cl9hdmcoZGV2aWNlX2Rpc2Nvbm5lY3RfdGltZSk7CmNtZl9hdHRyX2F2Zyhjb250cm9sX3VuaXRfcXVldWluZ190aW1lKTsKY21mX2F0dHJfYXZnKGRldmljZV9hY3RpdmVfb25seV90aW1lKTsKY21mX2F0dHJfYXZnKGRldmljZV9idXN5X3RpbWUpOwpjbWZfYXR0cl9hdmcoaW5pdGlhbF9jb21tYW5kX3Jlc3BvbnNlX3RpbWUpOwoKc3RhdGljIERFVklDRV9BVFRSKGF2Z19zYW1wbGVfaW50ZXJ2YWwsIDA0NDQsIGNtYl9zaG93X2F2Z19zYW1wbGVfaW50ZXJ2YWwsIE5VTEwpOwpzdGF0aWMgREVWSUNFX0FUVFIoYXZnX3V0aWxpemF0aW9uLCAwNDQ0LCBjbWJfc2hvd19hdmdfdXRpbGl6YXRpb24sIE5VTEwpOwoKc3RhdGljIHN0cnVjdCBhdHRyaWJ1dGUgKmNtZl9hdHRyaWJ1dGVzW10gPSB7CgkmZGV2X2F0dHJfYXZnX3NhbXBsZV9pbnRlcnZhbC5hdHRyLAoJJmRldl9hdHRyX2F2Z191dGlsaXphdGlvbi5hdHRyLAoJJmRldl9hdHRyX3NzY2hfcnNjaF9jb3VudC5hdHRyLAoJJmRldl9hdHRyX3NhbXBsZV9jb3VudC5hdHRyLAoJJmRldl9hdHRyX2F2Z19kZXZpY2VfY29ubmVjdF90aW1lLmF0dHIsCgkmZGV2X2F0dHJfYXZnX2Z1bmN0aW9uX3BlbmRpbmdfdGltZS5hdHRyLAoJJmRldl9hdHRyX2F2Z19kZXZpY2VfZGlzY29ubmVjdF90aW1lLmF0dHIsCgkmZGV2X2F0dHJfYXZnX2NvbnRyb2xfdW5pdF9xdWV1aW5nX3RpbWUuYXR0ciwKCSZkZXZfYXR0cl9hdmdfZGV2aWNlX2FjdGl2ZV9vbmx5X3RpbWUuYXR0ciwKCTAsCn07CgpzdGF0aWMgc3RydWN0IGF0dHJpYnV0ZV9ncm91cCBjbWZfYXR0cl9ncm91cCA9IHsKCS5uYW1lICA9ICJjbWYiLAoJLmF0dHJzID0gY21mX2F0dHJpYnV0ZXMsCn07CgpzdGF0aWMgc3RydWN0IGF0dHJpYnV0ZSAqY21mX2F0dHJpYnV0ZXNfZXh0W10gPSB7CgkmZGV2X2F0dHJfYXZnX3NhbXBsZV9pbnRlcnZhbC5hdHRyLAoJJmRldl9hdHRyX2F2Z191dGlsaXphdGlvbi5hdHRyLAoJJmRldl9hdHRyX3NzY2hfcnNjaF9jb3VudC5hdHRyLAoJJmRldl9hdHRyX3NhbXBsZV9jb3VudC5hdHRyLAoJJmRldl9hdHRyX2F2Z19kZXZpY2VfY29ubmVjdF90aW1lLmF0dHIsCgkmZGV2X2F0dHJfYXZnX2Z1bmN0aW9uX3BlbmRpbmdfdGltZS5hdHRyLAoJJmRldl9hdHRyX2F2Z19kZXZpY2VfZGlzY29ubmVjdF90aW1lLmF0dHIsCgkmZGV2X2F0dHJfYXZnX2NvbnRyb2xfdW5pdF9xdWV1aW5nX3RpbWUuYXR0ciwKCSZkZXZfYXR0cl9hdmdfZGV2aWNlX2FjdGl2ZV9vbmx5X3RpbWUuYXR0ciwKCSZkZXZfYXR0cl9hdmdfZGV2aWNlX2J1c3lfdGltZS5hdHRyLAoJJmRldl9hdHRyX2F2Z19pbml0aWFsX2NvbW1hbmRfcmVzcG9uc2VfdGltZS5hdHRyLAoJMCwKfTsKCnN0YXRpYyBzdHJ1Y3QgYXR0cmlidXRlX2dyb3VwIGNtZl9hdHRyX2dyb3VwX2V4dCA9IHsKCS5uYW1lICA9ICJjbWYiLAoJLmF0dHJzID0gY21mX2F0dHJpYnV0ZXNfZXh0LAp9OwoKc3RhdGljIHNzaXplX3QgY21iX2VuYWJsZV9zaG93KHN0cnVjdCBkZXZpY2UgKmRldiwgc3RydWN0IGRldmljZV9hdHRyaWJ1dGUgKmF0dHIsIGNoYXIgKmJ1ZikKewoJcmV0dXJuIHNwcmludGYoYnVmLCAiJWRcbiIsIHRvX2Njd2RldihkZXYpLT5wcml2YXRlLT5jbWIgPyAxIDogMCk7Cn0KCnN0YXRpYyBzc2l6ZV90IGNtYl9lbmFibGVfc3RvcmUoc3RydWN0IGRldmljZSAqZGV2LCBzdHJ1Y3QgZGV2aWNlX2F0dHJpYnV0ZSAqYXR0ciwgY29uc3QgY2hhciAqYnVmLCBzaXplX3QgYykKewoJc3RydWN0IGNjd19kZXZpY2UgKmNkZXY7CglpbnQgcmV0OwoKCWNkZXYgPSB0b19jY3dkZXYoZGV2KTsKCglzd2l0Y2ggKGJ1ZlswXSkgewoJY2FzZSAnMCc6CgkJcmV0ID0gZGlzYWJsZV9jbWYoY2Rldik7CgkJaWYgKHJldCkKCQkJcHJpbnRrKEtFUk5fSU5GTyAiZGlzYWJsZV9jbWYgZmFpbGVkICglZClcbiIsIHJldCk7CgkJYnJlYWs7CgljYXNlICcxJzoKCQlyZXQgPSBlbmFibGVfY21mKGNkZXYpOwoJCWlmIChyZXQgJiYgcmV0ICE9IC1FQlVTWSkKCQkJcHJpbnRrKEtFUk5fSU5GTyAiZW5hYmxlX2NtZiBmYWlsZWQgKCVkKVxuIiwgcmV0KTsKCQlicmVhazsKCX0KCglyZXR1cm4gYzsKfQoKREVWSUNFX0FUVFIoY21iX2VuYWJsZSwgMDY0NCwgY21iX2VuYWJsZV9zaG93LCBjbWJfZW5hYmxlX3N0b3JlKTsKCi8qIGVuYWJsZV9jbWYvZGlzYWJsZV9jbWY6IG1vZHVsZSBpbnRlcmZhY2UgZm9yIGNtZiAoZGUpYWN0aXZhdGlvbiAqLwppbnQKZW5hYmxlX2NtZihzdHJ1Y3QgY2N3X2RldmljZSAqY2RldikKewoJaW50IHJldDsKCglyZXQgPSBjbWJvcHMtPmFsbG9jKGNkZXYpOwoJY21ib3BzLT5yZXNldChjZGV2KTsKCWlmIChyZXQpCgkJcmV0dXJuIHJldDsKCXJldCA9IGNtYm9wcy0+c2V0KGNkZXYsIDIpOwoJaWYgKHJldCkgewoJCWNtYm9wcy0+ZnJlZShjZGV2KTsKCQlyZXR1cm4gcmV0OwoJfQoJcmV0ID0gc3lzZnNfY3JlYXRlX2dyb3VwKCZjZGV2LT5kZXYua29iaiwgY21ib3BzLT5hdHRyX2dyb3VwKTsKCWlmICghcmV0KQoJCXJldHVybiAwOwoJY21ib3BzLT5zZXQoY2RldiwgMCk7ICAvL0ZJWE1FOiB0aGlzIGNhbiBmYWlsCgljbWJvcHMtPmZyZWUoY2Rldik7CglyZXR1cm4gcmV0Owp9CgppbnQKZGlzYWJsZV9jbWYoc3RydWN0IGNjd19kZXZpY2UgKmNkZXYpCnsKCWludCByZXQ7CgoJcmV0ID0gY21ib3BzLT5zZXQoY2RldiwgMCk7CglpZiAocmV0KQoJCXJldHVybiByZXQ7CgljbWJvcHMtPmZyZWUoY2Rldik7CglzeXNmc19yZW1vdmVfZ3JvdXAoJmNkZXYtPmRldi5rb2JqLCBjbWJvcHMtPmF0dHJfZ3JvdXApOwoJcmV0dXJuIHJldDsKfQoKdTY0CmNtZl9yZWFkKHN0cnVjdCBjY3dfZGV2aWNlICpjZGV2LCBpbnQgaW5kZXgpCnsKCXJldHVybiBjbWJvcHMtPnJlYWQoY2RldiwgaW5kZXgpOwp9CgppbnQKY21mX3JlYWRhbGwoc3RydWN0IGNjd19kZXZpY2UgKmNkZXYsIHN0cnVjdCBjbWJkYXRhICpkYXRhKQp7CglyZXR1cm4gY21ib3BzLT5yZWFkYWxsKGNkZXYsIGRhdGEpOwp9CgpzdGF0aWMgaW50IF9faW5pdAppbml0X2NtZih2b2lkKQp7CgljaGFyICpmb3JtYXRfc3RyaW5nOwoJY2hhciAqZGV0ZWN0X3N0cmluZyA9ICJwYXJhbWV0ZXIiOwoKCS8qIFdlIGNhbm5vdCByZWFsbHkgYXV0b3Byb2JlIHRoaXMuIElmIHRoZSB1c2VyIGRpZCBub3QgZ2l2ZSBhIHBhcmFtZXRlciwKCSAgIHNlZSBpZiB3ZSBhcmUgcnVubmluZyBvbiB6OTkwIG9yIHVwLCBvdGhlcndpc2UgZmFsbCBiYWNrIHRvIGJhc2ljIG1vZGUuICovCgoJaWYgKGZvcm1hdCA9PSBDTUZfQVVUT0RFVEVDVCkgewoJCWlmICghY3NzX2NoYXJhY3RlcmlzdGljc19hdmFpbCB8fAoJCSAgICAhY3NzX2dlbmVyYWxfY2hhcmFjdGVyaXN0aWNzLmV4dF9tYikgewoJCQlmb3JtYXQgPSBDTUZfQkFTSUM7CgkJfSBlbHNlIHsKCQkJZm9ybWF0ID0gQ01GX0VYVEVOREVEOwoJCX0KCQlkZXRlY3Rfc3RyaW5nID0gImF1dG9kZXRlY3RlZCI7Cgl9IGVsc2UgewoJCWRldGVjdF9zdHJpbmcgPSAicGFyYW1ldGVyIjsKCX0KCglzd2l0Y2ggKGZvcm1hdCkgewoJY2FzZSBDTUZfQkFTSUM6CgkJZm9ybWF0X3N0cmluZyA9ICJiYXNpYyI7CgkJY21ib3BzID0gJmNtYm9wc19iYXNpYzsKCQlpZiAoY21iX2FyZWEubnVtX2NoYW5uZWxzID4gNDA5NiB8fCBjbWJfYXJlYS5udW1fY2hhbm5lbHMgPCAxKSB7CgkJCXByaW50ayhLRVJOX0VSUiAiQmFzaWMgY2hhbm5lbCBtZWFzdXJlbWVudCBmYWNpbGl0eSIKCQkJCQkiIGNhbiBvbmx5IHVzZSAxIHRvIDQwOTYgZGV2aWNlc1xuIgoJCQkgICAgICAgS0VSTl9FUlIgIndoZW4gdGhlIGNtZiBkcml2ZXIgaXMgYnVpbHQiCgkJCQkJIiBhcyBhIGxvYWRhYmxlIG1vZHVsZVxuIik7CgkJCXJldHVybiAxOwoJCX0KCQlicmVhazsKCWNhc2UgQ01GX0VYVEVOREVEOgogCQlmb3JtYXRfc3RyaW5nID0gImV4dGVuZGVkIjsKCQljbWJvcHMgPSAmY21ib3BzX2V4dGVuZGVkOwoJCWJyZWFrOwoJZGVmYXVsdDoKCQlwcmludGsoS0VSTl9FUlIgIkludmFsaWQgZm9ybWF0ICVkIGZvciBjaGFubmVsICIKCQkJIm1lYXN1cmVtZW50IGZhY2lsaXR5XG4iLCBmb3JtYXQpOwoJCXJldHVybiAxOwoJfQoKCXByaW50ayhLRVJOX0lORk8gIkNoYW5uZWwgbWVhc3VyZW1lbnQgZmFjaWxpdHkgdXNpbmcgJXMgZm9ybWF0ICglcylcbiIsCgkJZm9ybWF0X3N0cmluZywgZGV0ZWN0X3N0cmluZyk7CglyZXR1cm4gMDsKfQoKbW9kdWxlX2luaXQoaW5pdF9jbWYpOwoKCk1PRFVMRV9BVVRIT1IoIkFybmQgQmVyZ21hbm4gPGFybmRiQGRlLmlibS5jb20+Iik7Ck1PRFVMRV9MSUNFTlNFKCJHUEwiKTsKTU9EVUxFX0RFU0NSSVBUSU9OKCJjaGFubmVsIG1lYXN1cmVtZW50IGZhY2lsaXR5IGJhc2UgZHJpdmVyXG4iCgkJICAgIkNvcHlyaWdodCAyMDAzIElCTSBDb3Jwb3JhdGlvblxuIik7CgpFWFBPUlRfU1lNQk9MX0dQTChlbmFibGVfY21mKTsKRVhQT1JUX1NZTUJPTF9HUEwoZGlzYWJsZV9jbWYpOwpFWFBPUlRfU1lNQk9MX0dQTChjbWZfcmVhZCk7CkVYUE9SVF9TWU1CT0xfR1BMKGNtZl9yZWFkYWxsKTsK