Ci8qCiAqIElCTSBBU00gU2VydmljZSBQcm9jZXNzb3IgRGV2aWNlIERyaXZlcgogKgogKiBUaGlzIHByb2dyYW0gaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeQogKiBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieQogKiB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIgdmVyc2lvbiAyIG9mIHRoZSBMaWNlbnNlLCBvcgogKiAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZQogKiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiBhbG9uZyB3aXRoIHRoaXMgcHJvZ3JhbTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZQogKiBGb3VuZGF0aW9uLCBJbmMuLCA1OSBUZW1wbGUgUGxhY2UgLSBTdWl0ZSAzMzAsIEJvc3RvbiwgTUEgMDIxMTEtMTMwNywgVVNBLgogKgogKiBDb3B5cmlnaHQgKEMpIElCTSBDb3Jwb3JhdGlvbiwgMjAwNAogKgogKiBBdXRob3I6IE1heCBBc2L2Y2sgPGFtYXhAdXMuaWJtLmNvbT4gCiAqCiAqIFRoaXMgZHJpdmVyIGlzIGJhc2VkIG9uIGNvZGUgb3JpZ2luYWxseSB3cml0dGVuIGJ5IFBldGUgUmV5bm9sZHMgCiAqIGFuZCBvdGhlcnMuCiAqCiAqLwoKLyoKICogVGhlIEFTTSBkZXZpY2UgZHJpdmVyIGRvZXMgdGhlIGZvbGxvd2luZyB0aGluZ3M6CiAqCiAqIDEpIFdoZW4gbG9hZGVkIGl0IHNlbmRzIGEgbWVzc2FnZSB0byB0aGUgc2VydmljZSBwcm9jZXNzb3IsCiAqIGluZGljYXRpbmcgdGhhdCBhbiBPUyBpcyAqIHJ1bm5pbmcuIFRoaXMgY2F1c2VzIHRoZSBzZXJ2aWNlIHByb2Nlc3NvcgogKiB0byBzZW5kIHBlcmlvZGljIGhlYXJ0YmVhdHMgdG8gdGhlIE9TLiAKICoKICogMikgQW5zd2VycyB0aGUgcGVyaW9kaWMgaGVhcnRiZWF0cyBzZW50IGJ5IHRoZSBzZXJ2aWNlIHByb2Nlc3Nvci4KICogRmFpbHVyZSB0byBkbyBzbyB3b3VsZCByZXN1bHQgaW4gc3lzdGVtIHJlYm9vdC4KICoKICogMykgQWN0cyBhcyBhIHBhc3MgdGhyb3VnaCBmb3IgZG90IGNvbW1hbmRzIHNlbnQgZnJvbSB1c2VyIGFwcGxpY2F0aW9ucy4KICogVGhlIGludGVyZmFjZSBmb3IgdGhpcyBpcyB0aGUgaWJtYXNtZnMgZmlsZSBzeXN0ZW0uIAogKgogKiA0KSBBbGxvd3MgdXNlciBhcHBsaWNhdGlvbnMgdG8gcmVnaXN0ZXIgZm9yIGV2ZW50IG5vdGlmaWNhdGlvbi4gRXZlbnRzCiAqIGFyZSBzZW50IHRvIHRoZSBkcml2ZXIgdGhyb3VnaCBpbnRlcnJ1cHRzLiBUaGV5IGNhbiBiZSByZWFkIGZyb20gdXNlcgogKiBzcGFjZSB0aHJvdWdoIHRoZSBpYm1hc21mcyBmaWxlIHN5c3RlbS4KICoKICogNSkgQWxsb3dzIHVzZXIgc3BhY2UgYXBwbGljYXRpb25zIHRvIHNlbmQgaGVhcnRiZWF0cyB0byB0aGUgc2VydmljZQogKiBwcm9jZXNzb3IgKGFrYSByZXZlcnNlIGhlYXJ0YmVhdHMpLiBBZ2FpbiB0aGlzIGhhcHBlbnMgdGhyb3VnaCBpYm1hc21mcy4KICoKICogNikgSGFuZGxlcyByZW1vdGUgbW91c2UgYW5kIGtleWJvYXJkIGV2ZW50IGludGVycnVwdHMgYW5kIG1ha2VzIHRoZW0KICogYXZhaWxhYmxlIHRvIHVzZXIgYXBwbGljYXRpb25zIHRocm91Z2ggaWJtYXNtZnMuCiAqCiAqLwoKI2luY2x1ZGUgPGxpbnV4L3BjaS5oPgojaW5jbHVkZSA8bGludXgvaW5pdC5oPgojaW5jbHVkZSAiaWJtYXNtLmgiCiNpbmNsdWRlICJsb3dsZXZlbC5oIgojaW5jbHVkZSAicmVtb3RlLmgiCgoKc3RhdGljIGludCBfX2RldmluaXQgaWJtYXNtX2luaXRfb25lKHN0cnVjdCBwY2lfZGV2ICpwZGV2LCBjb25zdCBzdHJ1Y3QgcGNpX2RldmljZV9pZCAqaWQpCnsKCWludCBlcnIsIHJlc3VsdCA9IC1FTk9NRU07CglzdHJ1Y3Qgc2VydmljZV9wcm9jZXNzb3IgKnNwOwoKCWlmICgoZXJyID0gcGNpX2VuYWJsZV9kZXZpY2UocGRldikpKSB7CgkJcHJpbnRrKEtFUk5fRVJSICIlczogY2FuJ3QgZW5hYmxlIFBDSSBkZXZpY2UgYXQgJXNcbiIsCgkJCURSSVZFUl9OQU1FLCBwY2lfbmFtZShwZGV2KSk7CgkJcmV0dXJuIGVycjsKCX0KCglzcCA9IGttYWxsb2Moc2l6ZW9mKHN0cnVjdCBzZXJ2aWNlX3Byb2Nlc3NvciksIEdGUF9LRVJORUwpOwoJaWYgKHNwID09IE5VTEwpIHsKCQlkZXZfZXJyKCZwZGV2LT5kZXYsICJGYWlsZWQgdG8gYWxsb2NhdGUgbWVtb3J5XG4iKTsKCQlyZXN1bHQgPSAtRU5PTUVNOwoJCWdvdG8gZXJyb3Jfa21hbGxvYzsKCX0KCW1lbXNldChzcCwgMCwgc2l6ZW9mKHN0cnVjdCBzZXJ2aWNlX3Byb2Nlc3NvcikpOwoKCXBjaV9zZXRfZHJ2ZGF0YShwZGV2LCAodm9pZCAqKXNwKTsKCXNwLT5kZXYgPSAmcGRldi0+ZGV2OwoJc3AtPm51bWJlciA9IHBkZXYtPmJ1cy0+bnVtYmVyOwoJc25wcmludGYoc3AtPmRpcm5hbWUsIElCTUFTTV9OQU1FX1NJWkUsICIlZCIsIHNwLT5udW1iZXIpOwoJc25wcmludGYoc3AtPmRldm5hbWUsIElCTUFTTV9OQU1FX1NJWkUsICIlcyVkIiwgRFJJVkVSX05BTUUsIHNwLT5udW1iZXIpOwoKCWlmIChpYm1hc21fZXZlbnRfYnVmZmVyX2luaXQoc3ApKSB7CgkJZGV2X2VycihzcC0+ZGV2LCAiRmFpbGVkIHRvIGFsbG9jYXRlIGV2ZW50IGJ1ZmZlclxuIik7CgkJZ290byBlcnJvcl9ldmVudGJ1ZmZlcjsKCX0KCglpZiAoaWJtYXNtX2hlYXJ0YmVhdF9pbml0KHNwKSkgewoJCWRldl9lcnIoc3AtPmRldiwgIkZhaWxlZCB0byBhbGxvY2F0ZSBoZWFydGJlYXQgY29tbWFuZFxuIik7CgkJZ290byBlcnJvcl9oZWFydGJlYXQ7Cgl9CgoJc3AtPmlycSA9IHBkZXYtPmlycTsKCXNwLT5iYXNlX2FkZHJlc3MgPSBpb3JlbWFwKHBjaV9yZXNvdXJjZV9zdGFydChwZGV2LCAwKSwgCgkJCQkJcGNpX3Jlc291cmNlX2xlbihwZGV2LCAwKSk7CglpZiAoc3AtPmJhc2VfYWRkcmVzcyA9PSAwKSB7CgkJZGV2X2VycihzcC0+ZGV2LCAiRmFpbGVkIHRvIGlvcmVtYXAgcGNpIG1lbW9yeVxuIik7CgkJcmVzdWx0ID0gIC1FTk9ERVY7CgkJZ290byBlcnJvcl9pb3JlbWFwOwoJfQoKCXJlc3VsdCA9IGlibWFzbV9pbml0X3JlbW90ZV9xdWV1ZShzcCk7CglpZiAocmVzdWx0KSB7CgkJZGV2X2VycihzcC0+ZGV2LCAiRmFpbGVkIHRvIGluaXRpYWxpemUgcmVtb3RlIHF1ZXVlXG4iKTsKCQlnb3RvIGVycm9yX3JlbW90ZV9xdWV1ZTsKCX0KCglzcGluX2xvY2tfaW5pdCgmc3AtPmxvY2spOwoJSU5JVF9MSVNUX0hFQUQoJnNwLT5jb21tYW5kX3F1ZXVlKTsKCglyZXN1bHQgPSByZXF1ZXN0X2lycShzcC0+aXJxLCBpYm1hc21faW50ZXJydXB0X2hhbmRsZXIsIFNBX1NISVJRLCBzcC0+ZGV2bmFtZSwgKHZvaWQqKXNwKTsKCWlmIChyZXN1bHQpIHsKCQlkZXZfZXJyKHNwLT5kZXYsICJGYWlsZWQgdG8gcmVnaXN0ZXIgaW50ZXJydXB0IGhhbmRsZXJcbiIpOwoJCWdvdG8gZXJyb3JfcmVxdWVzdF9pcnE7Cgl9CgoJZW5hYmxlX3NwX2ludGVycnVwdHMoc3AtPmJhc2VfYWRkcmVzcyk7CglkaXNhYmxlX21vdXNlX2ludGVycnVwdHMoc3ApOwoKCXJlc3VsdCA9IGlibWFzbV9zZW5kX2RyaXZlcl92cGQoc3ApOwoJaWYgKHJlc3VsdCkgewoJCWRldl9lcnIoc3AtPmRldiwgIkZhaWxlZCB0byBzZW5kIGRyaXZlciBWUEQgdG8gc2VydmljZSBwcm9jZXNzb3JcbiIpOwoJCWdvdG8gZXJyb3Jfc2VuZF9tZXNzYWdlOwoJfQoJcmVzdWx0ID0gaWJtYXNtX3NlbmRfb3Nfc3RhdGUoc3AsIFNZU1RFTV9TVEFURV9PU19VUCk7CglpZiAocmVzdWx0KSB7CgkJZGV2X2VycihzcC0+ZGV2LCAiRmFpbGVkIHRvIHNlbmQgT1Mgc3RhdGUgdG8gc2VydmljZSBwcm9jZXNzb3JcbiIpOwoJCWdvdG8gZXJyb3Jfc2VuZF9tZXNzYWdlOwoJfQoJaWJtYXNtZnNfYWRkX3NwKHNwKTsKCglpYm1hc21fcmVnaXN0ZXJfdWFydChzcCk7CgoJZGV2X3ByaW50ayhLRVJOX0RFQlVHLCAmcGRldi0+ZGV2LCAiV0FSTklORzogVGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIHN1cHBvcnRlZCBvciBmdW5jdGlvblxuIik7CglkZXZfcHJpbnRrKEtFUk5fREVCVUcsICZwZGV2LT5kZXYsICJjb3JyZWN0bHkgb24geW91ciBJQk0gc2VydmVyLiBQbGVhc2UgY29uc3VsdCB0aGUgSUJNXG4iKTsKCWRldl9wcmludGsoS0VSTl9ERUJVRywgJnBkZXYtPmRldiwgIlNlcnZlclByb3ZlbiB3ZWJzaXRlXG4iKTsKCWRldl9wcmludGsoS0VSTl9ERUJVRywgJnBkZXYtPmRldiwgImh0dHA6Ly93d3cucGMuaWJtLmNvbS93dy9lc2VydmVyL3hzZXJpZXMvc2VydmVycHJvdmVuXG4iKTsKCWRldl9wcmludGsoS0VSTl9ERUJVRywgJnBkZXYtPmRldiwgImZvciBpbmZvcm1hdGlvbiBvbiB0aGUgc3BlY2lmaWMgZHJpdmVyIGxldmVsIGFuZCBzdXBwb3J0XG4iKTsKCWRldl9wcmludGsoS0VSTl9ERUJVRywgJnBkZXYtPmRldiwgInN0YXRlbWVudCBmb3IgeW91ciBJQk0gc2VydmVyLlxuIik7CgoJcmV0dXJuIDA7CgplcnJvcl9zZW5kX21lc3NhZ2U6CglkaXNhYmxlX3NwX2ludGVycnVwdHMoc3AtPmJhc2VfYWRkcmVzcyk7CglmcmVlX2lycShzcC0+aXJxLCAodm9pZCAqKXNwKTsKZXJyb3JfcmVxdWVzdF9pcnE6CglpYm1hc21fZnJlZV9yZW1vdGVfcXVldWUoc3ApOwplcnJvcl9yZW1vdGVfcXVldWU6Cglpb3VubWFwKHNwLT5iYXNlX2FkZHJlc3MpOwplcnJvcl9pb3JlbWFwOgoJaWJtYXNtX2hlYXJ0YmVhdF9leGl0KHNwKTsKZXJyb3JfaGVhcnRiZWF0OgoJaWJtYXNtX2V2ZW50X2J1ZmZlcl9leGl0KHNwKTsKZXJyb3JfZXZlbnRidWZmZXI6CglrZnJlZShzcCk7CmVycm9yX2ttYWxsb2M6CglwY2lfZGlzYWJsZV9kZXZpY2UocGRldik7CgoJcmV0dXJuIHJlc3VsdDsKfQoKc3RhdGljIHZvaWQgX19kZXZleGl0IGlibWFzbV9yZW1vdmVfb25lKHN0cnVjdCBwY2lfZGV2ICpwZGV2KQp7CglzdHJ1Y3Qgc2VydmljZV9wcm9jZXNzb3IgKnNwID0gKHN0cnVjdCBzZXJ2aWNlX3Byb2Nlc3NvciAqKXBjaV9nZXRfZHJ2ZGF0YShwZGV2KTsKCglpYm1hc21fdW5yZWdpc3Rlcl91YXJ0KHNwKTsKCWlibWFzbV9zZW5kX29zX3N0YXRlKHNwLCBTWVNURU1fU1RBVEVfT1NfRE9XTik7CglkaXNhYmxlX3NwX2ludGVycnVwdHMoc3AtPmJhc2VfYWRkcmVzcyk7CglkaXNhYmxlX21vdXNlX2ludGVycnVwdHMoc3ApOwoJZnJlZV9pcnEoc3AtPmlycSwgKHZvaWQgKilzcCk7CglpYm1hc21faGVhcnRiZWF0X2V4aXQoc3ApOwoJaWJtYXNtX2ZyZWVfcmVtb3RlX3F1ZXVlKHNwKTsKCWlvdW5tYXAoc3AtPmJhc2VfYWRkcmVzcyk7CglpYm1hc21fZXZlbnRfYnVmZmVyX2V4aXQoc3ApOwoJa2ZyZWUoc3ApOwoJcGNpX2Rpc2FibGVfZGV2aWNlKHBkZXYpOwp9CgpzdGF0aWMgc3RydWN0IHBjaV9kZXZpY2VfaWQgaWJtYXNtX3BjaV90YWJsZVtdID0KewoJeyBQQ0lfREVWSUNFKFZFTkRPUklEX0lCTSwgREVWSUNFSURfUlNBKSB9LAoJe30sCn07CgpzdGF0aWMgc3RydWN0IHBjaV9kcml2ZXIgaWJtYXNtX2RyaXZlciA9IHsKCS5uYW1lCQk9IERSSVZFUl9OQU1FLAoJLmlkX3RhYmxlCT0gaWJtYXNtX3BjaV90YWJsZSwKCS5wcm9iZQkJPSBpYm1hc21faW5pdF9vbmUsCgkucmVtb3ZlCQk9IF9fZGV2ZXhpdF9wKGlibWFzbV9yZW1vdmVfb25lKSwKfTsKCnN0YXRpYyB2b2lkIF9fZXhpdCBpYm1hc21fZXhpdCAodm9pZCkKewoJaWJtYXNtX3VucmVnaXN0ZXJfcGFuaWNfbm90aWZpZXIoKTsKCWlibWFzbWZzX3VucmVnaXN0ZXIoKTsKCXBjaV91bnJlZ2lzdGVyX2RyaXZlcigmaWJtYXNtX2RyaXZlcik7CglpbmZvKERSSVZFUl9ERVNDICIgdmVyc2lvbiAiIERSSVZFUl9WRVJTSU9OICIgdW5sb2FkZWQiKTsKfQoKc3RhdGljIGludCBfX2luaXQgaWJtYXNtX2luaXQodm9pZCkKewoJaW50IHJlc3VsdDsKCglyZXN1bHQgPSBpYm1hc21mc19yZWdpc3RlcigpOwoJaWYgKHJlc3VsdCkgewoJCWVycigiRmFpbGVkIHRvIHJlZ2lzdGVyIGlibWFzbWZzIGZpbGUgc3lzdGVtIik7CgkJcmV0dXJuIHJlc3VsdDsKCX0KCXJlc3VsdCA9IHBjaV9yZWdpc3Rlcl9kcml2ZXIoJmlibWFzbV9kcml2ZXIpOwoJaWYgKHJlc3VsdCkgewoJCWlibWFzbWZzX3VucmVnaXN0ZXIoKTsKCQlyZXR1cm4gcmVzdWx0OwoJfQoJaWJtYXNtX3JlZ2lzdGVyX3BhbmljX25vdGlmaWVyKCk7CglpbmZvKERSSVZFUl9ERVNDICIgdmVyc2lvbiAiIERSSVZFUl9WRVJTSU9OICIgbG9hZGVkIik7CglyZXR1cm4gMDsKfQoKbW9kdWxlX2luaXQoaWJtYXNtX2luaXQpOwptb2R1bGVfZXhpdChpYm1hc21fZXhpdCk7CgpNT0RVTEVfQVVUSE9SKERSSVZFUl9BVVRIT1IpOwpNT0RVTEVfREVTQ1JJUFRJT04oRFJJVkVSX0RFU0MpOwpNT0RVTEVfTElDRU5TRSgiR1BMIik7Ck1PRFVMRV9ERVZJQ0VfVEFCTEUocGNpLCBpYm1hc21fcGNpX3RhYmxlKTsKCg==