Ci8qCiAqIElCTSBBU00gU2VydmljZSBQcm9jZXNzb3IgRGV2aWNlIERyaXZlcgogKgogKiBUaGlzIHByb2dyYW0gaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeQogKiBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieQogKiB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIgdmVyc2lvbiAyIG9mIHRoZSBMaWNlbnNlLCBvcgogKiAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZQogKiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiBhbG9uZyB3aXRoIHRoaXMgcHJvZ3JhbTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZQogKiBGb3VuZGF0aW9uLCBJbmMuLCA1OSBUZW1wbGUgUGxhY2UgLSBTdWl0ZSAzMzAsIEJvc3RvbiwgTUEgMDIxMTEtMTMwNywgVVNBLgogKgogKiBDb3B5cmlnaHQgKEMpIElCTSBDb3Jwb3JhdGlvbiwgMjAwNAogKgogKiBBdXRob3I6IE1heCBBc2L2Y2sgPGFtYXhAdXMuaWJtLmNvbT4gCiAqCiAqIFRoaXMgZHJpdmVyIGlzIGJhc2VkIG9uIGNvZGUgb3JpZ2luYWxseSB3cml0dGVuIGJ5IFBldGUgUmV5bm9sZHMgCiAqIGFuZCBvdGhlcnMuCiAqCiAqLwoKLyoKICogVGhlIEFTTSBkZXZpY2UgZHJpdmVyIGRvZXMgdGhlIGZvbGxvd2luZyB0aGluZ3M6CiAqCiAqIDEpIFdoZW4gbG9hZGVkIGl0IHNlbmRzIGEgbWVzc2FnZSB0byB0aGUgc2VydmljZSBwcm9jZXNzb3IsCiAqIGluZGljYXRpbmcgdGhhdCBhbiBPUyBpcyAqIHJ1bm5pbmcuIFRoaXMgY2F1c2VzIHRoZSBzZXJ2aWNlIHByb2Nlc3NvcgogKiB0byBzZW5kIHBlcmlvZGljIGhlYXJ0YmVhdHMgdG8gdGhlIE9TLiAKICoKICogMikgQW5zd2VycyB0aGUgcGVyaW9kaWMgaGVhcnRiZWF0cyBzZW50IGJ5IHRoZSBzZXJ2aWNlIHByb2Nlc3Nvci4KICogRmFpbHVyZSB0byBkbyBzbyB3b3VsZCByZXN1bHQgaW4gc3lzdGVtIHJlYm9vdC4KICoKICogMykgQWN0cyBhcyBhIHBhc3MgdGhyb3VnaCBmb3IgZG90IGNvbW1hbmRzIHNlbnQgZnJvbSB1c2VyIGFwcGxpY2F0aW9ucy4KICogVGhlIGludGVyZmFjZSBmb3IgdGhpcyBpcyB0aGUgaWJtYXNtZnMgZmlsZSBzeXN0ZW0uIAogKgogKiA0KSBBbGxvd3MgdXNlciBhcHBsaWNhdGlvbnMgdG8gcmVnaXN0ZXIgZm9yIGV2ZW50IG5vdGlmaWNhdGlvbi4gRXZlbnRzCiAqIGFyZSBzZW50IHRvIHRoZSBkcml2ZXIgdGhyb3VnaCBpbnRlcnJ1cHRzLiBUaGV5IGNhbiBiZSByZWFkIGZyb20gdXNlcgogKiBzcGFjZSB0aHJvdWdoIHRoZSBpYm1hc21mcyBmaWxlIHN5c3RlbS4KICoKICogNSkgQWxsb3dzIHVzZXIgc3BhY2UgYXBwbGljYXRpb25zIHRvIHNlbmQgaGVhcnRiZWF0cyB0byB0aGUgc2VydmljZQogKiBwcm9jZXNzb3IgKGFrYSByZXZlcnNlIGhlYXJ0YmVhdHMpLiBBZ2FpbiB0aGlzIGhhcHBlbnMgdGhyb3VnaCBpYm1hc21mcy4KICoKICogNikgSGFuZGxlcyByZW1vdGUgbW91c2UgYW5kIGtleWJvYXJkIGV2ZW50IGludGVycnVwdHMgYW5kIG1ha2VzIHRoZW0KICogYXZhaWxhYmxlIHRvIHVzZXIgYXBwbGljYXRpb25zIHRocm91Z2ggaWJtYXNtZnMuCiAqCiAqLwoKI2luY2x1ZGUgPGxpbnV4L3BjaS5oPgojaW5jbHVkZSA8bGludXgvaW5pdC5oPgojaW5jbHVkZSAiaWJtYXNtLmgiCiNpbmNsdWRlICJsb3dsZXZlbC5oIgojaW5jbHVkZSAicmVtb3RlLmgiCgppbnQgaWJtYXNtX2RlYnVnID0gMDsKbW9kdWxlX3BhcmFtKGlibWFzbV9kZWJ1ZywgaW50ICwgU19JUlVHTyB8IFNfSVdVU1IpOwpNT0RVTEVfUEFSTV9ERVNDKGlibWFzbV9kZWJ1ZywgIiBTZXQgZGVidWcgbW9kZSBvbiBvciBvZmYiKTsKCgpzdGF0aWMgaW50IF9fZGV2aW5pdCBpYm1hc21faW5pdF9vbmUoc3RydWN0IHBjaV9kZXYgKnBkZXYsIGNvbnN0IHN0cnVjdCBwY2lfZGV2aWNlX2lkICppZCkKewoJaW50IHJlc3VsdDsKCXN0cnVjdCBzZXJ2aWNlX3Byb2Nlc3NvciAqc3A7CgoJaWYgKChyZXN1bHQgPSBwY2lfZW5hYmxlX2RldmljZShwZGV2KSkpIHsKCQlkZXZfZXJyKCZwZGV2LT5kZXYsICJGYWlsZWQgdG8gZW5hYmxlIFBDSSBkZXZpY2VcbiIpOwoJCXJldHVybiByZXN1bHQ7Cgl9CglpZiAoKHJlc3VsdCA9IHBjaV9yZXF1ZXN0X3JlZ2lvbnMocGRldiwgRFJJVkVSX05BTUUpKSkgewoJCWRldl9lcnIoJnBkZXYtPmRldiwgIkZhaWxlZCB0byBhbGxvY2F0ZSBQQ0kgcmVzb3VyY2VzXG4iKTsKCQlnb3RvIGVycm9yX3Jlc291cmNlczsKCX0KCS8qIHZuYyBjbGllbnQgd29uJ3Qgd29yayB3aXRob3V0IGJ1cy1tYXN0ZXJpbmcgKi8KCXBjaV9zZXRfbWFzdGVyKHBkZXYpOwoKCXNwID0ga21hbGxvYyhzaXplb2Yoc3RydWN0IHNlcnZpY2VfcHJvY2Vzc29yKSwgR0ZQX0tFUk5FTCk7CglpZiAoc3AgPT0gTlVMTCkgewoJCWRldl9lcnIoJnBkZXYtPmRldiwgIkZhaWxlZCB0byBhbGxvY2F0ZSBtZW1vcnlcbiIpOwoJCXJlc3VsdCA9IC1FTk9NRU07CgkJZ290byBlcnJvcl9rbWFsbG9jOwoJfQoJbWVtc2V0KHNwLCAwLCBzaXplb2Yoc3RydWN0IHNlcnZpY2VfcHJvY2Vzc29yKSk7CgoJc3AtPmxvY2sgPSBTUElOX0xPQ0tfVU5MT0NLRUQ7CglJTklUX0xJU1RfSEVBRCgmc3AtPmNvbW1hbmRfcXVldWUpOwoKCXBjaV9zZXRfZHJ2ZGF0YShwZGV2LCAodm9pZCAqKXNwKTsKCXNwLT5kZXYgPSAmcGRldi0+ZGV2OwoJc3AtPm51bWJlciA9IHBkZXYtPmJ1cy0+bnVtYmVyOwoJc25wcmludGYoc3AtPmRpcm5hbWUsIElCTUFTTV9OQU1FX1NJWkUsICIlZCIsIHNwLT5udW1iZXIpOwoJc25wcmludGYoc3AtPmRldm5hbWUsIElCTUFTTV9OQU1FX1NJWkUsICIlcyVkIiwgRFJJVkVSX05BTUUsIHNwLT5udW1iZXIpOwoKCWlmIChpYm1hc21fZXZlbnRfYnVmZmVyX2luaXQoc3ApKSB7CgkJZGV2X2VycihzcC0+ZGV2LCAiRmFpbGVkIHRvIGFsbG9jYXRlIGV2ZW50IGJ1ZmZlclxuIik7CgkJZ290byBlcnJvcl9ldmVudGJ1ZmZlcjsKCX0KCglpZiAoaWJtYXNtX2hlYXJ0YmVhdF9pbml0KHNwKSkgewoJCWRldl9lcnIoc3AtPmRldiwgIkZhaWxlZCB0byBhbGxvY2F0ZSBoZWFydGJlYXQgY29tbWFuZFxuIik7CgkJZ290byBlcnJvcl9oZWFydGJlYXQ7Cgl9CgoJc3AtPmlycSA9IHBkZXYtPmlycTsKCXNwLT5iYXNlX2FkZHJlc3MgPSBpb3JlbWFwKHBjaV9yZXNvdXJjZV9zdGFydChwZGV2LCAwKSwgCgkJCQkJcGNpX3Jlc291cmNlX2xlbihwZGV2LCAwKSk7CglpZiAoc3AtPmJhc2VfYWRkcmVzcyA9PSAwKSB7CgkJZGV2X2VycihzcC0+ZGV2LCAiRmFpbGVkIHRvIGlvcmVtYXAgcGNpIG1lbW9yeVxuIik7CgkJcmVzdWx0ID0gIC1FTk9ERVY7CgkJZ290byBlcnJvcl9pb3JlbWFwOwoJfQoKCXJlc3VsdCA9IHJlcXVlc3RfaXJxKHNwLT5pcnEsIGlibWFzbV9pbnRlcnJ1cHRfaGFuZGxlciwgU0FfU0hJUlEsIHNwLT5kZXZuYW1lLCAodm9pZCopc3ApOwoJaWYgKHJlc3VsdCkgewoJCWRldl9lcnIoc3AtPmRldiwgIkZhaWxlZCB0byByZWdpc3RlciBpbnRlcnJ1cHQgaGFuZGxlclxuIik7CgkJZ290byBlcnJvcl9yZXF1ZXN0X2lycTsKCX0KCgllbmFibGVfc3BfaW50ZXJydXB0cyhzcC0+YmFzZV9hZGRyZXNzKTsKCglyZXN1bHQgPSBpYm1hc21faW5pdF9yZW1vdGVfaW5wdXRfZGV2KHNwKTsKCWlmIChyZXN1bHQpIHsKCQlkZXZfZXJyKHNwLT5kZXYsICJGYWlsZWQgdG8gaW5pdGlhbGl6ZSByZW1vdGUgcXVldWVcbiIpOwoJCWdvdG8gZXJyb3Jfc2VuZF9tZXNzYWdlOwoJfQoKCXJlc3VsdCA9IGlibWFzbV9zZW5kX2RyaXZlcl92cGQoc3ApOwoJaWYgKHJlc3VsdCkgewoJCWRldl9lcnIoc3AtPmRldiwgIkZhaWxlZCB0byBzZW5kIGRyaXZlciBWUEQgdG8gc2VydmljZSBwcm9jZXNzb3JcbiIpOwoJCWdvdG8gZXJyb3Jfc2VuZF9tZXNzYWdlOwoJfQoJcmVzdWx0ID0gaWJtYXNtX3NlbmRfb3Nfc3RhdGUoc3AsIFNZU1RFTV9TVEFURV9PU19VUCk7CglpZiAocmVzdWx0KSB7CgkJZGV2X2VycihzcC0+ZGV2LCAiRmFpbGVkIHRvIHNlbmQgT1Mgc3RhdGUgdG8gc2VydmljZSBwcm9jZXNzb3JcbiIpOwoJCWdvdG8gZXJyb3Jfc2VuZF9tZXNzYWdlOwoJfQoJaWJtYXNtZnNfYWRkX3NwKHNwKTsKCglpYm1hc21fcmVnaXN0ZXJfdWFydChzcCk7CgoJcmV0dXJuIDA7CgplcnJvcl9zZW5kX21lc3NhZ2U6CglkaXNhYmxlX3NwX2ludGVycnVwdHMoc3AtPmJhc2VfYWRkcmVzcyk7CglpYm1hc21fZnJlZV9yZW1vdGVfaW5wdXRfZGV2KHNwKTsKCWZyZWVfaXJxKHNwLT5pcnEsICh2b2lkICopc3ApOwplcnJvcl9yZXF1ZXN0X2lycToKCWlvdW5tYXAoc3AtPmJhc2VfYWRkcmVzcyk7CmVycm9yX2lvcmVtYXA6CglpYm1hc21faGVhcnRiZWF0X2V4aXQoc3ApOwplcnJvcl9oZWFydGJlYXQ6CglpYm1hc21fZXZlbnRfYnVmZmVyX2V4aXQoc3ApOwplcnJvcl9ldmVudGJ1ZmZlcjoKCXBjaV9zZXRfZHJ2ZGF0YShwZGV2LCBOVUxMKTsKCWtmcmVlKHNwKTsKZXJyb3Jfa21hbGxvYzoKICAgICAgICBwY2lfcmVsZWFzZV9yZWdpb25zKHBkZXYpOwplcnJvcl9yZXNvdXJjZXM6CiAgICAgICAgcGNpX2Rpc2FibGVfZGV2aWNlKHBkZXYpOwoKCXJldHVybiByZXN1bHQ7Cn0KCnN0YXRpYyB2b2lkIF9fZGV2ZXhpdCBpYm1hc21fcmVtb3ZlX29uZShzdHJ1Y3QgcGNpX2RldiAqcGRldikKewoJc3RydWN0IHNlcnZpY2VfcHJvY2Vzc29yICpzcCA9IChzdHJ1Y3Qgc2VydmljZV9wcm9jZXNzb3IgKilwY2lfZ2V0X2RydmRhdGEocGRldik7CgoJZGJnKCJVbnJlZ2lzdGVyaW5nIFVBUlRcbiIpOwoJaWJtYXNtX3VucmVnaXN0ZXJfdWFydChzcCk7CglkYmcoIlNlbmRpbmcgT1MgZG93biBtZXNzYWdlXG4iKTsKCWlmIChpYm1hc21fc2VuZF9vc19zdGF0ZShzcCwgU1lTVEVNX1NUQVRFX09TX0RPV04pKQoJCWVycigiZmFpbGVkIHRvIGdldCByZXBzb25zZSB0byAnU2VuZCBPUyBTdGF0ZScgY29tbWFuZFxuIik7CglkYmcoIkRpc2FibGluZyBoZWFydGJlYXRzXG4iKTsKCWlibWFzbV9oZWFydGJlYXRfZXhpdChzcCk7CglkYmcoIkRpc2FibGluZyBpbnRlcnJ1cHRzXG4iKTsKCWRpc2FibGVfc3BfaW50ZXJydXB0cyhzcC0+YmFzZV9hZGRyZXNzKTsKCWRiZygiRnJlZWluZyBTUCBpcnFcbiIpOwoJZnJlZV9pcnEoc3AtPmlycSwgKHZvaWQgKilzcCk7CglkYmcoIkNsZWFuaW5nIHVwXG4iKTsKCWlibWFzbV9mcmVlX3JlbW90ZV9pbnB1dF9kZXYoc3ApOwoJaW91bm1hcChzcC0+YmFzZV9hZGRyZXNzKTsKCWlibWFzbV9ldmVudF9idWZmZXJfZXhpdChzcCk7CglwY2lfc2V0X2RydmRhdGEocGRldiwgTlVMTCk7CglrZnJlZShzcCk7CglwY2lfcmVsZWFzZV9yZWdpb25zKHBkZXYpOwoJcGNpX2Rpc2FibGVfZGV2aWNlKHBkZXYpOwp9CgpzdGF0aWMgc3RydWN0IHBjaV9kZXZpY2VfaWQgaWJtYXNtX3BjaV90YWJsZVtdID0KewoJeyBQQ0lfREVWSUNFKFZFTkRPUklEX0lCTSwgREVWSUNFSURfUlNBKSB9LAoJe30sCn07CgpzdGF0aWMgc3RydWN0IHBjaV9kcml2ZXIgaWJtYXNtX2RyaXZlciA9IHsKCS5uYW1lCQk9IERSSVZFUl9OQU1FLAoJLmlkX3RhYmxlCT0gaWJtYXNtX3BjaV90YWJsZSwKCS5wcm9iZQkJPSBpYm1hc21faW5pdF9vbmUsCgkucmVtb3ZlCQk9IF9fZGV2ZXhpdF9wKGlibWFzbV9yZW1vdmVfb25lKSwKfTsKCnN0YXRpYyB2b2lkIF9fZXhpdCBpYm1hc21fZXhpdCAodm9pZCkKewoJaWJtYXNtX3VucmVnaXN0ZXJfcGFuaWNfbm90aWZpZXIoKTsKCWlibWFzbWZzX3VucmVnaXN0ZXIoKTsKCXBjaV91bnJlZ2lzdGVyX2RyaXZlcigmaWJtYXNtX2RyaXZlcik7CglpbmZvKERSSVZFUl9ERVNDICIgdmVyc2lvbiAiIERSSVZFUl9WRVJTSU9OICIgdW5sb2FkZWQiKTsKfQoKc3RhdGljIGludCBfX2luaXQgaWJtYXNtX2luaXQodm9pZCkKewoJaW50IHJlc3VsdDsKCglyZXN1bHQgPSBpYm1hc21mc19yZWdpc3RlcigpOwoJaWYgKHJlc3VsdCkgewoJCWVycigiRmFpbGVkIHRvIHJlZ2lzdGVyIGlibWFzbWZzIGZpbGUgc3lzdGVtIik7CgkJcmV0dXJuIHJlc3VsdDsKCX0KCXJlc3VsdCA9IHBjaV9yZWdpc3Rlcl9kcml2ZXIoJmlibWFzbV9kcml2ZXIpOwoJaWYgKHJlc3VsdCkgewoJCWlibWFzbWZzX3VucmVnaXN0ZXIoKTsKCQlyZXR1cm4gcmVzdWx0OwoJfQoJaWJtYXNtX3JlZ2lzdGVyX3BhbmljX25vdGlmaWVyKCk7CglpbmZvKERSSVZFUl9ERVNDICIgdmVyc2lvbiAiIERSSVZFUl9WRVJTSU9OICIgbG9hZGVkIik7CglyZXR1cm4gMDsKfQoKbW9kdWxlX2luaXQoaWJtYXNtX2luaXQpOwptb2R1bGVfZXhpdChpYm1hc21fZXhpdCk7CgpNT0RVTEVfQVVUSE9SKERSSVZFUl9BVVRIT1IpOwpNT0RVTEVfREVTQ1JJUFRJT04oRFJJVkVSX0RFU0MpOwpNT0RVTEVfTElDRU5TRSgiR1BMIik7Ck1PRFVMRV9ERVZJQ0VfVEFCTEUocGNpLCBpYm1hc21fcGNpX3RhYmxlKTsKCg==