Ci8qCiAqIElCTSBBU00gU2VydmljZSBQcm9jZXNzb3IgRGV2aWNlIERyaXZlcgogKgogKiBUaGlzIHByb2dyYW0gaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeQogKiBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieQogKiB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIgdmVyc2lvbiAyIG9mIHRoZSBMaWNlbnNlLCBvcgogKiAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZQogKiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiBhbG9uZyB3aXRoIHRoaXMgcHJvZ3JhbTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZQogKiBGb3VuZGF0aW9uLCBJbmMuLCA1OSBUZW1wbGUgUGxhY2UgLSBTdWl0ZSAzMzAsIEJvc3RvbiwgTUEgMDIxMTEtMTMwNywgVVNBLgogKgogKiBDb3B5cmlnaHQgKEMpIElCTSBDb3Jwb3JhdGlvbiwgMjAwNAogKgogKiBBdXRob3I6IE1heCBBc2L2Y2sgPGFtYXhAdXMuaWJtLmNvbT4gCiAqCiAqIFRoaXMgZHJpdmVyIGlzIGJhc2VkIG9uIGNvZGUgb3JpZ2luYWxseSB3cml0dGVuIGJ5IFBldGUgUmV5bm9sZHMgCiAqIGFuZCBvdGhlcnMuCiAqCiAqLwoKLyoKICogVGhlIEFTTSBkZXZpY2UgZHJpdmVyIGRvZXMgdGhlIGZvbGxvd2luZyB0aGluZ3M6CiAqCiAqIDEpIFdoZW4gbG9hZGVkIGl0IHNlbmRzIGEgbWVzc2FnZSB0byB0aGUgc2VydmljZSBwcm9jZXNzb3IsCiAqIGluZGljYXRpbmcgdGhhdCBhbiBPUyBpcyAqIHJ1bm5pbmcuIFRoaXMgY2F1c2VzIHRoZSBzZXJ2aWNlIHByb2Nlc3NvcgogKiB0byBzZW5kIHBlcmlvZGljIGhlYXJ0YmVhdHMgdG8gdGhlIE9TLiAKICoKICogMikgQW5zd2VycyB0aGUgcGVyaW9kaWMgaGVhcnRiZWF0cyBzZW50IGJ5IHRoZSBzZXJ2aWNlIHByb2Nlc3Nvci4KICogRmFpbHVyZSB0byBkbyBzbyB3b3VsZCByZXN1bHQgaW4gc3lzdGVtIHJlYm9vdC4KICoKICogMykgQWN0cyBhcyBhIHBhc3MgdGhyb3VnaCBmb3IgZG90IGNvbW1hbmRzIHNlbnQgZnJvbSB1c2VyIGFwcGxpY2F0aW9ucy4KICogVGhlIGludGVyZmFjZSBmb3IgdGhpcyBpcyB0aGUgaWJtYXNtZnMgZmlsZSBzeXN0ZW0uIAogKgogKiA0KSBBbGxvd3MgdXNlciBhcHBsaWNhdGlvbnMgdG8gcmVnaXN0ZXIgZm9yIGV2ZW50IG5vdGlmaWNhdGlvbi4gRXZlbnRzCiAqIGFyZSBzZW50IHRvIHRoZSBkcml2ZXIgdGhyb3VnaCBpbnRlcnJ1cHRzLiBUaGV5IGNhbiBiZSByZWFkIGZyb20gdXNlcgogKiBzcGFjZSB0aHJvdWdoIHRoZSBpYm1hc21mcyBmaWxlIHN5c3RlbS4KICoKICogNSkgQWxsb3dzIHVzZXIgc3BhY2UgYXBwbGljYXRpb25zIHRvIHNlbmQgaGVhcnRiZWF0cyB0byB0aGUgc2VydmljZQogKiBwcm9jZXNzb3IgKGFrYSByZXZlcnNlIGhlYXJ0YmVhdHMpLiBBZ2FpbiB0aGlzIGhhcHBlbnMgdGhyb3VnaCBpYm1hc21mcy4KICoKICogNikgSGFuZGxlcyByZW1vdGUgbW91c2UgYW5kIGtleWJvYXJkIGV2ZW50IGludGVycnVwdHMgYW5kIG1ha2VzIHRoZW0KICogYXZhaWxhYmxlIHRvIHVzZXIgYXBwbGljYXRpb25zIHRocm91Z2ggaWJtYXNtZnMuCiAqCiAqLwoKI2luY2x1ZGUgPGxpbnV4L3BjaS5oPgojaW5jbHVkZSA8bGludXgvaW5pdC5oPgojaW5jbHVkZSAiaWJtYXNtLmgiCiNpbmNsdWRlICJsb3dsZXZlbC5oIgojaW5jbHVkZSAicmVtb3RlLmgiCgppbnQgaWJtYXNtX2RlYnVnID0gMDsKbW9kdWxlX3BhcmFtKGlibWFzbV9kZWJ1ZywgaW50ICwgU19JUlVHTyB8IFNfSVdVU1IpOwpNT0RVTEVfUEFSTV9ERVNDKGlibWFzbV9kZWJ1ZywgIiBTZXQgZGVidWcgbW9kZSBvbiBvciBvZmYiKTsKCgpzdGF0aWMgaW50IF9fZGV2aW5pdCBpYm1hc21faW5pdF9vbmUoc3RydWN0IHBjaV9kZXYgKnBkZXYsIGNvbnN0IHN0cnVjdCBwY2lfZGV2aWNlX2lkICppZCkKewoJaW50IHJlc3VsdDsKCXN0cnVjdCBzZXJ2aWNlX3Byb2Nlc3NvciAqc3A7CgoJaWYgKChyZXN1bHQgPSBwY2lfZW5hYmxlX2RldmljZShwZGV2KSkpIHsKCQlkZXZfZXJyKCZwZGV2LT5kZXYsICJGYWlsZWQgdG8gZW5hYmxlIFBDSSBkZXZpY2VcbiIpOwoJCXJldHVybiByZXN1bHQ7Cgl9CglpZiAoKHJlc3VsdCA9IHBjaV9yZXF1ZXN0X3JlZ2lvbnMocGRldiwgRFJJVkVSX05BTUUpKSkgewoJCWRldl9lcnIoJnBkZXYtPmRldiwgIkZhaWxlZCB0byBhbGxvY2F0ZSBQQ0kgcmVzb3VyY2VzXG4iKTsKCQlnb3RvIGVycm9yX3Jlc291cmNlczsKCX0KCS8qIHZuYyBjbGllbnQgd29uJ3Qgd29yayB3aXRob3V0IGJ1cy1tYXN0ZXJpbmcgKi8KCXBjaV9zZXRfbWFzdGVyKHBkZXYpOwoKCXNwID0ga21hbGxvYyhzaXplb2Yoc3RydWN0IHNlcnZpY2VfcHJvY2Vzc29yKSwgR0ZQX0tFUk5FTCk7CglpZiAoc3AgPT0gTlVMTCkgewoJCWRldl9lcnIoJnBkZXYtPmRldiwgIkZhaWxlZCB0byBhbGxvY2F0ZSBtZW1vcnlcbiIpOwoJCXJlc3VsdCA9IC1FTk9NRU07CgkJZ290byBlcnJvcl9rbWFsbG9jOwoJfQoJbWVtc2V0KHNwLCAwLCBzaXplb2Yoc3RydWN0IHNlcnZpY2VfcHJvY2Vzc29yKSk7CgoJc3Bpbl9sb2NrX2luaXQoJnNwLT5sb2NrKTsKCUlOSVRfTElTVF9IRUFEKCZzcC0+Y29tbWFuZF9xdWV1ZSk7CgoJcGNpX3NldF9kcnZkYXRhKHBkZXYsICh2b2lkICopc3ApOwoJc3AtPmRldiA9ICZwZGV2LT5kZXY7CglzcC0+bnVtYmVyID0gcGRldi0+YnVzLT5udW1iZXI7CglzbnByaW50ZihzcC0+ZGlybmFtZSwgSUJNQVNNX05BTUVfU0laRSwgIiVkIiwgc3AtPm51bWJlcik7CglzbnByaW50ZihzcC0+ZGV2bmFtZSwgSUJNQVNNX05BTUVfU0laRSwgIiVzJWQiLCBEUklWRVJfTkFNRSwgc3AtPm51bWJlcik7CgoJaWYgKGlibWFzbV9ldmVudF9idWZmZXJfaW5pdChzcCkpIHsKCQlkZXZfZXJyKHNwLT5kZXYsICJGYWlsZWQgdG8gYWxsb2NhdGUgZXZlbnQgYnVmZmVyXG4iKTsKCQlnb3RvIGVycm9yX2V2ZW50YnVmZmVyOwoJfQoKCWlmIChpYm1hc21faGVhcnRiZWF0X2luaXQoc3ApKSB7CgkJZGV2X2VycihzcC0+ZGV2LCAiRmFpbGVkIHRvIGFsbG9jYXRlIGhlYXJ0YmVhdCBjb21tYW5kXG4iKTsKCQlnb3RvIGVycm9yX2hlYXJ0YmVhdDsKCX0KCglzcC0+aXJxID0gcGRldi0+aXJxOwoJc3AtPmJhc2VfYWRkcmVzcyA9IGlvcmVtYXAocGNpX3Jlc291cmNlX3N0YXJ0KHBkZXYsIDApLCAKCQkJCQlwY2lfcmVzb3VyY2VfbGVuKHBkZXYsIDApKTsKCWlmIChzcC0+YmFzZV9hZGRyZXNzID09IDApIHsKCQlkZXZfZXJyKHNwLT5kZXYsICJGYWlsZWQgdG8gaW9yZW1hcCBwY2kgbWVtb3J5XG4iKTsKCQlyZXN1bHQgPSAgLUVOT0RFVjsKCQlnb3RvIGVycm9yX2lvcmVtYXA7Cgl9CgoJcmVzdWx0ID0gcmVxdWVzdF9pcnEoc3AtPmlycSwgaWJtYXNtX2ludGVycnVwdF9oYW5kbGVyLCBJUlFGX1NIQVJFRCwgc3AtPmRldm5hbWUsICh2b2lkKilzcCk7CglpZiAocmVzdWx0KSB7CgkJZGV2X2VycihzcC0+ZGV2LCAiRmFpbGVkIHRvIHJlZ2lzdGVyIGludGVycnVwdCBoYW5kbGVyXG4iKTsKCQlnb3RvIGVycm9yX3JlcXVlc3RfaXJxOwoJfQoKCWVuYWJsZV9zcF9pbnRlcnJ1cHRzKHNwLT5iYXNlX2FkZHJlc3MpOwoKCXJlc3VsdCA9IGlibWFzbV9pbml0X3JlbW90ZV9pbnB1dF9kZXYoc3ApOwoJaWYgKHJlc3VsdCkgewoJCWRldl9lcnIoc3AtPmRldiwgIkZhaWxlZCB0byBpbml0aWFsaXplIHJlbW90ZSBxdWV1ZVxuIik7CgkJZ290byBlcnJvcl9zZW5kX21lc3NhZ2U7Cgl9CgoJcmVzdWx0ID0gaWJtYXNtX3NlbmRfZHJpdmVyX3ZwZChzcCk7CglpZiAocmVzdWx0KSB7CgkJZGV2X2VycihzcC0+ZGV2LCAiRmFpbGVkIHRvIHNlbmQgZHJpdmVyIFZQRCB0byBzZXJ2aWNlIHByb2Nlc3NvclxuIik7CgkJZ290byBlcnJvcl9zZW5kX21lc3NhZ2U7Cgl9CglyZXN1bHQgPSBpYm1hc21fc2VuZF9vc19zdGF0ZShzcCwgU1lTVEVNX1NUQVRFX09TX1VQKTsKCWlmIChyZXN1bHQpIHsKCQlkZXZfZXJyKHNwLT5kZXYsICJGYWlsZWQgdG8gc2VuZCBPUyBzdGF0ZSB0byBzZXJ2aWNlIHByb2Nlc3NvclxuIik7CgkJZ290byBlcnJvcl9zZW5kX21lc3NhZ2U7Cgl9CglpYm1hc21mc19hZGRfc3Aoc3ApOwoKCWlibWFzbV9yZWdpc3Rlcl91YXJ0KHNwKTsKCglyZXR1cm4gMDsKCmVycm9yX3NlbmRfbWVzc2FnZToKCWRpc2FibGVfc3BfaW50ZXJydXB0cyhzcC0+YmFzZV9hZGRyZXNzKTsKCWlibWFzbV9mcmVlX3JlbW90ZV9pbnB1dF9kZXYoc3ApOwoJZnJlZV9pcnEoc3AtPmlycSwgKHZvaWQgKilzcCk7CmVycm9yX3JlcXVlc3RfaXJxOgoJaW91bm1hcChzcC0+YmFzZV9hZGRyZXNzKTsKZXJyb3JfaW9yZW1hcDoKCWlibWFzbV9oZWFydGJlYXRfZXhpdChzcCk7CmVycm9yX2hlYXJ0YmVhdDoKCWlibWFzbV9ldmVudF9idWZmZXJfZXhpdChzcCk7CmVycm9yX2V2ZW50YnVmZmVyOgoJcGNpX3NldF9kcnZkYXRhKHBkZXYsIE5VTEwpOwoJa2ZyZWUoc3ApOwplcnJvcl9rbWFsbG9jOgogICAgICAgIHBjaV9yZWxlYXNlX3JlZ2lvbnMocGRldik7CmVycm9yX3Jlc291cmNlczoKICAgICAgICBwY2lfZGlzYWJsZV9kZXZpY2UocGRldik7CgoJcmV0dXJuIHJlc3VsdDsKfQoKc3RhdGljIHZvaWQgX19kZXZleGl0IGlibWFzbV9yZW1vdmVfb25lKHN0cnVjdCBwY2lfZGV2ICpwZGV2KQp7CglzdHJ1Y3Qgc2VydmljZV9wcm9jZXNzb3IgKnNwID0gKHN0cnVjdCBzZXJ2aWNlX3Byb2Nlc3NvciAqKXBjaV9nZXRfZHJ2ZGF0YShwZGV2KTsKCglkYmcoIlVucmVnaXN0ZXJpbmcgVUFSVFxuIik7CglpYm1hc21fdW5yZWdpc3Rlcl91YXJ0KHNwKTsKCWRiZygiU2VuZGluZyBPUyBkb3duIG1lc3NhZ2VcbiIpOwoJaWYgKGlibWFzbV9zZW5kX29zX3N0YXRlKHNwLCBTWVNURU1fU1RBVEVfT1NfRE9XTikpCgkJZXJyKCJmYWlsZWQgdG8gZ2V0IHJlcHNvbnNlIHRvICdTZW5kIE9TIFN0YXRlJyBjb21tYW5kXG4iKTsKCWRiZygiRGlzYWJsaW5nIGhlYXJ0YmVhdHNcbiIpOwoJaWJtYXNtX2hlYXJ0YmVhdF9leGl0KHNwKTsKCWRiZygiRGlzYWJsaW5nIGludGVycnVwdHNcbiIpOwoJZGlzYWJsZV9zcF9pbnRlcnJ1cHRzKHNwLT5iYXNlX2FkZHJlc3MpOwoJZGJnKCJGcmVlaW5nIFNQIGlycVxuIik7CglmcmVlX2lycShzcC0+aXJxLCAodm9pZCAqKXNwKTsKCWRiZygiQ2xlYW5pbmcgdXBcbiIpOwoJaWJtYXNtX2ZyZWVfcmVtb3RlX2lucHV0X2RldihzcCk7Cglpb3VubWFwKHNwLT5iYXNlX2FkZHJlc3MpOwoJaWJtYXNtX2V2ZW50X2J1ZmZlcl9leGl0KHNwKTsKCXBjaV9zZXRfZHJ2ZGF0YShwZGV2LCBOVUxMKTsKCWtmcmVlKHNwKTsKCXBjaV9yZWxlYXNlX3JlZ2lvbnMocGRldik7CglwY2lfZGlzYWJsZV9kZXZpY2UocGRldik7Cn0KCnN0YXRpYyBzdHJ1Y3QgcGNpX2RldmljZV9pZCBpYm1hc21fcGNpX3RhYmxlW10gPQp7Cgl7IFBDSV9ERVZJQ0UoVkVORE9SSURfSUJNLCBERVZJQ0VJRF9SU0EpIH0sCgl7fSwKfTsKCnN0YXRpYyBzdHJ1Y3QgcGNpX2RyaXZlciBpYm1hc21fZHJpdmVyID0gewoJLm5hbWUJCT0gRFJJVkVSX05BTUUsCgkuaWRfdGFibGUJPSBpYm1hc21fcGNpX3RhYmxlLAoJLnByb2JlCQk9IGlibWFzbV9pbml0X29uZSwKCS5yZW1vdmUJCT0gX19kZXZleGl0X3AoaWJtYXNtX3JlbW92ZV9vbmUpLAp9OwoKc3RhdGljIHZvaWQgX19leGl0IGlibWFzbV9leGl0ICh2b2lkKQp7CglpYm1hc21fdW5yZWdpc3Rlcl9wYW5pY19ub3RpZmllcigpOwoJaWJtYXNtZnNfdW5yZWdpc3RlcigpOwoJcGNpX3VucmVnaXN0ZXJfZHJpdmVyKCZpYm1hc21fZHJpdmVyKTsKCWluZm8oRFJJVkVSX0RFU0MgIiB2ZXJzaW9uICIgRFJJVkVSX1ZFUlNJT04gIiB1bmxvYWRlZCIpOwp9CgpzdGF0aWMgaW50IF9faW5pdCBpYm1hc21faW5pdCh2b2lkKQp7CglpbnQgcmVzdWx0OwoKCXJlc3VsdCA9IGlibWFzbWZzX3JlZ2lzdGVyKCk7CglpZiAocmVzdWx0KSB7CgkJZXJyKCJGYWlsZWQgdG8gcmVnaXN0ZXIgaWJtYXNtZnMgZmlsZSBzeXN0ZW0iKTsKCQlyZXR1cm4gcmVzdWx0OwoJfQoJcmVzdWx0ID0gcGNpX3JlZ2lzdGVyX2RyaXZlcigmaWJtYXNtX2RyaXZlcik7CglpZiAocmVzdWx0KSB7CgkJaWJtYXNtZnNfdW5yZWdpc3RlcigpOwoJCXJldHVybiByZXN1bHQ7Cgl9CglpYm1hc21fcmVnaXN0ZXJfcGFuaWNfbm90aWZpZXIoKTsKCWluZm8oRFJJVkVSX0RFU0MgIiB2ZXJzaW9uICIgRFJJVkVSX1ZFUlNJT04gIiBsb2FkZWQiKTsKCXJldHVybiAwOwp9Cgptb2R1bGVfaW5pdChpYm1hc21faW5pdCk7Cm1vZHVsZV9leGl0KGlibWFzbV9leGl0KTsKCk1PRFVMRV9BVVRIT1IoRFJJVkVSX0FVVEhPUik7Ck1PRFVMRV9ERVNDUklQVElPTihEUklWRVJfREVTQyk7Ck1PRFVMRV9MSUNFTlNFKCJHUEwiKTsKTU9EVUxFX0RFVklDRV9UQUJMRShwY2ksIGlibWFzbV9wY2lfdGFibGUpOwoK