Ci8qCiAqIElCTSBBU00gU2VydmljZSBQcm9jZXNzb3IgRGV2aWNlIERyaXZlcgogKgogKiBUaGlzIHByb2dyYW0gaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeQogKiBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieQogKiB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIgdmVyc2lvbiAyIG9mIHRoZSBMaWNlbnNlLCBvcgogKiAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZQogKiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiBhbG9uZyB3aXRoIHRoaXMgcHJvZ3JhbTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZQogKiBGb3VuZGF0aW9uLCBJbmMuLCA1OSBUZW1wbGUgUGxhY2UgLSBTdWl0ZSAzMzAsIEJvc3RvbiwgTUEgMDIxMTEtMTMwNywgVVNBLgogKgogKiBDb3B5cmlnaHQgKEMpIElCTSBDb3Jwb3JhdGlvbiwgMjAwNAogKgogKiBBdXRob3I6IE1heCBBc2L2Y2sgPGFtYXhAdXMuaWJtLmNvbT4KICoKICogVGhpcyBkcml2ZXIgaXMgYmFzZWQgb24gY29kZSBvcmlnaW5hbGx5IHdyaXR0ZW4gYnkgUGV0ZSBSZXlub2xkcwogKiBhbmQgb3RoZXJzLgogKgogKi8KCi8qCiAqIFRoZSBBU00gZGV2aWNlIGRyaXZlciBkb2VzIHRoZSBmb2xsb3dpbmcgdGhpbmdzOgogKgogKiAxKSBXaGVuIGxvYWRlZCBpdCBzZW5kcyBhIG1lc3NhZ2UgdG8gdGhlIHNlcnZpY2UgcHJvY2Vzc29yLAogKiBpbmRpY2F0aW5nIHRoYXQgYW4gT1MgaXMgKiBydW5uaW5nLiBUaGlzIGNhdXNlcyB0aGUgc2VydmljZSBwcm9jZXNzb3IKICogdG8gc2VuZCBwZXJpb2RpYyBoZWFydGJlYXRzIHRvIHRoZSBPUy4KICoKICogMikgQW5zd2VycyB0aGUgcGVyaW9kaWMgaGVhcnRiZWF0cyBzZW50IGJ5IHRoZSBzZXJ2aWNlIHByb2Nlc3Nvci4KICogRmFpbHVyZSB0byBkbyBzbyB3b3VsZCByZXN1bHQgaW4gc3lzdGVtIHJlYm9vdC4KICoKICogMykgQWN0cyBhcyBhIHBhc3MgdGhyb3VnaCBmb3IgZG90IGNvbW1hbmRzIHNlbnQgZnJvbSB1c2VyIGFwcGxpY2F0aW9ucy4KICogVGhlIGludGVyZmFjZSBmb3IgdGhpcyBpcyB0aGUgaWJtYXNtZnMgZmlsZSBzeXN0ZW0uCiAqCiAqIDQpIEFsbG93cyB1c2VyIGFwcGxpY2F0aW9ucyB0byByZWdpc3RlciBmb3IgZXZlbnQgbm90aWZpY2F0aW9uLiBFdmVudHMKICogYXJlIHNlbnQgdG8gdGhlIGRyaXZlciB0aHJvdWdoIGludGVycnVwdHMuIFRoZXkgY2FuIGJlIHJlYWQgZnJvbSB1c2VyCiAqIHNwYWNlIHRocm91Z2ggdGhlIGlibWFzbWZzIGZpbGUgc3lzdGVtLgogKgogKiA1KSBBbGxvd3MgdXNlciBzcGFjZSBhcHBsaWNhdGlvbnMgdG8gc2VuZCBoZWFydGJlYXRzIHRvIHRoZSBzZXJ2aWNlCiAqIHByb2Nlc3NvciAoYWthIHJldmVyc2UgaGVhcnRiZWF0cykuIEFnYWluIHRoaXMgaGFwcGVucyB0aHJvdWdoIGlibWFzbWZzLgogKgogKiA2KSBIYW5kbGVzIHJlbW90ZSBtb3VzZSBhbmQga2V5Ym9hcmQgZXZlbnQgaW50ZXJydXB0cyBhbmQgbWFrZXMgdGhlbQogKiBhdmFpbGFibGUgdG8gdXNlciBhcHBsaWNhdGlvbnMgdGhyb3VnaCBpYm1hc21mcy4KICoKICovCgojaW5jbHVkZSA8bGludXgvcGNpLmg+CiNpbmNsdWRlIDxsaW51eC9pbml0Lmg+CiNpbmNsdWRlICJpYm1hc20uaCIKI2luY2x1ZGUgImxvd2xldmVsLmgiCiNpbmNsdWRlICJyZW1vdGUuaCIKCmludCBpYm1hc21fZGVidWcgPSAwOwptb2R1bGVfcGFyYW0oaWJtYXNtX2RlYnVnLCBpbnQgLCBTX0lSVUdPIHwgU19JV1VTUik7Ck1PRFVMRV9QQVJNX0RFU0MoaWJtYXNtX2RlYnVnLCAiIFNldCBkZWJ1ZyBtb2RlIG9uIG9yIG9mZiIpOwoKCnN0YXRpYyBpbnQgX19kZXZpbml0IGlibWFzbV9pbml0X29uZShzdHJ1Y3QgcGNpX2RldiAqcGRldiwgY29uc3Qgc3RydWN0IHBjaV9kZXZpY2VfaWQgKmlkKQp7CglpbnQgcmVzdWx0OwoJc3RydWN0IHNlcnZpY2VfcHJvY2Vzc29yICpzcDsKCglpZiAoKHJlc3VsdCA9IHBjaV9lbmFibGVfZGV2aWNlKHBkZXYpKSkgewoJCWRldl9lcnIoJnBkZXYtPmRldiwgIkZhaWxlZCB0byBlbmFibGUgUENJIGRldmljZVxuIik7CgkJcmV0dXJuIHJlc3VsdDsKCX0KCWlmICgocmVzdWx0ID0gcGNpX3JlcXVlc3RfcmVnaW9ucyhwZGV2LCBEUklWRVJfTkFNRSkpKSB7CgkJZGV2X2VycigmcGRldi0+ZGV2LCAiRmFpbGVkIHRvIGFsbG9jYXRlIFBDSSByZXNvdXJjZXNcbiIpOwoJCWdvdG8gZXJyb3JfcmVzb3VyY2VzOwoJfQoJLyogdm5jIGNsaWVudCB3b24ndCB3b3JrIHdpdGhvdXQgYnVzLW1hc3RlcmluZyAqLwoJcGNpX3NldF9tYXN0ZXIocGRldik7CgoJc3AgPSBremFsbG9jKHNpemVvZihzdHJ1Y3Qgc2VydmljZV9wcm9jZXNzb3IpLCBHRlBfS0VSTkVMKTsKCWlmIChzcCA9PSBOVUxMKSB7CgkJZGV2X2VycigmcGRldi0+ZGV2LCAiRmFpbGVkIHRvIGFsbG9jYXRlIG1lbW9yeVxuIik7CgkJcmVzdWx0ID0gLUVOT01FTTsKCQlnb3RvIGVycm9yX2ttYWxsb2M7Cgl9CgoJc3Bpbl9sb2NrX2luaXQoJnNwLT5sb2NrKTsKCUlOSVRfTElTVF9IRUFEKCZzcC0+Y29tbWFuZF9xdWV1ZSk7CgoJcGNpX3NldF9kcnZkYXRhKHBkZXYsICh2b2lkICopc3ApOwoJc3AtPmRldiA9ICZwZGV2LT5kZXY7CglzcC0+bnVtYmVyID0gcGRldi0+YnVzLT5udW1iZXI7CglzbnByaW50ZihzcC0+ZGlybmFtZSwgSUJNQVNNX05BTUVfU0laRSwgIiVkIiwgc3AtPm51bWJlcik7CglzbnByaW50ZihzcC0+ZGV2bmFtZSwgSUJNQVNNX05BTUVfU0laRSwgIiVzJWQiLCBEUklWRVJfTkFNRSwgc3AtPm51bWJlcik7CgoJaWYgKGlibWFzbV9ldmVudF9idWZmZXJfaW5pdChzcCkpIHsKCQlkZXZfZXJyKHNwLT5kZXYsICJGYWlsZWQgdG8gYWxsb2NhdGUgZXZlbnQgYnVmZmVyXG4iKTsKCQlnb3RvIGVycm9yX2V2ZW50YnVmZmVyOwoJfQoKCWlmIChpYm1hc21faGVhcnRiZWF0X2luaXQoc3ApKSB7CgkJZGV2X2VycihzcC0+ZGV2LCAiRmFpbGVkIHRvIGFsbG9jYXRlIGhlYXJ0YmVhdCBjb21tYW5kXG4iKTsKCQlnb3RvIGVycm9yX2hlYXJ0YmVhdDsKCX0KCglzcC0+aXJxID0gcGRldi0+aXJxOwoJc3AtPmJhc2VfYWRkcmVzcyA9IGlvcmVtYXAocGNpX3Jlc291cmNlX3N0YXJ0KHBkZXYsIDApLAoJCQkJCXBjaV9yZXNvdXJjZV9sZW4ocGRldiwgMCkpOwoJaWYgKCFzcC0+YmFzZV9hZGRyZXNzKSB7CgkJZGV2X2VycihzcC0+ZGV2LCAiRmFpbGVkIHRvIGlvcmVtYXAgcGNpIG1lbW9yeVxuIik7CgkJcmVzdWx0ID0gIC1FTk9ERVY7CgkJZ290byBlcnJvcl9pb3JlbWFwOwoJfQoKCXJlc3VsdCA9IHJlcXVlc3RfaXJxKHNwLT5pcnEsIGlibWFzbV9pbnRlcnJ1cHRfaGFuZGxlciwgSVJRRl9TSEFSRUQsIHNwLT5kZXZuYW1lLCAodm9pZCopc3ApOwoJaWYgKHJlc3VsdCkgewoJCWRldl9lcnIoc3AtPmRldiwgIkZhaWxlZCB0byByZWdpc3RlciBpbnRlcnJ1cHQgaGFuZGxlclxuIik7CgkJZ290byBlcnJvcl9yZXF1ZXN0X2lycTsKCX0KCgllbmFibGVfc3BfaW50ZXJydXB0cyhzcC0+YmFzZV9hZGRyZXNzKTsKCglyZXN1bHQgPSBpYm1hc21faW5pdF9yZW1vdGVfaW5wdXRfZGV2KHNwKTsKCWlmIChyZXN1bHQpIHsKCQlkZXZfZXJyKHNwLT5kZXYsICJGYWlsZWQgdG8gaW5pdGlhbGl6ZSByZW1vdGUgcXVldWVcbiIpOwoJCWdvdG8gZXJyb3Jfc2VuZF9tZXNzYWdlOwoJfQoKCXJlc3VsdCA9IGlibWFzbV9zZW5kX2RyaXZlcl92cGQoc3ApOwoJaWYgKHJlc3VsdCkgewoJCWRldl9lcnIoc3AtPmRldiwgIkZhaWxlZCB0byBzZW5kIGRyaXZlciBWUEQgdG8gc2VydmljZSBwcm9jZXNzb3JcbiIpOwoJCWdvdG8gZXJyb3Jfc2VuZF9tZXNzYWdlOwoJfQoJcmVzdWx0ID0gaWJtYXNtX3NlbmRfb3Nfc3RhdGUoc3AsIFNZU1RFTV9TVEFURV9PU19VUCk7CglpZiAocmVzdWx0KSB7CgkJZGV2X2VycihzcC0+ZGV2LCAiRmFpbGVkIHRvIHNlbmQgT1Mgc3RhdGUgdG8gc2VydmljZSBwcm9jZXNzb3JcbiIpOwoJCWdvdG8gZXJyb3Jfc2VuZF9tZXNzYWdlOwoJfQoJaWJtYXNtZnNfYWRkX3NwKHNwKTsKCglpYm1hc21fcmVnaXN0ZXJfdWFydChzcCk7CgoJcmV0dXJuIDA7CgplcnJvcl9zZW5kX21lc3NhZ2U6CglkaXNhYmxlX3NwX2ludGVycnVwdHMoc3AtPmJhc2VfYWRkcmVzcyk7CglpYm1hc21fZnJlZV9yZW1vdGVfaW5wdXRfZGV2KHNwKTsKCWZyZWVfaXJxKHNwLT5pcnEsICh2b2lkICopc3ApOwplcnJvcl9yZXF1ZXN0X2lycToKCWlvdW5tYXAoc3AtPmJhc2VfYWRkcmVzcyk7CmVycm9yX2lvcmVtYXA6CglpYm1hc21faGVhcnRiZWF0X2V4aXQoc3ApOwplcnJvcl9oZWFydGJlYXQ6CglpYm1hc21fZXZlbnRfYnVmZmVyX2V4aXQoc3ApOwplcnJvcl9ldmVudGJ1ZmZlcjoKCXBjaV9zZXRfZHJ2ZGF0YShwZGV2LCBOVUxMKTsKCWtmcmVlKHNwKTsKZXJyb3Jfa21hbGxvYzoKICAgICAgICBwY2lfcmVsZWFzZV9yZWdpb25zKHBkZXYpOwplcnJvcl9yZXNvdXJjZXM6CiAgICAgICAgcGNpX2Rpc2FibGVfZGV2aWNlKHBkZXYpOwoKCXJldHVybiByZXN1bHQ7Cn0KCnN0YXRpYyB2b2lkIF9fZGV2ZXhpdCBpYm1hc21fcmVtb3ZlX29uZShzdHJ1Y3QgcGNpX2RldiAqcGRldikKewoJc3RydWN0IHNlcnZpY2VfcHJvY2Vzc29yICpzcCA9IChzdHJ1Y3Qgc2VydmljZV9wcm9jZXNzb3IgKilwY2lfZ2V0X2RydmRhdGEocGRldik7CgoJZGJnKCJVbnJlZ2lzdGVyaW5nIFVBUlRcbiIpOwoJaWJtYXNtX3VucmVnaXN0ZXJfdWFydChzcCk7CglkYmcoIlNlbmRpbmcgT1MgZG93biBtZXNzYWdlXG4iKTsKCWlmIChpYm1hc21fc2VuZF9vc19zdGF0ZShzcCwgU1lTVEVNX1NUQVRFX09TX0RPV04pKQoJCWVycigiZmFpbGVkIHRvIGdldCByZXBzb25zZSB0byAnU2VuZCBPUyBTdGF0ZScgY29tbWFuZFxuIik7CglkYmcoIkRpc2FibGluZyBoZWFydGJlYXRzXG4iKTsKCWlibWFzbV9oZWFydGJlYXRfZXhpdChzcCk7CglkYmcoIkRpc2FibGluZyBpbnRlcnJ1cHRzXG4iKTsKCWRpc2FibGVfc3BfaW50ZXJydXB0cyhzcC0+YmFzZV9hZGRyZXNzKTsKCWRiZygiRnJlZWluZyBTUCBpcnFcbiIpOwoJZnJlZV9pcnEoc3AtPmlycSwgKHZvaWQgKilzcCk7CglkYmcoIkNsZWFuaW5nIHVwXG4iKTsKCWlibWFzbV9mcmVlX3JlbW90ZV9pbnB1dF9kZXYoc3ApOwoJaW91bm1hcChzcC0+YmFzZV9hZGRyZXNzKTsKCWlibWFzbV9ldmVudF9idWZmZXJfZXhpdChzcCk7CglwY2lfc2V0X2RydmRhdGEocGRldiwgTlVMTCk7CglrZnJlZShzcCk7CglwY2lfcmVsZWFzZV9yZWdpb25zKHBkZXYpOwoJcGNpX2Rpc2FibGVfZGV2aWNlKHBkZXYpOwp9CgpzdGF0aWMgc3RydWN0IHBjaV9kZXZpY2VfaWQgaWJtYXNtX3BjaV90YWJsZVtdID0KewoJeyBQQ0lfREVWSUNFKFZFTkRPUklEX0lCTSwgREVWSUNFSURfUlNBKSB9LAoJe30sCn07CgpzdGF0aWMgc3RydWN0IHBjaV9kcml2ZXIgaWJtYXNtX2RyaXZlciA9IHsKCS5uYW1lCQk9IERSSVZFUl9OQU1FLAoJLmlkX3RhYmxlCT0gaWJtYXNtX3BjaV90YWJsZSwKCS5wcm9iZQkJPSBpYm1hc21faW5pdF9vbmUsCgkucmVtb3ZlCQk9IF9fZGV2ZXhpdF9wKGlibWFzbV9yZW1vdmVfb25lKSwKfTsKCnN0YXRpYyB2b2lkIF9fZXhpdCBpYm1hc21fZXhpdCAodm9pZCkKewoJaWJtYXNtX3VucmVnaXN0ZXJfcGFuaWNfbm90aWZpZXIoKTsKCWlibWFzbWZzX3VucmVnaXN0ZXIoKTsKCXBjaV91bnJlZ2lzdGVyX2RyaXZlcigmaWJtYXNtX2RyaXZlcik7CglpbmZvKERSSVZFUl9ERVNDICIgdmVyc2lvbiAiIERSSVZFUl9WRVJTSU9OICIgdW5sb2FkZWQiKTsKfQoKc3RhdGljIGludCBfX2luaXQgaWJtYXNtX2luaXQodm9pZCkKewoJaW50IHJlc3VsdDsKCglyZXN1bHQgPSBpYm1hc21mc19yZWdpc3RlcigpOwoJaWYgKHJlc3VsdCkgewoJCWVycigiRmFpbGVkIHRvIHJlZ2lzdGVyIGlibWFzbWZzIGZpbGUgc3lzdGVtIik7CgkJcmV0dXJuIHJlc3VsdDsKCX0KCXJlc3VsdCA9IHBjaV9yZWdpc3Rlcl9kcml2ZXIoJmlibWFzbV9kcml2ZXIpOwoJaWYgKHJlc3VsdCkgewoJCWlibWFzbWZzX3VucmVnaXN0ZXIoKTsKCQlyZXR1cm4gcmVzdWx0OwoJfQoJaWJtYXNtX3JlZ2lzdGVyX3BhbmljX25vdGlmaWVyKCk7CglpbmZvKERSSVZFUl9ERVNDICIgdmVyc2lvbiAiIERSSVZFUl9WRVJTSU9OICIgbG9hZGVkIik7CglyZXR1cm4gMDsKfQoKbW9kdWxlX2luaXQoaWJtYXNtX2luaXQpOwptb2R1bGVfZXhpdChpYm1hc21fZXhpdCk7CgpNT0RVTEVfQVVUSE9SKERSSVZFUl9BVVRIT1IpOwpNT0RVTEVfREVTQ1JJUFRJT04oRFJJVkVSX0RFU0MpOwpNT0RVTEVfTElDRU5TRSgiR1BMIik7Ck1PRFVMRV9ERVZJQ0VfVEFCTEUocGNpLCBpYm1hc21fcGNpX3RhYmxlKTsKCg==