Ci8qCiAqIElCTSBBU00gU2VydmljZSBQcm9jZXNzb3IgRGV2aWNlIERyaXZlcgogKgogKiBUaGlzIHByb2dyYW0gaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeQogKiBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieQogKiB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIgdmVyc2lvbiAyIG9mIHRoZSBMaWNlbnNlLCBvcgogKiAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZQogKiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiBhbG9uZyB3aXRoIHRoaXMgcHJvZ3JhbTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZQogKiBGb3VuZGF0aW9uLCBJbmMuLCA1OSBUZW1wbGUgUGxhY2UgLSBTdWl0ZSAzMzAsIEJvc3RvbiwgTUEgMDIxMTEtMTMwNywgVVNBLgogKgogKiBDb3B5cmlnaHQgKEMpIElCTSBDb3Jwb3JhdGlvbiwgMjAwNAogKgogKiBBdXRob3I6IE1heCBBc2L2Y2sgPGFtYXhAdXMuaWJtLmNvbT4KICoKICogVGhpcyBkcml2ZXIgaXMgYmFzZWQgb24gY29kZSBvcmlnaW5hbGx5IHdyaXR0ZW4gYnkgUGV0ZSBSZXlub2xkcwogKiBhbmQgb3RoZXJzLgogKgogKi8KCi8qCiAqIFRoZSBBU00gZGV2aWNlIGRyaXZlciBkb2VzIHRoZSBmb2xsb3dpbmcgdGhpbmdzOgogKgogKiAxKSBXaGVuIGxvYWRlZCBpdCBzZW5kcyBhIG1lc3NhZ2UgdG8gdGhlIHNlcnZpY2UgcHJvY2Vzc29yLAogKiBpbmRpY2F0aW5nIHRoYXQgYW4gT1MgaXMgKiBydW5uaW5nLiBUaGlzIGNhdXNlcyB0aGUgc2VydmljZSBwcm9jZXNzb3IKICogdG8gc2VuZCBwZXJpb2RpYyBoZWFydGJlYXRzIHRvIHRoZSBPUy4KICoKICogMikgQW5zd2VycyB0aGUgcGVyaW9kaWMgaGVhcnRiZWF0cyBzZW50IGJ5IHRoZSBzZXJ2aWNlIHByb2Nlc3Nvci4KICogRmFpbHVyZSB0byBkbyBzbyB3b3VsZCByZXN1bHQgaW4gc3lzdGVtIHJlYm9vdC4KICoKICogMykgQWN0cyBhcyBhIHBhc3MgdGhyb3VnaCBmb3IgZG90IGNvbW1hbmRzIHNlbnQgZnJvbSB1c2VyIGFwcGxpY2F0aW9ucy4KICogVGhlIGludGVyZmFjZSBmb3IgdGhpcyBpcyB0aGUgaWJtYXNtZnMgZmlsZSBzeXN0ZW0uCiAqCiAqIDQpIEFsbG93cyB1c2VyIGFwcGxpY2F0aW9ucyB0byByZWdpc3RlciBmb3IgZXZlbnQgbm90aWZpY2F0aW9uLiBFdmVudHMKICogYXJlIHNlbnQgdG8gdGhlIGRyaXZlciB0aHJvdWdoIGludGVycnVwdHMuIFRoZXkgY2FuIGJlIHJlYWQgZnJvbSB1c2VyCiAqIHNwYWNlIHRocm91Z2ggdGhlIGlibWFzbWZzIGZpbGUgc3lzdGVtLgogKgogKiA1KSBBbGxvd3MgdXNlciBzcGFjZSBhcHBsaWNhdGlvbnMgdG8gc2VuZCBoZWFydGJlYXRzIHRvIHRoZSBzZXJ2aWNlCiAqIHByb2Nlc3NvciAoYWthIHJldmVyc2UgaGVhcnRiZWF0cykuIEFnYWluIHRoaXMgaGFwcGVucyB0aHJvdWdoIGlibWFzbWZzLgogKgogKiA2KSBIYW5kbGVzIHJlbW90ZSBtb3VzZSBhbmQga2V5Ym9hcmQgZXZlbnQgaW50ZXJydXB0cyBhbmQgbWFrZXMgdGhlbQogKiBhdmFpbGFibGUgdG8gdXNlciBhcHBsaWNhdGlvbnMgdGhyb3VnaCBpYm1hc21mcy4KICoKICovCgojaW5jbHVkZSA8bGludXgvcGNpLmg+CiNpbmNsdWRlIDxsaW51eC9pbml0Lmg+CiNpbmNsdWRlICJpYm1hc20uaCIKI2luY2x1ZGUgImxvd2xldmVsLmgiCiNpbmNsdWRlICJyZW1vdGUuaCIKCmludCBpYm1hc21fZGVidWcgPSAwOwptb2R1bGVfcGFyYW0oaWJtYXNtX2RlYnVnLCBpbnQgLCBTX0lSVUdPIHwgU19JV1VTUik7Ck1PRFVMRV9QQVJNX0RFU0MoaWJtYXNtX2RlYnVnLCAiIFNldCBkZWJ1ZyBtb2RlIG9uIG9yIG9mZiIpOwoKCnN0YXRpYyBpbnQgX19kZXZpbml0IGlibWFzbV9pbml0X29uZShzdHJ1Y3QgcGNpX2RldiAqcGRldiwgY29uc3Qgc3RydWN0IHBjaV9kZXZpY2VfaWQgKmlkKQp7CglpbnQgcmVzdWx0OwoJc3RydWN0IHNlcnZpY2VfcHJvY2Vzc29yICpzcDsKCglpZiAoKHJlc3VsdCA9IHBjaV9lbmFibGVfZGV2aWNlKHBkZXYpKSkgewoJCWRldl9lcnIoJnBkZXYtPmRldiwgIkZhaWxlZCB0byBlbmFibGUgUENJIGRldmljZVxuIik7CgkJcmV0dXJuIHJlc3VsdDsKCX0KCWlmICgocmVzdWx0ID0gcGNpX3JlcXVlc3RfcmVnaW9ucyhwZGV2LCBEUklWRVJfTkFNRSkpKSB7CgkJZGV2X2VycigmcGRldi0+ZGV2LCAiRmFpbGVkIHRvIGFsbG9jYXRlIFBDSSByZXNvdXJjZXNcbiIpOwoJCWdvdG8gZXJyb3JfcmVzb3VyY2VzOwoJfQoJLyogdm5jIGNsaWVudCB3b24ndCB3b3JrIHdpdGhvdXQgYnVzLW1hc3RlcmluZyAqLwoJcGNpX3NldF9tYXN0ZXIocGRldik7CgoJc3AgPSBremFsbG9jKHNpemVvZihzdHJ1Y3Qgc2VydmljZV9wcm9jZXNzb3IpLCBHRlBfS0VSTkVMKTsKCWlmIChzcCA9PSBOVUxMKSB7CgkJZGV2X2VycigmcGRldi0+ZGV2LCAiRmFpbGVkIHRvIGFsbG9jYXRlIG1lbW9yeVxuIik7CgkJcmVzdWx0ID0gLUVOT01FTTsKCQlnb3RvIGVycm9yX2ttYWxsb2M7Cgl9CgoJc3Bpbl9sb2NrX2luaXQoJnNwLT5sb2NrKTsKCUlOSVRfTElTVF9IRUFEKCZzcC0+Y29tbWFuZF9xdWV1ZSk7CgoJcGNpX3NldF9kcnZkYXRhKHBkZXYsICh2b2lkICopc3ApOwoJc3AtPmRldiA9ICZwZGV2LT5kZXY7CglzcC0+bnVtYmVyID0gcGRldi0+YnVzLT5udW1iZXI7CglzbnByaW50ZihzcC0+ZGlybmFtZSwgSUJNQVNNX05BTUVfU0laRSwgIiVkIiwgc3AtPm51bWJlcik7CglzbnByaW50ZihzcC0+ZGV2bmFtZSwgSUJNQVNNX05BTUVfU0laRSwgIiVzJWQiLCBEUklWRVJfTkFNRSwgc3AtPm51bWJlcik7CgoJaWYgKGlibWFzbV9ldmVudF9idWZmZXJfaW5pdChzcCkpIHsKCQlkZXZfZXJyKHNwLT5kZXYsICJGYWlsZWQgdG8gYWxsb2NhdGUgZXZlbnQgYnVmZmVyXG4iKTsKCQlnb3RvIGVycm9yX2V2ZW50YnVmZmVyOwoJfQoKCWlmIChpYm1hc21faGVhcnRiZWF0X2luaXQoc3ApKSB7CgkJZGV2X2VycihzcC0+ZGV2LCAiRmFpbGVkIHRvIGFsbG9jYXRlIGhlYXJ0YmVhdCBjb21tYW5kXG4iKTsKCQlnb3RvIGVycm9yX2hlYXJ0YmVhdDsKCX0KCglzcC0+aXJxID0gcGRldi0+aXJxOwoJc3AtPmJhc2VfYWRkcmVzcyA9IHBjaV9pb3JlbWFwX2JhcihwZGV2LCAwKTsKCWlmICghc3AtPmJhc2VfYWRkcmVzcykgewoJCWRldl9lcnIoc3AtPmRldiwgIkZhaWxlZCB0byBpb3JlbWFwIHBjaSBtZW1vcnlcbiIpOwoJCXJlc3VsdCA9ICAtRU5PREVWOwoJCWdvdG8gZXJyb3JfaW9yZW1hcDsKCX0KCglyZXN1bHQgPSByZXF1ZXN0X2lycShzcC0+aXJxLCBpYm1hc21faW50ZXJydXB0X2hhbmRsZXIsIElSUUZfU0hBUkVELCBzcC0+ZGV2bmFtZSwgKHZvaWQqKXNwKTsKCWlmIChyZXN1bHQpIHsKCQlkZXZfZXJyKHNwLT5kZXYsICJGYWlsZWQgdG8gcmVnaXN0ZXIgaW50ZXJydXB0IGhhbmRsZXJcbiIpOwoJCWdvdG8gZXJyb3JfcmVxdWVzdF9pcnE7Cgl9CgoJZW5hYmxlX3NwX2ludGVycnVwdHMoc3AtPmJhc2VfYWRkcmVzcyk7CgoJcmVzdWx0ID0gaWJtYXNtX2luaXRfcmVtb3RlX2lucHV0X2RldihzcCk7CglpZiAocmVzdWx0KSB7CgkJZGV2X2VycihzcC0+ZGV2LCAiRmFpbGVkIHRvIGluaXRpYWxpemUgcmVtb3RlIHF1ZXVlXG4iKTsKCQlnb3RvIGVycm9yX3NlbmRfbWVzc2FnZTsKCX0KCglyZXN1bHQgPSBpYm1hc21fc2VuZF9kcml2ZXJfdnBkKHNwKTsKCWlmIChyZXN1bHQpIHsKCQlkZXZfZXJyKHNwLT5kZXYsICJGYWlsZWQgdG8gc2VuZCBkcml2ZXIgVlBEIHRvIHNlcnZpY2UgcHJvY2Vzc29yXG4iKTsKCQlnb3RvIGVycm9yX3NlbmRfbWVzc2FnZTsKCX0KCXJlc3VsdCA9IGlibWFzbV9zZW5kX29zX3N0YXRlKHNwLCBTWVNURU1fU1RBVEVfT1NfVVApOwoJaWYgKHJlc3VsdCkgewoJCWRldl9lcnIoc3AtPmRldiwgIkZhaWxlZCB0byBzZW5kIE9TIHN0YXRlIHRvIHNlcnZpY2UgcHJvY2Vzc29yXG4iKTsKCQlnb3RvIGVycm9yX3NlbmRfbWVzc2FnZTsKCX0KCWlibWFzbWZzX2FkZF9zcChzcCk7CgoJaWJtYXNtX3JlZ2lzdGVyX3VhcnQoc3ApOwoKCXJldHVybiAwOwoKZXJyb3Jfc2VuZF9tZXNzYWdlOgoJZGlzYWJsZV9zcF9pbnRlcnJ1cHRzKHNwLT5iYXNlX2FkZHJlc3MpOwoJaWJtYXNtX2ZyZWVfcmVtb3RlX2lucHV0X2RldihzcCk7CglmcmVlX2lycShzcC0+aXJxLCAodm9pZCAqKXNwKTsKZXJyb3JfcmVxdWVzdF9pcnE6Cglpb3VubWFwKHNwLT5iYXNlX2FkZHJlc3MpOwplcnJvcl9pb3JlbWFwOgoJaWJtYXNtX2hlYXJ0YmVhdF9leGl0KHNwKTsKZXJyb3JfaGVhcnRiZWF0OgoJaWJtYXNtX2V2ZW50X2J1ZmZlcl9leGl0KHNwKTsKZXJyb3JfZXZlbnRidWZmZXI6CglwY2lfc2V0X2RydmRhdGEocGRldiwgTlVMTCk7CglrZnJlZShzcCk7CmVycm9yX2ttYWxsb2M6CiAgICAgICAgcGNpX3JlbGVhc2VfcmVnaW9ucyhwZGV2KTsKZXJyb3JfcmVzb3VyY2VzOgogICAgICAgIHBjaV9kaXNhYmxlX2RldmljZShwZGV2KTsKCglyZXR1cm4gcmVzdWx0Owp9CgpzdGF0aWMgdm9pZCBfX2RldmV4aXQgaWJtYXNtX3JlbW92ZV9vbmUoc3RydWN0IHBjaV9kZXYgKnBkZXYpCnsKCXN0cnVjdCBzZXJ2aWNlX3Byb2Nlc3NvciAqc3AgPSAoc3RydWN0IHNlcnZpY2VfcHJvY2Vzc29yICopcGNpX2dldF9kcnZkYXRhKHBkZXYpOwoKCWRiZygiVW5yZWdpc3RlcmluZyBVQVJUXG4iKTsKCWlibWFzbV91bnJlZ2lzdGVyX3VhcnQoc3ApOwoJZGJnKCJTZW5kaW5nIE9TIGRvd24gbWVzc2FnZVxuIik7CglpZiAoaWJtYXNtX3NlbmRfb3Nfc3RhdGUoc3AsIFNZU1RFTV9TVEFURV9PU19ET1dOKSkKCQllcnIoImZhaWxlZCB0byBnZXQgcmVwc29uc2UgdG8gJ1NlbmQgT1MgU3RhdGUnIGNvbW1hbmRcbiIpOwoJZGJnKCJEaXNhYmxpbmcgaGVhcnRiZWF0c1xuIik7CglpYm1hc21faGVhcnRiZWF0X2V4aXQoc3ApOwoJZGJnKCJEaXNhYmxpbmcgaW50ZXJydXB0c1xuIik7CglkaXNhYmxlX3NwX2ludGVycnVwdHMoc3AtPmJhc2VfYWRkcmVzcyk7CglkYmcoIkZyZWVpbmcgU1AgaXJxXG4iKTsKCWZyZWVfaXJxKHNwLT5pcnEsICh2b2lkICopc3ApOwoJZGJnKCJDbGVhbmluZyB1cFxuIik7CglpYm1hc21fZnJlZV9yZW1vdGVfaW5wdXRfZGV2KHNwKTsKCWlvdW5tYXAoc3AtPmJhc2VfYWRkcmVzcyk7CglpYm1hc21fZXZlbnRfYnVmZmVyX2V4aXQoc3ApOwoJcGNpX3NldF9kcnZkYXRhKHBkZXYsIE5VTEwpOwoJa2ZyZWUoc3ApOwoJcGNpX3JlbGVhc2VfcmVnaW9ucyhwZGV2KTsKCXBjaV9kaXNhYmxlX2RldmljZShwZGV2KTsKfQoKc3RhdGljIHN0cnVjdCBwY2lfZGV2aWNlX2lkIGlibWFzbV9wY2lfdGFibGVbXSA9CnsKCXsgUENJX0RFVklDRShWRU5ET1JJRF9JQk0sIERFVklDRUlEX1JTQSkgfSwKCXt9LAp9OwoKc3RhdGljIHN0cnVjdCBwY2lfZHJpdmVyIGlibWFzbV9kcml2ZXIgPSB7CgkubmFtZQkJPSBEUklWRVJfTkFNRSwKCS5pZF90YWJsZQk9IGlibWFzbV9wY2lfdGFibGUsCgkucHJvYmUJCT0gaWJtYXNtX2luaXRfb25lLAoJLnJlbW92ZQkJPSBfX2RldmV4aXRfcChpYm1hc21fcmVtb3ZlX29uZSksCn07CgpzdGF0aWMgdm9pZCBfX2V4aXQgaWJtYXNtX2V4aXQgKHZvaWQpCnsKCWlibWFzbV91bnJlZ2lzdGVyX3BhbmljX25vdGlmaWVyKCk7CglpYm1hc21mc191bnJlZ2lzdGVyKCk7CglwY2lfdW5yZWdpc3Rlcl9kcml2ZXIoJmlibWFzbV9kcml2ZXIpOwoJaW5mbyhEUklWRVJfREVTQyAiIHZlcnNpb24gIiBEUklWRVJfVkVSU0lPTiAiIHVubG9hZGVkIik7Cn0KCnN0YXRpYyBpbnQgX19pbml0IGlibWFzbV9pbml0KHZvaWQpCnsKCWludCByZXN1bHQ7CgoJcmVzdWx0ID0gaWJtYXNtZnNfcmVnaXN0ZXIoKTsKCWlmIChyZXN1bHQpIHsKCQllcnIoIkZhaWxlZCB0byByZWdpc3RlciBpYm1hc21mcyBmaWxlIHN5c3RlbSIpOwoJCXJldHVybiByZXN1bHQ7Cgl9CglyZXN1bHQgPSBwY2lfcmVnaXN0ZXJfZHJpdmVyKCZpYm1hc21fZHJpdmVyKTsKCWlmIChyZXN1bHQpIHsKCQlpYm1hc21mc191bnJlZ2lzdGVyKCk7CgkJcmV0dXJuIHJlc3VsdDsKCX0KCWlibWFzbV9yZWdpc3Rlcl9wYW5pY19ub3RpZmllcigpOwoJaW5mbyhEUklWRVJfREVTQyAiIHZlcnNpb24gIiBEUklWRVJfVkVSU0lPTiAiIGxvYWRlZCIpOwoJcmV0dXJuIDA7Cn0KCm1vZHVsZV9pbml0KGlibWFzbV9pbml0KTsKbW9kdWxlX2V4aXQoaWJtYXNtX2V4aXQpOwoKTU9EVUxFX0FVVEhPUihEUklWRVJfQVVUSE9SKTsKTU9EVUxFX0RFU0NSSVBUSU9OKERSSVZFUl9ERVNDKTsKTU9EVUxFX0xJQ0VOU0UoIkdQTCIpOwpNT0RVTEVfREVWSUNFX1RBQkxFKHBjaSwgaWJtYXNtX3BjaV90YWJsZSk7Cgo=